]> git.saurik.com Git - apple/security.git/commitdiff
Security-55471.tar.gz os-x-109 os-x-1091 v55471
authorApple <opensource@apple.com>
Tue, 29 Oct 2013 00:03:35 +0000 (00:03 +0000)
committerApple <opensource@apple.com>
Tue, 29 Oct 2013 00:03:35 +0000 (00:03 +0000)
1344 files changed:
CloudKeychainProxy/CloudKeychainProxy-Info.plist [new file with mode: 0644]
CloudKeychainProxy/cloudkeychain.entitlements.plist [new file with mode: 0644]
CloudKeychainProxy/com.apple.security.cloudkeychainproxy.plist [new file with mode: 0644]
CloudKeychainProxy/en.lproj/InfoPlist.strings [new file with mode: 0644]
Keychain Circle Notification/CloudKeychain.icns [new file with mode: 0644]
Keychain Circle Notification/KNAppDelegate.h [new file with mode: 0644]
Keychain Circle Notification/KNAppDelegate.m [new file with mode: 0644]
Keychain Circle Notification/KNPersistantState.h [new file with mode: 0644]
Keychain Circle Notification/KNPersistantState.m [new file with mode: 0644]
Keychain Circle Notification/Keychain Circle Notification-Info.plist [new file with mode: 0644]
Keychain Circle Notification/Keychain Circle Notification-Prefix.pch [new file with mode: 0644]
Keychain Circle Notification/NSArray+mapWithBlock.h [new file with mode: 0644]
Keychain Circle Notification/NSArray+mapWithBlock.m [new file with mode: 0644]
Keychain Circle Notification/NSDictionary+compactDescription.h [new file with mode: 0644]
Keychain Circle Notification/NSDictionary+compactDescription.m [new file with mode: 0644]
Keychain Circle Notification/NSSet+compactDescription.h [new file with mode: 0644]
Keychain Circle Notification/NSSet+compactDescription.m [new file with mode: 0644]
Keychain Circle Notification/NSString+compactDescription.h [new file with mode: 0644]
Keychain Circle Notification/NSString+compactDescription.m [new file with mode: 0644]
Keychain Circle Notification/com.apple.security.keychain-circle-notification.plist [new file with mode: 0644]
Keychain Circle Notification/en.lproj/Credits.rtf [new file with mode: 0644]
Keychain Circle Notification/en.lproj/InfoPlist.strings [new file with mode: 0644]
Keychain Circle Notification/en.lproj/Localizable.strings [new file with mode: 0644]
Keychain Circle Notification/en.lproj/MainMenu.xib [new file with mode: 0644]
Keychain Circle Notification/entitlments.plist [new file with mode: 0644]
Keychain Circle Notification/main.m [new file with mode: 0644]
Keychain/Icon.icns [new file with mode: 0644]
Keychain/KDAppDelegate.h [new file with mode: 0644]
Keychain/KDAppDelegate.m [new file with mode: 0644]
Keychain/KDCirclePeer.h [new file with mode: 0644]
Keychain/KDCirclePeer.m [new file with mode: 0644]
Keychain/KDSecCircle.h [new file with mode: 0644]
Keychain/KDSecCircle.m [new file with mode: 0644]
Keychain/KDSecItems.h [new file with mode: 0644]
Keychain/KDSecItems.m [new file with mode: 0644]
Keychain/Keychain-Info.plist [new file with mode: 0644]
Keychain/Keychain-Prefix.pch [new file with mode: 0644]
Keychain/en.lproj/Credits.rtf [new file with mode: 0644]
Keychain/en.lproj/InfoPlist.strings [new file with mode: 0644]
Keychain/en.lproj/MainMenu.xib [new file with mode: 0644]
Keychain/main.m [new file with mode: 0644]
Security.xcodeproj/project.pbxproj
Security.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
Security.xcodeproj/xcshareddata/xcschemes/Security.xcscheme
Security.xcodeproj/xcshareddata/xcschemes/Security_executables.xcscheme
Security.xcodeproj/xcshareddata/xcschemes/Security_frameworks.xcscheme
Security.xcodeproj/xcshareddata/xcschemes/World.xcscheme
Security.xcodeproj/xcshareddata/xcschemes/authd.xcscheme [new file with mode: 0644]
Security.xcodeproj/xcshareddata/xcschemes/copyHeaders.xcscheme
Security.xcodeproj/xcshareddata/xcschemes/secd.xcscheme
Security.xcodeproj/xcshareddata/xcschemes/secdtests.xcscheme [new file with mode: 0644]
asl/com.apple.securityd [new file with mode: 0644]
authd/Info.plist [new file with mode: 0644]
authd/agent.c [new file with mode: 0644]
authd/agent.h [new file with mode: 0644]
authd/authd_private.h [new file with mode: 0644]
authd/authdb.c [new file with mode: 0644]
authd/authdb.h [new file with mode: 0644]
authd/authitems.c [new file with mode: 0644]
authd/authitems.h [new file with mode: 0644]
authd/authorization.plist [new file with mode: 0644]
authd/authtoken.c [new file with mode: 0644]
authd/authtoken.h [new file with mode: 0644]
authd/authtypes.h [new file with mode: 0644]
authd/authutilities.c [new file with mode: 0644]
authd/authutilities.h [new file with mode: 0644]
authd/ccaudit.c [new file with mode: 0644]
authd/ccaudit.h [new file with mode: 0644]
authd/com.apple.authd [new file with mode: 0644]
authd/com.apple.authd.sb [new file with mode: 0644]
authd/connection.c [new file with mode: 0644]
authd/connection.h [new file with mode: 0644]
authd/crc.c [new file with mode: 0644]
authd/crc.h [new file with mode: 0644]
authd/credential.c [new file with mode: 0644]
authd/credential.h [new file with mode: 0644]
authd/debugging.c [new file with mode: 0644]
authd/debugging.h [new file with mode: 0644]
authd/en.lproj/InfoPlist.strings [new file with mode: 0644]
authd/engine.c [new file with mode: 0644]
authd/engine.h [new file with mode: 0644]
authd/main.c [new file with mode: 0644]
authd/mechanism.c [new file with mode: 0644]
authd/mechanism.h [new file with mode: 0644]
authd/object.c [new file with mode: 0644]
authd/object.h [new file with mode: 0644]
authd/process.c [new file with mode: 0644]
authd/process.h [new file with mode: 0644]
authd/rule.c [new file with mode: 0644]
authd/rule.h [new file with mode: 0644]
authd/security.auth-Prefix.pch [new file with mode: 0644]
authd/server.c [new file with mode: 0644]
authd/server.h [new file with mode: 0644]
authd/session.c [new file with mode: 0644]
authd/session.h [new file with mode: 0644]
cloud_keychain_diagnose/cloud_keychain_diagnose-Prefix.pch [new file with mode: 0644]
config/base.xcconfig
config/command.xcconfig [new file with mode: 0644]
config/debug.xcconfig
config/executable.xcconfig [new file with mode: 0644]
config/lib.xcconfig
config/release.xcconfig
config/security.xcconfig
config/test.xcconfig [new file with mode: 0644]
iCloudStats/com.apple.iCloudStats.plist [new file with mode: 0644]
iCloudStats/iCloudStats.1 [new file with mode: 0644]
iCloudStats/main.c [new file with mode: 0644]
lib/Info-Security.plist
lib/dummy.cpp [new file with mode: 0644]
lib/en.lproj/authorization.buttons.strings [new file with mode: 0644]
lib/en.lproj/authorization.prompts.strings [new file with mode: 0644]
lib/framework.sb [new file with mode: 0644]
lib/generateErrStrings.pl
lib/plugins/csparser-Info.plist
lib/security.exp [deleted file]
lib/security.exp-in [new file with mode: 0644]
libsecurity_apple_csp/lib/AppleCSPKeys.cpp
libsecurity_apple_csp/lib/BlockCryptor.cpp
libsecurity_apple_csp/lib/BlockCryptor.h
libsecurity_apple_csp/lib/DH_exchange.cpp
libsecurity_apple_csp/lib/DH_keys.cpp
libsecurity_apple_csp/lib/DH_utils.cpp
libsecurity_apple_csp/lib/FEEAsymmetricContext.cpp
libsecurity_apple_csp/lib/FEECSPUtils.cpp
libsecurity_apple_csp/lib/FEEKeys.cpp
libsecurity_apple_csp/lib/FEESignatureObject.cpp
libsecurity_apple_csp/lib/FEESignatureObject.h
libsecurity_apple_csp/lib/HMACSHA1.h
libsecurity_apple_csp/lib/MD2Object.cpp
libsecurity_apple_csp/lib/MD2Object.h
libsecurity_apple_csp/lib/MacContext.cpp
libsecurity_apple_csp/lib/RSA_DSA_keys.cpp
libsecurity_apple_csp/lib/RSA_DSA_keys.h
libsecurity_apple_csp/lib/RSA_DSA_signature.cpp
libsecurity_apple_csp/lib/RSA_DSA_signature.h
libsecurity_apple_csp/lib/RSA_asymmetric.cpp
libsecurity_apple_csp/lib/RawSigner.h
libsecurity_apple_csp/lib/SHA1_MD5_Object.cpp
libsecurity_apple_csp/lib/SHA2_Object.cpp
libsecurity_apple_csp/lib/SignatureContext.h
libsecurity_apple_csp/lib/aescsp.cpp
libsecurity_apple_csp/lib/ascContext.cpp
libsecurity_apple_csp/lib/ascContext.h
libsecurity_apple_csp/lib/bfContext.cpp
libsecurity_apple_csp/lib/bfContext.h
libsecurity_apple_csp/lib/castContext.cpp
libsecurity_apple_csp/lib/castContext.h
libsecurity_apple_csp/lib/cspdebugging.c
libsecurity_apple_csp/lib/cspdebugging.h
libsecurity_apple_csp/lib/deriveKey.cpp
libsecurity_apple_csp/lib/desContext.h
libsecurity_apple_csp/lib/gladmanContext.cpp
libsecurity_apple_csp/lib/gladmanContext.h
libsecurity_apple_csp/lib/opensshCoding.cpp
libsecurity_apple_csp/lib/opensshWrap.cpp
libsecurity_apple_csp/lib/pbkdf2.c
libsecurity_apple_csp/lib/pkcs12Derive.cpp
libsecurity_apple_csp/lib/rc2Context.cpp
libsecurity_apple_csp/lib/rc4Context.h
libsecurity_apple_csp/lib/rc5Context.cpp
libsecurity_apple_csp/lib/rijndael-alg-ref.c
libsecurity_apple_csp/lib/wrapKey.cpp
libsecurity_apple_csp/lib/wrapKeyCms.cpp
libsecurity_apple_csp/libsecurity_apple_csp.xcodeproj/project.pbxproj
libsecurity_apple_csp/open_ssl/bf/bf_locl.h
libsecurity_apple_csp/open_ssl/bio/bss_file.c
libsecurity_apple_csp/open_ssl/bn/bn_print.c
libsecurity_apple_csp/open_ssl/bn/bn_rand.c
libsecurity_apple_csp/open_ssl/buffer/buffer.c
libsecurity_apple_csp/open_ssl/err/err.c
libsecurity_apple_csp/open_ssl/err/err_prn.c
libsecurity_apple_csp/open_ssl/misc/rc2_cbc.c
libsecurity_apple_csp/open_ssl/misc/rc2_locl.h
libsecurity_apple_csp/open_ssl/misc/rc5_locl.h
libsecurity_apple_csp/open_ssl/opensslUtils/opensslAsn1.cpp
libsecurity_apple_cspdl/lib/SSCSPDLSession.cpp
libsecurity_apple_cspdl/lib/SSCSPSession.cpp
libsecurity_apple_cspdl/lib/SSCSPSession.h
libsecurity_apple_cspdl/lib/SSContext.cpp
libsecurity_apple_cspdl/lib/SSContext.h
libsecurity_apple_cspdl/lib/SSDLSession.cpp
libsecurity_apple_cspdl/lib/SSDatabase.cpp
libsecurity_apple_cspdl/lib/SSDatabase.h
libsecurity_apple_cspdl/lib/SSKey.cpp
libsecurity_apple_cspdl/libsecurity_apple_cspdl.xcodeproj/project.pbxproj
libsecurity_apple_file_dl/lib/AppleFileDL.cpp
libsecurity_apple_file_dl/libsecurity_apple_file_dl.xcodeproj/project.pbxproj
libsecurity_apple_x509_cl/lib/CLCertExtensions.cpp
libsecurity_apple_x509_cl/lib/CLCrlExtensions.cpp
libsecurity_apple_x509_cl/lib/CertFields.cpp
libsecurity_apple_x509_cl/lib/CrlFields.cpp
libsecurity_apple_x509_cl/lib/DecodedExtensions.cpp
libsecurity_apple_x509_cl/lib/clNameUtils.cpp
libsecurity_apple_x509_cl/lib/clNssUtils.cpp
libsecurity_apple_x509_cl/libsecurity_apple_x509_cl.xcodeproj/project.pbxproj
libsecurity_apple_x509_tp/lib/TPCertInfo.cpp
libsecurity_apple_x509_tp/lib/TPCrlInfo.cpp
libsecurity_apple_x509_tp/lib/TPDatabase.cpp
libsecurity_apple_x509_tp/lib/TPNetwork.cpp
libsecurity_apple_x509_tp/lib/certGroupUtils.cpp
libsecurity_apple_x509_tp/lib/cuEnc64.c
libsecurity_apple_x509_tp/lib/ocspRequest.cpp
libsecurity_apple_x509_tp/lib/tpCertGroup.cpp
libsecurity_apple_x509_tp/lib/tpCrlVerify.cpp
libsecurity_apple_x509_tp/lib/tpOcspCertVfy.cpp
libsecurity_apple_x509_tp/lib/tpOcspCertVfy.h
libsecurity_apple_x509_tp/lib/tpPolicies.cpp
libsecurity_apple_x509_tp/lib/tpPolicies.h
libsecurity_apple_x509_tp/lib/tpTime.c
libsecurity_apple_x509_tp/libsecurity_apple_x509_tp.xcodeproj/project.pbxproj
libsecurity_asn1/config/base.xcconfig
libsecurity_asn1/config/debug.xcconfig
libsecurity_asn1/config/lib.xcconfig
libsecurity_asn1/config/release.xcconfig
libsecurity_asn1/lib/SecAsn1Coder.c
libsecurity_asn1/lib/SecAsn1Coder.h
libsecurity_asn1/lib/X509Templates.h
libsecurity_asn1/lib/keyTemplates.c
libsecurity_asn1/lib/keyTemplates.h
libsecurity_asn1/lib/nameTemplates.c
libsecurity_asn1/lib/nameTemplates.h
libsecurity_asn1/lib/nsprPortX.c
libsecurity_asn1/lib/ocspTemplates.c
libsecurity_asn1/lib/ocspTemplates.h
libsecurity_asn1/lib/oidsalg.c
libsecurity_asn1/lib/oidsalg.h
libsecurity_asn1/lib/osKeyTemplates.h
libsecurity_asn1/lib/pkcs7Templates.h
libsecurity_asn1/lib/secasn1d.c
libsecurity_asn1/libsecurity_asn1.xcodeproj/project.pbxproj
libsecurity_authorization/lib/AuthSession.h
libsecurity_authorization/lib/Authorization.c [new file with mode: 0644]
libsecurity_authorization/lib/Authorization.cpp
libsecurity_authorization/lib/AuthorizationPlugin.h
libsecurity_authorization/lib/AuthorizationPriv.h
libsecurity_authorization/lib/AuthorizationTagsPriv.h
libsecurity_authorization/lib/trampolineClient.cpp
libsecurity_authorization/lib/trampolineServer.cpp
libsecurity_authorization/libsecurity_authorization.xcodeproj/project.pbxproj
libsecurity_cdsa_client/lib/cssmclient.cpp
libsecurity_cdsa_client/lib/cssmclient.h
libsecurity_cdsa_client/lib/dlclient.cpp
libsecurity_cdsa_client/lib/dlclient.h
libsecurity_cdsa_client/lib/dlquery.cpp
libsecurity_cdsa_client/lib/genkey.h
libsecurity_cdsa_client/lib/keyclient.cpp
libsecurity_cdsa_client/lib/securestorage.cpp
libsecurity_cdsa_client/lib/tpclient.h
libsecurity_cdsa_client/lib/wrapkey.cpp
libsecurity_cdsa_client/libsecurity_cdsa_client.xcodeproj/project.pbxproj
libsecurity_cdsa_plugin/lib/CSPsession.cpp
libsecurity_cdsa_plugin/lib/CSPsession.h
libsecurity_cdsa_plugin/lib/DatabaseSession.cpp
libsecurity_cdsa_plugin/lib/pluginspi.h
libsecurity_cdsa_plugin/libsecurity_cdsa_plugin.xcodeproj/project.pbxproj
libsecurity_cdsa_utilities/lib/AuthorizationData.cpp
libsecurity_cdsa_utilities/lib/Schema.m4
libsecurity_cdsa_utilities/lib/acl_comment.cpp
libsecurity_cdsa_utilities/lib/acl_preauth.cpp
libsecurity_cdsa_utilities/lib/aclsubject.h
libsecurity_cdsa_utilities/lib/callback.h
libsecurity_cdsa_utilities/lib/context.h
libsecurity_cdsa_utilities/lib/cssmaclpod.cpp
libsecurity_cdsa_utilities/lib/cssmdata.cpp
libsecurity_cdsa_utilities/lib/cssmdata.h
libsecurity_cdsa_utilities/lib/cssmdates.cpp
libsecurity_cdsa_utilities/lib/cssmdb.cpp
libsecurity_cdsa_utilities/lib/cssmdb.h
libsecurity_cdsa_utilities/lib/cssmdbname.cpp
libsecurity_cdsa_utilities/lib/cssmerrors.cpp
libsecurity_cdsa_utilities/lib/cssmpods.h
libsecurity_cdsa_utilities/lib/digestobject.h
libsecurity_cdsa_utilities/lib/handletemplates.cpp
libsecurity_cdsa_utilities/lib/handletemplates.h
libsecurity_cdsa_utilities/lib/handletemplates_defs.h
libsecurity_cdsa_utilities/lib/objectacl.cpp
libsecurity_cdsa_utilities/lib/objectacl.h
libsecurity_cdsa_utilities/lib/osxverifier.cpp
libsecurity_cdsa_utilities/lib/osxverifier.h
libsecurity_cdsa_utilities/lib/walkers.h
libsecurity_cdsa_utilities/libsecurity_cdsa_utilities.xcodeproj/project.pbxproj
libsecurity_cdsa_utils/lib/cuCdsaUtils.cpp
libsecurity_cdsa_utils/lib/cuDbUtils.cpp
libsecurity_cdsa_utils/lib/cuFileIo.c
libsecurity_cdsa_utils/lib/cuOidParser.cpp
libsecurity_cdsa_utils/lib/cuPem.cpp
libsecurity_cdsa_utils/lib/cuPrintCert.cpp
libsecurity_cdsa_utils/lib/cuTimeStr.cpp
libsecurity_cdsa_utils/libsecurity_cdsa_utils.xcodeproj/project.pbxproj
libsecurity_checkpw/checkpw.pam
libsecurity_checkpw/lib/checkpw.c
libsecurity_checkpw/libsecurity_checkpw.xcodeproj/project.pbxproj
libsecurity_cms/lib/CMSDecoder.cpp
libsecurity_cms/lib/CMSDecoder.h
libsecurity_cms/lib/CMSEncoder.cpp
libsecurity_cms/lib/CMSUtils.cpp
libsecurity_cms/lib/CMSUtils.h
libsecurity_cms/libsecurity_cms.xcodeproj/project.pbxproj
libsecurity_codesigning/CodeSigningHelper/CodeSigningHelper-Info.plist [new file with mode: 0644]
libsecurity_codesigning/CodeSigningHelper/com.apple.CodeSigningHelper.sb [new file with mode: 0644]
libsecurity_codesigning/CodeSigningHelper/main.c [new file with mode: 0644]
libsecurity_codesigning/antlr2/AUTHORS [new file with mode: 0644]
libsecurity_codesigning/antlr2/ChangeLog [new file with mode: 0644]
libsecurity_codesigning/antlr2/LICENSE.txt [new file with mode: 0644]
libsecurity_codesigning/antlr2/Makefile.in [new file with mode: 0644]
libsecurity_codesigning/antlr2/README [new file with mode: 0644]
libsecurity_codesigning/antlr2/TODO [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr.jar [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/ANTLRException.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/ANTLRUtil.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/AST.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/ASTArray.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/ASTFactory.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/ASTNULLType.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/ASTPair.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/ASTRefCount.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/BaseAST.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/BitSet.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/CharBuffer.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/CharInputBuffer.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/CharScanner.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/CharStreamException.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/CharStreamIOException.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/CircularQueue.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/CommonAST.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/CommonASTWithHiddenTokens.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/CommonHiddenStreamToken.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/CommonToken.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/IOException.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/InputBuffer.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/LLkParser.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/LexerSharedInputState.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/Makefile.in [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/MismatchedCharException.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/MismatchedTokenException.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/NoViableAltException.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/NoViableAltForCharException.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/Parser.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/ParserSharedInputState.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/RecognitionException.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/RefCount.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/SemanticException.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/String.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/Token.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/TokenBuffer.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/TokenRefCount.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/TokenStream.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/TokenStreamBasicFilter.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/TokenStreamException.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/TokenStreamHiddenTokenFilter.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/TokenStreamIOException.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/TokenStreamRecognitionException.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/TokenStreamRetryException.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/TokenStreamRewriteEngine.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/TokenStreamSelector.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/TokenWithIndex.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/TreeParser.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/TreeParserSharedInputState.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/antlr/config.hpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/contrib/bcb4/README [new file with mode: 0644]
libsecurity_codesigning/antlr2/contrib/bcb4/antlr.bpr [new file with mode: 0644]
libsecurity_codesigning/antlr2/contrib/bcb4/antlr.cpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/doxygen.cfg [new file with mode: 0644]
libsecurity_codesigning/antlr2/libsecurity_codesigning.plist [new file with mode: 0644]
libsecurity_codesigning/antlr2/libsecurity_codesigning.txt [new file with mode: 0644]
libsecurity_codesigning/antlr2/scripts/cr_stripper.sh [new file with mode: 0644]
libsecurity_codesigning/antlr2/scripts/make_change_log.tcl [new file with mode: 0755]
libsecurity_codesigning/antlr2/src/ANTLRUtil.cpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/src/ASTFactory.cpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/src/ASTNULLType.cpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/src/ASTRefCount.cpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/src/BaseAST.cpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/src/BitSet.cpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/src/CharBuffer.cpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/src/CharScanner.cpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/src/CommonAST.cpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/src/CommonASTWithHiddenTokens.cpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/src/CommonHiddenStreamToken.cpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/src/CommonToken.cpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/src/InputBuffer.cpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/src/LLkParser.cpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/src/Makefile.in [new file with mode: 0755]
libsecurity_codesigning/antlr2/src/MismatchedCharException.cpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/src/MismatchedTokenException.cpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/src/NoViableAltException.cpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/src/NoViableAltForCharException.cpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/src/Parser.cpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/src/RecognitionException.cpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/src/String.cpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/src/Token.cpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/src/TokenBuffer.cpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/src/TokenRefCount.cpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/src/TokenStreamBasicFilter.cpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/src/TokenStreamHiddenTokenFilter.cpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/src/TokenStreamRewriteEngine.cpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/src/TokenStreamSelector.cpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/src/TreeParser.cpp [new file with mode: 0644]
libsecurity_codesigning/antlr2/src/dll.cpp [new file with mode: 0644]
libsecurity_codesigning/gke/gkrecord
libsecurity_codesigning/gke/gkreport
libsecurity_codesigning/lib/CSCommon.h
libsecurity_codesigning/lib/CSCommonPriv.h
libsecurity_codesigning/lib/Code.cpp
libsecurity_codesigning/lib/CodeSigner.cpp
libsecurity_codesigning/lib/CodeSigner.h
libsecurity_codesigning/lib/RequirementParser.cpp
libsecurity_codesigning/lib/SecAssessment.cpp
libsecurity_codesigning/lib/SecAssessment.h
libsecurity_codesigning/lib/SecCode.cpp
libsecurity_codesigning/lib/SecCode.h
libsecurity_codesigning/lib/SecCodeHost.h
libsecurity_codesigning/lib/SecCodePriv.h
libsecurity_codesigning/lib/SecCodeSigner.cpp
libsecurity_codesigning/lib/SecCodeSigner.h
libsecurity_codesigning/lib/SecRequirement.cpp
libsecurity_codesigning/lib/SecRequirement.h
libsecurity_codesigning/lib/SecRequirementPriv.h
libsecurity_codesigning/lib/SecStaticCode.cpp
libsecurity_codesigning/lib/SecStaticCode.h
libsecurity_codesigning/lib/SecStaticCodePriv.h
libsecurity_codesigning/lib/SecTask.c
libsecurity_codesigning/lib/SecTaskPriv.h [new file with mode: 0644]
libsecurity_codesigning/lib/StaticCode.cpp
libsecurity_codesigning/lib/StaticCode.h
libsecurity_codesigning/lib/antlrplugin.cpp
libsecurity_codesigning/lib/bundlediskrep.cpp
libsecurity_codesigning/lib/bundlediskrep.h
libsecurity_codesigning/lib/cdbuilder.cpp
libsecurity_codesigning/lib/cdbuilder.h
libsecurity_codesigning/lib/cfmdiskrep.cpp
libsecurity_codesigning/lib/codedirectory.cpp
libsecurity_codesigning/lib/cs.h
libsecurity_codesigning/lib/csdatabase.cpp
libsecurity_codesigning/lib/csdatabase.h
libsecurity_codesigning/lib/csgeneric.cpp
libsecurity_codesigning/lib/cskernel.cpp
libsecurity_codesigning/lib/csprocess.cpp
libsecurity_codesigning/lib/csprocess.h
libsecurity_codesigning/lib/csutilities.cpp
libsecurity_codesigning/lib/csutilities.h
libsecurity_codesigning/lib/detachedrep.cpp
libsecurity_codesigning/lib/detachedrep.h
libsecurity_codesigning/lib/diskrep.h
libsecurity_codesigning/lib/machorep.cpp
libsecurity_codesigning/lib/piddiskrep.cpp [new file with mode: 0644]
libsecurity_codesigning/lib/piddiskrep.h [new file with mode: 0644]
libsecurity_codesigning/lib/policydb.cpp
libsecurity_codesigning/lib/policydb.h
libsecurity_codesigning/lib/policyengine.cpp
libsecurity_codesigning/lib/policyengine.h
libsecurity_codesigning/lib/renum.cpp [deleted file]
libsecurity_codesigning/lib/renum.h [deleted file]
libsecurity_codesigning/lib/reqdumper.cpp
libsecurity_codesigning/lib/reqinterp.cpp
libsecurity_codesigning/lib/reqmaker.cpp
libsecurity_codesigning/lib/reqmaker.h
libsecurity_codesigning/lib/reqreader.h
libsecurity_codesigning/lib/requirement.cpp
libsecurity_codesigning/lib/resources.cpp
libsecurity_codesigning/lib/resources.h
libsecurity_codesigning/lib/security_codesigning.exp
libsecurity_codesigning/lib/sigblob.cpp
libsecurity_codesigning/lib/signer.cpp
libsecurity_codesigning/lib/signer.h
libsecurity_codesigning/lib/signerutils.cpp
libsecurity_codesigning/lib/signerutils.h
libsecurity_codesigning/lib/slcrep.cpp
libsecurity_codesigning/lib/xpcengine.cpp
libsecurity_codesigning/lib/xpcengine.h
libsecurity_codesigning/libsecurity_codesigning.xcodeproj/project.pbxproj
libsecurity_comcryption/lib/comcryptPriv.c
libsecurity_comcryption/lib/comcryption.c
libsecurity_comcryption/lib/comcryption.h
libsecurity_cryptkit/lib/CryptKitDER.cpp
libsecurity_cryptkit/lib/HmacSha1Legacy.c
libsecurity_cryptkit/lib/HmacSha1Legacy.h
libsecurity_cryptkit/lib/ckutilities.c
libsecurity_cryptkit/lib/curveParams.h
libsecurity_cryptkit/lib/feeFunctions.h
libsecurity_cryptkit/lib/feePublicKey.c
libsecurity_cryptkit/lib/feePublicKey.h
libsecurity_cryptkit/lib/giantIntegers.c
libsecurity_cryptkit/lib/giantIntegers.h
libsecurity_cryptkit/libsecurity_cryptkit.xcodeproj/project.pbxproj
libsecurity_cssm/lib/attachment.cpp
libsecurity_cssm/lib/cssmapple.h
libsecurity_cssm/lib/cssmapplePriv.h
libsecurity_cssm/lib/cssmcontext.h
libsecurity_cssm/lib/module.h
libsecurity_cssm/lib/oidsbase.h
libsecurity_cssm/lib/oidscert.cpp
libsecurity_cssm/lib/oidscert.h
libsecurity_cssm/lib/transition.cpp
libsecurity_cssm/libsecurity_cssm.xcodeproj/project.pbxproj
libsecurity_filedb/lib/AppleDatabase.cpp
libsecurity_filedb/lib/AtomicFile.cpp
libsecurity_filedb/lib/AtomicFile.h
libsecurity_filedb/lib/DbIndex.cpp
libsecurity_filedb/lib/DbValue.cpp
libsecurity_filedb/lib/MetaRecord.cpp
libsecurity_filedb/lib/MetaRecord.h
libsecurity_filedb/lib/ReadWriteSection.cpp
libsecurity_filedb/lib/ReadWriteSection.h
libsecurity_filedb/libsecurity_filedb.xcodeproj/project.pbxproj
libsecurity_keychain/Security [new symlink]
libsecurity_keychain/lib/ACL.cpp
libsecurity_keychain/lib/Access.cpp
libsecurity_keychain/lib/CCallbackMgr.cp
libsecurity_keychain/lib/Certificate.cpp
libsecurity_keychain/lib/Certificate.h
libsecurity_keychain/lib/CertificateRequest.cpp
libsecurity_keychain/lib/CertificateValues.cpp
libsecurity_keychain/lib/CertificateValues.h
libsecurity_keychain/lib/DLDBListCFPref.cpp
libsecurity_keychain/lib/Globals.cpp
libsecurity_keychain/lib/Globals.h
libsecurity_keychain/lib/Identity.cpp
libsecurity_keychain/lib/Identity.h
libsecurity_keychain/lib/IdentityCursor.cpp
libsecurity_keychain/lib/Item.cpp
libsecurity_keychain/lib/Item.h
libsecurity_keychain/lib/KCCursor.cpp
libsecurity_keychain/lib/KCCursor.h
libsecurity_keychain/lib/KCExceptions.h
libsecurity_keychain/lib/KCUtilities.h
libsecurity_keychain/lib/KeyItem.cpp
libsecurity_keychain/lib/KeyItem.h
libsecurity_keychain/lib/Keychains.cpp
libsecurity_keychain/lib/Keychains.h
libsecurity_keychain/lib/MacOSErrorStrings.h
libsecurity_keychain/lib/Password.cpp
libsecurity_keychain/lib/Policies.cpp
libsecurity_keychain/lib/Policies.h
libsecurity_keychain/lib/PolicyCursor.cpp
libsecurity_keychain/lib/PolicyCursor.h
libsecurity_keychain/lib/PrimaryKey.cpp
libsecurity_keychain/lib/SecACL.cpp
libsecurity_keychain/lib/SecAccess.cpp
libsecurity_keychain/lib/SecBase.cpp
libsecurity_keychain/lib/SecBase.h
libsecurity_keychain/lib/SecBase64P.c
libsecurity_keychain/lib/SecBridge.h
libsecurity_keychain/lib/SecCertificate.cpp
libsecurity_keychain/lib/SecCertificate.h
libsecurity_keychain/lib/SecCertificateBundle.cpp
libsecurity_keychain/lib/SecCertificateInternalP.h
libsecurity_keychain/lib/SecCertificateP.c
libsecurity_keychain/lib/SecCertificateP.h
libsecurity_keychain/lib/SecCertificatePriv.h
libsecurity_keychain/lib/SecCertificatePrivP.h
libsecurity_keychain/lib/SecCertificateRequest.cpp
libsecurity_keychain/lib/SecCertificateRequest.h
libsecurity_keychain/lib/SecExport.cpp
libsecurity_keychain/lib/SecExternalRep.cpp
libsecurity_keychain/lib/SecFDERecoveryAsymmetricCrypto.cpp
libsecurity_keychain/lib/SecFrameworkP.c
libsecurity_keychain/lib/SecIdentity.cpp
libsecurity_keychain/lib/SecImport.cpp
libsecurity_keychain/lib/SecImportExport.c
libsecurity_keychain/lib/SecImportExport.h
libsecurity_keychain/lib/SecImportExportAgg.cpp
libsecurity_keychain/lib/SecImportExportCrypto.cpp
libsecurity_keychain/lib/SecImportExportOpenSSH.cpp
libsecurity_keychain/lib/SecImportExportPem.cpp
libsecurity_keychain/lib/SecImportExportPem.h
libsecurity_keychain/lib/SecImportExportPkcs8.cpp
libsecurity_keychain/lib/SecImportExportUtils.cpp
libsecurity_keychain/lib/SecImportExportUtils.h
libsecurity_keychain/lib/SecInternal.h
libsecurity_keychain/lib/SecItem.cpp
libsecurity_keychain/lib/SecItem.h
libsecurity_keychain/lib/SecItemConstants.c
libsecurity_keychain/lib/SecItemPriv.h
libsecurity_keychain/lib/SecKey.cpp
libsecurity_keychain/lib/SecKey.h
libsecurity_keychain/lib/SecKeyPriv.h
libsecurity_keychain/lib/SecKeychain.cpp
libsecurity_keychain/lib/SecKeychain.h
libsecurity_keychain/lib/SecKeychainAddIToolsPassword.cpp
libsecurity_keychain/lib/SecKeychainItem.cpp
libsecurity_keychain/lib/SecKeychainItem.h
libsecurity_keychain/lib/SecKeychainItemExtendedAttributes.cpp
libsecurity_keychain/lib/SecKeychainItemPriv.h
libsecurity_keychain/lib/SecKeychainPriv.h
libsecurity_keychain/lib/SecPassword.cpp
libsecurity_keychain/lib/SecPolicy.cpp
libsecurity_keychain/lib/SecPolicy.h
libsecurity_keychain/lib/SecPolicyPriv.h
libsecurity_keychain/lib/SecRSAKeyP.h
libsecurity_keychain/lib/SecRandom.c
libsecurity_keychain/lib/SecRecoveryPassword.c
libsecurity_keychain/lib/SecRecoveryPassword.h
libsecurity_keychain/lib/SecTrust.cpp
libsecurity_keychain/lib/SecTrust.h
libsecurity_keychain/lib/SecTrustPriv.h
libsecurity_keychain/lib/SecTrustSettings.cpp
libsecurity_keychain/lib/SecTrustedApplication.cpp
libsecurity_keychain/lib/SecTrustedApplication.h
libsecurity_keychain/lib/SecWrappedKeys.cpp
libsecurity_keychain/lib/Security.h
libsecurity_keychain/lib/StorageManager.cpp
libsecurity_keychain/lib/StorageManager.h
libsecurity_keychain/lib/Trust.cpp
libsecurity_keychain/lib/Trust.h
libsecurity_keychain/lib/TrustAdditions.cpp
libsecurity_keychain/lib/TrustKeychains.h
libsecurity_keychain/lib/TrustRevocation.cpp
libsecurity_keychain/lib/TrustSettings.cpp
libsecurity_keychain/lib/TrustSettingsUtils.cpp
libsecurity_keychain/lib/TrustSettingsUtils.h
libsecurity_keychain/lib/TrustStore.cpp
libsecurity_keychain/lib/TrustedApplication.cpp
libsecurity_keychain/lib/TrustedApplication.h
libsecurity_keychain/lib/cssmdatetime.cpp
libsecurity_keychain/lib/debuggingP.c [deleted file]
libsecurity_keychain/lib/debuggingP.h [deleted file]
libsecurity_keychain/lib/defaultcreds.cpp
libsecurity_keychain/lib/security_keychain.exp
libsecurity_keychain/libDER/config/base.xcconfig
libsecurity_keychain/libDER/config/debug.xcconfig
libsecurity_keychain/libDER/config/lib.xcconfig
libsecurity_keychain/libDER/config/release.xcconfig
libsecurity_keychain/libDER/libDER.xcodeproj/project.pbxproj
libsecurity_keychain/libDER/libDER/DER_Decode.c
libsecurity_keychain/libDER/libDER/oids.c
libsecurity_keychain/libDER/libDER/oids.h
libsecurity_keychain/libDER/libDERUtils/fileIo.c
libsecurity_keychain/libDER/libDERUtils/printFields.c
libsecurity_keychain/libDER/libDERUtils/printFields.h
libsecurity_keychain/libsecurity_keychain.xcodeproj/project.pbxproj
libsecurity_keychain/regressions/kc-40-seckey.c [new file with mode: 0644]
libsecurity_keychain/regressions/kc-41-sececkey.c [new file with mode: 0644]
libsecurity_keychain/regressions/keychain_regressions.h [new file with mode: 0644]
libsecurity_keychain/regressions/si-33-keychain-backup.c [new file with mode: 0644]
libsecurity_keychain/xpc/main.c
libsecurity_manifest/lib/AppleManifest.cpp
libsecurity_manifest/lib/Download.cpp
libsecurity_manifest/lib/ManifestInternal.cpp
libsecurity_manifest/lib/SecManifest.cpp
libsecurity_manifest/lib/SecureDownload.cpp
libsecurity_manifest/lib/SecureDownload.h
libsecurity_manifest/lib/SecureDownloadInternal.c
libsecurity_manifest/libsecurity_manifest.xcodeproj/project.pbxproj
libsecurity_mds/lib/MDSAttrParser.cpp
libsecurity_mds/lib/MDSAttrStrings.cpp
libsecurity_mds/lib/MDSDictionary.cpp
libsecurity_mds/lib/MDSModule.cpp
libsecurity_mds/lib/MDSSession.cpp
libsecurity_mds/lib/MDSSession.h
libsecurity_mds/libsecurity_mds.xcodeproj/project.pbxproj
libsecurity_ocspd/client/ocspdClient.cpp
libsecurity_ocspd/common/ocspResponse.cpp
libsecurity_ocspd/common/ocspdTypes.h
libsecurity_ocspd/common/ocspdUtils.cpp
libsecurity_ocspd/libsecurity_ocspd.xcodeproj/project.pbxproj
libsecurity_pkcs12/lib/SecPkcs12.cpp
libsecurity_pkcs12/lib/pkcs12BagAttrs.cpp
libsecurity_pkcs12/lib/pkcs12Coder.cpp
libsecurity_pkcs12/lib/pkcs12Encode.cpp
libsecurity_pkcs12/lib/pkcs12Keychain.cpp
libsecurity_pkcs12/lib/pkcs12SafeBag.cpp
libsecurity_pkcs12/lib/pkcs12Utils.cpp
libsecurity_pkcs12/lib/pkcs12Utils.h
libsecurity_pkcs12/libsecurity_pkcs12.xcodeproj/project.pbxproj
libsecurity_sd_cspdl/lib/SDCSPSession.cpp
libsecurity_sd_cspdl/lib/SDContext.cpp
libsecurity_sd_cspdl/lib/SDContext.h
libsecurity_sd_cspdl/lib/SDDLSession.cpp
libsecurity_sd_cspdl/lib/SDKey.cpp
libsecurity_sd_cspdl/lib/SDKey.h
libsecurity_sd_cspdl/libsecurity_sd_cspdl.xcodeproj/project.pbxproj
libsecurity_smime/lib/cert.c
libsecurity_smime/lib/cmsasn1.c
libsecurity_smime/lib/cmsattr.c
libsecurity_smime/lib/cmscipher.c
libsecurity_smime/lib/cmsdecode.c
libsecurity_smime/lib/cmsdigest.c
libsecurity_smime/lib/cmspubkey.c
libsecurity_smime/lib/cmsrecinfo.c
libsecurity_smime/lib/cmssigdata.c
libsecurity_smime/lib/cmssiginfo.c
libsecurity_smime/lib/cmsutil.c
libsecurity_smime/lib/secitem.c
libsecurity_smime/lib/secoid.c
libsecurity_smime/lib/smimeutil.c
libsecurity_smime/lib/tsaSupport.c
libsecurity_ssl/Security [new symlink]
libsecurity_ssl/Security/CipherSuite.h [deleted file]
libsecurity_ssl/Security/SecureTransport.h [deleted file]
libsecurity_ssl/Security/SecureTransportPriv.h [deleted file]
libsecurity_ssl/config/base.xcconfig
libsecurity_ssl/config/debug.xcconfig
libsecurity_ssl/config/kext.xcconfig [new file with mode: 0644]
libsecurity_ssl/config/lib.xcconfig
libsecurity_ssl/config/release.xcconfig
libsecurity_ssl/config/tests.xcconfig [new file with mode: 0644]
libsecurity_ssl/dtlsEcho/README [new file with mode: 0644]
libsecurity_ssl/dtlsEcho/dtlsEchoClient.c [new file with mode: 0644]
libsecurity_ssl/dtlsEcho/dtlsEchoServer.c [new file with mode: 0644]
libsecurity_ssl/lib/CipherSuite.h [new file with mode: 0644]
libsecurity_ssl/lib/SSLRecordInternal.c [new file with mode: 0644]
libsecurity_ssl/lib/SSLRecordInternal.h [new file with mode: 0644]
libsecurity_ssl/lib/SecureTransport.h [new file with mode: 0644]
libsecurity_ssl/lib/SecureTransportPriv.h [new file with mode: 0644]
libsecurity_ssl/lib/appleCdsa.c
libsecurity_ssl/lib/appleSession.c
libsecurity_ssl/lib/cipherSpecs.c
libsecurity_ssl/lib/cipherSpecs.h
libsecurity_ssl/lib/cryptType.h
libsecurity_ssl/lib/securetransport++.cpp
libsecurity_ssl/lib/security_ssl.exp
libsecurity_ssl/lib/ssl.h
libsecurity_ssl/lib/ssl3Callouts.c
libsecurity_ssl/lib/ssl3RecordCallouts.c [new file with mode: 0644]
libsecurity_ssl/lib/sslAlertMessage.c
libsecurity_ssl/lib/sslBER.c
libsecurity_ssl/lib/sslCert.c
libsecurity_ssl/lib/sslChangeCipher.c
libsecurity_ssl/lib/sslCipherSpecs.c [new file with mode: 0644]
libsecurity_ssl/lib/sslCipherSpecs.h [new file with mode: 0644]
libsecurity_ssl/lib/sslContext.c
libsecurity_ssl/lib/sslContext.h
libsecurity_ssl/lib/sslCrypto.c
libsecurity_ssl/lib/sslCrypto.h
libsecurity_ssl/lib/sslDebug.h
libsecurity_ssl/lib/sslDigests.c
libsecurity_ssl/lib/sslDigests.h
libsecurity_ssl/lib/sslHandshake.c
libsecurity_ssl/lib/sslHandshake.h
libsecurity_ssl/lib/sslHandshakeFinish.c
libsecurity_ssl/lib/sslHandshakeHello.c
libsecurity_ssl/lib/sslKeyExchange.c
libsecurity_ssl/lib/sslKeychain.c
libsecurity_ssl/lib/sslMemory.c
libsecurity_ssl/lib/sslMemory.h
libsecurity_ssl/lib/sslNullCipher.c
libsecurity_ssl/lib/sslPriv.h
libsecurity_ssl/lib/sslRand.c [new file with mode: 0644]
libsecurity_ssl/lib/sslRand.h [new file with mode: 0644]
libsecurity_ssl/lib/sslRecord.c
libsecurity_ssl/lib/sslRecord.h
libsecurity_ssl/lib/sslSession.c
libsecurity_ssl/lib/sslTransport.c
libsecurity_ssl/lib/sslTypes.h [new file with mode: 0644]
libsecurity_ssl/lib/sslUtils.c
libsecurity_ssl/lib/sslUtils.h
libsecurity_ssl/lib/symCipher.c
libsecurity_ssl/lib/symCipher.h
libsecurity_ssl/lib/symCipherParams.c [new file with mode: 0644]
libsecurity_ssl/lib/tls1Callouts.c
libsecurity_ssl/lib/tls1RecordCallouts.c [new file with mode: 0644]
libsecurity_ssl/lib/tls_digest.c [new file with mode: 0644]
libsecurity_ssl/lib/tls_digest.h [new file with mode: 0644]
libsecurity_ssl/lib/tls_hashhmac.c [new file with mode: 0644]
libsecurity_ssl/lib/tls_hashhmac.h [new file with mode: 0644]
libsecurity_ssl/lib/tls_hmac.c
libsecurity_ssl/lib/tls_hmac.h
libsecurity_ssl/lib/tls_record.h [new file with mode: 0644]
libsecurity_ssl/lib/tls_ssl.h
libsecurity_ssl/libsecurity_ssl.xcodeproj/project.pbxproj
libsecurity_ssl/regressions/ClientCert_ecc_ecc.h [new file with mode: 0644]
libsecurity_ssl/regressions/ClientCert_ecc_rsa.h [new file with mode: 0644]
libsecurity_ssl/regressions/ClientCert_rsa_ecc.h [new file with mode: 0644]
libsecurity_ssl/regressions/ClientCert_rsa_rsa.h [new file with mode: 0644]
libsecurity_ssl/regressions/ClientKey_ecc.h [new file with mode: 0644]
libsecurity_ssl/regressions/ClientKey_rsa.h [new file with mode: 0644]
libsecurity_ssl/regressions/SECG_ecc-secp256r1-client_cert.h [new file with mode: 0644]
libsecurity_ssl/regressions/SECG_ecc-secp256r1-client_key.h [new file with mode: 0644]
libsecurity_ssl/regressions/SECG_ecc_rsa-secp256r1-client_cert.h [new file with mode: 0644]
libsecurity_ssl/regressions/SECG_ecc_rsa-secp256r1-client_key.h [new file with mode: 0644]
libsecurity_ssl/regressions/cert-1.h [new file with mode: 0644]
libsecurity_ssl/regressions/gencerts.sh [new file with mode: 0755]
libsecurity_ssl/regressions/identity-1.h [new file with mode: 0644]
libsecurity_ssl/regressions/privkey-1.h [new file with mode: 0644]
libsecurity_ssl/regressions/ssl-39-echo.c [new file with mode: 0644]
libsecurity_ssl/regressions/ssl-40-clientauth.c [new file with mode: 0644]
libsecurity_ssl/regressions/ssl-41-clientauth.c [new file with mode: 0644]
libsecurity_ssl/regressions/ssl-42-ciphers.c [new file with mode: 0644]
libsecurity_ssl/regressions/ssl-43-ciphers.c [new file with mode: 0644]
libsecurity_ssl/regressions/ssl-44-crashes.c [new file with mode: 0644]
libsecurity_ssl/regressions/ssl-45-tls12.c [new file with mode: 0644]
libsecurity_ssl/regressions/ssl-46-SSLGetSupportedCiphers.c [new file with mode: 0644]
libsecurity_ssl/regressions/ssl-47-falsestart.c [new file with mode: 0644]
libsecurity_ssl/regressions/ssl-utils.c [new file with mode: 0644]
libsecurity_ssl/regressions/ssl-utils.h [new file with mode: 0644]
libsecurity_ssl/regressions/ssl_regressions.h [new file with mode: 0644]
libsecurity_ssl/sslViewer/ioSock.c
libsecurity_ssl/sslViewer/sslAppUtils.cpp
libsecurity_ssl/sslViewer/sslServer.cpp
libsecurity_ssl/sslViewer/sslViewer.cpp
libsecurity_transform/custom.mm
libsecurity_transform/lib/CEncryptDecrypt.c
libsecurity_transform/lib/Digest.cpp
libsecurity_transform/lib/Digest.h
libsecurity_transform/lib/EncodeDecodeTransforms.c
libsecurity_transform/lib/EncryptTransform.cpp
libsecurity_transform/lib/SecCustomTransform.cpp
libsecurity_transform/lib/SecSignVerifyTransform.c
libsecurity_transform/lib/SecTransformReadTransform.cpp
libsecurity_transform/lib/Transform.cpp
libsecurity_transform/lib/misc.c
libsecurity_transform/libsecurity_transform.xcodeproj/project.pbxproj
libsecurity_utilities/lib/adornments.h
libsecurity_utilities/lib/alloc.h
libsecurity_utilities/lib/blob.cpp
libsecurity_utilities/lib/blob.h
libsecurity_utilities/lib/cfclass.cpp
libsecurity_utilities/lib/cfmach++.cpp
libsecurity_utilities/lib/cfmunge.cpp
libsecurity_utilities/lib/cfutilities.cpp
libsecurity_utilities/lib/cfutilities.h
libsecurity_utilities/lib/debugging.cpp
libsecurity_utilities/lib/debugging.h
libsecurity_utilities/lib/debugging_internal.cpp [new file with mode: 0644]
libsecurity_utilities/lib/debugging_internal.h [new file with mode: 0644]
libsecurity_utilities/lib/debugsupport.h
libsecurity_utilities/lib/dyldcache.cpp
libsecurity_utilities/lib/endian.h
libsecurity_utilities/lib/errors.cpp
libsecurity_utilities/lib/errors.h
libsecurity_utilities/lib/exports [new file with mode: 0644]
libsecurity_utilities/lib/fdmover.cpp
libsecurity_utilities/lib/globalizer.cpp
libsecurity_utilities/lib/globalizer.h
libsecurity_utilities/lib/hashing.h
libsecurity_utilities/lib/inetreply.cpp
libsecurity_utilities/lib/kq++.h
libsecurity_utilities/lib/mach++.cpp
libsecurity_utilities/lib/mach++.h
libsecurity_utilities/lib/macho++.cpp
libsecurity_utilities/lib/macho++.h
libsecurity_utilities/lib/machrunloopserver.cpp
libsecurity_utilities/lib/machrunloopserver.h
libsecurity_utilities/lib/machserver.cpp
libsecurity_utilities/lib/machserver.h
libsecurity_utilities/lib/memstreams.h
libsecurity_utilities/lib/muscle++.cpp
libsecurity_utilities/lib/osxcode.cpp
libsecurity_utilities/lib/pcsc++.cpp
libsecurity_utilities/lib/pcsc++.h
libsecurity_utilities/lib/powerwatch.cpp
libsecurity_utilities/lib/powerwatch.h
libsecurity_utilities/lib/refcount.h
libsecurity_utilities/lib/seccfobject.cpp
libsecurity_utilities/lib/seccfobject.h
libsecurity_utilities/lib/sqlite++.cpp
libsecurity_utilities/lib/sqlite++.h
libsecurity_utilities/lib/superblob.h
libsecurity_utilities/lib/threading.cpp
libsecurity_utilities/lib/threading_internal.h
libsecurity_utilities/lib/unix++.cpp
libsecurity_utilities/lib/unix++.h
libsecurity_utilities/lib/vproc++.cpp
libsecurity_utilities/libsecurity_utilities.xcodeproj/project.pbxproj
libsecurityd/lib/SharedMemoryClient.cpp
libsecurityd/lib/dictionary.cpp
libsecurityd/lib/dictionary.h
libsecurityd/lib/sec_xdr.c
libsecurityd/lib/sec_xdr_array.c
libsecurityd/lib/sec_xdr_reference.c
libsecurityd/lib/sec_xdr_sizeof.c
libsecurityd/lib/ssblob.h
libsecurityd/lib/ssclient.cpp
libsecurityd/lib/ssclient.h
libsecurityd/lib/sstransit.cpp
libsecurityd/lib/sstransit.h
libsecurityd/lib/transition.cpp
libsecurityd/lib/xdr_auth.c
libsecurityd/lib/xdr_cssm.c
libsecurityd/lib/xdr_dldb.h
libsecurityd/libsecurityd.xcodeproj/project.pbxproj
libsecurityd/mig/ucsp.defs
regressions/README [new file with mode: 0644]
regressions/inc/IPC/Run3.pm [new file with mode: 0644]
regressions/inc/MyHarness.pm [new file with mode: 0644]
regressions/regressions.xcodeproj/project.pbxproj [new file with mode: 0644]
regressions/t/security.pl [new file with mode: 0755]
regressions/test/run_tests.sh [new file with mode: 0755]
regressions/test/test-00-test.c [new file with mode: 0644]
regressions/test/test_regressions.h [new file with mode: 0644]
regressions/test/testcert.c [new file with mode: 0644]
regressions/test/testcert.h [new file with mode: 0644]
regressions/test/testcpp.h [new file with mode: 0644]
regressions/test/testenv.c [new file with mode: 0644]
regressions/test/testenv.h [new file with mode: 0644]
regressions/test/testlist_begin.h [new file with mode: 0644]
regressions/test/testlist_end.h [new file with mode: 0644]
regressions/test/testmore.c [new file with mode: 0644]
regressions/test/testmore.h [new file with mode: 0644]
regressions/test/testpolicy.h [new file with mode: 0644]
regressions/test/testpolicy.m [new file with mode: 0644]
sec/CloudKeychainProxy/CloudKeychainProxy.1 [new file with mode: 0644]
sec/SOSCircle/CKBridge/CKClient.c [new file with mode: 0644]
sec/SOSCircle/CKBridge/CKClient.h [new file with mode: 0644]
sec/SOSCircle/CKBridge/SOSCloudKeychainClient.c [new file with mode: 0644]
sec/SOSCircle/CKBridge/SOSCloudKeychainClient.h [new file with mode: 0644]
sec/SOSCircle/CKBridge/SOSCloudKeychainConstants.c [new file with mode: 0644]
sec/SOSCircle/CKBridge/SOSCloudKeychainConstants.h [new file with mode: 0644]
sec/SOSCircle/CKBridge/SOSCloudTransport.c [new file with mode: 0644]
sec/SOSCircle/CKBridge/SOSCloudTransport.h [new file with mode: 0644]
sec/SOSCircle/CloudKeychainProxy/CKDKVSProxy.h [new file with mode: 0644]
sec/SOSCircle/CloudKeychainProxy/CKDKVSProxy.m [new file with mode: 0644]
sec/SOSCircle/CloudKeychainProxy/CKDPersistentState.h [new file with mode: 0644]
sec/SOSCircle/CloudKeychainProxy/CKDPersistentState.m [new file with mode: 0644]
sec/SOSCircle/CloudKeychainProxy/CKDUserInteraction.h [new file with mode: 0644]
sec/SOSCircle/CloudKeychainProxy/CKDUserInteraction.m [new file with mode: 0644]
sec/SOSCircle/CloudKeychainProxy/ckdmain.m [new file with mode: 0644]
sec/SOSCircle/CloudKeychainProxy/cloudkeychain.entitlements.plist [new file with mode: 0644]
sec/SOSCircle/CloudKeychainProxy/cloudkeychainproxy.m [new file with mode: 0644]
sec/SOSCircle/CloudKeychainProxy/en.lproj/InfoPlist.strings [new file with mode: 0644]
sec/SOSCircle/CloudKeychainProxy/scripts/PhoneTerms2.scpt [new file with mode: 0644]
sec/SOSCircle/CloudKeychainProxy/scripts/install_on_devices [new file with mode: 0755]
sec/SOSCircle/CloudKeychainProxy/scripts/sosbuildroot [new file with mode: 0755]
sec/SOSCircle/CloudKeychainProxy/scripts/soscopy [new file with mode: 0755]
sec/SOSCircle/CloudKeychainProxy/scripts/soscopysshkeys [new file with mode: 0755]
sec/SOSCircle/CloudKeychainProxy/scripts/sosinstallroot [new file with mode: 0644]
sec/SOSCircle/CloudKeychainProxy/scripts/sosreset [new file with mode: 0644]
sec/SOSCircle/CloudKeychainProxy/scripts/sshauser [new file with mode: 0755]
sec/SOSCircle/Empty.c [new file with mode: 0644]
sec/SOSCircle/Regressions/CKDKeyValueStore.h [new file with mode: 0644]
sec/SOSCircle/Regressions/CKDKeyValueStore.m [new file with mode: 0644]
sec/SOSCircle/Regressions/SOSCircle_regressions.h [new file with mode: 0644]
sec/SOSCircle/Regressions/SOSRegressionUtilities.c [new file with mode: 0644]
sec/SOSCircle/Regressions/SOSRegressionUtilities.h [new file with mode: 0644]
sec/SOSCircle/Regressions/SOSTestDataSource.c [new file with mode: 0644]
sec/SOSCircle/Regressions/SOSTestDataSource.h [new file with mode: 0644]
sec/SOSCircle/Regressions/SOSTestTransport.c [new file with mode: 0644]
sec/SOSCircle/Regressions/SOSTestTransport.h [new file with mode: 0644]
sec/SOSCircle/Regressions/sc-100-devicecircle.c [new file with mode: 0644]
sec/SOSCircle/Regressions/sc-101-accountsync.c [new file with mode: 0644]
sec/SOSCircle/Regressions/sc-102-cfusernotification.c [new file with mode: 0644]
sec/SOSCircle/Regressions/sc-103-syncupdate.c [new file with mode: 0644]
sec/SOSCircle/Regressions/sc-120-cloudcircle.c [new file with mode: 0644]
sec/SOSCircle/Regressions/sc-130-resignationticket.c [new file with mode: 0644]
sec/SOSCircle/Regressions/sc-20-keynames.c [new file with mode: 0644]
sec/SOSCircle/Regressions/sc-30-peerinfo.c [new file with mode: 0644]
sec/SOSCircle/Regressions/sc-40-circle.c [new file with mode: 0644]
sec/SOSCircle/Regressions/sc-41-cloudcircle.c [new file with mode: 0644]
sec/SOSCircle/Regressions/sc-51-persistentEC.c [new file with mode: 0644]
sec/SOSCircle/Regressions/sc-60-peer.c [new file with mode: 0644]
sec/SOSCircle/Regressions/sc-70-engine.c [new file with mode: 0644]
sec/SOSCircle/Regressions/sc-75-circle-engine.c [new file with mode: 0644]
sec/SOSCircle/Regressions/sc-90-ckdclient.c [new file with mode: 0644]
sec/SOSCircle/Regressions/sc-95-ckd2client.c [new file with mode: 0644]
sec/SOSCircle/Regressions/sc-kvstool.m [new file with mode: 0644]
sec/SOSCircle/SOSARCDefines.h [new file with mode: 0644]
sec/SOSCircle/SecureObjectSync/Imported/SOSCloudCircleServer.h [new symlink]
sec/SOSCircle/SecureObjectSync/Imported/SecItemServer.h [new symlink]
sec/SOSCircle/SecureObjectSync/Imported/SecuritydXPC.h [new symlink]
sec/SOSCircle/SecureObjectSync/Imported/securityd_client.h [new symlink]
sec/SOSCircle/SecureObjectSync/Imported/spi.h [new symlink]
sec/SOSCircle/SecureObjectSync/SOSAccount.c [new file with mode: 0644]
sec/SOSCircle/SecureObjectSync/SOSAccount.h [new file with mode: 0644]
sec/SOSCircle/SecureObjectSync/SOSCircle.c [new file with mode: 0644]
sec/SOSCircle/SecureObjectSync/SOSCircle.h [new file with mode: 0644]
sec/SOSCircle/SecureObjectSync/SOSCloudCircle.c [new file with mode: 0644]
sec/SOSCircle/SecureObjectSync/SOSCloudCircle.h [new file with mode: 0644]
sec/SOSCircle/SecureObjectSync/SOSCloudCircleInternal.h [new file with mode: 0644]
sec/SOSCircle/SecureObjectSync/SOSCoder.c [new file with mode: 0644]
sec/SOSCircle/SecureObjectSync/SOSCoder.h [new file with mode: 0644]
sec/SOSCircle/SecureObjectSync/SOSEngine.c [new file with mode: 0644]
sec/SOSCircle/SecureObjectSync/SOSEngine.h [new file with mode: 0644]
sec/SOSCircle/SecureObjectSync/SOSExports.exp-in [new file with mode: 0644]
sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.c [new file with mode: 0644]
sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.h [new file with mode: 0644]
sec/SOSCircle/SecureObjectSync/SOSInternal.c [new file with mode: 0644]
sec/SOSCircle/SecureObjectSync/SOSInternal.h [new file with mode: 0644]
sec/SOSCircle/SecureObjectSync/SOSPeer.c [new file with mode: 0644]
sec/SOSCircle/SecureObjectSync/SOSPeer.h [new file with mode: 0644]
sec/SOSCircle/SecureObjectSync/SOSPeerInfo.c [new file with mode: 0644]
sec/SOSCircle/SecureObjectSync/SOSPeerInfo.h [new file with mode: 0644]
sec/SOSCircle/SecureObjectSync/SOSPeerInfoInternal.h [new file with mode: 0644]
sec/SOSCircle/SecureObjectSync/SOSTransport.c [new file with mode: 0644]
sec/SOSCircle/SecureObjectSync/SOSTransport.h [new file with mode: 0644]
sec/SOSCircle/SecureObjectSync/SOSUserKey.c [new file with mode: 0644]
sec/SOSCircle/SecureObjectSync/SOSUserKey.h [new file with mode: 0644]
sec/SOSCircle/SecureObjectSync/SOSUserKeygen.c [new file with mode: 0644]
sec/SOSCircle/SecureObjectSync/SOSUserKeygen.h [new file with mode: 0644]
sec/SOSCircle/Tool/SOSCommands.h [new file with mode: 0644]
sec/SOSCircle/Tool/keychain_sync.c [new file with mode: 0644]
sec/SOSCircle/osxshim.c [new file with mode: 0644]
sec/Security/AppleBaselineEscrowCertificates.h [new file with mode: 0644]
sec/Security/AuthorizationStatus.h [new file with mode: 0644]
sec/Security/Regressions/Security_regressions.h [new file with mode: 0644]
sec/Security/Regressions/crypto/pbkdf2-00-hmac-sha1.c [new file with mode: 0644]
sec/Security/Regressions/crypto/spbkdf-00-hmac-sha1.c [new file with mode: 0644]
sec/Security/Regressions/otr/otr-00-identity.c [new file with mode: 0644]
sec/Security/Regressions/otr/otr-30-negotiation.c [new file with mode: 0644]
sec/Security/Regressions/otr/otr-otrdh.c [new file with mode: 0644]
sec/Security/Regressions/otr/otr-packetdata.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-00-find-nothing.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-05-add.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-10-find-internet.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-11-update-data.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-12-item-stress.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-14-dateparse.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-15-certificate.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-16-ec-certificate.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-20-sectrust-activation.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-20-sectrust.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-21-sectrust-asr.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-22-sectrust-iap.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-23-sectrust-ocsp-wwdr.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-23-sectrust-ocsp.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-24-sectrust-appleid.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-24-sectrust-digicert-malaysia.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-24-sectrust-diginotar.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-24-sectrust-itms.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-24-sectrust-mobileasset.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-24-sectrust-nist.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-24-sectrust-otatasking.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-24-sectrust-shoebox.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-25-sectrust-ipsec-eap.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-26-applicationsigning.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-27-sectrust-exceptions.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-28-sectrustsettings.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-29-sectrust-codesigning.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-30-keychain-upgrade.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-31-keychain-bad.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-31-keychain-unreadable.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-33-keychain-backup.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-40-seckey-custom.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-40-seckey.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-41-sececkey.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-42-identity.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-43-persistent.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-50-secrandom.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-60-cms.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-61-pkcs12.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-62-csr.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-63-scep.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-63-scep.h [new file with mode: 0644]
sec/Security/Regressions/secitem/si-63-scep/getcacert-mdes.h [new file with mode: 0644]
sec/Security/Regressions/secitem/si-63-scep/getcacert-mdesqa.h [new file with mode: 0644]
sec/Security/Regressions/secitem/si-64-ossl-cms.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-64-ossl-cms/attached_no_data_signed_data.h [new file with mode: 0644]
sec/Security/Regressions/secitem/si-64-ossl-cms/attached_signed_data.h [new file with mode: 0644]
sec/Security/Regressions/secitem/si-64-ossl-cms/detached_content.h [new file with mode: 0644]
sec/Security/Regressions/secitem/si-64-ossl-cms/detached_signed_data.h [new file with mode: 0644]
sec/Security/Regressions/secitem/si-64-ossl-cms/privkey.h [new file with mode: 0644]
sec/Security/Regressions/secitem/si-64-ossl-cms/signer.h [new file with mode: 0644]
sec/Security/Regressions/secitem/si-65-cms-cert-policy.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-66-smime.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-66-smime/signed-receipt.h [new file with mode: 0644]
sec/Security/Regressions/secitem/si-67-sectrust-blacklist.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-67-sectrust-blacklist/Global Trustee.cer.h [new file with mode: 0644]
sec/Security/Regressions/secitem/si-67-sectrust-blacklist/UTN-USERFirst-Hardware.cer.h [new file with mode: 0644]
sec/Security/Regressions/secitem/si-67-sectrust-blacklist/addons.mozilla.org.cer.h [new file with mode: 0644]
sec/Security/Regressions/secitem/si-67-sectrust-blacklist/login.live.com.cer.h [new file with mode: 0644]
sec/Security/Regressions/secitem/si-67-sectrust-blacklist/login.skype.com.cer.h [new file with mode: 0644]
sec/Security/Regressions/secitem/si-67-sectrust-blacklist/login.yahoo.com.1.cer.h [new file with mode: 0644]
sec/Security/Regressions/secitem/si-67-sectrust-blacklist/login.yahoo.com.2.cer.h [new file with mode: 0644]
sec/Security/Regressions/secitem/si-67-sectrust-blacklist/login.yahoo.com.cer.h [new file with mode: 0644]
sec/Security/Regressions/secitem/si-67-sectrust-blacklist/mail.google.com.cer.h [new file with mode: 0644]
sec/Security/Regressions/secitem/si-67-sectrust-blacklist/www.google.com.cer.h [new file with mode: 0644]
sec/Security/Regressions/secitem/si-68-secmatchissuer.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-69-keydesc.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-70-sectrust-unified.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-71-mobile-store-policy.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-72-syncableitems.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-73-secpasswordgenerate.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-74-OTAPKISigner.c [new file with mode: 0644]
sec/Security/Regressions/secitem/si-75-AppleIDRecordSigning.c [new file with mode: 0644]
sec/Security/Regressions/vmdh/vmdh-40.c [new file with mode: 0644]
sec/Security/Regressions/vmdh/vmdh-41-example.c [new file with mode: 0644]
sec/Security/Regressions/vmdh/vmdh-42-example2.c [new file with mode: 0644]
sec/Security/SecBase.h
sec/Security/SecBasePriv.h
sec/Security/SecCMS.c
sec/Security/SecCMS.h
sec/Security/SecCertificate.c
sec/Security/SecCertificate.h
sec/Security/SecCertificateInternal.h
sec/Security/SecCertificatePath.c
sec/Security/SecCertificatePath.h
sec/Security/SecCertificatePriv.h
sec/Security/SecCertificateRequest.c
sec/Security/SecCertificateRequest.h
sec/Security/SecDH.c
sec/Security/SecDH.h
sec/Security/SecECKey.c
sec/Security/SecECKey.h
sec/Security/SecExports.exp-in [new file with mode: 0644]
sec/Security/SecFramework.c
sec/Security/SecFramework.h
sec/Security/SecFrameworkStrings.h
sec/Security/SecIdentity.c
sec/Security/SecIdentity.h
sec/Security/SecIdentityPriv.h
sec/Security/SecImportExport.c
sec/Security/SecImportExport.h
sec/Security/SecInternal.h
sec/Security/SecItem.c
sec/Security/SecItem.h
sec/Security/SecItemConstants.c
sec/Security/SecItemInternal.h
sec/Security/SecItemPriv.h
sec/Security/SecKey.c
sec/Security/SecKey.h
sec/Security/SecKeyInternal.h
sec/Security/SecKeyPriv.h
sec/Security/SecOTR.h [new file with mode: 0644]
sec/Security/SecOTRDHKey.c [new file with mode: 0644]
sec/Security/SecOTRDHKey.h [new file with mode: 0644]
sec/Security/SecOTRErrors.h [new file with mode: 0644]
sec/Security/SecOTRFullIdentity.c [new file with mode: 0644]
sec/Security/SecOTRIdentityPriv.h [new file with mode: 0644]
sec/Security/SecOTRMath.c [new file with mode: 0644]
sec/Security/SecOTRMath.h [new file with mode: 0644]
sec/Security/SecOTRMathPrivate.h [new file with mode: 0644]
sec/Security/SecOTRPacketData.c [new file with mode: 0644]
sec/Security/SecOTRPacketData.h [new file with mode: 0644]
sec/Security/SecOTRPackets.c [new file with mode: 0644]
sec/Security/SecOTRPackets.h [new file with mode: 0644]
sec/Security/SecOTRPublicIdentity.c [new file with mode: 0644]
sec/Security/SecOTRSession.c [new file with mode: 0644]
sec/Security/SecOTRSession.h [new file with mode: 0644]
sec/Security/SecOTRSessionAKE.c [new file with mode: 0644]
sec/Security/SecOTRSessionPriv.h [new file with mode: 0644]
sec/Security/SecOTRUtils.c [new file with mode: 0644]
sec/Security/SecOnOSX.h [new file with mode: 0644]
sec/Security/SecPasswordGenerate.c [new file with mode: 0644]
sec/Security/SecPasswordGenerate.h [new file with mode: 0644]
sec/Security/SecPolicy.c
sec/Security/SecPolicy.h
sec/Security/SecPolicyInternal.h
sec/Security/SecPolicyPriv.h
sec/Security/SecRSAKey.c
sec/Security/SecRSAKey.h
sec/Security/SecRSAKeyPriv.h
sec/Security/SecRandom.h
sec/Security/SecSCEP.c
sec/Security/SecSCEP.h
sec/Security/SecTrust.c
sec/Security/SecTrust.h
sec/Security/SecTrustPriv.h
sec/Security/SecTrustSettings.c
sec/Security/SecTrustStore.c
sec/Security/SecTrustStore.h
sec/Security/Security.h
sec/Security/SecuritydXPC.c [new file with mode: 0644]
sec/Security/SecuritydXPC.h [new file with mode: 0644]
sec/Security/Tool/SecurityCommands.h [new file with mode: 0644]
sec/Security/Tool/add_internet_password.c [new file with mode: 0644]
sec/Security/Tool/codesign.c [new file with mode: 0644]
sec/Security/Tool/keychain_add.c [new file with mode: 0644]
sec/Security/Tool/keychain_backup.c [new file with mode: 0644]
sec/Security/Tool/keychain_find.c [new file with mode: 0644]
sec/Security/Tool/pkcs12_util.c [new file with mode: 0644]
sec/Security/Tool/scep.c [new file with mode: 0644]
sec/Security/Tool/show_certificates.c [new file with mode: 0644]
sec/Security/Tool/spc.c [new file with mode: 0644]
sec/Security/cssmapple.h [new file with mode: 0644]
sec/Security/keychain_find.h [new file with mode: 0644]
sec/Security/p12import.c
sec/Security/p12import.h
sec/Security/p12pbegen.c
sec/Security/pbkdf2.c
sec/Security/pbkdf2.h
sec/Security/vmdh.c
sec/SecurityTool/SecurityTool.c [new file with mode: 0644]
sec/SecurityTool/SecurityTool.h [new file with mode: 0644]
sec/SecurityTool/builtin_commands.h [new file with mode: 0644]
sec/SecurityTool/digest_calc.c [new file with mode: 0644]
sec/SecurityTool/entitlements.plist [new file with mode: 0644]
sec/SecurityTool/leaks.c [new file with mode: 0644]
sec/SecurityTool/leaks.h [new file with mode: 0644]
sec/SecurityTool/print_cert.c [new file with mode: 0644]
sec/SecurityTool/print_cert.h [new file with mode: 0644]
sec/SecurityTool/security.1 [new file with mode: 0644]
sec/SecurityTool/tool_errors.h [new file with mode: 0644]
sec/config/base.xcconfig
sec/config/debug.xcconfig
sec/config/lib-arc-only.xcconfig [new file with mode: 0644]
sec/config/lib.xcconfig
sec/config/release.xcconfig
sec/ipc/client.c
sec/ipc/com.apple.secd.plist
sec/ipc/com.apple.securityd.plist
sec/ipc/securityd_client.h [changed mode: 0644->0755]
sec/ipc/securityd_ipc_types.h [deleted file]
sec/ipc/securityd_rep.defs [deleted file]
sec/ipc/securityd_req.defs [deleted file]
sec/ipc/securityd_server.h [deleted file]
sec/ipc/server.c
sec/sec.xcodeproj/project.pbxproj
sec/securityd/OTATrustUtilities.c [new file with mode: 0644]
sec/securityd/OTATrustUtilities.h [new file with mode: 0644]
sec/securityd/Regressions/SOSAccountTesting.h [new file with mode: 0644]
sec/securityd/Regressions/SecdTestKeychainUtilities.c [new file with mode: 0644]
sec/securityd/Regressions/SecdTestKeychainUtilities.h [new file with mode: 0644]
sec/securityd/Regressions/sd-10-policytree.c [new file with mode: 0644]
sec/securityd/Regressions/sd-70-engine.c [new file with mode: 0644]
sec/securityd/Regressions/secd-01-items.c [new file with mode: 0644]
sec/securityd/Regressions/secd-02-upgrade-while-locked.c [new file with mode: 0644]
sec/securityd/Regressions/secd-03-corrupted-items.c [new file with mode: 0644]
sec/securityd/Regressions/secd-04-corrupted-items.c [new file with mode: 0644]
sec/securityd/Regressions/secd-05-corrupted-items.c [new file with mode: 0644]
sec/securityd/Regressions/secd-30-keychain-upgrade.c [new file with mode: 0644]
sec/securityd/Regressions/secd-31-keychain-bad.c [new file with mode: 0644]
sec/securityd/Regressions/secd-31-keychain-unreadable.c [new file with mode: 0644]
sec/securityd/Regressions/secd-50-account.c [new file with mode: 0644]
sec/securityd/Regressions/secd-51-account-inflate.c [new file with mode: 0644]
sec/securityd/Regressions/secd-52-account-changed.c [new file with mode: 0644]
sec/securityd/Regressions/secd-55-account-circle.c [new file with mode: 0644]
sec/securityd/Regressions/secd-55-account-incompatibility.c [new file with mode: 0644]
sec/securityd/Regressions/secd-56-account-apply.c [new file with mode: 0644]
sec/securityd/Regressions/secd-57-account-leave.c [new file with mode: 0644]
sec/securityd/Regressions/secd-58-password-change.c [new file with mode: 0644]
sec/securityd/Regressions/secd-59-account-cleanup.c [new file with mode: 0644]
sec/securityd/Regressions/secd-60-account-cloud-identity.c [new file with mode: 0644]
sec/securityd/Regressions/secd-61-account-leave-not-in-kansas-anymore.c [new file with mode: 0644]
sec/securityd/Regressions/secd_regressions.h [new file with mode: 0644]
sec/securityd/Regressions/securityd_regressions.h [new file with mode: 0644]
sec/securityd/SOSCloudCircleServer.c [new file with mode: 0644]
sec/securityd/SOSCloudCircleServer.h [new file with mode: 0644]
sec/securityd/SecCAIssuerCache.c
sec/securityd/SecCAIssuerCache.h
sec/securityd/SecCAIssuerRequest.c
sec/securityd/SecCAIssuerRequest.h
sec/securityd/SecDbItem.c [new file with mode: 0644]
sec/securityd/SecDbItem.h [new file with mode: 0644]
sec/securityd/SecItemServer.c
sec/securityd/SecItemServer.h
sec/securityd/SecOCSPCache.c
sec/securityd/SecOCSPCache.h
sec/securityd/SecOCSPRequest.c
sec/securityd/SecOCSPRequest.h
sec/securityd/SecOCSPResponse.c
sec/securityd/SecOCSPResponse.h
sec/securityd/SecPolicyServer.c
sec/securityd/SecPolicyServer.h
sec/securityd/SecTrustServer.c
sec/securityd/SecTrustServer.h
sec/securityd/SecTrustStoreServer.c
sec/securityd/SecTrustStoreServer.h
sec/securityd/asynchttp.c
sec/securityd/asynchttp.h
sec/securityd/entitlements.plist
sec/securityd/keystore.c [deleted file]
sec/securityd/keystore.h [deleted file]
sec/securityd/policytree.c
sec/securityd/policytree.h
sec/securityd/spi.c
sec/securityd/spi.h
secdtests/main.c [new file with mode: 0644]
secdtests/testlist.h [new file with mode: 0644]
sectests/SecurityTests-Entitlements.plist [new file with mode: 0644]
sectests/main.c [new file with mode: 0644]
sectests/test/testenv.c [new file with mode: 0644]
sectests/testlist.h [new file with mode: 0644]
security2/security2.1 [new file with mode: 0644]
security2/security_tool_commands.c [new file with mode: 0644]
security2/sub_commands.h [new file with mode: 0644]
security_utilities/debugging.c [deleted file]
security_utilities/debugging.h [deleted file]
security_utilities/fileIo.c [deleted file]
security_utilities/fileIo.h [deleted file]
security_utilities/sqlutils.h [deleted file]
tlsnke/loadkext.sh [new file with mode: 0755]
tlsnke/tlsnke.xcodeproj/project.pbxproj [new file with mode: 0644]
tlsnke/tlsnke.xcodeproj/project.xcworkspace/contents.xcworkspacedata [new file with mode: 0644]
tlsnke/tlsnke.xcodeproj/xcshareddata/xcschemes/Device.xcscheme [new file with mode: 0644]
tlsnke/tlsnke.xcodeproj/xcshareddata/xcschemes/Host.xcscheme [new file with mode: 0644]
tlsnke/tlsnke.xcodeproj/xcshareddata/xcschemes/tlsnke.xcscheme [new file with mode: 0644]
tlsnke/tlsnke.xcodeproj/xcshareddata/xcschemes/tlsnketest.xcscheme [new file with mode: 0644]
tlsnke/tlsnke.xcodeproj/xcuserdata/fabrice.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist [new file with mode: 0644]
tlsnke/tlsnke/en.lproj/InfoPlist.strings [new file with mode: 0644]
tlsnke/tlsnke/tlsnke-Info.plist [new file with mode: 0644]
tlsnke/tlsnke/tlsnke-Prefix.pch [new file with mode: 0644]
tlsnke/tlsnke/tlsnke.c [new file with mode: 0644]
tlsnke/tlsnke/tlsnke.h [new file with mode: 0644]
tlsnke/tlsnketest/cert-1.h [new file with mode: 0644]
tlsnke/tlsnketest/dtls_client.c [new file with mode: 0644]
tlsnke/tlsnketest/identity-1.h [new file with mode: 0644]
tlsnke/tlsnketest/main.c [new file with mode: 0644]
tlsnke/tlsnketest/privkey-1.h [new file with mode: 0644]
tlsnke/tlsnketest/ssl-utils.c [new file with mode: 0644]
tlsnke/tlsnketest/ssl-utils.h [new file with mode: 0644]
tlsnke/tlsnketest/st_test.c [new file with mode: 0644]
tlsnke/tlsnketest/tlssocket.c [new file with mode: 0644]
tlsnke/tlsnketest/tlssocket.h [new file with mode: 0644]
utilities/Regressions/su-10-cfstring-der.c [new file with mode: 0644]
utilities/Regressions/su-11-cfdata-der.c [new file with mode: 0644]
utilities/Regressions/su-12-cfboolean-der.c [new file with mode: 0644]
utilities/Regressions/su-13-cfnumber-der.c [new file with mode: 0644]
utilities/Regressions/su-14-cfarray-der.c [new file with mode: 0644]
utilities/Regressions/su-15-cfdictionary-der.c [new file with mode: 0644]
utilities/Regressions/su-16-cfdate-der.c [new file with mode: 0644]
utilities/Regressions/su-40-secdb.c [new file with mode: 0644]
utilities/Regressions/su-41-secdb-stress.c [new file with mode: 0644]
utilities/Regressions/utilities_regressions.h [new file with mode: 0644]
utilities/SecurityTool/not_on_this_platorm.c [new file with mode: 0644]
utilities/SecurityTool/readline.c [new file with mode: 0644]
utilities/SecurityTool/readline.h [new file with mode: 0644]
utilities/SecurityTool/security_tool_commands.h [new file with mode: 0644]
utilities/SecurityTool/security_tool_commands_table.h [new file with mode: 0644]
utilities/src/SecAKSWrappers.c [new file with mode: 0644]
utilities/src/SecAKSWrappers.h [new file with mode: 0644]
utilities/src/SecCFCanonicalHashes.c [new file with mode: 0644]
utilities/src/SecCFCanonicalHashes.h [new file with mode: 0644]
utilities/src/SecCFError.c [new file with mode: 0644]
utilities/src/SecCFError.h [new file with mode: 0644]
utilities/src/SecCFRelease.h [new file with mode: 0644]
utilities/src/SecCFWrappers.c [new file with mode: 0644]
utilities/src/SecCFWrappers.h [new file with mode: 0644]
utilities/src/SecDb.c [new file with mode: 0644]
utilities/src/SecDb.h [new file with mode: 0644]
utilities/src/SecDispatchRelease.h [new file with mode: 0644]
utilities/src/SecFileLocations.c [new file with mode: 0644]
utilities/src/SecFileLocations.h [new file with mode: 0644]
utilities/src/SecIOFormat.h [new file with mode: 0644]
utilities/src/SecXPCError.c [new file with mode: 0644]
utilities/src/SecXPCError.h [new file with mode: 0644]
utilities/src/array_size.h [new file with mode: 0644]
utilities/src/cloud_keychain_diagnose.c [new file with mode: 0644]
utilities/src/comparison.c [new file with mode: 0644]
utilities/src/comparison.h [new file with mode: 0644]
utilities/src/debugging.c [new file with mode: 0644]
utilities/src/debugging.h [new file with mode: 0644]
utilities/src/der_array.c [new file with mode: 0644]
utilities/src/der_boolean.c [new file with mode: 0644]
utilities/src/der_data.c [new file with mode: 0644]
utilities/src/der_date.c [new file with mode: 0644]
utilities/src/der_date.h [new file with mode: 0644]
utilities/src/der_dictionary.c [new file with mode: 0644]
utilities/src/der_null.c [new file with mode: 0644]
utilities/src/der_number.c [new file with mode: 0644]
utilities/src/der_plist.c [new file with mode: 0644]
utilities/src/der_plist.h [new file with mode: 0644]
utilities/src/der_plist_internal.c [new file with mode: 0644]
utilities/src/der_plist_internal.h [new file with mode: 0644]
utilities/src/der_string.c [new file with mode: 0644]
utilities/src/fileIo.c [new file with mode: 0644]
utilities/src/fileIo.h [new file with mode: 0644]
utilities/src/iCloudKeychainTrace.c [new file with mode: 0644]
utilities/src/iCloudKeychainTrace.h [new file with mode: 0644]
utilities/src/iOSforOSX-SecAttr.c [new file with mode: 0644]
utilities/src/iOSforOSX-SecRandom.c [new file with mode: 0644]
utilities/src/iOSforOSX.c [new file with mode: 0644]
utilities/src/iOSforOSX.h [new file with mode: 0644]
utilities/src/sqlutils.h [new file with mode: 0644]
utilities/utilities [new symlink]
utilities/utilities.xcodeproj/project.pbxproj [new file with mode: 0644]

diff --git a/CloudKeychainProxy/CloudKeychainProxy-Info.plist b/CloudKeychainProxy/CloudKeychainProxy-Info.plist
new file mode 100644 (file)
index 0000000..4f0ecf8
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>English</string>
+       <key>CFBundleExecutable</key>
+       <string>${EXECUTABLE_NAME}</string>
+       <key>CFBundleIconFile</key>
+       <string></string>
+       <key>CFBundleIdentifier</key>
+       <string>com.apple.security.cloudkeychainproxy3</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundleName</key>
+       <string>${PRODUCT_NAME}</string>
+       <key>CFBundlePackageType</key>
+       <string>BNDL</string>
+       <key>CFBundleShortVersionString</key>
+       <string>1.0</string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>55471</string>
+       <key>NSHumanReadableCopyright</key>
+       <string>Copyright © 2013 Apple, Inc. All rights reserved.</string>
+</dict>
+</plist>
diff --git a/CloudKeychainProxy/cloudkeychain.entitlements.plist b/CloudKeychainProxy/cloudkeychain.entitlements.plist
new file mode 100644 (file)
index 0000000..f09dd1b
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>keychain-sync-updates</key>
+       <true/>
+       <key>application-identifier</key>
+       <string>com.apple.security.cloudkeychainproxy3</string>
+       <key>sync-keychain</key>
+       <true/>
+       <key>keychain-access-groups</key>
+       <array>
+               <string>sync</string>
+               <string>*</string>
+       </array>
+       <key>com.apple.developer.ubiquity-container-identifiers</key>
+       <array>
+               <string>com.apple.security.cloudkeychainproxy3</string>
+               <string>com.apple.security.cloudkeychain</string>
+       </array>
+       <key>com.apple.developer.ubiquity-kvstore-identifier</key>
+       <string>com.apple.security.cloudkeychainproxy3</string>
+</dict>
+</plist>
diff --git a/CloudKeychainProxy/com.apple.security.cloudkeychainproxy.plist b/CloudKeychainProxy/com.apple.security.cloudkeychainproxy.plist
new file mode 100644 (file)
index 0000000..d23581f
--- /dev/null
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>LimitLoadToSessionType</key>
+       <string>Background</string>
+       <key>ProgramArguments</key>
+       <array>
+               <string>/System/Library/Frameworks/Security.framework/Versions/A/Resources/CloudKeychainProxy.bundle/Contents/MacOS/CloudKeychainProxy</string>
+       </array>
+       <key>MachServices</key>
+       <dict>
+               <key>com.apple.security.cloudkeychainproxy3</key>
+               <true/>
+       </dict>
+       <key>RunAtLoad</key>
+       <false/>
+       <key>KeepAlive</key>
+       <false/>
+       <key>Program</key>
+       <string>/System/Library/Frameworks/Security.framework/Versions/A/Resources/CloudKeychainProxy.bundle/Contents/MacOS/CloudKeychainProxy</string>
+       <key>Label</key>
+       <string>com.apple.security.cloudkeychainproxy3</string>
+       <key>EnvironmentVariables</key>
+       <dict>
+               <key>DEBUGSCOPE</key>
+               <string>all</string>
+               <key>WAIT4DEBUGGER</key>
+               <string>NO</string>
+       </dict>
+       <key>LaunchEvents</key>
+       <dict>
+               <key>com.apple.notifyd.matching</key>
+               <dict>
+                       <key>com.apple.keystore.lockstatus</key>
+                       <dict>
+                               <key>Notification</key>
+                               <string>com.apple.keystore.lockstatus</string>
+                       </dict>
+                       <key>com.apple.security.cloudkeychainproxy.kvstorechange3</key>
+                       <dict>
+                               <key>Notification</key>
+                               <string>com.apple.security.cloudkeychainproxy.kvstorechange3</string>
+                       </dict>
+                       <key>com.apple.security.cloudkeychain.forceupdate</key>
+                       <dict>
+                               <key>Notification</key>
+                               <string>com.apple.security.cloudkeychain.forceupdate</string>
+                       </dict>
+               </dict>
+       </dict>
+</dict>
+</plist>
diff --git a/CloudKeychainProxy/en.lproj/InfoPlist.strings b/CloudKeychainProxy/en.lproj/InfoPlist.strings
new file mode 100644 (file)
index 0000000..477b28f
--- /dev/null
@@ -0,0 +1,2 @@
+/* Localized versions of Info.plist keys */
+
diff --git a/Keychain Circle Notification/CloudKeychain.icns b/Keychain Circle Notification/CloudKeychain.icns
new file mode 100644 (file)
index 0000000..97fe7c7
Binary files /dev/null and b/Keychain Circle Notification/CloudKeychain.icns differ
diff --git a/Keychain Circle Notification/KNAppDelegate.h b/Keychain Circle Notification/KNAppDelegate.h
new file mode 100644 (file)
index 0000000..3c25735
--- /dev/null
@@ -0,0 +1,22 @@
+//
+//  KNAppDelegate.h
+//  Keychain Circle Notification
+//
+//  Created by J Osborne on 2/21/13.
+//
+//
+
+#import <Cocoa/Cocoa.h>
+#import <Foundation/NSUserNotification_Private.h>
+#import "KNPersistantState.h"
+
+@class KDSecCircle;
+
+@interface KNAppDelegate : NSObject <NSApplicationDelegate, _NSUserNotificationCenterDelegatePrivate>
+
+@property (assign) IBOutlet NSWindow *window;
+@property (retain) KDSecCircle *circle;
+@property (retain) NSMutableSet *viewedIds;
+@property (retain) KNPersistantState *state;
+
+@end
diff --git a/Keychain Circle Notification/KNAppDelegate.m b/Keychain Circle Notification/KNAppDelegate.m
new file mode 100644 (file)
index 0000000..33272c9
--- /dev/null
@@ -0,0 +1,388 @@
+//
+//  KNAppDelegate.m
+//  Keychain Circle Notification
+//
+//  Created by J Osborne on 2/21/13.
+//
+//
+
+#import "KNAppDelegate.h"
+#import "KDSecCircle.h"
+#import "KDCirclePeer.h"
+#import "NSDictionary+compactDescription.h"
+#import <AOSUI/NSImageAdditions.h>
+#import <AppleSystemInfo/AppleSystemInfo.h>
+#import <Security/SecFrameworkStrings.h>
+
+#import <AOSAccounts/MobileMePrefsCoreAEPrivate.h>
+#import <AOSAccounts/MobileMePrefsCore.h>
+
+static char *kLaunchLaterXPCName = "com.apple.security.Keychain-Circle-Notification-TICK";
+
+@implementation KNAppDelegate
+
+static NSUserNotificationCenter *appropriateNotificationCenter()
+{
+    return [NSUserNotificationCenter _centerForIdentifier:@"com.apple.security.keychain-circle-notification" type:_NSUserNotificationCenterTypeSystem];
+}
+
+-(void)notifyiCloudPreferencesAbout:(NSString *)eventName;
+{
+    if (nil == eventName) {
+        return;
+    }
+    
+    NSString *account = (__bridge NSString *)(MMCopyLoggedInAccount());
+    NSLog(@"notifyiCloudPreferencesAbout %@", eventName);
+    
+    AEDesc aeDesc;
+    BOOL createdAEDesc = createAEDescWithAEActionAndAccountID((__bridge NSString *)kMMServiceIDKeychainSync, eventName, account, &aeDesc);
+    if (createdAEDesc)
+    {
+        OSErr                                err;
+        LSLaunchURLSpec         lsSpec;
+        
+        lsSpec.appURL = NULL;
+        lsSpec.itemURLs = (__bridge CFArrayRef)([NSArray arrayWithObject:[NSURL fileURLWithPath:@"/System/Library/PreferencePanes/iCloudPref.prefPane"]]);
+        lsSpec.passThruParams = &aeDesc;
+        lsSpec.launchFlags = kLSLaunchDefaults | kLSLaunchAsync;
+        lsSpec.asyncRefCon = NULL;
+        
+        err = LSOpenFromURLSpec(&lsSpec, NULL);
+        
+        if (err) {
+            NSLog(@"Can't send event %@, err=%d", eventName, err);
+        }
+        AEDisposeDesc(&aeDesc);
+    }
+    else
+    {
+        NSLog(@"unable to create and send aedesc for account: '%@' and action: '%@'\n", account, eventName);
+    }
+}
+
+-(void)showiCloudPrefrences
+{
+    static NSAppleScript *script = nil;
+    if (!script) {
+        script = [[NSAppleScript alloc] initWithSource:@"tell application \"System Preferences\"\n\
+                  activate\n\
+                  set the current pane to pane id \"com.apple.preferences.icloud\"\n\
+                  end tell"];
+    }
+    
+    NSDictionary *appleScriptError = nil;
+    [script executeAndReturnError:&appleScriptError];
+    
+    if (appleScriptError) {
+        NSLog(@"appleScriptError: %@", appleScriptError);
+    } else {
+        NSLog(@"NO appleScript error");
+    }
+}
+
+-(void)timerCheck
+{
+       NSDate *nowish = [NSDate new];
+       self.state = [KNPersistantState loadFromStorage];
+       if ([nowish compare:self.state.pendingApplicationReminder] != NSOrderedAscending) {
+               NSLog(@"REMINDER TIME:     %@ >>> %@", nowish, self.state.pendingApplicationReminder);
+               // self.circle.rawStatus might not be valid yet
+               if (SOSCCThisDeviceIsInCircle(NULL) == kSOSCCRequestPending) {
+                       // Still have a request pending, send reminder, and also in addtion to the UI
+                       // we need to send a notification for iCloud pref pane to pick up
+                       
+                       CFNotificationCenterPostNotificationWithOptions(CFNotificationCenterGetDistributedCenter(), CFSTR("com.apple.security.secureobjectsync.pendingApplicationReminder"), (__bridge const void *)([self.state.applcationDate description]), NULL, 0);
+                       
+                       [self postApplicationReminder];
+                       self.state.pendingApplicationReminder = [self.state.applcationDate dateByAddingTimeInterval:[self getPendingApplicationReminderInterval]];
+                       [self.state writeToStorage];
+               }
+       }
+}
+
+-(void)scheduleActivityAt:(NSDate*)time
+{
+       if ([time compare:[NSDate distantFuture]] != NSOrderedSame) {
+               NSTimeInterval howSoon = [time timeIntervalSinceNow];
+               if (howSoon > 0) {
+                       [self scheduleActivityIn:howSoon];
+               } else {
+                       [self timerCheck];
+               }
+       }
+}
+
+-(void)scheduleActivityIn:(int)alertInterval
+{
+    xpc_object_t options = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_uint64(options, XPC_ACTIVITY_DELAY, alertInterval);
+    xpc_dictionary_set_uint64(options, XPC_ACTIVITY_GRACE_PERIOD, XPC_ACTIVITY_INTERVAL_1_MIN);
+    xpc_dictionary_set_bool(options, XPC_ACTIVITY_REPEATING, false);
+    xpc_dictionary_set_bool(options, XPC_ACTIVITY_ALLOW_BATTERY, true);
+    xpc_dictionary_set_string(options, XPC_ACTIVITY_PRIORITY, XPC_ACTIVITY_PRIORITY_UTILITY);
+    
+    xpc_activity_register(kLaunchLaterXPCName, options, ^(xpc_activity_t activity) {
+               [self timerCheck];
+    });
+}
+
+-(NSTimeInterval)getPendingApplicationReminderInterval
+{
+       if (self.state.pendingApplicationReminderInterval) {
+               return [self.state.pendingApplicationReminderInterval doubleValue];
+       } else {
+               return 48*24*60*60;
+       }
+}
+
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
+{
+       appropriateNotificationCenter().delegate = self;
+       
+       NSLog(@"Posted at launch: %@", appropriateNotificationCenter().deliveredNotifications);
+       
+    self.viewedIds = [NSMutableSet new];
+       self.circle = [KDSecCircle new];
+       self.state = [KNPersistantState loadFromStorage];
+       KNAppDelegate *me = self;
+       
+       [self.circle addChangeCallback:^{
+               me.state = [KNPersistantState loadFromStorage];
+               if ((me.state.lastCircleStatus == kSOSCCInCircle && !me.circle.isInCircle) || me.state.debugLeftReason) {
+                       enum DepartureReason reason = kSOSNeverLeftCircle;
+                       if (me.state.debugLeftReason) {
+                               reason = [me.state.debugLeftReason intValue];
+                               me.state.debugLeftReason = nil;
+                       } else {
+                               CFErrorRef err = NULL;
+                               reason = SOSCCGetLastDepartureReason(&err);
+                               if (reason == kSOSDepartureReasonError) {
+                                       NSLog(@"SOSCCGetLastDepartureReason err: %@", err);
+                               }
+                       }
+                       
+                       //NSString *model = (__bridge NSString *)(ASI_CopyComputerModelName(FALSE));
+                       NSString *body = nil;
+                       switch (reason) {
+                               case kSOSDepartureReasonError:
+                               case kSOSNeverLeftCircle:
+                               case kSOSWithdrewMembership:
+                                       break;
+                                       
+                               default:
+                                       NSLog(@"Unknown departure reason %d", reason);
+                                       // fallthrough on purpose
+                                       
+                               case kSOSMembershipRevoked:
+                               case kSOSLeftUntrustedCircle:
+                                       body = NSLocalizedString(@"Approve this Mac from another device to use iCloud Keychain.", @"Body for iCloud Keychain Reset notification");
+                                       break;
+                       }
+                       [me.state writeToStorage];
+                       NSLog(@"departure reason %d, body=%@", reason, body);
+                       if (body) {
+                               [me postKickedOutWithMessage: body];
+                       }
+               }
+               
+               [me timerCheck];
+               
+               if (me.state.lastCircleStatus != kSOSCCRequestPending && me.circle.rawStatus == kSOSCCRequestPending) {
+                       NSLog(@"Entered RequestPending");
+                       NSDate *nowish = [NSDate new];
+                       me.state.applcationDate = nowish;
+                       me.state.pendingApplicationReminder = [me.state.applcationDate dateByAddingTimeInterval:[me getPendingApplicationReminderInterval]];
+                       [me.state writeToStorage];
+                       [me scheduleActivityAt:me.state.pendingApplicationReminder];
+               }
+               
+               NSMutableSet *applicantIds = [NSMutableSet new];
+               for (KDCirclePeer *applicant in me.circle.applicants) {
+            if (!me.circle.isInCircle) {
+                // We don't want to yammer on about circles we aren't in,
+                // and we don't want to be extra confusing announcing our
+                // own join requests as if the user could approve them
+                // locally!
+                break;
+            }
+                       [me postForApplicant:applicant];
+                       [applicantIds addObject:applicant.idString];
+               }
+               
+               NSUserNotificationCenter *notificationCenter = appropriateNotificationCenter();
+               NSLog(@"Checking validity of %lu notes", (unsigned long)notificationCenter.deliveredNotifications.count);
+               for (NSUserNotification *note in notificationCenter.deliveredNotifications) {
+                       if (note.userInfo[@"applicantId"] && ![applicantIds containsObject:note.userInfo[@"applicantId"]]) {
+                               NSLog(@"No longer an applicant (%@) for %@ (I=%@)", note.userInfo[@"applicantId"], note, [note.userInfo compactDescription]);
+                               [notificationCenter removeDeliveredNotification:note];
+                       } else {
+                               NSLog(@"Still an applicant (%@) for %@ (I=%@)", note.userInfo[@"applicantId"], note, [note.userInfo compactDescription]);
+                       }
+               }
+               
+        me.state.lastCircleStatus = me.circle.rawStatus;
+        
+               [me.state writeToStorage];
+       }];
+       
+       [me scheduleActivityAt:me.state.pendingApplicationReminder];
+}
+
+-(BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification
+{
+       return YES;
+}
+
+-(void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification
+{
+    if (notification.activationType == NSUserNotificationActivationTypeActionButtonClicked) {
+        [self notifyiCloudPreferencesAbout:notification.userInfo[@"Activate"]];
+    }
+
+    // The "Later" seems handled Ok without doing anything here, but KickedOut & other special items need an action
+       if (notification.userInfo[@"SPECIAL"]) {
+               NSLog(@"ACTIVATED (remove): %@", notification);
+               [appropriateNotificationCenter() removeDeliveredNotification:notification];
+       } else {
+               NSLog(@"ACTIVATED (NOT removed): %@", notification);
+    }
+}
+
+-(void)userNotificationCenter:(NSUserNotificationCenter *)center didDismissAlert:(NSUserNotification *)notification
+{
+    [self notifyiCloudPreferencesAbout:notification.userInfo[@"Dismiss"]];
+    
+    if (!notification.userInfo[@"SPECIAL"]) {
+               // If we don't do anything here & another notification comes in we
+               // will repost the alert, which will be dumb.
+        id applicantId = notification.userInfo[@"applicantId"];
+        if (applicantId != nil) {
+            [self.viewedIds addObject:applicantId];
+        }
+        NSLog(@"DISMISS (t) %@", notification);
+       } else {
+        NSLog(@"DISMISS (f) %@", notification);
+               [appropriateNotificationCenter() removeDeliveredNotification:notification];
+       }
+}
+
+-(void)postForApplicant:(KDCirclePeer*)applicant
+{
+       static int postCount = 0;
+    
+    if ([self.viewedIds containsObject:applicant.idString]) {
+        NSLog(@"Already viewed %@, skipping", applicant);
+        return;
+    }
+    
+       NSUserNotificationCenter *noteCenter = appropriateNotificationCenter();
+       for (NSUserNotification *note in noteCenter.deliveredNotifications) {
+               if ([applicant.idString isEqualToString:note.userInfo[@"applicantId"]]) {
+                       if (note.isPresented) {
+                               NSLog(@"Already posted&presented: %@ (I=%@)", note, note.userInfo);
+                               return;
+                       } else {
+                               NSLog(@"Already posted, but not presented: %@ (I=%@)", note, note.userInfo);
+                       }
+               }
+       }
+       
+       NSUserNotification *note = [NSUserNotification new];
+       
+    // Genstrings command line is: genstrings -o en.lproj -u KNAppDelegate.m
+       note.title = [NSString stringWithFormat:NSLocalizedString(@"iCloud Keychain", @"Title for new keychain syncing device notification")];
+       note.informativeText = [NSString stringWithFormat:NSLocalizedString(@"\\U201C%1$@\\U201D wants to use your passwords.", @"Message text for new keychain syncing device notification"), applicant.name];
+           
+       note.hasActionButton = YES;
+       note._displayStyle = _NSUserNotificationDisplayStyleAlert;
+    note._identityImage = [NSImage bundleImage];
+    note._identityImageHasBorder = NO;
+    note._actionButtonIsSnooze = YES;
+       note.actionButtonTitle = NSLocalizedString(@"Later", @"Button label to dismiss device notification");
+       note.otherButtonTitle = NSLocalizedString(@"View", @"Button label to view device notification");
+       
+       note.identifier = [[NSUUID new] UUIDString];
+    
+    note.userInfo = @{@"applicantName": applicant.name,
+                      @"applicantId": applicant.idString,
+                      @"Dismiss": (__bridge NSString *)kMMPropertyKeychainMRRequestApprovalAEAction,
+                      };
+
+    NSLog(@"About to post#%d/%lu (%@): %@", postCount, (unsigned long)noteCenter.deliveredNotifications.count, applicant.idString, note);
+       [appropriateNotificationCenter() deliverNotification:note];
+       
+       postCount++;
+}
+
+-(void)postKickedOutWithMessage:(NSString*)body
+{
+       NSUserNotificationCenter *noteCenter = appropriateNotificationCenter();
+       for (NSUserNotification *note in noteCenter.deliveredNotifications) {
+               if (note.userInfo[@"KickedOut"]) {
+                       if (note.isPresented) {
+                               NSLog(@"Already posted&presented (removing): %@", note);
+                               [appropriateNotificationCenter() removeDeliveredNotification: note];
+                       } else {
+                               NSLog(@"Already posted, but not presented: %@", note);
+                       }
+               }
+       }
+       
+       NSUserNotification *note = [NSUserNotification new];
+       
+       note.title = NSLocalizedString(@"iCloud Keychain Was Reset", @"Title for iCloud Keychain Reset notification");
+       note.informativeText = body; // Already LOCed
+       
+    note._identityImage = [NSImage bundleImage];
+    note._identityImageHasBorder = NO;
+       note.otherButtonTitle = NSLocalizedString(@"Close", @"Close button");
+       note.actionButtonTitle = NSLocalizedString(@"Options", @"Options Button");
+       
+       note.identifier = [[NSUUID new] UUIDString];
+    
+    note.userInfo = @{@"KickedOut": @1,
+                                         @"SPECIAL": @1,
+                      @"Activate": (__bridge NSString *)kMMPropertyKeychainMRDetailsAEAction,
+                      };
+
+    NSLog(@"About to post#-/%lu (KICKOUT): %@", (unsigned long)noteCenter.deliveredNotifications.count, note);
+       [appropriateNotificationCenter() deliverNotification:note];
+}
+
+-(void)postApplicationReminder
+{
+       NSUserNotificationCenter *noteCenter = appropriateNotificationCenter();
+       for (NSUserNotification *note in noteCenter.deliveredNotifications) {
+               if (note.userInfo[@"ApplicationReminder"]) {
+                       if (note.isPresented) {
+                               NSLog(@"Already posted&presented (removing): %@", note);
+                               [appropriateNotificationCenter() removeDeliveredNotification: note];
+                       } else {
+                               NSLog(@"Already posted, but not presented: %@", note);
+                       }
+               }
+       }
+       
+       NSUserNotification *note = [NSUserNotification new];
+       
+       note.title = NSLocalizedString(@"iCloud Keychain", @"Title for iCloud Keychain Application still pending (from this device) reminder");
+       note.informativeText = NSLocalizedString(@"Approve this Mac from another device to use iCloud Keychain.", @"Body text for iCloud Keychain Application still pending (from this device) reminder");
+       
+    note._identityImage = [NSImage bundleImage];
+    note._identityImageHasBorder = NO;
+       note.otherButtonTitle = NSLocalizedString(@"Close", @"Close button");
+       note.actionButtonTitle = NSLocalizedString(@"Options", @"Options Button");
+       
+       note.identifier = [[NSUUID new] UUIDString];
+    
+    note.userInfo = @{@"ApplicationReminder": @1,
+                                         @"SPECIAL": @1,
+                      @"Activate": (__bridge NSString *)kMMPropertyKeychainWADetailsAEAction,
+                      };
+       
+    NSLog(@"About to post#-/%lu (REMINDER): %@", (unsigned long)noteCenter.deliveredNotifications.count, note);
+       [appropriateNotificationCenter() deliverNotification:note];
+}
+
+@end
diff --git a/Keychain Circle Notification/KNPersistantState.h b/Keychain Circle Notification/KNPersistantState.h
new file mode 100644 (file)
index 0000000..ad84248
--- /dev/null
@@ -0,0 +1,23 @@
+//
+//  KNPersistantState.h
+//  Security
+//
+//  Created by J Osborne on 7/28/13.
+//
+//
+
+#import <Foundation/Foundation.h>
+#include "SecureObjectSync/SOSCloudCircle.h"
+#include "SecureObjectSync/SOSPeerInfo.h"
+
+@interface KNPersistantState : NSObject
++(instancetype)loadFromStorage;
+-(void)writeToStorage;
+
+@property SOSCCStatus lastCircleStatus;
+@property NSNumber *debugLeftReason;
+@property NSNumber *pendingApplicationReminderInterval;
+@property NSDate *pendingApplicationReminder;
+@property NSDate *applcationDate;
+@property NSDate *lastWritten;
+@end
diff --git a/Keychain Circle Notification/KNPersistantState.m b/Keychain Circle Notification/KNPersistantState.m
new file mode 100644 (file)
index 0000000..dd65f76
--- /dev/null
@@ -0,0 +1,86 @@
+//
+//  KNPersistantState.m
+//  Security
+//
+//  Created by J Osborne on 7/28/13.
+//
+//
+
+#import "KNPersistantState.h"
+
+@implementation KNPersistantState
+
+-(NSURL*)urlForStorage
+{
+       return [NSURL URLWithString:@"Preferences/com.apple.security.KCN.plist" relativeToURL:[[NSFileManager defaultManager] URLForDirectory:NSLibraryDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:nil]];
+}
+
++(instancetype)loadFromStorage
+{
+       KNPersistantState *state = [[KNPersistantState alloc] init];
+    if (!state) {
+        return state;
+    }
+    
+    id plist = @{@"lastWritten": [NSDate distantPast]};
+
+    NSError *error = nil;
+    NSData *stateData = [NSData dataWithContentsOfURL:[state urlForStorage] options:0 error:&error];
+    if (!stateData) {
+        NSLog(@"Can't read state data (p=%@, err=%@)", [state urlForStorage], error);
+    } else {
+        NSPropertyListFormat format;
+        plist = [NSPropertyListSerialization propertyListWithData:stateData options: NSPropertyListMutableContainersAndLeaves format:&format error:&error];
+        
+        if (plist == nil) {
+            NSLog(@"Can't deserialize %@, e=%@", stateData, error);
+        }
+    }
+    
+    state.lastCircleStatus = plist[@"lastCircleStatus"] ? [plist[@"lastCircleStatus"] intValue] : kSOSCCCircleAbsent;
+    state.lastWritten = plist[@"lastWritten"];
+       state.pendingApplicationReminderInterval = plist[@"pendingApplicationReminderInterval"];
+       state.debugLeftReason = plist[@"debugLeftReason"];
+       state.pendingApplicationReminder = plist[@"pendingApplicationReminder"];
+       state.applcationDate = plist[@"applcationDate"];
+       if (!state.applcationDate) {
+               state.applcationDate = [NSDate distantPast];
+       }
+       if (!state.pendingApplicationReminder) {
+               state.pendingApplicationReminder = [NSDate distantFuture];
+       }
+    if (!state.pendingApplicationReminderInterval || [state.pendingApplicationReminderInterval doubleValue] <= 0) {
+        state.pendingApplicationReminderInterval = [NSNumber numberWithUnsignedInt:60 * 60 * 24 * 2];
+    }
+    
+    return state;
+}
+
+-(void)writeToStorage
+{
+    NSMutableDictionary *plist = [@{@"lastCircleStatus": [NSNumber numberWithInt:self.lastCircleStatus],
+                                                                       @"lastWritten": [NSDate date],
+                                                                       @"applcationDate": self.applcationDate,
+                                                                       @"pendingApplicationReminder": self.pendingApplicationReminder,
+                            } mutableCopy];
+       if (self.debugLeftReason) {
+               plist[@"debugLeftReason"] = self.debugLeftReason;
+       }
+       if (self.pendingApplicationReminderInterval) {
+               plist[@"pendingApplicationReminderInterval"] = self.pendingApplicationReminderInterval;
+       }
+    NSLog(@"writeToStorage plist=%@", plist);
+       
+    NSError *error = nil;
+    NSData *stateData = [NSPropertyListSerialization dataWithPropertyList:[plist copy] format:NSPropertyListXMLFormat_v1_0 options:kCFPropertyListImmutable error:&error];
+    if (!stateData) {
+        NSLog(@"Can't serialize %@: %@", plist, error);
+        return;
+    }
+    if (![stateData writeToURL:[self urlForStorage] options:NSDataWritingAtomic error:&error]) {
+        NSLog(@"Can't write to %@, error=%@", [self urlForStorage], error);
+    }
+}
+
+
+@end
diff --git a/Keychain Circle Notification/Keychain Circle Notification-Info.plist b/Keychain Circle Notification/Keychain Circle Notification-Info.plist
new file mode 100644 (file)
index 0000000..2fefb25
--- /dev/null
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>en</string>
+       <key>CFBundleExecutable</key>
+       <string>${EXECUTABLE_NAME}</string>
+       <key>CFBundleIconFile</key>
+       <string>CloudKeychain.icns</string>
+       <key>CFBundleIdentifier</key>
+       <string>com.security.apple.${PRODUCT_NAME:rfc1034identifier}</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundleName</key>
+       <string>${PRODUCT_NAME}</string>
+       <key>CFBundlePackageType</key>
+       <string>APPL</string>
+       <key>CFBundleShortVersionString</key>
+       <string>1.0</string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>55471</string>
+       <key>LSApplicationCategoryType</key>
+       <string></string>
+       <key>LSMinimumSystemVersion</key>
+       <string>${MACOSX_DEPLOYMENT_TARGET}</string>
+       <key>LSUIElement</key>
+       <true/>
+       <key>NSMainNibFile</key>
+       <string>MainMenu</string>
+       <key>NSPrincipalClass</key>
+       <string>NSApplication</string>
+       <key>NSUserNotificationAlertStyle</key>
+       <string>alert</string>
+</dict>
+</plist>
diff --git a/Keychain Circle Notification/Keychain Circle Notification-Prefix.pch b/Keychain Circle Notification/Keychain Circle Notification-Prefix.pch
new file mode 100644 (file)
index 0000000..4bc6784
--- /dev/null
@@ -0,0 +1,7 @@
+//
+// Prefix header for all source files of the 'Keychain Circle Notification' target in the 'Keychain Circle Notification' project
+//
+
+#ifdef __OBJC__
+       #import <Cocoa/Cocoa.h>
+#endif
diff --git a/Keychain Circle Notification/NSArray+mapWithBlock.h b/Keychain Circle Notification/NSArray+mapWithBlock.h
new file mode 100644 (file)
index 0000000..03d342b
--- /dev/null
@@ -0,0 +1,15 @@
+//
+//  NSArray+mapWithBlock.h
+//  Security
+//
+//  Created by J Osborne on 2/26/13.
+//
+//
+
+#import <Foundation/Foundation.h>
+
+typedef id (^mapBlock)(id obj);
+
+@interface NSArray (mapWithBlock)
+-(NSArray*)mapWithBlock:(mapBlock)block;
+@end
diff --git a/Keychain Circle Notification/NSArray+mapWithBlock.m b/Keychain Circle Notification/NSArray+mapWithBlock.m
new file mode 100644 (file)
index 0000000..0ec2e6d
--- /dev/null
@@ -0,0 +1,24 @@
+//
+//  NSArray+mapWithBlock.m
+//  Security
+//
+//  Created by J Osborne on 2/26/13.
+//
+//
+
+#import "NSArray+mapWithBlock.h"
+
+@implementation NSArray (mapWithBlock)
+
+-(NSArray*)mapWithBlock:(mapBlock)block
+{
+       NSMutableArray *mapped = [[NSMutableArray alloc] initWithCapacity:self.count];
+       
+       for (id obj in self) {
+               [mapped addObject:block(obj)];
+       }
+       
+       return [mapped copy];
+}
+
+@end
diff --git a/Keychain Circle Notification/NSDictionary+compactDescription.h b/Keychain Circle Notification/NSDictionary+compactDescription.h
new file mode 100644 (file)
index 0000000..1cd252d
--- /dev/null
@@ -0,0 +1,14 @@
+//
+//  NSDictionary+compactDescription.h
+//  KeychainMigrator
+//
+//  Created by J Osborne on 2/19/13.
+//
+//
+
+#import <Foundation/Foundation.h>
+
+@interface NSDictionary (compactDescription)
+-(NSString*)compactDescription;
+-(NSString*)compactDescriptionWithoutItemData;
+@end
diff --git a/Keychain Circle Notification/NSDictionary+compactDescription.m b/Keychain Circle Notification/NSDictionary+compactDescription.m
new file mode 100644 (file)
index 0000000..9b47d51
--- /dev/null
@@ -0,0 +1,52 @@
+//
+//  NSDictionary+compactDescription.m
+//  KeychainMigrator
+//
+//  Created by J Osborne on 2/19/13.
+//
+//
+
+#import "NSDictionary+compactDescription.h"
+#import "NSString+compactDescription.h"
+
+@implementation NSDictionary (compactDescription)
+
+-(NSString*)compactDescription
+{
+       NSMutableArray *results = [NSMutableArray new];
+       for (NSString *k in self) {
+               id v = self[k];
+               if ([v respondsToSelector:@selector(compactDescription)]) {
+                       v = [v compactDescription];
+               } else {
+                       v = [v description];
+               }
+               
+               [results addObject:[NSString stringWithFormat:@"%@=%@", [k compactDescription], v]];
+       }
+       return [NSString stringWithFormat:@"{%@}", [results componentsJoinedByString:@", "]];
+}
+
+-(NSString*)compactDescriptionWithoutItemData;
+{
+       NSMutableArray *results = [NSMutableArray new];
+       for (NSString *k in self) {
+               if ([k isEqualToString:kSecValueData]) {
+                       [results addObject:[NSString stringWithFormat:@"%@=<not-logged>", [k compactDescription]]];
+                       continue;
+               }
+               
+               id v = self[k];
+               if ([v respondsToSelector:@selector(compactDescription)]) {
+                       v = [v compactDescription];
+               } else {
+                       v = [v description];
+               }
+               
+               [results addObject:[NSString stringWithFormat:@"%@=%@", [k compactDescription], v]];
+       }
+       return [NSString stringWithFormat:@"{%@}", [results componentsJoinedByString:@", "]];
+
+}
+
+@end
diff --git a/Keychain Circle Notification/NSSet+compactDescription.h b/Keychain Circle Notification/NSSet+compactDescription.h
new file mode 100644 (file)
index 0000000..851dab0
--- /dev/null
@@ -0,0 +1,13 @@
+//
+//  NSSet+compactDescription.h
+//  KeychainMigrator
+//
+//  Created by J Osborne on 3/21/13.
+//
+//
+
+#import <Foundation/Foundation.h>
+
+@interface NSSet (compactDescription)
+-(NSString*)compactDescription;
+@end
diff --git a/Keychain Circle Notification/NSSet+compactDescription.m b/Keychain Circle Notification/NSSet+compactDescription.m
new file mode 100644 (file)
index 0000000..2c521f7
--- /dev/null
@@ -0,0 +1,26 @@
+//
+//  NSSet+compactDescription.m
+//  KeychainMigrator
+//
+//  Created by J Osborne on 3/21/13.
+//
+//
+
+#import "NSSet+compactDescription.h"
+
+@implementation NSSet (compactDescription)
+
+-(NSString*)compactDescription
+{
+       NSMutableArray *results = [NSMutableArray new];
+       for (id v in self) {
+               if ([v respondsToSelector:@selector(compactDescription)]) {
+                       [results addObject:[v compactDescription]];
+               } else {
+                       [results addObject:[v description]];
+               }
+       }
+       return [NSString stringWithFormat:@"[%@]", [results componentsJoinedByString:@", "]];
+}
+
+@end
diff --git a/Keychain Circle Notification/NSString+compactDescription.h b/Keychain Circle Notification/NSString+compactDescription.h
new file mode 100644 (file)
index 0000000..d810558
--- /dev/null
@@ -0,0 +1,13 @@
+//
+//  NSString+compactDescription.h
+//  KeychainMigrator
+//
+//  Created by J Osborne on 2/19/13.
+//
+//
+
+#import <Foundation/Foundation.h>
+
+@interface NSString (compactDescription)
+-(NSString*)compactDescription;
+@end
diff --git a/Keychain Circle Notification/NSString+compactDescription.m b/Keychain Circle Notification/NSString+compactDescription.m
new file mode 100644 (file)
index 0000000..52b242d
--- /dev/null
@@ -0,0 +1,30 @@
+//
+//  NSString+compactDescription.m
+//  KeychainMigrator
+//
+//  Created by J Osborne on 2/19/13.
+//
+//
+
+#import "NSString+compactDescription.h"
+
+@implementation NSString (compactDescription)
+
+-(NSString*)compactDescription
+{
+       static NSCharacterSet *forceQuotes = nil;
+       static dispatch_once_t setup;
+       dispatch_once(&setup, ^{
+               forceQuotes = [NSCharacterSet characterSetWithCharactersInString:@"\"' \t\n\r="];
+       });
+       
+       if ([self rangeOfCharacterFromSet:forceQuotes].location != NSNotFound) {
+               NSString *escaped = [self stringByReplacingOccurrencesOfString:@"\\" withString:@"\\\\"];
+               escaped = [escaped stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""];
+               return [NSString stringWithFormat:@"\"%@\"", escaped];
+       } else {
+               return self;
+       }
+}
+
+@end
diff --git a/Keychain Circle Notification/com.apple.security.keychain-circle-notification.plist b/Keychain Circle Notification/com.apple.security.keychain-circle-notification.plist
new file mode 100644 (file)
index 0000000..2c98255
--- /dev/null
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>Label</key>
+       <string>com.apple.security.keychain-circle-notification</string>
+       <key>RunAtLoad</key>
+       <false/>
+       <key>KeepAlive</key>
+       <false/>
+       <key>LaunchEvents</key>
+       <dict>
+               <key>com.apple.notifyd.matching</key>
+               <dict>
+                       <key>tick</key>
+                       <dict>
+                               <key>Notification</key>
+                               <string>com.apple.security.tick</string>
+                       </dict>
+                       <key>1stunlock</key>
+                       <dict>
+                               <key>Notification</key>
+                               <string>com.apple.keystore.firstunlock</string>
+                       </dict>
+                       <key>kSOSCCCircleChangedNotification</key>
+                       <dict>
+                               <key>Notification</key>
+                               <string>com.apple.security.secureobjectsync.circlechanged</string>
+                       </dict>
+               </dict>
+       </dict>
+       <key>ProgramArguments</key>
+       <array>
+               <string>/System/Library/CoreServices/Keychain Circle Notification.app/Contents/MacOS/Keychain Circle Notification</string>
+       </array>
+</dict>
+</plist>
diff --git a/Keychain Circle Notification/en.lproj/Credits.rtf b/Keychain Circle Notification/en.lproj/Credits.rtf
new file mode 100644 (file)
index 0000000..46576ef
--- /dev/null
@@ -0,0 +1,29 @@
+{\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\paperw9840\paperh8400
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
+
+\f0\b\fs24 \cf0 Engineering:
+\b0 \
+       Some people\
+\
+
+\b Human Interface Design:
+\b0 \
+       Some other people\
+\
+
+\b Testing:
+\b0 \
+       Hopefully not nobody\
+\
+
+\b Documentation:
+\b0 \
+       Whoever\
+\
+
+\b With special thanks to:
+\b0 \
+       Mom\
+}
diff --git a/Keychain Circle Notification/en.lproj/InfoPlist.strings b/Keychain Circle Notification/en.lproj/InfoPlist.strings
new file mode 100644 (file)
index 0000000..477b28f
--- /dev/null
@@ -0,0 +1,2 @@
+/* Localized versions of Info.plist keys */
+
diff --git a/Keychain Circle Notification/en.lproj/Localizable.strings b/Keychain Circle Notification/en.lproj/Localizable.strings
new file mode 100644 (file)
index 0000000..51626ac
Binary files /dev/null and b/Keychain Circle Notification/en.lproj/Localizable.strings differ
diff --git a/Keychain Circle Notification/en.lproj/MainMenu.xib b/Keychain Circle Notification/en.lproj/MainMenu.xib
new file mode 100644 (file)
index 0000000..daf30bf
--- /dev/null
@@ -0,0 +1,3244 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="8.00">
+       <data>
+               <int key="IBDocument.SystemTarget">1090</int>
+               <string key="IBDocument.SystemVersion">13A386b</string>
+               <string key="IBDocument.InterfaceBuilderVersion">4373</string>
+               <string key="IBDocument.AppKitVersion">1219</string>
+               <string key="IBDocument.HIToolboxVersion">662.00</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                       <string key="NS.object.0">4373</string>
+               </object>
+               <array key="IBDocument.IntegratedClassDependencies">
+                       <string>NSCustomObject</string>
+                       <string>NSMenu</string>
+                       <string>NSMenuItem</string>
+               </array>
+               <array key="IBDocument.PluginDependencies">
+                       <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+               </array>
+               <object class="NSMutableDictionary" key="IBDocument.Metadata">
+                       <string key="NS.key.0">PluginDependencyRecalculationVersion</string>
+                       <integer value="1" key="NS.object.0"/>
+               </object>
+               <array class="NSMutableArray" key="IBDocument.RootObjects" id="1048">
+                       <object class="NSCustomObject" id="1021">
+                               <string key="NSClassName">NSApplication</string>
+                       </object>
+                       <object class="NSCustomObject" id="1014">
+                               <string key="NSClassName">FirstResponder</string>
+                       </object>
+                       <object class="NSCustomObject" id="1050">
+                               <string key="NSClassName">NSApplication</string>
+                       </object>
+                       <object class="NSMenu" id="649796088">
+                               <string key="NSTitle">AMainMenu</string>
+                               <array class="NSMutableArray" key="NSMenuItems">
+                                       <object class="NSMenuItem" id="694149608">
+                                               <reference key="NSMenu" ref="649796088"/>
+                                               <string key="NSTitle">Keychain Circle Notification</string>
+                                               <string key="NSKeyEquiv"/>
+                                               <int key="NSKeyEquivModMask">1048576</int>
+                                               <int key="NSMnemonicLoc">2147483647</int>
+                                               <object class="NSCustomResource" key="NSOnImage" id="35465992">
+                                                       <string key="NSClassName">NSImage</string>
+                                                       <string key="NSResourceName">NSMenuCheckmark</string>
+                                               </object>
+                                               <object class="NSCustomResource" key="NSMixedImage" id="502551668">
+                                                       <string key="NSClassName">NSImage</string>
+                                                       <string key="NSResourceName">NSMenuMixedState</string>
+                                               </object>
+                                               <string key="NSAction">submenuAction:</string>
+                                               <reference key="NSTarget" ref="110575045"/>
+                                               <object class="NSMenu" key="NSSubmenu" id="110575045">
+                                                       <string key="NSTitle">Keychain Circle Notification</string>
+                                                       <array class="NSMutableArray" key="NSMenuItems">
+                                                               <object class="NSMenuItem" id="238522557">
+                                                                       <reference key="NSMenu" ref="110575045"/>
+                                                                       <string key="NSTitle">About Keychain Circle Notification</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="304266470">
+                                                                       <reference key="NSMenu" ref="110575045"/>
+                                                                       <bool key="NSIsDisabled">YES</bool>
+                                                                       <bool key="NSIsSeparator">YES</bool>
+                                                                       <string key="NSTitle"/>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="609285721">
+                                                                       <reference key="NSMenu" ref="110575045"/>
+                                                                       <string key="NSTitle">Preferences…</string>
+                                                                       <string key="NSKeyEquiv">,</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="481834944">
+                                                                       <reference key="NSMenu" ref="110575045"/>
+                                                                       <bool key="NSIsDisabled">YES</bool>
+                                                                       <bool key="NSIsSeparator">YES</bool>
+                                                                       <string key="NSTitle"/>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="1046388886">
+                                                                       <reference key="NSMenu" ref="110575045"/>
+                                                                       <string key="NSTitle">Services</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                       <string key="NSAction">submenuAction:</string>
+                                                                       <reference key="NSTarget" ref="752062318"/>
+                                                                       <object class="NSMenu" key="NSSubmenu" id="752062318">
+                                                                               <string key="NSTitle">Services</string>
+                                                                               <array class="NSMutableArray" key="NSMenuItems"/>
+                                                                               <string key="NSName">_NSServicesMenu</string>
+                                                                       </object>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="646227648">
+                                                                       <reference key="NSMenu" ref="110575045"/>
+                                                                       <bool key="NSIsDisabled">YES</bool>
+                                                                       <bool key="NSIsSeparator">YES</bool>
+                                                                       <string key="NSTitle"/>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="755159360">
+                                                                       <reference key="NSMenu" ref="110575045"/>
+                                                                       <string key="NSTitle">Hide Keychain Circle Notification</string>
+                                                                       <string key="NSKeyEquiv">h</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="342932134">
+                                                                       <reference key="NSMenu" ref="110575045"/>
+                                                                       <string key="NSTitle">Hide Others</string>
+                                                                       <string key="NSKeyEquiv">h</string>
+                                                                       <int key="NSKeyEquivModMask">1572864</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="908899353">
+                                                                       <reference key="NSMenu" ref="110575045"/>
+                                                                       <string key="NSTitle">Show All</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="1056857174">
+                                                                       <reference key="NSMenu" ref="110575045"/>
+                                                                       <bool key="NSIsDisabled">YES</bool>
+                                                                       <bool key="NSIsSeparator">YES</bool>
+                                                                       <string key="NSTitle"/>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="632727374">
+                                                                       <reference key="NSMenu" ref="110575045"/>
+                                                                       <string key="NSTitle">Quit Keychain Circle Notification</string>
+                                                                       <string key="NSKeyEquiv">q</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                       </array>
+                                                       <string key="NSName">_NSAppleMenu</string>
+                                               </object>
+                                       </object>
+                                       <object class="NSMenuItem" id="379814623">
+                                               <reference key="NSMenu" ref="649796088"/>
+                                               <string key="NSTitle">File</string>
+                                               <string key="NSKeyEquiv"/>
+                                               <int key="NSKeyEquivModMask">1048576</int>
+                                               <int key="NSMnemonicLoc">2147483647</int>
+                                               <reference key="NSOnImage" ref="35465992"/>
+                                               <reference key="NSMixedImage" ref="502551668"/>
+                                               <string key="NSAction">submenuAction:</string>
+                                               <reference key="NSTarget" ref="720053764"/>
+                                               <object class="NSMenu" key="NSSubmenu" id="720053764">
+                                                       <string key="NSTitle">File</string>
+                                                       <array class="NSMutableArray" key="NSMenuItems">
+                                                               <object class="NSMenuItem" id="705341025">
+                                                                       <reference key="NSMenu" ref="720053764"/>
+                                                                       <string key="NSTitle">New</string>
+                                                                       <string key="NSKeyEquiv">n</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="722745758">
+                                                                       <reference key="NSMenu" ref="720053764"/>
+                                                                       <string key="NSTitle">Open…</string>
+                                                                       <string key="NSKeyEquiv">o</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="1025936716">
+                                                                       <reference key="NSMenu" ref="720053764"/>
+                                                                       <string key="NSTitle">Open Recent</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                       <string key="NSAction">submenuAction:</string>
+                                                                       <reference key="NSTarget" ref="1065607017"/>
+                                                                       <object class="NSMenu" key="NSSubmenu" id="1065607017">
+                                                                               <string key="NSTitle">Open Recent</string>
+                                                                               <array class="NSMutableArray" key="NSMenuItems">
+                                                                                       <object class="NSMenuItem" id="759406840">
+                                                                                               <reference key="NSMenu" ref="1065607017"/>
+                                                                                               <string key="NSTitle">Clear Menu</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                               </array>
+                                                                               <string key="NSName">_NSRecentDocumentsMenu</string>
+                                                                       </object>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="425164168">
+                                                                       <reference key="NSMenu" ref="720053764"/>
+                                                                       <bool key="NSIsDisabled">YES</bool>
+                                                                       <bool key="NSIsSeparator">YES</bool>
+                                                                       <string key="NSTitle"/>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="776162233">
+                                                                       <reference key="NSMenu" ref="720053764"/>
+                                                                       <string key="NSTitle">Close</string>
+                                                                       <string key="NSKeyEquiv">w</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="1023925487">
+                                                                       <reference key="NSMenu" ref="720053764"/>
+                                                                       <string key="NSTitle">Save…</string>
+                                                                       <string key="NSKeyEquiv">s</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="579971712">
+                                                                       <reference key="NSMenu" ref="720053764"/>
+                                                                       <string key="NSTitle">Revert to Saved</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="1010469920">
+                                                                       <reference key="NSMenu" ref="720053764"/>
+                                                                       <bool key="NSIsDisabled">YES</bool>
+                                                                       <bool key="NSIsSeparator">YES</bool>
+                                                                       <string key="NSTitle"/>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="294629803">
+                                                                       <reference key="NSMenu" ref="720053764"/>
+                                                                       <string key="NSTitle">Page Setup...</string>
+                                                                       <string key="NSKeyEquiv">P</string>
+                                                                       <int key="NSKeyEquivModMask">1179648</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                       <string key="NSToolTip"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="49223823">
+                                                                       <reference key="NSMenu" ref="720053764"/>
+                                                                       <string key="NSTitle">Print…</string>
+                                                                       <string key="NSKeyEquiv">p</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                       </array>
+                                               </object>
+                                       </object>
+                                       <object class="NSMenuItem" id="952259628">
+                                               <reference key="NSMenu" ref="649796088"/>
+                                               <string key="NSTitle">Edit</string>
+                                               <string key="NSKeyEquiv"/>
+                                               <int key="NSKeyEquivModMask">1048576</int>
+                                               <int key="NSMnemonicLoc">2147483647</int>
+                                               <reference key="NSOnImage" ref="35465992"/>
+                                               <reference key="NSMixedImage" ref="502551668"/>
+                                               <string key="NSAction">submenuAction:</string>
+                                               <reference key="NSTarget" ref="789758025"/>
+                                               <object class="NSMenu" key="NSSubmenu" id="789758025">
+                                                       <string key="NSTitle">Edit</string>
+                                                       <array class="NSMutableArray" key="NSMenuItems">
+                                                               <object class="NSMenuItem" id="1058277027">
+                                                                       <reference key="NSMenu" ref="789758025"/>
+                                                                       <string key="NSTitle">Undo</string>
+                                                                       <string key="NSKeyEquiv">z</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="790794224">
+                                                                       <reference key="NSMenu" ref="789758025"/>
+                                                                       <string key="NSTitle">Redo</string>
+                                                                       <string key="NSKeyEquiv">Z</string>
+                                                                       <int key="NSKeyEquivModMask">1179648</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="1040322652">
+                                                                       <reference key="NSMenu" ref="789758025"/>
+                                                                       <bool key="NSIsDisabled">YES</bool>
+                                                                       <bool key="NSIsSeparator">YES</bool>
+                                                                       <string key="NSTitle"/>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="296257095">
+                                                                       <reference key="NSMenu" ref="789758025"/>
+                                                                       <string key="NSTitle">Cut</string>
+                                                                       <string key="NSKeyEquiv">x</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="860595796">
+                                                                       <reference key="NSMenu" ref="789758025"/>
+                                                                       <string key="NSTitle">Copy</string>
+                                                                       <string key="NSKeyEquiv">c</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="29853731">
+                                                                       <reference key="NSMenu" ref="789758025"/>
+                                                                       <string key="NSTitle">Paste</string>
+                                                                       <string key="NSKeyEquiv">v</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="82994268">
+                                                                       <reference key="NSMenu" ref="789758025"/>
+                                                                       <string key="NSTitle">Paste and Match Style</string>
+                                                                       <string key="NSKeyEquiv">V</string>
+                                                                       <int key="NSKeyEquivModMask">1572864</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="437104165">
+                                                                       <reference key="NSMenu" ref="789758025"/>
+                                                                       <string key="NSTitle">Delete</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="583158037">
+                                                                       <reference key="NSMenu" ref="789758025"/>
+                                                                       <string key="NSTitle">Select All</string>
+                                                                       <string key="NSKeyEquiv">a</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="212016141">
+                                                                       <reference key="NSMenu" ref="789758025"/>
+                                                                       <bool key="NSIsDisabled">YES</bool>
+                                                                       <bool key="NSIsSeparator">YES</bool>
+                                                                       <string key="NSTitle"/>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="892235320">
+                                                                       <reference key="NSMenu" ref="789758025"/>
+                                                                       <string key="NSTitle">Find</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                       <string key="NSAction">submenuAction:</string>
+                                                                       <reference key="NSTarget" ref="963351320"/>
+                                                                       <object class="NSMenu" key="NSSubmenu" id="963351320">
+                                                                               <string key="NSTitle">Find</string>
+                                                                               <array class="NSMutableArray" key="NSMenuItems">
+                                                                                       <object class="NSMenuItem" id="447796847">
+                                                                                               <reference key="NSMenu" ref="963351320"/>
+                                                                                               <string key="NSTitle">Find…</string>
+                                                                                               <string key="NSKeyEquiv">f</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <int key="NSTag">1</int>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="738670835">
+                                                                                               <reference key="NSMenu" ref="963351320"/>
+                                                                                               <string key="NSTitle">Find and Replace…</string>
+                                                                                               <string key="NSKeyEquiv">f</string>
+                                                                                               <int key="NSKeyEquivModMask">1572864</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <int key="NSTag">12</int>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="326711663">
+                                                                                               <reference key="NSMenu" ref="963351320"/>
+                                                                                               <string key="NSTitle">Find Next</string>
+                                                                                               <string key="NSKeyEquiv">g</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <int key="NSTag">2</int>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="270902937">
+                                                                                               <reference key="NSMenu" ref="963351320"/>
+                                                                                               <string key="NSTitle">Find Previous</string>
+                                                                                               <string key="NSKeyEquiv">G</string>
+                                                                                               <int key="NSKeyEquivModMask">1179648</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <int key="NSTag">3</int>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="159080638">
+                                                                                               <reference key="NSMenu" ref="963351320"/>
+                                                                                               <string key="NSTitle">Use Selection for Find</string>
+                                                                                               <string key="NSKeyEquiv">e</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <int key="NSTag">7</int>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="88285865">
+                                                                                               <reference key="NSMenu" ref="963351320"/>
+                                                                                               <string key="NSTitle">Jump to Selection</string>
+                                                                                               <string key="NSKeyEquiv">j</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                               </array>
+                                                                       </object>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="972420730">
+                                                                       <reference key="NSMenu" ref="789758025"/>
+                                                                       <string key="NSTitle">Spelling and Grammar</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                       <string key="NSAction">submenuAction:</string>
+                                                                       <reference key="NSTarget" ref="769623530"/>
+                                                                       <object class="NSMenu" key="NSSubmenu" id="769623530">
+                                                                               <string key="NSTitle">Spelling and Grammar</string>
+                                                                               <array class="NSMutableArray" key="NSMenuItems">
+                                                                                       <object class="NSMenuItem" id="679648819">
+                                                                                               <reference key="NSMenu" ref="769623530"/>
+                                                                                               <string key="NSTitle">Show Spelling and Grammar</string>
+                                                                                               <string key="NSKeyEquiv">:</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="96193923">
+                                                                                               <reference key="NSMenu" ref="769623530"/>
+                                                                                               <string key="NSTitle">Check Document Now</string>
+                                                                                               <string key="NSKeyEquiv">;</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="859480356">
+                                                                                               <reference key="NSMenu" ref="769623530"/>
+                                                                                               <bool key="NSIsDisabled">YES</bool>
+                                                                                               <bool key="NSIsSeparator">YES</bool>
+                                                                                               <string key="NSTitle"/>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="948374510">
+                                                                                               <reference key="NSMenu" ref="769623530"/>
+                                                                                               <string key="NSTitle">Check Spelling While Typing</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="967646866">
+                                                                                               <reference key="NSMenu" ref="769623530"/>
+                                                                                               <string key="NSTitle">Check Grammar With Spelling</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="795346622">
+                                                                                               <reference key="NSMenu" ref="769623530"/>
+                                                                                               <string key="NSTitle">Correct Spelling Automatically</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                               </array>
+                                                                       </object>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="507821607">
+                                                                       <reference key="NSMenu" ref="789758025"/>
+                                                                       <string key="NSTitle">Substitutions</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                       <string key="NSAction">submenuAction:</string>
+                                                                       <reference key="NSTarget" ref="698887838"/>
+                                                                       <object class="NSMenu" key="NSSubmenu" id="698887838">
+                                                                               <string key="NSTitle">Substitutions</string>
+                                                                               <array class="NSMutableArray" key="NSMenuItems">
+                                                                                       <object class="NSMenuItem" id="65139061">
+                                                                                               <reference key="NSMenu" ref="698887838"/>
+                                                                                               <string key="NSTitle">Show Substitutions</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="19036812">
+                                                                                               <reference key="NSMenu" ref="698887838"/>
+                                                                                               <bool key="NSIsDisabled">YES</bool>
+                                                                                               <bool key="NSIsSeparator">YES</bool>
+                                                                                               <string key="NSTitle"/>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="605118523">
+                                                                                               <reference key="NSMenu" ref="698887838"/>
+                                                                                               <string key="NSTitle">Smart Copy/Paste</string>
+                                                                                               <string key="NSKeyEquiv">f</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <int key="NSTag">1</int>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="197661976">
+                                                                                               <reference key="NSMenu" ref="698887838"/>
+                                                                                               <string key="NSTitle">Smart Quotes</string>
+                                                                                               <string key="NSKeyEquiv">g</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <int key="NSTag">2</int>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="672708820">
+                                                                                               <reference key="NSMenu" ref="698887838"/>
+                                                                                               <string key="NSTitle">Smart Dashes</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="708854459">
+                                                                                               <reference key="NSMenu" ref="698887838"/>
+                                                                                               <string key="NSTitle">Smart Links</string>
+                                                                                               <string key="NSKeyEquiv">G</string>
+                                                                                               <int key="NSKeyEquivModMask">1179648</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <int key="NSTag">3</int>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="537092702">
+                                                                                               <reference key="NSMenu" ref="698887838"/>
+                                                                                               <string key="NSTitle">Text Replacement</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                               </array>
+                                                                       </object>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="288088188">
+                                                                       <reference key="NSMenu" ref="789758025"/>
+                                                                       <string key="NSTitle">Transformations</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                       <string key="NSAction">submenuAction:</string>
+                                                                       <reference key="NSTarget" ref="579392910"/>
+                                                                       <object class="NSMenu" key="NSSubmenu" id="579392910">
+                                                                               <string key="NSTitle">Transformations</string>
+                                                                               <array class="NSMutableArray" key="NSMenuItems">
+                                                                                       <object class="NSMenuItem" id="1060694897">
+                                                                                               <reference key="NSMenu" ref="579392910"/>
+                                                                                               <string key="NSTitle">Make Upper Case</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="879586729">
+                                                                                               <reference key="NSMenu" ref="579392910"/>
+                                                                                               <string key="NSTitle">Make Lower Case</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="56570060">
+                                                                                               <reference key="NSMenu" ref="579392910"/>
+                                                                                               <string key="NSTitle">Capitalize</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                               </array>
+                                                                       </object>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="676164635">
+                                                                       <reference key="NSMenu" ref="789758025"/>
+                                                                       <string key="NSTitle">Speech</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                       <string key="NSAction">submenuAction:</string>
+                                                                       <reference key="NSTarget" ref="785027613"/>
+                                                                       <object class="NSMenu" key="NSSubmenu" id="785027613">
+                                                                               <string key="NSTitle">Speech</string>
+                                                                               <array class="NSMutableArray" key="NSMenuItems">
+                                                                                       <object class="NSMenuItem" id="731782645">
+                                                                                               <reference key="NSMenu" ref="785027613"/>
+                                                                                               <string key="NSTitle">Start Speaking</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="680220178">
+                                                                                               <reference key="NSMenu" ref="785027613"/>
+                                                                                               <string key="NSTitle">Stop Speaking</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                               </array>
+                                                                       </object>
+                                                               </object>
+                                                       </array>
+                                               </object>
+                                       </object>
+                                       <object class="NSMenuItem" id="302598603">
+                                               <reference key="NSMenu" ref="649796088"/>
+                                               <string key="NSTitle">Format</string>
+                                               <string key="NSKeyEquiv"/>
+                                               <int key="NSMnemonicLoc">2147483647</int>
+                                               <reference key="NSOnImage" ref="35465992"/>
+                                               <reference key="NSMixedImage" ref="502551668"/>
+                                               <string key="NSAction">submenuAction:</string>
+                                               <reference key="NSTarget" ref="941447902"/>
+                                               <object class="NSMenu" key="NSSubmenu" id="941447902">
+                                                       <string key="NSTitle">Format</string>
+                                                       <array class="NSMutableArray" key="NSMenuItems">
+                                                               <object class="NSMenuItem" id="792887677">
+                                                                       <reference key="NSMenu" ref="941447902"/>
+                                                                       <string key="NSTitle">Font</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                       <string key="NSAction">submenuAction:</string>
+                                                                       <reference key="NSTarget" ref="786677654"/>
+                                                                       <object class="NSMenu" key="NSSubmenu" id="786677654">
+                                                                               <string key="NSTitle">Font</string>
+                                                                               <array class="NSMutableArray" key="NSMenuItems">
+                                                                                       <object class="NSMenuItem" id="159677712">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <string key="NSTitle">Show Fonts</string>
+                                                                                               <string key="NSKeyEquiv">t</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="305399458">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <string key="NSTitle">Bold</string>
+                                                                                               <string key="NSKeyEquiv">b</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <int key="NSTag">2</int>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="814362025">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <string key="NSTitle">Italic</string>
+                                                                                               <string key="NSKeyEquiv">i</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <int key="NSTag">1</int>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="330926929">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <string key="NSTitle">Underline</string>
+                                                                                               <string key="NSKeyEquiv">u</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="533507878">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <bool key="NSIsDisabled">YES</bool>
+                                                                                               <bool key="NSIsSeparator">YES</bool>
+                                                                                               <string key="NSTitle"/>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="158063935">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <string key="NSTitle">Bigger</string>
+                                                                                               <string key="NSKeyEquiv">+</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <int key="NSTag">3</int>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="885547335">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <string key="NSTitle">Smaller</string>
+                                                                                               <string key="NSKeyEquiv">-</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <int key="NSTag">4</int>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="901062459">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <bool key="NSIsDisabled">YES</bool>
+                                                                                               <bool key="NSIsSeparator">YES</bool>
+                                                                                               <string key="NSTitle"/>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="767671776">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <string key="NSTitle">Kern</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <string key="NSAction">submenuAction:</string>
+                                                                                               <reference key="NSTarget" ref="175441468"/>
+                                                                                               <object class="NSMenu" key="NSSubmenu" id="175441468">
+                                                                                                       <string key="NSTitle">Kern</string>
+                                                                                                       <array class="NSMutableArray" key="NSMenuItems">
+                                                                                                               <object class="NSMenuItem" id="252969304">
+                                                                                                                       <reference key="NSMenu" ref="175441468"/>
+                                                                                                                       <string key="NSTitle">Use Default</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="766922938">
+                                                                                                                       <reference key="NSMenu" ref="175441468"/>
+                                                                                                                       <string key="NSTitle">Use None</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="677519740">
+                                                                                                                       <reference key="NSMenu" ref="175441468"/>
+                                                                                                                       <string key="NSTitle">Tighten</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="238351151">
+                                                                                                                       <reference key="NSMenu" ref="175441468"/>
+                                                                                                                       <string key="NSTitle">Loosen</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                       </array>
+                                                                                               </object>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="691570813">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <string key="NSTitle">Ligatures</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <string key="NSAction">submenuAction:</string>
+                                                                                               <reference key="NSTarget" ref="1058217995"/>
+                                                                                               <object class="NSMenu" key="NSSubmenu" id="1058217995">
+                                                                                                       <string key="NSTitle">Ligatures</string>
+                                                                                                       <array class="NSMutableArray" key="NSMenuItems">
+                                                                                                               <object class="NSMenuItem" id="706297211">
+                                                                                                                       <reference key="NSMenu" ref="1058217995"/>
+                                                                                                                       <string key="NSTitle">Use Default</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="568384683">
+                                                                                                                       <reference key="NSMenu" ref="1058217995"/>
+                                                                                                                       <string key="NSTitle">Use None</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="663508465">
+                                                                                                                       <reference key="NSMenu" ref="1058217995"/>
+                                                                                                                       <string key="NSTitle">Use All</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                       </array>
+                                                                                               </object>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="769124883">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <string key="NSTitle">Baseline</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <string key="NSAction">submenuAction:</string>
+                                                                                               <reference key="NSTarget" ref="18263474"/>
+                                                                                               <object class="NSMenu" key="NSSubmenu" id="18263474">
+                                                                                                       <string key="NSTitle">Baseline</string>
+                                                                                                       <array class="NSMutableArray" key="NSMenuItems">
+                                                                                                               <object class="NSMenuItem" id="257962622">
+                                                                                                                       <reference key="NSMenu" ref="18263474"/>
+                                                                                                                       <string key="NSTitle">Use Default</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="644725453">
+                                                                                                                       <reference key="NSMenu" ref="18263474"/>
+                                                                                                                       <string key="NSTitle">Superscript</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="1037576581">
+                                                                                                                       <reference key="NSMenu" ref="18263474"/>
+                                                                                                                       <string key="NSTitle">Subscript</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="941806246">
+                                                                                                                       <reference key="NSMenu" ref="18263474"/>
+                                                                                                                       <string key="NSTitle">Raise</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="1045724900">
+                                                                                                                       <reference key="NSMenu" ref="18263474"/>
+                                                                                                                       <string key="NSTitle">Lower</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                       </array>
+                                                                                               </object>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="739652853">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <bool key="NSIsDisabled">YES</bool>
+                                                                                               <bool key="NSIsSeparator">YES</bool>
+                                                                                               <string key="NSTitle"/>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="1012600125">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <string key="NSTitle">Show Colors</string>
+                                                                                               <string key="NSKeyEquiv">C</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="214559597">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <bool key="NSIsDisabled">YES</bool>
+                                                                                               <bool key="NSIsSeparator">YES</bool>
+                                                                                               <string key="NSTitle"/>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="596732606">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <string key="NSTitle">Copy Style</string>
+                                                                                               <string key="NSKeyEquiv">c</string>
+                                                                                               <int key="NSKeyEquivModMask">1572864</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="393423671">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <string key="NSTitle">Paste Style</string>
+                                                                                               <string key="NSKeyEquiv">v</string>
+                                                                                               <int key="NSKeyEquivModMask">1572864</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                               </array>
+                                                                               <string key="NSName">_NSFontMenu</string>
+                                                                       </object>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="215659978">
+                                                                       <reference key="NSMenu" ref="941447902"/>
+                                                                       <string key="NSTitle">Text</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                       <string key="NSAction">submenuAction:</string>
+                                                                       <reference key="NSTarget" ref="446991534"/>
+                                                                       <object class="NSMenu" key="NSSubmenu" id="446991534">
+                                                                               <string key="NSTitle">Text</string>
+                                                                               <array class="NSMutableArray" key="NSMenuItems">
+                                                                                       <object class="NSMenuItem" id="875092757">
+                                                                                               <reference key="NSMenu" ref="446991534"/>
+                                                                                               <string key="NSTitle">Align Left</string>
+                                                                                               <string key="NSKeyEquiv">{</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="630155264">
+                                                                                               <reference key="NSMenu" ref="446991534"/>
+                                                                                               <string key="NSTitle">Center</string>
+                                                                                               <string key="NSKeyEquiv">|</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="945678886">
+                                                                                               <reference key="NSMenu" ref="446991534"/>
+                                                                                               <string key="NSTitle">Justify</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="512868991">
+                                                                                               <reference key="NSMenu" ref="446991534"/>
+                                                                                               <string key="NSTitle">Align Right</string>
+                                                                                               <string key="NSKeyEquiv">}</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="163117631">
+                                                                                               <reference key="NSMenu" ref="446991534"/>
+                                                                                               <bool key="NSIsDisabled">YES</bool>
+                                                                                               <bool key="NSIsSeparator">YES</bool>
+                                                                                               <string key="NSTitle"/>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="31516759">
+                                                                                               <reference key="NSMenu" ref="446991534"/>
+                                                                                               <string key="NSTitle">Writing Direction</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <string key="NSAction">submenuAction:</string>
+                                                                                               <reference key="NSTarget" ref="956096989"/>
+                                                                                               <object class="NSMenu" key="NSSubmenu" id="956096989">
+                                                                                                       <string key="NSTitle">Writing Direction</string>
+                                                                                                       <array class="NSMutableArray" key="NSMenuItems">
+                                                                                                               <object class="NSMenuItem" id="257099033">
+                                                                                                                       <reference key="NSMenu" ref="956096989"/>
+                                                                                                                       <bool key="NSIsDisabled">YES</bool>
+                                                                                                                       <string key="NSTitle">Paragraph</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="551969625">
+                                                                                                                       <reference key="NSMenu" ref="956096989"/>
+                                                                                                                       <string type="base64-UTF8" key="NSTitle">CURlZmF1bHQ</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="249532473">
+                                                                                                                       <reference key="NSMenu" ref="956096989"/>
+                                                                                                                       <string type="base64-UTF8" key="NSTitle">CUxlZnQgdG8gUmlnaHQ</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="607364498">
+                                                                                                                       <reference key="NSMenu" ref="956096989"/>
+                                                                                                                       <string type="base64-UTF8" key="NSTitle">CVJpZ2h0IHRvIExlZnQ</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="508151438">
+                                                                                                                       <reference key="NSMenu" ref="956096989"/>
+                                                                                                                       <bool key="NSIsDisabled">YES</bool>
+                                                                                                                       <bool key="NSIsSeparator">YES</bool>
+                                                                                                                       <string key="NSTitle"/>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="981751889">
+                                                                                                                       <reference key="NSMenu" ref="956096989"/>
+                                                                                                                       <bool key="NSIsDisabled">YES</bool>
+                                                                                                                       <string key="NSTitle">Selection</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="380031999">
+                                                                                                                       <reference key="NSMenu" ref="956096989"/>
+                                                                                                                       <string type="base64-UTF8" key="NSTitle">CURlZmF1bHQ</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="825984362">
+                                                                                                                       <reference key="NSMenu" ref="956096989"/>
+                                                                                                                       <string type="base64-UTF8" key="NSTitle">CUxlZnQgdG8gUmlnaHQ</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="560145579">
+                                                                                                                       <reference key="NSMenu" ref="956096989"/>
+                                                                                                                       <string type="base64-UTF8" key="NSTitle">CVJpZ2h0IHRvIExlZnQ</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                       </array>
+                                                                                               </object>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="908105787">
+                                                                                               <reference key="NSMenu" ref="446991534"/>
+                                                                                               <bool key="NSIsDisabled">YES</bool>
+                                                                                               <bool key="NSIsSeparator">YES</bool>
+                                                                                               <string key="NSTitle"/>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="644046920">
+                                                                                               <reference key="NSMenu" ref="446991534"/>
+                                                                                               <string key="NSTitle">Show Ruler</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="231811626">
+                                                                                               <reference key="NSMenu" ref="446991534"/>
+                                                                                               <string key="NSTitle">Copy Ruler</string>
+                                                                                               <string key="NSKeyEquiv">c</string>
+                                                                                               <int key="NSKeyEquivModMask">1310720</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="883618387">
+                                                                                               <reference key="NSMenu" ref="446991534"/>
+                                                                                               <string key="NSTitle">Paste Ruler</string>
+                                                                                               <string key="NSKeyEquiv">v</string>
+                                                                                               <int key="NSKeyEquivModMask">1310720</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                               </array>
+                                                                       </object>
+                                                               </object>
+                                                       </array>
+                                               </object>
+                                       </object>
+                                       <object class="NSMenuItem" id="586577488">
+                                               <reference key="NSMenu" ref="649796088"/>
+                                               <string key="NSTitle">View</string>
+                                               <string key="NSKeyEquiv"/>
+                                               <int key="NSKeyEquivModMask">1048576</int>
+                                               <int key="NSMnemonicLoc">2147483647</int>
+                                               <reference key="NSOnImage" ref="35465992"/>
+                                               <reference key="NSMixedImage" ref="502551668"/>
+                                               <string key="NSAction">submenuAction:</string>
+                                               <reference key="NSTarget" ref="466310130"/>
+                                               <object class="NSMenu" key="NSSubmenu" id="466310130">
+                                                       <string key="NSTitle">View</string>
+                                                       <array class="NSMutableArray" key="NSMenuItems">
+                                                               <object class="NSMenuItem" id="102151532">
+                                                                       <reference key="NSMenu" ref="466310130"/>
+                                                                       <string key="NSTitle">Show Toolbar</string>
+                                                                       <string key="NSKeyEquiv">t</string>
+                                                                       <int key="NSKeyEquivModMask">1572864</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="237841660">
+                                                                       <reference key="NSMenu" ref="466310130"/>
+                                                                       <string key="NSTitle">Customize Toolbar…</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                       </array>
+                                               </object>
+                                       </object>
+                                       <object class="NSMenuItem" id="713487014">
+                                               <reference key="NSMenu" ref="649796088"/>
+                                               <string key="NSTitle">Window</string>
+                                               <string key="NSKeyEquiv"/>
+                                               <int key="NSKeyEquivModMask">1048576</int>
+                                               <int key="NSMnemonicLoc">2147483647</int>
+                                               <reference key="NSOnImage" ref="35465992"/>
+                                               <reference key="NSMixedImage" ref="502551668"/>
+                                               <string key="NSAction">submenuAction:</string>
+                                               <reference key="NSTarget" ref="835318025"/>
+                                               <object class="NSMenu" key="NSSubmenu" id="835318025">
+                                                       <string key="NSTitle">Window</string>
+                                                       <array class="NSMutableArray" key="NSMenuItems">
+                                                               <object class="NSMenuItem" id="1011231497">
+                                                                       <reference key="NSMenu" ref="835318025"/>
+                                                                       <string key="NSTitle">Minimize</string>
+                                                                       <string key="NSKeyEquiv">m</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="575023229">
+                                                                       <reference key="NSMenu" ref="835318025"/>
+                                                                       <string key="NSTitle">Zoom</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="299356726">
+                                                                       <reference key="NSMenu" ref="835318025"/>
+                                                                       <bool key="NSIsDisabled">YES</bool>
+                                                                       <bool key="NSIsSeparator">YES</bool>
+                                                                       <string key="NSTitle"/>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="625202149">
+                                                                       <reference key="NSMenu" ref="835318025"/>
+                                                                       <string key="NSTitle">Bring All to Front</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                       </array>
+                                                       <string key="NSName">_NSWindowsMenu</string>
+                                               </object>
+                                       </object>
+                                       <object class="NSMenuItem" id="448692316">
+                                               <reference key="NSMenu" ref="649796088"/>
+                                               <string key="NSTitle">Help</string>
+                                               <string key="NSKeyEquiv"/>
+                                               <int key="NSMnemonicLoc">2147483647</int>
+                                               <reference key="NSOnImage" ref="35465992"/>
+                                               <reference key="NSMixedImage" ref="502551668"/>
+                                               <string key="NSAction">submenuAction:</string>
+                                               <reference key="NSTarget" ref="992780483"/>
+                                               <object class="NSMenu" key="NSSubmenu" id="992780483">
+                                                       <string key="NSTitle">Help</string>
+                                                       <array class="NSMutableArray" key="NSMenuItems">
+                                                               <object class="NSMenuItem" id="105068016">
+                                                                       <reference key="NSMenu" ref="992780483"/>
+                                                                       <string key="NSTitle">Keychain Circle Notification Help</string>
+                                                                       <string key="NSKeyEquiv">?</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                       </array>
+                                                       <string key="NSName">_NSHelpMenu</string>
+                                               </object>
+                                       </object>
+                               </array>
+                               <string key="NSName">_NSMainMenu</string>
+                       </object>
+                       <object class="NSCustomObject" id="976324537">
+                               <string key="NSClassName">KNAppDelegate</string>
+                       </object>
+                       <object class="NSCustomObject" id="755631768">
+                               <string key="NSClassName">NSFontManager</string>
+                       </object>
+               </array>
+               <object class="IBObjectContainer" key="IBDocument.Objects">
+                       <array class="NSMutableArray" key="connectionRecords">
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">terminate:</string>
+                                               <reference key="source" ref="1050"/>
+                                               <reference key="destination" ref="632727374"/>
+                                       </object>
+                                       <int key="connectionID">449</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">orderFrontStandardAboutPanel:</string>
+                                               <reference key="source" ref="1021"/>
+                                               <reference key="destination" ref="238522557"/>
+                                       </object>
+                                       <int key="connectionID">142</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBOutletConnection" key="connection">
+                                               <string key="label">delegate</string>
+                                               <reference key="source" ref="1021"/>
+                                               <reference key="destination" ref="976324537"/>
+                                       </object>
+                                       <int key="connectionID">495</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">performMiniaturize:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="1011231497"/>
+                                       </object>
+                                       <int key="connectionID">37</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">arrangeInFront:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="625202149"/>
+                                       </object>
+                                       <int key="connectionID">39</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">print:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="49223823"/>
+                                       </object>
+                                       <int key="connectionID">86</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">runPageLayout:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="294629803"/>
+                                       </object>
+                                       <int key="connectionID">87</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">clearRecentDocuments:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="759406840"/>
+                                       </object>
+                                       <int key="connectionID">127</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">performClose:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="776162233"/>
+                                       </object>
+                                       <int key="connectionID">193</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">toggleContinuousSpellChecking:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="948374510"/>
+                                       </object>
+                                       <int key="connectionID">222</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">undo:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="1058277027"/>
+                                       </object>
+                                       <int key="connectionID">223</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">copy:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="860595796"/>
+                                       </object>
+                                       <int key="connectionID">224</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">checkSpelling:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="96193923"/>
+                                       </object>
+                                       <int key="connectionID">225</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">paste:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="29853731"/>
+                                       </object>
+                                       <int key="connectionID">226</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">stopSpeaking:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="680220178"/>
+                                       </object>
+                                       <int key="connectionID">227</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">cut:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="296257095"/>
+                                       </object>
+                                       <int key="connectionID">228</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">showGuessPanel:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="679648819"/>
+                                       </object>
+                                       <int key="connectionID">230</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">redo:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="790794224"/>
+                                       </object>
+                                       <int key="connectionID">231</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">selectAll:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="583158037"/>
+                                       </object>
+                                       <int key="connectionID">232</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">startSpeaking:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="731782645"/>
+                                       </object>
+                                       <int key="connectionID">233</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">delete:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="437104165"/>
+                                       </object>
+                                       <int key="connectionID">235</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">performZoom:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="575023229"/>
+                                       </object>
+                                       <int key="connectionID">240</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">performFindPanelAction:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="447796847"/>
+                                       </object>
+                                       <int key="connectionID">241</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">centerSelectionInVisibleArea:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="88285865"/>
+                                       </object>
+                                       <int key="connectionID">245</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">toggleGrammarChecking:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="967646866"/>
+                                       </object>
+                                       <int key="connectionID">347</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">toggleSmartInsertDelete:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="605118523"/>
+                                       </object>
+                                       <int key="connectionID">355</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">toggleAutomaticQuoteSubstitution:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="197661976"/>
+                                       </object>
+                                       <int key="connectionID">356</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">toggleAutomaticLinkDetection:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="708854459"/>
+                                       </object>
+                                       <int key="connectionID">357</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">saveDocument:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="1023925487"/>
+                                       </object>
+                                       <int key="connectionID">362</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">revertDocumentToSaved:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="579971712"/>
+                                       </object>
+                                       <int key="connectionID">364</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">runToolbarCustomizationPalette:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="237841660"/>
+                                       </object>
+                                       <int key="connectionID">365</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">toggleToolbarShown:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="102151532"/>
+                                       </object>
+                                       <int key="connectionID">366</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">hide:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="755159360"/>
+                                       </object>
+                                       <int key="connectionID">367</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">hideOtherApplications:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="342932134"/>
+                                       </object>
+                                       <int key="connectionID">368</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">unhideAllApplications:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="908899353"/>
+                                       </object>
+                                       <int key="connectionID">370</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">newDocument:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="705341025"/>
+                                       </object>
+                                       <int key="connectionID">373</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">openDocument:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="722745758"/>
+                                       </object>
+                                       <int key="connectionID">374</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">raiseBaseline:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="941806246"/>
+                                       </object>
+                                       <int key="connectionID">426</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">lowerBaseline:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="1045724900"/>
+                                       </object>
+                                       <int key="connectionID">427</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">copyFont:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="596732606"/>
+                                       </object>
+                                       <int key="connectionID">428</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">subscript:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="1037576581"/>
+                                       </object>
+                                       <int key="connectionID">429</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">superscript:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="644725453"/>
+                                       </object>
+                                       <int key="connectionID">430</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">tightenKerning:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="677519740"/>
+                                       </object>
+                                       <int key="connectionID">431</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">underline:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="330926929"/>
+                                       </object>
+                                       <int key="connectionID">432</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">orderFrontColorPanel:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="1012600125"/>
+                                       </object>
+                                       <int key="connectionID">433</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">useAllLigatures:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="663508465"/>
+                                       </object>
+                                       <int key="connectionID">434</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">loosenKerning:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="238351151"/>
+                                       </object>
+                                       <int key="connectionID">435</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">pasteFont:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="393423671"/>
+                                       </object>
+                                       <int key="connectionID">436</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">unscript:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="257962622"/>
+                                       </object>
+                                       <int key="connectionID">437</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">useStandardKerning:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="252969304"/>
+                                       </object>
+                                       <int key="connectionID">438</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">useStandardLigatures:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="706297211"/>
+                                       </object>
+                                       <int key="connectionID">439</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">turnOffLigatures:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="568384683"/>
+                                       </object>
+                                       <int key="connectionID">440</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">turnOffKerning:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="766922938"/>
+                                       </object>
+                                       <int key="connectionID">441</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">toggleAutomaticSpellingCorrection:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="795346622"/>
+                                       </object>
+                                       <int key="connectionID">456</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">orderFrontSubstitutionsPanel:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="65139061"/>
+                                       </object>
+                                       <int key="connectionID">458</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">toggleAutomaticDashSubstitution:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="672708820"/>
+                                       </object>
+                                       <int key="connectionID">461</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">toggleAutomaticTextReplacement:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="537092702"/>
+                                       </object>
+                                       <int key="connectionID">463</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">uppercaseWord:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="1060694897"/>
+                                       </object>
+                                       <int key="connectionID">464</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">capitalizeWord:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="56570060"/>
+                                       </object>
+                                       <int key="connectionID">467</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">lowercaseWord:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="879586729"/>
+                                       </object>
+                                       <int key="connectionID">468</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">pasteAsPlainText:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="82994268"/>
+                                       </object>
+                                       <int key="connectionID">486</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">performFindPanelAction:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="326711663"/>
+                                       </object>
+                                       <int key="connectionID">487</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">performFindPanelAction:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="270902937"/>
+                                       </object>
+                                       <int key="connectionID">488</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">performFindPanelAction:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="159080638"/>
+                                       </object>
+                                       <int key="connectionID">489</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">showHelp:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="105068016"/>
+                                       </object>
+                                       <int key="connectionID">493</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">alignCenter:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="630155264"/>
+                                       </object>
+                                       <int key="connectionID">518</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">pasteRuler:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="883618387"/>
+                                       </object>
+                                       <int key="connectionID">519</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">toggleRuler:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="644046920"/>
+                                       </object>
+                                       <int key="connectionID">520</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">alignRight:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="512868991"/>
+                                       </object>
+                                       <int key="connectionID">521</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">copyRuler:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="231811626"/>
+                                       </object>
+                                       <int key="connectionID">522</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">alignJustified:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="945678886"/>
+                                       </object>
+                                       <int key="connectionID">523</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">alignLeft:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="875092757"/>
+                                       </object>
+                                       <int key="connectionID">524</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">makeBaseWritingDirectionNatural:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="551969625"/>
+                                       </object>
+                                       <int key="connectionID">525</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">makeBaseWritingDirectionLeftToRight:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="249532473"/>
+                                       </object>
+                                       <int key="connectionID">526</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">makeBaseWritingDirectionRightToLeft:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="607364498"/>
+                                       </object>
+                                       <int key="connectionID">527</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">makeTextWritingDirectionNatural:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="380031999"/>
+                                       </object>
+                                       <int key="connectionID">528</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">makeTextWritingDirectionLeftToRight:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="825984362"/>
+                                       </object>
+                                       <int key="connectionID">529</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">makeTextWritingDirectionRightToLeft:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="560145579"/>
+                                       </object>
+                                       <int key="connectionID">530</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">performFindPanelAction:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="738670835"/>
+                                       </object>
+                                       <int key="connectionID">535</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">addFontTrait:</string>
+                                               <reference key="source" ref="755631768"/>
+                                               <reference key="destination" ref="305399458"/>
+                                       </object>
+                                       <int key="connectionID">421</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">addFontTrait:</string>
+                                               <reference key="source" ref="755631768"/>
+                                               <reference key="destination" ref="814362025"/>
+                                       </object>
+                                       <int key="connectionID">422</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">modifyFont:</string>
+                                               <reference key="source" ref="755631768"/>
+                                               <reference key="destination" ref="885547335"/>
+                                       </object>
+                                       <int key="connectionID">423</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">orderFrontFontPanel:</string>
+                                               <reference key="source" ref="755631768"/>
+                                               <reference key="destination" ref="159677712"/>
+                                       </object>
+                                       <int key="connectionID">424</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">modifyFont:</string>
+                                               <reference key="source" ref="755631768"/>
+                                               <reference key="destination" ref="158063935"/>
+                                       </object>
+                                       <int key="connectionID">425</int>
+                               </object>
+                       </array>
+                       <object class="IBMutableOrderedSet" key="objectRecords">
+                               <array key="orderedObjects">
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">0</int>
+                                               <array key="object" id="0"/>
+                                               <reference key="children" ref="1048"/>
+                                               <nil key="parent"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-2</int>
+                                               <reference key="object" ref="1021"/>
+                                               <reference key="parent" ref="0"/>
+                                               <string key="objectName">File's Owner</string>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-1</int>
+                                               <reference key="object" ref="1014"/>
+                                               <reference key="parent" ref="0"/>
+                                               <string key="objectName">First Responder</string>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-3</int>
+                                               <reference key="object" ref="1050"/>
+                                               <reference key="parent" ref="0"/>
+                                               <string key="objectName">Application</string>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">29</int>
+                                               <reference key="object" ref="649796088"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="713487014"/>
+                                                       <reference ref="694149608"/>
+                                                       <reference ref="952259628"/>
+                                                       <reference ref="379814623"/>
+                                                       <reference ref="586577488"/>
+                                                       <reference ref="302598603"/>
+                                                       <reference ref="448692316"/>
+                                               </array>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">19</int>
+                                               <reference key="object" ref="713487014"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="835318025"/>
+                                               </array>
+                                               <reference key="parent" ref="649796088"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">56</int>
+                                               <reference key="object" ref="694149608"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="110575045"/>
+                                               </array>
+                                               <reference key="parent" ref="649796088"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">217</int>
+                                               <reference key="object" ref="952259628"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="789758025"/>
+                                               </array>
+                                               <reference key="parent" ref="649796088"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">83</int>
+                                               <reference key="object" ref="379814623"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="720053764"/>
+                                               </array>
+                                               <reference key="parent" ref="649796088"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">81</int>
+                                               <reference key="object" ref="720053764"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="1023925487"/>
+                                                       <reference ref="49223823"/>
+                                                       <reference ref="722745758"/>
+                                                       <reference ref="705341025"/>
+                                                       <reference ref="1025936716"/>
+                                                       <reference ref="294629803"/>
+                                                       <reference ref="776162233"/>
+                                                       <reference ref="425164168"/>
+                                                       <reference ref="579971712"/>
+                                                       <reference ref="1010469920"/>
+                                               </array>
+                                               <reference key="parent" ref="379814623"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">75</int>
+                                               <reference key="object" ref="1023925487"/>
+                                               <reference key="parent" ref="720053764"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">78</int>
+                                               <reference key="object" ref="49223823"/>
+                                               <reference key="parent" ref="720053764"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">72</int>
+                                               <reference key="object" ref="722745758"/>
+                                               <reference key="parent" ref="720053764"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">82</int>
+                                               <reference key="object" ref="705341025"/>
+                                               <reference key="parent" ref="720053764"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">124</int>
+                                               <reference key="object" ref="1025936716"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="1065607017"/>
+                                               </array>
+                                               <reference key="parent" ref="720053764"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">77</int>
+                                               <reference key="object" ref="294629803"/>
+                                               <reference key="parent" ref="720053764"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">73</int>
+                                               <reference key="object" ref="776162233"/>
+                                               <reference key="parent" ref="720053764"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">79</int>
+                                               <reference key="object" ref="425164168"/>
+                                               <reference key="parent" ref="720053764"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">112</int>
+                                               <reference key="object" ref="579971712"/>
+                                               <reference key="parent" ref="720053764"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">74</int>
+                                               <reference key="object" ref="1010469920"/>
+                                               <reference key="parent" ref="720053764"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">125</int>
+                                               <reference key="object" ref="1065607017"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="759406840"/>
+                                               </array>
+                                               <reference key="parent" ref="1025936716"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">126</int>
+                                               <reference key="object" ref="759406840"/>
+                                               <reference key="parent" ref="1065607017"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">205</int>
+                                               <reference key="object" ref="789758025"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="437104165"/>
+                                                       <reference ref="583158037"/>
+                                                       <reference ref="1058277027"/>
+                                                       <reference ref="212016141"/>
+                                                       <reference ref="296257095"/>
+                                                       <reference ref="29853731"/>
+                                                       <reference ref="860595796"/>
+                                                       <reference ref="1040322652"/>
+                                                       <reference ref="790794224"/>
+                                                       <reference ref="892235320"/>
+                                                       <reference ref="972420730"/>
+                                                       <reference ref="676164635"/>
+                                                       <reference ref="507821607"/>
+                                                       <reference ref="288088188"/>
+                                                       <reference ref="82994268"/>
+                                               </array>
+                                               <reference key="parent" ref="952259628"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">202</int>
+                                               <reference key="object" ref="437104165"/>
+                                               <reference key="parent" ref="789758025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">198</int>
+                                               <reference key="object" ref="583158037"/>
+                                               <reference key="parent" ref="789758025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">207</int>
+                                               <reference key="object" ref="1058277027"/>
+                                               <reference key="parent" ref="789758025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">214</int>
+                                               <reference key="object" ref="212016141"/>
+                                               <reference key="parent" ref="789758025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">199</int>
+                                               <reference key="object" ref="296257095"/>
+                                               <reference key="parent" ref="789758025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">203</int>
+                                               <reference key="object" ref="29853731"/>
+                                               <reference key="parent" ref="789758025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">197</int>
+                                               <reference key="object" ref="860595796"/>
+                                               <reference key="parent" ref="789758025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">206</int>
+                                               <reference key="object" ref="1040322652"/>
+                                               <reference key="parent" ref="789758025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">215</int>
+                                               <reference key="object" ref="790794224"/>
+                                               <reference key="parent" ref="789758025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">218</int>
+                                               <reference key="object" ref="892235320"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="963351320"/>
+                                               </array>
+                                               <reference key="parent" ref="789758025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">216</int>
+                                               <reference key="object" ref="972420730"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="769623530"/>
+                                               </array>
+                                               <reference key="parent" ref="789758025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">200</int>
+                                               <reference key="object" ref="769623530"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="948374510"/>
+                                                       <reference ref="96193923"/>
+                                                       <reference ref="679648819"/>
+                                                       <reference ref="967646866"/>
+                                                       <reference ref="859480356"/>
+                                                       <reference ref="795346622"/>
+                                               </array>
+                                               <reference key="parent" ref="972420730"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">219</int>
+                                               <reference key="object" ref="948374510"/>
+                                               <reference key="parent" ref="769623530"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">201</int>
+                                               <reference key="object" ref="96193923"/>
+                                               <reference key="parent" ref="769623530"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">204</int>
+                                               <reference key="object" ref="679648819"/>
+                                               <reference key="parent" ref="769623530"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">220</int>
+                                               <reference key="object" ref="963351320"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="270902937"/>
+                                                       <reference ref="88285865"/>
+                                                       <reference ref="159080638"/>
+                                                       <reference ref="326711663"/>
+                                                       <reference ref="447796847"/>
+                                                       <reference ref="738670835"/>
+                                               </array>
+                                               <reference key="parent" ref="892235320"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">213</int>
+                                               <reference key="object" ref="270902937"/>
+                                               <reference key="parent" ref="963351320"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">210</int>
+                                               <reference key="object" ref="88285865"/>
+                                               <reference key="parent" ref="963351320"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">221</int>
+                                               <reference key="object" ref="159080638"/>
+                                               <reference key="parent" ref="963351320"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">208</int>
+                                               <reference key="object" ref="326711663"/>
+                                               <reference key="parent" ref="963351320"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">209</int>
+                                               <reference key="object" ref="447796847"/>
+                                               <reference key="parent" ref="963351320"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">57</int>
+                                               <reference key="object" ref="110575045"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="238522557"/>
+                                                       <reference ref="755159360"/>
+                                                       <reference ref="908899353"/>
+                                                       <reference ref="632727374"/>
+                                                       <reference ref="646227648"/>
+                                                       <reference ref="609285721"/>
+                                                       <reference ref="481834944"/>
+                                                       <reference ref="304266470"/>
+                                                       <reference ref="1046388886"/>
+                                                       <reference ref="1056857174"/>
+                                                       <reference ref="342932134"/>
+                                               </array>
+                                               <reference key="parent" ref="694149608"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">58</int>
+                                               <reference key="object" ref="238522557"/>
+                                               <reference key="parent" ref="110575045"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">134</int>
+                                               <reference key="object" ref="755159360"/>
+                                               <reference key="parent" ref="110575045"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">150</int>
+                                               <reference key="object" ref="908899353"/>
+                                               <reference key="parent" ref="110575045"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">136</int>
+                                               <reference key="object" ref="632727374"/>
+                                               <reference key="parent" ref="110575045"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">144</int>
+                                               <reference key="object" ref="646227648"/>
+                                               <reference key="parent" ref="110575045"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">129</int>
+                                               <reference key="object" ref="609285721"/>
+                                               <reference key="parent" ref="110575045"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">143</int>
+                                               <reference key="object" ref="481834944"/>
+                                               <reference key="parent" ref="110575045"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">236</int>
+                                               <reference key="object" ref="304266470"/>
+                                               <reference key="parent" ref="110575045"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">131</int>
+                                               <reference key="object" ref="1046388886"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="752062318"/>
+                                               </array>
+                                               <reference key="parent" ref="110575045"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">149</int>
+                                               <reference key="object" ref="1056857174"/>
+                                               <reference key="parent" ref="110575045"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">145</int>
+                                               <reference key="object" ref="342932134"/>
+                                               <reference key="parent" ref="110575045"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">130</int>
+                                               <reference key="object" ref="752062318"/>
+                                               <reference key="parent" ref="1046388886"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">24</int>
+                                               <reference key="object" ref="835318025"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="299356726"/>
+                                                       <reference ref="625202149"/>
+                                                       <reference ref="575023229"/>
+                                                       <reference ref="1011231497"/>
+                                               </array>
+                                               <reference key="parent" ref="713487014"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">92</int>
+                                               <reference key="object" ref="299356726"/>
+                                               <reference key="parent" ref="835318025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">5</int>
+                                               <reference key="object" ref="625202149"/>
+                                               <reference key="parent" ref="835318025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">239</int>
+                                               <reference key="object" ref="575023229"/>
+                                               <reference key="parent" ref="835318025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">23</int>
+                                               <reference key="object" ref="1011231497"/>
+                                               <reference key="parent" ref="835318025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">295</int>
+                                               <reference key="object" ref="586577488"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="466310130"/>
+                                               </array>
+                                               <reference key="parent" ref="649796088"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">296</int>
+                                               <reference key="object" ref="466310130"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="102151532"/>
+                                                       <reference ref="237841660"/>
+                                               </array>
+                                               <reference key="parent" ref="586577488"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">297</int>
+                                               <reference key="object" ref="102151532"/>
+                                               <reference key="parent" ref="466310130"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">298</int>
+                                               <reference key="object" ref="237841660"/>
+                                               <reference key="parent" ref="466310130"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">211</int>
+                                               <reference key="object" ref="676164635"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="785027613"/>
+                                               </array>
+                                               <reference key="parent" ref="789758025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">212</int>
+                                               <reference key="object" ref="785027613"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="680220178"/>
+                                                       <reference ref="731782645"/>
+                                               </array>
+                                               <reference key="parent" ref="676164635"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">195</int>
+                                               <reference key="object" ref="680220178"/>
+                                               <reference key="parent" ref="785027613"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">196</int>
+                                               <reference key="object" ref="731782645"/>
+                                               <reference key="parent" ref="785027613"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">346</int>
+                                               <reference key="object" ref="967646866"/>
+                                               <reference key="parent" ref="769623530"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">348</int>
+                                               <reference key="object" ref="507821607"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="698887838"/>
+                                               </array>
+                                               <reference key="parent" ref="789758025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">349</int>
+                                               <reference key="object" ref="698887838"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="605118523"/>
+                                                       <reference ref="197661976"/>
+                                                       <reference ref="708854459"/>
+                                                       <reference ref="65139061"/>
+                                                       <reference ref="19036812"/>
+                                                       <reference ref="672708820"/>
+                                                       <reference ref="537092702"/>
+                                               </array>
+                                               <reference key="parent" ref="507821607"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">350</int>
+                                               <reference key="object" ref="605118523"/>
+                                               <reference key="parent" ref="698887838"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">351</int>
+                                               <reference key="object" ref="197661976"/>
+                                               <reference key="parent" ref="698887838"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">354</int>
+                                               <reference key="object" ref="708854459"/>
+                                               <reference key="parent" ref="698887838"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">375</int>
+                                               <reference key="object" ref="302598603"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="941447902"/>
+                                               </array>
+                                               <reference key="parent" ref="649796088"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">376</int>
+                                               <reference key="object" ref="941447902"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="792887677"/>
+                                                       <reference ref="215659978"/>
+                                               </array>
+                                               <reference key="parent" ref="302598603"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">377</int>
+                                               <reference key="object" ref="792887677"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="786677654"/>
+                                               </array>
+                                               <reference key="parent" ref="941447902"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">388</int>
+                                               <reference key="object" ref="786677654"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="159677712"/>
+                                                       <reference ref="305399458"/>
+                                                       <reference ref="814362025"/>
+                                                       <reference ref="330926929"/>
+                                                       <reference ref="533507878"/>
+                                                       <reference ref="158063935"/>
+                                                       <reference ref="885547335"/>
+                                                       <reference ref="901062459"/>
+                                                       <reference ref="767671776"/>
+                                                       <reference ref="691570813"/>
+                                                       <reference ref="769124883"/>
+                                                       <reference ref="739652853"/>
+                                                       <reference ref="1012600125"/>
+                                                       <reference ref="214559597"/>
+                                                       <reference ref="596732606"/>
+                                                       <reference ref="393423671"/>
+                                               </array>
+                                               <reference key="parent" ref="792887677"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">389</int>
+                                               <reference key="object" ref="159677712"/>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">390</int>
+                                               <reference key="object" ref="305399458"/>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">391</int>
+                                               <reference key="object" ref="814362025"/>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">392</int>
+                                               <reference key="object" ref="330926929"/>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">393</int>
+                                               <reference key="object" ref="533507878"/>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">394</int>
+                                               <reference key="object" ref="158063935"/>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">395</int>
+                                               <reference key="object" ref="885547335"/>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">396</int>
+                                               <reference key="object" ref="901062459"/>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">397</int>
+                                               <reference key="object" ref="767671776"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="175441468"/>
+                                               </array>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">398</int>
+                                               <reference key="object" ref="691570813"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="1058217995"/>
+                                               </array>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">399</int>
+                                               <reference key="object" ref="769124883"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="18263474"/>
+                                               </array>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">400</int>
+                                               <reference key="object" ref="739652853"/>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">401</int>
+                                               <reference key="object" ref="1012600125"/>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">402</int>
+                                               <reference key="object" ref="214559597"/>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">403</int>
+                                               <reference key="object" ref="596732606"/>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">404</int>
+                                               <reference key="object" ref="393423671"/>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">405</int>
+                                               <reference key="object" ref="18263474"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="257962622"/>
+                                                       <reference ref="644725453"/>
+                                                       <reference ref="1037576581"/>
+                                                       <reference ref="941806246"/>
+                                                       <reference ref="1045724900"/>
+                                               </array>
+                                               <reference key="parent" ref="769124883"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">406</int>
+                                               <reference key="object" ref="257962622"/>
+                                               <reference key="parent" ref="18263474"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">407</int>
+                                               <reference key="object" ref="644725453"/>
+                                               <reference key="parent" ref="18263474"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">408</int>
+                                               <reference key="object" ref="1037576581"/>
+                                               <reference key="parent" ref="18263474"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">409</int>
+                                               <reference key="object" ref="941806246"/>
+                                               <reference key="parent" ref="18263474"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">410</int>
+                                               <reference key="object" ref="1045724900"/>
+                                               <reference key="parent" ref="18263474"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">411</int>
+                                               <reference key="object" ref="1058217995"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="706297211"/>
+                                                       <reference ref="568384683"/>
+                                                       <reference ref="663508465"/>
+                                               </array>
+                                               <reference key="parent" ref="691570813"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">412</int>
+                                               <reference key="object" ref="706297211"/>
+                                               <reference key="parent" ref="1058217995"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">413</int>
+                                               <reference key="object" ref="568384683"/>
+                                               <reference key="parent" ref="1058217995"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">414</int>
+                                               <reference key="object" ref="663508465"/>
+                                               <reference key="parent" ref="1058217995"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">415</int>
+                                               <reference key="object" ref="175441468"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="252969304"/>
+                                                       <reference ref="766922938"/>
+                                                       <reference ref="677519740"/>
+                                                       <reference ref="238351151"/>
+                                               </array>
+                                               <reference key="parent" ref="767671776"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">416</int>
+                                               <reference key="object" ref="252969304"/>
+                                               <reference key="parent" ref="175441468"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">417</int>
+                                               <reference key="object" ref="766922938"/>
+                                               <reference key="parent" ref="175441468"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">418</int>
+                                               <reference key="object" ref="677519740"/>
+                                               <reference key="parent" ref="175441468"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">419</int>
+                                               <reference key="object" ref="238351151"/>
+                                               <reference key="parent" ref="175441468"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">420</int>
+                                               <reference key="object" ref="755631768"/>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">450</int>
+                                               <reference key="object" ref="288088188"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="579392910"/>
+                                               </array>
+                                               <reference key="parent" ref="789758025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">451</int>
+                                               <reference key="object" ref="579392910"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="1060694897"/>
+                                                       <reference ref="879586729"/>
+                                                       <reference ref="56570060"/>
+                                               </array>
+                                               <reference key="parent" ref="288088188"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">452</int>
+                                               <reference key="object" ref="1060694897"/>
+                                               <reference key="parent" ref="579392910"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">453</int>
+                                               <reference key="object" ref="859480356"/>
+                                               <reference key="parent" ref="769623530"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">454</int>
+                                               <reference key="object" ref="795346622"/>
+                                               <reference key="parent" ref="769623530"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">457</int>
+                                               <reference key="object" ref="65139061"/>
+                                               <reference key="parent" ref="698887838"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">459</int>
+                                               <reference key="object" ref="19036812"/>
+                                               <reference key="parent" ref="698887838"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">460</int>
+                                               <reference key="object" ref="672708820"/>
+                                               <reference key="parent" ref="698887838"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">462</int>
+                                               <reference key="object" ref="537092702"/>
+                                               <reference key="parent" ref="698887838"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">465</int>
+                                               <reference key="object" ref="879586729"/>
+                                               <reference key="parent" ref="579392910"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">466</int>
+                                               <reference key="object" ref="56570060"/>
+                                               <reference key="parent" ref="579392910"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">485</int>
+                                               <reference key="object" ref="82994268"/>
+                                               <reference key="parent" ref="789758025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">490</int>
+                                               <reference key="object" ref="448692316"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="992780483"/>
+                                               </array>
+                                               <reference key="parent" ref="649796088"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">491</int>
+                                               <reference key="object" ref="992780483"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="105068016"/>
+                                               </array>
+                                               <reference key="parent" ref="448692316"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">492</int>
+                                               <reference key="object" ref="105068016"/>
+                                               <reference key="parent" ref="992780483"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">494</int>
+                                               <reference key="object" ref="976324537"/>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">496</int>
+                                               <reference key="object" ref="215659978"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="446991534"/>
+                                               </array>
+                                               <reference key="parent" ref="941447902"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">497</int>
+                                               <reference key="object" ref="446991534"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="875092757"/>
+                                                       <reference ref="630155264"/>
+                                                       <reference ref="945678886"/>
+                                                       <reference ref="512868991"/>
+                                                       <reference ref="163117631"/>
+                                                       <reference ref="31516759"/>
+                                                       <reference ref="908105787"/>
+                                                       <reference ref="644046920"/>
+                                                       <reference ref="231811626"/>
+                                                       <reference ref="883618387"/>
+                                               </array>
+                                               <reference key="parent" ref="215659978"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">498</int>
+                                               <reference key="object" ref="875092757"/>
+                                               <reference key="parent" ref="446991534"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">499</int>
+                                               <reference key="object" ref="630155264"/>
+                                               <reference key="parent" ref="446991534"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">500</int>
+                                               <reference key="object" ref="945678886"/>
+                                               <reference key="parent" ref="446991534"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">501</int>
+                                               <reference key="object" ref="512868991"/>
+                                               <reference key="parent" ref="446991534"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">502</int>
+                                               <reference key="object" ref="163117631"/>
+                                               <reference key="parent" ref="446991534"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">503</int>
+                                               <reference key="object" ref="31516759"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="956096989"/>
+                                               </array>
+                                               <reference key="parent" ref="446991534"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">504</int>
+                                               <reference key="object" ref="908105787"/>
+                                               <reference key="parent" ref="446991534"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">505</int>
+                                               <reference key="object" ref="644046920"/>
+                                               <reference key="parent" ref="446991534"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">506</int>
+                                               <reference key="object" ref="231811626"/>
+                                               <reference key="parent" ref="446991534"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">507</int>
+                                               <reference key="object" ref="883618387"/>
+                                               <reference key="parent" ref="446991534"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">508</int>
+                                               <reference key="object" ref="956096989"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="257099033"/>
+                                                       <reference ref="551969625"/>
+                                                       <reference ref="249532473"/>
+                                                       <reference ref="607364498"/>
+                                                       <reference ref="508151438"/>
+                                                       <reference ref="981751889"/>
+                                                       <reference ref="380031999"/>
+                                                       <reference ref="825984362"/>
+                                                       <reference ref="560145579"/>
+                                               </array>
+                                               <reference key="parent" ref="31516759"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">509</int>
+                                               <reference key="object" ref="257099033"/>
+                                               <reference key="parent" ref="956096989"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">510</int>
+                                               <reference key="object" ref="551969625"/>
+                                               <reference key="parent" ref="956096989"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">511</int>
+                                               <reference key="object" ref="249532473"/>
+                                               <reference key="parent" ref="956096989"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">512</int>
+                                               <reference key="object" ref="607364498"/>
+                                               <reference key="parent" ref="956096989"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">513</int>
+                                               <reference key="object" ref="508151438"/>
+                                               <reference key="parent" ref="956096989"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">514</int>
+                                               <reference key="object" ref="981751889"/>
+                                               <reference key="parent" ref="956096989"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">515</int>
+                                               <reference key="object" ref="380031999"/>
+                                               <reference key="parent" ref="956096989"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">516</int>
+                                               <reference key="object" ref="825984362"/>
+                                               <reference key="parent" ref="956096989"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">517</int>
+                                               <reference key="object" ref="560145579"/>
+                                               <reference key="parent" ref="956096989"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">534</int>
+                                               <reference key="object" ref="738670835"/>
+                                               <reference key="parent" ref="963351320"/>
+                                       </object>
+                               </array>
+                       </object>
+                       <dictionary class="NSMutableDictionary" key="flattenedProperties">
+                               <string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="-3.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="112.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="124.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="125.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="126.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="129.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="130.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="131.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="134.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="136.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="143.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="144.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="145.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="149.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="150.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="19.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="195.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="196.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="197.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="198.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="199.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="200.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="201.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="202.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="203.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="204.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="205.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="206.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="207.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="208.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="209.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="210.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="211.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="212.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="213.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="214.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="215.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="216.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="217.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="218.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="219.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="220.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="221.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="23.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="236.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="239.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="24.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="29.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="295.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="296.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="297.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="298.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="346.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="348.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="349.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="350.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="351.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="354.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="375.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="376.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="377.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="388.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="389.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="390.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="391.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="392.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="393.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="394.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="395.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="396.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="397.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="398.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="399.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="400.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="401.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="402.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="403.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="404.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="405.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="406.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="407.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="408.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="409.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="410.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="411.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="412.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="413.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="414.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="415.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="416.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="417.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="418.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="419.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="420.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="450.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="451.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="452.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="453.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="454.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="457.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="459.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="460.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="462.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="465.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="466.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="485.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="490.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="491.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="492.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="494.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="496.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="497.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="498.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="499.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="5.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="500.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="501.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="502.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="503.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="504.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="505.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="506.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="507.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="508.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="509.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="510.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="511.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="512.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="513.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="514.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="515.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="516.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="517.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="534.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="56.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="57.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="58.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="72.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="73.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="74.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="75.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="77.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="78.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="79.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="81.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="82.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="83.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="92.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                       </dictionary>
+                       <dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
+                       <nil key="activeLocalization"/>
+                       <dictionary class="NSMutableDictionary" key="localizations"/>
+                       <nil key="sourceID"/>
+                       <int key="maxID">535</int>
+               </object>
+               <object class="IBClassDescriber" key="IBDocument.Classes">
+                       <array class="NSMutableArray" key="referencedPartialClassDescriptions">
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">KNAppDelegate</string>
+                                       <string key="superclassName">NSObject</string>
+                                       <object class="NSMutableDictionary" key="outlets">
+                                               <string key="NS.key.0">window</string>
+                                               <string key="NS.object.0">NSWindow</string>
+                                       </object>
+                                       <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <string key="NS.key.0">window</string>
+                                               <object class="IBToOneOutletInfo" key="NS.object.0">
+                                                       <string key="name">window</string>
+                                                       <string key="candidateClassName">NSWindow</string>
+                                               </object>
+                                       </object>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/KNAppDelegate.h</string>
+                                       </object>
+                               </object>
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">NSDocumentController</string>
+                                       <object class="NSMutableDictionary" key="actions">
+                                               <string key="NS.key.0">_openRecentDocument:</string>
+                                               <string key="NS.object.0">id</string>
+                                       </object>
+                                       <object class="NSMutableDictionary" key="actionInfosByName">
+                                               <string key="NS.key.0">_openRecentDocument:</string>
+                                               <object class="IBActionInfo" key="NS.object.0">
+                                                       <string key="name">_openRecentDocument:</string>
+                                                       <string key="candidateClassName">id</string>
+                                               </object>
+                                       </object>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/NSDocumentController.h</string>
+                                       </object>
+                               </object>
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">NSMovePanel</string>
+                                       <string key="superclassName">NSPanel</string>
+                                       <dictionary class="NSMutableDictionary" key="actions">
+                                               <string key="cancel:">id</string>
+                                               <string key="newDocument:">id</string>
+                                               <string key="ok:">id</string>
+                                       </dictionary>
+                                       <dictionary class="NSMutableDictionary" key="actionInfosByName">
+                                               <object class="IBActionInfo" key="cancel:">
+                                                       <string key="name">cancel:</string>
+                                                       <string key="candidateClassName">id</string>
+                                               </object>
+                                               <object class="IBActionInfo" key="newDocument:">
+                                                       <string key="name">newDocument:</string>
+                                                       <string key="candidateClassName">id</string>
+                                               </object>
+                                               <object class="IBActionInfo" key="ok:">
+                                                       <string key="name">ok:</string>
+                                                       <string key="candidateClassName">id</string>
+                                               </object>
+                                       </dictionary>
+                                       <dictionary class="NSMutableDictionary" key="outlets">
+                                               <string key="_cancelButton">NSButton</string>
+                                               <string key="_moveButton">NSButton</string>
+                                               <string key="_movePanelContentView">NSView</string>
+                                               <string key="_movePopUp">FILocationPopUp</string>
+                                               <string key="_movePopUpLabel">NSTextField</string>
+                                       </dictionary>
+                                       <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <object class="IBToOneOutletInfo" key="_cancelButton">
+                                                       <string key="name">_cancelButton</string>
+                                                       <string key="candidateClassName">NSButton</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_moveButton">
+                                                       <string key="name">_moveButton</string>
+                                                       <string key="candidateClassName">NSButton</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_movePanelContentView">
+                                                       <string key="name">_movePanelContentView</string>
+                                                       <string key="candidateClassName">NSView</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_movePopUp">
+                                                       <string key="name">_movePopUp</string>
+                                                       <string key="candidateClassName">FILocationPopUp</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_movePopUpLabel">
+                                                       <string key="name">_movePopUpLabel</string>
+                                                       <string key="candidateClassName">NSTextField</string>
+                                               </object>
+                                       </dictionary>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/NSMovePanel.h</string>
+                                       </object>
+                               </object>
+                       </array>
+               </object>
+               <int key="IBDocument.localizationMode">0</int>
+               <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
+               <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+               <int key="IBDocument.defaultPropertyAccessControl">3</int>
+               <dictionary class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
+                       <string key="NSMenuCheckmark">{11, 11}</string>
+                       <string key="NSMenuMixedState">{10, 3}</string>
+               </dictionary>
+               <bool key="IBDocument.UseAutolayout">YES</bool>
+       </data>
+</archive>
diff --git a/Keychain Circle Notification/entitlments.plist b/Keychain Circle Notification/entitlments.plist
new file mode 100644 (file)
index 0000000..f1eb0a1
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>com.apple.private.notificationcenter-system</key>
+       <array>
+               <dict>
+                       <key>identifier</key>
+                       <string>com.apple.security.keychain-circle-notification</string>
+               </dict>
+       </array>
+       <key>keychain-cloud-circle</key>
+       <true/>
+</dict>
+</plist>
diff --git a/Keychain Circle Notification/main.m b/Keychain Circle Notification/main.m
new file mode 100644 (file)
index 0000000..a647330
--- /dev/null
@@ -0,0 +1,14 @@
+//
+//  main.m
+//  Keychain Circle Notification
+//
+//  Created by J Osborne on 2/21/13.
+//
+//
+
+#import <Cocoa/Cocoa.h>
+
+int main(int argc, char *argv[])
+{
+       return NSApplicationMain(argc, (const char **)argv);
+}
diff --git a/Keychain/Icon.icns b/Keychain/Icon.icns
new file mode 100644 (file)
index 0000000..c12f3fe
Binary files /dev/null and b/Keychain/Icon.icns differ
diff --git a/Keychain/KDAppDelegate.h b/Keychain/KDAppDelegate.h
new file mode 100644 (file)
index 0000000..6e40385
--- /dev/null
@@ -0,0 +1,33 @@
+//
+//  KDAppDelegate.h
+//  Keychain
+//
+//  Created by J Osborne on 2/13/13.
+//
+//
+
+#import <Cocoa/Cocoa.h>
+#import "KDSecItems.h"
+#import "KDSecCircle.h"
+
+@interface KDAppDelegate : NSObject <NSApplicationDelegate>
+
+@property (assign) IBOutlet NSWindow *window;
+@property (assign) IBOutlet NSTableView *itemTable;
+@property (assign) IBOutlet NSTextFieldCell *itemTableTitle;
+@property (retain) id<NSTableViewDataSource> itemDataSource;
+
+@property (assign) IBOutlet NSButton *enableKeychainSyncing;
+@property (assign) IBOutlet NSTextFieldCell *circleStatusCell;
+@property (assign) IBOutlet NSTextFieldCell *peerCountCell;
+@property (assign) IBOutlet NSTextView *peerTextList;
+@property (assign) IBOutlet NSTextFieldCell *applicantCountCell;
+@property (assign) IBOutlet NSTextView *applicantTextList;
+@property (assign) IBOutlet NSProgressIndicator *syncSpinner;
+
+@property (retain) KDSecCircle *circle;
+
+@property (retain) NSMutableArray *stuffNotToLeak;
+
+-(IBAction)enableKeychainSyncingClicked:(id)sender;
+@end
diff --git a/Keychain/KDAppDelegate.m b/Keychain/KDAppDelegate.m
new file mode 100644 (file)
index 0000000..1d3b81f
--- /dev/null
@@ -0,0 +1,83 @@
+//
+//  KDAppDelegate.m
+//  Keychain
+//
+//  Created by J Osborne on 2/13/13.
+//
+//
+
+#import "KDAppDelegate.h"
+#import "KDCirclePeer.h"
+#import "NSArray+mapWithBlock.h"
+#include <notify.h>
+
+#define kSecServerKeychainChangedNotification "com.apple.security.keychainchanged"
+
+@implementation KDAppDelegate
+
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
+{
+    self.stuffNotToLeak = [NSMutableArray new];
+    [self.stuffNotToLeak addObject:[[NSNotificationCenter defaultCenter] addObserverForName:kKDSecItemsUpdated object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
+        self.itemTableTitle.title = [NSString stringWithFormat:@"All Items (%ld)", (long)[self.itemDataSource numberOfRowsInTableView:self.itemTable]];
+    }]];
+    
+    [self.syncSpinner setUsesThreadedAnimation:YES];
+    [self.syncSpinner startAnimation:nil];
+    
+    self.itemDataSource = [[KDSecItems alloc] init];
+    self.itemTable.dataSource = self.itemDataSource;
+    
+    int notificationToken;
+    uint32_t rc = notify_register_dispatch(kSecServerKeychainChangedNotification, &notificationToken, dispatch_get_main_queue(), ^(int token __unused) {
+            NSLog(@"Received %s", kSecServerKeychainChangedNotification);
+            [(KDSecItems*)self.itemDataSource loadItems];
+            [self.itemTable reloadData];
+         });
+    NSAssert(rc == 0, @"Can't register for %s", kSecServerKeychainChangedNotification);
+       
+       self.circle = [KDSecCircle new];
+       [self.circle addChangeCallback:^{
+               self.circleStatusCell.stringValue = self.circle.status;
+        
+        [self setCheckbox];
+        
+               self.peerCountCell.objectValue = @(self.circle.peers.count);
+               NSString *peerNames = [[self.circle.peers mapWithBlock:^id(id obj) {
+                       return ((KDCirclePeer*)obj).name;
+               }] componentsJoinedByString:@"\n"];
+               [self.peerTextList.textStorage replaceCharactersInRange:NSMakeRange(0, [self.peerTextList.textStorage length]) withString:peerNames];
+        
+               self.applicantCountCell.objectValue = @(self.circle.applicants.count);
+               NSString *applicantNames = [[self.circle.applicants mapWithBlock:^id(id obj) {
+                       return ((KDCirclePeer*)obj).name;
+               }] componentsJoinedByString:@"\n"];
+               [self.applicantTextList.textStorage replaceCharactersInRange:NSMakeRange(0, [self.applicantTextList.textStorage length]) withString:applicantNames];
+        
+        [self.syncSpinner stopAnimation:nil];
+       }];
+}
+
+-(void)setCheckbox
+{
+    if (self.circle.isInCircle) {
+        [self.enableKeychainSyncing setState:NSOnState];
+    } else if (self.circle.isOutOfCircle) {
+        [self.enableKeychainSyncing setState:NSOffState];
+    } else {
+        [self.enableKeychainSyncing setState:NSMixedState];
+    }
+}
+
+-(IBAction)enableKeychainSyncingClicked:(id)sender
+{
+    [self.syncSpinner startAnimation:sender];
+    if (self.circle.isOutOfCircle) {
+        [self.circle enableSync];
+    } else {
+        [self.circle disableSync];
+    }
+    [self setCheckbox];
+}
+
+@end
diff --git a/Keychain/KDCirclePeer.h b/Keychain/KDCirclePeer.h
new file mode 100644 (file)
index 0000000..45416f9
--- /dev/null
@@ -0,0 +1,19 @@
+//
+//  KDCirclePeer.h
+//  Security
+//
+//  Created by J Osborne on 2/25/13.
+//
+//
+
+#import <Foundation/Foundation.h>
+
+@interface KDCirclePeer : NSObject
+
+@property (readonly) NSString *name;
+@property (readonly) NSString *idString;
+@property (readonly) id peerObject;
+
+-(id)initWithPeerObject:(id)peerObject;
+
+@end
diff --git a/Keychain/KDCirclePeer.m b/Keychain/KDCirclePeer.m
new file mode 100644 (file)
index 0000000..695af37
--- /dev/null
@@ -0,0 +1,42 @@
+//
+//  KDCirclePeer.m
+//  Security
+//
+//  Created by J Osborne on 2/25/13.
+//
+//
+
+#import "KDCirclePeer.h"
+#include "SecureObjectSync/SOSCloudCircle.h"
+#include "SecureObjectSync/SOSPeerInfo.h"
+
+@interface KDCirclePeer ()
+
+@property (readwrite) NSString *name;
+@property (readwrite) NSString *idString;
+@property (readwrite) id peerObject;
+
+@end
+
+@implementation KDCirclePeer
+
+-(id)initWithPeerObject:(id)peerObject
+{
+       self = [super init];
+       if (!self) {
+               return self;
+       }
+       
+       self.peerObject = peerObject;
+       self.name = (__bridge NSString *)(SOSPeerInfoGetPeerName((__bridge SOSPeerInfoRef)peerObject));
+       self.idString = (__bridge NSString *)(SOSPeerInfoGetPeerID((__bridge SOSPeerInfoRef)peerObject));
+       
+       return self;
+}
+
+-(NSString*)description
+{
+    return [NSString stringWithFormat:@"[peer n='%@' id='%@' o=%@]", self.name, self.idString, self.peerObject];
+}
+
+@end
diff --git a/Keychain/KDSecCircle.h b/Keychain/KDSecCircle.h
new file mode 100644 (file)
index 0000000..35455a3
--- /dev/null
@@ -0,0 +1,35 @@
+//
+//  KDSecCircle.h
+//  Security
+//
+//  Created by J Osborne on 2/20/13.
+//
+//
+
+#import "SecureObjectSync/SOSCloudCircle.h"
+#import <Foundation/Foundation.h>
+
+@interface KDSecCircle : NSObject
+
+@property (readonly) BOOL isInCircle;
+@property (readonly) BOOL isOutOfCircle;
+
+@property (readonly) SOSCCStatus rawStatus;
+
+@property (readonly) NSString *status;
+@property (readonly) NSError *error;
+
+// Both of these are arrays of KDCircelPeer objects
+@property (readonly) NSArray *peers;
+@property (readonly) NSArray *applicants;
+
+-(void)addChangeCallback:(dispatch_block_t)callback;
+-(id)init;
+
+// these are "try to", and may (most likely will) not complete by the time they return
+-(void)enableSync;
+-(void)disableSync;
+-(void)rejectApplicantId:(NSString*)applicantId;
+-(void)acceptApplicantId:(NSString*)applicantId;
+
+@end
diff --git a/Keychain/KDSecCircle.m b/Keychain/KDSecCircle.m
new file mode 100644 (file)
index 0000000..0952b91
--- /dev/null
@@ -0,0 +1,190 @@
+//
+//  KDSecCircle.m
+//  Security
+//
+//  Created by J Osborne on 2/20/13.
+//
+//
+
+#import "KDSecCircle.h"
+#import "KDCirclePeer.h"
+#include <notify.h>
+#include <dispatch/dispatch.h>
+#import "SecureObjectSync/SOSCloudCircle.h"
+#include "SecureObjectSync/SOSPeerInfo.h"
+
+@interface KDSecCircle ()
+@property (retain) NSMutableArray *callbacks;
+
+@property (readwrite) unsigned long long changeCount;
+
+@property (readwrite) SOSCCStatus rawStatus;
+
+@property (readwrite) NSString *status;
+@property (readwrite) NSError *error;
+
+@property (readwrite) NSArray *peers;
+@property (readwrite) NSArray *applicants;
+
+@property (readwrite) dispatch_queue_t queue_;
+
+@end
+
+@implementation KDSecCircle
+
+-(void)updateCheck
+{
+       // XXX: assert not on main_queue
+       CFErrorRef err = NULL;
+       SOSCCStatus newRawStatus = SOSCCThisDeviceIsInCircle(&err);
+    
+    NSArray *peerInfos = (__bridge NSArray *)(SOSCCCopyApplicantPeerInfo(&err));
+    NSMutableArray *newApplicants = [[NSMutableArray alloc] initWithCapacity:peerInfos.count];
+       [peerInfos enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
+        [newApplicants addObject:[[KDCirclePeer alloc] initWithPeerObject:obj]];
+    }];
+       
+       peerInfos = (__bridge NSArray *)(SOSCCCopyPeerPeerInfo(&err));
+    NSMutableArray *newPeers = [[NSMutableArray alloc] initWithCapacity:peerInfos.count];
+       [peerInfos enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
+        [newPeers addObject:[[KDCirclePeer alloc] initWithPeerObject:obj]];
+    }];
+    
+    NSLog(@"rawStatus %d, #applicants %lu, #peers %lu, err=%@", newRawStatus, (unsigned long)[newApplicants count], (unsigned long)[newPeers count], err);
+
+       dispatch_async(dispatch_get_main_queue(), ^{
+        self.rawStatus = newRawStatus;
+        
+               switch (newRawStatus) {
+                       case kSOSCCInCircle:
+                               self.status = @"In Circle";
+                               break;
+                               
+                       case kSOSCCNotInCircle:
+                               self.status = @"Not In Circle";
+                               break;
+
+                       case kSOSCCRequestPending:
+                               self.status = @"Request Pending";
+                               break;
+                               
+                       case kSOSCCCircleAbsent:
+                               self.status = @"Circle Absent";
+                               break;
+                               
+                       case kSOSCCError:
+                               self.status = [NSString stringWithFormat:@"Error: %@", err];
+                               break;
+                               
+                       case kSOSCCParamErr:
+                               self.status = [NSString stringWithFormat:@"ParamError: %@", err];
+                               break;
+                               
+                       default:
+                               self.status = [NSString stringWithFormat:@"Unknown status code %d", self.rawStatus];
+                               break;
+               }
+        
+        self.applicants = [newApplicants copy];
+        self.peers = [newPeers copy];
+        self.error = (__bridge NSError *)(err);
+
+        self.changeCount++;
+        for (dispatch_block_t callback in self.callbacks) {
+            callback();
+        }
+       });
+}
+
+// XXX It's a botch to use the "name" and not applicant, but
+// it is hard to get anythign else to survive a serialastion
+// trip thoguth NSUserNotificationCenter.
+//
+// Er, now that I look more closely maybe SOSPeerInfoGetPeerID...
+
+typedef void (^applicantBlock)(id applicant);
+
+-(void)forApplicantId:(NSString*)applicantId run:(applicantBlock)applicantBlock
+{
+    dispatch_async(self.queue_, ^{
+               for (KDCirclePeer *applicant in self.applicants) {
+                       if ([applicantId isEqualToString:applicantId]) {
+                               applicantBlock(applicant.peerObject);
+                               break;
+                       }
+               }
+    });
+}
+
+-(void)acceptApplicantId:(NSString*)applicantId
+{
+    [self forApplicantId:applicantId run:^void(id applicant) {
+        CFErrorRef err;
+        bool ok = SOSCCAcceptApplicants((__bridge CFArrayRef)(@[applicant]), &err);
+        NSAssert(ok, @"Error %@ while accepting %@ (%@)", err, applicantId, applicant);
+    }];
+}
+
+-(void)rejectApplicantId:(NSString*)applicantId
+{
+    [self forApplicantId:applicantId run:^void(id applicant) {
+        CFErrorRef err;
+        bool ok = SOSCCRejectApplicants((__bridge CFArrayRef)(@[applicant]), &err);
+        NSAssert(ok, @"Error %@ while rejecting %@ (%@)", err, applicantId, applicant);
+    }];
+}
+
+-(id)init
+{
+       self = [super init];
+       int token;
+    
+    self->_queue_ = dispatch_queue_create([[NSString stringWithFormat:@"KDSecCircle@%p", self] UTF8String], NULL);
+    self->_callbacks = [NSMutableArray new];
+    // Replace "com.apple.security.secureobjectsync.circlechanged" with kSOSCCCircleChangedNotification once it is exported
+       notify_register_dispatch("com.apple.security.secureobjectsync.circlechanged", &token, self.queue_, ^(int token){
+               [self updateCheck];
+       });
+    
+    return self;
+}
+
+-(void)addChangeCallback:(dispatch_block_t)callback
+{
+       [self.callbacks addObject:callback];
+    if (self.changeCount) {
+        dispatch_async(dispatch_get_main_queue(), callback);
+    } else if (self.callbacks.count == 1) {
+        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+            [self updateCheck];
+        });
+    }
+}
+
+-(BOOL)isInCircle
+{
+    return (self.rawStatus == kSOSCCInCircle) ? YES : NO;
+}
+
+-(BOOL)isOutOfCircle
+{
+    return (self.rawStatus == kSOSCCNotInCircle || self.rawStatus == kSOSCCCircleAbsent);
+}
+
+-(void)enableSync
+{
+    CFErrorRef err;
+       if (self.rawStatus == kSOSCCCircleAbsent) {
+               SOSCCResetToOffering(&err);
+       } else {
+               SOSCCRequestToJoinCircle(&err);
+       }
+}
+
+-(void)disableSync
+{
+    CFErrorRef err;
+    SOSCCRemoveThisDeviceFromCircle(&err);
+}
+
+@end
diff --git a/Keychain/KDSecItems.h b/Keychain/KDSecItems.h
new file mode 100644 (file)
index 0000000..72a6c71
--- /dev/null
@@ -0,0 +1,18 @@
+//
+//  KDSecItems.h
+//  Security
+//
+//  Created by J Osborne on 2/14/13.
+//
+//
+
+#import <Foundation/Foundation.h>
+
+extern NSString *kKDSecItemsUpdated;
+
+@interface KDSecItems : NSObject<NSTableViewDataSource>
+-(NSInteger)numberOfRowsInTableView:(NSTableView*)t;
+- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex;
+
+-(void)loadItems;
+@end
diff --git a/Keychain/KDSecItems.m b/Keychain/KDSecItems.m
new file mode 100644 (file)
index 0000000..0f26422
--- /dev/null
@@ -0,0 +1,108 @@
+//
+//  KDSecItems.m
+//  Security
+//
+//  Created by J Osborne on 2/14/13.
+//
+//
+
+#import "KDSecItems.h"
+#include <Security/Security.h>
+#include <Security/SecItemPriv.h>
+
+
+NSString *kKDSecItemsUpdated = @"KDSecItemsUpdated";
+
+@interface KDSecItems ()
+@property NSMutableArray *items;
+@end
+
+@implementation KDSecItems
+
+-(NSInteger)numberOfRowsInTableView:(NSTableView*)t
+{
+    return [self.items count];
+}
+
++(NSString*)nameOfItem:(NSDictionary*)item
+{
+    id name = item[(id)kSecAttrService];
+    if (name) {
+        return name;
+    }
+    
+    NSString *path = item[(id)kSecAttrPath];
+    if (!path) {
+        path = @"/";
+    }
+    NSString *port = item[(id)kSecAttrPort];
+    if ([@"0" isEqualToString:port] || [@0 isEqual:port]) {
+        port = @"";
+    } else {
+        port = [NSString stringWithFormat:@":%@", port];
+    }
+    
+    return [NSString stringWithFormat:@"%@://%@%@%@", item[(id)kSecAttrProtocol], item[(id)kSecAttrServer], port, path];
+}
+
+- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex
+{
+    NSString *identifier = [aTableColumn identifier];
+    
+    if ([@"account" isEqualToString:identifier]) {
+        return self.items[rowIndex][(id)kSecAttrAccount];
+    }
+    if ([@"name" isEqualToString:identifier]) {
+        return [KDSecItems nameOfItem:self.items[rowIndex]];
+    }
+    
+    return [NSString stringWithFormat:@"*** c=%@ r%ld", [aTableColumn identifier], (long)rowIndex];
+}
+
+-(NSArray*)fetchItemsMatching:(NSDictionary *)query
+{
+    CFTypeRef raw_items = NULL;
+    OSStatus result = SecItemCopyMatching((__bridge CFDictionaryRef)(query), &raw_items);
+    if (result) {
+        // XXX: UI
+        NSLog(@"Error result %d - query: %@", result, query);
+        return nil;
+    }
+    if (CFArrayGetTypeID() == CFGetTypeID(raw_items)) {
+        return (__bridge NSArray*)raw_items;
+    }
+    
+    NSLog(@"Unexpected result type from copyMatching: %@ (query=%@)", raw_items, query);
+    CFRelease(raw_items);
+
+    return nil;
+}
+
+-(void)loadItems
+{
+    NSDictionary *query_genp = @{(id)kSecClass: (id)kSecClassGenericPassword,
+                                 (__bridge id)kSecAttrSynchronizable: @1,
+                                 (id)kSecMatchLimit: (id)kSecMatchLimitAll,
+                                 (id)kSecReturnAttributes: (id)kCFBooleanTrue};
+    NSDictionary *query_inet = @{(id)kSecClass: (id)kSecClassInternetPassword,
+                                 (__bridge id)kSecAttrSynchronizable: @1,
+                                 (id)kSecMatchLimit: (id)kSecMatchLimitAll,
+                                 (id)kSecReturnAttributes: (id)kCFBooleanTrue};
+    NSArray *nextItems = [[self fetchItemsMatching:query_genp] arrayByAddingObjectsFromArray:[self fetchItemsMatching:query_inet]];
+    self.items = [[nextItems sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
+        NSDictionary *da = a, *db = b;
+        return [da[(id)kSecAttrService] caseInsensitiveCompare:db[(id)kSecAttrService]];
+    }] mutableCopy];
+        
+    dispatch_async(dispatch_get_main_queue(), ^{
+        [[NSNotificationCenter defaultCenter] postNotificationName:kKDSecItemsUpdated object:self];
+    });
+}
+
+-(id)init
+{
+    [self loadItems];
+    return self;
+}
+
+@end
diff --git a/Keychain/Keychain-Info.plist b/Keychain/Keychain-Info.plist
new file mode 100644 (file)
index 0000000..27194d1
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>en</string>
+       <key>CFBundleExecutable</key>
+       <string>${EXECUTABLE_NAME}</string>
+       <key>CFBundleIconFile</key>
+       <string>Icon.icns</string>
+       <key>CFBundleIdentifier</key>
+       <string>com.apple.security.${PRODUCT_NAME:rfc1034identifier}</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundleName</key>
+       <string>${PRODUCT_NAME}</string>
+       <key>CFBundlePackageType</key>
+       <string>APPL</string>
+       <key>CFBundleShortVersionString</key>
+       <string>1.0</string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>55471</string>
+       <key>LSMinimumSystemVersion</key>
+       <string>${MACOSX_DEPLOYMENT_TARGET}</string>
+       <key>NSMainNibFile</key>
+       <string>MainMenu</string>
+       <key>NSPrincipalClass</key>
+       <string>NSApplication</string>
+</dict>
+</plist>
diff --git a/Keychain/Keychain-Prefix.pch b/Keychain/Keychain-Prefix.pch
new file mode 100644 (file)
index 0000000..2de6125
--- /dev/null
@@ -0,0 +1,7 @@
+//
+// Prefix header for all source files of the 'Keychain' target in the 'Keychain' project
+//
+
+#ifdef __OBJC__
+    #import <Cocoa/Cocoa.h>
+#endif
diff --git a/Keychain/en.lproj/Credits.rtf b/Keychain/en.lproj/Credits.rtf
new file mode 100644 (file)
index 0000000..46576ef
--- /dev/null
@@ -0,0 +1,29 @@
+{\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\paperw9840\paperh8400
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
+
+\f0\b\fs24 \cf0 Engineering:
+\b0 \
+       Some people\
+\
+
+\b Human Interface Design:
+\b0 \
+       Some other people\
+\
+
+\b Testing:
+\b0 \
+       Hopefully not nobody\
+\
+
+\b Documentation:
+\b0 \
+       Whoever\
+\
+
+\b With special thanks to:
+\b0 \
+       Mom\
+}
diff --git a/Keychain/en.lproj/InfoPlist.strings b/Keychain/en.lproj/InfoPlist.strings
new file mode 100644 (file)
index 0000000..477b28f
--- /dev/null
@@ -0,0 +1,2 @@
+/* Localized versions of Info.plist keys */
+
diff --git a/Keychain/en.lproj/MainMenu.xib b/Keychain/en.lproj/MainMenu.xib
new file mode 100644 (file)
index 0000000..74412ef
--- /dev/null
@@ -0,0 +1,6586 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="8.00">
+       <data>
+               <int key="IBDocument.SystemTarget">1090</int>
+               <string key="IBDocument.SystemVersion">13A386b</string>
+               <string key="IBDocument.InterfaceBuilderVersion">4373</string>
+               <string key="IBDocument.AppKitVersion">1219</string>
+               <string key="IBDocument.HIToolboxVersion">662.00</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                       <string key="NS.object.0">4373</string>
+               </object>
+               <array key="IBDocument.IntegratedClassDependencies">
+                       <string>IBNSLayoutConstraint</string>
+                       <string>NSBox</string>
+                       <string>NSButton</string>
+                       <string>NSButtonCell</string>
+                       <string>NSCustomObject</string>
+                       <string>NSMenu</string>
+                       <string>NSMenuItem</string>
+                       <string>NSProgressIndicator</string>
+                       <string>NSScrollView</string>
+                       <string>NSScroller</string>
+                       <string>NSTabView</string>
+                       <string>NSTabViewItem</string>
+                       <string>NSTableColumn</string>
+                       <string>NSTableHeaderView</string>
+                       <string>NSTableView</string>
+                       <string>NSTextField</string>
+                       <string>NSTextFieldCell</string>
+                       <string>NSTextView</string>
+                       <string>NSView</string>
+                       <string>NSWindowTemplate</string>
+               </array>
+               <array key="IBDocument.PluginDependencies">
+                       <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+               </array>
+               <object class="NSMutableDictionary" key="IBDocument.Metadata">
+                       <string key="NS.key.0">PluginDependencyRecalculationVersion</string>
+                       <integer value="1" key="NS.object.0"/>
+               </object>
+               <array class="NSMutableArray" key="IBDocument.RootObjects" id="1048">
+                       <object class="NSCustomObject" id="1021">
+                               <string key="NSClassName">NSApplication</string>
+                       </object>
+                       <object class="NSCustomObject" id="1014">
+                               <string key="NSClassName">FirstResponder</string>
+                       </object>
+                       <object class="NSCustomObject" id="1050">
+                               <string key="NSClassName">NSApplication</string>
+                       </object>
+                       <object class="NSMenu" id="649796088">
+                               <string key="NSTitle">AMainMenu</string>
+                               <array class="NSMutableArray" key="NSMenuItems">
+                                       <object class="NSMenuItem" id="694149608">
+                                               <reference key="NSMenu" ref="649796088"/>
+                                               <string key="NSTitle">Cloud Keychain Utility</string>
+                                               <string key="NSKeyEquiv"/>
+                                               <int key="NSKeyEquivModMask">1048576</int>
+                                               <int key="NSMnemonicLoc">2147483647</int>
+                                               <object class="NSCustomResource" key="NSOnImage" id="35465992">
+                                                       <string key="NSClassName">NSImage</string>
+                                                       <string key="NSResourceName">NSMenuCheckmark</string>
+                                               </object>
+                                               <object class="NSCustomResource" key="NSMixedImage" id="502551668">
+                                                       <string key="NSClassName">NSImage</string>
+                                                       <string key="NSResourceName">NSMenuMixedState</string>
+                                               </object>
+                                               <string key="NSAction">submenuAction:</string>
+                                               <reference key="NSTarget" ref="110575045"/>
+                                               <object class="NSMenu" key="NSSubmenu" id="110575045">
+                                                       <string key="NSTitle">Cloud Keychain Utility</string>
+                                                       <array class="NSMutableArray" key="NSMenuItems">
+                                                               <object class="NSMenuItem" id="238522557">
+                                                                       <reference key="NSMenu" ref="110575045"/>
+                                                                       <string key="NSTitle">About Keychain</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="304266470">
+                                                                       <reference key="NSMenu" ref="110575045"/>
+                                                                       <bool key="NSIsDisabled">YES</bool>
+                                                                       <bool key="NSIsSeparator">YES</bool>
+                                                                       <string key="NSTitle"/>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="609285721">
+                                                                       <reference key="NSMenu" ref="110575045"/>
+                                                                       <string key="NSTitle">Preferences…</string>
+                                                                       <string key="NSKeyEquiv">,</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="481834944">
+                                                                       <reference key="NSMenu" ref="110575045"/>
+                                                                       <bool key="NSIsDisabled">YES</bool>
+                                                                       <bool key="NSIsSeparator">YES</bool>
+                                                                       <string key="NSTitle"/>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="1046388886">
+                                                                       <reference key="NSMenu" ref="110575045"/>
+                                                                       <string key="NSTitle">Services</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                       <string key="NSAction">submenuAction:</string>
+                                                                       <reference key="NSTarget" ref="752062318"/>
+                                                                       <object class="NSMenu" key="NSSubmenu" id="752062318">
+                                                                               <string key="NSTitle">Services</string>
+                                                                               <array class="NSMutableArray" key="NSMenuItems"/>
+                                                                               <string key="NSName">_NSServicesMenu</string>
+                                                                       </object>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="646227648">
+                                                                       <reference key="NSMenu" ref="110575045"/>
+                                                                       <bool key="NSIsDisabled">YES</bool>
+                                                                       <bool key="NSIsSeparator">YES</bool>
+                                                                       <string key="NSTitle"/>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="755159360">
+                                                                       <reference key="NSMenu" ref="110575045"/>
+                                                                       <string key="NSTitle">Hide Keychain</string>
+                                                                       <string key="NSKeyEquiv">h</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="342932134">
+                                                                       <reference key="NSMenu" ref="110575045"/>
+                                                                       <string key="NSTitle">Hide Others</string>
+                                                                       <string key="NSKeyEquiv">h</string>
+                                                                       <int key="NSKeyEquivModMask">1572864</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="908899353">
+                                                                       <reference key="NSMenu" ref="110575045"/>
+                                                                       <string key="NSTitle">Show All</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="1056857174">
+                                                                       <reference key="NSMenu" ref="110575045"/>
+                                                                       <bool key="NSIsDisabled">YES</bool>
+                                                                       <bool key="NSIsSeparator">YES</bool>
+                                                                       <string key="NSTitle"/>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="632727374">
+                                                                       <reference key="NSMenu" ref="110575045"/>
+                                                                       <string key="NSTitle">Quit Keychain</string>
+                                                                       <string key="NSKeyEquiv">q</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                       </array>
+                                                       <string key="NSName">_NSAppleMenu</string>
+                                               </object>
+                                       </object>
+                                       <object class="NSMenuItem" id="379814623">
+                                               <reference key="NSMenu" ref="649796088"/>
+                                               <string key="NSTitle">File</string>
+                                               <string key="NSKeyEquiv"/>
+                                               <int key="NSKeyEquivModMask">1048576</int>
+                                               <int key="NSMnemonicLoc">2147483647</int>
+                                               <reference key="NSOnImage" ref="35465992"/>
+                                               <reference key="NSMixedImage" ref="502551668"/>
+                                               <string key="NSAction">submenuAction:</string>
+                                               <reference key="NSTarget" ref="720053764"/>
+                                               <object class="NSMenu" key="NSSubmenu" id="720053764">
+                                                       <string key="NSTitle">File</string>
+                                                       <array class="NSMutableArray" key="NSMenuItems">
+                                                               <object class="NSMenuItem" id="705341025">
+                                                                       <reference key="NSMenu" ref="720053764"/>
+                                                                       <string key="NSTitle">New</string>
+                                                                       <string key="NSKeyEquiv">n</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="722745758">
+                                                                       <reference key="NSMenu" ref="720053764"/>
+                                                                       <string key="NSTitle">Open…</string>
+                                                                       <string key="NSKeyEquiv">o</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="1025936716">
+                                                                       <reference key="NSMenu" ref="720053764"/>
+                                                                       <string key="NSTitle">Open Recent</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                       <string key="NSAction">submenuAction:</string>
+                                                                       <reference key="NSTarget" ref="1065607017"/>
+                                                                       <object class="NSMenu" key="NSSubmenu" id="1065607017">
+                                                                               <string key="NSTitle">Open Recent</string>
+                                                                               <array class="NSMutableArray" key="NSMenuItems">
+                                                                                       <object class="NSMenuItem" id="759406840">
+                                                                                               <reference key="NSMenu" ref="1065607017"/>
+                                                                                               <string key="NSTitle">Clear Menu</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                               </array>
+                                                                               <string key="NSName">_NSRecentDocumentsMenu</string>
+                                                                       </object>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="425164168">
+                                                                       <reference key="NSMenu" ref="720053764"/>
+                                                                       <bool key="NSIsDisabled">YES</bool>
+                                                                       <bool key="NSIsSeparator">YES</bool>
+                                                                       <string key="NSTitle"/>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="776162233">
+                                                                       <reference key="NSMenu" ref="720053764"/>
+                                                                       <string key="NSTitle">Close</string>
+                                                                       <string key="NSKeyEquiv">w</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="1023925487">
+                                                                       <reference key="NSMenu" ref="720053764"/>
+                                                                       <string key="NSTitle">Save…</string>
+                                                                       <string key="NSKeyEquiv">s</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="579971712">
+                                                                       <reference key="NSMenu" ref="720053764"/>
+                                                                       <string key="NSTitle">Revert to Saved</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="1010469920">
+                                                                       <reference key="NSMenu" ref="720053764"/>
+                                                                       <bool key="NSIsDisabled">YES</bool>
+                                                                       <bool key="NSIsSeparator">YES</bool>
+                                                                       <string key="NSTitle"/>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="294629803">
+                                                                       <reference key="NSMenu" ref="720053764"/>
+                                                                       <string key="NSTitle">Page Setup...</string>
+                                                                       <string key="NSKeyEquiv">P</string>
+                                                                       <int key="NSKeyEquivModMask">1179648</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                       <string key="NSToolTip"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="49223823">
+                                                                       <reference key="NSMenu" ref="720053764"/>
+                                                                       <string key="NSTitle">Print…</string>
+                                                                       <string key="NSKeyEquiv">p</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                       </array>
+                                               </object>
+                                       </object>
+                                       <object class="NSMenuItem" id="952259628">
+                                               <reference key="NSMenu" ref="649796088"/>
+                                               <string key="NSTitle">Edit</string>
+                                               <string key="NSKeyEquiv"/>
+                                               <int key="NSKeyEquivModMask">1048576</int>
+                                               <int key="NSMnemonicLoc">2147483647</int>
+                                               <reference key="NSOnImage" ref="35465992"/>
+                                               <reference key="NSMixedImage" ref="502551668"/>
+                                               <string key="NSAction">submenuAction:</string>
+                                               <reference key="NSTarget" ref="789758025"/>
+                                               <object class="NSMenu" key="NSSubmenu" id="789758025">
+                                                       <string key="NSTitle">Edit</string>
+                                                       <array class="NSMutableArray" key="NSMenuItems">
+                                                               <object class="NSMenuItem" id="1058277027">
+                                                                       <reference key="NSMenu" ref="789758025"/>
+                                                                       <string key="NSTitle">Undo</string>
+                                                                       <string key="NSKeyEquiv">z</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="790794224">
+                                                                       <reference key="NSMenu" ref="789758025"/>
+                                                                       <string key="NSTitle">Redo</string>
+                                                                       <string key="NSKeyEquiv">Z</string>
+                                                                       <int key="NSKeyEquivModMask">1179648</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="1040322652">
+                                                                       <reference key="NSMenu" ref="789758025"/>
+                                                                       <bool key="NSIsDisabled">YES</bool>
+                                                                       <bool key="NSIsSeparator">YES</bool>
+                                                                       <string key="NSTitle"/>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="296257095">
+                                                                       <reference key="NSMenu" ref="789758025"/>
+                                                                       <string key="NSTitle">Cut</string>
+                                                                       <string key="NSKeyEquiv">x</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="860595796">
+                                                                       <reference key="NSMenu" ref="789758025"/>
+                                                                       <string key="NSTitle">Copy</string>
+                                                                       <string key="NSKeyEquiv">c</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="29853731">
+                                                                       <reference key="NSMenu" ref="789758025"/>
+                                                                       <string key="NSTitle">Paste</string>
+                                                                       <string key="NSKeyEquiv">v</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="82994268">
+                                                                       <reference key="NSMenu" ref="789758025"/>
+                                                                       <string key="NSTitle">Paste and Match Style</string>
+                                                                       <string key="NSKeyEquiv">V</string>
+                                                                       <int key="NSKeyEquivModMask">1572864</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="437104165">
+                                                                       <reference key="NSMenu" ref="789758025"/>
+                                                                       <string key="NSTitle">Delete</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="583158037">
+                                                                       <reference key="NSMenu" ref="789758025"/>
+                                                                       <string key="NSTitle">Select All</string>
+                                                                       <string key="NSKeyEquiv">a</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="212016141">
+                                                                       <reference key="NSMenu" ref="789758025"/>
+                                                                       <bool key="NSIsDisabled">YES</bool>
+                                                                       <bool key="NSIsSeparator">YES</bool>
+                                                                       <string key="NSTitle"/>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="892235320">
+                                                                       <reference key="NSMenu" ref="789758025"/>
+                                                                       <string key="NSTitle">Find</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                       <string key="NSAction">submenuAction:</string>
+                                                                       <reference key="NSTarget" ref="963351320"/>
+                                                                       <object class="NSMenu" key="NSSubmenu" id="963351320">
+                                                                               <string key="NSTitle">Find</string>
+                                                                               <array class="NSMutableArray" key="NSMenuItems">
+                                                                                       <object class="NSMenuItem" id="447796847">
+                                                                                               <reference key="NSMenu" ref="963351320"/>
+                                                                                               <string key="NSTitle">Find…</string>
+                                                                                               <string key="NSKeyEquiv">f</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <int key="NSTag">1</int>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="738670835">
+                                                                                               <reference key="NSMenu" ref="963351320"/>
+                                                                                               <string key="NSTitle">Find and Replace…</string>
+                                                                                               <string key="NSKeyEquiv">f</string>
+                                                                                               <int key="NSKeyEquivModMask">1572864</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <int key="NSTag">12</int>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="326711663">
+                                                                                               <reference key="NSMenu" ref="963351320"/>
+                                                                                               <string key="NSTitle">Find Next</string>
+                                                                                               <string key="NSKeyEquiv">g</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <int key="NSTag">2</int>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="270902937">
+                                                                                               <reference key="NSMenu" ref="963351320"/>
+                                                                                               <string key="NSTitle">Find Previous</string>
+                                                                                               <string key="NSKeyEquiv">G</string>
+                                                                                               <int key="NSKeyEquivModMask">1179648</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <int key="NSTag">3</int>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="159080638">
+                                                                                               <reference key="NSMenu" ref="963351320"/>
+                                                                                               <string key="NSTitle">Use Selection for Find</string>
+                                                                                               <string key="NSKeyEquiv">e</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <int key="NSTag">7</int>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="88285865">
+                                                                                               <reference key="NSMenu" ref="963351320"/>
+                                                                                               <string key="NSTitle">Jump to Selection</string>
+                                                                                               <string key="NSKeyEquiv">j</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                               </array>
+                                                                       </object>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="972420730">
+                                                                       <reference key="NSMenu" ref="789758025"/>
+                                                                       <string key="NSTitle">Spelling and Grammar</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                       <string key="NSAction">submenuAction:</string>
+                                                                       <reference key="NSTarget" ref="769623530"/>
+                                                                       <object class="NSMenu" key="NSSubmenu" id="769623530">
+                                                                               <string key="NSTitle">Spelling and Grammar</string>
+                                                                               <array class="NSMutableArray" key="NSMenuItems">
+                                                                                       <object class="NSMenuItem" id="679648819">
+                                                                                               <reference key="NSMenu" ref="769623530"/>
+                                                                                               <string key="NSTitle">Show Spelling and Grammar</string>
+                                                                                               <string key="NSKeyEquiv">:</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="96193923">
+                                                                                               <reference key="NSMenu" ref="769623530"/>
+                                                                                               <string key="NSTitle">Check Document Now</string>
+                                                                                               <string key="NSKeyEquiv">;</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="859480356">
+                                                                                               <reference key="NSMenu" ref="769623530"/>
+                                                                                               <bool key="NSIsDisabled">YES</bool>
+                                                                                               <bool key="NSIsSeparator">YES</bool>
+                                                                                               <string key="NSTitle"/>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="948374510">
+                                                                                               <reference key="NSMenu" ref="769623530"/>
+                                                                                               <string key="NSTitle">Check Spelling While Typing</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="967646866">
+                                                                                               <reference key="NSMenu" ref="769623530"/>
+                                                                                               <string key="NSTitle">Check Grammar With Spelling</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="795346622">
+                                                                                               <reference key="NSMenu" ref="769623530"/>
+                                                                                               <string key="NSTitle">Correct Spelling Automatically</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                               </array>
+                                                                       </object>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="507821607">
+                                                                       <reference key="NSMenu" ref="789758025"/>
+                                                                       <string key="NSTitle">Substitutions</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                       <string key="NSAction">submenuAction:</string>
+                                                                       <reference key="NSTarget" ref="698887838"/>
+                                                                       <object class="NSMenu" key="NSSubmenu" id="698887838">
+                                                                               <string key="NSTitle">Substitutions</string>
+                                                                               <array class="NSMutableArray" key="NSMenuItems">
+                                                                                       <object class="NSMenuItem" id="65139061">
+                                                                                               <reference key="NSMenu" ref="698887838"/>
+                                                                                               <string key="NSTitle">Show Substitutions</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="19036812">
+                                                                                               <reference key="NSMenu" ref="698887838"/>
+                                                                                               <bool key="NSIsDisabled">YES</bool>
+                                                                                               <bool key="NSIsSeparator">YES</bool>
+                                                                                               <string key="NSTitle"/>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="605118523">
+                                                                                               <reference key="NSMenu" ref="698887838"/>
+                                                                                               <string key="NSTitle">Smart Copy/Paste</string>
+                                                                                               <string key="NSKeyEquiv">f</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <int key="NSTag">1</int>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="197661976">
+                                                                                               <reference key="NSMenu" ref="698887838"/>
+                                                                                               <string key="NSTitle">Smart Quotes</string>
+                                                                                               <string key="NSKeyEquiv">g</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <int key="NSTag">2</int>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="672708820">
+                                                                                               <reference key="NSMenu" ref="698887838"/>
+                                                                                               <string key="NSTitle">Smart Dashes</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="708854459">
+                                                                                               <reference key="NSMenu" ref="698887838"/>
+                                                                                               <string key="NSTitle">Smart Links</string>
+                                                                                               <string key="NSKeyEquiv">G</string>
+                                                                                               <int key="NSKeyEquivModMask">1179648</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <int key="NSTag">3</int>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="537092702">
+                                                                                               <reference key="NSMenu" ref="698887838"/>
+                                                                                               <string key="NSTitle">Text Replacement</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                               </array>
+                                                                       </object>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="288088188">
+                                                                       <reference key="NSMenu" ref="789758025"/>
+                                                                       <string key="NSTitle">Transformations</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                       <string key="NSAction">submenuAction:</string>
+                                                                       <reference key="NSTarget" ref="579392910"/>
+                                                                       <object class="NSMenu" key="NSSubmenu" id="579392910">
+                                                                               <string key="NSTitle">Transformations</string>
+                                                                               <array class="NSMutableArray" key="NSMenuItems">
+                                                                                       <object class="NSMenuItem" id="1060694897">
+                                                                                               <reference key="NSMenu" ref="579392910"/>
+                                                                                               <string key="NSTitle">Make Upper Case</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="879586729">
+                                                                                               <reference key="NSMenu" ref="579392910"/>
+                                                                                               <string key="NSTitle">Make Lower Case</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="56570060">
+                                                                                               <reference key="NSMenu" ref="579392910"/>
+                                                                                               <string key="NSTitle">Capitalize</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                               </array>
+                                                                       </object>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="676164635">
+                                                                       <reference key="NSMenu" ref="789758025"/>
+                                                                       <string key="NSTitle">Speech</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                       <string key="NSAction">submenuAction:</string>
+                                                                       <reference key="NSTarget" ref="785027613"/>
+                                                                       <object class="NSMenu" key="NSSubmenu" id="785027613">
+                                                                               <string key="NSTitle">Speech</string>
+                                                                               <array class="NSMutableArray" key="NSMenuItems">
+                                                                                       <object class="NSMenuItem" id="731782645">
+                                                                                               <reference key="NSMenu" ref="785027613"/>
+                                                                                               <string key="NSTitle">Start Speaking</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="680220178">
+                                                                                               <reference key="NSMenu" ref="785027613"/>
+                                                                                               <string key="NSTitle">Stop Speaking</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                               </array>
+                                                                       </object>
+                                                               </object>
+                                                       </array>
+                                               </object>
+                                       </object>
+                                       <object class="NSMenuItem" id="302598603">
+                                               <reference key="NSMenu" ref="649796088"/>
+                                               <string key="NSTitle">Format</string>
+                                               <string key="NSKeyEquiv"/>
+                                               <int key="NSMnemonicLoc">2147483647</int>
+                                               <reference key="NSOnImage" ref="35465992"/>
+                                               <reference key="NSMixedImage" ref="502551668"/>
+                                               <string key="NSAction">submenuAction:</string>
+                                               <reference key="NSTarget" ref="941447902"/>
+                                               <object class="NSMenu" key="NSSubmenu" id="941447902">
+                                                       <string key="NSTitle">Format</string>
+                                                       <array class="NSMutableArray" key="NSMenuItems">
+                                                               <object class="NSMenuItem" id="792887677">
+                                                                       <reference key="NSMenu" ref="941447902"/>
+                                                                       <string key="NSTitle">Font</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                       <string key="NSAction">submenuAction:</string>
+                                                                       <reference key="NSTarget" ref="786677654"/>
+                                                                       <object class="NSMenu" key="NSSubmenu" id="786677654">
+                                                                               <string key="NSTitle">Font</string>
+                                                                               <array class="NSMutableArray" key="NSMenuItems">
+                                                                                       <object class="NSMenuItem" id="159677712">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <string key="NSTitle">Show Fonts</string>
+                                                                                               <string key="NSKeyEquiv">t</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="305399458">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <string key="NSTitle">Bold</string>
+                                                                                               <string key="NSKeyEquiv">b</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <int key="NSTag">2</int>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="814362025">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <string key="NSTitle">Italic</string>
+                                                                                               <string key="NSKeyEquiv">i</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <int key="NSTag">1</int>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="330926929">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <string key="NSTitle">Underline</string>
+                                                                                               <string key="NSKeyEquiv">u</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="533507878">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <bool key="NSIsDisabled">YES</bool>
+                                                                                               <bool key="NSIsSeparator">YES</bool>
+                                                                                               <string key="NSTitle"/>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="158063935">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <string key="NSTitle">Bigger</string>
+                                                                                               <string key="NSKeyEquiv">+</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <int key="NSTag">3</int>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="885547335">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <string key="NSTitle">Smaller</string>
+                                                                                               <string key="NSKeyEquiv">-</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <int key="NSTag">4</int>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="901062459">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <bool key="NSIsDisabled">YES</bool>
+                                                                                               <bool key="NSIsSeparator">YES</bool>
+                                                                                               <string key="NSTitle"/>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="767671776">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <string key="NSTitle">Kern</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <string key="NSAction">submenuAction:</string>
+                                                                                               <reference key="NSTarget" ref="175441468"/>
+                                                                                               <object class="NSMenu" key="NSSubmenu" id="175441468">
+                                                                                                       <string key="NSTitle">Kern</string>
+                                                                                                       <array class="NSMutableArray" key="NSMenuItems">
+                                                                                                               <object class="NSMenuItem" id="252969304">
+                                                                                                                       <reference key="NSMenu" ref="175441468"/>
+                                                                                                                       <string key="NSTitle">Use Default</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="766922938">
+                                                                                                                       <reference key="NSMenu" ref="175441468"/>
+                                                                                                                       <string key="NSTitle">Use None</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="677519740">
+                                                                                                                       <reference key="NSMenu" ref="175441468"/>
+                                                                                                                       <string key="NSTitle">Tighten</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="238351151">
+                                                                                                                       <reference key="NSMenu" ref="175441468"/>
+                                                                                                                       <string key="NSTitle">Loosen</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                       </array>
+                                                                                               </object>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="691570813">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <string key="NSTitle">Ligatures</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <string key="NSAction">submenuAction:</string>
+                                                                                               <reference key="NSTarget" ref="1058217995"/>
+                                                                                               <object class="NSMenu" key="NSSubmenu" id="1058217995">
+                                                                                                       <string key="NSTitle">Ligatures</string>
+                                                                                                       <array class="NSMutableArray" key="NSMenuItems">
+                                                                                                               <object class="NSMenuItem" id="706297211">
+                                                                                                                       <reference key="NSMenu" ref="1058217995"/>
+                                                                                                                       <string key="NSTitle">Use Default</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="568384683">
+                                                                                                                       <reference key="NSMenu" ref="1058217995"/>
+                                                                                                                       <string key="NSTitle">Use None</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="663508465">
+                                                                                                                       <reference key="NSMenu" ref="1058217995"/>
+                                                                                                                       <string key="NSTitle">Use All</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                       </array>
+                                                                                               </object>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="769124883">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <string key="NSTitle">Baseline</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <string key="NSAction">submenuAction:</string>
+                                                                                               <reference key="NSTarget" ref="18263474"/>
+                                                                                               <object class="NSMenu" key="NSSubmenu" id="18263474">
+                                                                                                       <string key="NSTitle">Baseline</string>
+                                                                                                       <array class="NSMutableArray" key="NSMenuItems">
+                                                                                                               <object class="NSMenuItem" id="257962622">
+                                                                                                                       <reference key="NSMenu" ref="18263474"/>
+                                                                                                                       <string key="NSTitle">Use Default</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="644725453">
+                                                                                                                       <reference key="NSMenu" ref="18263474"/>
+                                                                                                                       <string key="NSTitle">Superscript</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="1037576581">
+                                                                                                                       <reference key="NSMenu" ref="18263474"/>
+                                                                                                                       <string key="NSTitle">Subscript</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="941806246">
+                                                                                                                       <reference key="NSMenu" ref="18263474"/>
+                                                                                                                       <string key="NSTitle">Raise</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="1045724900">
+                                                                                                                       <reference key="NSMenu" ref="18263474"/>
+                                                                                                                       <string key="NSTitle">Lower</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                       </array>
+                                                                                               </object>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="739652853">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <bool key="NSIsDisabled">YES</bool>
+                                                                                               <bool key="NSIsSeparator">YES</bool>
+                                                                                               <string key="NSTitle"/>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="1012600125">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <string key="NSTitle">Show Colors</string>
+                                                                                               <string key="NSKeyEquiv">C</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="214559597">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <bool key="NSIsDisabled">YES</bool>
+                                                                                               <bool key="NSIsSeparator">YES</bool>
+                                                                                               <string key="NSTitle"/>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="596732606">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <string key="NSTitle">Copy Style</string>
+                                                                                               <string key="NSKeyEquiv">c</string>
+                                                                                               <int key="NSKeyEquivModMask">1572864</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="393423671">
+                                                                                               <reference key="NSMenu" ref="786677654"/>
+                                                                                               <string key="NSTitle">Paste Style</string>
+                                                                                               <string key="NSKeyEquiv">v</string>
+                                                                                               <int key="NSKeyEquivModMask">1572864</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                               </array>
+                                                                               <string key="NSName">_NSFontMenu</string>
+                                                                       </object>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="215659978">
+                                                                       <reference key="NSMenu" ref="941447902"/>
+                                                                       <string key="NSTitle">Text</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                       <string key="NSAction">submenuAction:</string>
+                                                                       <reference key="NSTarget" ref="446991534"/>
+                                                                       <object class="NSMenu" key="NSSubmenu" id="446991534">
+                                                                               <string key="NSTitle">Text</string>
+                                                                               <array class="NSMutableArray" key="NSMenuItems">
+                                                                                       <object class="NSMenuItem" id="875092757">
+                                                                                               <reference key="NSMenu" ref="446991534"/>
+                                                                                               <string key="NSTitle">Align Left</string>
+                                                                                               <string key="NSKeyEquiv">{</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="630155264">
+                                                                                               <reference key="NSMenu" ref="446991534"/>
+                                                                                               <string key="NSTitle">Center</string>
+                                                                                               <string key="NSKeyEquiv">|</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="945678886">
+                                                                                               <reference key="NSMenu" ref="446991534"/>
+                                                                                               <string key="NSTitle">Justify</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="512868991">
+                                                                                               <reference key="NSMenu" ref="446991534"/>
+                                                                                               <string key="NSTitle">Align Right</string>
+                                                                                               <string key="NSKeyEquiv">}</string>
+                                                                                               <int key="NSKeyEquivModMask">1048576</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="163117631">
+                                                                                               <reference key="NSMenu" ref="446991534"/>
+                                                                                               <bool key="NSIsDisabled">YES</bool>
+                                                                                               <bool key="NSIsSeparator">YES</bool>
+                                                                                               <string key="NSTitle"/>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="31516759">
+                                                                                               <reference key="NSMenu" ref="446991534"/>
+                                                                                               <string key="NSTitle">Writing Direction</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                               <string key="NSAction">submenuAction:</string>
+                                                                                               <reference key="NSTarget" ref="956096989"/>
+                                                                                               <object class="NSMenu" key="NSSubmenu" id="956096989">
+                                                                                                       <string key="NSTitle">Writing Direction</string>
+                                                                                                       <array class="NSMutableArray" key="NSMenuItems">
+                                                                                                               <object class="NSMenuItem" id="257099033">
+                                                                                                                       <reference key="NSMenu" ref="956096989"/>
+                                                                                                                       <bool key="NSIsDisabled">YES</bool>
+                                                                                                                       <string key="NSTitle">Paragraph</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="551969625">
+                                                                                                                       <reference key="NSMenu" ref="956096989"/>
+                                                                                                                       <string type="base64-UTF8" key="NSTitle">CURlZmF1bHQ</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="249532473">
+                                                                                                                       <reference key="NSMenu" ref="956096989"/>
+                                                                                                                       <string type="base64-UTF8" key="NSTitle">CUxlZnQgdG8gUmlnaHQ</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="607364498">
+                                                                                                                       <reference key="NSMenu" ref="956096989"/>
+                                                                                                                       <string type="base64-UTF8" key="NSTitle">CVJpZ2h0IHRvIExlZnQ</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="508151438">
+                                                                                                                       <reference key="NSMenu" ref="956096989"/>
+                                                                                                                       <bool key="NSIsDisabled">YES</bool>
+                                                                                                                       <bool key="NSIsSeparator">YES</bool>
+                                                                                                                       <string key="NSTitle"/>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="981751889">
+                                                                                                                       <reference key="NSMenu" ref="956096989"/>
+                                                                                                                       <bool key="NSIsDisabled">YES</bool>
+                                                                                                                       <string key="NSTitle">Selection</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="380031999">
+                                                                                                                       <reference key="NSMenu" ref="956096989"/>
+                                                                                                                       <string type="base64-UTF8" key="NSTitle">CURlZmF1bHQ</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="825984362">
+                                                                                                                       <reference key="NSMenu" ref="956096989"/>
+                                                                                                                       <string type="base64-UTF8" key="NSTitle">CUxlZnQgdG8gUmlnaHQ</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                               <object class="NSMenuItem" id="560145579">
+                                                                                                                       <reference key="NSMenu" ref="956096989"/>
+                                                                                                                       <string type="base64-UTF8" key="NSTitle">CVJpZ2h0IHRvIExlZnQ</string>
+                                                                                                                       <string key="NSKeyEquiv"/>
+                                                                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                                                                               </object>
+                                                                                                       </array>
+                                                                                               </object>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="908105787">
+                                                                                               <reference key="NSMenu" ref="446991534"/>
+                                                                                               <bool key="NSIsDisabled">YES</bool>
+                                                                                               <bool key="NSIsSeparator">YES</bool>
+                                                                                               <string key="NSTitle"/>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="644046920">
+                                                                                               <reference key="NSMenu" ref="446991534"/>
+                                                                                               <string key="NSTitle">Show Ruler</string>
+                                                                                               <string key="NSKeyEquiv"/>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="231811626">
+                                                                                               <reference key="NSMenu" ref="446991534"/>
+                                                                                               <string key="NSTitle">Copy Ruler</string>
+                                                                                               <string key="NSKeyEquiv">c</string>
+                                                                                               <int key="NSKeyEquivModMask">1310720</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                                       <object class="NSMenuItem" id="883618387">
+                                                                                               <reference key="NSMenu" ref="446991534"/>
+                                                                                               <string key="NSTitle">Paste Ruler</string>
+                                                                                               <string key="NSKeyEquiv">v</string>
+                                                                                               <int key="NSKeyEquivModMask">1310720</int>
+                                                                                               <int key="NSMnemonicLoc">2147483647</int>
+                                                                                               <reference key="NSOnImage" ref="35465992"/>
+                                                                                               <reference key="NSMixedImage" ref="502551668"/>
+                                                                                       </object>
+                                                                               </array>
+                                                                       </object>
+                                                               </object>
+                                                       </array>
+                                               </object>
+                                       </object>
+                                       <object class="NSMenuItem" id="586577488">
+                                               <reference key="NSMenu" ref="649796088"/>
+                                               <string key="NSTitle">View</string>
+                                               <string key="NSKeyEquiv"/>
+                                               <int key="NSKeyEquivModMask">1048576</int>
+                                               <int key="NSMnemonicLoc">2147483647</int>
+                                               <reference key="NSOnImage" ref="35465992"/>
+                                               <reference key="NSMixedImage" ref="502551668"/>
+                                               <string key="NSAction">submenuAction:</string>
+                                               <reference key="NSTarget" ref="466310130"/>
+                                               <object class="NSMenu" key="NSSubmenu" id="466310130">
+                                                       <string key="NSTitle">View</string>
+                                                       <array class="NSMutableArray" key="NSMenuItems">
+                                                               <object class="NSMenuItem" id="102151532">
+                                                                       <reference key="NSMenu" ref="466310130"/>
+                                                                       <string key="NSTitle">Show Toolbar</string>
+                                                                       <string key="NSKeyEquiv">t</string>
+                                                                       <int key="NSKeyEquivModMask">1572864</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="237841660">
+                                                                       <reference key="NSMenu" ref="466310130"/>
+                                                                       <string key="NSTitle">Customize Toolbar…</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                       </array>
+                                               </object>
+                                       </object>
+                                       <object class="NSMenuItem" id="713487014">
+                                               <reference key="NSMenu" ref="649796088"/>
+                                               <string key="NSTitle">Window</string>
+                                               <string key="NSKeyEquiv"/>
+                                               <int key="NSKeyEquivModMask">1048576</int>
+                                               <int key="NSMnemonicLoc">2147483647</int>
+                                               <reference key="NSOnImage" ref="35465992"/>
+                                               <reference key="NSMixedImage" ref="502551668"/>
+                                               <string key="NSAction">submenuAction:</string>
+                                               <reference key="NSTarget" ref="835318025"/>
+                                               <object class="NSMenu" key="NSSubmenu" id="835318025">
+                                                       <string key="NSTitle">Window</string>
+                                                       <array class="NSMutableArray" key="NSMenuItems">
+                                                               <object class="NSMenuItem" id="1011231497">
+                                                                       <reference key="NSMenu" ref="835318025"/>
+                                                                       <string key="NSTitle">Minimize</string>
+                                                                       <string key="NSKeyEquiv">m</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="575023229">
+                                                                       <reference key="NSMenu" ref="835318025"/>
+                                                                       <string key="NSTitle">Zoom</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="299356726">
+                                                                       <reference key="NSMenu" ref="835318025"/>
+                                                                       <bool key="NSIsDisabled">YES</bool>
+                                                                       <bool key="NSIsSeparator">YES</bool>
+                                                                       <string key="NSTitle"/>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="625202149">
+                                                                       <reference key="NSMenu" ref="835318025"/>
+                                                                       <string key="NSTitle">Bring All to Front</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                       </array>
+                                                       <string key="NSName">_NSWindowsMenu</string>
+                                               </object>
+                                       </object>
+                                       <object class="NSMenuItem" id="448692316">
+                                               <reference key="NSMenu" ref="649796088"/>
+                                               <string key="NSTitle">Help</string>
+                                               <string key="NSKeyEquiv"/>
+                                               <int key="NSMnemonicLoc">2147483647</int>
+                                               <reference key="NSOnImage" ref="35465992"/>
+                                               <reference key="NSMixedImage" ref="502551668"/>
+                                               <string key="NSAction">submenuAction:</string>
+                                               <reference key="NSTarget" ref="992780483"/>
+                                               <object class="NSMenu" key="NSSubmenu" id="992780483">
+                                                       <string key="NSTitle">Help</string>
+                                                       <array class="NSMutableArray" key="NSMenuItems">
+                                                               <object class="NSMenuItem" id="105068016">
+                                                                       <reference key="NSMenu" ref="992780483"/>
+                                                                       <string key="NSTitle">Keychain Help</string>
+                                                                       <string key="NSKeyEquiv">?</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="35465992"/>
+                                                                       <reference key="NSMixedImage" ref="502551668"/>
+                                                               </object>
+                                                       </array>
+                                                       <string key="NSName">_NSHelpMenu</string>
+                                               </object>
+                                       </object>
+                               </array>
+                               <string key="NSName">_NSMainMenu</string>
+                       </object>
+                       <object class="NSWindowTemplate" id="972006081">
+                               <int key="NSWindowStyleMask">15</int>
+                               <int key="NSWindowBacking">2</int>
+                               <string key="NSWindowRect">{{335, 390}, {472, 415}}</string>
+                               <int key="NSWTFlags">1954021376</int>
+                               <string key="NSWindowTitle">☁️Keychain Utility</string>
+                               <string key="NSWindowClass">NSWindow</string>
+                               <nil key="NSViewClass"/>
+                               <nil key="NSUserInterfaceItemIdentifier"/>
+                               <object class="NSView" key="NSWindowView" id="439893737">
+                                       <reference key="NSNextResponder"/>
+                                       <int key="NSvFlags">256</int>
+                                       <array class="NSMutableArray" key="NSSubviews">
+                                               <object class="NSTabView" id="916837096">
+                                                       <reference key="NSNextResponder" ref="439893737"/>
+                                                       <int key="NSvFlags">12</int>
+                                                       <string key="NSFrame">{{15, -12}, {464, 434}}</string>
+                                                       <reference key="NSSuperview" ref="439893737"/>
+                                                       <reference key="NSWindow"/>
+                                                       <reference key="NSNextKeyView" ref="933472960"/>
+                                                       <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                       <array class="NSMutableArray" key="NSTabViewItems">
+                                                               <object class="NSTabViewItem" id="761467965">
+                                                                       <string key="NSIdentifier">keys</string>
+                                                                       <object class="NSView" key="NSView" id="716065875">
+                                                                               <nil key="NSNextResponder"/>
+                                                                               <int key="NSvFlags">256</int>
+                                                                               <array class="NSMutableArray" key="NSSubviews">
+                                                                                       <object class="NSTextField" id="233427652">
+                                                                                               <reference key="NSNextResponder" ref="716065875"/>
+                                                                                               <int key="NSvFlags">268</int>
+                                                                                               <string key="NSFrame">{{0, 380}, {408, 17}}</string>
+                                                                                               <reference key="NSSuperview" ref="716065875"/>
+                                                                                               <reference key="NSNextKeyView" ref="542670786"/>
+                                                                                               <string key="NSReuseIdentifierKey">_NS:1535</string>
+                                                                                               <bool key="NSEnabled">YES</bool>
+                                                                                               <object class="NSTextFieldCell" key="NSCell" id="974410057">
+                                                                                                       <int key="NSCellFlags">68157504</int>
+                                                                                                       <int key="NSCellFlags2">138413056</int>
+                                                                                                       <string key="NSContents">All Items (#)</string>
+                                                                                                       <object class="NSFont" key="NSSupport">
+                                                                                                               <string key="NSName">LucidaGrande-Bold</string>
+                                                                                                               <double key="NSSize">13</double>
+                                                                                                               <int key="NSfFlags">2072</int>
+                                                                                                       </object>
+                                                                                                       <string key="NSCellIdentifier">_NS:1535</string>
+                                                                                                       <reference key="NSControlView" ref="233427652"/>
+                                                                                                       <object class="NSColor" key="NSBackgroundColor" id="926294313">
+                                                                                                               <int key="NSColorSpace">6</int>
+                                                                                                               <string key="NSCatalogName">System</string>
+                                                                                                               <string key="NSColorName">controlColor</string>
+                                                                                                               <object class="NSColor" key="NSColor" id="961815644">
+                                                                                                                       <int key="NSColorSpace">3</int>
+                                                                                                                       <bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes>
+                                                                                                               </object>
+                                                                                                       </object>
+                                                                                                       <object class="NSColor" key="NSTextColor" id="842671716">
+                                                                                                               <int key="NSColorSpace">6</int>
+                                                                                                               <string key="NSCatalogName">System</string>
+                                                                                                               <string key="NSColorName">controlTextColor</string>
+                                                                                                               <object class="NSColor" key="NSColor" id="415257931">
+                                                                                                                       <int key="NSColorSpace">3</int>
+                                                                                                                       <bytes key="NSWhite">MAA</bytes>
+                                                                                                               </object>
+                                                                                                       </object>
+                                                                                               </object>
+                                                                                               <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+                                                                                       </object>
+                                                                                       <object class="NSButton" id="834759928">
+                                                                                               <reference key="NSNextResponder" ref="716065875"/>
+                                                                                               <int key="NSvFlags">268</int>
+                                                                                               <string key="NSFrame">{{367, 370}, {40, 29}}</string>
+                                                                                               <reference key="NSSuperview" ref="716065875"/>
+                                                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                                                               <bool key="NSEnabled">YES</bool>
+                                                                                               <object class="NSButtonCell" key="NSCell" id="1053170940">
+                                                                                                       <int key="NSCellFlags">67108864</int>
+                                                                                                       <int key="NSCellFlags2">134217728</int>
+                                                                                                       <string key="NSContents">+</string>
+                                                                                                       <object class="NSFont" key="NSSupport">
+                                                                                                               <string key="NSName">LucidaGrande</string>
+                                                                                                               <double key="NSSize">20</double>
+                                                                                                               <int key="NSfFlags">16</int>
+                                                                                                       </object>
+                                                                                                       <string key="NSCellIdentifier">_NS:9</string>
+                                                                                                       <reference key="NSControlView" ref="834759928"/>
+                                                                                                       <int key="NSButtonFlags">-2038153216</int>
+                                                                                                       <int key="NSButtonFlags2">130</int>
+                                                                                                       <string key="NSAlternateContents"/>
+                                                                                                       <string key="NSKeyEquivalent"/>
+                                                                                                       <int key="NSPeriodicDelay">400</int>
+                                                                                                       <int key="NSPeriodicInterval">75</int>
+                                                                                               </object>
+                                                                                               <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+                                                                                       </object>
+                                                                                       <object class="NSScrollView" id="542670786">
+                                                                                               <reference key="NSNextResponder" ref="716065875"/>
+                                                                                               <int key="NSvFlags">268</int>
+                                                                                               <array class="NSMutableArray" key="NSSubviews">
+                                                                                                       <object class="NSClipView" id="934177664">
+                                                                                                               <reference key="NSNextResponder" ref="542670786"/>
+                                                                                                               <int key="NSvFlags">2304</int>
+                                                                                                               <array class="NSMutableArray" key="NSSubviews">
+                                                                                                                       <object class="NSTableView" id="836264498">
+                                                                                                                               <reference key="NSNextResponder" ref="934177664"/>
+                                                                                                                               <int key="NSvFlags">256</int>
+                                                                                                                               <string key="NSFrameSize">{400, 342}</string>
+                                                                                                                               <reference key="NSSuperview" ref="934177664"/>
+                                                                                                                               <reference key="NSNextKeyView" ref="390520950"/>
+                                                                                                                               <string key="NSReuseIdentifierKey">_NS:13</string>
+                                                                                                                               <bool key="NSEnabled">YES</bool>
+                                                                                                                               <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+                                                                                                                               <bool key="NSControlAllowsExpansionToolTips">YES</bool>
+                                                                                                                               <object class="NSTableHeaderView" key="NSHeaderView" id="254105964">
+                                                                                                                                       <reference key="NSNextResponder" ref="390520950"/>
+                                                                                                                                       <int key="NSvFlags">256</int>
+                                                                                                                                       <string key="NSFrameSize">{400, 17}</string>
+                                                                                                                                       <reference key="NSSuperview" ref="390520950"/>
+                                                                                                                                       <reference key="NSNextKeyView" ref="934177664"/>
+                                                                                                                                       <string key="NSReuseIdentifierKey">_NS:16</string>
+                                                                                                                                       <reference key="NSTableView" ref="836264498"/>
+                                                                                                                               </object>
+                                                                                                                               <object class="_NSCornerView" key="NSCornerView">
+                                                                                                                                       <nil key="NSNextResponder"/>
+                                                                                                                                       <int key="NSvFlags">-2147483392</int>
+                                                                                                                                       <string key="NSFrame">{{224, 0}, {16, 17}}</string>
+                                                                                                                                       <reference key="NSNextKeyView" ref="934177664"/>
+                                                                                                                                       <string key="NSReuseIdentifierKey">_NS:19</string>
+                                                                                                                               </object>
+                                                                                                                               <array class="NSMutableArray" key="NSTableColumns">
+                                                                                                                                       <object class="NSTableColumn" id="412324706">
+                                                                                                                                               <string key="NSIdentifier">name</string>
+                                                                                                                                               <double key="NSWidth">197</double>
+                                                                                                                                               <double key="NSMinWidth">40</double>
+                                                                                                                                               <double key="NSMaxWidth">1000</double>
+                                                                                                                                               <object class="NSTableHeaderCell" key="NSHeaderCell">
+                                                                                                                                                       <int key="NSCellFlags">75497536</int>
+                                                                                                                                                       <int key="NSCellFlags2">2048</int>
+                                                                                                                                                       <string key="NSContents"/>
+                                                                                                                                                       <object class="NSFont" key="NSSupport" id="26">
+                                                                                                                                                               <string key="NSName">LucidaGrande</string>
+                                                                                                                                                               <double key="NSSize">11</double>
+                                                                                                                                                               <int key="NSfFlags">3100</int>
+                                                                                                                                                       </object>
+                                                                                                                                                       <object class="NSColor" key="NSBackgroundColor" id="67157928">
+                                                                                                                                                               <int key="NSColorSpace">3</int>
+                                                                                                                                                               <bytes key="NSWhite">MC4zMzMzMzI5ODU2AA</bytes>
+                                                                                                                                                       </object>
+                                                                                                                                                       <object class="NSColor" key="NSTextColor" id="270112593">
+                                                                                                                                                               <int key="NSColorSpace">6</int>
+                                                                                                                                                               <string key="NSCatalogName">System</string>
+                                                                                                                                                               <string key="NSColorName">headerTextColor</string>
+                                                                                                                                                               <reference key="NSColor" ref="415257931"/>
+                                                                                                                                                       </object>
+                                                                                                                                               </object>
+                                                                                                                                               <object class="NSTextFieldCell" key="NSDataCell" id="56933546">
+                                                                                                                                                       <int key="NSCellFlags">69206081</int>
+                                                                                                                                                       <int key="NSCellFlags2">2048</int>
+                                                                                                                                                       <string key="NSContents"/>
+                                                                                                                                                       <object class="NSFont" key="NSSupport" id="598757250">
+                                                                                                                                                               <string key="NSName">LucidaGrande</string>
+                                                                                                                                                               <double key="NSSize">13</double>
+                                                                                                                                                               <int key="NSfFlags">1044</int>
+                                                                                                                                                       </object>
+                                                                                                                                                       <string key="NSPlaceholderString">Name</string>
+                                                                                                                                                       <reference key="NSControlView" ref="836264498"/>
+                                                                                                                                                       <bool key="NSDrawsBackground">YES</bool>
+                                                                                                                                                       <object class="NSColor" key="NSBackgroundColor" id="275811800">
+                                                                                                                                                               <int key="NSColorSpace">6</int>
+                                                                                                                                                               <string key="NSCatalogName">System</string>
+                                                                                                                                                               <string key="NSColorName">controlBackgroundColor</string>
+                                                                                                                                                               <reference key="NSColor" ref="961815644"/>
+                                                                                                                                                       </object>
+                                                                                                                                                       <reference key="NSTextColor" ref="842671716"/>
+                                                                                                                                               </object>
+                                                                                                                                               <int key="NSResizingMask">3</int>
+                                                                                                                                               <bool key="NSIsResizeable">YES</bool>
+                                                                                                                                               <bool key="NSIsEditable">YES</bool>
+                                                                                                                                               <reference key="NSTableView" ref="836264498"/>
+                                                                                                                                       </object>
+                                                                                                                                       <object class="NSTableColumn" id="787416139">
+                                                                                                                                               <string key="NSIdentifier">account</string>
+                                                                                                                                               <double key="NSWidth">197</double>
+                                                                                                                                               <double key="NSMinWidth">40</double>
+                                                                                                                                               <double key="NSMaxWidth">1000</double>
+                                                                                                                                               <object class="NSTableHeaderCell" key="NSHeaderCell">
+                                                                                                                                                       <int key="NSCellFlags">75497536</int>
+                                                                                                                                                       <int key="NSCellFlags2">2048</int>
+                                                                                                                                                       <string key="NSContents"/>
+                                                                                                                                                       <reference key="NSSupport" ref="26"/>
+                                                                                                                                                       <reference key="NSBackgroundColor" ref="67157928"/>
+                                                                                                                                                       <reference key="NSTextColor" ref="270112593"/>
+                                                                                                                                               </object>
+                                                                                                                                               <object class="NSTextFieldCell" key="NSDataCell" id="327973200">
+                                                                                                                                                       <int key="NSCellFlags">69206081</int>
+                                                                                                                                                       <int key="NSCellFlags2">2048</int>
+                                                                                                                                                       <string key="NSContents"/>
+                                                                                                                                                       <reference key="NSSupport" ref="598757250"/>
+                                                                                                                                                       <string key="NSPlaceholderString">Account</string>
+                                                                                                                                                       <reference key="NSControlView" ref="836264498"/>
+                                                                                                                                                       <reference key="NSBackgroundColor" ref="275811800"/>
+                                                                                                                                                       <reference key="NSTextColor" ref="842671716"/>
+                                                                                                                                               </object>
+                                                                                                                                               <int key="NSResizingMask">3</int>
+                                                                                                                                               <bool key="NSIsResizeable">YES</bool>
+                                                                                                                                               <bool key="NSIsEditable">YES</bool>
+                                                                                                                                               <reference key="NSTableView" ref="836264498"/>
+                                                                                                                                       </object>
+                                                                                                                               </array>
+                                                                                                                               <double key="NSIntercellSpacingWidth">3</double>
+                                                                                                                               <double key="NSIntercellSpacingHeight">2</double>
+                                                                                                                               <object class="NSColor" key="NSBackgroundColor" id="569807385">
+                                                                                                                                       <int key="NSColorSpace">3</int>
+                                                                                                                                       <bytes key="NSWhite">MQA</bytes>
+                                                                                                                               </object>
+                                                                                                                               <object class="NSColor" key="NSGridColor">
+                                                                                                                                       <int key="NSColorSpace">6</int>
+                                                                                                                                       <string key="NSCatalogName">System</string>
+                                                                                                                                       <string key="NSColorName">gridColor</string>
+                                                                                                                                       <object class="NSColor" key="NSColor">
+                                                                                                                                               <int key="NSColorSpace">3</int>
+                                                                                                                                               <bytes key="NSWhite">MC41AA</bytes>
+                                                                                                                                       </object>
+                                                                                                                               </object>
+                                                                                                                               <double key="NSRowHeight">17</double>
+                                                                                                                               <int key="NSTvFlags">-163545088</int>
+                                                                                                                               <reference key="NSDelegate"/>
+                                                                                                                               <reference key="NSDataSource"/>
+                                                                                                                               <int key="NSGridStyleMask">9</int>
+                                                                                                                               <int key="NSColumnAutoresizingStyle">1</int>
+                                                                                                                               <int key="NSDraggingSourceMaskForLocal">15</int>
+                                                                                                                               <int key="NSDraggingSourceMaskForNonLocal">0</int>
+                                                                                                                               <bool key="NSAllowsTypeSelect">YES</bool>
+                                                                                                                               <int key="NSTableViewDraggingDestinationStyle">0</int>
+                                                                                                                               <int key="NSTableViewGroupRowStyle">1</int>
+                                                                                                                       </object>
+                                                                                                               </array>
+                                                                                                               <string key="NSFrame">{{1, 17}, {400, 342}}</string>
+                                                                                                               <reference key="NSSuperview" ref="542670786"/>
+                                                                                                               <reference key="NSNextKeyView" ref="836264498"/>
+                                                                                                               <string key="NSReuseIdentifierKey">_NS:11</string>
+                                                                                                               <reference key="NSDocView" ref="836264498"/>
+                                                                                                               <reference key="NSBGColor" ref="275811800"/>
+                                                                                                               <int key="NScvFlags">4</int>
+                                                                                                       </object>
+                                                                                                       <object class="NSScroller" id="410011191">
+                                                                                                               <reference key="NSNextResponder" ref="542670786"/>
+                                                                                                               <int key="NSvFlags">-2147483392</int>
+                                                                                                               <string key="NSFrame">{{224, 17}, {15, 102}}</string>
+                                                                                                               <reference key="NSSuperview" ref="542670786"/>
+                                                                                                               <reference key="NSNextKeyView" ref="341785125"/>
+                                                                                                               <string key="NSReuseIdentifierKey">_NS:58</string>
+                                                                                                               <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+                                                                                                               <reference key="NSTarget" ref="542670786"/>
+                                                                                                               <string key="NSAction">_doScroller:</string>
+                                                                                                               <double key="NSCurValue">37</double>
+                                                                                                               <double key="NSPercent">0.1947367936372757</double>
+                                                                                                       </object>
+                                                                                                       <object class="NSScroller" id="341785125">
+                                                                                                               <reference key="NSNextResponder" ref="542670786"/>
+                                                                                                               <int key="NSvFlags">-2147483392</int>
+                                                                                                               <string key="NSFrame">{{1, 119}, {223, 15}}</string>
+                                                                                                               <reference key="NSSuperview" ref="542670786"/>
+                                                                                                               <reference key="NSNextKeyView" ref="834759928"/>
+                                                                                                               <string key="NSReuseIdentifierKey">_NS:60</string>
+                                                                                                               <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+                                                                                                               <int key="NSsFlags">1</int>
+                                                                                                               <reference key="NSTarget" ref="542670786"/>
+                                                                                                               <string key="NSAction">_doScroller:</string>
+                                                                                                               <double key="NSPercent">0.57142859697341919</double>
+                                                                                                       </object>
+                                                                                                       <object class="NSClipView" id="390520950">
+                                                                                                               <reference key="NSNextResponder" ref="542670786"/>
+                                                                                                               <int key="NSvFlags">2304</int>
+                                                                                                               <array class="NSMutableArray" key="NSSubviews">
+                                                                                                                       <reference ref="254105964"/>
+                                                                                                               </array>
+                                                                                                               <string key="NSFrame">{{1, 0}, {400, 17}}</string>
+                                                                                                               <reference key="NSSuperview" ref="542670786"/>
+                                                                                                               <reference key="NSNextKeyView" ref="254105964"/>
+                                                                                                               <string key="NSReuseIdentifierKey">_NS:15</string>
+                                                                                                               <reference key="NSDocView" ref="254105964"/>
+                                                                                                               <reference key="NSBGColor" ref="275811800"/>
+                                                                                                               <int key="NScvFlags">4</int>
+                                                                                                       </object>
+                                                                                               </array>
+                                                                                               <string key="NSFrame">{{3, 12}, {402, 360}}</string>
+                                                                                               <reference key="NSSuperview" ref="716065875"/>
+                                                                                               <reference key="NSNextKeyView" ref="934177664"/>
+                                                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                                                               <int key="NSsFlags">133682</int>
+                                                                                               <reference key="NSVScroller" ref="410011191"/>
+                                                                                               <reference key="NSHScroller" ref="341785125"/>
+                                                                                               <reference key="NSContentView" ref="934177664"/>
+                                                                                               <reference key="NSHeaderClipView" ref="390520950"/>
+                                                                                               <bytes key="NSScrollAmts">QSAAAEEgAABBmAAAQZgAAA</bytes>
+                                                                                               <double key="NSMinMagnification">0.25</double>
+                                                                                               <double key="NSMaxMagnification">4</double>
+                                                                                               <double key="NSMagnification">1</double>
+                                                                                       </object>
+                                                                               </array>
+                                                                               <string key="NSFrame">{{32, 7}, {422, 414}}</string>
+                                                                               <reference key="NSNextKeyView" ref="233427652"/>
+                                                                               <string key="NSReuseIdentifierKey">_NS:11</string>
+                                                                       </object>
+                                                                       <string key="NSLabel">🔑</string>
+                                                                       <reference key="NSColor" ref="926294313"/>
+                                                                       <reference key="NSTabView" ref="916837096"/>
+                                                               </object>
+                                                               <object class="NSTabViewItem" id="993304700">
+                                                                       <string key="NSIdentifier">sync</string>
+                                                                       <object class="NSView" key="NSView" id="141374255">
+                                                                               <nil key="NSNextResponder"/>
+                                                                               <int key="NSvFlags">256</int>
+                                                                               <array class="NSMutableArray" key="NSSubviews">
+                                                                                       <object class="NSButton" id="1048394879">
+                                                                                               <reference key="NSNextResponder" ref="141374255"/>
+                                                                                               <int key="NSvFlags">268</int>
+                                                                                               <string key="NSFrame">{{1, 381}, {177, 18}}</string>
+                                                                                               <reference key="NSSuperview" ref="141374255"/>
+                                                                                               <reference key="NSNextKeyView" ref="998974400"/>
+                                                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                                                               <bool key="NSEnabled">YES</bool>
+                                                                                               <object class="NSButtonCell" key="NSCell" id="1020736299">
+                                                                                                       <int key="NSCellFlags">-2080374784</int>
+                                                                                                       <int key="NSCellFlags2">293601280</int>
+                                                                                                       <string key="NSContents">Enable Keychain Syncing</string>
+                                                                                                       <reference key="NSSupport" ref="598757250"/>
+                                                                                                       <string key="NSCellIdentifier">_NS:9</string>
+                                                                                                       <reference key="NSControlView" ref="1048394879"/>
+                                                                                                       <int key="NSButtonFlags">1211912448</int>
+                                                                                                       <int key="NSButtonFlags2">2</int>
+                                                                                                       <object class="NSCustomResource" key="NSNormalImage" id="549337529">
+                                                                                                               <string key="NSClassName">NSImage</string>
+                                                                                                               <string key="NSResourceName">NSSwitch</string>
+                                                                                                       </object>
+                                                                                                       <object class="NSButtonImageSource" key="NSAlternateImage" id="466233108">
+                                                                                                               <string key="NSImageName">NSSwitch</string>
+                                                                                                       </object>
+                                                                                                       <string key="NSAlternateContents"/>
+                                                                                                       <string key="NSKeyEquivalent"/>
+                                                                                                       <int key="NSPeriodicDelay">200</int>
+                                                                                                       <int key="NSPeriodicInterval">25</int>
+                                                                                               </object>
+                                                                                               <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+                                                                                       </object>
+                                                                                       <object class="NSProgressIndicator" id="1020307009">
+                                                                                               <reference key="NSNextResponder" ref="141374255"/>
+                                                                                               <int key="NSvFlags">268</int>
+                                                                                               <string key="NSFrame">{{373, 365}, {32, 32}}</string>
+                                                                                               <reference key="NSSuperview" ref="141374255"/>
+                                                                                               <reference key="NSNextKeyView" ref="1071550691"/>
+                                                                                               <bool key="NSViewCanDrawConcurrently">YES</bool>
+                                                                                               <string key="NSReuseIdentifierKey">_NS:945</string>
+                                                                                               <int key="NSpiFlags">28682</int>
+                                                                                               <double key="NSMaxValue">100</double>
+                                                                                       </object>
+                                                                                       <object class="NSTextField" id="998974400">
+                                                                                               <reference key="NSNextResponder" ref="141374255"/>
+                                                                                               <int key="NSvFlags">268</int>
+                                                                                               <string key="NSFrame">{{3, 358}, {176, 17}}</string>
+                                                                                               <reference key="NSSuperview" ref="141374255"/>
+                                                                                               <reference key="NSNextKeyView" ref="1020307009"/>
+                                                                                               <string key="NSReuseIdentifierKey">_NS:1535</string>
+                                                                                               <bool key="NSEnabled">YES</bool>
+                                                                                               <object class="NSTextFieldCell" key="NSCell" id="718406896">
+                                                                                                       <int key="NSCellFlags">68157504</int>
+                                                                                                       <int key="NSCellFlags2">272630784</int>
+                                                                                                       <string key="NSContents"/>
+                                                                                                       <reference key="NSSupport" ref="598757250"/>
+                                                                                                       <string key="NSPlaceholderString">Sync status message</string>
+                                                                                                       <string key="NSCellIdentifier">_NS:1535</string>
+                                                                                                       <reference key="NSControlView" ref="998974400"/>
+                                                                                                       <reference key="NSBackgroundColor" ref="926294313"/>
+                                                                                                       <reference key="NSTextColor" ref="842671716"/>
+                                                                                               </object>
+                                                                                               <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+                                                                                       </object>
+                                                                                       <object class="NSBox" id="1071550691">
+                                                                                               <reference key="NSNextResponder" ref="141374255"/>
+                                                                                               <int key="NSvFlags">12</int>
+                                                                                               <string key="NSFrame">{{3, 347}, {402, 5}}</string>
+                                                                                               <reference key="NSSuperview" ref="141374255"/>
+                                                                                               <reference key="NSNextKeyView" ref="660421540"/>
+                                                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                                                               <string key="NSOffsets">{0, 0}</string>
+                                                                                               <object class="NSTextFieldCell" key="NSTitleCell">
+                                                                                                       <int key="NSCellFlags">67108864</int>
+                                                                                                       <int key="NSCellFlags2">0</int>
+                                                                                                       <string key="NSContents">Box</string>
+                                                                                                       <reference key="NSSupport" ref="598757250"/>
+                                                                                                       <object class="NSColor" key="NSBackgroundColor">
+                                                                                                               <int key="NSColorSpace">6</int>
+                                                                                                               <string key="NSCatalogName">System</string>
+                                                                                                               <string key="NSColorName">textBackgroundColor</string>
+                                                                                                               <reference key="NSColor" ref="569807385"/>
+                                                                                                       </object>
+                                                                                                       <object class="NSColor" key="NSTextColor">
+                                                                                                               <int key="NSColorSpace">3</int>
+                                                                                                               <bytes key="NSWhite">MCAwLjgwMDAwMDAxMTkAA</bytes>
+                                                                                                       </object>
+                                                                                               </object>
+                                                                                               <int key="NSBorderType">3</int>
+                                                                                               <int key="NSBoxType">2</int>
+                                                                                               <int key="NSTitlePosition">0</int>
+                                                                                               <bool key="NSTransparent">NO</bool>
+                                                                                       </object>
+                                                                                       <object class="NSTextField" id="660421540">
+                                                                                               <reference key="NSNextResponder" ref="141374255"/>
+                                                                                               <int key="NSvFlags">268</int>
+                                                                                               <string key="NSFrame">{{3, 324}, {38, 17}}</string>
+                                                                                               <reference key="NSSuperview" ref="141374255"/>
+                                                                                               <reference key="NSNextKeyView" ref="665082678"/>
+                                                                                               <string key="NSReuseIdentifierKey">_NS:1535</string>
+                                                                                               <bool key="NSEnabled">YES</bool>
+                                                                                               <object class="NSTextFieldCell" key="NSCell" id="15806633">
+                                                                                                       <int key="NSCellFlags">68157504</int>
+                                                                                                       <int key="NSCellFlags2">272630784</int>
+                                                                                                       <string key="NSContents">Peers:</string>
+                                                                                                       <reference key="NSSupport" ref="598757250"/>
+                                                                                                       <string key="NSCellIdentifier">_NS:1535</string>
+                                                                                                       <reference key="NSControlView" ref="660421540"/>
+                                                                                                       <reference key="NSBackgroundColor" ref="926294313"/>
+                                                                                                       <reference key="NSTextColor" ref="842671716"/>
+                                                                                               </object>
+                                                                                               <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+                                                                                       </object>
+                                                                                       <object class="NSTextField" id="665082678">
+                                                                                               <reference key="NSNextResponder" ref="141374255"/>
+                                                                                               <int key="NSvFlags">268</int>
+                                                                                               <string key="NSFrame">{{63, 324}, {47, 17}}</string>
+                                                                                               <reference key="NSSuperview" ref="141374255"/>
+                                                                                               <reference key="NSNextKeyView" ref="588513756"/>
+                                                                                               <string key="NSReuseIdentifierKey">_NS:1535</string>
+                                                                                               <bool key="NSEnabled">YES</bool>
+                                                                                               <object class="NSTextFieldCell" key="NSCell" id="353430769">
+                                                                                                       <int key="NSCellFlags">68157504</int>
+                                                                                                       <int key="NSCellFlags2">272630784</int>
+                                                                                                       <string key="NSContents"/>
+                                                                                                       <reference key="NSSupport" ref="598757250"/>
+                                                                                                       <string key="NSPlaceholderString">#peers</string>
+                                                                                                       <string key="NSCellIdentifier">_NS:1535</string>
+                                                                                                       <reference key="NSControlView" ref="665082678"/>
+                                                                                                       <reference key="NSBackgroundColor" ref="926294313"/>
+                                                                                                       <reference key="NSTextColor" ref="842671716"/>
+                                                                                               </object>
+                                                                                               <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+                                                                                       </object>
+                                                                                       <object class="NSScrollView" id="588513756">
+                                                                                               <reference key="NSNextResponder" ref="141374255"/>
+                                                                                               <int key="NSvFlags">256</int>
+                                                                                               <array class="NSMutableArray" key="NSSubviews">
+                                                                                                       <object class="NSClipView" id="212131435">
+                                                                                                               <reference key="NSNextResponder" ref="588513756"/>
+                                                                                                               <int key="NSvFlags">2304</int>
+                                                                                                               <array class="NSMutableArray" key="NSSubviews">
+                                                                                                                       <object class="NSTextView" id="445558087">
+                                                                                                                               <reference key="NSNextResponder" ref="212131435"/>
+                                                                                                                               <int key="NSvFlags">2322</int>
+                                                                                                                               <string key="NSFrameSize">{400, 133}</string>
+                                                                                                                               <reference key="NSSuperview" ref="212131435"/>
+                                                                                                                               <reference key="NSNextKeyView" ref="508177949"/>
+                                                                                                                               <string key="NSReuseIdentifierKey">_NS:13</string>
+                                                                                                                               <object class="NSTextContainer" key="NSTextContainer" id="57440719">
+                                                                                                                                       <object class="NSLayoutManager" key="NSLayoutManager">
+                                                                                                                                               <object class="NSTextStorage" key="NSTextStorage">
+                                                                                                                                                       <object class="NSMutableString" key="NSString">
+                                                                                                                                                               <characters key="NS.bytes"/>
+                                                                                                                                                       </object>
+                                                                                                                                                       <nil key="NSDelegate"/>
+                                                                                                                                               </object>
+                                                                                                                                               <array class="NSMutableArray" key="NSTextContainers">
+                                                                                                                                                       <reference ref="57440719"/>
+                                                                                                                                               </array>
+                                                                                                                                               <int key="NSLMFlags">166</int>
+                                                                                                                                               <nil key="NSDelegate"/>
+                                                                                                                                       </object>
+                                                                                                                                       <reference key="NSTextView" ref="445558087"/>
+                                                                                                                                       <double key="NSWidth">400</double>
+                                                                                                                                       <int key="NSTCFlags">1</int>
+                                                                                                                               </object>
+                                                                                                                               <object class="NSTextViewSharedData" key="NSSharedData">
+                                                                                                                                       <int key="NSFlags">67121125</int>
+                                                                                                                                       <int key="NSTextCheckingTypes">0</int>
+                                                                                                                                       <nil key="NSMarkedAttributes"/>
+                                                                                                                                       <reference key="NSBackgroundColor" ref="569807385"/>
+                                                                                                                                       <dictionary key="NSSelectedAttributes">
+                                                                                                                                               <object class="NSColor" key="NSBackgroundColor" id="911183320">
+                                                                                                                                                       <int key="NSColorSpace">6</int>
+                                                                                                                                                       <string key="NSCatalogName">System</string>
+                                                                                                                                                       <string key="NSColorName">selectedTextBackgroundColor</string>
+                                                                                                                                                       <reference key="NSColor" ref="961815644"/>
+                                                                                                                                               </object>
+                                                                                                                                               <object class="NSColor" key="NSColor" id="296498919">
+                                                                                                                                                       <int key="NSColorSpace">6</int>
+                                                                                                                                                       <string key="NSCatalogName">System</string>
+                                                                                                                                                       <string key="NSColorName">selectedTextColor</string>
+                                                                                                                                                       <reference key="NSColor" ref="415257931"/>
+                                                                                                                                               </object>
+                                                                                                                                       </dictionary>
+                                                                                                                                       <reference key="NSInsertionColor" ref="415257931"/>
+                                                                                                                                       <dictionary key="NSLinkAttributes">
+                                                                                                                                               <object class="NSColor" key="NSColor" id="367160189">
+                                                                                                                                                       <int key="NSColorSpace">1</int>
+                                                                                                                                                       <bytes key="NSRGB">MCAwIDEAA</bytes>
+                                                                                                                                               </object>
+                                                                                                                                               <object class="NSCursor" key="NSCursor" id="436196747">
+                                                                                                                                                       <string key="NSHotSpot">{8, -8}</string>
+                                                                                                                                                       <int key="NSCursorType">13</int>
+                                                                                                                                               </object>
+                                                                                                                                               <integer value="1" key="NSUnderline"/>
+                                                                                                                                       </dictionary>
+                                                                                                                                       <nil key="NSDefaultParagraphStyle"/>
+                                                                                                                                       <nil key="NSTextFinder"/>
+                                                                                                                                       <int key="NSPreferredTextFinderStyle">1</int>
+                                                                                                                               </object>
+                                                                                                                               <int key="NSTVFlags">6</int>
+                                                                                                                               <string key="NSMaxSize">{463, 10000000}</string>
+                                                                                                                               <nil key="NSDelegate"/>
+                                                                                                                       </object>
+                                                                                                               </array>
+                                                                                                               <string key="NSFrame">{{1, 1}, {400, 133}}</string>
+                                                                                                               <reference key="NSSuperview" ref="588513756"/>
+                                                                                                               <reference key="NSNextKeyView" ref="445558087"/>
+                                                                                                               <string key="NSReuseIdentifierKey">_NS:11</string>
+                                                                                                               <reference key="NSDocView" ref="445558087"/>
+                                                                                                               <reference key="NSBGColor" ref="569807385"/>
+                                                                                                               <object class="NSCursor" key="NSCursor">
+                                                                                                                       <string key="NSHotSpot">{4, 5}</string>
+                                                                                                                       <object class="NSImage" key="NSImage">
+                                                                                                                               <int key="NSImageFlags">79691776</int>
+                                                                                                                               <array key="NSReps">
+                                                                                                                                       <array>
+                                                                                                                                               <integer value="5"/>
+                                                                                                                                               <object class="NSURL">
+                                                                                                                                                       <nil key="NS.base"/>
+                                                                                                                                                       <string key="NS.relative">file:///Applications/Xcode.app/Contents/SharedFrameworks/DVTKit.framework/Resources/DVTIbeamCursor.tiff</string>
+                                                                                                                                               </object>
+                                                                                                                                       </array>
+                                                                                                                               </array>
+                                                                                                                               <object class="NSColor" key="NSColor" id="572307721">
+                                                                                                                                       <int key="NSColorSpace">3</int>
+                                                                                                                                       <bytes key="NSWhite">MCAwAA</bytes>
+                                                                                                                               </object>
+                                                                                                                       </object>
+                                                                                                               </object>
+                                                                                                               <int key="NScvFlags">4</int>
+                                                                                                       </object>
+                                                                                                       <object class="NSScroller" id="508177949">
+                                                                                                               <reference key="NSNextResponder" ref="588513756"/>
+                                                                                                               <int key="NSvFlags">256</int>
+                                                                                                               <string key="NSFrame">{{385, 1}, {16, 133}}</string>
+                                                                                                               <reference key="NSSuperview" ref="588513756"/>
+                                                                                                               <reference key="NSNextKeyView" ref="477817691"/>
+                                                                                                               <string key="NSReuseIdentifierKey">_NS:83</string>
+                                                                                                               <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+                                                                                                               <reference key="NSTarget" ref="588513756"/>
+                                                                                                               <string key="NSAction">_doScroller:</string>
+                                                                                                               <double key="NSCurValue">1</double>
+                                                                                                               <double key="NSPercent">0.85256409645080566</double>
+                                                                                                       </object>
+                                                                                                       <object class="NSScroller" id="892199647">
+                                                                                                               <reference key="NSNextResponder" ref="588513756"/>
+                                                                                                               <int key="NSvFlags">-2147483392</int>
+                                                                                                               <string key="NSFrame">{{-100, -100}, {87, 18}}</string>
+                                                                                                               <reference key="NSSuperview" ref="588513756"/>
+                                                                                                               <reference key="NSNextKeyView" ref="212131435"/>
+                                                                                                               <string key="NSReuseIdentifierKey">_NS:33</string>
+                                                                                                               <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+                                                                                                               <int key="NSsFlags">1</int>
+                                                                                                               <reference key="NSTarget" ref="588513756"/>
+                                                                                                               <string key="NSAction">_doScroller:</string>
+                                                                                                               <double key="NSCurValue">1</double>
+                                                                                                               <double key="NSPercent">0.94565218687057495</double>
+                                                                                                       </object>
+                                                                                               </array>
+                                                                                               <string key="NSFrame">{{3, 181}, {402, 135}}</string>
+                                                                                               <reference key="NSSuperview" ref="141374255"/>
+                                                                                               <reference key="NSNextKeyView" ref="892199647"/>
+                                                                                               <bool key="NSViewIsLayerTreeHost">YES</bool>
+                                                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                                                               <int key="NSsFlags">133138</int>
+                                                                                               <reference key="NSVScroller" ref="508177949"/>
+                                                                                               <reference key="NSHScroller" ref="892199647"/>
+                                                                                               <reference key="NSContentView" ref="212131435"/>
+                                                                                               <double key="NSMinMagnification">0.25</double>
+                                                                                               <double key="NSMaxMagnification">4</double>
+                                                                                               <double key="NSMagnification">1</double>
+                                                                                       </object>
+                                                                                       <object class="NSTextField" id="477817691">
+                                                                                               <reference key="NSNextResponder" ref="141374255"/>
+                                                                                               <int key="NSvFlags">268</int>
+                                                                                               <string key="NSFrame">{{6, 156}, {75, 17}}</string>
+                                                                                               <reference key="NSSuperview" ref="141374255"/>
+                                                                                               <reference key="NSNextKeyView" ref="305991928"/>
+                                                                                               <string key="NSReuseIdentifierKey">_NS:1535</string>
+                                                                                               <bool key="NSEnabled">YES</bool>
+                                                                                               <object class="NSTextFieldCell" key="NSCell" id="249835835">
+                                                                                                       <int key="NSCellFlags">68157504</int>
+                                                                                                       <int key="NSCellFlags2">272630784</int>
+                                                                                                       <string key="NSContents">Applicants:</string>
+                                                                                                       <reference key="NSSupport" ref="598757250"/>
+                                                                                                       <string key="NSCellIdentifier">_NS:1535</string>
+                                                                                                       <reference key="NSControlView" ref="477817691"/>
+                                                                                                       <reference key="NSBackgroundColor" ref="926294313"/>
+                                                                                                       <reference key="NSTextColor" ref="842671716"/>
+                                                                                               </object>
+                                                                                               <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+                                                                                       </object>
+                                                                                       <object class="NSTextField" id="305991928">
+                                                                                               <reference key="NSNextResponder" ref="141374255"/>
+                                                                                               <int key="NSvFlags">268</int>
+                                                                                               <string key="NSFrame">{{83, 156}, {77, 17}}</string>
+                                                                                               <reference key="NSSuperview" ref="141374255"/>
+                                                                                               <reference key="NSNextKeyView" ref="887827883"/>
+                                                                                               <string key="NSReuseIdentifierKey">_NS:1535</string>
+                                                                                               <bool key="NSEnabled">YES</bool>
+                                                                                               <object class="NSTextFieldCell" key="NSCell" id="255632910">
+                                                                                                       <int key="NSCellFlags">68157504</int>
+                                                                                                       <int key="NSCellFlags2">272630784</int>
+                                                                                                       <string key="NSContents"/>
+                                                                                                       <reference key="NSSupport" ref="598757250"/>
+                                                                                                       <string key="NSPlaceholderString">#applicants</string>
+                                                                                                       <string key="NSCellIdentifier">_NS:1535</string>
+                                                                                                       <reference key="NSControlView" ref="305991928"/>
+                                                                                                       <reference key="NSBackgroundColor" ref="926294313"/>
+                                                                                                       <reference key="NSTextColor" ref="842671716"/>
+                                                                                               </object>
+                                                                                               <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+                                                                                       </object>
+                                                                                       <object class="NSScrollView" id="887827883">
+                                                                                               <reference key="NSNextResponder" ref="141374255"/>
+                                                                                               <int key="NSvFlags">256</int>
+                                                                                               <array class="NSMutableArray" key="NSSubviews">
+                                                                                                       <object class="NSClipView" id="208976775">
+                                                                                                               <reference key="NSNextResponder" ref="887827883"/>
+                                                                                                               <int key="NSvFlags">2304</int>
+                                                                                                               <array class="NSMutableArray" key="NSSubviews">
+                                                                                                                       <object class="NSTextView" id="97048596">
+                                                                                                                               <reference key="NSNextResponder" ref="208976775"/>
+                                                                                                                               <int key="NSvFlags">2322</int>
+                                                                                                                               <string key="NSFrameSize">{400, 129}</string>
+                                                                                                                               <reference key="NSSuperview" ref="208976775"/>
+                                                                                                                               <reference key="NSNextKeyView" ref="68514601"/>
+                                                                                                                               <string key="NSReuseIdentifierKey">_NS:13</string>
+                                                                                                                               <object class="NSTextContainer" key="NSTextContainer" id="229341991">
+                                                                                                                                       <object class="NSLayoutManager" key="NSLayoutManager">
+                                                                                                                                               <object class="NSTextStorage" key="NSTextStorage">
+                                                                                                                                                       <object class="NSMutableString" key="NSString">
+                                                                                                                                                               <characters key="NS.bytes"/>
+                                                                                                                                                       </object>
+                                                                                                                                                       <nil key="NSDelegate"/>
+                                                                                                                                               </object>
+                                                                                                                                               <array class="NSMutableArray" key="NSTextContainers">
+                                                                                                                                                       <reference ref="229341991"/>
+                                                                                                                                               </array>
+                                                                                                                                               <int key="NSLMFlags">166</int>
+                                                                                                                                               <nil key="NSDelegate"/>
+                                                                                                                                       </object>
+                                                                                                                                       <reference key="NSTextView" ref="97048596"/>
+                                                                                                                                       <double key="NSWidth">400</double>
+                                                                                                                                       <int key="NSTCFlags">1</int>
+                                                                                                                               </object>
+                                                                                                                               <object class="NSTextViewSharedData" key="NSSharedData">
+                                                                                                                                       <int key="NSFlags">67121125</int>
+                                                                                                                                       <int key="NSTextCheckingTypes">0</int>
+                                                                                                                                       <nil key="NSMarkedAttributes"/>
+                                                                                                                                       <reference key="NSBackgroundColor" ref="569807385"/>
+                                                                                                                                       <dictionary key="NSSelectedAttributes">
+                                                                                                                                               <reference key="NSBackgroundColor" ref="911183320"/>
+                                                                                                                                               <reference key="NSColor" ref="296498919"/>
+                                                                                                                                       </dictionary>
+                                                                                                                                       <reference key="NSInsertionColor" ref="415257931"/>
+                                                                                                                                       <dictionary key="NSLinkAttributes">
+                                                                                                                                               <reference key="NSColor" ref="367160189"/>
+                                                                                                                                               <reference key="NSCursor" ref="436196747"/>
+                                                                                                                                               <integer value="1" key="NSUnderline"/>
+                                                                                                                                       </dictionary>
+                                                                                                                                       <nil key="NSDefaultParagraphStyle"/>
+                                                                                                                                       <nil key="NSTextFinder"/>
+                                                                                                                                       <int key="NSPreferredTextFinderStyle">1</int>
+                                                                                                                               </object>
+                                                                                                                               <int key="NSTVFlags">6</int>
+                                                                                                                               <string key="NSMaxSize">{463, 10000000}</string>
+                                                                                                                               <nil key="NSDelegate"/>
+                                                                                                                       </object>
+                                                                                                               </array>
+                                                                                                               <string key="NSFrame">{{1, 1}, {400, 129}}</string>
+                                                                                                               <reference key="NSSuperview" ref="887827883"/>
+                                                                                                               <reference key="NSNextKeyView" ref="97048596"/>
+                                                                                                               <string key="NSReuseIdentifierKey">_NS:11</string>
+                                                                                                               <reference key="NSDocView" ref="97048596"/>
+                                                                                                               <reference key="NSBGColor" ref="569807385"/>
+                                                                                                               <object class="NSCursor" key="NSCursor">
+                                                                                                                       <string key="NSHotSpot">{4, 5}</string>
+                                                                                                                       <object class="NSImage" key="NSImage">
+                                                                                                                               <int key="NSImageFlags">79691776</int>
+                                                                                                                               <array key="NSReps">
+                                                                                                                                       <array>
+                                                                                                                                               <integer value="5"/>
+                                                                                                                                               <object class="NSURL">
+                                                                                                                                                       <nil key="NS.base"/>
+                                                                                                                                                       <string key="NS.relative">file:///Applications/Xcode.app/Contents/SharedFrameworks/DVTKit.framework/Resources/DVTIbeamCursor.tiff</string>
+                                                                                                                                               </object>
+                                                                                                                                       </array>
+                                                                                                                               </array>
+                                                                                                                               <reference key="NSColor" ref="572307721"/>
+                                                                                                                       </object>
+                                                                                                               </object>
+                                                                                                               <int key="NScvFlags">4</int>
+                                                                                                       </object>
+                                                                                                       <object class="NSScroller" id="68514601">
+                                                                                                               <reference key="NSNextResponder" ref="887827883"/>
+                                                                                                               <int key="NSvFlags">256</int>
+                                                                                                               <string key="NSFrame">{{385, 1}, {16, 129}}</string>
+                                                                                                               <reference key="NSSuperview" ref="887827883"/>
+                                                                                                               <reference key="NSNextKeyView" ref="916837096"/>
+                                                                                                               <string key="NSReuseIdentifierKey">_NS:83</string>
+                                                                                                               <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+                                                                                                               <reference key="NSTarget" ref="887827883"/>
+                                                                                                               <string key="NSAction">_doScroller:</string>
+                                                                                                               <double key="NSCurValue">1</double>
+                                                                                                               <double key="NSPercent">0.85256409645080566</double>
+                                                                                                       </object>
+                                                                                                       <object class="NSScroller" id="748993527">
+                                                                                                               <reference key="NSNextResponder" ref="887827883"/>
+                                                                                                               <int key="NSvFlags">-2147483392</int>
+                                                                                                               <string key="NSFrame">{{-100, -100}, {87, 18}}</string>
+                                                                                                               <reference key="NSSuperview" ref="887827883"/>
+                                                                                                               <reference key="NSNextKeyView" ref="208976775"/>
+                                                                                                               <string key="NSReuseIdentifierKey">_NS:33</string>
+                                                                                                               <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+                                                                                                               <int key="NSsFlags">1</int>
+                                                                                                               <reference key="NSTarget" ref="887827883"/>
+                                                                                                               <string key="NSAction">_doScroller:</string>
+                                                                                                               <double key="NSCurValue">1</double>
+                                                                                                               <double key="NSPercent">0.94565218687057495</double>
+                                                                                                       </object>
+                                                                                               </array>
+                                                                                               <string key="NSFrame">{{3, 17}, {402, 131}}</string>
+                                                                                               <reference key="NSSuperview" ref="141374255"/>
+                                                                                               <reference key="NSNextKeyView" ref="748993527"/>
+                                                                                               <bool key="NSViewIsLayerTreeHost">YES</bool>
+                                                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                                                               <int key="NSsFlags">133138</int>
+                                                                                               <reference key="NSVScroller" ref="68514601"/>
+                                                                                               <reference key="NSHScroller" ref="748993527"/>
+                                                                                               <reference key="NSContentView" ref="208976775"/>
+                                                                                               <double key="NSMinMagnification">0.25</double>
+                                                                                               <double key="NSMaxMagnification">4</double>
+                                                                                               <double key="NSMagnification">1</double>
+                                                                                       </object>
+                                                                               </array>
+                                                                               <string key="NSFrame">{{32, 7}, {422, 414}}</string>
+                                                                               <reference key="NSNextKeyView" ref="1048394879"/>
+                                                                               <string key="NSReuseIdentifierKey">_NS:28</string>
+                                                                       </object>
+                                                                       <string key="NSLabel">🌀</string>
+                                                                       <reference key="NSColor" ref="926294313"/>
+                                                                       <reference key="NSTabView" ref="916837096"/>
+                                                               </object>
+                                                               <object class="NSTabViewItem" id="133282229">
+                                                                       <string key="NSIdentifier">tools</string>
+                                                                       <object class="NSView" key="NSView" id="933472960">
+                                                                               <reference key="NSNextResponder" ref="916837096"/>
+                                                                               <int key="NSvFlags">256</int>
+                                                                               <array class="NSMutableArray" key="NSSubviews">
+                                                                                       <object class="NSButton" id="1003098491">
+                                                                                               <reference key="NSNextResponder" ref="933472960"/>
+                                                                                               <int key="NSvFlags">268</int>
+                                                                                               <string key="NSFrame">{{249, 262}, {156, 19}}</string>
+                                                                                               <reference key="NSSuperview" ref="933472960"/>
+                                                                                               <reference key="NSWindow"/>
+                                                                                               <reference key="NSNextKeyView" ref="914091846"/>
+                                                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                                                               <bool key="NSEnabled">YES</bool>
+                                                                                               <object class="NSButtonCell" key="NSCell" id="1031398538">
+                                                                                                       <int key="NSCellFlags">-1543503872</int>
+                                                                                                       <int key="NSCellFlags2">134217728</int>
+                                                                                                       <string key="NSContents">Auto-populate Keychain</string>
+                                                                                                       <object class="NSFont" key="NSSupport" id="1055465101">
+                                                                                                               <string key="NSName">LucidaGrande</string>
+                                                                                                               <double key="NSSize">12</double>
+                                                                                                               <int key="NSfFlags">16</int>
+                                                                                                       </object>
+                                                                                                       <string key="NSCellIdentifier">_NS:9</string>
+                                                                                                       <reference key="NSControlView" ref="1003098491"/>
+                                                                                                       <int key="NSButtonFlags">-2038153216</int>
+                                                                                                       <int key="NSButtonFlags2">164</int>
+                                                                                                       <string key="NSAlternateContents"/>
+                                                                                                       <string key="NSKeyEquivalent"/>
+                                                                                                       <int key="NSPeriodicDelay">400</int>
+                                                                                                       <int key="NSPeriodicInterval">75</int>
+                                                                                               </object>
+                                                                                               <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+                                                                                       </object>
+                                                                                       <object class="NSButton" id="928329068">
+                                                                                               <reference key="NSNextResponder" ref="933472960"/>
+                                                                                               <int key="NSvFlags">268</int>
+                                                                                               <string key="NSFrame">{{249, 158}, {156, 19}}</string>
+                                                                                               <reference key="NSSuperview" ref="933472960"/>
+                                                                                               <reference key="NSWindow"/>
+                                                                                               <reference key="NSNextKeyView" ref="786023451"/>
+                                                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                                                               <bool key="NSEnabled">YES</bool>
+                                                                                               <object class="NSButtonCell" key="NSCell" id="235965764">
+                                                                                                       <int key="NSCellFlags">-1543503872</int>
+                                                                                                       <int key="NSCellFlags2">134217728</int>
+                                                                                                       <string key="NSContents">Clear KVS</string>
+                                                                                                       <reference key="NSSupport" ref="1055465101"/>
+                                                                                                       <string key="NSCellIdentifier">_NS:9</string>
+                                                                                                       <reference key="NSControlView" ref="928329068"/>
+                                                                                                       <int key="NSButtonFlags">-2038153216</int>
+                                                                                                       <int key="NSButtonFlags2">164</int>
+                                                                                                       <string key="NSAlternateContents"/>
+                                                                                                       <string key="NSKeyEquivalent"/>
+                                                                                                       <int key="NSPeriodicDelay">400</int>
+                                                                                                       <int key="NSPeriodicInterval">75</int>
+                                                                                               </object>
+                                                                                               <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+                                                                                       </object>
+                                                                                       <object class="NSButton" id="1053273967">
+                                                                                               <reference key="NSNextResponder" ref="933472960"/>
+                                                                                               <int key="NSvFlags">268</int>
+                                                                                               <string key="NSFrame">{{249, 132}, {156, 19}}</string>
+                                                                                               <reference key="NSSuperview" ref="933472960"/>
+                                                                                               <reference key="NSWindow"/>
+                                                                                               <reference key="NSNextKeyView" ref="760674507"/>
+                                                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                                                               <bool key="NSEnabled">YES</bool>
+                                                                                               <object class="NSButtonCell" key="NSCell" id="276328216">
+                                                                                                       <int key="NSCellFlags">-2080374784</int>
+                                                                                                       <int key="NSCellFlags2">134217728</int>
+                                                                                                       <string key="NSContents">Force Sync Now</string>
+                                                                                                       <reference key="NSSupport" ref="1055465101"/>
+                                                                                                       <string key="NSCellIdentifier">_NS:9</string>
+                                                                                                       <reference key="NSControlView" ref="1053273967"/>
+                                                                                                       <int key="NSButtonFlags">-2038153216</int>
+                                                                                                       <int key="NSButtonFlags2">164</int>
+                                                                                                       <string key="NSAlternateContents"/>
+                                                                                                       <string key="NSKeyEquivalent"/>
+                                                                                                       <int key="NSPeriodicDelay">400</int>
+                                                                                                       <int key="NSPeriodicInterval">75</int>
+                                                                                               </object>
+                                                                                               <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+                                                                                       </object>
+                                                                                       <object class="NSButton" id="347352225">
+                                                                                               <reference key="NSNextResponder" ref="933472960"/>
+                                                                                               <int key="NSvFlags">268</int>
+                                                                                               <string key="NSFrame">{{249, 210}, {156, 19}}</string>
+                                                                                               <reference key="NSSuperview" ref="933472960"/>
+                                                                                               <reference key="NSWindow"/>
+                                                                                               <reference key="NSNextKeyView" ref="874894253"/>
+                                                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                                                               <bool key="NSEnabled">YES</bool>
+                                                                                               <object class="NSButtonCell" key="NSCell" id="315128676">
+                                                                                                       <int key="NSCellFlags">-2080374784</int>
+                                                                                                       <int key="NSCellFlags2">134217728</int>
+                                                                                                       <string key="NSContents">Reset Circle to Empty</string>
+                                                                                                       <reference key="NSSupport" ref="1055465101"/>
+                                                                                                       <string key="NSCellIdentifier">_NS:9</string>
+                                                                                                       <reference key="NSControlView" ref="347352225"/>
+                                                                                                       <int key="NSButtonFlags">-2038153216</int>
+                                                                                                       <int key="NSButtonFlags2">164</int>
+                                                                                                       <string key="NSAlternateContents"/>
+                                                                                                       <string key="NSKeyEquivalent"/>
+                                                                                                       <int key="NSPeriodicDelay">400</int>
+                                                                                                       <int key="NSPeriodicInterval">75</int>
+                                                                                               </object>
+                                                                                               <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+                                                                                       </object>
+                                                                                       <object class="NSButton" id="874894253">
+                                                                                               <reference key="NSNextResponder" ref="933472960"/>
+                                                                                               <int key="NSvFlags">268</int>
+                                                                                               <string key="NSFrame">{{249, 184}, {156, 19}}</string>
+                                                                                               <reference key="NSSuperview" ref="933472960"/>
+                                                                                               <reference key="NSWindow"/>
+                                                                                               <reference key="NSNextKeyView" ref="928329068"/>
+                                                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                                                               <bool key="NSEnabled">YES</bool>
+                                                                                               <object class="NSButtonCell" key="NSCell" id="956278817">
+                                                                                                       <int key="NSCellFlags">-1543503872</int>
+                                                                                                       <int key="NSCellFlags2">134217728</int>
+                                                                                                       <string key="NSContents">Dump KVS</string>
+                                                                                                       <reference key="NSSupport" ref="1055465101"/>
+                                                                                                       <string key="NSCellIdentifier">_NS:9</string>
+                                                                                                       <reference key="NSControlView" ref="874894253"/>
+                                                                                                       <int key="NSButtonFlags">-2038153216</int>
+                                                                                                       <int key="NSButtonFlags2">164</int>
+                                                                                                       <string key="NSAlternateContents"/>
+                                                                                                       <string key="NSKeyEquivalent"/>
+                                                                                                       <int key="NSPeriodicDelay">400</int>
+                                                                                                       <int key="NSPeriodicInterval">75</int>
+                                                                                               </object>
+                                                                                               <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+                                                                                       </object>
+                                                                                       <object class="NSButton" id="914091846">
+                                                                                               <reference key="NSNextResponder" ref="933472960"/>
+                                                                                               <int key="NSvFlags">268</int>
+                                                                                               <string key="NSFrame">{{249, 236}, {156, 19}}</string>
+                                                                                               <reference key="NSSuperview" ref="933472960"/>
+                                                                                               <reference key="NSWindow"/>
+                                                                                               <reference key="NSNextKeyView" ref="347352225"/>
+                                                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                                                               <bool key="NSEnabled">YES</bool>
+                                                                                               <object class="NSButtonCell" key="NSCell" id="607450495">
+                                                                                                       <int key="NSCellFlags">-1543503872</int>
+                                                                                                       <int key="NSCellFlags2">134217728</int>
+                                                                                                       <string key="NSContents">Clear Keychain</string>
+                                                                                                       <reference key="NSSupport" ref="1055465101"/>
+                                                                                                       <string key="NSCellIdentifier">_NS:9</string>
+                                                                                                       <reference key="NSControlView" ref="914091846"/>
+                                                                                                       <int key="NSButtonFlags">-2038153216</int>
+                                                                                                       <int key="NSButtonFlags2">164</int>
+                                                                                                       <string key="NSAlternateContents"/>
+                                                                                                       <string key="NSKeyEquivalent"/>
+                                                                                                       <int key="NSPeriodicDelay">400</int>
+                                                                                                       <int key="NSPeriodicInterval">75</int>
+                                                                                               </object>
+                                                                                               <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+                                                                                       </object>
+                                                                                       <object class="NSButton" id="786023451">
+                                                                                               <reference key="NSNextResponder" ref="933472960"/>
+                                                                                               <int key="NSvFlags">268</int>
+                                                                                               <string key="NSFrame">{{1, 115}, {144, 18}}</string>
+                                                                                               <reference key="NSSuperview" ref="933472960"/>
+                                                                                               <reference key="NSWindow"/>
+                                                                                               <reference key="NSNextKeyView" ref="1053273967"/>
+                                                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                                                               <bool key="NSEnabled">YES</bool>
+                                                                                               <object class="NSButtonCell" key="NSCell" id="502128501">
+                                                                                                       <int key="NSCellFlags">67108864</int>
+                                                                                                       <int key="NSCellFlags2">268435456</int>
+                                                                                                       <string key="NSContents">Enable Unsafe Stuff</string>
+                                                                                                       <reference key="NSSupport" ref="598757250"/>
+                                                                                                       <string key="NSCellIdentifier">_NS:9</string>
+                                                                                                       <reference key="NSControlView" ref="786023451"/>
+                                                                                                       <int key="NSButtonFlags">1211912448</int>
+                                                                                                       <int key="NSButtonFlags2">2</int>
+                                                                                                       <reference key="NSNormalImage" ref="549337529"/>
+                                                                                                       <reference key="NSAlternateImage" ref="466233108"/>
+                                                                                                       <string key="NSAlternateContents"/>
+                                                                                                       <string key="NSKeyEquivalent"/>
+                                                                                                       <int key="NSPeriodicDelay">200</int>
+                                                                                                       <int key="NSPeriodicInterval">25</int>
+                                                                                               </object>
+                                                                                               <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+                                                                                       </object>
+                                                                                       <object class="NSProgressIndicator" id="935864981">
+                                                                                               <reference key="NSNextResponder" ref="933472960"/>
+                                                                                               <int key="NSvFlags">268</int>
+                                                                                               <string key="NSFrame">{{373, 365}, {32, 32}}</string>
+                                                                                               <reference key="NSSuperview" ref="933472960"/>
+                                                                                               <reference key="NSWindow"/>
+                                                                                               <reference key="NSNextKeyView" ref="141416926"/>
+                                                                                               <string key="NSReuseIdentifierKey">_NS:945</string>
+                                                                                               <int key="NSpiFlags">20490</int>
+                                                                                               <double key="NSMaxValue">100</double>
+                                                                                       </object>
+                                                                                       <object class="NSTextField" id="760674507">
+                                                                                               <reference key="NSNextResponder" ref="933472960"/>
+                                                                                               <int key="NSvFlags">268</int>
+                                                                                               <string key="NSFrame">{{3, 17}, {405, 17}}</string>
+                                                                                               <reference key="NSSuperview" ref="933472960"/>
+                                                                                               <reference key="NSWindow"/>
+                                                                                               <reference key="NSNextKeyView"/>
+                                                                                               <string key="NSReuseIdentifierKey">_NS:1535</string>
+                                                                                               <bool key="NSEnabled">YES</bool>
+                                                                                               <object class="NSTextFieldCell" key="NSCell" id="82712399">
+                                                                                                       <int key="NSCellFlags">68157504</int>
+                                                                                                       <int key="NSCellFlags2">272630784</int>
+                                                                                                       <string key="NSContents"/>
+                                                                                                       <reference key="NSSupport" ref="598757250"/>
+                                                                                                       <string key="NSPlaceholderString">Idle</string>
+                                                                                                       <string key="NSCellIdentifier">_NS:1535</string>
+                                                                                                       <reference key="NSControlView" ref="760674507"/>
+                                                                                                       <reference key="NSBackgroundColor" ref="926294313"/>
+                                                                                                       <reference key="NSTextColor" ref="842671716"/>
+                                                                                               </object>
+                                                                                               <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+                                                                                       </object>
+                                                                                       <object class="NSTextField" id="141416926">
+                                                                                               <reference key="NSNextResponder" ref="933472960"/>
+                                                                                               <int key="NSvFlags">268</int>
+                                                                                               <string key="NSFrame">{{15, 282}, {401, 62}}</string>
+                                                                                               <reference key="NSSuperview" ref="933472960"/>
+                                                                                               <reference key="NSWindow"/>
+                                                                                               <reference key="NSNextKeyView" ref="1003098491"/>
+                                                                                               <string key="NSReuseIdentifierKey">_NS:1535</string>
+                                                                                               <bool key="NSEnabled">YES</bool>
+                                                                                               <object class="NSTextFieldCell" key="NSCell" id="917984923">
+                                                                                                       <int key="NSCellFlags">68157504</int>
+                                                                                                       <int key="NSCellFlags2">272630784</int>
+                                                                                                       <string key="NSContents">None of this pane does anything, try 🌀 or 🔑</string>
+                                                                                                       <object class="NSFont" key="NSSupport">
+                                                                                                               <string key="NSName">LucidaGrande</string>
+                                                                                                               <double key="NSSize">18</double>
+                                                                                                               <int key="NSfFlags">16</int>
+                                                                                                       </object>
+                                                                                                       <string key="NSCellIdentifier">_NS:1535</string>
+                                                                                                       <reference key="NSControlView" ref="141416926"/>
+                                                                                                       <reference key="NSBackgroundColor" ref="926294313"/>
+                                                                                                       <object class="NSColor" key="NSTextColor">
+                                                                                                               <int key="NSColorSpace">1</int>
+                                                                                                               <bytes key="NSRGB">MSAwIDAAA</bytes>
+                                                                                                       </object>
+                                                                                               </object>
+                                                                                               <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+                                                                                       </object>
+                                                                               </array>
+                                                                               <string key="NSFrame">{{32, 7}, {422, 414}}</string>
+                                                                               <reference key="NSSuperview" ref="916837096"/>
+                                                                               <reference key="NSWindow"/>
+                                                                               <reference key="NSNextKeyView" ref="935864981"/>
+                                                                       </object>
+                                                                       <string key="NSLabel">🔧</string>
+                                                                       <reference key="NSColor" ref="926294313"/>
+                                                                       <reference key="NSTabView" ref="916837096"/>
+                                                               </object>
+                                                       </array>
+                                                       <reference key="NSSelectedTabViewItem" ref="133282229"/>
+                                                       <reference key="NSFont" ref="598757250"/>
+                                                       <int key="NSTvFlags">1</int>
+                                                       <bool key="NSAllowTruncatedLabels">YES</bool>
+                                                       <bool key="NSDrawsBackground">YES</bool>
+                                                       <array class="NSMutableArray" key="NSSubviews">
+                                                               <reference ref="933472960"/>
+                                                       </array>
+                                               </object>
+                                       </array>
+                                       <string key="NSFrameSize">{472, 415}</string>
+                                       <reference key="NSSuperview"/>
+                                       <reference key="NSWindow"/>
+                                       <reference key="NSNextKeyView" ref="916837096"/>
+                               </object>
+                               <string key="NSScreenRect">{{0, 0}, {1440, 878}}</string>
+                               <string key="NSMaxSize">{10000000000000, 10000000000000}</string>
+                               <bool key="NSWindowIsRestorable">YES</bool>
+                       </object>
+                       <object class="NSCustomObject" id="976324537">
+                               <string key="NSClassName">KDAppDelegate</string>
+                       </object>
+                       <object class="NSCustomObject" id="755631768">
+                               <string key="NSClassName">NSFontManager</string>
+                       </object>
+               </array>
+               <object class="IBObjectContainer" key="IBDocument.Objects">
+                       <array class="NSMutableArray" key="connectionRecords">
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">terminate:</string>
+                                               <reference key="source" ref="1050"/>
+                                               <reference key="destination" ref="632727374"/>
+                                       </object>
+                                       <int key="connectionID">449</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">orderFrontStandardAboutPanel:</string>
+                                               <reference key="source" ref="1021"/>
+                                               <reference key="destination" ref="238522557"/>
+                                       </object>
+                                       <int key="connectionID">142</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBOutletConnection" key="connection">
+                                               <string key="label">delegate</string>
+                                               <reference key="source" ref="1021"/>
+                                               <reference key="destination" ref="976324537"/>
+                                       </object>
+                                       <int key="connectionID">495</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">performMiniaturize:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="1011231497"/>
+                                       </object>
+                                       <int key="connectionID">37</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">arrangeInFront:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="625202149"/>
+                                       </object>
+                                       <int key="connectionID">39</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">print:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="49223823"/>
+                                       </object>
+                                       <int key="connectionID">86</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">runPageLayout:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="294629803"/>
+                                       </object>
+                                       <int key="connectionID">87</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">clearRecentDocuments:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="759406840"/>
+                                       </object>
+                                       <int key="connectionID">127</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">performClose:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="776162233"/>
+                                       </object>
+                                       <int key="connectionID">193</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">toggleContinuousSpellChecking:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="948374510"/>
+                                       </object>
+                                       <int key="connectionID">222</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">undo:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="1058277027"/>
+                                       </object>
+                                       <int key="connectionID">223</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">copy:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="860595796"/>
+                                       </object>
+                                       <int key="connectionID">224</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">checkSpelling:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="96193923"/>
+                                       </object>
+                                       <int key="connectionID">225</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">paste:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="29853731"/>
+                                       </object>
+                                       <int key="connectionID">226</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">stopSpeaking:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="680220178"/>
+                                       </object>
+                                       <int key="connectionID">227</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">cut:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="296257095"/>
+                                       </object>
+                                       <int key="connectionID">228</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">showGuessPanel:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="679648819"/>
+                                       </object>
+                                       <int key="connectionID">230</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">redo:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="790794224"/>
+                                       </object>
+                                       <int key="connectionID">231</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">selectAll:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="583158037"/>
+                                       </object>
+                                       <int key="connectionID">232</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">startSpeaking:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="731782645"/>
+                                       </object>
+                                       <int key="connectionID">233</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">delete:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="437104165"/>
+                                       </object>
+                                       <int key="connectionID">235</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">performZoom:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="575023229"/>
+                                       </object>
+                                       <int key="connectionID">240</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">performFindPanelAction:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="447796847"/>
+                                       </object>
+                                       <int key="connectionID">241</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">centerSelectionInVisibleArea:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="88285865"/>
+                                       </object>
+                                       <int key="connectionID">245</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">toggleGrammarChecking:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="967646866"/>
+                                       </object>
+                                       <int key="connectionID">347</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">toggleSmartInsertDelete:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="605118523"/>
+                                       </object>
+                                       <int key="connectionID">355</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">toggleAutomaticQuoteSubstitution:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="197661976"/>
+                                       </object>
+                                       <int key="connectionID">356</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">toggleAutomaticLinkDetection:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="708854459"/>
+                                       </object>
+                                       <int key="connectionID">357</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">saveDocument:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="1023925487"/>
+                                       </object>
+                                       <int key="connectionID">362</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">revertDocumentToSaved:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="579971712"/>
+                                       </object>
+                                       <int key="connectionID">364</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">runToolbarCustomizationPalette:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="237841660"/>
+                                       </object>
+                                       <int key="connectionID">365</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">toggleToolbarShown:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="102151532"/>
+                                       </object>
+                                       <int key="connectionID">366</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">hide:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="755159360"/>
+                                       </object>
+                                       <int key="connectionID">367</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">hideOtherApplications:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="342932134"/>
+                                       </object>
+                                       <int key="connectionID">368</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">unhideAllApplications:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="908899353"/>
+                                       </object>
+                                       <int key="connectionID">370</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">newDocument:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="705341025"/>
+                                       </object>
+                                       <int key="connectionID">373</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">openDocument:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="722745758"/>
+                                       </object>
+                                       <int key="connectionID">374</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">raiseBaseline:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="941806246"/>
+                                       </object>
+                                       <int key="connectionID">426</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">lowerBaseline:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="1045724900"/>
+                                       </object>
+                                       <int key="connectionID">427</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">copyFont:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="596732606"/>
+                                       </object>
+                                       <int key="connectionID">428</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">subscript:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="1037576581"/>
+                                       </object>
+                                       <int key="connectionID">429</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">superscript:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="644725453"/>
+                                       </object>
+                                       <int key="connectionID">430</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">tightenKerning:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="677519740"/>
+                                       </object>
+                                       <int key="connectionID">431</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">underline:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="330926929"/>
+                                       </object>
+                                       <int key="connectionID">432</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">orderFrontColorPanel:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="1012600125"/>
+                                       </object>
+                                       <int key="connectionID">433</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">useAllLigatures:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="663508465"/>
+                                       </object>
+                                       <int key="connectionID">434</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">loosenKerning:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="238351151"/>
+                                       </object>
+                                       <int key="connectionID">435</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">pasteFont:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="393423671"/>
+                                       </object>
+                                       <int key="connectionID">436</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">unscript:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="257962622"/>
+                                       </object>
+                                       <int key="connectionID">437</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">useStandardKerning:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="252969304"/>
+                                       </object>
+                                       <int key="connectionID">438</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">useStandardLigatures:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="706297211"/>
+                                       </object>
+                                       <int key="connectionID">439</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">turnOffLigatures:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="568384683"/>
+                                       </object>
+                                       <int key="connectionID">440</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">turnOffKerning:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="766922938"/>
+                                       </object>
+                                       <int key="connectionID">441</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">toggleAutomaticSpellingCorrection:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="795346622"/>
+                                       </object>
+                                       <int key="connectionID">456</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">orderFrontSubstitutionsPanel:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="65139061"/>
+                                       </object>
+                                       <int key="connectionID">458</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">toggleAutomaticDashSubstitution:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="672708820"/>
+                                       </object>
+                                       <int key="connectionID">461</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">toggleAutomaticTextReplacement:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="537092702"/>
+                                       </object>
+                                       <int key="connectionID">463</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">uppercaseWord:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="1060694897"/>
+                                       </object>
+                                       <int key="connectionID">464</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">capitalizeWord:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="56570060"/>
+                                       </object>
+                                       <int key="connectionID">467</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">lowercaseWord:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="879586729"/>
+                                       </object>
+                                       <int key="connectionID">468</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">pasteAsPlainText:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="82994268"/>
+                                       </object>
+                                       <int key="connectionID">486</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">performFindPanelAction:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="326711663"/>
+                                       </object>
+                                       <int key="connectionID">487</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">performFindPanelAction:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="270902937"/>
+                                       </object>
+                                       <int key="connectionID">488</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">performFindPanelAction:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="159080638"/>
+                                       </object>
+                                       <int key="connectionID">489</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">showHelp:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="105068016"/>
+                                       </object>
+                                       <int key="connectionID">493</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">alignCenter:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="630155264"/>
+                                       </object>
+                                       <int key="connectionID">518</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">pasteRuler:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="883618387"/>
+                                       </object>
+                                       <int key="connectionID">519</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">toggleRuler:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="644046920"/>
+                                       </object>
+                                       <int key="connectionID">520</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">alignRight:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="512868991"/>
+                                       </object>
+                                       <int key="connectionID">521</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">copyRuler:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="231811626"/>
+                                       </object>
+                                       <int key="connectionID">522</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">alignJustified:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="945678886"/>
+                                       </object>
+                                       <int key="connectionID">523</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">alignLeft:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="875092757"/>
+                                       </object>
+                                       <int key="connectionID">524</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">makeBaseWritingDirectionNatural:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="551969625"/>
+                                       </object>
+                                       <int key="connectionID">525</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">makeBaseWritingDirectionLeftToRight:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="249532473"/>
+                                       </object>
+                                       <int key="connectionID">526</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">makeBaseWritingDirectionRightToLeft:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="607364498"/>
+                                       </object>
+                                       <int key="connectionID">527</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">makeTextWritingDirectionNatural:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="380031999"/>
+                                       </object>
+                                       <int key="connectionID">528</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">makeTextWritingDirectionLeftToRight:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="825984362"/>
+                                       </object>
+                                       <int key="connectionID">529</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">makeTextWritingDirectionRightToLeft:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="560145579"/>
+                                       </object>
+                                       <int key="connectionID">530</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">performFindPanelAction:</string>
+                                               <reference key="source" ref="1014"/>
+                                               <reference key="destination" ref="738670835"/>
+                                       </object>
+                                       <int key="connectionID">535</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">addFontTrait:</string>
+                                               <reference key="source" ref="755631768"/>
+                                               <reference key="destination" ref="305399458"/>
+                                       </object>
+                                       <int key="connectionID">421</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">addFontTrait:</string>
+                                               <reference key="source" ref="755631768"/>
+                                               <reference key="destination" ref="814362025"/>
+                                       </object>
+                                       <int key="connectionID">422</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">modifyFont:</string>
+                                               <reference key="source" ref="755631768"/>
+                                               <reference key="destination" ref="885547335"/>
+                                       </object>
+                                       <int key="connectionID">423</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">orderFrontFontPanel:</string>
+                                               <reference key="source" ref="755631768"/>
+                                               <reference key="destination" ref="159677712"/>
+                                       </object>
+                                       <int key="connectionID">424</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">modifyFont:</string>
+                                               <reference key="source" ref="755631768"/>
+                                               <reference key="destination" ref="158063935"/>
+                                       </object>
+                                       <int key="connectionID">425</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBOutletConnection" key="connection">
+                                               <string key="label">window</string>
+                                               <reference key="source" ref="976324537"/>
+                                               <reference key="destination" ref="972006081"/>
+                                       </object>
+                                       <int key="connectionID">532</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBOutletConnection" key="connection">
+                                               <string key="label">itemTableTitle</string>
+                                               <reference key="source" ref="976324537"/>
+                                               <reference key="destination" ref="974410057"/>
+                                       </object>
+                                       <int key="connectionID">834</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBOutletConnection" key="connection">
+                                               <string key="label">itemTable</string>
+                                               <reference key="source" ref="976324537"/>
+                                               <reference key="destination" ref="836264498"/>
+                                       </object>
+                                       <int key="connectionID">835</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBOutletConnection" key="connection">
+                                               <string key="label">circleStatusCell</string>
+                                               <reference key="source" ref="976324537"/>
+                                               <reference key="destination" ref="718406896"/>
+                                       </object>
+                                       <int key="connectionID">836</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBOutletConnection" key="connection">
+                                               <string key="label">peerCountCell</string>
+                                               <reference key="source" ref="976324537"/>
+                                               <reference key="destination" ref="353430769"/>
+                                       </object>
+                                       <int key="connectionID">837</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBOutletConnection" key="connection">
+                                               <string key="label">peerTextList</string>
+                                               <reference key="source" ref="976324537"/>
+                                               <reference key="destination" ref="445558087"/>
+                                       </object>
+                                       <int key="connectionID">838</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBOutletConnection" key="connection">
+                                               <string key="label">applicantCountCell</string>
+                                               <reference key="source" ref="976324537"/>
+                                               <reference key="destination" ref="255632910"/>
+                                       </object>
+                                       <int key="connectionID">839</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBOutletConnection" key="connection">
+                                               <string key="label">applicantTextList</string>
+                                               <reference key="source" ref="976324537"/>
+                                               <reference key="destination" ref="97048596"/>
+                                       </object>
+                                       <int key="connectionID">840</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBOutletConnection" key="connection">
+                                               <string key="label">enableKeychainSyncing</string>
+                                               <reference key="source" ref="976324537"/>
+                                               <reference key="destination" ref="1048394879"/>
+                                       </object>
+                                       <int key="connectionID">841</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">enableKeychainSyncingClicked:</string>
+                                               <reference key="source" ref="976324537"/>
+                                               <reference key="destination" ref="1048394879"/>
+                                       </object>
+                                       <int key="connectionID">843</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBOutletConnection" key="connection">
+                                               <string key="label">syncSpinner</string>
+                                               <reference key="source" ref="976324537"/>
+                                               <reference key="destination" ref="1020307009"/>
+                                       </object>
+                                       <int key="connectionID">844</int>
+                               </object>
+                       </array>
+                       <object class="IBMutableOrderedSet" key="objectRecords">
+                               <array key="orderedObjects">
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">0</int>
+                                               <array key="object" id="0"/>
+                                               <reference key="children" ref="1048"/>
+                                               <nil key="parent"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-2</int>
+                                               <reference key="object" ref="1021"/>
+                                               <reference key="parent" ref="0"/>
+                                               <string key="objectName">File's Owner</string>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-1</int>
+                                               <reference key="object" ref="1014"/>
+                                               <reference key="parent" ref="0"/>
+                                               <string key="objectName">First Responder</string>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-3</int>
+                                               <reference key="object" ref="1050"/>
+                                               <reference key="parent" ref="0"/>
+                                               <string key="objectName">Application</string>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">29</int>
+                                               <reference key="object" ref="649796088"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="713487014"/>
+                                                       <reference ref="694149608"/>
+                                                       <reference ref="952259628"/>
+                                                       <reference ref="379814623"/>
+                                                       <reference ref="586577488"/>
+                                                       <reference ref="302598603"/>
+                                                       <reference ref="448692316"/>
+                                               </array>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">19</int>
+                                               <reference key="object" ref="713487014"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="835318025"/>
+                                               </array>
+                                               <reference key="parent" ref="649796088"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">56</int>
+                                               <reference key="object" ref="694149608"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="110575045"/>
+                                               </array>
+                                               <reference key="parent" ref="649796088"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">217</int>
+                                               <reference key="object" ref="952259628"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="789758025"/>
+                                               </array>
+                                               <reference key="parent" ref="649796088"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">83</int>
+                                               <reference key="object" ref="379814623"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="720053764"/>
+                                               </array>
+                                               <reference key="parent" ref="649796088"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">81</int>
+                                               <reference key="object" ref="720053764"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="1023925487"/>
+                                                       <reference ref="49223823"/>
+                                                       <reference ref="722745758"/>
+                                                       <reference ref="705341025"/>
+                                                       <reference ref="1025936716"/>
+                                                       <reference ref="294629803"/>
+                                                       <reference ref="776162233"/>
+                                                       <reference ref="425164168"/>
+                                                       <reference ref="579971712"/>
+                                                       <reference ref="1010469920"/>
+                                               </array>
+                                               <reference key="parent" ref="379814623"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">75</int>
+                                               <reference key="object" ref="1023925487"/>
+                                               <reference key="parent" ref="720053764"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">78</int>
+                                               <reference key="object" ref="49223823"/>
+                                               <reference key="parent" ref="720053764"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">72</int>
+                                               <reference key="object" ref="722745758"/>
+                                               <reference key="parent" ref="720053764"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">82</int>
+                                               <reference key="object" ref="705341025"/>
+                                               <reference key="parent" ref="720053764"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">124</int>
+                                               <reference key="object" ref="1025936716"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="1065607017"/>
+                                               </array>
+                                               <reference key="parent" ref="720053764"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">77</int>
+                                               <reference key="object" ref="294629803"/>
+                                               <reference key="parent" ref="720053764"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">73</int>
+                                               <reference key="object" ref="776162233"/>
+                                               <reference key="parent" ref="720053764"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">79</int>
+                                               <reference key="object" ref="425164168"/>
+                                               <reference key="parent" ref="720053764"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">112</int>
+                                               <reference key="object" ref="579971712"/>
+                                               <reference key="parent" ref="720053764"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">74</int>
+                                               <reference key="object" ref="1010469920"/>
+                                               <reference key="parent" ref="720053764"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">125</int>
+                                               <reference key="object" ref="1065607017"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="759406840"/>
+                                               </array>
+                                               <reference key="parent" ref="1025936716"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">126</int>
+                                               <reference key="object" ref="759406840"/>
+                                               <reference key="parent" ref="1065607017"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">205</int>
+                                               <reference key="object" ref="789758025"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="437104165"/>
+                                                       <reference ref="583158037"/>
+                                                       <reference ref="1058277027"/>
+                                                       <reference ref="212016141"/>
+                                                       <reference ref="296257095"/>
+                                                       <reference ref="29853731"/>
+                                                       <reference ref="860595796"/>
+                                                       <reference ref="1040322652"/>
+                                                       <reference ref="790794224"/>
+                                                       <reference ref="892235320"/>
+                                                       <reference ref="972420730"/>
+                                                       <reference ref="676164635"/>
+                                                       <reference ref="507821607"/>
+                                                       <reference ref="288088188"/>
+                                                       <reference ref="82994268"/>
+                                               </array>
+                                               <reference key="parent" ref="952259628"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">202</int>
+                                               <reference key="object" ref="437104165"/>
+                                               <reference key="parent" ref="789758025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">198</int>
+                                               <reference key="object" ref="583158037"/>
+                                               <reference key="parent" ref="789758025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">207</int>
+                                               <reference key="object" ref="1058277027"/>
+                                               <reference key="parent" ref="789758025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">214</int>
+                                               <reference key="object" ref="212016141"/>
+                                               <reference key="parent" ref="789758025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">199</int>
+                                               <reference key="object" ref="296257095"/>
+                                               <reference key="parent" ref="789758025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">203</int>
+                                               <reference key="object" ref="29853731"/>
+                                               <reference key="parent" ref="789758025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">197</int>
+                                               <reference key="object" ref="860595796"/>
+                                               <reference key="parent" ref="789758025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">206</int>
+                                               <reference key="object" ref="1040322652"/>
+                                               <reference key="parent" ref="789758025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">215</int>
+                                               <reference key="object" ref="790794224"/>
+                                               <reference key="parent" ref="789758025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">218</int>
+                                               <reference key="object" ref="892235320"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="963351320"/>
+                                               </array>
+                                               <reference key="parent" ref="789758025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">216</int>
+                                               <reference key="object" ref="972420730"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="769623530"/>
+                                               </array>
+                                               <reference key="parent" ref="789758025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">200</int>
+                                               <reference key="object" ref="769623530"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="948374510"/>
+                                                       <reference ref="96193923"/>
+                                                       <reference ref="679648819"/>
+                                                       <reference ref="967646866"/>
+                                                       <reference ref="859480356"/>
+                                                       <reference ref="795346622"/>
+                                               </array>
+                                               <reference key="parent" ref="972420730"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">219</int>
+                                               <reference key="object" ref="948374510"/>
+                                               <reference key="parent" ref="769623530"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">201</int>
+                                               <reference key="object" ref="96193923"/>
+                                               <reference key="parent" ref="769623530"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">204</int>
+                                               <reference key="object" ref="679648819"/>
+                                               <reference key="parent" ref="769623530"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">220</int>
+                                               <reference key="object" ref="963351320"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="270902937"/>
+                                                       <reference ref="88285865"/>
+                                                       <reference ref="159080638"/>
+                                                       <reference ref="326711663"/>
+                                                       <reference ref="447796847"/>
+                                                       <reference ref="738670835"/>
+                                               </array>
+                                               <reference key="parent" ref="892235320"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">213</int>
+                                               <reference key="object" ref="270902937"/>
+                                               <reference key="parent" ref="963351320"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">210</int>
+                                               <reference key="object" ref="88285865"/>
+                                               <reference key="parent" ref="963351320"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">221</int>
+                                               <reference key="object" ref="159080638"/>
+                                               <reference key="parent" ref="963351320"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">208</int>
+                                               <reference key="object" ref="326711663"/>
+                                               <reference key="parent" ref="963351320"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">209</int>
+                                               <reference key="object" ref="447796847"/>
+                                               <reference key="parent" ref="963351320"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">57</int>
+                                               <reference key="object" ref="110575045"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="238522557"/>
+                                                       <reference ref="755159360"/>
+                                                       <reference ref="908899353"/>
+                                                       <reference ref="632727374"/>
+                                                       <reference ref="646227648"/>
+                                                       <reference ref="609285721"/>
+                                                       <reference ref="481834944"/>
+                                                       <reference ref="304266470"/>
+                                                       <reference ref="1046388886"/>
+                                                       <reference ref="1056857174"/>
+                                                       <reference ref="342932134"/>
+                                               </array>
+                                               <reference key="parent" ref="694149608"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">58</int>
+                                               <reference key="object" ref="238522557"/>
+                                               <reference key="parent" ref="110575045"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">134</int>
+                                               <reference key="object" ref="755159360"/>
+                                               <reference key="parent" ref="110575045"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">150</int>
+                                               <reference key="object" ref="908899353"/>
+                                               <reference key="parent" ref="110575045"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">136</int>
+                                               <reference key="object" ref="632727374"/>
+                                               <reference key="parent" ref="110575045"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">144</int>
+                                               <reference key="object" ref="646227648"/>
+                                               <reference key="parent" ref="110575045"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">129</int>
+                                               <reference key="object" ref="609285721"/>
+                                               <reference key="parent" ref="110575045"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">143</int>
+                                               <reference key="object" ref="481834944"/>
+                                               <reference key="parent" ref="110575045"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">236</int>
+                                               <reference key="object" ref="304266470"/>
+                                               <reference key="parent" ref="110575045"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">131</int>
+                                               <reference key="object" ref="1046388886"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="752062318"/>
+                                               </array>
+                                               <reference key="parent" ref="110575045"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">149</int>
+                                               <reference key="object" ref="1056857174"/>
+                                               <reference key="parent" ref="110575045"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">145</int>
+                                               <reference key="object" ref="342932134"/>
+                                               <reference key="parent" ref="110575045"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">130</int>
+                                               <reference key="object" ref="752062318"/>
+                                               <reference key="parent" ref="1046388886"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">24</int>
+                                               <reference key="object" ref="835318025"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="299356726"/>
+                                                       <reference ref="625202149"/>
+                                                       <reference ref="575023229"/>
+                                                       <reference ref="1011231497"/>
+                                               </array>
+                                               <reference key="parent" ref="713487014"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">92</int>
+                                               <reference key="object" ref="299356726"/>
+                                               <reference key="parent" ref="835318025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">5</int>
+                                               <reference key="object" ref="625202149"/>
+                                               <reference key="parent" ref="835318025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">239</int>
+                                               <reference key="object" ref="575023229"/>
+                                               <reference key="parent" ref="835318025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">23</int>
+                                               <reference key="object" ref="1011231497"/>
+                                               <reference key="parent" ref="835318025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">295</int>
+                                               <reference key="object" ref="586577488"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="466310130"/>
+                                               </array>
+                                               <reference key="parent" ref="649796088"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">296</int>
+                                               <reference key="object" ref="466310130"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="102151532"/>
+                                                       <reference ref="237841660"/>
+                                               </array>
+                                               <reference key="parent" ref="586577488"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">297</int>
+                                               <reference key="object" ref="102151532"/>
+                                               <reference key="parent" ref="466310130"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">298</int>
+                                               <reference key="object" ref="237841660"/>
+                                               <reference key="parent" ref="466310130"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">211</int>
+                                               <reference key="object" ref="676164635"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="785027613"/>
+                                               </array>
+                                               <reference key="parent" ref="789758025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">212</int>
+                                               <reference key="object" ref="785027613"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="680220178"/>
+                                                       <reference ref="731782645"/>
+                                               </array>
+                                               <reference key="parent" ref="676164635"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">195</int>
+                                               <reference key="object" ref="680220178"/>
+                                               <reference key="parent" ref="785027613"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">196</int>
+                                               <reference key="object" ref="731782645"/>
+                                               <reference key="parent" ref="785027613"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">346</int>
+                                               <reference key="object" ref="967646866"/>
+                                               <reference key="parent" ref="769623530"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">348</int>
+                                               <reference key="object" ref="507821607"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="698887838"/>
+                                               </array>
+                                               <reference key="parent" ref="789758025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">349</int>
+                                               <reference key="object" ref="698887838"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="605118523"/>
+                                                       <reference ref="197661976"/>
+                                                       <reference ref="708854459"/>
+                                                       <reference ref="65139061"/>
+                                                       <reference ref="19036812"/>
+                                                       <reference ref="672708820"/>
+                                                       <reference ref="537092702"/>
+                                               </array>
+                                               <reference key="parent" ref="507821607"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">350</int>
+                                               <reference key="object" ref="605118523"/>
+                                               <reference key="parent" ref="698887838"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">351</int>
+                                               <reference key="object" ref="197661976"/>
+                                               <reference key="parent" ref="698887838"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">354</int>
+                                               <reference key="object" ref="708854459"/>
+                                               <reference key="parent" ref="698887838"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">371</int>
+                                               <reference key="object" ref="972006081"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="439893737"/>
+                                               </array>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">372</int>
+                                               <reference key="object" ref="439893737"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <object class="IBNSLayoutConstraint" id="192567985">
+                                                               <reference key="firstItem" ref="916837096"/>
+                                                               <int key="firstAttribute">6</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="439893737"/>
+                                                               <int key="secondAttribute">6</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">0.0</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="439893737"/>
+                                                               <int key="scoringType">8</int>
+                                                               <float key="scoringTypeFloat">29</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="439273158">
+                                                               <reference key="firstItem" ref="916837096"/>
+                                                               <int key="firstAttribute">5</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="439893737"/>
+                                                               <int key="secondAttribute">5</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBNSLayoutSymbolicConstant" key="constant">
+                                                                       <double key="value">20</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="439893737"/>
+                                                               <int key="scoringType">8</int>
+                                                               <float key="scoringTypeFloat">29</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="811760524">
+                                                               <reference key="firstItem" ref="916837096"/>
+                                                               <int key="firstAttribute">3</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="439893737"/>
+                                                               <int key="secondAttribute">3</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">-3</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="439893737"/>
+                                                               <int key="scoringType">3</int>
+                                                               <float key="scoringTypeFloat">9</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="378483925">
+                                                               <reference key="firstItem" ref="916837096"/>
+                                                               <int key="firstAttribute">10</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="439893737"/>
+                                                               <int key="secondAttribute">10</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">0.0</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="439893737"/>
+                                                               <int key="scoringType">5</int>
+                                                               <float key="scoringTypeFloat">22</float>
+                                                               <int key="contentType">2</int>
+                                                       </object>
+                                                       <reference ref="916837096"/>
+                                               </array>
+                                               <reference key="parent" ref="972006081"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">375</int>
+                                               <reference key="object" ref="302598603"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="941447902"/>
+                                               </array>
+                                               <reference key="parent" ref="649796088"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">376</int>
+                                               <reference key="object" ref="941447902"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="792887677"/>
+                                                       <reference ref="215659978"/>
+                                               </array>
+                                               <reference key="parent" ref="302598603"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">377</int>
+                                               <reference key="object" ref="792887677"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="786677654"/>
+                                               </array>
+                                               <reference key="parent" ref="941447902"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">388</int>
+                                               <reference key="object" ref="786677654"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="159677712"/>
+                                                       <reference ref="305399458"/>
+                                                       <reference ref="814362025"/>
+                                                       <reference ref="330926929"/>
+                                                       <reference ref="533507878"/>
+                                                       <reference ref="158063935"/>
+                                                       <reference ref="885547335"/>
+                                                       <reference ref="901062459"/>
+                                                       <reference ref="767671776"/>
+                                                       <reference ref="691570813"/>
+                                                       <reference ref="769124883"/>
+                                                       <reference ref="739652853"/>
+                                                       <reference ref="1012600125"/>
+                                                       <reference ref="214559597"/>
+                                                       <reference ref="596732606"/>
+                                                       <reference ref="393423671"/>
+                                               </array>
+                                               <reference key="parent" ref="792887677"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">389</int>
+                                               <reference key="object" ref="159677712"/>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">390</int>
+                                               <reference key="object" ref="305399458"/>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">391</int>
+                                               <reference key="object" ref="814362025"/>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">392</int>
+                                               <reference key="object" ref="330926929"/>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">393</int>
+                                               <reference key="object" ref="533507878"/>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">394</int>
+                                               <reference key="object" ref="158063935"/>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">395</int>
+                                               <reference key="object" ref="885547335"/>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">396</int>
+                                               <reference key="object" ref="901062459"/>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">397</int>
+                                               <reference key="object" ref="767671776"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="175441468"/>
+                                               </array>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">398</int>
+                                               <reference key="object" ref="691570813"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="1058217995"/>
+                                               </array>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">399</int>
+                                               <reference key="object" ref="769124883"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="18263474"/>
+                                               </array>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">400</int>
+                                               <reference key="object" ref="739652853"/>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">401</int>
+                                               <reference key="object" ref="1012600125"/>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">402</int>
+                                               <reference key="object" ref="214559597"/>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">403</int>
+                                               <reference key="object" ref="596732606"/>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">404</int>
+                                               <reference key="object" ref="393423671"/>
+                                               <reference key="parent" ref="786677654"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">405</int>
+                                               <reference key="object" ref="18263474"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="257962622"/>
+                                                       <reference ref="644725453"/>
+                                                       <reference ref="1037576581"/>
+                                                       <reference ref="941806246"/>
+                                                       <reference ref="1045724900"/>
+                                               </array>
+                                               <reference key="parent" ref="769124883"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">406</int>
+                                               <reference key="object" ref="257962622"/>
+                                               <reference key="parent" ref="18263474"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">407</int>
+                                               <reference key="object" ref="644725453"/>
+                                               <reference key="parent" ref="18263474"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">408</int>
+                                               <reference key="object" ref="1037576581"/>
+                                               <reference key="parent" ref="18263474"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">409</int>
+                                               <reference key="object" ref="941806246"/>
+                                               <reference key="parent" ref="18263474"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">410</int>
+                                               <reference key="object" ref="1045724900"/>
+                                               <reference key="parent" ref="18263474"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">411</int>
+                                               <reference key="object" ref="1058217995"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="706297211"/>
+                                                       <reference ref="568384683"/>
+                                                       <reference ref="663508465"/>
+                                               </array>
+                                               <reference key="parent" ref="691570813"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">412</int>
+                                               <reference key="object" ref="706297211"/>
+                                               <reference key="parent" ref="1058217995"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">413</int>
+                                               <reference key="object" ref="568384683"/>
+                                               <reference key="parent" ref="1058217995"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">414</int>
+                                               <reference key="object" ref="663508465"/>
+                                               <reference key="parent" ref="1058217995"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">415</int>
+                                               <reference key="object" ref="175441468"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="252969304"/>
+                                                       <reference ref="766922938"/>
+                                                       <reference ref="677519740"/>
+                                                       <reference ref="238351151"/>
+                                               </array>
+                                               <reference key="parent" ref="767671776"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">416</int>
+                                               <reference key="object" ref="252969304"/>
+                                               <reference key="parent" ref="175441468"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">417</int>
+                                               <reference key="object" ref="766922938"/>
+                                               <reference key="parent" ref="175441468"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">418</int>
+                                               <reference key="object" ref="677519740"/>
+                                               <reference key="parent" ref="175441468"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">419</int>
+                                               <reference key="object" ref="238351151"/>
+                                               <reference key="parent" ref="175441468"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">420</int>
+                                               <reference key="object" ref="755631768"/>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">450</int>
+                                               <reference key="object" ref="288088188"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="579392910"/>
+                                               </array>
+                                               <reference key="parent" ref="789758025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">451</int>
+                                               <reference key="object" ref="579392910"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="1060694897"/>
+                                                       <reference ref="879586729"/>
+                                                       <reference ref="56570060"/>
+                                               </array>
+                                               <reference key="parent" ref="288088188"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">452</int>
+                                               <reference key="object" ref="1060694897"/>
+                                               <reference key="parent" ref="579392910"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">453</int>
+                                               <reference key="object" ref="859480356"/>
+                                               <reference key="parent" ref="769623530"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">454</int>
+                                               <reference key="object" ref="795346622"/>
+                                               <reference key="parent" ref="769623530"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">457</int>
+                                               <reference key="object" ref="65139061"/>
+                                               <reference key="parent" ref="698887838"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">459</int>
+                                               <reference key="object" ref="19036812"/>
+                                               <reference key="parent" ref="698887838"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">460</int>
+                                               <reference key="object" ref="672708820"/>
+                                               <reference key="parent" ref="698887838"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">462</int>
+                                               <reference key="object" ref="537092702"/>
+                                               <reference key="parent" ref="698887838"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">465</int>
+                                               <reference key="object" ref="879586729"/>
+                                               <reference key="parent" ref="579392910"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">466</int>
+                                               <reference key="object" ref="56570060"/>
+                                               <reference key="parent" ref="579392910"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">485</int>
+                                               <reference key="object" ref="82994268"/>
+                                               <reference key="parent" ref="789758025"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">490</int>
+                                               <reference key="object" ref="448692316"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="992780483"/>
+                                               </array>
+                                               <reference key="parent" ref="649796088"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">491</int>
+                                               <reference key="object" ref="992780483"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="105068016"/>
+                                               </array>
+                                               <reference key="parent" ref="448692316"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">492</int>
+                                               <reference key="object" ref="105068016"/>
+                                               <reference key="parent" ref="992780483"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">494</int>
+                                               <reference key="object" ref="976324537"/>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">496</int>
+                                               <reference key="object" ref="215659978"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="446991534"/>
+                                               </array>
+                                               <reference key="parent" ref="941447902"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">497</int>
+                                               <reference key="object" ref="446991534"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="875092757"/>
+                                                       <reference ref="630155264"/>
+                                                       <reference ref="945678886"/>
+                                                       <reference ref="512868991"/>
+                                                       <reference ref="163117631"/>
+                                                       <reference ref="31516759"/>
+                                                       <reference ref="908105787"/>
+                                                       <reference ref="644046920"/>
+                                                       <reference ref="231811626"/>
+                                                       <reference ref="883618387"/>
+                                               </array>
+                                               <reference key="parent" ref="215659978"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">498</int>
+                                               <reference key="object" ref="875092757"/>
+                                               <reference key="parent" ref="446991534"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">499</int>
+                                               <reference key="object" ref="630155264"/>
+                                               <reference key="parent" ref="446991534"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">500</int>
+                                               <reference key="object" ref="945678886"/>
+                                               <reference key="parent" ref="446991534"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">501</int>
+                                               <reference key="object" ref="512868991"/>
+                                               <reference key="parent" ref="446991534"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">502</int>
+                                               <reference key="object" ref="163117631"/>
+                                               <reference key="parent" ref="446991534"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">503</int>
+                                               <reference key="object" ref="31516759"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="956096989"/>
+                                               </array>
+                                               <reference key="parent" ref="446991534"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">504</int>
+                                               <reference key="object" ref="908105787"/>
+                                               <reference key="parent" ref="446991534"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">505</int>
+                                               <reference key="object" ref="644046920"/>
+                                               <reference key="parent" ref="446991534"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">506</int>
+                                               <reference key="object" ref="231811626"/>
+                                               <reference key="parent" ref="446991534"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">507</int>
+                                               <reference key="object" ref="883618387"/>
+                                               <reference key="parent" ref="446991534"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">508</int>
+                                               <reference key="object" ref="956096989"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="257099033"/>
+                                                       <reference ref="551969625"/>
+                                                       <reference ref="249532473"/>
+                                                       <reference ref="607364498"/>
+                                                       <reference ref="508151438"/>
+                                                       <reference ref="981751889"/>
+                                                       <reference ref="380031999"/>
+                                                       <reference ref="825984362"/>
+                                                       <reference ref="560145579"/>
+                                               </array>
+                                               <reference key="parent" ref="31516759"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">509</int>
+                                               <reference key="object" ref="257099033"/>
+                                               <reference key="parent" ref="956096989"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">510</int>
+                                               <reference key="object" ref="551969625"/>
+                                               <reference key="parent" ref="956096989"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">511</int>
+                                               <reference key="object" ref="249532473"/>
+                                               <reference key="parent" ref="956096989"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">512</int>
+                                               <reference key="object" ref="607364498"/>
+                                               <reference key="parent" ref="956096989"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">513</int>
+                                               <reference key="object" ref="508151438"/>
+                                               <reference key="parent" ref="956096989"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">514</int>
+                                               <reference key="object" ref="981751889"/>
+                                               <reference key="parent" ref="956096989"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">515</int>
+                                               <reference key="object" ref="380031999"/>
+                                               <reference key="parent" ref="956096989"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">516</int>
+                                               <reference key="object" ref="825984362"/>
+                                               <reference key="parent" ref="956096989"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">517</int>
+                                               <reference key="object" ref="560145579"/>
+                                               <reference key="parent" ref="956096989"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">534</int>
+                                               <reference key="object" ref="738670835"/>
+                                               <reference key="parent" ref="963351320"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">536</int>
+                                               <reference key="object" ref="916837096"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="761467965"/>
+                                                       <reference ref="993304700"/>
+                                                       <reference ref="133282229"/>
+                                               </array>
+                                               <reference key="parent" ref="439893737"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">537</int>
+                                               <reference key="object" ref="761467965"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="716065875"/>
+                                               </array>
+                                               <reference key="parent" ref="916837096"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">538</int>
+                                               <reference key="object" ref="993304700"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="141374255"/>
+                                               </array>
+                                               <reference key="parent" ref="916837096"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">539</int>
+                                               <reference key="object" ref="141374255"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="1048394879"/>
+                                                       <object class="IBNSLayoutConstraint" id="345226256">
+                                                               <reference key="firstItem" ref="141374255"/>
+                                                               <int key="firstAttribute">6</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="1020307009"/>
+                                                               <int key="secondAttribute">6</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">17</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="141374255"/>
+                                                               <int key="scoringType">8</int>
+                                                               <float key="scoringTypeFloat">29</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="44041073">
+                                                               <reference key="firstItem" ref="1020307009"/>
+                                                               <int key="firstAttribute">3</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="141374255"/>
+                                                               <int key="secondAttribute">3</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">17</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="141374255"/>
+                                                               <int key="scoringType">8</int>
+                                                               <float key="scoringTypeFloat">29</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="928146715">
+                                                               <reference key="firstItem" ref="887827883"/>
+                                                               <int key="firstAttribute">5</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="141374255"/>
+                                                               <int key="secondAttribute">5</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">3</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="141374255"/>
+                                                               <int key="scoringType">8</int>
+                                                               <float key="scoringTypeFloat">29</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="609490562">
+                                                               <reference key="firstItem" ref="141374255"/>
+                                                               <int key="firstAttribute">6</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="887827883"/>
+                                                               <int key="secondAttribute">6</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">17</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="141374255"/>
+                                                               <int key="scoringType">8</int>
+                                                               <float key="scoringTypeFloat">29</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="828184300">
+                                                               <reference key="firstItem" ref="141374255"/>
+                                                               <int key="firstAttribute">4</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="887827883"/>
+                                                               <int key="secondAttribute">4</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">17</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="141374255"/>
+                                                               <int key="scoringType">8</int>
+                                                               <float key="scoringTypeFloat">29</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="416923576">
+                                                               <reference key="firstItem" ref="887827883"/>
+                                                               <int key="firstAttribute">3</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="477817691"/>
+                                                               <int key="secondAttribute">4</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBNSLayoutSymbolicConstant" key="constant">
+                                                                       <double key="value">8</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="141374255"/>
+                                                               <int key="scoringType">6</int>
+                                                               <float key="scoringTypeFloat">24</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="262227236">
+                                                               <reference key="firstItem" ref="305991928"/>
+                                                               <int key="firstAttribute">5</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="477817691"/>
+                                                               <int key="secondAttribute">6</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBNSLayoutSymbolicConstant" key="constant">
+                                                                       <double key="value">8</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="141374255"/>
+                                                               <int key="scoringType">6</int>
+                                                               <float key="scoringTypeFloat">24</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="38440651">
+                                                               <reference key="firstItem" ref="305991928"/>
+                                                               <int key="firstAttribute">11</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="477817691"/>
+                                                               <int key="secondAttribute">11</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">0.0</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="141374255"/>
+                                                               <int key="scoringType">6</int>
+                                                               <float key="scoringTypeFloat">24</float>
+                                                               <int key="contentType">2</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="981154238">
+                                                               <reference key="firstItem" ref="477817691"/>
+                                                               <int key="firstAttribute">5</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="141374255"/>
+                                                               <int key="secondAttribute">5</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">9</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="141374255"/>
+                                                               <int key="scoringType">3</int>
+                                                               <float key="scoringTypeFloat">9</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="388914140">
+                                                               <reference key="firstItem" ref="477817691"/>
+                                                               <int key="firstAttribute">3</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="141374255"/>
+                                                               <int key="secondAttribute">3</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">241</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="141374255"/>
+                                                               <int key="scoringType">3</int>
+                                                               <float key="scoringTypeFloat">9</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="169396712">
+                                                               <reference key="firstItem" ref="477817691"/>
+                                                               <int key="firstAttribute">3</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="588513756"/>
+                                                               <int key="secondAttribute">4</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBNSLayoutSymbolicConstant" key="constant">
+                                                                       <double key="value">8</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="141374255"/>
+                                                               <int key="scoringType">6</int>
+                                                               <float key="scoringTypeFloat">24</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="137774417">
+                                                               <reference key="firstItem" ref="141374255"/>
+                                                               <int key="firstAttribute">6</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="588513756"/>
+                                                               <int key="secondAttribute">6</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">17</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="141374255"/>
+                                                               <int key="scoringType">8</int>
+                                                               <float key="scoringTypeFloat">29</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="387714677">
+                                                               <reference key="firstItem" ref="588513756"/>
+                                                               <int key="firstAttribute">5</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="141374255"/>
+                                                               <int key="secondAttribute">5</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">3</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="141374255"/>
+                                                               <int key="scoringType">8</int>
+                                                               <float key="scoringTypeFloat">29</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="40363452">
+                                                               <reference key="firstItem" ref="588513756"/>
+                                                               <int key="firstAttribute">3</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="660421540"/>
+                                                               <int key="secondAttribute">4</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBNSLayoutSymbolicConstant" key="constant">
+                                                                       <double key="value">8</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="141374255"/>
+                                                               <int key="scoringType">6</int>
+                                                               <float key="scoringTypeFloat">24</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="944134702">
+                                                               <reference key="firstItem" ref="665082678"/>
+                                                               <int key="firstAttribute">11</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="660421540"/>
+                                                               <int key="secondAttribute">11</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">0.0</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="141374255"/>
+                                                               <int key="scoringType">6</int>
+                                                               <float key="scoringTypeFloat">24</float>
+                                                               <int key="contentType">2</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="18572239">
+                                                               <reference key="firstItem" ref="665082678"/>
+                                                               <int key="firstAttribute">5</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="141374255"/>
+                                                               <int key="secondAttribute">5</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">66</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="141374255"/>
+                                                               <int key="scoringType">3</int>
+                                                               <float key="scoringTypeFloat">9</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="567908768">
+                                                               <reference key="firstItem" ref="660421540"/>
+                                                               <int key="firstAttribute">5</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="998974400"/>
+                                                               <int key="secondAttribute">5</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">0.0</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="141374255"/>
+                                                               <int key="scoringType">6</int>
+                                                               <float key="scoringTypeFloat">24</float>
+                                                               <int key="contentType">2</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="745285132">
+                                                               <reference key="firstItem" ref="660421540"/>
+                                                               <int key="firstAttribute">3</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="1071550691"/>
+                                                               <int key="secondAttribute">4</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBNSLayoutSymbolicConstant" key="constant">
+                                                                       <double key="value">8</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="141374255"/>
+                                                               <int key="scoringType">6</int>
+                                                               <float key="scoringTypeFloat">24</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="57320816">
+                                                               <reference key="firstItem" ref="141374255"/>
+                                                               <int key="firstAttribute">6</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="1071550691"/>
+                                                               <int key="secondAttribute">6</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">17</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="141374255"/>
+                                                               <int key="scoringType">8</int>
+                                                               <float key="scoringTypeFloat">29</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="641151141">
+                                                               <reference key="firstItem" ref="1071550691"/>
+                                                               <int key="firstAttribute">5</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="141374255"/>
+                                                               <int key="secondAttribute">5</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">3</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="141374255"/>
+                                                               <int key="scoringType">8</int>
+                                                               <float key="scoringTypeFloat">29</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="86449967">
+                                                               <reference key="firstItem" ref="1071550691"/>
+                                                               <int key="firstAttribute">3</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="998974400"/>
+                                                               <int key="secondAttribute">4</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBNSLayoutSymbolicConstant" key="constant">
+                                                                       <double key="value">8</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="141374255"/>
+                                                               <int key="scoringType">6</int>
+                                                               <float key="scoringTypeFloat">24</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="781422004">
+                                                               <reference key="firstItem" ref="998974400"/>
+                                                               <int key="firstAttribute">6</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="1048394879"/>
+                                                               <int key="secondAttribute">6</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">0.0</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="141374255"/>
+                                                               <int key="scoringType">6</int>
+                                                               <float key="scoringTypeFloat">24</float>
+                                                               <int key="contentType">2</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="411200262">
+                                                               <reference key="firstItem" ref="998974400"/>
+                                                               <int key="firstAttribute">3</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="1048394879"/>
+                                                               <int key="secondAttribute">4</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBNSLayoutSymbolicConstant" key="constant">
+                                                                       <double key="value">8</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="141374255"/>
+                                                               <int key="scoringType">6</int>
+                                                               <float key="scoringTypeFloat">24</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="421908976">
+                                                               <reference key="firstItem" ref="1048394879"/>
+                                                               <int key="firstAttribute">5</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="141374255"/>
+                                                               <int key="secondAttribute">5</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">3</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="141374255"/>
+                                                               <int key="scoringType">8</int>
+                                                               <float key="scoringTypeFloat">29</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="507784761">
+                                                               <reference key="firstItem" ref="1048394879"/>
+                                                               <int key="firstAttribute">3</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="141374255"/>
+                                                               <int key="secondAttribute">3</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">17</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="141374255"/>
+                                                               <int key="scoringType">8</int>
+                                                               <float key="scoringTypeFloat">29</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <reference ref="1020307009"/>
+                                                       <reference ref="998974400"/>
+                                                       <reference ref="1071550691"/>
+                                                       <reference ref="660421540"/>
+                                                       <reference ref="665082678"/>
+                                                       <reference ref="588513756"/>
+                                                       <reference ref="477817691"/>
+                                                       <reference ref="887827883"/>
+                                                       <reference ref="305991928"/>
+                                               </array>
+                                               <reference key="parent" ref="993304700"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">540</int>
+                                               <reference key="object" ref="716065875"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="233427652"/>
+                                                       <object class="IBNSLayoutConstraint" id="535717307">
+                                                               <reference key="firstItem" ref="716065875"/>
+                                                               <int key="firstAttribute">6</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="834759928"/>
+                                                               <int key="secondAttribute">6</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">17</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="716065875"/>
+                                                               <int key="scoringType">8</int>
+                                                               <float key="scoringTypeFloat">29</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="1012174613">
+                                                               <reference key="firstItem" ref="834759928"/>
+                                                               <int key="firstAttribute">3</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="716065875"/>
+                                                               <int key="secondAttribute">3</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">17</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="716065875"/>
+                                                               <int key="scoringType">8</int>
+                                                               <float key="scoringTypeFloat">29</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="1023530864">
+                                                               <reference key="firstItem" ref="716065875"/>
+                                                               <int key="firstAttribute">6</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="542670786"/>
+                                                               <int key="secondAttribute">6</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">17</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="716065875"/>
+                                                               <int key="scoringType">8</int>
+                                                               <float key="scoringTypeFloat">29</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="262192932">
+                                                               <reference key="firstItem" ref="716065875"/>
+                                                               <int key="firstAttribute">4</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="542670786"/>
+                                                               <int key="secondAttribute">4</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">12</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="716065875"/>
+                                                               <int key="scoringType">3</int>
+                                                               <float key="scoringTypeFloat">9</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="333258764">
+                                                               <reference key="firstItem" ref="542670786"/>
+                                                               <int key="firstAttribute">5</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="716065875"/>
+                                                               <int key="secondAttribute">5</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">3</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="716065875"/>
+                                                               <int key="scoringType">8</int>
+                                                               <float key="scoringTypeFloat">29</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="1069701848">
+                                                               <reference key="firstItem" ref="542670786"/>
+                                                               <int key="firstAttribute">3</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="233427652"/>
+                                                               <int key="secondAttribute">4</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBNSLayoutSymbolicConstant" key="constant">
+                                                                       <double key="value">8</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="716065875"/>
+                                                               <int key="scoringType">6</int>
+                                                               <float key="scoringTypeFloat">24</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="894709607">
+                                                               <reference key="firstItem" ref="233427652"/>
+                                                               <int key="firstAttribute">11</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="834759928"/>
+                                                               <int key="secondAttribute">11</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">0.0</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="716065875"/>
+                                                               <int key="scoringType">6</int>
+                                                               <float key="scoringTypeFloat">24</float>
+                                                               <int key="contentType">2</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="716429724">
+                                                               <reference key="firstItem" ref="716065875"/>
+                                                               <int key="firstAttribute">6</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="233427652"/>
+                                                               <int key="secondAttribute">6</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">17</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="716065875"/>
+                                                               <int key="scoringType">8</int>
+                                                               <float key="scoringTypeFloat">29</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="697046937">
+                                                               <reference key="firstItem" ref="233427652"/>
+                                                               <int key="firstAttribute">5</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="716065875"/>
+                                                               <int key="secondAttribute">5</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">3</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="716065875"/>
+                                                               <int key="scoringType">8</int>
+                                                               <float key="scoringTypeFloat">29</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="743528712">
+                                                               <reference key="firstItem" ref="233427652"/>
+                                                               <int key="firstAttribute">3</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="716065875"/>
+                                                               <int key="secondAttribute">3</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">17</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="716065875"/>
+                                                               <int key="scoringType">8</int>
+                                                               <float key="scoringTypeFloat">29</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <reference ref="834759928"/>
+                                                       <reference ref="542670786"/>
+                                               </array>
+                                               <reference key="parent" ref="761467965"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">549</int>
+                                               <reference key="object" ref="133282229"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="933472960"/>
+                                               </array>
+                                               <reference key="parent" ref="916837096"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">550</int>
+                                               <reference key="object" ref="933472960"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <object class="IBNSLayoutConstraint" id="89597442">
+                                                               <reference key="firstItem" ref="933472960"/>
+                                                               <int key="firstAttribute">6</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="760674507"/>
+                                                               <int key="secondAttribute">6</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">17</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="933472960"/>
+                                                               <int key="scoringType">8</int>
+                                                               <float key="scoringTypeFloat">29</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="845083749">
+                                                               <reference key="firstItem" ref="933472960"/>
+                                                               <int key="firstAttribute">4</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="760674507"/>
+                                                               <int key="secondAttribute">4</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">17</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="933472960"/>
+                                                               <int key="scoringType">8</int>
+                                                               <float key="scoringTypeFloat">29</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="130043084">
+                                                               <reference key="firstItem" ref="933472960"/>
+                                                               <int key="firstAttribute">6</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="935864981"/>
+                                                               <int key="secondAttribute">6</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">17</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="933472960"/>
+                                                               <int key="scoringType">8</int>
+                                                               <float key="scoringTypeFloat">29</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="757760411">
+                                                               <reference key="firstItem" ref="935864981"/>
+                                                               <int key="firstAttribute">3</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="933472960"/>
+                                                               <int key="secondAttribute">3</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">17</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="933472960"/>
+                                                               <int key="scoringType">8</int>
+                                                               <float key="scoringTypeFloat">29</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="1027570841">
+                                                               <reference key="firstItem" ref="933472960"/>
+                                                               <int key="firstAttribute">6</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="1053273967"/>
+                                                               <int key="secondAttribute">6</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">17</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="933472960"/>
+                                                               <int key="scoringType">8</int>
+                                                               <float key="scoringTypeFloat">29</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="1007963555">
+                                                               <reference key="firstItem" ref="1053273967"/>
+                                                               <int key="firstAttribute">3</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="928329068"/>
+                                                               <int key="secondAttribute">4</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBNSLayoutSymbolicConstant" key="constant">
+                                                                       <double key="value">8</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="933472960"/>
+                                                               <int key="scoringType">6</int>
+                                                               <float key="scoringTypeFloat">24</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="282288707">
+                                                               <reference key="firstItem" ref="933472960"/>
+                                                               <int key="firstAttribute">6</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="928329068"/>
+                                                               <int key="secondAttribute">6</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">17</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="933472960"/>
+                                                               <int key="scoringType">8</int>
+                                                               <float key="scoringTypeFloat">29</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="989392316">
+                                                               <reference key="firstItem" ref="928329068"/>
+                                                               <int key="firstAttribute">3</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="874894253"/>
+                                                               <int key="secondAttribute">4</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBNSLayoutSymbolicConstant" key="constant">
+                                                                       <double key="value">8</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="933472960"/>
+                                                               <int key="scoringType">6</int>
+                                                               <float key="scoringTypeFloat">24</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="411897828">
+                                                               <reference key="firstItem" ref="874894253"/>
+                                                               <int key="firstAttribute">3</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="347352225"/>
+                                                               <int key="secondAttribute">4</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBNSLayoutSymbolicConstant" key="constant">
+                                                                       <double key="value">8</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="933472960"/>
+                                                               <int key="scoringType">6</int>
+                                                               <float key="scoringTypeFloat">24</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="950351222">
+                                                               <reference key="firstItem" ref="933472960"/>
+                                                               <int key="firstAttribute">6</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="874894253"/>
+                                                               <int key="secondAttribute">6</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">17</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="933472960"/>
+                                                               <int key="scoringType">8</int>
+                                                               <float key="scoringTypeFloat">29</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="396092194">
+                                                               <reference key="firstItem" ref="347352225"/>
+                                                               <int key="firstAttribute">3</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="914091846"/>
+                                                               <int key="secondAttribute">4</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBNSLayoutSymbolicConstant" key="constant">
+                                                                       <double key="value">8</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="933472960"/>
+                                                               <int key="scoringType">6</int>
+                                                               <float key="scoringTypeFloat">24</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="893031406">
+                                                               <reference key="firstItem" ref="933472960"/>
+                                                               <int key="firstAttribute">6</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="347352225"/>
+                                                               <int key="secondAttribute">6</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">17</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="933472960"/>
+                                                               <int key="scoringType">8</int>
+                                                               <float key="scoringTypeFloat">29</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="901114028">
+                                                               <reference key="firstItem" ref="914091846"/>
+                                                               <int key="firstAttribute">7</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="1053273967"/>
+                                                               <int key="secondAttribute">7</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">0.0</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="933472960"/>
+                                                               <int key="scoringType">9</int>
+                                                               <float key="scoringTypeFloat">40</float>
+                                                               <int key="contentType">5</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="990680857">
+                                                               <reference key="firstItem" ref="914091846"/>
+                                                               <int key="firstAttribute">7</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="1003098491"/>
+                                                               <int key="secondAttribute">7</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">0.0</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="933472960"/>
+                                                               <int key="scoringType">9</int>
+                                                               <float key="scoringTypeFloat">40</float>
+                                                               <int key="contentType">5</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="546965660">
+                                                               <reference key="firstItem" ref="914091846"/>
+                                                               <int key="firstAttribute">7</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="928329068"/>
+                                                               <int key="secondAttribute">7</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">0.0</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="933472960"/>
+                                                               <int key="scoringType">9</int>
+                                                               <float key="scoringTypeFloat">40</float>
+                                                               <int key="contentType">5</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="72930728">
+                                                               <reference key="firstItem" ref="914091846"/>
+                                                               <int key="firstAttribute">7</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="874894253"/>
+                                                               <int key="secondAttribute">7</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">0.0</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="933472960"/>
+                                                               <int key="scoringType">9</int>
+                                                               <float key="scoringTypeFloat">40</float>
+                                                               <int key="contentType">5</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="9527619">
+                                                               <reference key="firstItem" ref="914091846"/>
+                                                               <int key="firstAttribute">7</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="347352225"/>
+                                                               <int key="secondAttribute">7</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">0.0</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="933472960"/>
+                                                               <int key="scoringType">9</int>
+                                                               <float key="scoringTypeFloat">40</float>
+                                                               <int key="contentType">5</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="309643227">
+                                                               <reference key="firstItem" ref="914091846"/>
+                                                               <int key="firstAttribute">3</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="1003098491"/>
+                                                               <int key="secondAttribute">4</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBNSLayoutSymbolicConstant" key="constant">
+                                                                       <double key="value">8</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="933472960"/>
+                                                               <int key="scoringType">6</int>
+                                                               <float key="scoringTypeFloat">24</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="676061611">
+                                                               <reference key="firstItem" ref="933472960"/>
+                                                               <int key="firstAttribute">6</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="914091846"/>
+                                                               <int key="secondAttribute">6</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">17</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="933472960"/>
+                                                               <int key="scoringType">8</int>
+                                                               <float key="scoringTypeFloat">29</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="664039895">
+                                                               <reference key="firstItem" ref="1003098491"/>
+                                                               <int key="firstAttribute">3</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="933472960"/>
+                                                               <int key="secondAttribute">3</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">133</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="933472960"/>
+                                                               <int key="scoringType">3</int>
+                                                               <float key="scoringTypeFloat">9</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="972186788">
+                                                               <reference key="firstItem" ref="933472960"/>
+                                                               <int key="firstAttribute">6</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="1003098491"/>
+                                                               <int key="secondAttribute">6</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">17</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="933472960"/>
+                                                               <int key="scoringType">8</int>
+                                                               <float key="scoringTypeFloat">29</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="913874730">
+                                                               <reference key="firstItem" ref="786023451"/>
+                                                               <int key="firstAttribute">5</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="933472960"/>
+                                                               <int key="secondAttribute">5</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">3</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="933472960"/>
+                                                               <int key="scoringType">8</int>
+                                                               <float key="scoringTypeFloat">29</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="91603433">
+                                                               <reference key="firstItem" ref="933472960"/>
+                                                               <int key="firstAttribute">4</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="786023451"/>
+                                                               <int key="secondAttribute">4</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">117</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="933472960"/>
+                                                               <int key="scoringType">3</int>
+                                                               <float key="scoringTypeFloat">9</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="501302931">
+                                                               <reference key="firstItem" ref="141416926"/>
+                                                               <int key="firstAttribute">5</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="933472960"/>
+                                                               <int key="secondAttribute">5</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">18</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="933472960"/>
+                                                               <int key="scoringType">3</int>
+                                                               <float key="scoringTypeFloat">9</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <object class="IBNSLayoutConstraint" id="813707">
+                                                               <reference key="firstItem" ref="141416926"/>
+                                                               <int key="firstAttribute">3</int>
+                                                               <int key="relation">0</int>
+                                                               <reference key="secondItem" ref="933472960"/>
+                                                               <int key="secondAttribute">3</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">70</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="933472960"/>
+                                                               <int key="scoringType">3</int>
+                                                               <float key="scoringTypeFloat">9</float>
+                                                               <int key="contentType">3</int>
+                                                       </object>
+                                                       <reference ref="1003098491"/>
+                                                       <reference ref="928329068"/>
+                                                       <reference ref="1053273967"/>
+                                                       <reference ref="347352225"/>
+                                                       <reference ref="874894253"/>
+                                                       <reference ref="914091846"/>
+                                                       <reference ref="786023451"/>
+                                                       <reference ref="935864981"/>
+                                                       <reference ref="760674507"/>
+                                                       <reference ref="141416926"/>
+                                               </array>
+                                               <reference key="parent" ref="133282229"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">555</int>
+                                               <reference key="object" ref="378483925"/>
+                                               <reference key="parent" ref="439893737"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">558</int>
+                                               <reference key="object" ref="811760524"/>
+                                               <reference key="parent" ref="439893737"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">560</int>
+                                               <reference key="object" ref="439273158"/>
+                                               <reference key="parent" ref="439893737"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">562</int>
+                                               <reference key="object" ref="192567985"/>
+                                               <reference key="parent" ref="439893737"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">599</int>
+                                               <reference key="object" ref="1048394879"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="1020736299"/>
+                                               </array>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">600</int>
+                                               <reference key="object" ref="1020736299"/>
+                                               <reference key="parent" ref="1048394879"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">601</int>
+                                               <reference key="object" ref="507784761"/>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">602</int>
+                                               <reference key="object" ref="421908976"/>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">603</int>
+                                               <reference key="object" ref="1020307009"/>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">608</int>
+                                               <reference key="object" ref="44041073"/>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">609</int>
+                                               <reference key="object" ref="345226256"/>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">610</int>
+                                               <reference key="object" ref="998974400"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="718406896"/>
+                                                       <object class="IBNSLayoutConstraint" id="216970794">
+                                                               <reference key="firstItem" ref="998974400"/>
+                                                               <int key="firstAttribute">7</int>
+                                                               <int key="relation">0</int>
+                                                               <nil key="secondItem"/>
+                                                               <int key="secondAttribute">0</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">170</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="998974400"/>
+                                                               <int key="scoringType">3</int>
+                                                               <float key="scoringTypeFloat">9</float>
+                                                               <int key="contentType">1</int>
+                                                       </object>
+                                               </array>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">611</int>
+                                               <reference key="object" ref="718406896"/>
+                                               <reference key="parent" ref="998974400"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">612</int>
+                                               <reference key="object" ref="411200262"/>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">614</int>
+                                               <reference key="object" ref="781422004"/>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">615</int>
+                                               <reference key="object" ref="216970794"/>
+                                               <reference key="parent" ref="998974400"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">632</int>
+                                               <reference key="object" ref="1071550691"/>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">633</int>
+                                               <reference key="object" ref="86449967"/>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">634</int>
+                                               <reference key="object" ref="641151141"/>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">636</int>
+                                               <reference key="object" ref="57320816"/>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">637</int>
+                                               <reference key="object" ref="660421540"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="15806633"/>
+                                                       <object class="IBNSLayoutConstraint" id="39042094">
+                                                               <reference key="firstItem" ref="660421540"/>
+                                                               <int key="firstAttribute">7</int>
+                                                               <int key="relation">0</int>
+                                                               <nil key="secondItem"/>
+                                                               <int key="secondAttribute">0</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">32</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="660421540"/>
+                                                               <int key="scoringType">3</int>
+                                                               <float key="scoringTypeFloat">9</float>
+                                                               <int key="contentType">1</int>
+                                                       </object>
+                                               </array>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">638</int>
+                                               <reference key="object" ref="15806633"/>
+                                               <reference key="parent" ref="660421540"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">641</int>
+                                               <reference key="object" ref="665082678"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="353430769"/>
+                                               </array>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">642</int>
+                                               <reference key="object" ref="353430769"/>
+                                               <reference key="parent" ref="665082678"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">643</int>
+                                               <reference key="object" ref="39042094"/>
+                                               <reference key="parent" ref="660421540"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">645</int>
+                                               <reference key="object" ref="944134702"/>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">652</int>
+                                               <reference key="object" ref="588513756"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="445558087"/>
+                                                       <reference ref="892199647"/>
+                                                       <reference ref="508177949"/>
+                                               </array>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">653</int>
+                                               <reference key="object" ref="445558087"/>
+                                               <reference key="parent" ref="588513756"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">654</int>
+                                               <reference key="object" ref="892199647"/>
+                                               <reference key="parent" ref="588513756"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">655</int>
+                                               <reference key="object" ref="508177949"/>
+                                               <reference key="parent" ref="588513756"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">660</int>
+                                               <reference key="object" ref="40363452"/>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">644</int>
+                                               <reference key="object" ref="18572239"/>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">639</int>
+                                               <reference key="object" ref="745285132"/>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">664</int>
+                                               <reference key="object" ref="387714677"/>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">640</int>
+                                               <reference key="object" ref="567908768"/>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">665</int>
+                                               <reference key="object" ref="137774417"/>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">689</int>
+                                               <reference key="object" ref="477817691"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="249835835"/>
+                                               </array>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">690</int>
+                                               <reference key="object" ref="305991928"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="255632910"/>
+                                               </array>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">691</int>
+                                               <reference key="object" ref="887827883"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="68514601"/>
+                                                       <reference ref="748993527"/>
+                                                       <reference ref="97048596"/>
+                                               </array>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">692</int>
+                                               <reference key="object" ref="68514601"/>
+                                               <reference key="parent" ref="887827883"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">693</int>
+                                               <reference key="object" ref="748993527"/>
+                                               <reference key="parent" ref="887827883"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">694</int>
+                                               <reference key="object" ref="97048596"/>
+                                               <reference key="parent" ref="887827883"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">695</int>
+                                               <reference key="object" ref="255632910"/>
+                                               <reference key="parent" ref="305991928"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">697</int>
+                                               <reference key="object" ref="249835835"/>
+                                               <reference key="parent" ref="477817691"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">703</int>
+                                               <reference key="object" ref="38440651"/>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">711</int>
+                                               <reference key="object" ref="169396712"/>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">715</int>
+                                               <reference key="object" ref="388914140"/>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">722</int>
+                                               <reference key="object" ref="416923576"/>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">724</int>
+                                               <reference key="object" ref="981154238"/>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">725</int>
+                                               <reference key="object" ref="828184300"/>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">726</int>
+                                               <reference key="object" ref="609490562"/>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">727</int>
+                                               <reference key="object" ref="928146715"/>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">728</int>
+                                               <reference key="object" ref="262227236"/>
+                                               <reference key="parent" ref="141374255"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">729</int>
+                                               <reference key="object" ref="1003098491"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="1031398538"/>
+                                               </array>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">730</int>
+                                               <reference key="object" ref="1031398538"/>
+                                               <reference key="parent" ref="1003098491"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">733</int>
+                                               <reference key="object" ref="972186788"/>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">734</int>
+                                               <reference key="object" ref="914091846"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="607450495"/>
+                                               </array>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">735</int>
+                                               <reference key="object" ref="607450495"/>
+                                               <reference key="parent" ref="914091846"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">738</int>
+                                               <reference key="object" ref="676061611"/>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">739</int>
+                                               <reference key="object" ref="309643227"/>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">740</int>
+                                               <reference key="object" ref="347352225"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="315128676"/>
+                                               </array>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">741</int>
+                                               <reference key="object" ref="315128676"/>
+                                               <reference key="parent" ref="347352225"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">744</int>
+                                               <reference key="object" ref="893031406"/>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">745</int>
+                                               <reference key="object" ref="396092194"/>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">750</int>
+                                               <reference key="object" ref="874894253"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="956278817"/>
+                                               </array>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">751</int>
+                                               <reference key="object" ref="956278817"/>
+                                               <reference key="parent" ref="874894253"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">754</int>
+                                               <reference key="object" ref="950351222"/>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">755</int>
+                                               <reference key="object" ref="411897828"/>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">756</int>
+                                               <reference key="object" ref="928329068"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="235965764"/>
+                                               </array>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">757</int>
+                                               <reference key="object" ref="235965764"/>
+                                               <reference key="parent" ref="928329068"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">760</int>
+                                               <reference key="object" ref="989392316"/>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">761</int>
+                                               <reference key="object" ref="282288707"/>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">762</int>
+                                               <reference key="object" ref="1053273967"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="276328216"/>
+                                               </array>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">763</int>
+                                               <reference key="object" ref="276328216"/>
+                                               <reference key="parent" ref="1053273967"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">766</int>
+                                               <reference key="object" ref="1007963555"/>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">767</int>
+                                               <reference key="object" ref="1027570841"/>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">768</int>
+                                               <reference key="object" ref="664039895"/>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">769</int>
+                                               <reference key="object" ref="786023451"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="502128501"/>
+                                               </array>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">770</int>
+                                               <reference key="object" ref="502128501"/>
+                                               <reference key="parent" ref="786023451"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">771</int>
+                                               <reference key="object" ref="91603433"/>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">772</int>
+                                               <reference key="object" ref="913874730"/>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">773</int>
+                                               <reference key="object" ref="935864981"/>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">778</int>
+                                               <reference key="object" ref="757760411"/>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">779</int>
+                                               <reference key="object" ref="130043084"/>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">791</int>
+                                               <reference key="object" ref="9527619"/>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">792</int>
+                                               <reference key="object" ref="72930728"/>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">793</int>
+                                               <reference key="object" ref="546965660"/>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">794</int>
+                                               <reference key="object" ref="990680857"/>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">795</int>
+                                               <reference key="object" ref="901114028"/>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">796</int>
+                                               <reference key="object" ref="760674507"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="82712399"/>
+                                                       <object class="IBNSLayoutConstraint" id="40369113">
+                                                               <reference key="firstItem" ref="760674507"/>
+                                                               <int key="firstAttribute">7</int>
+                                                               <int key="relation">0</int>
+                                                               <nil key="secondItem"/>
+                                                               <int key="secondAttribute">0</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">399</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="760674507"/>
+                                                               <int key="scoringType">3</int>
+                                                               <float key="scoringTypeFloat">9</float>
+                                                               <int key="contentType">1</int>
+                                                       </object>
+                                               </array>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">797</int>
+                                               <reference key="object" ref="82712399"/>
+                                               <reference key="parent" ref="760674507"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">799</int>
+                                               <reference key="object" ref="845083749"/>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">800</int>
+                                               <reference key="object" ref="89597442"/>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">801</int>
+                                               <reference key="object" ref="40369113"/>
+                                               <reference key="parent" ref="760674507"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">802</int>
+                                               <reference key="object" ref="233427652"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="974410057"/>
+                                                       <object class="IBNSLayoutConstraint" id="375519311">
+                                                               <reference key="firstItem" ref="233427652"/>
+                                                               <int key="firstAttribute">8</int>
+                                                               <int key="relation">0</int>
+                                                               <nil key="secondItem"/>
+                                                               <int key="secondAttribute">0</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">17</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="233427652"/>
+                                                               <int key="scoringType">3</int>
+                                                               <float key="scoringTypeFloat">9</float>
+                                                               <int key="contentType">1</int>
+                                                       </object>
+                                               </array>
+                                               <reference key="parent" ref="716065875"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">803</int>
+                                               <reference key="object" ref="974410057"/>
+                                               <reference key="parent" ref="233427652"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">805</int>
+                                               <reference key="object" ref="743528712"/>
+                                               <reference key="parent" ref="716065875"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">807</int>
+                                               <reference key="object" ref="697046937"/>
+                                               <reference key="parent" ref="716065875"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">808</int>
+                                               <reference key="object" ref="716429724"/>
+                                               <reference key="parent" ref="716065875"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">809</int>
+                                               <reference key="object" ref="834759928"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="1053170940"/>
+                                               </array>
+                                               <reference key="parent" ref="716065875"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">810</int>
+                                               <reference key="object" ref="1053170940"/>
+                                               <reference key="parent" ref="834759928"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">811</int>
+                                               <reference key="object" ref="1012174613"/>
+                                               <reference key="parent" ref="716065875"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">812</int>
+                                               <reference key="object" ref="535717307"/>
+                                               <reference key="parent" ref="716065875"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">815</int>
+                                               <reference key="object" ref="375519311"/>
+                                               <reference key="parent" ref="233427652"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">816</int>
+                                               <reference key="object" ref="894709607"/>
+                                               <reference key="parent" ref="716065875"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">817</int>
+                                               <reference key="object" ref="542670786"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="836264498"/>
+                                                       <reference ref="341785125"/>
+                                                       <reference ref="254105964"/>
+                                                       <reference ref="410011191"/>
+                                               </array>
+                                               <reference key="parent" ref="716065875"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">818</int>
+                                               <reference key="object" ref="836264498"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="412324706"/>
+                                                       <reference ref="787416139"/>
+                                               </array>
+                                               <reference key="parent" ref="542670786"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">819</int>
+                                               <reference key="object" ref="341785125"/>
+                                               <reference key="parent" ref="542670786"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">820</int>
+                                               <reference key="object" ref="254105964"/>
+                                               <reference key="parent" ref="542670786"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">821</int>
+                                               <reference key="object" ref="410011191"/>
+                                               <reference key="parent" ref="542670786"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">822</int>
+                                               <reference key="object" ref="412324706"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="56933546"/>
+                                               </array>
+                                               <reference key="parent" ref="836264498"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">823</int>
+                                               <reference key="object" ref="787416139"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="327973200"/>
+                                               </array>
+                                               <reference key="parent" ref="836264498"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">824</int>
+                                               <reference key="object" ref="327973200"/>
+                                               <reference key="parent" ref="787416139"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">825</int>
+                                               <reference key="object" ref="56933546"/>
+                                               <reference key="parent" ref="412324706"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">826</int>
+                                               <reference key="object" ref="1069701848"/>
+                                               <reference key="parent" ref="716065875"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">828</int>
+                                               <reference key="object" ref="333258764"/>
+                                               <reference key="parent" ref="716065875"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">831</int>
+                                               <reference key="object" ref="262192932"/>
+                                               <reference key="parent" ref="716065875"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">832</int>
+                                               <reference key="object" ref="1023530864"/>
+                                               <reference key="parent" ref="716065875"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">845</int>
+                                               <reference key="object" ref="141416926"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="917984923"/>
+                                                       <object class="IBNSLayoutConstraint" id="428535427">
+                                                               <reference key="firstItem" ref="141416926"/>
+                                                               <int key="firstAttribute">8</int>
+                                                               <int key="relation">0</int>
+                                                               <nil key="secondItem"/>
+                                                               <int key="secondAttribute">0</int>
+                                                               <float key="multiplier">1</float>
+                                                               <object class="IBLayoutConstant" key="constant">
+                                                                       <double key="value">62</double>
+                                                               </object>
+                                                               <float key="priority">1000</float>
+                                                               <reference key="containingView" ref="141416926"/>
+                                                               <int key="scoringType">3</int>
+                                                               <float key="scoringTypeFloat">9</float>
+                                                               <int key="contentType">1</int>
+                                                       </object>
+                                               </array>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">846</int>
+                                               <reference key="object" ref="917984923"/>
+                                               <reference key="parent" ref="141416926"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">849</int>
+                                               <reference key="object" ref="428535427"/>
+                                               <reference key="parent" ref="141416926"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">853</int>
+                                               <reference key="object" ref="813707"/>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">854</int>
+                                               <reference key="object" ref="501302931"/>
+                                               <reference key="parent" ref="933472960"/>
+                                       </object>
+                               </array>
+                       </object>
+                       <dictionary class="NSMutableDictionary" key="flattenedProperties">
+                               <string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="-3.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="112.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="124.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="125.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="126.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="129.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="130.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="131.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="134.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="136.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="143.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="144.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="145.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="149.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="150.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="19.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="195.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="196.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="197.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="198.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="199.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="200.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="201.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="202.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="203.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="204.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="205.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="206.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="207.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="208.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="209.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="210.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="211.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="212.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="213.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="214.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="215.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="216.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="217.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="218.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="219.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="220.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="221.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="23.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="236.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="239.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="24.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="29.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="295.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="296.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="297.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="298.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="346.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="348.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="349.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="350.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="351.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="354.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="371.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="371.IBWindowTemplateEditedContentRect">{{380, 496}, {480, 360}}</string>
+                               <integer value="1" key="371.NSWindowTemplate.visibleAtLaunch"/>
+                               <array class="NSMutableArray" key="372.IBNSViewMetadataConstraints">
+                                       <reference ref="378483925"/>
+                                       <reference ref="811760524"/>
+                                       <reference ref="439273158"/>
+                                       <reference ref="192567985"/>
+                               </array>
+                               <string key="372.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="375.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="376.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="377.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="388.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="389.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="390.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="391.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="392.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="393.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="394.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="395.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="396.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="397.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="398.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="399.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="400.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="401.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="402.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="403.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="404.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="405.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="406.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="407.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="408.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="409.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="410.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="411.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="412.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="413.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="414.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="415.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="416.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="417.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="418.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="419.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="420.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="450.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="451.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="452.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="453.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="454.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="457.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="459.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="460.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="462.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="465.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="466.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="485.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="490.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="491.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="492.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="494.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="496.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="497.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="498.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="499.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="5.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="500.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="501.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="502.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="503.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="504.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="505.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="506.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="507.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="508.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="509.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="510.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="511.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="512.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="513.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="514.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="515.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="516.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="517.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="534.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <boolean value="NO" key="536.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+                               <string key="536.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="537.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="538.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <array class="NSMutableArray" key="539.IBNSViewMetadataConstraints">
+                                       <reference ref="507784761"/>
+                                       <reference ref="421908976"/>
+                                       <reference ref="411200262"/>
+                                       <reference ref="781422004"/>
+                                       <reference ref="86449967"/>
+                                       <reference ref="641151141"/>
+                                       <reference ref="57320816"/>
+                                       <reference ref="745285132"/>
+                                       <reference ref="567908768"/>
+                                       <reference ref="18572239"/>
+                                       <reference ref="944134702"/>
+                                       <reference ref="40363452"/>
+                                       <reference ref="387714677"/>
+                                       <reference ref="137774417"/>
+                                       <reference ref="169396712"/>
+                                       <reference ref="388914140"/>
+                                       <reference ref="981154238"/>
+                                       <reference ref="38440651"/>
+                                       <reference ref="262227236"/>
+                                       <reference ref="416923576"/>
+                                       <reference ref="828184300"/>
+                                       <reference ref="609490562"/>
+                                       <reference ref="928146715"/>
+                                       <reference ref="44041073"/>
+                                       <reference ref="345226256"/>
+                               </array>
+                               <string key="539.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <array class="NSMutableArray" key="540.IBNSViewMetadataConstraints">
+                                       <reference ref="743528712"/>
+                                       <reference ref="697046937"/>
+                                       <reference ref="716429724"/>
+                                       <reference ref="894709607"/>
+                                       <reference ref="1069701848"/>
+                                       <reference ref="333258764"/>
+                                       <reference ref="262192932"/>
+                                       <reference ref="1023530864"/>
+                                       <reference ref="1012174613"/>
+                                       <reference ref="535717307"/>
+                               </array>
+                               <string key="540.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="549.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <array class="NSMutableArray" key="550.IBNSViewMetadataConstraints">
+                                       <reference ref="813707"/>
+                                       <reference ref="501302931"/>
+                                       <reference ref="91603433"/>
+                                       <reference ref="913874730"/>
+                                       <reference ref="972186788"/>
+                                       <reference ref="664039895"/>
+                                       <reference ref="676061611"/>
+                                       <reference ref="309643227"/>
+                                       <reference ref="9527619"/>
+                                       <reference ref="72930728"/>
+                                       <reference ref="546965660"/>
+                                       <reference ref="990680857"/>
+                                       <reference ref="901114028"/>
+                                       <reference ref="893031406"/>
+                                       <reference ref="396092194"/>
+                                       <reference ref="950351222"/>
+                                       <reference ref="411897828"/>
+                                       <reference ref="989392316"/>
+                                       <reference ref="282288707"/>
+                                       <reference ref="1007963555"/>
+                                       <reference ref="1027570841"/>
+                                       <reference ref="757760411"/>
+                                       <reference ref="130043084"/>
+                                       <reference ref="845083749"/>
+                                       <reference ref="89597442"/>
+                               </array>
+                               <string key="550.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="555.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="558.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="56.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="560.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="562.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="57.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="58.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <boolean value="NO" key="599.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+                               <string key="599.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="600.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="601.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="602.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <boolean value="NO" key="603.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+                               <string key="603.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="608.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="609.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <array key="610.IBNSViewMetadataConstraints">
+                                       <reference ref="216970794"/>
+                               </array>
+                               <boolean value="NO" key="610.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+                               <string key="610.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="611.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="612.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="614.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="615.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <boolean value="NO" key="632.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+                               <string key="632.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="633.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="634.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="636.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <array key="637.IBNSViewMetadataConstraints">
+                                       <reference ref="39042094"/>
+                               </array>
+                               <boolean value="NO" key="637.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+                               <string key="637.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="638.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="639.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="640.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <boolean value="NO" key="641.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+                               <string key="641.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="642.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="643.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="644.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="645.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <boolean value="NO" key="652.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+                               <string key="652.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="653.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="654.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="655.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="660.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="664.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="665.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <boolean value="NO" key="689.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+                               <string key="689.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <boolean value="NO" key="690.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+                               <string key="690.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <boolean value="NO" key="691.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+                               <string key="691.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="692.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="693.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="694.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="695.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="697.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="703.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="711.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="715.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="72.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="722.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="724.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="725.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="726.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="727.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="728.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <boolean value="NO" key="729.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+                               <string key="729.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="73.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="730.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="733.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <boolean value="NO" key="734.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+                               <string key="734.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="735.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="738.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="739.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="74.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <boolean value="NO" key="740.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+                               <string key="740.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="741.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="744.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="745.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="75.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <boolean value="NO" key="750.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+                               <string key="750.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="751.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="754.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="755.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <boolean value="NO" key="756.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+                               <string key="756.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="757.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="760.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="761.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <boolean value="NO" key="762.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+                               <string key="762.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="763.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="766.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="767.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="768.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <boolean value="NO" key="769.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+                               <string key="769.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="77.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="770.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="771.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="772.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <boolean value="NO" key="773.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+                               <string key="773.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="778.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="779.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="78.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="79.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="791.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="792.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="793.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="794.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="795.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <array key="796.IBNSViewMetadataConstraints">
+                                       <reference ref="40369113"/>
+                               </array>
+                               <boolean value="NO" key="796.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+                               <string key="796.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="797.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="799.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="800.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="801.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <array key="802.IBNSViewMetadataConstraints">
+                                       <reference ref="375519311"/>
+                               </array>
+                               <boolean value="NO" key="802.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+                               <string key="802.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="803.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="805.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="807.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="808.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <boolean value="NO" key="809.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+                               <string key="809.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="81.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="810.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="811.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="812.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="815.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="816.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <boolean value="NO" key="817.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+                               <string key="817.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="818.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="819.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="82.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="820.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="821.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="822.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="823.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="824.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="825.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="826.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="828.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="83.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="831.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="832.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <array class="NSMutableArray" key="845.IBNSViewMetadataConstraints">
+                                       <reference ref="428535427"/>
+                               </array>
+                               <boolean value="NO" key="845.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+                               <string key="845.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="846.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="849.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="853.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="854.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="92.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                       </dictionary>
+                       <dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
+                       <nil key="activeLocalization"/>
+                       <dictionary class="NSMutableDictionary" key="localizations"/>
+                       <nil key="sourceID"/>
+                       <int key="maxID">855</int>
+               </object>
+               <object class="IBClassDescriber" key="IBDocument.Classes">
+                       <array class="NSMutableArray" key="referencedPartialClassDescriptions">
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">KDAppDelegate</string>
+                                       <string key="superclassName">NSObject</string>
+                                       <object class="NSMutableDictionary" key="actions">
+                                               <string key="NS.key.0">enableKeychainSyncingClicked:</string>
+                                               <string key="NS.object.0">id</string>
+                                       </object>
+                                       <object class="NSMutableDictionary" key="actionInfosByName">
+                                               <string key="NS.key.0">enableKeychainSyncingClicked:</string>
+                                               <object class="IBActionInfo" key="NS.object.0">
+                                                       <string key="name">enableKeychainSyncingClicked:</string>
+                                                       <string key="candidateClassName">id</string>
+                                               </object>
+                                       </object>
+                                       <dictionary class="NSMutableDictionary" key="outlets">
+                                               <string key="applicantCountCell">NSTextFieldCell</string>
+                                               <string key="applicantTextList">NSTextView</string>
+                                               <string key="circleStatusCell">NSTextFieldCell</string>
+                                               <string key="enableKeychainSyncing">NSButton</string>
+                                               <string key="itemTable">NSTableView</string>
+                                               <string key="itemTableTitle">NSTextFieldCell</string>
+                                               <string key="peerCountCell">NSTextFieldCell</string>
+                                               <string key="peerTextList">NSTextView</string>
+                                               <string key="syncSpinner">NSProgressIndicator</string>
+                                               <string key="window">NSWindow</string>
+                                       </dictionary>
+                                       <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <object class="IBToOneOutletInfo" key="applicantCountCell">
+                                                       <string key="name">applicantCountCell</string>
+                                                       <string key="candidateClassName">NSTextFieldCell</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="applicantTextList">
+                                                       <string key="name">applicantTextList</string>
+                                                       <string key="candidateClassName">NSTextView</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="circleStatusCell">
+                                                       <string key="name">circleStatusCell</string>
+                                                       <string key="candidateClassName">NSTextFieldCell</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="enableKeychainSyncing">
+                                                       <string key="name">enableKeychainSyncing</string>
+                                                       <string key="candidateClassName">NSButton</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="itemTable">
+                                                       <string key="name">itemTable</string>
+                                                       <string key="candidateClassName">NSTableView</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="itemTableTitle">
+                                                       <string key="name">itemTableTitle</string>
+                                                       <string key="candidateClassName">NSTextFieldCell</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="peerCountCell">
+                                                       <string key="name">peerCountCell</string>
+                                                       <string key="candidateClassName">NSTextFieldCell</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="peerTextList">
+                                                       <string key="name">peerTextList</string>
+                                                       <string key="candidateClassName">NSTextView</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="syncSpinner">
+                                                       <string key="name">syncSpinner</string>
+                                                       <string key="candidateClassName">NSProgressIndicator</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="window">
+                                                       <string key="name">window</string>
+                                                       <string key="candidateClassName">NSWindow</string>
+                                               </object>
+                                       </dictionary>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/KDAppDelegate.h</string>
+                                       </object>
+                               </object>
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">NSDocumentController</string>
+                                       <object class="NSMutableDictionary" key="actions">
+                                               <string key="NS.key.0">_openRecentDocument:</string>
+                                               <string key="NS.object.0">id</string>
+                                       </object>
+                                       <object class="NSMutableDictionary" key="actionInfosByName">
+                                               <string key="NS.key.0">_openRecentDocument:</string>
+                                               <object class="IBActionInfo" key="NS.object.0">
+                                                       <string key="name">_openRecentDocument:</string>
+                                                       <string key="candidateClassName">id</string>
+                                               </object>
+                                       </object>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/NSDocumentController.h</string>
+                                       </object>
+                               </object>
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">NSLayoutConstraint</string>
+                                       <string key="superclassName">NSObject</string>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/NSLayoutConstraint.h</string>
+                                       </object>
+                               </object>
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">NSMovePanel</string>
+                                       <string key="superclassName">NSPanel</string>
+                                       <dictionary class="NSMutableDictionary" key="actions">
+                                               <string key="cancel:">id</string>
+                                               <string key="newDocument:">id</string>
+                                               <string key="ok:">id</string>
+                                       </dictionary>
+                                       <dictionary class="NSMutableDictionary" key="actionInfosByName">
+                                               <object class="IBActionInfo" key="cancel:">
+                                                       <string key="name">cancel:</string>
+                                                       <string key="candidateClassName">id</string>
+                                               </object>
+                                               <object class="IBActionInfo" key="newDocument:">
+                                                       <string key="name">newDocument:</string>
+                                                       <string key="candidateClassName">id</string>
+                                               </object>
+                                               <object class="IBActionInfo" key="ok:">
+                                                       <string key="name">ok:</string>
+                                                       <string key="candidateClassName">id</string>
+                                               </object>
+                                       </dictionary>
+                                       <dictionary class="NSMutableDictionary" key="outlets">
+                                               <string key="_cancelButton">NSButton</string>
+                                               <string key="_moveButton">NSButton</string>
+                                               <string key="_movePanelContentView">NSView</string>
+                                               <string key="_movePopUp">FILocationPopUp</string>
+                                               <string key="_movePopUpLabel">NSTextField</string>
+                                       </dictionary>
+                                       <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <object class="IBToOneOutletInfo" key="_cancelButton">
+                                                       <string key="name">_cancelButton</string>
+                                                       <string key="candidateClassName">NSButton</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_moveButton">
+                                                       <string key="name">_moveButton</string>
+                                                       <string key="candidateClassName">NSButton</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_movePanelContentView">
+                                                       <string key="name">_movePanelContentView</string>
+                                                       <string key="candidateClassName">NSView</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_movePopUp">
+                                                       <string key="name">_movePopUp</string>
+                                                       <string key="candidateClassName">FILocationPopUp</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_movePopUpLabel">
+                                                       <string key="name">_movePopUpLabel</string>
+                                                       <string key="candidateClassName">NSTextField</string>
+                                               </object>
+                                       </dictionary>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/NSMovePanel.h</string>
+                                       </object>
+                               </object>
+                       </array>
+               </object>
+               <int key="IBDocument.localizationMode">0</int>
+               <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
+               <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+               <int key="IBDocument.defaultPropertyAccessControl">3</int>
+               <dictionary class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
+                       <string key="NSMenuCheckmark">{11, 11}</string>
+                       <string key="NSMenuMixedState">{10, 3}</string>
+                       <string key="NSSwitch">{15, 15}</string>
+               </dictionary>
+               <bool key="IBDocument.UseAutolayout">YES</bool>
+       </data>
+</archive>
diff --git a/Keychain/main.m b/Keychain/main.m
new file mode 100644 (file)
index 0000000..a56dff2
--- /dev/null
@@ -0,0 +1,14 @@
+//
+//  main.m
+//  Keychain
+//
+//  Created by J Osborne on 2/13/13.
+//
+//
+
+#import <Cocoa/Cocoa.h>
+
+int main(int argc, char *argv[])
+{
+    return NSApplicationMain(argc, (const char **)argv);
+}
index a6d6c969031ddd3347f82b692927f40ca4f4a60f..1433a392f21a0c8832fa407b637c63438088d14a 100644 (file)
@@ -7,14 +7,28 @@
        objects = {
 
 /* Begin PBXAggregateTarget section */
        objects = {
 
 /* Begin PBXAggregateTarget section */
+               0C6C642915D5ADB500BC68CD /* Security_kexts */ = {
+                       isa = PBXAggregateTarget;
+                       buildConfigurationList = 0C6C642A15D5ADB500BC68CD /* Build configuration list for PBXAggregateTarget "Security_kexts" */;
+                       buildPhases = (
+                       );
+                       dependencies = (
+                               0C6C643015D5AE4C00BC68CD /* PBXTargetDependency */,
+                               0C6C642E15D5ADC900BC68CD /* PBXTargetDependency */,
+                       );
+                       name = Security_kexts;
+                       productName = Security_kexts;
+               };
                182BB598146FE295000BF1F3 /* World */ = {
                        isa = PBXAggregateTarget;
                        buildConfigurationList = 182BB599146FE295000BF1F3 /* Build configuration list for PBXAggregateTarget "World" */;
                        buildPhases = (
                182BB598146FE295000BF1F3 /* World */ = {
                        isa = PBXAggregateTarget;
                        buildConfigurationList = 182BB599146FE295000BF1F3 /* Build configuration list for PBXAggregateTarget "World" */;
                        buildPhases = (
+                               18F2360315CB30EC00060520 /* ShellScript */,
                        );
                        dependencies = (
                                186F779914E5A06500434E1F /* PBXTargetDependency */,
                                186F779B14E5A06800434E1F /* PBXTargetDependency */,
                        );
                        dependencies = (
                                186F779914E5A06500434E1F /* PBXTargetDependency */,
                                186F779B14E5A06800434E1F /* PBXTargetDependency */,
+                               0CFE4BA7167943EF0077AE4F /* PBXTargetDependency */,
                        );
                        name = World;
                        productName = SecurityFramework;
                        );
                        name = World;
                        productName = SecurityFramework;
                        buildPhases = (
                        );
                        dependencies = (
                        buildPhases = (
                        );
                        dependencies = (
+                               721680B3179B4C6C00406BB4 /* PBXTargetDependency */,
+                               722CF218175D602F00BCE0A5 /* PBXTargetDependency */,
+                               521470291697842500DF0DB3 /* PBXTargetDependency */,
+                               18F235FF15CA100300060520 /* PBXTargetDependency */,
                                186F779114E5A00F00434E1F /* PBXTargetDependency */,
                                186F779114E5A00F00434E1F /* PBXTargetDependency */,
+                               0CCEBDBA16C303D8001BD7F6 /* PBXTargetDependency */,
+                               0CFC55E315DDB86500BEC89E /* PBXTargetDependency */,
                                C2432A2515C726B50096DB5B /* PBXTargetDependency */,
                                C2432A2515C726B50096DB5B /* PBXTargetDependency */,
+                               4CB23B90169F59D8003A0131 /* PBXTargetDependency */,
+                               EBB9FFE01682E71F00FF9774 /* PBXTargetDependency */,
                        );
                        name = Security_executables;
                        productName = Other;
                };
                        );
                        name = Security_executables;
                        productName = Other;
                };
+               4CE4729E16D833FD009070D1 /* Security_temporary_UI */ = {
+                       isa = PBXAggregateTarget;
+                       buildConfigurationList = 4CE472C716D833FE009070D1 /* Build configuration list for PBXAggregateTarget "Security_temporary_UI" */;
+                       buildPhases = (
+                       );
+                       dependencies = (
+                               4C797BC916D83A3100C7B586 /* PBXTargetDependency */,
+                               4C797BF116D83A3800C7B586 /* PBXTargetDependency */,
+                       );
+                       name = Security_temporary_UI;
+                       productName = "Security_ temporary_UI";
+               };
 /* End PBXAggregateTarget section */
 
 /* Begin PBXBuildFile section */
 /* End PBXAggregateTarget section */
 
 /* Begin PBXBuildFile section */
-               18270EE714CF292100B05E7F /* libsecurity.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 18D4053B14CE2C1600A2BE4E /* libsecurity.a */; };
+               0C10987616CAAE8200803B8F /* libASN1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1831329914EB2C6D00F0BCAC /* libASN1.a */; };
+               0C4EAE4C1766864F00773425 /* libaks.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 18752C1D16F2837A004E2799 /* libaks.a */; };
+               0C4EAE761766875E00773425 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18270EFD14CF429600B05E7F /* IOKit.framework */; };
+               0C4EAE7717668DDF00773425 /* libsecdRegressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C4EAE721766865000773425 /* libsecdRegressions.a */; };
+               0C4F055E15C9E51A00F9DFD5 /* sslTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C4F055D15C9E51A00F9DFD5 /* sslTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0C6C632A15D1989900BC68CD /* libsecurity_ssl_regressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C6D77CF15C8B66000BB4405 /* libsecurity_ssl_regressions.a */; };
+               0C6C633015D19FF500BC68CD /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 182BB569146F4DCA000BF1F3 /* CoreFoundation.framework */; };
+               0C6D0065177B54CB0095D167 /* com.apple.securityd in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0C6D0064177B54C60095D167 /* com.apple.securityd */; };
+               0CAA7AB516C9A72A00A32C6D /* libsecurity_keychain_regressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CBD50B316C325F000713B6C /* libsecurity_keychain_regressions.a */; };
+               0CBD50DC16C32C8D00713B6C /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C12894015FFECF3008CE3E3 /* libutilities.a */; };
+               0CC3351C16C1ED8000399E53 /* libsecurity.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 18D4053B14CE2C1600A2BE4E /* libsecurity.a */; };
+               0CC3351E16C1ED8000399E53 /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1831329A14EB2C6D00F0BCAC /* libDER.a */; };
+               0CC3351F16C1ED8000399E53 /* libSecItemShimOSX.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 186CDD1E14CA11C700AF9171 /* libSecItemShimOSX.a */; };
+               0CC3352016C1ED8000399E53 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C12894015FFECF3008CE3E3 /* libutilities.a */; };
+               0CC3352116C1ED8000399E53 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF42B8F159E674D00ACACE1 /* Foundation.framework */; };
+               0CC3352216C1ED8000399E53 /* libcorecrypto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C8313C814F5A26500DF7FDC /* libcorecrypto.dylib */; };
+               0CC3352316C1ED8000399E53 /* libSOSRegressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C1288EC15FFE9D7008CE3E3 /* libSOSRegressions.a */; };
+               0CC3352416C1ED8000399E53 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 182BB569146F4DCA000BF1F3 /* CoreFoundation.framework */; };
+               0CC3352616C1ED8000399E53 /* libsecipc_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 18270F6014CF655B00B05E7F /* libsecipc_client.a */; };
+               0CC3352716C1ED8000399E53 /* libSecureObjectSync.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C1288EA15FFE9D7008CE3E3 /* libSecureObjectSync.a */; };
+               0CC3355A16C1EEE700399E53 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CC3355716C1EEE700399E53 /* main.c */; };
+               0CC3356316C1EFBE00399E53 /* libregressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CC3356016C1EF5D00399E53 /* libregressions.a */; };
+               0CCEBDB116C2CFC1001BD7F6 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C6C630E15D193C800BC68CD /* main.c */; };
+               0CCEBDB416C2D026001BD7F6 /* libregressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CC3356016C1EF5D00399E53 /* libregressions.a */; };
+               0CCEBDB616C2E431001BD7F6 /* libsecurityd.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 18270C7D14CE573D00B05E7F /* libsecurityd.a */; };
+               0CCEBDB716C2E6B0001BD7F6 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18270EFB14CF427800B05E7F /* CFNetwork.framework */; };
+               0CCEBDB816C2E6CE001BD7F6 /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 182BB5AD146FEF43000BF1F3 /* libsqlite3.dylib */; };
+               0CCEBDBB16C30924001BD7F6 /* libutilitiesRegressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C12894215FFECF3008CE3E3 /* libutilitiesRegressions.a */; };
                18270EE814CF294500B05E7F /* libsecurityd.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 18270C7D14CE573D00B05E7F /* libsecurityd.a */; };
                18270EE814CF294500B05E7F /* libsecurityd.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 18270C7D14CE573D00B05E7F /* libsecurityd.a */; };
-               18270EF414CF334A00B05E7F /* securityd_rep.defs in Sources */ = {isa = PBXBuildFile; fileRef = 18270EF014CF333400B05E7F /* securityd_rep.defs */; settings = {ATTRIBUTES = (Client, Server, ); }; };
-               18270EF514CF334A00B05E7F /* securityd_req.defs in Sources */ = {isa = PBXBuildFile; fileRef = 18270EF114CF333400B05E7F /* securityd_req.defs */; settings = {ATTRIBUTES = (Server, Client, ); }; };
                18270EF614CF334A00B05E7F /* server.c in Sources */ = {isa = PBXBuildFile; fileRef = 18270EF314CF333400B05E7F /* server.c */; };
                18270EF814CF424900B05E7F /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 182BB569146F4DCA000BF1F3 /* CoreFoundation.framework */; };
                18270EF914CF425100B05E7F /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 182BB5B9146FF0BE000BF1F3 /* libbsm.dylib */; };
                18270EF614CF334A00B05E7F /* server.c in Sources */ = {isa = PBXBuildFile; fileRef = 18270EF314CF333400B05E7F /* server.c */; };
                18270EF814CF424900B05E7F /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 182BB569146F4DCA000BF1F3 /* CoreFoundation.framework */; };
                18270EF914CF425100B05E7F /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 182BB5B9146FF0BE000BF1F3 /* libbsm.dylib */; };
                18270EFC14CF427800B05E7F /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18270EFB14CF427800B05E7F /* CFNetwork.framework */; };
                18270EFE14CF429600B05E7F /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18270EFD14CF429600B05E7F /* IOKit.framework */; };
                18270F0014CF42CA00B05E7F /* libcorecrypto.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 18270EFF14CF42CA00B05E7F /* libcorecrypto.a */; };
                18270EFC14CF427800B05E7F /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18270EFB14CF427800B05E7F /* CFNetwork.framework */; };
                18270EFE14CF429600B05E7F /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18270EFD14CF429600B05E7F /* IOKit.framework */; };
                18270F0014CF42CA00B05E7F /* libcorecrypto.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 18270EFF14CF42CA00B05E7F /* libcorecrypto.a */; };
-               18270F3C14CF44C400B05E7F /* debugging.c in Sources */ = {isa = PBXBuildFile; fileRef = 18270F3A14CF44C400B05E7F /* debugging.c */; };
-               18270F4114CF465700B05E7F /* client.c in Sources */ = {isa = PBXBuildFile; fileRef = 18270EEC14CF333400B05E7F /* client.c */; };
                18270F6114CF656E00B05E7F /* libsecipc_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 18270F6014CF655B00B05E7F /* libsecipc_client.a */; };
                18270F6114CF656E00B05E7F /* libsecipc_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 18270F6014CF655B00B05E7F /* libsecipc_client.a */; };
+               182A191115D09AFF006AB103 /* connection.c in Sources */ = {isa = PBXBuildFile; fileRef = 182A191015D09AFF006AB103 /* connection.c */; };
                182BB22A146F068B000BF1F3 /* iToolsTrustedApps.plist in Resources */ = {isa = PBXBuildFile; fileRef = 182BB229146F068B000BF1F3 /* iToolsTrustedApps.plist */; };
                182BB3C5146F1DCB000BF1F3 /* sd_cspdl_common.mdsinfo in Resources */ = {isa = PBXBuildFile; fileRef = 182BB3C4146F1DCB000BF1F3 /* sd_cspdl_common.mdsinfo */; };
                182BB41B146F2533000BF1F3 /* libsecurity_apple_csp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1879B5C6146DE6C8007E536C /* libsecurity_apple_csp.a */; };
                182BB22A146F068B000BF1F3 /* iToolsTrustedApps.plist in Resources */ = {isa = PBXBuildFile; fileRef = 182BB229146F068B000BF1F3 /* iToolsTrustedApps.plist */; };
                182BB3C5146F1DCB000BF1F3 /* sd_cspdl_common.mdsinfo in Resources */ = {isa = PBXBuildFile; fileRef = 182BB3C4146F1DCB000BF1F3 /* sd_cspdl_common.mdsinfo */; };
                182BB41B146F2533000BF1F3 /* libsecurity_apple_csp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1879B5C6146DE6C8007E536C /* libsecurity_apple_csp.a */; };
                182BB590146FE125000BF1F3 /* libsecurity_cdsa_utilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1879B55A146DE227007E536C /* libsecurity_cdsa_utilities.a */; };
                182BB591146FE12F000BF1F3 /* libsecurity_utilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1879B538146DDBE5007E536C /* libsecurity_utilities.a */; };
                182BB592146FE1D7000BF1F3 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 182BB569146F4DCA000BF1F3 /* CoreFoundation.framework */; };
                182BB590146FE125000BF1F3 /* libsecurity_cdsa_utilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1879B55A146DE227007E536C /* libsecurity_cdsa_utilities.a */; };
                182BB591146FE12F000BF1F3 /* libsecurity_utilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1879B538146DDBE5007E536C /* libsecurity_utilities.a */; };
                182BB592146FE1D7000BF1F3 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 182BB569146F4DCA000BF1F3 /* CoreFoundation.framework */; };
-               182BB594146FE1EE000BF1F3 /* libantlr2c++.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 182BB593146FE1ED000BF1F3 /* libantlr2c++.a */; };
-               182BB597146FE286000BF1F3 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1807384B146D0D4E00F05C24 /* Security.framework */; };
-               182BB5A8146FE6D4000BF1F3 /* security_exports.s in Sources */ = {isa = PBXBuildFile; fileRef = 182BB5A7146FE6D4000BF1F3 /* security_exports.s */; };
                182BB5AA146FEE50000BF1F3 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 182BB569146F4DCA000BF1F3 /* CoreFoundation.framework */; };
                182BB5AC146FEF15000BF1F3 /* libpam.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 182BB5AB146FEF14000BF1F3 /* libpam.dylib */; };
                182BB5AE146FEF43000BF1F3 /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 182BB5AD146FEF43000BF1F3 /* libsqlite3.dylib */; };
                182BB5AA146FEE50000BF1F3 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 182BB569146F4DCA000BF1F3 /* CoreFoundation.framework */; };
                182BB5AC146FEF15000BF1F3 /* libpam.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 182BB5AB146FEF14000BF1F3 /* libpam.dylib */; };
                182BB5AE146FEF43000BF1F3 /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 182BB5AD146FEF43000BF1F3 /* libsqlite3.dylib */; };
-               182BB5B0146FEFE2000BF1F3 /* libstdc++.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 182BB5AF146FEFE2000BF1F3 /* libstdc++.dylib */; };
                182BB5B2146FF039000BF1F3 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 182BB5B1146FF039000BF1F3 /* libz.dylib */; };
                182BB5B4146FF04C000BF1F3 /* libxar.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 182BB5B3146FF04C000BF1F3 /* libxar.dylib */; };
                182BB5B6146FF090000BF1F3 /* libauto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 182BB5B5146FF08F000BF1F3 /* libauto.dylib */; };
                182BB5B2146FF039000BF1F3 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 182BB5B1146FF039000BF1F3 /* libz.dylib */; };
                182BB5B4146FF04C000BF1F3 /* libxar.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 182BB5B3146FF04C000BF1F3 /* libxar.dylib */; };
                182BB5B6146FF090000BF1F3 /* libauto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 182BB5B5146FF08F000BF1F3 /* libauto.dylib */; };
                182BB5BB146FF62F000BF1F3 /* libsecurity_comcryption.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1879B676146DE75E007E536C /* libsecurity_comcryption.a */; };
                1831329B14EB2C6D00F0BCAC /* libASN1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1831329914EB2C6D00F0BCAC /* libASN1.a */; };
                1831329C14EB2C6D00F0BCAC /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1831329A14EB2C6D00F0BCAC /* libDER.a */; };
                182BB5BB146FF62F000BF1F3 /* libsecurity_comcryption.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1879B676146DE75E007E536C /* libsecurity_comcryption.a */; };
                1831329B14EB2C6D00F0BCAC /* libASN1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1831329914EB2C6D00F0BCAC /* libASN1.a */; };
                1831329C14EB2C6D00F0BCAC /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1831329A14EB2C6D00F0BCAC /* libDER.a */; };
+               18363C1417026084002D5C1C /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18270EFD14CF429600B05E7F /* IOKit.framework */; };
                1844605F146DE93E00B12992 /* csp_capabilities.mdsinfo in Resources */ = {isa = PBXBuildFile; fileRef = 1844605B146DE93E00B12992 /* csp_capabilities.mdsinfo */; };
                18446060146DE93E00B12992 /* csp_capabilities_common.mds in Resources */ = {isa = PBXBuildFile; fileRef = 1844605C146DE93E00B12992 /* csp_capabilities_common.mds */; };
                18446061146DE93E00B12992 /* csp_common.mdsinfo in Resources */ = {isa = PBXBuildFile; fileRef = 1844605D146DE93E00B12992 /* csp_common.mdsinfo */; };
                1844605F146DE93E00B12992 /* csp_capabilities.mdsinfo in Resources */ = {isa = PBXBuildFile; fileRef = 1844605B146DE93E00B12992 /* csp_capabilities.mdsinfo */; };
                18446060146DE93E00B12992 /* csp_capabilities_common.mds in Resources */ = {isa = PBXBuildFile; fileRef = 1844605C146DE93E00B12992 /* csp_capabilities_common.mds */; };
                18446061146DE93E00B12992 /* csp_common.mdsinfo in Resources */ = {isa = PBXBuildFile; fileRef = 1844605D146DE93E00B12992 /* csp_common.mdsinfo */; };
                1879B546146DE192007E536C /* libsecurity_utilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1879B538146DDBE5007E536C /* libsecurity_utilities.a */; };
                1879B570146DE2E6007E536C /* libsecurity_cdsa_utils.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1879B54F146DE212007E536C /* libsecurity_cdsa_utils.a */; };
                1879B571146DE2FF007E536C /* libsecurity_cssm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1879B565146DE244007E536C /* libsecurity_cssm.a */; };
                1879B546146DE192007E536C /* libsecurity_utilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1879B538146DDBE5007E536C /* libsecurity_utilities.a */; };
                1879B570146DE2E6007E536C /* libsecurity_cdsa_utils.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1879B54F146DE212007E536C /* libsecurity_cdsa_utils.a */; };
                1879B571146DE2FF007E536C /* libsecurity_cssm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1879B565146DE244007E536C /* libsecurity_cssm.a */; };
+               187A05B1170393FF0038C158 /* libaks.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 18752C1D16F2837A004E2799 /* libaks.a */; };
+               187D6B9315D435BD00E27494 /* authorization.buttons.strings in Resources */ = {isa = PBXBuildFile; fileRef = 187D6B8F15D4359F00E27494 /* authorization.buttons.strings */; };
+               187D6B9415D435C700E27494 /* authorization.prompts.strings in Resources */ = {isa = PBXBuildFile; fileRef = 187D6B9115D4359F00E27494 /* authorization.prompts.strings */; };
+               187D6B9715D438AD00E27494 /* authorization.plist in Copy authorization.plist */ = {isa = PBXBuildFile; fileRef = 187D6B9515D436BF00E27494 /* authorization.plist */; };
+               187D6B9815D4476D00E27494 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18270EFD14CF429600B05E7F /* IOKit.framework */; };
                1885B45214D9AB8100519375 /* libASN1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1885B3F914D8D9B100519375 /* libASN1.a */; };
                188AD8DC1471FE3E0081C619 /* FDELocalizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 188AD8D81471FE3D0081C619 /* FDELocalizable.strings */; };
                188AD8DD1471FE3E0081C619 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 188AD8DA1471FE3D0081C619 /* InfoPlist.strings */; };
                1885B45214D9AB8100519375 /* libASN1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1885B3F914D8D9B100519375 /* libASN1.a */; };
                188AD8DC1471FE3E0081C619 /* FDELocalizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 188AD8D81471FE3D0081C619 /* FDELocalizable.strings */; };
                188AD8DD1471FE3E0081C619 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 188AD8DA1471FE3D0081C619 /* InfoPlist.strings */; };
+               189757871700CF4C00672567 /* libaks.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 18752C1D16F2837A004E2799 /* libaks.a */; };
+               18A5493315EFD3690059E6DC /* dummy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18A5493115EFD2F40059E6DC /* dummy.cpp */; };
                18AD56A414CDE7BE008233F2 /* libSecItemShimOSX.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 186CDD1E14CA11C700AF9171 /* libSecItemShimOSX.a */; };
                18B647EC14D9F20500F538BF /* oidsalg.h in Headers */ = {isa = PBXBuildFile; fileRef = 18B647E814D9EB6300F538BF /* oidsalg.h */; settings = {ATTRIBUTES = (Public, ); }; };
                18B647ED14D9F20F00F538BF /* oidsattr.h in Headers */ = {isa = PBXBuildFile; fileRef = 18B647EA14D9EE4300F538BF /* oidsattr.h */; settings = {ATTRIBUTES = (Public, ); }; };
                18BBC7361471F5A300F2B224 /* SecExternalSourceTransform.h in Headers */ = {isa = PBXBuildFile; fileRef = 18BBC7351471F5A300F2B224 /* SecExternalSourceTransform.h */; settings = {ATTRIBUTES = (Private, ); }; };
                18BEB19A14CF7F8100C8BD36 /* com.apple.secd.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 18BEB19614CF74C100C8BD36 /* com.apple.secd.plist */; };
                18AD56A414CDE7BE008233F2 /* libSecItemShimOSX.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 186CDD1E14CA11C700AF9171 /* libSecItemShimOSX.a */; };
                18B647EC14D9F20500F538BF /* oidsalg.h in Headers */ = {isa = PBXBuildFile; fileRef = 18B647E814D9EB6300F538BF /* oidsalg.h */; settings = {ATTRIBUTES = (Public, ); }; };
                18B647ED14D9F20F00F538BF /* oidsattr.h in Headers */ = {isa = PBXBuildFile; fileRef = 18B647EA14D9EE4300F538BF /* oidsattr.h */; settings = {ATTRIBUTES = (Public, ); }; };
                18BBC7361471F5A300F2B224 /* SecExternalSourceTransform.h in Headers */ = {isa = PBXBuildFile; fileRef = 18BBC7351471F5A300F2B224 /* SecExternalSourceTransform.h */; settings = {ATTRIBUTES = (Private, ); }; };
                18BEB19A14CF7F8100C8BD36 /* com.apple.secd.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 18BEB19614CF74C100C8BD36 /* com.apple.secd.plist */; };
+               18CD682717272EBC005345FB /* libaks.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 18752C1D16F2837A004E2799 /* libaks.a */; };
+               18CD684E17272EE2005345FB /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18270EFD14CF429600B05E7F /* IOKit.framework */; };
+               18CFEE8915DEE2C600E3F2A3 /* com.apple.authd.sb in Copy sandbox profile */ = {isa = PBXBuildFile; fileRef = 18CFEE8715DEE25200E3F2A3 /* com.apple.authd.sb */; };
+               18D6803B16B768F700DF6D2E /* com.apple.authd in Copy asl module */ = {isa = PBXBuildFile; fileRef = 18D6803916B768D500DF6D2E /* com.apple.authd */; };
+               18F2352115C9FA3C00060520 /* agent.c in Sources */ = {isa = PBXBuildFile; fileRef = 18F234F915C9FA3B00060520 /* agent.c */; };
+               18F2352215C9FA3C00060520 /* authdb.c in Sources */ = {isa = PBXBuildFile; fileRef = 18F234FB15C9FA3B00060520 /* authdb.c */; };
+               18F2352315C9FA3C00060520 /* authitems.c in Sources */ = {isa = PBXBuildFile; fileRef = 18F234FD15C9FA3B00060520 /* authitems.c */; };
+               18F2352415C9FA3C00060520 /* authtoken.c in Sources */ = {isa = PBXBuildFile; fileRef = 18F234FF15C9FA3B00060520 /* authtoken.c */; };
+               18F2352515C9FA3C00060520 /* authutilities.c in Sources */ = {isa = PBXBuildFile; fileRef = 18F2350215C9FA3B00060520 /* authutilities.c */; };
+               18F2352615C9FA3C00060520 /* ccaudit.c in Sources */ = {isa = PBXBuildFile; fileRef = 18F2350415C9FA3B00060520 /* ccaudit.c */; };
+               18F2352715C9FA3C00060520 /* crc.c in Sources */ = {isa = PBXBuildFile; fileRef = 18F2350615C9FA3B00060520 /* crc.c */; };
+               18F2352815C9FA3C00060520 /* credential.c in Sources */ = {isa = PBXBuildFile; fileRef = 18F2350815C9FA3B00060520 /* credential.c */; };
+               18F2352915C9FA3C00060520 /* debugging.c in Sources */ = {isa = PBXBuildFile; fileRef = 18F2350A15C9FA3B00060520 /* debugging.c */; };
+               18F2352B15C9FA3C00060520 /* engine.c in Sources */ = {isa = PBXBuildFile; fileRef = 18F2350F15C9FA3B00060520 /* engine.c */; };
+               18F2352C15C9FA3C00060520 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 18F2351115C9FA3B00060520 /* main.c */; };
+               18F2352D15C9FA3C00060520 /* mechanism.c in Sources */ = {isa = PBXBuildFile; fileRef = 18F2351215C9FA3B00060520 /* mechanism.c */; };
+               18F2352E15C9FA3C00060520 /* object.c in Sources */ = {isa = PBXBuildFile; fileRef = 18F2351415C9FA3C00060520 /* object.c */; };
+               18F2352F15C9FA3C00060520 /* process.c in Sources */ = {isa = PBXBuildFile; fileRef = 18F2351615C9FA3C00060520 /* process.c */; };
+               18F2353015C9FA3C00060520 /* rule.c in Sources */ = {isa = PBXBuildFile; fileRef = 18F2351815C9FA3C00060520 /* rule.c */; };
+               18F2353215C9FA3C00060520 /* server.c in Sources */ = {isa = PBXBuildFile; fileRef = 18F2351D15C9FA3C00060520 /* server.c */; };
+               18F2353315C9FA3C00060520 /* session.c in Sources */ = {isa = PBXBuildFile; fileRef = 18F2351F15C9FA3C00060520 /* session.c */; };
+               18F2353515C9FDB700060520 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 182BB569146F4DCA000BF1F3 /* CoreFoundation.framework */; };
+               18F2353615C9FDD200060520 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF42BB515A3947F00ACACE1 /* Security.framework */; };
+               18F2353715C9FDE400060520 /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 182BB5B9146FF0BE000BF1F3 /* libbsm.dylib */; };
+               18F2353815C9FDEF00060520 /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 182BB5AD146FEF43000BF1F3 /* libsqlite3.dylib */; };
+               18F2360115CAF41200060520 /* libsecurity_codesigning.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 18F2360015CAF41100060520 /* libsecurity_codesigning.a */; };
                18FE68021471A42900A2CBE3 /* SecDigestTransform.h in Headers */ = {isa = PBXBuildFile; fileRef = 182BB3A3146F1BEC000BF1F3 /* SecDigestTransform.h */; settings = {ATTRIBUTES = (Public, ); }; };
                18FE68031471A42900A2CBE3 /* SecReadTransform.h in Headers */ = {isa = PBXBuildFile; fileRef = 182BB3A4146F1BEC000BF1F3 /* SecReadTransform.h */; settings = {ATTRIBUTES = (Public, ); }; };
                18FE68041471A42900A2CBE3 /* SecTransform.h in Headers */ = {isa = PBXBuildFile; fileRef = 182BB3A5146F1BEC000BF1F3 /* SecTransform.h */; settings = {ATTRIBUTES = (Public, ); }; };
                18FE68021471A42900A2CBE3 /* SecDigestTransform.h in Headers */ = {isa = PBXBuildFile; fileRef = 182BB3A3146F1BEC000BF1F3 /* SecDigestTransform.h */; settings = {ATTRIBUTES = (Public, ); }; };
                18FE68031471A42900A2CBE3 /* SecReadTransform.h in Headers */ = {isa = PBXBuildFile; fileRef = 182BB3A4146F1BEC000BF1F3 /* SecReadTransform.h */; settings = {ATTRIBUTES = (Public, ); }; };
                18FE68041471A42900A2CBE3 /* SecTransform.h in Headers */ = {isa = PBXBuildFile; fileRef = 182BB3A5146F1BEC000BF1F3 /* SecTransform.h */; settings = {ATTRIBUTES = (Public, ); }; };
                18FE685D1471A46600A2CBE3 /* SecAssessment.h in Headers */ = {isa = PBXBuildFile; fileRef = 18446194146E9A8F00B12992 /* SecAssessment.h */; settings = {ATTRIBUTES = (Private, ); }; };
                18FE685E1471A46600A2CBE3 /* SecBasePriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 182BB1B3146EAD5D000BF1F3 /* SecBasePriv.h */; settings = {ATTRIBUTES = (Private, ); }; };
                18FE685F1471A46600A2CBE3 /* SecCertificateBundle.h in Headers */ = {isa = PBXBuildFile; fileRef = 182BB1B4146EAD5D000BF1F3 /* SecCertificateBundle.h */; settings = {ATTRIBUTES = (Private, ); }; };
                18FE685D1471A46600A2CBE3 /* SecAssessment.h in Headers */ = {isa = PBXBuildFile; fileRef = 18446194146E9A8F00B12992 /* SecAssessment.h */; settings = {ATTRIBUTES = (Private, ); }; };
                18FE685E1471A46600A2CBE3 /* SecBasePriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 182BB1B3146EAD5D000BF1F3 /* SecBasePriv.h */; settings = {ATTRIBUTES = (Private, ); }; };
                18FE685F1471A46600A2CBE3 /* SecCertificateBundle.h in Headers */ = {isa = PBXBuildFile; fileRef = 182BB1B4146EAD5D000BF1F3 /* SecCertificateBundle.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               18FE68601471A46600A2CBE3 /* SecCertificateInternalP.h in Headers */ = {isa = PBXBuildFile; fileRef = 182BB1CD146EAD5D000BF1F3 /* SecCertificateInternalP.h */; settings = {ATTRIBUTES = (Private, ); }; };
                18FE68611471A46600A2CBE3 /* SecCertificatePriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 182BB1B5146EAD5D000BF1F3 /* SecCertificatePriv.h */; settings = {ATTRIBUTES = (Private, ); }; };
                18FE68621471A46600A2CBE3 /* SecCertificateRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 182BB1B6146EAD5D000BF1F3 /* SecCertificateRequest.h */; settings = {ATTRIBUTES = (Private, ); }; };
                18FE68631471A46600A2CBE3 /* SecCmsBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 182BB383146F14D2000BF1F3 /* SecCmsBase.h */; settings = {ATTRIBUTES = (Private, ); }; };
                18FE68611471A46600A2CBE3 /* SecCertificatePriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 182BB1B5146EAD5D000BF1F3 /* SecCertificatePriv.h */; settings = {ATTRIBUTES = (Private, ); }; };
                18FE68621471A46600A2CBE3 /* SecCertificateRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 182BB1B6146EAD5D000BF1F3 /* SecCertificateRequest.h */; settings = {ATTRIBUTES = (Private, ); }; };
                18FE68631471A46600A2CBE3 /* SecCmsBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 182BB383146F14D2000BF1F3 /* SecCmsBase.h */; settings = {ATTRIBUTES = (Private, ); }; };
                18FE688B1471A46700A2CBE3 /* SecureTransportPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 182BB372146F13BB000BF1F3 /* SecureTransportPriv.h */; settings = {ATTRIBUTES = (Private, ); }; };
                18FE688C1471A46700A2CBE3 /* TrustSettingsSchema.h in Headers */ = {isa = PBXBuildFile; fileRef = 182BB1C8146EAD5D000BF1F3 /* TrustSettingsSchema.h */; settings = {ATTRIBUTES = (Private, ); }; };
                18FE688D1471A46700A2CBE3 /* X509Templates.h in Headers */ = {isa = PBXBuildFile; fileRef = 1844609E146DFCB700B12992 /* X509Templates.h */; settings = {ATTRIBUTES = (Private, ); }; };
                18FE688B1471A46700A2CBE3 /* SecureTransportPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 182BB372146F13BB000BF1F3 /* SecureTransportPriv.h */; settings = {ATTRIBUTES = (Private, ); }; };
                18FE688C1471A46700A2CBE3 /* TrustSettingsSchema.h in Headers */ = {isa = PBXBuildFile; fileRef = 182BB1C8146EAD5D000BF1F3 /* TrustSettingsSchema.h */; settings = {ATTRIBUTES = (Private, ); }; };
                18FE688D1471A46700A2CBE3 /* X509Templates.h in Headers */ = {isa = PBXBuildFile; fileRef = 1844609E146DFCB700B12992 /* X509Templates.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               395E7CEE16C64EA500CD82A4 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 395E7CED16C64EA500CD82A4 /* SystemConfiguration.framework */; };
+               39BFB04516D304DE0022564B /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 395E7CED16C64EA500CD82A4 /* SystemConfiguration.framework */; };
+               4A5C1790161A9DFB00ABF784 /* authd_private.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 18F2351A15C9FA3C00060520 /* authd_private.h */; };
+               4AD6F6F91651D2A600DB4CE6 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF42B8F159E674D00ACACE1 /* Foundation.framework */; };
+               4C01DF14164C3E7C006798CD /* libSecureObjectSync.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C1288EA15FFE9D7008CE3E3 /* libSecureObjectSync.a */; };
+               4C2505B716D2DF9F002CE025 /* Icon.icns in Resources */ = {isa = PBXBuildFile; fileRef = 4C2505B616D2DF9F002CE025 /* Icon.icns */; };
+               4C328D301778EC4F0015EED1 /* AOSUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C328D2F1778EC4F0015EED1 /* AOSUI.framework */; };
+               4C49390D16E51ACE00CE110C /* com.apple.security.keychain-circle-notification.plist in Resources */ = {isa = PBXBuildFile; fileRef = 4C49390C16E51ACE00CE110C /* com.apple.security.keychain-circle-notification.plist */; };
+               4C49390F16E51FC700CE110C /* com.apple.security.keychain-circle-notification.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4C49390C16E51ACE00CE110C /* com.apple.security.keychain-circle-notification.plist */; };
+               4C5DD46A17A5E5D000696A79 /* KNPersistantState.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C5DD44317A5E31900696A79 /* KNPersistantState.m */; };
+               4C5DD46C17A5F67300696A79 /* AppleSystemInfo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C5DD46B17A5F67300696A79 /* AppleSystemInfo.framework */; };
+               4C7D453D17BEE69B00DDD88F /* NSString+compactDescription.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C7D453C17BEE69B00DDD88F /* NSString+compactDescription.m */; };
+               4C7D456817BEED0400DDD88F /* NSDictionary+compactDescription.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C7D456517BEE6B700DDD88F /* NSDictionary+compactDescription.m */; };
+               4C7D456917BEED1400DDD88F /* NSSet+compactDescription.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C7D456717BEE6B700DDD88F /* NSSet+compactDescription.m */; };
+               4C7D8765160A74C400D041E3 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C12894015FFECF3008CE3E3 /* libutilities.a */; };
                4C8313C914F5A26500DF7FDC /* libcorecrypto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C8313C814F5A26500DF7FDC /* libcorecrypto.dylib */; };
                4C8313C914F5A26500DF7FDC /* libcorecrypto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C8313C814F5A26500DF7FDC /* libcorecrypto.dylib */; };
+               4C85DEDA16DBD5BF00ED8D47 /* KDCirclePeer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C85DED916DBD5BF00ED8D47 /* KDCirclePeer.m */; };
+               4C85DEDB16DBD5BF00ED8D47 /* KDCirclePeer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C85DED916DBD5BF00ED8D47 /* KDCirclePeer.m */; };
+               4C8D8651177A752D0019A804 /* libsecipc_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 18270F6014CF655B00B05E7F /* libsecipc_client.a */; };
+               4C96F76016D5462F00D3B39D /* KDSecCircle.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C96F73916D5372C00D3B39D /* KDSecCircle.m */; };
+               4C96F76216D54C9600D3B39D /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C96F76116D54C9600D3B39D /* CoreFoundation.framework */; };
+               4C96F7C216D6DF8400D3B39D /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5214700716977CB800DF0DB3 /* Cocoa.framework */; };
+               4C96F7C816D6DF8400D3B39D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 4C96F7C616D6DF8400D3B39D /* InfoPlist.strings */; };
+               4C96F7CA16D6DF8400D3B39D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C96F7C916D6DF8400D3B39D /* main.m */; };
+               4C96F7CE16D6DF8400D3B39D /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 4C96F7CC16D6DF8400D3B39D /* Credits.rtf */; };
+               4C96F7D116D6DF8400D3B39D /* KNAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C96F7D016D6DF8400D3B39D /* KNAppDelegate.m */; };
+               4C96F7D416D6DF8400D3B39D /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C96F7D216D6DF8400D3B39D /* MainMenu.xib */; };
+               4C97761E17BEB23E0002BFE4 /* AOSAccounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C97761D17BEB23E0002BFE4 /* AOSAccounts.framework */; };
+               4CAEACCC16D6FBF600263776 /* KDSecCircle.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C96F73916D5372C00D3B39D /* KDSecCircle.m */; };
+               4CAEACCD16D6FC7600263776 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF42BB515A3947F00ACACE1 /* Security.framework */; };
+               4CB23B47169F5873003A0131 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 182BB569146F4DCA000BF1F3 /* CoreFoundation.framework */; };
+               4CB23B4C169F5873003A0131 /* security2.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4CB23B4B169F5873003A0131 /* security2.1 */; };
+               4CB23B81169F58DE003A0131 /* security_tool_commands.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CB23B80169F58DE003A0131 /* security_tool_commands.c */; };
+               4CB23B89169F5990003A0131 /* libSecurityTool.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CB23B76169F5873003A0131 /* libSecurityTool.a */; };
+               4CB23B8A169F599A003A0131 /* libSecurityCommands.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CB23B78169F5873003A0131 /* libSecurityCommands.a */; };
+               4CB23B8B169F599A003A0131 /* libSOSCommands.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CB23B7A169F5873003A0131 /* libSOSCommands.a */; };
+               4CB23B8C169F59AD003A0131 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C12894015FFECF3008CE3E3 /* libutilities.a */; };
+               4CB86AF0167A6FF300F46643 /* SOSCircle.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4CB86AE6167A6FF200F46643 /* SOSCircle.h */; };
+               4CB86AF1167A6FF300F46643 /* SOSCloudCircle.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4CB86AE7167A6FF200F46643 /* SOSCloudCircle.h */; };
+               4CB86AF2167A6FF300F46643 /* SOSCloudCircleInternal.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4CB86AE8167A6FF200F46643 /* SOSCloudCircleInternal.h */; };
+               4CB86AF3167A6FF300F46643 /* SOSEngine.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4CB86AE9167A6FF200F46643 /* SOSEngine.h */; };
+               4CB86AF4167A6FF300F46643 /* SOSFullPeerInfo.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4CB86AEA167A6FF300F46643 /* SOSFullPeerInfo.h */; };
+               4CB86AF5167A6FF300F46643 /* SOSInternal.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4CB86AEB167A6FF300F46643 /* SOSInternal.h */; };
+               4CB86AF6167A6FF300F46643 /* SOSPeer.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4CB86AEC167A6FF300F46643 /* SOSPeer.h */; };
+               4CB86AF7167A6FF300F46643 /* SOSPeerInfo.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4CB86AED167A6FF300F46643 /* SOSPeerInfo.h */; };
+               4CB86AF8167A6FF300F46643 /* SOSTransport.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4CB86AEE167A6FF300F46643 /* SOSTransport.h */; };
+               4CB86AFB167A8F2200F46643 /* SOSAccount.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4CB86AFA167A8F2200F46643 /* SOSAccount.h */; };
+               4CC7A7B416CC2A85003E10C1 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5214700716977CB800DF0DB3 /* Cocoa.framework */; };
+               4CC7A7BA16CC2A85003E10C1 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 4CC7A7B816CC2A85003E10C1 /* InfoPlist.strings */; };
+               4CC7A7BC16CC2A85003E10C1 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CC7A7BB16CC2A85003E10C1 /* main.m */; };
+               4CC7A7C016CC2A85003E10C1 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 4CC7A7BE16CC2A85003E10C1 /* Credits.rtf */; };
+               4CC7A7C316CC2A85003E10C1 /* KDAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CC7A7C216CC2A85003E10C1 /* KDAppDelegate.m */; };
+               4CC7A7C616CC2A85003E10C1 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4CC7A7C416CC2A85003E10C1 /* MainMenu.xib */; };
+               4CC7A7F316CC2B0A003E10C1 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CC7A7F216CC2B0A003E10C1 /* Security.framework */; };
+               4CC7A7F616CD99E2003E10C1 /* KDSecItems.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CC7A7F516CD95D3003E10C1 /* KDSecItems.m */; };
+               4CC8DEA416DC1AC800462517 /* libSecOtrOSX.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C1288F215FFE9D7008CE3E3 /* libSecOtrOSX.a */; };
+               4CD1980D16DD3BDF00A9E8FD /* NSArray+mapWithBlock.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD1980C16DD3BDF00A9E8FD /* NSArray+mapWithBlock.m */; };
+               4CD1980E16DD3BDF00A9E8FD /* NSArray+mapWithBlock.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD1980C16DD3BDF00A9E8FD /* NSArray+mapWithBlock.m */; };
+               4CFE1CB916DD4B9C0026E900 /* CloudKeychain.icns in Resources */ = {isa = PBXBuildFile; fileRef = 4CFE1CB816DD4B9C0026E900 /* CloudKeychain.icns */; };
+               5208BF4F16A0993C0062DDC5 /* libsecurity.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 18D4053B14CE2C1600A2BE4E /* libsecurity.a */; };
+               5208C0D716A0C96F0062DDC5 /* libSecureObjectSync.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C1288EA15FFE9D7008CE3E3 /* libSecureObjectSync.a */; };
+               52146FDB1697673900DF0DB3 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C12894015FFECF3008CE3E3 /* libutilities.a */; };
+               5214701216977CB800DF0DB3 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5214701016977CB800DF0DB3 /* InfoPlist.strings */; };
+               5214701D16977D9500DF0DB3 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C12894015FFECF3008CE3E3 /* libutilities.a */; };
+               5214701E16977DA700DF0DB3 /* libCloudKeychainProxy.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C01DE32164C3793006798CD /* libCloudKeychainProxy.a */; };
+               5214702216977E7D00DF0DB3 /* CloudKeychainProxy-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5214700F16977CB800DF0DB3 /* CloudKeychainProxy-Info.plist */; };
+               521470261697800500DF0DB3 /* com.apple.security.cloudkeychainproxy.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 5214702516977FEC00DF0DB3 /* com.apple.security.cloudkeychainproxy.plist */; };
+               5214702A1697855800DF0DB3 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5214700C16977CB800DF0DB3 /* Foundation.framework */; };
+               5241C60D16DC1BA100DB5C6F /* libSecOtrOSX.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C1288F215FFE9D7008CE3E3 /* libSecOtrOSX.a */; };
+               52669053169D181900ED8231 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF42BB515A3947F00ACACE1 /* Security.framework */; };
+               529E948C169E29450000AC9B /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18FE67EA1471A3AA00A2CBE3 /* Security.framework */; };
+               529E948D169E29470000AC9B /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18FE67EA1471A3AA00A2CBE3 /* Security.framework */; };
                52AEA489153C778C005AFC59 /* tsaSupportPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 52AEA484153C7581005AFC59 /* tsaSupportPriv.h */; settings = {ATTRIBUTES = (Private, ); }; };
                52B006C015238F76005D4556 /* TimeStampingPrefs.plist in Resources */ = {isa = PBXBuildFile; fileRef = 52B006BF15238F76005D4556 /* TimeStampingPrefs.plist */; };
                52B5A9C21519330300664F11 /* tsaSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B5A9C01519330300664F11 /* tsaSupport.h */; settings = {ATTRIBUTES = (Private, ); }; };
                52B5A9C31519330300664F11 /* tsaTemplates.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B5A9C11519330300664F11 /* tsaTemplates.h */; settings = {ATTRIBUTES = (Private, ); }; };
                52AEA489153C778C005AFC59 /* tsaSupportPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 52AEA484153C7581005AFC59 /* tsaSupportPriv.h */; settings = {ATTRIBUTES = (Private, ); }; };
                52B006C015238F76005D4556 /* TimeStampingPrefs.plist in Resources */ = {isa = PBXBuildFile; fileRef = 52B006BF15238F76005D4556 /* TimeStampingPrefs.plist */; };
                52B5A9C21519330300664F11 /* tsaSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B5A9C01519330300664F11 /* tsaSupport.h */; settings = {ATTRIBUTES = (Private, ); }; };
                52B5A9C31519330300664F11 /* tsaTemplates.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B5A9C11519330300664F11 /* tsaTemplates.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               52C3D236169B56860091D9D3 /* ckdmain.m in Sources */ = {isa = PBXBuildFile; fileRef = 52C3D235169B56860091D9D3 /* ckdmain.m */; };
+               52CD052316A0E24900218387 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF42BB515A3947F00ACACE1 /* Security.framework */; };
+               52CD052416A0E2A000218387 /* libcorecrypto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C8313C814F5A26500DF7FDC /* libcorecrypto.dylib */; };
+               532847791785076B009118DC /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5328475117850741009118DC /* Localizable.strings */; };
+               721680A6179B40F600406BB4 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72756C9E175D566800F52070 /* CoreFoundation.framework */; };
+               721680A9179B40F600406BB4 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 721680A8179B40F600406BB4 /* main.c */; };
+               721680AF179B4C3200406BB4 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1807384B146D0D4E00F05C24 /* Security.framework */; };
+               721680BE179B509900406BB4 /* com.apple.iCloudStats.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 721680BD179B4F9100406BB4 /* com.apple.iCloudStats.plist */; };
+               72756C31175D48C100F52070 /* cloud_keychain_diagnose.c in Sources */ = {isa = PBXBuildFile; fileRef = 72756C30175D48C100F52070 /* cloud_keychain_diagnose.c */; };
+               72CC327B175D6E0A00217455 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72756C9E175D566800F52070 /* CoreFoundation.framework */; };
+               72CC327C175D6E1800217455 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 722CF215175D5E5000BCE0A5 /* Security.framework */; };
+               AAF3DCCB1666D03300376593 /* libsecurity_utilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 18F235F715CA0D9D00060520 /* libsecurity_utilities.a */; };
+               BE8C5F0A16F7CE450074CF86 /* framework.sb in Resources */ = {isa = PBXBuildFile; fileRef = BE8C5F0916F7CE450074CF86 /* framework.sb */; };
+               BEC3A76816F79497003E5634 /* SecTaskPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = BEC3A76716F79497003E5634 /* SecTaskPriv.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C288A0891505796F00E773B7 /* libOpenScriptingUtil.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = C288A0881505795D00E773B7 /* libOpenScriptingUtil.dylib */; settings = {ATTRIBUTES = (Weak, ); }; };
                C288A0891505796F00E773B7 /* libOpenScriptingUtil.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = C288A0881505795D00E773B7 /* libOpenScriptingUtil.dylib */; settings = {ATTRIBUTES = (Weak, ); }; };
+               CDDE9D1E1729E2E60013B0E8 /* SecPasswordGenerate.h in Headers */ = {isa = PBXBuildFile; fileRef = CDDE9D1C1729DF250013B0E8 /* SecPasswordGenerate.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               E778BFBC17176DDE00302C14 /* security.exp-in in Sources */ = {isa = PBXBuildFile; fileRef = 182BB562146F4C73000BF1F3 /* security.exp-in */; };
 /* End PBXBuildFile section */
 
 /* End PBXBuildFile section */
 
+/* Begin PBXBuildRule section */
+               E778BFB91717461800302C14 /* PBXBuildRule */ = {
+                       isa = PBXBuildRule;
+                       compilerSpec = com.apple.compilers.proxy.script;
+                       filePatterns = "*.exp-in";
+                       fileType = pattern.proxy;
+                       isEditable = 1;
+                       outputFiles = (
+                               "$(BUILT_PRODUCTS_DIR)/$(TARGETNAME).$(CURRENT_ARCH).exp",
+                       );
+                       script = "#!/bin/sh\n\nfor file in ${HEADER_SEARCH_PATHS[@]} ; do\nHEADER_SEARCH_OPTIONS=\"${HEADER_SEARCH_OPTIONS} -I${file}\"\ndone\n\nxcrun clang -E -Xpreprocessor -P -x c -arch ${CURRENT_ARCH} ${HEADER_SEARCH_OPTIONS} ${INPUT_FILE_PATH} -o ${BUILT_PRODUCTS_DIR}/${TARGETNAME}.${CURRENT_ARCH}.exp\n";
+               };
+/* End PBXBuildRule section */
+
 /* Begin PBXContainerItemProxy section */
 /* Begin PBXContainerItemProxy section */
+               0C4EAE711766865000773425 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 186CDD1614CA11C700AF9171 /* sec.xcodeproj */;
+                       proxyType = 2;
+                       remoteGlobalIDString = 0C0BDB5F175687EC00BC1A7E;
+                       remoteInfo = libsecdRegressions;
+               };
+               0C4EAE7817668DFF00773425 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 186CDD1614CA11C700AF9171 /* sec.xcodeproj */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 0C0BDB55175687EC00BC1A7E;
+                       remoteInfo = libsecdRegressions;
+               };
+               0C6C632D15D19D2900BC68CD /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 1879B71F146DE839007E536C /* libsecurity_ssl.xcodeproj */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 0CCA415815C89E8B002AEC4C;
+                       remoteInfo = libsecurity_ssl_regressions;
+               };
+               0C6C642D15D5ADC900BC68CD /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 0C6D77DE15C8C06500BB4405 /* tlsnke.xcodeproj */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 0CC9A7EF146DF66000C18F89;
+                       remoteInfo = tlsnke;
+               };
+               0C6C642F15D5AE4C00BC68CD /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 1879B71F146DE839007E536C /* libsecurity_ssl.xcodeproj */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 0C1C92EF15C8AC81007D377B;
+                       remoteInfo = libsecurity_ssl_kext;
+               };
+               0C6D77CC15C8B66000BB4405 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 1879B71F146DE839007E536C /* libsecurity_ssl.xcodeproj */;
+                       proxyType = 2;
+                       remoteGlobalIDString = 0C1C933A15C8AC81007D377B;
+                       remoteInfo = libsecurity_ssl_kext;
+               };
+               0C6D77CE15C8B66000BB4405 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 1879B71F146DE839007E536C /* libsecurity_ssl.xcodeproj */;
+                       proxyType = 2;
+                       remoteGlobalIDString = 0CCA415915C89E8B002AEC4C;
+                       remoteInfo = libsecurity_ssl_regressions;
+               };
+               0C6D77D015C8B66000BB4405 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 1879B71F146DE839007E536C /* libsecurity_ssl.xcodeproj */;
+                       proxyType = 2;
+                       remoteGlobalIDString = 0CCA42C915C8A387002AEC4C;
+                       remoteInfo = dtlsEchoClient;
+               };
+               0C6D77D215C8B66000BB4405 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 1879B71F146DE839007E536C /* libsecurity_ssl.xcodeproj */;
+                       proxyType = 2;
+                       remoteGlobalIDString = 0CCA42D715C8A395002AEC4C;
+                       remoteInfo = dtlsEchoServer;
+               };
+               0C6D77E815C8C06600BB4405 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 0C6D77DE15C8C06500BB4405 /* tlsnke.xcodeproj */;
+                       proxyType = 2;
+                       remoteGlobalIDString = 0CC9A7F0146DF66000C18F89;
+                       remoteInfo = tlsnke;
+               };
+               0C6D77EA15C8C06600BB4405 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 0C6D77DE15C8C06500BB4405 /* tlsnke.xcodeproj */;
+                       proxyType = 2;
+                       remoteGlobalIDString = 0CE08A73148FF2C6000473EB;
+                       remoteInfo = tlsnketest;
+               };
+               0C6D77EC15C8C06600BB4405 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 0C6D77DE15C8C06500BB4405 /* tlsnke.xcodeproj */;
+                       proxyType = 2;
+                       remoteGlobalIDString = 0CDF46A014DC794300FFE2FD;
+                       remoteInfo = tlssocket;
+               };
+               0CBD50B216C325F000713B6C /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 1879B6A0146DE79F007E536C /* libsecurity_keychain.xcodeproj */;
+                       proxyType = 2;
+                       remoteGlobalIDString = 0CBD509716C3242200713B6C;
+                       remoteInfo = libsecurity_keychain_regressions;
+               };
+               0CBD50C616C3260D00713B6C /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 1879B6A0146DE79F007E536C /* libsecurity_keychain.xcodeproj */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 0CBD500016C3242200713B6C;
+                       remoteInfo = libsecurity_keychain_regressions;
+               };
+               0CC3350916C1ED8000399E53 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 186CDD1614CA11C700AF9171 /* sec.xcodeproj */;
+                       proxyType = 1;
+                       remoteGlobalIDString = E702E73514E1F3EA00CDE635;
+                       remoteInfo = libSecureObjectSync;
+               };
+               0CC3350B16C1ED8000399E53 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 4C12893715FFECF3008CE3E3 /* utilities.xcodeproj */;
+                       proxyType = 1;
+                       remoteGlobalIDString = E742A09B14E343E70052A486;
+                       remoteInfo = utilities;
+               };
+               0CC3350D16C1ED8000399E53 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 186CDD1614CA11C700AF9171 /* sec.xcodeproj */;
+                       proxyType = 1;
+                       remoteGlobalIDString = E702E75714E1F48800CDE635;
+                       remoteInfo = libSOSRegressions;
+               };
+               0CC3351116C1ED8000399E53 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 186CDD1614CA11C700AF9171 /* sec.xcodeproj */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 18D4043414CE0CF300A2BE4E;
+                       remoteInfo = libsecurity;
+               };
+               0CC3351316C1ED8000399E53 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 186CDD1614CA11C700AF9171 /* sec.xcodeproj */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 18270F5414CF651900B05E7F;
+                       remoteInfo = libsecipc_client;
+               };
+               0CC3351516C1ED8000399E53 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 186CDD1614CA11C700AF9171 /* sec.xcodeproj */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 186CDD0E14CA116C00AF9171;
+                       remoteInfo = libSecItemShimOSX;
+               };
+               0CC3355F16C1EF5D00399E53 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 0CC3355B16C1EF5D00399E53 /* regressions.xcodeproj */;
+                       proxyType = 2;
+                       remoteGlobalIDString = E710C6FE133192E900F85568;
+                       remoteInfo = regressions;
+               };
+               0CC3356116C1EF8B00399E53 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 0CC3355B16C1EF5D00399E53 /* regressions.xcodeproj */;
+                       proxyType = 1;
+                       remoteGlobalIDString = E710C6FD133192E900F85568;
+                       remoteInfo = regressions;
+               };
+               0CCEBDB216C2CFD4001BD7F6 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 0CC3355B16C1EF5D00399E53 /* regressions.xcodeproj */;
+                       proxyType = 1;
+                       remoteGlobalIDString = E710C6FD133192E900F85568;
+                       remoteInfo = regressions;
+               };
+               0CCEBDB916C303D8001BD7F6 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 18073841146D0D4E00F05C24 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 0CC3350716C1ED8000399E53;
+                       remoteInfo = secdtests;
+               };
+               0CCEBDBC16C30948001BD7F6 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 4C12893715FFECF3008CE3E3 /* utilities.xcodeproj */;
+                       proxyType = 1;
+                       remoteGlobalIDString = E7E0D8E8158FA9A3002CA176;
+                       remoteInfo = utilitiesRegressions;
+               };
+               0CFC55E215DDB86500BEC89E /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 18073841146D0D4E00F05C24 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 0C6C630A15D193C800BC68CD;
+                       remoteInfo = sectests;
+               };
+               0CFE4BA6167943EF0077AE4F /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 18073841146D0D4E00F05C24 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 0C6C642915D5ADB500BC68CD;
+                       remoteInfo = Security_kexts;
+               };
                18270C7C14CE573D00B05E7F /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 186CDD1614CA11C700AF9171 /* sec.xcodeproj */;
                18270C7C14CE573D00B05E7F /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 186CDD1614CA11C700AF9171 /* sec.xcodeproj */;
                        remoteGlobalIDString = 18D4043514CE0CF300A2BE4E;
                        remoteInfo = security;
                };
                        remoteGlobalIDString = 18D4043514CE0CF300A2BE4E;
                        remoteInfo = security;
                };
+               18F235FE15CA100300060520 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 18073841146D0D4E00F05C24 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 18F234EA15C9F9A600060520;
+                       remoteInfo = security.auth;
+               };
                18FE688E1471A4C900A2CBE3 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 18073841146D0D4E00F05C24 /* Project object */;
                18FE688E1471A4C900A2CBE3 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 18073841146D0D4E00F05C24 /* Project object */;
                        remoteGlobalIDString = 18FE67E91471A3AA00A2CBE3;
                        remoteInfo = copyHeaders;
                };
                        remoteGlobalIDString = 18FE67E91471A3AA00A2CBE3;
                        remoteInfo = copyHeaders;
                };
+               4AD6F6F31651CC2500DB4CE6 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 186CDD1614CA11C700AF9171 /* sec.xcodeproj */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 4A5CCA4E15ACEFA500702357;
+                       remoteInfo = libSecOtrOSX;
+               };
+               4C01DE31164C3793006798CD /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 186CDD1614CA11C700AF9171 /* sec.xcodeproj */;
+                       proxyType = 2;
+                       remoteGlobalIDString = 528402A0164445760035F320;
+                       remoteInfo = libCloudKeychainProxy;
+               };
+               4C01DF12164C3E74006798CD /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 186CDD1614CA11C700AF9171 /* sec.xcodeproj */;
+                       proxyType = 1;
+                       remoteGlobalIDString = E702E73514E1F3EA00CDE635;
+                       remoteInfo = libSecureObjectSync;
+               };
+               4C1288E915FFE9D7008CE3E3 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 186CDD1614CA11C700AF9171 /* sec.xcodeproj */;
+                       proxyType = 2;
+                       remoteGlobalIDString = E702E75614E1F3EA00CDE635;
+                       remoteInfo = libSecureObjectSync;
+               };
+               4C1288EB15FFE9D7008CE3E3 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 186CDD1614CA11C700AF9171 /* sec.xcodeproj */;
+                       proxyType = 2;
+                       remoteGlobalIDString = E702E77814E1F48800CDE635;
+                       remoteInfo = libSOSRegressions;
+               };
+               4C1288ED15FFE9D7008CE3E3 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 186CDD1614CA11C700AF9171 /* sec.xcodeproj */;
+                       proxyType = 2;
+                       remoteGlobalIDString = 4A824B03158FF07000F932C0;
+                       remoteInfo = libSecurityRegressions;
+               };
+               4C1288EF15FFE9D7008CE3E3 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 186CDD1614CA11C700AF9171 /* sec.xcodeproj */;
+                       proxyType = 2;
+                       remoteGlobalIDString = 4CC92B1415A3BC6B00C6D578;
+                       remoteInfo = libsecuritydRegressions;
+               };
+               4C1288F115FFE9D7008CE3E3 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 186CDD1614CA11C700AF9171 /* sec.xcodeproj */;
+                       proxyType = 2;
+                       remoteGlobalIDString = 4A5CCA4F15ACEFA500702357;
+                       remoteInfo = libSecOtrOSX;
+               };
+               4C12893F15FFECF3008CE3E3 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 4C12893715FFECF3008CE3E3 /* utilities.xcodeproj */;
+                       proxyType = 2;
+                       remoteGlobalIDString = E742A09C14E343E70052A486;
+                       remoteInfo = utilities;
+               };
+               4C12894115FFECF3008CE3E3 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 4C12893715FFECF3008CE3E3 /* utilities.xcodeproj */;
+                       proxyType = 2;
+                       remoteGlobalIDString = E7E0D8F9158FA9A3002CA176;
+                       remoteInfo = utilitiesRegressions;
+               };
+               4C12894315FFED03008CE3E3 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 4C12893715FFECF3008CE3E3 /* utilities.xcodeproj */;
+                       proxyType = 1;
+                       remoteGlobalIDString = E742A09B14E343E70052A486;
+                       remoteInfo = utilities;
+               };
+               4C797BC816D83A3100C7B586 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 18073841146D0D4E00F05C24 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 4C96F7C016D6DF8300D3B39D;
+                       remoteInfo = "Keychain Circle Notification";
+               };
+               4C797BF016D83A3800C7B586 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 18073841146D0D4E00F05C24 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 4CC7A7B216CC2A84003E10C1;
+                       remoteInfo = "Cloud Keychain Utility";
+               };
+               4C7D8763160A746E00D041E3 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 4C12893715FFECF3008CE3E3 /* utilities.xcodeproj */;
+                       proxyType = 1;
+                       remoteGlobalIDString = E742A09B14E343E70052A486;
+                       remoteInfo = utilities;
+               };
+               4C8D864F177A75100019A804 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 186CDD1614CA11C700AF9171 /* sec.xcodeproj */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 18270F5414CF651900B05E7F;
+                       remoteInfo = libsecipc_client;
+               };
+               4CB23B75169F5873003A0131 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 186CDD1614CA11C700AF9171 /* sec.xcodeproj */;
+                       proxyType = 2;
+                       remoteGlobalIDString = E71049F2169E023B00DB0045;
+                       remoteInfo = libSecurityTool;
+               };
+               4CB23B77169F5873003A0131 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 186CDD1614CA11C700AF9171 /* sec.xcodeproj */;
+                       proxyType = 2;
+                       remoteGlobalIDString = E7104A1D169E216E00DB0045;
+                       remoteInfo = libSecurityCommands;
+               };
+               4CB23B79169F5873003A0131 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 186CDD1614CA11C700AF9171 /* sec.xcodeproj */;
+                       proxyType = 2;
+                       remoteGlobalIDString = E7FEFB8C169E363300E18152;
+                       remoteInfo = libSOSCommands;
+               };
+               4CB23B83169F5961003A0131 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 186CDD1614CA11C700AF9171 /* sec.xcodeproj */;
+                       proxyType = 1;
+                       remoteGlobalIDString = E7FEFB82169E363300E18152;
+                       remoteInfo = libSOSCommands;
+               };
+               4CB23B85169F5971003A0131 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 186CDD1614CA11C700AF9171 /* sec.xcodeproj */;
+                       proxyType = 1;
+                       remoteGlobalIDString = E7104A12169E216E00DB0045;
+                       remoteInfo = libSecurityCommands;
+               };
+               4CB23B87169F597D003A0131 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 186CDD1614CA11C700AF9171 /* sec.xcodeproj */;
+                       proxyType = 1;
+                       remoteGlobalIDString = E71049F1169E023B00DB0045;
+                       remoteInfo = libSecurityTool;
+               };
+               4CB23B8F169F59D8003A0131 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 18073841146D0D4E00F05C24 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 4CB23B45169F5873003A0131;
+                       remoteInfo = security2;
+               };
+               5208C0FD16A0D3980062DDC5 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 186CDD1614CA11C700AF9171 /* sec.xcodeproj */;
+                       proxyType = 1;
+                       remoteGlobalIDString = E702E73514E1F3EA00CDE635;
+                       remoteInfo = libSecureObjectSync;
+               };
+               5214701716977D1D00DF0DB3 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 4C12893715FFECF3008CE3E3 /* utilities.xcodeproj */;
+                       proxyType = 1;
+                       remoteGlobalIDString = E742A09B14E343E70052A486;
+                       remoteInfo = utilities;
+               };
+               5214701916977D2500DF0DB3 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 186CDD1614CA11C700AF9171 /* sec.xcodeproj */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 5284029F164445760035F320;
+                       remoteInfo = libCloudKeychainProxy;
+               };
+               521470281697842500DF0DB3 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 18073841146D0D4E00F05C24 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 5214700516977CB800DF0DB3;
+                       remoteInfo = CloudKeychainProxy;
+               };
                529FF21F1523BD7F0029D842 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 1879B6A0146DE79F007E536C /* libsecurity_keychain.xcodeproj */;
                529FF21F1523BD7F0029D842 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 1879B6A0146DE79F007E536C /* libsecurity_keychain.xcodeproj */;
                        remoteGlobalIDString = 52200F8F14F2B88000F7F6E7;
                        remoteInfo = XPCTimeStampingService;
                };
                        remoteGlobalIDString = 52200F8F14F2B88000F7F6E7;
                        remoteInfo = XPCTimeStampingService;
                };
+               721680B2179B4C6C00406BB4 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 18073841146D0D4E00F05C24 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 721680A4179B40F600406BB4;
+                       remoteInfo = iCloudStats;
+               };
+               722CF217175D602F00BCE0A5 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 18073841146D0D4E00F05C24 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 72756BFD175D485D00F52070;
+                       remoteInfo = cloud_keychain_diagnose;
+               };
                C2432A0715C7112A0096DB5B /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 1879B657146DE756007E536C /* libsecurity_codesigning.xcodeproj */;
                C2432A0715C7112A0096DB5B /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 1879B657146DE756007E536C /* libsecurity_codesigning.xcodeproj */;
                        remoteGlobalIDString = C209695F15BF52040093035F;
                        remoteInfo = gkunpack;
                };
                        remoteGlobalIDString = C209695F15BF52040093035F;
                        remoteInfo = gkunpack;
                };
+               EB2E1F57166D6B3700A7EF61 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 1879B657146DE756007E536C /* libsecurity_codesigning.xcodeproj */;
+                       proxyType = 2;
+                       remoteGlobalIDString = EB2E1F05166D69B800A7EF61;
+                       remoteInfo = CodeSigningHelper;
+               };
+               EBB9FFDF1682E71F00FF9774 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 1879B657146DE756007E536C /* libsecurity_codesigning.xcodeproj */;
+                       proxyType = 1;
+                       remoteGlobalIDString = EBB9FF6E1682E51300FF9774;
+                       remoteInfo = CodeSigningHelper;
+               };
 /* End PBXContainerItemProxy section */
 
 /* Begin PBXCopyFilesBuildPhase section */
 /* End PBXContainerItemProxy section */
 
 /* Begin PBXCopyFilesBuildPhase section */
-               18BEB19914CF7F0B00C8BD36 /* CopyFiles */ = {
+               0C6D003C177B545D0095D167 /* CopyFiles */ = {
                        isa = PBXCopyFilesBuildPhase;
                        buildActionMask = 8;
                        isa = PBXCopyFilesBuildPhase;
                        buildActionMask = 8;
-                       dstPath = /System/Library/LaunchDaemons;
+                       dstPath = /private/etc/asl;
                        dstSubfolderSpec = 0;
                        files = (
                        dstSubfolderSpec = 0;
                        files = (
-                               18BEB19A14CF7F8100C8BD36 /* com.apple.secd.plist in CopyFiles */,
+                               0C6D0065177B54CB0095D167 /* com.apple.securityd in CopyFiles */,
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                };
-/* End PBXCopyFilesBuildPhase section */
-
-/* Begin PBXFileReference section */
-               1807384B146D0D4E00F05C24 /* Security.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Security.framework; sourceTree = BUILT_PRODUCTS_DIR; };
-               18073856146D0D4E00F05C24 /* Info-Security.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-Security.plist"; sourceTree = "<group>"; };
-               181EA422146D4A2A00A6D320 /* base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = base.xcconfig; sourceTree = "<group>"; };
-               181EA423146D4A2A00A6D320 /* debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = debug.xcconfig; sourceTree = "<group>"; };
-               181EA424146D4A2A00A6D320 /* lib.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = lib.xcconfig; sourceTree = "<group>"; wrapsLines = 0; };
-               181EA425146D4A2A00A6D320 /* release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = release.xcconfig; sourceTree = "<group>"; };
+               187D6B9615D4381C00E27494 /* Copy authorization.plist */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 8;
+                       dstPath = "$(SYSTEM_LIBRARY_DIR)/Security";
+                       dstSubfolderSpec = 0;
+                       files = (
+                               187D6B9715D438AD00E27494 /* authorization.plist in Copy authorization.plist */,
+                       );
+                       name = "Copy authorization.plist";
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+               18BEB19914CF7F0B00C8BD36 /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 8;
+                       dstPath = /System/Library/LaunchAgents;
+                       dstSubfolderSpec = 0;
+                       files = (
+                               18BEB19A14CF7F8100C8BD36 /* com.apple.secd.plist in CopyFiles */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+               18CFEE8815DEE2BA00E3F2A3 /* Copy sandbox profile */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 8;
+                       dstPath = "$(SYSTEM_LIBRARY_DIR)/Sandbox/Profiles";
+                       dstSubfolderSpec = 0;
+                       files = (
+                               18CFEE8915DEE2C600E3F2A3 /* com.apple.authd.sb in Copy sandbox profile */,
+                       );
+                       name = "Copy sandbox profile";
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+               18D6803A16B768DE00DF6D2E /* Copy asl module */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 8;
+                       dstPath = /private/etc/asl;
+                       dstSubfolderSpec = 0;
+                       files = (
+                               18D6803B16B768F700DF6D2E /* com.apple.authd in Copy asl module */,
+                       );
+                       name = "Copy asl module";
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+               4A5C178F161A9DE000ABF784 /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 8;
+                       dstPath = /usr/local/include;
+                       dstSubfolderSpec = 0;
+                       files = (
+                               4A5C1790161A9DFB00ABF784 /* authd_private.h in CopyFiles */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+               4C49390E16E51ED100CE110C /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 12;
+                       dstPath = /System/Library/LaunchAgents;
+                       dstSubfolderSpec = 0;
+                       files = (
+                               4C49390F16E51FC700CE110C /* com.apple.security.keychain-circle-notification.plist in CopyFiles */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               4CB23B44169F5873003A0131 /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 2147483647;
+                       dstPath = /usr/share/man/man1/;
+                       dstSubfolderSpec = 0;
+                       files = (
+                               4CB23B4C169F5873003A0131 /* security2.1 in CopyFiles */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+               4CB86AE4167A6F3D00F46643 /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 8;
+                       dstPath = PrivateHeaders/SecureObjectSync;
+                       dstSubfolderSpec = 1;
+                       files = (
+                               4CB86AFB167A8F2200F46643 /* SOSAccount.h in CopyFiles */,
+                               4CB86AF0167A6FF300F46643 /* SOSCircle.h in CopyFiles */,
+                               4CB86AF1167A6FF300F46643 /* SOSCloudCircle.h in CopyFiles */,
+                               4CB86AF2167A6FF300F46643 /* SOSCloudCircleInternal.h in CopyFiles */,
+                               4CB86AF3167A6FF300F46643 /* SOSEngine.h in CopyFiles */,
+                               4CB86AF4167A6FF300F46643 /* SOSFullPeerInfo.h in CopyFiles */,
+                               4CB86AF5167A6FF300F46643 /* SOSInternal.h in CopyFiles */,
+                               4CB86AF6167A6FF300F46643 /* SOSPeer.h in CopyFiles */,
+                               4CB86AF7167A6FF300F46643 /* SOSPeerInfo.h in CopyFiles */,
+                               4CB86AF8167A6FF300F46643 /* SOSTransport.h in CopyFiles */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+               5214702316977EA600DF0DB3 /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 8;
+                       dstPath = "$(INDIGO_INSTALL_PATH_PREFIX)/System/Library/LaunchAgents/";
+                       dstSubfolderSpec = 0;
+                       files = (
+                               521470261697800500DF0DB3 /* com.apple.security.cloudkeychainproxy.plist in CopyFiles */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+               721680A3179B40F600406BB4 /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 2147483647;
+                       dstPath = "$(INDIGO_INSTALL_PATH_PREFIX)/System/Library/LaunchDaemons";
+                       dstSubfolderSpec = 0;
+                       files = (
+                               721680BE179B509900406BB4 /* com.apple.iCloudStats.plist in CopyFiles */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+               72756BFC175D485D00F52070 /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 2147483647;
+                       dstPath = /usr/share/man/man1/;
+                       dstSubfolderSpec = 0;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+               0C4F055D15C9E51A00F9DFD5 /* sslTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sslTypes.h; path = libsecurity_ssl/lib/sslTypes.h; sourceTree = SOURCE_ROOT; };
+               0C6C630B15D193C800BC68CD /* sectests */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = sectests; sourceTree = BUILT_PRODUCTS_DIR; };
+               0C6C630E15D193C800BC68CD /* main.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = "<group>"; };
+               0C6C632415D1964200BC68CD /* testlist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = testlist.h; sourceTree = "<group>"; };
+               0C6C632F15D19DE600BC68CD /* test.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = test.xcconfig; sourceTree = "<group>"; };
+               0C6D0064177B54C60095D167 /* com.apple.securityd */ = {isa = PBXFileReference; lastKnownFileType = text; name = com.apple.securityd; path = asl/com.apple.securityd; sourceTree = SOURCE_ROOT; };
+               0C6D77DE15C8C06500BB4405 /* tlsnke.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = tlsnke.xcodeproj; path = tlsnke/tlsnke.xcodeproj; sourceTree = "<group>"; };
+               0CC3352D16C1ED8000399E53 /* secdtests */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = secdtests; sourceTree = BUILT_PRODUCTS_DIR; };
+               0CC3355716C1EEE700399E53 /* main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = main.c; path = secdtests/main.c; sourceTree = "<group>"; };
+               0CC3355816C1EEE700399E53 /* testlist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = testlist.h; path = secdtests/testlist.h; sourceTree = "<group>"; };
+               0CC3355B16C1EF5D00399E53 /* regressions.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = regressions.xcodeproj; path = regressions/regressions.xcodeproj; sourceTree = SOURCE_ROOT; };
+               1807384B146D0D4E00F05C24 /* Security.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Security.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+               18073856146D0D4E00F05C24 /* Info-Security.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-Security.plist"; sourceTree = "<group>"; };
+               181EA422146D4A2A00A6D320 /* base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = base.xcconfig; sourceTree = "<group>"; };
+               181EA423146D4A2A00A6D320 /* debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = debug.xcconfig; sourceTree = "<group>"; };
+               181EA424146D4A2A00A6D320 /* lib.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = lib.xcconfig; sourceTree = "<group>"; wrapsLines = 0; };
+               181EA425146D4A2A00A6D320 /* release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = release.xcconfig; sourceTree = "<group>"; };
                18270ED614CF282600B05E7F /* secd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = secd; sourceTree = BUILT_PRODUCTS_DIR; };
                18270EEC14CF333400B05E7F /* client.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = client.c; sourceTree = "<group>"; };
                18270EED14CF333400B05E7F /* com.apple.securityd.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = com.apple.securityd.plist; sourceTree = "<group>"; };
                18270ED614CF282600B05E7F /* secd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = secd; sourceTree = BUILT_PRODUCTS_DIR; };
                18270EEC14CF333400B05E7F /* client.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = client.c; sourceTree = "<group>"; };
                18270EED14CF333400B05E7F /* com.apple.securityd.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = com.apple.securityd.plist; sourceTree = "<group>"; };
                18270F0814CF43C000B05E7F /* libDER.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libDER.xcodeproj; path = libsecurity_keychain/libDER/libDER.xcodeproj; sourceTree = "<group>"; };
                18270F3A14CF44C400B05E7F /* debugging.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = debugging.c; sourceTree = "<group>"; };
                18270F3B14CF44C400B05E7F /* debugging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debugging.h; sourceTree = "<group>"; };
                18270F0814CF43C000B05E7F /* libDER.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libDER.xcodeproj; path = libsecurity_keychain/libDER/libDER.xcodeproj; sourceTree = "<group>"; };
                18270F3A14CF44C400B05E7F /* debugging.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = debugging.c; sourceTree = "<group>"; };
                18270F3B14CF44C400B05E7F /* debugging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debugging.h; sourceTree = "<group>"; };
+               182A190F15D09AF0006AB103 /* connection.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = connection.h; sourceTree = "<group>"; };
+               182A191015D09AFF006AB103 /* connection.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = connection.c; sourceTree = "<group>"; };
                182BB187146EAD4C000BF1F3 /* SecAccess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecAccess.h; path = libsecurity_keychain/lib/SecAccess.h; sourceTree = SOURCE_ROOT; };
                182BB188146EAD4C000BF1F3 /* SecACL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecACL.h; path = libsecurity_keychain/lib/SecACL.h; sourceTree = SOURCE_ROOT; };
                182BB189146EAD4C000BF1F3 /* SecBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecBase.h; path = libsecurity_keychain/lib/SecBase.h; sourceTree = SOURCE_ROOT; };
                182BB187146EAD4C000BF1F3 /* SecAccess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecAccess.h; path = libsecurity_keychain/lib/SecAccess.h; sourceTree = SOURCE_ROOT; };
                182BB188146EAD4C000BF1F3 /* SecACL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecACL.h; path = libsecurity_keychain/lib/SecACL.h; sourceTree = SOURCE_ROOT; };
                182BB189146EAD4C000BF1F3 /* SecBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecBase.h; path = libsecurity_keychain/lib/SecBase.h; sourceTree = SOURCE_ROOT; };
                182BB1C8146EAD5D000BF1F3 /* TrustSettingsSchema.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TrustSettingsSchema.h; path = libsecurity_keychain/lib/TrustSettingsSchema.h; sourceTree = SOURCE_ROOT; };
                182BB1CA146EAD5D000BF1F3 /* SecItemPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecItemPriv.h; path = libsecurity_keychain/lib/SecItemPriv.h; sourceTree = SOURCE_ROOT; };
                182BB1CB146EAD5D000BF1F3 /* SecKeychainItemExtendedAttributes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecKeychainItemExtendedAttributes.h; path = libsecurity_keychain/lib/SecKeychainItemExtendedAttributes.h; sourceTree = SOURCE_ROOT; };
                182BB1C8146EAD5D000BF1F3 /* TrustSettingsSchema.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TrustSettingsSchema.h; path = libsecurity_keychain/lib/TrustSettingsSchema.h; sourceTree = SOURCE_ROOT; };
                182BB1CA146EAD5D000BF1F3 /* SecItemPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecItemPriv.h; path = libsecurity_keychain/lib/SecItemPriv.h; sourceTree = SOURCE_ROOT; };
                182BB1CB146EAD5D000BF1F3 /* SecKeychainItemExtendedAttributes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecKeychainItemExtendedAttributes.h; path = libsecurity_keychain/lib/SecKeychainItemExtendedAttributes.h; sourceTree = SOURCE_ROOT; };
-               182BB1CD146EAD5D000BF1F3 /* SecCertificateInternalP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCertificateInternalP.h; path = libsecurity_keychain/lib/SecCertificateInternalP.h; sourceTree = SOURCE_ROOT; };
                182BB1CE146EAD5D000BF1F3 /* SecRecoveryPassword.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecRecoveryPassword.h; path = libsecurity_keychain/lib/SecRecoveryPassword.h; sourceTree = SOURCE_ROOT; };
                182BB1CF146EAD5D000BF1F3 /* SecRandomP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecRandomP.h; path = libsecurity_keychain/lib/SecRandomP.h; sourceTree = SOURCE_ROOT; };
                182BB229146F068B000BF1F3 /* iToolsTrustedApps.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = iToolsTrustedApps.plist; path = libsecurity_keychain/plist/iToolsTrustedApps.plist; sourceTree = SOURCE_ROOT; };
                182BB1CE146EAD5D000BF1F3 /* SecRecoveryPassword.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecRecoveryPassword.h; path = libsecurity_keychain/lib/SecRecoveryPassword.h; sourceTree = SOURCE_ROOT; };
                182BB1CF146EAD5D000BF1F3 /* SecRandomP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecRandomP.h; path = libsecurity_keychain/lib/SecRandomP.h; sourceTree = SOURCE_ROOT; };
                182BB229146F068B000BF1F3 /* iToolsTrustedApps.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = iToolsTrustedApps.plist; path = libsecurity_keychain/plist/iToolsTrustedApps.plist; sourceTree = SOURCE_ROOT; };
                182BB55C146F4544000BF1F3 /* FDEPrefs.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = FDEPrefs.plist; sourceTree = "<group>"; };
                182BB55D146F4544000BF1F3 /* generateErrStrings.pl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.perl; path = generateErrStrings.pl; sourceTree = "<group>"; };
                182BB55E146F4544000BF1F3 /* Security.order */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Security.order; sourceTree = "<group>"; };
                182BB55C146F4544000BF1F3 /* FDEPrefs.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = FDEPrefs.plist; sourceTree = "<group>"; };
                182BB55D146F4544000BF1F3 /* generateErrStrings.pl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.perl; path = generateErrStrings.pl; sourceTree = "<group>"; };
                182BB55E146F4544000BF1F3 /* Security.order */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Security.order; sourceTree = "<group>"; };
-               182BB562146F4C73000BF1F3 /* security.exp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.exports; path = security.exp; sourceTree = "<group>"; };
+               182BB562146F4C73000BF1F3 /* security.exp-in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "security.exp-in"; sourceTree = "<group>"; };
                182BB568146F4DCA000BF1F3 /* csparser.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = csparser.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
                182BB569146F4DCA000BF1F3 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
                182BB593146FE1ED000BF1F3 /* libantlr2c++.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libantlr2c++.a"; path = "/usr/local/lib/libantlr2c++.a"; sourceTree = "<absolute>"; };
                182BB568146F4DCA000BF1F3 /* csparser.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = csparser.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
                182BB569146F4DCA000BF1F3 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
                182BB593146FE1ED000BF1F3 /* libantlr2c++.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libantlr2c++.a"; path = "/usr/local/lib/libantlr2c++.a"; sourceTree = "<absolute>"; };
-               182BB5A7146FE6D4000BF1F3 /* security_exports.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = security_exports.s; path = derived_src/security_exports.s; sourceTree = BUILT_PRODUCTS_DIR; };
                182BB5AB146FEF14000BF1F3 /* libpam.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libpam.dylib; path = /usr/lib/libpam.dylib; sourceTree = "<absolute>"; };
                182BB5AD146FEF43000BF1F3 /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = /usr/lib/libsqlite3.dylib; sourceTree = "<absolute>"; };
                182BB5AB146FEF14000BF1F3 /* libpam.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libpam.dylib; path = /usr/lib/libpam.dylib; sourceTree = "<absolute>"; };
                182BB5AD146FEF43000BF1F3 /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = /usr/lib/libsqlite3.dylib; sourceTree = "<absolute>"; };
-               182BB5AF146FEFE2000BF1F3 /* libstdc++.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libstdc++.dylib"; path = "/usr/lib/libstdc++.dylib"; sourceTree = "<absolute>"; };
                182BB5B1146FF039000BF1F3 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = /usr/lib/libz.dylib; sourceTree = "<absolute>"; };
                182BB5B3146FF04C000BF1F3 /* libxar.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libxar.dylib; path = /usr/lib/libxar.dylib; sourceTree = "<absolute>"; };
                182BB5B5146FF08F000BF1F3 /* libauto.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libauto.dylib; path = /usr/lib/libauto.dylib; sourceTree = "<absolute>"; };
                182BB5B1146FF039000BF1F3 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = /usr/lib/libz.dylib; sourceTree = "<absolute>"; };
                182BB5B3146FF04C000BF1F3 /* libxar.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libxar.dylib; path = /usr/lib/libxar.dylib; sourceTree = "<absolute>"; };
                182BB5B5146FF08F000BF1F3 /* libauto.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libauto.dylib; path = /usr/lib/libauto.dylib; sourceTree = "<absolute>"; };
                18446191146E9A8F00B12992 /* SecIntegrity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecIntegrity.h; path = libsecurity_codesigning/lib/SecIntegrity.h; sourceTree = SOURCE_ROOT; };
                18446192146E9A8F00B12992 /* SecIntegrityLib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecIntegrityLib.h; path = libsecurity_codesigning/lib/SecIntegrityLib.h; sourceTree = SOURCE_ROOT; };
                18446193146E9A8F00B12992 /* SecCodeHostLib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCodeHostLib.h; path = libsecurity_codesigning/lib/SecCodeHostLib.h; sourceTree = SOURCE_ROOT; };
                18446191146E9A8F00B12992 /* SecIntegrity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecIntegrity.h; path = libsecurity_codesigning/lib/SecIntegrity.h; sourceTree = SOURCE_ROOT; };
                18446192146E9A8F00B12992 /* SecIntegrityLib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecIntegrityLib.h; path = libsecurity_codesigning/lib/SecIntegrityLib.h; sourceTree = SOURCE_ROOT; };
                18446193146E9A8F00B12992 /* SecCodeHostLib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCodeHostLib.h; path = libsecurity_codesigning/lib/SecCodeHostLib.h; sourceTree = SOURCE_ROOT; };
-               18446194146E9A8F00B12992 /* SecAssessment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecAssessment.h; path = libsecurity_codesigning/lib/SecAssessment.h; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
+               18446194146E9A8F00B12992 /* SecAssessment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecAssessment.h; path = libsecurity_codesigning/lib/SecAssessment.h; sourceTree = SOURCE_ROOT; };
                184461A3146E9D3200B12992 /* libsecurityd.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libsecurityd.xcodeproj; path = libsecurityd/libsecurityd.xcodeproj; sourceTree = "<group>"; };
                18500F9A14708D0E006F9AB4 /* SecDebugErrorMessages.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = SecDebugErrorMessages.strings; path = derived_src/SecDebugErrorMessages.strings; sourceTree = BUILT_PRODUCTS_DIR; };
                18500FA014708F19006F9AB4 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = derived_src/en.lproj/SecErrorMessages.strings; sourceTree = BUILT_PRODUCTS_DIR; };
                186CDD1614CA11C700AF9171 /* sec.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = sec.xcodeproj; sourceTree = "<group>"; };
                184461A3146E9D3200B12992 /* libsecurityd.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libsecurityd.xcodeproj; path = libsecurityd/libsecurityd.xcodeproj; sourceTree = "<group>"; };
                18500F9A14708D0E006F9AB4 /* SecDebugErrorMessages.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = SecDebugErrorMessages.strings; path = derived_src/SecDebugErrorMessages.strings; sourceTree = BUILT_PRODUCTS_DIR; };
                18500FA014708F19006F9AB4 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = derived_src/en.lproj/SecErrorMessages.strings; sourceTree = BUILT_PRODUCTS_DIR; };
                186CDD1614CA11C700AF9171 /* sec.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = sec.xcodeproj; sourceTree = "<group>"; };
+               18752C1D16F2837A004E2799 /* libaks.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libaks.a; path = usr/local/lib/libaks.a; sourceTree = SDKROOT; };
                1879B4A9146DCA18007E536C /* cssm.mdsinfo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = cssm.mdsinfo; path = libsecurity_cssm/mds/cssm.mdsinfo; sourceTree = SOURCE_ROOT; };
                1879B4AB146DCA4A007E536C /* cssmapplePriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cssmapplePriv.h; path = libsecurity_cssm/lib/cssmapplePriv.h; sourceTree = SOURCE_ROOT; };
                1879B4AD146DCA84007E536C /* certextensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = certextensions.h; path = libsecurity_cssm/lib/certextensions.h; sourceTree = SOURCE_ROOT; };
                1879B4A9146DCA18007E536C /* cssm.mdsinfo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = cssm.mdsinfo; path = libsecurity_cssm/mds/cssm.mdsinfo; sourceTree = SOURCE_ROOT; };
                1879B4AB146DCA4A007E536C /* cssmapplePriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cssmapplePriv.h; path = libsecurity_cssm/lib/cssmapplePriv.h; sourceTree = SOURCE_ROOT; };
                1879B4AD146DCA84007E536C /* certextensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = certextensions.h; path = libsecurity_cssm/lib/certextensions.h; sourceTree = SOURCE_ROOT; };
                1879B712146DE825007E536C /* libsecurity_smime.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libsecurity_smime.xcodeproj; path = libsecurity_smime/libsecurity_smime.xcodeproj; sourceTree = "<group>"; };
                1879B71F146DE839007E536C /* libsecurity_ssl.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libsecurity_ssl.xcodeproj; path = libsecurity_ssl/libsecurity_ssl.xcodeproj; sourceTree = "<group>"; };
                1879B72B146DE844007E536C /* libsecurity_transform.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libsecurity_transform.xcodeproj; path = libsecurity_transform/libsecurity_transform.xcodeproj; sourceTree = "<group>"; };
                1879B712146DE825007E536C /* libsecurity_smime.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libsecurity_smime.xcodeproj; path = libsecurity_smime/libsecurity_smime.xcodeproj; sourceTree = "<group>"; };
                1879B71F146DE839007E536C /* libsecurity_ssl.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libsecurity_ssl.xcodeproj; path = libsecurity_ssl/libsecurity_ssl.xcodeproj; sourceTree = "<group>"; };
                1879B72B146DE844007E536C /* libsecurity_transform.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libsecurity_transform.xcodeproj; path = libsecurity_transform/libsecurity_transform.xcodeproj; sourceTree = "<group>"; };
+               187D6B9015D4359F00E27494 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/authorization.buttons.strings; sourceTree = "<group>"; };
+               187D6B9215D4359F00E27494 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/authorization.prompts.strings; sourceTree = "<group>"; };
+               187D6B9515D436BF00E27494 /* authorization.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = authorization.plist; sourceTree = "<group>"; };
                188AD8D91471FE3D0081C619 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/FDELocalizable.strings; sourceTree = "<group>"; };
                188AD8DB1471FE3E0081C619 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
                188AD8D91471FE3D0081C619 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/FDELocalizable.strings; sourceTree = "<group>"; };
                188AD8DB1471FE3E0081C619 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+               18A5493115EFD2F40059E6DC /* dummy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dummy.cpp; sourceTree = "<group>"; };
                18B647E814D9EB6300F538BF /* oidsalg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = oidsalg.h; path = ../libsecurity_asn1/lib/oidsalg.h; sourceTree = "<group>"; };
                18B647EA14D9EE4300F538BF /* oidsattr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = oidsattr.h; path = ../libsecurity_asn1/lib/oidsattr.h; sourceTree = "<group>"; };
                18B647EF14D9F75300F538BF /* generateErrStrings.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = generateErrStrings.mm; path = derived_src/generateErrStrings.mm; sourceTree = BUILT_PRODUCTS_DIR; };
                18BBC6801471EF1600F2B224 /* security.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = security.xcconfig; sourceTree = "<group>"; };
                18BBC7351471F5A300F2B224 /* SecExternalSourceTransform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecExternalSourceTransform.h; path = libsecurity_transform/lib/SecExternalSourceTransform.h; sourceTree = SOURCE_ROOT; };
                18BEB19614CF74C100C8BD36 /* com.apple.secd.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.secd.plist; sourceTree = "<group>"; };
                18B647E814D9EB6300F538BF /* oidsalg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = oidsalg.h; path = ../libsecurity_asn1/lib/oidsalg.h; sourceTree = "<group>"; };
                18B647EA14D9EE4300F538BF /* oidsattr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = oidsattr.h; path = ../libsecurity_asn1/lib/oidsattr.h; sourceTree = "<group>"; };
                18B647EF14D9F75300F538BF /* generateErrStrings.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = generateErrStrings.mm; path = derived_src/generateErrStrings.mm; sourceTree = BUILT_PRODUCTS_DIR; };
                18BBC6801471EF1600F2B224 /* security.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = security.xcconfig; sourceTree = "<group>"; };
                18BBC7351471F5A300F2B224 /* SecExternalSourceTransform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecExternalSourceTransform.h; path = libsecurity_transform/lib/SecExternalSourceTransform.h; sourceTree = SOURCE_ROOT; };
                18BEB19614CF74C100C8BD36 /* com.apple.secd.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.secd.plist; sourceTree = "<group>"; };
+               18BFC44017C43393005DE6C3 /* executable.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = executable.xcconfig; sourceTree = "<group>"; };
+               18CFEE8715DEE25200E3F2A3 /* com.apple.authd.sb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = com.apple.authd.sb; sourceTree = "<group>"; };
+               18D6803916B768D500DF6D2E /* com.apple.authd */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = com.apple.authd; sourceTree = "<group>"; };
+               18ED4D2317270DB6003AF11B /* SecurityTests-Entitlements.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "SecurityTests-Entitlements.plist"; sourceTree = "<group>"; };
+               18F234EB15C9F9A600060520 /* authd.xpc */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = authd.xpc; sourceTree = BUILT_PRODUCTS_DIR; };
+               18F234F915C9FA3B00060520 /* agent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = agent.c; sourceTree = "<group>"; };
+               18F234FA15C9FA3B00060520 /* agent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = agent.h; sourceTree = "<group>"; };
+               18F234FB15C9FA3B00060520 /* authdb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = authdb.c; sourceTree = "<group>"; };
+               18F234FC15C9FA3B00060520 /* authdb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = authdb.h; sourceTree = "<group>"; };
+               18F234FD15C9FA3B00060520 /* authitems.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = authitems.c; sourceTree = "<group>"; };
+               18F234FE15C9FA3B00060520 /* authitems.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = authitems.h; sourceTree = "<group>"; };
+               18F234FF15C9FA3B00060520 /* authtoken.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = authtoken.c; sourceTree = "<group>"; };
+               18F2350015C9FA3B00060520 /* authtoken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = authtoken.h; sourceTree = "<group>"; };
+               18F2350115C9FA3B00060520 /* authtypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = authtypes.h; sourceTree = "<group>"; };
+               18F2350215C9FA3B00060520 /* authutilities.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = authutilities.c; sourceTree = "<group>"; };
+               18F2350315C9FA3B00060520 /* authutilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = authutilities.h; sourceTree = "<group>"; };
+               18F2350415C9FA3B00060520 /* ccaudit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ccaudit.c; sourceTree = "<group>"; };
+               18F2350515C9FA3B00060520 /* ccaudit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ccaudit.h; sourceTree = "<group>"; };
+               18F2350615C9FA3B00060520 /* crc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crc.c; sourceTree = "<group>"; };
+               18F2350715C9FA3B00060520 /* crc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = crc.h; sourceTree = "<group>"; };
+               18F2350815C9FA3B00060520 /* credential.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = credential.c; sourceTree = "<group>"; };
+               18F2350915C9FA3B00060520 /* credential.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = credential.h; sourceTree = "<group>"; };
+               18F2350A15C9FA3B00060520 /* debugging.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = debugging.c; sourceTree = "<group>"; };
+               18F2350B15C9FA3B00060520 /* debugging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debugging.h; sourceTree = "<group>"; };
+               18F2350E15C9FA3B00060520 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = InfoPlist.strings; sourceTree = "<group>"; };
+               18F2350F15C9FA3B00060520 /* engine.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = engine.c; sourceTree = "<group>"; };
+               18F2351015C9FA3B00060520 /* engine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = engine.h; sourceTree = "<group>"; };
+               18F2351115C9FA3B00060520 /* main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = "<group>"; };
+               18F2351215C9FA3B00060520 /* mechanism.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mechanism.c; sourceTree = "<group>"; };
+               18F2351315C9FA3B00060520 /* mechanism.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mechanism.h; sourceTree = "<group>"; };
+               18F2351415C9FA3C00060520 /* object.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = object.c; sourceTree = "<group>"; };
+               18F2351515C9FA3C00060520 /* object.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = object.h; sourceTree = "<group>"; };
+               18F2351615C9FA3C00060520 /* process.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = process.c; sourceTree = "<group>"; };
+               18F2351715C9FA3C00060520 /* process.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = process.h; sourceTree = "<group>"; };
+               18F2351815C9FA3C00060520 /* rule.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rule.c; sourceTree = "<group>"; };
+               18F2351915C9FA3C00060520 /* rule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rule.h; sourceTree = "<group>"; };
+               18F2351A15C9FA3C00060520 /* authd_private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = authd_private.h; sourceTree = "<group>"; };
+               18F2351B15C9FA3C00060520 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+               18F2351C15C9FA3C00060520 /* security.auth-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "security.auth-Prefix.pch"; sourceTree = "<group>"; };
+               18F2351D15C9FA3C00060520 /* server.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = server.c; sourceTree = "<group>"; };
+               18F2351E15C9FA3C00060520 /* server.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = server.h; sourceTree = "<group>"; };
+               18F2351F15C9FA3C00060520 /* session.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = session.c; sourceTree = "<group>"; };
+               18F2352015C9FA3C00060520 /* session.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = session.h; sourceTree = "<group>"; };
+               18F235F515CA0D8100060520 /* libsecurity_cdsa_utilities.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libsecurity_cdsa_utilities.a; path = /usr/local/lib/libsecurity_cdsa_utilities.a; sourceTree = "<absolute>"; };
+               18F235F715CA0D9D00060520 /* libsecurity_utilities.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libsecurity_utilities.a; path = /usr/local/lib/libsecurity_utilities.a; sourceTree = "<absolute>"; };
+               18F235F915CA0DB000060520 /* libsecurity_agent_client.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libsecurity_agent_client.a; path = /usr/local/lib/libsecurity_agent_client.a; sourceTree = "<absolute>"; };
+               18F235FC15CA0EDB00060520 /* libstdc++.6.0.9.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libstdc++.6.0.9.dylib"; path = "/usr/lib/libstdc++.6.0.9.dylib"; sourceTree = "<absolute>"; };
+               18F2360015CAF41100060520 /* libsecurity_codesigning.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libsecurity_codesigning.a; path = /usr/local/lib/libsecurity_codesigning.a; sourceTree = "<absolute>"; };
                18FE67EA1471A3AA00A2CBE3 /* Security.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Security.framework; sourceTree = BUILT_PRODUCTS_DIR; };
                18FE67EA1471A3AA00A2CBE3 /* Security.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Security.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+               395E7CED16C64EA500CD82A4 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
+               4C12893715FFECF3008CE3E3 /* utilities.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = utilities.xcodeproj; sourceTree = "<group>"; };
+               4C2505B616D2DF9F002CE025 /* Icon.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = Icon.icns; sourceTree = "<group>"; };
+               4C328D2F1778EC4F0015EED1 /* AOSUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AOSUI.framework; path = ../../../../../../../System/Library/PrivateFrameworks/AOSUI.framework; sourceTree = "<group>"; };
+               4C49390C16E51ACE00CE110C /* com.apple.security.keychain-circle-notification.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "com.apple.security.keychain-circle-notification.plist"; sourceTree = "<group>"; };
+               4C5DD44217A5E31900696A79 /* KNPersistantState.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KNPersistantState.h; sourceTree = "<group>"; };
+               4C5DD44317A5E31900696A79 /* KNPersistantState.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KNPersistantState.m; sourceTree = "<group>"; };
+               4C5DD46B17A5F67300696A79 /* AppleSystemInfo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppleSystemInfo.framework; path = ../../../../../../../System/Library/PrivateFrameworks/AppleSystemInfo.framework; sourceTree = "<group>"; };
+               4C7D453B17BEE69B00DDD88F /* NSString+compactDescription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+compactDescription.h"; sourceTree = "<group>"; };
+               4C7D453C17BEE69B00DDD88F /* NSString+compactDescription.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+compactDescription.m"; sourceTree = "<group>"; };
+               4C7D456417BEE6B700DDD88F /* NSDictionary+compactDescription.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+compactDescription.h"; sourceTree = "<group>"; };
+               4C7D456517BEE6B700DDD88F /* NSDictionary+compactDescription.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+compactDescription.m"; sourceTree = "<group>"; };
+               4C7D456617BEE6B700DDD88F /* NSSet+compactDescription.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSSet+compactDescription.h"; sourceTree = "<group>"; };
+               4C7D456717BEE6B700DDD88F /* NSSet+compactDescription.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSSet+compactDescription.m"; sourceTree = "<group>"; };
                4C8313C814F5A26500DF7FDC /* libcorecrypto.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libcorecrypto.dylib; path = /usr/lib/system/libcorecrypto.dylib; sourceTree = "<absolute>"; };
                4C8313C814F5A26500DF7FDC /* libcorecrypto.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libcorecrypto.dylib; path = /usr/lib/system/libcorecrypto.dylib; sourceTree = "<absolute>"; };
+               4C85DED816DBD5BF00ED8D47 /* KDCirclePeer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KDCirclePeer.h; sourceTree = "<group>"; };
+               4C85DED916DBD5BF00ED8D47 /* KDCirclePeer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KDCirclePeer.m; sourceTree = "<group>"; };
+               4C96F73816D5372C00D3B39D /* KDSecCircle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KDSecCircle.h; sourceTree = "<group>"; };
+               4C96F73916D5372C00D3B39D /* KDSecCircle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KDSecCircle.m; sourceTree = "<group>"; };
+               4C96F76116D54C9600D3B39D /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/CoreFoundation.framework; sourceTree = DEVELOPER_DIR; };
+               4C96F7C116D6DF8300D3B39D /* Keychain Circle Notification.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Keychain Circle Notification.app"; sourceTree = BUILT_PRODUCTS_DIR; };
+               4C96F7C516D6DF8400D3B39D /* Keychain Circle Notification-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Keychain Circle Notification-Info.plist"; sourceTree = "<group>"; };
+               4C96F7C716D6DF8400D3B39D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+               4C96F7C916D6DF8400D3B39D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+               4C96F7CB16D6DF8400D3B39D /* Keychain Circle Notification-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Keychain Circle Notification-Prefix.pch"; sourceTree = "<group>"; };
+               4C96F7CD16D6DF8400D3B39D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = "<group>"; };
+               4C96F7CF16D6DF8400D3B39D /* KNAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KNAppDelegate.h; sourceTree = "<group>"; };
+               4C96F7D016D6DF8400D3B39D /* KNAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KNAppDelegate.m; sourceTree = "<group>"; };
+               4C96F7D316D6DF8400D3B39D /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = "<group>"; };
+               4C97761D17BEB23E0002BFE4 /* AOSAccounts.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AOSAccounts.framework; path = ../../../../../../../System/Library/PrivateFrameworks/AOSAccounts.framework; sourceTree = "<group>"; };
+               4CB23B46169F5873003A0131 /* security2 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = security2; sourceTree = BUILT_PRODUCTS_DIR; };
+               4CB23B4B169F5873003A0131 /* security2.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = security2.1; sourceTree = "<group>"; };
+               4CB23B80169F58DE003A0131 /* security_tool_commands.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = security_tool_commands.c; sourceTree = "<group>"; };
+               4CB23B82169F592C003A0131 /* sub_commands.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = sub_commands.h; sourceTree = "<group>"; };
+               4CB23B91169F5CFF003A0131 /* command.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = command.xcconfig; sourceTree = "<group>"; };
+               4CB86AE6167A6FF200F46643 /* SOSCircle.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SOSCircle.h; path = ../sec/SOSCircle/SecureObjectSync/SOSCircle.h; sourceTree = "<group>"; };
+               4CB86AE7167A6FF200F46643 /* SOSCloudCircle.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SOSCloudCircle.h; path = ../sec/SOSCircle/SecureObjectSync/SOSCloudCircle.h; sourceTree = "<group>"; };
+               4CB86AE8167A6FF200F46643 /* SOSCloudCircleInternal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SOSCloudCircleInternal.h; path = ../sec/SOSCircle/SecureObjectSync/SOSCloudCircleInternal.h; sourceTree = "<group>"; };
+               4CB86AE9167A6FF200F46643 /* SOSEngine.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SOSEngine.h; path = ../sec/SOSCircle/SecureObjectSync/SOSEngine.h; sourceTree = "<group>"; };
+               4CB86AEA167A6FF300F46643 /* SOSFullPeerInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SOSFullPeerInfo.h; path = ../sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.h; sourceTree = "<group>"; };
+               4CB86AEB167A6FF300F46643 /* SOSInternal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SOSInternal.h; path = ../sec/SOSCircle/SecureObjectSync/SOSInternal.h; sourceTree = "<group>"; };
+               4CB86AEC167A6FF300F46643 /* SOSPeer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SOSPeer.h; path = ../sec/SOSCircle/SecureObjectSync/SOSPeer.h; sourceTree = "<group>"; };
+               4CB86AED167A6FF300F46643 /* SOSPeerInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SOSPeerInfo.h; path = ../sec/SOSCircle/SecureObjectSync/SOSPeerInfo.h; sourceTree = "<group>"; };
+               4CB86AEE167A6FF300F46643 /* SOSTransport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SOSTransport.h; path = ../sec/SOSCircle/SecureObjectSync/SOSTransport.h; sourceTree = "<group>"; };
+               4CB86AFA167A8F2200F46643 /* SOSAccount.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SOSAccount.h; path = ../sec/SOSCircle/SecureObjectSync/SOSAccount.h; sourceTree = "<group>"; };
+               4CB9121C17750E6500C1CCCA /* entitlments.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = entitlments.plist; sourceTree = "<group>"; };
+               4CC7A7B316CC2A84003E10C1 /* Cloud Keychain Utility.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Cloud Keychain Utility.app"; sourceTree = BUILT_PRODUCTS_DIR; };
+               4CC7A7B716CC2A85003E10C1 /* Keychain-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Keychain-Info.plist"; sourceTree = "<group>"; };
+               4CC7A7B916CC2A85003E10C1 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+               4CC7A7BB16CC2A85003E10C1 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+               4CC7A7BD16CC2A85003E10C1 /* Keychain-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Keychain-Prefix.pch"; sourceTree = "<group>"; };
+               4CC7A7BF16CC2A85003E10C1 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = "<group>"; };
+               4CC7A7C116CC2A85003E10C1 /* KDAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KDAppDelegate.h; sourceTree = "<group>"; };
+               4CC7A7C216CC2A85003E10C1 /* KDAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KDAppDelegate.m; sourceTree = "<group>"; };
+               4CC7A7C516CC2A85003E10C1 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = "<group>"; };
+               4CC7A7F216CC2B0A003E10C1 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/Security.framework; sourceTree = DEVELOPER_DIR; };
+               4CC7A7F416CD95D2003E10C1 /* KDSecItems.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KDSecItems.h; sourceTree = "<group>"; };
+               4CC7A7F516CD95D3003E10C1 /* KDSecItems.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KDSecItems.m; sourceTree = "<group>"; };
+               4CD1980B16DD3BDF00A9E8FD /* NSArray+mapWithBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSArray+mapWithBlock.h"; path = "Keychain Circle Notification/NSArray+mapWithBlock.h"; sourceTree = SOURCE_ROOT; };
+               4CD1980C16DD3BDF00A9E8FD /* NSArray+mapWithBlock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSArray+mapWithBlock.m"; path = "Keychain Circle Notification/NSArray+mapWithBlock.m"; sourceTree = SOURCE_ROOT; };
+               4CF42B8F159E674D00ACACE1 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+               4CF42BB515A3947F00ACACE1 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = /System/Library/Frameworks/Security.framework; sourceTree = "<absolute>"; };
+               4CFE1CB816DD4B9C0026E900 /* CloudKeychain.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = CloudKeychain.icns; sourceTree = "<group>"; };
+               5214700616977CB800DF0DB3 /* CloudKeychainProxy.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CloudKeychainProxy.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
+               5214700716977CB800DF0DB3 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
+               5214700A16977CB800DF0DB3 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
+               5214700B16977CB800DF0DB3 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
+               5214700C16977CB800DF0DB3 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+               5214700F16977CB800DF0DB3 /* CloudKeychainProxy-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "CloudKeychainProxy-Info.plist"; sourceTree = "<group>"; };
+               5214701116977CB800DF0DB3 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+               5214702416977FEC00DF0DB3 /* cloudkeychain.entitlements.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = cloudkeychain.entitlements.plist; sourceTree = "<group>"; };
+               5214702516977FEC00DF0DB3 /* com.apple.security.cloudkeychainproxy.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = com.apple.security.cloudkeychainproxy.plist; sourceTree = "<group>"; };
                52AEA484153C7581005AFC59 /* tsaSupportPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tsaSupportPriv.h; path = libsecurity_smime/lib/tsaSupportPriv.h; sourceTree = SOURCE_ROOT; };
                52B006BF15238F76005D4556 /* TimeStampingPrefs.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = TimeStampingPrefs.plist; sourceTree = "<group>"; };
                52B5A9C01519330300664F11 /* tsaSupport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = tsaSupport.h; path = libsecurity_smime/lib/tsaSupport.h; sourceTree = SOURCE_ROOT; };
                52B5A9C11519330300664F11 /* tsaTemplates.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = tsaTemplates.h; path = libsecurity_smime/lib/tsaTemplates.h; sourceTree = SOURCE_ROOT; };
                52AEA484153C7581005AFC59 /* tsaSupportPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tsaSupportPriv.h; path = libsecurity_smime/lib/tsaSupportPriv.h; sourceTree = SOURCE_ROOT; };
                52B006BF15238F76005D4556 /* TimeStampingPrefs.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = TimeStampingPrefs.plist; sourceTree = "<group>"; };
                52B5A9C01519330300664F11 /* tsaSupport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = tsaSupport.h; path = libsecurity_smime/lib/tsaSupport.h; sourceTree = SOURCE_ROOT; };
                52B5A9C11519330300664F11 /* tsaTemplates.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = tsaTemplates.h; path = libsecurity_smime/lib/tsaTemplates.h; sourceTree = SOURCE_ROOT; };
+               52C3D235169B56860091D9D3 /* ckdmain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ckdmain.m; path = sec/SOSCircle/CloudKeychainProxy/ckdmain.m; sourceTree = SOURCE_ROOT; };
+               5328475217850741009118DC /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
+               721680A5179B40F600406BB4 /* iCloudStats */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = iCloudStats; sourceTree = BUILT_PRODUCTS_DIR; };
+               721680A8179B40F600406BB4 /* main.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = "<group>"; };
+               721680AA179B40F600406BB4 /* iCloudStats.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = iCloudStats.1; sourceTree = "<group>"; };
+               721680BD179B4F9100406BB4 /* com.apple.iCloudStats.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.iCloudStats.plist; sourceTree = "<group>"; };
+               722CF215175D5E5000BCE0A5 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.Internal.sdk/System/Library/Frameworks/Security.framework; sourceTree = DEVELOPER_DIR; };
+               72756BFE175D485D00F52070 /* cloud_keychain_diagnose */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = cloud_keychain_diagnose; sourceTree = BUILT_PRODUCTS_DIR; };
+               72756C04175D485D00F52070 /* cloud_keychain_diagnose-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "cloud_keychain_diagnose-Prefix.pch"; sourceTree = "<group>"; };
+               72756C30175D48C100F52070 /* cloud_keychain_diagnose.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cloud_keychain_diagnose.c; path = utilities/src/cloud_keychain_diagnose.c; sourceTree = SOURCE_ROOT; };
+               72756C9A175D51B100F52070 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/IOKit.framework; sourceTree = DEVELOPER_DIR; };
+               72756C9C175D51C900F52070 /* Kernel.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Kernel.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/Kernel.framework; sourceTree = DEVELOPER_DIR; };
+               72756C9E175D566800F52070 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.Internal.sdk/System/Library/Frameworks/CoreFoundation.framework; sourceTree = DEVELOPER_DIR; };
+               72A3DE5B179B2C0400E78247 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.Internal.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
+               BE8C5F0916F7CE450074CF86 /* framework.sb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = framework.sb; sourceTree = "<group>"; };
+               BEC3A76716F79497003E5634 /* SecTaskPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecTaskPriv.h; path = libsecurity_codesigning/lib/SecTaskPriv.h; sourceTree = SOURCE_ROOT; };
                C288A0881505795D00E773B7 /* libOpenScriptingUtil.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libOpenScriptingUtil.dylib; path = ../../../../../usr/lib/libOpenScriptingUtil.dylib; sourceTree = "<group>"; };
                C288A0881505795D00E773B7 /* libOpenScriptingUtil.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libOpenScriptingUtil.dylib; path = ../../../../../usr/lib/libOpenScriptingUtil.dylib; sourceTree = "<group>"; };
+               CDDE9D1C1729DF250013B0E8 /* SecPasswordGenerate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecPasswordGenerate.h; path = ../sec/Security/SecPasswordGenerate.h; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
+               0C6C630815D193C800BC68CD /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               18CD682717272EBC005345FB /* libaks.a in Frameworks */,
+                               0CBD50DC16C32C8D00713B6C /* libutilities.a in Frameworks */,
+                               0CCEBDB416C2D026001BD7F6 /* libregressions.a in Frameworks */,
+                               52669053169D181900ED8231 /* Security.framework in Frameworks */,
+                               4AD6F6F91651D2A600DB4CE6 /* Foundation.framework in Frameworks */,
+                               0C6C633015D19FF500BC68CD /* CoreFoundation.framework in Frameworks */,
+                               0C6C632A15D1989900BC68CD /* libsecurity_ssl_regressions.a in Frameworks */,
+                               0CAA7AB516C9A72A00A32C6D /* libsecurity_keychain_regressions.a in Frameworks */,
+                               18CD684E17272EE2005345FB /* IOKit.framework in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               0CC3351B16C1ED8000399E53 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               187A05B1170393FF0038C158 /* libaks.a in Frameworks */,
+                               18363C1417026084002D5C1C /* IOKit.framework in Frameworks */,
+                               39BFB04516D304DE0022564B /* SystemConfiguration.framework in Frameworks */,
+                               0CC3351E16C1ED8000399E53 /* libDER.a in Frameworks */,
+                               0C10987616CAAE8200803B8F /* libASN1.a in Frameworks */,
+                               0CC3356316C1EFBE00399E53 /* libregressions.a in Frameworks */,
+                               0CC3351F16C1ED8000399E53 /* libSecItemShimOSX.a in Frameworks */,
+                               0CC3352016C1ED8000399E53 /* libutilities.a in Frameworks */,
+                               0CC3351C16C1ED8000399E53 /* libsecurity.a in Frameworks */,
+                               0CCEBDB616C2E431001BD7F6 /* libsecurityd.a in Frameworks */,
+                               0CC3352616C1ED8000399E53 /* libsecipc_client.a in Frameworks */,
+                               0CC3352716C1ED8000399E53 /* libSecureObjectSync.a in Frameworks */,
+                               0CCEBDB816C2E6CE001BD7F6 /* libsqlite3.dylib in Frameworks */,
+                               0CC3352216C1ED8000399E53 /* libcorecrypto.dylib in Frameworks */,
+                               0CC3352116C1ED8000399E53 /* Foundation.framework in Frameworks */,
+                               0CC3352416C1ED8000399E53 /* CoreFoundation.framework in Frameworks */,
+                               0CCEBDB716C2E6B0001BD7F6 /* CFNetwork.framework in Frameworks */,
+                               0CC3352316C1ED8000399E53 /* libSOSRegressions.a in Frameworks */,
+                               0CCEBDBB16C30924001BD7F6 /* libutilitiesRegressions.a in Frameworks */,
+                               0C4EAE7717668DDF00773425 /* libsecdRegressions.a in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                18073847146D0D4E00F05C24 /* Frameworks */ = {
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                18073847146D0D4E00F05C24 /* Frameworks */ = {
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               5241C60D16DC1BA100DB5C6F /* libSecOtrOSX.a in Frameworks */,
+                               5208C0D716A0C96F0062DDC5 /* libSecureObjectSync.a in Frameworks */,
+                               52146FDB1697673900DF0DB3 /* libutilities.a in Frameworks */,
                                4C8313C914F5A26500DF7FDC /* libcorecrypto.dylib in Frameworks */,
                                1885B45214D9AB8100519375 /* libASN1.a in Frameworks */,
                                18270F6114CF656E00B05E7F /* libsecipc_client.a in Frameworks */,
                                4C8313C914F5A26500DF7FDC /* libcorecrypto.dylib in Frameworks */,
                                1885B45214D9AB8100519375 /* libASN1.a in Frameworks */,
                                18270F6114CF656E00B05E7F /* libsecipc_client.a in Frameworks */,
                                182BB5B6146FF090000BF1F3 /* libauto.dylib in Frameworks */,
                                182BB5B4146FF04C000BF1F3 /* libxar.dylib in Frameworks */,
                                182BB5B2146FF039000BF1F3 /* libz.dylib in Frameworks */,
                                182BB5B6146FF090000BF1F3 /* libauto.dylib in Frameworks */,
                                182BB5B4146FF04C000BF1F3 /* libxar.dylib in Frameworks */,
                                182BB5B2146FF039000BF1F3 /* libz.dylib in Frameworks */,
-                               182BB5B0146FEFE2000BF1F3 /* libstdc++.dylib in Frameworks */,
                                182BB5AE146FEF43000BF1F3 /* libsqlite3.dylib in Frameworks */,
                                182BB5AC146FEF15000BF1F3 /* libpam.dylib in Frameworks */,
                                182BB5AA146FEE50000BF1F3 /* CoreFoundation.framework in Frameworks */,
                                182BB5AE146FEF43000BF1F3 /* libsqlite3.dylib in Frameworks */,
                                182BB5AC146FEF15000BF1F3 /* libpam.dylib in Frameworks */,
                                182BB5AA146FEE50000BF1F3 /* CoreFoundation.framework in Frameworks */,
                                1879B546146DE192007E536C /* libsecurity_utilities.a in Frameworks */,
                                1879B570146DE2E6007E536C /* libsecurity_cdsa_utils.a in Frameworks */,
                                C288A0891505796F00E773B7 /* libOpenScriptingUtil.dylib in Frameworks */,
                                1879B546146DE192007E536C /* libsecurity_utilities.a in Frameworks */,
                                1879B570146DE2E6007E536C /* libsecurity_cdsa_utils.a in Frameworks */,
                                C288A0891505796F00E773B7 /* libOpenScriptingUtil.dylib in Frameworks */,
+                               4CC8DEA416DC1AC800462517 /* libSecOtrOSX.a in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               189757871700CF4C00672567 /* libaks.a in Frameworks */,
+                               395E7CEE16C64EA500CD82A4 /* SystemConfiguration.framework in Frameworks */,
+                               5208BF4F16A0993C0062DDC5 /* libsecurity.a in Frameworks */,
+                               AAF3DCCB1666D03300376593 /* libsecurity_utilities.a in Frameworks */,
+                               4C7D8765160A74C400D041E3 /* libutilities.a in Frameworks */,
+                               18F2360115CAF41200060520 /* libsecurity_codesigning.a in Frameworks */,
                                1831329B14EB2C6D00F0BCAC /* libASN1.a in Frameworks */,
                                1831329C14EB2C6D00F0BCAC /* libDER.a in Frameworks */,
                                18270F0014CF42CA00B05E7F /* libcorecrypto.a in Frameworks */,
                                1831329B14EB2C6D00F0BCAC /* libASN1.a in Frameworks */,
                                1831329C14EB2C6D00F0BCAC /* libDER.a in Frameworks */,
                                18270F0014CF42CA00B05E7F /* libcorecrypto.a in Frameworks */,
                                18270EFA14CF426200B05E7F /* libsqlite3.dylib in Frameworks */,
                                18270EF914CF425100B05E7F /* libbsm.dylib in Frameworks */,
                                18270EE814CF294500B05E7F /* libsecurityd.a in Frameworks */,
                                18270EFA14CF426200B05E7F /* libsqlite3.dylib in Frameworks */,
                                18270EF914CF425100B05E7F /* libbsm.dylib in Frameworks */,
                                18270EE814CF294500B05E7F /* libsecurityd.a in Frameworks */,
-                               18270EE714CF292100B05E7F /* libsecurity.a in Frameworks */,
+                               4C01DF14164C3E7C006798CD /* libSecureObjectSync.a in Frameworks */,
+                               4C8D8651177A752D0019A804 /* libsecipc_client.a in Frameworks */,
                                18270EF814CF424900B05E7F /* CoreFoundation.framework in Frameworks */,
                                18270EFC14CF427800B05E7F /* CFNetwork.framework in Frameworks */,
                        );
                                18270EF814CF424900B05E7F /* CoreFoundation.framework in Frameworks */,
                                18270EFC14CF427800B05E7F /* CFNetwork.framework in Frameworks */,
                        );
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
-                               182BB597146FE286000BF1F3 /* Security.framework in Frameworks */,
-                               182BB594146FE1EE000BF1F3 /* libantlr2c++.a in Frameworks */,
                                182BB592146FE1D7000BF1F3 /* CoreFoundation.framework in Frameworks */,
                                182BB591146FE12F000BF1F3 /* libsecurity_utilities.a in Frameworks */,
                                182BB590146FE125000BF1F3 /* libsecurity_cdsa_utilities.a in Frameworks */,
                                182BB589146FE013000BF1F3 /* libsecurity_codesigning.a in Frameworks */,
                                182BB592146FE1D7000BF1F3 /* CoreFoundation.framework in Frameworks */,
                                182BB591146FE12F000BF1F3 /* libsecurity_utilities.a in Frameworks */,
                                182BB590146FE125000BF1F3 /* libsecurity_cdsa_utilities.a in Frameworks */,
                                182BB589146FE013000BF1F3 /* libsecurity_codesigning.a in Frameworks */,
+                               529E948D169E29470000AC9B /* Security.framework in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               18F234E815C9F9A600060520 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               18F2353815C9FDEF00060520 /* libsqlite3.dylib in Frameworks */,
+                               18F2353715C9FDE400060520 /* libbsm.dylib in Frameworks */,
+                               18F2353615C9FDD200060520 /* Security.framework in Frameworks */,
+                               18F2353515C9FDB700060520 /* CoreFoundation.framework in Frameworks */,
+                               187D6B9815D4476D00E27494 /* IOKit.framework in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               4C96F7BE16D6DF8300D3B39D /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               4C97761E17BEB23E0002BFE4 /* AOSAccounts.framework in Frameworks */,
+                               4C5DD46C17A5F67300696A79 /* AppleSystemInfo.framework in Frameworks */,
+                               4C328D301778EC4F0015EED1 /* AOSUI.framework in Frameworks */,
+                               4CAEACCD16D6FC7600263776 /* Security.framework in Frameworks */,
+                               4C96F7C216D6DF8400D3B39D /* Cocoa.framework in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               4CB23B43169F5873003A0131 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               52CD052316A0E24900218387 /* Security.framework in Frameworks */,
+                               4CB23B8C169F59AD003A0131 /* libutilities.a in Frameworks */,
+                               4CB23B8A169F599A003A0131 /* libSecurityCommands.a in Frameworks */,
+                               4CB23B8B169F599A003A0131 /* libSOSCommands.a in Frameworks */,
+                               52CD052416A0E2A000218387 /* libcorecrypto.dylib in Frameworks */,
+                               4CB23B89169F5990003A0131 /* libSecurityTool.a in Frameworks */,
+                               4CB23B47169F5873003A0131 /* CoreFoundation.framework in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               4CC7A7B016CC2A84003E10C1 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               4CC7A7F316CC2B0A003E10C1 /* Security.framework in Frameworks */,
+                               4CC7A7B416CC2A85003E10C1 /* Cocoa.framework in Frameworks */,
+                               4C96F76216D54C9600D3B39D /* CoreFoundation.framework in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               5214700316977CB800DF0DB3 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               5214702A1697855800DF0DB3 /* Foundation.framework in Frameworks */,
+                               5214701E16977DA700DF0DB3 /* libCloudKeychainProxy.a in Frameworks */,
+                               5214701D16977D9500DF0DB3 /* libutilities.a in Frameworks */,
+                               529E948C169E29450000AC9B /* Security.framework in Frameworks */,
+                               0C4EAE4C1766864F00773425 /* libaks.a in Frameworks */,
+                               0C4EAE761766875E00773425 /* IOKit.framework in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               721680A2179B40F600406BB4 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               721680AF179B4C3200406BB4 /* Security.framework in Frameworks */,
+                               721680A6179B40F600406BB4 /* CoreFoundation.framework in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               72756BFB175D485D00F52070 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               72CC327C175D6E1800217455 /* Security.framework in Frameworks */,
+                               72CC327B175D6E0A00217455 /* CoreFoundation.framework in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
+               0C6C630D15D193C800BC68CD /* sectests */ = {
+                       isa = PBXGroup;
+                       children = (
+                               18ED4D2317270DB6003AF11B /* SecurityTests-Entitlements.plist */,
+                               0C6C630E15D193C800BC68CD /* main.c */,
+                               0C6C632415D1964200BC68CD /* testlist.h */,
+                       );
+                       path = sectests;
+                       sourceTree = "<group>";
+               };
+               0C6D0063177B54A70095D167 /* asl */ = {
+                       isa = PBXGroup;
+                       children = (
+                               0C6D0064177B54C60095D167 /* com.apple.securityd */,
+                       );
+                       name = asl;
+                       path = lib;
+                       sourceTree = "<group>";
+               };
+               0C6D77DF15C8C06500BB4405 /* Products */ = {
+                       isa = PBXGroup;
+                       children = (
+                               0C6D77E915C8C06600BB4405 /* tlsnke.kext */,
+                               0C6D77EB15C8C06600BB4405 /* tlsnketest */,
+                               0C6D77ED15C8C06600BB4405 /* libtlssocket.a */,
+                       );
+                       name = Products;
+                       sourceTree = "<group>";
+               };
+               0C6D77EE15C8C07C00BB4405 /* tlsnke */ = {
+                       isa = PBXGroup;
+                       children = (
+                               0C6D77DE15C8C06500BB4405 /* tlsnke.xcodeproj */,
+                       );
+                       name = tlsnke;
+                       sourceTree = "<group>";
+               };
+               0CC3355516C1EEAD00399E53 /* secdtests */ = {
+                       isa = PBXGroup;
+                       children = (
+                               0CC3355716C1EEE700399E53 /* main.c */,
+                               0CC3355816C1EEE700399E53 /* testlist.h */,
+                       );
+                       name = secdtests;
+                       sourceTree = "<group>";
+               };
+               0CC3355C16C1EF5D00399E53 /* Products */ = {
+                       isa = PBXGroup;
+                       children = (
+                               0CC3356016C1EF5D00399E53 /* libregressions.a */,
+                       );
+                       name = Products;
+                       sourceTree = "<group>";
+               };
                1807383F146D0D4E00F05C24 = {
                        isa = PBXGroup;
                        children = (
                1807383F146D0D4E00F05C24 = {
                        isa = PBXGroup;
                        children = (
+                               0C6D0063177B54A70095D167 /* asl */,
+                               4C1288F615FFECF2008CE3E3 /* utilities */,
                                18073854146D0D4E00F05C24 /* lib */,
                                181EA3D0146D1ED200A6D320 /* libsecurity */,
                                186CDD0314CA10E700AF9171 /* sec */,
                                186CDE7914CA3A3800AF9171 /* secd */,
                                18073854146D0D4E00F05C24 /* lib */,
                                181EA3D0146D1ED200A6D320 /* libsecurity */,
                                186CDD0314CA10E700AF9171 /* sec */,
                                186CDE7914CA3A3800AF9171 /* secd */,
+                               0C6D77EE15C8C07C00BB4405 /* tlsnke */,
                                181EA421146D4A2A00A6D320 /* config */,
                                181EA421146D4A2A00A6D320 /* config */,
+                               0CC3355516C1EEAD00399E53 /* secdtests */,
+                               0C6C630D15D193C800BC68CD /* sectests */,
+                               18F234ED15C9F9A700060520 /* authd */,
+                               5214700D16977CB800DF0DB3 /* CloudKeychainProxy */,
+                               4CB23B48169F5873003A0131 /* security2 */,
+                               4CC7A7B516CC2A85003E10C1 /* KeychainDemoApp */,
+                               4C96F7C316D6DF8400D3B39D /* Keychain Circle Notification */,
+                               72756C00175D485D00F52070 /* cloud_keychain_diagnose */,
+                               721680A7179B40F600406BB4 /* iCloudStats */,
                                1807384D146D0D4E00F05C24 /* Frameworks */,
                                1807384C146D0D4E00F05C24 /* Products */,
                        );
                                1807384D146D0D4E00F05C24 /* Frameworks */,
                                1807384C146D0D4E00F05C24 /* Products */,
                        );
                                182BB568146F4DCA000BF1F3 /* csparser.bundle */,
                                18FE67EA1471A3AA00A2CBE3 /* Security.framework */,
                                18270ED614CF282600B05E7F /* secd */,
                                182BB568146F4DCA000BF1F3 /* csparser.bundle */,
                                18FE67EA1471A3AA00A2CBE3 /* Security.framework */,
                                18270ED614CF282600B05E7F /* secd */,
+                               0C6C630B15D193C800BC68CD /* sectests */,
+                               18F234EB15C9F9A600060520 /* authd.xpc */,
+                               5214700616977CB800DF0DB3 /* CloudKeychainProxy.bundle */,
+                               4CB23B46169F5873003A0131 /* security2 */,
+                               0CC3352D16C1ED8000399E53 /* secdtests */,
+                               4CC7A7B316CC2A84003E10C1 /* Cloud Keychain Utility.app */,
+                               4C96F7C116D6DF8300D3B39D /* Keychain Circle Notification.app */,
+                               72756BFE175D485D00F52070 /* cloud_keychain_diagnose */,
+                               721680A5179B40F600406BB4 /* iCloudStats */,
                        );
                        name = Products;
                        sourceTree = "<group>";
                        );
                        name = Products;
                        sourceTree = "<group>";
                1807384D146D0D4E00F05C24 /* Frameworks */ = {
                        isa = PBXGroup;
                        children = (
                1807384D146D0D4E00F05C24 /* Frameworks */ = {
                        isa = PBXGroup;
                        children = (
+                               4C97761D17BEB23E0002BFE4 /* AOSAccounts.framework */,
+                               4C5DD46B17A5F67300696A79 /* AppleSystemInfo.framework */,
+                               72A3DE5B179B2C0400E78247 /* Foundation.framework */,
+                               4C328D2F1778EC4F0015EED1 /* AOSUI.framework */,
+                               722CF215175D5E5000BCE0A5 /* Security.framework */,
+                               72756C9E175D566800F52070 /* CoreFoundation.framework */,
+                               72756C9C175D51C900F52070 /* Kernel.framework */,
+                               72756C9A175D51B100F52070 /* IOKit.framework */,
+                               18752C1D16F2837A004E2799 /* libaks.a */,
+                               4C96F76116D54C9600D3B39D /* CoreFoundation.framework */,
+                               4CC7A7F216CC2B0A003E10C1 /* Security.framework */,
+                               395E7CED16C64EA500CD82A4 /* SystemConfiguration.framework */,
+                               18F2360015CAF41100060520 /* libsecurity_codesigning.a */,
+                               18F235FC15CA0EDB00060520 /* libstdc++.6.0.9.dylib */,
+                               18F235F915CA0DB000060520 /* libsecurity_agent_client.a */,
+                               18F235F715CA0D9D00060520 /* libsecurity_utilities.a */,
+                               18F235F515CA0D8100060520 /* libsecurity_cdsa_utilities.a */,
+                               4CF42BB515A3947F00ACACE1 /* Security.framework */,
                                1831329914EB2C6D00F0BCAC /* libASN1.a */,
                                1831329A14EB2C6D00F0BCAC /* libDER.a */,
                                18270EFF14CF42CA00B05E7F /* libcorecrypto.a */,
                                1831329914EB2C6D00F0BCAC /* libASN1.a */,
                                1831329A14EB2C6D00F0BCAC /* libDER.a */,
                                18270EFF14CF42CA00B05E7F /* libcorecrypto.a */,
                                182BB5B5146FF08F000BF1F3 /* libauto.dylib */,
                                182BB5B3146FF04C000BF1F3 /* libxar.dylib */,
                                182BB5B1146FF039000BF1F3 /* libz.dylib */,
                                182BB5B5146FF08F000BF1F3 /* libauto.dylib */,
                                182BB5B3146FF04C000BF1F3 /* libxar.dylib */,
                                182BB5B1146FF039000BF1F3 /* libz.dylib */,
-                               182BB5AF146FEFE2000BF1F3 /* libstdc++.dylib */,
                                182BB5AD146FEF43000BF1F3 /* libsqlite3.dylib */,
                                182BB5AB146FEF14000BF1F3 /* libpam.dylib */,
                                182BB593146FE1ED000BF1F3 /* libantlr2c++.a */,
                                C288A0881505795D00E773B7 /* libOpenScriptingUtil.dylib */,
                                182BB569146F4DCA000BF1F3 /* CoreFoundation.framework */,
                                182BB5AD146FEF43000BF1F3 /* libsqlite3.dylib */,
                                182BB5AB146FEF14000BF1F3 /* libpam.dylib */,
                                182BB593146FE1ED000BF1F3 /* libantlr2c++.a */,
                                C288A0881505795D00E773B7 /* libOpenScriptingUtil.dylib */,
                                182BB569146F4DCA000BF1F3 /* CoreFoundation.framework */,
+                               4CF42B8F159E674D00ACACE1 /* Foundation.framework */,
+                               5214700716977CB800DF0DB3 /* Cocoa.framework */,
+                               5214700916977CB800DF0DB3 /* Other Frameworks */,
                        );
                        name = Frameworks;
                        sourceTree = "<group>";
                        );
                        name = Frameworks;
                        sourceTree = "<group>";
                                18073855146D0D4E00F05C24 /* Supporting Files */,
                                182BB555146F450F000BF1F3 /* plugins */,
                                182BB5A9146FEB27000BF1F3 /* derived_src */,
                                18073855146D0D4E00F05C24 /* Supporting Files */,
                                182BB555146F450F000BF1F3 /* plugins */,
                                182BB5A9146FEB27000BF1F3 /* derived_src */,
+                               18A5493115EFD2F40059E6DC /* dummy.cpp */,
                        );
                        path = lib;
                        sourceTree = "<group>";
                        );
                        path = lib;
                        sourceTree = "<group>";
                18073855146D0D4E00F05C24 /* Supporting Files */ = {
                        isa = PBXGroup;
                        children = (
                18073855146D0D4E00F05C24 /* Supporting Files */ = {
                        isa = PBXGroup;
                        children = (
-                               182BB562146F4C73000BF1F3 /* security.exp */,
+                               182BB562146F4C73000BF1F3 /* security.exp-in */,
                                182BB55D146F4544000BF1F3 /* generateErrStrings.pl */,
                                182BB55E146F4544000BF1F3 /* Security.order */,
                                18073856146D0D4E00F05C24 /* Info-Security.plist */,
                                182BB55D146F4544000BF1F3 /* generateErrStrings.pl */,
                                182BB55E146F4544000BF1F3 /* Security.order */,
                                18073856146D0D4E00F05C24 /* Info-Security.plist */,
                181EA421146D4A2A00A6D320 /* config */ = {
                        isa = PBXGroup;
                        children = (
                181EA421146D4A2A00A6D320 /* config */ = {
                        isa = PBXGroup;
                        children = (
+                               18BFC44017C43393005DE6C3 /* executable.xcconfig */,
                                18BBC6801471EF1600F2B224 /* security.xcconfig */,
                                181EA422146D4A2A00A6D320 /* base.xcconfig */,
                                181EA423146D4A2A00A6D320 /* debug.xcconfig */,
                                181EA424146D4A2A00A6D320 /* lib.xcconfig */,
                                18BBC6801471EF1600F2B224 /* security.xcconfig */,
                                181EA422146D4A2A00A6D320 /* base.xcconfig */,
                                181EA423146D4A2A00A6D320 /* debug.xcconfig */,
                                181EA424146D4A2A00A6D320 /* lib.xcconfig */,
+                               0C6C632F15D19DE600BC68CD /* test.xcconfig */,
+                               4CB23B91169F5CFF003A0131 /* command.xcconfig */,
                                181EA425146D4A2A00A6D320 /* release.xcconfig */,
                        );
                        path = config;
                                181EA425146D4A2A00A6D320 /* release.xcconfig */,
                        );
                        path = config;
                182BB228146F0674000BF1F3 /* Resources */ = {
                        isa = PBXGroup;
                        children = (
                182BB228146F0674000BF1F3 /* Resources */ = {
                        isa = PBXGroup;
                        children = (
+                               187D6B8F15D4359F00E27494 /* authorization.buttons.strings */,
+                               BE8C5F0916F7CE450074CF86 /* framework.sb */,
+                               187D6B9115D4359F00E27494 /* authorization.prompts.strings */,
                                52B006BF15238F76005D4556 /* TimeStampingPrefs.plist */,
                                188AD8D81471FE3D0081C619 /* FDELocalizable.strings */,
                                188AD8DA1471FE3D0081C619 /* InfoPlist.strings */,
                                52B006BF15238F76005D4556 /* TimeStampingPrefs.plist */,
                                188AD8D81471FE3D0081C619 /* FDELocalizable.strings */,
                                188AD8DA1471FE3D0081C619 /* InfoPlist.strings */,
                                18B647EF14D9F75300F538BF /* generateErrStrings.mm */,
                                18500F9F14708F19006F9AB4 /* SecErrorMessages.strings */,
                                18500F9A14708D0E006F9AB4 /* SecDebugErrorMessages.strings */,
                                18B647EF14D9F75300F538BF /* generateErrStrings.mm */,
                                18500F9F14708F19006F9AB4 /* SecErrorMessages.strings */,
                                18500F9A14708D0E006F9AB4 /* SecDebugErrorMessages.strings */,
-                               182BB5A7146FE6D4000BF1F3 /* security_exports.s */,
                        );
                        name = derived_src;
                        sourceTree = "<group>";
                        );
                        name = derived_src;
                        sourceTree = "<group>";
                                18270C7D14CE573D00B05E7F /* libsecurityd.a */,
                                186CDD1E14CA11C700AF9171 /* libSecItemShimOSX.a */,
                                18270F6014CF655B00B05E7F /* libsecipc_client.a */,
                                18270C7D14CE573D00B05E7F /* libsecurityd.a */,
                                186CDD1E14CA11C700AF9171 /* libSecItemShimOSX.a */,
                                18270F6014CF655B00B05E7F /* libsecipc_client.a */,
+                               4C1288EA15FFE9D7008CE3E3 /* libSecureObjectSync.a */,
+                               4C1288EC15FFE9D7008CE3E3 /* libSOSRegressions.a */,
+                               4C1288EE15FFE9D7008CE3E3 /* libSecurityRegressions.a */,
+                               4C1288F015FFE9D7008CE3E3 /* libsecuritydRegressions.a */,
+                               4C1288F215FFE9D7008CE3E3 /* libSecOtrOSX.a */,
+                               4C01DE32164C3793006798CD /* libCloudKeychainProxy.a */,
+                               4CB23B76169F5873003A0131 /* libSecurityTool.a */,
+                               4CB23B78169F5873003A0131 /* libSecurityCommands.a */,
+                               4CB23B7A169F5873003A0131 /* libSOSCommands.a */,
+                               0C4EAE721766865000773425 /* libsecdRegressions.a */,
                        );
                        name = Products;
                        sourceTree = "<group>";
                        );
                        name = Products;
                        sourceTree = "<group>";
                                182BB3AA146F1BEC000BF1F3 /* SecSignVerifyTransform.h */,
                                18446182146E9A8500B12992 /* SecStaticCode.h */,
                                1844617E146E9A8500B12992 /* SecTask.h */,
                                182BB3AA146F1BEC000BF1F3 /* SecSignVerifyTransform.h */,
                                18446182146E9A8500B12992 /* SecStaticCode.h */,
                                1844617E146E9A8500B12992 /* SecTask.h */,
+                               BEC3A76716F79497003E5634 /* SecTaskPriv.h */,
                                182BB3A5146F1BEC000BF1F3 /* SecTransform.h */,
                                182BB3AB146F1BEC000BF1F3 /* SecTransformReadTransform.h */,
                                182BB194146EAD4C000BF1F3 /* SecTrust.h */,
                                182BB3A5146F1BEC000BF1F3 /* SecTransform.h */,
                                182BB3AB146F1BEC000BF1F3 /* SecTransformReadTransform.h */,
                                182BB194146EAD4C000BF1F3 /* SecTrust.h */,
                                182BB315146F0E7E000BF1F3 /* SecureDownload.h */,
                                182BB36F146F13B4000BF1F3 /* SecureTransport.h */,
                                182BB196146EAD4C000BF1F3 /* Security.h */,
                                182BB315146F0E7E000BF1F3 /* SecureDownload.h */,
                                182BB36F146F13B4000BF1F3 /* SecureTransport.h */,
                                182BB196146EAD4C000BF1F3 /* Security.h */,
+                               4CB86AFA167A8F2200F46643 /* SOSAccount.h */,
+                               4CB86AE6167A6FF200F46643 /* SOSCircle.h */,
+                               4CB86AE7167A6FF200F46643 /* SOSCloudCircle.h */,
+                               4CB86AE8167A6FF200F46643 /* SOSCloudCircleInternal.h */,
+                               4CB86AE9167A6FF200F46643 /* SOSEngine.h */,
+                               4CB86AEA167A6FF300F46643 /* SOSFullPeerInfo.h */,
+                               4CB86AEB167A6FF300F46643 /* SOSInternal.h */,
+                               4CB86AEC167A6FF300F46643 /* SOSPeer.h */,
+                               4CB86AED167A6FF300F46643 /* SOSPeerInfo.h */,
+                               4CB86AEE167A6FF300F46643 /* SOSTransport.h */,
                                1879B4C4146DCA84007E536C /* x509defs.h */,
                        );
                        name = Headers;
                                1879B4C4146DCA84007E536C /* x509defs.h */,
                        );
                        name = Headers;
                                18446194146E9A8F00B12992 /* SecAssessment.h */,
                                182BB1B3146EAD5D000BF1F3 /* SecBasePriv.h */,
                                182BB1B4146EAD5D000BF1F3 /* SecCertificateBundle.h */,
                                18446194146E9A8F00B12992 /* SecAssessment.h */,
                                182BB1B3146EAD5D000BF1F3 /* SecBasePriv.h */,
                                182BB1B4146EAD5D000BF1F3 /* SecCertificateBundle.h */,
-                               182BB1CD146EAD5D000BF1F3 /* SecCertificateInternalP.h */,
                                182BB1B5146EAD5D000BF1F3 /* SecCertificatePriv.h */,
                                182BB1B6146EAD5D000BF1F3 /* SecCertificateRequest.h */,
                                182BB383146F14D2000BF1F3 /* SecCmsBase.h */,
                                182BB1B5146EAD5D000BF1F3 /* SecCertificatePriv.h */,
                                182BB1B6146EAD5D000BF1F3 /* SecCertificateRequest.h */,
                                182BB383146F14D2000BF1F3 /* SecCmsBase.h */,
                                182BB317146F0E94000BF1F3 /* SecManifest.h */,
                                182BB3B6146F1BF9000BF1F3 /* SecNullTransform.h */,
                                182BB1B0146EAD5D000BF1F3 /* SecPassword.h */,
                                182BB317146F0E94000BF1F3 /* SecManifest.h */,
                                182BB3B6146F1BF9000BF1F3 /* SecNullTransform.h */,
                                182BB1B0146EAD5D000BF1F3 /* SecPassword.h */,
+                               CDDE9D1C1729DF250013B0E8 /* SecPasswordGenerate.h */,
                                182BB1BB146EAD5D000BF1F3 /* SecPolicyPriv.h */,
                                182BB1CF146EAD5D000BF1F3 /* SecRandomP.h */,
                                182BB1CE146EAD5D000BF1F3 /* SecRecoveryPassword.h */,
                                182BB1BB146EAD5D000BF1F3 /* SecPolicyPriv.h */,
                                182BB1CF146EAD5D000BF1F3 /* SecRandomP.h */,
                                182BB1CE146EAD5D000BF1F3 /* SecRecoveryPassword.h */,
                                182BB1C6146EAD5D000BF1F3 /* SecTrustSettingsPriv.h */,
                                182BB318146F0E94000BF1F3 /* SecureDownloadInternal.h */,
                                182BB372146F13BB000BF1F3 /* SecureTransportPriv.h */,
                                182BB1C6146EAD5D000BF1F3 /* SecTrustSettingsPriv.h */,
                                182BB318146F0E94000BF1F3 /* SecureDownloadInternal.h */,
                                182BB372146F13BB000BF1F3 /* SecureTransportPriv.h */,
+                               0C4F055D15C9E51A00F9DFD5 /* sslTypes.h */,
                                182BB1C8146EAD5D000BF1F3 /* TrustSettingsSchema.h */,
                                182BB1C8146EAD5D000BF1F3 /* TrustSettingsSchema.h */,
-                               1844609E146DFCB700B12992 /* X509Templates.h */,
                                52B5A9C01519330300664F11 /* tsaSupport.h */,
                                52AEA484153C7581005AFC59 /* tsaSupportPriv.h */,
                                52B5A9C11519330300664F11 /* tsaTemplates.h */,
                                52B5A9C01519330300664F11 /* tsaSupport.h */,
                                52AEA484153C7581005AFC59 /* tsaSupportPriv.h */,
                                52B5A9C11519330300664F11 /* tsaTemplates.h */,
+                               1844609E146DFCB700B12992 /* X509Templates.h */,
                        );
                        name = PrivateHeaders;
                        sourceTree = "<group>";
                        );
                        name = PrivateHeaders;
                        sourceTree = "<group>";
                                1879B66A146DE757007E536C /* libintegrity.a */,
                                1879B66C146DE757007E536C /* libcodehost.a */,
                                C2432A0815C7112A0096DB5B /* gkunpack */,
                                1879B66A146DE757007E536C /* libintegrity.a */,
                                1879B66C146DE757007E536C /* libcodehost.a */,
                                C2432A0815C7112A0096DB5B /* gkunpack */,
+                               EB2E1F58166D6B3700A7EF61 /* com.apple.CodeSigningHelper.xpc */,
                        );
                        name = Products;
                        sourceTree = "<group>";
                        );
                        name = Products;
                        sourceTree = "<group>";
                                1879B6B3146DE7A0007E536C /* libsecurity_keychain.a */,
                                1879B6B7146DE7A0007E536C /* XPCKeychainSandboxCheck.xpc */,
                                52B5A8F6151928B400664F11 /* XPCTimeStampingService.xpc */,
                                1879B6B3146DE7A0007E536C /* libsecurity_keychain.a */,
                                1879B6B7146DE7A0007E536C /* XPCKeychainSandboxCheck.xpc */,
                                52B5A8F6151928B400664F11 /* XPCTimeStampingService.xpc */,
+                               0CBD50B316C325F000713B6C /* libsecurity_keychain_regressions.a */,
                        );
                        name = Products;
                        sourceTree = "<group>";
                        );
                        name = Products;
                        sourceTree = "<group>";
                        isa = PBXGroup;
                        children = (
                                1879B728146DE839007E536C /* libsecurity_ssl.a */,
                        isa = PBXGroup;
                        children = (
                                1879B728146DE839007E536C /* libsecurity_ssl.a */,
+                               0C6D77CD15C8B66000BB4405 /* libsecurity_ssl_kext.a */,
+                               0C6D77CF15C8B66000BB4405 /* libsecurity_ssl_regressions.a */,
+                               0C6D77D115C8B66000BB4405 /* dtlsEchoClient */,
+                               0C6D77D315C8B66000BB4405 /* dtlsEchoServer */,
                        );
                        name = Products;
                        sourceTree = "<group>";
                        );
                        name = Products;
                        sourceTree = "<group>";
                        name = Products;
                        sourceTree = "<group>";
                };
                        name = Products;
                        sourceTree = "<group>";
                };
+               18F234ED15C9F9A700060520 /* authd */ = {
+                       isa = PBXGroup;
+                       children = (
+                               18F234F915C9FA3B00060520 /* agent.c */,
+                               18F234FA15C9FA3B00060520 /* agent.h */,
+                               18F2351A15C9FA3C00060520 /* authd_private.h */,
+                               18F234FB15C9FA3B00060520 /* authdb.c */,
+                               18F234FC15C9FA3B00060520 /* authdb.h */,
+                               18F234FD15C9FA3B00060520 /* authitems.c */,
+                               18F234FE15C9FA3B00060520 /* authitems.h */,
+                               18F234FF15C9FA3B00060520 /* authtoken.c */,
+                               18F2350015C9FA3B00060520 /* authtoken.h */,
+                               18F2350115C9FA3B00060520 /* authtypes.h */,
+                               18F2350215C9FA3B00060520 /* authutilities.c */,
+                               18F2350315C9FA3B00060520 /* authutilities.h */,
+                               18F2350415C9FA3B00060520 /* ccaudit.c */,
+                               18F2350515C9FA3B00060520 /* ccaudit.h */,
+                               182A191015D09AFF006AB103 /* connection.c */,
+                               182A190F15D09AF0006AB103 /* connection.h */,
+                               18F2350615C9FA3B00060520 /* crc.c */,
+                               18F2350715C9FA3B00060520 /* crc.h */,
+                               18F2350815C9FA3B00060520 /* credential.c */,
+                               18F2350915C9FA3B00060520 /* credential.h */,
+                               18F2350A15C9FA3B00060520 /* debugging.c */,
+                               18F2350B15C9FA3B00060520 /* debugging.h */,
+                               18F2350F15C9FA3B00060520 /* engine.c */,
+                               18F2351015C9FA3B00060520 /* engine.h */,
+                               18F2351115C9FA3B00060520 /* main.c */,
+                               18F2351215C9FA3B00060520 /* mechanism.c */,
+                               18F2351315C9FA3B00060520 /* mechanism.h */,
+                               18F2351415C9FA3C00060520 /* object.c */,
+                               18F2351515C9FA3C00060520 /* object.h */,
+                               18F2351615C9FA3C00060520 /* process.c */,
+                               18F2351715C9FA3C00060520 /* process.h */,
+                               18F2351815C9FA3C00060520 /* rule.c */,
+                               18F2351915C9FA3C00060520 /* rule.h */,
+                               18F2351D15C9FA3C00060520 /* server.c */,
+                               18F2351E15C9FA3C00060520 /* server.h */,
+                               18F2351F15C9FA3C00060520 /* session.c */,
+                               18F2352015C9FA3C00060520 /* session.h */,
+                               18F2353415C9FA7F00060520 /* Supporting Files */,
+                       );
+                       path = authd;
+                       sourceTree = "<group>";
+               };
+               18F2353415C9FA7F00060520 /* Supporting Files */ = {
+                       isa = PBXGroup;
+                       children = (
+                               18D6803916B768D500DF6D2E /* com.apple.authd */,
+                               18CFEE8715DEE25200E3F2A3 /* com.apple.authd.sb */,
+                               187D6B9515D436BF00E27494 /* authorization.plist */,
+                               18F2350D15C9FA3B00060520 /* InfoPlist.strings */,
+                               18F2351B15C9FA3C00060520 /* Info.plist */,
+                               18F2351C15C9FA3C00060520 /* security.auth-Prefix.pch */,
+                       );
+                       name = "Supporting Files";
+                       sourceTree = "<group>";
+               };
+               4C1288F615FFECF2008CE3E3 /* utilities */ = {
+                       isa = PBXGroup;
+                       children = (
+                               0CC3355B16C1EF5D00399E53 /* regressions.xcodeproj */,
+                               4C12893715FFECF3008CE3E3 /* utilities.xcodeproj */,
+                       );
+                       path = utilities;
+                       sourceTree = "<group>";
+               };
+               4C12893815FFECF3008CE3E3 /* Products */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4C12894015FFECF3008CE3E3 /* libutilities.a */,
+                               4C12894215FFECF3008CE3E3 /* libutilitiesRegressions.a */,
+                       );
+                       name = Products;
+                       sourceTree = "<group>";
+               };
+               4C96F7C316D6DF8400D3B39D /* Keychain Circle Notification */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4CD1980B16DD3BDF00A9E8FD /* NSArray+mapWithBlock.h */,
+                               4CD1980C16DD3BDF00A9E8FD /* NSArray+mapWithBlock.m */,
+                               4C96F7CF16D6DF8400D3B39D /* KNAppDelegate.h */,
+                               4C96F7D016D6DF8400D3B39D /* KNAppDelegate.m */,
+                               4C96F7D216D6DF8400D3B39D /* MainMenu.xib */,
+                               4C5DD44217A5E31900696A79 /* KNPersistantState.h */,
+                               4C5DD44317A5E31900696A79 /* KNPersistantState.m */,
+                               4C96F7C416D6DF8400D3B39D /* Supporting Files */,
+                               4CB9121C17750E6500C1CCCA /* entitlments.plist */,
+                       );
+                       path = "Keychain Circle Notification";
+                       sourceTree = "<group>";
+               };
+               4C96F7C416D6DF8400D3B39D /* Supporting Files */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4C7D456417BEE6B700DDD88F /* NSDictionary+compactDescription.h */,
+                               4C7D456517BEE6B700DDD88F /* NSDictionary+compactDescription.m */,
+                               4C7D456617BEE6B700DDD88F /* NSSet+compactDescription.h */,
+                               4C7D456717BEE6B700DDD88F /* NSSet+compactDescription.m */,
+                               4C7D453B17BEE69B00DDD88F /* NSString+compactDescription.h */,
+                               4C7D453C17BEE69B00DDD88F /* NSString+compactDescription.m */,
+                               5328475117850741009118DC /* Localizable.strings */,
+                               4CFE1CB816DD4B9C0026E900 /* CloudKeychain.icns */,
+                               4C96F7C516D6DF8400D3B39D /* Keychain Circle Notification-Info.plist */,
+                               4C96F7C616D6DF8400D3B39D /* InfoPlist.strings */,
+                               4C96F7C916D6DF8400D3B39D /* main.m */,
+                               4C96F7CB16D6DF8400D3B39D /* Keychain Circle Notification-Prefix.pch */,
+                               4C96F7CC16D6DF8400D3B39D /* Credits.rtf */,
+                               4C49390C16E51ACE00CE110C /* com.apple.security.keychain-circle-notification.plist */,
+                       );
+                       name = "Supporting Files";
+                       sourceTree = "<group>";
+               };
+               4CB23B48169F5873003A0131 /* security2 */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4CB23B4B169F5873003A0131 /* security2.1 */,
+                               4CB23B80169F58DE003A0131 /* security_tool_commands.c */,
+                               4CB23B82169F592C003A0131 /* sub_commands.h */,
+                       );
+                       path = security2;
+                       sourceTree = "<group>";
+               };
+               4CC7A7B516CC2A85003E10C1 /* KeychainDemoApp */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4CC7A7C116CC2A85003E10C1 /* KDAppDelegate.h */,
+                               4CC7A7C216CC2A85003E10C1 /* KDAppDelegate.m */,
+                               4C85DED816DBD5BF00ED8D47 /* KDCirclePeer.h */,
+                               4C85DED916DBD5BF00ED8D47 /* KDCirclePeer.m */,
+                               4CC7A7F416CD95D2003E10C1 /* KDSecItems.h */,
+                               4CC7A7F516CD95D3003E10C1 /* KDSecItems.m */,
+                               4CC7A7C416CC2A85003E10C1 /* MainMenu.xib */,
+                               4C96F73816D5372C00D3B39D /* KDSecCircle.h */,
+                               4C96F73916D5372C00D3B39D /* KDSecCircle.m */,
+                               4CC7A7B616CC2A85003E10C1 /* Supporting Files */,
+                       );
+                       name = KeychainDemoApp;
+                       path = Keychain;
+                       sourceTree = "<group>";
+               };
+               4CC7A7B616CC2A85003E10C1 /* Supporting Files */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4C2505B616D2DF9F002CE025 /* Icon.icns */,
+                               4CC7A7B716CC2A85003E10C1 /* Keychain-Info.plist */,
+                               4CC7A7B816CC2A85003E10C1 /* InfoPlist.strings */,
+                               4CC7A7BB16CC2A85003E10C1 /* main.m */,
+                               4CC7A7BD16CC2A85003E10C1 /* Keychain-Prefix.pch */,
+                               4CC7A7BE16CC2A85003E10C1 /* Credits.rtf */,
+                       );
+                       name = "Supporting Files";
+                       sourceTree = "<group>";
+               };
+               5214700916977CB800DF0DB3 /* Other Frameworks */ = {
+                       isa = PBXGroup;
+                       children = (
+                               5214700A16977CB800DF0DB3 /* AppKit.framework */,
+                               5214700B16977CB800DF0DB3 /* CoreData.framework */,
+                               5214700C16977CB800DF0DB3 /* Foundation.framework */,
+                       );
+                       name = "Other Frameworks";
+                       sourceTree = "<group>";
+               };
+               5214700D16977CB800DF0DB3 /* CloudKeychainProxy */ = {
+                       isa = PBXGroup;
+                       children = (
+                               52C3D235169B56860091D9D3 /* ckdmain.m */,
+                               5214700E16977CB800DF0DB3 /* Supporting Files */,
+                       );
+                       path = CloudKeychainProxy;
+                       sourceTree = "<group>";
+               };
+               5214700E16977CB800DF0DB3 /* Supporting Files */ = {
+                       isa = PBXGroup;
+                       children = (
+                               5214702416977FEC00DF0DB3 /* cloudkeychain.entitlements.plist */,
+                               5214702516977FEC00DF0DB3 /* com.apple.security.cloudkeychainproxy.plist */,
+                               5214700F16977CB800DF0DB3 /* CloudKeychainProxy-Info.plist */,
+                               5214701016977CB800DF0DB3 /* InfoPlist.strings */,
+                       );
+                       name = "Supporting Files";
+                       sourceTree = "<group>";
+               };
+               721680A7179B40F600406BB4 /* iCloudStats */ = {
+                       isa = PBXGroup;
+                       children = (
+                               721680A8179B40F600406BB4 /* main.c */,
+                               721680AA179B40F600406BB4 /* iCloudStats.1 */,
+                               721680BD179B4F9100406BB4 /* com.apple.iCloudStats.plist */,
+                       );
+                       path = iCloudStats;
+                       sourceTree = "<group>";
+               };
+               72756C00175D485D00F52070 /* cloud_keychain_diagnose */ = {
+                       isa = PBXGroup;
+                       children = (
+                               72756C30175D48C100F52070 /* cloud_keychain_diagnose.c */,
+                               72756C03175D485D00F52070 /* Supporting Files */,
+                       );
+                       path = cloud_keychain_diagnose;
+                       sourceTree = "<group>";
+               };
+               72756C03175D485D00F52070 /* Supporting Files */ = {
+                       isa = PBXGroup;
+                       children = (
+                               72756C04175D485D00F52070 /* cloud_keychain_diagnose-Prefix.pch */,
+                       );
+                       name = "Supporting Files";
+                       sourceTree = "<group>";
+               };
 /* End PBXGroup section */
 
 /* Begin PBXHeadersBuildPhase section */
 /* End PBXGroup section */
 
 /* Begin PBXHeadersBuildPhase section */
                                18FE684F1471A46600A2CBE3 /* AuthorizationTagsPriv.h in Headers */,
                                18FE68501471A46600A2CBE3 /* certExtensionTemplates.h in Headers */,
                                18FE68511471A46600A2CBE3 /* checkpw.h in Headers */,
                                18FE684F1471A46600A2CBE3 /* AuthorizationTagsPriv.h in Headers */,
                                18FE68501471A46600A2CBE3 /* certExtensionTemplates.h in Headers */,
                                18FE68511471A46600A2CBE3 /* checkpw.h in Headers */,
+                               CDDE9D1E1729E2E60013B0E8 /* SecPasswordGenerate.h in Headers */,
                                18FE68521471A46600A2CBE3 /* CMSPrivate.h in Headers */,
                                18FE68531471A46600A2CBE3 /* CSCommonPriv.h in Headers */,
                                18FE68541471A46600A2CBE3 /* csrTemplates.h in Headers */,
                                18FE68521471A46600A2CBE3 /* CMSPrivate.h in Headers */,
                                18FE68531471A46600A2CBE3 /* CSCommonPriv.h in Headers */,
                                18FE68541471A46600A2CBE3 /* csrTemplates.h in Headers */,
                                18FE685D1471A46600A2CBE3 /* SecAssessment.h in Headers */,
                                18FE685E1471A46600A2CBE3 /* SecBasePriv.h in Headers */,
                                18FE685F1471A46600A2CBE3 /* SecCertificateBundle.h in Headers */,
                                18FE685D1471A46600A2CBE3 /* SecAssessment.h in Headers */,
                                18FE685E1471A46600A2CBE3 /* SecBasePriv.h in Headers */,
                                18FE685F1471A46600A2CBE3 /* SecCertificateBundle.h in Headers */,
-                               18FE68601471A46600A2CBE3 /* SecCertificateInternalP.h in Headers */,
                                18FE68611471A46600A2CBE3 /* SecCertificatePriv.h in Headers */,
                                18FE68621471A46600A2CBE3 /* SecCertificateRequest.h in Headers */,
                                18FE68631471A46600A2CBE3 /* SecCmsBase.h in Headers */,
                                18FE68611471A46600A2CBE3 /* SecCertificatePriv.h in Headers */,
                                18FE68621471A46600A2CBE3 /* SecCertificateRequest.h in Headers */,
                                18FE68631471A46600A2CBE3 /* SecCmsBase.h in Headers */,
                                18FE68851471A46700A2CBE3 /* SecStaticCodePriv.h in Headers */,
                                18FE68861471A46700A2CBE3 /* SecTransformInternal.h in Headers */,
                                18FE68871471A46700A2CBE3 /* SecTrustedApplicationPriv.h in Headers */,
                                18FE68851471A46700A2CBE3 /* SecStaticCodePriv.h in Headers */,
                                18FE68861471A46700A2CBE3 /* SecTransformInternal.h in Headers */,
                                18FE68871471A46700A2CBE3 /* SecTrustedApplicationPriv.h in Headers */,
+                               BEC3A76816F79497003E5634 /* SecTaskPriv.h in Headers */,
                                18FE68881471A46700A2CBE3 /* SecTrustPriv.h in Headers */,
                                18FE68891471A46700A2CBE3 /* SecTrustSettingsPriv.h in Headers */,
                                18FE688A1471A46700A2CBE3 /* SecureDownloadInternal.h in Headers */,
                                18FE688B1471A46700A2CBE3 /* SecureTransportPriv.h in Headers */,
                                18FE688C1471A46700A2CBE3 /* TrustSettingsSchema.h in Headers */,
                                18FE688D1471A46700A2CBE3 /* X509Templates.h in Headers */,
                                18FE68881471A46700A2CBE3 /* SecTrustPriv.h in Headers */,
                                18FE68891471A46700A2CBE3 /* SecTrustSettingsPriv.h in Headers */,
                                18FE688A1471A46700A2CBE3 /* SecureDownloadInternal.h in Headers */,
                                18FE688B1471A46700A2CBE3 /* SecureTransportPriv.h in Headers */,
                                18FE688C1471A46700A2CBE3 /* TrustSettingsSchema.h in Headers */,
                                18FE688D1471A46700A2CBE3 /* X509Templates.h in Headers */,
+                               0C4F055E15C9E51A00F9DFD5 /* sslTypes.h in Headers */,
                                18BBC7361471F5A300F2B224 /* SecExternalSourceTransform.h in Headers */,
                                18B647EC14D9F20500F538BF /* oidsalg.h in Headers */,
                                52B5A9C21519330300664F11 /* tsaSupport.h in Headers */,
                                18BBC7361471F5A300F2B224 /* SecExternalSourceTransform.h in Headers */,
                                18B647EC14D9F20500F538BF /* oidsalg.h in Headers */,
                                52B5A9C21519330300664F11 /* tsaSupport.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               4AF95B8B16193B1B00662B04 /* Headers */ = {
+                       isa = PBXHeadersBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
 /* End PBXHeadersBuildPhase section */
 
 /* Begin PBXNativeTarget section */
 /* End PBXHeadersBuildPhase section */
 
 /* Begin PBXNativeTarget section */
+               0C6C630A15D193C800BC68CD /* sectests */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 0C6C631215D193C900BC68CD /* Build configuration list for PBXNativeTarget "sectests" */;
+                       buildPhases = (
+                               0C6C630715D193C800BC68CD /* Sources */,
+                               0C6C630815D193C800BC68CD /* Frameworks */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                               0CBD50C716C3260D00713B6C /* PBXTargetDependency */,
+                               0CCEBDB316C2CFD4001BD7F6 /* PBXTargetDependency */,
+                               0C6C632E15D19D2900BC68CD /* PBXTargetDependency */,
+                       );
+                       name = sectests;
+                       productName = sectests;
+                       productReference = 0C6C630B15D193C800BC68CD /* sectests */;
+                       productType = "com.apple.product-type.tool";
+               };
+               0CC3350716C1ED8000399E53 /* secdtests */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 0CC3352A16C1ED8000399E53 /* Build configuration list for PBXNativeTarget "secdtests" */;
+                       buildPhases = (
+                               0CC3351616C1ED8000399E53 /* Sources */,
+                               0CC3351B16C1ED8000399E53 /* Frameworks */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                               0CC3350A16C1ED8000399E53 /* PBXTargetDependency */,
+                               0CC3351016C1ED8000399E53 /* PBXTargetDependency */,
+                               0CC3351216C1ED8000399E53 /* PBXTargetDependency */,
+                               0CC3351416C1ED8000399E53 /* PBXTargetDependency */,
+                               0CC3350816C1ED8000399E53 /* PBXTargetDependency */,
+                               0CC3356216C1EF8B00399E53 /* PBXTargetDependency */,
+                               0CC3350C16C1ED8000399E53 /* PBXTargetDependency */,
+                               0CCEBDBD16C30948001BD7F6 /* PBXTargetDependency */,
+                               0C4EAE7917668DFF00773425 /* PBXTargetDependency */,
+                       );
+                       name = secdtests;
+                       productName = sectests;
+                       productReference = 0CC3352D16C1ED8000399E53 /* secdtests */;
+                       productType = "com.apple.product-type.tool";
+               };
                1807384A146D0D4E00F05C24 /* Security */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = 18073875146D0D4E00F05C24 /* Build configuration list for PBXNativeTarget "Security" */;
                        buildPhases = (
                1807384A146D0D4E00F05C24 /* Security */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = 18073875146D0D4E00F05C24 /* Build configuration list for PBXNativeTarget "Security" */;
                        buildPhases = (
-                               18500F9214708073006F9AB4 /* Run Script Generate Source */,
                                18073846146D0D4E00F05C24 /* Sources */,
                                18073847146D0D4E00F05C24 /* Frameworks */,
                                18073848146D0D4E00F05C24 /* Headers */,
                                18073846146D0D4E00F05C24 /* Sources */,
                                18073847146D0D4E00F05C24 /* Frameworks */,
                                18073848146D0D4E00F05C24 /* Headers */,
                                18500F9114707E10006F9AB4 /* Run Script Copy XPC Service */,
                        );
                        buildRules = (
                                18500F9114707E10006F9AB4 /* Run Script Copy XPC Service */,
                        );
                        buildRules = (
+                               E778BFB91717461800302C14 /* PBXBuildRule */,
                        );
                        dependencies = (
                        );
                        dependencies = (
+                               1879B545146DE18D007E536C /* PBXTargetDependency */,
+                               4AD6F6F41651CC2500DB4CE6 /* PBXTargetDependency */,
+                               4C12894415FFED03008CE3E3 /* PBXTargetDependency */,
                                18FE688F1471A4C900A2CBE3 /* PBXTargetDependency */,
                                1885B45114D9AB3D00519375 /* PBXTargetDependency */,
                                18270F5D14CF655B00B05E7F /* PBXTargetDependency */,
                                18AD56A614CDED59008233F2 /* PBXTargetDependency */,
                                18FE688F1471A4C900A2CBE3 /* PBXTargetDependency */,
                                1885B45114D9AB3D00519375 /* PBXTargetDependency */,
                                18270F5D14CF655B00B05E7F /* PBXTargetDependency */,
                                18AD56A614CDED59008233F2 /* PBXTargetDependency */,
-                               1879B545146DE18D007E536C /* PBXTargetDependency */,
                                182BB410146F248D000BF1F3 /* PBXTargetDependency */,
                                1879B56C146DE2CF007E536C /* PBXTargetDependency */,
                                18B9655C1472F83C005A4D2E /* PBXTargetDependency */,
                                182BB410146F248D000BF1F3 /* PBXTargetDependency */,
                                1879B56C146DE2CF007E536C /* PBXTargetDependency */,
                                18B9655C1472F83C005A4D2E /* PBXTargetDependency */,
                                182BB3EC146F2448000BF1F3 /* PBXTargetDependency */,
                                18446082146DF52F00B12992 /* PBXTargetDependency */,
                                1879B56E146DE2D3007E536C /* PBXTargetDependency */,
                                182BB3EC146F2448000BF1F3 /* PBXTargetDependency */,
                                18446082146DF52F00B12992 /* PBXTargetDependency */,
                                1879B56E146DE2D3007E536C /* PBXTargetDependency */,
+                               5208C0FE16A0D3980062DDC5 /* PBXTargetDependency */,
                                182BB22C146F07DD000BF1F3 /* PBXTargetDependency */,
                                529FF2201523BD7F0029D842 /* PBXTargetDependency */,
                        );
                                182BB22C146F07DD000BF1F3 /* PBXTargetDependency */,
                                529FF2201523BD7F0029D842 /* PBXTargetDependency */,
                        );
                                18270ED214CF282600B05E7F /* Sources */,
                                18270ED314CF282600B05E7F /* Frameworks */,
                                18BEB19914CF7F0B00C8BD36 /* CopyFiles */,
                                18270ED214CF282600B05E7F /* Sources */,
                                18270ED314CF282600B05E7F /* Frameworks */,
                                18BEB19914CF7F0B00C8BD36 /* CopyFiles */,
+                               0C6D003C177B545D0095D167 /* CopyFiles */,
                        );
                        buildRules = (
                        );
                        dependencies = (
                        );
                        buildRules = (
                        );
                        dependencies = (
+                               4C8D8650177A75100019A804 /* PBXTargetDependency */,
+                               4C01DF13164C3E74006798CD /* PBXTargetDependency */,
+                               4C7D8764160A746E00D041E3 /* PBXTargetDependency */,
                                18270EE314CF28D900B05E7F /* PBXTargetDependency */,
                                18270EE114CF28D000B05E7F /* PBXTargetDependency */,
                        );
                                18270EE314CF28D900B05E7F /* PBXTargetDependency */,
                                18270EE114CF28D000B05E7F /* PBXTargetDependency */,
                        );
                        productReference = 182BB568146F4DCA000BF1F3 /* csparser.bundle */;
                        productType = "com.apple.product-type.bundle";
                };
                        productReference = 182BB568146F4DCA000BF1F3 /* csparser.bundle */;
                        productType = "com.apple.product-type.bundle";
                };
+               18F234EA15C9F9A600060520 /* authd */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 18F234F615C9F9A700060520 /* Build configuration list for PBXNativeTarget "authd" */;
+                       buildPhases = (
+                               4AF95B8B16193B1B00662B04 /* Headers */,
+                               18F234E715C9F9A600060520 /* Sources */,
+                               18F234E815C9F9A600060520 /* Frameworks */,
+                               187D6B9615D4381C00E27494 /* Copy authorization.plist */,
+                               18CFEE8815DEE2BA00E3F2A3 /* Copy sandbox profile */,
+                               4A5C178F161A9DE000ABF784 /* CopyFiles */,
+                               18D6803A16B768DE00DF6D2E /* Copy asl module */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = authd;
+                       productName = security.auth;
+                       productReference = 18F234EB15C9F9A600060520 /* authd.xpc */;
+                       productType = "com.apple.product-type.bundle";
+               };
                18FE67E91471A3AA00A2CBE3 /* copyHeaders */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = 18FE67FB1471A3AA00A2CBE3 /* Build configuration list for PBXNativeTarget "copyHeaders" */;
                        buildPhases = (
                                18FE67E71471A3AA00A2CBE3 /* Headers */,
                18FE67E91471A3AA00A2CBE3 /* copyHeaders */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = 18FE67FB1471A3AA00A2CBE3 /* Build configuration list for PBXNativeTarget "copyHeaders" */;
                        buildPhases = (
                                18FE67E71471A3AA00A2CBE3 /* Headers */,
+                               4CB86AE4167A6F3D00F46643 /* CopyFiles */,
                        );
                        buildRules = (
                        );
                        );
                        buildRules = (
                        );
                        productReference = 18FE67EA1471A3AA00A2CBE3 /* Security.framework */;
                        productType = "com.apple.product-type.framework";
                };
                        productReference = 18FE67EA1471A3AA00A2CBE3 /* Security.framework */;
                        productType = "com.apple.product-type.framework";
                };
+               4C96F7C016D6DF8300D3B39D /* Keychain Circle Notification */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 4C96F7D516D6DF8400D3B39D /* Build configuration list for PBXNativeTarget "Keychain Circle Notification" */;
+                       buildPhases = (
+                               4C96F7BD16D6DF8300D3B39D /* Sources */,
+                               4C96F7BE16D6DF8300D3B39D /* Frameworks */,
+                               4C96F7BF16D6DF8300D3B39D /* Resources */,
+                               4C49390E16E51ED100CE110C /* CopyFiles */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = "Keychain Circle Notification";
+                       productName = "Keychain Circle Notification";
+                       productReference = 4C96F7C116D6DF8300D3B39D /* Keychain Circle Notification.app */;
+                       productType = "com.apple.product-type.application";
+               };
+               4CB23B45169F5873003A0131 /* security2 */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 4CB23B7F169F5873003A0131 /* Build configuration list for PBXNativeTarget "security2" */;
+                       buildPhases = (
+                               4CB23B42169F5873003A0131 /* Sources */,
+                               4CB23B43169F5873003A0131 /* Frameworks */,
+                               4CB23B44169F5873003A0131 /* CopyFiles */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                               4CB23B88169F597D003A0131 /* PBXTargetDependency */,
+                               4CB23B86169F5971003A0131 /* PBXTargetDependency */,
+                               4CB23B84169F5961003A0131 /* PBXTargetDependency */,
+                       );
+                       name = security2;
+                       productName = security2;
+                       productReference = 4CB23B46169F5873003A0131 /* security2 */;
+                       productType = "com.apple.product-type.tool";
+               };
+               4CC7A7B216CC2A84003E10C1 /* Cloud Keychain Utility */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 4CC7A7EF16CC2A85003E10C1 /* Build configuration list for PBXNativeTarget "Cloud Keychain Utility" */;
+                       buildPhases = (
+                               4CC7A7AF16CC2A84003E10C1 /* Sources */,
+                               4CC7A7B016CC2A84003E10C1 /* Frameworks */,
+                               4CC7A7B116CC2A84003E10C1 /* Resources */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = "Cloud Keychain Utility";
+                       productName = Keychain;
+                       productReference = 4CC7A7B316CC2A84003E10C1 /* Cloud Keychain Utility.app */;
+                       productType = "com.apple.product-type.application";
+               };
+               5214700516977CB800DF0DB3 /* CloudKeychainProxy */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 5214701416977CB800DF0DB3 /* Build configuration list for PBXNativeTarget "CloudKeychainProxy" */;
+                       buildPhases = (
+                               5214700216977CB800DF0DB3 /* Sources */,
+                               5214700316977CB800DF0DB3 /* Frameworks */,
+                               5214700416977CB800DF0DB3 /* Resources */,
+                               5214702316977EA600DF0DB3 /* CopyFiles */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                               5214701A16977D2500DF0DB3 /* PBXTargetDependency */,
+                               5214701816977D1D00DF0DB3 /* PBXTargetDependency */,
+                       );
+                       name = CloudKeychainProxy;
+                       productName = CloudKeychainProxy;
+                       productReference = 5214700616977CB800DF0DB3 /* CloudKeychainProxy.bundle */;
+                       productType = "com.apple.product-type.bundle";
+               };
+               721680A4179B40F600406BB4 /* iCloudStats */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 721680AC179B40F600406BB4 /* Build configuration list for PBXNativeTarget "iCloudStats" */;
+                       buildPhases = (
+                               721680A1179B40F600406BB4 /* Sources */,
+                               721680A2179B40F600406BB4 /* Frameworks */,
+                               721680A3179B40F600406BB4 /* CopyFiles */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = iCloudStats;
+                       productName = iCloudStats;
+                       productReference = 721680A5179B40F600406BB4 /* iCloudStats */;
+                       productType = "com.apple.product-type.tool";
+               };
+               72756BFD175D485D00F52070 /* cloud_keychain_diagnose */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 72756C2F175D485D00F52070 /* Build configuration list for PBXNativeTarget "cloud_keychain_diagnose" */;
+                       buildPhases = (
+                               72756BFA175D485D00F52070 /* Sources */,
+                               72756BFB175D485D00F52070 /* Frameworks */,
+                               72756BFC175D485D00F52070 /* CopyFiles */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = cloud_keychain_diagnose;
+                       productName = cloud_keychain_diagnose;
+                       productReference = 72756BFE175D485D00F52070 /* cloud_keychain_diagnose */;
+                       productType = "com.apple.product-type.tool";
+               };
 /* End PBXNativeTarget section */
 
 /* Begin PBXProject section */
 /* End PBXNativeTarget section */
 
 /* Begin PBXProject section */
                                        ProductGroup = 184461A4146E9D3200B12992 /* Products */;
                                        ProjectRef = 184461A3146E9D3200B12992 /* libsecurityd.xcodeproj */;
                                },
                                        ProductGroup = 184461A4146E9D3200B12992 /* Products */;
                                        ProjectRef = 184461A3146E9D3200B12992 /* libsecurityd.xcodeproj */;
                                },
+                               {
+                                       ProductGroup = 0CC3355C16C1EF5D00399E53 /* Products */;
+                                       ProjectRef = 0CC3355B16C1EF5D00399E53 /* regressions.xcodeproj */;
+                               },
                                {
                                        ProductGroup = 186CDD1714CA11C700AF9171 /* Products */;
                                        ProjectRef = 186CDD1614CA11C700AF9171 /* sec.xcodeproj */;
                                },
                                {
                                        ProductGroup = 186CDD1714CA11C700AF9171 /* Products */;
                                        ProjectRef = 186CDD1614CA11C700AF9171 /* sec.xcodeproj */;
                                },
+                               {
+                                       ProductGroup = 0C6D77DF15C8C06500BB4405 /* Products */;
+                                       ProjectRef = 0C6D77DE15C8C06500BB4405 /* tlsnke.xcodeproj */;
+                               },
+                               {
+                                       ProductGroup = 4C12893815FFECF3008CE3E3 /* Products */;
+                                       ProjectRef = 4C12893715FFECF3008CE3E3 /* utilities.xcodeproj */;
+                               },
                        );
                        projectRoot = "";
                        targets = (
                                186F778814E59FB200434E1F /* Security_frameworks */,
                                186F778C14E59FDA00434E1F /* Security_executables */,
                        );
                        projectRoot = "";
                        targets = (
                                186F778814E59FB200434E1F /* Security_frameworks */,
                                186F778C14E59FDA00434E1F /* Security_executables */,
+                               0C6C642915D5ADB500BC68CD /* Security_kexts */,
                                182BB598146FE295000BF1F3 /* World */,
                                1807384A146D0D4E00F05C24 /* Security */,
                                182BB567146F4DCA000BF1F3 /* csparser */,
                                18FE67E91471A3AA00A2CBE3 /* copyHeaders */,
                                18270ED514CF282600B05E7F /* secd */,
                                182BB598146FE295000BF1F3 /* World */,
                                1807384A146D0D4E00F05C24 /* Security */,
                                182BB567146F4DCA000BF1F3 /* csparser */,
                                18FE67E91471A3AA00A2CBE3 /* copyHeaders */,
                                18270ED514CF282600B05E7F /* secd */,
+                               0CC3350716C1ED8000399E53 /* secdtests */,
+                               0C6C630A15D193C800BC68CD /* sectests */,
+                               18F234EA15C9F9A600060520 /* authd */,
+                               5214700516977CB800DF0DB3 /* CloudKeychainProxy */,
+                               4CB23B45169F5873003A0131 /* security2 */,
+                               4CC7A7B216CC2A84003E10C1 /* Cloud Keychain Utility */,
+                               4C96F7C016D6DF8300D3B39D /* Keychain Circle Notification */,
+                               4CE4729E16D833FD009070D1 /* Security_temporary_UI */,
+                               72756BFD175D485D00F52070 /* cloud_keychain_diagnose */,
+                               721680A4179B40F600406BB4 /* iCloudStats */,
                        );
                };
 /* End PBXProject section */
 
 /* Begin PBXReferenceProxy section */
                        );
                };
 /* End PBXProject section */
 
 /* Begin PBXReferenceProxy section */
+               0C4EAE721766865000773425 /* libsecdRegressions.a */ = {
+                       isa = PBXReferenceProxy;
+                       fileType = archive.ar;
+                       path = libsecdRegressions.a;
+                       remoteRef = 0C4EAE711766865000773425 /* PBXContainerItemProxy */;
+                       sourceTree = BUILT_PRODUCTS_DIR;
+               };
+               0C6D77CD15C8B66000BB4405 /* libsecurity_ssl_kext.a */ = {
+                       isa = PBXReferenceProxy;
+                       fileType = archive.ar;
+                       path = libsecurity_ssl_kext.a;
+                       remoteRef = 0C6D77CC15C8B66000BB4405 /* PBXContainerItemProxy */;
+                       sourceTree = BUILT_PRODUCTS_DIR;
+               };
+               0C6D77CF15C8B66000BB4405 /* libsecurity_ssl_regressions.a */ = {
+                       isa = PBXReferenceProxy;
+                       fileType = archive.ar;
+                       path = libsecurity_ssl_regressions.a;
+                       remoteRef = 0C6D77CE15C8B66000BB4405 /* PBXContainerItemProxy */;
+                       sourceTree = BUILT_PRODUCTS_DIR;
+               };
+               0C6D77D115C8B66000BB4405 /* dtlsEchoClient */ = {
+                       isa = PBXReferenceProxy;
+                       fileType = "compiled.mach-o.executable";
+                       path = dtlsEchoClient;
+                       remoteRef = 0C6D77D015C8B66000BB4405 /* PBXContainerItemProxy */;
+                       sourceTree = BUILT_PRODUCTS_DIR;
+               };
+               0C6D77D315C8B66000BB4405 /* dtlsEchoServer */ = {
+                       isa = PBXReferenceProxy;
+                       fileType = "compiled.mach-o.executable";
+                       path = dtlsEchoServer;
+                       remoteRef = 0C6D77D215C8B66000BB4405 /* PBXContainerItemProxy */;
+                       sourceTree = BUILT_PRODUCTS_DIR;
+               };
+               0C6D77E915C8C06600BB4405 /* tlsnke.kext */ = {
+                       isa = PBXReferenceProxy;
+                       fileType = wrapper.cfbundle;
+                       path = tlsnke.kext;
+                       remoteRef = 0C6D77E815C8C06600BB4405 /* PBXContainerItemProxy */;
+                       sourceTree = BUILT_PRODUCTS_DIR;
+               };
+               0C6D77EB15C8C06600BB4405 /* tlsnketest */ = {
+                       isa = PBXReferenceProxy;
+                       fileType = "compiled.mach-o.executable";
+                       path = tlsnketest;
+                       remoteRef = 0C6D77EA15C8C06600BB4405 /* PBXContainerItemProxy */;
+                       sourceTree = BUILT_PRODUCTS_DIR;
+               };
+               0C6D77ED15C8C06600BB4405 /* libtlssocket.a */ = {
+                       isa = PBXReferenceProxy;
+                       fileType = archive.ar;
+                       path = libtlssocket.a;
+                       remoteRef = 0C6D77EC15C8C06600BB4405 /* PBXContainerItemProxy */;
+                       sourceTree = BUILT_PRODUCTS_DIR;
+               };
+               0CBD50B316C325F000713B6C /* libsecurity_keychain_regressions.a */ = {
+                       isa = PBXReferenceProxy;
+                       fileType = archive.ar;
+                       path = libsecurity_keychain_regressions.a;
+                       remoteRef = 0CBD50B216C325F000713B6C /* PBXContainerItemProxy */;
+                       sourceTree = BUILT_PRODUCTS_DIR;
+               };
+               0CC3356016C1EF5D00399E53 /* libregressions.a */ = {
+                       isa = PBXReferenceProxy;
+                       fileType = archive.ar;
+                       path = libregressions.a;
+                       remoteRef = 0CC3355F16C1EF5D00399E53 /* PBXContainerItemProxy */;
+                       sourceTree = BUILT_PRODUCTS_DIR;
+               };
                18270C7D14CE573D00B05E7F /* libsecurityd.a */ = {
                        isa = PBXReferenceProxy;
                        fileType = archive.ar;
                18270C7D14CE573D00B05E7F /* libsecurityd.a */ = {
                        isa = PBXReferenceProxy;
                        fileType = archive.ar;
                        remoteRef = 18D4053A14CE2C1600A2BE4E /* PBXContainerItemProxy */;
                        sourceTree = BUILT_PRODUCTS_DIR;
                };
                        remoteRef = 18D4053A14CE2C1600A2BE4E /* PBXContainerItemProxy */;
                        sourceTree = BUILT_PRODUCTS_DIR;
                };
+               4C01DE32164C3793006798CD /* libCloudKeychainProxy.a */ = {
+                       isa = PBXReferenceProxy;
+                       fileType = archive.ar;
+                       path = libCloudKeychainProxy.a;
+                       remoteRef = 4C01DE31164C3793006798CD /* PBXContainerItemProxy */;
+                       sourceTree = BUILT_PRODUCTS_DIR;
+               };
+               4C1288EA15FFE9D7008CE3E3 /* libSecureObjectSync.a */ = {
+                       isa = PBXReferenceProxy;
+                       fileType = archive.ar;
+                       path = libSecureObjectSync.a;
+                       remoteRef = 4C1288E915FFE9D7008CE3E3 /* PBXContainerItemProxy */;
+                       sourceTree = BUILT_PRODUCTS_DIR;
+               };
+               4C1288EC15FFE9D7008CE3E3 /* libSOSRegressions.a */ = {
+                       isa = PBXReferenceProxy;
+                       fileType = archive.ar;
+                       path = libSOSRegressions.a;
+                       remoteRef = 4C1288EB15FFE9D7008CE3E3 /* PBXContainerItemProxy */;
+                       sourceTree = BUILT_PRODUCTS_DIR;
+               };
+               4C1288EE15FFE9D7008CE3E3 /* libSecurityRegressions.a */ = {
+                       isa = PBXReferenceProxy;
+                       fileType = archive.ar;
+                       path = libSecurityRegressions.a;
+                       remoteRef = 4C1288ED15FFE9D7008CE3E3 /* PBXContainerItemProxy */;
+                       sourceTree = BUILT_PRODUCTS_DIR;
+               };
+               4C1288F015FFE9D7008CE3E3 /* libsecuritydRegressions.a */ = {
+                       isa = PBXReferenceProxy;
+                       fileType = archive.ar;
+                       path = libsecuritydRegressions.a;
+                       remoteRef = 4C1288EF15FFE9D7008CE3E3 /* PBXContainerItemProxy */;
+                       sourceTree = BUILT_PRODUCTS_DIR;
+               };
+               4C1288F215FFE9D7008CE3E3 /* libSecOtrOSX.a */ = {
+                       isa = PBXReferenceProxy;
+                       fileType = archive.ar;
+                       path = libSecOtrOSX.a;
+                       remoteRef = 4C1288F115FFE9D7008CE3E3 /* PBXContainerItemProxy */;
+                       sourceTree = BUILT_PRODUCTS_DIR;
+               };
+               4C12894015FFECF3008CE3E3 /* libutilities.a */ = {
+                       isa = PBXReferenceProxy;
+                       fileType = archive.ar;
+                       path = libutilities.a;
+                       remoteRef = 4C12893F15FFECF3008CE3E3 /* PBXContainerItemProxy */;
+                       sourceTree = BUILT_PRODUCTS_DIR;
+               };
+               4C12894215FFECF3008CE3E3 /* libutilitiesRegressions.a */ = {
+                       isa = PBXReferenceProxy;
+                       fileType = archive.ar;
+                       path = libutilitiesRegressions.a;
+                       remoteRef = 4C12894115FFECF3008CE3E3 /* PBXContainerItemProxy */;
+                       sourceTree = BUILT_PRODUCTS_DIR;
+               };
+               4CB23B76169F5873003A0131 /* libSecurityTool.a */ = {
+                       isa = PBXReferenceProxy;
+                       fileType = archive.ar;
+                       path = libSecurityTool.a;
+                       remoteRef = 4CB23B75169F5873003A0131 /* PBXContainerItemProxy */;
+                       sourceTree = BUILT_PRODUCTS_DIR;
+               };
+               4CB23B78169F5873003A0131 /* libSecurityCommands.a */ = {
+                       isa = PBXReferenceProxy;
+                       fileType = archive.ar;
+                       path = libSecurityCommands.a;
+                       remoteRef = 4CB23B77169F5873003A0131 /* PBXContainerItemProxy */;
+                       sourceTree = BUILT_PRODUCTS_DIR;
+               };
+               4CB23B7A169F5873003A0131 /* libSOSCommands.a */ = {
+                       isa = PBXReferenceProxy;
+                       fileType = archive.ar;
+                       path = libSOSCommands.a;
+                       remoteRef = 4CB23B79169F5873003A0131 /* PBXContainerItemProxy */;
+                       sourceTree = BUILT_PRODUCTS_DIR;
+               };
                52B5A8F6151928B400664F11 /* XPCTimeStampingService.xpc */ = {
                        isa = PBXReferenceProxy;
                        fileType = wrapper.application;
                52B5A8F6151928B400664F11 /* XPCTimeStampingService.xpc */ = {
                        isa = PBXReferenceProxy;
                        fileType = wrapper.application;
                        remoteRef = C2432A0715C7112A0096DB5B /* PBXContainerItemProxy */;
                        sourceTree = BUILT_PRODUCTS_DIR;
                };
                        remoteRef = C2432A0715C7112A0096DB5B /* PBXContainerItemProxy */;
                        sourceTree = BUILT_PRODUCTS_DIR;
                };
+               EB2E1F58166D6B3700A7EF61 /* com.apple.CodeSigningHelper.xpc */ = {
+                       isa = PBXReferenceProxy;
+                       fileType = wrapper.cfbundle;
+                       path = com.apple.CodeSigningHelper.xpc;
+                       remoteRef = EB2E1F57166D6B3700A7EF61 /* PBXContainerItemProxy */;
+                       sourceTree = BUILT_PRODUCTS_DIR;
+               };
 /* End PBXReferenceProxy section */
 
 /* Begin PBXResourcesBuildPhase section */
 /* End PBXReferenceProxy section */
 
 /* Begin PBXResourcesBuildPhase section */
                                182BB55F146F4544000BF1F3 /* FDEPrefs.plist in Resources */,
                                18500F9B14708D0E006F9AB4 /* SecDebugErrorMessages.strings in Resources */,
                                18500FA114708F19006F9AB4 /* SecErrorMessages.strings in Resources */,
                                182BB55F146F4544000BF1F3 /* FDEPrefs.plist in Resources */,
                                18500F9B14708D0E006F9AB4 /* SecDebugErrorMessages.strings in Resources */,
                                18500FA114708F19006F9AB4 /* SecErrorMessages.strings in Resources */,
+                               BE8C5F0A16F7CE450074CF86 /* framework.sb in Resources */,
                                188AD8DC1471FE3E0081C619 /* FDELocalizable.strings in Resources */,
                                188AD8DD1471FE3E0081C619 /* InfoPlist.strings in Resources */,
                                52B006C015238F76005D4556 /* TimeStampingPrefs.plist in Resources */,
                                188AD8DC1471FE3E0081C619 /* FDELocalizable.strings in Resources */,
                                188AD8DD1471FE3E0081C619 /* InfoPlist.strings in Resources */,
                                52B006C015238F76005D4556 /* TimeStampingPrefs.plist in Resources */,
+                               187D6B9315D435BD00E27494 /* authorization.buttons.strings in Resources */,
+                               187D6B9415D435C700E27494 /* authorization.prompts.strings in Resources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               4C96F7BF16D6DF8300D3B39D /* Resources */ = {
+                       isa = PBXResourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               532847791785076B009118DC /* Localizable.strings in Resources */,
+                               4CFE1CB916DD4B9C0026E900 /* CloudKeychain.icns in Resources */,
+                               4C49390D16E51ACE00CE110C /* com.apple.security.keychain-circle-notification.plist in Resources */,
+                               4C96F7C816D6DF8400D3B39D /* InfoPlist.strings in Resources */,
+                               4C96F7CE16D6DF8400D3B39D /* Credits.rtf in Resources */,
+                               4C96F7D416D6DF8400D3B39D /* MainMenu.xib in Resources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               4CC7A7B116CC2A84003E10C1 /* Resources */ = {
+                       isa = PBXResourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               4C2505B716D2DF9F002CE025 /* Icon.icns in Resources */,
+                               4CC7A7BA16CC2A85003E10C1 /* InfoPlist.strings in Resources */,
+                               4CC7A7C016CC2A85003E10C1 /* Credits.rtf in Resources */,
+                               4CC7A7C616CC2A85003E10C1 /* MainMenu.xib in Resources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               5214700416977CB800DF0DB3 /* Resources */ = {
+                       isa = PBXResourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               5214702216977E7D00DF0DB3 /* CloudKeychainProxy-Info.plist in Resources */,
+                               5214701216977CB800DF0DB3 /* InfoPlist.strings in Resources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
 /* End PBXResourcesBuildPhase section */
 
 /* Begin PBXShellScriptBuildPhase section */
 /* End PBXResourcesBuildPhase section */
 
 /* Begin PBXShellScriptBuildPhase section */
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        shellPath = /bin/sh;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        shellPath = /bin/sh;
-                       shellScript = "XPC_SERVICE=XPCKeychainSandboxCheck.xpc\nditto -v ${TARGET_BUILD_DIR}/${XPC_SERVICE} ${BUILT_PRODUCTS_DIR}/Security.framework/XPCServices/${XPC_SERVICE}\nXPC_SERVICE=XPCTimeStampingService.xpc\nditto -v ${TARGET_BUILD_DIR}/${XPC_SERVICE} ${BUILT_PRODUCTS_DIR}/Security.framework/XPCServices/${XPC_SERVICE}\nexit 0";
+                       shellScript = "DST=${BUILT_PRODUCTS_DIR}/${CONTENTS_FOLDER_PATH}/XPCServices\n\nXPC_SERVICE=XPCKeychainSandboxCheck.xpc\nditto -v ${BUILT_PRODUCTS_DIR}/${XPC_SERVICE} ${DST}/${XPC_SERVICE}\nif [ $0 -ne 0]; then\n    exit $0;\nfi\nXPC_SERVICE=XPCTimeStampingService.xpc\nditto -v ${BUILT_PRODUCTS_DIR}/${XPC_SERVICE} ${DST}/${XPC_SERVICE}\n\nif [ $0 -ne 0]; then\n    exit $0;\nfi\n\nif [ ! -h ${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}/XPCServices ]; then\n    ln -s Versions/Current/XPCServices ${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}/XPCServices\nfi\n\nexit 0";
                        showEnvVarsInLog = 0;
                };
                        showEnvVarsInLog = 0;
                };
-               18500F9214708073006F9AB4 /* Run Script Generate Source */ = {
+               18500F961470828E006F9AB4 /* Run Script Generate Strings */ = {
                        isa = PBXShellScriptBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        );
                        inputPaths = (
                        );
                        isa = PBXShellScriptBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        );
                        inputPaths = (
                        );
-                       name = "Run Script Generate Source";
+                       name = "Run Script Generate Strings";
                        outputPaths = (
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        shellPath = /bin/sh;
                        outputPaths = (
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        shellPath = /bin/sh;
-                       shellScript = "DERIVED_SRC=${BUILT_PRODUCTS_DIR}/derived_src\nmkdir -p ${DERIVED_SRC}\n\nEXPORTS=${PROJECT_DIR}/lib/security.exp\nEXPORTS_DST=${DERIVED_SRC}/security.exp\nsort -u ${EXPORTS} | grep -v '^#' | grep -v '^$' > ${EXPORTS_DST}\n\nTARGET=${DERIVED_SRC}/security_exports.s\n\nsed 's/^/.reference /' < ${EXPORTS_DST} > ${TARGET}\n";
+                       shellScript = "DERIVED_SRC=${BUILT_PRODUCTS_DIR}/derived_src\nmkdir -p ${DERIVED_SRC}\n\n# make error message string files\n\nGENDEBUGSTRS[0]=YES; ERRORSTRINGS[0]=${DERIVED_SRC}/SecDebugErrorMessages.strings\nGENDEBUGSTRS[1]=NO ; ERRORSTRINGS[1]=${DERIVED_SRC}/en.lproj/SecErrorMessages.strings\n\nmkdir -p ${DERIVED_SRC}/en.lproj\n\nfor ((ix=0;ix<2;ix++)) ; do\nperl lib/generateErrStrings.pl \\\n${GENDEBUGSTRS[ix]} \\\n${DERIVED_SRC} \\\n${ERRORSTRINGS[ix]} \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/Authorization.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/AuthSession.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/SecureTransport.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/SecBase.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/cssmerr.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/cssmapple.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/CSCommon.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/PrivateHeaders/AuthorizationPriv.h \\\n${PROJECT_DIR}/libsecurity_keychain/lib/MacOSErrorStrings.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/PrivateHeaders/SecureTransportPriv.h\ndone";
                        showEnvVarsInLog = 0;
                };
                        showEnvVarsInLog = 0;
                };
-               18500F961470828E006F9AB4 /* Run Script Generate Strings */ = {
+               18F2360315CB30EC00060520 /* ShellScript */ = {
                        isa = PBXShellScriptBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        );
                        inputPaths = (
                        );
                        isa = PBXShellScriptBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        );
                        inputPaths = (
                        );
-                       name = "Run Script Generate Strings";
                        outputPaths = (
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        shellPath = /bin/sh;
                        outputPaths = (
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        shellPath = /bin/sh;
-                       shellScript = "DERIVED_SRC=${BUILT_PRODUCTS_DIR}/derived_src\nmkdir -p ${DERIVED_SRC}\n\n# make error message string files\n\nGENDEBUGSTRS[0]=YES; ERRORSTRINGS[0]=${DERIVED_SRC}/SecDebugErrorMessages.strings\nGENDEBUGSTRS[1]=NO ; ERRORSTRINGS[1]=${DERIVED_SRC}/en.lproj/SecErrorMessages.strings\n\nmkdir -p ${DERIVED_SRC}/en.lproj\n\nfor ((ix=0;ix<2;ix++)) ; do\nperl lib/generateErrStrings.pl \\\n${GENDEBUGSTRS[ix]} \\\n${DERIVED_SRC} \\\n${ERRORSTRINGS[ix]} \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/Authorization.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/AuthSession.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/SecureTransport.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/SecBase.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/cssmerr.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/cssmapple.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/CSCommon.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/PrivateHeaders/AuthorizationPriv.h \\\n${PROJECT_DIR}/libsecurity_keychain/lib/MacOSErrorStrings.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/PrivateHeaders/SecureTransportPriv.h\ndone";
+                       shellScript = "DST=${BUILT_PRODUCTS_DIR}/Security.framework/Versions/${FRAMEWORK_VERSION}/XPCServices\n\nXPC_SERVICE=authd.xpc\nditto -v ${BUILT_PRODUCTS_DIR}/${XPC_SERVICE} ${DST}/${XPC_SERVICE}\n\nexit 0";
                        showEnvVarsInLog = 0;
                };
 /* End PBXShellScriptBuildPhase section */
 
 /* Begin PBXSourcesBuildPhase section */
                        showEnvVarsInLog = 0;
                };
 /* End PBXShellScriptBuildPhase section */
 
 /* Begin PBXSourcesBuildPhase section */
+               0C6C630715D193C800BC68CD /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               0CCEBDB116C2CFC1001BD7F6 /* main.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               0CC3351616C1ED8000399E53 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               0CC3355A16C1EEE700399E53 /* main.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                18073846146D0D4E00F05C24 /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                18073846146D0D4E00F05C24 /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
-                               182BB5A8146FE6D4000BF1F3 /* security_exports.s in Sources */,
+                               18A5493315EFD3690059E6DC /* dummy.cpp in Sources */,
+                               E778BFBC17176DDE00302C14 /* security.exp-in in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
-                               18270F4114CF465700B05E7F /* client.c in Sources */,
-                               18270EF414CF334A00B05E7F /* securityd_rep.defs in Sources */,
-                               18270EF514CF334A00B05E7F /* securityd_req.defs in Sources */,
                                18270EF614CF334A00B05E7F /* server.c in Sources */,
                                18270EF614CF334A00B05E7F /* server.c in Sources */,
-                               18270F3C14CF44C400B05E7F /* debugging.c in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
-/* End PBXSourcesBuildPhase section */
-
-/* Begin PBXTargetDependency section */
-               18270EE114CF28D000B05E7F /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       name = libsecurity;
-                       targetProxy = 18270EE014CF28D000B05E7F /* PBXContainerItemProxy */;
+               18F234E715C9F9A600060520 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               18F2352115C9FA3C00060520 /* agent.c in Sources */,
+                               18F2352215C9FA3C00060520 /* authdb.c in Sources */,
+                               18F2352315C9FA3C00060520 /* authitems.c in Sources */,
+                               18F2352415C9FA3C00060520 /* authtoken.c in Sources */,
+                               18F2352515C9FA3C00060520 /* authutilities.c in Sources */,
+                               18F2352615C9FA3C00060520 /* ccaudit.c in Sources */,
+                               18F2352715C9FA3C00060520 /* crc.c in Sources */,
+                               18F2352815C9FA3C00060520 /* credential.c in Sources */,
+                               18F2352915C9FA3C00060520 /* debugging.c in Sources */,
+                               18F2352B15C9FA3C00060520 /* engine.c in Sources */,
+                               18F2352C15C9FA3C00060520 /* main.c in Sources */,
+                               18F2352D15C9FA3C00060520 /* mechanism.c in Sources */,
+                               18F2352E15C9FA3C00060520 /* object.c in Sources */,
+                               18F2352F15C9FA3C00060520 /* process.c in Sources */,
+                               18F2353015C9FA3C00060520 /* rule.c in Sources */,
+                               18F2353215C9FA3C00060520 /* server.c in Sources */,
+                               18F2353315C9FA3C00060520 /* session.c in Sources */,
+                               182A191115D09AFF006AB103 /* connection.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
                };
                };
-               18270EE314CF28D900B05E7F /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       name = libsecurityd;
-                       targetProxy = 18270EE214CF28D900B05E7F /* PBXContainerItemProxy */;
+               4C96F7BD16D6DF8300D3B39D /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               4CAEACCC16D6FBF600263776 /* KDSecCircle.m in Sources */,
+                               4C5DD46A17A5E5D000696A79 /* KNPersistantState.m in Sources */,
+                               4CD1980E16DD3BDF00A9E8FD /* NSArray+mapWithBlock.m in Sources */,
+                               4C7D456817BEED0400DDD88F /* NSDictionary+compactDescription.m in Sources */,
+                               4C7D453D17BEE69B00DDD88F /* NSString+compactDescription.m in Sources */,
+                               4C96F7CA16D6DF8400D3B39D /* main.m in Sources */,
+                               4C85DEDB16DBD5BF00ED8D47 /* KDCirclePeer.m in Sources */,
+                               4C96F7D116D6DF8400D3B39D /* KNAppDelegate.m in Sources */,
+                               4C7D456917BEED1400DDD88F /* NSSet+compactDescription.m in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
                };
                };
-               18270F5D14CF655B00B05E7F /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       name = libsecipc_client;
-                       targetProxy = 18270F5C14CF655B00B05E7F /* PBXContainerItemProxy */;
+               4CB23B42169F5873003A0131 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               4CB23B81169F58DE003A0131 /* security_tool_commands.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
                };
                };
-               182BB22C146F07DD000BF1F3 /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       name = XPCKeychainSandboxCheck;
-                       targetProxy = 182BB22B146F07DD000BF1F3 /* PBXContainerItemProxy */;
+               4CC7A7AF16CC2A84003E10C1 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               4C96F76016D5462F00D3B39D /* KDSecCircle.m in Sources */,
+                               4C85DEDA16DBD5BF00ED8D47 /* KDCirclePeer.m in Sources */,
+                               4CC7A7BC16CC2A85003E10C1 /* main.m in Sources */,
+                               4CC7A7C316CC2A85003E10C1 /* KDAppDelegate.m in Sources */,
+                               4CC7A7F616CD99E2003E10C1 /* KDSecItems.m in Sources */,
+                               4CD1980D16DD3BDF00A9E8FD /* NSArray+mapWithBlock.m in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               5214700216977CB800DF0DB3 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               52C3D236169B56860091D9D3 /* ckdmain.m in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               721680A1179B40F600406BB4 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               721680A9179B40F600406BB4 /* main.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               72756BFA175D485D00F52070 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               72756C31175D48C100F52070 /* cloud_keychain_diagnose.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+               0C4EAE7917668DFF00773425 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       name = libsecdRegressions;
+                       targetProxy = 0C4EAE7817668DFF00773425 /* PBXContainerItemProxy */;
+               };
+               0C6C632E15D19D2900BC68CD /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       name = libsecurity_ssl_regressions;
+                       targetProxy = 0C6C632D15D19D2900BC68CD /* PBXContainerItemProxy */;
+               };
+               0C6C642E15D5ADC900BC68CD /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       name = tlsnke;
+                       targetProxy = 0C6C642D15D5ADC900BC68CD /* PBXContainerItemProxy */;
+               };
+               0C6C643015D5AE4C00BC68CD /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       name = libsecurity_ssl_kext;
+                       targetProxy = 0C6C642F15D5AE4C00BC68CD /* PBXContainerItemProxy */;
+               };
+               0CBD50C716C3260D00713B6C /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       name = libsecurity_keychain_regressions;
+                       targetProxy = 0CBD50C616C3260D00713B6C /* PBXContainerItemProxy */;
+               };
+               0CC3350816C1ED8000399E53 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       name = libSecureObjectSync;
+                       targetProxy = 0CC3350916C1ED8000399E53 /* PBXContainerItemProxy */;
+               };
+               0CC3350A16C1ED8000399E53 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       name = utilities;
+                       targetProxy = 0CC3350B16C1ED8000399E53 /* PBXContainerItemProxy */;
+               };
+               0CC3350C16C1ED8000399E53 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       name = libSOSRegressions;
+                       targetProxy = 0CC3350D16C1ED8000399E53 /* PBXContainerItemProxy */;
+               };
+               0CC3351016C1ED8000399E53 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       name = libsecurity;
+                       targetProxy = 0CC3351116C1ED8000399E53 /* PBXContainerItemProxy */;
+               };
+               0CC3351216C1ED8000399E53 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       name = libsecipc_client;
+                       targetProxy = 0CC3351316C1ED8000399E53 /* PBXContainerItemProxy */;
+               };
+               0CC3351416C1ED8000399E53 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       name = libSecItemShimOSX;
+                       targetProxy = 0CC3351516C1ED8000399E53 /* PBXContainerItemProxy */;
+               };
+               0CC3356216C1EF8B00399E53 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       name = regressions;
+                       targetProxy = 0CC3356116C1EF8B00399E53 /* PBXContainerItemProxy */;
+               };
+               0CCEBDB316C2CFD4001BD7F6 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       name = regressions;
+                       targetProxy = 0CCEBDB216C2CFD4001BD7F6 /* PBXContainerItemProxy */;
+               };
+               0CCEBDBA16C303D8001BD7F6 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 0CC3350716C1ED8000399E53 /* secdtests */;
+                       targetProxy = 0CCEBDB916C303D8001BD7F6 /* PBXContainerItemProxy */;
+               };
+               0CCEBDBD16C30948001BD7F6 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       name = utilitiesRegressions;
+                       targetProxy = 0CCEBDBC16C30948001BD7F6 /* PBXContainerItemProxy */;
+               };
+               0CFC55E315DDB86500BEC89E /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 0C6C630A15D193C800BC68CD /* sectests */;
+                       targetProxy = 0CFC55E215DDB86500BEC89E /* PBXContainerItemProxy */;
+               };
+               0CFE4BA7167943EF0077AE4F /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 0C6C642915D5ADB500BC68CD /* Security_kexts */;
+                       targetProxy = 0CFE4BA6167943EF0077AE4F /* PBXContainerItemProxy */;
+               };
+               18270EE114CF28D000B05E7F /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       name = libsecurity;
+                       targetProxy = 18270EE014CF28D000B05E7F /* PBXContainerItemProxy */;
+               };
+               18270EE314CF28D900B05E7F /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       name = libsecurityd;
+                       targetProxy = 18270EE214CF28D900B05E7F /* PBXContainerItemProxy */;
+               };
+               18270F5D14CF655B00B05E7F /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       name = libsecipc_client;
+                       targetProxy = 18270F5C14CF655B00B05E7F /* PBXContainerItemProxy */;
+               };
+               182BB22C146F07DD000BF1F3 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       name = XPCKeychainSandboxCheck;
+                       targetProxy = 182BB22B146F07DD000BF1F3 /* PBXContainerItemProxy */;
                };
                182BB3EC146F2448000BF1F3 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                };
                182BB3EC146F2448000BF1F3 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        name = world;
                        targetProxy = 18B9655B1472F83C005A4D2E /* PBXContainerItemProxy */;
                };
                        name = world;
                        targetProxy = 18B9655B1472F83C005A4D2E /* PBXContainerItemProxy */;
                };
+               18F235FF15CA100300060520 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 18F234EA15C9F9A600060520 /* authd */;
+                       targetProxy = 18F235FE15CA100300060520 /* PBXContainerItemProxy */;
+               };
                18FE688F1471A4C900A2CBE3 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = 18FE67E91471A3AA00A2CBE3 /* copyHeaders */;
                        targetProxy = 18FE688E1471A4C900A2CBE3 /* PBXContainerItemProxy */;
                };
                18FE688F1471A4C900A2CBE3 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = 18FE67E91471A3AA00A2CBE3 /* copyHeaders */;
                        targetProxy = 18FE688E1471A4C900A2CBE3 /* PBXContainerItemProxy */;
                };
+               4AD6F6F41651CC2500DB4CE6 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       name = libSecOtrOSX;
+                       targetProxy = 4AD6F6F31651CC2500DB4CE6 /* PBXContainerItemProxy */;
+               };
+               4C01DF13164C3E74006798CD /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       name = libSecureObjectSync;
+                       targetProxy = 4C01DF12164C3E74006798CD /* PBXContainerItemProxy */;
+               };
+               4C12894415FFED03008CE3E3 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       name = utilities;
+                       targetProxy = 4C12894315FFED03008CE3E3 /* PBXContainerItemProxy */;
+               };
+               4C797BC916D83A3100C7B586 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 4C96F7C016D6DF8300D3B39D /* Keychain Circle Notification */;
+                       targetProxy = 4C797BC816D83A3100C7B586 /* PBXContainerItemProxy */;
+               };
+               4C797BF116D83A3800C7B586 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 4CC7A7B216CC2A84003E10C1 /* Cloud Keychain Utility */;
+                       targetProxy = 4C797BF016D83A3800C7B586 /* PBXContainerItemProxy */;
+               };
+               4C7D8764160A746E00D041E3 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       name = utilities;
+                       targetProxy = 4C7D8763160A746E00D041E3 /* PBXContainerItemProxy */;
+               };
+               4C8D8650177A75100019A804 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       name = libsecipc_client;
+                       targetProxy = 4C8D864F177A75100019A804 /* PBXContainerItemProxy */;
+               };
+               4CB23B84169F5961003A0131 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       name = libSOSCommands;
+                       targetProxy = 4CB23B83169F5961003A0131 /* PBXContainerItemProxy */;
+               };
+               4CB23B86169F5971003A0131 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       name = libSecurityCommands;
+                       targetProxy = 4CB23B85169F5971003A0131 /* PBXContainerItemProxy */;
+               };
+               4CB23B88169F597D003A0131 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       name = libSecurityTool;
+                       targetProxy = 4CB23B87169F597D003A0131 /* PBXContainerItemProxy */;
+               };
+               4CB23B90169F59D8003A0131 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 4CB23B45169F5873003A0131 /* security2 */;
+                       targetProxy = 4CB23B8F169F59D8003A0131 /* PBXContainerItemProxy */;
+               };
+               5208C0FE16A0D3980062DDC5 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       name = libSecureObjectSync;
+                       targetProxy = 5208C0FD16A0D3980062DDC5 /* PBXContainerItemProxy */;
+               };
+               5214701816977D1D00DF0DB3 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       name = utilities;
+                       targetProxy = 5214701716977D1D00DF0DB3 /* PBXContainerItemProxy */;
+               };
+               5214701A16977D2500DF0DB3 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       name = libCloudKeychainProxy;
+                       targetProxy = 5214701916977D2500DF0DB3 /* PBXContainerItemProxy */;
+               };
+               521470291697842500DF0DB3 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 5214700516977CB800DF0DB3 /* CloudKeychainProxy */;
+                       targetProxy = 521470281697842500DF0DB3 /* PBXContainerItemProxy */;
+               };
                529FF2201523BD7F0029D842 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        name = XPCTimeStampingService;
                        targetProxy = 529FF21F1523BD7F0029D842 /* PBXContainerItemProxy */;
                };
                529FF2201523BD7F0029D842 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        name = XPCTimeStampingService;
                        targetProxy = 529FF21F1523BD7F0029D842 /* PBXContainerItemProxy */;
                };
+               721680B3179B4C6C00406BB4 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 721680A4179B40F600406BB4 /* iCloudStats */;
+                       targetProxy = 721680B2179B4C6C00406BB4 /* PBXContainerItemProxy */;
+               };
+               722CF218175D602F00BCE0A5 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 72756BFD175D485D00F52070 /* cloud_keychain_diagnose */;
+                       targetProxy = 722CF217175D602F00BCE0A5 /* PBXContainerItemProxy */;
+               };
                C2432A2515C726B50096DB5B /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        name = gkunpack;
                        targetProxy = C2432A2415C726B50096DB5B /* PBXContainerItemProxy */;
                };
                C2432A2515C726B50096DB5B /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        name = gkunpack;
                        targetProxy = C2432A2415C726B50096DB5B /* PBXContainerItemProxy */;
                };
+               EBB9FFE01682E71F00FF9774 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       name = CodeSigningHelper;
+                       targetProxy = EBB9FFDF1682E71F00FF9774 /* PBXContainerItemProxy */;
+               };
 /* End PBXTargetDependency section */
 
 /* Begin PBXVariantGroup section */
 /* End PBXTargetDependency section */
 
 /* Begin PBXVariantGroup section */
                        path = ../../Security;
                        sourceTree = BUILT_PRODUCTS_DIR;
                };
                        path = ../../Security;
                        sourceTree = BUILT_PRODUCTS_DIR;
                };
+               187D6B8F15D4359F00E27494 /* authorization.buttons.strings */ = {
+                       isa = PBXVariantGroup;
+                       children = (
+                               187D6B9015D4359F00E27494 /* en */,
+                       );
+                       name = authorization.buttons.strings;
+                       sourceTree = "<group>";
+               };
+               187D6B9115D4359F00E27494 /* authorization.prompts.strings */ = {
+                       isa = PBXVariantGroup;
+                       children = (
+                               187D6B9215D4359F00E27494 /* en */,
+                       );
+                       name = authorization.prompts.strings;
+                       sourceTree = "<group>";
+               };
                188AD8D81471FE3D0081C619 /* FDELocalizable.strings */ = {
                        isa = PBXVariantGroup;
                        children = (
                188AD8D81471FE3D0081C619 /* FDELocalizable.strings */ = {
                        isa = PBXVariantGroup;
                        children = (
                        name = InfoPlist.strings;
                        sourceTree = "<group>";
                };
                        name = InfoPlist.strings;
                        sourceTree = "<group>";
                };
+               18F2350D15C9FA3B00060520 /* InfoPlist.strings */ = {
+                       isa = PBXVariantGroup;
+                       children = (
+                               18F2350E15C9FA3B00060520 /* en */,
+                       );
+                       name = InfoPlist.strings;
+                       path = en.lproj;
+                       sourceTree = "<group>";
+               };
+               4C96F7C616D6DF8400D3B39D /* InfoPlist.strings */ = {
+                       isa = PBXVariantGroup;
+                       children = (
+                               4C96F7C716D6DF8400D3B39D /* en */,
+                       );
+                       name = InfoPlist.strings;
+                       sourceTree = "<group>";
+               };
+               4C96F7CC16D6DF8400D3B39D /* Credits.rtf */ = {
+                       isa = PBXVariantGroup;
+                       children = (
+                               4C96F7CD16D6DF8400D3B39D /* en */,
+                       );
+                       name = Credits.rtf;
+                       sourceTree = "<group>";
+               };
+               4C96F7D216D6DF8400D3B39D /* MainMenu.xib */ = {
+                       isa = PBXVariantGroup;
+                       children = (
+                               4C96F7D316D6DF8400D3B39D /* en */,
+                       );
+                       name = MainMenu.xib;
+                       sourceTree = "<group>";
+               };
+               4CC7A7B816CC2A85003E10C1 /* InfoPlist.strings */ = {
+                       isa = PBXVariantGroup;
+                       children = (
+                               4CC7A7B916CC2A85003E10C1 /* en */,
+                       );
+                       name = InfoPlist.strings;
+                       sourceTree = "<group>";
+               };
+               4CC7A7BE16CC2A85003E10C1 /* Credits.rtf */ = {
+                       isa = PBXVariantGroup;
+                       children = (
+                               4CC7A7BF16CC2A85003E10C1 /* en */,
+                       );
+                       name = Credits.rtf;
+                       sourceTree = "<group>";
+               };
+               4CC7A7C416CC2A85003E10C1 /* MainMenu.xib */ = {
+                       isa = PBXVariantGroup;
+                       children = (
+                               4CC7A7C516CC2A85003E10C1 /* en */,
+                       );
+                       name = MainMenu.xib;
+                       sourceTree = "<group>";
+               };
+               5214701016977CB800DF0DB3 /* InfoPlist.strings */ = {
+                       isa = PBXVariantGroup;
+                       children = (
+                               5214701116977CB800DF0DB3 /* en */,
+                       );
+                       name = InfoPlist.strings;
+                       sourceTree = "<group>";
+               };
+               5328475117850741009118DC /* Localizable.strings */ = {
+                       isa = PBXVariantGroup;
+                       children = (
+                               5328475217850741009118DC /* en */,
+                       );
+                       name = Localizable.strings;
+                       sourceTree = "<group>";
+               };
 /* End PBXVariantGroup section */
 
 /* Begin XCBuildConfiguration section */
 /* End PBXVariantGroup section */
 
 /* Begin XCBuildConfiguration section */
+               0C6C631315D193C900BC68CD /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 0C6C632F15D19DE600BC68CD /* test.xcconfig */;
+                       buildSettings = {
+                               ARCHS = "$(ARCHS_STANDARD_64_BIT)";
+                               CODE_SIGN_ENTITLEMENTS = "sectests/SecurityTests-Entitlements.plist";
+                               LIBRARY_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       /usr/lib/system,
+                               );
+                               OTHER_LDFLAGS = "-t";
+                               VALID_ARCHS = x86_64;
+                       };
+                       name = Debug;
+               };
+               0C6C631415D193C900BC68CD /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 0C6C632F15D19DE600BC68CD /* test.xcconfig */;
+                       buildSettings = {
+                               ARCHS = "$(ARCHS_STANDARD_64_BIT)";
+                               CODE_SIGN_ENTITLEMENTS = "sectests/SecurityTests-Entitlements.plist";
+                               LIBRARY_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       /usr/lib/system,
+                               );
+                               OTHER_LDFLAGS = "-t";
+                               VALID_ARCHS = x86_64;
+                       };
+                       name = Release;
+               };
+               0C6C642B15D5ADB500BC68CD /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Debug;
+               };
+               0C6C642C15D5ADB500BC68CD /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Release;
+               };
+               0CC3352B16C1ED8000399E53 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 0C6C632F15D19DE600BC68CD /* test.xcconfig */;
+                       buildSettings = {
+                               ARCHS = "$(ARCHS_STANDARD_64_BIT)";
+                               CODE_SIGN_ENTITLEMENTS = sec/securityd/entitlements.plist;
+                               HEADER_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       "$(PROJECT_DIR)/sec",
+                                       "$(PROJECT_DIR)/utilities",
+                               );
+                               LIBRARY_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       /usr/lib/system,
+                               );
+                               OTHER_LDFLAGS = "-t";
+                               "OTHER_LDFLAGS[sdk=macosx*]" = (
+                                       "-t",
+                                       "-F$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
+                                       "-framework",
+                                       AppleSystemInfo,
+                               );
+                               PRODUCT_NAME = secdtests;
+                               VALID_ARCHS = x86_64;
+                       };
+                       name = Debug;
+               };
+               0CC3352C16C1ED8000399E53 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 0C6C632F15D19DE600BC68CD /* test.xcconfig */;
+                       buildSettings = {
+                               ARCHS = "$(ARCHS_STANDARD_64_BIT)";
+                               CODE_SIGN_ENTITLEMENTS = sec/securityd/entitlements.plist;
+                               HEADER_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       "$(PROJECT_DIR)/sec",
+                                       "$(PROJECT_DIR)/utilities",
+                               );
+                               LIBRARY_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       /usr/lib/system,
+                               );
+                               OTHER_LDFLAGS = "-t";
+                               "OTHER_LDFLAGS[sdk=macosx*]" = (
+                                       "-t",
+                                       "-F$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
+                                       "-framework",
+                                       AppleSystemInfo,
+                               );
+                               PRODUCT_NAME = secdtests;
+                               VALID_ARCHS = x86_64;
+                       };
+                       name = Release;
+               };
                18073873146D0D4E00F05C24 /* Debug */ = {
                        isa = XCBuildConfiguration;
                18073873146D0D4E00F05C24 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 18BBC6801471EF1600F2B224 /* security.xcconfig */;
+                       baseConfigurationReference = 181EA423146D4A2A00A6D320 /* debug.xcconfig */;
                        buildSettings = {
                        };
                        name = Debug;
                };
                18073874146D0D4E00F05C24 /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                        };
                        name = Debug;
                };
                18073874146D0D4E00F05C24 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 18BBC6801471EF1600F2B224 /* security.xcconfig */;
+                       baseConfigurationReference = 181EA425146D4A2A00A6D320 /* release.xcconfig */;
                        buildSettings = {
                        };
                        name = Release;
                };
                18073876146D0D4E00F05C24 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                        };
                        name = Release;
                };
                18073876146D0D4E00F05C24 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 181EA423146D4A2A00A6D320 /* debug.xcconfig */;
+                       baseConfigurationReference = 18BBC6801471EF1600F2B224 /* security.xcconfig */;
                        buildSettings = {
                        buildSettings = {
-                               EXPORTED_SYMBOLS_FILE = lib/security.exp;
+                               EXPORTED_SYMBOLS_FILE = "$(BUILT_PRODUCTS_DIR)/$(TARGETNAME).$(CURRENT_ARCH).exp";
                                INFOPLIST_FILE = "lib/Info-Security.plist";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
                                LIBRARY_SEARCH_PATHS = (
                                INFOPLIST_FILE = "lib/Info-Security.plist";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
                                LIBRARY_SEARCH_PATHS = (
                };
                18073877146D0D4E00F05C24 /* Release */ = {
                        isa = XCBuildConfiguration;
                };
                18073877146D0D4E00F05C24 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 181EA425146D4A2A00A6D320 /* release.xcconfig */;
+                       baseConfigurationReference = 18BBC6801471EF1600F2B224 /* security.xcconfig */;
                        buildSettings = {
                        buildSettings = {
-                               EXPORTED_SYMBOLS_FILE = lib/security.exp;
+                               EXPORTED_SYMBOLS_FILE = "$(BUILT_PRODUCTS_DIR)/$(TARGETNAME).$(CURRENT_ARCH).exp";
                                INFOPLIST_FILE = "lib/Info-Security.plist";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
                                LIBRARY_SEARCH_PATHS = (
                                INFOPLIST_FILE = "lib/Info-Security.plist";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
                                LIBRARY_SEARCH_PATHS = (
                };
                18270EDE14CF282600B05E7F /* Debug */ = {
                        isa = XCBuildConfiguration;
                };
                18270EDE14CF282600B05E7F /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 181EA423146D4A2A00A6D320 /* debug.xcconfig */;
+                       baseConfigurationReference = 18BBC6801471EF1600F2B224 /* security.xcconfig */;
                        buildSettings = {
                        buildSettings = {
+                               CODE_SIGN_ENTITLEMENTS = sec/securityd/entitlements.plist;
                                GCC_PREPROCESSOR_DEFINITIONS = (
                                        "SECITEM_SHIM_OSX=1",
                                        "$(inherited)",
                                );
                                GCC_PREPROCESSOR_DEFINITIONS = (
                                        "SECITEM_SHIM_OSX=1",
                                        "$(inherited)",
                                );
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
                                HEADER_SEARCH_PATHS = (
                                        "$(PROJECT_DIR)/sec",
                                        "$(PROJECT_DIR)/sec/securityd",
                                        "$(PROJECT_DIR)/sec/ipc",
                                HEADER_SEARCH_PATHS = (
                                        "$(PROJECT_DIR)/sec",
                                        "$(PROJECT_DIR)/sec/securityd",
                                        "$(PROJECT_DIR)/sec/ipc",
+                                       "$(PROJECT_DIR)/sec/SOSCircle",
+                                       "$(PROJECT_DIR)/utilities",
                                        "$(PROJECT_DIR)",
                                        "$(PROJECT_DIR)/../ios/asn1",
                                        "$(PROJECT_DIR)/../libsecurity_keychain/libDER",
                                        "$(PROJECT_DIR)",
                                        "$(PROJECT_DIR)/../ios/asn1",
                                        "$(PROJECT_DIR)/../libsecurity_keychain/libDER",
                                        "$(inherited)",
                                );
                                INSTALL_PATH = /usr/libexec;
                                        "$(inherited)",
                                );
                                INSTALL_PATH = /usr/libexec;
+                               "OTHER_LDFLAGS[sdk=macosx*]" = (
+                                       "-F$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
+                                       "-framework",
+                                       AppleSystemInfo,
+                               );
                                USE_HEADERMAP = NO;
                                USE_HEADERMAP = NO;
+                               VALID_ARCHS = x86_64;
                        };
                        name = Debug;
                };
                18270EDF14CF282600B05E7F /* Release */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Debug;
                };
                18270EDF14CF282600B05E7F /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 181EA425146D4A2A00A6D320 /* release.xcconfig */;
+                       baseConfigurationReference = 18BBC6801471EF1600F2B224 /* security.xcconfig */;
                        buildSettings = {
                        buildSettings = {
+                               CODE_SIGN_ENTITLEMENTS = sec/securityd/entitlements.plist;
                                GCC_PREPROCESSOR_DEFINITIONS = (
                                        "SECITEM_SHIM_OSX=1",
                                        "$(inherited)",
                                );
                                GCC_PREPROCESSOR_DEFINITIONS = (
                                        "SECITEM_SHIM_OSX=1",
                                        "$(inherited)",
                                );
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
                                HEADER_SEARCH_PATHS = (
                                        "$(PROJECT_DIR)/sec",
                                        "$(PROJECT_DIR)/sec/securityd",
                                        "$(PROJECT_DIR)/sec/ipc",
                                HEADER_SEARCH_PATHS = (
                                        "$(PROJECT_DIR)/sec",
                                        "$(PROJECT_DIR)/sec/securityd",
                                        "$(PROJECT_DIR)/sec/ipc",
+                                       "$(PROJECT_DIR)/sec/SOSCircle",
+                                       "$(PROJECT_DIR)/utilities",
                                        "$(PROJECT_DIR)",
                                        "$(PROJECT_DIR)/../ios/asn1",
                                        "$(PROJECT_DIR)/../libsecurity_keychain/libDER",
                                        "$(PROJECT_DIR)",
                                        "$(PROJECT_DIR)/../ios/asn1",
                                        "$(PROJECT_DIR)/../libsecurity_keychain/libDER",
                                        "$(inherited)",
                                );
                                INSTALL_PATH = /usr/libexec;
                                        "$(inherited)",
                                );
                                INSTALL_PATH = /usr/libexec;
+                               "OTHER_LDFLAGS[sdk=macosx*]" = (
+                                       "-F$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
+                                       "-framework",
+                                       AppleSystemInfo,
+                               );
                                USE_HEADERMAP = NO;
                                USE_HEADERMAP = NO;
+                               VALID_ARCHS = x86_64;
                        };
                        name = Release;
                };
                182BB573146F4DCB000BF1F3 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Release;
                };
                182BB573146F4DCB000BF1F3 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 181EA423146D4A2A00A6D320 /* debug.xcconfig */;
+                       baseConfigurationReference = 18BBC6801471EF1600F2B224 /* security.xcconfig */;
                        buildSettings = {
                                EXPORTED_SYMBOLS_FILE = lib/plugins/csparser.exp;
                                INFOPLIST_FILE = "lib/plugins/csparser-Info.plist";
                        buildSettings = {
                                EXPORTED_SYMBOLS_FILE = lib/plugins/csparser.exp;
                                INFOPLIST_FILE = "lib/plugins/csparser-Info.plist";
                };
                182BB574146F4DCB000BF1F3 /* Release */ = {
                        isa = XCBuildConfiguration;
                };
                182BB574146F4DCB000BF1F3 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 181EA425146D4A2A00A6D320 /* release.xcconfig */;
+                       baseConfigurationReference = 18BBC6801471EF1600F2B224 /* security.xcconfig */;
                        buildSettings = {
                                EXPORTED_SYMBOLS_FILE = lib/plugins/csparser.exp;
                                INFOPLIST_FILE = "lib/plugins/csparser-Info.plist";
                        buildSettings = {
                                EXPORTED_SYMBOLS_FILE = lib/plugins/csparser.exp;
                                INFOPLIST_FILE = "lib/plugins/csparser-Info.plist";
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
+               18F234F715C9F9A700060520 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 18BFC44017C43393005DE6C3 /* executable.xcconfig */;
+                       buildSettings = {
+                               ARCHS = "$(ARCHS_STANDARD_64_BIT)";
+                               CLANG_ENABLE_OBJC_ARC = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
+                               CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+                               GCC_PRECOMPILE_PREFIX_HEADER = YES;
+                               GCC_PREFIX_HEADER = "authd/security.auth-Prefix.pch";
+                               GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
+                               GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
+                               GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
+                               GCC_WARN_SHADOW = YES;
+                               GCC_WARN_SIGN_COMPARE = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
+                               GCC_WARN_UNKNOWN_PRAGMAS = YES;
+                               GCC_WARN_UNUSED_FUNCTION = YES;
+                               GCC_WARN_UNUSED_LABEL = YES;
+                               GCC_WARN_UNUSED_PARAMETER = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               INFOPLIST_FILE = authd/Info.plist;
+                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/Versions/${FRAMEWORK_VERSION}/XPCServices";
+                               MACH_O_TYPE = mh_execute;
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               RUN_CLANG_STATIC_ANALYZER = YES;
+                               SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator";
+                               WRAPPER_EXTENSION = xpc;
+                       };
+                       name = Debug;
+               };
+               18F234F815C9F9A700060520 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 18BFC44017C43393005DE6C3 /* executable.xcconfig */;
+                       buildSettings = {
+                               ARCHS = "$(ARCHS_STANDARD_64_BIT)";
+                               CLANG_ENABLE_OBJC_ARC = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
+                               CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+                               GCC_PRECOMPILE_PREFIX_HEADER = YES;
+                               GCC_PREFIX_HEADER = "authd/security.auth-Prefix.pch";
+                               GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
+                               GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
+                               GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
+                               GCC_WARN_SHADOW = YES;
+                               GCC_WARN_SIGN_COMPARE = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
+                               GCC_WARN_UNKNOWN_PRAGMAS = YES;
+                               GCC_WARN_UNUSED_FUNCTION = YES;
+                               GCC_WARN_UNUSED_LABEL = YES;
+                               GCC_WARN_UNUSED_PARAMETER = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               INFOPLIST_FILE = authd/Info.plist;
+                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/Versions/${FRAMEWORK_VERSION}/XPCServices";
+                               MACH_O_TYPE = mh_execute;
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator";
+                               WRAPPER_EXTENSION = xpc;
+                       };
+                       name = Release;
+               };
                18FE67FC1471A3AA00A2CBE3 /* Debug */ = {
                        isa = XCBuildConfiguration;
                18FE67FC1471A3AA00A2CBE3 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 181EA423146D4A2A00A6D320 /* debug.xcconfig */;
+                       baseConfigurationReference = 18BBC6801471EF1600F2B224 /* security.xcconfig */;
                        buildSettings = {
                                CODE_SIGN_IDENTITY = "";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
                        buildSettings = {
                                CODE_SIGN_IDENTITY = "";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
                };
                18FE67FD1471A3AA00A2CBE3 /* Release */ = {
                        isa = XCBuildConfiguration;
                };
                18FE67FD1471A3AA00A2CBE3 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 181EA425146D4A2A00A6D320 /* release.xcconfig */;
+                       baseConfigurationReference = 18BBC6801471EF1600F2B224 /* security.xcconfig */;
                        buildSettings = {
                                CODE_SIGN_IDENTITY = "";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
                        buildSettings = {
                                CODE_SIGN_IDENTITY = "";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
+               4C96F7D616D6DF8400D3B39D /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+                               CLANG_CXX_LIBRARY = "libc++";
+                               CLANG_ENABLE_OBJC_ARC = YES;
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               CODE_SIGN_ENTITLEMENTS = "Keychain Circle Notification/entitlments.plist";
+                               CODE_SIGN_IDENTITY = "-";
+                               COMBINE_HIDPI_IMAGES = YES;
+                               COPY_PHASE_STRIP = NO;
+                               FRAMEWORK_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
+                               );
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               GCC_PREFIX_HEADER = "Keychain Circle Notification/Keychain Circle Notification-Prefix.pch";
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "DEBUG=1",
+                                       "$(inherited)",
+                               );
+                               GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               HEADER_SEARCH_PATHS = (
+                                       /System/Library/Frameworks/Security.framework/PrivateHeaders,
+                                       /System/Library/Frameworks/CoreFoundation.framework/PrivateHeaders,
+                                       "$(PROJECT_DIR)/sec",
+                               );
+                               INFOPLIST_FILE = "Keychain Circle Notification/Keychain Circle Notification-Info.plist";
+                               INSTALL_PATH = /System/Library/CoreServices;
+                               MACOSX_DEPLOYMENT_TARGET = 10.9;
+                               ONLY_ACTIVE_ARCH = YES;
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               SDKROOT = "";
+                               VALID_ARCHS = x86_64;
+                               WRAPPER_EXTENSION = app;
+                       };
+                       name = Debug;
+               };
+               4C96F7D716D6DF8400D3B39D /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+                               CLANG_CXX_LIBRARY = "libc++";
+                               CLANG_ENABLE_OBJC_ARC = YES;
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               CODE_SIGN_ENTITLEMENTS = "Keychain Circle Notification/entitlments.plist";
+                               CODE_SIGN_IDENTITY = "-";
+                               COMBINE_HIDPI_IMAGES = YES;
+                               COPY_PHASE_STRIP = YES;
+                               DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+                               ENABLE_NS_ASSERTIONS = NO;
+                               FRAMEWORK_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
+                               );
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+                               GCC_PREFIX_HEADER = "Keychain Circle Notification/Keychain Circle Notification-Prefix.pch";
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               HEADER_SEARCH_PATHS = (
+                                       /System/Library/Frameworks/Security.framework/PrivateHeaders,
+                                       /System/Library/Frameworks/CoreFoundation.framework/PrivateHeaders,
+                                       "$(PROJECT_DIR)/sec",
+                               );
+                               INFOPLIST_FILE = "Keychain Circle Notification/Keychain Circle Notification-Info.plist";
+                               INSTALL_PATH = /System/Library/CoreServices;
+                               MACOSX_DEPLOYMENT_TARGET = 10.9;
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               SDKROOT = "";
+                               VALID_ARCHS = x86_64;
+                               WRAPPER_EXTENSION = app;
+                       };
+                       name = Release;
+               };
+               4CB23B4D169F5873003A0131 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 4CB23B91169F5CFF003A0131 /* command.xcconfig */;
+                       buildSettings = {
+                               ARCHS = "$(ARCHS_STANDARD_64_BIT)";
+                               CODE_SIGN_ENTITLEMENTS = sec/SecurityTool/entitlements.plist;
+                               CODE_SIGN_IDENTITY = "-";
+                               DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+                               ONLY_ACTIVE_ARCH = YES;
+                               PRODUCT_NAME = security2;
+                               PROVISIONING_PROFILE = "";
+                       };
+                       name = Debug;
+               };
+               4CB23B4E169F5873003A0131 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 4CB23B91169F5CFF003A0131 /* command.xcconfig */;
+                       buildSettings = {
+                               ARCHS = "$(ARCHS_STANDARD_64_BIT)";
+                               CODE_SIGN_ENTITLEMENTS = sec/SecurityTool/entitlements.plist;
+                               CODE_SIGN_IDENTITY = "-";
+                               DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+                               PRODUCT_NAME = security2;
+                               PROVISIONING_PROFILE = "";
+                       };
+                       name = Release;
+               };
+               4CC7A7C716CC2A85003E10C1 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+                               CLANG_CXX_LIBRARY = "libc++";
+                               CLANG_ENABLE_OBJC_ARC = YES;
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               CODE_SIGN_ENTITLEMENTS = sec/SecurityTool/entitlements.plist;
+                               CODE_SIGN_IDENTITY = "-";
+                               COMBINE_HIDPI_IMAGES = YES;
+                               COPY_PHASE_STRIP = NO;
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               GCC_PREFIX_HEADER = "Keychain/Keychain-Prefix.pch";
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "DEBUG=1",
+                                       "$(inherited)",
+                               );
+                               GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               HEADER_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       /System/Library/Frameworks/Security.framework/PrivateHeaders,
+                                       /System/Library/Frameworks/CoreFoundation.framework/PrivateHeaders,
+                               );
+                               INFOPLIST_FILE = "Keychain/Keychain-Info.plist";
+                               INSTALL_PATH = /AppleInternal/Applications;
+                               MACOSX_DEPLOYMENT_TARGET = 10.9;
+                               ONLY_ACTIVE_ARCH = YES;
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               SDKROOT = "";
+                               VALID_ARCHS = x86_64;
+                               WRAPPER_EXTENSION = app;
+                       };
+                       name = Debug;
+               };
+               4CC7A7C816CC2A85003E10C1 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+                               CLANG_CXX_LIBRARY = "libc++";
+                               CLANG_ENABLE_OBJC_ARC = YES;
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               CODE_SIGN_ENTITLEMENTS = sec/SecurityTool/entitlements.plist;
+                               CODE_SIGN_IDENTITY = "-";
+                               COMBINE_HIDPI_IMAGES = YES;
+                               COPY_PHASE_STRIP = YES;
+                               DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+                               ENABLE_NS_ASSERTIONS = NO;
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+                               GCC_PREFIX_HEADER = "Keychain/Keychain-Prefix.pch";
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               HEADER_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       /System/Library/Frameworks/Security.framework/PrivateHeaders,
+                                       /System/Library/Frameworks/CoreFoundation.framework/PrivateHeaders,
+                               );
+                               INFOPLIST_FILE = "Keychain/Keychain-Info.plist";
+                               INSTALL_PATH = /AppleInternal/Applications;
+                               MACOSX_DEPLOYMENT_TARGET = 10.9;
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               SDKROOT = "";
+                               VALID_ARCHS = x86_64;
+                               WRAPPER_EXTENSION = app;
+                       };
+                       name = Release;
+               };
+               4CE4729F16D833FE009070D1 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Debug;
+               };
+               4CE472A016D833FE009070D1 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Release;
+               };
+               5214701516977CB800DF0DB3 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 18BBC6801471EF1600F2B224 /* security.xcconfig */;
+                       buildSettings = {
+                               ARCHS = "$(ARCHS_STANDARD_64_BIT)";
+                               CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+                               CLANG_CXX_LIBRARY = "libc++";
+                               CLANG_ENABLE_OBJC_ARC = YES;
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               CODE_SIGN_ENTITLEMENTS = CloudKeychainProxy/cloudkeychain.entitlements.plist;
+                               CODE_SIGN_IDENTITY = "-";
+                               COMBINE_HIDPI_IMAGES = YES;
+                               COPY_PHASE_STRIP = NO;
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "DEBUG=1",
+                                       "$(inherited)",
+                               );
+                               GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               INFOPLIST_FILE = "CloudKeychainProxy/CloudKeychainProxy-Info.plist";
+                               INSTALL_PATH = "$(INDIGO_INSTALL_PATH_PREFIX)$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/Versions/A/Resources";
+                               MACH_O_TYPE = mh_execute;
+                               MACOSX_DEPLOYMENT_TARGET = 10.9;
+                               ONLY_ACTIVE_ARCH = YES;
+                               "OTHER_LDFLAGS[sdk=iphoneos*]" = (
+                                       "$(inherited)",
+                                       "-framework",
+                                       MobileKeyBag,
+                               );
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               PROVISIONING_PROFILE = "";
+                               SDKROOT = "";
+                               VALID_ARCHS = "armv6 armv7 x86_64";
+                               WRAPPER_EXTENSION = bundle;
+                       };
+                       name = Debug;
+               };
+               5214701616977CB800DF0DB3 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 18BBC6801471EF1600F2B224 /* security.xcconfig */;
+                       buildSettings = {
+                               ARCHS = "$(ARCHS_STANDARD_64_BIT)";
+                               CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+                               CLANG_CXX_LIBRARY = "libc++";
+                               CLANG_ENABLE_OBJC_ARC = YES;
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               CODE_SIGN_ENTITLEMENTS = CloudKeychainProxy/cloudkeychain.entitlements.plist;
+                               CODE_SIGN_IDENTITY = "-";
+                               COMBINE_HIDPI_IMAGES = YES;
+                               COPY_PHASE_STRIP = YES;
+                               DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               INFOPLIST_FILE = "CloudKeychainProxy/CloudKeychainProxy-Info.plist";
+                               INSTALL_PATH = "$(INDIGO_INSTALL_PATH_PREFIX)$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/Versions/A/Resources";
+                               MACH_O_TYPE = mh_execute;
+                               MACOSX_DEPLOYMENT_TARGET = 10.9;
+                               "OTHER_LDFLAGS[sdk=iphoneos*]" = (
+                                       "$(inherited)",
+                                       "-framework",
+                                       MobileKeyBag,
+                               );
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               PROVISIONING_PROFILE = "";
+                               SDKROOT = "";
+                               VALID_ARCHS = "armv6 armv7 x86_64";
+                               WRAPPER_EXTENSION = bundle;
+                       };
+                       name = Release;
+               };
+               721680AD179B40F600406BB4 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+                               CLANG_CXX_LIBRARY = "libc++";
+                               CLANG_ENABLE_MODULES = YES;
+                               CLANG_ENABLE_OBJC_ARC = YES;
+                               CLANG_WARN_BOOL_CONVERSION = YES;
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               COPY_PHASE_STRIP = NO;
+                               FRAMEWORK_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       "$(SYSTEM_APPS_DIR)/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.Internal.sdk/System/Library/Frameworks",
+                               );
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "DEBUG=1",
+                                       "$(inherited)",
+                               );
+                               GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+                               GCC_WARN_UNDECLARED_SELECTOR = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
+                               GCC_WARN_UNUSED_FUNCTION = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               HEADER_SEARCH_PATHS = "$(PROJECT)/sec/SOSCircle";
+                               INSTALL_PATH = /usr/libexec;
+                               MACOSX_DEPLOYMENT_TARGET = 10.9;
+                               ONLY_ACTIVE_ARCH = YES;
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               SDKROOT = macosx;
+                       };
+                       name = Debug;
+               };
+               721680AE179B40F600406BB4 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+                               CLANG_CXX_LIBRARY = "libc++";
+                               CLANG_ENABLE_MODULES = YES;
+                               CLANG_ENABLE_OBJC_ARC = YES;
+                               CLANG_WARN_BOOL_CONVERSION = YES;
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               COPY_PHASE_STRIP = YES;
+                               DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+                               ENABLE_NS_ASSERTIONS = NO;
+                               FRAMEWORK_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       "$(SYSTEM_APPS_DIR)/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.Internal.sdk/System/Library/Frameworks",
+                               );
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+                               GCC_WARN_UNDECLARED_SELECTOR = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
+                               GCC_WARN_UNUSED_FUNCTION = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               HEADER_SEARCH_PATHS = "$(PROJECT)/sec/SOSCircle";
+                               INSTALL_PATH = /usr/libexec;
+                               MACOSX_DEPLOYMENT_TARGET = 10.9;
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               SDKROOT = macosx;
+                       };
+                       name = Release;
+               };
+               72756C07175D485D00F52070 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+                               CLANG_CXX_LIBRARY = "libc++";
+                               CLANG_ENABLE_MODULES = YES;
+                               CLANG_ENABLE_OBJC_ARC = YES;
+                               CLANG_WARN_BOOL_CONVERSION = YES;
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               COPY_PHASE_STRIP = NO;
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               GCC_PRECOMPILE_PREFIX_HEADER = NO;
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "DEBUG=1",
+                                       "$(inherited)",
+                               );
+                               GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+                               GCC_WARN_UNDECLARED_SELECTOR = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
+                               GCC_WARN_UNUSED_FUNCTION = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               HEADER_SEARCH_PATHS = (
+                                       /usr/local/include,
+                                       "$(PROJECT_DIR)",
+                                       "$(PROJECT_DIR)/security2",
+                                       "$(PROJECT_DIR)/sec/SOSCircle",
+                                       "$(PROJECT_DIR)/utilities",
+                                       "$(PROJECT_DIR)/sec",
+                               );
+                               MACOSX_DEPLOYMENT_TARGET = 10.9;
+                               ONLY_ACTIVE_ARCH = YES;
+                               OTHER_LDFLAGS = "-laks";
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               SDKROOT = macosx.internal;
+                       };
+                       name = Debug;
+               };
+               72756C08175D485D00F52070 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+                               CLANG_CXX_LIBRARY = "libc++";
+                               CLANG_ENABLE_MODULES = YES;
+                               CLANG_ENABLE_OBJC_ARC = YES;
+                               CLANG_WARN_BOOL_CONVERSION = YES;
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               COPY_PHASE_STRIP = YES;
+                               DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+                               ENABLE_NS_ASSERTIONS = NO;
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+                               GCC_PRECOMPILE_PREFIX_HEADER = NO;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+                               GCC_WARN_UNDECLARED_SELECTOR = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
+                               GCC_WARN_UNUSED_FUNCTION = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               HEADER_SEARCH_PATHS = (
+                                       /usr/local/include,
+                                       "$(PROJECT_DIR)",
+                                       "$(PROJECT_DIR)/security2",
+                                       "$(PROJECT_DIR)/sec/SOSCircle",
+                                       "$(PROJECT_DIR)/utilities",
+                                       "$(PROJECT_DIR)/sec",
+                               );
+                               MACOSX_DEPLOYMENT_TARGET = 10.9;
+                               OTHER_LDFLAGS = "-laks";
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               SDKROOT = macosx.internal;
+                       };
+                       name = Release;
+               };
 /* End XCBuildConfiguration section */
 
 /* Begin XCConfigurationList section */
 /* End XCBuildConfiguration section */
 
 /* Begin XCConfigurationList section */
+               0C6C631215D193C900BC68CD /* Build configuration list for PBXNativeTarget "sectests" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               0C6C631315D193C900BC68CD /* Debug */,
+                               0C6C631415D193C900BC68CD /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               0C6C642A15D5ADB500BC68CD /* Build configuration list for PBXAggregateTarget "Security_kexts" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               0C6C642B15D5ADB500BC68CD /* Debug */,
+                               0C6C642C15D5ADB500BC68CD /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               0CC3352A16C1ED8000399E53 /* Build configuration list for PBXNativeTarget "secdtests" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               0CC3352B16C1ED8000399E53 /* Debug */,
+                               0CC3352C16C1ED8000399E53 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
                18073844146D0D4E00F05C24 /* Build configuration list for PBXProject "Security" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                18073844146D0D4E00F05C24 /* Build configuration list for PBXProject "Security" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
+               18F234F615C9F9A700060520 /* Build configuration list for PBXNativeTarget "authd" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               18F234F715C9F9A700060520 /* Debug */,
+                               18F234F815C9F9A700060520 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
                18FE67FB1471A3AA00A2CBE3 /* Build configuration list for PBXNativeTarget "copyHeaders" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                18FE67FB1471A3AA00A2CBE3 /* Build configuration list for PBXNativeTarget "copyHeaders" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
+               4C96F7D516D6DF8400D3B39D /* Build configuration list for PBXNativeTarget "Keychain Circle Notification" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               4C96F7D616D6DF8400D3B39D /* Debug */,
+                               4C96F7D716D6DF8400D3B39D /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               4CB23B7F169F5873003A0131 /* Build configuration list for PBXNativeTarget "security2" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               4CB23B4D169F5873003A0131 /* Debug */,
+                               4CB23B4E169F5873003A0131 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               4CC7A7EF16CC2A85003E10C1 /* Build configuration list for PBXNativeTarget "Cloud Keychain Utility" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               4CC7A7C716CC2A85003E10C1 /* Debug */,
+                               4CC7A7C816CC2A85003E10C1 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               4CE472C716D833FE009070D1 /* Build configuration list for PBXAggregateTarget "Security_temporary_UI" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               4CE4729F16D833FE009070D1 /* Debug */,
+                               4CE472A016D833FE009070D1 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               5214701416977CB800DF0DB3 /* Build configuration list for PBXNativeTarget "CloudKeychainProxy" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               5214701516977CB800DF0DB3 /* Debug */,
+                               5214701616977CB800DF0DB3 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               721680AC179B40F600406BB4 /* Build configuration list for PBXNativeTarget "iCloudStats" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               721680AD179B40F600406BB4 /* Debug */,
+                               721680AE179B40F600406BB4 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               72756C2F175D485D00F52070 /* Build configuration list for PBXNativeTarget "cloud_keychain_diagnose" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               72756C07175D485D00F52070 /* Debug */,
+                               72756C08175D485D00F52070 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
 /* End XCConfigurationList section */
        };
        rootObject = 18073841146D0D4E00F05C24 /* Project object */;
 /* End XCConfigurationList section */
        };
        rootObject = 18073841146D0D4E00F05C24 /* Project object */;
index 250c57ccb25ef35e57b2c5c3917a1e090d0d39e4..08de0be8d3c8c1786ebe04545dd772526853eef4 100644 (file)
@@ -2,7 +2,7 @@
 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 <plist version="1.0">
 <dict>
 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 <plist version="1.0">
 <dict>
-    <key>IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded</key>
-    <false/>
+       <key>IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded</key>
+       <false/>
 </dict>
 </plist>
 </dict>
 </plist>
index 8d48ee79d206fcfe9bbb06da111e23e1a18c010b..68e113a070827b53dd00d34bf5e0d63a27bf4ab3 100644 (file)
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
+   LastUpgradeVersion = "0500"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
       buildConfiguration = "Debug">
       <Testables>
       </Testables>
       buildConfiguration = "Debug">
       <Testables>
       </Testables>
+      <MacroExpansion>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "0C6C630A15D193C800BC68CD"
+            BuildableName = "sectests"
+            BlueprintName = "sectests"
+            ReferencedContainer = "container:Security.xcodeproj">
+         </BuildableReference>
+      </MacroExpansion>
    </TestAction>
    <LaunchAction
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
    </TestAction>
    <LaunchAction
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       ignoresPersistentStateOnLaunch = "NO"
       debugDocumentVersioning = "YES"
       allowLocationSimulation = "YES">
       ignoresPersistentStateOnLaunch = "NO"
       debugDocumentVersioning = "YES"
       allowLocationSimulation = "YES">
+      <BuildableProductRunnable>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "0C6C630A15D193C800BC68CD"
+            BuildableName = "sectests"
+            BlueprintName = "sectests"
+            ReferencedContainer = "container:Security.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
       <AdditionalOptions>
       </AdditionalOptions>
    </LaunchAction>
       <AdditionalOptions>
       </AdditionalOptions>
    </LaunchAction>
index 92748dff50c0639b7274ae19d137d9919cc5b0b9..d3e084b3cc167e8dfdd6fc74fbb462cc454955e8 100644 (file)
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
+   LastUpgradeVersion = "0500"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
index d532de4089d63e718cfd036548ffb9322326091b..9c5eea4daec5748a1e38917c83684657528cbaca 100644 (file)
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
+   LastUpgradeVersion = "0500"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
index 8102e9f1c67ceff89a0f056c29e84e6a005f3d25..741e66b5e14e945de478a557ac27e3aa0feb183e 100644 (file)
@@ -1,8 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
+   LastUpgradeVersion = "0500"
    version = "1.3">
    <BuildAction
    version = "1.3">
    <BuildAction
-      parallelizeBuildables = "YES"
+      parallelizeBuildables = "NO"
       buildImplicitDependencies = "YES">
       <BuildActionEntries>
          <BuildActionEntry
       buildImplicitDependencies = "YES">
       <BuildActionEntries>
          <BuildActionEntry
diff --git a/Security.xcodeproj/xcshareddata/xcschemes/authd.xcscheme b/Security.xcodeproj/xcshareddata/xcschemes/authd.xcscheme
new file mode 100644 (file)
index 0000000..5ba8ae3
--- /dev/null
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "0500"
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "18F234EA15C9F9A600060520"
+               BuildableName = "authd.xpc"
+               BlueprintName = "authd"
+               ReferencedContainer = "container:Security.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      buildConfiguration = "Debug">
+      <Testables>
+      </Testables>
+   </TestAction>
+   <LaunchAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Debug"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      allowLocationSimulation = "YES">
+      <AdditionalOptions>
+      </AdditionalOptions>
+   </LaunchAction>
+   <ProfileAction
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Release"
+      debugDocumentVersioning = "YES">
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>
index adc69b37d3d930cca39d7f4390c69c3be32da3c7..8145ed015039d16f0aa113277b08f5336d7e64fb 100644 (file)
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
+   LastUpgradeVersion = "0500"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
index 63a88abe31f8e127590c9964bc86231de905dd60..72a5cb46afacf2d1cba0eb4817ed466ef945486b 100644 (file)
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
+   LastUpgradeVersion = "0500"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/Security.xcodeproj/xcshareddata/xcschemes/secdtests.xcscheme b/Security.xcodeproj/xcshareddata/xcschemes/secdtests.xcscheme
new file mode 100644 (file)
index 0000000..06e4bd6
--- /dev/null
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "0500"
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "0CC3350716C1ED8000399E53"
+               BuildableName = "secdtests"
+               BlueprintName = "secdtests"
+               ReferencedContainer = "container:Security.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      buildConfiguration = "Debug">
+      <Testables>
+      </Testables>
+      <MacroExpansion>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "0CC3350716C1ED8000399E53"
+            BuildableName = "secdtests"
+            BlueprintName = "secdtests"
+            ReferencedContainer = "container:Security.xcodeproj">
+         </BuildableReference>
+      </MacroExpansion>
+   </TestAction>
+   <LaunchAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Debug"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      allowLocationSimulation = "YES">
+      <BuildableProductRunnable>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "0CC3350716C1ED8000399E53"
+            BuildableName = "secdtests"
+            BlueprintName = "secdtests"
+            ReferencedContainer = "container:Security.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+      <CommandLineArguments>
+         <CommandLineArgument
+            argument = "secd_51_account_inflate"
+            isEnabled = "NO">
+         </CommandLineArgument>
+         <CommandLineArgument
+            argument = "secd_55_account_circle"
+            isEnabled = "NO">
+         </CommandLineArgument>
+         <CommandLineArgument
+            argument = "secd_61_account_leave_not_in_kansas_anymore"
+            isEnabled = "NO">
+         </CommandLineArgument>
+         <CommandLineArgument
+            argument = "secd_57_account_leave"
+            isEnabled = "NO">
+         </CommandLineArgument>
+         <CommandLineArgument
+            argument = "-v"
+            isEnabled = "NO">
+         </CommandLineArgument>
+      </CommandLineArguments>
+      <AdditionalOptions>
+      </AdditionalOptions>
+   </LaunchAction>
+   <ProfileAction
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Release"
+      debugDocumentVersioning = "YES">
+      <BuildableProductRunnable>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "0CC3350716C1ED8000399E53"
+            BuildableName = "secdtests"
+            BlueprintName = "secdtests"
+            ReferencedContainer = "container:Security.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>
diff --git a/asl/com.apple.securityd b/asl/com.apple.securityd
new file mode 100644 (file)
index 0000000..9a00330
--- /dev/null
@@ -0,0 +1,28 @@
+> security.log format='$Time $(Sender)[$(PID)] <$((Level)(str))> [$(Facility){$(SecAPITrace)} $(CALLER)]: $Message' rotate=utc-basic crashlog compress file_max=5M all_max=20M
+
+# Note: this file is for OSX only.
+
+# Note:
+# securityd is the iOS securityd
+# com.apple.securityd is the OSX securityd
+# com.apple.secd is the iOS version of securityd running on OSX
+
+? [T SecAPITrace] file security.log
+? [= Sender com.apple.securityd] file security.log
+? [= Sender com.apple.secd] file security.log
+? [= Sender CloudKeychainProxy] file security.log
+? [= Sender securityd] file security.log
+? [= Sender secd] file security.log
+? [= Sender securityd_service] file security.log
+
+# Claim prevents the built-in ASL configuration from
+# processing our messages.   We claim anything short
+# of errors, and let ASL do what it wants with the rest
+
+? [T SecAPITrace] [> Level error] claim
+? [= Sender com.apple.securityd] [> Level error] claim
+? [= Sender com.apple.secd] [> Level error] claim
+? [= Sender CloudKeychainProxy] [> Level error] claim
+? [= Sender securityd] [> Level error] claim
+? [= Sender secd] [> Level error] claim
+? [= Sender securityd_service] [> Level error] claim
diff --git a/authd/Info.plist b/authd/Info.plist
new file mode 100644 (file)
index 0000000..ca58834
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>English</string>
+       <key>CFBundleExecutable</key>
+       <string>${EXECUTABLE_NAME}</string>
+       <key>CFBundleIdentifier</key>
+       <string>com.apple.${PRODUCT_NAME:rfc1034identifier}</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundleName</key>
+       <string>${PRODUCT_NAME}</string>
+       <key>CFBundlePackageType</key>
+       <string>XPC!</string>
+       <key>CFBundleShortVersionString</key>
+       <string>1.0</string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>55471</string>
+       <key>NSHumanReadableCopyright</key>
+       <string>Copyright © 2012 Apple. All rights reserved.</string>
+       <key>XPCService</key>
+       <dict>
+               <key>ServiceType</key>
+               <string>System</string>
+       </dict>
+</dict>
+</plist>
diff --git a/authd/agent.c b/authd/agent.c
new file mode 100644 (file)
index 0000000..677b711
--- /dev/null
@@ -0,0 +1,399 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#include "agent.h"
+#include "authitems.h"
+#include "authd_private.h"
+#include "process.h"
+#include "mechanism.h"
+#include "authutilities.h"
+#include "authtoken.h"
+#include "session.h"
+#include "debugging.h"
+#include "engine.h"
+
+#import <xpc/private.h>
+#include <Security/AuthorizationPlugin.h>
+
+#include <mach/mach.h>
+#include <servers/bootstrap.h>
+#include <bootstrap_priv.h>
+
+#define SECURITYAGENT_BOOTSTRAP_NAME_BASE       "com.apple.security.agentMain"
+#define SECURITYAGENT_STUB_BOOTSTRAP_NAME_BASE       "com.apple.security.agentStub"
+//#define SECURITYAGENT_LOGINWINDOW_BOOTSTRAP_NAME_BASE       "com.apple.security.agent.login"
+#define AUTHORIZATIONHOST_BOOTSTRAP_NAME_BASE   "com.apple.security.authhost"
+
+#define UUID_INITIALIZER_FROM_SESSIONID(sessionid) \
+{ 0,0,0,0, 0,0,0,0, 0,0,0,0, (unsigned char)((0xff000000 & (sessionid))>>24), (unsigned char)((0x00ff0000 & (sessionid))>>16), (unsigned char)((0x0000ff00 & (sessionid))>>8),  (unsigned char)((0x000000ff & (sessionid))) }
+
+struct _agent_s {
+    __AUTH_BASE_STRUCT_HEADER__;
+    
+    auth_items_t hints;
+    auth_items_t context;
+    mechanism_t mech;
+    engine_t engine;
+    PluginState pluginState;
+    uint64_t status;
+    
+    xpc_connection_t agentConnection;
+    xpc_connection_t agentStubConnection;
+    dispatch_queue_t eventQueue;
+    dispatch_queue_t actionQueue;
+    
+    pid_t agentPid;
+};
+
+static void
+_agent_finalize(CFTypeRef value)
+{
+    agent_t agent = (agent_t)value;
+    
+    // If this ever becomes a concurrent queue, then this would need to be a barrier sync
+    dispatch_sync(agent->eventQueue, ^{
+        // Mark the agent as dead
+        agent->pluginState = dead;
+    });
+                  
+    // We're going away, which means no outside references exist. It's safe to dispose of the XPC connection.
+    if (NULL != agent->agentConnection) {
+        xpc_release(agent->agentConnection);
+        agent->agentConnection = NULL;
+    }
+    
+    if (NULL != agent->agentStubConnection) {
+        xpc_release(agent->agentStubConnection);
+        agent->agentStubConnection = NULL;
+    }
+    
+    // Now that we've released any XPC connection that may (or may not) be present
+    // it's safe to go ahead and free our memory. This is provided that all other
+    // blocks that were added to the event queue before the axe came down on the
+    // xpc connection have been executed.
+    
+    // If this ever becomes a concurrent queue, then this would need to be a barrier sync
+    dispatch_sync(agent->eventQueue, ^{
+        CFReleaseSafe(agent->hints);
+        CFReleaseSafe(agent->context);
+        CFReleaseSafe(agent->mech);
+        CFReleaseSafe(agent->engine);
+        dispatch_release(agent->actionQueue);
+    });
+    
+    dispatch_release(agent->eventQueue);
+
+    LOGD("agent[%i]: _agent_finalize called", agent->agentPid);
+}
+
+AUTH_TYPE_INSTANCE(agent,
+                   .init = NULL,
+                   .copy = NULL,
+                   .finalize = _agent_finalize,
+                   .equal = NULL,
+                   .hash = NULL,
+                   .copyFormattingDesc = NULL,
+                   .copyDebugDesc = NULL
+                   );
+
+static CFTypeID agent_get_type_id() {
+    static CFTypeID type_id = _kCFRuntimeNotATypeID;
+    static dispatch_once_t onceToken;
+    
+    dispatch_once(&onceToken, ^{
+        type_id = _CFRuntimeRegisterClass(&_auth_type_agent);
+    });
+    
+    return type_id;
+}
+
+agent_t
+agent_create(engine_t engine, mechanism_t mech, auth_token_t auth, process_t proc, bool firstMech)
+{
+    bool doSwitchAudit = false;
+    bool doSwitchBootstrap = false;
+    agent_t agent = NULL;
+    
+    agent = (agent_t)_CFRuntimeCreateInstance(kCFAllocatorDefault, agent_get_type_id(), AUTH_CLASS_SIZE(agent), NULL);
+    require(agent != NULL, done);
+    
+    agent->mech = (mechanism_t)CFRetain(mech);
+    agent->engine = (engine_t)CFRetain(engine);
+    agent->hints = auth_items_create();
+    agent->context = auth_items_create();
+    agent->pluginState = init;
+    agent->agentPid = process_get_pid(proc);
+    agent->agentStubConnection = NULL;
+    
+    const audit_info_s *audit_info = auth_token_get_audit_info(auth);
+
+    auditinfo_addr_t tempAddr;
+    tempAddr.ai_asid = audit_info->asid;
+    auditon(A_GETSINFO_ADDR, &tempAddr, sizeof(tempAddr));
+    
+    LOGV("agent[%i]: Stored auid %d fetched auid %d", agent->agentPid, audit_info->auid, tempAddr.ai_auid);
+    uid_t auid = tempAddr.ai_auid;
+    uuid_t sessionUUID = UUID_INITIALIZER_FROM_SESSIONID((uint32_t)audit_info->asid);
+
+    agent->eventQueue = dispatch_queue_create("Agent Event Queue", 0);
+    agent->actionQueue = dispatch_queue_create("Agent Action Queue", 0);
+    
+    mach_port_t bootstrapPort = process_get_bootstrap(proc);
+    if (!mechanism_is_privileged(mech)) {
+        if ((int32_t)auid != -1) {
+            agent->agentStubConnection = xpc_connection_create_mach_service(SECURITYAGENT_STUB_BOOTSTRAP_NAME_BASE, NULL, 0);
+            xpc_connection_set_target_uid(agent->agentStubConnection, auid);
+            LOGV("agent[%i]: Creating a security agent stub", agent->agentPid);
+            xpc_connection_set_event_handler(agent->agentStubConnection, ^(xpc_object_t object){}); // Yes, this is a dummy handler, we never ever care about any responses from the stub. It can die in a fire for all I care.
+            xpc_connection_resume(agent->agentStubConnection);
+            
+            xpc_object_t wakeupMessage = xpc_dictionary_create(NULL, NULL, 0);
+            xpc_dictionary_set_data(wakeupMessage, AUTH_XPC_SESSION_UUID, sessionUUID, sizeof(uuid_t));
+            xpc_object_t responseMessage = xpc_connection_send_message_with_reply_sync(agent->agentStubConnection, wakeupMessage);
+            if (xpc_get_type(responseMessage) == XPC_TYPE_DICTIONARY) {
+                LOGV("agent[%i]: Valid response received from stub", agent->agentPid);
+            } else {
+                LOGV("agent[%i]: Error response received from stub", agent->agentPid);
+            }
+            xpc_release(wakeupMessage);
+            xpc_release(responseMessage);
+            
+            mach_port_t newBootstrapPort = auth_token_get_creator_bootstrap(auth);
+            if (newBootstrapPort != MACH_PORT_NULL) {
+                bootstrapPort = newBootstrapPort;
+            }
+        }
+        
+        agent->agentConnection = xpc_connection_create_mach_service(SECURITYAGENT_BOOTSTRAP_NAME_BASE, NULL,0);
+        xpc_connection_set_instance(agent->agentConnection, sessionUUID);
+        LOGV("agent[%i]: Creating a security agent", agent->agentPid);
+        doSwitchAudit = true;
+        doSwitchBootstrap = true;
+    } else {
+        agent->agentConnection = xpc_connection_create_mach_service(AUTHORIZATIONHOST_BOOTSTRAP_NAME_BASE, NULL, 0);
+        xpc_connection_set_instance(agent->agentConnection, sessionUUID);
+        LOGV("agent[%i]: Creating a standard authhost", agent->agentPid);
+        doSwitchAudit = true;
+        doSwitchBootstrap = true;
+    }
+    
+    // **************** Here's the event handler, since I can never find it
+    xpc_connection_set_target_queue(agent->agentConnection, agent->eventQueue);
+    xpc_connection_set_event_handler(agent->agentConnection, ^(xpc_object_t object) {
+        char* objectDesc = xpc_copy_description(object);
+        LOGV("agent[%i]: global xpc message received %s", agent->agentPid, objectDesc);
+        free(objectDesc);
+        
+        if (agent->pluginState == dead) {
+            // If the agent is dead for some reason, drop this message before we hurt ourselves.
+            return;
+        }
+        
+        if (xpc_get_type(object) == XPC_TYPE_DICTIONARY) {
+            const char *replyType = xpc_dictionary_get_string(object, AUTH_XPC_REPLY_METHOD_KEY);
+            if (0 == strcmp(replyType, AUTH_XPC_REPLY_METHOD_INTERRUPT)) {
+                agent->pluginState = interrupting;
+                engine_interrupt_agent(agent->engine);
+            }
+        }
+    });
+    
+    xpc_connection_resume(agent->agentConnection);
+    
+    xpc_object_t requestObject = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_string(requestObject, AUTH_XPC_REQUEST_METHOD_KEY, AUTH_XPC_REQUEST_METHOD_CREATE);
+    xpc_dictionary_set_string(requestObject, AUTH_XPC_PLUGIN_NAME, mechanism_get_plugin(mech));
+    xpc_dictionary_set_string(requestObject, AUTH_XPC_MECHANISM_NAME, mechanism_get_param(mech));
+       if (doSwitchAudit) {
+        mach_port_name_t jobPort;
+        if (audit_info != NULL) {
+            if (0 == audit_session_port(audit_info->asid, &jobPort)) {
+                LOGV("agent[%i]: attaching an audit session port", agent->agentPid);
+                xpc_dictionary_set_mach_send(requestObject, AUTH_XPC_AUDIT_SESSION_PORT, jobPort);
+            }
+        }
+    }
+
+       if (doSwitchBootstrap) {
+        LOGV("agent[%i]: attaching a bootstrap port", agent->agentPid);
+        xpc_dictionary_set_mach_send(requestObject, AUTH_XPC_BOOTSTRAP_PORT, bootstrapPort);
+    }
+    
+    // This loop will be repeated until we can get ahold of a SecurityAgent, or get a fatal error
+    // This will cause us to retry any CONNECTION_INTERRUPTED status messages
+    do {
+        xpc_object_t object = xpc_connection_send_message_with_reply_sync(agent->agentConnection, requestObject);
+        
+        if (xpc_get_type(object) == XPC_TYPE_DICTIONARY) {
+            const char *replyType = xpc_dictionary_get_string(object, AUTH_XPC_REPLY_METHOD_KEY);
+            if (0 == strcmp(replyType, AUTH_XPC_REPLY_METHOD_CREATE)) {
+                agent->status = xpc_dictionary_get_uint64(object, AUTH_XPC_REPLY_RESULT_VALUE);
+                if (agent->status == kAuthorizationResultAllow) {
+                    // Only go here if we have an "allow" from the SecurityAgent (the plugin create might have failed)
+                    // This is backwards compatible so that it goes gently into the build, as the default is "allow".
+                    agent->pluginState = created;
+                } else {
+                    agent->pluginState = dead;
+                }
+            }
+        } else if (xpc_get_type(object) == XPC_TYPE_ERROR) {
+            if (object == XPC_ERROR_CONNECTION_INVALID) {
+                agent->pluginState = dead;
+            }
+        }
+        xpc_release(object);
+    } while ((agent->pluginState == init) && (firstMech));
+    
+    xpc_release(requestObject);
+
+    if (agent->pluginState != created) {
+        CFRelease(agent);
+        agent = NULL;
+    }
+done:
+    return agent;
+}
+
+uint64_t
+agent_run(agent_t agent, auth_items_t hints, auth_items_t context, auth_items_t immutable_hints)
+{
+    xpc_object_t hintsArray = auth_items_export_xpc(hints);
+    xpc_object_t contextArray = auth_items_export_xpc(context);
+    xpc_object_t immutableHintsArray = auth_items_export_xpc(immutable_hints);
+    
+    dispatch_semaphore_t replyWaiter = dispatch_semaphore_create(0);
+    dispatch_sync(agent->actionQueue, ^{
+        if (agent->pluginState != mechinterrupting) {
+            agent->pluginState = current;
+            agent->status = kAuthorizationResultUndefined; // Set this while the plugin chews on the user input.
+            
+            auth_items_clear(agent->hints);
+            auth_items_clear(agent->context);
+            
+            xpc_object_t requestObject = xpc_dictionary_create(NULL, NULL, 0);
+            xpc_dictionary_set_string(requestObject, AUTH_XPC_REQUEST_METHOD_KEY, AUTH_XPC_REQUEST_METHOD_INVOKE);
+            xpc_dictionary_set_value(requestObject, AUTH_XPC_HINTS_NAME, hintsArray);
+            xpc_dictionary_set_value(requestObject, AUTH_XPC_CONTEXT_NAME, contextArray);
+            xpc_dictionary_set_value(requestObject, AUTH_XPC_IMMUTABLE_HINTS_NAME, immutableHintsArray);
+            
+            xpc_connection_send_message_with_reply(agent->agentConnection, requestObject, agent->actionQueue, ^(xpc_object_t object){
+                if (xpc_get_type(object) == XPC_TYPE_DICTIONARY) {
+                    const char *replyType = xpc_dictionary_get_string(object, AUTH_XPC_REPLY_METHOD_KEY);
+                    if (0 == strcmp(replyType, AUTH_XPC_REPLY_METHOD_RESULT)) {
+                        if (agent->pluginState == current) {
+                            xpc_object_t xpcContext = xpc_dictionary_get_value(object, AUTH_XPC_CONTEXT_NAME);
+                            xpc_object_t xpcHints = xpc_dictionary_get_value(object, AUTH_XPC_HINTS_NAME);
+                            auth_items_copy_xpc(agent->context, xpcContext);
+                            auth_items_copy_xpc(agent->hints, xpcHints);
+                            agent->status = xpc_dictionary_get_uint64(object, AUTH_XPC_REPLY_RESULT_VALUE);
+                            agent->pluginState = active;
+                        }
+                    }
+                } else if (xpc_get_type(object) == XPC_TYPE_ERROR) {
+                    if ((object == XPC_ERROR_CONNECTION_INVALID) || (object == XPC_ERROR_CONNECTION_INTERRUPTED)) {
+                        agent->pluginState = dead;
+                    }
+                }
+                dispatch_semaphore_signal(replyWaiter);
+            });
+            xpc_release(requestObject);
+        }
+    });
+
+    if (agent->pluginState == current) {
+        dispatch_semaphore_wait(replyWaiter, DISPATCH_TIME_FOREVER);
+    }
+    dispatch_release(replyWaiter);
+    
+    LOGV("agent[%i]: Finished call to SecurityAgent", agent->agentPid);
+    
+    xpc_release(hintsArray);
+    xpc_release(contextArray);
+    xpc_release(immutableHintsArray);
+    
+    return agent->status;
+}
+
+auth_items_t
+agent_get_hints(agent_t agent)
+{
+    return agent->hints;
+}
+
+auth_items_t
+agent_get_context(agent_t agent)
+{
+    return agent->context;
+}
+
+mechanism_t
+agent_get_mechanism(agent_t agent)
+{
+    return agent->mech;
+}
+
+void
+agent_deactivate(agent_t agent)
+{
+    xpc_object_t requestObject = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_string(requestObject, AUTH_XPC_REQUEST_METHOD_KEY, AUTH_XPC_REQUEST_METHOD_DEACTIVATE);
+
+    agent->pluginState = deactivating;
+
+    xpc_object_t object = xpc_connection_send_message_with_reply_sync(agent->agentConnection, requestObject);
+    if (xpc_get_type(object) == XPC_TYPE_DICTIONARY) {
+        const char *replyType = xpc_dictionary_get_string(object, AUTH_XPC_REPLY_METHOD_KEY);
+        if (0 == strcmp(replyType, AUTH_XPC_REPLY_METHOD_DEACTIVATE)) {
+            agent->pluginState = active; // This is strange, but true. We do actually want to set the state 'active'.
+        }
+    } else if (xpc_get_type(object) == XPC_TYPE_ERROR) {
+        if ((object == XPC_ERROR_CONNECTION_INVALID) || (object == XPC_ERROR_CONNECTION_INTERRUPTED)) {
+            agent->pluginState = dead;
+        }
+    }
+    xpc_release(object);
+    xpc_release(requestObject);
+}
+
+void agent_destroy(agent_t agent)
+{
+    xpc_object_t requestObject = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_string(requestObject, AUTH_XPC_REQUEST_METHOD_KEY, AUTH_XPC_REQUEST_METHOD_DESTROY);
+    xpc_connection_send_message(agent->agentConnection, requestObject);
+    xpc_release(requestObject);
+}
+
+PluginState
+agent_get_state(agent_t agent)
+{
+    return agent->pluginState;
+}
+
+void
+agent_notify_interrupt(agent_t agent)
+{
+    dispatch_sync(agent->actionQueue, ^{
+        if (agent->pluginState == current) {
+            xpc_object_t requestObject = xpc_dictionary_create(NULL, NULL, 0);
+            xpc_dictionary_set_string(requestObject, AUTH_XPC_REQUEST_METHOD_KEY, AUTH_XPC_REQUEST_METHOD_INTERRUPT);
+            xpc_connection_send_message(agent->agentConnection, requestObject);
+            xpc_release(requestObject);
+        } else if (agent->pluginState == active) {
+            agent->pluginState = mechinterrupting;
+        }
+    });
+}
+
+void
+agent_clear_interrupt(agent_t agent)
+{
+    dispatch_sync(agent->actionQueue, ^{
+        if (agent->pluginState == mechinterrupting) {
+            agent->pluginState = active;
+        }
+    });
+}
+
+void
+agent_recieve(agent_t agent)
+{
+}
diff --git a/authd/agent.h b/authd/agent.h
new file mode 100644 (file)
index 0000000..5b1a18b
--- /dev/null
@@ -0,0 +1,106 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#ifndef _SECURITY_AUTH_AGENT_H_
+#define _SECURITY_AUTH_AGENT_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+typedef enum _PluginState {
+    init,
+    created,
+    current,
+    deactivating,
+    active,
+    interrupting,
+    mechinterrupting,
+    dead
+} PluginState;
+    
+typedef enum {
+    privilegedAuthHost,
+    securityAgent,
+    userAuthHost
+} AuthHostType;
+    
+//
+// 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
+    oldPassphraseWrong,             // the old passphrase given is wrong
+    
+    // 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
+    
+    worldChanged = 101
+};
+    
+typedef enum {
+    tool = 'TOOL',
+    bundle = 'BNDL',
+    unknown = 'UNKN'
+} RequestorType;
+    
+AUTH_WARN_RESULT AUTH_MALLOC AUTH_NONNULL_ALL AUTH_RETURNS_RETAINED
+agent_t agent_create(engine_t engine, mechanism_t mech, auth_token_t auth, process_t proc, bool firstMech);
+
+AUTH_NONNULL_ALL
+uint64_t agent_run(agent_t,auth_items_t hints, auth_items_t context, auth_items_t immutable_hints);
+    
+AUTH_NONNULL_ALL
+auth_items_t agent_get_hints(agent_t);
+
+AUTH_NONNULL_ALL
+auth_items_t agent_get_context(agent_t);
+
+AUTH_NONNULL_ALL
+void agent_deactivate(agent_t);
+    
+AUTH_NONNULL_ALL
+void agent_destroy(agent_t);
+    
+AUTH_NONNULL_ALL
+PluginState agent_get_state(agent_t);
+
+AUTH_NONNULL_ALL
+mechanism_t agent_get_mechanism(agent_t);
+    
+AUTH_NONNULL_ALL
+void agent_recieve(agent_t);
+
+AUTH_NONNULL_ALL
+void
+agent_notify_interrupt(agent_t agent);
+
+AUTH_NONNULL_ALL
+void
+agent_clear_interrupt(agent_t agent);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_SECURITY_AUTH_AGENT_H_ */
diff --git a/authd/authd_private.h b/authd/authd_private.h
new file mode 100644 (file)
index 0000000..9e3b232
--- /dev/null
@@ -0,0 +1,118 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#ifndef _AUTHD_PRIVATE_H_
+#define _AUTHD_PRIVATE_H_
+
+#include <stdint.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define AUTH_NONNULL1 __attribute__((__nonnull__(1)))
+#define AUTH_NONNULL2 __attribute__((__nonnull__(2)))
+#define AUTH_NONNULL3 __attribute__((__nonnull__(3)))
+#define AUTH_NONNULL4 __attribute__((__nonnull__(4)))
+#define AUTH_NONNULL5 __attribute__((__nonnull__(5)))
+#define AUTH_NONNULL6 __attribute__((__nonnull__(6)))
+#define AUTH_NONNULL7 __attribute__((__nonnull__(7)))
+#define AUTH_NONNULL_ALL __attribute__((__nonnull__))
+#define AUTH_MALLOC __attribute__((__malloc__))
+#define AUTH_UNUSED __attribute__((unused))
+#define AUTH_WARN_RESULT __attribute__((__warn_unused_result__))
+#define AUTH_INLINE static __inline__ __attribute__((__always_inline__))
+
+#if __has_feature(attribute_cf_returns_retained)
+#define AUTH_RETURNS_RETAINED __attribute__((cf_returns_retained))
+#else
+#define AUTH_RETURNS_RETAINED
+#endif
+
+#if __has_feature(attribute_cf_returns_not_retained)
+#define AUTH_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained))
+#else
+#define AUTH_RETURNS_NOT_RETAINED
+#endif
+    
+#if __has_feature(attribute_cf_consumed)
+#define AUTH_CONSUMED __attribute__((cf_consumed))
+#else
+#define AUTH_CONSUMED
+#endif
+    
+#define SECURITY_AUTH_NAME "com.apple.authd"
+    
+#define AUTH_XPC_TYPE       "_type"
+#define AUTH_XPC_RIGHTS     "_rights"
+#define AUTH_XPC_ENVIROMENT "_enviroment"
+#define AUTH_XPC_FLAGS      "_flags"
+#define AUTH_XPC_BLOB       "_blob"
+#define AUTH_XPC_STATUS     "_status"
+#define AUTH_XPC_RIGHT_NAME "_right_name"
+#define AUTH_XPC_TAG        "_tag"
+#define AUTH_XPC_OUT_ITEMS  "_out_items"
+#define AUTH_XPC_EXTERNAL   "_external"
+#define AUTH_XPC_DATA       "_data"
+#define AUTH_XPC_BOOTSTRAP  "_bootstrap"
+
+#define AUTH_XPC_ITEM_NAME  "_item_name"
+#define AUTH_XPC_ITEM_FLAGS "_item_flags"
+#define AUTH_XPC_ITEM_VALUE "_item_value"
+#define AUTH_XPC_ITEM_TYPE  "_item_type"
+
+#define AUTH_XPC_REQUEST_METHOD_KEY "_agent_request_key"
+#define AUTH_XPC_REQUEST_METHOD_CREATE "_agent_request_create"
+#define AUTH_XPC_REQUEST_METHOD_INVOKE "_agent_request_invoke"
+#define AUTH_XPC_REQUEST_METHOD_DEACTIVATE "_agent_request_deactivate"
+#define AUTH_XPC_REQUEST_METHOD_DESTROY "_agent_request_destroy"
+#define AUTH_XPC_REQUEST_METHOD_INTERRUPT "_agent_request_interrupt"
+#define AUTH_XPC_REQUEST_METHOD_SET_PREFS "_agent_request_setprefs"
+#define AUTH_XPC_REPLY_METHOD_KEY "_agent_reply_key"
+#define AUTH_XPC_REPLY_METHOD_RESULT "_agent_reply_result"
+#define AUTH_XPC_REPLY_METHOD_INTERRUPT "_agent_reply_interrupt"
+#define AUTH_XPC_REPLY_METHOD_CREATE "_agent_reply_create"
+#define AUTH_XPC_REPLY_METHOD_DEACTIVATE "_agent_reply_deactivate"
+#define AUTH_XPC_PLUGIN_NAME "_agent_plugin"
+#define AUTH_XPC_MECHANISM_NAME "_agent_mechanism"
+#define AUTH_XPC_HINTS_NAME "_agent_hints"
+#define AUTH_XPC_CONTEXT_NAME "_agent_context"
+#define AUTH_XPC_IMMUTABLE_HINTS_NAME "_agent_immutable_hints"
+#define AUTH_XPC_REPLY_RESULT_VALUE "_agent_reply_result_value"
+#define AUTH_XPC_AUDIT_SESSION_PORT "_agent_audit_session_port"
+#define AUTH_XPC_BOOTSTRAP_PORT "_agent_bootstrap_port"
+#define AUTH_XPC_SESSION_UUID "_agent_session_uuid"
+#define AUTH_XPC_SESSION_PREFS "_agent_session_prefs"
+#define AUTH_XPC_SESSION_INPUT_METHOD "_agent_session_inputMethod"
+
+typedef struct AuthorizationBlob {
+        uint32_t data[2];
+} AuthorizationBlob;
+
+typedef struct AuthorizationExternalBlob {
+    AuthorizationBlob blob;
+    int32_t session;
+} AuthorizationExternalBlob;
+    
+enum {
+    AUTHORIZATION_CREATE = 1,
+    AUTHORIZATION_FREE,
+    AUTHORIZATION_COPY_RIGHTS,
+    AUTHORIZATION_COPY_INFO,
+    AUTHORIZATION_MAKE_EXTERNAL_FORM,
+    AUTHORIZATION_CREATE_FROM_EXTERNAL_FORM,
+    AUTHORIZATION_RIGHT_GET,
+    AUTHORIZATION_RIGHT_SET,
+    AUTHORIZATION_RIGHT_REMOVE,
+    SESSION_SET_USER_PREFERENCES,
+    AUTHORIZATION_DEV,
+    AUTHORIZATION_CREATE_WITH_AUDIT_TOKEN,
+    AUTHORIZATION_DISMISS,
+    AUTHORIZATION_SETUP,
+    AUTHORIZATION_ENABLE_SMARTCARD
+};
+    
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_AUTHD_PRIVATE_H_ */
diff --git a/authd/authdb.c b/authd/authdb.c
new file mode 100644 (file)
index 0000000..d6952d0
--- /dev/null
@@ -0,0 +1,1073 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#include "authdb.h"
+#include "mechanism.h"
+#include "rule.h"
+#include "debugging.h"
+#include "authitems.h"
+#include "server.h"
+
+#include <sqlite3.h>
+#include <sqlite3_private.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include "rule.h"
+#include "authutilities.h"
+#include <libgen.h>
+#include <sys/stat.h>
+
+#define AUTHDB "/var/db/auth.db"
+#define AUTHDB_DATA "/System/Library/Security/authorization.plist"
+
+#define AUTH_STR(x) #x
+#define AUTH_STRINGIFY(x) AUTH_STR(x)
+
+#define AUTHDB_VERSION 1
+#define AUTHDB_VERSION_STRING AUTH_STRINGIFY(AUTHDB_VERSION)
+
+#define AUTHDB_BUSY_DELAY 1
+#define AUTHDB_MAX_HANDLES 3
+
+struct _authdb_connection_s {
+    __AUTH_BASE_STRUCT_HEADER__;
+    
+    authdb_t db;
+    sqlite3 * handle;
+};
+
+struct _authdb_s {
+    __AUTH_BASE_STRUCT_HEADER__;
+    
+    char * db_path;
+    dispatch_queue_t queue;
+    CFMutableArrayRef connections;
+};
+
+static const char * const authdb_upgrade_sql[] = {
+    /* 0 */
+    /* current scheme */
+    "CREATE TABLE delegates_map ("
+        "r_id INTEGER NOT NULL REFERENCES rules(id) ON DELETE CASCADE,"
+        "d_id INTEGER NOT NULL REFERENCES rules(id) ON DELETE CASCADE,"
+        "ord INTEGER NOT NULL"
+        ");"
+    "CREATE INDEX d_map_d_id ON delegates_map(d_id);"
+    "CREATE INDEX d_map_r_id ON delegates_map(r_id);"
+    "CREATE INDEX d_map_r_id_ord ON delegates_map (r_id, ord);"
+    "CREATE TABLE mechanisms ("
+        "id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,"
+        "plugin TEXT NOT NULL,"
+        "param TEXT NOT NULL,"
+        "privileged INTEGER CHECK (privileged = 0 OR privileged = 1) NOT NULL DEFAULT (0)"
+        ");"
+    "CREATE UNIQUE INDEX mechanisms_lookup ON mechanisms (plugin,param,privileged);"
+    "CREATE TABLE mechanisms_map ("
+        "r_id INTEGER NOT NULL REFERENCES rules(id) ON DELETE CASCADE,"
+        "m_id INTEGER NOT NULL REFERENCES mechanisms(id) ON DELETE CASCADE,"
+        "ord INTEGER NOT NULL"
+        ");"
+    "CREATE INDEX m_map_m_id ON mechanisms_map (m_id);"
+    "CREATE INDEX m_map_r_id ON mechanisms_map (r_id);"
+    "CREATE INDEX m_map_r_id_ord ON mechanisms_map (r_id, ord);"
+    "CREATE TABLE rules ("
+        "id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,"
+        "name TEXT NOT NULL UNIQUE,"
+        "type INTEGER CHECK (type = 1 OR type = 2) NOT NULL,"
+        "class INTEGER CHECK (class > 0),"
+        "'group' TEXT,"
+        "kofn INTEGER,"
+        "timeout INTEGER,"
+        "flags INTEGER,"
+        "tries INTEGER,"
+        "version INTEGER NOT NULL DEFAULT (0),"
+        "created REAL NOT NULL DEFAULT (0),"
+        "modified REAL NOT NULL DEFAULT (0),"
+        "hash BLOB,"
+        "identifier TEXT,"
+        "requirement BLOB,"
+        "comment TEXT"
+        ");"
+    "CREATE INDEX a_type ON rules (type);"
+    "CREATE TABLE config ("
+        "'key' TEXT PRIMARY KEY NOT NULL UNIQUE,"
+        "value"
+        ");"
+    "CREATE TABLE prompts ("
+        "r_id INTEGER NOT NULL REFERENCES rules(id) ON DELETE CASCADE,"
+        "lang TEXT NOT NULL,"
+        "value TEXT NOT NULL"
+        ");"
+    "CREATE INDEX p_r_id ON prompts(r_id);"
+    "CREATE TABLE buttons ("
+        "r_id INTEGER NOT NULL REFERENCES rules(id) ON DELETE CASCADE,"
+        "lang TEXT NOT NULL,"
+        "value TEXT NOT NULL"
+        ");"
+    "CREATE INDEX b_r_id ON buttons(r_id);"
+    "INSERT INTO config VALUES('version', "AUTHDB_VERSION_STRING");"
+};
+
+static int32_t
+_sqlite3_exec(sqlite3 * handle, const char * query)
+{
+    int32_t rc = SQLITE_ERROR;
+    require(query != NULL, done);
+    
+    char * errmsg = NULL;
+    rc = sqlite3_exec(handle, query, NULL, NULL, &errmsg);
+    if (errmsg) {
+        LOGE("authdb: exec, (%i) %s", rc, errmsg);
+        sqlite3_free(errmsg);
+    }
+    
+done:
+    return rc;
+}
+
+struct _db_upgrade_stages {
+    int pre;
+    int main;
+    int post;
+};
+
+static struct _db_upgrade_stages auth_upgrade_script[] = {
+    { .pre = -1, .main = 0, .post = -1 } // Create version AUTHDB_VERSION databse.
+};
+
+static int32_t _db_run_script(authdb_connection_t dbconn, int number)
+{
+    int32_t s3e;
+    
+    /* Script -1 == skip this step. */
+    if (number < 0)
+        return SQLITE_OK;
+    
+    /* If we are attempting to run a script we don't have, fail. */
+    if ((size_t)number >= sizeof(authdb_upgrade_sql) / sizeof(char*))
+        return SQLITE_CORRUPT;
+    
+    s3e = _sqlite3_exec(dbconn->handle, authdb_upgrade_sql[number]);
+    
+    return s3e;
+}
+
+static int32_t _db_upgrade_from_version(authdb_connection_t dbconn, int32_t version)
+{
+    int32_t s3e;
+    
+    /* If we are attempting to upgrade to a version greater than what we have
+     an upgrade script for, fail. */
+    if (version < 0 ||
+        (size_t)version >= sizeof(auth_upgrade_script) / sizeof(struct _db_upgrade_stages))
+        return SQLITE_CORRUPT;
+    
+    struct _db_upgrade_stages *script = &auth_upgrade_script[version];
+    s3e = _db_run_script(dbconn, script->pre);
+    if (s3e == SQLITE_OK)
+        s3e = _db_run_script(dbconn, script->main);
+    if (s3e == SQLITE_OK)
+        s3e = _db_run_script(dbconn, script->post);
+    
+    return s3e;
+}
+
+static void _printCFError(const char * errmsg, CFErrorRef err)
+{
+    CFStringRef errString = NULL;
+    errString = CFErrorCopyDescription(err);
+    char * tmp = _copy_cf_string(errString, NULL);
+    LOGV("%s, %s", errmsg, tmp);
+    free_safe(tmp);
+    CFReleaseSafe(errString);
+}
+
+static void _db_load_data(authdb_connection_t dbconn, auth_items_t config)
+{
+    CFURLRef authURL = NULL;
+    CFPropertyListRef plist = NULL;
+    CFDataRef data = NULL;
+    int32_t rc = 0;
+    CFErrorRef err = NULL;
+    CFTypeRef value = NULL;
+    CFAbsoluteTime ts = 0;
+    CFAbsoluteTime old_ts = 0;
+    
+    authURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR(AUTHDB_DATA), kCFURLPOSIXPathStyle, false);
+    require_action(authURL != NULL, done, LOGE("authdb: file not found %s", AUTHDB_DATA));
+    
+    CFURLCopyResourcePropertyForKey(authURL, kCFURLContentModificationDateKey, &value, &err);
+    require_action(err == NULL, done, _printCFError("authdb: failed to get modification date", err));
+    
+    if (CFGetTypeID(value) == CFDateGetTypeID()) {
+        ts = CFDateGetAbsoluteTime(value);
+    }
+    
+    old_ts = auth_items_get_double(config, "data_ts");
+    if (ts > old_ts) {
+        LOGV("authdb: %s modified old=%f, new=%f", AUTHDB_DATA, old_ts, ts);
+        CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, authURL, &data, NULL, NULL, (SInt32*)&rc);
+        require_noerr_action(rc, done, LOGE("authdb: failed to load %s", AUTHDB_DATA));
+
+        plist = CFPropertyListCreateWithData(kCFAllocatorDefault, data, kCFPropertyListImmutable, NULL, &err);
+        require_action(err == NULL, done, _printCFError("authdb: failed to read plist", err));
+        
+        if (authdb_import_plist(dbconn, plist, true)) {
+            LOGD("authdb: updating data_ts");
+            auth_items_t update = auth_items_create();
+            auth_items_set_double(update, "data_ts", ts);
+            authdb_set_key_value(dbconn, "config", update);
+            CFReleaseSafe(update);
+        }
+    }
+    
+done:
+    CFReleaseSafe(value);
+    CFReleaseSafe(authURL);
+    CFReleaseSafe(plist);
+    CFReleaseSafe(err);
+    CFReleaseSafe(data);
+}
+
+static bool _truncate_db(authdb_connection_t dbconn)
+{
+    int32_t rc = SQLITE_ERROR;
+    int32_t flags = SQLITE_TRUNCATE_JOURNALMODE_WAL | SQLITE_TRUNCATE_AUTOVACUUM_FULL;
+    rc = sqlite3_file_control(dbconn->handle, NULL, SQLITE_TRUNCATE_DATABASE, &flags);
+    if (rc != SQLITE_OK) {
+        LOGV("Failed to delete db handle!  SQLite error %i.\n", rc);
+        if (rc == SQLITE_IOERR) {
+            // Unable to recover successfully if we can't truncate
+            abort();
+        }
+    }
+    
+    return rc == SQLITE_OK;
+}
+
+static void _handle_corrupt_db(authdb_connection_t dbconn)
+{
+    int32_t rc = SQLITE_ERROR;
+    char buf[PATH_MAX+1];
+    sqlite3 *corrupt_db = NULL;
+    
+    snprintf(buf, sizeof(buf), "%s-corrupt", dbconn->db->db_path);
+    if (sqlite3_open(buf, &corrupt_db) == SQLITE_OK) {
+        
+        int on = 1;
+        sqlite3_file_control(corrupt_db, 0, SQLITE_FCNTL_PERSIST_WAL, &on);
+        
+        rc = sqlite3_file_control(corrupt_db, NULL, SQLITE_REPLACE_DATABASE, (void *)dbconn->handle);
+        if (SQLITE_OK == rc) {
+            LOGE("Database at path %s is corrupt. Copying it to %s for further investigation.", dbconn->db->db_path, buf);
+        } else {
+            LOGE("Tried to copy corrupt database at path %s, but we failed with SQLite error %i.", dbconn->db->db_path, rc);
+        }
+        sqlite3_close(corrupt_db);
+    }
+    
+    _truncate_db(dbconn);
+}
+
+static int32_t _db_maintenance(authdb_connection_t dbconn)
+{
+    __block int32_t s3e = SQLITE_OK;
+    __block auth_items_t config = NULL;
+    
+    authdb_transaction(dbconn, AuthDBTransactionNormal, ^bool(void) {
+        
+        authdb_get_key_value(dbconn, "config", &config);
+        
+        // We don't have a config table
+        if (NULL == config) {
+            LOGV("authdb: initializing database");
+            s3e = _db_upgrade_from_version(dbconn, 0);
+            require_noerr_action(s3e, done, LOGE("authdb: failed to initialize database %i", s3e));
+            
+            s3e = authdb_get_key_value(dbconn, "config", &config);
+            require_noerr_action(s3e, done, LOGE("authdb: failed to get config %i", s3e));
+        }
+        
+        int64_t currentVersion = auth_items_get_int64(config, "version");
+        LOGV("authdb: current db ver=%lli", currentVersion);
+        if (currentVersion < AUTHDB_VERSION) {
+            LOGV("authdb: upgrading schema");
+            s3e = _db_upgrade_from_version(dbconn, (int32_t)currentVersion);
+            
+            auth_items_set_int64(config, "version", AUTHDB_VERSION);
+            authdb_set_key_value(dbconn, "config", config);
+        }
+
+    done:
+        return true;
+    });
+    
+    CFReleaseSafe(config);
+    return s3e;
+}
+
+//static void unlock_notify_cb(void **apArg, int nArg AUTH_UNUSED){
+//    dispatch_semaphore_t semaphore = (dispatch_semaphore_t)apArg[0];
+//    dispatch_semaphore_signal(semaphore);
+//}
+//
+//static int32_t _wait_for_unlock_notify(authdb_connection_t dbconn, sqlite3_stmt * stmt)
+//{
+//    int32_t rc;
+//    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
+//    
+//    rc = sqlite3_unlock_notify(dbconn->handle, unlock_notify_cb, semaphore);
+//    require(!rc, done);
+//    
+//    if (dispatch_semaphore_wait(semaphore, 5*NSEC_PER_SEC) != 0) {
+//        LOGV("authdb: timeout occurred!");
+//        sqlite3_unlock_notify(dbconn->handle, NULL, NULL);
+//        rc = SQLITE_LOCKED;
+//    } else if (stmt){
+//        sqlite3_reset(stmt);
+//    }
+//
+//done:
+//    dispatch_release(semaphore);
+//    return rc;
+//}
+
+static bool _is_busy(int32_t rc)
+{
+    return SQLITE_BUSY == rc || SQLITE_LOCKED == rc;
+}
+
+static void _checkResult(authdb_connection_t dbconn, int32_t rc, const char * fn_name, sqlite3_stmt * stmt)
+{
+    bool isCorrupt = (SQLITE_CORRUPT == rc) || (SQLITE_NOTADB == rc) || (SQLITE_IOERR == rc);
+    
+    if (isCorrupt) {
+        _handle_corrupt_db(dbconn);
+        authdb_maintenance(dbconn);
+    } else if (SQLITE_CONSTRAINT == rc || SQLITE_READONLY == rc) {
+        if (stmt) {
+            LOGV("authdb: %s %s for %s", fn_name, sqlite3_errmsg(dbconn->handle), sqlite3_sql(stmt));
+        } else {
+            LOGV("authdb: %s %s", fn_name, sqlite3_errmsg(dbconn->handle));
+        }
+    }
+}
+
+char * authdb_copy_sql_string(sqlite3_stmt * sql,int32_t col)
+{
+    char * result = NULL;
+    const char * sql_str = (const char *)sqlite3_column_text(sql, col);
+    if (sql_str) {
+        size_t len = strlen(sql_str) + 1;
+        result = (char*)calloc(1u, len);
+        check(result != NULL);
+        
+        strlcpy(result, sql_str, len);
+    }
+    return result;
+}
+
+#pragma mark -
+#pragma mark authdb_t
+
+static void
+_authdb_finalize(CFTypeRef value)
+{
+    authdb_t db = (authdb_t)value;
+    
+    CFReleaseSafe(db->connections);
+    dispatch_release(db->queue);
+    free_safe(db->db_path);
+}
+
+AUTH_TYPE_INSTANCE(authdb,
+                   .init = NULL,
+                   .copy = NULL,
+                   .finalize = _authdb_finalize,
+                   .equal = NULL,
+                   .hash = NULL,
+                   .copyFormattingDesc = NULL,
+                   .copyDebugDesc = NULL
+                   );
+
+static CFTypeID authdb_get_type_id() {
+    static CFTypeID type_id = _kCFRuntimeNotATypeID;
+    static dispatch_once_t onceToken;
+    
+    dispatch_once(&onceToken, ^{
+        type_id = _CFRuntimeRegisterClass(&_auth_type_authdb);
+    });
+    
+    return type_id;
+}
+
+authdb_t
+authdb_create()
+{
+    authdb_t db = NULL;
+    
+    db = (authdb_t)_CFRuntimeCreateInstance(kCFAllocatorDefault, authdb_get_type_id(), AUTH_CLASS_SIZE(authdb), NULL);
+    require(db != NULL, done);
+    
+    db->queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
+    db->connections = CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL);
+    
+    if (getenv("__OSINSTALL_ENVIRONMENT") != NULL) {
+        LOGV("authdb: running from installer");
+        db->db_path = _copy_string("file::memory:?cache=shared");
+    } else {
+        db->db_path = _copy_string(AUTHDB);
+    }
+    
+done:
+    return db;
+}
+
+authdb_connection_t authdb_connection_acquire(authdb_t db)
+{
+    __block authdb_connection_t dbconn = NULL;
+#if DEBUG
+    static int32_t total = 0;
+#endif
+    dispatch_sync(db->queue, ^{
+        CFIndex count = CFArrayGetCount(db->connections);
+        if (count) {
+            dbconn = (authdb_connection_t)CFArrayGetValueAtIndex(db->connections, 0);
+            CFArrayRemoveValueAtIndex(db->connections, 0);
+        } else {
+            dbconn = authdb_connection_create(db);
+#if DEBUG
+            total++;
+            LOGV("authdb: no handles available total: %i", total);
+#endif
+        }
+    });
+
+    return dbconn;
+}
+
+void authdb_connection_release(authdb_connection_t * dbconn)
+{
+    if (!dbconn || !(*dbconn))
+        return;
+
+    authdb_connection_t tmp = *dbconn;
+    *dbconn = NULL;
+    
+    dispatch_async(tmp->db->queue, ^{
+        CFIndex count = CFArrayGetCount(tmp->db->connections);
+        if (count <= AUTHDB_MAX_HANDLES) {
+            CFArrayAppendValue(tmp->db->connections, tmp);
+        } else {
+            LOGD("authdb: freeing extra connection");
+            CFRelease(tmp);
+        }
+    });
+}
+
+static bool _db_check_corrupted(authdb_connection_t dbconn)
+{
+    bool isCorrupted = true;
+    sqlite3_stmt *stmt = NULL;
+    int32_t rc;
+    
+    rc = sqlite3_prepare_v2(dbconn->handle, "PRAGMA integrity_check;", -1, &stmt, NULL);
+    if (rc == SQLITE_LOCKED || rc == SQLITE_BUSY) {
+        LOGV("authdb: warning error %i when running integrity check", rc);
+        isCorrupted = false;
+        
+    } else if (rc == SQLITE_OK) {
+        rc = sqlite3_step(stmt);
+        
+        if (rc == SQLITE_LOCKED || rc == SQLITE_BUSY) {
+            LOGV("authdb: warning error %i when running integrity check", rc);
+            isCorrupted = false;
+        } else if (rc == SQLITE_ROW) {
+            const char * result = (const char*)sqlite3_column_text(stmt, 0);
+            
+            if (result && strncasecmp(result, "ok", 3) == 0) {
+                isCorrupted = false;
+            }
+        }
+    }
+    
+    sqlite3_finalize(stmt);
+    return isCorrupted;
+}
+
+bool authdb_maintenance(authdb_connection_t dbconn)
+{
+    LOGD("authdb: starting maintenance");
+    int32_t rc = SQLITE_ERROR;
+    auth_items_t config = NULL;
+    
+    bool isCorrupted = _db_check_corrupted(dbconn);
+    LOGD("authdb: integrity check=%s", isCorrupted ? "fail" : "pass");
+    
+    if (isCorrupted) {
+        _handle_corrupt_db(dbconn);
+    }
+
+    _db_maintenance(dbconn);
+    
+    rc = authdb_get_key_value(dbconn, "config", &config);
+    require_noerr_action(rc, done, LOGV("authdb: maintenance failed %i", rc));
+    
+    _db_load_data(dbconn, config);
+    
+done:
+    CFReleaseSafe(config);
+    LOGD("authdb: finished maintenance");
+    return rc == SQLITE_OK;
+}
+
+int32_t
+authdb_exec(authdb_connection_t dbconn, const char * query)
+{
+    int32_t rc = SQLITE_ERROR;
+    require(query != NULL, done);
+    
+    rc = _sqlite3_exec(dbconn->handle, query);
+    _checkResult(dbconn, rc, __FUNCTION__, NULL);
+    
+done:
+    return rc;
+}
+
+static int32_t _prepare(authdb_connection_t dbconn, const char * sql, sqlite3_stmt ** out_stmt)
+{
+    int32_t rc;
+    sqlite3_stmt * stmt = NULL; 
+    
+    require_action(sql != NULL, done, rc = SQLITE_ERROR);
+    require_action(out_stmt != NULL, done, rc = SQLITE_ERROR);
+    
+    rc = sqlite3_prepare_v2(dbconn->handle, sql, -1, &stmt, NULL);
+    require_noerr_action(rc, done, LOGV("authdb: prepare (%i) %s", rc, sqlite3_errmsg(dbconn->handle)));
+    
+    *out_stmt = stmt;
+    
+done:
+    _checkResult(dbconn, rc, __FUNCTION__, stmt);
+    return rc;
+}
+
+static void _parseItemsAtIndex(sqlite3_stmt * stmt, int32_t col, auth_items_t items, const char * key)
+{
+    switch (sqlite3_column_type(stmt, col)) {
+        case SQLITE_FLOAT:
+            auth_items_set_double(items, key, sqlite3_column_double(stmt, col));
+            break;
+        case SQLITE_INTEGER:
+            auth_items_set_int64(items, key, sqlite3_column_int64(stmt, col));
+            break;
+        case SQLITE_BLOB:
+            auth_items_set_data(items,
+                                key,
+                                sqlite3_column_blob(stmt, col),
+                                (size_t)sqlite3_column_bytes(stmt, col));
+            break;
+        case SQLITE_NULL:
+            break;
+        case SQLITE_TEXT:
+        default:
+            auth_items_set_string(items, key, (const char *)sqlite3_column_text(stmt, col));
+            break;
+    }
+
+//    LOGD("authdb: col=%s, val=%s, type=%i", sqlite3_column_name(stmt, col), sqlite3_column_text(stmt, col), sqlite3_column_type(stmt,col));
+}
+
+static int32_t _bindItemsAtIndex(sqlite3_stmt * stmt, int col, auth_items_t items, const char * key)
+{
+    int32_t rc;
+    switch (auth_items_get_type(items, key)) {
+        case AI_TYPE_INT:
+            rc = sqlite3_bind_int64(stmt, col, auth_items_get_int(items, key));
+            break;
+        case AI_TYPE_UINT:
+            rc = sqlite3_bind_int64(stmt, col, auth_items_get_uint(items, key));
+            break;
+        case AI_TYPE_INT64:
+            rc = sqlite3_bind_int64(stmt, col, auth_items_get_int64(items, key));
+            break;
+        case AI_TYPE_UINT64:
+            rc = sqlite3_bind_int64(stmt, col, (int64_t)auth_items_get_uint64(items, key));
+            break;
+        case AI_TYPE_DOUBLE:
+            rc = sqlite3_bind_double(stmt, col, auth_items_get_double(items, key));
+            break;
+        case AI_TYPE_BOOL:
+            rc = sqlite3_bind_int64(stmt, col, auth_items_get_bool(items, key));
+            break;
+        case AI_TYPE_DATA:
+        {
+            size_t blobLen = 0;
+            const void * blob = auth_items_get_data(items, key, &blobLen);
+            rc = sqlite3_bind_blob(stmt, col, blob, (int32_t)blobLen, NULL);
+        }
+            break;
+        case AI_TYPE_STRING:
+            rc = sqlite3_bind_text(stmt, col, auth_items_get_string(items, key), -1, NULL);
+            break;
+        default:
+            rc = sqlite3_bind_null(stmt, col);
+            break;
+    }
+    if (rc != SQLITE_OK) {
+        LOGV("authdb: auth_items bind failed (%i)", rc);
+    }
+    return rc;
+}
+
+int32_t authdb_get_key_value(authdb_connection_t dbconn, const char * table, auth_items_t * out_items)
+{
+    int32_t rc = SQLITE_ERROR;
+    char * query = NULL;
+    sqlite3_stmt * stmt = NULL;
+    auth_items_t items = NULL;
+    
+    require(table != NULL, done);
+    require(out_items != NULL, done);
+    
+    asprintf(&query, "SELECT * FROM %s", table);
+    
+    rc = _prepare(dbconn, query, &stmt);
+    require_noerr(rc, done);
+    
+    items = auth_items_create();
+    while ((rc = sqlite3_step(stmt)) != SQLITE_DONE) {
+        switch (rc) {
+            case SQLITE_ROW:
+                _parseItemsAtIndex(stmt, 1, items, (const char*)sqlite3_column_text(stmt, 0));
+                break;
+            default:
+                _checkResult(dbconn, rc, __FUNCTION__, stmt);
+                if (_is_busy(rc)) {
+                    sleep(AUTHDB_BUSY_DELAY);
+                } else {
+                    require_noerr_action(rc, done, LOGV("authdb: get_key_value (%i) %s", rc, sqlite3_errmsg(dbconn->handle)));
+                }
+                break;
+        }
+    }
+    
+    rc = SQLITE_OK;
+    CFRetain(items);
+    *out_items = items;
+    
+done:
+    CFReleaseSafe(items);
+    free_safe(query);
+    sqlite3_finalize(stmt);
+    return rc;
+}
+
+int32_t authdb_set_key_value(authdb_connection_t dbconn, const char * table, auth_items_t items)
+{
+    __block int32_t rc = SQLITE_ERROR;
+    char * query = NULL;
+    sqlite3_stmt * stmt = NULL;
+    
+    require(table != NULL, done);
+    require(items != NULL, done);
+    
+    asprintf(&query, "INSERT OR REPLACE INTO %s VALUES (?,?)", table);
+    
+    rc = _prepare(dbconn, query, &stmt);
+    require_noerr(rc, done);
+    
+    auth_items_iterate(items, ^bool(const char *key) {
+        sqlite3_reset(stmt);
+        _checkResult(dbconn, rc, __FUNCTION__, stmt);
+        
+        sqlite3_bind_text(stmt, 1, key, -1, NULL);
+        _bindItemsAtIndex(stmt, 2, items, key);
+        
+        rc = sqlite3_step(stmt);
+        if (rc != SQLITE_DONE) {
+            _checkResult(dbconn, rc, __FUNCTION__, stmt);
+            LOGV("authdb: set_key_value, step (%i) %s", rc, sqlite3_errmsg(dbconn->handle));
+        }
+        
+        return true;
+    });
+    
+done:
+    free_safe(query);
+    sqlite3_finalize(stmt);
+    return rc;
+}
+
+static int32_t _begin_transaction_type(authdb_connection_t dbconn, AuthDBTransactionType type)
+{
+    int32_t result = SQLITE_ERROR;
+    
+    const char * query = NULL;
+    switch (type) {
+        case AuthDBTransactionImmediate:
+            query = "BEGIN IMMEDATE;";
+            break;
+        case AuthDBTransactionExclusive:
+            query = "BEGIN EXCLUSIVE;";
+            break;
+        case AuthDBTransactionNormal:
+            query = "BEGIN;";
+            break;
+        default:
+            break;
+    }
+    
+    result = SQLITE_OK;
+    
+    if (query != NULL && sqlite3_get_autocommit(dbconn->handle) != 0) {
+        result = _sqlite3_exec(dbconn->handle, query);
+    }
+    
+    return result;
+}
+
+static int32_t _end_transaction(authdb_connection_t dbconn, bool commit)
+{
+    if (commit) {
+        return _sqlite3_exec(dbconn->handle, "END;");
+    } else {
+        return _sqlite3_exec(dbconn->handle, "ROLLBACK;");
+    }
+}
+
+bool authdb_transaction(authdb_connection_t dbconn, AuthDBTransactionType type, bool (^t)(void))
+{
+    int32_t result = SQLITE_ERROR;
+    bool commit = false;
+
+    result = _begin_transaction_type(dbconn, type);
+    require_action(result == SQLITE_OK, done, LOGV("authdb: transaction begin failed %i", result));
+
+    commit = t();
+    
+    result = _end_transaction(dbconn, commit);
+    require_action(result == SQLITE_OK, done, commit = false; LOGV("authdb: transaction end failed %i", result));
+
+done:
+    return commit;
+}
+
+bool authdb_step(authdb_connection_t dbconn, const char * sql, void (^bind_stmt)(sqlite3_stmt*), authdb_iterator_t iter)
+{
+    bool result = false;
+    sqlite3_stmt * stmt = NULL;
+    int32_t rc = SQLITE_ERROR;
+    
+    require_action(sql != NULL, done, rc = SQLITE_ERROR);
+    
+    rc = _prepare(dbconn, sql, &stmt);
+    require_noerr(rc, done);
+    
+    if (bind_stmt) {
+        bind_stmt(stmt);
+    }
+    
+    int32_t count = sqlite3_column_count(stmt);
+    
+    auth_items_t items = NULL;
+    while ((rc = sqlite3_step(stmt)) != SQLITE_DONE) {
+        switch (rc) {
+            case SQLITE_ROW:
+                {
+                    if (iter) {
+                        items = auth_items_create();
+                        for (int i = 0; i < count; i++) {
+                            _parseItemsAtIndex(stmt, i, items, sqlite3_column_name(stmt, i));
+                        }
+                        result = iter(items);
+                        CFReleaseNull(items);
+                        if (!result) {
+                            goto done;
+                        }
+                    }
+                }
+                break;
+            default:
+                if (_is_busy(rc)) {
+                    LOGV("authdb: %s", sqlite3_errmsg(dbconn->handle));
+                    sleep(AUTHDB_BUSY_DELAY);
+                    sqlite3_reset(stmt);
+                } else {
+                    require_noerr_action(rc, done, LOGV("authdb: step (%i) %s", rc, sqlite3_errmsg(dbconn->handle)));
+                }
+                break;
+        }
+    }
+    
+done:
+    _checkResult(dbconn, rc, __FUNCTION__, stmt);
+    sqlite3_finalize(stmt);
+    return rc == SQLITE_DONE;
+}
+
+void authdb_checkpoint(authdb_connection_t dbconn)
+{
+    int32_t rc = sqlite3_wal_checkpoint(dbconn->handle, NULL);
+    if (rc != SQLITE_OK) {
+        LOGV("authdb: checkpoit failed %i", rc);
+    }
+}
+
+static CFMutableArrayRef
+_copy_rules_dict(RuleType type, CFDictionaryRef plist, authdb_connection_t dbconn)
+{
+    CFMutableArrayRef result = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+    require(result != NULL, done);
+
+    _cf_dictionary_iterate(plist, ^bool(CFTypeRef key, CFTypeRef value) {
+        if (CFGetTypeID(key) != CFStringGetTypeID()) {
+            return true;
+        }
+        
+        if (CFGetTypeID(value) != CFDictionaryGetTypeID()) {
+            return true;
+        }
+        
+        rule_t rule = rule_create_with_plist(type, key, value, dbconn);
+        if (rule) {
+            CFArrayAppendValue(result, rule);
+            CFReleaseSafe(rule);
+        }
+        
+        return true;
+    });
+    
+done:
+    return result;
+}
+
+static void
+_import_rules(authdb_connection_t dbconn, CFMutableArrayRef rules, bool version_check, CFAbsoluteTime now)
+{
+    CFMutableArrayRef notcommited = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+    CFIndex count = CFArrayGetCount(rules);
+    
+    for (CFIndex i = 0; i < count; i++) {
+        rule_t rule = (rule_t)CFArrayGetValueAtIndex(rules, i);
+        
+        bool update = false;
+        if (version_check) {
+            if (rule_get_id(rule) != 0) { // rule already exists see if we need to update
+                rule_t current = rule_create_with_string(rule_get_name(rule), dbconn);
+                if (rule_get_version(rule) > rule_get_version(current)) {
+                    update = true;
+                }
+                CFReleaseSafe(current);
+                
+                if (!update) {
+                    continue;
+                }
+            }
+        }
+        
+        __block bool delayCommit = false;
+        
+        switch (rule_get_type(rule)) {
+            case RT_RULE:
+                rule_delegates_iterator(rule, ^bool(rule_t delegate) {
+                    if (rule_get_id(delegate) == 0) {
+                        // fetch the rule from the database if it was previously committed
+                        rule_sql_fetch(delegate, dbconn);
+                    }
+                    if (rule_get_id(delegate) == 0) {
+                        LOGD("authdb: delaying %s waiting for delegate %s", rule_get_name(rule), rule_get_name(delegate));
+                        delayCommit = true;
+                        return false;
+                    }
+                    return true;
+                });
+                break;
+            default:
+                break;
+        }
+        
+        if (!delayCommit) {
+            bool success = rule_sql_commit(rule, dbconn, now, NULL);
+            LOGV("authdb: %s %s %s %s",
+                 update ? "updating" : "importing",
+                 rule_get_type(rule) == RT_RULE ? "rule" : "right",
+                 rule_get_name(rule), success ? "success" : "FAIL");
+            if (!success) {
+                CFArrayAppendValue(notcommited, rule);
+            }
+        } else {
+            CFArrayAppendValue(notcommited, rule);
+        }
+    }
+    CFArrayRemoveAllValues(rules);
+    CFArrayAppendArray(rules, notcommited, CFRangeMake(0, CFArrayGetCount(notcommited)));
+    CFReleaseSafe(notcommited);
+}
+
+bool
+authdb_import_plist(authdb_connection_t dbconn, CFDictionaryRef plist, bool version_check)
+{
+    bool result = false;
+    
+    LOGV("authdb: starting import");
+    
+    CFAbsoluteTime now = CFAbsoluteTimeGetCurrent();
+    CFMutableArrayRef rights = NULL;
+    CFMutableArrayRef rules = NULL;
+    require(plist != NULL, done);
+    
+    CFTypeRef rightsDict = CFDictionaryGetValue(plist, CFSTR("rights"));
+    if (rightsDict && CFGetTypeID(rightsDict) == CFDictionaryGetTypeID()) {
+        rights = _copy_rules_dict(RT_RIGHT, rightsDict, dbconn);
+    }
+    
+    CFTypeRef rulesDict = CFDictionaryGetValue(plist, CFSTR("rules"));
+    if (rulesDict && CFGetTypeID(rulesDict) == CFDictionaryGetTypeID()) {
+        rules = _copy_rules_dict(RT_RULE, rulesDict, dbconn);
+    }
+
+    LOGV("authdb: rights = %li", CFArrayGetCount(rights));
+    LOGV("authdb: rules = %li", CFArrayGetCount(rules));
+    
+    CFIndex count;
+    // first pass import base rules without delegations
+    // remaining import rules that delegate to other rules
+    // loop upto 3 times to commit dependent rules first
+    for (int32_t j = 0; j < 3; j++) {
+        count = CFArrayGetCount(rules);
+        if (!count)
+            break;
+
+        _import_rules(dbconn, rules, version_check, now);
+    }
+    
+    _import_rules(dbconn, rights, version_check, now);
+    
+    if (CFArrayGetCount(rights) == 0) {
+        result = true;
+    }
+    
+    authdb_checkpoint(dbconn);
+    
+done:
+    CFReleaseSafe(rights);
+    CFReleaseSafe(rules);
+    
+    LOGV("authdb: finished import, %s", result ? "succeeded" : "failed");
+    
+    return result;
+}
+
+#pragma mark -
+#pragma mark authdb_connection_t
+
+static bool _sql_profile_enabled(void)
+{
+    static bool profile_enabled = false;
+    
+#if DEBUG
+    static dispatch_once_t onceToken;
+
+    //sudo defaults write /Library/Preferences/com.apple.security.auth profile -bool true
+    dispatch_once(&onceToken, ^{
+               CFTypeRef profile = (CFNumberRef)CFPreferencesCopyValue(CFSTR("profile"), CFSTR(SECURITY_AUTH_NAME), kCFPreferencesAnyUser, kCFPreferencesCurrentHost);
+        
+        if (profile && CFGetTypeID(profile) == CFBooleanGetTypeID()) {
+            profile_enabled = CFBooleanGetValue((CFBooleanRef)profile);
+        }
+        
+        LOGV("authdb: sql profile: %s", profile_enabled ? "enabled" : "disabled");
+        
+        CFReleaseSafe(profile);
+    });
+#endif
+    
+    return profile_enabled;
+}
+
+static void _profile(void *context AUTH_UNUSED, const char *sql, sqlite3_uint64 ns) {
+    LOGV("==\nauthdb: %s\nTime: %llu ms\n", sql, ns >> 20);
+}
+
+static sqlite3 * _create_handle(authdb_t db)
+{
+    bool dbcreated = false;
+    sqlite3 * handle = NULL;
+    int32_t rc = sqlite3_open_v2(db->db_path, &handle, SQLITE_OPEN_READWRITE, NULL);
+    
+    if (rc != SQLITE_OK) {
+        char * tmp = dirname(db->db_path);
+        if (tmp) {
+            mkpath_np(tmp, 0700);
+        }
+        rc = sqlite3_open_v2(db->db_path, &handle, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
+        dbcreated = true;
+    }
+    require_noerr_action(rc, done, LOGE("authdb: open %s (%i) %s", db->db_path, rc, sqlite3_errmsg(handle)));
+    
+    if (_sql_profile_enabled()) {
+        sqlite3_profile(handle, _profile, NULL);
+    }
+    
+    _sqlite3_exec(handle, "PRAGMA foreign_keys = ON");
+    _sqlite3_exec(handle, "PRAGMA temp_store = MEMORY");
+    
+    if (dbcreated) {
+        _sqlite3_exec(handle, "PRAGMA auto_vacuum = FULL");
+        _sqlite3_exec(handle, "PRAGMA journal_mode = WAL");
+        
+        int on = 1;
+        sqlite3_file_control(handle, 0, SQLITE_FCNTL_PERSIST_WAL, &on);
+        
+        chmod(db->db_path, S_IRUSR | S_IWUSR);
+    }
+    
+done:
+    return handle;
+}
+
+static void
+_authdb_connection_finalize(CFTypeRef value)
+{
+    authdb_connection_t dbconn = (authdb_connection_t)value;
+    
+    if (dbconn->handle) {
+        sqlite3_close(dbconn->handle);
+    }
+    CFReleaseSafe(dbconn->db);
+}
+
+AUTH_TYPE_INSTANCE(authdb_connection,
+                   .init = NULL,
+                   .copy = NULL,
+                   .finalize = _authdb_connection_finalize,
+                   .equal = NULL,
+                   .hash = NULL,
+                   .copyFormattingDesc = NULL,
+                   .copyDebugDesc = NULL
+                   );
+
+static CFTypeID authdb_connection_get_type_id() {
+    static CFTypeID type_id = _kCFRuntimeNotATypeID;
+    static dispatch_once_t onceToken;
+    
+    dispatch_once(&onceToken, ^{
+        type_id = _CFRuntimeRegisterClass(&_auth_type_authdb_connection);
+    });
+    
+    return type_id;
+}
+
+authdb_connection_t
+authdb_connection_create(authdb_t db)
+{
+    authdb_connection_t dbconn = NULL;
+    
+    dbconn = (authdb_connection_t)_CFRuntimeCreateInstance(kCFAllocatorDefault, authdb_connection_get_type_id(), AUTH_CLASS_SIZE(authdb_connection), NULL);
+    require(dbconn != NULL, done);
+    
+    dbconn->db = (authdb_t)CFRetain(db);
+    dbconn->handle = _create_handle(dbconn->db);
+
+done:
+    return dbconn;
+}
diff --git a/authd/authdb.h b/authd/authdb.h
new file mode 100644 (file)
index 0000000..b1eb9ed
--- /dev/null
@@ -0,0 +1,72 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#ifndef _SECURITY_AUTH_AUTHDB_H_
+#define _SECURITY_AUTH_AUTHDB_H_
+
+#include <sqlite3.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+enum {
+    AuthDBTransactionNone = 0,
+    AuthDBTransactionImmediate,
+    AuthDBTransactionExclusive,
+    AuthDBTransactionNormal
+};
+typedef uint32_t AuthDBTransactionType;
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#pragma mark -
+#pragma mark authdb_t
+    
+typedef bool (^authdb_iterator_t)(auth_items_t data);
+    
+AUTH_WARN_RESULT AUTH_NONNULL_ALL
+char * authdb_copy_sql_string(sqlite3_stmt*,int32_t);
+
+AUTH_WARN_RESULT AUTH_MALLOC AUTH_RETURNS_RETAINED
+authdb_t authdb_create(void);
+
+AUTH_WARN_RESULT AUTH_NONNULL_ALL
+authdb_connection_t authdb_connection_acquire(authdb_t);
+
+AUTH_NONNULL_ALL
+void authdb_connection_release(authdb_connection_t*);
+    
+AUTH_NONNULL_ALL
+bool authdb_maintenance(authdb_connection_t);
+        
+AUTH_NONNULL_ALL
+int32_t authdb_exec(authdb_connection_t, const char *);
+
+AUTH_NONNULL_ALL    
+bool authdb_transaction(authdb_connection_t, AuthDBTransactionType, bool (^t)(void));
+    
+AUTH_NONNULL1 AUTH_NONNULL2 AUTH_NONNULL3
+bool authdb_step(authdb_connection_t, const char * sql, void (^bind_stmt)(sqlite3_stmt* stmt), authdb_iterator_t iter);
+
+AUTH_NONNULL_ALL    
+int32_t authdb_get_key_value(authdb_connection_t, const char * table, auth_items_t * out_items);
+
+AUTH_NONNULL_ALL    
+int32_t authdb_set_key_value(authdb_connection_t, const char * table, auth_items_t items);
+    
+AUTH_NONNULL_ALL
+void authdb_checkpoint(authdb_connection_t);
+
+AUTH_NONNULL_ALL
+bool authdb_import_plist(authdb_connection_t,CFDictionaryRef,bool);
+    
+#pragma mark -
+#pragma mark authdb_connection_t
+    
+AUTH_NONNULL_ALL
+authdb_connection_t authdb_connection_create(authdb_t);
+    
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_SECURITY_AUTH_AUTHDB_H_ */
diff --git a/authd/authitems.c b/authd/authitems.c
new file mode 100644 (file)
index 0000000..a55850b
--- /dev/null
@@ -0,0 +1,1168 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#include "authitems.h"
+#include "crc.h"
+#include "debugging.h"
+
+#include "authutilities.h"
+#include <Security/AuthorizationTags.h>
+
+typedef struct _auth_item_s * auth_item_t;
+
+#pragma mark -
+#pragma mark auth_item_t
+
+struct _auth_item_s {
+    __AUTH_BASE_STRUCT_HEADER__;
+       
+    AuthorizationItem data;
+    uint32_t type;
+    size_t bufLen;
+    
+    CFStringRef cfKey;
+};
+
+static const char *
+auth_item_get_string(auth_item_t item)
+{
+    if (item->bufLen <= item->data.valueLength) {
+        item->bufLen = item->data.valueLength+1; // make sure buffer has a null char
+        item->data.value = realloc(item->data.value, item->bufLen);
+        if (item->data.value == NULL) {
+            // this is added to prevent running off into random memory if a string buffer doesn't have a null char
+            LOGE("realloc failed");
+            abort();
+        }
+        ((uint8_t*)item->data.value)[item->bufLen-1] = '\0';
+    }
+    return item->data.value;
+}
+
+static CFStringRef
+auth_item_get_cf_key(auth_item_t item)
+{
+    if (!item->cfKey) {
+        item->cfKey = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, item->data.name, kCFStringEncodingUTF8, kCFAllocatorNull);
+    }
+    return item->cfKey;
+}
+
+static AuthorizationItem *
+auth_item_get_auth_item(auth_item_t item)
+{
+    return &item->data;
+}
+
+static xpc_object_t
+auth_item_copy_auth_item_xpc(auth_item_t item)
+{
+    xpc_object_t xpc_data = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_string(xpc_data, AUTH_XPC_ITEM_NAME, item->data.name);
+    if (item->data.value) {
+        xpc_dictionary_set_data(xpc_data, AUTH_XPC_ITEM_VALUE, item->data.value, item->data.valueLength);
+    }
+    xpc_dictionary_set_uint64(xpc_data, AUTH_XPC_ITEM_FLAGS, item->data.flags);
+    xpc_dictionary_set_uint64(xpc_data, AUTH_XPC_ITEM_TYPE, item->type);
+    return xpc_data;
+}
+
+static void
+_auth_item_finalize(CFTypeRef value)
+{
+    auth_item_t item = (auth_item_t)value;
+    
+    CFReleaseSafe(item->cfKey);
+    
+    if (item->data.name) {
+        free((void*)item->data.name);
+    }
+
+    if (item->data.value) {
+        memset(item->data.value, 0, item->data.valueLength);
+        free(item->data.value);
+    }
+}
+
+static Boolean
+_auth_item_equal(CFTypeRef value1, CFTypeRef value2)
+{
+    return (CFHash(value1) == CFHash(value2));
+}
+
+static CFStringRef
+_auth_item_copy_description(CFTypeRef value)
+{
+    bool hidden = false;
+    auth_item_t item = (auth_item_t)value;
+
+#ifndef DEBUG
+    static size_t passLen = strlen(kAuthorizationEnvironmentPassword);
+    if (strncasecmp(item->data.name, kAuthorizationEnvironmentPassword, passLen) == 0) {
+        hidden = true;
+    }
+#endif
+    
+    CFMutableStringRef desc = CFStringCreateMutable(kCFAllocatorDefault, 0);
+    CFStringAppendFormat(desc, NULL, CFSTR("auth_item: %s, type=%i, length=%li, flags=%x"),
+                        item->data.name, item->type,
+                        hidden ? 0 : item->data.valueLength, item->data.flags);
+    
+    switch (item->type) {
+        case AI_TYPE_STRING:
+            CFStringAppendFormat(desc, NULL, CFSTR(" value=%s"), hidden ? "(hidden)" : auth_item_get_string(item));
+            break;
+        case AI_TYPE_INT:
+            CFStringAppendFormat(desc, NULL, CFSTR(" value=%i"), *(int32_t*)item->data.value);
+            break;
+        case AI_TYPE_UINT:
+            CFStringAppendFormat(desc, NULL, CFSTR(" value=%u"), *(uint32_t*)item->data.value);
+            break;
+        case AI_TYPE_INT64:
+            CFStringAppendFormat(desc, NULL, CFSTR(" value=%lli"), *(int64_t*)item->data.value);
+            break;
+        case AI_TYPE_UINT64:
+            CFStringAppendFormat(desc, NULL, CFSTR(" value=%llu"), *(uint64_t*)item->data.value);
+            break;
+        case AI_TYPE_BOOL:
+            CFStringAppendFormat(desc, NULL, CFSTR(" value=%i"), *(bool*)item->data.value);
+            break;
+        case AI_TYPE_DOUBLE:
+            CFStringAppendFormat(desc, NULL, CFSTR(" value=%f"), *(double*)item->data.value);
+            break;
+        case AI_TYPE_DATA:
+        case AI_TYPE_UNKNOWN:
+            if (hidden) {
+                CFStringAppendFormat(desc, NULL, CFSTR(" value=(hidden)"));
+            } else {
+                CFStringAppendFormat(desc, NULL, CFSTR(" value=0x"));
+                size_t i = item->data.valueLength < 10 ? item->data.valueLength : 10;
+                uint8_t * data = item->data.value;
+                for (; i > 0; i--) {
+                    CFStringAppendFormat(desc, NULL, CFSTR("%02x"), data[i-1]);
+                }
+            }
+            break;
+        default:
+            break;
+    }
+    return desc;
+}
+
+static CFHashCode
+_auth_item_hash(CFTypeRef value)
+{
+    auth_item_t item = (auth_item_t)value;
+    uint64_t crc = crc64_init();
+    crc = crc64_update(crc, item->data.name, strlen(item->data.name));
+    if (item->data.value) {
+        crc = crc64_update(crc, item->data.value, item->data.valueLength);
+    }
+    crc = crc64_update(crc, &item->data.flags, sizeof(item->data.flags));
+
+    crc = crc64_final(crc);
+    return crc;
+}
+
+AUTH_TYPE_INSTANCE(auth_item,
+                   .init = NULL,
+                   .copy = NULL,
+                   .finalize = _auth_item_finalize,
+                   .equal = _auth_item_equal,
+                   .hash = _auth_item_hash,
+                   .copyFormattingDesc = NULL,
+                   .copyDebugDesc = _auth_item_copy_description
+                   );
+
+static CFTypeID auth_item_get_type_id() {
+    static CFTypeID type_id = _kCFRuntimeNotATypeID;
+    static dispatch_once_t onceToken;
+    
+    dispatch_once(&onceToken, ^{
+        type_id = _CFRuntimeRegisterClass(&_auth_type_auth_item);
+    });
+    
+    return type_id;
+}
+
+static auth_item_t
+_auth_item_create()
+{
+    auth_item_t item = NULL;
+    
+    item = (auth_item_t)_CFRuntimeCreateInstance(kCFAllocatorDefault, auth_item_get_type_id(), AUTH_CLASS_SIZE(auth_item), NULL);
+    require(item != NULL, done);
+    
+done:
+    return item;
+}
+
+static auth_item_t
+auth_item_create(uint32_t type, const char * name, const void * value, size_t valueLen, uint32_t flags)
+{
+    auth_item_t item = NULL;
+    require(name != NULL, done);
+    
+    item = _auth_item_create();
+    require(item != NULL, done);
+    
+    item->type = type;
+    item->data.flags = flags;
+    item->data.name = _copy_string(name);
+    item->data.valueLength = valueLen;
+    item->bufLen = valueLen;
+    if (value) {
+        if (item->type == AI_TYPE_STRING) {
+            item->bufLen++;
+            item->data.value = calloc(1u, item->bufLen);
+        } else if (valueLen) {
+            item->data.value = calloc(1u, item->bufLen);
+        }
+        if (valueLen) {
+            memcpy(item->data.value, value, valueLen);
+        }
+    }
+    
+done:
+    return item;
+}
+
+static auth_item_t
+auth_item_create_with_xpc(xpc_object_t data)
+{
+    auth_item_t item = NULL;
+    require(data != NULL, done);
+    require(xpc_get_type(data) == XPC_TYPE_DICTIONARY, done);
+    require(xpc_dictionary_get_string(data, AUTH_XPC_ITEM_NAME) != NULL, done);
+    
+    item = _auth_item_create();
+    require(item != NULL, done);
+    
+    item->data.name = _copy_string(xpc_dictionary_get_string(data, AUTH_XPC_ITEM_NAME));
+    item->data.flags = (uint32_t)xpc_dictionary_get_uint64(data, AUTH_XPC_ITEM_FLAGS);
+    item->type = (uint32_t)xpc_dictionary_get_uint64(data, AUTH_XPC_ITEM_TYPE);
+    
+    size_t len;
+    const void * value = xpc_dictionary_get_data(data, AUTH_XPC_ITEM_VALUE, &len);
+    if (value) {
+        item->bufLen = len;
+        item->data.valueLength = len;
+        item->data.value = calloc(1u, len);
+        memcpy(item->data.value, value, len);
+    }
+    
+done:
+    return item;
+}
+
+#pragma mark -
+#pragma mark auth_items_t
+
+struct _auth_items_s {
+    __AUTH_BASE_STRUCT_HEADER__;
+
+    CFMutableDictionaryRef dictionary;
+    AuthorizationItemSet set;
+};
+
+static void
+_auth_items_finalize(CFTypeRef value)
+{
+    auth_items_t items = (auth_items_t)value;
+
+    CFReleaseNull(items->dictionary);
+    free_safe(items->set.items)
+}
+
+static Boolean
+_auth_items_equal(CFTypeRef value1, CFTypeRef value2)
+{
+    auth_items_t items1 = (auth_items_t)value1;
+    auth_items_t items2 = (auth_items_t)value2;
+
+    return CFEqual(items1->dictionary, items2->dictionary);
+}
+
+static CFStringRef
+_auth_items_copy_description(CFTypeRef value)
+{
+    auth_items_t items = (auth_items_t)value;
+    return CFCopyDescription(items->dictionary);
+}
+
+AUTH_TYPE_INSTANCE(auth_items,
+                   .init = NULL,
+                   .copy = NULL,
+                   .finalize = _auth_items_finalize,
+                   .equal = _auth_items_equal,
+                   .hash = NULL,
+                   .copyFormattingDesc = NULL,
+                   .copyDebugDesc = _auth_items_copy_description
+                   );
+
+CFTypeID auth_items_get_type_id()
+{
+    static CFTypeID type_id = _kCFRuntimeNotATypeID;
+    static dispatch_once_t onceToken;
+    
+    dispatch_once(&onceToken, ^{
+        type_id = _CFRuntimeRegisterClass(&_auth_type_auth_items);
+    });
+    
+    return type_id;
+}
+
+static auth_items_t
+_auth_items_create(bool createDict)
+{
+    auth_items_t items = NULL;
+    
+    items = (auth_items_t)_CFRuntimeCreateInstance(kCFAllocatorDefault, auth_items_get_type_id(), AUTH_CLASS_SIZE(auth_items), NULL);
+    require(items != NULL, done);
+    
+    if (createDict) {
+        items->dictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    }
+    
+done:
+    return items;
+}
+
+auth_items_t
+auth_items_create()
+{
+    auth_items_t items = NULL;
+    
+    items = _auth_items_create(true);
+    require(items != NULL, done);
+    
+done:
+    return items;
+}
+
+static bool
+_auth_items_parse_xpc(auth_items_t items, const xpc_object_t data)
+{
+    bool result = false;
+    require(data != NULL, done);
+    require(xpc_get_type(data) == XPC_TYPE_ARRAY, done);
+    
+    result = xpc_array_apply(data, ^bool(size_t index AUTH_UNUSED, xpc_object_t value) {
+        
+        auth_item_t item = auth_item_create_with_xpc(value);
+        if (item) {
+            CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item);
+            CFReleaseSafe(item);
+        }
+        
+        return true;
+    });
+    
+done:
+    return result;
+}
+
+auth_items_t auth_items_create_with_xpc(const xpc_object_t data)
+{
+    auth_items_t items = NULL;
+
+    items = _auth_items_create(true);
+    require(items != NULL, done);
+    
+    _auth_items_parse_xpc(items, data);
+    
+done:
+    return items;
+}
+
+auth_items_t
+auth_items_create_copy(auth_items_t copy)
+{
+    auth_items_t items = NULL;
+    
+    items = _auth_items_create(false);
+    require(items != NULL, done);
+    
+    items->dictionary = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, CFDictionaryGetCount(copy->dictionary), copy->dictionary);
+    
+done:
+    return items;
+}
+
+size_t
+auth_items_get_count(auth_items_t items)
+{
+    return (size_t)CFDictionaryGetCount(items->dictionary);
+}
+
+AuthorizationItemSet *
+auth_items_get_item_set(auth_items_t items)
+{
+    uint32_t count = (uint32_t)CFDictionaryGetCount(items->dictionary);
+    if (count) {
+        size_t size = count * sizeof(AuthorizationItem);
+        if (items->set.items == NULL) {
+            items->set.items = calloc(1u, size);
+            require(items->set.items != NULL, done);
+        } else {
+            if (count > items->set.count) {
+                items->set.items = realloc(items->set.items, size);
+                require_action(items->set.items != NULL, done, items->set.count = 0);
+            }
+        }
+        items->set.count = count;
+        CFTypeRef keys[count], values[count];
+        CFDictionaryGetKeysAndValues(items->dictionary, keys, values);
+        for (CFIndex i = 0; i < count; i++) {
+            auth_item_t item = (auth_item_t)values[i];
+            items->set.items[i] = *auth_item_get_auth_item(item);
+        }
+    } else {
+        items->set.count = 0;
+    }
+    
+done:
+    return &items->set;
+}
+
+xpc_object_t
+auth_items_export_xpc(auth_items_t items)
+{
+    xpc_object_t array = xpc_array_create(NULL, 0);
+    
+    _cf_dictionary_iterate(items->dictionary, ^bool(CFTypeRef key AUTH_UNUSED, CFTypeRef value) {
+        auth_item_t item = (auth_item_t)value;
+        xpc_object_t xpc_data = auth_item_copy_auth_item_xpc(item);
+        xpc_array_append_value(array, xpc_data);
+        xpc_release_safe(xpc_data);
+        return true;
+    });
+    
+    return array;
+}
+
+static auth_item_t
+_find_item(auth_items_t items, const char * key)
+{
+    auth_item_t item = NULL;
+    CFStringRef lookup = NULL;
+    require(key != NULL, done);
+    
+    lookup = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, key, kCFStringEncodingUTF8, kCFAllocatorNull);
+    require(lookup != NULL, done);
+    
+    item = (auth_item_t)CFDictionaryGetValue(items->dictionary, lookup);
+    
+done:
+    CFReleaseSafe(lookup);
+    return item;
+}
+
+void
+auth_items_set_flags(auth_items_t items, const char *key, uint32_t flags)
+{
+    auth_item_t item = _find_item(items,key);
+    if (item) {
+        item->data.flags |= flags;
+    }
+}
+
+void
+auth_items_clear_flags(auth_items_t items, const char *key, uint32_t flags)
+{
+    auth_item_t item = _find_item(items,key);
+    if (item) {
+        item->data.flags &= ~flags;
+    }
+}
+
+uint32_t
+auth_items_get_flags(auth_items_t items, const char *key)
+{
+    auth_item_t item = _find_item(items,key);
+    if (item) {
+        return item->data.flags;
+    }
+    
+    return 0;
+}
+
+bool
+auth_items_check_flags(auth_items_t items, const char *key, uint32_t flags)
+{
+    uint32_t current = auth_items_get_flags(items,key);
+    return flags ? (current & flags) != 0 : current == 0;
+}
+
+void
+auth_items_set_key(auth_items_t items, const char *key)
+{
+    auth_item_t item = _find_item(items,key);
+    if (!item) {
+        item = auth_item_create(AI_TYPE_RIGHT, key, NULL, 0, 0);
+        if (item) {
+            CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item);
+            CFReleaseSafe(item);
+        }
+    }
+}
+
+bool
+auth_items_exist(auth_items_t items, const char *key)
+{
+    return _find_item(items,key) != NULL;
+}
+
+void
+auth_items_remove(auth_items_t items, const char *key)
+{
+    CFStringRef lookup = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, key, kCFStringEncodingUTF8, kCFAllocatorNull);
+    CFDictionaryRemoveValue(items->dictionary, lookup);
+    CFReleaseSafe(lookup);
+}
+
+void
+auth_items_remove_with_flags(auth_items_t items, uint32_t flags)
+{
+    auth_items_iterate(items, ^bool(const char *key) {
+        if (auth_items_check_flags(items, key, flags)) {
+            auth_items_remove(items,key);
+        }
+        return true;
+    });
+}
+
+void
+auth_items_clear(auth_items_t items)
+{
+    CFDictionaryRemoveAllValues(items->dictionary);
+}
+
+void
+auth_items_copy(auth_items_t items, auth_items_t src)
+{
+    auth_items_iterate(src, ^bool(const char *key) {
+        CFStringRef lookup = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, key, kCFStringEncodingUTF8, kCFAllocatorNull);
+        auth_item_t item = (auth_item_t)CFDictionaryGetValue(src->dictionary, lookup);
+        CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item);
+        CFReleaseSafe(lookup);
+        return true;
+    });
+}
+
+void
+auth_items_copy_xpc(auth_items_t items, const xpc_object_t src)
+{
+    _auth_items_parse_xpc(items,src);
+}
+
+void
+auth_items_copy_with_flags(auth_items_t items, auth_items_t src, uint32_t flags)
+{
+    auth_items_iterate(src, ^bool(const char *key) {
+        if (auth_items_check_flags(src, key, flags)) {
+            CFStringRef lookup = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, key, kCFStringEncodingUTF8, kCFAllocatorNull);
+            auth_item_t item = (auth_item_t)CFDictionaryGetValue(src->dictionary, lookup);
+            CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item);
+            CFReleaseSafe(lookup);
+        }
+        return true;
+    });
+}
+
+bool
+auth_items_iterate(auth_items_t items, auth_items_iterator_t iter)
+{
+    bool result = false;
+    CFTypeRef* keys = NULL;
+    CFTypeRef* values = NULL;
+
+    CFIndex count = CFDictionaryGetCount(items->dictionary);
+    keys = calloc((size_t)count, sizeof(CFTypeRef));
+    require(keys != NULL, done);
+    
+    values = calloc((size_t)count, sizeof(CFTypeRef));
+    require(values != NULL, done);
+    
+    CFDictionaryGetKeysAndValues(items->dictionary, keys, values);
+    for (CFIndex i = 0; i < count; i++) {
+        auth_item_t item = (auth_item_t)values[i];
+        result = iter(item->data.name);
+        if (!result) {
+            break;
+        }
+    }
+
+done:
+    free_safe(keys);
+    free_safe(values);
+    return result;
+}
+
+void
+auth_items_set_string(auth_items_t items, const char *key, const char *value)
+{
+    if (value) {
+        size_t valLen = strlen(value);
+        auth_item_t item = _find_item(items,key);
+        if (item && item->type == AI_TYPE_STRING && valLen < item->bufLen) {
+            memcpy(item->data.value, value, valLen+1); // copy null
+            item->data.valueLength = valLen;
+        } else {
+            item = auth_item_create(AI_TYPE_STRING, key, value, valLen, 0);
+            if (item) {
+                CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item);
+                CFReleaseSafe(item);
+            }
+        }
+    }
+}
+
+const char *
+auth_items_get_string(auth_items_t items, const char *key)
+{
+    auth_item_t item = _find_item(items,key);
+    if (item) {
+#if DEBUG
+        if (!(item->type == AI_TYPE_STRING || item->type == AI_TYPE_UNKNOWN)) {
+            LOGV("auth_items: key = %s, invalid type=%i expected=%i",
+                 item->data.name, item->type, AI_TYPE_STRING);
+        }
+#endif
+        return auth_item_get_string(item);
+    }
+
+    return NULL;
+}
+
+void
+auth_items_set_data(auth_items_t items, const char *key, const void *value, size_t len)
+{
+    if (value && len) {
+        auth_item_t item = _find_item(items,key);
+        if (item && item->type == AI_TYPE_DATA && len <= item->bufLen) {
+            memcpy(item->data.value, value, len);
+            item->data.valueLength = len;
+        } else {
+            item = auth_item_create(AI_TYPE_DATA, key, value, len, 0);
+            if (item) {
+                CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item);
+                CFReleaseSafe(item);
+            }
+        }
+    }
+}
+
+const void *
+auth_items_get_data(auth_items_t items, const char *key, size_t *len)
+{
+    auth_item_t item = _find_item(items,key);
+    if (item) {
+#if DEBUG
+        if (!(item->type == AI_TYPE_DATA || item->type == AI_TYPE_UNKNOWN)) {
+            LOGV("auth_items: key = %s, invalid type=%i expected=%i",
+                 item->data.name, item->type, AI_TYPE_DATA);
+        }
+#endif
+        if (len) {
+            *len = item->data.valueLength;
+        }
+        return item->data.value;
+    }
+    
+    return NULL;
+}
+
+void
+auth_items_set_bool(auth_items_t items, const char *key, bool value)
+{
+    auth_item_t item = _find_item(items,key);
+    if (item && item->type == AI_TYPE_BOOL) {
+        *(bool*)item->data.value = value;
+    } else {
+        item = auth_item_create(AI_TYPE_BOOL, key, &value, sizeof(bool), 0);
+        if (item) {
+            CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item);
+            CFReleaseSafe(item);
+        }
+    }
+}
+
+bool
+auth_items_get_bool(auth_items_t items, const char *key)
+{
+    auth_item_t item = _find_item(items,key);
+    if (item) {
+#if DEBUG
+        if (!(item->type == AI_TYPE_BOOL || item->type == AI_TYPE_UNKNOWN) || (item->data.valueLength != sizeof(bool))) {
+            LOGV("auth_items: key = %s, invalid type=%i expected=%i or size=%li expected=%li",
+                 item->data.name, item->type, AI_TYPE_BOOL, item->data.valueLength, sizeof(bool));
+        }
+#endif
+        if (item->type == AI_TYPE_STRING) {
+            return atoi(auth_item_get_string(item));
+        }
+        
+        require(item->data.value != NULL, done);
+        require(item->data.valueLength == sizeof(bool), done);
+        
+        return *(bool*)item->data.value;
+    } 
+
+done:
+    return false;
+}
+
+void
+auth_items_set_int(auth_items_t items, const char *key, int32_t value)
+{
+    auth_item_t item = _find_item(items,key);
+    if (item && item->type == AI_TYPE_INT) {
+        *(int32_t*)item->data.value = value;
+    } else {
+        item = auth_item_create(AI_TYPE_INT, key, &value, sizeof(int32_t), 0);
+        if (item) {
+            CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item);
+            CFReleaseSafe(item);
+        }
+    }
+}
+
+int32_t
+auth_items_get_int(auth_items_t items, const char *key)
+{
+    auth_item_t item = _find_item(items,key);
+    if (item) {
+#if DEBUG
+        if (!(item->type ==AI_TYPE_INT || item->type == AI_TYPE_UNKNOWN) || (item->data.valueLength != sizeof(int32_t))) {
+            LOGV("auth_items: key = %s, invalid type=%i expected=%i or size=%li expected=%li",
+                 item->data.name, item->type, AI_TYPE_INT, item->data.valueLength, sizeof(int32_t));
+        }
+#endif
+        if (item->type == AI_TYPE_STRING) {
+            return atoi(auth_item_get_string(item));
+        }
+        
+        require(item->data.value != NULL, done);
+        require(item->data.valueLength == sizeof(int32_t), done);
+        
+        return *(int32_t*)item->data.value;
+    }
+
+done:
+    return 0;
+}
+
+void
+auth_items_set_uint(auth_items_t items, const char *key, uint32_t value)
+{
+    auth_item_t item = _find_item(items,key);
+    if (item && item->type == AI_TYPE_UINT) {
+        *(uint32_t*)item->data.value = value;
+    } else {
+        item = auth_item_create(AI_TYPE_UINT, key, &value, sizeof(uint32_t), 0);
+        if (item) {
+            CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item);
+            CFReleaseSafe(item);
+        }
+    }
+}
+
+uint32_t
+auth_items_get_uint(auth_items_t items, const char *key)
+{
+    auth_item_t item = _find_item(items,key);
+    if (item) {
+#if DEBUG
+        if (!(item->type ==AI_TYPE_UINT || item->type == AI_TYPE_UNKNOWN) || (item->data.valueLength != sizeof(uint32_t))) {
+            LOGV("auth_items: key = %s, invalid type=%i expected=%i or size=%li expected=%li",
+                 item->data.name, item->type, AI_TYPE_UINT, item->data.valueLength, sizeof(uint32_t));
+        }
+#endif
+        if (item->type == AI_TYPE_STRING) {
+            return (uint32_t)atoi(auth_item_get_string(item));
+        }
+        
+        require(item->data.value != NULL, done);
+        require(item->data.valueLength == sizeof(uint32_t), done);
+        
+        return *(uint32_t*)item->data.value;
+    }
+    
+done:
+    return 0;
+}
+
+void
+auth_items_set_int64(auth_items_t items, const char *key, int64_t value)
+{
+    auth_item_t item = _find_item(items,key);
+    if (item && item->type == AI_TYPE_INT64) {
+        *(int64_t*)item->data.value = value;
+    } else {
+        item = auth_item_create(AI_TYPE_INT64, key, &value, sizeof(int64_t), 0);
+        if (item) {
+            CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item);
+            CFReleaseSafe(item);
+        }
+    }
+}
+
+int64_t
+auth_items_get_int64(auth_items_t items, const char *key)
+{
+    auth_item_t item = _find_item(items,key);
+    if (item) {
+#if DEBUG
+        if (!(item->type ==AI_TYPE_INT64 || item->type == AI_TYPE_UNKNOWN) || (item->data.valueLength != sizeof(int64_t))) {
+            LOGV("auth_items: key = %s, invalid type=%i expected=%i or size=%li expected=%li",
+                 item->data.name, item->type, AI_TYPE_INT64, item->data.valueLength, sizeof(int64_t));
+        }
+#endif
+        if (item->type == AI_TYPE_STRING) {
+            return atoll(auth_item_get_string(item));
+        }
+
+        require(item->data.value != NULL, done);
+        require(item->data.valueLength == sizeof(int64_t), done);
+        
+        return *(int64_t*)item->data.value;
+    }
+
+done:
+    return 0;
+}
+
+void
+auth_items_set_uint64(auth_items_t items, const char *key, uint64_t value)
+{
+    auth_item_t item = _find_item(items,key);
+    if (item && item->type == AI_TYPE_UINT64) {
+        *(uint64_t*)item->data.value = value;
+    } else {
+        item = auth_item_create(AI_TYPE_UINT64, key, &value, sizeof(uint64_t), 0);
+        if (item) {
+            CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item);
+            CFReleaseSafe(item);
+        }
+    }
+}
+
+uint64_t
+auth_items_get_uint64(auth_items_t items, const char *key)
+{
+    auth_item_t item = _find_item(items,key);
+    if (item) {
+#if DEBUG
+        if (!(item->type ==AI_TYPE_UINT64 || item->type == AI_TYPE_UNKNOWN) || (item->data.valueLength != sizeof(uint64_t))) {
+            LOGV("auth_items: key = %s, invalid type=%i expected=%i or size=%li expected=%li",
+                 item->data.name, item->type, AI_TYPE_UINT64, item->data.valueLength, sizeof(uint64_t));
+        }
+#endif
+        if (item->type == AI_TYPE_STRING) {
+            return (uint64_t)atoll(auth_item_get_string(item));
+        }
+        
+        require(item->data.value != NULL, done);
+        require(item->data.valueLength == sizeof(uint64_t), done);
+        
+        return *(uint64_t*)item->data.value;
+    }
+
+done:
+    return 0;
+}
+
+void auth_items_set_double(auth_items_t items, const char *key, double value)
+{
+    auth_item_t item = _find_item(items,key);
+    if (item && item->type == AI_TYPE_DOUBLE) {
+        *(double*)item->data.value = value;
+    } else {
+        item = auth_item_create(AI_TYPE_DOUBLE, key, &value, sizeof(double), 0);
+        if (item) {
+            CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item);
+            CFReleaseSafe(item);
+        }
+    }
+}
+
+double auth_items_get_double(auth_items_t items, const char *key)
+{
+    auth_item_t item = _find_item(items,key);
+    if (item) {
+#if DEBUG
+        if (!(item->type ==AI_TYPE_DOUBLE || item->type == AI_TYPE_UNKNOWN) || (item->data.valueLength != sizeof(double))) {
+            LOGV("auth_items: key = %s, invalid type=%i expected=%i or size=%li expected=%li",
+                 item->data.name, item->type, AI_TYPE_DOUBLE, item->data.valueLength, sizeof(double));
+        }
+#endif
+        if (item->type == AI_TYPE_STRING) {
+            return atof(auth_item_get_string(item));
+        }
+        
+        require(item->data.value != NULL, done);
+        require(item->data.valueLength == sizeof(double), done);
+        
+        return *(double*)item->data.value;
+    }
+    
+done:
+    return 0;
+}
+
+uint32_t auth_items_get_type(auth_items_t items, const char *key)
+{
+    auth_item_t item = _find_item(items,key);
+    if (item) {
+        return item->type;
+    }
+
+    return AI_TYPE_UNKNOWN;
+}
+
+size_t auth_items_get_length(auth_items_t items, const char *key)
+{
+    auth_item_t item = _find_item(items,key);
+    if (item) {
+        return item->data.valueLength;
+    }
+    
+    return 0;
+}
+
+void auth_items_set_value(auth_items_t items, const char *key, uint32_t type, uint32_t flags, const void *value, size_t len)
+{
+    auth_item_t item = auth_item_create(type, key, value, len, flags);
+    if (item) {
+        CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item);
+        CFReleaseSafe(item);
+    }
+}
+
+#pragma mark -
+#pragma mark auth_rights_t
+
+struct _auth_rights_s {
+    __AUTH_BASE_STRUCT_HEADER__;
+    
+    CFMutableArrayRef array;
+};
+
+static void
+_auth_rights_finalize(CFTypeRef value)
+{
+    auth_rights_t rights = (auth_rights_t)value;
+    
+    CFReleaseNull(rights->array);
+}
+
+static Boolean
+_auth_rights_equal(CFTypeRef value1, CFTypeRef value2)
+{
+    auth_rights_t rights1 = (auth_rights_t)value1;
+    auth_rights_t rights2 = (auth_rights_t)value2;
+    
+    return CFEqual(rights1->array, rights2->array);
+}
+
+static CFStringRef
+_auth_rights_copy_description(CFTypeRef value)
+{
+    auth_rights_t rights = (auth_rights_t)value;
+    return CFCopyDescription(rights->array);
+}
+
+AUTH_TYPE_INSTANCE(auth_rights,
+                   .init = NULL,
+                   .copy = NULL,
+                   .finalize = _auth_rights_finalize,
+                   .equal = _auth_rights_equal,
+                   .hash = NULL,
+                   .copyFormattingDesc = NULL,
+                   .copyDebugDesc = _auth_rights_copy_description
+                   );
+
+static CFTypeID auth_rights_get_type_id()
+{
+    static CFTypeID type_id = _kCFRuntimeNotATypeID;
+    static dispatch_once_t onceToken;
+    
+    dispatch_once(&onceToken, ^{
+        type_id = _CFRuntimeRegisterClass(&_auth_type_auth_rights);
+    });
+    
+    return type_id;
+}
+
+static auth_rights_t
+_auth_rights_create()
+{
+    auth_rights_t rights = NULL;
+    
+    rights = (auth_rights_t)_CFRuntimeCreateInstance(kCFAllocatorDefault, auth_rights_get_type_id(), AUTH_CLASS_SIZE(auth_rights), NULL);
+    require(rights != NULL, done);
+    
+    rights->array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+    
+done:
+    return rights;
+}
+
+auth_rights_t
+auth_rights_create()
+{
+    auth_rights_t rights = _auth_rights_create();
+    require(rights != NULL, done);
+    
+done:
+    return rights;
+}
+
+auth_rights_t auth_rights_create_with_xpc(const xpc_object_t data)
+{
+    auth_rights_t rights = _auth_rights_create();
+    require(rights != NULL, done);
+    require(data != NULL, done);
+    require(xpc_get_type(data) == XPC_TYPE_ARRAY, done);
+    
+    xpc_array_apply(data, ^bool(size_t index AUTH_UNUSED, xpc_object_t value) {
+        
+        auth_item_t item = auth_item_create_with_xpc(value);
+        if (item) {
+            CFArrayAppendValue(rights->array, item);
+            CFReleaseSafe(item);
+        }
+        
+        return true;
+    });
+    
+done:
+    return rights;
+}
+
+xpc_object_t auth_rights_export_xpc(auth_rights_t rights)
+{
+    xpc_object_t array = xpc_array_create(NULL, 0);
+    
+    CFIndex count = CFArrayGetCount(rights->array);
+    for (CFIndex i = 0; i < count; i++) {
+        auth_item_t item = (auth_item_t)CFArrayGetValueAtIndex(rights->array, i);
+        xpc_object_t xpc_data = auth_item_copy_auth_item_xpc(item);
+        xpc_array_append_value(array, xpc_data);
+        xpc_release_safe(xpc_data);
+    }
+    
+    return array;
+}
+
+static auth_item_t
+_find_right_item(auth_rights_t rights, const char * key)
+{
+    auth_item_t item = NULL;
+    CFStringRef lookup = NULL;
+    require(key != NULL, done);
+    
+    lookup = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, key, kCFStringEncodingUTF8, kCFAllocatorNull);
+    require(lookup != NULL, done);
+    
+    CFIndex count = CFArrayGetCount(rights->array);
+    for (CFIndex i = 0; i < count; i++) {
+        auth_item_t tmp = (auth_item_t)CFArrayGetValueAtIndex(rights->array, i);
+        if (tmp && CFEqual(auth_item_get_cf_key(tmp), lookup)) {
+            item = tmp;
+            break;
+        }
+    }
+    
+done:
+    CFReleaseSafe(lookup);
+    return item;
+}
+
+void auth_rights_set_flags(auth_rights_t rights, const char *key, uint32_t flags)
+{
+    auth_item_t item = _find_right_item(rights,key);
+    if (item) {
+        item->data.flags |= flags;
+    }
+}
+
+void auth_rights_clear_flags(auth_rights_t rights, const char *key, uint32_t flags)
+{
+    auth_item_t item = _find_right_item(rights,key);
+    if (item) {
+        item->data.flags &= ~flags;
+    }
+}
+
+uint32_t auth_rights_get_flags(auth_rights_t rights, const char *key)
+{
+    auth_item_t item = _find_right_item(rights,key);
+    if (item) {
+        return item->data.flags;
+    }
+    
+    return 0;
+}
+
+bool auth_rights_check_flags(auth_rights_t rights, const char *key, uint32_t flags)
+{
+    uint32_t current = auth_rights_get_flags(rights,key);
+    return flags ? (current & flags) != 0 : current == 0;
+}
+
+size_t auth_rights_get_count(auth_rights_t rights)
+{
+    return (size_t)CFArrayGetCount(rights->array);
+}
+
+void auth_rights_add(auth_rights_t rights, const char *key)
+{
+    auth_item_t item = auth_item_create(AI_TYPE_RIGHT, key, NULL, 0, 0);
+    if (item) {
+        CFArrayAppendValue(rights->array, item);
+        CFReleaseSafe(item);
+    }
+}
+
+bool auth_rights_exist(auth_rights_t rights, const char *key)
+{
+    return (_find_right_item(rights,key) != NULL);
+}
+
+void auth_rights_remove(auth_rights_t rights, const char *key)
+{
+    CFStringRef lookup = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, key, kCFStringEncodingUTF8, kCFAllocatorNull);
+    CFIndex count = CFArrayGetCount(rights->array);
+    for (CFIndex i = 0; i < count; i++) {
+        auth_item_t item = (auth_item_t)CFArrayGetValueAtIndex(rights->array, i);
+        if (CFEqual(auth_item_get_cf_key(item), lookup)) {
+            CFArrayRemoveValueAtIndex(rights->array, i);
+            i--;
+            count--;
+        }
+    }
+    CFReleaseSafe(lookup);
+}
+
+void auth_rights_clear(auth_rights_t rights)
+{
+    CFArrayRemoveAllValues(rights->array);
+}
+
+bool
+auth_rights_iterate(auth_rights_t rights, bool(^iter)(const char * key))
+{
+    bool result = false;
+    
+    CFIndex count = CFArrayGetCount(rights->array);
+    for (CFIndex i = 0; i < count; i++) {
+        auth_item_t item = (auth_item_t)CFArrayGetValueAtIndex(rights->array, i);
+        result = iter(item->data.name);
+        if (!result) {
+            break;
+        }
+    }
+    
+    return result;
+}
diff --git a/authd/authitems.h b/authd/authitems.h
new file mode 100644 (file)
index 0000000..c8bebc5
--- /dev/null
@@ -0,0 +1,199 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#ifndef _SECURITY_AUTH_ITEMS_H_
+#define _SECURITY_AUTH_ITEMS_H_
+
+#include <Security/Authorization.h>
+#include <xpc/xpc.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+enum {
+    AI_TYPE_UNKNOWN = 0,
+    AI_TYPE_RIGHT,
+    AI_TYPE_STRING,
+    AI_TYPE_INT,
+    AI_TYPE_UINT,
+    AI_TYPE_INT64,
+    AI_TYPE_UINT64,
+    AI_TYPE_DOUBLE,
+    AI_TYPE_BOOL,
+    AI_TYPE_DATA
+};
+
+#pragma mark -
+#pragma mark auth_items_t
+    
+/* unordered items */
+    
+#ifdef __BLOCKS__
+typedef bool (^auth_items_iterator_t)(const char *key);
+#endif /* __BLOCKS__ */
+
+CFTypeID auth_items_get_type_id(void);
+    
+AUTH_WARN_RESULT AUTH_MALLOC AUTH_RETURNS_RETAINED
+auth_items_t auth_items_create(void);
+    
+AUTH_WARN_RESULT AUTH_MALLOC AUTH_NONNULL_ALL AUTH_RETURNS_RETAINED
+auth_items_t auth_items_create_with_xpc(const xpc_object_t data);
+    
+AUTH_WARN_RESULT AUTH_MALLOC AUTH_NONNULL_ALL AUTH_RETURNS_RETAINED
+auth_items_t auth_items_create_copy(auth_items_t);
+
+AUTH_WARN_RESULT AUTH_NONNULL_ALL
+size_t auth_items_get_count(auth_items_t);
+
+AUTH_WARN_RESULT AUTH_NONNULL_ALL
+AuthorizationItemSet * auth_items_get_item_set(auth_items_t);
+
+AUTH_WARN_RESULT AUTH_NONNULL_ALL
+xpc_object_t auth_items_export_xpc(auth_items_t);
+
+AUTH_NONNULL_ALL
+void auth_items_set_flags(auth_items_t, const char *key, uint32_t flags);
+
+AUTH_NONNULL_ALL
+void auth_items_clear_flags(auth_items_t, const char *key, uint32_t flags);
+    
+AUTH_WARN_RESULT AUTH_NONNULL_ALL
+uint32_t auth_items_get_flags(auth_items_t, const char *key);
+
+AUTH_NONNULL_ALL
+bool auth_items_check_flags(auth_items_t, const char *key, uint32_t flags);
+
+AUTH_NONNULL_ALL
+void auth_items_set_key(auth_items_t, const char *key);
+    
+AUTH_NONNULL_ALL
+bool auth_items_exist(auth_items_t, const char *key);
+
+AUTH_NONNULL_ALL
+void auth_items_remove(auth_items_t, const char *key);
+
+AUTH_NONNULL_ALL
+void auth_items_remove_with_flags(auth_items_t, uint32_t flags);
+    
+AUTH_NONNULL_ALL
+void auth_items_clear(auth_items_t);
+
+AUTH_NONNULL_ALL
+void auth_items_copy(auth_items_t, auth_items_t src);
+    
+AUTH_NONNULL_ALL
+void auth_items_copy_xpc(auth_items_t, const xpc_object_t src);
+
+AUTH_NONNULL_ALL    
+void auth_items_copy_with_flags(auth_items_t, auth_items_t src, uint32_t flags);
+    
+AUTH_NONNULL_ALL    
+bool auth_items_iterate(auth_items_t, auth_items_iterator_t iter);
+    
+AUTH_NONNULL_ALL
+void auth_items_set_string(auth_items_t, const char *key, const char *value);
+
+AUTH_WARN_RESULT AUTH_NONNULL_ALL
+const char * auth_items_get_string(auth_items_t, const char *key);
+    
+AUTH_NONNULL_ALL
+void auth_items_set_data(auth_items_t, const char *key, const void *value, size_t len);
+
+AUTH_WARN_RESULT AUTH_NONNULL_ALL
+const void * auth_items_get_data(auth_items_t, const char *key, size_t * len);
+    
+AUTH_NONNULL_ALL
+void auth_items_set_bool(auth_items_t, const char *key, bool value);
+
+AUTH_WARN_RESULT AUTH_NONNULL_ALL
+bool auth_items_get_bool(auth_items_t, const char *key);
+    
+AUTH_NONNULL_ALL
+void auth_items_set_int(auth_items_t, const char *key, int32_t value);
+
+AUTH_WARN_RESULT AUTH_NONNULL_ALL
+int32_t auth_items_get_int(auth_items_t, const char *key);
+
+AUTH_NONNULL_ALL
+void auth_items_set_uint(auth_items_t, const char *key, uint32_t value);
+
+AUTH_WARN_RESULT AUTH_NONNULL_ALL
+uint32_t auth_items_get_uint(auth_items_t, const char *key);
+    
+AUTH_NONNULL_ALL
+void auth_items_set_int64(auth_items_t, const char *key, int64_t value);
+
+AUTH_WARN_RESULT AUTH_NONNULL_ALL
+int64_t auth_items_get_int64(auth_items_t, const char *key);
+
+AUTH_NONNULL_ALL
+void auth_items_set_uint64(auth_items_t, const char *key, uint64_t value);
+
+AUTH_WARN_RESULT AUTH_NONNULL_ALL    
+uint64_t auth_items_get_uint64(auth_items_t, const char *key);
+
+AUTH_NONNULL_ALL
+void auth_items_set_double(auth_items_t, const char *key, double value);
+
+AUTH_WARN_RESULT AUTH_NONNULL_ALL
+double auth_items_get_double(auth_items_t, const char *key);
+    
+AUTH_WARN_RESULT AUTH_NONNULL_ALL
+uint32_t auth_items_get_type(auth_items_t, const char *key);
+
+AUTH_WARN_RESULT AUTH_NONNULL_ALL
+size_t auth_items_get_length(auth_items_t, const char *key);
+
+AUTH_NONNULL_ALL
+void auth_items_set_value(auth_items_t, const char *key, uint32_t type, uint32_t flags, const void *value, size_t len);
+
+#pragma mark -
+#pragma mark auth_rights_t
+    
+/* ordered items */
+    
+AUTH_WARN_RESULT AUTH_MALLOC AUTH_RETURNS_RETAINED
+auth_rights_t auth_rights_create(void);
+
+AUTH_WARN_RESULT AUTH_MALLOC AUTH_NONNULL_ALL AUTH_RETURNS_RETAINED
+auth_rights_t auth_rights_create_with_xpc(const xpc_object_t data);
+
+AUTH_WARN_RESULT AUTH_NONNULL_ALL
+xpc_object_t auth_rights_export_xpc(auth_rights_t);
+
+AUTH_NONNULL_ALL
+void auth_rights_set_flags(auth_rights_t, const char *key, uint32_t flags);
+
+AUTH_NONNULL_ALL
+void auth_rights_clear_flags(auth_rights_t, const char *key, uint32_t flags);
+
+AUTH_WARN_RESULT AUTH_NONNULL_ALL
+uint32_t auth_rights_get_flags(auth_rights_t, const char *key);
+
+AUTH_NONNULL_ALL
+bool auth_rights_check_flags(auth_rights_t, const char *key, uint32_t flags);
+    
+AUTH_WARN_RESULT AUTH_NONNULL_ALL
+size_t auth_rights_get_count(auth_rights_t);
+
+AUTH_NONNULL_ALL
+void auth_rights_add(auth_rights_t, const char *key);
+
+AUTH_NONNULL_ALL
+bool auth_rights_exist(auth_rights_t, const char *key);
+
+AUTH_NONNULL_ALL
+void auth_rights_remove(auth_rights_t, const char *key);
+
+AUTH_NONNULL_ALL
+void auth_rights_clear(auth_rights_t);
+
+AUTH_NONNULL_ALL
+bool auth_rights_iterate(auth_rights_t rights, bool(^iter)(const char * key));
+    
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_SECURITY_AUTH_ITEMS_H_ */
diff --git a/authd/authorization.plist b/authd/authorization.plist
new file mode 100644 (file)
index 0000000..1ad51c9
--- /dev/null
@@ -0,0 +1,1731 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>comment</key>
+       <string>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.
+
+allow rule: this is always allowed
+&lt;key&gt;com.apple.TestApp.benign&lt;/key&gt;
+&lt;string&gt;allow&lt;/string&gt;
+
+deny rule: this is always denied
+&lt;key&gt;com.apple.TestApp.dangerous&lt;/key&gt;
+&lt;string&gt;deny&lt;/string&gt;
+
+user 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 (i.e., those in the 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.
+</string>
+       <key>rights</key>
+       <dict>
+               <key></key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>comment</key>
+                       <string>Matches otherwise unmatched rights (i.e., is a default).</string>
+                       <key>rule</key>
+                       <string>default</string>
+               </dict>
+               <key>com.apple.</key>
+               <dict>
+                       <key>rule</key>
+                       <string>default</string>
+               </dict>
+               <key>com.apple.AOSNotification.FindMyMac.modify</key>
+               <dict>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>k-of-n</key>
+                       <integer>1</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>is-root</string>
+                               <string>is-admin</string>
+                               <string>default</string>
+                       </array>
+               </dict>
+               <key>com.apple.AOSNotification.FindMyMac.remove</key>
+               <dict>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>group</key>
+                       <string>admin</string>
+               </dict>
+               <key>com.apple.DiskManagement.</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>comment</key>
+                       <string>Used by diskmanagementd to allow access to its privileged functions</string>
+                       <key>k-of-n</key>
+                       <integer>1</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>is-root</string>
+                               <string>is-admin</string>
+                               <string>on-console</string>
+                               <string>default</string>
+                       </array>
+               </dict>
+               <key>com.apple.DiskManagement.internal.</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>comment</key>
+                       <string>Used by diskmanagementd to allow access to its privileged functions</string>
+                       <key>k-of-n</key>
+                       <integer>1</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>is-root</string>
+                               <string>is-admin</string>
+                               <string>default</string>
+                       </array>
+               </dict>
+               <key>com.apple.DiskManagement.reserveKEK</key>
+               <dict>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Used by diskmanagementd to allow use of the reserve KEK.</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <false/>
+               </dict>
+               <key>com.apple.KerberosAgent</key>
+               <dict>
+                       <key>class</key>
+                       <string>evaluate-mechanisms</string>
+                       <key>comment</key>
+                       <string>Used to acquire Kerberos credentials.</string>
+                       <key>mechanisms</key>
+                       <array>
+                               <string>KerberosAgent:kerberos-dialog</string>
+                               <string>KerberosAgent:kerberos-authenticate,privileged</string>
+                       </array>
+               </dict>
+               <key>com.apple.OpenScripting.additions.send</key>
+               <dict>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Used to send restricted scripting addition commands to processes that require authorization to handle the events.</string>
+                       <key>group</key>
+                       <string>admin</string>
+               </dict>
+               <key>com.apple.ReportPanic.fixRight</key>
+               <dict>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>authenticate-user</key>
+                       <true/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>require-apple-signed</key>
+                       <true/>
+                       <key>shared</key>
+                       <false/>
+                       <key>timeout</key>
+                       <integer>10</integer>
+               </dict>
+               <key>com.apple.Safari.parental-controls</key>
+               <dict>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>comment</key>
+                       <string>Checked when changing parental controls for Safari.</string>
+                       <key>k-of-n</key>
+                       <integer>1</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>is-admin</string>
+                               <string>authenticate-admin</string>
+                       </array>
+                       <key>shared</key>
+                       <false/>
+                       <key>timeout</key>
+                       <integer>60</integer>
+               </dict>
+               <key>com.apple.Safari.show-credit-card-numbers</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>This right is used by Safari to show credit card numbers.</string>
+                       <key>session-owner</key>
+                       <true/>
+                       <key>shared</key>
+                       <false/>
+                       <key>timeout</key>
+                       <integer>10</integer>
+               </dict>
+               <key>com.apple.Safari.show-passwords</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>This right is used by Safari to show passwords </string>
+                       <key>session-owner</key>
+                       <true/>
+                       <key>shared</key>
+                       <false/>
+                       <key>timeout</key>
+                       <integer>10</integer>
+               </dict>
+               <key>com.apple.ServiceManagement.blesshelper</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>comment</key>
+                       <string>Used by the ServiceManagement framework to add a privileged helper tool to the system launchd.</string>
+                       <key>k-of-n</key>
+                       <integer>1</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>is-root</string>
+                               <string>authenticate-admin-30</string>
+                       </array>
+               </dict>
+               <key>com.apple.ServiceManagement.daemons.modify</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>comment</key>
+                       <string>Used by the ServiceManagement framework to make changes to the system launchd's set of daemons.</string>
+                       <key>k-of-n</key>
+                       <integer>1</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>is-root</string>
+                               <string>entitled-admin-or-authenticate-admin</string>
+                       </array>
+               </dict>
+               <key>com.apple.SoftwareUpdate.modify-settings</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>comment</key>
+                       <string>Checked by the Admin framework when making changes to the Software Update preference pane.</string>
+                       <key>rule</key>
+                       <string>root-or-entitled-admin-or-app-specific-admin</string>
+               </dict>
+               <key>com.apple.SoftwareUpdate.scan</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>comment</key>
+                       <string>Checked when user is updating software.</string>
+                       <key>rule</key>
+                       <string>root-or-entitled-admin-or-authenticate-admin</string>
+               </dict>
+               <key>com.apple.XType.fontmover.install</key>
+               <dict>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <true/>
+                       <key>timeout</key>
+                       <integer>300</integer>
+               </dict>
+               <key>com.apple.XType.fontmover.remove</key>
+               <dict>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <true/>
+                       <key>timeout</key>
+                       <integer>300</integer>
+               </dict>
+               <key>com.apple.XType.fontmover.restore</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>rule</key>
+                       <string>root-or-entitled-admin-or-authenticate-admin</string>
+               </dict>
+               <key>com.apple.ZFSManager.</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>comment</key>
+                       <string>Used by zfsmanager to allow access to destructive zfs functions</string>
+                       <key>k-of-n</key>
+                       <integer>1</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>is-root</string>
+                               <string>is-admin</string>
+                               <string>default</string>
+                       </array>
+                       <key>shared</key>
+                       <true/>
+               </dict>
+               <key>com.apple.activitymonitor.kill</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>comment</key>
+                       <string>Used by Activity Monitor to authorize killing processes not owned by the user.</string>
+                       <key>rule</key>
+                       <string>entitled-admin-or-authenticate-admin</string>
+                       <key>shared</key>
+                       <false/>
+                       <key>timeout</key>
+                       <integer>0</integer>
+               </dict>
+               <key>com.apple.appserver.privilege.admin</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>comment</key>
+                       <string>For administrative access to the Application Server management tool.</string>
+                       <key>rule</key>
+                       <string>appserver-admin</string>
+               </dict>
+               <key>com.apple.appserver.privilege.user</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>comment</key>
+                       <string>For user access to the Application Server management tool.</string>
+                       <key>k-of-n</key>
+                       <integer>1</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>appserver-admin</string>
+                               <string>appserver-user</string>
+                       </array>
+               </dict>
+               <key>com.apple.builtin.confirm-access</key>
+               <dict>
+                       <key>class</key>
+                       <string>evaluate-mechanisms</string>
+                       <key>mechanisms</key>
+                       <array>
+                               <string>builtin:confirm-access</string>
+                       </array>
+                       <key>tries</key>
+                       <integer>1</integer>
+               </dict>
+               <key>com.apple.builtin.confirm-access-password</key>
+               <dict>
+                       <key>class</key>
+                       <string>evaluate-mechanisms</string>
+                       <key>mechanisms</key>
+                       <array>
+                               <string>builtin:confirm-access-password</string>
+                       </array>
+               </dict>
+               <key>com.apple.builtin.generic-new-passphrase</key>
+               <dict>
+                       <key>class</key>
+                       <string>evaluate-mechanisms</string>
+                       <key>mechanisms</key>
+                       <array>
+                               <string>builtin:generic-new-passphrase</string>
+                       </array>
+               </dict>
+               <key>com.apple.builtin.generic-unlock</key>
+               <dict>
+                       <key>class</key>
+                       <string>evaluate-mechanisms</string>
+                       <key>mechanisms</key>
+                       <array>
+                               <string>builtin:generic-unlock</string>
+                       </array>
+               </dict>
+               <key>com.apple.container-repair</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <false/>
+                       <key>timeout</key>
+                       <integer>30</integer>
+               </dict>
+               <key>com.apple.dashboard.advisory.allow</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <false/>
+                       <key>timeout</key>
+                       <integer>300</integer>
+               </dict>
+               <key>com.apple.desktopservices</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>For privileged file operations from within the Finder.</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <false/>
+                       <key>timeout</key>
+                       <integer>0</integer>
+               </dict>
+               <key>com.apple.desktopservices.scripted</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>For scripting-initiated privileged file operations from within the Finder.</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <false/>
+                       <key>timeout</key>
+                       <integer>0</integer>
+               </dict>
+               <key>com.apple.docset.install</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Used by Xcode to restrict access to a daemon it uses to install and update documentation sets.</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <false/>
+               </dict>
+               <key>com.apple.iBooksX.ParentalControl</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Checked when making changes to the Parental Controls for iBooks.</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <false/>
+               </dict>
+               <key>com.apple.library-repair</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>group</key>
+                       <string>admin</string>
+               </dict>
+               <key>com.apple.lldb.LaunchUsingXPC</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>group</key>
+                       <string>admin</string>
+               </dict>
+               <key>com.apple.opendirectoryd.linkidentity</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>rule</key>
+                       <string>entitled-session-owner-or-authenticate-session-owner</string>
+               </dict>
+               <key>com.apple.pf.rule</key>
+               <dict>
+                       <key>authenticate-user</key>
+                       <true/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>timeout</key>
+                       <integer>0</integer>
+               </dict>
+               <key>com.apple.security.assessment.update</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>rule</key>
+                       <string>root-or-entitled-admin-or-authenticate-admin</string>
+               </dict>
+               <key>com.apple.server.admin.streaming</key>
+               <dict>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>comment</key>
+                       <string>For making administrative requests to the QuickTime Streaming Server.</string>
+                       <key>k-of-n</key>
+                       <integer>1</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>is-admin</string>
+                               <string>authenticate-admin</string>
+                       </array>
+                       <key>shared</key>
+                       <false/>
+                       <key>timeout</key>
+                       <integer>0</integer>
+               </dict>
+               <key>com.apple.trust-settings.admin</key>
+               <dict>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>For modifying Trust Settings in the Local Admin domain.</string>
+                       <key>group</key>
+                       <string>admin</string>
+               </dict>
+               <key>com.apple.trust-settings.user</key>
+               <dict>
+                       <key>comment</key>
+                       <string>For modifying per-user Trust Settings.</string>
+                       <key>rule</key>
+                       <string>entitled-session-owner-or-authenticate-session-owner</string>
+               </dict>
+               <key>com.apple.uninstalld.uninstall</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>rule</key>
+                       <string>entitled-admin-or-authenticate-admin</string>
+               </dict>
+               <key>config.add.</key>
+               <dict>
+                       <key>class</key>
+                       <string>allow</string>
+                       <key>comment</key>
+                       <string>Wildcard right for adding rights.  Anyone is allowed to add any (non-wildcard) rights.</string>
+               </dict>
+               <key>config.config.</key>
+               <dict>
+                       <key>class</key>
+                       <string>deny</string>
+                       <key>comment</key>
+                       <string>Wildcard right for any change to meta-rights for db modification.  Not allowed programmatically (just edit this file).</string>
+               </dict>
+               <key>config.modify.</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>comment</key>
+                       <string>Wildcard right for modifying rights.  Admins are allowed to modify any (non-wildcard) rights.  Root does not require authentication.</string>
+                       <key>k-of-n</key>
+                       <integer>1</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>is-root</string>
+                               <string>authenticate-admin</string>
+                       </array>
+               </dict>
+               <key>config.remove.</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>comment</key>
+                       <string>Wildcard right for deleting rights.  Admins are allowed to delete any (non-wildcard) rights.  Root does not require authentication.</string>
+                       <key>k-of-n</key>
+                       <integer>1</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>is-root</string>
+                               <string>authenticate-admin</string>
+                       </array>
+               </dict>
+               <key>config.remove.system.</key>
+               <dict>
+                       <key>class</key>
+                       <string>deny</string>
+                       <key>comment</key>
+                       <string>Wildcard right for deleting system rights.</string>
+               </dict>
+               <key>sys.openfile.</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>See authopen(1) for information on the use of this right.</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <false/>
+                       <key>timeout</key>
+                       <integer>300</integer>
+               </dict>
+               <key>system.</key>
+               <dict>
+                       <key>rule</key>
+                       <string>default</string>
+               </dict>
+               <key>system.burn</key>
+               <dict>
+                       <key>class</key>
+                       <string>allow</string>
+                       <key>comment</key>
+                       <string>For burning media.</string>
+               </dict>
+               <key>system.csfde.requestpassword</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Used by CoreStorage Full Disk Encryption to request the user's password.</string>
+                       <key>extract-password</key>
+                       <true/>
+                       <key>group</key>
+                       <string>staff</string>
+                       <key>shared</key>
+                       <false/>
+                       <key>timeout</key>
+                       <integer>0</integer>
+               </dict>
+               <key>system.device.dvd.setregion.initial</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Used by the DVD player to set the region code the first time.  Note that changing the region code after it has been set requires a different right (system.device.dvd.setregion.change).</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <true/>
+               </dict>
+               <key>system.disk.unlock</key>
+               <dict>
+                       <key>class</key>
+                       <string>evaluate-mechanisms</string>
+                       <key>comment</key>
+                       <string>Do not modify.</string>
+                       <key>mechanisms</key>
+                       <array>
+                               <string>DiskUnlock:prompt</string>
+                               <string>DiskUnlock:unlock,privileged</string>
+                       </array>
+               </dict>
+               <key>system.global-login-items.</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>k-of-n</key>
+                       <integer>1</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>default</string>
+                       </array>
+                       <key>version</key>
+                       <integer>1</integer>
+               </dict>
+               <key>system.hdd.smart</key>
+               <dict>
+                       <key>class</key>
+                       <string>allow</string>
+                       <key>comment</key>
+                       <string>For modifying SMART settings.</string>
+               </dict>
+               <key>system.identity.write.</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>comment</key>
+                       <string>For creating, changing or deleting local user accounts and groups.</string>
+                       <key>k-of-n</key>
+                       <integer>1</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>is-admin</string>
+                               <string>authenticate-admin</string>
+                       </array>
+               </dict>
+               <key>system.identity.write.credential</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>comment</key>
+                       <string>Checked when changing authentication credentials (password or certificate) for a local user account.</string>
+                       <key>rule</key>
+                       <string>default</string>
+               </dict>
+               <key>system.identity.write.self</key>
+               <dict>
+                       <key>authenticate-user</key>
+                       <false/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Checked when changing authentication credentials (password or certificate) for the current user's account.</string>
+                       <key>session-owner</key>
+                       <true/>
+               </dict>
+               <key>system.install.app-store-software</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>comment</key>
+                       <string>Checked when user is installing software from the App Store.</string>
+                       <key>rule</key>
+                       <string>entitled-appstore-or-entitled-authenticate-appstore</string>
+               </dict>
+               <key>system.install.app-store-software.standard-user</key>
+               <dict>
+                       <key>authenticate-user</key>
+                       <true/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Checked when user is installing new software.</string>
+                       <key>entitled</key>
+                       <true/>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>timeout</key>
+                       <integer>10</integer>
+               </dict>
+               <key>system.install.apple-config-data</key>
+               <dict>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>rule</key>
+                       <string>entitled</string>
+               </dict>
+               <key>system.install.apple-software</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>comment</key>
+                       <string>Checked when user is installing Apple-provided software.</string>
+                       <key>rule</key>
+                       <string>root-or-entitled-admin-or-authenticate-admin</string>
+               </dict>
+               <key>system.install.apple-software.standard-user</key>
+               <dict>
+                       <key>authenticate-user</key>
+                       <true/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Checked when user is installing new software.</string>
+                       <key>entitled</key>
+                       <true/>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>timeout</key>
+                       <integer>10</integer>
+               </dict>
+               <key>system.install.iap-software</key>
+               <dict>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>authenticate-user</key>
+                       <false/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>entitled</key>
+                       <true/>
+               </dict>
+               <key>system.install.software</key>
+               <dict>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Checked when user is installing new software.</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <false/>
+                       <key>timeout</key>
+                       <integer>300</integer>
+               </dict>
+               <key>system.keychain.create.loginkc</key>
+               <dict>
+                       <key>allow-root</key>
+                       <false/>
+                       <key>class</key>
+                       <string>evaluate-mechanisms</string>
+                       <key>comment</key>
+                       <string>Used by the Security framework when you add an item to an unconfigured default keychain.</string>
+                       <key>mechanisms</key>
+                       <array>
+                               <string>loginKC:queryCreate</string>
+                               <string>loginKC:showPasswordUI</string>
+                               <string>authinternal</string>
+                       </array>
+                       <key>session-owner</key>
+                       <true/>
+                       <key>shared</key>
+                       <false/>
+               </dict>
+               <key>system.keychain.modify</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Used by Keychain Access when editing a system keychain.</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <true/>
+                       <key>timeout</key>
+                       <integer>30</integer>
+               </dict>
+               <key>system.login.console</key>
+               <dict>
+                       <key>class</key>
+                       <string>evaluate-mechanisms</string>
+                       <key>comment</key>
+                       <string>Login mechanism based rule.  Not for general use, yet.</string>
+                       <key>mechanisms</key>
+                       <array>
+                               <string>builtin:policy-banner</string>
+                               <string>loginwindow:login</string>
+                               <string>builtin:login-begin</string>
+                               <string>builtin:reset-password,privileged</string>
+                               <string>builtin:forward-login,privileged</string>
+                               <string>builtin:auto-login,privileged</string>
+                               <string>builtin:authenticate,privileged</string>
+                               <string>PKINITMechanism:auth,privileged</string>
+                               <string>builtin:login-success</string>
+                               <string>loginwindow:success</string>
+                               <string>HomeDirMechanism:login,privileged</string>
+                               <string>HomeDirMechanism:status</string>
+                               <string>MCXMechanism:login</string>
+                               <string>loginwindow:done</string>
+                       </array>
+                       <key>version</key>
+                       <integer>1</integer>
+               </dict>
+               <key>system.login.done</key>
+               <dict>
+                       <key>class</key>
+                       <string>evaluate-mechanisms</string>
+                       <key>mechanisms</key>
+                       <array/>
+               </dict>
+               <key>system.login.screensaver</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>comment</key>
+                       <string>The owner or any administrator can unlock the screensaver, set rule to "authenticate-session-owner-or-admin" to enable SecurityAgent.</string>
+                       <key>rule</key>
+                       <string>use-login-window-ui</string>
+                       <key>version</key>
+                       <integer>1</integer>
+               </dict>
+               <key>system.login.tty</key>
+               <dict>
+                       <key>class</key>
+                       <string>evaluate-mechanisms</string>
+                       <key>mechanisms</key>
+                       <array>
+                               <string>push_hints_to_context</string>
+                               <string>authinternal</string>
+                       </array>
+                       <key>tries</key>
+                       <integer>1</integer>
+               </dict>
+               <key>system.preferences</key>
+               <dict>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Checked by the Admin framework when making changes to certain System Preferences.</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <true/>
+               </dict>
+               <key>system.preferences.accessibility</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Checked when making changes to the Accessibility Preferences.</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <false/>
+                       <key>timeout</key>
+                       <integer>0</integer>
+               </dict>
+               <key>system.preferences.accounts</key>
+               <dict>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Checked by the Admin framework when making changes to the Users &amp; Groups preference pane.</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <false/>
+               </dict>
+               <key>system.preferences.datetime</key>
+               <dict>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Checked by the Admin framework when making changes to the Date &amp; Time preference pane.</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <true/>
+               </dict>
+               <key>system.preferences.energysaver</key>
+               <dict>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Checked by the Admin framework when making changes to the Energy Saver preference pane.</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <true/>
+               </dict>
+               <key>system.preferences.location</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>comment</key>
+                       <string>For changing the network location from the Apple menu.</string>
+                       <key>k-of-n</key>
+                       <integer>1</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>on-console</string>
+                               <string>is-admin</string>
+                               <string>is-root</string>
+                       </array>
+               </dict>
+               <key>system.preferences.network</key>
+               <dict>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Checked by the Admin framework when making changes to the Network preference pane.</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <true/>
+               </dict>
+               <key>system.preferences.nvram</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>k-of-n</key>
+                       <integer>1</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>entitled</string>
+                               <string>admin</string>
+                       </array>
+               </dict>
+               <key>system.preferences.parental-controls</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Checked when making changes to the Parental Controls preference pane.</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <false/>
+               </dict>
+               <key>system.preferences.printing</key>
+               <dict>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Checked by the Admin framework when making changes to the Printing preference pane.</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <true/>
+               </dict>
+               <key>system.preferences.security</key>
+               <dict>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Checked by the Admin framework when making changes to the Security preference pane.</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <false/>
+               </dict>
+               <key>system.preferences.security.remotepair</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Used by Bezel Services to gate IR remote pairing.</string>
+                       <key>entitled-group</key>
+                       <true/>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <true/>
+                       <key>timeout</key>
+                       <integer>30</integer>
+                       <key>version</key>
+                       <integer>1</integer>
+               </dict>
+               <key>system.preferences.sharing</key>
+               <dict>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Checked by the Admin framework when making changes to the Sharing preference pane.</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <true/>
+               </dict>
+               <key>system.preferences.softwareupdate</key>
+               <dict>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Checked by the Admin framework when making changes to the Software Update preference pane.</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <true/>
+               </dict>
+               <key>system.preferences.startupdisk</key>
+               <dict>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Checked by the Admin framework when making changes to the Startup Disk preference pane.</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <true/>
+               </dict>
+               <key>system.preferences.timemachine</key>
+               <dict>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Checked by the Admin framework when making changes to the Time Machine preference pane.</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <true/>
+               </dict>
+               <key>system.preferences.version-cue</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>comment</key>
+                       <string>For gating modifications to Adobe Version Cue preferences.</string>
+                       <key>rule</key>
+                       <string>authenticate-admin</string>
+               </dict>
+               <key>system.print.admin</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>rule</key>
+                       <string>root-or-lpadmin</string>
+               </dict>
+               <key>system.print.operator</key>
+               <dict>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>group</key>
+                       <string>_lpoperator</string>
+                       <key>shared</key>
+                       <true/>
+               </dict>
+               <key>system.printingmanager</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>comment</key>
+                       <string>For printing to locked printers.</string>
+                       <key>k-of-n</key>
+                       <integer>1</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>is-admin</string>
+                               <string>authenticate-admin</string>
+                       </array>
+               </dict>
+               <key>system.privilege.admin</key>
+               <dict>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Used by AuthorizationExecuteWithPrivileges(...).  
+               AuthorizationExecuteWithPrivileges() is used by programs requesting
+               to run a tool as root (e.g., some installers).</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <false/>
+                       <key>timeout</key>
+                       <integer>300</integer>
+               </dict>
+               <key>system.privilege.taskport</key>
+               <dict>
+                       <key>allow-root</key>
+                       <false/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Used by task_for_pid(...).
+               Task_for_pid is called by programs requesting full control over another program
+               for things like debugging or performance analysis. This authorization only applies
+               if the requesting and target programs are run by the same user; it will never
+               authorize access to the program of another user.  WARNING: administrators are advised not to modify this right.</string>
+                       <key>group</key>
+                       <string>_developer</string>
+                       <key>shared</key>
+                       <true/>
+                       <key>timeout</key>
+                       <integer>36000</integer>
+               </dict>
+               <key>system.privilege.taskport.debug</key>
+               <dict>
+                       <key>allow-root</key>
+                       <false/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>For use by Apple.  WARNING: administrators are advised
+            not to modify this right.</string>
+                       <key>group</key>
+                       <string>_developer</string>
+                       <key>shared</key>
+                       <true/>
+                       <key>timeout</key>
+                       <integer>36000</integer>
+               </dict>
+               <key>system.privilege.taskport.safe</key>
+               <dict>
+                       <key>class</key>
+                       <string>allow</string>
+                       <key>comment</key>
+                       <string>For use by Apple.</string>
+               </dict>
+               <key>system.restart</key>
+               <dict>
+                       <key>class</key>
+                       <string>evaluate-mechanisms</string>
+                       <key>comment</key>
+                       <string>Checked if the foreground console user tries to restart the system while other users are logged in via fast-user switching.</string>
+                       <key>mechanisms</key>
+                       <array>
+                               <string>RestartAuthorization:restart</string>
+                               <string>builtin:authenticate,privileged</string>
+                               <string>RestartAuthorization:success</string>
+                       </array>
+               </dict>
+               <key>system.services.directory.configure</key>
+               <dict>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>For making Directory Services changes.</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <false/>
+               </dict>
+               <key>system.services.systemconfiguration.network</key>
+               <dict>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>For making change to network configuration via System Configuration.</string>
+                       <key>entitled-group</key>
+                       <true/>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>version</key>
+                       <integer>1</integer>
+                       <key>vpn-entitled-group</key>
+                       <true/>
+               </dict>
+               <key>system.sharepoints.</key>
+               <dict>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Checked when making changes to the Sharepoints.</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <true/>
+               </dict>
+               <key>system.shutdown</key>
+               <dict>
+                       <key>class</key>
+                       <string>evaluate-mechanisms</string>
+                       <key>comment</key>
+                       <string>Checked if the foreground console user tries to shut down the system while other users are logged in via fast-user switching.</string>
+                       <key>mechanisms</key>
+                       <array>
+                               <string>RestartAuthorization:shutdown</string>
+                               <string>builtin:authenticate,privileged</string>
+                               <string>RestartAuthorization:success</string>
+                       </array>
+               </dict>
+               <key>system.volume.</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>comment</key>
+                       <string>system.volume.(external|internal|removable).(adopt|encode|mount|rename|unmount)</string>
+                       <key>k-of-n</key>
+                       <integer>1</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>is-root</string>
+                               <string>is-admin</string>
+                               <string>authenticate-admin-30</string>
+                       </array>
+               </dict>
+               <key>system.volume.external.</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>comment</key>
+                       <string>system.volume.(external|internal|removable).(adopt|encode|mount|rename|unmount)</string>
+                       <key>k-of-n</key>
+                       <integer>1</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>is-root</string>
+                               <string>is-admin</string>
+                               <string>on-console</string>
+                               <string>authenticate-admin-30</string>
+                       </array>
+               </dict>
+               <key>system.volume.external.adopt</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>comment</key>
+                       <string>system.volume.(external|internal|removable).(adopt|encode|mount|rename|unmount)</string>
+                       <key>k-of-n</key>
+                       <integer>1</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>is-root</string>
+                               <string>is-admin</string>
+                               <string>authenticate-admin-30</string>
+                       </array>
+               </dict>
+               <key>system.volume.removable.</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>comment</key>
+                       <string>system.volume.(external|internal|removable).(adopt|encode|mount|rename|unmount)</string>
+                       <key>k-of-n</key>
+                       <integer>1</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>is-root</string>
+                               <string>is-admin</string>
+                               <string>on-console</string>
+                               <string>authenticate-admin-30</string>
+                       </array>
+               </dict>
+               <key>system.volume.removable.adopt</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>comment</key>
+                       <string>system.volume.(external|internal|removable).(adopt|encode|mount|rename|unmount)</string>
+                       <key>k-of-n</key>
+                       <integer>1</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>is-root</string>
+                               <string>is-admin</string>
+                               <string>authenticate-admin-30</string>
+                       </array>
+               </dict>
+       </dict>
+       <key>rules</key>
+       <dict>
+               <key>admin</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <true/>
+               </dict>
+               <key>allow</key>
+               <dict>
+                       <key>class</key>
+                       <string>allow</string>
+                       <key>comment</key>
+                       <string>Allow anyone.</string>
+               </dict>
+               <key>app-specific-admin</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>group</key>
+                       <string>admin</string>
+               </dict>
+               <key>appserver-admin</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>group</key>
+                       <string>appserveradm</string>
+               </dict>
+               <key>appserver-user</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>group</key>
+                       <string>appserverusr</string>
+               </dict>
+               <key>authenticate</key>
+               <dict>
+                       <key>class</key>
+                       <string>evaluate-mechanisms</string>
+                       <key>mechanisms</key>
+                       <array>
+                               <string>builtin:authenticate</string>
+                               <string>builtin:reset-password,privileged</string>
+                               <string>builtin:authenticate,privileged</string>
+                               <string>PKINITMechanism:auth,privileged</string>
+                       </array>
+               </dict>
+               <key>authenticate-admin</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Authenticate as an administrator.</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <true/>
+                       <key>timeout</key>
+                       <integer>0</integer>
+               </dict>
+               <key>authenticate-admin-30</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Like the default rule, but 
+            credentials remain valid for only 30 seconds after they've 
+            been obtained.  An acquired credential is shared by all clients.
+                       </string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <true/>
+                       <key>timeout</key>
+                       <integer>30</integer>
+               </dict>
+               <key>authenticate-appstore-30</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>group</key>
+                       <string>_appstore</string>
+                       <key>shared</key>
+                       <true/>
+                       <key>timeout</key>
+                       <integer>30</integer>
+               </dict>
+               <key>authenticate-developer</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Authenticate as a developer.</string>
+                       <key>group</key>
+                       <string>_developer</string>
+                       <key>shared</key>
+                       <true/>
+                       <key>timeout</key>
+                       <integer>36000</integer>
+               </dict>
+               <key>authenticate-session-owner</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Authenticate as the session owner.</string>
+                       <key>session-owner</key>
+                       <true/>
+               </dict>
+               <key>authenticate-session-owner-or-admin</key>
+               <dict>
+                       <key>allow-root</key>
+                       <false/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Authenticate either as the owner or as an administrator.</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>session-owner</key>
+                       <true/>
+                       <key>shared</key>
+                       <false/>
+               </dict>
+               <key>authenticate-session-user</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Same as authenticate-session-owner.</string>
+                       <key>session-owner</key>
+                       <true/>
+               </dict>
+               <key>default</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Default rule.   
+            Credentials remain valid for 5 minutes after they've been obtained. 
+            An acquired credential is shared by all clients.
+                       </string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <true/>
+                       <key>timeout</key>
+                       <integer>300</integer>
+               </dict>
+               <key>entitled</key>
+               <dict>
+                       <key>class</key>
+                       <string>evaluate-mechanisms</string>
+                       <key>mechanisms</key>
+                       <array>
+                               <string>builtin:entitled,privileged</string>
+                       </array>
+                       <key>tries</key>
+                       <integer>1</integer>
+               </dict>
+               <key>entitled-admin</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>k-of-n</key>
+                       <integer>2</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>is-admin</string>
+                               <string>entitled</string>
+                       </array>
+               </dict>
+               <key>entitled-admin-or-authenticate-admin</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>k-of-n</key>
+                       <integer>1</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>entitled-admin</string>
+                               <string>authenticate-admin-30</string>
+                       </array>
+               </dict>
+               <key>entitled-appstore</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>k-of-n</key>
+                       <integer>2</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>is-appstore</string>
+                               <string>entitled</string>
+                       </array>
+               </dict>
+               <key>entitled-appstore-or-entitled-authenticate-appstore</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>k-of-n</key>
+                       <integer>1</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>entitled-appstore</string>
+                               <string>entitled-authenticate-appstore</string>
+                       </array>
+               </dict>
+               <key>entitled-authenticate-admin</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>k-of-n</key>
+                       <integer>2</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>entitled</string>
+                               <string>authenticate-admin-30</string>
+                       </array>
+               </dict>
+               <key>entitled-authenticate-appstore</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>k-of-n</key>
+                       <integer>2</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>entitled</string>
+                               <string>authenticate-appstore-30</string>
+                       </array>
+               </dict>
+               <key>entitled-session-owner</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>k-of-n</key>
+                       <integer>2</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>is-session-owner</string>
+                               <string>entitled</string>
+                       </array>
+               </dict>
+               <key>entitled-session-owner-or-authenticate-session-owner</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>k-of-n</key>
+                       <integer>1</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>entitled-session-owner</string>
+                               <string>authenticate-session-owner</string>
+                       </array>
+               </dict>
+               <key>is-admin</key>
+               <dict>
+                       <key>authenticate-user</key>
+                       <false/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Verify that the user asking for authorization is an administrator.</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <true/>
+               </dict>
+               <key>is-appstore</key>
+               <dict>
+                       <key>authenticate-user</key>
+                       <false/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>group</key>
+                       <string>_appstore</string>
+                       <key>shared</key>
+                       <true/>
+               </dict>
+               <key>is-developer</key>
+               <dict>
+                       <key>authenticate-user</key>
+                       <false/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Verify that the user asking for authorization is a developer.</string>
+                       <key>group</key>
+                       <string>_developer</string>
+               </dict>
+               <key>is-lpadmin</key>
+               <dict>
+                       <key>authenticate-user</key>
+                       <false/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>group</key>
+                       <string>_lpadmin</string>
+               </dict>
+               <key>is-root</key>
+               <dict>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>authenticate-user</key>
+                       <false/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Verify that the process that created this AuthorizationRef is running as root.</string>
+               </dict>
+               <key>is-session-owner</key>
+               <dict>
+                       <key>allow-root</key>
+                       <false/>
+                       <key>authenticate-user</key>
+                       <false/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Verify that the requesting process is running as the session owner.</string>
+                       <key>session-owner</key>
+                       <true/>
+               </dict>
+               <key>lpadmin</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>group</key>
+                       <string>_lpadmin</string>
+                       <key>shared</key>
+                       <true/>
+               </dict>
+               <key>on-console</key>
+               <dict>
+                       <key>class</key>
+                       <string>evaluate-mechanisms</string>
+                       <key>mechanisms</key>
+                       <array>
+                               <string>builtin:on-console</string>
+                       </array>
+                       <key>tries</key>
+                       <integer>1</integer>
+               </dict>
+               <key>root-or-entitled-admin-or-admin</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>k-of-n</key>
+                       <integer>1</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>is-root</string>
+                               <string>entitled-admin</string>
+                               <string>admin</string>
+                       </array>
+               </dict>
+               <key>root-or-entitled-admin-or-app-specific-admin</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>k-of-n</key>
+                       <integer>1</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>is-root</string>
+                               <string>entitled-admin</string>
+                               <string>app-specific-admin</string>
+                       </array>
+               </dict>
+               <key>root-or-entitled-admin-or-authenticate-admin</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>k-of-n</key>
+                       <integer>1</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>is-root</string>
+                               <string>entitled-admin-or-authenticate-admin</string>
+                       </array>
+               </dict>
+               <key>root-or-lpadmin</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>k-of-n</key>
+                       <integer>1</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>is-root</string>
+                               <string>is-lpadmin</string>
+                               <string>lpadmin</string>
+                       </array>
+               </dict>
+               <key>use-login-window-ui</key>
+               <dict>
+                       <key>allow-root</key>
+                       <false/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Authenticate either as the owner or as an administrator.</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>session-owner</key>
+                       <true/>
+                       <key>shared</key>
+                       <false/>
+               </dict>
+       </dict>
+</dict>
+</plist>
diff --git a/authd/authtoken.c b/authd/authtoken.c
new file mode 100644 (file)
index 0000000..fe49535
--- /dev/null
@@ -0,0 +1,515 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#include "authtoken.h"
+#include "authd_private.h"
+#include "process.h"
+#include "authitems.h"
+#include "debugging.h"
+#include "authutilities.h"
+#include "server.h"
+
+#include <CommonCrypto/CommonRandomSPI.h>
+#include <Security/Authorization.h>
+#include <Security/SecBase.h>
+#include <sandbox.h>
+
+static Boolean AuthTokenEqualCallBack(const void *value1, const void *value2)
+{
+    return (*(uint64_t*)value1) == (*(uint64_t*)value2);
+}
+
+static CFHashCode AuthTokenHashCallBack(const void *value)
+{
+//    CFHashCode hash;
+//    AuthorizationBlob* blob = (AuthorizationBlob*)value;
+//    hash = blob->data[1];
+//    hash <<= 32;
+//    hash |= blob->data[0];
+//    return hash;
+    //quick 64 bit aligned version
+    return *((CFHashCode*)((AuthorizationBlob*)value)->data);
+}
+
+const CFDictionaryKeyCallBacks kAuthTokenKeyCallBacks = {
+    .version = 0,
+    .retain = NULL,
+    .release = NULL,
+    .copyDescription = NULL,
+    .equal = &AuthTokenEqualCallBack,
+    .hash = &AuthTokenHashCallBack
+};
+
+struct _auth_token_s {
+    __AUTH_BASE_STRUCT_HEADER__;
+    
+    AuthorizationBlob blob;
+    auth_token_state_t state;
+    audit_info_s auditInfo;
+    dispatch_queue_t dispatch_queue;
+    
+    CFMutableSetRef processes;
+    
+    session_t session;
+    process_t creator; // weak reference, used for entitlement checking
+    mach_port_t creator_bootstrap_port;
+    
+    auth_items_t context;
+    
+    CFMutableSetRef credentials;
+    CFMutableSetRef authorized_rights;
+    
+    bool least_privileged;
+    bool appleSigned;
+    
+    bool sandboxed;
+    char * code_url;
+    
+    credential_t credential;
+};
+
+static void
+_auth_token_finalize(CFTypeRef value)
+{
+    auth_token_t auth = (auth_token_t)value;
+    LOGV("authtoken: deallocated %p", auth);
+    
+    dispatch_barrier_sync(auth->dispatch_queue, ^{});
+    
+    dispatch_release(auth->dispatch_queue);
+    CFReleaseSafe(auth->session);
+    CFReleaseSafe(auth->processes);
+    CFReleaseSafe(auth->context);
+    CFReleaseSafe(auth->credentials);
+    CFReleaseSafe(auth->authorized_rights);
+    free_safe(auth->code_url);
+    CFReleaseSafe(auth->credential);
+    
+    if (auth->creator_bootstrap_port != MACH_PORT_NULL) {
+        mach_port_deallocate(mach_task_self(), auth->creator_bootstrap_port);
+    }
+}
+
+static Boolean
+_auth_token_equal(CFTypeRef value1, CFTypeRef value2)
+{
+    auth_token_t auth1 = (auth_token_t)value1;
+    auth_token_t auth2 = (auth_token_t)value2;
+    
+    return memcmp(&auth1->blob, &auth2->blob, sizeof(AuthorizationBlob)) == 0;
+}
+
+static CFStringRef
+_auth_token_copy_description(CFTypeRef value)
+{
+    auth_token_t auth = (auth_token_t)value;
+    return CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("auth_token: %p, uid=%i, pid=%i, processes=%li least_privileged=%i"),
+                                    auth, auth->auditInfo.euid, auth->auditInfo.pid, CFSetGetCount(auth->processes), auth->least_privileged);
+}
+
+static CFHashCode
+_auth_token_hash(CFTypeRef value)
+{
+    auth_token_t auth = (auth_token_t)value;
+    return *(CFHashCode*)&auth->blob;
+}
+
+AUTH_TYPE_INSTANCE(auth_token,
+                   .init = NULL,
+                   .copy = NULL,
+                   .finalize = _auth_token_finalize,
+                   .equal = _auth_token_equal,
+                   .hash = _auth_token_hash,
+                   .copyFormattingDesc = NULL,
+                   .copyDebugDesc = _auth_token_copy_description
+                   );
+
+static CFTypeID auth_token_get_type_id() {
+    static CFTypeID type_id = _kCFRuntimeNotATypeID;
+    static dispatch_once_t onceToken;
+    
+    dispatch_once(&onceToken, ^{
+        type_id = _CFRuntimeRegisterClass(&_auth_type_auth_token);
+    });
+    
+    return type_id;
+}
+
+static auth_token_t
+_auth_token_create(const audit_info_s * auditInfo, bool operateAsLeastPrivileged)
+{
+#if __LLP64__
+    __Check_Compile_Time(sizeof(CFHashCode) == sizeof(AuthorizationBlob));
+#endif
+    
+    auth_token_t auth = (auth_token_t)_CFRuntimeCreateInstance(kCFAllocatorDefault, auth_token_get_type_id(), AUTH_CLASS_SIZE(auth_token), NULL);
+    require(auth != NULL, done);
+    
+    if (CCRandomCopyBytes(kCCRandomDefault, auth->blob.data, sizeof(auth->blob.data)) != kCCSuccess) {
+        LOGE("authtoken[%i]: failed to generate blob", auditInfo->pid);
+        CFReleaseNull(auth);
+        goto done;
+    }
+    
+    auth->context = auth_items_create();
+    auth->auditInfo = *auditInfo;
+    auth->least_privileged = operateAsLeastPrivileged;
+
+    auth->dispatch_queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
+    check(auth->dispatch_queue != NULL);
+    
+    auth->credentials = CFSetCreateMutable(kCFAllocatorDefault, 0, &kCFTypeSetCallBacks);
+    auth->authorized_rights = CFSetCreateMutable(kCFAllocatorDefault, 0, &kCFTypeSetCallBacks);
+    auth->processes = CFSetCreateMutable(kCFAllocatorDefault, 0, NULL);
+    auth->creator_bootstrap_port = MACH_PORT_NULL;
+
+    if (sandbox_check(auth->auditInfo.pid, "authorization-right-obtain", SANDBOX_CHECK_NO_REPORT) != 0)
+               auth->sandboxed = true;
+       else
+               auth->sandboxed = false;
+    
+#if DEBUG
+    CFHashCode code = AuthTokenHashCallBack(&auth->blob);
+    if (memcmp(&code, auth->blob.data, sizeof(auth->blob.data)) != 0) {
+        LOGD("authtoken[%i]: blob = %x%01x", auth->auditInfo.pid, auth->blob.data[1], auth->blob.data[0]);
+        LOGD("authtoken[%i]: hash = %lx", auth->auditInfo.pid, code);
+        assert(false);
+    }
+#endif
+    
+done:
+    return auth;
+}
+
+auth_token_t
+auth_token_create(process_t proc, bool operateAsLeastPrivileged)
+{
+    auth_token_t auth = NULL;
+    require(proc != NULL, done);
+    
+    auth = _auth_token_create(process_get_audit_info(proc), operateAsLeastPrivileged);
+    require(auth != NULL, done);
+    
+    auth->creator = proc;
+    auth->session = (session_t)CFRetain(process_get_session(proc));
+    auth->code_url = _copy_string(process_get_code_url(proc));
+    auth->appleSigned = process_apple_signed(proc);
+    auth->creator_bootstrap_port = process_get_bootstrap(proc);
+    // This line grabs a reference to the send right to the bootstrap (our right to send to the bootstrap)
+    // This makes it critical to use the same call in reverse as we are only getting a ref to one right,
+    // but deallocate will free a ref to all 5 rights.
+    if (auth->creator_bootstrap_port != MACH_PORT_NULL) {
+        kern_return_t error_code = mach_port_mod_refs(mach_task_self(), auth->creator_bootstrap_port, MACH_PORT_RIGHT_SEND, 1);
+        if (error_code != KERN_SUCCESS) {
+            // If no reference to the mach port right can be obtained, we don't hold the copy, so mark it NULL again!
+            auth->creator_bootstrap_port = MACH_PORT_NULL;
+        }
+    }
+    
+    LOGV("authtoken[%i]: created %p", auth->auditInfo.pid, auth);
+
+done:
+    return auth;
+}
+
+auth_token_t
+auth_token_create_with_audit_info(const audit_info_s* info, bool operateAsLeastPrivileged)
+{
+    OSStatus status = errSecSuccess;
+    SecCodeRef code_Ref = NULL;
+    CFURLRef code_url = NULL;
+    
+    auth_token_t auth = NULL;
+    require(info != NULL, done);
+    
+    auth = _auth_token_create(info, operateAsLeastPrivileged);
+    require(auth != NULL, done);
+    
+    auth->session = server_find_copy_session(info->asid, true);
+    if (auth->session == NULL) {
+        LOGV("authtoken[%i]: failed to create session", auth->auditInfo.pid);
+        CFReleaseNull(auth);
+        goto done;
+    }
+    
+    CFMutableDictionaryRef codeDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    CFNumberRef codePid = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &auth->auditInfo.pid);
+    CFDictionarySetValue(codeDict, kSecGuestAttributePid, codePid);
+    status = SecCodeCopyGuestWithAttributes(NULL, codeDict, kSecCSDefaultFlags, &code_Ref);
+    CFReleaseSafe(codeDict);
+    CFReleaseSafe(codePid);
+    
+    if (status) {
+        LOGV("authtoken[%i]: failed to create code ref (%i)", auth->auditInfo.pid, status);
+        CFReleaseNull(auth);
+        goto done;
+    }
+
+    if (SecCodeCopyPath(code_Ref, kSecCSDefaultFlags, &code_url) == errSecSuccess) {
+        auth->code_url = calloc(1u, PATH_MAX+1);
+        if (auth->code_url) {
+            CFURLGetFileSystemRepresentation(code_url, true, (UInt8*)auth->code_url, PATH_MAX);
+        }
+    }
+
+    LOGV("authtoken[%i]: created %p for %s", auth->auditInfo.pid, auth, auth->code_url);
+    
+done:
+    CFReleaseSafe(code_Ref);
+    CFReleaseSafe(code_url);
+    return auth;
+}
+
+bool
+auth_token_get_sandboxed(auth_token_t auth)
+{
+    return auth->sandboxed;
+}
+
+const char *
+auth_token_get_code_url(auth_token_t auth)
+{
+    return auth->code_url;
+}
+
+const void *
+auth_token_get_key(auth_token_t auth)
+{
+    return &auth->blob;
+}
+
+auth_items_t
+auth_token_get_context(auth_token_t auth)
+{
+    return auth->context;
+}
+
+bool
+auth_token_least_privileged(auth_token_t auth)
+{
+    return auth->least_privileged;
+}
+
+uid_t
+auth_token_get_uid(auth_token_t auth)
+{
+    return auth ? auth->auditInfo.euid : (uid_t)-2;
+}
+
+pid_t
+auth_token_get_pid(auth_token_t auth)
+{
+    return auth ? auth->auditInfo.pid : -1;
+}
+
+session_t
+auth_token_get_session(auth_token_t auth)
+{
+    return auth->session;
+}
+
+const AuthorizationBlob *
+auth_token_get_blob(auth_token_t auth)
+{
+    return &auth->blob;
+}
+
+const audit_info_s *
+auth_token_get_audit_info(auth_token_t auth)
+{
+    return &auth->auditInfo;
+}
+
+mach_port_t
+auth_token_get_creator_bootstrap(auth_token_t auth)
+{
+    return auth->creator_bootstrap_port;
+}
+
+CFIndex
+auth_token_add_process(auth_token_t auth, process_t proc)
+{
+    __block CFIndex count = 0;
+    dispatch_sync(auth->dispatch_queue, ^{
+        CFSetAddValue(auth->processes, proc);
+        count = CFSetGetCount(auth->processes);
+    });
+    return count;
+}
+
+CFIndex
+auth_token_remove_process(auth_token_t auth, process_t proc)
+{
+    __block CFIndex count = 0;
+    dispatch_sync(auth->dispatch_queue, ^{
+        if (auth->creator == proc) {
+            auth->creator = NULL;
+        }
+        CFSetRemoveValue(auth->processes, proc);
+        count = CFSetGetCount(auth->processes);
+    });
+    return count;
+}
+
+CFIndex
+auth_token_get_process_count(auth_token_t auth)
+{
+    __block CFIndex count = 0;
+    dispatch_sync(auth->dispatch_queue, ^{
+        count = CFSetGetCount(auth->processes);
+    });
+    return count;
+}
+
+void
+auth_token_set_credential(auth_token_t auth, credential_t cred)
+{
+    dispatch_sync(auth->dispatch_queue, ^{
+        CFSetSetValue(auth->credentials, cred);
+    });
+}
+
+bool
+auth_token_credentials_iterate(auth_token_t auth, credential_iterator_t iter)
+{
+    __block bool result = false;
+    
+    dispatch_sync(auth->dispatch_queue, ^{
+        CFIndex count = CFSetGetCount(auth->credentials);
+        CFTypeRef values[count];
+        CFSetGetValues(auth->credentials, values);
+        for (CFIndex i = 0; i < count; i++) {
+            credential_t cred = (credential_t)values[i];
+            result = iter(cred);
+            if (!result) {
+                break;
+            }
+        }
+    });
+    
+    return result;
+}
+
+void
+auth_token_set_right(auth_token_t auth, credential_t right)
+{
+    dispatch_sync(auth->dispatch_queue, ^{
+        CFSetSetValue(auth->authorized_rights, right);
+    });
+}
+
+bool
+auth_token_rights_iterate(auth_token_t auth, credential_iterator_t iter)
+{
+    __block bool result = false;
+    
+    dispatch_sync(auth->dispatch_queue, ^{
+        CFIndex count = CFSetGetCount(auth->authorized_rights);
+        CFTypeRef values[count];
+        CFSetGetValues(auth->authorized_rights, values);
+        for (CFIndex i = 0; i < count; i++) {
+            credential_t right = (credential_t)values[i];
+            result = iter(right);
+            if (!result) {
+                break;
+            }
+        }
+    });
+    
+    return result;
+}
+
+CFTypeRef
+auth_token_copy_entitlement_value(auth_token_t auth, const char * entitlement)
+{
+    __block CFTypeRef value = NULL;
+    dispatch_sync(auth->dispatch_queue, ^{
+        if (auth->creator) {
+            value = process_copy_entitlement_value(auth->creator, entitlement);
+        }
+    });
+    
+    return value;
+}
+
+bool
+auth_token_has_entitlement(auth_token_t auth, const char * entitlement)
+{
+    __block bool entitled = false;
+
+    dispatch_sync(auth->dispatch_queue, ^{
+        if (auth->creator) {
+            entitled = process_has_entitlement(auth->creator, entitlement);
+        }
+    });
+    
+    return entitled;
+}
+
+bool
+auth_token_has_entitlement_for_right(auth_token_t auth, const char * right)
+{
+    __block bool entitled = false;
+    
+    dispatch_sync(auth->dispatch_queue, ^{
+        if (auth->creator) {
+            entitled = process_has_entitlement_for_right(auth->creator, right);
+        }
+    });
+    
+    return entitled;
+}
+
+credential_t
+auth_token_get_credential(auth_token_t auth)
+{
+    dispatch_sync(auth->dispatch_queue, ^{
+        if (auth->credential == NULL) {
+            auth->credential = credential_create(auth->auditInfo.euid);
+        }
+    });
+    
+    return auth->credential;
+}
+
+bool
+auth_token_apple_signed(auth_token_t auth)
+{
+    return auth->appleSigned;
+}
+
+bool auth_token_is_creator(auth_token_t auth, process_t proc)
+{
+    __block bool creator = false;
+    if (proc) {
+        dispatch_sync(auth->dispatch_queue, ^{
+            if (auth->creator == proc) {
+                creator = true;
+            }
+        });
+    }
+    return creator;
+}
+
+void auth_token_set_state(auth_token_t auth, auth_token_state_t state)
+{
+    auth->state |= state;
+}
+
+void auth_token_clear_state(auth_token_t auth, auth_token_state_t state)
+{
+    auth->state &= ~state;
+}
+
+auth_token_state_t auth_token_get_state(auth_token_t auth)
+{
+    return auth->state;
+}
+
+bool auth_token_check_state(auth_token_t auth, auth_token_state_t state)
+{
+    if (state) {
+        return (auth->state & state) != 0;
+    } else {
+        return auth->state == 0;
+    }
+}
diff --git a/authd/authtoken.h b/authd/authtoken.h
new file mode 100644 (file)
index 0000000..6f6282c
--- /dev/null
@@ -0,0 +1,115 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#ifndef _SECURITY_AUTH_AUTHTOKEN_H_
+#define _SECURITY_AUTH_AUTHTOKEN_H_
+
+#include "credential.h"
+#include <CoreFoundation/CoreFoundation.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+enum {
+    auth_token_state_zombie     = 1 << 0,
+    auth_token_state_registered = 1 << 1
+};
+typedef uint32_t auth_token_state_t;
+
+extern const CFDictionaryKeyCallBacks kAuthTokenKeyCallBacks;
+    
+AUTH_WARN_RESULT AUTH_MALLOC AUTH_NONNULL_ALL AUTH_RETURNS_RETAINED
+auth_token_t auth_token_create(process_t,bool operateAsLeastPrivileged);
+
+AUTH_WARN_RESULT AUTH_MALLOC AUTH_NONNULL_ALL AUTH_RETURNS_RETAINED
+auth_token_t auth_token_create_with_audit_info(const audit_info_s*,bool operateAsLeastPrivileged);
+    
+AUTH_NONNULL_ALL
+bool auth_token_get_sandboxed(auth_token_t);
+    
+AUTH_NONNULL_ALL
+const char * auth_token_get_code_url(auth_token_t);
+    
+AUTH_NONNULL_ALL
+const void * auth_token_get_key(auth_token_t);
+
+AUTH_NONNULL_ALL
+auth_items_t auth_token_get_context(auth_token_t);
+
+AUTH_NONNULL_ALL
+bool auth_token_least_privileged(auth_token_t);
+    
+AUTH_NONNULL_ALL
+uid_t auth_token_get_uid(auth_token_t);
+    
+AUTH_NONNULL_ALL
+pid_t auth_token_get_pid(auth_token_t);
+    
+AUTH_NONNULL_ALL
+session_t auth_token_get_session(auth_token_t);
+    
+AUTH_NONNULL_ALL
+const AuthorizationBlob * auth_token_get_blob(auth_token_t);
+    
+AUTH_NONNULL_ALL
+const audit_info_s * auth_token_get_audit_info(auth_token_t);
+
+AUTH_NONNULL_ALL
+mach_port_t auth_token_get_creator_bootstrap(auth_token_t auth);
+    
+AUTH_NONNULL_ALL
+CFIndex auth_token_add_process(auth_token_t,process_t);
+
+AUTH_NONNULL_ALL
+CFIndex auth_token_remove_process(auth_token_t,process_t);
+
+AUTH_NONNULL_ALL
+CFIndex auth_token_get_process_count(auth_token_t);
+    
+AUTH_NONNULL_ALL
+void auth_token_set_credential(auth_token_t,credential_t);
+    
+AUTH_NONNULL_ALL
+bool auth_token_credentials_iterate(auth_token_t, credential_iterator_t iter);
+
+AUTH_NONNULL_ALL
+void auth_token_set_right(auth_token_t,credential_t);
+    
+AUTH_NONNULL_ALL
+bool auth_token_rights_iterate(auth_token_t, credential_iterator_t iter);
+
+AUTH_NONNULL_ALL
+CFTypeRef auth_token_copy_entitlement_value(auth_token_t, const char * entitlement);
+    
+AUTH_NONNULL_ALL
+bool auth_token_has_entitlement(auth_token_t, const char * entitlement);
+
+AUTH_NONNULL_ALL
+bool auth_token_has_entitlement_for_right(auth_token_t, const char * right);
+
+AUTH_NONNULL_ALL
+credential_t auth_token_get_credential(auth_token_t);
+
+AUTH_NONNULL_ALL
+bool auth_token_apple_signed(auth_token_t);
+
+AUTH_NONNULL_ALL
+bool auth_token_is_creator(auth_token_t,process_t);
+
+AUTH_NONNULL_ALL
+void auth_token_set_state(auth_token_t,auth_token_state_t);
+
+AUTH_NONNULL_ALL
+void auth_token_clear_state(auth_token_t,auth_token_state_t);
+
+AUTH_WARN_RESULT AUTH_NONNULL_ALL
+auth_token_state_t auth_token_get_state(auth_token_t);
+
+AUTH_NONNULL_ALL
+bool auth_token_check_state(auth_token_t, auth_token_state_t);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_SECURITY_AUTH_AUTHTOKEN_H_ */
diff --git a/authd/authtypes.h b/authd/authtypes.h
new file mode 100644 (file)
index 0000000..5f5a170
--- /dev/null
@@ -0,0 +1,41 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#ifndef _SECURITY_AUTH_TYPES_H_
+#define _SECURITY_AUTH_TYPES_H_
+
+#include <bsm/audit.h>
+#include <mach/message.h>
+
+typedef struct {
+    uid_t auid;
+       uid_t euid;
+       gid_t egid;
+       uid_t ruid;
+       gid_t rgid;
+       pid_t pid;
+       au_asid_t asid;
+       int32_t tid;
+    audit_token_t opaqueToken;
+} audit_info_s;
+
+typedef au_asid_t session_id_t;
+typedef struct _session_s * session_t;
+typedef struct _process_s * process_t;
+typedef struct _connection_s * connection_t;
+
+typedef struct _auth_token_s * auth_token_t;
+typedef struct _credential_s * credential_t;
+
+typedef struct _ccaudit_s * ccaudit_t;
+typedef struct _mechanism_s * mechanism_t;
+typedef struct _rule_s * rule_t;
+typedef struct _agent_s * agent_t;
+typedef struct _engine_s * engine_t;
+
+typedef struct _authdb_s * authdb_t;
+typedef struct _authdb_connection_s * authdb_connection_t;
+
+typedef struct _auth_items_s * auth_items_t;
+typedef struct _auth_rights_s * auth_rights_t;
+
+#endif /* !_SECURITY_AUTH_TYPES_H_ */
diff --git a/authd/authutilities.c b/authd/authutilities.c
new file mode 100644 (file)
index 0000000..52e4b0f
--- /dev/null
@@ -0,0 +1,283 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#include "authutilities.h"
+#include "authd_private.h"
+#include "debugging.h"
+
+#include <AssertMacros.h>
+#include <assert.h>
+#include <syslog.h>
+
+xpc_object_t
+SerializeItemSet(const AuthorizationItemSet * itemSet)
+{
+    xpc_object_t set = NULL;
+    require_quiet(itemSet != NULL, done);
+    require_quiet(itemSet->count != 0, done);
+    
+    set = xpc_array_create(NULL, 0);
+    require(set != NULL, done);
+    
+    for (uint32_t i = 0; i < itemSet->count; i++) {
+        xpc_object_t item = xpc_dictionary_create(NULL, NULL, 0);
+        require(item != NULL, done);
+        
+        xpc_dictionary_set_string(item, AUTH_XPC_ITEM_NAME, itemSet->items[i].name);
+        xpc_dictionary_set_uint64(item, AUTH_XPC_ITEM_FLAGS, itemSet->items[i].flags);
+        xpc_dictionary_set_data(item, AUTH_XPC_ITEM_VALUE, itemSet->items[i].value, itemSet->items[i].valueLength);
+        xpc_array_set_value(set, XPC_ARRAY_APPEND, item);
+        xpc_release(item);
+    }
+    
+done:
+    return set;
+}
+
+AuthorizationItemSet *
+DeserializeItemSet(const xpc_object_t data)
+{
+    AuthorizationItemSet * set = NULL;
+    require_quiet(data != NULL, done);
+    xpc_retain(data);
+    require(xpc_get_type(data) == XPC_TYPE_ARRAY, done);
+    
+    set = (AuthorizationItemSet*)calloc(1u, sizeof(AuthorizationItemSet));
+    require(set != NULL, done);
+    
+    set->count = (uint32_t)xpc_array_get_count(data);
+    if (set->count) {
+        set->items = (AuthorizationItem*)calloc(set->count, sizeof(AuthorizationItem));
+        require_action(set->items != NULL, done, set->count = 0);
+        
+        xpc_array_apply(data, ^bool(size_t index, xpc_object_t value) {
+            require(xpc_get_type(value) == XPC_TYPE_DICTIONARY, done);
+            size_t nameLen = 0;
+            const char * name = xpc_dictionary_get_string(value, AUTH_XPC_ITEM_NAME);
+            if (name) {
+                nameLen = strlen(name) + 1;
+                set->items[index].name = calloc(1u, nameLen);
+                require(set->items[index].name != NULL, done);
+                
+                strlcpy((char*)set->items[index].name, name, nameLen);
+            }
+            set->items[index].flags = (uint32_t)xpc_dictionary_get_uint64(value, AUTH_XPC_ITEM_FLAGS);
+            size_t len;
+            const void * valueData = xpc_dictionary_get_data(value, AUTH_XPC_ITEM_VALUE, &len);
+            set->items[index].valueLength = len;
+            if (len) {
+                set->items[index].value = calloc(1u, len);
+                require(set->items[index].value != NULL, done);
+                
+                memcpy(set->items[index].value, valueData, len);
+            }
+        done:
+            return true;
+        });
+    }
+    
+done:
+    if (data != NULL) {
+        xpc_release(data);
+    }
+    return set;
+}
+
+void FreeItemSet(AuthorizationItemSet * itemSet)
+{
+    if (!itemSet) { return; }
+    
+    for(uint32_t i = 0; i < itemSet->count; i++ ) {
+        if (itemSet->items[i].name) {
+            free((void*)itemSet->items[i].name);
+        }
+        if (itemSet->items[i].value) {
+            free(itemSet->items[i].value);
+        }
+    }
+    if (itemSet->items) {
+        free(itemSet->items);
+    }
+
+    free(itemSet);
+}
+
+char *
+_copy_cf_string(CFTypeRef str, const char * defaultValue)
+{
+    char * result = NULL;
+    require(str != NULL, done);   
+    require(CFGetTypeID(str) == CFStringGetTypeID(), done);
+    
+    CFIndex length = CFStringGetLength(str);
+    CFIndex size = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1;
+    
+    result = (char*)calloc(1u, (size_t)size);
+    check(result != NULL);
+    
+    if (!CFStringGetCString(str, result, size, kCFStringEncodingUTF8)) {
+        free_safe(result);
+    }
+    
+done:
+    if (result == NULL && defaultValue) {
+        size_t len = strlen(defaultValue);
+        result = (char*)calloc(1u, len);
+        check(result != NULL);
+        
+        strlcpy(result, defaultValue, len);
+    }
+    
+    return result;
+}
+
+int64_t
+_get_cf_int(CFTypeRef num, int64_t defaultValue)
+{
+    int64_t result = defaultValue;
+    require(num != NULL, done);
+    require(CFGetTypeID(num) == CFNumberGetTypeID(), done);
+    
+    if (!CFNumberGetValue(num, kCFNumberSInt64Type, &result)) {
+        result = defaultValue;
+    }
+    
+done:
+    return result;
+}
+
+bool
+_get_cf_bool(CFTypeRef value, bool defaultValue)
+{
+    bool result = defaultValue;
+    require(value != NULL, done);
+    require(CFGetTypeID(value) == CFBooleanGetTypeID(), done);
+    
+    result = CFBooleanGetValue(value);
+    
+done:
+    return result;
+}
+
+bool
+_compare_string(const char * str1, const char * str2)
+{
+    if (!(str1 == str2)) {  // compare null or same pointer
+        if (str1 && str2) { // check both are non null
+            if (strcasecmp(str1, str2) != 0) { // compare strings
+                return false; // return false if not equal
+            }
+        } else {
+            return false; // return false if one null
+        }
+    }
+    
+    return true;
+}
+
+char *
+_copy_string(const char * str)
+{
+    char * result = NULL;
+    require(str != NULL, done);
+    
+    size_t len = strlen(str) + 1;
+    result = calloc(1u, len);
+    require(result != NULL, done);
+    
+    strlcpy(result, str, len);
+    
+done:
+    return result;
+}
+
+void *
+_copy_data(const void * data, size_t dataLen)
+{
+    void * result = NULL;
+    require(data != NULL, done);
+    
+    result = calloc(1u, dataLen);
+    require(result != NULL, done);
+    
+    memcpy(result, data, dataLen);
+    
+done:
+    return result;
+}
+
+bool _cf_set_iterate(CFSetRef set, bool(^iterator)(CFTypeRef value))
+{
+    bool result = false;
+    CFTypeRef* values = NULL;
+    
+    require(set != NULL, done);
+    
+    CFIndex count = CFSetGetCount(set);
+    values = calloc((size_t)count, sizeof(CFTypeRef));
+    require(values != NULL, done);
+    
+    CFSetGetValues(set, values);
+    for (CFIndex i = 0; i < count; i++) {
+        result = iterator(values[i]);
+        if (!result) {
+            break;
+        }
+    }
+
+done:
+    free_safe(values);
+    return result;
+}
+
+bool _cf_bag_iterate(CFBagRef bag, bool(^iterator)(CFTypeRef value))
+{
+    bool result = false;
+    CFTypeRef* values = NULL;
+
+    require(bag != NULL, done);
+
+    CFIndex count = CFBagGetCount(bag);
+    values = calloc((size_t)count, sizeof(CFTypeRef));
+    require(values != NULL, done);
+
+    CFBagGetValues(bag, values);
+    for (CFIndex i = 0; i < count; i++) {
+        result = iterator(values[i]);
+        if (!result) {
+            break;
+        }
+    }
+
+done:
+    free_safe(values);
+    return result;
+}
+
+bool _cf_dictionary_iterate(CFDictionaryRef dict, bool(^iterator)(CFTypeRef key, CFTypeRef value))
+{
+    bool result = false;
+    CFTypeRef* keys = NULL;
+    CFTypeRef* values = NULL;
+    
+    require(dict != NULL, done);
+    
+    CFIndex count = CFDictionaryGetCount(dict);
+    keys = calloc((size_t)count, sizeof(CFTypeRef));
+    require(keys != NULL, done);
+    
+    values = calloc((size_t)count, sizeof(CFTypeRef));
+    require(values != NULL, done);
+    
+    CFDictionaryGetKeysAndValues(dict, keys, values);
+    for (CFIndex i = 0; i < count; i++) {
+        result = iterator(keys[i], values[i]);
+        if (!result) {
+            break;
+        }
+    }
+
+done:
+    free_safe(keys);
+    free_safe(values);
+    return result;
+}
diff --git a/authd/authutilities.h b/authd/authutilities.h
new file mode 100644 (file)
index 0000000..6d07c9c
--- /dev/null
@@ -0,0 +1,34 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#ifndef _SECURITY_AUTH_UTILITIES_H_
+#define _SECURITY_AUTH_UTILITIES_H_
+
+#include <xpc/xpc.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/Authorization.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+AuthorizationItemSet * DeserializeItemSet(const xpc_object_t);
+xpc_object_t SerializeItemSet(const AuthorizationItemSet*);
+void FreeItemSet(AuthorizationItemSet*);
+
+char * _copy_cf_string(CFTypeRef,const char*);
+int64_t _get_cf_int(CFTypeRef,int64_t);
+bool _get_cf_bool(CFTypeRef,bool);
+
+bool _compare_string(const char *, const char *);
+char * _copy_string(const char *);
+void * _copy_data(const void * data, size_t dataLen);
+
+bool _cf_set_iterate(CFSetRef, bool(^iterator)(CFTypeRef value));
+bool _cf_bag_iterate(CFBagRef, bool(^iterator)(CFTypeRef value));
+bool _cf_dictionary_iterate(CFDictionaryRef, bool(^iterator)(CFTypeRef key,CFTypeRef value));
+    
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_SECURITY_AUTH_UTILITIES_H_ */
diff --git a/authd/ccaudit.c b/authd/ccaudit.c
new file mode 100644 (file)
index 0000000..6914737
--- /dev/null
@@ -0,0 +1,260 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#include "ccaudit.h"
+#include "debugging.h"
+#include "process.h"
+#include "authtoken.h"
+
+#include <Security/Authorization.h>
+#include <Security/AuthorizationPlugin.h>
+#include <bsm/libbsm.h>
+
+
+struct _ccaudit_s {
+    __AUTH_BASE_STRUCT_HEADER__;
+    
+    int fd;
+    int32_t event;
+
+    auth_token_t auth;
+    process_t proc;
+    audit_info_s auditInfo;
+    au_tid_t tid;
+};
+
+static void
+_ccaudit_finalizer(CFTypeRef value)
+{
+    ccaudit_t ccaudit = (ccaudit_t)value;
+
+    CFReleaseSafe(ccaudit->auth);
+    CFReleaseSafe(ccaudit->proc);
+}
+
+AUTH_TYPE_INSTANCE(ccaudit,
+                   .init = NULL,
+                   .copy = NULL,
+                   .finalize = _ccaudit_finalizer,
+                   .equal = NULL,
+                   .hash = NULL,
+                   .copyFormattingDesc = NULL,
+                   .copyDebugDesc = NULL
+                   );
+
+static CFTypeID ccaudit_get_type_id() {
+    static CFTypeID type_id = _kCFRuntimeNotATypeID;
+    static dispatch_once_t onceToken;
+    
+    dispatch_once(&onceToken, ^{
+        type_id = _CFRuntimeRegisterClass(&_auth_type_ccaudit);
+    });
+    
+    return type_id;
+}
+
+ccaudit_t
+ccaudit_create(process_t proc, auth_token_t auth, int32_t event)
+{
+    ccaudit_t ccaudit = NULL;
+
+    require(auth != NULL, done);
+    
+    ccaudit = (ccaudit_t)_CFRuntimeCreateInstance(kCFAllocatorDefault, ccaudit_get_type_id(), AUTH_CLASS_SIZE(ccaudit), NULL);
+    require(ccaudit != NULL, done);
+    
+    ccaudit->auth = (auth_token_t)CFRetain(auth);
+    ccaudit->proc = (process_t)CFRetain(proc);
+    ccaudit->fd = -1;
+    ccaudit->event = event;
+    
+    ccaudit->auditInfo = *auth_token_get_audit_info(auth);
+    ccaudit->tid.port = ccaudit->auditInfo.tid;
+    
+done:
+    return ccaudit;
+}
+
+static bool _enabled()
+{
+    static dispatch_once_t onceToken;
+    static bool enabled = false;
+    
+    dispatch_once(&onceToken, ^{
+        int acond = au_get_state();
+        switch (acond) {
+            case AUC_NOAUDIT:
+                break;
+            case AUC_AUDITING:
+                enabled = true;
+                break;
+            default:
+                LOGE("ccaudit: error checking auditing status (%d)", acond);
+        }
+    });
+
+    return enabled;
+}
+
+static bool _open(ccaudit_t ccaudit)
+{
+    if (!_enabled()) {
+        return false;
+    }
+    
+    if (-1 != ccaudit->fd)
+        return true;
+
+    if ((ccaudit->fd = au_open()) < 0) {
+        LOGE("ccaudit: au_open() failed (%s)", strerror(errno));
+        return false;
+    }
+
+    return true;
+}
+
+static void _close(ccaudit_t ccaudit)
+{
+    if (-1 != ccaudit->fd) {
+        int err = au_close(ccaudit->fd, AU_TO_WRITE, (short)ccaudit->event);
+        ccaudit->fd = -1;
+        if (err < 0) {
+            LOGE("ccaudit: au_close() failed; record not committed");
+        }
+    }
+}
+
+static bool _write(ccaudit_t ccaudit, token_t * token, const char * name)
+{
+    const char *tokenName = name ?  name : "<unidentified>";
+    if (NULL == token)
+    {
+        LOGE("ccaudit: invalid '%s' token", tokenName);
+        return false;
+    }
+    if (au_write(ccaudit->fd, token) < 0) {
+        LOGE("ccaudit: error writing '%s' token (%s)", tokenName, strerror(errno));
+        return false;
+    }
+    return true;
+}
+
+static bool _subject(ccaudit_t ccaudit)
+{
+    token_t * token = au_to_subject32(ccaudit->auditInfo.auid, ccaudit->auditInfo.euid, ccaudit->auditInfo.egid,
+                                      ccaudit->auditInfo.ruid, ccaudit->auditInfo.rgid, ccaudit->auditInfo.pid, ccaudit->auditInfo.asid, &ccaudit->tid);
+    return _write(ccaudit, token, "subject");
+}
+
+void ccaudit_log_authorization(ccaudit_t ccaudit, const char * right, OSStatus err)
+{
+
+    if (!_open(ccaudit)) {
+        return;
+    }
+    char buf[PATH_MAX+1];
+    
+    _subject(ccaudit);
+    _write(ccaudit, au_to_text(right), "right");
+    snprintf(buf, sizeof(buf), "client %s", process_get_code_url(ccaudit->proc));
+    _write(ccaudit, au_to_text(buf), "Authorization client");
+    snprintf(buf, sizeof(buf), "creator %s", auth_token_get_code_url(ccaudit->auth));
+    _write(ccaudit, au_to_text(buf), "Authorization creator");
+    
+    if (auth_token_least_privileged(ccaudit->auth)) {
+        _write(ccaudit, au_to_text("least-privilege"), "least-privilege");
+    }
+    
+    if (err == errAuthorizationSuccess) {
+        _write(ccaudit, au_to_return32(0, 0), "return");
+    } else {
+        _write(ccaudit, au_to_return32(EPERM, (uint32_t)err), "return");
+    }
+    
+    _close(ccaudit);
+}
+
+void ccaudit_log_success(ccaudit_t ccaudit, credential_t cred, const char * right)
+{
+
+    if (!_open(ccaudit)) {
+        return;
+    }
+    char buf[PATH_MAX+1];
+    
+    _subject(ccaudit);
+    _write(ccaudit, au_to_text(right), "right");
+    _write(ccaudit, au_to_arg32(1, "known UID ", auth_token_get_uid(ccaudit->auth)), "authenticator");
+    snprintf(buf, sizeof(buf), "authenticated as %s", credential_get_name(cred));
+    _write(ccaudit, au_to_arg32(2, buf, credential_get_uid(cred)), "target");
+    _write(ccaudit, au_to_return32(0, 0), "return");
+    
+    _close(ccaudit);
+}
+
+void ccaudit_log_failure(ccaudit_t ccaudit, const char * credName, const char * right)
+{
+
+    if (!_open(ccaudit)) {
+        return;
+    }
+    _subject(ccaudit);
+    _write(ccaudit, au_to_text(right), "right");
+    _write(ccaudit, au_to_arg32(1, "authenticated as ", auth_token_get_uid(ccaudit->auth)), "authenticator");
+    
+    if (NULL == credName) {
+        _write(ccaudit, au_to_text("<unknown user>"), "target username");
+    } else {
+        _write(ccaudit, au_to_text(credName), "target username");
+    }
+    _write(ccaudit, au_to_return32(EPERM, (uint32_t)errAuthorizationDenied), "return");
+    
+    _close(ccaudit);
+}
+
+void ccaudit_log_mechanism(ccaudit_t ccaudit, const char * right, const char * mech, uint32_t status, const char * interrupted)
+{
+
+    if (!_open(ccaudit)) {
+        return;
+    }
+    char buf[PATH_MAX+1];
+    
+    _subject(ccaudit);
+    _write(ccaudit, au_to_text(right), "right");
+    snprintf(buf, sizeof(buf), "mechanism %s", mech);
+    _write(ccaudit, au_to_text(buf), "mechanism");
+    
+    if (interrupted) {
+        _write(ccaudit, au_to_text(interrupted), "interrupt");
+    }
+    
+    if (status == kAuthorizationResultAllow) {
+        _write(ccaudit, au_to_return32(0, 0), "return");
+    } else {
+        _write(ccaudit, au_to_return32(EPERM, (uint32_t)status), "return");
+    }
+    
+    _close(ccaudit);
+}
+
+void ccaudit_log(ccaudit_t ccaudit, const char * right, const char * msg, OSStatus err)
+{
+    if (!_open(ccaudit)) {
+        return;
+    }
+    
+    _subject(ccaudit);
+    _write(ccaudit, au_to_text(right), "right");
+    
+    if (msg) {
+        _write(ccaudit, au_to_text(msg), "evaluation error");
+    }
+    
+    if (err == errAuthorizationSuccess) {
+        _write(ccaudit, au_to_return32(0, 0), "return");
+    } else {
+        _write(ccaudit, au_to_return32(EPERM, (uint32_t)err), "return");
+    }
+    
+    _close(ccaudit);
+}
diff --git a/authd/ccaudit.h b/authd/ccaudit.h
new file mode 100644 (file)
index 0000000..1485790
--- /dev/null
@@ -0,0 +1,26 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#ifndef _SECURITY_AUTH_CCAUDIT_H_
+#define _SECURITY_AUTH_CCAUDIT_H_
+
+#include <bsm/audit_uevents.h>
+
+AUTH_WARN_RESULT AUTH_MALLOC AUTH_NONNULL_ALL AUTH_RETURNS_RETAINED
+ccaudit_t ccaudit_create(process_t, auth_token_t, int32_t event);
+
+AUTH_NONNULL_ALL
+void ccaudit_log_authorization(ccaudit_t, const char * right, OSStatus err);
+
+AUTH_NONNULL_ALL
+void ccaudit_log_success(ccaudit_t, credential_t cred, const char * right);
+
+AUTH_NONNULL_ALL
+void ccaudit_log_failure(ccaudit_t, const char * credName, const char * right);
+
+AUTH_NONNULL1
+void ccaudit_log_mechanism(ccaudit_t, const char * right, const char * mech, uint32_t status, const char * interrupted);
+
+AUTH_NONNULL1
+void ccaudit_log(ccaudit_t, const char * right, const char * msg, OSStatus err);
+
+#endif /* !_SECURITY_AUTH_CCAUDIT_H_ */
diff --git a/authd/com.apple.authd b/authd/com.apple.authd
new file mode 100644 (file)
index 0000000..ead3047
--- /dev/null
@@ -0,0 +1,4 @@
+? [= Sender com.apple.authd] claim only
+* file /var/log/authd.log mode=0640 compress format=bsd rotate=seq file_max=5M all_max=20M
+? [<= Level error] file /var/log/system.log
+? [<= Level error] store
diff --git a/authd/com.apple.authd.sb b/authd/com.apple.authd.sb
new file mode 100644 (file)
index 0000000..1d7e29d
--- /dev/null
@@ -0,0 +1,32 @@
+(version 1)
+
+(deny default)
+
+(import "system.sb")
+
+(allow file-ioctl
+       (literal "/dev/auditsessions"))
+
+(allow file-read*)
+
+(allow file-read* file-write*
+       (regex #"^/private/var/db/auth\.db.*$")
+       (literal "/private/var/db/mds/system/mds.lock"))
+
+(allow mach-lookup
+       (global-name "com.apple.CoreServices.coreservicesd")
+       (global-name "com.apple.PowerManagement.control")
+       (global-name "com.apple.security.agentMain")
+       (global-name "com.apple.security.agentStub")
+       (global-name "com.apple.security.authhost")
+       (global-name "com.apple.SecurityServer")
+       (global-name "com.apple.system.opendirectoryd.api")
+       (global-name "com.apple.ocspd"))
+       
+(allow ipc-posix-shm
+       (ipc-posix-name "apple.shm.notification_center")
+       (ipc-posix-name "com.apple.AppleDatabaseChanged"))
+
+(allow mach-per-user-lookup)
+
+(allow system-audit system-sched)
diff --git a/authd/connection.c b/authd/connection.c
new file mode 100644 (file)
index 0000000..1f34d74
--- /dev/null
@@ -0,0 +1,118 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#include "connection.h"
+#include "process.h"
+#include "authdb.h"
+#include "engine.h"
+#include "server.h"
+#include "debugging.h"
+
+struct _connection_s {
+    __AUTH_BASE_STRUCT_HEADER__;
+    
+    process_t proc;
+    engine_t engine;
+    dispatch_queue_t dispatch_queue;
+    dispatch_queue_t dispatch_queue_internal;
+    bool sent_syslog_warn;
+};
+
+static void
+_connection_finalize(CFTypeRef value)
+{
+    connection_t conn = (connection_t)value;
+    
+    process_remove_connection(conn->proc, conn);
+    
+    dispatch_barrier_sync(conn->dispatch_queue, ^{});
+    dispatch_barrier_sync(conn->dispatch_queue_internal, ^{});
+    
+    CFReleaseSafe(conn->proc);
+    CFReleaseNull(conn->engine);
+    dispatch_release(conn->dispatch_queue);
+    dispatch_release(conn->dispatch_queue_internal);
+}
+
+AUTH_TYPE_INSTANCE(connection,
+                   .init = NULL,
+                   .copy = NULL,
+                   .finalize = _connection_finalize,
+                   .equal = NULL,
+                   .hash = NULL,
+                   .copyFormattingDesc = NULL,
+                   .copyDebugDesc = NULL
+                   );
+
+static CFTypeID connection_get_type_id() {
+    static CFTypeID type_id = _kCFRuntimeNotATypeID;
+    static dispatch_once_t onceToken;
+    
+    dispatch_once(&onceToken, ^{
+        type_id = _CFRuntimeRegisterClass(&_auth_type_connection);
+    });
+    
+    return type_id;
+}
+
+connection_t
+connection_create(process_t proc)
+{
+    connection_t conn = NULL;
+    
+    conn = (connection_t)_CFRuntimeCreateInstance(kCFAllocatorDefault, connection_get_type_id(), AUTH_CLASS_SIZE(connection), NULL);
+    require(conn != NULL, done);
+    
+    conn->proc = (process_t)CFRetain(proc);
+    conn->dispatch_queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
+    conn->dispatch_queue_internal = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
+    
+done:
+    return conn;
+}
+
+pid_t connection_get_pid(connection_t conn)
+{
+    return process_get_pid(conn->proc);
+}
+
+process_t connection_get_process(connection_t conn)
+{
+    return conn->proc;
+}
+
+dispatch_queue_t connection_get_dispatch_queue(connection_t conn)
+{
+    return conn->dispatch_queue;
+}
+
+void connection_set_engine(connection_t conn, engine_t engine)
+{
+    dispatch_sync(conn->dispatch_queue_internal, ^{
+        if (engine) {
+            CFReleaseNull(conn->engine);
+            conn->engine = (engine_t)CFRetain(engine);
+        } else {
+            CFReleaseNull(conn->engine);
+        }
+    });
+}
+
+void connection_destory_agents(connection_t conn)
+{
+    dispatch_sync(conn->dispatch_queue_internal, ^{
+        if (conn->engine) {
+            engine_destroy_agents(conn->engine);
+        }
+    });
+}
+
+bool connection_get_syslog_warn(connection_t conn)
+{
+    return conn->sent_syslog_warn;
+}
+
+void connection_set_syslog_warn(connection_t conn)
+{
+    conn->sent_syslog_warn = true;
+}
+
diff --git a/authd/connection.h b/authd/connection.h
new file mode 100644 (file)
index 0000000..f23cc8f
--- /dev/null
@@ -0,0 +1,38 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#ifndef _SECURITY_AUTH_CONNECTION_H_
+#define _SECURITY_AUTH_CONNECTION_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+AUTH_WARN_RESULT AUTH_MALLOC AUTH_NONNULL_ALL AUTH_RETURNS_RETAINED
+connection_t connection_create(process_t);
+
+AUTH_NONNULL_ALL
+pid_t connection_get_pid(connection_t);
+    
+AUTH_NONNULL_ALL
+process_t connection_get_process(connection_t);
+    
+AUTH_NONNULL_ALL
+dispatch_queue_t connection_get_dispatch_queue(connection_t);
+
+AUTH_NONNULL1
+void connection_set_engine(connection_t, engine_t);
+
+AUTH_NONNULL_ALL
+void connection_destory_agents(connection_t);
+
+AUTH_NONNULL_ALL
+bool connection_get_syslog_warn(connection_t);
+
+AUTH_NONNULL_ALL
+void connection_set_syslog_warn(connection_t);
+    
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_SECURITY_AUTH_CONNECTION_H_ */
diff --git a/authd/crc.c b/authd/crc.c
new file mode 100644 (file)
index 0000000..3feadcc
--- /dev/null
@@ -0,0 +1,125 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#include "crc.h"
+
+// G(x): x^64 + x^62 + x^57 + x^55 + x^54 + x^53 + x^52 + x^47 + x^46 + x^45 + x^40 + x^39 +
+//       x^38 + x^37 + x^35 + x^33 + x^32 + x^31 + x^29 + x^27 + x^24 + x^23 + x^22 + x^21 +
+//       x^19 + x^17 + x^13 + x^12 + x^10 + x^9  + x^7  + x^4  + x^1  + 1
+
+//    Mathematically, the CRC value corresponding to the given data is defined by the following proce-
+//    dure:
+//
+//    The n bits to be evaluated are considered to be the coefficients of a mod 2 polynomial
+//    M(x) of degree n-1.  These n bits are the bits from the data, with the most significant
+//    bit being the most significant bit of the first octet of the data and the last bit being
+//    the least significant bit of the last octet, padded with zero bits (if necessary) to
+//    achieve an integral number of octets, followed by one or more octets representing the
+//    length of the data as a binary value, least significant octet first.  The smallest num-
+//    ber of octets capable of representing this integer are used.
+//
+//    M(x) is multiplied by x^64 (i.e., shifted left 56 bits) and divided by G(x) using mod 2
+//    division, producing a remainder R(x) of degree <= 63.
+//
+//    The coefficients of R(x) are considered to be a 64-bit sequence.
+//
+//    The bit sequence is complemented and the result is the CRC.
+
+const uint64_t xorout = 0xffffffffffffffffULL;
+
+// polynomial = 0x42F0E1EBA9EA3693ULL using ECMA-182
+
+const uint64_t _crc_table64[256] = {
+    0x0000000000000000ULL, 0x42f0e1eba9ea3693ULL, 0x85e1c3d753d46d26ULL, 0xc711223cfa3e5bb5ULL,
+    0x493366450e42ecdfULL, 0x0bc387aea7a8da4cULL, 0xccd2a5925d9681f9ULL, 0x8e224479f47cb76aULL,
+    0x9266cc8a1c85d9beULL, 0xd0962d61b56fef2dULL, 0x17870f5d4f51b498ULL, 0x5577eeb6e6bb820bULL,
+    0xdb55aacf12c73561ULL, 0x99a54b24bb2d03f2ULL, 0x5eb4691841135847ULL, 0x1c4488f3e8f96ed4ULL,
+    0x663d78ff90e185efULL, 0x24cd9914390bb37cULL, 0xe3dcbb28c335e8c9ULL, 0xa12c5ac36adfde5aULL,
+    0x2f0e1eba9ea36930ULL, 0x6dfeff5137495fa3ULL, 0xaaefdd6dcd770416ULL, 0xe81f3c86649d3285ULL,
+    0xf45bb4758c645c51ULL, 0xb6ab559e258e6ac2ULL, 0x71ba77a2dfb03177ULL, 0x334a9649765a07e4ULL,
+    0xbd68d2308226b08eULL, 0xff9833db2bcc861dULL, 0x388911e7d1f2dda8ULL, 0x7a79f00c7818eb3bULL,
+    0xcc7af1ff21c30bdeULL, 0x8e8a101488293d4dULL, 0x499b3228721766f8ULL, 0x0b6bd3c3dbfd506bULL,
+    0x854997ba2f81e701ULL, 0xc7b97651866bd192ULL, 0x00a8546d7c558a27ULL, 0x4258b586d5bfbcb4ULL,
+    0x5e1c3d753d46d260ULL, 0x1cecdc9e94ace4f3ULL, 0xdbfdfea26e92bf46ULL, 0x990d1f49c77889d5ULL,
+    0x172f5b3033043ebfULL, 0x55dfbadb9aee082cULL, 0x92ce98e760d05399ULL, 0xd03e790cc93a650aULL,
+    0xaa478900b1228e31ULL, 0xe8b768eb18c8b8a2ULL, 0x2fa64ad7e2f6e317ULL, 0x6d56ab3c4b1cd584ULL,
+    0xe374ef45bf6062eeULL, 0xa1840eae168a547dULL, 0x66952c92ecb40fc8ULL, 0x2465cd79455e395bULL,
+    0x3821458aada7578fULL, 0x7ad1a461044d611cULL, 0xbdc0865dfe733aa9ULL, 0xff3067b657990c3aULL,
+    0x711223cfa3e5bb50ULL, 0x33e2c2240a0f8dc3ULL, 0xf4f3e018f031d676ULL, 0xb60301f359dbe0e5ULL,
+    0xda050215ea6c212fULL, 0x98f5e3fe438617bcULL, 0x5fe4c1c2b9b84c09ULL, 0x1d14202910527a9aULL,
+    0x93366450e42ecdf0ULL, 0xd1c685bb4dc4fb63ULL, 0x16d7a787b7faa0d6ULL, 0x5427466c1e109645ULL,
+    0x4863ce9ff6e9f891ULL, 0x0a932f745f03ce02ULL, 0xcd820d48a53d95b7ULL, 0x8f72eca30cd7a324ULL,
+    0x0150a8daf8ab144eULL, 0x43a04931514122ddULL, 0x84b16b0dab7f7968ULL, 0xc6418ae602954ffbULL,
+    0xbc387aea7a8da4c0ULL, 0xfec89b01d3679253ULL, 0x39d9b93d2959c9e6ULL, 0x7b2958d680b3ff75ULL,
+    0xf50b1caf74cf481fULL, 0xb7fbfd44dd257e8cULL, 0x70eadf78271b2539ULL, 0x321a3e938ef113aaULL,
+    0x2e5eb66066087d7eULL, 0x6cae578bcfe24bedULL, 0xabbf75b735dc1058ULL, 0xe94f945c9c3626cbULL,
+    0x676dd025684a91a1ULL, 0x259d31cec1a0a732ULL, 0xe28c13f23b9efc87ULL, 0xa07cf2199274ca14ULL,
+    0x167ff3eacbaf2af1ULL, 0x548f120162451c62ULL, 0x939e303d987b47d7ULL, 0xd16ed1d631917144ULL,
+    0x5f4c95afc5edc62eULL, 0x1dbc74446c07f0bdULL, 0xdaad56789639ab08ULL, 0x985db7933fd39d9bULL,
+    0x84193f60d72af34fULL, 0xc6e9de8b7ec0c5dcULL, 0x01f8fcb784fe9e69ULL, 0x43081d5c2d14a8faULL,
+    0xcd2a5925d9681f90ULL, 0x8fdab8ce70822903ULL, 0x48cb9af28abc72b6ULL, 0x0a3b7b1923564425ULL,
+    0x70428b155b4eaf1eULL, 0x32b26afef2a4998dULL, 0xf5a348c2089ac238ULL, 0xb753a929a170f4abULL,
+    0x3971ed50550c43c1ULL, 0x7b810cbbfce67552ULL, 0xbc902e8706d82ee7ULL, 0xfe60cf6caf321874ULL,
+    0xe224479f47cb76a0ULL, 0xa0d4a674ee214033ULL, 0x67c58448141f1b86ULL, 0x253565a3bdf52d15ULL,
+    0xab1721da49899a7fULL, 0xe9e7c031e063acecULL, 0x2ef6e20d1a5df759ULL, 0x6c0603e6b3b7c1caULL,
+    0xf6fae5c07d3274cdULL, 0xb40a042bd4d8425eULL, 0x731b26172ee619ebULL, 0x31ebc7fc870c2f78ULL,
+    0xbfc9838573709812ULL, 0xfd39626eda9aae81ULL, 0x3a28405220a4f534ULL, 0x78d8a1b9894ec3a7ULL,
+    0x649c294a61b7ad73ULL, 0x266cc8a1c85d9be0ULL, 0xe17dea9d3263c055ULL, 0xa38d0b769b89f6c6ULL,
+    0x2daf4f0f6ff541acULL, 0x6f5faee4c61f773fULL, 0xa84e8cd83c212c8aULL, 0xeabe6d3395cb1a19ULL,
+    0x90c79d3fedd3f122ULL, 0xd2377cd44439c7b1ULL, 0x15265ee8be079c04ULL, 0x57d6bf0317edaa97ULL,
+    0xd9f4fb7ae3911dfdULL, 0x9b041a914a7b2b6eULL, 0x5c1538adb04570dbULL, 0x1ee5d94619af4648ULL,
+    0x02a151b5f156289cULL, 0x4051b05e58bc1e0fULL, 0x87409262a28245baULL, 0xc5b073890b687329ULL,
+    0x4b9237f0ff14c443ULL, 0x0962d61b56fef2d0ULL, 0xce73f427acc0a965ULL, 0x8c8315cc052a9ff6ULL,
+    0x3a80143f5cf17f13ULL, 0x7870f5d4f51b4980ULL, 0xbf61d7e80f251235ULL, 0xfd913603a6cf24a6ULL,
+    0x73b3727a52b393ccULL, 0x31439391fb59a55fULL, 0xf652b1ad0167feeaULL, 0xb4a25046a88dc879ULL,
+    0xa8e6d8b54074a6adULL, 0xea16395ee99e903eULL, 0x2d071b6213a0cb8bULL, 0x6ff7fa89ba4afd18ULL,
+    0xe1d5bef04e364a72ULL, 0xa3255f1be7dc7ce1ULL, 0x64347d271de22754ULL, 0x26c49cccb40811c7ULL,
+    0x5cbd6cc0cc10fafcULL, 0x1e4d8d2b65facc6fULL, 0xd95caf179fc497daULL, 0x9bac4efc362ea149ULL,
+    0x158e0a85c2521623ULL, 0x577eeb6e6bb820b0ULL, 0x906fc95291867b05ULL, 0xd29f28b9386c4d96ULL,
+    0xcedba04ad0952342ULL, 0x8c2b41a1797f15d1ULL, 0x4b3a639d83414e64ULL, 0x09ca82762aab78f7ULL,
+    0x87e8c60fded7cf9dULL, 0xc51827e4773df90eULL, 0x020905d88d03a2bbULL, 0x40f9e43324e99428ULL,
+    0x2cffe7d5975e55e2ULL, 0x6e0f063e3eb46371ULL, 0xa91e2402c48a38c4ULL, 0xebeec5e96d600e57ULL,
+    0x65cc8190991cb93dULL, 0x273c607b30f68faeULL, 0xe02d4247cac8d41bULL, 0xa2dda3ac6322e288ULL,
+    0xbe992b5f8bdb8c5cULL, 0xfc69cab42231bacfULL, 0x3b78e888d80fe17aULL, 0x7988096371e5d7e9ULL,
+    0xf7aa4d1a85996083ULL, 0xb55aacf12c735610ULL, 0x724b8ecdd64d0da5ULL, 0x30bb6f267fa73b36ULL,
+    0x4ac29f2a07bfd00dULL, 0x08327ec1ae55e69eULL, 0xcf235cfd546bbd2bULL, 0x8dd3bd16fd818bb8ULL,
+    0x03f1f96f09fd3cd2ULL, 0x41011884a0170a41ULL, 0x86103ab85a2951f4ULL, 0xc4e0db53f3c36767ULL,
+    0xd8a453a01b3a09b3ULL, 0x9a54b24bb2d03f20ULL, 0x5d45907748ee6495ULL, 0x1fb5719ce1045206ULL,
+    0x919735e51578e56cULL, 0xd367d40ebc92d3ffULL, 0x1476f63246ac884aULL, 0x568617d9ef46bed9ULL,
+    0xe085162ab69d5e3cULL, 0xa275f7c11f7768afULL, 0x6564d5fde549331aULL, 0x279434164ca30589ULL,
+    0xa9b6706fb8dfb2e3ULL, 0xeb46918411358470ULL, 0x2c57b3b8eb0bdfc5ULL, 0x6ea7525342e1e956ULL,
+    0x72e3daa0aa188782ULL, 0x30133b4b03f2b111ULL, 0xf7021977f9cceaa4ULL, 0xb5f2f89c5026dc37ULL,
+    0x3bd0bce5a45a6b5dULL, 0x79205d0e0db05dceULL, 0xbe317f32f78e067bULL, 0xfcc19ed95e6430e8ULL,
+    0x86b86ed5267cdbd3ULL, 0xc4488f3e8f96ed40ULL, 0x0359ad0275a8b6f5ULL, 0x41a94ce9dc428066ULL,
+    0xcf8b0890283e370cULL, 0x8d7be97b81d4019fULL, 0x4a6acb477bea5a2aULL, 0x089a2aacd2006cb9ULL,
+    0x14dea25f3af9026dULL, 0x562e43b4931334feULL, 0x913f6188692d6f4bULL, 0xd3cf8063c0c759d8ULL,
+    0x5dedc41a34bbeeb2ULL, 0x1f1d25f19d51d821ULL, 0xd80c07cd676f8394ULL, 0x9afce626ce85b507ULL
+};
+
+////uint64_t poly = 0xA17870F5D4F51B49ULL; // reverse of reciprocal
+////uint64_t poly = 0xC96C5795D7870F42ULL; // reverse
+//uint64_t poly = 0x42F0E1EBA9EA3693ULL; // normal
+
+//uint64_t table[256];
+
+//void generate_table()
+//{
+//    printf("static const uint64_t _crc_table64[256] = {\n");
+//    
+//    for(uint64_t i=0; i<256; ++i)
+//    {
+//     uint64_t crc = i << 56;
+//        
+//        int bits = 8 + 1;
+//        while (--bits) {
+//            crc = (crc & 0x8000000000000000ULL) ? (crc << 1) ^ poly : (crc << 1);
+//     }
+//        
+//        //table[i] = crc;
+//        printf(" ");
+//        printf("0x%016llxULL", crc);
+//        if (i != 255) printf(",");
+//        if ((i+1) % 4 == 0) printf("\n");
+//    }
+//    
+//    printf("};\n");
+//}
diff --git a/authd/crc.h b/authd/crc.h
new file mode 100644 (file)
index 0000000..3459678
--- /dev/null
@@ -0,0 +1,53 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#ifndef _SECURITY_AUTH_CRC_H_
+#define _SECURITY_AUTH_CRC_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+extern const uint64_t _crc_table64[256];
+extern const uint64_t xorout;
+    
+AUTH_INLINE uint64_t
+crc64_init()
+{
+    return xorout;
+}
+
+AUTH_INLINE uint64_t
+crc64_final(uint64_t crc)
+{
+      return crc ^= xorout;
+}
+    
+AUTH_INLINE AUTH_NONNULL_ALL uint64_t
+crc64_update(uint64_t crc, const void *buf, uint64_t len)
+{
+    const unsigned char * ptr = (const unsigned char *) buf;
+
+    while (len-- > 0) {
+        crc = _crc_table64[((crc >> 56) ^ *(ptr++)) & 0xff] ^ (crc << 8);
+    }
+    
+    return crc;
+}
+
+AUTH_INLINE uint64_t
+crc64(const void *buf, uint64_t len)
+{
+    uint64_t crc = crc64_init();
+    
+    crc = crc64_update(crc, buf, len);
+    
+    crc = crc64_final(crc);
+    
+    return crc;
+}
+    
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_SECURITY_AUTH_CRC_H_ */
diff --git a/authd/credential.c b/authd/credential.c
new file mode 100644 (file)
index 0000000..bbfaae1
--- /dev/null
@@ -0,0 +1,263 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#include "credential.h"
+#include "authutilities.h"
+#include "debugging.h"
+#include "crc.h"
+
+#include <pwd.h>
+#include <membership.h>
+#include <membershipPriv.h>
+
+struct _credential_s {
+    __AUTH_BASE_STRUCT_HEADER__;
+
+    bool right;   // is least-privileged credential
+    
+    uid_t uid;
+    char * name;
+    char * realName;
+    
+    CFAbsoluteTime creationTime;
+    bool valid;
+    bool shared;
+    
+    CFMutableSetRef cachedGroups;
+};
+
+static void
+_credential_finalize(CFTypeRef value)
+{
+    credential_t cred = (credential_t)value;
+    
+    free_safe(cred->name);
+    free_safe(cred->realName);
+    CFReleaseSafe(cred->cachedGroups);
+}
+
+static CFStringRef
+_credential_copy_description(CFTypeRef value)
+{
+    credential_t cred = (credential_t)value;
+    CFStringRef str = NULL;
+    CFTimeZoneRef sys_tz = CFTimeZoneCopySystem();
+    CFGregorianDate date = CFAbsoluteTimeGetGregorianDate(cred->creationTime, sys_tz);
+    CFReleaseSafe(sys_tz);
+    if (cred->right) {
+        str = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("credential: right=%s, shared=%i, creation=%01i:%01i:%01i, valid=%i"), cred->name, cred->shared, date.hour,date.minute,(int32_t)date.second, cred->valid);
+    } else {
+        str = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("credential: uid=%i, name=%s, shared=%i, creation=%01i:%01i:%01i valid=%i"), cred->uid, cred->name, cred->shared, date.hour,date.minute,(int32_t)date.second, cred->valid);
+    }
+    return str;
+}
+
+static CFHashCode
+_credential_hash(CFTypeRef value)
+{
+    credential_t cred = (credential_t)value;
+    uint64_t crc = crc64_init();
+    if (cred->right) {
+        crc = crc64_update(crc, cred->name, strlen(cred->name));
+    } else {
+        crc = crc64_update(crc, &cred->uid, sizeof(cred->uid));
+    }
+    crc = crc64_update(crc, &cred->shared, sizeof(cred->shared));
+    crc = crc64_final(crc);
+    
+    return crc;
+}
+
+static Boolean
+_credential_equal(CFTypeRef value1, CFTypeRef value2)
+{
+    credential_t cred1 = (credential_t)value1;
+    credential_t cred2 = (credential_t)value2;
+    
+    return _credential_hash(cred1) == _credential_hash(cred2);
+}
+
+AUTH_TYPE_INSTANCE(credential,
+                   .init = NULL,
+                   .copy = NULL,
+                   .finalize = _credential_finalize,
+                   .equal = _credential_equal,
+                   .hash = _credential_hash,
+                   .copyFormattingDesc = NULL,
+                   .copyDebugDesc = _credential_copy_description
+                   );
+
+static CFTypeID credential_get_type_id() {
+    static CFTypeID type_id = _kCFRuntimeNotATypeID;
+    static dispatch_once_t onceToken;
+    
+    dispatch_once(&onceToken, ^{
+        type_id = _CFRuntimeRegisterClass(&_auth_type_credential);
+    });
+    
+    return type_id;
+}
+
+static credential_t
+_credential_create()
+{
+    credential_t cred = NULL;
+    
+    cred = (credential_t)_CFRuntimeCreateInstance(kCFAllocatorDefault, credential_get_type_id(), AUTH_CLASS_SIZE(credential), NULL);
+    require(cred != NULL, done);
+    
+    cred->creationTime = CFAbsoluteTimeGetCurrent();
+    cred->cachedGroups = CFSetCreateMutable(kCFAllocatorDefault, 0, &kCFTypeSetCallBacks);;
+    
+done:
+    return cred;
+}
+
+credential_t
+credential_create(uid_t uid)
+{
+    credential_t cred = NULL;
+    
+    cred = _credential_create();
+    require(cred != NULL, done);
+
+    struct passwd *pw = getpwuid(uid);
+       if (pw != NULL) {
+        // avoid hinting a locked account
+               if ( (pw->pw_passwd == NULL) || strcmp(pw->pw_passwd, "*") ) {
+            cred->uid = pw->pw_uid;
+            cred->name = _copy_string(pw->pw_name);
+            cred->realName = _copy_string(pw->pw_gecos);
+            cred->valid = true;
+        } else {
+            cred->uid = (uid_t)-2;
+            cred->valid = false;
+        }
+        endpwent();
+    }
+    
+done:
+    return cred;
+}
+
+credential_t
+credential_create_with_credential(credential_t srcCred, bool shared)
+{
+    credential_t cred = NULL;
+    
+    cred = _credential_create();
+    require(cred != NULL, done);
+    
+    cred->uid = srcCred->uid;
+    cred->name = _copy_string(srcCred->name);
+    cred->realName = _copy_string(srcCred->realName);
+    cred->valid = srcCred->valid;
+    cred->right = srcCred->right;
+    cred->shared = shared;
+    
+done:
+    return cred;
+}
+
+credential_t
+credential_create_with_right(const char * right)
+{
+    credential_t cred = NULL;
+    
+    cred = _credential_create();
+    require(cred != NULL, done);
+    
+    cred->right = true;
+    cred->name = _copy_string(right);
+    cred->uid = (uid_t)-2;
+    cred->valid = true;
+    
+done:
+    return cred;
+}
+
+uid_t
+credential_get_uid(credential_t cred)
+{
+    return cred->uid;
+}
+
+const char *
+credential_get_name(credential_t cred)
+{
+    return cred->name;
+}
+
+const char *
+credential_get_realname(credential_t cred)
+{
+    return cred->realName;
+}
+
+CFAbsoluteTime
+credential_get_creation_time(credential_t cred)
+{
+    return cred->creationTime;
+}
+
+bool
+credential_get_valid(credential_t cred)
+{
+    return cred->valid;
+}
+
+bool
+credential_get_shared(credential_t cred)
+{
+    return cred->shared;
+}
+
+bool
+credential_is_right(credential_t cred)
+{
+    return cred->right;
+}
+
+bool
+credential_check_membership(credential_t cred,const char* group)
+{
+    bool result = false;
+    CFStringRef cachedGroup = NULL;
+    require(group != NULL, done);
+    require(cred->uid != 0 || cred->uid != (uid_t)-2, done);
+    require(cred->right != true, done);
+    
+    cachedGroup = CFStringCreateWithCString(kCFAllocatorDefault, group, kCFStringEncodingUTF8);
+    require(cachedGroup != NULL, done);
+    
+    if (CFSetGetValue(cred->cachedGroups, cachedGroup) != NULL) {
+        result = true;
+        goto done;
+    }
+    
+    int rc, ismember;
+    uuid_t group_uuid, user_uuid;
+    rc = mbr_group_name_to_uuid(group, group_uuid);
+    require_noerr(rc, done);
+    
+    rc = mbr_uid_to_uuid(cred->uid, user_uuid);
+    require_noerr(rc, done);
+    
+    rc = mbr_check_membership(user_uuid, group_uuid, &ismember);
+    require_noerr(rc, done);
+    
+    result = ismember;
+    
+    if (ismember) {
+        CFSetSetValue(cred->cachedGroups, cachedGroup);
+    }
+
+done:
+    CFReleaseSafe(cachedGroup);
+    return result;
+}
+
+void
+credential_invalidate(credential_t cred)
+{
+    cred->valid = false;
+}
diff --git a/authd/credential.h b/authd/credential.h
new file mode 100644 (file)
index 0000000..eb25b45
--- /dev/null
@@ -0,0 +1,54 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#ifndef _SECURITY_AUTH_CREDENTIAL_H_
+#define _SECURITY_AUTH_CREDENTIAL_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#ifdef __BLOCKS__
+    typedef bool (^credential_iterator_t)(credential_t);
+#endif /* __BLOCKS__ */
+    
+AUTH_WARN_RESULT AUTH_MALLOC AUTH_NONNULL_ALL AUTH_RETURNS_RETAINED
+credential_t credential_create(uid_t);
+
+AUTH_WARN_RESULT AUTH_MALLOC AUTH_NONNULL_ALL AUTH_RETURNS_RETAINED    
+credential_t credential_create_with_credential(credential_t,bool);
+    
+AUTH_WARN_RESULT AUTH_MALLOC AUTH_NONNULL_ALL AUTH_RETURNS_RETAINED    
+credential_t credential_create_with_right(const char *);
+
+AUTH_NONNULL_ALL
+uid_t credential_get_uid(credential_t);
+
+AUTH_NONNULL_ALL
+const char * credential_get_name(credential_t);
+
+AUTH_NONNULL_ALL
+const char * credential_get_realname(credential_t);
+    
+AUTH_NONNULL_ALL
+CFAbsoluteTime credential_get_creation_time(credential_t);
+    
+AUTH_NONNULL_ALL
+bool credential_get_valid(credential_t);
+
+AUTH_NONNULL_ALL    
+bool credential_get_shared(credential_t);
+    
+AUTH_NONNULL_ALL
+bool credential_is_right(credential_t);
+
+AUTH_NONNULL_ALL    
+bool credential_check_membership(credential_t,const char*);
+    
+AUTH_NONNULL_ALL
+void credential_invalidate(credential_t);
+    
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_SECURITY_AUTH_CREDENTIAL_H_ */
diff --git a/authd/debugging.c b/authd/debugging.c
new file mode 100644 (file)
index 0000000..beb0803
--- /dev/null
@@ -0,0 +1,75 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#include "debugging.h"
+#include "authd_private.h"
+#include "authutilities.h"
+#include <stdarg.h>
+#include <syslog.h>
+#include <dispatch/dispatch.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+// sudo defaults write /Library/Preferences/com.apple.security.coderequirements Entitlements -string always
+
+static bool
+security_auth_verbose(void)
+{
+    static dispatch_once_t onceToken;
+    static bool verbose_enabled = false;
+    
+    //sudo defaults write /Library/Preferences/com.apple.authd verbose -bool true
+    dispatch_once(&onceToken, ^{
+               CFTypeRef verbose = (CFNumberRef)CFPreferencesCopyValue(CFSTR("verbose"), CFSTR(SECURITY_AUTH_NAME), kCFPreferencesAnyUser, kCFPreferencesCurrentHost);
+        
+        if (verbose && CFGetTypeID(verbose) == CFBooleanGetTypeID()) {
+            verbose_enabled = CFBooleanGetValue((CFBooleanRef)verbose);
+        }
+#if DEBUG
+        syslog(LOG_NOTICE, "verbose: %s", verbose_enabled ? "enabled" : "disabled");
+#endif
+        CFReleaseSafe(verbose);
+    });
+    
+    return verbose_enabled;
+}
+
+void
+security_auth_log(int type,const char * format,...)
+{
+    va_list ap;
+    va_start(ap, format);
+    switch (type) {
+        case AUTH_LOG_NORMAL:
+            vsyslog(LOG_NOTICE, format, ap);
+            break;
+        case AUTH_LOG_VERBOSE:
+            if (security_auth_verbose()) {
+                vsyslog(LOG_NOTICE, format, ap);
+            }
+            break;
+        case AUTH_LOG_ERROR:
+            vsyslog(LOG_ERR, format, ap);
+            break;
+        default:
+            break;
+    }
+    va_end(ap);
+}
+
+void _show_cf(CFTypeRef value)
+{
+    CFStringRef string = NULL;
+    char * tmp = NULL;
+    require(value != NULL, done);
+    
+    if (security_auth_verbose()) {
+        string = CFCopyDescription(value);
+        tmp = _copy_cf_string(string, NULL);
+        
+        syslog(LOG_NOTICE, "%s", tmp);
+    }
+    
+done:
+    CFReleaseSafe(string);
+    free_safe(tmp);
+    return;
+}
diff --git a/authd/debugging.h b/authd/debugging.h
new file mode 100644 (file)
index 0000000..07a3e1c
--- /dev/null
@@ -0,0 +1,41 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#ifndef _SECURITY_AUTH_DEBUGGING_H_
+#define _SECURITY_AUTH_DEBUGGING_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+enum {
+    AUTH_LOG_NORMAL,
+    AUTH_LOG_VERBOSE,
+    AUTH_LOG_ERROR
+};
+    
+#define LOG(...) security_auth_log(AUTH_LOG_NORMAL, ##__VA_ARGS__)
+#define LOGV(...) security_auth_log(AUTH_LOG_VERBOSE, ##__VA_ARGS__)
+#define LOGE(...) security_auth_log(AUTH_LOG_ERROR, ##__VA_ARGS__)
+#if DEBUG
+#define LOGD(...) security_auth_log(AUTH_LOG_VERBOSE, ##__VA_ARGS__)
+#else
+#define LOGD(...) 
+#endif
+    
+void security_auth_log(int,const char *,...) __printflike(2, 3);
+
+#define CFReleaseSafe(CF) { CFTypeRef _cf = (CF); if (_cf) CFRelease(_cf); }
+#define CFReleaseNull(CF) { CFTypeRef _cf = (CF); \
+    if (_cf) { (CF) = NULL; CFRelease(_cf); } }
+#define CFRetainSafe(CF) { CFTypeRef _cf = (CF); if (_cf) CFRetain(_cf); }
+    
+#define xpc_release_safe(obj)  if (obj) { xpc_release(obj); obj = NULL; }
+#define free_safe(obj)  if (obj) { free(obj); obj = NULL; }
+
+void _show_cf(CFTypeRef);
+    
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_SECURITY_AUTH_DEBUGGING_H_ */
diff --git a/authd/en.lproj/InfoPlist.strings b/authd/en.lproj/InfoPlist.strings
new file mode 100644 (file)
index 0000000..477b28f
--- /dev/null
@@ -0,0 +1,2 @@
+/* Localized versions of Info.plist keys */
+
diff --git a/authd/engine.c b/authd/engine.c
new file mode 100644 (file)
index 0000000..0223192
--- /dev/null
@@ -0,0 +1,1294 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#include "engine.h"
+#include "rule.h"
+#include "authitems.h"
+#include "authtoken.h"
+#include "agent.h"
+#include "process.h"
+#include "debugging.h"
+#include "server.h"
+#include "credential.h"
+#include "session.h"
+#include "mechanism.h"
+#include "authutilities.h"
+#include "ccaudit.h"
+#include "connection.h"
+
+#include <pwd.h>
+#include <Security/checkpw.h>
+int checkpw_internal( const struct passwd *pw, const char* password );
+
+#include <Security/AuthorizationTags.h>
+#include <Security/AuthorizationTagsPriv.h>
+#include <Security/AuthorizationPlugin.h>
+#include <sandbox.h>
+
+static void _set_process_hints(auth_items_t, process_t);
+static void _set_process_immutable_hints(auth_items_t, process_t);
+static void _set_auth_token_hints(auth_items_t, auth_token_t);
+static OSStatus _evaluate_user_credential_for_rule(engine_t, credential_t, rule_t, bool, bool, enum Reason *);
+static void _engine_set_credential(engine_t, credential_t, bool);
+static OSStatus _evaluate_rule(engine_t, rule_t);
+
+enum {
+    kEngineHintsFlagTemporary = (1 << 30)
+};
+
+#pragma mark -
+#pragma mark engine creation
+
+struct _engine_s {
+    __AUTH_BASE_STRUCT_HEADER__;
+    
+    connection_t conn;
+    process_t proc;
+    auth_token_t auth;
+    
+    AuthorizationFlags flags;
+    auth_items_t hints;
+    auth_items_t context;
+    auth_items_t sticky_context;
+    auth_items_t immutable_hints;
+    
+    auth_rights_t grantedRights;
+    
+    enum Reason reason;
+    int32_t tries;
+    
+    CFAbsoluteTime now;
+    
+    credential_t sessionCredential;
+    CFMutableSetRef credentials;
+    CFMutableSetRef effectiveCredentials;
+    
+    CFMutableDictionaryRef mechanism_agents;
+    
+    // set only in engine_authorize
+    const char * currentRightName; // weak ref
+    rule_t currentRule; // weak ref
+    
+    rule_t authenticateRule;
+    
+    bool dismissed;
+};
+
+static void
+_engine_finalizer(CFTypeRef value)
+{
+    engine_t engine = (engine_t)value;
+    
+    CFReleaseSafe(engine->mechanism_agents);
+    CFReleaseSafe(engine->conn);
+    CFReleaseSafe(engine->auth);
+    CFReleaseSafe(engine->hints);
+    CFReleaseSafe(engine->context);
+    CFReleaseSafe(engine->immutable_hints);
+    CFReleaseSafe(engine->sticky_context);
+    CFReleaseSafe(engine->grantedRights);
+    CFReleaseSafe(engine->sessionCredential);
+    CFReleaseSafe(engine->credentials);
+    CFReleaseSafe(engine->effectiveCredentials);
+    CFReleaseSafe(engine->authenticateRule);
+}
+
+AUTH_TYPE_INSTANCE(engine,
+                   .init = NULL,
+                   .copy = NULL,
+                   .finalize = _engine_finalizer,
+                   .equal = NULL,
+                   .hash = NULL,
+                   .copyFormattingDesc = NULL,
+                   .copyDebugDesc = NULL
+                   );
+
+static CFTypeID engine_get_type_id() {
+    static CFTypeID type_id = _kCFRuntimeNotATypeID;
+    static dispatch_once_t onceToken;
+    
+    dispatch_once(&onceToken, ^{
+        type_id = _CFRuntimeRegisterClass(&_auth_type_engine);
+    });
+    
+    return type_id;
+}
+
+engine_t
+engine_create(connection_t conn, auth_token_t auth)
+{
+    engine_t engine = NULL;
+    require(conn != NULL, done);
+    require(auth != NULL, done);
+
+    engine = (engine_t)_CFRuntimeCreateInstance(kCFAllocatorDefault, engine_get_type_id(), AUTH_CLASS_SIZE(engine), NULL);
+    require(engine != NULL, done);
+    
+    engine->conn = (connection_t)CFRetain(conn);
+    engine->proc = connection_get_process(conn);
+    engine->auth = (auth_token_t)CFRetain(auth);
+    
+    engine->hints = auth_items_create();
+    engine->context = auth_items_create();
+    engine->immutable_hints = auth_items_create();
+    engine->sticky_context = auth_items_create();
+    _set_process_hints(engine->hints, engine->proc);
+    _set_process_immutable_hints(engine->immutable_hints, engine->proc);
+    _set_auth_token_hints(engine->hints, auth);
+    
+    engine->grantedRights = auth_rights_create();
+    
+    engine->reason = noReason;
+    
+    engine->now = CFAbsoluteTimeGetCurrent();
+    
+    session_update(auth_token_get_session(engine->auth));
+    engine->sessionCredential = credential_create(session_get_uid(auth_token_get_session(engine->auth)));
+    engine->credentials = CFSetCreateMutable(kCFAllocatorDefault, 0, &kCFTypeSetCallBacks);
+    engine->effectiveCredentials = CFSetCreateMutable(kCFAllocatorDefault, 0, &kCFTypeSetCallBacks);
+    
+    session_credentials_iterate(auth_token_get_session(engine->auth), ^bool(credential_t cred) {
+        CFSetAddValue(engine->effectiveCredentials, cred);
+        return true;
+    });
+    
+    auth_token_credentials_iterate(engine->auth, ^bool(credential_t cred) {
+        // we added all session credentials already now just add all previously acquired credentials
+        if (!credential_get_shared(cred)) {
+            CFSetAddValue(engine->credentials, cred);
+        }
+        return true;
+    });
+    
+    engine->mechanism_agents = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    
+done:
+    return engine;
+}
+
+#pragma mark -
+#pragma mark agent hints
+
+void
+_set_process_hints(auth_items_t hints, process_t proc)
+{
+    // process information
+    RequestorType type = bundle;
+    auth_items_set_data(hints, AGENT_HINT_CLIENT_TYPE, &type, sizeof(type));
+    auth_items_set_int(hints, AGENT_HINT_CLIENT_PID, process_get_pid(proc));
+    auth_items_set_uint(hints, AGENT_HINT_CLIENT_UID, process_get_uid(proc));
+}
+
+void
+_set_process_immutable_hints(auth_items_t immutable_hints, process_t proc)
+{
+    // process information - immutable
+    auth_items_set_bool(immutable_hints, AGENT_HINT_PROCESS_SIGNED, process_apple_signed(proc));
+}
+
+void
+_set_auth_token_hints(auth_items_t hints, auth_token_t auth)
+{
+    auth_items_set_string(hints, AGENT_HINT_CLIENT_PATH, auth_token_get_code_url(auth));
+    auth_items_set_int(hints, AGENT_HINT_CREATOR_PID, auth_token_get_pid(auth));
+    const audit_info_s * info = auth_token_get_audit_info(auth);
+    auth_items_set_data(hints, AGENT_HINT_CREATOR_AUDIT_TOKEN, &info->opaqueToken, sizeof(info->opaqueToken));
+}
+
+static void
+_set_right_hints(auth_items_t hints, const char * right)
+{
+   auth_items_set_string(hints, AGENT_HINT_AUTHORIZE_RIGHT, right);
+}
+
+static void
+_set_rule_hints(auth_items_t hints, rule_t rule)
+{
+    auth_items_set_string(hints, AGENT_HINT_AUTHORIZE_RULE, rule_get_name(rule));
+    const char * group = rule_get_group(rule);
+    if (rule_get_class(rule) == RC_USER && group != NULL) {
+        auth_items_set_string(hints, AGENT_HINT_REQUIRE_USER_IN_GROUP, group);
+    } else {
+        auth_items_remove(hints, AGENT_HINT_REQUIRE_USER_IN_GROUP);
+    }
+}
+
+static void
+_set_localization_hints(authdb_connection_t dbconn, auth_items_t hints, rule_t rule)
+{
+    char * key = calloc(1u, 128);
+
+    authdb_step(dbconn, "SELECT lang,value FROM prompts WHERE r_id = ?", ^(sqlite3_stmt *stmt) {
+        sqlite3_bind_int64(stmt, 1, rule_get_id(rule));
+    }, ^bool(auth_items_t data) {
+        snprintf(key, 128, "%s%s", kAuthorizationRuleParameterDescription, auth_items_get_string(data, "lang"));
+        auth_items_set_string(hints, key, auth_items_get_string(data, "value"));
+        auth_items_set_flags(hints, key, kEngineHintsFlagTemporary);
+        return true;
+    });
+
+    authdb_step(dbconn, "SELECT lang,value FROM buttons WHERE r_id = ?", ^(sqlite3_stmt *stmt) {
+        sqlite3_bind_int64(stmt, 1, rule_get_id(rule));
+    }, ^bool(auth_items_t data) {
+        snprintf(key, 128, "%s%s", kAuthorizationRuleParameterButton, auth_items_get_string(data, "lang"));
+        auth_items_set_string(hints, key, auth_items_get_string(data, "value"));
+        auth_items_set_flags(hints, key, kEngineHintsFlagTemporary);
+        return true;
+    });
+
+    free_safe(key);
+}
+
+static void
+_set_session_hints(engine_t engine, rule_t rule)
+{
+    LOGV("engine[%i]: ** prepare agent hints for rule %s", connection_get_pid(engine->conn), rule_get_name(rule));
+    if (_evaluate_user_credential_for_rule(engine, engine->sessionCredential, rule, true, true, NULL) == errAuthorizationSuccess) {
+        const char * tmp = credential_get_name(engine->sessionCredential);
+        if (tmp != NULL) {
+            auth_items_set_string(engine->hints, AGENT_HINT_SUGGESTED_USER, tmp);
+        }
+        tmp = credential_get_realname(engine->sessionCredential);
+        if (tmp != NULL) {
+            auth_items_set_string(engine->hints, AGENT_HINT_SUGGESTED_USER_LONG, tmp);
+        }
+    } else {
+        auth_items_remove(engine->hints, AGENT_HINT_SUGGESTED_USER);
+        auth_items_remove(engine->hints, AGENT_HINT_SUGGESTED_USER_LONG);
+    }
+}
+
+#pragma mark -
+#pragma mark right processing
+
+static OSStatus
+_evaluate_credential_for_rule(engine_t engine, credential_t cred, rule_t rule, bool ignoreShared, bool sessionOwner, enum Reason * reason)
+{
+    if (auth_token_least_privileged(engine->auth)) {
+        if (credential_is_right(cred) && credential_get_valid(cred) && _compare_string(engine->currentRightName, credential_get_name(cred))) {
+            if (!ignoreShared) {
+                if (!rule_get_shared(rule) && credential_get_shared(cred)) {
+                    LOGV("engine[%i]: - shared right %s (does NOT satisfy rule)", connection_get_pid(engine->conn), credential_get_name(cred));
+                    if (reason) {  *reason = unknownReason; }
+                    return errAuthorizationDenied;
+                }
+            }
+            
+            return errAuthorizationSuccess;
+        } else {
+            if (reason) {  *reason = unknownReason; }
+            return errAuthorizationDenied;
+        }
+    } else {
+        return _evaluate_user_credential_for_rule(engine,cred,rule,ignoreShared,sessionOwner, reason);
+    }
+}
+
+static OSStatus
+_evaluate_user_credential_for_rule(engine_t engine, credential_t cred, rule_t rule, bool ignoreShared, bool sessionOwner, enum Reason * reason)
+{
+    const char * cred_label = sessionOwner ? "session owner" : "credential";
+    LOGV("engine[%i]: - validating %s%s %s (%i) for %s", connection_get_pid(engine->conn),
+         credential_get_shared(cred) ? "shared " : "",
+         cred_label,
+         credential_get_name(cred),
+         credential_get_uid(cred),
+         rule_get_name(rule));
+    
+    if (rule_get_class(rule) != RC_USER) {
+        LOGV("engine[%i]: - invalid rule class %i (denied)", connection_get_pid(engine->conn), rule_get_class(rule));
+        return errAuthorizationDenied;
+    }
+
+    if (credential_get_valid(cred) != true) {
+        LOGV("engine[%i]: - %s %i invalid (does NOT satisfy rule)", connection_get_pid(engine->conn), cred_label, credential_get_uid(cred));
+        if (reason) {  *reason = invalidPassphrase; }
+        return errAuthorizationDenied;
+    }
+
+    if (engine->now - credential_get_creation_time(cred) > rule_get_timeout(rule)) {
+        LOGV("engine[%i]: - %s %i expired '%f > %lli' (does NOT satisfy rule)", connection_get_pid(engine->conn), cred_label, credential_get_uid(cred),
+             (engine->now - credential_get_creation_time(cred)), rule_get_timeout(rule));
+        if (reason) {  *reason = unknownReason; }
+        return errAuthorizationDenied;
+    }
+
+    
+    if (!ignoreShared) {
+        if (!rule_get_shared(rule) && credential_get_shared(cred)) {
+            LOGV("engine[%i]: - shared %s %i (does NOT satisfy rule)", connection_get_pid(engine->conn), cred_label, credential_get_uid(cred));
+            if (reason) {  *reason = unknownReason; }
+            return errAuthorizationDenied;
+        }
+    }
+    
+    if (credential_get_uid(cred) == 0) {
+        LOGV("engine[%i]: - %s %i has uid 0 (does satisfy rule)", connection_get_pid(engine->conn), cred_label, credential_get_uid(cred));
+        return errAuthorizationSuccess;
+    }
+    
+    if (rule_get_session_owner(rule)) {
+        if (credential_get_uid(cred) == session_get_uid(auth_token_get_session(engine->auth))) {
+            LOGV("engine[%i]: - %s %i is session owner (does satisfy rule)", connection_get_pid(engine->conn), cred_label, credential_get_uid(cred));
+            return errAuthorizationSuccess;
+        }
+    }
+    
+    if (rule_get_group(rule) != NULL) {
+        do
+        {
+            // This allows testing a group modifier without prompting the user
+            // When (authenticate-user = false) we are just testing the creator uid.
+            // If a group modifier is enabled (RuleFlagEntitledAndGroup | RuleFlagVPNEntitledAndGroup)
+            // we want to skip the creator uid group check.
+            // group modifiers are checked early during the evaluation in _check_entitlement_for_rule 
+            if (!rule_get_authenticate_user(rule)) {
+                if (rule_check_flags(rule, RuleFlagEntitledAndGroup | RuleFlagVPNEntitledAndGroup)) {
+                    break;
+                }
+            }
+            
+            if (credential_check_membership(cred, rule_get_group(rule))) {
+                LOGV("engine[%i]: - %s %i is member of group %s (does satisfy rule)", connection_get_pid(engine->conn), cred_label, credential_get_uid(cred), rule_get_group(rule));
+                return errAuthorizationSuccess;
+            } else {
+                if (reason) {  *reason = userNotInGroup; }
+            }
+        } while (0);
+    } else if (rule_get_session_owner(rule)) { // rule asks only if user is the session owner
+        if (reason) {  *reason = unacceptableUser; }
+    }
+
+    LOGV("engine[%i]: - %s %i (does NOT satisfy rule)", connection_get_pid(engine->conn), cred_label, credential_get_uid(cred));
+    return errAuthorizationDenied;
+}
+
+static agent_t
+_get_agent(engine_t engine, mechanism_t mech, bool create, bool firstMech)
+{
+    agent_t agent = (agent_t)CFDictionaryGetValue(engine->mechanism_agents, mech);
+    if (create && !agent) {
+        agent = agent_create(engine, mech, engine->auth, engine->proc, firstMech);
+        if (agent) {
+            CFDictionaryAddValue(engine->mechanism_agents, mech, agent);
+            CFReleaseSafe(agent);
+        }
+    }
+    return agent;
+}
+
+static uint64_t
+_evaluate_builtin_mechanism(engine_t engine, mechanism_t mech)
+{
+    uint64_t result = kAuthorizationResultDeny;
+
+    switch (mechanism_get_type(mech)) {
+        case kMechanismTypeEntitled:
+            if (auth_token_has_entitlement_for_right(engine->auth, engine->currentRightName)) {
+                result = kAuthorizationResultAllow;
+            }
+        break;
+        default:
+            break;
+    }
+    
+    return result;
+}
+
+
+static OSStatus
+_evaluate_mechanisms(engine_t engine, CFArrayRef mechanisms)
+{
+    uint64_t result = kAuthorizationResultAllow;
+    ccaudit_t ccaudit = ccaudit_create(engine->proc, engine->auth, AUE_ssauthmech);
+    auth_items_t context = auth_items_create();
+    auth_items_t hints = auth_items_create();
+    
+    auth_items_copy(context, engine->context);
+    auth_items_copy(hints, engine->hints);
+    auth_items_copy(context, engine->sticky_context);
+    
+    CFIndex count = CFArrayGetCount(mechanisms);
+    for (CFIndex i = 0; i < count; i++) {
+        mechanism_t mech = (mechanism_t)CFArrayGetValueAtIndex(mechanisms, i);
+        
+        if (mechanism_get_type(mech)) {
+            LOGV("engine[%i]: running builtin mechanism %s (%li of %li)", connection_get_pid(engine->conn), mechanism_get_string(mech), i+1, count);
+            result = _evaluate_builtin_mechanism(engine, mech);
+        } else {
+            agent_t agent = _get_agent(engine, mech, true, i == 0);
+            require_action(agent != NULL, done, result = kAuthorizationResultUndefined; LOGE("engine[%i]: error creating mechanism agent", connection_get_pid(engine->conn)));
+            LOGV("engine[%i]: running mechanism %s (%li of %li)", connection_get_pid(engine->conn), mechanism_get_string(agent_get_mechanism(agent)), i+1, count);
+            result = agent_run(agent, hints, context, engine->immutable_hints);
+            
+            auth_items_copy(context, agent_get_context(agent));
+            auth_items_copy(hints, agent_get_hints(agent));
+            
+            bool interrupted = false;
+            for (CFIndex i2 = 0; i2 != i; i2++) {
+                agent_t agent2 = _get_agent(engine, (mechanism_t)CFArrayGetValueAtIndex(mechanisms, i2), false, i == 0);
+                if (agent_get_state(agent2) == interrupting) {
+                    agent_deactivate(agent);
+                    interrupted = true;
+                    i = i2 - 1;
+                    char * buf = NULL;
+                    asprintf(&buf, "evaluation interrupted by %s; restarting evaluation there", mechanism_get_string(agent_get_mechanism(agent2)));
+                    ccaudit_log_mechanism(ccaudit, engine->currentRightName, mechanism_get_string(agent_get_mechanism(agent2)), kAuthorizationResultAllow, buf);
+                    free_safe(buf);
+                    auth_items_copy(context, agent_get_context(agent2));
+                    auth_items_copy(hints, agent_get_hints(agent2));
+                    break;
+                }
+            }
+            
+            if (interrupted) {
+                LOGV("engine[%i]: mechanisms interrupted", connection_get_pid(engine->conn));
+                enum Reason reason = worldChanged;
+                auth_items_set_data(hints, AGENT_HINT_RETRY_REASON, &reason, sizeof(reason));
+                result = kAuthorizationResultAllow;
+                _cf_dictionary_iterate(engine->mechanism_agents, ^bool(CFTypeRef key __attribute__((__unused__)), CFTypeRef value) {
+                    agent_t tempagent = (agent_t)value;
+                    agent_clear_interrupt(tempagent);
+                    return true;
+                });
+            }
+        }
+        
+        if (result == kAuthorizationResultAllow) {
+            ccaudit_log_mechanism(ccaudit, engine->currentRightName, mechanism_get_string(mech), kAuthorizationResultAllow, NULL);
+        } else {
+            ccaudit_log_mechanism(ccaudit, engine->currentRightName, mechanism_get_string(mech), (uint32_t)result, NULL);
+            break;
+        }
+    }
+
+done:
+    if ((result == kAuthorizationResultUserCanceled) || (result == kAuthorizationResultAllow)) {
+        // only make non-sticky context values available externally
+        auth_items_set_flags(context, kAuthorizationEnvironmentPassword, kAuthorizationContextFlagVolatile);
+        auth_items_copy_with_flags(engine->context, context, kAuthorizationContextFlagExtractable | kAuthorizationContextFlagVolatile);
+    } else if (result == kAuthorizationResultDeny) {
+        auth_items_clear(engine->sticky_context);
+        // save off sticky values in context
+        auth_items_copy_with_flags(engine->sticky_context, context, kAuthorizationContextFlagSticky);
+    }
+    
+    CFReleaseSafe(ccaudit);
+    CFReleaseSafe(context);
+    CFReleaseSafe(hints);
+    
+    switch(result)
+    {
+        case kAuthorizationResultDeny:
+            return errAuthorizationDenied;
+        case kAuthorizationResultUserCanceled:
+            return errAuthorizationCanceled;
+        case kAuthorizationResultAllow:
+            return errAuthorizationSuccess;
+        case kAuthorizationResultUndefined:
+            return errAuthorizationInternal;
+        default:
+        {
+            LOGV("engine[%i]: unexpected error result", connection_get_pid(engine->conn));
+            return errAuthorizationInternal;
+        }
+    }
+}
+
+static OSStatus
+_evaluate_authentication(engine_t engine, rule_t rule)
+{
+    OSStatus status = errAuthorizationDenied;
+    ccaudit_t ccaudit = ccaudit_create(engine->proc, engine->auth, AUE_ssauthint);
+    LOGV("engine[%i]: evaluate authentication", connection_get_pid(engine->conn));
+    _set_rule_hints(engine->hints, rule);
+    _set_session_hints(engine, rule);
+
+    CFArrayRef mechanisms = rule_get_mechanisms(rule);
+    if (!(CFArrayGetCount(mechanisms) > 0)) {
+        mechanisms = rule_get_mechanisms(engine->authenticateRule);
+    }
+    require_action(CFArrayGetCount(mechanisms) > 0, done, LOGV("engine[%i]: error no mechanisms found", connection_get_pid(engine->conn)));
+    
+    int64_t ruleTries = rule_get_tries(rule);
+    for (engine->tries = 0; engine->tries < ruleTries; engine->tries++) {
+        
+        auth_items_set_data(engine->hints, AGENT_HINT_RETRY_REASON, &engine->reason, sizeof(engine->reason));
+        auth_items_set_int(engine->hints, AGENT_HINT_TRIES, engine->tries);
+        
+        status = _evaluate_mechanisms(engine, mechanisms);
+        
+        LOGV("engine[%i]: evaluate mechanisms result %i", connection_get_pid(engine->conn), status);
+        
+        // successfully ran mechanisms to obtain credential
+        if (status == errAuthorizationSuccess) {
+            // deny is the default
+            status = errAuthorizationDenied;
+            
+            credential_t newCred = NULL;
+            if (auth_items_exist(engine->context, "uid")) {
+                newCred = credential_create(auth_items_get_uint(engine->context, "uid"));
+            } else {
+                LOGV("engine[%i]: mechanism failed to return a valid uid", connection_get_pid(engine->conn));
+            }
+            
+            if (newCred) {
+                if (credential_get_valid(newCred)) {
+                    LOG("UID %u authenticated as user %s (UID %u) for right '%s'", auth_token_get_uid(engine->auth), credential_get_name(newCred), credential_get_uid(newCred), engine->currentRightName);
+                    ccaudit_log_success(ccaudit, newCred, engine->currentRightName);
+                } else {
+                    LOG("UID %u failed to authenticate as user '%s' for right '%s'", auth_token_get_uid(engine->auth), auth_items_get_string(engine->context, "username"), engine->currentRightName);
+                    ccaudit_log_failure(ccaudit, auth_items_get_string(engine->context, "username"), engine->currentRightName);
+                }
+                
+                status = _evaluate_user_credential_for_rule(engine, newCred, rule, true, false, &engine->reason);
+
+                if (status == errAuthorizationSuccess) {
+                    _engine_set_credential(engine, newCred, rule_get_shared(rule));
+                    CFReleaseSafe(newCred);
+                    
+                    if (auth_token_least_privileged(engine->auth)) {
+                        credential_t rightCred = credential_create_with_right(engine->currentRightName);
+                        _engine_set_credential(engine, rightCred, rule_get_shared(rule));
+                        CFReleaseSafe(rightCred);
+                    }
+                    
+                    session_t session = auth_token_get_session(engine->auth);
+                    if (credential_get_uid(newCred) == session_get_uid(session)) {
+                        LOGV("engine[%i]: authenticated as the session owner", connection_get_pid(engine->conn));
+                        session_set_attributes(auth_token_get_session(engine->auth), AU_SESSION_FLAG_HAS_AUTHENTICATED);
+                    }
+
+                    break;
+                }
+
+                CFReleaseSafe(newCred);
+            }
+            
+        } else if (status == errAuthorizationCanceled || status == errAuthorizationInternal) {
+            break;
+        } else if (status == errAuthorizationDenied) {
+            engine->reason = invalidPassphrase;
+        }
+    }
+    
+    if (engine->tries == ruleTries) {
+        engine->reason = tooManyTries;
+        auth_items_set_data(engine->hints, AGENT_HINT_RETRY_REASON, &engine->reason, sizeof(engine->reason));
+        auth_items_set_int(engine->hints, AGENT_HINT_TRIES, engine->tries);
+        _evaluate_mechanisms(engine, mechanisms);
+        ccaudit_log(ccaudit, engine->currentRightName, NULL, 1113);
+    }
+    
+done:
+    CFReleaseSafe(ccaudit);
+    
+    return status;
+}
+
+static bool
+_check_entitlement_for_rule(engine_t engine, rule_t rule)
+{
+    bool entitled = false;
+    CFTypeRef value = NULL;
+    
+    if (rule_check_flags(rule, RuleFlagEntitledAndGroup)) {
+        if (auth_token_has_entitlement_for_right(engine->auth, engine->currentRightName)) {
+            if (credential_check_membership(auth_token_get_credential(engine->auth), rule_get_group(rule))) {
+                LOGV("engine[%i]: creator of authorization has entitlement for right %s and is member of group '%s'", connection_get_pid(engine->conn), engine->currentRightName, rule_get_group(rule));
+                entitled = true;
+                goto done;
+            }
+        }
+    }
+    
+    if (rule_check_flags(rule, RuleFlagVPNEntitledAndGroup)) {
+        // com.apple.networking.vpn.configuration is an array we only check for it's existence
+        value = auth_token_copy_entitlement_value(engine->auth, "com.apple.networking.vpn.configuration");
+        if (value) {
+            if (credential_check_membership(auth_token_get_credential(engine->auth), rule_get_group(rule))) {
+                LOGV("engine[%i]: creator of authorization has VPN entitlement and is member of group '%s'", connection_get_pid(engine->conn), rule_get_group(rule));
+                entitled = true;
+                goto done;
+            }
+        }
+    }
+    
+done:
+    CFReleaseSafe(value);
+    return entitled;
+}
+
+static OSStatus
+_evaluate_class_user(engine_t engine, rule_t rule)
+{
+    __block OSStatus status = errAuthorizationDenied;
+    
+    if (_check_entitlement_for_rule(engine,rule)) {
+        return errAuthorizationSuccess;
+    }
+    
+    if (rule_get_allow_root(rule) && auth_token_get_uid(engine->auth) == 0) {
+        LOGV("engine[%i]: creator of authorization has uid == 0 granting right %s", connection_get_pid(engine->conn), engine->currentRightName);
+        return errAuthorizationSuccess;
+    }
+    
+    if (!rule_get_authenticate_user(rule)) {
+        status = _evaluate_user_credential_for_rule(engine, engine->sessionCredential, rule, true, true, NULL);
+        
+        if (status == errAuthorizationSuccess) {
+            return errAuthorizationSuccess;
+        }
+        
+        return errAuthorizationDenied;
+    }
+    
+    // First -- check all the credentials we have either acquired or currently have
+    _cf_set_iterate(engine->credentials, ^bool(CFTypeRef value) {
+        credential_t cred = (credential_t)value;
+        // Passed-in user credentials are allowed for least-privileged mode
+        if (auth_token_least_privileged(engine->auth) && !credential_is_right(cred) && credential_get_valid(cred)) {
+            status = _evaluate_user_credential_for_rule(engine, cred, rule, false, false, NULL);
+            if (errAuthorizationSuccess == status) {
+                credential_t rightCred = credential_create_with_right(engine->currentRightName);
+                _engine_set_credential(engine,rightCred,rule_get_shared(rule));
+                CFReleaseSafe(rightCred);
+                return false; // exit loop
+            }
+        }
+        
+        status = _evaluate_credential_for_rule(engine, cred, rule, false, false, NULL);
+        if (status == errAuthorizationSuccess) {
+            return false; // exit loop
+        }
+        return true;
+    });
+    
+    if (status == errAuthorizationSuccess) {
+        return status;
+    }
+
+    // Second -- go through the credentials associated to the authorization token session/auth token
+    _cf_set_iterate(engine->effectiveCredentials, ^bool(CFTypeRef value) {
+        credential_t cred = (credential_t)value;
+        status = _evaluate_credential_for_rule(engine, cred, rule, false, false, NULL);
+        if (status == errAuthorizationSuccess) {
+            // Add the credential we used to the output set.
+            _engine_set_credential(engine, cred, false);
+            return false; // exit loop
+        }
+        return true;
+    });
+    
+    if (status == errAuthorizationSuccess) {
+        return status;
+    }
+    
+    // Finally - we didn't find a credential. Obtain a new credential if our flags let us do so.
+    if (!(engine->flags & kAuthorizationFlagExtendRights)) {
+        LOGV("engine[%i]: authorization denied (kAuthorizationFlagExtendRights not set)", connection_get_pid(engine->conn));
+        return errAuthorizationDenied;
+    }
+    
+    // authorization that timeout immediately cannot be preauthorized
+    if (engine->flags & kAuthorizationFlagPreAuthorize && rule_get_timeout(rule) == 0) {
+        return errAuthorizationSuccess;
+    }
+    
+    if (!(engine->flags & kAuthorizationFlagInteractionAllowed)) {
+               LOGV("engine[%i]: Interaction not allowed (kAuthorizationFlagInteractionAllowed not set)", connection_get_pid(engine->conn));
+        return errAuthorizationInteractionNotAllowed;
+    }
+    
+    if (!(session_get_attributes(auth_token_get_session(engine->auth)) & AU_SESSION_FLAG_HAS_GRAPHIC_ACCESS)) {
+        LOGV("engine[%i]: Interaction not allowed (session has no ui access)", connection_get_pid(engine->conn));
+        return errAuthorizationInteractionNotAllowed;
+    }
+    
+    if (server_in_dark_wake()) {
+        LOGV("engine[%i]: authorization denied (in DarkWake)", connection_get_pid(engine->conn));
+        return errAuthorizationDenied;
+    }
+    
+    return _evaluate_authentication(engine,rule);
+}
+
+static OSStatus
+_evaluate_class_rule(engine_t engine, rule_t rule)
+{
+    __block OSStatus status = errAuthorizationDenied;
+    int64_t kofn = rule_get_kofn(rule);
+
+    uint32_t total = (uint32_t)rule_get_delegates_count(rule);
+    __block uint32_t success_count = 0;
+    __block uint32_t count = 0;
+    LOGV("engine[%i]: ** rule %s has %zi delegates kofn = %lli", connection_get_pid(engine->conn), rule_get_name(rule), total, kofn);
+    rule_delegates_iterator(rule, ^bool(rule_t delegate) {
+        count++;
+        
+        if (kofn != 0 && success_count == kofn) {
+            status = errAuthorizationSuccess;
+            return false;
+        }
+        
+        LOGV("engine[%i]: * evaluate rule %s (%i)", connection_get_pid(engine->conn), rule_get_name(delegate), count);
+        status = _evaluate_rule(engine, delegate);
+        
+        // if status is cancel/internal error abort
+               if ((status == errAuthorizationCanceled) || (status == errAuthorizationInternal))
+                       return false;
+        
+        if (status != errAuthorizationSuccess) {
+            if (kofn != 0) {
+                // if remaining is less then required abort
+                if ((total - count) < (kofn - success_count)) {
+                    LOGD("engine[%i]: rule evaluation remaining: %i, required: %lli", connection_get_pid(engine->conn), (total - count), (kofn - success_count));
+                    return false;
+                }
+                return true;
+            }
+            return false;
+        } else {
+            success_count++;
+            return true;
+        }
+    });
+    
+    return status;
+}
+
+static OSStatus
+_evaluate_class_mechanism(engine_t engine, rule_t rule)
+{
+    OSStatus status = errAuthorizationDenied;
+    CFArrayRef mechanisms = NULL;
+    
+    require_action(rule_get_mechanisms_count(rule) > 0, done, status = errAuthorizationSuccess; LOGV("engine[%i]: no mechanisms specified", connection_get_pid(engine->conn)));
+    
+    mechanisms = rule_get_mechanisms(rule);
+    
+    if (server_in_dark_wake()) {
+        CFIndex count = CFArrayGetCount(mechanisms);
+        for (CFIndex i = 0; i < count; i++) {
+            if (!mechanism_is_privileged((mechanism_t)CFArrayGetValueAtIndex(mechanisms, i))) {
+                LOGV("engine[%i]: authorization denied (in DarkWake)", connection_get_pid(engine->conn));
+                goto done;
+            }
+        }
+    }
+    
+    int64_t ruleTries = rule_get_tries(rule);
+    engine->tries = 0;
+    do {
+        auth_items_set_data(engine->hints, AGENT_HINT_RETRY_REASON, &engine->reason, sizeof(engine->reason));
+        auth_items_set_int(engine->hints, AGENT_HINT_TRIES, engine->tries);
+        
+        status = _evaluate_mechanisms(engine, mechanisms);
+        LOGV("engine[%i]: evaluate mechanisms result %i", connection_get_pid(engine->conn), status);
+        
+        if ((status == errAuthorizationSuccess) || (status == errAuthorizationCanceled)) {
+            
+            if (status == errAuthorizationSuccess) {
+                credential_t newCred = NULL;
+                if (auth_items_exist(engine->context, "uid")) {
+                    newCred = credential_create(auth_items_get_uint(engine->context, "uid"));
+                } else {
+                    LOGV("engine[%i]: mechanism did not return a uid", connection_get_pid(engine->conn));
+                }
+
+                if (newCred) {
+                    _engine_set_credential(engine, newCred, rule_get_shared(rule));
+                    
+                    if (auth_token_least_privileged(engine->auth)) {
+                        credential_t rightCred = credential_create_with_right(engine->currentRightName);
+                        _engine_set_credential(engine, rightCred, rule_get_shared(rule));
+                        CFReleaseSafe(rightCred);
+                    }
+                    
+                    if (strcmp(engine->currentRightName, "system.login.console") == 0 && !auth_items_exist(engine->context, AGENT_CONTEXT_AUTO_LOGIN)) {
+                        session_set_attributes(auth_token_get_session(engine->auth), AU_SESSION_FLAG_HAS_AUTHENTICATED);
+                    }
+                    
+                    CFReleaseSafe(newCred);
+                }
+            } 
+        } // mechanism errAuthorizationSuccess
+
+        engine->tries++;
+        
+    } while ( (status == errAuthorizationDenied) // only if we have an expected faulure we continue
+             && ((ruleTries == 0) || ((ruleTries > 0) && engine->tries < ruleTries))); // ruleTries == 0 means we try forever
+                                                                                       // ruleTires > 0 means we try upto ruleTries times
+done:
+    return status;
+}
+
+static OSStatus
+_evaluate_rule(engine_t engine, rule_t rule)
+{
+    if (rule_check_flags(rule, RuleFlagEntitled)) {
+        if (auth_token_has_entitlement_for_right(engine->auth, engine->currentRightName)) {
+            LOGV("engine[%i]: rule allow, creator of authorization has entitlement for right %s", connection_get_pid(engine->conn), engine->currentRightName);
+            return errAuthorizationSuccess;
+        }
+    }
+    
+    if (rule_check_flags(rule, RuleFlagRequireAppleSigned)) {
+        if (!auth_token_apple_signed(engine->auth)) {
+            LOGV("engine[%i]: rule deny, creator of authorization is not signed by apple", connection_get_pid(engine->conn));
+            return errAuthorizationDenied;
+        }
+    }
+    
+    switch (rule_get_class(rule)) {
+        case RC_ALLOW:
+            LOGV("engine[%i]: rule set to allow", connection_get_pid(engine->conn));
+            return errAuthorizationSuccess;
+        case RC_DENY:
+            LOGV("engine[%i]: rule set to deny", connection_get_pid(engine->conn));
+            return errAuthorizationDenied;
+        case RC_USER:
+            return _evaluate_class_user(engine,rule);
+        case RC_RULE:
+            return _evaluate_class_rule(engine, rule);
+        case RC_MECHANISM:
+            return _evaluate_class_mechanism(engine, rule);
+        default:
+            LOGV("engine[%i]: invalid class for rule or rule not found", connection_get_pid(engine->conn));
+            return errAuthorizationInternal;
+    }
+}
+
+static rule_t
+_find_rule(engine_t engine, authdb_connection_t dbconn, const char * string)
+{
+    rule_t r = NULL;
+    size_t sLen = strlen(string);
+    
+    char * buf = calloc(1u, sLen + 1);
+    strlcpy(buf, string, sLen + 1);
+    char * ptr = buf + sLen;
+    __block int64_t count = 0;
+    
+    for (;;) {
+        
+        // lookup rule
+        authdb_step(dbconn, "SELECT COUNT(name) AS cnt FROM rules WHERE name = ? AND type = 1",
+        ^(sqlite3_stmt *stmt) {
+            sqlite3_bind_text(stmt, 1, buf, -1, NULL);
+        }, ^bool(auth_items_t data) {
+            count = auth_items_get_int64(data, "cnt");
+            return false;
+        });
+        
+        if (count > 0) {
+            r = rule_create_with_string(buf, dbconn);
+            goto done;
+        }
+        
+        // if buf ends with a . and we didn't find a rule remove .
+        if (*ptr == '.') {
+            *ptr = '\0';
+        }
+        // find any remaining . and truncate the string
+        ptr = strrchr(buf, '.');
+        if (ptr) {
+            *(ptr+1) = '\0';
+        } else {
+            break;
+        }
+    }
+    
+done:
+    free_safe(buf);
+    
+    // set default if we didn't find a rule
+    if (r == NULL) {
+        r = rule_create_with_string("", dbconn);
+        if (rule_get_id(r) == 0) {
+            CFReleaseNull(r);
+            LOGE("engine[%i]: default rule lookup error (missing), using builtin defaults", connection_get_pid(engine->conn));
+            r = rule_create_default();
+        }
+    }
+    return r;
+}
+
+static void _parse_enviroment(engine_t engine, auth_items_t enviroment)
+{
+    require(enviroment != NULL, done);
+
+#if DEBUG
+    LOGV("engine[%i]: Dumping Enviroment", connection_get_pid(engine->conn));
+    _show_cf(enviroment);
+#endif
+
+    // Check if a credential was passed into the environment and we were asked to extend the rights
+    if (engine->flags & kAuthorizationFlagExtendRights) {
+        const char * user = auth_items_get_string(enviroment, kAuthorizationEnvironmentUsername);
+        const char * pass = auth_items_get_string(enviroment, kAuthorizationEnvironmentPassword);
+        bool shared = auth_items_exist(enviroment, kAuthorizationEnvironmentShared);
+        require(user != NULL, done);
+
+        struct passwd *pw = getpwnam(user);
+        require_action(pw != NULL, done, LOGE("engine[%i]: user not found %s", connection_get_pid(engine->conn), user));
+        
+        int checkpw_status = checkpw_internal(pw, pass ? pass : "");
+        require_action(checkpw_status == CHECKPW_SUCCESS, done, LOGE("engine[%i]: checkpw() returned %d; failed to authenticate user %s (uid %u).", connection_get_pid(engine->conn), checkpw_status, pw->pw_name, pw->pw_uid));
+        
+        credential_t cred = credential_create(pw->pw_uid);
+        if (credential_get_valid(cred)) {
+            LOG("engine[%i]: checkpw() succeeded, creating credential for user %s", connection_get_pid(engine->conn), user);
+            _engine_set_credential(engine, cred, shared);
+            
+            auth_items_set_string(engine->context, kAuthorizationEnvironmentUsername, user);
+            auth_items_set_string(engine->context, kAuthorizationEnvironmentPassword, pass ? pass : "");
+        }
+        CFReleaseSafe(cred);
+    }
+    
+done:
+    endpwent();
+    return;
+}
+
+static bool _verify_sandbox(engine_t engine, const char * right)
+{
+    pid_t pid = process_get_pid(engine->proc);
+    if (sandbox_check(pid, "authorization-right-obtain", SANDBOX_FILTER_RIGHT_NAME, right)) {
+        LOGE("Sandbox denied authorizing right '%s' by client '%s' [%d]", right, process_get_code_url(engine->proc), pid);
+        return false;
+    }
+    
+    pid = auth_token_get_pid(engine->auth);
+    if (auth_token_get_sandboxed(engine->auth) && sandbox_check(pid, "authorization-right-obtain", SANDBOX_FILTER_RIGHT_NAME, right)) {
+        LOGE("Sandbox denied authorizing right '%s' for authorization created by '%s' [%d]", right, auth_token_get_code_url(engine->auth), pid);
+        return false;
+    }
+    
+    return true;
+}
+
+#pragma mark -
+#pragma mark engine methods
+
+OSStatus engine_authorize(engine_t engine, auth_rights_t rights, auth_items_t enviroment, AuthorizationFlags flags)
+{
+    __block OSStatus status = errAuthorizationSuccess;
+    __block bool savePassword = false;
+    ccaudit_t ccaudit = NULL;
+    
+    require(rights != NULL, done);
+    
+    ccaudit = ccaudit_create(engine->proc, engine->auth, AUE_ssauthorize);
+    if (auth_rights_get_count(rights) > 0) {
+        ccaudit_log(ccaudit, "begin evaluation", NULL, 0);
+    }
+    
+    engine->flags = flags;
+    
+    if (enviroment) {
+        _parse_enviroment(engine, enviroment);
+        auth_items_copy(engine->hints, enviroment);
+    }
+    
+    auth_items_copy(engine->context, auth_token_get_context(engine->auth));
+    
+    engine->dismissed = false;
+    auth_rights_clear(engine->grantedRights);
+    
+    auth_rights_iterate(rights, ^bool(const char *key) {
+        if (!key)
+            return true;
+
+
+        if (!_verify_sandbox(engine, key)) {
+            status = errAuthorizationDenied;
+            return false;
+        }
+        
+        authdb_connection_t dbconn = authdb_connection_acquire(server_get_database()); // get db handle
+        
+        LOGV("engine[%i]: evaluate right %s", connection_get_pid(engine->conn), key);
+        rule_t rule = _find_rule(engine, dbconn, key);
+        const char * rule_name = rule_get_name(rule);
+        if (rule_name && (strcasecmp(rule_name, "") == 0)) {
+            rule_name = "default (not defined)";
+        }
+        LOGV("engine[%i]: using rule %s", connection_get_pid(engine->conn), rule_name);
+
+        // only need the hints & mechanisms if we are going to show ui
+        if (engine->flags & kAuthorizationFlagInteractionAllowed) {
+            _set_right_hints(engine->hints, key);
+            _set_localization_hints(dbconn, engine->hints, rule);
+            if (!engine->authenticateRule) {
+                engine->authenticateRule = rule_create_with_string("authenticate", dbconn);
+            }
+        }
+        
+        authdb_connection_release(&dbconn); // release db handle
+        
+        engine->currentRightName = key;
+        engine->currentRule = rule;
+        
+        ccaudit_log(ccaudit, key, rule_name, 0);
+        
+        status = _evaluate_rule(engine, engine->currentRule);
+        switch (status) {
+            case errAuthorizationSuccess:
+                auth_rights_add(engine->grantedRights, key);
+                auth_rights_set_flags(engine->grantedRights, key, auth_rights_get_flags(rights,key));
+                
+                if ((engine->flags & kAuthorizationFlagPreAuthorize) &&
+                    (rule_get_class(engine->currentRule) == RC_USER) &&
+                    (rule_get_timeout(engine->currentRule) == 0)) {
+                    auth_rights_set_flags(engine->grantedRights, engine->currentRightName, kAuthorizationFlagPreAuthorize);
+                }
+                
+                LOG("Succeeded authorizing right '%s' by client '%s' [%d] for authorization created by '%s' [%d] (%X,%d)",
+                    key, process_get_code_url(engine->proc), process_get_pid(engine->proc),
+                    auth_token_get_code_url(engine->auth), auth_token_get_pid(engine->auth), engine->flags, auth_token_least_privileged(engine->auth));
+                if (rule_get_extract_password(engine->currentRule)) {
+                    savePassword = true;
+                }
+                break;
+            case errAuthorizationDenied:
+            case errAuthorizationInteractionNotAllowed:
+            case errAuthorizationCanceled:
+                if (engine->flags & kAuthorizationFlagInteractionAllowed) {
+                    LOG("Failed to authorize right '%s' by client '%s' [%d] for authorization created by '%s' [%d] (%X,%d) (%i)",
+                        key, process_get_code_url(engine->proc), process_get_pid(engine->proc),
+                        auth_token_get_code_url(engine->auth), auth_token_get_pid(engine->auth), engine->flags, auth_token_least_privileged(engine->auth), status);
+                } else {
+                    LOGV("Failed to authorize right '%s' by client '%s' [%d] for authorization created by '%s' [%d] (%X,%d) (%i)",
+                        key, process_get_code_url(engine->proc), process_get_pid(engine->proc),
+                        auth_token_get_code_url(engine->auth), auth_token_get_pid(engine->auth), engine->flags, auth_token_least_privileged(engine->auth), status);
+                }
+                break;
+            default:
+                LOGE("engine[%i]: evaluate returned %i returning errAuthorizationInternal", connection_get_pid(engine->conn), status);
+                status = errAuthorizationInternal;
+                break;
+        }
+
+        ccaudit_log_authorization(ccaudit, engine->currentRightName, status);
+        
+        CFReleaseSafe(rule);
+        engine->currentRightName = NULL;
+        engine->currentRule = NULL;
+        
+        auth_items_remove_with_flags(engine->hints, kEngineHintsFlagTemporary);
+        
+        if (!(engine->flags & kAuthorizationFlagPartialRights) && (status != errAuthorizationSuccess)) {
+            return false;
+        }
+        
+        return true;
+    });
+    
+    if ((engine->flags & kAuthorizationFlagPartialRights) && (auth_rights_get_count(engine->grantedRights) > 0)) {
+        status = errAuthorizationSuccess;
+    }
+    
+    if (engine->dismissed) {
+        status = errAuthorizationDenied;
+    }
+    
+    LOGV("engine[%i]: authorize result: %i", connection_get_pid(engine->conn), status);
+    
+    if ((engine->flags & kAuthorizationFlagExtendRights) && !(engine->flags & kAuthorizationFlagDestroyRights)) {
+        _cf_set_iterate(engine->credentials, ^bool(CFTypeRef value) {
+            credential_t cred = (credential_t)value;
+            // skip all uid credentials when running in least privileged
+            if (auth_token_least_privileged(engine->auth) && !credential_is_right(cred))
+                return true; 
+            
+            session_t session = auth_token_get_session(engine->auth);
+            auth_token_set_credential(engine->auth, cred);
+            if (credential_get_shared(cred)) {
+                session_set_credential(session, cred);
+            }
+            if (credential_is_right(cred)) {
+                LOGV("engine[%i]: adding least privileged %scredential %s to authorization", connection_get_pid(engine->conn), credential_get_shared(cred) ? "shared " : "", credential_get_name(cred));
+            } else {
+                LOGV("engine[%i]: adding %scredential %s (%i) to authorization", connection_get_pid(engine->conn), credential_get_shared(cred) ? "shared " : "", credential_get_name(cred), credential_get_uid(cred));
+            }
+            return true;
+        });
+    }
+    
+    if ((status == errAuthorizationSuccess) || (status == errAuthorizationCanceled)) {
+        if (savePassword && (status == errAuthorizationSuccess)) {
+            auth_items_set_flags(engine->context, kAuthorizationEnvironmentPassword, kAuthorizationContextFlagExtractable);
+        }
+        
+        auth_items_copy_with_flags(auth_token_get_context(engine->auth), engine->context, kAuthorizationContextFlagExtractable);
+    }
+    
+    if (auth_rights_get_count(rights) > 0) {
+        ccaudit_log(ccaudit, "end evaluation", NULL, status);
+    }
+    
+#if DEBUG
+    LOGV("engine[%i]: ********** Dumping auth->credentials **********", connection_get_pid(engine->conn));
+    auth_token_credentials_iterate(engine->auth, ^bool(credential_t cred) {
+        _show_cf(cred);
+        return true;
+    });
+    LOGV("engine[%i]: ********** Dumping session->credentials **********", connection_get_pid(engine->conn));
+    session_credentials_iterate(auth_token_get_session(engine->auth), ^bool(credential_t cred) {
+        _show_cf(cred);
+        return true;
+    });
+    LOGV("engine[%i]: ********** Dumping engine->context **********", connection_get_pid(engine->conn));
+    _show_cf(engine->context);
+    LOGV("engine[%i]: ********** Dumping auth->context **********", connection_get_pid(engine->conn));
+    _show_cf(auth_token_get_context(engine->auth));
+    LOGV("engine[%i]: ********** Dumping granted rights **********", connection_get_pid(engine->conn));
+    _show_cf(engine->grantedRights);
+#endif
+    
+done:
+    auth_items_clear(engine->context);
+    auth_items_clear(engine->sticky_context);
+    CFReleaseSafe(ccaudit);
+    CFDictionaryRemoveAllValues(engine->mechanism_agents);
+    
+    return status;
+}
+
+static bool
+_wildcard_right_exists(engine_t engine, const char * right)
+{
+    // checks if a wild card right exists
+    // ex: com.apple. system.
+    bool exists = false;
+    rule_t rule = NULL;
+    authdb_connection_t dbconn = authdb_connection_acquire(server_get_database()); // get db handle
+    require(dbconn != NULL, done);
+    
+    rule = _find_rule(engine, dbconn, right);
+    require(rule != NULL, done);
+    
+    const char * ruleName = rule_get_name(rule);
+    require(ruleName != NULL, done);
+    size_t len = strlen(ruleName);
+    require(len != 0, done);
+    
+    if (ruleName[len-1] == '.') {
+        exists = true;
+        goto done;
+    }
+
+done:
+    authdb_connection_release(&dbconn);
+    CFReleaseSafe(rule);
+
+    return exists;
+}
+
+// Validate db right modification
+
+// meta rights are constructed as follows:
+// we don't allow setting of wildcard rights, so you can only be more specific
+// note that you should never restrict things with a wildcard right without disallowing
+// changes to the entire domain.  ie.
+//             system.privilege.               -> never
+//             config.add.system.privilege.    -> never
+//             config.modify.system.privilege. -> never
+//             config.delete.system.privilege. -> never
+// For now we don't allow any configuration of configuration rules
+//             config.config. -> never
+
+OSStatus engine_verify_modification(engine_t engine, rule_t rule, bool remove, bool force_modify)
+{
+    OSStatus status = errAuthorizationDenied;
+    auth_rights_t checkRight = NULL;
+    char buf[BUFSIZ];
+    memset(buf, 0, sizeof(buf));
+    
+    const char * right = rule_get_name(rule);
+    require(right != NULL, done);
+    size_t len = strlen(right);
+    require(len != 0, done);
+
+    require_action(right[len-1] != '.', done, LOGE("engine[%i]: not allowed to set wild card rules", connection_get_pid(engine->conn)));
+
+    if (strncasecmp(right, kConfigRight, strlen(kConfigRight)) == 0) {
+        // special handling of meta right change:
+               // config.add. config.modify. config.remove. config.{}.
+               // check for config.<right> (which always starts with config.config.)
+        strlcat(buf, kConfigRight, sizeof(buf));
+    } else {
+        bool existing = (rule_get_id(rule) != 0) ? true : _wildcard_right_exists(engine, right);
+        if (!remove) {
+            if (existing || force_modify) {
+                strlcat(buf, kAuthorizationConfigRightModify,sizeof(buf));
+            } else {
+                strlcat(buf, kAuthorizationConfigRightAdd, sizeof(buf));
+            }
+        } else {
+            if (existing) {
+                strlcat(buf, kAuthorizationConfigRightRemove, sizeof(buf));
+            } else {
+                status = errAuthorizationSuccess;
+                goto done;
+            }
+        }
+    }
+    
+    strlcat(buf, right, sizeof(buf));
+
+    checkRight = auth_rights_create();
+    auth_rights_add(checkRight, buf);
+    status = engine_authorize(engine, checkRight, NULL, kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed | kAuthorizationFlagExtendRights);
+
+done:
+    LOGV("engine[%i]: authorizing %s for db modification: %i", connection_get_pid(engine->conn), right, status);
+    CFReleaseSafe(checkRight);
+    return status;
+}
+
+void
+_engine_set_credential(engine_t engine, credential_t cred, bool shared)
+{
+    LOGV("engine[%i]: adding %scredential %s (%i) to engine shared: %i", connection_get_pid(engine->conn), credential_get_shared(cred) ? "shared " : "", credential_get_name(cred), credential_get_uid(cred), shared);
+    CFSetSetValue(engine->credentials, cred);
+    if (shared) {
+        credential_t sharedCred = credential_create_with_credential(cred, true);
+        CFSetSetValue(engine->credentials, sharedCred);
+        CFReleaseSafe(sharedCred);
+    }
+}
+
+auth_rights_t
+engine_get_granted_rights(engine_t engine)
+{
+    return engine->grantedRights;
+}
+
+CFAbsoluteTime engine_get_time(engine_t engine)
+{
+    return engine->now;
+}
+
+void engine_destroy_agents(engine_t engine)
+{
+    engine->dismissed = true;
+
+    _cf_dictionary_iterate(engine->mechanism_agents, ^bool(CFTypeRef key __attribute__((__unused__)), CFTypeRef value) {
+        LOGD("engine[%i]: Destroying %s", connection_get_pid(engine->conn), mechanism_get_string((mechanism_t)key));
+        agent_t agent = (agent_t)value;
+        agent_destroy(agent);
+        
+        return true;
+    });
+}
+
+void engine_interrupt_agent(engine_t engine)
+{
+    _cf_dictionary_iterate(engine->mechanism_agents, ^bool(CFTypeRef key __attribute__((__unused__)), CFTypeRef value) {
+        agent_t agent = (agent_t)value;
+        agent_notify_interrupt(agent);
+        return true;
+    });
+}
diff --git a/authd/engine.h b/authd/engine.h
new file mode 100644 (file)
index 0000000..42170f0
--- /dev/null
@@ -0,0 +1,38 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#ifndef _SECURITY_AUTH_ENGINE_H_
+#define _SECURITY_AUTH_ENGINE_H_
+
+#include "credential.h"
+#include <Security/Authorization.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+AUTH_WARN_RESULT AUTH_MALLOC AUTH_NONNULL_ALL AUTH_RETURNS_RETAINED
+engine_t engine_create(connection_t, auth_token_t);
+
+AUTH_NONNULL1 AUTH_NONNULL2
+OSStatus engine_authorize(engine_t, auth_rights_t rights, auth_items_t enviroment, AuthorizationFlags);
+
+AUTH_NONNULL_ALL
+OSStatus engine_verify_modification(engine_t, rule_t, bool remove, bool force_modify);
+
+AUTH_NONNULL_ALL
+auth_rights_t engine_get_granted_rights(engine_t);
+
+AUTH_NONNULL_ALL
+CFAbsoluteTime engine_get_time(engine_t);
+    
+AUTH_NONNULL_ALL
+void engine_destroy_agents(engine_t);
+    
+AUTH_NONNULL_ALL
+void engine_interrupt_agent(engine_t engine);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_SECURITY_AUTH_ENGINE_H_ */
diff --git a/authd/main.c b/authd/main.c
new file mode 100644 (file)
index 0000000..9309d5c
--- /dev/null
@@ -0,0 +1,208 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#include "debugging.h"
+#include "server.h"
+#include "process.h"
+#include "session.h"
+#include "authtoken.h"
+#include "engine.h"
+#include "authd_private.h"
+#include "connection.h"
+
+#include <Security/Authorization.h>
+
+#include <xpc/xpc.h>
+#include <xpc/private.h>
+#include <dispatch/dispatch.h>
+#include <assert.h>
+#include <sandbox.h>
+
+#if DEBUG
+#include <malloc/malloc.h>
+#endif
+
+static void
+security_auth_peer_event_handler(xpc_connection_t connection, xpc_object_t event)
+{
+    __block OSStatus status = errAuthorizationDenied;
+    
+    connection_t conn = (connection_t)xpc_connection_get_context(connection);
+    require_action(conn != NULL, done, LOGE("xpc[%i]: process context not found", xpc_connection_get_pid(connection)));
+
+    CFRetainSafe(conn);
+
+    xpc_type_t type = xpc_get_type(event);
+
+       if (type == XPC_TYPE_ERROR) {
+               if (event == XPC_ERROR_CONNECTION_INVALID) {
+                       // The client process on the other end of the connection has either
+                       // crashed or cancelled the connection. After receiving this error,
+                       // the connection is in an invalid state, and you do not need to
+                       // call xpc_connection_cancel(). Just tear down any associated state
+                       // here.
+            LOGV("xpc[%i]: client disconnected", xpc_connection_get_pid(connection));
+            connection_destory_agents(conn);
+               } else if (event == XPC_ERROR_TERMINATION_IMMINENT) {
+                       // Handle per-connection termination cleanup.
+            LOGD("xpc[%i]: per-connection termination", xpc_connection_get_pid(connection));
+               }
+       } else {
+               assert(type == XPC_TYPE_DICTIONARY);
+        
+        xpc_object_t reply = xpc_dictionary_create_reply(event);
+        require(reply != NULL, done);
+        
+        uint64_t auth_type = xpc_dictionary_get_uint64(event, AUTH_XPC_TYPE);
+        LOGV("xpc[%i]: received message type=%llu", connection_get_pid(conn), auth_type);
+        
+        switch (auth_type) {
+            case AUTHORIZATION_CREATE:
+                status = authorization_create(conn,event,reply);
+                break;
+            case AUTHORIZATION_CREATE_WITH_AUDIT_TOKEN:
+                status = authorization_create_with_audit_token(conn,event,reply);
+                break;
+            case AUTHORIZATION_FREE:
+                status = authorization_free(conn,event,reply);
+                break;
+            case AUTHORIZATION_COPY_RIGHTS:
+                status = authorization_copy_rights(conn,event,reply);
+                break;
+            case AUTHORIZATION_COPY_INFO:
+                status = authorization_copy_info(conn,event,reply);
+                break;
+            case AUTHORIZATION_MAKE_EXTERNAL_FORM:
+                status = authorization_make_external_form(conn,event,reply);
+                break;
+            case AUTHORIZATION_CREATE_FROM_EXTERNAL_FORM:
+                status = authorization_create_from_external_form(conn,event,reply);
+                break;
+            case AUTHORIZATION_RIGHT_GET:
+                status = authorization_right_get(conn,event,reply);
+                break;
+            case AUTHORIZATION_RIGHT_SET:
+                status = authorization_right_set(conn,event,reply);
+                break;
+            case AUTHORIZATION_RIGHT_REMOVE:
+                status = authorization_right_remove(conn,event,reply);
+                break;
+            case SESSION_SET_USER_PREFERENCES:
+                status = session_set_user_preferences(conn,event,reply);
+                break;
+            case AUTHORIZATION_DISMISS:
+                connection_destory_agents(conn);
+                status = errAuthorizationSuccess;
+                break;
+            case AUTHORIZATION_ENABLE_SMARTCARD:
+                status = authorization_enable_smartcard(conn,event,reply);
+                break;
+            case AUTHORIZATION_SETUP:
+                {
+                    mach_port_t bootstrap = xpc_dictionary_copy_mach_send(event, AUTH_XPC_BOOTSTRAP);
+                    if (!process_set_bootstrap(connection_get_process(conn), bootstrap)) {
+                        if (bootstrap != MACH_PORT_NULL) {
+                            mach_port_deallocate(mach_task_self(), bootstrap);
+                        }
+                    }
+                }
+                status = errAuthorizationSuccess;
+                break;
+#if DEBUG
+            case AUTHORIZATION_DEV:
+                server_dev();
+                break;
+#endif
+            default:
+                break;
+        }
+
+        xpc_dictionary_set_int64(reply, AUTH_XPC_STATUS, status);
+        xpc_connection_send_message(connection, reply);
+        xpc_release(reply);
+       }
+
+done:
+    CFReleaseSafe(conn);
+}
+
+static void
+connection_finalizer(void * conn)
+{
+    LOGD("xpc[%i]: connection_finalizer", connection_get_pid(conn));
+    server_unregister_connection(conn);
+
+//#if DEBUG
+//    malloc_printf("-=-=-=- connection_finalizer() -=-=-=-\n");
+//    malloc_zone_print(malloc_default_zone(), false);
+//#endif
+}
+
+static void
+security_auth_event_handler(xpc_connection_t xpc_conn)
+{
+    connection_t conn = server_register_connection(xpc_conn);
+    
+    if (conn) {
+        xpc_connection_set_context(xpc_conn, conn);
+        xpc_connection_set_finalizer_f(xpc_conn, connection_finalizer);
+        
+        xpc_connection_set_event_handler(xpc_conn, ^(xpc_object_t event) {
+            xpc_retain(xpc_conn);
+            xpc_retain(event);
+            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+                security_auth_peer_event_handler(xpc_conn, event);
+                xpc_release(event);
+                xpc_release(xpc_conn);
+            });
+        });
+        xpc_connection_resume(xpc_conn);
+
+    } else {
+        LOGE("xpc[%i]: failed to register connection", xpc_connection_get_pid(xpc_conn));
+        xpc_connection_cancel(xpc_conn);
+    }
+}
+
+static void sandbox()
+{
+    char * errorbuf;
+    int32_t rc;
+    
+    rc = sandbox_init(SECURITY_AUTH_NAME, SANDBOX_NAMED, &errorbuf);
+    
+    if (rc) {
+        LOGE("server: sandbox_init failed %s (%i)", errorbuf, rc);
+        sandbox_free_error(errorbuf);
+#ifndef DEBUG
+        abort();
+#endif
+    }
+}
+
+int main(int argc AUTH_UNUSED, const char *argv[] AUTH_UNUSED)
+{
+//#if DEBUG
+//    malloc_printf("-=-=-=- main() -=-=-=-\n");
+//    malloc_zone_print(malloc_default_zone(), false);
+//#endif
+
+    LOGV("starting");
+    
+    sandbox();
+
+    if (server_init() != errAuthorizationSuccess) {
+        LOGE("auth: server_init() failed");
+        return errAuthorizationInternal;
+    }
+        
+//#if DEBUG
+//    malloc_printf("-=-=-=- server_init() -=-=-=-\n");
+//    malloc_zone_print(malloc_default_zone(), false);
+//#endif
+
+    xpc_main(security_auth_event_handler);
+    
+    server_cleanup();
+    
+       return 0;
+}
diff --git a/authd/mechanism.c b/authd/mechanism.c
new file mode 100644 (file)
index 0000000..e57c820
--- /dev/null
@@ -0,0 +1,324 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#include "mechanism.h"
+#include "authdb.h"
+#include "authutilities.h"
+#include "crc.h"
+#include "debugging.h"
+#include "server.h"
+#include "authitems.h"
+
+#define MECHANISM_ID "id"
+#define MECHANISM_PLUGIN "plugin"
+#define MECHANISM_PARAM "param"
+#define MECHANISM_PRIVILEGED "privileged"
+
+static const char SystemPlugins[] = "/System/Library/CoreServices/SecurityAgentPlugins";
+static const char LibraryPlugins[] = "/Library/Security/SecurityAgentPlugins";
+static const char BuiltinMechanismPrefix[] = "builtin";
+
+typedef struct _mechTypeItem
+{
+    const char * name;
+    uint64_t type;
+} mechTypeItem;
+
+static mechTypeItem mechTypeMap[] =
+{
+    { "entitled", kMechanismTypeEntitled }
+};
+
+struct _mechanism_s {
+    __AUTH_BASE_STRUCT_HEADER__;
+    
+    auth_items_t data;
+
+    bool valid;
+    char * string;
+    
+    uint64_t type;
+};
+
+static void
+_mechanism_finalize(CFTypeRef value)
+{
+    mechanism_t mech = (mechanism_t)value;
+    
+    CFReleaseSafe(mech->data);
+    free_safe(mech->string);
+}
+
+static Boolean
+_mechanism_equal(CFTypeRef value1, CFTypeRef value2)
+{
+    mechanism_t mech1 = (mechanism_t)value1;
+    mechanism_t mech2 = (mechanism_t)value2;
+    
+    if (mech1 == mech2) {
+        return true;
+    }
+    
+    if (!_compare_string(mechanism_get_plugin(mech1), mechanism_get_plugin(mech2))) {
+        return false;
+    }
+    
+    if (!_compare_string(mechanism_get_param(mech1), mechanism_get_param(mech2))) {
+        return false;
+    }
+    
+    return mechanism_is_privileged(mech1) == mechanism_is_privileged(mech2);
+}
+
+static CFStringRef
+_mechanism_copy_description(CFTypeRef value)
+{
+    mechanism_t mech = (mechanism_t)value;
+    return CFCopyDescription(mech->data);
+}
+
+static CFHashCode
+_mechanism_hash(CFTypeRef value)
+{
+    uint64_t crc = crc64_init();
+    mechanism_t mech = (mechanism_t)value;
+    
+    const char * str = mechanism_get_plugin(mech);
+    crc = crc64_update(crc, str, strlen(str));
+    str = mechanism_get_plugin(mech);
+    crc = crc64_update(crc, str, strlen(str));
+    bool priv = mechanism_is_privileged(mech);
+    crc = crc64_update(crc, &priv, sizeof(priv));
+    crc = crc64_final(crc);
+    
+    return crc;
+}
+
+AUTH_TYPE_INSTANCE(mechanism,
+                   .init = NULL,
+                   .copy = NULL,
+                   .finalize = _mechanism_finalize,
+                   .equal = _mechanism_equal,
+                   .hash = _mechanism_hash,
+                   .copyFormattingDesc = NULL,
+                   .copyDebugDesc = _mechanism_copy_description
+                   );
+
+static CFTypeID mechanism_get_type_id() {
+    static CFTypeID type_id = _kCFRuntimeNotATypeID;
+    static dispatch_once_t onceToken;
+    
+    dispatch_once(&onceToken, ^{
+        type_id = _CFRuntimeRegisterClass(&_auth_type_mechanism);
+    });
+    
+    return type_id;
+}
+
+static mechanism_t
+_mechanism_create()
+{
+    mechanism_t mech = (mechanism_t)_CFRuntimeCreateInstance(kCFAllocatorDefault, mechanism_get_type_id(), AUTH_CLASS_SIZE(mechanism), NULL);
+    require(mech != NULL, done);
+    
+    mech->data = auth_items_create();
+    
+done:
+    return mech;
+}
+
+static void _mechanism_set_type(mechanism_t mech)
+{
+    const char * plugin = mechanism_get_plugin(mech);
+    const char * param = mechanism_get_param(mech);
+    if (strncasecmp(plugin, BuiltinMechanismPrefix, sizeof(BuiltinMechanismPrefix)) == 0) {
+        size_t n = sizeof(mechTypeMap)/sizeof(mechTypeItem);
+        for (size_t i = 0; i < n; i++) {
+            if (strcasecmp(mechTypeMap[i].name, param) == 0) {
+                mech->type = mechTypeMap[i].type;
+                break;
+            }
+        }
+    }
+}
+
+mechanism_t
+mechanism_create_with_sql(auth_items_t sql)
+{
+    mechanism_t mech = NULL;
+    require(sql != NULL, done);
+    require(auth_items_get_int64(sql, MECHANISM_ID) != 0, done);
+    
+    mech = _mechanism_create();
+    require(mech != NULL, done);
+    
+    auth_items_copy(mech->data, sql);
+    
+    _mechanism_set_type(mech);
+    
+done:
+    return mech;
+}
+
+mechanism_t
+mechanism_create_with_string(const char * str, authdb_connection_t dbconn)
+{
+    mechanism_t mech = NULL;
+    require(str != NULL, done);
+    require(strchr(str,':') != NULL, done);
+    
+    mech = _mechanism_create();
+    require(mech != NULL, done);
+    
+    const char delimiters[] = ":,";
+    size_t buf_len = strlen(str)+1;
+    char * buf = (char*)calloc(1u, buf_len);
+    strlcpy(buf, str, buf_len);
+    
+    char * tok = strtok(buf, delimiters);
+    if (tok) {
+        auth_items_set_string(mech->data, MECHANISM_PLUGIN, tok);
+    }
+    tok = strtok(NULL, delimiters);
+    if (tok) {
+        auth_items_set_string(mech->data, MECHANISM_PARAM, tok);
+    }
+    tok = strtok(NULL, delimiters);
+    if (tok) {
+        auth_items_set_int64(mech->data, MECHANISM_PRIVILEGED, strcasecmp("privileged", tok) == 0);
+    }
+    free(buf);
+    
+    if (dbconn) {
+        mechanism_sql_fetch(mech, dbconn);
+    }
+    
+    _mechanism_set_type(mech);
+    
+done:
+    return mech;
+}
+
+static
+bool _pluginExists(const char * plugin, const char * base)
+{
+    bool result = false;
+    
+    require(plugin != NULL, done);
+    require(base != NULL, done);
+
+    char filePath[PATH_MAX];
+    char realPath[PATH_MAX+1];
+    snprintf(filePath, sizeof(filePath), "%s/%s.bundle", base, plugin);
+
+    require(realpath(filePath, realPath) != NULL, done);
+    require(strncmp(realPath, base, strlen(base)) == 0, done);
+    
+    if (access(filePath, F_OK) == 0) {
+        result = true;
+    }
+    
+done:
+    return result;
+}
+
+bool
+mechanism_exists(mechanism_t mech)
+{
+    if (mech->valid) {
+        return true;
+    }
+
+    const char * plugin = mechanism_get_plugin(mech);
+    if (plugin == NULL) {
+        return false;
+    }
+    
+    if (strncasecmp(plugin, BuiltinMechanismPrefix, sizeof(BuiltinMechanismPrefix)) == 0) {
+        mech->valid = true;
+        return true;
+    }
+
+    if (_pluginExists(plugin, SystemPlugins)) {
+        mech->valid = true;
+        return true;
+    }
+    
+    if (_pluginExists(plugin,LibraryPlugins)) {
+        mech->valid = true;
+        return true;
+    }
+    
+    return false;
+}
+
+bool
+mechanism_sql_fetch(mechanism_t mech, authdb_connection_t dbconn)
+{
+    __block bool result = false;
+    
+    authdb_step(dbconn, "SELECT id FROM mechanisms WHERE plugin = ? AND param = ? AND privileged = ? LIMIT 1", ^(sqlite3_stmt * stmt) {
+        sqlite3_bind_text(stmt, 1, mechanism_get_plugin(mech), -1, NULL);
+        sqlite3_bind_text(stmt, 2, mechanism_get_param(mech), -1, NULL);
+        sqlite3_bind_int(stmt, 3, mechanism_is_privileged(mech));
+    }, ^bool(auth_items_t data) {
+        result = true;
+        auth_items_copy(mech->data, data);
+        return true;
+    });
+    
+    return result;
+}
+
+bool
+mechanism_sql_commit(mechanism_t mech, authdb_connection_t dbconn)
+{
+    bool result = false;
+
+    result = authdb_step(dbconn, "INSERT INTO mechanisms VALUES (NULL,?,?,?)", ^(sqlite3_stmt *stmt) {
+        sqlite3_bind_text(stmt, 1, mechanism_get_plugin(mech), -1, NULL);
+        sqlite3_bind_text(stmt, 2, mechanism_get_param(mech), -1, NULL);
+        sqlite3_bind_int(stmt, 3, mechanism_is_privileged(mech));
+    }, NULL);
+    
+    return result;
+}
+
+const char *
+mechanism_get_string(mechanism_t mech)
+{
+    if (!mech->string) {
+        asprintf(&mech->string, "%s:%s%s", mechanism_get_plugin(mech), mechanism_get_param(mech), mechanism_is_privileged(mech) ? ",privileged" : "");
+    }
+    
+    return mech->string;
+}
+
+int64_t
+mechanism_get_id(mechanism_t mech)
+{
+    return auth_items_get_int64(mech->data, MECHANISM_ID);
+}
+
+const char *
+mechanism_get_plugin(mechanism_t mech)
+{
+    return auth_items_get_string(mech->data, MECHANISM_PLUGIN);
+}
+
+const char *
+mechanism_get_param(mechanism_t mech)
+{
+    return auth_items_get_string(mech->data, MECHANISM_PARAM);
+}
+
+bool
+mechanism_is_privileged(mechanism_t mech)
+{
+    return auth_items_get_int64(mech->data, MECHANISM_PRIVILEGED);
+}
+
+uint64_t
+mechanism_get_type(mechanism_t mech)
+{
+    return mech->type;
+}
diff --git a/authd/mechanism.h b/authd/mechanism.h
new file mode 100644 (file)
index 0000000..f483a98
--- /dev/null
@@ -0,0 +1,53 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#ifndef _SECURITY_AUTH_MECHANISM_H_
+#define _SECURITY_AUTH_MECHANISM_H_
+
+#include "authdb.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+enum {
+    kMechanismTypeEntitled              = 1
+};
+    
+AUTH_WARN_RESULT AUTH_MALLOC AUTH_NONNULL_ALL AUTH_RETURNS_RETAINED
+mechanism_t mechanism_create_with_sql(auth_items_t);
+
+AUTH_WARN_RESULT AUTH_MALLOC AUTH_NONNULL1 AUTH_RETURNS_RETAINED
+mechanism_t mechanism_create_with_string(const char *,authdb_connection_t);
+    
+AUTH_NONNULL_ALL
+bool mechanism_sql_fetch(mechanism_t,authdb_connection_t);
+    
+AUTH_NONNULL_ALL
+bool mechanism_sql_commit(mechanism_t,authdb_connection_t);
+
+AUTH_NONNULL_ALL
+bool mechanism_exists(mechanism_t);
+
+AUTH_NONNULL_ALL
+const char * mechanism_get_string(mechanism_t);
+    
+AUTH_NONNULL_ALL
+int64_t mechanism_get_id(mechanism_t);
+    
+AUTH_NONNULL_ALL
+const char * mechanism_get_plugin(mechanism_t);
+
+AUTH_NONNULL_ALL
+const char * mechanism_get_param(mechanism_t);
+    
+AUTH_NONNULL_ALL
+uint64_t mechanism_get_type(mechanism_t);
+  
+AUTH_NONNULL_ALL
+bool mechanism_is_privileged(mechanism_t);
+    
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_SECURITY_AUTH_MECHANISM_H_ */
diff --git a/authd/object.c b/authd/object.c
new file mode 100644 (file)
index 0000000..7e50769
--- /dev/null
@@ -0,0 +1,5 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#include "object.h"
+#include "crc.h"
+#include "authutilities.h"
diff --git a/authd/object.h b/authd/object.h
new file mode 100644 (file)
index 0000000..7731f78
--- /dev/null
@@ -0,0 +1,36 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#ifndef _SECURITY_AUTH_OBJECT_H_
+#define _SECURITY_AUTH_OBJECT_H_
+
+#include "authd_private.h"
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreFoundation/CFRuntime.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+    
+#define __AUTH_BASE_STRUCT_HEADER__ \
+    CFRuntimeBase _base;
+    
+struct _auth_base_s {
+    __AUTH_BASE_STRUCT_HEADER__;
+};
+
+#define AUTH_TYPE(type) const CFRuntimeClass type
+    
+#define AUTH_TYPE_INSTANCE(name, ...) \
+    AUTH_TYPE(_auth_type_##name) = { \
+        .version = 0, \
+        .className = #name "_t", \
+        __VA_ARGS__ \
+    }
+
+#define AUTH_CLASS_SIZE(name) (sizeof(struct _##name##_s) - sizeof(CFRuntimeBase))
+    
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_SECURITY_AUTH_OBJECT_H_ */
diff --git a/authd/process.c b/authd/process.c
new file mode 100644 (file)
index 0000000..9f1b216
--- /dev/null
@@ -0,0 +1,484 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#include "process.h"
+#include "server.h"
+#include "session.h"
+#include "debugging.h"
+#include "authd_private.h"
+#include "authtoken.h"
+#include "authutilities.h"
+#include "ccaudit.h"
+
+#include <Security/SecCode.h>
+#include <Security/SecRequirement.h>
+
+struct _process_s {
+    __AUTH_BASE_STRUCT_HEADER__;
+    
+    audit_info_s auditInfo;
+    
+    session_t session;
+    
+    CFMutableBagRef authTokens;
+    dispatch_queue_t dispatch_queue;
+    
+    CFMutableSetRef connections;
+    
+    SecCodeRef codeRef;
+    char code_url[PATH_MAX+1];
+    char * code_identifier;
+    CFDataRef code_requirement_data;
+    SecRequirementRef code_requirement;
+    CFDictionaryRef code_entitlements;
+    
+    mach_port_t bootstrap;
+    
+    bool appleSigned;
+};
+
+static void
+_unregister_auth_tokens(const void *value, void *context)
+{
+    auth_token_t auth = (auth_token_t)value;
+    process_t proc = (process_t)context;
+    
+    CFIndex count = auth_token_remove_process(auth, proc);
+    if ((count == 0)  && auth_token_check_state(auth, auth_token_state_registered)) {
+        server_unregister_auth_token(auth);
+    }
+}
+
+static void
+_destroy_zombie_tokens(process_t proc)
+{
+    LOGD("process[%i] destroy zombies, %ld auth tokens", process_get_pid(proc), CFBagGetCount(proc->authTokens));
+    _cf_bag_iterate(proc->authTokens, ^bool(CFTypeRef value) {
+        auth_token_t auth = (auth_token_t)value;
+        LOGD("process[%i] %p, creator=%i, zombie=%i, process_cout=%ld", process_get_pid(proc), auth, auth_token_is_creator(auth, proc), auth_token_check_state(auth, auth_token_state_zombie), auth_token_get_process_count(auth));
+        if (auth_token_is_creator(auth, proc) && auth_token_check_state(auth, auth_token_state_zombie) && (auth_token_get_process_count(auth) == 1)) {
+            CFBagRemoveValue(proc->authTokens, auth);
+        }
+        return true;
+    });
+}
+
+static void
+_process_finalize(CFTypeRef value)
+{
+    process_t proc = (process_t)value;
+
+    LOGV("process[%i]: deallocated %p", proc->auditInfo.pid, proc);
+    
+    dispatch_barrier_sync(proc->dispatch_queue, ^{
+        CFBagApplyFunction(proc->authTokens, _unregister_auth_tokens, proc);
+    });
+    
+    session_remove_process(proc->session, proc);
+    
+    dispatch_release(proc->dispatch_queue);
+    CFReleaseSafe(proc->authTokens);
+    CFReleaseSafe(proc->connections);
+    CFReleaseSafe(proc->session);
+    CFReleaseSafe(proc->codeRef);
+    CFReleaseSafe(proc->code_requirement);
+    CFReleaseSafe(proc->code_requirement_data);
+    CFReleaseSafe(proc->code_entitlements);
+    free_safe(proc->code_identifier);
+    if (proc->bootstrap != MACH_PORT_NULL) {
+        mach_port_deallocate(mach_task_self(), proc->bootstrap);
+    }
+}
+
+AUTH_TYPE_INSTANCE(process,
+                   .init = NULL,
+                   .copy = NULL,
+                   .finalize = _process_finalize,
+                   .equal = NULL,
+                   .hash = NULL,
+                   .copyFormattingDesc = NULL,
+                   .copyDebugDesc = NULL
+                   );
+
+static CFTypeID process_get_type_id() {
+    static CFTypeID type_id = _kCFRuntimeNotATypeID;
+    static dispatch_once_t onceToken;
+    
+    dispatch_once(&onceToken, ^{
+        type_id = _CFRuntimeRegisterClass(&_auth_type_process);
+    });
+    
+    return type_id;
+}
+
+process_t
+process_create(const audit_info_s * auditInfo, session_t session)
+{
+    OSStatus status = errSecSuccess;
+    process_t proc = NULL;
+    CFDictionaryRef code_info = NULL;
+    CFURLRef code_url = NULL;
+
+    require(session != NULL, done);
+    require(auditInfo != NULL, done);
+    
+    proc = (process_t)_CFRuntimeCreateInstance(kCFAllocatorDefault, process_get_type_id(), AUTH_CLASS_SIZE(process), NULL);
+    require(proc != NULL, done);
+    
+    proc->auditInfo = *auditInfo;
+    
+    proc->session = (session_t)CFRetain(session);
+    
+    proc->connections = CFSetCreateMutable(kCFAllocatorDefault, 0, NULL);
+    
+    proc->authTokens = CFBagCreateMutable(kCFAllocatorDefault, 0, &kCFTypeBagCallBacks);
+    check(proc->authTokens != NULL);
+    
+    proc->dispatch_queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
+    check(proc->dispatch_queue != NULL);
+
+    CFMutableDictionaryRef codeDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    CFNumberRef codePid = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &proc->auditInfo.pid);
+    CFDictionarySetValue(codeDict, kSecGuestAttributePid, codePid);
+    status = SecCodeCopyGuestWithAttributes(NULL, codeDict, kSecCSDefaultFlags, &proc->codeRef);
+    CFReleaseSafe(codeDict);
+    CFReleaseSafe(codePid);
+
+    if (status) {
+        LOGE("process[%i]: failed to create code ref %i", proc->auditInfo.pid, status);
+        CFReleaseNull(proc);
+        goto done;
+    }
+    
+    status = SecCodeCopySigningInformation(proc->codeRef, kSecCSRequirementInformation, &code_info);
+    require_noerr_action(status, done, LOGV("process[%i]: SecCodeCopySigningInformation failed with %i", proc->auditInfo.pid, status));
+
+    CFTypeRef value = NULL;
+    if (CFDictionaryGetValueIfPresent(code_info, kSecCodeInfoDesignatedRequirement, (const void**)&value)) {
+        if (CFGetTypeID(value) == SecRequirementGetTypeID()) {
+            SecRequirementCopyData((SecRequirementRef)value, kSecCSDefaultFlags, &proc->code_requirement_data);
+            if (proc->code_requirement_data) {
+                SecRequirementCreateWithData(proc->code_requirement_data, kSecCSDefaultFlags, &proc->code_requirement);
+            }
+        }
+        value = NULL;
+    }
+
+    if (SecCodeCopyPath(proc->codeRef, kSecCSDefaultFlags, &code_url) == errSecSuccess) {
+        CFURLGetFileSystemRepresentation(code_url, true, (UInt8*)proc->code_url, sizeof(proc->code_url));
+    }
+
+    if (CFDictionaryGetValueIfPresent(code_info, kSecCodeInfoIdentifier, &value)) {
+        if (CFGetTypeID(value) == CFStringGetTypeID()) {
+            proc->code_identifier = _copy_cf_string(value, NULL);
+        }
+        value = NULL;
+    }
+    
+    if (CFDictionaryGetValueIfPresent(code_info, kSecCodeInfoEntitlementsDict, &value)) {
+        if (CFGetTypeID(value) == CFDictionaryGetTypeID()) {
+            proc->code_entitlements = CFDictionaryCreateCopy(kCFAllocatorDefault, value);
+        }
+        value = NULL;
+    }
+
+    // This is the clownfish supported way to check for a Mac App Store or B&I signed build
+    CFStringRef requirementString = CFSTR("(anchor apple) or (anchor apple generic and certificate leaf[field.1.2.840.113635.100.6.1.9])");
+    SecRequirementRef  secRequirementRef = NULL;
+    status = SecRequirementCreateWithString(requirementString, kSecCSDefaultFlags, &secRequirementRef);
+    if (status == errSecSuccess) {
+        proc->appleSigned = process_verify_requirment(proc, secRequirementRef);
+    }
+    CFRelease(secRequirementRef);
+
+    LOGV("process[%i]: created (sid=%i) %s %p", proc->auditInfo.pid, proc->auditInfo.asid, proc->code_url, proc);
+
+done:
+    CFReleaseSafe(code_info);
+    CFReleaseSafe(code_url);
+    return proc;
+}
+
+const void *
+process_get_key(process_t proc)
+{
+    return &proc->auditInfo;
+}
+
+uid_t
+process_get_uid(process_t proc)
+{
+    return proc ? proc->auditInfo.euid : (uid_t)-2;
+}
+
+pid_t
+process_get_pid(process_t proc)
+{
+    return proc ? proc->auditInfo.pid : -1;
+}
+
+int32_t process_get_generation(process_t proc)
+{
+    return proc->auditInfo.tid;
+}
+
+session_id_t
+process_get_session_id(process_t proc)
+{
+    return proc ? proc->auditInfo.asid : -1;
+}
+
+session_t
+process_get_session(process_t proc)
+{
+    return proc->session;
+}
+
+const audit_info_s *
+process_get_audit_info(process_t proc)
+{
+    return &proc->auditInfo;
+}
+
+SecCodeRef
+process_get_code(process_t proc)
+{
+    return proc->codeRef;
+}
+
+const char *
+process_get_code_url(process_t proc)
+{
+    return proc->code_url;
+}
+
+void
+process_add_auth_token(process_t proc, auth_token_t auth)
+{
+    dispatch_sync(proc->dispatch_queue, ^{
+        CFBagAddValue(proc->authTokens, auth);
+        if (CFBagGetCountOfValue(proc->authTokens, auth) == 1) {
+            auth_token_add_process(auth, proc);
+        }
+    });
+}
+
+void
+process_remove_auth_token(process_t proc, auth_token_t auth, AuthorizationFlags flags)
+{
+    dispatch_sync(proc->dispatch_queue, ^{
+        bool destroy = false;
+        bool creator = auth_token_is_creator(auth, proc);
+        CFIndex count = auth_token_get_process_count(auth);
+
+        // if we are the last ones associated with this auth token or the caller passed in the kAuthorizationFlagDestroyRights
+        // then we break the link between the process and auth token.  If another process holds a reference
+        // then kAuthorizationFlagDestroyRights will only break the link and not destroy the auth token
+        // <rdar://problem/14553640>
+        if ((count == 1) ||
+            (flags & kAuthorizationFlagDestroyRights))
+        {
+            destroy = true;
+            goto done;
+        }
+
+        // If we created this token and someone else is holding a reference to it
+        // don't destroy the link until they have freed the authorization ref
+        // instead set the zombie state on the auth_token
+        if (creator) {
+            if (CFBagGetCountOfValue(proc->authTokens, auth) == 1) {
+                auth_token_set_state(auth, auth_token_state_zombie);
+            } else {
+                destroy = true;
+            }
+        } else {
+            destroy = true;
+        }
+
+    done:
+        if (destroy) {
+            CFBagRemoveValue(proc->authTokens, auth);
+            if (!CFBagContainsValue(proc->authTokens, auth)) {
+                auth_token_remove_process(auth, proc);
+
+                if ((count == 1) && auth_token_check_state(auth, auth_token_state_registered)) {
+                    server_unregister_auth_token(auth);
+                }
+            }
+        }
+
+        // destroy all eligible zombies
+        _destroy_zombie_tokens(proc);
+    });
+}
+
+auth_token_t
+process_find_copy_auth_token(process_t proc, const AuthorizationBlob * blob)
+{
+    __block CFTypeRef auth = NULL;
+    dispatch_sync(proc->dispatch_queue, ^{
+        _cf_bag_iterate(proc->authTokens, ^bool(CFTypeRef value) {
+            auth_token_t iter = (auth_token_t)value;
+            if (memcmp(blob, auth_token_get_blob(iter), sizeof(AuthorizationBlob)) == 0) {
+                auth = iter;
+                CFRetain(auth);
+                return false;
+            }
+            return true;
+        });
+    });
+    return (auth_token_t)auth;
+}
+
+CFIndex
+process_get_auth_token_count(process_t proc)
+{
+    __block CFIndex count = 0;
+    dispatch_sync(proc->dispatch_queue, ^{
+        count = CFBagGetCount(proc->authTokens);
+    });
+    return count;
+}
+
+CFIndex
+process_add_connection(process_t proc, connection_t conn)
+{
+    __block CFIndex count = 0;
+    dispatch_sync(proc->dispatch_queue, ^{
+        CFSetAddValue(proc->connections, conn);
+        count = CFSetGetCount(proc->connections);
+    });
+    return count;
+}
+
+CFIndex
+process_remove_connection(process_t proc, connection_t conn)
+{
+    __block CFIndex count = 0;
+    dispatch_sync(proc->dispatch_queue, ^{
+        CFSetRemoveValue(proc->connections, conn);
+        count = CFSetGetCount(proc->connections);
+    });
+    return count;
+}
+
+CFIndex
+process_get_connection_count(process_t proc)
+{
+    __block CFIndex count = 0;
+    dispatch_sync(proc->dispatch_queue, ^{
+        count = CFSetGetCount(proc->connections);
+    });
+    return count;
+}
+
+CFTypeRef
+process_copy_entitlement_value(process_t proc, const char * entitlement)
+{
+    CFTypeRef value = NULL;
+    require(entitlement != NULL, done);
+
+    CFStringRef key = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, entitlement, kCFStringEncodingUTF8, kCFAllocatorNull);
+    if (proc->code_entitlements && key && (CFDictionaryGetValueIfPresent(proc->code_entitlements, key, &value))) {
+        CFRetainSafe(value);
+    }
+    CFReleaseSafe(key);
+    
+done:
+    return value;
+}
+
+bool
+process_has_entitlement(process_t proc, const char * entitlement)
+{
+    bool entitled = false;
+    require(entitlement != NULL, done);
+
+    CFStringRef key = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, entitlement, kCFStringEncodingUTF8, kCFAllocatorNull);
+    CFTypeRef value = NULL;
+    if (proc->code_entitlements && key && (CFDictionaryGetValueIfPresent(proc->code_entitlements, key, &value))) {
+        if (CFGetTypeID(value) == CFBooleanGetTypeID()) {
+            entitled = CFBooleanGetValue(value);
+        }
+    }
+    CFReleaseSafe(key);
+    
+done:
+    return entitled;
+}
+
+bool
+process_has_entitlement_for_right(process_t proc, const char * right)
+{
+    bool entitled = false;
+    require(right != NULL, done);
+
+    CFTypeRef rights = NULL;
+    if (proc->code_entitlements && CFDictionaryGetValueIfPresent(proc->code_entitlements, CFSTR("com.apple.private.AuthorizationServices"), &rights)) {
+        if (CFGetTypeID(rights) == CFArrayGetTypeID()) {
+            CFStringRef key = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, right, kCFStringEncodingUTF8, kCFAllocatorNull);
+            require(key != NULL, done);
+            
+            CFIndex count = CFArrayGetCount(rights);
+            for (CFIndex i = 0; i < count; i++) {
+                if (CFEqual(CFArrayGetValueAtIndex(rights, i), key)) {
+                    entitled = true;
+                    break;
+                }
+            }
+            CFReleaseSafe(key);
+        }
+    }
+    
+done:
+    return entitled;
+}
+
+const char *
+process_get_identifier(process_t proc)
+{
+    return proc->code_identifier;
+}
+
+CFDataRef
+process_get_requirement_data(process_t proc)
+{
+    return proc->code_requirement_data;
+}
+
+SecRequirementRef
+process_get_requirement(process_t proc)
+{
+    return proc->code_requirement;
+}
+
+bool process_verify_requirment(process_t proc, SecRequirementRef requirment)
+{
+    OSStatus status = SecCodeCheckValidity(proc->codeRef, kSecCSDefaultFlags, requirment);
+    if (status != errSecSuccess) {
+        LOGV("process[%i]: code requirement check failed (%d)", proc->auditInfo.pid, status);
+    }
+    return (status == errSecSuccess);
+}
+
+// Returns true if the process was signed by B&I or the Mac App Store
+bool process_apple_signed(process_t proc) {
+    return proc->appleSigned;
+}
+
+mach_port_t process_get_bootstrap(process_t proc)
+{
+    return proc->bootstrap;
+}
+
+bool process_set_bootstrap(process_t proc, mach_port_t bootstrap)
+{
+    if (bootstrap != MACH_PORT_NULL) {
+        if (proc->bootstrap != MACH_PORT_NULL) {
+            mach_port_deallocate(mach_task_self(), proc->bootstrap);
+        }
+        proc->bootstrap = bootstrap;
+        return true;
+    }
+    return false;
+}
+
diff --git a/authd/process.h b/authd/process.h
new file mode 100644 (file)
index 0000000..94e5d29
--- /dev/null
@@ -0,0 +1,102 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#ifndef _SECURITY_AUTH_PROCESS_H_
+#define _SECURITY_AUTH_PROCESS_H_
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCode.h>
+#include <mach/mach.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+    
+AUTH_WARN_RESULT AUTH_MALLOC AUTH_NONNULL_ALL AUTH_RETURNS_RETAINED
+process_t process_create(const audit_info_s*,session_t);
+
+AUTH_NONNULL_ALL
+const void * process_get_key(process_t);
+    
+AUTH_NONNULL_ALL
+uid_t process_get_uid(process_t);
+
+AUTH_NONNULL_ALL
+pid_t process_get_pid(process_t);
+
+AUTH_NONNULL_ALL
+int32_t process_get_generation(process_t);
+    
+AUTH_NONNULL_ALL
+session_id_t process_get_session_id(process_t);
+
+AUTH_NONNULL_ALL
+session_t process_get_session(process_t);
+
+AUTH_NONNULL_ALL
+uint32_t process_get_count(process_t);
+
+AUTH_NONNULL_ALL
+const audit_info_s * process_get_audit_info(process_t);
+    
+AUTH_NONNULL_ALL    
+SecCodeRef process_get_code(process_t);
+    
+AUTH_NONNULL_ALL    
+const char * process_get_code_url(process_t);
+    
+AUTH_NONNULL_ALL
+CFIndex process_add_connection(process_t, connection_t);
+
+AUTH_NONNULL_ALL
+CFIndex process_remove_connection(process_t, connection_t);
+
+AUTH_NONNULL_ALL
+CFIndex process_get_connection_count(process_t);
+    
+AUTH_NONNULL_ALL
+void process_add_auth_token(process_t,auth_token_t);
+
+AUTH_NONNULL_ALL
+void process_remove_auth_token(process_t,auth_token_t, uint32_t flags);
+
+AUTH_NONNULL_ALL
+auth_token_t process_find_copy_auth_token(process_t,const AuthorizationBlob*);
+
+AUTH_NONNULL_ALL
+CFIndex process_get_auth_token_count(process_t);
+
+AUTH_NONNULL_ALL
+CFTypeRef process_copy_entitlement_value(process_t, const char * entitlement);
+    
+AUTH_NONNULL_ALL
+bool process_has_entitlement(process_t, const char * entitlement);
+    
+AUTH_NONNULL_ALL
+bool process_has_entitlement_for_right(process_t, const char * right);
+
+AUTH_NONNULL_ALL
+const char * process_get_identifier(process_t);
+
+AUTH_NONNULL_ALL
+CFDataRef process_get_requirement_data(process_t);
+    
+AUTH_NONNULL_ALL
+SecRequirementRef process_get_requirement(process_t);
+    
+AUTH_NONNULL_ALL
+bool process_verify_requirment(process_t,SecRequirementRef);
+
+AUTH_NONNULL_ALL
+bool process_apple_signed(process_t proc);
+
+AUTH_NONNULL_ALL
+mach_port_t process_get_bootstrap(process_t);
+    
+AUTH_NONNULL_ALL
+bool process_set_bootstrap(process_t, mach_port_t);
+    
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_SECURITY_AUTH_PROCESS_H_ */
diff --git a/authd/rule.c b/authd/rule.c
new file mode 100644 (file)
index 0000000..bf31c89
--- /dev/null
@@ -0,0 +1,1213 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#include "rule.h"
+#include "authutilities.h"
+#include "mechanism.h"
+#include "crc.h"
+#include "debugging.h"
+#include "authitems.h"
+#include "process.h"
+
+#include <Security/AuthorizationDB.h>
+#include <Security/AuthorizationTagsPriv.h>
+#include "server.h"
+
+static void _sql_get_id(rule_t,authdb_connection_t);
+static RuleClass _get_cf_rule_class(CFTypeRef);
+static bool _copy_cf_rule_mechanisms(rule_t,CFTypeRef,authdb_connection_t);
+static bool _copy_cf_rule_delegations(rule_t, CFTypeRef,authdb_connection_t);
+
+#define kMaximumAuthorizationTries 10000
+
+#define RULE_ID "id"
+#define RULE_NAME "name"
+#define RULE_TYPE "type"
+#define RULE_CLASS "class"
+#define RULE_GROUP "group"
+#define RULE_KOFN   "kofn"
+#define RULE_TIMEOUT "timeout"
+#define RULE_FLAGS "flags"
+#define RULE_TRIES "tries"
+#define RULE_COMMENT "comment"
+#define RULE_VERSION "version"
+#define RULE_CREATED "created"
+#define RULE_MODIFIED "modified"
+#define RULE_IDENTIFIER "identifier"
+#define RULE_REQUIREMENT "requirement"
+#define RULE_HASH "hash"
+
+struct _rule_s {
+    __AUTH_BASE_STRUCT_HEADER__;
+
+    auth_items_t data;
+    CFMutableArrayRef mechanisms;
+    CFMutableArrayRef delegations;
+    
+    CFMutableDictionaryRef loc_prompts;
+    CFMutableDictionaryRef loc_buttons;
+    
+    CFDataRef requirement_data;
+    SecRequirementRef requirement;
+};
+
+static void
+_rule_finalize(CFTypeRef value)
+{
+    rule_t rule = (rule_t)value;
+    CFReleaseSafe(rule->data);
+    CFReleaseSafe(rule->mechanisms);
+    CFReleaseSafe(rule->delegations);
+    CFReleaseSafe(rule->loc_prompts);
+    CFReleaseSafe(rule->loc_buttons);
+    CFReleaseSafe(rule->requirement_data);
+    CFReleaseSafe(rule->requirement);
+}
+
+static Boolean
+_rule_equal(CFTypeRef value1, CFTypeRef value2)
+{
+    rule_t rule1 = (rule_t)value1;
+    rule_t rule2 = (rule_t)value2;
+    
+    return strcasecmp(rule_get_name(rule1), rule_get_name(rule2)) == 0;
+}
+
+static CFStringRef
+_rule_copy_description(CFTypeRef value)
+{
+    rule_t rule = (rule_t)value;
+    CFMutableStringRef str = CFStringCreateMutable(kCFAllocatorDefault, 0);
+    CFStringRef tmp = CFCopyDescription(rule->data);
+    CFStringAppend(str, tmp);
+    CFReleaseNull(tmp);
+    tmp = CFCopyDescription(rule->mechanisms);
+    CFStringAppend(str, tmp);
+    CFReleaseNull(tmp);
+    tmp = CFCopyDescription(rule->delegations);
+    CFStringAppend(str, tmp);
+    CFReleaseNull(tmp);
+    return str;
+}
+
+static CFHashCode
+_rule_hash(CFTypeRef value)
+{
+    rule_t rule = (rule_t)value;
+    const char * str = rule_get_name(rule);
+    return crc64(str, strlen(str));
+}
+
+AUTH_TYPE_INSTANCE(rule,
+                   .init = NULL,
+                   .copy = NULL,
+                   .finalize = _rule_finalize,
+                   .equal = _rule_equal,
+                   .hash = _rule_hash,
+                   .copyFormattingDesc = NULL,
+                   .copyDebugDesc = _rule_copy_description
+                   );
+
+static CFTypeID rule_get_type_id() {
+    static CFTypeID type_id = _kCFRuntimeNotATypeID;
+    static dispatch_once_t onceToken;
+    
+    dispatch_once(&onceToken, ^{
+        type_id = _CFRuntimeRegisterClass(&_auth_type_rule);
+    });
+    
+    return type_id;
+}
+
+static rule_t
+_rule_create()
+{
+    rule_t rule = (rule_t)_CFRuntimeCreateInstance(kCFAllocatorDefault, rule_get_type_id(), AUTH_CLASS_SIZE(rule), NULL);
+    require(rule != NULL, done);
+    
+    rule->data = auth_items_create();
+    rule->delegations = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+    rule->mechanisms = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+    
+done:
+    return rule;
+}
+
+static rule_t
+_rule_create_with_sql(auth_items_t sql)
+{
+    rule_t rule = NULL;
+    require(sql != NULL, done);
+    
+    rule = _rule_create();
+    require(rule != NULL, done);
+    
+    auth_items_copy(rule->data, sql);
+    
+done:
+    return rule;
+}
+
+rule_t
+rule_create_default()
+{
+    rule_t rule = _rule_create();
+    require(rule != NULL, done);
+
+    auth_items_set_int64(rule->data, RULE_TYPE, RT_RIGHT);
+    auth_items_set_string(rule->data, RULE_NAME, "(default)");
+    auth_items_set_int64(rule->data, RULE_CLASS, RC_USER);
+    auth_items_set_string(rule->data, RULE_GROUP, "admin");
+    auth_items_set_int64(rule->data, RULE_TIMEOUT, 300);
+    auth_items_set_int64(rule->data, RULE_TRIES, kMaximumAuthorizationTries);
+    auth_items_set_int64(rule->data, RULE_FLAGS, RuleFlagShared | RuleFlagAuthenticateUser);
+    
+    mechanism_t mech = mechanism_create_with_string("builtin:authenticate", NULL);
+    CFArrayAppendValue(rule->mechanisms, mech);
+    CFReleaseNull(mech);
+
+    mech = mechanism_create_with_string("builtin:reset-password,privileged", NULL);
+    CFArrayAppendValue(rule->mechanisms, mech);
+    CFReleaseNull(mech);
+
+    mech = mechanism_create_with_string("builtin:authenticate,privileged", NULL);
+    CFArrayAppendValue(rule->mechanisms, mech);
+    CFReleaseNull(mech);
+
+    mech = mechanism_create_with_string("PKINITMechanism:auth,privileged", NULL);
+    CFArrayAppendValue(rule->mechanisms, mech);
+    CFReleaseNull(mech);
+    
+done:
+    return rule;
+}
+
+rule_t
+rule_create_with_string(const char * str, authdb_connection_t dbconn)
+{
+    rule_t rule = NULL;
+    require(str != NULL, done);
+    
+    rule = _rule_create();
+    require(rule != NULL, done);
+    
+    auth_items_set_string(rule->data, RULE_NAME, str);
+
+    if (dbconn) {
+        rule_sql_fetch(rule, dbconn);
+    }
+    
+done:
+    return rule;
+}
+
+static void _set_data_string(rule_t rule, const char * key, CFStringRef str)
+{
+    char * tmpStr = _copy_cf_string(str, NULL);
+    
+    if (tmpStr) {
+        auth_items_set_string(rule->data, key, tmpStr);
+        free_safe(tmpStr);
+    }
+}
+
+rule_t
+rule_create_with_plist(RuleType type, CFStringRef name, CFDictionaryRef plist, authdb_connection_t dbconn)
+{
+    rule_t rule = NULL;
+    require(name != NULL, done);
+    require(plist != NULL, done);
+            
+    rule = _rule_create();
+    require(rule != NULL, done);
+    
+    _set_data_string(rule, RULE_NAME, name);
+    require_action(rule_get_name(rule) != NULL, done, CFReleaseSafe(rule));
+    
+    _sql_get_id(rule, dbconn);
+
+    auth_items_set_int64(rule->data, RULE_TYPE, type);
+    
+    auth_items_set_int64(rule->data, RULE_CLASS, _get_cf_rule_class(CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleClass))));
+    _set_data_string(rule, RULE_COMMENT, CFDictionaryGetValue(plist, CFSTR(kAuthorizationComment)));
+
+    
+    CFTypeRef loc_tmp = CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterDefaultPrompt));
+    if (loc_tmp) {
+        rule->loc_prompts = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, loc_tmp);
+    }
+    loc_tmp = CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterDefaultButton));
+    if (loc_tmp) {
+        rule->loc_buttons = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, loc_tmp);
+    }
+    
+    auth_items_set_int64(rule->data, RULE_VERSION, _get_cf_int(CFDictionaryGetValue(plist, CFSTR("version")), 0));
+    
+    RuleFlags flags = 0;
+    
+    if (_get_cf_bool(CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterEntitled)), false)) {
+        flags |= RuleFlagEntitled;
+    }
+    
+    if (_get_cf_bool(CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterRequireAppleSigned)), false)) {
+        flags |= RuleFlagRequireAppleSigned;
+    }
+    
+    switch (rule_get_class(rule)) {
+        case RC_USER:
+            _set_data_string(rule, RULE_GROUP, CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterGroup)));
+            auth_items_set_int64(rule->data, RULE_TIMEOUT, _get_cf_int(CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterCredentialTimeout)), INT32_MAX));
+            auth_items_set_int64(rule->data, RULE_TRIES, _get_cf_int(CFDictionaryGetValue(plist, CFSTR("tries")), kMaximumAuthorizationTries));
+
+            if (_get_cf_bool(CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterCredentialShared)), false)) {
+                flags |= RuleFlagShared;
+            }
+            if (_get_cf_bool(CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterAllowRoot)), false)) {
+                flags |= RuleFlagAllowRoot;
+            }
+            if (_get_cf_bool(CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterCredentialSessionOwner)), false)) {
+                flags |= RuleFlagSessionOwner;
+            }
+            if (_get_cf_bool(CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterAuthenticateUser)), true)) {
+                flags |= RuleFlagAuthenticateUser;
+            }
+            if (_get_cf_bool(CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterExtractPassword)), false)) {
+                flags |= RuleFlagExtractPassword;
+            }
+            if (_get_cf_bool(CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterEntitledAndGroup)), false)) {
+                flags |= RuleFlagEntitledAndGroup;
+            }
+            if (_get_cf_bool(CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterVPNEntitledAndGroup)), false)) {
+                flags |= RuleFlagVPNEntitledAndGroup;
+            }
+           
+            _copy_cf_rule_mechanisms(rule, CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterMechanisms)), dbconn);
+            
+            break;
+        case RC_RULE:
+            auth_items_set_int64(rule->data, RULE_KOFN, _get_cf_int(CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterKofN)), 0));
+            
+            _copy_cf_rule_delegations(rule, CFDictionaryGetValue(plist, CFSTR(kAuthorizationRightRule)), dbconn);
+            break;
+        case RC_MECHANISM:
+            auth_items_set_int64(rule->data, RULE_TRIES, _get_cf_int(CFDictionaryGetValue(plist, CFSTR("tries")), kMaximumAuthorizationTries));
+            if (_get_cf_bool(CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterCredentialShared)), true)) {
+                flags |= RuleFlagShared;
+            }
+            if (_get_cf_bool(CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterExtractPassword)), false)) {
+                flags |= RuleFlagExtractPassword;
+            }
+            
+            _copy_cf_rule_mechanisms(rule, CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterMechanisms)), dbconn);
+            
+            break;
+        case RC_DENY:
+            break;
+        case RC_ALLOW:
+            break;
+        default:
+            LOGD("rule: invalid rule class");
+            break;
+    }
+    
+    auth_items_set_int64(rule->data, RULE_FLAGS, flags);
+    
+done:
+    return rule;
+}
+
+static void
+_sql_get_id(rule_t rule, authdb_connection_t dbconn)
+{
+    authdb_step(dbconn, "SELECT id,created,identifier,requirement FROM rules WHERE name = ? LIMIT 1",
+    ^(sqlite3_stmt *stmt) {
+        sqlite3_bind_text(stmt, 1, rule_get_name(rule), -1, NULL);
+    }, ^bool(auth_items_t data) {
+        auth_items_copy(rule->data, data);
+        return true;
+    });
+}
+
+static bool
+_copy_cf_rule_delegations(rule_t rule, CFTypeRef value, authdb_connection_t dbconn)
+{
+    bool result = false;
+    char * tmp_str = NULL;
+    require(value != NULL, done);
+    
+    if (CFGetTypeID(value) == CFStringGetTypeID()) {
+        tmp_str = _copy_cf_string(value, NULL);
+        rule_t delegate = rule_create_with_string(tmp_str, dbconn);
+        free_safe(tmp_str);
+        if (delegate) {
+            CFArrayAppendValue(rule->delegations, delegate);
+            CFReleaseSafe(delegate);
+        }
+    } else { //array
+        CFIndex count = CFArrayGetCount(value);
+        for (CFIndex i = 0; i < count; i++) {
+            tmp_str = _copy_cf_string(CFArrayGetValueAtIndex(value,i), NULL);
+            rule_t delegate = rule_create_with_string(tmp_str, dbconn);
+            free_safe(tmp_str);
+            if (delegate) {
+                CFArrayAppendValue(rule->delegations, delegate);
+                CFReleaseSafe(delegate);
+            }
+        }
+    }
+
+    result = true;
+    
+done:
+    return result;
+}
+
+static bool
+_copy_cf_rule_mechanisms(rule_t rule, CFTypeRef array, authdb_connection_t dbconn)
+{
+    bool result = false;
+    require(array != NULL, done);
+    require(CFGetTypeID(array) == CFArrayGetTypeID(), done);
+    
+    CFIndex count = CFArrayGetCount(array);
+    for (CFIndex i = 0; i < count; i++) {
+        mechanism_t mech = NULL;
+        char * string = _copy_cf_string(CFArrayGetValueAtIndex(array, i), NULL);
+
+        if (!string)
+            continue;
+        
+        mech = mechanism_create_with_string(string, dbconn);
+        if (mech) {
+            CFArrayAppendValue(rule->mechanisms, mech);
+            CFReleaseSafe(mech);
+        }
+        free(string);
+    }
+    
+    result = true;
+    
+done:
+    return result;
+}
+
+static RuleClass
+_get_cf_rule_class(CFTypeRef str)
+{
+    RuleClass rc = RC_RULE;
+    require(str != NULL, done);
+    require(CFGetTypeID(str) == CFStringGetTypeID(), done);
+
+    if (CFEqual(str, CFSTR(kAuthorizationRuleClassUser)))
+        return RC_USER;
+    
+    if (CFEqual(str, CFSTR(kAuthorizationRightRule)))
+        return RC_RULE;
+    
+    if (CFEqual(str, CFSTR(kAuthorizationRuleClassMechanisms)))
+        return RC_MECHANISM;
+    
+    if (CFEqual(str, CFSTR(kAuthorizationRuleClassDeny)))
+        return RC_DENY;
+    
+    if (CFEqual(str, CFSTR(kAuthorizationRuleClassAllow)))
+        return RC_ALLOW;
+    
+done:
+    return rc;
+}
+
+static bool
+_sql_bind(rule_t rule, sqlite3_stmt * stmt)
+{
+    int64_t n;
+    int32_t rc = 0;
+    require(stmt != NULL, err);
+
+    int32_t column = 1;
+    rc = sqlite3_bind_text(stmt, column++, rule_get_name(rule), -1, NULL);
+    require_noerr(rc, err);
+    rc = sqlite3_bind_int(stmt, column++, rule_get_type(rule));
+    require_noerr(rc, err);
+    rc = sqlite3_bind_int(stmt, column++, rule_get_class(rule));
+    require_noerr(rc, err);
+    
+    switch (rule_get_class(rule)) {
+        case RC_USER:
+            rc = sqlite3_bind_text(stmt, column++, rule_get_group(rule), -1, NULL);
+            require_noerr(rc, err);
+            rc = sqlite3_bind_null(stmt, column++); // kofn
+            require_noerr(rc, err);
+            rc = sqlite3_bind_int64(stmt, column++, rule_get_timeout(rule));
+            require_noerr(rc, err);
+            rc = sqlite3_bind_int64(stmt, column++, auth_items_get_int64(rule->data, RULE_FLAGS));
+            require_noerr(rc, err);
+            rc = sqlite3_bind_int64(stmt, column++, rule_get_tries(rule));
+            require_noerr(rc, err);
+            break;
+        case RC_RULE:
+            rc = sqlite3_bind_null(stmt, column++); // group
+            require_noerr(rc, err);
+            n = rule_get_kofn(rule);
+            if (n) {
+                rc = sqlite3_bind_int64(stmt, column++, n);
+            } else {
+                rc = sqlite3_bind_null(stmt, column++);
+            }
+            require_noerr(rc, err);
+            rc = sqlite3_bind_null(stmt, column++); // timeout
+            require_noerr(rc, err);
+            rc = sqlite3_bind_int64(stmt, column++, auth_items_get_int64(rule->data, RULE_FLAGS));
+            require_noerr(rc, err);
+            rc = sqlite3_bind_null(stmt, column++); // tries
+            require_noerr(rc, err);
+            break;
+        case RC_MECHANISM:
+            rc = sqlite3_bind_null(stmt, column++); // group
+            require_noerr(rc, err);
+            rc = sqlite3_bind_null(stmt, column++); // kofn
+            require_noerr(rc, err);
+            rc = sqlite3_bind_null(stmt, column++); // timeout
+            require_noerr(rc, err);
+            rc = sqlite3_bind_int64(stmt, column++, auth_items_get_int64(rule->data, RULE_FLAGS));
+            require_noerr(rc, err);
+            rc = sqlite3_bind_int64(stmt, column++, rule_get_tries(rule));
+            require_noerr(rc, err);
+            break;
+        case RC_DENY:
+        case RC_ALLOW:
+            rc = sqlite3_bind_null(stmt, column++); // group
+            require_noerr(rc, err);
+            rc = sqlite3_bind_null(stmt, column++); // kofn
+            require_noerr(rc, err);
+            rc = sqlite3_bind_null(stmt, column++); // timeout
+            require_noerr(rc, err);
+            rc = sqlite3_bind_int64(stmt, column++, auth_items_get_int64(rule->data, RULE_FLAGS));
+            require_noerr(rc, err);
+            rc = sqlite3_bind_null(stmt, column++); // tries
+            require_noerr(rc, err);
+            break;
+        default:
+            LOGD("rule: sql bind, invalid rule class");
+            break;
+    }
+
+    rc = sqlite3_bind_int64(stmt, column++, rule_get_version(rule)); // version
+    require_noerr(rc, err);
+    rc = sqlite3_bind_double(stmt, column++, rule_get_created(rule)); // created
+    require_noerr(rc, err);
+    rc = sqlite3_bind_double(stmt, column++, rule_get_modified(rule)); // modified
+    require_noerr(rc, err);
+    rc = sqlite3_bind_null(stmt, column++); // hash
+    require_noerr(rc, err);
+    rc = sqlite3_bind_text(stmt, column++, rule_get_identifier(rule), -1, NULL);
+    require_noerr(rc, err);
+
+    CFDataRef data = rule_get_requirment_data(rule);
+    if (data) {
+        rc = sqlite3_bind_blob(stmt, column++, CFDataGetBytePtr(data), (int32_t)CFDataGetLength(data), NULL);
+    } else {
+        rc = sqlite3_bind_null(stmt, column++);
+    }
+    require_noerr(rc, err);
+
+    rc = sqlite3_bind_text(stmt, column++, rule_get_comment(rule), -1, NULL);
+    require_noerr(rc, err);
+
+    return true;
+    
+err:
+    LOGD("rule: sql bind, error %i", rc);
+    return false;
+}
+
+static void
+_get_sql_mechanisms(rule_t rule, authdb_connection_t dbconn)
+{
+    CFArrayRemoveAllValues(rule->mechanisms);
+    
+    authdb_step(dbconn, "SELECT mechanisms.* " \
+                "FROM mechanisms " \
+                "JOIN mechanisms_map ON mechanisms.id = mechanisms_map.m_id " \
+                "WHERE mechanisms_map.r_id = ? ORDER BY mechanisms_map.ord ASC",
+    ^(sqlite3_stmt *stmt) {
+        sqlite3_bind_int64(stmt, 1, rule_get_id(rule));
+    }, ^bool(auth_items_t data) {
+        mechanism_t mechanism = mechanism_create_with_sql(data);
+        CFArrayAppendValue(rule->mechanisms, mechanism);
+        CFReleaseSafe(mechanism);
+        return true;
+    });
+}
+
+static void
+_get_sql_delegates(rule_t rule, authdb_connection_t dbconn)
+{
+    CFArrayRemoveAllValues(rule->delegations);
+    
+    authdb_step(dbconn, "SELECT rules.* " \
+                "FROM rules " \
+                "JOIN delegates_map ON rules.id = delegates_map.d_id " \
+                "WHERE delegates_map.r_id = ? ORDER BY delegates_map.ord ASC",
+                ^(sqlite3_stmt *stmt) {
+                    sqlite3_bind_int64(stmt, 1, rule_get_id(rule));
+                }, ^bool(auth_items_t data) {
+                    rule_t delegate = _rule_create_with_sql(data);
+                    if (delegate) {
+                        _get_sql_mechanisms(delegate, dbconn);
+                        
+                        if (rule_get_class(rule) == RC_RULE) {
+                            _get_sql_delegates(delegate, dbconn);
+                        }
+                        
+                        CFArrayAppendValue(rule->delegations, delegate);
+                        CFReleaseSafe(delegate);
+                    }
+                    return true;
+                });
+}
+
+bool
+rule_sql_fetch(rule_t rule, authdb_connection_t dbconn)
+{
+    __block bool result = false;
+    
+    authdb_step(dbconn, "SELECT * FROM rules WHERE name = ? LIMIT 1",
+    ^(sqlite3_stmt *stmt) {
+        sqlite3_bind_text(stmt, 1, rule_get_name(rule), -1, NULL);
+    }, ^bool(auth_items_t data) {
+        result = true;
+        auth_items_copy(rule->data, data);
+        return true;
+    });
+
+    if (rule_get_id(rule) != 0) {
+        _get_sql_mechanisms(rule,dbconn);
+        
+        if (rule_get_class(rule) == RC_RULE) {
+            _get_sql_delegates(rule, dbconn);
+        }
+    }
+
+    return result;
+}
+
+static bool
+_sql_update(rule_t rule, authdb_connection_t dbconn)
+{
+    bool result = false;
+    
+    result = authdb_step(dbconn, "UPDATE rules " \
+                         "SET name=?,type=?,class=?,'group'=?,kofn=?,timeout=?,flags=?,tries=?,version=?,created=?,modified=?,hash=?,identifier=?,requirement=?,comment=? " \
+                         "WHERE id = ?",
+                         ^(sqlite3_stmt *stmt) {
+                             _sql_bind(rule, stmt);
+                             sqlite3_bind_int64(stmt, sqlite3_bind_parameter_count(stmt), rule_get_id(rule));
+                         }, NULL);
+    return result;
+}
+
+static bool
+_sql_insert(rule_t rule, authdb_connection_t dbconn)
+{
+    bool result = false;
+
+    result = authdb_step(dbconn, "INSERT INTO rules VALUES (NULL,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
+                         ^(sqlite3_stmt *stmt) {
+                             _sql_bind(rule, stmt);
+                         }, NULL);
+    return result;
+}
+
+static bool
+_sql_commit_mechanisms_map(rule_t rule, authdb_connection_t dbconn)
+{
+    bool result = false;
+    
+    result = authdb_step(dbconn, "DELETE FROM mechanisms_map WHERE r_id = ?", ^(sqlite3_stmt *stmt) {
+        sqlite3_bind_int64(stmt, 1, rule_get_id(rule));
+    }, NULL);
+    require(result == true, done);
+    
+    CFIndex count = CFArrayGetCount(rule->mechanisms);
+    for(CFIndex i = 0; i < count; i++) {
+        mechanism_t mech = (mechanism_t)CFArrayGetValueAtIndex(rule->mechanisms, i);
+        result = authdb_step(dbconn, "INSERT INTO mechanisms_map VALUES (?,?,?)", ^(sqlite3_stmt *stmt) {
+            sqlite3_bind_int64(stmt, 1, rule_get_id(rule));
+            sqlite3_bind_int64(stmt, 2, mechanism_get_id(mech));
+            sqlite3_bind_int64(stmt, 3, i);
+        }, NULL);
+        require(result == true, done);
+    }
+    
+done:
+    return result;
+}
+
+static bool
+_sql_commit_delegates_map(rule_t rule, authdb_connection_t dbconn)
+{
+    bool result = false;
+    
+    result = authdb_step(dbconn, "DELETE FROM delegates_map WHERE r_id = ?", ^(sqlite3_stmt *stmt) {
+        sqlite3_bind_int64(stmt, 1, rule_get_id(rule));
+    }, NULL);
+    require(result == true, done);
+    
+    CFIndex count = CFArrayGetCount(rule->delegations);
+    for(CFIndex i = 0; i < count; i++) {
+        rule_t delegate = (rule_t)CFArrayGetValueAtIndex(rule->delegations, i);
+        result = authdb_step(dbconn, "INSERT INTO delegates_map VALUES (?,?,?)", ^(sqlite3_stmt *stmt) {
+            sqlite3_bind_int64(stmt, 1, rule_get_id(rule));
+            sqlite3_bind_int64(stmt, 2, rule_get_id(delegate));
+            sqlite3_bind_int64(stmt, 3, i);
+        }, NULL);
+        require(result == true, done);
+    }
+    
+done:
+    return result;
+}
+
+static void
+_sql_commit_localization(rule_t rule, authdb_connection_t dbconn)
+{
+
+    authdb_step(dbconn, "DELETE FROM prompts WHERE r_id = ?", ^(sqlite3_stmt *stmt) {
+        sqlite3_bind_int64(stmt, 1, rule_get_id(rule));
+    }, NULL);
+    
+    authdb_step(dbconn, "DELETE FROM buttons WHERE r_id = ?", ^(sqlite3_stmt *stmt) {
+        sqlite3_bind_int64(stmt, 1, rule_get_id(rule));
+    }, NULL);
+    
+    if (rule->loc_prompts) {
+        _cf_dictionary_iterate(rule->loc_prompts, ^bool(CFTypeRef key, CFTypeRef value) {
+            char * lang = _copy_cf_string(key, NULL);
+            char * str = _copy_cf_string(value, NULL);
+            
+            authdb_step(dbconn, "INSERT INTO prompts VALUES (?,?,?)", ^(sqlite3_stmt *stmt) {
+                sqlite3_bind_int64(stmt, 1, rule_get_id(rule));
+                sqlite3_bind_text(stmt, 2, lang, -1, NULL);
+                sqlite3_bind_text(stmt, 3, str, -1, NULL);
+            }, NULL);
+            
+            free_safe(lang);
+            free_safe(str);
+            
+            return true;
+        });
+    }
+
+    if (rule->loc_buttons) {
+        _cf_dictionary_iterate(rule->loc_buttons, ^bool(CFTypeRef key, CFTypeRef value) {
+            char * lang = _copy_cf_string(key, NULL);
+            char * str = _copy_cf_string(value, NULL);
+            
+            authdb_step(dbconn, "INSERT INTO buttons VALUES (?,?,?)", ^(sqlite3_stmt *stmt) {
+                sqlite3_bind_int64(stmt, 1, rule_get_id(rule));
+                sqlite3_bind_text(stmt, 2, lang, -1, NULL);
+                sqlite3_bind_text(stmt, 3, str, -1, NULL);
+            }, NULL);
+            
+            free_safe(lang);
+            free_safe(str);
+            return true;
+        });
+    }
+
+}
+
+bool
+rule_sql_commit(rule_t rule, authdb_connection_t dbconn, CFAbsoluteTime modified, process_t proc)
+{
+    bool result = false;
+    // type and class required else rule is name only?
+    RuleClass rule_class = rule_get_class(rule);
+    require(rule_get_type(rule) != 0, done);
+    require(rule_class != 0, done);
+    
+    CFIndex mechCount = 0;
+    if (rule_class == RC_USER || rule_class == RC_MECHANISM) {
+        // Validate mechanisms
+        mechCount = CFArrayGetCount(rule->mechanisms);
+        for (CFIndex i = 0; i < mechCount; i++) {
+            mechanism_t mech = (mechanism_t)CFArrayGetValueAtIndex(rule->mechanisms, i);
+            if (mechanism_get_id(mech) == 0) {
+                if (!mechanism_sql_fetch(mech, dbconn)) {
+                    mechanism_sql_commit(mech, dbconn);
+                    mechanism_sql_fetch(mech, dbconn);
+                }
+            }
+            if (!mechanism_exists(mech)) {
+                LOGE("Warning mechanism not found on disk %s during import of %s", mechanism_get_string(mech), rule_get_name(rule));
+            }
+            require_action(mechanism_get_id(mech) != 0, done, LOGE("rule: commit, invalid mechanism %s:%s for %s", mechanism_get_plugin(mech), mechanism_get_param(mech), rule_get_name(rule)));
+        }
+    }
+    
+    CFIndex delegateCount = 0;
+    if (rule_class == RC_RULE) {
+        // Validate delegates
+        delegateCount = CFArrayGetCount(rule->delegations);
+        for (CFIndex i = 0; i < delegateCount; i++) {
+            rule_t delegate = (rule_t)CFArrayGetValueAtIndex(rule->delegations, i);
+            if (rule_get_id(delegate) == 0) {
+                rule_sql_fetch(delegate, dbconn);
+            }
+            require_action(rule_get_id(delegate) != 0, done, LOGE("rule: commit, missing delegate %s for %s", rule_get_name(delegate), rule_get_name(rule)));
+        }
+    }
+    
+    auth_items_set_double(rule->data, RULE_MODIFIED, modified);
+    
+    result = authdb_transaction(dbconn, AuthDBTransactionNormal, ^bool{
+        bool update = false;
+        
+        if (rule_get_id(rule)) {
+            update = _sql_update(rule, dbconn);
+        } else {
+            if (proc) {
+                const char * ident = process_get_identifier(proc);
+                if (ident) {
+                    auth_items_set_string(rule->data, RULE_IDENTIFIER, ident);
+                }
+                CFDataRef req = process_get_requirement_data(proc);
+                if (req) {
+                    auth_items_set_data(rule->data, RULE_REQUIREMENT, CFDataGetBytePtr(req), (size_t)CFDataGetLength(req));
+                }
+            }
+            auth_items_set_double(rule->data, RULE_CREATED, modified);
+            update = _sql_insert(rule, dbconn);
+            _sql_get_id(rule, dbconn);
+        }
+        
+        _sql_commit_localization(rule, dbconn);
+        
+        if (update) {
+            update = _sql_commit_mechanisms_map(rule, dbconn);
+        }
+        
+        if (update) {
+            update = _sql_commit_delegates_map(rule,dbconn);
+        }
+        
+        return update;
+    });
+
+    
+done:
+    if (!result) {
+        LOGV("rule: commit, failed for %s (%llu)", rule_get_name(rule), rule_get_id(rule));
+    }
+    return result;
+}
+
+bool
+rule_sql_remove(rule_t rule, authdb_connection_t dbconn)
+{
+    bool result = false;
+    int64_t id = rule_get_id(rule);
+    
+    if (id == 0) {
+        rule_sql_fetch(rule, dbconn);
+        id = rule_get_id(rule);
+        require(id != 0, done);
+    }
+
+    result = authdb_step(dbconn, "DELETE FROM rules WHERE id = ?",
+                         ^(sqlite3_stmt *stmt) {
+                             sqlite3_bind_int64(stmt, 1, id);
+                         }, NULL);
+done:
+    return result;
+}
+
+CFMutableDictionaryRef
+rule_copy_to_cfobject(rule_t rule, authdb_connection_t dbconn) {
+    CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    
+    CFTypeRef tmp = NULL;
+    CFMutableArrayRef array = NULL;
+    CFIndex count = 0;
+    CFIndex i = 0;
+    int64_t n;
+    double d;
+    
+    const char * comment = rule_get_comment(rule);
+    if (comment) {
+        tmp = CFStringCreateWithCString(kCFAllocatorDefault, comment, kCFStringEncodingUTF8);
+        CFDictionarySetValue(dict, CFSTR(kAuthorizationComment), tmp);
+        CFReleaseSafe(tmp);
+    }
+    
+    n = rule_get_version(rule);
+    tmp = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &n);
+    CFDictionarySetValue(dict, CFSTR(RULE_VERSION), tmp);
+    CFReleaseSafe(tmp);
+    
+    d = rule_get_created(rule);
+    tmp = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloat64Type, &d);
+    CFDictionarySetValue(dict, CFSTR(RULE_CREATED), tmp);
+    CFReleaseSafe(tmp);
+    
+    d = rule_get_modified(rule);
+    tmp = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloat64Type, &d);
+    CFDictionarySetValue(dict, CFSTR(RULE_MODIFIED), tmp);
+    CFReleaseSafe(tmp);
+    
+    const char * identifier = rule_get_identifier(rule);
+    if (identifier) {
+        tmp = CFStringCreateWithCString(kCFAllocatorDefault, identifier, kCFStringEncodingUTF8);
+        CFDictionarySetValue(dict, CFSTR(RULE_IDENTIFIER), tmp);
+        CFReleaseSafe(tmp);
+    }
+    
+    SecRequirementRef req = rule_get_requirment(rule);
+    if (req) {
+        CFStringRef reqStr = NULL;
+        SecRequirementCopyString(req, kSecCSDefaultFlags, &reqStr);
+        if (reqStr) {
+            CFDictionarySetValue(dict, CFSTR(RULE_REQUIREMENT), reqStr);
+            CFReleaseSafe(reqStr);
+        }
+    }
+    
+    if (rule_check_flags(rule, RuleFlagEntitled)) {
+        CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleParameterEntitled), kCFBooleanTrue);
+    }
+    
+    if (rule_check_flags(rule, RuleFlagRequireAppleSigned)) {
+        CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleParameterRequireAppleSigned), kCFBooleanTrue);
+    }
+    
+    if (rule_get_type(rule) == RT_RIGHT) {
+        CFMutableDictionaryRef prompts = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+        authdb_step(dbconn, "SELECT * FROM prompts WHERE r_id = ?", ^(sqlite3_stmt *stmt) {
+            sqlite3_bind_int64(stmt, 1, rule_get_id(rule));
+        }, ^bool(auth_items_t data) {
+            CFStringRef key = CFStringCreateWithCString(kCFAllocatorDefault, auth_items_get_string(data, "lang"), kCFStringEncodingUTF8);
+            CFStringRef value = CFStringCreateWithCString(kCFAllocatorDefault, auth_items_get_string(data, "value"), kCFStringEncodingUTF8);
+            CFDictionaryAddValue(prompts, key, value);
+            CFReleaseSafe(key);
+            CFReleaseSafe(value);
+            return true;
+        });
+        
+        if (CFDictionaryGetCount(prompts)) {
+            CFDictionaryAddValue(dict, CFSTR(kAuthorizationRuleParameterDefaultPrompt), prompts);
+        }
+        CFReleaseSafe(prompts);
+        
+        CFMutableDictionaryRef buttons = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+        authdb_step(dbconn, "SELECT * FROM buttons WHERE r_id = ?", ^(sqlite3_stmt *stmt) {
+            sqlite3_bind_int64(stmt, 1, rule_get_id(rule));
+        }, ^bool(auth_items_t data) {
+            CFStringRef key = CFStringCreateWithCString(kCFAllocatorDefault, auth_items_get_string(data, "lang"), kCFStringEncodingUTF8);
+            CFStringRef value = CFStringCreateWithCString(kCFAllocatorDefault, auth_items_get_string(data, "value"), kCFStringEncodingUTF8);
+            CFDictionaryAddValue(buttons, key, value);
+            CFReleaseSafe(key);
+            CFReleaseSafe(value);
+            return true;
+        });
+        
+        if (CFDictionaryGetCount(buttons)) {
+            CFDictionaryAddValue(dict, CFSTR(kAuthorizationRuleParameterDefaultButton), buttons);
+        }
+        CFReleaseSafe(buttons);
+    }
+
+    switch (rule_get_class(rule)) {
+        case RC_USER:
+            CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleClass), CFSTR(kAuthorizationRuleClassUser));
+            
+            const char * group = rule_get_group(rule);
+            if (group) {
+                tmp = CFStringCreateWithCString(kCFAllocatorDefault, group, kCFStringEncodingUTF8);
+                CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleParameterGroup), tmp);
+                CFReleaseSafe(tmp);
+            }
+            
+            n = rule_get_timeout(rule);
+            tmp = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &n);
+            CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleParameterCredentialTimeout), tmp);
+            CFReleaseSafe(tmp);
+            
+            n = rule_get_tries(rule);
+            tmp = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &n);
+            CFDictionarySetValue(dict, CFSTR("tries"), tmp);
+            CFReleaseSafe(tmp);
+            
+            CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleParameterCredentialShared), rule_get_shared(rule) ? kCFBooleanTrue : kCFBooleanFalse);
+            CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleParameterAllowRoot), rule_get_allow_root(rule) ? kCFBooleanTrue : kCFBooleanFalse);
+            CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleParameterCredentialSessionOwner), rule_get_session_owner(rule) ? kCFBooleanTrue : kCFBooleanFalse);
+            CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleParameterAuthenticateUser), rule_get_authenticate_user(rule) ? kCFBooleanTrue : kCFBooleanFalse);
+            if (rule_check_flags(rule, RuleFlagEntitledAndGroup)) {
+                CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleParameterEntitledAndGroup), kCFBooleanTrue);
+            }
+            if (rule_check_flags(rule, RuleFlagVPNEntitledAndGroup)) {
+                CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleParameterVPNEntitledAndGroup), kCFBooleanTrue);
+            }
+            if (rule_get_extract_password(rule)) {
+                CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleParameterExtractPassword), kCFBooleanTrue);
+            }
+            
+            count = CFArrayGetCount(rule->mechanisms);
+            if (count) {
+                array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+                for (i = 0; i < count; i++) {
+                    mechanism_t mech = (mechanism_t)CFArrayGetValueAtIndex(rule->mechanisms, i);
+                    tmp = CFStringCreateWithCString(kCFAllocatorDefault, mechanism_get_string(mech), kCFStringEncodingUTF8);
+                    CFArrayAppendValue(array, tmp);
+                    CFReleaseSafe(tmp);
+                }
+                CFDictionaryAddValue(dict, CFSTR(kAuthorizationRuleParameterMechanisms), array);
+                CFRelease(array);
+            }
+            break;
+        case RC_RULE:
+            CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleClass), CFSTR(kAuthorizationRightRule));
+            int64_t kofn = rule_get_kofn(rule);
+            if (kofn) {
+                tmp = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &kofn);
+                CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleParameterKofN), tmp);
+                CFReleaseSafe(tmp);
+            }
+            
+            count = CFArrayGetCount(rule->delegations);
+            if (count) {
+                array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+                for (i = 0; i < count; i++) {
+                    rule_t delegate = (rule_t)CFArrayGetValueAtIndex(rule->delegations, i);
+                    tmp = CFStringCreateWithCString(kCFAllocatorDefault, rule_get_name(delegate), kCFStringEncodingUTF8);
+                    CFArrayAppendValue(array, tmp);
+                    CFReleaseSafe(tmp);
+                }
+                CFDictionaryAddValue(dict, CFSTR(kAuthorizationRightRule), array);
+                CFRelease(array);
+            }
+            break;
+        case RC_MECHANISM:
+            CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleClass), CFSTR(kAuthorizationRuleClassMechanisms));
+
+            CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleParameterCredentialShared), rule_get_shared(rule) ? kCFBooleanTrue : kCFBooleanFalse);
+            if (rule_get_extract_password(rule)) {
+                CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleParameterExtractPassword), kCFBooleanTrue);
+            }
+            
+            n = rule_get_tries(rule);
+            tmp = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &n);
+            CFDictionarySetValue(dict, CFSTR("tries"), tmp);
+            CFReleaseSafe(tmp);
+
+            count = CFArrayGetCount(rule->mechanisms);
+            if (count) {
+                array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+                for (i = 0; i < count; i++) {
+                    mechanism_t mech = (mechanism_t)CFArrayGetValueAtIndex(rule->mechanisms, i);
+                    tmp = CFStringCreateWithCString(kCFAllocatorDefault, mechanism_get_string(mech), kCFStringEncodingUTF8);
+                    CFArrayAppendValue(array, tmp);
+                    CFReleaseSafe(tmp);
+                }
+                CFDictionaryAddValue(dict, CFSTR(kAuthorizationRuleParameterMechanisms), array);
+                CFRelease(array);
+            }
+            break;
+        case RC_DENY:
+            CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleClass), CFSTR(kAuthorizationRuleClassDeny));
+            break;
+        case RC_ALLOW:
+            CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleClass), CFSTR(kAuthorizationRuleClassAllow));
+            break;
+        default:
+            break;
+    }
+
+    return dict;
+}
+
+
+CFArrayRef
+rule_get_mechanisms(rule_t rule)
+{
+    return rule->mechanisms;
+}
+
+size_t
+rule_get_mechanisms_count(rule_t rule)
+{
+    return (size_t)CFArrayGetCount(rule->mechanisms);
+}
+
+bool
+rule_mechanisms_iterator(rule_t rule, mechanism_iterator_t iter)
+{
+    bool result = false;
+    
+    CFIndex count = CFArrayGetCount(rule->mechanisms);
+    for (CFIndex i = 0; i < count; i++) {
+        mechanism_t mech = (mechanism_t)CFArrayGetValueAtIndex(rule->mechanisms, i);
+        result = iter(mech);
+        if (!result) {
+            break;
+        }
+    }
+    
+    return result;
+}
+
+size_t
+rule_get_delegates_count(rule_t rule)
+{
+    return (size_t)CFArrayGetCount(rule->delegations);
+}
+
+bool
+rule_delegates_iterator(rule_t rule, delegate_iterator_t iter)
+{
+    bool result = false;
+    
+    CFIndex count = CFArrayGetCount(rule->delegations);
+    for (CFIndex i = 0; i < count; i++) {
+        rule_t tmp = (rule_t)CFArrayGetValueAtIndex(rule->delegations, i);
+        result = iter(tmp);
+        if (!result) {
+            break;
+        }
+    }
+    
+    return result;
+}
+
+int64_t
+rule_get_id(rule_t rule)
+{
+    return auth_items_get_int64(rule->data, RULE_ID);
+}
+
+const char *
+rule_get_name(rule_t rule)
+{
+    return auth_items_get_string(rule->data, RULE_NAME);
+}
+
+RuleType
+rule_get_type(rule_t rule)
+{
+    return (RuleType)auth_items_get_int64(rule->data, RULE_TYPE);
+}
+
+RuleClass
+rule_get_class(rule_t rule)
+{
+    return (RuleClass)auth_items_get_int64(rule->data, RULE_CLASS);
+}
+
+const char *
+rule_get_group(rule_t rule)
+{
+    return auth_items_get_string(rule->data, RULE_GROUP);
+}
+
+int64_t
+rule_get_kofn(rule_t rule)
+{
+    return auth_items_get_int64(rule->data, RULE_KOFN);
+}
+
+int64_t
+rule_get_timeout(rule_t rule)
+{
+    return auth_items_get_int64(rule->data, RULE_TIMEOUT);
+}
+
+bool
+rule_check_flags(rule_t rule, RuleFlags flags)
+{
+    return (auth_items_get_int64(rule->data, RULE_FLAGS) & flags) != 0;
+}
+
+bool
+rule_get_shared(rule_t rule)
+{
+    return rule_check_flags(rule, RuleFlagShared);
+}
+
+bool
+rule_get_allow_root(rule_t rule)
+{
+    return rule_check_flags(rule, RuleFlagAllowRoot);
+}
+
+bool
+rule_get_session_owner(rule_t rule)
+{
+    return rule_check_flags(rule, RuleFlagSessionOwner);
+}
+
+bool
+rule_get_authenticate_user(rule_t rule)
+{
+    return rule_check_flags(rule, RuleFlagAuthenticateUser);
+}
+
+bool
+rule_get_extract_password(rule_t rule)
+{
+    return rule_check_flags(rule, RuleFlagExtractPassword);
+}
+
+int64_t
+rule_get_tries(rule_t rule)
+{
+    return auth_items_get_int64(rule->data, RULE_TRIES);
+}
+
+const char *
+rule_get_comment(rule_t rule)
+{
+    return auth_items_get_string(rule->data, RULE_COMMENT);
+}
+
+int64_t
+rule_get_version(rule_t rule)
+{
+    return auth_items_get_int64(rule->data, RULE_VERSION);
+}
+
+double rule_get_created(rule_t rule)
+{
+    return auth_items_get_double(rule->data, RULE_CREATED);
+}
+
+double rule_get_modified(rule_t rule)
+{
+    return auth_items_get_double(rule->data, RULE_MODIFIED);
+}
+
+const char * rule_get_identifier(rule_t rule)
+{
+    return auth_items_get_string(rule->data, RULE_IDENTIFIER);
+}
+
+CFDataRef rule_get_requirment_data(rule_t rule)
+{
+    if (!rule->requirement_data && auth_items_exist(rule->data, RULE_REQUIREMENT)) {
+        size_t len;
+        const void * data = auth_items_get_data(rule->data, RULE_REQUIREMENT, &len);
+        rule->requirement_data = CFDataCreate(kCFAllocatorDefault, data, (CFIndex)len);
+    }
+    
+    return rule->requirement_data;
+}
+
+SecRequirementRef rule_get_requirment(rule_t rule)
+{
+    if (!rule->requirement) {
+        CFDataRef data = rule_get_requirment_data(rule);
+        if (data) {
+            SecRequirementCreateWithData(data, kSecCSDefaultFlags, &rule->requirement);
+        }
+    }
+    
+    return rule->requirement;
+}
diff --git a/authd/rule.h b/authd/rule.h
new file mode 100644 (file)
index 0000000..1aefb22
--- /dev/null
@@ -0,0 +1,146 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#ifndef _SECURITY_AUTH_RULE_H_
+#define _SECURITY_AUTH_RULE_H_
+
+#include "authdb.h"
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecRequirement.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+typedef bool (^mechanism_iterator_t)(mechanism_t mechanism);
+typedef bool (^delegate_iterator_t)(rule_t delegate);
+    
+typedef enum {
+    RT_RIGHT = 1,
+    RT_RULE
+} RuleType;
+
+typedef enum {
+    RC_USER = 1,
+    RC_RULE,
+    RC_MECHANISM,
+    RC_ALLOW,
+    RC_DENY
+} RuleClass;
+
+enum {
+    RuleFlagShared              = 1 << 0,
+    RuleFlagAllowRoot           = 1 << 1,
+    RuleFlagSessionOwner        = 1 << 2,
+    RuleFlagAuthenticateUser    = 1 << 3,
+    RuleFlagExtractPassword     = 1 << 4,
+    RuleFlagEntitled            = 1 << 5,
+    RuleFlagEntitledAndGroup    = 1 << 6,
+    RuleFlagRequireAppleSigned  = 1 << 7,
+    RuleFlagVPNEntitledAndGroup = 1 << 8
+};
+typedef uint32_t RuleFlags;
+
+AUTH_WARN_RESULT AUTH_MALLOC AUTH_NONNULL_ALL AUTH_RETURNS_RETAINED
+rule_t rule_create_default(void);
+
+AUTH_WARN_RESULT AUTH_MALLOC AUTH_NONNULL1 AUTH_RETURNS_RETAINED
+rule_t rule_create_with_string(const char *,authdb_connection_t);
+        
+AUTH_WARN_RESULT AUTH_MALLOC AUTH_NONNULL_ALL AUTH_RETURNS_RETAINED
+rule_t rule_create_with_plist(RuleType,CFStringRef,CFDictionaryRef,authdb_connection_t);
+
+AUTH_NONNULL_ALL
+size_t rule_get_mechanisms_count(rule_t);
+
+AUTH_NONNULL_ALL
+CFArrayRef rule_get_mechanisms(rule_t);
+
+AUTH_NONNULL_ALL
+bool rule_mechanisms_iterator(rule_t,mechanism_iterator_t iter);
+
+AUTH_NONNULL_ALL
+size_t rule_get_delegates_count(rule_t);
+    
+AUTH_NONNULL_ALL
+bool rule_delegates_iterator(rule_t,delegate_iterator_t iter);
+
+AUTH_NONNULL_ALL
+bool rule_sql_fetch(rule_t,authdb_connection_t);
+    
+AUTH_NONNULL1 AUTH_NONNULL2
+bool rule_sql_commit(rule_t,authdb_connection_t,CFAbsoluteTime,process_t);
+
+AUTH_NONNULL_ALL
+bool rule_sql_remove(rule_t,authdb_connection_t);
+
+AUTH_NONNULL_ALL
+CFMutableDictionaryRef rule_copy_to_cfobject(rule_t,authdb_connection_t);
+    
+AUTH_NONNULL_ALL
+int64_t rule_get_id(rule_t);
+
+AUTH_NONNULL_ALL
+const char * rule_get_name(rule_t);
+    
+AUTH_NONNULL_ALL
+RuleType rule_get_type(rule_t);
+    
+AUTH_NONNULL_ALL
+RuleClass rule_get_class(rule_t);
+    
+AUTH_NONNULL_ALL
+const char * rule_get_group(rule_t);
+    
+AUTH_NONNULL_ALL
+int64_t rule_get_kofn(rule_t);
+    
+AUTH_NONNULL_ALL
+int64_t rule_get_timeout(rule_t);
+    
+AUTH_NONNULL_ALL
+bool rule_check_flags(rule_t,RuleFlags);
+    
+AUTH_NONNULL_ALL
+bool rule_get_shared(rule_t);
+    
+AUTH_NONNULL_ALL
+bool rule_get_allow_root(rule_t);
+    
+AUTH_NONNULL_ALL
+bool rule_get_session_owner(rule_t);
+    
+AUTH_NONNULL_ALL
+bool rule_get_authenticate_user(rule_t);
+    
+AUTH_NONNULL_ALL
+bool rule_get_extract_password(rule_t);
+    
+AUTH_NONNULL_ALL
+int64_t rule_get_tries(rule_t);
+    
+AUTH_NONNULL_ALL
+const char * rule_get_comment(rule_t);
+
+AUTH_NONNULL_ALL
+int64_t rule_get_version(rule_t);
+
+AUTH_NONNULL_ALL
+double rule_get_created(rule_t);
+    
+AUTH_NONNULL_ALL
+double rule_get_modified(rule_t);
+
+AUTH_NONNULL_ALL
+const char * rule_get_identifier(rule_t);
+
+AUTH_NONNULL_ALL
+CFDataRef rule_get_requirment_data(rule_t);
+
+AUTH_NONNULL_ALL
+SecRequirementRef rule_get_requirment(rule_t);
+    
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_SECURITY_AUTH_RULE_H_ */
diff --git a/authd/security.auth-Prefix.pch b/authd/security.auth-Prefix.pch
new file mode 100644 (file)
index 0000000..3494610
--- /dev/null
@@ -0,0 +1,14 @@
+//
+// Prefix header for all source files of the 'security.auth' target in the 'security.auth' project
+//
+
+#include "authtypes.h"
+#include "object.h"
+
+#include <CoreFoundation/CFBase.h>
+#include <CoreFoundation/CFRuntime.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <AssertMacros.h>
+#include <mach/message.h>
+#include <sys/types.h>
diff --git a/authd/server.c b/authd/server.c
new file mode 100644 (file)
index 0000000..8b8d8e0
--- /dev/null
@@ -0,0 +1,1163 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#include "server.h"
+#include "session.h"
+#include "process.h"
+#include "authtoken.h"
+#include "authdb.h"
+#include "rule.h"
+#include "authutilities.h"
+#include "crc.h"
+#include "mechanism.h"
+#include "agent.h"
+#include "authitems.h"
+#include "debugging.h"
+#include "engine.h"
+#include "connection.h"
+
+#include <bsm/libbsm.h>
+#include <Security/Authorization.h>
+#include <Security/AuthorizationPriv.h>
+#include <Security/AuthorizationTagsPriv.h>
+#include <xpc/private.h>
+#include <dispatch/dispatch.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreFoundation/CFXPCBridge.h>
+#include <IOKit/IOMessage.h>
+#include <IOKit/pwr_mgt/IOPMLib.h>
+#include <IOKit/pwr_mgt/IOPMLibPrivate.h>
+
+#define MAX_PROCESS_RIGHTS   30
+
+static CFMutableDictionaryRef gProcessMap = NULL;
+static CFMutableDictionaryRef gSessionMap = NULL;
+static CFMutableDictionaryRef gAuthTokenMap = NULL;
+static authdb_t gDatabase = NULL;
+
+static dispatch_queue_t power_queue;
+static bool gInDarkWake = false;
+static IOPMConnection gIOPMconn = NULL;
+static bool gXPCTransaction = false;
+
+static dispatch_queue_t
+get_server_dispatch_queue()
+{
+    static dispatch_once_t onceToken;
+    static dispatch_queue_t server_queue = NULL;
+    
+    dispatch_once(&onceToken, ^{
+        server_queue = dispatch_queue_create("com.apple.security.auth.server", DISPATCH_QUEUE_SERIAL);
+        check(server_queue != NULL);
+    });
+    
+    return server_queue;
+}
+
+static Boolean _processEqualCallBack(const void *value1, const void *value2)
+{
+    audit_info_s * info1 = (audit_info_s*)value1;
+    audit_info_s * info2 = (audit_info_s*)value2;
+    if (info1->pid == info2->pid) {
+        if (info1->tid == info2->tid) {
+            return true;
+        }
+    }
+    return false;
+}
+
+static CFHashCode _processHashCallBack(const void *value)
+{
+    audit_info_s * info = (audit_info_s*)value;
+    uint64_t crc = crc64_init();
+    crc = crc64_update(crc, &info->pid, sizeof(info->pid));
+    crc = crc64_update(crc, &info->tid, sizeof(info->tid));
+    crc = crc64_final(crc);
+    return crc;
+}
+
+static const CFDictionaryKeyCallBacks kProcessMapKeyCallBacks = {
+    .version = 0,
+    .retain = NULL,
+    .release = NULL,
+    .copyDescription = NULL,
+    .equal = &_processEqualCallBack,
+    .hash = &_processHashCallBack
+};
+
+static Boolean _sessionEqualCallBack(const void *value1, const void *value2)
+{
+    return (*(session_id_t*)value1) == (*(session_id_t*)value2);
+}
+
+static CFHashCode _sessionHashCallBack(const void *value)
+{
+    return (CFHashCode)(*(session_id_t*)(value));
+}
+
+static const CFDictionaryKeyCallBacks kSessionMapKeyCallBacks = {
+    .version = 0,
+    .retain = NULL,
+    .release = NULL,
+    .copyDescription = NULL,
+    .equal = &_sessionEqualCallBack,
+    .hash = &_sessionHashCallBack
+};
+
+void server_cleanup()
+{
+    CFRelease(gProcessMap);
+    CFRelease(gSessionMap);
+    CFRelease(gAuthTokenMap);
+    
+    IOPMConnectionSetDispatchQueue(gIOPMconn, NULL);
+    IOPMConnectionRelease(gIOPMconn);
+    
+    dispatch_queue_t queue = get_server_dispatch_queue();
+    if (queue) {
+        dispatch_release(queue);
+    }
+    dispatch_release(power_queue);
+}
+
+static void _IOMPCallBack(void * param AUTH_UNUSED, IOPMConnection connection, IOPMConnectionMessageToken token, IOPMSystemPowerStateCapabilities capabilities)
+{
+    LOGV("server: IOMP powerstates %i", capabilities);
+    if (capabilities & kIOPMSystemPowerStateCapabilityDisk)
+        LOGV("server: disk");
+    if (capabilities & kIOPMSystemPowerStateCapabilityNetwork)
+        LOGV("server: net");
+    if (capabilities & kIOPMSystemPowerStateCapabilityAudio)
+        LOGV("server: audio");
+    if (capabilities & kIOPMSystemPowerStateCapabilityVideo)
+        LOGV("server: video");
+    
+    /* if cpu and no display -> in DarkWake */
+    LOGD("server: DarkWake check current=%i==%i", (capabilities & (kIOPMSystemPowerStateCapabilityCPU|kIOPMSystemPowerStateCapabilityVideo)), kIOPMSystemPowerStateCapabilityCPU);
+    if ((capabilities & (kIOPMSystemPowerStateCapabilityCPU|kIOPMSystemPowerStateCapabilityVideo)) == kIOPMSystemPowerStateCapabilityCPU) {
+        LOGV("server: enter DarkWake");
+        gInDarkWake = true;
+    } else if (gInDarkWake) {
+        LOGV("server: exit DarkWake");
+        gInDarkWake = false;
+    }
+    
+    (void)IOPMConnectionAcknowledgeEvent(connection, token);
+    
+    return;
+}
+
+static void
+_setupDarkWake(void *ctx)
+{
+    IOReturn ret;
+    
+    IOPMConnectionCreate(CFSTR("IOPowerWatcher"),
+                         kIOPMSystemPowerStateCapabilityDisk
+                         | kIOPMSystemPowerStateCapabilityNetwork
+                         | kIOPMSystemPowerStateCapabilityAudio
+                         | kIOPMSystemPowerStateCapabilityVideo,
+                         &gIOPMconn);
+
+    ret = IOPMConnectionSetNotification(gIOPMconn, NULL, _IOMPCallBack);
+    if (ret != kIOReturnSuccess)
+        return;
+    
+    IOPMConnectionSetDispatchQueue(gIOPMconn, power_queue);
+}
+
+bool server_in_dark_wake()
+{
+    return gInDarkWake;
+}
+
+authdb_t server_get_database()
+{
+    return gDatabase;
+}
+
+static void _setupAuditSessionMonitor()
+{
+    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+        au_sdev_handle_t *dev = au_sdev_open(AU_SDEVF_ALLSESSIONS);
+        int event;
+        auditinfo_addr_t aia;
+        
+        if (NULL == dev) {
+            LOGE("server: could not open %s %d", AUDIT_SDEV_PATH, errno);
+            return;
+        }
+        
+        for (;;) {
+            if (0 != au_sdev_read_aia(dev, &event, &aia)) {
+                LOGE("server: au_sdev_read_aia failed: %d", errno);
+                continue;
+            }
+            LOGD("server: au_sdev_handle_t event=%i, session=%i", event, aia.ai_asid);
+            if (event == AUE_SESSION_CLOSE) {
+                dispatch_async(get_server_dispatch_queue(), ^{
+                    LOGV("server: session %i destroyed", aia.ai_asid);
+                    CFDictionaryRemoveValue(gSessionMap, &aia.ai_asid);
+                });
+            }
+        }
+        
+    });
+}
+
+static void _setupSignalHandlers()
+{
+    signal(SIGTERM, SIG_IGN);
+    static dispatch_source_t sigtermHandler;
+    sigtermHandler = dispatch_source_create(DISPATCH_SOURCE_TYPE_SIGNAL, SIGTERM, 0, get_server_dispatch_queue());
+    if (sigtermHandler) {
+        dispatch_source_set_event_handler(sigtermHandler, ^{
+
+            // should we clean up any state?
+            exit(EXIT_SUCCESS);
+        });
+        dispatch_resume(sigtermHandler);
+    }
+}
+
+OSStatus server_init(void)
+{
+    OSStatus status = errAuthorizationSuccess;
+    
+    auditinfo_addr_t info;
+    memset(&info, 0, sizeof(info));
+    getaudit_addr(&info, sizeof(info));
+    LOGV("server: uid=%i, sid=%i", info.ai_auid, info.ai_asid);
+    
+    require_action(get_server_dispatch_queue() != NULL, done, status = errAuthorizationInternal);
+    
+    gProcessMap = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kProcessMapKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    require_action(gProcessMap != NULL, done, status = errAuthorizationInternal);
+    
+    gSessionMap = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kSessionMapKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    require_action(gSessionMap != NULL, done, status = errAuthorizationInternal);
+    
+    gAuthTokenMap = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kAuthTokenKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    require_action(gAuthTokenMap != NULL, done, status = errAuthorizationInternal);
+    
+    gDatabase = authdb_create();
+    require_action(gDatabase != NULL, done, status = errAuthorizationInternal);
+    
+    // check to see if we have an updates
+    authdb_connection_t dbconn = authdb_connection_acquire(gDatabase);
+    authdb_maintenance(dbconn);
+    authdb_connection_release(&dbconn);
+    
+    power_queue = dispatch_queue_create("com.apple.security.auth.power", DISPATCH_QUEUE_SERIAL);
+    check(power_queue != NULL);
+    dispatch_async_f(power_queue, NULL, _setupDarkWake);
+
+    _setupAuditSessionMonitor();
+    _setupSignalHandlers();
+    
+done:
+    return status;
+}
+
+static void _server_parse_audit_token(audit_token_t * token, audit_info_s * info)
+{
+    if (token && info) {
+        memset(info, 0, sizeof(*info));
+        au_tid_t tid;
+        memset(&tid, 0, sizeof(tid));
+        audit_token_to_au32(*token, &info->auid, &info->euid,
+                            &info->egid, &info->ruid, &info->rgid,
+                            &info->pid, &info->asid, &tid);
+        info->tid = tid.port;
+        info->opaqueToken = *token;
+    }
+}
+
+connection_t
+server_register_connection(xpc_connection_t connection)
+{
+    __block connection_t conn = NULL;
+    __block session_t session = NULL;
+    __block process_t proc = NULL;
+    __block CFIndex conn_count = 0;
+
+    require(connection != NULL, done);
+    
+    audit_token_t auditToken;
+    audit_info_s info;
+    xpc_connection_get_audit_token(connection, &auditToken);
+    _server_parse_audit_token(&auditToken, &info);
+    
+    
+    dispatch_sync(get_server_dispatch_queue(), ^{
+        session = (session_t)CFDictionaryGetValue(gSessionMap, &info.asid);
+        if (session) {
+            CFRetain(session);
+        } else {
+            session = session_create(info.asid);
+            CFDictionarySetValue(gSessionMap, session_get_key(session), session);
+        }
+        
+        proc = (process_t)CFDictionaryGetValue(gProcessMap, &info);
+        if (proc) {
+            CFRetain(proc);
+        }
+
+        if (proc) {
+            conn = connection_create(proc);
+            conn_count = process_add_connection(proc, conn);
+        } else {
+            proc = process_create(&info, session);
+            if (proc) {
+                conn = connection_create(proc);
+                conn_count = process_add_connection(proc, conn);
+                session_add_process(session, proc);
+                CFDictionarySetValue(gProcessMap, process_get_key(proc), proc);
+            }
+        }
+        
+        if (!gXPCTransaction) {
+            xpc_transaction_begin();
+            gXPCTransaction = true;
+        }
+    });
+    
+    LOGV("server[%i]: registered connection (total=%li)", info.pid, conn_count);
+
+done:
+    CFReleaseSafe(session);
+    CFReleaseSafe(proc);
+    return conn;
+}
+
+void
+server_unregister_connection(connection_t conn)
+{
+    if (conn != NULL) {
+        process_t proc = connection_get_process(conn);
+        
+        dispatch_sync(get_server_dispatch_queue(), ^{
+            CFIndex connectionCount = process_get_connection_count(proc);
+            LOGV("server[%i]: unregistered connection (total=%li)", process_get_pid(proc), connectionCount);
+
+            if (connectionCount == 1) {
+                CFDictionaryRemoveValue(gProcessMap, process_get_key(proc));
+            }
+            
+            if (CFDictionaryGetCount(gProcessMap) == 0) {
+                xpc_transaction_end();
+                gXPCTransaction = false;
+            }
+        });
+        // move the destruction of the connection/process off the server queue
+        CFRelease(conn);
+    }
+}
+
+void
+server_register_auth_token(auth_token_t auth)
+{
+    if (auth != NULL) {
+        dispatch_sync(get_server_dispatch_queue(), ^{
+            LOGV("server: registering auth %p", auth);
+            CFDictionarySetValue(gAuthTokenMap, auth_token_get_key(auth), auth);
+            auth_token_set_state(auth, auth_token_state_registered);
+        });
+    }
+}
+
+void
+server_unregister_auth_token(auth_token_t auth)
+{
+    if (auth != NULL) {
+        AuthorizationBlob blob = *(AuthorizationBlob*)auth_token_get_key(auth);
+        dispatch_async(get_server_dispatch_queue(), ^{
+            LOGV("server: unregistering auth %p", auth);
+            CFDictionaryRemoveValue(gAuthTokenMap, &blob);
+        });
+    }
+}
+
+auth_token_t
+server_find_copy_auth_token(AuthorizationBlob * blob)
+{
+    __block auth_token_t auth = NULL;
+    if (blob != NULL) {
+        dispatch_sync(get_server_dispatch_queue(), ^{
+            auth = (auth_token_t)CFDictionaryGetValue(gAuthTokenMap, blob);
+            if (auth) {
+                CFRetain(auth);
+            }
+        });
+    }
+    return auth;
+}
+
+session_t
+server_find_copy_session(session_id_t sid, bool create)
+{
+    __block session_t session = NULL;
+    
+    dispatch_sync(get_server_dispatch_queue(), ^{
+        session = (session_t)CFDictionaryGetValue(gSessionMap, &sid);
+        if (session) {
+            CFRetain(session);
+        } else if (create) {
+            session = session_create(sid);
+            if (session) {
+                CFDictionarySetValue(gSessionMap, session_get_key(session), session);
+            }
+        }
+    });
+    
+    return session;
+}
+
+#pragma mark -
+#pragma mark API
+
+static OSStatus
+_process_find_copy_auth_token_from_xpc(process_t proc, xpc_object_t message, auth_token_t * auth_out)
+{
+    OSStatus status = errAuthorizationSuccess;
+    require_action(auth_out != NULL, done, status = errAuthorizationInternal);
+    
+    size_t len;
+    AuthorizationBlob * blob = (AuthorizationBlob *)xpc_dictionary_get_data(message, AUTH_XPC_BLOB, &len);
+    require_action(blob != NULL, done, status = errAuthorizationInvalidRef);
+    require_action(len == sizeof(AuthorizationBlob), done, status = errAuthorizationInvalidRef);
+    
+    auth_token_t auth = process_find_copy_auth_token(proc, blob);
+    require_action(auth != NULL, done, status = errAuthorizationInvalidRef);
+
+#if DEBUG
+    LOGV("server[%i]: authtoken lookup %#x%x %p", process_get_pid(proc), blob->data[1],blob->data[0], auth);
+#else
+    LOGV("server[%i]: authtoken lookup %p", process_get_pid(proc), auth);
+#endif
+    
+    *auth_out = auth;
+    
+done:
+    return status;
+}
+
+static OSStatus _server_authorize(connection_t conn, auth_token_t auth, AuthorizationFlags flags, auth_rights_t rights, auth_items_t enviroment, engine_t * engine_out)
+{
+    __block OSStatus status = errAuthorizationDenied;
+    engine_t engine = NULL;
+    
+    require_action(conn, done, status = errAuthorizationInternal);
+
+    engine = engine_create(conn, auth);
+    require_action(engine, done, status = errAuthorizationInternal);
+    
+    if (flags & kAuthorizationFlagInteractionAllowed) {
+        dispatch_sync(connection_get_dispatch_queue(conn), ^{
+            connection_set_engine(conn, engine);
+            status = engine_authorize(engine, rights, enviroment, flags);
+            connection_set_engine(conn, NULL);
+        });
+    } else {
+        status = engine_authorize(engine, rights, enviroment, flags);
+    }
+    
+done:
+    if (engine) {
+        if (engine_out) {
+            *engine_out = engine;
+        } else {
+            CFRelease(engine);
+        }
+    }
+    return status;
+}
+
+// IN:  AUTH_XPC_RIGHTS, AUTH_XPC_ENVIROMENT, AUTH_XPC_FLAGS
+// OUT: AUTH_XPC_BLOB
+OSStatus
+authorization_create(connection_t conn, xpc_object_t message, xpc_object_t reply)
+{
+    OSStatus status = errAuthorizationDenied;
+    
+    process_t proc = connection_get_process(conn);
+    
+    // Passed in args
+    auth_rights_t rights = auth_rights_create_with_xpc(xpc_dictionary_get_value(message, AUTH_XPC_RIGHTS));
+    auth_items_t enviroment = auth_items_create_with_xpc(xpc_dictionary_get_value(message, AUTH_XPC_ENVIROMENT));
+    AuthorizationFlags flags = (AuthorizationFlags)xpc_dictionary_get_uint64(message, AUTH_XPC_FLAGS);
+    
+    // Create Authorization Token
+    auth_token_t auth = auth_token_create(proc, flags & kAuthorizationFlagLeastPrivileged);
+    require_action(auth != NULL, done, status = errAuthorizationInternal);
+    
+    if (!(flags & kAuthorizationFlagNoData)) {
+        process_add_auth_token(proc,auth);
+    }
+    
+    status = _server_authorize(conn, auth, flags, rights, enviroment, NULL);
+    require_noerr(status, done);
+    
+    //reply
+    xpc_dictionary_set_data(reply, AUTH_XPC_BLOB, auth_token_get_blob(auth), sizeof(AuthorizationBlob));
+    
+done:
+    CFReleaseSafe(rights);
+    CFReleaseSafe(enviroment);
+    CFReleaseSafe(auth);
+    return status;
+}
+
+// IN:  AUTH_XPC_DATA, AUTH_XPC_ENVIROMENT, AUTH_XPC_FLAGS
+// OUT: AUTH_XPC_BLOB
+OSStatus authorization_create_with_audit_token(connection_t conn, xpc_object_t message, xpc_object_t reply)
+{
+    OSStatus status = errAuthorizationDenied;
+    auth_token_t auth = NULL;
+    
+    process_t proc = connection_get_process(conn);
+    require(process_get_uid(proc) == 0, done);  //only root can use this call
+    
+    // Passed in args
+    size_t len = 0;
+    const char * data = xpc_dictionary_get_data(message, AUTH_XPC_DATA, &len);
+    require(data != NULL, done);
+    require(len == sizeof(audit_token_t), done);
+    
+//    auth_items_t enviroment = auth_items_create_with_xpc(xpc_dictionary_get_value(message, AUTH_XPC_ENVIROMENT));
+    AuthorizationFlags flags = (AuthorizationFlags)xpc_dictionary_get_uint64(message, AUTH_XPC_FLAGS);
+    
+    audit_info_s auditInfo;
+    _server_parse_audit_token((audit_token_t*)data, &auditInfo);
+    
+    // Create Authorization Token
+    auth = auth_token_create(proc, flags & kAuthorizationFlagLeastPrivileged);
+    require_action(auth != NULL, done, status = errAuthorizationInternal);
+    
+    process_add_auth_token(proc,auth);
+    
+    //reply
+    xpc_dictionary_set_data(reply, AUTH_XPC_BLOB, auth_token_get_blob(auth), sizeof(AuthorizationBlob));
+
+done:
+//    CFReleaseSafe(enviroment);
+    CFReleaseSafe(auth);
+    return status;
+}
+
+// IN:  AUTH_XPC_BLOB, AUTH_XPC_FLAGS
+// OUT: 
+OSStatus
+authorization_free(connection_t conn, xpc_object_t message, xpc_object_t reply AUTH_UNUSED)
+{
+    OSStatus status = errAuthorizationSuccess;
+    AuthorizationFlags flags = 0;
+    process_t proc = connection_get_process(conn);
+    
+    auth_token_t auth = NULL;
+    status = _process_find_copy_auth_token_from_xpc(proc, message, &auth);
+    require_noerr(status, done);
+    
+    flags = (AuthorizationFlags)xpc_dictionary_get_uint64(message, AUTH_XPC_FLAGS);
+    
+    if (flags & kAuthorizationFlagDestroyRights) {
+        auth_token_credentials_iterate(auth, ^bool(credential_t cred) {
+            credential_invalidate(cred);
+            LOGV("engine[%i]: invalidating %scredential %s (%i) from authorization (%p)", connection_get_pid(conn), credential_get_shared(cred) ? "shared " : "", credential_get_name(cred), credential_get_uid(cred), auth);
+            return true;
+        });
+        
+        session_credentials_purge(auth_token_get_session(auth));
+    }
+    
+    process_remove_auth_token(proc, auth, flags);
+    
+done:
+    CFReleaseSafe(auth);
+    LOGV("server[%i]: AuthorizationFree %i (flags:%x)", connection_get_pid(conn), status, flags);
+    return status;
+}
+
+// IN:  AUTH_XPC_BLOB, AUTH_XPC_RIGHTS, AUTH_XPC_ENVIROMENT, AUTH_XPC_FLAGS
+// OUT: AUTH_XPC_OUT_ITEMS
+OSStatus
+authorization_copy_rights(connection_t conn, xpc_object_t message, xpc_object_t reply)
+{
+    OSStatus status = errAuthorizationDenied;
+    engine_t engine = NULL;
+    
+    process_t proc = connection_get_process(conn);
+    
+    // Passed in args
+    auth_rights_t rights = auth_rights_create_with_xpc(xpc_dictionary_get_value(message, AUTH_XPC_RIGHTS));
+    auth_items_t enviroment = auth_items_create_with_xpc(xpc_dictionary_get_value(message, AUTH_XPC_ENVIROMENT));
+    AuthorizationFlags flags = (AuthorizationFlags)xpc_dictionary_get_uint64(message, AUTH_XPC_FLAGS);
+    
+    auth_token_t auth = NULL;
+    status = _process_find_copy_auth_token_from_xpc(proc, message, &auth);
+    require_noerr(status, done);
+    
+    status = _server_authorize(conn, auth, flags, rights, enviroment, &engine);
+    require_noerr(status, done);
+    
+    //reply
+    xpc_object_t outItems = auth_rights_export_xpc(engine_get_granted_rights(engine));
+    xpc_dictionary_set_value(reply, AUTH_XPC_OUT_ITEMS, outItems);
+    xpc_release_safe(outItems);
+
+done:
+    CFReleaseSafe(rights);
+    CFReleaseSafe(enviroment);
+    CFReleaseSafe(auth);
+    CFReleaseSafe(engine);
+    
+    return status;
+}
+
+// IN:  AUTH_XPC_BLOB, AUTH_XPC_TAG
+// OUT: AUTH_XPC_OUT_ITEMS
+OSStatus
+authorization_copy_info(connection_t conn, xpc_object_t message, xpc_object_t reply)
+{
+    
+    OSStatus status = errAuthorizationSuccess;
+    auth_items_t items = NULL;
+    const char * tag = NULL;
+    
+    process_t proc = connection_get_process(conn);
+    
+    auth_token_t auth = NULL;
+    status = _process_find_copy_auth_token_from_xpc(proc, message, &auth);
+    require_noerr(status, done);
+    
+    items = auth_items_create();
+    
+    tag = xpc_dictionary_get_string(message, AUTH_XPC_TAG);
+    LOGV("server[%i]: requested tag: %s", connection_get_pid(conn), tag ? tag : "(all)");
+    if (tag) {
+        size_t len;
+        const void * data = auth_items_get_data(auth_token_get_context(auth), tag, &len);
+        if (data) {
+            auth_items_set_data(items, tag, data, len);
+        }
+    } else {
+        auth_items_copy(items, auth_token_get_context(auth));
+    }
+
+#if DEBUG
+    LOGV("server[%i]: Dumping requested AuthRef items", connection_get_pid(conn));
+    _show_cf(items);
+#endif
+
+    //reply
+    xpc_object_t outItems = auth_items_export_xpc(items);
+    xpc_dictionary_set_value(reply, AUTH_XPC_OUT_ITEMS, outItems);
+    xpc_release_safe(outItems);
+    
+done:
+    CFReleaseSafe(items);
+    CFReleaseSafe(auth);
+    LOGV("server[%i]: AuthorizationCopyInfo %i", connection_get_pid(conn), status);
+    return status;
+}
+
+// IN:  AUTH_XPC_BLOB
+// OUT: AUTH_XPC_EXTERNAL
+OSStatus
+authorization_make_external_form(connection_t conn, xpc_object_t message, xpc_object_t reply)
+{
+    OSStatus status = errAuthorizationSuccess;
+
+    process_t proc = connection_get_process(conn);
+    
+    auth_token_t auth = NULL;
+    status = _process_find_copy_auth_token_from_xpc(proc, message, &auth);
+    require_noerr(status, done);
+    
+    AuthorizationExternalForm exForm;
+    AuthorizationExternalBlob * exBlob = (AuthorizationExternalBlob *)&exForm;
+    memset(&exForm, 0, sizeof(exForm));
+    
+    exBlob->blob = *auth_token_get_blob(auth);
+    exBlob->session = process_get_session_id(proc);
+    
+    xpc_dictionary_set_data(reply, AUTH_XPC_EXTERNAL, &exForm, sizeof(exForm));
+    server_register_auth_token(auth);
+    
+done:
+    CFReleaseSafe(auth);
+    LOGV("server[%i]: AuthorizationMakeExternalForm %i", connection_get_pid(conn), status);
+    return status;
+}
+
+// IN:  AUTH_XPC_EXTERNAL
+// OUT: AUTH_XPC_BLOB
+OSStatus
+authorization_create_from_external_form(connection_t conn, xpc_object_t message, xpc_object_t reply)
+{
+    OSStatus status = errAuthorizationSuccess;
+    auth_token_t auth = NULL;
+    
+    process_t proc = connection_get_process(conn);
+    
+    size_t len;
+    AuthorizationExternalForm * exForm = (AuthorizationExternalForm *)xpc_dictionary_get_data(message, AUTH_XPC_EXTERNAL, &len);
+    require_action(exForm != NULL, done, status = errAuthorizationInternal);
+    require_action(len == sizeof(AuthorizationExternalForm), done, status = errAuthorizationInvalidRef);
+    
+    AuthorizationExternalBlob * exBlob = (AuthorizationExternalBlob *)exForm;
+    auth = server_find_copy_auth_token(&exBlob->blob);
+    require_action(auth != NULL, done, status = errAuthorizationDenied);
+    
+    process_add_auth_token(proc, auth);
+    xpc_dictionary_set_data(reply, AUTH_XPC_BLOB, auth_token_get_blob(auth), sizeof(AuthorizationBlob));
+    
+done:
+    CFReleaseSafe(auth);
+    LOGV("server[%i]: AuthorizationCreateFromExternalForm %i", connection_get_pid(conn), status);
+    return status;
+}
+
+// IN:  AUTH_XPC_RIGHT_NAME
+// OUT: AUTH_XPC_DATA
+OSStatus
+authorization_right_get(connection_t conn AUTH_UNUSED, xpc_object_t message, xpc_object_t reply)
+{
+    OSStatus status = errAuthorizationDenied;
+    rule_t rule = NULL;
+    CFTypeRef cfdict = NULL;
+    xpc_object_t xpcdict = NULL;
+    
+    authdb_connection_t dbconn = authdb_connection_acquire(server_get_database());
+    rule = rule_create_with_string(xpc_dictionary_get_string(message, AUTH_XPC_RIGHT_NAME), dbconn);
+    require(rule != NULL, done);
+    require(rule_get_id(rule) != 0, done);
+    
+    cfdict = rule_copy_to_cfobject(rule, dbconn);
+    require(cfdict != NULL, done);
+    
+    xpcdict = _CFXPCCreateXPCObjectFromCFObject(cfdict);
+    require(xpcdict != NULL, done);
+    
+    // reply
+    xpc_dictionary_set_value(reply, AUTH_XPC_DATA, xpcdict);
+
+    status = errAuthorizationSuccess;
+
+done:
+    authdb_connection_release(&dbconn);
+    CFReleaseSafe(cfdict);
+    xpc_release_safe(xpcdict);
+    CFReleaseSafe(rule);
+    LOGV("server[%i]: AuthorizationRightGet %i", connection_get_pid(conn), status);
+    return status;
+}
+
+static bool _prompt_for_modifications(process_t proc, rule_t rule)
+{
+//    <rdar://problem/13853228> will put back it back at some later date
+//    SecRequirementRef ruleReq = rule_get_requirment(rule);
+//
+//    if (ruleReq && process_verify_requirment(proc, ruleReq)) {
+//        return false;
+//    }
+    
+    return true;
+}
+
+static CFIndex _get_mechanism_index(CFArrayRef mechanisms, CFStringRef m_name)
+{
+    CFIndex index = -1;
+    require(mechanisms, done);
+
+    CFIndex c = CFArrayGetCount(mechanisms);
+    CFStringRef i_name = NULL;
+    for (CFIndex i = 0; i < c; ++i)
+    {
+        i_name = CFArrayGetValueAtIndex(mechanisms, i);
+        if (i_name && (CFGetTypeID(m_name) == CFStringGetTypeID())) {
+            if (CFStringCompare(i_name, m_name, kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
+                index = i;
+                break;
+            }
+        }
+    }
+
+done:
+    return index;
+}
+
+static bool _update_rule_mechanism(authdb_connection_t dbconn, const char * rule_name, CFStringRef mechanism_name, CFStringRef insert_after_name, bool remove)
+{
+    bool updated = false;
+    rule_t rule = NULL;
+    rule_t update_rule = NULL;
+    CFMutableDictionaryRef cfdict = NULL;
+    CFStringRef update_name = NULL;
+
+    require(mechanism_name, done);
+
+    rule = rule_create_with_string(rule_name, dbconn);
+    require(rule_get_id(rule) != 0, done); // rule doesn't exist in the database
+
+    cfdict = rule_copy_to_cfobject(rule, dbconn);
+    require(cfdict != NULL, done);
+
+    CFMutableArrayRef mechanisms = NULL;
+    bool res = CFDictionaryGetValueIfPresent(cfdict, CFSTR(kAuthorizationRuleParameterMechanisms), (void*)&mechanisms);
+    require(res == true, done);
+
+    CFIndex index = -1;
+
+    if (remove) {
+        index = _get_mechanism_index(mechanisms, mechanism_name);
+    } else {
+        if (insert_after_name) {
+            if ((index = _get_mechanism_index(mechanisms, insert_after_name)) != -1) {
+                index++;
+            } else {
+                index = 0; // if we couldn't find the index add it to the begining
+            }
+        } else {
+            index = 0;
+        }
+    }
+
+    if (index != -1) {
+        if(remove) {
+            CFArrayRemoveValueAtIndex(mechanisms, index);
+        } else {
+            if (index < CFArrayGetCount(mechanisms)) {
+                require_action(CFStringCompare(CFArrayGetValueAtIndex(mechanisms, index), mechanism_name, kCFCompareCaseInsensitive) != kCFCompareEqualTo, done, updated = true);
+            }
+            CFArrayInsertValueAtIndex(mechanisms, index, mechanism_name);
+        }
+        
+        CFDictionarySetValue(cfdict, CFSTR(kAuthorizationRuleParameterMechanisms), mechanisms);
+
+        // and write it back
+        update_name = CFStringCreateWithCString(kCFAllocatorDefault, rule_name, kCFStringEncodingUTF8);
+        require(update_name, done);
+        update_rule = rule_create_with_plist(rule_get_type(rule), update_name, cfdict, dbconn);
+        require(update_rule, done);
+        
+        require(rule_sql_commit(update_rule, dbconn, CFAbsoluteTimeGetCurrent(), NULL), done);
+    }
+
+    updated = true;
+
+done:
+    CFReleaseSafe(rule);
+    CFReleaseSafe(update_rule);
+    CFReleaseSafe(cfdict);
+    CFReleaseSafe(update_name);
+    return updated;
+}
+
+/// IN:  AUTH_XPC_BLOB, AUTH_XPC_INT64
+// OUT:
+OSStatus
+authorization_enable_smartcard(connection_t conn, xpc_object_t message, xpc_object_t reply AUTH_UNUSED)
+{
+    const CFStringRef SMARTCARD_LINE = CFSTR("builtin:smartcard-sniffer,privileged");
+    const CFStringRef BUILTIN_LINE = CFSTR("builtin:policy-banner");
+    const char* SYSTEM_LOGIN_CONSOLE = "system.login.console";
+    const char* AUTHENTICATE = "authenticate";
+
+    __block OSStatus status = errAuthorizationSuccess;
+    bool enable_smartcard = false;
+    authdb_connection_t dbconn = NULL;
+    auth_token_t auth = NULL;
+    auth_rights_t checkRight = NULL;
+
+    process_t proc = connection_get_process(conn);
+
+    status = _process_find_copy_auth_token_from_xpc(proc, message, &auth);
+    require_noerr(status, done);
+
+    checkRight = auth_rights_create();
+    auth_rights_add(checkRight, "config.modify.smartcard");
+    status = _server_authorize(conn, auth, kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed | kAuthorizationFlagExtendRights, checkRight, NULL, NULL);
+    require_noerr(status, done);
+
+    enable_smartcard = xpc_dictionary_get_bool(message, AUTH_XPC_DATA);
+
+    dbconn = authdb_connection_acquire(server_get_database());
+
+    if (!_update_rule_mechanism(dbconn, SYSTEM_LOGIN_CONSOLE, SMARTCARD_LINE, BUILTIN_LINE, enable_smartcard ? false : true)) {
+        status = errAuthorizationInternal;
+        LOGE("server[%i]: smartcard: enable(%i) failed to update %s", connection_get_pid(conn), enable_smartcard, SYSTEM_LOGIN_CONSOLE);
+    }
+    if (!_update_rule_mechanism(dbconn, AUTHENTICATE, SMARTCARD_LINE, NULL, enable_smartcard ? false : true)) {
+        status = errAuthorizationInternal;
+        LOGE("server[%i]: smartcard: enable(%i) failed to update %s", connection_get_pid(conn), enable_smartcard, AUTHENTICATE);
+    }
+
+    authdb_checkpoint(dbconn);
+
+done:
+    authdb_connection_release(&dbconn);
+    CFReleaseSafe(checkRight);
+    CFReleaseSafe(auth);
+    return status;
+}
+
+static int64_t _process_get_identifier_count(process_t proc, authdb_connection_t conn)
+{
+    __block int64_t result = 0;
+    
+    authdb_step(conn, "SELECT COUNT(*) AS cnt FROM rules WHERE identifier = ? ", ^(sqlite3_stmt *stmt) {
+        sqlite3_bind_text(stmt, 1, process_get_identifier(proc), -1, NULL);
+    }, ^bool(auth_items_t data) {
+        result = auth_items_get_int64(data, "cnt");
+        return true;
+    });
+    
+    return result;
+}
+
+static int64_t _get_max_process_rights()
+{
+    static dispatch_once_t onceToken;
+    static int64_t max_rights = MAX_PROCESS_RIGHTS;
+    
+    //sudo defaults write /Library/Preferences/com.apple.authd max_process_rights -bool true
+    dispatch_once(&onceToken, ^{
+               CFTypeRef max = (CFNumberRef)CFPreferencesCopyValue(CFSTR("max_process_rights"), CFSTR(SECURITY_AUTH_NAME), kCFPreferencesAnyUser, kCFPreferencesCurrentHost);
+        
+        if (max && CFGetTypeID(max) == CFNumberGetTypeID()) {
+            CFNumberGetValue(max, kCFNumberSInt64Type, &max_rights);
+        }
+        CFReleaseSafe(max);
+    });
+    
+    return max_rights;
+}
+
+// IN:  AUTH_XPC_BLOB, AUTH_XPC_RIGHT_NAME, AUTH_XPC_DATA
+// OUT: 
+OSStatus
+authorization_right_set(connection_t conn, xpc_object_t message, xpc_object_t reply AUTH_UNUSED)
+{
+    __block OSStatus status = errAuthorizationDenied;
+    __block engine_t engine = NULL;
+    CFStringRef cf_rule_name = NULL;
+    CFDictionaryRef cf_rule_dict = NULL;
+    rule_t rule = NULL;
+    rule_t existingRule = NULL;
+    authdb_connection_t dbconn = NULL;
+    auth_token_t auth = NULL;
+    bool force_modify = false;
+    RuleType rule_type = RT_RIGHT;
+    const char * rule_name = NULL;
+    bool auth_rule = false;
+
+    process_t proc = connection_get_process(conn);
+
+    status = _process_find_copy_auth_token_from_xpc(proc, message, &auth);
+    require_noerr(status, done);
+    
+    require_action(xpc_dictionary_get_string(message, AUTH_XPC_RIGHT_NAME) != NULL, done, status = errAuthorizationInternal);
+    require_action(xpc_dictionary_get_value(message, AUTH_XPC_DATA) != NULL, done, status = errAuthorizationInternal);
+
+    rule_name = xpc_dictionary_get_string(message, AUTH_XPC_RIGHT_NAME);
+    require(rule_name != NULL, done);
+
+    if (_compare_string(rule_name, "authenticate")) {
+        rule_type = RT_RULE;
+        auth_rule = true;
+    }
+    
+    cf_rule_name = CFStringCreateWithCString(kCFAllocatorDefault, rule_name, kCFStringEncodingUTF8);
+    require(cf_rule_name != NULL, done);
+    
+    cf_rule_dict = _CFXPCCreateCFObjectFromXPCObject(xpc_dictionary_get_value(message, AUTH_XPC_DATA));
+    require(cf_rule_dict != NULL, done);
+    
+    dbconn = authdb_connection_acquire(server_get_database());
+    
+    rule = rule_create_with_plist(rule_type, cf_rule_name, cf_rule_dict, dbconn);
+    if (process_get_uid(proc) != 0) {
+        require_action(rule_get_extract_password(rule) == false, done, status = errAuthorizationDenied; LOGE("server[%i]: AuthorizationRightSet not allowed to set extract-password. (denied)", connection_get_pid(conn)));
+    }
+    
+    // if rule doesn't currently exist then we have to check to see if they are over the Max.
+    if (rule_get_id(rule) == 0) {
+        if (process_get_identifier(proc) == NULL) {
+            LOGE("server[%i]: AuthorizationRightSet required for process %s (missing code signature). To add rights to the Authorization database, your process must have a code signature.", connection_get_pid(conn), process_get_code_url(proc));
+            force_modify = true;
+        } else {
+            int64_t process_rule_count = _process_get_identifier_count(proc, dbconn);
+            if ((process_rule_count >= _get_max_process_rights())) {
+                if (!connection_get_syslog_warn(conn)) {
+                    LOGE("server[%i]: AuthorizationRightSet Denied API abuse process %s already contains %lli rights.", connection_get_pid(conn), process_get_code_url(proc), _get_max_process_rights());
+                    connection_set_syslog_warn(conn);
+                }
+                status = errAuthorizationDenied;
+                goto done;
+            }
+        }
+    } else {
+        if (auth_rule) {
+            if (process_get_uid(proc) != 0) {
+                LOGE("server[%i]: AuthorizationRightSet denied, root required to update the 'authenticate' rule", connection_get_pid(conn));
+                status = errAuthorizationDenied;
+                goto done;
+            }
+        } else {
+            // verify they are updating a right and not a rule
+            existingRule = rule_create_with_string(rule_get_name(rule), dbconn);
+            if (rule_get_type(existingRule) == RT_RULE) {
+                LOGE("server[%i]: AuthorizationRightSet Denied updating '%s' rule is prohibited", connection_get_pid(conn), rule_get_name(existingRule));
+                status = errAuthorizationDenied;
+                goto done;
+            }
+        }
+    }
+    
+    if (_prompt_for_modifications(proc,rule)) {
+        authdb_connection_release(&dbconn);
+
+        dispatch_sync(connection_get_dispatch_queue(conn), ^{
+            engine = engine_create(conn, auth);
+            connection_set_engine(conn, engine);
+            status = engine_verify_modification(engine, rule, false, force_modify);
+            connection_set_engine(conn, NULL);
+        });
+        require_noerr(status, done);
+        
+        dbconn = authdb_connection_acquire(server_get_database());
+    }
+    
+    if (rule_sql_commit(rule, dbconn, engine ? engine_get_time(engine) : CFAbsoluteTimeGetCurrent(), proc)) {
+        LOGV("server[%i]: Successfully updated rule %s", connection_get_pid(conn), rule_get_name(rule));
+        authdb_checkpoint(dbconn);
+        status = errAuthorizationSuccess;
+    } else {
+        LOGE("server[%i]: Failed to update rule %s", connection_get_pid(conn), rule_get_name(rule));
+        status = errAuthorizationDenied;
+    }
+
+done:
+    authdb_connection_release(&dbconn);
+    CFReleaseSafe(existingRule);
+    CFReleaseSafe(cf_rule_name);
+    CFReleaseSafe(cf_rule_dict);
+    CFReleaseSafe(auth);
+    CFReleaseSafe(rule);
+    CFReleaseSafe(engine);
+    return status;
+}
+
+// IN:  AUTH_XPC_BLOB, AUTH_XPC_RIGHT_NAME
+// OUT:
+OSStatus
+authorization_right_remove(connection_t conn, xpc_object_t message, xpc_object_t reply AUTH_UNUSED)
+{
+    __block OSStatus status = errAuthorizationDenied;
+    __block engine_t engine = NULL;
+    rule_t rule = NULL;
+    authdb_connection_t dbconn = NULL;
+    
+    process_t proc = connection_get_process(conn);
+
+    auth_token_t auth = NULL;
+    status = _process_find_copy_auth_token_from_xpc(proc, message, &auth);
+    require_noerr(status, done);
+    
+    dbconn = authdb_connection_acquire(server_get_database());
+    
+    rule = rule_create_with_string(xpc_dictionary_get_string(message, AUTH_XPC_RIGHT_NAME), dbconn);
+    require(rule != NULL, done);
+    
+    if (_prompt_for_modifications(proc,rule)) {
+        authdb_connection_release(&dbconn);
+        
+        dispatch_sync(connection_get_dispatch_queue(conn), ^{
+            engine = engine_create(conn, auth);
+            connection_set_engine(conn, engine);
+            status = engine_verify_modification(engine, rule, true, false);
+            connection_set_engine(conn, NULL);
+        });
+        require_noerr(status, done);
+        
+        dbconn = authdb_connection_acquire(server_get_database());
+    }
+    
+    if (rule_get_id(rule) != 0) {
+        rule_sql_remove(rule, dbconn);
+    }
+    
+done:
+    authdb_connection_release(&dbconn);
+    CFReleaseSafe(auth);
+    CFReleaseSafe(rule);
+    CFReleaseSafe(engine);
+    LOGV("server[%i]: AuthorizationRightRemove %i", connection_get_pid(conn), status);
+    return status;
+}
+
+#pragma mark -
+#pragma mark test code
+
+OSStatus
+session_set_user_preferences(connection_t conn, xpc_object_t message, xpc_object_t reply)
+{
+    (void)conn;
+    (void)message;
+    (void)reply;
+    return errAuthorizationSuccess;
+}
+
+void
+server_dev() {
+//    rule_t rule = rule_create_with_string("system.preferences.accounts");
+//    CFDictionaryRef dict = rule_copy_to_cfobject(rule);
+//    _show_cf(dict);
+//    CFReleaseSafe(rule);
+//    CFReleaseSafe(dict);
+    
+//    auth_items_t config = NULL;
+//    double d2 = 0, d1 = 5;
+//    authdb_get_key_value(server_get_authdb_reader(), "config", &config);
+//    auth_items_set_double(config, "test", d1);
+//    d2 = auth_items_get_double(config, "test");
+//    LOGV("d1=%f d2=%f", d1, d2);
+//    CFReleaseSafe(config);
+    
+    
+//    auth_items_t items = auth_items_create();
+//    auth_items_set_string(items, "test", "testing 1");
+//    auth_items_set_string(items, "test2", "testing 2");
+//    auth_items_set_string(items, "test3", "testing 3");
+//    auth_items_set_flags(items, "test3", 4);
+//    auth_items_set_string(items, "apple", "apple");
+//    auth_items_set_flags(items, "apple", 1);
+//    auth_items_set_int(items, "int", 45);
+//    auth_items_set_flags(items, "int", 2);
+//    auth_items_set_bool(items, "true", true);
+//    auth_items_set_bool(items, "false", false);
+//    auth_items_set(items, "com.apple.");
+//    auth_show(items);
+//    LOGD("Yeah it works: %s", auth_items_get_string(items, "test3"));
+//    LOGD("Yeah it works: %i", auth_items_get_bool(items, "true"));
+//    LOGD("Yeah it works: %i", auth_items_get_bool(items, "false"));
+//    LOGD("Yeah it works: %i", auth_items_get_int(items, "int"));
+//    (void)auth_items_get_bool(items, "test3");
+//    AuthorizationItemSet * itemSet = auth_items_get_item_set(items);
+//    for (uint32_t i = 0; i < itemSet->count; i++) {
+//        LOGD("item: %s", itemSet->items[i].name);
+//    }
+//
+//    xpc_object_t xpcdata = SerializeItemSet(auth_items_get_item_set(items));
+//    auth_items_t items2 = auth_items_create_with_xpc(xpcdata);
+//    xpc_release(xpcdata);
+//    auth_items_remove_with_flags(items2, 7);
+////    auth_items_set_string(items2, "test3", "testing 3 very good");
+//    auth_items_copy_with_flags(items2, items, 7);
+//    LOGD("Yeah it works: %s", auth_items_get_string(items2, "test3"));
+//    auth_show(items2);
+//    CFReleaseSafe(items2);
+//    
+//    CFReleaseSafe(items);
+}
+
diff --git a/authd/server.h b/authd/server.h
new file mode 100644 (file)
index 0000000..9b4a738
--- /dev/null
@@ -0,0 +1,80 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#ifndef _SECURITY_AUTH_SERVER_H_
+#define _SECURITY_AUTH_SERVER_H_
+
+#include "authd_private.h"
+#include <xpc/xpc.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+OSStatus server_init(void);
+void server_cleanup(void);
+bool server_in_dark_wake(void);
+authdb_t server_get_database(void);
+    
+AUTH_NONNULL_ALL
+connection_t server_register_connection(xpc_connection_t);
+
+AUTH_NONNULL_ALL
+void server_unregister_connection(connection_t);
+    
+AUTH_NONNULL_ALL
+void server_register_auth_token(auth_token_t);
+AUTH_NONNULL_ALL
+void server_unregister_auth_token(auth_token_t);
+
+AUTH_NONNULL_ALL
+auth_token_t server_find_copy_auth_token(AuthorizationBlob * blob);
+    
+AUTH_NONNULL_ALL
+session_t server_find_copy_session(session_id_t,bool create);
+
+void server_dev(void);
+    
+/* API */
+    
+AUTH_NONNULL_ALL
+OSStatus authorization_create(connection_t,xpc_object_t,xpc_object_t);
+
+AUTH_NONNULL_ALL
+OSStatus authorization_create_with_audit_token(connection_t,xpc_object_t,xpc_object_t);
+    
+AUTH_NONNULL_ALL
+OSStatus authorization_free(connection_t,xpc_object_t,xpc_object_t);
+    
+AUTH_NONNULL_ALL
+OSStatus authorization_copy_rights(connection_t,xpc_object_t,xpc_object_t);
+    
+AUTH_NONNULL_ALL
+OSStatus authorization_copy_info(connection_t,xpc_object_t,xpc_object_t);
+    
+AUTH_NONNULL_ALL
+OSStatus authorization_make_external_form(connection_t,xpc_object_t,xpc_object_t);
+    
+AUTH_NONNULL_ALL
+OSStatus authorization_create_from_external_form(connection_t,xpc_object_t,xpc_object_t);
+    
+AUTH_NONNULL_ALL
+OSStatus authorization_right_get(connection_t,xpc_object_t,xpc_object_t);
+    
+AUTH_NONNULL_ALL
+OSStatus authorization_right_set(connection_t,xpc_object_t,xpc_object_t);
+    
+AUTH_NONNULL_ALL
+OSStatus authorization_enable_smartcard(connection_t,xpc_object_t,xpc_object_t);
+
+AUTH_NONNULL_ALL
+OSStatus authorization_right_remove(connection_t,xpc_object_t,xpc_object_t);
+    
+AUTH_NONNULL_ALL
+OSStatus session_set_user_preferences(connection_t,xpc_object_t,xpc_object_t);
+    
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_SECURITY_AUTH_SERVER_H_ */
diff --git a/authd/session.c b/authd/session.c
new file mode 100644 (file)
index 0000000..2484ddf
--- /dev/null
@@ -0,0 +1,208 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#include "session.h"
+#include "process.h"
+#include "debugging.h"
+#include <dispatch/dispatch.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+struct _session_s {
+    __AUTH_BASE_STRUCT_HEADER__;
+    
+    CFMutableSetRef credentials;
+    CFMutableSetRef processes;
+    auditinfo_addr_t auditinfo;
+    
+    dispatch_queue_t dispatch_queue;
+
+};
+
+static void
+_session_finalize(CFTypeRef value)
+{
+    session_t session = (session_t)value;
+    
+    LOGV("session: %i deallocated %p", session->auditinfo.ai_asid, session);
+    
+    // make sure queue is empty
+    dispatch_barrier_sync(session->dispatch_queue, ^{});
+    
+    dispatch_release(session->dispatch_queue);
+    CFReleaseSafe(session->credentials);
+    CFReleaseSafe(session->processes);
+}
+
+AUTH_TYPE_INSTANCE(session,
+                   .init = NULL,
+                   .copy = NULL,
+                   .finalize = _session_finalize,
+                   .equal = NULL,
+                   .hash = NULL,
+                   .copyFormattingDesc = NULL,
+                   .copyDebugDesc = NULL
+                   );
+
+static CFTypeID session_get_type_id() {
+    static CFTypeID type_id = _kCFRuntimeNotATypeID;
+    static dispatch_once_t onceToken;
+    
+    dispatch_once(&onceToken, ^{
+        type_id = _CFRuntimeRegisterClass(&_auth_type_session);
+    });
+    
+    return type_id;
+}
+
+session_t
+session_create(session_id_t sid)
+{
+    session_t session = NULL;
+        
+    session = (session_t)_CFRuntimeCreateInstance(kCFAllocatorDefault, session_get_type_id(), AUTH_CLASS_SIZE(session), NULL);
+    require(session != NULL, done);
+    
+    session->auditinfo.ai_asid = sid;
+    
+    if (!session_update(session)) {
+        LOGE("session: failed to get session info");
+    }
+    
+    session->dispatch_queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
+    check(session->dispatch_queue != NULL);
+    
+    session->credentials = CFSetCreateMutable(kCFAllocatorDefault, 0, &kCFTypeSetCallBacks);
+    session->processes = CFSetCreateMutable(kCFAllocatorDefault, 0, NULL);
+    
+    LOGV("session: %i created (uid=%i) %p", session->auditinfo.ai_asid, session->auditinfo.ai_auid, session);
+
+done:
+    return session;
+}
+
+bool session_update(session_t session)
+{
+    return auditon(A_GETSINFO_ADDR, &session->auditinfo, sizeof(session->auditinfo)) == 0;
+}
+
+uint64_t session_get_attributes(session_t session)
+{
+    session_update(session);
+    
+    return session->auditinfo.ai_flags;
+}
+
+static void _set_attributes(session_t session, uint64_t flags)
+{
+    session->auditinfo.ai_flags = flags;
+    int32_t rc = setaudit_addr(&session->auditinfo, sizeof(session->auditinfo));
+    if (rc != 0) {
+        LOGV("session: failed to update session info (%d)", rc);
+    }
+}
+
+void session_set_attributes(session_t session, uint64_t flags)
+{
+    session_update(session);
+    _set_attributes(session,session->auditinfo.ai_flags | flags);
+}
+
+void session_clear_attributes(session_t session, uint64_t flags)
+{
+    session_update(session);
+    _set_attributes(session,session->auditinfo.ai_flags & ~flags);
+}
+
+
+const void *
+session_get_key(session_t session)
+{
+    return &session->auditinfo.ai_asid;
+}
+
+session_id_t
+session_get_id(session_t session)
+{
+    return session ? session->auditinfo.ai_asid : -1;
+}
+
+uid_t
+session_get_uid(session_t session)
+{
+    return session ? session->auditinfo.ai_auid : (uid_t)-2;
+}
+
+CFIndex
+session_add_process(session_t session, process_t proc)
+{
+    __block CFIndex count = 0;
+    dispatch_sync(session->dispatch_queue, ^{
+        CFSetAddValue(session->processes, proc);
+        count = CFSetGetCount(session->processes);
+    });
+    return count;
+}
+
+CFIndex
+session_remove_process(session_t session, process_t proc)
+{
+    __block CFIndex count = 0;
+    dispatch_sync(session->dispatch_queue, ^{
+        CFSetRemoveValue(session->processes, proc);
+        count = CFSetGetCount(session->processes);
+    });
+    return count;
+}
+
+CFIndex
+session_get_process_count(session_t session)
+{
+    __block CFIndex count = 0;
+    dispatch_sync(session->dispatch_queue, ^{
+        count = CFSetGetCount(session->processes);
+    });
+    return count;
+}
+
+void
+session_set_credential(session_t session, credential_t cred)
+{
+    if (!credential_get_valid(cred))
+        return;
+    
+    dispatch_sync(session->dispatch_queue, ^{
+        CFSetSetValue(session->credentials, cred);
+    });
+}
+
+void
+session_credentials_purge(session_t session)
+{
+    session_credentials_iterate(session, ^bool(credential_t cred) {
+        if (!credential_get_valid(cred)) {
+            CFSetRemoveValue(session->credentials, cred);
+        }
+        return true;
+    });
+}
+
+bool
+session_credentials_iterate(session_t session, credential_iterator_t iter)
+{
+    __block bool result = false;
+    
+    dispatch_sync(session->dispatch_queue, ^{
+        CFIndex count = CFSetGetCount(session->credentials);
+        CFTypeRef values[count];
+        CFSetGetValues(session->credentials, values);
+        for (CFIndex i = 0; i < count; i++) {
+            credential_t cred = (credential_t)values[i];
+            result = iter(cred);
+            if (!result) {
+                break;
+            }
+        }
+    });
+
+    
+    return result;
+}
diff --git a/authd/session.h b/authd/session.h
new file mode 100644 (file)
index 0000000..460e2a3
--- /dev/null
@@ -0,0 +1,60 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#ifndef _SECURITY_AUTH_SESSION_H_
+#define _SECURITY_AUTH_SESSION_H_
+
+#include "credential.h"
+#include <Security/AuthSession.h>
+#include <bsm/audit_session.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+    
+AUTH_WARN_RESULT AUTH_MALLOC AUTH_NONNULL_ALL AUTH_RETURNS_RETAINED
+session_t session_create(session_id_t);
+
+AUTH_NONNULL_ALL
+bool session_update(session_t);
+
+AUTH_NONNULL_ALL
+uint64_t session_get_attributes(session_t);
+    
+AUTH_NONNULL_ALL
+void session_set_attributes(session_t,uint64_t flags);
+
+AUTH_NONNULL_ALL
+void session_clear_attributes(session_t,uint64_t flags);
+    
+AUTH_NONNULL_ALL
+const void * session_get_key(session_t);
+    
+AUTH_NONNULL_ALL
+session_id_t session_get_id(session_t);
+    
+AUTH_NONNULL_ALL
+uid_t session_get_uid(session_t);
+
+AUTH_NONNULL_ALL
+CFIndex session_add_process(session_t, process_t);
+
+AUTH_NONNULL_ALL
+CFIndex session_remove_process(session_t, process_t);
+
+AUTH_NONNULL_ALL
+CFIndex session_get_process_count(session_t);
+
+AUTH_NONNULL_ALL
+void session_set_credential(session_t,credential_t);
+
+AUTH_NONNULL_ALL
+void session_credentials_purge(session_t);
+    
+AUTH_NONNULL_ALL
+bool session_credentials_iterate(session_t, credential_iterator_t iter);
+    
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_SECURITY_AUTH_SESSION_H_ */
diff --git a/cloud_keychain_diagnose/cloud_keychain_diagnose-Prefix.pch b/cloud_keychain_diagnose/cloud_keychain_diagnose-Prefix.pch
new file mode 100644 (file)
index 0000000..b0e33d7
--- /dev/null
@@ -0,0 +1,5 @@
+//
+// Prefix header for all source files of the 'cloud_keychain_diagnose' target in the 'cloud_keychain_diagnose' project
+//
+
+#inclucde  <CoreFoundation/CoreFoundation.h>
index 7c1c312ecd88963256848b2ba4ad86a7868afead..905215b6338d5cec0984d1509196c77669c7dcaf 100644 (file)
@@ -5,4 +5,11 @@ DEBUG_INFORMATION_FORMAT = dwarf-with-dsym
 SDKROOT = 
 CURRENT_PROJECT_VERSION = $(RC_ProjectSourceVersion)
 VERSIONING_SYSTEM = apple-generic;
 SDKROOT = 
 CURRENT_PROJECT_VERSION = $(RC_ProjectSourceVersion)
 VERSIONING_SYSTEM = apple-generic;
-DEAD_CODE_STRIPPING = YES;
+
+DEAD_CODE_STRIPPING = YES
+
+// Debug symbols should be on obviously
+GCC_GENERATE_DEBUGGING_SYMBOLS = YES
+COPY_PHASE_STRIP = NO
+STRIP_STYLE = debugging
+STRIP_INSTALLED_PRODUCT = NO
diff --git a/config/command.xcconfig b/config/command.xcconfig
new file mode 100644 (file)
index 0000000..9e80246
--- /dev/null
@@ -0,0 +1,13 @@
+//
+//  command.xcconfig
+//  Security
+//
+//  Created by J Osborne on 1/10/13.
+//
+//
+
+HEADER_SEARCH_PATHS = $(PROJECT_DIR) $(PROJECT_DIR)/security2 $(PROJECT_DIR)/sec/SOSCircle $(PROJECT_DIR)/utilities $(PROJECT_DIR)/sec
+
+STRIP_STYLE = all
+STRIP_INSTALLED_PRODUCT = YES
+DEPLOYMENT_POSTPROCESSING = YES
index 937d177552d7c32bc7eea9753d7d6523f1f0ea72..47555cf5ce157140e769b2e16f93723b761e7281 100644 (file)
@@ -1,3 +1,2 @@
 GCC_OPTIMIZATION_LEVEL = 0
 GCC_PREPROCESSOR_DEFINITIONS = DEBUG=1 $(inherited)
 GCC_OPTIMIZATION_LEVEL = 0
 GCC_PREPROCESSOR_DEFINITIONS = DEBUG=1 $(inherited)
-COPY_PHASE_STRIP = NO
diff --git a/config/executable.xcconfig b/config/executable.xcconfig
new file mode 100644 (file)
index 0000000..e6f1e68
--- /dev/null
@@ -0,0 +1,7 @@
+#include "base.xcconfig"
+
+PRODUCT_NAME = $(TARGET_NAME)
+
+STRIP_STYLE = all
+STRIP_INSTALLED_PRODUCT = YES
+DEPLOYMENT_POSTPROCESSING = YES
index 1dec02cca81b4b5185ce6046faa21f0c2271fdb7..70d116f787b93186984bfdbb8e96b3a9bbe7a636 100644 (file)
@@ -5,7 +5,7 @@ EXECUTABLE_PREFIX =
 
 CODE_SIGN_IDENTITY = 
 
 
 CODE_SIGN_IDENTITY = 
 
-HEADER_SEARCH_PATHS = $(PROJECT_DIR)/../include $(BUILT_PRODUCTS_DIR)/derived_src $(BUILT_PRODUCTS_DIR) $(PROJECT_DIR)/lib
+HEADER_SEARCH_PATHS = $(PROJECT_DIR)/../regressions $(PROJECT_DIR)/../include $(BUILT_PRODUCTS_DIR)/derived_src $(BUILT_PRODUCTS_DIR) $(PROJECT_DIR)/lib $(PROJECT_DIR)/../utilities
 
 SKIP_INSTALL = YES
 
 
 SKIP_INSTALL = YES
 
@@ -13,7 +13,9 @@ ALWAYS_SEARCH_USER_PATHS = YES
 
 GCC_C_LANGUAGE_STANDARD = gnu99
 
 
 GCC_C_LANGUAGE_STANDARD = gnu99
 
-WARNING_CFLAGS = -Wmost -Wno-four-char-constants -Wno-unknown-pragmas $(inherited)
+GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+
+WARNING_CFLAGS = -Wno-error=#warnings -Wmost -Wno-four-char-constants -Wno-unknown-pragmas $(inherited)
 
 GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO
 
 
 GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO
 
index dc5f876186f862c53b5476ef98113138383b775f..088ded92a81006819c31d49f1dc81025b210663d 100644 (file)
@@ -1,3 +1,2 @@
+GCC_OPTIMIZATION_LEVEL = s
 GCC_PREPROCESSOR_DEFINITIONS = NDEBUG=1 $(inherited)
 GCC_PREPROCESSOR_DEFINITIONS = NDEBUG=1 $(inherited)
-COPY_PHASE_STRIP = YES
-
index 72bd92076b4e8e971b09c0aea1eabc3417a57995..bf031881fb0f815afe90f76cba18ad7408d3ceed 100644 (file)
@@ -11,8 +11,13 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES
 
 ALWAYS_SEARCH_USER_PATHS = NO
 
 
 ALWAYS_SEARCH_USER_PATHS = NO
 
+HEADER_SEARCH_PATHS = $(PROJECT_DIR)/include $(PROJECT_DIR)/sec/SOSCircle $(PROJECT_DIR)/utilities
+
 //INSTALLHDRS_SCRIPT_PHASE = YES
 
 //INSTALLHDRS_SCRIPT_PHASE = YES
 
+STRIP_INSTALLED_PRODUCT = YES
+DEPLOYMENT_POSTPROCESSING = YES
+
 GCC_C_LANGUAGE_STANDARD = gnu99
 
 GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO
 GCC_C_LANGUAGE_STANDARD = gnu99
 
 GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO
diff --git a/config/test.xcconfig b/config/test.xcconfig
new file mode 100644 (file)
index 0000000..8f60b70
--- /dev/null
@@ -0,0 +1,4 @@
+#include "security.xcconfig"
+
+HEADER_SEARCH_PATHS = $(PROJECT_DIR) $(PROJECT_DIR)/regressions/
+
diff --git a/iCloudStats/com.apple.iCloudStats.plist b/iCloudStats/com.apple.iCloudStats.plist
new file mode 100644 (file)
index 0000000..08282ee
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>Label</key>
+       <string>com.apple.iCloudStats</string>
+       <key>ProgramArguments</key>
+       <array>
+               <string>/usr/libexec/iCloudStats</string>
+       </array>
+       <!-- Check every seven days   60 * 60 * 24 * 7 =  604800 -->
+       <key>StartInterval</key>
+       <integer>604800</integer>
+       <!--
+       <key>Umask</key>
+       <integer>18</integer>
+       <key>UserName</key>
+       <string>_securityd</string>
+       -->
+</dict>
+</plist>
diff --git a/iCloudStats/iCloudStats.1 b/iCloudStats/iCloudStats.1
new file mode 100644 (file)
index 0000000..516ef44
--- /dev/null
@@ -0,0 +1,79 @@
+.\"Modified from man(1) of FreeBSD, the NetBSD mdoc.template, and mdoc.samples.\r
+.\"See Also:\r
+.\"man mdoc.samples for a complete listing of options\r
+.\"man mdoc for the short list of editing options\r
+.\"/usr/share/misc/mdoc.template\r
+.Dd 7/20/13               \" DATE \r
+.Dt iCloudStats 1      \" Program name and manual section number \r
+.Os Darwin\r
+.Sh NAME                 \" Section Header - required - don't modify \r
+.Nm iCloudStats,\r
+.\" The following lines are read in generating the apropos(man -k) database. Use only key\r
+.\" words here as the database is built based on the words here and in the .ND line. \r
+.Nm Other_name_for_same_program(),\r
+.Nm Yet another name for the same program.\r
+.\" Use .Nm macro to designate other names for the documented program.\r
+.Nd This line parsed for whatis database.\r
+.Sh SYNOPSIS             \" Section Header - required - don't modify\r
+.Nm\r
+.Op Fl abcd              \" [-abcd]\r
+.Op Fl a Ar path         \" [-a path] \r
+.Op Ar file              \" [file]\r
+.Op Ar                   \" [file ...]\r
+.Ar arg0                 \" Underlined argument - use .Ar anywhere to underline\r
+arg2 ...                 \" Arguments\r
+.Sh DESCRIPTION          \" Section Header - required - don't modify\r
+Use the .Nm macro to refer to your program throughout the man page like such:\r
+.Nm\r
+Underlining is accomplished with the .Ar macro like this:\r
+.Ar underlined text .\r
+.Pp                      \" Inserts a space\r
+A list of items with descriptions:\r
+.Bl -tag -width -indent  \" Begins a tagged list \r
+.It item a               \" Each item preceded by .It macro\r
+Description of item a\r
+.It item b\r
+Description of item b\r
+.El                      \" Ends the list\r
+.Pp\r
+A list of flags and their descriptions:\r
+.Bl -tag -width -indent  \" Differs from above in tag removed \r
+.It Fl a                 \"-a flag as a list item\r
+Description of -a flag\r
+.It Fl b\r
+Description of -b flag\r
+.El                      \" Ends the list\r
+.Pp\r
+.\" .Sh ENVIRONMENT      \" May not be needed\r
+.\" .Bl -tag -width "ENV_VAR_1" -indent \" ENV_VAR_1 is width of the string ENV_VAR_1\r
+.\" .It Ev ENV_VAR_1\r
+.\" Description of ENV_VAR_1\r
+.\" .It Ev ENV_VAR_2\r
+.\" Description of ENV_VAR_2\r
+.\" .El                      \r
+.Sh FILES                \" File used or created by the topic of the man page\r
+.Bl -tag -width "/Users/joeuser/Library/really_long_file_name" -compact\r
+.It Pa /usr/share/file_name\r
+FILE_1 description\r
+.It Pa /Users/joeuser/Library/really_long_file_name\r
+FILE_2 description\r
+.El                      \" Ends the list\r
+.\" .Sh DIAGNOSTICS       \" May not be needed\r
+.\" .Bl -diag\r
+.\" .It Diagnostic Tag\r
+.\" Diagnostic informtion here.\r
+.\" .It Diagnostic Tag\r
+.\" Diagnostic informtion here.\r
+.\" .El\r
+.Sh SEE ALSO \r
+.\" List links in ascending order by section, alphabetically within a section.\r
+.\" Please do not reference files that do not exist without filing a bug report\r
+.Xr a 1 , \r
+.Xr b 1 ,\r
+.Xr c 1 ,\r
+.Xr a 2 ,\r
+.Xr b 2 ,\r
+.Xr a 3 ,\r
+.Xr b 3 \r
+.\" .Sh BUGS              \" Document known, unremedied bugs \r
+.\" .Sh HISTORY           \" Document history if command behaves in a unique manner
\ No newline at end of file
diff --git a/iCloudStats/main.c b/iCloudStats/main.c
new file mode 100644 (file)
index 0000000..d5f79a6
--- /dev/null
@@ -0,0 +1,274 @@
+//
+//  main.c
+//  iCloudStats
+//
+//  Created by local on 7/20/13.
+//
+//
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#import "SOSCloudCircle.h"
+#import <Security/Security.h>
+
+static const CFStringRef gMessageTracerPrefix = CFSTR("com.apple.message.");
+
+static const CFStringRef gClientIsUsingiCloudKeychainSyncing = CFSTR("com.apple.cloudkeychain.deviceIsUsingICloudKeychain");
+static const CFStringRef gClientIsNotUsingiCloudKeychainSyncing = CFSTR("com.apple.cloudkeychain.deviceIsNotUsingICloudKeychain");
+static const CFStringRef gNumberOfPeers = CFSTR("com.apple.cloudkeychain.numberOfPeers");
+static const CFStringRef gNumberOfItemsBeingSynced = CFSTR("com.apple.cloudkeychain.numberOfItemsBeingSynced");
+
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR))
+#include <asl.h>
+
+static const char* gMessageTracerDomainField = "com.apple.message.domain";
+static const const char* gTopLevelKeyForiCloudKeychainTracing = "com.apple.cloudkeychain";
+
+static bool OSX_SetCloudKeychainTraceValueForKey(CFStringRef key, int64_t value)
+{
+       bool result = false;
+       
+       if (NULL == key)
+       {
+               return result;
+       }
+       
+       aslmsg mAsl = NULL;
+       mAsl = asl_new(ASL_TYPE_MSG);
+       if (NULL == mAsl)
+       {
+               return result;
+       }
+    
+    CFIndex key_length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(key), kCFStringEncodingUTF8);
+    key_length += 1; // For null
+    char base_key_buffer[key_length];
+    memset(base_key_buffer, 0,key_length);
+    if (!CFStringGetCString(key, base_key_buffer, key_length, kCFStringEncodingUTF8))
+    {
+        asl_free(mAsl);
+        return result;
+    }
+    
+    
+    CFStringRef key_str = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@%@"), gMessageTracerPrefix, key);
+    if (NULL == key_str)
+    {
+        asl_free(mAsl);
+        return result;
+    }
+       
+       CFStringRef value_str = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%lld"), value);
+    if (NULL == value_str)
+    {
+        asl_free(mAsl);
+        CFRelease(key_str);
+        return result;
+    }
+    
+    CFIndex key_str_numBytes = CFStringGetMaximumSizeForEncoding(CFStringGetLength(key_str), kCFStringEncodingUTF8);
+    key_str_numBytes += 1; // For null
+    char key_buffer[key_str_numBytes];
+    memset(key_buffer, 0, key_str_numBytes);
+    if (!CFStringGetCString(key_str, key_buffer, key_str_numBytes, kCFStringEncodingUTF8))
+    {
+        asl_free(mAsl);
+        CFRelease(key_str);
+        CFRelease(value_str);
+        return result;
+    }
+    CFRelease(key_str);
+    
+    CFIndex value_str_numBytes = CFStringGetMaximumSizeForEncoding(CFStringGetLength(value_str), kCFStringEncodingUTF8);
+    value_str_numBytes += 1; // For null
+    char value_buffer[value_str_numBytes];
+    memset(value_buffer, 0, value_str_numBytes);
+    if (!CFStringGetCString(value_str, value_buffer, value_str_numBytes, kCFStringEncodingUTF8))
+    {
+        asl_free(mAsl);
+        CFRelease(value_str);
+        return result;
+    }
+    CFRelease(value_str);
+       
+       asl_set(mAsl, gMessageTracerDomainField, base_key_buffer);
+       
+       asl_set(mAsl, key_buffer, value_buffer);
+       asl_log(NULL, mAsl, ASL_LEVEL_NOTICE, "%s is %lld", key_buffer, value);
+       asl_free(mAsl);
+       return true;
+}
+#endif
+
+#if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR)
+#import <AggregateDictionary/ADClient.h>
+
+static bool iOS_SetCloudKeychainTraceValueForKey(CFStringRef key, int64_t value)
+{
+       if (NULL == key)
+       {
+               return false;
+       }
+       
+       ADClientSetValueForScalarKey(key, value);
+       return true;
+}
+#endif
+
+static bool ClientIsInCircle()
+{
+    bool result = false;
+    CFErrorRef error = NULL;
+    SOSCCStatus status = kSOSCCError;
+    
+    status = SOSCCThisDeviceIsInCircle(&error);
+    if (NULL != error)
+    {
+        CFRelease(error);
+    }
+    else
+    {
+        switch (status)
+        {
+            case kSOSCCInCircle:
+            {
+                result = true;
+            }
+                               break;
+                               
+                               // kSOSCCRequestPending
+                               // While this device will be in a circle, it is not in
+                               // one yet. For now, this will be treated as if the device
+                               // was not in a circle and will wait for the device to
+                               // be in a circle and have that turn on this daemon with
+                               // launchctl
+            case kSOSCCRequestPending:
+            case kSOSCCCircleAbsent:
+            case kSOSCCError:
+            default:
+                break;
+        }
+    }
+    return result;
+}
+
+
+static bool sendTraceMessage(CFStringRef key, int64_t value)
+{
+       
+#if (TARGET_IPHONE_SIMULATOR)
+       return false;
+#endif
+    
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+       return OSX_SetCloudKeychainTraceValueForKey(key, value);
+#endif
+    
+#if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR)
+       return iOS_SetCloudKeychainTraceValueForKey(key, value);
+#endif
+       
+}
+
+int64_t GetNumberOfPeers()
+{
+       int64_t result = 0;
+       
+       CFErrorRef error = NULL;
+       CFArrayRef peers = NULL;
+       
+       peers = SOSCCCopyPeerPeerInfo(&error);
+       if (NULL != error)
+       {
+               CFRelease(error);
+               if (NULL != peers)
+               {
+                       CFRelease(peers);
+               }
+               return result;
+       }
+       
+       if (NULL != peers)
+       {
+               result = (int64_t)CFArrayGetCount(peers);
+               CFRelease(peers);
+       }
+       
+       return result;
+}
+
+
+int64_t GetNumberOfItemsBeingSynced()
+{
+       int64_t result = 0;
+       
+       
+    CFTypeRef classTypes[] = {kSecClassInternetPassword, kSecClassGenericPassword};
+    
+    
+    CFArrayRef classTypesArray = CFArrayCreate(kCFAllocatorDefault,
+                (const void **)classTypes, (sizeof(classTypes)/sizeof(classTypes[0])),
+                &kCFTypeArrayCallBacks);
+    if (NULL == classTypesArray)
+    {
+        return result;
+    }
+    
+    CFTypeRef keys[] = {kSecClass, kSecAttrSynchronizable, kSecReturnAttributes};
+    CFTypeRef values[] = {classTypesArray, kCFBooleanTrue, kCFBooleanTrue};
+    
+    CFDictionaryRef query = CFDictionaryCreate(kCFAllocatorDefault, (const void **)keys, (const void **)values, (sizeof(keys)/sizeof(keys[0])), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    CFRelease(classTypesArray);
+    if (NULL == query)
+    {
+        return result;
+    }
+    
+       CFArrayRef query_result = NULL;
+       OSStatus status =  SecItemCopyMatching(query, (CFTypeRef *)&query_result);
+       if (noErr != status)
+       {
+        CFRelease(query);
+               if (NULL != query_result)
+               {
+                       CFRelease(query_result);
+               }
+               return result;
+       }
+    CFRelease(query);
+       
+       if (NULL != query_result)
+    {
+        result = 1; // There is at least one item being synced
+        if (CFArrayGetTypeID() == CFGetTypeID(query_result))
+        {
+            result = (int64_t)CFArrayGetCount(query_result);
+        }
+        CFRelease(query_result);
+    }
+       
+       return result;
+}
+
+
+int main(int argc, const char * argv[])
+{
+       int64_t value = 1;
+    if (!ClientIsInCircle())
+    {
+               sendTraceMessage(gClientIsNotUsingiCloudKeychainSyncing, value);
+        return 0;
+    }
+    
+    sendTraceMessage(gClientIsUsingiCloudKeychainSyncing, value);
+    
+    value = GetNumberOfPeers();
+    sendTraceMessage(gNumberOfPeers, value);
+    
+    value = GetNumberOfItemsBeingSynced();
+    sendTraceMessage(gNumberOfItemsBeingSynced, value);
+
+    
+    return 0;
+}
+
index 65447ee78c5fdda08af57c7ade8bd048faf069b1..fcafbdfa3969207d38ee3984959007cc0f3eb8c6 100644 (file)
@@ -19,6 +19,6 @@
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>55179.13</string>
+       <string>55471</string>
 </dict>
 </plist>
 </dict>
 </plist>
diff --git a/lib/dummy.cpp b/lib/dummy.cpp
new file mode 100644 (file)
index 0000000..f4475ab
--- /dev/null
@@ -0,0 +1,3 @@
+#include <cstdio>
+
+// This file was created for the sole purpose of dynamically linking with libc++.dylib
\ No newline at end of file
diff --git a/lib/en.lproj/authorization.buttons.strings b/lib/en.lproj/authorization.buttons.strings
new file mode 100644 (file)
index 0000000..f2a53e6
--- /dev/null
@@ -0,0 +1,131 @@
+"system.preferences.accounts" = "Unlock";
+
+"com.apple.SoftwareUpdate.scan" = "Check";
+
+"system.preferences.datetime" = "Unlock";
+
+"system.identity.write.credential" = "Update Credentials";
+
+"com.apple.appserver.privilege.admin" = "Modify Settings";
+
+"system.privilege.taskport.safe" = "Take Control";
+
+"com.apple.DiskManagement.internal." = "Modify Disk";
+
+"system.print.operator" = "Allow Printing";
+
+"com.apple.AOSNotification.FindMyMac.modify" = "Allow";
+
+"system.printingmanager" = "Print";
+
+"com.apple.DiskManagement.reserveKEK" = "Modify Disk";
+
+"system.services.systemconfiguration.network" = "Modify Configuration";
+
+"sys.openfile." = "Open";
+
+"com.apple.OpenScripting.additions.send" = "Send Commands";
+
+"com.apple.library-repair" = "Repair";
+
+"com.apple.XType.fontmover.restore" = "Restore";
+
+"system.csfde.requestpassword" = "Unlock";
+
+"system.sharepoints." = "Modify Preferences";
+
+"system.preferences.energysaver" = "Unlock";
+
+"system.install.apple-software" = "Install Software";
+
+"com.apple.security.assessment.update" = "Modify Settings";
+
+"com.apple.docset.install" = "Update Documentation";
+
+"com.apple.Safari.parental-controls" = "Modify Settings";
+
+"com.apple.ServiceManagement.blesshelper" = "Install Helper";
+
+"system.device.dvd.setregion.initial" = "Set";
+
+"system.preferences.network" = "Unlock";
+
+"system.identity.write." = "Update Users";
+
+"com.apple.trust-settings.user" = "Update Settings";
+
+"system.preferences.printing" = "Unlock";
+
+"system.hdd.smart" = "Modify Settings";
+
+"system.print.admin" = "Modify Settings";
+
+"system.preferences.accessibility" = "Unlock";
+
+"com.apple.activitymonitor.kill" = "Quit Process";
+
+"system.burn" = "Burn";
+
+"system.preferences.sharing" = "Unlock";
+
+"system.preferences.parental-controls" = "Unlock";
+
+"system.preferences.security" = "Unlock";
+
+"system.preferences.startupdisk" = "Unlock";
+
+"com.apple.ServiceManagement.daemons.modify" = "Add Helper";
+
+"com.apple.DiskManagement." = "Modify Disk";
+
+"com.apple.trust-settings.admin" = "Update Settings";
+
+"system.identity.write.self" = "Update Credentials";
+
+"system.install.app-store-software" = "Install Software";
+
+"system.install.app-store-software.standard-user" = "Install Software";
+
+"system.install.apple-software.standard-user" = "Install Software";
+
+"system.preferences.version-cue" = "Modify Preferences";
+
+"system.preferences" = "Modify Settings";
+
+"com.apple.SoftwareUpdate.modify-settings" = "Unlock";
+
+"com.apple.uninstalld.uninstall" = "Delete";
+
+"system.privilege.taskport" = "Take Control";
+
+"system.install.software" = "Install Software";
+
+"system.preferences.security.remotepair" = "Pair";
+
+"com.apple.XType.fontmover.remove" = "Remove";
+
+"system.global-login-items." = "Add";
+
+"com.apple.server.admin.streaming" = "Modify Settings";
+
+"system.preferences.softwareupdate" = "Unlock";
+
+"system.keychain.modify" = "Modify Keychain";
+
+"com.apple.XType.fontmover.install" = "Install";
+
+"system.services.directory.configure" = "Modify Configuration";
+
+"system.preferences.timemachine" = "Unlock";
+
+"com.apple.appserver.privilege.user" = "Modify Settings";
+
+"system.privilege.taskport.debug" = "Continue";
+
+"com.apple.container-repair" = "Repair";
+
+"com.apple.AOSNotification.FindMyMac.remove" = "Turn Off";
+
+"com.apple.ReportPanic.fixRight" = "Move to Trash";
+
+"com.apple.iBooksX.ParentalControl" = "Unlock";
diff --git a/lib/en.lproj/authorization.prompts.strings b/lib/en.lproj/authorization.prompts.strings
new file mode 100644 (file)
index 0000000..9ef4fe7
--- /dev/null
@@ -0,0 +1,139 @@
+"system.preferences.accounts" = "__APPNAME__ is trying to unlock Users & Groups preferences.";
+
+"com.apple.SoftwareUpdate.scan" = "__APPNAME__ is trying to check for new Apple-provided software.";
+
+"system.preferences.datetime" = "__APPNAME__ is trying to unlock the Date & Time preferences.";
+
+"system.identity.write.credential" = "__APPNAME__ is trying to update the authentication credentials.";
+
+"com.apple.appserver.privilege.admin" = "__APPNAME__ is trying to modify the Application Server settings.";
+
+"system.privilege.taskport.safe" = "__APPNAME__ is trying to take control of another process.";
+
+"com.apple.DiskManagement.internal." = "__APPNAME__ is trying to modify the selected disk.";
+
+"system.print.operator" = "__APPNAME__ is trying to use the printer.";
+
+"com.apple.AOSNotification.FindMyMac.modify" = "__APPNAME__ wants to make changes to Find My Mac.";
+
+"system.printingmanager" = "__APPNAME__ is trying to print to a locked printer.";
+
+"com.apple.DiskManagement.reserveKEK" = "__APPNAME__ is trying to modify an encrypted disk.";
+
+"system.services.systemconfiguration.network" = "__APPNAME__ is trying to modify the system network configuration.";
+
+"sys.openfile." = "__APPNAME__ is trying to open the chosen file.";
+
+"com.apple.lldb.LaunchUsingXPC" = "__APPNAME__ is trying to take control of a root process.";
+
+"com.apple.OpenScripting.additions.send" = "__APPNAME__ is trying to send restricted scripting addition commands to other applications.";
+
+"com.apple.library-repair" = "__APPNAME__ is trying to repair your photo library.";
+
+"com.apple.XType.fontmover.restore" = "__APPNAME__ is trying to restore the default system fonts.";
+
+"system.csfde.requestpassword" = "__APPNAME__ needs to unlock your disk.";
+
+"com.apple.Safari.show-passwords" = "__APPNAME__ is trying to show passwords.";
+
+"com.apple.Safari.show-credit-card-numbers" = "__APPNAME__ is trying to show credit card numbers.";
+
+"system.sharepoints." = "__APPNAME__ is trying to modify Sharing preferences.";
+
+"system.preferences.energysaver" = "__APPNAME__ is trying to unlock the Energy Saver preferences.";
+
+"system.install.apple-software" = "__APPNAME__ is trying to install Apple-provided software.";
+
+"system.install.apple-software.standard-user" = "__APPNAME__ is trying to install Apple-provided software.";
+
+"com.apple.security.assessment.update" = "__APPNAME__ is trying to allow an item to always run.";
+
+"com.apple.docset.install" = "__APPNAME__ is trying to update the developer documentation.";
+
+"com.apple.Safari.parental-controls" = "__APPNAME__ is trying to modify the Parental Controls settings for Safari.";
+
+"com.apple.ServiceManagement.blesshelper" = "__APPNAME__ is trying to install a new helper tool.";
+
+"system.device.dvd.setregion.initial" = "__APPNAME__ is trying to set the DVD region code for the first time.";
+
+"system.preferences.network" = "__APPNAME__ is trying to unlock the Network preferences.";
+
+"system.identity.write." = "__APPNAME__ is trying to update the set of local users.";
+
+"com.apple.opendirectoryd.linkidentity" = "__APPNAME__ is trying to modify your user account.";
+
+"com.apple.trust-settings.user" = "You are making changes to your Certificate Trust Settings.";
+
+"system.preferences.printing" = "__APPNAME__ is trying to unlock the Printers & Scanners preferences.";
+
+"system.hdd.smart" = "__APPNAME__ is trying to modify the diagnostic settings for your hard drive.";
+
+"system.print.admin" = "__APPNAME__ is trying to modify the printer settings.";
+
+"system.preferences.accessibility" = "__APPNAME__ is trying to unlock Accessibility preferences.";
+
+"com.apple.activitymonitor.kill" = "__APPNAME__ is trying to quit the selected process.";
+
+"system.burn" = "__APPNAME__ is trying to burn a disc.";
+
+"system.preferences.sharing" = "__APPNAME__ is trying to unlock the Sharing preferences.";
+
+"system.preferences.parental-controls" = "__APPNAME__ is trying to unlock Parental Controls preferences.";
+
+"system.preferences.security" = "__APPNAME__ is trying to unlock Security & Privacy preferences.";
+
+"system.preferences.startupdisk" = "__APPNAME__ is trying to unlock the Startup Disk preferences.";
+
+"com.apple.ServiceManagement.daemons.modify" = "__APPNAME__ is trying to add a new helper tool.";
+
+"com.apple.DiskManagement." = "__APPNAME__ is trying to modify the selected disk.";
+
+"com.apple.trust-settings.admin" = "You are making changes to the System Certificate Trust Settings.";
+
+"system.identity.write.self" = "__APPNAME__ is trying to update your authentication credentials.";
+
+"system.install.app-store-software" = "__APPNAME__ is trying to install software.";
+
+"system.install.app-store-software.standard-user" = "__APPNAME__ is trying to install software.";
+
+"system.preferences.version-cue" = "__APPNAME__ is trying to modify the Version Cue preferences.";
+
+"system.preferences" = "__APPNAME__ is trying to modify your system settings.";
+
+"com.apple.SoftwareUpdate.modify-settings" = "__APPNAME__ is trying to unlock the Software Update preferences.";
+
+"com.apple.uninstalld.uninstall" = "__APPNAME__ is trying to delete an application.";
+
+"system.privilege.taskport" = "__APPNAME__ is trying to take control of another process.";
+
+"system.install.software" = "__APPNAME__ is trying to install new software.";
+
+"system.preferences.security.remotepair" = "__APPNAME__ is trying to pair the remote.";
+
+"com.apple.XType.fontmover.remove" = "__APPNAME__ is trying to remove existing system fonts.";
+
+"system.global-login-items." = "__APPNAME__ is trying to add a login item.";
+
+"com.apple.server.admin.streaming" = "__APPNAME__ is trying to modify the QuickTime Streaming Server settings.";
+
+"system.preferences.softwareupdate" = "__APPNAME__ is trying to unlock the Software Update preferences.";
+
+"system.keychain.modify" = "__APPNAME__ is trying to modify the system keychain.";
+
+"com.apple.XType.fontmover.install" = "__APPNAME__ is trying to install new system fonts.";
+
+"system.services.directory.configure" = "__APPNAME__ is trying to modify the Directory Services configuration.";
+
+"system.preferences.timemachine" = "__APPNAME__ is trying to unlock the Time Machine preferences.";
+
+"com.apple.appserver.privilege.user" = "__APPNAME__ is trying to modify your Application Server settings.";
+
+"system.privilege.taskport.debug" = "__APPNAME__ needs to take control of another process for debugging to continue.";
+
+"com.apple.container-repair" = "__APPNAME__ needs to repair your Library to run applications.";
+
+"com.apple.pf.rule" = "__APPNAME__ is trying to modify firewall rules.";
+
+"com.apple.AOSNotification.FindMyMac.remove" = "__APPNAME__ is trying to turn off Find My Mac.";
+
+"com.apple.iBooksX.ParentalControl" = "__APPNAME__ is trying to unlock your Parental Controls preferences.";
diff --git a/lib/framework.sb b/lib/framework.sb
new file mode 100644 (file)
index 0000000..fcba2c8
--- /dev/null
@@ -0,0 +1,2 @@
+;; allow clients to communicate with secd
+(allow mach-lookup (global-name "com.apple.secd"))
index 8e47f97dad5cc45544c0792be3aa8ff9299f1a48..18cc2b0d7b6186c20426fba77200e2077f90970f 100644 (file)
@@ -331,7 +331,7 @@ MAINPROGRAM
        die "$compile exited funny: $?" unless $status == 0;
 
        $status = system( <<"LINKERSTEP");
        die "$compile exited funny: $?" unless $status == 0;
 
        $status = system( <<"LINKERSTEP");
-(cd ${TMPDIR} ; /usr/bin/g++ -o generateErrStrings generateErrStrings.o -framework Foundation )
+(cd ${TMPDIR} ; /usr/bin/clang++ -o generateErrStrings generateErrStrings.o -framework Foundation )
 LINKERSTEP
        die "$linker exited funny: $?" unless $status == 0;
 
 LINKERSTEP
        die "$linker exited funny: $?" unless $status == 0;
 
index 28d41d4924f49347310b7dddb8abd48a735e5c57..6e400b01be6e171231f3bd7cd23ea9b82799bf1a 100644 (file)
@@ -17,7 +17,7 @@
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>55179.13</string>
+       <string>55471</string>
        <key>CFBundleShortVersionString</key>
        <string>3.0</string>
 </dict>
        <key>CFBundleShortVersionString</key>
        <string>3.0</string>
 </dict>
diff --git a/lib/security.exp b/lib/security.exp
deleted file mode 100644 (file)
index d34e4db..0000000
+++ /dev/null
@@ -1,2067 +0,0 @@
-_SecurityVersionNumber
-_SecurityVersionString
-
-# libsecurity_asn1
-#####################################################################################
-_SecAsn1AllocCopy
-_SecAsn1AllocCopyItem
-_SecAsn1AllocItem
-_SecAsn1CoderCreate
-_SecAsn1CoderRelease
-_SecAsn1Decode
-_SecAsn1DecodeData
-_SecAsn1EncodeItem
-_SecAsn1Malloc
-_kSecAsn1AnyTemplate
-_kSecAsn1BMPStringTemplate
-_kSecAsn1BitStringTemplate
-_kSecAsn1BooleanTemplate
-_kSecAsn1EnumeratedTemplate
-_kSecAsn1GeneralizedTimeTemplate
-_kSecAsn1IA5StringTemplate
-_kSecAsn1IntegerTemplate
-_kSecAsn1NullTemplate
-_kSecAsn1ObjectIDTemplate
-_kSecAsn1OctetStringTemplate
-_kSecAsn1PointerToAnyTemplate
-_kSecAsn1PointerToBMPStringTemplate
-_kSecAsn1PointerToBitStringTemplate
-_kSecAsn1PointerToBooleanTemplate
-_kSecAsn1PointerToEnumeratedTemplate
-_kSecAsn1PointerToGeneralizedTimeTemplate
-_kSecAsn1PointerToIA5StringTemplate
-_kSecAsn1PointerToIntegerTemplate
-_kSecAsn1PointerToNullTemplate
-_kSecAsn1PointerToObjectIDTemplate
-_kSecAsn1PointerToOctetStringTemplate
-_kSecAsn1PointerToPrintableStringTemplate
-_kSecAsn1PointerToT61StringTemplate
-_kSecAsn1PointerToTeletexStringTemplate
-_kSecAsn1PointerToUTCTimeTemplate
-_kSecAsn1PointerToUTF8StringTemplate
-_kSecAsn1PointerToUniversalStringTemplate
-_kSecAsn1PointerToVisibleStringTemplate
-_kSecAsn1PrintableStringTemplate
-_kSecAsn1SequenceOfAnyTemplate
-_kSecAsn1SequenceOfBMPStringTemplate
-_kSecAsn1SequenceOfBitStringTemplate
-_kSecAsn1SequenceOfBooleanTemplate
-_kSecAsn1SequenceOfEnumeratedTemplate
-_kSecAsn1SequenceOfGeneralizedTimeTemplate
-_kSecAsn1SequenceOfIA5StringTemplate
-_kSecAsn1SequenceOfIntegerTemplate
-_kSecAsn1SequenceOfNullTemplate
-_kSecAsn1SequenceOfObjectIDTemplate
-_kSecAsn1SequenceOfOctetStringTemplate
-_kSecAsn1SequenceOfPrintableStringTemplate
-_kSecAsn1SequenceOfT61StringTemplate
-_kSecAsn1SequenceOfTeletexStringTemplate
-_kSecAsn1SequenceOfUTCTimeTemplate
-_kSecAsn1SequenceOfUTF8StringTemplate
-_kSecAsn1SequenceOfUniversalStringTemplate
-_kSecAsn1SequenceOfVisibleStringTemplate
-_kSecAsn1SetOfAnyTemplate
-_kSecAsn1SetOfBMPStringTemplate
-_kSecAsn1SetOfBitStringTemplate
-_kSecAsn1SetOfBooleanTemplate
-_kSecAsn1SetOfEnumeratedTemplate
-_kSecAsn1SetOfGeneralizedTimeTemplate
-_kSecAsn1SetOfIA5StringTemplate
-_kSecAsn1SetOfIntegerTemplate
-_kSecAsn1SetOfNullTemplate
-_kSecAsn1SetOfObjectIDTemplate
-_kSecAsn1SetOfOctetStringTemplate
-_kSecAsn1SetOfPrintableStringTemplate
-_kSecAsn1SetOfT61StringTemplate
-_kSecAsn1SetOfTeletexStringTemplate
-_kSecAsn1SetOfUTCTimeTemplate
-_kSecAsn1SetOfUTF8StringTemplate
-_kSecAsn1SetOfUniversalStringTemplate
-_kSecAsn1SetOfVisibleStringTemplate
-_kSecAsn1SkipTemplate
-_kSecAsn1T61StringTemplate
-_kSecAsn1TeletexStringTemplate
-_kSecAsn1UTCTimeTemplate
-_kSecAsn1UTF8StringTemplate
-_kSecAsn1UniversalStringTemplate
-_kSecAsn1UnsignedIntegerTemplate
-_kSecAsn1VisibleStringTemplate
-_kSecAsn1CertExtensionTemplate
-_kSecAsn1RevokedCertTemplate
-_kSecAsn1SequenceOfCertExtensionTemplate
-_kSecAsn1SequenceOfRevokedCertTemplate
-_kSecAsn1SignedCertOrCRLTemplate
-_kSecAsn1SignedCertTemplate
-_kSecAsn1SignedCrlTemplate
-_kSecAsn1TBSCertificateTemplate
-_kSecAsn1TBSCrlTemplate
-_kSecAsn1ValidityTemplate
-_kSecAsn1AccessDescriptionTemplate
-_kSecAsn1AuthorityInfoAccessTemplate
-_kSecAsn1AuthorityKeyIdTemplate
-_kSecAsn1BasicConstraintsTemplate
-_kSecAsn1CRLDistributionPointsTemplate
-_kSecAsn1CertPoliciesTemplate
-_kSecAsn1DistPointFullNameTemplate
-_kSecAsn1DistPointRDNTemplate
-_kSecAsn1DistributionPointTemplate
-_kSecAsn1IssuingDistributionPointTemplate
-_kSecAsn1PolicyInformationTemplate
-_kSecAsn1PolicyQualifierTemplate
-_kSecAsn1CertRequestInfoTemplate
-_kSecAsn1CertRequestTemplate
-_kSecAsn1SignedCertRequestTemplate
-_kSecAsn1AlgorithmIDTemplate
-_kSecAsn1AttributeTemplate
-_kSecAsn1DHAlgorithmIdentifierX942Template
-_kSecAsn1DHDomainParamsX942Template
-_kSecAsn1DHParameterBlockTemplate
-_kSecAsn1DHParameterTemplate
-_kSecAsn1DHPrivateKeyPKCS8Template
-_kSecAsn1DHPrivateKeyTemplate
-_kSecAsn1DHPublicKeyX509Template
-_kSecAsn1DHValidationParamsTemplate
-_kSecAsn1DigestInfoTemplate
-_kSecAsn1EncryptedPrivateKeyInfoTemplate
-_kSecAsn1PrivateKeyInfoTemplate
-_kSecAsn1RSAPrivateKeyPKCS1Template
-_kSecAsn1RSAPublicKeyPKCS1Template
-_kSecAsn1SetOfAttributeTemplate
-_kSecAsn1SubjectPublicKeyInfoTemplate
-_kSecAsn1ATVTemplate
-_kSecAsn1GenNameOtherNameTemplate
-_kSecAsn1GeneralNameTemplate
-_kSecAsn1NameTemplate
-_kSecAsn1OtherNameTemplate
-_kSecAsn1RDNTemplate
-_SecAsn1TaggedTemplateChooser
-_kSecAsn1DSAAlgParamsTemplate
-_kSecAsn1DSAAlgParamsBSAFETemplate
-_kSecAsn1DSAAlgorithmIdX509Template
-_kSecAsn1DSAAlgorithmIdBSAFETemplate
-_kSecAsn1DSAPublicKeyX509Template
-_kSecAsn1DSAPublicKeyBSAFETemplate
-_kSecAsn1DSAPrivateKeyOpensslTemplate
-_kSecAsn1DSAPrivateKeyOctsTemplate
-_kSecAsn1DSAPrivateKeyBSAFETemplate
-_kSecAsn1DSAPrivateKeyPKCS8Template
-_kSecAsn1DSASignatureTemplate
-_kSecAsn1OCSPBasicResponseTemplate
-_kSecAsn1OCSPCertIDTemplate
-_kSecAsn1OCSPCertStatusGoodTemplate
-_kSecAsn1OCSPCertStatusRevokedTemplate
-_kSecAsn1OCSPCertStatusUnknownTemplate
-_kSecAsn1OCSPRequestTemplate
-_kSecAsn1OCSPResponderIDAsNameTemplate
-_kSecAsn1OCSPResponderIDAsKeyTemplate
-_kSecAsn1OCSPResponseBytesTemplate
-_kSecAsn1OCSPResponseDataTemplate
-_kSecAsn1OCSPResponseTemplate
-_kSecAsn1OCSPRevokedInfoTemplate
-_kSecAsn1OCSPSignatureTemplate
-_kSecAsn1OCSPSignedRequestTemplate
-_kSecAsn1OCSPSingleResponseTemplate
-_kSecAsn1OCSPTbsRequestTemplate
-_kSecAsn1OCSPDRequestTemplate
-_kSecAsn1OCSPDRequestsTemplate
-_kSecAsn1OCSPDReplyTemplate
-_kSecAsn1OCSPDRepliesTemplate
-_kSecAsn1SemanticsInformationTemplate
-_kSecAsn1QC_StatementTemplate
-_kSecAsn1QC_StatementsTemplate
-
-# libsecurity_authorization
-#####################################################################################
-_AuthorizationCopyInfo
-_AuthorizationCopyPrivilegedReference
-_AuthorizationCopyRights
-_AuthorizationCopyRightsAsync
-_AuthorizationCreate
-_AuthorizationCreateFromExternalForm
-_AuthorizationExecuteWithPrivileges
-_AuthorizationFree
-_AuthorizationFreeItemSet
-_AuthorizationMakeExternalForm
-_AuthorizationRightGet
-_AuthorizationRightRemove
-_AuthorizationRightSet
-_SessionCreate
-_SessionGetInfo
-_SessionSetDistinguishedUser
-_SessionGetDistinguishedUser
-_SessionSetUserPreferences
-
-# libsecurity_checkpw
-#####################################################################################
-_checkpw
-_checkpw_internal
-
-# libsecurity_cms
-#####################################################################################
-_CMSEncode
-_CMSEncodeContent
-_CMSEncoderAddSupportingCerts
-_CMSEncoderAddRecipients
-_CMSEncoderAddSigners
-_CMSEncoderCopySupportingCerts
-_CMSEncoderCopyRecipients
-_CMSEncoderCopySigners
-_CMSEncoderCreate
-_CMSEncoderCopyEncodedContent
-_CMSEncoderGetCmsMessage
-_CMSEncoderSetHasDetachedContent
-_CMSEncoderGetHasDetachedContent
-_CMSEncoderCopyEncapsulatedContentType
-_CMSEncoderGetEncoder
-_CMSEncoderGetTypeID
-_CMSEncoderSetEncapsulatedContentType
-_CMSEncoderSetEncapsulatedContentTypeOID
-_CMSEncoderSetEncoder
-_CMSEncoderAddSignedAttributes
-_CMSEncoderSetSigningTime
-_CMSEncoderSetCertificateChainMode
-_CMSEncoderGetCertificateChainMode
-_CMSEncoderUpdateContent
-_CMSDecoderCopyAllCerts
-_CMSDecoderCopyContent
-_CMSDecoderCopyDetachedContent
-_CMSDecoderCopySignerStatus
-_CMSDecoderCreate
-_CMSDecoderGetTypeID
-_CMSDecoderFinalizeMessage
-_CMSDecoderGetDecoder
-_CMSDecoderCopyEncapsulatedContentType
-_CMSDecoderIsContentEncrypted
-_CMSDecoderGetNumSigners
-_CMSDecoderSetDecoder
-_CMSDecoderSetDetachedContent
-_CMSDecoderUpdateMessage
-_CMSDecoderGetCmsMessage
-_CMSDecoderSetSearchKeychain
-_CMSDecoderCopySignerEmailAddress
-_CMSDecoderCopySignerCert
-_CmsMessageSetTSAContext
-_CMSDecoderCopySignerSigningTime
-_CMSDecoderCopySignerTimestamp
-_CMSDecoderCopySignerTimestampCertificates
-_CMSEncoderCopySignerTimestamp
-
-# libsecurity_codesigning
-#####################################################################################
-_SecCodeGetTypeID
-_SecCodeCopySelf
-_SecCodeCopyInternalRequirement
-_SecCodeGetStatus
-_SecCodeSetStatus
-_SecCodeCopyStaticCode
-_SecCodeCopyHost
-_SecCodeCopyGuestWithAttributes
-_SecCodeCreateWithPID
-_SecCodeCheckValidity
-_SecCodeCheckValidityWithErrors
-_SecCodeCopyPath
-_SecCodeCopyDesignatedRequirement
-_SecCodeCopySigningInformation
-_SecCodeMapMemory
-_SecCodeSetDetachedSignature
-_kSecCodeAttributeArchitecture
-_kSecCodeAttributeBundleVersion
-_kSecCodeAttributeSubarchitecture
-_SecStaticCodeGetTypeID
-_SecStaticCodeCreateWithPath
-_SecStaticCodeCreateWithPathAndAttributes
-_SecStaticCodeCheckValidity
-_SecStaticCodeCheckValidityWithErrors
-_SecRequirementGetTypeID
-_SecRequirementCreateWithData
-_SecRequirementCreateWithResource
-_SecRequirementCreateWithString
-_SecRequirementCreateWithStringAndErrors
-_SecRequirementCreateGroup
-_SecRequirementCopyData
-_SecRequirementCopyString
-_SecRequirementEvaluate
-_SecRequirementsCreateFromRequirements
-_SecRequirementsCopyRequirements
-_SecRequirementsCreateWithString
-_SecRequirementsCopyString
-_SecCodeSignerGetTypeID
-_SecCodeSignerCreate
-_SecCodeSignerAddSignature
-_SecCodeSignerAddSignatureWithErrors
-_SecHostCreateGuest
-_SecHostRemoveGuest
-_SecHostSetGuestStatus
-_SecHostSelectGuest
-_SecHostSelectedGuest
-_SecHostSetHostingPort
-_kSecCodeDirectoryFlagTable
-_kSecCodeSignerApplicationData
-_kSecCodeSignerDetached
-_kSecCodeSignerDigestAlgorithm
-_kSecCodeSignerDryRun
-_kSecCodeSignerEntitlements
-_kSecCodeSignerFlags
-_kSecCodeSignerIdentifier
-_kSecCodeSignerIdentifierPrefix
-_kSecCodeSignerIdentity
-_kSecCodeSignerPageSize
-_kSecCodeSignerRequirements
-_kSecCodeSignerResourceRules
-_kSecCodeSignerSDKRoot
-_kSecCodeSignerSigningTime
-_kSecCodeSignerRequireTimestamp
-_kSecCodeSignerTimestampServer
-_kSecCodeSignerTimestampAuthentication
-_kSecCodeSignerTimestampOmitCertificates
-_kSecCodeSignerTSAClientAuth
-_kSecCodeSignerTSAUse
-_kSecCodeSignerTSAURL
-_kSecCodeSignerTSANoCerts
-_kSecCodeInfoCertificates
-_kSecCodeInfoChangedFiles
-_kSecCodeInfoCMS
-_kSecCodeInfoTime
-_kSecCodeInfoTimestamp
-_kSecCodeInfoDesignatedRequirement
-_kSecCodeInfoEntitlements
-_kSecCodeInfoEntitlementsDict
-_kSecCodeInfoFormat
-_kSecCodeInfoDigestAlgorithm
-_kSecCodeInfoIdentifier
-_kSecCodeInfoImplicitDesignatedRequirement
-_kSecCodeInfoMainExecutable
-_kSecCodeInfoPList
-_kSecCodeInfoRequirements
-_kSecCodeInfoRequirementData
-_kSecCodeInfoSource
-_kSecCodeInfoStatus
-_kSecCodeInfoTrust
-_kSecCodeInfoUnique
-_kSecCodeInfoCodeDirectory
-_kSecCodeInfoCodeOffset
-_kSecCodeInfoResourceDirectory
-_kSecGuestAttributeCanonical
-_kSecGuestAttributeHash
-_kSecGuestAttributeMachPort
-_kSecGuestAttributePid
-_kSecRequirementKeyInfoPlist
-_kSecRequirementKeyEntitlements
-_kSecRequirementKeyIdentifier
-_kSecCFErrorArchitecture
-_kSecCFErrorPath
-_kSecCFErrorPattern
-_kSecCFErrorResourceSeal
-_kSecCFErrorResourceAdded
-_kSecCFErrorResourceAltered
-_kSecCFErrorResourceMissing
-_kSecCFErrorInfoPlist
-_kSecCFErrorGuestAttributes
-_kSecCFErrorRequirementSyntax
-
-_SecTaskGetTypeID
-_SecTaskCreateWithAuditToken
-_SecTaskCreateFromSelf
-_SecTaskCopyValueForEntitlement
-_SecTaskCopyValuesForEntitlements
-
-_SecAssessmentCreate
-_SecAssessmentCopyResult
-_SecAssessmentUpdate
-_SecAssessmentCopyUpdate
-_SecAssessmentControl
-_kSecAssessmentContextKeyOperation
-_kSecAssessmentOperationTypeExecute
-_kSecAssessmentOperationTypeInstall
-_kSecAssessmentOperationTypeOpenDocument
-_kSecAssessmentContextKeyUpdate
-_kSecAssessmentContextKeyCertificates
-_kSecAssessmentUpdateOperationAdd
-_kSecAssessmentUpdateOperationRemove
-_kSecAssessmentUpdateOperationEnable
-_kSecAssessmentUpdateOperationDisable
-_kSecAssessmentUpdateOperationFind
-_kSecAssessmentUpdateKeyAuthorization
-_kSecAssessmentUpdateKeyAllow
-_kSecAssessmentUpdateKeyExpires
-_kSecAssessmentUpdateKeyLabel
-_kSecAssessmentUpdateKeyPriority
-_kSecAssessmentUpdateKeyRemarks
-_kSecAssessmentUpdateKeyRow
-_kSecAssessmentUpdateKeyCount
-_kSecAssessmentUpdateKeyFound
-_kSecAssessmentAssessmentAuthority
-_kSecAssessmentAssessmentAuthorityOverride
-_kSecAssessmentAssessmentAuthorityRow
-_kSecAssessmentAssessmentFromCache
-_kSecAssessmentAssessmentOriginator
-_kSecAssessmentAssessmentSource
-_kSecAssessmentAssessmentVerdict
-_kSecAssessmentRuleKeyID
-_kSecAssessmentRuleKeyPriority
-_kSecAssessmentRuleKeyAllow
-_kSecAssessmentRuleKeyLabel
-_kSecAssessmentRuleKeyRemarks
-_kSecAssessmentRuleKeyRequirement
-_kSecAssessmentRuleKeyType
-_kSecAssessmentRuleKeyExpires
-_kSecAssessmentRuleKeyDisabled
-_kSecAssessmentRuleKeyBookmark
-
-# libsecurity_cssm
-#####################################################################################
-_CSSMOID_ANSI_DH_EPHEM
-_CSSMOID_ANSI_DH_EPHEM_SHA1
-_CSSMOID_ANSI_DH_HYBRID1
-_CSSMOID_ANSI_DH_HYBRID1_SHA1
-_CSSMOID_ANSI_DH_HYBRID2
-_CSSMOID_ANSI_DH_HYBRID2_SHA1
-_CSSMOID_ANSI_DH_HYBRID_ONEFLOW
-_CSSMOID_ANSI_DH_ONE_FLOW
-_CSSMOID_ANSI_DH_ONE_FLOW_SHA1
-_CSSMOID_ANSI_DH_PUB_NUMBER
-_CSSMOID_ANSI_DH_STATIC
-_CSSMOID_ANSI_DH_STATIC_SHA1
-_CSSMOID_ANSI_MQV1
-_CSSMOID_ANSI_MQV1_SHA1
-_CSSMOID_ANSI_MQV2
-_CSSMOID_ANSI_MQV2_SHA1
-_CSSMOID_APPLE_ASC
-_CSSMOID_APPLE_ECDSA
-_CSSMOID_APPLE_FEE
-_CSSMOID_APPLE_FEED
-_CSSMOID_APPLE_FEEDEXP
-_CSSMOID_APPLE_FEE_MD5
-_CSSMOID_APPLE_FEE_SHA1
-_CSSMOID_APPLE_ISIGN
-_CSSMOID_APPLE_TP_CSR_GEN
-_CSSMOID_APPLE_TP_EAP
-_CSSMOID_APPLE_TP_CODE_SIGN
-_CSSMOID_APPLE_TP_SW_UPDATE_SIGNING
-_CSSMOID_APPLE_TP_IP_SEC
-_CSSMOID_APPLE_TP_LOCAL_CERT_GEN
-_CSSMOID_APPLE_TP_REVOCATION_CRL
-_CSSMOID_APPLE_TP_REVOCATION_OCSP
-_CSSMOID_APPLE_TP_SMIME
-_CSSMOID_APPLE_TP_SSL
-_CSSMOID_APPLE_TP_ICHAT
-_CSSMOID_APPLE_TP_RESOURCE_SIGN
-_CSSMOID_APPLE_TP_PKINIT_CLIENT
-_CSSMOID_APPLE_TP_PKINIT_SERVER
-_CSSMOID_APPLE_TP_CODE_SIGNING
-_CSSMOID_APPLE_TP_PACKAGE_SIGNING
-_CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT
-_CSSMOID_APPLE_TP_APPLEID_SHARING
-_CSSMOID_APPLE_TP_TIMESTAMPING
-_CSSMOID_APPLE_X509_BASIC
-_CSSMOID_AliasedEntryName
-_CSSMOID_AuthorityKeyIdentifier
-_CSSMOID_AuthorityRevocationList
-_CSSMOID_BasicConstraints
-_CSSMOID_BusinessCategory
-_CSSMOID_CACertificate
-_CSSMOID_CSSMKeyStruct
-_CSSMOID_CertIssuer
-_CSSMOID_CertificatePolicies
-_CSSMOID_CertificateRevocationList
-_CSSMOID_ChallengePassword
-_CSSMOID_ClientAuth
-_CSSMOID_CollectiveFacsimileTelephoneNumber
-_CSSMOID_CollectiveInternationalISDNNumber
-_CSSMOID_CollectiveOrganizationName
-_CSSMOID_CollectiveOrganizationalUnitName
-_CSSMOID_CollectivePhysicalDeliveryOfficeName
-_CSSMOID_CollectivePostOfficeBox
-_CSSMOID_CollectivePostalAddress
-_CSSMOID_CollectivePostalCode
-_CSSMOID_CollectiveStateProvinceName
-_CSSMOID_CollectiveStreetAddress
-_CSSMOID_CollectiveTelephoneNumber
-_CSSMOID_CollectiveTelexNumber
-_CSSMOID_CollectiveTelexTerminalIdentifier
-_CSSMOID_CommonName
-_CSSMOID_ContentType
-_CSSMOID_CounterSignature
-_CSSMOID_CountryName
-_CSSMOID_CrlDistributionPoints
-_CSSMOID_CrlNumber
-_CSSMOID_CrlReason
-_CSSMOID_CrossCertificatePair
-_CSSMOID_DH
-_CSSMOID_DNQualifier
-_CSSMOID_DSA
-_CSSMOID_DSA_CMS
-_CSSMOID_DSA_JDK
-_CSSMOID_DeltaCrlIndicator
-_CSSMOID_Description
-_CSSMOID_DestinationIndicator
-_CSSMOID_DistinguishedName
-_CSSMOID_EmailAddress
-_CSSMOID_EmailProtection
-_CSSMOID_EnhancedSearchGuide
-_CSSMOID_ExtendedCertificateAttributes
-_CSSMOID_ExtendedKeyUsage
-_CSSMOID_AuthorityInfoAccess
-_CSSMOID_BiometricInfo
-_CSSMOID_QC_Statements
-_CSSMOID_SubjectInfoAccess
-_CSSMOID_ExtendedKeyUsageAny
-_CSSMOID_ExtendedUseCodeSigning
-_CSSMOID_FacsimileTelephoneNumber
-_CSSMOID_GenerationQualifier
-_CSSMOID_GivenName
-_CSSMOID_HoldInstructionCode
-_CSSMOID_HouseIdentifier
-_CSSMOID_Initials
-_CSSMOID_InternationalISDNNumber
-_CSSMOID_InvalidityDate
-_CSSMOID_IssuerAltName
-_CSSMOID_IssuingDistributionPoint
-_CSSMOID_IssuingDistributionPoints
-_CSSMOID_KeyUsage
-_CSSMOID_KnowledgeInformation
-_CSSMOID_LocalityName
-_CSSMOID_MD2
-_CSSMOID_MD2WithRSA
-_CSSMOID_MD4
-_CSSMOID_MD4WithRSA
-_CSSMOID_MD5
-_CSSMOID_MD5WithRSA
-_CSSMOID_Member
-_CSSMOID_MessageDigest
-_CSSMOID_Name
-_CSSMOID_NameConstraints
-_CSSMOID_NetscapeCertType
-_CSSMOID_NetscapeCertSequence
-_CSSMOID_NetscapeSGC
-_CSSMOID_MicrosoftSGC
-_CSSMOID_OCSPSigning
-_CSSMOID_KERBv5_PKINIT_KP_CLIENT_AUTH
-_CSSMOID_KERBv5_PKINIT_KP_KDC
-_CSSMOID_EKU_IPSec
-_CSSMOID_ObjectClass
-_CSSMOID_OrganizationName
-_CSSMOID_OrganizationalUnitName
-_CSSMOID_Owner
-_CSSMOID_PKCS12_certBag
-_CSSMOID_PKCS12_crlBag
-_CSSMOID_PKCS12_keyBag
-_CSSMOID_PKCS12_pbeWithSHAAnd128BitRC2CBC
-_CSSMOID_PKCS12_pbeWithSHAAnd128BitRC4
-_CSSMOID_PKCS12_pbeWithSHAAnd2Key3DESCBC
-_CSSMOID_PKCS12_pbeWithSHAAnd3Key3DESCBC
-_CSSMOID_PKCS12_pbeWithSHAAnd40BitRC4
-_CSSMOID_PKCS12_pbewithSHAAnd40BitRC2CBC
-_CSSMOID_PKCS12_safeContentsBag
-_CSSMOID_PKCS12_secretBag
-_CSSMOID_PKCS12_shroudedKeyBag
-_CSSMOID_KERBv5_PKINIT_AUTH_DATA
-_CSSMOID_KERBv5_PKINIT_DH_KEY_DATA
-_CSSMOID_KERBv5_PKINIT_RKEY_DATA
-_CSSMOID_PKCS3
-_CSSMOID_PKCS7_Data
-_CSSMOID_PKCS7_DataWithAttributes
-_CSSMOID_PKCS7_DigestedData
-_CSSMOID_PKCS7_EncryptedData
-_CSSMOID_PKCS7_EncryptedPrivateKeyInfo
-_CSSMOID_PKCS7_EnvelopedData
-_CSSMOID_PKCS7_SignedAndEnvelopedData
-_CSSMOID_PKCS7_SignedData
-_CSSMOID_PKCS9_CertTypes
-_CSSMOID_PKCS9_CrlTypes
-_CSSMOID_PKCS9_FriendlyName
-_CSSMOID_PKCS9_LocalKeyId
-_CSSMOID_PKCS9_SdsiCertificate
-_CSSMOID_PKCS9_X509Certificate
-_CSSMOID_PKCS9_X509Crl
-_CSSMOID_PKCS9_Id_Ct_TSTInfo
-_CSSMOID_PKCS9_TimeStampToken
-_CSSMOID_PKCS5_DIGEST_ALG
-_CSSMOID_PKCS5_ENCRYPT_ALG
-_CSSMOID_PKCS5_HMAC_SHA1
-_CSSMOID_PKCS5_pbeWithMD2AndDES
-_CSSMOID_PKCS5_pbeWithMD5AndDES
-_CSSMOID_PKCS5_pbeWithMD2AndRC2
-_CSSMOID_PKCS5_pbeWithMD5AndRC2
-_CSSMOID_PKCS5_pbeWithSHA1AndDES
-_CSSMOID_PKCS5_pbeWithSHA1AndRC2
-_CSSMOID_PKCS5_PBKDF2
-_CSSMOID_PKCS5_PBES2
-_CSSMOID_PKCS5_PBMAC1
-_CSSMOID_PKCS5_RC2_CBC
-_CSSMOID_PKCS5_DES_EDE3_CBC
-_CSSMOID_PKCS5_RC5_CBC
-_CSSMOID_PhysicalDeliveryOfficeName
-_CSSMOID_PolicyConstraints
-_CSSMOID_PolicyMappings
-_CSSMOID_PostOfficeBox
-_CSSMOID_PostalAddress
-_CSSMOID_PostalCode
-_CSSMOID_PreferredDeliveryMethod
-_CSSMOID_PresentationAddress
-_CSSMOID_PrivateKeyUsagePeriod
-_CSSMOID_ProtocolInformation
-_CSSMOID_QT_CPS
-_CSSMOID_QT_UNOTICE
-_CSSMOID_AD_OCSP
-_CSSMOID_AD_CA_ISSUERS
-_CSSMOID_AD_TIME_STAMPING
-_CSSMOID_AD_CA_REPOSITORY
-_CSSMOID_PDA_DATE_OF_BIRTH
-_CSSMOID_PDA_PLACE_OF_BIRTH
-_CSSMOID_PDA_GENDER
-_CSSMOID_PDA_COUNTRY_CITIZEN
-_CSSMOID_PDA_COUNTRY_RESIDENCE
-_CSSMOID_OID_QCS_SYNTAX_V1
-_CSSMOID_OID_QCS_SYNTAX_V2
-_CSSMOID_ETSI_QCS_QC_COMPLIANCE
-_CSSMOID_ETSI_QCS_QC_LIMIT_VALUE
-_CSSMOID_ETSI_QCS_QC_RETENTION
-_CSSMOID_ETSI_QCS_QC_SSCD
-_CSSMOID_RSA
-_CSSMOID_RegisteredAddress
-_CSSMOID_RoleOccupant
-_CSSMOID_SHA1
-_CSSMOID_SHA224
-_CSSMOID_SHA256
-_CSSMOID_SHA384
-_CSSMOID_SHA512
-_CSSMOID_SHA1WithDSA
-_CSSMOID_SHA1WithDSA_CMS
-_CSSMOID_SHA1WithDSA_JDK
-_CSSMOID_SHA1WithRSA
-_CSSMOID_SHA224WithRSA
-_CSSMOID_SHA256WithRSA
-_CSSMOID_SHA384WithRSA
-_CSSMOID_SHA512WithRSA
-_CSSMOID_SHA1WithRSA_OIW
-_CSSMOID_RSAWithOAEP
-_CSSMOID_OAEP_MGF1
-_CSSMOID_OAEP_ID_PSPECIFIED
-_CSSMOID_SearchGuide
-_CSSMOID_SeeAlso
-_CSSMOID_SerialNumber
-_CSSMOID_ServerAuth
-_CSSMOID_SigningTime
-_CSSMOID_StateProvinceName
-_CSSMOID_StreetAddress
-_CSSMOID_SubjectAltName
-_CSSMOID_SubjectDirectoryAttributes
-_CSSMOID_SubjectEmailAddress
-_CSSMOID_SubjectKeyIdentifier
-_CSSMOID_SubjectPicture
-_CSSMOID_SubjectSignatureBitmap
-_CSSMOID_SupportedApplicationContext
-_CSSMOID_Surname
-_CSSMOID_TelephoneNumber
-_CSSMOID_TelexNumber
-_CSSMOID_TelexTerminalIdentifier
-_CSSMOID_TimeStamping
-_CSSMOID_Title
-_CSSMOID_UniqueIdentifier
-_CSSMOID_UniqueMember
-_CSSMOID_UnstructuredAddress
-_CSSMOID_UnstructuredName
-_CSSMOID_UseExemptions
-_CSSMOID_UserCertificate
-_CSSMOID_UserID
-_CSSMOID_UserPassword
-_CSSMOID_X509V1CRLIssuerNameCStruct
-_CSSMOID_X509V1CRLIssuerNameLDAP
-_CSSMOID_X509V1CRLIssuerStruct
-_CSSMOID_X509V1CRLNextUpdate
-_CSSMOID_X509V1CRLNumberOfRevokedCertEntries
-_CSSMOID_X509V1CRLRevokedCertificatesCStruct
-_CSSMOID_X509V1CRLRevokedCertificatesStruct
-_CSSMOID_X509V1CRLRevokedEntryCStruct
-_CSSMOID_X509V1CRLRevokedEntryRevocationDate
-_CSSMOID_X509V1CRLRevokedEntrySerialNumber
-_CSSMOID_X509V1CRLRevokedEntryStruct
-_CSSMOID_X509V1CRLThisUpdate
-_CSSMOID_X509V1CertificateIssuerUniqueId
-_CSSMOID_X509V1CertificateSubjectUniqueId
-_CSSMOID_X509V1IssuerName
-_CSSMOID_X509V1IssuerNameCStruct
-_CSSMOID_X509V1IssuerNameLDAP
-_CSSMOID_X509V1IssuerNameStd
-_CSSMOID_X509V1SerialNumber
-_CSSMOID_X509V1Signature
-_CSSMOID_X509V1SignatureAlgorithm
-_CSSMOID_X509V1SignatureAlgorithmParameters
-_CSSMOID_X509V1SignatureAlgorithmTBS
-_CSSMOID_X509V1SignatureCStruct
-_CSSMOID_X509V1SignatureStruct
-_CSSMOID_X509V1SubjectName
-_CSSMOID_X509V1SubjectNameCStruct
-_CSSMOID_X509V1SubjectNameLDAP
-_CSSMOID_X509V1SubjectNameStd
-_CSSMOID_X509V1SubjectPublicKey
-_CSSMOID_X509V1SubjectPublicKeyAlgorithm
-_CSSMOID_X509V1SubjectPublicKeyAlgorithmParameters
-_CSSMOID_X509V1SubjectPublicKeyCStruct
-_CSSMOID_X509V1ValidityNotAfter
-_CSSMOID_X509V1ValidityNotBefore
-_CSSMOID_X509V1Version
-_CSSMOID_X509V2CRLAllExtensionsCStruct
-_CSSMOID_X509V2CRLAllExtensionsStruct
-_CSSMOID_X509V2CRLExtensionCritical
-_CSSMOID_X509V2CRLExtensionId
-_CSSMOID_X509V2CRLExtensionType
-_CSSMOID_X509V2CRLNumberOfExtensions
-_CSSMOID_X509V2CRLRevokedEntryAllExtensionsCStruct
-_CSSMOID_X509V2CRLRevokedEntryAllExtensionsStruct
-_CSSMOID_X509V2CRLRevokedEntryExtensionCritical
-_CSSMOID_X509V2CRLRevokedEntryExtensionId
-_CSSMOID_X509V2CRLRevokedEntryExtensionType
-_CSSMOID_X509V2CRLRevokedEntryExtensionValue
-_CSSMOID_X509V2CRLRevokedEntryNumberOfExtensions
-_CSSMOID_X509V2CRLRevokedEntrySingleExtensionCStruct
-_CSSMOID_X509V2CRLRevokedEntrySingleExtensionStruct
-_CSSMOID_X509V2CRLSignedCrlCStruct
-_CSSMOID_X509V2CRLSignedCrlStruct
-_CSSMOID_X509V2CRLSingleExtensionCStruct
-_CSSMOID_X509V2CRLSingleExtensionStruct
-_CSSMOID_X509V2CRLTbsCertListCStruct
-_CSSMOID_X509V2CRLTbsCertListStruct
-_CSSMOID_X509V2CRLVersion
-_CSSMOID_X509V3Certificate
-_CSSMOID_X509V3CertificateCStruct
-_CSSMOID_X509V3CertificateExtensionCStruct
-_CSSMOID_X509V3CertificateExtensionCritical
-_CSSMOID_X509V3CertificateExtensionId
-_CSSMOID_X509V3CertificateExtensionStruct
-_CSSMOID_X509V3CertificateExtensionType
-_CSSMOID_X509V3CertificateExtensionValue
-_CSSMOID_X509V3CertificateExtensionsCStruct
-_CSSMOID_X509V3CertificateExtensionsStruct
-_CSSMOID_X509V3CertificateNumberOfExtensions
-_CSSMOID_X509V3SignedCertificate
-_CSSMOID_X509V3SignedCertificateCStruct
-_CSSMOID_X_121Address
-_CSSMOID_DOTMAC_CERT
-_CSSMOID_DOTMAC_CERT_REQ
-_CSSMOID_DOTMAC_CERT_REQ_IDENTITY
-_CSSMOID_DOTMAC_CERT_REQ_EMAIL_SIGN
-_CSSMOID_DOTMAC_CERT_REQ_EMAIL_ENCRYPT
-_CSSMOID_DOTMAC_CERT_REQ_ARCHIVE_LIST
-_CSSMOID_DOTMAC_CERT_REQ_ARCHIVE_STORE
-_CSSMOID_DOTMAC_CERT_REQ_ARCHIVE_FETCH
-_CSSMOID_DOTMAC_CERT_REQ_ARCHIVE_REMOVE
-_CSSMOID_DOTMAC_CERT_REQ_SHARED_SERVICES
-_CSSMOID_DOTMAC_CERT_REQ_VALUE_USERNAME
-_CSSMOID_DOTMAC_CERT_REQ_VALUE_PASSWORD
-_CSSMOID_DOTMAC_CERT_REQ_VALUE_HOSTNAME
-_CSSMOID_DOTMAC_CERT_REQ_VALUE_RENEW
-_CSSMOID_DOTMAC_CERT_REQ_VALUE_ASYNC
-_CSSMOID_DOTMAC_CERT_REQ_VALUE_IS_PENDING
-_CSSMOID_DOTMAC_CERT_EXTENSION
-_CSSMOID_DOTMAC_CERT_IDENTITY
-_CSSMOID_DOTMAC_CERT_EMAIL_SIGN
-_CSSMOID_DOTMAC_CERT_EMAIL_ENCRYPT
-_CSSMOID_APPLE_CERT_POLICY
-_CSSMOID_DOTMAC_CERT_POLICY
-_CSSMOID_ADC_CERT_POLICY
-_CSSMOID_MACAPPSTORE_CERT_POLICY
-_CSSMOID_MACAPPSTORE_RECEIPT_CERT_POLICY
-_CSSMOID_APPLEID_CERT_POLICY
-_CSSMOID_APPLEID_SHARING_CERT_POLICY
-_CSSMOID_APPLE_EKU_CODE_SIGNING
-_CSSMOID_APPLE_EKU_CODE_SIGNING_DEV
-_CSSMOID_APPLE_EKU_RESOURCE_SIGNING
-_CSSMOID_APPLE_EKU_ICHAT_SIGNING
-_CSSMOID_APPLE_EKU_ICHAT_ENCRYPTION
-_CSSMOID_APPLE_EKU_SYSTEM_IDENTITY
-_CSSMOID_APPLE_EXTENSION
-_CSSMOID_APPLE_EXTENSION_CODE_SIGNING
-_CSSMOID_APPLE_EXTENSION_APPLE_SIGNING
-_CSSMOID_APPLE_EXTENSION_ADC_DEV_SIGNING
-_CSSMOID_APPLE_EXTENSION_ADC_APPLE_SIGNING
-_CSSMOID_APPLE_EXTENSION_MACAPPSTORE_RECEIPT
-_CSSMOID_APPLE_EXTENSION_INTERMEDIATE_MARKER
-_CSSMOID_APPLE_EXTENSION_WWDR_INTERMEDIATE
-_CSSMOID_APPLE_EXTENSION_ITMS_INTERMEDIATE
-_CSSMOID_APPLE_EXTENSION_AAI_INTERMEDIATE
-_CSSMOID_APPLE_EXTENSION_APPLEID_SHARING
-_CSSMOID_PKIX_OCSP
-_CSSMOID_PKIX_OCSP_ARCHIVE_CUTOFF
-_CSSMOID_PKIX_OCSP_BASIC
-_CSSMOID_PKIX_OCSP_CRL
-_CSSMOID_PKIX_OCSP_NOCHECK
-_CSSMOID_PKIX_OCSP_NONCE
-_CSSMOID_PKIX_OCSP_RESPONSE
-_CSSMOID_PKIX_OCSP_SERVICE_LOCATOR
-_CSSM_AC_AuthCompute
-_CSSM_AC_PassThrough
-_CSSM_CL_CertAbortCache
-_CSSM_CL_CertAbortQuery
-_CSSM_CL_CertCache
-_CSSM_CL_CertCreateTemplate
-_CSSM_CL_CertDescribeFormat
-_CSSM_CL_CertGetAllFields
-_CSSM_CL_CertGetAllTemplateFields
-_CSSM_CL_CertGetFirstCachedFieldValue
-_CSSM_CL_CertGetFirstFieldValue
-_CSSM_CL_CertGetKeyInfo
-_CSSM_CL_CertGetNextCachedFieldValue
-_CSSM_CL_CertGetNextFieldValue
-_CSSM_CL_CertGroupFromVerifiedBundle
-_CSSM_CL_CertGroupToSignedBundle
-_CSSM_CL_CertSign
-_CSSM_CL_CertVerify
-_CSSM_CL_CertVerifyWithKey
-_CSSM_CL_CrlAbortCache
-_CSSM_CL_CrlAbortQuery
-_CSSM_CL_CrlAddCert
-_CSSM_CL_CrlCache
-_CSSM_CL_CrlCreateTemplate
-_CSSM_CL_CrlDescribeFormat
-_CSSM_CL_CrlGetAllCachedRecordFields
-_CSSM_CL_CrlGetAllFields
-_CSSM_CL_CrlGetFirstCachedFieldValue
-_CSSM_CL_CrlGetFirstFieldValue
-_CSSM_CL_CrlGetNextCachedFieldValue
-_CSSM_CL_CrlGetNextFieldValue
-_CSSM_CL_CrlRemoveCert
-_CSSM_CL_CrlSetFields
-_CSSM_CL_CrlSign
-_CSSM_CL_CrlVerify
-_CSSM_CL_CrlVerifyWithKey
-_CSSM_CL_FreeFieldValue
-_CSSM_CL_FreeFields
-_CSSM_CL_IsCertInCachedCrl
-_CSSM_CL_IsCertInCrl
-_CSSM_CL_PassThrough
-_CSSM_CSP_ChangeLoginAcl
-_CSSM_CSP_ChangeLoginOwner
-_CSSM_CSP_CreateAsymmetricContext
-_CSSM_CSP_CreateDeriveKeyContext
-_CSSM_CSP_CreateDigestContext
-_CSSM_CSP_CreateKeyGenContext
-_CSSM_CSP_CreateMacContext
-_CSSM_CSP_CreatePassThroughContext
-_CSSM_CSP_CreateRandomGenContext
-_CSSM_CSP_CreateSignatureContext
-_CSSM_CSP_CreateSymmetricContext
-_CSSM_CSP_GetLoginAcl
-_CSSM_CSP_GetLoginOwner
-_CSSM_CSP_GetOperationalStatistics
-_CSSM_CSP_Login
-_CSSM_CSP_Logout
-_CSSM_CSP_ObtainPrivateKeyFromPublicKey
-_CSSM_CSP_PassThrough
-_CSSM_ChangeKeyAcl
-_CSSM_ChangeKeyOwner
-_CSSM_DL_Authenticate
-_CSSM_DL_ChangeDbAcl
-_CSSM_DL_ChangeDbOwner
-_CSSM_DL_CreateRelation
-_CSSM_DL_DataAbortQuery
-_CSSM_DL_DataDelete
-_CSSM_DL_DataGetFirst
-_CSSM_DL_DataGetFromUniqueRecordId
-_CSSM_DL_DataGetNext
-_CSSM_DL_DataInsert
-_CSSM_DL_DataModify
-_CSSM_DL_DbClose
-_CSSM_DL_DbCreate
-_CSSM_DL_DbDelete
-_CSSM_DL_DbOpen
-_CSSM_DL_DestroyRelation
-_CSSM_DL_FreeNameList
-_CSSM_DL_FreeUniqueRecord
-_CSSM_DL_GetDbAcl
-_CSSM_DL_GetDbNameFromHandle
-_CSSM_DL_GetDbNames
-_CSSM_DL_GetDbOwner
-_CSSM_DL_PassThrough
-_CSSM_DecryptData
-_CSSM_DecryptDataFinal
-_CSSM_DecryptDataInit
-_CSSM_DecryptDataInitP
-_CSSM_DecryptDataP
-_CSSM_DecryptDataUpdate
-_CSSM_DeleteContext
-_CSSM_DeleteContextAttributes
-_CSSM_DeriveKey
-_CSSM_DigestData
-_CSSM_DigestDataClone
-_CSSM_DigestDataFinal
-_CSSM_DigestDataInit
-_CSSM_DigestDataUpdate
-_CSSM_EncryptData
-_CSSM_EncryptDataFinal
-_CSSM_EncryptDataInit
-_CSSM_EncryptDataInitP
-_CSSM_EncryptDataP
-_CSSM_EncryptDataUpdate
-_CSSM_FreeContext
-_CSSM_FreeKey
-_CSSM_GenerateAlgorithmParams
-_CSSM_GenerateKey
-_CSSM_GenerateKeyP
-_CSSM_GenerateKeyPair
-_CSSM_GenerateKeyPairP
-_CSSM_GenerateMac
-_CSSM_GenerateMacFinal
-_CSSM_GenerateMacInit
-_CSSM_GenerateMacUpdate
-_CSSM_GenerateRandom
-_CSSM_GetAPIMemoryFunctions
-_CSSM_GetContext
-_CSSM_GetContextAttribute
-_CSSM_GetKeyAcl
-_CSSM_GetKeyOwner
-_CSSM_GetModuleGUIDFromHandle
-_CSSM_GetPrivilege
-_CSSM_GetSubserviceUIDFromHandle
-_CSSM_GetTimeValue
-_CSSM_Init
-_CSSM_Introduce
-_CSSM_ListAttachedModuleManagers
-_CSSM_ModuleAttach
-_CSSM_ModuleDetach
-_CSSM_ModuleLoad
-_CSSM_ModuleUnload
-_CSSM_QueryKeySizeInBits
-_CSSM_QuerySize
-_CSSM_RetrieveCounter
-_CSSM_RetrieveUniqueId
-_CSSM_SetContext
-_CSSM_SetPrivilege
-_CSSM_SignData
-_CSSM_SignDataFinal
-_CSSM_SignDataInit
-_CSSM_SignDataUpdate
-_CSSM_TP_ApplyCrlToDb
-_CSSM_TP_CertCreateTemplate
-_CSSM_TP_CertGetAllTemplateFields
-_CSSM_TP_CertGroupConstruct
-_CSSM_TP_CertGroupPrune
-_CSSM_TP_CertGroupToTupleGroup
-_CSSM_TP_CertGroupVerify
-_CSSM_TP_CertReclaimAbort
-_CSSM_TP_CertReclaimKey
-_CSSM_TP_CertRemoveFromCrlTemplate
-_CSSM_TP_CertRevoke
-_CSSM_TP_CertSign
-_CSSM_TP_ConfirmCredResult
-_CSSM_TP_CrlCreateTemplate
-_CSSM_TP_CrlSign
-_CSSM_TP_CrlVerify
-_CSSM_TP_FormRequest
-_CSSM_TP_FormSubmit
-_CSSM_TP_PassThrough
-_CSSM_TP_ReceiveConfirmation
-_CSSM_TP_RetrieveCredResult
-_CSSM_TP_SubmitCredRequest
-_CSSM_TP_TupleGroupToCertGroup
-_CSSM_Terminate
-_CSSM_Unintroduce
-_CSSM_UnwrapKey
-_CSSM_UnwrapKeyP
-_CSSM_UpdateContextAttributes
-_CSSM_VerifyData
-_CSSM_VerifyDataFinal
-_CSSM_VerifyDataInit
-_CSSM_VerifyDataUpdate
-_CSSM_VerifyDevice
-_CSSM_VerifyMac
-_CSSM_VerifyMacFinal
-_CSSM_VerifyMacInit
-_CSSM_VerifyMacUpdate
-_CSSM_WrapKey
-_CSSM_WrapKeyP
-_cssmAlgToOid
-_cssmOidToAlg
-_gGuidAppleCSP
-_gGuidAppleCSPDL
-_gGuidAppleFileDL
-_gGuidAppleX509CL
-_gGuidAppleX509TP
-_gGuidAppleDotMacTP
-_gGuidAppleSdCSPDL
-_gGuidCssm
-_gGuidAppleLDAPDL
-_gGuidAppleDotMacDL
-_CSSMOID_X9_62
-_CSSMOID_X9_62_FieldType
-_CSSMOID_X9_62_PubKeyType
-_CSSMOID_X9_62_EllCurve
-_CSSMOID_X9_62_C_TwoCurve
-_CSSMOID_X9_62_PrimeCurve
-_CSSMOID_X9_62_SigType
-_CSSMOID_secp192r1
-_CSSMOID_secp256r1
-_CSSMOID_Certicom
-_CSSMOID_CerticomEllCurve
-_CSSMOID_secp112r1
-_CSSMOID_secp112r2
-_CSSMOID_secp128r1
-_CSSMOID_secp128r2
-_CSSMOID_secp160k1
-_CSSMOID_secp160r1
-_CSSMOID_secp160r2
-_CSSMOID_secp192k1
-_CSSMOID_secp224k1
-_CSSMOID_secp224r1
-_CSSMOID_secp256k1
-_CSSMOID_secp384r1
-_CSSMOID_secp521r1
-_CSSMOID_sect113r1
-_CSSMOID_sect113r2
-_CSSMOID_sect131r1
-_CSSMOID_sect131r2
-_CSSMOID_sect163k1
-_CSSMOID_sect163r1
-_CSSMOID_sect163r2
-_CSSMOID_sect193r1
-_CSSMOID_sect193r2
-_CSSMOID_sect233k1
-_CSSMOID_sect233r1
-_CSSMOID_sect239k1
-_CSSMOID_sect283k1
-_CSSMOID_sect283r1
-_CSSMOID_sect409k1
-_CSSMOID_sect409r1
-_CSSMOID_sect571k1
-_CSSMOID_sect571r1
-_CSSMOID_ecPublicKey
-_CSSMOID_ECDSA_WithSHA1
-_CSSMOID_ECDSA_WithSHA224
-_CSSMOID_ECDSA_WithSHA256
-_CSSMOID_ECDSA_WithSHA384
-_CSSMOID_ECDSA_WithSHA512
-_CSSMOID_ECDSA_WithSpecified
-
-# libsecurity_keychain
-#####################################################################################
-_cssmErrorString
-_cssmPerror
-_kSecACLAuthorizationAny
-_kSecACLAuthorizationLogin
-_kSecACLAuthorizationGenKey
-_kSecACLAuthorizationDelete
-_kSecACLAuthorizationExportWrapped
-_kSecACLAuthorizationExportClear
-_kSecACLAuthorizationImportWrapped
-_kSecACLAuthorizationImportClear
-_kSecACLAuthorizationSign
-_kSecACLAuthorizationEncrypt
-_kSecACLAuthorizationDecrypt
-_kSecACLAuthorizationMAC
-_kSecACLAuthorizationDerive
-_kSecACLAuthorizationKeychainCreate
-_kSecACLAuthorizationKeychainDelete
-_kSecACLAuthorizationKeychainItemRead
-_kSecACLAuthorizationKeychainItemInsert
-_kSecACLAuthorizationKeychainItemModify
-_kSecACLAuthorizationKeychainItemDelete
-_kSecIdentityDomainDefault
-_kSecIdentityDomainKerberosKDC
-_kSecClass
-_kSecClassGenericPassword
-_kSecClassInternetPassword
-_kSecClassAppleSharePassword
-_kSecClassCertificate
-_kSecClassKey
-_kSecClassIdentity
-_kSecAttrAccess
-_kSecAttrCreationDate
-_kSecAttrModificationDate
-_kSecAttrDescription
-_kSecAttrComment
-_kSecAttrCreator
-_kSecAttrType
-_kSecAttrLabel
-_kSecAttrIsInvisible
-_kSecAttrIsNegative
-_kSecAttrAccount
-_kSecAttrService
-_kSecAttrGeneric
-_kSecAttrSecurityDomain
-_kSecAttrServer
-_kSecAttrProtocol
-_kSecAttrAuthenticationType
-_kSecAttrPort
-_kSecAttrPath
-_kSecAttrVolume
-_kSecAttrAddress
-_kSecAttrAFPServerSignature
-_kSecAttrAlias
-_kSecAttrSubject
-_kSecAttrIssuer
-_kSecAttrSerialNumber
-_kSecAttrSubjectKeyID
-_kSecAttrPublicKeyHash
-_kSecAttrCertificateType
-_kSecAttrCertificateEncoding
-_kSecAttrKeyClass
-_kSecAttrApplicationLabel
-_kSecAttrIsPermanent
-_kSecAttrIsPrivate
-_kSecAttrIsModifiable
-_kSecAttrApplicationTag
-_kSecAttrKeyCreator
-_kSecAttrKeyType
-_kSecAttrKeySizeInBits
-_kSecAttrEffectiveKeySize
-_kSecAttrStartDate
-_kSecAttrEndDate
-_kSecAttrIsSensitive
-_kSecAttrWasAlwaysSensitive
-_kSecAttrIsExtractable
-_kSecAttrWasNeverExtractable
-_kSecAttrCanEncrypt
-_kSecAttrCanDecrypt
-_kSecAttrCanDerive
-_kSecAttrCanSign
-_kSecAttrCanVerify
-_kSecAttrCanSignRecover
-_kSecAttrCanVerifyRecover
-_kSecAttrCanWrap
-_kSecAttrCanUnwrap
-_kSecAttrScriptCode
-_kSecAttrHasCustomIcon
-_kSecAttrCRLType
-_kSecAttrCRLEncoding
-_kSecAttrAccessGroup
-_kSecAttrSynchronizable
-_kSecMatchPolicy
-_kSecMatchItemList
-_kSecMatchSearchList
-_kSecMatchIssuers
-_kSecMatchEmailAddressIfPresent
-_kSecMatchSubjectContains
-_kSecMatchSubjectStartsWith
-_kSecMatchSubjectEndsWith
-_kSecMatchSubjectWholeString
-_kSecMatchCaseInsensitive
-_kSecMatchDiacriticInsensitive
-_kSecMatchWidthInsensitive
-_kSecMatchTrustedOnly
-_kSecMatchValidOnDate
-_kSecMatchLimit
-_kSecMatchLimitOne
-_kSecMatchLimitAll
-_kSecReturnData
-_kSecReturnAttributes
-_kSecReturnRef
-_kSecReturnPersistentRef
-_kSecValueData
-_kSecValueRef
-_kSecValuePersistentRef
-_kSecUseItemList
-_kSecUseKeychain
-_kSecAttrProtocolFTP
-_kSecAttrProtocolFTPAccount
-_kSecAttrProtocolHTTP
-_kSecAttrProtocolIRC
-_kSecAttrProtocolNNTP
-_kSecAttrProtocolPOP3
-_kSecAttrProtocolSMTP
-_kSecAttrProtocolSOCKS
-_kSecAttrProtocolIMAP
-_kSecAttrProtocolLDAP
-_kSecAttrProtocolAppleTalk
-_kSecAttrProtocolAFP
-_kSecAttrProtocolTelnet
-_kSecAttrProtocolSSH
-_kSecAttrProtocolFTPS
-_kSecAttrProtocolHTTPS
-_kSecAttrProtocolHTTPProxy
-_kSecAttrProtocolHTTPSProxy
-_kSecAttrProtocolFTPProxy
-_kSecAttrProtocolSMB
-_kSecAttrProtocolRTSP
-_kSecAttrProtocolRTSPProxy
-_kSecAttrProtocolDAAP
-_kSecAttrProtocolEPPC
-_kSecAttrProtocolIPP
-_kSecAttrProtocolNNTPS
-_kSecAttrProtocolLDAPS
-_kSecAttrProtocolTelnetS
-_kSecAttrProtocolIMAPS
-_kSecAttrProtocolIRCS
-_kSecAttrProtocolPOP3S
-_kSecAttrAuthenticationTypeNTLM
-_kSecAttrAuthenticationTypeMSN
-_kSecAttrAuthenticationTypeDPA
-_kSecAttrAuthenticationTypeRPA
-_kSecAttrAuthenticationTypeHTTPBasic
-_kSecAttrAuthenticationTypeHTTPDigest
-_kSecAttrAuthenticationTypeHTMLForm
-_kSecAttrAuthenticationTypeDefault
-_kSecAttrKeyClassPublic
-_kSecAttrKeyClassPrivate
-_kSecAttrKeyClassSymmetric
-_kSecPrivateKeyAttrs
-_kSecPublicKeyAttrs
-_kSecImportExportPassphrase
-_kSecImportExportKeychain
-_kSecImportExportAccess
-_kSecImportItemLabel
-_kSecImportItemKeyID
-_kSecImportItemTrust
-_kSecImportItemCertChain
-_kSecImportItemIdentity
-_kSecPolicyAppleX509Basic
-_kSecPolicyAppleSSL
-_kSecPolicyAppleSMIME
-_kSecPolicyAppleEAP
-_kSecPolicyAppleIPsec
-_kSecPolicyAppleiChat
-_kSecPolicyApplePKINITClient
-_kSecPolicyApplePKINITServer
-_kSecPolicyAppleCodeSigning
-_kSecPolicyMacAppStoreReceipt
-_kSecPolicyAppleIDValidation
-_kSecPolicyAppleTimeStamping
-_kSecPolicyOid
-_kSecPolicyName
-_kSecPolicyClient
-_kSecPolicyKU_DigitalSignature
-_kSecPolicyKU_NonRepudiation
-_kSecPolicyKU_KeyEncipherment
-_kSecPolicyKU_DataEncipherment
-_kSecPolicyKU_KeyAgreement
-_kSecPolicyKU_KeyCertSign
-_kSecPolicyKU_CRLSign
-_kSecPolicyKU_EncipherOnly
-_kSecPolicyKU_DecipherOnly
-_kSecPropertyTypeTitle
-_kSecPropertyTypeError
-_kSecPropertyKeyType
-_kSecPropertyKeyLabel
-_kSecPropertyKeyLocalizedLabel
-_kSecPropertyKeyValue
-_kSecPropertyTypeWarning
-_kSecPropertyTypeSuccess
-_kSecPropertyTypeSection
-_kSecPropertyTypeData
-_kSecPropertyTypeString
-_kSecPropertyTypeURL
-_kSecPropertyTypeDate
-_kSecOIDADC_CERT_POLICY
-_kSecOIDAPPLE_CERT_POLICY
-_kSecOIDAPPLE_EKU_CODE_SIGNING
-_kSecOIDAPPLE_EKU_CODE_SIGNING_DEV
-_kSecOIDAPPLE_EKU_ICHAT_ENCRYPTION
-_kSecOIDAPPLE_EKU_ICHAT_SIGNING
-_kSecOIDAPPLE_EKU_RESOURCE_SIGNING
-_kSecOIDAPPLE_EKU_SYSTEM_IDENTITY
-_kSecOIDAPPLE_EXTENSION
-_kSecOIDAPPLE_EXTENSION_ADC_APPLE_SIGNING
-_kSecOIDAPPLE_EXTENSION_ADC_DEV_SIGNING
-_kSecOIDAPPLE_EXTENSION_APPLE_SIGNING
-_kSecOIDAPPLE_EXTENSION_CODE_SIGNING
-_kSecOIDAuthorityInfoAccess
-_kSecOIDAuthorityKeyIdentifier
-_kSecOIDBasicConstraints
-_kSecOIDBiometricInfo
-_kSecOIDCSSMKeyStruct
-_kSecOIDCertIssuer
-_kSecOIDCertificatePolicies
-_kSecOIDClientAuth
-_kSecOIDCollectiveStateProvinceName
-_kSecOIDCollectiveStreetAddress
-_kSecOIDCommonName
-_kSecOIDCountryName
-_kSecOIDCrlDistributionPoints
-_kSecOIDCrlNumber
-_kSecOIDCrlReason
-_kSecOIDDOTMAC_CERT_EMAIL_ENCRYPT
-_kSecOIDDOTMAC_CERT_EMAIL_SIGN
-_kSecOIDDOTMAC_CERT_EXTENSION
-_kSecOIDDOTMAC_CERT_IDENTITY
-_kSecOIDDOTMAC_CERT_POLICY
-_kSecOIDDeltaCrlIndicator
-_kSecOIDDescription
-_kSecOIDEKU_IPSec
-_kSecOIDEmailAddress
-_kSecOIDEmailProtection
-_kSecOIDExtendedKeyUsage
-_kSecOIDExtendedKeyUsageAny
-_kSecOIDExtendedUseCodeSigning
-_kSecOIDGivenName
-_kSecOIDHoldInstructionCode
-_kSecOIDInvalidityDate
-_kSecOIDIssuerAltName
-_kSecOIDIssuingDistributionPoint
-_kSecOIDIssuingDistributionPoints
-_kSecOIDKERBv5_PKINIT_KP_CLIENT_AUTH
-_kSecOIDKERBv5_PKINIT_KP_KDC
-_kSecOIDKeyUsage
-_kSecOIDLocalityName
-_kSecOIDMS_NTPrincipalName
-_kSecOIDMicrosoftSGC
-_kSecOIDNameConstraints
-_kSecOIDNetscapeCertSequence
-_kSecOIDNetscapeCertType
-_kSecOIDNetscapeSGC
-_kSecOIDOCSPSigning
-_kSecOIDOrganizationName
-_kSecOIDOrganizationalUnitName
-_kSecOIDPolicyConstraints
-_kSecOIDPolicyMappings
-_kSecOIDPrivateKeyUsagePeriod
-_kSecOIDQC_Statements
-_kSecOIDSerialNumber
-_kSecOIDServerAuth
-_kSecOIDStateProvinceName
-_kSecOIDStreetAddress
-_kSecOIDSubjectAltName
-_kSecOIDSubjectDirectoryAttributes
-_kSecOIDSubjectEmailAddress
-_kSecOIDSubjectInfoAccess
-_kSecOIDSubjectKeyIdentifier
-_kSecOIDSubjectPicture
-_kSecOIDSubjectSignatureBitmap
-_kSecOIDSurname
-_kSecOIDTimeStamping
-_kSecOIDTitle
-_kSecOIDUseExemptions
-_kSecOIDX509V1CertificateIssuerUniqueId
-_kSecOIDX509V1CertificateSubjectUniqueId
-_kSecOIDX509V1IssuerName
-_kSecOIDX509V1IssuerNameCStruct
-_kSecOIDX509V1IssuerNameLDAP
-_kSecOIDX509V1IssuerNameStd
-_kSecOIDX509V1SerialNumber
-_kSecOIDX509V1Signature
-_kSecOIDX509V1SignatureAlgorithm
-_kSecOIDX509V1SignatureAlgorithmParameters
-_kSecOIDX509V1SignatureAlgorithmTBS
-_kSecOIDX509V1SignatureCStruct
-_kSecOIDX509V1SignatureStruct
-_kSecOIDX509V1SubjectName
-_kSecOIDX509V1SubjectNameCStruct
-_kSecOIDX509V1SubjectNameLDAP
-_kSecOIDX509V1SubjectNameStd
-_kSecOIDX509V1SubjectPublicKey
-_kSecOIDX509V1SubjectPublicKeyAlgorithm
-_kSecOIDX509V1SubjectPublicKeyAlgorithmParameters
-_kSecOIDX509V1SubjectPublicKeyCStruct
-_kSecOIDX509V1ValidityNotAfter
-_kSecOIDX509V1ValidityNotBefore
-_kSecOIDX509V1Version
-_kSecOIDX509V3Certificate
-_kSecOIDX509V3CertificateCStruct
-_kSecOIDX509V3CertificateExtensionCStruct
-_kSecOIDX509V3CertificateExtensionCritical
-_kSecOIDX509V3CertificateExtensionId
-_kSecOIDX509V3CertificateExtensionStruct
-_kSecOIDX509V3CertificateExtensionType
-_kSecOIDX509V3CertificateExtensionValue
-_kSecOIDX509V3CertificateExtensionsCStruct
-_kSecOIDX509V3CertificateExtensionsStruct
-_kSecOIDX509V3CertificateNumberOfExtensions
-_kSecOIDX509V3SignedCertificate
-_kSecOIDX509V3SignedCertificateCStruct
-_kSecOIDSRVName
-_kSecRandomDefault
-_SecACLCopySimpleContents
-_SecACLCreateFromSimpleContents
-_SecACLCreateWithSimpleContents
-_SecACLCopyContents
-_SecACLGetAuthorizations
-_SecACLCopyAuthorizations
-_SecACLGetTypeID
-_SecACLRemove
-_SecACLSetAuthorizations
-_SecACLUpdateAuthorizations
-_SecACLSetContents
-_SecACLSetSimpleContents
-_SecAccessCopyACLList
-_SecAccessCopySelectedACLList
-_SecAccessCopyMatchingACLList
-_SecAccessCreate
-_SecAccessCreateFromOwnerAndACL
-_SecAccessCreateWithOwnerAndACL
-_SecAccessCreateWithTrustedApplications
-_SecAccessGetOwnerAndACL
-_SecAccessCopyOwnerAndACL
-_SecAccessGetTypeID
-_SecCertifcateBundleExport
-_SecCertificateAddToKeychain
-_SecCertificateBundleExport
-_SecCertificateBundleImport
-_SecCertificateCopyCommonName
-_SecCertificateCopyData
-_SecCertificateCopySubjectComponent
-_SecCertificateCopyEmailAddresses
-_SecCertificateCopyFieldValues
-_SecCertificateCopyFirstFieldValue
-_SecCertificateCopyPreference
-_SecCertificateCopyPreferred
-_SecCertificateCopyPublicKey
-_SecCertificateCopySubjectSummary
-_SecCertificateCreateFromData
-_SecCertificateCreateWithBytes
-_SecCertificateCreateWithData
-_SecCertificateFindByEmail
-_SecCertificateFindByIssuerAndSN
-_SecCertificateFindBySubjectKeyID
-_SecCertificateGetAlgorithmID
-_SecCertificateGetCLHandle
-_SecCertificateGetBytePtr
-_SecCertificateGetCommonName
-_SecCertificateGetData
-_SecCertificateGetEmailAddress
-_SecCertificateGetIssuer
-_SecCertificateGetLength
-_SecCertificateGetSubject
-_SecCertificateGetType
-_SecCertificateGetTypeID
-_SecCertificateInferLabel
-_SecCertificateIsSelfSigned
-_SecCertificateRequestCreate
-_SecCertificateRequestGetTypeID
-_SecCertificateRequestSubmit
-_SecCertificateRequestGetType
-_SecCertificateRequestGetResult
-_SecCertificateReleaseFieldValues
-_SecCertificateFindRequest
-_SecCertificateRequestGetData
-_SecCertificateReleaseFirstFieldValue
-_SecCertificateSetPreference
-_SecCertificateSetPreferred
-_SecCertificateCopyValues
-_SecCertificateCopyLongDescription
-_SecCertificateCopyShortDescription
-_SecCopyErrorMessageString
-_SecDigestGetData
-_SecIdentityAddPreferenceItem
-_SecIdentityCompare
-_SecIdentityCopyCertificate
-_SecIdentityCopyFromPreferenceItem
-_SecIdentityCopyPreference
-_SecIdentityCopyPreferred
-_SecIdentityCopyPrivateKey
-_SecIdentityCopySystemIdentity
-_SecIdentityCreate
-_SecIdentityCreateWithCertificate
-_SecIdentityFindPreferenceItem
-_SecIdentityGetTypeID
-_SecIdentitySearchCopyNext
-_SecIdentitySearchCreate
-_SecIdentitySearchCreateWithAttributes
-_SecIdentitySearchCreateWithPolicy
-_SecIdentitySearchGetTypeID
-_SecIdentitySetPreference
-_SecIdentitySetPreferred
-_SecIdentitySetSystemIdentity
-_SecIdentityUpdatePreferenceItem
-_SecInferLabelFromX509Name
-_SecItemAdd
-_SecItemCopyDisplayNames
-_SecItemCopyMatching
-_SecItemDelete
-_SecItemUpdate
-_kSecAttrKeyTypeRSA
-_kSecAttrKeyTypeDSA
-_kSecAttrKeyTypeAES
-_kSecAttrKeyTypeDES
-_kSecAttrKeyType3DES
-_kSecAttrKeyTypeRC4
-_kSecAttrKeyTypeRC2
-_kSecAttrKeyTypeCAST
-_kSecAttrKeyTypeECDSA
-_kSecAttrPRF
-_kSecAttrPRFHmacAlgSHA1
-_kSecAttrPRFHmacAlgSHA224
-_kSecAttrPRFHmacAlgSHA256
-_kSecAttrPRFHmacAlgSHA384
-_kSecAttrPRFHmacAlgSHA512
-_kSecAttrSalt
-_kSecAttrRounds
-_SecECKeyGetNamedCurve
-_SecItemExport
-_SecItemImport
-_SecKeyCreate
-_SecKeyCreatePair
-_SecKeyCreateWithCSSMKey
-_SecKeyDecrypt
-_SecKeyEncrypt
-_SecKeyGenerate
-_SecKeyGeneratePair
-_SecKeyGetAlgorithmID
-_SecKeyGetAlgorithmId
-_SecKeyGetBlockSize
-_SecKeyGetCSPHandle
-_SecKeyGetCSSMKey
-_SecKeyGetCredentials
-_SecKeyGetStrengthInBits
-_SecKeyGetTypeID
-_SecKeyImportPair
-_SecKeyRawSign
-_SecKeyRawVerify
-_SecKeySignDigest
-_SecKeyVerifyDigest
-_SecKeyGenerateSymmetric
-_SecKeyCreateFromData
-_SecKeyGeneratePairAsync
-_SecKeyDeriveFromPassword
-_SecKeyWrapSymmetric
-_SecKeyUnwrapSymmetric
-_SecKeychainAddCallback
-_SecKeychainAddDBToKeychainList
-_SecKeychainAddGenericPassword
-_SecKeychainAddIToolsPassword
-_SecKeychainAddInternetPassword
-_SecKeychainAttributeInfoForItemID
-_SecKeychainChangePassword
-_SecKeychainCopyAccess
-_SecKeychainCopyBlob
-_SecKeychainCopyDefault
-_SecKeychainCopyDomainDefault
-_SecKeychainCopyDomainSearchList
-_SecKeychainCopyLogin
-_SecKeychainCopySearchList
-_SecKeychainCopySettings
-_SecKeychainCopySignature
-_SecKeychainCreate
-_SecKeychainCreateNew
-_SecKeychainCreateWithBlob
-_SecKeychainDBIsInKeychainList
-_SecKeychainDelete
-_SecKeychainErrFromOSStatus
-_SecKeychainFindGenericPassword
-_SecKeychainFindInternetPassword
-_SecKeychainFreeAttributeInfo
-_SecKeychainGetCSPHandle
-_SecKeychainGetDLDBHandle
-_SecKeychainGetPath
-_SecKeychainGetPreferenceDomain
-_SecKeychainGetStatus
-_SecKeychainGetTypeID
-_SecKeychainGetUserInteractionAllowed
-_SecKeychainGetVersion
-_SecKeychainIsValid
-_SecKeychainItemAdd
-_SecKeychainItemAddNoUI
-_SecKeychainItemCopyAccess
-_SecKeychainItemCopyAllExtendedAttributes
-_SecKeychainItemCopyAttributesAndData
-_SecKeychainItemCopyAttributesAndEncryptedData
-_SecKeychainItemCopyContent
-_SecKeychainItemCopyExtendedAttribute
-_SecKeychainItemCopyFromRecordIdentifier
-_SecKeychainItemCopyKeychain
-_SecKeychainItemCopyFromPersistentReference
-_SecKeychainItemCopyRecordIdentifier
-_SecKeychainItemCreateCopy
-_SecKeychainItemCreateFromContent
-_SecKeychainItemCreateFromEncryptedContent
-_SecKeychainItemCreateNew
-_SecKeychainItemCreatePersistentReference
-_SecKeychainItemDelete
-_SecKeychainItemFindFirst
-_SecKeychainItemFreeAttributesAndData
-_SecKeychainItemFreeContent
-_SecKeychainItemGetAttribute
-_SecKeychainItemGetDLDBHandle
-_SecKeychainItemGetData
-_SecKeychainItemGetTypeID
-_SecKeychainItemGetUniqueRecordID
-_SecKeychainItemExport
-_SecKeychainItemImport
-_SecKeychainItemModifyAttributesAndData
-_SecKeychainItemModifyEncryptedData
-_SecKeychainItemModifyContent
-_SecKeychainItemSetAccess
-_SecKeychainItemSetAttribute
-_SecKeychainItemSetData
-_SecKeychainItemSetExtendedAttribute
-_SecKeychainItemUpdate
-_SecKeychainListCopyKeychainAtIndex
-_SecKeychainListGetCount
-_SecKeychainListRemoveKeychain
-_SecKeychainLock
-_SecKeychainLockAll
-_SecKeychainLogin
-_SecKeychainLogout
-_SecKeychainMakeFromFullPath
-_SecKeychainOpen
-_SecKeychainOpenWithGuid
-_SecKeychainRecodeKeychain
-_SecKeychainRemoveCallback
-_SecKeychainRemoveDBFromKeychainList
-_SecKeychainRemoveFromSearchList
-_SecKeychainResetLogin
-_SecKeychainSearchCopyNext
-_SecKeychainSearchCreateForCertificateByEmail
-_SecKeychainSearchCreateForCertificateByIssuerAndSN
-_SecKeychainSearchCreateForCertificateBySubjectKeyID
-_SecKeychainSearchCreateFromAttributes
-_SecKeychainSearchCreateFromAttributesExtended
-_SecKeychainSearchGetTypeID
-_SecKeychainSetAccess
-_SecKeychainSetDefault
-_SecKeychainSetDomainDefault
-_SecKeychainSetDomainSearchList
-_SecKeychainSetPreferenceDomain
-_SecKeychainSetSearchList
-_SecKeychainSetServerMode
-_SecKeychainSetSettings
-_SecKeychainSetUserInteractionAllowed
-_SecKeychainSystemKeychainCheckWouldDeadlock
-_SecKeychainUnlock
-_SecGenericPasswordCreate
-_SecPasswordSetInitialAccess
-_SecPasswordAction
-_SecPKCS12Import
-_SecPolicyCreateBasicX509
-_SecPolicyCreateSSL
-_SecPolicyCreateWithOID
-_SecPolicyGetOID
-_SecPolicyGetTPHandle
-_SecPolicyGetTypeID
-_SecPolicyGetValue
-_SecPolicySearchCopyNext
-_SecPolicySearchCreate
-_SecPolicySearchGetTypeID
-_SecPolicySetValue
-_SecPolicyCopy
-_SecPolicyCopyAll
-_SecPolicyCopyProperties
-_SecPolicySetProperties
-_SecTrustCopyAnchorCertificates
-_SecTrustCopyCustomAnchorCertificates
-_SecTrustCopyExtendedResult
-_SecTrustCopyPolicies
-_SecTrustCopyProperties
-_SecTrustCopyPublicKey
-_SecTrustCreateWithCertificates
-_SecTrustEvaluate
-_SecTrustEvaluateAsync
-_SecTrustGetCertificateAtIndex
-_SecTrustGetCertificateCount
-_SecTrustGetCSSMAnchorCertificates
-_SecTrustGetCssmResult
-_SecTrustGetCssmResultCode
-_SecTrustGetResult
-_SecTrustGetTrustResult
-_SecTrustGetTPHandle
-_SecTrustGetTypeID
-_SecTrustGetUserTrust
-_SecTrustGetVerifyTime
-_SecTrustKeychainsGetMutex
-_SecTrustSetAnchorCertificates
-_SecTrustSetAnchorCertificatesOnly
-_SecTrustSetKeychains
-_SecTrustSetOptions
-_SecTrustSetParameters
-_SecTrustSetPolicies
-_SecTrustSetUserTrust
-_SecTrustSetUserTrustLegacy
-_SecTrustSetVerifyDate
-_SecTrustedApplicationCopyData
-_SecTrustedApplicationCreateFromPath
-_SecTrustedApplicationCreateApplicationGroup
-_SecTrustedApplicationGetTypeID
-_SecTrustedApplicationIsUpdateCandidate
-_SecTrustedApplicationMakeEquivalent
-_SecTrustedApplicationRemoveEquivalence
-_SecTrustedApplicationSetData
-_SecTrustedApplicationUseAlternateSystem
-_SecTrustedApplicationValidateWithPath
-_SecTrustedApplicationCreateFromRequirement
-_SecTrustedApplicationCopyExternalRepresentation
-_SecTrustedApplicationCreateWithExternalRepresentation
-_SecTrustedApplicationCopyRequirement
-_SecTrustSettingsEvaluateCert
-_SecTrustSettingsCopyTrustSettings
-_SecTrustSettingsSetTrustSettings
-_SecTrustSettingsRemoveTrustSettings
-_SecTrustSettingsCopyCertificates
-_SecTrustSettingsCopyModificationDate
-_SecTrustSettingsCreateExternalRepresentation
-_SecTrustSettingsImportExternalRepresentation
-_SecTrustSettingsSetTrustSettingsExternal
-_SecTrustSettingsCopyQualifiedCerts
-_SecTrustSettingsCopyUnrestrictedRoots
-_SecKeychainSetBatchMode
-_SecCertificateGetAuthorityKeyID
-_SecCertificateGetSubjectKeyID
-_SecCertificateGetCRLDistributionPoints
-_SecCertificateGetOCSPResponders
-_SecCertificateGetCAIssuers
-_SecCertificateShow
-_SecCertificateCopyIssuerSequence
-_SecCertificateCopySubjectSequence
-_SecCertificateGetNormalizedIssuerContent
-_SecCertificateGetNormalizedSubjectContent
-_SecCertificateHasSubject
-_SecCertificateHasCriticalSubjectAltName
-_SecCertificateHasUnknownCriticalExtension
-_SecCertificateIsValid
-_SecCertificateCopyAttributeDictionary
-_SecCertificateCreateFromAttributeDictionary
-_SecCertificateCopyPublicKeyP
-_SecCertificateGetBasicConstraints
-_SecCertificateGetPolicyConstraints
-_SecCertificateGetPolicyMappings
-_SecCertificateGetCertificatePolicies
-_SecCertificateGetInhibitAnyPolicySkipCerts
-_SecCertificateGetPublicKeyAlgorithm
-_SecCertificateGetPublicKeyData
-_SecCertificateCreateWithPEM
-_SecCertificateCopySerialNumber
-_SecCertificateCopyNormalizedIssuerContent
-_SecCertificateCopyNormalizedSubjectContent
-_SecCertificateIsValidX
-_SecDERItemCopyOIDDecimalRepresentation
-_SecAbsoluteTimeFromDateContent
-_SecWrapRecoveryPasswordWithAnswers
-_SecUnwrapRecoveryPasswordWithAnswers
-_SecCreateRecoveryPassword
-_kSecRecVersionNumber
-_kSecRecQuestions
-_kSecRecLocale
-_kSecRecIV
-_kSecRecWrappedPassword
-_SecFDERecoveryWrapCRSKWithPubKey
-_SecFDERecoveryUnwrapCRSKWithPrivKey
-_SecKeychainSearchCreateForCertificateByIssuerAndSN_CF
-_SecRandomCopyBytes
-_SecRandomCopyData
-
-# libsecurity_manifest
-#####################################################################################
-_SecManifestGetVersion
-_SecManifestCompare
-_SecManifestCreate
-_SecManifestRelease
-_SecManifestVerifySignature
-_SecManifestVerifySignatureWithPolicy
-_SecManifestCreateSignature
-_SecManifestAddObject
-_SecManifestAddSigner
-_SecureDownloadCreateWithTicket
-_SecureDownloadUpdateWithData
-_SecureDownloadFinished
-_SecureDownloadRelease
-_SecureDownloadCopyName
-_SecureDownloadCopyURLs
-_SecureDownloadCopyCreationDate
-_SecureDownloadGetDownloadSize
-__SecureDownloadCreateTicketXML
-_SecureDownloadCopyTicketLocation
-
-# libsecurity_mds
-#####################################################################################
-_MDS_Initialize
-_MDS_Install
-_MDS_Terminate
-_MDS_Uninstall
-_MDS_InstallFile
-_MDS_RemoveSubservice
-
-# libsecurity_smime
-#####################################################################################
-_SecArenaPoolCreate
-_SecArenaPoolFree
-_SecCmsContentInfoGetBulkKey
-_SecCmsContentInfoGetBulkKeySize
-_SecCmsContentInfoGetChildContentInfo
-_SecCmsContentInfoGetContent
-_SecCmsContentInfoGetContentEncAlg
-_SecCmsContentInfoGetContentEncAlgTag
-_SecCmsContentInfoGetContentTypeOID
-_SecCmsContentInfoGetContentTypeTag
-_SecCmsContentInfoGetInnerContent
-_SecCmsContentInfoSetBulkKey
-_SecCmsContentInfoSetContentData
-_SecCmsContentInfoSetContentDigestedData
-_SecCmsContentInfoSetContentEncAlg
-_SecCmsContentInfoSetContentEncAlgID
-_SecCmsContentInfoSetContentEncryptedData
-_SecCmsContentInfoSetContentEnvelopedData
-_SecCmsContentInfoSetContentSignedData
-_SecCmsContentInfoSetContentOther
-_SecCmsDecoderCreate
-_SecCmsDecoderDestroy
-_SecCmsDecoderFinish
-_SecCmsDecoderUpdate
-_SecCmsDigestContextCancel
-_SecCmsDigestContextFinishMultiple
-_SecCmsDigestContextStartMultiple
-_SecCmsDigestContextUpdate
-_SecCmsDigestedDataCreate
-_SecCmsDigestedDataDestroy
-_SecCmsDigestedDataGetContentInfo
-_SecCmsEncoderCreate
-_SecCmsEncoderDestroy
-_SecCmsEncoderFinish
-_SecCmsEncoderUpdate
-_SecCmsEncryptedDataCreate
-_SecCmsEncryptedDataDestroy
-_SecCmsEncryptedDataGetContentInfo
-_SecCmsEnvelopedDataAddRecipient
-_SecCmsEnvelopedDataCreate
-_SecCmsEnvelopedDataDestroy
-_SecCmsEnvelopedDataGetContentInfo
-_SecCmsMessageContainsCertsOrCrls
-_SecCmsMessageContentLevel
-_SecCmsMessageContentLevelCount
-_SecCmsMessageCopy
-_SecCmsMessageCreate
-_SecCmsMessageDecode
-_SecCmsMessageDestroy
-_SecCmsMessageEncode
-_SecCmsMessageGetArena
-_SecCmsMessageGetContent
-_SecCmsMessageGetContentInfo
-_SecCmsMessageIsContentEmpty
-_SecCmsMessageIsEncrypted
-_SecCmsMessageIsSigned
-_SecCmsMessageContainsTSTInfo
-_SecCmsMessageSetTSACallback
-_SecCmsMessageSetTSAContext
-_SecCmsTSAGetDefaultContext
-_SecCmsTSADefaultCallback
-_SecTSAResponseCopyDEREncoding
-_kTSAContextKeyURL
-_kTSAContextKeyNoCerts
-_kTSADebugContextKeyBadReq
-_kTSADebugContextKeyBadNonce
-_SecCmsRecipientInfoCreate
-_SecCmsRecipientInfoCreateWithSubjKeyID
-_SecCmsRecipientInfoCreateWithSubjKeyIDFromCert
-_SecCmsRecipientInfoDestroy
-_SecCmsSignedDataAddCertChain
-_SecCmsSignedDataAddCertList
-_SecCmsSignedDataAddCertificate
-_SecCmsSignedDataAddSignerInfo
-_SecCmsSignedDataContainsCertsOrCrls
-_SecCmsSignedDataCreate
-_SecCmsSignedDataCreateCertsOnly
-_SecCmsSignedDataDestroy
-_SecCmsSignedDataGetCertificateList
-_SecCmsSignedDataGetContentInfo
-_SecCmsSignedDataGetDigestAlgs
-_SecCmsSignedDataGetSignerInfo
-_SecCmsSignedDataGetSignerInfos
-_SecCmsSignedDataHasDigests
-_SecCmsSignedDataImportCerts
-_SecCmsSignedDataSetDigests
-_SecCmsSignedDataSignerInfoCount
-_SecCmsSignedDataVerifyCertsOnly
-_SecCmsSignedDataVerifySignerInfo
-_SecCmsSignerInfoAddCounterSignature
-_SecCmsSignerInfoAddMSSMIMEEncKeyPrefs
-_SecCmsSignerInfoAddSMIMECaps
-_SecCmsSignerInfoAddSMIMEEncKeyPrefs
-_SecCmsSignerInfoAddSigningTime
-_SecCmsSignerInfoCreate
-_SecCmsSignerInfoCreateWithSubjKeyID
-_SecCmsSignerInfoDestroy
-_SecCmsSignerInfoGetCertList
-_SecCmsSignerInfoGetDigestAlg
-_SecCmsSignerInfoGetDigestAlgTag
-_SecCmsSignerInfoGetSignerCommonName
-_SecCmsSignerInfoGetSignerEmailAddress
-_SecCmsSignerInfoGetSigningCertificate
-_SecCmsSignerInfoGetSigningTime
-_SecCmsSignerInfoGetTimestampTime
-_SecCmsSignerInfoGetVerificationStatus
-_SecCmsSignerInfoGetEncDigest
-_SecCmsSignerInfoIncludeCerts
-_SecCmsSignerInfoSaveSMIMEProfile
-_SecCmsUtilVerificationStatusToString
-_SecSMIMEFindBulkAlgForRecipients
-
-# libsecurity_ssl
-#####################################################################################
-_SSLAddDistinguishedName
-_SSLClose
-_SSLContextGetTypeID
-_SSLCreateContext
-_SSLDisposeContext
-_SSLGetAllowsAnyRoot
-_SSLGetAllowsExpiredCerts
-_SSLGetAllowsExpiredRoots
-_SSLGetBufferedReadSize
-_SSLGetClientCertificateState
-_SSLGetClientSideAuthenticate
-_SSLGetConnection
-_SSLGetDiffieHellmanParams
-_SSLGetEnableCertVerify
-_SSLGetEnabledCiphers
-_SSLGetNegotiatedCipher
-_SSLGetNegotiatedProtocolVersion
-_SSLGetNumberEnabledCiphers
-_SSLGetNumberSupportedCiphers
-_SSLGetPeerCertificates
-_SSLCopyPeerCertificates
-_SSLCopyPeerTrust
-_SSLGetPeerDomainName
-_SSLGetPeerDomainNameLength
-_SSLGetPeerID
-_SSLGetPeerSecTrust
-_SSLGetProtocolVersion
-_SSLGetProtocolVersionEnabled
-_SSLGetProtocolVersionMax
-_SSLGetProtocolVersionMin
-_SSLGetResumableSessionInfo
-_SSLGetRsaBlinding
-_SSLGetSessionOption
-_SSLGetSessionState
-_SSLGetSupportedCiphers
-_SSLGetTrustedRoots
-_SSLCopyTrustedRoots
-_SSLSetTrustedLeafCertificates
-_SSLCopyTrustedLeafCertificates
-_SSLHandshake
-_SSLInternalClientRandom
-_SSLInternalMasterSecret
-_SSLInternalServerRandom
-_SSLGetCipherSizes
-_SSLInternal_PRF
-_SSLNewContext
-_SSLRead
-_SSLSetAllowsAnyRoot
-_SSLSetAllowsExpiredCerts
-_SSLSetAllowsExpiredRoots
-_SSLSetCertificate
-_SSLGetCertificate
-_SSLSetClientSideAuthenticate
-_SSLSetConnection
-_SSLSetDatagramHelloCookie
-_SSLSetMaxDatagramRecordSize
-_SSLGetMaxDatagramRecordSize
-_SSLSetDiffieHellmanParams
-_SSLSetEnableCertVerify
-_SSLSetEnabledCiphers
-_SSLSetEncryptionCertificate
-_SSLGetEncryptionCertificate
-_SSLSetIOFuncs
-_SSLSetPeerDomainName
-_SSLSetPeerID
-_SSLSetProtocolVersion
-_SSLSetProtocolVersionEnabled
-_SSLSetProtocolVersionMax
-_SSLSetProtocolVersionMin
-_SSLSetRsaBlinding
-_SSLSetTrustedRoots
-_SSLWrite
-_SSLSetSessionCacheTimeout
-_SSLSetSessionOption
-_SSLInternalSetMasterSecretFunction
-_SSLInternalSetSessionTicket
-_SSLSetAllowAnonymousCiphers
-_SSLGetAllowAnonymousCiphers
-_SSLCopyDistinguishedNames
-_SSLSetCertificateAuthorities
-_SSLCopyCertificateAuthorities
-_SSLGetNegotiatedCurve
-_SSLGetNumberOfECDSACurves
-_SSLGetECDSACurves
-_SSLSetECDSACurves
-_SSLGetNumberOfClientAuthTypes
-_SSLGetClientAuthTypes
-_SSLGetNegotiatedClientAuthType
-_SSLGetNumberOfSignatureAlgorithms
-_SSLGetSignatureAlgorithms
-_SSLNewDatagramContext
-_SSLGetDatagramWriteSize
-
-# libsecurity_transform
-#####################################################################################
-_SecTransformCreateFromExternalRepresentation
-_SecTransformCreateValidatorForCFtype
-_SecTransformCopyExternalRepresentation
-_SecTransformConnectTransforms
-_SecTransformSetAttribute
-_SecTransformGetAttribute
-_SecTransformFindByName
-_SecTransformExecute
-_SecTransformExecuteAsync
-_SecNullTransformCreate
-_SecDigestTransformCreate
-_SecCreateMaskGenerationFunctionTransform
-_SecTransformCreate
-_SecTransformRegister
-_SecTransformNoData
-_kSecDigestMD2
-_kSecDigestMD4
-_kSecDigestMD5
-_kSecDigestSHA1
-_kSecDigestSHA2
-_kSecDigestHMACSHA1
-_kSecDigestHMACMD5
-_kSecDigestHMACKeyAttribute
-_kSecDigestHMACSHA2
-_SecExternalSourceTransformCreate
-_SecExternalSourceSetValue
-_kSecDecodeTypeAttribute
-_CreateSecTransformErrorRef
-_kSecTransformAbortOriginatorKey
-_SecGroupTransformHasMember
-_kSecDigestTypeAttribute
-_kSecDigestLengthAttribute
-_kSecOAEPEncodingParametersAttributeName
-_kSecTransformInputAttributeName
-_kSecTransformDebugAttributeName
-_kSecTransformOutputAttributeName
-_kSecTransformTransformName
-_kSecTransformAbortAttributeName
-_kSecPaddingNoneKey
-_kSecPaddingPKCS1Key
-_kSecPaddingPKCS5Key
-_kSecPaddingPKCS7Key
-_kSecPaddingOAEPKey
-_kSecModeNoneKey
-_kSecModeECBKey
-_kSecModeCBCKey
-_kSecModeCFBKey
-_kSecModeOFBKey
-_kSecEncryptKey
-_kSecPaddingKey
-_kSecIVKey
-_kSecEncryptionMode
-_SecEncryptTransformCreate
-_SecDecryptTransformCreate
-_SecDecodeTransformCreate
-_SecEncodeTransformCreate
-_SecSignTransformCreate
-_SecVerifyTransformCreate
-_kSecBase32Encoding
-_kSecBase64Encoding
-_kSecZLibEncoding
-_kSecEncodeLineLengthAttribute
-_kSecEncodeTypeAttribute
-_kSecCompressionRatio
-_kSecKeyAttributeName
-_kSecSignatureAttributeName
-_kSecInputIsAttributeName
-_kSecInputIsPlainText
-_kSecInputIsDigest
-_kSecInputIsRaw
-_kSecTransformActionCanExecute
-_kSecTransformActionStartingExecution
-_kSecTransformActionFinalize
-_kSecTransformActionProcessData
-_SecTransformSetAttributeAction
-_SecGroupTransformFindLastTransform
-_SecGroupTransformFindMonitor
-_SecTransformDisconnectTransforms
-_SecTransformDotForDebugging
-_SecCreateCollectTransform
-_SecTransformGetTypeID
-_SecGroupTransformGetTypeID
-_SecTransformCreateGroupTransform
-_SecTransformSetDataAction
-_SecTransformSetTransformAction
-_SecTranformCustomGetAttribute
-_SecTransformCustomSetAttribute
-_SecTransformPushbackAttribute
-_kSecTransformActionExternalizeExtraData
-_kSecTransformActionInternalizeExtraData
-_kSecTransformActionAttributeNotification
-_kSecTransformActionAttributeValidation
-_kSecTransformErrorDomain
-_kSecTransformPreviousErrorKey
-_SecTransformCreateReadTransformWithReadStream
-_kSecLineLength64
-_kSecLineLength76
diff --git a/lib/security.exp-in b/lib/security.exp-in
new file mode 100644 (file)
index 0000000..301de44
--- /dev/null
@@ -0,0 +1,2200 @@
+//
+//
+//
+#include <TargetConditionals.h>
+
+_SecurityVersionNumber
+_SecurityVersionString
+
+//
+// libsecurity_asn1
+//
+_SecAsn1AllocCopy
+_SecAsn1AllocCopyItem
+_SecAsn1AllocItem
+_SecAsn1CoderCreate
+_SecAsn1CoderRelease
+_SecAsn1Decode
+_SecAsn1DecodeData
+_SecAsn1EncodeItem
+_SecAsn1Malloc
+_kSecAsn1AnyTemplate
+_kSecAsn1BMPStringTemplate
+_kSecAsn1BitStringTemplate
+_kSecAsn1BooleanTemplate
+_kSecAsn1EnumeratedTemplate
+_kSecAsn1GeneralizedTimeTemplate
+_kSecAsn1IA5StringTemplate
+_kSecAsn1IntegerTemplate
+_kSecAsn1NullTemplate
+_kSecAsn1ObjectIDTemplate
+_kSecAsn1OctetStringTemplate
+_kSecAsn1PointerToAnyTemplate
+_kSecAsn1PointerToBMPStringTemplate
+_kSecAsn1PointerToBitStringTemplate
+_kSecAsn1PointerToBooleanTemplate
+_kSecAsn1PointerToEnumeratedTemplate
+_kSecAsn1PointerToGeneralizedTimeTemplate
+_kSecAsn1PointerToIA5StringTemplate
+_kSecAsn1PointerToIntegerTemplate
+_kSecAsn1PointerToNullTemplate
+_kSecAsn1PointerToObjectIDTemplate
+_kSecAsn1PointerToOctetStringTemplate
+_kSecAsn1PointerToPrintableStringTemplate
+_kSecAsn1PointerToT61StringTemplate
+_kSecAsn1PointerToTeletexStringTemplate
+_kSecAsn1PointerToUTCTimeTemplate
+_kSecAsn1PointerToUTF8StringTemplate
+_kSecAsn1PointerToUniversalStringTemplate
+_kSecAsn1PointerToVisibleStringTemplate
+_kSecAsn1PrintableStringTemplate
+_kSecAsn1SequenceOfAnyTemplate
+_kSecAsn1SequenceOfBMPStringTemplate
+_kSecAsn1SequenceOfBitStringTemplate
+_kSecAsn1SequenceOfBooleanTemplate
+_kSecAsn1SequenceOfEnumeratedTemplate
+_kSecAsn1SequenceOfGeneralizedTimeTemplate
+_kSecAsn1SequenceOfIA5StringTemplate
+_kSecAsn1SequenceOfIntegerTemplate
+_kSecAsn1SequenceOfNullTemplate
+_kSecAsn1SequenceOfObjectIDTemplate
+_kSecAsn1SequenceOfOctetStringTemplate
+_kSecAsn1SequenceOfPrintableStringTemplate
+_kSecAsn1SequenceOfT61StringTemplate
+_kSecAsn1SequenceOfTeletexStringTemplate
+_kSecAsn1SequenceOfUTCTimeTemplate
+_kSecAsn1SequenceOfUTF8StringTemplate
+_kSecAsn1SequenceOfUniversalStringTemplate
+_kSecAsn1SequenceOfVisibleStringTemplate
+_kSecAsn1SetOfAnyTemplate
+_kSecAsn1SetOfBMPStringTemplate
+_kSecAsn1SetOfBitStringTemplate
+_kSecAsn1SetOfBooleanTemplate
+_kSecAsn1SetOfEnumeratedTemplate
+_kSecAsn1SetOfGeneralizedTimeTemplate
+_kSecAsn1SetOfIA5StringTemplate
+_kSecAsn1SetOfIntegerTemplate
+_kSecAsn1SetOfNullTemplate
+_kSecAsn1SetOfObjectIDTemplate
+_kSecAsn1SetOfOctetStringTemplate
+_kSecAsn1SetOfPrintableStringTemplate
+_kSecAsn1SetOfT61StringTemplate
+_kSecAsn1SetOfTeletexStringTemplate
+_kSecAsn1SetOfUTCTimeTemplate
+_kSecAsn1SetOfUTF8StringTemplate
+_kSecAsn1SetOfUniversalStringTemplate
+_kSecAsn1SetOfVisibleStringTemplate
+_kSecAsn1SkipTemplate
+_kSecAsn1T61StringTemplate
+_kSecAsn1TeletexStringTemplate
+_kSecAsn1UTCTimeTemplate
+_kSecAsn1UTF8StringTemplate
+_kSecAsn1UniversalStringTemplate
+_kSecAsn1UnsignedIntegerTemplate
+_kSecAsn1VisibleStringTemplate
+_kSecAsn1CertExtensionTemplate
+_kSecAsn1RevokedCertTemplate
+_kSecAsn1SequenceOfCertExtensionTemplate
+_kSecAsn1SequenceOfRevokedCertTemplate
+_kSecAsn1SignedCertOrCRLTemplate
+_kSecAsn1SignedCertTemplate
+_kSecAsn1SignedCrlTemplate
+_kSecAsn1TBSCertificateTemplate
+_kSecAsn1TBSCrlTemplate
+_kSecAsn1ValidityTemplate
+_kSecAsn1AccessDescriptionTemplate
+_kSecAsn1AuthorityInfoAccessTemplate
+_kSecAsn1AuthorityKeyIdTemplate
+_kSecAsn1BasicConstraintsTemplate
+_kSecAsn1CRLDistributionPointsTemplate
+_kSecAsn1CertPoliciesTemplate
+_kSecAsn1DistPointFullNameTemplate
+_kSecAsn1DistPointRDNTemplate
+_kSecAsn1DistributionPointTemplate
+_kSecAsn1IssuingDistributionPointTemplate
+_kSecAsn1PolicyInformationTemplate
+_kSecAsn1PolicyQualifierTemplate
+_kSecAsn1CertRequestInfoTemplate
+_kSecAsn1CertRequestTemplate
+_kSecAsn1SignedCertRequestTemplate
+_kSecAsn1AlgorithmIDTemplate
+_kSecAsn1AttributeTemplate
+_kSecAsn1DHAlgorithmIdentifierX942Template
+_kSecAsn1DHDomainParamsX942Template
+_kSecAsn1DHParameterBlockTemplate
+_kSecAsn1DHParameterTemplate
+_kSecAsn1DHPrivateKeyPKCS8Template
+_kSecAsn1DHPrivateKeyTemplate
+_kSecAsn1DHPublicKeyX509Template
+_kSecAsn1DHValidationParamsTemplate
+_kSecAsn1DigestInfoTemplate
+_kSecAsn1EncryptedPrivateKeyInfoTemplate
+_kSecAsn1PrivateKeyInfoTemplate
+_kSecAsn1RSAPrivateKeyPKCS1Template
+_kSecAsn1RSAPublicKeyPKCS1Template
+_kSecAsn1SetOfAttributeTemplate
+_kSecAsn1SubjectPublicKeyInfoTemplate
+_kSecAsn1ATVTemplate
+_kSecAsn1GenNameOtherNameTemplate
+_kSecAsn1GeneralNameTemplate
+_kSecAsn1NameTemplate
+_kSecAsn1OtherNameTemplate
+_kSecAsn1RDNTemplate
+_SecAsn1TaggedTemplateChooser
+_kSecAsn1DSAAlgParamsTemplate
+_kSecAsn1DSAAlgParamsBSAFETemplate
+_kSecAsn1DSAAlgorithmIdX509Template
+_kSecAsn1DSAAlgorithmIdBSAFETemplate
+_kSecAsn1DSAPublicKeyX509Template
+_kSecAsn1DSAPublicKeyBSAFETemplate
+_kSecAsn1DSAPrivateKeyOpensslTemplate
+_kSecAsn1DSAPrivateKeyOctsTemplate
+_kSecAsn1DSAPrivateKeyBSAFETemplate
+_kSecAsn1DSAPrivateKeyPKCS8Template
+_kSecAsn1DSASignatureTemplate
+_kSecAsn1OCSPBasicResponseTemplate
+_kSecAsn1OCSPCertIDTemplate
+_kSecAsn1OCSPCertStatusGoodTemplate
+_kSecAsn1OCSPCertStatusRevokedTemplate
+_kSecAsn1OCSPCertStatusUnknownTemplate
+_kSecAsn1OCSPRequestTemplate
+_kSecAsn1OCSPResponderIDAsNameTemplate
+_kSecAsn1OCSPResponderIDAsKeyTemplate
+_kSecAsn1OCSPResponseBytesTemplate
+_kSecAsn1OCSPResponseDataTemplate
+_kSecAsn1OCSPResponseTemplate
+_kSecAsn1OCSPRevokedInfoTemplate
+_kSecAsn1OCSPSignatureTemplate
+_kSecAsn1OCSPSignedRequestTemplate
+_kSecAsn1OCSPSingleResponseTemplate
+_kSecAsn1OCSPTbsRequestTemplate
+_kSecAsn1OCSPDRequestTemplate
+_kSecAsn1OCSPDRequestsTemplate
+_kSecAsn1OCSPDReplyTemplate
+_kSecAsn1OCSPDRepliesTemplate
+_kSecAsn1SemanticsInformationTemplate
+_kSecAsn1QC_StatementTemplate
+_kSecAsn1QC_StatementsTemplate
+
+//
+// libsecurity_authorization
+//
+_AuthorizationCopyInfo
+_AuthorizationCopyPrivilegedReference
+_AuthorizationCopyRights
+_AuthorizationCopyRightsAsync
+_AuthorizationDismiss
+_AuthorizationCreate
+_AuthorizationCreateWithAuditToken
+_AuthorizationCreateFromExternalForm
+_AuthorizationExecuteWithPrivileges
+_AuthorizationExecuteWithPrivilegesExternalForm
+_AuthorizationFree
+_AuthorizationFreeItemSet
+_AuthorizationMakeExternalForm
+_AuthorizationRightGet
+_AuthorizationRightRemove
+_AuthorizationRightSet
+_AuthorizationEnableSmartCard
+_SessionCreate
+_SessionGetInfo
+_SessionSetDistinguishedUser
+_SessionGetDistinguishedUser
+_SessionSetUserPreferences
+
+//
+// libsecurity_checkpw
+//
+_checkpw
+_checkpw_internal
+
+//
+// libsecurity_cms
+//
+_CMSEncode
+_CMSEncodeContent
+_CMSEncoderAddSupportingCerts
+_CMSEncoderAddRecipients
+_CMSEncoderAddSigners
+_CMSEncoderCopySupportingCerts
+_CMSEncoderCopyRecipients
+_CMSEncoderCopySigners
+_CMSEncoderCreate
+_CMSEncoderCopyEncodedContent
+_CMSEncoderGetCmsMessage
+_CMSEncoderSetHasDetachedContent
+_CMSEncoderGetHasDetachedContent
+_CMSEncoderCopyEncapsulatedContentType
+_CMSEncoderGetEncoder
+_CMSEncoderGetTypeID
+_CMSEncoderSetEncapsulatedContentType
+_CMSEncoderSetEncapsulatedContentTypeOID
+_CMSEncoderSetEncoder
+_CMSEncoderAddSignedAttributes
+_CMSEncoderSetSigningTime
+_CMSEncoderSetCertificateChainMode
+_CMSEncoderGetCertificateChainMode
+_CMSEncoderUpdateContent
+_CMSDecoderCopyAllCerts
+_CMSDecoderCopyContent
+_CMSDecoderCopyDetachedContent
+_CMSDecoderCopySignerStatus
+_CMSDecoderCreate
+_CMSDecoderGetTypeID
+_CMSDecoderFinalizeMessage
+_CMSDecoderGetDecoder
+_CMSDecoderCopyEncapsulatedContentType
+_CMSDecoderIsContentEncrypted
+_CMSDecoderGetNumSigners
+_CMSDecoderSetDecoder
+_CMSDecoderSetDetachedContent
+_CMSDecoderUpdateMessage
+_CMSDecoderGetCmsMessage
+_CMSDecoderSetSearchKeychain
+_CMSDecoderCopySignerEmailAddress
+_CMSDecoderCopySignerCert
+_CmsMessageSetTSAContext
+_CMSDecoderCopySignerSigningTime
+_CMSDecoderCopySignerTimestamp
+_CMSDecoderCopySignerTimestampCertificates
+_CMSEncoderCopySignerTimestamp
+
+//
+// libsecurity_codesigning
+//
+_SecCodeGetTypeID
+_SecCodeCopySelf
+_SecCodeCopyInternalRequirement
+_SecCodeGetStatus
+_SecCodeSetStatus
+_SecCodeCopyStaticCode
+_SecCodeCopyHost
+_SecCodeCopyGuestWithAttributes
+_SecCodeCreateWithPID
+_SecCodeCheckValidity
+_SecCodeCheckValidityWithErrors
+_SecCodeCopyPath
+_SecCodeCopyDesignatedRequirement
+_SecCodeCopySigningInformation
+_SecCodeMapMemory
+_SecCodeSetDetachedSignature
+_kSecCodeAttributeArchitecture
+_kSecCodeAttributeBundleVersion
+_kSecCodeAttributeSubarchitecture
+_kSecCodeAttributeUniversalFileOffset
+_SecStaticCodeGetTypeID
+_SecStaticCodeCreateWithPath
+_SecStaticCodeCreateWithPathAndAttributes
+_SecStaticCodeCheckValidity
+_SecStaticCodeCheckValidityWithErrors
+_SecStaticCodeSetCallback
+_SecRequirementGetTypeID
+_SecRequirementCreateWithData
+_SecRequirementCreateWithResource
+_SecRequirementCreateWithString
+_SecRequirementCreateWithStringAndErrors
+_SecRequirementCreateGroup
+_SecRequirementCopyData
+_SecRequirementCopyString
+_SecRequirementEvaluate
+_SecRequirementsCreateFromRequirements
+_SecRequirementsCopyRequirements
+_SecRequirementsCreateWithString
+_SecRequirementsCopyString
+_SecCodeSignerGetTypeID
+_SecCodeSignerCreate
+_SecCodeSignerAddSignature
+_SecCodeSignerAddSignatureWithErrors
+_SecHostCreateGuest
+_SecHostRemoveGuest
+_SecHostSetGuestStatus
+_SecHostSelectGuest
+_SecHostSelectedGuest
+_SecHostSetHostingPort
+_kSecCodeDirectoryFlagTable
+_kSecCodeSignerApplicationData
+_kSecCodeSignerDetached
+_kSecCodeSignerDigestAlgorithm
+_kSecCodeSignerDryRun
+_kSecCodeSignerEntitlements
+_kSecCodeSignerFlags
+_kSecCodeSignerIdentifier
+_kSecCodeSignerIdentifierPrefix
+_kSecCodeSignerIdentity
+_kSecCodeSignerPageSize
+_kSecCodeSignerPreserveMetadata
+_kSecCodeSignerRequirements
+_kSecCodeSignerResourceRules
+_kSecCodeSignerSDKRoot
+_kSecCodeSignerSigningTime
+_kSecCodeSignerRequireTimestamp
+_kSecCodeSignerTimestampServer
+_kSecCodeSignerTimestampAuthentication
+_kSecCodeSignerTimestampOmitCertificates
+_kSecCodeInfoCertificates
+_kSecCodeInfoChangedFiles
+_kSecCodeInfoCMS
+_kSecCodeInfoTime
+_kSecCodeInfoTimestamp
+_kSecCodeInfoDesignatedRequirement
+_kSecCodeInfoEntitlements
+_kSecCodeInfoEntitlementsDict
+_kSecCodeInfoFlags
+_kSecCodeInfoFormat
+_kSecCodeInfoDigestAlgorithm
+_kSecCodeInfoIdentifier
+_kSecCodeInfoImplicitDesignatedRequirement
+_kSecCodeInfoMainExecutable
+_kSecCodeInfoPList
+_kSecCodeInfoRequirements
+_kSecCodeInfoRequirementData
+_kSecCodeInfoSource
+_kSecCodeInfoStatus
+_kSecCodeInfoTrust
+_kSecCodeInfoUnique
+_kSecCodeInfoCodeDirectory
+_kSecCodeInfoCodeOffset
+_kSecCodeInfoResourceDirectory
+_kSecGuestAttributeCanonical
+_kSecGuestAttributeDynamicCode
+_kSecGuestAttributeDynamicCodeInfoPlist
+_kSecGuestAttributeHash
+_kSecGuestAttributeMachPort
+_kSecGuestAttributePid
+_kSecRequirementKeyInfoPlist
+_kSecRequirementKeyEntitlements
+_kSecRequirementKeyIdentifier
+_kSecCFErrorArchitecture
+_kSecCFErrorPath
+_kSecCFErrorPattern
+_kSecCFErrorResourceSeal
+_kSecCFErrorResourceAdded
+_kSecCFErrorResourceAltered
+_kSecCFErrorResourceMissing
+_kSecCFErrorInfoPlist
+_kSecCFErrorGuestAttributes
+_kSecCFErrorRequirementSyntax
+
+_SecTaskGetTypeID
+_SecTaskCreateWithAuditToken
+_SecTaskCreateFromSelf
+_SecTaskCopyValueForEntitlement
+_SecTaskCopyValuesForEntitlements
+_SecTaskValidateForRequirement
+
+_SecAssessmentCreate
+_SecAssessmentCopyResult
+_SecAssessmentUpdate
+_SecAssessmentCopyUpdate
+_SecAssessmentControl
+_kSecAssessmentContextKeyOperation
+_kSecAssessmentOperationTypeExecute
+_kSecAssessmentOperationTypeInstall
+_kSecAssessmentOperationTypeOpenDocument
+_kSecAssessmentContextKeyUpdate
+_kSecAssessmentUpdateOperationAdd
+_kSecAssessmentUpdateOperationRemove
+_kSecAssessmentUpdateOperationEnable
+_kSecAssessmentUpdateOperationDisable
+_kSecAssessmentUpdateOperationFind
+_kSecAssessmentUpdateKeyAuthorization
+_kSecAssessmentUpdateKeyAllow
+_kSecAssessmentUpdateKeyExpires
+_kSecAssessmentUpdateKeyLabel
+_kSecAssessmentUpdateKeyPriority
+_kSecAssessmentUpdateKeyRemarks
+_kSecAssessmentUpdateKeyRow
+_kSecAssessmentUpdateKeyCount
+_kSecAssessmentUpdateKeyFound
+_kSecAssessmentAssessmentAuthority
+_kSecAssessmentAssessmentAuthorityOverride
+_kSecAssessmentAssessmentAuthorityRow
+_kSecAssessmentAssessmentFromCache
+_kSecAssessmentAssessmentOriginator
+_kSecAssessmentAssessmentSource
+_kSecAssessmentAssessmentVerdict
+_kSecAssessmentRuleKeyID
+_kSecAssessmentRuleKeyPriority
+_kSecAssessmentRuleKeyAllow
+_kSecAssessmentRuleKeyLabel
+_kSecAssessmentRuleKeyRemarks
+_kSecAssessmentRuleKeyRequirement
+_kSecAssessmentRuleKeyType
+_kSecAssessmentRuleKeyExpires
+_kSecAssessmentRuleKeyDisabled
+_kSecAssessmentRuleKeyBookmark
+
+//
+// libsecurity_cssm
+//
+_CSSMOID_ANSI_DH_EPHEM
+_CSSMOID_ANSI_DH_EPHEM_SHA1
+_CSSMOID_ANSI_DH_HYBRID1
+_CSSMOID_ANSI_DH_HYBRID1_SHA1
+_CSSMOID_ANSI_DH_HYBRID2
+_CSSMOID_ANSI_DH_HYBRID2_SHA1
+_CSSMOID_ANSI_DH_HYBRID_ONEFLOW
+_CSSMOID_ANSI_DH_ONE_FLOW
+_CSSMOID_ANSI_DH_ONE_FLOW_SHA1
+_CSSMOID_ANSI_DH_PUB_NUMBER
+_CSSMOID_ANSI_DH_STATIC
+_CSSMOID_ANSI_DH_STATIC_SHA1
+_CSSMOID_ANSI_MQV1
+_CSSMOID_ANSI_MQV1_SHA1
+_CSSMOID_ANSI_MQV2
+_CSSMOID_ANSI_MQV2_SHA1
+_CSSMOID_APPLE_ASC
+_CSSMOID_APPLE_ECDSA
+_CSSMOID_APPLE_FEE
+_CSSMOID_APPLE_FEED
+_CSSMOID_APPLE_FEEDEXP
+_CSSMOID_APPLE_FEE_MD5
+_CSSMOID_APPLE_FEE_SHA1
+_CSSMOID_APPLE_ISIGN
+_CSSMOID_APPLE_TP_CSR_GEN
+_CSSMOID_APPLE_TP_EAP
+_CSSMOID_APPLE_TP_CODE_SIGN
+_CSSMOID_APPLE_TP_SW_UPDATE_SIGNING
+_CSSMOID_APPLE_TP_IP_SEC
+_CSSMOID_APPLE_TP_LOCAL_CERT_GEN
+_CSSMOID_APPLE_TP_REVOCATION_CRL
+_CSSMOID_APPLE_TP_REVOCATION_OCSP
+_CSSMOID_APPLE_TP_SMIME
+_CSSMOID_APPLE_TP_SSL
+_CSSMOID_APPLE_TP_ICHAT
+_CSSMOID_APPLE_TP_RESOURCE_SIGN
+_CSSMOID_APPLE_TP_PKINIT_CLIENT
+_CSSMOID_APPLE_TP_PKINIT_SERVER
+_CSSMOID_APPLE_TP_CODE_SIGNING
+_CSSMOID_APPLE_TP_PACKAGE_SIGNING
+_CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT
+_CSSMOID_APPLE_TP_APPLEID_SHARING
+_CSSMOID_APPLE_TP_TIMESTAMPING
+_CSSMOID_APPLE_TP_REVOCATION
+_CSSMOID_APPLE_TP_PASSBOOK_SIGNING
+_CSSMOID_APPLE_TP_MOBILE_STORE
+_CSSMOID_APPLE_TP_ESCROW_SERVICE
+_CSSMOID_APPLE_TP_PROFILE_SIGNING
+_CSSMOID_APPLE_TP_QA_PROFILE_SIGNING
+_CSSMOID_APPLE_TP_TEST_MOBILE_STORE
+_CSSMOID_APPLE_X509_BASIC
+_CSSMOID_AliasedEntryName
+_CSSMOID_AuthorityKeyIdentifier
+_CSSMOID_AuthorityRevocationList
+_CSSMOID_BasicConstraints
+_CSSMOID_BusinessCategory
+_CSSMOID_CACertificate
+_CSSMOID_CSSMKeyStruct
+_CSSMOID_CertIssuer
+_CSSMOID_CertificatePolicies
+_CSSMOID_CertificateRevocationList
+_CSSMOID_ChallengePassword
+_CSSMOID_ClientAuth
+_CSSMOID_CollectiveFacsimileTelephoneNumber
+_CSSMOID_CollectiveInternationalISDNNumber
+_CSSMOID_CollectiveOrganizationName
+_CSSMOID_CollectiveOrganizationalUnitName
+_CSSMOID_CollectivePhysicalDeliveryOfficeName
+_CSSMOID_CollectivePostOfficeBox
+_CSSMOID_CollectivePostalAddress
+_CSSMOID_CollectivePostalCode
+_CSSMOID_CollectiveStateProvinceName
+_CSSMOID_CollectiveStreetAddress
+_CSSMOID_CollectiveTelephoneNumber
+_CSSMOID_CollectiveTelexNumber
+_CSSMOID_CollectiveTelexTerminalIdentifier
+_CSSMOID_CommonName
+_CSSMOID_ContentType
+_CSSMOID_CounterSignature
+_CSSMOID_CountryName
+_CSSMOID_CrlDistributionPoints
+_CSSMOID_CrlNumber
+_CSSMOID_CrlReason
+_CSSMOID_CrossCertificatePair
+_CSSMOID_DH
+_CSSMOID_DNQualifier
+_CSSMOID_DSA
+_CSSMOID_DSA_CMS
+_CSSMOID_DSA_JDK
+_CSSMOID_DeltaCrlIndicator
+_CSSMOID_Description
+_CSSMOID_DestinationIndicator
+_CSSMOID_DistinguishedName
+_CSSMOID_EmailAddress
+_CSSMOID_EmailProtection
+_CSSMOID_EnhancedSearchGuide
+_CSSMOID_ExtendedCertificateAttributes
+_CSSMOID_ExtendedKeyUsage
+_CSSMOID_AuthorityInfoAccess
+_CSSMOID_BiometricInfo
+_CSSMOID_QC_Statements
+_CSSMOID_SubjectInfoAccess
+_CSSMOID_ExtendedKeyUsageAny
+_CSSMOID_ExtendedUseCodeSigning
+_CSSMOID_FacsimileTelephoneNumber
+_CSSMOID_GenerationQualifier
+_CSSMOID_GivenName
+_CSSMOID_HoldInstructionCode
+_CSSMOID_HouseIdentifier
+_CSSMOID_Initials
+_CSSMOID_InternationalISDNNumber
+_CSSMOID_InvalidityDate
+_CSSMOID_IssuerAltName
+_CSSMOID_IssuingDistributionPoint
+_CSSMOID_IssuingDistributionPoints
+_CSSMOID_KeyUsage
+_CSSMOID_KnowledgeInformation
+_CSSMOID_LocalityName
+_CSSMOID_MD2
+_CSSMOID_MD2WithRSA
+_CSSMOID_MD4
+_CSSMOID_MD4WithRSA
+_CSSMOID_MD5
+_CSSMOID_MD5WithRSA
+_CSSMOID_Member
+_CSSMOID_MessageDigest
+_CSSMOID_Name
+_CSSMOID_NameConstraints
+_CSSMOID_NetscapeCertType
+_CSSMOID_NetscapeCertSequence
+_CSSMOID_NetscapeSGC
+_CSSMOID_MicrosoftSGC
+_CSSMOID_OCSPSigning
+_CSSMOID_KERBv5_PKINIT_KP_CLIENT_AUTH
+_CSSMOID_KERBv5_PKINIT_KP_KDC
+_CSSMOID_EKU_IPSec
+_CSSMOID_ObjectClass
+_CSSMOID_OrganizationName
+_CSSMOID_OrganizationalUnitName
+_CSSMOID_Owner
+_CSSMOID_PKCS12_certBag
+_CSSMOID_PKCS12_crlBag
+_CSSMOID_PKCS12_keyBag
+_CSSMOID_PKCS12_pbeWithSHAAnd128BitRC2CBC
+_CSSMOID_PKCS12_pbeWithSHAAnd128BitRC4
+_CSSMOID_PKCS12_pbeWithSHAAnd2Key3DESCBC
+_CSSMOID_PKCS12_pbeWithSHAAnd3Key3DESCBC
+_CSSMOID_PKCS12_pbeWithSHAAnd40BitRC4
+_CSSMOID_PKCS12_pbewithSHAAnd40BitRC2CBC
+_CSSMOID_PKCS12_safeContentsBag
+_CSSMOID_PKCS12_secretBag
+_CSSMOID_PKCS12_shroudedKeyBag
+_CSSMOID_KERBv5_PKINIT_AUTH_DATA
+_CSSMOID_KERBv5_PKINIT_DH_KEY_DATA
+_CSSMOID_KERBv5_PKINIT_RKEY_DATA
+_CSSMOID_PKCS3
+_CSSMOID_PKCS7_Data
+_CSSMOID_PKCS7_DataWithAttributes
+_CSSMOID_PKCS7_DigestedData
+_CSSMOID_PKCS7_EncryptedData
+_CSSMOID_PKCS7_EncryptedPrivateKeyInfo
+_CSSMOID_PKCS7_EnvelopedData
+_CSSMOID_PKCS7_SignedAndEnvelopedData
+_CSSMOID_PKCS7_SignedData
+_CSSMOID_PKCS9_CertTypes
+_CSSMOID_PKCS9_CrlTypes
+_CSSMOID_PKCS9_FriendlyName
+_CSSMOID_PKCS9_LocalKeyId
+_CSSMOID_PKCS9_SdsiCertificate
+_CSSMOID_PKCS9_X509Certificate
+_CSSMOID_PKCS9_X509Crl
+_CSSMOID_PKCS9_Id_Ct_TSTInfo
+_CSSMOID_PKCS9_TimeStampToken
+_CSSMOID_PKCS5_DIGEST_ALG
+_CSSMOID_PKCS5_ENCRYPT_ALG
+_CSSMOID_PKCS5_HMAC_SHA1
+_CSSMOID_PKCS5_pbeWithMD2AndDES
+_CSSMOID_PKCS5_pbeWithMD5AndDES
+_CSSMOID_PKCS5_pbeWithMD2AndRC2
+_CSSMOID_PKCS5_pbeWithMD5AndRC2
+_CSSMOID_PKCS5_pbeWithSHA1AndDES
+_CSSMOID_PKCS5_pbeWithSHA1AndRC2
+_CSSMOID_PKCS5_PBKDF2
+_CSSMOID_PKCS5_PBES2
+_CSSMOID_PKCS5_PBMAC1
+_CSSMOID_PKCS5_RC2_CBC
+_CSSMOID_PKCS5_DES_EDE3_CBC
+_CSSMOID_PKCS5_RC5_CBC
+_CSSMOID_PhysicalDeliveryOfficeName
+_CSSMOID_PolicyConstraints
+_CSSMOID_PolicyMappings
+_CSSMOID_PostOfficeBox
+_CSSMOID_PostalAddress
+_CSSMOID_PostalCode
+_CSSMOID_PreferredDeliveryMethod
+_CSSMOID_PresentationAddress
+_CSSMOID_PrivateKeyUsagePeriod
+_CSSMOID_ProtocolInformation
+_CSSMOID_QT_CPS
+_CSSMOID_QT_UNOTICE
+_CSSMOID_AD_OCSP
+_CSSMOID_AD_CA_ISSUERS
+_CSSMOID_AD_TIME_STAMPING
+_CSSMOID_AD_CA_REPOSITORY
+_CSSMOID_PDA_DATE_OF_BIRTH
+_CSSMOID_PDA_PLACE_OF_BIRTH
+_CSSMOID_PDA_GENDER
+_CSSMOID_PDA_COUNTRY_CITIZEN
+_CSSMOID_PDA_COUNTRY_RESIDENCE
+_CSSMOID_OID_QCS_SYNTAX_V1
+_CSSMOID_OID_QCS_SYNTAX_V2
+_CSSMOID_ETSI_QCS_QC_COMPLIANCE
+_CSSMOID_ETSI_QCS_QC_LIMIT_VALUE
+_CSSMOID_ETSI_QCS_QC_RETENTION
+_CSSMOID_ETSI_QCS_QC_SSCD
+_CSSMOID_RSA
+_CSSMOID_RegisteredAddress
+_CSSMOID_RoleOccupant
+_CSSMOID_SHA1
+_CSSMOID_SHA224
+_CSSMOID_SHA256
+_CSSMOID_SHA384
+_CSSMOID_SHA512
+_CSSMOID_SHA1WithDSA
+_CSSMOID_SHA1WithDSA_CMS
+_CSSMOID_SHA1WithDSA_JDK
+_CSSMOID_SHA1WithRSA
+_CSSMOID_SHA224WithRSA
+_CSSMOID_SHA256WithRSA
+_CSSMOID_SHA384WithRSA
+_CSSMOID_SHA512WithRSA
+_CSSMOID_SHA1WithRSA_OIW
+_CSSMOID_RSAWithOAEP
+_CSSMOID_OAEP_MGF1
+_CSSMOID_OAEP_ID_PSPECIFIED
+_CSSMOID_SearchGuide
+_CSSMOID_SeeAlso
+_CSSMOID_SerialNumber
+_CSSMOID_ServerAuth
+_CSSMOID_SigningTime
+_CSSMOID_StateProvinceName
+_CSSMOID_StreetAddress
+_CSSMOID_SubjectAltName
+_CSSMOID_SubjectDirectoryAttributes
+_CSSMOID_SubjectEmailAddress
+_CSSMOID_SubjectKeyIdentifier
+_CSSMOID_SubjectPicture
+_CSSMOID_SubjectSignatureBitmap
+_CSSMOID_SupportedApplicationContext
+_CSSMOID_Surname
+_CSSMOID_TelephoneNumber
+_CSSMOID_TelexNumber
+_CSSMOID_TelexTerminalIdentifier
+_CSSMOID_TimeStamping
+_CSSMOID_Title
+_CSSMOID_UniqueIdentifier
+_CSSMOID_UniqueMember
+_CSSMOID_UnstructuredAddress
+_CSSMOID_UnstructuredName
+_CSSMOID_UseExemptions
+_CSSMOID_UserCertificate
+_CSSMOID_UserID
+_CSSMOID_UserPassword
+_CSSMOID_X509V1CRLIssuerNameCStruct
+_CSSMOID_X509V1CRLIssuerNameLDAP
+_CSSMOID_X509V1CRLIssuerStruct
+_CSSMOID_X509V1CRLNextUpdate
+_CSSMOID_X509V1CRLNumberOfRevokedCertEntries
+_CSSMOID_X509V1CRLRevokedCertificatesCStruct
+_CSSMOID_X509V1CRLRevokedCertificatesStruct
+_CSSMOID_X509V1CRLRevokedEntryCStruct
+_CSSMOID_X509V1CRLRevokedEntryRevocationDate
+_CSSMOID_X509V1CRLRevokedEntrySerialNumber
+_CSSMOID_X509V1CRLRevokedEntryStruct
+_CSSMOID_X509V1CRLThisUpdate
+_CSSMOID_X509V1CertificateIssuerUniqueId
+_CSSMOID_X509V1CertificateSubjectUniqueId
+_CSSMOID_X509V1IssuerName
+_CSSMOID_X509V1IssuerNameCStruct
+_CSSMOID_X509V1IssuerNameLDAP
+_CSSMOID_X509V1IssuerNameStd
+_CSSMOID_X509V1SerialNumber
+_CSSMOID_X509V1Signature
+_CSSMOID_X509V1SignatureAlgorithm
+_CSSMOID_X509V1SignatureAlgorithmParameters
+_CSSMOID_X509V1SignatureAlgorithmTBS
+_CSSMOID_X509V1SignatureCStruct
+_CSSMOID_X509V1SignatureStruct
+_CSSMOID_X509V1SubjectName
+_CSSMOID_X509V1SubjectNameCStruct
+_CSSMOID_X509V1SubjectNameLDAP
+_CSSMOID_X509V1SubjectNameStd
+_CSSMOID_X509V1SubjectPublicKey
+_CSSMOID_X509V1SubjectPublicKeyAlgorithm
+_CSSMOID_X509V1SubjectPublicKeyAlgorithmParameters
+_CSSMOID_X509V1SubjectPublicKeyCStruct
+_CSSMOID_X509V1ValidityNotAfter
+_CSSMOID_X509V1ValidityNotBefore
+_CSSMOID_X509V1Version
+_CSSMOID_X509V2CRLAllExtensionsCStruct
+_CSSMOID_X509V2CRLAllExtensionsStruct
+_CSSMOID_X509V2CRLExtensionCritical
+_CSSMOID_X509V2CRLExtensionId
+_CSSMOID_X509V2CRLExtensionType
+_CSSMOID_X509V2CRLNumberOfExtensions
+_CSSMOID_X509V2CRLRevokedEntryAllExtensionsCStruct
+_CSSMOID_X509V2CRLRevokedEntryAllExtensionsStruct
+_CSSMOID_X509V2CRLRevokedEntryExtensionCritical
+_CSSMOID_X509V2CRLRevokedEntryExtensionId
+_CSSMOID_X509V2CRLRevokedEntryExtensionType
+_CSSMOID_X509V2CRLRevokedEntryExtensionValue
+_CSSMOID_X509V2CRLRevokedEntryNumberOfExtensions
+_CSSMOID_X509V2CRLRevokedEntrySingleExtensionCStruct
+_CSSMOID_X509V2CRLRevokedEntrySingleExtensionStruct
+_CSSMOID_X509V2CRLSignedCrlCStruct
+_CSSMOID_X509V2CRLSignedCrlStruct
+_CSSMOID_X509V2CRLSingleExtensionCStruct
+_CSSMOID_X509V2CRLSingleExtensionStruct
+_CSSMOID_X509V2CRLTbsCertListCStruct
+_CSSMOID_X509V2CRLTbsCertListStruct
+_CSSMOID_X509V2CRLVersion
+_CSSMOID_X509V3Certificate
+_CSSMOID_X509V3CertificateCStruct
+_CSSMOID_X509V3CertificateExtensionCStruct
+_CSSMOID_X509V3CertificateExtensionCritical
+_CSSMOID_X509V3CertificateExtensionId
+_CSSMOID_X509V3CertificateExtensionStruct
+_CSSMOID_X509V3CertificateExtensionType
+_CSSMOID_X509V3CertificateExtensionValue
+_CSSMOID_X509V3CertificateExtensionsCStruct
+_CSSMOID_X509V3CertificateExtensionsStruct
+_CSSMOID_X509V3CertificateNumberOfExtensions
+_CSSMOID_X509V3SignedCertificate
+_CSSMOID_X509V3SignedCertificateCStruct
+_CSSMOID_X_121Address
+_CSSMOID_DOTMAC_CERT
+_CSSMOID_DOTMAC_CERT_REQ
+_CSSMOID_DOTMAC_CERT_REQ_IDENTITY
+_CSSMOID_DOTMAC_CERT_REQ_EMAIL_SIGN
+_CSSMOID_DOTMAC_CERT_REQ_EMAIL_ENCRYPT
+_CSSMOID_DOTMAC_CERT_REQ_ARCHIVE_LIST
+_CSSMOID_DOTMAC_CERT_REQ_ARCHIVE_STORE
+_CSSMOID_DOTMAC_CERT_REQ_ARCHIVE_FETCH
+_CSSMOID_DOTMAC_CERT_REQ_ARCHIVE_REMOVE
+_CSSMOID_DOTMAC_CERT_REQ_SHARED_SERVICES
+_CSSMOID_DOTMAC_CERT_REQ_VALUE_USERNAME
+_CSSMOID_DOTMAC_CERT_REQ_VALUE_PASSWORD
+_CSSMOID_DOTMAC_CERT_REQ_VALUE_HOSTNAME
+_CSSMOID_DOTMAC_CERT_REQ_VALUE_RENEW
+_CSSMOID_DOTMAC_CERT_REQ_VALUE_ASYNC
+_CSSMOID_DOTMAC_CERT_REQ_VALUE_IS_PENDING
+_CSSMOID_DOTMAC_CERT_EXTENSION
+_CSSMOID_DOTMAC_CERT_IDENTITY
+_CSSMOID_DOTMAC_CERT_EMAIL_SIGN
+_CSSMOID_DOTMAC_CERT_EMAIL_ENCRYPT
+_CSSMOID_APPLE_CERT_POLICY
+_CSSMOID_DOTMAC_CERT_POLICY
+_CSSMOID_ADC_CERT_POLICY
+_CSSMOID_MACAPPSTORE_CERT_POLICY
+_CSSMOID_MACAPPSTORE_RECEIPT_CERT_POLICY
+_CSSMOID_APPLEID_CERT_POLICY
+_CSSMOID_APPLEID_SHARING_CERT_POLICY
+_CSSMOID_MOBILE_STORE_SIGNING_POLICY
+_CSSMOID_TEST_MOBILE_STORE_SIGNING_POLICY
+_CSSMOID_APPLE_EKU_CODE_SIGNING
+_CSSMOID_APPLE_EKU_CODE_SIGNING_DEV
+_CSSMOID_APPLE_EKU_RESOURCE_SIGNING
+_CSSMOID_APPLE_EKU_ICHAT_SIGNING
+_CSSMOID_APPLE_EKU_ICHAT_ENCRYPTION
+_CSSMOID_APPLE_EKU_SYSTEM_IDENTITY
+_CSSMOID_APPLE_EKU_PASSBOOK_SIGNING
+_CSSMOID_APPLE_EKU_PROFILE_SIGNING
+_CSSMOID_APPLE_EKU_QA_PROFILE_SIGNING
+_CSSMOID_APPLE_EXTENSION
+_CSSMOID_APPLE_EXTENSION_CODE_SIGNING
+_CSSMOID_APPLE_EXTENSION_APPLE_SIGNING
+_CSSMOID_APPLE_EXTENSION_ADC_DEV_SIGNING
+_CSSMOID_APPLE_EXTENSION_ADC_APPLE_SIGNING
+_CSSMOID_APPLE_EXTENSION_PASSBOOK_SIGNING
+_CSSMOID_APPLE_EXTENSION_MACAPPSTORE_RECEIPT
+_CSSMOID_APPLE_EXTENSION_INTERMEDIATE_MARKER
+_CSSMOID_APPLE_EXTENSION_WWDR_INTERMEDIATE
+_CSSMOID_APPLE_EXTENSION_ITMS_INTERMEDIATE
+_CSSMOID_APPLE_EXTENSION_AAI_INTERMEDIATE
+_CSSMOID_APPLE_EXTENSION_APPLEID_INTERMEDIATE
+_CSSMOID_APPLE_EXTENSION_APPLEID_SHARING
+_CSSMOID_APPLE_EXTENSION_SYSINT2_INTERMEDIATE
+_CSSMOID_APPLE_EXTENSION_ESCROW_SERVICE
+_CSSMOID_PKIX_OCSP
+_CSSMOID_PKIX_OCSP_ARCHIVE_CUTOFF
+_CSSMOID_PKIX_OCSP_BASIC
+_CSSMOID_PKIX_OCSP_CRL
+_CSSMOID_PKIX_OCSP_NOCHECK
+_CSSMOID_PKIX_OCSP_NONCE
+_CSSMOID_PKIX_OCSP_RESPONSE
+_CSSMOID_PKIX_OCSP_SERVICE_LOCATOR
+_CSSM_AC_AuthCompute
+_CSSM_AC_PassThrough
+_CSSM_CL_CertAbortCache
+_CSSM_CL_CertAbortQuery
+_CSSM_CL_CertCache
+_CSSM_CL_CertCreateTemplate
+_CSSM_CL_CertDescribeFormat
+_CSSM_CL_CertGetAllFields
+_CSSM_CL_CertGetAllTemplateFields
+_CSSM_CL_CertGetFirstCachedFieldValue
+_CSSM_CL_CertGetFirstFieldValue
+_CSSM_CL_CertGetKeyInfo
+_CSSM_CL_CertGetNextCachedFieldValue
+_CSSM_CL_CertGetNextFieldValue
+_CSSM_CL_CertGroupFromVerifiedBundle
+_CSSM_CL_CertGroupToSignedBundle
+_CSSM_CL_CertSign
+_CSSM_CL_CertVerify
+_CSSM_CL_CertVerifyWithKey
+_CSSM_CL_CrlAbortCache
+_CSSM_CL_CrlAbortQuery
+_CSSM_CL_CrlAddCert
+_CSSM_CL_CrlCache
+_CSSM_CL_CrlCreateTemplate
+_CSSM_CL_CrlDescribeFormat
+_CSSM_CL_CrlGetAllCachedRecordFields
+_CSSM_CL_CrlGetAllFields
+_CSSM_CL_CrlGetFirstCachedFieldValue
+_CSSM_CL_CrlGetFirstFieldValue
+_CSSM_CL_CrlGetNextCachedFieldValue
+_CSSM_CL_CrlGetNextFieldValue
+_CSSM_CL_CrlRemoveCert
+_CSSM_CL_CrlSetFields
+_CSSM_CL_CrlSign
+_CSSM_CL_CrlVerify
+_CSSM_CL_CrlVerifyWithKey
+_CSSM_CL_FreeFieldValue
+_CSSM_CL_FreeFields
+_CSSM_CL_IsCertInCachedCrl
+_CSSM_CL_IsCertInCrl
+_CSSM_CL_PassThrough
+_CSSM_CSP_ChangeLoginAcl
+_CSSM_CSP_ChangeLoginOwner
+_CSSM_CSP_CreateAsymmetricContext
+_CSSM_CSP_CreateDeriveKeyContext
+_CSSM_CSP_CreateDigestContext
+_CSSM_CSP_CreateKeyGenContext
+_CSSM_CSP_CreateMacContext
+_CSSM_CSP_CreatePassThroughContext
+_CSSM_CSP_CreateRandomGenContext
+_CSSM_CSP_CreateSignatureContext
+_CSSM_CSP_CreateSymmetricContext
+_CSSM_CSP_GetLoginAcl
+_CSSM_CSP_GetLoginOwner
+_CSSM_CSP_GetOperationalStatistics
+_CSSM_CSP_Login
+_CSSM_CSP_Logout
+_CSSM_CSP_ObtainPrivateKeyFromPublicKey
+_CSSM_CSP_PassThrough
+_CSSM_ChangeKeyAcl
+_CSSM_ChangeKeyOwner
+_CSSM_DL_Authenticate
+_CSSM_DL_ChangeDbAcl
+_CSSM_DL_ChangeDbOwner
+_CSSM_DL_CreateRelation
+_CSSM_DL_DataAbortQuery
+_CSSM_DL_DataDelete
+_CSSM_DL_DataGetFirst
+_CSSM_DL_DataGetFromUniqueRecordId
+_CSSM_DL_DataGetNext
+_CSSM_DL_DataInsert
+_CSSM_DL_DataModify
+_CSSM_DL_DbClose
+_CSSM_DL_DbCreate
+_CSSM_DL_DbDelete
+_CSSM_DL_DbOpen
+_CSSM_DL_DestroyRelation
+_CSSM_DL_FreeNameList
+_CSSM_DL_FreeUniqueRecord
+_CSSM_DL_GetDbAcl
+_CSSM_DL_GetDbNameFromHandle
+_CSSM_DL_GetDbNames
+_CSSM_DL_GetDbOwner
+_CSSM_DL_PassThrough
+_CSSM_DecryptData
+_CSSM_DecryptDataFinal
+_CSSM_DecryptDataInit
+_CSSM_DecryptDataInitP
+_CSSM_DecryptDataP
+_CSSM_DecryptDataUpdate
+_CSSM_DeleteContext
+_CSSM_DeleteContextAttributes
+_CSSM_DeriveKey
+_CSSM_DigestData
+_CSSM_DigestDataClone
+_CSSM_DigestDataFinal
+_CSSM_DigestDataInit
+_CSSM_DigestDataUpdate
+_CSSM_EncryptData
+_CSSM_EncryptDataFinal
+_CSSM_EncryptDataInit
+_CSSM_EncryptDataInitP
+_CSSM_EncryptDataP
+_CSSM_EncryptDataUpdate
+_CSSM_FreeContext
+_CSSM_FreeKey
+_CSSM_GenerateAlgorithmParams
+_CSSM_GenerateKey
+_CSSM_GenerateKeyP
+_CSSM_GenerateKeyPair
+_CSSM_GenerateKeyPairP
+_CSSM_GenerateMac
+_CSSM_GenerateMacFinal
+_CSSM_GenerateMacInit
+_CSSM_GenerateMacUpdate
+_CSSM_GenerateRandom
+_CSSM_GetAPIMemoryFunctions
+_CSSM_GetContext
+_CSSM_GetContextAttribute
+_CSSM_GetKeyAcl
+_CSSM_GetKeyOwner
+_CSSM_GetModuleGUIDFromHandle
+_CSSM_GetPrivilege
+_CSSM_GetSubserviceUIDFromHandle
+_CSSM_GetTimeValue
+_CSSM_Init
+_CSSM_Introduce
+_CSSM_ListAttachedModuleManagers
+_CSSM_ModuleAttach
+_CSSM_ModuleDetach
+_CSSM_ModuleLoad
+_CSSM_ModuleUnload
+_CSSM_QueryKeySizeInBits
+_CSSM_QuerySize
+_CSSM_RetrieveCounter
+_CSSM_RetrieveUniqueId
+_CSSM_SetContext
+_CSSM_SetPrivilege
+_CSSM_SignData
+_CSSM_SignDataFinal
+_CSSM_SignDataInit
+_CSSM_SignDataUpdate
+_CSSM_TP_ApplyCrlToDb
+_CSSM_TP_CertCreateTemplate
+_CSSM_TP_CertGetAllTemplateFields
+_CSSM_TP_CertGroupConstruct
+_CSSM_TP_CertGroupPrune
+_CSSM_TP_CertGroupToTupleGroup
+_CSSM_TP_CertGroupVerify
+_CSSM_TP_CertReclaimAbort
+_CSSM_TP_CertReclaimKey
+_CSSM_TP_CertRemoveFromCrlTemplate
+_CSSM_TP_CertRevoke
+_CSSM_TP_CertSign
+_CSSM_TP_ConfirmCredResult
+_CSSM_TP_CrlCreateTemplate
+_CSSM_TP_CrlSign
+_CSSM_TP_CrlVerify
+_CSSM_TP_FormRequest
+_CSSM_TP_FormSubmit
+_CSSM_TP_PassThrough
+_CSSM_TP_ReceiveConfirmation
+_CSSM_TP_RetrieveCredResult
+_CSSM_TP_SubmitCredRequest
+_CSSM_TP_TupleGroupToCertGroup
+_CSSM_Terminate
+_CSSM_Unintroduce
+_CSSM_UnwrapKey
+_CSSM_UnwrapKeyP
+_CSSM_UpdateContextAttributes
+_CSSM_VerifyData
+_CSSM_VerifyDataFinal
+_CSSM_VerifyDataInit
+_CSSM_VerifyDataUpdate
+_CSSM_VerifyDevice
+_CSSM_VerifyMac
+_CSSM_VerifyMacFinal
+_CSSM_VerifyMacInit
+_CSSM_VerifyMacUpdate
+_CSSM_WrapKey
+_CSSM_WrapKeyP
+_cssmAlgToOid
+_cssmOidToAlg
+_gGuidAppleCSP
+_gGuidAppleCSPDL
+_gGuidAppleFileDL
+_gGuidAppleX509CL
+_gGuidAppleX509TP
+_gGuidAppleDotMacTP
+_gGuidAppleSdCSPDL
+_gGuidCssm
+_gGuidAppleLDAPDL
+_gGuidAppleDotMacDL
+_CSSMOID_X9_62
+_CSSMOID_X9_62_FieldType
+_CSSMOID_X9_62_PubKeyType
+_CSSMOID_X9_62_EllCurve
+_CSSMOID_X9_62_C_TwoCurve
+_CSSMOID_X9_62_PrimeCurve
+_CSSMOID_X9_62_SigType
+_CSSMOID_secp192r1
+_CSSMOID_secp256r1
+_CSSMOID_Certicom
+_CSSMOID_CerticomEllCurve
+_CSSMOID_secp112r1
+_CSSMOID_secp112r2
+_CSSMOID_secp128r1
+_CSSMOID_secp128r2
+_CSSMOID_secp160k1
+_CSSMOID_secp160r1
+_CSSMOID_secp160r2
+_CSSMOID_secp192k1
+_CSSMOID_secp224k1
+_CSSMOID_secp224r1
+_CSSMOID_secp256k1
+_CSSMOID_secp384r1
+_CSSMOID_secp521r1
+_CSSMOID_sect113r1
+_CSSMOID_sect113r2
+_CSSMOID_sect131r1
+_CSSMOID_sect131r2
+_CSSMOID_sect163k1
+_CSSMOID_sect163r1
+_CSSMOID_sect163r2
+_CSSMOID_sect193r1
+_CSSMOID_sect193r2
+_CSSMOID_sect233k1
+_CSSMOID_sect233r1
+_CSSMOID_sect239k1
+_CSSMOID_sect283k1
+_CSSMOID_sect283r1
+_CSSMOID_sect409k1
+_CSSMOID_sect409r1
+_CSSMOID_sect571k1
+_CSSMOID_sect571r1
+_CSSMOID_ecPublicKey
+_CSSMOID_ECDSA_WithSHA1
+_CSSMOID_ECDSA_WithSHA224
+_CSSMOID_ECDSA_WithSHA256
+_CSSMOID_ECDSA_WithSHA384
+_CSSMOID_ECDSA_WithSHA512
+_CSSMOID_ECDSA_WithSpecified
+
+//
+// libsecurity_keychain
+//
+_cssmErrorString
+_cssmPerror
+_kSecACLAuthorizationAny
+_kSecACLAuthorizationLogin
+_kSecACLAuthorizationGenKey
+_kSecACLAuthorizationDelete
+_kSecACLAuthorizationExportWrapped
+_kSecACLAuthorizationExportClear
+_kSecACLAuthorizationImportWrapped
+_kSecACLAuthorizationImportClear
+_kSecACLAuthorizationSign
+_kSecACLAuthorizationEncrypt
+_kSecACLAuthorizationDecrypt
+_kSecACLAuthorizationMAC
+_kSecACLAuthorizationDerive
+_kSecACLAuthorizationKeychainCreate
+_kSecACLAuthorizationKeychainDelete
+_kSecACLAuthorizationKeychainItemRead
+_kSecACLAuthorizationKeychainItemInsert
+_kSecACLAuthorizationKeychainItemModify
+_kSecACLAuthorizationKeychainItemDelete
+_kSecIdentityDomainDefault
+_kSecIdentityDomainKerberosKDC
+_kSecClass
+_kSecClassGenericPassword
+_kSecClassInternetPassword
+_kSecClassAppleSharePassword
+_kSecClassCertificate
+_kSecClassKey
+_kSecClassIdentity
+_kSecAttrAccess
+_kSecAttrAccessGroup
+_kSecAttrAccessible
+_kSecAttrAccessibleWhenUnlocked
+_kSecAttrAccessibleAfterFirstUnlock
+_kSecAttrAccessibleAlways
+_kSecAttrAccessibleWhenUnlockedThisDeviceOnly
+_kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
+_kSecAttrAccessibleAlwaysThisDeviceOnly
+_kSecAttrCreationDate
+_kSecAttrModificationDate
+_kSecAttrDescription
+_kSecAttrComment
+_kSecAttrCreator
+_kSecAttrType
+_kSecAttrLabel
+_kSecAttrIsInvisible
+_kSecAttrIsNegative
+_kSecAttrAccount
+_kSecAttrService
+_kSecAttrGeneric
+_kSecAttrSecurityDomain
+_kSecAttrServer
+_kSecAttrProtocol
+_kSecAttrAuthenticationType
+_kSecAttrPort
+_kSecAttrPath
+_kSecAttrVolume
+_kSecAttrAddress
+_kSecAttrAFPServerSignature
+_kSecAttrAlias
+_kSecAttrSubject
+_kSecAttrIssuer
+_kSecAttrSerialNumber
+_kSecAttrSubjectKeyID
+_kSecAttrPublicKeyHash
+_kSecAttrCertificateType
+_kSecAttrCertificateEncoding
+_kSecAttrKeyClass
+_kSecAttrApplicationLabel
+_kSecAttrIsPermanent
+_kSecAttrIsPrivate
+_kSecAttrIsModifiable
+_kSecAttrApplicationTag
+_kSecAttrKeyCreator
+_kSecAttrKeyType
+_kSecAttrKeySizeInBits
+_kSecAttrEffectiveKeySize
+_kSecAttrStartDate
+_kSecAttrEndDate
+_kSecAttrIsSensitive
+_kSecAttrWasAlwaysSensitive
+_kSecAttrIsExtractable
+_kSecAttrWasNeverExtractable
+_kSecAttrCanEncrypt
+_kSecAttrCanDecrypt
+_kSecAttrCanDerive
+_kSecAttrCanSign
+_kSecAttrCanVerify
+_kSecAttrCanSignRecover
+_kSecAttrCanVerifyRecover
+_kSecAttrCanWrap
+_kSecAttrCanUnwrap
+_kSecAttrScriptCode
+_kSecAttrHasCustomIcon
+_kSecAttrCRLType
+_kSecAttrCRLEncoding
+_kSecAttrSynchronizable
+_kSecAttrSynchronizableAny
+_kSecAttrTombstone
+_kSecMatchPolicy
+_kSecMatchItemList
+_kSecMatchSearchList
+_kSecMatchIssuers
+_kSecMatchEmailAddressIfPresent
+_kSecMatchSubjectContains
+_kSecMatchSubjectStartsWith
+_kSecMatchSubjectEndsWith
+_kSecMatchSubjectWholeString
+_kSecMatchCaseInsensitive
+_kSecMatchDiacriticInsensitive
+_kSecMatchWidthInsensitive
+_kSecMatchTrustedOnly
+_kSecMatchValidOnDate
+_kSecMatchLimit
+_kSecMatchLimitOne
+_kSecMatchLimitAll
+_kSecReturnData
+_kSecReturnAttributes
+_kSecReturnRef
+_kSecReturnPersistentRef
+_kSecValueData
+_kSecValueRef
+_kSecValuePersistentRef
+_kSecUseItemList
+_kSecUseKeychain
+_kSecAttrProtocolFTP
+_kSecAttrProtocolFTPAccount
+_kSecAttrProtocolHTTP
+_kSecAttrProtocolIRC
+_kSecAttrProtocolNNTP
+_kSecAttrProtocolPOP3
+_kSecAttrProtocolSMTP
+_kSecAttrProtocolSOCKS
+_kSecAttrProtocolIMAP
+_kSecAttrProtocolLDAP
+_kSecAttrProtocolAppleTalk
+_kSecAttrProtocolAFP
+_kSecAttrProtocolTelnet
+_kSecAttrProtocolSSH
+_kSecAttrProtocolFTPS
+_kSecAttrProtocolHTTPS
+_kSecAttrProtocolHTTPProxy
+_kSecAttrProtocolHTTPSProxy
+_kSecAttrProtocolFTPProxy
+_kSecAttrProtocolSMB
+_kSecAttrProtocolRTSP
+_kSecAttrProtocolRTSPProxy
+_kSecAttrProtocolDAAP
+_kSecAttrProtocolEPPC
+_kSecAttrProtocolIPP
+_kSecAttrProtocolNNTPS
+_kSecAttrProtocolLDAPS
+_kSecAttrProtocolTelnetS
+_kSecAttrProtocolIMAPS
+_kSecAttrProtocolIRCS
+_kSecAttrProtocolPOP3S
+_kSecAttrAuthenticationTypeNTLM
+_kSecAttrAuthenticationTypeMSN
+_kSecAttrAuthenticationTypeDPA
+_kSecAttrAuthenticationTypeRPA
+_kSecAttrAuthenticationTypeHTTPBasic
+_kSecAttrAuthenticationTypeHTTPDigest
+_kSecAttrAuthenticationTypeHTMLForm
+_kSecAttrAuthenticationTypeDefault
+_kSecAttrKeyClassPublic
+_kSecAttrKeyClassPrivate
+_kSecAttrKeyClassSymmetric
+_kSecPrivateKeyAttrs
+_kSecPublicKeyAttrs
+_kSecImportExportPassphrase
+_kSecImportExportKeychain
+_kSecImportExportAccess
+_kSecImportItemLabel
+_kSecImportItemKeyID
+_kSecImportItemTrust
+_kSecImportItemCertChain
+_kSecImportItemIdentity
+_kSecPolicyAppleX509Basic
+_kSecPolicyAppleSSL
+_kSecPolicyAppleSMIME
+_kSecPolicyAppleEAP
+_kSecPolicyAppleIPsec
+_kSecPolicyAppleiChat
+_kSecPolicyApplePKINITClient
+_kSecPolicyApplePKINITServer
+_kSecPolicyAppleCodeSigning
+_kSecPolicyMacAppStoreReceipt
+_kSecPolicyAppleIDValidation
+_kSecPolicyAppleTimeStamping
+_kSecPolicyAppleRevocation
+_kSecPolicyApplePassbookSigning
+_kSecPolicyAppleMobileStore
+_kSecPolicyAppleEscrowService
+_kSecPolicyAppleProfileSigner
+_kSecPolicyAppleQAProfileSigner
+_kSecPolicyAppleTestMobileStore
+_kSecPolicyOid
+_kSecPolicyName
+_kSecPolicyClient
+_kSecPolicyRevocationFlags
+_kSecPolicyTeamIdentifier
+_kSecPolicyKU_DigitalSignature
+_kSecPolicyKU_NonRepudiation
+_kSecPolicyKU_KeyEncipherment
+_kSecPolicyKU_DataEncipherment
+_kSecPolicyKU_KeyAgreement
+_kSecPolicyKU_KeyCertSign
+_kSecPolicyKU_CRLSign
+_kSecPolicyKU_EncipherOnly
+_kSecPolicyKU_DecipherOnly
+_kSecPropertyTypeTitle
+_kSecPropertyTypeError
+_kSecPropertyKeyType
+_kSecPropertyKeyLabel
+_kSecPropertyKeyLocalizedLabel
+_kSecPropertyKeyValue
+_kSecPropertyTypeWarning
+_kSecPropertyTypeSuccess
+_kSecPropertyTypeSection
+_kSecPropertyTypeData
+_kSecPropertyTypeString
+_kSecPropertyTypeURL
+_kSecPropertyTypeDate
+_kSecOIDADC_CERT_POLICY
+_kSecOIDAPPLE_CERT_POLICY
+_kSecOIDAPPLE_EKU_CODE_SIGNING
+_kSecOIDAPPLE_EKU_CODE_SIGNING_DEV
+_kSecOIDAPPLE_EKU_ICHAT_ENCRYPTION
+_kSecOIDAPPLE_EKU_ICHAT_SIGNING
+_kSecOIDAPPLE_EKU_RESOURCE_SIGNING
+_kSecOIDAPPLE_EKU_SYSTEM_IDENTITY
+_kSecOIDAPPLE_EXTENSION
+_kSecOIDAPPLE_EXTENSION_ADC_APPLE_SIGNING
+_kSecOIDAPPLE_EXTENSION_ADC_DEV_SIGNING
+_kSecOIDAPPLE_EXTENSION_APPLE_SIGNING
+_kSecOIDAPPLE_EXTENSION_CODE_SIGNING
+_kSecOIDAuthorityInfoAccess
+_kSecOIDAuthorityKeyIdentifier
+_kSecOIDBasicConstraints
+_kSecOIDBiometricInfo
+_kSecOIDCSSMKeyStruct
+_kSecOIDCertIssuer
+_kSecOIDCertificatePolicies
+_kSecOIDClientAuth
+_kSecOIDCollectiveStateProvinceName
+_kSecOIDCollectiveStreetAddress
+_kSecOIDCommonName
+_kSecOIDCountryName
+_kSecOIDCrlDistributionPoints
+_kSecOIDCrlNumber
+_kSecOIDCrlReason
+_kSecOIDDOTMAC_CERT_EMAIL_ENCRYPT
+_kSecOIDDOTMAC_CERT_EMAIL_SIGN
+_kSecOIDDOTMAC_CERT_EXTENSION
+_kSecOIDDOTMAC_CERT_IDENTITY
+_kSecOIDDOTMAC_CERT_POLICY
+_kSecOIDDeltaCrlIndicator
+_kSecOIDDescription
+_kSecOIDEKU_IPSec
+_kSecOIDEmailAddress
+_kSecOIDEmailProtection
+_kSecOIDExtendedKeyUsage
+_kSecOIDExtendedKeyUsageAny
+_kSecOIDExtendedUseCodeSigning
+_kSecOIDGivenName
+_kSecOIDHoldInstructionCode
+_kSecOIDInvalidityDate
+_kSecOIDIssuerAltName
+_kSecOIDIssuingDistributionPoint
+_kSecOIDIssuingDistributionPoints
+_kSecOIDKERBv5_PKINIT_KP_CLIENT_AUTH
+_kSecOIDKERBv5_PKINIT_KP_KDC
+_kSecOIDKeyUsage
+_kSecOIDLocalityName
+_kSecOIDMS_NTPrincipalName
+_kSecOIDMicrosoftSGC
+_kSecOIDNameConstraints
+_kSecOIDNetscapeCertSequence
+_kSecOIDNetscapeCertType
+_kSecOIDNetscapeSGC
+_kSecOIDOCSPSigning
+_kSecOIDOrganizationName
+_kSecOIDOrganizationalUnitName
+_kSecOIDPolicyConstraints
+_kSecOIDPolicyMappings
+_kSecOIDPrivateKeyUsagePeriod
+_kSecOIDQC_Statements
+_kSecOIDSerialNumber
+_kSecOIDServerAuth
+_kSecOIDStateProvinceName
+_kSecOIDStreetAddress
+_kSecOIDSubjectAltName
+_kSecOIDSubjectDirectoryAttributes
+_kSecOIDSubjectEmailAddress
+_kSecOIDSubjectInfoAccess
+_kSecOIDSubjectKeyIdentifier
+_kSecOIDSubjectPicture
+_kSecOIDSubjectSignatureBitmap
+_kSecOIDSurname
+_kSecOIDTimeStamping
+_kSecOIDTitle
+_kSecOIDUseExemptions
+_kSecOIDX509V1CertificateIssuerUniqueId
+_kSecOIDX509V1CertificateSubjectUniqueId
+_kSecOIDX509V1IssuerName
+_kSecOIDX509V1IssuerNameCStruct
+_kSecOIDX509V1IssuerNameLDAP
+_kSecOIDX509V1IssuerNameStd
+_kSecOIDX509V1SerialNumber
+_kSecOIDX509V1Signature
+_kSecOIDX509V1SignatureAlgorithm
+_kSecOIDX509V1SignatureAlgorithmParameters
+_kSecOIDX509V1SignatureAlgorithmTBS
+_kSecOIDX509V1SignatureCStruct
+_kSecOIDX509V1SignatureStruct
+_kSecOIDX509V1SubjectName
+_kSecOIDX509V1SubjectNameCStruct
+_kSecOIDX509V1SubjectNameLDAP
+_kSecOIDX509V1SubjectNameStd
+_kSecOIDX509V1SubjectPublicKey
+_kSecOIDX509V1SubjectPublicKeyAlgorithm
+_kSecOIDX509V1SubjectPublicKeyAlgorithmParameters
+_kSecOIDX509V1SubjectPublicKeyCStruct
+_kSecOIDX509V1ValidityNotAfter
+_kSecOIDX509V1ValidityNotBefore
+_kSecOIDX509V1Version
+_kSecOIDX509V3Certificate
+_kSecOIDX509V3CertificateCStruct
+_kSecOIDX509V3CertificateExtensionCStruct
+_kSecOIDX509V3CertificateExtensionCritical
+_kSecOIDX509V3CertificateExtensionId
+_kSecOIDX509V3CertificateExtensionStruct
+_kSecOIDX509V3CertificateExtensionType
+_kSecOIDX509V3CertificateExtensionValue
+_kSecOIDX509V3CertificateExtensionsCStruct
+_kSecOIDX509V3CertificateExtensionsStruct
+_kSecOIDX509V3CertificateNumberOfExtensions
+_kSecOIDX509V3SignedCertificate
+_kSecOIDX509V3SignedCertificateCStruct
+_kSecOIDSRVName
+_kSecRandomDefault
+_kSecTrustEvaluationDate
+_kSecTrustExtendedValidation
+_kSecTrustOrganizationName
+_kSecTrustResultDetails
+_kSecTrustResultValue
+_kSecTrustRevocationChecked
+_kSecTrustRevocationValidUntilDate
+_SecACLCopySimpleContents
+_SecACLCreateFromSimpleContents
+_SecACLCreateWithSimpleContents
+_SecACLCopyContents
+_SecACLGetAuthorizations
+_SecACLCopyAuthorizations
+_SecACLGetTypeID
+_SecACLRemove
+_SecACLSetAuthorizations
+_SecACLUpdateAuthorizations
+_SecACLSetContents
+_SecACLSetSimpleContents
+_SecAccessCopyACLList
+_SecAccessCopySelectedACLList
+_SecAccessCopyMatchingACLList
+_SecAccessCreate
+_SecAccessCreateFromOwnerAndACL
+_SecAccessCreateWithOwnerAndACL
+_SecAccessCreateWithTrustedApplications
+_SecAccessGetOwnerAndACL
+_SecAccessCopyOwnerAndACL
+_SecAccessGetTypeID
+_SecCertifcateBundleExport
+_SecCertificateAddToKeychain
+_SecCertificateBundleExport
+_SecCertificateBundleImport
+_SecCertificateCopyCommonName
+_SecCertificateCopyData
+_SecCertificateCopySubjectComponent
+_SecCertificateCopyEmailAddresses
+_SecCertificateCopyFieldValues
+_SecCertificateCopyFirstFieldValue
+_SecCertificateCopyPreference
+_SecCertificateCopyPreferred
+_SecCertificateCopyPublicKey
+_SecCertificateCopyPublicKeySHA1DigestFromCertificateData
+_SecCertificateCopySubjectSummary
+_SecCertificateCreateFromData
+_SecCertificateCreateWithBytes
+_SecCertificateCreateWithData
+_SecCertificateCreateWithDataP
+_SecCertificateFindByEmail
+_SecCertificateFindByIssuerAndSN
+_SecCertificateFindBySubjectKeyID
+_SecCertificateGetAlgorithmID
+_SecCertificateGetBytePtr
+_SecCertificateGetCLHandle
+_SecCertificateGetCommonName
+_SecCertificateGetData
+_SecCertificateGetEmailAddress
+_SecCertificateGetIssuer
+_SecCertificateGetLength
+_SecCertificateGetSHA1Digest
+_SecCertificateGetSubject
+_SecCertificateGetType
+_SecCertificateGetTypeID
+_SecCertificateInferLabel
+_SecCertificateIsSelfSigned
+_SecCertificateRequestCreate
+_SecCertificateRequestGetTypeID
+_SecCertificateRequestSubmit
+_SecCertificateRequestGetType
+_SecCertificateRequestGetResult
+_SecCertificateReleaseFieldValues
+_SecCertificateFindRequest
+_SecCertificateRequestGetData
+_SecCertificateReleaseFirstFieldValue
+_SecCertificateSetPreference
+_SecCertificateSetPreferred
+_SecCertificateCopyValues
+_SecCertificateCopyLongDescription
+_SecCertificateCopyShortDescription
+_SecCertificateCopyEscrowRoots
+_kSecCertificateProductionEscrowKey
+_kSecCertificateEscrowFileName
+_SecCopyErrorMessageString
+_SecDigestGetData
+_SecIdentityAddPreferenceItem
+_SecIdentityCompare
+_SecIdentityCopyCertificate
+_SecIdentityCopyFromPreferenceItem
+_SecIdentityCopyPreference
+_SecIdentityCopyPreferred
+_SecIdentityCopyPrivateKey
+_SecIdentityCopySystemIdentity
+_SecIdentityCreate
+_SecIdentityCreateWithCertificate
+_SecIdentityFindPreferenceItem
+_SecIdentityGetTypeID
+_SecIdentitySearchCopyNext
+_SecIdentitySearchCreate
+_SecIdentitySearchCreateWithAttributes
+_SecIdentitySearchCreateWithPolicy
+_SecIdentitySearchGetTypeID
+_SecIdentitySetPreference
+_SecIdentitySetPreferred
+_SecIdentitySetSystemIdentity
+_SecIdentityUpdatePreferenceItem
+_SecInferLabelFromX509Name
+_SecItemAdd
+_SecItemCopyDisplayNames
+_SecItemCopyMatching
+_SecItemDelete
+_SecItemUpdate
+__SecItemGetPersistentReference
+_kSecAttrKeyTypeRSA
+_kSecAttrKeyTypeDSA
+_kSecAttrKeyTypeAES
+_kSecAttrKeyTypeDES
+_kSecAttrKeyType3DES
+_kSecAttrKeyTypeRC4
+_kSecAttrKeyTypeRC2
+_kSecAttrKeyTypeCAST
+_kSecAttrKeyTypeECDSA
+_kSecAttrKeyTypeEC
+_kSecAttrPRF
+_kSecAttrPRFHmacAlgSHA1
+_kSecAttrPRFHmacAlgSHA224
+_kSecAttrPRFHmacAlgSHA256
+_kSecAttrPRFHmacAlgSHA384
+_kSecAttrPRFHmacAlgSHA512
+_kSecAttrSalt
+_kSecAttrRounds
+_SecECKeyGetNamedCurve
+_SecItemExport
+_SecItemImport
+_SecKeyCopyPublicBytes
+_SecKeyCreate
+_SecKeyCreatePair
+_SecKeyCreateWithCSSMKey
+_SecKeyDecrypt
+_SecKeyEncrypt
+_SecKeyGenerate
+_SecKeyGeneratePair
+_SecKeyGetAlgorithmID
+_SecKeyGetAlgorithmId
+_SecKeyGetBlockSize
+_SecKeyGetCSPHandle
+_SecKeyGetCSSMKey
+_SecKeyGetCredentials
+_SecKeyGetStrengthInBits
+_SecKeyGetTypeID
+_SecKeyImportPair
+_SecKeyRawSign
+_SecKeyRawVerify
+_SecKeySignDigest
+_SecKeyVerifyDigest
+_SecKeyGenerateSymmetric
+_SecKeyCreateFromData
+_SecKeyCreateFromPublicData
+_SecKeyRawVerifyOSX
+_SecKeyGeneratePairAsync
+_SecKeyDeriveFromPassword
+_SecKeyWrapSymmetric
+_SecKeyUnwrapSymmetric
+_SecKeychainAddCallback
+_SecKeychainAddDBToKeychainList
+_SecKeychainAddGenericPassword
+_SecKeychainAddIToolsPassword
+_SecKeychainAddInternetPassword
+_SecKeychainAttributeInfoForItemID
+_SecKeychainChangePassword
+_SecKeychainCopyAccess
+_SecKeychainCopyBlob
+_SecKeychainCopyDefault
+_SecKeychainCopyDomainDefault
+_SecKeychainCopyDomainSearchList
+_SecKeychainCopyLogin
+_SecKeychainCopySearchList
+_SecKeychainCopySettings
+_SecKeychainCopySignature
+_SecKeychainCreate
+_SecKeychainCreateNew
+_SecKeychainCreateWithBlob
+_SecKeychainDBIsInKeychainList
+_SecKeychainDelete
+_SecKeychainErrFromOSStatus
+_SecKeychainFindGenericPassword
+_SecKeychainFindInternetPassword
+_SecKeychainFreeAttributeInfo
+_SecKeychainGetCSPHandle
+_SecKeychainGetDLDBHandle
+_SecKeychainGetPath
+_SecKeychainGetPreferenceDomain
+_SecKeychainGetStatus
+_SecKeychainGetTypeID
+_SecKeychainGetUserInteractionAllowed
+_SecKeychainGetVersion
+_SecKeychainIsValid
+_SecKeychainItemAdd
+_SecKeychainItemAddNoUI
+_SecKeychainItemCopyAccess
+_SecKeychainItemCopyAllExtendedAttributes
+_SecKeychainItemCopyAttributesAndData
+_SecKeychainItemCopyAttributesAndEncryptedData
+_SecKeychainItemCopyContent
+_SecKeychainItemCopyExtendedAttribute
+_SecKeychainItemCopyFromRecordIdentifier
+_SecKeychainItemCopyKeychain
+_SecKeychainItemCopyFromPersistentReference
+_SecKeychainItemCopyRecordIdentifier
+_SecKeychainItemCreateCopy
+_SecKeychainItemCreateFromContent
+_SecKeychainItemCreateFromEncryptedContent
+_SecKeychainItemCreateNew
+_SecKeychainItemCreatePersistentReference
+_SecKeychainItemDelete
+_SecKeychainItemFindFirst
+_SecKeychainItemFreeAttributesAndData
+_SecKeychainItemFreeContent
+_SecKeychainItemGetAttribute
+_SecKeychainItemGetDLDBHandle
+_SecKeychainItemGetData
+_SecKeychainItemGetTypeID
+_SecKeychainItemGetUniqueRecordID
+_SecKeychainItemExport
+_SecKeychainItemImport
+_SecKeychainItemModifyAttributesAndData
+_SecKeychainItemModifyEncryptedData
+_SecKeychainItemModifyContent
+_SecKeychainItemSetAccess
+_SecKeychainItemSetAttribute
+_SecKeychainItemSetData
+_SecKeychainItemSetExtendedAttribute
+_SecKeychainItemUpdate
+_SecKeychainListCopyKeychainAtIndex
+_SecKeychainListGetCount
+_SecKeychainListRemoveKeychain
+_SecKeychainLock
+_SecKeychainLockAll
+_SecKeychainLogin
+_SecKeychainStash
+_SecKeychainLogout
+_SecKeychainMakeFromFullPath
+_SecKeychainOpen
+_SecKeychainOpenWithGuid
+_SecKeychainRecodeKeychain
+_SecKeychainRemoveCallback
+_SecKeychainRemoveDBFromKeychainList
+_SecKeychainRemoveFromSearchList
+_SecKeychainResetLogin
+_SecKeychainSearchCopyNext
+_SecKeychainSearchCreateForCertificateByEmail
+_SecKeychainSearchCreateForCertificateByIssuerAndSN
+_SecKeychainSearchCreateForCertificateBySubjectKeyID
+_SecKeychainSearchCreateFromAttributes
+_SecKeychainSearchCreateFromAttributesExtended
+_SecKeychainSearchGetTypeID
+_SecKeychainSetAccess
+_SecKeychainSetDefault
+_SecKeychainSetDomainDefault
+_SecKeychainSetDomainSearchList
+_SecKeychainSetPreferenceDomain
+_SecKeychainSetSearchList
+_SecKeychainSetServerMode
+_SecKeychainSetSettings
+_SecKeychainSetUserInteractionAllowed
+_SecKeychainSystemKeychainCheckWouldDeadlock
+__SecKeychainSyncUpdate
+_SecKeychainUnlock
+_SecKeychainVerifyKeyStorePassphrase
+_SecKeychainChangeKeyStorePassphrase
+_SecGenericPasswordCreate
+_SecPasswordSetInitialAccess
+_SecPasswordAction
+_SecPKCS12Import
+_SecPolicyCreateBasicX509
+_SecPolicyCreateRevocation
+_SecPolicyCreateSSL
+_SecPolicyCreateWithOID
+_SecPolicyCreateWithProperties
+_SecPolicyGetOID
+_SecPolicyGetTPHandle
+_SecPolicyGetTypeID
+_SecPolicyGetValue
+_SecPolicySearchCopyNext
+_SecPolicySearchCreate
+_SecPolicySearchGetTypeID
+_SecPolicySetValue
+_SecPolicyCopy
+_SecPolicyCopyAll
+_SecPolicyCopyProperties
+_SecPolicySetProperties
+_SecPolicyCopyEscrowRootCertificates
+_SecTrustCopyAnchorCertificates
+_SecTrustCopyCustomAnchorCertificates
+_SecTrustCopyExceptions
+_SecTrustCopyExtendedResult
+_SecTrustCopyPolicies
+_SecTrustCopyProperties
+_SecTrustCopyPublicKey
+_SecTrustCopyResult
+_SecTrustCreateWithCertificates
+_SecTrustEvaluate
+_SecTrustEvaluateAsync
+_SecTrustGetCertificateAtIndex
+_SecTrustGetCertificateCount
+_SecTrustGetCSSMAnchorCertificates
+_SecTrustGetCssmResult
+_SecTrustGetCssmResultCode
+_SecTrustGetNetworkFetchAllowed
+_SecTrustGetResult
+_SecTrustGetTrustResult
+_SecTrustGetTPHandle
+_SecTrustGetTypeID
+_SecTrustGetUserTrust
+_SecTrustGetVerifyTime
+_SecTrustSetAnchorCertificates
+_SecTrustSetAnchorCertificatesOnly
+_SecTrustSetExceptions
+_SecTrustSetKeychains
+_SecTrustSetNetworkFetchAllowed
+_SecTrustSetOCSPResponse
+_SecTrustSetOptions
+_SecTrustSetParameters
+_SecTrustSetPolicies
+_SecTrustSetUserTrust
+_SecTrustSetUserTrustLegacy
+_SecTrustSetVerifyDate
+_SecTrustedApplicationCopyData
+_SecTrustedApplicationCreateFromPath
+_SecTrustedApplicationCreateApplicationGroup
+_SecTrustedApplicationGetTypeID
+_SecTrustedApplicationIsUpdateCandidate
+_SecTrustedApplicationMakeEquivalent
+_SecTrustedApplicationRemoveEquivalence
+_SecTrustedApplicationSetData
+_SecTrustedApplicationUseAlternateSystem
+_SecTrustedApplicationValidateWithPath
+_SecTrustedApplicationCreateFromRequirement
+_SecTrustedApplicationCopyExternalRepresentation
+_SecTrustedApplicationCreateWithExternalRepresentation
+_SecTrustedApplicationCopyRequirement
+_SecTrustSettingsEvaluateCert
+_SecTrustSettingsCopyTrustSettings
+_SecTrustSettingsSetTrustSettings
+_SecTrustSettingsRemoveTrustSettings
+_SecTrustSettingsCopyCertificates
+_SecTrustSettingsCopyModificationDate
+_SecTrustSettingsCreateExternalRepresentation
+_SecTrustSettingsImportExternalRepresentation
+_SecTrustSettingsSetTrustSettingsExternal
+_SecTrustSettingsCopyQualifiedCerts
+_SecTrustSettingsCopyUnrestrictedRoots
+_SecKeychainSetBatchMode
+_SecCertificateGetAuthorityKeyID
+_SecCertificateGetSubjectKeyID
+_SecCertificateGetCRLDistributionPoints
+_SecCertificateGetOCSPResponders
+_SecCertificateGetCAIssuers
+_SecCertificateShow
+_SecCertificateCopyIssuerSequence
+_SecCertificateCopySubjectSequence
+_SecCertificateGetNormalizedIssuerContent
+_SecCertificateGetNormalizedSubjectContent
+_SecCertificateHasSubject
+_SecCertificateHasCriticalSubjectAltName
+_SecCertificateHasUnknownCriticalExtension
+_SecCertificateIsValid
+_SecCertificateIsValidX
+_SecCertificateNotValidBefore
+_SecCertificateNotValidAfter
+_SecCertificateCopyAttributeDictionary
+_SecCertificateCreateFromAttributeDictionary
+_SecCertificateCopyPublicKeyP
+_SecCertificateGetBasicConstraints
+_SecCertificateGetPolicyConstraints
+_SecCertificateGetPolicyMappings
+_SecCertificateGetCertificatePolicies
+_SecCertificateGetInhibitAnyPolicySkipCerts
+_SecCertificateGetPublicKeyAlgorithm
+_SecCertificateGetPublicKeyData
+_SecCertificateCreateWithPEM
+_SecCertificateCopySerialNumber
+_SecCertificateCopyNormalizedIssuerContent
+_SecCertificateCopyNormalizedSubjectContent
+_SecDERItemCopyOIDDecimalRepresentation
+_SecAbsoluteTimeFromDateContent
+_SecWrapRecoveryPasswordWithAnswers
+_SecUnwrapRecoveryPasswordWithAnswers
+_SecCreateRecoveryPassword
+_kSecRecVersionNumber
+_kSecRecQuestions
+_kSecRecLocale
+_kSecRecIV
+_kSecRecWrappedPassword
+_SecFDERecoveryWrapCRSKWithPubKey
+_SecFDERecoveryUnwrapCRSKWithPrivKey
+_SecKeychainSearchCreateForCertificateByIssuerAndSN_CF
+_SecRandomCopyBytes
+_SecRandomCopyData
+__SecKeychainBackupSyncable
+__SecKeychainRestoreSyncable
+
+//
+// libsecurity_manifest
+//
+_SecManifestGetVersion
+_SecManifestCompare
+_SecManifestCreate
+_SecManifestRelease
+_SecManifestVerifySignature
+_SecManifestVerifySignatureWithPolicy
+_SecManifestCreateSignature
+_SecManifestAddObject
+_SecManifestAddSigner
+_SecureDownloadCreateWithTicket
+_SecureDownloadUpdateWithData
+_SecureDownloadFinished
+_SecureDownloadRelease
+_SecureDownloadCopyName
+_SecureDownloadCopyURLs
+_SecureDownloadCopyCreationDate
+_SecureDownloadGetDownloadSize
+__SecureDownloadCreateTicketXML
+_SecureDownloadCopyTicketLocation
+
+//
+// libsecurity_mds
+//
+_MDS_Initialize
+_MDS_Install
+_MDS_Terminate
+_MDS_Uninstall
+_MDS_InstallFile
+_MDS_RemoveSubservice
+
+//
+// libsecurity_smime
+//
+_SecArenaPoolCreate
+_SecArenaPoolFree
+_SecCmsContentInfoGetBulkKey
+_SecCmsContentInfoGetBulkKeySize
+_SecCmsContentInfoGetChildContentInfo
+_SecCmsContentInfoGetContent
+_SecCmsContentInfoGetContentEncAlg
+_SecCmsContentInfoGetContentEncAlgTag
+_SecCmsContentInfoGetContentTypeOID
+_SecCmsContentInfoGetContentTypeTag
+_SecCmsContentInfoGetInnerContent
+_SecCmsContentInfoSetBulkKey
+_SecCmsContentInfoSetContentData
+_SecCmsContentInfoSetContentDigestedData
+_SecCmsContentInfoSetContentEncAlg
+_SecCmsContentInfoSetContentEncAlgID
+_SecCmsContentInfoSetContentEncryptedData
+_SecCmsContentInfoSetContentEnvelopedData
+_SecCmsContentInfoSetContentSignedData
+_SecCmsContentInfoSetContentOther
+_SecCmsDecoderCreate
+_SecCmsDecoderDestroy
+_SecCmsDecoderFinish
+_SecCmsDecoderUpdate
+_SecCmsDigestContextCancel
+_SecCmsDigestContextFinishMultiple
+_SecCmsDigestContextStartMultiple
+_SecCmsDigestContextUpdate
+_SecCmsDigestedDataCreate
+_SecCmsDigestedDataDestroy
+_SecCmsDigestedDataGetContentInfo
+_SecCmsEncoderCreate
+_SecCmsEncoderDestroy
+_SecCmsEncoderFinish
+_SecCmsEncoderUpdate
+_SecCmsEncryptedDataCreate
+_SecCmsEncryptedDataDestroy
+_SecCmsEncryptedDataGetContentInfo
+_SecCmsEnvelopedDataAddRecipient
+_SecCmsEnvelopedDataCreate
+_SecCmsEnvelopedDataDestroy
+_SecCmsEnvelopedDataGetContentInfo
+_SecCmsMessageContainsCertsOrCrls
+_SecCmsMessageContentLevel
+_SecCmsMessageContentLevelCount
+_SecCmsMessageCopy
+_SecCmsMessageCreate
+_SecCmsMessageDecode
+_SecCmsMessageDestroy
+_SecCmsMessageEncode
+_SecCmsMessageGetArena
+_SecCmsMessageGetContent
+_SecCmsMessageGetContentInfo
+_SecCmsMessageIsContentEmpty
+_SecCmsMessageIsEncrypted
+_SecCmsMessageIsSigned
+_SecCmsMessageContainsTSTInfo
+_SecCmsMessageSetTSACallback
+_SecCmsMessageSetTSAContext
+_SecCmsTSAGetDefaultContext
+_SecCmsTSADefaultCallback
+_SecTSAResponseCopyDEREncoding
+_kTSAContextKeyURL
+_kTSAContextKeyNoCerts
+_kTSADebugContextKeyBadReq
+_kTSADebugContextKeyBadNonce
+_SecCmsRecipientInfoCreate
+_SecCmsRecipientInfoCreateWithSubjKeyID
+_SecCmsRecipientInfoCreateWithSubjKeyIDFromCert
+_SecCmsRecipientInfoDestroy
+_SecCmsSignedDataAddCertChain
+_SecCmsSignedDataAddCertList
+_SecCmsSignedDataAddCertificate
+_SecCmsSignedDataAddSignerInfo
+_SecCmsSignedDataContainsCertsOrCrls
+_SecCmsSignedDataCreate
+_SecCmsSignedDataCreateCertsOnly
+_SecCmsSignedDataDestroy
+_SecCmsSignedDataGetCertificateList
+_SecCmsSignedDataGetContentInfo
+_SecCmsSignedDataGetDigestAlgs
+_SecCmsSignedDataGetSignerInfo
+_SecCmsSignedDataGetSignerInfos
+_SecCmsSignedDataHasDigests
+_SecCmsSignedDataImportCerts
+_SecCmsSignedDataSetDigests
+_SecCmsSignedDataSignerInfoCount
+_SecCmsSignedDataVerifyCertsOnly
+_SecCmsSignedDataVerifySignerInfo
+_SecCmsSignerInfoAddCounterSignature
+_SecCmsSignerInfoAddMSSMIMEEncKeyPrefs
+_SecCmsSignerInfoAddSMIMECaps
+_SecCmsSignerInfoAddSMIMEEncKeyPrefs
+_SecCmsSignerInfoAddSigningTime
+_SecCmsSignerInfoCreate
+_SecCmsSignerInfoCreateWithSubjKeyID
+_SecCmsSignerInfoDestroy
+_SecCmsSignerInfoGetCertList
+_SecCmsSignerInfoGetDigestAlg
+_SecCmsSignerInfoGetDigestAlgTag
+_SecCmsSignerInfoGetSignerCommonName
+_SecCmsSignerInfoGetSignerEmailAddress
+_SecCmsSignerInfoGetSigningCertificate
+_SecCmsSignerInfoGetSigningTime
+_SecCmsSignerInfoGetTimestampTime
+_SecCmsSignerInfoGetVerificationStatus
+_SecCmsSignerInfoGetEncDigest
+_SecCmsSignerInfoIncludeCerts
+_SecCmsSignerInfoSaveSMIMEProfile
+_SecCmsUtilVerificationStatusToString
+_SecSMIMEFindBulkAlgForRecipients
+
+//
+// libsecurity_ssl
+//
+_SSLAddDistinguishedName
+_SSLClose
+_SSLContextGetTypeID
+_SSLCreateContext
+_SSLCreateContextWithRecordFuncs
+_SSLDisposeContext
+_SSLGetAllowsAnyRoot
+_SSLGetAllowsExpiredCerts
+_SSLGetAllowsExpiredRoots
+_SSLGetBufferedReadSize
+_SSLGetClientCertificateState
+_SSLGetClientSideAuthenticate
+_SSLGetConnection
+_SSLGetDiffieHellmanParams
+_SSLGetEnableCertVerify
+_SSLGetEnabledCiphers
+_SSLGetNegotiatedCipher
+_SSLGetNegotiatedProtocolVersion
+_SSLGetNumberEnabledCiphers
+_SSLGetNumberSupportedCiphers
+_SSLGetPeerCertificates
+_SSLCopyPeerCertificates
+_SSLCopyPeerTrust
+_SSLGetPeerDomainName
+_SSLGetPeerDomainNameLength
+_SSLGetPeerID
+_SSLGetPeerSecTrust
+_SSLGetProtocolVersion
+_SSLGetProtocolVersionEnabled
+_SSLGetProtocolVersionMax
+_SSLGetProtocolVersionMin
+_SSLGetResumableSessionInfo
+_SSLGetRsaBlinding
+_SSLGetSessionOption
+_SSLGetSessionState
+_SSLGetSupportedCiphers
+_SSLCopyTrustedRoots
+_SSLSetTrustedLeafCertificates
+_SSLCopyTrustedLeafCertificates
+_SSLHandshake
+_SSLInternalClientRandom
+_SSLInternalMasterSecret
+_SSLInternalServerRandom
+_SSLGetCipherSizes
+_SSLInternal_PRF
+_SSLNewContext
+_SSLRead
+_SSLSetAllowsAnyRoot
+_SSLSetAllowsExpiredCerts
+_SSLSetAllowsExpiredRoots
+_SSLSetCertificate
+_SSLGetCertificate
+_SSLSetClientSideAuthenticate
+_SSLSetConnection
+_SSLSetDatagramHelloCookie
+_SSLSetMaxDatagramRecordSize
+_SSLGetMaxDatagramRecordSize
+_SSLSetDiffieHellmanParams
+_SSLSetEnableCertVerify
+_SSLSetEnabledCiphers
+_SSLSetEncryptionCertificate
+_SSLGetEncryptionCertificate
+_SSLSetIOFuncs
+_SSLSetPeerDomainName
+_SSLSetPeerID
+_SSLSetProtocolVersion
+_SSLSetProtocolVersionEnabled
+_SSLSetProtocolVersionMax
+_SSLSetProtocolVersionMin
+_SSLSetRecordContext
+_SSLSetRsaBlinding
+_SSLSetTrustedRoots
+_SSLWrite
+_SSLSetSessionCacheTimeout
+_SSLSetSessionOption
+_SSLInternalSetMasterSecretFunction
+_SSLInternalSetSessionTicket
+_SSLSetAllowAnonymousCiphers
+_SSLGetAllowAnonymousCiphers
+_SSLCopyDistinguishedNames
+_SSLSetCertificateAuthorities
+_SSLCopyCertificateAuthorities
+_SSLGetNegotiatedCurve
+_SSLGetNumberOfECDSACurves
+_SSLGetECDSACurves
+_SSLSetECDSACurves
+_SSLGetNumberOfClientAuthTypes
+_SSLGetClientAuthTypes
+_SSLGetNegotiatedClientAuthType
+_SSLGetNumberOfSignatureAlgorithms
+_SSLGetSignatureAlgorithms
+_SSLNewDatagramContext
+_SSLGetDatagramWriteSize
+_SSLSetPSKSharedSecret
+_SSLSetPSKIdentity
+
+//
+// libsecurity_transform
+//
+_SecTransformCreateFromExternalRepresentation
+_SecTransformCreateValidatorForCFtype
+_SecTransformCopyExternalRepresentation
+_SecTransformConnectTransforms
+_SecTransformSetAttribute
+_SecTransformGetAttribute
+_SecTransformFindByName
+_SecTransformExecute
+_SecTransformExecuteAsync
+_SecNullTransformCreate
+_SecDigestTransformCreate
+_SecCreateMaskGenerationFunctionTransform
+_SecTransformCreate
+_SecTransformRegister
+_SecTransformNoData
+_kSecDigestMD2
+_kSecDigestMD4
+_kSecDigestMD5
+_kSecDigestSHA1
+_kSecDigestSHA2
+_kSecDigestHMACSHA1
+_kSecDigestHMACMD5
+_kSecDigestHMACKeyAttribute
+_kSecDigestHMACSHA2
+_SecExternalSourceTransformCreate
+_SecExternalSourceSetValue
+_kSecDecodeTypeAttribute
+_CreateSecTransformErrorRef
+_kSecTransformAbortOriginatorKey
+_SecGroupTransformHasMember
+_kSecDigestTypeAttribute
+_kSecDigestLengthAttribute
+_kSecOAEPEncodingParametersAttributeName
+_kSecTransformInputAttributeName
+_kSecTransformDebugAttributeName
+_kSecTransformOutputAttributeName
+_kSecTransformTransformName
+_kSecTransformAbortAttributeName
+_kSecPaddingNoneKey
+_kSecPaddingPKCS1Key
+_kSecPaddingPKCS5Key
+_kSecPaddingPKCS7Key
+_kSecPaddingOAEPKey
+_kSecModeNoneKey
+_kSecModeECBKey
+_kSecModeCBCKey
+_kSecModeCFBKey
+_kSecModeOFBKey
+_kSecEncryptKey
+_kSecPaddingKey
+_kSecIVKey
+_kSecEncryptionMode
+_SecEncryptTransformCreate
+_SecDecryptTransformCreate
+_SecDecodeTransformCreate
+_SecEncodeTransformCreate
+_SecSignTransformCreate
+_SecVerifyTransformCreate
+_kSecBase32Encoding
+_kSecBase64Encoding
+_kSecZLibEncoding
+_kSecEncodeLineLengthAttribute
+_kSecEncodeTypeAttribute
+_kSecCompressionRatio
+_kSecKeyAttributeName
+_kSecSignatureAttributeName
+_kSecInputIsAttributeName
+_kSecInputIsPlainText
+_kSecInputIsDigest
+_kSecInputIsRaw
+_kSecTransformActionCanExecute
+_kSecTransformActionStartingExecution
+_kSecTransformActionFinalize
+_kSecTransformActionProcessData
+_SecTransformSetAttributeAction
+_SecGroupTransformFindLastTransform
+_SecGroupTransformFindMonitor
+_SecTransformDisconnectTransforms
+_SecTransformDotForDebugging
+_SecCreateCollectTransform
+_SecTransformGetTypeID
+_SecGroupTransformGetTypeID
+_SecTransformCreateGroupTransform
+_SecTransformSetDataAction
+_SecTransformSetTransformAction
+_SecTranformCustomGetAttribute
+_SecTransformCustomSetAttribute
+_SecTransformPushbackAttribute
+_kSecTransformActionExternalizeExtraData
+_kSecTransformActionInternalizeExtraData
+_kSecTransformActionAttributeNotification
+_kSecTransformActionAttributeValidation
+_kSecTransformErrorDomain
+_kSecTransformPreviousErrorKey
+_SecTransformCreateReadTransformWithReadStream
+_kSecLineLength64
+_kSecLineLength76
+_SecKeyCreatePublicFromPrivate
+
+//
+// libsecurity_utilities
+//
+_secdebug_internal
+
+//
+// libSecureObjectSync
+//
+#include "SecureObjectSync/SOSExports.exp-in"
+
+// sec/Security
+_SecFrameworkCopyLocalizedString
+_SecPasswordCopyDefaultPasswordLength
+_SecPasswordGenerate
+_SecPasswordIsPasswordWeak
+_kSecPasswordDefaultForType
+_kSecPasswordMinLengthKey
+_kSecPasswordMaxLengthKey
+_kSecPasswordAllowedCharactersKey
+_kSecPasswordRequiredCharactersKey
+_kSecPasswordDisallowedCharacters
+_kSecPasswordCantStartWithChars
+_kSecPasswordCantEndWithChars
+_kSecPasswordContainsNoMoreThanNSpecificCharacters
+_kSecPasswordContainsAtLeastNSpecificCharacters
+_kSecPasswordContainsNoMoreThanNConsecutiveIdenticalCharacters
+_kSecPasswordCharacters
+_kSecPasswordCharacterCount
+_kSecPasswordGroupSize
+_kSecPasswordNumberOfGroups
+_kSecPasswordSeparator
+
+
+//
+// utilities
+//
+_add_security_log_hanlder
index d1143ad16e2d2f28e85fa50505b59734dc1ed8ad..957c72f1001de9231929e0bb1bd20780aad8f6a2 100644 (file)
@@ -67,7 +67,7 @@ void SymmetricKeyInfoProvider::QueryKeySizeInBits(
 {
        /* FIXME - do we ever need to calculate RC2 effective size here? */
        keySize.LogicalKeySizeInBits = keySize.EffectiveKeySizeInBits =
 {
        /* FIXME - do we ever need to calculate RC2 effective size here? */
        keySize.LogicalKeySizeInBits = keySize.EffectiveKeySizeInBits =
-               mKey.length() * 8;
+               (uint32)(mKey.length() * 8);
 }
 
 /* 
 }
 
 /* 
index 85d3bbbd2865f7a667e86ed5b9d869dfcaca9967..23ab820315dad42124ef5b837a9668eef3a1f0df 100644 (file)
@@ -318,7 +318,7 @@ void BlockCryptor::update(
        /* 
         * en/decrypt even blocks in (remaining) inp.  
         */
        /* 
         * en/decrypt even blocks in (remaining) inp.  
         */
-       unsigned leftOver = uInSize % mInBlockSize;
+       size_t leftOver = uInSize % mInBlockSize;
        if((leftOver == 0) && needLeftOver) {
                /* 
                 * Even blocks coming in, but we really need to leave some data
        if((leftOver == 0) && needLeftOver) {
                /* 
                 * Even blocks coming in, but we really need to leave some data
index 1f101799b3f0f59a922bf6c931703aa35891e46f..13ceb8b74808b502ecc80bbc31f2a9d442c16cd5 100644 (file)
@@ -26,7 +26,6 @@
 #define _BLOCK_CRYPTOR_H_
 
 #include "AppleCSPContext.h"
 #define _BLOCK_CRYPTOR_H_
 
 #include "AppleCSPContext.h"
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
 
 /*
  * Base class for AppleCSPContexts associated with BlockCryptObjects. 
 
 /*
  * Base class for AppleCSPContexts associated with BlockCryptObjects. 
index ae5f1eefa6ef0b56ea432c0014c77e094971fe22..f09c83f7eee267b79d91decbd65b310de1cbdf61 100644 (file)
@@ -74,7 +74,7 @@ void DeriveKey_DH (
                        errorLog0("DeriveKey_DH: no pub_key, no Param\n");
                        CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
                }
                        errorLog0("DeriveKey_DH: no pub_key, no Param\n");
                        CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
                }
-               pubKeyBn = BN_bin2bn(Param.Data, Param.Length, NULL);
+               pubKeyBn = BN_bin2bn(Param.Data, (int)Param.Length, NULL);
                if(pubKeyBn == NULL) {
                        CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);
                }
                if(pubKeyBn == NULL) {
                        CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);
                }
@@ -94,7 +94,7 @@ void DeriveKey_DH (
                 * to deal with that if they really need privSize bytes.
                 */
                assert((uint32)rtn <= privSize);
                 * to deal with that if they really need privSize bytes.
                 */
                assert((uint32)rtn <= privSize);
-               uint32 toMove = keyData->Length;
+               CSSM_SIZE toMove = keyData->Length;
                if((uint32)rtn < toMove) {
                        toMove = (uint32)rtn;
                }
                if((uint32)rtn < toMove) {
                        toMove = (uint32)rtn;
                }
index ab65f28e4cf0d1e08387b5ab200441bf138e75b0..3ad1b392460579c674cb75906a710b21d26a5556 100644 (file)
@@ -235,7 +235,7 @@ void DHKeyPairGenContext::generate(
                }
                
                /* ensure caller's key size matches the incoming params */
                }
                
                /* ensure caller's key size matches the incoming params */
-               uint32 paramKeyBytes;
+               size_t paramKeyBytes;
                if(privValueLen) {
                        paramKeyBytes = (privValueLen + 7) / 8;
                }
                if(privValueLen) {
                        paramKeyBytes = (privValueLen + 7) / 8;
                }
index 98096261786ddeabc367b4505ef3e440769a7c76..3b92db4aeeefcd0817a0fccf9ea25e23fd7d2cbc 100644 (file)
@@ -164,11 +164,11 @@ DH *rawCssmKeyToDh(
     {
         if(isPub) {
             crtn = DHPublicKeyDecode(dhKey, hdr->Format,
     {
         if(isPub) {
             crtn = DHPublicKeyDecode(dhKey, hdr->Format,
-                cssmKey.KeyData.Data, cssmKey.KeyData.Length);
+                cssmKey.KeyData.Data, (unsigned)cssmKey.KeyData.Length);
         }
         else {
             crtn = DHPrivateKeyDecode(dhKey, hdr->Format,
         }
         else {
             crtn = DHPrivateKeyDecode(dhKey, hdr->Format,
-                cssmKey.KeyData.Data, cssmKey.KeyData.Length);
+                cssmKey.KeyData.Data, (unsigned)cssmKey.KeyData.Length);
         }
     }
     
         }
     }
     
index 60c5df6bf7af545c0a85072bdc7bd8efa2858f48..3556c887590e54f44ed2077fd1eb672261c379f2 100644 (file)
@@ -168,7 +168,7 @@ void CryptKit::FEEDContext::encryptBlock(
        assert(mFeeFeed != NULL);
        frtn = feeFEEDEncryptBlock(mFeeFeed,
                (unsigned char *)plainText,
        assert(mFeeFeed != NULL);
        frtn = feeFEEDEncryptBlock(mFeeFeed,
                (unsigned char *)plainText,
-               plainTextLen,
+               (unsigned int)plainTextLen,
                (unsigned char *)cipherText,
                &actMoved,
                final ? 1 : 0);
                (unsigned char *)cipherText,
                &actMoved,
                final ? 1 : 0);
@@ -195,7 +195,7 @@ void CryptKit::FEEDContext::decryptBlock(
        assert(mFeeFeed != NULL);
        frtn = feeFEEDDecryptBlock(mFeeFeed,
                (unsigned char *)cipherText,
        assert(mFeeFeed != NULL);
        frtn = feeFEEDDecryptBlock(mFeeFeed,
                (unsigned char *)cipherText,
-               inBlockSize(),
+               (unsigned int)inBlockSize(),
                (unsigned char *)plainText,
                &actMoved,
                final ? 1 : 0);
                (unsigned char *)plainText,
                &actMoved,
                final ? 1 : 0);
@@ -229,10 +229,10 @@ size_t CryptKit::FEEDContext::inputSize(
         */
        unsigned inSize;
        if(encoding()) {
         */
        unsigned inSize;
        if(encoding()) {
-               inSize = feeFEEDPlainTextSize(mFeeFeed, outSize, 0);
+               inSize = feeFEEDPlainTextSize(mFeeFeed, (unsigned int)outSize, 0);
        }
        else {
        }
        else {
-               inSize = feeFEEDCipherTextSize(mFeeFeed, outSize, 0);
+               inSize = feeFEEDCipherTextSize(mFeeFeed, (unsigned int)outSize, 0);
        }
        
        /* account for possible pending buffered input */
        }
        
        /* account for possible pending buffered input */
@@ -242,8 +242,8 @@ size_t CryptKit::FEEDContext::inputSize(
        
        /* round up to next block size, then lop off one...anything from
         * blockSize*n to (blockSize*n)-1 has same effect */
        
        /* 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;
+       unsigned inBlocks = (unsigned int)((inSize + inBlockSize()) / inBlockSize());
+       inSize = (unsigned int)(inBlocks * inBlockSize()) - 1;
        bprintf(("--- FEEDContext::inputSize  inSize 0x%x outSize 0x%x\n",
                inSize, outSize));
        return inSize;
        bprintf(("--- FEEDContext::inputSize  inSize 0x%x outSize 0x%x\n",
                inSize, outSize));
        return inSize;
@@ -255,10 +255,10 @@ size_t CryptKit::FEEDContext::outputSize(
 {
        size_t rtn;
        if(encoding()) {
 {
        size_t rtn;
        if(encoding()) {
-               rtn = feeFEEDCipherTextSize(mFeeFeed, inSize + inBufSize(), final ? 1 : 0);
+               rtn = feeFEEDCipherTextSize(mFeeFeed, (unsigned int)(inSize + inBufSize()), final ? 1 : 0);
        }
        else {
        }
        else {
-               rtn = feeFEEDPlainTextSize(mFeeFeed, inSize + inBufSize(), final ? 1 : 0);
+               rtn = feeFEEDPlainTextSize(mFeeFeed, (unsigned int)(inSize + inBufSize()), final ? 1 : 0);
        }
        bprintf(("--- FEEDContext::outputSize inSize 0x%x outSize 0x%x final %d\n",
                inSize, rtn, final));
        }
        bprintf(("--- FEEDContext::outputSize inSize 0x%x outSize 0x%x final %d\n",
                inSize, rtn, final));
@@ -398,7 +398,7 @@ void CryptKit::FEEDExpContext::encryptBlock(
        assert(mFeeFeedExp != NULL);
        frtn = feeFEEDExpEncryptBlock(mFeeFeedExp,
                (unsigned char *)plainText,
        assert(mFeeFeedExp != NULL);
        frtn = feeFEEDExpEncryptBlock(mFeeFeedExp,
                (unsigned char *)plainText,
-               plainTextLen,
+               (unsigned int)plainTextLen,
                (unsigned char *)cipherText,
                &actMoved,
                final ? 1 : 0);
                (unsigned char *)cipherText,
                &actMoved,
                final ? 1 : 0);
@@ -425,7 +425,7 @@ void CryptKit::FEEDExpContext::decryptBlock(
        assert(mFeeFeedExp != NULL);
        frtn = feeFEEDExpDecryptBlock(mFeeFeedExp,
                (unsigned char *)cipherText,
        assert(mFeeFeedExp != NULL);
        frtn = feeFEEDExpDecryptBlock(mFeeFeedExp,
                (unsigned char *)cipherText,
-               inBlockSize(),
+               (unsigned int)inBlockSize(),
                (unsigned char *)plainText,
                &actMoved,
                final ? 1 : 0);
                (unsigned char *)plainText,
                &actMoved,
                final ? 1 : 0);
@@ -484,14 +484,14 @@ static feeReturn ecdhKdf(
                int32ToBytes(counter, counterBytes);
                CC_SHA1_Update(&sha1, counterBytes, 4);
                if(sharedInfoLen) {
                int32ToBytes(counter, counterBytes);
                CC_SHA1_Update(&sha1, counterBytes, 4);
                if(sharedInfoLen) {
-                       CC_SHA1_Update(&sha1, sharedInfo, sharedInfoLen);
+                       CC_SHA1_Update(&sha1, sharedInfo, (CC_LONG)sharedInfoLen);
                }
                CC_SHA1_Final(digOut, &sha1);
                
                /* digest --> output */
                unsigned toMove = CC_SHA1_DIGEST_LENGTH;
                if(toMove > bytesToGo) {
                }
                CC_SHA1_Final(digOut, &sha1);
                
                /* digest --> output */
                unsigned toMove = CC_SHA1_DIGEST_LENGTH;
                if(toMove > bytesToGo) {
-                       toMove = bytesToGo;
+                       toMove = (unsigned int)bytesToGo;
                }
                memmove(outp, digOut, toMove);
                
                }
                memmove(outp, digOut, toMove);
                
index f20bff626bb846ad935e4944935ac34469c3515f..9db7a700bd69e65b829000df06e08da5ddb7ff24 100644 (file)
@@ -215,7 +215,7 @@ feePubKey CryptKit::rawCssmKeyToFee(
                                                        /* FEE, public key, native byte stream */
                                                        frtn = feePubKeyInitFromPubBlob(feeKey,
                                                                cssmKey.KeyData.Data,
                                                        /* FEE, public key, native byte stream */
                                                        frtn = feePubKeyInitFromPubBlob(feeKey,
                                                                cssmKey.KeyData.Data,
-                                                               cssmKey.KeyData.Length);
+                                                               (unsigned int)cssmKey.KeyData.Length);
                                                        break;
                                                default:
                                                        badFormat = true;
                                                        break;
                                                default:
                                                        badFormat = true;
@@ -234,7 +234,7 @@ feePubKey CryptKit::rawCssmKeyToFee(
                                                        /* FEE, private key, native byte stream */
                                                        frtn = feePubKeyInitFromPrivBlob(feeKey,
                                                                cssmKey.KeyData.Data,
                                                        /* FEE, private key, native byte stream */
                                                        frtn = feePubKeyInitFromPrivBlob(feeKey,
                                                                cssmKey.KeyData.Data,
-                                                               cssmKey.KeyData.Length);
+                                                               (unsigned int)cssmKey.KeyData.Length);
                                                        break;
                                                default:
                                                        badFormat = true;
                                                        break;
                                                default:
                                                        badFormat = true;
index 90220ba0767964bc07f182d2c63744643029fbce..831ce376b696b413b6697d05a604840a5448fdd9 100644 (file)
@@ -338,7 +338,7 @@ void CryptKit::FEEKeyPairGenContext::generate(
        feeReturn frtn = feePubKeyInitFromPrivDataKeyBits( 
                fPrivBinKey.feeKey(),
                (unsigned char *)seed->data(),
        feeReturn frtn = feePubKeyInitFromPrivDataKeyBits( 
                fPrivBinKey.feeKey(),
                (unsigned char *)seed->data(),
-               seed->length(),
+               (unsigned int)seed->length(),
                keyBits,
                primeType,
                curveType,
                keyBits,
                primeType,
                curveType,
index 12bdfecd680d5f6625ccb1c5611e70ecf53bf8ce..74fa0959fc67a8be85474b1f30a3246ceb2dc479 100644 (file)
@@ -99,7 +99,7 @@ void CryptKit::FEERawSigner::sign(
        feeSig                  fsig;
        feeReturn               frtn;
        unsigned char   *feeSig;
        feeSig                  fsig;
        feeReturn               frtn;
        unsigned char   *feeSig;
-       unsigned                feeSigLen;
+       unsigned                feeSigLen=0;
        
        if(mFeeKey == NULL) {
                throwCryptKit(FR_BadPubKey, "FEERawSigner::sign (no key)");
        
        if(mFeeKey == NULL) {
                throwCryptKit(FR_BadPubKey, "FEERawSigner::sign (no key)");
@@ -110,7 +110,7 @@ void CryptKit::FEERawSigner::sign(
        }
        frtn = feeSigSign(fsig,
                (unsigned char *)data,
        }
        frtn = feeSigSign(fsig,
                (unsigned char *)data,
-               dataLen,
+               (unsigned)dataLen,
                mFeeKey);
        if(frtn == FR_Success) {
                frtn = feeSigData(fsig, &feeSig, &feeSigLen);
                mFeeKey);
        if(frtn == FR_Success) {
                frtn = feeSigData(fsig, &feeSig, &feeSigLen);
@@ -149,7 +149,7 @@ void CryptKit::FEERawSigner::verify(
        }
        frtn = feeSigVerify(fsig,
                (unsigned char *)data,
        }
        frtn = feeSigVerify(fsig,
                (unsigned char *)data,
-               dataLen,
+               (unsigned int)dataLen,
                mFeeKey);
        feeSigFree(fsig);
        if(frtn) {
                mFeeKey);
        feeSigFree(fsig);
        if(frtn) {
@@ -186,7 +186,7 @@ void CryptKit::FEEECDSASigner::sign(
        }
        frtn = feeECDSASign(mFeeKey,
                (unsigned char *)data,   // data to be signed
        }
        frtn = feeECDSASign(mFeeKey,
                (unsigned char *)data,   // data to be signed
-               dataLen,                                // in bytes
+               (unsigned int)dataLen,                          // in bytes
                mRandFcn, 
                mRandRef,
                &feeSig,
                mRandFcn, 
                mRandRef,
                &feeSig,
@@ -220,7 +220,7 @@ void CryptKit::FEEECDSASigner::verify(
        frtn = feeECDSAVerify((unsigned char *)sig,
                sigLen,
                (unsigned char *)data,
        frtn = feeECDSAVerify((unsigned char *)sig,
                sigLen,
                (unsigned char *)data,
-               dataLen,
+               (unsigned int)dataLen,
                mFeeKey);
        if(frtn) {
                throwCryptKit(frtn, NULL);
                mFeeKey);
        if(frtn) {
                throwCryptKit(frtn, NULL);
index 8b7f8f6c22e1894ff218a9c3d894d6dce1194f85..c5e144ef21029b92d1257d816f410a0564a50d3c 100644 (file)
@@ -25,7 +25,6 @@
 #ifndef        _FEE_SIGNATURE_OBJECT_H_
 #define _FEE_SIGNATURE_OBJECT_H_
 
 #ifndef        _FEE_SIGNATURE_OBJECT_H_
 #define _FEE_SIGNATURE_OBJECT_H_
 
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
 #include <security_cryptkit/feePublicKey.h>
 #include <security_cryptkit/feeECDSA.h>
 #include "FEECSPUtils.h"
 #include <security_cryptkit/feePublicKey.h>
 #include <security_cryptkit/feeECDSA.h>
 #include "FEECSPUtils.h"
index 7cd95e75bae9e72e6b2adfeb784e154f6536c86d..1c3bf71dc2f8f8bfc1750b3257740afc4000f8ba 100644 (file)
@@ -25,7 +25,6 @@
 #ifndef __HMACSHA1__
 #define __HMACSHA1__
 
 #ifndef __HMACSHA1__
 #define __HMACSHA1__
 
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
 #include <Security/cssmtype.h>
 #include <pbkdDigest.h>
 #include <CommonCrypto/CommonDigest.h>
 #include <Security/cssmtype.h>
 #include <pbkdDigest.h>
 #include <CommonCrypto/CommonDigest.h>
index b2b2aee19021ef3f32abc010397d4b1869ea40ad..18531cb4ecb234bc59c8b325ff6969b004850136 100644 (file)
@@ -35,7 +35,7 @@ void MD2Object::digestUpdate(
        if(isDone()) {
                throw std::runtime_error("MD2 digestUpdate after final");
        }
        if(isDone()) {
                throw std::runtime_error("MD2 digestUpdate after final");
        }
-       CC_MD2_Update(&mCtx, (unsigned char *)data, len);
+       CC_MD2_Update(&mCtx, (unsigned char *)data, (CC_LONG)len);
 }
 
 void MD2Object::digestFinal(
 }
 
 void MD2Object::digestFinal(
index 8c5caa7217443ff8f4173f83da93f87516033539..b247e3b81bebbe9b9b01f2098fc15fdc081b0e89 100644 (file)
@@ -23,7 +23,6 @@
 #ifndef        _MD2_OBJECT_H_
 #define _MD2_OBJECT_H_
 
 #ifndef        _MD2_OBJECT_H_
 #define _MD2_OBJECT_H_
 
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
 #include <security_cdsa_utilities/digestobject.h>
 #include <CommonCrypto/CommonDigest.h>
 
 #include <security_cdsa_utilities/digestobject.h>
 #include <CommonCrypto/CommonDigest.h>
 
index 91353fd7381824ed5a7fc636acb016d37bf74f56..67e273281ea2bb113c1778637dc0cda41683f1fc 100644 (file)
@@ -133,7 +133,7 @@ void MacLegacyContext::init(const Context &context, bool isSigning)
                CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
        }
        
                CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
        }
        
-       OSStatus ortn = hmacLegacyInit(mHmac, keyData, keyLen);
+       OSStatus ortn = hmacLegacyInit(mHmac, keyData, (UInt32)keyLen);
        if(ortn) {
                MacOSError::throwMe(ortn);
        }
        if(ortn) {
                MacOSError::throwMe(ortn);
        }
@@ -143,7 +143,7 @@ void MacLegacyContext::update(const CssmData &data)
 {
        OSStatus ortn = hmacLegacyUpdate(mHmac,
                data.data(),
 {
        OSStatus ortn = hmacLegacyUpdate(mHmac,
                data.data(),
-               data.length());
+               (UInt32)data.length());
        if(ortn) {
                MacOSError::throwMe(ortn);
        }
        if(ortn) {
                MacOSError::throwMe(ortn);
        }
index 7b9deb5f6b33189b37f42faf7bc4cbed40df0a0e..b73fc470d1dece7267a9a30a6bd92d9be44456bb 100644 (file)
@@ -562,7 +562,7 @@ void DSAKeyPairGenContext::generate(
        if(paramData != NULL) {
                /* this contains the DER encoding of a NSS_DSAAlgParams */
                CSSM_RETURN crtn = DSADecodeAlgParams(algParams, paramData->Data,
        if(paramData != NULL) {
                /* this contains the DER encoding of a NSS_DSAAlgParams */
                CSSM_RETURN crtn = DSADecodeAlgParams(algParams, paramData->Data,
-                       paramData->Length, coder);
+                       (unsigned)paramData->Length, coder);
                if(crtn) {
                        CssmError::throwMe(crtn);
                }
                if(crtn) {
                        CssmError::throwMe(crtn);
                }
@@ -623,7 +623,7 @@ void DSAKeyPairGenContext::generate(
        CssmData *seedData = context.get<CssmData>(CSSM_ATTRIBUTE_SEED);
        if(seedData) {
                seed = seedData->data();
        CssmData *seedData = context.get<CssmData>(CSSM_ATTRIBUTE_SEED);
        if(seedData) {
                seed = seedData->data();
-               seedLen = seedData->length();
+               seedLen = (unsigned)seedData->length();
        }
 
        /* generate the params, temp alloc from SecNssCoder  */
        }
 
        /* generate the params, temp alloc from SecNssCoder  */
index 8bc2cb15e3249a537fccf47fe90dee8d77bfe890..c5cd8886996717f66ef83ee821af7e0a6e1c679a 100644 (file)
@@ -1,12 +1,12 @@
 /*
  * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
 /*
  * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- * 
+ *
  * The contents of this file constitute Original Code as defined in and are
  * subject to the Apple Public Source License Version 1.2 (the 'License').
  * You may not use this file except in 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 contents of this file constitute Original Code as defined in and are
  * subject to the Apple Public Source License Version 1.2 (the 'License').
  * You may not use this file except in compliance with the License. Please obtain
  * a copy of the License at http://www.apple.com/publicsource and read it before
  * using this file.
- * 
+ *
  * This Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
  * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
  * This Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
  * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
@@ -19,7 +19,7 @@
 /*
  * RSA_DSA_keys.h - key pair support for RSA/DSA
  */
 /*
  * RSA_DSA_keys.h - key pair support for RSA/DSA
  */
+
 #ifndef        _RSA_DSA_KEYS_H_
 #define _RSA_DSA_KEYS_H_
 
 #ifndef        _RSA_DSA_KEYS_H_
 #define _RSA_DSA_KEYS_H_
 
 #define DSA_MAX_KEY_SIZE               4096
 #define DSA_KEY_BITS_MASK              (64 - 1)        /* these bits must be zero */
                                                                                        /* i.e., aligned to 64 bits */
 #define DSA_MAX_KEY_SIZE               4096
 #define DSA_KEY_BITS_MASK              (64 - 1)        /* these bits must be zero */
                                                                                        /* i.e., aligned to 64 bits */
-                                                                                       
+
 #define RSA_MAX_KEY_SIZE                       4096
 #define RSA_MAX_PUB_EXPONENT_SIZE      64
 
 /* Those max RSA sizes can be overridden with these system preferences */
 #define RSA_MAX_KEY_SIZE                       4096
 #define RSA_MAX_PUB_EXPONENT_SIZE      64
 
 /* Those max RSA sizes can be overridden with these system preferences */
-#define kRSAKeySizePrefsDomain         "com.apple.crypto"
+#define kRSAKeySizePrefsDomain         "com.apple.security"
 #define kRSAMaxKeySizePref                     CFSTR("RSAMaxKeySize")
 #define kRSAMaxPublicExponentPref      CFSTR("RSAMaxPublicExponent")
 
 #define kRSAMaxKeySizePref                     CFSTR("RSAMaxKeySize")
 #define kRSAMaxPublicExponentPref      CFSTR("RSAMaxPublicExponent")
 
@@ -68,21 +68,21 @@ public:
                CSSM_KEYATTR_FLAGS      &attrFlags);    /* IN/OUT */
 
        RSA                                             *mRsaKey;
                CSSM_KEYATTR_FLAGS      &attrFlags);    /* IN/OUT */
 
        RSA                                             *mRsaKey;
-       
+
        bool isOaep()                           { return mOaep; }
        const CSSM_DATA &label()        { return mLabel; }
        void setOaep(
                const CSSM_DATA         &label);
 private:
        bool isOaep()                           { return mOaep; }
        const CSSM_DATA &label()        { return mLabel; }
        void setOaep(
                const CSSM_DATA         &label);
 private:
-       /* 
-        * optional fields for OEAP keys 
-        * (mKeyHeader.AlgorithmId == CSSM_ALGMODE_PKCS1_EME_OAEP) 
+       /*
+        * optional fields for OEAP keys
+        * (mKeyHeader.AlgorithmId == CSSM_ALGMODE_PKCS1_EME_OAEP)
         */
        bool                                    mOaep;
        CssmAutoData                    mLabel;
 };
 
         */
        bool                                    mOaep;
        CssmAutoData                    mLabel;
 };
 
-class RSAKeyPairGenContext : 
+class RSAKeyPairGenContext :
        public AppleCSPContext, private AppleKeyPairGenContext  {
 public:
        RSAKeyPairGenContext(
        public AppleCSPContext, private AppleKeyPairGenContext  {
 public:
        RSAKeyPairGenContext(
@@ -91,31 +91,31 @@ public:
                        AppleCSPContext(session) {}
 
        ~RSAKeyPairGenContext() { }
                        AppleCSPContext(session) {}
 
        ~RSAKeyPairGenContext() { }
-       
+
        /* no init functionality, but we need to implement it */
        void init(
        /* no init functionality, but we need to implement it */
        void init(
-               const Context &, 
+               const Context &,
                bool) { }
                bool) { }
-               
+
        // this one is specified in, and called from, CSPFullPluginSession
        void generate(
        // this one is specified in, and called from, CSPFullPluginSession
        void generate(
-               const Context   &context, 
-               CssmKey                 &pubKey, 
+               const Context   &context,
+               CssmKey                 &pubKey,
                CssmKey                 &privKey);
                CssmKey                 &privKey);
-               
+
        // this one is specified in, and called from, AppleKeyPairGenContext
        void generate(
                const Context   &context,
        // this one is specified in, and called from, AppleKeyPairGenContext
        void generate(
                const Context   &context,
-               BinaryKey               &pubBinKey,     
+               BinaryKey               &pubBinKey,
                BinaryKey               &privBinKey,
                uint32                  &keySize);
                BinaryKey               &privBinKey,
                uint32                  &keySize);
-       
+
 };     /* KeyPairGenContext */
 
 /*
  * CSPKeyInfoProvider for RSA keys
  */
 };     /* KeyPairGenContext */
 
 /*
  * CSPKeyInfoProvider for RSA keys
  */
-class RSAKeyInfoProvider : public CSPKeyInfoProvider 
+class RSAKeyInfoProvider : public CSPKeyInfoProvider
 {
 private:
        RSAKeyInfoProvider(
 {
 private:
        RSAKeyInfoProvider(
@@ -156,7 +156,7 @@ public:
        DSA                                             *mDsaKey;
 };
 
        DSA                                             *mDsaKey;
 };
 
-class DSAKeyPairGenContext : 
+class DSAKeyPairGenContext :
        public AppleCSPContext, private AppleKeyPairGenContext  {
 public:
        DSAKeyPairGenContext(
        public AppleCSPContext, private AppleKeyPairGenContext  {
 public:
        DSAKeyPairGenContext(
@@ -165,33 +165,33 @@ public:
                        AppleCSPContext(session), mGenAttrs(NULL) {}
 
        ~DSAKeyPairGenContext() { freeGenAttrs(); }
                        AppleCSPContext(session), mGenAttrs(NULL) {}
 
        ~DSAKeyPairGenContext() { freeGenAttrs(); }
-       
+
        /* no init functionality, but we need to implement it */
        void init(
        /* no init functionality, but we need to implement it */
        void init(
-               const Context &, 
+               const Context &,
                bool) { }
                bool) { }
-               
+
        // this one is specified in, and called from, CSPFullPluginSession
        void generate(
        // this one is specified in, and called from, CSPFullPluginSession
        void generate(
-               const Context   &context, 
-               CssmKey                 &pubKey, 
+               const Context   &context,
+               CssmKey                 &pubKey,
                CssmKey                 &privKey);
                CssmKey                 &privKey);
-               
+
        // this one is specified in, and called from, AppleKeyPairGenContext
        void generate(
                const Context   &context,
        // this one is specified in, and called from, AppleKeyPairGenContext
        void generate(
                const Context   &context,
-               BinaryKey               &pubBinKey,     
+               BinaryKey               &pubBinKey,
                BinaryKey               &privBinKey,
                uint32                  &keySize);
 
        // specified in, and called from, CSPFullPluginSessionÊ- generate parameters
        void generate(
                BinaryKey               &privBinKey,
                uint32                  &keySize);
 
        // specified in, and called from, CSPFullPluginSessionÊ- generate parameters
        void generate(
-               const Context   &context, 
+               const Context   &context,
                uint32                  bitSize,
                CssmData                &params,
                uint32                  bitSize,
                CssmData                &params,
-               uint32                  &attrCount, 
+               uint32                  &attrCount,
                Context::Attr * &attrs);
                Context::Attr * &attrs);
-       
+
        /*
         * Necessary to handle and deflect "context changed" notification which occurs
         * after the strange return from "generate parameters", when the plugin adds
        /*
         * Necessary to handle and deflect "context changed" notification which occurs
         * after the strange return from "generate parameters", when the plugin adds
@@ -205,7 +205,7 @@ public:
                unsigned                inSeedLen,
                NSS_DSAAlgParams &algParams,
                SecNssCoder             &coder);
                unsigned                inSeedLen,
                NSS_DSAAlgParams &algParams,
                SecNssCoder             &coder);
-       
+
 private:
        /* gross hack to store attributes "returned" from GenParams */
        Context::Attr           *mGenAttrs;
 private:
        /* gross hack to store attributes "returned" from GenParams */
        Context::Attr           *mGenAttrs;
@@ -215,7 +215,7 @@ private:
 /*
  * CSPKeyInfoProvider for DSA keys
  */
 /*
  * CSPKeyInfoProvider for DSA keys
  */
-class DSAKeyInfoProvider : public CSPKeyInfoProvider 
+class DSAKeyInfoProvider : public CSPKeyInfoProvider
 {
 private:
        DSAKeyInfoProvider(
 {
 private:
        DSAKeyInfoProvider(
@@ -225,7 +225,7 @@ public:
        static CSPKeyInfoProvider *provider(
                const CssmKey           &cssmKey,
                AppleCSPSession         &session);
        static CSPKeyInfoProvider *provider(
                const CssmKey           &cssmKey,
                AppleCSPSession         &session);
-               
+
        ~DSAKeyInfoProvider() { }
        void CssmKeyToBinary(
                CssmKey                         *paramKey,      // optional
        ~DSAKeyInfoProvider() { }
        void CssmKeyToBinary(
                CssmKey                         *paramKey,      // optional
index d28a61dfb05a895ac8ad9dca11b68b1315fe14b1..1864d32e24a7ffa7d683dd7fd68dbfc6a1a108cd 100644 (file)
@@ -112,7 +112,7 @@ void RSASigner::sign(
        }
 
        /* signature := encrypted digest info */
        }
 
        /* signature := encrypted digest info */
-       irtn = RSA_private_encrypt(encodedInfo.length(), 
+       irtn = RSA_private_encrypt((int)encodedInfo.length(),
                (unsigned char *)encodedInfo.data(),
                (unsigned char *)sig, 
                mRsaKey,
                (unsigned char *)encodedInfo.data(),
                (unsigned char *)sig, 
                mRsaKey,
@@ -161,7 +161,7 @@ void RSASigner::verify(
        unsigned decryptSigLen;
        
        /* signature should be encrypted digest info; decrypt the signature  */
        unsigned decryptSigLen;
        
        /* signature should be encrypted digest info; decrypt the signature  */
-       irtn = RSA_public_decrypt(sigLen, 
+       irtn = RSA_public_decrypt((int)sigLen,
                (unsigned char *)sig,
                decryptSig, 
                mRsaKey,
                (unsigned char *)sig,
                decryptSig, 
                mRsaKey,
@@ -279,7 +279,7 @@ void DSASigner::sign(
        }
        
        /* get signature in internal format */
        }
        
        /* get signature in internal format */
-       DSA_SIG *dsaSig = DSA_do_sign((unsigned char *)data, dataLen, mDsaKey);
+       DSA_SIG *dsaSig = DSA_do_sign((unsigned char *)data, (int)dataLen, mDsaKey);
        if(dsaSig == NULL) {
                throwRsaDsa("DSA_do_sign");
        }
        if(dsaSig == NULL) {
                throwRsaDsa("DSA_do_sign");
        }
@@ -319,12 +319,12 @@ void DSASigner::verify(
 
        /* incoming sig is DER encoded....decode into internal format */
        dsaSig = DSA_SIG_new();
 
        /* incoming sig is DER encoded....decode into internal format */
        dsaSig = DSA_SIG_new();
-       crtn = DSASigDecode(dsaSig, sig, sigLen);
+       crtn = DSASigDecode(dsaSig, sig, (unsigned int)sigLen);
        if(crtn) {
                goto abort;
        }
 
        if(crtn) {
                goto abort;
        }
 
-       irtn = DSA_do_verify((unsigned char *)data, dataLen, dsaSig, mDsaKey);
+       irtn = DSA_do_verify((unsigned char *)data, (int)dataLen, dsaSig, mDsaKey);
        if(irtn != 1) {
                throwSigVerify = true;
        }
        if(irtn != 1) {
                throwSigVerify = true;
        }
index c0fdbdd70b889ae140ccd4fe83cd219d55414fa3..7a5d15748f273aa612aeb0556387161533112094 100644 (file)
@@ -23,7 +23,6 @@
 #ifndef        _RSA_DSA_SIGNATURE_H_
 #define _RSA_DSA_SIGNATURE_H_
 
 #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 <RawSigner.h>
 #include <openssl/rsa.h>
 #include <openssl/dsa.h>
 #include <RawSigner.h>
index 03167b96a40c25ea108bffb19ccaa1021cecebcb..b7866b7904562e08f67d657aad5491a45bc5e366 100644 (file)
@@ -149,14 +149,14 @@ void RSA_CryptContext::encryptBlock(
        
        /* FIXME do OAEP encoding here */
        if(mRsaKey->d == NULL) {
        
        /* FIXME do OAEP encoding here */
        if(mRsaKey->d == NULL) {
-               irtn =  RSA_public_encrypt(plainTextLen, 
+               irtn =  RSA_public_encrypt((int)plainTextLen,
                        (unsigned char *)plainText,
                        (unsigned char *)cipherText, 
                        mRsaKey,
                        mPadding);
        }
        else {
                        (unsigned char *)plainText,
                        (unsigned char *)cipherText, 
                        mRsaKey,
                        mPadding);
        }
        else {
-               irtn =  RSA_private_encrypt(plainTextLen, 
+               irtn =  RSA_private_encrypt((int)plainTextLen,
                        (unsigned char *)plainText,
                        (unsigned char *)cipherText, 
                        mRsaKey,
                        (unsigned char *)plainText,
                        (unsigned char *)cipherText, 
                        mRsaKey,
@@ -186,14 +186,14 @@ void RSA_CryptContext::decryptBlock(
        rsaCryptDebug("decryptBlock padding %d", mPadding);
        /* FIXME do OAEP encoding here */
        if(mRsaKey->d == NULL) {
        rsaCryptDebug("decryptBlock padding %d", mPadding);
        /* FIXME do OAEP encoding here */
        if(mRsaKey->d == NULL) {
-               irtn = RSA_public_decrypt(inBlockSize(), 
+               irtn = RSA_public_decrypt((int)inBlockSize(),
                        (unsigned char *)cipherText,
                        (unsigned char *)plainText, 
                        mRsaKey,
                        mPadding);
        }
        else {
                        (unsigned char *)cipherText,
                        (unsigned char *)plainText, 
                        mRsaKey,
                        mPadding);
        }
        else {
-               irtn = RSA_private_decrypt(inBlockSize(), 
+               irtn = RSA_private_decrypt((int)inBlockSize(),
                        (unsigned char *)cipherText,
                        (unsigned char *)plainText, 
                        mRsaKey,
                        (unsigned char *)cipherText,
                        (unsigned char *)plainText, 
                        mRsaKey,
@@ -216,9 +216,9 @@ size_t RSA_CryptContext::outputSize(
 {
        StLock<Mutex> _(gMutex());
        
 {
        StLock<Mutex> _(gMutex());
        
-       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());
+       size_t rawBytes = inSize + inBufSize();
+       size_t rawBlocks = (rawBytes + inBlockSize() - 1) / inBlockSize();
+       rbprintf("--- RSA_CryptContext::outputSize inSize 0x%lux outSize 0x%lux mInBufSize 0x%lux",
+               (unsigned long)inSize, (unsigned long)(rawBlocks * outBlockSize()), (unsigned long)inBufSize());
        return rawBlocks * outBlockSize();
 }
        return rawBlocks * outBlockSize();
 }
index b72d8d66eb71b6ae24bcfcc530f0645f1d2fe3ab..92d6532d08fbac96d221d7eeed62e7c7645e450d 100644 (file)
@@ -23,7 +23,6 @@
 #ifndef        _RAW_SIGNER_H_
 #define _RAW_SIGNER_H_
 
 #ifndef        _RAW_SIGNER_H_
 #define _RAW_SIGNER_H_
 
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
 #include <security_cdsa_utilities/context.h>
 #include <security_utilities/alloc.h>
 
 #include <security_cdsa_utilities/context.h>
 #include <security_utilities/alloc.h>
 
index 6cef3342f16955560329a46ba1dc07cbd68d2987..7e79c005f309481bc8726aef2a162e9f7064988c 100644 (file)
@@ -48,7 +48,7 @@ void MD5Object::digestUpdate(
        if(mIsDone) {
                throw std::runtime_error("MD5 digestUpdate after final");
        }
        if(mIsDone) {
                throw std::runtime_error("MD5 digestUpdate after final");
        }
-       CC_MD5_Update(&mCtx, data, len);
+       CC_MD5_Update(&mCtx, data, (CC_LONG)len);
 }
 
 void MD5Object::digestFinal(
 }
 
 void MD5Object::digestFinal(
@@ -85,7 +85,7 @@ void SHA1Object::digestUpdate(
        const void      *data, 
        size_t          len)
 {
        const void      *data, 
        size_t          len)
 {
-       CC_SHA1_Update(&mCtx, (const unsigned char *)data, len);
+       CC_SHA1_Update(&mCtx, (const unsigned char *)data, (CC_LONG)len);
 }
 
 void SHA1Object::digestFinal(
 }
 
 void SHA1Object::digestFinal(
index 77e7edd3a1cc44e5e760b608805cfe6fbc9984b6..169c9ec332bfa33714284b8fe7d5f855157d9c57 100644 (file)
@@ -45,7 +45,7 @@ void SHA224Object::digestUpdate(
        const void      *data, 
        size_t          len)
 {
        const void      *data, 
        size_t          len)
 {
-       CC_SHA224_Update(&mCtx, (const unsigned char *)data, len);
+       CC_SHA224_Update(&mCtx, (const unsigned char *)data, (CC_LONG)len);
 }
 
 void SHA224Object::digestFinal(
 }
 
 void SHA224Object::digestFinal(
@@ -79,7 +79,7 @@ void SHA256Object::digestUpdate(
        const void      *data, 
        size_t          len)
 {
        const void      *data, 
        size_t          len)
 {
-       CC_SHA256_Update(&mCtx, (const unsigned char *)data, len);
+       CC_SHA256_Update(&mCtx, (const unsigned char *)data, (CC_LONG)len);
 }
 
 void SHA256Object::digestFinal(
 }
 
 void SHA256Object::digestFinal(
@@ -113,7 +113,7 @@ void SHA384Object::digestUpdate(
        const void      *data, 
        size_t          len)
 {
        const void      *data, 
        size_t          len)
 {
-       CC_SHA384_Update(&mCtx, (const unsigned char *)data, len);
+       CC_SHA384_Update(&mCtx, (const unsigned char *)data, (CC_LONG)len);
 }
 
 void SHA384Object::digestFinal(
 }
 
 void SHA384Object::digestFinal(
@@ -147,7 +147,7 @@ void SHA512Object::digestUpdate(
        const void      *data, 
        size_t          len)
 {
        const void      *data, 
        size_t          len)
 {
-       CC_SHA512_Update(&mCtx, (const unsigned char *)data, len);
+       CC_SHA512_Update(&mCtx, (const unsigned char *)data, (CC_LONG)len);
 }
 
 void SHA512Object::digestFinal(
 }
 
 void SHA512Object::digestFinal(
index da365a93bf554265a0882a4ed9d317ae3ddfebde..1edc6e2872802c4bfa8041d14007edd0114b0a64 100644 (file)
@@ -50,8 +50,7 @@ public:
                        AppleCSPContext(session), 
                        mDigest(digest), 
                        mSigner(signer),
                        AppleCSPContext(session), 
                        mDigest(digest), 
                        mSigner(signer),
-                       mInitFlag(false),
-                       mOpStarted(false) { }
+                       mInitFlag(false) { }
                        
        ~SignatureContext();
        
                        
        ~SignatureContext();
        
@@ -76,7 +75,6 @@ private:
        DigestObject    &mDigest;
        RawSigner               &mSigner;
        bool                    mInitFlag;                      // true after init
        DigestObject    &mDigest;
        RawSigner               &mSigner;
        bool                    mInitFlag;                      // true after init
-       bool                    mOpStarted;                     // true after update
 };
 
 
 };
 
 
index 9f068b3a40eaf90075802dd86598805a61469134..65d769dfbeaae3bf1ee9a2a871f0e09ae955a091 100644 (file)
@@ -162,8 +162,8 @@ void AESContext::init(
        /* init key only if key size, block size, or key bits have changed */
        if(!sameKeyAndBlockSizes || memcmp(mRawKey, keyData, mRawKeySize)) {
                int artn = makeKey((keyInstance *)mAesKey, 
        /* 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, 
+                       (int)keyLen * 8,
+                        mBlockSize * 8,
                        (word8 *)keyData,
                        opt128);
                if(artn < 0) {
                        (word8 *)keyData,
                        opt128);
                if(artn < 0) {
@@ -172,7 +172,7 @@ void AESContext::init(
                
                /* save this raw key data */
                memmove(mRawKey, keyData, mRawKeySize); 
                
                /* save this raw key data */
                memmove(mRawKey, keyData, mRawKeySize); 
-               mRawKeySize = keyLen;
+               mRawKeySize = (uint32)keyLen;
        }
 
 #if            !GLADMAN_AES_128_ENABLE
        }
 
 #if            !GLADMAN_AES_128_ENABLE
index f0a45b17e29eeb6929a98e6a7f724417bf565cdc..253468c760bef2fbe612a19ce6685c3598e6c36a 100644 (file)
@@ -177,7 +177,7 @@ void ASCContext::init(
                }
        }
         
                }
        }
         
-       crtn = comcryptInit(mCcObj, keyData, keyLen, optimize);
+       crtn = comcryptInit(mCcObj, keyData, (unsigned)keyLen, optimize);
        if(crtn) {
                throwComcrypt(crtn, "comcryptInit");
        }
        if(crtn) {
                throwComcrypt(crtn, "comcryptInit");
        }
@@ -198,10 +198,10 @@ void ASCContext::update(
        unsigned char *outText = (unsigned char *)outp;
        
        if(encoding()) {
        unsigned char *outText = (unsigned char *)outp;
        
        if(encoding()) {
-               outLen = outSize;
+               outLen = (unsigned)outSize;
                crtn = comcryptData(mCcObj, 
                        inText, 
                crtn = comcryptData(mCcObj, 
                        inText, 
-                       inSize,
+                       (unsigned)inSize,
                        outText,
                        &outLen,
                        CCE_MORE_TO_COME);              // not used on encrypt
                        outText,
                        &outLen,
                        CCE_MORE_TO_COME);              // not used on encrypt
@@ -219,7 +219,7 @@ void ASCContext::update(
                unsigned thisOutLen;
                unsigned partialOutLen = 0;
                if(mDecryptBufValid) {
                unsigned thisOutLen;
                unsigned partialOutLen = 0;
                if(mDecryptBufValid) {
-                       thisOutLen = outSize;
+                       thisOutLen = (unsigned)outSize;
                        crtn = deComcryptData(mCcObj,
                                &mDecryptBuf,
                                1,
                        crtn = deComcryptData(mCcObj,
                                &mDecryptBuf,
                                1,
@@ -238,10 +238,10 @@ void ASCContext::update(
                 * Now decrypt remaining, less one byte (which is stored in the 
                 * buffer).
                 */
                 * Now decrypt remaining, less one byte (which is stored in the 
                 * buffer).
                 */
-               thisOutLen = outSize - partialOutLen;
+               thisOutLen = (unsigned)(outSize - partialOutLen);
                crtn = deComcryptData(mCcObj,
                        inText, 
                crtn = deComcryptData(mCcObj,
                        inText, 
-                       inSize - 1,
+                       (unsigned)(inSize - 1),
                        outText,
                        &thisOutLen,
                        CCE_MORE_TO_COME);
                        outText,
                        &thisOutLen,
                        CCE_MORE_TO_COME);
@@ -269,7 +269,7 @@ void ASCContext::final(
                        CssmError::throwMe(CSSMERR_CSP_INPUT_LENGTH_ERROR);
                }
                comcryptReturn crtn;
                        CssmError::throwMe(CSSMERR_CSP_INPUT_LENGTH_ERROR);
                }
                comcryptReturn crtn;
-               unsigned outLen = out.Length;
+               unsigned outLen = (unsigned)out.Length;
                crtn = deComcryptData(mCcObj,
                        &mDecryptBuf,
                        1,
                crtn = deComcryptData(mCcObj,
                        &mDecryptBuf,
                        1,
@@ -290,7 +290,7 @@ size_t ASCContext::inputSize(
        size_t                  outSize)                        // input for given output size
 {
        size_t rtn = comcryptMaxInBufSize(mCcObj,
        size_t                  outSize)                        // input for given output size
 {
        size_t rtn = comcryptMaxInBufSize(mCcObj,
-               outSize,
+               (unsigned)outSize,
                encoding() ? CCOP_COMCRYPT : CCOP_DECOMCRYPT);
        abprintf("--- ASCContext::inputSize  inSize %ld outSize %ld",
                rtn, outSize);
                encoding() ? CCOP_COMCRYPT : CCOP_DECOMCRYPT);
        abprintf("--- ASCContext::inputSize  inSize %ld outSize %ld",
                rtn, outSize);
@@ -310,7 +310,7 @@ size_t ASCContext::outputSize(
        bool                    final, 
        size_t                  inSize)                         // output for given input size
 {
        bool                    final, 
        size_t                  inSize)                         // output for given input size
 {
-       unsigned effectiveInSize = inSize;
+       unsigned effectiveInSize = (unsigned)inSize;
        size_t rtn;
        if(encoding()) {
                rtn = comcryptMaxOutBufSize(mCcObj,
        size_t rtn;
        if(encoding()) {
                rtn = comcryptMaxOutBufSize(mCcObj,
@@ -363,7 +363,7 @@ void ASCContext::minimumProgress(
                        in = 0;
                }
                out = comcryptMaxOutBufSize(mCcObj,
                        in = 0;
                }
                out = comcryptMaxOutBufSize(mCcObj,
-                       in,
+                       (unsigned)in,
                        CCOP_DECOMCRYPT,
                        0);
        }
                        CCOP_DECOMCRYPT,
                        0);
        }
index bea6d24ac8bff7d6d50c9a42005774e7cb64f74b..55d2ad8d53626aaf1f421b7b96329f619fa4d47d 100644 (file)
@@ -10,7 +10,6 @@
 #define _ASC_CONTEXT_H_
 
 #include "AppleCSPContext.h"
 #define _ASC_CONTEXT_H_
 
 #include "AppleCSPContext.h"
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
 #include <security_comcryption/comcryption.h>
 
 /* symmetric encrypt/decrypt context */
 #include <security_comcryption/comcryption.h>
 
 /* symmetric encrypt/decrypt context */
index 3180e40717f26381c22bf77b144faa3f5b490fa0..8c809b5c3adb2de8a213ba69c13b01a07c134839 100644 (file)
@@ -71,11 +71,11 @@ void BlowfishContext::init(
 
        /* init key only if key size or key bits have changed */
        if(!sameKeySize || memcmp(mRawKey, keyData, mRawKeySize)) {
 
        /* init key only if key size or key bits have changed */
        if(!sameKeySize || memcmp(mRawKey, keyData, mRawKeySize)) {
-               BF_set_key(&mBfKey, keyLen, keyData);
+               BF_set_key(&mBfKey, (int)keyLen, keyData);
        
                /* save this raw key data */
                memmove(mRawKey, keyData, keyLen); 
        
                /* save this raw key data */
                memmove(mRawKey, keyData, keyLen); 
-               mRawKeySize = keyLen;
+               mRawKeySize = (unsigned int)keyLen;
        }
        
        /* Finally, have BlockCryptor do its setup */
        }
        
        /* Finally, have BlockCryptor do its setup */
index d148760dd45cdccfc8b04a935f0aa72d8b33ca99..15525f1477cb812d2b066d450d022e9aa89c2c76 100644 (file)
@@ -27,7 +27,6 @@
 
 #include "AppleCSPContext.h"
 #include "BlockCryptor.h"
 
 #include "AppleCSPContext.h"
 #include "BlockCryptor.h"
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
 #include <openssl/blowfish.h>
 
 class BlowfishContext : public BlockCryptor {
 #include <openssl/blowfish.h>
 
 class BlowfishContext : public BlockCryptor {
index dcf76abaf11093debab7ba28fa6bff0ebd15c041..503d667ed101ebc615c9bfed7ce8d1a2db9de138 100644 (file)
@@ -26,8 +26,8 @@
 
 CastContext::CastContext(AppleCSPSession &session) :
     BlockCryptor(session),
 
 CastContext::CastContext(AppleCSPSession &session) :
     BlockCryptor(session),
-    mInitFlag(false),
     mCastKey(NULL),
     mCastKey(NULL),
+    mInitFlag(false),
     mRawKeySize(0)
 {
 }
     mRawKeySize(0)
 {
 }
@@ -88,7 +88,7 @@ void CastContext::init(
        
                /* save this raw key data */
                memmove(mRawKey, keyData, keyLen); 
        
                /* save this raw key data */
                memmove(mRawKey, keyData, keyLen); 
-               mRawKeySize = keyLen;
+               mRawKeySize = (uint32)keyLen;
        }
        
        /* Finally, have BlockCryptor do its setup */
        }
        
        /* Finally, have BlockCryptor do its setup */
index 122fb5dd3ff0dff8abcdc74567848af294468c28..5d3d1fd105896b5ce07010a19948a48f284ffa30 100644 (file)
@@ -40,9 +40,8 @@
 
 #include "AppleCSPContext.h"
 #include "BlockCryptor.h"
 
 #include "AppleCSPContext.h"
 #include "BlockCryptor.h"
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
 #include <CommonCrypto/CommonCryptor.h>
 #include <CommonCrypto/CommonCryptor.h>
-#include "/usr/local/include/CommonCrypto/CommonCryptorSPI.h"
+#include <CommonCrypto/CommonCryptorSPI.h>
 
 class CastContext : public BlockCryptor {
 public:
 
 class CastContext : public BlockCryptor {
 public:
index bac414c52c776642826e081cbba59d65e5791c8a..a06bcf20b9eca99c5118809feffcf3379bca0997 100644 (file)
@@ -36,7 +36,6 @@
 #if            !LOG_VIA_PRINTF
 
 #include <string.h>
 #if            !LOG_VIA_PRINTF
 
 #include <string.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
 #include <TextUtils.h>
 
 /* common log macros */
 #include <TextUtils.h>
 
 /* common log macros */
index 01e7e0dcce8bf6dc048720edc0ba61eaf398f0e5..9492d27435000a7ac7291b364bdf8dcebe9776c9 100644 (file)
@@ -56,7 +56,6 @@
 #error Hey, figure out a debug mechanism
 
 #include <string.h>
 #error Hey, figure out a debug mechanism
 
 #include <string.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
 #include <TextUtils.h>
 
 /* common log macros */
 #include <TextUtils.h>
 
 /* common log macros */
index 6229c270145cd0b10c792e8edb5950bced0917f5..f329020c6f5e6e88504647845435869202ce07e2 100644 (file)
@@ -115,7 +115,7 @@ void AppleCSPSession::DeriveKey_PBKDF2(
         *    = MAX (hLen, saltLen + 4) + 2 * hLen
         *    = MAX (kSHA1DigestSize, saltLen + 4) + 2 * kSHA1DigestSize
         */
         *    = MAX (hLen, saltLen + 4) + 2 * hLen
         *    = MAX (kSHA1DigestSize, saltLen + 4) + 2 * kSHA1DigestSize
         */
-       uint32 tempLen = salt.Length + 4;
+       size_t tempLen = salt.Length + 4;
        if(tempLen < kSHA1DigestSize) {
                tempLen = kSHA1DigestSize;
        }
        if(tempLen < kSHA1DigestSize) {
                tempLen = kSHA1DigestSize;
        }
@@ -126,10 +126,10 @@ void AppleCSPSession::DeriveKey_PBKDF2(
        /* go */
        pbkdf2 (hmacsha1, 
                kSHA1DigestSize,
        /* go */
        pbkdf2 (hmacsha1, 
                kSHA1DigestSize,
-               passphrase, passphraseLen,
-               salt.Data, salt.Length,
+               passphrase, (uint32)passphraseLen,
+               salt.Data, (uint32)salt.Length,
                iterCount,
                iterCount,
-               keyData->Data, keyData->Length,
+               keyData->Data, (uint32)keyData->Length,
                tempData.Data);
        freeData(&tempData, privAllocator, false);
 }
                tempData.Data);
        freeData(&tempData, privAllocator, false);
 }
@@ -233,9 +233,9 @@ void AppleCSPSession::DeriveKey_PKCS5_V1_5(
         */
        DigestCtx ctx;
        uint8 *keyDataP         = keyData->Data;
         */
        DigestCtx ctx;
        uint8 *keyDataP         = keyData->Data;
-       uint32 keyBytesToGo = keyData->Length;
+       size_t keyBytesToGo = keyData->Length;
        uint8 *ivDataP          = iv.Data;
        uint8 *ivDataP          = iv.Data;
-       uint32 ivBytesToGo  = iv.Length;
+       size_t ivBytesToGo  = iv.Length;
        bool looping            = false;                // true for additional bytes for openssl
        unsigned char digestOut[kMaxDigestSize];
        
        bool looping            = false;                // true for additional bytes for openssl
        unsigned char digestOut[kMaxDigestSize];
        
@@ -249,8 +249,8 @@ void AppleCSPSession::DeriveKey_PKCS5_V1_5(
                }
                
                /* digest password then salt */
                }
                
                /* digest password then salt */
-               DigestCtxUpdate(&ctx, pwd.Data, pwd.Length);
-               DigestCtxUpdate(&ctx, salt.Data, salt.Length);
+               DigestCtxUpdate(&ctx, pwd.Data, (uint32)pwd.Length);
+               DigestCtxUpdate(&ctx, salt.Data, (uint32)salt.Length);
 
                DigestCtxFinal(&ctx, digestOut);
                
 
                DigestCtxFinal(&ctx, digestOut);
                
@@ -263,7 +263,7 @@ void AppleCSPSession::DeriveKey_PKCS5_V1_5(
                
                /* first n bytes to the key */
                uint32 bytesAvail = digestLen;
                
                /* first n bytes to the key */
                uint32 bytesAvail = digestLen;
-               uint32 toMove = (keyBytesToGo > bytesAvail) ? bytesAvail : keyBytesToGo;
+               size_t toMove = (keyBytesToGo > bytesAvail) ? bytesAvail : keyBytesToGo;
                memmove(keyDataP, digestOut, toMove);
                uint8 *remainder = digestOut + toMove;
                bytesAvail   -= toMove;
                memmove(keyDataP, digestOut, toMove);
                uint8 *remainder = digestOut + toMove;
                bytesAvail   -= toMove;
@@ -421,7 +421,7 @@ void AppleCSPSession::DeriveKey(
                KeyAttr, 
                KeyUsage);
        /* handle derived size < requested size, legal for Diffie-Hellman */
                KeyAttr, 
                KeyUsage);
        /* handle derived size < requested size, legal for Diffie-Hellman */
-       hdr.LogicalKeySizeInBits = keyData->Length * 8;
+       hdr.LogicalKeySizeInBits = (uint32)(keyData->Length * 8);
        
        if(keyStorage == CKS_Ref) {
                /* store and convert to ref key */
        
        if(keyStorage == CKS_Ref) {
                /* store and convert to ref key */
index 55158ab4bb8a459fc23b018009fe8e893c491378..bd52b14527e72183eb3f0950923b1251eb8e2373 100644 (file)
@@ -29,7 +29,7 @@
 #include "AppleCSPSession.h"
 #include "BlockCryptor.h"
 #include <CommonCrypto/CommonCryptor.h>
 #include "AppleCSPSession.h"
 #include "BlockCryptor.h"
 #include <CommonCrypto/CommonCryptor.h>
-#include "/usr/local/include/CommonCrypto/CommonCryptorSPI.h"
+#include <CommonCrypto/CommonCryptorSPI.h>
 
 #define DES_KEY_SIZE_BITS_EXTERNAL             (kCCKeySizeDES * 8)
 #define DES_BLOCK_SIZE_BYTES                   kCCBlockSizeDES
 
 #define DES_KEY_SIZE_BITS_EXTERNAL             (kCCKeySizeDES * 8)
 #define DES_BLOCK_SIZE_BYTES                   kCCBlockSizeDES
index e08d927e8b66392d310454dc30a375c3daa3139c..16fddca77bba52d99dc0f5e09527874e6ffaf6fa 100644 (file)
@@ -109,7 +109,7 @@ void GAESContext::init(
 
                /* save this raw key data */
                memmove(mRawKey, keyData, keyLen); 
 
                /* save this raw key data */
                memmove(mRawKey, keyData, keyLen); 
-               mRawKeySize = keyLen;
+               mRawKeySize = (uint32)keyLen;
                mWasEncrypting = encrypting;
        }
 
                mWasEncrypting = encrypting;
        }
 
index 48a9ba68c15899e86d891ec632e1ec9465b50f20..87a8d3297f92c469ddf47b65e19c0d307e53a9fb 100644 (file)
@@ -28,7 +28,7 @@
 #include "AppleCSPSession.h"
 #include "BlockCryptor.h"
 #include <CommonCrypto/CommonCryptor.h>
 #include "AppleCSPSession.h"
 #include "BlockCryptor.h"
 #include <CommonCrypto/CommonCryptor.h>
-#include "/usr/local/include/CommonCrypto/CommonCryptorSPI.h"
+#include <CommonCrypto/CommonCryptorSPI.h>
 #include "aesCommon.h"
 
 #define GLADMAN_BLOCK_SIZE_BYTES       DEFAULT_AES_BLOCK_BYTES
 #include "aesCommon.h"
 
 #define GLADMAN_BLOCK_SIZE_BYTES       DEFAULT_AES_BLOCK_BYTES
index 15bc177edd182d0f9f592a33f3be78c60d332855..f331813bc727abc6cb39e0764453b2daecad7700 100644 (file)
@@ -228,7 +228,7 @@ static CSSM_RETURN parseSSH2PubKey(
        unsigned char **decodedBlob,    // mallocd and RETURNED
        unsigned *decodedBlobLen)               // RETURNED
 {
        unsigned char **decodedBlob,    // mallocd and RETURNED
        unsigned *decodedBlobLen)               // RETURNED
 {
-       unsigned len = strlen(header);
+       size_t len = strlen(header);
        *decodedBlob = NULL;
        
        /* ID string plus at least one space */
        *decodedBlob = NULL;
        
        /* ID string plus at least one space */
@@ -258,7 +258,7 @@ static CSSM_RETURN parseSSH2PubKey(
        /* key is start of base64 blob */
        const unsigned char *encodedBlob = key;
        const unsigned char *endBlob = findNextWhite(key, keyLen);
        /* key is start of base64 blob */
        const unsigned char *encodedBlob = key;
        const unsigned char *endBlob = findNextWhite(key, keyLen);
-       unsigned encodedBlobLen = endBlob - encodedBlob;
+       unsigned encodedBlobLen = (unsigned)(endBlob - encodedBlob);
        
        /* decode base 64 */
        *decodedBlob = cuDec64(encodedBlob, encodedBlobLen, decodedBlobLen);
        
        /* decode base 64 */
        *decodedBlob = cuDec64(encodedBlob, encodedBlobLen, decodedBlobLen);
@@ -300,11 +300,11 @@ CSSM_RETURN RSAPublicKeyEncodeOpenSSH1(
 
        snprintf(bitString, sizeof(bitString), "%u ", numBits);
        CFDataAppendBytes(cfOut, (const UInt8 *)bitString, strlen(bitString));
 
        snprintf(bitString, sizeof(bitString), "%u ", numBits);
        CFDataAppendBytes(cfOut, (const UInt8 *)bitString, strlen(bitString));
-       if(ourRtn = appendBigNumDec(cfOut, rsa->e)) {
+       if((ourRtn = appendBigNumDec(cfOut, rsa->e))) {
                goto errOut;
        }
        CFDataAppendBytes(cfOut, &c, 1);
                goto errOut;
        }
        CFDataAppendBytes(cfOut, &c, 1);
-       if(ourRtn = appendBigNumDec(cfOut, rsa->n)) {
+       if((ourRtn = appendBigNumDec(cfOut, rsa->n))) {
                goto errOut;
        }
        
                goto errOut;
        }
        
@@ -328,7 +328,7 @@ CSSM_RETURN RSAPublicKeyDecodeOpenSSH1(
        size_t                  length)
 {
        const unsigned char *cp = (const unsigned char *)p;
        size_t                  length)
 {
        const unsigned char *cp = (const unsigned char *)p;
-       unsigned remLen = length;
+       unsigned remLen = (unsigned)length;
        
        skipWhite(cp, remLen);
        
        
        skipWhite(cp, remLen);
        
@@ -355,7 +355,7 @@ CSSM_RETURN RSAPublicKeyDecodeOpenSSH1(
                dprintf("RSAPublicKeyDecodeOpenSSH1: short key (3)\n");
                return CSSMERR_CSP_INVALID_KEY;
        }
                dprintf("RSAPublicKeyDecodeOpenSSH1: short key (3)\n");
                return CSSMERR_CSP_INVALID_KEY;
        }
-       unsigned len = ep - cp;
+       unsigned len = (unsigned)(ep - cp);
        rsa->e = parseDecimalBn(cp, len);
        if(rsa->e == NULL) {
                return CSSMERR_CSP_INVALID_KEY;
        rsa->e = parseDecimalBn(cp, len);
        if(rsa->e == NULL) {
                return CSSMERR_CSP_INVALID_KEY;
@@ -370,7 +370,7 @@ CSSM_RETURN RSAPublicKeyDecodeOpenSSH1(
        
        /* cp points to start of n */
        ep = findNextWhite(cp, remLen);
        
        /* cp points to start of n */
        ep = findNextWhite(cp, remLen);
-       len = ep - cp;
+       len = (unsigned)(ep - cp);
        rsa->n = parseDecimalBn(cp, len);
        if(rsa->n == NULL) {
                return CSSMERR_CSP_INVALID_KEY;
        rsa->n = parseDecimalBn(cp, len);
        if(rsa->n == NULL) {
                return CSSMERR_CSP_INVALID_KEY;
@@ -389,7 +389,7 @@ CSSM_RETURN RSAPrivateKeyEncodeOpenSSH1(
        CFDataRef cfOut;
        CSSM_RETURN ourRtn;
 
        CFDataRef cfOut;
        CSSM_RETURN ourRtn;
 
-       ourRtn = encodeOpenSSHv1PrivKey(rsa, descData.Data, descData.Length, NULL, &cfOut);
+       ourRtn = encodeOpenSSHv1PrivKey(rsa, descData.Data, (unsigned)descData.Length, NULL, &cfOut);
        if(ourRtn) {
                return ourRtn;
        }
        if(ourRtn) {
                return ourRtn;
        }
@@ -403,7 +403,7 @@ extern CSSM_RETURN RSAPrivateKeyDecodeOpenSSH1(
        void                    *p, 
        size_t                  length)
 {
        void                    *p, 
        size_t                  length)
 {
-       return decodeOpenSSHv1PrivKey((const unsigned char *)p, length,
+       return decodeOpenSSHv1PrivKey((const unsigned char *)p, (unsigned)length,
                openKey, NULL, NULL, NULL);
 }
 
                openKey, NULL, NULL, NULL);
 }
 
@@ -427,15 +427,15 @@ CSSM_RETURN RSAPublicKeyEncodeOpenSSH2(
        CFMutableDataRef cfOut = CFDataCreateMutable(NULL, 0);
        CSSM_RETURN ourRtn = CSSM_OK;
        appendString(cfOut, SSH2_RSA_HEADER, strlen(SSH2_RSA_HEADER));
        CFMutableDataRef cfOut = CFDataCreateMutable(NULL, 0);
        CSSM_RETURN ourRtn = CSSM_OK;
        appendString(cfOut, SSH2_RSA_HEADER, strlen(SSH2_RSA_HEADER));
-       if(ourRtn = appendBigNum2(cfOut, rsa->e)) {
+       if((ourRtn = appendBigNum2(cfOut, rsa->e))) {
                goto errOut;
        }
                goto errOut;
        }
-       if(ourRtn = appendBigNum2(cfOut, rsa->n)) {
+       if((ourRtn = appendBigNum2(cfOut, rsa->n))) {
                goto errOut;
        }
        
        /* base64 encode that */
                goto errOut;
        }
        
        /* base64 encode that */
-       b64 = cuEnc64((unsigned char *)CFDataGetBytePtr(cfOut), CFDataGetLength(cfOut), &b64Len);
+       b64 = cuEnc64((unsigned char *)CFDataGetBytePtr(cfOut), (unsigned)CFDataGetLength(cfOut), &b64Len);
        
        /* cuEnc64 added newline and NULL, which we really don't want */
        b64Len -= 2;
        
        /* cuEnc64 added newline and NULL, which we really don't want */
        b64Len -= 2;
@@ -472,7 +472,7 @@ CSSM_RETURN RSAPublicKeyDecodeOpenSSH2(
        size_t                  length)
 {
        const unsigned char *key = (const unsigned char *)p;
        size_t                  length)
 {
        const unsigned char *key = (const unsigned char *)p;
-       unsigned keyLen = length;
+       unsigned keyLen = (unsigned)length;
        CSSM_RETURN ourRtn;
        
        /* 
        CSSM_RETURN ourRtn;
        
        /* 
@@ -481,7 +481,7 @@ CSSM_RETURN RSAPublicKeyDecodeOpenSSH2(
         */
        unsigned char *decodedBlob = NULL;
        unsigned decodedBlobLen = 0;
         */
        unsigned char *decodedBlob = NULL;
        unsigned decodedBlobLen = 0;
-       if(ourRtn = parseSSH2PubKey(key, keyLen, SSH2_RSA_HEADER, &decodedBlob, &decodedBlobLen)) {
+       if((ourRtn = parseSSH2PubKey(key, keyLen, SSH2_RSA_HEADER, &decodedBlob, &decodedBlobLen))) {
                return ourRtn;
        }
        /* subsequent errors to errOut: */
                return ourRtn;
        }
        /* subsequent errors to errOut: */
@@ -555,21 +555,21 @@ CSSM_RETURN DSAPublicKeyEncodeOpenSSH2(
        CFMutableDataRef cfOut = CFDataCreateMutable(NULL, 0);
        int ourRtn = 0;
        appendString(cfOut, SSH2_DSA_HEADER, strlen(SSH2_DSA_HEADER));
        CFMutableDataRef cfOut = CFDataCreateMutable(NULL, 0);
        int ourRtn = 0;
        appendString(cfOut, SSH2_DSA_HEADER, strlen(SSH2_DSA_HEADER));
-       if(ourRtn = appendBigNum2(cfOut, dsa->p)) {
+       if((ourRtn = appendBigNum2(cfOut, dsa->p))) {
                goto errOut;
        }
                goto errOut;
        }
-       if(ourRtn = appendBigNum2(cfOut, dsa->q)) {
+       if((ourRtn = appendBigNum2(cfOut, dsa->q))) {
                goto errOut;
        }
                goto errOut;
        }
-       if(ourRtn = appendBigNum2(cfOut, dsa->g)) {
+       if((ourRtn = appendBigNum2(cfOut, dsa->g))) {
                goto errOut;
        }
                goto errOut;
        }
-       if(ourRtn = appendBigNum2(cfOut, dsa->pub_key)) {
+       if((ourRtn = appendBigNum2(cfOut, dsa->pub_key))) {
                goto errOut;
        }
        
        /* base64 encode that */
                goto errOut;
        }
        
        /* base64 encode that */
-       b64 = cuEnc64((unsigned char *)CFDataGetBytePtr(cfOut), CFDataGetLength(cfOut), &b64Len);
+       b64 = cuEnc64((unsigned char *)CFDataGetBytePtr(cfOut), (unsigned)CFDataGetLength(cfOut), &b64Len);
        
        /* cuEnc64 added newline and NULL, which we really don't want */
        b64Len -= 2;
        
        /* cuEnc64 added newline and NULL, which we really don't want */
        b64Len -= 2;
@@ -607,7 +607,7 @@ CSSM_RETURN DSAPublicKeyDecodeOpenSSH2(
        size_t                  length)
 {
        const unsigned char *key = (const unsigned char *)p;
        size_t                  length)
 {
        const unsigned char *key = (const unsigned char *)p;
-       unsigned keyLen = length;
+       unsigned keyLen = (unsigned)length;
        CSSM_RETURN ourRtn;
        
        /* 
        CSSM_RETURN ourRtn;
        
        /* 
@@ -616,7 +616,7 @@ CSSM_RETURN DSAPublicKeyDecodeOpenSSH2(
         */
        unsigned char *decodedBlob = NULL;
        unsigned decodedBlobLen = 0;
         */
        unsigned char *decodedBlob = NULL;
        unsigned decodedBlobLen = 0;
-       if(ourRtn = parseSSH2PubKey(key, keyLen, SSH2_DSA_HEADER, &decodedBlob, &decodedBlobLen)) {
+       if((ourRtn = parseSSH2PubKey(key, keyLen, SSH2_DSA_HEADER, &decodedBlob, &decodedBlobLen))) {
                return ourRtn;
        }
        /* subsequent errors to errOut: */
                return ourRtn;
        }
        /* subsequent errors to errOut: */
index 9338d52b706e5540be1f34774191829310b50a86..18f448eeb6360358581a19f516960e3dcb7f075a 100644 (file)
@@ -252,7 +252,7 @@ static CSSM_RETURN ssh1DES3Crypt(
                return CSSMERR_CSP_INTERNAL_ERROR;
        }
 
                return CSSMERR_CSP_INTERNAL_ERROR;
        }
 
-       *outTextLen = moved;    
+       *outTextLen = (unsigned)moved;
        return CSSM_OK;
 }
 
        return CSSM_OK;
 }
 
@@ -306,7 +306,7 @@ void AppleCSPSession::DeriveKey_OpenSSH1(
        }
 
        /* here it is */
        }
 
        /* here it is */
-       CC_MD5(pwd.Data, pwd.Length, keyData->Data);
+       CC_MD5(pwd.Data, (CC_LONG)pwd.Length, keyData->Data);
 
 }
 
 
 }
 
@@ -389,9 +389,9 @@ CSSM_RETURN encodeOpenSSHv1PrivKey(
        appendBigNum(ptext, rsa->p);
        
        /* pad to block boundary */
        appendBigNum(ptext, rsa->p);
        
        /* pad to block boundary */
-       unsigned ptextLen = CFDataGetLength(ptext);
+       CFIndex ptextLen = CFDataGetLength(ptext);
        unsigned padding = 0;
        unsigned padding = 0;
-       unsigned rem = ptextLen & 0x7;
+       unsigned rem = (unsigned)ptextLen & 0x7;
        if(rem) {
                padding = 8 - rem;
        }
        if(rem) {
                padding = 8 - rem;
        }
@@ -405,7 +405,7 @@ CSSM_RETURN encodeOpenSSHv1PrivKey(
        unsigned char ctext[ptextLen];
        unsigned ctextLen;
        ourRtn = ssh1DES3Crypt(cipherSpec, true, 
        unsigned char ctext[ptextLen];
        unsigned ctextLen;
        ourRtn = ssh1DES3Crypt(cipherSpec, true, 
-               (unsigned char *)CFDataGetBytePtr(ptext), ptextLen, 
+               (unsigned char *)CFDataGetBytePtr(ptext), (unsigned)ptextLen,
                encryptKey, encryptKey ? CC_MD5_DIGEST_LENGTH : 0,
                ctext, &ctextLen);
        if(ourRtn != 0) {
                encryptKey, encryptKey ? CC_MD5_DIGEST_LENGTH : 0,
                ctext, &ctextLen);
        if(ourRtn != 0) {
@@ -470,7 +470,7 @@ void AppleCSPSession::WrapKeyOpenSSH1(
        unsigned commentLen = 0;
        if((DescriptiveData != NULL) && (DescriptiveData->Length != 0)) {
                comment = (const UInt8 *)DescriptiveData->Data;
        unsigned commentLen = 0;
        if((DescriptiveData != NULL) && (DescriptiveData->Length != 0)) {
                comment = (const UInt8 *)DescriptiveData->Data;
-               commentLen = DescriptiveData->Length;
+               commentLen = (unsigned)DescriptiveData->Length;
        }
 
        /* generate the encrypted blob */
        }
 
        /* generate the encrypted blob */
@@ -480,7 +480,7 @@ void AppleCSPSession::WrapKeyOpenSSH1(
        }
        
        /* allocate key data in session's memory space */
        }
        
        /* allocate key data in session's memory space */
-       unsigned len = CFDataGetLength(cfOut);
+       CFIndex len = CFDataGetLength(cfOut);
        setUpData(WrappedKey.KeyData, len, normAllocator);
        memmove(WrappedKey.KeyData.Data, CFDataGetBytePtr(cfOut), len);
        CFRelease(cfOut);
        setUpData(WrappedKey.KeyData, len, normAllocator);
        memmove(WrappedKey.KeyData.Data, CFDataGetBytePtr(cfOut), len);
        CFRelease(cfOut);
@@ -507,7 +507,7 @@ CSSM_RETURN decodeOpenSSHv1PrivKey(
        uint8 **comment,                        /* optional, mallocd and RETURNED */
        unsigned *commentLen)           /* RETURNED */
 {
        uint8 **comment,                        /* optional, mallocd and RETURNED */
        unsigned *commentLen)           /* RETURNED */
 {
-       unsigned len = strlen(authfile_id_string);
+       unsigned len = (unsigned)strlen(authfile_id_string);
        const unsigned char *cp = encodedKey;
        unsigned remLen = encodedKeyLen;
        CSSM_RETURN ourRtn = CSSM_OK;
        const unsigned char *cp = encodedKey;
        unsigned remLen = encodedKeyLen;
        CSSM_RETURN ourRtn = CSSM_OK;
@@ -701,7 +701,7 @@ void AppleCSPSession::UnwrapKeyOpenSSH1(
        RSABinaryKey *binKey = NULL;
        
        ourRtn = decodeOpenSSHv1PrivKey((const unsigned char *)WrappedKey.KeyData.Data,
        RSABinaryKey *binKey = NULL;
        
        ourRtn = decodeOpenSSHv1PrivKey((const unsigned char *)WrappedKey.KeyData.Data,
-               WrappedKey.KeyData.Length,
+               (unsigned)WrappedKey.KeyData.Length,
                rsa, unwrapKey, &comment, &commentLen);
        if(ourRtn) {
                goto errOut;
                rsa, unwrapKey, &comment, &commentLen);
        if(ourRtn) {
                goto errOut;
index 55057b32d4e89d259ce68c9be606df3b536b1c6b..87827638feedf87774e8ffe84cecdde9a6d8aa44 100644 (file)
@@ -23,7 +23,7 @@
        Written by:     Michael Brouwer <mb@apple.com>
 */
 #include "pbkdf2.h"
        Written by:     Michael Brouwer <mb@apple.com>
 */
 #include "pbkdf2.h"
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/ConditionalMacros.h>
+#include <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. 
 #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. 
index 5fe8d649d66cf917a32aeb4b0e00069c648a5e32..10d465b26bd15f792d278046e962cd279d5cab3e 100644 (file)
@@ -88,7 +88,7 @@ static CSSM_RETURN p12PbeGen(
        unsigned                        outbufLen)
 {
        CSSM_RETURN ourRtn = CSSM_OK;
        unsigned                        outbufLen)
 {
        CSSM_RETURN ourRtn = CSSM_OK;
-       unsigned unipassLen = pwd.Length;
+       unsigned unipassLen = (unsigned)pwd.Length;
        unsigned char *unipass = pwd.Data;
        int irtn;
        
        unsigned char *unipass = pwd.Data;
        int irtn;
        
@@ -173,8 +173,7 @@ static CSSM_RETURN p12PbeGen(
        /* one reusable hash object */
        DigestCtx ourDigest;
        DigestCtx *hashHand = &ourDigest;
        /* one reusable hash object */
        DigestCtx ourDigest;
        DigestCtx *hashHand = &ourDigest;
-       memset(hashHand, 0, sizeof(hashHand));
-       
+
        /* reused inside the loop */
        unsigned char *p12_B = (unsigned char *)coder.malloc(p12_v + 1);
        BIGNUM *Ij = BN_new();
        /* reused inside the loop */
        unsigned char *p12_B = (unsigned char *)coder.malloc(p12_v + 1);
        BIGNUM *Ij = BN_new();
@@ -350,11 +349,11 @@ void DeriveKey_PKCS12 (
                }
                
                /* convert unicode to chars with an extra double-NULL */
                }
                
                /* convert unicode to chars with an extra double-NULL */
-               unsigned len = CFStringGetLength(cfStr);
+               CFIndex len = CFStringGetLength(cfStr);
                tmpCoder.allocItem(pwd, sizeof(UniChar) * (len + 1));
                unsigned char *cp = pwd.Data;
                UniChar uc = 0;
                tmpCoder.allocItem(pwd, sizeof(UniChar) * (len + 1));
                unsigned char *cp = pwd.Data;
                UniChar uc = 0;
-               for(unsigned dex=0; dex<len; dex++) {
+               for(CFIndex dex=0; dex<len; dex++) {
                        uc = CFStringGetCharacterAtIndex(cfStr, dex);
                        *cp++ = uc >> 8;
                        *cp++ = uc & 0xff;
                        uc = CFStringGetCharacterAtIndex(cfStr, dex);
                        *cp++ = uc >> 8;
                        *cp++ = uc & 0xff;
@@ -380,7 +379,7 @@ void DeriveKey_PKCS12 (
        CssmData *csalt = context.get<CssmData>(CSSM_ATTRIBUTE_SALT);
        if(csalt) {
                salt = csalt->Data;
        CssmData *csalt = context.get<CssmData>(CSSM_ATTRIBUTE_SALT);
        if(csalt) {
                salt = csalt->Data;
-               saltLen = csalt->Length;
+               saltLen = (uint32)csalt->Length;
        }
        
        /* 
        }
        
        /* 
@@ -421,7 +420,7 @@ void DeriveKey_PKCS12 (
                CSSM_ALGID_SHA1,                        // all we support for now
                tmpCoder,
                keyData->Data,
                CSSM_ALGID_SHA1,                        // all we support for now
                tmpCoder,
                keyData->Data,
-               keyData->Length);
+               (unsigned)keyData->Length);
        if(crtn) {
                CssmError::throwMe(crtn);
        }
        if(crtn) {
                CssmError::throwMe(crtn);
        }
@@ -438,7 +437,7 @@ void DeriveKey_PKCS12 (
                        CSSM_ALGID_SHA1,                        // all we support for now
                        tmpCoder,
                        Param.Data,
                        CSSM_ALGID_SHA1,                        // all we support for now
                        tmpCoder,
                        Param.Data,
-                       Param.Length);
+                       (unsigned)Param.Length);
                if(crtn) {
                        CssmError::throwMe(crtn);
                }
                if(crtn) {
                        CssmError::throwMe(crtn);
                }
index e258b51fdbb4607ba5287ed1448e8d00cdece75a..d8810225cd2de811789b06c34d13bb03cf76e58c 100644 (file)
@@ -62,7 +62,7 @@ void RC2Context::init(
        }
 
        /* init the low-level state */
        }
 
        /* init the low-level state */
-       RC2_set_key(&rc2Key, keyLen, keyData, effectiveBits);
+       RC2_set_key(&rc2Key, (int)keyLen, keyData, effectiveBits);
 
        /* Finally, have BlockCryptor do its setup */
        setup(RC2_BLOCK_SIZE_BYTES, context);
 
        /* Finally, have BlockCryptor do its setup */
        setup(RC2_BLOCK_SIZE_BYTES, context);
index e3aeb905e852e6307bebeb1595acdbdf564630a3..71a5a69acced9c7bc8fe342107406a55ff33fce9 100644 (file)
@@ -24,9 +24,8 @@
 #define _RC4_CONTEXT_H_
 
 #include "AppleCSPContext.h"
 #define _RC4_CONTEXT_H_
 
 #include "AppleCSPContext.h"
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
 #include <CommonCrypto/CommonCryptor.h>
 #include <CommonCrypto/CommonCryptor.h>
-#include "/usr/local/include/CommonCrypto/CommonCryptorSPI.h"
+#include <CommonCrypto/CommonCryptorSPI.h>
 
 class RC4Context : public AppleCSPContext {
 public:
 
 class RC4Context : public AppleCSPContext {
 public:
index 24dfac0f20329ca4bfa509ebf2ca59a5cb16fac3..0b3566f4acff268616a1188d172aca4e2b138a53 100644 (file)
@@ -60,7 +60,7 @@ void RC5Context::init(
        }
 
        /* init the low-level state */
        }
 
        /* init the low-level state */
-       RC5_32_set_key(&rc5Key, keyLen, keyData, rounds);
+       RC5_32_set_key(&rc5Key, (int)keyLen, keyData, rounds);
 
        /* Finally, have BlockCryptor do its setup */
        setup(RC5_BLOCK_SIZE_BYTES, context);
 
        /* Finally, have BlockCryptor do its setup */
        setup(RC5_BLOCK_SIZE_BYTES, context);
index 2a35091444e944974acaf11fb24aaccfc3037d30..ff329cc60690f6b2f03c6b832350881d6d192f5d 100644 (file)
@@ -105,6 +105,7 @@ word8 mul(word8 a, word8 b) {
 }
 #endif /* !AES_MUL_BY_LOOKUP */
 
 }
 #endif /* !AES_MUL_BY_LOOKUP */
 
+static
 void KeyAddition(word8 a[4][MAXBC], word8 rk[4][MAXBC], word8 BC) {
        /* Exor corresponding text input and round key input bytes
         */
 void KeyAddition(word8 a[4][MAXBC], word8 rk[4][MAXBC], word8 BC) {
        /* Exor corresponding text input and round key input bytes
         */
@@ -114,6 +115,7 @@ void KeyAddition(word8 a[4][MAXBC], word8 rk[4][MAXBC], word8 BC) {
                for(j = 0; j < BC; j++) a[i][j] ^= rk[i][j];
 }
 
                for(j = 0; j < BC; j++) a[i][j] ^= rk[i][j];
 }
 
+static
 void ShiftRow(word8 a[4][MAXBC], word8 d, word8 BC) {
        /* Row 0 remains unchanged
         * The other three rows are shifted a variable amount
 void ShiftRow(word8 a[4][MAXBC], word8 d, word8 BC) {
        /* Row 0 remains unchanged
         * The other three rows are shifted a variable amount
@@ -127,6 +129,7 @@ void ShiftRow(word8 a[4][MAXBC], word8 d, word8 BC) {
        }
 }
 
        }
 }
 
+static
 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
 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
@@ -137,6 +140,7 @@ void Substitution(word8 a[4][MAXBC], const word8 box[256], word8 BC) {
                for(j = 0; j < BC; j++) a[i][j] = box[a[i][j]] ;
 }
    
                for(j = 0; j < BC; j++) a[i][j] = box[a[i][j]] ;
 }
    
+static
 void MixColumn(word8 a[4][MAXBC], word8 BC) {
        /* Mix the four bytes of every column in a linear way
         */
 void MixColumn(word8 a[4][MAXBC], word8 BC) {
        /* Mix the four bytes of every column in a linear way
         */
@@ -163,6 +167,7 @@ void MixColumn(word8 a[4][MAXBC], word8 BC) {
        }
 }
 
        }
 }
 
+static
 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
 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
index 2d84b2ce0fe1369554968b0575c6e21321f13354..44c3eb94f54428143a3e6cfc4b23747521740d5b 100644 (file)
@@ -698,7 +698,7 @@ void AppleCSPSession::UnwrapKey(
                                                CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING;
                                        if(unwrappedHdr.LogicalKeySizeInBits == 0) {
                                                unwrappedHdr.LogicalKeySizeInBits =
                                                CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING;
                                        if(unwrappedHdr.LogicalKeySizeInBits == 0) {
                                                unwrappedHdr.LogicalKeySizeInBits =
-                                                       bytesDecrypted * 8;
+                                                       (unsigned)(bytesDecrypted * 8);
                                        }
                                        /* app has to infer/know algorithm */
                                        break;
                                        }
                                        /* app has to infer/know algorithm */
                                        break;
index b35ac45e465506626509bf95db1ed08551b44aa0..75d64867e06cb130188aa033e6b4c866c91182af 100644 (file)
@@ -151,9 +151,9 @@ void AppleCSPSession::WrapKeyCms(
                ddLen = 0;
        }
        else {
                ddLen = 0;
        }
        else {
-               ddLen = DescriptiveData->Length;
+               ddLen = (uint32) DescriptiveData->Length;
        }
        }
-       uint32 pkbLen = 4 +  ddLen + rawBlob.Length;
+       size_t pkbLen = 4 +  ddLen + rawBlob.Length;
        setUpCssmData(PRIVATE_KEY_BYTES, pkbLen, privAllocator);
        uint8 *cp = PRIVATE_KEY_BYTES.Data;
        serializeUint32(ddLen, cp);
        setUpCssmData(PRIVATE_KEY_BYTES, pkbLen, privAllocator);
        uint8 *cp = PRIVATE_KEY_BYTES.Data;
        serializeUint32(ddLen, cp);
@@ -234,7 +234,7 @@ void AppleCSPSession::WrapKeyCms(
        #endif  /* REUSE_CONTEXT */
        
        uint8 *savedIV = IV2.Data;
        #endif  /* REUSE_CONTEXT */
        
        uint8 *savedIV = IV2.Data;
-       uint32 savedIVLen = IV2.Length;
+       CSSM_SIZE savedIVLen = IV2.Length;
        IV2.Data = (uint8 *)magicCmsIv;
        IV2.Length = 8;
        CssmData &outBlob = CssmData::overlay(WrappedKey.KeyData);
        IV2.Data = (uint8 *)magicCmsIv;
        IV2.Length = 8;
        CssmData &outBlob = CssmData::overlay(WrappedKey.KeyData);
@@ -317,7 +317,7 @@ void AppleCSPSession::UnwrapKeyCms(
        CssmData &IV1 = Context.get<CssmData>(CSSM_ATTRIBUTE_INIT_VECTOR, 
                                CSSMERR_CSP_MISSING_ATTR_INIT_VECTOR);
        uint8 *savedIV = IV1.Data;
        CssmData &IV1 = Context.get<CssmData>(CSSM_ATTRIBUTE_INIT_VECTOR, 
                                CSSMERR_CSP_MISSING_ATTR_INIT_VECTOR);
        uint8 *savedIV = IV1.Data;
-       uint32 savedIvLen = IV1.Length;
+       CSSM_SIZE savedIvLen = IV1.Length;
        IV1.Data = (uint8 *)magicCmsIv;
        IV1.Length = 8;
        CssmData TEMP3;
        IV1.Data = (uint8 *)magicCmsIv;
        IV1.Length = 8;
        CssmData TEMP3;
@@ -432,7 +432,7 @@ void AppleCSPSession::UnwrapKeyCms(
        setUpCssmData(DescriptiveData, ddLen, normAllocator);
        memcpy(DescriptiveData.Data, cp1, ddLen);
        cp1 += ddLen;
        setUpCssmData(DescriptiveData, ddLen, normAllocator);
        memcpy(DescriptiveData.Data, cp1, ddLen);
        cp1 += ddLen;
-       uint32 outBlobLen = PRIVATE_KEY_BYTES.Length - ddLen - 4;
+       size_t 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);
        if(ddLen > MAX_MALLOC_SIZE) {
                dprintf0("UnwrapKeyCms: preposterous outBlobLen in PRIVATE_KEY_BYTES\n");
                CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
index 8db494d82f91db0a617c71779ac1d685dbf88d17..043c165f686aa13d65d309291988852dd1072f99 100644 (file)
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0420;
+                               LastUpgradeCheck = 0500;
                        };
                        buildConfigurationList = C27AD2550987FCDC001272E0 /* Build configuration list for PBXProject "libsecurity_apple_csp" */;
                        compatibilityVersion = "Xcode 3.2";
                        };
                        buildConfigurationList = C27AD2550987FCDC001272E0 /* Build configuration list for PBXProject "libsecurity_apple_csp" */;
                        compatibilityVersion = "Xcode 3.2";
                053910870A37725A00B9E848 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                053910870A37725A00B9E848 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                        };
                        name = Debug;
                };
                0539108A0A37725A00B9E848 /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                        };
                        name = Debug;
                };
                0539108A0A37725A00B9E848 /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446066146DE98E00B12992 /* debug.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446066146DE98E00B12992 /* debug.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
                                HEADER_SEARCH_PATHS = (
                                        "$(inherited)",
                                        "$(PROJECT_DIR)/open_ssl",
                                HEADER_SEARCH_PATHS = (
                                        "$(inherited)",
                                        "$(PROJECT_DIR)/open_ssl",
                                        "-DASC_CSP_ENABLE",
                                        "-DCK_SECURITY_BUILD",
                                );
                                        "-DASC_CSP_ENABLE",
                                        "-DCK_SECURITY_BUILD",
                                );
+                               WARNING_CFLAGS = (
+                                       "$(inherited)",
+                                       "-Wno-error=overloaded-virtual",
+                               );
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446068146DE98E00B12992 /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446068146DE98E00B12992 /* release.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
                                HEADER_SEARCH_PATHS = (
                                        "$(inherited)",
                                        "$(PROJECT_DIR)/open_ssl",
                                HEADER_SEARCH_PATHS = (
                                        "$(inherited)",
                                        "$(PROJECT_DIR)/open_ssl",
                                        "-DASC_CSP_ENABLE",
                                        "-DCK_SECURITY_BUILD",
                                );
                                        "-DASC_CSP_ENABLE",
                                        "-DCK_SECURITY_BUILD",
                                );
+                               WARNING_CFLAGS = (
+                                       "$(inherited)",
+                                       "-Wno-error=overloaded-virtual",
+                               );
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446067146DE98E00B12992 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446067146DE98E00B12992 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446067146DE98E00B12992 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446067146DE98E00B12992 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
index 778420b0899215a5b3520b2bba58088a62f888ab..40b982edd10023891d46548213e2598d18ea3232 100644 (file)
 #include <openssl/opensslconf.h> /* BF_PTR, BF_PTR2 */
 
 #undef c2l
 #include <openssl/opensslconf.h> /* BF_PTR, BF_PTR2 */
 
 #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)
+#define c2l(c,l)       (l =(((BF_LONG))(*((c)++)))    , \
+                        l|=(((BF_LONG))(*((c)++)))<< 8L, \
+                        l|=(((BF_LONG))(*((c)++)))<<16L, \
+                        l|=(((BF_LONG))(*((c)++)))<<24L)
 
 /* NOTE - c is not incremented as per c2l */
 #undef c2ln
 
 /* NOTE - c is not incremented as per c2l */
 #undef c2ln
                        c+=n; \
                        l1=l2=0; \
                        switch (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))));     \
+                       case 8: l2 =(((BF_LONG))(*(--(c))))<<24L; \
+                       case 7: l2|=(((BF_LONG))(*(--(c))))<<16L; \
+                       case 6: l2|=(((BF_LONG))(*(--(c))))<< 8L; \
+                       case 5: l2|=(((BF_LONG))(*(--(c))));     \
+                       case 4: l1 =(((BF_LONG))(*(--(c))))<<24L; \
+                       case 3: l1|=(((BF_LONG))(*(--(c))))<<16L; \
+                       case 2: l1|=(((BF_LONG))(*(--(c))))<< 8L; \
+                       case 1: l1|=(((BF_LONG))(*(--(c))));     \
                                } \
                        }
 
                                } \
                        }
 
                        c+=n; \
                        l1=l2=0; \
                        switch (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; \
+                       case 8: l2 =((BF_LONG)(*(--(c))))    ; \
+                       case 7: l2|=((BF_LONG)(*(--(c))))<< 8; \
+                       case 6: l2|=((BF_LONG)(*(--(c))))<<16; \
+                       case 5: l2|=((BF_LONG)(*(--(c))))<<24; \
+                       case 4: l1 =((BF_LONG)(*(--(c))))    ; \
+                       case 3: l1|=((BF_LONG)(*(--(c))))<< 8; \
+                       case 2: l1|=((BF_LONG)(*(--(c))))<<16; \
+                       case 1: l1|=((BF_LONG)(*(--(c))))<<24; \
                                } \
                        }
 
                                } \
                        }
 
 #undef n2l
 #if    defined(__GNUC__) && defined(__ppc__)
 /* alignment tolerant big-endian optimization */
 #undef n2l
 #if    defined(__GNUC__) && defined(__ppc__)
 /* alignment tolerant big-endian optimization */
-       #define n2l(c,l)        { l= *((unsigned long *)c); c += 4; }
+       #define n2l(c,l)        { l= *(((BF_LONG) *)c); c += 4; }
 #else
 /* little endian, etc. */
 #else
 /* little endian, etc. */
-       #define n2l(c,l)        (l =((unsigned long)(*((c)++)))<<24L, \
-                         l|=((unsigned long)(*((c)++)))<<16L, \
-                         l|=((unsigned long)(*((c)++)))<< 8L, \
-                         l|=((unsigned long)(*((c)++))))
+       #define n2l(c,l)        (l =((BF_LONG)(*((c)++)))<<24L, \
+                         l|=((BF_LONG)(*((c)++)))<<16L, \
+                         l|=((BF_LONG)(*((c)++)))<< 8L, \
+                         l|=((BF_LONG)(*((c)++))))
 #endif
 
 #undef l2n
 #if    defined(__GNUC__) && defined(__ppc__)
        /* alignment tolerant big-endian optimization */
 #endif
 
 #undef l2n
 #if    defined(__GNUC__) && defined(__ppc__)
        /* alignment tolerant big-endian optimization */
-       #define l2n(l,c)        { *((unsigned long *)c) = l; c += 4; }
+       #define l2n(l,c)        { *(((BF_LONG) *)c) = l; c += 4; }
 #else
        /* little endian, etc. */
        #define l2n(l,c)    (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
 #else
        /* little endian, etc. */
        #define l2n(l,c)    (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
index 97ad27b7634d9687977324d2d38a27c591d4840a..ccaabd7b3ffa0a455d672c63e1766554d0230c2f 100644 (file)
@@ -176,7 +176,7 @@ static int MS_CALLBACK file_read(BIO *b, char *out, int outl)
 
        if (b->init && (out != NULL))
                {
 
        if (b->init && (out != NULL))
                {
-               ret=fread(out,1,(int)outl,(FILE *)b->ptr);
+               ret=(int)fread(out,1,outl,(FILE *)b->ptr);
                }
        return(ret);
        }
                }
        return(ret);
        }
@@ -308,7 +308,7 @@ static int MS_CALLBACK file_gets(BIO *bp, char *buf, int size)
        buf[0]='\0';
        fgets(buf,size,(FILE *)bp->ptr);
        if (buf[0] != '\0')
        buf[0]='\0';
        fgets(buf,size,(FILE *)bp->ptr);
        if (buf[0] != '\0')
-               ret=strlen(buf);
+               ret=(int)strlen(buf);
        return(ret);
        }
 
        return(ret);
        }
 
@@ -316,7 +316,7 @@ static int MS_CALLBACK file_puts(BIO *bp, char *str)
        {
        int n,ret;
 
        {
        int n,ret;
 
-       n=strlen(str);
+       n=(int)strlen(str);
        ret=file_write(bp,str,n);
        return(ret);
        }
        ret=file_write(bp,str,n);
        return(ret);
        }
index 4faf351b050fc90e6c490330e8e22f0095cf36a5..58f22f0c9ebf462218b47fb428836a063084cc60 100644 (file)
@@ -157,12 +157,12 @@ char *BN_bn2dec(const BIGNUM *a)
                /* 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. */
                /* 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);
+               sprintf(p,BN_DEC_FMT1,(unsigned long)*lp);
                while (*p) p++;
                while (lp != bn_data)
                        {
                        lp--;
                while (*p) p++;
                while (lp != bn_data)
                        {
                        lp--;
-                       sprintf(p,BN_DEC_FMT2,*lp);
+                       sprintf(p,BN_DEC_FMT2,(unsigned long)*lp);
                        while (*p) p++;
                        }
                }
                        while (*p) p++;
                        }
                }
index 05eeff1f2e980e4b3fcceeace06a39f35d8892b0..9f7464a31c87d6a224daa91e5f39f9069596d168 100644 (file)
@@ -164,7 +164,7 @@ int     BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom)
        return bnrand(1, rnd, bits, top, bottom);
        }
 
        return bnrand(1, rnd, bits, top, bottom);
        }
 
-#if 1
+#if 0
 int     BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom)
        {
        return bnrand(2, rnd, bits, top, bottom);
 int     BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom)
        {
        return bnrand(2, rnd, bits, top, bottom);
index 5fa4d11d9faa62eb36f2cc15833f0d2f7e82fab6..317b6953d33b34e5a8352956f5ebccacfad0dce0 100644 (file)
@@ -145,7 +145,7 @@ int BUF_MEM_grow(BUF_MEM *str, int len)
 char *BUF_strdup(const char *str)
        {
        char *ret;
 char *BUF_strdup(const char *str)
        {
        char *ret;
-       int n;
+       size_t n;
 
        if (str == NULL) return(NULL);
 
 
        if (str == NULL) return(NULL);
 
index 32325ca14c034e5b1ca1d929dc6395bade2980e2..ebf63535b8c913449620d87ad69963aaacdc1bda 100644 (file)
@@ -506,7 +506,7 @@ char *ERR_error_string(unsigned long e, char *ret)
        static char buf[256];
        const char *ls,*fs,*rs;
        unsigned long l,f,r;
        static char buf[256];
        const char *ls,*fs,*rs;
        unsigned long l,f,r;
-       int i;
+       size_t i;
 
        l=ERR_GET_LIB(e);
        f=ERR_GET_FUNC(e);
 
        l=ERR_GET_LIB(e);
        f=ERR_GET_FUNC(e);
index a878c75fa9028ff1bab0054ac81b86f72cc296e5..3d78601903c9378c4638779cfc3476b412c0f351 100644 (file)
@@ -114,9 +114,9 @@ void ERR_print_errors(BIO *bp)
                {
                sprintf(buf2,"%lu:%s:%s:%d:",es,ERR_error_string(l,buf),
                        file,line);
                {
                sprintf(buf2,"%lu:%s:%s:%d:",es,ERR_error_string(l,buf),
                        file,line);
-               BIO_write(bp,buf2,strlen(buf2));
+               BIO_write(bp,buf2,(int)strlen(buf2));
                if (flags & ERR_TXT_STRING)
                if (flags & ERR_TXT_STRING)
-                       BIO_write(bp,data,strlen(data));
+                       BIO_write(bp,data,(int)strlen(data));
                BIO_write(bp,"\n",1);
                }
        }
                BIO_write(bp,"\n",1);
                }
        }
index f53628c40138e61f70df95184ee332d413d45ed5..a2b5492a7e6cf71e394b223805f0bb993a6c7dd6 100644 (file)
@@ -200,8 +200,8 @@ void RC2_encrypt(unsigned long *d, RC2_KEY *key)
                        }
                }
 
                        }
                }
 
-       d[0]=(unsigned long)(x0&0xffff)|((unsigned long)(x1&0xffff)<<16L);
-       d[1]=(unsigned long)(x2&0xffff)|((unsigned long)(x3&0xffff)<<16L);
+       d[0]=(RC2_INT)(x0&0xffff)|((RC2_INT)(x1&0xffff)<<16L);
+       d[1]=(RC2_INT)(x2&0xffff)|((RC2_INT)(x3&0xffff)<<16L);
        }
 
 #ifdef _OPENSSL_APPLE_CDSA_
        }
 
 #ifdef _OPENSSL_APPLE_CDSA_
@@ -250,7 +250,7 @@ void RC2_decrypt(unsigned long *d, RC2_KEY *key)
                        }
                }
 
                        }
                }
 
-       d[0]=(unsigned long)(x0&0xffff)|((unsigned long)(x1&0xffff)<<16L);
-       d[1]=(unsigned long)(x2&0xffff)|((unsigned long)(x3&0xffff)<<16L);
+       d[0]=(RC2_INT)(x0&0xffff)|((RC2_INT)(x1&0xffff)<<16L);
+       d[1]=(RC2_INT)(x2&0xffff)|((RC2_INT)(x3&0xffff)<<16L);
        }
 
        }
 
index 6b66202b3f6a905d79f3956cf1ca923a04c4784e..8ac27a1ad64665108eef3b2b5441598f48d906da 100644 (file)
  */
 
 #undef c2l
  */
 
 #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)
+#define c2l(c,l)       (l =((RC2_INT)(*((c)++)))    , \
+                        l|=((RC2_INT)(*((c)++)))<< 8L, \
+                        l|=((RC2_INT)(*((c)++)))<<16L, \
+                        l|=((RC2_INT)(*((c)++)))<<24L)
 
 /* NOTE - c is not incremented as per c2l */
 #undef c2ln
 
 /* NOTE - c is not incremented as per c2l */
 #undef c2ln
                        c+=n; \
                        l1=l2=0; \
                        switch (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))));     \
+                       case 8: l2 =((RC2_INT)(*(--(c))))<<24L; \
+                       case 7: l2|=((RC2_INT)(*(--(c))))<<16L; \
+                       case 6: l2|=((RC2_INT)(*(--(c))))<< 8L; \
+                       case 5: l2|=((RC2_INT)(*(--(c))));     \
+                       case 4: l1 =((RC2_INT)(*(--(c))))<<24L; \
+                       case 3: l1|=((RC2_INT)(*(--(c))))<<16L; \
+                       case 2: l1|=((RC2_INT)(*(--(c))))<< 8L; \
+                       case 1: l1|=((RC2_INT)(*(--(c))));     \
                                } \
                        }
 
                                } \
                        }
 
                        c+=n; \
                        l1=l2=0; \
                        switch (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; \
+                       case 8: l2 =((RC2_INT)(*(--(c))))    ; \
+                       case 7: l2|=((RC2_INT)(*(--(c))))<< 8; \
+                       case 6: l2|=((RC2_INT)(*(--(c))))<<16; \
+                       case 5: l2|=((RC2_INT)(*(--(c))))<<24; \
+                       case 4: l1 =((RC2_INT)(*(--(c))))    ; \
+                       case 3: l1|=((RC2_INT)(*(--(c))))<< 8; \
+                       case 2: l1|=((RC2_INT)(*(--(c))))<<16; \
+                       case 1: l1|=((RC2_INT)(*(--(c))))<<24; \
                                } \
                        }
 
                                } \
                        }
 
                        }
 
 #undef n2l
                        }
 
 #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)++))))
+#define n2l(c,l)        (l =((RC2_INT)(*((c)++)))<<24L, \
+                         l|=((RC2_INT)(*((c)++)))<<16L, \
+                         l|=((RC2_INT)(*((c)++)))<< 8L, \
+                         l|=((RC2_INT)(*((c)++))))
 
 #undef l2n
 #define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
 
 #undef l2n
 #define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
index 2c45d85df774b186a28b278ec790b79bdc0ba4a3..9840861569008607f6a19e6bb4823bd9258cc159 100644 (file)
 #include <stdlib.h>
 
 #undef c2l
 #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)
+#define c2l(c,l)       (l =((RC5_32_INT)(*((c)++)))    , \
+                        l|=((RC5_32_INT)(*((c)++)))<< 8L, \
+                        l|=((RC5_32_INT)(*((c)++)))<<16L, \
+                        l|=((RC5_32_INT)(*((c)++)))<<24L)
 
 /* NOTE - c is not incremented as per c2l */
 #undef c2ln
 
 /* NOTE - c is not incremented as per c2l */
 #undef c2ln
                        c+=n; \
                        l1=l2=0; \
                        switch (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))));     \
+                       case 8: l2 =((RC5_32_INT)(*(--(c))))<<24L; \
+                       case 7: l2|=((RC5_32_INT)(*(--(c))))<<16L; \
+                       case 6: l2|=((RC5_32_INT)(*(--(c))))<< 8L; \
+                       case 5: l2|=((RC5_32_INT)(*(--(c))));     \
+                       case 4: l1 =((RC5_32_INT)(*(--(c))))<<24L; \
+                       case 3: l1|=((RC5_32_INT)(*(--(c))))<<16L; \
+                       case 2: l1|=((RC5_32_INT)(*(--(c))))<< 8L; \
+                       case 1: l1|=((RC5_32_INT)(*(--(c))));     \
                                } \
                        }
 
                                } \
                        }
 
                        c+=n; \
                        l1=l2=0; \
                        switch (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; \
+                       case 8: l2 =((RC5_32_INT)(*(--(c))))    ; \
+                       case 7: l2|=((RC5_32_INT)(*(--(c))))<< 8; \
+                       case 6: l2|=((RC5_32_INT)(*(--(c))))<<16; \
+                       case 5: l2|=((RC5_32_INT)(*(--(c))))<<24; \
+                       case 4: l1 =((RC5_32_INT)(*(--(c))))    ; \
+                       case 3: l1|=((RC5_32_INT)(*(--(c))))<< 8; \
+                       case 2: l1|=((RC5_32_INT)(*(--(c))))<<16; \
+                       case 1: l1|=((RC5_32_INT)(*(--(c))))<<24; \
                                } \
                        }
 
                                } \
                        }
 
                        }
 
 #undef n2l
                        }
 
 #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)++))))
+#define n2l(c,l)        (l =((RC5_32_INT)(*((c)++)))<<24L, \
+                         l|=((RC5_32_INT)(*((c)++)))<<16L, \
+                         l|=((RC5_32_INT)(*((c)++)))<< 8L, \
+                         l|=((RC5_32_INT)(*((c)++))))
 
 #undef l2n
 #define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
 
 #undef l2n
 #define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
index 7a211b909fe21662f6a4a948e21b4da873aacff4..74d064a050cb6d199997e2a6935b5c40ac451926 100644 (file)
@@ -67,7 +67,7 @@ BIGNUM *cssmDataToBn(
        BIGNUM *bn = BN_new();
        BIGNUM *rtn;
 
        BIGNUM *bn = BN_new();
        BIGNUM *rtn;
 
-       rtn = BN_bin2bn(cdata.Data, cdata.Length, bn);
+       rtn = BN_bin2bn(cdata.Data, (int)cdata.Length, bn);
        if(rtn == NULL) {
                BN_free(bn);
                CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);
        if(rtn == NULL) {
                BN_free(bn);
                CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);
@@ -253,7 +253,7 @@ static CSSM_RETURN RSAPublicKeyDecodeX509(
                        return CSSMERR_CSP_INVALID_KEY;
                }
                if(nssPubKeyInfo.algorithm.parameters.Data != NULL) {
                        return CSSMERR_CSP_INVALID_KEY;
                }
                if(nssPubKeyInfo.algorithm.parameters.Data != NULL) {
-                       uint32 len = nssPubKeyInfo.algorithm.parameters.Length;
+                       CSSM_SIZE len = nssPubKeyInfo.algorithm.parameters.Length;
                        *algParams = (uint8 *)malloc(len);
                        memmove(*algParams, nssPubKeyInfo.algorithm.parameters.Data, len);
                        *algParamLen = len;
                        *algParams = (uint8 *)malloc(len);
                        memmove(*algParams, nssPubKeyInfo.algorithm.parameters.Data, len);
                        *algParamLen = len;
@@ -420,7 +420,7 @@ static CSSM_RETURN RSAPrivateKeyDecodePKCS8(
                        return CSSMERR_CSP_INVALID_KEY;
                }
                if(nssPrivKeyInfo.algorithm.parameters.Data != NULL) {
                        return CSSMERR_CSP_INVALID_KEY;
                }
                if(nssPrivKeyInfo.algorithm.parameters.Data != NULL) {
-                       uint32 len = nssPrivKeyInfo.algorithm.parameters.Length;
+                       CSSM_SIZE len = nssPrivKeyInfo.algorithm.parameters.Length;
                        *algParams = (uint8 *)malloc(len);
                        memmove(*algParams, nssPrivKeyInfo.algorithm.parameters.Data, len);
                        *algParamLen = len;
                        *algParams = (uint8 *)malloc(len);
                        memmove(*algParams, nssPrivKeyInfo.algorithm.parameters.Data, len);
                        *algParamLen = len;
@@ -585,7 +585,7 @@ CSSM_RETURN RSAOAEPPrivateKeyEncode(
        CSSM_DATA encodedParams = {0, NULL};
        /* TBD encode the label into a RSAES-OAEP-params */
 
        CSSM_DATA encodedParams = {0, NULL};
        /* TBD encode the label into a RSAES-OAEP-params */
 
-       return RSAPrivateKeyEncodePKCS8(coder, openKey, encodedKey, encodedParams.Data, encodedParams.Length);
+       return RSAPrivateKeyEncodePKCS8(coder, openKey, encodedKey, encodedParams.Data, (unsigned int)encodedParams.Length);
 }
 
 CSSM_RETURN    RSAOAEPPublicKeyEncode(
 }
 
 CSSM_RETURN    RSAOAEPPublicKeyEncode(
@@ -597,7 +597,7 @@ CSSM_RETURN RSAOAEPPublicKeyEncode(
        CSSM_DATA encodedParams = {0, NULL};
        /* TBD encode the label into a RSAES-OAEP-params */
 
        CSSM_DATA encodedParams = {0, NULL};
        /* TBD encode the label into a RSAES-OAEP-params */
 
-       return RSAPublicKeyEncodeX509(coder, openKey, encodedKey, encodedParams.Data, encodedParams.Length);
+       return RSAPublicKeyEncodeX509(coder, openKey, encodedKey, encodedParams.Data, (unsigned int)encodedParams.Length);
 }
 
 CSSM_RETURN RSAOAEPPublicKeyDecode(
 }
 
 CSSM_RETURN RSAOAEPPublicKeyDecode(
@@ -718,11 +718,12 @@ static CSSM_RETURN nssAlgIdToDsaX509(
  * DSA public keys, FIPS186 format.
  * Compatible with BSAFE.
  */
  * DSA public keys, FIPS186 format.
  * Compatible with BSAFE.
  */
+static
 CSSM_RETURN DSAPublicKeyDecodeFIPS186(
        SecNssCoder     &coder,
        DSA                     *openKey, 
        void                    *p, 
 CSSM_RETURN DSAPublicKeyDecodeFIPS186(
        SecNssCoder     &coder,
        DSA                     *openKey, 
        void                    *p, 
-       unsigned                length)
+       size_t          length)
 {
        NSS_DSAPublicKeyBSAFE nssPubKey;
        PRErrorCode perr;
 {
        NSS_DSAPublicKeyBSAFE nssPubKey;
        PRErrorCode perr;
@@ -762,6 +763,7 @@ CSSM_RETURN DSAPublicKeyDecodeFIPS186(
        return 0;
 }
 
        return 0;
 }
 
+static
 CSSM_RETURN    DSAPublicKeyEncodeFIPS186(
        SecNssCoder             &coder,
        DSA                     *openKey, 
 CSSM_RETURN    DSAPublicKeyEncodeFIPS186(
        SecNssCoder             &coder,
        DSA                     *openKey, 
@@ -803,6 +805,7 @@ CSSM_RETURN DSAPublicKeyEncodeFIPS186(
  * DSA private keys, FIPS186 format.
  * Compatible with BSAFE.
  */
  * DSA private keys, FIPS186 format.
  * Compatible with BSAFE.
  */
+static
 CSSM_RETURN DSAPrivateKeyDecodeFIPS186(
        SecNssCoder     &coder,
        DSA                     *openKey, 
 CSSM_RETURN DSAPrivateKeyDecodeFIPS186(
        SecNssCoder     &coder,
        DSA                     *openKey, 
@@ -849,6 +852,7 @@ CSSM_RETURN DSAPrivateKeyDecodeFIPS186(
        }
 }
 
        }
 }
 
+static
 CSSM_RETURN    DSAPrivateKeyEncodeFIPS186(
        SecNssCoder     &coder,
        DSA                     *openKey, 
 CSSM_RETURN    DSAPrivateKeyEncodeFIPS186(
        SecNssCoder     &coder,
        DSA                     *openKey, 
@@ -884,6 +888,7 @@ CSSM_RETURN DSAPrivateKeyEncodeFIPS186(
 /* 
  * DSA private keys, PKCS8/SMIME format.
  */
 /* 
  * DSA private keys, PKCS8/SMIME format.
  */
+static
 CSSM_RETURN DSAPrivateKeyDecodePKCS8(
        SecNssCoder     &coder,
        DSA                     *openKey, 
 CSSM_RETURN DSAPrivateKeyDecodePKCS8(
        SecNssCoder     &coder,
        DSA                     *openKey, 
@@ -932,6 +937,7 @@ CSSM_RETURN DSAPrivateKeyDecodePKCS8(
        }
 }
 
        }
 }
 
+static
 CSSM_RETURN    DSAPrivateKeyEncodePKCS8(
        SecNssCoder     &coder,
        DSA                     *openKey, 
 CSSM_RETURN    DSAPrivateKeyEncodePKCS8(
        SecNssCoder     &coder,
        DSA                     *openKey, 
@@ -1210,11 +1216,11 @@ CSSM_RETURN DSAPrivateKeyDecode(
 
        switch(format) {
                case CSSM_KEYBLOB_RAW_FORMAT_FIPS186:
 
        switch(format) {
                case CSSM_KEYBLOB_RAW_FORMAT_FIPS186:
-                       return DSAPrivateKeyDecodeFIPS186(coder, openKey, p, length);
+                       return DSAPrivateKeyDecodeFIPS186(coder, openKey, p, (unsigned)length);
                case CSSM_KEYBLOB_RAW_FORMAT_OPENSSL:
                        return DSAPrivateKeyDecodeOpenssl(coder, openKey, p, length);
                case CSSM_KEYBLOB_RAW_FORMAT_PKCS8:
                case CSSM_KEYBLOB_RAW_FORMAT_OPENSSL:
                        return DSAPrivateKeyDecodeOpenssl(coder, openKey, p, length);
                case CSSM_KEYBLOB_RAW_FORMAT_PKCS8:
-                       return DSAPrivateKeyDecodePKCS8(coder, openKey, p, length);
+                       return DSAPrivateKeyDecodePKCS8(coder, openKey, p, (unsigned)length);
                default:
                        assert(0);
                        return CSSMERR_CSP_INTERNAL_ERROR;
                default:
                        assert(0);
                        return CSSMERR_CSP_INTERNAL_ERROR;
@@ -1331,7 +1337,7 @@ CSSM_RETURN DSADecodeAlgParams(
 
 #pragma mark -
 #pragma mark *** Diffie-Hellman key encode/decode ***
 
 #pragma mark -
 #pragma mark *** Diffie-Hellman key encode/decode ***
-
+static
 CSSM_RETURN DHPrivateKeyDecodePKCS3(
        SecNssCoder             &coder,
        DH                              *openKey, 
 CSSM_RETURN DHPrivateKeyDecodePKCS3(
        SecNssCoder             &coder,
        DH                              *openKey, 
@@ -1370,6 +1376,7 @@ CSSM_RETURN DHPrivateKeyDecodePKCS3(
        return 0;
 }
 
        return 0;
 }
 
+static
 CSSM_RETURN    DHPrivateKeyEncodePKCS3(
        SecNssCoder             &coder,
        DH                              *openKey, 
 CSSM_RETURN    DHPrivateKeyEncodePKCS3(
        SecNssCoder             &coder,
        DH                              *openKey, 
@@ -1459,6 +1466,7 @@ static CSSM_RETURN nssAlgIdToDhX942(
        return CSSM_OK;
 }
 
        return CSSM_OK;
 }
 
+static
 CSSM_RETURN DHPrivateKeyDecodePKCS8(
        SecNssCoder             &coder,
        DH                              *openKey, 
 CSSM_RETURN DHPrivateKeyDecodePKCS8(
        SecNssCoder             &coder,
        DH                              *openKey, 
@@ -1500,6 +1508,7 @@ CSSM_RETURN DHPrivateKeyDecodePKCS8(
        return 0;
 }
 
        return 0;
 }
 
+static
 CSSM_RETURN    DHPrivateKeyEncodePKCS8(
        SecNssCoder             &coder,
        DH                              *openKey, 
 CSSM_RETURN    DHPrivateKeyEncodePKCS8(
        SecNssCoder             &coder,
        DH                              *openKey, 
index 00a867ec291a6f00cebb8c7f2069f3e009cb664f..305147168620ab77f77ed5c0c1892036e75ec4fa 100644 (file)
@@ -143,7 +143,7 @@ SSCSPDLSession::didChangeKeyAcl(SecurityServer::ClientSession &clientSession,
        else
        {
                // @@@ Should we really throw here or just continue without updating the ACL?  In reality this should never happen, so let's at least log it and throw.
        else
        {
                // @@@ Should we really throw here or just continue without updating the ACL?  In reality this should never happen, so let's at least log it and throw.
-               secdebug("keyacl", "SSCSPDLSession::didChangeKeyAcl() keyHandle: %lu not found in map", keyHandle);
+               secdebug("keyacl", "SSCSPDLSession::didChangeKeyAcl() keyHandle: %lu not found in map", (unsigned long)keyHandle);
                CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_REFERENCE);
        }
 }
                CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_REFERENCE);
        }
 }
index 650e1d8400600c9b8f8d19d829739c87e86eb4c3..994ef203e489eb09377cb235277f64af58b8a3bc 100644 (file)
@@ -333,8 +333,8 @@ SSCSPSession::ObtainPrivateKeyFromPublicKey(const CssmKey &PublicKey,
 
 void
 SSCSPSession::QueryKeySizeInBits(CSSM_CC_HANDLE CCHandle,
 
 void
 SSCSPSession::QueryKeySizeInBits(CSSM_CC_HANDLE CCHandle,
-                                                                const Context &Context,
-                                                                const CssmKey &Key,
+                                                                const Context *Context,
+                                                                const CssmKey *Key,
                                                                 CSSM_KEY_SIZE &KeySize)
 {
        unimplemented();
                                                                 CSSM_KEY_SIZE &KeySize)
 {
        unimplemented();
index ff27dbbdefa6f47153ff4ead92ae349f406bdb3e..35da74967b8fc9ec328c3254f0407b428166c65c 100644 (file)
@@ -121,8 +121,8 @@ public:
        void ObtainPrivateKeyFromPublicKey(const CssmKey &PublicKey,
                                                                        CssmKey &PrivateKey);
        void QueryKeySizeInBits(CSSM_CC_HANDLE CCHandle,
        void ObtainPrivateKeyFromPublicKey(const CssmKey &PublicKey,
                                                                        CssmKey &PrivateKey);
        void QueryKeySizeInBits(CSSM_CC_HANDLE CCHandle,
-                                                       const Context &Context,
-                                                       const CssmKey &Key,
+                                                       const Context *Context,
+                                                       const CssmKey *Key,
                                                        CSSM_KEY_SIZE &KeySize);
        void FreeKey(const AccessCredentials *AccessCred,
                                CssmKey &key, CSSM_BOOL Delete);
                                                        CSSM_KEY_SIZE &KeySize);
        void FreeKey(const AccessCredentials *AccessCred,
                                CssmKey &key, CSSM_BOOL Delete);
index 0acbe52a968e4804ea2069845b0c5e188f2b7465..df3e887b8b2ad59fb57778e5b6be569e18c0e781 100644 (file)
@@ -292,7 +292,7 @@ size_t SSSignatureContext::outputSize(bool final, size_t inSize)
                        /* FIXME - what to use for inSize here - we don't want to 
                         * interrogate mDigest, as that would result in another RPC...
                         * and signature size is not related to input size...right? */
                        /* FIXME - what to use for inSize here - we don't want to 
                         * interrogate mDigest, as that would result in another RPC...
                         * and signature size is not related to input size...right? */
-                       inSize,
+                       (uint32)inSize,
                        true);
                ssCryptDebug("===sig outputSize(RPC) %u", (unsigned)outSize);
                return (size_t)outSize;
                        true);
                ssCryptDebug("===sig outputSize(RPC) %u", (unsigned)outSize);
                return (size_t)outSize;
@@ -446,7 +446,7 @@ SSCryptContext::outputSize(bool final, size_t inSize)
                /* out-of-band case, ask CSP via SS */
                uint32 outSize = clientSession().getOutputSize(*mContext, 
                        mKeyHandle, 
                /* out-of-band case, ask CSP via SS */
                uint32 outSize = clientSession().getOutputSize(*mContext, 
                        mKeyHandle, 
-                       inBufSize + inSize,
+                       (uint32)(inBufSize + inSize),
                        encoding());
                ssCryptDebug("   ===outSize(RPC) %u", (unsigned)outSize);
                return (size_t)outSize;
                        encoding());
                ssCryptDebug("   ===outSize(RPC) %u", (unsigned)outSize);
                return (size_t)outSize;
@@ -488,7 +488,7 @@ SSCryptContext::final(CssmData &out)
        if(!inSize) return;
 
        const CssmData in(const_cast<void *>(mNullDigest.digestPtr()), inSize);
        if(!inSize) return;
 
        const CssmData in(const_cast<void *>(mNullDigest.digestPtr()), inSize);
-       IFDEBUG(unsigned origOutSize = out.length());
+       IFDEBUG(size_t origOutSize = out.length());
        if (encoding()) {
                clientSession().encrypt(*mContext, mKeyHandle, in, out);
        }
        if (encoding()) {
                clientSession().encrypt(*mContext, mKeyHandle, in, out);
        }
@@ -536,7 +536,7 @@ size_t SSDigestContext::outputSize(bool final, size_t inSize)
                return 0;
        }
        else {
                return 0;
        }
        else {
-               return (size_t)mDigest->getOutputSize(inSize);
+               return (size_t)mDigest->getOutputSize((uint32)inSize);
        }
 }
 
        }
 }
 
@@ -591,7 +591,7 @@ size_t SSMACContext::outputSize(bool final, size_t inSize)
                /* out-of-band case, ask CSP via SS */
                uint32 outSize = clientSession().getOutputSize(*mContext, 
                        mKeyHandle, 
                /* out-of-band case, ask CSP via SS */
                uint32 outSize = clientSession().getOutputSize(*mContext, 
                        mKeyHandle, 
-                       inSize + mNullDigest.digestSizeInBytes(),
+                       (uint32)(inSize + mNullDigest.digestSizeInBytes()),
                        true);
                ssCryptDebug("===mac outputSize(RPC) %u", (unsigned)outSize);
                return (size_t)outSize;
                        true);
                ssCryptDebug("===mac outputSize(RPC) %u", (unsigned)outSize);
                return (size_t)outSize;
index c7e1354f582ff8ea0338551d09fa3014a55e70a9..942d2d93842519098764af10f7d298f048594520 100644 (file)
@@ -90,8 +90,7 @@ private:
        /* alg-dependent, calculated at init time */
        CSSM_ALGORITHMS mSigAlg;                // raw signature alg
        CSSM_ALGORITHMS mDigestAlg;             // digest
        /* alg-dependent, calculated at init time */
        CSSM_ALGORITHMS mSigAlg;                // raw signature alg
        CSSM_ALGORITHMS mDigestAlg;             // digest
-       CSSM_ALGORITHMS mOrigAlg;               // caller's context alg
-       
+
        /* exactly one of these is used to collect updates */
        NullDigest                      *mNullDigest;
        CssmClient::Digest      *mDigest;
        /* exactly one of these is used to collect updates */
        NullDigest                      *mNullDigest;
        CssmClient::Digest      *mDigest;
index a91e55e524b23caf1575b90eeed034e170ebcbef..cde4301a639b93bde04672632629e1df28ab8bfe 100644 (file)
@@ -58,8 +58,8 @@ SSDLSession::SSDLSession(CSSM_MODULE_HANDLE handle,
 }
 
 SSDLSession::~SSDLSession()
 }
 
 SSDLSession::~SSDLSession()
+try
 {
 {
-       // @@@ What about a catch?
        StLock<Mutex> _1(mSSUniqueRecordLock);
        mSSUniqueRecordMap.clear();
 
        StLock<Mutex> _1(mSSUniqueRecordLock);
        mSSUniqueRecordMap.clear();
 
@@ -71,6 +71,9 @@ SSDLSession::~SSDLSession()
        mDbHandleMap.clear();
        mDL->detach();
 }
        mDbHandleMap.clear();
        mDL->detach();
 }
+catch (...)
+{
+}
 
 // Utility functions
 void
 
 // Utility functions
 void
@@ -597,7 +600,7 @@ SSDLSession::unwrapAttributesAndData (uint32 &numAttributes,
                                        case CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32:
                                        {
                                                uint32* d = (uint32*) attributes[i].Value[j].Data;
                                        case CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32:
                                        {
                                                uint32* d = (uint32*) attributes[i].Value[j].Data;
-                                               uint32 numValues = attributes[i].Value[j].Length / sizeof (UInt32);
+                                               unsigned long numValues = attributes[i].Value[j].Length / sizeof (UInt32);
                                                while (numValues--)
                                                {
                                                        *d++ = GetUInt32AtFinger (finger);
                                                while (numValues--)
                                                {
                                                        *d++ = GetUInt32AtFinger (finger);
@@ -737,7 +740,7 @@ SSDLSession::getWrappedAttributesAndData (SSDatabase &db,
                unsigned j;
                for (j = 0; j < attributes[i].NumberOfValues; ++j)
                {
                unsigned j;
                for (j = 0; j < attributes[i].NumberOfValues; ++j)
                {
-                       appendUInt32ToData (attributes[i].Value[j].Length, output);
+                       appendUInt32ToData ((uint32)attributes[i].Value[j].Length, output);
                        if (attributes[i].Value[j].Length != 0)
                        {
                                switch (attributes[i].Info.AttributeFormat)
                        if (attributes[i].Value[j].Length != 0)
                        {
                                switch (attributes[i].Info.AttributeFormat)
@@ -764,7 +767,7 @@ SSDLSession::getWrappedAttributesAndData (SSDatabase &db,
        }
        
        // write the length of the data
        }
        
        // write the length of the data
-       appendUInt32ToData (data.Length, output);
+       appendUInt32ToData ((uint32)data.Length, output);
        
        // write the data itself
        if (data.Length != 0)
        
        // write the data itself
        if (data.Length != 0)
@@ -877,7 +880,7 @@ void SSDLSession::doGetWithoutEncryption (SSDatabase &db, const void *inInputPar
        getWrappedAttributesAndData (db, params->attributes->DataRecordType, uniqueID, data, &blobData);
        
        // write out the data blob
        getWrappedAttributesAndData (db, params->attributes->DataRecordType, uniqueID, data, &blobData);
        
        // write out the data blob
-       appendUInt32ToData (data.Length, output);
+       appendUInt32ToData ((uint32)data.Length, output);
        output.append (CssmPolyData (data));
        
        // figure out what we need to do with the key blob
        output.append (CssmPolyData (data));
        
        // figure out what we need to do with the key blob
@@ -904,7 +907,7 @@ void SSDLSession::doGetWithoutEncryption (SSDatabase &db, const void *inInputPar
        
        
        // write out the length of the key blob
        
        
        // write out the length of the key blob
-       appendUInt32ToData (key.Length, output);
+       appendUInt32ToData ((uint32)key.Length, output);
 
        if (key.Length != 0)
        {
 
        if (key.Length != 0)
        {
@@ -1185,7 +1188,13 @@ SSDLSession::PassThrough(CSSM_DB_HANDLE inDbHandle,
                        else
                                db->unlock();
                        break;
                        else
                                db->unlock();
                        break;
-               case CSSM_APPLECSPDL_DB_GET_SETTINGS:
+               case CSSM_APPLECSPDL_DB_STASH:
+            db->stash();
+            break;
+        case CSSM_APPLECSPDL_DB_STASH_CHECK:
+            db->stashCheck();
+            break;
+        case CSSM_APPLECSPDL_DB_GET_SETTINGS:
                {
                        if (!outOutputParams)
                                CssmError::throwMe(CSSM_ERRCODE_INVALID_OUTPUT_POINTER);
                {
                        if (!outOutputParams)
                                CssmError::throwMe(CSSM_ERRCODE_INVALID_OUTPUT_POINTER);
@@ -1313,7 +1322,8 @@ SSDLSession::makeDbHandle(SSDatabase &inDb)
 {
        StLock<Mutex> _(mDbHandleLock);
        CSSM_DB_HANDLE aDbHandle = inDb->handle().DBHandle;
 {
        StLock<Mutex> _(mDbHandleLock);
        CSSM_DB_HANDLE aDbHandle = inDb->handle().DBHandle;
-       IFDEBUG(bool inserted =) mDbHandleMap.insert(DbHandleMap::value_type(aDbHandle, inDb)).second;
+       bool inserted;
+    inserted = mDbHandleMap.insert(DbHandleMap::value_type(aDbHandle, inDb)).second;
        assert(inserted);
        // fprintf(stderr, "%p Added %p to %p\n", pthread_self(), (void*) aDbHandle, (void*) this);
        return aDbHandle;
        assert(inserted);
        // fprintf(stderr, "%p Added %p to %p\n", pthread_self(), (void*) aDbHandle, (void*) this);
        return aDbHandle;
@@ -1363,7 +1373,8 @@ SSDLSession::makeSSUniqueRecord(SSUniqueRecord &uniqueId)
 {
        StLock<Mutex> _(mSSUniqueRecordLock);
        CSSM_HANDLE ref = CSSM_HANDLE(static_cast<CSSM_DB_UNIQUE_RECORD *>(uniqueId));
 {
        StLock<Mutex> _(mSSUniqueRecordLock);
        CSSM_HANDLE ref = CSSM_HANDLE(static_cast<CSSM_DB_UNIQUE_RECORD *>(uniqueId));
-       IFDEBUG(bool inserted =) mSSUniqueRecordMap.insert(SSUniqueRecordMap::value_type(ref, uniqueId)).second;
+       bool inserted;
+    inserted = mSSUniqueRecordMap.insert(SSUniqueRecordMap::value_type(ref, uniqueId)).second;
        assert(inserted);
        return createUniqueRecord(ref);
 }
        assert(inserted);
        return createUniqueRecord(ref);
 }
index 34ff89fd3a72ca7bd513d4c1a17f9605b8e66a53..fe5de1909e30ca17647c8d60b2592b77191904ff 100644 (file)
@@ -36,10 +36,14 @@ SSDatabaseImpl::SSDatabaseImpl(ClientSession &inClientSession, const CssmClient:
 }
 
 SSDatabaseImpl::~SSDatabaseImpl()
 }
 
 SSDatabaseImpl::~SSDatabaseImpl()
+try
 {
        if (mSSDbHandle != noDb)
                mClientSession.releaseDb(mSSDbHandle);
 }
 {
        if (mSSDbHandle != noDb)
                mClientSession.releaseDb(mSSDbHandle);
 }
+catch (...)
+{
+}
 
 SSUniqueRecord
 SSDatabaseImpl::insert(CSSM_DB_RECORDTYPE recordType,
 
 SSUniqueRecord
 SSDatabaseImpl::insert(CSSM_DB_RECORDTYPE recordType,
@@ -82,6 +86,18 @@ SSDatabaseImpl::unlock(const CSSM_DATA &password)
        mClientSession.unlock(dbHandle(), CssmData::overlay(password));
 }
 
        mClientSession.unlock(dbHandle(), CssmData::overlay(password));
 }
 
+void
+SSDatabaseImpl::stash()
+{
+    mClientSession.stashDb(dbHandle());
+}
+
+void
+SSDatabaseImpl::stashCheck()
+{
+    mClientSession.stashDbCheck(dbHandle());
+}
+
 void
 SSDatabaseImpl::getSettings(uint32 &outIdleTimeout, bool &outLockOnSleep)
 {
 void
 SSDatabaseImpl::getSettings(uint32 &outIdleTimeout, bool &outLockOnSleep)
 {
index ba22a0b673659df40f4bf3ac2cbdfae82e7b7c80..c1f6ea8b747ee8dc536b90f2ad8aa26ddf28fb4e 100644 (file)
@@ -60,6 +60,8 @@ public:
        void lock();
        void unlock();
        void unlock(const CSSM_DATA &password);
        void lock();
        void unlock();
        void unlock(const CSSM_DATA &password);
+    void stash();
+    void stashCheck();
        void getSettings(uint32 &outIdleTimeout, bool &outLockOnSleep);
        void setSettings(uint32 inIdleTimeout, bool inLockOnSleep);
        bool isLocked();
        void getSettings(uint32 &outIdleTimeout, bool &outLockOnSleep);
        void setSettings(uint32 inIdleTimeout, bool inLockOnSleep);
        bool isLocked();
index 6400b629a716689181ea344e09cfe9b12fe020f7..472170d8baf693831bd6d5f97db0424a033a2f36 100644 (file)
@@ -334,7 +334,7 @@ SSKey::didChangeAcl()
 {
        if (mUniqueId == true)
        {
 {
        if (mUniqueId == true)
        {
-           secdebug("keyacl", "SSKey::didChangeAcl() keyHandle: %lu updating DL entry", mKeyHandle);
+           secdebug("keyacl", "SSKey::didChangeAcl() keyHandle: %lu updating DL entry", (unsigned long)mKeyHandle);
                // The key is persistent, make the change on disk.
                CssmDataContainer keyBlob(mAllocator);
                clientSession().encodeKey(keyHandle(), keyBlob);
                // The key is persistent, make the change on disk.
                CssmDataContainer keyBlob(mAllocator);
                clientSession().encodeKey(keyHandle(), keyBlob);
@@ -342,6 +342,6 @@ SSKey::didChangeAcl()
        }
        else
        {
        }
        else
        {
-           secdebug("keyacl", "SSKey::didChangeAcl() keyHandle: %lu transient key no update done", mKeyHandle);
+           secdebug("keyacl", "SSKey::didChangeAcl() keyHandle: %lu transient key no update done", (unsigned long)mKeyHandle);
        }
 }
        }
 }
index 090b2ba2c0f6f7d7bea30ac24f5f333f0ec1e0cb..a003d32281af8ce94b67d7c44c53cb76170c9194 100644 (file)
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0420;
+                               LastUpgradeCheck = 0500;
                        };
                        buildConfigurationList = C27AD26A0987FCDC001272E0 /* Build configuration list for PBXProject "libsecurity_apple_cspdl" */;
                        compatibilityVersion = "Xcode 3.2";
                        };
                        buildConfigurationList = C27AD26A0987FCDC001272E0 /* Build configuration list for PBXProject "libsecurity_apple_cspdl" */;
                        compatibilityVersion = "Xcode 3.2";
 /* Begin XCBuildConfiguration section */
                C27AD2640987FCDC001272E0 /* Debug */ = {
                        isa = XCBuildConfiguration;
 /* Begin XCBuildConfiguration section */
                C27AD2640987FCDC001272E0 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 184460CD146E7B7B00B12992 /* debug.xcconfig */;
+                       baseConfigurationReference = 184460CE146E7B7B00B12992 /* lib.xcconfig */;
                        buildSettings = {
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                               WARNING_CFLAGS = (
+                                       "$(inherited)",
+                                       "-Wno-error=overloaded-virtual",
+                               );
                        };
                        name = Debug;
                };
                C27AD2690987FCDC001272E0 /* Release */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Debug;
                };
                C27AD2690987FCDC001272E0 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 184460CF146E7B7B00B12992 /* release.xcconfig */;
+                       baseConfigurationReference = 184460CE146E7B7B00B12992 /* lib.xcconfig */;
                        buildSettings = {
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                               WARNING_CFLAGS = (
+                                       "$(inherited)",
+                                       "-Wno-error=overloaded-virtual",
+                               );
                        };
                        name = Release;
                };
                C27AD26B0987FCDC001272E0 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Release;
                };
                C27AD26B0987FCDC001272E0 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 184460CE146E7B7B00B12992 /* lib.xcconfig */;
+                       baseConfigurationReference = 184460CD146E7B7B00B12992 /* debug.xcconfig */;
                        buildSettings = {
                        };
                        name = Debug;
                };
                C27AD2700987FCDC001272E0 /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                        };
                        name = Debug;
                };
                C27AD2700987FCDC001272E0 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 184460CE146E7B7B00B12992 /* lib.xcconfig */;
+                       baseConfigurationReference = 184460CF146E7B7B00B12992 /* release.xcconfig */;
                        buildSettings = {
                        };
                        name = Release;
                        buildSettings = {
                        };
                        name = Release;
index be3e9020aa96fdcbbb320f3f68e5140374128b9f..7e4e43e8a60af1feaafb76295a7fb91f3083d9af 100644 (file)
@@ -38,7 +38,7 @@ static const AppleDatabaseTableName kTableNames[] = {
        { 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" },
        { 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 }
+       { ~0U, NULL }
 };
 
 //
 };
 
 //
index b176ae52684b7f95ab4a329d30499522ae101e9f..2045ab1d0aad04b9043de54d286266f03947e9b3 100644 (file)
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0420;
+                               LastUpgradeCheck = 0500;
                        };
                        buildConfigurationList = C27AD27B0987FCDC001272E0 /* Build configuration list for PBXProject "libsecurity_apple_file_dl" */;
                        compatibilityVersion = "Xcode 3.2";
                        };
                        buildConfigurationList = C27AD27B0987FCDC001272E0 /* Build configuration list for PBXProject "libsecurity_apple_file_dl" */;
                        compatibilityVersion = "Xcode 3.2";
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 184460E7146E808700B12992 /* debug.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 184460E7146E808700B12992 /* debug.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 184460E9146E808700B12992 /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 184460E9146E808700B12992 /* release.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 184460E8146E808700B12992 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 184460E8146E808700B12992 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 184460E8146E808700B12992 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 184460E8146E808700B12992 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
index 1c19b74b736b5a963c5c795fc90950acae9d3c89..2a5d845d86a18d27d555bd2227e878d186584b60 100644 (file)
@@ -100,7 +100,7 @@ bool getFieldKeyUsage(
        /* make a copy - can't modify length in place */
        CSSM_DATA bitString = *nssObj;
        clNssBitStringToCssm(bitString);
        /* make a copy - can't modify length in place */
        CSSM_DATA bitString = *nssObj;
        clNssBitStringToCssm(bitString);
-       unsigned toCopy = bitString.Length;
+       size_t toCopy = bitString.Length;
        if(toCopy > 2) {
                /* I hope I never see this... */
                clErrorLog("getFieldKeyUsage: KeyUsage larger than 2 bytes!");
        if(toCopy > 2) {
                /* I hope I never see this... */
                clErrorLog("getFieldKeyUsage: KeyUsage larger than 2 bytes!");
@@ -767,7 +767,7 @@ bool getFieldNetscapeCertType(
        /* make a copy - can't modify length in place */
        CSSM_DATA bitString = *nssObj;
        clNssBitStringToCssm(bitString);
        /* make a copy - can't modify length in place */
        CSSM_DATA bitString = *nssObj;
        clNssBitStringToCssm(bitString);
-       unsigned toCopy = bitString.Length;
+       size_t toCopy = bitString.Length;
        if(toCopy > 2) {
                /* I hope I never see this... */
                clErrorLog("getFieldKeyUsage: CertType larger than 2 bytes!");
        if(toCopy > 2) {
                /* I hope I never see this... */
                clErrorLog("getFieldKeyUsage: CertType larger than 2 bytes!");
index 0519aeaf3bfd790ffea17382ead83e7f4fef2df1..38018df509b1c1a581293155baade2c6023fb04d 100644 (file)
@@ -63,7 +63,7 @@ void setFieldCrlNumber(
                kSecAsn1IntegerTemplate); 
 }
 
                kSecAsn1IntegerTemplate); 
 }
 
-
+static
 bool getFieldCrlCommon(
        DecodedItem                     &crl,
        const CSSM_OID          &fieldId,               // identifies extension we seek
 bool getFieldCrlCommon(
        DecodedItem                     &crl,
        const CSSM_OID          &fieldId,               // identifies extension we seek
index d034f0e8987073fa2358d0d7bcc15dbb5f5897e7..8fcdc5cf6c1674dd88d9ebaa2fa44de24698fdbb 100644 (file)
@@ -1,12 +1,12 @@
 /*
  * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
 /*
  * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- * 
+ *
  * The contents of this file constitute Original Code as defined in and are
  * subject to the Apple Public Source License Version 1.2 (the 'License').
  * You may not use this file except in 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 contents of this file constitute Original Code as defined in and are
  * subject to the Apple Public Source License Version 1.2 (the 'License').
  * You may not use this file except in compliance with the License. Please obtain
  * a copy of the License at http://www.apple.com/publicsource and read it before
  * using this file.
- * 
+ *
  * This Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
  * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
  * This Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
  * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
@@ -20,8 +20,8 @@
  * CertFields.cpp - convert between NSS-based Certificate components and CDSA-style
  *                  fields. A major component of DecodedCert.
  *
  * CertFields.cpp - convert between NSS-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. 
+ * Created 9/1/2000 by Doug Mitchell.
+ * Copyright (c) 2000 by Apple Computer.
  */
 
 #include "DecodedCert.h"
  */
 
 #include "DecodedCert.h"
@@ -140,7 +140,7 @@ static bool getField_Issuer (
        }
 
        bool brtn;
        }
 
        bool brtn;
-       
+
        const DecodedCert &cert = dynamic_cast<const DecodedCert &>(item);
        try {
                brtn = getField_RDN_NSS(cert.mCert.tbs.issuer, fieldValue);
        const DecodedCert &cert = dynamic_cast<const DecodedCert &>(item);
        try {
                brtn = getField_RDN_NSS(cert.mCert.tbs.issuer, fieldValue);
@@ -179,7 +179,7 @@ static bool getField_Subject (
        }
 
        bool brtn;
        }
 
        bool brtn;
-       
+
        const DecodedCert &cert = dynamic_cast<const DecodedCert &>(item);
        try {
                brtn = getField_RDN_NSS(cert.mCert.tbs.subject, fieldValue);
        const DecodedCert &cert = dynamic_cast<const DecodedCert &>(item);
        try {
                brtn = getField_RDN_NSS(cert.mCert.tbs.subject, fieldValue);
@@ -220,7 +220,7 @@ static bool getFieldSubjectNorm(
                return false;
        }
        const DecodedCert &cert = dynamic_cast<const DecodedCert &>(item);
                return false;
        }
        const DecodedCert &cert = dynamic_cast<const DecodedCert &>(item);
-       return getField_normRDN_NSS(cert.mCert.tbs.derSubject, numFields, 
+       return getField_normRDN_NSS(cert.mCert.tbs.derSubject, numFields,
                fieldValue);
 }
 
                fieldValue);
 }
 
@@ -298,7 +298,7 @@ static void setField_TbsAlgId (
 {
        DecodedCert &cert = dynamic_cast<DecodedCert &>(item);
        CSSM_X509_ALGORITHM_IDENTIFIER &dstAlgId = cert.mCert.tbs.signature;
 {
        DecodedCert &cert = dynamic_cast<DecodedCert &>(item);
        CSSM_X509_ALGORITHM_IDENTIFIER &dstAlgId = cert.mCert.tbs.signature;
-       tbsSetCheck(dstAlgId.algorithm.Data, fieldValue, 
+       tbsSetCheck(dstAlgId.algorithm.Data, fieldValue,
                sizeof(CSSM_X509_ALGORITHM_IDENTIFIER), "TBS_AlgId");
        setField_AlgIdNSS(fieldValue, dstAlgId, cert.coder());
 }
                sizeof(CSSM_X509_ALGORITHM_IDENTIFIER), "TBS_AlgId");
        setField_AlgIdNSS(fieldValue, dstAlgId, cert.coder());
 }
@@ -343,7 +343,7 @@ static void setField_NotBefore (
 {
        DecodedCert &cert = dynamic_cast<DecodedCert &>(item);
        NSS_Time &dstTime = cert.mCert.tbs.validity.notBefore;
 {
        DecodedCert &cert = dynamic_cast<DecodedCert &>(item);
        NSS_Time &dstTime = cert.mCert.tbs.validity.notBefore;
-       tbsSetCheck(dstTime.item.Data, fieldValue, 
+       tbsSetCheck(dstTime.item.Data, fieldValue,
                sizeof(CSSM_X509_TIME), "NotBefore");
        setField_TimeNSS(fieldValue, dstTime, cert.coder());
 }
                sizeof(CSSM_X509_TIME), "NotBefore");
        setField_TimeNSS(fieldValue, dstTime, cert.coder());
 }
@@ -366,7 +366,7 @@ static void setField_NotAfter (
 {
        DecodedCert &cert = dynamic_cast<DecodedCert &>(item);
        NSS_Time &dstTime = cert.mCert.tbs.validity.notAfter;
 {
        DecodedCert &cert = dynamic_cast<DecodedCert &>(item);
        NSS_Time &dstTime = cert.mCert.tbs.validity.notAfter;
-       tbsSetCheck(dstTime.item.Data, fieldValue, 
+       tbsSetCheck(dstTime.item.Data, fieldValue,
                sizeof(CSSM_X509_TIME), "NotAfter");
        setField_TimeNSS(fieldValue, dstTime, cert.coder());
 }
                sizeof(CSSM_X509_TIME), "NotAfter");
        setField_TimeNSS(fieldValue, dstTime, cert.coder());
 }
@@ -374,7 +374,7 @@ static void setField_NotAfter (
 /***
  *** Subject/issuer unique ID
  *** Format: Raw bytes. It's stored in the cert as an ASN bit string; the decoded
 /***
  *** 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). 
+ *** 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.
  *** 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.
@@ -452,7 +452,7 @@ static bool getField_PublicKeyInfo (
        CssmOwnedData           &fieldValue)    // RETURNED
 {
        const DecodedCert &cert = dynamic_cast<const DecodedCert &>(item);
        CssmOwnedData           &fieldValue)    // RETURNED
 {
        const DecodedCert &cert = dynamic_cast<const DecodedCert &>(item);
-       const CSSM_X509_SUBJECT_PUBLIC_KEY_INFO &srcInfo = 
+       const CSSM_X509_SUBJECT_PUBLIC_KEY_INFO &srcInfo =
                cert.mCert.tbs.subjectPublicKeyInfo;
        if(!tbsGetCheck(srcInfo.subjectPublicKey.Data, index)) {
                return false;
                cert.mCert.tbs.subjectPublicKeyInfo;
        if(!tbsGetCheck(srcInfo.subjectPublicKey.Data, index)) {
                return false;
@@ -460,9 +460,9 @@ static bool getField_PublicKeyInfo (
 
        Allocator &alloc = fieldValue.allocator;
        fieldValue.malloc(sizeof(CSSM_X509_SUBJECT_PUBLIC_KEY_INFO));
 
        Allocator &alloc = fieldValue.allocator;
        fieldValue.malloc(sizeof(CSSM_X509_SUBJECT_PUBLIC_KEY_INFO));
-       CSSM_X509_SUBJECT_PUBLIC_KEY_INFO *dstInfo = 
+       CSSM_X509_SUBJECT_PUBLIC_KEY_INFO *dstInfo =
                (CSSM_X509_SUBJECT_PUBLIC_KEY_INFO *)fieldValue.data();
                (CSSM_X509_SUBJECT_PUBLIC_KEY_INFO *)fieldValue.data();
-               
+
        CL_copySubjPubKeyInfo(srcInfo, true,            // length in bits here
                *dstInfo, false,                                                // length in bytes
                alloc);
        CL_copySubjPubKeyInfo(srcInfo, true,            // length in bits here
                *dstInfo, false,                                                // length in bytes
                alloc);
@@ -476,12 +476,12 @@ static void setField_PublicKeyInfo (
        const CssmData          &fieldValue)
 {
        DecodedCert &cert = dynamic_cast<DecodedCert &>(item);
        const CssmData          &fieldValue)
 {
        DecodedCert &cert = dynamic_cast<DecodedCert &>(item);
-       CSSM_X509_SUBJECT_PUBLIC_KEY_INFO &dstKeyInfo = 
+       CSSM_X509_SUBJECT_PUBLIC_KEY_INFO &dstKeyInfo =
                cert.mCert.tbs.subjectPublicKeyInfo;
                cert.mCert.tbs.subjectPublicKeyInfo;
-       tbsSetCheck(dstKeyInfo.subjectPublicKey.Data, fieldValue, 
+       tbsSetCheck(dstKeyInfo.subjectPublicKey.Data, fieldValue,
                sizeof(CSSM_X509_SUBJECT_PUBLIC_KEY_INFO), "PubKeyInfo");
                sizeof(CSSM_X509_SUBJECT_PUBLIC_KEY_INFO), "PubKeyInfo");
-               
-       CSSM_X509_SUBJECT_PUBLIC_KEY_INFO *srcKeyInfo = 
+
+       CSSM_X509_SUBJECT_PUBLIC_KEY_INFO *srcKeyInfo =
                (CSSM_X509_SUBJECT_PUBLIC_KEY_INFO *)fieldValue.Data;
        if((srcKeyInfo->subjectPublicKey.Data == NULL) ||
           (srcKeyInfo->subjectPublicKey.Length == 0)) {
                (CSSM_X509_SUBJECT_PUBLIC_KEY_INFO *)fieldValue.Data;
        if((srcKeyInfo->subjectPublicKey.Data == NULL) ||
           (srcKeyInfo->subjectPublicKey.Length == 0)) {
@@ -497,7 +497,7 @@ static void setField_PublicKeyInfo (
 static void freeField_PublicKeyInfo (
        CssmOwnedData           &fieldValue)
 {
 static void freeField_PublicKeyInfo (
        CssmOwnedData           &fieldValue)
 {
-       CSSM_X509_SUBJECT_PUBLIC_KEY_INFO *cssmKeyInfo = 
+       CSSM_X509_SUBJECT_PUBLIC_KEY_INFO *cssmKeyInfo =
                (CSSM_X509_SUBJECT_PUBLIC_KEY_INFO *)fieldValue.data();
        if(cssmKeyInfo == NULL) {
                return;
                (CSSM_X509_SUBJECT_PUBLIC_KEY_INFO *)fieldValue.data();
        if(cssmKeyInfo == NULL) {
                return;
@@ -533,9 +533,9 @@ static void setField_PublicKeyStruct (
        const CssmData          &fieldValue)
 {
        DecodedCert &cert = dynamic_cast<DecodedCert &>(item);
        const CssmData          &fieldValue)
 {
        DecodedCert &cert = dynamic_cast<DecodedCert &>(item);
-       CSSM_X509_SUBJECT_PUBLIC_KEY_INFO &dstKeyInfo = 
+       CSSM_X509_SUBJECT_PUBLIC_KEY_INFO &dstKeyInfo =
                cert.mCert.tbs.subjectPublicKeyInfo;
                cert.mCert.tbs.subjectPublicKeyInfo;
-       tbsSetCheck(dstKeyInfo.subjectPublicKey.Data, fieldValue, 
+       tbsSetCheck(dstKeyInfo.subjectPublicKey.Data, fieldValue,
                sizeof(CSSM_KEY), "PubKeyStruct");
 
        CSSM_KEY_PTR cssmKey = (CSSM_KEY_PTR)fieldValue.data();
                sizeof(CSSM_KEY), "PubKeyStruct");
 
        CSSM_KEY_PTR cssmKey = (CSSM_KEY_PTR)fieldValue.data();
@@ -577,7 +577,7 @@ static bool getField_Signature (
 /***
  *** end of field-specific triplets
  ***/
 /***
  *** end of field-specific triplets
  ***/
+
 /*
  * Table to map OID to {get,set,free}field
  */
 /*
  * Table to map OID to {get,set,free}field
  */
@@ -585,22 +585,22 @@ typedef struct {
        const CSSM_OID          *fieldId;
        getItemFieldFcn         *getFcn;
        setItemFieldFcn         *setFcn;
        const CSSM_OID          *fieldId;
        getItemFieldFcn         *getFcn;
        setItemFieldFcn         *setFcn;
-       freeFieldFcn            *freeFcn;               // OPTIONAL - NULL means just free the 
+       freeFieldFcn            *freeFcn;               // OPTIONAL - NULL means just free the
                                                                                // top-level data
 } oidToFieldFuncs;
 
 static const oidToFieldFuncs fieldFuncTable[] = {
                                                                                // top-level data
 } oidToFieldFuncs;
 
 static const oidToFieldFuncs fieldFuncTable[] = {
-       {       &CSSMOID_X509V1Version, 
+       {       &CSSMOID_X509V1Version,
                &getField_Version, &setField_Version, NULL },
                &getField_Version, &setField_Version, NULL },
-       {       &CSSMOID_X509V1SerialNumber, 
+       {       &CSSMOID_X509V1SerialNumber,
                &getField_SerialNumber, &setField_SerialNumber, NULL    },
                &getField_SerialNumber, &setField_SerialNumber, NULL    },
-       {       &CSSMOID_X509V1IssuerNameCStruct, 
+       {       &CSSMOID_X509V1IssuerNameCStruct,
                &getField_Issuer, &setField_Issuer, &freeField_RDN },
                &getField_Issuer, &setField_Issuer, &freeField_RDN },
-       {       &CSSMOID_X509V1SubjectNameCStruct, 
+       {       &CSSMOID_X509V1SubjectNameCStruct,
                &getField_Subject, &setField_Subject, &freeField_RDN },
        {       &CSSMOID_X509V1SignatureAlgorithmTBS,
                &getField_TbsAlgId, &setField_TbsAlgId, &freeField_AlgId },
                &getField_Subject, &setField_Subject, &freeField_RDN },
        {       &CSSMOID_X509V1SignatureAlgorithmTBS,
                &getField_TbsAlgId, &setField_TbsAlgId, &freeField_AlgId },
-       {       &CSSMOID_X509V1SignatureAlgorithm, 
+       {       &CSSMOID_X509V1SignatureAlgorithm,
                &getField_CertAlgId, &setField_ReadOnly, &freeField_AlgId       },
        {       &CSSMOID_X509V1ValidityNotBefore,
                &getField_NotBefore,    &setField_NotBefore,    &freeField_Time },
                &getField_CertAlgId, &setField_ReadOnly, &freeField_AlgId       },
        {       &CSSMOID_X509V1ValidityNotBefore,
                &getField_NotBefore,    &setField_NotBefore,    &freeField_Time },
@@ -613,28 +613,28 @@ static const oidToFieldFuncs fieldFuncTable[] = {
        {       &CSSMOID_X509V1SubjectPublicKeyCStruct,
                &getField_PublicKeyInfo, &setField_PublicKeyInfo, &freeField_PublicKeyInfo },
        {       &CSSMOID_CSSMKeyStruct,
        {       &CSSMOID_X509V1SubjectPublicKeyCStruct,
                &getField_PublicKeyInfo, &setField_PublicKeyInfo, &freeField_PublicKeyInfo },
        {       &CSSMOID_CSSMKeyStruct,
-               &getField_PublicKeyStruct, &setField_PublicKeyStruct, 
+               &getField_PublicKeyStruct, &setField_PublicKeyStruct,
                &freeField_PublicKeyStruct },
        {       &CSSMOID_X509V1Signature,
                &getField_Signature, &setField_ReadOnly, NULL },
                &freeField_PublicKeyStruct },
        {       &CSSMOID_X509V1Signature,
                &getField_Signature, &setField_ReadOnly, NULL },
-       {   &CSSMOID_X509V1IssuerName, 
+       {   &CSSMOID_X509V1IssuerName,
                getFieldIssuerNorm, &setField_ReadOnly, NULL },
                getFieldIssuerNorm, &setField_ReadOnly, NULL },
-       {   &CSSMOID_X509V1SubjectName, 
+       {   &CSSMOID_X509V1SubjectName,
                getFieldSubjectNorm, &setField_ReadOnly, NULL },
                getFieldSubjectNorm, &setField_ReadOnly, NULL },
-       {   &CSSMOID_X509V1IssuerNameStd, 
+       {   &CSSMOID_X509V1IssuerNameStd,
                getFieldIssuerStd, &setField_ReadOnly, NULL },
                getFieldIssuerStd, &setField_ReadOnly, NULL },
-       {   &CSSMOID_X509V1SubjectNameStd, 
+       {   &CSSMOID_X509V1SubjectNameStd,
                getFieldSubjectStd, &setField_ReadOnly, NULL },
                getFieldSubjectStd, &setField_ReadOnly, NULL },
-               
-       /* 
-        * Extensions, implemented in CLCertExtensions.cpp 
+
+       /*
+        * Extensions, implemented in CLCertExtensions.cpp
         * When adding new ones, also add to:
         *   -- clOidToNssInfo() in CLFieldsCommon.cpp
         *   -- get/set/free functions in CLCertExtensions.{cpp,h}
         */
         * When adding new ones, also add to:
         *   -- clOidToNssInfo() in CLFieldsCommon.cpp
         *   -- get/set/free functions in CLCertExtensions.{cpp,h}
         */
-       {       &CSSMOID_KeyUsage, &getFieldKeyUsage, &setFieldKeyUsage, 
+       {       &CSSMOID_KeyUsage, &getFieldKeyUsage, &setFieldKeyUsage,
            &freeFieldSimpleExtension },
            &freeFieldSimpleExtension },
-       {   &CSSMOID_BasicConstraints, &getFieldBasicConstraints, 
+       {   &CSSMOID_BasicConstraints, &getFieldBasicConstraints,
            &setFieldBasicConstraints, &freeFieldSimpleExtension },
        {       &CSSMOID_ExtendedKeyUsage, &getFieldExtKeyUsage,
                &setFieldExtKeyUsage, &freeFieldExtKeyUsage } ,
            &setFieldBasicConstraints, &freeFieldSimpleExtension },
        {       &CSSMOID_ExtendedKeyUsage, &getFieldExtKeyUsage,
                &setFieldExtKeyUsage, &freeFieldExtKeyUsage } ,
@@ -686,6 +686,10 @@ static const oidToFieldFuncs *oidToFields(
                }
                fieldTable++;
        }
                }
                fieldTable++;
        }
+#ifndef        NDEBUG
+       clErrorLog("oidToFields: unknown OID (len=%d): %s\n",
+               (int)fieldId.length(), fieldId.toHex().c_str());
+#endif
        CssmError::throwMe(CSSMERR_CL_UNKNOWN_TAG);
 }
 
        CssmError::throwMe(CSSMERR_CL_UNKNOWN_TAG);
 }
 
@@ -694,22 +698,22 @@ static const oidToFieldFuncs *oidToFields(
  *** Public functions
  ***/
 
  *** 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.
  * 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. 
+ * 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)    // RETURNED
  */
 bool DecodedCert::getCertFieldData(
        const CssmOid           &fieldId,               // which field
        unsigned                        index,                  // which occurrence (0 = first)
        uint32                          &numFields,             // RETURNED
        CssmOwnedData           &fieldValue)    // RETURNED
-{ 
+{
        switch(mState) {
        switch(mState) {
-               case IS_Empty:          
-               case IS_Building:       
+               case IS_Empty:
+               case IS_Building:
                        clErrorLog("DecodedCert::getCertField: can't parse undecoded cert!");
                        CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR);
                case IS_DecodedAll:
                        clErrorLog("DecodedCert::getCertField: can't parse undecoded cert!");
                        CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR);
                case IS_DecodedAll:
@@ -719,15 +723,15 @@ bool DecodedCert::getCertFieldData(
        const oidToFieldFuncs *fieldFuncs = oidToFields(fieldId);
        return fieldFuncs->getFcn(*this, index, numFields, fieldValue);
 }
        const oidToFieldFuncs *fieldFuncs = oidToFields(fieldId);
        return fieldFuncs->getFcn(*this, index, numFields, fieldValue);
 }
+
 /*
 /*
- * Set the field specified by fieldId in the specified Cert. 
+ * Set the field specified by fieldId in the specified Cert.
  * Note no index - individual field routines either append (for extensions)
  * Note no index - individual field routines either append (for extensions)
- * or if field already set ::throwMe(for all others) 
+ * or if field already set ::throwMe(for all others)
  */
 void DecodedCert::setCertField(
        const CssmOid           &fieldId,               // which field
  */
 void DecodedCert::setCertField(
        const CssmOid           &fieldId,               // which field
-       const CssmData          &fieldValue) 
+       const CssmData          &fieldValue)
 {
        switch(mState) {
                case IS_Empty:                  // first time thru
 {
        switch(mState) {
                case IS_Empty:                  // first time thru
@@ -749,7 +753,7 @@ void DecodedCert::setCertField(
 }
 
 /*
 }
 
 /*
- * Free the fieldId-specific data referred to by fieldValue->Data. 
+ * Free the fieldId-specific data referred to by fieldValue->Data.
  */
 void DecodedCert::freeCertFieldData(
        const CssmOid           &fieldId,
  */
 void DecodedCert::freeCertFieldData(
        const CssmOid           &fieldId,
@@ -770,7 +774,7 @@ void DecodedCert::freeCertFieldData(
 
 
 /*
 
 
 /*
- * Common means to get all fields from a decoded cert. Used in 
+ * Common means to get all fields from a decoded cert. Used in
  * CertGetAllTemplateFields and CertGetAllFields.
  */
 void DecodedCert::getAllParsedCertFields(
  * CertGetAllTemplateFields and CertGetAllFields.
  */
 void DecodedCert::getAllParsedCertFields(
@@ -780,7 +784,7 @@ void DecodedCert::getAllParsedCertFields(
        /* this is the max - some might be missing */
        uint32 maxFields = NUM_STD_CERT_FIELDS + mDecodedExtensions.numExtensions();
        CSSM_FIELD_PTR outFields = (CSSM_FIELD_PTR)mAlloc.malloc(maxFields * sizeof(CSSM_FIELD));
        /* this is the max - some might be missing */
        uint32 maxFields = NUM_STD_CERT_FIELDS + mDecodedExtensions.numExtensions();
        CSSM_FIELD_PTR outFields = (CSSM_FIELD_PTR)mAlloc.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.
        /*
         * We'll be copying oids and values for fields we find into
         * outFields; current number of valid fields found in numOutFields.
@@ -791,24 +795,24 @@ void DecodedCert::getAllParsedCertFields(
        uint32                  currOidDex;
        const CSSM_OID  *currOid;
        CssmAutoData    aData(mAlloc);          // for malloc/copy of outgoing data
        uint32                  currOidDex;
        const CSSM_OID  *currOid;
        CssmAutoData    aData(mAlloc);          // 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
 
        /* 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. 
+               /*
+                * Return false if field not there, which is not an error here.
                 * Actual exceptions are fatal.
                 */
                 * Actual exceptions are fatal.
                 */
-               if(!fieldFuncs->getFcn(*this, 
+               if(!fieldFuncs->getFcn(*this,
                                0,                              // index - looking for first one
                                0,                              // index - looking for first one
-                               numFields, 
+                               numFields,
                                aData)) {
                        continue;
                }
                                aData)) {
                        continue;
                }
-               
+
                /* got some data for this oid - copy it and oid to outgoing CertFields */
                assert(numOutFields < maxFields);
                currOutField = &outFields[numOutFields];
                /* got some data for this oid - copy it and oid to outgoing CertFields */
                assert(numOutFields < maxFields);
                currOutField = &outFields[numOutFields];
@@ -816,12 +820,12 @@ void DecodedCert::getAllParsedCertFields(
                aData.copy(*currOid);
                currOutField->FieldOid = aData.release();
                numOutFields++;
                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,
                /* 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,                       
+                               fieldDex,
                                numFields,                      // shouldn't change
                                aData);
                        if(!brtn) {
                                numFields,                      // shouldn't change
                                aData);
                        if(!brtn) {
@@ -836,7 +840,7 @@ void DecodedCert::getAllParsedCertFields(
                        numOutFields++;
                }       /* multiple fields for currOid */
        }               /* for each known OID */
                        numOutFields++;
                }       /* multiple fields for currOid */
        }               /* for each known OID */
-       
+
        NumberOfFields = numOutFields;
        CertFields = outFields;
 }
        NumberOfFields = numOutFields;
        CertFields = outFields;
 }
index 62b2655477589635108c6b01fd0c423219e78dce..7e0c3260853b7d41665ad3a714d71d2a89d6b9a8 100644 (file)
@@ -362,7 +362,7 @@ static void setField_SignedCrl (
        CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
 }
 
        CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
 }
 
-void freeField_SignedCrl (
+static void freeField_SignedCrl (
        CssmOwnedData           &fieldValue)
 {
        CSSM_X509_SIGNED_CRL *cssmCrl = 
        CssmOwnedData           &fieldValue)
 {
        CSSM_X509_SIGNED_CRL *cssmCrl = 
index 92b6cf262ff4f441d1c462d636ebb2da31065b30..2f5bedc6f3158c79f5972802f760b3c9f1f8f3e2 100644 (file)
@@ -1,12 +1,12 @@
 /*
  * Copyright (c) 2002 Apple Computer, Inc. All Rights Reserved.
 /*
  * Copyright (c) 2002 Apple Computer, Inc. All Rights Reserved.
- * 
+ *
  * The contents of this file constitute Original Code as defined in and are
  * subject to the Apple Public Source License Version 1.2 (the 'License').
  * You may not use this file except in 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 contents of this file constitute Original Code as defined in and are
  * subject to the Apple Public Source License Version 1.2 (the 'License').
  * You may not use this file except in compliance with the License. Please obtain
  * a copy of the License at http://www.apple.com/publicsource and read it before
  * using this file.
- * 
+ *
  * This Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
  * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
  * This Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
  * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
 
 
 /*
 
 
 /*
- * DecodedItem.cpp - class representing the common portions of 
- * NSS-format decoded certs and CRLs, with extensions parsed and 
+ * DecodedItem.cpp - class representing the common portions of
+ * NSS-format decoded certs and CRLs, with extensions parsed and
  * decoded (still in NSS format).
  */
 
 #include "DecodedItem.h"
 #include "cldebugging.h"
  * decoded (still in NSS format).
  */
 
 #include "DecodedItem.h"
 #include "cldebugging.h"
-#include "AppleX509CLSession.h" 
+#include "AppleX509CLSession.h"
 #include "CSPAttacher.h"
 #include "CLFieldsCommon.h"
 #include "clNssUtils.h"
 #include "clNameUtils.h"
 #include "CSPAttacher.h"
 #include "CLFieldsCommon.h"
 #include "clNssUtils.h"
 #include "clNameUtils.h"
+#include <security_asn1/SecAsn1Types.h>
 #include <Security/cssmapple.h>
 #include <Security/oidscert.h>
 
 #include <Security/cssmapple.h>
 #include <Security/oidscert.h>
 
@@ -37,7 +38,7 @@
 DecodedExten::DecodedExten(
        const CSSM_OID  &extnId,        // copied
        bool                    critical,
 DecodedExten::DecodedExten(
        const CSSM_OID  &extnId,        // copied
        bool                    critical,
-       void                    *nssObj,        // NSS_KeyUsage, NSS_BasicConstraints, 
+       void                    *nssObj,        // NSS_KeyUsage, NSS_BasicConstraints,
                                                                //   etc. NOT COPIED, exists in same
                                                                //   memory space as coder
        bool                    berEncoded,     // indicates unknown extension which we
                                                                //   etc. NOT COPIED, exists in same
                                                                //   memory space as coder
        bool                    berEncoded,     // indicates unknown extension which we
@@ -66,11 +67,11 @@ DecodedExten::~DecodedExten()
         * when coder is freed */
 }
 
         * when coder is freed */
 }
 
-/* 
+/*
  * Given a fully encoded BER object, create a CSSM_X509EXT_TAGandVALUE
  * Given a fully encoded BER object, create a CSSM_X509EXT_TAGandVALUE
- * representing it. We malloc the CSSM_X509EXT_TAGandVALUE itself using 
+ * representing it. We malloc the CSSM_X509EXT_TAGandVALUE itself using
  * specified allocator, but the referent (in CSSM_X509EXT_TAGandVALUE.value)
  * specified allocator, but the referent (in CSSM_X509EXT_TAGandVALUE.value)
- * merely points to data inside the berValue. 
+ * merely points to data inside the berValue.
  */
 CSSM_X509EXT_TAGandVALUE *DecodedExten::createTagAndValue(
        const CSSM_DATA &berValue,
  */
 CSSM_X509EXT_TAGandVALUE *DecodedExten::createTagAndValue(
        const CSSM_DATA &berValue,
@@ -81,10 +82,24 @@ CSSM_X509EXT_TAGandVALUE *DecodedExten::createTagAndValue(
        }
        CSSM_X509EXT_TAGandVALUE *tv = (CSSM_X509EXT_TAGandVALUE *)
                alloc.malloc(sizeof(CSSM_X509EXT_TAGandVALUE));
        }
        CSSM_X509EXT_TAGandVALUE *tv = (CSSM_X509EXT_TAGandVALUE *)
                alloc.malloc(sizeof(CSSM_X509EXT_TAGandVALUE));
+
+       // Important: by the time we get called, the extension data
+       // has already been deconstructed, and the raw value we are
+       // handed in berValue does not include ASN.1 type or length.
+       // Since createTagAndValue is only called in the case where
+       // the contents are unknown (and thus opaque), always treat
+       // as an octet string.
+
+       tv->type = SEC_ASN1_OCTET_STRING;
+       tv->value.Length = berValue.Length;
+       tv->value.Data = berValue.Data;
+       return tv;
+
+#if 0
        tv->type = berValue.Data[0];
        tv->type = berValue.Data[0];
-       
-       /* 
-        * length of length is variable; ASN spec says it can actually be up to  
+
+       /*
+        * length of length is variable; ASN spec says it can actually be up to
         * 127 bytes, but we only have room for 32 bits!
         */
        const uint8 *lp = berValue.Data + 1;
         * 127 bytes, but we only have room for 32 bits!
         */
        const uint8 *lp = berValue.Data + 1;
@@ -95,14 +110,14 @@ CSSM_X509EXT_TAGandVALUE *DecodedExten::createTagAndValue(
                tv->value.Data = const_cast<uint8 *>(lp + 1);
                return tv;
        }
                tv->value.Data = const_cast<uint8 *>(lp + 1);
                return tv;
        }
-       
+
        unsigned numLenBytes = len1 & 0x7f;
        if(numLenBytes > 4) {
                clErrorLog("createTagAndValue: impossible length of length (%u)\n", numLenBytes);
                alloc.free(tv);
                CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT);
        }
        unsigned numLenBytes = len1 & 0x7f;
        if(numLenBytes > 4) {
                clErrorLog("createTagAndValue: impossible length of length (%u)\n", numLenBytes);
                alloc.free(tv);
                CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT);
        }
-       
+
        uint32 len = 0;
        lp++;                   // points to first length byte
        for(uint32 dex=0; dex<numLenBytes; dex++) {
        uint32 len = 0;
        lp++;                   // points to first length byte
        for(uint32 dex=0; dex<numLenBytes; dex++) {
@@ -113,6 +128,7 @@ CSSM_X509EXT_TAGandVALUE *DecodedExten::createTagAndValue(
        tv->value.Length = len;
        tv->value.Data = const_cast<uint8 *>(lp);
        return tv;
        tv->value.Length = len;
        tv->value.Data = const_cast<uint8 *>(lp);
        return tv;
+#endif
 }
 
 /*
 }
 
 /*
@@ -128,10 +144,10 @@ void DecodedExten::convertToCdsa(
 {
        clAllocCopyData(alloc, mExtnId, cssmExt->extnId);
        cssmExt->critical = mCritical ? CSSM_TRUE : CSSM_FALSE;
 {
        clAllocCopyData(alloc, mExtnId, cssmExt->extnId);
        cssmExt->critical = mCritical ? CSSM_TRUE : CSSM_FALSE;
-       
-       /* 
+
+       /*
         * in either case copy the raw extension data if we have it (we may not
         * in either case copy the raw extension data if we have it (we may not
-        * have it if this was created via setField). 
+        * have it if this was created via setField).
         */
        if(mRawExtn) {
                clAllocCopyData(alloc, *mRawExtn, cssmExt->BERvalue);
         */
        if(mRawExtn) {
                clAllocCopyData(alloc, *mRawExtn, cssmExt->BERvalue);
@@ -157,12 +173,12 @@ void DecodedExten::convertToCdsa(
 
 /*
  * Convert a DecodedExten to a CSSM_X509_EXTENSION. This includes
 
 /*
  * Convert a DecodedExten to a CSSM_X509_EXTENSION. This includes
- * the mapping of the extnId to a known CDSA type and type and doing the 
- * actual NSS-to-CDSA conversion. At the time this function is 
- * called, the DecodedExten either has a valid mNssObj, or it's an 
+ * the mapping of the extnId to a known CDSA type and type and doing the
+ * actual NSS-to-CDSA conversion. At the time this function is
+ * called, the DecodedExten either has a valid mNssObj, or it's an
  * unknown extension type in which case mNssObj is an AsnOcts containing
  * unknown extension type in which case mNssObj is an AsnOcts containing
- * the opaquely DER-encoded extension value. 
- * 
+ * the opaquely DER-encoded extension value.
+ *
  * Currently only used when decoding a CRL and converting it en masse
  * to CDSA.
  */
  * Currently only used when decoding a CRL and converting it en masse
  * to CDSA.
  */
@@ -173,7 +189,7 @@ void nssToCssm(
        CdsaType                        *&cdsaObj,              // mallocd and RETURNED
        Allocator               &alloc)
 {
        CdsaType                        *&cdsaObj,              // mallocd and RETURNED
        Allocator               &alloc)
 {
-       nssObj = (NssType *)(decodedExt.nssObj());  
+       nssObj = (NssType *)(decodedExt.nssObj());
        assert(nssObj != NULL);
        cdsaObj = (CdsaType *)alloc.malloc(sizeof(CdsaType));
        memset(cdsaObj, 0, sizeof(CdsaType));
        assert(nssObj != NULL);
        cdsaObj = (CdsaType *)alloc.malloc(sizeof(CdsaType));
        memset(cdsaObj, 0, sizeof(CdsaType));
@@ -257,14 +273,14 @@ void DecodedExten::parse(
                NSS_CRLDistributionPoints *nssObj;
                nssToCssm<NSS_CRLDistributionPoints, CE_CRLDistPointsSyntax>(
                        *this,
                NSS_CRLDistributionPoints *nssObj;
                nssToCssm<NSS_CRLDistributionPoints, CE_CRLDistPointsSyntax>(
                        *this,
-                       nssObj, 
+                       nssObj,
                        cdsaObj,
                        alloc);
                CL_nssDistPointsToCssm((const NSS_CRLDistributionPoints&)*nssObj, *cdsaObj, mCoder, alloc);
                vCdsaObj = cdsaObj;
        }
        /*
                        cdsaObj,
                        alloc);
                CL_nssDistPointsToCssm((const NSS_CRLDistributionPoints&)*nssObj, *cdsaObj, mCoder, alloc);
                vCdsaObj = cdsaObj;
        }
        /*
-        * cert entry extensions 
+        * cert entry extensions
         */
        else if(clCompareCssmData(&mExtnId, &CSSMOID_HoldInstructionCode)) {
                /* value is just an OID */
         */
        else if(clCompareCssmData(&mExtnId, &CSSMOID_HoldInstructionCode)) {
                /* value is just an OID */
@@ -291,7 +307,7 @@ void DecodedExten::parse(
                vCdsaObj = cdsaObj;
        }
        else {
                vCdsaObj = cdsaObj;
        }
        else {
-               /* if we get here, this routine is not keeping up with 
+               /* if we get here, this routine is not keeping up with
                 * clOidToNssInfo()  */
                // assert(0);
                CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR);
                 * clOidToNssInfo()  */
                // assert(0);
                CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR);
@@ -304,10 +320,10 @@ void DecodedExten::parse(
 
 /*
  * A variable-size array of DecodedExtens.
 
 /*
  * A variable-size array of DecodedExtens.
- * Used for storing cert and CRL extensions as well as per-CRL-entry 
+ * Used for storing cert and CRL extensions as well as per-CRL-entry
  * extensions.
  */
  * extensions.
  */
-DecodedExtensions::DecodedExtensions(  
+DecodedExtensions::DecodedExtensions(
        SecNssCoder             &coder,
        Allocator       &alloc)
        :       mCoder(coder),
        SecNssCoder             &coder,
        Allocator       &alloc)
        :       mCoder(coder),
@@ -318,7 +334,7 @@ DecodedExtensions::DecodedExtensions(
 {
 
 }
 {
 
 }
-       
+
 DecodedExtensions::~DecodedExtensions()
 {
        for(unsigned i=0; i<mNumExtensions; i++) {
 DecodedExtensions::~DecodedExtensions()
 {
        for(unsigned i=0; i<mNumExtensions; i++) {
@@ -334,16 +350,16 @@ DecodedExtensions::~DecodedExtensions()
 
 /*
  * Initialize by decoding a NSS-style NSS_CertExtension array.
 
 /*
  * Initialize by decoding a NSS-style NSS_CertExtension array.
- * This involves figuring out what kind of object is represented in the 
- * octet string in the  extension, decoding it, and appending the resulting 
+ * This involves figuring out what kind of object is represented in the
+ * octet string in the  extension, decoding it, and appending the resulting
  * NSS object to mExtensions in the form of a DecodedExten.
  *
  * NSS object to mExtensions in the form of a DecodedExten.
  *
- * Called when decoding either a cert or a CRL (for caching it or 
- * getting its fields) or a cert template (only via 
+ * Called when decoding either a cert or a CRL (for caching it or
+ * getting its fields) or a cert template (only via
  * CertGetAllTemplateFields()).
  */
 void DecodedExtensions::decodeFromNss(
  * CertGetAllTemplateFields()).
  */
 void DecodedExtensions::decodeFromNss(
-       NSS_CertExtension       **extensions)   
+       NSS_CertExtension       **extensions)
 {
        if(extensions == NULL) {
                /* OK, no extensions present */
 {
        if(extensions == NULL) {
                /* OK, no extensions present */
@@ -354,9 +370,9 @@ void DecodedExtensions::decodeFromNss(
        /* traverse extension list */
        for(unsigned dex=0; dex<numExtens; dex++) {
                NSS_CertExtension *nssExten = extensions[dex];
        /* traverse extension list */
        for(unsigned dex=0; dex<numExtens; dex++) {
                NSS_CertExtension *nssExten = extensions[dex];
-               
+
                /*
                /*
-                * For this extension->extnId, cook up an appropriate 
+                * For this extension->extnId, cook up an appropriate
                 * NSS-specific type (NSS_KeyUsage, etc.);
                 */
                CSSM_DATA &rawExtn = nssExten->value;
                 * NSS-specific type (NSS_KeyUsage, etc.);
                 */
                CSSM_DATA &rawExtn = nssExten->value;
@@ -367,38 +383,38 @@ void DecodedExtensions::decodeFromNss(
                void *nssObj = NULL;                                    // decode destination
                found = clOidToNssInfo(nssExten->extnId, nssObjLen, templ);
                if(!found) {
                void *nssObj = NULL;                                    // decode destination
                found = clOidToNssInfo(nssExten->extnId, nssObjLen, templ);
                if(!found) {
-                       /* 
+                       /*
                         * We don't know how to deal with this.
                         */
                        berEncoded = true;
                }
                else {
                         * We don't know how to deal with this.
                         */
                        berEncoded = true;
                }
                else {
-                       /* 
+                       /*
                         * Create NSS-style object specific to this extension, just
                         * Create NSS-style object specific to this extension, just
-                        * by knowing its length and ASN template. 
+                        * by knowing its length and ASN template.
                         * Decode the extensions's extnValue into that object. We don't
                         * Decode the extensions's extnValue into that object. We don't
-                        * have to know what kind of object it is anymore. 
+                        * have to know what kind of object it is anymore.
                         */
                        assert(templ != NULL);
                        nssObj = mCoder.malloc(nssObjLen);
                        memset(nssObj, 0, nssObjLen);
                        PRErrorCode prtn;
                         */
                        assert(templ != NULL);
                        nssObj = mCoder.malloc(nssObjLen);
                        memset(nssObj, 0, nssObjLen);
                        PRErrorCode prtn;
-                       prtn = mCoder.decodeItem(rawExtn, templ, nssObj); 
+                       prtn = mCoder.decodeItem(rawExtn, templ, nssObj);
                        if(prtn) {
                        if(prtn) {
-                               /* 
-                                * FIXME - what do we do here? For now flag it 
+                               /*
+                                * FIXME - what do we do here? For now flag it
                                 * as an non-understood extension...
                                 */
                                clErrorLog("decodeExtensions: extension decode error\n");
                                nssObj = NULL;
                                berEncoded = true;
                        }
                                 * as an non-understood extension...
                                 */
                                clErrorLog("decodeExtensions: extension decode error\n");
                                nssObj = NULL;
                                berEncoded = true;
                        }
-               }       
+               }
                if((nssObj != NULL) || berEncoded) {
                        /* append if the decode was successful */
                        addExtension(nssExten->extnId,
                                clNssBoolToCssm(nssExten->critical),
                if((nssObj != NULL) || berEncoded) {
                        /* append if the decode was successful */
                        addExtension(nssExten->extnId,
                                clNssBoolToCssm(nssExten->critical),
-                               nssObj, 
+                               nssObj,
                                berEncoded,
                                templ,
                                &rawExtn);
                                berEncoded,
                                templ,
                                &rawExtn);
@@ -413,7 +429,7 @@ void DecodedExtensions::decodeFromNss(
  * is BER-encoded and the result is stored as an octet string
  * (AsnOcts) in a new Extension object in the TBS.
  *
  * is BER-encoded and the result is stored as an octet string
  * (AsnOcts) in a new Extension object in the TBS.
  *
- * Called from {Crl,Cert}CreateTemplate via encode{Tbs,Cts}(). 
+ * Called from {Crl,Cert}CreateTemplate via encode{Tbs,Cts}().
  */
 void DecodedExtensions::encodeToNss(
        NSS_CertExtension       **&extensions)
  */
 void DecodedExtensions::encodeToNss(
        NSS_CertExtension       **&extensions)
@@ -424,22 +440,22 @@ void DecodedExtensions::encodeToNss(
                /* no extensions, no error */
                return;
        }
                /* no extensions, no error */
                return;
        }
-       
+
        /* malloc a NULL_terminated array of NSS_CertExtension pointers */
        unsigned len = (mNumExtensions + 1) * sizeof(NSS_CertExtension *);
        extensions = (NSS_CertExtension **)mCoder.malloc(len);
        memset(extensions, 0, len);
        /* malloc a NULL_terminated array of NSS_CertExtension pointers */
        unsigned len = (mNumExtensions + 1) * sizeof(NSS_CertExtension *);
        extensions = (NSS_CertExtension **)mCoder.malloc(len);
        memset(extensions, 0, len);
-       
-       /* grind thru our DecodedExtens, creating an NSS_CertExtension for 
+
+       /* grind thru our DecodedExtens, creating an NSS_CertExtension for
         * each one */
        for(unsigned extenDex=0; extenDex<mNumExtensions; extenDex++) {
         * each one */
        for(unsigned extenDex=0; extenDex<mNumExtensions; extenDex++) {
-               NSS_CertExtension *thisNssExten = 
+               NSS_CertExtension *thisNssExten =
                        (NSS_CertExtension *)mCoder.malloc(sizeof(NSS_CertExtension));
                memset(thisNssExten, 0, sizeof(NSS_CertExtension));
                extensions[extenDex] = thisNssExten;
                        (NSS_CertExtension *)mCoder.malloc(sizeof(NSS_CertExtension));
                memset(thisNssExten, 0, sizeof(NSS_CertExtension));
                extensions[extenDex] = thisNssExten;
-               
+
                const DecodedExten *decodedExt = getExtension(extenDex);
                const DecodedExten *decodedExt = getExtension(extenDex);
-               
+
                /* BER-encode the extension object if appropriate */
                if(decodedExt->berEncoded()) {
                        /* unknown extension type, it's already encoded */
                /* BER-encode the extension object if appropriate */
                if(decodedExt->berEncoded()) {
                        /* unknown extension type, it's already encoded */
@@ -469,19 +485,19 @@ void DecodedExtensions::encodeToNss(
 void DecodedExtensions::addExtension(
        const CSSM_OID  &extnId,        // copied
        bool                    critical,
 void DecodedExtensions::addExtension(
        const CSSM_OID  &extnId,        // copied
        bool                    critical,
-       void                    *nssObj,        // NSS_KeyUsage, NSS_BasicConstraints, 
+       void                    *nssObj,        // NSS_KeyUsage, NSS_BasicConstraints,
                                                                //   etc. NOT COPIED, exists in same
                                                                //   memory space as coder
        bool                    berEncoded,     // indicates unknown extension which we
                                                                // do not BER-decode when parsing a cert
        const SecAsn1Template *templ, // required if !berEncoded
        const CSSM_DATA *rawExtn)       // NSS_CertExtension.value, copied,
                                                                //   etc. NOT COPIED, exists in same
                                                                //   memory space as coder
        bool                    berEncoded,     // indicates unknown extension which we
                                                                // do not BER-decode when parsing a cert
        const SecAsn1Template *templ, // required if !berEncoded
        const CSSM_DATA *rawExtn)       // NSS_CertExtension.value, copied,
-                                                               //   optional (not present during a 
+                                                               //   optional (not present during a
                                                                //   SetField op)
 {
        if(mNumExtensions == mSizeofExtensions) {
                /* expand by doubling, or initial malloc */
                                                                //   SetField op)
 {
        if(mNumExtensions == mSizeofExtensions) {
                /* expand by doubling, or initial malloc */
-               mSizeofExtensions = mNumExtensions ? 
+               mSizeofExtensions = mNumExtensions ?
                        (2 * mNumExtensions) : MIN_EXTENSIONS;
                mExtensions = (DecodedExten **)mAlloc.realloc(
                        mExtensions, mSizeofExtensions * sizeof(DecodedExten));
                        (2 * mNumExtensions) : MIN_EXTENSIONS;
                mExtensions = (DecodedExten **)mAlloc.realloc(
                        mExtensions, mSizeofExtensions * sizeof(DecodedExten));
@@ -489,7 +505,7 @@ void DecodedExtensions::addExtension(
        mExtensions[mNumExtensions++] = new DecodedExten(extnId,
                critical, nssObj, berEncoded, templ, mCoder, rawExtn);
 }
        mExtensions[mNumExtensions++] = new DecodedExten(extnId,
                critical, nssObj, berEncoded, templ, mCoder, rawExtn);
 }
-       
+
 const DecodedExten *DecodedExtensions::getExtension(
        unsigned extenDex) const
 {
 const DecodedExten *DecodedExtensions::getExtension(
        unsigned extenDex) const
 {
@@ -510,7 +526,7 @@ void DecodedExtensions::convertToCdsa(
        }
        cssmExtens.extensions = (CSSM_X509_EXTENSION_PTR)alloc.malloc(
                sizeof(CSSM_X509_EXTENSION) * mNumExtensions);
        }
        cssmExtens.extensions = (CSSM_X509_EXTENSION_PTR)alloc.malloc(
                sizeof(CSSM_X509_EXTENSION) * mNumExtensions);
-       memset(cssmExtens.extensions, 0, 
+       memset(cssmExtens.extensions, 0,
                sizeof(CSSM_X509_EXTENSION) * mNumExtensions);
        cssmExtens.numberOfExtensions = mNumExtensions;
        for(unsigned dex=0; dex<mNumExtensions; dex++) {
                sizeof(CSSM_X509_EXTENSION) * mNumExtensions);
        cssmExtens.numberOfExtensions = mNumExtensions;
        for(unsigned dex=0; dex<mNumExtensions; dex++) {
index 27f9e5018c908ee44ceea02e9cc30153d0092084..0c88a1eba21c4f93cf35b5e025dbff649539a871 100644 (file)
@@ -29,7 +29,7 @@
 /* 
  * NSS_ATV --> CSSM_X509_TYPE_VALUE_PAIR
  */
 /* 
  * NSS_ATV --> CSSM_X509_TYPE_VALUE_PAIR
  */
-
+static
 void CL_nssAtvToCssm(
        const NSS_ATV                           &nssObj,
        CSSM_X509_TYPE_VALUE_PAIR       &cssmObj,
 void CL_nssAtvToCssm(
        const NSS_ATV                           &nssObj,
        CSSM_X509_TYPE_VALUE_PAIR       &cssmObj,
@@ -214,7 +214,7 @@ void CL_normalizeString(
                }
        };
 
                }
        };
 
-       strLen = pD - strPtr;
+       strLen = (int)(pD - strPtr);
 }
 
 /* 
 }
 
 /* 
@@ -266,7 +266,7 @@ void CL_normalizeX509NameNSS(
 
                        /* normalize */
                        char *strPtr = (char *)attrVal.item.Data;
 
                        /* normalize */
                        char *strPtr = (char *)attrVal.item.Data;
-                       int newLen = attrVal.item.Length;
+                       int newLen = (int)attrVal.item.Length;
                        CL_normalizeString(strPtr, newLen);
                        
                        /* possible length adjustment */
                        CL_normalizeString(strPtr, newLen);
                        
                        /* possible length adjustment */
index d4a9ddd0561c2c5fe7c6024ff908ca46cda3f1ef..a559e6ae8f640e2f2db150255f4ff367c95318c2 100644 (file)
@@ -122,7 +122,7 @@ uint32 clDataToInt(
        if((cdata.Length == 0) || (cdata.Data == NULL)) {
                return 0;
        }
        if((cdata.Length == 0) || (cdata.Data == NULL)) {
                return 0;
        }
-       uint32 len = cdata.Length;
+       size_t len = cdata.Length;
        if(len > sizeof(uint32)) {
                if(toThrow == 0) {
                        /* tolerate this */
        if(len > sizeof(uint32)) {
                if(toThrow == 0) {
                        /* tolerate this */
@@ -135,7 +135,7 @@ uint32 clDataToInt(
        
        uint32 rtn = 0;
        uint8 *cp = cdata.Data;
        
        uint32 rtn = 0;
        uint8 *cp = cdata.Data;
-       for(uint32 i=0; i<len; i++) {
+       for(size_t i=0; i<len; i++) {
                rtn = (rtn << 8) | *cp++;
        }
        return rtn;
                rtn = (rtn << 8) | *cp++;
        }
        return rtn;
@@ -205,12 +205,12 @@ void clCssmBoolToNss(
 void clCssmBitStringToNss(
        CSSM_DATA &b)
 {
 void clCssmBitStringToNss(
        CSSM_DATA &b)
 {
-       int numBits = b.Length * 8;
+       size_t numBits = b.Length * 8;
        
        /* start at end of bit array, scanning backwards looking
         * for the first set bit */
        bool foundSet = false;
        
        /* start at end of bit array, scanning backwards looking
         * for the first set bit */
        bool foundSet = false;
-       for(int dex=b.Length-1; dex>=0; dex--) {
+       for(ptrdiff_t dex=b.Length-1; dex>=0; dex--) {
                unsigned bitMask = 0x01;
                uint8 byte = b.Data[dex];
                for(unsigned bdex=0; bdex<8; bdex++) {
                unsigned bitMask = 0x01;
                uint8 byte = b.Data[dex];
                for(unsigned bdex=0; bdex<8; bdex++) {
@@ -229,7 +229,7 @@ void clCssmBitStringToNss(
        }
        /* !foundSet --> numBits = 0 */
        assert(((numBits > 0) & foundSet) || ((numBits == 0) && !foundSet));
        }
        /* !foundSet --> numBits = 0 */
        assert(((numBits > 0) & foundSet) || ((numBits == 0) && !foundSet));
-       b.Length = (uint32)numBits;
+       b.Length = numBits;
 }
 
 /*
 }
 
 /*
@@ -241,7 +241,7 @@ void clCssmBitStringToNss(
 void clNssBitStringToCssm(
        CSSM_DATA &b)
 {
 void clNssBitStringToCssm(
        CSSM_DATA &b)
 {
-       uint32 byteCount = (b.Length + 7) / 8;
+       CSSM_SIZE byteCount = (b.Length + 7) / 8;
        unsigned partialBits = b.Length & 0x7;
        b.Length = byteCount;
        if(partialBits == 0) {
        unsigned partialBits = b.Length & 0x7;
        b.Length = byteCount;
        if(partialBits == 0) {
@@ -290,7 +290,7 @@ void **clNssNullArray(
 CE_KeyUsage clBitStringToKeyUsage(
        const CSSM_DATA &cdata)
 {
 CE_KeyUsage clBitStringToKeyUsage(
        const CSSM_DATA &cdata)
 {
-       unsigned toCopy = (cdata.Length + 7) / 8;
+       size_t toCopy = (cdata.Length + 7) / 8;
        if(toCopy > 2) {
                /* I hope I never see this... */
                clErrorLog("clBitStringToKeyUsage: KeyUsage larger than 2 bytes!");
        if(toCopy > 2) {
                /* I hope I never see this... */
                clErrorLog("clBitStringToKeyUsage: KeyUsage larger than 2 bytes!");
index c55e15ebc36ea7d32ee48b71dc2e2dee20123296..7c0401c98d9f89241031889d9e446d6c998d75a3 100644 (file)
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0420;
+                               LastUpgradeCheck = 0500;
                        };
                        buildConfigurationList = C27AD28D0987FCDC001272E0 /* Build configuration list for PBXProject "libsecurity_apple_x509_cl" */;
                        compatibilityVersion = "Xcode 3.2";
                        };
                        buildConfigurationList = C27AD28D0987FCDC001272E0 /* Build configuration list for PBXProject "libsecurity_apple_x509_cl" */;
                        compatibilityVersion = "Xcode 3.2";
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 184460FF146E82B800B12992 /* debug.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 184460FF146E82B800B12992 /* debug.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446101146E82B800B12992 /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446101146E82B800B12992 /* release.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                        };
                        name = Release;
                };
                C27AD28A0987FCDC001272E0 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                        };
                        name = Release;
                };
                C27AD28A0987FCDC001272E0 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                EXECUTABLE_PREFIX = "";
                                INFOPLIST_FILE = "Info-plugin_apple_x509_cl.plist";
                                PRODUCT_NAME = apple_x509_cl;
                                EXECUTABLE_PREFIX = "";
                                INFOPLIST_FILE = "Info-plugin_apple_x509_cl.plist";
                                PRODUCT_NAME = apple_x509_cl;
                C27AD28C0987FCDC001272E0 /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                C27AD28C0987FCDC001272E0 /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                EXECUTABLE_PREFIX = "";
                                INFOPLIST_FILE = "Info-plugin_apple_x509_cl.plist";
                                PRODUCT_NAME = apple_x509_cl;
                                EXECUTABLE_PREFIX = "";
                                INFOPLIST_FILE = "Info-plugin_apple_x509_cl.plist";
                                PRODUCT_NAME = apple_x509_cl;
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446100146E82B800B12992 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446100146E82B800B12992 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446100146E82B800B12992 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446100146E82B800B12992 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
index c32bb40421c5b4257123583cead855587f34245a..ec90d955ef169ae915203c30632c82efe0ec0204 100644 (file)
@@ -1,12 +1,12 @@
 /*
  * Copyright (c) 2000-2011 Apple Inc. All Rights Reserved.
 /*
  * Copyright (c) 2000-2011 Apple Inc. All Rights Reserved.
- * 
+ *
  * The contents of this file constitute Original Code as defined in and are
  * subject to the Apple Public Source License Version 1.2 (the 'License').
  * You may not use this file except in 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 contents of this file constitute Original Code as defined in and are
  * subject to the Apple Public Source License Version 1.2 (the 'License').
  * You may not use this file except in compliance with the License. Please obtain
  * a copy of the License at http://www.apple.com/publicsource and read it before
  * using this file.
- * 
+ *
  * This Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
  * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
  * This Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
  * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
@@ -40,7 +40,7 @@
 #include <Security/SecImportExport.h>
 #include <Security/SecTrustSettingsPriv.h>
 
 #include <Security/SecImportExport.h>
 #include <Security/SecTrustSettingsPriv.h>
 
-#define tpTimeDbg(args...)             secdebug("tpTime", ## args) 
+#define tpTimeDbg(args...)             secdebug("tpTime", ## args)
 #define tpCertInfoDbg(args...) secdebug("tpCert", ## args)
 
 static const TPClItemCalls tpCertClCalls =
 #define tpCertInfoDbg(args...) secdebug("tpCert", ## args)
 
 static const TPClItemCalls tpCertClCalls =
@@ -64,7 +64,7 @@ TPClItemInfo::TPClItemInfo(
        const CSSM_DATA         *itemData,
        TPItemCopy                      copyItemData,
        const char                      *verifyTime)    // may be NULL
        const CSSM_DATA         *itemData,
        TPItemCopy                      copyItemData,
        const char                      *verifyTime)    // may be NULL
-               :       
+               :
                        mClHand(clHand),
                        mCspHand(cspHand),
                        mClCalls(clCalls),
                        mClHand(clHand),
                        mCspHand(cspHand),
                        mClCalls(clCalls),
@@ -83,9 +83,9 @@ TPClItemInfo::TPClItemInfo(
                CSSM_RETURN crtn = cacheItem(itemData, copyItemData);
                if(crtn) {
                        CssmError::throwMe(crtn);
                CSSM_RETURN crtn = cacheItem(itemData, copyItemData);
                if(crtn) {
                        CssmError::throwMe(crtn);
-               }                       
-                       
-               /* 
+               }
+
+               /*
                 * Fetch standard fields...
                 * Issue name assumes same OID for Certs and CRLs!
                 */
                 * Fetch standard fields...
                 * Issue name assumes same OID for Certs and CRLs!
                 */
@@ -93,9 +93,9 @@ TPClItemInfo::TPClItemInfo(
                if(crtn) {
                        CssmError::throwMe(crtn);
                }
                if(crtn) {
                        CssmError::throwMe(crtn);
                }
-               
-               /* 
-                * Signing algorithm, infer from TBS algId 
+
+               /*
+                * Signing algorithm, infer from TBS algId
                 * Note this assumes that the OID for fetching this field is the
                 * same for CRLs and Certs.
                 */
                 * Note this assumes that the OID for fetching this field is the
                 * same for CRLs and Certs.
                 */
@@ -109,7 +109,7 @@ TPClItemInfo::TPClItemInfo(
                        tpErrorLog("TPClItemInfo: bad CSSM_X509_ALGORITHM_IDENTIFIER\n");
                        CssmError::throwMe(CSSMERR_TP_INTERNAL_ERROR);
                }
                        tpErrorLog("TPClItemInfo: bad CSSM_X509_ALGORITHM_IDENTIFIER\n");
                        CssmError::throwMe(CSSMERR_TP_INTERNAL_ERROR);
                }
-               CSSM_X509_ALGORITHM_IDENTIFIER *algId = 
+               CSSM_X509_ALGORITHM_IDENTIFIER *algId =
                        (CSSM_X509_ALGORITHM_IDENTIFIER *)algField->Data;
                bool algFound = cssmOidToAlg(&algId->algorithm, &mSigAlg);
                if(!algFound) {
                        (CSSM_X509_ALGORITHM_IDENTIFIER *)algField->Data;
                bool algFound = cssmOidToAlg(&algId->algorithm, &mSigAlg);
                if(!algFound) {
@@ -124,7 +124,7 @@ TPClItemInfo::TPClItemInfo(
                        }
                }
                freeField(&CSSMOID_X509V1SignatureAlgorithmTBS, algField);
                        }
                }
                freeField(&CSSMOID_X509V1SignatureAlgorithmTBS, algField);
-       
+
                fetchNotBeforeAfter();
                calculateCurrent(verifyTime);
        }
                fetchNotBeforeAfter();
                calculateCurrent(verifyTime);
        }
@@ -171,7 +171,7 @@ CSSM_RETURN TPClItemInfo::fetchField(
        CSSM_DATA_PTR   *fieldData)             // mallocd by CL and RETURNED
 {
        CSSM_RETURN crtn;
        CSSM_DATA_PTR   *fieldData)             // mallocd by CL and RETURNED
 {
        CSSM_RETURN crtn;
-       
+
        uint32 NumberOfFields = 0;
        CSSM_HANDLE resultHand = 0;
        *fieldData = NULL;
        uint32 NumberOfFields = 0;
        CSSM_HANDLE resultHand = 0;
        *fieldData = NULL;
@@ -189,7 +189,7 @@ CSSM_RETURN TPClItemInfo::fetchField(
                return crtn;
        }
        if(NumberOfFields != 1) {
                return crtn;
        }
        if(NumberOfFields != 1) {
-               tpErrorLog("TPCertInfo::fetchField: numFields %d, expected 1\n", 
+               tpCertInfoDbg("TPClItemInfo::fetchField: numFields %d, expected 1\n",
                        (int)NumberOfFields);
        }
        mClCalls.abortQuery(mClHand, resultHand);
                        (int)NumberOfFields);
        }
        mClCalls.abortQuery(mClHand, resultHand);
@@ -197,15 +197,15 @@ CSSM_RETURN TPClItemInfo::fetchField(
 }
 
 /* free arbitrary field obtained from fetchField() */
 }
 
 /* free arbitrary field obtained from fetchField() */
-CSSM_RETURN TPClItemInfo::freeField( 
+CSSM_RETURN TPClItemInfo::freeField(
        const CSSM_OID  *fieldOid,
        const CSSM_OID  *fieldOid,
-       CSSM_DATA_PTR   fieldData)      
+       CSSM_DATA_PTR   fieldData)
 {
        return CSSM_CL_FreeFieldValue(mClHand, fieldOid, fieldData);
 
 }
 
 {
        return CSSM_CL_FreeFieldValue(mClHand, fieldOid, fieldData);
 
 }
 
-/* 
+/*
  * Verify with an issuer cert - works on certs and CRLs.
  * Issuer/subject name match already performed by caller.
  * Optional paramCert is used to provide parameters when issuer
  * Verify with an issuer cert - works on certs and CRLs.
  * Issuer/subject name match already performed by caller.
  * Optional paramCert is used to provide parameters when issuer
@@ -220,9 +220,9 @@ CSSM_RETURN TPClItemInfo::verifyWithIssuer(
        assert(mClHand != 0);
        assert(issuerCert->isIssuerOf(*this));
        assert(mCspHand != 0);
        assert(mClHand != 0);
        assert(issuerCert->isIssuerOf(*this));
        assert(mCspHand != 0);
-       
+
        /*
        /*
-        * Special case: detect partial public key right now; don't even 
+        * Special case: detect partial public key right now; don't even
         * bother trying the cert verify in that case.
         */
        if(issuerCert->hasPartialKey() && (paramCert == NULL)) {
         * bother trying the cert verify in that case.
         */
        if(issuerCert->hasPartialKey() && (paramCert == NULL)) {
@@ -230,7 +230,7 @@ CSSM_RETURN TPClItemInfo::verifyWithIssuer(
                tpVfyDebug("verifyWithIssuer PUBLIC_KEY_INCOMPLETE");
                return CSSMERR_CSP_APPLE_PUBLIC_KEY_INCOMPLETE;
        }
                tpVfyDebug("verifyWithIssuer PUBLIC_KEY_INCOMPLETE");
                return CSSMERR_CSP_APPLE_PUBLIC_KEY_INCOMPLETE;
        }
-       
+
        CSSM_CC_HANDLE ccHand;
        crtn = CSSM_CSP_CreateSignatureContext(mCspHand,
                mSigAlg,
        CSSM_CC_HANDLE ccHand;
        crtn = CSSM_CSP_CreateSignatureContext(mCspHand,
                mSigAlg,
@@ -243,10 +243,10 @@ CSSM_RETURN TPClItemInfo::verifyWithIssuer(
        }
        if(paramCert != NULL) {
                assert(issuerCert->hasPartialKey());
        }
        if(paramCert != NULL) {
                assert(issuerCert->hasPartialKey());
-               
+
                /* add in parameter-bearing key */
                /* add in parameter-bearing key */
-               CSSM_CONTEXT_ATTRIBUTE          newAttr;        
-               
+               CSSM_CONTEXT_ATTRIBUTE          newAttr;
+
                newAttr.AttributeType   = CSSM_ATTRIBUTE_PARAM_KEY;
                newAttr.AttributeLength = sizeof(CSSM_KEY);
                newAttr.Attribute.Key   = paramCert->pubKey();
                newAttr.AttributeType   = CSSM_ATTRIBUTE_PARAM_KEY;
                newAttr.AttributeLength = sizeof(CSSM_KEY);
                newAttr.Attribute.Key   = paramCert->pubKey();
@@ -256,8 +256,8 @@ CSSM_RETURN TPClItemInfo::verifyWithIssuer(
                        CssmError::throwMe(crtn);
                }
        }
                        CssmError::throwMe(crtn);
                }
        }
-       crtn = mClCalls.itemVerify(mClHand, 
-       ccHand, 
+       crtn = mClCalls.itemVerify(mClHand,
+       ccHand,
        mItemData,
        NULL,                           // issuer cert
        NULL,                           // VerifyScope
        mItemData,
        NULL,                           // issuer cert
        NULL,                           // VerifyScope
@@ -280,7 +280,7 @@ CSSM_RETURN TPClItemInfo::verifyWithIssuer(
 
 CSSM_RETURN TPClItemInfo::cacheItem(
        const CSSM_DATA         *itemData,
 
 CSSM_RETURN TPClItemInfo::cacheItem(
        const CSSM_DATA         *itemData,
-       TPItemCopy                      copyItemData)                                                                                           
+       TPItemCopy                      copyItemData)
 {
        switch(copyItemData) {
                case TIC_NoCopy:
 {
        switch(copyItemData) {
                case TIC_NoCopy:
@@ -294,18 +294,18 @@ CSSM_RETURN TPClItemInfo::cacheItem(
                        assert(0);
                        CssmError::throwMe(CSSMERR_TP_INTERNAL_ERROR);
        }
                        assert(0);
                        CssmError::throwMe(CSSMERR_TP_INTERNAL_ERROR);
        }
-       
+
        /* cache the cert/CRL in the CL */
        return mClCalls.cacheItem(mClHand, mItemData, &mCacheHand);
 }
 
        /* cache the cert/CRL in the CL */
        return mClCalls.cacheItem(mClHand, mItemData, &mCacheHand);
 }
 
-/* 
- * Calculate not before/after times as struct tm. Only throws on 
+/*
+ * Calculate not before/after times as struct tm. Only throws on
  * gross error (CSSMERR_TP_INVALID_CERT_POINTER, etc.).
  *
  * gross error (CSSMERR_TP_INVALID_CERT_POINTER, etc.).
  *
- * Only differences between Cert and CRL flavors of this are the 
+ * Only differences between Cert and CRL flavors of this are the
  * OIDs used to fetch the appropriate before/after times, both of
  * OIDs used to fetch the appropriate before/after times, both of
- * which are expressed as CSSM_X509_TIME structs for both Certs 
+ * which are expressed as CSSM_X509_TIME structs for both Certs
  * and CRLS.
  */
 void TPClItemInfo::fetchNotBeforeAfter()
  * and CRLS.
  */
 void TPClItemInfo::fetchNotBeforeAfter()
@@ -314,17 +314,17 @@ void TPClItemInfo::fetchNotBeforeAfter()
        CSSM_DATA_PTR   notAfterField = NULL;
        CSSM_RETURN             crtn = CSSM_OK;
        CSSM_X509_TIME  *xTime;
        CSSM_DATA_PTR   notAfterField = NULL;
        CSSM_RETURN             crtn = CSSM_OK;
        CSSM_X509_TIME  *xTime;
-       
+
        assert(cacheHand() != CSSM_INVALID_HANDLE);
        crtn = fetchField(mClCalls.notBeforeOid, &notBeforeField);
        if(crtn) {
                tpErrorLog("fetchNotBeforeAfter: GetField error\n");
                CssmError::throwMe(mClCalls.invalidItemRtn);
        }
        assert(cacheHand() != CSSM_INVALID_HANDLE);
        crtn = fetchField(mClCalls.notBeforeOid, &notBeforeField);
        if(crtn) {
                tpErrorLog("fetchNotBeforeAfter: GetField error\n");
                CssmError::throwMe(mClCalls.invalidItemRtn);
        }
-       
+
        /* subsequent errors to errOut */
        xTime = (CSSM_X509_TIME *)notBeforeField->Data;
        /* subsequent errors to errOut */
        xTime = (CSSM_X509_TIME *)notBeforeField->Data;
-       if(timeStringToCfDate((char *)xTime->time.Data, xTime->time.Length, &mNotBefore)) {
+       if(timeStringToCfDate((char *)xTime->time.Data, (unsigned)xTime->time.Length, &mNotBefore)) {
                tpErrorLog("fetchNotBeforeAfter: malformed notBefore time\n");
                crtn = mClCalls.invalidItemRtn;
                goto errOut;
                tpErrorLog("fetchNotBeforeAfter: malformed notBefore time\n");
                crtn = mClCalls.invalidItemRtn;
                goto errOut;
@@ -333,7 +333,7 @@ void TPClItemInfo::fetchNotBeforeAfter()
        crtn = fetchField(mClCalls.notAfterOid, &notAfterField);
        if(crtn) {
                /*
        crtn = fetchField(mClCalls.notAfterOid, &notAfterField);
        if(crtn) {
                /*
-                * Tolerate a missing NextUpdate in CRL only 
+                * Tolerate a missing NextUpdate in CRL only
                 */
                if(mClCalls.notAfterOid == &CSSMOID_X509V1ValidityNotAfter) {
                        tpErrorLog("fetchNotBeforeAfter: GetField error\n");
                 */
                if(mClCalls.notAfterOid == &CSSMOID_X509V1ValidityNotAfter) {
                        tpErrorLog("fetchNotBeforeAfter: GetField error\n");
@@ -344,14 +344,14 @@ void TPClItemInfo::fetchNotBeforeAfter()
                        /*
                         * Fake NextUpdate to be "at the end of time"
                         */
                        /*
                         * Fake NextUpdate to be "at the end of time"
                         */
-                       timeStringToCfDate(CSSM_APPLE_CRL_END_OF_TIME, 
-                               strlen(CSSM_APPLE_CRL_END_OF_TIME), 
+                       timeStringToCfDate(CSSM_APPLE_CRL_END_OF_TIME,
+                               strlen(CSSM_APPLE_CRL_END_OF_TIME),
                                &mNotAfter);
                }
        }
        else {
                xTime = (CSSM_X509_TIME *)notAfterField->Data;
                                &mNotAfter);
                }
        }
        else {
                xTime = (CSSM_X509_TIME *)notAfterField->Data;
-               if(timeStringToCfDate((char *)xTime->time.Data, xTime->time.Length, &mNotAfter)) {
+               if(timeStringToCfDate((char *)xTime->time.Data, (unsigned)xTime->time.Length, &mNotAfter)) {
                        tpErrorLog("fetchNotBeforeAfter: malformed notAfter time\n");
                        crtn = mClCalls.invalidItemRtn;
                        goto errOut;
                        tpErrorLog("fetchNotBeforeAfter: malformed notAfter time\n");
                        crtn = mClCalls.invalidItemRtn;
                        goto errOut;
@@ -370,9 +370,9 @@ errOut:
        }
 }
 
        }
 }
 
-/* 
+/*
  * Verify validity (not before/after) by comparing the reference
  * Verify validity (not before/after) by comparing the reference
- * time (verifyString if present, or "now" if NULL) to the 
+ * time (verifyString if present, or "now" if NULL) to the
  * not before/after fields fetched from the item at construction.
  *
  * Called implicitly at construction; can be called again any time
  * not before/after fields fetched from the item at construction.
  *
  * Called implicitly at construction; can be called again any time
@@ -389,10 +389,10 @@ CSSM_RETURN TPClItemInfo::calculateCurrent(
        const char                      *verifyString)
 {
        CFDateRef refTime = NULL;
        const char                      *verifyString)
 {
        CFDateRef refTime = NULL;
-       
+
        if(verifyString != NULL) {
                /* caller specifies verification time base */
        if(verifyString != NULL) {
                /* caller specifies verification time base */
-               if(timeStringToCfDate(verifyString, strlen(verifyString), &refTime)) {
+               if(timeStringToCfDate(verifyString, (unsigned)strlen(verifyString), &refTime)) {
                        tpErrorLog("calculateCurrent: timeStringToCfDate error\n");
                        return CSSMERR_TP_INVALID_TIMESTRING;
                }
                        tpErrorLog("calculateCurrent: timeStringToCfDate error\n");
                        return CSSMERR_TP_INVALID_TIMESTRING;
                }
@@ -403,7 +403,7 @@ CSSM_RETURN TPClItemInfo::calculateCurrent(
        }
        if(compareTimes(refTime, mNotBefore) < 0) {
                mIsNotValidYet = true;
        }
        if(compareTimes(refTime, mNotBefore) < 0) {
                mIsNotValidYet = true;
-               tpTimeDbg("\nTP_CERT_NOT_VALID_YET: now %g notBefore %g", 
+               tpTimeDbg("\nTP_CERT_NOT_VALID_YET: now %g notBefore %g",
                        CFDateGetAbsoluteTime(refTime), CFDateGetAbsoluteTime(mNotBefore));
                CFRelease(refTime);
                return mClCalls.notValidYetRtn;
                        CFDateGetAbsoluteTime(refTime), CFDateGetAbsoluteTime(mNotBefore));
                CFRelease(refTime);
                return mClCalls.notValidYetRtn;
@@ -414,7 +414,7 @@ CSSM_RETURN TPClItemInfo::calculateCurrent(
 
        if(compareTimes(refTime, mNotAfter) > 0) {
                mIsExpired = true;
 
        if(compareTimes(refTime, mNotAfter) > 0) {
                mIsExpired = true;
-               tpTimeDbg("\nTP_CERT_EXPIRED: now %g notBefore %g", 
+               tpTimeDbg("\nTP_CERT_EXPIRED: now %g notBefore %g",
                        CFDateGetAbsoluteTime(refTime), CFDateGetAbsoluteTime(mNotBefore));
                CFRelease(refTime);
                return mClCalls.expiredRtn;
                        CFDateGetAbsoluteTime(refTime), CFDateGetAbsoluteTime(mNotBefore));
                CFRelease(refTime);
                return mClCalls.expiredRtn;
@@ -427,7 +427,7 @@ CSSM_RETURN TPClItemInfo::calculateCurrent(
 }
 
 
 }
 
 
-/* 
+/*
  * No default constructor - this is the only way.
  * This caches the cert and fetches subjectName, issuerName, and
  * mPublicKey to ensure the incoming certData is well-constructed.
  * No default constructor - this is the only way.
  * This caches the cert and fetches subjectName, issuerName, and
  * mPublicKey to ensure the incoming certData is well-constructed.
@@ -440,7 +440,7 @@ TPCertInfo::TPCertInfo(
                                                                                        // false - caller owns
        const char                      *verifyTime)            // may be NULL
        :
                                                                                        // false - caller owns
        const char                      *verifyTime)            // may be NULL
        :
-               TPClItemInfo(clHand, cspHand, tpCertClCalls, certData, 
+               TPClItemInfo(clHand, cspHand, tpCertClCalls, certData,
                        copyCertData, verifyTime),
                mSubjectName(NULL),
                mPublicKeyData(NULL),
                        copyCertData, verifyTime),
                mSubjectName(NULL),
                mPublicKeyData(NULL),
@@ -472,7 +472,7 @@ TPCertInfo::TPCertInfo(
        tpCertInfoDbg("TPCertInfo construct this %p", this);
        mDlDbHandle.DLHandle = 0;
        mDlDbHandle.DBHandle = 0;
        tpCertInfoDbg("TPCertInfo construct this %p", this);
        mDlDbHandle.DLHandle = 0;
        mDlDbHandle.DBHandle = 0;
-       
+
        /* fetch subject name */
        crtn = fetchField(&CSSMOID_X509V1SubjectName, &mSubjectName);
        if(crtn) {
        /* fetch subject name */
        crtn = fetchField(&CSSMOID_X509V1SubjectName, &mSubjectName);
        if(crtn) {
@@ -480,7 +480,7 @@ TPCertInfo::TPCertInfo(
                releaseResources();
                CssmError::throwMe(crtn);
        }
                releaseResources();
                CssmError::throwMe(crtn);
        }
-       
+
        /* this cert's public key */
        crtn = fetchField(&CSSMOID_CSSMKeyStruct, &mPublicKeyData);
        if(crtn || (mPublicKeyData->Length != sizeof(CSSM_KEY))) {
        /* this cert's public key */
        crtn = fetchField(&CSSMOID_CSSMKeyStruct, &mPublicKeyData);
        if(crtn || (mPublicKeyData->Length != sizeof(CSSM_KEY))) {
@@ -489,7 +489,7 @@ TPCertInfo::TPCertInfo(
                CssmError::throwMe(crtn);
        }
        mPublicKey = (CSSM_KEY_PTR)mPublicKeyData->Data;
                CssmError::throwMe(crtn);
        }
        mPublicKey = (CSSM_KEY_PTR)mPublicKeyData->Data;
-       
+
        /* calculate other commonly used fields */
        if(tpCompareCssmData(mSubjectName, issuerName())) {
                /*
        /* calculate other commonly used fields */
        if(tpCompareCssmData(mSubjectName, issuerName())) {
                /*
@@ -503,7 +503,7 @@ TPCertInfo::TPCertInfo(
                mIsRoot = TRS_NotRoot;
        }
 }
                mIsRoot = TRS_NotRoot;
        }
 }
-       
+
 /* frees mSubjectName, mIssuerName, mCacheHand via mClHand */
 TPCertInfo::~TPCertInfo()
 {
 /* frees mSubjectName, mIssuerName, mCacheHand via mClHand */
 TPCertInfo::~TPCertInfo()
 {
@@ -541,10 +541,10 @@ const CSSM_DATA *TPCertInfo::subjectName()
        return mSubjectName;
 }
 
        return mSubjectName;
 }
 
-/* 
+/*
  * Perform semi-lazy evaluation of "rootness". Subject and issuer names
  * compared at constructor.
  * Perform semi-lazy evaluation of "rootness". Subject and issuer names
  * compared at constructor.
- * If avoidVerify is true, we won't do the signature verify: caller 
+ * If avoidVerify is true, we won't do the signature verify: caller
  * just wants to know if the subject and issuer names match.
  */
 bool TPCertInfo::isSelfSigned(bool avoidVerify)
  * just wants to know if the subject and issuer names match.
  */
 bool TPCertInfo::isSelfSigned(bool avoidVerify)
@@ -577,7 +577,7 @@ bool TPCertInfo::isSelfSigned(bool avoidVerify)
 
 /*
  * Am I the issuer of the specified subject item? Returns true if so.
 
 /*
  * Am I the issuer of the specified subject item? Returns true if so.
- * Works for subject certs as well as CRLs. 
+ * Works for subject certs as well as CRLs.
  */
 bool TPCertInfo::isIssuerOf(
        const TPClItemInfo      &subject)
  */
 bool TPCertInfo::isIssuerOf(
        const TPClItemInfo      &subject)
@@ -595,7 +595,7 @@ bool TPCertInfo::isIssuerOf(
 bool TPCertInfo::addStatusCode(CSSM_RETURN code)
 {
        mNumStatusCodes++;
 bool TPCertInfo::addStatusCode(CSSM_RETURN code)
 {
        mNumStatusCodes++;
-       mStatusCodes = (CSSM_RETURN *)realloc(mStatusCodes, 
+       mStatusCodes = (CSSM_RETURN *)realloc(mStatusCodes,
                mNumStatusCodes * sizeof(CSSM_RETURN));
        mStatusCodes[mNumStatusCodes - 1] = code;
        return isStatusFatal(code);
                mNumStatusCodes * sizeof(CSSM_RETURN));
        mStatusCodes[mNumStatusCodes - 1] = code;
        return isStatusFatal(code);
@@ -623,7 +623,7 @@ bool TPCertInfo::isStatusFatal(CSSM_RETURN code)
        return true;
 }
 
        return true;
 }
 
-/* 
+/*
  * Indicate whether this cert's public key is a CSSM_KEYATTR_PARTIAL
  * key.
  */
  * Indicate whether this cert's public key is a CSSM_KEYATTR_PARTIAL
  * key.
  */
@@ -696,8 +696,8 @@ bool TPCertInfo::shouldReject()
 }
 
 /*
 }
 
 /*
- * Evaluate trust settings; returns true in *foundMatchingEntry if positive 
- * match found - i.e., cert chain construction is done. 
+ * Evaluate trust settings; returns true in *foundMatchingEntry if positive
+ * match found - i.e., cert chain construction is done.
  */
 OSStatus TPCertInfo::evaluateTrustSettings(
        const CSSM_OID &policyOid,
  */
 OSStatus TPCertInfo::evaluateTrustSettings(
        const CSSM_OID &policyOid,
@@ -707,9 +707,9 @@ OSStatus TPCertInfo::evaluateTrustSettings(
        bool *foundMatchingEntry,                       // RETURNED
        bool *foundAnyEntry)                            // RETURNED
 {
        bool *foundMatchingEntry,                       // RETURNED
        bool *foundAnyEntry)                            // RETURNED
 {
-       /* 
+       /*
         * We might have to force a re-evaluation if the requested key usage
         * We might have to force a re-evaluation if the requested key usage
-        * is not a subset of what we already checked for (and cached). 
+        * is not a subset of what we already checked for (and cached).
         */
        if(mTrustSettingsEvaluated) {
                bool doFlush = false;
         */
        if(mTrustSettingsEvaluated) {
                bool doFlush = false;
@@ -738,10 +738,10 @@ OSStatus TPCertInfo::evaluateTrustSettings(
                /* else we can safely use the cached values */
        }
        if(!mTrustSettingsEvaluated) {
                /* else we can safely use the cached values */
        }
        if(!mTrustSettingsEvaluated) {
-       
+
                if(mCertHashStr == NULL) {
                        const CSSM_DATA *certData = itemData();
                if(mCertHashStr == NULL) {
                        const CSSM_DATA *certData = itemData();
-                       mCertHashStr = SecTrustSettingsCertHashStrFromData(certData->Data, 
+                       mCertHashStr = SecTrustSettingsCertHashStrFromData(certData->Data,
                                certData->Length);
                }
 
                                certData->Length);
                }
 
@@ -750,7 +750,7 @@ OSStatus TPCertInfo::evaluateTrustSettings(
                        policyString,
                        policyStringLen,
                        keyUse,
                        policyString,
                        policyStringLen,
                        keyUse,
-                       /* 
+                       /*
                         * This is the purpose of the avoidVerify option, right here.
                         * If this is a root cert and it has trust settings, we avoid
                         * the signature verify. If it turns out there are no trust
                         * This is the purpose of the avoidVerify option, right here.
                         * If this is a root cert and it has trust settings, we avoid
                         * the signature verify. If it turns out there are no trust
@@ -772,7 +772,7 @@ OSStatus TPCertInfo::evaluateTrustSettings(
                mTrustSettingsKeyUsage = keyUse;
                #ifndef NDEBUG
                if(mTrustSettingsFoundMatchingEntry) {
                mTrustSettingsKeyUsage = keyUse;
                #ifndef NDEBUG
                if(mTrustSettingsFoundMatchingEntry) {
-                       tpTrustSettingsDbg("evaluateTrustSettings: found for %p result %d", 
+                       tpTrustSettingsDbg("evaluateTrustSettings: found for %p result %d",
                                this, (int)mTrustSettingsResult);
                }
                #endif
                                this, (int)mTrustSettingsResult);
                }
                #endif
@@ -784,7 +784,7 @@ OSStatus TPCertInfo::evaluateTrustSettings(
        *foundMatchingEntry = mTrustSettingsFoundMatchingEntry;
        *foundAnyEntry = mTrustSettingsFoundAnyEntry;
 
        *foundMatchingEntry = mTrustSettingsFoundMatchingEntry;
        *foundAnyEntry = mTrustSettingsFoundAnyEntry;
 
-       return noErr;
+       return errSecSuccess;
 }
 
 /* true means "verification terminated due to user trust setting" */
 }
 
 /* true means "verification terminated due to user trust setting" */
@@ -799,7 +799,7 @@ bool TPCertInfo::trustSettingsFound()
        }
 }
 
        }
 }
 
-/* 
+/*
  * Determine if this has an empty SubjectName field. Returns true if so.
  */
 bool TPCertInfo::hasEmptySubjectName()
  * Determine if this has an empty SubjectName field. Returns true if so.
  */
 bool TPCertInfo::hasEmptySubjectName()
@@ -810,16 +810,16 @@ bool TPCertInfo::hasEmptySubjectName()
         * field, as well as a possible BER-encoded subject with some extra cruft.
         */
        if((mSubjectName == NULL) || (mSubjectName->Length <= 4)) {
         * field, as well as a possible BER-encoded subject with some extra cruft.
         */
        if((mSubjectName == NULL) || (mSubjectName->Length <= 4)) {
-               return true;    
+               return true;
        }
        else {
        }
        else {
-               return false;   
+               return false;
        }
 }
 
        }
 }
 
-/* 
+/*
  * Free mUniqueRecord if it exists.
  * Free mUniqueRecord if it exists.
- * This is *not* done in our destructor because this record sometimes 
+ * This is *not* done in our destructor because this record sometimes
  * has to persist in the form of a CSSM evidence chain.
  */
 void TPCertInfo::freeUniqueRecord()
  * has to persist in the form of a CSSM evidence chain.
  */
 void TPCertInfo::freeUniqueRecord()
@@ -834,7 +834,7 @@ void TPCertInfo::freeUniqueRecord()
 /***
  *** TPCertGroup class
  ***/
 /***
  *** TPCertGroup class
  ***/
+
 /* build empty group */
 TPCertGroup::TPCertGroup(
        Allocator                       &alloc,
 /* build empty group */
 TPCertGroup::TPCertGroup(
        Allocator                       &alloc,
@@ -848,12 +848,12 @@ TPCertGroup::TPCertGroup(
        tpCertInfoDbg("TPCertGroup simple construct this %p", this);
        /* nothing for now */
 }
        tpCertInfoDbg("TPCertGroup simple construct this %p", this);
        /* nothing for now */
 }
-       
+
 /*
  * Construct from unordered, untrusted CSSM_CERTGROUP. Resulting
  * TPCertInfos are more or less in the same order as the incoming
  * certs, though incoming certs are discarded if they don't parse.
 /*
  * Construct from unordered, untrusted CSSM_CERTGROUP. Resulting
  * TPCertInfos are more or less in the same order as the incoming
  * certs, though incoming certs are discarded if they don't parse.
- * No verification of any sort is performed. 
+ * No verification of any sort is performed.
  */
 TPCertGroup::TPCertGroup(
        const CSSM_CERTGROUP    &CertGroupFrag,
  */
 TPCertGroup::TPCertGroup(
        const CSSM_CERTGROUP    &CertGroupFrag,
@@ -879,7 +879,7 @@ TPCertGroup::TPCertGroup(
                CssmError::throwMe(CSSMERR_TP_INVALID_CL_HANDLE);
        }
        if(firstCertMustBeValid) {
                CssmError::throwMe(CSSMERR_TP_INVALID_CL_HANDLE);
        }
        if(firstCertMustBeValid) {
-               if( (CertGroupFrag.NumCerts == 0) ||                    
+               if( (CertGroupFrag.NumCerts == 0) ||
                (CertGroupFrag.GroupList.CertList[0].Data == NULL) ||
                (CertGroupFrag.GroupList.CertList[0].Length == 0)) {
                                CssmError::throwMe(CSSMERR_TP_INVALID_CERTIFICATE);
                (CertGroupFrag.GroupList.CertList[0].Data == NULL) ||
                (CertGroupFrag.GroupList.CertList[0].Length == 0)) {
                                CssmError::throwMe(CSSMERR_TP_INVALID_CERTIFICATE);
@@ -903,9 +903,9 @@ TPCertGroup::TPCertGroup(
                default:
                        CssmError::throwMe(CSSMERR_TP_UNKNOWN_FORMAT);
        }
                default:
                        CssmError::throwMe(CSSMERR_TP_UNKNOWN_FORMAT);
        }
-       
-       /* 
-        * Add remaining input certs to mCertInfo. 
+
+       /*
+        * Add remaining input certs to mCertInfo.
         */
        TPCertInfo *certInfo = NULL;
        for(unsigned certDex=0; certDex<CertGroupFrag.NumCerts; certDex++) {
         */
        TPCertInfo *certInfo = NULL;
        for(unsigned certDex=0; certDex<CertGroupFrag.NumCerts; certDex++) {
@@ -960,7 +960,7 @@ void TPCertGroup::appendCert(
                else {
                        mSizeofCertInfo *= 2;
                }
                else {
                        mSizeofCertInfo *= 2;
                }
-               mCertInfo = (TPCertInfo **)mAlloc.realloc(mCertInfo, 
+               mCertInfo = (TPCertInfo **)mAlloc.realloc(mCertInfo,
                        mSizeofCertInfo * sizeof(TPCertInfo *));
        }
        mCertInfo[mNumCerts++] = certInfo;
                        mSizeofCertInfo * sizeof(TPCertInfo *));
        }
        mCertInfo[mNumCerts++] = certInfo;
@@ -976,14 +976,14 @@ TPCertInfo *TPCertGroup::certAtIndex(
 }
 
 TPCertInfo *TPCertGroup::removeCertAtIndex(
 }
 
 TPCertInfo *TPCertGroup::removeCertAtIndex(
-       unsigned                        index)                          // doesn't delete the cert, just 
+       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];
                                                                                        // 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++) {
        /* removed requested element and compact remaining array */
        unsigned i;
        for(i=index; i<(mNumCerts - 1); i++) {
@@ -1017,21 +1017,21 @@ TPCertInfo *TPCertGroup::lastCert()
 /* build a CSSM_CERTGROUP corresponding with our mCertInfo */
 CSSM_CERTGROUP_PTR TPCertGroup::buildCssmCertGroup()
 {
 /* build a CSSM_CERTGROUP corresponding with our mCertInfo */
 CSSM_CERTGROUP_PTR TPCertGroup::buildCssmCertGroup()
 {
-       CSSM_CERTGROUP_PTR cgrp = 
+       CSSM_CERTGROUP_PTR cgrp =
                (CSSM_CERTGROUP_PTR)mAlloc.malloc(sizeof(CSSM_CERTGROUP));
        cgrp->NumCerts = mNumCerts;
        cgrp->CertGroupType = CSSM_CERTGROUP_DATA;
        cgrp->CertType = CSSM_CERT_X_509v3;
                (CSSM_CERTGROUP_PTR)mAlloc.malloc(sizeof(CSSM_CERTGROUP));
        cgrp->NumCerts = mNumCerts;
        cgrp->CertGroupType = CSSM_CERTGROUP_DATA;
        cgrp->CertType = CSSM_CERT_X_509v3;
-       cgrp->CertEncoding = CSSM_CERT_ENCODING_DER; 
+       cgrp->CertEncoding = CSSM_CERT_ENCODING_DER;
        if(mNumCerts == 0) {
                /* legal */
                cgrp->GroupList.CertList = NULL;
                return cgrp;
        }
        if(mNumCerts == 0) {
                /* legal */
                cgrp->GroupList.CertList = NULL;
                return cgrp;
        }
-       cgrp->GroupList.CertList = (CSSM_DATA_PTR)mAlloc.calloc(mNumCerts, 
+       cgrp->GroupList.CertList = (CSSM_DATA_PTR)mAlloc.calloc(mNumCerts,
                sizeof(CSSM_DATA));
        for(unsigned i=0; i<mNumCerts; i++) {
                sizeof(CSSM_DATA));
        for(unsigned i=0; i<mNumCerts; i++) {
-               tpCopyCssmData(mAlloc, mCertInfo[i]->itemData(), 
+               tpCopyCssmData(mAlloc, mCertInfo[i]->itemData(),
                        &cgrp->GroupList.CertList[i]);
        }
        return cgrp;
                        &cgrp->GroupList.CertList[i]);
        }
        return cgrp;
@@ -1041,13 +1041,13 @@ CSSM_CERTGROUP_PTR TPCertGroup::buildCssmCertGroup()
 CSSM_TP_APPLE_EVIDENCE_INFO *TPCertGroup::buildCssmEvidenceInfo()
 {
        CSSM_TP_APPLE_EVIDENCE_INFO *infoArray;
 CSSM_TP_APPLE_EVIDENCE_INFO *TPCertGroup::buildCssmEvidenceInfo()
 {
        CSSM_TP_APPLE_EVIDENCE_INFO *infoArray;
-       
+
        infoArray = (CSSM_TP_APPLE_EVIDENCE_INFO *)mAlloc.calloc(mNumCerts,
                sizeof(CSSM_TP_APPLE_EVIDENCE_INFO));
        for(unsigned i=0; i<mNumCerts; i++) {
                TPCertInfo *certInfo = mCertInfo[i];
                CSSM_TP_APPLE_EVIDENCE_INFO *evInfo = &infoArray[i];
        infoArray = (CSSM_TP_APPLE_EVIDENCE_INFO *)mAlloc.calloc(mNumCerts,
                sizeof(CSSM_TP_APPLE_EVIDENCE_INFO));
        for(unsigned i=0; i<mNumCerts; i++) {
                TPCertInfo *certInfo = mCertInfo[i];
                CSSM_TP_APPLE_EVIDENCE_INFO *evInfo = &infoArray[i];
-               
+
                /* first the booleans */
                if(certInfo->isExpired()) {
                        evInfo->StatusBits |= CSSM_CERT_STATUS_EXPIRED;
                /* first the booleans */
                if(certInfo->isExpired()) {
                        evInfo->StatusBits |= CSSM_CERT_STATUS_EXPIRED;
@@ -1124,10 +1124,10 @@ CSSM_TP_APPLE_EVIDENCE_INFO *TPCertGroup::buildCssmEvidenceInfo()
        }
        return infoArray;
 }
        }
        return infoArray;
 }
-               
+
 /* Given a status for basic construction of a cert group and a status
  * of (optional) policy verification, plus the implicit notBefore/notAfter
 /* Given a status for basic construction of a cert group and a status
  * of (optional) policy verification, plus the implicit notBefore/notAfter
- * status in the certs, calculate a global return code. This just 
+ * status in the certs, calculate a global return code. This just
  * encapsulates a policy for CertGroupConstruct and CertGroupVerify.
  */
 CSSM_RETURN TPCertGroup::getReturnCode(
  * encapsulates a policy for CertGroupConstruct and CertGroupVerify.
  */
 CSSM_RETURN TPCertGroup::getReturnCode(
@@ -1148,13 +1148,13 @@ CSSM_RETURN TPCertGroup::getReturnCode(
        bool allowPostdated = allowExpired; // flag overrides any temporal invalidity
        bool requireRevPerCert = (actionFlags & CSSM_TP_ACTION_REQUIRE_REV_PER_CERT) ?
                true : false;
        bool allowPostdated = allowExpired; // flag overrides any temporal invalidity
        bool requireRevPerCert = (actionFlags & CSSM_TP_ACTION_REQUIRE_REV_PER_CERT) ?
                true : false;
-               
+
        /* check for expired, not valid yet */
        for(unsigned i=0; i<mNumCerts; i++) {
                TPCertInfo *ci = mCertInfo[i];
        /* check for expired, not valid yet */
        for(unsigned i=0; i<mNumCerts; i++) {
                TPCertInfo *ci = mCertInfo[i];
-               /* 
-                * Note avoidVerify = true for isSelfSigned(); if it were appropriate to 
-                * verify the signature, that would have happened in 
+               /*
+                * Note avoidVerify = true for isSelfSigned(); if it were appropriate to
+                * verify the signature, that would have happened in
                 * buildCssmEvidenceInfo() at the latest.
                 */
                if(ci->isExpired() &&
                 * buildCssmEvidenceInfo() at the latest.
                 */
                if(ci->isExpired() &&
@@ -1162,7 +1162,7 @@ CSSM_RETURN TPCertGroup::getReturnCode(
                    ci->isStatusFatal(CSSMERR_TP_CERT_EXPIRED)) {       // allowed for this cert
                        expired = true;
                }
                    ci->isStatusFatal(CSSMERR_TP_CERT_EXPIRED)) {       // allowed for this cert
                        expired = true;
                }
-               if(ci->isNotValidYet() && 
+               if(ci->isNotValidYet() &&
                   ci->isStatusFatal(CSSMERR_TP_CERT_NOT_VALID_YET)) {
                        postdated = true;
                }
                   ci->isStatusFatal(CSSMERR_TP_CERT_NOT_VALID_YET)) {
                        postdated = true;
                }
@@ -1173,7 +1173,7 @@ CSSM_RETURN TPCertGroup::getReturnCode(
        if(postdated && !allowPostdated) {
                return CSSMERR_TP_CERT_NOT_VALID_YET;
        }
        if(postdated && !allowPostdated) {
                return CSSMERR_TP_CERT_NOT_VALID_YET;
        }
-       
+
        /* Check for missing revocation check */
        if(requireRevPerCert) {
                for(unsigned i=0; i<mNumCerts; i++) {
        /* Check for missing revocation check */
        if(requireRevPerCert) {
                for(unsigned i=0; i<mNumCerts; i++) {
@@ -1210,11 +1210,11 @@ void TPCertGroup::setAllUnused()
 /*
  * See if the specified error status is allowed (return true) or
  * fatal (return false) per each cert's mAllowedErrs[]. Returns
 /*
  * See if the specified error status is allowed (return true) or
  * fatal (return false) per each cert's mAllowedErrs[]. Returns
- * true if any cert returns false for its isStatusFatal() call. 
+ * true if any cert returns false for its isStatusFatal() call.
  * The list of errors which can apply to cert-chain-wide allowedErrors
  * is right here; if the incoming error is not in that list, we
  * return false. If the incoming error code is CSSM_OK we return
  * The list of errors which can apply to cert-chain-wide allowedErrors
  * is right here; if the incoming error is not in that list, we
  * return false. If the incoming error code is CSSM_OK we return
- * true as a convenience for our callers. 
+ * true as a convenience for our callers.
  */
 bool TPCertGroup::isAllowedError(
        CSSM_RETURN     code)
  */
 bool TPCertGroup::isAllowedError(
        CSSM_RETURN     code)
@@ -1232,7 +1232,7 @@ bool TPCertGroup::isAllowedError(
                        break;
                default:
                        /* not a candidate for cert-chain-wide allowedErrors */
                        break;
                default:
                        /* not a candidate for cert-chain-wide allowedErrors */
-                       return false; 
+                       return false;
        }
 
        for(unsigned dex=0; dex<mNumCerts; dex++) {
        }
 
        for(unsigned dex=0; dex<mNumCerts; dex++) {
@@ -1254,13 +1254,13 @@ bool TPCertGroup::isInGroup(TPCertInfo &certInfo)
 {
        for(unsigned dex=0; dex<mNumCerts; dex++) {
                if(tpCompareCssmData(certInfo.itemData(), mCertInfo[dex]->itemData())) {
 {
        for(unsigned dex=0; dex<mNumCerts; dex++) {
                if(tpCompareCssmData(certInfo.itemData(), mCertInfo[dex]->itemData())) {
-                       return true;    
+                       return true;
                }
        }
        return false;
 }
 
                }
        }
        return false;
 }
 
-/* 
+/*
  * Encode issuing certs in this group as a PEM-encoded data blob.
  * Caller must free.
  */
  * Encode issuing certs in this group as a PEM-encoded data blob.
  * Caller must free.
  */
@@ -1323,7 +1323,7 @@ void TPCertGroup::encodeIssuers(CSSM_DATA &issuers)
  * Search unused incoming certs to find an issuer of specified cert or CRL.
  * WARNING this assumes a valid "used" state for all certs in this group.
  * If partialIssuerKey is true on return, caller must re-verify signature
  * Search unused incoming certs to find an issuer of specified cert or CRL.
  * WARNING this assumes a valid "used" state for all certs in this group.
  * If partialIssuerKey is true on return, caller must re-verify signature
- * of subject later when sufficient info is available. 
+ * of subject later when sufficient info is available.
  */
 TPCertInfo *TPCertGroup::findIssuerForCertOrCrl(
        const TPClItemInfo &subject,
  */
 TPCertInfo *TPCertGroup::findIssuerForCertOrCrl(
        const TPClItemInfo &subject,
@@ -1331,15 +1331,15 @@ TPCertInfo *TPCertGroup::findIssuerForCertOrCrl(
 {
        partialIssuerKey = false;
        TPCertInfo *expiredIssuer = NULL;
 {
        partialIssuerKey = false;
        TPCertInfo *expiredIssuer = NULL;
-       
+
        for(unsigned certDex=0; certDex<mNumCerts; certDex++) {
                TPCertInfo *certInfo = certAtIndex(certDex);
        for(unsigned certDex=0; certDex<mNumCerts; certDex++) {
                TPCertInfo *certInfo = certAtIndex(certDex);
-               
+
                /* has this one already been used in this search? */
                if(certInfo->used()) {
                        continue;
                }
                /* has this one already been used in this search? */
                if(certInfo->used()) {
                        continue;
                }
-               
+
                /* subject/issuer names match? */
                if(certInfo->isIssuerOf(subject)) {
                        /* yep, do a sig verify */
                /* subject/issuer names match? */
                if(certInfo->isIssuerOf(subject)) {
                        /* yep, do a sig verify */
@@ -1351,9 +1351,9 @@ TPCertInfo *TPCertGroup::findIssuerForCertOrCrl(
                                        partialIssuerKey = true;
                                        /* and fall thru */
                                case CSSM_OK:
                                        partialIssuerKey = true;
                                        /* and fall thru */
                                case CSSM_OK:
-                                       /* 
+                                       /*
                                         * Temporal validity check: if we're not already holding an expired
                                         * Temporal validity check: if we're not already holding an expired
-                                        * issuer, and this one's invalid, hold it and keep going. 
+                                        * issuer, and this one's invalid, hold it and keep going.
                                         */
                                        if((crtn == CSSM_OK) && (expiredIssuer == NULL)) {
                                                if(certInfo->isExpired() || certInfo->isNotValidYet()) {
                                         */
                                        if((crtn == CSSM_OK) && (expiredIssuer == NULL)) {
                                                if(certInfo->isExpired() || certInfo->isNotValidYet()) {
@@ -1379,32 +1379,32 @@ TPCertInfo *TPCertGroup::findIssuerForCertOrCrl(
                expiredIssuer->used(true);
                return expiredIssuer;
        }
                expiredIssuer->used(true);
                return expiredIssuer;
        }
-       
+
        /* not found */
        return NULL;
        /* not found */
        return NULL;
-}      
+}
 
 /*
 
 /*
- * Construct ordered, verified cert chain from a variety of inputs. 
- * Time validity does not affect the function return or any status, 
- * we always try to find a valid cert to replace an expired or 
- * not-yet-valid cert if we can. Final temporal validity of each 
- * cert must be checked by caller (it's stored in each TPCertInfo 
- * we add to ourself during construction). 
- * 
+ * Construct ordered, verified cert chain from a variety of inputs.
+ * Time validity does not affect the function return or any status,
+ * we always try to find a valid cert to replace an expired or
+ * not-yet-valid cert if we can. Final temporal validity of each
+ * cert must be checked by caller (it's stored in each TPCertInfo
+ * we add to ourself during construction).
+ *
  * Only possible error returns are:
  *      CSSMERR_TP_CERTIFICATE_CANT_OPERATE : issuer cert was found with a partial
  * Only possible error returns are:
  *      CSSMERR_TP_CERTIFICATE_CANT_OPERATE : issuer cert was found with a partial
- *                     public key, rendering full verification impossible. 
- *   CSSMERR_TP_INVALID_CERT_AUTHORITY : issuer cert was found with a partial 
+ *                     public key, rendering full verification impossible.
+ *   CSSMERR_TP_INVALID_CERT_AUTHORITY : issuer cert was found with a partial
  *                     public key and which failed to perform subsequent signature
  *                     verification.
  *
  *                     public key and which failed to perform subsequent signature
  *                     verification.
  *
- * Other interesting status is returned via the verifiedToRoot and 
- * verifiedToAnchor flags. 
+ * Other interesting status is returned via the verifiedToRoot and
+ * verifiedToAnchor flags.
  *
  *
- * NOTE: is it the caller's responsibility to call setAllUnused() for both 
+ * NOTE: is it the caller's responsibility to call setAllUnused() for both
  * incoming cert groups (inCertGroup and gatheredCerts). We don't do that
  * incoming cert groups (inCertGroup and gatheredCerts). We don't do that
- * here because we may call ourself recursively. 
+ * here because we may call ourself recursively.
  */
 CSSM_RETURN TPCertGroup::buildCertGroup(
        const TPClItemInfo              &subjectItem,   // Cert or CRL
  */
 CSSM_RETURN TPCertGroup::buildCertGroup(
        const TPClItemInfo              &subjectItem,   // Cert or CRL
@@ -1418,14 +1418,14 @@ CSSM_RETURN TPCertGroup::buildCertGroup(
        /* FIXME - maybe this should be a TPCertGroup */
        uint32                                  numAnchorCerts,
        const CSSM_DATA                 *anchorCerts,
        /* FIXME - maybe this should be a TPCertGroup */
        uint32                                  numAnchorCerts,
        const CSSM_DATA                 *anchorCerts,
-       
-       /* 
+
+       /*
         * Certs to be freed by caller (i.e., TPCertInfo which we allocate
         * as a result of using a cert from anchorCerts or dbList) are added
         * to this group.
         */
        TPCertGroup                             &certsToBeFreed,
         * Certs to be freed by caller (i.e., TPCertInfo which we allocate
         * as a result of using a cert from anchorCerts or dbList) are added
         * to this group.
         */
        TPCertGroup                             &certsToBeFreed,
-       
+
        /*
         * Other certificates gathered during the course of this operation,
         * currently consisting of certs fetched from DBs and from the net.
        /*
         * Other certificates gathered during the course of this operation,
         * currently consisting of certs fetched from DBs and from the net.
@@ -1433,32 +1433,32 @@ CSSM_RETURN TPCertGroup::buildCertGroup(
         * it's an optimization for the case when we're building a cert group
         * for TPCrlInfo::verifyWithContext - we avoid re-fetching certs from
         * the net which are needed to verify both the subject cert and a CRL.
         * it's an optimization for the case when we're building a cert group
         * for TPCrlInfo::verifyWithContext - we avoid re-fetching certs from
         * the net which are needed to verify both the subject cert and a CRL.
-        * We don't modify this TPCertGroup, we only use certs from it. 
+        * We don't modify this TPCertGroup, we only use certs from it.
         */
        TPCertGroup                             *gatheredCerts,
         */
        TPCertGroup                             *gatheredCerts,
-       
+
        /*
         * Indicates that subjectItem is a cert in this cert group.
        /*
         * Indicates that subjectItem is a cert in this cert group.
-        * If true, that cert will be tested for "root-ness", including 
+        * If true, that cert will be tested for "root-ness", including
         *   -- subject/issuer compare
         *   -- signature self-verify
         *   -- anchor compare
         */
        CSSM_BOOL                               subjectIsInGroup,
         *   -- subject/issuer compare
         *   -- signature self-verify
         *   -- anchor compare
         */
        CSSM_BOOL                               subjectIsInGroup,
-       
-       /* 
+
+       /*
         * CSSM_TP_ACTION_FETCH_CERT_FROM_NET,
         * CSSM_TP_ACTION_TRUST_SETTING,
         * CSSM_TP_ACTION_FETCH_CERT_FROM_NET,
         * CSSM_TP_ACTION_TRUST_SETTING,
-        * CSSM_TP_ACTION_IMPLICIT_ANCHORS are interesting 
+        * CSSM_TP_ACTION_IMPLICIT_ANCHORS are interesting
         */
        CSSM_APPLE_TP_ACTION_FLAGS      actionFlags,
         */
        CSSM_APPLE_TP_ACTION_FLAGS      actionFlags,
-       
+
        /* CSSM_TP_ACTION_TRUST_SETTING parameters */
        const CSSM_OID                  *policyOid,
        const char                              *policyStr,
        uint32                                  policyStrLen,
        SecTrustSettingsKeyUsage leafKeyUse,                            // usage of *first* cert in chain
        /* CSSM_TP_ACTION_TRUST_SETTING parameters */
        const CSSM_OID                  *policyOid,
        const char                              *policyStr,
        uint32                                  policyStrLen,
        SecTrustSettingsKeyUsage leafKeyUse,                            // usage of *first* cert in chain
-       
+
        /* returned */
        CSSM_BOOL                               &verifiedToRoot,                        // end of chain self-verifies
        CSSM_BOOL                               &verifiedToAnchor,                      // end of chain in anchors
        /* returned */
        CSSM_BOOL                               &verifiedToRoot,                        // end of chain self-verifies
        CSSM_BOOL                               &verifiedToAnchor,                      // end of chain in anchors
@@ -1473,52 +1473,52 @@ CSSM_RETURN TPCertGroup::buildCertGroup(
        bool attemptNetworkFetch = false;
        CSSM_BOOL firstSubjectIsInGroup = subjectIsInGroup;
        TPCertInfo *endCert;
        bool attemptNetworkFetch = false;
        CSSM_BOOL firstSubjectIsInGroup = subjectIsInGroup;
        TPCertInfo *endCert;
-       
+
        tpVfyDebug("buildCertGroup top");
        tpVfyDebug("buildCertGroup top");
-       
-       /* possible expired root which we'll only use if we can't find 
+
+       /* possible expired root which we'll only use if we can't find
         * a better one */
        TPCertInfo *expiredRoot = NULL;
         * a better one */
        TPCertInfo *expiredRoot = NULL;
-       
+
        /* and the general case of an expired or not yet valid cert */
        TPCertInfo *expiredIssuer = NULL;
        /* and the general case of an expired or not yet valid cert */
        TPCertInfo *expiredIssuer = NULL;
-       
+
        verifiedToRoot = CSSM_FALSE;
        verifiedToAnchor = CSSM_FALSE;
        verifiedViaTrustSettings = CSSM_FALSE;
        verifiedToRoot = CSSM_FALSE;
        verifiedToAnchor = CSSM_FALSE;
        verifiedViaTrustSettings = CSSM_FALSE;
-       
+
        /*** main loop to seach inCertGroup and dbList ***
         *
        /*** main loop to seach inCertGroup and dbList ***
         *
-        * Exit loop on: 
+        * Exit loop on:
         *   -- find a root cert in the chain (self-signed)
         *   -- find a non-root cert which is also in the anchors list
         *   -- find a cert which is trusted per Trust Settings (if enabled)
         *   -- memory error
         *   -- find a root cert in the chain (self-signed)
         *   -- find a non-root cert which is also in the anchors list
         *   -- find a cert which is trusted per Trust Settings (if enabled)
         *   -- memory error
-        *   -- or no more certs to add to chain. 
+        *   -- or no more certs to add to chain.
         */
        for(;;) {
         */
        for(;;) {
-               /* 
-                * Top of loop: thisSubject is the item we're trying to verify. 
+               /*
+                * Top of loop: thisSubject is the item we're trying to verify.
                 */
                 */
-                
+
                /* is thisSubject a root cert or listed in user trust list?  */
                if(subjectIsInGroup) {
                        TPCertInfo *subjCert = lastCert();
                        assert(subjCert != NULL);
                /* is thisSubject a root cert or listed in user trust list?  */
                if(subjectIsInGroup) {
                        TPCertInfo *subjCert = lastCert();
                        assert(subjCert != NULL);
-                       
+
                        if(actionFlags & CSSM_TP_ACTION_TRUST_SETTINGS) {
                                assert(policyOid != NULL);
                        if(actionFlags & CSSM_TP_ACTION_TRUST_SETTINGS) {
                                assert(policyOid != NULL);
-                               
-                               /* 
+
+                               /*
                                 * Figure out key usage. If this is a leaf cert, the caller - actually
                                 * the per-policy code - inferred the usage. Else it could be for
                                 * Figure out key usage. If this is a leaf cert, the caller - actually
                                 * the per-policy code - inferred the usage. Else it could be for
-                                * verifying a cert or a CRL. 
+                                * verifying a cert or a CRL.
                                 *
                                 *
-                                * We want to avoid multiple calls to the effective portion of 
-                                * evaluateTrustSettings(), but a CA cert could be usable for only 
-                                * signing certs and not CRLs. Thus we're evaluating a CA cert, 
-                                * try to evaluate for signing certs *and* CRLs in case we come 
-                                * this way again later when performing CRL verification. If that 
+                                * We want to avoid multiple calls to the effective portion of
+                                * evaluateTrustSettings(), but a CA cert could be usable for only
+                                * signing certs and not CRLs. Thus we're evaluating a CA cert,
+                                * try to evaluate for signing certs *and* CRLs in case we come
+                                * this way again later when performing CRL verification. If that
                                 * fails, then retry with just cert signing.
                                 */
                                SecTrustSettingsKeyUsage localKeyUse;
                                 * fails, then retry with just cert signing.
                                 */
                                SecTrustSettingsKeyUsage localKeyUse;
@@ -1531,7 +1531,7 @@ CSSM_RETURN TPCertGroup::buildCertGroup(
                                else {
                                        localKeyUse = kSecTrustSettingsKeyUseSignCert | kSecTrustSettingsKeyUseSignRevocation;
                                        /* and if necessary */
                                else {
                                        localKeyUse = kSecTrustSettingsKeyUseSignCert | kSecTrustSettingsKeyUseSignRevocation;
                                        /* and if necessary */
-                                       doRetry = true; 
+                                       doRetry = true;
                                }
                                /* this lets us avoid searching for the same thing twice when there
                                 * is in fact no entry for it */
                                }
                                /* this lets us avoid searching for the same thing twice when there
                                 * is in fact no entry for it */
@@ -1547,14 +1547,14 @@ CSSM_RETURN TPCertGroup::buildCertGroup(
                                if(!trustSettingsFound && foundEntry && doRetry) {
                                        tpTrustSettingsDbg("buildCertGroup: retrying evaluateTrustSettings with Cert only");
                                        ortn = subjCert->evaluateTrustSettings(*policyOid,
                                if(!trustSettingsFound && foundEntry && doRetry) {
                                        tpTrustSettingsDbg("buildCertGroup: retrying evaluateTrustSettings with Cert only");
                                        ortn = subjCert->evaluateTrustSettings(*policyOid,
-                                               policyStr, policyStrLen, kSecTrustSettingsKeyUseSignCert, 
+                                               policyStr, policyStrLen, kSecTrustSettingsKeyUseSignCert,
                                                &trustSettingsFound, &foundEntry);
                                        if(ortn) {
                                                crtn = ortn;
                                                goto final_out;
                                        }
                                }
                                                &trustSettingsFound, &foundEntry);
                                        if(ortn) {
                                                crtn = ortn;
                                                goto final_out;
                                        }
                                }
-                               if(trustSettingsFound) {                                        
+                               if(trustSettingsFound) {
                                        switch(subjCert->trustSettingsResult()) {
                                                case kSecTrustSettingsResultInvalid:
                                                        /* should not happen... */
                                        switch(subjCert->trustSettingsResult()) {
                                                case kSecTrustSettingsResultInvalid:
                                                        /* should not happen... */
@@ -1571,14 +1571,14 @@ CSSM_RETURN TPCertGroup::buildCertGroup(
                                                        crtn = CSSMERR_APPLETP_TRUST_SETTING_DENY;
                                                        break;
                                                case kSecTrustSettingsResultUnspecified:
                                                        crtn = CSSMERR_APPLETP_TRUST_SETTING_DENY;
                                                        break;
                                                case kSecTrustSettingsResultUnspecified:
-                                                       /* special case here: this means "keep going, we don't trust or 
+                                                       /* special case here: this means "keep going, we don't trust or
                                                         * distrust this cert". Typically used to express allowed errors
                                                         * distrust this cert". Typically used to express allowed errors
-                                                        * only. 
+                                                        * only.
                                                         */
                                                        tpTrustSettingsDbg("TrustResultUnspecified found");
                                                        goto post_trust_setting;
                                                default:
                                                         */
                                                        tpTrustSettingsDbg("TrustResultUnspecified found");
                                                        goto post_trust_setting;
                                                default:
-                                                       tpTrustSettingsDbg("Unknown TrustResult (%d)", 
+                                                       tpTrustSettingsDbg("Unknown TrustResult (%d)",
                                                                (int)subjCert->trustSettingsResult());
                                                        crtn = CSSMERR_TP_INTERNAL_ERROR;
                                                        break;
                                                                (int)subjCert->trustSettingsResult());
                                                        crtn = CSSMERR_TP_INTERNAL_ERROR;
                                                        break;
@@ -1593,14 +1593,14 @@ post_trust_setting:
                        if(subjCert->isSelfSigned()) {
                                /* We're at the end of the chain. */
                                verifiedToRoot = CSSM_TRUE;
                        if(subjCert->isSelfSigned()) {
                                /* We're at the end of the chain. */
                                verifiedToRoot = CSSM_TRUE;
-                               
+
                                /*
                                 * Special case if this root is temporally invalid (and it's not
                                 * the leaf): remove it from the outgoing cert group, save it,
                                /*
                                 * Special case if this root is temporally invalid (and it's not
                                 * the leaf): remove it from the outgoing cert group, save it,
-                                * and proceed, looking another (good) root in anchors. 
+                                * and proceed, looking another (good) root in anchors.
                                 * There's no way we'll find another good one in this loop.
                                 */
                                 * There's no way we'll find another good one in this loop.
                                 */
-                               if((subjCert->isExpired() || subjCert->isNotValidYet()) && 
+                               if((subjCert->isExpired() || subjCert->isNotValidYet()) &&
                                   (!firstSubjectIsInGroup || (mNumCerts > 1))) {
                                        tpDebug("buildCertGroup: EXPIRED ROOT %p, looking for good one", subjCert);
                                        expiredRoot = subjCert;
                                   (!firstSubjectIsInGroup || (mNumCerts > 1))) {
                                        tpDebug("buildCertGroup: EXPIRED ROOT %p, looking for good one", subjCert);
                                        expiredRoot = subjCert;
@@ -1618,7 +1618,7 @@ post_trust_setting:
                                }
                                break;          /* out of main loop */
                        }       /* root */
                                }
                                break;          /* out of main loop */
                        }       /* root */
-                       
+
                        /*
                         * If this non-root cert is in the provided anchors list,
                         * we can stop building the chain at this point.
                        /*
                         * If this non-root cert is in the provided anchors list,
                         * we can stop building the chain at this point.
@@ -1666,39 +1666,39 @@ post_trust_setting:
                                        break; /* out of main loop */
                                }
                        } /* non-root */
                                        break; /* out of main loop */
                                }
                        } /* non-root */
-                       
+
                }       /* subjectIsInGroup */
                }       /* subjectIsInGroup */
-               
-               /* 
+
+               /*
                 * Search unused incoming certs to find an issuer.
                 * Both cert groups are optional.
                 * We'll add issuer to outCertGroup below.
                 * If we find  a cert that's expired or not yet valid, we hold on to it
                 * Search unused incoming certs to find an issuer.
                 * Both cert groups are optional.
                 * We'll add issuer to outCertGroup below.
                 * If we find  a cert that's expired or not yet valid, we hold on to it
-                * and look for a better one. If we don't find it here we drop back to the 
-                * expired one at the end of the loop. If that expired cert is a root 
-                * cert, we'll use the expiredRoot mechanism (see above) to roll back and 
-                * see if we can find a good root in the incoming anchors. 
+                * and look for a better one. If we don't find it here we drop back to the
+                * expired one at the end of the loop. If that expired cert is a root
+                * cert, we'll use the expiredRoot mechanism (see above) to roll back and
+                * see if we can find a good root in the incoming anchors.
                 */
                if(inCertGroup != NULL) {
                        bool partial = false;
                 */
                if(inCertGroup != NULL) {
                        bool partial = false;
-                       issuerCert = inCertGroup->findIssuerForCertOrCrl(*thisSubject, 
+                       issuerCert = inCertGroup->findIssuerForCertOrCrl(*thisSubject,
                                partial);
                        if(issuerCert) {
                                issuerCert->isFromInputCerts(true);
                                if(partial) {
                                        /* deal with this later */
                                        foundPartialIssuer = true;
                                partial);
                        if(issuerCert) {
                                issuerCert->isFromInputCerts(true);
                                if(partial) {
                                        /* deal with this later */
                                        foundPartialIssuer = true;
-                                       tpDebug("buildCertGroup: PARTIAL Cert FOUND in inCertGroup");           
+                                       tpDebug("buildCertGroup: PARTIAL Cert FOUND in inCertGroup");
                                }
                                else {
                                }
                                else {
-                                       tpDebug("buildCertGroup: Cert FOUND in inCertGroup");           
+                                       tpDebug("buildCertGroup: Cert FOUND in inCertGroup");
                                }
                        }
                }
                if(issuerCert != NULL) {
                        if(issuerCert->isExpired() || issuerCert->isNotValidYet()) {
                                if(expiredIssuer == NULL) {
                                }
                        }
                }
                if(issuerCert != NULL) {
                        if(issuerCert->isExpired() || issuerCert->isNotValidYet()) {
                                if(expiredIssuer == NULL) {
-                                       tpDebug("buildCertGroup: saving expired cert %p (1)", issuerCert);              
+                                       tpDebug("buildCertGroup: saving expired cert %p (1)", issuerCert);
                                        expiredIssuer = issuerCert;
                                        issuerCert = NULL;
                                }
                                        expiredIssuer = issuerCert;
                                        issuerCert = NULL;
                                }
@@ -1714,7 +1714,7 @@ post_trust_setting:
                                expiredIssuer = NULL;
                        }
                }
                                expiredIssuer = NULL;
                        }
                }
-               
+
                if((issuerCert == NULL) && (gatheredCerts != NULL)) {
                        bool partial = false;
                        issuerCert = gatheredCerts->findIssuerForCertOrCrl(*thisSubject,
                if((issuerCert == NULL) && (gatheredCerts != NULL)) {
                        bool partial = false;
                        issuerCert = gatheredCerts->findIssuerForCertOrCrl(*thisSubject,
@@ -1723,18 +1723,18 @@ post_trust_setting:
                                if(partial) {
                                        /* deal with this later */
                                        foundPartialIssuer = true;
                                if(partial) {
                                        /* deal with this later */
                                        foundPartialIssuer = true;
-                                       tpDebug("buildCertGroup: PARTIAL Cert FOUND in gatheredCerts");         
+                                       tpDebug("buildCertGroup: PARTIAL Cert FOUND in gatheredCerts");
                                }
                                else {
                                        tpDebug("buildCertGroup: Cert FOUND in gatheredCerts");
                                }
                        }
                }
                                }
                                else {
                                        tpDebug("buildCertGroup: Cert FOUND in gatheredCerts");
                                }
                        }
                }
-               
+
                if(issuerCert != NULL) {
                        if(issuerCert->isExpired() || issuerCert->isNotValidYet()) {
                                if(expiredIssuer == NULL) {
                if(issuerCert != NULL) {
                        if(issuerCert->isExpired() || issuerCert->isNotValidYet()) {
                                if(expiredIssuer == NULL) {
-                                       tpDebug("buildCertGroup: saving expired cert %p (2)", issuerCert);              
+                                       tpDebug("buildCertGroup: saving expired cert %p (2)", issuerCert);
                                        expiredIssuer = issuerCert;
                                        issuerCert = NULL;
                                }
                                        expiredIssuer = issuerCert;
                                        issuerCert = NULL;
                                }
@@ -1776,7 +1776,7 @@ post_trust_setting:
 
                                /*
                                 * Handle Radar 4566041, endless loop of cross-signed certs.
 
                                /*
                                 * Handle Radar 4566041, endless loop of cross-signed certs.
-                                * This can only happen when fetching certs from a DLDB or 
+                                * This can only happen when fetching certs from a DLDB or
                                 * from the net; we prevent that from happening when the certs
                                 * are in inCertGroup or gatheredCerts by keeping track of those
                                 * certs' mUsed state.
                                 * from the net; we prevent that from happening when the certs
                                 * are in inCertGroup or gatheredCerts by keeping track of those
                                 * certs' mUsed state.
@@ -1792,7 +1792,7 @@ post_trust_setting:
                                        if(partial) {
                                                /* deal with this later */
                                                foundPartialIssuer = true;
                                        if(partial) {
                                                /* deal with this later */
                                                foundPartialIssuer = true;
-                                               tpDebug("buildCertGroup: PARTIAL Cert FOUND in dbList");                
+                                               tpDebug("buildCertGroup: PARTIAL Cert FOUND in dbList");
                                        }
                                        else {
                                                tpDebug("buildCertGroup: Cert FOUND in dbList");
                                        }
                                        else {
                                                tpDebug("buildCertGroup: Cert FOUND in dbList");
@@ -1800,33 +1800,33 @@ post_trust_setting:
                                }
                        }
                }       /*  searching DLDB list */
                                }
                        }
                }       /*  searching DLDB list */
-               
+
                /*
                 * Note: we don't handle an expired cert returned from tpDbFindIssuerCert()
                /*
                 * Note: we don't handle an expired cert returned from tpDbFindIssuerCert()
-                * in any special way like we do with findIssuerForCertOrCrl(). 
+                * in any special way like we do with findIssuerForCertOrCrl().
                 * tpDbFindIssuerCert() does its best to give us a temporally valid cert; if
                 * it returns an expired cert (or, if findIssuerForCertOrCrl() gave us an
                 * tpDbFindIssuerCert() does its best to give us a temporally valid cert; if
                 * it returns an expired cert (or, if findIssuerForCertOrCrl() gave us an
-                * expired cert and tpDbFindIssuerCert() could not do any better), that's all 
-                * we have to work with at this point. We'll go back to the top of the loop 
-                * and apply trust settings if enabled; if an expired cert is trusted per 
-                * Trust Settings, we're done. (Note that anchors are fetched from a DLDB 
-                * when Trust Settings are enabled, so even if two roots with the same key 
-                * and subject name are in DLDBs, and one of them is expired, we'll have the 
-                * good one at this time because of tpDbFindIssuerCert()'s ability to find 
-                * the best cert.) 
-                * 
-                * If Trust Settings are not enabled, and we have an expired root at this 
-                * point, the expiredRoot mechanism is used to roll back and search for 
-                * an anchor that verifies the last good cert. 
+                * expired cert and tpDbFindIssuerCert() could not do any better), that's all
+                * we have to work with at this point. We'll go back to the top of the loop
+                * and apply trust settings if enabled; if an expired cert is trusted per
+                * Trust Settings, we're done. (Note that anchors are fetched from a DLDB
+                * when Trust Settings are enabled, so even if two roots with the same key
+                * and subject name are in DLDBs, and one of them is expired, we'll have the
+                * good one at this time because of tpDbFindIssuerCert()'s ability to find
+                * the best cert.)
+                *
+                * If Trust Settings are not enabled, and we have an expired root at this
+                * point, the expiredRoot mechanism is used to roll back and search for
+                * an anchor that verifies the last good cert.
                 */
                 */
-                
+
                if((issuerCert == NULL) &&                      /* tpDbFindIssuerCert() hasn't found one and
                                                                                         * we don't have a good one */
                   (expiredIssuer != NULL)) {           /* but we have an expired candidate */
                if((issuerCert == NULL) &&                      /* tpDbFindIssuerCert() hasn't found one and
                                                                                         * we don't have a good one */
                   (expiredIssuer != NULL)) {           /* but we have an expired candidate */
-                       /* 
-                        * OK, we'll take the expired issuer. 
+                       /*
+                        * OK, we'll take the expired issuer.
                         * Note we don't have to free expiredIssuer if we found a good one since
                         * Note we don't have to free expiredIssuer if we found a good one since
-                        * expiredIssuer can only come from inCertGroup or gatheredCerts (not from 
+                        * expiredIssuer can only come from inCertGroup or gatheredCerts (not from
                         * dbList).
                         */
                        tpDebug("buildCertGroup: USING expired cert %p", expiredIssuer);
                         * dbList).
                         */
                        tpDebug("buildCertGroup: USING expired cert %p", expiredIssuer);
@@ -1837,7 +1837,7 @@ post_trust_setting:
                        /* end of search, broken chain */
                        break;
                }
                        /* 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 thisSubject for
                /*
                 * One way or the other, we've found a cert which verifies subjectCert.
                 * Add the issuer to outCertGroup and make it the new thisSubject for
@@ -1848,21 +1848,21 @@ post_trust_setting:
                subjectIsInGroup = CSSM_TRUE;
                issuerCert = NULL;
        }       /* main loop */
                subjectIsInGroup = CSSM_TRUE;
                issuerCert = NULL;
        }       /* main loop */
-       
-       /* 
-        * This can be NULL if we're evaluating a CRL (and we haven't 
+
+       /*
+        * This can be NULL if we're evaluating a CRL (and we haven't
         * gotten very far).
         */
        endCert = lastCert();
 
         * gotten very far).
         */
        endCert = lastCert();
 
-       /* 
+       /*
         * This, on the other hand, is always valid. It could be a CRL.
         */
        assert(thisSubject != NULL);
         * This, on the other hand, is always valid. It could be a CRL.
         */
        assert(thisSubject != NULL);
-       
+
        if( (actionFlags & CSSM_TP_ACTION_IMPLICIT_ANCHORS) &&
                ( (endCert && endCert->isSelfSigned()) || expiredRoot) ) {
        if( (actionFlags & CSSM_TP_ACTION_IMPLICIT_ANCHORS) &&
                ( (endCert && endCert->isSelfSigned()) || expiredRoot) ) {
-               /* 
+               /*
                 * Caller will be satisfied with this; skip further anchor processing.
                 */
                tpAnchorDebug("buildCertGroup: found IMPLICIT anchor");
                 * Caller will be satisfied with this; skip further anchor processing.
                 */
                tpAnchorDebug("buildCertGroup: found IMPLICIT anchor");
@@ -1873,21 +1873,21 @@ post_trust_setting:
                goto post_anchor;
        }
        assert(anchorCerts != NULL);
                goto post_anchor;
        }
        assert(anchorCerts != NULL);
-       
+
        /*** anchor cert handling ***/
        /*** anchor cert handling ***/
-       
-       /* 
+
+       /*
         * Case 1: If thisSubject is not a root cert, try to validate with incoming anchor certs.
         */
        expiredIssuer = NULL;
        if(!(endCert && endCert->isSelfSigned())) {
                for(certDex=0; certDex<numAnchorCerts; certDex++) {
         * Case 1: If thisSubject is not a root cert, try to validate with incoming anchor certs.
         */
        expiredIssuer = NULL;
        if(!(endCert && endCert->isSelfSigned())) {
                for(certDex=0; certDex<numAnchorCerts; certDex++) {
-                       
+
                        try {
                                anchorInfo = new TPCertInfo(clHand,
                                        cspHand,
                        try {
                                anchorInfo = new TPCertInfo(clHand,
                                        cspHand,
-                                       &anchorCerts[certDex], 
-                                       TIC_NoCopy, 
+                                       &anchorCerts[certDex],
+                                       TIC_NoCopy,
                                        verifyTime);
                        }
                        catch(...) {
                                        verifyTime);
                        }
                        catch(...) {
@@ -1895,8 +1895,8 @@ post_trust_setting:
                                anchorInfo = NULL;
                                continue;
                        }
                                anchorInfo = NULL;
                                continue;
                        }
-                       
-                       /* 
+
+                       /*
                         * We must subsequently delete anchorInfo one way or the other.
                         * If we add it to tpCertGroup, we also add it to certsToBeFreed.
                         * Otherwise we delete it.
                         * We must subsequently delete anchorInfo one way or the other.
                         * If we add it to tpCertGroup, we also add it to certsToBeFreed.
                         * Otherwise we delete it.
@@ -1910,14 +1910,14 @@ post_trust_setting:
                        }
 
                        crtn = thisSubject->verifyWithIssuer(anchorInfo);
                        }
 
                        crtn = thisSubject->verifyWithIssuer(anchorInfo);
-                       
+
                        if(crtn == CSSM_OK) {
                                if(anchorInfo->isExpired() || anchorInfo->isNotValidYet()) {
                                        if(expiredIssuer == NULL) {
                        if(crtn == CSSM_OK) {
                                if(anchorInfo->isExpired() || anchorInfo->isNotValidYet()) {
                                        if(expiredIssuer == NULL) {
-                                               /* 
-                                                * Hang on to this one; keep looking for a better one. 
+                                               /*
+                                                * Hang on to this one; keep looking for a better one.
                                                 */
                                                 */
-                                               tpDebug("buildCertGroup: saving expired anchor %p", anchorInfo);                
+                                               tpDebug("buildCertGroup: saving expired anchor %p", anchorInfo);
                                                expiredIssuer = anchorInfo;
                                                /* flag this condition for the switch below */
                                                crtn = CSSM_CERT_STATUS_EXPIRED;
                                                expiredIssuer = anchorInfo;
                                                /* flag this condition for the switch below */
                                                crtn = CSSM_CERT_STATUS_EXPIRED;
@@ -1929,8 +1929,8 @@ post_trust_setting:
                                        /* else we already have an expired candidate anchor */
                                }
                                else {
                                        /* else we already have an expired candidate anchor */
                                }
                                else {
-                                       /* 
-                                        * Done with possible expiredIssuer. We don't delete it, since we already added 
+                                       /*
+                                        * Done with possible expiredIssuer. We don't delete it, since we already added
                                         * it to certsToBeFreed, above.
                                         */
                                        if(expiredIssuer != NULL) {
                                         * it to certsToBeFreed, above.
                                         */
                                        if(expiredIssuer != NULL) {
@@ -1939,13 +1939,13 @@ post_trust_setting:
                                        }
                                }
                        }
                                        }
                                }
                        }
-                       
+
                        switch(crtn) {
                                case CSSMERR_CSP_APPLE_PUBLIC_KEY_INCOMPLETE:
                                        /*
                                         * A bit of a corner case. Found an issuer in AnchorCerts, but
                                         * we can't do a signature verify since the issuer has a partial
                        switch(crtn) {
                                case CSSMERR_CSP_APPLE_PUBLIC_KEY_INCOMPLETE:
                                        /*
                                         * A bit of a corner case. Found an issuer in AnchorCerts, but
                                         * we can't do a signature verify since the issuer has a partial
-                                        * public key. Proceed but return 
+                                        * public key. Proceed but return
                                         * CSSMERR_TP_CERTIFICATE_CANT_OPERATE.
                                         */
                                        if(anchorInfo->addStatusCode(CSSMERR_TP_CERTIFICATE_CANT_OPERATE)) {
                                         * CSSMERR_TP_CERTIFICATE_CANT_OPERATE.
                                         */
                                        if(anchorInfo->addStatusCode(CSSMERR_TP_CERTIFICATE_CANT_OPERATE)) {
@@ -1961,11 +1961,11 @@ post_trust_setting:
                                        /*  A fully successful return. */
                                        verifiedToAnchor = CSSM_TRUE;
                                        if(anchorInfo->isSelfSigned()) {
                                        /*  A fully successful return. */
                                        verifiedToAnchor = CSSM_TRUE;
                                        if(anchorInfo->isSelfSigned()) {
-                                               verifiedToRoot = CSSM_TRUE;     
+                                               verifiedToRoot = CSSM_TRUE;
                                        }
                                        }
-                                       
+
                                        /*
                                        /*
-                                        * Add this anchor cert to the output group 
+                                        * Add this anchor cert to the output group
                                         * and to certsToBeFreed.
                                         */
                                        appendCert(anchorInfo);
                                         * and to certsToBeFreed.
                                         */
                                        appendCert(anchorInfo);
@@ -1973,7 +1973,7 @@ post_trust_setting:
                                        assert(!anchorInfo->isFromInputCerts());
                                        anchorInfo->index(certDex);
                                        certsToBeFreed.appendCert(anchorInfo);
                                        assert(!anchorInfo->isFromInputCerts());
                                        anchorInfo->index(certDex);
                                        certsToBeFreed.appendCert(anchorInfo);
-                                       tpDebug("buildCertGroup: Cert FOUND by signer in AnchorList");  
+                                       tpDebug("buildCertGroup: Cert FOUND by signer in AnchorList");
                                        tpAnchorDebug("buildCertGroup: Cert FOUND by signer in AnchorList");
                                        /* one more thing: partial public key processing needed? */
                                        if(foundPartialIssuer) {
                                        tpAnchorDebug("buildCertGroup: Cert FOUND by signer in AnchorList");
                                        /* one more thing: partial public key processing needed? */
                                        if(foundPartialIssuer) {
@@ -1982,7 +1982,7 @@ post_trust_setting:
                                        else {
                                                return crtn;
                                        }
                                        else {
                                                return crtn;
                                        }
-                                       
+
                                default:
                                        /* continue to next anchor */
                                        if(crtn != CSSM_CERT_STATUS_EXPIRED) {
                                default:
                                        /* continue to next anchor */
                                        if(crtn != CSSM_CERT_STATUS_EXPIRED) {
@@ -1995,17 +1995,17 @@ post_trust_setting:
                        }
                }       /* for each anchor */
        }       /* thisSubject not a root cert */
                        }
                }       /* for each anchor */
        }       /* thisSubject not a root cert */
-       
+
        /*
         * Case 2: Check whether endCert is present in anchor certs.
         *
        /*
         * Case 2: Check whether endCert is present in anchor certs.
         *
-        * Also used to validate an expiredRoot that we pulled off the chain in 
-        * hopes of finding something better (which, if we're here, we haven't done). 
+        * Also used to validate an expiredRoot that we pulled off the chain in
+        * hopes of finding something better (which, if we're here, we haven't done).
         *
         * Note that the main loop above did the actual root self-verify test.
         */
        if(endCert || expiredRoot) {
         *
         * Note that the main loop above did the actual root self-verify test.
         */
        if(endCert || expiredRoot) {
-               
+
                TPCertInfo *theRoot;
                if(expiredRoot) {
                        /* this is NOT in our outgoing cert group (yet) */
                TPCertInfo *theRoot;
                if(expiredRoot) {
                        /* this is NOT in our outgoing cert group (yet) */
@@ -2026,7 +2026,7 @@ post_trust_setting:
                                        theRoot->index(certDex);
                                }
                                if(expiredRoot) {
                                        theRoot->index(certDex);
                                }
                                if(expiredRoot) {
-                                       /* verified to anchor but caller will see 
+                                       /* verified to anchor but caller will see
                                         * CSSMERR_TP_CERT_EXPIRED */
                                        appendCert(expiredRoot);
                                }
                                         * CSSMERR_TP_CERT_EXPIRED */
                                        appendCert(expiredRoot);
                                }
@@ -2040,7 +2040,7 @@ post_trust_setting:
                        }
                }
                tpAnchorDebug("buildCertGroup: end cert in input, NOT anchors");
                        }
                }
                tpAnchorDebug("buildCertGroup: end cert in input, NOT anchors");
-               
+
                if(!expiredRoot && endCert->isSelfSigned()) {
                        /* verified to a root cert which is not an anchor */
                        /* Generally maps to CSSMERR_TP_INVALID_ANCHOR_CERT by caller */
                if(!expiredRoot && endCert->isSelfSigned()) {
                        /* verified to a root cert which is not an anchor */
                        /* Generally maps to CSSMERR_TP_INVALID_ANCHOR_CERT by caller */
@@ -2063,7 +2063,7 @@ post_trust_setting:
                appendCert(expiredIssuer);
                verifiedToAnchor = CSSM_TRUE;
                if(expiredIssuer->isSelfSigned()) {
                appendCert(expiredIssuer);
                verifiedToAnchor = CSSM_TRUE;
                if(expiredIssuer->isSelfSigned()) {
-                       verifiedToRoot = CSSM_TRUE;     
+                       verifiedToRoot = CSSM_TRUE;
                }
                /* no matter what, we don't want this one */
                expiredRoot = NULL;
                }
                /* no matter what, we don't want this one */
                expiredRoot = NULL;
@@ -2071,7 +2071,7 @@ post_trust_setting:
 post_anchor:
        if(expiredRoot) {
                /*
 post_anchor:
        if(expiredRoot) {
                /*
-                * One remaining special case: expiredRoot found in input certs, but 
+                * One remaining special case: expiredRoot found in input certs, but
                 * no luck resolving the problem with the anchors. Go ahead and (re-)append
                 * the expired root and return.
                 */
                 * no luck resolving the problem with the anchors. Go ahead and (re-)append
                 * the expired root and return.
                 */
@@ -2098,11 +2098,11 @@ post_anchor:
                 */
                attemptNetworkFetch = false;
        }
                 */
                attemptNetworkFetch = false;
        }
-       
-       /* 
+
+       /*
         * If we haven't verified to a root, and net fetch of certs is enabled,
         * try to get the issuer of the last cert in the chain from the net.
         * If we haven't verified to a root, and net fetch of certs is enabled,
         * try to get the issuer of the last cert in the chain from the net.
-        * If that succeeds, then call ourself recursively to perform the 
+        * If that succeeds, then call ourself recursively to perform the
         * whole search again (including comparing to or verifying against
         * anchor certs).
         */
         * whole search again (including comparing to or verifying against
         * anchor certs).
         */
@@ -2138,12 +2138,12 @@ post_anchor:
                                        crtn = CSSMERR_TP_CERTGROUP_INCOMPLETE;
                                        break;
                                }
                                        crtn = CSSMERR_TP_CERTGROUP_INCOMPLETE;
                                        break;
                                }
-                                       
+
                                /* add this fetched cert to constructed group */
                                appendCert(issuer);
                                issuer->isFromNet(true);
                                certsToBeFreed.appendCert(issuer);
                                /* add this fetched cert to constructed group */
                                appendCert(issuer);
                                issuer->isFromNet(true);
                                certsToBeFreed.appendCert(issuer);
-                               
+
                                /* and go again */
                                cr = buildCertGroup(*issuer,
                                        inCertGroup,
                                /* and go again */
                                cr = buildCertGroup(*issuer,
                                        inCertGroup,
@@ -2155,7 +2155,7 @@ post_anchor:
                                        anchorCerts,
                                        certsToBeFreed,
                                        gatheredCerts,
                                        anchorCerts,
                                        certsToBeFreed,
                                        gatheredCerts,
-                                       CSSM_TRUE,              // subjectIsInGroup     
+                                       CSSM_TRUE,              // subjectIsInGroup
                                        actionFlags,
                                        policyOid,
                                        policyStr,
                                        actionFlags,
                                        policyOid,
                                        policyStr,
@@ -2168,7 +2168,7 @@ post_anchor:
                                if(cr) {
                                        return cr;
                                }
                                if(cr) {
                                        return cr;
                                }
-                               
+
                                /* one more thing: partial public key processing needed? */
                                if(foundPartialIssuer) {
                                        return verifyWithPartialKeys(subjectItem);
                                /* one more thing: partial public key processing needed? */
                                if(foundPartialIssuer) {
                                        return verifyWithPartialKeys(subjectItem);
@@ -2192,7 +2192,7 @@ final_out:
        }
 }
 
        }
 }
 
-/* 
+/*
  * Called from buildCertGroup as final processing of a constructed
  * group when CSSMERR_CSP_APPLE_PUBLIC_KEY_INCOMPLETE has been
  * detected. Perform partial public key processing.
  * Called from buildCertGroup as final processing of a constructed
  * group when CSSMERR_CSP_APPLE_PUBLIC_KEY_INCOMPLETE has been
  * detected. Perform partial public key processing.
@@ -2201,9 +2201,9 @@ final_out:
  * issuers have partial public keys.
  *
  * Returns:
  * issuers have partial public keys.
  *
  * Returns:
- *      CSSMERR_TP_CERTIFICATE_CANT_OPERATE in the case of an issuer cert 
+ *      CSSMERR_TP_CERTIFICATE_CANT_OPERATE in the case of an issuer cert
  *             with a partial public key which can't be completed.
  *             with a partial public key which can't be completed.
- *      CSSMERR_TP_INVALID_CERT_AUTHORITY if sig verify failed with 
+ *      CSSMERR_TP_INVALID_CERT_AUTHORITY if sig verify failed with
  *             a (supposedly) completed partial key
  */
 CSSM_RETURN TPCertGroup::verifyWithPartialKeys(
  *             a (supposedly) completed partial key
  */
 CSSM_RETURN TPCertGroup::verifyWithPartialKeys(
@@ -2211,11 +2211,11 @@ CSSM_RETURN TPCertGroup::verifyWithPartialKeys(
 {
        TPCertInfo *lastFullKeyCert = NULL;
        tpDebug("verifyWithPartialKeys top");
 {
        TPCertInfo *lastFullKeyCert = NULL;
        tpDebug("verifyWithPartialKeys top");
-       
+
        /* start from the end - it's easier */
        for(int dex=mNumCerts-1; dex >= 0; dex--) {
                TPCertInfo *thisCert = mCertInfo[dex];
        /* start from the end - it's easier */
        for(int dex=mNumCerts-1; dex >= 0; dex--) {
                TPCertInfo *thisCert = mCertInfo[dex];
-               
+
                /*
                 * If this is the start of the cert chain, and it's not being
                 * used to verify subjectItem, then we're done.
                /*
                 * If this is the start of the cert chain, and it's not being
                 * used to verify subjectItem, then we're done.
@@ -2227,7 +2227,7 @@ CSSM_RETURN TPCertGroup::verifyWithPartialKeys(
                        }
                }
                if(!thisCert->hasPartialKey()) {
                        }
                }
                if(!thisCert->hasPartialKey()) {
-                       /* 
+                       /*
                         * Good to know. Record this and move on.
                         */
                        lastFullKeyCert = thisCert;
                         * Good to know. Record this and move on.
                         */
                        lastFullKeyCert = thisCert;
@@ -2246,7 +2246,7 @@ CSSM_RETURN TPCertGroup::verifyWithPartialKeys(
                                break;
                        }
                }
                                break;
                        }
                }
-               
+
                /* do the verify - of next cert in chain or of subjectItem */
                const TPClItemInfo *subject;
                if(dex == 0) {
                /* do the verify - of next cert in chain or of subjectItem */
                const TPClItemInfo *subject;
                if(dex == 0) {
@@ -2257,7 +2257,7 @@ CSSM_RETURN TPCertGroup::verifyWithPartialKeys(
                        subject = mCertInfo[dex - 1];
                        tpDebug("...verifying with partial cert %d", dex);
                }
                        subject = mCertInfo[dex - 1];
                        tpDebug("...verifying with partial cert %d", dex);
                }
-               CSSM_RETURN crtn = subject->verifyWithIssuer(thisCert, 
+               CSSM_RETURN crtn = subject->verifyWithIssuer(thisCert,
                        lastFullKeyCert);
                if(crtn) {
                        tpDebug("CERT VERIFY ERROR with partial cert at index %d", dex);
                        lastFullKeyCert);
                if(crtn) {
                        tpDebug("CERT VERIFY ERROR with partial cert at index %d", dex);
@@ -2269,15 +2269,15 @@ CSSM_RETURN TPCertGroup::verifyWithPartialKeys(
                        }
                }
        }
                        }
                }
        }
-       
+
        /* we just verified subjectItem - right?  */
        assert((void *)mCertInfo[0] != (void *)&subjectItem);
        tpDebug("verifyWithPartialKeys: success at subjectItem");
        return CSSM_OK;
 }
 
        /* we just verified subjectItem - right?  */
        assert((void *)mCertInfo[0] != (void *)&subjectItem);
        tpDebug("verifyWithPartialKeys: success at subjectItem");
        return CSSM_OK;
 }
 
-/* 
- * Free records obtained from DBs. Called when these records are not going to 
+/*
+ * Free records obtained from DBs. Called when these records are not going to
  * be passed to caller of CertGroupConstruct or CertGroupVerify.
  */
 void TPCertGroup::freeDbRecords()
  * be passed to caller of CertGroupConstruct or CertGroupVerify.
  */
 void TPCertGroup::freeDbRecords()
index 4efa50c1a29f7598f4dbceb3cb87a2ad25878fe9..eef40e68a71bb4039e10e3880ecae58a93359416 100644 (file)
@@ -535,14 +535,14 @@ CSSM_RETURN TPCrlInfo::isCertRevoked(
                         */
                        CSSM_X509_TIME_PTR xTime = &entry->revocationDate;
                        int rtn;
                         */
                        CSSM_X509_TIME_PTR xTime = &entry->revocationDate;
                        int rtn;
-                       rtn = timeStringToCfDate((char *)xTime->time.Data, xTime->time.Length, 
+                       rtn = timeStringToCfDate((char *)xTime->time.Data, (unsigned)xTime->time.Length,
                                &cfRevokedTime);
                        if(rtn) {
                                tpErrorLog("fetchNotBeforeAfter: malformed revocationDate\n");
                        }
                        else {
                                if(verifyTime != NULL) {
                                &cfRevokedTime);
                        if(rtn) {
                                tpErrorLog("fetchNotBeforeAfter: malformed revocationDate\n");
                        }
                        else {
                                if(verifyTime != NULL) {
-                                       rtn = timeStringToCfDate((char *)verifyTime, strlen(verifyTime), 
+                                       rtn = timeStringToCfDate((char *)verifyTime, (unsigned)strlen(verifyTime),
                                                                                         &cfVerifyTime);
                                }
                                else {
                                                                                         &cfVerifyTime);
                                }
                                else {
index 431769554306d3e87b28a6eb094042e69eec2ae8..5c2ba89be59aaba15da719df4dabb86b573afe45 100644 (file)
@@ -323,7 +323,7 @@ static CSSM_DB_UNIQUE_RECORD_PTR tpCrlLookup(
        /* now before/after. Cook up an appropriate time string. */
        if(verifyTime != NULL) {
                /* Caller spec'd tolerate any format */
        /* now before/after. Cook up an appropriate time string. */
        if(verifyTime != NULL) {
                /* Caller spec'd tolerate any format */
-               int rtn = tpTimeToCssmTimestring(verifyTime, strlen(verifyTime), timeStr);
+               int rtn = tpTimeToCssmTimestring(verifyTime, (unsigned)strlen(verifyTime), timeStr);
                if(rtn) {
                        tpErrorLog("tpCrlLookup: Invalid VerifyTime string\n");
                        return NULL;
                if(rtn) {
                        tpErrorLog("tpCrlLookup: Invalid VerifyTime string\n");
                        return NULL;
index 377be2763c4a2c8a460e6ff109df191cbd669c84..e6895229fe2ac327cbb36dd5787c9f4d6bdfd7d8 100644 (file)
@@ -46,7 +46,7 @@ static CSSM_RETURN tpDecodeCert(
        CSSM_DATA               &rtnBlob)               // will be reallocated if needed
 {
        const unsigned char *inbuf = (const unsigned char *)rtnBlob.Data;
        CSSM_DATA               &rtnBlob)               // will be reallocated if needed
 {
        const unsigned char *inbuf = (const unsigned char *)rtnBlob.Data;
-       unsigned inlen = rtnBlob.Length;
+       unsigned inlen = (unsigned)rtnBlob.Length;
        unsigned char *outbuf = NULL;
        unsigned outlen = 0;
        CSSM_RETURN ortn = cuConvertPem(inbuf, inlen, &outbuf, &outlen);
        unsigned char *outbuf = NULL;
        unsigned outlen = 0;
        CSSM_RETURN ortn = cuConvertPem(inbuf, inlen, &outbuf, &outlen);
index 06b00d34f5e0652d6d67c1d56d9c8adb26158573..a86c310fbf7bd719195ab933b88e7d39d4411e88 100644 (file)
@@ -1,12 +1,12 @@
 /*
  * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
 /*
  * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- * 
+ *
  * The contents of this file constitute Original Code as defined in and are
  * subject to the Apple Public Source License Version 1.2 (the 'License').
  * You may not use this file except in 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 contents of this file constitute Original Code as defined in and are
  * subject to the Apple Public Source License Version 1.2 (the 'License').
  * You may not use this file except in compliance with the License. Please obtain
  * a copy of the License at http://www.apple.com/publicsource and read it before
  * using this file.
- * 
+ *
  * This Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
  * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
  * This Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
  * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
@@ -19,7 +19,7 @@
 /*
        certGroupUtils.cpp
 
 /*
        certGroupUtils.cpp
 
-       Created 10/9/2000 by Doug Mitchell. 
+       Created 10/9/2000 by Doug Mitchell.
 */
 
 #include <Security/cssmtype.h>
 */
 
 #include <Security/cssmtype.h>
@@ -31,7 +31,7 @@
 #include <Security/SecAsn1Coder.h>
 #include <Security/keyTemplates.h>
 
 #include <Security/SecAsn1Coder.h>
 #include <Security/keyTemplates.h>
 
-#include "certGroupUtils.h" 
+#include "certGroupUtils.h"
 #include "tpdebugging.h"
 #include "tpTime.h"
 
 #include "tpdebugging.h"
 #include "tpTime.h"
 
@@ -39,7 +39,7 @@
 
 
 /*
 
 
 /*
- * Copy one CSSM_DATA to another, mallocing destination. 
+ * Copy one CSSM_DATA to another, mallocing destination.
  */
 void tpCopyCssmData(
        Allocator               &alloc,
  */
 void tpCopyCssmData(
        Allocator               &alloc,
@@ -92,8 +92,8 @@ void tpFreeCssmData(
 CSSM_BOOL tpCompareCssmData(
        const CSSM_DATA *data1,
        const CSSM_DATA *data2)
 CSSM_BOOL tpCompareCssmData(
        const CSSM_DATA *data1,
        const CSSM_DATA *data2)
-{      
-       if((data1 == NULL) || (data1->Data == NULL) || 
+{
+       if((data1 == NULL) || (data1->Data == NULL) ||
           (data2 == NULL) || (data2->Data == NULL) ||
           (data1->Length != data2->Length)) {
                return CSSM_FALSE;
           (data2 == NULL) || (data2->Data == NULL) ||
           (data1->Length != data2->Length)) {
                return CSSM_FALSE;
@@ -129,14 +129,14 @@ void tpFreePluginMemory(
 /*
  * Obtain the public key blob from a cert.
  */
 /*
  * Obtain the public key blob from a cert.
  */
-CSSM_DATA_PTR tp_CertGetPublicKey( 
+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;
     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) {
        *valueToFree = NULL;
        crtn = cert->fetchField(&CSSMOID_X509V1SubjectPublicKeyCStruct, &val);
        if(crtn) {
@@ -158,13 +158,13 @@ void tp_CertFreePublicKey(
 /*
  * Obtain signature algorithm info from a cert.
  */
 /*
  * Obtain signature algorithm info from a cert.
  */
-CSSM_X509_ALGORITHM_IDENTIFIER_PTR tp_CertGetAlgId( 
+CSSM_X509_ALGORITHM_IDENTIFIER_PTR tp_CertGetAlgId(
     TPCertInfo         *cert,
        CSSM_DATA_PTR   *valueToFree)                   // used in tp_CertFreeAlgId
 {
        CSSM_RETURN crtn;
        CSSM_DATA_PTR val;
     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) {
        *valueToFree = NULL;
        crtn = cert->fetchField(&CSSMOID_X509V1SignatureAlgorithm, &val);
        if(crtn) {
@@ -183,7 +183,7 @@ void tp_CertFreeAlgId(
 }
 
 /*
 }
 
 /*
- * Determine if two certs - passed in encoded form - are equivalent. 
+ * Determine if two certs - passed in encoded form - are equivalent.
  */
 CSSM_BOOL tp_CompareCerts(
        const CSSM_DATA                 *cert1,
  */
 CSSM_BOOL tp_CompareCerts(
        const CSSM_DATA                 *cert1,
@@ -209,7 +209,7 @@ void tpToLower(
  * Normalize an RFC822 addr-spec. This consists of converting
  * all characters following the '@' character to lower case.
  * A true normalizeAll results in lower-casing all characters
  * Normalize an RFC822 addr-spec. This consists of converting
  * all characters following the '@' character to lower case.
  * A true normalizeAll results in lower-casing all characters
- * (e.g. for iChat). 
+ * (e.g. for iChat).
  */
 void tpNormalizeAddrSpec(
        char            *addr,
  */
 void tpNormalizeAddrSpec(
        char            *addr,
@@ -235,15 +235,15 @@ void tpNormalizeAddrSpec(
 
 /***
  *** dnsName compare support.
 
 /***
  *** dnsName compare support.
- *** Please do not make any changes to this code without talking to 
+ *** Please do not make any changes to this code without talking to
  *** dmitch about updating (if necessary) and running (always)
  *** regression tests which specifically test this logic.
  ***/
  *** dmitch about updating (if necessary) and running (always)
  *** regression tests which specifically test this logic.
  ***/
+
 /*
  * Max length of a distinguished name component (label) we handle.
  * Various RFCs spec this out at 63 bytes; we're just allocating space
 /*
  * Max length of a distinguished name component (label) we handle.
  * Various RFCs spec this out at 63 bytes; we're just allocating space
- * for these on the stack, so why not cut some slack. 
+ * for these on the stack, so why not cut some slack.
  */
 #define MAX_DNS_COMP_LEN       128
 
  */
 #define MAX_DNS_COMP_LEN       128
 
@@ -262,7 +262,7 @@ static bool tpNextDnsComp(
        if(inBufLen == 0) {
                return false;
        }
        if(inBufLen == 0) {
                return false;
        }
-       
+
        /* skip over leading '.' */
        if(*inBuf == '.') {
                inBuf++;
        /* skip over leading '.' */
        if(*inBuf == '.') {
                inBuf++;
@@ -270,7 +270,7 @@ static bool tpNextDnsComp(
                        return false;
                }
        }
                        return false;
                }
        }
-       
+
        /* copy chars until out of data or next '.' found */
        do {
                if(*inBuf == '.') {
        /* copy chars until out of data or next '.' found */
        do {
                if(*inBuf == '.') {
@@ -313,21 +313,21 @@ static const char *tpSubStr(
                        }
                        if(!memcmp(bigstr+1, substr+1, substrLen - 1)) {
                                return bigstr;
                        }
                        if(!memcmp(bigstr+1, substr+1, substrLen - 1)) {
                                return bigstr;
-                       } 
+                       }
                }
                bigstr++;
                }
                bigstr++;
-       } 
+       }
        return NULL;
 }
 
 /*
  * Compare two DNS components, with full wildcard check. We assume
        return NULL;
 }
 
 /*
  * Compare two DNS components, with full wildcard check. We assume
- * that no '.' chars exist (per the processing performed in 
+ * that no '.' chars exist (per the processing performed in
  * tpNextDnsComp()). Returns CSSM_TRUE on match, else CSSM_FALSE.
  */
 static CSSM_BOOL tpCompareComps(
        const char      *hostComp,                      // no wildcards
  * tpNextDnsComp()). Returns CSSM_TRUE on match, else CSSM_FALSE.
  */
 static CSSM_BOOL tpCompareComps(
        const char      *hostComp,                      // no wildcards
-       uint32          hostCompLen, 
+       uint32          hostCompLen,
        const char      *certComp,                      // wildcards OK here
        uint32          certCompLen)
 {
        const char      *certComp,                      // wildcards OK here
        uint32          certCompLen)
 {
@@ -347,13 +347,13 @@ static CSSM_BOOL tpCompareComps(
                                return CSSM_FALSE;
                        }
                }
                                return CSSM_FALSE;
                        }
                }
-               
+
                if(wildCard != certComp) {
                if(wildCard != certComp) {
-                       /* 
+                       /*
                         * Require literal match of hostComp with certComp
                         * up until (but not including) the wildcard
                         */
                         * Require literal match of hostComp with certComp
                         * up until (but not including) the wildcard
                         */
-                       uint32 subStrLen = wildCard - certComp;
+                       ptrdiff_t subStrLen = wildCard - certComp;
                        if(subStrLen > hostCompLen) {
                                /* out of host name chars */
                                return CSSM_FALSE;
                        if(subStrLen > hostCompLen) {
                                /* out of host name chars */
                                return CSSM_FALSE;
@@ -369,48 +369,48 @@ static CSSM_BOOL tpCompareComps(
                        certCompLen -= subStrLen;
                        continue;
                }
                        certCompLen -= subStrLen;
                        continue;
                }
-               
+
                /*
                 * Currently looking at a wildcard.
                 *
                 * Find substring in hostComp which matches from the char after
                 * the wildcard up to whichever of these comes next:
                 *
                /*
                 * Currently looking at a wildcard.
                 *
                 * Find substring in hostComp which matches from the char after
                 * the wildcard up to whichever of these comes next:
                 *
-                *  -- end of certComp 
+                *  -- end of certComp
                 *  -- another wildcard
                 */
                 *  -- another wildcard
                 */
-               wildCard++;             
+               wildCard++;
                if(wildCard == endCertComp) {
                if(wildCard == endCertComp) {
-                       /* 
+                       /*
                         * -- Wild card at end of cert's DNS
                         * -- nothing else to match - rest of hostComp is the wildcard
                         *    match
                         * -- Wild card at end of cert's DNS
                         * -- nothing else to match - rest of hostComp is the wildcard
                         *    match
-                        * -- done, success 
+                        * -- done, success
                         */
                        return CSSM_TRUE;
                }
                         */
                        return CSSM_TRUE;
                }
-               
+
                const char *afterSubStr;                // in certComp
                const char *afterSubStr;                // in certComp
-               afterSubStr = tpSubStr(wildCard, endCertComp - wildCard,
+               afterSubStr = tpSubStr(wildCard, (uint32)(endCertComp - wildCard),
                        "*", 1);
                if(afterSubStr == NULL) {
                        /* no more wildcards - use end of certComp */
                        afterSubStr = endCertComp;
                }
                        "*", 1);
                if(afterSubStr == NULL) {
                        /* no more wildcards - use end of certComp */
                        afterSubStr = endCertComp;
                }
-               uint32 subStrLen = afterSubStr - wildCard;
+               uint32 subStrLen = (uint32)(afterSubStr - wildCard);
                const char *foundSub = tpSubStr(hostComp, hostCompLen,
                        wildCard, subStrLen);
                if(foundSub == NULL) {
                        /* No match of explicit chars */
                        return CSSM_FALSE;
                }
                const char *foundSub = tpSubStr(hostComp, hostCompLen,
                        wildCard, subStrLen);
                if(foundSub == NULL) {
                        /* No match of explicit chars */
                        return CSSM_FALSE;
                }
-               
+
                /* found it - skip past this substring */
                hostComp    = foundSub + subStrLen;
                /* found it - skip past this substring */
                hostComp    = foundSub + subStrLen;
-               hostCompLen = endHostComp - hostComp;
+               hostCompLen = (uint32)(endHostComp - hostComp);
                certComp    = afterSubStr;
                certComp    = afterSubStr;
-               certCompLen = endCertComp - afterSubStr;
-               
+               certCompLen = (uint32)(endCertComp - afterSubStr);
+
        } while((hostCompLen != 0) || (certCompLen != 0));
        if((hostCompLen == 0) && (certCompLen == 0)) {
                return CSSM_TRUE;
        } while((hostCompLen != 0) || (certCompLen != 0));
        if((hostCompLen == 0) && (certCompLen == 0)) {
                return CSSM_TRUE;
@@ -422,13 +422,13 @@ static CSSM_BOOL tpCompareComps(
 }
 
 /*
 }
 
 /*
- * Compare hostname, is presented to the TP in 
+ * Compare hostname, is presented to the TP in
  * CSSM_APPLE_TP_SSL_OPTIONS.ServerName, to a server name obtained
  * from the server's cert (i.e., from subjectAltName or commonName).
  * CSSM_APPLE_TP_SSL_OPTIONS.ServerName, to a server name obtained
  * from the server's cert (i.e., from subjectAltName or commonName).
- * Limited wildcard checking is performed here. 
+ * Limited wildcard checking is performed here.
  *
  * The incoming hostname is assumed to have been processed by tpToLower();
  *
  * The incoming hostname is assumed to have been processed by tpToLower();
- * we'll perform that processing on certName here. 
+ * we'll perform that processing on certName here.
  *
  * Trailing '.' characters in both host names will be ignored per Radar 3996792.
  *
  *
  * Trailing '.' characters in both host names will be ignored per Radar 3996792.
  *
@@ -449,7 +449,7 @@ CSSM_BOOL tpCompareHostNames(
        if(certNameLen && (certName[certNameLen - 1] == '\0')) {
                certNameLen--;
        }
        if(certNameLen && (certName[certNameLen - 1] == '\0')) {
                certNameLen--;
        }
-       
+
        if((hostNameLen == 0) || (certNameLen == 0)) {
                /* trivial case with at least one empty name */
                if(hostNameLen == certNameLen) {
        if((hostNameLen == 0) || (certNameLen == 0)) {
                /* trivial case with at least one empty name */
                if(hostNameLen == certNameLen) {
@@ -459,7 +459,7 @@ CSSM_BOOL tpCompareHostNames(
                        return CSSM_FALSE;
                }
        }
                        return CSSM_FALSE;
                }
        }
-       
+
        /* trim off trailing dots */
        if(hostName[hostNameLen - 1] == '.') {
                hostNameLen--;
        /* trim off trailing dots */
        if(hostName[hostNameLen - 1] == '.') {
                hostNameLen--;
@@ -467,16 +467,16 @@ CSSM_BOOL tpCompareHostNames(
        if(certName[certNameLen - 1] == '.') {
                certNameLen--;
        }
        if(certName[certNameLen - 1] == '.') {
                certNameLen--;
        }
-       
+
        /* Case 1: exact match */
        if((certNameLen == hostNameLen) &&
            !memcmp(certName, hostName, certNameLen)) {
                return CSSM_TRUE;
        }
        /* Case 1: exact match */
        if((certNameLen == hostNameLen) &&
            !memcmp(certName, hostName, certNameLen)) {
                return CSSM_TRUE;
        }
-       
-       /* 
+
+       /*
         * Case 2: Compare one component at a time, handling wildcards in
         * Case 2: Compare one component at a time, handling wildcards in
-        * cert's server name. The characters implicitly matched by a 
+        * cert's server name. The characters implicitly matched by a
         * wildcard span only one component of a dnsName.
         */
        do {
         * wildcard span only one component of a dnsName.
         */
        do {
@@ -485,7 +485,7 @@ CSSM_BOOL tpCompareHostNames(
                char certComp[MAX_DNS_COMP_LEN];
                uint32 hostCompLen;
                uint32 certCompLen;
                char certComp[MAX_DNS_COMP_LEN];
                uint32 hostCompLen;
                uint32 certCompLen;
-               
+
                bool foundHost = tpNextDnsComp(hostName, hostNameLen,
                                hostComp, hostCompLen);
                bool foundCert = tpNextDnsComp(certName, certNameLen,
                bool foundHost = tpNextDnsComp(hostName, hostNameLen,
                                hostComp, hostCompLen);
                bool foundCert = tpNextDnsComp(certName, certNameLen,
@@ -499,14 +499,14 @@ CSSM_BOOL tpCompareHostNames(
                        /* normal successful termination */
                        return CSSM_TRUE;
                }
                        /* normal successful termination */
                        return CSSM_TRUE;
                }
-               
+
                /* compare individual components */
                /* compare individual components */
-               if(!tpCompareComps(hostComp, hostCompLen, 
+               if(!tpCompareComps(hostComp, hostCompLen,
                                certComp, certCompLen)) {
                        tpPolicyError("tpCompareHostNames: wildcard mismatch (2)");
                        return CSSM_FALSE;
                }
                                certComp, certCompLen)) {
                        tpPolicyError("tpCompareHostNames: wildcard mismatch (2)");
                        return CSSM_FALSE;
                }
-               
+
                /* skip over this component
                 * (note: since tpNextDnsComp will first skip over a leading '.',
                 * we must make sure to skip over it here as well.)
                /* skip over this component
                 * (note: since tpNextDnsComp will first skip over a leading '.',
                 * we must make sure to skip over it here as well.)
@@ -522,14 +522,14 @@ CSSM_BOOL tpCompareHostNames(
 }
 
 /*
 }
 
 /*
- * Compare email address, is presented to the TP in 
+ * Compare email address, is presented to the TP in
  * CSSM_APPLE_TP_SMIME_OPTIONS.SenderEmail, to a string obtained
  * from the sender's cert (i.e., from subjectAltName or Subject DN).
  *
  * Returns CSSM_TRUE on match, else CSSM_FALSE.
  *
  * Incoming appEmail string has already been tpNormalizeAddrSpec'd.
  * CSSM_APPLE_TP_SMIME_OPTIONS.SenderEmail, to a string obtained
  * from the sender's cert (i.e., from subjectAltName or Subject DN).
  *
  * Returns CSSM_TRUE on match, else CSSM_FALSE.
  *
  * Incoming appEmail string has already been tpNormalizeAddrSpec'd.
- * We do that for certEmail string here. 
+ * We do that for certEmail string here.
  */
 CSSM_BOOL tpCompareEmailAddr(
        const char              *appEmail,              // spec'd by app, normalized
  */
 CSSM_BOOL tpCompareEmailAddr(
        const char              *appEmail,              // spec'd by app, normalized
@@ -559,9 +559,9 @@ CSSM_BOOL tpCompareEmailAddr(
        }
 }
 
        }
 }
 
-/* 
+/*
  * Following a CSSMOID_ECDSA_WithSpecified algorithm is an encoded
  * Following a CSSMOID_ECDSA_WithSpecified algorithm is an encoded
- * ECDSA_SigAlgParams containing the digest agorithm OID. Decode and return 
+ * ECDSA_SigAlgParams containing the digest agorithm OID. Decode and return
  * a unified ECDSA/digest alg (e.g. CSSM_ALGID_SHA512WithECDSA).
  * Returns nonzero on error.
  */
  * a unified ECDSA/digest alg (e.g. CSSM_ALGID_SHA512WithECDSA).
  * Returns nonzero on error.
  */
index 4e258ee4687f566d29f0a7d6dfeea75daa83ea3f..14d02f5432b84498e8f99631d96d0c4c2daefe81 100644 (file)
@@ -21,6 +21,7 @@
 #include "cuEnc64.h"
 #include <stdlib.h>
 #include <string.h>
 #include "cuEnc64.h"
 #include <stdlib.h>
 #include <string.h>
+#include <stddef.h>
 
 #ifndef        NULL
 #define NULL ((void *)0)
 
 #ifndef        NULL
 #define NULL ((void *)0)
@@ -405,7 +406,7 @@ static const char *findStr(
 {
        /* probably not the hottest string search algorithm... */
        const char *cp;
 {
        /* probably not the hottest string search algorithm... */
        const char *cp;
-       unsigned srchStrLen = strlen(str);
+       size_t srchStrLen = strlen(str);
        char c = str[0];
        
        /* last char * we can search in inText for start of str */
        char c = str[0];
        
        /* last char * we can search in inText for start of str */
@@ -455,7 +456,7 @@ static const char *getLine(
                inTextLen--;
                cp++;
        }
                inTextLen--;
                cp++;
        }
-       unsigned linelen;
+       ptrdiff_t linelen;
        if(newline) {
                linelen = newline - inText;
        }
        if(newline) {
                linelen = newline - inText;
        }
@@ -496,7 +497,7 @@ int cuConvertPem(
        const char *startLine = findStr(currCp, lenToGo, "-----BEGIN");
        if(startLine != NULL) {
                /* possibly skip over leading garbage */
        const char *startLine = findStr(currCp, lenToGo, "-----BEGIN");
        if(startLine != NULL) {
                /* possibly skip over leading garbage */
-               consumed = startLine - currCp;
+               consumed = (unsigned)(startLine - currCp);
                lenToGo -= consumed;
                currCp = startLine;
                
                lenToGo -= consumed;
                currCp = startLine;
                
@@ -524,7 +525,7 @@ int cuConvertPem(
                        goto errOut;
                }
                int skipThis = 0;
                        goto errOut;
                }
                int skipThis = 0;
-               unsigned lineLen = strlen(currLine);
+               size_t lineLen = strlen(currLine);
                if(lineLen == 0) {
                        /* empty line */
                        skipThis = 1;
                if(lineLen == 0) {
                        /* empty line */
                        skipThis = 1;
@@ -559,7 +560,7 @@ int cuConvertPem(
                        ortn = UNSUPPORTED_FORMAT_ERR;
                        goto errOut;
                }
                        ortn = UNSUPPORTED_FORMAT_ERR;
                        goto errOut;
                }
-               base64Len = end64 - start64;
+               base64Len = (unsigned)(end64 - start64);
        }
        /* else no END, no reason to complain about that as long as base64 decode works OK */
        
        }
        /* else no END, no reason to complain about that as long as base64 decode works OK */
        
index e5cbda692d705e3439f5d37f33c41cc2d8165041..b752e49a7596dd34fb7a6a9de859601628a50209 100644 (file)
@@ -82,7 +82,7 @@ const CSSM_DATA *OCSPRequest::encode()
        CSSM_DATA_PTR   issuerKey;
        CSSM_KEY_PTR    issuerPubKey;
        /* from subject */
        CSSM_DATA_PTR   issuerKey;
        CSSM_KEY_PTR    issuerPubKey;
        /* from subject */
-       CSSM_DATA_PTR   subjectSerial;
+       CSSM_DATA_PTR   subjectSerial=NULL;
 
        CSSM_RETURN                                     crtn;
        uint8                                           issuerNameHash[CC_SHA1_DIGEST_LENGTH];
 
        CSSM_RETURN                                     crtn;
        uint8                                           issuerNameHash[CC_SHA1_DIGEST_LENGTH];
@@ -129,7 +129,7 @@ const CSSM_DATA *OCSPRequest::encode()
        }
 
        /* SHA1(issuerName) */
        }
 
        /* SHA1(issuerName) */
-       ocspdSha1(issuerName->Data, issuerName->Length, issuerNameHash);
+       ocspdSha1(issuerName->Data, (CC_LONG)issuerName->Length, issuerNameHash);
 
        /* SHA1(issuer public key) */
        if(issuerKey->Length != sizeof(CSSM_KEY)) {
 
        /* SHA1(issuer public key) */
        if(issuerKey->Length != sizeof(CSSM_KEY)) {
@@ -138,7 +138,7 @@ const CSSM_DATA *OCSPRequest::encode()
                goto errOut;
        }
        issuerPubKey = (CSSM_KEY_PTR)issuerKey->Data;
                goto errOut;
        }
        issuerPubKey = (CSSM_KEY_PTR)issuerKey->Data;
-       ocspdSha1(issuerPubKey->KeyData.Data, issuerPubKey->KeyData.Length, pubKeyHash);
+       ocspdSha1(issuerPubKey->KeyData.Data, (CC_LONG)issuerPubKey->KeyData.Length, pubKeyHash);
        
        /* build the CertID from those components */
        certId.issuerNameHash.Data = issuerNameHash;
        
        /* build the CertID from those components */
        certId.issuerNameHash.Data = issuerNameHash;
index 9867134a08b24ed7859313df025ceeb48bfd414d..80e40b7d49bf66703561f66bb4280b27929362fc 100644 (file)
@@ -1,12 +1,12 @@
 /*
  * Copyright (c) 2000-2001, 2011 Apple Inc. All Rights Reserved.
 /*
  * Copyright (c) 2000-2001, 2011 Apple Inc. All Rights Reserved.
- * 
+ *
  * The contents of this file constitute Original Code as defined in and are
  * subject to the Apple Public Source License Version 1.2 (the 'License').
  * You may not use this file except in 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 contents of this file constitute Original Code as defined in and are
  * subject to the Apple Public Source License Version 1.2 (the 'License').
  * You may not use this file except in compliance with the License. Please obtain
  * a copy of the License at http://www.apple.com/publicsource and read it before
  * using this file.
- * 
+ *
  * This Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
  * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
  * This Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
  * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
@@ -17,9 +17,9 @@
 
 
 /*
 
 
 /*
- * tpCertGroup.cpp - Cert group functions (construct, verify) 
+ * tpCertGroup.cpp - Cert group functions (construct, verify)
  */
  */
+
 #include "AppleTPSession.h"
 #include "certGroupUtils.h"
 #include "TPCertInfo.h"
 #include "AppleTPSession.h"
 #include "certGroupUtils.h"
 #include "TPCertInfo.h"
@@ -34,7 +34,7 @@
  * This is a temporary hack to allow verification of PKINIT server certs
  * which are self-signed and not in the system anchors list. If the self-
  * signed cert is in a magic keychain (whose location is not published),
  * This is a temporary hack to allow verification of PKINIT server certs
  * which are self-signed and not in the system anchors list. If the self-
  * signed cert is in a magic keychain (whose location is not published),
- * we'll allow it as if it were indeed a full-fledged anchor cert. 
+ * we'll allow it as if it were indeed a full-fledged anchor cert.
  */
 #define TP_PKINIT_SERVER_HACK  1
 #if            TP_PKINIT_SERVER_HACK
  */
 #define TP_PKINIT_SERVER_HACK  1
 #if            TP_PKINIT_SERVER_HACK
 
 #define CFRELEASE(cf)  if(cf) { CFRelease(cf); }
 
 
 #define CFRELEASE(cf)  if(cf) { CFRelease(cf); }
 
-/* 
+/*
  * Returns true if we are to allow/trust the specified
  * cert as a PKINIT-only anchor.
  */
 static bool tpCheckPkinitServerCert(
        TPCertGroup &certGroup)
 {
  * Returns true if we are to allow/trust the specified
  * cert as a PKINIT-only anchor.
  */
 static bool tpCheckPkinitServerCert(
        TPCertGroup &certGroup)
 {
-       /* 
+       /*
         * Basic requirement: exactly one cert, self-signed.
         * The numCerts == 1 requirement might change...
         */
         * Basic requirement: exactly one cert, self-signed.
         * The numCerts == 1 requirement might change...
         */
@@ -71,11 +71,11 @@ static bool tpCheckPkinitServerCert(
                return false;
        }
        const CSSM_DATA *subjectName = theCert->subjectName();
                return false;
        }
        const CSSM_DATA *subjectName = theCert->subjectName();
-       
-       /* 
+
+       /*
         * Open the magic keychain.
         * Open the magic keychain.
-        * We're going up and over the Sec layer here, not generally 
-        * kosher, but this is a temp hack.
+        * We're going up and over the Sec layer here, not generally
+        * kosher, but this is a hack.
         */
        OSStatus ortn;
        SecKeychainRef kcRef = NULL;
         */
        OSStatus ortn;
        SecKeychainRef kcRef = NULL;
@@ -101,7 +101,7 @@ static bool tpCheckPkinitServerCert(
                return false;
        }
        /* subsequent errors to errOut: */
                return false;
        }
        /* subsequent errors to errOut: */
-       
+
        bool ourRtn = false;
        SecKeychainStatus kcStatus;
        CSSM_DATA_PTR subjSerial = NULL;
        bool ourRtn = false;
        SecKeychainStatus kcStatus;
        CSSM_DATA_PTR subjSerial = NULL;
@@ -110,13 +110,13 @@ static bool tpCheckPkinitServerCert(
        SecKeychainAttributeList        attrList;
        SecKeychainAttribute            attrs[2];
        SecKeychainItemRef                      foundItem = NULL;
        SecKeychainAttributeList        attrList;
        SecKeychainAttribute            attrs[2];
        SecKeychainItemRef                      foundItem = NULL;
-       
+
        ortn = SecKeychainGetStatus(kcRef, &kcStatus);
        if(ortn) {
                tpDebug("tpCheckPkinitServerCert: keychain not found (2)");
                goto errOut;
        }
        ortn = SecKeychainGetStatus(kcRef, &kcStatus);
        if(ortn) {
                tpDebug("tpCheckPkinitServerCert: keychain not found (2)");
                goto errOut;
        }
-       
+
        /*
         * We already have this cert's normalized name; get its
         * serial number.
        /*
         * We already have this cert's normalized name; get its
         * serial number.
@@ -127,16 +127,16 @@ static bool tpCheckPkinitServerCert(
                tpDebug("tpCheckPkinitServerCert: error fetching serial number");
                goto errOut;
        }
                tpDebug("tpCheckPkinitServerCert: error fetching serial number");
                goto errOut;
        }
-       
+
        attrs[0].tag    = kSecSubjectItemAttr;
        attrs[0].tag    = kSecSubjectItemAttr;
-       attrs[0].length = subjectName->Length;
+       attrs[0].length = (UInt32)subjectName->Length;
        attrs[0].data   = subjectName->Data;
        attrs[1].tag    = kSecSerialNumberItemAttr;
        attrs[0].data   = subjectName->Data;
        attrs[1].tag    = kSecSerialNumberItemAttr;
-       attrs[1].length = subjSerial->Length;
+       attrs[1].length = (UInt32)subjSerial->Length;
        attrs[1].data   = subjSerial->Data;
        attrList.count  = 2;
        attrList.attr   = attrs;
        attrs[1].data   = subjSerial->Data;
        attrList.count  = 2;
        attrList.attr   = attrs;
-       
+
        ortn = SecKeychainSearchCreateFromAttributes(kcRef,
                kSecCertificateItemClass,
                &attrList,
        ortn = SecKeychainSearchCreateFromAttributes(kcRef,
                kSecCertificateItemClass,
                &attrList,
@@ -151,7 +151,7 @@ static bool tpCheckPkinitServerCert(
                        tpDebug("tpCheckPkinitServerCert: end search");
                        break;
                }
                        tpDebug("tpCheckPkinitServerCert: end search");
                        break;
                }
-               
+
                /* found a matching cert; do byte-for-byte compare */
                CSSM_DATA certData;
                ortn = SecCertificateGetData((SecCertificateRef)foundItem, &certData);
                /* found a matching cert; do byte-for-byte compare */
                CSSM_DATA certData;
                ortn = SecCertificateGetData((SecCertificateRef)foundItem, &certData);
@@ -192,41 +192,41 @@ errOut:
  *   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
  *   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: 
+ *   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
  *   -- 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. 
+ *      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
  *   -- 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. 
+ *             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
  *
  * 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.  
- *   
+ *   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
  *   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. 
- *   
+ *   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.)
  *
  *---------------------------------------------------------------------------*/
  *   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,
 /* public version */
 void AppleTPSession::CertGroupConstruct(CSSM_CL_HANDLE clHand,
                CSSM_CSP_HANDLE cspHand,
@@ -236,23 +236,23 @@ void AppleTPSession::CertGroupConstruct(CSSM_CL_HANDLE clHand,
                CSSM_CERTGROUP_PTR &CertGroup)
 {
        TPCertGroup outCertGroup(*this, TGO_Caller);
                CSSM_CERTGROUP_PTR &CertGroup)
 {
        TPCertGroup outCertGroup(*this, TGO_Caller);
-       TPCertGroup inCertGroup(CertGroupFrag, 
-               clHand, 
-               cspHand, 
-               *this, 
+       TPCertGroup inCertGroup(CertGroupFrag,
+               clHand,
+               cspHand,
+               *this,
                NULL,           // cssmTimeStr
                true,           // firstCertMustBeValid
                TGO_Group);
                NULL,           // cssmTimeStr
                true,           // firstCertMustBeValid
                TGO_Group);
-               
+
        /* set up for disposal of TPCertInfos created by CertGroupConstructPriv */
        TPCertGroup                     gatheredCerts(*this, TGO_Group);
        /* set up for disposal of TPCertInfos created by CertGroupConstructPriv */
        TPCertGroup                     gatheredCerts(*this, TGO_Group);
-       
+
        CSSM_RETURN constructReturn = CSSM_OK;
        CSSM_APPLE_TP_ACTION_FLAGS      actionFlags = 0;
        CSSM_BOOL verifiedToRoot;               // not used
        CSSM_BOOL verifiedToAnchor;             // not used
        CSSM_BOOL verifiedViaTrustSetting;      // not used
        CSSM_RETURN constructReturn = CSSM_OK;
        CSSM_APPLE_TP_ACTION_FLAGS      actionFlags = 0;
        CSSM_BOOL verifiedToRoot;               // not used
        CSSM_BOOL verifiedToAnchor;             // not used
        CSSM_BOOL verifiedViaTrustSetting;      // not used
-       
+
        try {
                CertGroupConstructPriv(clHand,
                        cspHand,
        try {
                CertGroupConstructPriv(clHand,
                        cspHand,
@@ -280,21 +280,21 @@ void AppleTPSession::CertGroupConstruct(CSSM_CL_HANDLE clHand,
        CertGroup = outCertGroup.buildCssmCertGroup();
        /* caller of this function never gets evidence... */
        outCertGroup.freeDbRecords();
        CertGroup = outCertGroup.buildCssmCertGroup();
        /* caller of this function never gets evidence... */
        outCertGroup.freeDbRecords();
-       
+
        if(constructReturn) {
                CssmError::throwMe(constructReturn);
        }
 }
 
 
        if(constructReturn) {
                CssmError::throwMe(constructReturn);
        }
 }
 
 
-/* 
+/*
  * Private version of CertGroupConstruct, used by CertGroupConstruct and
  * CertGroupVerify. Populates a TP-style TPCertGroup for further processing.
  * Private version of CertGroupConstruct, used by CertGroupConstruct and
  * CertGroupVerify. Populates a TP-style TPCertGroup for further processing.
- * This only throws CSSM-style exceptions in the following cases: 
- * 
+ * 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).
  *  -- input parameter errors
  *  -- the first (leaf) cert is bad (doesn't parse, expired, not valid yet).
- *  -- root found but it doesn't self-verify 
+ *  -- root found but it doesn't self-verify
  *
  *  All other cert-related errors simply result in the bad cert being ignored.
  *  Other exceptions are gross system errors like malloc failure.
  *
  *  All other cert-related errors simply result in the bad cert being ignored.
  *  Other exceptions are gross system errors like malloc failure.
@@ -304,12 +304,12 @@ void AppleTPSession::CertGroupConstructPriv(CSSM_CL_HANDLE clHand,
                TPCertGroup                     &inCertGroup,
                const CSSM_DL_DB_LIST   *DBList,                        // optional here
                const char                              *cssmTimeStr,           // optional
                TPCertGroup                     &inCertGroup,
                const CSSM_DL_DB_LIST   *DBList,                        // optional here
                const char                              *cssmTimeStr,           // optional
-               
+
                /* trusted anchors, optional */
                /* FIXME - maybe this should be a TPCertGroup */
                uint32                                  numAnchorCerts,
                const CSSM_DATA                 *anchorCerts,
                /* trusted anchors, optional */
                /* FIXME - maybe this should be a TPCertGroup */
                uint32                                  numAnchorCerts,
                const CSSM_DATA                 *anchorCerts,
-               
+
                /* CSSM_TP_ACTION_FETCH_CERT_FROM_NET, CSSM_TP_ACTION_TRUST_SETTINGS */
                CSSM_APPLE_TP_ACTION_FLAGS      actionFlags,
 
                /* CSSM_TP_ACTION_FETCH_CERT_FROM_NET, CSSM_TP_ACTION_TRUST_SETTINGS */
                CSSM_APPLE_TP_ACTION_FLAGS      actionFlags,
 
@@ -318,8 +318,8 @@ void AppleTPSession::CertGroupConstructPriv(CSSM_CL_HANDLE clHand,
                const char                              *policyStr,
                uint32                                  policyStrLen,
                SecTrustSettingsKeyUsage        keyUse,
                const char                              *policyStr,
                uint32                                  policyStrLen,
                SecTrustSettingsKeyUsage        keyUse,
-               
-               /* 
+
+               /*
                 * Certs to be freed by caller (i.e., TPCertInfo which we allocate
                 * as a result of using a cert from anchorCerts or dbList) are added
                 * to this group.
                 * Certs to be freed by caller (i.e., TPCertInfo which we allocate
                 * as a result of using a cert from anchorCerts or dbList) are added
                 * to this group.
@@ -334,7 +334,7 @@ void AppleTPSession::CertGroupConstructPriv(CSSM_CL_HANDLE clHand,
 {
        TPCertInfo                      *subjectCert;                           // the one we're working on
        CSSM_RETURN                     outErr = CSSM_OK;
 {
        TPCertInfo                      *subjectCert;                           // the one we're working on
        CSSM_RETURN                     outErr = CSSM_OK;
-       
+
        /* this'll be the first subject cert in the main loop */
        subjectCert = inCertGroup.certAtIndex(0);
 
        /* this'll be the first subject cert in the main loop */
        subjectCert = inCertGroup.certAtIndex(0);
 
@@ -344,14 +344,14 @@ void AppleTPSession::CertGroupConstructPriv(CSSM_CL_HANDLE clHand,
        subjectCert->isFromInputCerts(true);
        outCertGroup.setAllUnused();
        subjectCert->used(true);
        subjectCert->isFromInputCerts(true);
        outCertGroup.setAllUnused();
        subjectCert->used(true);
-       
+
        outErr = outCertGroup.buildCertGroup(
        outErr = outCertGroup.buildCertGroup(
-               *subjectCert,   
+               *subjectCert,
                &inCertGroup,
                DBList,
                clHand,
                cspHand,
                &inCertGroup,
                DBList,
                clHand,
                cspHand,
-               cssmTimeStr,    
+               cssmTimeStr,
                numAnchorCerts,
                anchorCerts,
                certsToBeFreed,
                numAnchorCerts,
                anchorCerts,
                certsToBeFreed,
@@ -363,8 +363,8 @@ void AppleTPSession::CertGroupConstructPriv(CSSM_CL_HANDLE clHand,
                policyStr,
                policyStrLen,
                keyUse,
                policyStr,
                policyStrLen,
                keyUse,
-               
-               verifiedToRoot, 
+
+               verifiedToRoot,
                verifiedToAnchor,
                verifiedViaTrustSetting);
        if(outErr) {
                verifiedToAnchor,
                verifiedViaTrustSetting);
        if(outErr) {
@@ -445,6 +445,30 @@ static bool checkPolicyOid(
                tpPolicy = kTP_TimeStamping;
                return true;
        }
                tpPolicy = kTP_TimeStamping;
                return true;
        }
+       else if(tpCompareOids(&oid, &CSSMOID_APPLE_TP_PASSBOOK_SIGNING)) {
+               tpPolicy = kTP_PassbookSigning;
+               return true;
+       }
+       else if(tpCompareOids(&oid, &CSSMOID_APPLE_TP_MOBILE_STORE)) {
+               tpPolicy = kTP_MobileStore;
+               return true;
+       }
+       else if(tpCompareOids(&oid, &CSSMOID_APPLE_TP_TEST_MOBILE_STORE)) {
+               tpPolicy = kTP_TestMobileStore;
+               return true;
+       }
+       else if(tpCompareOids(&oid, &CSSMOID_APPLE_TP_ESCROW_SERVICE)) {
+               tpPolicy = kTP_EscrowService;
+               return true;
+       }
+       else if(tpCompareOids(&oid, &CSSMOID_APPLE_TP_PROFILE_SIGNING)) {
+               tpPolicy = kTP_ProfileSigning;
+               return true;
+       }
+       else if(tpCompareOids(&oid, &CSSMOID_APPLE_TP_QA_PROFILE_SIGNING)) {
+               tpPolicy = kTP_QAProfileSigning;
+               return true;
+       }
        return false;
 }
 
        return false;
 }
 
@@ -452,43 +476,43 @@ static bool checkPolicyOid(
  * CertGroupVerify
  *
  * Description:
  * 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. 
+ *   -- 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 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. 
+ *   -- 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
  *
  * 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.  
- *   
+ *   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.
  *   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. 
- *   
+ *   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.)
  *   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. 
- *   
+ *
+ *   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
  *   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},
  *
  *                     For both of these, the associated FieldValue must be {0, NULL},
  *
- *   NumberOfPolicyIdentifiers, size of PolicyIdentifiers array, must be 
- *      zero or one. 
- * 
+ *   NumberOfPolicyIdentifiers, size of PolicyIdentifiers array, must be
+ *      zero or one.
+ *
  *   All other arguments must be zero/NULL.
  *
  *   Returns:
  *   All other arguments must be zero/NULL.
  *
  *   Returns:
@@ -496,20 +520,20 @@ static bool checkPolicyOid(
  *      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
  *      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. 
+ *             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
  *             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. 
+ *             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
  *             CSSMERR_TP_INVALID_REQUEST_INPUTS : no incoming VerifyContext.
  *             CSSMERR_TP_CERT_EXPIRED and CSSMERR_TP_CERT_NOT_VALID_YET: see comments
- *                     for CertGroupConstruct. 
+ *                     for CertGroupConstruct.
  *             CSSMERR_TP_CERTIFICATE_CANT_OPERATE : issuer cert was found with a partial
  *             CSSMERR_TP_CERTIFICATE_CANT_OPERATE : issuer cert was found with a partial
- *                     public key, rendering full verification impossible. 
- *     CSSMERR_TP_INVALID_CERT_AUTHORITY : issuer cert was found with a partial 
+ *                     public key, rendering full verification impossible.
+ *     CSSMERR_TP_INVALID_CERT_AUTHORITY : issuer cert was found with a partial
  *                     public key and which failed to perform subsequent signature
  *                     verification.
  *---------------------------------------------------------------------------*/
  *                     public key and which failed to perform subsequent signature
  *                     verification.
  *---------------------------------------------------------------------------*/
@@ -531,11 +555,11 @@ void AppleTPSession::CertGroupVerify(CSSM_CL_HANDLE clHand,
        CSSM_TIMESTRING                 cssmTimeStr;
        CSSM_APPLE_TP_ACTION_FLAGS      actionFlags = 0;
        CSSM_TP_STOP_ON                 tpStopOn = 0;
        CSSM_TIMESTRING                 cssmTimeStr;
        CSSM_APPLE_TP_ACTION_FLAGS      actionFlags = 0;
        CSSM_TP_STOP_ON                 tpStopOn = 0;
-       
+
        /* keep track of whether we did policy checking; if not, we do defaults */
        bool                                    didCertPolicy = false;
        bool                                    didRevokePolicy = false;
        /* keep track of whether we did policy checking; if not, we do defaults */
        bool                                    didCertPolicy = false;
        bool                                    didRevokePolicy = false;
-       
+
        /* user trust parameters */
        CSSM_OID                                utNullPolicy = {0, NULL};
        const CSSM_OID                  *utPolicyOid = NULL;
        /* user trust parameters */
        CSSM_OID                                utNullPolicy = {0, NULL};
        const CSSM_OID                  *utPolicyOid = NULL;
@@ -543,7 +567,7 @@ void AppleTPSession::CertGroupVerify(CSSM_CL_HANDLE clHand,
        uint32                                  utPolicyStrLen = 0;
        SecTrustSettingsKeyUsage        utKeyUse = 0;
        bool                                    utTrustSettingEnabled = false;
        uint32                                  utPolicyStrLen = 0;
        SecTrustSettingsKeyUsage        utKeyUse = 0;
        bool                                    utTrustSettingEnabled = false;
-       
+
        if(VerifyContextResult) {
                memset(VerifyContextResult, 0, sizeof(*VerifyContextResult));
        }
        if(VerifyContextResult) {
                memset(VerifyContextResult, 0, sizeof(*VerifyContextResult));
        }
@@ -554,7 +578,7 @@ void AppleTPSession::CertGroupVerify(CSSM_CL_HANDLE clHand,
                        CssmError::throwMe(CSSMERR_TP_INVALID_REQUEST_INPUTS);
        }
        cred = VerifyContext->Cred;
                        CssmError::throwMe(CSSMERR_TP_INVALID_REQUEST_INPUTS);
        }
        cred = VerifyContext->Cred;
-       
+
        /* Optional ActionData affecting all policies */
        actionData = (CSSM_APPLE_TP_ACTION_DATA * volatile)VerifyContext->ActionData.Data;
        if(actionData != NULL) {
        /* Optional ActionData affecting all policies */
        actionData = (CSSM_APPLE_TP_ACTION_DATA * volatile)VerifyContext->ActionData.Data;
        if(actionData != NULL) {
@@ -574,14 +598,14 @@ void AppleTPSession::CertGroupVerify(CSSM_CL_HANDLE clHand,
                        utTrustSettingEnabled = true;
                }
        }
                        utTrustSettingEnabled = true;
                }
        }
-       
+
        /* optional, may be NULL */
        cssmTimeStr = cred->VerifyTime;
        /* optional, may be NULL */
        cssmTimeStr = cred->VerifyTime;
-       
+
        tpStopOn = cred->VerificationAbortOn;
        switch(tpStopOn) {
                /* the only two we support */
        tpStopOn = cred->VerificationAbortOn;
        switch(tpStopOn) {
                /* the only two we support */
-               case CSSM_TP_STOP_ON_NONE:      
+               case CSSM_TP_STOP_ON_NONE:
                case CSSM_TP_STOP_ON_FIRST_FAIL:
                        break;
                /* default maps to stop on first fail */
                case CSSM_TP_STOP_ON_FIRST_FAIL:
                        break;
                /* default maps to stop on first fail */
@@ -591,18 +615,18 @@ void AppleTPSession::CertGroupVerify(CSSM_CL_HANDLE clHand,
                default:
                        CssmError::throwMe(CSSMERR_TP_INVALID_STOP_ON_POLICY);
        }
                default:
                        CssmError::throwMe(CSSMERR_TP_INVALID_STOP_ON_POLICY);
        }
-       
+
        /* now the args we can't deal with */
        if(cred->CallerCredentials != NULL) {
                        CssmError::throwMe(CSSMERR_TP_INVALID_CALLERAUTH_CONTEXT_POINTER);
        }
        /* ...any others? */
        /* now the args we can't deal with */
        if(cred->CallerCredentials != NULL) {
                        CssmError::throwMe(CSSMERR_TP_INVALID_CALLERAUTH_CONTEXT_POINTER);
        }
        /* ...any others? */
-       
+
        /* set up for optional user trust evaluation */
        if(utTrustSettingEnabled) {
                const CSSM_TP_POLICYINFO *pinfo = &cred->Policy;
                TPPolicy utPolicy = kTPx509Basic;
        /* set up for optional user trust evaluation */
        if(utTrustSettingEnabled) {
                const CSSM_TP_POLICYINFO *pinfo = &cred->Policy;
                TPPolicy utPolicy = kTPx509Basic;
-               
+
                /* default policy OID in case caller hasn't specified one */
                utPolicyOid = &utNullPolicy;
                if(pinfo->NumberOfPolicyIds == 0) {
                /* default policy OID in case caller hasn't specified one */
                utPolicyOid = &utNullPolicy;
                if(pinfo->NumberOfPolicyIds == 0) {
@@ -622,27 +646,27 @@ void AppleTPSession::CertGroupVerify(CSSM_CL_HANDLE clHand,
                                tp_policyTrustSettingParams(utPolicy, &utPolicyField->FieldValue,
                                        &utPolicyStr, &utPolicyStrLen, &utKeyUse);
                        }
                                tp_policyTrustSettingParams(utPolicy, &utPolicyField->FieldValue,
                                        &utPolicyStr, &utPolicyStrLen, &utKeyUse);
                        }
-               }       
+               }
        }
        }
-       
+
        /* get verified (possibly partial) outCertGroup - error is fatal */
        /* BUT: we still return partial evidence if asked to...from now on. */
        /* get verified (possibly partial) outCertGroup - error is fatal */
        /* BUT: we still return partial evidence if asked to...from now on. */
-       TPCertGroup outCertGroup(*this, 
+       TPCertGroup outCertGroup(*this,
                TGO_Caller);            // certs are owned by inCertGroup
                TGO_Caller);            // certs are owned by inCertGroup
-       TPCertGroup inCertGroup(CertGroupToBeVerified, clHand, cspHand, *this, 
+       TPCertGroup inCertGroup(CertGroupToBeVerified, clHand, cspHand, *this,
                cssmTimeStr,            // optional 'this' time
                true,                           // firstCertMustBeValid
                cssmTimeStr,            // optional 'this' time
                true,                           // firstCertMustBeValid
-               TGO_Group);     
-               
+               TGO_Group);
+
        /* set up for disposal of TPCertInfos created by CertGroupConstructPriv */
        TPCertGroup     gatheredCerts(*this, TGO_Group);
        /* set up for disposal of TPCertInfos created by CertGroupConstructPriv */
        TPCertGroup     gatheredCerts(*this, TGO_Group);
-       
+
        try {
                CertGroupConstructPriv(
                        clHand,
                        cspHand,
                        inCertGroup,
        try {
                CertGroupConstructPriv(
                        clHand,
                        cspHand,
                        inCertGroup,
-                       cred->DBList, 
+                       cred->DBList,
                        cssmTimeStr,
                        cred->NumberOfAnchorCerts,
                        cred->AnchorCerts,
                        cssmTimeStr,
                        cred->NumberOfAnchorCerts,
                        cred->AnchorCerts,
@@ -652,7 +676,7 @@ void AppleTPSession::CertGroupVerify(CSSM_CL_HANDLE clHand,
                        utPolicyStrLen,
                        utKeyUse,
                        gatheredCerts,
                        utPolicyStrLen,
                        utKeyUse,
                        gatheredCerts,
-                       verifiedToRoot, 
+                       verifiedToRoot,
                        verifiedToAnchor,
                        verifiedViaTrustSetting,
                        outCertGroup);
                        verifiedToAnchor,
                        verifiedViaTrustSetting,
                        outCertGroup);
@@ -667,7 +691,7 @@ void AppleTPSession::CertGroupVerify(CSSM_CL_HANDLE clHand,
        }
        /* others are way fatal */
        assert(outCertGroup.numCerts() >= 1);
        }
        /* others are way fatal */
        assert(outCertGroup.numCerts() >= 1);
-       
+
        /* Infer interim status from return values */
        switch(constructReturn) {
                /* these values do not get overridden */
        /* Infer interim status from return values */
        switch(constructReturn) {
                /* these values do not get overridden */
@@ -696,30 +720,30 @@ void AppleTPSession::CertGroupVerify(CSSM_CL_HANDLE clHand,
                                constructReturn = CSSMERR_TP_NOT_TRUSTED;
                        }
 
                                constructReturn = CSSMERR_TP_NOT_TRUSTED;
                        }
 
-                       /* 
+                       /*
                         * Those errors can be allowed, cert-chain-wide, per individual
                         * certs' allowedErrors
                         */
                         * Those errors can be allowed, cert-chain-wide, per individual
                         * certs' allowedErrors
                         */
-                       if((constructReturn != CSSM_OK) && 
+                       if((constructReturn != CSSM_OK) &&
                            outCertGroup.isAllowedError(constructReturn)) {
                                constructReturn = CSSM_OK;
                        }
                        break;
        }
                            outCertGroup.isAllowedError(constructReturn)) {
                                constructReturn = CSSM_OK;
                        }
                        break;
        }
-       
+
        /*
         * Parameters passed to tp_policyVerify() and which vary per policy
        /*
         * Parameters passed to tp_policyVerify() and which vary per policy
-        * in the loop below 
+        * in the loop below
         */
        TPPolicy tpPolicy;
        const CSSM_APPLE_TP_SSL_OPTIONS *sslOpts;
        CSSM_RETURN thisPolicyRtn = CSSM_OK;    // returned from tp_policyVerify()
         */
        TPPolicy tpPolicy;
        const CSSM_APPLE_TP_SSL_OPTIONS *sslOpts;
        CSSM_RETURN thisPolicyRtn = CSSM_OK;    // returned from tp_policyVerify()
-       
+
        /* common CRL verify parameters */
        TPCrlGroup *crlGroup = NULL;
        try {
                crlGroup = new TPCrlGroup(&VerifyContext->Crls,
        /* common CRL verify parameters */
        TPCrlGroup *crlGroup = NULL;
        try {
                crlGroup = new TPCrlGroup(&VerifyContext->Crls,
-                       clHand, cspHand, 
+                       clHand, cspHand,
                        *this,                          // alloc
                        NULL,                           // cssmTimeStr - we want CRLs that are valid 'now'
                        TGO_Group);
                        *this,                          // alloc
                        NULL,                           // cssmTimeStr - we want CRLs that are valid 'now'
                        TGO_Group);
@@ -755,12 +779,12 @@ void AppleTPSession::CertGroupVerify(CSSM_CL_HANDLE clHand,
                utPolicyStr,
                utPolicyStrLen,
                utKeyUse);
                utPolicyStr,
                utPolicyStrLen,
                utKeyUse);
-               
+
        /* true if we're to execute tp_policyVerify at end of loop */
        bool doPolicyVerify;
        /* true if we're to execute a revocation policy at end of loop */
        bool doRevocationPolicy;
        /* true if we're to execute tp_policyVerify at end of loop */
        bool doPolicyVerify;
        /* true if we're to execute a revocation policy at end of loop */
        bool doRevocationPolicy;
-       
+
        /* grind thru each policy */
        for(uint32 polDex=0; polDex<cred->Policy.NumberOfPolicyIds; polDex++) {
                if(cred->Policy.PolicyIds == NULL) {
        /* grind thru each policy */
        for(uint32 polDex=0; polDex<cred->Policy.NumberOfPolicyIds; polDex++) {
                if(cred->Policy.PolicyIds == NULL) {
@@ -774,7 +798,7 @@ void AppleTPSession::CertGroupVerify(CSSM_CL_HANDLE clHand,
                doPolicyVerify = false;
                doRevocationPolicy = false;
                sslOpts = NULL;
                doPolicyVerify = false;
                doRevocationPolicy = false;
                sslOpts = NULL;
-               
+
                /* first the basic cert policies */
                doPolicyVerify = checkPolicyOid(*oid, tpPolicy);
                if(doPolicyVerify) {
                /* first the basic cert policies */
                doPolicyVerify = checkPolicyOid(*oid, tpPolicy);
                if(doPolicyVerify) {
@@ -808,10 +832,10 @@ void AppleTPSession::CertGroupVerify(CSSM_CL_HANDLE clHand,
                        }
                        #endif  /* TP_PKINIT_SERVER_HACK */
                }
                        }
                        #endif  /* TP_PKINIT_SERVER_HACK */
                }
-               
-               /* 
-                * Now revocation policies. Note some fields in revokeVfyContext can 
-                * accumulate across multiple policy calls, e.g., signerCerts. 
+
+               /*
+                * Now revocation policies. Note some fields in revokeVfyContext can
+                * accumulate across multiple policy calls, e.g., signerCerts.
                 */
                else if(tpCompareOids(oid, &CSSMOID_APPLE_TP_REVOCATION_CRL)) {
                        /* CRL-specific options */
                 */
                else if(tpCompareOids(oid, &CSSMOID_APPLE_TP_REVOCATION_CRL)) {
                        /* CRL-specific options */
@@ -821,9 +845,9 @@ void AppleTPSession::CertGroupVerify(CSSM_CL_HANDLE clHand,
                        if(crlOpts != NULL) {
                                switch(crlOpts->Version) {
                                        case CSSM_APPLE_TP_CRL_OPTS_VERSION:
                        if(crlOpts != NULL) {
                                switch(crlOpts->Version) {
                                        case CSSM_APPLE_TP_CRL_OPTS_VERSION:
-                                               if(fieldVal->Length != 
+                                               if(fieldVal->Length !=
                                                                sizeof(CSSM_APPLE_TP_CRL_OPTIONS)) {
                                                                sizeof(CSSM_APPLE_TP_CRL_OPTIONS)) {
-                                                       thisPolicyRtn = 
+                                                       thisPolicyRtn =
                                                                CSSMERR_TP_INVALID_POLICY_IDENTIFIERS;
                                                        break;
                                                }
                                                                CSSMERR_TP_INVALID_POLICY_IDENTIFIERS;
                                                        break;
                                                }
@@ -850,9 +874,9 @@ void AppleTPSession::CertGroupVerify(CSSM_CL_HANDLE clHand,
                        if(ocspOpts != NULL) {
                                switch(ocspOpts->Version) {
                                        case CSSM_APPLE_TP_OCSP_OPTS_VERSION:
                        if(ocspOpts != NULL) {
                                switch(ocspOpts->Version) {
                                        case CSSM_APPLE_TP_OCSP_OPTS_VERSION:
-                                               if(fieldVal->Length != 
+                                               if(fieldVal->Length !=
                                                                sizeof(CSSM_APPLE_TP_OCSP_OPTIONS)) {
                                                                sizeof(CSSM_APPLE_TP_OCSP_OPTIONS)) {
-                                                       thisPolicyRtn = 
+                                                       thisPolicyRtn =
                                                                CSSMERR_TP_INVALID_POLICY_IDENTIFIERS;
                                                        break;
                                                }
                                                                CSSMERR_TP_INVALID_POLICY_IDENTIFIERS;
                                                        break;
                                                }
@@ -877,7 +901,7 @@ void AppleTPSession::CertGroupVerify(CSSM_CL_HANDLE clHand,
                        policyReturn = CSSMERR_TP_INVALID_POLICY_IDENTIFIERS;
                        break;
                }
                        policyReturn = CSSMERR_TP_INVALID_POLICY_IDENTIFIERS;
                        break;
                }
-               
+
                /* common cert policy call */
                if(doPolicyVerify) {
                        assert(!doRevocationPolicy);    // one at a time
                /* common cert policy call */
                if(doPolicyVerify) {
                        assert(!doRevocationPolicy);    // one at a time
@@ -917,7 +941,7 @@ void AppleTPSession::CertGroupVerify(CSSM_CL_HANDLE clHand,
                        }
                }
        }       /* for each policy */
                        }
                }
        }       /* for each policy */
-       
+
        /*
         * Upon completion of the above loop, perform default policy ops if
         * appropriate.
        /*
         * Upon completion of the above loop, perform default policy ops if
         * appropriate.
@@ -946,7 +970,7 @@ void AppleTPSession::CertGroupVerify(CSSM_CL_HANDLE clHand,
                        )
                  ) {
                        revokeVfyContext.policy = TP_CRL_POLICY_DEFAULT;
                        )
                  ) {
                        revokeVfyContext.policy = TP_CRL_POLICY_DEFAULT;
-                       CSSM_RETURN thisPolicyRtn = tpRevocationPolicyVerify(revokeVfyContext, 
+                       CSSM_RETURN thisPolicyRtn = tpRevocationPolicyVerify(revokeVfyContext,
                                outCertGroup);
                        if((thisPolicyRtn != CSSM_OK) &&
                                outCertGroup.isAllowedError(thisPolicyRtn)) {
                                outCertGroup);
                        if((thisPolicyRtn != CSSM_OK) &&
                                outCertGroup.isAllowedError(thisPolicyRtn)) {
@@ -955,12 +979,12 @@ void AppleTPSession::CertGroupVerify(CSSM_CL_HANDLE clHand,
                        if((thisPolicyRtn != CSSM_OK) && (policyReturn == CSSM_OK)) {
                                policyReturn = thisPolicyRtn;
                        }
                        if((thisPolicyRtn != CSSM_OK) && (policyReturn == CSSM_OK)) {
                                policyReturn = thisPolicyRtn;
                        }
-               
+
                }
        }       /* default policy opts */
                }
        }       /* default policy opts */
-       
+
        delete crlGroup;
        delete crlGroup;
-       
+
        /* return evidence - i.e., constructed chain - if asked to */
        if(VerifyContextResult != NULL) {
                /*
        /* return evidence - i.e., constructed chain - if asked to */
        if(VerifyContextResult != NULL) {
                /*
@@ -969,21 +993,21 @@ void AppleTPSession::CertGroupVerify(CSSM_CL_HANDLE clHand,
                 * VerifyContextResult->Evidence[2] : CSSM_TP_APPLE_EVIDENCE_INFO
                 */
                VerifyContextResult->NumberOfEvidences = 3;
                 * VerifyContextResult->Evidence[2] : CSSM_TP_APPLE_EVIDENCE_INFO
                 */
                VerifyContextResult->NumberOfEvidences = 3;
-               VerifyContextResult->Evidence = 
+               VerifyContextResult->Evidence =
                        (CSSM_EVIDENCE_PTR)calloc(3, sizeof(CSSM_EVIDENCE));
 
                        (CSSM_EVIDENCE_PTR)calloc(3, sizeof(CSSM_EVIDENCE));
 
-               CSSM_TP_APPLE_EVIDENCE_HEADER *hdr = 
+               CSSM_TP_APPLE_EVIDENCE_HEADER *hdr =
                        (CSSM_TP_APPLE_EVIDENCE_HEADER *)malloc(
                                sizeof(CSSM_TP_APPLE_EVIDENCE_HEADER));
                hdr->Version = CSSM_TP_APPLE_EVIDENCE_VERSION;
                CSSM_EVIDENCE_PTR ev = &VerifyContextResult->Evidence[0];
                ev->EvidenceForm = CSSM_EVIDENCE_FORM_APPLE_HEADER;
                ev->Evidence = hdr;
                        (CSSM_TP_APPLE_EVIDENCE_HEADER *)malloc(
                                sizeof(CSSM_TP_APPLE_EVIDENCE_HEADER));
                hdr->Version = CSSM_TP_APPLE_EVIDENCE_VERSION;
                CSSM_EVIDENCE_PTR ev = &VerifyContextResult->Evidence[0];
                ev->EvidenceForm = CSSM_EVIDENCE_FORM_APPLE_HEADER;
                ev->Evidence = hdr;
-               
+
                ev = &VerifyContextResult->Evidence[1];
                ev->EvidenceForm = CSSM_EVIDENCE_FORM_APPLE_CERTGROUP;
                ev->Evidence = outCertGroup.buildCssmCertGroup();
                ev = &VerifyContextResult->Evidence[1];
                ev->EvidenceForm = CSSM_EVIDENCE_FORM_APPLE_CERTGROUP;
                ev->Evidence = outCertGroup.buildCssmCertGroup();
-               
+
                ev = &VerifyContextResult->Evidence[2];
                ev->EvidenceForm = CSSM_EVIDENCE_FORM_APPLE_CERT_INFO;
                ev->Evidence = outCertGroup.buildCssmEvidenceInfo();
                ev = &VerifyContextResult->Evidence[2];
                ev->EvidenceForm = CSSM_EVIDENCE_FORM_APPLE_CERT_INFO;
                ev->Evidence = outCertGroup.buildCssmEvidenceInfo();
@@ -994,7 +1018,7 @@ void AppleTPSession::CertGroupVerify(CSSM_CL_HANDLE clHand,
        }
        CSSM_RETURN outErr = outCertGroup.getReturnCode(constructReturn, policyReturn,
                actionFlags);
        }
        CSSM_RETURN outErr = outCertGroup.getReturnCode(constructReturn, policyReturn,
                actionFlags);
-       
+
        if(outErr) {
                CssmError::throwMe(outErr);
        }
        if(outErr) {
                CssmError::throwMe(outErr);
        }
index 71007b790cb1d0a2506c7b5df6872d2c427b5aa5..483ad49b16dc9dce26682a1418fa5330efacdd77 100644 (file)
@@ -285,6 +285,7 @@ static bool tpCertHasCrlDistPt(
  * Note that ocspdCRLStatus does NOT wait for the CRL to be downloaded before
  * returning, nor does it initiate a CRL download.
  */
  * Note that ocspdCRLStatus does NOT wait for the CRL to be downloaded before
  * returning, nor does it initiate a CRL download.
  */
+static
 CSSM_RETURN tpGetCrlStatusForCert(
        TPCertInfo                                              &subject,
        const CSSM_DATA                                 &issuers)
 CSSM_RETURN tpGetCrlStatusForCert(
        TPCertInfo                                              &subject,
        const CSSM_DATA                                 &issuers)
index 287f0f63839b677877a7a3e88bae044c395ea761..f0a7815ae1e88f75fe51f456cf91c0bfc8fdb176 100644 (file)
@@ -109,6 +109,7 @@ errOut:
  * be the issuer of both that response and the cert being verified. Returns
  * true if OK.
  */
  * be the issuer of both that response and the cert being verified. Returns
  * true if OK.
  */
+static
 bool tpOcspResponderIDCheck(
        OCSPResponse    &ocspResp,
        TPCertInfo              &signer)
 bool tpOcspResponderIDCheck(
        OCSPResponse    &ocspResp,
        TPCertInfo              &signer)
@@ -144,7 +145,7 @@ bool tpOcspResponderIDCheck(
                assert(pubKey != NULL);
                uint8 digest[CC_SHA1_DIGEST_LENGTH];
                CSSM_DATA keyHash = {CC_SHA1_DIGEST_LENGTH, digest};
                assert(pubKey != NULL);
                uint8 digest[CC_SHA1_DIGEST_LENGTH];
                CSSM_DATA keyHash = {CC_SHA1_DIGEST_LENGTH, digest};
-               ocspdSha1(pubKey->KeyData.Data, pubKey->KeyData.Length, digest);
+               ocspdSha1(pubKey->KeyData.Data, (CC_LONG)pubKey->KeyData.Length, digest);
                const CSSM_DATA *respKeyHash = &ocspResp.responderID().byKey;
                if(tpCompareCssmData(&keyHash, respKeyHash)) {
                        tpOcspDebug("tpOcspResponderIDCheck: good ResponderID.byKey");
                const CSSM_DATA *respKeyHash = &ocspResp.responderID().byKey;
                if(tpCompareCssmData(&keyHash, respKeyHash)) {
                        tpOcspDebug("tpOcspResponderIDCheck: good ResponderID.byKey");
index 16a6757effa09341f698d30f5c423088e9b20aec..395b29af7d884717e701551c4e2a0f52fcd8aed5 100644 (file)
@@ -33,7 +33,7 @@
 #include <security_asn1/SecNssCoder.h>
 #include <security_ocspd/ocspResponse.h>
 
 #include <security_asn1/SecNssCoder.h>
 #include <security_ocspd/ocspResponse.h>
 
-#ifdef __cplusplus>
+#ifdef __cplusplus
 
 extern "C" {
 #endif
 
 extern "C" {
 #endif
index 07a1f7911d77bdb50ddcc7ad49296637c2110fb9..4dcb08b6c4a1cdc97b801693faf035c517fb3df5 100644 (file)
@@ -1,12 +1,12 @@
 /*
 /*
- * Copyright (c) 2000-2012 Apple Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2000-2013 Apple Inc. All Rights Reserved.
+ *
  * The contents of this file constitute Original Code as defined in and are
  * subject to the Apple Public Source License Version 1.2 (the 'License').
  * You may not use this file except in 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 contents of this file constitute Original Code as defined in and are
  * subject to the Apple Public Source License Version 1.2 (the 'License').
  * You may not use this file except in compliance with the License. Please obtain
  * a copy of the License at http://www.apple.com/publicsource and read it before
  * using this file.
- * 
+ *
  * This Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
  * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
  * This Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
  * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
 #include <Security/oidscert.h>
 #include <Security/certextensions.h>
 #include <Security/cssmapple.h>
 #include <Security/oidscert.h>
 #include <Security/certextensions.h>
 #include <Security/cssmapple.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecCertificatePriv.h>
 #include <string.h>
 #include <ctype.h>
 #include <assert.h>
 #include <CoreFoundation/CFString.h>
 #include <string.h>
 #include <ctype.h>
 #include <assert.h>
 #include <CoreFoundation/CFString.h>
+#include <CommonCrypto/CommonDigest.h>
 
 
-
-/* 
+/*
  * Our private per-extension info. One of these per (understood) extension per
  * Our private per-extension info. One of these per (understood) extension per
- * cert. 
+ * cert.
  */
 typedef struct {
        CSSM_BOOL               present;
  */
 typedef struct {
        CSSM_BOOL               present;
@@ -70,19 +72,25 @@ typedef struct {
        iSignExtenInfo          inhibitAnyPolicy;
        iSignExtenInfo          certificatePolicies;
 
        iSignExtenInfo          inhibitAnyPolicy;
        iSignExtenInfo          certificatePolicies;
 
+       /* flag indicating presence of CSSMOID_APPLE_EXTENSION_PASSBOOK_SIGNING */
+       CSSM_BOOL                       foundPassbookSigning;
+       /* flag indicating presence of CSSMOID_APPLE_EXTENSION_SYSINT2_INTERMEDIATE */
+       CSSM_BOOL                       foundAppleSysInt2Marker;
+       /* flag indicating presence of CSSMOID_APPLE_EXTENSION_ESCROW_SERVICE */
+       CSSM_BOOL                       foundEscrowServiceMarker;
        /* flag indicating presence of a critical extension we don't understand */
        CSSM_BOOL                       foundUnknownCritical;
        /* flag indicating that this certificate was signed with a known-broken algorithm */
        CSSM_BOOL                       untrustedSigAlg;
        /* flag indicating presence of a critical extension we don't understand */
        CSSM_BOOL                       foundUnknownCritical;
        /* flag indicating that this certificate was signed with a known-broken algorithm */
        CSSM_BOOL                       untrustedSigAlg;
-       
+
 } iSignCertInfo;
 } iSignCertInfo;
-/* 
- * The list of Qualified Cert Statement statementIds we understand, even though 
- * we don't actually do anything with them; if these are found in a Qualified 
+
+/*
+ * The list of Qualified Cert Statement statementIds we understand, even though
+ * we don't actually do anything with them; if these are found in a Qualified
  * Cert Statement that's critical, we can truthfully say "yes we understand this".
  */
  * Cert Statement that's critical, we can truthfully say "yes we understand this".
  */
-static const CSSM_OID_PTR knownQualifiedCertStatements[] = 
+static const CSSM_OID_PTR knownQualifiedCertStatements[] =
 {
        (const CSSM_OID_PTR)&CSSMOID_OID_QCS_SYNTAX_V1,
        (const CSSM_OID_PTR)&CSSMOID_OID_QCS_SYNTAX_V2,
 {
        (const CSSM_OID_PTR)&CSSMOID_OID_QCS_SYNTAX_V1,
        (const CSSM_OID_PTR)&CSSMOID_OID_QCS_SYNTAX_V2,
@@ -93,10 +101,25 @@ static const CSSM_OID_PTR knownQualifiedCertStatements[] =
 };
 #define NUM_KNOWN_QUAL_CERT_STATEMENTS (sizeof(knownQualifiedCertStatements) / sizeof(CSSM_OID_PTR))
 
 };
 #define NUM_KNOWN_QUAL_CERT_STATEMENTS (sizeof(knownQualifiedCertStatements) / sizeof(CSSM_OID_PTR))
 
-static CSSM_RETURN tp_verifyMacAppStoreReciptOpts(TPCertGroup &certGroup, 
+static CSSM_RETURN tp_verifyMacAppStoreReceiptOpts(TPCertGroup &certGroup,
        const CSSM_DATA *fieldOpts,     const iSignCertInfo *certInfo);
        const CSSM_DATA *fieldOpts,     const iSignCertInfo *certInfo);
+
+static CSSM_RETURN tp_verifyPassbookSigningOpts(TPCertGroup &certGroup,
+       const CSSM_DATA *fieldOpts, const iSignCertInfo *certInfo);
+
 bool certificatePoliciesContainsOID(const CE_CertPolicies *certPolicies, const CSSM_OID *oidToFind);
 bool certificatePoliciesContainsOID(const CE_CertPolicies *certPolicies, const CSSM_OID *oidToFind);
-       
+
+#define kSecPolicySHA1Size 20
+static const UInt8 kAppleCASHA1[kSecPolicySHA1Size] = {
+    0x61, 0x1E, 0x5B, 0x66, 0x2C, 0x59, 0x3A, 0x08, 0xFF, 0x58,
+    0xD1, 0x4A, 0xE2, 0x24, 0x52, 0xD1, 0x98, 0xDF, 0x6C, 0x60
+};
+
+static const UInt8 kMobileRootSHA1[kSecPolicySHA1Size] =  {
+    0xBD, 0xD6, 0x7C, 0x34, 0xD0, 0xB2, 0x68, 0x5D, 0x31, 0x82,
+    0xCD, 0x32, 0xCB, 0xF4, 0x54, 0x69, 0xA1, 0xF1, 0x6B, 0x09
+};
+
 /*
  * Certificate policy OIDs
  */
 /*
  * Certificate policy OIDs
  */
@@ -135,10 +158,10 @@ static CSSM_RETURN tp_verifyAppleIDSharingOpts(TPCertGroup &certGroup,
                                                                                                const iSignCertInfo *certInfo);
 /*
  * Setup a single iSignExtenInfo. Called once per known extension
                                                                                                const iSignCertInfo *certInfo);
 /*
  * Setup a single iSignExtenInfo. Called once per known extension
- * per cert. 
+ * per cert.
  */
 static CSSM_RETURN tpSetupExtension(
  */
 static CSSM_RETURN tpSetupExtension(
-       Allocator                       &alloc, 
+       Allocator                       &alloc,
        CSSM_DATA                       *extnData,
        iSignExtenInfo          *extnInfo)              // which component of certInfo
 {
        CSSM_DATA                       *extnData,
        iSignExtenInfo          *extnInfo)              // which component of certInfo
 {
@@ -158,14 +181,14 @@ static CSSM_RETURN tpSetupExtension(
  * Fetch a known extension, set up associated iSignExtenInfo if present.
  */
 static CSSM_RETURN iSignFetchExtension(
  * Fetch a known extension, set up associated iSignExtenInfo if present.
  */
 static CSSM_RETURN iSignFetchExtension(
-       Allocator                       &alloc, 
+       Allocator                       &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;
        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:
        crtn = tpCert->fetchField(fieldOid, &fieldValue);
        switch(crtn) {
                case CSSM_OK:
@@ -191,10 +214,10 @@ static CSSM_RETURN iSignVerifyCriticalExtension(
 {
        if (!cssmExt || !cssmExt->extnId.Data)
                return CSSMERR_TP_INVALID_FIELD_POINTER;
 {
        if (!cssmExt || !cssmExt->extnId.Data)
                return CSSMERR_TP_INVALID_FIELD_POINTER;
-       
+
        if (!cssmExt->critical)
                return CSSM_OK;
        if (!cssmExt->critical)
                return CSSM_OK;
-       
+
        /* FIXME: remove when policyConstraints NSS template is fixed */
        if (!memcmp(cssmExt->extnId.Data, CSSMOID_PolicyConstraints.Data, CSSMOID_PolicyConstraints.Length))
                return CSSM_OK;
        /* FIXME: remove when policyConstraints NSS template is fixed */
        if (!memcmp(cssmExt->extnId.Data, CSSMOID_PolicyConstraints.Data, CSSMOID_PolicyConstraints.Length))
                return CSSM_OK;
@@ -203,14 +226,14 @@ static CSSM_RETURN iSignVerifyCriticalExtension(
                !memcmp(cssmExt->extnId.Data, CSSMOID_APPLE_EXTENSION.Data, APPLE_EXTENSION_OID_LENGTH)) {
                /* This extension's OID is under the appleCertificateExtensions arc */
                return CSSM_OK;
                !memcmp(cssmExt->extnId.Data, CSSMOID_APPLE_EXTENSION.Data, APPLE_EXTENSION_OID_LENGTH)) {
                /* This extension's OID is under the appleCertificateExtensions arc */
                return CSSM_OK;
-       
+
        }
        return CSSMERR_APPLETP_UNKNOWN_CRITICAL_EXTEN;
 }
 
 /*
        }
        return CSSMERR_APPLETP_UNKNOWN_CRITICAL_EXTEN;
 }
 
 /*
- * Search for all unknown extensions. If we find one which is flagged critical, 
- * flag certInfo->foundUnknownCritical. Only returns error on gross errors.  
+ * Search for all 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,
  */
 static CSSM_RETURN iSignSearchUnknownExtensions(
        TPCertInfo                      *tpCert,
@@ -220,12 +243,16 @@ static CSSM_RETURN iSignSearchUnknownExtensions(
        CSSM_DATA_PTR   fieldValue = NULL;
        CSSM_HANDLE             searchHand = CSSM_INVALID_HANDLE;
        uint32                  numFields = 0;
        CSSM_DATA_PTR   fieldValue = NULL;
        CSSM_HANDLE             searchHand = CSSM_INVALID_HANDLE;
        uint32                  numFields = 0;
-       
+
+       certInfo->foundPassbookSigning = CSSM_FALSE;
+       certInfo->foundAppleSysInt2Marker = CSSM_FALSE;
+       certInfo->foundEscrowServiceMarker = CSSM_FALSE;
+
        crtn = CSSM_CL_CertGetFirstCachedFieldValue(tpCert->clHand(),
                tpCert->cacheHand(),
                &CSSMOID_X509V3CertificateExtensionCStruct,
                &searchHand,
        crtn = CSSM_CL_CertGetFirstCachedFieldValue(tpCert->clHand(),
                tpCert->cacheHand(),
                &CSSMOID_X509V3CertificateExtensionCStruct,
                &searchHand,
-               &numFields, 
+               &numFields,
                &fieldValue);
        switch(crtn) {
                case CSSM_OK:
                &fieldValue);
        switch(crtn) {
                case CSSM_OK:
@@ -237,22 +264,42 @@ static CSSM_RETURN iSignSearchUnknownExtensions(
                default:
                        return crtn;
        }
                default:
                        return crtn;
        }
-       
+
        if(fieldValue->Length != sizeof(CSSM_X509_EXTENSION)) {
                tpPolicyError("iSignSearchUnknownExtensions: malformed CSSM_FIELD");
                return CSSMERR_TP_UNKNOWN_FORMAT;
        }
        if(fieldValue->Length != sizeof(CSSM_X509_EXTENSION)) {
                tpPolicyError("iSignSearchUnknownExtensions: malformed CSSM_FIELD");
                return CSSMERR_TP_UNKNOWN_FORMAT;
        }
+
        CSSM_X509_EXTENSION *cssmExt = (CSSM_X509_EXTENSION *)fieldValue->Data;
        CSSM_X509_EXTENSION *cssmExt = (CSSM_X509_EXTENSION *)fieldValue->Data;
+       if (cssmExt->extnId.Length == APPLE_EXTENSION_CODE_SIGNING_LENGTH+1 &&
+               !memcmp(cssmExt->extnId.Data, CSSMOID_APPLE_EXTENSION_PASSBOOK_SIGNING.Data,
+               APPLE_EXTENSION_CODE_SIGNING_LENGTH+1)) {
+               /* this is the Passbook Signing extension */
+               certInfo->foundPassbookSigning = CSSM_TRUE;
+       }
+       if (cssmExt->extnId.Length == APPLE_EXTENSION_SYSINT2_INTERMEDIATE_LENGTH &&
+               !memcmp(cssmExt->extnId.Data, CSSMOID_APPLE_EXTENSION_SYSINT2_INTERMEDIATE.Data,
+                APPLE_EXTENSION_SYSINT2_INTERMEDIATE_LENGTH)) {
+               /* this is the Apple System Integration 2 Signing extension */
+               certInfo->foundAppleSysInt2Marker = CSSM_TRUE;
+       }
+       if (cssmExt->extnId.Length == APPLE_EXTENSION_ESCROW_SERVICE_LENGTH &&
+               !memcmp(cssmExt->extnId.Data, CSSMOID_APPLE_EXTENSION_ESCROW_SERVICE.Data,
+                APPLE_EXTENSION_ESCROW_SERVICE_LENGTH)) {
+               /* this is the Escrow Service Signing extension */
+               certInfo->foundEscrowServiceMarker = CSSM_TRUE;
+       }
+
        if(iSignVerifyCriticalExtension(cssmExt) != CSSM_OK) {
                /* BRRZAPP! Found an unknown extension marked critical */
                certInfo->foundUnknownCritical = CSSM_TRUE;
                goto fini;
        }
        if(iSignVerifyCriticalExtension(cssmExt) != CSSM_OK) {
                /* BRRZAPP! Found an unknown extension marked critical */
                certInfo->foundUnknownCritical = CSSM_TRUE;
                goto fini;
        }
-       CSSM_CL_FreeFieldValue(tpCert->clHand(), 
-               &CSSMOID_X509V3CertificateExtensionCStruct, 
+       CSSM_CL_FreeFieldValue(tpCert->clHand(),
+               &CSSMOID_X509V3CertificateExtensionCStruct,
                fieldValue);
        fieldValue = NULL;
                fieldValue);
        fieldValue = NULL;
-       
+
        /* process remaining unknown extensions */
        for(unsigned i=1; i<numFields; i++) {
                crtn = CSSM_CL_CertGetNextCachedFieldValue(tpCert->clHand(),
        /* process remaining unknown extensions */
        for(unsigned i=1; i<numFields; i++) {
                crtn = CSSM_CL_CertGetNextCachedFieldValue(tpCert->clHand(),
@@ -270,22 +317,42 @@ static CSSM_RETURN iSignSearchUnknownExtensions(
                        crtn = CSSMERR_TP_UNKNOWN_FORMAT;
                        break;
                }
                        crtn = CSSMERR_TP_UNKNOWN_FORMAT;
                        break;
                }
+
                CSSM_X509_EXTENSION *cssmExt = (CSSM_X509_EXTENSION *)fieldValue->Data;
                CSSM_X509_EXTENSION *cssmExt = (CSSM_X509_EXTENSION *)fieldValue->Data;
+               if (cssmExt->extnId.Length == APPLE_EXTENSION_CODE_SIGNING_LENGTH+1 &&
+                               !memcmp(cssmExt->extnId.Data, CSSMOID_APPLE_EXTENSION_PASSBOOK_SIGNING.Data,
+                                       APPLE_EXTENSION_CODE_SIGNING_LENGTH+1)) {
+                       /* this is the Passbook Signing extension */
+                       certInfo->foundPassbookSigning = CSSM_TRUE;
+               }
+               if (cssmExt->extnId.Length == APPLE_EXTENSION_SYSINT2_INTERMEDIATE_LENGTH &&
+                               !memcmp(cssmExt->extnId.Data, CSSMOID_APPLE_EXTENSION_SYSINT2_INTERMEDIATE.Data,
+                                       APPLE_EXTENSION_SYSINT2_INTERMEDIATE_LENGTH)) {
+                       /* this is the Apple System Integration 2 Signing extension */
+                       certInfo->foundAppleSysInt2Marker = CSSM_TRUE;
+               }
+               if (cssmExt->extnId.Length == APPLE_EXTENSION_ESCROW_SERVICE_LENGTH &&
+                               !memcmp(cssmExt->extnId.Data, CSSMOID_APPLE_EXTENSION_ESCROW_SERVICE.Data,
+                                       APPLE_EXTENSION_ESCROW_SERVICE_LENGTH)) {
+                       /* this is the Escrow Service Signing extension */
+                       certInfo->foundEscrowServiceMarker = CSSM_TRUE;
+               }
+
                if(iSignVerifyCriticalExtension(cssmExt) != CSSM_OK) {
                        /* BRRZAPP! Found an unknown extension marked critical */
                        certInfo->foundUnknownCritical = CSSM_TRUE;
                        break;
                }
                if(iSignVerifyCriticalExtension(cssmExt) != CSSM_OK) {
                        /* BRRZAPP! Found an unknown extension marked critical */
                        certInfo->foundUnknownCritical = CSSM_TRUE;
                        break;
                }
-               CSSM_CL_FreeFieldValue(tpCert->clHand(), 
-                       &CSSMOID_X509V3CertificateExtensionCStruct, 
+               CSSM_CL_FreeFieldValue(tpCert->clHand(),
+                       &CSSMOID_X509V3CertificateExtensionCStruct,
                        fieldValue);
                fieldValue = NULL;
        } /* for additional fields */
                        fieldValue);
                fieldValue = NULL;
        } /* for additional fields */
-                               
+
 fini:
        if(fieldValue) {
 fini:
        if(fieldValue) {
-               CSSM_CL_FreeFieldValue(tpCert->clHand(), 
-                       &CSSMOID_X509V3CertificateExtensionCStruct, 
+               CSSM_CL_FreeFieldValue(tpCert->clHand(),
+                       &CSSMOID_X509V3CertificateExtensionCStruct,
                        fieldValue);
        }
        if(searchHand != CSSM_INVALID_HANDLE) {
                        fieldValue);
        }
        if(searchHand != CSSM_INVALID_HANDLE) {
@@ -295,7 +362,7 @@ fini:
 }
 
 /*
 }
 
 /*
- * Check the signature algorithm. If it's known to be untrusted, 
+ * Check the signature algorithm. If it's known to be untrusted,
  * flag certInfo->untrustedSigAlg.
  */
 static void iSignCheckSignatureAlgorithm(
  * flag certInfo->untrustedSigAlg.
  */
 static void iSignCheckSignatureAlgorithm(
@@ -304,11 +371,13 @@ static void iSignCheckSignatureAlgorithm(
 {
        CSSM_X509_ALGORITHM_IDENTIFIER  *algId = NULL;
        CSSM_DATA_PTR                                   valueToFree = NULL;
 {
        CSSM_X509_ALGORITHM_IDENTIFIER  *algId = NULL;
        CSSM_DATA_PTR                                   valueToFree = NULL;
-       
+
        algId = tp_CertGetAlgId(tpCert, &valueToFree);
        if(!algId ||
        algId = tp_CertGetAlgId(tpCert, &valueToFree);
        if(!algId ||
-          tpCompareCssmData(&algId->algorithm, &CSSMOID_MD2) ||
-          tpCompareCssmData(&algId->algorithm, &CSSMOID_MD2WithRSA)) {
+               tpCompareCssmData(&algId->algorithm, &CSSMOID_MD2) ||
+               tpCompareCssmData(&algId->algorithm, &CSSMOID_MD2WithRSA) ||
+               tpCompareCssmData(&algId->algorithm, &CSSMOID_MD5) ||
+               tpCompareCssmData(&algId->algorithm, &CSSMOID_MD5WithRSA) ) {
                certInfo->untrustedSigAlg = CSSM_TRUE;
        } else {
                certInfo->untrustedSigAlg = CSSM_FALSE;
                certInfo->untrustedSigAlg = CSSM_TRUE;
        } else {
                certInfo->untrustedSigAlg = CSSM_FALSE;
@@ -320,16 +389,16 @@ static void iSignCheckSignatureAlgorithm(
 }
 
 /*
 }
 
 /*
- * Given a TPCertInfo, fetch the associated iSignCertInfo fields. 
- * Returns CSSM_FAIL on error. 
+ * Given a TPCertInfo, fetch the associated iSignCertInfo fields.
+ * Returns CSSM_FAIL on error.
  */
 static CSSM_RETURN iSignGetCertInfo(
  */
 static CSSM_RETURN iSignGetCertInfo(
-       Allocator                       &alloc, 
+       Allocator                       &alloc,
        TPCertInfo                      *tpCert,
        iSignCertInfo           *certInfo)
 {
        CSSM_RETURN                     crtn;
        TPCertInfo                      *tpCert,
        iSignCertInfo           *certInfo)
 {
        CSSM_RETURN                     crtn;
-       
+
        /* first grind thru the extensions we're interested in */
        crtn = iSignFetchExtension(alloc,
                tpCert,
        /* first grind thru the extensions we're interested in */
        crtn = iSignFetchExtension(alloc,
                tpCert,
@@ -428,11 +497,11 @@ static CSSM_RETURN iSignGetCertInfo(
                &certInfo->certificatePolicies);
        if(crtn) {
                return crtn;
                &certInfo->certificatePolicies);
        if(crtn) {
                return crtn;
-       }       
-       
+       }
+
        /* check signature algorithm field */
        iSignCheckSignatureAlgorithm(tpCert, certInfo);
        /* check signature algorithm field */
        iSignCheckSignatureAlgorithm(tpCert, certInfo);
-       
+
        /* now look for extensions we don't understand - the only thing we're interested
         * in is the critical flag. */
        return iSignSearchUnknownExtensions(tpCert, certInfo);
        /* now look for extensions we don't understand - the only thing we're interested
         * in is the critical flag. */
        return iSignSearchUnknownExtensions(tpCert, certInfo);
@@ -446,66 +515,68 @@ static void iSignFreeCertInfo(
        iSignCertInfo   *certInfo)
 {
        if(certInfo->authorityId.present) {
        iSignCertInfo   *certInfo)
 {
        if(certInfo->authorityId.present) {
-               CSSM_CL_FreeFieldValue(clHand, &CSSMOID_AuthorityKeyIdentifier, 
+               CSSM_CL_FreeFieldValue(clHand, &CSSMOID_AuthorityKeyIdentifier,
                        certInfo->authorityId.valToFree);
        }
        if(certInfo->subjectId.present) {
                        certInfo->authorityId.valToFree);
        }
        if(certInfo->subjectId.present) {
-               CSSM_CL_FreeFieldValue(clHand, &CSSMOID_SubjectKeyIdentifier, 
+               CSSM_CL_FreeFieldValue(clHand, &CSSMOID_SubjectKeyIdentifier,
                        certInfo->subjectId.valToFree);
        }
        if(certInfo->keyUsage.present) {
                        certInfo->subjectId.valToFree);
        }
        if(certInfo->keyUsage.present) {
-               CSSM_CL_FreeFieldValue(clHand, &CSSMOID_KeyUsage, 
+               CSSM_CL_FreeFieldValue(clHand, &CSSMOID_KeyUsage,
                        certInfo->keyUsage.valToFree);
        }
        if(certInfo->extendKeyUsage.present) {
                        certInfo->keyUsage.valToFree);
        }
        if(certInfo->extendKeyUsage.present) {
-               CSSM_CL_FreeFieldValue(clHand, &CSSMOID_ExtendedKeyUsage, 
+               CSSM_CL_FreeFieldValue(clHand, &CSSMOID_ExtendedKeyUsage,
                        certInfo->extendKeyUsage.valToFree);
        }
        if(certInfo->basicConstraints.present) {
                        certInfo->extendKeyUsage.valToFree);
        }
        if(certInfo->basicConstraints.present) {
-               CSSM_CL_FreeFieldValue(clHand, &CSSMOID_BasicConstraints, 
+               CSSM_CL_FreeFieldValue(clHand, &CSSMOID_BasicConstraints,
                        certInfo->basicConstraints.valToFree);
        }
        if(certInfo->netscapeCertType.present) {
                        certInfo->basicConstraints.valToFree);
        }
        if(certInfo->netscapeCertType.present) {
-               CSSM_CL_FreeFieldValue(clHand, &CSSMOID_NetscapeCertType, 
+               CSSM_CL_FreeFieldValue(clHand, &CSSMOID_NetscapeCertType,
                        certInfo->netscapeCertType.valToFree);
        }
        if(certInfo->subjectAltName.present) {
                        certInfo->netscapeCertType.valToFree);
        }
        if(certInfo->subjectAltName.present) {
-               CSSM_CL_FreeFieldValue(clHand, &CSSMOID_SubjectAltName, 
+               CSSM_CL_FreeFieldValue(clHand, &CSSMOID_SubjectAltName,
                        certInfo->subjectAltName.valToFree);
        }
        if(certInfo->certPolicies.present) {
                        certInfo->subjectAltName.valToFree);
        }
        if(certInfo->certPolicies.present) {
-               CSSM_CL_FreeFieldValue(clHand, &CSSMOID_CertificatePolicies, 
+               CSSM_CL_FreeFieldValue(clHand, &CSSMOID_CertificatePolicies,
                        certInfo->certPolicies.valToFree);
        }
 //     if(certInfo->policyConstraints.present) {
                        certInfo->certPolicies.valToFree);
        }
 //     if(certInfo->policyConstraints.present) {
-//             CSSM_CL_FreeFieldValue(clHand, &CSSMOID_PolicyConstraints, 
+//             CSSM_CL_FreeFieldValue(clHand, &CSSMOID_PolicyConstraints,
 //                     certInfo->policyConstraints.valToFree);
 //     }
        if(certInfo->qualCertStatements.present) {
 //                     certInfo->policyConstraints.valToFree);
 //     }
        if(certInfo->qualCertStatements.present) {
-               CSSM_CL_FreeFieldValue(clHand, &CSSMOID_QC_Statements, 
+               CSSM_CL_FreeFieldValue(clHand, &CSSMOID_QC_Statements,
                        certInfo->qualCertStatements.valToFree);
        }
        if(certInfo->certificatePolicies.present) {
                        certInfo->qualCertStatements.valToFree);
        }
        if(certInfo->certificatePolicies.present) {
-               CSSM_CL_FreeFieldValue(clHand, &CSSMOID_CertificatePolicies, 
+               CSSM_CL_FreeFieldValue(clHand, &CSSMOID_CertificatePolicies,
                        certInfo->certificatePolicies.valToFree);
        }
 }
 
                        certInfo->certificatePolicies.valToFree);
        }
 }
 
-/* 
- * See if cert's Subject.{commonName,EmailAddress} matches caller-specified 
- * string. Returns CSSM_TRUE if match, else returns CSSM_FALSE. 
+/*
+ * See if cert's Subject.{commonName,EmailAddress} matches caller-specified
+ * string. Returns CSSM_TRUE if match, else returns CSSM_FALSE.
  * Also indicates whether *any* of the specified fields were found, regardless
  * of match state.
  */
 typedef enum {
        SN_CommonName,                  // CSSMOID_CommonName, host name format
  * Also indicates whether *any* of the specified fields were found, regardless
  * of match state.
  */
 typedef enum {
        SN_CommonName,                  // CSSMOID_CommonName, host name format
-       SN_Email                                // CSSMOID_EmailAddress
+       SN_Email,                               // CSSMOID_EmailAddress
+       SN_UserID,                              // CSSMOID_UserID
+       SN_OrgUnit                              // CSSMOID_OrganizationalUnitName
 } SubjSubjNameSearchType;
 
 static CSSM_BOOL tpCompareSubjectName(
        TPCertInfo                              &cert,
        SubjSubjNameSearchType  searchType,
 } SubjSubjNameSearchType;
 
 static CSSM_BOOL tpCompareSubjectName(
        TPCertInfo                              &cert,
        SubjSubjNameSearchType  searchType,
-       bool                                    normalizeAll,           // for SN_Email case: lower-case all of 
+       bool                                    normalizeAll,           // for SN_Email case: lower-case all of
                                                                                                // the cert's value, not just the portion
                                                                                                // after the '@'
        const char                              *callerStr,                     // already tpToLower'd
                                                                                                // the cert's value, not just the portion
                                                                                                // after the '@'
        const char                              *callerStr,                     // already tpToLower'd
@@ -518,7 +589,10 @@ static CSSM_BOOL tpCompareSubjectName(
        CSSM_RETURN     crtn;
        CSSM_BOOL               ourRtn = CSSM_FALSE;
        const CSSM_OID  *oidSrch;
        CSSM_RETURN     crtn;
        CSSM_BOOL               ourRtn = CSSM_FALSE;
        const CSSM_OID  *oidSrch;
-       
+
+       const char x500_userid_oid[] = { 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x01 };
+       CSSM_OID X500_UserID_OID = { sizeof(x500_userid_oid), (uint8*)x500_userid_oid };
+
        fieldFound = false;
        switch(searchType) {
                case SN_CommonName:
        fieldFound = false;
        switch(searchType) {
                case SN_CommonName:
@@ -527,6 +601,12 @@ static CSSM_BOOL tpCompareSubjectName(
                case SN_Email:
                        oidSrch = &CSSMOID_EmailAddress;
                        break;
                case SN_Email:
                        oidSrch = &CSSMOID_EmailAddress;
                        break;
+               case SN_UserID:
+                       oidSrch = &X500_UserID_OID;
+                       break;
+               case SN_OrgUnit:
+                       oidSrch = &CSSMOID_OrganizationalUnitName;
+                       break;
                default:
                        assert(0);
                        return CSSM_FALSE;
                default:
                        assert(0);
                        return CSSM_FALSE;
@@ -549,7 +629,7 @@ static CSSM_BOOL tpCompareSubjectName(
        CSSM_X509_RDN_PTR               rdnp;
        unsigned                                        rdnDex;
        unsigned                                        pairDex;
        CSSM_X509_RDN_PTR               rdnp;
        unsigned                                        rdnDex;
        unsigned                                        pairDex;
-       
+
        for(rdnDex=0; rdnDex<x509name->numberOfRDNs; rdnDex++) {
                rdnp = &x509name->RelativeDistinguishedName[rdnDex];
                for(pairDex=0; pairDex<rdnp->numberOfPairs; pairDex++) {
        for(rdnDex=0; rdnDex<x509name->numberOfRDNs; rdnDex++) {
                rdnp = &x509name->RelativeDistinguishedName[rdnDex];
                for(pairDex=0; pairDex<rdnp->numberOfPairs; pairDex++) {
@@ -557,14 +637,14 @@ static CSSM_BOOL tpCompareSubjectName(
                        if(tpCompareOids(&ptvp->type, oidSrch)) {
                                fieldFound = true;
                                certName = (char *)ptvp->value.Data;
                        if(tpCompareOids(&ptvp->type, oidSrch)) {
                                fieldFound = true;
                                certName = (char *)ptvp->value.Data;
-                               certNameLen = ptvp->value.Length;
+                               certNameLen = (uint32)ptvp->value.Length;
                                switch(searchType) {
                                switch(searchType) {
-                                       case SN_CommonName: 
+                                       case SN_CommonName:
                                        {
                                                /* handle odd encodings that we need to convert to 8-bit */
                                                CFStringBuiltInEncodings encoding;
                                                CFDataRef cfd = NULL;
                                        {
                                                /* handle odd encodings that we need to convert to 8-bit */
                                                CFStringBuiltInEncodings encoding;
                                                CFDataRef cfd = NULL;
-                                               bool doConvert = false;                                         
+                                               bool doConvert = false;
                                                switch(ptvp->valueType) {
                                                        case BER_TAG_T61_STRING:
                                                                /* a.k.a. Teletex */
                                                switch(ptvp->valueType) {
                                                        case BER_TAG_T61_STRING:
                                                                /* a.k.a. Teletex */
@@ -575,9 +655,9 @@ static CSSM_BOOL tpCompareSubjectName(
                                                                encoding = kCFStringEncodingUnicode;
                                                                doConvert = true;
                                                                break;
                                                                encoding = kCFStringEncodingUnicode;
                                                                doConvert = true;
                                                                break;
-                                                       /* 
+                                                       /*
                                                         * All others - either take as is, or let it fail due to
                                                         * All others - either take as is, or let it fail due to
-                                                        * illegal/incomprehensible format 
+                                                        * illegal/incomprehensible format
                                                         */
                                                        default:
                                                                break;
                                                         */
                                                        default:
                                                                break;
@@ -596,7 +676,7 @@ static CSSM_BOOL tpCompareSubjectName(
                                                                tpPolicyError("tpCompareSubjectName: bad str (1)");
                                                                break;
                                                        }
                                                                tpPolicyError("tpCompareSubjectName: bad str (1)");
                                                                break;
                                                        }
-                                                       
+
                                                        /* CFString ==> straight ASCII */
                                                        cfd = CFStringCreateExternalRepresentation(NULL,
                                                                cfStr, kCFStringEncodingASCII, 0);
                                                        /* CFString ==> straight ASCII */
                                                        cfd = CFStringCreateExternalRepresentation(NULL,
                                                                cfStr, kCFStringEncodingASCII, 0);
@@ -605,10 +685,10 @@ static CSSM_BOOL tpCompareSubjectName(
                                                                tpPolicyError("tpCompareSubjectName: bad str (2)");
                                                                break;
                                                        }
                                                                tpPolicyError("tpCompareSubjectName: bad str (2)");
                                                                break;
                                                        }
-                                                       certNameLen = CFDataGetLength(cfd);
+                                                       certNameLen = (uint32)CFDataGetLength(cfd);
                                                        certName = (char *)CFDataGetBytePtr(cfd);
                                                }
                                                        certName = (char *)CFDataGetBytePtr(cfd);
                                                }
-                                               ourRtn = tpCompareHostNames(callerStr, callerStrLen, 
+                                               ourRtn = tpCompareHostNames(callerStr, callerStrLen,
                                                        certName, certNameLen);
                                                if(doConvert) {
                                                        assert(cfd != NULL);
                                                        certName, certNameLen);
                                                if(doConvert) {
                                                        assert(cfd != NULL);
@@ -620,6 +700,13 @@ static CSSM_BOOL tpCompareSubjectName(
                                                ourRtn = tpCompareEmailAddr(callerStr, callerStrLen,
                                                        certName, certNameLen, normalizeAll);
                                                break;
                                                ourRtn = tpCompareEmailAddr(callerStr, callerStrLen,
                                                        certName, certNameLen, normalizeAll);
                                                break;
+                                       case SN_UserID:
+                                       case SN_OrgUnit:
+                                               /* exact match only here, for now */
+                                               ourRtn = ((callerStrLen == certNameLen) &&
+                                                               !memcmp(callerStr, certName, certNameLen)) ?
+                                                               CSSM_TRUE : CSSM_FALSE;
+                                               break;
                                }
                                if(ourRtn) {
                                        /* success */
                                }
                                if(ourRtn) {
                                        /* success */
@@ -637,7 +724,7 @@ static CSSM_BOOL tpCompareSubjectName(
 }
 
 /*
 }
 
 /*
- * Compare ASCII form of an IP address to a CSSM_DATA containing 
+ * Compare ASCII form of an IP address to a CSSM_DATA containing
  * the IP address's numeric components. Returns true on match.
  */
 static CSSM_BOOL tpCompIpAddrStr(
  * the IP address's numeric components. Returns true on match.
  */
 static CSSM_BOOL tpCompIpAddrStr(
@@ -648,7 +735,7 @@ static CSSM_BOOL tpCompIpAddrStr(
        const char *cp = str;
        const char *nextDot;
        char buf[100];
        const char *cp = str;
        const char *nextDot;
        char buf[100];
-       
+
        if((numeric == NULL) || (numeric->Length == 0) || (str == NULL)) {
                return CSSM_FALSE;
        }
        if((numeric == NULL) || (numeric->Length == 0) || (str == NULL)) {
                return CSSM_FALSE;
        }
@@ -675,7 +762,7 @@ static CSSM_BOOL tpCompIpAddrStr(
                else if(dex == (numeric->Length - 1)) {
                        return CSSM_FALSE;
                }
                else if(dex == (numeric->Length - 1)) {
                        return CSSM_FALSE;
                }
-               unsigned digLen = nextDot - cp;
+               ptrdiff_t digLen = nextDot - cp;
                if(digLen >= sizeof(buf)) {
                        /* preposterous */
                        return CSSM_FALSE;
                if(digLen >= sizeof(buf)) {
                        /* preposterous */
                        return CSSM_FALSE;
@@ -694,20 +781,20 @@ static CSSM_BOOL tpCompIpAddrStr(
        return CSSM_TRUE;
 }
 
        return CSSM_TRUE;
 }
 
-/* 
- * See if cert's subjectAltName contains an element matching caller-specified 
+/*
+ * See if cert's subjectAltName contains an element matching caller-specified
  * string, hostname, in the following forms:
  *
  * SAN_HostName : dnsName, iPAddress
  * SAN_Email    : RFC822Name
  *
  * string, hostname, in the following forms:
  *
  * SAN_HostName : dnsName, iPAddress
  * SAN_Email    : RFC822Name
  *
- * Returns CSSM_TRUE if match, else returns CSSM_FALSE. 
+ * Returns CSSM_TRUE if match, else returns CSSM_FALSE.
  *
  * Also indicates whether or not a dnsName (search type HostName) or
  * RFC822Name (search type SAM_Email) was found, regardless of result
  *
  * Also indicates whether or not a dnsName (search type HostName) or
  * RFC822Name (search type SAM_Email) was found, regardless of result
- * of comparison. 
+ * of comparison.
  *
  *
- * The appStr/appStrLen args are optional - if NULL/0, only the 
+ * The appStr/appStrLen args are optional - if NULL/0, only the
  * search for dnsName/RFC822Name is done.
  */
 typedef enum {
  * search for dnsName/RFC822Name is done.
  */
 typedef enum {
@@ -720,7 +807,7 @@ static CSSM_BOOL tpCompareSubjectAltName(
        const char                              *appStr,                        // caller has lower-cased as appropriate
        uint32                                  appStrLen,
        SubjAltNameSearchType   searchType,
        const char                              *appStr,                        // caller has lower-cased as appropriate
        uint32                                  appStrLen,
        SubjAltNameSearchType   searchType,
-       bool                                    normalizeAll,           // for SAN_Email case: lower-case all of 
+       bool                                    normalizeAll,           // for SAN_Email case: lower-case all of
                                                                                                // the cert's value, not just the portion
                                                                                                // after the '@'
        bool                                    &dnsNameFound,          // RETURNED, SAN_HostName case
                                                                                                // the cert's value, not just the portion
                                                                                                // after the '@'
        bool                                    &dnsNameFound,          // RETURNED, SAN_HostName case
@@ -734,10 +821,10 @@ static CSSM_BOOL tpCompareSubjectAltName(
        }
 
        CE_GeneralNames *names = &subjAltNameInfo.extnData->subjectAltName;
        }
 
        CE_GeneralNames *names = &subjAltNameInfo.extnData->subjectAltName;
-       CSSM_BOOL               ourRtn = CSSM_FALSE;    
+       CSSM_BOOL               ourRtn = CSSM_FALSE;
        char                    *certName;
        char                    *certName;
-       unsigned                certNameLen;
-       
+       uint32                  certNameLen;
+
        /* Search thru the CE_GeneralNames looking for the appropriate attribute */
        for(unsigned dex=0; dex<names->numNames; dex++) {
                CE_GeneralName *name = &names->generalName[dex];
        /* Search thru the CE_GeneralNames looking for the appropriate attribute */
        for(unsigned dex=0; dex<names->numNames; dex++) {
                CE_GeneralName *name = &names->generalName[dex];
@@ -751,7 +838,7 @@ static CSSM_BOOL tpCompareSubjectAltName(
                                                }
                                                ourRtn = tpCompIpAddrStr(appStr, appStrLen, &name->name);
                                                break;
                                                }
                                                ourRtn = tpCompIpAddrStr(appStr, appStrLen, &name->name);
                                                break;
-                                               
+
                                        case GNT_DNSName:
                                                if(name->berEncoded) {
                                                        tpErrorLog("tpCompareSubjectAltName: malformed "
                                        case GNT_DNSName:
                                                if(name->berEncoded) {
                                                        tpErrorLog("tpCompareSubjectAltName: malformed "
@@ -764,21 +851,21 @@ static CSSM_BOOL tpCompareSubjectAltName(
                                                                "CE_GeneralName (2)\n");
                                                        break;
                                                }
                                                                "CE_GeneralName (2)\n");
                                                        break;
                                                }
-                                               certNameLen = name->name.Length;
+                                               certNameLen = (uint32)(name->name.Length);
                                                dnsNameFound = true;
                                                if(appStr != NULL) {
                                                        /* skip if caller passed in NULL */
                                                dnsNameFound = true;
                                                if(appStr != NULL) {
                                                        /* skip if caller passed in NULL */
-                                                       ourRtn = tpCompareHostNames(appStr, appStrLen, 
+                                                       ourRtn = tpCompareHostNames(appStr, appStrLen,
                                                                certName, certNameLen);
                                                }
                                                break;
                                                                certName, certNameLen);
                                                }
                                                break;
-               
+
                                        default:
                                                /* not interested, proceed to next name */
                                                break;
                                }
                                break;  /* from case HostName */
                                        default:
                                                /* not interested, proceed to next name */
                                                break;
                                }
                                break;  /* from case HostName */
-                               
+
                        case SAN_Email:
                                if(name->nameType != GNT_RFC822Name) {
                                        /* not interested */
                        case SAN_Email:
                                if(name->nameType != GNT_RFC822Name) {
                                        /* not interested */
@@ -790,10 +877,10 @@ static CSSM_BOOL tpCompareSubjectAltName(
                                                "GNT_RFC822Name\n");
                                        break;
                                }
                                                "GNT_RFC822Name\n");
                                        break;
                                }
-                               certNameLen = name->name.Length;
+                               certNameLen = (uint32)(name->name.Length);
                                emailFound = true;
                                if(appStr != NULL) {
                                emailFound = true;
                                if(appStr != NULL) {
-                                       ourRtn = tpCompareEmailAddr(appStr, appStrLen, certName, 
+                                       ourRtn = tpCompareEmailAddr(appStr, appStrLen, certName,
                                                certNameLen, normalizeAll);
                                }
                                break;
                                                certNameLen, normalizeAll);
                                }
                                break;
@@ -808,7 +895,7 @@ static CSSM_BOOL tpCompareSubjectAltName(
 
 /* is host name in the form of a.b.c.d, where a,b,c, and d are digits? */
 static CSSM_BOOL tpIsNumeric(
 
 /* is host name in the form of a.b.c.d, where a,b,c, and d are digits? */
 static CSSM_BOOL tpIsNumeric(
-       const char *hostName, 
+       const char *hostName,
        unsigned hostNameLen)
 {
        if(hostName[hostNameLen - 1] == '\0') {
        unsigned hostNameLen)
 {
        if(hostName[hostNameLen - 1] == '\0') {
@@ -828,7 +915,7 @@ static CSSM_BOOL tpIsNumeric(
 }
 
 /*
 }
 
 /*
- * Convert a typed string represented by a CSSM_X509_TYPE_VALUE_PAIR to a 
+ * Convert a typed string represented by a CSSM_X509_TYPE_VALUE_PAIR to a
  * CFStringRef. Caller owns and must release the result. NULL return means
  * unconvertible input "string".
  */
  * CFStringRef. Caller owns and must release the result. NULL return means
  * unconvertible input "string".
  */
@@ -852,7 +939,7 @@ static CFStringRef tpTvpToCfString(
                default:
                        return NULL;
        }
                default:
                        return NULL;
        }
-       
+
        /* raw data ==> CFString */
        CFDataRef cfd = CFDataCreate(NULL, tvp->value.Data,     tvp->value.Length);
        if(cfd == NULL) {
        /* raw data ==> CFString */
        CFDataRef cfd = CFDataCreate(NULL, tvp->value.Data,     tvp->value.Length);
        if(cfd == NULL) {
@@ -863,8 +950,8 @@ static CFStringRef tpTvpToCfString(
        return cfStr;
 }
 
        return cfStr;
 }
 
-/* 
- * Compare a CFString and a string represented by a CSSM_X509_TYPE_VALUE_PAIR. 
+/*
+ * Compare a CFString and a string represented by a CSSM_X509_TYPE_VALUE_PAIR.
  * Returns CSSM_TRUE if they are equal.
  */
 static bool tpCompareTvpToCfString(
  * Returns CSSM_TRUE if they are equal.
  */
 static bool tpCompareTvpToCfString(
@@ -889,7 +976,7 @@ static bool tpCompareTvpToCfString(
 /*
  * Given one iSignCertInfo, determine whether or not the specified
  * EKU OID, or - optionally - CSSMOID_ExtendedKeyUsageAny - is present.
 /*
  * Given one iSignCertInfo, determine whether or not the specified
  * EKU OID, or - optionally - CSSMOID_ExtendedKeyUsageAny - is present.
- * Returns true if so, else false. 
+ * Returns true if so, else false.
  */
 static bool tpVerifyEKU(
        const iSignCertInfo &certInfo,
  */
 static bool tpVerifyEKU(
        const iSignCertInfo &certInfo,
@@ -901,7 +988,7 @@ static bool tpVerifyEKU(
        }
        CE_ExtendedKeyUsage *eku = &certInfo.extendKeyUsage.extnData->extendedKeyUsage;
        assert(eku != NULL);
        }
        CE_ExtendedKeyUsage *eku = &certInfo.extendKeyUsage.extnData->extendedKeyUsage;
        assert(eku != NULL);
-       
+
        for(unsigned i=0; i<eku->numPurposes; i++) {
                const CSSM_OID *foundEku = &eku->purposes[i];
                if(tpCompareOids(foundEku, &ekuOid)) {
        for(unsigned i=0; i<eku->numPurposes; i++) {
                const CSSM_OID *foundEku = &eku->purposes[i];
                if(tpCompareOids(foundEku, &ekuOid)) {
@@ -942,8 +1029,8 @@ static bool tpVerifyCPE(
        return false;
 }
 
        return false;
 }
 
-/* 
- * Verify iChat handle. We search for a matching (case-insensitive) string 
+/*
+ * Verify iChat handle. We search for a matching (case-insensitive) string
  * comprised of:
  *
  *   -- name component ("dmitch") from subject name's CommonName
  * comprised of:
  *
  *   -- name component ("dmitch") from subject name's CommonName
@@ -965,13 +1052,13 @@ static bool tpCompareIChatHandleName(
        CSSM_X509_RDN_PTR               rdnp;
        unsigned                                        rdnDex;
        unsigned                                        pairDex;
        CSSM_X509_RDN_PTR               rdnp;
        unsigned                                        rdnDex;
        unsigned                                        pairDex;
-       
+
        /* search until all of these are true */
        CSSM_BOOL       commonNameMatch = CSSM_FALSE;           // name before '@'
        CSSM_BOOL       orgUnitMatch = CSSM_FALSE;                      // domain after '@
        CSSM_BOOL       orgMatch = CSSM_FALSE;                          // Apple Computer, Inc. (or Apple Inc.)
        /* search until all of these are true */
        CSSM_BOOL       commonNameMatch = CSSM_FALSE;           // name before '@'
        CSSM_BOOL       orgUnitMatch = CSSM_FALSE;                      // domain after '@
        CSSM_BOOL       orgMatch = CSSM_FALSE;                          // Apple Computer, Inc. (or Apple Inc.)
-       
-       /* 
+
+       /*
         * incoming UTF8 handle ==> two components.
         * First convert to CFString.
         */
         * incoming UTF8 handle ==> two components.
         * First convert to CFString.
         */
@@ -983,14 +1070,14 @@ static bool tpCompareIChatHandleName(
        if(cfd == NULL) {
                return false;
        }
        if(cfd == NULL) {
                return false;
        }
-       CFStringRef handleStr = CFStringCreateFromExternalRepresentation(NULL, cfd, 
+       CFStringRef handleStr = CFStringCreateFromExternalRepresentation(NULL, cfd,
                kCFStringEncodingUTF8);
        CFRelease(cfd);
        if(handleStr == NULL) {
                tpPolicyError("tpCompareIChatHandleName: bad incoming handle (1)");
                return false;
        }
                kCFStringEncodingUTF8);
        CFRelease(cfd);
        if(handleStr == NULL) {
                tpPolicyError("tpCompareIChatHandleName: bad incoming handle (1)");
                return false;
        }
-       
+
        /*
         * Find the '@' delimiter
         */
        /*
         * Find the '@' delimiter
         */
@@ -1001,9 +1088,9 @@ static bool tpCompareIChatHandleName(
                CFRelease(handleStr);
                return false;
        }
                CFRelease(handleStr);
                return false;
        }
-       
-       /* 
-        * Two components, before and after delimiter 
+
+       /*
+        * Two components, before and after delimiter
         */
        CFRange r = {0, whereIsAt.location};
        CFStringRef     iChatName = CFStringCreateWithSubstring(NULL, handleStr, r);
         */
        CFRange r = {0, whereIsAt.location};
        CFStringRef     iChatName = CFStringCreateWithSubstring(NULL, handleStr, r);
@@ -1022,7 +1109,7 @@ static bool tpCompareIChatHandleName(
                return false;
        }
        /* subsequent errors to errOut: */
                return false;
        }
        /* subsequent errors to errOut: */
-       
+
        /* get subject name in CSSM form, all subsequent ops work on that */
        crtn = cert.fetchField(&CSSMOID_X509V1SubjectNameCStruct, &subjNameData);
        if(crtn) {
        /* get subject name in CSSM form, all subsequent ops work on that */
        crtn = cert.fetchField(&CSSMOID_X509V1SubjectNameCStruct, &subjNameData);
        if(crtn) {
@@ -1030,7 +1117,7 @@ static bool tpCompareIChatHandleName(
                tpPolicyError("tpCompareIChatHandleName: error retrieving subject name");
                goto errOut;
        }
                tpPolicyError("tpCompareIChatHandleName: error retrieving subject name");
                goto errOut;
        }
-       
+
        x509name = (CSSM_X509_NAME_PTR)subjNameData->Data;
        if((x509name == NULL) || (subjNameData->Length != sizeof(CSSM_X509_NAME))) {
                tpPolicyError("tpCompareIChatHandleName: malformed CSSM_X509_NAME");
        x509name = (CSSM_X509_NAME_PTR)subjNameData->Data;
        if((x509name == NULL) || (subjNameData->Length != sizeof(CSSM_X509_NAME))) {
                tpPolicyError("tpCompareIChatHandleName: malformed CSSM_X509_NAME");
@@ -1038,31 +1125,31 @@ static bool tpCompareIChatHandleName(
        }
 
        /* Now grunge thru the X509 name looking for three fields */
        }
 
        /* Now grunge thru the X509 name looking for three fields */
-       
+
        for(rdnDex=0; rdnDex<x509name->numberOfRDNs; rdnDex++) {
                rdnp = &x509name->RelativeDistinguishedName[rdnDex];
                for(pairDex=0; pairDex<rdnp->numberOfPairs; pairDex++) {
                        ptvp = &rdnp->AttributeTypeAndValue[pairDex];
        for(rdnDex=0; rdnDex<x509name->numberOfRDNs; rdnDex++) {
                rdnp = &x509name->RelativeDistinguishedName[rdnDex];
                for(pairDex=0; pairDex<rdnp->numberOfPairs; pairDex++) {
                        ptvp = &rdnp->AttributeTypeAndValue[pairDex];
-                       if(!commonNameMatch && 
+                       if(!commonNameMatch &&
                           tpCompareOids(&ptvp->type, &CSSMOID_CommonName) &&
                           tpCompareTvpToCfString(ptvp, iChatName, kCFCompareCaseInsensitive)) {
                                        commonNameMatch = CSSM_TRUE;
                        }
                           tpCompareOids(&ptvp->type, &CSSMOID_CommonName) &&
                           tpCompareTvpToCfString(ptvp, iChatName, kCFCompareCaseInsensitive)) {
                                        commonNameMatch = CSSM_TRUE;
                        }
-                       
-                       if(!orgUnitMatch && 
+
+                       if(!orgUnitMatch &&
                           tpCompareOids(&ptvp->type, &CSSMOID_OrganizationalUnitName) &&
                           tpCompareTvpToCfString(ptvp, iChatDomain, kCFCompareCaseInsensitive)) {
                                        orgUnitMatch = CSSM_TRUE;
                        }
                           tpCompareOids(&ptvp->type, &CSSMOID_OrganizationalUnitName) &&
                           tpCompareTvpToCfString(ptvp, iChatDomain, kCFCompareCaseInsensitive)) {
                                        orgUnitMatch = CSSM_TRUE;
                        }
-                       
-                       if(!orgMatch && 
+
+                       if(!orgMatch &&
                           tpCompareOids(&ptvp->type, &CSSMOID_OrganizationName) &&
                           /* this one is case sensitive */
                           (tpCompareTvpToCfString(ptvp, CFSTR("Apple Computer, Inc."), 0) ||
                            tpCompareTvpToCfString(ptvp, CFSTR("Apple Inc."), 0))) {
                                        orgMatch = CSSM_TRUE;
                        }
                           tpCompareOids(&ptvp->type, &CSSMOID_OrganizationName) &&
                           /* this one is case sensitive */
                           (tpCompareTvpToCfString(ptvp, CFSTR("Apple Computer, Inc."), 0) ||
                            tpCompareTvpToCfString(ptvp, CFSTR("Apple Inc."), 0))) {
                                        orgMatch = CSSM_TRUE;
                        }
-                       
+
                        if(commonNameMatch && orgUnitMatch && orgMatch) {
                                /* TA DA */
                                ourRtn = true;
                        if(commonNameMatch && orgUnitMatch && orgMatch) {
                                /* TA DA */
                                ourRtn = true;
@@ -1078,7 +1165,7 @@ errOut:
 }
 
 /*
 }
 
 /*
- * Verify SSL options. Currently this just consists of matching the 
+ * Verify SSL options. Currently this just consists of matching the
  * leaf cert's subject common name against the caller's (optional)
  * server name.
  */
  * leaf cert's subject common name against the caller's (optional)
  * server name.
  */
@@ -1093,7 +1180,7 @@ static CSSM_RETURN tp_verifySslOpts(
        const char *serverName = NULL;
        TPCertInfo *leaf = certGroup.certAtIndex(0);
        assert(leaf != NULL);
        const char *serverName = NULL;
        TPCertInfo *leaf = certGroup.certAtIndex(0);
        assert(leaf != NULL);
-               
+
        /* CSSM_APPLE_TP_SSL_OPTIONS is optional */
        if((sslFieldOpts != NULL) && (sslFieldOpts->Data != NULL)) {
                sslOpts = (CSSM_APPLE_TP_SSL_OPTIONS *)sslFieldOpts->Data;
        /* CSSM_APPLE_TP_SSL_OPTIONS is optional */
        if((sslFieldOpts != NULL) && (sslFieldOpts->Data != NULL)) {
                sslOpts = (CSSM_APPLE_TP_SSL_OPTIONS *)sslFieldOpts->Data;
@@ -1110,7 +1197,7 @@ static CSSM_RETURN tp_verifySslOpts(
                hostNameLen = sslOpts->ServerNameLen;
                serverName = sslOpts->ServerName;
        }
                hostNameLen = sslOpts->ServerNameLen;
                serverName = sslOpts->ServerName;
        }
-       
+
        /* host name check is optional */
        if(hostNameLen != 0) {
                if(serverName == NULL) {
        /* host name check is optional */
        if(hostNameLen != 0) {
                if(serverName == NULL) {
@@ -1121,17 +1208,17 @@ static CSSM_RETURN tp_verifySslOpts(
                char *hostName = (char *)certGroup.alloc().malloc(hostNameLen);
                memmove(hostName, serverName, hostNameLen);
                tpToLower(hostName, hostNameLen);
                char *hostName = (char *)certGroup.alloc().malloc(hostNameLen);
                memmove(hostName, serverName, hostNameLen);
                tpToLower(hostName, hostNameLen);
-               
+
                CSSM_BOOL match = CSSM_FALSE;
                CSSM_BOOL match = CSSM_FALSE;
-               
+
                /* First check subjectAltName... */
                bool dnsNameFound = false;
                bool dummy;
                /* First check subjectAltName... */
                bool dnsNameFound = false;
                bool dummy;
-               match = tpCompareSubjectAltName(leafCertInfo.subjectAltName, 
-                       hostName, hostNameLen, 
+               match = tpCompareSubjectAltName(leafCertInfo.subjectAltName,
+                       hostName, hostNameLen,
                        SAN_HostName, false, dnsNameFound, dummy);
                        SAN_HostName, false, dnsNameFound, dummy);
-                       
-               /* 
+
+               /*
                 * Then common name, if
                 *  -- no match from subjectAltName, AND
                 *  -- dnsName was NOT found, AND
                 * Then common name, if
                 *  -- no match from subjectAltName, AND
                 *  -- dnsName was NOT found, AND
@@ -1142,17 +1229,17 @@ static CSSM_RETURN tp_verifySslOpts(
                        match = tpCompareSubjectName(*leaf, SN_CommonName, false, hostName, hostNameLen,
                                fieldFound);
                }
                        match = tpCompareSubjectName(*leaf, SN_CommonName, false, hostName, hostNameLen,
                                fieldFound);
                }
-               certGroup.alloc().free(hostName);       
+               certGroup.alloc().free(hostName);
                if(!match) {
                        if(leaf->addStatusCode(CSSMERR_APPLETP_HOSTNAME_MISMATCH)) {
                                return CSSMERR_APPLETP_HOSTNAME_MISMATCH;
                        }
                }
        }
                if(!match) {
                        if(leaf->addStatusCode(CSSMERR_APPLETP_HOSTNAME_MISMATCH)) {
                                return CSSMERR_APPLETP_HOSTNAME_MISMATCH;
                        }
                }
        }
-       
+
        /*
        /*
-        * Ensure that, if an extendedKeyUsage extension is present in the 
-        * leaf, that either anyExtendedKeyUsage or the appropriate 
+        * Ensure that, if an extendedKeyUsage extension is present in the
+        * leaf, that either anyExtendedKeyUsage or the appropriate
         * CSSMOID_{Server,Client}Auth, or a SeverGatedCrypto usage is present.
         */
        const iSignExtenInfo &ekuInfo = leafCertInfo.extendKeyUsage;
         * CSSMOID_{Server,Client}Auth, or a SeverGatedCrypto usage is present.
         */
        const iSignExtenInfo &ekuInfo = leafCertInfo.extendKeyUsage;
@@ -1162,8 +1249,8 @@ static CSSM_RETURN tp_verifySslOpts(
                CE_ExtendedKeyUsage *eku = (CE_ExtendedKeyUsage *)ekuInfo.extnData;
                assert(eku != NULL);
 
                CE_ExtendedKeyUsage *eku = (CE_ExtendedKeyUsage *)ekuInfo.extnData;
                assert(eku != NULL);
 
-               /* 
-                * Determine appropriate extended key usage; default is SSL server 
+               /*
+                * Determine appropriate extended key usage; default is SSL server
                 */
                const CSSM_OID *extUse = &CSSMOID_ServerAuth;
                if((sslOpts != NULL) &&                         /* optional, default server side */
                 */
                const CSSM_OID *extUse = &CSSMOID_ServerAuth;
                if((sslOpts != NULL) &&                         /* optional, default server side */
@@ -1210,10 +1297,10 @@ static CSSM_RETURN tp_verifySslOpts(
 }
 
 /*
 }
 
 /*
- * Verify SMIME and iChat options. 
+ * Verify SMIME and iChat options.
  * This deals with both S/MIME and iChat policies; within the iChat domain it
  * deals with Apple-specific .mac certs as well as what we call "generic AIM"
  * This deals with both S/MIME and iChat policies; within the iChat domain it
  * deals with Apple-specific .mac certs as well as what we call "generic AIM"
- * certs, as used in the Windows AIM client. 
+ * certs, as used in the Windows AIM client.
  */
 #define CE_CIPHER_MASK (~(CE_KU_EncipherOnly | CE_KU_DecipherOnly))
 
  */
 #define CE_CIPHER_MASK (~(CE_KU_EncipherOnly | CE_KU_DecipherOnly))
 
@@ -1224,8 +1311,8 @@ static CSSM_RETURN tp_verifySmimeOpts(
        const iSignCertInfo &leafCertInfo)
 {
        bool iChat = (policy == kTP_iChat) ? true : false;
        const iSignCertInfo &leafCertInfo)
 {
        bool iChat = (policy == kTP_iChat) ? true : false;
-       
-       /* 
+
+       /*
         * The CSSM_APPLE_TP_SMIME_OPTIONS pointer is optional as is everything in it.
         */
        CSSM_APPLE_TP_SMIME_OPTIONS *smimeOpts = NULL;
         * The CSSM_APPLE_TP_SMIME_OPTIONS pointer is optional as is everything in it.
         */
        CSSM_APPLE_TP_SMIME_OPTIONS *smimeOpts = NULL;
@@ -1235,7 +1322,7 @@ static CSSM_RETURN tp_verifySmimeOpts(
        if(smimeOpts != NULL) {
                switch(smimeOpts->Version) {
                        case CSSM_APPLE_TP_SMIME_OPTS_VERSION:
        if(smimeOpts != NULL) {
                switch(smimeOpts->Version) {
                        case CSSM_APPLE_TP_SMIME_OPTS_VERSION:
-                               if(smimeFieldOpts->Length != 
+                               if(smimeFieldOpts->Length !=
                                                sizeof(CSSM_APPLE_TP_SMIME_OPTIONS)) {
                                        return CSSMERR_TP_INVALID_POLICY_IDENTIFIERS;
                                }
                                                sizeof(CSSM_APPLE_TP_SMIME_OPTIONS)) {
                                        return CSSMERR_TP_INVALID_POLICY_IDENTIFIERS;
                                }
@@ -1245,7 +1332,7 @@ static CSSM_RETURN tp_verifySmimeOpts(
                                return CSSMERR_TP_INVALID_POLICY_IDENTIFIERS;
                }
        }
                                return CSSMERR_TP_INVALID_POLICY_IDENTIFIERS;
                }
        }
-       
+
        TPCertInfo *leaf = certGroup.certAtIndex(0);
        assert(leaf != NULL);
 
        TPCertInfo *leaf = certGroup.certAtIndex(0);
        assert(leaf != NULL);
 
@@ -1254,7 +1341,7 @@ static CSSM_RETURN tp_verifySmimeOpts(
        if(smimeOpts != NULL) {
                emailLen = smimeOpts->SenderEmailLen;
        }
        if(smimeOpts != NULL) {
                emailLen = smimeOpts->SenderEmailLen;
        }
-       
+
        bool match = false;
        bool emailFoundInSAN = false;
        bool iChatHandleFound = false;          /* indicates a genuine Apple iChat cert */
        bool match = false;
        bool emailFoundInSAN = false;
        bool iChatHandleFound = false;          /* indicates a genuine Apple iChat cert */
@@ -1266,39 +1353,39 @@ static CSSM_RETURN tp_verifySmimeOpts(
 
                /* iChat - first try the Apple custom format */
                if(iChat) {
 
                /* iChat - first try the Apple custom format */
                if(iChat) {
-                       iChatHandleFound = tpCompareIChatHandleName(*leaf,      smimeOpts->SenderEmail, 
+                       iChatHandleFound = tpCompareIChatHandleName(*leaf,      smimeOpts->SenderEmail,
                                emailLen);
                        if(iChatHandleFound) {
                                match = true;
                        }
                                emailLen);
                        if(iChatHandleFound) {
                                match = true;
                        }
-                       
+
                }
                }
-               
+
                if(!match) {
                if(!match) {
-                       /* 
-                        * normalize caller's email string 
+                       /*
+                        * normalize caller's email string
                         *  SMIME - lowercase only the portion after '@'
                         *  iChat - lowercase all of it
                         */
                        char *email = (char *)certGroup.alloc().malloc(emailLen);
                        memmove(email, smimeOpts->SenderEmail, emailLen);
                        tpNormalizeAddrSpec(email, emailLen, iChat);
                         *  SMIME - lowercase only the portion after '@'
                         *  iChat - lowercase all of it
                         */
                        char *email = (char *)certGroup.alloc().malloc(emailLen);
                        memmove(email, smimeOpts->SenderEmail, emailLen);
                        tpNormalizeAddrSpec(email, emailLen, iChat);
-                       
-                       
-                       /* 
+
+
+                       /*
                         * First check subjectAltName. The emailFound bool indicates
                         * that *some* email address was found, regardless of a match
                         * condition.
                         */
                        bool dummy;
                         * First check subjectAltName. The emailFound bool indicates
                         * that *some* email address was found, regardless of a match
                         * condition.
                         */
                        bool dummy;
-                       match = tpCompareSubjectAltName(leafCertInfo.subjectAltName, 
-                               email, emailLen, 
+                       match = tpCompareSubjectAltName(leafCertInfo.subjectAltName,
+                               email, emailLen,
                                SAN_Email, iChat, dummy, emailFoundInSAN);
                                SAN_Email, iChat, dummy, emailFoundInSAN);
-                       
-                       /* 
-                        * Then subject DN, CSSMOID_EmailAddress, if no match from 
-                        * subjectAltName. In this case the whole email address is 
-                        * case insensitive (RFC 3280, section 4.1.2.6), so 
+
+                       /*
+                        * Then subject DN, CSSMOID_EmailAddress, if no match from
+                        * subjectAltName. In this case the whole email address is
+                        * case insensitive (RFC 3280, section 4.1.2.6), so
                         * renormalize.
                         */
                        if(!match) {
                         * renormalize.
                         */
                        if(!match) {
@@ -1306,11 +1393,11 @@ static CSSM_RETURN tp_verifySmimeOpts(
                                match = tpCompareSubjectName(*leaf, SN_Email, true, email, emailLen,
                                        emailFoundInDN);
                        }
                                match = tpCompareSubjectName(*leaf, SN_Email, true, email, emailLen,
                                        emailFoundInDN);
                        }
-                       certGroup.alloc().free(email);  
-                       
+                       certGroup.alloc().free(email);
+
                        /*
                         * Error here if no match found but there was indeed *some*
                        /*
                         * Error here if no match found but there was indeed *some*
-                        * email address in the cert. 
+                        * email address in the cert.
                         */
                        if(!match && (emailFoundInSAN || emailFoundInDN)) {
                                if(leaf->addStatusCode(CSSMERR_APPLETP_SMIME_EMAIL_ADDRS_NOT_FOUND)) {
                         */
                        if(!match && (emailFoundInSAN || emailFoundInDN)) {
                                if(leaf->addStatusCode(CSSMERR_APPLETP_SMIME_EMAIL_ADDRS_NOT_FOUND)) {
@@ -1319,9 +1406,9 @@ static CSSM_RETURN tp_verifySmimeOpts(
                                }
                        }
                }
                                }
                        }
                }
-               
+
                /*
                /*
-                * iChat only: error if app specified email address but there was 
+                * iChat only: error if app specified email address but there was
                 * none in the cert.
                 */
                if(iChat && !emailFoundInSAN && !emailFoundInDN && !iChatHandleFound) {
                 * none in the cert.
                 */
                if(iChat && !emailFoundInSAN && !emailFoundInDN && !iChatHandleFound) {
@@ -1331,14 +1418,14 @@ static CSSM_RETURN tp_verifySmimeOpts(
                        }
                }
        }
                        }
                }
        }
-       
+
        /*
         * Going by the letter of the law, here's what RFC 2632 has to say
         * about the legality of an empty Subject Name:
         *
        /*
         * Going by the letter of the law, here's what RFC 2632 has to say
         * about the legality of an empty Subject Name:
         *
-        *    ...the subject DN in a user's (i.e. end-entity) certificate MAY 
-        *    be an empty SEQUENCE in which case the subjectAltName extension 
-        *    will include the subject's identifier and MUST be marked as 
+        *    ...the subject DN in a user's (i.e. end-entity) certificate MAY
+        *    be an empty SEQUENCE in which case the subjectAltName extension
+        *    will include the subject's identifier and MUST be marked as
         *    critical.
         *
         * OK, first examine the leaf cert's subject name.
         *    critical.
         *
         * OK, first examine the leaf cert's subject name.
@@ -1348,12 +1435,12 @@ static CSSM_RETURN tp_verifySmimeOpts(
        const iSignExtenInfo &kuInfo = leafCertInfo.keyUsage;
        const iSignExtenInfo &ekuInfo = leafCertInfo.extendKeyUsage;
        const CSSM_X509_NAME *x509Name = NULL;
        const iSignExtenInfo &kuInfo = leafCertInfo.keyUsage;
        const iSignExtenInfo &ekuInfo = leafCertInfo.extendKeyUsage;
        const CSSM_X509_NAME *x509Name = NULL;
-       
+
        if(iChat) {
                /* empty subject name processing is S/MIME only */
                goto checkEku;
        }
        if(iChat) {
                /* empty subject name processing is S/MIME only */
                goto checkEku;
        }
-       
+
        crtn = leaf->fetchField(&CSSMOID_X509V1SubjectNameCStruct, &subjNameData);
        if(crtn) {
                /* This should really never happen */
        crtn = leaf->fetchField(&CSSMOID_X509V1SubjectNameCStruct, &subjNameData);
        if(crtn) {
                /* This should really never happen */
@@ -1362,21 +1449,21 @@ static CSSM_RETURN tp_verifySmimeOpts(
                return CSSMERR_TP_INVALID_CERTIFICATE;
        }
        /* must do a leaf->freeField(&CSSMOID_X509V1SubjectNameCStruct on exit */
                return CSSMERR_TP_INVALID_CERTIFICATE;
        }
        /* must do a leaf->freeField(&CSSMOID_X509V1SubjectNameCStruct on exit */
-       
+
        x509Name = (const CSSM_X509_NAME *)subjNameData->Data;
        if(x509Name->numberOfRDNs == 0) {
        x509Name = (const CSSM_X509_NAME *)subjNameData->Data;
        if(x509Name->numberOfRDNs == 0) {
-               /* 
-                * Empty subject name. If we haven't already seen a valid 
+               /*
+                * Empty subject name. If we haven't already seen a valid
                 * email address in the subject alternate name (by looking
                 * email address in the subject alternate name (by looking
-                * for a specific address specified by app), try to find 
+                * for a specific address specified by app), try to find
                 * one now.
                 */
                if(!emailFoundInSAN &&          // haven't found one, and
                   (emailLen == 0)) {           // didn't even look yet
                        bool dummy;
                 * one now.
                 */
                if(!emailFoundInSAN &&          // haven't found one, and
                   (emailLen == 0)) {           // didn't even look yet
                        bool dummy;
-                       tpCompareSubjectAltName(leafCertInfo.subjectAltName, 
-                                       NULL, 0,                                // email, emailLen, 
-                                       SAN_Email, false, dummy, 
+                       tpCompareSubjectAltName(leafCertInfo.subjectAltName,
+                                       NULL, 0,                                // email, emailLen,
+                                       SAN_Email, false, dummy,
                                        emailFoundInSAN);               // the variable we're updating
                }
                if(!emailFoundInSAN) {
                                        emailFoundInSAN);               // the variable we're updating
                }
                if(!emailFoundInSAN) {
@@ -1391,7 +1478,7 @@ static CSSM_RETURN tp_verifySmimeOpts(
                                goto postSAN;
                        }
                }
                                goto postSAN;
                        }
                }
-               
+
                /*
                 * One more thing: this leaf must indeed have a subjAltName
                 * extension and it must be critical. We would not have gotten this
                /*
                 * One more thing: this leaf must indeed have a subjAltName
                 * extension and it must be critical. We would not have gotten this
@@ -1409,7 +1496,7 @@ static CSSM_RETURN tp_verifySmimeOpts(
        }
 postSAN:
        leaf->freeField(&CSSMOID_X509V1SubjectNameCStruct, subjNameData);
        }
 postSAN:
        leaf->freeField(&CSSMOID_X509V1SubjectNameCStruct, subjNameData);
-        
+
        /*
         * Enforce the usage of the key associated with the leaf cert.
         * Cert's KeyUsage must be a superset of what the app is trying to do.
        /*
         * Enforce the usage of the key associated with the leaf cert.
         * Cert's KeyUsage must be a superset of what the app is trying to do.
@@ -1426,15 +1513,15 @@ postSAN:
                                return CSSMERR_TP_VERIFY_ACTION_FAILED;
                        }
                }
                                return CSSMERR_TP_VERIFY_ACTION_FAILED;
                        }
                }
-               
+
                /* Now the en/de cipher only bits - for keyAgreement only */
                if(appKu & CE_KU_KeyAgreement) {
                /* Now the en/de cipher only bits - for keyAgreement only */
                if(appKu & CE_KU_KeyAgreement) {
-                       /* 
+                       /*
                         * 1. App wants to use this for key agreement; it must
                         *    say what it wants to do with the derived key.
                         *    In this context, the app's XXXonly bit means that
                         *    it wants to use the key for that op - not necessarliy
                         * 1. App wants to use this for key agreement; it must
                         *    say what it wants to do with the derived key.
                         *    In this context, the app's XXXonly bit means that
                         *    it wants to use the key for that op - not necessarliy
-                        *    "only". 
+                        *    "only".
                         */
                        if((appKu & (CE_KU_EncipherOnly | CE_KU_DecipherOnly)) == 0) {
                                tpPolicyError("SMIME KeyUsage err: KeyAgreement with "
                         */
                        if((appKu & (CE_KU_EncipherOnly | CE_KU_DecipherOnly)) == 0) {
                                tpPolicyError("SMIME KeyUsage err: KeyAgreement with "
@@ -1443,12 +1530,12 @@ postSAN:
                                        return CSSMERR_TP_VERIFY_ACTION_FAILED;
                                }
                        }
                                        return CSSMERR_TP_VERIFY_ACTION_FAILED;
                                }
                        }
-                       
+
                        /*
                         * 2. If cert restricts to encipher only make sure the
                         *    app isn't trying to decipher.
                         */
                        /*
                         * 2. If cert restricts to encipher only make sure the
                         *    app isn't trying to decipher.
                         */
-                       if((certKu & CE_KU_EncipherOnly) && 
+                       if((certKu & CE_KU_EncipherOnly) &&
                           (appKu & CE_KU_DecipherOnly)) {
                                tpPolicyError("SMIME KeyUsage err: cert EncipherOnly, "
                                        "app wants to decipher");
                           (appKu & CE_KU_DecipherOnly)) {
                                tpPolicyError("SMIME KeyUsage err: cert EncipherOnly, "
                                        "app wants to decipher");
@@ -1456,12 +1543,12 @@ postSAN:
                                        return CSSMERR_TP_VERIFY_ACTION_FAILED;
                                }
                        }
                                        return CSSMERR_TP_VERIFY_ACTION_FAILED;
                                }
                        }
-                       
+
                        /*
                         * 3. If cert restricts to decipher only make sure the
                         *    app isn't trying to encipher.
                         */
                        /*
                         * 3. If cert restricts to decipher only make sure the
                         *    app isn't trying to encipher.
                         */
-                       if((certKu & CE_KU_DecipherOnly) && 
+                       if((certKu & CE_KU_DecipherOnly) &&
                           (appKu & CE_KU_EncipherOnly)) {
                                tpPolicyError("SMIME KeyUsage err: cert DecipherOnly, "
                                        "app wants to encipher");
                           (appKu & CE_KU_EncipherOnly)) {
                                tpPolicyError("SMIME KeyUsage err: cert DecipherOnly, "
                                        "app wants to encipher");
@@ -1471,16 +1558,16 @@ postSAN:
                        }
                }
        }
                        }
                }
        }
-       
+
        /*
        /*
-        * Extended Key Use verification, which is different for the two policies. 
+        * Extended Key Use verification, which is different for the two policies.
         */
 checkEku:
        if(iChat && !ekuInfo.present) {
         */
 checkEku:
        if(iChat && !ekuInfo.present) {
-               /* 
-                * iChat: whether generic AIM cert or Apple .mac/iChat cert, we must have an 
-                * extended key use extension. 
-                */ 
+               /*
+                * iChat: whether generic AIM cert or Apple .mac/iChat cert, we must have an
+                * extended key use extension.
+                */
                tpPolicyError("iChat: No extended Key Use");
                if(leaf->addStatusCode(CSSMERR_APPLETP_SMIME_BAD_EXT_KEY_USE)) {
                        return CSSMERR_APPLETP_SMIME_BAD_EXT_KEY_USE;
                tpPolicyError("iChat: No extended Key Use");
                if(leaf->addStatusCode(CSSMERR_APPLETP_SMIME_BAD_EXT_KEY_USE)) {
                        return CSSMERR_APPLETP_SMIME_BAD_EXT_KEY_USE;
@@ -1488,13 +1575,13 @@ checkEku:
        }
 
        if(!iChatHandleFound) {
        }
 
        if(!iChatHandleFound) {
-               /* 
+               /*
                 * S/MIME and generic AIM certs when evaluating iChat policy.
                 * Look for either emailProtection or anyExtendedKeyUsage usages.
                 *
                 * S/MIME and generic AIM certs when evaluating iChat policy.
                 * Look for either emailProtection or anyExtendedKeyUsage usages.
                 *
-                * S/MIME : the whole extension is optional. 
-                * iChat  : extension must be there (which we've already covered, above) 
-                *          and we must find one of those extensions. 
+                * S/MIME : the whole extension is optional.
+                * iChat  : extension must be there (which we've already covered, above)
+                *          and we must find one of those extensions.
                 */
                if(ekuInfo.present) {
                        bool foundGoodEku = false;
                 */
                if(ekuInfo.present) {
                        bool foundGoodEku = false;
@@ -1519,7 +1606,7 @@ checkEku:
                }
        }
        else {
                }
        }
        else {
-               /* 
+               /*
                 * Apple iChat cert. Look for anyExtendedKeyUsage, iChatSigning,
                 * ichatEncrypting - the latter of two which can optionally be
                 * required by app.
                 * Apple iChat cert. Look for anyExtendedKeyUsage, iChatSigning,
                 * ichatEncrypting - the latter of two which can optionally be
                 * required by app.
@@ -1531,13 +1618,13 @@ checkEku:
                bool foundISignEncrypt = false;
                CE_ExtendedKeyUsage *eku = (CE_ExtendedKeyUsage *)ekuInfo.extnData;
                assert(eku != NULL);
                bool foundISignEncrypt = false;
                CE_ExtendedKeyUsage *eku = (CE_ExtendedKeyUsage *)ekuInfo.extnData;
                assert(eku != NULL);
-               
+
                for(unsigned i=0; i<eku->numPurposes; i++) {
                for(unsigned i=0; i<eku->numPurposes; i++) {
-                       if(tpCompareOids(&eku->purposes[i], 
+                       if(tpCompareOids(&eku->purposes[i],
                                        &CSSMOID_APPLE_EKU_ICHAT_SIGNING)) {
                                foundIChatSign = true;
                        }
                                        &CSSMOID_APPLE_EKU_ICHAT_SIGNING)) {
                                foundIChatSign = true;
                        }
-                       else if(tpCompareOids(&eku->purposes[i], 
+                       else if(tpCompareOids(&eku->purposes[i],
                                        &CSSMOID_APPLE_EKU_ICHAT_ENCRYPTION)) {
                                foundISignEncrypt = true;
                        }
                                        &CSSMOID_APPLE_EKU_ICHAT_ENCRYPTION)) {
                                foundISignEncrypt = true;
                        }
@@ -1545,7 +1632,7 @@ checkEku:
                                foundAnyEku = true;
                        }
                }
                                foundAnyEku = true;
                        }
                }
-               
+
                if(!foundAnyEku && !foundISignEncrypt && !foundIChatSign) {
                        /* No go - no acceptable uses found */
                        tpPolicyError("iChat: No valid extended Key Uses found");
                if(!foundAnyEku && !foundISignEncrypt && !foundIChatSign) {
                        /* No go - no acceptable uses found */
                        tpPolicyError("iChat: No valid extended Key Uses found");
@@ -1553,7 +1640,7 @@ checkEku:
                                return CSSMERR_APPLETP_SMIME_BAD_EXT_KEY_USE;
                        }
                }
                                return CSSMERR_APPLETP_SMIME_BAD_EXT_KEY_USE;
                        }
                }
-               
+
                /* check for specifically required uses */
                if((smimeOpts != NULL) && (smimeOpts->IntendedUsage != 0)) {
                        if(smimeOpts->IntendedUsage & CE_KU_DigitalSignature) {
                /* check for specifically required uses */
                if((smimeOpts != NULL) && (smimeOpts->IntendedUsage != 0)) {
                        if(smimeOpts->IntendedUsage & CE_KU_DigitalSignature) {
@@ -1574,30 +1661,30 @@ checkEku:
                        }
                }       /* checking IntendedUsage */
        }       /* iChat cert format */
                        }
                }       /* checking IntendedUsage */
        }       /* iChat cert format */
-        
+
        return CSSM_OK;
 }
 
 /*
        return CSSM_OK;
 }
 
 /*
- * Verify Apple SW Update signing (was Apple Code Signing, pre-Leopard) options. 
+ * Verify Apple SW Update signing (was Apple Code Signing, pre-Leopard) options.
  *
  * -- Must have one intermediate cert
  * -- intermediate must have basic constraints with path length 0
  * -- intermediate has CSSMOID_APPLE_EKU_CODE_SIGNING EKU
  *
  * -- Must have one intermediate cert
  * -- intermediate must have basic constraints with path length 0
  * -- intermediate has CSSMOID_APPLE_EKU_CODE_SIGNING EKU
- * -- leaf cert has either CODE_SIGNING or CODE_SIGN_DEVELOPMENT EKU (the latter of 
+ * -- leaf cert has either CODE_SIGNING or CODE_SIGN_DEVELOPMENT EKU (the latter of
  *    which triggers a CSSMERR_APPLETP_CODE_SIGN_DEVELOPMENT error)
  */
 static CSSM_RETURN tp_verifySWUpdateSigningOpts(
        TPCertGroup &certGroup,
        const CSSM_DATA *fieldOpts,                     // currently unused
  *    which triggers a CSSMERR_APPLETP_CODE_SIGN_DEVELOPMENT error)
  */
 static CSSM_RETURN tp_verifySWUpdateSigningOpts(
        TPCertGroup &certGroup,
        const CSSM_DATA *fieldOpts,                     // currently unused
-       const iSignCertInfo *certInfo)          // all certs, size certGroup.numCerts() 
+       const iSignCertInfo *certInfo)          // all certs, size certGroup.numCerts()
 {
        unsigned numCerts = certGroup.numCerts();
        const iSignCertInfo *isCertInfo;
        TPCertInfo *tpCert;
 //     const CE_BasicConstraints *bc;          // currently unused
        CE_ExtendedKeyUsage *eku;
 {
        unsigned numCerts = certGroup.numCerts();
        const iSignCertInfo *isCertInfo;
        TPCertInfo *tpCert;
 //     const CE_BasicConstraints *bc;          // currently unused
        CE_ExtendedKeyUsage *eku;
-       CSSM_RETURN crtn = CSSM_OK;     
+       CSSM_RETURN crtn = CSSM_OK;
 
        if(numCerts != 3) {
                if(!certGroup.isAllowedError(CSSMERR_APPLETP_CS_BAD_CERT_CHAIN_LENGTH)) {
 
        if(numCerts != 3) {
                if(!certGroup.isAllowedError(CSSMERR_APPLETP_CS_BAD_CERT_CHAIN_LENGTH)) {
@@ -1635,7 +1722,7 @@ static CSSM_RETURN tp_verifySWUpdateSigningOpts(
        eku = &isCertInfo->extendKeyUsage.extnData->extendedKeyUsage;
        assert(eku != NULL);
        if(eku->numPurposes != 1) {
        eku = &isCertInfo->extendKeyUsage.extnData->extendedKeyUsage;
        assert(eku != NULL);
        if(eku->numPurposes != 1) {
-               tpPolicyError("tp_verifySWUpdateSigningOpts: bad eku->numPurposes in intermediate (%lu)", 
+               tpPolicyError("tp_verifySWUpdateSigningOpts: bad eku->numPurposes in intermediate (%lu)",
                        (unsigned long)eku->numPurposes);
                if(tpCert->addStatusCode(CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE)) {
                        return CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE;
                        (unsigned long)eku->numPurposes);
                if(tpCert->addStatusCode(CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE)) {
                        return CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE;
@@ -1646,7 +1733,7 @@ static CSSM_RETURN tp_verifySWUpdateSigningOpts(
                }
                /* else ignore error and we have an intermediate EKU; proceed */
        }
                }
                /* else ignore error and we have an intermediate EKU; proceed */
        }
-               
+
        if(!tpCompareOids(&eku->purposes[0], &CSSMOID_APPLE_EKU_CODE_SIGNING)) {
                tpPolicyError("tp_verifySWUpdateSigningOpts: bad EKU");
                if(tpCert->addStatusCode(CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE)) {
        if(!tpCompareOids(&eku->purposes[0], &CSSMOID_APPLE_EKU_CODE_SIGNING)) {
                tpPolicyError("tp_verifySWUpdateSigningOpts: bad EKU");
                if(tpCert->addStatusCode(CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE)) {
@@ -1673,7 +1760,7 @@ checkLeaf:
        eku = &isCertInfo->extendKeyUsage.extnData->extendedKeyUsage;
        assert(eku != NULL);
        if(eku->numPurposes != 1) {
        eku = &isCertInfo->extendKeyUsage.extnData->extendedKeyUsage;
        assert(eku != NULL);
        if(eku->numPurposes != 1) {
-               tpPolicyError("tp_verifySWUpdateSigningOpts: bad eku->numPurposes (%lu)", 
+               tpPolicyError("tp_verifySWUpdateSigningOpts: bad eku->numPurposes (%lu)",
                        (unsigned long)eku->numPurposes);
                if(tpCert->addStatusCode(CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE)) {
                        if(crtn == CSSM_OK) {
                        (unsigned long)eku->numPurposes);
                if(tpCert->addStatusCode(CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE)) {
                        if(crtn == CSSM_OK) {
@@ -1705,7 +1792,7 @@ checkLeaf:
 }
 
 /*
 }
 
 /*
- * Verify Apple Resource Signing options. 
+ * Verify Apple Resource Signing options.
  *
  * -- leaf cert must have CSSMOID_APPLE_EKU_RESOURCE_SIGNING EKU
  * -- chain length must be >= 2
  *
  * -- leaf cert must have CSSMOID_APPLE_EKU_RESOURCE_SIGNING EKU
  * -- chain length must be >= 2
@@ -1714,7 +1801,7 @@ checkLeaf:
 static CSSM_RETURN tp_verifyResourceSigningOpts(
        TPCertGroup &certGroup,
        const CSSM_DATA *fieldOpts,                     // currently unused
 static CSSM_RETURN tp_verifyResourceSigningOpts(
        TPCertGroup &certGroup,
        const CSSM_DATA *fieldOpts,                     // currently unused
-       const iSignCertInfo *certInfo)          // all certs, size certGroup.numCerts() 
+       const iSignCertInfo *certInfo)          // all certs, size certGroup.numCerts()
 {
        unsigned numCerts = certGroup.numCerts();
        if(numCerts < 2) {
 {
        unsigned numCerts = certGroup.numCerts();
        if(numCerts < 2) {
@@ -1725,7 +1812,7 @@ static CSSM_RETURN tp_verifyResourceSigningOpts(
        }
        const iSignCertInfo &leafCert = certInfo[0];
        TPCertInfo *leaf = certGroup.certAtIndex(0);
        }
        const iSignCertInfo &leafCert = certInfo[0];
        TPCertInfo *leaf = certGroup.certAtIndex(0);
-       
+
        /* leaf ExtendedKeyUse required, one legal value */
        if(!tpVerifyEKU(leafCert, CSSMOID_APPLE_EKU_RESOURCE_SIGNING, false)) {
                tpPolicyError("tp_verifyResourceSigningOpts: no RESOURCE_SIGNING EKU");
        /* leaf ExtendedKeyUse required, one legal value */
        if(!tpVerifyEKU(leafCert, CSSMOID_APPLE_EKU_RESOURCE_SIGNING, false)) {
                tpPolicyError("tp_verifyResourceSigningOpts: no RESOURCE_SIGNING EKU");
@@ -1737,16 +1824,16 @@ static CSSM_RETURN tp_verifyResourceSigningOpts(
        return CSSM_OK;
 }
 
        return CSSM_OK;
 }
 
-/* 
+/*
  * Common code for Apple Code Signing and Apple Package Signing.
  * For now we just require an RFC3280-style CodeSigning EKU in the leaf
  * for both policies.
  */
 static CSSM_RETURN tp_verifyCodePkgSignOpts(
  * Common code for Apple Code Signing and Apple Package Signing.
  * For now we just require an RFC3280-style CodeSigning EKU in the leaf
  * for both policies.
  */
 static CSSM_RETURN tp_verifyCodePkgSignOpts(
-       TPPolicy policy, 
+       TPPolicy policy,
        TPCertGroup &certGroup,
        const CSSM_DATA *fieldOpts,                     // currently unused
        TPCertGroup &certGroup,
        const CSSM_DATA *fieldOpts,                     // currently unused
-       const iSignCertInfo *certInfo)          // all certs, size certGroup.numCerts() 
+       const iSignCertInfo *certInfo)          // all certs, size certGroup.numCerts()
 {
        const iSignCertInfo &leafCert = certInfo[0];
 
 {
        const iSignCertInfo &leafCert = certInfo[0];
 
@@ -1764,27 +1851,27 @@ static CSSM_RETURN tp_verifyCodePkgSignOpts(
 }
 
 /*
 }
 
 /*
- * Verify MacAppStore receipt verification policy options. 
+ * Verify MacAppStore receipt verification policy options.
  *
  * -- Must have one intermediate cert
  * -- intermediate must be the FairPlay intermediate
  * -- leaf cert has the CSSMOID_APPLE_EXTENSION_MACAPPSTORE_RECEIPT marker extension
  */
  *
  * -- Must have one intermediate cert
  * -- intermediate must be the FairPlay intermediate
  * -- leaf cert has the CSSMOID_APPLE_EXTENSION_MACAPPSTORE_RECEIPT marker extension
  */
-static CSSM_RETURN tp_verifyMacAppStoreReciptOpts(
+static CSSM_RETURN tp_verifyMacAppStoreReceiptOpts(
        TPCertGroup &certGroup,
        const CSSM_DATA *fieldOpts,                     // currently unused
        TPCertGroup &certGroup,
        const CSSM_DATA *fieldOpts,                     // currently unused
-       const iSignCertInfo *certInfo)          // all certs, size certGroup.numCerts() 
+       const iSignCertInfo *certInfo)          // all certs, size certGroup.numCerts()
 {
        unsigned numCerts = certGroup.numCerts();
        if (numCerts < 3)
        {
                if (!certGroup.isAllowedError(CSSMERR_APPLETP_CS_BAD_CERT_CHAIN_LENGTH))
                {
 {
        unsigned numCerts = certGroup.numCerts();
        if (numCerts < 3)
        {
                if (!certGroup.isAllowedError(CSSMERR_APPLETP_CS_BAD_CERT_CHAIN_LENGTH))
                {
-                       tpPolicyError("tp_verifyMacAppStoreReciptOpts: numCerts %u", numCerts);
+                       tpPolicyError("tp_verifyMacAppStoreReceiptOpts: numCerts %u", numCerts);
                        return CSSMERR_APPLETP_CS_BAD_CERT_CHAIN_LENGTH;
                }
        }
                        return CSSMERR_APPLETP_CS_BAD_CERT_CHAIN_LENGTH;
                }
        }
-       
+
        const iSignCertInfo *isCertInfo;
        TPCertInfo *tpCert;
 
        const iSignCertInfo *isCertInfo;
        TPCertInfo *tpCert;
 
@@ -1804,8 +1891,8 @@ static CSSM_RETURN tp_verifyMacAppStoreReciptOpts(
        tpCert = certGroup.certAtIndex(0);
        if (certInfo->certificatePolicies.present)
        {
        tpCert = certGroup.certAtIndex(0);
        if (certInfo->certificatePolicies.present)
        {
-       //      syslog(LOG_ERR, "tp_verifyMacAppStoreReciptOpts: found certificatePolicies");
-               const CE_CertPolicies *certPolicies = 
+       //      syslog(LOG_ERR, "tp_verifyMacAppStoreReceiptOpts: found certificatePolicies");
+               const CE_CertPolicies *certPolicies =
                                &isCertInfo->certificatePolicies.extnData->certPolicies;
                if (!certificatePoliciesContainsOID(certPolicies, &CSSMOID_MACAPPSTORE_RECEIPT_CERT_POLICY))
                        if (tpCert->addStatusCode(CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION))
                                &isCertInfo->certificatePolicies.extnData->certPolicies;
                if (!certificatePoliciesContainsOID(certPolicies, &CSSMOID_MACAPPSTORE_RECEIPT_CERT_POLICY))
                        if (tpCert->addStatusCode(CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION))
@@ -1813,19 +1900,19 @@ static CSSM_RETURN tp_verifyMacAppStoreReciptOpts(
        }
        else
        {
        }
        else
        {
-       //      syslog(LOG_ERR, "tp_verifyMacAppStoreReciptOpts: no certificatePolicies present");      // DEBUG
-        tpPolicyError("tp_verifyMacAppStoreReciptOpts: no certificatePolicies present in leaf");
+       //      syslog(LOG_ERR, "tp_verifyMacAppStoreReceiptOpts: no certificatePolicies present");     // DEBUG
+        tpPolicyError("tp_verifyMacAppStoreReceiptOpts: no certificatePolicies present in leaf");
         if (tpCert->addStatusCode(CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION))
                        return CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION;
        }
         if (tpCert->addStatusCode(CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION))
                        return CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION;
        }
-               
+
        return CSSM_OK;
 }
 
 bool certificatePoliciesContainsOID(const CE_CertPolicies *certPolicies, const CSSM_OID *oidToFind)
 {
     // returns true if the given OID is present in the cert policies
        return CSSM_OK;
 }
 
 bool certificatePoliciesContainsOID(const CE_CertPolicies *certPolicies, const CSSM_OID *oidToFind)
 {
     // returns true if the given OID is present in the cert policies
-    
+
     if (!certPolicies || !oidToFind)
                return false;
 
     if (!certPolicies || !oidToFind)
                return false;
 
@@ -1837,13 +1924,13 @@ bool certificatePoliciesContainsOID(const CE_CertPolicies *certPolicies, const C
                if (oid && tpCompareOids(oid, oidToFind))       // found it
                        return true;
     }
                if (oid && tpCompareOids(oid, oidToFind))       // found it
                        return true;
     }
-       
+
        return false;
 }
 
 
 /*
        return false;
 }
 
 
 /*
- * Verify Apple ID Sharing options. 
+ * Verify Apple ID Sharing options.
  *
  * -- Do basic cert validation (OCSP-based certs)
  * -- Validate that the cert is an Apple ID sharing cert:
  *
  * -- Do basic cert validation (OCSP-based certs)
  * -- Validate that the cert is an Apple ID sharing cert:
@@ -1852,7 +1939,7 @@ bool certificatePoliciesContainsOID(const CE_CertPolicies *certPolicies, const C
  *             EKU should have both client and server authentication
  *             chains to the "Apple Application Integration Certification Authority" intermediate
  * -- optionally has a client-specified common name, which is the Apple ID account's UUID.
  *             EKU should have both client and server authentication
  *             chains to the "Apple Application Integration Certification Authority" intermediate
  * -- optionally has a client-specified common name, which is the Apple ID account's UUID.
+
  * -- Must have one intermediate cert ("Apple Application Integration Certification Authority")
  * -- intermediate must have basic constraints with path length 0
  * -- intermediate has CSSMOID_APPLE_EXTENSION_AAI_INTERMEDIATE extension (OID 1 2 840 113635 100 6 2 3)
  * -- Must have one intermediate cert ("Apple Application Integration Certification Authority")
  * -- intermediate must have basic constraints with path length 0
  * -- intermediate has CSSMOID_APPLE_EXTENSION_AAI_INTERMEDIATE extension (OID 1 2 840 113635 100 6 2 3)
@@ -1861,14 +1948,14 @@ bool certificatePoliciesContainsOID(const CE_CertPolicies *certPolicies, const C
 
 static CSSM_RETURN tp_verifyAppleIDSharingOpts(TPCertGroup &certGroup,
                                                                                                const CSSM_DATA *fieldOpts,                     // optional Common Name
 
 static CSSM_RETURN tp_verifyAppleIDSharingOpts(TPCertGroup &certGroup,
                                                                                                const CSSM_DATA *fieldOpts,                     // optional Common Name
-                                                                                               const iSignCertInfo *certInfo)          // all certs, size certGroup.numCerts() 
+                                                                                               const iSignCertInfo *certInfo)          // all certs, size certGroup.numCerts()
 {
        unsigned numCerts = certGroup.numCerts();
        const iSignCertInfo *isCertInfo;
        TPCertInfo *tpCert;
        //      const CE_BasicConstraints *bc;          // currently unused
        CE_ExtendedKeyUsage *eku;
 {
        unsigned numCerts = certGroup.numCerts();
        const iSignCertInfo *isCertInfo;
        TPCertInfo *tpCert;
        //      const CE_BasicConstraints *bc;          // currently unused
        CE_ExtendedKeyUsage *eku;
-       CSSM_RETURN crtn = CSSM_OK;     
+       CSSM_RETURN crtn = CSSM_OK;
        unsigned int serverNameLen = 0;
        const char *serverName = NULL;
 
        unsigned int serverNameLen = 0;
        const char *serverName = NULL;
 
@@ -1906,11 +1993,11 @@ static CSSM_RETURN tp_verifyAppleIDSharingOpts(TPCertGroup &certGroup,
                        goto checkLeaf;
                }
        }
                        goto checkLeaf;
                }
        }
-       
+
        /* verify intermediate cert */
        isCertInfo = &certInfo[1];
        tpCert = certGroup.certAtIndex(1);
        /* verify intermediate cert */
        isCertInfo = &certInfo[1];
        tpCert = certGroup.certAtIndex(1);
-       
+
        if (!isCertInfo->basicConstraints.present)
        {
                tpPolicyError("tp_verifyAppleIDSharingOpts: no basicConstraints in intermediate");
        if (!isCertInfo->basicConstraints.present)
        {
                tpPolicyError("tp_verifyAppleIDSharingOpts: no basicConstraints in intermediate");
@@ -1919,7 +2006,7 @@ static CSSM_RETURN tp_verifyAppleIDSharingOpts(TPCertGroup &certGroup,
        }
 
 checkLeaf:
        }
 
 checkLeaf:
-       
+
        /* verify leaf cert */
        isCertInfo = &certInfo[0];
        tpCert = certGroup.certAtIndex(0);
        /* verify leaf cert */
        isCertInfo = &certInfo[0];
        tpCert = certGroup.certAtIndex(0);
@@ -1929,26 +2016,26 @@ checkLeaf:
        {
                if (serverName == NULL)
                        return CSSMERR_TP_INVALID_POINTER;
        {
                if (serverName == NULL)
                        return CSSMERR_TP_INVALID_POINTER;
-               
+
                /* convert caller's hostname string to lower case */
                char *hostName = (char *)certGroup.alloc().malloc(serverNameLen);
                memmove(hostName, serverName, serverNameLen);
                tpToLower(hostName, serverNameLen);
                /* convert caller's hostname string to lower case */
                char *hostName = (char *)certGroup.alloc().malloc(serverNameLen);
                memmove(hostName, serverName, serverNameLen);
                tpToLower(hostName, serverNameLen);
-                               
+
                /* Check common name... */
 
                bool fieldFound;
                /* Check common name... */
 
                bool fieldFound;
-               CSSM_BOOL match = tpCompareSubjectName(*tpCert, SN_CommonName, false, hostName, 
+               CSSM_BOOL match = tpCompareSubjectName(*tpCert, SN_CommonName, false, hostName,
                                                                         serverNameLen, fieldFound);
 
                                                                         serverNameLen, fieldFound);
 
-               certGroup.alloc().free(hostName);       
+               certGroup.alloc().free(hostName);
                if (!match && tpCert->addStatusCode(CSSMERR_APPLETP_HOSTNAME_MISMATCH))
             return CSSMERR_APPLETP_HOSTNAME_MISMATCH;
        }
 
        if (certInfo->certificatePolicies.present)
        {
                if (!match && tpCert->addStatusCode(CSSMERR_APPLETP_HOSTNAME_MISMATCH))
             return CSSMERR_APPLETP_HOSTNAME_MISMATCH;
        }
 
        if (certInfo->certificatePolicies.present)
        {
-               const CE_CertPolicies *certPolicies = 
+               const CE_CertPolicies *certPolicies =
                                &isCertInfo->certificatePolicies.extnData->certPolicies;
                if (!certificatePoliciesContainsOID(certPolicies, &CSSMOID_APPLEID_SHARING_CERT_POLICY))
                        if (tpCert->addStatusCode(CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION))
                                &isCertInfo->certificatePolicies.extnData->certPolicies;
                if (!certificatePoliciesContainsOID(certPolicies, &CSSMOID_APPLEID_SHARING_CERT_POLICY))
                        if (tpCert->addStatusCode(CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION))
@@ -1973,7 +2060,7 @@ checkLeaf:
        assert(eku != NULL);
        if(eku->numPurposes != 2)
        {
        assert(eku != NULL);
        if(eku->numPurposes != 2)
        {
-               tpPolicyError("tp_verifyAppleIDSharingOpts: bad eku->numPurposes (%lu)", 
+               tpPolicyError("tp_verifyAppleIDSharingOpts: bad eku->numPurposes (%lu)",
                                          (unsigned long)eku->numPurposes);
                if (tpCert->addStatusCode(CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE))
                {
                                          (unsigned long)eku->numPurposes);
                if (tpCert->addStatusCode(CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE))
                {
@@ -1996,7 +2083,7 @@ checkLeaf:
                        break;
                }
        }
                        break;
                }
        }
-       
+
        if (!(canDoClientAuth && canDoServerAuth))
                ekuError = true;
        if (ekuError)
        if (!(canDoClientAuth && canDoServerAuth))
                ekuError = true;
        if (ekuError)
@@ -2008,7 +2095,7 @@ checkLeaf:
                                crtn = CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE;
                }
        }
                                crtn = CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE;
                }
        }
-       
+
        return crtn;
 }
 
        return crtn;
 }
 
@@ -2020,9 +2107,9 @@ checkLeaf:
  */
 static CSSM_RETURN tp_verifyTimeStampingOpts(TPCertGroup &certGroup,
                                                                                         const CSSM_DATA *fieldOpts,            // currently unused
  */
 static CSSM_RETURN tp_verifyTimeStampingOpts(TPCertGroup &certGroup,
                                                                                         const CSSM_DATA *fieldOpts,            // currently unused
-                                                                                        const iSignCertInfo *certInfo)         // all certs, size certGroup.numCerts() 
+                                                                                        const iSignCertInfo *certInfo)         // all certs, size certGroup.numCerts()
 {
 {
-       unsigned numCerts = certGroup.numCerts();
+    //unsigned numCerts = certGroup.numCerts();
        const iSignCertInfo *isCertInfo;
        TPCertInfo *tpCert;
        CE_ExtendedKeyUsage *eku;
        const iSignCertInfo *isCertInfo;
        TPCertInfo *tpCert;
        CE_ExtendedKeyUsage *eku;
@@ -2065,6 +2152,407 @@ static CSSM_RETURN tp_verifyTimeStampingOpts(TPCertGroup &certGroup,
        return CSSM_OK;
 }
 
        return CSSM_OK;
 }
 
+/*
+ * Verify Passbook Signing policy options.
+ *
+ * -- Do basic cert validation (OCSP-based certs)
+ * -- Chains to the Apple root CA
+ * -- Has custom marker extension (1.2.840.113635.100.6.1.16)
+ *             (CSSMOID_APPLE_EXTENSION_PASSBOOK_SIGNING)
+ * -- EKU contains Passbook Signing purpose (1.2.840.113635.100.4.14)
+ *             (CSSMOID_APPLE_EKU_PASSBOOK_SIGNING)
+ * -- UID field of Subject must contain provided card signer string
+ * -- OU field of Subject must contain provided team identifier string
+ */
+static CSSM_RETURN tp_verifyPassbookSigningOpts(TPCertGroup &certGroup,
+                                                                                        const CSSM_DATA *fieldOpts,
+                                                                                        const iSignCertInfo *certInfo)         // all certs, size certGroup.numCerts()
+{
+       unsigned numCerts = certGroup.numCerts();
+       const iSignCertInfo *isCertInfo;
+       TPCertInfo *tpCert;
+       CE_ExtendedKeyUsage *eku;
+       CSSM_RETURN crtn = CSSM_OK;
+       unsigned int nameLen = 0;
+       const char *name = NULL;
+       char *p, *signerName = NULL, *teamIdentifier = NULL;
+       bool found;
+
+       isCertInfo = &certInfo[0];
+       tpCert = certGroup.certAtIndex(0);
+
+       /* The CSSM_APPLE_TP_SMIME_OPTIONS pointer is required. */
+    if (!fieldOpts || !fieldOpts->Data)
+               return CSSMERR_TP_INVALID_POLICY_IDENTIFIERS;
+    else {
+               CSSM_APPLE_TP_SMIME_OPTIONS *opts = (CSSM_APPLE_TP_SMIME_OPTIONS *)fieldOpts->Data;
+        switch (opts->Version)
+        {
+        case CSSM_APPLE_TP_SMIME_OPTS_VERSION:
+            if (fieldOpts->Length != sizeof(CSSM_APPLE_TP_SMIME_OPTIONS))
+                return CSSMERR_TP_INVALID_POLICY_IDENTIFIERS;
+            break;
+            /* handle backwards compatibility here if necessary */
+        default:
+            return CSSMERR_TP_INVALID_POLICY_IDENTIFIERS;
+               }
+               nameLen = opts->SenderEmailLen;
+               name = opts->SenderEmail;
+               if (!name || !nameLen)
+                       return CSSMERR_APPLETP_IDENTIFIER_MISSING;
+       }
+
+       /* Split the provided name into signer name and team identifier
+        * (allocates memory, which must be freed at end) */
+       signerName = (char *)certGroup.alloc().malloc(nameLen);
+       teamIdentifier = (char *)certGroup.alloc().malloc(nameLen);
+       memmove(signerName, name, nameLen);
+       teamIdentifier[0] = '\0';
+       if ((p = strchr(signerName, '\t')) != NULL) {
+               *p++ = '\0';
+               memmove(teamIdentifier, p, strlen(p)+1);
+       }
+
+       /* Check signer name in UID field */
+       if (CSSM_FALSE == tpCompareSubjectName(*tpCert,
+               SN_UserID, false, signerName, (unsigned int)strlen(signerName), found)) {
+               tpPolicyError("tp_verifyPassbookSigningOpts: signer name not in subject UID field");
+               tpCert->addStatusCode(CSSMERR_APPLETP_IDENTIFIER_MISSING);
+               crtn = CSSMERR_APPLETP_IDENTIFIER_MISSING;
+               goto cleanup;
+       }
+
+       /* Check team identifier in OU field */
+       if (CSSM_FALSE == tpCompareSubjectName(*tpCert,
+               SN_OrgUnit, false, teamIdentifier, (unsigned int)strlen(teamIdentifier), found)) {
+               tpPolicyError("tp_verifyPassbookSigningOpts: team identifier not in subject OU field");
+               tpCert->addStatusCode(CSSMERR_APPLETP_IDENTIFIER_MISSING);
+               crtn = CSSMERR_APPLETP_IDENTIFIER_MISSING;
+               goto cleanup;
+       }
+
+       /* Check that EKU extension is present */
+       if (!isCertInfo->extendKeyUsage.present) {
+               tpPolicyError("tp_verifyPassbookSigningOpts: no extendedKeyUse in leaf");
+               tpCert->addStatusCode(CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION);
+               crtn = CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION;
+               goto cleanup;
+       }
+
+       /* Check that EKU contains Passbook Signing purpose */
+       eku = &isCertInfo->extendKeyUsage.extnData->extendedKeyUsage;
+       assert(eku != NULL);
+       found = false;
+       for (int ix=0;ix<eku->numPurposes;ix++) {
+               if (tpCompareOids(&eku->purposes[ix], &CSSMOID_APPLE_EKU_PASSBOOK_SIGNING)) {
+                       found = true;
+                       break;
+               }
+       }
+       if (!found) {
+               tpPolicyError("tp_verifyPassbookSigningOpts: Passbook Signing purpose not found");
+               tpCert->addStatusCode(CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE);
+               crtn = CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE;
+               goto cleanup;
+       }
+
+       /* Check that Passbook Signing marker extension is present */
+       if (!(isCertInfo->foundPassbookSigning == CSSM_TRUE)) {
+               tpPolicyError("tp_verifyPassbookSigningOpts: no Passbook Signing extension in leaf");
+               tpCert->addStatusCode(CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION);
+               crtn = CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION;
+               goto cleanup;
+       }
+
+       /* Check that cert chain is anchored by the Apple Root CA */
+       if (numCerts < 3) {
+               tpPolicyError("tp_verifyPassbookSigningOpts: numCerts %u", numCerts);
+               crtn = CSSMERR_APPLETP_CS_BAD_CERT_CHAIN_LENGTH;
+               goto cleanup;
+       }
+       else {
+               tpCert = certGroup.certAtIndex(numCerts-1);
+               const CSSM_DATA *certData = tpCert->itemData();
+               unsigned char digest[CC_SHA1_DIGEST_LENGTH];
+               CC_SHA1(certData->Data, (CC_LONG)certData->Length, digest);
+               if (memcmp(digest, kAppleCASHA1, sizeof(digest))) {
+                       tpPolicyError("tp_verifyPassbookSigningOpts: invalid anchor for policy");
+                       tpCert->addStatusCode(CSSMERR_APPLETP_CS_BAD_CERT_CHAIN_LENGTH);
+                       crtn = CSSMERR_APPLETP_CS_BAD_CERT_CHAIN_LENGTH;
+                       goto cleanup;
+               }
+       }
+
+cleanup:
+       if (signerName)
+               certGroup.alloc().free(signerName);
+       if (teamIdentifier)
+               certGroup.alloc().free(teamIdentifier);
+
+       return crtn;
+}
+
+/*
+ * Verify Mobile Store policy options.
+ *
+ * -- Do basic cert validation.
+ * -- Chain length must be exactly 3.
+ * -- Must chain to known Mobile Store root.
+ * -- Intermediate must have CSSMOID_APPLE_EXTENSION_SYSINT2_INTERMEDIATE marker
+ *             (1.2.840.113635.100.6.2.10)
+ * -- Key usage in leaf certificate must be Digital Signature.
+ * -- Leaf has certificatePolicies extension with appropriate policy:
+ *             (1.2.840.113635.100.5.12) if testPolicy is false
+ *             (1.2.840.113635.100.5.12.1) if testPolicy is true
+ */
+static CSSM_RETURN tp_verifyMobileStoreSigningOpts(TPCertGroup &certGroup,
+                                                                                        const CSSM_DATA *fieldOpts,
+                                                                                        const iSignCertInfo *certInfo,         // all certs, size certGroup.numCerts()
+                                                                                        bool testPolicy)
+{
+       unsigned numCerts = certGroup.numCerts();
+       const iSignCertInfo *isCertInfo;
+       TPCertInfo *tpCert;
+       CE_KeyUsage ku;
+       CSSM_RETURN crtn = CSSM_OK;
+
+       isCertInfo = &certInfo[0];
+       tpCert = certGroup.certAtIndex(0);
+
+       /* Check that KU extension is present */
+       if (!isCertInfo->keyUsage.present) {
+               tpPolicyError("tp_verifyMobileStoreSigningOpts: no keyUsage in leaf");
+               tpCert->addStatusCode(CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION);
+               crtn = CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION;
+               goto cleanup;
+       }
+
+       /* Check that KU contains Digital Signature usage */
+       ku = isCertInfo->keyUsage.extnData->keyUsage;
+       if (!(ku & CE_KU_DigitalSignature)) {
+               tpPolicyError("tp_verifyMobileStoreSigningOpts: DigitalSignature usage not found");
+               tpCert->addStatusCode(CSSMERR_APPLETP_INVALID_KEY_USAGE);
+               crtn = CSSMERR_APPLETP_INVALID_KEY_USAGE;
+               goto cleanup;
+       }
+
+       /* Check that Mobile Store Signing certicate policy is present in leaf */
+       if (isCertInfo->certificatePolicies.present)
+       {
+               const CE_CertPolicies *certPolicies =
+                               &isCertInfo->certificatePolicies.extnData->certPolicies;
+               const CSSM_OID *policyOID = (testPolicy) ?
+                               &CSSMOID_TEST_MOBILE_STORE_SIGNING_POLICY :
+                               &CSSMOID_MOBILE_STORE_SIGNING_POLICY;
+               if (!certificatePoliciesContainsOID(certPolicies, policyOID))
+                       if (tpCert->addStatusCode(CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION))
+                               return CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION;
+       }
+       else
+       {
+        tpPolicyError("tp_verifyMobileStoreSigningOpts: no certificatePolicies present in leaf");
+        if (tpCert->addStatusCode(CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION))
+                       return CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION;
+       }
+
+       /* Check that cert chain length is 3 */
+       if (numCerts != 3) {
+               tpPolicyError("tp_verifyMobileStoreSigningOpts: numCerts %u", numCerts);
+               crtn = CSSMERR_APPLETP_CS_BAD_CERT_CHAIN_LENGTH;
+               goto cleanup;
+       }
+
+       /* Check that cert chain is anchored by a known root */
+       {
+               tpCert = certGroup.certAtIndex(numCerts-1);
+               const CSSM_DATA *certData = tpCert->itemData();
+               unsigned char digest[CC_SHA1_DIGEST_LENGTH];
+               CC_SHA1(certData->Data, (CC_LONG)certData->Length, digest);
+               if (memcmp(digest, kMobileRootSHA1, sizeof(digest))) {
+                       tpPolicyError("tp_verifyMobileStoreSigningOpts: invalid anchor for policy");
+                       tpCert->addStatusCode(CSSMERR_APPLETP_CS_BAD_CERT_CHAIN_LENGTH);
+                       crtn = CSSMERR_APPLETP_CS_BAD_CERT_CHAIN_LENGTH;
+                       goto cleanup;
+               }
+       }
+
+       /* Check that Apple System Integration 2 marker extension is present in intermediate */
+       isCertInfo = &certInfo[1];
+       tpCert = certGroup.certAtIndex(1);
+       if (!(isCertInfo->foundAppleSysInt2Marker == CSSM_TRUE)) {
+               tpPolicyError("tp_verifyMobileStoreSigningOpts: intermediate marker extension not found");
+               tpCert->addStatusCode(CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION);
+               crtn = CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION;
+               goto cleanup;
+       }
+
+cleanup:
+       return crtn;
+}
+
+/*
+ * Verify Escrow Service policy options.
+ *
+ * -- Chain length must be exactly 2.
+ * -- Must be issued by known escrow root.
+ * -- Key usage in leaf certificate must be Key Encipherment.
+ * -- Leaf has CSSMOID_APPLE_EXTENSION_ESCROW_SERVICE_MARKER extension
+ *             (1.2.840.113635.100.6.23.1)
+ */
+static CSSM_RETURN tp_verifyEscrowServiceSigningOpts(TPCertGroup &certGroup,
+                                                                                        const CSSM_DATA *fieldOpts,
+                                                                                        const iSignCertInfo *certInfo)         // all certs, size certGroup.numCerts()
+{
+       unsigned numCerts = certGroup.numCerts();
+       const iSignCertInfo *isCertInfo;
+       TPCertInfo *tpCert;
+       CE_KeyUsage ku;
+       CSSM_RETURN crtn = CSSM_OK;
+
+       isCertInfo = &certInfo[0];
+       tpCert = certGroup.certAtIndex(0);
+
+       /* Check that KU extension is present */
+       if (!isCertInfo->keyUsage.present) {
+               tpPolicyError("tp_verifyEscrowServiceSigningOpts: no keyUsage in leaf");
+               tpCert->addStatusCode(CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION);
+               crtn = CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION;
+               goto cleanup;
+       }
+
+       /* Check that KU contains Key Encipherment usage */
+       ku = isCertInfo->keyUsage.extnData->keyUsage;
+       if (!(ku & CE_KU_KeyEncipherment)) {
+               tpPolicyError("tp_verifyEscrowServiceSigningOpts: KeyEncipherment usage not found");
+               tpCert->addStatusCode(CSSMERR_APPLETP_INVALID_KEY_USAGE);
+               crtn = CSSMERR_APPLETP_INVALID_KEY_USAGE;
+               goto cleanup;
+       }
+
+       /* Check that Escrow Service marker extension is present */
+       if (!(isCertInfo->foundEscrowServiceMarker == CSSM_TRUE)) {
+               tpPolicyError("tp_verifyEscrowServiceSigningOpts: no Escrow Service extension in leaf");
+               tpCert->addStatusCode(CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION);
+               crtn = CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION;
+               goto cleanup;
+       }
+
+       /* Check that cert chain length is 2 */
+       if (numCerts != 2) {
+               tpPolicyError("tp_verifyEscrowServiceSigningOpts: numCerts %u", numCerts);
+               crtn = CSSMERR_APPLETP_CS_BAD_CERT_CHAIN_LENGTH;
+               goto cleanup;
+       }
+
+       /* Check that cert chain is anchored by a known root */
+       {
+               tpCert = certGroup.certAtIndex(numCerts-1);
+               const CSSM_DATA *certData = tpCert->itemData();
+               bool anchorMatch = false;
+               SecCertificateRef anchor = NULL;
+               OSStatus status = SecCertificateCreateFromData(certData, CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER, &anchor);
+               if (!status) {
+                       CFArrayRef anchors = SecCertificateCopyEscrowRoots(kSecCertificateProductionEscrowRoot);
+                       CFIndex idx, count = (anchors) ? CFArrayGetCount(anchors) : 0;
+                       for (idx = 0; idx < count; idx++) {
+                               SecCertificateRef cert = (SecCertificateRef) CFArrayGetValueAtIndex(anchors, idx);
+                               if (cert && CFEqual(cert, anchor)) {
+                                       anchorMatch = true;
+                                       break;
+                               }
+                       }
+                       if (anchors)
+                               CFRelease(anchors);
+               }
+               if (anchor)
+                       CFRelease(anchor);
+
+               if (!anchorMatch) {
+                       tpPolicyError("tp_verifyEscrowServiceSigningOpts: invalid anchor for policy");
+                       tpCert->addStatusCode(CSSMERR_APPLETP_CS_BAD_CERT_CHAIN_LENGTH);
+                       crtn = CSSMERR_APPLETP_CS_BAD_CERT_CHAIN_LENGTH;
+                       goto cleanup;
+               }
+       }
+
+cleanup:
+       return crtn;
+}
+
+/*
+ * Verify Configuration Profile Signing policy options.
+ *
+ * -- Do basic cert validation (OCSP-based certs)
+ * -- Chains to the Apple root CA
+ * -- Leaf has EKU extension with appropriate purpose:
+ *             (1.2.840.113635.100.4.16) if testPolicy is false
+ *             (1.2.840.113635.100.4.17) if testPolicy is true
+ */
+static CSSM_RETURN tp_verifyProfileSigningOpts(TPCertGroup &certGroup,
+                                                                                        const CSSM_DATA *fieldOpts,
+                                                                                        const iSignCertInfo *certInfo,         // all certs, size certGroup.numCerts()
+                                                                                        bool testPolicy)
+{
+       unsigned numCerts = certGroup.numCerts();
+       const iSignCertInfo *isCertInfo;
+       TPCertInfo *tpCert;
+       CE_ExtendedKeyUsage *eku;
+       CSSM_RETURN crtn = CSSM_OK;
+       bool found;
+
+       isCertInfo = &certInfo[0];
+       tpCert = certGroup.certAtIndex(0);
+
+       /* Check that EKU extension is present */
+       if (!isCertInfo->extendKeyUsage.present) {
+               tpPolicyError("tp_verifyProfileSigningOpts: no extendedKeyUse in leaf");
+               tpCert->addStatusCode(CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION);
+               crtn = CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION;
+               goto cleanup;
+       }
+
+       /* Check that EKU contains appropriate Profile Signing purpose */
+       eku = &isCertInfo->extendKeyUsage.extnData->extendedKeyUsage;
+       assert(eku != NULL);
+       found = false;
+       for (int ix=0;ix<eku->numPurposes;ix++) {
+               if (tpCompareOids(&eku->purposes[ix], (testPolicy) ?
+                       &CSSMOID_APPLE_EKU_QA_PROFILE_SIGNING :
+                       &CSSMOID_APPLE_EKU_PROFILE_SIGNING)) {
+                       found = true;
+                       break;
+               }
+       }
+       if (!found) {
+               tpPolicyError("tp_verifyProfileSigningOpts: Profile Signing purpose not found");
+               tpCert->addStatusCode(CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE);
+               crtn = CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE;
+               goto cleanup;
+       }
+
+       /* Check that cert chain is anchored by the Apple Root CA */
+       if (numCerts < 3) {
+               tpPolicyError("tp_verifyProfileSigningOpts: numCerts %u", numCerts);
+               crtn = CSSMERR_APPLETP_CS_BAD_CERT_CHAIN_LENGTH;
+               goto cleanup;
+       }
+       else {
+               tpCert = certGroup.certAtIndex(numCerts-1);
+               const CSSM_DATA *certData = tpCert->itemData();
+               unsigned char digest[CC_SHA1_DIGEST_LENGTH];
+               CC_SHA1(certData->Data, (CC_LONG)certData->Length, digest);
+               if (memcmp(digest, kAppleCASHA1, sizeof(digest))) {
+                       tpPolicyError("tp_verifyProfileSigningOpts: invalid anchor for policy");
+                       tpCert->addStatusCode(CSSMERR_APPLETP_CS_BAD_CERT_CHAIN_LENGTH);
+                       crtn = CSSMERR_APPLETP_CS_BAD_CERT_CHAIN_LENGTH;
+                       goto cleanup;
+               }
+       }
+
+cleanup:
+       return crtn;
+}
+
 /*
  * RFC2459 says basicConstraints must be flagged critical for
  * CA certs, but Verisign doesn't work that way.
 /*
  * RFC2459 says basicConstraints must be flagged critical for
  * CA certs, but Verisign doesn't work that way.
@@ -2073,13 +2561,13 @@ static CSSM_RETURN tp_verifyTimeStampingOpts(TPCertGroup &certGroup,
 
 /*
  * TP iSign spec says Extended Key Usage required for leaf certs,
 
 /*
  * TP iSign spec says Extended Key Usage required for leaf certs,
- * but Verisign doesn't work that way. 
+ * 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,
  */
 #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. 
+ * but Verisign doesn't work that way.
  */
 #define SUBJECT_ALT_NAME_REQUIRED_FOR_LEAF             0
 
  */
 #define SUBJECT_ALT_NAME_REQUIRED_FOR_LEAF             0
 
@@ -2091,23 +2579,23 @@ static CSSM_RETURN tp_verifyTimeStampingOpts(TPCertGroup &certGroup,
 
 /*
  * RFC 2632, "S/MIME Version 3 Certificate Handling", section
 
 /*
  * RFC 2632, "S/MIME Version 3 Certificate Handling", section
- * 4.4.2, says that KeyUsage extensions MUST be flagged critical, 
- * but Thawte's intermediate cert (common name "Thawte Personal 
+ * 4.4.2, says that KeyUsage extensions MUST be flagged critical,
+ * but Thawte's intermediate cert (common name "Thawte Personal
  * Freemail Issuing CA") does not meet this requirement.
  */
 #define SMIME_KEY_USAGE_MUST_BE_CRITICAL               0
 
 /*
  * Freemail Issuing CA") does not meet this requirement.
  */
 #define SMIME_KEY_USAGE_MUST_BE_CRITICAL               0
 
 /*
- * Public routine to perform TP verification on a constructed 
+ * Public routine to perform TP verification on a constructed
  * cert group.
  * Returns CSSM_OK on success.
  * Assumes the chain has passed basic subject/issuer verification. First cert of
  * cert group.
  * Returns CSSM_OK on success.
  * Assumes the chain has passed basic subject/issuer verification. First cert of
- * incoming certGroup is end-entity (leaf). 
+ * 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.
  *
  * 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. 
+ *   kTPx509Basic: CertGroup of length one allowed.
  */
 CSSM_RETURN tp_policyVerify(
        TPPolicy                                                policy,
  */
 CSSM_RETURN tp_policyVerify(
        TPPolicy                                                policy,
@@ -2116,7 +2604,7 @@ CSSM_RETURN tp_policyVerify(
        CSSM_CSP_HANDLE                                 cspHand,
        TPCertGroup                                     *certGroup,
        CSSM_BOOL                                               verifiedToRoot,         // last cert is good root
        CSSM_CSP_HANDLE                                 cspHand,
        TPCertGroup                                     *certGroup,
        CSSM_BOOL                                               verifiedToRoot,         // last cert is good root
-       CSSM_BOOL                                               verifiedViaTrustSetting,        // last cert verified via 
+       CSSM_BOOL                                               verifiedViaTrustSetting,        // last cert verified via
                                                                                                                        //     user trust
        CSSM_APPLE_TP_ACTION_FLAGS              actionFlags,
        const CSSM_DATA                                 *policyFieldData,       // optional
                                                                                                                        //     user trust
        CSSM_APPLE_TP_ACTION_FLAGS              actionFlags,
        const CSSM_DATA                                 *policyFieldData,       // optional
@@ -2137,12 +2625,12 @@ CSSM_RETURN tp_policyVerify(
        CSSM_RETURN                             outErr = CSSM_OK;               // for gross, non-policy errors
        CSSM_BOOL                               policyFail = CSSM_FALSE;// generic CSSMERR_TP_VERIFY_ACTION_FAILED
        CSSM_RETURN                             policyError = CSSM_OK;  // policy-specific failure
        CSSM_RETURN                             outErr = CSSM_OK;               // for gross, non-policy errors
        CSSM_BOOL                               policyFail = CSSM_FALSE;// generic CSSMERR_TP_VERIFY_ACTION_FAILED
        CSSM_RETURN                             policyError = CSSM_OK;  // policy-specific failure
-       
+
        /* First, kTPDefault is a nop here */
        if(policy == kTPDefault) {
                return CSSM_OK;
        }
        /* First, kTPDefault is a nop here */
        if(policy == kTPDefault) {
                return CSSM_OK;
        }
-       
+
        if(certGroup == NULL) {
                return CSSMERR_TP_INVALID_CERTGROUP;
        }
        if(certGroup == NULL) {
                return CSSMERR_TP_INVALID_CERTGROUP;
        }
@@ -2160,33 +2648,33 @@ CSSM_RETURN tp_policyVerify(
                        return CSSMERR_TP_VERIFY_ACTION_FAILED;
                }
        }
                        return CSSMERR_TP_VERIFY_ACTION_FAILED;
                }
        }
-       
+
        /* cook up an iSignCertInfo array */
        certInfo = (iSignCertInfo *)tpCalloc(alloc, numCerts, sizeof(iSignCertInfo));
        /* subsequent errors to errOut: */
        /* 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++) {
        /* fill it with interesting info from parsed certs */
        for(certDex=0; certDex<numCerts; certDex++) {
-               if(iSignGetCertInfo(alloc, 
-                               certGroup->certAtIndex(certDex),                
+               if(iSignGetCertInfo(alloc,
+                               certGroup->certAtIndex(certDex),
                                &certInfo[certDex])) {
                        (certGroup->certAtIndex(certDex))->addStatusCode(
                                CSSMERR_TP_INVALID_CERTIFICATE);
                        /* this one is fatal (and can't ignore) */
                        outErr = CSSMERR_TP_INVALID_CERTIFICATE;
                        goto errOut;
                                &certInfo[certDex])) {
                        (certGroup->certAtIndex(certDex))->addStatusCode(
                                CSSMERR_TP_INVALID_CERTIFICATE);
                        /* this one is fatal (and can't ignore) */
                        outErr = CSSMERR_TP_INVALID_CERTIFICATE;
                        goto errOut;
-               }       
+               }
        }
        }
-               
+
        /*
         * OK, the heart of TP enforcement.
         */
        for(certDex=0; certDex<numCerts; certDex++) {
                thisCertInfo = &certInfo[certDex];
                TPCertInfo *thisTpCertInfo = certGroup->certAtIndex(certDex);
        /*
         * OK, the heart of TP enforcement.
         */
        for(certDex=0; certDex<numCerts; certDex++) {
                thisCertInfo = &certInfo[certDex];
                TPCertInfo *thisTpCertInfo = certGroup->certAtIndex(certDex);
-               
+
                /*
                /*
-                * First check for presence of required extensions and 
+                * First check for presence of required extensions and
                 * critical extensions we don't understand.
                 */
                if(thisCertInfo->foundUnknownCritical) {
                 * critical extensions we don't understand.
                 */
                if(thisCertInfo->foundUnknownCritical) {
@@ -2196,7 +2684,7 @@ CSSM_RETURN tp_policyVerify(
                                policyFail = CSSM_TRUE;
                        }
                }
                                policyFail = CSSM_TRUE;
                        }
                }
-               
+
                /*
                 * Check for unsupported key length, per <rdar://6892837>
                 */
                /*
                 * Check for unsupported key length, per <rdar://6892837>
                 */
@@ -2210,14 +2698,14 @@ CSSM_RETURN tp_policyVerify(
                        }
                }
 
                        }
                }
 
-               /* 
+               /*
                 * Note it's possible for both of these to be true, for a chain
                 * of length one (kTPx509Basic, kCrlPolicy only!)
                 * FIXME: should this code work if the last cert in the chain is NOT a root?
                 */
                isLeaf = thisTpCertInfo->isLeaf();
                isRoot = thisTpCertInfo->isSelfSigned(true);
                 * Note it's possible for both of these to be true, for a chain
                 * of length one (kTPx509Basic, kCrlPolicy only!)
                 * FIXME: should this code work if the last cert in the chain is NOT a root?
                 */
                isLeaf = thisTpCertInfo->isLeaf();
                isRoot = thisTpCertInfo->isSelfSigned(true);
-                       
+
                /*
                 * BasicConstraints.cA
                 * iSign:        required in all but leaf and root,
                /*
                 * BasicConstraints.cA
                 * iSign:        required in all but leaf and root,
@@ -2243,9 +2731,9 @@ CSSM_RETURN tp_policyVerify(
                        else {
                                switch(policy) {
                                        default:
                        else {
                                switch(policy) {
                                        default:
-                                               /* 
-                                                * not present, not leaf, not root.... 
-                                                * ....RFC2459 says this can not be a CA 
+                                               /*
+                                                * not present, not leaf, not root....
+                                                * ....RFC2459 says this can not be a CA
                                                 */
                                                cA = CSSM_FALSE;
                                                break;
                                                 */
                                                cA = CSSM_FALSE;
                                                break;
@@ -2275,11 +2763,11 @@ CSSM_RETURN tp_policyVerify(
                        }
                        #endif  /* BASIC_CONSTRAINTS_MUST_BE_CRITICAL */
 
                        }
                        #endif  /* BASIC_CONSTRAINTS_MUST_BE_CRITICAL */
 
-                       const CE_BasicConstraints *bcp = 
+                       const CE_BasicConstraints *bcp =
                                &thisCertInfo->basicConstraints.extnData->basicConstraints;
                                &thisCertInfo->basicConstraints.extnData->basicConstraints;
-                       
+
                        cA = bcp->cA;
                        cA = bcp->cA;
-                       
+
                        /* Verify pathLenConstraint if present */
                        if(!isLeaf &&                                                   // leaf, certDex=0, don't care
                           cA &&                                                                // p.l.c. only valid for CAs
                        /* Verify pathLenConstraint if present */
                        if(!isLeaf &&                                                   // leaf, certDex=0, don't care
                           cA &&                                                                // p.l.c. only valid for CAs
@@ -2287,8 +2775,8 @@ CSSM_RETURN tp_policyVerify(
                                /*
                                 * pathLenConstraint=0 legal for certDex 1 only
                                 * pathLenConstraint=1 legal for certDex {1,2}
                                /*
                                 * pathLenConstraint=0 legal for certDex 1 only
                                 * pathLenConstraint=1 legal for certDex {1,2}
-                                * etc. 
-                                */ 
+                                * etc.
+                                */
                                if(certDex > (bcp->pathLenConstraint + 1)) {
                                        tpPolicyError("tp_policyVerify: pathLenConstraint "
                                                "exceeded");
                                if(certDex > (bcp->pathLenConstraint + 1)) {
                                        tpPolicyError("tp_policyVerify: pathLenConstraint "
                                                "exceeded");
@@ -2299,15 +2787,15 @@ CSSM_RETURN tp_policyVerify(
                                }
                        }
                }
                                }
                        }
                }
-               
+
                if(isLeaf) {
                if(isLeaf) {
-                       /* 
-                        * Special cases to allow a chain of length 1, leaf and root 
+                       /*
+                        * Special cases to allow a chain of length 1, leaf and root
                         * both true, and for caller to override the "leaf can't be a CA"
                         * both true, and for caller to override the "leaf can't be a CA"
-                        * requirement when a CA cert is explicitly being evaluated as the 
+                        * requirement when a CA cert is explicitly being evaluated as the
                         * leaf.
                         */
                         * leaf.
                         */
-                       if(cA && !isRoot && 
+                       if(cA && !isRoot &&
                           !(actionFlags & CSSM_TP_ACTION_LEAF_IS_CA)) {
                                tpPolicyError("tp_policyVerify: cA true for leaf");
                                if(thisTpCertInfo->addStatusCode(CSSMERR_APPLETP_INVALID_CA)) {
                           !(actionFlags & CSSM_TP_ACTION_LEAF_IS_CA)) {
                                tpPolicyError("tp_policyVerify: cA true for leaf");
                                if(thisTpCertInfo->addStatusCode(CSSMERR_APPLETP_INVALID_CA)) {
@@ -2320,13 +2808,13 @@ CSSM_RETURN tp_policyVerify(
                                policyFail = CSSM_TRUE;
                        }
                }
                                policyFail = CSSM_TRUE;
                        }
                }
-               
+
                /*
                 * Authority Key Identifier optional
                /*
                 * Authority Key Identifier optional
-                * iSign                : only allowed in !root. 
+                * iSign                : only allowed in !root.
                 *                If present, must not be critical.
                 * all others   : ignored (though used later for chain verification)
                 *                If present, must not be critical.
                 * all others   : ignored (though used later for chain verification)
-                */ 
+                */
                if((policy == kTPiSign) && thisCertInfo->authorityId.present) {
                        if(isRoot) {
                                tpPolicyError("tp_policyVerify: authorityId in root");
                if((policy == kTPiSign) && thisCertInfo->authorityId.present) {
                        if(isRoot) {
                                tpPolicyError("tp_policyVerify: authorityId in root");
@@ -2345,10 +2833,10 @@ CSSM_RETURN tp_policyVerify(
                }
 
                /*
                }
 
                /*
-                * Subject Key Identifier optional 
-                * iSign                 : can't be critical. 
+                * Subject Key Identifier optional
+                * iSign                 : can't be critical.
                 * all others    : ignored (though used later for chain verification)
                 * all others    : ignored (though used later for chain verification)
-                */ 
+                */
                if(thisCertInfo->subjectId.present) {
                        if((policy == kTPiSign) && thisCertInfo->subjectId.critical) {
                                tpPolicyError("tp_policyVerify: subjectId marked critical");
                if(thisCertInfo->subjectId.present) {
                        if((policy == kTPiSign) && thisCertInfo->subjectId.critical) {
                                tpPolicyError("tp_policyVerify: subjectId marked critical");
@@ -2357,28 +2845,28 @@ CSSM_RETURN tp_policyVerify(
                                }
                        }
                }
                                }
                        }
                }
-               
+
                /*
                 * Key Usage optional except required as noted
                 * iSign        : required for non-root/non-leaf
                 *                Leaf cert : if present, usage = digitalSignature
                /*
                 * Key Usage optional except required as noted
                 * iSign        : required for non-root/non-leaf
                 *                Leaf cert : if present, usage = digitalSignature
-                *                                Exception : if leaf, and keyUsage not present, 
+                *                                Exception : if leaf, and keyUsage not present,
                 *                                                netscape-cert-type must be present, with
                 *                                                        Object Signing bit set
                 * kCrlPolicy   : Leaf: usage = CRLSign
                 * kTP_SMIME    : if present, must be critical
                 *                                                netscape-cert-type must be present, with
                 *                                                        Object Signing bit set
                 * kCrlPolicy   : Leaf: usage = CRLSign
                 * kTP_SMIME    : if present, must be critical
-                * kTP_SWUpdateSign, kTP_ResourceSign, kTP_CodeSigning, kTP_PackageSigning : Leaf : 
+                * kTP_SWUpdateSign, kTP_ResourceSign, kTP_CodeSigning, kTP_PackageSigning : Leaf :
                                                  usage = digitalSignature
                 * all others   : non-leaf  : usage = keyCertSign
                 *                                Leaf : don't care
                                                  usage = digitalSignature
                 * all others   : non-leaf  : usage = keyCertSign
                 *                                Leaf : don't care
-                */ 
+                */
                if(thisCertInfo->keyUsage.present) {
                        /*
                         * Leaf cert:
                         *    iSign and *Signing: usage = digitalSignature
                         *    all others : don't care
                         * Others:    usage = keyCertSign
                if(thisCertInfo->keyUsage.present) {
                        /*
                         * Leaf cert:
                         *    iSign and *Signing: usage = digitalSignature
                         *    all others : don't care
                         * Others:    usage = keyCertSign
-                        * We only require that one bit to be set, we ignore others. 
+                        * We only require that one bit to be set, we ignore others.
                         */
                        if(isLeaf) {
                                switch(policy) {
                         */
                        if(isLeaf) {
                                switch(policy) {
@@ -2412,11 +2900,11 @@ CSSM_RETURN tp_policyVerify(
                                        policyFail = CSSM_TRUE;
                                }
                        }
                                        policyFail = CSSM_TRUE;
                                }
                        }
-                       
+
                        #if 0
                        #if 0
-                       /* 
+                       /*
                         * Radar 3523221 renders this whole check obsolete, but I'm leaving
                         * Radar 3523221 renders this whole check obsolete, but I'm leaving
-                        * the code here to document its conspicuous functional absence.  
+                        * the code here to document its conspicuous functional absence.
                         */
                        if((policy == kTP_SMIME) && !thisCertInfo->keyUsage.critical) {
                                /*
                         */
                        if((policy == kTP_SMIME) && !thisCertInfo->keyUsage.critical) {
                                /*
@@ -2433,14 +2921,14 @@ CSSM_RETURN tp_policyVerify(
                        #endif
                }
                else if(policy == kTPiSign) {
                        #endif
                }
                else if(policy == kTPiSign) {
-                       /* 
+                       /*
                         * iSign requires keyUsage present for non root OR
                         * netscape-cert-type/ObjectSigning for leaf
                         */
                        if(isLeaf && thisCertInfo->netscapeCertType.present) {
                         * iSign requires keyUsage present for non root OR
                         * netscape-cert-type/ObjectSigning for leaf
                         */
                        if(isLeaf && thisCertInfo->netscapeCertType.present) {
-                               CE_NetscapeCertType ct = 
+                               CE_NetscapeCertType ct =
                                        thisCertInfo->netscapeCertType.extnData->netscapeCertType;
                                        thisCertInfo->netscapeCertType.extnData->netscapeCertType;
-                                       
+
                                if(!(ct & CE_NCT_ObjSign)) {
                                        tpPolicyError("tp_policyVerify: netscape-cert-type, "
                                                "!ObjectSign");
                                if(!(ct & CE_NCT_ObjSign)) {
                                        tpPolicyError("tp_policyVerify: netscape-cert-type, "
                                                "!ObjectSign");
@@ -2456,7 +2944,7 @@ CSSM_RETURN tp_policyVerify(
                                        policyFail = CSSM_TRUE;
                                }
                        }
                                        policyFail = CSSM_TRUE;
                                }
                        }
-               }                               
+               }
 
                /*
                 * RFC 3280, 4.1.2.6, says that an empty subject name can only appear in a
 
                /*
                 * RFC 3280, 4.1.2.6, says that an empty subject name can only appear in a
@@ -2466,10 +2954,10 @@ CSSM_RETURN tp_policyVerify(
                        bool badEmptySubject = false;
                        if(actionFlags & CSSM_TP_ACTION_LEAF_IS_CA) {
                                /*
                        bool badEmptySubject = false;
                        if(actionFlags & CSSM_TP_ACTION_LEAF_IS_CA) {
                                /*
-                                * True when evaluating a CA cert as well as when 
+                                * True when evaluating a CA cert as well as when
                                 * evaluating a CRL's cert chain. Note the odd case of a CRL's
                                 * signer having an empty subject matching an empty issuer
                                 * evaluating a CRL's cert chain. Note the odd case of a CRL's
                                 * signer having an empty subject matching an empty issuer
-                                * in the CRL. That'll be caught here. 
+                                * in the CRL. That'll be caught here.
                                 */
                                badEmptySubject = true;
                        }
                                 */
                                badEmptySubject = true;
                        }
@@ -2481,17 +2969,17 @@ CSSM_RETURN tp_policyVerify(
                                tpPolicyError("tp_policyVerify: bad empty subject");
                                if(thisTpCertInfo->addStatusCode(CSSMERR_APPLETP_INVALID_EMPTY_SUBJECT)) {
                                        policyFail = CSSM_TRUE;
                                tpPolicyError("tp_policyVerify: bad empty subject");
                                if(thisTpCertInfo->addStatusCode(CSSMERR_APPLETP_INVALID_EMPTY_SUBJECT)) {
                                        policyFail = CSSM_TRUE;
-                               }                               
+                               }
                        }
                }
                        }
                }
-          
+
                /*
                /*
-                * RFC 3739: if this cert has a Qualified Cert Statements extension, and 
+                * RFC 3739: if this cert has a Qualified Cert Statements extension, and
                 * it's Critical, make sure we understand all of the extension's statementIds.
                 */
                if(thisCertInfo->qualCertStatements.present &&
                   thisCertInfo->qualCertStatements.critical) {
                 * it's Critical, make sure we understand all of the extension's statementIds.
                 */
                if(thisCertInfo->qualCertStatements.present &&
                   thisCertInfo->qualCertStatements.critical) {
-                       CE_QC_Statements *qcss = 
+                       CE_QC_Statements *qcss =
                                &thisCertInfo->qualCertStatements.extnData->qualifiedCertStatements;
                        uint32 numQcs = qcss->numQCStatements;
                        for(unsigned qdex=0; qdex<numQcs; qdex++) {
                                &thisCertInfo->qualCertStatements.extnData->qualifiedCertStatements;
                        uint32 numQcs = qcss->numQCStatements;
                        for(unsigned qdex=0; qdex<numQcs; qdex++) {
@@ -2552,9 +3040,9 @@ CSSM_RETURN tp_policyVerify(
        }       /* for certDex, checking presence of extensions */
 
        /*
        }       /* for certDex, checking presence of extensions */
 
        /*
-        * Special case checking for leaf (end entity) cert     
+        * Special case checking for leaf (end entity) cert
         *
         *
-        * iSign only: Extended key usage, optional for leaf, 
+        * iSign only: Extended key usage, optional for leaf,
         * value CSSMOID_ExtendedUseCodeSigning
         */
        if((policy == kTPiSign) && certInfo[0].extendKeyUsage.present) {
         * value CSSMOID_ExtendedUseCodeSigning
         */
        if((policy == kTPiSign) && certInfo[0].extendKeyUsage.present) {
@@ -2577,16 +3065,16 @@ CSSM_RETURN tp_policyVerify(
                        }
                }
        }
                        }
                }
        }
-       
+
        /*
         * Verify authorityId-->subjectId linkage.
         * All optional - skip if needed fields not present.
        /*
         * Verify authorityId-->subjectId linkage.
         * All optional - skip if needed fields not present.
-        * Also, always skip last (root) cert.  
+        * Also, always skip last (root) cert.
         */
        for(certDex=0; certDex<(numCerts-1); certDex++) {
                if(!certInfo[certDex].authorityId.present ||
                   !certInfo[certDex+1].subjectId.present) {
         */
        for(certDex=0; certDex<(numCerts-1); certDex++) {
                if(!certInfo[certDex].authorityId.present ||
                   !certInfo[certDex+1].subjectId.present) {
-                       continue;  
+                       continue;
                }
                authorityId = &certInfo[certDex].authorityId.extnData->authorityKeyID;
                if(!authorityId->keyIdentifierPresent) {
                }
                authorityId = &certInfo[certDex].authorityId.extnData->authorityKeyID;
                if(!authorityId->keyIdentifierPresent) {
@@ -2622,20 +3110,20 @@ CSSM_RETURN tp_policyVerify(
                case kTP_SSL:
                case kTP_EAP:
                case kTP_IPSec:
                case kTP_SSL:
                case kTP_EAP:
                case kTP_IPSec:
-                       /* 
+                       /*
                         * SSL, EAP, IPSec: optionally verify common name; all are identical
                         * SSL, EAP, IPSec: optionally verify common name; all are identical
-                        * other than their names. 
+                        * other than their names.
                         * FIXME - should this be before or after the root cert test? How can
                         * we return both errors?
                         */
                        policyError = tp_verifySslOpts(policy, *certGroup, policyFieldData, certInfo[0]);
                        break;
                         * FIXME - should this be before or after the root cert test? How can
                         * we return both errors?
                         */
                        policyError = tp_verifySslOpts(policy, *certGroup, policyFieldData, certInfo[0]);
                        break;
-                       
+
                case kTP_iChat:
                        tpDebug("iChat policy");
                        /* fall thru */
                case kTP_SMIME:
                case kTP_iChat:
                        tpDebug("iChat policy");
                        /* fall thru */
                case kTP_SMIME:
-                       policyError = tp_verifySmimeOpts(policy, *certGroup, policyFieldData, 
+                       policyError = tp_verifySmimeOpts(policy, *certGroup, policyFieldData,
                                certInfo[0]);
                        break;
                case kTP_SWUpdateSign:
                                certInfo[0]);
                        break;
                case kTP_SWUpdateSign:
@@ -2649,7 +3137,7 @@ CSSM_RETURN tp_policyVerify(
                        policyError = tp_verifyCodePkgSignOpts(policy, *certGroup, policyFieldData, certInfo);
                        break;
                case kTP_MacAppStoreRec:
                        policyError = tp_verifyCodePkgSignOpts(policy, *certGroup, policyFieldData, certInfo);
                        break;
                case kTP_MacAppStoreRec:
-                       policyError = tp_verifyMacAppStoreReciptOpts(*certGroup, policyFieldData, certInfo);
+                       policyError = tp_verifyMacAppStoreReceiptOpts(*certGroup, policyFieldData, certInfo);
                        break;
                case kTP_AppleIDSharing:
                        policyError = tp_verifyAppleIDSharingOpts(*certGroup, policyFieldData, certInfo);
                        break;
                case kTP_AppleIDSharing:
                        policyError = tp_verifyAppleIDSharingOpts(*certGroup, policyFieldData, certInfo);
@@ -2657,6 +3145,24 @@ CSSM_RETURN tp_policyVerify(
                case kTP_TimeStamping:
                        policyError = tp_verifyTimeStampingOpts(*certGroup, policyFieldData, certInfo);
                        break;
                case kTP_TimeStamping:
                        policyError = tp_verifyTimeStampingOpts(*certGroup, policyFieldData, certInfo);
                        break;
+               case kTP_PassbookSigning:
+                       policyError = tp_verifyPassbookSigningOpts(*certGroup, policyFieldData, certInfo);
+                       break;
+               case kTP_MobileStore:
+                       policyError = tp_verifyMobileStoreSigningOpts(*certGroup, policyFieldData, certInfo, false);
+                       break;
+               case kTP_TestMobileStore:
+                       policyError = tp_verifyMobileStoreSigningOpts(*certGroup, policyFieldData, certInfo, true);
+                       break;
+               case kTP_EscrowService:
+                       policyError = tp_verifyEscrowServiceSigningOpts(*certGroup, policyFieldData, certInfo);
+                       break;
+               case kTP_ProfileSigning:
+                       policyError = tp_verifyProfileSigningOpts(*certGroup, policyFieldData, certInfo, false);
+                       break;
+               case kTP_QAProfileSigning:
+                       policyError = tp_verifyProfileSigningOpts(*certGroup, policyFieldData, certInfo, true);
+                       break;
                case kTPx509Basic:
                case kTPiSign:
                case kCrlPolicy:
                case kTPx509Basic:
                case kTPiSign:
                case kCrlPolicy:
@@ -2665,7 +3171,7 @@ CSSM_RETURN tp_policyVerify(
                        break;
 
        }
                        break;
 
        }
-       
+
        if(outErr == CSSM_OK) {
                /* policy-specific error takes precedence here */
                if(policyError != CSSM_OK) {
        if(outErr == CSSM_OK) {
                /* policy-specific error takes precedence here */
                if(policyError != CSSM_OK) {
@@ -2686,7 +3192,7 @@ errOut:
        return outErr;
 }
 
        return outErr;
 }
 
-/* 
+/*
  * Obtain policy-specific User Trust parameters
  */
 void tp_policyTrustSettingParams(
  * Obtain policy-specific User Trust parameters
  */
 void tp_policyTrustSettingParams(
@@ -2700,7 +3206,7 @@ void tp_policyTrustSettingParams(
        /* default values */
        *policyStr = NULL;
        *keyUse = kSecTrustSettingsKeyUseAny;
        /* default values */
        *policyStr = NULL;
        *keyUse = kSecTrustSettingsKeyUseAny;
-       
+
        if((policyData == NULL) || (policyData->Data == NULL)) {
                /* currently, no further action possible */
                return;
        if((policyData == NULL) || (policyData->Data == NULL)) {
                /* currently, no further action possible */
                return;
@@ -2709,19 +3215,19 @@ void tp_policyTrustSettingParams(
                case kTP_SSL:
                case kTP_EAP:
                case kTP_IPSec:
                case kTP_SSL:
                case kTP_EAP:
                case kTP_IPSec:
-               {       
+               {
                        if(policyData->Length != sizeof(CSSM_APPLE_TP_SSL_OPTIONS)) {
                                /* this error will be caught later */
                                return;
                        }
                        if(policyData->Length != sizeof(CSSM_APPLE_TP_SSL_OPTIONS)) {
                                /* this error will be caught later */
                                return;
                        }
-                       CSSM_APPLE_TP_SSL_OPTIONS *sslOpts = 
+                       CSSM_APPLE_TP_SSL_OPTIONS *sslOpts =
                                (CSSM_APPLE_TP_SSL_OPTIONS *)policyData->Data;
                        *policyStr = sslOpts->ServerName;
                        *policyStrLen = sslOpts->ServerNameLen;
                        if(sslOpts->Flags & CSSM_APPLE_TP_SSL_CLIENT) {
                                (CSSM_APPLE_TP_SSL_OPTIONS *)policyData->Data;
                        *policyStr = sslOpts->ServerName;
                        *policyStrLen = sslOpts->ServerNameLen;
                        if(sslOpts->Flags & CSSM_APPLE_TP_SSL_CLIENT) {
-                               /* 
+                               /*
                                 * Client signs with its priv key. Server end,
                                 * Client signs with its priv key. Server end,
-                                * which (also) verifies the client cert, verifies. 
+                                * which (also) verifies the client cert, verifies.
                                 */
                                *keyUse = kSecTrustSettingsKeyUseSignature;
                        }
                                 */
                                *keyUse = kSecTrustSettingsKeyUseSignature;
                        }
@@ -2731,7 +3237,7 @@ void tp_policyTrustSettingParams(
                        }
                        return;
                }
                        }
                        return;
                }
-               
+
                case kTP_iChat:
                case kTP_SMIME:
                {
                case kTP_iChat:
                case kTP_SMIME:
                {
@@ -2739,7 +3245,7 @@ void tp_policyTrustSettingParams(
                                /* this error will be caught later */
                                return;
                        }
                                /* this error will be caught later */
                                return;
                        }
-                       CSSM_APPLE_TP_SMIME_OPTIONS *smimeOpts = 
+                       CSSM_APPLE_TP_SMIME_OPTIONS *smimeOpts =
                                (CSSM_APPLE_TP_SMIME_OPTIONS *)policyData->Data;
                        *policyStr = smimeOpts->SenderEmail;
                        *policyStrLen = smimeOpts->SenderEmailLen;
                                (CSSM_APPLE_TP_SMIME_OPTIONS *)policyData->Data;
                        *policyStr = smimeOpts->SenderEmail;
                        *policyStrLen = smimeOpts->SenderEmailLen;
@@ -2754,7 +3260,7 @@ void tp_policyTrustSettingParams(
                        *keyUse = ku;
                        return;
                }
                        *keyUse = ku;
                        return;
                }
-               
+
                default:
                        /* no other options */
                        return;
                default:
                        /* no other options */
                        return;
index 25fd2652e9da000628f849b1f3a05109a27648c2..9013f0f527ee33d39d51e166e15959ace78a6f71 100644 (file)
@@ -1,12 +1,12 @@
 /*
 /*
- * Copyright (c) 2000-2012 Apple Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2000-2013 Apple Inc. All Rights Reserved.
+ *
  * The contents of this file constitute Original Code as defined in and are
  * subject to the Apple Public Source License Version 1.2 (the 'License').
  * You may not use this file except in 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 contents of this file constitute Original Code as defined in and are
  * subject to the Apple Public Source License Version 1.2 (the 'License').
  * You may not use this file except in compliance with the License. Please obtain
  * a copy of the License at http://www.apple.com/publicsource and read it before
  * using this file.
- * 
+ *
  * This Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
  * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
  * This Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
  * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
@@ -41,7 +41,7 @@ typedef enum {
        kTPiSign,                       /* (obsolete) Apple code signing */
        kTP_SSL,                        /* SecureTransport/SSL */
        kCrlPolicy,                     /* cert chain verification via CRL */
        kTPiSign,                       /* (obsolete) Apple code signing */
        kTP_SSL,                        /* SecureTransport/SSL */
        kCrlPolicy,                     /* cert chain verification via CRL */
-       kTP_SMIME,                      /* S/MIME */            
+       kTP_SMIME,                      /* S/MIME */
        kTP_EAP,
        kTP_SWUpdateSign,       /* Apple SW Update signing (was Apple Code Signing) */
        kTP_ResourceSign,       /* Apple Resource Signing */
        kTP_EAP,
        kTP_SWUpdateSign,       /* Apple SW Update signing (was Apple Code Signing) */
        kTP_ResourceSign,       /* Apple Resource Signing */
@@ -53,7 +53,13 @@ typedef enum {
        kTP_PackageSigning,     /* Package Signing */
        kTP_MacAppStoreRec,     /* MacApp store receipt */
        kTP_AppleIDSharing,     /* AppleID Sharing */
        kTP_PackageSigning,     /* Package Signing */
        kTP_MacAppStoreRec,     /* MacApp store receipt */
        kTP_AppleIDSharing,     /* AppleID Sharing */
-       kTP_TimeStamping        /* RFC3161 time stamping */
+       kTP_TimeStamping,       /* RFC3161 time stamping */
+       kTP_PassbookSigning,    /* Passbook Signing */
+       kTP_MobileStore,        /* Apple Mobile Store Signing */
+       kTP_TestMobileStore,    /* Apple Test Mobile Store Signing */
+       kTP_EscrowService,      /* Apple Escrow Service Signing */
+       kTP_ProfileSigning,     /* Apple Configuration Profile Signing */
+       kTP_QAProfileSigning,   /* Apple QA Configuration Profile Signing */
 } TPPolicy;
 
 /*
 } TPPolicy;
 
 /*
@@ -71,7 +77,7 @@ CSSM_RETURN tp_policyVerify(
        const CSSM_DATA                                 *policyFieldData,       // optional
     void                                                       *policyControl);        // future use
 
        const CSSM_DATA                                 *policyFieldData,       // optional
     void                                                       *policyControl);        // future use
 
-/* 
+/*
  * Obtain policy-specific User Trust parameters
  */
 void tp_policyTrustSettingParams(
  * Obtain policy-specific User Trust parameters
  */
 void tp_policyTrustSettingParams(
@@ -81,7 +87,7 @@ void tp_policyTrustSettingParams(
        const char                              **policyStr,
        uint32                                  *policyStrLen,
        SecTrustSettingsKeyUsage        *keyUse);
        const char                              **policyStr,
        uint32                                  *policyStrLen,
        SecTrustSettingsKeyUsage        *keyUse);
-       
+
 #ifdef __cplusplus
 }
 #endif
 #ifdef __cplusplus
 }
 #endif
index 2793e57df8861ef150f5d577514ac1f91ddb195e..eb164202de3972b3227bffc0483c7e8e18435e51 100644 (file)
@@ -44,7 +44,7 @@ int timeStringToCfDate(
        bool            isLocal = false;                // trailing timezone offset
        bool            isCssmTime = false;             // no trailing 'Z'
        bool            noSeconds = false;
        bool            isLocal = false;                // trailing timezone offset
        bool            isCssmTime = false;             // no trailing 'Z'
        bool            noSeconds = false;
-       unsigned        x;
+       int             x;
        unsigned        i;
        char            *cp;
        CFGregorianDate         gd;
        unsigned        i;
        char            *cp;
        CFGregorianDate         gd;
index 56d1dd5c465c26678d4ee0cc0d44a374cca858a4..157cf8bd6b7bc23d1056ad71d3c751a961ba0ba3 100644 (file)
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0420;
+                               LastUpgradeCheck = 0500;
                        };
                        buildConfigurationList = C27AD29B0987FCDD001272E0 /* Build configuration list for PBXProject "libsecurity_apple_x509_tp" */;
                        compatibilityVersion = "Xcode 3.2";
                        };
                        buildConfigurationList = C27AD29B0987FCDD001272E0 /* Build configuration list for PBXProject "libsecurity_apple_x509_tp" */;
                        compatibilityVersion = "Xcode 3.2";
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844611B146E85EA00B12992 /* debug.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844611B146E85EA00B12992 /* debug.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844611D146E85EA00B12992 /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844611D146E85EA00B12992 /* release.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844611C146E85EA00B12992 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844611C146E85EA00B12992 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844611C146E85EA00B12992 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844611C146E85EA00B12992 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
index 1e170bffe7fdbe1d3c9f99c1f308413477365c3e..ae4cd0fd6dc327a2f578a0f9fb53ccc0c36ef9da 100644 (file)
@@ -6,3 +6,11 @@ VERSIONING_SYSTEM = apple-generic;
 DEAD_CODE_STRIPPING = YES;
 
 ARCHS = $(ARCHS_STANDARD_32_64_BIT)
 DEAD_CODE_STRIPPING = YES;
 
 ARCHS = $(ARCHS_STANDARD_32_64_BIT)
+
+INDIGO_INSTALL_PATH_PREFIX[sdk=iphonesimulator*] = $(SDKROOT)
+
+// Debug symbols should be on obviously
+GCC_GENERATE_DEBUGGING_SYMBOLS = YES
+COPY_PHASE_STRIP = NO
+STRIP_STYLE = debugging
+STRIP_INSTALLED_PRODUCT = NO
index 937d177552d7c32bc7eea9753d7d6523f1f0ea72..47555cf5ce157140e769b2e16f93723b761e7281 100644 (file)
@@ -1,3 +1,2 @@
 GCC_OPTIMIZATION_LEVEL = 0
 GCC_PREPROCESSOR_DEFINITIONS = DEBUG=1 $(inherited)
 GCC_OPTIMIZATION_LEVEL = 0
 GCC_PREPROCESSOR_DEFINITIONS = DEBUG=1 $(inherited)
-COPY_PHASE_STRIP = NO
index 363ca975da64407a7fc6547f05e87498eeef7f3c..a08d1b746dce77c735ed69a135f7218ba5c14aba 100644 (file)
@@ -1,19 +1,18 @@
 #include "base.xcconfig"
 #include "base.xcconfig"
-#include "<DEVELOPER_DIR>/AppleInternal/XcodeConfig/AspenFamily.xcconfig"
 
 PRODUCT_NAME = $(TARGET_NAME)
 EXECUTABLE_PREFIX = 
 
 CODE_SIGN_IDENTITY = 
 
 
 PRODUCT_NAME = $(TARGET_NAME)
 EXECUTABLE_PREFIX = 
 
 CODE_SIGN_IDENTITY = 
 
-HEADER_SEARCH_PATHS[sdk=macosx*] = $(PROJECT_DIR) $(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Headers $(inherited)
+HEADER_SEARCH_PATHS[sdk=macosx*] = $(PROJECT_DIR) $(PROJECT_DIR)/../include $(BUILT_PRODUCTS_DIR)/derived_src $(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Headers $(inherited)
 
 
-HEADER_SEARCH_PATHS[sdk=iphone*] = $(PROJECT_DIR) $(BUILT_PRODUCTS_DIR)$(INDIGO_INSTALL_PATH_PREFIX)/usr/local/include $(inherited)
+HEADER_SEARCH_PATHS[sdk=iphone*] = $(PROJECT_DIR) $(PROJECT_DIR)/../sec $(BUILT_PRODUCTS_DIR)$(INDIGO_INSTALL_PATH_PREFIX)/usr/local/include $(inherited)
 
 INSTALL_PATH = $(INDIGO_INSTALL_PATH_PREFIX)/usr/local/lib
 INSTALL_PATH_ACTUAL[sdk=iphonesimulator*] = /usr/local/lib
 PRIVATE_HEADERS_FOLDER_PATH[sdk=iphone*] = $(INDIGO_INSTALL_PATH_PREFIX)/usr/local/include/security_asn1
 
 INSTALL_PATH = $(INDIGO_INSTALL_PATH_PREFIX)/usr/local/lib
 INSTALL_PATH_ACTUAL[sdk=iphonesimulator*] = /usr/local/lib
 PRIVATE_HEADERS_FOLDER_PATH[sdk=iphone*] = $(INDIGO_INSTALL_PATH_PREFIX)/usr/local/include/security_asn1
-PUBLIC_HEADERS_FOLDER_PATH[sdk=iphone*] = $(INDIGO_INSTALL_PATH_PREFIX)/usr/local/include/Security
+PUBLIC_HEADERS_FOLDER_PATH[sdk=iphone*] = $(INDIGO_INSTALL_PATH_PREFIX)/usr/local/include/security_asn1
 PRIVATE_HEADERS_FOLDER_PATH[sdk=macosx*] = /usr/local/include/security_asn1
 PUBLIC_HEADERS_FOLDER_PATH[sdk=macosx*] = /usr/local/include/security_asn1
 
 PRIVATE_HEADERS_FOLDER_PATH[sdk=macosx*] = /usr/local/include/security_asn1
 PUBLIC_HEADERS_FOLDER_PATH[sdk=macosx*] = /usr/local/include/security_asn1
 
index 3110dcb5b93f17bd64177e01d5adf4243c5562ae..088ded92a81006819c31d49f1dc81025b210663d 100644 (file)
@@ -1,2 +1,2 @@
+GCC_OPTIMIZATION_LEVEL = s
 GCC_PREPROCESSOR_DEFINITIONS = NDEBUG=1 $(inherited)
 GCC_PREPROCESSOR_DEFINITIONS = NDEBUG=1 $(inherited)
-COPY_PHASE_STRIP = YES
index 29708f6de3b65e6cbb23be3d89d8dfefa6d236fe..3512ffcee8d71caa2435397cf67e96db878778f8 100644 (file)
@@ -28,7 +28,7 @@
 #include "prerror.h"
 #include "seccomon.h"
 #include "secasn1.h"
 #include "prerror.h"
 #include "seccomon.h"
 #include "secasn1.h"
-#include <MacErrors.h>
+#include <Security/SecBase.h>
 
 /* 
  * Default chunk size for new arena pool.
 
 /* 
  * Default chunk size for new arena pool.
@@ -52,22 +52,23 @@ OSStatus SecAsn1CoderCreate(
        SecAsn1CoderRef  *coder)
 {
        if(coder == NULL) {
        SecAsn1CoderRef  *coder)
 {
        if(coder == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        SecAsn1CoderRef _coder = (SecAsn1CoderRef)malloc(sizeof(SecAsn1Coder_t));
        _coder->mPool = PORT_NewArena(CHUNKSIZE_DEF);
        if(_coder->mPool == NULL) {
        }
        SecAsn1CoderRef _coder = (SecAsn1CoderRef)malloc(sizeof(SecAsn1Coder_t));
        _coder->mPool = PORT_NewArena(CHUNKSIZE_DEF);
        if(_coder->mPool == NULL) {
-               return memFullErr;
+        free(_coder);
+               return errSecAllocate;
        }
        *coder = _coder;
        }
        *coder = _coder;
-       return noErr;
+       return errSecSuccess;
 }
        
 OSStatus SecAsn1CoderRelease(
        SecAsn1CoderRef  coder)
 {
        if(coder == NULL) {
 }
        
 OSStatus SecAsn1CoderRelease(
        SecAsn1CoderRef  coder)
 {
        if(coder == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        if(coder->mPool != NULL) {
                /*
        }
        if(coder->mPool != NULL) {
                /*
@@ -78,7 +79,7 @@ OSStatus SecAsn1CoderRelease(
                coder->mPool = NULL;
        }
        free(coder);
                coder->mPool = NULL;
        }
        free(coder);
-       return noErr;
+       return errSecSuccess;
 }
        
 /*
 }
        
 /*
@@ -97,14 +98,14 @@ OSStatus SecAsn1Decode(
        void                                    *dest)
 {
        if((coder == NULL) || (src == NULL) || (templ == NULL) || (dest == NULL)) {
        void                                    *dest)
 {
        if((coder == NULL) || (src == NULL) || (templ == NULL) || (dest == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        SECStatus prtn = SEC_ASN1Decode(coder->mPool, dest, templ, (const char *)src, len);
        if(prtn) {
                return errSecDecode;
        }
        else {
        }
        SECStatus prtn = SEC_ASN1Decode(coder->mPool, dest, templ, (const char *)src, len);
        if(prtn) {
                return errSecDecode;
        }
        else {
-               return noErr;
+               return errSecSuccess;
        }
 }
                
        }
 }
                
@@ -133,7 +134,7 @@ OSStatus SecAsn1EncodeItem(
        SecAsn1Item                             *dest)
 {
        if((coder == NULL) || (src == NULL) || (templ == NULL) || (dest == NULL)) {
        SecAsn1Item                             *dest)
 {
        if((coder == NULL) || (src == NULL) || (templ == NULL) || (dest == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        dest->Data = NULL;
        dest->Length = 0;
        }
        dest->Data = NULL;
        dest->Length = 0;
@@ -141,10 +142,10 @@ OSStatus SecAsn1EncodeItem(
        SecAsn1Item *rtnItem = SEC_ASN1EncodeItem(coder->mPool, dest, src, templ);
        if(rtnItem == NULL) {
                /* FIXME what to return here? */
        SecAsn1Item *rtnItem = SEC_ASN1EncodeItem(coder->mPool, dest, src, templ);
        if(rtnItem == NULL) {
                /* FIXME what to return here? */
-               return paramErr;
+               return errSecParam;
        }
        else {
        }
        else {
-               return noErr;
+               return errSecSuccess;
        }
 }
                
        }
 }
                
@@ -155,7 +156,7 @@ OSStatus SecAsn1EncodeItem(
  * temp allocs of memory which only needs a scope which is the
  * same as this object. 
  *
  * temp allocs of memory which only needs a scope which is the
  * same as this object. 
  *
- * These return a memFullErr in the highly unlikely event of 
+ * These return a errSecAllocate in the highly unlikely event of 
  * a malloc failure.
  */
 void *SecAsn1Malloc(
  * a malloc failure.
  */
 void *SecAsn1Malloc(
@@ -175,14 +176,14 @@ OSStatus SecAsn1AllocItem(
        size_t                                  len)
 {
        if((coder == NULL) || (item == NULL)) {
        size_t                                  len)
 {
        if((coder == NULL) || (item == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        item->Data = (uint8_t *)PORT_ArenaAlloc(coder->mPool, len);
        if(item->Data == NULL) {
        }
        item->Data = (uint8_t *)PORT_ArenaAlloc(coder->mPool, len);
        if(item->Data == NULL) {
-               return memFullErr;
+               return errSecAllocate;
        }
        item->Length = len;
        }
        item->Length = len;
-       return noErr;
+       return errSecSuccess;
 }
        
 /* malloc and copy, various forms */
 }
        
 /* malloc and copy, various forms */
@@ -193,14 +194,14 @@ OSStatus SecAsn1AllocCopy(
        SecAsn1Item                             *dest)
 {
        if(src == NULL) {
        SecAsn1Item                             *dest)
 {
        if(src == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        OSStatus ortn = SecAsn1AllocItem(coder, dest, len);
        if(ortn) {
                return ortn;
        }
        memmove(dest->Data, src, len);
        }
        OSStatus ortn = SecAsn1AllocItem(coder, dest, len);
        if(ortn) {
                return ortn;
        }
        memmove(dest->Data, src, len);
-       return noErr;
+       return errSecSuccess;
 }
        
 OSStatus SecAsn1AllocCopyItem(
 }
        
 OSStatus SecAsn1AllocCopyItem(
index 33ed59eceaedae35dee0fa8ec4f0c15b7dfca489..d27e768d27ebb7c7c1bd0c4bbdbccd89bc6ba394 100644 (file)
@@ -108,7 +108,7 @@ OSStatus SecAsn1EncodeItem(
  * temp allocs of memory which only needs a scope which is the
  * same as this object. 
  *
  * temp allocs of memory which only needs a scope which is the
  * same as this object. 
  *
- * All except SecAsn1Malloc return a memFullErr in the highly 
+ * All except SecAsn1Malloc return a errSecAllocate in the highly 
  * unlikely event of a malloc failure.
  *
  * SecAsn1Malloc() returns a pointer to allocated memory, like 
  * unlikely event of a malloc failure.
  *
  * SecAsn1Malloc() returns a pointer to allocated memory, like 
index 10c90114f18e44942ec3b74a785c2086f85473b0..ad071bb29028431684223d6a041a64c9552cead4 100644 (file)
@@ -42,7 +42,7 @@
 extern "C" {
 #endif
 
 extern "C" {
 #endif
 
-#pragma mark --- X509 Validity support ---
+// MARK: --- X509 Validity support ---
 
 /* 
  * ASN Class : Validity
 
 /* 
  * ASN Class : Validity
@@ -64,7 +64,7 @@ typedef struct  {
 
 extern const SecAsn1Template kSecAsn1ValidityTemplate[];
 
 
 extern const SecAsn1Template kSecAsn1ValidityTemplate[];
 
-#pragma mark --- Certificate ---
+// MARK: --- Certificate ---
 
 /*
  * X509 cert extension
 
 /*
  * X509 cert extension
@@ -126,7 +126,7 @@ typedef struct {
 
 extern const SecAsn1Template kSecAsn1SignedCertTemplate[];
 
 
 extern const SecAsn1Template kSecAsn1SignedCertTemplate[];
 
-#pragma mark --- CRL ---
+// MARK: --- CRL ---
 
 /*
  * ASN class : revokedCertificate
 
 /*
  * ASN class : revokedCertificate
index 4aad23fc975d1a21d4c3bda56c20083027fcda52..8f4e46514e0e6b60378759f760f608bd958f49fb 100644 (file)
@@ -99,8 +99,8 @@ const SecAsn1Template kSecAsn1DigestInfoTemplate[] = {
     { 0 }
 };
 
     { 0 }
 };
 
-#pragma mark -
-#pragma mark *** RSA ***
+// MARK: -
+// MARK: *** RSA ***
 
 /*** RSA public key, PKCS1 format : NSS_RSAPublicKeyPKCS1 ***/
 const SecAsn1Template kSecAsn1RSAPublicKeyPKCS1Template[] = {
 
 /*** RSA public key, PKCS1 format : NSS_RSAPublicKeyPKCS1 ***/
 const SecAsn1Template kSecAsn1RSAPublicKeyPKCS1Template[] = {
@@ -125,8 +125,8 @@ const SecAsn1Template kSecAsn1RSAPrivateKeyPKCS1Template[] = {
     { 0, }
 };
 
     { 0, }
 };
 
-#pragma mark -
-#pragma mark *** Diffie-Hellman ***
+// MARK: -
+// MARK: *** Diffie-Hellman ***
 
 /****
  **** Diffie-Hellman, from PKCS3.
 
 /****
  **** Diffie-Hellman, from PKCS3.
index e77fc603e8f7a948da01504a6f15238ac2338d43..9b766faf17071bfe3b25647def5a96a5b913a076 100644 (file)
@@ -110,7 +110,7 @@ extern const SecAsn1Template kSecAsn1DigestInfoTemplate[];
  * Key structs and templates, placed here due to their ubiquitous use.
  */
 
  * Key structs and templates, placed here due to their ubiquitous use.
  */
 
-#pragma mark *** RSA ***
+// MARK: *** RSA ***
 
 /*
  * RSA public key, PKCS1 format
 
 /*
  * RSA public key, PKCS1 format
@@ -154,7 +154,7 @@ extern const SecAsn1Template kSecAsn1RSAPrivateKeyPKCS1Template[];
  * value is a DER-encoded NSS_RSAPrivateKeyPKCS1.
  */
 
  * value is a DER-encoded NSS_RSAPrivateKeyPKCS1.
  */
 
-#pragma mark *** Diffie-Hellman ***
+// MARK: *** Diffie-Hellman ***
 
 /*** from PKCS3 ***/
 
 
 /*** from PKCS3 ***/
 
@@ -253,7 +253,7 @@ typedef struct {
 extern const SecAsn1Template kSecAsn1DHPrivateKeyPKCS8Template[];
 extern const SecAsn1Template kSecAsn1DHPublicKeyX509Template[];
  
 extern const SecAsn1Template kSecAsn1DHPrivateKeyPKCS8Template[];
 extern const SecAsn1Template kSecAsn1DHPublicKeyX509Template[];
  
-#pragma mark *** ECDSA ***
+// MARK: *** ECDSA ***
 
 /* 
  * ECDSA Private key as defined in section C.4 of Certicom SEC1.
 
 /* 
  * ECDSA Private key as defined in section C.4 of Certicom SEC1.
index b7e1fee2df086640570843d42eda5a926a240d12..e466cb3ced7871b7aca1e75c84e0901f64e9249a 100644 (file)
@@ -35,7 +35,7 @@ typedef struct {
     SecAsn1Item value; // unparsed, BER-encoded
 } CE_OtherName;
 
     SecAsn1Item value; // unparsed, BER-encoded
 } CE_OtherName;
 
-#pragma mark ----- Generalized NSS_TaggedItem template chooser support -----
+// MARK: ----- Generalized NSS_TaggedItem template chooser support -----
 
 /*
  * Generalized Template chooser.
 
 /*
  * Generalized Template chooser.
@@ -88,7 +88,7 @@ const SecAsn1Template * SecAsn1TaggedTemplateChooser(
        return templ;
 }
 
        return templ;
 }
 
-#pragma mark ----- X509 Name, RDN ------
+// MARK: ----- X509 Name, RDN ------
 
 /* AttributeTypeAndValue */
 
 
 /* AttributeTypeAndValue */
 
@@ -139,7 +139,7 @@ const SecAsn1Template kSecAsn1NameTemplate[] = {
          offsetof(NSS_Name,rdns), kSecAsn1RDNTemplate, sizeof(NSS_Name) }
 };
 
          offsetof(NSS_Name,rdns), kSecAsn1RDNTemplate, sizeof(NSS_Name) }
 };
 
-#pragma mark ----- OtherName, GeneralizedName -----
+// MARK: ----- OtherName, GeneralizedName -----
 
 /*
  * CE_OtherName.value expressed as ASN_ANY, not en/decoded.
 
 /*
  * CE_OtherName.value expressed as ASN_ANY, not en/decoded.
index c8a213433f7cc21d6e28c21619f2a39e6fa89633..0e55eae8f9ec6dfc54d0d5d25801fffeffd334b3 100644 (file)
@@ -32,7 +32,7 @@
 extern "C" {
 #endif
 
 extern "C" {
 #endif
 
-#pragma mark ----- Generalized NSS_TaggedItem template chooser support -----
+// MARK: ----- Generalized NSS_TaggedItem template chooser support -----
 
 /*
  * A tagged item for use with simple CHOICE types implemented
 
 /*
  * A tagged item for use with simple CHOICE types implemented
@@ -65,7 +65,7 @@ const SecAsn1Template * SecAsn1TaggedTemplateChooser(
        /* array of tag/template pairs */
        const NSS_TagChoice *chooser);
 
        /* array of tag/template pairs */
        const NSS_TagChoice *chooser);
 
-#pragma mark ----- X509 Name, RDN ------
+// MARK: ----- X509 Name, RDN ------
 
 /* 
  * ASN class : AttributeTypeAndValue
 
 /* 
  * ASN class : AttributeTypeAndValue
@@ -118,7 +118,7 @@ extern const SecAsn1Template kSecAsn1ATVTemplate[];
 extern const SecAsn1Template kSecAsn1RDNTemplate[];
 extern const SecAsn1Template kSecAsn1NameTemplate[];
 
 extern const SecAsn1Template kSecAsn1RDNTemplate[];
 extern const SecAsn1Template kSecAsn1NameTemplate[];
 
-#pragma mark ----- OtherName, GeneralizedName -----
+// MARK: ----- OtherName, GeneralizedName -----
 
 /* 
  * ASN Class : OtherName
 
 /* 
  * ASN Class : OtherName
index 838408e63c073d025da36d4f811503d879596fb6..6c642fb386922ab31fce0c319c0175b34ec66578 100644 (file)
@@ -37,7 +37,7 @@
 #include <pthread.h>
 #include <string.h>
 
 #include <pthread.h>
 #include <string.h>
 
-#pragma mark *** Memory ***
+// MARK: *** Memory ***
 
 NSPR_API(void *) PR_Malloc(PRSize size)
 {
 
 NSPR_API(void *) PR_Malloc(PRSize size)
 {
@@ -56,7 +56,7 @@ NSPR_API(void) PR_Free(void *ptr)
        return free(ptr);
 }
 
        return free(ptr);
 }
 
-#pragma mark *** locks ***
+// MARK: *** locks ***
 
 NSPR_API(PRLock*) PR_NewLock(void)
 {
 
 NSPR_API(PRLock*) PR_NewLock(void)
 {
@@ -97,7 +97,7 @@ NSPR_API(PRStatus) PR_Unlock(PRLock *lock)
        return PR_SUCCESS;
 }
 
        return PR_SUCCESS;
 }
 
-#pragma mark *** get/set error ***
+// MARK: *** get/set error ***
 
 /* 
  * key for pthread_{set,get}specific and a lock to ensure it gets 
 
 /* 
  * key for pthread_{set,get}specific and a lock to ensure it gets 
@@ -235,7 +235,7 @@ PR_IMPLEMENT(void) PR_SetError(PRErrorCode code, PRInt32 osErr)
        /* else per-thread logic uninitialized */
 }
 
        /* else per-thread logic uninitialized */
 }
 
-#pragma mark *** misc. ***
+// MARK: *** misc. ***
 
 /*
 ** Compute the log of the least power of 2 greater than or equal to n
 
 /*
 ** Compute the log of the least power of 2 greater than or equal to n
index 798f3212b0a6902153ef949bcb9fb26ae68246d0..fb32f56a6377bf4d26e31b7f1eded6a49656bbc7 100644 (file)
@@ -29,7 +29,7 @@
 #include <stddef.h>
 #include <assert.h>
 
 #include <stddef.h>
 #include <assert.h>
 
-#pragma mark ----- OCSP Request -----
+// MARK: ----- OCSP Request -----
 
 const SecAsn1Template kSecAsn1OCSPCertIDTemplate[] = {
     { SEC_ASN1_SEQUENCE,
 
 const SecAsn1Template kSecAsn1OCSPCertIDTemplate[] = {
     { SEC_ASN1_SEQUENCE,
@@ -107,7 +107,7 @@ const SecAsn1Template kSecAsn1OCSPSignedRequestTemplate[] = {
     { 0 }
 };
 
     { 0 }
 };
 
-#pragma mark ----- OCSP Response -----
+// MARK: ----- OCSP Response -----
 
 const SecAsn1Template kSecAsn1OCSPRevokedInfoTemplate[] = {
     { SEC_ASN1_SEQUENCE,
 
 const SecAsn1Template kSecAsn1OCSPRevokedInfoTemplate[] = {
     { SEC_ASN1_SEQUENCE,
@@ -240,7 +240,7 @@ const SecAsn1Template kSecAsn1OCSPResponseTemplate[] = {
     { 0 }
 };
 
     { 0 }
 };
 
-#pragma mark ---- OCSPD RPC ----
+// MARK: ---- OCSPD RPC ----
 
 const SecAsn1Template kSecAsn1OCSPDRequestTemplate[] = {
     { SEC_ASN1_SEQUENCE,
 
 const SecAsn1Template kSecAsn1OCSPDRequestTemplate[] = {
     { SEC_ASN1_SEQUENCE,
index 6124d84719545cd0c67ae7a1d8c669033f31d27f..af742a379bc87f8e034c818a512373241a710010 100644 (file)
@@ -33,7 +33,7 @@
 extern "C" {
 #endif
 
 extern "C" {
 #endif
 
-#pragma mark ----- OCSP Request -----
+// MARK: ----- OCSP Request -----
 
 /*
  * CertID          ::=     SEQUENCE {
 
 /*
  * CertID          ::=     SEQUENCE {
@@ -109,7 +109,7 @@ typedef struct {
 
 extern const SecAsn1Template kSecAsn1OCSPSignedRequestTemplate[];
 
 
 extern const SecAsn1Template kSecAsn1OCSPSignedRequestTemplate[];
 
-#pragma mark ----- OCSP Response -----
+// MARK: ----- OCSP Response -----
 
 /*
  * CertStatus ::= CHOICE {
 
 /*
  * CertStatus ::= CHOICE {
index 3c95a3cba4368b8d58ee11b3d0a5efb69a3febc8..4eae7bf2225ea5e9369bd7bda3af6c7f9c051922 100644 (file)
@@ -228,6 +228,27 @@ APPLE_TP_MACAPPSTORE_RECEIPT[]     = {APPLE_TP_OID, 19},
 /* Apple Time Stamping Server Cert Policy := { appleTrustPolicy 20 } */
 APPLE_TP_TIMESTAMPING[]                        = {APPLE_TP_OID, 20},
 
 /* Apple Time Stamping Server Cert Policy := { appleTrustPolicy 20 } */
 APPLE_TP_TIMESTAMPING[]                        = {APPLE_TP_OID, 20},
 
+/* Apple Revocation Policy := { appleTrustPolicy 21 } */
+APPLE_TP_REVOCATION[]                  = {APPLE_TP_OID, 21},
+
+/* Apple Passbook Signing Policy := { appleTrustPolicy 22 } */
+APPLE_TP_PASSBOOK_SIGNING[]                    = {APPLE_TP_OID, 22},
+
+/* Apple Mobile Store Policy := { appleTrustPolicy 23 } */
+APPLE_TP_MOBILE_STORE[]                        = {APPLE_TP_OID, 23},
+
+/* Apple Escrow Service Policy := { appleTrustPolicy 24 } */
+APPLE_TP_ESCROW_SERVICE[]                      = {APPLE_TP_OID, 24},
+
+/* Apple Configuration Profile Signing Policy := { appleTrustPolicy 25 } */
+APPLE_TP_PROFILE_SIGNING[]                     = {APPLE_TP_OID, 25},
+
+/* Apple QA Configuration Profile Signing Policy := { appleTrustPolicy 26 } */
+APPLE_TP_QA_PROFILE_SIGNING[]          = {APPLE_TP_OID, 26},
+
+/* Apple Test Mobile Store Policy := { appleTrustPolicy 27 } */
+APPLE_TP_TEST_MOBILE_STORE[]           = {APPLE_TP_OID, 27},
+
 /*
  *     fee OBJECT IDENTIFIER ::=
  *             { appleSecurityAlgorithm 1 }
 /*
  *     fee OBJECT IDENTIFIER ::=
  *             { appleSecurityAlgorithm 1 }
@@ -343,6 +364,13 @@ CSSMOID_APPLE_TP_PACKAGE_SIGNING = {APPLE_TP_OID_LENGTH+1,  (uint8_t *)APPLE_TP_
 CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT = {APPLE_TP_OID_LENGTH+1,  (uint8_t *)APPLE_TP_MACAPPSTORE_RECEIPT},
 CSSMOID_APPLE_TP_APPLEID_SHARING = {APPLE_TP_OID_LENGTH+1,  (uint8_t *)APPLE_TP_APPLEID_SHARING},
 CSSMOID_APPLE_TP_TIMESTAMPING = {APPLE_TP_OID_LENGTH+1, (uint8_t *)APPLE_TP_TIMESTAMPING},
 CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT = {APPLE_TP_OID_LENGTH+1,  (uint8_t *)APPLE_TP_MACAPPSTORE_RECEIPT},
 CSSMOID_APPLE_TP_APPLEID_SHARING = {APPLE_TP_OID_LENGTH+1,  (uint8_t *)APPLE_TP_APPLEID_SHARING},
 CSSMOID_APPLE_TP_TIMESTAMPING = {APPLE_TP_OID_LENGTH+1, (uint8_t *)APPLE_TP_TIMESTAMPING},
+CSSMOID_APPLE_TP_REVOCATION = {APPLE_TP_OID_LENGTH+1, (uint8_t *)APPLE_TP_REVOCATION},
+CSSMOID_APPLE_TP_PASSBOOK_SIGNING = {APPLE_TP_OID_LENGTH+1, (uint8_t *)APPLE_TP_PASSBOOK_SIGNING},
+CSSMOID_APPLE_TP_MOBILE_STORE = {APPLE_TP_OID_LENGTH+1, (uint8_t *)APPLE_TP_MOBILE_STORE},
+CSSMOID_APPLE_TP_ESCROW_SERVICE = {APPLE_TP_OID_LENGTH+1, (uint8_t *)APPLE_TP_ESCROW_SERVICE},
+CSSMOID_APPLE_TP_PROFILE_SIGNING = {APPLE_TP_OID_LENGTH+1, (uint8_t *)APPLE_TP_PROFILE_SIGNING},
+CSSMOID_APPLE_TP_QA_PROFILE_SIGNING = {APPLE_TP_OID_LENGTH+1, (uint8_t *)APPLE_TP_QA_PROFILE_SIGNING},
+CSSMOID_APPLE_TP_TEST_MOBILE_STORE = {APPLE_TP_OID_LENGTH+1, (uint8_t *)APPLE_TP_TEST_MOBILE_STORE},
 CSSMOID_APPLE_FEE        = {APPLE_ALG_OID_LENGTH+1, (uint8_t *)APPLE_FEE},
 CSSMOID_APPLE_ASC        = {APPLE_ALG_OID_LENGTH+1, (uint8_t *)APPLE_ASC},
 CSSMOID_APPLE_FEE_MD5    = {APPLE_ALG_OID_LENGTH+1, (uint8_t *)APPLE_FEE_MD5},
 CSSMOID_APPLE_FEE        = {APPLE_ALG_OID_LENGTH+1, (uint8_t *)APPLE_FEE},
 CSSMOID_APPLE_ASC        = {APPLE_ALG_OID_LENGTH+1, (uint8_t *)APPLE_ASC},
 CSSMOID_APPLE_FEE_MD5    = {APPLE_ALG_OID_LENGTH+1, (uint8_t *)APPLE_FEE_MD5},
index a63dc097198b11a72fc45a90ca3160548cb3bcd9..b1c1df20cfa57aeaf0fabbf8afc86c9144e11d91 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 1999-2004,2008,2010,2012 Apple Inc. All Rights Reserved.
+ * Copyright (c) 1999-2004,2008-2013 Apple Inc. All Rights Reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -33,123 +33,130 @@ extern "C" {
 #endif
 
 extern const SecAsn1Oid
 #endif
 
 extern const SecAsn1Oid
-       CSSMOID_MD2 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_MD4 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_MD5 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_RSA DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_MD2WithRSA DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_MD4WithRSA DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_MD5WithRSA DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_SHA1WithRSA DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_SHA224WithRSA DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_SHA256WithRSA DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_SHA384WithRSA DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_SHA512WithRSA DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_SHA1WithRSA_OIW DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_RSAWithOAEP DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_OAEP_MGF1 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_OAEP_ID_PSPECIFIED DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_DES_CBC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_ANSI_DH_PUB_NUMBER DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_ANSI_DH_STATIC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_ANSI_DH_ONE_FLOW DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_ANSI_DH_EPHEM DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_ANSI_DH_HYBRID1 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_ANSI_DH_HYBRID2 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_ANSI_DH_HYBRID_ONEFLOW DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_ANSI_MQV1 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_ANSI_MQV2 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_ANSI_DH_STATIC_SHA1 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_ANSI_DH_ONE_FLOW_SHA1 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_ANSI_DH_EPHEM_SHA1 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_ANSI_DH_HYBRID1_SHA1 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_ANSI_DH_HYBRID2_SHA1 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_ANSI_MQV1_SHA1 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_ANSI_MQV2_SHA1 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_PKCS3 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_DH DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
+       CSSMOID_MD2 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_MD4 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_MD5 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_RSA DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_MD2WithRSA DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_MD4WithRSA DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_MD5WithRSA DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_SHA1WithRSA DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_SHA224WithRSA DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_SHA256WithRSA DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_SHA384WithRSA DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_SHA512WithRSA DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_SHA1WithRSA_OIW DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_RSAWithOAEP DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_OAEP_MGF1 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_OAEP_ID_PSPECIFIED DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_DES_CBC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_ANSI_DH_PUB_NUMBER DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_ANSI_DH_STATIC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_ANSI_DH_ONE_FLOW DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_ANSI_DH_EPHEM DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_ANSI_DH_HYBRID1 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_ANSI_DH_HYBRID2 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_ANSI_DH_HYBRID_ONEFLOW DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_ANSI_MQV1 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_ANSI_MQV2 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_ANSI_DH_STATIC_SHA1 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_ANSI_DH_ONE_FLOW_SHA1 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_ANSI_DH_EPHEM_SHA1 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_ANSI_DH_HYBRID1_SHA1 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_ANSI_DH_HYBRID2_SHA1 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_ANSI_MQV1_SHA1 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_ANSI_MQV2_SHA1 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_PKCS3 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_DH DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_DSA DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,                              // BSAFE only
        CSSMOID_DSA_CMS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,                  // X509/CMS
        CSSMOID_DSA_JDK DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,                  // JDK 1.1
        CSSMOID_SHA1WithDSA DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,              // BSAFE
        CSSMOID_DSA DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,                              // BSAFE only
        CSSMOID_DSA_CMS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,                  // X509/CMS
        CSSMOID_DSA_JDK DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,                  // JDK 1.1
        CSSMOID_SHA1WithDSA DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,              // BSAFE
-       CSSMOID_SHA1WithDSA_CMS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,  // X509/CMS     
+       CSSMOID_SHA1WithDSA_CMS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,  // X509/CMS
        CSSMOID_SHA1WithDSA_JDK DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,  // JDK 1.1
        CSSMOID_SHA1WithDSA_JDK DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,  // JDK 1.1
-       CSSMOID_SHA1 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_SHA224 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_SHA256 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_SHA384 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_SHA512 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_ecPublicKey DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_ECDSA_WithSHA1 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_ECDSA_WithSHA224 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_ECDSA_WithSHA256 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_ECDSA_WithSHA384 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_ECDSA_WithSHA512 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_ECDSA_WithSpecified DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_ISIGN DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_X509_BASIC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_TP_SSL DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_TP_LOCAL_CERT_GEN DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_TP_CSR_GEN DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_TP_REVOCATION_CRL DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_TP_REVOCATION_OCSP DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_TP_SMIME DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_TP_EAP DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_TP_CODE_SIGN DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_TP_SW_UPDATE_SIGNING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_TP_IP_SEC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_TP_ICHAT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_TP_RESOURCE_SIGN DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_TP_PKINIT_CLIENT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_TP_PKINIT_SERVER DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_TP_CODE_SIGNING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_TP_PACKAGE_SIGNING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
+       CSSMOID_SHA1 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_SHA224 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_SHA256 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_SHA384 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_SHA512 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_ecPublicKey DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_ECDSA_WithSHA1 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_ECDSA_WithSHA224 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_ECDSA_WithSHA256 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_ECDSA_WithSHA384 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_ECDSA_WithSHA512 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_ECDSA_WithSpecified DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_ISIGN DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_X509_BASIC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_TP_SSL DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_TP_LOCAL_CERT_GEN DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_TP_CSR_GEN DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_TP_REVOCATION_CRL DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_TP_REVOCATION_OCSP DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_TP_SMIME DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_TP_EAP DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_TP_CODE_SIGN DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_TP_SW_UPDATE_SIGNING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_TP_IP_SEC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_TP_ICHAT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_TP_RESOURCE_SIGN DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_TP_PKINIT_CLIENT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_TP_PKINIT_SERVER DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_TP_CODE_SIGNING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_TP_PACKAGE_SIGNING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
-       CSSMOID_APPLE_TP_APPLEID_SHARING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
+       CSSMOID_APPLE_TP_APPLEID_SHARING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_APPLE_TP_TIMESTAMPING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_APPLE_TP_TIMESTAMPING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
-       CSSMOID_APPLE_FEE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_ASC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_FEE_MD5 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_FEE_SHA1 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_FEED DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_FEEDEXP DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_ECDSA DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_DOTMAC_CERT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_DOTMAC_CERT_REQ DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_DOTMAC_CERT_REQ_IDENTITY DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_DOTMAC_CERT_REQ_EMAIL_SIGN DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_DOTMAC_CERT_REQ_EMAIL_ENCRYPT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_DOTMAC_CERT_REQ_ARCHIVE_LIST DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_DOTMAC_CERT_REQ_ARCHIVE_STORE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_DOTMAC_CERT_REQ_ARCHIVE_FETCH DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_DOTMAC_CERT_REQ_ARCHIVE_REMOVE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_DOTMAC_CERT_REQ_SHARED_SERVICES DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_DOTMAC_CERT_REQ_VALUE_USERNAME DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_DOTMAC_CERT_REQ_VALUE_PASSWORD DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_DOTMAC_CERT_REQ_VALUE_HOSTNAME DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_DOTMAC_CERT_REQ_VALUE_RENEW DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_DOTMAC_CERT_REQ_VALUE_ASYNC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_DOTMAC_CERT_REQ_VALUE_IS_PENDING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_PKCS5_DIGEST_ALG DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_PKCS5_ENCRYPT_ALG DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_PKCS5_HMAC_SHA1 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_PKCS5_pbeWithMD2AndDES DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_PKCS5_pbeWithMD2AndRC2 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_PKCS5_pbeWithMD5AndDES DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_PKCS5_pbeWithMD5AndRC2 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_PKCS5_pbeWithSHA1AndDES DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_PKCS5_pbeWithSHA1AndRC2 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_PKCS5_PBKDF2 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_PKCS5_PBES2 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_PKCS5_PBMAC1 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_PKCS5_RC2_CBC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_PKCS5_DES_EDE3_CBC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_PKCS5_RC5_CBC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_PKCS12_pbeWithSHAAnd128BitRC4 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_PKCS12_pbeWithSHAAnd40BitRC4 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_PKCS12_pbeWithSHAAnd3Key3DESCBC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_PKCS12_pbeWithSHAAnd2Key3DESCBC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_PKCS12_pbeWithSHAAnd128BitRC2CBC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
+       CSSMOID_APPLE_TP_REVOCATION DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_TP_PASSBOOK_SIGNING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_TP_MOBILE_STORE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_TP_ESCROW_SERVICE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_TP_PROFILE_SIGNING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_TP_QA_PROFILE_SIGNING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_TP_TEST_MOBILE_STORE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_FEE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_ASC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_FEE_MD5 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_FEE_SHA1 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_FEED DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_FEEDEXP DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_ECDSA DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_DOTMAC_CERT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_DOTMAC_CERT_REQ DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_DOTMAC_CERT_REQ_IDENTITY DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_DOTMAC_CERT_REQ_EMAIL_SIGN DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_DOTMAC_CERT_REQ_EMAIL_ENCRYPT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_DOTMAC_CERT_REQ_ARCHIVE_LIST DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_DOTMAC_CERT_REQ_ARCHIVE_STORE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_DOTMAC_CERT_REQ_ARCHIVE_FETCH DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_DOTMAC_CERT_REQ_ARCHIVE_REMOVE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_DOTMAC_CERT_REQ_SHARED_SERVICES DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_DOTMAC_CERT_REQ_VALUE_USERNAME DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_DOTMAC_CERT_REQ_VALUE_PASSWORD DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_DOTMAC_CERT_REQ_VALUE_HOSTNAME DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_DOTMAC_CERT_REQ_VALUE_RENEW DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_DOTMAC_CERT_REQ_VALUE_ASYNC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_DOTMAC_CERT_REQ_VALUE_IS_PENDING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_PKCS5_DIGEST_ALG DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_PKCS5_ENCRYPT_ALG DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_PKCS5_HMAC_SHA1 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_PKCS5_pbeWithMD2AndDES DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_PKCS5_pbeWithMD2AndRC2 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_PKCS5_pbeWithMD5AndDES DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_PKCS5_pbeWithMD5AndRC2 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_PKCS5_pbeWithSHA1AndDES DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_PKCS5_pbeWithSHA1AndRC2 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_PKCS5_PBKDF2 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_PKCS5_PBES2 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_PKCS5_PBMAC1 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_PKCS5_RC2_CBC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_PKCS5_DES_EDE3_CBC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_PKCS5_RC5_CBC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_PKCS12_pbeWithSHAAnd128BitRC4 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_PKCS12_pbeWithSHAAnd40BitRC4 DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_PKCS12_pbeWithSHAAnd3Key3DESCBC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_PKCS12_pbeWithSHAAnd2Key3DESCBC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_PKCS12_pbeWithSHAAnd128BitRC2CBC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_PKCS12_pbewithSHAAnd40BitRC2CBC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
 
 #ifdef __cplusplus
        CSSMOID_PKCS12_pbewithSHAAnd40BitRC2CBC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
 
 #ifdef __cplusplus
index 2df01047d6effeb2c751805fadc5b6877adce548..38e274a7c0f7eb037a0c0978b76fa8fe24f60469 100644 (file)
@@ -47,7 +47,7 @@ extern "C" {
  *** security_asn1/keyTemplates.h.
  ***/
  
  *** security_asn1/keyTemplates.h.
  ***/
  
-#pragma mark *** DSA ***
+// MARK: *** DSA ***
 
 /* 
  * Note that most of the DSA structs are hand rolled and are not
 
 /* 
  * Note that most of the DSA structs are hand rolled and are not
index 05fe8f15faf15fc67f145bec413fa2e77c7e3bf8..45ea88463dc5ed1fb4c63982b42862cf011d0579 100644 (file)
@@ -64,7 +64,7 @@ typedef struct {
 
 extern const SecAsn1Template NSS_P7_RawContentInfoTemplate[];
 
 
 extern const SecAsn1Template NSS_P7_RawContentInfoTemplate[];
 
-#pragma mark ---- ContentInfo.content types -----
+// MARK: ---- ContentInfo.content types -----
 
 /*
  * Expand beyond ASN_ANY/CSSM_DATA as needed
 
 /*
  * Expand beyond ASN_ANY/CSSM_DATA as needed
@@ -115,7 +115,7 @@ extern const SecAsn1Template NSS_P7_PtrToEncryptedDataTemplate[];
 #define NSS_P7_PtrToSignEnvelDataTemplate      kSecAsn1PointerToAnyTemplate
 #define NSS_P7_PtrToDigestedDataTemplate       kSecAsn1PointerToAnyTemplate
 
 #define NSS_P7_PtrToSignEnvelDataTemplate      kSecAsn1PointerToAnyTemplate
 #define NSS_P7_PtrToDigestedDataTemplate       kSecAsn1PointerToAnyTemplate
 
-#pragma mark ---- decoded ContentInfo -----
+// MARK: ---- decoded ContentInfo -----
 
 /*
  * For convenience, out dynamic template chooser for ContentInfo.content
 
 /*
  * For convenience, out dynamic template chooser for ContentInfo.content
index 8f20af238ae893f30d6fba1d567ac28bd684d76b..d4b6d2e3adbcd31c11a2005f54c93e96f840b9d6 100644 (file)
@@ -1335,7 +1335,7 @@ regular_string_type:
            struct subitem *subitem;
            unsigned long len;
 
            struct subitem *subitem;
            unsigned long len;
 
-           PORT_Assert (item->Length == 0 && item->Data == NULL);
+           PORT_Assert (item != NULL && item->Length == 0 && item->Data == NULL);
            /*
             * Check for and handle an ANY which has stashed aside the
             * header (identifier and length) bytes for us to include
            /*
             * Check for and handle an ANY which has stashed aside the
             * header (identifier and length) bytes for us to include
index 1c1d7679718cda1b6fb03dcc655efa165610e962..93f2d1c87979081d4b375db7963422a2371a7e9f 100644 (file)
@@ -11,7 +11,7 @@
                1885B45314D9BB1A00519375 /* SecNssCoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C6434280534D3B800F287B2 /* SecNssCoder.cpp */; };
                18B6B2A714DB73A000EDDE5F /* secErrorStr.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C6434270534D3B800F287B2 /* secErrorStr.c */; };
                4C28246B0F1BC75800CAADEC /* oidsocsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2824670F1BC75800CAADEC /* oidsocsp.c */; };
                1885B45314D9BB1A00519375 /* SecNssCoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C6434280534D3B800F287B2 /* SecNssCoder.cpp */; };
                18B6B2A714DB73A000EDDE5F /* secErrorStr.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C6434270534D3B800F287B2 /* secErrorStr.c */; };
                4C28246B0F1BC75800CAADEC /* oidsocsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2824670F1BC75800CAADEC /* oidsocsp.c */; };
-               4C28246C0F1BC75800CAADEC /* oidsocsp.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C2824680F1BC75800CAADEC /* oidsocsp.h */; };
+               4C28246C0F1BC75800CAADEC /* oidsocsp.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C2824680F1BC75800CAADEC /* oidsocsp.h */; settings = {ATTRIBUTES = (Public, ); }; };
                795CA8220D38041D00BAE6A2 /* SecAsn1Coder.c in Sources */ = {isa = PBXBuildFile; fileRef = 0545C7B806502D1100543007 /* SecAsn1Coder.c */; };
                795CA8230D38041D00BAE6A2 /* SecAsn1Coder.h in Headers */ = {isa = PBXBuildFile; fileRef = 0545C7B906502D1100543007 /* SecAsn1Coder.h */; settings = {ATTRIBUTES = (Public, ); }; };
                795CA8240D38041D00BAE6A2 /* SecAsn1Templates.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C6433F80534D3B800F287B2 /* SecAsn1Templates.c */; };
                795CA8220D38041D00BAE6A2 /* SecAsn1Coder.c in Sources */ = {isa = PBXBuildFile; fileRef = 0545C7B806502D1100543007 /* SecAsn1Coder.c */; };
                795CA8230D38041D00BAE6A2 /* SecAsn1Coder.h in Headers */ = {isa = PBXBuildFile; fileRef = 0545C7B906502D1100543007 /* SecAsn1Coder.h */; settings = {ATTRIBUTES = (Public, ); }; };
                795CA8240D38041D00BAE6A2 /* SecAsn1Templates.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C6433F80534D3B800F287B2 /* SecAsn1Templates.c */; };
                9D56980C03E74D6100003D05 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
                9D56980C03E74D6100003D05 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0430;
+                               LastUpgradeCheck = 0500;
                        };
                        buildConfigurationList = C23B0CEC09A298C500B7FCED /* Build configuration list for PBXProject "libsecurity_asn1" */;
                        compatibilityVersion = "Xcode 3.2";
                        };
                        buildConfigurationList = C23B0CEC09A298C500B7FCED /* Build configuration list for PBXProject "libsecurity_asn1" */;
                        compatibilityVersion = "Xcode 3.2";
 /* Begin XCBuildConfiguration section */
                795CA8090D3801A700BAE6A2 /* Debug */ = {
                        isa = XCBuildConfiguration;
 /* Begin XCBuildConfiguration section */
                795CA8090D3801A700BAE6A2 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 18B647F714D9FD4500F538BF /* lib.xcconfig */;
+                       baseConfigurationReference = 18B647F614D9FD4500F538BF /* debug.xcconfig */;
                        buildSettings = {
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Debug;
                };
                795CA80D0D3801A700BAE6A2 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Debug;
                };
                795CA80D0D3801A700BAE6A2 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 18B647F614D9FD4500F538BF /* debug.xcconfig */;
+                       baseConfigurationReference = 18B647F714D9FD4500F538BF /* lib.xcconfig */;
                        buildSettings = {
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                LIBRARY_STYLE = STATIC;
                        };
                        name = Debug;
                };
                795CA8180D3801A900BAE6A2 /* Release */ = {
                        isa = XCBuildConfiguration;
                                LIBRARY_STYLE = STATIC;
                        };
                        name = Debug;
                };
                795CA8180D3801A900BAE6A2 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 18B647F714D9FD4500F538BF /* lib.xcconfig */;
+                       baseConfigurationReference = 18B647F814D9FD4500F538BF /* release.xcconfig */;
                        buildSettings = {
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Release;
                };
                795CA81C0D3801A900BAE6A2 /* Release */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Release;
                };
                795CA81C0D3801A900BAE6A2 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 18B647F814D9FD4500F538BF /* release.xcconfig */;
+                       baseConfigurationReference = 18B647F714D9FD4500F538BF /* lib.xcconfig */;
                        buildSettings = {
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                LIBRARY_STYLE = STATIC;
                        };
                        name = Release;
                                LIBRARY_STYLE = STATIC;
                        };
                        name = Release;
index dd218be0f72d1eaf1b59755b5e22affb3a495ad0..65c01918eee5deedff71f462d94bffea84615985 100644 (file)
@@ -141,7 +141,7 @@ enum {
         
     @param attributes (output/optional) Receives the attribute bits for the session.
 
         
     @param attributes (output/optional) Receives the attribute bits for the session.
 
-    @result An OSStatus indicating success (noErr) or an error cause.
+    @result An OSStatus indicating success (errSecSuccess) or an error cause.
     
     errSessionInvalidId -60500 Invalid session id specified
 
     
     errSessionInvalidId -60500 Invalid session id specified
 
@@ -176,7 +176,7 @@ OSStatus SessionGetInfo(SecuritySessionId session,
     @param attributes The set of attribute bits to set for the new session.
         Not all bits can be set this way.
     
     @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.
+    @result An OSStatus indicating success (errSecSuccess) or an error cause.
     
     errSessionInvalidAttributes -60501 Attempt to set invalid attribute bits   
     errSessionAuthorizationDenied -60502 Attempt to re-initialize a session
     
     errSessionInvalidAttributes -60501 Attempt to set invalid attribute bits   
     errSessionAuthorizationDenied -60502 Attempt to re-initialize a session
diff --git a/libsecurity_authorization/lib/Authorization.c b/libsecurity_authorization/lib/Authorization.c
new file mode 100644 (file)
index 0000000..dde4d1a
--- /dev/null
@@ -0,0 +1,719 @@
+/* Copyright (c) 2012 Apple Inc. All rights reserved. */
+
+#include "Authorization.h"
+#include "authd_private.h"
+#include "authutilities.h"
+#include "debugging.h"
+
+#include <Security/AuthorizationPriv.h>
+#include <Security/AuthorizationDB.h>
+#include <Security/AuthorizationTags.h>
+#include <Security/AuthorizationTagsPriv.h>
+#include <xpc/xpc.h>
+#include <xpc/private.h>
+#include <mach/mach.h>
+#include <syslog.h>
+#include <AssertMacros.h>
+#include <CoreFoundation/CFXPCBridge.h>
+
+static dispatch_queue_t
+get_authorization_dispatch_queue()
+{
+    static dispatch_once_t onceToken = 0;
+    static dispatch_queue_t connection_queue = NULL;
+    dispatch_once(&onceToken, ^{
+        connection_queue = dispatch_queue_create("authorization-connection-queue", DISPATCH_QUEUE_SERIAL);
+    });
+    
+    return connection_queue;
+}
+
+static xpc_connection_t
+get_authorization_connection()
+{
+    static xpc_connection_t connection = NULL;
+    
+    dispatch_sync(get_authorization_dispatch_queue(), ^{
+        if (connection == NULL) {
+            connection = xpc_connection_create(SECURITY_AUTH_NAME, NULL);
+
+            if (!connection) {
+                syslog(LOG_ERR, "Authorization, failed to create xpc connection to %s", SECURITY_AUTH_NAME);
+                connection = xpc_connection_create(SECURITY_AUTH_NAME, NULL);
+            }
+            
+            xpc_connection_set_event_handler(connection, ^(xpc_object_t event) {
+                if (xpc_get_type(event) == XPC_TYPE_ERROR) {
+                    if (event == XPC_ERROR_CONNECTION_INVALID) {
+                        syslog(LOG_ERR, "Authorization, server not available");
+                    }
+                    // XPC_ERROR_CONNECTION_INTERRUPTED
+                    // XPC_ERROR_TERMINATION_IMMINENT
+                } else {
+                    char * desc = xpc_copy_description(event);
+                    syslog(LOG_ERR, "Authorization, we should never get messages on this connection: %s", desc);
+                    free(desc);
+                }
+            });
+            
+            xpc_connection_resume(connection);
+            
+            // Send
+            xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
+            xpc_dictionary_set_uint64(message, AUTH_XPC_TYPE, AUTHORIZATION_SETUP);
+            mach_port_t bootstrap = MACH_PORT_NULL;
+            task_get_bootstrap_port(mach_task_self(), &bootstrap);
+            xpc_dictionary_set_mach_send(message, AUTH_XPC_BOOTSTRAP, bootstrap);
+            xpc_object_t reply = xpc_connection_send_message_with_reply_sync(connection, message);
+            xpc_release_safe(message);
+            xpc_release_safe(reply);
+        }
+    });
+    
+    return connection;
+}
+
+static void
+setItemSet(xpc_object_t message, const char * key, const AuthorizationItemSet * itemSet)
+{
+    xpc_object_t serialized = SerializeItemSet(itemSet);
+    if (serialized) {
+        xpc_dictionary_set_value(message, key, serialized);
+        xpc_release(serialized);
+    }
+}
+
+OSStatus AuthorizationCreate(const AuthorizationRights *rights,
+                    const AuthorizationEnvironment *environment,
+                    AuthorizationFlags flags,
+                    AuthorizationRef *authorization)
+{
+    OSStatus status = errAuthorizationInternal;
+    xpc_object_t message = NULL;
+    xpc_object_t reply = NULL;
+
+//    require_action(!(rights == NULL && authorization == NULL), done, status = errAuthorizationInvalidSet);
+    
+    // Send
+    message = xpc_dictionary_create(NULL, NULL, 0);
+    require_action(message != NULL, done, status = errAuthorizationInternal);
+    
+    xpc_dictionary_set_uint64(message, AUTH_XPC_TYPE, AUTHORIZATION_CREATE);
+    setItemSet(message, AUTH_XPC_RIGHTS, rights);
+    setItemSet(message, AUTH_XPC_ENVIROMENT, environment);
+    xpc_dictionary_set_uint64(message, AUTH_XPC_FLAGS, flags | (authorization ? 0 : kAuthorizationFlagNoData));
+    
+    // Reply
+    reply = xpc_connection_send_message_with_reply_sync(get_authorization_connection(), message);
+    require_action(reply != NULL, done, status = errAuthorizationInternal);
+    require_action(xpc_get_type(reply) != XPC_TYPE_ERROR, done, status = errAuthorizationInternal);
+
+    // Status
+    status = (OSStatus)xpc_dictionary_get_int64(reply, AUTH_XPC_STATUS);
+    
+    // Out
+    if (authorization && status == errAuthorizationSuccess) {
+        size_t len;
+        const void * data = xpc_dictionary_get_data(reply, AUTH_XPC_BLOB, &len);
+        require_action(data != NULL, done, status = errAuthorizationInternal);
+        assert(len == sizeof(AuthorizationBlob));
+        
+        AuthorizationBlob * blob = (AuthorizationBlob*)calloc(1u, sizeof(AuthorizationBlob));
+        require_action(blob != NULL, done, status = errAuthorizationInternal);
+        *blob = *(AuthorizationBlob*)data;
+        
+        *authorization = (AuthorizationRef)blob;
+    }
+
+done:
+    xpc_release_safe(message);
+    xpc_release_safe(reply);
+    return status;
+}
+
+OSStatus AuthorizationCreateWithAuditToken(audit_token_t token,
+                                 const AuthorizationEnvironment *environment,
+                                 AuthorizationFlags flags,
+                                 AuthorizationRef *authorization)
+{
+    OSStatus status = errAuthorizationInternal;
+    xpc_object_t message = NULL;
+    xpc_object_t reply = NULL;
+    
+    require_action(authorization != NULL, done, status = errAuthorizationInvalidPointer);
+    
+    // Send
+    message = xpc_dictionary_create(NULL, NULL, 0);
+    require_action(message != NULL, done, status = errAuthorizationInternal);
+    
+    xpc_dictionary_set_uint64(message, AUTH_XPC_TYPE, AUTHORIZATION_CREATE_WITH_AUDIT_TOKEN);
+    xpc_dictionary_set_data(message, AUTH_XPC_DATA, &token, sizeof(token));
+    setItemSet(message, AUTH_XPC_ENVIROMENT, environment);
+    xpc_dictionary_set_uint64(message, AUTH_XPC_FLAGS, flags);
+    
+    // Reply
+    reply = xpc_connection_send_message_with_reply_sync(get_authorization_connection(), message);
+    require_action(reply != NULL, done, status = errAuthorizationInternal);
+    require_action(xpc_get_type(reply) != XPC_TYPE_ERROR, done, status = errAuthorizationInternal);
+    
+    // Status
+    status = (OSStatus)xpc_dictionary_get_int64(reply, AUTH_XPC_STATUS);
+    
+    // Out
+    if (status == errAuthorizationSuccess) {
+        size_t len;
+        const void * data = xpc_dictionary_get_data(reply, AUTH_XPC_BLOB, &len);
+        require_action(data != NULL, done, status = errAuthorizationInternal);
+        assert(len == sizeof(AuthorizationBlob));
+        
+        AuthorizationBlob * blob = (AuthorizationBlob*)calloc(1u, sizeof(AuthorizationBlob));
+        require_action(blob != NULL, done, status = errAuthorizationInternal);
+        *blob = *(AuthorizationBlob*)data;
+        
+        *authorization = (AuthorizationRef)blob;
+    }
+    
+done:
+    xpc_release_safe(message);
+    xpc_release_safe(reply);
+    return status;
+}
+
+OSStatus AuthorizationFree(AuthorizationRef authorization, AuthorizationFlags flags)
+{
+    OSStatus status = errAuthorizationInternal;
+    xpc_object_t message = NULL;
+    xpc_object_t reply = NULL;
+    AuthorizationBlob *blob = NULL;
+
+    require_action(authorization != NULL, done, status = errAuthorizationInvalidRef);
+    blob = (AuthorizationBlob *)authorization;
+    
+    // Send
+    message = xpc_dictionary_create(NULL, NULL, 0);
+    require_action(message != NULL, done, status = errAuthorizationInternal);
+    
+    xpc_dictionary_set_uint64(message, AUTH_XPC_TYPE, AUTHORIZATION_FREE);
+    xpc_dictionary_set_data(message, AUTH_XPC_BLOB, blob, sizeof(AuthorizationBlob));
+    xpc_dictionary_set_uint64(message, AUTH_XPC_FLAGS, flags);
+
+    // Reply
+    reply = xpc_connection_send_message_with_reply_sync(get_authorization_connection(), message);
+    require_action(reply != NULL, done, status = errAuthorizationInternal);
+    require_action(xpc_get_type(reply) != XPC_TYPE_ERROR, done, status = errAuthorizationInternal);
+    
+    // Status
+    status = (OSStatus)xpc_dictionary_get_int64(reply, AUTH_XPC_STATUS);
+    
+    // Free
+    free(blob);
+    
+done:
+    xpc_release_safe(message);
+    xpc_release_safe(reply);
+    return status;
+}
+
+static OSStatus
+_AuthorizationCopyRights_send_message(xpc_object_t message, AuthorizationRights **authorizedRights)
+{
+    OSStatus status = errAuthorizationInternal;
+    xpc_object_t reply = NULL;
+
+    // Send
+    require_action(message != NULL, done, status = errAuthorizationInternal);
+
+    // Reply
+    reply = xpc_connection_send_message_with_reply_sync(get_authorization_connection(), message);
+    require_action(reply != NULL, done, status = errAuthorizationInternal);
+    require_action(xpc_get_type(reply) != XPC_TYPE_ERROR, done, status = errAuthorizationInternal);
+
+    // Status
+    status = (OSStatus)xpc_dictionary_get_int64(reply, AUTH_XPC_STATUS);
+
+    // Out
+    if (authorizedRights && status == errAuthorizationSuccess) {
+        xpc_object_t tmpItems = xpc_dictionary_get_value(reply, AUTH_XPC_OUT_ITEMS);
+        AuthorizationRights * grantedRights = DeserializeItemSet(tmpItems);
+        require_action(grantedRights != NULL, done, status = errAuthorizationInternal);
+
+        *authorizedRights = grantedRights;
+    }
+
+done:
+    xpc_release_safe(reply);
+    return status;
+}
+
+static OSStatus
+_AuthorizationCopyRights_prepare_message(AuthorizationRef authorization, const AuthorizationRights *rights, const AuthorizationEnvironment *environment, AuthorizationFlags flags, xpc_object_t *message_out)
+{
+    OSStatus status = errAuthorizationInternal;
+    AuthorizationBlob *blob = NULL;
+    xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
+    require_action(message != NULL, done, status = errAuthorizationInternal);
+
+    require_action(authorization != NULL, done, status = errAuthorizationInvalidRef);
+    blob = (AuthorizationBlob *)authorization;
+
+    xpc_dictionary_set_uint64(message, AUTH_XPC_TYPE, AUTHORIZATION_COPY_RIGHTS);
+    xpc_dictionary_set_data(message, AUTH_XPC_BLOB, blob, sizeof(AuthorizationBlob));
+    setItemSet(message, AUTH_XPC_RIGHTS, rights);
+    setItemSet(message, AUTH_XPC_ENVIROMENT, environment);
+    xpc_dictionary_set_uint64(message, AUTH_XPC_FLAGS, flags);
+
+    *message_out = message;
+    message = NULL;
+    status = errAuthorizationSuccess;
+
+done:
+    xpc_release_safe(message);
+    return status;
+}
+
+OSStatus AuthorizationCopyRights(AuthorizationRef authorization,
+                        const AuthorizationRights *rights,
+                        const AuthorizationEnvironment *environment,
+                        AuthorizationFlags flags,
+                        AuthorizationRights **authorizedRights)
+{
+    OSStatus status = errAuthorizationInternal;
+    xpc_object_t message = NULL;
+
+    require_noerr(status = _AuthorizationCopyRights_prepare_message(authorization, rights, environment, flags, &message), done);
+    require_noerr(status = _AuthorizationCopyRights_send_message(message, authorizedRights), done);
+
+done:
+    xpc_release_safe(message);
+    return status;
+}
+
+
+void AuthorizationCopyRightsAsync(AuthorizationRef authorization,
+                         const AuthorizationRights *rights,
+                         const AuthorizationEnvironment *environment,
+                         AuthorizationFlags flags,
+                         AuthorizationAsyncCallback callbackBlock)
+{
+    OSStatus prepare_status = errAuthorizationInternal;
+    __block xpc_object_t message = NULL;
+
+    prepare_status = _AuthorizationCopyRights_prepare_message(authorization, rights, environment, flags, &message);
+    if (prepare_status != errAuthorizationSuccess) {
+        callbackBlock(prepare_status, NULL);
+    }
+
+    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+               AuthorizationRights *blockAuthorizedRights = NULL;
+        OSStatus status = _AuthorizationCopyRights_send_message(message, &blockAuthorizedRights);
+        callbackBlock(status, blockAuthorizedRights);
+        xpc_release_safe(message);
+       });
+}
+
+OSStatus AuthorizationDismiss()
+{
+    OSStatus status = errAuthorizationInternal;
+    xpc_object_t message = NULL;
+    xpc_object_t reply = NULL;
+
+    // Send
+    message = xpc_dictionary_create(NULL, NULL, 0);
+    require(message != NULL, done);
+    
+    xpc_dictionary_set_uint64(message, AUTH_XPC_TYPE, AUTHORIZATION_DISMISS);
+    
+    // Reply
+    reply = xpc_connection_send_message_with_reply_sync(get_authorization_connection(), message);
+    require_action(reply != NULL, done, status = errAuthorizationInternal);
+    require_action(xpc_get_type(reply) != XPC_TYPE_ERROR, done, status = errAuthorizationInternal);
+    
+    // Status
+    status = (OSStatus)xpc_dictionary_get_int64(reply, AUTH_XPC_STATUS);
+    
+done:
+    xpc_release_safe(message);
+    xpc_release_safe(reply);
+    return status;
+}
+
+OSStatus AuthorizationCopyInfo(AuthorizationRef authorization,
+                      AuthorizationString tag,
+                      AuthorizationItemSet **info)
+{
+    OSStatus status = errAuthorizationInternal;
+    xpc_object_t message = NULL;
+    xpc_object_t reply = NULL;
+    AuthorizationBlob *blob = NULL;
+    
+    require_action(info != NULL, done, status = errAuthorizationInvalidSet);
+    require_action(authorization != NULL, done, status = errAuthorizationInvalidRef);
+    blob = (AuthorizationBlob *)authorization;
+    
+    // Send
+    message = xpc_dictionary_create(NULL, NULL, 0);
+    require_action(message != NULL, done, status = errAuthorizationInternal);
+    
+    xpc_dictionary_set_uint64(message, AUTH_XPC_TYPE, AUTHORIZATION_COPY_INFO);
+    xpc_dictionary_set_data(message, AUTH_XPC_BLOB, blob, sizeof(AuthorizationBlob));
+    if (tag) {
+        xpc_dictionary_set_string(message, AUTH_XPC_TAG, tag);
+    }
+    
+    // Reply
+    reply = xpc_connection_send_message_with_reply_sync(get_authorization_connection(), message);
+    require_action(reply != NULL, done, status = errAuthorizationInternal);
+    require_action(xpc_get_type(reply) != XPC_TYPE_ERROR, done, status = errAuthorizationInternal);
+    
+    // Status
+    status = (OSStatus)xpc_dictionary_get_int64(reply, AUTH_XPC_STATUS);
+
+    // Out
+    if (info && status == errAuthorizationSuccess) {
+        xpc_object_t tmpItems = xpc_dictionary_get_value(reply, AUTH_XPC_OUT_ITEMS);
+        AuthorizationRights * outInfo = DeserializeItemSet(tmpItems);
+        require_action(outInfo != NULL, done, status = errAuthorizationInternal);
+        
+        *info = outInfo;
+    }
+    
+done:
+    xpc_release_safe(message);
+    xpc_release_safe(reply);
+    return status;
+}
+
+OSStatus AuthorizationMakeExternalForm(AuthorizationRef authorization,
+                              AuthorizationExternalForm *extForm)
+{
+    OSStatus status = errAuthorizationInternal;
+    xpc_object_t message = NULL;
+    xpc_object_t reply = NULL;
+    AuthorizationBlob *blob = NULL;
+    
+    require_action(extForm != NULL, done, status = errAuthorizationInvalidPointer);
+    require_action(authorization != NULL, done, status = errAuthorizationInvalidRef);
+    blob = (AuthorizationBlob *)authorization;
+    
+    // Send
+    message = xpc_dictionary_create(NULL, NULL, 0);
+    require_action(message != NULL, done, status = errAuthorizationInternal);
+    
+    xpc_dictionary_set_uint64(message, AUTH_XPC_TYPE, AUTHORIZATION_MAKE_EXTERNAL_FORM);
+    xpc_dictionary_set_data(message, AUTH_XPC_BLOB, blob, sizeof(AuthorizationBlob));
+    
+    // Reply
+    reply = xpc_connection_send_message_with_reply_sync(get_authorization_connection(), message);
+    require_action(reply != NULL, done, status = errAuthorizationInternal);
+    require_action(xpc_get_type(reply) != XPC_TYPE_ERROR, done, status = errAuthorizationInternal);
+    
+    // Status
+    status = (OSStatus)xpc_dictionary_get_int64(reply, AUTH_XPC_STATUS);
+    
+    // out
+    if (status == errAuthorizationSuccess) {
+        size_t len;
+        const void * data = xpc_dictionary_get_data(reply, AUTH_XPC_EXTERNAL, &len);
+        require_action(data != NULL, done, status = errAuthorizationInternal);
+        assert(len == sizeof(AuthorizationExternalForm));
+        
+        *extForm = *(AuthorizationExternalForm*)data;
+    }
+    
+done:
+    xpc_release_safe(message);
+    xpc_release_safe(reply);
+    return status;
+}
+
+OSStatus AuthorizationCreateFromExternalForm(const AuthorizationExternalForm *extForm,
+                                    AuthorizationRef *authorization)
+{
+    OSStatus status = errAuthorizationInternal;
+    xpc_object_t message = NULL;
+    xpc_object_t reply = NULL;
+    
+    require_action(extForm != NULL, done, status = errAuthorizationInvalidPointer);
+    require_action(authorization != NULL, done, status = errAuthorizationInvalidRef);
+    
+    // Send
+    message = xpc_dictionary_create(NULL, NULL, 0);
+    require_action(message != NULL, done, status = errAuthorizationInternal);
+    
+    xpc_dictionary_set_uint64(message, AUTH_XPC_TYPE, AUTHORIZATION_CREATE_FROM_EXTERNAL_FORM);
+    xpc_dictionary_set_data(message, AUTH_XPC_EXTERNAL, extForm, sizeof(AuthorizationExternalForm));
+    
+    // Reply
+    reply = xpc_connection_send_message_with_reply_sync(get_authorization_connection(), message);
+    require_action(reply != NULL, done, status = errAuthorizationInternal);
+    require_action(xpc_get_type(reply) != XPC_TYPE_ERROR, done, status = errAuthorizationInternal);
+    
+    // Status
+    status = (OSStatus)xpc_dictionary_get_int64(reply, AUTH_XPC_STATUS);
+    
+    // Out
+    if (authorization && status == errAuthorizationSuccess) {
+        size_t len;
+        const void * data = xpc_dictionary_get_data(reply, AUTH_XPC_BLOB, &len);
+        require_action(data != NULL, done, status = errAuthorizationInternal);
+        assert(len == sizeof(AuthorizationBlob));
+        
+        AuthorizationBlob * blob = (AuthorizationBlob*)calloc(1u, sizeof(AuthorizationBlob));
+        require_action(blob != NULL, done, status = errAuthorizationInternal);
+        *blob = *(AuthorizationBlob*)data;
+        
+        *authorization = (AuthorizationRef)blob;
+    }
+    
+done:
+    xpc_release_safe(message);
+    xpc_release_safe(reply);
+    return status;
+}
+
+OSStatus AuthorizationFreeItemSet(AuthorizationItemSet *set)
+{
+    FreeItemSet(set);
+    return errAuthorizationSuccess;
+}
+
+OSStatus AuthorizationEnableSmartCard(AuthorizationRef authRef, Boolean enable)
+{
+    OSStatus status = errAuthorizationInternal;
+    xpc_object_t message = NULL;
+    xpc_object_t reply = NULL;
+    AuthorizationBlob *blob = NULL;
+
+    // Send
+    message = xpc_dictionary_create(NULL, NULL, 0);
+    require_action(message != NULL, done, status = errAuthorizationInternal);
+    require_action(authRef != NULL, done, status = errAuthorizationInvalidRef);
+    blob = (AuthorizationBlob *)authRef;
+    xpc_dictionary_set_uint64(message, AUTH_XPC_TYPE, AUTHORIZATION_ENABLE_SMARTCARD);
+    xpc_dictionary_set_data(message, AUTH_XPC_BLOB, blob, sizeof(AuthorizationBlob));
+    xpc_dictionary_set_bool(message, AUTH_XPC_DATA, enable);
+    
+    // Reply
+    reply = xpc_connection_send_message_with_reply_sync(get_authorization_connection(), message);
+    require_action(reply != NULL, done, status = errAuthorizationInternal);
+    require_action(xpc_get_type(reply) != XPC_TYPE_ERROR, done, status = errAuthorizationInternal);
+    
+    status = (OSStatus)xpc_dictionary_get_int64(reply, AUTH_XPC_STATUS);
+
+done:
+    xpc_release_safe(message);
+    xpc_release_safe(reply);
+    return status;
+}
+
+
+OSStatus AuthorizationRightGet(const char *rightName,
+                      CFDictionaryRef *rightDefinition)
+{
+    OSStatus status = errAuthorizationInternal;
+    xpc_object_t message = NULL;
+    xpc_object_t reply = NULL;
+    
+    require_action(rightName != NULL, done, status = errAuthorizationInvalidPointer);
+    
+    // Send
+    message = xpc_dictionary_create(NULL, NULL, 0);
+    require_action(message != NULL, done, status = errAuthorizationInternal);
+    
+    xpc_dictionary_set_uint64(message, AUTH_XPC_TYPE, AUTHORIZATION_RIGHT_GET);
+    xpc_dictionary_set_string(message, AUTH_XPC_RIGHT_NAME, rightName);
+    
+    // Reply
+    reply = xpc_connection_send_message_with_reply_sync(get_authorization_connection(), message);
+    require_action(reply != NULL, done, status = errAuthorizationInternal);
+    require_action(xpc_get_type(reply) != XPC_TYPE_ERROR, done, status = errAuthorizationInternal);
+    
+    // Status
+    status = (OSStatus)xpc_dictionary_get_int64(reply, AUTH_XPC_STATUS);
+    
+    // Out
+    if (rightDefinition && status == errAuthorizationSuccess) {
+        xpc_object_t value = xpc_dictionary_get_value(reply, AUTH_XPC_DATA);
+        require_action(value != NULL, done, status = errAuthorizationInternal);
+        require_action(xpc_get_type(value) == XPC_TYPE_DICTIONARY, done, status = errAuthorizationInternal);
+        
+        CFTypeRef cfdict = _CFXPCCreateCFObjectFromXPCObject(value);
+        require_action(cfdict != NULL, done, status = errAuthorizationInternal);
+        
+        *rightDefinition = cfdict;
+    }
+    
+done:
+    xpc_release_safe(message);
+    xpc_release_safe(reply);
+    return status;
+}
+
+OSStatus AuthorizationRightSet(AuthorizationRef authRef,
+                      const char *rightName,
+                      CFTypeRef rightDefinition,
+                      CFStringRef descriptionKey,
+                      CFBundleRef bundle,
+                      CFStringRef tableName)
+{
+    OSStatus status = errAuthorizationInternal;
+    xpc_object_t message = NULL;
+    xpc_object_t reply = NULL;
+    AuthorizationBlob *blob = NULL;
+    CFMutableDictionaryRef rightDict = NULL;
+    CFBundleRef clientBundle = bundle;
+    
+    if (bundle) {
+        CFRetain(bundle);
+    }
+    
+    require_action(rightDefinition != NULL, done, status = errAuthorizationInvalidPointer);
+    require_action(rightName != NULL, done, status = errAuthorizationInvalidPointer);
+    require_action(authRef != NULL, done, status = errAuthorizationInvalidRef);
+    blob = (AuthorizationBlob *)authRef;
+    
+    // Send
+    message = xpc_dictionary_create(NULL, NULL, 0);
+    require_action(message != NULL, done, status = errAuthorizationInternal);
+    
+    xpc_dictionary_set_uint64(message, AUTH_XPC_TYPE, AUTHORIZATION_RIGHT_SET);
+    xpc_dictionary_set_data(message, AUTH_XPC_BLOB, blob, sizeof(AuthorizationBlob));
+    xpc_dictionary_set_string(message, AUTH_XPC_RIGHT_NAME, rightName);
+    
+    // Create rightDict
+    if (CFGetTypeID(rightDefinition) == CFStringGetTypeID()) {
+        rightDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+        require_action(rightDict != NULL, done, status = errAuthorizationInternal);
+        
+        CFDictionarySetValue(rightDict, CFSTR(kAuthorizationRightRule), rightDefinition);
+    
+    } else if (CFGetTypeID(rightDefinition) == CFDictionaryGetTypeID()) {
+        rightDict = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, rightDefinition);
+        require_action(rightDict != NULL, done, status = errAuthorizationInternal);
+    
+    } else {
+        status = errAuthorizationInvalidPointer;
+        goto done;
+    }
+    
+    // Create locDict
+    if (descriptionKey) {
+        CFMutableDictionaryRef locDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+        require_action(locDict != NULL, done, status = errAuthorizationInternal);
+        
+        if (clientBundle == NULL) {
+            clientBundle = CFBundleGetMainBundle();
+            CFRetain(clientBundle);
+        }
+        
+        if (clientBundle) {
+            CFArrayRef bundleLocalizations = CFBundleCopyBundleLocalizations(clientBundle);
+            if (bundleLocalizations) {
+                // for every CFString in localizations do
+                CFIndex locIndex, allLocs = CFArrayGetCount(bundleLocalizations);
+                for (locIndex = 0; locIndex < allLocs; locIndex++)
+                {
+                    CFStringRef oneLocalization = (CFStringRef)CFArrayGetValueAtIndex(bundleLocalizations, locIndex);
+                    
+                    if (!oneLocalization)
+                        continue;
+                    
+                    // @@@ no way to get "Localized" and "strings" as constants?
+                    CFURLRef locURL = CFBundleCopyResourceURLForLocalization(clientBundle, tableName ? tableName :  CFSTR("Localizable"), CFSTR("strings"), NULL /*subDirName*/, oneLocalization);
+                    
+                    if (!locURL)
+                        continue;
+                    
+                    CFDataRef tableData = NULL;
+                    SInt32 errCode;
+                    CFStringRef errStr = NULL;
+                    CFPropertyListRef stringTable = NULL;
+                    
+                    CFURLCreateDataAndPropertiesFromResource(CFGetAllocator(clientBundle), locURL, &tableData, NULL, NULL, &errCode);
+                    CFReleaseSafe(locURL);
+                    if (errCode)
+                    {
+                        CFReleaseSafe(tableData);
+                        continue;
+                    }
+                    
+                    stringTable = CFPropertyListCreateFromXMLData(CFGetAllocator(clientBundle), tableData, kCFPropertyListImmutable, &errStr);
+                    CFReleaseSafe(errStr);
+                    CFReleaseSafe(tableData);
+                    
+                    CFStringRef value = (CFStringRef)CFDictionaryGetValue(stringTable, descriptionKey);
+                    if (value == NULL || CFEqual(value, CFSTR(""))) {
+                        CFReleaseSafe(stringTable);
+                        continue;
+                    } else {
+                        // oneLocalization/value into our dictionary 
+                        CFDictionarySetValue(locDict, oneLocalization, value);
+                        CFReleaseSafe(stringTable);
+                    }
+                }
+                CFReleaseSafe(bundleLocalizations);
+            }
+        }
+        
+        // add the description as the default localization into the dictionary
+               CFDictionarySetValue(locDict, CFSTR(""), descriptionKey);
+               
+               // stuff localization table into right definition
+               CFDictionarySetValue(rightDict, CFSTR(kAuthorizationRuleParameterDefaultPrompt), locDict);
+        CFReleaseSafe(locDict);
+    }
+    
+    xpc_object_t value = _CFXPCCreateXPCObjectFromCFObject(rightDict);
+    xpc_dictionary_set_value(message, AUTH_XPC_DATA, value);
+    xpc_release_safe(value);
+    
+    // Reply
+    reply = xpc_connection_send_message_with_reply_sync(get_authorization_connection(), message);
+    require_action(reply != NULL, done, status = errAuthorizationInternal);
+    require_action(xpc_get_type(reply) != XPC_TYPE_ERROR, done, status = errAuthorizationInternal);
+    
+    // Status
+    status = (OSStatus)xpc_dictionary_get_int64(reply, AUTH_XPC_STATUS);
+    
+done:
+    CFReleaseSafe(clientBundle);
+    CFReleaseSafe(rightDict);
+    xpc_release_safe(message);
+    xpc_release_safe(reply);
+    return status;
+}
+
+OSStatus AuthorizationRightRemove(AuthorizationRef authorization,
+                         const char *rightName)
+{
+    OSStatus status = errAuthorizationInternal;
+    xpc_object_t message = NULL;
+    xpc_object_t reply = NULL;
+    AuthorizationBlob *blob = NULL;
+    
+    require_action(rightName != NULL, done, status = errAuthorizationInvalidPointer);
+    require_action(authorization != NULL, done, status = errAuthorizationInvalidRef);
+    blob = (AuthorizationBlob *)authorization;
+    
+    // Send
+    message = xpc_dictionary_create(NULL, NULL, 0);
+    require_action(message != NULL, done, status = errAuthorizationInternal);
+    
+    xpc_dictionary_set_uint64(message, AUTH_XPC_TYPE, AUTHORIZATION_RIGHT_REMOVE);
+    xpc_dictionary_set_data(message, AUTH_XPC_BLOB, blob, sizeof(AuthorizationBlob));
+    xpc_dictionary_set_string(message, AUTH_XPC_RIGHT_NAME, rightName);
+    
+    // Reply
+    reply = xpc_connection_send_message_with_reply_sync(get_authorization_connection(), message);
+    require_action(reply != NULL, done, status = errAuthorizationInternal);
+    require_action(xpc_get_type(reply) != XPC_TYPE_ERROR, done, status = errAuthorizationInternal);
+    
+    // Status
+    status = (OSStatus)xpc_dictionary_get_int64(reply, AUTH_XPC_STATUS);
+    
+done:
+    xpc_release_safe(message);
+    xpc_release_safe(reply);
+    return status;
+}
index 549153136796e2cca8b104ad90e370796673ec8c..2e6af978eb251b3fa343c1363eb653890a643ef0 100644 (file)
 // This file is the unified implementation of the Authorization and AuthSession APIs.
 //
 #include <stdint.h>
 // This file is the unified implementation of the Authorization and AuthSession APIs.
 //
 #include <stdint.h>
-#include <Security/Authorization.h>
-#include <Security/AuthorizationPriv.h>
-#include <Security/AuthorizationDB.h>
-#include <Security/AuthorizationTagsPriv.h>
 #include <Security/AuthSession.h>
 #include <Security/AuthSession.h>
-#include <security_utilities/mach++.h>
-#include <security_utilities/globalizer.h>
-#include <security_utilities/alloc.h>
-#include <security_utilities/cfutilities.h>
-#include <security_cdsa_utilities/cssmbridge.h>
-#include <security_cdsa_utilities/AuthorizationWalkers.h>
+#include <Security/AuthorizationPriv.h>
 #include <security_utilities/ccaudit.h>
 #include <security_utilities/ccaudit.h>
-#include <securityd_client/ssclient.h>
-#include <CoreFoundation/CFPreferences.h>
-#include <Carbon/../Frameworks/HIToolbox.framework/Headers/TextInputSources.h>
-
+#include <security_cdsa_utilities/cssmbridge.h>
+#include <Security/SecBase.h>
 #include <security_utilities/logging.h>
 
 #include <security_utilities/logging.h>
 
-using namespace SecurityServer;
-using namespace MachPlusPlus;
-
-
-//
-// Shared cached client object
-//
-class AuthClient : public SecurityServer::ClientSession {
-public:
-       AuthClient()
-       : SecurityServer::ClientSession(Allocator::standard(), Allocator::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, errAuthorizationInvalidRef), 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, errAuthorizationInvalidRef),
-               rights, environment, flags, authorizedRights);
-       END_API(CSSM)
-}
-
-
-//
-// Augment and/or interrogate an authorization asynchronously
-//
-void AuthorizationCopyRightsAsync(AuthorizationRef authorization,
-       const AuthorizationRights *rights,
-       const AuthorizationEnvironment *environment,
-       AuthorizationFlags flags,
-       AuthorizationAsyncCallback callbackBlock)
-{
-       __block AuthorizationRights *blockAuthorizedRights = NULL;
-       
-       dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
-               OSStatus status = AuthorizationCopyRights(authorization, rights, environment, flags, &blockAuthorizedRights);
-               callbackBlock(status, blockAuthorizedRights);
-       });
-}
-
-
-//
-// 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, errAuthorizationInvalidRef),
-               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, errAuthorizationInvalidRef), *extForm);
-       END_API(CSSM)
-}
-
-OSStatus AuthorizationCreateFromExternalForm(const AuthorizationExternalForm *extForm,
-       AuthorizationRef *authorization)
-{
-       BEGIN_API
-       AuthorizationBlob result;
-       server().authInternalize(*extForm, result);
-       Required(authorization, errAuthorizationInvalidRef) =
-               (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)
-}
-
-
 //
 // This no longer talks to securityd; it is a kernel function.
 //
 //
 // This no longer talks to securityd; it is a kernel function.
 //
@@ -206,7 +51,7 @@ OSStatus SessionGetInfo(SecuritySessionId requestedSession,
        if (sessionId)
                *sessionId = session.sessionId();
        if (attributes)
        if (sessionId)
                *sessionId = session.sessionId();
        if (attributes)
-        *attributes = session.flags();
+        *attributes = (SessionAttributeBits)session.flags();
     END_API(CSSM)
 }
 
     END_API(CSSM)
 }
 
@@ -223,7 +68,7 @@ OSStatus SessionCreate(SessionCreationFlags flags,
 
        // we don't support the session creation flags anymore
        if (flags)
 
        // we don't support the session creation flags anymore
        if (flags)
-               Syslog::warning("SessionCreate flags=0x%x unsupported (ignored)", flags);
+               Syslog::warning("SessionCreate flags=0x%lx unsupported (ignored)", (unsigned long)flags);
        CommonCriteria::AuditInfo session;
        session.create(attributes);
         
        CommonCriteria::AuditInfo session;
        session.create(attributes);
         
@@ -260,232 +105,75 @@ OSStatus SessionGetDistinguishedUser(SecuritySessionId session, uid_t *user)
     END_API(CSSM)
 }
 
     END_API(CSSM)
 }
 
-OSStatus _SessionSetUserPreferences(SecuritySessionId session);
-
-void SessionUserPreferencesChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
-{
-       _SessionSetUserPreferences(uintptr_t(observer));
-}
-
-OSStatus _SessionSetUserPreferences(SecuritySessionId session)
-{
-    BEGIN_API
-       CFStringRef appleLanguagesStr = CFSTR("AppleLanguages");
-       CFStringRef controlTintStr = CFSTR("AppleAquaColorVariant");
-       CFStringRef keyboardUIModeStr = CFSTR("AppleKeyboardUIMode");
-       CFStringRef textDirectionStr = CFSTR("AppleTextDirection");
-       CFStringRef hitoolboxAppIDStr = CFSTR("com.apple.HIToolbox");
-       CFNotificationCenterRef center = CFNotificationCenterGetDistributedCenter();
-
-       CFRef<CFMutableDictionaryRef> userPrefsDict(CFDictionaryCreateMutable(NULL, 10, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
-       CFRef<CFMutableDictionaryRef> globalPrefsDict(CFDictionaryCreateMutable(NULL, 10, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
-       
-       if (!userPrefsDict || !globalPrefsDict)
-               return errSessionValueNotSet;
-       
-       CFRef<CFArrayRef> appleLanguagesArray(static_cast<CFArrayRef>(CFPreferencesCopyAppValue(appleLanguagesStr, kCFPreferencesCurrentApplication)));
-       if (appleLanguagesArray)
-               CFDictionarySetValue(globalPrefsDict, appleLanguagesStr, appleLanguagesArray);
-       
-       CFRef<CFNumberRef> controlTintNumber(static_cast<CFNumberRef>(CFPreferencesCopyAppValue(controlTintStr, kCFPreferencesCurrentApplication)));
-       if (controlTintNumber)
-               CFDictionarySetValue(globalPrefsDict, controlTintStr, controlTintNumber);
-
-       CFRef<CFNumberRef> keyboardUIModeNumber(static_cast<CFNumberRef>(CFPreferencesCopyAppValue(keyboardUIModeStr, kCFPreferencesCurrentApplication)));
-       if (keyboardUIModeNumber)
-               CFDictionarySetValue(globalPrefsDict, keyboardUIModeStr, keyboardUIModeNumber);
-
-       CFRef<CFNumberRef> textDirectionNumber(static_cast<CFNumberRef>(CFPreferencesCopyAppValue(textDirectionStr, kCFPreferencesCurrentApplication)));
-       if (textDirectionNumber)
-               CFDictionarySetValue(globalPrefsDict, textDirectionStr, textDirectionNumber);
-       
-       if (CFDictionaryGetCount(globalPrefsDict) > 0)
-               CFDictionarySetValue(userPrefsDict, kCFPreferencesAnyApplication, globalPrefsDict);
-
-       CFPreferencesSynchronize(hitoolboxAppIDStr, kCFPreferencesCurrentUser, 
-                       kCFPreferencesCurrentHost);
-       CFRef<CFDictionaryRef> hitoolboxPrefsDict(static_cast<CFDictionaryRef>(CFPreferencesCopyMultiple(NULL, hitoolboxAppIDStr, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost)));
-       if (hitoolboxPrefsDict) {
-               CFDictionarySetValue(userPrefsDict, hitoolboxAppIDStr, hitoolboxPrefsDict);
-               CFNotificationCenterPostNotification(center, CFSTR("com.apple.securityagent.InputPrefsChanged"), CFSTR("com.apple.loginwindow"), hitoolboxPrefsDict, true);
-       }
-       
-       CFRef<CFDataRef> userPrefsData(CFPropertyListCreateXMLData(NULL, userPrefsDict));
-       if (!userPrefsData)
-               return errSessionValueNotSet;
-       server().setSessionUserPrefs(session, CFDataGetLength(userPrefsData), CFDataGetBytePtr(userPrefsData));
-
-    END_API(CSSM)
-}
+//OSStatus _SessionSetUserPreferences(SecuritySessionId session);
+//
+//static
+//void SessionUserPreferencesChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
+//{
+//#warning "The cast will loose some information"
+//     _SessionSetUserPreferences((SecuritySessionId)uintptr_t(observer));
+//}
+//
+//OSStatus _SessionSetUserPreferences(SecuritySessionId session)
+//{
+//    BEGIN_API
+//     CFStringRef appleLanguagesStr = CFSTR("AppleLanguages");
+//     CFStringRef controlTintStr = CFSTR("AppleAquaColorVariant");
+//     CFStringRef keyboardUIModeStr = CFSTR("AppleKeyboardUIMode");
+//     CFStringRef textDirectionStr = CFSTR("AppleTextDirection");
+//     CFStringRef hitoolboxAppIDStr = CFSTR("com.apple.HIToolbox");
+//     CFNotificationCenterRef center = CFNotificationCenterGetDistributedCenter();
+//
+//     CFRef<CFMutableDictionaryRef> userPrefsDict(CFDictionaryCreateMutable(NULL, 10, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+//     CFRef<CFMutableDictionaryRef> globalPrefsDict(CFDictionaryCreateMutable(NULL, 10, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+//     
+//     if (!userPrefsDict || !globalPrefsDict)
+//             return errSessionValueNotSet;
+//     
+//     CFRef<CFArrayRef> appleLanguagesArray(static_cast<CFArrayRef>(CFPreferencesCopyAppValue(appleLanguagesStr, kCFPreferencesCurrentApplication)));
+//     if (appleLanguagesArray)
+//             CFDictionarySetValue(globalPrefsDict, appleLanguagesStr, appleLanguagesArray);
+//     
+//     CFRef<CFNumberRef> controlTintNumber(static_cast<CFNumberRef>(CFPreferencesCopyAppValue(controlTintStr, kCFPreferencesCurrentApplication)));
+//     if (controlTintNumber)
+//             CFDictionarySetValue(globalPrefsDict, controlTintStr, controlTintNumber);
+//
+//     CFRef<CFNumberRef> keyboardUIModeNumber(static_cast<CFNumberRef>(CFPreferencesCopyAppValue(keyboardUIModeStr, kCFPreferencesCurrentApplication)));
+//     if (keyboardUIModeNumber)
+//             CFDictionarySetValue(globalPrefsDict, keyboardUIModeStr, keyboardUIModeNumber);
+//
+//     CFRef<CFNumberRef> textDirectionNumber(static_cast<CFNumberRef>(CFPreferencesCopyAppValue(textDirectionStr, kCFPreferencesCurrentApplication)));
+//     if (textDirectionNumber)
+//             CFDictionarySetValue(globalPrefsDict, textDirectionStr, textDirectionNumber);
+//     
+//     if (CFDictionaryGetCount(globalPrefsDict) > 0)
+//             CFDictionarySetValue(userPrefsDict, kCFPreferencesAnyApplication, globalPrefsDict);
+//
+//     CFPreferencesSynchronize(hitoolboxAppIDStr, kCFPreferencesCurrentUser, 
+//                     kCFPreferencesCurrentHost);
+//     CFRef<CFDictionaryRef> hitoolboxPrefsDict(static_cast<CFDictionaryRef>(CFPreferencesCopyMultiple(NULL, hitoolboxAppIDStr, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost)));
+//     if (hitoolboxPrefsDict) {
+//             CFDictionarySetValue(userPrefsDict, hitoolboxAppIDStr, hitoolboxPrefsDict);
+//             CFNotificationCenterPostNotification(center, CFSTR("com.apple.securityagent.InputPrefsChanged"), CFSTR("com.apple.loginwindow"), hitoolboxPrefsDict, true);
+//     }
+//     
+//     CFRef<CFDataRef> userPrefsData(CFPropertyListCreateXMLData(NULL, userPrefsDict));
+//     if (!userPrefsData)
+//             return errSessionValueNotSet;
+//     server().setSessionUserPrefs(session, (uint32_t)CFDataGetLength(userPrefsData), CFDataGetBytePtr(userPrefsData));
+//
+//    END_API(CSSM)
+//}
 
 OSStatus SessionSetUserPreferences(SecuritySessionId session)
 {
 
 OSStatus SessionSetUserPreferences(SecuritySessionId session)
 {
-       OSStatus status = _SessionSetUserPreferences(session);
-       if (noErr == status) {
-               CFNotificationCenterRef center = CFNotificationCenterGetDistributedCenter();
-               // We've succeeded in setting up a static set of prefs, now set up 
-               CFNotificationCenterAddObserver(center, (void*)session, SessionUserPreferencesChanged, CFSTR("com.apple.Carbon.TISNotifySelectedKeyboardInputSourceChanged"), NULL, CFNotificationSuspensionBehaviorDeliverImmediately);
-               CFNotificationCenterAddObserver(center, (void*)session, SessionUserPreferencesChanged, CFSTR("com.apple.Carbon.TISNotifyEnabledKeyboardInputSourcesChanged"), NULL, CFNotificationSuspensionBehaviorDeliverImmediately);
-       }
-       return status;
-}
-
-
-//
-// Modify Authorization rules
-//
-
-// 
-// AuthorizationRightGet 
-// 
-OSStatus AuthorizationRightGet(const char *rightName, CFDictionaryRef *rightDefinition)
-{
-       BEGIN_API;
-       Required(rightName);
-       CssmDataContainer definition(server().returnAllocator);
-
-       server().authorizationdbGet(rightName, definition, server().returnAllocator);
-       // convert rightDefinition to dictionary
-       
-       if (rightDefinition)
-       {
-               CFRef<CFDataRef> data(CFDataCreate(NULL, static_cast<UInt8 *>(definition.data()), definition.length()));
-               if (!data)
-                       CssmError::throwMe(errAuthorizationInternal);
-                       
-               CFRef<CFDictionaryRef> rightDict(static_cast<CFDictionaryRef>(CFPropertyListCreateFromXMLData(NULL, data, kCFPropertyListImmutable, NULL)));
-               if (!rightDict 
-                       || CFGetTypeID(rightDict) != CFDictionaryGetTypeID()) 
-                               CssmError::throwMe(errAuthorizationInternal);
-
-               CFRetain(rightDict);
-               *rightDefinition = rightDict;
-       }
-
-       END_API(CSSM);
-}
-
-//
-// AuthorizationRightSet
-//
-OSStatus AuthorizationRightSet(AuthorizationRef authRef, 
-       const char *rightName, CFTypeRef rightDefinition, 
-       CFStringRef descriptionKey, CFBundleRef bundle, CFStringRef tableName)
-{
-       BEGIN_API;
-       Required(rightName);
-       AuthorizationBlob *auth = (AuthorizationBlob *)authRef;
-
-       CFRef<CFMutableDictionaryRef> rightDefinitionDict;
-       if (rightDefinition && (CFGetTypeID(rightDefinition) == CFStringGetTypeID()))
-       {
-               rightDefinitionDict = CFDictionaryCreateMutable(NULL, 10, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-               if (!rightDefinitionDict)
-                               CssmError::throwMe(errAuthorizationInternal);
-               CFDictionarySetValue(rightDefinitionDict, CFSTR(kAuthorizationRightRule), rightDefinition);
-       }
-       else
-               if (rightDefinition && (CFGetTypeID(rightDefinition) == CFDictionaryGetTypeID()))
-               {
-                       rightDefinitionDict = CFDictionaryCreateMutableCopy(NULL, 0, static_cast<CFDictionaryRef>(rightDefinition));
-                       if (!rightDefinitionDict)
-                               CssmError::throwMe(errAuthorizationInternal);
-               }
-               else
-                       CssmError::throwMe(errAuthorizationDenied);
-
-       if (rightDefinitionDict)
-               CFRelease(rightDefinitionDict); // we just assigned things that were already retained
-       
-       if (descriptionKey)
-       {
-               CFRef<CFMutableDictionaryRef> localizedDescriptions(CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
-               
-               if (!localizedDescriptions)
-                       CssmError::throwMe(errAuthorizationInternal);
-       
-               // assigning to perform a retain on either
-               CFRef<CFBundleRef> clientBundle; clientBundle = bundle ? bundle : CFBundleGetMainBundle(); 
-               
-               // looks like a list of CFStrings: English us_en etc.
-               CFRef<CFArrayRef> localizations(CFBundleCopyBundleLocalizations(clientBundle));
-       
-               if (localizations)
-               {
-                       // for every CFString in localizations do
-                       CFIndex locIndex, allLocs = CFArrayGetCount(localizations);
-                       for (locIndex = 0; locIndex < allLocs; locIndex++)
-                       {
-                               CFStringRef oneLocalization = static_cast<CFStringRef>(CFArrayGetValueAtIndex(localizations, locIndex));
-                               
-                               if (!oneLocalization)
-                                       continue;
-               
-                               // @@@ no way to get "Localized" and "strings" as constants?
-                               CFRef<CFURLRef> locURL(CFBundleCopyResourceURLForLocalization(clientBundle, tableName ? tableName :  CFSTR("Localizable"), CFSTR("strings"), NULL /*subDirName*/, oneLocalization));
-                               
-                               if (!locURL)
-                                       continue;
-                               
-                               CFDataRef tableData = NULL;
-                               SInt32 errCode;
-                               CFStringRef errStr;
-                               CFPropertyListRef stringTable;
-               
-                               CFURLCreateDataAndPropertiesFromResource(CFGetAllocator(clientBundle), locURL, &tableData, NULL, NULL, &errCode);
-                               
-                               if (errCode)
-                               {
-                                       if (NULL != tableData) {
-                                               CFRelease(tableData);
-                                       }
-                                       continue;
-                               }
-               
-                               stringTable = CFPropertyListCreateFromXMLData(CFGetAllocator(clientBundle), tableData, kCFPropertyListImmutable, &errStr);
-                               if (errStr != NULL) {
-                                       CFRelease(errStr);
-                                       errStr = NULL;
-                               }
-                               CFRelease(tableData);
-                               
-                               CFStringRef value = static_cast<CFStringRef>(CFDictionaryGetValue(static_cast<CFDictionaryRef>(stringTable), descriptionKey));
-                               if (value == NULL || CFEqual(value, CFSTR(""))) {
-                                       CFRelease(stringTable);
-                                       continue;
-                               } else {
-                                       // oneLocalization/value into our dictionary 
-                                       CFDictionarySetValue(localizedDescriptions, oneLocalization, value);
-                                       CFRelease(stringTable);
-                               }
-                       }
-               }
-
-               // add the description as the default localization into the dictionary
-               CFDictionarySetValue(localizedDescriptions, CFSTR(""), descriptionKey);
-               
-               // stuff localization table into rule definition
-               CFDictionarySetValue(rightDefinitionDict, CFSTR(kAuthorizationRuleParameterDefaultPrompt), localizedDescriptions);
-
-       }
-       
-       // serialize cfdictionary with data into rightDefinitionXML
-       CFRef<CFDataRef> rightDefinitionXML(CFPropertyListCreateXMLData(NULL, rightDefinitionDict));
-
-       server().authorizationdbSet(Required(auth), rightName, CFDataGetLength(rightDefinitionXML), CFDataGetBytePtr(rightDefinitionXML));
-               
-    END_API(CSSM);
-}
-
-//
-// AuthorizationRightRemove
-//
-OSStatus AuthorizationRightRemove(AuthorizationRef authRef, const char *rightName)
-{
-       BEGIN_API;
-       Required(rightName);
-       AuthorizationBlob *auth = (AuthorizationBlob *)authRef;
-       server().authorizationdbRemove(Required(auth), rightName);
-       END_API(CSSM);
+//     OSStatus status = _SessionSetUserPreferences(session);
+//     if (errSecSuccess == status) {
+//             CFNotificationCenterRef center = CFNotificationCenterGetDistributedCenter();
+//             // We've succeeded in setting up a static set of prefs, now set up 
+//             CFNotificationCenterAddObserver(center, (void*)session, SessionUserPreferencesChanged, CFSTR("com.apple.Carbon.TISNotifySelectedKeyboardInputSourceChanged"), NULL, CFNotificationSuspensionBehaviorDeliverImmediately);
+//             CFNotificationCenterAddObserver(center, (void*)session, SessionUserPreferencesChanged, CFSTR("com.apple.Carbon.TISNotifyEnabledKeyboardInputSourcesChanged"), NULL, CFNotificationSuspensionBehaviorDeliverImmediately);
+//     }
+//     return status;
+    return errSecSuccess;
 }
 }
-
index 46ed15e2231071eb2ec7883e2fc67283e378cf79..746a8c008a748f7177831a388c0e5dc1aa23a777 100644 (file)
@@ -182,7 +182,7 @@ enum {
     interface.
 */
 enum {
     interface.
 */
 enum {
-    kAuthorizationCallbacksVersion = 0
+    kAuthorizationCallbacksVersion = 1
 };
 
 
 };
 
 
@@ -247,6 +247,11 @@ typedef struct AuthorizationCallbacks {
     OSStatus (*GetSessionId)(AuthorizationEngineRef inEngine,
         AuthorizationSessionId *outSessionId);
 
     OSStatus (*GetSessionId)(AuthorizationEngineRef inEngine,
         AuthorizationSessionId *outSessionId);
 
+    /* Read value from hints. AuthorizationValue does not own data. */
+    OSStatus (*GetImmutableHintValue)(AuthorizationEngineRef inEngine,
+        AuthorizationString inKey,
+        const AuthorizationValue **outValue);
+
 } AuthorizationCallbacks;
 
 
 } AuthorizationCallbacks;
 
 
index 596df4a5fde76d7d312cbf44c7fa30708741c347..82a98aee0cf531b4f07141531e08af4337a4f284 100644 (file)
@@ -34,6 +34,7 @@
 #include <Security/Authorization.h>
 #include <Security/AuthSession.h>
 #include <sys/types.h> // uid_t
 #include <Security/Authorization.h>
 #include <Security/AuthSession.h>
 #include <sys/types.h> // uid_t
+#include <mach/message.h>
 
 #if defined(__cplusplus)
 extern "C" {
 
 #if defined(__cplusplus)
 extern "C" {
@@ -55,6 +56,61 @@ enum {
        kAuthorizationFlagLeastPrivileged               = (1 << 5)
 };
 
        kAuthorizationFlagLeastPrivileged               = (1 << 5)
 };
 
+/*!
+    @function AuthorizationCreateWithAuditToken
+    @abstract Create a AuthorizationRef for the process that sent the mach message
+        represented by the audit token. Requires root.
+    @param token The audit token of a mach message
+    @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) 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.
+    @result errAuthorizationSuccess 0 authorization or all requested rights succeeded.
+    errAuthorizationDenied -60005 The authorization for one or more of the requested rights was denied.
+*/
+
+OSStatus AuthorizationCreateWithAuditToken(audit_token_t token,
+    const AuthorizationEnvironment *environment,
+    AuthorizationFlags flags,
+    AuthorizationRef *authorization);
+
+/*!
+    @function AuthorizationExecuteWithPrivilegesExternalForm
+    Run an executable tool with enhanced privileges after passing
+    suitable authorization procedures.
+
+    @param authorization in external form 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.
+
+    @discussion This function has been deprecated and should no longer be used.
+    Use a launchd-launched helper tool and/or the Service Mangement framework
+    for this functionality.
+*/
+    
+OSStatus AuthorizationExecuteWithPrivilegesExternalForm(const AuthorizationExternalForm * extForm,
+    const char *pathToTool,
+    AuthorizationFlags flags,
+    char *const *arguments,
+    FILE **communicationsPipe) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_7,__IPHONE_NA,__IPHONE_NA);
+
+/*
+    @function AuthorizationDismiss
+    @abstract Dismisses all Authorization dialogs associated to the calling process.
+        Any active authorization requests will be canceled and return errAuthorizationDenied
+*/
+
+OSStatus AuthorizationDismiss(void);
+    
 /*!
        @function SessionSetDistinguishedUser
        This function allows the creator of a (new) security session to associate an arbitrary
 /*!
        @function SessionSetDistinguishedUser
        This function allows the creator of a (new) security session to associate an arbitrary
@@ -93,6 +149,15 @@ OSStatus SessionGetDistinguishedUser(SecuritySessionId session, uid_t *user);
  */
 OSStatus SessionSetUserPreferences(SecuritySessionId session);
 
  */
 OSStatus SessionSetUserPreferences(SecuritySessionId session);
 
+    
+/*!
+    @function AuthorizationEnableSmartCard
+    Enable or disable system login using smartcard or get current status.
+    @param authorization (input) The authorization object on which this operation is performed.
+    @param enable (input) desired smartcard login support state, TRUE to enable, FALSE to disable
+ */
+OSStatus AuthorizationEnableSmartCard(AuthorizationRef authRef, Boolean enable);
 
 #if defined(__cplusplus)
 }
 
 #if defined(__cplusplus)
 }
index 9fb80b4242886c9b32c179b762a6b0bba807b1a1..c3d52ba7f1761db6b1e67375dbd1cd10d71bc8c2 100644 (file)
  */
 #define kAuthorizationRuleParameterExtractPassword             "extract-password"
 
  */
 #define kAuthorizationRuleParameterExtractPassword             "extract-password"
 
+/*! @defined kAuthorizationRuleParameterEntitled
+ boolean that indicates whether to grant a right based on the entitlement
+ */
+#define kAuthorizationRuleParameterEntitled             "entitled"
+
+/*! @defined kAuthorizationRuleParameterEntitledAndGroup
+ boolean that indicates whether to grant a right base on the entitlement 
+ and if the user is a member of kAuthorizationRuleParameterGroup
+ */
+#define kAuthorizationRuleParameterEntitledAndGroup            "entitled-group"
+
+/*! @defined kAuthorizationRuleParameterVPNEntitledAndGroup
+ boolean that indicates whether to grant a right base on the VPN entitlement
+ and if the user is a member of kAuthorizationRuleParameterGroup
+ */
+#define kAuthorizationRuleParameterVPNEntitledAndGroup         "vpn-entitled-group"
+
+/*! @defined kAuthorizationRuleParameterRequireAppleSigned
+ boolean require the caller to be signed by apple
+ */
+#define kAuthorizationRuleParameterRequireAppleSigned          "require-apple-signed"
+
 /*
  * Hints for internal Authorization use
  */
 /*
  * Hints for internal Authorization use
  */
 #define AGENT_HINT_RETRY_REASON "reason"
 #define AGENT_HINT_AUTHORIZE_RULE "authorize-rule"
 #define AGENT_HINT_TOKEN_NAME "token-name"
 #define AGENT_HINT_RETRY_REASON "reason"
 #define AGENT_HINT_AUTHORIZE_RULE "authorize-rule"
 #define AGENT_HINT_TOKEN_NAME "token-name"
+#define AGENT_HINT_PROCESS_SIGNED "process-apple-signed"
+#define AGENT_HINT_SHOW_RESET "show-reset"
 
 /* passed by loginwindow to securityd and agent */
 #define AGENT_HINT_IMMEDIATE_LAUNCH "immediate-agent"
 
 /* passed by loginwindow to securityd and agent */
 #define AGENT_HINT_IMMEDIATE_LAUNCH "immediate-agent"
 #define AGENT_CONTEXT_AUTO_LOGIN "auto-login"
 #define AGENT_CONTEXT_USER_CONSENT "user-consent"
 
 #define AGENT_CONTEXT_AUTO_LOGIN "auto-login"
 #define AGENT_CONTEXT_USER_CONSENT "user-consent"
 
+// Allow the user to choose to display their password
+#define AGENT_HINT_ALLOW_SHOW_PASSWORD "show-add-password"
+
 #define AGENT_HINT_SHOW_ADD_TO_KEYCHAIN "show-add-to-keychain"
 #define AGENT_HINT_SHOW_ADD_TO_KEYCHAIN "show-add-to-keychain"
+#define AGENT_CONTEXT_RESET_PASSWORD "reset-password"
+
 /* can be in hints or context */
 #define AGENT_ADD_TO_KEYCHAIN "add-to-keychain"
 
 /* can be in hints or context */
 #define AGENT_ADD_TO_KEYCHAIN "add-to-keychain"
 
index e25befd9c414f6b01c9b86596e983d76cac3c35e..cfc71a79ecde1c19e10624bee59c23e50a036caf 100644 (file)
@@ -33,6 +33,8 @@
 #include <stdlib.h>
 #include <sys/socket.h>
 #include <Security/Authorization.h>
 #include <stdlib.h>
 #include <sys/socket.h>
 #include <Security/Authorization.h>
+#include <Security/AuthorizationPriv.h>
+#include <Security/SecBase.h>
 #include <security_utilities/endian.h>
 #include <security_utilities/debugging.h>
 
 #include <security_utilities/endian.h>
 #include <security_utilities/debugging.h>
 
@@ -61,15 +63,32 @@ static const char **argVector(const char *trampoline,
        char *const *arguments);
 
 
        char *const *arguments);
 
 
+OSStatus AuthorizationExecuteWithPrivileges(AuthorizationRef authorization,
+                                            const char *pathToTool,
+                                            AuthorizationFlags flags,
+                                            char *const *arguments,
+                                            FILE **communicationsPipe)
+{
+       // externalize the authorization
+       AuthorizationExternalForm extForm;
+       if (OSStatus err = AuthorizationMakeExternalForm(authorization, &extForm))
+               return err;
+    
+    return AuthorizationExecuteWithPrivilegesExternalForm(&extForm, pathToTool, flags, arguments, communicationsPipe);
+}
+
 //
 // The public client API function.
 //
 //
 // The public client API function.
 //
-OSStatus AuthorizationExecuteWithPrivileges(AuthorizationRef authorization,
+OSStatus AuthorizationExecuteWithPrivilegesExternalForm(const AuthorizationExternalForm * extForm,
        const char *pathToTool,
        AuthorizationFlags flags,
        char *const *arguments,
        FILE **communicationsPipe)
 {
        const char *pathToTool,
        AuthorizationFlags flags,
        char *const *arguments,
        FILE **communicationsPipe)
 {
+       if (extForm == NULL)
+        return errAuthorizationInvalidPointer;
+    
        // report the caller to the authorities
        aslmsg m = asl_new(ASL_TYPE_MSG);
        asl_set(m, "com.apple.message.domain", "com.apple.libsecurity_authorization.AuthorizationExecuteWithPrivileges");
        // report the caller to the authorities
        aslmsg m = asl_new(ASL_TYPE_MSG);
        asl_set(m, "com.apple.message.domain", "com.apple.libsecurity_authorization.AuthorizationExecuteWithPrivileges");
@@ -81,25 +100,33 @@ OSStatus AuthorizationExecuteWithPrivileges(AuthorizationRef authorization,
        if (flags != 0)
                return errAuthorizationInvalidFlags;
 
        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;
     // create the mailbox file
     FILE *mbox = tmpfile();
     if (!mbox)
         return errAuthorizationInternal;
-    if (fwrite(&extForm, sizeof(extForm), 1, mbox) != 1) {
+    if (fwrite(extForm, sizeof(*extForm), 1, mbox) != 1) {
         fclose(mbox);
         return errAuthorizationInternal;
     }
     fflush(mbox);
     
         fclose(mbox);
         return errAuthorizationInternal;
     }
     fflush(mbox);
     
+       // compute the argument vector here because we can't allocate memory once we fork.
+
     // make text representation of the temp-file descriptor
     char mboxFdText[20];
     snprintf(mboxFdText, sizeof(mboxFdText), "auth %d", fileno(mbox));
     // make text representation of the temp-file descriptor
     char mboxFdText[20];
     snprintf(mboxFdText, sizeof(mboxFdText), "auth %d", fileno(mbox));
-    
+
+       // where is the trampoline?
+#if defined(NDEBUG)
+       const char *trampoline = TRAMPOLINE;
+#else //!NDEBUG
+       const char *trampoline = getenv("AUTHORIZATIONTRAMPOLINE");
+       if (!trampoline)
+               trampoline = TRAMPOLINE;
+#endif //NDEBUG
+
+       const char **argv = argVector(trampoline, pathToTool, mboxFdText, arguments);
+       
        // make a notifier pipe
        int notify[2];
        if (pipe(notify)) {
        // make a notifier pipe
        int notify[2];
        if (pipe(notify)) {
@@ -115,6 +142,8 @@ OSStatus AuthorizationExecuteWithPrivileges(AuthorizationRef authorization,
                return errAuthorizationToolExecuteFailure;
        }
 
                return errAuthorizationToolExecuteFailure;
        }
 
+       OSStatus status = errSecSuccess;
+
        // do the standard forking tango...
        int delay = 1;
        for (int n = 5;; n--, delay *= 2) {
        // do the standard forking tango...
        int delay = 1;
        for (int n = 5;; n--, delay *= 2) {
@@ -142,7 +171,6 @@ OSStatus AuthorizationExecuteWithPrivileges(AuthorizationRef authorization,
             fclose(mbox);
                        
                        // get status notification from child
             fclose(mbox);
                        
                        // get status notification from child
-                       OSStatus status;
                        secdebug("authexec", "parent waiting for status");
                        ssize_t rc = read(notify[READ], &status, sizeof(status));
                        status = n2h(status);
                        secdebug("authexec", "parent waiting for status");
                        ssize_t rc = read(notify[READ], &status, sizeof(status));
                        status = n2h(status);
@@ -155,16 +183,18 @@ OSStatus AuthorizationExecuteWithPrivileges(AuthorizationRef authorization,
                                secdebug("authexec", "parent received status=%d", (int)status);
                                close(notify[READ]);
                                if (communicationsPipe) { close(comm[READ]); close(comm[WRITE]); }
                                secdebug("authexec", "parent received status=%d", (int)status);
                                close(notify[READ]);
                                if (communicationsPipe) { close(comm[READ]); close(comm[WRITE]); }
-                               return status;
+                               goto exit_point;
                        case 0:                                 // end of file: exec succeeded
                                close(notify[READ]);
                                if (communicationsPipe)
                                        *communicationsPipe = fdopen(comm[READ], "r+");
                                secdebug("authexec", "parent resumes (no error)");
                        case 0:                                 // end of file: exec succeeded
                                close(notify[READ]);
                                if (communicationsPipe)
                                        *communicationsPipe = fdopen(comm[READ], "r+");
                                secdebug("authexec", "parent resumes (no error)");
-                               return noErr;
+                               status = errSecSuccess;
+                               goto exit_point;
                        }
         }
                        }
         }
-
+               break;
+               
                case 0:         // child
                        // close foreign side of pipes
                        close(notify[READ]);
                case 0:         // child
                        // close foreign side of pipes
                        close(notify[READ]);
@@ -184,21 +214,9 @@ OSStatus AuthorizationExecuteWithPrivileges(AuthorizationRef authorization,
                                open("/dev/null", O_RDWR);
                        }
                        
                                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
                        // okay, execute the trampoline
-                       secdebug("authexec", "child exec(%s:%s)",
-                               trampoline, pathToTool);
-                       if (const char **argv = argVector(trampoline, pathToTool, mboxFdText, arguments))
+                       if (argv)
                                execv(trampoline, (char *const*)argv);
                                execv(trampoline, (char *const*)argv);
-                       secdebug("authexec", "trampoline exec failed (errno=%d)", errno);
 
                        // execute failed - tell the parent
                        {
 
                        // execute failed - tell the parent
                        {
@@ -209,6 +227,10 @@ OSStatus AuthorizationExecuteWithPrivileges(AuthorizationRef authorization,
                        }
                }
        }
                        }
                }
        }
+
+exit_point:
+       free(argv);
+       return status;
 }
 
 
 }
 
 
index 343dab1ecb312a85582d062862e204452e6ff431..d886ba51fd4d217d325285739563c7dad2059a3a 100644 (file)
@@ -28,7 +28,7 @@
 #include <cstdlib>
 #include <unistd.h>
 #include <Security/Authorization.h>
 #include <cstdlib>
 #include <unistd.h>
 #include <Security/Authorization.h>
-
+#include <Security/SecBase.h>
 
 //
 // In a tool launched via AuthorizationCopyPrivilegedReference, retrieve a copy
 
 //
 // In a tool launched via AuthorizationCopyPrivilegedReference, retrieve a copy
@@ -64,5 +64,5 @@ OSStatus AuthorizationCopyPrivilegedReference(AuthorizationRef *authorization,
 
        // well, here you go
        *authorization = auth;
 
        // well, here you go
        *authorization = auth;
-       return noErr;
+       return errSecSuccess;
 }
 }
index ed32c93d4aa72123c19f3c13b05d3189f463fa92..637ac80273ef99680897ee1927d6515e9d4cb124 100644 (file)
@@ -7,6 +7,8 @@
        objects = {
 
 /* Begin PBXBuildFile section */
        objects = {
 
 /* Begin PBXBuildFile section */
+               18F2360515CB387000060520 /* Authorization.c in Sources */ = {isa = PBXBuildFile; fileRef = 18F2360415CB387000060520 /* Authorization.c */; };
+               18F2360915CB3C7700060520 /* authutilities.c in Sources */ = {isa = PBXBuildFile; fileRef = 18F2360815CB3C7700060520 /* authutilities.c */; };
                40BC5D9B053230FA009E6ADA /* Authorization.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2A593D3052E3AC700AF1EE3 /* Authorization.cpp */; };
                4C481F05058161C400846F0C /* trampolineClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C481F03058161C400846F0C /* trampolineClient.cpp */; };
                4C481F06058161C400846F0C /* trampolineServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C481F04058161C400846F0C /* trampolineServer.cpp */; };
                40BC5D9B053230FA009E6ADA /* Authorization.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2A593D3052E3AC700AF1EE3 /* Authorization.cpp */; };
                4C481F05058161C400846F0C /* trampolineClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C481F03058161C400846F0C /* trampolineClient.cpp */; };
                4C481F06058161C400846F0C /* trampolineServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C481F04058161C400846F0C /* trampolineServer.cpp */; };
@@ -42,6 +44,8 @@
                18446156146E928E00B12992 /* lib.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = lib.xcconfig; sourceTree = "<group>"; };
                18446157146E928E00B12992 /* release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = release.xcconfig; sourceTree = "<group>"; };
                18446158146E92F800B12992 /* libsecurity_utilities.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libsecurity_utilities.xcodeproj; path = ../libsecurity_utilities/libsecurity_utilities.xcodeproj; sourceTree = "<group>"; };
                18446156146E928E00B12992 /* lib.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = lib.xcconfig; sourceTree = "<group>"; };
                18446157146E928E00B12992 /* release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = release.xcconfig; sourceTree = "<group>"; };
                18446158146E92F800B12992 /* libsecurity_utilities.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libsecurity_utilities.xcodeproj; path = ../libsecurity_utilities/libsecurity_utilities.xcodeproj; sourceTree = "<group>"; };
+               18F2360415CB387000060520 /* Authorization.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Authorization.c; path = lib/Authorization.c; sourceTree = "<group>"; };
+               18F2360815CB3C7700060520 /* authutilities.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = authutilities.c; path = ../authd/authutilities.c; sourceTree = "<group>"; };
                40BC5D9005322F76009E6ADA /* Authorization.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Authorization.h; path = lib/Authorization.h; sourceTree = "<group>"; };
                40BC5D9305322F76009E6ADA /* AuthorizationDB.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AuthorizationDB.h; path = lib/AuthorizationDB.h; sourceTree = "<group>"; };
                40BC5D9405322F76009E6ADA /* AuthorizationPlugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AuthorizationPlugin.h; path = lib/AuthorizationPlugin.h; sourceTree = "<group>"; };
                40BC5D9005322F76009E6ADA /* Authorization.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Authorization.h; path = lib/Authorization.h; sourceTree = "<group>"; };
                40BC5D9305322F76009E6ADA /* AuthorizationDB.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AuthorizationDB.h; path = lib/AuthorizationDB.h; sourceTree = "<group>"; };
                40BC5D9405322F76009E6ADA /* AuthorizationPlugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AuthorizationPlugin.h; path = lib/AuthorizationPlugin.h; sourceTree = "<group>"; };
                C2A593CE052E3A8400AF1EE3 /* lib */ = {
                        isa = PBXGroup;
                        children = (
                C2A593CE052E3A8400AF1EE3 /* lib */ = {
                        isa = PBXGroup;
                        children = (
+                               18F2360815CB3C7700060520 /* authutilities.c */,
+                               18F2360415CB387000060520 /* Authorization.c */,
                                40C767090534CCDB008AC043 /* AuthorizationTagsPriv.h */,
                                40BC5D9005322F76009E6ADA /* Authorization.h */,
                                40BC5D9305322F76009E6ADA /* AuthorizationDB.h */,
                                40C767090534CCDB008AC043 /* AuthorizationTagsPriv.h */,
                                40BC5D9005322F76009E6ADA /* Authorization.h */,
                                40BC5D9305322F76009E6ADA /* AuthorizationDB.h */,
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0420;
+                               LastUpgradeCheck = 0500;
                        };
                        buildConfigurationList = C27AD2B70987FCDD001272E0 /* Build configuration list for PBXProject "libsecurity_authorization" */;
                        compatibilityVersion = "Xcode 3.2";
                        };
                        buildConfigurationList = C27AD2B70987FCDD001272E0 /* Build configuration list for PBXProject "libsecurity_authorization" */;
                        compatibilityVersion = "Xcode 3.2";
                                40BC5D9B053230FA009E6ADA /* Authorization.cpp in Sources */,
                                4C481F05058161C400846F0C /* trampolineClient.cpp in Sources */,
                                4C481F06058161C400846F0C /* trampolineServer.cpp in Sources */,
                                40BC5D9B053230FA009E6ADA /* Authorization.cpp in Sources */,
                                4C481F05058161C400846F0C /* trampolineClient.cpp in Sources */,
                                4C481F06058161C400846F0C /* trampolineServer.cpp in Sources */,
+                               18F2360515CB387000060520 /* Authorization.c in Sources */,
+                               18F2360915CB3C7700060520 /* authutilities.c in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446155146E928E00B12992 /* debug.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446155146E928E00B12992 /* debug.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                               HEADER_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       ../authd,
+                               );
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446157146E928E00B12992 /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446157146E928E00B12992 /* release.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                               HEADER_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       ../authd,
+                               );
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446156146E928E00B12992 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446156146E928E00B12992 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446156146E928E00B12992 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446156146E928E00B12992 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
index b019b79d066d5f070c4473604e8df426f7f8c776..dc091bb52b81887407d92533be995bcb7dbb8fcd 100644 (file)
@@ -30,7 +30,7 @@
 // and thus don't need to be interlocked explicitly.
 //
 #include <security_cdsa_client/cssmclient.h>
 // and thus don't need to be interlocked explicitly.
 //
 #include <security_cdsa_client/cssmclient.h>
-
+#include <syslog.h>
 
 using namespace CssmClient;
 
 
 using namespace CssmClient;
 
@@ -77,8 +77,11 @@ ObjectImpl::ObjectImpl(const Object &mommy) : mParent(mommy.mImpl), mChildCount(
 ObjectImpl::~ObjectImpl()
 try
 {
 ObjectImpl::~ObjectImpl()
 try
 {
-       assert(!mActive);       // subclass must have deactivated us
-       assert(isIdle());
+    if (!isIdle())
+    {
+        int i = mChildCount;
+        syslog(LOG_ALERT, "Object %p still has %d children at delete.\n", this, i);
+    }
                
        // release parent from her obligations (if we still have one)
        if (mParent)
                
        // release parent from her obligations (if we still have one)
        if (mParent)
@@ -410,8 +413,8 @@ ModuleImpl::activate()
             mActive = true;
         }
     }
             mActive = true;
         }
     }
-
-       session()->catchExit();
+    
+    session()->catchExit();
 }
 
 void
 }
 
 void
index 43fb3141c717617b82a94d1858ac8a9fa001289b..faa2fe8d893754c223dd5ac747df07c1e2dc0c62 100644 (file)
@@ -97,6 +97,7 @@ public:
        virtual bool operator ==(const ObjectImpl &other) const;
 
        static void check(CSSM_RETURN status);
        virtual bool operator ==(const ObjectImpl &other) const;
 
        static void check(CSSM_RETURN status);
+       bool isIdle() const { return mChildCount == 0; }
 
 protected:
        bool mActive;                                   // loaded, attached, etc.
 
 protected:
        bool mActive;                                   // loaded, attached, etc.
@@ -108,7 +109,6 @@ protected:
 
        void addChild();
        void removeChild();
 
        void addChild();
        void removeChild();
-       bool isIdle() const { return mChildCount == 0; }
 
        // {de,}activate() assume you have locked *this
        virtual void activate() = 0;
 
        // {de,}activate() assume you have locked *this
        virtual void activate() = 0;
@@ -152,6 +152,8 @@ public:
        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; }
 
+    Impl* get() {return mImpl;}
+
 private:
        RefPointer<Impl> mImpl;
 };
 private:
        RefPointer<Impl> mImpl;
 };
index bac07b58b25af57a8946e6c77aafe9ee184b1a10..31510a53255be31380c778d6ee22e5c4a05ae23c 100644 (file)
@@ -23,6 +23,7 @@
 #include <security_cdsa_client/aclclient.h>
 #include <Security/cssmapple.h>
 #include <Security/cssmapplePriv.h>
 #include <security_cdsa_client/aclclient.h>
 #include <Security/cssmapple.h>
 #include <Security/cssmapplePriv.h>
+#include <Security/SecBase.h>
 
 using namespace CssmClient;
 
 
 using namespace CssmClient;
 
@@ -106,7 +107,6 @@ DbImpl::open()
 {
     {
         StLock<Mutex> _(mActivateMutex);
 {
     {
         StLock<Mutex> _(mActivateMutex);
-
         if (!mActive)
         {
             assert(mDbInfo == nil);
         if (!mActive)
         {
             assert(mDbInfo == nil);
@@ -114,10 +114,11 @@ DbImpl::open()
             check(CSSM_DL_DbOpen(mHandle.DLHandle, mDbName.canonicalName(), dbLocation(),
                                     mAccessRequest, mAccessCredentials,
                                     mOpenParameters, &mHandle.DBHandle));
             check(CSSM_DL_DbOpen(mHandle.DLHandle, mDbName.canonicalName(), dbLocation(),
                                     mAccessRequest, mAccessCredentials,
                                     mOpenParameters, &mHandle.DBHandle));
+
             mActive = true;
         }
             mActive = true;
         }
-    }
-    
+       }
+
     if (!mAccessCredentials && mDefaultCredentials)
         if (const AccessCredentials *creds = mDefaultCredentials->makeCredentials())
             CSSM_DL_Authenticate(handle(), mAccessRequest, creds);     // ignore error
     if (!mAccessCredentials && mDefaultCredentials)
         if (const AccessCredentials *creds = mDefaultCredentials->makeCredentials())
             CSSM_DL_Authenticate(handle(), mAccessRequest, creds);     // ignore error
@@ -367,6 +368,18 @@ DbImpl::unlock(const CSSM_DATA &password)
        check(CSSM_DL_PassThrough(handle(), CSSM_APPLECSPDL_DB_UNLOCK, &password, NULL));
 }
 
        check(CSSM_DL_PassThrough(handle(), CSSM_APPLECSPDL_DB_UNLOCK, &password, NULL));
 }
 
+void
+DbImpl::stash()
+{
+    check(CSSM_DL_PassThrough(handle(), CSSM_APPLECSPDL_DB_STASH, NULL, NULL));
+}
+
+void
+DbImpl::stashCheck()
+{
+    check(CSSM_DL_PassThrough(handle(), CSSM_APPLECSPDL_DB_STASH_CHECK, NULL, NULL));
+}
+
 void
 DbImpl::getSettings(uint32 &outIdleTimeout, bool &outLockOnSleep)
 {
 void
 DbImpl::getSettings(uint32 &outIdleTimeout, bool &outLockOnSleep)
 {
@@ -437,7 +450,7 @@ void DbImpl::setBatchMode(Boolean mode, Boolean rollback)
        //
        // Now, toggle the autocommit...
        //
        //
        // Now, toggle the autocommit...
        //
-       if ( result == noErr )
+       if ( result == errSecSuccess )
        {
                CSSM_BOOL modeToUse = !mode;
                if (rollback)
        {
                CSSM_BOOL modeToUse = !mode;
                if (rollback)
@@ -448,7 +461,7 @@ void DbImpl::setBatchMode(Boolean mode, Boolean rollback)
 
                result = CSSM_DL_PassThrough(dldbHandleOfUnderlyingDL,
                                                                         CSSM_APPLEFILEDL_TOGGLE_AUTOCOMMIT,
 
                result = CSSM_DL_PassThrough(dldbHandleOfUnderlyingDL,
                                                                         CSSM_APPLEFILEDL_TOGGLE_AUTOCOMMIT,
-                                                                        (void *)(modeToUse),
+                                                                        (void *)((size_t) modeToUse),
                                                                         NULL);
                if (!rollback && modeToUse)
                        result = CSSM_DL_PassThrough(dldbHandleOfUnderlyingDL,
                                                                         NULL);
                if (!rollback && modeToUse)
                        result = CSSM_DL_PassThrough(dldbHandleOfUnderlyingDL,
index 2579a42809343a1eb83d7fb9b086b801bfba37f6..a26d6915835d62d9d84c87c9e8c03c6b82d137be 100644 (file)
@@ -312,6 +312,8 @@ public:
        virtual void lock();
        virtual void unlock();
        virtual void unlock(const CSSM_DATA &password);
        virtual void lock();
        virtual void unlock();
        virtual void unlock(const CSSM_DATA &password);
+    virtual void stash();
+    virtual void stashCheck();
        virtual void getSettings(uint32 &outIdleTimeout, bool &outLockOnSleep);
        virtual void setSettings(uint32 inIdleTimeout, bool inLockOnSleep);
        virtual bool isLocked();
        virtual void getSettings(uint32 &outIdleTimeout, bool &outLockOnSleep);
        virtual void setSettings(uint32 inIdleTimeout, bool inLockOnSleep);
        virtual bool isLocked();
index 1a8976852f9c2916fe7da7b84fb95ba27ec11cd0..5b0ce87ca914b2fe2bd6b70f39a7a9cc1aaede15 100644 (file)
@@ -117,7 +117,7 @@ const CssmQuery &Query::cssmQuery() const
                        pred.attribute().set(it->mValue.get());
                        mPredicates.push_back(pred);
                }
                        pred.attribute().set(it->mValue.get());
                        mPredicates.push_back(pred);
                }
-               mQuery.set(mPredicates.size(), &mPredicates[0]);
+               mQuery.set((uint32)mPredicates.size(), &mPredicates[0]);
                mQueryValid = true;
        }
        return mQuery;
                mQueryValid = true;
        }
        return mQuery;
index 4d1381b25106324c865297a7424a1c11bab6993d..30e3248a30ced8febdcce16303f52c5485a53291 100644 (file)
@@ -68,8 +68,8 @@ private:
        const CssmData *mParams;
        Db mDb;
 
        const CssmData *mParams;
        Db mDb;
 
-       // generation parameters(?)
-       const ResourceControlContext *mInitialAcl;
+       // generation parameters(?) -- Unused
+       // const ResourceControlContext *mInitialAcl;
 };
 
 } // end namespace CssmClient
 };
 
 } // end namespace CssmClient
index 3c42c340a5c7f4ffc171af056ad681031f95d0bb..77e56255f75af3878c0fbfb655e1b65b28663e93 100644 (file)
@@ -39,7 +39,7 @@ KeyImpl::KeyImpl(const CSP &csp, const CSSM_KEY &key, bool copy) : ObjectImpl(cs
 }
 
 KeyImpl::KeyImpl(const CSP &csp, const CSSM_DATA &keyData) : ObjectImpl(csp),
 }
 
 KeyImpl::KeyImpl(const CSP &csp, const CSSM_DATA &keyData) : ObjectImpl(csp),
-CssmKey(keyData.Length, csp->allocator().alloc<uint8>(keyData.Length)) 
+CssmKey((uint32)keyData.Length, csp->allocator().alloc<uint8>((UInt32)keyData.Length))
 {
        memcpy(KeyData.Data, keyData.Data, keyData.Length);
        mActive=true;
 {
        memcpy(KeyData.Data, keyData.Data, keyData.Length);
        mActive=true;
@@ -48,7 +48,7 @@ CssmKey(keyData.Length, csp->allocator().alloc<uint8>(keyData.Length))
 KeyImpl::~KeyImpl()
 try
 {
 KeyImpl::~KeyImpl()
 try
 {
-       deactivate();
+    deactivate();
 }
 catch (...)
 {
 }
 catch (...)
 {
index cc12b8337182a0b8b5c23026a245d78d59b5cf2e..6918bc873113765b2b65028a7b4f9bc748da2d9d 100644 (file)
@@ -41,6 +41,10 @@ DLImpl(module)
 }
 
 CSPDLImpl::~CSPDLImpl()
 }
 
 CSPDLImpl::~CSPDLImpl()
+try
+{
+}
+catch (...)
 {
 }
 
 {
 }
 
@@ -231,7 +235,7 @@ SSGroupImpl::SSGroupImpl(const SSDb &ssDb,
 
        // Generate a kLabelSize byte random number that will be the label of
        // the key which we store in the dataBlob.
 
        // 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);
+       random.generate(mLabel, (uint32)mLabel.Length);
 
        // Overwrite the first 4 bytes with the magic cookie for a group.
        reinterpret_cast<uint32 *>(mLabel.Data)[0] = h2n(uint32(kGroupMagic));
 
        // Overwrite the first 4 bytes with the magic cookie for a group.
        reinterpret_cast<uint32 *>(mLabel.Data)[0] = h2n(uint32(kGroupMagic));
@@ -325,8 +329,8 @@ SSGroupImpl::decodeDataBlob(const CSSM_DATA &dataBlob,
        decrypt.final(plainText2);
 
        // Use DL allocator for allocating memory for data.
        decrypt.final(plainText2);
 
        // Use DL allocator for allocating memory for data.
-       uint32 length = plainText1.Length + plainText2.Length;
-       data.Data = allocator.alloc<uint8>(length);
+       CSSM_SIZE length = plainText1.Length + plainText2.Length;
+       data.Data = allocator.alloc<uint8>((UInt32)length);
        data.Length = length;
        memcpy(data.Data, plainText1.Data, plainText1.Length);
        memcpy(&data.Data[plainText1.Length], plainText2.Data, plainText2.Length);
        data.Length = length;
        memcpy(data.Data, plainText1.Data, plainText1.Length);
        memcpy(&data.Data[plainText1.Length], plainText2.Data, plainText2.Length);
@@ -367,9 +371,9 @@ SSGroupImpl::encodeDataBlob(const CSSM_DATA *data,
 
        // Create a dataBlob containing the label followed by the IV followed
        // by the cipherText.
 
        // Create a dataBlob containing the label followed by the IV followed
        // by the cipherText.
-       uint32 length = (kLabelSize + kIVSize
+       CSSM_SIZE length = (kLabelSize + kIVSize
                                         + cipherText1.Length + cipherText2.Length);
                                         + cipherText1.Length + cipherText2.Length);
-       dataBlob.Data = dataBlob.mAllocator.alloc<uint8>(length);
+       dataBlob.Data = dataBlob.mAllocator.alloc<uint8>((UInt32)length);
        dataBlob.Length = length;
        memcpy(dataBlob.Data, mLabel.Data, kLabelSize);
        memcpy(&dataBlob.Data[kLabelSize], iv.Data, kIVSize);
        dataBlob.Length = length;
        memcpy(dataBlob.Data, mLabel.Data, kLabelSize);
        memcpy(&dataBlob.Data[kLabelSize], iv.Data, kIVSize);
index f655d3a9717d04bb3ab3e4b2e6bf750c33991a78..a592cd618f72142b14ae34465e1dbb3ee33e3a66 100644 (file)
@@ -97,7 +97,7 @@ public:
     
 private:
     TPCallerAuth mCallerAuth;
     
 private:
     TPCallerAuth mCallerAuth;
-    PolicyInfo mPolicyInfo;
+    // PolicyInfo mPolicyInfo; // -- unused
        CssmDlDbList mDlDbList;
 };
 
        CssmDlDbList mDlDbList;
 };
 
index 674fc8d8e6a0287a6051b28c275a7f5cb6314f90..68cb65044a51863e9ea46b500dc3e7d7fc9af9db 100644 (file)
@@ -51,7 +51,7 @@ WrapKey::activate()
        if (!mActive)
        {
                Crypt::activate();
        if (!mActive)
        {
                Crypt::activate();
-               if (mWrappedKeyFormat != CSSM_KEYBLOB_WRAPPED_FORMAT_NONE);
+               if (mWrappedKeyFormat != CSSM_KEYBLOB_WRAPPED_FORMAT_NONE)
                        set(CSSM_ATTRIBUTE_WRAPPED_KEY_FORMAT, mWrappedKeyFormat);
        }
 }
                        set(CSSM_ATTRIBUTE_WRAPPED_KEY_FORMAT, mWrappedKeyFormat);
        }
 }
index c8ba138e258c1570d04e4add5d56050f8633bc7a..95caa836eb3bf26409f8b7a0780756030b54d586 100644 (file)
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0420;
+                               LastUpgradeCheck = 0500;
                        };
                        buildConfigurationList = C27AD2D60987FCDD001272E0 /* Build configuration list for PBXProject "libsecurity_cdsa_client" */;
                        compatibilityVersion = "Xcode 3.2";
                        };
                        buildConfigurationList = C27AD2D60987FCDD001272E0 /* Build configuration list for PBXProject "libsecurity_cdsa_client" */;
                        compatibilityVersion = "Xcode 3.2";
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446164146E94DE00B12992 /* debug.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446164146E94DE00B12992 /* debug.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/security_cdsa_client;
                                SKIP_INSTALL = NO;
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/security_cdsa_client;
                                SKIP_INSTALL = NO;
+                               WARNING_CFLAGS = (
+                                       "$(inherited)",
+                                       "-Wno-error=overloaded-virtual",
+                               );
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446166146E94DE00B12992 /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446166146E94DE00B12992 /* release.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/security_cdsa_client;
                                SKIP_INSTALL = NO;
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/security_cdsa_client;
                                SKIP_INSTALL = NO;
+                               WARNING_CFLAGS = (
+                                       "$(inherited)",
+                                       "-Wno-error=overloaded-virtual",
+                               );
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446165146E94DE00B12992 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446165146E94DE00B12992 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446165146E94DE00B12992 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446165146E94DE00B12992 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
index 862df1675a1c940dda45ce436fe8f0e156512c8d..d3eb96087e8319889148c8a342c316976cc31433 100644 (file)
@@ -432,7 +432,7 @@ void CSPFullPluginSession::QuerySize(CSSM_CC_HANDLE ccHandle,
        for (uint32 n = 0; n < querySizeCount; n++) {
                // the outputSize() call might throw CSSMERR_CSP_QUERY_SIZE_UNKNOWN
                dataBlock[n].SizeOutputBlock =
        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());
+                       (uint32)ctx->outputSize(n == querySizeCount-1, dataBlock[n].inputSize());
        }
        //@@@ if we forced a context creation, should we discard it now?
 }
        }
        //@@@ if we forced a context creation, should we discard it now?
 }
@@ -1039,8 +1039,8 @@ void
 KeyPool::add(ReferencedKey &referencedKey)
 {
        StLock<Mutex> _(mKeyMapLock);
 KeyPool::add(ReferencedKey &referencedKey)
 {
        StLock<Mutex> _(mKeyMapLock);
-       IFDEBUG(bool inserted =)
-               mKeyMap.insert(KeyMap::value_type(referencedKey.keyReference(), &referencedKey)).second;
+       bool inserted;
+    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);
        // Since add is only called from the constructor of ReferencedKey we should
        // never add a key that is already in mKeyMap
        assert(inserted);
index 1d2ae9b1d63e9dd3d9b5ef26009013ee0c76482b..74234bdb492dfc6f29891ef3bdb404cfddfd4d3f 100644 (file)
@@ -126,7 +126,7 @@ protected:
        
                // can this buffer be extended?
                bool isExtensible() const
        
                // can this buffer be extended?
                bool isExtensible() const
-               { return !*vec || remData && !*remData; }
+               { return !*vec || (remData && !*remData); }
        
                // increase size if necessary (and possible)
                void allocate(size_t needed, Allocator &alloc);
        
                // increase size if necessary (and possible)
                void allocate(size_t needed, Allocator &alloc);
index 1f554afda6e9847bca8e794e7a4f8669819fd2f7..5c0b2ac62d160801aadaed1985e5b406ef0208df 100644 (file)
@@ -322,7 +322,12 @@ DatabaseSession::GetDbNameFromHandle(CSSM_DB_HANDLE inDbHandle,
        secdebug("dbsession", "********************");
 }
 
        secdebug("dbsession", "********************");
 }
 
+
 #ifndef NDEBUG
 #ifndef NDEBUG
+
+#if 0 /* unusued functions */
+
+static
 void DumpAttributeInfo(const CSSM_DB_ATTRIBUTE_INFO &info)
 {
        const char* attrNameType;
 void DumpAttributeInfo(const CSSM_DB_ATTRIBUTE_INFO &info)
 {
        const char* attrNameType;
@@ -393,7 +398,7 @@ void DumpAttributeInfo(const CSSM_DB_ATTRIBUTE_INFO &info)
 }
 
 
 }
 
 
-
+static
 void DumpAttributes(const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes)
 {
        if (!inAttributes)
 void DumpAttributes(const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes)
 {
        if (!inAttributes)
@@ -443,8 +448,8 @@ void DumpAttributes(const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes)
                                        break;
                                case CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32:
                                {
                                        break;
                                case CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32:
                                {
-                                       unsigned j;
-                                       unsigned numInts = inAttributes->AttributeData[n].Value[i].Length / sizeof(UInt32);
+                                       unsigned long j;
+                                       unsigned long numInts = inAttributes->AttributeData[n].Value[i].Length / sizeof(UInt32);
                                        for (j = 0; j < numInts; ++j)
                                        {
                                                uint32* nums = (uint32*) inAttributes->AttributeData[n].Value[i].Data;
                                        for (j = 0; j < numInts; ++j)
                                        {
                                                uint32* nums = (uint32*) inAttributes->AttributeData[n].Value[i].Data;
@@ -461,15 +466,15 @@ void DumpAttributes(const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes)
                }
        }
 }
                }
        }
 }
+#endif 
 
 
 
 
-
-void
+static void
 DumpUniqueRecord(const CSSM_DB_UNIQUE_RECORD &record)
 {
 DumpUniqueRecord(const CSSM_DB_UNIQUE_RECORD &record)
 {
+/*
        const char* s;
 
        const char* s;
 
-/*     
        switch (record.RecordLocator.IndexType)
        {
                case CSSM_DB_INDEX_UNIQUE:
        switch (record.RecordLocator.IndexType)
        {
                case CSSM_DB_INDEX_UNIQUE:
@@ -527,7 +532,7 @@ DumpUniqueRecord(const CSSM_DB_UNIQUE_RECORD &record)
        
        secdebug("dbsession", "    RecordIdentifier.Data: %s", output.c_str());
 }
        
        secdebug("dbsession", "    RecordIdentifier.Data: %s", output.c_str());
 }
-#endif
+#endif /* NDEBUG */
 
 void
 DatabaseSession::DataInsert(CSSM_DB_HANDLE inDbHandle,
 
 void
 DatabaseSession::DataInsert(CSSM_DB_HANDLE inDbHandle,
index b9845e71404f42208ce48c32e6cb5727f03c32a3..b435c4ae3a942b334cd0fab1bc16c9aabfccdd43 100644 (file)
 # define SPINAME(s) s
 #endif
 
 # define SPINAME(s) s
 #endif
 
+SPIPREFIX CSSM_RETURN SPINAME(CSSM_SPI_ModuleLoad) (const CSSM_GUID *CssmGuid,
+                                                    const CSSM_GUID *ModuleGuid,
+                                                    CSSM_SPI_ModuleEventHandler CssmNotifyCallback,
+                                                    void *CssmNotifyCallbackCtx);
 
 SPIPREFIX CSSM_RETURN SPINAME(CSSM_SPI_ModuleLoad) (const CSSM_GUID *CssmGuid,
     const CSSM_GUID *ModuleGuid,
 
 SPIPREFIX CSSM_RETURN SPINAME(CSSM_SPI_ModuleLoad) (const CSSM_GUID *CssmGuid,
     const CSSM_GUID *ModuleGuid,
@@ -50,6 +54,11 @@ SPIPREFIX CSSM_RETURN SPINAME(CSSM_SPI_ModuleLoad) (const CSSM_GUID *CssmGuid,
     END_API(CSSM)
 }
 
     END_API(CSSM)
 }
 
+SPIPREFIX CSSM_RETURN SPINAME(CSSM_SPI_ModuleUnload) (const CSSM_GUID *CssmGuid,
+                                                      const CSSM_GUID *ModuleGuid,
+                                                      CSSM_SPI_ModuleEventHandler CssmNotifyCallback,
+                                                      void *CssmNotifyCallbackCtx);
+
 SPIPREFIX CSSM_RETURN SPINAME(CSSM_SPI_ModuleUnload) (const CSSM_GUID *CssmGuid,
     const CSSM_GUID *ModuleGuid,
     CSSM_SPI_ModuleEventHandler CssmNotifyCallback,
 SPIPREFIX CSSM_RETURN SPINAME(CSSM_SPI_ModuleUnload) (const CSSM_GUID *CssmGuid,
     const CSSM_GUID *ModuleGuid,
     CSSM_SPI_ModuleEventHandler CssmNotifyCallback,
@@ -62,6 +71,19 @@ SPIPREFIX CSSM_RETURN SPINAME(CSSM_SPI_ModuleUnload) (const CSSM_GUID *CssmGuid,
     END_API(CSSM)
 }
 
     END_API(CSSM)
 }
 
+SPIPREFIX CSSM_RETURN SPINAME(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);
+
 SPIPREFIX CSSM_RETURN SPINAME(CSSM_SPI_ModuleAttach) (const CSSM_GUID *ModuleGuid,
     const CSSM_VERSION *Version,
     uint32 SubserviceID,
 SPIPREFIX CSSM_RETURN SPINAME(CSSM_SPI_ModuleAttach) (const CSSM_GUID *ModuleGuid,
     const CSSM_VERSION *Version,
     uint32 SubserviceID,
@@ -91,6 +113,8 @@ SPIPREFIX CSSM_RETURN SPINAME(CSSM_SPI_ModuleAttach) (const CSSM_GUID *ModuleGui
     END_API(CSSM)
 }
 
     END_API(CSSM)
 }
 
+SPIPREFIX CSSM_RETURN SPINAME(CSSM_SPI_ModuleDetach) (CSSM_MODULE_HANDLE ModuleHandle);
+
 SPIPREFIX CSSM_RETURN SPINAME(CSSM_SPI_ModuleDetach) (CSSM_MODULE_HANDLE ModuleHandle)
 {
     BEGIN_API
 SPIPREFIX CSSM_RETURN SPINAME(CSSM_SPI_ModuleDetach) (CSSM_MODULE_HANDLE ModuleHandle)
 {
     BEGIN_API
index 77f74464c5c82430a46e66fdaa61da8a3ee9f291..e2caf9aeba20ef8c58e3b078c233ede46d200af2 100644 (file)
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0420;
+                               LastUpgradeCheck = 0500;
                        };
                        buildConfigurationList = C27AD2E80987FCDD001272E0 /* Build configuration list for PBXProject "libsecurity_cdsa_plugin" */;
                        compatibilityVersion = "Xcode 3.2";
                        };
                        buildConfigurationList = C27AD2E80987FCDD001272E0 /* Build configuration list for PBXProject "libsecurity_cdsa_plugin" */;
                        compatibilityVersion = "Xcode 3.2";
                C27AD2DD0987FCDD001272E0 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                C27AD2DD0987FCDD001272E0 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                CSSM_HEADERS = "$(PROJECT_DIR)/../libsecurity_cssm/lib";
                                INSTALLHDRS_SCRIPT_PHASE = YES;
                        };
                                CSSM_HEADERS = "$(PROJECT_DIR)/../libsecurity_cssm/lib";
                                INSTALLHDRS_SCRIPT_PHASE = YES;
                        };
                C27AD2DF0987FCDD001272E0 /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                C27AD2DF0987FCDD001272E0 /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                CSSM_HEADERS = "$(PROJECT_DIR)/../libsecurity_cssm/lib";
                                INSTALLHDRS_SCRIPT_PHASE = YES;
                        };
                                CSSM_HEADERS = "$(PROJECT_DIR)/../libsecurity_cssm/lib";
                                INSTALLHDRS_SCRIPT_PHASE = YES;
                        };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844606E146DEE4400B12992 /* debug.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844606E146DEE4400B12992 /* debug.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                OTHER_CFLAGS = "";
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/security_cdsa_plugin;
                                SKIP_INSTALL = NO;
                                OTHER_CFLAGS = "";
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/security_cdsa_plugin;
                                SKIP_INSTALL = NO;
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446070146DEE4400B12992 /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446070146DEE4400B12992 /* release.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                OTHER_CFLAGS = "";
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/security_cdsa_plugin;
                                SKIP_INSTALL = NO;
                                OTHER_CFLAGS = "";
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/security_cdsa_plugin;
                                SKIP_INSTALL = NO;
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844606F146DEE4400B12992 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844606F146DEE4400B12992 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844606F146DEE4400B12992 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844606F146DEE4400B12992 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
index dc007fd679f62989a365a10b026f02bf58d37fe7..a1f5b3b2f1960e32040e2bea5fd303dec04c3834 100644 (file)
@@ -108,7 +108,7 @@ void
 AuthValueVector::copy(AuthorizationValueVector **data, size_t *length) const
 {
     AuthorizationValueVector valueVector;
 AuthValueVector::copy(AuthorizationValueVector **data, size_t *length) const
 {
     AuthorizationValueVector valueVector;
-    valueVector.count = size();
+    valueVector.count = (UInt32)size();
     valueVector.values = new AuthorizationValue[valueVector.count];
     int i = 0;
        for (const_iterator it = begin(); it != end(); ++it, ++i)
     valueVector.values = new AuthorizationValue[valueVector.count];
     int i = 0;
        for (const_iterator it = begin(); it != end(); ++it, ++i)
@@ -323,7 +323,7 @@ void
 AuthItemSet::copy(AuthorizationItemSet *&data, size_t &length, Allocator &alloc) const
 {
     AuthorizationItemSet itemSet;
 AuthItemSet::copy(AuthorizationItemSet *&data, size_t &length, Allocator &alloc) const
 {
     AuthorizationItemSet itemSet;
-    itemSet.count = size();
+    itemSet.count = (UInt32)size();
     itemSet.items = new AuthorizationItem[itemSet.count];
     int i = 0;
     for (const_iterator it = begin(); it != end(); ++it, ++i)
     itemSet.items = new AuthorizationItem[itemSet.count];
     int i = 0;
     for (const_iterator it = begin(); it != end(); ++it, ++i)
index b611e62d9c1ecdf88b60d7c993857685b60d5126..08de9989a35f2590fd446d55d43dae25c8401d24 100644 (file)
@@ -2,13 +2,13 @@ divert(-1)
 changecom(/*, */)
 /*
  * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
 changecom(/*, */)
 /*
  * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
- * 
+ *
  * The contents of this file constitute Original Code as defined in and are
  * subject to the Apple Public Source License Version 1.2 (the 'License').
  * You may not use this file except in 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 contents of this file constitute Original Code as defined in and are
  * subject to the Apple Public Source License Version 1.2 (the 'License').
  * You may not use this file except in compliance with the License. Please obtain
  * a copy of the License at http://www.apple.com/publicsource and read it before
  * using this file.
- * 
+ *
  * This Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
  * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
  * This Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
  * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
@@ -312,7 +312,7 @@ newAttribute(`  Ss', PrintName, kSecLabelItemAttr, (char*) "PrintName", 0, NULL,
 newAttribute(`  Ss', Alias, kSecAlias, (char*) "Alias", 0, NULL, BLOB)
 endNewClass()
 
 newAttribute(`  Ss', Alias, kSecAlias, (char*) "Alias", 0, NULL, BLOB)
 endNewClass()
 
-// Extended Attribute 
+// Extended Attribute
 startNewClass(ExtendedAttribute)
 newAttribute(`UISs', RecordType, kExtendedAttrRecordTypeAttr, (char*) "RecordType", 0, NULL, UINT32)
 newAttribute(`UISs', ItemID, kExtendedAttrItemIDAttr, (char*) "ItemID", 0, NULL, BLOB)
 startNewClass(ExtendedAttribute)
 newAttribute(`UISs', RecordType, kExtendedAttrRecordTypeAttr, (char*) "RecordType", 0, NULL, UINT32)
 newAttribute(`UISs', ItemID, kExtendedAttrItemIDAttr, (char*) "ItemID", 0, NULL, BLOB)
@@ -367,7 +367,7 @@ recordTypeFor(SecItemClass itemClass)
     {
     case kSecGenericPasswordItemClass: return CSSM_DL_DB_RECORD_GENERIC_PASSWORD;
     case kSecInternetPasswordItemClass: return CSSM_DL_DB_RECORD_INTERNET_PASSWORD;
     {
     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;
+    case 'ashp': return CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD;
     default: return CSSM_DB_RECORDTYPE(itemClass);
     }
 }
     default: return CSSM_DB_RECORDTYPE(itemClass);
     }
 }
@@ -379,7 +379,7 @@ itemClassFor(CSSM_DB_RECORDTYPE recordType)
     {
     case CSSM_DL_DB_RECORD_GENERIC_PASSWORD: return kSecGenericPasswordItemClass;
     case CSSM_DL_DB_RECORD_INTERNET_PASSWORD: return kSecInternetPasswordItemClass;
     {
     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;
+    case CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD: return 'ashp';
     default: return SecItemClass(recordType);
     }
 }
     default: return SecItemClass(recordType);
     }
 }
@@ -387,7 +387,7 @@ itemClassFor(CSSM_DB_RECORDTYPE recordType)
 const CSSM_DB_ATTRIBUTE_INFO &
 attributeInfo(SecKeychainAttrType attrType)
 {
 const CSSM_DB_ATTRIBUTE_INFO &
 attributeInfo(SecKeychainAttrType attrType)
 {
-    switch (attrType) 
+    switch (attrType)
     {
     case kSecCreationDateItemAttr: return kGenericCreationDate;
     case kSecModDateItemAttr: return kGenericModDate;
     {
     case kSecCreationDateItemAttr: return kGenericCreationDate;
     case kSecModDateItemAttr: return kGenericModDate;
index 6a5ab718ef5ba0898917747f2cdee7501daf663b..a10adb2ff17c7938b7dba553004ce10b3029cd60 100644 (file)
@@ -104,7 +104,9 @@ CommentAclSubject *CommentAclSubject::Maker::make(Version, Reader &pub, Reader &
        // Phew. I'd rather be lucky than good...
        //
        // So let's get started:
        // Phew. I'd rather be lucky than good...
        //
        // So let's get started:
+#ifndef NDEBUG
        static const size_t minCssmList = 12;   // min(sizeof(CSSM_LIST)) of all architectures
        static const size_t minCssmList = 12;   // min(sizeof(CSSM_LIST)) of all architectures
+#endif
        pub.get<void>(4);                       // skip first 4 bytes
        uint32_t lop; pub(lop);         // read L4n-or-(bottom of)P8h
        uint32_t tol; pub(tol);         // read T4h-or-L4n
        pub.get<void>(4);                       // skip first 4 bytes
        uint32_t lop; pub(lop);         // read L4n-or-(bottom of)P8h
        uint32_t tol; pub(tol);         // read T4h-or-L4n
index 86ad36e27401988dad08e89cfd230938bf345317..a2f3e41701bfa243d6b775d51137b8ec870a7daa 100644 (file)
@@ -171,7 +171,7 @@ bool SourceAclSubject::SourceAclSubject::validate(const AclValidationContext &ba
                        CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_SUBJECT_VALUE);
                uint32 slot = CSSM_ACL_AUTHORIZATION_PREAUTH_SLOT(auth);
                secdebug("preauth", "using state %d@%p", slot, &env->store(this));
                        CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_SUBJECT_VALUE);
                uint32 slot = CSSM_ACL_AUTHORIZATION_PREAUTH_SLOT(auth);
                secdebug("preauth", "using state %d@%p", slot, &env->store(this));
-               bool &accepted = env->store(this).attachment<AclState>((void *)slot).accepted;
+               bool &accepted = env->store(this).attachment<AclState>((void *)((size_t) slot)).accepted;
                if (!accepted) {
                        secdebug("preauth", "%p needs to authenticate its subject", this);
                        SourceValidationContext ctx(baseCtx);
                if (!accepted) {
                        secdebug("preauth", "%p needs to authenticate its subject", this);
                        SourceValidationContext ctx(baseCtx);
index b62e33254f19b773f7a91218c50f025261792b5c..ee996361b866ca1bb697e8d3ad3c087fd3069f61 100644 (file)
@@ -78,7 +78,8 @@ class AclValidationContext {
 public:
     AclValidationContext(const AccessCredentials *cred,
         AclAuthorization auth, AclValidationEnvironment *env = NULL)
 public:
     AclValidationContext(const AccessCredentials *cred,
         AclAuthorization auth, AclValidationEnvironment *env = NULL)
-    : mCred(cred), mAuth(auth), mEnv(env), mEntryTag(NULL) { }
+    : mAcl((ObjectAcl*) 0xDEADDEADDEADDEAD), mSubject((AclSubject*) 0xDEADDEADDEADDEAD), mCred(cred),
+        mAuth(auth), mEnv(env), mEntryTag(NULL) { }
     AclValidationContext(const AclValidationContext &ctx)
     : mAcl(ctx.mAcl), mSubject(ctx.mSubject), mCred(ctx.mCred),
          mAuth(ctx.mAuth), mEnv(ctx.mEnv), mEntryTag(NULL) { }
     AclValidationContext(const AclValidationContext &ctx)
     : mAcl(ctx.mAcl), mSubject(ctx.mSubject), mCred(ctx.mCred),
          mAuth(ctx.mAuth), mEnv(ctx.mEnv), mEntryTag(NULL) { }
index 7bb5191d7868edb90f6e947b36e297cd5b584039..ed51eb1c55e16d3c821feac3cd3655a677fa5b58 100644 (file)
@@ -56,7 +56,7 @@ public:
     { return mCallback == cb.mCallback && mContext == cb.mContext; }
     bool operator < (const ModuleCallback &cb) const
     { return mCallback < cb.mCallback
     { return mCallback == cb.mCallback && mContext == cb.mContext; }
     bool operator < (const ModuleCallback &cb) const
     { return mCallback < cb.mCallback
-        || mCallback == cb.mCallback && mContext < cb.mContext; }
+        || (mCallback == cb.mCallback && mContext < cb.mContext); }
 
 private:
     CSSM_API_ModuleEventHandler mCallback;
 
 private:
     CSSM_API_ModuleEventHandler mCallback;
@@ -75,7 +75,7 @@ private:
 //
 class ModuleCallbackSet {
 public:
 //
 class ModuleCallbackSet {
 public:
-    unsigned int size() const { return callbacks.size(); }
+    unsigned int size() const { return (int)callbacks.size(); }
     void insert(const ModuleCallback &newCallback);
     void erase(const ModuleCallback &oldCallback);
 
     void insert(const ModuleCallback &newCallback);
     void erase(const ModuleCallback &oldCallback);
 
index 5fdd972593e4089aa36d56968b57a6dd3e0a2c7c..0df2e5bd0e211db1b88d999131159b5349b9c67f 100644 (file)
@@ -74,7 +74,7 @@ public:
             AttributeType = typ;
                        // attribute component pointers are stupidly non-const; allow const input
             Attribute.String = const_cast<char *>(reinterpret_cast<const char *>(&value));
             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);
+            AttributeLength = (uint32_t) (size ? size : sizeof(T));
         }
 
         Attr(CSSM_ATTRIBUTE_TYPE typ, uint32 value)
         }
 
         Attr(CSSM_ATTRIBUTE_TYPE typ, uint32 value)
@@ -339,7 +339,7 @@ public:
             assert(slot < slotCount);                  // check overflow
             Attr &attribute = attributes[slot++];
             attribute.AttributeType = type;
             assert(slot < slotCount);                  // check overflow
             Attr &attribute = attributes[slot++];
             attribute.AttributeType = type;
-            attribute.AttributeLength = size(p); //@@@ needed? how/when/what for?
+            attribute.AttributeLength =  (uint32)size(p); //@@@ needed? how/when/what for?
             T *tmp = const_cast<T *>(p);
             attribute = walk(copier, tmp);
         }
             T *tmp = const_cast<T *>(p);
             attribute = walk(copier, tmp);
         }
index def26ab1628bc9cc40db2ae48a3e98106b701179..e7144c43f6db919e82f3250dd5f7b80542e9d514 100644 (file)
@@ -55,7 +55,7 @@ AclAuthorizationSet::AclAuthorizationSet(AclAuthorization auth0, AclAuthorizatio
 //
 AuthorizationGroup::AuthorizationGroup(const AclAuthorizationSet &auths, Allocator &alloc)
 {
 //
 AuthorizationGroup::AuthorizationGroup(const AclAuthorizationSet &auths, Allocator &alloc)
 {
-       NumberOfAuthTags = auths.size();
+       NumberOfAuthTags = (uint32)auths.size();
        AuthTags = alloc.alloc<CSSM_ACL_AUTHORIZATION_TAG>(NumberOfAuthTags);
        copy(auths.begin(), auths.end(), AuthTags);     // happens to be sorted
 }
        AuthTags = alloc.alloc<CSSM_ACL_AUTHORIZATION_TAG>(NumberOfAuthTags);
        copy(auths.begin(), auths.end(), AuthTags);     // happens to be sorted
 }
@@ -112,7 +112,8 @@ void AclEntryPrototype::tag(const string &tagString)
 AclOwnerPrototype *AutoAclOwnerPrototype::make()
 {
        if (!mAclOwnerPrototype) {
 AclOwnerPrototype *AutoAclOwnerPrototype::make()
 {
        if (!mAclOwnerPrototype) {
-               mAclOwnerPrototype = new AclOwnerPrototype; 
+               mAclOwnerPrototype = (AclOwnerPrototype*) mAllocator->malloc(sizeof(AclOwnerPrototype));
+        new (mAclOwnerPrototype) AclOwnerPrototype;
                mAclOwnerPrototype->clearPod();
        }
        return mAclOwnerPrototype;
                mAclOwnerPrototype->clearPod();
        }
        return mAclOwnerPrototype;
index 661d29b7ef7ee6f88192868e096d63e0b9fcf5eb..74b50566b67633a2ac98b59d37a6bccdcf441dfb 100644 (file)
@@ -120,8 +120,8 @@ string CssmData::toOid() const
        // first byte is composite (q1,q2)
        char buffer[10];
        unsigned long oid1 = getOid(*this, pos);
        // first byte is composite (q1,q2)
        char buffer[10];
        unsigned long oid1 = getOid(*this, pos);
-       unsigned int q1 = min(oid1 / 40, 2ul);
-       snprintf(buffer, sizeof(buffer), "%u.%lu", q1, oid1 - q1 * 40);
+       unsigned long q1 = min(oid1 / 40, 2ul);
+       snprintf(buffer, sizeof(buffer), "%lu.%lu", q1, oid1 - q1 * 40);
        string s = buffer;
 
        // now for the rest
        string s = buffer;
 
        // now for the rest
index a55d0f37fdb115e04a9ea3002bbff167a04903ce..591a1ddb04a30711d46021ad02b96991497b574f 100644 (file)
@@ -507,7 +507,7 @@ public:
        ~CssmDataContainer() { if (Data) mAllocator.free(Data); }
        void append(const CssmPolyData &data)
        {
        ~CssmDataContainer() { if (Data) mAllocator.free(Data); }
        void append(const CssmPolyData &data)
        {
-               uint32 newLength = Length + data.Length;
+               size_t newLength = Length + data.Length;
                Data = reinterpret_cast<uint8 *>(mAllocator.realloc(Data, newLength));
                memcpy(Data + Length, data.Data, data.Length);
                Length = newLength;
                Data = reinterpret_cast<uint8 *>(mAllocator.realloc(Data, newLength));
                memcpy(Data + Length, data.Data, data.Length);
                Length = newLength;
index 0c938a7f6f26a1f5077dd8a720b979894b11e145..d4bceb5a4a5366b375da934c778cdd7884abcbf0 100644 (file)
@@ -83,7 +83,7 @@ int CssmDate::day() const
 void CssmDate::assign(char *dest, int width, const char *src)
 {
     // pick last width characters of src at most
 void CssmDate::assign(char *dest, int width, const char *src)
 {
     // pick last width characters of src at most
-    int len = strlen(src);
+    size_t len = strlen(src);
     if (len > width)
         CssmError::throwMe(CSSM_ERRCODE_UNKNOWN_FORMAT);
     memset(dest, '0', width - len);
     if (len > width)
         CssmError::throwMe(CSSM_ERRCODE_UNKNOWN_FORMAT);
     memset(dest, '0', width - len);
@@ -191,5 +191,5 @@ void CssmUniformDate::setFromString(const char *src, const char *format, size_t
         CssmError::throwMe(CSSM_ERRCODE_UNKNOWN_FORMAT);
 
     // success
         CssmError::throwMe(CSSM_ERRCODE_UNKNOWN_FORMAT);
 
     // success
-    mTime = Gregorian(year, month, day, hour, minute, second);
+    mTime = Gregorian((int)year, month, day, hour, minute, second);
 }
 }
index 5765e86ded6ad91fee8d12490c21cd7dc4afc3dd..85c49a261affb97081c5c8917ce712e30a93ceab 100644 (file)
@@ -283,7 +283,7 @@ void CssmDbAttributeData::set(const CSSM_DB_ATTRIBUTE_INFO &inInfo, const CssmPo
        NumberOfValues = 0;
        Value = inAllocator.alloc<CSSM_DATA>();
        Value[0].Length = 0;
        NumberOfValues = 0;
        Value = inAllocator.alloc<CSSM_DATA>();
        Value[0].Length = 0;
-       Value[0].Data = inAllocator.alloc<uint8>(inValue.Length);
+       Value[0].Data = inAllocator.alloc<uint8>((UInt32)inValue.Length);
        Value[0].Length = inValue.Length;
        memcpy(Value[0].Data, inValue.Data, inValue.Length);
        NumberOfValues = 1;
        Value[0].Length = inValue.Length;
        memcpy(Value[0].Data, inValue.Data, inValue.Length);
        NumberOfValues = 1;
@@ -356,7 +356,7 @@ CssmDbAttributeData::add(const CssmDbAttributeData &src, Allocator &inAllocator)
                uint32 destIndex = NumberOfValues + srcIndex;
                
                Value[destIndex].Length = 0;
                uint32 destIndex = NumberOfValues + srcIndex;
                
                Value[destIndex].Length = 0;
-               Value[destIndex].Data = inAllocator.alloc<uint8>(src.Value[srcIndex].Length);
+               Value[destIndex].Data = inAllocator.alloc<uint8>((UInt32)src.Value[srcIndex].Length);
                Value[destIndex].Length = src.Value[srcIndex].Length;
                memcpy(Value[destIndex].Data, src.Value[srcIndex].Data, src.Value[srcIndex].Length);
        }
                Value[destIndex].Length = src.Value[srcIndex].Length;
                memcpy(Value[destIndex].Data, src.Value[srcIndex].Data, src.Value[srcIndex].Length);
        }
index f4fa0befa9177a2c65c64e2a14a5b8ca016f6a68..f49fa48276845e7cda025f62e0553ce0ff00f5ee 100644 (file)
@@ -214,7 +214,11 @@ class CssmDLPolyData
 {
 public:
        CssmDLPolyData(const CSSM_DATA &data, CSSM_DB_ATTRIBUTE_FORMAT format)
 {
 public:
        CssmDLPolyData(const CSSM_DATA &data, CSSM_DB_ATTRIBUTE_FORMAT format)
-       : mData(CssmData::overlay(data)), mFormat(format) {}
+       : mData(CssmData::overlay(data))
+#ifndef NDEBUG
+    , mFormat(format)
+#endif 
+    {}
 
        // @@@ Don't use assert, but throw an exception.
        // @@@ Do a size check on mData as well.
 
        // @@@ Don't use assert, but throw an exception.
        // @@@ Do a size check on mData as well.
@@ -260,7 +264,9 @@ public:
 
 private:
        const CssmData &mData;
 
 private:
        const CssmData &mData;
+#ifndef NDEBUG
        CSSM_DB_ATTRIBUTE_FORMAT mFormat;
        CSSM_DB_ATTRIBUTE_FORMAT mFormat;
+#endif
 };
 
 
 };
 
 
index 02a541195538aede4a6b04400d9728ec9a03b962..269f86bdf29186d3b9b2c9b4241657ab0384974e 100644 (file)
@@ -72,7 +72,7 @@ void DbName::CanonicalizeName()
                        // we will pull the path apart and try again.
                        
                        // search backward for the delimiter
                        // we will pull the path apart and try again.
                        
                        // search backward for the delimiter
-                       int n = mDbName.length() - 1;
+                       ptrdiff_t n = mDbName.length() - 1;
                        
                        // all subpaths must be tested, because there may be more than just
                        // the file name that doesn't exist.
                        
                        // all subpaths must be tested, because there may be more than just
                        // the file name that doesn't exist.
index e5a3460ce56bac3ace7f6d9a437c5f3915b4ea07..2d9a688ce18384ad530a3a72d05154f83210d01c 100644 (file)
@@ -28,7 +28,7 @@
 #include <security_cdsa_utilities/cssmerrors.h>
 #include <security_utilities/mach++.h>
 #include <Security/cssmapple.h>
 #include <security_cdsa_utilities/cssmerrors.h>
 #include <security_utilities/mach++.h>
 #include <Security/cssmapple.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+#include <Security/SecBase.h>
 
 namespace Security {
 
 
 namespace Security {
 
@@ -49,7 +49,7 @@ OSStatus CssmError::osStatus() const
 {
        if (error == CSSM_ERRCODE_INVALID_POINTER)
        {
 {
        if (error == CSSM_ERRCODE_INVALID_POINTER)
        {
-               return paramErr;
+               return errSecParam;
        }
        
        return error;
        }
        
        return error;
index 1e5eab49be544394c30d5c7b4e97bb62783f3b6c..b154c7df93cabbdb9d759c683c7f26a7aa1ef7ef 100644 (file)
@@ -56,7 +56,7 @@ public:
     bool operator < (const CSSM_GUID &other) const
     { return memcmp(this, &other, sizeof(CSSM_GUID)) < 0; }
     size_t hash() const {      //@@@ revisit this hash
     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;
+        return Data1 + (Data2 << 3) + (Data3 << 11) + (Data4[3]) + (Data4[6] << 22);
     }
 
     static const unsigned stringRepLength = 38;        // "{x8-x4-x4-x4-x12}"
     }
 
     static const unsigned stringRepLength = 38;        // "{x8-x4-x4-x4-x12}"
index 8faad5370bfbf4341bda4b020106ceb513ee6745..3ba1408eea7b83fd2abc06236ba21eebaf9aecc8 100644 (file)
@@ -29,7 +29,6 @@
 #ifndef        _DIGEST_OBJECT_H_
 #define _DIGEST_OBJECT_H_
 
 #ifndef        _DIGEST_OBJECT_H_
 #define _DIGEST_OBJECT_H_
 
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
 #include <security_cdsa_utilities/cssmalloc.h>
 
 /* common virtual digest class */
 #include <security_cdsa_utilities/cssmalloc.h>
 
 /* common virtual digest class */
index db747003fa0cb3dcefb7315034ba3b60afc37052..453b9e207278b883c7099e32aca4e7e360884dac 100644 (file)
@@ -32,7 +32,7 @@
 // aren't linked in everywhere.  
 //
 
 // aren't linked in everywhere.  
 //
 
-template class TypedHandle<CSSM_HANDLE>;        // HandledObject
+template struct TypedHandle<CSSM_HANDLE>;        // HandledObject
 
 template class MappingHandle<CSSM_HANDLE>;      // HandleObject
 
 
 template class MappingHandle<CSSM_HANDLE>;      // HandleObject
 
index 6644e2fdf1aaba360b9547c8a642d63e57089fe3..d28572a30269c018d006834116d4cbda9e1a8433 100644 (file)
@@ -32,6 +32,7 @@
 #include <security_utilities/threading.h>
 #include <security_utilities/globalizer.h>
 #include <security_cdsa_utilities/cssmerrors.h>
 #include <security_utilities/threading.h>
 #include <security_utilities/globalizer.h>
 #include <security_cdsa_utilities/cssmerrors.h>
+#include <vector>
 
 #if __GNUC__ > 2
 #include <ext/hash_map>
 
 #if __GNUC__ > 2
 #include <ext/hash_map>
@@ -129,7 +130,7 @@ public:
     // @@@  Remove when 4003540 is fixed
     template <class Subtype>
     static void findAllRefs(std::vector<_Handle> &refs) {
     // @@@  Remove when 4003540 is fixed
     template <class Subtype>
     static void findAllRefs(std::vector<_Handle> &refs) {
-        state().findAllRefs<Subtype>(refs);
+        state().template findAllRefs<Subtype>(refs);
     }
     
 protected:
     }
     
 protected:
index 5a6c7597ca9aa76c72301334966453ea465180e0..033704f8006075d1069ae2768231d54c7e12de24 100644 (file)
@@ -73,7 +73,7 @@ void MappingHandle<_Handle>::make()
 {
     StLock<Mutex> _(state());
     
 {
     StLock<Mutex> _(state());
     
-    _Handle hbase = reinterpret_cast<uintptr_t>(this);
+    _Handle hbase = (_Handle)reinterpret_cast<uintptr_t>(this);
     for (;;) {
         _Handle handle = hbase ^ state().nextSeq();
         if (!state().handleInUse(handle)) {
     for (;;) {
         _Handle handle = hbase ^ state().nextSeq();
         if (!state().handleInUse(handle)) {
index 3fc1d6bd6f0f99d9c1e281e5370c7a5cdb3d7579..23e0b9b791435d718a5d2b155bfa752c2acfc88f 100644 (file)
@@ -172,7 +172,9 @@ void ObjectAcl::validateOwner(AclAuthorization authorizationHint,
 
 void ObjectAcl::validateOwner(AclValidationContext &ctx)
 {
 
 void ObjectAcl::validateOwner(AclValidationContext &ctx)
 {
-       instantiateAcl();
+    instantiateAcl();
+    
+    ctx.init(this, mOwner.subject);
     if (mOwner.validate(ctx))
         return;
     CssmError::throwMe(CSSM_ERRCODE_OPERATION_AUTH_DENIED);
     if (mOwner.validate(ctx))
         return;
     CssmError::throwMe(CSSM_ERRCODE_OPERATION_AUTH_DENIED);
@@ -187,7 +189,7 @@ void ObjectAcl::exportBlob(CssmData &publicBlob, CssmData &privateBlob)
 {
        instantiateAcl();
     Writer::Counter pubSize, privSize;
 {
        instantiateAcl();
     Writer::Counter pubSize, privSize;
-       Endian<uint32> entryCount = mEntries.size();
+       Endian<uint32> entryCount = (uint32)mEntries.size();
     mOwner.exportBlob(pubSize, privSize);
        pubSize(entryCount);
     for (EntryMap::iterator it = begin(); it != end(); it++)
     mOwner.exportBlob(pubSize, privSize);
        pubSize(entryCount);
     for (EntryMap::iterator it = begin(); it != end(); it++)
@@ -260,14 +262,14 @@ unsigned int ObjectAcl::getRange(const std::string &tag,
 {
     if (!tag.empty()) {        // tag restriction in effect
         range = mEntries.equal_range(tag);
 {
     if (!tag.empty()) {        // tag restriction in effect
         range = mEntries.equal_range(tag);
-        uint32 count = mEntries.count(tag);
+        unsigned int count = (unsigned int)mEntries.count(tag);
         if (count == 0)
             CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_ENTRY_TAG);
         return count;
     } else {                           // try all tags
         range.first = mEntries.begin();
         range.second = mEntries.end();
         if (count == 0)
             CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_ENTRY_TAG);
         return count;
     } else {                           // try all tags
         range.first = mEntries.begin();
         range.second = mEntries.end();
-        return mEntries.size();
+        return (unsigned int)mEntries.size();
     }
 }
 
     }
 }
 
index f464eab97c775ac92114d39f232c8ab29d001cac..319af7923fdcd543123780a8a41c005eafe1b55a 100644 (file)
@@ -180,7 +180,7 @@ public:
             const char *s = tag.c_str(); pub(s);
             uint32 aa = authorizesAnything; pub(aa);
             if (!authorizesAnything) {
             const char *s = tag.c_str(); pub(s);
             uint32 aa = authorizesAnything; pub(aa);
             if (!authorizesAnything) {
-                Endian<uint32> count = authorizations.size(); pub(count);
+                Endian<uint32> count = (uint32)authorizations.size(); pub(count);
                 for (AclAuthorizationSet::iterator it = authorizations.begin();
                     it != authorizations.end(); it++) {
                     Endian<AclAuthorization> auth = *it; pub(auth);
                 for (AclAuthorizationSet::iterator it = authorizations.begin();
                     it != authorizations.end(); it++) {
                     Endian<AclAuthorization> auth = *it; pub(auth);
index a9616415737ef326c7e1670ac24ae5ebc9f743cf..d09e9a4149899297cb36052e18a355686871b915 100644 (file)
@@ -49,7 +49,7 @@ OSXVerifier::OSXVerifier(OSXCode *code)
        CFRef<SecStaticCodeRef> staticCode = code->codeRef();
        switch (OSStatus rc = SecCodeCopyDesignatedRequirement(staticCode,
                        kSecCSDefaultFlags, &mRequirement.aref())) {
        CFRef<SecStaticCodeRef> staticCode = code->codeRef();
        switch (OSStatus rc = SecCodeCopyDesignatedRequirement(staticCode,
                        kSecCSDefaultFlags, &mRequirement.aref())) {
-       case noErr:
+       case errSecSuccess:
                secdebug("codesign", "  is signed; canonical requirement loaded");
                break;
        case errSecCSUnsigned:
                secdebug("codesign", "  is signed; canonical requirement loaded");
                break;
        case errSecCSUnsigned:
index a431c338b78942bb9369dc156565ab947e5c8aa2..791878d8d5239d18bfb71ee8ff49d8e01c92886f 100644 (file)
@@ -53,7 +53,7 @@ public:
 
        // components
        const unsigned char *legacyHash() const { return mLegacyHash; }
 
        // components
        const unsigned char *legacyHash() const { return mLegacyHash; }
-       std::string path() const { return mPath; }
+       const std::string& path() const { return mPath; }
        SecRequirementRef requirement() const { return mRequirement; }
 
 public:
        SecRequirementRef requirement() const { return mRequirement; }
 
 public:
index 4d4baa3fbfe8dacddbceec4e8a3ad86f9192d709..2d3a897f0dedd6bc08025a5267b574ea9b04cae6 100644 (file)
@@ -141,7 +141,7 @@ public:
     {
                DEBUGWALK("reconstitute");
         if (addr)
     {
                DEBUGWALK("reconstitute");
         if (addr)
-            addr = LowLevelMemoryUtilities::increment<T>(addr, mOffset);
+            addr = LowLevelMemoryUtilities::increment<T>(addr, (ptrdiff_t)mOffset);
     }
     
        template <class T>
     }
     
        template <class T>
index df02c6ce3f1c4ccce0f482e60ef569c331f3c209..5321b9353ad0dc30d0d18cf226a7f98e2bbdb3d1 100644 (file)
@@ -56,8 +56,6 @@
                4C3895410534B31D009CF879 /* KeySchema.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C3895400534B31D009CF879 /* KeySchema.cpp */; };
                4C66D5EA05321B2700537B59 /* cssmdbname.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C66D5E805321B2700537B59 /* cssmdbname.cpp */; };
                4C838EA6058163A4006DA084 /* AuthorizationData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C838EA3058163A4006DA084 /* AuthorizationData.cpp */; };
                4C3895410534B31D009CF879 /* KeySchema.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C3895400534B31D009CF879 /* KeySchema.cpp */; };
                4C66D5EA05321B2700537B59 /* cssmdbname.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C66D5E805321B2700537B59 /* cssmdbname.cpp */; };
                4C838EA6058163A4006DA084 /* AuthorizationData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C838EA3058163A4006DA084 /* AuthorizationData.cpp */; };
-               4C838EA7058163A4006DA084 /* AuthorizationData.h in Sources */ = {isa = PBXBuildFile; fileRef = 4C838EA4058163A4006DA084 /* AuthorizationData.h */; };
-               4C838EA8058163A4006DA084 /* AuthorizationWalkers.h in Sources */ = {isa = PBXBuildFile; fileRef = 4C838EA5058163A4006DA084 /* AuthorizationWalkers.h */; };
                4C92661705349551004B0E72 /* cssmerrors.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C22EC429052B8E4900D55C69 /* cssmerrors.cpp */; };
                4C96462105378CEE00499C82 /* Schema.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C96462005378CEE00499C82 /* Schema.cpp */; };
                4CF64D26052A3278008ED0EA /* acl_any.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CF64CE0052A3278008ED0EA /* acl_any.cpp */; };
                4C92661705349551004B0E72 /* cssmerrors.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C22EC429052B8E4900D55C69 /* cssmerrors.cpp */; };
                4C96462105378CEE00499C82 /* Schema.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C96462005378CEE00499C82 /* Schema.cpp */; };
                4CF64D26052A3278008ED0EA /* acl_any.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CF64CE0052A3278008ED0EA /* acl_any.cpp */; };
                4CA2A5330523D2CD00978A7B /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
                4CA2A5330523D2CD00978A7B /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0420;
+                               LastUpgradeCheck = 0500;
                        };
                        buildConfigurationList = C27AD2FA0987FCDD001272E0 /* Build configuration list for PBXProject "libsecurity_cdsa_utilities" */;
                        compatibilityVersion = "Xcode 3.2";
                        };
                        buildConfigurationList = C27AD2FA0987FCDD001272E0 /* Build configuration list for PBXProject "libsecurity_cdsa_utilities" */;
                        compatibilityVersion = "Xcode 3.2";
                                C21A3EC40545BEFA00C40B2E /* cssmkey.cpp in Sources */,
                                C21A3EC60545BEFA00C40B2E /* cssmpods.cpp in Sources */,
                                4C838EA6058163A4006DA084 /* AuthorizationData.cpp in Sources */,
                                C21A3EC40545BEFA00C40B2E /* cssmkey.cpp in Sources */,
                                C21A3EC60545BEFA00C40B2E /* cssmpods.cpp in Sources */,
                                4C838EA6058163A4006DA084 /* AuthorizationData.cpp in Sources */,
-                               4C838EA7058163A4006DA084 /* AuthorizationData.h in Sources */,
-                               4C838EA8058163A4006DA084 /* AuthorizationWalkers.h in Sources */,
                                C2371E4006DD3E5E00E15E6F /* acl_preauth.cpp in Sources */,
                                C2BFD03406E6CDFE0047EA99 /* aclsubject.cpp in Sources */,
                                C2BFD03506E6CDFE0047EA99 /* objectacl.cpp in Sources */,
                                C2371E4006DD3E5E00E15E6F /* acl_preauth.cpp in Sources */,
                                C2BFD03406E6CDFE0047EA99 /* aclsubject.cpp in Sources */,
                                C2BFD03506E6CDFE0047EA99 /* objectacl.cpp in Sources */,
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1879B516146DD045007E536C /* debug.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1879B516146DD045007E536C /* debug.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/security_cdsa_utilities;
                                SKIP_INSTALL = NO;
                        };
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/security_cdsa_utilities;
                                SKIP_INSTALL = NO;
                        };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1879B518146DD045007E536C /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1879B518146DD045007E536C /* release.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/security_cdsa_utilities;
                                SKIP_INSTALL = NO;
                        };
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/security_cdsa_utilities;
                                SKIP_INSTALL = NO;
                        };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1879B517146DD045007E536C /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1879B517146DD045007E536C /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1879B517146DD045007E536C /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1879B517146DD045007E536C /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
index 76c899c75adc6280de784bc1bea8f6d0279c4b6a..2b3779f4279cf14295112405a81a6f45491b9ddb 100644 (file)
@@ -390,6 +390,7 @@ CSSM_DB_HANDLE cuDbStartupByName(CSSM_DL_HANDLE dlHand,
  * CSSM_CONTEXT_ATTRIBUTE to the context as specified by AttributeType,
  * AttributeLength, and an untyped pointer.
  */
  * CSSM_CONTEXT_ATTRIBUTE to the context as specified by AttributeType,
  * AttributeLength, and an untyped pointer.
  */
+static
 CSSM_RETURN cuAddContextAttribute(CSSM_CC_HANDLE CCHandle,
        uint32 AttributeType,
        uint32 AttributeLength,
 CSSM_RETURN cuAddContextAttribute(CSSM_CC_HANDLE CCHandle,
        uint32 AttributeType,
        uint32 AttributeLength,
index 494c605207989f0716aba43c9bc74ea57c0cfec9..6b26056aa44cddb3e09d0811e9ba623e059ad7dd 100644 (file)
@@ -410,7 +410,7 @@ CSSM_RETURN cuAddCrlToDb(
        }
        recordAttrs.DataRecordType = CSSM_DL_DB_RECORD_X509_CRL;
        recordAttrs.SemanticInformation = 0;
        }
        recordAttrs.DataRecordType = CSSM_DL_DB_RECORD_X509_CRL;
        recordAttrs.SemanticInformation = 0;
-       recordAttrs.NumberOfAttributes = attr - attrs;
+       recordAttrs.NumberOfAttributes = (uint32)(attr - attrs);
        recordAttrs.AttributeData = attrs;
        
        crtn = CSSM_DL_DataInsert(dlDbHand,
        recordAttrs.AttributeData = attrs;
        
        crtn = CSSM_DL_DataInsert(dlDbHand,
@@ -528,10 +528,10 @@ CSSM_RETURN cuDumpCrlsCerts(
        /* got one; print it */
        dprintf("%s %u:\n", itemStr, numItems);
        if(isCert) {
        /* got one; print it */
        dprintf("%s %u:\n", itemStr, numItems);
        if(isCert) {
-               printCert(certCrl.Data, certCrl.Length, verbose);
+               printCert(certCrl.Data, (unsigned)certCrl.Length, verbose);
        }
        else {
        }
        else {
-               printCrl(certCrl.Data, certCrl.Length, verbose);
+               printCrl(certCrl.Data, (unsigned)certCrl.Length, verbose);
        }
        CSSM_DL_FreeUniqueRecord(dlDbHand, record);
        APP_FREE(certCrl.Data);
        }
        CSSM_DL_FreeUniqueRecord(dlDbHand, record);
        APP_FREE(certCrl.Data);
@@ -550,10 +550,10 @@ CSSM_RETURN cuDumpCrlsCerts(
                        case CSSM_OK:
                                dprintf("%s %u:\n", itemStr, numItems);
                                if(isCert) {
                        case CSSM_OK:
                                dprintf("%s %u:\n", itemStr, numItems);
                                if(isCert) {
-                                       printCert(certCrl.Data, certCrl.Length, verbose);
+                                       printCert(certCrl.Data, (unsigned)certCrl.Length, verbose);
                                }
                                else {
                                }
                                else {
-                                       printCrl(certCrl.Data, certCrl.Length, verbose);
+                                       printCrl(certCrl.Data, (unsigned)certCrl.Length, verbose);
                                }
                                CSSM_DL_FreeUniqueRecord(dlDbHand, record);
                                APP_FREE(certCrl.Data);
                                }
                                CSSM_DL_FreeUniqueRecord(dlDbHand, record);
                                APP_FREE(certCrl.Data);
index 513e8b220f6f1b3dd0151d8737f96309dd23aeba..6b643d99d3b0bdc74d512bedc2acc377dc086b7a 100644 (file)
@@ -43,11 +43,11 @@ int writeFile(
        if(fd < 0) {
                return errno;
        }
        if(fd < 0) {
                return errno;
        }
-       rtn = lseek(fd, 0, SEEK_SET);
+       rtn = (int)lseek(fd, 0, SEEK_SET);
        if(rtn < 0) {
                return errno;
        }
        if(rtn < 0) {
                return errno;
        }
-       rtn = write(fd, bytes, (size_t)numBytes);
+       rtn = (int)write(fd, bytes, (size_t)numBytes);
        if(rtn != (int)numBytes) {
                if(rtn >= 0) {
                        printf("writeFile: short write\n");
        if(rtn != (int)numBytes) {
                if(rtn >= 0) {
                        printf("writeFile: short write\n");
@@ -85,17 +85,17 @@ int readFile(
        if(rtn) {
                goto errOut;
        }
        if(rtn) {
                goto errOut;
        }
-       size = sb.st_size;
+       size = (unsigned)sb.st_size;
        buf = malloc(size);
        if(buf == NULL) {
                rtn = ENOMEM;
                goto errOut;
        }
        buf = malloc(size);
        if(buf == NULL) {
                rtn = ENOMEM;
                goto errOut;
        }
-       rtn = lseek(fd, 0, SEEK_SET);
+       rtn = (int)lseek(fd, 0, SEEK_SET);
        if(rtn < 0) {
                goto errOut;
        }
        if(rtn < 0) {
                goto errOut;
        }
-       rtn = read(fd, buf, (size_t)size);
+       rtn = (int)read(fd, buf, (size_t)size);
        if(rtn != (int)size) {
                if(rtn >= 0) {
                        printf("readFile: short read\n");
        if(rtn != (int)size) {
                if(rtn >= 0) {
                        printf("readFile: short read\n");
index aa9326ce223cd5dfeca753ac31681e9f30914088..e03f1239307f36abd134b665c4ae0e0cbd863585 100644 (file)
@@ -47,6 +47,7 @@ static const char     *OID_DESCR_START = "Description = ";
 /*
  * Read entire file with extra bytes left over in the mallocd buffer. 
  */
 /*
  * Read entire file with extra bytes left over in the mallocd buffer. 
  */
+static
 int readFileExtra(
        const char              *fileName,
        unsigned                extraBytes,
 int readFileExtra(
        const char              *fileName,
        unsigned                extraBytes,
@@ -69,17 +70,17 @@ int readFileExtra(
        if(rtn) {
                goto errOut;
        }
        if(rtn) {
                goto errOut;
        }
-       size = sb.st_size;
+       size = (size_t)sb.st_size;
        buf = (unsigned char *)malloc(size + extraBytes);
        if(buf == NULL) {
                rtn = ENOMEM;
                goto errOut;
        }
        buf = (unsigned char *)malloc(size + extraBytes);
        if(buf == NULL) {
                rtn = ENOMEM;
                goto errOut;
        }
-       rtn = lseek(fd, 0, SEEK_SET);
+       rtn = (int)lseek(fd, 0, SEEK_SET);
        if(rtn < 0) {
                goto errOut;
        }
        if(rtn < 0) {
                goto errOut;
        }
-       rtn = read(fd, buf, (size_t)size);
+       rtn = (int)read(fd, buf, (size_t)size);
        if(rtn != (int)size) {
                if(rtn >= 0) {
                        printf("readFile: short read\n");
        if(rtn != (int)size) {
                if(rtn >= 0) {
                        printf("readFile: short read\n");
@@ -243,7 +244,7 @@ static CSSM_BOOL parseOidWithConfig(
        }
        
        /* caller's string buf = remainder of description line */
        }
        
        /* caller's string buf = remainder of description line */
-       len = eol - descStart;
+       len = (int)(eol - descStart);
        if(len > (OID_PARSER_STRING_SIZE - 1)) {
                /* fixed-length output buf, avoid overflow */
                len = OID_PARSER_STRING_SIZE - 1;
        if(len > (OID_PARSER_STRING_SIZE - 1)) {
                /* fixed-length output buf, avoid overflow */
                len = OID_PARSER_STRING_SIZE - 1;
index 6675ef60e20a09fecf97b09d00c0b45352f0d143..94925b74e6c87d5fef3fb3eef4d2af0a288499a1 100644 (file)
@@ -105,11 +105,11 @@ int pemEncode(
        }
                
        /* estimate outsize - just be sloppy, way conservative */
        }
                
        /* estimate outsize - just be sloppy, way conservative */
-       unsigned outSize = encLen + (2 * strlen(headerString)) + 200;
+       size_t outSize = encLen + (2 * strlen(headerString)) + 200;
        *outData = (unsigned char *)malloc(outSize);
        sprintf((char *)*outData, "-----BEGIN %s-----\n%s-----END %s-----\n",
                headerString, (char *)enc, headerString);
        *outData = (unsigned char *)malloc(outSize);
        sprintf((char *)*outData, "-----BEGIN %s-----\n%s-----END %s-----\n",
                headerString, (char *)enc, headerString);
-       *outDataLen = strlen((char *)*outData);
+       *outDataLen = (unsigned int)strlen((char *)*outData);
 
        if((*outData)[*outDataLen - 1] == '\0') {
                (*outDataLen)--;
 
        if((*outData)[*outDataLen - 1] == '\0') {
                (*outDataLen)--;
@@ -181,7 +181,7 @@ int pemDecode(
        endPem = curr1;
        /* endPem points to last PEM data plus one */
        
        endPem = curr1;
        /* endPem points to last PEM data plus one */
        
-       out = cuDec64((unsigned char *)startPem, endPem-startPem, &outLen);
+       out = cuDec64((unsigned char *)startPem, (unsigned int)(endPem-startPem), &outLen);
        if(out == NULL) {
                printf("Bad PEM format (3)\n");
                ourRtn = -1;
        if(out == NULL) {
                printf("Bad PEM format (3)\n");
                ourRtn = -1;
index 5972e4da2aff42de6b75132a90e73e4696a2e346..cf6405731a7aba423457d2000a732146d182a9d4 100644 (file)
@@ -45,7 +45,7 @@ static void printTimeStr(const CSSM_DATA *cssmTime)
        struct tm tm;
        
        /* ignore cssmTime->timeType for now */
        struct tm tm;
        
        /* ignore cssmTime->timeType for now */
-       if(cuTimeStringToTm((char *)cssmTime->Data, cssmTime->Length, &tm)) {
+       if(cuTimeStringToTm((char *)cssmTime->Data, (unsigned int)cssmTime->Length, &tm)) {
                printf("***Bad time string format***\n");
                return;
        }
                printf("***Bad time string format***\n");
                return;
        }
@@ -72,7 +72,7 @@ static void printDataAsHex(
 {
        unsigned i;
        bool more = false;
 {
        unsigned i;
        bool more = false;
-       uint32 len = d->Length;
+       uint32 len = (uint32)d->Length;
        uint8 *cp = d->Data;
        
        if((maxToPrint != 0) && (len > maxToPrint)) {
        uint8 *cp = d->Data;
        
        if((maxToPrint != 0) && (len > maxToPrint)) {
@@ -150,7 +150,7 @@ static void printOid(OidParser &parser, const CSSM_DATA *oid)
                printf("EMPTY\n");
                return;
        }
                printf("EMPTY\n");
                return;
        }
-       parser.oidParse(oid->Data, oid->Length, strBuf);
+       parser.oidParse(oid->Data, (unsigned int)oid->Length, strBuf);
        printf("%s\n", strBuf);
 }
 
        printf("%s\n", strBuf);
 }
 
@@ -229,16 +229,16 @@ static void printDerThing(
                        printString(thing);
                        return;
                case BER_TAG_OCTET_STRING:
                        printString(thing);
                        return;
                case BER_TAG_OCTET_STRING:
-                       printBlobBytes("Byte string", "bytes", thing->Length, thing);
+                       printBlobBytes("Byte string", "bytes", (uint32)thing->Length, thing);
                        return;
                case BER_TAG_BIT_STRING:
                        return;
                case BER_TAG_BIT_STRING:
-                       printBlobBytes("Bit string", "bits", (thing->Length + 7) / 8, thing);
+                       printBlobBytes("Bit string", "bits", (uint32)(thing->Length + 7) / 8, thing);
                        return;
                case BER_TAG_SEQUENCE:
                        return;
                case BER_TAG_SEQUENCE:
-                       printBlobBytes("Sequence", "bytes", thing->Length, thing);
+                       printBlobBytes("Sequence", "bytes", (uint32)thing->Length, thing);
                        return;
                case BER_TAG_SET:
                        return;
                case BER_TAG_SET:
-                       printBlobBytes("Set", "bytes", thing->Length, thing);
+                       printBlobBytes("Set", "bytes", (uint32)thing->Length, thing);
                        return;
                case BER_TAG_OID:
                        printf("OID = ");
                        return;
                case BER_TAG_OID:
                        printf("OID = ");
@@ -496,7 +496,7 @@ static void printGeneralName(
                case GNT_X400Address:
                        /* ORAddress, a very complicated struct - punt */
                        printf("   X400Address     : ");
                case GNT_X400Address:
                        /* ORAddress, a very complicated struct - punt */
                        printf("   X400Address     : ");
-                       printBlobBytes("Sequence", "bytes", name->name.Length, &name->name);
+                       printBlobBytes("Sequence", "bytes", (uint32)name->name.Length, &name->name);
                        break;
                case GNT_DirectoryName:
                        if(!name->berEncoded) {
                        break;
                case GNT_DirectoryName:
                        if(!name->berEncoded) {
@@ -514,13 +514,13 @@ static void printGeneralName(
                                /* encoded Name (i.e. CSSM_X509_NAME) */
                                printf("   Dir Name        : ");
                                printBlobBytes("Byte string", "bytes", 
                                /* encoded Name (i.e. CSSM_X509_NAME) */
                                printf("   Dir Name        : ");
                                printBlobBytes("Byte string", "bytes", 
-                                       name->name.Length, &name->name);
+                                       (uint32)name->name.Length, &name->name);
                        }
                        break;
                case GNT_EdiPartyName:
                        /* sequence EDIPartyName */
                        printf("   EdiPartyName    : ");
                        }
                        break;
                case GNT_EdiPartyName:
                        /* sequence EDIPartyName */
                        printf("   EdiPartyName    : ");
-                       printBlobBytes("Sequence", "bytes", name->name.Length, &name->name);
+                       printBlobBytes("Sequence", "bytes", (uint32)name->name.Length, &name->name);
                        break;
                case GNT_OtherName:
                {
                        break;
                case GNT_OtherName:
                {
@@ -1173,6 +1173,7 @@ void printCertField(
        }
 }
 
        }
 }
 
+static
 void printCrlExten(
        const CSSM_X509_EXTENSION *exten,
        CSSM_BOOL                       verbose,
 void printCrlExten(
        const CSSM_X509_EXTENSION *exten,
        CSSM_BOOL                       verbose,
@@ -1228,6 +1229,8 @@ void printCrlExten(
        }
 }
 
        }
 }
 
+
+static
 void printCrlEntryExten(
        const CSSM_X509_EXTENSION *exten,
        CSSM_BOOL                       verbose,
 void printCrlEntryExten(
        const CSSM_X509_EXTENSION *exten,
        CSSM_BOOL                       verbose,
@@ -1300,6 +1303,7 @@ void printCrlEntryExten(
        }
 }
 
        }
 }
 
+static
 void printCrlFields(
        const CSSM_X509_SIGNED_CRL *signedCrl,
        CSSM_BOOL                                       verbose,
 void printCrlFields(
        const CSSM_X509_SIGNED_CRL *signedCrl,
        CSSM_BOOL                                       verbose,
index 39028cac2570f4113f15ba43f68d39cd0765a45e..f99c69e0863a498a1e09a6eb7efc4e52536774f5 100644 (file)
@@ -39,7 +39,7 @@ int cuTimeStringToTm(
        char            szTemp[5];
        unsigned        isUtc = 0;
        unsigned        noSeconds = 0;
        char            szTemp[5];
        unsigned        isUtc = 0;
        unsigned        noSeconds = 0;
-       unsigned        x;
+       int             x;
        unsigned        i;
        char            *cp;
 
        unsigned        i;
        char            *cp;
 
@@ -233,7 +233,7 @@ char *cuX509TimeToCssmTimestring(
        const CSSM_X509_TIME    *x509Time,
        unsigned                                *rtnLen)                // for caller's convenience
 {
        const CSSM_X509_TIME    *x509Time,
        unsigned                                *rtnLen)                // for caller's convenience
 {
-       int len = x509Time->time.Length;
+       int len = (int)x509Time->time.Length;
        const char *inStr = (char *)x509Time->time.Data;        
                                                                                        // not NULL terminated!
        char *rtn;
        const char *inStr = (char *)x509Time->time.Data;        
                                                                                        // not NULL terminated!
        char *rtn;
index bc4c73abbfbad7652506adadbeefc0d0818d5afd..e59a3d2af95f251a2282e8f150ad89e4a66895c5 100644 (file)
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0420;
+                               LastUpgradeCheck = 0500;
                        };
                        buildConfigurationList = C27AD3080987FCDE001272E0 /* Build configuration list for PBXProject "libsecurity_cdsa_utils" */;
                        compatibilityVersion = "Xcode 3.2";
                        };
                        buildConfigurationList = C27AD3080987FCDE001272E0 /* Build configuration list for PBXProject "libsecurity_cdsa_utils" */;
                        compatibilityVersion = "Xcode 3.2";
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1879B51C146DD04F007E536C /* debug.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1879B51C146DD04F007E536C /* debug.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/security_cdsa_utils;
                                SKIP_INSTALL = NO;
                        };
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/security_cdsa_utils;
                                SKIP_INSTALL = NO;
                        };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1879B51E146DD04F007E536C /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1879B51E146DD04F007E536C /* release.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/security_cdsa_utils;
                                SKIP_INSTALL = NO;
                        };
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/security_cdsa_utils;
                                SKIP_INSTALL = NO;
                        };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1879B51D146DD04F007E536C /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1879B51D146DD04F007E536C /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1879B51D146DD04F007E536C /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1879B51D146DD04F007E536C /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
index 240964541c463f0695bc0138ca8642aeb22b8625..d72a354e9d1a524036945956374779cfe590513e 100644 (file)
@@ -1,3 +1,3 @@
 # libsecurity_checkpw: auth account
 # libsecurity_checkpw: auth account
-auth       required       pam_opendirectory.so use_first_pass
+auth       required       pam_opendirectory.so use_first_pass nullok
 account    required       pam_opendirectory.so no_check_home no_check_shell
 account    required       pam_opendirectory.so no_check_home no_check_shell
index f5207f7dcb80fc89e6102dfdd86734c454c3d512..1d1b20714846889dc8b907692d05790b9c8be3df 100644 (file)
 
 #include "checkpw.h"
 #include <syslog.h>
 
 #include "checkpw.h"
 #include <syslog.h>
+#include <unistd.h>
 
 #define PAM_STACK_NAME "checkpw"
 
 
 #define PAM_STACK_NAME "checkpw"
 
+static
 int checkpw_internal_pam( const char* uname, const char* password )
 {
        int checkpwret = CHECKPW_FAILURE;
 int checkpw_internal_pam( const char* uname, const char* password )
 {
        int checkpwret = CHECKPW_FAILURE;
@@ -76,6 +78,8 @@ pamerr_no_end:
 
 }
 
 
 }
 
+#warning TODO: this should be declared in some header.
+int checkpw_internal( const struct passwd* pw, const char* password );
 int checkpw_internal( const struct passwd* pw, const char* password )
 {
        return checkpw(pw->pw_name, password);
 int checkpw_internal( const struct passwd* pw, const char* password )
 {
        return checkpw(pw->pw_name, password);
index 28f56cc29f0270e7b0b06f61dfd191c310c8481d..bb44bf9b89d5167588bc45897a7a6c1c8aa135bf 100644 (file)
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0420;
+                               LastUpgradeCheck = 0500;
                        };
                        buildConfigurationList = C27AD3160987FCDE001272E0 /* Build configuration list for PBXProject "libsecurity_checkpw" */;
                        compatibilityVersion = "Xcode 3.2";
                        };
                        buildConfigurationList = C27AD3160987FCDE001272E0 /* Build configuration list for PBXProject "libsecurity_checkpw" */;
                        compatibilityVersion = "Xcode 3.2";
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844616C146E966100B12992 /* debug.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844616C146E966100B12992 /* debug.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844616E146E966100B12992 /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844616E146E966100B12992 /* release.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844616D146E966100B12992 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844616D146E966100B12992 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844616D146E966100B12992 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844616D146E966100B12992 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
index 93ccab3f3800bec97f4f47acc8d57708e81ee211..930c0c5ecb13c13582271dc053b15ca2f10ae9e4 100644 (file)
@@ -1,15 +1,15 @@
 /*
  * Copyright (c) 2006-2010 Apple Inc. All Rights Reserved.
 /*
  * Copyright (c) 2006-2010 Apple Inc. All Rights Reserved.
- * 
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
 /*
  * CMSDecoder.cpp - Interface for decoding CMS messages.
  */
  * @APPLE_LICENSE_HEADER_END@
  */
 
 /*
  * CMSDecoder.cpp - Interface for decoding CMS messages.
  */
+
 #include "CMSDecoder.h"
 #include "CMSPrivate.h"
 #include "CMSUtils.h"
 #include "CMSDecoder.h"
 #include "CMSPrivate.h"
 #include "CMSUtils.h"
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+#include <../libsecurity_codesigning/lib/csutilities.h>
 
 #include <Security/SecCmsDecoder.h>
 #include <Security/SecCmsEnvelopedData.h>
 
 #include <Security/SecCmsDecoder.h>
 #include <Security/SecCmsEnvelopedData.h>
@@ -57,7 +57,7 @@ typedef enum {
 } CMSDecoderState;
 
 /*
 } CMSDecoderState;
 
 /*
- * Caller's CMSDecoderRef points to one of these. 
+ * Caller's CMSDecoderRef points to one of these.
  */
 struct _CMSDecoder {
        CFRuntimeBase           base;
  */
 struct _CMSDecoder {
        CFRuntimeBase           base;
@@ -67,7 +67,7 @@ struct _CMSDecoder {
        CFDataRef                       detachedContent;
        CFTypeRef                       keychainOrArray;        /* from CMSDecoderSetSearchKeychain() */
        
        CFDataRef                       detachedContent;
        CFTypeRef                       keychainOrArray;        /* from CMSDecoderSetSearchKeychain() */
        
-       /* 
+       /*
         * The following are valid (and quiescent) after CMSDecoderFinalizeMessage().
         */
        SecCmsMessageRef        cmsMsg;
         * The following are valid (and quiescent) after CMSDecoderFinalizeMessage().
         */
        SecCmsMessageRef        cmsMsg;
@@ -82,7 +82,7 @@ struct _CMSDecoder {
 static void cmsDecoderInit(CFTypeRef dec);
 static void cmsDecoderFinalize(CFTypeRef dec);
 
 static void cmsDecoderInit(CFTypeRef dec);
 static void cmsDecoderFinalize(CFTypeRef dec);
 
-static CFRuntimeClass cmsDecoderRuntimeClass = 
+static CFRuntimeClass cmsDecoderRuntimeClass =
 {
        0,                      /* version */
        "CMSDecoder",
 {
        0,                      /* version */
        "CMSDecoder",
@@ -102,8 +102,8 @@ static CFTypeID cmsDecoderTypeID = _kCFRuntimeNotATypeID;
 /* one time only class init, called via pthread_once() in CMSDecoderGetTypeID() */
 static void cmsDecoderClassInitialize(void)
 {
 /* one time only class init, called via pthread_once() in CMSDecoderGetTypeID() */
 static void cmsDecoderClassInitialize(void)
 {
-       cmsDecoderTypeID = 
-               _CFRuntimeRegisterClass((const CFRuntimeClass * const)&cmsDecoderRuntimeClass);
+       cmsDecoderTypeID =
+    _CFRuntimeRegisterClass((const CFRuntimeClass * const)&cmsDecoderRuntimeClass);
 }
 
 /* init called out from _CFRuntimeCreateInstance() */
 }
 
 /* init called out from _CFRuntimeCreateInstance() */
@@ -117,15 +117,15 @@ static void cmsDecoderInit(CFTypeRef dec)
  * Dispose of a CMSDecoder. Called out from CFRelease().
  */
 static void cmsDecoderFinalize(
  * Dispose of a CMSDecoder. Called out from CFRelease().
  */
 static void cmsDecoderFinalize(
-       CFTypeRef               dec)
+                               CFTypeRef               dec)
 {
        CMSDecoderRef cmsDecoder = (CMSDecoderRef)dec;
        if(cmsDecoder == NULL) {
                return;
        }
        if(cmsDecoder->decoder != NULL) {
 {
        CMSDecoderRef cmsDecoder = (CMSDecoderRef)dec;
        if(cmsDecoder == NULL) {
                return;
        }
        if(cmsDecoder->decoder != NULL) {
-               /* 
-                * Normally this gets freed in SecCmsDecoderFinish - this is 
+               /*
+                * Normally this gets freed in SecCmsDecoderFinish - this is
                 * an error case.
                 * FIXME: SecCmsDecoderDestroy() appears to destroy the
                 * cmsMsg too! Plus there's a comment there re: a leak...
                 * an error case.
                 * FIXME: SecCmsDecoderDestroy() appears to destroy the
                 * cmsMsg too! Plus there's a comment there re: a leak...
@@ -144,13 +144,13 @@ static void cmsDecoderFinalize(
 
 
 /*
 
 
 /*
- * Given detached content and a valid (decoded) SignedData, digest the detached 
- * content. This occurs at the later of {CMSDecoderFinalizeMessage() finding a 
- * SignedData when already have detachedContent, or CMSDecoderSetDetachedContent() 
+ * Given detached content and a valid (decoded) SignedData, digest the detached
+ * content. This occurs at the later of {CMSDecoderFinalizeMessage() finding a
+ * SignedData when already have detachedContent, or CMSDecoderSetDetachedContent()
  * when we already have a SignedData).
  */
 static OSStatus cmsDigestDetachedContent(
  * when we already have a SignedData).
  */
 static OSStatus cmsDigestDetachedContent(
-       CMSDecoderRef cmsDecoder)
+                                         CMSDecoderRef cmsDecoder)
 {
        ASSERT((cmsDecoder->signedData != NULL) && (cmsDecoder->detachedContent != NULL));
        
 {
        ASSERT((cmsDecoder->signedData != NULL) && (cmsDecoder->detachedContent != NULL));
        
@@ -160,12 +160,12 @@ static OSStatus cmsDigestDetachedContent(
        }
        SecCmsDigestContextRef digcx = SecCmsDigestContextStartMultiple(digestAlgorithms);
        if(digcx == NULL) {
        }
        SecCmsDigestContextRef digcx = SecCmsDigestContextStartMultiple(digestAlgorithms);
        if(digcx == NULL) {
-               return memFullErr;
+               return errSecAllocate;
        }
        CSSM_DATA **digests = NULL;
        
        }
        CSSM_DATA **digests = NULL;
        
-       SecCmsDigestContextUpdate(digcx, CFDataGetBytePtr(cmsDecoder->detachedContent), 
-               CFDataGetLength(cmsDecoder->detachedContent));
+       SecCmsDigestContextUpdate(digcx, CFDataGetBytePtr(cmsDecoder->detachedContent),
+                              CFDataGetLength(cmsDecoder->detachedContent));
        /* note this frees the digest content regardless */
        OSStatus ortn = SecCmsDigestContextFinishMultiple(digcx, cmsDecoder->arena, &digests);
        if(ortn) {
        /* note this frees the digest content regardless */
        OSStatus ortn = SecCmsDigestContextFinishMultiple(digcx, cmsDecoder->arena, &digests);
        if(ortn) {
@@ -197,32 +197,32 @@ CFTypeID CMSDecoderGetTypeID(void)
  * Create a CMSDecoder. Result must eventually be freed via CFRelease().
  */
 OSStatus CMSDecoderCreate(
  * Create a CMSDecoder. Result must eventually be freed via CFRelease().
  */
 OSStatus CMSDecoderCreate(
-       CMSDecoderRef           *cmsDecoderOut) /* RETURNED */
+                          CMSDecoderRef                *cmsDecoderOut) /* RETURNED */
 {
        CMSDecoderRef cmsDecoder = NULL;
 {
        CMSDecoderRef cmsDecoder = NULL;
-
+    
        uint32_t extra = sizeof(*cmsDecoder) - sizeof(cmsDecoder->base);
        cmsDecoder = (CMSDecoderRef)_CFRuntimeCreateInstance(NULL, CMSDecoderGetTypeID(),
        uint32_t extra = sizeof(*cmsDecoder) - sizeof(cmsDecoder->base);
        cmsDecoder = (CMSDecoderRef)_CFRuntimeCreateInstance(NULL, CMSDecoderGetTypeID(),
-               extra, NULL);
+                                                         extra, NULL);
        if(cmsDecoder == NULL) {
        if(cmsDecoder == NULL) {
-               return memFullErr;
+               return errSecAllocate;
        }
        cmsDecoder->decState = DS_Init;
        *cmsDecoderOut = cmsDecoder;
        }
        cmsDecoder->decState = DS_Init;
        *cmsDecoderOut = cmsDecoder;
-       return noErr;
+       return errSecSuccess;
 }
 
 }
 
-/* 
+/*
  * Feed raw bytes of the message to be decoded into the decoder. Can be called
  * Feed raw bytes of the message to be decoded into the decoder. Can be called
- * multiple times. 
+ * multiple times.
  */
 OSStatus CMSDecoderUpdateMessage(
  */
 OSStatus CMSDecoderUpdateMessage(
-       CMSDecoderRef           cmsDecoder,
-       const void                      *msgBytes,
-       size_t                          msgBytesLen)
+                                 CMSDecoderRef         cmsDecoder,
+                                 const void                    *msgBytes,
+                                 size_t                                msgBytesLen)
 {
        if(cmsDecoder == NULL) {
 {
        if(cmsDecoder == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        
        OSStatus ortn;
        }
        
        OSStatus ortn;
@@ -235,8 +235,8 @@ OSStatus CMSDecoderUpdateMessage(
                        if(ortn) {
                                return cmsRtnToOSStatus(ortn);
                        }
                        if(ortn) {
                                return cmsRtnToOSStatus(ortn);
                        }
-                       ortn = SecCmsDecoderCreate(cmsDecoder->arena, 
-                               NULL, NULL, NULL, NULL, NULL, NULL, &cmsDecoder->decoder);
+                       ortn = SecCmsDecoderCreate(cmsDecoder->arena,
+                                       NULL, NULL, NULL, NULL, NULL, NULL, &cmsDecoder->decoder);
                        if(ortn) {
                                ortn = cmsRtnToOSStatus(ortn);
                                CSSM_PERROR("SecCmsDecoderCreate", ortn);
                        if(ortn) {
                                ortn = cmsRtnToOSStatus(ortn);
                                CSSM_PERROR("SecCmsDecoderCreate", ortn);
@@ -244,18 +244,18 @@ OSStatus CMSDecoderUpdateMessage(
                        }
                        cmsDecoder->decState = DS_Updating;
                        break;
                        }
                        cmsDecoder->decState = DS_Updating;
                        break;
-               
+            
                case DS_Updating:
                        ASSERT(cmsDecoder->decoder != NULL);
                        break;
                        
                case DS_Final:
                        /* Too late for another update */
                case DS_Updating:
                        ASSERT(cmsDecoder->decoder != NULL);
                        break;
                        
                case DS_Final:
                        /* Too late for another update */
-                       return paramErr;
+                       return errSecParam;
                        
                default:
                        dprintf("CMSDecoderUpdateMessage: bad decState\n");
                        
                default:
                        dprintf("CMSDecoderUpdateMessage: bad decState\n");
-                       return internalComponentErr;
+                       return errSecInternalComponent;
        }
        
        /* FIXME - CFIndex same size as size_t on 64bit? */
        }
        
        /* FIXME - CFIndex same size as size_t on 64bit? */
@@ -266,20 +266,20 @@ OSStatus CMSDecoderUpdateMessage(
        }
        return ortn;
 }
        }
        return ortn;
 }
-       
-/* 
+
+/*
  * Indicate that no more CMSDecoderUpdateMessage() calls are forthcoming;
  * Indicate that no more CMSDecoderUpdateMessage() calls are forthcoming;
- * finish decoding the message. We parse the message as best we can, up to 
- * but not including verifying individual signerInfos. 
+ * finish decoding the message. We parse the message as best we can, up to
+ * but not including verifying individual signerInfos.
  */
 OSStatus CMSDecoderFinalizeMessage(
  */
 OSStatus CMSDecoderFinalizeMessage(
-       CMSDecoderRef           cmsDecoder)
+                                   CMSDecoderRef               cmsDecoder)
 {
        if(cmsDecoder == NULL) {
 {
        if(cmsDecoder == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsDecoder->decState != DS_Updating) {
        }
        if(cmsDecoder->decState != DS_Updating) {
-               return paramErr;
+               return errSecParam;
        }
        ASSERT(cmsDecoder->decoder != NULL);
        OSStatus ortn = SecCmsDecoderFinish(cmsDecoder->decoder, &cmsDecoder->cmsMsg);
        }
        ASSERT(cmsDecoder->decoder != NULL);
        OSStatus ortn = SecCmsDecoderFinish(cmsDecoder->decoder, &cmsDecoder->cmsMsg);
@@ -305,8 +305,8 @@ OSStatus CMSDecoderFinalizeMessage(
                SECOidTag tag = SecCmsContentInfoGetContentTypeTag(ci);
                switch(tag) {
                        case SEC_OID_PKCS7_SIGNED_DATA:
                SECOidTag tag = SecCmsContentInfoGetContentTypeTag(ci);
                switch(tag) {
                        case SEC_OID_PKCS7_SIGNED_DATA:
-                               cmsDecoder->signedData = 
-                                       (SecCmsSignedDataRef)SecCmsContentInfoGetContent(ci);
+                               cmsDecoder->signedData =
+                (SecCmsSignedDataRef)SecCmsContentInfoGetContent(ci);
                                /* dig down one more layer for eContentType */
                                ci = SecCmsSignedDataGetContentInfo(cmsDecoder->signedData);
                                cmsDecoder->eContentType = SecCmsContentInfoGetContentTypeOID(ci);
                                /* dig down one more layer for eContentType */
                                ci = SecCmsSignedDataGetContentInfo(cmsDecoder->signedData);
                                cmsDecoder->eContentType = SecCmsContentInfoGetContentTypeOID(ci);
@@ -317,13 +317,13 @@ OSStatus CMSDecoderFinalizeMessage(
                if(cmsDecoder->signedData != NULL) {
                        break;
                }
                if(cmsDecoder->signedData != NULL) {
                        break;
                }
-                                       
+        
        }
        
        /* minimal processing of optional signedData... */
        if(cmsDecoder->signedData != NULL) {
                cmsDecoder->numSigners = (size_t)
        }
        
        /* minimal processing of optional signedData... */
        if(cmsDecoder->signedData != NULL) {
                cmsDecoder->numSigners = (size_t)
-                       SecCmsSignedDataSignerInfoCount(cmsDecoder->signedData);
+        SecCmsSignedDataSignerInfoCount(cmsDecoder->signedData);
                if(cmsDecoder->detachedContent != NULL) {
                        /* time to calculate digests from detached content */
                        ortn = cmsDigestDetachedContent(cmsDecoder);
                if(cmsDecoder->detachedContent != NULL) {
                        /* time to calculate digests from detached content */
                        ortn = cmsDigestDetachedContent(cmsDecoder);
@@ -335,20 +335,20 @@ OSStatus CMSDecoderFinalizeMessage(
 /*
  * A signed CMS message optionally includes the data which was signed. If the
  * message does not include the signed data, caller specifies the signed data
 /*
  * A signed CMS message optionally includes the data which was signed. If the
  * message does not include the signed data, caller specifies the signed data
- * (the "detached content") here. 
+ * (the "detached content") here.
  *
  * This can be called either before or after the actual decoding of the message
  * (via CMSDecoderUpdateMessage() and CMSDecoderFinalizeMessage()); the only
  *
  * This can be called either before or after the actual decoding of the message
  * (via CMSDecoderUpdateMessage() and CMSDecoderFinalizeMessage()); the only
- * restriction is that, if detached content is required, this function must 
- * be called befoere successfully ascertaining the signature status via 
+ * restriction is that, if detached content is required, this function must
+ * be called befoere successfully ascertaining the signature status via
  * CMSDecoderCopySignerStatus().
  */
 OSStatus CMSDecoderSetDetachedContent(
  * CMSDecoderCopySignerStatus().
  */
 OSStatus CMSDecoderSetDetachedContent(
-       CMSDecoderRef           cmsDecoder,
-       CFDataRef                       detachedContent)
+                                      CMSDecoderRef            cmsDecoder,
+                                      CFDataRef                        detachedContent)
 {
        if((cmsDecoder == NULL) || (detachedContent == NULL)) {
 {
        if((cmsDecoder == NULL) || (detachedContent == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        cmsDecoder->detachedContent = detachedContent;
        CFRetain(detachedContent);
        }
        cmsDecoder->detachedContent = detachedContent;
        CFRetain(detachedContent);
@@ -358,84 +358,84 @@ OSStatus CMSDecoderSetDetachedContent(
                ASSERT(cmsDecoder->decState == DS_Final);
                return cmsDigestDetachedContent(cmsDecoder);
        }
                ASSERT(cmsDecoder->decState == DS_Final);
                return cmsDigestDetachedContent(cmsDecoder);
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
  * Obtain the detached content specified in CMSDecoderSetDetachedContent().
 }
 
 /*
  * Obtain the detached content specified in CMSDecoderSetDetachedContent().
- * Returns a NULL detachedContent if no detached content has been specified. 
+ * Returns a NULL detachedContent if no detached content has been specified.
  * Caller must CFRelease() the result.
  */
 OSStatus CMSDecoderCopyDetachedContent(
  * Caller must CFRelease() the result.
  */
 OSStatus CMSDecoderCopyDetachedContent(
-       CMSDecoderRef           cmsDecoder,
-       CFDataRef                       *detachedContent)               /* RETURNED */
+                                       CMSDecoderRef           cmsDecoder,
+                                       CFDataRef                       *detachedContent)               /* RETURNED */
 {
        if((cmsDecoder == NULL) || (detachedContent == NULL)) {
 {
        if((cmsDecoder == NULL) || (detachedContent == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsDecoder->detachedContent != NULL) {
                CFRetain(cmsDecoder->detachedContent);
        }
        *detachedContent = cmsDecoder->detachedContent;
        }
        if(cmsDecoder->detachedContent != NULL) {
                CFRetain(cmsDecoder->detachedContent);
        }
        *detachedContent = cmsDecoder->detachedContent;
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
  * Optionally specify a SecKeychainRef, or an array of them, containing
  * intermediate certs to be used in verifying a signed message's signer
 }
 
 /*
  * Optionally specify a SecKeychainRef, or an array of them, containing
  * intermediate certs to be used in verifying a signed message's signer
- * certs. By default, the default keychain search list is used for this. 
+ * certs. By default, the default keychain search list is used for this.
  * Specify an empty CFArrayRef to search *no* keychains for intermediate
  * Specify an empty CFArrayRef to search *no* keychains for intermediate
- * certs. 
+ * certs.
  * IF this is called, it must be called before CMSDecoderCopySignerStatus().
  */
 OSStatus CMSDecoderSetSearchKeychain(
  * IF this is called, it must be called before CMSDecoderCopySignerStatus().
  */
 OSStatus CMSDecoderSetSearchKeychain(
-       CMSDecoderRef           cmsDecoder,
-       CFTypeRef                       keychainOrArray)
+                                     CMSDecoderRef             cmsDecoder,
+                                     CFTypeRef                 keychainOrArray)
 {
        if(cmsDecoder == NULL) {
 {
        if(cmsDecoder == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        cmsDecoder->keychainOrArray = keychainOrArray;
        if(keychainOrArray) {
                CFRetain(keychainOrArray);
        }
        }
        cmsDecoder->keychainOrArray = keychainOrArray;
        if(keychainOrArray) {
                CFRetain(keychainOrArray);
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
  * Obtain the number of signers of a message. A result of zero indicates that
 }
 
 /*
  * Obtain the number of signers of a message. A result of zero indicates that
- * the message was not signed. 
+ * the message was not signed.
  */
 OSStatus CMSDecoderGetNumSigners(
  */
 OSStatus CMSDecoderGetNumSigners(
-       CMSDecoderRef           cmsDecoder,
-       size_t                          *numSigners)                    /* RETURNED */
+                                 CMSDecoderRef         cmsDecoder,
+                                 size_t                                *numSigners)                    /* RETURNED */
 {
        if((cmsDecoder == NULL) || (numSigners == NULL)) {
 {
        if((cmsDecoder == NULL) || (numSigners == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsDecoder->decState != DS_Final) {
        }
        if(cmsDecoder->decState != DS_Final) {
-               return paramErr;
+               return errSecParam;
        }
        *numSigners = cmsDecoder->numSigners;
        }
        *numSigners = cmsDecoder->numSigners;
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
- * Obtain the status of a CMS message's signature. A CMS message can 
+ * Obtain the status of a CMS message's signature. A CMS message can
  * be signed my multiple signers; this function returns the status
  * be signed my multiple signers; this function returns the status
- * associated with signer 'n' as indicated by the signerIndex parameter. 
+ * associated with signer 'n' as indicated by the signerIndex parameter.
  */
 OSStatus CMSDecoderCopySignerStatus(
  */
 OSStatus CMSDecoderCopySignerStatus(
-       CMSDecoderRef           cmsDecoder,
-       size_t                          signerIndex,
-       CFTypeRef                       policyOrArray,
-       Boolean                         evaluateSecTrust,
-       CMSSignerStatus         *signerStatus,                  /* optional; RETURNED */
-       SecTrustRef                     *secTrust,                              /* optional; RETURNED */
-       OSStatus                        *certVerifyResultCode)  /* optional; RETURNED */
+                                    CMSDecoderRef              cmsDecoder,
+                                    size_t                             signerIndex,
+                                    CFTypeRef                  policyOrArray,
+                                    Boolean                            evaluateSecTrust,
+                                    CMSSignerStatus            *signerStatus,                  /* optional; RETURNED */
+                                    SecTrustRef                        *secTrust,                              /* optional; RETURNED */
+                                    OSStatus                   *certVerifyResultCode)  /* optional; RETURNED */
 {
        if((cmsDecoder == NULL) || (cmsDecoder->decState != DS_Final)) {
 {
        if((cmsDecoder == NULL) || (cmsDecoder->decState != DS_Final)) {
-               return paramErr;
+               return errSecParam;
        }
        
        /* initialize return values */
        }
        
        /* initialize return values */
@@ -451,45 +451,45 @@ OSStatus CMSDecoderCopySignerStatus(
        
        if(cmsDecoder->signedData == NULL) {
                *signerStatus = kCMSSignerUnsigned;     /* redundant, I know, but explicit */
        
        if(cmsDecoder->signedData == NULL) {
                *signerStatus = kCMSSignerUnsigned;     /* redundant, I know, but explicit */
-               return noErr;
+               return errSecSuccess;
        }
        ASSERT(cmsDecoder->numSigners > 0);
        if(signerIndex >= cmsDecoder->numSigners) {
                *signerStatus = kCMSSignerInvalidIndex;
        }
        ASSERT(cmsDecoder->numSigners > 0);
        if(signerIndex >= cmsDecoder->numSigners) {
                *signerStatus = kCMSSignerInvalidIndex;
-               return noErr;
+               return errSecSuccess;
        }
        if(!SecCmsSignedDataHasDigests(cmsDecoder->signedData)) {
        }
        if(!SecCmsSignedDataHasDigests(cmsDecoder->signedData)) {
-               *signerStatus = kCMSSignerNeedsDetachedContent; 
-               return noErr;
+               *signerStatus = kCMSSignerNeedsDetachedContent;
+               return errSecSuccess;
        }
        
        /*
         * OK, we should be able to verify this signerInfo.
        }
        
        /*
         * OK, we should be able to verify this signerInfo.
-        * I think we have to do the SecCmsSignedDataVerifySignerInfo first 
-        * in order get all the cert pieces into place before returning them 
-        * to the caller. 
+        * I think we have to do the SecCmsSignedDataVerifySignerInfo first
+        * in order get all the cert pieces into place before returning them
+        * to the caller.
         */
        SecTrustRef theTrust = NULL;
         */
        SecTrustRef theTrust = NULL;
-       OSStatus vfyRtn = SecCmsSignedDataVerifySignerInfo(cmsDecoder->signedData, 
-               signerIndex, 
-               /* 
-                * FIXME this cast should not be necessary, but libsecurity_smime 
-                * declares this argument as a SecKeychainRef
-                */
-               (SecKeychainRef)cmsDecoder->keychainOrArray,
-               policyOrArray, 
-               &theTrust);
-        /* Subsequent errors to errOut: */
-        
+       OSStatus vfyRtn = SecCmsSignedDataVerifySignerInfo(cmsDecoder->signedData,
+                                                       (int)signerIndex,
+                                                       /*
+                                                        * FIXME this cast should not be necessary, but libsecurity_smime
+                                                        * declares this argument as a SecKeychainRef
+                                                        */
+                                                       (SecKeychainRef)cmsDecoder->keychainOrArray,
+                                                       policyOrArray,
+                                                       &theTrust);
+    /* Subsequent errors to errOut: */
+    
        /*
        /*
-        * NOTE the smime lib did NOT evaluate that SecTrust - it only does 
+        * NOTE the smime lib did NOT evaluate that SecTrust - it only does
         * SecTrustEvaluate() if we don't ask for a copy.
         * SecTrustEvaluate() if we don't ask for a copy.
-        * 
+        *
         * FIXME deal with multitudes of status returns here...for now, proceed with
         * obtaining components the caller wants and assume that a nonzero vfyRtn
         * FIXME deal with multitudes of status returns here...for now, proceed with
         * obtaining components the caller wants and assume that a nonzero vfyRtn
-        * means "bad signature". 
+        * means "bad signature".
         */
         */
-       OSStatus ortn = noErr;
+       OSStatus ortn = errSecSuccess;
        SecTrustResultType secTrustResult;
        CSSM_RETURN tpVfyStatus = CSSM_OK;
        OSStatus evalRtn;
        SecTrustResultType secTrustResult;
        CSSM_RETURN tpVfyStatus = CSSM_OK;
        OSStatus evalRtn;
@@ -500,16 +500,16 @@ OSStatus CMSDecoderCopySignerStatus(
                if (theTrust)
                        CFRetain(theTrust);
        }
                if (theTrust)
                        CFRetain(theTrust);
        }
-       SecCmsSignerInfoRef signerInfo = 
-               SecCmsSignedDataGetSignerInfo(cmsDecoder->signedData, signerIndex);
+       SecCmsSignerInfoRef signerInfo =
+    SecCmsSignedDataGetSignerInfo(cmsDecoder->signedData, (int)signerIndex);
        if(signerInfo == NULL) {
                /* should never happen */
                ASSERT(0);
                dprintf("CMSDecoderCopySignerStatus: no signerInfo\n");
        if(signerInfo == NULL) {
                /* should never happen */
                ASSERT(0);
                dprintf("CMSDecoderCopySignerStatus: no signerInfo\n");
-               ortn = internalComponentErr;
+               ortn = errSecInternalComponent;
                goto errOut;
        }
                goto errOut;
        }
-
+    
        /* now do the actual cert verify */
        if(evaluateSecTrust) {
                evalRtn = SecTrustEvaluate(theTrust, &secTrustResult);
        /* now do the actual cert verify */
        if(evaluateSecTrust) {
                evalRtn = SecTrustEvaluate(theTrust, &secTrustResult);
@@ -517,7 +517,7 @@ OSStatus CMSDecoderCopySignerStatus(
                        /* should never happen */
                        CSSM_PERROR("SecTrustEvaluate", evalRtn);
                        dprintf("CMSDecoderCopySignerStatus: SecTrustEvaluate error\n");
                        /* should never happen */
                        CSSM_PERROR("SecTrustEvaluate", evalRtn);
                        dprintf("CMSDecoderCopySignerStatus: SecTrustEvaluate error\n");
-                       ortn = internalComponentErr;
+                       ortn = errSecInternalComponent;
                        goto errOut;
                }
                switch(secTrustResult) {
                        goto errOut;
                }
                switch(secTrustResult) {
@@ -555,10 +555,10 @@ OSStatus CMSDecoderCopySignerStatus(
        
        /* cook up global status based on vfyRtn and tpVfyStatus */
        if(signerStatus != NULL) {
        
        /* cook up global status based on vfyRtn and tpVfyStatus */
        if(signerStatus != NULL) {
-               if((vfyRtn == noErr) && (tpVfyStatus == CSSM_OK))  {
+               if((vfyRtn == errSecSuccess) && (tpVfyStatus == CSSM_OK))  {
                        *signerStatus = kCMSSignerValid;
                }
                        *signerStatus = kCMSSignerValid;
                }
-               else if(vfyRtn != noErr) {
+               else if(vfyRtn != errSecSuccess) {
                        /* this could mean other things, but for now... */
                        *signerStatus = kCMSSignerInvalidSignature;
                }
                        /* this could mean other things, but for now... */
                        *signerStatus = kCMSSignerInvalidSignature;
                }
@@ -573,65 +573,65 @@ errOut:
 
 /*
  * Obtain the email address of signer 'signerIndex' of a CMS message, if
 
 /*
  * Obtain the email address of signer 'signerIndex' of a CMS message, if
- * present. 
+ * present.
  *
  *
- * This cannot be called until after CMSDecoderFinalizeMessage() is called. 
+ * This cannot be called until after CMSDecoderFinalizeMessage() is called.
  */
 OSStatus CMSDecoderCopySignerEmailAddress(
  */
 OSStatus CMSDecoderCopySignerEmailAddress(
-       CMSDecoderRef           cmsDecoder,
-       size_t                          signerIndex,
-       CFStringRef                     *signerEmailAddress)    /* RETURNED */
+                                          CMSDecoderRef                cmsDecoder,
+                                          size_t                               signerIndex,
+                                          CFStringRef                  *signerEmailAddress)    /* RETURNED */
 {
 {
-       if((cmsDecoder == NULL) || 
+       if((cmsDecoder == NULL) ||
           (signerEmailAddress == NULL) ||
           (cmsDecoder->signedData == NULL) ||                  /* not signed */
           (signerIndex >= cmsDecoder->numSigners) ||   /* index out of range */
           (cmsDecoder->decState != DS_Final)) {
           (signerEmailAddress == NULL) ||
           (cmsDecoder->signedData == NULL) ||                  /* not signed */
           (signerIndex >= cmsDecoder->numSigners) ||   /* index out of range */
           (cmsDecoder->decState != DS_Final)) {
-               return paramErr;
+               return errSecParam;
        }
        
        }
        
-       SecCmsSignerInfoRef signerInfo = 
-               SecCmsSignedDataGetSignerInfo(cmsDecoder->signedData, signerIndex);
+       SecCmsSignerInfoRef signerInfo =
+    SecCmsSignedDataGetSignerInfo(cmsDecoder->signedData, (int)signerIndex);
        if(signerInfo == NULL) {
                /* should never happen */
                ASSERT(0);
                dprintf("CMSDecoderCopySignerEmailAddress: no signerInfo\n");
        if(signerInfo == NULL) {
                /* should never happen */
                ASSERT(0);
                dprintf("CMSDecoderCopySignerEmailAddress: no signerInfo\n");
-               return internalComponentErr;
+               return errSecInternalComponent;
        }
        
        }
        
-       /* 
-        * This is leaking memory in libsecurityKeychain per Radar 4412699. 
+       /*
+        * This is leaking memory in libsecurityKeychain per Radar 4412699.
         */
        *signerEmailAddress = SecCmsSignerInfoGetSignerEmailAddress(signerInfo);
         */
        *signerEmailAddress = SecCmsSignerInfoGetSignerEmailAddress(signerInfo);
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
  * Obtain the certificate of signer 'signerIndex' of a CMS message, if
 }
 
 /*
  * Obtain the certificate of signer 'signerIndex' of a CMS message, if
- * present. 
+ * present.
  *
  *
- * This cannot be called until after CMSDecoderFinalizeMessage() is called. 
+ * This cannot be called until after CMSDecoderFinalizeMessage() is called.
  */
 OSStatus CMSDecoderCopySignerCert(
  */
 OSStatus CMSDecoderCopySignerCert(
-       CMSDecoderRef           cmsDecoder,
-       size_t                          signerIndex,
-       SecCertificateRef       *signerCert)                    /* RETURNED */
+                                  CMSDecoderRef                cmsDecoder,
+                                  size_t                               signerIndex,
+                                  SecCertificateRef    *signerCert)                    /* RETURNED */
 {
 {
-       if((cmsDecoder == NULL) || 
+       if((cmsDecoder == NULL) ||
           (signerCert == NULL) ||
           (cmsDecoder->signedData == NULL) ||                  /* not signed */
           (signerIndex >= cmsDecoder->numSigners) ||   /* index out of range */
           (cmsDecoder->decState != DS_Final)) {
           (signerCert == NULL) ||
           (cmsDecoder->signedData == NULL) ||                  /* not signed */
           (signerIndex >= cmsDecoder->numSigners) ||   /* index out of range */
           (cmsDecoder->decState != DS_Final)) {
-               return paramErr;
+               return errSecParam;
        }
        }
-
-       SecCmsSignerInfoRef signerInfo = 
-               SecCmsSignedDataGetSignerInfo(cmsDecoder->signedData, signerIndex);
+    
+       SecCmsSignerInfoRef signerInfo =
+    SecCmsSignedDataGetSignerInfo(cmsDecoder->signedData, (int)signerIndex);
        if(signerInfo == NULL) {
                /* should never happen */
                ASSERT(0);
                dprintf("CMSDecoderCopySignerCertificate: no signerInfo\n");
        if(signerInfo == NULL) {
                /* should never happen */
                ASSERT(0);
                dprintf("CMSDecoderCopySignerCertificate: no signerInfo\n");
-               return internalComponentErr;
+               return errSecInternalComponent;
        }
        *signerCert = SecCmsSignerInfoGetSigningCertificate(signerInfo, NULL);
        /* libsecurity_smime does NOT retain that */
        }
        *signerCert = SecCmsSignerInfoGetSigningCertificate(signerInfo, NULL);
        /* libsecurity_smime does NOT retain that */
@@ -639,43 +639,43 @@ OSStatus CMSDecoderCopySignerCert(
                /* should never happen */
                ASSERT(0);
                dprintf("CMSDecoderCopySignerCertificate: no signerCert\n");
                /* should never happen */
                ASSERT(0);
                dprintf("CMSDecoderCopySignerCertificate: no signerCert\n");
-               return internalComponentErr;
+               return errSecInternalComponent;
        }
        CFRetain(*signerCert);
        }
        CFRetain(*signerCert);
-       return noErr;
+       return errSecSuccess;
 }
 
 }
 
-/* 
+/*
  * Determine whether a CMS message was encrypted, and if so, whether we were
  * Determine whether a CMS message was encrypted, and if so, whether we were
- * able to decrypt it. 
+ * able to decrypt it.
  */
 OSStatus CMSDecoderIsContentEncrypted(
  */
 OSStatus CMSDecoderIsContentEncrypted(
-       CMSDecoderRef   cmsDecoder,
-       Boolean                 *wasEncrypted)
+                                      CMSDecoderRef    cmsDecoder,
+                                      Boolean                  *wasEncrypted)
 {
        if((cmsDecoder == NULL) || (wasEncrypted == NULL)) {
 {
        if((cmsDecoder == NULL) || (wasEncrypted == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsDecoder->decState != DS_Final) {
        }
        if(cmsDecoder->decState != DS_Final) {
-               return paramErr;
+               return errSecParam;
        }
        *wasEncrypted = cmsDecoder->wasEncrypted;
        }
        *wasEncrypted = cmsDecoder->wasEncrypted;
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
- * Obtain the eContentType OID for a SignedData's EncapsulatedContentType, if 
+ * Obtain the eContentType OID for a SignedData's EncapsulatedContentType, if
  * present.
  */
 OSStatus CMSDecoderCopyEncapsulatedContentType(
  * present.
  */
 OSStatus CMSDecoderCopyEncapsulatedContentType(
-       CMSDecoderRef           cmsDecoder,
-       CFDataRef                       *eContentType)          /* RETURNED */
+                                               CMSDecoderRef           cmsDecoder,
+                                               CFDataRef                       *eContentType)          /* RETURNED */
 {
        if((cmsDecoder == NULL) || (eContentType == NULL)) {
 {
        if((cmsDecoder == NULL) || (eContentType == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsDecoder->decState != DS_Final) {
        }
        if(cmsDecoder->decState != DS_Final) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsDecoder->signedData == NULL) {
                *eContentType = NULL;
        }
        if(cmsDecoder->signedData == NULL) {
                *eContentType = NULL;
@@ -684,36 +684,36 @@ OSStatus CMSDecoderCopyEncapsulatedContentType(
                CSSM_OID *ecOid = cmsDecoder->eContentType;
                *eContentType = CFDataCreate(NULL, ecOid->Data, ecOid->Length);
        }
                CSSM_OID *ecOid = cmsDecoder->eContentType;
                *eContentType = CFDataCreate(NULL, ecOid->Data, ecOid->Length);
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
- * Obtain an array of all of the certificates in a message. Elements of the 
- * returned array are SecCertificateRefs. The caller must CFRelease the returned 
+ * Obtain an array of all of the certificates in a message. Elements of the
+ * returned array are SecCertificateRefs. The caller must CFRelease the returned
  * array.
  * array.
- * This cannot be called until after CMSDecoderFinalizeMessage() is called. 
+ * This cannot be called until after CMSDecoderFinalizeMessage() is called.
  */
 OSStatus CMSDecoderCopyAllCerts(
  */
 OSStatus CMSDecoderCopyAllCerts(
-       CMSDecoderRef           cmsDecoder,
-       CFArrayRef                      *certs)                                 /* RETURNED */
+                                CMSDecoderRef          cmsDecoder,
+                                CFArrayRef                     *certs)                                 /* RETURNED */
 {
        if((cmsDecoder == NULL) || (certs == NULL)) {
 {
        if((cmsDecoder == NULL) || (certs == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsDecoder->decState != DS_Final) {
        }
        if(cmsDecoder->decState != DS_Final) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsDecoder->signedData == NULL) {
                /* message wasn't signed */
                *certs = NULL;
        }
        if(cmsDecoder->signedData == NULL) {
                /* message wasn't signed */
                *certs = NULL;
-               return noErr;
+               return errSecSuccess;
        }
        
        /* NULL_terminated array of CSSM_DATA ptrs */
        CSSM_DATA_PTR *cssmCerts = SecCmsSignedDataGetCertificateList(cmsDecoder->signedData);
        if((cssmCerts == NULL) || (*cssmCerts == NULL)) {
                *certs = NULL;
        }
        
        /* NULL_terminated array of CSSM_DATA ptrs */
        CSSM_DATA_PTR *cssmCerts = SecCmsSignedDataGetCertificateList(cmsDecoder->signedData);
        if((cssmCerts == NULL) || (*cssmCerts == NULL)) {
                *certs = NULL;
-               return noErr;
+               return errSecSuccess;
        }
        
        CFMutableArrayRef allCerts = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
        }
        
        CFMutableArrayRef allCerts = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
@@ -721,9 +721,9 @@ OSStatus CMSDecoderCopyAllCerts(
        for(cssmCert=cssmCerts; *cssmCert!=NULL; cssmCert++) {
                OSStatus ortn;
                SecCertificateRef cfCert;
        for(cssmCert=cssmCerts; *cssmCert!=NULL; cssmCert++) {
                OSStatus ortn;
                SecCertificateRef cfCert;
-               ortn = SecCertificateCreateFromData(*cssmCert, 
-                       CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER,
-                       &cfCert);
+               ortn = SecCertificateCreateFromData(*cssmCert,
+                                            CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER,
+                                            &cfCert);
                if(ortn) {
                        CFRelease(allCerts);
                        return ortn;
                if(ortn) {
                        CFRelease(allCerts);
                        return ortn;
@@ -733,104 +733,104 @@ OSStatus CMSDecoderCopyAllCerts(
                CFRelease(cfCert);
        }
        *certs = allCerts;
                CFRelease(cfCert);
        }
        *certs = allCerts;
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
  * Obtain the actual message content (payload), if any. If the message was
  * signed with detached content this will return NULL.
 }
 
 /*
  * Obtain the actual message content (payload), if any. If the message was
  * signed with detached content this will return NULL.
- * Caller must CFRelease the result. 
+ * Caller must CFRelease the result.
  */
 OSStatus CMSDecoderCopyContent(
  */
 OSStatus CMSDecoderCopyContent(
-       CMSDecoderRef           cmsDecoder,
-       CFDataRef                       *content)                               /* RETURNED */
+                               CMSDecoderRef           cmsDecoder,
+                               CFDataRef                       *content)                               /* RETURNED */
 {
        if((cmsDecoder == NULL) || (content == NULL)) {
 {
        if((cmsDecoder == NULL) || (content == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsDecoder->decState != DS_Final) {
        }
        if(cmsDecoder->decState != DS_Final) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsDecoder->cmsMsg == NULL) {
                /* Hmmm....looks like the finalize call failed */
        }
        if(cmsDecoder->cmsMsg == NULL) {
                /* Hmmm....looks like the finalize call failed */
-               return paramErr;
+               return errSecParam;
        }
        CSSM_DATA_PTR odata = SecCmsMessageGetContent(cmsDecoder->cmsMsg);
        if((odata == NULL) || (odata->Length == 0)) {
                /* i.e., detached content */
                *content = NULL;
        }
        CSSM_DATA_PTR odata = SecCmsMessageGetContent(cmsDecoder->cmsMsg);
        if((odata == NULL) || (odata->Length == 0)) {
                /* i.e., detached content */
                *content = NULL;
-               return noErr;
+               return errSecSuccess;
        }
        *content = CFDataCreate(NULL, (const UInt8 *)odata->Data, odata->Length);
        }
        *content = CFDataCreate(NULL, (const UInt8 *)odata->Data, odata->Length);
-       return noErr;
+       return errSecSuccess;
 }
 
 #pragma mark --- SPI declared in CMSPrivate.h ---
 
 /*
 }
 
 #pragma mark --- SPI declared in CMSPrivate.h ---
 
 /*
- * Obtain the SecCmsMessageRef associated with a CMSDecoderRef. Intended 
- * to be called after decoding the message (i.e., after 
+ * Obtain the SecCmsMessageRef associated with a CMSDecoderRef. Intended
+ * to be called after decoding the message (i.e., after
  * CMSDecoderFinalizeMessage() to gain finer access to the contents of the
  * CMSDecoderFinalizeMessage() to gain finer access to the contents of the
- * SecCmsMessageRef than is otherwise available via the CMSDecoder interface. 
+ * SecCmsMessageRef than is otherwise available via the CMSDecoder interface.
  * Returns a NULL SecCmsMessageRef if CMSDecoderFinalizeMessage() has not been
  * Returns a NULL SecCmsMessageRef if CMSDecoderFinalizeMessage() has not been
- * called. 
+ * called.
  *
  * The CMSDecoder retains ownership of the returned SecCmsMessageRef.
  */
 OSStatus CMSDecoderGetCmsMessage(
  *
  * The CMSDecoder retains ownership of the returned SecCmsMessageRef.
  */
 OSStatus CMSDecoderGetCmsMessage(
-       CMSDecoderRef           cmsDecoder,
-       SecCmsMessageRef        *cmsMessage)            /* RETURNED */
+                                 CMSDecoderRef         cmsDecoder,
+                                 SecCmsMessageRef      *cmsMessage)            /* RETURNED */
 {
        if((cmsDecoder == NULL) || (cmsMessage == NULL)) {
 {
        if((cmsDecoder == NULL) || (cmsMessage == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        /* any state, whether we have a msg or not is OK */
        *cmsMessage = cmsDecoder->cmsMsg;
        }
        /* any state, whether we have a msg or not is OK */
        *cmsMessage = cmsDecoder->cmsMsg;
-       return noErr;
+       return errSecSuccess;
 }
 
 }
 
-/* 
+/*
  * Optionally specify a SecCmsDecoderRef to use with a CMSDecoderRef.
  * Optionally specify a SecCmsDecoderRef to use with a CMSDecoderRef.
- * If this is called, it must be called before the first call to 
+ * If this is called, it must be called before the first call to
  * CMSDecoderUpdateMessage(). The CMSDecoderRef takes ownership of the
  * incoming SecCmsDecoderRef.
  */
 OSStatus CMSDecoderSetDecoder(
  * CMSDecoderUpdateMessage(). The CMSDecoderRef takes ownership of the
  * incoming SecCmsDecoderRef.
  */
 OSStatus CMSDecoderSetDecoder(
-       CMSDecoderRef           cmsDecoder,
-       SecCmsDecoderRef        decoder)
+                              CMSDecoderRef            cmsDecoder,
+                              SecCmsDecoderRef decoder)
 {
        if((cmsDecoder == NULL) || (decoder == NULL)) {
 {
        if((cmsDecoder == NULL) || (decoder == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        switch(cmsDecoder->decState) {
                case DS_Init:
                        ASSERT(cmsDecoder->decoder == NULL);
                        cmsDecoder->decoder = decoder;
                        cmsDecoder->decState = DS_Updating;
        }
        switch(cmsDecoder->decState) {
                case DS_Init:
                        ASSERT(cmsDecoder->decoder == NULL);
                        cmsDecoder->decoder = decoder;
                        cmsDecoder->decState = DS_Updating;
-                       return noErr;
+                       return errSecSuccess;
                case DS_Updating:
                case DS_Final:
                case DS_Updating:
                case DS_Final:
-                       return paramErr;
+                       return errSecParam;
        }
        }
-       return noErr;
-}              
-       
-/* 
- * Obtain the SecCmsDecoderRef associated with a CMSDecoderRef. 
+       return errSecSuccess;
+}
+
+/*
+ * Obtain the SecCmsDecoderRef associated with a CMSDecoderRef.
  * Returns a NULL SecCmsDecoderRef if neither CMSDecoderSetDecoder() nor
  * Returns a NULL SecCmsDecoderRef if neither CMSDecoderSetDecoder() nor
- * CMSDecoderUpdateMessage() has been called. 
+ * CMSDecoderUpdateMessage() has been called.
  * The CMSDecoderRef retains ownership of the SecCmsDecoderRef.
  */
 OSStatus CMSDecoderGetDecoder(
  * The CMSDecoderRef retains ownership of the SecCmsDecoderRef.
  */
 OSStatus CMSDecoderGetDecoder(
-       CMSDecoderRef           cmsDecoder,
-       SecCmsDecoderRef        *decoder)                       /* RETURNED */
+                              CMSDecoderRef            cmsDecoder,
+                              SecCmsDecoderRef *decoder)                       /* RETURNED */
 {
        if((cmsDecoder == NULL) || (decoder == NULL)) {
 {
        if((cmsDecoder == NULL) || (decoder == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        /* any state, whether we have a decoder or not is OK */
        *decoder = cmsDecoder->decoder;
        }
        /* any state, whether we have a decoder or not is OK */
        *decoder = cmsDecoder->decoder;
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -838,17 +838,17 @@ OSStatus CMSDecoderGetDecoder(
  * present. This is an unauthenticate time, although it is part of the
  * signed attributes of the message.
  *
  * present. This is an unauthenticate time, although it is part of the
  * signed attributes of the message.
  *
- * Returns paramErr if the CMS message was not signed or if signerIndex
- * is greater than the number of signers of the message minus one. 
+ * Returns errSecParam if the CMS message was not signed or if signerIndex
+ * is greater than the number of signers of the message minus one.
  *
  *
- * This cannot be called until after CMSDecoderFinalizeMessage() is called. 
+ * This cannot be called until after CMSDecoderFinalizeMessage() is called.
  */
 OSStatus CMSDecoderCopySignerSigningTime(
  */
 OSStatus CMSDecoderCopySignerSigningTime(
-       CMSDecoderRef           cmsDecoder,
-       size_t                          signerIndex,            /* usually 0 */
-       CFAbsoluteTime      *signingTime)                       /* RETURNED */
+                                         CMSDecoderRef         cmsDecoder,
+                                         size_t                                signerIndex,            /* usually 0 */
+                                         CFAbsoluteTime      *signingTime)                     /* RETURNED */
 {
 {
-    OSStatus status = paramErr;
+    OSStatus status = errSecParam;
        SecCmsMessageRef cmsg;
        SecCmsSignedDataRef signedData = NULL;
     int numContentInfos = 0;
        SecCmsMessageRef cmsg;
        SecCmsSignedDataRef signedData = NULL;
     int numContentInfos = 0;
@@ -877,21 +877,21 @@ xit:
  * present. This timestamp is an authenticated timestamp provided by
  * a timestamping authority.
  *
  * present. This timestamp is an authenticated timestamp provided by
  * a timestamping authority.
  *
- * Returns paramErr if the CMS message was not signed or if signerIndex
- * is greater than the number of signers of the message minus one. 
+ * Returns errSecParam if the CMS message was not signed or if signerIndex
+ * is greater than the number of signers of the message minus one.
  *
  *
- * This cannot be called until after CMSDecoderFinalizeMessage() is called. 
+ * This cannot be called until after CMSDecoderFinalizeMessage() is called.
  */
 OSStatus CMSDecoderCopySignerTimestamp(
  */
 OSStatus CMSDecoderCopySignerTimestamp(
-       CMSDecoderRef           cmsDecoder,
-       size_t                          signerIndex,        /* usually 0 */
-       CFAbsoluteTime      *timestamp)                 /* RETURNED */
+                                       CMSDecoderRef           cmsDecoder,
+                                       size_t                          signerIndex,        /* usually 0 */
+                                       CFAbsoluteTime      *timestamp)                 /* RETURNED */
 {
 {
-    OSStatus status = paramErr;
+    OSStatus status = errSecParam;
        SecCmsMessageRef cmsg;
        SecCmsSignedDataRef signedData = NULL;
     int numContentInfos = 0;
        SecCmsMessageRef cmsg;
        SecCmsSignedDataRef signedData = NULL;
     int numContentInfos = 0;
-
+    
     require(cmsDecoder && timestamp, xit);
        require_noerr(CMSDecoderGetCmsMessage(cmsDecoder, &cmsg), xit);
     numContentInfos = SecCmsMessageContentLevelCount(cmsg);
     require(cmsDecoder && timestamp, xit);
        require_noerr(CMSDecoderGetCmsMessage(cmsDecoder, &cmsg), xit);
     numContentInfos = SecCmsMessageContentLevelCount(cmsg);
@@ -907,33 +907,35 @@ OSStatus CMSDecoderCopySignerTimestamp(
                     break;
                 }
     }
                     break;
                 }
     }
-
+    
 xit:
     return status;
 }
 
 /*
 xit:
     return status;
 }
 
 /*
- * Obtain an array of the certificates in a timestamp response. Elements of the 
+ * Obtain an array of the certificates in a timestamp response. Elements of the
  * returned array are SecCertificateRefs. The caller must CFRelease the returned
  * array. This timestamp is an authenticated timestamp provided by
  * a timestamping authority.
  *
  * returned array are SecCertificateRefs. The caller must CFRelease the returned
  * array. This timestamp is an authenticated timestamp provided by
  * a timestamping authority.
  *
- * Returns paramErr if the CMS message was not signed or if signerIndex
+ * Returns errSecParam if the CMS message was not signed or if signerIndex
  * is greater than the number of signers of the message minus one. It returns
  * errSecItemNotFound if no certificates were found.
  *
  * This cannot be called until after CMSDecoderFinalizeMessage() is called. 
  */
 OSStatus CMSDecoderCopySignerTimestampCertificates(
  * is greater than the number of signers of the message minus one. It returns
  * errSecItemNotFound if no certificates were found.
  *
  * This cannot be called until after CMSDecoderFinalizeMessage() is called. 
  */
 OSStatus CMSDecoderCopySignerTimestampCertificates(
-       CMSDecoderRef           cmsDecoder,
-       size_t                          signerIndex,            /* usually 0 */
-       CFArrayRef          *certificateRefs)       /* RETURNED */
+                                                   CMSDecoderRef               cmsDecoder,
+                                                   size_t                              signerIndex,            /* usually 0 */
+                                                   CFArrayRef          *certificateRefs)       /* RETURNED */
 {
 {
-    OSStatus status = paramErr;
-       SecCmsMessageRef cmsg;
+    OSStatus status = errSecParam;
+       SecCmsMessageRef cmsg = NULL;
        SecCmsSignedDataRef signedData = NULL;
     int numContentInfos = 0;
        SecCmsSignedDataRef signedData = NULL;
     int numContentInfos = 0;
-
+    CFIndex tsn = 0;
+    bool good = false;
+    
     require(cmsDecoder && certificateRefs, xit);
        require_noerr(CMSDecoderGetCmsMessage(cmsDecoder, &cmsg), xit);
     numContentInfos = SecCmsMessageContentLevelCount(cmsg);
     require(cmsDecoder && certificateRefs, xit);
        require_noerr(CMSDecoderGetCmsMessage(cmsDecoder, &cmsg), xit);
     numContentInfos = SecCmsMessageContentLevelCount(cmsg);
@@ -947,12 +949,35 @@ OSStatus CMSDecoderCopySignerTimestampCertificates(
                 {
                     CFArrayRef certList = SecCmsSignerInfoGetTimestampCertList(signerInfo);
                     require_action(certList, xit, status = errSecItemNotFound);
                 {
                     CFArrayRef certList = SecCmsSignerInfoGetTimestampCertList(signerInfo);
                     require_action(certList, xit, status = errSecItemNotFound);
-                    *certificateRefs = CFArrayCreateCopy(kCFAllocatorDefault, certList);
-                    status = noErr;
+                    CFMutableArrayRef certs = CFArrayCreateMutableCopy(kCFAllocatorDefault, CFArrayGetCount(certList), certList);
+                    
+                    if(certs){
+                        //reorder certificates:
+                        tsn = CFArrayGetCount(certs);
+                        good = tsn > 0 && Security::CodeSigning::isAppleCA(SecCertificateRef(CFArrayGetValueAtIndex(certs, tsn-1)));
+                        
+                        if ( good == false )
+                        {
+                            //change TS certificate ordering.
+                            for (CFIndex n = 0; n < tsn; n++)
+                            {
+                                if (SecCertificateRef tsRoot = SecCertificateRef(CFArrayGetValueAtIndex(certs, n)))
+                                    if ((good = Security::CodeSigning::isAppleCA(tsRoot))) {
+                                        CFArrayExchangeValuesAtIndices(certs, n, tsn-1);
+                                        break;
+                                    }
+                            }
+                        }
+                        
+                        *certificateRefs = CFArrayCreateCopy(kCFAllocatorDefault, certs);
+                        CFRelease(certs);
+                        status = errSecSuccess;
+                    }
                     break;
                 }
     }
                     break;
                 }
     }
-
-xit:
-    return status;
-}
+    
+    
+    xit:
+        return status;
+    }
index 4ee58e36ed08e5d6f273ad44af0ba7d846625226..6886be00e90954a56de1c343a88bbec6178468d3 100644 (file)
@@ -230,7 +230,7 @@ OSStatus CMSDecoderCopySignerStatus(
  * Obtain the email address of signer 'signerIndex' of a CMS message, if
  * present. 
  *
  * Obtain the email address of signer 'signerIndex' of a CMS message, if
  * present. 
  *
- * Returns paramErr if the CMS message was not signed or if signerIndex
+ * Returns errSecParam if the CMS message was not signed or if signerIndex
  * is greater than the number of signers of the message minus one. 
  *
  * This cannot be called until after CMSDecoderFinalizeMessage() is called. 
  * is greater than the number of signers of the message minus one. 
  *
  * This cannot be called until after CMSDecoderFinalizeMessage() is called. 
@@ -245,7 +245,7 @@ OSStatus CMSDecoderCopySignerEmailAddress(
  * Obtain the certificate of signer 'signerIndex' of a CMS message, if
  * present. 
  *
  * Obtain the certificate of signer 'signerIndex' of a CMS message, if
  * present. 
  *
- * Returns paramErr if the CMS message was not signed or if signerIndex
+ * Returns errSecParam if the CMS message was not signed or if signerIndex
  * is greater than the number of signers of the message minus one. 
  *
  * This cannot be called until after CMSDecoderFinalizeMessage() is called. 
  * is greater than the number of signers of the message minus one. 
  *
  * This cannot be called until after CMSDecoderFinalizeMessage() is called. 
@@ -259,7 +259,7 @@ OSStatus CMSDecoderCopySignerCert(
 /* 
  * Determine whether a CMS message was encrypted. Returns TRUE if so, FALSE if not.
  * Note that if the message was encrypted, and the decoding succeeded, (i.e.,
 /* 
  * Determine whether a CMS message was encrypted. Returns TRUE if so, FALSE if not.
  * Note that if the message was encrypted, and the decoding succeeded, (i.e.,
- * CMSDecoderFinalizeMessage() returned noErr), then the message was successfully 
+ * CMSDecoderFinalizeMessage() returned errSecSuccess), then the message was successfully
  * decrypted. 
  * This cannot be called until after CMSDecoderFinalizeMessage() is called. 
  */
  * decrypted. 
  * This cannot be called until after CMSDecoderFinalizeMessage() is called. 
  */
@@ -285,7 +285,7 @@ OSStatus CMSDecoderCopyEncapsulatedContentType(
  * returned array are SecCertificateRefs. The caller must CFRelease the returned 
  * array. If a message does not contain any certificates (which is the case for
  * a message which is encrypted but not signed), the returned *certs value 
  * returned array are SecCertificateRefs. The caller must CFRelease the returned 
  * array. If a message does not contain any certificates (which is the case for
  * a message which is encrypted but not signed), the returned *certs value 
- * is NULL. The function will return noErr in this case.
+ * is NULL. The function will return errSecSuccess in this case.
  * This cannot be called until after CMSDecoderFinalizeMessage() is called. 
  */
 OSStatus CMSDecoderCopyAllCerts(
  * This cannot be called until after CMSDecoderFinalizeMessage() is called. 
  */
 OSStatus CMSDecoderCopyAllCerts(
@@ -309,7 +309,7 @@ OSStatus CMSDecoderCopyContent(
  * present. This is an unauthenticate time, although it is part of the
  * signed attributes of the message.
  *
  * present. This is an unauthenticate time, although it is part of the
  * signed attributes of the message.
  *
- * Returns paramErr if the CMS message was not signed or if signerIndex
+ * Returns errSecParam if the CMS message was not signed or if signerIndex
  * is greater than the number of signers of the message minus one. 
  *
  * This cannot be called until after CMSDecoderFinalizeMessage() is called. 
  * is greater than the number of signers of the message minus one. 
  *
  * This cannot be called until after CMSDecoderFinalizeMessage() is called. 
@@ -325,7 +325,7 @@ OSStatus CMSDecoderCopySignerSigningTime(
  * present. This timestamp is an authenticated timestamp provided by
  * a timestamping authority.
  *
  * present. This timestamp is an authenticated timestamp provided by
  * a timestamping authority.
  *
- * Returns paramErr if the CMS message was not signed or if signerIndex
+ * Returns errSecParam if the CMS message was not signed or if signerIndex
  * is greater than the number of signers of the message minus one. 
  *
  * This cannot be called until after CMSDecoderFinalizeMessage() is called. 
  * is greater than the number of signers of the message minus one. 
  *
  * This cannot be called until after CMSDecoderFinalizeMessage() is called. 
@@ -342,7 +342,7 @@ OSStatus CMSDecoderCopySignerTimestamp(
  * array. This timestamp is an authenticated timestamp provided by
  * a timestamping authority.
  *
  * array. This timestamp is an authenticated timestamp provided by
  * a timestamping authority.
  *
- * Returns paramErr if the CMS message was not signed or if signerIndex
+ * Returns errSecParam if the CMS message was not signed or if signerIndex
  * is greater than the number of signers of the message minus one. It returns
  * errSecItemNotFound if no certificates were found.
  *
  * is greater than the number of signers of the message minus one. It returns
  * errSecItemNotFound if no certificates were found.
  *
index d41e2af30dc9096c1fd2ee2b28e0208af6bf37d7..36a2f1bd7326cf646afce9b969d51fc11cf7787a 100644 (file)
@@ -28,7 +28,7 @@
 #include "CMSEncoder.h"
 #include "CMSPrivate.h"
 #include "CMSUtils.h"
 #include "CMSEncoder.h"
 #include "CMSPrivate.h"
 #include "CMSUtils.h"
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+#include <Security/SecBase.h>
 #include <Security/SecCmsEncoder.h>
 #include <Security/SecCmsEnvelopedData.h>
 #include <Security/SecCmsMessage.h>
 #include <Security/SecCmsEncoder.h>
 #include <Security/SecCmsEnvelopedData.h>
 #include <Security/SecCmsMessage.h>
@@ -186,14 +186,15 @@ static int encodeOid(
 {
        unsigned char **digits = NULL;          /* array of char * from encodeNumber */
        unsigned *numDigits = NULL;                     /* array of unsigned from encodeNumber */
 {
        unsigned char **digits = NULL;          /* array of char * from encodeNumber */
        unsigned *numDigits = NULL;                     /* array of unsigned from encodeNumber */
-       unsigned digit;
+       CFIndex digit;
        unsigned numDigitBytes;                         /* total #of output chars */
        unsigned char firstByte;
        unsigned char *outP;
        unsigned numDigitBytes;                         /* total #of output chars */
        unsigned char firstByte;
        unsigned char *outP;
-       unsigned numsToProcess;
+       CFIndex numsToProcess;
        CFStringRef oidStr = NULL;
        CFArrayRef argvRef = NULL;
        CFStringRef oidStr = NULL;
        CFArrayRef argvRef = NULL;
-       int num, argc, result = 1;
+       int num, result = 1;
+        CFIndex argc;
        
        /* parse input string into array of substrings */
        if (!inStr || !outOid || !outLen) goto cleanExit;
        
        /* parse input string into array of substrings */
        if (!inStr || !outOid || !outLen) goto cleanExit;
@@ -265,7 +266,7 @@ static int convertOid(
        CSSM_OID *outOid)
 {
        if (!inRef || !outOid)
        CSSM_OID *outOid)
 {
        if (!inRef || !outOid)
-               return paramErr;
+               return errSecParam;
        
        unsigned char *oidData = NULL;
        unsigned int oidLen = 0;
        
        unsigned char *oidData = NULL;
        unsigned int oidLen = 0;
@@ -276,10 +277,10 @@ static int convertOid(
                CFIndex max = CFStringGetLength(inStr) * 3;
                char buf[max];
                if (!CFStringGetCString(inStr, buf, max-1, kCFStringEncodingASCII))
                CFIndex max = CFStringGetLength(inStr) * 3;
                char buf[max];
                if (!CFStringGetCString(inStr, buf, max-1, kCFStringEncodingASCII))
-                       return paramErr;
+                       return errSecParam;
 
                if(encodeOid((unsigned char *)buf, &oidData, &oidLen) != 0)
 
                if(encodeOid((unsigned char *)buf, &oidData, &oidLen) != 0)
-                       return paramErr;
+                       return errSecParam;
        }
        else if (CFGetTypeID(inRef) == CFDataGetTypeID()) {
                // CFDataRef: OID representation is in binary DER format
        }
        else if (CFGetTypeID(inRef) == CFDataGetTypeID()) {
                // CFDataRef: OID representation is in binary DER format
@@ -290,7 +291,7 @@ static int convertOid(
        }
        else {
                // Not in a format we understand
        }
        else {
                // Not in a format we understand
-               return paramErr;
+               return errSecParam;
        }
        outOid->Length = oidLen;
        outOid->Data = (uint8 *)oidData;
        }
        outOid->Length = oidLen;
        outOid->Data = (uint8 *)oidData;
@@ -367,7 +368,7 @@ static OSStatus cmsSetupEncoder(
        if(ortn) {
                return cmsRtnToOSStatus(ortn);
        }
        if(ortn) {
                return cmsRtnToOSStatus(ortn);
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 /* 
 }
 
 /* 
@@ -388,12 +389,12 @@ static OSStatus cmsSetupForSignedData(
        }
        cmsEncoder->cmsMsg = SecCmsMessageCreate(NULL);
        if(cmsEncoder->cmsMsg == NULL) {
        }
        cmsEncoder->cmsMsg = SecCmsMessageCreate(NULL);
        if(cmsEncoder->cmsMsg == NULL) {
-               return internalComponentErr;
+               return errSecInternalComponent;
        }
 
        signedData = SecCmsSignedDataCreate(cmsEncoder->cmsMsg);
        if(signedData == NULL) {
        }
 
        signedData = SecCmsSignedDataCreate(cmsEncoder->cmsMsg);
        if(signedData == NULL) {
-               return internalComponentErr;
+               return errSecInternalComponent;
        }
        contentInfo = SecCmsMessageGetContentInfo(cmsEncoder->cmsMsg);
        ortn = SecCmsContentInfoSetContentSignedData(cmsEncoder->cmsMsg, contentInfo, 
        }
        contentInfo = SecCmsMessageGetContentInfo(cmsEncoder->cmsMsg);
        ortn = SecCmsContentInfoSetContentSignedData(cmsEncoder->cmsMsg, contentInfo, 
@@ -473,7 +474,7 @@ static OSStatus cmsSetupForSignedData(
                }
                signerInfo = SecCmsSignerInfoCreate(cmsEncoder->cmsMsg, ourId, SEC_OID_SHA1);
                if (signerInfo == NULL) {
                }
                signerInfo = SecCmsSignerInfoCreate(cmsEncoder->cmsMsg, ourId, SEC_OID_SHA1);
                if (signerInfo == NULL) {
-                       ortn = internalComponentErr;
+                       ortn = errSecInternalComponent;
                        break;
                }
 
                        break;
                }
 
@@ -584,12 +585,12 @@ static OSStatus cmsSetupForEnvelopedData(
        }
        cmsEncoder->cmsMsg = SecCmsMessageCreate(NULL);
        if(cmsEncoder->cmsMsg == NULL) {
        }
        cmsEncoder->cmsMsg = SecCmsMessageCreate(NULL);
        if(cmsEncoder->cmsMsg == NULL) {
-               return internalComponentErr;
+               return errSecInternalComponent;
        }
        envelopedData = SecCmsEnvelopedDataCreate(cmsEncoder->cmsMsg, 
                algorithmTag, keySize);
        if(envelopedData == NULL) {
        }
        envelopedData = SecCmsEnvelopedDataCreate(cmsEncoder->cmsMsg, 
                algorithmTag, keySize);
        if(envelopedData == NULL) {
-               return internalComponentErr;
+               return errSecInternalComponent;
        }
        contentInfo = SecCmsMessageGetContentInfo(cmsEncoder->cmsMsg);
        ortn = SecCmsContentInfoSetContentEnvelopedData(cmsEncoder->cmsMsg, 
        }
        contentInfo = SecCmsMessageGetContentInfo(cmsEncoder->cmsMsg);
        ortn = SecCmsContentInfoSetContentEnvelopedData(cmsEncoder->cmsMsg, 
@@ -636,7 +637,7 @@ static OSStatus cmsSetupForEnvelopedData(
                        return ortn;
                }
        }
                        return ortn;
                }
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 /* 
 }
 
 /* 
@@ -663,10 +664,10 @@ static OSStatus cmsSetupCmsMsg(
        }
        else {
                dprintf("CMSEncoderUpdateContent: nothing to do\n");
        }
        else {
                dprintf("CMSEncoderUpdateContent: nothing to do\n");
-               return paramErr;
+               return errSecParam;
        }
        
        }
        
-       OSStatus ortn = noErr;
+       OSStatus ortn = errSecSuccess;
        
        switch(cmsEncoder->op) {
                case EO_Sign:
        
        switch(cmsEncoder->op) {
                case EO_Sign:
@@ -719,10 +720,10 @@ static OSStatus cmsContentInfoContent(
     }
     if(decodedInfo.content.Data == NULL) {
                dprintf("***Error decoding contentInfo: no content\n");
     }
     if(decodedInfo.content.Data == NULL) {
                dprintf("***Error decoding contentInfo: no content\n");
-               return internalComponentErr;
+               return errSecInternalComponent;
     }
     *content = decodedInfo.content;
     }
     *content = decodedInfo.content;
-       return noErr;
+       return errSecSuccess;
 }
 
 #pragma mark --- Start of Public API ---
 }
 
 #pragma mark --- Start of Public API ---
@@ -749,12 +750,12 @@ OSStatus CMSEncoderCreate(
        cmsEncoder = (CMSEncoderRef)_CFRuntimeCreateInstance(NULL, CMSEncoderGetTypeID(),
                extra, NULL);
        if(cmsEncoder == NULL) {
        cmsEncoder = (CMSEncoderRef)_CFRuntimeCreateInstance(NULL, CMSEncoderGetTypeID(),
                extra, NULL);
        if(cmsEncoder == NULL) {
-               return memFullErr;
+               return errSecAllocate;
        }
        cmsEncoder->encState = ES_Init;
        cmsEncoder->chainMode = kCMSCertificateChain;
        *cmsEncoderOut = cmsEncoder;
        }
        cmsEncoder->encState = ES_Init;
        cmsEncoder->chainMode = kCMSCertificateChain;
        *cmsEncoderOut = cmsEncoder;
-       return noErr;
+       return errSecSuccess;
 }
        
 #pragma mark --- Getters & Setters ---
 }
        
 #pragma mark --- Getters & Setters ---
@@ -767,10 +768,10 @@ OSStatus CMSEncoderAddSigners(
        CFTypeRef                       signerOrArray)
 {
        if(cmsEncoder == NULL) {
        CFTypeRef                       signerOrArray)
 {
        if(cmsEncoder == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsEncoder->encState != ES_Init) {
        }
        if(cmsEncoder->encState != ES_Init) {
-               return paramErr;
+               return errSecParam;
        }
        return cmsAppendToArray(signerOrArray, &cmsEncoder->signers, SecIdentityGetTypeID());
 }
        }
        return cmsAppendToArray(signerOrArray, &cmsEncoder->signers, SecIdentityGetTypeID());
 }
@@ -783,13 +784,13 @@ OSStatus CMSEncoderCopySigners(
        CFArrayRef                      *signers)
 {
        if((cmsEncoder == NULL) || (signers == NULL)) {
        CFArrayRef                      *signers)
 {
        if((cmsEncoder == NULL) || (signers == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsEncoder->signers != NULL) {
                CFRetain(cmsEncoder->signers);
        }
        *signers = cmsEncoder->signers;
        }
        if(cmsEncoder->signers != NULL) {
                CFRetain(cmsEncoder->signers);
        }
        *signers = cmsEncoder->signers;
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -800,10 +801,10 @@ OSStatus CMSEncoderAddRecipients(
        CFTypeRef                       recipientOrArray)
 {
        if(cmsEncoder == NULL) {
        CFTypeRef                       recipientOrArray)
 {
        if(cmsEncoder == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsEncoder->encState != ES_Init) {
        }
        if(cmsEncoder->encState != ES_Init) {
-               return paramErr;
+               return errSecParam;
        }
        return cmsAppendToArray(recipientOrArray, &cmsEncoder->recipients, 
                        SecCertificateGetTypeID());
        }
        return cmsAppendToArray(recipientOrArray, &cmsEncoder->recipients, 
                        SecCertificateGetTypeID());
@@ -817,13 +818,13 @@ OSStatus CMSEncoderCopyRecipients(
        CFArrayRef                      *recipients)
 {
        if((cmsEncoder == NULL) || (recipients == NULL)) {
        CFArrayRef                      *recipients)
 {
        if((cmsEncoder == NULL) || (recipients == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsEncoder->recipients != NULL) {
                CFRetain(cmsEncoder->recipients);
        }
        *recipients = cmsEncoder->recipients;
        }
        if(cmsEncoder->recipients != NULL) {
                CFRetain(cmsEncoder->recipients);
        }
        *recipients = cmsEncoder->recipients;
-       return noErr;
+       return errSecSuccess;
 }
 
 /* 
 }
 
 /* 
@@ -834,10 +835,10 @@ OSStatus CMSEncoderAddSupportingCerts(
        CFTypeRef                       certOrArray)
 {
        if(cmsEncoder == NULL) {
        CFTypeRef                       certOrArray)
 {
        if(cmsEncoder == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsEncoder->encState != ES_Init) {
        }
        if(cmsEncoder->encState != ES_Init) {
-               return paramErr;
+               return errSecParam;
        }
        return cmsAppendToArray(certOrArray, &cmsEncoder->otherCerts, 
                        SecCertificateGetTypeID());
        }
        return cmsAppendToArray(certOrArray, &cmsEncoder->otherCerts, 
                        SecCertificateGetTypeID());
@@ -851,13 +852,13 @@ OSStatus CMSEncoderCopySupportingCerts(
        CFArrayRef                      *certs)                 /* RETURNED */
 {
        if((cmsEncoder == NULL) || (certs == NULL)) {
        CFArrayRef                      *certs)                 /* RETURNED */
 {
        if((cmsEncoder == NULL) || (certs == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsEncoder->otherCerts != NULL) {
                CFRetain(cmsEncoder->otherCerts);
        }
        *certs = cmsEncoder->otherCerts;
        }
        if(cmsEncoder->otherCerts != NULL) {
                CFRetain(cmsEncoder->otherCerts);
        }
        *certs = cmsEncoder->otherCerts;
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus CMSEncoderSetHasDetachedContent(
 }
 
 OSStatus CMSEncoderSetHasDetachedContent(
@@ -865,13 +866,13 @@ OSStatus CMSEncoderSetHasDetachedContent(
        Boolean                         detachedContent)
 {
        if(cmsEncoder == NULL) {
        Boolean                         detachedContent)
 {
        if(cmsEncoder == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsEncoder->encState != ES_Init) {
        }
        if(cmsEncoder->encState != ES_Init) {
-               return paramErr;
+               return errSecParam;
        }
        cmsEncoder->detachedContent = detachedContent;
        }
        cmsEncoder->detachedContent = detachedContent;
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus CMSEncoderGetHasDetachedContent(
 }
 
 OSStatus CMSEncoderGetHasDetachedContent(
@@ -879,10 +880,10 @@ OSStatus CMSEncoderGetHasDetachedContent(
        Boolean                         *detachedContent)       /* RETURNED */
 {
        if((cmsEncoder == NULL) || (detachedContent == NULL)) {
        Boolean                         *detachedContent)       /* RETURNED */
 {
        if((cmsEncoder == NULL) || (detachedContent == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        *detachedContent = cmsEncoder->detachedContent;
        }
        *detachedContent = cmsEncoder->detachedContent;
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -895,10 +896,10 @@ OSStatus CMSEncoderSetEncapsulatedContentType(
        const CSSM_OID  *eContentType)
 {
        if((cmsEncoder == NULL) || (eContentType == NULL)) {
        const CSSM_OID  *eContentType)
 {
        if((cmsEncoder == NULL) || (eContentType == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsEncoder->encState != ES_Init) {
        }
        if(cmsEncoder->encState != ES_Init) {
-               return paramErr;
+               return errSecParam;
        }
        
        CSSM_OID *ecOid = &cmsEncoder->eContentType;
        }
        
        CSSM_OID *ecOid = &cmsEncoder->eContentType;
@@ -906,7 +907,7 @@ OSStatus CMSEncoderSetEncapsulatedContentType(
                free(ecOid->Data);
        }
        cmsCopyCmsData(eContentType, ecOid);
                free(ecOid->Data);
        }
        cmsCopyCmsData(eContentType, ecOid);
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus CMSEncoderSetEncapsulatedContentTypeOID(
 }
 
 OSStatus CMSEncoderSetEncapsulatedContentTypeOID(
@@ -916,7 +917,7 @@ OSStatus CMSEncoderSetEncapsulatedContentTypeOID(
        // convert eContentTypeOID to a CSSM_OID
        CSSM_OID contentType = { 0, NULL };
        if (!eContentTypeOID || convertOid(eContentTypeOID, &contentType) != 0)
        // convert eContentTypeOID to a CSSM_OID
        CSSM_OID contentType = { 0, NULL };
        if (!eContentTypeOID || convertOid(eContentTypeOID, &contentType) != 0)
-               return paramErr;
+               return errSecParam;
        OSStatus result = CMSEncoderSetEncapsulatedContentType(cmsEncoder, &contentType);
        if (contentType.Data)
                free(contentType.Data);
        OSStatus result = CMSEncoderSetEncapsulatedContentType(cmsEncoder, &contentType);
        if (contentType.Data)
                free(contentType.Data);
@@ -931,7 +932,7 @@ OSStatus CMSEncoderCopyEncapsulatedContentType(
        CFDataRef                       *eContentType)
 {
        if((cmsEncoder == NULL) || (eContentType == NULL)) {
        CFDataRef                       *eContentType)
 {
        if((cmsEncoder == NULL) || (eContentType == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        
        CSSM_OID *ecOid = &cmsEncoder->eContentType;
        }
        
        CSSM_OID *ecOid = &cmsEncoder->eContentType;
@@ -941,7 +942,7 @@ OSStatus CMSEncoderCopyEncapsulatedContentType(
        else {
                *eContentType = CFDataCreate(NULL, ecOid->Data, ecOid->Length);
        }
        else {
                *eContentType = CFDataCreate(NULL, ecOid->Data, ecOid->Length);
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -954,13 +955,13 @@ OSStatus CMSEncoderAddSignedAttributes(
        CMSSignedAttributes     signedAttributes)
 {
        if(cmsEncoder == NULL) {
        CMSSignedAttributes     signedAttributes)
 {
        if(cmsEncoder == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsEncoder->encState != ES_Init) {
        }
        if(cmsEncoder->encState != ES_Init) {
-               return paramErr;
+               return errSecParam;
        }
        cmsEncoder->signedAttributes = signedAttributes;
        }
        cmsEncoder->signedAttributes = signedAttributes;
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -972,13 +973,13 @@ OSStatus CMSEncoderSetSigningTime(
        CFAbsoluteTime          time)
 {
        if(cmsEncoder == NULL) {
        CFAbsoluteTime          time)
 {
        if(cmsEncoder == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsEncoder->encState != ES_Init) {
        }
        if(cmsEncoder->encState != ES_Init) {
-               return paramErr;
+               return errSecParam;
        }
        cmsEncoder->signingTime = time;
        }
        cmsEncoder->signingTime = time;
-       return noErr;
+       return errSecSuccess;
 }
 
 
 }
 
 
@@ -987,10 +988,10 @@ OSStatus CMSEncoderSetCertificateChainMode(
        CMSCertificateChainMode chainMode)
 {
        if(cmsEncoder == NULL) {
        CMSCertificateChainMode chainMode)
 {
        if(cmsEncoder == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsEncoder->encState != ES_Init) {
        }
        if(cmsEncoder->encState != ES_Init) {
-               return paramErr;
+               return errSecParam;
        }
        switch(chainMode) {
                case kCMSCertificateNone:
        }
        switch(chainMode) {
                case kCMSCertificateNone:
@@ -999,10 +1000,10 @@ OSStatus CMSEncoderSetCertificateChainMode(
                case kCMSCertificateChainWithRoot:
                        break;
                default:
                case kCMSCertificateChainWithRoot:
                        break;
                default:
-                       return paramErr;
+                       return errSecParam;
        }
        cmsEncoder->chainMode = chainMode;
        }
        cmsEncoder->chainMode = chainMode;
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus CMSEncoderGetCertificateChainMode(
 }
 
 OSStatus CMSEncoderGetCertificateChainMode(
@@ -1010,10 +1011,10 @@ OSStatus CMSEncoderGetCertificateChainMode(
        CMSCertificateChainMode *chainModeOut)
 {
        if(cmsEncoder == NULL) {
        CMSCertificateChainMode *chainModeOut)
 {
        if(cmsEncoder == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        *chainModeOut = cmsEncoder->chainMode;
        }
        *chainModeOut = cmsEncoder->chainMode;
-       return noErr;
+       return errSecSuccess;
 }
 
 void
 }
 
 void
@@ -1043,10 +1044,10 @@ OSStatus CMSEncoderUpdateContent(
        size_t                          contentLen)
 {
        if(cmsEncoder == NULL) {
        size_t                          contentLen)
 {
        if(cmsEncoder == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        
        }
        
-       OSStatus ortn = noErr;
+       OSStatus ortn = errSecSuccess;
        switch(cmsEncoder->encState) {
                case ES_Init:
                        /* 
        switch(cmsEncoder->encState) {
                case ES_Init:
                        /* 
@@ -1076,10 +1077,10 @@ OSStatus CMSEncoderUpdateContent(
 
                case ES_Final:
                        /* Too late for another update */
 
                case ES_Final:
                        /* Too late for another update */
-                       return paramErr;
+                       return errSecParam;
                        
                default:
                        
                default:
-                       return internalComponentErr;
+                       return errSecInternalComponent;
        }
        
        /* FIXME - CFIndex same size as size_t on 64bit? */
        }
        
        /* FIXME - CFIndex same size as size_t on 64bit? */
@@ -1100,7 +1101,7 @@ OSStatus CMSEncoderCopyEncodedContent(
        CFDataRef                       *encodedContent)
 {
        if((cmsEncoder == NULL) || (encodedContent == NULL)) {
        CFDataRef                       *encodedContent)
 {
        if((cmsEncoder == NULL) || (encodedContent == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
 
        OSStatus ortn;
        }
 
        OSStatus ortn;
@@ -1111,7 +1112,7 @@ OSStatus CMSEncoderCopyEncodedContent(
                        break;
                case ES_Final:
                        /* already been called */
                        break;
                case ES_Final:
                        /* already been called */
-                       return paramErr;
+                       return errSecParam;
                case ES_Msg:
                case ES_Init:
                        /*
                case ES_Msg:
                case ES_Init:
                        /*
@@ -1121,7 +1122,7 @@ OSStatus CMSEncoderCopyEncodedContent(
                        if((cmsEncoder->signers != NULL) ||
                           (cmsEncoder->recipients != NULL) ||
                           (cmsEncoder->otherCerts == NULL)) {
                        if((cmsEncoder->signers != NULL) ||
                           (cmsEncoder->recipients != NULL) ||
                           (cmsEncoder->otherCerts == NULL)) {
-                               return paramErr;
+                               return errSecParam;
                        }
                        
                        /* Set up for certs only */
                        }
                        
                        /* Set up for certs only */
@@ -1150,12 +1151,12 @@ OSStatus CMSEncoderCopyEncodedContent(
        if((cmsEncoder->encoderOut.Data == NULL) && !cmsEncoder->customCoder) {
                /* not sure how this could happen... */
                dprintf("Successful encode, but no data\n");
        if((cmsEncoder->encoderOut.Data == NULL) && !cmsEncoder->customCoder) {
                /* not sure how this could happen... */
                dprintf("Successful encode, but no data\n");
-               return internalComponentErr;
+               return errSecInternalComponent;
        }
        if(cmsEncoder->customCoder) {
                /* we're done */
                *encodedContent = NULL;
        }
        if(cmsEncoder->customCoder) {
                /* we're done */
                *encodedContent = NULL;
-               return noErr;
+               return errSecSuccess;
        }
        
        /* in two out of three cases, we're done */
        }
        
        /* in two out of three cases, we're done */
@@ -1164,7 +1165,7 @@ OSStatus CMSEncoderCopyEncodedContent(
                case EO_Encrypt:
                        *encodedContent = CFDataCreate(NULL, (const UInt8 *)cmsEncoder->encoderOut.Data,        
                                cmsEncoder->encoderOut.Length);
                case EO_Encrypt:
                        *encodedContent = CFDataCreate(NULL, (const UInt8 *)cmsEncoder->encoderOut.Data,        
                                cmsEncoder->encoderOut.Length);
-                       return noErr;
+                       return errSecSuccess;
                case EO_SignEncrypt:
                        /* proceed, more work to do */
                        break;
                case EO_SignEncrypt:
                        /* proceed, more work to do */
                        break;
@@ -1223,10 +1224,10 @@ OSStatus CMSEncode(
        CFDataRef                       *encodedContent)        /* RETURNED */
 {
        if((signers == NULL) && (recipients == NULL)) {
        CFDataRef                       *encodedContent)        /* RETURNED */
 {
        if((signers == NULL) && (recipients == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        if(encodedContent == NULL) {
        }
        if(encodedContent == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        
        CMSEncoderRef cmsEncoder;
        }
        
        CMSEncoderRef cmsEncoder;
@@ -1294,7 +1295,7 @@ OSStatus CMSEncodeContent(
        // convert eContentTypeOID to a CSSM_OID
        CSSM_OID contentType = { 0, NULL };
        if (eContentTypeOID && convertOid(eContentTypeOID, &contentType) != 0)
        // convert eContentTypeOID to a CSSM_OID
        CSSM_OID contentType = { 0, NULL };
        if (eContentTypeOID && convertOid(eContentTypeOID, &contentType) != 0)
-               return paramErr;
+               return errSecParam;
        const CSSM_OID *contentTypePtr = (eContentTypeOID) ? &contentType : NULL;
        OSStatus result = CMSEncode(signers, recipients, contentTypePtr,
                                                                        detachedContent, signedAttributes,
        const CSSM_OID *contentTypePtr = (eContentTypeOID) ? &contentType : NULL;
        OSStatus result = CMSEncode(signers, recipients, contentTypePtr,
                                                                        detachedContent, signedAttributes,
@@ -1316,12 +1317,12 @@ OSStatus CMSEncoderGetCmsMessage(
        SecCmsMessageRef        *cmsMessage)            /* RETURNED */
 {
        if((cmsEncoder == NULL) || (cmsMessage == NULL)) {
        SecCmsMessageRef        *cmsMessage)            /* RETURNED */
 {
        if((cmsEncoder == NULL) || (cmsMessage == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsEncoder->cmsMsg != NULL) {
                ASSERT(cmsEncoder->encState != ES_Init);
                *cmsMessage = cmsEncoder->cmsMsg;
        }
        if(cmsEncoder->cmsMsg != NULL) {
                ASSERT(cmsEncoder->encState != ES_Init);
                *cmsMessage = cmsEncoder->cmsMsg;
-               return noErr;
+               return errSecSuccess;
        }
 
        OSStatus ortn = cmsSetupCmsMsg(cmsEncoder);
        }
 
        OSStatus ortn = cmsSetupCmsMsg(cmsEncoder);
@@ -1332,7 +1333,7 @@ OSStatus CMSEncoderGetCmsMessage(
        
        /* Don't set up encoder yet; caller might do that via CMSEncoderSetEncoder */
        cmsEncoder->encState = ES_Msg;
        
        /* Don't set up encoder yet; caller might do that via CMSEncoderSetEncoder */
        cmsEncoder->encState = ES_Msg;
-       return noErr;
+       return errSecSuccess;
 }
 
 /* 
 }
 
 /* 
@@ -1346,7 +1347,7 @@ OSStatus CMSEncoderSetEncoder(
        SecCmsEncoderRef        encoder)
 {
        if((cmsEncoder == NULL) || (encoder == NULL)) {
        SecCmsEncoderRef        encoder)
 {
        if((cmsEncoder == NULL) || (encoder == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        
        OSStatus ortn;
        }
        
        OSStatus ortn;
@@ -1368,10 +1369,10 @@ OSStatus CMSEncoderSetEncoder(
                        cmsEncoder->encoder = encoder;
                        cmsEncoder->encState = ES_Updating;
                        cmsEncoder->customCoder = true;                 /* we won't see data */
                        cmsEncoder->encoder = encoder;
                        cmsEncoder->encState = ES_Updating;
                        cmsEncoder->customCoder = true;                 /* we won't see data */
-                       return noErr;
+                       return errSecSuccess;
                default:
                        /* no can do, too late */
                default:
                        /* no can do, too late */
-                       return paramErr;
+                       return errSecParam;
        }
 }
        
        }
 }
        
@@ -1386,12 +1387,12 @@ OSStatus CMSEncoderGetEncoder(
        SecCmsEncoderRef        *encoder)                       /* RETURNED */
 {
        if((cmsEncoder == NULL) || (encoder == NULL)) {
        SecCmsEncoderRef        *encoder)                       /* RETURNED */
 {
        if((cmsEncoder == NULL) || (encoder == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        
        /* any state, whether we have an encoder or not is OK */
        *encoder = cmsEncoder->encoder;
        }
        
        /* any state, whether we have an encoder or not is OK */
        *encoder = cmsEncoder->encoder;
-       return noErr;
+       return errSecSuccess;
 }
 
 #include <AssertMacros.h>
 }
 
 #include <AssertMacros.h>
@@ -1401,7 +1402,7 @@ OSStatus CMSEncoderGetEncoder(
  * present. This timestamp is an authenticated timestamp provided by
  * a timestamping authority.
  *
  * present. This timestamp is an authenticated timestamp provided by
  * a timestamping authority.
  *
- * Returns paramErr if the CMS message was not signed or if signerIndex
+ * Returns errSecParam if the CMS message was not signed or if signerIndex
  * is greater than the number of signers of the message minus one. 
  *
  * This cannot be called until after CMSEncoderCopyEncodedContent() is called. 
  * is greater than the number of signers of the message minus one. 
  *
  * This cannot be called until after CMSEncoderCopyEncodedContent() is called. 
@@ -1411,7 +1412,7 @@ OSStatus CMSEncoderCopySignerTimestamp(
        size_t                          signerIndex,        /* usually 0 */
        CFAbsoluteTime      *timestamp)                 /* RETURNED */
 {
        size_t                          signerIndex,        /* usually 0 */
        CFAbsoluteTime      *timestamp)                 /* RETURNED */
 {
-    OSStatus status = paramErr;
+    OSStatus status = errSecParam;
        SecCmsMessageRef cmsg;
        SecCmsSignedDataRef signedData = NULL;
     int numContentInfos = 0;
        SecCmsMessageRef cmsg;
        SecCmsSignedDataRef signedData = NULL;
     int numContentInfos = 0;
index 712d7ed6df35c71d14945eaffac67396bf6184d4..da0d7ad4c5d69ef855ccc1c0004ccfc7a5e3fc58 100644 (file)
@@ -29,7 +29,6 @@
 #include "CMSUtils.h"
 #include <stdlib.h>
 #include <string.h>
 #include "CMSUtils.h"
 #include <stdlib.h>
 #include <string.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 #include <security_asn1/secerr.h>
 #include <security_asn1/seccomon.h>
 #include <Security/SecBase.h>
 #include <security_asn1/secerr.h>
 #include <security_asn1/seccomon.h>
 #include <Security/SecBase.h>
@@ -50,7 +49,7 @@ void cmsCopyCmsData(
  * Append a CF type, or the contents of an array, to another array.
  * destination array will be created if necessary.
  * If srcItemOrArray is not of the type specified in expectedType,
  * Append a CF type, or the contents of an array, to another array.
  * destination array will be created if necessary.
  * If srcItemOrArray is not of the type specified in expectedType,
- * paramErr will be returned. 
+ * errSecParam will be returned. 
  */
 OSStatus cmsAppendToArray(
        CFTypeRef srcItemOrArray,
  */
 OSStatus cmsAppendToArray(
        CFTypeRef srcItemOrArray,
@@ -58,7 +57,7 @@ OSStatus cmsAppendToArray(
        CFTypeID expectedType)  
 {
        if(srcItemOrArray == NULL) {
        CFTypeID expectedType)  
 {
        if(srcItemOrArray == NULL) {
-               return noErr;
+               return errSecSuccess;
        }
        if(*dstArray == NULL) {
                *dstArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
        }
        if(*dstArray == NULL) {
                *dstArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
@@ -73,9 +72,9 @@ OSStatus cmsAppendToArray(
                CFArrayAppendValue(*dstArray, srcItemOrArray);
        }
        else {
                CFArrayAppendValue(*dstArray, srcItemOrArray);
        }
        else {
-               return paramErr;
+               return errSecParam;
        }
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 /* 
 }
 
 /* 
@@ -92,7 +91,7 @@ OSStatus cmsRtnToOSStatus(
                if(smimeRtn == 0) {
                        /* S/MIME just gave us generic error; no further info available; punt. */
                        dprintf("cmsRtnToOSStatus: SECFailure, no status avilable\n");
                if(smimeRtn == 0) {
                        /* S/MIME just gave us generic error; no further info available; punt. */
                        dprintf("cmsRtnToOSStatus: SECFailure, no status avilable\n");
-                       return defaultRtn ? defaultRtn : internalComponentErr;
+                       return defaultRtn ? defaultRtn : errSecInternalComponent;
                }
                /* else proceed to map smimeRtn to OSStatus */
        }
                }
                /* else proceed to map smimeRtn to OSStatus */
        }
@@ -107,16 +106,16 @@ OSStatus cmsRtnToOSStatus(
                case SEC_ERROR_BAD_DATA:
                        return errSecUnknownFormat;
                case SEC_ERROR_NO_MEMORY:
                case SEC_ERROR_BAD_DATA:
                        return errSecUnknownFormat;
                case SEC_ERROR_NO_MEMORY:
-                       return memFullErr;
+                       return errSecAllocate;
                case SEC_ERROR_IO:
                case SEC_ERROR_IO:
-                       return ioErr;
+                       return errSecIO;
                case SEC_ERROR_OUTPUT_LEN:
                case SEC_ERROR_INPUT_LEN:
                case SEC_ERROR_INVALID_ARGS:
                case SEC_ERROR_INVALID_ALGORITHM:
                case SEC_ERROR_INVALID_AVA:
                case SEC_ERROR_INVALID_TIME:
                case SEC_ERROR_OUTPUT_LEN:
                case SEC_ERROR_INPUT_LEN:
                case SEC_ERROR_INVALID_ARGS:
                case SEC_ERROR_INVALID_ALGORITHM:
                case SEC_ERROR_INVALID_AVA:
                case SEC_ERROR_INVALID_TIME:
-                       return paramErr;
+                       return errSecParam;
                case SEC_ERROR_PKCS7_BAD_SIGNATURE:
                case SEC_ERROR_BAD_SIGNATURE:
                        return CSSMERR_CSP_VERIFY_FAILED;
                case SEC_ERROR_PKCS7_BAD_SIGNATURE:
                case SEC_ERROR_BAD_SIGNATURE:
                        return CSSMERR_CSP_VERIFY_FAILED;
@@ -133,13 +132,13 @@ OSStatus cmsRtnToOSStatus(
                case SEC_ERROR_INADEQUATE_KEY_USAGE:
                        return CSSMERR_CSP_KEY_USAGE_INCORRECT;
                case SEC_INTERNAL_ONLY:
                case SEC_ERROR_INADEQUATE_KEY_USAGE:
                        return CSSMERR_CSP_KEY_USAGE_INCORRECT;
                case SEC_INTERNAL_ONLY:
-                       return internalComponentErr;
+                       return errSecInternalComponent;
                case SEC_ERROR_NO_USER_INTERACTION:
                        return errSecInteractionNotAllowed;
                case SEC_ERROR_USER_CANCELLED:
                case SEC_ERROR_NO_USER_INTERACTION:
                        return errSecInteractionNotAllowed;
                case SEC_ERROR_USER_CANCELLED:
-                       return userCanceledErr;
+                       return errSecUserCanceled;
                default:
                        dprintf("cmsRtnToOSStatus: smimeRtn 0x%x\n", smimeRtn);
                default:
                        dprintf("cmsRtnToOSStatus: smimeRtn 0x%x\n", smimeRtn);
-                       return defaultRtn ? defaultRtn : internalComponentErr;
+                       return defaultRtn ? defaultRtn : errSecInternalComponent;
        }
 }
        }
 }
index 1d705d92ba83f7958f86542b6ba6903e34b5c475..17bedd862011bdbcba9033ec9bf8f67c8fefe98d 100644 (file)
@@ -48,7 +48,7 @@ void cmsCopyCmsData(
  * Append a CF type, or the contents of an array, to another array.
  * destination array will be created if necessary.
  * If srcItemOrArray is not of the type specified in expectedType,
  * Append a CF type, or the contents of an array, to another array.
  * destination array will be created if necessary.
  * If srcItemOrArray is not of the type specified in expectedType,
- * paramErr will be returned. 
+ * errSecParam will be returned. 
  */
 OSStatus cmsAppendToArray(
        CFTypeRef srcItemOrArray,
  */
 OSStatus cmsAppendToArray(
        CFTypeRef srcItemOrArray,
@@ -65,8 +65,8 @@ OSStatus cmsRtnToOSStatus(
 
 #define CFRELEASE(cfr) if(cfr != NULL) { CFRelease(cfr); }
 
 
 #define CFRELEASE(cfr) if(cfr != NULL) { CFRelease(cfr); }
 
-#define DEBUG 0
-#if            DEBUG
+#define CMS_DEBUG 0
+#if    CMS_DEBUG
 #define ASSERT(s)                      assert(s)
 #define CSSM_PERROR(s, r)      cssmPerror(s, r)
 #define dprintf(args...)       printf(args)
 #define ASSERT(s)                      assert(s)
 #define CSSM_PERROR(s, r)      cssmPerror(s, r)
 #define dprintf(args...)       printf(args)
index 3ee9381343e8ec95f5155fed4ada4e54bf0d8947..970ceabaee803bdf2389300d3434f7e6ae2d899b 100644 (file)
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0420;
+                               LastUpgradeCheck = 0500;
                        };
                        buildConfigurationList = C263E67909A2971B000043F1 /* Build configuration list for PBXProject "libsecurity_cms" */;
                        compatibilityVersion = "Xcode 3.2";
                        };
                        buildConfigurationList = C263E67909A2971B000043F1 /* Build configuration list for PBXProject "libsecurity_cms" */;
                        compatibilityVersion = "Xcode 3.2";
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446178146E984400B12992 /* debug.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446178146E984400B12992 /* debug.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844617A146E984400B12992 /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844617A146E984400B12992 /* release.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446179146E984400B12992 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446179146E984400B12992 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446179146E984400B12992 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 18446179146E984400B12992 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
diff --git a/libsecurity_codesigning/CodeSigningHelper/CodeSigningHelper-Info.plist b/libsecurity_codesigning/CodeSigningHelper/CodeSigningHelper-Info.plist
new file mode 100644 (file)
index 0000000..49b4751
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>English</string>
+       <key>CFBundleExecutable</key>
+       <string>${EXECUTABLE_NAME}</string>
+       <key>CFBundleIdentifier</key>
+       <string>${PRODUCT_NAME}</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundleName</key>
+       <string>${PRODUCT_NAME}</string>
+       <key>CFBundlePackageType</key>
+       <string>XPC!</string>
+       <key>CFBundleShortVersionString</key>
+       <string>1.0</string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>1</string>
+       <key>XPCService</key>
+       <dict>
+               <key>ServiceType</key>
+               <string>System</string>
+       </dict>
+</dict>
+</plist>
diff --git a/libsecurity_codesigning/CodeSigningHelper/com.apple.CodeSigningHelper.sb b/libsecurity_codesigning/CodeSigningHelper/com.apple.CodeSigningHelper.sb
new file mode 100644 (file)
index 0000000..4326bde
--- /dev/null
@@ -0,0 +1,16 @@
+;;;;;; Copyright (c) 2012 Apple Inc.  All Rights reserved.
+;;;;;;
+;;;;;; WARNING: The sandbox rules in this file currently constitute
+;;;;;; Apple System Private Interface and are subject to change at any time and
+;;;;;; without notice. The contents of this file are also auto-generated and
+;;;;;; not user editable; it may be overwritten at any time.
+
+(version 1)
+
+(deny default)
+(import "system.sb")
+(import "com.apple.corefoundation.sb")
+
+(corefoundation)
+
+(allow file-read*)
diff --git a/libsecurity_codesigning/CodeSigningHelper/main.c b/libsecurity_codesigning/CodeSigningHelper/main.c
new file mode 100644 (file)
index 0000000..37dd25b
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2012 Apple Computer, Inc. All Rights Reserved.
+ * 
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * A simple XPCService that returns the Info.plist for a specific pid,
+ * the use-case is is for service that is not running as the user or
+ * in a sandbox and can't access the file directly.
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreFoundation/CFBundlePriv.h>
+#include <sys/param.h>
+#include <xpc/xpc.h>
+#include <syslog.h>
+#include <assert.h>
+#include <libproc.h>
+#include <sandbox.h>
+#include <syslog.h>
+
+static CFDataRef
+CopyDataFromURL(CFURLRef url)
+{
+       CFReadStreamRef stream = CFReadStreamCreateWithFile(NULL, url);
+       if (stream == NULL)
+               return NULL;
+
+       if (!CFReadStreamOpen(stream)) {
+               CFRelease(stream);
+               return NULL;
+       }
+
+        CFMutableDataRef data = CFDataCreateMutable(NULL, 0);
+        if (data == NULL) {
+                CFRelease(stream);
+                return NULL;
+        }
+
+        UInt8 buf[4096];
+
+        while (1) {
+                /* limit to 100k */
+                if (CFDataGetLength(data) > 100 * 1024) {
+                       syslog(LOG_ERR, "refusing to handle back Info.plist that is more then 100K");
+                        CFRelease(stream);
+                        CFRelease(data);
+                        return NULL;
+                }
+                CFIndex readBytes = CFReadStreamRead(stream, buf, sizeof(buf));
+                if (readBytes == 0) {
+                        break;
+                } else if (readBytes <= 0) {
+                        CFRelease(data);
+                        CFRelease(stream);
+                        return NULL;
+                }
+
+                assert(readBytes <= sizeof(buf));
+                CFDataAppendBytes(data, (void *)buf, readBytes);
+        }
+
+        CFReadStreamClose(stream);
+        CFRelease(stream);
+
+        return data;
+}
+
+static void
+fetchData(xpc_connection_t peer, xpc_object_t event)
+{
+       CFBundleRef bundle = NULL;
+        char path[MAXPATHLEN];
+        pid_t pid;
+
+        pid = (pid_t)xpc_dictionary_get_int64(event, "pid");
+        if (pid <= 0)
+                return;
+
+        xpc_object_t reply = xpc_dictionary_create_reply(event);
+        if (reply == NULL)
+                return;
+
+        if (proc_pidpath(pid, path, sizeof(path)) == 0) {
+                xpc_dictionary_set_string(reply, "error", "no process for that pid");
+                goto send;
+        }
+        path[sizeof(path) - 1] = '\0';
+
+        CFURLRef url = CFURLCreateFromFileSystemRepresentation(NULL, (const uint8_t *)path, strlen(path), 0);
+        if (url == NULL) {
+                xpc_dictionary_set_string(reply, "error", "failed to create URL");
+                goto send;
+        }
+
+        bundle = _CFBundleCreateWithExecutableURLIfMightBeBundle(NULL, url);
+        CFRelease(url);
+        if (bundle == NULL) {
+                xpc_dictionary_set_string(reply, "error", "Failed to create a bundle");
+                goto send;
+        }
+
+        CFURLRef infoPlistURL = _CFBundleCopyInfoPlistURL(bundle);
+        if (infoPlistURL == NULL) {
+                xpc_dictionary_set_string(reply, "error", "Info.plist missing");
+                goto send;
+        }
+
+        CFDataRef data = CopyDataFromURL(infoPlistURL);
+        CFRelease(infoPlistURL);
+        if (data == NULL) {
+                xpc_dictionary_set_string(reply, "error", "can't get content of Info.plist");
+                goto send;
+        }
+
+        xpc_dictionary_set_data(reply, "infoPlist", CFDataGetBytePtr(data), CFDataGetLength(data));
+        CFRelease(data);
+
+       CFURLRef bundleURL = CFBundleCopyBundleURL(bundle);
+       if (bundleURL == NULL)
+               goto send;
+
+       data = CFURLCreateData(NULL, bundleURL, kCFStringEncodingUTF8, true);
+       CFRelease(bundleURL);
+       if (data == NULL)
+               goto send;
+       
+        xpc_dictionary_set_data(reply, "bundleURL", CFDataGetBytePtr(data), CFDataGetLength(data));
+       CFRelease(data);
+
+send:
+       if (bundle)
+               CFRelease(bundle);
+        xpc_connection_send_message(peer, reply);
+}
+
+
+static void CodeSigningHelper_peer_event_handler(xpc_connection_t peer, xpc_object_t event)
+{
+       xpc_type_t type = xpc_get_type(event);
+       if (type == XPC_TYPE_ERROR)
+                return;
+
+       assert(type == XPC_TYPE_DICTIONARY);
+
+        const char *cmd = xpc_dictionary_get_string(event, "command");
+        if (cmd == NULL) {
+                xpc_connection_cancel(peer);
+        } else if (strcmp(cmd, "fetchData") == 0)
+                fetchData(peer, event);
+        else {
+                syslog(LOG_ERR, "peer sent invalid command %s", cmd);
+                xpc_connection_cancel(peer);
+       }
+}
+
+static void CodeSigningHelper_event_handler(xpc_connection_t peer)
+{
+       xpc_connection_set_event_handler(peer, ^(xpc_object_t event) {
+               CodeSigningHelper_peer_event_handler(peer, event);
+       });
+       xpc_connection_resume(peer);
+}
+
+int main(int argc, const char *argv[])
+{
+        char *error = NULL;
+        if (sandbox_init("com.apple.CodeSigningHelper", SANDBOX_NAMED, &error)) {
+                syslog(LOG_ERR, "failed to enter sandbox: %s", error);
+                exit(EXIT_FAILURE);
+        }
+        xpc_main(CodeSigningHelper_event_handler);
+        return 0;
+}
+
diff --git a/libsecurity_codesigning/antlr2/AUTHORS b/libsecurity_codesigning/antlr2/AUTHORS
new file mode 100644 (file)
index 0000000..7bdc485
--- /dev/null
@@ -0,0 +1,2 @@
+Author:
+  Peter Wells  <pete@yamuna.demon.co.uk>
diff --git a/libsecurity_codesigning/antlr2/ChangeLog b/libsecurity_codesigning/antlr2/ChangeLog
new file mode 100644 (file)
index 0000000..4d8d87a
--- /dev/null
@@ -0,0 +1,815 @@
+Change 499 on 2001/05/31 by klaren@klaren.hawking.dev
+
+   - Ported action.g fixes from C++ to Java action.g. Warnings and errors
+     in actions are now correctly reported in java mode as well.
+   - Ported $lookaheadSet functionality to java mode.
+   - Moved processActionForTreeSpecifiers from CodeGenerator.java to
+     JavaCodeGenerator.java and made it abstract. Added setFileName call
+     to it.
+   - Added a lot of getLine's to calls of processActionForTreeSpecifiers in
+     JavaCodegen.
+   - Moved a number one liner methods to the header file for better inlining.
+   - Added clear methods to the Queue type objects (java/C++).
+   - Added reset methods to the Input/TokenBuffer objects (java/C++).
+   - Added reset methods to the SharedInputState objects (java/C++).
+   - Added to the C++ LexerSharedInputState an initialize function that
+     reinitializes the thing with a new stream.
+   - Added docu.
+
+   - Bugfix: Initialized attribute filename a little bit earlier so error
+         message shows the filename in stead of 'null'.
+
+Change 495 on 2001/05/31 by klaren@klaren.hawking.dev
+
+   Added -h/-help/--help options. Adapted the year range in the copyright in
+   the help message.
+
+Change 494 on 2001/05/29 by klaren@klaren.hawking.dev
+
+   Changed order of equals test a bit to be more efficient.
+
+Change 493 on 2001/05/29 by klaren@klaren.hawking.dev
+
+   Moved some methods a bit around to get better inlining.
+
+Change 492 on 2001/05/22 by klaren@klaren.hawking.dev
+
+   Dug up a mail from Bill Zheng about doxygen. Fixed a few things as a result.
+
+Change 491 on 2001/05/22 by klaren@klaren.hawking.dev
+
+   More tweaks for the ditching of the tokenNames vector. GNU C++ had some
+   trouble with the previous incarnation.
+
+Change 490 on 2001/05/21 by klaren@klaren.hawking.dev
+
+   Changed all remaining "antlr/xxx.hpp" includes to <antlr/xxx.hpp> ones
+   in the header files.
+
+Change 489 on 2001/05/18 by klaren@klaren.hawking.dev
+
+   Missed a few tracer class changes in this one. Also some missing
+   virtuals fixed.
+
+Change 488 on 2001/05/18 by klaren@klaren.hawking.dev
+
+   Removed /** from license comments, they brought doxygen of track.
+   Replaced ANTLR_BEGIN/END_NAMESPACE defines with a
+   ANTLR_CXX_SUPPORTS_NAMESPACE macro, again for doxygen. Here and there some
+   reformatting and reordering.
+
+Change 487 on 2001/05/18 by klaren@klaren.hawking.dev
+
+   Optimizations in Tracer classes (dumped string's). Removed setTokenNames
+   from the support library. Switched tokenNames to use a char* array.
+   Generate NUM_TOKENS attribute in parsers. Added getNumTokens methods to
+   parsers. Changes in MismatchedTokenException to reflect the previous.
+
+Change 486 on 2001/05/18 by klaren@klaren.hawking.dev
+
+   Allow whitespace between $setxxx and following '('.
+
+Change 485 on 2001/05/14 by klaren@klaren.hawking.dev
+
+   And now really fix giving errors... stupid java *snicker*
+
+Change 484 on 2001/05/14 by klaren@klaren.hawking.dev
+
+   Allow whitespace between $setxxx and following '('.
+
+Change 483 on 2001/05/14 by klaren@klaren.hawking.dev
+
+   Give errors when target file/directory not writeable.
+
+Change 482 on 2001/05/11 by klaren@klaren.hawking.dev
+
+   Added config file for doxygen.
+
+Change 480 on 2001/05/11 by klaren@klaren.hawking.dev
+
+   Tagged a bug in the code. (heteroast trouble)
+
+Change 479 on 2001/05/11 by klaren@klaren.hawking.dev
+
+   Added Ernest Pasour's $lookaheadSet feature to the C++ codegen. (This
+   needs to be ported to Java mode). Also cleaned up action.g's error
+   reporting this should also be ported to java mode.
+
+Change 476 on 2001/05/11 by klaren@klaren.hawking.dev
+
+   More fixes for XML I/O. It's a bit tidier now. Some too advanced things
+   removed (ios_base::failure). Embedding custom XML elements in the stream
+   should be possible now.
+
+Change 475 on 2001/05/08 by parrt@parrt.foggy
+
+   made default charbuffer bigger per token.
+
+Change 471 on 2001/04/26 by klaren@klaren.hawking.dev
+
+   Bugfix: in case of a certain order of header actions (pre_include_xx etc.)
+   one header action might overwrite another. Probably only affects C++.
+
+Change 468 on 2001/03/22 by klaren@klaren.hawking.dev
+
+   A few extra ANTLR_API's to make antlr.dll work from other dll's. Thanks
+   to Ernest Passour.
+
+Change 466 on 2001/03/15 by klaren@klaren.hawking.dev
+
+   Fix from Emir Uner for KAI C++ cast string literal to 'const
+   char*' for make_pair.
+
+Change 465 on 2001/03/08 by klaren@klaren.hawking.dev
+
+   Fix for bugreport from Emir Uner, static member const char *
+   initializations are not standard compliant.
+
+Change 464 on 2001/03/05 by klaren@klaren.hawking.dev
+
+   Changes for XML input and output. Restructuring of ASTFactory and some
+   fixes for heterogeneous AST's.
+
+Change 463 on 2001/02/05 by klaren@klaren.hawking.dev
+
+   Improved exception handling in trace routines of parser. Patch submitted
+   by John Fremlin. Tracer class now catch exceptions from lexer. Fixed
+   forgotten message in BitSet.cpp.
+
+Change 462 on 2001/02/05 by klaren@klaren.hawking.dev
+
+   Improved errormessage. Now says unexpected end of file and stuff like that.
+
+Change 461 on 2001/01/31 by klaren@klaren.hawking.dev
+
+   Changed the position of the init actions for (..)* (..)+ to just inside
+   the loop handling the closure. This way we can check EOF conditions in the
+   init action for each loop invocation.
+
+Change 460 on 2001/01/31 by klaren@klaren.hawking.dev
+
+   Fixed typo in error message.
+
+Change 458 on 2001/01/17 by klaren@klaren.hawking.dev
+
+   Removed dos newlines.
+
+Change 457 on 2001/01/15 by klaren@klaren.hawking.dev
+
+   Removed the superfluous '// line xxx' comments in genHashLines=false case.
+
+Change 454 on 2001/01/11 by klaren@klaren.hawking.dev
+
+   Updated the changelog and fixed buglet in changelog script.
+
+Change 453 on 2001/01/11 by klaren@klaren.hawking.dev
+
+   Tweaked the make_change_log script to include both my dev depot as well
+   as the main branch.
+
+Change 452 on 2001/01/11 by klaren@klaren.hawking.dev
+
+   Changes to let ANTLR only overwrite a file if it really changes. (Mainly
+   for C++ mode). With supporting changes in mkxxxjar batch files.
+
+Change 451 on 2001/01/11 by klaren@klaren.hawking.dev
+
+   Changed the charName in C++ mode and NoViableAltForCharException in java
+   mode so that only printable characters are printed and non printable ones
+   get 'hexdumped'.
+
+Change 450 on 2001/01/10 by klaren@klaren.hawking.dev
+
+   Fixed some typo's in javadoc comments.
+
+Change 449 on 2001/01/08 by klaren@klaren.hawking.dev
+
+   Removed StdAfx.h from the .dsp file.
+
+Change 448 on 2001/01/08 by klaren@klaren.hawking.dev
+
+   Added implementations for getLAChars and getMarkedChars.
+
+Change 447 on 2001/01/05 by klaren@klaren.hawking.dev
+
+   Small fix to the genBitSets method of CppCodeGenerator now the generated
+   sets are also dumped for lexers.
+
+Change 446 on 2000/12/18 by klaren@klaren.hawking.dev
+
+   Changes for MSCV DLL building. Now also includes dsp/dsw files.
+   Contributed by Stephen Naughton.
+
+Change 444 on 2000/12/12 by klaren@klaren.hawking.dev
+
+   Added <string> include. (Needed for new gcc version 2.97)
+
+Change 441 on 2000/12/05 by klaren@klaren.hawking.dev
+
+   Fixed problems with buggy tolower (truncating -1 (EOF) to 0xff)
+   functions together with STLport/HPUX also reverted fix 422 since this
+   one also catches that.
+
+Change 440 on 2000/11/30 by klaren@klaren.hawking.dev
+
+   Fixed typo in code generated for $setText.
+
+Change 439 on 2000/11/22 by klaren@klaren.hawking.dev
+
+   Few minor tweaks. And removed my name from the generated author section
+   a bit too much copy'n'paste.
+
+Change 438 on 2000/11/20 by klaren@klaren.hawking.dev
+
+   Fixed bug with C/C++ preprocessor constructs (#if's etc). Also changed
+   code generated for $setText to be surrounded by '{}'.
+
+Change 437 on 2000/11/20 by klaren@klaren.hawking.dev
+
+   SGI Irix 6.5.10 MIPSPro compiler support contributed by Anna Winkler.
+
+Change 436 on 2000/11/20 by klaren@klaren.hawking.dev
+
+   Virtualized a most methods of Parser and LLkParser (as requested by
+   Alexander Lenski)
+
+Change 434 on 2000/11/09 by klaren@klaren.hawking.dev
+
+   First stab at a docbook codegenerator. It now produces something that get's
+   parsed by jade and gives pretty ok HTML output.
+
+Change 433 on 2000/11/08 by klaren@klaren.hawking.dev
+
+   Cleaned up some superfluous methods.
+
+Change 432 on 2000/11/08 by klaren@klaren.hawking.dev
+
+   Cleaned up generated HTML added quoting for special entities (probably
+   still missed some). Removed printing of parameters, returns, syntactic
+   and semantic actions since these obscure the output. It's now HTML 4.01
+   Transitional compliant it seems.
+
+Change 427 on 2000/10/23 by klaren@klaren.hawking.dev
+
+   Virtualized destructors in xxSharedInputState. This to support
+   overloading. By request of Alexander Lenski.
+
+Change 426 on 2000/10/19 by klaren@klaren.hawking.dev
+
+   Incorporated bugfix suggested by Joe Comuzzi. Fixes ommission of
+   semantic predicates in the big unicode case.
+
+Change 425 on 2000/10/19 by klaren@klaren.hawking.dev
+
+   Michael Schmitt's changes for a better exception hierarchy.
+
+Change 424 on 2000/10/19 by klaren@klaren.hawking.dev
+
+   Cleaned up generated code a bit. Removed excess constructors etc.
+
+Change 422 on 2000/10/03 by klaren@klaren.hawking.dev
+
+   Fix for VC++ 6.0 bug with tolower and setlocale
+
+Change 421 on 2000/10/03 by klaren@klaren.hawking.dev
+
+   Integrate 2.7.1 main line into development version.
+
+Change 412 on 2000/10/01 by parrt@parrt.foggy
+
+   changes to prevent Tool from runtime jar
+
+Change 410 on 2000/10/01 by parrt@parrt.foggy
+
+   hetero tree labels are of the specified type if any instead of AST
+
+Change 409 on 2000/10/01 by parrt@parrt.foggy
+
+   updated output of .g files
+
+Change 407 on 2000/10/01 by parrt@parrt.foggy
+
+   added column tracking example, updated commontoken to print col.
+
+Change 405 on 2000/09/27 by parrt@parrt.foggy
+
+   changed type
+
+Change 401 on 2000/09/27 by klaren@klaren.hawking.main
+
+   ChangeLog updated. + tweak to script.
+
+Change 400 on 2000/09/27 by klaren@klaren.hawking.main
+
+   Made little TCL script to pretty print a ChangeLog with C++ stuff.
+
+Change 399 on 2000/09/27 by klaren@klaren.hawking.main
+
+   Fixed generating too many ASTNULL checks in wrong places.
+
+Change 397 on 2000/09/27 by klaren@klaren.hawking.main
+
+   Some *UGLY* fixes for the last typecasting problems in Cpp codegen. It
+   now works. In 2.7.2 or later I'll fix this in a nice way.
+
+Change 394 on 2000/09/26 by klaren@klaren.hawking.main
+
+   Prefixed Unicode optimization checks with a ASTNULL check.
+
+Change 393 on 2000/09/25 by klaren@klaren.hawking.main
+
+   Bumped up the version no from 2.7.1a4 to 2.7.1.
+
+Change 381 on 2000/09/24 by parrt@parrt.foggy
+
+   updated to use addElement
+
+Change 380 on 2000/09/24 by parrt@parrt.foggy
+
+   integrating ric's stuff into main
+
+Change 378 on 2000/09/23 by klaren@klaren.hawking.dev
+
+   Forgot another ANTLR_USE_NAMESPACE macro.
+
+Change 377 on 2000/09/22 by klaren@klaren.hawking.dev
+
+   More todo's collected from my mailbox..
+
+Change 372 on 2000/09/22 by klaren@klaren.hawking.dev
+
+   Updated.
+
+Change 371 on 2000/09/22 by klaren@klaren.hawking.dev
+
+   More TODO's...
+
+Change 370 on 2000/09/22 by klaren@klaren.hawking.dev
+
+   Added nested namespace support submitted by David Wagner.
+
+Change 369 on 2000/09/22 by klaren@klaren.hawking.dev
+
+   Bug fix for #ast_in and #( #ast_in ) differences. Split of
+   actions/java/action.g into a java and cpp part. C++-isms removed from java
+   part. Added support in C++ part for some_method(static_cast<sumthin>(#ast)).
+
+Change 367 on 2000/09/22 by klaren@klaren.hawking.dev
+
+   Port of Unicode optimizations from java. Fixes for custom AST usage.
+
+Change 366 on 2000/09/22 by klaren@klaren.hawking.dev
+
+   Implemented missing initializes to CAWHT for Sun CC 6.0 and fixed throw
+   out_of_range for STL_PORT in BitSet.cpp.
+
+Change 363 on 2000/09/13 by parrt@parrt.foggy
+
+   set initial column to 1 instead of 0
+
+Change 362 on 2000/09/13 by klaren@klaren.hawking.dev
+
+   Some bugfixes for getASTCreateString( ... ) hopefully all mismatches between
+   astFactory.create and it's parameters are fixed. (Maybe even a speed
+   improvement)
+
+Change 360 on 2000/09/13 by klaren@klaren.hawking.dev
+
+   Borland C++ builder 4.0 project files for antlr.lib donated by Ross Bencina
+
+Change 358 on 2000/09/11 by klaren@klaren.hawking.dev
+
+   Removed a superfluous typename (caused problem with Irix Mips compiler)
+
+Change 349 on 2000/09/08 by klaren@klaren.hawking.dev
+
+   More configure tweaks. Some libtool enhancements added.
+
+Change 348 on 2000/09/07 by klaren@klaren.hawking.main
+
+   Small improvement in constructor of CommonAST.
+
+Change 346 on 2000/09/07 by klaren@klaren.hawking.dev
+
+   Miniscule fix for Borland C++Builder 4.0/C++ 5.4. (extra parens)
+
+Change 344 on 2000/09/06 by klaren@klaren.hawking.main
+
+   Fixed missing namespace in generated TreeParsers as reported by Ross
+   Bencina.
+
+Change 343 on 2000/09/06 by klaren@klaren.hawking.dev
+
+   Fixed namespace mishap with generated TreeParser constructors as reported
+   by Ross Bencina.
+
+Change 342 on 2000/09/06 by klaren@klaren.hawking.dev
+
+   Some small optimizations. And a maybe fix for Borland compiler warning.
+
+Change 341 on 2000/09/06 by klaren@klaren.hawking.main
+
+   Miniscule fix for Borland C++Builder 4.0/C++ 5.4. (extra parens)
+
+Change 340 on 2000/09/05 by mika@y0
+
+   Sather code generation/runtime catching up with Java bug fixes/enhancements
+
+Change 338 on 2000/09/03 by parrt@parrt.foggy
+
+   cleaned up formatting
+
+Change 336 on 2000/09/03 by parrt@parrt.foggy
+
+   optimized out the large unicode sets from switches.
+
+Change 335 on 2000/09/03 by parrt@parrt.foggy
+
+   up'd version to 2.7.1
+
+Change 334 on 2000/09/03 by parrt@parrt.foggy
+
+   added throws option for rules
+
+Change 330 on 2000/08/30 by klaren@klaren.hawking.dev
+
+   Small 'fix' to RecognitionException getFileLineString.
+
+Change 325 on 2000/08/29 by klaren@klaren.hawking.dev
+
+   Shut a few compiler warnings up.
+
+Change 323 on 2000/08/24 by klaren@klaren.hawking.dev
+
+   importVocab statements now cause antlr to look in $PWD first for the
+   imported vocabulary files, and if that fails, to check in the directory
+   specified by the '-o <output_dir>' command-line argument
+
+Change 322 on 2000/08/24 by klaren@klaren.hawking.dev
+
+   More typecasts for nullAST's. (Should be the last)
+
+Change 319 on 2000/08/23 by klaren@klaren.hawking.dev
+
+   Michael Schmitt found a missing static_cast in the generated C++ code.
+
+Change 318 on 2000/08/22 by klaren@klaren.hawking.dev
+
+   So many things to do... <sigh>
+
+Change 317 on 2000/08/22 by klaren@klaren.hawking.main
+
+   Updated changelog for a5 (or was it 2.7.1) release..
+
+Change 316 on 2000/08/22 by klaren@klaren.hawking.main
+
+   All kinds of small Makefile/configure tweaks. All gcc-isms should be
+   gone now.
+
+Change 315 on 2000/08/21 by bob@bob.melvin
+
+   importVocab statements now cause antlr to look in $PWD first
+   for the imported vocabulary files, and if that fails, to
+   check in the directory specified by the '-o <output_dir>'
+   command-line argument
+
+Change 310 on 2000/08/16 by klaren@klaren.hawking.dev
+
+   Fixed a bug concerning one of the nullAST initialization strings being unset.
+
+Change 309 on 2000/08/15 by klaren@klaren.hawking.main
+
+   Integrate bugfixes from klaren.dev to MismatchedChar/TokenException.
+
+Change 308 on 2000/08/15 by klaren@klaren.hawking.dev
+
+   Fixes for some cut'n'paste'o's in MismatchedToken/CharException (error
+   messages are ok again)
+
+Change 307 on 2000/08/15 by klaren@klaren.hawking.dev
+
+   Added todo list.
+
+Change 306 on 2000/08/14 by klaren@klaren.hawking.dev
+
+   Configure fixes and a small cleanup.
+
+Change 305 on 2000/08/14 by klaren@klaren.hawking.dev
+
+   Got rid of the last member template. At the expense of some casts.
+
+Change 304 on 2000/08/11 by klaren@klaren.hawking.dev
+
+   Last changes for ASTLabelType support. It seems to work now.
+
+Change 303 on 2000/08/10 by klaren@klaren.kronecker.dev
+
+   Changes for better support of ASTLabelType in C++ grammars.
+
+Change 302 on 2000/08/08 by klaren@klaren.kronecker.dev
+
+   Sync with main tree.
+
+Change 301 on 2000/08/08 by klaren@klaren.kronecker.main
+
+   Fix for the $setText bug in C++ code generation.
+   More C++ fixes to action.g. Allow '->' in $setText arguments and some other places.
+
+Change 298 on 2000/08/08 by klaren@klaren.kronecker.dev
+
+   Integrate main branch with playground.
+
+Change 297 on 2000/08/07 by klaren@klaren.kronecker.main
+
+   Fixes for namespace/namespaceAntlr/namespaceStd/genHashLines options.
+
+Change 296 on 2000/08/07 by klaren@klaren.kronecker.main
+
+   Virtualized all functions that someone should want to override. Probably
+   necessary for heteroAST stuff.
+
+Change 291 on 2000/08/07 by klaren@klaren.kronecker.main
+
+   Some tweaks to configure.in and Makefile.am's. Fix for CXXFLAGS being
+   set incorrectly when not using gcc.
+
+Change 290 on 2000/08/05 by klaren@klaren.kronecker.main
+
+   Updated prototype of toLower to definition in cpp file. It seems I
+   messed them up a while back.
+
+Change 289 on 2000/08/05 by klaren@klaren.kronecker.main
+
+   Added namespace macro to out_of_range exception.
+
+Change 288 on 2000/07/28 by parrt@parrt.foggy
+
+   re-added toLower return type fix
+
+Change 285 on 2000/07/19 by klaren@klaren.kronecker.main
+
+   Fixed thinko.
+
+Change 284 on 2000/07/19 by klaren@klaren.kronecker.main
+
+   Dumped output of p4 changes -l into it...
+
+Change 283 on 2000/07/19 by klaren@klaren.kronecker.main
+
+   Fix for bug found by Michael Ebner. Bitset size was not increased in add method.
+
+Change 280 on 2000/07/19 by klaren@klaren.kronecker.main
+
+   Made namespaceAntlr, namespaceStd and genHashlines options file-level
+   options. Removed nameSpace member from Tool class all is now handled in
+   CppCodegenerator.java.
+
+Change 279 on 2000/07/18 by klaren@klaren.kronecker.main
+
+   Added -diagnostic and -glib options to the usage message.
+
+Change 278 on 2000/07/18 by klaren@klaren.kronecker.main
+
+   Java changes for indented traceIn/Out stuff.
+
+Change 276 on 2000/07/18 by klaren@klaren.kronecker.main
+
+   C++ Changes for the indented traceXXXX output as invented by Monty Zukowski
+
+Change 275 on 2000/07/18 by klaren@klaren.kronecker.main
+
+   Added missing initializer in generated code for TreeParser
+
+Change 272 on 2000/07/17 by klaren@klaren.kronecker.main
+
+   Another workspace for MSVC6 has support for dll's (for version 2.6.1).
+
+Change 271 on 2000/07/17 by klaren@klaren.kronecker.main
+
+   New autoconf/automake stuff for the C++ support library.
+
+Change 270 on 2000/07/17 by klaren@klaren.kronecker.main
+
+   Fixed error within the NO_STATIC_CONSTS #ifdef
+
+Change 269 on 2000/07/17 by klaren@klaren.kronecker.main
+
+   Move C++ files to lib/cpp/src as first step for autoconf setup
+
+Change 268 on 2000/07/17 by klaren@klaren.kronecker.main
+
+   Add contrib dir and Microsoft Visual C++ 6.0 projects supplied by John Millaway
+
+Change 262 on 2000/07/16 by parrt@parrt.foggy
+
+   changed version to 2.7.1a4
+
+Change 261 on 2000/07/16 by parrt@parrt.foggy
+
+   added constructors for this class
+
+Change 260 on 2000/07/14 by klaren@klaren.kronecker.main
+
+   Fixed crashbugs/typos in constructors of Mismatched[Token|Char]Exception
+
+Change 259 on 2000/07/13 by parrt@parrt.foggy
+
+   cutting ric's branch
+
+Change 258 on 2000/07/10 by parrt@parrt.foggy
+
+   fixes per klaren
+
+Change 255 on 2000/07/09 by parrt@parrt.foggy
+
+   removed magelang from tag line
+
+Change 252 on 2000/07/09 by parrt@parrt.foggy
+
+   reformatted
+
+Change 251 on 2000/07/04 by mika@y0
+
+   Reflecting change to the Java action lexer in the Sather action lexer
+
+Change 249 on 2000/07/04 by parrt@parrt.foggy
+
+   changed version number
+
+Change 248 on 2000/07/04 by parrt@parrt.foggy
+
+   Ric Klaren's changes to C++ lib
+
+Change 247 on 2000/07/04 by parrt@parrt.foggy
+
+   Ric Klaren's changes for namespaces
+
+Change 246 on 2000/06/16 by mika@y0
+
+   reflecting changes antlr/CodeGenerator.java #3 -> #4
+
+Change 245 on 2000/06/16 by mika@y0
+
+   reflecting changes in antlr/actions/java/action.g #3 -> #4
+
+Change 242 on 2000/06/06 by parrt@parrt.foggy
+
+   fixed my new method addition to handle empty input case correctly
+
+Change 241 on 2000/06/06 by parrt@parrt.foggy
+
+   allows whitespace now after ( in $setType.
+
+Change 240 on 2000/06/03 by parrt@parrt.foggy
+
+   fixed a bug where duplicate grammars caused an exception
+
+Change 239 on 2000/06/03 by parrt@parrt.foggy
+
+   adjusted so it works; header actions got converted to Token objects from Strings; lots of cast problems and then null ptr exceptions.
+
+Change 238 on 2000/06/03 by parrt@parrt.foggy
+
+   made it ignore zero-length strings for processActionForTreeSpecifiers
+
+Change 237 on 2000/06/03 by parrt@parrt.foggy
+
+   had to run ANTLR on antlr.g to make it compile.
+
+Change 236 on 2000/06/03 by parrt@parrt.foggy
+
+   changed refs to headerActions to imply Token not String.
+
+Change 235 on 2000/05/31 by pete@pete.linux
+
+   More changes to support #line generation in C++ (from Ric Klaren)
+
+Change 233 on 2000/05/30 by mika@y0
+
+   Bug fixes from Gilbert Roulot
+
+Change 232 on 2000/05/29 by parrt@parrt.foggy
+
+   improved diagnostic DEBUG_ANALYZER output a lot and fixed a nasty FOLLOW cycle computation bug.  I was being too aggressive with my locking; i locked block end nodes even when not computing FIRST(block start).
+
+Change 231 on 2000/05/29 by parrt@parrt.foggy
+
+   added code to print out FOLLOW set for rule at end
+
+Change 230 on 2000/05/29 by parrt@parrt.foggy
+
+   added code you can uncomment to print out grammar after code gen
+
+Change 229 on 2000/05/29 by parrt@parrt.foggy
+
+   changed version to 2.7.1a2
+
+Change 228 on 2000/05/29 by parrt@parrt.foggy
+
+   added toString method to print out rules
+
+Change 227 on 2000/05/29 by parrt@parrt.foggy
+
+   added code to dump lookahead sets for each alt in toString()
+
+Change 220 on 2000/05/29 by parrt@parrt.foggy
+
+   changed char to int for toLower
+
+Change 219 on 2000/05/28 by pete@pete.linux
+
+   Mirroring Java changes
+
+Change 218 on 2000/05/28 by pete@pete.linux
+
+   Cleaned up the #line generator a little.
+
+Change 217 on 2000/05/27 by parrt@parrt.foggy
+
+   bug fix: wasn't providing always 4 digits for escapeChar.
+
+Change 216 on 2000/05/27 by parrt@parrt.foggy
+
+   added checking for unterminated rules
+
+Change 215 on 2000/05/27 by parrt@parrt.foggy
+
+   added column tracking support; tabs are counted as 1
+
+Change 214 on 2000/05/27 by parrt@parrt.foggy
+
+   allow comments after tokens/options etc...
+
+Change 213 on 2000/05/27 by parrt@parrt.foggy
+
+   setInputState was actually getInputState :(
+
+Change 212 on 2000/05/27 by parrt@parrt.foggy
+
+   updated to handle } in tokens{}
+
+Change 211 on 2000/05/27 by parrt@parrt.foggy
+
+   had same bug as JavaCodeGenerator related to ~(A|B)
+
+Change 208 on 2000/05/27 by parrt@parrt.foggy
+
+   updated version
+
+Change 205 on 2000/05/24 by pete@pete.linux
+
+   Add support for Metrowerks Codewarrior
+
+Change 203 on 2000/05/22 by pete@pete.linux
+
+   Fix for multithreading from Jan Mikkelsen
+
+Change 202 on 2000/05/21 by pete@pete.linux
+
+   Merged in some fixes from Ric Klaren for tracing TreeParsers, cleaner namespace
+   code, and #line generation.
+
+Change 201 on 2000/05/21 by pete@pete.linux
+
+   Added destructors with empty throw specs, as suggested by Dan Field.
+
+Change 200 on 2000/05/21 by pete@pete.linux
+
+   Various performance improvements, mostly from Eric Dumas.
+
+Change 183 on 2000/02/08 by pete@pete.linux
+
+   Added support for Sun CC 5.0 (from Michael Schmitt)
+
+Change 182 on 2000/02/08 by pete@pete.linux
+
+   Fix a couple of minor problems with C++ generation (noted by Michael Schmitt)
+
+Change 162 on 2000/01/20 by mika@y0
+
+   heterogeneous AST change.  not sure if correct.
+
+Change 153 on 2000/01/19 by parrt@parrt.foggy
+
+   forgot to propogate b1 changes to mkjar etc..
+
+Change 151 on 2000/01/19 by parrt@parrt.foggy
+
+   pushing changes back into main/main from fixed tree stuff
+
+Change 142 on 2000/01/19 by parrt@parrt.foggy
+
+   propogating mika's changes forward
+
+Change 132 on 2000/01/18 by parrt@parrt.foggy
+
+   setting type to ktext for everything
+
+Change 131 on 2000/01/18 by parrt@parrt.foggy
+
+   from dev back to main
+
+Change 1 on 1999/12/13 by parrt@parrt.foggy
+
+   adding 2.6.0 from antlr site as initial main line
+
diff --git a/libsecurity_codesigning/antlr2/LICENSE.txt b/libsecurity_codesigning/antlr2/LICENSE.txt
new file mode 100644 (file)
index 0000000..0ec09a9
--- /dev/null
@@ -0,0 +1,31 @@
+\r
+SOFTWARE RIGHTS\r
+\r
+ANTLR 1989-2006 Developed by Terence Parr
+Partially supported by University of San Francisco & jGuru.com\r
+\r
+We reserve no legal rights to the ANTLR--it is fully in the\r
+public domain. An individual or company may do whatever\r
+they wish with source code distributed with ANTLR or the\r
+code generated by ANTLR, including the incorporation of\r
+ANTLR, or its output, into commerical software.\r
+\r
+We encourage users to develop software with ANTLR. However,\r
+we do ask that credit is given to us for developing\r
+ANTLR. By "credit", we mean that if you use ANTLR or\r
+incorporate any source code into one of your programs\r
+(commercial product, research project, or otherwise) that\r
+you acknowledge this fact somewhere in the documentation,\r
+research report, etc... If you like ANTLR and have\r
+developed a nice tool with the output, please mention that\r
+you developed it using ANTLR. In addition, we ask that the\r
+headers remain intact in our source code. As long as these\r
+guidelines are kept, we expect to continue enhancing this\r
+system and expect to make other tools available as they are\r
+completed.\r
+\r
+The primary ANTLR guy:\r
+\r
+Terence Parr\r
+parrt@cs.usfca.edu
+parrt@antlr.org
diff --git a/libsecurity_codesigning/antlr2/Makefile.in b/libsecurity_codesigning/antlr2/Makefile.in
new file mode 100644 (file)
index 0000000..3d3c67a
--- /dev/null
@@ -0,0 +1,19 @@
+###############################################################################
+# $Id:$
+###############################################################################
+## do not change this value 
+subdir=lib/cpp
+
+## get configured autoconf variables
+@stdvars@
+
+## Your own variables shall go here ..
+
+# Docs
+DOXY_TARGET=doxygen.cfg
+DOXY_GENDIR=gendoc/html
+
+@stdmake@
+
+
+@stddeps@
diff --git a/libsecurity_codesigning/antlr2/README b/libsecurity_codesigning/antlr2/README
new file mode 100644 (file)
index 0000000..f6e6089
--- /dev/null
@@ -0,0 +1,191 @@
+ANTLR C++ Support Libraries Additional Notes
+
+1.1 Using Microsoft Visual C++
+
+Currently this is still (or again) somewhat experimental. MSVC is not the
+development platform and I don't have access to the compiler currently.
+YMMV
+
+Make sure you compile the library *and* your project with the same
+settings. (multithreaded/debug/etc.)
+
+Visual C++ 6 only is supported for static builds. Some hacking and STLPort
+is needed to build a DLL (only for experts).
+
+Visual C++ 7.0 and 7.1 should support both static and DLL builds (DLL
+builds might be broken). In general the main problem is getting the right
+template instantiations into the DLL. For 7.0 you might have to tweak the
+list in lib/cpp/src/dll.cpp. I'm told 7.1 does not need this.
+
+For a static build (works probably best)
+
+1. Create a win32 static library project.
+2. Enable RTTI. (Run Time Type Information)
+3. Add the source files from <installpath>/antlr/lib/cpp/src to the project
+   (except dll.cpp) put <installpath>/antlr/lib/cpp in the search path for
+   include files.
+
+For the DLL build (MSVC 7.0 tested)
+
+* Project settings ("create new project" dialogs)
+      - Win32 project
+        - Application Settings
+          - Application type
+            - DLL
+          - Additional options
+            - Export symbols
+* Project properties (change defaults to)
+      - Configuration Properties
+        - C/C++
+          - General
+            - Additional Include Directories
+              - drive:\antlr-2.7.2\lib\cpp
+          - Preprocessor
+            - Preprocessor Definitions
+              - WIN32;_DEBUG;_WINDOWS;_USRDLL;ANTLR_EXPORTS
+            - Code Generation
+              - Runtime Library
+                - Multi-threaded Debug DLL (/MDd)
+              - Enable Function-Level Linking:
+                - Yes
+            - Language
+              - Enable Run-Time Type Info
+                - Yes
+            - Precompiled Headers
+              - Create/Use Precompiled Headers
+
+NOTE: Do not use the antlr generated and support library in a multithreaded
+way. It was not designed for a multithreaded environment.
+
+1.3 Building with GCJ
+
+NOTE: outdated the new Makefiles do not support this anymore.
+
+It is also possible to build a native binary of ANTLR. This is somewhat
+experimental and can be enabled by giving the --enable-gcj option to
+configure. You need a recent GCC to do this and even then the constructed
+binary crashes on some platforms.
+
+2. Tested Compilers for this release
+
+Don't get worried if your favourite compiler is not mentioned here. Any
+somewhat recent ISO compliant C++ compiler should have little trouble with
+the runtime library.
+
+*NOTE* this section was not updated for the new configure script/Makefiles some of the things listed here to pass different flags to configure may not work anymore. Check INSTALL.txt or handedit generated scripts after configure.
+
+2.1 Solaris
+
+2.1.1 Sun Workshop 6.0
+
+Identifies itself as:
+
+   CC: Sun WorkShop 6 2000/08/30 C++ 5.1 Patch 109490-01
+
+Compiles out of the box configure using:
+
+   CXX=CC CC=cc AR=CC ARFLAGS="-xar -o" ./configure
+
+Use CC to make the archive to ensure bundling of template instances. Check
+manpage for details.
+
+2.1.2 GCC
+
+Tested 3.0.4, 3.2.1, 3.2.3, 3.3.2, 3.4.0.
+
+All tested gcc are using a recent GNU binutils for linker and assembler.
+You will probably run into trouble if you use the solaris
+linker/assembler.
+
+2.2 Windows
+
+2.2.1 Visual C++
+
+Visual C++ 6.0 reported to work well with static build. DLL build not
+supported (reported to work when using STLPort in previous ANTLR versions).
+I heart that in some cases there could be problems with precompiled headers
+and the use of normal '/' in the #include directives (with service pack 5).
+
+Visual C++ 7.0 reported to work, might need some tweaks for DLL builds due
+to some shuffling around in the code.
+
+Visual C++ 7.1 reported to work, might need some tweaks, see above.
+
+My current guess is that DLL builds are all over the line broken. A
+workaround is to make a DLL from the complete generated parser including
+the static ANTLR support library.
+
+2.2.2 Cygwin/MinGW
+
+Not expecting any big problems maybe some tweaks needed in configure.
+
+3. Old notes for a number of compilers
+
+3.1 SGI Irix 6.5.10 MIPSPro compiler
+
+You can't compile ANTLR with the MIPSPro compiler on anything < 6.5.10
+because SGI just fixed a big bug dealing with namespaces in that release.
+
+Note: To get it to compile do basically the following:
+
+   CC=cc CXX=CC CXXFLAGS=-LANG:std ./configure --prefix=/usr/local/antlr
+
+Note probably dates back to 2.7.0-2.7.1 era.
+
+3.2 Sun CC 5
+
+It may be you'll have to change one or two static_cast<char*>()'s to a
+C-style cast. (think that's a compiler bug)
+
+Configure using:
+
+   CXX=CC CC=cc RANLIB="CC -xar" ./configure
+
+The custom ranlib is needed to get the template instances into the archive.
+Check manpages. Maybe the Sun CC 6 instructions above will work as well.
+
+3.3 GCC on some platforms (Alpha Tru64)
+
+The -pipe option not supported it seems. Configure using:
+
+CFLAGS="-W -Wall" ./configure
+
+Or remove the -pipe's from the generated scripts/Config.make.
+
+4. IT DOESN'T WORK!?
+
+4.1 Compile problems
+
+The ANTLR code uses some relatively new features of C++ which not all
+compilers support yet (such as namespaces, and new style standard headers).
+
+At the moment, you may be able to work around the problem with a few nasty
+tricks:
+
+Try creating some header files like 'iostream' just containing:
+
+#include <iostream.h>
+
+and compile with an option to define away the word 'std', such as
+
+CC .... -Dstd= ....
+
+Also in the antlr subdirectory there's a file config.hpp. Tweak this one to
+enable/disable the different bells and whistles used in the rest of the code.
+Don't forget to submit those changes back to us (along with compiler info)
+so we can incorporate them in our next release!
+
+4.2 Reporting problems
+
+When reporting problems please try to be as specific as possible e.g.
+mention ANTLR release, and try to provide a clear and minimal example of
+what goes wrong and what you expected.
+
+Bug reports can be done to Terence or the current subsystem maintainers as
+mentioned in the doc directory. Another option is to use the mailing list
+linked from http://www.antlr.org.
+
+Before reporting a problem you might want to try with a development
+snapshot, there is a link to these in the File Sharing section of
+
+http://www.antlr.org.
diff --git a/libsecurity_codesigning/antlr2/TODO b/libsecurity_codesigning/antlr2/TODO
new file mode 100644 (file)
index 0000000..693ec99
--- /dev/null
@@ -0,0 +1,83 @@
+* ANTLR should issue a warning if you have protected rules and
+  filter == true or filter=IGNORE in a lexer?
+  This can be tackled by tracking rule references in a more general approach.
+
+* Have a look at the doc's.
+
+* Add allocators to the objects
+
+* Look more at exception handling
+
+* TreeParser.cpp around line 76 the MismatchedTokenException here does not
+  use ttype to improve it's errormessage. Would require changing a bit in
+  MismatchedTokenException.cpp
+
+* On Thu, Sep 21, 2000 at 12:33:48AM -0700, John Lambert <JohnL@jBASE.com> wrote:
+  > 1) The literal EOF is not defined and causes the define of EOF_CHAR  in
+  > CharScanner.hpp to fail.
+
+  ANTLR with STL Port. Changing the EOF define to char_traits<char>::eof()
+  breaks things for gcc-2.95.2. Fix this in next release portably.
+  http://www.egroups.com/message/antlr-interest/2520
+
+* Fix heterogeneous AST stuff. It boils down to adding a method to AST
+  types that knows how to duplicate the sucker.
+  -> done clone() added.
+  Knowing one factory is not enough.
+  -> done in C++ have a superfactory.
+  Also look at having to set the astfactory by hand (this is not 100% necessary).
+  Double check generated code.
+  http://groups.yahoo.com/group/antlr-interest/message/2496
+
+* Look at messageLog stuff Ross Bencina proposed. Looks good at first glance.
+  http://www.egroups.com/message/antlr-interest/2555
+
+* Add RW_STL & CC 4.2 patch from Ulrich Teichert:
+  See my mailbox.. and these comments from Ross Bencina:
+  http://www.egroups.com/message/antlr-interest/2494
+
+* in action.g (java and C++) ##.initialize / ##->initialize is not
+  recognized as an assigment to the root node. In the case ## is followed
+  by ./-> initialize transInfo.assignToRoot should be set to true.
+  Report by Matthew Ford (12 march 2001)
+
+* Add TokenLabelType option for generated lexers. Hmmm can already set token
+  factory. Then again.. you may run into a cast fest..
+
+* Fix some #line counting oddities (Mike Barnett)
+  >    nonterm
+  >    {
+  >          ## = #([TOK,"TOK"],
+  >                    ... Other stuff ...
+  >             );
+  >          f();
+  >    }
+  generates wrong #line info need to fix action.g a bit better.
+
+* This one triggers a bug in antlr's codegen.
+  #perform_action = #( create_tau_ast(#p1->getLine(),#p1->getColumn()), #p1 );
+
+  #p1 are replaced by p1 in stead of p1_AST. It's really time to rewrite this
+  mess.
+
+  Workaround:
+
+  RefModest_AST tau = create_tau_ast(#p1->getLine(),#p1->getColumn());
+  #perform_action = #( tau, #p1 );
+
+* Unicode and related.
+  - The patch from Jean-Daniel Fekete is an approach. But has some issues.
+  + It is probably necessary to discern an 'internal' string/char type and
+    'external' ones. The external ones are for the lexer input. The
+        'internal ones' are for standard antlr error messages etc. Translators
+        from external to internal should be provided.
+        Hmm on second thought.. probably not really an issue.
+  + What should the lexer read?
+    - Unicode units from a 'unicode reader' in a sense this unicode reader
+      is a lexer itself. Just reading iconv/iconv_open manpages.. Maybe we
+      can hide this with iconv in the InputBuffer mechanisms?
+        - Interpret unicode ourselves. Ugh don't want to think of that right now.
+          we probably redo something that has been done. Only problem is that we
+               need something that's portable (C++ case)
+  + What changes are necessary in the rest of the code to support a wide
+    character set? Think most should be handled in/below the lexer level.
diff --git a/libsecurity_codesigning/antlr2/antlr.jar b/libsecurity_codesigning/antlr2/antlr.jar
new file mode 100644 (file)
index 0000000..ee78b27
Binary files /dev/null and b/libsecurity_codesigning/antlr2/antlr.jar differ
diff --git a/libsecurity_codesigning/antlr2/antlr/ANTLRException.hpp b/libsecurity_codesigning/antlr2/antlr/ANTLRException.hpp
new file mode 100644 (file)
index 0000000..c91e927
--- /dev/null
@@ -0,0 +1,59 @@
+#ifndef INC_ANTLRException_hpp__
+#define INC_ANTLRException_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/ANTLRException.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <string>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+class ANTLR_API ANTLRException
+{
+public:
+       /// Create ANTLR base exception without error message
+       ANTLRException() : text("")
+       {
+       }
+       /// Create ANTLR base exception with error message
+       ANTLRException(const ANTLR_USE_NAMESPACE(std)string& s)
+       : text(s)
+       {
+       }
+       virtual ~ANTLRException() throw()
+       {
+       }
+
+       /** Return complete error message with line/column number info (if present)
+        * @note for your own exceptions override this one. Call getMessage from
+        * here to get the 'clean' error message stored in the text attribute.
+        */
+       virtual ANTLR_USE_NAMESPACE(std)string toString() const
+       {
+               return text;
+       }
+
+       /** Return error message without additional info (if present)
+        * @note when making your own exceptions classes override toString
+        * and call in toString getMessage which relays the text attribute
+        * from here.
+        */
+       virtual ANTLR_USE_NAMESPACE(std)string getMessage() const
+       {
+               return text;
+       }
+private:
+       ANTLR_USE_NAMESPACE(std)string text;
+};
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_ANTLRException_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/ANTLRUtil.hpp b/libsecurity_codesigning/antlr2/antlr/ANTLRUtil.hpp
new file mode 100644 (file)
index 0000000..4c76972
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef INC_ANTLRUtil_hpp__
+#define INC_ANTLRUtil_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id:$
+ */
+
+#include <antlr/config.hpp>
+#include <istream>
+#include <string>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/** Eat whitespace from the input stream
+ * @param is the stream to read from
+ */
+ANTLR_USE_NAMESPACE(std)istream& eatwhite( ANTLR_USE_NAMESPACE(std)istream& is );
+
+/** Read a string enclosed by '"' from a stream. Also handles escaping of \".
+ * Skips leading whitespace.
+ * @param in the istream to read from.
+ * @returns the string read from file exclusive the '"'
+ * @throws ios_base::failure if string is badly formatted
+ */
+ANTLR_USE_NAMESPACE(std)string read_string( ANTLR_USE_NAMESPACE(std)istream& in );
+
+/* Read a ([A-Z][0-9][a-z]_)* kindoff thing. Skips leading whitespace.
+ * @param in the istream to read from.
+ */
+ANTLR_USE_NAMESPACE(std)string read_identifier( ANTLR_USE_NAMESPACE(std)istream& in );
+
+/** Read a attribute="value" thing. Leading whitespace is skipped.
+ * Between attribute and '=' no whitespace is allowed. After the '=' it is
+ * permitted.
+ * @param in the istream to read from.
+ * @param attribute string the attribute name is put in
+ * @param value string the value of the attribute is put in
+ * @throws ios_base::failure if something is fishy. E.g. malformed quoting
+ * or missing '='
+ */
+void read_AttributeNValue( ANTLR_USE_NAMESPACE(std)istream& in,
+                                                                  ANTLR_USE_NAMESPACE(std)string& attribute,
+                                                                  ANTLR_USE_NAMESPACE(std)string& value );
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/libsecurity_codesigning/antlr2/antlr/AST.hpp b/libsecurity_codesigning/antlr2/antlr/AST.hpp
new file mode 100644 (file)
index 0000000..c47be5f
--- /dev/null
@@ -0,0 +1,166 @@
+#ifndef INC_AST_hpp__
+#define INC_AST_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/AST.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/ASTRefCount.hpp>
+#include <antlr/Token.hpp>
+#include <vector>
+#include <string>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+struct ASTRef;
+
+class ANTLR_API AST {
+public:
+       AST() : ref(0) {}
+       AST(const AST&) : ref(0) {}
+       virtual ~AST() {}
+
+       /// Return the type name for this AST node. (for XML output)
+       virtual const char* typeName( void ) const = 0;
+       /// Clone this AST node.
+       virtual RefAST clone( void ) const = 0;
+   /// Is node t equal to this in terms of token type and text?
+       virtual bool equals(RefAST t) const = 0;
+   /** Is t an exact structural and equals() match of this tree. The
+        * 'this' reference is considered the start of a sibling list.
+        */
+       virtual bool equalsList(RefAST t) const = 0;
+
+       /** Is 't' a subtree of this list? The siblings of the root are NOT ignored.
+    */
+       virtual bool equalsListPartial(RefAST t) const = 0;
+       /** Is tree rooted at 'this' equal to 't'?  The siblings of 'this' are
+        * ignored.
+        */
+       virtual bool equalsTree(RefAST t) const = 0;
+       /** Is 't' a subtree of the tree rooted at 'this'? The siblings of
+        * 'this' are ignored.
+        */
+       virtual bool equalsTreePartial(RefAST t) const = 0;
+
+       /** Walk the tree looking for all exact subtree matches.  Return
+        *  a vector of RefAST that lets the caller walk the list
+        *  of subtree roots found herein.
+        */
+       virtual ANTLR_USE_NAMESPACE(std)vector<RefAST> findAll(RefAST t) = 0;
+
+   /** Walk the tree looking for all subtrees.  Return
+    *  a vector of RefAST that lets the caller walk the list
+    *  of subtree roots found herein.
+    */
+       virtual ANTLR_USE_NAMESPACE(std)vector<RefAST> findAllPartial(RefAST t) = 0;
+
+   /// Add a node to the end of the child list for this node
+       virtual void addChild(RefAST c) = 0;
+       /// Get the number of children. Returns 0 if the node is a leaf
+       virtual size_t getNumberOfChildren() const = 0;
+
+       /// Get the first child of this node; null if no children
+       virtual RefAST getFirstChild() const = 0;
+       /// Get  the next sibling in line after this one
+       virtual RefAST getNextSibling() const = 0;
+
+       /// Get the token text for this node
+       virtual ANTLR_USE_NAMESPACE(std)string getText() const = 0;
+       /// Get the token type for this node
+       virtual int getType() const = 0;
+
+       /** Various initialization routines. Used by several factories to initialize
+        * an AST element.
+        */
+       virtual void initialize(int t, const ANTLR_USE_NAMESPACE(std)string& txt) = 0;
+       virtual void initialize(RefAST t) = 0;
+       virtual void initialize(RefToken t) = 0;
+
+#ifdef ANTLR_SUPPORT_XML
+       /** initialize this node from the contents of a stream.
+        * @param in the stream to read the AST attributes from.
+        */
+       virtual void initialize( ANTLR_USE_NAMESPACE(std)istream& in ) = 0;
+#endif
+
+       /// Set the first child of a node.
+       virtual void setFirstChild(RefAST c) = 0;
+       /// Set the next sibling after this one.
+       virtual void setNextSibling(RefAST n) = 0;
+
+       /// Set the token text for this node
+       virtual void setText(const ANTLR_USE_NAMESPACE(std)string& txt) = 0;
+       /// Set the token type for this node
+       virtual void setType(int type) = 0;
+
+       /// Return this AST node as a string
+       virtual ANTLR_USE_NAMESPACE(std)string toString() const = 0;
+
+       /// Print out a child-sibling tree in LISP notation
+       virtual ANTLR_USE_NAMESPACE(std)string toStringList() const = 0;
+       virtual ANTLR_USE_NAMESPACE(std)string toStringTree() const = 0;
+
+#ifdef ANTLR_SUPPORT_XML
+       /** get attributes of this node to 'out'. Override to customize XML
+        * output.
+        * @param out the stream to write the AST attributes to.
+        * @returns if a explicit closetag should be written
+        */
+       virtual bool attributesToStream( ANTLR_USE_NAMESPACE(std)ostream& out ) const = 0;
+
+       /** Print a symbol over ostream. Overload this one to customize the XML
+        * output for AST derived AST-types
+        * @param output stream
+        */
+       virtual void toStream( ANTLR_USE_NAMESPACE(std)ostream &out ) const = 0;
+
+       /** Dump AST contents in XML format to output stream.
+        * Works in conjunction with to_stream method. Overload that one is
+        * derived classes to customize behaviour.
+        * @param output stream to write to string to put the stuff in.
+        * @param ast RefAST object to write.
+        */
+       friend ANTLR_USE_NAMESPACE(std)ostream& operator<<( ANTLR_USE_NAMESPACE(std)ostream& output, const RefAST& ast );
+#endif
+
+private:
+       friend struct ASTRef;
+       ASTRef* ref;
+
+       AST(RefAST other);
+       AST& operator=(const AST& other);
+       AST& operator=(RefAST other);
+};
+
+#ifdef ANTLR_SUPPORT_XML
+inline ANTLR_USE_NAMESPACE(std)ostream& operator<<( ANTLR_USE_NAMESPACE(std)ostream& output, const RefAST& ast )
+{
+       ast->toStream(output);
+       return output;
+}
+#endif
+
+extern ANTLR_API RefAST nullAST;
+extern ANTLR_API AST* const nullASTptr;
+
+#ifdef NEEDS_OPERATOR_LESS_THAN
+// RK: apparently needed by MSVC and a SUN CC, up to and including
+// 2.7.2 this was undefined ?
+inline bool operator<( RefAST l, RefAST r )
+{
+       return nullAST == l ? ( nullAST == r ? false : true ) : l->getType() < r->getType();
+}
+#endif
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_AST_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/ASTArray.hpp b/libsecurity_codesigning/antlr2/antlr/ASTArray.hpp
new file mode 100644 (file)
index 0000000..d667c33
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef INC_ASTArray_hpp__
+#define INC_ASTArray_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/ASTArray.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/AST.hpp>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/** ASTArray is a class that allows ANTLR to
+  * generate code that can create and initialize an array
+  * in one expression, like:
+  *    (new ASTArray(3))->add(x)->add(y)->add(z)
+  */
+class ANTLR_API ASTArray {
+public:
+       int size; // = 0;
+       ANTLR_USE_NAMESPACE(std)vector<RefAST> array;
+
+       ASTArray(int capacity)
+       : size(0)
+       , array(capacity)
+       {
+       }
+
+       ASTArray* add(RefAST node)
+       {
+               array[size++] = node;
+               return this;
+       }
+};
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_ASTArray_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/ASTFactory.hpp b/libsecurity_codesigning/antlr2/antlr/ASTFactory.hpp
new file mode 100644 (file)
index 0000000..9fdcc24
--- /dev/null
@@ -0,0 +1,165 @@
+#ifndef INC_ASTFactory_hpp__
+#define INC_ASTFactory_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/ASTFactory.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/AST.hpp>
+#include <antlr/ASTArray.hpp>
+#include <antlr/ASTPair.hpp>
+
+#include <istream>
+#include <utility>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+// Using these extra types to appease MSVC
+typedef RefAST (*factory_type_)();
+typedef ANTLR_USE_NAMESPACE(std)pair< const char*, factory_type_ >  factory_descriptor_;
+typedef ANTLR_USE_NAMESPACE(std)vector< factory_descriptor_* >      factory_descriptor_list_;
+
+/** AST Super Factory shared by TreeParser and Parser.
+ * This super factory maintains a map of all AST node types to their respective
+ * AST factories. One instance should be shared among a parser/treeparser
+ * chain.
+ *
+ * @todo check all this code for possible use of references in
+ * stead of RefAST's.
+ */
+class ANTLR_API ASTFactory {
+public:
+       typedef factory_type_             factory_type;
+       typedef factory_descriptor_       factory_descriptor;
+       typedef factory_descriptor_list_  factory_descriptor_list;
+protected:
+       /* The mapping of AST node type to factory..
+        */
+       factory_descriptor default_factory_descriptor;
+       factory_descriptor_list nodeFactories;
+public:
+       /// Make new factory. Per default (Ref)CommonAST instances are generated.
+       ASTFactory();
+       /** Initialize factory with a non default node type.
+        * factory_node_name should be the name of the AST node type the factory
+        * generates. (should exist during the existance of this ASTFactory
+        * instance)
+        */
+       ASTFactory( const char* factory_node_name, factory_type factory );
+       /// Destroy factory
+       virtual ~ASTFactory();
+
+       /// Register a node factory for the node type type with name ast_name
+       void registerFactory( int type, const char* ast_name, factory_type factory );
+       /// Set the maximum node (AST) type this factory may encounter
+       void setMaxNodeType( int type );
+
+       /// Add a child to the current AST
+       void addASTChild(ASTPair& currentAST, RefAST child);
+       /// Create new empty AST node. The right default type shou
+       virtual RefAST create();
+       /// Create AST node of the right type for 'type'
+       RefAST create(int type);
+       /// Create AST node of the right type for 'type' and initialize with txt
+       RefAST create(int type, const ANTLR_USE_NAMESPACE(std)string& txt);
+       /// Create duplicate of tr
+       RefAST create(RefAST tr);
+       /// Create new AST node and initialize contents from a token.
+       RefAST create(RefToken tok);
+       /// Create new AST node and initialize contents from a stream.
+       RefAST create(const ANTLR_USE_NAMESPACE(std)string& txt, ANTLR_USE_NAMESPACE(std)istream& infile );
+       /** Deep copy a single node. This function the new clone() methods in the
+        * AST interface. Returns a new RefAST(nullASTptr) if t is null.
+        */
+       RefAST dup(RefAST t);
+       /// Duplicate tree including siblings of root.
+       RefAST dupList(RefAST t);
+       /** Duplicate a tree, assuming this is a root node of a tree--
+        * duplicate that node and what's below; ignore siblings of root node.
+        */
+       RefAST dupTree(RefAST t);
+       /** Make a tree from a list of nodes. The first element in the
+        * array is the root. If the root is null, then the tree is
+        * a simple list not a tree. Handles null children nodes correctly.
+        * For example, make(a, b, null, c) yields tree (a b c).  make(null,a,b)
+        * yields tree (nil a b).
+        */
+       RefAST make(ANTLR_USE_NAMESPACE(std)vector<RefAST>& nodes);
+       /** Make a tree from a list of nodes, where the nodes are contained
+        * in an ASTArray object. The ASTArray is deleted after use.
+        * @todo FIXME! I have a feeling we can get rid of this ugly ASTArray thing
+        */
+       RefAST make(ASTArray* nodes);
+       /// Make an AST the root of current AST
+       void makeASTRoot(ASTPair& currentAST, RefAST root);
+
+       /** Set a new default AST type.
+        * factory_node_name should be the name of the AST node type the factory
+        * generates. (should exist during the existance of this ASTFactory
+        * instance).
+        * Only change factory between parser runs. You might get unexpected results
+        * otherwise.
+        */
+       void setASTNodeFactory( const char* factory_node_name, factory_type factory );
+
+#ifdef ANTLR_SUPPORT_XML
+       /** Load a XML AST from stream. Make sure you have all the factories
+        * registered before use.
+        * @note this 'XML' stuff is quite rough still. YMMV.
+        */
+       RefAST LoadAST( ANTLR_USE_NAMESPACE(std)istream& infile );
+#endif
+protected:
+       void loadChildren( ANTLR_USE_NAMESPACE(std)istream& infile, RefAST current );
+       void loadSiblings( ANTLR_USE_NAMESPACE(std)istream& infile, RefAST current );
+       bool checkCloseTag( ANTLR_USE_NAMESPACE(std)istream& infile );
+
+#ifdef ANTLR_VECTOR_HAS_AT
+       /// construct a node of 'type'
+       inline RefAST getNodeOfType( unsigned int type )
+       {
+               return RefAST(nodeFactories.at(type)->second());
+       }
+       /// get the name of the node 'type'
+       const char* getASTNodeType( unsigned int type )
+       {
+               return nodeFactories.at(type)->first;
+       }
+       /// get the factory used for node 'type'
+       factory_type getASTNodeFactory( unsigned int type )
+       {
+               return nodeFactories.at(type)->second;
+       }
+#else
+       inline RefAST getNodeOfType( unsigned int type )
+       {
+               return RefAST(nodeFactories[type]->second());
+       }
+       /// get the name of the node 'type'
+       const char* getASTNodeType( unsigned int type )
+       {
+               return nodeFactories[type]->first;
+       }
+       factory_type getASTNodeFactory( unsigned int type )
+       {
+               return nodeFactories[type]->second;
+       }
+#endif
+
+private:
+       // no copying and such..
+       ASTFactory( const ASTFactory& );
+       ASTFactory& operator=( const ASTFactory& );
+};
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_ASTFactory_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/ASTNULLType.hpp b/libsecurity_codesigning/antlr2/antlr/ASTNULLType.hpp
new file mode 100644 (file)
index 0000000..5e9a970
--- /dev/null
@@ -0,0 +1,67 @@
+#ifndef INC_ASTNULLType_hpp__
+#define INC_ASTNULLType_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/ASTNULLType.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/AST.hpp>
+#include <vector>
+#include <string>
+#include <istream>
+#include <ostream>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/** There is only one instance of this class **/
+class ANTLR_API ASTNULLType : public AST {
+public:
+       const char* typeName( void ) const;
+       RefAST clone( void ) const;
+
+       void addChild(RefAST c);
+       size_t getNumberOfChildren() const;
+       void setFirstChild(RefAST c);
+       void setNextSibling(RefAST n);
+
+       bool equals(RefAST t) const;
+       bool equalsList(RefAST t) const;
+       bool equalsListPartial(RefAST t) const;
+       bool equalsTree(RefAST t) const;
+       bool equalsTreePartial(RefAST t) const;
+
+       ANTLR_USE_NAMESPACE(std)vector<RefAST> findAll(RefAST tree);
+       ANTLR_USE_NAMESPACE(std)vector<RefAST> findAllPartial(RefAST subtree);
+
+       RefAST getFirstChild() const;
+       RefAST getNextSibling() const;
+
+       ANTLR_USE_NAMESPACE(std)string getText() const;
+       int getType() const;
+
+       void initialize(int t, const ANTLR_USE_NAMESPACE(std)string& txt);
+       void initialize(RefAST t);
+       void initialize(RefToken t);
+       void initialize(ANTLR_USE_NAMESPACE(std)istream& infile);
+
+       void setText(const ANTLR_USE_NAMESPACE(std)string& text);
+       void setType(int ttype);
+       ANTLR_USE_NAMESPACE(std)string toString() const;
+       ANTLR_USE_NAMESPACE(std)string toStringList() const;
+       ANTLR_USE_NAMESPACE(std)string toStringTree() const;
+
+       bool attributesToStream( ANTLR_USE_NAMESPACE(std)ostream &out ) const;
+       void toStream( ANTLR_USE_NAMESPACE(std)ostream &out ) const;
+};
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_ASTNULLType_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/ASTPair.hpp b/libsecurity_codesigning/antlr2/antlr/ASTPair.hpp
new file mode 100644 (file)
index 0000000..ec54253
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef INC_ASTPair_hpp__
+#define INC_ASTPair_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/ASTPair.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/AST.hpp>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/** ASTPair:  utility class used for manipulating a pair of ASTs
+  * representing the current AST root and current AST sibling.
+  * This exists to compensate for the lack of pointers or 'var'
+  * arguments in Java.
+  *
+  * OK, so we can do those things in C++, but it seems easier
+  * to stick with the Java way for now.
+  */
+class ANTLR_API ASTPair {
+public:
+       RefAST root;            // current root of tree
+       RefAST child;           // current child to which siblings are added
+
+       /** Make sure that child is the last sibling */
+       void advanceChildToEnd() {
+               if (child) {
+                       while (child->getNextSibling()) {
+                               child = child->getNextSibling();
+                       }
+               }
+       }
+//     /** Copy an ASTPair.  Don't call it clone() because we want type-safety */
+//     ASTPair copy() {
+//             ASTPair tmp = new ASTPair();
+//             tmp.root = root;
+//             tmp.child = child;
+//             return tmp;
+//     }
+       ANTLR_USE_NAMESPACE(std)string toString() const {
+               ANTLR_USE_NAMESPACE(std)string r = !root ? ANTLR_USE_NAMESPACE(std)string("null") : root->getText();
+               ANTLR_USE_NAMESPACE(std)string c = !child ? ANTLR_USE_NAMESPACE(std)string("null") : child->getText();
+               return "["+r+","+c+"]";
+       }
+};
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_ASTPair_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/ASTRefCount.hpp b/libsecurity_codesigning/antlr2/antlr/ASTRefCount.hpp
new file mode 100644 (file)
index 0000000..293f2d5
--- /dev/null
@@ -0,0 +1,98 @@
+#ifndef INC_ASTRefCount_hpp__
+# define INC_ASTRefCount_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/ASTRefCount.hpp#2 $
+ */
+
+# include <antlr/config.hpp>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+       class AST;
+
+struct ANTLR_API ASTRef
+{
+       AST* const ptr;
+       unsigned int count;
+
+       ASTRef(AST* p);
+       ~ASTRef();
+       ASTRef* increment()
+       {
+               ++count;
+               return this;
+       }
+       bool decrement()
+       {
+               return (--count==0);
+       }
+
+       static ASTRef* getRef(const AST* p);
+private:
+       ASTRef( const ASTRef& );
+       ASTRef& operator=( const ASTRef& );
+};
+
+template<class T>
+       class ANTLR_API ASTRefCount
+{
+private:
+       ASTRef* ref;
+
+public:
+       ASTRefCount(const AST* p=0)
+       : ref(p ? ASTRef::getRef(p) : 0)
+       {
+       }
+       ASTRefCount(const ASTRefCount<T>& other)
+       : ref(other.ref ? other.ref->increment() : 0)
+       {
+       }
+       ~ASTRefCount()
+       {
+               if (ref && ref->decrement())
+                       delete ref;
+       }
+       ASTRefCount<T>& operator=(AST* other)
+       {
+               ASTRef* tmp = ASTRef::getRef(other);
+
+               if (ref && ref->decrement())
+                       delete ref;
+
+               ref=tmp;
+
+               return *this;
+       }
+       ASTRefCount<T>& operator=(const ASTRefCount<T>& other)
+       {
+               if( other.ref != ref )
+               {
+                       ASTRef* tmp = other.ref ? other.ref->increment() : 0;
+
+                       if (ref && ref->decrement())
+                               delete ref;
+
+                       ref=tmp;
+               }
+               return *this;
+       }
+
+       operator T* ()  const { return ref ? static_cast<T*>(ref->ptr) : 0; }
+       T* operator->() const { return ref ? static_cast<T*>(ref->ptr) : 0; }
+       T* get()        const { return ref ? static_cast<T*>(ref->ptr) : 0; }
+};
+
+typedef ASTRefCount<AST> RefAST;
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_ASTRefCount_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/BaseAST.hpp b/libsecurity_codesigning/antlr2/antlr/BaseAST.hpp
new file mode 100644 (file)
index 0000000..afdbb15
--- /dev/null
@@ -0,0 +1,195 @@
+#ifndef INC_BaseAST_hpp__
+#define INC_BaseAST_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/BaseAST.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/AST.hpp>
+
+#include <vector>
+#include <string>
+#include <ostream>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+class ANTLR_API BaseAST;
+typedef ASTRefCount<BaseAST> RefBaseAST;
+
+class ANTLR_API BaseAST : public AST {
+public:
+       BaseAST() : AST()
+       {
+       }
+       BaseAST(const BaseAST& other)
+       : AST(other)
+       {
+       }
+       virtual ~BaseAST()
+       {
+       }
+
+       /// Return the class name
+       virtual const char* typeName( void ) const = 0;
+
+       /// Clone this AST node.
+       virtual RefAST clone( void ) const = 0;
+
+   /// Is node t equal to this in terms of token type and text?
+       virtual bool equals(RefAST t) const;
+
+   /** Is t an exact structural and equals() match of this tree. The
+        * 'this' reference is considered the start of a sibling list.
+        */
+       virtual bool equalsList(RefAST t) const;
+
+   /** Is 't' a subtree of this list? The siblings of the root are NOT ignored.
+    */
+       virtual bool equalsListPartial(RefAST t) const;
+
+       /** Is tree rooted at 'this' equal to 't'?  The siblings of 'this' are
+        * ignored.
+        */
+       virtual bool equalsTree(RefAST t) const;
+
+       /** Is 't' a subtree of the tree rooted at 'this'? The siblings of
+        * 'this' are ignored.
+        */
+       virtual bool equalsTreePartial(RefAST t) const;
+
+       /** Walk the tree looking for all exact subtree matches.  Return
+        *  an ASTEnumerator that lets the caller walk the list
+        *  of subtree roots found herein.
+        */
+       virtual ANTLR_USE_NAMESPACE(std)vector<RefAST> findAll(RefAST t);
+
+   /** Walk the tree looking for all subtrees.  Return
+    *  an ASTEnumerator that lets the caller walk the list
+    *  of subtree roots found herein.
+    */
+       virtual ANTLR_USE_NAMESPACE(std)vector<RefAST> findAllPartial(RefAST t);
+
+   /// Add a node to the end of the child list for this node
+       virtual void addChild(RefAST c)
+       {
+               if( !c )
+                       return;
+
+               RefBaseAST tmp = down;
+
+               if (tmp)
+               {
+                       while (tmp->right)
+                               tmp = tmp->right;
+                       tmp->right = c;
+               }
+               else
+                       down = c;
+       }
+
+       /** Get the number of child nodes of this node (shallow e.g. not of the
+        * whole tree it spans).
+        */
+       virtual size_t getNumberOfChildren() const;
+
+       /// Get the first child of this node; null if no children
+       virtual RefAST getFirstChild() const
+       {
+               return RefAST(down);
+       }
+       /// Get  the next sibling in line after this one
+       virtual RefAST getNextSibling() const
+       {
+               return RefAST(right);
+       }
+
+       /// Get the token text for this node
+       virtual ANTLR_USE_NAMESPACE(std)string getText() const
+       {
+               return "";
+       }
+       /// Get the token type for this node
+       virtual int getType() const
+       {
+               return 0;
+       }
+
+       /// Remove all children
+       virtual void removeChildren()
+       {
+               down = static_cast<BaseAST*>(static_cast<AST*>(nullAST));
+       }
+
+       /// Set the first child of a node.
+       virtual void setFirstChild(RefAST c)
+       {
+               down = static_cast<BaseAST*>(static_cast<AST*>(c));
+       }
+
+       /// Set the next sibling after this one.
+       virtual void setNextSibling(RefAST n)
+       {
+               right = static_cast<BaseAST*>(static_cast<AST*>(n));
+       }
+
+       /// Set the token text for this node
+       virtual void setText(const ANTLR_USE_NAMESPACE(std)string& txt)
+       {
+       }
+
+       /// Set the token type for this node
+       virtual void setType(int type)
+       {
+       }
+
+#ifdef ANTLR_SUPPORT_XML
+       /** print attributes of this node to 'out'. Override to customize XML
+        * output.
+        * @param out the stream to write the AST attributes to.
+        */
+       virtual bool attributesToStream( ANTLR_USE_NAMESPACE(std)ostream& out ) const;
+       /** Write this subtree to a stream. Overload this one to customize the XML
+        * output for AST derived AST-types
+        * @param output stream
+        */
+       virtual void toStream( ANTLR_USE_NAMESPACE(std)ostream &out ) const;
+#endif
+
+       /// Return string representation for the AST
+       virtual ANTLR_USE_NAMESPACE(std)string toString() const
+       {
+               return getText();
+       }
+
+       /// Print out a child sibling tree in LISP notation
+       virtual ANTLR_USE_NAMESPACE(std)string toStringList() const;
+       virtual ANTLR_USE_NAMESPACE(std)string toStringTree() const;
+protected:
+       RefBaseAST down;
+       RefBaseAST right;
+private:
+       void doWorkForFindAll(ANTLR_USE_NAMESPACE(std)vector<RefAST>& v,
+                                                                RefAST target,
+                                                                bool partialMatch);
+};
+
+/** Is node t equal to this in terms of token type and text?
+ */
+inline bool BaseAST::equals(RefAST t) const
+{
+       if (!t)
+               return false;
+       return ((getType() == t->getType()) && (getText() == t->getText()));
+}
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_BaseAST_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/BitSet.hpp b/libsecurity_codesigning/antlr2/antlr/BitSet.hpp
new file mode 100644 (file)
index 0000000..e1869cf
--- /dev/null
@@ -0,0 +1,60 @@
+#ifndef INC_BitSet_hpp__
+#define INC_BitSet_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/BitSet.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <vector>
+#include <stdexcept>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/** A BitSet to replace java.util.BitSet.
+ * Primary differences are that most set operators return new sets
+ * as opposed to oring and anding "in place".  Further, a number of
+ * operations were added.  I cannot contain a BitSet because there
+ * is no way to access the internal bits (which I need for speed)
+ * and, because it is final, I cannot subclass to add functionality.
+ * Consider defining set degree.  Without access to the bits, I must
+ * call a method n times to test the ith bit...ack!
+ *
+ * Also seems like or() from util is wrong when size of incoming set is bigger
+ * than this.length.
+ *
+ * This is a C++ version of the Java class described above, with only
+ * a handful of the methods implemented, because we don't need the
+ * others at runtime. It's really just a wrapper around vector<bool>,
+ * which should probably be changed to a wrapper around bitset, once
+ * bitset is more widely available.
+ *
+ * @author Terence Parr, MageLang Institute
+ * @author <br><a href="mailto:pete@yamuna.demon.co.uk">Pete Wells</a>
+ */
+class ANTLR_API BitSet {
+private:
+       ANTLR_USE_NAMESPACE(std)vector<bool> storage;
+
+public:
+       BitSet( unsigned int nbits=64 );
+       BitSet( const unsigned long* bits_, unsigned int nlongs);
+       ~BitSet();
+
+       void add( unsigned int el );
+
+       bool member( unsigned int el ) const;
+
+       ANTLR_USE_NAMESPACE(std)vector<unsigned int> toArray() const;
+};
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_BitSet_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/CharBuffer.hpp b/libsecurity_codesigning/antlr2/antlr/CharBuffer.hpp
new file mode 100644 (file)
index 0000000..57ab3e6
--- /dev/null
@@ -0,0 +1,56 @@
+#ifndef INC_CharBuffer_hpp__
+#define INC_CharBuffer_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/CharBuffer.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+
+#include <istream>
+
+#include <antlr/InputBuffer.hpp>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/**A Stream of characters fed to the lexer from a InputStream that can
+ * be rewound via mark()/rewind() methods.
+ * <p>
+ * A dynamic array is used to buffer up all the input characters.  Normally,
+ * "k" characters are stored in the buffer.  More characters may be stored
+ * during guess mode (testing syntactic predicate), or when LT(i>k) is
+ * referenced.
+ * Consumption of characters is deferred.  In other words, reading the next
+ * character is not done by consume(), but deferred until needed by LA or LT.
+ * <p>
+ *
+ * @see antlr.CharQueue
+ */
+
+class ANTLR_API CharBuffer : public InputBuffer {
+public:
+       /// Create a character buffer
+       CharBuffer( ANTLR_USE_NAMESPACE(std)istream& input );
+       /// Get the next character from the stream
+       int getChar();
+
+protected:
+       // character source
+       ANTLR_USE_NAMESPACE(std)istream& input;
+
+private:
+       // NOTE: Unimplemented
+       CharBuffer(const CharBuffer& other);
+       CharBuffer& operator=(const CharBuffer& other);
+};
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_CharBuffer_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/CharInputBuffer.hpp b/libsecurity_codesigning/antlr2/antlr/CharInputBuffer.hpp
new file mode 100644 (file)
index 0000000..ac2da0c
--- /dev/null
@@ -0,0 +1,77 @@
+#ifndef INC_CharInputBuffer_hpp__
+# define INC_CharInputBuffer_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id:$
+ */
+
+# include <antlr/config.hpp>
+# include <antlr/InputBuffer.hpp>
+
+# ifdef HAS_NOT_CCTYPE_H
+#      include <ctype.h>
+# else
+#      include <cctype>
+# endif
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/** CharInputBuffer.hpp provides an InputBuffer for plain character arrays (buffers).
+ */
+class CharInputBuffer : public InputBuffer
+{
+public:
+       /** Construct a CharInputBuffer.hpp object with a char* buffer of 'size'
+        * if 'owner' is true, then the buffer will be delete[]-ed on destruction.
+        * @note it is assumed the buffer was allocated with new[]!
+        */
+       CharInputBuffer( unsigned char* buf, size_t size, bool owner = false )
+       : buffer(buf)
+       , ptr(buf)
+       , end(buf + size)
+       , delete_buffer(owner)
+       {
+       }
+
+       /** Destructor
+        * @note If you're using malloced data, then you probably need to change
+        * this destructor. Or better use this class as template for your own.
+        */
+       ~CharInputBuffer( void )
+       {
+               if( delete_buffer && buffer )
+                       delete [] buffer;
+       }
+
+       /** Reset the CharInputBuffer to initial state
+        * Called from LexerInputState::reset.
+        * @see LexerInputState
+        */
+       virtual inline void reset( void )
+       {
+               InputBuffer::reset();
+               ptr = buffer;
+       }
+
+       virtual int getChar( void )
+       {
+               return (ptr < end) ? *ptr++ : EOF;
+       }
+
+protected:
+       unsigned char* buffer;  ///< the buffer with data
+       unsigned char* ptr;             ///< position ptr into the buffer
+       unsigned char* end;             ///< end sentry for buffer
+       bool delete_buffer;             ///< flag signifying if we have to delete the buffer
+};
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/libsecurity_codesigning/antlr2/antlr/CharScanner.hpp b/libsecurity_codesigning/antlr2/antlr/CharScanner.hpp
new file mode 100644 (file)
index 0000000..8a97e97
--- /dev/null
@@ -0,0 +1,574 @@
+#ifndef INC_CharScanner_hpp__
+#define INC_CharScanner_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/CharScanner.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+
+#include <map>
+
+#ifdef HAS_NOT_CCTYPE_H
+#include <ctype.h>
+#else
+#include <cctype>
+#endif
+
+#if ( _MSC_VER == 1200 )
+// VC6 seems to need this
+// note that this is not a standard C++ include file.
+# include <stdio.h>
+#endif
+
+#include <antlr/TokenStream.hpp>
+#include <antlr/RecognitionException.hpp>
+#include <antlr/SemanticException.hpp>
+#include <antlr/MismatchedCharException.hpp>
+#include <antlr/InputBuffer.hpp>
+#include <antlr/BitSet.hpp>
+#include <antlr/LexerSharedInputState.hpp>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+class ANTLR_API CharScanner;
+
+ANTLR_C_USING(tolower)
+
+#ifdef ANTLR_REALLY_NO_STRCASECMP
+// Apparently, neither strcasecmp nor stricmp is standard, and Codewarrior
+// on the mac has neither...
+inline int strcasecmp(const char *s1, const char *s2)
+{
+       while (true)
+       {
+               char  c1 = tolower(*s1++),
+                               c2 = tolower(*s2++);
+               if (c1 < c2) return -1;
+               if (c1 > c2) return 1;
+               if (c1 == 0) return 0;
+       }
+}
+#else
+#ifdef NO_STRCASECMP
+ANTLR_C_USING(stricmp)
+#else
+ANTLR_C_USING(strcasecmp)
+#endif
+#endif
+
+/** Functor for the literals map
+ */
+class ANTLR_API CharScannerLiteralsLess : public ANTLR_USE_NAMESPACE(std)binary_function<ANTLR_USE_NAMESPACE(std)string,ANTLR_USE_NAMESPACE(std)string,bool> {
+private:
+       const CharScanner* scanner;
+public:
+#ifdef NO_TEMPLATE_PARTS
+       CharScannerLiteralsLess() {} // not really used, definition to appease MSVC
+#endif
+       CharScannerLiteralsLess(const CharScanner* theScanner)
+       : scanner(theScanner)
+       {
+       }
+       bool operator() (const ANTLR_USE_NAMESPACE(std)string& x,const ANTLR_USE_NAMESPACE(std)string& y) const;
+// defaults are good enough..
+       //      CharScannerLiteralsLess(const CharScannerLiteralsLess&);
+       //      CharScannerLiteralsLess& operator=(const CharScannerLiteralsLess&);
+};
+
+/** Superclass of generated lexers
+ */
+class ANTLR_API CharScanner : public TokenStream {
+protected:
+       typedef RefToken (*factory_type)();
+public:
+       CharScanner(InputBuffer& cb, bool case_sensitive );
+       CharScanner(InputBuffer* cb, bool case_sensitive );
+       CharScanner(const LexerSharedInputState& state, bool case_sensitive );
+
+       virtual ~CharScanner()
+       {
+       }
+
+       virtual int LA(unsigned int i);
+
+       virtual void append(char c)
+       {
+               if (saveConsumedInput)
+               {
+                       size_t l = text.length();
+
+                       if ((l%256) == 0)
+                               text.reserve(l+256);
+
+                       text.replace(l,0,&c,1);
+               }
+       }
+
+       virtual void append(const ANTLR_USE_NAMESPACE(std)string& s)
+       {
+               if( saveConsumedInput )
+                       text += s;
+       }
+
+       virtual void commit()
+       {
+               inputState->getInput().commit();
+       }
+
+       /** called by the generated lexer to do error recovery, override to
+        * customize the behaviour.
+        */
+       virtual void recover(const RecognitionException& ex, const BitSet& tokenSet)
+       {
+               consume();
+               consumeUntil(tokenSet);
+       }
+
+       virtual void consume()
+       {
+               if (inputState->guessing == 0)
+               {
+                       int c = LA(1);
+                       if (caseSensitive)
+                       {
+                               append(c);
+                       }
+                       else
+                       {
+                               // use input.LA(), not LA(), to get original case
+                               // CharScanner.LA() would toLower it.
+                               append(inputState->getInput().LA(1));
+                       }
+
+                       // RK: in a sense I don't like this automatic handling.
+                       if (c == '\t')
+                               tab();
+                       else
+                               inputState->column++;
+               }
+               inputState->getInput().consume();
+       }
+
+       /** Consume chars until one matches the given char */
+       virtual void consumeUntil(int c)
+       {
+               for(;;)
+               {
+                       int la_1 = LA(1);
+                       if( la_1 == EOF_CHAR || la_1 == c )
+                               break;
+                       consume();
+               }
+       }
+
+       /** Consume chars until one matches the given set */
+       virtual void consumeUntil(const BitSet& set)
+       {
+               for(;;)
+               {
+                       int la_1 = LA(1);
+                       if( la_1 == EOF_CHAR || set.member(la_1) )
+                               break;
+                       consume();
+               }
+       }
+
+       /// Mark the current position and return a id for it
+       virtual unsigned int mark()
+       {
+               return inputState->getInput().mark();
+       }
+       /// Rewind the scanner to a previously marked position
+       virtual void rewind(unsigned int pos)
+       {
+               inputState->getInput().rewind(pos);
+       }
+
+       /// See if input contains character 'c' throw MismatchedCharException if not
+       virtual void match(int c)
+       {
+               int la_1 = LA(1);
+               if ( la_1 != c )
+                       throw MismatchedCharException(la_1, c, false, this);
+               consume();
+       }
+
+       /** See if input contains element from bitset b
+        * throw MismatchedCharException if not
+        */
+       virtual void match(const BitSet& b)
+       {
+               int la_1 = LA(1);
+
+               if ( !b.member(la_1) )
+                       throw MismatchedCharException( la_1, b, false, this );
+               consume();
+       }
+
+       /** See if input contains string 's' throw MismatchedCharException if not
+        * @note the string cannot match EOF
+        */
+       virtual void match( const char* s )
+       {
+               while( *s != '\0' )
+               {
+                       // the & 0xFF is here to prevent sign extension lateron
+                       int la_1 = LA(1), c = (*s++ & 0xFF);
+
+                       if ( la_1 != c )
+                               throw MismatchedCharException(la_1, c, false, this);
+
+                       consume();
+               }
+       }
+       /** See if input contains string 's' throw MismatchedCharException if not
+        * @note the string cannot match EOF
+        */
+       virtual void match(const ANTLR_USE_NAMESPACE(std)string& s)
+       {
+               size_t len = s.length();
+
+               for (size_t i = 0; i < len; i++)
+               {
+                       // the & 0xFF is here to prevent sign extension lateron
+                       int la_1 = LA(1), c = (s[i] & 0xFF);
+
+                       if ( la_1 != c )
+                               throw MismatchedCharException(la_1, c, false, this);
+
+                       consume();
+               }
+       }
+       /** See if input does not contain character 'c'
+        * throw MismatchedCharException if not
+        */
+       virtual void matchNot(int c)
+       {
+               int la_1 = LA(1);
+
+               if ( la_1 == c )
+                       throw MismatchedCharException(la_1, c, true, this);
+
+               consume();
+       }
+       /** See if input contains character in range c1-c2
+        * throw MismatchedCharException if not
+        */
+       virtual void matchRange(int c1, int c2)
+       {
+               int la_1 = LA(1);
+
+               if ( la_1 < c1 || la_1 > c2 )
+                       throw MismatchedCharException(la_1, c1, c2, false, this);
+
+               consume();
+       }
+
+       virtual bool getCaseSensitive() const
+       {
+               return caseSensitive;
+       }
+
+       virtual void setCaseSensitive(bool t)
+       {
+               caseSensitive = t;
+       }
+
+       virtual bool getCaseSensitiveLiterals() const=0;
+
+       /// Get the line the scanner currently is in (starts at 1)
+       virtual int getLine() const
+       {
+               return inputState->line;
+       }
+
+       /// set the line number
+       virtual void setLine(int l)
+       {
+               inputState->line = l;
+       }
+
+       /// Get the column the scanner currently is in (starts at 1)
+       virtual int getColumn() const
+       {
+               return inputState->column;
+       }
+       /// set the column number
+       virtual void setColumn(int c)
+       {
+               inputState->column = c;
+       }
+
+       /// get the filename for the file currently used
+       virtual const ANTLR_USE_NAMESPACE(std)string& getFilename() const
+       {
+               return inputState->filename;
+       }
+       /// Set the filename the scanner is using (used in error messages)
+       virtual void setFilename(const ANTLR_USE_NAMESPACE(std)string& f)
+       {
+               inputState->filename = f;
+       }
+
+       virtual bool getCommitToPath() const
+       {
+               return commitToPath;
+       }
+
+       virtual void setCommitToPath(bool commit)
+       {
+               commitToPath = commit;
+       }
+
+       /** return a copy of the current text buffer */
+       virtual const ANTLR_USE_NAMESPACE(std)string& getText() const
+       {
+               return text;
+       }
+
+       virtual void setText(const ANTLR_USE_NAMESPACE(std)string& s)
+       {
+               text = s;
+       }
+
+       virtual void resetText()
+       {
+               text = "";
+               inputState->tokenStartColumn = inputState->column;
+               inputState->tokenStartLine = inputState->line;
+       }
+
+       virtual RefToken getTokenObject() const
+       {
+               return _returnToken;
+       }
+
+       /** Used to keep track of line breaks, needs to be called from
+        * within generated lexers when a \n \r is encountered.
+        */
+       virtual void newline()
+       {
+               ++inputState->line;
+               inputState->column = 1;
+       }
+
+       /** Advance the current column number by an appropriate amount according
+        * to the tabsize. This method needs to be explicitly called from the
+        * lexer rules encountering tabs.
+        */
+       virtual void tab()
+       {
+               int c = getColumn();
+               int nc = ( ((c-1)/tabsize) + 1) * tabsize + 1;      // calculate tab stop
+               setColumn( nc );
+       }
+       /// set the tabsize. Returns the old tabsize
+       int setTabsize( int size )
+       {
+               int oldsize = tabsize;
+               tabsize = size;
+               return oldsize;
+       }
+       /// Return the tabsize used by the scanner
+       int getTabSize() const
+       {
+               return tabsize;
+       }
+
+       /** Report exception errors caught in nextToken() */
+       virtual void reportError(const RecognitionException& e);
+
+       /** Parser error-reporting function can be overridden in subclass */
+       virtual void reportError(const ANTLR_USE_NAMESPACE(std)string& s);
+
+       /** Parser warning-reporting function can be overridden in subclass */
+       virtual void reportWarning(const ANTLR_USE_NAMESPACE(std)string& s);
+
+       virtual InputBuffer& getInputBuffer()
+       {
+               return inputState->getInput();
+       }
+
+       virtual LexerSharedInputState getInputState()
+       {
+               return inputState;
+       }
+
+       /** set the input state for the lexer.
+        * @note state is a reference counted object, hence no reference */
+       virtual void setInputState(LexerSharedInputState state)
+       {
+               inputState = state;
+       }
+
+       /// Set the factory for created tokens
+       virtual void setTokenObjectFactory(factory_type factory)
+       {
+               tokenFactory = factory;
+       }
+
+       /** Test the token text against the literals table
+        * Override this method to perform a different literals test
+        */
+       virtual int testLiteralsTable(int ttype) const
+       {
+               ANTLR_USE_NAMESPACE(std)map<ANTLR_USE_NAMESPACE(std)string,int,CharScannerLiteralsLess>::const_iterator i = literals.find(text);
+               if (i != literals.end())
+                       ttype = (*i).second;
+               return ttype;
+       }
+
+       /** Test the text passed in against the literals table
+        * Override this method to perform a different literals test
+        * This is used primarily when you want to test a portion of
+        * a token
+        */
+       virtual int testLiteralsTable(const ANTLR_USE_NAMESPACE(std)string& txt,int ttype) const
+       {
+               ANTLR_USE_NAMESPACE(std)map<ANTLR_USE_NAMESPACE(std)string,int,CharScannerLiteralsLess>::const_iterator i = literals.find(txt);
+               if (i != literals.end())
+                       ttype = (*i).second;
+               return ttype;
+       }
+
+       /// Override this method to get more specific case handling
+       virtual int toLower(int c) const
+       {
+               // test on EOF_CHAR for buggy (?) STLPort tolower (or HPUX tolower?)
+               // also VC++ 6.0 does this. (see fix 422 (is reverted by this fix)
+               // this one is more structural. Maybe make this configurable.
+               return (c == EOF_CHAR ? EOF_CHAR : tolower(c));
+       }
+
+       /** This method is called by YourLexer::nextToken() when the lexer has
+        *  hit EOF condition.  EOF is NOT a character.
+        *  This method is not called if EOF is reached during
+        *  syntactic predicate evaluation or during evaluation
+        *  of normal lexical rules, which presumably would be
+        *  an IOException.  This traps the "normal" EOF condition.
+        *
+        *  uponEOF() is called after the complete evaluation of
+        *  the previous token and only if your parser asks
+        *  for another token beyond that last non-EOF token.
+        *
+        *  You might want to throw token or char stream exceptions
+        *  like: "Heh, premature eof" or a retry stream exception
+        *  ("I found the end of this file, go back to referencing file").
+        */
+       virtual void uponEOF()
+       {
+       }
+
+       /// Methods used to change tracing behavior
+       virtual void traceIndent();
+       virtual void traceIn(const char* rname);
+       virtual void traceOut(const char* rname);
+
+#ifndef NO_STATIC_CONSTS
+       static const int EOF_CHAR = EOF;
+#else
+       enum {
+               EOF_CHAR = EOF
+       };
+#endif
+protected:
+       ANTLR_USE_NAMESPACE(std)string text; ///< Text of current token
+       /// flag indicating wether consume saves characters
+       bool saveConsumedInput;
+       factory_type tokenFactory;                              ///< Factory for tokens
+       bool caseSensitive;                                             ///< Is this lexer case sensitive
+       ANTLR_USE_NAMESPACE(std)map<ANTLR_USE_NAMESPACE(std)string,int,CharScannerLiteralsLess> literals; // set by subclass
+
+       RefToken _returnToken;          ///< used to return tokens w/o using return val
+
+       /// Input state, gives access to input stream, shared among different lexers
+       LexerSharedInputState inputState;
+
+       /** Used during filter mode to indicate that path is desired.
+        * A subsequent scan error will report an error as usual
+        * if acceptPath=true;
+        */
+       bool commitToPath;
+
+       int tabsize;    ///< tab size the scanner uses.
+
+       /// Create a new RefToken of type t
+       virtual RefToken makeToken(int t)
+       {
+               RefToken tok = tokenFactory();
+               tok->setType(t);
+               tok->setColumn(inputState->tokenStartColumn);
+               tok->setLine(inputState->tokenStartLine);
+               return tok;
+       }
+
+       /** Tracer class, used when -traceLexer is passed to antlr
+        */
+       class Tracer {
+       private:
+               CharScanner* parser;
+               const char* text;
+
+               Tracer(const Tracer& other);                                    // undefined
+               Tracer& operator=(const Tracer& other);         // undefined
+       public:
+               Tracer( CharScanner* p,const char* t )
+               : parser(p), text(t)
+               {
+                       parser->traceIn(text);
+               }
+               ~Tracer()
+               {
+                       parser->traceOut(text);
+               }
+       };
+
+       int traceDepth;
+private:
+       CharScanner( const CharScanner& other );                                        // undefined
+       CharScanner& operator=( const CharScanner& other );     // undefined
+
+#ifndef NO_STATIC_CONSTS
+       static const int NO_CHAR = 0;
+#else
+       enum {
+               NO_CHAR = 0
+       };
+#endif
+};
+
+inline int CharScanner::LA(unsigned int i)
+{
+       int c = inputState->getInput().LA(i);
+
+       if ( caseSensitive )
+               return c;
+       else
+               return toLower(c);      // VC 6 tolower bug caught in toLower.
+}
+
+inline bool CharScannerLiteralsLess::operator() (const ANTLR_USE_NAMESPACE(std)string& x,const ANTLR_USE_NAMESPACE(std)string& y) const
+{
+       if (scanner->getCaseSensitiveLiterals())
+               return ANTLR_USE_NAMESPACE(std)less<ANTLR_USE_NAMESPACE(std)string>()(x,y);
+       else
+       {
+#ifdef NO_STRCASECMP
+               return (stricmp(x.c_str(),y.c_str())<0);
+#else
+               return (strcasecmp(x.c_str(),y.c_str())<0);
+#endif
+       }
+}
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_CharScanner_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/CharStreamException.hpp b/libsecurity_codesigning/antlr2/antlr/CharStreamException.hpp
new file mode 100644 (file)
index 0000000..ee7ad43
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef INC_CharStreamException_hpp__
+#define INC_CharStreamException_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/CharStreamException.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/ANTLRException.hpp>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+class ANTLR_API CharStreamException : public ANTLRException {
+public:
+       CharStreamException(const ANTLR_USE_NAMESPACE(std)string& s)
+               : ANTLRException(s) {}
+       ~CharStreamException() throw() {}
+};
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_CharStreamException_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/CharStreamIOException.hpp b/libsecurity_codesigning/antlr2/antlr/CharStreamIOException.hpp
new file mode 100644 (file)
index 0000000..ebbb0fd
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef INC_CharStreamIOException_hpp__
+#define INC_CharStreamIOException_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/CharStreamIOException.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/CharStreamException.hpp>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+class ANTLR_API CharStreamIOException : public CharStreamException {
+public:
+       ANTLR_USE_NAMESPACE(std)exception io;
+
+       CharStreamIOException(ANTLR_USE_NAMESPACE(std)exception& e)
+               : CharStreamException(e.what()), io(e) {}
+       ~CharStreamIOException() throw() {}
+};
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_CharStreamIOException_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/CircularQueue.hpp b/libsecurity_codesigning/antlr2/antlr/CircularQueue.hpp
new file mode 100644 (file)
index 0000000..a4d1154
--- /dev/null
@@ -0,0 +1,100 @@
+#ifndef INC_CircularQueue_hpp__
+#define INC_CircularQueue_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/CircularQueue.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/Token.hpp>
+#include <vector>
+#include <cassert>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+// Resize every 5000 items
+#define OFFSET_MAX_RESIZE 5000
+
+template <class T>
+class ANTLR_API CircularQueue {
+public:
+       CircularQueue()
+       : storage()
+       , m_offset(0)
+       {
+       }
+       ~CircularQueue()
+       {
+       }
+
+       /// Clear the queue
+       inline void clear( void )
+       {
+               m_offset = 0;
+               storage.clear();
+       }
+
+       /// @todo this should use at or should have a check
+       inline T elementAt( size_t idx ) const
+       {
+               return storage[idx+m_offset];
+       }
+       void removeFirst()
+       {
+               if (m_offset >= OFFSET_MAX_RESIZE)
+               {
+                       storage.erase( storage.begin(), storage.begin() + m_offset + 1 );
+                       m_offset = 0;
+               }
+               else
+                       ++m_offset;
+       }
+       inline void removeItems( size_t nb )
+       {
+               // it would be nice if we would not get called with nb > entries
+               // (or to be precise when entries() == 0)
+               // This case is possible when lexer/parser::recover() calls
+               // consume+consumeUntil when the queue is empty.
+               // In recover the consume says to prepare to read another
+               // character/token. Then in the subsequent consumeUntil the
+               // LA() call will trigger
+               // syncConsume which calls this method *before* the same queue
+               // has been sufficiently filled.
+               if( nb > entries() )
+                       nb = entries();
+
+               if (m_offset >= OFFSET_MAX_RESIZE)
+               {
+                       storage.erase( storage.begin(), storage.begin() + m_offset + nb );
+                       m_offset = 0;
+               }
+               else
+                       m_offset += nb;
+       }
+       inline void append(const T& t)
+       {
+               storage.push_back(t);
+       }
+       inline size_t entries() const
+       {
+               return storage.size() - m_offset;
+       }
+
+private:
+       ANTLR_USE_NAMESPACE(std)vector<T> storage;
+       size_t m_offset;
+
+       CircularQueue(const CircularQueue&);
+       const CircularQueue& operator=(const CircularQueue&);
+};
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_CircularQueue_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/CommonAST.hpp b/libsecurity_codesigning/antlr2/antlr/CommonAST.hpp
new file mode 100644 (file)
index 0000000..ab16aa2
--- /dev/null
@@ -0,0 +1,110 @@
+#ifndef INC_CommonAST_hpp__
+#define INC_CommonAST_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/CommonAST.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/BaseAST.hpp>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+class ANTLR_API CommonAST : public BaseAST {
+public:
+       CommonAST()
+       : BaseAST()
+       , ttype( Token::INVALID_TYPE )
+       , text()
+       {
+       }
+
+       CommonAST( RefToken t )
+       : BaseAST()
+       , ttype( t->getType() )
+       , text( t->getText() )
+       {
+       }
+
+       CommonAST( const CommonAST& other )
+       : BaseAST(other)
+       , ttype(other.ttype)
+       , text(other.text)
+       {
+       }
+
+       virtual ~CommonAST()
+       {
+       }
+
+       virtual const char* typeName( void ) const
+       {
+               return CommonAST::TYPE_NAME;
+       }
+
+       /// Clone this AST node.
+       virtual RefAST clone( void ) const
+       {
+               CommonAST *ast = new CommonAST( *this );
+               return RefAST(ast);
+       }
+
+       virtual ANTLR_USE_NAMESPACE(std)string getText() const
+       {
+               return text;
+       }
+       virtual int getType() const
+       {
+               return ttype;
+       }
+
+       virtual void initialize( int t, const ANTLR_USE_NAMESPACE(std)string& txt )
+       {
+               setType(t);
+               setText(txt);
+       }
+
+       virtual void initialize( RefAST t )
+       {
+               setType(t->getType());
+               setText(t->getText());
+       }
+       virtual void initialize( RefToken t )
+       {
+               setType(t->getType());
+               setText(t->getText());
+       }
+
+#ifdef ANTLR_SUPPORT_XML
+       virtual void initialize( ANTLR_USE_NAMESPACE(std)istream& in );
+#endif
+
+       virtual void setText( const ANTLR_USE_NAMESPACE(std)string& txt )
+       {
+               text = txt;
+       }
+       virtual void setType( int type )
+       {
+               ttype = type;
+       }
+
+       static RefAST factory();
+
+       static const char* const TYPE_NAME;
+protected:
+       int ttype;
+       ANTLR_USE_NAMESPACE(std)string text;
+};
+
+typedef ASTRefCount<CommonAST> RefCommonAST;
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_CommonAST_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/CommonASTWithHiddenTokens.hpp b/libsecurity_codesigning/antlr2/antlr/CommonASTWithHiddenTokens.hpp
new file mode 100644 (file)
index 0000000..8fa4d93
--- /dev/null
@@ -0,0 +1,60 @@
+#ifndef INC_CommonASTWithHiddenTokens_hpp__
+#define INC_CommonASTWithHiddenTokens_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/CommonASTWithHiddenTokens.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/CommonAST.hpp>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/** A CommonAST whose initialization copies hidden token
+ *  information from the Token used to create a node.
+ */
+class ANTLR_API CommonASTWithHiddenTokens : public CommonAST {
+public:
+       CommonASTWithHiddenTokens();
+       virtual ~CommonASTWithHiddenTokens();
+       virtual const char* typeName( void ) const
+       {
+               return CommonASTWithHiddenTokens::TYPE_NAME;
+       }
+       /// Clone this AST node.
+       virtual RefAST clone( void ) const;
+
+       // Borland C++ builder seems to need the decl's of the first two...
+       virtual void initialize(int t,const ANTLR_USE_NAMESPACE(std)string& txt);
+       virtual void initialize(RefAST t);
+       virtual void initialize(RefToken t);
+
+       virtual RefToken getHiddenAfter() const
+       {
+               return hiddenAfter;
+       }
+
+       virtual RefToken getHiddenBefore() const
+       {
+               return hiddenBefore;
+       }
+
+       static RefAST factory();
+
+       static const char* const TYPE_NAME;
+protected:
+       RefToken hiddenBefore,hiddenAfter; // references to hidden tokens
+};
+
+typedef ASTRefCount<CommonASTWithHiddenTokens> RefCommonASTWithHiddenTokens;
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_CommonASTWithHiddenTokens_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/CommonHiddenStreamToken.hpp b/libsecurity_codesigning/antlr2/antlr/CommonHiddenStreamToken.hpp
new file mode 100644 (file)
index 0000000..30a7015
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef INC_CommonHiddenStreamToken_hpp__
+#define INC_CommonHiddenStreamToken_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/CommonHiddenStreamToken.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/CommonToken.hpp>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+class ANTLR_API CommonHiddenStreamToken : public CommonToken {
+protected:
+       RefToken hiddenBefore;
+       RefToken hiddenAfter;
+
+public:
+       CommonHiddenStreamToken();
+       CommonHiddenStreamToken(int t, const ANTLR_USE_NAMESPACE(std)string& txt);
+       CommonHiddenStreamToken(const ANTLR_USE_NAMESPACE(std)string& s);
+
+       RefToken getHiddenAfter();
+       RefToken getHiddenBefore();
+
+   static RefToken factory();
+
+       void setHiddenAfter(RefToken t);
+       void setHiddenBefore(RefToken t);
+};
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_CommonHiddenStreamToken_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/CommonToken.hpp b/libsecurity_codesigning/antlr2/antlr/CommonToken.hpp
new file mode 100644 (file)
index 0000000..8a032d7
--- /dev/null
@@ -0,0 +1,83 @@
+#ifndef INC_CommonToken_hpp__
+#define INC_CommonToken_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/CommonToken.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/Token.hpp>
+#include <string>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+class ANTLR_API CommonToken : public Token {
+public:
+       CommonToken();
+       CommonToken(int t, const ANTLR_USE_NAMESPACE(std)string& txt);
+       CommonToken(const ANTLR_USE_NAMESPACE(std)string& s);
+
+       /// return contents of token
+       virtual ANTLR_USE_NAMESPACE(std)string getText() const
+       {
+               return text;
+       }
+
+       /// set contents of token
+       virtual void setText(const ANTLR_USE_NAMESPACE(std)string& s)
+       {
+               text = s;
+       }
+
+       /** get the line the token is at (starting at 1)
+        * @see CharScanner::newline()
+        * @see CharScanner::tab()
+        */
+       virtual int getLine() const
+       {
+               return line;
+       }
+       /** gt the column the token is at (starting at 1)
+        * @see CharScanner::newline()
+        * @see CharScanner::tab()
+        */
+       virtual int getColumn() const
+       {
+               return col;
+       }
+
+       /// set line for token
+       virtual void setLine(int l)
+       {
+               line = l;
+       }
+       /// set column for token
+       virtual void setColumn(int c)
+       {
+               col = c;
+       }
+
+       virtual ANTLR_USE_NAMESPACE(std)string toString() const;
+       static RefToken factory();
+
+protected:
+       // most tokens will want line and text information
+       int line;
+       int col;
+       ANTLR_USE_NAMESPACE(std)string text;
+
+private:
+       CommonToken(const CommonToken&);
+       const CommonToken& operator=(const CommonToken&);
+};
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_CommonToken_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/IOException.hpp b/libsecurity_codesigning/antlr2/antlr/IOException.hpp
new file mode 100644 (file)
index 0000000..ed87f8a
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef INC_IOException_hpp__
+#define INC_IOException_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id:$
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/ANTLRException.hpp>
+#include <exception>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/** Generic IOException used inside support code. (thrown by XML I/O routs)
+ * basically this is something I'm using since a lot of compilers don't
+ * support ios_base::failure.
+ */
+class ANTLR_API IOException : public ANTLRException
+{
+public:
+       ANTLR_USE_NAMESPACE(std)exception io;
+
+       IOException( ANTLR_USE_NAMESPACE(std)exception& e )
+               : ANTLRException(e.what())
+       {
+       }
+       IOException( const ANTLR_USE_NAMESPACE(std)string& mesg )
+               : ANTLRException(mesg)
+       {
+       }
+       virtual ~IOException() throw()
+       {
+       }
+};
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_IOException_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/InputBuffer.hpp b/libsecurity_codesigning/antlr2/antlr/InputBuffer.hpp
new file mode 100644 (file)
index 0000000..f557f40
--- /dev/null
@@ -0,0 +1,146 @@
+#ifndef INC_InputBuffer_hpp__
+#define INC_InputBuffer_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/InputBuffer.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/CircularQueue.hpp>
+#include <string>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/** A Stream of characters fed to the lexer from a InputStream that can
+ * be rewound via mark()/rewind() methods.
+ * <p>
+ * A dynamic array is used to buffer up all the input characters.  Normally,
+ * "k" characters are stored in the buffer.  More characters may be stored during
+ * guess mode (testing syntactic predicate), or when LT(i>k) is referenced.
+ * Consumption of characters is deferred.  In other words, reading the next
+ * character is not done by conume(), but deferred until needed by LA or LT.
+ * <p>
+ *
+ * @see antlr.CharQueue
+ */
+class ANTLR_API InputBuffer {
+public:
+       /** Create a character buffer */
+       InputBuffer()
+       : nMarkers(0)
+       , markerOffset(0)
+       , numToConsume(0)
+       {
+       }
+
+       virtual ~InputBuffer()
+       {
+       }
+
+       /// Reset the input buffer to empty state
+       virtual inline void reset( void )
+       {
+               nMarkers = 0;
+               markerOffset = 0;
+               numToConsume = 0;
+               queue.clear();
+       }
+
+       /** This method updates the state of the input buffer so that
+        * the text matched since the most recent mark() is no longer
+        * held by the buffer.  So, you either do a mark/rewind for
+        * failed predicate or mark/commit to keep on parsing without
+        * rewinding the input.
+        */
+       inline void commit( void )
+       {
+               nMarkers--;
+       }
+
+       /** Mark another character for deferred consumption */
+       virtual inline void consume()
+       {
+               numToConsume++;
+       }
+
+       /** Ensure that the character buffer is sufficiently full */
+       virtual void fill(unsigned int amount);
+
+       /** Override this in subclasses to get the next character */
+       virtual int getChar()=0;
+
+       /** Get a lookahead character */
+       virtual inline int LA(unsigned int i)
+       {
+               fill(i);
+               return queue.elementAt(markerOffset + i - 1);
+       }
+
+       /** Return an integer marker that can be used to rewind the buffer to
+        * its current state.
+        */
+       virtual unsigned int mark();
+       /// Are there any marks active in the InputBuffer
+       virtual inline bool isMarked() const
+       {
+               return (nMarkers != 0);
+       }
+       /** Rewind the character buffer to a marker.
+        * @param mark Marker returned previously from mark()
+        */
+       virtual void rewind(unsigned int mark);
+
+       /** Get the number of non-consumed characters
+        */
+       virtual unsigned int entries() const;
+
+       ANTLR_USE_NAMESPACE(std)string getLAChars() const;
+
+       ANTLR_USE_NAMESPACE(std)string getMarkedChars() const;
+
+protected:
+       // char source
+       // leave to subclasses
+
+       // Number of active markers
+       unsigned int nMarkers; // = 0;
+
+       // Additional offset used when markers are active
+       unsigned int markerOffset; // = 0;
+
+       // Number of calls to consume() since last LA() or LT() call
+       unsigned int numToConsume; // = 0;
+
+       // Circular queue
+       CircularQueue<int> queue;
+
+       /** Sync up deferred consumption */
+       void syncConsume();
+
+private:
+       InputBuffer(const InputBuffer& other);
+       InputBuffer& operator=(const InputBuffer& other);
+};
+
+/** Sync up deferred consumption */
+inline void InputBuffer::syncConsume() {
+       if (numToConsume > 0)
+       {
+               if (nMarkers > 0)
+                       markerOffset += numToConsume;
+               else
+                       queue.removeItems( numToConsume );
+               numToConsume = 0;
+       }
+}
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_InputBuffer_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/LLkParser.hpp b/libsecurity_codesigning/antlr2/antlr/LLkParser.hpp
new file mode 100644 (file)
index 0000000..ef9181a
--- /dev/null
@@ -0,0 +1,67 @@
+#ifndef INC_LLkParser_hpp__
+#define INC_LLkParser_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/LLkParser.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/Parser.hpp>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/**An LL(k) parser.
+ *
+ * @see antlr.Token
+ * @see antlr.TokenBuffer
+ * @see antlr.LL1Parser
+ */
+class ANTLR_API LLkParser : public Parser {
+public:
+       LLkParser(const ParserSharedInputState& lexer, int k_);
+
+       LLkParser(TokenBuffer& tokenBuf, int k_);
+
+       LLkParser(TokenStream& lexer, int k_);
+
+       /** Consume another token from the input stream.  Can only write sequentially!
+        * If you need 3 tokens ahead, you must consume() 3 times.
+        * <p>
+        * Note that it is possible to overwrite tokens that have not been matched.
+        * For example, calling consume() 3 times when k=2, means that the first token
+        * consumed will be overwritten with the 3rd.
+        */
+       virtual inline void consume()
+       {
+               inputState->getInput().consume();
+       }
+
+       virtual inline int LA(unsigned int i)
+       {
+               return inputState->getInput().LA(i);
+       }
+
+       virtual inline RefToken LT(unsigned int i)
+       {
+               return inputState->getInput().LT(i);
+       }
+protected:
+       /// the lookahead this LL(k) parser is using.
+       int k;
+private:
+       void trace(const char* ee, const char* rname);
+public:
+       virtual void traceIn(const char* rname);
+       virtual void traceOut(const char* rname);
+};
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_LLkParser_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/LexerSharedInputState.hpp b/libsecurity_codesigning/antlr2/antlr/LexerSharedInputState.hpp
new file mode 100644 (file)
index 0000000..ff082dc
--- /dev/null
@@ -0,0 +1,156 @@
+#ifndef INC_LexerSharedInputState_hpp__
+#define INC_LexerSharedInputState_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/LexerSharedInputState.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/InputBuffer.hpp>
+#include <antlr/RefCount.hpp>
+#include <antlr/CharBuffer.hpp>
+#include <string>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/** This object contains the data associated with an
+ *  input stream of characters.  Multiple lexers
+ *  share a single LexerSharedInputState to lex
+ *  the same input stream.
+ */
+class ANTLR_API LexerInputState {
+public:
+       /** Construct a new LexerInputState
+        * @param inbuf the InputBuffer to read from. The object is deleted together
+        * with the LexerInputState object.
+        */
+       LexerInputState(InputBuffer* inbuf)
+       : column(1)
+       , line(1)
+       , tokenStartColumn(1)
+       , tokenStartLine(1)
+       , guessing(0)
+       , filename("")
+       , input(inbuf)
+       , inputResponsible(true)
+       {
+       }
+
+       /** Construct a new LexerInputState
+        * @param inbuf the InputBuffer to read from.
+        */
+       LexerInputState(InputBuffer& inbuf)
+       : column(1)
+       , line(1)
+       , tokenStartColumn(1)
+       , tokenStartLine(1)
+       , guessing(0)
+       , filename("")
+       , input(&inbuf)
+       , inputResponsible(false)
+       {
+       }
+
+       /** Construct a new LexerInputState
+        * @param in an istream to read from.
+        * @see antlr.CharBuffer
+        */
+       LexerInputState(ANTLR_USE_NAMESPACE(std)istream& in)
+       : column(1)
+       , line(1)
+       , tokenStartColumn(1)
+       , tokenStartLine(1)
+       , guessing(0)
+       , filename("")
+       , input(new CharBuffer(in))
+       , inputResponsible(true)
+       {
+       }
+
+       /** Reset the LexerInputState with a specified stream and filename.
+        * This method is a hack, dunno what I was thinking when I added it.
+        * This should actually be done in a subclass.
+        * @deprecated
+        */
+       virtual void initialize( ANTLR_USE_NAMESPACE(std)istream& in, const char* file = "" )
+       {
+               column = 1;
+               line = 1;
+               tokenStartColumn = 1;
+               tokenStartLine = 1;
+               guessing = 0;
+               filename = file;
+
+               if( input && inputResponsible )
+                       delete input;
+
+               input = new CharBuffer(in);
+               inputResponsible = true;
+       }
+
+       /** Reset the LexerInputState to initial state.
+        * The underlying InputBuffer is also reset.
+        */
+       virtual void reset( void )
+       {
+               column = 1;
+               line = 1;
+               tokenStartColumn = 1;
+               tokenStartLine = 1;
+               guessing = 0;
+               input->reset();
+       }
+
+       /** Set the file position of the SharedLexerInputState.
+        * @param line_ line number to be set
+        * @param column_ column number to be set
+        */
+       void setPosition( int line_, int column_ )
+       {
+               line = line_;
+               column = column_;
+       }
+
+       virtual ~LexerInputState()
+       {
+               if (inputResponsible)
+                       delete input;
+       }
+
+       int column;
+       int line;
+       int tokenStartColumn;
+       int tokenStartLine;
+       int guessing;
+       /** What file (if known) caused the problem? */
+       ANTLR_USE_NAMESPACE(std)string filename;
+       InputBuffer& getInput();
+private:
+       /// Input buffer we use
+       InputBuffer* input;
+       /// Who is responsible for cleaning up the InputBuffer?
+       bool inputResponsible;
+
+       // we don't want these:
+       LexerInputState(const LexerInputState&);
+       LexerInputState& operator=(const LexerInputState&);
+};
+
+inline InputBuffer& LexerInputState::getInput()
+{
+       return *input;
+}
+
+/// A reference counted LexerInputState object
+typedef RefCount<LexerInputState> LexerSharedInputState;
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_LexerSharedInputState_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/Makefile.in b/libsecurity_codesigning/antlr2/antlr/Makefile.in
new file mode 100644 (file)
index 0000000..210c8b4
--- /dev/null
@@ -0,0 +1,89 @@
+###############################################################################
+# $Id:$
+###############################################################################
+
+##xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+@stdvars@
+##xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+
+## do not change this value 
+subdir=lib/cpp/antlr
+
+antlr_hpp_FILES = \
+  @abs_top_srcdir@/lib/cpp/antlr/ANTLRException.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/ANTLRUtil.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/ASTArray.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/ASTFactory.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/AST.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/ASTNULLType.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/ASTPair.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/ASTRefCount.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/BaseAST.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/BitSet.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/CharBuffer.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/CharInputBuffer.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/CharScanner.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/CharStreamException.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/CharStreamIOException.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/CircularQueue.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/CommonAST.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/CommonASTWithHiddenTokens.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/CommonHiddenStreamToken.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/CommonToken.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/config.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/Countable.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/InputBuffer.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/IOException.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/LexerSharedInputState.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/LLkParser.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/MismatchedCharException.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/MismatchedTokenException.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/NoViableAltException.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/NoViableAltForCharException.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/Parser.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/ParserSharedInputState.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/RecognitionException.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/RefCount.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/SemanticException.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/String.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/TokenBuffer.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/Token.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/TokenRefCount.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/TokenStreamBasicFilter.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/TokenStreamException.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/TokenStreamHiddenTokenFilter.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/TokenStream.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/TokenStreamIOException.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/TokenStreamRecognitionException.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/TokenStreamRetryException.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/TokenStreamRewriteEngine.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/TokenStreamSelector.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/TokenWithIndex.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/TreeParser.hpp \
+  @abs_top_srcdir@/lib/cpp/antlr/TreeParserSharedInputState.hpp \
+       $(eol)
+
+
+all : 
+
+clean:
+
+distclean: clean
+       @RMF@ Makefile
+
+test:
+
+install:
+       @@ECHO@ "install hpp files .. "
+       @$(MKDIR) -p "$(includedir)/antlr"
+       @for f in $(antlr_hpp_FILES) ; do \
+               @ECHO@ "install $${f}" ; \
+               if test -f "$${f}" ; then \
+                       $(INSTALL) -m 444 "$${f}" "$(includedir)/antlr" ; \
+               fi ;\
+       done
+
+.PHONY: all clean distclean install test
+##xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+@stddeps@
+##xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
diff --git a/libsecurity_codesigning/antlr2/antlr/MismatchedCharException.hpp b/libsecurity_codesigning/antlr2/antlr/MismatchedCharException.hpp
new file mode 100644 (file)
index 0000000..4505412
--- /dev/null
@@ -0,0 +1,102 @@
+#ifndef INC_MismatchedCharException_hpp__
+#define INC_MismatchedCharException_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/MismatchedCharException.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/RecognitionException.hpp>
+#include <antlr/BitSet.hpp>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+class CharScanner;
+
+class ANTLR_API MismatchedCharException : public RecognitionException {
+public:
+       // Types of chars
+#ifndef NO_STATIC_CONSTS
+       static const int CHAR = 1;
+       static const int NOT_CHAR = 2;
+       static const int RANGE = 3;
+       static const int NOT_RANGE = 4;
+       static const int SET = 5;
+       static const int NOT_SET = 6;
+#else
+       enum {
+               CHAR = 1,
+               NOT_CHAR = 2,
+               RANGE = 3,
+               NOT_RANGE = 4,
+               SET = 5,
+               NOT_SET = 6
+       };
+#endif
+
+public:
+       // One of the above
+       int mismatchType;
+
+       // what was found on the input stream
+       int foundChar;
+
+       // For CHAR/NOT_CHAR and RANGE/NOT_RANGE
+       int expecting;
+
+       // For RANGE/NOT_RANGE (expecting is lower bound of range)
+       int upper;
+
+       // For SET/NOT_SET
+       BitSet set;
+
+protected:
+       // who knows...they may want to ask scanner questions
+       CharScanner* scanner;
+
+public:
+       MismatchedCharException();
+
+       // Expected range / not range
+       MismatchedCharException(
+               int c,
+               int lower,
+               int upper_,
+               bool matchNot,
+               CharScanner* scanner_
+       );
+
+       // Expected token / not token
+       MismatchedCharException(
+               int c,
+               int expecting_,
+               bool matchNot,
+               CharScanner* scanner_
+       );
+
+       // Expected BitSet / not BitSet
+       MismatchedCharException(
+               int c,
+               BitSet set_,
+               bool matchNot,
+               CharScanner* scanner_
+       );
+
+       ~MismatchedCharException() throw() {}
+
+       /**
+        * Returns a clean error message (no line number/column information)
+        */
+       ANTLR_USE_NAMESPACE(std)string getMessage() const;
+};
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_MismatchedCharException_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/MismatchedTokenException.hpp b/libsecurity_codesigning/antlr2/antlr/MismatchedTokenException.hpp
new file mode 100644 (file)
index 0000000..4631f50
--- /dev/null
@@ -0,0 +1,144 @@
+#ifndef INC_MismatchedTokenException_hpp__
+#define INC_MismatchedTokenException_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/MismatchedTokenException.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/RecognitionException.hpp>
+#include <antlr/BitSet.hpp>
+#include <antlr/Token.hpp>
+#include <antlr/AST.hpp>
+#include <vector>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+class ANTLR_API MismatchedTokenException : public RecognitionException {
+public:
+       MismatchedTokenException();
+
+       /// Expected range / not range
+       MismatchedTokenException(
+               const char* const* tokenNames_,
+               const int numTokens_,
+               RefAST node_,
+               int lower,
+               int upper_,
+               bool matchNot
+       );
+
+       // Expected token / not token
+       MismatchedTokenException(
+               const char* const* tokenNames_,
+               const int numTokens_,
+               RefAST node_,
+               int expecting_,
+               bool matchNot
+       );
+
+       // Expected BitSet / not BitSet
+       MismatchedTokenException(
+               const char* const* tokenNames_,
+               const int numTokens_,
+               RefAST node_,
+               BitSet set_,
+               bool matchNot
+       );
+
+       // Expected range / not range
+       MismatchedTokenException(
+               const char* const* tokenNames_,
+               const int numTokens_,
+               RefToken token_,
+               int lower,
+               int upper_,
+               bool matchNot,
+               const ANTLR_USE_NAMESPACE(std)string& fileName_
+       );
+
+       // Expected token / not token
+       MismatchedTokenException(
+               const char* const* tokenNames_,
+               const int numTokens_,
+               RefToken token_,
+               int expecting_,
+               bool matchNot,
+               const ANTLR_USE_NAMESPACE(std)string& fileName_
+       );
+
+       // Expected BitSet / not BitSet
+       MismatchedTokenException(
+               const char* const* tokenNames_,
+               const int numTokens_,
+               RefToken token_,
+               BitSet set_,
+               bool matchNot,
+               const ANTLR_USE_NAMESPACE(std)string& fileName_
+       );
+       ~MismatchedTokenException() throw() {}
+
+       /**
+        * Returns a clean error message (no line number/column information)
+        */
+       ANTLR_USE_NAMESPACE(std)string getMessage() const;
+
+public:
+       /// The token that was encountered
+       const RefToken token;
+       /// The offending AST node if tree walking
+       const RefAST node;
+       /// taken from node or token object
+       ANTLR_USE_NAMESPACE(std)string tokenText;
+
+       /// Types of tokens
+#ifndef NO_STATIC_CONSTS
+       static const int TOKEN = 1;
+       static const int NOT_TOKEN = 2;
+       static const int RANGE = 3;
+       static const int NOT_RANGE = 4;
+       static const int SET = 5;
+       static const int NOT_SET = 6;
+#else
+       enum {
+               TOKEN = 1,
+               NOT_TOKEN = 2,
+               RANGE = 3,
+               NOT_RANGE = 4,
+               SET = 5,
+               NOT_SET = 6
+       };
+#endif
+
+public:
+       /// One of the above
+       int mismatchType;
+
+       /// For TOKEN/NOT_TOKEN and RANGE/NOT_RANGE
+       int expecting;
+
+       /// For RANGE/NOT_RANGE (expecting is lower bound of range)
+       int upper;
+
+       /// For SET/NOT_SET
+       BitSet set;
+
+private:
+       /// Token names array for formatting
+       const char* const* tokenNames;
+       /// Max number of tokens in tokenNames
+       const int numTokens;
+       /// Return token name for tokenType
+       ANTLR_USE_NAMESPACE(std)string tokenName(int tokenType) const;
+};
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_MismatchedTokenException_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/NoViableAltException.hpp b/libsecurity_codesigning/antlr2/antlr/NoViableAltException.hpp
new file mode 100644 (file)
index 0000000..e3677de
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef INC_NoViableAltException_hpp__
+#define INC_NoViableAltException_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/NoViableAltException.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/RecognitionException.hpp>
+#include <antlr/Token.hpp>
+#include <antlr/AST.hpp>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+class ANTLR_API NoViableAltException : public RecognitionException {
+public:
+       const RefToken token;
+       const RefAST node; // handles parsing and treeparsing
+
+       NoViableAltException(RefAST t);
+       NoViableAltException(RefToken t,const ANTLR_USE_NAMESPACE(std)string& fileName_);
+
+       ~NoViableAltException() throw() {}
+
+       /**
+        * Returns a clean error message (no line number/column information)
+        */
+       ANTLR_USE_NAMESPACE(std)string getMessage() const;
+};
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_NoViableAltException_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/NoViableAltForCharException.hpp b/libsecurity_codesigning/antlr2/antlr/NoViableAltForCharException.hpp
new file mode 100644 (file)
index 0000000..d61c18b
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef INC_NoViableAltForCharException_hpp__
+# define INC_NoViableAltForCharException_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/NoViableAltForCharException.hpp#2 $
+ */
+
+# include <antlr/config.hpp>
+# include <antlr/RecognitionException.hpp>
+# include <antlr/CharScanner.hpp>
+
+# ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr
+{
+# endif
+
+class ANTLR_API NoViableAltForCharException : public RecognitionException
+{
+public:
+       NoViableAltForCharException(int c, CharScanner* scanner);
+       NoViableAltForCharException(int c, const ANTLR_USE_NAMESPACE(std)string& fileName_,
+                                                                                int line_, int column_);
+
+       virtual ~NoViableAltForCharException() throw()
+       {
+       }
+
+       /// Returns a clean error message (no line number/column information)
+       ANTLR_USE_NAMESPACE(std)string getMessage() const;
+protected:
+       int foundChar;
+};
+
+# ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+# endif
+
+#endif //INC_NoViableAltForCharException_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/Parser.hpp b/libsecurity_codesigning/antlr2/antlr/Parser.hpp
new file mode 100644 (file)
index 0000000..8213ccd
--- /dev/null
@@ -0,0 +1,318 @@
+#ifndef INC_Parser_hpp__
+#define INC_Parser_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/Parser.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+
+#include <stdio.h>
+#include <exception>
+
+#include <antlr/BitSet.hpp>
+#include <antlr/TokenBuffer.hpp>
+#include <antlr/RecognitionException.hpp>
+#include <antlr/MismatchedTokenException.hpp>
+#include <antlr/ASTFactory.hpp>
+#include <antlr/ParserSharedInputState.hpp>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+extern bool DEBUG_PARSER;
+
+/** A generic ANTLR parser (LL(k) for k>=1) containing a bunch of
+ * utility routines useful at any lookahead depth.  We distinguish between
+ * the LL(1) and LL(k) parsers because of efficiency.  This may not be
+ * necessary in the near future.
+ *
+ * Each parser object contains the state of the parse including a lookahead
+ * cache (the form of which is determined by the subclass), whether or
+ * not the parser is in guess mode, where tokens come from, etc...
+ *
+ * <p>
+ * During <b>guess</b> mode, the current lookahead token(s) and token type(s)
+ * cache must be saved because the token stream may not have been informed
+ * to save the token (via <tt>mark</tt>) before the <tt>try</tt> block.
+ * Guessing is started by:
+ * <ol>
+ * <li>saving the lookahead cache.
+ * <li>marking the current position in the TokenBuffer.
+ * <li>increasing the guessing level.
+ * </ol>
+ *
+ * After guessing, the parser state is restored by:
+ * <ol>
+ * <li>restoring the lookahead cache.
+ * <li>rewinding the TokenBuffer.
+ * <li>decreasing the guessing level.
+ * </ol>
+ *
+ * @see antlr.Token
+ * @see antlr.TokenBuffer
+ * @see antlr.TokenStream
+ * @see antlr.LL1Parser
+ * @see antlr.LLkParser
+ *
+ * @todo add constructors with ASTFactory.
+ */
+class ANTLR_API Parser {
+protected:
+       Parser(TokenBuffer& input)
+       : inputState(new ParserInputState(input)), astFactory(0), traceDepth(0)
+       {
+       }
+       Parser(TokenBuffer* input)
+       : inputState(new ParserInputState(input)), astFactory(0), traceDepth(0)
+       {
+       }
+       Parser(const ParserSharedInputState& state)
+       : inputState(state), astFactory(0), traceDepth(0)
+       {
+       }
+public:
+       virtual ~Parser()
+       {
+       }
+
+       /** Return the token type of the ith token of lookahead where i=1
+        * is the current token being examined by the parser (i.e., it
+        * has not been matched yet).
+        */
+       virtual int LA(unsigned int i)=0;
+
+       /// Return the i-th token of lookahead
+       virtual RefToken LT(unsigned int i)=0;
+
+       /** DEPRECATED! Specify the factory to be used during tree building. (Compulsory)
+        * Setting the factory is nowadays compulsory.
+        * @see setASTFactory
+        */
+       virtual void setASTNodeFactory( ASTFactory *factory )
+       {
+               astFactory = factory;
+       }
+       /** Specify the factory to be used during tree building. (Compulsory)
+        * Setting the factory is nowadays compulsory.
+        */
+       virtual void setASTFactory( ASTFactory *factory )
+       {
+               astFactory = factory;
+       }
+       /** Return a pointer to the ASTFactory used.
+        * So you might use it in subsequent treewalkers or to reload AST's
+        * from disk.
+        */
+       virtual ASTFactory* getASTFactory()
+       {
+               return astFactory;
+       }
+       /** Get the root AST node of the generated AST. When using a custom AST type
+        * or heterogenous AST's, you'll have to convert it to the right type
+        * yourself.
+        */
+       virtual RefAST getAST() = 0;
+
+       /// Return the filename of the input file.
+       virtual inline ANTLR_USE_NAMESPACE(std)string getFilename() const
+       {
+               return inputState->filename;
+       }
+       /// Set the filename of the input file (used for error reporting).
+       virtual void setFilename(const ANTLR_USE_NAMESPACE(std)string& f)
+       {
+               inputState->filename = f;
+       }
+
+       virtual void setInputState(ParserSharedInputState state)
+       {
+               inputState = state;
+       }
+       virtual inline ParserSharedInputState getInputState() const
+       {
+               return inputState;
+       }
+
+       /// Get another token object from the token stream
+       virtual void consume()=0;
+       /// Consume tokens until one matches the given token
+       virtual void consumeUntil(int tokenType)
+       {
+               while (LA(1) != Token::EOF_TYPE && LA(1) != tokenType)
+                       consume();
+       }
+
+       /// Consume tokens until one matches the given token set
+       virtual void consumeUntil(const BitSet& set)
+       {
+               while (LA(1) != Token::EOF_TYPE && !set.member(LA(1)))
+                       consume();
+       }
+
+       /** Make sure current lookahead symbol matches token type <tt>t</tt>.
+        * Throw an exception upon mismatch, which is catch by either the
+        * error handler or by the syntactic predicate.
+        */
+       virtual void match(int t)
+       {
+               if ( DEBUG_PARSER )
+               {
+                       traceIndent();
+                   //     printf("< lexer %s; c==%d\n", rname, LA(1));
+                       printf("enter match(%d) with LA(1)=%d\n", t, LA(1));
+               }
+               if ( LA(1) != t )
+               {
+                       if ( DEBUG_PARSER )
+                       {
+                               traceIndent();
+                               printf("token mismatch: %d!=%d\n", LA(1), t);
+                       }
+                       throw MismatchedTokenException(getTokenNames(), getNumTokens(), LT(1), t, false, getFilename());
+               }
+               else
+               {
+                       // mark token as consumed -- fetch next token deferred until LA/LT
+                       consume();
+               }
+       }
+
+       virtual void matchNot(int t)
+       {
+               if ( LA(1)==t )
+               {
+                       // Throws inverted-sense exception
+                       throw MismatchedTokenException(getTokenNames(), getNumTokens(), LT(1), t, true, getFilename());
+               }
+               else
+               {
+                       // mark token as consumed -- fetch next token deferred until LA/LT
+                       consume();
+               }
+       }
+
+       /** Make sure current lookahead symbol matches the given set
+        * Throw an exception upon mismatch, which is catch by either the
+        * error handler or by the syntactic predicate.
+        */
+       virtual void match(const BitSet& b)
+       {
+               if ( DEBUG_PARSER )
+               {
+                       traceIndent();
+                       printf("enter match(bitset) with LA(1)=%d\n", LA(1));
+               }
+               if ( !b.member(LA(1)) )
+               {
+                       if ( DEBUG_PARSER )
+                       {
+                               traceIndent();
+                               printf("token mismatch: %d not member of bitset\n", LA(1));
+                       }
+                       throw MismatchedTokenException(getTokenNames(), getNumTokens(), LT(1), b, false, getFilename());
+               }
+               else
+               {
+                       // mark token as consumed -- fetch next token deferred until LA/LT
+                       consume();
+               }
+       }
+
+       /** Mark a spot in the input and return the position.
+        * Forwarded to TokenBuffer.
+        */
+       virtual inline unsigned int mark()
+       {
+               return inputState->getInput().mark();
+       }
+       /// rewind to a previously marked position
+       virtual inline void rewind(unsigned int pos)
+       {
+               inputState->getInput().rewind(pos);
+       }
+       /** called by the generated parser to do error recovery, override to
+        * customize the behaviour.
+        */
+       virtual void recover(const RecognitionException& ex, const BitSet& tokenSet)
+       {
+               consume();
+               consumeUntil(tokenSet);
+       }
+
+       /// Parser error-reporting function can be overridden in subclass
+       virtual void reportError(const RecognitionException& ex);
+       /// Parser error-reporting function can be overridden in subclass
+       virtual void reportError(const ANTLR_USE_NAMESPACE(std)string& s);
+       /// Parser warning-reporting function can be overridden in subclass
+       virtual void reportWarning(const ANTLR_USE_NAMESPACE(std)string& s);
+
+       /// get the token name for the token number 'num'
+       virtual const char* getTokenName(int num) const = 0;
+       /// get a vector with all token names
+       virtual const char* const* getTokenNames() const = 0;
+       /** Get the number of tokens defined.
+        * This one should be overridden in subclasses.
+        */
+       virtual int getNumTokens(void) const = 0;
+
+       /** Set or change the input token buffer */
+//     void setTokenBuffer(TokenBuffer<Token>* t);
+
+       virtual void traceIndent();
+       virtual void traceIn(const char* rname);
+       virtual void traceOut(const char* rname);
+protected:
+//     void setTokenNames(const char** tokenNames_);
+
+       ParserSharedInputState inputState;
+
+//     /// AST return value for a rule is squirreled away here
+//     RefAST returnAST;
+
+       /// AST support code; parser and treeparser delegate to this object
+       ASTFactory *astFactory;
+
+       // used to keep track of the indentation for the trace
+       int traceDepth;
+
+       /** Utility class which allows tracing to work even when exceptions are
+        * thrown.
+        */
+       class Tracer { /*{{{*/
+       private:
+               Parser* parser;
+               const char* text;
+       public:
+               Tracer(Parser* p,const char * t)
+               : parser(p), text(t)
+               {
+                       parser->traceIn(text);
+               }
+               ~Tracer()
+               {
+#ifdef ANTLR_CXX_SUPPORTS_UNCAUGHT_EXCEPTION
+                       // Only give trace if there's no uncaught exception..
+                       if(!ANTLR_USE_NAMESPACE(std)uncaught_exception())
+#endif
+                               parser->traceOut(text);
+               }
+       private:
+               Tracer(const Tracer&);                                                  // undefined
+               const Tracer& operator=(const Tracer&); // undefined
+               /*}}}*/
+       };
+private:
+       Parser(const Parser&);                                                          // undefined
+       const Parser& operator=(const Parser&);         // undefined
+};
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_Parser_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/ParserSharedInputState.hpp b/libsecurity_codesigning/antlr2/antlr/ParserSharedInputState.hpp
new file mode 100644 (file)
index 0000000..d1f8d15
--- /dev/null
@@ -0,0 +1,92 @@
+#ifndef INC_ParserSharedInputState_hpp__
+#define INC_ParserSharedInputState_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/ParserSharedInputState.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/TokenBuffer.hpp>
+#include <antlr/RefCount.hpp>
+#include <string>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/** This object contains the data associated with an
+ * input stream of tokens.  Multiple parsers
+ * share a single ParserSharedInputState to parse
+ * the same stream of tokens.
+ */
+class ANTLR_API ParserInputState {
+public:
+       /** Construct a new ParserInputState
+        * @param in the TokenBuffer to read from. The object is deleted together
+        * with the ParserInputState object.
+        */
+       ParserInputState( TokenBuffer* in )
+       : guessing(0)
+       , filename()
+       , input(in)
+       , inputResponsible(true)
+       {
+       }
+       /** Construct a new ParserInputState
+        * @param in the TokenBuffer to read from.
+        */
+       ParserInputState( TokenBuffer& in )
+       : guessing(0)
+       , filename("")
+       , input(&in)
+       , inputResponsible(false)
+       {
+       }
+
+       virtual ~ParserInputState()
+       {
+               if (inputResponsible)
+                       delete input;
+       }
+
+       TokenBuffer& getInput( void )
+       {
+               return *input;
+       }
+
+       /// Reset the ParserInputState and the underlying TokenBuffer
+       void reset( void )
+       {
+               input->reset();
+               guessing = 0;
+       }
+
+public:
+       /** Are we guessing (guessing>0)? */
+       int guessing;
+       /** What file (if known) caused the problem?
+        * @todo wrap this one..
+        */
+       ANTLR_USE_NAMESPACE(std)string filename;
+private:
+       /** Where to get token objects */
+       TokenBuffer* input;
+       /// Do we need to free the TokenBuffer or is it owned by another..
+       bool inputResponsible;
+
+       // we don't want these:
+       ParserInputState(const ParserInputState&);
+       ParserInputState& operator=(const ParserInputState&);
+};
+
+/// A reference counted ParserInputState
+typedef RefCount<ParserInputState> ParserSharedInputState;
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_ParserSharedInputState_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/RecognitionException.hpp b/libsecurity_codesigning/antlr2/antlr/RecognitionException.hpp
new file mode 100644 (file)
index 0000000..c131831
--- /dev/null
@@ -0,0 +1,66 @@
+#ifndef INC_RecognitionException_hpp__
+# define INC_RecognitionException_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/RecognitionException.hpp#2 $
+ */
+
+# include <antlr/config.hpp>
+# include <antlr/ANTLRException.hpp>
+
+# ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr
+{
+# endif
+       class ANTLR_API RecognitionException : public ANTLRException
+       {
+       public:
+               RecognitionException();
+               RecognitionException(const ANTLR_USE_NAMESPACE(std)string& s);
+               RecognitionException(const ANTLR_USE_NAMESPACE(std)string& s,
+                                                                       const ANTLR_USE_NAMESPACE(std)string& fileName,
+                                                                       int line, int column );
+
+               virtual ~RecognitionException() throw()
+               {
+               }
+
+               /// Return file where mishap occurred.
+               virtual ANTLR_USE_NAMESPACE(std)string getFilename() const throw()
+               {
+                       return fileName;
+               }
+               /**
+                * @return the line number that this exception happened on.
+                */
+               virtual int getLine() const throw()
+               {
+                       return line;
+               }
+               /**
+                * @return the column number that this exception happened on.
+                */
+               virtual int getColumn() const throw()
+               {
+                       return column;
+               }
+
+               /// Return complete error message with line/column number info (if present)
+               virtual ANTLR_USE_NAMESPACE(std)string toString() const;
+
+               /// See what file/line/column info is present and return it as a string
+               virtual ANTLR_USE_NAMESPACE(std)string getFileLineColumnString() const;
+       protected:
+               ANTLR_USE_NAMESPACE(std)string fileName; // not used by treeparsers
+               int line;    // not used by treeparsers
+               int column;  // not used by treeparsers
+       };
+
+# ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+# endif
+
+#endif //INC_RecognitionException_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/RefCount.hpp b/libsecurity_codesigning/antlr2/antlr/RefCount.hpp
new file mode 100644 (file)
index 0000000..4a98d92
--- /dev/null
@@ -0,0 +1,80 @@
+#ifndef INC_RefCount_hpp__
+#define INC_RefCount_hpp__
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/RefCount.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+template<class T>
+class ANTLR_API RefCount {
+private:
+       struct Ref {
+               T* const ptr;
+               unsigned int count;
+
+               Ref(T* p) : ptr(p), count(1) {}
+               ~Ref() {delete ptr;}
+               Ref* increment() {++count;return this;}
+               bool decrement() {return (--count==0);}
+       private:
+               Ref(const Ref&);
+               Ref& operator=(const Ref&);
+       }* ref;
+
+public:
+       explicit RefCount(T* p = 0)
+       : ref(p ? new Ref(p) : 0)
+       {
+       }
+       RefCount(const RefCount<T>& other)
+       : ref(other.ref ? other.ref->increment() : 0)
+       {
+       }
+       ~RefCount()
+       {
+               if (ref && ref->decrement())
+                       delete ref;
+       }
+       RefCount<T>& operator=(const RefCount<T>& other)
+       {
+               Ref* tmp = other.ref ? other.ref->increment() : 0;
+               if (ref && ref->decrement())
+                       delete ref;
+               ref = tmp;
+               return *this;
+       }
+
+       operator T* () const
+       {
+               return ref ? ref->ptr : 0;
+       }
+
+       T* operator->() const
+       {
+               return ref ? ref->ptr : 0;
+       }
+
+       T* get() const
+       {
+               return ref ? ref->ptr : 0;
+       }
+
+       template<class newType> operator RefCount<newType>()
+       {
+               return RefCount<newType>(ref);
+       }
+};
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_RefCount_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/SemanticException.hpp b/libsecurity_codesigning/antlr2/antlr/SemanticException.hpp
new file mode 100644 (file)
index 0000000..c8e9ea3
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef INC_SemanticException_hpp__
+#define INC_SemanticException_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/SemanticException.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/RecognitionException.hpp>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+class ANTLR_API SemanticException : public RecognitionException {
+public:
+       SemanticException(const ANTLR_USE_NAMESPACE(std)string& s)
+       : RecognitionException(s)
+       {
+       }
+       SemanticException(const ANTLR_USE_NAMESPACE(std)string& s,
+                                                       const ANTLR_USE_NAMESPACE(std)string& fileName_,
+                                                       int line_,int column_)
+       : RecognitionException(s,fileName_,line_,column_)
+       {
+       }
+
+       ~SemanticException() throw()
+       {
+       }
+};
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_SemanticException_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/String.hpp b/libsecurity_codesigning/antlr2/antlr/String.hpp
new file mode 100644 (file)
index 0000000..b3da3c3
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef INC_String_hpp__
+#define INC_String_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/String.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <string>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+ANTLR_API ANTLR_USE_NAMESPACE(std)string operator+( const ANTLR_USE_NAMESPACE(std)string& lhs, const int rhs );
+ANTLR_API ANTLR_USE_NAMESPACE(std)string operator+( const ANTLR_USE_NAMESPACE(std)string& lhs, size_t rhs );
+
+ANTLR_API ANTLR_USE_NAMESPACE(std)string charName( int ch );
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_String_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/Token.hpp b/libsecurity_codesigning/antlr2/antlr/Token.hpp
new file mode 100644 (file)
index 0000000..3340642
--- /dev/null
@@ -0,0 +1,108 @@
+#ifndef INC_Token_hpp__
+#define INC_Token_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/Token.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/TokenRefCount.hpp>
+#include <string>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+struct TokenRef;
+
+/** A token is minimally a token type.  Subclasses can add the text matched
+ *  for the token and line info.
+ */
+class ANTLR_API Token
+{
+public:
+       // constants
+#ifndef NO_STATIC_CONSTS
+       static const int MIN_USER_TYPE = 4;
+       static const int NULL_TREE_LOOKAHEAD = 3;
+       static const int INVALID_TYPE = 0;
+       static const int EOF_TYPE = 1;
+       static const int SKIP = -1;
+#else
+       enum {
+               MIN_USER_TYPE = 4,
+               NULL_TREE_LOOKAHEAD = 3,
+               INVALID_TYPE = 0,
+               EOF_TYPE = 1,
+               SKIP = -1
+       };
+#endif
+
+       Token()
+       : ref(0)
+       , type(INVALID_TYPE)
+       {
+       }
+       Token(int t)
+       : ref(0)
+       , type(t)
+       {
+       }
+       Token(int t, const ANTLR_USE_NAMESPACE(std)string& txt)
+       : ref(0)
+       , type(t)
+       {
+               setText(txt);
+       }
+       virtual ~Token()
+       {
+       }
+
+       virtual int getColumn() const;
+       virtual int getLine() const;
+       virtual ANTLR_USE_NAMESPACE(std)string getText() const;
+       virtual const ANTLR_USE_NAMESPACE(std)string& getFilename() const;
+       virtual int getType() const;
+
+       virtual void setColumn(int c);
+
+       virtual void setLine(int l);
+       virtual void setText(const ANTLR_USE_NAMESPACE(std)string& t);
+       virtual void setType(int t);
+
+       virtual void setFilename( const std::string& file );
+
+       virtual ANTLR_USE_NAMESPACE(std)string toString() const;
+
+private:
+       friend struct TokenRef;
+       TokenRef* ref;
+
+       int type;                                                       ///< the type of the token
+
+       Token(RefToken other);
+       Token& operator=(const Token& other);
+       Token& operator=(RefToken other);
+
+       Token(const Token&);
+};
+
+extern ANTLR_API RefToken nullToken;
+
+#ifdef NEEDS_OPERATOR_LESS_THAN
+// RK: Added after 2.7.2 previously it was undefined.
+// AL: what to return if l and/or r point to nullToken???
+inline bool operator<( RefToken l, RefToken r )
+{
+       return nullToken == l ? ( nullToken == r ? false : true ) : l->getType() < r->getType();
+}
+#endif
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_Token_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/TokenBuffer.hpp b/libsecurity_codesigning/antlr2/antlr/TokenBuffer.hpp
new file mode 100644 (file)
index 0000000..948243f
--- /dev/null
@@ -0,0 +1,121 @@
+#ifndef INC_TokenBuffer_hpp__
+#define INC_TokenBuffer_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/TokenBuffer.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/TokenStream.hpp>
+#include <antlr/CircularQueue.hpp>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/**A Stream of Token objects fed to the parser from a TokenStream that can
+ * be rewound via mark()/rewind() methods.
+ * <p>
+ * A dynamic array is used to buffer up all the input tokens.  Normally,
+ * "k" tokens are stored in the buffer.  More tokens may be stored during
+ * guess mode (testing syntactic predicate), or when LT(i>k) is referenced.
+ * Consumption of tokens is deferred.  In other words, reading the next
+ * token is not done by conume(), but deferred until needed by LA or LT.
+ * <p>
+ *
+ * @todo: see if we can integrate this one with InputBuffer into one template
+ * or so.
+ *
+ * @see antlr.Token
+ * @see antlr.TokenStream
+ * @see antlr.TokenQueue
+ */
+class ANTLR_API TokenBuffer {
+public:
+       /** Create a token buffer */
+       TokenBuffer(TokenStream& input_);
+       virtual ~TokenBuffer();
+
+       /// Reset the input buffer to empty state
+       inline void reset( void )
+       {
+               nMarkers = 0;
+               markerOffset = 0;
+               numToConsume = 0;
+               queue.clear();
+       }
+
+       /** Get a lookahead token value */
+       int LA( unsigned int i );
+
+       /** Get a lookahead token */
+       RefToken LT( unsigned int i );
+
+       /** Return an integer marker that can be used to rewind the buffer to
+        * its current state.
+        */
+       unsigned int mark();
+
+       /**Rewind the token buffer to a marker.
+        * @param mark Marker returned previously from mark()
+        */
+       void rewind(unsigned int mark);
+
+       /** Mark another token for deferred consumption */
+       inline void consume()
+       {
+               numToConsume++;
+       }
+
+       /// Return the number of entries in the TokenBuffer
+       virtual unsigned int entries() const;
+
+private:
+       /** Ensure that the token buffer is sufficiently full */
+       void fill(unsigned int amount);
+       /** Sync up deferred consumption */
+       void syncConsume();
+
+protected:
+       /// Token source
+       TokenStream& input;
+
+       /// Number of active markers
+       unsigned int nMarkers;
+
+       /// Additional offset used when markers are active
+       unsigned int markerOffset;
+
+       /// Number of calls to consume() since last LA() or LT() call
+       unsigned int numToConsume;
+
+       /// Circular queue with Tokens
+       CircularQueue<RefToken> queue;
+
+private:
+       TokenBuffer(const TokenBuffer& other);
+       const TokenBuffer& operator=(const TokenBuffer& other);
+};
+
+/** Sync up deferred consumption */
+inline void TokenBuffer::syncConsume()
+{
+       if (numToConsume > 0)
+       {
+               if (nMarkers > 0)
+                       markerOffset += numToConsume;
+               else
+                       queue.removeItems( numToConsume );
+
+               numToConsume = 0;
+       }
+}
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_TokenBuffer_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/TokenRefCount.hpp b/libsecurity_codesigning/antlr2/antlr/TokenRefCount.hpp
new file mode 100644 (file)
index 0000000..9ccbb98
--- /dev/null
@@ -0,0 +1,98 @@
+#ifndef INC_TokenRefCount_hpp__
+# define INC_TokenRefCount_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id:$
+ */
+
+# include <antlr/config.hpp>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+class Token;
+
+struct ANTLR_API TokenRef
+{
+       Token* const ptr;
+       unsigned int count;
+
+       TokenRef(Token* p);
+       ~TokenRef();
+       TokenRef* increment()
+       {
+               ++count;
+               return this;
+       }
+       bool decrement()
+       {
+               return (--count==0);
+       }
+
+       static TokenRef* getRef(const Token* p);
+private:
+       TokenRef( const TokenRef& );
+       TokenRef& operator=( const TokenRef& );
+};
+
+template<class T>
+       class ANTLR_API TokenRefCount
+{
+private:
+       TokenRef* ref;
+
+public:
+       TokenRefCount(const Token* p=0)
+       : ref(p ? TokenRef::getRef(p) : 0)
+       {
+       }
+       TokenRefCount(const TokenRefCount<T>& other)
+       : ref(other.ref ? other.ref->increment() : 0)
+       {
+       }
+       ~TokenRefCount()
+       {
+               if (ref && ref->decrement())
+                       delete ref;
+       }
+       TokenRefCount<T>& operator=(Token* other)
+       {
+               TokenRef* tmp = TokenRef::getRef(other);
+
+               if (ref && ref->decrement())
+                       delete ref;
+
+               ref=tmp;
+
+               return *this;
+       }
+       TokenRefCount<T>& operator=(const TokenRefCount<T>& other)
+       {
+               if( other.ref != ref )
+               {
+                       TokenRef* tmp = other.ref ? other.ref->increment() : 0;
+
+                       if (ref && ref->decrement())
+                               delete ref;
+
+                       ref=tmp;
+               }
+               return *this;
+       }
+
+       operator T* ()  const { return ref ? static_cast<T*>(ref->ptr) : 0; }
+       T* operator->() const { return ref ? static_cast<T*>(ref->ptr) : 0; }
+       T* get()        const { return ref ? static_cast<T*>(ref->ptr) : 0; }
+};
+
+typedef TokenRefCount<Token> RefToken;
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_TokenRefCount_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/TokenStream.hpp b/libsecurity_codesigning/antlr2/antlr/TokenStream.hpp
new file mode 100644 (file)
index 0000000..3bec598
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef INC_TokenStream_hpp__
+#define INC_TokenStream_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/TokenStream.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/Token.hpp>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/** This interface allows any object to pretend it is a stream
+ * of tokens.
+ * @author Terence Parr, MageLang Institute
+ */
+class ANTLR_API TokenStream {
+public:
+       virtual RefToken nextToken()=0;
+       virtual ~TokenStream()
+       {
+       }
+};
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_TokenStream_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/TokenStreamBasicFilter.hpp b/libsecurity_codesigning/antlr2/antlr/TokenStreamBasicFilter.hpp
new file mode 100644 (file)
index 0000000..839f97e
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef INC_TokenStreamBasicFilter_hpp__
+#define INC_TokenStreamBasicFilter_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/TokenStreamBasicFilter.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/BitSet.hpp>
+#include <antlr/TokenStream.hpp>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/** This object is a TokenStream that passes through all
+ *  tokens except for those that you tell it to discard.
+ *  There is no buffering of the tokens.
+ */
+class ANTLR_API TokenStreamBasicFilter : public TokenStream {
+       /** The set of token types to discard */
+protected:
+       BitSet discardMask;
+
+       /** The input stream */
+protected:
+       TokenStream* input;
+
+public:
+       TokenStreamBasicFilter(TokenStream& input_);
+
+       void discard(int ttype);
+
+       void discard(const BitSet& mask);
+
+       RefToken nextToken();
+};
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_TokenStreamBasicFilter_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/TokenStreamException.hpp b/libsecurity_codesigning/antlr2/antlr/TokenStreamException.hpp
new file mode 100644 (file)
index 0000000..a3f4d54
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef INC_TokenStreamException_hpp__
+#define INC_TokenStreamException_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/TokenStreamException.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/ANTLRException.hpp>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/** Baseclass for exceptions thrown by classes implementing the TokenStream
+ * interface.
+ * @see TokenStream
+ */
+class ANTLR_API TokenStreamException : public ANTLRException {
+public:
+       TokenStreamException() 
+       : ANTLRException()      
+       {
+       }
+       TokenStreamException(const ANTLR_USE_NAMESPACE(std)string& s)
+       : ANTLRException(s)
+       {
+       }
+       virtual ~TokenStreamException() throw()
+       {
+       }
+};
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_TokenStreamException_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/TokenStreamHiddenTokenFilter.hpp b/libsecurity_codesigning/antlr2/antlr/TokenStreamHiddenTokenFilter.hpp
new file mode 100644 (file)
index 0000000..7ab5c82
--- /dev/null
@@ -0,0 +1,95 @@
+#ifndef INC_TokenStreamHiddenTokenFilter_hpp__
+#define INC_TokenStreamHiddenTokenFilter_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/TokenStreamHiddenTokenFilter.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/TokenStreamBasicFilter.hpp>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/**This object filters a token stream coming from a lexer
+ * or another TokenStream so that only certain token channels
+ * get transmitted to the parser.
+ *
+ * Any of the channels can be filtered off as "hidden" channels whose
+ * tokens can be accessed from the parser.
+ */
+class ANTLR_API TokenStreamHiddenTokenFilter : public TokenStreamBasicFilter {
+       // protected BitSet discardMask;
+protected:
+       BitSet hideMask;
+
+private:
+       RefToken nextMonitoredToken;
+
+protected:
+       /** track tail of hidden list emanating from previous
+        *  monitored token
+        */
+       RefToken lastHiddenToken;
+
+       RefToken firstHidden; // = null;
+
+public:
+       TokenStreamHiddenTokenFilter(TokenStream& input);
+
+protected:
+       void consume();
+
+private:
+       void consumeFirst();
+
+public:
+       BitSet getDiscardMask() const;
+
+       /** Return a ptr to the hidden token appearing immediately after
+        *  token t in the input stream.
+        */
+       RefToken getHiddenAfter(RefToken t);
+
+       /** Return a ptr to the hidden token appearing immediately before
+        *  token t in the input stream.
+        */
+       RefToken getHiddenBefore(RefToken t);
+
+       BitSet getHideMask() const;
+
+       /** Return the first hidden token if one appears
+        *  before any monitored token.
+        */
+       RefToken getInitialHiddenToken();
+
+       void hide(int m);
+
+       void hide(const BitSet& mask);
+
+protected:
+       RefToken LA(int i);
+
+public:
+/** Return the next monitored token.
+ *  Test the token following the monitored token.
+ *  If following is another monitored token, save it
+ *  for the next invocation of nextToken (like a single
+ *  lookahead token) and return it then.
+ *  If following is unmonitored, nondiscarded (hidden)
+ *  channel token, add it to the monitored token.
+ *
+ *  Note: EOF must be a monitored Token.
+ */
+       RefToken nextToken();
+};
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_TokenStreamHiddenTokenFilter_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/TokenStreamIOException.hpp b/libsecurity_codesigning/antlr2/antlr/TokenStreamIOException.hpp
new file mode 100644 (file)
index 0000000..29f508b
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef INC_TokenStreamIOException_hpp__
+#define INC_TokenStreamIOException_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/TokenStreamIOException.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/TokenStreamException.hpp>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+class TokenStreamIOException : public TokenStreamException {
+public:
+       TokenStreamIOException()
+       : TokenStreamException()        
+       {
+       }
+       TokenStreamIOException(const ANTLR_USE_NAMESPACE(std)exception& e)
+       : TokenStreamException(e.what())
+       , io(e)
+       {
+       }
+       ~TokenStreamIOException() throw()
+       {
+       }
+private:
+       ANTLR_USE_NAMESPACE(std)exception io;
+};
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_TokenStreamIOException_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/TokenStreamRecognitionException.hpp b/libsecurity_codesigning/antlr2/antlr/TokenStreamRecognitionException.hpp
new file mode 100644 (file)
index 0000000..3968578
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef INC_TokenStreamRecognitionException_hpp__
+#define INC_TokenStreamRecognitionException_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/TokenStreamRecognitionException.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/TokenStreamException.hpp>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/** Exception thrown from generated lexers when there's no default error
+ * handler specified.
+ * @see TokenStream
+ */
+class TokenStreamRecognitionException : public TokenStreamException {
+public:
+       TokenStreamRecognitionException(RecognitionException& re)
+       : TokenStreamException(re.getMessage())
+       , recog(re)
+       {
+       }
+       virtual ~TokenStreamRecognitionException() throw()
+       {
+       }
+       virtual ANTLR_USE_NAMESPACE(std)string toString() const
+       {
+               return recog.getFileLineColumnString()+getMessage();
+       }
+
+       virtual ANTLR_USE_NAMESPACE(std)string getFilename() const throw()
+       {
+               return recog.getFilename();
+       }
+       virtual int getLine() const throw()
+       {
+               return recog.getLine();
+       }
+       virtual int getColumn() const throw()
+       {
+               return recog.getColumn();
+       }
+private:
+       RecognitionException recog;
+};
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_TokenStreamRecognitionException_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/TokenStreamRetryException.hpp b/libsecurity_codesigning/antlr2/antlr/TokenStreamRetryException.hpp
new file mode 100644 (file)
index 0000000..7d17b3c
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef INC_TokenStreamRetryException_hpp__
+#define INC_TokenStreamRetryException_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/TokenStreamRetryException.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/TokenStreamException.hpp>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+class TokenStreamRetryException : public TokenStreamException {
+public:
+       TokenStreamRetryException() {}
+       ~TokenStreamRetryException() throw() {}
+};
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_TokenStreamRetryException_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/TokenStreamRewriteEngine.hpp b/libsecurity_codesigning/antlr2/antlr/TokenStreamRewriteEngine.hpp
new file mode 100644 (file)
index 0000000..7c26709
--- /dev/null
@@ -0,0 +1,439 @@
+#ifndef INC_TokenStreamRewriteEngine_hpp__
+#define INC_TokenStreamRewriteEngine_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ */
+
+#include <string>
+#include <list>
+#include <vector>
+#include <map>
+#include <utility>
+#include <ostream>
+#include <iterator>
+#include <cassert>
+#include <algorithm>
+
+#include <antlr/config.hpp>
+
+#include <antlr/TokenStream.hpp>
+#include <antlr/TokenWithIndex.hpp>
+#include <antlr/BitSet.hpp>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/** This token stream tracks the *entire* token stream coming from
+ *      a lexer, but does not pass on the whitespace (or whatever else
+ *      you want to discard) to the parser.
+ *
+ *      This class can then be asked for the ith token in the input stream.
+ *      Useful for dumping out the input stream exactly after doing some
+ *      augmentation or other manipulations.   Tokens are index from 0..n-1
+ *
+ *      You can insert stuff, replace, and delete chunks.       Note that the
+ *      operations are done lazily--only if you convert the buffer to a
+ *      String.         This is very efficient because you are not moving data around
+ *      all the time.   As the buffer of tokens is converted to strings, the
+ *      toString() method(s) check to see if there is an operation at the
+ *      current index.  If so, the operation is done and then normal String
+ *      rendering continues on the buffer.      This is like having multiple Turing
+ *      machine instruction streams (programs) operating on a single input tape. :)
+ *
+ *      Since the operations are done lazily at toString-time, operations do not
+ *      screw up the token index values.  That is, an insert operation at token
+ *      index i does not change the index values for tokens i+1..n-1.
+ *
+ *      Because operations never actually alter the buffer, you may always get
+ *      the original token stream back without undoing anything.  Since
+ *      the instructions are queued up, you can easily simulate transactions and
+ *      roll back any changes if there is an error just by removing instructions.
+ *      For example,
+ *
+ *                     TokenStreamRewriteEngine rewriteEngine =
+ *                             new TokenStreamRewriteEngine(lexer);
+ *               JavaRecognizer parser = new JavaRecognizer(rewriteEngine);
+ *               ...
+ *               rewriteEngine.insertAfter("pass1", t, "foobar");}
+ *                     rewriteEngine.insertAfter("pass2", u, "start");}
+ *                     System.out.println(rewriteEngine.toString("pass1"));
+ *                     System.out.println(rewriteEngine.toString("pass2"));
+ *
+ *      You can also have multiple "instruction streams" and get multiple
+ *      rewrites from a single pass over the input.     Just name the instruction
+ *      streams and use that name again when printing the buffer.      This could be
+ *      useful for generating a C file and also its header file--all from the
+ *      same buffer.
+ *
+ *      If you don't use named rewrite streams, a "default" stream is used.
+ *
+ *      Terence Parr, parrt@cs.usfca.edu
+ *      University of San Francisco
+ *      February 2004
+ */
+class TokenStreamRewriteEngine : public TokenStream
+{
+public:
+       typedef ANTLR_USE_NAMESPACE(std)vector<antlr::RefTokenWithIndex> token_list;
+       static const char* DEFAULT_PROGRAM_NAME;
+#ifndef NO_STATIC_CONSTS
+       static const size_t MIN_TOKEN_INDEX;
+       static const int PROGRAM_INIT_SIZE;
+#else
+       enum {
+               MIN_TOKEN_INDEX = 0,
+               PROGRAM_INIT_SIZE = 100
+       };
+#endif
+
+       struct tokenToStream {
+               tokenToStream( ANTLR_USE_NAMESPACE(std)ostream& o ) : out(o) {}
+               template <typename T> void operator() ( const T& t ) {
+                       out << t->getText();
+               }
+               ANTLR_USE_NAMESPACE(std)ostream& out;
+       };
+
+       class RewriteOperation {
+       protected:
+               RewriteOperation( size_t idx, const ANTLR_USE_NAMESPACE(std)string& txt )
+               : index(idx), text(txt)
+               {
+               }
+       public:
+               virtual ~RewriteOperation()
+               {
+               }
+               /** Execute the rewrite operation by possibly adding to the buffer.
+                *       Return the index of the next token to operate on.
+                */
+               virtual size_t execute( ANTLR_USE_NAMESPACE(std)ostream& /* out */ ) {
+                       return index;
+               }
+               virtual size_t getIndex() const {
+                       return index;
+               }
+               virtual const char* type() const {
+                       return "RewriteOperation";
+               }
+       protected:
+               size_t index;
+               ANTLR_USE_NAMESPACE(std)string text;
+       };
+
+       struct executeOperation {
+               ANTLR_USE_NAMESPACE(std)ostream& out;
+               executeOperation( ANTLR_USE_NAMESPACE(std)ostream& s ) : out(s) {}
+               void operator () ( RewriteOperation* t ) {
+                       t->execute(out);
+               }
+       };
+
+       /// list of rewrite operations
+       typedef ANTLR_USE_NAMESPACE(std)list<RewriteOperation*> operation_list;
+       /// map program name to <program counter,program> tuple
+       typedef ANTLR_USE_NAMESPACE(std)map<ANTLR_USE_NAMESPACE(std)string,operation_list> program_map;
+
+       class InsertBeforeOp : public RewriteOperation
+       {
+       public:
+               InsertBeforeOp( size_t index, const ANTLR_USE_NAMESPACE(std)string& text )
+               : RewriteOperation(index, text)
+               {
+               }
+               virtual ~InsertBeforeOp() {}
+               virtual size_t execute( ANTLR_USE_NAMESPACE(std)ostream& out )
+               {
+                       out << text;
+                       return index;
+               }
+               virtual const char* type() const {
+                       return "InsertBeforeOp";
+               }
+       };
+
+       class ReplaceOp : public RewriteOperation
+       {
+       public:
+               ReplaceOp(size_t from, size_t to, ANTLR_USE_NAMESPACE(std)string text)
+               : RewriteOperation(from,text)
+               , lastIndex(to)
+               {
+               }
+               virtual ~ReplaceOp() {}
+               virtual size_t execute( ANTLR_USE_NAMESPACE(std)ostream& out ) {
+                       out << text;
+                       return lastIndex+1;
+               }
+               virtual const char* type() const {
+                       return "ReplaceOp";
+               }
+       protected:
+               size_t lastIndex;
+       };
+
+       class DeleteOp : public ReplaceOp {
+       public:
+               DeleteOp(size_t from, size_t to)
+               : ReplaceOp(from,to,"")
+               {
+               }
+               virtual const char* type() const {
+                       return "DeleteOp";
+               }
+       };
+
+       TokenStreamRewriteEngine(TokenStream& upstream);
+
+       TokenStreamRewriteEngine(TokenStream& upstream, size_t initialSize);
+
+       RefToken nextToken( void );
+
+       void rollback(size_t instructionIndex) {
+               rollback(DEFAULT_PROGRAM_NAME, instructionIndex);
+       }
+
+       /** Rollback the instruction stream for a program so that
+        *       the indicated instruction (via instructionIndex) is no
+        *       longer in the stream.  UNTESTED!
+        */
+       void rollback(const ANTLR_USE_NAMESPACE(std)string& programName,
+                                         size_t instructionIndex );
+
+       void deleteProgram() {
+               deleteProgram(DEFAULT_PROGRAM_NAME);
+       }
+
+       /** Reset the program so that no instructions exist */
+       void deleteProgram(const ANTLR_USE_NAMESPACE(std)string& programName) {
+               rollback(programName, MIN_TOKEN_INDEX);
+       }
+
+       void insertAfter( RefTokenWithIndex t,
+                                                       const ANTLR_USE_NAMESPACE(std)string& text )
+       {
+               insertAfter(DEFAULT_PROGRAM_NAME, t, text);
+       }
+
+       void insertAfter(size_t index, const ANTLR_USE_NAMESPACE(std)string& text) {
+               insertAfter(DEFAULT_PROGRAM_NAME, index, text);
+       }
+
+       void insertAfter( const ANTLR_USE_NAMESPACE(std)string& programName,
+                                                       RefTokenWithIndex t,
+                                                       const ANTLR_USE_NAMESPACE(std)string& text )
+       {
+               insertAfter(programName, t->getIndex(), text);
+       }
+
+       void insertAfter( const ANTLR_USE_NAMESPACE(std)string& programName,
+                                                       size_t index,
+                                                       const ANTLR_USE_NAMESPACE(std)string& text )
+       {
+               // to insert after, just insert before next index (even if past end)
+               insertBefore(programName,index+1, text);
+       }
+
+       void insertBefore( RefTokenWithIndex t,
+                                                        const ANTLR_USE_NAMESPACE(std)string& text )
+       {
+               // std::cout << "insertBefore index " << t->getIndex() << " " << text << std::endl;
+               insertBefore(DEFAULT_PROGRAM_NAME, t, text);
+       }
+
+       void insertBefore(size_t index, const ANTLR_USE_NAMESPACE(std)string& text) {
+               insertBefore(DEFAULT_PROGRAM_NAME, index, text);
+       }
+
+       void insertBefore( const ANTLR_USE_NAMESPACE(std)string& programName,
+                                                        RefTokenWithIndex t,
+                                                        const ANTLR_USE_NAMESPACE(std)string& text )
+       {
+               insertBefore(programName, t->getIndex(), text);
+       }
+
+       void insertBefore( const ANTLR_USE_NAMESPACE(std)string& programName,
+                                                        size_t index,
+                                                        const ANTLR_USE_NAMESPACE(std)string& text )
+       {
+               addToSortedRewriteList(programName, new InsertBeforeOp(index,text));
+       }
+
+       void replace(size_t index, const ANTLR_USE_NAMESPACE(std)string& text)
+       {
+               replace(DEFAULT_PROGRAM_NAME, index, index, text);
+       }
+
+       void replace( size_t from, size_t to,
+                                         const ANTLR_USE_NAMESPACE(std)string& text)
+       {
+               replace(DEFAULT_PROGRAM_NAME, from, to, text);
+       }
+
+       void replace( RefTokenWithIndex indexT,
+                                         const ANTLR_USE_NAMESPACE(std)string& text )
+       {
+               replace(DEFAULT_PROGRAM_NAME, indexT->getIndex(), indexT->getIndex(), text);
+       }
+
+       void replace( RefTokenWithIndex from,
+                                         RefTokenWithIndex to,
+                                         const ANTLR_USE_NAMESPACE(std)string& text )
+       {
+               replace(DEFAULT_PROGRAM_NAME, from, to, text);
+       }
+
+       void replace(const ANTLR_USE_NAMESPACE(std)string& programName,
+                                        size_t from, size_t to,
+                                        const ANTLR_USE_NAMESPACE(std)string& text )
+       {
+               addToSortedRewriteList(programName,new ReplaceOp(from, to, text));
+       }
+
+       void replace( const ANTLR_USE_NAMESPACE(std)string& programName,
+                                         RefTokenWithIndex from,
+                                         RefTokenWithIndex to,
+                                         const ANTLR_USE_NAMESPACE(std)string& text )
+       {
+               replace(programName,
+                                 from->getIndex(),
+                                 to->getIndex(),
+                                 text);
+       }
+
+       void remove(size_t index) {
+               remove(DEFAULT_PROGRAM_NAME, index, index);
+       }
+
+       void remove(size_t from, size_t to) {
+               remove(DEFAULT_PROGRAM_NAME, from, to);
+       }
+
+       void remove(RefTokenWithIndex indexT) {
+               remove(DEFAULT_PROGRAM_NAME, indexT, indexT);
+       }
+
+       void remove(RefTokenWithIndex from, RefTokenWithIndex to) {
+               remove(DEFAULT_PROGRAM_NAME, from, to);
+       }
+
+       void remove( const ANTLR_USE_NAMESPACE(std)string& programName,
+                                        size_t from, size_t to)
+       {
+               replace(programName,from,to,"");
+       }
+
+       void remove( const ANTLR_USE_NAMESPACE(std)string& programName,
+                                        RefTokenWithIndex from, RefTokenWithIndex to )
+       {
+               replace(programName,from,to,"");
+       }
+
+       void discard(int ttype) {
+               discardMask.add(ttype);
+       }
+
+       RefToken getToken( size_t i )
+       {
+               return RefToken(tokens.at(i));
+       }
+
+       size_t getTokenStreamSize() const {
+               return tokens.size();
+       }
+
+       void originalToStream( ANTLR_USE_NAMESPACE(std)ostream& out ) const {
+               ANTLR_USE_NAMESPACE(std)for_each( tokens.begin(), tokens.end(), tokenToStream(out) );
+       }
+
+       void originalToStream( ANTLR_USE_NAMESPACE(std)ostream& out,
+                                                                 size_t start, size_t end ) const;
+
+       void toStream( ANTLR_USE_NAMESPACE(std)ostream& out ) const {
+               toStream( out, MIN_TOKEN_INDEX, getTokenStreamSize());
+       }
+
+       void toStream( ANTLR_USE_NAMESPACE(std)ostream& out,
+                                               const ANTLR_USE_NAMESPACE(std)string& programName ) const
+       {
+               toStream( out, programName, MIN_TOKEN_INDEX, getTokenStreamSize());
+       }
+
+       void toStream( ANTLR_USE_NAMESPACE(std)ostream& out,
+                                               size_t start, size_t end ) const
+       {
+               toStream(out, DEFAULT_PROGRAM_NAME, start, end);
+       }
+
+       void toStream( ANTLR_USE_NAMESPACE(std)ostream& out,
+                                               const ANTLR_USE_NAMESPACE(std)string& programName,
+                                               size_t firstToken, size_t lastToken ) const;
+
+       void toDebugStream( ANTLR_USE_NAMESPACE(std)ostream& out ) const {
+               toDebugStream( out, MIN_TOKEN_INDEX, getTokenStreamSize());
+       }
+
+       void toDebugStream( ANTLR_USE_NAMESPACE(std)ostream& out,
+                                                         size_t start, size_t end ) const;
+
+       size_t getLastRewriteTokenIndex() const {
+               return getLastRewriteTokenIndex(DEFAULT_PROGRAM_NAME);
+       }
+
+       /** Return the last index for the program named programName
+        * return 0 if the program does not exist or the program is empty.
+        * (Note this is different from the java implementation that returns -1)
+        */
+       size_t getLastRewriteTokenIndex(const ANTLR_USE_NAMESPACE(std)string& programName) const {
+               program_map::const_iterator rewrites = programs.find(programName);
+
+               if( rewrites == programs.end() )
+                       return 0;
+
+               const operation_list& prog = rewrites->second;
+               if( !prog.empty() )
+               {
+                       operation_list::const_iterator last = prog.end();
+                       --last;
+                       return (*last)->getIndex();
+               }
+               return 0;
+       }
+
+protected:
+       /** If op.index > lastRewriteTokenIndexes, just add to the end.
+        *       Otherwise, do linear */
+       void addToSortedRewriteList(RewriteOperation* op) {
+               addToSortedRewriteList(DEFAULT_PROGRAM_NAME, op);
+       }
+
+       void addToSortedRewriteList( const ANTLR_USE_NAMESPACE(std)string& programName,
+                                                                                 RewriteOperation* op );
+
+protected:
+       /** Who do we suck tokens from? */
+       TokenStream& stream;
+       /** track index of tokens */
+       size_t index;
+
+       /** Track the incoming list of tokens */
+       token_list tokens;
+
+       /** You may have multiple, named streams of rewrite operations.
+        *  I'm calling these things "programs."
+        *  Maps String (name) -> rewrite (List)
+        */
+       program_map programs;
+
+       /** Which (whitespace) token(s) to throw out */
+       BitSet discardMask;
+};
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/libsecurity_codesigning/antlr2/antlr/TokenStreamSelector.hpp b/libsecurity_codesigning/antlr2/antlr/TokenStreamSelector.hpp
new file mode 100644 (file)
index 0000000..4d4dd57
--- /dev/null
@@ -0,0 +1,87 @@
+#ifndef INC_TokenStreamSelector_hpp__
+#define INC_TokenStreamSelector_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/TokenStreamSelector.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/TokenStream.hpp>
+#include <map>
+#include <stack>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/** A token stream MUX (multiplexor) knows about n token streams
+ *  and can multiplex them onto the same channel for use by token
+ *  stream consumer like a parser.  This is a way to have multiple
+ *  lexers break up the same input stream for a single parser.
+ * Or, you can have multiple instances of the same lexer handle
+ *  multiple input streams; this works great for includes.
+ */
+class ANTLR_API TokenStreamSelector : public TokenStream {
+protected:
+       /** The set of inputs to the MUX */
+#ifdef OS_NO_ALLOCATOR
+       typedef ANTLR_USE_NAMESPACE(std)less<ANTLR_USE_NAMESPACE(std)string> lessp;
+       typedef ANTLR_USE_NAMESPACE(std)map<ANTLR_USE_NAMESPACE(std)string,TokenStream*,lessp> inputStreamNames_coll;
+#else
+       typedef ANTLR_USE_NAMESPACE(std)map<ANTLR_USE_NAMESPACE(std)string,TokenStream*> inputStreamNames_coll;
+#endif
+       inputStreamNames_coll inputStreamNames;
+
+       /** The currently-selected token stream input */
+       TokenStream* input;
+
+       /** Used to track stack of input streams */
+#ifdef OS_NO_ALLOCATOR
+       typedef ANTLR_USE_NAMESPACE(std)stack<TokenStream*, ANTLR_USE_NAMESPACE(std)deque<TokenStream*> > streamStack_coll;
+#else
+       typedef ANTLR_USE_NAMESPACE(std)stack<TokenStream*> streamStack_coll;
+#endif
+       streamStack_coll streamStack;
+
+public:
+       TokenStreamSelector();
+       ~TokenStreamSelector();
+
+       void addInputStream(TokenStream* stream, const ANTLR_USE_NAMESPACE(std)string& key);
+
+       /// Return the stream from which tokens are being pulled at the moment.
+       TokenStream* getCurrentStream() const;
+
+       TokenStream* getStream(const ANTLR_USE_NAMESPACE(std)string& sname) const;
+
+       RefToken nextToken();
+
+       TokenStream* pop();
+
+       void push(TokenStream* stream);
+
+       void push(const ANTLR_USE_NAMESPACE(std)string& sname);
+
+       /** Abort recognition of current Token and try again.
+        *  A stream can push a new stream (for include files
+        *  for example, and then retry(), which will cause
+        *  the current stream to abort back to this.nextToken().
+        *  this.nextToken() then asks for a token from the
+        *  current stream, which is the new "substream."
+        */
+       void retry();
+
+       /** Set the stream without pushing old stream */
+       void select(TokenStream* stream);
+
+       void select(const ANTLR_USE_NAMESPACE(std)string& sname);
+};
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_TokenStreamSelector_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/TokenWithIndex.hpp b/libsecurity_codesigning/antlr2/antlr/TokenWithIndex.hpp
new file mode 100644 (file)
index 0000000..e4a3e37
--- /dev/null
@@ -0,0 +1,84 @@
+#ifndef INC_TokenWithIndex_hpp__
+#define INC_TokenWithIndex_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id:$
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/CommonToken.hpp>
+#include <antlr/String.hpp>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+class ANTLR_API TokenWithIndex : public ANTLR_USE_NAMESPACE(antlr)CommonToken {
+public:
+       // static size_t count;
+       TokenWithIndex() : CommonToken(), index(0)
+       {
+               // std::cout << __PRETTY_FUNCTION__ << std::endl;
+               // count++;
+       }
+       TokenWithIndex(int t, const ANTLR_USE_NAMESPACE(std)string& txt)
+       : CommonToken(t,txt)
+       , index(0)
+       {
+               // std::cout << __PRETTY_FUNCTION__ << std::endl;
+               // count++;
+       }
+       TokenWithIndex(const ANTLR_USE_NAMESPACE(std)string& s)
+       : CommonToken(s)
+       , index(0)
+       {
+               // std::cout << __PRETTY_FUNCTION__ << std::endl;
+               // count++;
+       }
+       ~TokenWithIndex()
+       {
+               // count--;
+       }
+       void setIndex( size_t idx )
+       {
+               index = idx;
+       }
+       size_t getIndex( void ) const
+       {
+               return index;
+       }
+
+       ANTLR_USE_NAMESPACE(std)string toString() const
+       {
+               return ANTLR_USE_NAMESPACE(std)string("[")+
+                       index+
+                       ":\""+
+                       getText()+"\",<"+
+                       getType()+">,line="+
+                       getLine()+",column="+
+                       getColumn()+"]";
+       }
+
+       static RefToken factory()
+       {
+               return RefToken(new TokenWithIndex());
+       }
+
+protected:
+       size_t index;
+
+private:
+       TokenWithIndex(const TokenWithIndex&);
+       const TokenWithIndex& operator=(const TokenWithIndex&);
+};
+
+typedef TokenRefCount<TokenWithIndex> RefTokenWithIndex;
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_CommonToken_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/TreeParser.hpp b/libsecurity_codesigning/antlr2/antlr/TreeParser.hpp
new file mode 100644 (file)
index 0000000..b7dc548
--- /dev/null
@@ -0,0 +1,155 @@
+#ifndef INC_TreeParser_hpp__
+#define INC_TreeParser_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/TreeParser.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/AST.hpp>
+#include <antlr/ASTFactory.hpp>
+#include <antlr/BitSet.hpp>
+#include <antlr/RecognitionException.hpp>
+#include <antlr/MismatchedTokenException.hpp>
+#include <antlr/TreeParserSharedInputState.hpp>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+class ANTLR_API TreeParser {
+public:
+       TreeParser()
+       : astFactory(0)
+       , inputState(new TreeParserInputState())
+       , traceDepth(0)
+       {
+       }
+
+       TreeParser(const TreeParserSharedInputState& state)
+       : astFactory(0)
+       , inputState(state)
+       , traceDepth(0)
+       {
+       }
+
+       virtual ~TreeParser()
+       {
+       }
+
+       /// Get the AST return value squirreled away in the parser
+       virtual RefAST getAST() = 0;
+
+       /** Make sure current lookahead symbol matches the given set
+        * Throw an exception upon mismatch, which is caught by either the
+        * error handler or by a syntactic predicate.
+        */
+       virtual void match(RefAST t, const BitSet& b)
+       {
+               if ( !t || t==ASTNULL || !b.member(t->getType()) )
+                       throw MismatchedTokenException( getTokenNames(), getNumTokens(),
+                                                                                                         t, b, false );
+       }
+
+       /** Specify the AST factory to be used during tree building. (Compulsory)
+        * Setting the factory is compulsory (if you intend to modify
+        * the tree in the treeparser). The AST Factory is shared between
+        * parser (who builds the initial AST) and treeparser.
+        * @see Parser::getASTFactory()
+        */
+       virtual void setASTFactory(ASTFactory* factory)
+       {
+               astFactory = factory;
+       }
+       /// Return pointer to ASTFactory
+       virtual ASTFactory* getASTFactory() const
+       {
+               return astFactory;
+       }
+       /// Get the name for token 'num'
+       virtual const char* getTokenName(int num) const = 0;
+       /// Return the number of tokens defined
+       virtual int getNumTokens() const = 0;
+       /// Return an array of getNumTokens() token names
+       virtual const char* const* getTokenNames() const = 0;
+
+       /// Parser error-reporting function can be overridden in subclass
+       virtual void reportError(const RecognitionException& ex);
+       /// Parser error-reporting function can be overridden in subclass
+       virtual void reportError(const ANTLR_USE_NAMESPACE(std)string& s);
+       /// Parser warning-reporting function can be overridden in subclass
+       virtual void reportWarning(const ANTLR_USE_NAMESPACE(std)string& s);
+
+       /// These are used during when traceTreeParser commandline option is passed.
+       virtual void traceIndent();
+       virtual void traceIn(const char* rname, RefAST t);
+       virtual void traceOut(const char* rname, RefAST t);
+
+       /** The AST Null object; the parsing cursor is set to this when
+        * it is found to be null.  This way, we can test the
+        * token type of a node without having to have tests for 0
+        * everywhere.
+        */
+       static RefAST ASTNULL;
+
+protected:
+       virtual void match(RefAST t, int ttype)
+       {
+               if (!t || t == ASTNULL || t->getType() != ttype )
+                       throw MismatchedTokenException( getTokenNames(), getNumTokens(),
+                                                                                                         t, ttype, false );
+       }
+
+       virtual void matchNot(RefAST t, int ttype)
+       {
+               if ( !t || t == ASTNULL || t->getType() == ttype )
+                       throw MismatchedTokenException( getTokenNames(), getNumTokens(),
+                                                                                                         t, ttype, true );
+       }
+
+       /** AST support code; parser and treeparser delegate to this object */
+       ASTFactory* astFactory;
+
+       /// The input state of this tree parser.
+       TreeParserSharedInputState inputState;
+
+       /** Used to keep track of indent depth with -traceTreeParser */
+       int traceDepth;
+
+       /** Utility class which allows tracing to work even when exceptions are
+        * thrown.
+        */
+       class Tracer {
+       private:
+               TreeParser* parser;
+               const char* text;
+               RefAST tree;
+       public:
+               Tracer(TreeParser* p, const char* t, RefAST a)
+               : parser(p), text(t), tree(a)
+               {
+                       parser->traceIn(text,tree);
+               }
+               ~Tracer()
+               {
+                       parser->traceOut(text,tree);
+               }
+       private:
+               Tracer(const Tracer&);                                                  // undefined
+               const Tracer& operator=(const Tracer&); // undefined
+       };
+
+private:
+       // no copying of treeparser instantiations...
+       TreeParser(const TreeParser& other);
+       TreeParser& operator=(const TreeParser& other);
+};
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_TreeParser_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/TreeParserSharedInputState.hpp b/libsecurity_codesigning/antlr2/antlr/TreeParserSharedInputState.hpp
new file mode 100644 (file)
index 0000000..5e7c4c2
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef INC_TreeParserSharedInputState_hpp__
+#define INC_TreeParserSharedInputState_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/TreeParserSharedInputState.hpp#2 $
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/RefCount.hpp>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/** This object contains the data associated with an
+ *  input AST.  Multiple parsers
+ *  share a single TreeParserSharedInputState to parse
+ *  the same tree or to have the parser walk multiple
+ *  trees.
+ */
+class ANTLR_API TreeParserInputState {
+public:
+       TreeParserInputState() : guessing(0) {}
+       virtual ~TreeParserInputState() {}
+
+public:
+       /** Are we guessing (guessing>0)? */
+       int guessing; //= 0;
+
+private:
+       // we don't want these:
+       TreeParserInputState(const TreeParserInputState&);
+       TreeParserInputState& operator=(const TreeParserInputState&);
+};
+
+typedef RefCount<TreeParserInputState> TreeParserSharedInputState;
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+#endif //INC_TreeParserSharedInputState_hpp__
diff --git a/libsecurity_codesigning/antlr2/antlr/config.hpp b/libsecurity_codesigning/antlr2/antlr/config.hpp
new file mode 100644 (file)
index 0000000..e336950
--- /dev/null
@@ -0,0 +1,290 @@
+#ifndef INC_config_hpp__
+#define INC_config_hpp__
+
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/antlr/config.hpp#2 $
+ */
+
+/*
+ * Just a simple configuration file to differentiate between the
+ * various compilers used and reconfigure stuff for any oddities of the
+ * compiler in question.
+ *
+ * These are the defaults. Per compiler these are amended.
+ */
+#define ANTLR_USE_NAMESPACE(_x_) _x_::
+#define ANTLR_USING_NAMESPACE(_x_) using namespace _x_;
+#define ANTLR_CXX_SUPPORTS_NAMESPACE 1
+#define ANTLR_C_USING(_x_)
+#define ANTLR_API
+#ifndef CUSTOM_API
+# define CUSTOM_API
+#endif
+#define ANTLR_IOS_BASE ios_base
+/** define if cctype functions/macros need a std:: prefix. A lot of compilers
+ * define these as macros, in which case something barfs.
+ */
+#define ANTLR_CCTYPE_NEEDS_STD
+
+/// Define if C++ compiler supports std::uncaught_exception
+#define ANTLR_CXX_SUPPORTS_UNCAUGHT_EXCEPTION
+
+#define ANTLR_ATOI_IN_STD
+
+/******************************************************************************/
+/*{{{ Microsoft Visual C++ */
+// NOTE: If you provide patches for a specific MSVC version guard them for
+// the specific version!!!!
+// _MSC_VER == 1100 for Microsoft Visual C++ 5.0
+// _MSC_VER == 1200 for Microsoft Visual C++ 6.0
+// _MSC_VER == 1300 for Microsoft Visual C++ 7.0
+#if defined(_MSC_VER)
+
+# if _MSC_VER < 1300
+#      define NOMINMAX
+#      pragma warning(disable : 4786)
+#      define min _cpp_min
+# endif
+
+// This warning really gets on my nerves.
+// It's the one about symbol longer than 256 chars, and it happens
+// all the time with STL.
+# pragma warning( disable : 4786 4231 )
+// this shuts up some DLL interface warnings for STL
+# pragma warning( disable : 4251 )
+
+# ifdef ANTLR_CXX_USE_STLPORT
+#      undef ANTLR_CXX_SUPPORTS_UNCAUGHT_EXCEPTION
+# endif
+
+# if ( _MSC_VER < 1300 ) && ( defined(ANTLR_EXPORTS) || defined(ANTLR_IMPORTS) )
+#      error "DLL Build not supported on these MSVC versions."
+// see comment in lib/cpp/src/dll.cpp
+# endif
+
+// For the DLL support originally contributed by Stephen Naughton
+// If you are building statically leave ANTLR_EXPORTS/ANTLR_IMPORTS undefined
+// If you are building the DLL define ANTLR_EXPORTS
+// If you are compiling code to be used with the DLL define ANTLR_IMPORTS
+# ifdef ANTLR_EXPORTS
+#      undef ANTLR_API
+#      define ANTLR_API __declspec(dllexport)
+# endif
+
+# ifdef ANTLR_IMPORTS
+#      undef ANTLR_API
+#      define ANTLR_API __declspec(dllimport)
+# endif
+
+# if ( _MSC_VER < 1200 )
+// supposedly only for MSVC5 and before...
+// Using vector<XXX> requires operator<(X,X) to be defined
+#      define NEEDS_OPERATOR_LESS_THAN
+# endif
+
+// VC6
+# if ( _MSC_VER == 1200 )
+#      undef ANTLR_ATOI_IN_STD
+# endif
+
+# if ( _MSC_VER < 1310 )
+// Supposedly only for MSVC7 and before...
+// Not allowed to put 'static const int XXX=20;' in a class definition
+#      define NO_STATIC_CONSTS
+#      define NO_TEMPLATE_PARTS
+# endif
+
+// No strcasecmp in the C library (so use stricmp instead)
+// - Anyone know which is in which standard?
+# define NO_STRCASECMP
+# undef ANTLR_CCTYPE_NEEDS_STD
+#      define NO_STATIC_CONSTS
+#endif // End of Microsoft Visual C++
+
+/*}}}*/
+/******************************************************************************/
+/*{{{ SunPro Compiler (Using OBJECTSPACE STL)
+ *****************************************************************************/
+#ifdef __SUNPRO_CC
+
+# if (__SUNPRO_CC >= 0x500)
+
+#      define NEEDS_OPERATOR_LESS_THAN
+#      define NO_TEMPLATE_PARTS
+
+# else
+
+#      undef namespace
+#      define namespace
+
+#      if (__SUNPRO_CC == 0x420)
+
+/* This code is specif to SunWspro Compiler 4.2, and will compile with
+ the objectspace 2.1 toolkit for Solaris2.6 */
+#       define HAS_NOT_CASSERT_H
+#       define HAS_NOT_CSTRING_H
+#       define HAS_NOT_CCTYPE_H
+#       define HAS_NOT_CSTDIO_H
+#       define HAS_OSTREAM_H
+
+/* #define OS_SOLARIS_2_6
+ #define OS_NO_WSTRING
+ #define OS_NO_ALLOCATORS
+ #define OS_MULTI_THREADED
+ #define OS_SOLARIS_NATIVE
+ #define OS_REALTIME
+ #define __OSVERSION__=5
+ #define SVR4
+ */
+
+// ObjectSpace + some specific templates constructions with stl.
+/* #define OS_NO_ALLOCATOR */
+
+// This great compiler does not have the namespace feature.
+#       undef  ANTLR_USE_NAMESPACE
+#       define ANTLR_USE_NAMESPACE(_x_)
+#       undef ANTLR_USING_NAMESPACE
+#       define ANTLR_USING_NAMESPACE(_x_)
+#       undef ANTLR_CXX_SUPPORTS_NAMESPACE
+#      endif           // End __SUNPRO_CC == 0x420
+
+#      undef explicit
+#      define explicit
+
+#      define exception os_exception
+#      define bad_exception os_bad_exception
+
+// Not allowed to put 'static const int XXX=20;' in a class definition
+#      define NO_STATIC_CONSTS
+// Using vector<XXX> requires operator<(X,X) to be defined
+#      define NEEDS_OPERATOR_LESS_THAN
+
+# endif
+
+# undef ANTLR_CCTYPE_NEEDS_STD
+
+#endif // end __SUNPRO_CC
+/*}}}*/
+/*****************************************************************************/
+/*{{{ Inprise C++ Builder 3.0
+ *****************************************************************************/
+#ifdef __BCPLUSPLUS__
+# define NO_TEMPLATE_PARTS
+# define NO_STRCASECMP
+# undef ANTLR_CCTYPE_NEEDS_STD
+#endif // End of C++ Builder 3.0
+/*}}}*/
+/*****************************************************************************/
+/*{{{ IBM VisualAge C++ ( which includes the Dinkumware C++ Library )
+ *****************************************************************************/
+#ifdef __IBMCPP__
+
+// No strcasecmp in the C library (so use stricmp instead)
+// - Anyone know which is in which standard?
+#if (defined(_AIX) && (__IBMCPP__ >= 600))
+# define NO_STATIC_CONSTS
+#else
+# define NO_STRCASECMP
+# undef ANTLR_CCTYPE_NEEDS_STD
+#endif
+
+#endif // end IBM VisualAge C++
+/*}}}*/
+/*****************************************************************************/
+/*{{{ Metrowerks Codewarrior
+ *****************************************************************************/
+#ifdef __MWERKS__
+# if (__MWERKS__ <= 0x2201)
+#      define NO_TEMPLATE_PARTS
+# endif
+
+// CW 6.0 and 7.0 still do not have it.
+# define ANTLR_REALLY_NO_STRCASECMP
+
+# undef ANTLR_C_USING
+# define ANTLR_C_USING(_x_)   using std:: ## _x_;
+
+# define ANTLR_CCTYPE_NEEDS_STD
+# undef ANTLR_CXX_SUPPORTS_UNCAUGHT_EXCEPTION
+
+#endif // End of Metrowerks Codewarrior
+/*}}}*/
+/*****************************************************************************/
+/*{{{ SGI Irix 6.5.10 MIPSPro compiler
+ *****************************************************************************/
+// (contributed by Anna Winkler)
+// Note: you can't compile ANTLR with the MIPSPro compiler on
+// anything < 6.5.10 because SGI just fixed a big bug dealing with
+// namespaces in that release.
+#ifdef __sgi
+# define HAS_NOT_CCTYPE_H
+# define HAS_NOT_CSTRING_H
+# define HAS_NOT_CSTDIO_H
+# undef ANTLR_CCTYPE_NEEDS_STD
+#endif // End IRIX MIPSPro
+/*}}}*/
+/*****************************************************************************/
+/*{{{ G++ in various incarnations
+ *****************************************************************************/
+// With the gcc-2.95 and 3.0 being in the near future we should start handling
+// incompatabilities between the various libstdc++'s.
+#if defined(__GNUC__) || defined(__GNUG__)
+// gcc 2 branch..
+# if (__GNUC__ == 2 )
+#      if (__GNUC_MINOR__ <= 8 )
+#       undef ANTLR_USE_NAMESPACE
+#       define ANTLR_USE_NAMESPACE(_x_)
+#       undef ANTLR_USING_NAMESPACE
+#       define ANTLR_USING_NAMESPACE(_x_)
+#       undef ANTLR_CXX_SUPPORTS_NAMESPACE
+#      endif
+#      if (__GNUC_MINOR__ > 8 && __GNUC_MINOR__ <= 95 )
+#        undef ANTLR_IOS_BASE
+#        define ANTLR_IOS_BASE ios
+#        undef ANTLR_CCTYPE_NEEDS_STD
+// compiling with -ansi ?
+#        ifdef __STRICT_ANSI__
+#              undef ANTLR_REALLY_NO_STRCASECMP
+#              define ANTLR_REALLY_NO_STRCASECMP
+#        endif
+#      else
+// experimental .96 .97 branches..
+#       undef ANTLR_CCTYPE_NEEDS_STD
+#      endif
+# endif
+#endif // ! __GNUC__
+/*}}}*/
+/*****************************************************************************/
+/*{{{ Digital CXX (Tru64)
+ *****************************************************************************/
+#ifdef __DECCXX
+#define __USE_STD_IOSTREAM
+#endif
+/*}}}*/
+/*****************************************************************************/
+#ifdef __BORLANDC__
+# if  __BORLANDC__ >= 560
+#      include <ctype>
+#      include <stdlib>
+#      define ANTLR_CCTYPE_NEEDS_STD
+# else
+#      error "sorry, compiler is too old - consider an update."
+# endif
+#endif
+
+// Redefine these for backwards compatability..
+#undef ANTLR_BEGIN_NAMESPACE
+#undef ANTLR_END_NAMESPACE
+
+#if ANTLR_CXX_SUPPORTS_NAMESPACE == 1
+# define ANTLR_BEGIN_NAMESPACE(_x_) namespace _x_ {
+# define ANTLR_END_NAMESPACE }
+#else
+# define ANTLR_BEGIN_NAMESPACE(_x_)
+# define ANTLR_END_NAMESPACE
+#endif
+
+#endif //INC_config_hpp__
diff --git a/libsecurity_codesigning/antlr2/contrib/bcb4/README b/libsecurity_codesigning/antlr2/contrib/bcb4/README
new file mode 100644 (file)
index 0000000..3bee8b8
--- /dev/null
@@ -0,0 +1,3 @@
+Project files for Borland C++Builder 4.0 to build antlr.lib
+
+Donated by Ross Bencina
diff --git a/libsecurity_codesigning/antlr2/contrib/bcb4/antlr.bpr b/libsecurity_codesigning/antlr2/contrib/bcb4/antlr.bpr
new file mode 100644 (file)
index 0000000..8734937
--- /dev/null
@@ -0,0 +1,182 @@
+# ---------------------------------------------------------------------------
+!if !$d(BCB)
+BCB = $(MAKEDIR)\..
+!endif
+
+# ---------------------------------------------------------------------------
+# IDE SECTION
+# ---------------------------------------------------------------------------
+# The following section of the project makefile is managed by the BCB IDE.
+# It is recommended to use the IDE to change any of the values in this
+# section.
+# ---------------------------------------------------------------------------
+
+VERSION = BCB.04.04
+# ---------------------------------------------------------------------------
+PROJECT = antlr.lib
+OBJFILES = antlr.obj ..\..\src\TreeParserSharedInputState.obj ..\..\src\ASTFactory.obj \
+  ..\..\src\ASTRefCount.obj ..\..\src\BaseAST.obj ..\..\src\BitSet.obj \
+  ..\..\src\CharBuffer.obj ..\..\src\CharScanner.obj ..\..\src\CommonAST.obj \
+  ..\..\src\CommonASTWithHiddenTokens.obj ..\..\src\CommonHiddenStreamToken.obj \
+  ..\..\src\CommonToken.obj ..\..\src\InputBuffer.obj \
+  ..\..\src\LexerSharedInputState.obj ..\..\src\LLkParser.obj \
+  ..\..\src\MismatchedCharException.obj ..\..\src\MismatchedTokenException.obj \
+  ..\..\src\NoViableAltException.obj ..\..\src\NoViableAltForCharException.obj \
+  ..\..\src\Parser.obj ..\..\src\ParserSharedInputState.obj \
+  ..\..\src\RecognitionException.obj ..\..\src\String.obj ..\..\src\Token.obj \
+  ..\..\src\TokenBuffer.obj ..\..\src\TokenStreamBasicFilter.obj \
+  ..\..\src\TokenStreamHiddenTokenFilter.obj ..\..\src\TokenStreamSelector.obj \
+  ..\..\src\TreeParser.obj ..\..\src\ANTLRException.obj
+DEFFILE =
+LIBFILES =
+RESDEPEN = $(RESFILES)
+RESFILES =
+LIBRARIES =
+PACKAGES =
+# ---------------------------------------------------------------------------
+PATHCPP = .;..\..\src
+PATHASM = .;
+PATHPAS = .;
+PATHRC = .;
+USERDEFINES = HAS_NOT_CSTDIO_H
+SYSDEFINES =NO_STRICT
+# ---------------------------------------------------------------------------
+CFLAG1 = -I..\..\src;$(BCB)\include;$(BCB)\include\vcl;..\.. -O2 -w -Ve -a8 -k- -vi -c \
+  -b- -w-par -w-inl -Vx -tWM -D$(SYSDEFINES);$(USERDEFINES)
+PFLAGS = -U..\..\src;$(DEBUGLIBPATH) -I..\..\src;$(BCB)\include;$(BCB)\include\vcl;..\.. \
+  -DHAS_NOT_CSTDIO_H -$Y- -$L- -$D- -v -JPHN -M
+AFLAGS = /i..\..\src /i$(BCB)\include /i$(BCB)\include\vcl /i..\..\..\cpp \
+  /dHAS_NOT_CSTDIO_H /mx /w2 /zn
+RFLAGS = -i..\..\src;$(BCB)\include;$(BCB)\include\vcl;..\..
+LFLAGS = /P64
+# ---------------------------------------------------------------------------
+ALLOBJ = $(OBJFILES)
+# ---------------------------------------------------------------------------
+!ifdef IDEOPTIONS
+
+[Version Info]
+IncludeVerInfo=0
+AutoIncBuild=0
+MajorVer=1
+MinorVer=0
+Release=0
+Build=0
+Debug=0
+PreRelease=0
+Special=0
+Private=0
+DLL=0
+Locale=1033
+CodePage=1252
+
+[Version Info Keys]
+CompanyName=
+FileDescription=
+FileVersion=1.0.0.0
+InternalName=
+LegalCopyright=
+LegalTrademarks=
+OriginalFilename=
+ProductName=
+ProductVersion=1.0.0.0
+Comments=
+
+[HistoryLists\hlIncludePath]
+Count=4
+Item0=..\..\src;$(BCB)\include;$(BCB)\include\vcl;..\..\..\cpp
+Item1=..\..\src;$(BCB)\include;$(BCB)\include\vcl;..\..
+Item2=$(BCB)\include;$(BCB)\include\vcl;F:\antlr2.7.1k\lib\cpp
+Item3=$(BCB)\include;$(BCB)\include\vcl
+
+[HistoryLists\hlDebugSourcePath]
+Count=1
+Item0=$(BCB)\source\vcl
+
+[HistoryLists\hlConditionals]
+Count=1
+Item0=HAS_NOT_CSTDIO_H
+
+[Debugging]
+DebugSourceDirs=$(BCB)\source\vcl
+
+[Parameters]
+RunParams=
+HostApplication=
+RemoteHost=
+RemotePath=
+RemoteDebug=0
+
+[Compiler]
+InMemoryExe=0
+ShowInfoMsgs=0
+
+!endif
+
+# ---------------------------------------------------------------------------
+# MAKE SECTION
+# ---------------------------------------------------------------------------
+# This section of the project makefile is not used by the BCB IDE.  It is for
+# the benefit of building from the command-line using the MAKE utility.
+# ---------------------------------------------------------------------------
+
+.autodepend
+# ---------------------------------------------------------------------------
+!if !$d(BCC32)
+BCC32 = bcc32
+!endif
+
+!if !$d(CPP32)
+CPP32 = cpp32
+!endif
+
+!if !$d(DCC32)
+DCC32 = dcc32
+!endif
+
+!if !$d(TASM32)
+TASM32 = tasm32
+!endif
+
+!if !$d(LINKER)
+LINKER = TLib
+!endif
+# ---------------------------------------------------------------------------
+!if $d(PATHCPP)
+.PATH.CPP = $(PATHCPP)
+.PATH.C   = $(PATHCPP)
+!endif
+
+!if $d(PATHPAS)
+.PATH.PAS = $(PATHPAS)
+!endif
+
+!if $d(PATHASM)
+.PATH.ASM = $(PATHASM)
+!endif
+# ---------------------------------------------------------------------------
+$(PROJECT): $(OBJFILES) $(LIBFILES)
+    $(BCB)\BIN\$(LINKER) /u $@ @&&!
+    $(LFLAGS) $?
+!
+# ---------------------------------------------------------------------------
+.pas.hpp:
+    $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< }
+
+.pas.obj:
+    $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< }
+
+.cpp.obj:
+    $(BCB)\BIN\$(BCC32) $(CFLAG1) -n$(@D) {$< }
+
+.c.obj:
+    $(BCB)\BIN\$(BCC32) $(CFLAG1) -n$(@D) {$< }
+
+.c.i:
+    $(BCB)\BIN\$(CPP32) $(CFLAG1) -n. {$< }
+
+.cpp.i:
+    $(BCB)\BIN\$(CPP32) $(CFLAG1) -n. {$< }
+
+.asm.obj:
+    $(BCB)\BIN\$(TASM32) $(AFLAGS) $<, $@
+# ---------------------------------------------------------------------------
diff --git a/libsecurity_codesigning/antlr2/contrib/bcb4/antlr.cpp b/libsecurity_codesigning/antlr2/contrib/bcb4/antlr.cpp
new file mode 100644 (file)
index 0000000..a7841bd
--- /dev/null
@@ -0,0 +1,37 @@
+//---------------------------------------------------------------------------
+#include <vcl.h>
+#pragma hdrstop
+USEUNIT("..\..\src\TreeParserSharedInputState.cpp");
+USEUNIT("..\..\src\ASTFactory.cpp");
+USEUNIT("..\..\src\ASTRefCount.cpp");
+USEUNIT("..\..\src\BaseAST.cpp");
+USEUNIT("..\..\src\BitSet.cpp");
+USEUNIT("..\..\src\CharBuffer.cpp");
+USEUNIT("..\..\src\CharScanner.cpp");
+USEUNIT("..\..\src\CommonAST.cpp");
+USEUNIT("..\..\src\CommonASTWithHiddenTokens.cpp");
+USEUNIT("..\..\src\CommonHiddenStreamToken.cpp");
+USEUNIT("..\..\src\CommonToken.cpp");
+USEUNIT("..\..\src\InputBuffer.cpp");
+USEUNIT("..\..\src\LexerSharedInputState.cpp");
+USEUNIT("..\..\src\LLkParser.cpp");
+USEUNIT("..\..\src\MismatchedCharException.cpp");
+USEUNIT("..\..\src\MismatchedTokenException.cpp");
+USEUNIT("..\..\src\NoViableAltException.cpp");
+USEUNIT("..\..\src\NoViableAltForCharException.cpp");
+USEUNIT("..\..\src\Parser.cpp");
+USEUNIT("..\..\src\ParserSharedInputState.cpp");
+USEUNIT("..\..\src\RecognitionException.cpp");
+USEUNIT("..\..\src\String.cpp");
+USEUNIT("..\..\src\Token.cpp");
+USEUNIT("..\..\src\TokenBuffer.cpp");
+USEUNIT("..\..\src\TokenStreamBasicFilter.cpp");
+USEUNIT("..\..\src\TokenStreamHiddenTokenFilter.cpp");
+USEUNIT("..\..\src\TokenStreamSelector.cpp");
+USEUNIT("..\..\src\TreeParser.cpp");
+USEUNIT("..\..\src\ANTLRException.cpp");
+//---------------------------------------------------------------------------
+#define Library
+
+// To add a file to the library use the Project menu 'Add to Project'.
+
diff --git a/libsecurity_codesigning/antlr2/doxygen.cfg b/libsecurity_codesigning/antlr2/doxygen.cfg
new file mode 100644 (file)
index 0000000..c88da52
--- /dev/null
@@ -0,0 +1,101 @@
+# 
+# Doxygen config file for ANTLR's C++ support libraries.
+#
+# Thanks to Bill Zheng for parts of this.
+#
+PROJECT_NAME       = "ANTLR Support Libraries 2.7.1+"
+# Input files:
+INPUT              = antlr src
+RECURSIVE          = YES
+FILE_PATTERNS      = *.cpp *.h *.hpp
+JAVADOC_AUTOBRIEF  = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor 
+#---------------------------------------------------------------------------
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed.
+MACRO_EXPANSION      = YES
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+SEARCH_INCLUDES      = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+INCLUDE_PATH         =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed.
+PREDEFINED           =  "ANTLR_USE_NAMESPACE(_x_)=_x_::" \
+                       "ANTLR_USING_NAMESPACE(_x_)=using namespace _x_;" \
+                       "ANTLR_C_USING(_x_)=" \
+                       "ANTLR_API="
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED tag.
+EXPAND_ONLY_PREDEF   = YES
+
+# Output options
+OUTPUT_DIRECTORY   = gen_doc
+PAPER_TYPE         = a4wide
+#PAPER_TYPE        = a4
+TAB_SIZE           = 3
+CASE_SENSE_NAMES   = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+REPEAT_BRIEF         = YES
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+INTERNAL_DOCS        = NO
+
+# if the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# reimplements.
+INHERIT_DOCS         = YES
+
+# if the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+INLINE_INFO          = YES
+
+# Dot and friends...
+HAVE_DOT           = YES
+CLASS_GRAPH        = YES
+COLLABORATION_GRAPH = YES
+INCLUDE_GRAPH      = YES
+INCLUDED_BY_GRAPH  = YES
+EXTRACT_ALL        = YES
+EXTRACT_STATIC     = YES
+EXTRACT_PRIVATE    = YES
+# HTML output and friends...
+GENERATE_HTML      = YES
+# Tree view gives too much trouble with various browsers.
+GENERATE_TREEVIEW  = NO
+# Latex output and friends...
+GENERATE_LATEX     = NO
+PDF_HYPERLINKS     = YES
+GENERATE_MAN       = NO
+GENERATE_RTF       = NO
+# Control of convenience stuff
+GENERATE_TODOLIST = YES
+# Control over warnings etc. Unset EXTRACT_ALL to get this to work
+WARN_IF_UNDOCUMENTED = YES
+WARNINGS             = YES
+QUIET                = YES
diff --git a/libsecurity_codesigning/antlr2/libsecurity_codesigning.plist b/libsecurity_codesigning/antlr2/libsecurity_codesigning.plist
new file mode 100644 (file)
index 0000000..f2ac2ca
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<array>
+       <dict>
+               <key>OpenSourceLicense</key>
+               <string>public domain</string>
+               <key>OpenSourceLicenseFile</key>
+               <string>libsecurity_codesigning.txt</string>
+               <key>OpenSourceModifications</key>
+               <string>none</string>
+               <key>OpenSourceProject</key>
+               <string>antlr2</string>
+               <key>OpenSourceURL</key>
+               <string>http://www.antlr2.org/download/antlr-2.7.7.tar.gz</string>
+               <key>OpenSourceVersion</key>
+               <string>antlr2-2.7.7</string>
+               <key>OpenSourceWebsiteURL</key>
+               <string>http://www.antlr2.org/</string>
+               <key>OpenSourceImportDate</key>
+               <string>2012-12-21</string>
+       </dict>
+</array>
+</plist>
diff --git a/libsecurity_codesigning/antlr2/libsecurity_codesigning.txt b/libsecurity_codesigning/antlr2/libsecurity_codesigning.txt
new file mode 100644 (file)
index 0000000..0ec09a9
--- /dev/null
@@ -0,0 +1,31 @@
+\r
+SOFTWARE RIGHTS\r
+\r
+ANTLR 1989-2006 Developed by Terence Parr
+Partially supported by University of San Francisco & jGuru.com\r
+\r
+We reserve no legal rights to the ANTLR--it is fully in the\r
+public domain. An individual or company may do whatever\r
+they wish with source code distributed with ANTLR or the\r
+code generated by ANTLR, including the incorporation of\r
+ANTLR, or its output, into commerical software.\r
+\r
+We encourage users to develop software with ANTLR. However,\r
+we do ask that credit is given to us for developing\r
+ANTLR. By "credit", we mean that if you use ANTLR or\r
+incorporate any source code into one of your programs\r
+(commercial product, research project, or otherwise) that\r
+you acknowledge this fact somewhere in the documentation,\r
+research report, etc... If you like ANTLR and have\r
+developed a nice tool with the output, please mention that\r
+you developed it using ANTLR. In addition, we ask that the\r
+headers remain intact in our source code. As long as these\r
+guidelines are kept, we expect to continue enhancing this\r
+system and expect to make other tools available as they are\r
+completed.\r
+\r
+The primary ANTLR guy:\r
+\r
+Terence Parr\r
+parrt@cs.usfca.edu
+parrt@antlr.org
diff --git a/libsecurity_codesigning/antlr2/scripts/cr_stripper.sh b/libsecurity_codesigning/antlr2/scripts/cr_stripper.sh
new file mode 100644 (file)
index 0000000..8133c1d
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+for f in antlr/*.hpp src/*.cpp; do
+       cat "$f" | tr -d "\r" > $$
+       cmp -s $$ "$f" || (p4 edit "$f" && mv $$ "$f" && echo "$f Fixed")
+done
diff --git a/libsecurity_codesigning/antlr2/scripts/make_change_log.tcl b/libsecurity_codesigning/antlr2/scripts/make_change_log.tcl
new file mode 100755 (executable)
index 0000000..50a17ab
--- /dev/null
@@ -0,0 +1,57 @@
+#!/bin/sh
+# the next line restarts using tclsh \
+exec tclsh8.3 $0 $*
+
+# 
+# Sort the (C++) changes recorded in the repository by change number and
+# print them to stdout
+#
+set depots {//depot/code/org.antlr/dev/klaren.dev //depot/code/org.antlr/main/main }
+set files { /lib/cpp/... /antlr/... }
+set filespec ""
+foreach depot $depots {
+       foreach file $files {
+               append filespec "$depot$file "
+       }
+}
+
+puts stderr "Gettting changes from: $filespec"
+
+catch {set file [open "|p4 changes -l $filespec" r]}
+
+set cnt 0
+set changes {}
+set text ""
+set change_nr -1
+
+while {![eof $file]} {
+       set line [gets $file]
+
+       if { [regexp -- {^Change ([0-9]+).*$} $line dummy tmp] } {
+               # append the number to the list of found changes
+               lappend changes $tmp
+
+               if { $change_nr != -1 } {
+                       # were already working on change..
+                       # so we have text to store..
+                       set description($change_nr) $text
+               }
+
+               # remember number...
+               set change_nr $tmp
+               # reinit text
+               set text "[string trim $line]\n"
+       } else {
+               append text "   [string trim $line]\n"
+       }
+}
+
+set description($change_nr) $text
+
+catch {close $file}
+
+set sorted_changes [lsort -unique -integer -decreasing $changes]
+
+foreach change $sorted_changes {
+       puts $description($change)
+}
diff --git a/libsecurity_codesigning/antlr2/src/ANTLRUtil.cpp b/libsecurity_codesigning/antlr2/src/ANTLRUtil.cpp
new file mode 100644 (file)
index 0000000..4b5f9d8
--- /dev/null
@@ -0,0 +1,164 @@
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id:$
+ */
+
+#include <antlr/config.hpp>
+#include <antlr/IOException.hpp>
+#include <antlr/ANTLRUtil.hpp>
+
+#include <istream>
+#include <cctype>
+#include <string>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/** Eat whitespace from the input stream
+ * @param is the stream to read from
+ */
+ANTLR_USE_NAMESPACE(std)istream& eatwhite( ANTLR_USE_NAMESPACE(std)istream& is )
+{
+       char c;
+       while( is.get(c) )
+       {
+#ifdef ANTLR_CCTYPE_NEEDS_STD
+               if( !ANTLR_USE_NAMESPACE(std)isspace(c) )
+#else
+               if( !isspace(c) )
+#endif
+               {
+                       is.putback(c);
+                       break;
+               }
+       }
+       return is;
+}
+
+/** Read a string enclosed by '"' from a stream. Also handles escaping of \".
+ * Skips leading whitespace.
+ * @param in the istream to read from.
+ * @returns the string read from file exclusive the '"'
+ * @throws IOException if string is badly formatted
+ */
+ANTLR_USE_NAMESPACE(std)string read_string( ANTLR_USE_NAMESPACE(std)istream& in )
+{
+       char ch;
+       ANTLR_USE_NAMESPACE(std)string ret("");
+       // States for a simple state machine...
+       enum { START, READING, ESCAPE, FINISHED };
+       int state = START;
+
+       eatwhite(in);
+
+       while( state != FINISHED && in.get(ch) )
+       {
+               switch( state )
+               {
+               case START:
+                       // start state: check wether starting with " then switch to READING
+                       if( ch != '"' )
+                               throw IOException("string must start with '\"'");
+                       state = READING;
+                       continue;
+               case READING:
+                       // reading state: look out for escape sequences and closing "
+                       if( ch == '\\' )                // got escape sequence
+                       {
+                               state = ESCAPE;
+                               continue;
+                       }
+                       if( ch == '"' )                 // close quote -> stop
+                       {
+                               state = FINISHED;
+                               continue;
+                       }
+                       ret += ch;                              // else append...
+                       continue;
+               case ESCAPE:
+                       switch(ch)
+                       {
+                       case '\\':
+                               ret += ch;
+                               state = READING;
+                               continue;
+                       case '"':
+                               ret += ch;
+                               state = READING;
+                               continue;
+                       case '0':
+                               ret += '\0';
+                               state = READING;
+                               continue;
+                       default:                                                // unrecognized escape is not mapped
+                               ret += '\\';
+                               ret += ch;
+                               state = READING;
+                               continue;
+                       }
+               }
+       }
+       if( state != FINISHED )
+               throw IOException("badly formatted string: "+ret);
+
+       return ret;
+}
+
+/* Read a ([A-Z][0-9][a-z]_)* kindoff thing. Skips leading whitespace.
+ * @param in the istream to read from.
+ */
+ANTLR_USE_NAMESPACE(std)string read_identifier( ANTLR_USE_NAMESPACE(std)istream& in )
+{
+       char ch;
+       ANTLR_USE_NAMESPACE(std)string ret("");
+
+       eatwhite(in);
+
+       while( in.get(ch) )
+       {
+#ifdef ANTLR_CCTYPE_NEEDS_STD
+               if( ANTLR_USE_NAMESPACE(std)isupper(ch) ||
+                        ANTLR_USE_NAMESPACE(std)islower(ch) ||
+                        ANTLR_USE_NAMESPACE(std)isdigit(ch) ||
+                        ch == '_' )
+#else
+               if( isupper(ch) || islower(ch) || isdigit(ch) || ch == '_' )
+#endif
+                       ret += ch;
+               else
+               {
+                       in.putback(ch);
+                       break;
+               }
+       }
+       return ret;
+}
+
+/** Read a attribute="value" thing. Leading whitespace is skipped.
+ * Between attribute and '=' no whitespace is allowed. After the '=' it is
+ * permitted.
+ * @param in the istream to read from.
+ * @param attribute string the attribute name is put in
+ * @param value string the value of the attribute is put in
+ * @throws IOException if something is fishy. E.g. malformed quoting
+ * or missing '='
+ */
+void read_AttributeNValue( ANTLR_USE_NAMESPACE(std)istream& in,
+                                                                       ANTLR_USE_NAMESPACE(std)string& attribute,
+                                                                       ANTLR_USE_NAMESPACE(std)string& value )
+{
+       attribute = read_identifier(in);
+
+       char ch;
+       if( in.get(ch) && ch == '=' )
+               value = read_string(in);
+       else
+               throw IOException("invalid attribute=value thing "+attribute);
+}
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
diff --git a/libsecurity_codesigning/antlr2/src/ASTFactory.cpp b/libsecurity_codesigning/antlr2/src/ASTFactory.cpp
new file mode 100644 (file)
index 0000000..d4c7e30
--- /dev/null
@@ -0,0 +1,504 @@
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/src/ASTFactory.cpp#2 $
+ */
+
+#include "antlr/CommonAST.hpp"
+#include "antlr/ANTLRException.hpp"
+#include "antlr/IOException.hpp"
+#include "antlr/ASTFactory.hpp"
+#include "antlr/ANTLRUtil.hpp"
+
+//#include <iostream>
+#include <istream>
+
+using namespace std;
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/** AST Support code shared by TreeParser and Parser.
+ * We use delegation to share code (and have only one
+ * bit of code to maintain) rather than subclassing
+ * or superclassing (forces AST support code to be
+ * loaded even when you don't want to do AST stuff).
+ *
+ * This class collects all factories of AST types used inside the code.
+ * New AST node types are registered with the registerFactory method.
+ * On creation of an ASTFactory object a default AST node factory may be
+ * specified.
+ *
+ * When registering types gaps between different types are filled with entries
+ * for the default factory.
+ */
+
+/// Initialize factory
+ASTFactory::ASTFactory()
+: default_factory_descriptor(ANTLR_USE_NAMESPACE(std)make_pair(CommonAST::TYPE_NAME,&CommonAST::factory))
+{
+       nodeFactories.resize( Token::MIN_USER_TYPE, &default_factory_descriptor );
+}
+
+/** Initialize factory with a non default node type.
+ * factory_node_name should be the name of the AST node type the factory
+ * generates. (should exist during the existance of this ASTFactory instance)
+ */
+ASTFactory::ASTFactory( const char* factory_node_name, factory_type fact )
+: default_factory_descriptor(ANTLR_USE_NAMESPACE(std)make_pair(factory_node_name, fact))
+{
+       nodeFactories.resize( Token::MIN_USER_TYPE, &default_factory_descriptor );
+}
+
+/// Delete ASTFactory
+ASTFactory::~ASTFactory()
+{
+       factory_descriptor_list::iterator i = nodeFactories.begin();
+
+       while( i != nodeFactories.end() )
+       {
+               if( *i != &default_factory_descriptor )
+                       delete *i;
+               i++;
+       }
+}
+
+/// Register a factory for a given AST type
+void ASTFactory::registerFactory( int type, const char* ast_name, factory_type factory )
+{
+       // check validity of arguments...
+       if( type < Token::MIN_USER_TYPE )
+               throw ANTLRException("Internal parser error invalid type passed to RegisterFactory");
+       if( factory == 0 )
+               throw ANTLRException("Internal parser error 0 factory passed to RegisterFactory");
+
+       // resize up to and including 'type' and initalize any gaps to default
+       // factory.
+       if( nodeFactories.size() < (static_cast<unsigned int>(type)+1) )
+               nodeFactories.resize( type+1, &default_factory_descriptor );
+
+       // And add new thing..
+       nodeFactories[type] = new ANTLR_USE_NAMESPACE(std)pair<const char*, factory_type>( ast_name, factory );
+}
+
+void ASTFactory::setMaxNodeType( int type )
+{
+       if( nodeFactories.size() < (static_cast<unsigned int>(type)+1) )
+               nodeFactories.resize( type+1, &default_factory_descriptor );
+}
+
+/** Create a new empty AST node; if the user did not specify
+ *  an AST node type, then create a default one: CommonAST.
+ */
+RefAST ASTFactory::create()
+{
+       RefAST node = nodeFactories[0]->second();
+       node->setType(Token::INVALID_TYPE);
+       return node;
+}
+
+RefAST ASTFactory::create(int type)
+{
+       RefAST t = nodeFactories[type]->second();
+       t->initialize(type,"");
+       return t;
+}
+
+RefAST ASTFactory::create(int type, const ANTLR_USE_NAMESPACE(std)string& txt)
+{
+       RefAST t = nodeFactories[type]->second();
+       t->initialize(type,txt);
+       return t;
+}
+
+#ifdef ANTLR_SUPPORT_XML
+RefAST ASTFactory::create(const ANTLR_USE_NAMESPACE(std)string& type_name, ANTLR_USE_NAMESPACE(std)istream& infile )
+{
+       factory_descriptor_list::iterator fact = nodeFactories.begin();
+
+       while( fact != nodeFactories.end() )
+       {
+               if( type_name == (*fact)->first )
+               {
+                       RefAST t = (*fact)->second();
+                       t->initialize(infile);
+                       return t;
+               }
+               fact++;
+       }
+
+       string error = "ASTFactory::create: Unknown AST type '" + type_name + "'";
+       throw ANTLRException(error);
+}
+#endif
+
+/** Create a new empty AST node; if the user did not specify
+ *  an AST node type, then create a default one: CommonAST.
+ */
+RefAST ASTFactory::create(RefAST tr)
+{
+       if (!tr)
+               return nullAST;
+
+//     cout << "create(tr)" << endl;
+
+       RefAST t = nodeFactories[tr->getType()]->second();
+       t->initialize(tr);
+       return t;
+}
+
+RefAST ASTFactory::create(RefToken tok)
+{
+//     cout << "create( tok="<< tok->getType() << ", " << tok->getText() << ")" << nodeFactories.size() << endl;
+       RefAST t = nodeFactories[tok->getType()]->second();
+       t->initialize(tok);
+       return t;
+}
+
+/** Add a child to the current AST */
+void ASTFactory::addASTChild(ASTPair& currentAST, RefAST child)
+{
+       if (child)
+       {
+               if (!currentAST.root)
+               {
+                       // Make new child the current root
+                       currentAST.root = child;
+               }
+               else
+               {
+                       if (!currentAST.child)
+                       {
+                               // Add new child to current root
+                               currentAST.root->setFirstChild(child);
+                       }
+                       else
+                       {
+                               currentAST.child->setNextSibling(child);
+                       }
+               }
+               // Make new child the current child
+               currentAST.child = child;
+               currentAST.advanceChildToEnd();
+       }
+}
+
+/** Deep copy a single node. This function the new clone() methods in the AST
+ * interface. Returns nullAST if t is null.
+ */
+RefAST ASTFactory::dup(RefAST t)
+{
+       if( t )
+               return t->clone();
+       else
+               return RefAST(nullASTptr);
+}
+
+/** Duplicate tree including siblings of root. */
+RefAST ASTFactory::dupList(RefAST t)
+{
+       RefAST result = dupTree(t);         // if t == null, then result==null
+       RefAST nt = result;
+
+       while( t )
+       {                                                                                               // for each sibling of the root
+               t = t->getNextSibling();
+               nt->setNextSibling(dupTree(t)); // dup each subtree, building new tree
+               nt = nt->getNextSibling();
+       }
+       return result;
+}
+
+/** Duplicate a tree, assuming this is a root node of a tree
+ * duplicate that node and what's below; ignore siblings of root node.
+ */
+RefAST ASTFactory::dupTree(RefAST t)
+{
+       RefAST result = dup(t);         // make copy of root
+       // copy all children of root.
+       if( t )
+               result->setFirstChild( dupList(t->getFirstChild()) );
+       return result;
+}
+
+/** Make a tree from a list of nodes.  The first element in the
+ * array is the root.  If the root is null, then the tree is
+ * a simple list not a tree.  Handles null children nodes correctly.
+ * For example, make(a, b, null, c) yields tree (a b c).  make(null,a,b)
+ * yields tree (nil a b).
+ */
+RefAST ASTFactory::make(ANTLR_USE_NAMESPACE(std)vector<RefAST>& nodes)
+{
+       if ( nodes.size() == 0 )
+               return RefAST(nullASTptr);
+
+       RefAST root = nodes[0];
+       RefAST tail = RefAST(nullASTptr);
+
+       if( root )
+               root->setFirstChild(RefAST(nullASTptr));        // don't leave any old pointers set
+
+       // link in children;
+       for( unsigned int i = 1; i < nodes.size(); i++ )
+       {
+               if ( nodes[i] == 0 )            // ignore null nodes
+                       continue;
+
+               if ( root == 0 )                        // Set the root and set it up for a flat list
+                       root = tail = nodes[i];
+               else if ( tail == 0 )
+               {
+                       root->setFirstChild(nodes[i]);
+                       tail = root->getFirstChild();
+               }
+               else
+               {
+                       tail->setNextSibling(nodes[i]);
+                       tail = tail->getNextSibling();
+               }
+
+               if( tail )      // RK: I cannot fathom why this missing check didn't bite anyone else...
+               {
+                       // Chase tail to last sibling
+                       while (tail->getNextSibling())
+                               tail = tail->getNextSibling();
+               }
+       }
+
+       return root;
+}
+
+/** Make a tree from a list of nodes, where the nodes are contained
+ * in an ASTArray object
+ */
+RefAST ASTFactory::make(ASTArray* nodes)
+{
+       RefAST ret = make(nodes->array);
+       delete nodes;
+       return ret;
+}
+
+/// Make an AST the root of current AST
+void ASTFactory::makeASTRoot( ASTPair& currentAST, RefAST root )
+{
+       if (root)
+       {
+               // Add the current root as a child of new root
+               root->addChild(currentAST.root);
+               // The new current child is the last sibling of the old root
+               currentAST.child = currentAST.root;
+               currentAST.advanceChildToEnd();
+               // Set the new root
+               currentAST.root = root;
+       }
+}
+
+void ASTFactory::setASTNodeFactory( const char* factory_node_name,
+                                                                                          factory_type factory )
+{
+       default_factory_descriptor.first = factory_node_name;
+       default_factory_descriptor.second = factory;
+}
+
+#ifdef ANTLR_SUPPORT_XML
+bool ASTFactory::checkCloseTag( ANTLR_USE_NAMESPACE(std)istream& in )
+{
+       char ch;
+
+       if( in.get(ch) )
+       {
+               if( ch == '<' )
+               {
+                       char ch2;
+                       if( in.get(ch2) )
+                       {
+                               if( ch2 == '/' )
+                               {
+                                       in.putback(ch2);
+                                       in.putback(ch);
+                                       return true;
+                               }
+                               in.putback(ch2);
+                               in.putback(ch);
+                               return false;
+                       }
+               }
+               in.putback(ch);
+               return false;
+       }
+       return false;
+}
+
+void ASTFactory::loadChildren( ANTLR_USE_NAMESPACE(std)istream& infile,
+                                                                                RefAST current )
+{
+       char ch;
+
+       for(;;)                 // for all children of this node....
+       {
+               eatwhite(infile);
+
+               infile.get(ch); // '<'
+               if( ch != '<' )
+               {
+                       string error = "Invalid XML file... no '<' found (";
+                       error += ch + ")";
+                       throw IOException(error);
+               }
+
+               infile.get(ch);         // / or text....
+
+               if( ch == '/' )         // check for close tag...
+               {
+                       string temp;
+
+                       // read until '>' and see if it matches the open tag... if not trouble
+                       temp = read_identifier( infile );
+
+                       if( strcmp(temp.c_str(), current->typeName() ) != 0 )
+                       {
+                               string error = "Invalid XML file... close tag does not match start tag: ";
+                               error += current->typeName();
+                               error += " closed by " + temp;
+                               throw IOException(error);
+                       }
+
+                       infile.get(ch); // must be a '>'
+
+                       if( ch != '>' )
+                       {
+                               string error = "Invalid XML file... no '>' found (";
+                               error += ch + ")";
+                               throw IOException(error);
+                       }
+                       // close tag => exit loop
+                       break;
+               }
+
+               // put our 'look ahead' back where it came from
+               infile.putback(ch);
+               infile.putback('<');
+
+               // and recurse into the tree...
+               RefAST child = LoadAST(infile);
+
+               current->addChild( child );
+       }
+}
+
+void ASTFactory::loadSiblings(ANTLR_USE_NAMESPACE(std)istream& infile,
+                                                                               RefAST current )
+{
+       for(;;)
+       {
+               eatwhite(infile);
+
+               if( infile.eof() )
+                       break;
+
+               if( checkCloseTag(infile) )
+                       break;
+
+               RefAST sibling = LoadAST(infile);
+               current->setNextSibling(sibling);
+       }
+}
+
+RefAST ASTFactory::LoadAST( ANTLR_USE_NAMESPACE(std)istream& infile )
+{
+       RefAST current = nullAST;
+       char ch;
+
+       eatwhite(infile);
+
+       if( !infile.get(ch) )
+               return nullAST;
+
+       if( ch != '<' )
+       {
+               string error = "Invalid XML file... no '<' found (";
+               error += ch + ")";
+               throw IOException(error);
+       }
+
+       string ast_type = read_identifier(infile);
+
+       // create the ast of type 'ast_type'
+       current = create( ast_type, infile );
+       if( current == nullAST )
+       {
+               string error = "Unsuported AST type: " + ast_type;
+               throw IOException(error);
+       }
+
+       eatwhite(infile);
+
+       infile.get(ch);
+
+       // now if we have a '/' here it's a single node. If it's a '>' we get
+       // a tree with children
+
+       if( ch == '/' )
+       {
+               infile.get(ch);         // get the closing '>'
+               if( ch != '>' )
+               {
+                       string error = "Invalid XML file... no '>' found after '/' (";
+                       error += ch + ")";
+                       throw IOException(error);
+               }
+
+               // get the rest on this level
+               loadSiblings( infile, current );
+
+               return current;
+       }
+
+       // and finaly see if we got the close tag...
+       if( ch != '>' )
+       {
+               string error = "Invalid XML file... no '>' found (";
+               error += ch + ")";
+               throw IOException(error);
+       }
+
+       // handle the ones below this level..
+       loadChildren( infile, current );
+
+       // load the rest on this level...
+       loadSiblings( infile, current );
+
+       return current;
+}
+#endif // ANTLR_SUPPORT_XML
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+/* Heterogeneous AST/XML-I/O ramblings...
+ *
+ * So there is some heterogeneous AST support....
+ * basically in the code generators a new custom ast is generated without
+ * going throug the factory. It also expects the RefXAST to be defined.
+ *
+ * Is it maybe better to register all AST types with the ASTFactory class
+ * together with the respective factory methods.
+ *
+ * More and more I get the impression that hetero ast was a kindoff hack
+ * on top of ANTLR's normal AST system.
+ *
+ * The heteroast stuff will generate trouble for all astFactory.create( ... )
+ * invocations. Most of this is handled via getASTCreateString methods in the
+ * codegenerator. At the moment getASTCreateString(GrammarAtom, String) has
+ * slightly to little info to do it's job (ok the hack that is in now
+ * works, but it's an ugly hack)
+ *
+ * An extra caveat is the 'nice' action.g thing. Which also judiciously calls
+ * getASTCreateString methods because it handles the #( ... ) syntax.
+ * And converts that to ASTFactory calls.
+ *
+ *
+ */
diff --git a/libsecurity_codesigning/antlr2/src/ASTNULLType.cpp b/libsecurity_codesigning/antlr2/src/ASTNULLType.cpp
new file mode 100644 (file)
index 0000000..e8e4c63
--- /dev/null
@@ -0,0 +1,157 @@
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id:$
+ */
+
+#include "antlr/config.hpp"
+#include "antlr/AST.hpp"
+#include "antlr/ASTNULLType.hpp"
+
+//#include <iostream>
+
+ANTLR_USING_NAMESPACE(std)
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+RefAST ASTNULLType::clone( void ) const
+{
+       return RefAST(this);
+}
+
+void ASTNULLType::addChild( RefAST )
+{
+}
+
+size_t ASTNULLType::getNumberOfChildren() const
+{
+       return 0;
+}
+
+bool ASTNULLType::equals( RefAST ) const
+{
+       return false;
+}
+
+bool ASTNULLType::equalsList( RefAST ) const
+{
+       return false;
+}
+
+bool ASTNULLType::equalsListPartial( RefAST ) const
+{
+       return false;
+}
+
+bool ASTNULLType::equalsTree( RefAST ) const
+{
+       return false;
+}
+
+bool ASTNULLType::equalsTreePartial( RefAST ) const
+{
+       return false;
+}
+
+vector<RefAST> ASTNULLType::findAll( RefAST )
+{
+       return vector<RefAST>();
+}
+
+vector<RefAST> ASTNULLType::findAllPartial( RefAST )
+{
+       return vector<RefAST>();
+}
+
+RefAST ASTNULLType::getFirstChild() const
+{
+       return this;
+}
+
+RefAST ASTNULLType::getNextSibling() const
+{
+       return this;
+}
+
+string ASTNULLType::getText() const
+{
+       return "<ASTNULL>";
+}
+
+int ASTNULLType::getType() const
+{
+       return Token::NULL_TREE_LOOKAHEAD;
+}
+
+void ASTNULLType::initialize( int, const string& )
+{
+}
+
+void ASTNULLType::initialize( RefAST )
+{
+}
+
+void ASTNULLType::initialize( RefToken )
+{
+}
+
+#ifdef ANTLR_SUPPORT_XML
+void ASTNULLType::initialize( istream& )
+{
+}
+#endif
+
+void ASTNULLType::setFirstChild( RefAST )
+{
+}
+
+void ASTNULLType::setNextSibling( RefAST )
+{
+}
+
+void ASTNULLType::setText( const string& )
+{
+}
+
+void ASTNULLType::setType( int )
+{
+}
+
+string ASTNULLType::toString() const
+{
+       return getText();
+}
+
+string ASTNULLType::toStringList() const
+{
+       return getText();
+}
+
+string ASTNULLType::toStringTree() const
+{
+       return getText();
+}
+
+#ifdef ANTLR_SUPPORT_XML
+bool ASTNULLType::attributesToStream( ostream& ) const
+{
+       return false;
+}
+
+void ASTNULLType::toStream( ostream& out ) const
+{
+       out << "</ASTNULL>" << endl;
+}
+#endif
+
+const char* ASTNULLType::typeName( void ) const
+{
+       return "ASTNULLType";
+}
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
diff --git a/libsecurity_codesigning/antlr2/src/ASTRefCount.cpp b/libsecurity_codesigning/antlr2/src/ASTRefCount.cpp
new file mode 100644 (file)
index 0000000..340005b
--- /dev/null
@@ -0,0 +1,41 @@
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/src/ASTRefCount.cpp#2 $
+ */
+#include "antlr/ASTRefCount.hpp"
+#include "antlr/AST.hpp"
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+ASTRef::ASTRef(AST* p)
+: ptr(p), count(1)
+{
+       if (p && !p->ref)
+               p->ref = this;
+}
+
+ASTRef::~ASTRef()
+{
+       delete ptr;
+}
+
+ASTRef* ASTRef::getRef(const AST* p)
+{
+       if (p) {
+               AST* pp = const_cast<AST*>(p);
+               if (pp->ref)
+                       return pp->ref->increment();
+               else
+                       return new ASTRef(pp);
+       } else
+               return 0;
+}
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
diff --git a/libsecurity_codesigning/antlr2/src/BaseAST.cpp b/libsecurity_codesigning/antlr2/src/BaseAST.cpp
new file mode 100644 (file)
index 0000000..0d2fba4
--- /dev/null
@@ -0,0 +1,281 @@
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/src/BaseAST.cpp#2 $
+ */
+
+#include "antlr/config.hpp"
+
+//#include <iostream>
+
+#include "antlr/AST.hpp"
+#include "antlr/BaseAST.hpp"
+
+ANTLR_USING_NAMESPACE(std)
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+size_t BaseAST::getNumberOfChildren() const
+{
+       RefBaseAST t = this->down;
+       size_t n = 0;
+       if( t )
+       {
+               n = 1;
+               while( t->right )
+               {
+                       t = t->right;
+                       n++;
+               }
+               return n;
+       }
+       return n;
+}
+
+void BaseAST::doWorkForFindAll(
+               ANTLR_USE_NAMESPACE(std)vector<RefAST>& v,
+               RefAST target,bool partialMatch)
+{
+       // Start walking sibling lists, looking for matches.
+       for (RefAST sibling=this;
+                       sibling;
+                       sibling=sibling->getNextSibling())
+       {
+               if ( (partialMatch && sibling->equalsTreePartial(target)) ||
+                               (!partialMatch && sibling->equalsTree(target)) ) {
+                       v.push_back(sibling);
+               }
+               // regardless of match or not, check any children for matches
+               if ( sibling->getFirstChild() ) {
+                       RefBaseAST(sibling->getFirstChild())->doWorkForFindAll(v, target, partialMatch);
+               }
+       }
+}
+
+/** Is t an exact structural and equals() match of this tree.  The
+ *  'this' reference is considered the start of a sibling list.
+ */
+bool BaseAST::equalsList(RefAST t) const
+{
+       // the empty tree is not a match of any non-null tree.
+       if (!t)
+               return false;
+
+       // Otherwise, start walking sibling lists.  First mismatch, return false.
+       RefAST sibling=this;
+       for (;sibling && t;
+                       sibling=sibling->getNextSibling(), t=t->getNextSibling()) {
+               // as a quick optimization, check roots first.
+               if (!sibling->equals(t))
+                       return false;
+               // if roots match, do full list match test on children.
+               if (sibling->getFirstChild()) {
+                       if (!sibling->getFirstChild()->equalsList(t->getFirstChild()))
+                               return false;
+               }
+               // sibling has no kids, make sure t doesn't either
+               else if (t->getFirstChild())
+                       return false;
+       }
+
+       if (!sibling && !t)
+               return true;
+
+       // one sibling list has more than the other
+       return false;
+}
+
+/** Is 'sub' a subtree of this list?
+ *  The siblings of the root are NOT ignored.
+ */
+bool BaseAST::equalsListPartial(RefAST sub) const
+{
+       // the empty tree is always a subset of any tree.
+       if (!sub)
+               return true;
+
+       // Otherwise, start walking sibling lists.  First mismatch, return false.
+       RefAST sibling=this;
+       for (;sibling && sub;
+                       sibling=sibling->getNextSibling(), sub=sub->getNextSibling()) {
+               // as a quick optimization, check roots first.
+               if (!sibling->equals(sub))
+                       return false;
+               // if roots match, do partial list match test on children.
+               if (sibling->getFirstChild())
+                       if (!sibling->getFirstChild()->equalsListPartial(sub->getFirstChild()))
+                               return false;
+       }
+
+       if (!sibling && sub)
+               // nothing left to match in this tree, but subtree has more
+               return false;
+
+       // either both are null or sibling has more, but subtree doesn't
+       return true;
+}
+
+/** Is tree rooted at 'this' equal to 't'?  The siblings
+ *  of 'this' are ignored.
+ */
+bool BaseAST::equalsTree(RefAST t) const
+{
+       // check roots first
+       if (!equals(t))
+               return false;
+       // if roots match, do full list match test on children.
+       if (getFirstChild()) {
+               if (!getFirstChild()->equalsList(t->getFirstChild()))
+                       return false;
+       }
+       // sibling has no kids, make sure t doesn't either
+       else if (t->getFirstChild())
+               return false;
+
+       return true;
+}
+
+/** Is 'sub' a subtree of the tree rooted at 'this'?  The siblings
+ *  of 'this' are ignored.
+ */
+bool BaseAST::equalsTreePartial(RefAST sub) const
+{
+       // the empty tree is always a subset of any tree.
+       if (!sub)
+               return true;
+
+       // check roots first
+       if (!equals(sub))
+               return false;
+       // if roots match, do full list partial match test on children.
+       if (getFirstChild())
+               if (!getFirstChild()->equalsListPartial(sub->getFirstChild()))
+                       return false;
+
+       return true;
+}
+
+/** Walk the tree looking for all exact subtree matches.  Return
+ *  an ASTEnumerator that lets the caller walk the list
+ *  of subtree roots found herein.
+ */
+ANTLR_USE_NAMESPACE(std)vector<RefAST> BaseAST::findAll(RefAST target)
+{
+       ANTLR_USE_NAMESPACE(std)vector<RefAST> roots;
+
+       // the empty tree cannot result in an enumeration
+       if (target) {
+               doWorkForFindAll(roots,target,false); // find all matches recursively
+       }
+
+       return roots;
+}
+
+/** Walk the tree looking for all subtrees.  Return
+ *  an ASTEnumerator that lets the caller walk the list
+ *  of subtree roots found herein.
+ */
+ANTLR_USE_NAMESPACE(std)vector<RefAST> BaseAST::findAllPartial(RefAST target)
+{
+       ANTLR_USE_NAMESPACE(std)vector<RefAST> roots;
+
+       // the empty tree cannot result in an enumeration
+       if (target)
+               doWorkForFindAll(roots,target,true); // find all matches recursively
+
+       return roots;
+}
+
+ANTLR_USE_NAMESPACE(std)string BaseAST::toStringList() const
+{
+       ANTLR_USE_NAMESPACE(std)string ts="";
+
+       if (getFirstChild())
+       {
+               ts+=" ( ";
+               ts+=toString();
+               ts+=getFirstChild()->toStringList();
+               ts+=" )";
+       }
+       else
+       {
+               ts+=" ";
+               ts+=toString();
+       }
+
+       if (getNextSibling())
+               ts+=getNextSibling()->toStringList();
+
+       return ts;
+}
+
+ANTLR_USE_NAMESPACE(std)string BaseAST::toStringTree() const
+{
+       ANTLR_USE_NAMESPACE(std)string ts = "";
+
+       if (getFirstChild())
+       {
+               ts+=" ( ";
+               ts+=toString();
+               ts+=getFirstChild()->toStringList();
+               ts+=" )";
+       }
+       else
+       {
+               ts+=" ";
+               ts+=toString();
+       }
+       return ts;
+}
+
+#ifdef ANTLR_SUPPORT_XML
+/* This whole XML output stuff needs a little bit more thought
+ * I'd like to store extra XML data in the node. e.g. for custom ast's
+ * with for instance symboltable references. This
+ * should be more pluggable..
+ * @returns boolean value indicating wether a closetag should be produced.
+ */
+bool BaseAST::attributesToStream( ANTLR_USE_NAMESPACE(std)ostream& out ) const
+{
+       out << "text=\"" << this->getText()
+               << "\" type=\"" << this->getType() << "\"";
+
+       return false;
+}
+
+void BaseAST::toStream( ANTLR_USE_NAMESPACE(std)ostream& out ) const
+{
+       for( RefAST node = this; node != 0; node = node->getNextSibling() )
+       {
+               out << "<" << this->typeName() << " ";
+
+               // Write out attributes and if there is extra data...
+               bool need_close_tag = node->attributesToStream( out );
+
+               if( need_close_tag )
+               {
+                       // got children so write them...
+                       if( node->getFirstChild() != 0 )
+                               node->getFirstChild()->toStream( out );
+
+                       // and a closing tag..
+                       out << "</" << node->typeName() << ">" << endl;
+               }
+       }
+}
+#endif
+
+// this is nasty, but it makes the code generation easier
+ANTLR_API RefAST nullAST;
+
+#if defined(_MSC_VER) && !defined(__ICL) // Microsoft Visual C++
+extern ANTLR_API AST* const nullASTptr = 0;
+#else
+ANTLR_API AST* const nullASTptr = 0;
+#endif
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
diff --git a/libsecurity_codesigning/antlr2/src/BitSet.cpp b/libsecurity_codesigning/antlr2/src/BitSet.cpp
new file mode 100644 (file)
index 0000000..d280813
--- /dev/null
@@ -0,0 +1,62 @@
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/src/BitSet.cpp#2 $
+ */
+#include "antlr/BitSet.hpp"
+#include <string>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+BitSet::BitSet(unsigned int nbits)
+: storage(nbits)
+{
+       for (unsigned int i = 0; i < nbits ; i++ )
+               storage[i] = false;
+}
+
+BitSet::BitSet( const unsigned long* bits_, unsigned int nlongs )
+: storage(nlongs*32)
+{
+       for ( unsigned int i = 0 ; i < (nlongs * 32); i++)
+               storage[i] = (bits_[i>>5] & (1UL << (i&31))) ? true : false;
+}
+
+BitSet::~BitSet()
+{
+}
+
+void BitSet::add(unsigned int el)
+{
+       if( el >= storage.size() )
+               storage.resize( el+1, false );
+
+       storage[el] = true;
+}
+
+bool BitSet::member(unsigned int el) const
+{
+       if ( el >= storage.size())
+               return false;
+
+       return storage[el];
+}
+
+ANTLR_USE_NAMESPACE(std)vector<unsigned int> BitSet::toArray() const
+{
+       ANTLR_USE_NAMESPACE(std)vector<unsigned int> elems;
+       for (unsigned int i = 0; i < storage.size(); i++)
+       {
+               if (storage[i])
+                       elems.push_back(i);
+       }
+
+       return elems;
+}
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
diff --git a/libsecurity_codesigning/antlr2/src/CharBuffer.cpp b/libsecurity_codesigning/antlr2/src/CharBuffer.cpp
new file mode 100644 (file)
index 0000000..c40495e
--- /dev/null
@@ -0,0 +1,52 @@
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/src/CharBuffer.cpp#2 $
+ */
+
+#include "antlr/CharBuffer.hpp"
+//#include <iostream>
+
+//#include <ios>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/* RK: Per default istream does not throw exceptions. This can be
+ * enabled with:
+ * stream.exceptions(ios_base::badbit|ios_base::failbit|ios_base::eofbit);
+ *
+ * We could try catching the bad/fail stuff. But handling eof via this is
+ * not a good idea. EOF is best handled as a 'normal' character.
+ *
+ * So this does not work yet with gcc... Comment it until I get to a platform
+ * that does..
+ */
+
+/** Create a character buffer. Enable fail and bad exceptions, if supported
+ * by platform. */
+CharBuffer::CharBuffer(ANTLR_USE_NAMESPACE(std)istream& input_)
+: input(input_)
+{
+//     input.exceptions(ANTLR_USE_NAMESPACE(std)ios_base::badbit|
+//                                               ANTLR_USE_NAMESPACE(std)ios_base::failbit);
+}
+
+/** Get the next character from the stream. May throw CharStreamIOException
+ * when something bad happens (not EOF) (if supported by platform).
+ */
+int CharBuffer::getChar()
+{
+//     try {
+               return input.get();
+//     }
+//     catch (ANTLR_USE_NAMESPACE(std)ios_base::failure& e) {
+//             throw CharStreamIOException(e);
+//     }
+}
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
diff --git a/libsecurity_codesigning/antlr2/src/CharScanner.cpp b/libsecurity_codesigning/antlr2/src/CharScanner.cpp
new file mode 100644 (file)
index 0000000..8167c56
--- /dev/null
@@ -0,0 +1,107 @@
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/src/CharScanner.cpp#2 $
+ */
+
+#include <stdio.h>
+#include <string>
+
+#include "antlr/CharScanner.hpp"
+#include "antlr/CommonToken.hpp"
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+ANTLR_C_USING(exit)
+
+CharScanner::CharScanner(InputBuffer& cb, bool case_sensitive )
+       : saveConsumedInput(true) //, caseSensitiveLiterals(true)
+       , caseSensitive(case_sensitive)
+       , literals(CharScannerLiteralsLess(this))
+       , inputState(new LexerInputState(cb))
+       , commitToPath(false)
+       , tabsize(8)
+       , traceDepth(0)
+{
+       setTokenObjectFactory(&CommonToken::factory);
+}
+
+CharScanner::CharScanner(InputBuffer* cb, bool case_sensitive )
+       : saveConsumedInput(true) //, caseSensitiveLiterals(true)
+       , caseSensitive(case_sensitive)
+       , literals(CharScannerLiteralsLess(this))
+       , inputState(new LexerInputState(cb))
+       , commitToPath(false)
+       , tabsize(8)
+       , traceDepth(0)
+{
+       setTokenObjectFactory(&CommonToken::factory);
+}
+
+CharScanner::CharScanner( const LexerSharedInputState& state, bool case_sensitive )
+       : saveConsumedInput(true) //, caseSensitiveLiterals(true)
+       , caseSensitive(case_sensitive)
+       , literals(CharScannerLiteralsLess(this))
+       , inputState(state)
+       , commitToPath(false)
+       , tabsize(8)
+       , traceDepth(0)
+{
+       setTokenObjectFactory(&CommonToken::factory);
+}
+
+/** Report exception errors caught in nextToken() */
+void CharScanner::reportError(const RecognitionException& ex)
+{
+       fprintf(stderr, "%s", (ex.toString() + "\n").c_str());
+}
+
+/** Parser error-reporting function can be overridden in subclass */
+void CharScanner::reportError(const ANTLR_USE_NAMESPACE(std)string& s)
+{
+       if ( getFilename()=="" )
+               fprintf(stderr, "%s", ("error: " + s + "\n").c_str());
+       else
+               fprintf(stderr, "%s", (getFilename() + ": error: " + s + "\n").c_str());
+}
+
+/** Parser warning-reporting function can be overridden in subclass */
+void CharScanner::reportWarning(const ANTLR_USE_NAMESPACE(std)string& s)
+{
+       if ( getFilename()=="" )
+               fprintf(stderr, "%s", ("warning: " + s + "\n").c_str());
+       else
+               fprintf(stderr, "%s", (getFilename() + ": warning: " + s + "\n").c_str());
+}
+
+void CharScanner::traceIndent()
+{
+       for( int i = 0; i < traceDepth; i++ )
+               printf(" ");
+}
+
+void CharScanner::traceIn(const char* rname)
+{
+       traceDepth++;
+       traceIndent();
+       printf("> lexer %s; c==%d\n", rname, LA(1));
+}
+
+void CharScanner::traceOut(const char* rname)
+{
+       traceIndent();
+       printf("< lexer %s; c==%d\n", rname, LA(1));
+       traceDepth--;
+}
+
+#ifndef NO_STATIC_CONSTS
+const int CharScanner::NO_CHAR;
+const int CharScanner::EOF_CHAR;
+#endif
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
diff --git a/libsecurity_codesigning/antlr2/src/CommonAST.cpp b/libsecurity_codesigning/antlr2/src/CommonAST.cpp
new file mode 100644 (file)
index 0000000..acba576
--- /dev/null
@@ -0,0 +1,49 @@
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/src/CommonAST.cpp#2 $
+ */
+#include "antlr/config.hpp"
+
+#include <cstdlib>
+//#include <iostream>
+
+#include "antlr/CommonAST.hpp"
+#include "antlr/ANTLRUtil.hpp"
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+const char* const CommonAST::TYPE_NAME = "CommonAST";
+
+#ifdef ANTLR_SUPPORT_XML
+void CommonAST::initialize( ANTLR_USE_NAMESPACE(std)istream& in )
+{
+       ANTLR_USE_NAMESPACE(std)string t1, t2, text;
+
+       // text
+       read_AttributeNValue( in, t1, text );
+
+       read_AttributeNValue( in, t1, t2 );
+#ifdef ANTLR_ATOI_IN_STD
+       int type = ANTLR_USE_NAMESPACE(std)atoi(t2.c_str());
+#else
+       int type = atoi(t2.c_str());
+#endif
+
+       // initialize first part of AST.
+       this->initialize( type, text );
+}
+#endif
+
+RefAST CommonAST::factory()
+{
+       return RefAST(new CommonAST);
+}
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
diff --git a/libsecurity_codesigning/antlr2/src/CommonASTWithHiddenTokens.cpp b/libsecurity_codesigning/antlr2/src/CommonASTWithHiddenTokens.cpp
new file mode 100644 (file)
index 0000000..db2377b
--- /dev/null
@@ -0,0 +1,64 @@
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/src/CommonASTWithHiddenTokens.cpp#2 $
+ */
+#include "antlr/config.hpp"
+#include "antlr/AST.hpp"
+#include "antlr/BaseAST.hpp"
+#include "antlr/CommonAST.hpp"
+#include "antlr/CommonASTWithHiddenTokens.hpp"
+#include "antlr/CommonHiddenStreamToken.hpp"
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+const char* const CommonASTWithHiddenTokens::TYPE_NAME = "CommonASTWithHiddenTokens";
+// RK: Do not put constructor and destructor into the header file here..
+// this triggers something very obscure in gcc 2.95.3 (and 3.0)
+// missing vtables and stuff.
+// Although this may be a problem with with binutils.
+CommonASTWithHiddenTokens::CommonASTWithHiddenTokens()
+: CommonAST()
+{
+}
+
+CommonASTWithHiddenTokens::~CommonASTWithHiddenTokens()
+{
+}
+
+void CommonASTWithHiddenTokens::initialize(int t,const ANTLR_USE_NAMESPACE(std)string& txt)
+{
+       CommonAST::initialize(t,txt);
+}
+
+void CommonASTWithHiddenTokens::initialize(RefAST t)
+{
+       CommonAST::initialize(t);
+       hiddenBefore = RefCommonASTWithHiddenTokens(t)->getHiddenBefore();
+       hiddenAfter = RefCommonASTWithHiddenTokens(t)->getHiddenAfter();
+}
+
+void CommonASTWithHiddenTokens::initialize(RefToken t)
+{
+       CommonAST::initialize(t);
+       hiddenBefore = static_cast<CommonHiddenStreamToken*>(t.get())->getHiddenBefore();
+       hiddenAfter = static_cast<CommonHiddenStreamToken*>(t.get())->getHiddenAfter();
+}
+
+RefAST CommonASTWithHiddenTokens::factory()
+{
+       return RefAST(new CommonASTWithHiddenTokens);
+}
+
+RefAST CommonASTWithHiddenTokens::clone( void ) const
+{
+       CommonASTWithHiddenTokens *ast = new CommonASTWithHiddenTokens( *this );
+       return RefAST(ast);
+}
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
diff --git a/libsecurity_codesigning/antlr2/src/CommonHiddenStreamToken.cpp b/libsecurity_codesigning/antlr2/src/CommonHiddenStreamToken.cpp
new file mode 100644 (file)
index 0000000..adf386b
--- /dev/null
@@ -0,0 +1,56 @@
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/src/CommonHiddenStreamToken.cpp#2 $
+ */
+#include "antlr/CommonHiddenStreamToken.hpp"
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+CommonHiddenStreamToken::CommonHiddenStreamToken()
+: CommonToken()
+{
+}
+
+CommonHiddenStreamToken::CommonHiddenStreamToken(int t, const ANTLR_USE_NAMESPACE(std)string& txt)
+: CommonToken(t,txt)
+{
+}
+
+CommonHiddenStreamToken::CommonHiddenStreamToken(const ANTLR_USE_NAMESPACE(std)string& s)
+: CommonToken(s)
+{
+}
+
+RefToken CommonHiddenStreamToken::getHiddenAfter()
+{
+       return hiddenAfter;
+}
+
+RefToken CommonHiddenStreamToken::getHiddenBefore()
+{
+       return hiddenBefore;
+}
+
+RefToken CommonHiddenStreamToken::factory()
+{
+       return RefToken(new CommonHiddenStreamToken);
+}
+
+void CommonHiddenStreamToken::setHiddenAfter(RefToken t)
+{
+       hiddenAfter = t;
+}
+
+void CommonHiddenStreamToken::setHiddenBefore(RefToken t)
+{
+       hiddenBefore = t;
+}
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
diff --git a/libsecurity_codesigning/antlr2/src/CommonToken.cpp b/libsecurity_codesigning/antlr2/src/CommonToken.cpp
new file mode 100644 (file)
index 0000000..d49a0e2
--- /dev/null
@@ -0,0 +1,45 @@
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/src/CommonToken.cpp#2 $
+ */
+
+#include "antlr/CommonToken.hpp"
+#include "antlr/String.hpp"
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+CommonToken::CommonToken() : Token(), line(1), col(1), text("")
+{}
+
+CommonToken::CommonToken(int t, const ANTLR_USE_NAMESPACE(std)string& txt)
+: Token(t)
+, line(1)
+, col(1)
+, text(txt)
+{}
+
+CommonToken::CommonToken(const ANTLR_USE_NAMESPACE(std)string& s)
+: Token()
+, line(1)
+, col(1)
+, text(s)
+{}
+
+ANTLR_USE_NAMESPACE(std)string CommonToken::toString() const
+{
+       return "[\""+getText()+"\",<"+getType()+">,line="+getLine()+",column="+getColumn()+"]";
+}
+
+RefToken CommonToken::factory()
+{
+       return RefToken(new CommonToken);
+}
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
diff --git a/libsecurity_codesigning/antlr2/src/InputBuffer.cpp b/libsecurity_codesigning/antlr2/src/InputBuffer.cpp
new file mode 100644 (file)
index 0000000..235d60e
--- /dev/null
@@ -0,0 +1,81 @@
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/src/InputBuffer.cpp#2 $
+ */
+
+#include "antlr/config.hpp"
+#include "antlr/InputBuffer.hpp"
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/** Ensure that the character buffer is sufficiently full */
+void InputBuffer::fill(unsigned int amount)
+{
+       syncConsume();
+       // Fill the buffer sufficiently to hold needed characters
+       while (queue.entries() < amount + markerOffset)
+       {
+               // Append the next character
+               queue.append(getChar());
+       }
+}
+
+/** get the current lookahead characters as a string
+ * @warning it may treat 0 and EOF values wrong
+ */
+ANTLR_USE_NAMESPACE(std)string InputBuffer::getLAChars( void ) const
+{
+       ANTLR_USE_NAMESPACE(std)string ret;
+
+       for(unsigned int i = markerOffset; i < queue.entries(); i++)
+               ret += queue.elementAt(i);
+
+       return ret;
+}
+
+/** get the current marked characters as a string
+ * @warning it may treat 0 and EOF values wrong
+ */
+ANTLR_USE_NAMESPACE(std)string InputBuffer::getMarkedChars( void ) const
+{
+       ANTLR_USE_NAMESPACE(std)string ret;
+
+       for(unsigned int i = 0; i < markerOffset; i++)
+               ret += queue.elementAt(i);
+
+       return ret;
+}
+
+/** Return an integer marker that can be used to rewind the buffer to
+ * its current state.
+ */
+unsigned int InputBuffer::mark()
+{
+       syncConsume();
+       nMarkers++;
+       return markerOffset;
+}
+
+/** Rewind the character buffer to a marker.
+ * @param mark Marker returned previously from mark()
+ */
+void InputBuffer::rewind(unsigned int mark)
+{
+       syncConsume();
+       markerOffset = mark;
+       nMarkers--;
+}
+
+unsigned int InputBuffer::entries() const
+{
+       //assert(queue.entries() >= markerOffset);
+       return (unsigned int)queue.entries() - markerOffset;
+}
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
diff --git a/libsecurity_codesigning/antlr2/src/LLkParser.cpp b/libsecurity_codesigning/antlr2/src/LLkParser.cpp
new file mode 100644 (file)
index 0000000..4f4b7b3
--- /dev/null
@@ -0,0 +1,85 @@
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/src/LLkParser.cpp#2 $
+ */
+
+#include "antlr/LLkParser.hpp"
+#include <stdio.h>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+ANTLR_USING_NAMESPACE(std)
+
+/**An LL(k) parser.
+ *
+ * @see antlr.Token
+ * @see antlr.TokenBuffer
+ * @see antlr.LL1Parser
+ */
+
+//     LLkParser(int k_);
+
+LLkParser::LLkParser(const ParserSharedInputState& state, int k_)
+: Parser(state), k(k_)
+{
+}
+
+LLkParser::LLkParser(TokenBuffer& tokenBuf, int k_)
+: Parser(tokenBuf), k(k_)
+{
+}
+
+LLkParser::LLkParser(TokenStream& lexer, int k_)
+: Parser(new TokenBuffer(lexer)), k(k_)
+{
+}
+
+void LLkParser::trace(const char* ee, const char* rname)
+{
+       traceIndent();
+
+       printf("%s", ((string)ee + rname + ((inputState->guessing>0)?"; [guessing]":"; ")).c_str());
+
+       for (int i = 1; i <= k; i++)
+       {
+               if (i != 1) {
+                       printf(", ");
+               }
+               printf("LA(%d)==", i);
+
+               string temp;
+
+               try {
+                       temp = LT(i)->getText().c_str();
+               }
+               catch( ANTLRException& ae )
+               {
+                       temp = "[error: ";
+                       temp += ae.toString();
+                       temp += ']';
+               }
+               printf("%s", temp.c_str());
+       }
+
+       printf("\n");;
+}
+
+void LLkParser::traceIn(const char* rname)
+{
+       traceDepth++;
+       trace("> ",rname);
+}
+
+void LLkParser::traceOut(const char* rname)
+{
+       trace("< ",rname);
+       traceDepth--;
+}
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
diff --git a/libsecurity_codesigning/antlr2/src/Makefile.in b/libsecurity_codesigning/antlr2/src/Makefile.in
new file mode 100755 (executable)
index 0000000..3a9bf00
--- /dev/null
@@ -0,0 +1,136 @@
+##############################################################################
+# $Id:$
+###############################################################################
+
+##xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+@stdvars@
+##xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+
+## do not change this value 
+subdir=lib/cpp/src
+
+all : lib
+
+lib: @ANTLR_LIB@
+
+compile: $(antlr_obj_FILES)
+
+
+antlr_cxx_FILES = \
+ @abs_top_srcdir@/lib/cpp/src/ANTLRUtil.cpp \
+ @abs_top_srcdir@/lib/cpp/src/ASTFactory.cpp \
+ @abs_top_srcdir@/lib/cpp/src/ASTNULLType.cpp \
+ @abs_top_srcdir@/lib/cpp/src/ASTRefCount.cpp \
+ @abs_top_srcdir@/lib/cpp/src/BaseAST.cpp \
+ @abs_top_srcdir@/lib/cpp/src/BitSet.cpp \
+ @abs_top_srcdir@/lib/cpp/src/CharBuffer.cpp \
+ @abs_top_srcdir@/lib/cpp/src/CharScanner.cpp \
+ @abs_top_srcdir@/lib/cpp/src/CommonAST.cpp \
+ @abs_top_srcdir@/lib/cpp/src/CommonASTWithHiddenTokens.cpp \
+ @abs_top_srcdir@/lib/cpp/src/CommonHiddenStreamToken.cpp \
+ @abs_top_srcdir@/lib/cpp/src/CommonToken.cpp \
+ @abs_top_srcdir@/lib/cpp/src/InputBuffer.cpp \
+ @abs_top_srcdir@/lib/cpp/src/LLkParser.cpp \
+ @abs_top_srcdir@/lib/cpp/src/MismatchedCharException.cpp \
+ @abs_top_srcdir@/lib/cpp/src/MismatchedTokenException.cpp \
+ @abs_top_srcdir@/lib/cpp/src/NoViableAltException.cpp \
+ @abs_top_srcdir@/lib/cpp/src/NoViableAltForCharException.cpp \
+ @abs_top_srcdir@/lib/cpp/src/Parser.cpp \
+ @abs_top_srcdir@/lib/cpp/src/RecognitionException.cpp \
+ @abs_top_srcdir@/lib/cpp/src/String.cpp \
+ @abs_top_srcdir@/lib/cpp/src/Token.cpp \
+ @abs_top_srcdir@/lib/cpp/src/TokenBuffer.cpp \
+ @abs_top_srcdir@/lib/cpp/src/TokenStreamBasicFilter.cpp \
+ @abs_top_srcdir@/lib/cpp/src/TokenStreamHiddenTokenFilter.cpp \
+ @abs_top_srcdir@/lib/cpp/src/TokenStreamSelector.cpp \
+ @abs_top_srcdir@/lib/cpp/src/TokenStreamRewriteEngine.cpp \
+ @abs_top_srcdir@/lib/cpp/src/TreeParser.cpp \
+ @abs_top_srcdir@/lib/cpp/src/TokenRefCount.cpp \
+ $(eol)
+
+## contents of this varialbe could also be processed  by
+## some advanced GNU make 'scripting' features. This may
+## simplify maintenance but makes Makefile far less read-
+## able and non-portable.
+antlr_obj_FILES = \
+ @abs_this_builddir@/lib/cpp/src/ANTLRUtil@OBJEXT@ \
+ @abs_this_builddir@/lib/cpp/src/ASTFactory@OBJEXT@ \
+ @abs_this_builddir@/lib/cpp/src/ASTNULLType@OBJEXT@ \
+ @abs_this_builddir@/lib/cpp/src/ASTRefCount@OBJEXT@ \
+ @abs_this_builddir@/lib/cpp/src/BaseAST@OBJEXT@ \
+ @abs_this_builddir@/lib/cpp/src/BitSet@OBJEXT@ \
+ @abs_this_builddir@/lib/cpp/src/CharBuffer@OBJEXT@ \
+ @abs_this_builddir@/lib/cpp/src/CharScanner@OBJEXT@ \
+ @abs_this_builddir@/lib/cpp/src/CommonAST@OBJEXT@ \
+ @abs_this_builddir@/lib/cpp/src/CommonASTWithHiddenTokens@OBJEXT@ \
+ @abs_this_builddir@/lib/cpp/src/CommonHiddenStreamToken@OBJEXT@ \
+ @abs_this_builddir@/lib/cpp/src/CommonToken@OBJEXT@ \
+ @abs_this_builddir@/lib/cpp/src/InputBuffer@OBJEXT@ \
+ @abs_this_builddir@/lib/cpp/src/LLkParser@OBJEXT@ \
+ @abs_this_builddir@/lib/cpp/src/MismatchedCharException@OBJEXT@ \
+ @abs_this_builddir@/lib/cpp/src/MismatchedTokenException@OBJEXT@ \
+ @abs_this_builddir@/lib/cpp/src/NoViableAltException@OBJEXT@ \
+ @abs_this_builddir@/lib/cpp/src/NoViableAltForCharException@OBJEXT@ \
+ @abs_this_builddir@/lib/cpp/src/Parser@OBJEXT@ \
+ @abs_this_builddir@/lib/cpp/src/RecognitionException@OBJEXT@ \
+ @abs_this_builddir@/lib/cpp/src/String@OBJEXT@ \
+ @abs_this_builddir@/lib/cpp/src/Token@OBJEXT@ \
+ @abs_this_builddir@/lib/cpp/src/TokenBuffer@OBJEXT@ \
+ @abs_this_builddir@/lib/cpp/src/TokenStreamBasicFilter@OBJEXT@ \
+ @abs_this_builddir@/lib/cpp/src/TokenStreamHiddenTokenFilter@OBJEXT@ \
+ @abs_this_builddir@/lib/cpp/src/TokenStreamSelector@OBJEXT@ \
+ @abs_this_builddir@/lib/cpp/src/TokenStreamRewriteEngine@OBJEXT@ \
+ @abs_this_builddir@/lib/cpp/src/TreeParser@OBJEXT@ \
+ @abs_this_builddir@/lib/cpp/src/TokenRefCount@OBJEXT@ \
+ $(eol)
+
+
+## GNU make - how to make object file
+@abs_this_builddir@/lib/cpp/src/%@OBJEXT@ : @abs_top_srcdir@/lib/cpp/src/%.cpp
+       @ @CXX_COMPILE_CMD@ $<
+
+## Build static library. How the library is build as well as
+## libraries's name is hidden by our script, ie. configured.
+@ANTLR_LIB@ :: $(antlr_obj_FILES)
+       @ @CXX_LIB_CMD@ $(antlr_obj_FILES)
+
+clean:
+       @RMF@ *.obj *.o *.a  *.lib *.so *.dll *~ @ANTLR_LIB@
+
+## use this target if you just want to rebuild the lib without
+## compiling again.
+clean-lib:
+       @RMF@ @ANTLR_LIB@
+
+distclean: clean
+       @RMF@ Makefile
+
+test:
+
+install: this-install
+
+antlr_lib_FILES = \
+  @ANTLR_LIB@ \
+  $(eol)
+
+this-install: @ANTLR_LIB@ 
+       @$(MKDIR) -p "$(libdir)"
+       @@ECHO@ "install C++ core files .. "
+       @for f in $(antlr_lib_FILES) ; do \
+               @ECHO@ "install $${f}" ; \
+               if test -f "$${f}" ; then \
+                       $(INSTALL) -m 444 "$${f}" "$(libdir)" ; \
+               fi ;\
+       done
+
+
+.PHONY: all clean distclean compile lib install test clean-lib this-install
+
+## dependencies
+$(antlr_obj_FILES) : @abs_this_builddir@/scripts/cxx.sh
+@ANTLR_LIB@        :: @abs_this_builddir@/scripts/lib.sh
+
+## other dependencies to be listed below
+##xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+@stddeps@
+##xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
diff --git a/libsecurity_codesigning/antlr2/src/MismatchedCharException.cpp b/libsecurity_codesigning/antlr2/src/MismatchedCharException.cpp
new file mode 100644 (file)
index 0000000..6ca66e0
--- /dev/null
@@ -0,0 +1,120 @@
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/src/MismatchedCharException.cpp#2 $
+ */
+
+#include "antlr/CharScanner.hpp"
+#include "antlr/MismatchedCharException.hpp"
+#include "antlr/String.hpp"
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+MismatchedCharException::MismatchedCharException()
+  : RecognitionException("Mismatched char")
+{}
+
+// Expected range / not range
+MismatchedCharException::MismatchedCharException(
+       int c,
+       int lower,
+       int upper_,
+       bool matchNot,
+       CharScanner* scanner_
+) : RecognitionException("Mismatched char",
+                         scanner_->getFilename(),
+                                                                scanner_->getLine(), scanner_->getColumn())
+  , mismatchType(matchNot ? NOT_RANGE : RANGE)
+  , foundChar(c)
+  , expecting(lower)
+  , upper(upper_)
+  , scanner(scanner_)
+{
+}
+
+// Expected token / not token
+MismatchedCharException::MismatchedCharException(
+       int c,
+       int expecting_,
+       bool matchNot,
+       CharScanner* scanner_
+) : RecognitionException("Mismatched char",
+                         scanner_->getFilename(),
+                                                                scanner_->getLine(), scanner_->getColumn())
+  , mismatchType(matchNot ? NOT_CHAR : CHAR)
+  , foundChar(c)
+  , expecting(expecting_)
+  , scanner(scanner_)
+{
+}
+
+// Expected BitSet / not BitSet
+MismatchedCharException::MismatchedCharException(
+       int c,
+       BitSet set_,
+       bool matchNot,
+       CharScanner* scanner_
+) : RecognitionException("Mismatched char",
+                         scanner_->getFilename(),
+                                                                scanner_->getLine(), scanner_->getColumn())
+  , mismatchType(matchNot ? NOT_SET : SET)
+  , foundChar(c)
+  , set(set_)
+  , scanner(scanner_)
+{
+}
+
+ANTLR_USE_NAMESPACE(std)string MismatchedCharException::getMessage() const
+{
+       ANTLR_USE_NAMESPACE(std)string s;
+
+       switch (mismatchType) {
+       case CHAR :
+               s += "expecting '" + charName(expecting) + "', found '" + charName(foundChar) + "'";
+               break;
+       case NOT_CHAR :
+               s += "expecting anything but '" + charName(expecting) + "'; got it anyway";
+               break;
+       case RANGE :
+               s += "expecting token in range: '" + charName(expecting) + "'..'" + charName(upper) + "', found '" + charName(foundChar) + "'";
+               break;
+       case NOT_RANGE :
+               s += "expecting token NOT in range: " + charName(expecting) + "'..'" + charName(upper) + "', found '" + charName(foundChar) + "'";
+               break;
+       case SET :
+       case NOT_SET :
+               {
+                       s += ANTLR_USE_NAMESPACE(std)string("expecting ") + (mismatchType == NOT_SET ? "NOT " : "") + "one of (";
+                       ANTLR_USE_NAMESPACE(std)vector<unsigned int> elems = set.toArray();
+                       for ( unsigned int i = 0; i < elems.size(); i++ )
+                       {
+                               s += " '";
+                               s += charName(elems[i]);
+                               s += "'";
+                       }
+                       s += "), found '" + charName(foundChar) + "'";
+               }
+               break;
+       default :
+               s += RecognitionException::getMessage();
+               break;
+       }
+
+       return s;
+}
+
+#ifndef NO_STATIC_CONSTS
+const int MismatchedCharException::CHAR;
+const int MismatchedCharException::NOT_CHAR;
+const int MismatchedCharException::RANGE;
+const int MismatchedCharException::NOT_RANGE;
+const int MismatchedCharException::SET;
+const int MismatchedCharException::NOT_SET;
+#endif
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
diff --git a/libsecurity_codesigning/antlr2/src/MismatchedTokenException.cpp b/libsecurity_codesigning/antlr2/src/MismatchedTokenException.cpp
new file mode 100644 (file)
index 0000000..8fae8f0
--- /dev/null
@@ -0,0 +1,196 @@
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/src/MismatchedTokenException.cpp#2 $
+ */
+
+#include "antlr/MismatchedTokenException.hpp"
+#include "antlr/String.hpp"
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+MismatchedTokenException::MismatchedTokenException()
+  : RecognitionException("Mismatched Token: expecting any AST node","<AST>",-1,-1)
+  , token(0)
+  , node(nullASTptr)
+  , tokenNames(0)
+  , numTokens(0)
+{
+}
+
+// Expected range / not range
+MismatchedTokenException::MismatchedTokenException(
+       const char* const* tokenNames_,
+       const int numTokens_,
+       RefAST node_,
+       int lower,
+       int upper_,
+       bool matchNot
+) : RecognitionException("Mismatched Token","<AST>",-1,-1)
+  , token(0)
+  , node(node_)
+  , tokenText( (node_ ? node_->toString(): ANTLR_USE_NAMESPACE(std)string("<empty tree>")) )
+  , mismatchType(matchNot ? NOT_RANGE : RANGE)
+  , expecting(lower)
+  , upper(upper_)
+  , tokenNames(tokenNames_)
+  , numTokens(numTokens_)
+{
+}
+
+// Expected token / not token
+MismatchedTokenException::MismatchedTokenException(
+       const char* const* tokenNames_,
+       const int numTokens_,
+       RefAST node_,
+       int expecting_,
+       bool matchNot
+) : RecognitionException("Mismatched Token","<AST>",-1,-1)
+  , token(0)
+  , node(node_)
+  , tokenText( (node_ ? node_->toString(): ANTLR_USE_NAMESPACE(std)string("<empty tree>")) )
+  , mismatchType(matchNot ? NOT_TOKEN : TOKEN)
+  , expecting(expecting_)
+  , tokenNames(tokenNames_)
+  , numTokens(numTokens_)
+{
+}
+
+// Expected BitSet / not BitSet
+MismatchedTokenException::MismatchedTokenException(
+       const char* const* tokenNames_,
+       const int numTokens_,
+       RefAST node_,
+       BitSet set_,
+       bool matchNot
+) : RecognitionException("Mismatched Token","<AST>",-1,-1)
+  , token(0)
+  , node(node_)
+  , tokenText( (node_ ? node_->toString(): ANTLR_USE_NAMESPACE(std)string("<empty tree>")) )
+  , mismatchType(matchNot ? NOT_SET : SET)
+  , set(set_)
+  , tokenNames(tokenNames_)
+  , numTokens(numTokens_)
+{
+}
+
+// Expected range / not range
+MismatchedTokenException::MismatchedTokenException(
+       const char* const* tokenNames_,
+       const int numTokens_,
+       RefToken token_,
+       int lower,
+       int upper_,
+       bool matchNot,
+       const ANTLR_USE_NAMESPACE(std)string& fileName_
+) : RecognitionException("Mismatched Token",fileName_,token_->getLine(),token_->getColumn())
+  , token(token_)
+  , node(nullASTptr)
+  , tokenText(token_->getText())
+  , mismatchType(matchNot ? NOT_RANGE : RANGE)
+  , expecting(lower)
+  , upper(upper_)
+  , tokenNames(tokenNames_)
+  , numTokens(numTokens_)
+{
+}
+
+// Expected token / not token
+MismatchedTokenException::MismatchedTokenException(
+       const char* const* tokenNames_,
+       const int numTokens_,
+       RefToken token_,
+       int expecting_,
+       bool matchNot,
+       const ANTLR_USE_NAMESPACE(std)string& fileName_
+) : RecognitionException("Mismatched Token",fileName_,token_->getLine(),token_->getColumn())
+  , token(token_)
+  , node(nullASTptr)
+  , tokenText(token_->getText())
+  , mismatchType(matchNot ? NOT_TOKEN : TOKEN)
+  , expecting(expecting_)
+  , tokenNames(tokenNames_)
+  , numTokens(numTokens_)
+{
+}
+
+// Expected BitSet / not BitSet
+MismatchedTokenException::MismatchedTokenException(
+       const char* const* tokenNames_,
+       const int numTokens_,
+       RefToken token_,
+       BitSet set_,
+       bool matchNot,
+       const ANTLR_USE_NAMESPACE(std)string& fileName_
+) : RecognitionException("Mismatched Token",fileName_,token_->getLine(),token_->getColumn())
+  , token(token_)
+  , node(nullASTptr)
+  , tokenText(token_->getText())
+  , mismatchType(matchNot ? NOT_SET : SET)
+  , set(set_)
+  , tokenNames(tokenNames_)
+  , numTokens(numTokens_)
+{
+}
+
+ANTLR_USE_NAMESPACE(std)string MismatchedTokenException::getMessage() const
+{
+       ANTLR_USE_NAMESPACE(std)string s;
+       switch (mismatchType) {
+       case TOKEN:
+               s += "expecting " + tokenName(expecting) + ", found '" + tokenText + "'";
+               break;
+       case NOT_TOKEN:
+               s += "expecting anything but " + tokenName(expecting) + "; got it anyway";
+               break;
+       case RANGE:
+               s += "expecting token in range: " + tokenName(expecting) + ".." + tokenName(upper) + ", found '" + tokenText + "'";
+               break;
+       case NOT_RANGE:
+               s += "expecting token NOT in range: " + tokenName(expecting) + ".." + tokenName(upper) + ", found '" + tokenText + "'";
+               break;
+       case SET:
+       case NOT_SET:
+               {
+                       s += ANTLR_USE_NAMESPACE(std)string("expecting ") + (mismatchType == NOT_SET ? "NOT " : "") + "one of (";
+                       ANTLR_USE_NAMESPACE(std)vector<unsigned int> elems = set.toArray();
+                       for ( unsigned int i = 0; i < elems.size(); i++ )
+                       {
+                               s += " ";
+                               s += tokenName(elems[i]);
+                       }
+                       s += "), found '" + tokenText + "'";
+               }
+               break;
+       default:
+               s = RecognitionException::getMessage();
+               break;
+       }
+       return s;
+}
+
+ANTLR_USE_NAMESPACE(std)string MismatchedTokenException::tokenName(int tokenType) const
+{
+       if (tokenType == Token::INVALID_TYPE)
+               return "<Set of tokens>";
+       else if (tokenType < 0 || tokenType >= numTokens)
+               return ANTLR_USE_NAMESPACE(std)string("<") + tokenType + ">";
+       else
+               return tokenNames[tokenType];
+}
+
+#ifndef NO_STATIC_CONSTS
+const int MismatchedTokenException::TOKEN;
+const int MismatchedTokenException::NOT_TOKEN;
+const int MismatchedTokenException::RANGE;
+const int MismatchedTokenException::NOT_RANGE;
+const int MismatchedTokenException::SET;
+const int MismatchedTokenException::NOT_SET;
+#endif
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
diff --git a/libsecurity_codesigning/antlr2/src/NoViableAltException.cpp b/libsecurity_codesigning/antlr2/src/NoViableAltException.cpp
new file mode 100644 (file)
index 0000000..a41779d
--- /dev/null
@@ -0,0 +1,52 @@
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/src/NoViableAltException.cpp#2 $
+ */
+
+#include "antlr/NoViableAltException.hpp"
+#include "antlr/String.hpp"
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+ANTLR_USING_NAMESPACE(std)
+
+NoViableAltException::NoViableAltException(RefAST t)
+  : RecognitionException("NoViableAlt","<AST>",-1,-1),
+    token(0), node(t)
+{
+}
+
+NoViableAltException::NoViableAltException(
+       RefToken t,
+       const ANTLR_USE_NAMESPACE(std)string& fileName_
+) : RecognitionException("NoViableAlt",fileName_,t->getLine(),t->getColumn()),
+    token(t), node(nullASTptr)
+{
+}
+
+ANTLR_USE_NAMESPACE(std)string NoViableAltException::getMessage() const
+{
+       if (token)
+       {
+               if( token->getType() == Token::EOF_TYPE )
+                       return string("unexpected end of file");
+               else if( token->getType() == Token::NULL_TREE_LOOKAHEAD )
+                       return string("unexpected end of tree");
+               else
+                       return string("unexpected token: ")+token->getText();
+       }
+
+       // must a tree parser error if token==null
+       if (!node)
+               return "unexpected end of subtree";
+
+       return string("unexpected AST node: ")+node->toString();
+}
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
diff --git a/libsecurity_codesigning/antlr2/src/NoViableAltForCharException.cpp b/libsecurity_codesigning/antlr2/src/NoViableAltForCharException.cpp
new file mode 100644 (file)
index 0000000..0b2cf2d
--- /dev/null
@@ -0,0 +1,39 @@
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/src/NoViableAltForCharException.cpp#2 $
+ */
+
+#include "antlr/NoViableAltForCharException.hpp"
+#include "antlr/String.hpp"
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+NoViableAltForCharException::NoViableAltForCharException(int c, CharScanner* scanner)
+  : RecognitionException("NoViableAlt",
+                         scanner->getFilename(),
+                                                                scanner->getLine(),scanner->getColumn()),
+    foundChar(c)
+{
+}
+
+NoViableAltForCharException::NoViableAltForCharException(
+                                       int c,
+               const ANTLR_USE_NAMESPACE(std)string& fileName_,
+                                       int line_, int column_)
+  : RecognitionException("NoViableAlt",fileName_,line_,column_),
+    foundChar(c)
+{
+}
+
+ANTLR_USE_NAMESPACE(std)string NoViableAltForCharException::getMessage() const
+{
+       return ANTLR_USE_NAMESPACE(std)string("unexpected char: ")+charName(foundChar);
+}
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
diff --git a/libsecurity_codesigning/antlr2/src/Parser.cpp b/libsecurity_codesigning/antlr2/src/Parser.cpp
new file mode 100644 (file)
index 0000000..8b540f8
--- /dev/null
@@ -0,0 +1,113 @@
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/src/Parser.cpp#2 $
+ */
+
+#include "antlr/Parser.hpp"
+
+#include <stdio.h>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/** A generic ANTLR parser (LL(k) for k>=1) containing a bunch of
+ * utility routines useful at any lookahead depth.  We distinguish between
+ * the LL(1) and LL(k) parsers because of efficiency.  This may not be
+ * necessary in the near future.
+ *
+ * Each parser object contains the state of the parse including a lookahead
+ * cache (the form of which is determined by the subclass), whether or
+ * not the parser is in guess mode, where tokens come from, etc...
+ *
+ * <p>
+ * During <b>guess</b> mode, the current lookahead token(s) and token type(s)
+ * cache must be saved because the token stream may not have been informed
+ * to save the token (via <tt>mark</tt>) before the <tt>try</tt> block.
+ * Guessing is started by:
+ * <ol>
+ * <li>saving the lookahead cache.
+ * <li>marking the current position in the TokenBuffer.
+ * <li>increasing the guessing level.
+ * </ol>
+ *
+ * After guessing, the parser state is restored by:
+ * <ol>
+ * <li>restoring the lookahead cache.
+ * <li>rewinding the TokenBuffer.
+ * <li>decreasing the guessing level.
+ * </ol>
+ *
+ * @see antlr.Token
+ * @see antlr.TokenBuffer
+ * @see antlr.TokenStream
+ * @see antlr.LL1Parser
+ * @see antlr.LLkParser
+ */
+
+bool DEBUG_PARSER = false;
+
+/** Parser error-reporting function can be overridden in subclass */
+void Parser::reportError(const RecognitionException& ex)
+{
+       fprintf(stderr, "%s", (ex.toString() + "\n").c_str());
+}
+
+/** Parser error-reporting function can be overridden in subclass */
+void Parser::reportError(const ANTLR_USE_NAMESPACE(std)string& s)
+{
+       if ( getFilename()=="" )
+               fprintf(stderr, "%s", ("error: " + s + "\n").c_str());
+       else
+               fprintf(stderr, "%s", (getFilename() + ": error: " + s + "\n").c_str());
+}
+
+/** Parser warning-reporting function can be overridden in subclass */
+void Parser::reportWarning(const ANTLR_USE_NAMESPACE(std)string& s)
+{
+    if ( getFilename()=="" )
+        fprintf(stderr, "%s", ("warning: " + s + "\n").c_str());
+    else
+        fprintf(stderr, "%s", (getFilename() + ": warning: " + s + "\n").c_str());
+}
+
+/** Set or change the input token buffer */
+//     void setTokenBuffer(TokenBuffer<Token>* t);
+
+void Parser::traceIndent()
+{
+       for( int i = 0; i < traceDepth; i++ )
+               printf(" ");
+}
+
+void Parser::traceIn(const char* rname)
+{
+       traceDepth++;
+
+       for( int i = 0; i < traceDepth; i++ )
+               printf(" ");;
+
+       printf("%s",((ANTLR_USE_NAMESPACE(std)string)"> " + rname
+               + "; LA(1)==" + LT(1)->getText()
+               +       ((inputState->guessing>0)?" [guessing]":"")
+               + "\n").c_str());
+}
+
+void Parser::traceOut(const char* rname)
+{
+       for( int i = 0; i < traceDepth; i++ )
+        printf(" ");;
+
+       printf("%s",((ANTLR_USE_NAMESPACE(std)string)"< " + rname
+               + "; LA(1)==" + LT(1)->getText()
+               +       ((inputState->guessing>0)?" [guessing]":"")
+               + "\n").c_str());
+
+       traceDepth--;
+}
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
diff --git a/libsecurity_codesigning/antlr2/src/RecognitionException.cpp b/libsecurity_codesigning/antlr2/src/RecognitionException.cpp
new file mode 100644 (file)
index 0000000..c078c5c
--- /dev/null
@@ -0,0 +1,71 @@
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/src/RecognitionException.cpp#2 $
+ */
+
+#include "antlr/RecognitionException.hpp"
+#include "antlr/String.hpp"
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+RecognitionException::RecognitionException()
+: ANTLRException("parsing error")
+, line(-1)
+, column(-1)
+{
+}
+
+RecognitionException::RecognitionException(const ANTLR_USE_NAMESPACE(std)string& s)
+: ANTLRException(s)
+, line(-1)
+, column(-1)
+{
+}
+
+RecognitionException::RecognitionException(const ANTLR_USE_NAMESPACE(std)string& s,
+                                           const ANTLR_USE_NAMESPACE(std)string& fileName_,
+                                           int line_,int column_)
+: ANTLRException(s)
+, fileName(fileName_)
+, line(line_)
+, column(column_)
+{
+}
+
+ANTLR_USE_NAMESPACE(std)string RecognitionException::getFileLineColumnString() const
+{
+       ANTLR_USE_NAMESPACE(std)string fileLineColumnString;
+
+       if ( fileName.length() > 0 )
+               fileLineColumnString = fileName + ":";
+
+       if ( line != -1 )
+       {
+               if ( fileName.length() == 0 )
+                       fileLineColumnString = fileLineColumnString + "line ";
+
+               fileLineColumnString = fileLineColumnString + line;
+
+               if ( column != -1 )
+                       fileLineColumnString = fileLineColumnString + ":" + column;
+
+               fileLineColumnString = fileLineColumnString + ":";
+       }
+
+       fileLineColumnString = fileLineColumnString + " ";
+
+       return fileLineColumnString;
+}
+
+ANTLR_USE_NAMESPACE(std)string RecognitionException::toString() const
+{
+       return getFileLineColumnString()+getMessage();
+}
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
diff --git a/libsecurity_codesigning/antlr2/src/String.cpp b/libsecurity_codesigning/antlr2/src/String.cpp
new file mode 100644 (file)
index 0000000..2e9e9a9
--- /dev/null
@@ -0,0 +1,90 @@
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/src/String.cpp#2 $
+ */
+
+#include "antlr/String.hpp"
+
+#include <cctype>
+
+#ifdef HAS_NOT_CSTDIO_H
+#include <stdio.h>
+#else
+#include <cstdio>
+#endif
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+// wh: hack for Borland C++ 5.6
+#if __BORLANDC__
+  using std::sprintf;
+#endif
+
+
+// RK: should be using snprintf actually... (or stringstream)
+ANTLR_C_USING(sprintf)
+
+ANTLR_USE_NAMESPACE(std)string operator+( const ANTLR_USE_NAMESPACE(std)string& lhs, const int rhs )
+{
+       char tmp[100];
+       sprintf(tmp,"%d",rhs);
+       return lhs+tmp;
+}
+
+ANTLR_USE_NAMESPACE(std)string operator+( const ANTLR_USE_NAMESPACE(std)string& lhs, size_t rhs )
+{
+       char tmp[100];
+       sprintf(tmp,"%lu",(unsigned long)rhs);
+       return lhs+tmp;
+}
+
+/** Convert character to readable string
+ */
+ANTLR_USE_NAMESPACE(std)string charName(int ch)
+{
+       if (ch == EOF)
+               return "EOF";
+       else
+       {
+               ANTLR_USE_NAMESPACE(std)string s;
+
+               // when you think you've seen it all.. an isprint that crashes...
+               ch = ch & 0xFF;
+#ifdef ANTLR_CCTYPE_NEEDS_STD
+               if( ANTLR_USE_NAMESPACE(std)isprint( ch ) )
+#else
+               if( isprint( ch ) )
+#endif
+               {
+                       s.append("'");
+                       s += ch;
+                       s.append("'");
+//                     s += "'"+ch+"'";
+               }
+               else
+               {
+                       s += "0x";
+
+                       unsigned int t = ch >> 4;
+                       if( t < 10 )
+                               s += t | 0x30;
+                       else
+                               s += t + 0x37;
+                       t = ch & 0xF;
+                       if( t < 10 )
+                               s += t | 0x30;
+                       else
+                               s += t + 0x37;
+               }
+               return s;
+       }
+}
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
diff --git a/libsecurity_codesigning/antlr2/src/Token.cpp b/libsecurity_codesigning/antlr2/src/Token.cpp
new file mode 100644 (file)
index 0000000..8104813
--- /dev/null
@@ -0,0 +1,80 @@
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/src/Token.cpp#2 $
+ */
+
+#include "antlr/Token.hpp"
+#include "antlr/String.hpp"
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+int Token::getColumn() const
+{
+       return 0;
+}
+
+int Token::getLine() const
+{
+       return 0;
+}
+
+ANTLR_USE_NAMESPACE(std)string Token::getText() const
+{
+       return "<no text>";
+}
+
+int Token::getType() const
+{
+       return type;
+}
+
+void Token::setColumn(int)
+{
+}
+
+void Token::setLine(int)
+{
+}
+
+void Token::setText(const ANTLR_USE_NAMESPACE(std)string&)
+{
+}
+
+void Token::setType(int t)
+{
+       type = t;
+}
+
+void Token::setFilename(const ANTLR_USE_NAMESPACE(std)string&)
+{
+}
+
+ANTLR_USE_NAMESPACE(std)string emptyString("");
+
+const ANTLR_USE_NAMESPACE(std)string& Token::getFilename() const
+{
+       return emptyString;
+}
+
+ANTLR_USE_NAMESPACE(std)string Token::toString() const
+{
+       return "[\""+getText()+"\",<"+type+">]";
+}
+
+ANTLR_API RefToken nullToken;
+
+#ifndef NO_STATIC_CONSTS
+const int Token::MIN_USER_TYPE;
+const int Token::NULL_TREE_LOOKAHEAD;
+const int Token::INVALID_TYPE;
+const int Token::EOF_TYPE;
+const int Token::SKIP;
+#endif
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
diff --git a/libsecurity_codesigning/antlr2/src/TokenBuffer.cpp b/libsecurity_codesigning/antlr2/src/TokenBuffer.cpp
new file mode 100644 (file)
index 0000000..a57e54d
--- /dev/null
@@ -0,0 +1,96 @@
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/src/TokenBuffer.cpp#2 $
+ */
+
+#include "antlr/TokenBuffer.hpp"
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/**A Stream of Token objects fed to the parser from a TokenStream that can
+ * be rewound via mark()/rewind() methods.
+ * <p>
+ * A dynamic array is used to buffer up all the input tokens.  Normally,
+ * "k" tokens are stored in the buffer.  More tokens may be stored during
+ * guess mode (testing syntactic predicate), or when LT(i>k) is referenced.
+ * Consumption of tokens is deferred.  In other words, reading the next
+ * token is not done by conume(), but deferred until needed by LA or LT.
+ * <p>
+ *
+ * @see antlr.Token
+ * @see antlr.TokenStream
+ * @see antlr.TokenQueue
+ */
+
+/** Create a token buffer */
+TokenBuffer::TokenBuffer( TokenStream& inp )
+: input(inp)
+, nMarkers(0)
+, markerOffset(0)
+, numToConsume(0)
+{
+}
+
+TokenBuffer::~TokenBuffer( void )
+{
+}
+
+/** Ensure that the token buffer is sufficiently full */
+void TokenBuffer::fill(unsigned int amount)
+{
+       syncConsume();
+       // Fill the buffer sufficiently to hold needed tokens
+       while (queue.entries() < (amount + markerOffset))
+       {
+               // Append the next token
+               queue.append(input.nextToken());
+       }
+}
+
+/** Get a lookahead token value */
+int TokenBuffer::LA(unsigned int i)
+{
+       fill(i);
+       return queue.elementAt(markerOffset+i-1)->getType();
+}
+
+/** Get a lookahead token */
+RefToken TokenBuffer::LT(unsigned int i)
+{
+       fill(i);
+       return queue.elementAt(markerOffset+i-1);
+}
+
+/** Return an integer marker that can be used to rewind the buffer to
+ * its current state.
+ */
+unsigned int TokenBuffer::mark()
+{
+       syncConsume();
+       nMarkers++;
+       return markerOffset;
+}
+
+/**Rewind the token buffer to a marker.
+ * @param mark Marker returned previously from mark()
+ */
+void TokenBuffer::rewind(unsigned int mark)
+{
+       syncConsume();
+       markerOffset=mark;
+       nMarkers--;
+}
+
+/// Get number of non-consumed tokens
+unsigned int TokenBuffer::entries() const
+{
+       return (unsigned int)queue.entries() - markerOffset;
+}
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+       }
+#endif
diff --git a/libsecurity_codesigning/antlr2/src/TokenRefCount.cpp b/libsecurity_codesigning/antlr2/src/TokenRefCount.cpp
new file mode 100644 (file)
index 0000000..0afb0f8
--- /dev/null
@@ -0,0 +1,41 @@
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id:$
+ */
+#include "antlr/TokenRefCount.hpp"
+#include "antlr/Token.hpp"
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+TokenRef::TokenRef(Token* p)
+: ptr(p), count(1)
+{
+       if (p && !p->ref)
+               p->ref = this;
+}
+
+TokenRef::~TokenRef()
+{
+       delete ptr;
+}
+
+TokenRef* TokenRef::getRef(const Token* p)
+{
+       if (p) {
+               Token* pp = const_cast<Token*>(p);
+               if (pp->ref)
+                       return pp->ref->increment();
+               else
+                       return new TokenRef(pp);
+       } else
+               return 0;
+}
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
diff --git a/libsecurity_codesigning/antlr2/src/TokenStreamBasicFilter.cpp b/libsecurity_codesigning/antlr2/src/TokenStreamBasicFilter.cpp
new file mode 100644 (file)
index 0000000..af30689
--- /dev/null
@@ -0,0 +1,44 @@
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/src/TokenStreamBasicFilter.cpp#2 $
+ */
+#include "antlr/TokenStreamBasicFilter.hpp"
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/** This object is a TokenStream that passes through all
+ *  tokens except for those that you tell it to discard.
+ *  There is no buffering of the tokens.
+ */
+TokenStreamBasicFilter::TokenStreamBasicFilter(TokenStream& input_)
+: input(&input_)
+{
+}
+
+void TokenStreamBasicFilter::discard(int ttype)
+{
+       discardMask.add(ttype);
+}
+
+void TokenStreamBasicFilter::discard(const BitSet& mask)
+{
+       discardMask = mask;
+}
+
+RefToken TokenStreamBasicFilter::nextToken()
+{
+       RefToken tok = input->nextToken();
+       while ( tok && discardMask.member(tok->getType()) ) {
+               tok = input->nextToken();
+       }
+       return tok;
+}
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
diff --git a/libsecurity_codesigning/antlr2/src/TokenStreamHiddenTokenFilter.cpp b/libsecurity_codesigning/antlr2/src/TokenStreamHiddenTokenFilter.cpp
new file mode 100644 (file)
index 0000000..2c3b69d
--- /dev/null
@@ -0,0 +1,156 @@
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/src/TokenStreamHiddenTokenFilter.cpp#2 $
+ */
+#include "antlr/TokenStreamHiddenTokenFilter.hpp"
+#include "antlr/CommonHiddenStreamToken.hpp"
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/**This object filters a token stream coming from a lexer
+ * or another TokenStream so that only certain token channels
+ * get transmitted to the parser.
+ *
+ * Any of the channels can be filtered off as "hidden" channels whose
+ * tokens can be accessed from the parser.
+ */
+
+TokenStreamHiddenTokenFilter::TokenStreamHiddenTokenFilter(TokenStream& input)
+: TokenStreamBasicFilter(input)
+{
+}
+
+void TokenStreamHiddenTokenFilter::consume()
+{
+       nextMonitoredToken = input->nextToken();
+}
+
+void TokenStreamHiddenTokenFilter::consumeFirst()
+{
+       consume();
+
+       // Handle situation where hidden or discarded tokens
+       // appear first in input stream
+       RefToken p;
+       // while hidden or discarded scarf tokens
+       while ( hideMask.member(LA(1)->getType()) || discardMask.member(LA(1)->getType()) ) {
+               if ( hideMask.member(LA(1)->getType()) ) {
+                       if ( !p ) {
+                               p = LA(1);
+                       }
+                       else {
+                               static_cast<CommonHiddenStreamToken*>(p.get())->setHiddenAfter(LA(1));
+                               static_cast<CommonHiddenStreamToken*>(LA(1).get())->setHiddenBefore(p); // double-link
+                               p = LA(1);
+                       }
+                       lastHiddenToken = p;
+                       if (!firstHidden)
+                               firstHidden = p; // record hidden token if first
+               }
+               consume();
+       }
+}
+
+BitSet TokenStreamHiddenTokenFilter::getDiscardMask() const
+{
+       return discardMask;
+}
+
+/** Return a ptr to the hidden token appearing immediately after
+ *  token t in the input stream.
+ */
+RefToken TokenStreamHiddenTokenFilter::getHiddenAfter(RefToken t)
+{
+       return static_cast<CommonHiddenStreamToken*>(t.get())->getHiddenAfter();
+}
+
+/** Return a ptr to the hidden token appearing immediately before
+ *  token t in the input stream.
+ */
+RefToken TokenStreamHiddenTokenFilter::getHiddenBefore(RefToken t)
+{
+       return static_cast<CommonHiddenStreamToken*>(t.get())->getHiddenBefore();
+}
+
+BitSet TokenStreamHiddenTokenFilter::getHideMask() const
+{
+       return hideMask;
+}
+
+/** Return the first hidden token if one appears
+ *  before any monitored token.
+ */
+RefToken TokenStreamHiddenTokenFilter::getInitialHiddenToken()
+{
+       return firstHidden;
+}
+
+void TokenStreamHiddenTokenFilter::hide(int m)
+{
+       hideMask.add(m);
+}
+
+void TokenStreamHiddenTokenFilter::hide(const BitSet& mask)
+{
+       hideMask = mask;
+}
+
+RefToken TokenStreamHiddenTokenFilter::LA(int)
+{
+       return nextMonitoredToken;
+}
+
+/** Return the next monitored token.
+*  Test the token following the monitored token.
+*  If following is another monitored token, save it
+*  for the next invocation of nextToken (like a single
+*  lookahead token) and return it then.
+*  If following is unmonitored, nondiscarded (hidden)
+*  channel token, add it to the monitored token.
+*
+*  Note: EOF must be a monitored Token.
+*/
+RefToken TokenStreamHiddenTokenFilter::nextToken()
+{
+       // handle an initial condition; don't want to get lookahead
+       // token of this splitter until first call to nextToken
+       if ( !LA(1) ) {
+               consumeFirst();
+       }
+
+       // we always consume hidden tokens after monitored, thus,
+       // upon entry LA(1) is a monitored token.
+       RefToken monitored = LA(1);
+       // point to hidden tokens found during last invocation
+       static_cast<CommonHiddenStreamToken*>(monitored.get())->setHiddenBefore(lastHiddenToken);
+       lastHiddenToken = nullToken;
+
+       // Look for hidden tokens, hook them into list emanating
+       // from the monitored tokens.
+       consume();
+       RefToken p = monitored;
+       // while hidden or discarded scarf tokens
+       while ( hideMask.member(LA(1)->getType()) || discardMask.member(LA(1)->getType()) ) {
+               if ( hideMask.member(LA(1)->getType()) ) {
+                       // attach the hidden token to the monitored in a chain
+                       // link forwards
+                       static_cast<CommonHiddenStreamToken*>(p.get())->setHiddenAfter(LA(1));
+                       // link backwards
+                       if (p != monitored) { //hidden cannot point to monitored tokens
+                               static_cast<CommonHiddenStreamToken*>(LA(1).get())->setHiddenBefore(p);
+                       }
+                       p = lastHiddenToken = LA(1);
+               }
+               consume();
+       }
+       return monitored;
+}
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
diff --git a/libsecurity_codesigning/antlr2/src/TokenStreamRewriteEngine.cpp b/libsecurity_codesigning/antlr2/src/TokenStreamRewriteEngine.cpp
new file mode 100644 (file)
index 0000000..4279355
--- /dev/null
@@ -0,0 +1,214 @@
+#include <antlr/config.hpp>
+
+#include <string>
+#include <list>
+#include <vector>
+#include <map>
+#include <utility>
+//#include <iostream>
+#include <iterator>
+#include <sstream>
+#include <cassert>
+
+#include <antlr/TokenStream.hpp>
+#include <antlr/TokenWithIndex.hpp>
+#include <antlr/BitSet.hpp>
+#include <antlr/TokenStreamRewriteEngine.hpp>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+#ifndef NO_STATIC_CONSTS
+const size_t TokenStreamRewriteEngine::MIN_TOKEN_INDEX = 0;
+const int TokenStreamRewriteEngine::PROGRAM_INIT_SIZE = 100;
+#endif
+
+const char* TokenStreamRewriteEngine::DEFAULT_PROGRAM_NAME = "default";
+
+namespace {
+
+       struct compareOperationIndex {
+               typedef TokenStreamRewriteEngine::RewriteOperation RewriteOperation;
+               bool operator() ( const RewriteOperation* a, const RewriteOperation* b ) const
+               {
+                       return a->getIndex() < b->getIndex();
+               }
+       };
+       struct dumpTokenWithIndex {
+               dumpTokenWithIndex( ANTLR_USE_NAMESPACE(std)ostream& o ) : out(o) {}
+               void operator() ( const RefTokenWithIndex& t ) {
+                       out << "[txt='" << t->getText() << "' tp=" << t->getType() << " idx=" << t->getIndex() << "]\n";
+               }
+               ANTLR_USE_NAMESPACE(std)ostream& out;
+       };
+}
+
+TokenStreamRewriteEngine::TokenStreamRewriteEngine(TokenStream& upstream)
+: stream(upstream)
+, index(MIN_TOKEN_INDEX)
+, tokens()
+, programs()
+, discardMask()
+{
+}
+
+TokenStreamRewriteEngine::TokenStreamRewriteEngine(TokenStream& upstream, size_t initialSize )
+: stream(upstream)
+, index(MIN_TOKEN_INDEX)
+, tokens(initialSize)
+, programs()
+, discardMask()
+{
+}
+
+RefToken TokenStreamRewriteEngine::nextToken( void )
+{
+       RefTokenWithIndex t;
+       // suck tokens until end of stream or we find a non-discarded token
+       do {
+               t = RefTokenWithIndex(stream.nextToken());
+               if ( t )
+               {
+                       t->setIndex(index);  // what is t's index in list?
+                       if ( t->getType() != Token::EOF_TYPE ) {
+                               tokens.push_back(t);  // track all tokens except EOF
+                       }
+                       index++;                        // move to next position
+               }
+       } while ( t && discardMask.member(t->getType()) );
+       return RefToken(t);
+}
+
+void TokenStreamRewriteEngine::rollback( const std::string& programName,
+                                                                                                         size_t instructionIndex )
+{
+       program_map::iterator rewrite = programs.find(programName);
+       if( rewrite != programs.end() )
+       {
+               operation_list& prog = rewrite->second;
+               operation_list::iterator
+                       j = prog.begin(),
+                       end = prog.end();
+
+               std::advance(j,instructionIndex);
+               if( j != end )
+                       prog.erase(j, end);
+       }
+}
+
+void TokenStreamRewriteEngine::originalToStream( std::ostream& out,
+                                                                                                                                size_t start,
+                                                                                                                                size_t end ) const
+{
+       token_list::const_iterator s = tokens.begin();
+       std::advance( s, start );
+       token_list::const_iterator e = s;
+       std::advance( e, end-start );
+       std::for_each( s, e, tokenToStream(out) );
+}
+
+void TokenStreamRewriteEngine::toStream( std::ostream& out,
+                                                                                                         const std::string& programName,
+                                                                                                         size_t firstToken,
+                                                                                                         size_t lastToken ) const
+{
+       if( tokens.size() == 0 )
+               return;
+
+       program_map::const_iterator rewriter = programs.find(programName);
+
+       if ( rewriter == programs.end() )
+               return;
+
+       // get the prog and some iterators in it...
+       const operation_list& prog = rewriter->second;
+       operation_list::const_iterator
+               rewriteOpIndex = prog.begin(),
+               rewriteOpEnd = prog.end();
+
+       size_t tokenCursor = firstToken;
+       // make sure we don't run out of the tokens we have...
+       if( lastToken > (tokens.size() - 1) )
+               lastToken = tokens.size() - 1;
+
+               while ( tokenCursor <= lastToken )
+               {
+//                     std::cout << "tokenCursor = " << tokenCursor << " first prog index = " << (*rewriteOpIndex)->getIndex() << std::endl;
+
+                       if( rewriteOpIndex != rewriteOpEnd )
+                       {
+                               size_t up_to_here = std::min(lastToken,(*rewriteOpIndex)->getIndex());
+                               while( tokenCursor < up_to_here )
+                                       out << tokens[tokenCursor++]->getText();
+                       }
+                       while ( rewriteOpIndex != rewriteOpEnd &&
+                                         tokenCursor == (*rewriteOpIndex)->getIndex() &&
+                                         tokenCursor <= lastToken )
+                       {
+                               tokenCursor = (*rewriteOpIndex)->execute(out);
+                               ++rewriteOpIndex;
+                       }
+                       if( tokenCursor <= lastToken )
+                               out << tokens[tokenCursor++]->getText();
+               }
+       // std::cout << "Handling tail operations # left = " << std::distance(rewriteOpIndex,rewriteOpEnd) << std::endl;
+       // now see if there are operations (append) beyond last token index
+       std::for_each( rewriteOpIndex, rewriteOpEnd, executeOperation(out) );
+       rewriteOpIndex = rewriteOpEnd;
+}
+
+void TokenStreamRewriteEngine::toDebugStream( std::ostream& out,
+                                                                                                                        size_t start,
+                                                                                                                        size_t end ) const
+{
+       token_list::const_iterator s = tokens.begin();
+       std::advance( s, start );
+       token_list::const_iterator e = s;
+       std::advance( e, end-start );
+       std::for_each( s, e, dumpTokenWithIndex(out) );
+}
+
+void TokenStreamRewriteEngine::addToSortedRewriteList( const std::string& programName,
+                                                                                                                                                RewriteOperation* op )
+{
+       program_map::iterator rewrites = programs.find(programName);
+       // check if we got the program already..
+       if ( rewrites == programs.end() )
+       {
+               // no prog make a new one...
+               operation_list ops;
+               ops.push_back(op);
+               programs.insert(std::make_pair(programName,ops));
+               return;
+       }
+       operation_list& prog = rewrites->second;
+
+       if( prog.empty() )
+       {
+               prog.push_back(op);
+               return;
+       }
+
+       operation_list::iterator i, end = prog.end();
+       i = end;
+       --i;
+       // if at or beyond last op's index, just append
+       if ( op->getIndex() >= (*i)->getIndex() ) {
+               prog.push_back(op); // append to list of operations
+               return;
+       }
+       i = prog.begin();
+
+       if( i != end )
+       {
+               operation_list::iterator pos = std::upper_bound( i, end, op, compareOperationIndex() );
+               prog.insert(pos,op);
+       }
+       else
+               prog.push_back(op);
+}
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
diff --git a/libsecurity_codesigning/antlr2/src/TokenStreamSelector.cpp b/libsecurity_codesigning/antlr2/src/TokenStreamSelector.cpp
new file mode 100644 (file)
index 0000000..254a9a9
--- /dev/null
@@ -0,0 +1,107 @@
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/src/TokenStreamSelector.cpp#2 $
+ */
+#include "antlr/TokenStreamSelector.hpp"
+#include "antlr/TokenStreamRetryException.hpp"
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/** A token stream MUX (multiplexor) knows about n token streams
+ *  and can multiplex them onto the same channel for use by token
+ *  stream consumer like a parser.  This is a way to have multiple
+ *  lexers break up the same input stream for a single parser.
+ *     Or, you can have multiple instances of the same lexer handle
+ *  multiple input streams; this works great for includes.
+ */
+
+TokenStreamSelector::TokenStreamSelector()
+: input(0)
+{
+}
+
+TokenStreamSelector::~TokenStreamSelector()
+{
+}
+
+void TokenStreamSelector::addInputStream(TokenStream* stream, const ANTLR_USE_NAMESPACE(std)string& key)
+{
+       inputStreamNames[key] = stream;
+}
+
+TokenStream* TokenStreamSelector::getCurrentStream() const
+{
+       return input;
+}
+
+TokenStream* TokenStreamSelector::getStream(const ANTLR_USE_NAMESPACE(std)string& sname) const
+{
+       inputStreamNames_coll::const_iterator i = inputStreamNames.find(sname);
+       if (i == inputStreamNames.end()) {
+               throw ANTLR_USE_NAMESPACE(std)string("TokenStream ")+sname+" not found";
+       }
+       return (*i).second;
+}
+
+RefToken TokenStreamSelector::nextToken()
+{
+       // keep looking for a token until you don't
+       // get a retry exception
+       for (;;) {
+               try {
+                       return input->nextToken();
+               }
+               catch (TokenStreamRetryException&) {
+                       // just retry "forever"
+               }
+       }
+}
+
+TokenStream* TokenStreamSelector::pop()
+{
+       TokenStream* stream = streamStack.top();
+       streamStack.pop();
+       select(stream);
+       return stream;
+}
+
+void TokenStreamSelector::push(TokenStream* stream)
+{
+       streamStack.push(input);
+       select(stream);
+}
+
+void TokenStreamSelector::push(const ANTLR_USE_NAMESPACE(std)string& sname)
+{
+       streamStack.push(input);
+       select(sname);
+}
+
+void TokenStreamSelector::retry()
+{
+       throw TokenStreamRetryException();
+}
+
+/** Set the stream without pushing old stream */
+void TokenStreamSelector::select(TokenStream* stream)
+{
+       input = stream;
+}
+
+void TokenStreamSelector::select(const ANTLR_USE_NAMESPACE(std)string& sname)
+{
+       inputStreamNames_coll::const_iterator i = inputStreamNames.find(sname);
+       if (i == inputStreamNames.end()) {
+               throw ANTLR_USE_NAMESPACE(std)string("TokenStream ")+sname+" not found";
+       }
+       input = (*i).second;
+}
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
diff --git a/libsecurity_codesigning/antlr2/src/TreeParser.cpp b/libsecurity_codesigning/antlr2/src/TreeParser.cpp
new file mode 100644 (file)
index 0000000..aec7865
--- /dev/null
@@ -0,0 +1,73 @@
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/src/TreeParser.cpp#2 $
+ */
+
+#include "antlr/TreeParser.hpp"
+#include "antlr/ASTNULLType.hpp"
+#include <stdio.h>
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+/** The AST Null object; the parsing cursor is set to this when
+ *  it is found to be null.  This way, we can test the
+ *  token type of a node without having to have tests for null
+ *  everywhere.
+ */
+RefAST TreeParser::ASTNULL(new ASTNULLType);
+
+/** Parser error-reporting function can be overridden in subclass */
+void TreeParser::reportError(const RecognitionException& ex)
+{
+       fprintf(stderr, "%s", (ex.toString() + "\n").c_str());
+}
+
+/** Parser error-reporting function can be overridden in subclass */
+void TreeParser::reportError(const ANTLR_USE_NAMESPACE(std)string& s)
+{
+       fprintf(stderr, "%s", ("error: " + s + "\n").c_str());
+}
+
+/** Parser warning-reporting function can be overridden in subclass */
+void TreeParser::reportWarning(const ANTLR_USE_NAMESPACE(std)string& s)
+{
+       fprintf(stderr, "%s", ("warning: " + s + "\n").c_str());
+}
+
+/** Procedure to write out an indent for traceIn and traceOut */
+void TreeParser::traceIndent()
+{
+       for( int i = 0; i < traceDepth; i++ )
+               printf(" ");
+}
+
+void TreeParser::traceIn(const char* rname, RefAST t)
+{
+       traceDepth++;
+       traceIndent();
+
+       printf("%s",((ANTLR_USE_NAMESPACE(std)string)"> " + rname
+                       + "(" + (t ? t->toString().c_str() : "null") + ")"
+                       + ((inputState->guessing>0)?" [guessing]":"")
+                       + "\n").c_str());
+}
+
+void TreeParser::traceOut(const char* rname, RefAST t)
+{
+       traceIndent();
+
+       printf("%s",((ANTLR_USE_NAMESPACE(std)string)"< " + rname
+                       + "(" + (t ? t->toString().c_str() : "null") + ")"
+                       + ((inputState->guessing>0)?" [guessing]":"")
+                       + "\n").c_str());
+
+       traceDepth--;
+}
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
diff --git a/libsecurity_codesigning/antlr2/src/dll.cpp b/libsecurity_codesigning/antlr2/src/dll.cpp
new file mode 100644 (file)
index 0000000..020a9d8
--- /dev/null
@@ -0,0 +1,138 @@
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id:$
+ */
+
+/*
+ * DLL stub for MSVC++. Based upon versions of Stephen Naughton and Michael
+ * T. Richter
+ */
+
+// RK: Uncommented by instruction of Alexander Lenski
+//#if _MSC_VER > 1000
+//# pragma once
+//#endif // _MSC_VER > 1000
+
+// Exclude rarely-used stuff from Windows headers
+#define WIN32_LEAN_AND_MEAN
+
+#include <windows.h>
+
+#if defined( _MSC_VER ) && ( _MSC_VER < 1300 )
+# error "DLL Build not supported on old MSVC's"
+// Ok it seems to be possible with STLPort in stead of the vanilla MSVC STL
+// implementation. This needs some work though. (and don't try it if you're
+// not that familiar with compilers/building C++ DLL's in windows)
+#endif
+
+#include <vector>
+#include "antlr/config.hpp"
+#include "antlr/Token.hpp"
+#include "antlr/CircularQueue.hpp"
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+// Take care of necessary implicit instantiations of templates from STL
+
+// This should take care of MSVC 7.0
+#if defined( _MSC_VER ) && ( _MSC_VER == 1300 )
+
+// these come from AST.hpp
+template class ANTLR_API ASTRefCount< AST >;
+template class ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< RefAST >;
+template class ANTLR_API ANTLR_USE_NAMESPACE(std)vector< RefAST >;
+//template ANTLR_API int operator<( ASTRefCount< AST >, ASTRefCount< AST > );
+
+// ASTFactory.hpp
+template class  ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< factory_descriptor_* >;
+template class  ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const char*, factory_type_ > >;
+template struct ANTLR_API ANTLR_USE_NAMESPACE(std)pair< const char*, factory_type_ >;
+template class  ANTLR_API ANTLR_USE_NAMESPACE(std)_Vector_val< factory_descriptor_*, ANTLR_USE_NAMESPACE(std)allocator< factory_descriptor_* > >;
+template class  ANTLR_API ANTLR_USE_NAMESPACE(std)vector< factory_descriptor_* >;
+
+// BitSet.hpp
+template class ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< bool >;
+template class ANTLR_API ANTLR_USE_NAMESPACE(std)_Vector_val< bool, ANTLR_USE_NAMESPACE(std)allocator< bool > >;
+template class ANTLR_API ANTLR_USE_NAMESPACE(std)vector< bool >;
+
+// CharScanner.hpp
+template class  ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< ANTLR_USE_NAMESPACE(std)string, int > >;
+template class  ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, int > >;
+template class  ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)_Tree_nod< ANTLR_USE_NAMESPACE(std)_Tmap_traits< ANTLR_USE_NAMESPACE(std)string, int, CharScannerLiteralsLess, ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, int > >, false > >::_Node >;
+template class  ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)_Tree_ptr< ANTLR_USE_NAMESPACE(std)_Tmap_traits< ANTLR_USE_NAMESPACE(std)string, int, CharScannerLiteralsLess, ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, int > >, false > >::_Nodeptr >;
+template struct ANTLR_API ANTLR_USE_NAMESPACE(std)pair< ANTLR_USE_NAMESPACE(std)string, int >;
+template class  ANTLR_API ANTLR_USE_NAMESPACE(std)_Tmap_traits< ANTLR_USE_NAMESPACE(std)string, int, CharScannerLiteralsLess, ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, int > >,false >;
+template class  ANTLR_API ANTLR_USE_NAMESPACE(std)_Tree_nod< ANTLR_USE_NAMESPACE(std)_Tmap_traits< ANTLR_USE_NAMESPACE(std)string, int, CharScannerLiteralsLess, ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, int > >,false > >;
+template class  ANTLR_API ANTLR_USE_NAMESPACE(std)_Tree_ptr< ANTLR_USE_NAMESPACE(std)_Tmap_traits< ANTLR_USE_NAMESPACE(std)string, int, CharScannerLiteralsLess, ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, int > >,false > >;
+template class  ANTLR_API ANTLR_USE_NAMESPACE(std)_Tree_val< ANTLR_USE_NAMESPACE(std)_Tmap_traits< ANTLR_USE_NAMESPACE(std)string, int, CharScannerLiteralsLess, ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, int > >,false > >;
+template class  ANTLR_API ANTLR_USE_NAMESPACE(std)_Tree< ANTLR_USE_NAMESPACE(std)_Tmap_traits< ANTLR_USE_NAMESPACE(std)string, int, CharScannerLiteralsLess, ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, int > >,false > >;
+template class  ANTLR_API ANTLR_USE_NAMESPACE(std)map< ANTLR_USE_NAMESPACE(std)string, int, CharScannerLiteralsLess >;
+
+// CircularQueue.hpp
+// RK: it might well be that a load of these ints need to be unsigned ints
+//  (made some more stuff unsigned)
+template class ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< int >;
+template class ANTLR_API ANTLR_USE_NAMESPACE(std)_Vector_val< int, ANTLR_USE_NAMESPACE(std)allocator< int > >;
+template class ANTLR_API ANTLR_USE_NAMESPACE(std)vector< int >;
+template class ANTLR_API ANTLR_USE_NAMESPACE(std)vector< int, ANTLR_USE_NAMESPACE(std)allocator< int > >;
+//  template ANTLR_API inline int CircularQueue< int >::entries() const;
+
+template class ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< RefToken >;
+template class ANTLR_API ANTLR_USE_NAMESPACE(std)_Vector_val< RefToken, ANTLR_USE_NAMESPACE(std)allocator< RefToken > >;
+template class ANTLR_API ANTLR_USE_NAMESPACE(std)vector< RefToken >;
+template class ANTLR_API ANTLR_USE_NAMESPACE(std)vector< RefToken, ANTLR_USE_NAMESPACE(std)allocator< RefToken > >;
+//  template ANTLR_API inline int CircularQueue< RefToken >::entries() const;
+
+// CommonAST.hpp
+template class ANTLR_API ASTRefCount< CommonAST >;
+
+// CommonASTWithHiddenTokenTypes.hpp
+template class ANTLR_API ASTRefCount< CommonASTWithHiddenTokens >;
+
+// LexerSharedInputState.hpp
+template class ANTLR_API RefCount< LexerInputState >;
+
+// ParserSharedInputState.hpp
+template class ANTLR_API RefCount< ParserInputState >;
+
+// TokenStreamSelector.hpp
+template class  ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< ANTLR_USE_NAMESPACE(std)string, TokenStream* > >;
+template class  ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, TokenStream* > >;
+template class  ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)_Tree_nod< ANTLR_USE_NAMESPACE(std)_Tmap_traits< ANTLR_USE_NAMESPACE(std)string, TokenStream*, ANTLR_USE_NAMESPACE(std)less< ANTLR_USE_NAMESPACE(std)string >, ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, TokenStream* > >, false > >::_Node >;
+template class  ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)_Tree_ptr< ANTLR_USE_NAMESPACE(std)_Tmap_traits< ANTLR_USE_NAMESPACE(std)string, TokenStream*, ANTLR_USE_NAMESPACE(std)less< ANTLR_USE_NAMESPACE(std)string >, ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, TokenStream* > >, false > >::_Nodeptr >;
+template struct ANTLR_API ANTLR_USE_NAMESPACE(std)pair< ANTLR_USE_NAMESPACE(std)string, TokenStream* >;
+template class  ANTLR_API ANTLR_USE_NAMESPACE(std)_Tmap_traits< ANTLR_USE_NAMESPACE(std)string, TokenStream*, ANTLR_USE_NAMESPACE(std)less< ANTLR_USE_NAMESPACE(std)string >, ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, TokenStream* > >,false >;
+template class  ANTLR_API ANTLR_USE_NAMESPACE(std)_Tree_nod< ANTLR_USE_NAMESPACE(std)_Tmap_traits< ANTLR_USE_NAMESPACE(std)string, TokenStream*, ANTLR_USE_NAMESPACE(std)less< ANTLR_USE_NAMESPACE(std)string >, ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, TokenStream* > >,false > >;
+template class  ANTLR_API ANTLR_USE_NAMESPACE(std)_Tree_ptr< ANTLR_USE_NAMESPACE(std)_Tmap_traits< ANTLR_USE_NAMESPACE(std)string, TokenStream*, ANTLR_USE_NAMESPACE(std)less< ANTLR_USE_NAMESPACE(std)string >, ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, TokenStream* > >,false > >;
+template class  ANTLR_API ANTLR_USE_NAMESPACE(std)_Tree_val< ANTLR_USE_NAMESPACE(std)_Tmap_traits< ANTLR_USE_NAMESPACE(std)string, TokenStream*, ANTLR_USE_NAMESPACE(std)less< ANTLR_USE_NAMESPACE(std)string >, ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, TokenStream* > >,false > >;
+template class  ANTLR_API ANTLR_USE_NAMESPACE(std)_Tree< ANTLR_USE_NAMESPACE(std)_Tmap_traits< ANTLR_USE_NAMESPACE(std)string, TokenStream*, ANTLR_USE_NAMESPACE(std)less< ANTLR_USE_NAMESPACE(std)string >, ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, TokenStream* > >,false > >;
+template class  ANTLR_API ANTLR_USE_NAMESPACE(std)map< ANTLR_USE_NAMESPACE(std)string, TokenStream* >;
+
+template class  ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< TokenStream* >;
+template class  ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)_Deque_map< TokenStream* , ANTLR_USE_NAMESPACE(std)allocator< TokenStream* > >::_Tptr >;
+template class  ANTLR_API ANTLR_USE_NAMESPACE(std)_Deque_map< TokenStream*, ANTLR_USE_NAMESPACE(std)allocator< TokenStream* > >;
+template class  ANTLR_API ANTLR_USE_NAMESPACE(std)_Deque_val< TokenStream*, ANTLR_USE_NAMESPACE(std)allocator< TokenStream* > >;
+template class  ANTLR_API ANTLR_USE_NAMESPACE(std)deque< TokenStream*, ANTLR_USE_NAMESPACE(std)allocator< TokenStream* > >;
+template class  ANTLR_API ANTLR_USE_NAMESPACE(std)stack< TokenStream*, ANTLR_USE_NAMESPACE(std)deque<TokenStream*> >;
+
+#elif  defined( _MSC_VER ) && ( _MSC_VER == 1310 )
+// Instantiations for MSVC 7.1
+template class ANTLR_API CircularQueue< int >;
+template class ANTLR_API CircularQueue< RefToken >;
+
+// #else future msvc's
+
+#endif
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif
+
+BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved )
+{
+       return TRUE;
+}
index 52616881b0c9966c7e6a23e3a949724f38c06c53..47a1aceae0b073a028fac3a70c257be16677680a 100755 (executable)
@@ -141,7 +141,8 @@ for line in file:
                        path=path,
                        type=type,
                        status=status,
                        path=path,
                        type=type,
                        status=status,
-                       cdhash=cdhash
+                       cdhash=cdhash,
+                       version=2
                )
        elif cmd == "SIGNATURE":
                (type, sigpath, path) = args.split(";", 2)
                )
        elif cmd == "SIGNATURE":
                (type, sigpath, path) = args.split(";", 2)
index 8bf49fa5696d089713bca8ffabdfeae58e17643c..4dc6da83b73e09e273e2991073a8a4f0481f3c19 100755 (executable)
@@ -5,7 +5,7 @@
 main=$(/usr/sbin/spctl --status)
 gk=$(/usr/sbin/spctl --test-devid-status)
 /usr/bin/syslog -s -k \
 main=$(/usr/sbin/spctl --status)
 gk=$(/usr/sbin/spctl --test-devid-status)
 /usr/bin/syslog -s -k \
-       com.apple.message.domain com.apple.security.assessment.current_state \
+       com.apple.message.domain com.apple.security.assessment.state \
        com.apple.message.signature "$main" \
        com.apple.message.signature2 "$gk" \
        Message "Gatekeeper state $main/$gk"
        com.apple.message.signature "$main" \
        com.apple.message.signature2 "$gk" \
        Message "Gatekeeper state $main/$gk"
index 3a3d17e838e1a5349e9a89991c7f9f21e8d7b8e7..23cd134a210fde052b26746ad3878fcb77c7df94 100644 (file)
@@ -93,6 +93,12 @@ enum {
        errSecCSFileHardQuarantined =           -67026, /* File created by an AppSandbox, exec/open not allowed */
        errSecCSOutdated =                                      -67025, /* presented data is out of date */
        errSecCSDbCorrupt =                                     -67024, /* a system database or file is corrupt */
        errSecCSFileHardQuarantined =           -67026, /* File created by an AppSandbox, exec/open not allowed */
        errSecCSOutdated =                                      -67025, /* presented data is out of date */
        errSecCSDbCorrupt =                                     -67024, /* a system database or file is corrupt */
+       errSecCSResourceDirectoryFailed =       -67023, /* invalid resource directory (directory or signature have been modified) */
+       errSecCSUnsignedNestedCode =            -67022, /* nested code is unsigned */
+       errSecCSBadNestedCode =                         -67021, /* nested code is modified or invalid */
+       errSecCSBadCallbackValue =                      -67020, /* monitor callback returned invalid value */
+       errSecCSHelperFailed =                          -67019, /* the codesign_allocate helper tool cannot be found or used */
+       errSecCSVetoed =                                        -67018,
 };
 
 
 };
 
 
@@ -223,6 +229,8 @@ enum {
        kSecCodeSignatureForceHard = 0x0100,    /* always set HARD mode on launch */
        kSecCodeSignatureForceKill = 0x0200,    /* always set KILL mode on launch */
        kSecCodeSignatureForceExpiration = 0x0400, /* force certificate expiration checks */
        kSecCodeSignatureForceHard = 0x0100,    /* always set HARD mode on launch */
        kSecCodeSignatureForceKill = 0x0200,    /* always set KILL mode on launch */
        kSecCodeSignatureForceExpiration = 0x0400, /* force certificate expiration checks */
+       kSecCodeSignatureRestrict = 0x0800, /* restrict dyld loading */
+       kSecCodeSignatureEnforcement = 0x1000, /* enforce code signing */
 };
 
 
 };
 
 
index f87f4541d9d746120b81f9284133a18f44d83d60..81106fbe80ef4e22cf9f1bb88ed6859cd0c3719a 100644 (file)
@@ -104,13 +104,17 @@ enum {
        kSecCodeSignatureNoHash                                                 =  0,   /* null value */
        kSecCodeSignatureHashSHA1                                               =  1,   /* SHA-1 */
        kSecCodeSignatureHashSHA256                                             =  2,   /* SHA-256 */
        kSecCodeSignatureNoHash                                                 =  0,   /* null value */
        kSecCodeSignatureHashSHA1                                               =  1,   /* SHA-1 */
        kSecCodeSignatureHashSHA256                                             =  2,   /* SHA-256 */
-       kSecCodeSignatureHashPrestandardSkein160x256    = 32,   /* Skein, 160 bits, 256 bit pool */
-       kSecCodeSignatureHashPrestandardSkein256x512    = 33,   /* Skein, 256 bits, 512 bit pool */
        
        kSecCodeSignatureDefaultDigestAlgorithm = kSecCodeSignatureHashSHA1
 };
 
 
        
        kSecCodeSignatureDefaultDigestAlgorithm = kSecCodeSignatureHashSHA1
 };
 
 
+/*!
+       A callback block type for monitoring certain code signing operations
+ */
+typedef CFTypeRef (^SecCodeCallback)(SecStaticCodeRef code, CFStringRef stage, CFDictionaryRef info);
+
+
 #ifdef __cplusplus
 }
 #endif
 #ifdef __cplusplus
 }
 #endif
index ab5072aec05ac5726d264e54f4de488ae3d2b2c7..ec5da804e7a6b1920cda0d9a494aff27fda35a4f 100644 (file)
@@ -261,7 +261,7 @@ SecCode *SecCode::autoLocateGuest(CFDictionaryRef attributes, SecCSFlags flags)
        if (!cfscan(attributes, "{%O=%d}", kSecGuestAttributePid, &pid))
                CSError::throwMe(errSecCSUnsupportedGuestAttributes, kSecCFErrorGuestAttributes, attributes);
        if (SecCode *process =
        if (!cfscan(attributes, "{%O=%d}", kSecGuestAttributePid, &pid))
                CSError::throwMe(errSecCSUnsupportedGuestAttributes, kSecCFErrorGuestAttributes, attributes);
        if (SecCode *process =
-                       KernelCode::active()->locateGuest(CFTemp<CFDictionaryRef>("{%O=%d}", kSecGuestAttributePid, pid))) {
+                       KernelCode::active()->locateGuest(attributes)) {
                SecPointer<SecCode> code;
                code.take(process);             // locateGuest gave us a retained object
                if (code->staticCode()->flag(kSecCodeSignatureHost)) {
                SecPointer<SecCode> code;
                code.take(process);             // locateGuest gave us a retained object
                if (code->staticCode()->flag(kSecCodeSignatureHost)) {
index e40620b921d5f5c10e45f45ab8809f57159e4e17..6d1f07aa8d1531ff24f60728ec7719bd9948e93d 100644 (file)
@@ -26,8 +26,6 @@
 //
 #include "CodeSigner.h"
 #include "signer.h"
 //
 #include "CodeSigner.h"
 #include "signer.h"
-#include "reqparser.h"
-#include "renum.h"
 #include "csdatabase.h"
 #include "drmaker.h"
 #include "csutilities.h"
 #include "csdatabase.h"
 #include "drmaker.h"
 #include "csutilities.h"
@@ -66,7 +64,7 @@ public:
 // Construct a SecCodeSigner
 //
 SecCodeSigner::SecCodeSigner(SecCSFlags flags)
 // Construct a SecCodeSigner
 //
 SecCodeSigner::SecCodeSigner(SecCSFlags flags)
-       : mOpFlags(flags), mRequirements(NULL), mDigestAlgorithm(kSecCodeSignatureDefaultDigestAlgorithm)
+       : mOpFlags(flags), mDigestAlgorithm(kSecCodeSignatureDefaultDigestAlgorithm)
 {
 }
 
 {
 }
 
@@ -76,7 +74,6 @@ SecCodeSigner::SecCodeSigner(SecCSFlags flags)
 //
 SecCodeSigner::~SecCodeSigner() throw()
 try {
 //
 SecCodeSigner::~SecCodeSigner() throw()
 try {
-       ::free((Requirements *)mRequirements);
 } catch (...) {
        return;
 }
 } catch (...) {
        return;
 }
@@ -110,6 +107,8 @@ bool SecCodeSigner::valid() const
 //
 void SecCodeSigner::sign(SecStaticCode *code, SecCSFlags flags)
 {
 //
 void SecCodeSigner::sign(SecStaticCode *code, SecCSFlags flags)
 {
+       if (code->isSigned() && (flags & kSecCSSignPreserveSignature))
+               return;
        Signer operation(*this, code);
        if ((flags | mOpFlags) & kSecCSRemoveSignature) {
                secdebug("signer", "%p will remove signature from %p", this, code);
        Signer operation(*this, code);
        if ((flags | mOpFlags) & kSecCSRemoveSignature) {
                secdebug("signer", "%p will remove signature from %p", this, code);
@@ -139,7 +138,8 @@ void SecCodeSigner::returnDetachedSignature(BlobCore *blob, Signer &signer)
                CFDataAppendBytes(CFMutableDataRef(mDetached.get()),
                        (const UInt8 *)blob, blob->length());
        } else if (CFGetTypeID(mDetached) == CFNullGetTypeID()) {
                CFDataAppendBytes(CFMutableDataRef(mDetached.get()),
                        (const UInt8 *)blob, blob->length());
        } else if (CFGetTypeID(mDetached) == CFNullGetTypeID()) {
-               signatureDatabaseWriter().storeCode(blob, signer.path().c_str());
+               SignatureDatabaseWriter db;
+               db.storeCode(blob, signer.path().c_str());
        } else
                assert(false);
 }
        } else
                assert(false);
 }
@@ -163,6 +163,11 @@ bool SecCodeSigner::isAdhoc() const
        return mSigner == SecIdentityRef(kCFNull);
 }
 
        return mSigner == SecIdentityRef(kCFNull);
 }
 
+SecCSFlags SecCodeSigner::signingFlags() const
+{
+       return mOpFlags;
+}
+
 
 //
 // The actual parsing operation is done in the Parser class.
 
 //
 // The actual parsing operation is done in the Parser class.
@@ -195,6 +200,13 @@ SecCodeSigner::Parser::Parser(SecCodeSigner &state, CFDictionaryRef parameters)
        else
                state.mCMSSize = 9000;  // likely big enough
 
        else
                state.mCMSSize = 9000;  // likely big enough
 
+       // metadata preservation options
+       if (CFNumberRef preserve = get<CFNumberRef>(kSecCodeSignerPreserveMetadata)) {
+               state.mPreserveMetadata = cfNumber<uint32_t>(preserve);
+       } else
+               state.mPreserveMetadata = 0;
+
+
        // signing time can be a CFDateRef or null
        if (CFTypeRef time = get<CFTypeRef>(kSecCodeSignerSigningTime)) {
                if (CFGetTypeID(time) == CFDateGetTypeID() || time == kCFNull)
        // signing time can be a CFDateRef or null
        if (CFTypeRef time = get<CFTypeRef>(kSecCodeSignerSigningTime)) {
                if (CFGetTypeID(time) == CFDateGetTypeID() || time == kCFNull)
@@ -209,14 +221,12 @@ SecCodeSigner::Parser::Parser(SecCodeSigner &state, CFDictionaryRef parameters)
        if (CFStringRef prefix = get<CFStringRef>(kSecCodeSignerIdentifierPrefix))
                state.mIdentifierPrefix = cfString(prefix);
        
        if (CFStringRef prefix = get<CFStringRef>(kSecCodeSignerIdentifierPrefix))
                state.mIdentifierPrefix = cfString(prefix);
        
-       // requirements can be binary or string (to be compiled)
+       // Requirements can be binary or string (to be compiled).
+       // We must pass them along to the signer for possible text substitution
        if (CFTypeRef reqs = get<CFTypeRef>(kSecCodeSignerRequirements)) {
        if (CFTypeRef reqs = get<CFTypeRef>(kSecCodeSignerRequirements)) {
-               if (CFGetTypeID(reqs) == CFDataGetTypeID()) {           // binary form
-                       const Requirements *rp = (const Requirements *)CFDataGetBytePtr(CFDataRef(reqs));
-                       state.mRequirements = rp->clone();
-               } else if (CFGetTypeID(reqs) == CFStringGetTypeID()) { // text form
-                       state.mRequirements = parseRequirements(cfString(CFStringRef(reqs)));
-               } else
+               if (CFGetTypeID(reqs) == CFDataGetTypeID() || CFGetTypeID(reqs) == CFStringGetTypeID())
+                       state.mRequirements = reqs;
+               else
                        MacOSError::throwMe(errSecCSInvalidObjectRef);
        } else
                state.mRequirements = NULL;
                        MacOSError::throwMe(errSecCSInvalidObjectRef);
        } else
                state.mRequirements = NULL;
index 71f9cc3baf33a1a4b60cab2f4c5d652f2bb11186..9b050c18571922f2aa70a59f737bef3ac9f795b1 100644 (file)
@@ -64,6 +64,7 @@ public:
 protected:
        std::string sdkPath(const std::string &path) const;
        bool isAdhoc() const;
 protected:
        std::string sdkPath(const std::string &path) const;
        bool isAdhoc() const;
+       SecCSFlags signingFlags() const;
        
 private:
        // parsed parameter set
        
 private:
        // parsed parameter set
@@ -75,9 +76,10 @@ private:
        CFRef<CFDataRef> mApplicationData; // contents of application slot
        CFRef<CFDataRef> mEntitlementData; // entitlement configuration data
        CFRef<CFURLRef> mSDKRoot;               // substitute filesystem root for sub-component lookup
        CFRef<CFDataRef> mApplicationData; // contents of application slot
        CFRef<CFDataRef> mEntitlementData; // entitlement configuration data
        CFRef<CFURLRef> mSDKRoot;               // substitute filesystem root for sub-component lookup
-       const Requirements *mRequirements; // internal code requirements
+       CFRef<CFTypeRef> mRequirements; // internal code requirements
        size_t mCMSSize;                                // size estimate for CMS blob
        uint32_t mCdFlags;                              // CodeDirectory flags
        size_t mCMSSize;                                // size estimate for CMS blob
        uint32_t mCdFlags;                              // CodeDirectory flags
+       uint32_t mPreserveMetadata;             // metadata preservation options
        bool mCdFlagsGiven;                             // CodeDirectory flags were specified
        CodeDirectory::HashAlgorithm mDigestAlgorithm; // interior digest (hash) algorithm
        std::string mIdentifier;                // unique identifier override
        bool mCdFlagsGiven;                             // CodeDirectory flags were specified
        CodeDirectory::HashAlgorithm mDigestAlgorithm; // interior digest (hash) algorithm
        std::string mIdentifier;                // unique identifier override
index 90995c995bea6c1b33fb584073e6e363c4211c4b..9b5e79c4f59d9285fcb12c7a0ee31fc18ab7dc17 100644 (file)
@@ -57,7 +57,7 @@ ANTLR_BEGIN_NAMESPACE(Security_CodeSigning)
        
        static const char *matchPrefix(const string &key, const char *prefix)
        {
        
        static const char *matchPrefix(const string &key, const char *prefix)
        {
-               unsigned pLength = strlen(prefix);
+               size_t pLength = strlen(prefix);
                if (!key.compare(0, pLength, prefix, 0, pLength))
                        return key.c_str() + pLength;
                else
                if (!key.compare(0, pLength, prefix, 0, pLength))
                        return key.c_str() + pLength;
                else
@@ -247,7 +247,7 @@ uint32_t  RequirementParser::requirementType() {
                {
                        stype = LT(1);
                        match(INTEGER);
                {
                        stype = LT(1);
                        match(INTEGER);
-                       type = atol(stype->getText().c_str());
+                       type = (uint32_t)atol(stype->getText().c_str());
                        break;
                }
                default:
                        break;
                }
                default:
@@ -759,7 +759,7 @@ int32_t  RequirementParser::certSlot() {
                {
                        s = LT(1);
                        match(INTEGER);
                {
                        s = LT(1);
                        match(INTEGER);
-                       slot = atol(s->getText().c_str());
+                       slot = (int32_t)atol(s->getText().c_str());
                        break;
                }
                case NEG:
                        break;
                }
                case NEG:
@@ -767,7 +767,7 @@ int32_t  RequirementParser::certSlot() {
                        match(NEG);
                        ss = LT(1);
                        match(INTEGER);
                        match(NEG);
                        ss = LT(1);
                        match(INTEGER);
-                       slot = -atol(ss->getText().c_str());
+                       slot = (int32_t)-atol(ss->getText().c_str());
                        break;
                }
                case LITERAL_leaf:
                        break;
                }
                case LITERAL_leaf:
index 954f4ae8b4756f90859c6bfb09a3eaa2e54ac0b9..2e9862ea418e8f0458ad6d5efd70ac1872a2fb5e 100644 (file)
 #include <security_utilities/unix++.h>
 #include <security_utilities/cfmunge.h>
 #include <notify.h>
 #include <security_utilities/unix++.h>
 #include <security_utilities/cfmunge.h>
 #include <notify.h>
+#include <esp.h>
 
 using namespace CodeSigning;
 
 
 
 using namespace CodeSigning;
 
 
+static void esp_do_check(const char *op, CFDictionaryRef dict)
+{
+       OSStatus result = __esp_check_ns(op, (void *)(CFDictionaryRef)dict);
+       if (result != noErr)
+               MacOSError::throwMe(result);
+}
+
 //
 // CF Objects
 //
 //
 // CF Objects
 //
@@ -82,7 +90,6 @@ CFTypeID assessmentType = _kCFRuntimeNotATypeID;
        
 CFTypeID SecAssessmentGetTypeID()
 {
        
 CFTypeID SecAssessmentGetTypeID()
 {
-       
        dispatch_once(&assessmentOnce, ^void() {
                if ((assessmentType = _CFRuntimeRegisterClass(&assessmentClass)) == _kCFRuntimeNotATypeID)
                        abort();
        dispatch_once(&assessmentOnce, ^void() {
                if ((assessmentType = _CFRuntimeRegisterClass(&assessmentClass)) == _kCFRuntimeNotATypeID)
                        abort();
@@ -125,12 +132,11 @@ CFStringRef kSecAssessmentAssessmentAuthority = CFSTR("assessment:authority");
 CFStringRef kSecAssessmentAssessmentSource = CFSTR("assessment:authority:source");
 CFStringRef kSecAssessmentAssessmentAuthorityRow = CFSTR("assessment:authority:row");
 CFStringRef kSecAssessmentAssessmentAuthorityOverride = CFSTR("assessment:authority:override");
 CFStringRef kSecAssessmentAssessmentSource = CFSTR("assessment:authority:source");
 CFStringRef kSecAssessmentAssessmentAuthorityRow = CFSTR("assessment:authority:row");
 CFStringRef kSecAssessmentAssessmentAuthorityOverride = CFSTR("assessment:authority:override");
+CFStringRef kSecAssessmentAssessmentAuthorityOriginalVerdict = CFSTR("assessment:authority:verdict");
 CFStringRef kSecAssessmentAssessmentFromCache = CFSTR("assessment:authority:cached");
 
 CFStringRef kDisabledOverride = CFSTR("security disabled");
 
 CFStringRef kSecAssessmentAssessmentFromCache = CFSTR("assessment:authority:cached");
 
 CFStringRef kDisabledOverride = CFSTR("security disabled");
 
-CFStringRef kSecAssessmentContextKeyCertificates = CFSTR("context:certificates");      // obsolete
-
 SecAssessmentRef SecAssessmentCreate(CFURLRef path,
        SecAssessmentFlags flags,
        CFDictionaryRef context,
 SecAssessmentRef SecAssessmentCreate(CFURLRef path,
        SecAssessmentFlags flags,
        CFDictionaryRef context,
@@ -147,9 +153,14 @@ SecAssessmentRef SecAssessmentCreate(CFURLRef path,
        SYSPOLICY_ASSESS_API(cfString(path).c_str(), int(type), flags);
 
        try {
        SYSPOLICY_ASSESS_API(cfString(path).c_str(), int(type), flags);
 
        try {
+               if (__esp_enabled() && (flags & kSecAssessmentFlagDirect)) {
+                       CFTemp<CFDictionaryRef> dict("{path=%O, flags=%d, context=%O, override=%d}", path, flags, context, overrideAssessment());
+                       esp_do_check("cs-assessment-evaluate", dict);
+               }
+
                // check the object cache first unless caller denied that or we need extended processing
                if (!(flags & (kSecAssessmentFlagRequestOrigin | kSecAssessmentFlagIgnoreCache))) {
                // check the object cache first unless caller denied that or we need extended processing
                if (!(flags & (kSecAssessmentFlagRequestOrigin | kSecAssessmentFlagIgnoreCache))) {
-                       if (gDatabase().checkCache(path, type, result))
+                       if (gDatabase().checkCache(path, type, flags, result))
                                return new SecAssessment(path, type, result.yield());
                }
                
                                return new SecAssessment(path, type, result.yield());
                }
                
@@ -167,7 +178,7 @@ SecAssessmentRef SecAssessmentCreate(CFURLRef path,
                case CSSMERR_TP_CERT_REVOKED:
                        throw;
                default:
                case CSSMERR_TP_CERT_REVOKED:
                        throw;
                default:
-                       if (!overrideAssessment())
+                       if (!overrideAssessment(flags))
                                throw;          // let it go as an error
                        break;
                }
                                throw;          // let it go as an error
                        break;
                }
@@ -175,67 +186,144 @@ SecAssessmentRef SecAssessmentCreate(CFURLRef path,
                cfadd(result, "{%O=#F,'assessment:error'=%d}}", kSecAssessmentAssessmentVerdict, error.osStatus());
        } catch (...) {
                // catch stray errors not conforming to the CommonError scheme
                cfadd(result, "{%O=#F,'assessment:error'=%d}}", kSecAssessmentAssessmentVerdict, error.osStatus());
        } catch (...) {
                // catch stray errors not conforming to the CommonError scheme
-               if (!overrideAssessment())
+               if (!overrideAssessment(flags))
                        throw;          // let it go as an error
                cfadd(result, "{%O=#F}", kSecAssessmentAssessmentVerdict);
        }
                        throw;          // let it go as an error
                cfadd(result, "{%O=#F}", kSecAssessmentAssessmentVerdict);
        }
+
+       if (__esp_enabled() && (flags & kSecAssessmentFlagDirect)) {
+               CFTemp<CFDictionaryRef> dict("{path=%O, flags=%d, context=%O, override=%d, result=%O}", path, flags, context, overrideAssessment(), (CFDictionaryRef)result);
+               __esp_notify_ns("cs-assessment-evaluate", (void *)(CFDictionaryRef)dict);
+       }
+
        return new SecAssessment(path, type, result.yield());
 
        END_CSAPI_ERRORS1(NULL)
 }
 
 
        return new SecAssessment(path, type, result.yield());
 
        END_CSAPI_ERRORS1(NULL)
 }
 
 
-static void traceResult(SecAssessment &assessment, AuthorityType type, CFDictionaryRef result)
+static void traceResult(CFURLRef target, MessageTrace &trace, std::string &sanitized)
 {
 {
-       if (CFDictionaryGetValue(result, CFSTR("assessment:remote")))
-               return;         // just traced in syspolicyd
-
-       CFRef<CFURLRef> url = CFURLCopyAbsoluteURL(assessment.path);
-       string sanitized = cfString(url);
-       string::size_type rslash = sanitized.rfind('/');
-       if (rslash != string::npos)
-               sanitized = sanitized.substr(rslash+1);
-       string::size_type dot = sanitized.rfind('.');
-       if (dot != string::npos)
-               sanitized = sanitized.substr(dot+1);
-       else
-               sanitized = "(none)";
+       static const char *interestingBundles[] = {
+               "UNBUNDLED",
+               "com.apple.",
+               "com.install4j.",
+               "com.MindVision.",
+               "com.yourcompany.",
+
+               "com.adobe.flashplayer.installmanager",
+               "com.adobe.Installers.Setup",
+               "com.adobe.PDApp.setup",
+               "com.bittorrent.uTorrent",
+               "com.divx.divx6formacinstaller",
+               "com.getdropbox.dropbox",
+               "com.google.Chrome",
+               "com.Google.GoogleEarthPlugin.plugin",
+               "com.Google.GoogleEarthPlus",
+               "com.hp.Installer",
+               "com.macpaw.CleanMyMac",
+               "com.microsoft.SilverlightInstaller",
+               "com.paragon-software.filesystems.NTFS.pkg",
+               "com.RealNetworks.RealPlayer",
+               "com.skype.skype",
+               "it.alfanet.squared5.MPEGStreamclip",
+               "org.mozilla.firefox",
+               "org.videolan.vlc",
+               
+               NULL    // sentinel
+       };
 
        string identifier = "UNBUNDLED";
 
        string identifier = "UNBUNDLED";
-       if (CFRef<CFBundleRef> bundle = CFBundleCreate(NULL, assessment.path))
+       string version = "UNKNOWN";
+       if (CFRef<CFBundleRef> bundle = CFBundleCreate(NULL, target)) {
                if (CFStringRef ident = CFBundleGetIdentifier(bundle))
                        identifier = cfString(ident);
                if (CFStringRef ident = CFBundleGetIdentifier(bundle))
                        identifier = cfString(ident);
+               if (CFStringRef vers = CFStringRef(CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("CFBundleShortVersionString"))))
+                       version = cfString(vers);
+       }
+       
+       CFRef<CFURLRef> url = CFURLCopyAbsoluteURL(target);
+       sanitized = cfString(url);
+       string::size_type rslash = sanitized.rfind('/');
+       if (rslash != string::npos)
+               sanitized = sanitized.substr(rslash+1);
+       bool keepFilename = false;
+       for (const char **pfx = interestingBundles; *pfx; pfx++) {
+               size_t pfxlen = strlen(*pfx);
+               if (identifier.compare(0, pfxlen, *pfx, pfxlen) == 0)
+                       if (pfxlen == identifier.size() || (*pfx)[pfxlen-1] == '.') {
+                               keepFilename = true;
+                               break;
+                       }
+       }
+       if (!keepFilename) {
+               string::size_type dot = sanitized.rfind('.');
+               if (dot != string::npos)
+                       sanitized = sanitized.substr(dot);
+               else
+                       sanitized = "(none)";
+       }
+       
+       trace.add("signature2", "bundle:%s", identifier.c_str());
+       trace.add("signature3", "%s", sanitized.c_str());
+       trace.add("signature5", "%s", version.c_str());
+}
+       
+static void traceAssessment(SecAssessment &assessment, AuthorityType type, CFDictionaryRef result)
+{
+       if (CFDictionaryGetValue(result, CFSTR("assessment:remote")))
+               return;         // just traced in syspolicyd
        
        string authority = "UNSPECIFIED";
        bool overridden = false;
        
        string authority = "UNSPECIFIED";
        bool overridden = false;
+       bool old_overridden = false;
        if (CFDictionaryRef authdict = CFDictionaryRef(CFDictionaryGetValue(result, kSecAssessmentAssessmentAuthority))) {
                if (CFStringRef auth = CFStringRef(CFDictionaryGetValue(authdict, kSecAssessmentAssessmentSource)))
                        authority = cfString(auth);
                else
                        authority = "no authority";
                if (CFTypeRef override = CFDictionaryGetValue(authdict, kSecAssessmentAssessmentAuthorityOverride))
        if (CFDictionaryRef authdict = CFDictionaryRef(CFDictionaryGetValue(result, kSecAssessmentAssessmentAuthority))) {
                if (CFStringRef auth = CFStringRef(CFDictionaryGetValue(authdict, kSecAssessmentAssessmentSource)))
                        authority = cfString(auth);
                else
                        authority = "no authority";
                if (CFTypeRef override = CFDictionaryGetValue(authdict, kSecAssessmentAssessmentAuthorityOverride))
-                       if (CFEqual(override, kDisabledOverride))
-                               overridden = true;
+                       if (CFEqual(override, kDisabledOverride)) {
+                               old_overridden = true;
+                               if (CFDictionaryGetValue(authdict, kSecAssessmentAssessmentAuthorityOriginalVerdict) == kCFBooleanFalse)
+                                       overridden = true;
+                       }
        }
        }
-       
-       MessageTrace trace("com.apple.security.assessment.outcome", NULL);
-       trace.add("signature2", "bundle:%s", identifier.c_str());
+
+       MessageTrace trace("com.apple.security.assessment.outcome2", NULL);
+       std::string sanitized;
+       traceResult(assessment.path, trace, sanitized);
        trace.add("signature4", "%d", type);
        trace.add("signature4", "%d", type);
+
        if (CFDictionaryGetValue(result, kSecAssessmentAssessmentVerdict) == kCFBooleanFalse) {
                trace.add("signature", "denied:%s", authority.c_str());
        if (CFDictionaryGetValue(result, kSecAssessmentAssessmentVerdict) == kCFBooleanFalse) {
                trace.add("signature", "denied:%s", authority.c_str());
-               trace.add("signature3", sanitized.c_str());
                trace.send("assessment denied for %s", sanitized.c_str());
                trace.send("assessment denied for %s", sanitized.c_str());
-       } else if (overridden) {
-               trace.add("signature", "override:%s", authority.c_str());
-               trace.add("signature3", sanitized.c_str());
+       } else if (overridden) {                // would have failed except for override
+               trace.add("signature", "defeated:%s", authority.c_str());
                trace.send("assessment denied for %s but overridden", sanitized.c_str());
                trace.send("assessment denied for %s but overridden", sanitized.c_str());
+       } else if (old_overridden) {    // would have succeeded even without override
+               trace.add("signature", "override:%s", authority.c_str());
+               trace.send("assessment granted for %s and overridden", sanitized.c_str());
        } else {
                trace.add("signature", "granted:%s", authority.c_str());
        } else {
                trace.add("signature", "granted:%s", authority.c_str());
-               trace.add("signature3", sanitized.c_str());
                trace.send("assessment granted for %s by %s", sanitized.c_str(), authority.c_str());
        }
 }
 
                trace.send("assessment granted for %s by %s", sanitized.c_str(), authority.c_str());
        }
 }
 
+static void traceUpdate(CFTypeRef target, CFDictionaryRef context, CFDictionaryRef result)
+{
+       // only trace add operations on URL targets
+       if (target == NULL || CFGetTypeID(target) != CFURLGetTypeID())
+               return;
+       CFStringRef edit = CFStringRef(CFDictionaryGetValue(context, kSecAssessmentContextKeyUpdate));
+       if (!CFEqual(edit, kSecAssessmentUpdateOperationAdd))
+               return;
+       MessageTrace trace("com.apple.security.assessment.update", NULL);
+       std::string sanitized;
+       traceResult(CFURLRef(target), trace, sanitized);
+       trace.send("added rule for %s", sanitized.c_str());
+}
+
 
 //
 // At present, CopyResult simply retrieves the result already formed by Create.
 
 //
 // At present, CopyResult simply retrieves the result already formed by Create.
@@ -249,14 +337,16 @@ CFDictionaryRef SecAssessmentCopyResult(SecAssessmentRef assessmentRef,
 
        SecAssessment &assessment = SecAssessment::ref(assessmentRef);
        CFCopyRef<CFDictionaryRef> result = assessment.result;
 
        SecAssessment &assessment = SecAssessment::ref(assessmentRef);
        CFCopyRef<CFDictionaryRef> result = assessment.result;
-       if (!(flags & kSecAssessmentFlagEnforce) && overrideAssessment()) {
+       if (overrideAssessment(flags)) {
                // turn rejections into approvals, but note that we did that
                // turn rejections into approvals, but note that we did that
-               if (CFDictionaryGetValue(result, kSecAssessmentAssessmentVerdict) == kCFBooleanFalse) {
+               CFTypeRef verdict = CFDictionaryGetValue(result, kSecAssessmentAssessmentVerdict);
+               if (verdict == kCFBooleanFalse) {
                        CFRef<CFMutableDictionaryRef> adulterated = makeCFMutableDictionary(result.get());
                        CFDictionarySetValue(adulterated, kSecAssessmentAssessmentVerdict, kCFBooleanTrue);
                        if (CFDictionaryRef authority = CFDictionaryRef(CFDictionaryGetValue(adulterated, kSecAssessmentAssessmentAuthority))) {
                                CFRef<CFMutableDictionaryRef> authority2 = makeCFMutableDictionary(authority);
                                CFDictionarySetValue(authority2, kSecAssessmentAssessmentAuthorityOverride, kDisabledOverride);
                        CFRef<CFMutableDictionaryRef> adulterated = makeCFMutableDictionary(result.get());
                        CFDictionarySetValue(adulterated, kSecAssessmentAssessmentVerdict, kCFBooleanTrue);
                        if (CFDictionaryRef authority = CFDictionaryRef(CFDictionaryGetValue(adulterated, kSecAssessmentAssessmentAuthority))) {
                                CFRef<CFMutableDictionaryRef> authority2 = makeCFMutableDictionary(authority);
                                CFDictionarySetValue(authority2, kSecAssessmentAssessmentAuthorityOverride, kDisabledOverride);
+                               CFDictionarySetValue(authority2, kSecAssessmentAssessmentAuthorityOriginalVerdict, verdict);
                                CFDictionarySetValue(adulterated, kSecAssessmentAssessmentAuthority, authority2);
                        } else {
                                cfadd(adulterated, "{%O={%O=%O}}",
                                CFDictionarySetValue(adulterated, kSecAssessmentAssessmentAuthority, authority2);
                        } else {
                                cfadd(adulterated, "{%O={%O=%O}}",
@@ -265,7 +355,7 @@ CFDictionaryRef SecAssessmentCopyResult(SecAssessmentRef assessmentRef,
                        result = adulterated.get();
                }
        }
                        result = adulterated.get();
                }
        }
-       traceResult(assessment, assessment.type, result);
+       traceAssessment(assessment, assessment.type, result);
        return result.yield();
 
        END_CSAPI_ERRORS1(NULL)
        return result.yield();
 
        END_CSAPI_ERRORS1(NULL)
@@ -327,15 +417,31 @@ CFDictionaryRef SecAssessmentCopyUpdate(CFTypeRef target,
        BEGIN_CSAPI
 
        CFDictionary ctx(context, errSecCSInvalidAttributeValues);
        BEGIN_CSAPI
 
        CFDictionary ctx(context, errSecCSInvalidAttributeValues);
+       CFRef<CFDictionaryRef> result;
 
        if (flags & kSecAssessmentFlagDirect) {
 
        if (flags & kSecAssessmentFlagDirect) {
+               if (__esp_enabled()) {
+                       CFTemp<CFDictionaryRef> dict("{target=%O, flags=%d, context=%O}", target, flags, context);
+                       OSStatus esp_result = __esp_check_ns("cs-assessment-update", (void *)(CFDictionaryRef)dict);
+                       if (esp_result != noErr)
+                               return NULL;
+               }
+
                // ask the engine right here to do its thing
                // ask the engine right here to do its thing
-               return gEngine().update(target, flags, ctx);
+               result = gEngine().update(target, flags, ctx);
        } else {
                // relay the question to our daemon for consideration
        } else {
                // relay the question to our daemon for consideration
-               return xpcEngineUpdate(target, flags, ctx);
+               result = xpcEngineUpdate(target, flags, ctx);
        }
 
        }
 
+       if (__esp_enabled() && (flags & kSecAssessmentFlagDirect)) {
+               CFTemp<CFDictionaryRef> dict("{target=%O, flags=%d, context=%O, outcome=%O}", target, flags, context, (CFDictionaryRef)result);
+               __esp_notify_ns("cs-assessment-update", (void *)(CFDictionaryRef)dict);
+       }
+
+       traceUpdate(target, context, result);
+       return result.yield();
+
        END_CSAPI_ERRORS1(false)
 }
 
        END_CSAPI_ERRORS1(false)
 }
 
@@ -348,6 +454,9 @@ Boolean SecAssessmentControl(CFStringRef control, void *arguments, CFErrorRef *e
 {
        BEGIN_CSAPI
        
 {
        BEGIN_CSAPI
        
+       CFTemp<CFDictionaryRef> dict("{control=%O}", control);
+       esp_do_check("cs-assessment-control", dict);
+
        if (CFEqual(control, CFSTR("ui-enable"))) {
                setAssessment(true);
                MessageTrace trace("com.apple.security.assessment.state", "enable");
        if (CFEqual(control, CFSTR("ui-enable"))) {
                setAssessment(true);
                MessageTrace trace("com.apple.security.assessment.state", "enable");
@@ -386,6 +495,23 @@ Boolean SecAssessmentControl(CFStringRef control, void *arguments, CFErrorRef *e
                else
                        result = kCFBooleanTrue;
                return true;
                else
                        result = kCFBooleanTrue;
                return true;
+       } else if (CFEqual(control, CFSTR("ui-record-reject"))) {
+               // send this through syspolicyd for update validation
+               xpcEngineRecord(CFDictionaryRef(arguments));
+               return true;
+       } else if (CFEqual(control, CFSTR("ui-record-reject-local"))) {
+               // perform the local operation (requires root)
+               gEngine().recordFailure(CFDictionaryRef(arguments));
+               return true;
+       } else if (CFEqual(control, CFSTR("ui-recall-reject"))) {
+               // no special privileges required for this, so read directly
+               CFDictionaryRef &result = *(CFDictionaryRef*)(arguments);
+               CFRef<CFDataRef> infoData = cfLoadFile(lastRejectFile);
+               if (infoData)
+                       result = makeCFDictionaryFrom(infoData);
+               else
+                       result = NULL;
+               return true;
        } else
                MacOSError::throwMe(errSecCSInvalidAttributeValues);
 
        } else
                MacOSError::throwMe(errSecCSInvalidAttributeValues);
 
index 96665816b8a716adc451d66e1162c37de1a7c093..7c9e3ba6fb1b5d082d46be4763aaff655cdba34b 100644 (file)
@@ -48,6 +48,7 @@ CFTypeID SecAssessmentGetTypeID();
  */
 #define kNotifySecAssessmentMasterSwitch "com.apple.security.assessment.masterswitch"
 #define kNotifySecAssessmentUpdate "com.apple.security.assessment.update"
  */
 #define kNotifySecAssessmentMasterSwitch "com.apple.security.assessment.masterswitch"
 #define kNotifySecAssessmentUpdate "com.apple.security.assessment.update"
+#define kNotifySecAssessmentRecordingChange "com.apple.security.assessment.UIRecordRejectDidChangeNotification"
 
 
 /*!
 
 
 /*!
@@ -131,6 +132,7 @@ extern CFStringRef kSecAssessmentAssessmentSource;          // CFStringRef: primary sour
 extern CFStringRef kSecAssessmentAssessmentFromCache;  // present if result is from cache
 extern CFStringRef kSecAssessmentAssessmentAuthorityRow; // (internal)
 extern CFStringRef kSecAssessmentAssessmentAuthorityOverride; // (internal)
 extern CFStringRef kSecAssessmentAssessmentFromCache;  // present if result is from cache
 extern CFStringRef kSecAssessmentAssessmentAuthorityRow; // (internal)
 extern CFStringRef kSecAssessmentAssessmentAuthorityOverride; // (internal)
+extern CFStringRef kSecAssessmentAssessmentAuthorityOriginalVerdict; // (internal)
 
 extern CFStringRef kDisabledOverride;                                  // AuthorityOverride value for "Gatekeeper is disabled"
 
 
 extern CFStringRef kDisabledOverride;                                  // AuthorityOverride value for "Gatekeeper is disabled"
 
@@ -242,7 +244,6 @@ extern CFStringRef kSecAssessmentUpdateOperationEnable;     // enable rule(s) in pol
 extern CFStringRef kSecAssessmentUpdateOperationDisable;       // disable rule(s) in policy database
 extern CFStringRef kSecAssessmentUpdateOperationFind;  // extract rule(s) from the policy database
 
 extern CFStringRef kSecAssessmentUpdateOperationDisable;       // disable rule(s) in policy database
 extern CFStringRef kSecAssessmentUpdateOperationFind;  // extract rule(s) from the policy database
 
-extern CFStringRef kSecAssessmentContextKeyCertificates; // obsolete
 extern CFStringRef kSecAssessmentUpdateKeyAuthorization;       // [CFData] external form of governing authorization
 
 extern CFStringRef kSecAssessmentUpdateKeyPriority;            // rule priority
 extern CFStringRef kSecAssessmentUpdateKeyAuthorization;       // [CFData] external form of governing authorization
 
 extern CFStringRef kSecAssessmentUpdateKeyPriority;            // rule priority
index f5b300f6dc9ae15e815f5c125375ecfab6de198c..cd91d81349c0bd4707325739da0a1f03310fa64c 100644 (file)
@@ -114,8 +114,15 @@ OSStatus SecCodeCopyStaticCode(SecCodeRef codeRef, SecCSFlags flags, SecStaticCo
 {
        BEGIN_CSAPI
        
 {
        BEGIN_CSAPI
        
-       checkFlags(flags);
+       checkFlags(flags, kSecCSUseAllArchitectures);
        SecPointer<SecStaticCode> staticCode = SecCode::required(codeRef)->staticCode();
        SecPointer<SecStaticCode> staticCode = SecCode::required(codeRef)->staticCode();
+       if (flags & kSecCSUseAllArchitectures)
+               if (Universal* macho = staticCode->diskRep()->mainExecutableImage())    // Mach-O main executable
+                       if (macho->narrowed()) {
+                               // create a new StaticCode comprising the whole fat file
+                               RefPointer<DiskRep> rep = DiskRep::bestGuess(staticCode->diskRep()->mainExecutablePath());
+                               staticCode = new SecStaticCode(rep);
+                       }
        CodeSigning::Required(staticCodeRef) = staticCode ? staticCode->handle() : NULL;
 
        END_CSAPI
        CodeSigning::Required(staticCodeRef) = staticCode ? staticCode->handle() : NULL;
 
        END_CSAPI
@@ -144,6 +151,8 @@ const CFStringRef kSecGuestAttributeCanonical =             CFSTR("canonical");
 const CFStringRef kSecGuestAttributeHash =                     CFSTR("codedirectory-hash");
 const CFStringRef kSecGuestAttributeMachPort =         CFSTR("mach-port");
 const CFStringRef kSecGuestAttributePid =                      CFSTR("pid");
 const CFStringRef kSecGuestAttributeHash =                     CFSTR("codedirectory-hash");
 const CFStringRef kSecGuestAttributeMachPort =         CFSTR("mach-port");
 const CFStringRef kSecGuestAttributePid =                      CFSTR("pid");
+const CFStringRef kSecGuestAttributeDynamicCode =               CFSTR("dynamicCode");
+const CFStringRef kSecGuestAttributeDynamicCodeInfoPlist =               CFSTR("dynamicCodeInfoPlist");
 const CFStringRef kSecGuestAttributeArchitecture =     CFSTR("architecture");
 const CFStringRef kSecGuestAttributeSubarchitecture = CFSTR("subarchitecture");
 
 const CFStringRef kSecGuestAttributeArchitecture =     CFSTR("architecture");
 const CFStringRef kSecGuestAttributeSubarchitecture = CFSTR("subarchitecture");
 
@@ -222,6 +231,7 @@ const CFStringRef kSecCodeInfoCMS =                         CFSTR("cms");
 const CFStringRef kSecCodeInfoDesignatedRequirement = CFSTR("designated-requirement");
 const CFStringRef kSecCodeInfoEntitlements =   CFSTR("entitlements");
 const CFStringRef kSecCodeInfoEntitlementsDict =       CFSTR("entitlements-dict");
 const CFStringRef kSecCodeInfoDesignatedRequirement = CFSTR("designated-requirement");
 const CFStringRef kSecCodeInfoEntitlements =   CFSTR("entitlements");
 const CFStringRef kSecCodeInfoEntitlementsDict =       CFSTR("entitlements-dict");
+const CFStringRef kSecCodeInfoFlags =                  CFSTR("flags");
 const CFStringRef kSecCodeInfoFormat =                 CFSTR("format");
 const CFStringRef kSecCodeInfoDigestAlgorithm =        CFSTR("digest-algorithm");
 const CFStringRef kSecCodeInfoIdentifier =             CFSTR("identifier");
 const CFStringRef kSecCodeInfoFormat =                 CFSTR("format");
 const CFStringRef kSecCodeInfoDigestAlgorithm =        CFSTR("digest-algorithm");
 const CFStringRef kSecCodeInfoIdentifier =             CFSTR("identifier");
@@ -265,4 +275,3 @@ OSStatus SecCodeCopySigningInformation(SecStaticCodeRef codeRef, SecCSFlags flag
        
        END_CSAPI
 }
        
        END_CSAPI
 }
-
index 4ae85d901082de00a678626205ef43c9b170f6e1..1afbfebd68c6ded5c8b0810e76d704dedfe85648 100644 (file)
@@ -56,7 +56,7 @@ CFTypeID SecCodeGetTypeID(void);
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param self Upon successful return, contains a SecCodeRef representing the caller.
        
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param self Upon successful return, contains a SecCodeRef representing the caller.
        
-       @result Upon success, noErr. Upon error, an OSStatus value documented in
+       @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in
        CSCommon.h or certain other Security framework headers.
  */
 OSStatus SecCodeCopySelf(SecCSFlags flags, SecCodeRef *self);
        CSCommon.h or certain other Security framework headers.
  */
 OSStatus SecCodeCopySelf(SecCSFlags flags, SecCodeRef *self);
@@ -83,12 +83,22 @@ OSStatus SecCodeCopySelf(SecCSFlags flags, SecCodeRef *self);
 
        @param code A valid SecCode object reference representing code running
        on the system.
 
        @param code A valid SecCode object reference representing code running
        on the system.
+       
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
+       @constant kSecCSUseAllArchitectures
+       If code refers to a single architecture of a universal binary, return a SecStaticCodeRef
+       that refers to the entire universal code with all its architectures. By default, the
+       returned static reference identifies only the actual architecture of the running program.
+
        @param staticCode On successful return, a SecStaticCode object reference representing
        the file system origin of the given SecCode. On error, unchanged.
        @param staticCode On successful return, a SecStaticCode object reference representing
        the file system origin of the given SecCode. On error, unchanged.
-       @result Upon success, noErr. Upon error, an OSStatus value documented in
+       @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in
        CSCommon.h or certain other Security framework headers.
 */
        CSCommon.h or certain other Security framework headers.
 */
+enum {
+       kSecCSUseAllArchitectures = 1 << 0,
+};
+
 OSStatus SecCodeCopyStaticCode(SecCodeRef code, SecCSFlags flags, SecStaticCodeRef *staticCode);
 
 
 OSStatus SecCodeCopyStaticCode(SecCodeRef code, SecCSFlags flags, SecStaticCodeRef *staticCode);
 
 
@@ -104,7 +114,7 @@ OSStatus SecCodeCopyStaticCode(SecCodeRef code, SecCSFlags flags, SecStaticCodeR
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param host On successful return, a SecCode object reference identifying
        the code's host.
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param host On successful return, a SecCode object reference identifying
        the code's host.
-       @result Upon success, noErr. Upon error, an OSStatus value documented in
+       @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in
        CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecCodeCopyHost(SecCodeRef guest, SecCSFlags flags, SecCodeRef *host);
        CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecCodeCopyHost(SecCodeRef guest, SecCSFlags flags, SecCodeRef *host);
@@ -148,8 +158,8 @@ OSStatus SecCodeCopyHost(SecCodeRef guest, SecCSFlags flags, SecCodeRef *host);
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param guest On successful return, a SecCode object reference identifying
        the particular guest of the host that owns the attribute value(s) specified.
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param guest On successful return, a SecCode object reference identifying
        the particular guest of the host that owns the attribute value(s) specified.
-       This argument will not be changed if the call fails (does not return noErr).
-       @result Upon success, noErr. Upon error, an OSStatus value documented in
+       This argument will not be changed if the call fails (does not return errSecSuccess).
+       @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in
        CSCommon.h or certain other Security framework headers. In particular:
        @error errSecCSUnsupportedGuestAttributes The host does not support the attribute
        type given by attributeType.
        CSCommon.h or certain other Security framework headers. In particular:
        @error errSecCSUnsupportedGuestAttributes The host does not support the attribute
        type given by attributeType.
@@ -168,6 +178,8 @@ extern const CFStringRef kSecGuestAttributeCanonical;
 extern const CFStringRef kSecGuestAttributeHash;
 extern const CFStringRef kSecGuestAttributeMachPort;
 extern const CFStringRef kSecGuestAttributePid;
 extern const CFStringRef kSecGuestAttributeHash;
 extern const CFStringRef kSecGuestAttributeMachPort;
 extern const CFStringRef kSecGuestAttributePid;
+extern const CFStringRef kSecGuestAttributeDynamicCode;
+extern const CFStringRef kSecGuestAttributeDynamicCodeInfoPlist;
 extern const CFStringRef kSecGuestAttributeArchitecture;
 extern const CFStringRef kSecGuestAttributeSubarchitecture;
 
 extern const CFStringRef kSecGuestAttributeArchitecture;
 extern const CFStringRef kSecGuestAttributeSubarchitecture;
 
@@ -194,10 +206,10 @@ OSStatus SecCodeCopyGuestWithAttributes(SecCodeRef host,
        the code object must satisfy to be considered valid. If NULL, no additional
        requirements are imposed.
        @param errors An optional pointer to a CFErrorRef variable. If the call fails
        the code object must satisfy to be considered valid. If NULL, no additional
        requirements are imposed.
        @param errors An optional pointer to a CFErrorRef variable. If the call fails
-       (and something other than noErr is returned), and this argument is non-NULL,
+       (and something other than errSecSuccess is returned), and this argument is non-NULL,
        a CFErrorRef is stored there further describing the nature and circumstances
        of the failure. The caller must CFRelease() this error object when done with it.
        a CFErrorRef is stored there further describing the nature and circumstances
        of the failure. The caller must CFRelease() this error object when done with it.
-       @result If validation passes, noErr. If validation fails, an OSStatus value
+       @result If validation passes, errSecSuccess. If validation fails, an OSStatus value
        documented in CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecCodeCheckValidity(SecCodeRef code, SecCSFlags flags,
        documented in CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecCodeCheckValidity(SecCodeRef code, SecCSFlags flags,
@@ -221,7 +233,7 @@ OSStatus SecCodeCheckValidityWithErrors(SecCodeRef code, SecCSFlags flags,
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param path On successful return, contains a CFURL identifying the location
        on disk of the staticCode object.
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param path On successful return, contains a CFURL identifying the location
        on disk of the staticCode object.
-       @result On success, noErr. On error, an OSStatus value
+       @result On success, errSecSuccess. On error, an OSStatus value
        documented in CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecCodeCopyPath(SecStaticCodeRef staticCode, SecCSFlags flags,
        documented in CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecCodeCopyPath(SecStaticCodeRef staticCode, SecCSFlags flags,
@@ -246,7 +258,7 @@ OSStatus SecCodeCopyPath(SecStaticCodeRef staticCode, SecCSFlags flags,
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param requirement On successful return, contains a copy of a SecRequirement
        object representing the code's Designated Requirement. On error, unchanged.
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param requirement On successful return, contains a copy of a SecRequirement
        object representing the code's Designated Requirement. On error, unchanged.
-       @result On success, noErr. On error, an OSStatus value
+       @result On success, errSecSuccess. On error, an OSStatus value
                documented in CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecCodeCopyDesignatedRequirement(SecStaticCodeRef code, SecCSFlags flags,
                documented in CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecCodeCopyDesignatedRequirement(SecStaticCodeRef code, SecCSFlags flags,
@@ -284,7 +296,7 @@ OSStatus SecCodeCopyDesignatedRequirement(SecStaticCodeRef code, SecCSFlags flag
                used by the code signing infrastructure. Making changes to these objects
                is unsupported and may cause subsequent code signing operations on the
                affected code to behave in undefined ways.
                used by the code signing infrastructure. Making changes to these objects
                is unsupported and may cause subsequent code signing operations on the
                affected code to behave in undefined ways.
-       @result On success, noErr. On error, an OSStatus value
+       @result On success, errSecSuccess. On error, an OSStatus value
                documented in CSCommon.h or certain other Security framework headers.
                
        Flags:
                documented in CSCommon.h or certain other Security framework headers.
                
        Flags:
@@ -322,6 +334,8 @@ OSStatus SecCodeCopyDesignatedRequirement(SecStaticCodeRef code, SecCSFlags flag
                of the code if it has entitlements and they are in standard dictionary form.
                Absent if the code has no entitlements, or they are in a different format (in which
                case, see kSecCodeInfoEntitlements).
                of the code if it has entitlements and they are in standard dictionary form.
                Absent if the code has no entitlements, or they are in a different format (in which
                case, see kSecCodeInfoEntitlements).
+       @constant kSecCodeInfoFlags A CFNumber with the static (on-disk) state of the object.
+               Contants are defined by the type SecCodeSignatureFlags.
        @constant kSecCodeInfoFormat A CFString characterizing the type and format of
                the code. Suitable for display to a (knowledeable) user.
        @constant kSecCodeInfoDigestAlgorithm A CFNumber indicating the kind of cryptographic
        @constant kSecCodeInfoFormat A CFString characterizing the type and format of
                the code. Suitable for display to a (knowledeable) user.
        @constant kSecCodeInfoDigestAlgorithm A CFNumber indicating the kind of cryptographic
@@ -372,8 +386,6 @@ OSStatus SecCodeCopyDesignatedRequirement(SecStaticCodeRef code, SecCSFlags flag
                This is currently the SHA-1 hash of the code's CodeDirectory. However, future
                versions of the system may use a different algorithm for newly signed code.
                Already-signed code not change the reported value in this case.
                This is currently the SHA-1 hash of the code's CodeDirectory. However, future
                versions of the system may use a different algorithm for newly signed code.
                Already-signed code not change the reported value in this case.
-       @constant kSecCodeSignerFlags A CFNumber with the dynamic state of the object.
-               Contants are defined by the type SecCodeSignatureFlags.
  */
 enum {
        kSecCSInternalInformation = 1 << 0,
  */
 enum {
        kSecCSInternalInformation = 1 << 0,
@@ -390,6 +402,7 @@ extern const CFStringRef kSecCodeInfoCMS;                   /* Signing */
 extern const CFStringRef kSecCodeInfoDesignatedRequirement; /* Requirement */
 extern const CFStringRef kSecCodeInfoEntitlements;     /* Requirement */
 extern const CFStringRef kSecCodeInfoEntitlementsDict; /* Requirement */
 extern const CFStringRef kSecCodeInfoDesignatedRequirement; /* Requirement */
 extern const CFStringRef kSecCodeInfoEntitlements;     /* Requirement */
 extern const CFStringRef kSecCodeInfoEntitlementsDict; /* Requirement */
+extern const CFStringRef kSecCodeInfoFlags;            /* generic */
 extern const CFStringRef kSecCodeInfoFormat;           /* generic */
 extern const CFStringRef kSecCodeInfoDigestAlgorithm; /* generic */
 extern const CFStringRef kSecCodeInfoIdentifier;       /* generic */
 extern const CFStringRef kSecCodeInfoFormat;           /* generic */
 extern const CFStringRef kSecCodeInfoDigestAlgorithm; /* generic */
 extern const CFStringRef kSecCodeInfoIdentifier;       /* generic */
@@ -404,7 +417,6 @@ extern const CFStringRef kSecCodeInfoTime;                  /* Signing */
 extern const CFStringRef kSecCodeInfoTimestamp;                /* Signing */
 extern const CFStringRef kSecCodeInfoTrust;                    /* Signing */
 extern const CFStringRef kSecCodeInfoUnique;           /* generic */
 extern const CFStringRef kSecCodeInfoTimestamp;                /* Signing */
 extern const CFStringRef kSecCodeInfoTrust;                    /* Signing */
 extern const CFStringRef kSecCodeInfoUnique;           /* generic */
-extern const CFStringRef kSecCodeSignerFlags;          /* dynamic */
 
 OSStatus SecCodeCopySigningInformation(SecStaticCodeRef code, SecCSFlags flags,
        CFDictionaryRef *information);
 
 OSStatus SecCodeCopySigningInformation(SecStaticCodeRef code, SecCSFlags flags,
        CFDictionaryRef *information);
index dd70b8ab6f01df60acf2a1a2c2d09a6b27174a84..2607422e8353d442765f926b834a0b457c82b344 100644 (file)
@@ -105,7 +105,7 @@ extern "C" {
        (in SecCode.h) are conventionally used here.
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior, or
        a combination of the flags defined below for special features.
        (in SecCode.h) are conventionally used here.
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior, or
        a combination of the flags defined below for special features.
-       @result Upon success, noErr. Upon error, an OSStatus value documented in
+       @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in
        CSCommon.h or certain other Security framework headers.
        @param newGuest Upon successful creation of the new guest, the new SecGuestRef
        that should be used to identify the new guest from here on.
        CSCommon.h or certain other Security framework headers.
        @param newGuest Upon successful creation of the new guest, the new SecGuestRef
        that should be used to identify the new guest from here on.
@@ -149,7 +149,7 @@ OSStatus SecHostCreateGuest(SecGuestRef host,
        @param guest The handle for a Guest previously created with SecHostCreateGuest
        that has not previously been destroyed. This guest is to be destroyed now.
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param guest The handle for a Guest previously created with SecHostCreateGuest
        that has not previously been destroyed. This guest is to be destroyed now.
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
-       @result Upon success, noErr. Upon error, an OSStatus value documented in
+       @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in
        CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecHostRemoveGuest(SecGuestRef host, SecGuestRef guest, SecCSFlags flags);
        CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecHostRemoveGuest(SecGuestRef host, SecGuestRef guest, SecCSFlags flags);
@@ -167,7 +167,7 @@ OSStatus SecHostRemoveGuest(SecGuestRef host, SecGuestRef guest, SecCSFlags flag
        To indicate that the thread will act on behalf of the Host itself (rather than
        any Guest), pass kSecNoGuest.
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        To indicate that the thread will act on behalf of the Host itself (rather than
        any Guest), pass kSecNoGuest.
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
-       @result Upon success, noErr. Upon error, an OSStatus value documented in
+       @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in
        CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecHostSelectGuest(SecGuestRef guestRef, SecCSFlags flags);
        CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecHostSelectGuest(SecGuestRef guestRef, SecCSFlags flags);
@@ -181,7 +181,7 @@ OSStatus SecHostSelectGuest(SecGuestRef guestRef, SecCSFlags flags);
        @param guestRef Will be assigned the SecGuestRef currently in effect for
        the calling thread. If no Guest is active on this thread (i.e. the thread
        is acting for the Host), the return value is kSecNoGuest.
        @param guestRef Will be assigned the SecGuestRef currently in effect for
        the calling thread. If no Guest is active on this thread (i.e. the thread
        is acting for the Host), the return value is kSecNoGuest.
-       @result Upon success, noErr. Upon error, an OSStatus value documented in
+       @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in
        CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecHostSelectedGuest(SecCSFlags flags, SecGuestRef *guestRef);
        CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecHostSelectedGuest(SecCSFlags flags, SecGuestRef *guestRef);
@@ -202,7 +202,7 @@ OSStatus SecHostSelectedGuest(SecCSFlags flags, SecGuestRef *guestRef);
        this guest from all guests of the caller. If given, it completely replaces the attributes
        specified earlier. If NULL, previously established attributes are retained.
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        this guest from all guests of the caller. If given, it completely replaces the attributes
        specified earlier. If NULL, previously established attributes are retained.
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
-       @result Upon success, noErr. Upon error, an OSStatus value documented in
+       @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in
        CSCommon.h or certain other Security framework headers.
  */
 OSStatus SecHostSetGuestStatus(SecGuestRef guestRef,
        CSCommon.h or certain other Security framework headers.
  */
 OSStatus SecHostSetGuestStatus(SecGuestRef guestRef,
@@ -228,7 +228,7 @@ OSStatus SecHostSetGuestStatus(SecGuestRef guestRef,
        @param hostingPort A Mach message port with send rights. This port will be recorded
        and handed to parties interested in querying the host about its children.
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param hostingPort A Mach message port with send rights. This port will be recorded
        and handed to parties interested in querying the host about its children.
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
-       @result Upon success, noErr. Upon error, an OSStatus value documented in
+       @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in
        CSCommon.h or certain other Security framework headers.
  */
 OSStatus SecHostSetHostingPort(mach_port_t hostingPort, SecCSFlags flags);
        CSCommon.h or certain other Security framework headers.
  */
 OSStatus SecHostSetHostingPort(mach_port_t hostingPort, SecCSFlags flags);
index 54759b8250e645d9f4f58a32b1ae583eebb34c23..d924ddf60587966b238b65a96f7d02bece834dd3 100644 (file)
@@ -65,7 +65,7 @@ extern const CFStringRef kSecCodeInfoResourceDirectory;               /* Internal */
        @param status Upon successful return, contains the dynamic status of code as
        determined by its host.
        
        @param status Upon successful return, contains the dynamic status of code as
        determined by its host.
        
-       @result Upon success, noErr. Upon error, an OSStatus value documented in
+       @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in
        CSCommon.h or certain other Security framework headers.
  */
 OSStatus SecCodeGetStatus(SecCodeRef code, SecCSFlags flags, SecCodeStatus *status);
        CSCommon.h or certain other Security framework headers.
  */
 OSStatus SecCodeGetStatus(SecCodeRef code, SecCSFlags flags, SecCodeStatus *status);
@@ -81,7 +81,7 @@ OSStatus SecCodeGetStatus(SecCodeRef code, SecCSFlags flags, SecCodeStatus *stat
        @param status Upon successful return, contains the dynamic status of code as
        determined by its host.
        
        @param status Upon successful return, contains the dynamic status of code as
        determined by its host.
        
-       @result Upon success, noErr. Upon error, an OSStatus value documented in
+       @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in
        CSCommon.h or certain other Security framework headers.
  */
 typedef uint32_t SecCodeStatusOperation;
        CSCommon.h or certain other Security framework headers.
  */
 typedef uint32_t SecCodeStatusOperation;
@@ -117,7 +117,7 @@ OSStatus SecCodeSetStatus(SecCodeRef code, SecCodeStatusOperation operation,
        @param requirement On successful return, contains a copy of the internal requirement
                of the given type included in the given code. If the code has no such internal
                requirement, this argument is set to NULL (with no error).
        @param requirement On successful return, contains a copy of the internal requirement
                of the given type included in the given code. If the code has no such internal
                requirement, this argument is set to NULL (with no error).
-       @result On success, noErr. On error, an OSStatus value
+       @result On success, errSecSuccess. On error, an OSStatus value
                documented in CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecCodeCopyInternalRequirement(SecStaticCodeRef code, SecRequirementType type,
                documented in CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecCodeCopyInternalRequirement(SecStaticCodeRef code, SecRequirementType type,
@@ -137,7 +137,7 @@ OSStatus SecCodeCopyInternalRequirement(SecStaticCodeRef code, SecRequirementTyp
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param process On successful return, a SecCode object reference identifying
        the requesteed process.
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param process On successful return, a SecCode object reference identifying
        the requesteed process.
-       @result Upon success, noErr. Upon error, an OSStatus value documented in
+       @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in
        CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecCodeCreateWithPID(pid_t pid, SecCSFlags flags, SecCodeRef *process)
        CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecCodeCreateWithPID(pid_t pid, SecCSFlags flags, SecCodeRef *process)
index d5e7438fb7657fcea710a0a326cbfc03151b9381..33e380291c42552d82057694fe0ba21ddfc5b66c 100644 (file)
@@ -56,6 +56,7 @@ const CFStringRef kSecCodeSignerRequireTimestamp = CFSTR("timestamp-required");
 const CFStringRef kSecCodeSignerTimestampServer = CFSTR("timestamp-url");
 const CFStringRef kSecCodeSignerTimestampAuthentication = CFSTR("timestamp-authentication");
 const CFStringRef kSecCodeSignerTimestampOmitCertificates =    CFSTR("timestamp-omit-certificates");
 const CFStringRef kSecCodeSignerTimestampServer = CFSTR("timestamp-url");
 const CFStringRef kSecCodeSignerTimestampAuthentication = CFSTR("timestamp-authentication");
 const CFStringRef kSecCodeSignerTimestampOmitCertificates =    CFSTR("timestamp-omit-certificates");
+const CFStringRef kSecCodeSignerPreserveMetadata = CFSTR("preserve-metadata");
 
 // temporary add-back to bridge B&I build dependencies -- remove soon
 const CFStringRef kSecCodeSignerTSAUse = CFSTR("timestamp-required");
 
 // temporary add-back to bridge B&I build dependencies -- remove soon
 const CFStringRef kSecCodeSignerTSAUse = CFSTR("timestamp-required");
@@ -83,7 +84,13 @@ OSStatus SecCodeSignerCreate(CFDictionaryRef parameters, SecCSFlags flags,
 {
        BEGIN_CSAPI
                
 {
        BEGIN_CSAPI
                
-       checkFlags(flags, kSecCSRemoveSignature);
+       checkFlags(flags,
+                 kSecCSRemoveSignature
+               | kSecCSSignPreserveSignature
+               | kSecCSSignNestedCode
+               | kSecCSSignOpaque
+               | kSecCSSignV1
+               | kSecCSSignNoV1);
        SecPointer<SecCodeSigner> signer = new SecCodeSigner(flags);
        signer->parameters(parameters);
        CodeSigning::Required(signerRef) = signer->handle();
        SecPointer<SecCodeSigner> signer = new SecCodeSigner(flags);
        signer->parameters(parameters);
        CodeSigning::Required(signerRef) = signer->handle();
@@ -105,6 +112,7 @@ OSStatus SecCodeSignerAddSignatureWithErrors(SecCodeSignerRef signerRef,
        SecStaticCodeRef codeRef, SecCSFlags flags, CFErrorRef *errors)
 {
        BEGIN_CSAPI
        SecStaticCodeRef codeRef, SecCSFlags flags, CFErrorRef *errors)
 {
        BEGIN_CSAPI
+       checkFlags(flags);
        SecCodeSigner::required(signerRef)->sign(SecStaticCode::required(codeRef), flags);
     END_CSAPI_ERRORS
 }
        SecCodeSigner::required(signerRef)->sign(SecStaticCode::required(codeRef), flags);
     END_CSAPI_ERRORS
 }
index 42ad08993d2bacf9c56fdb7adcfd532c15ce89f4..b0c223834952b6f27e4c5c0ffd9913b365ea6f72 100644 (file)
@@ -154,12 +154,15 @@ extern const CFStringRef kSecCodeSignerTimestampAuthentication;
 extern const CFStringRef kSecCodeSignerRequireTimestamp;
 extern const CFStringRef kSecCodeSignerTimestampServer;
 extern const CFStringRef kSecCodeSignerTimestampOmitCertificates;
 extern const CFStringRef kSecCodeSignerRequireTimestamp;
 extern const CFStringRef kSecCodeSignerTimestampServer;
 extern const CFStringRef kSecCodeSignerTimestampOmitCertificates;
+extern const CFStringRef kSecCodeSignerPreserveMetadata;
 
 
-// temporary add-back to bridge B&I build dependencies -- remove soon
-extern const CFStringRef kSecCodeSignerTSAUse;
-extern const CFStringRef kSecCodeSignerTSAURL;
-extern const CFStringRef kSecCodeSignerTSAClientAuth;
-extern const CFStringRef kSecCodeSignerTSANoCerts;
+enum {
+    kSecCodeSignerPreserveIdentifier = 1 << 0,         // preserve signing identifier
+    kSecCodeSignerPreserveRequirements = 1 << 1,       // preserve internal requirements (including DR)
+    kSecCodeSignerPreserveEntitlements = 1 << 2,       // preserve entitlements
+    kSecCodeSignerPreserveResourceRules = 1 << 3,      // preserve resource rules (and thus resources)
+    kSecCodeSignerPreserveFlags = 1 << 4,                      // preserve signing flags
+};
 
 
 /*!
 
 
 /*!
@@ -175,11 +178,16 @@ extern const CFStringRef kSecCodeSignerTSANoCerts;
                from the target code instead of signing.
        @param staticCode On successful return, a SecStaticCode object reference representing
        the file system origin of the given SecCode. On error, unchanged.
                from the target code instead of signing.
        @param staticCode On successful return, a SecStaticCode object reference representing
        the file system origin of the given SecCode. On error, unchanged.
-       @result Upon success, noErr. Upon error, an OSStatus value documented in
+       @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in
        CSCommon.h or certain other Security framework headers.
 */
 enum {
        kSecCSRemoveSignature = 1 << 0,         // strip existing signature
        CSCommon.h or certain other Security framework headers.
 */
 enum {
        kSecCSRemoveSignature = 1 << 0,         // strip existing signature
+       kSecCSSignPreserveSignature = 1 << 1, // do not (re)sign if an embedded signature is already present
+       kSecCSSignNestedCode = 1 << 2,          // recursive (deep) signing
+       kSecCSSignOpaque = 1 << 3,                      // treat all files as resources (no nest scan, no flexibility)
+       kSecCSSignV1 = 1 << 4,                          // sign ONLY in V1 form
+       kSecCSSignNoV1 = 1 << 5,                        // do not include V1 form
 };
 
 
 };
 
 
@@ -198,10 +206,10 @@ OSStatus SecCodeSignerCreate(CFDictionaryRef parameters, SecCSFlags flags,
        the resulting signature data.
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param errors An optional pointer to a CFErrorRef variable. If the call fails
        the resulting signature data.
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param errors An optional pointer to a CFErrorRef variable. If the call fails
-       (and something other than noErr is returned), and this argument is non-NULL,
+       (and something other than errSecSuccess is returned), and this argument is non-NULL,
        a CFErrorRef is stored there further describing the nature and circumstances
        of the failure. The caller must CFRelease() this error object when done with it.
        a CFErrorRef is stored there further describing the nature and circumstances
        of the failure. The caller must CFRelease() this error object when done with it.
-       @result Upon success, noErr. Upon error, an OSStatus value documented in
+       @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in
        CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecCodeSignerAddSignature(SecCodeSignerRef signer,
        CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecCodeSignerAddSignature(SecCodeSignerRef signer,
index 68d95e45e8ab96b4be7777326cb08209d8e3f5ae..7414cec927e8a8239230b91c59548b5df5774ced 100644 (file)
@@ -228,6 +228,8 @@ OSStatus SecRequirementsCopyRequirements(CFDataRef requirementSet, SecCSFlags fl
        if (requirementSet == NULL)
                return errSecCSObjectRequired;
        const Requirements *reqs = (const Requirements *)CFDataGetBytePtr(requirementSet);
        if (requirementSet == NULL)
                return errSecCSObjectRequired;
        const Requirements *reqs = (const Requirements *)CFDataGetBytePtr(requirementSet);
+       if (!reqs->validateBlob())
+               MacOSError::throwMe(errSecCSReqInvalid);
        CFRef<CFMutableDictionaryRef> dict = makeCFMutableDictionary();
        unsigned count = reqs->count();
        for (unsigned n = 0; n < count; n++) {
        CFRef<CFMutableDictionaryRef> dict = makeCFMutableDictionary();
        unsigned count = reqs->count();
        for (unsigned n = 0; n < count; n++) {
index 9a11c6f999f34b54d62163af2544139dd2602856..dce6a83d804f589139cec83757a8e70344acc383 100644 (file)
@@ -64,7 +64,7 @@ CFTypeID SecRequirementGetTypeID(void);
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param requirement On successful return, contains a reference to a SecRequirement
        object that behaves identically to the one the data blob was obtained from.
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param requirement On successful return, contains a reference to a SecRequirement
        object that behaves identically to the one the data blob was obtained from.
-       @result Upon success, noErr. Upon error, an OSStatus value documented in
+       @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in
        CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecRequirementCreateWithData(CFDataRef data, SecCSFlags flags,
        CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecRequirementCreateWithData(CFDataRef data, SecCSFlags flags,
@@ -81,10 +81,10 @@ OSStatus SecRequirementCreateWithData(CFDataRef data, SecCSFlags flags,
        @param requirement On successful return, contains a reference to a SecRequirement
        object that implements the conditions described in text.
        @param errors An optional pointer to a CFErrorRef variable. If the call fails
        @param requirement On successful return, contains a reference to a SecRequirement
        object that implements the conditions described in text.
        @param errors An optional pointer to a CFErrorRef variable. If the call fails
-       (and something other than noErr is returned), and this argument is non-NULL,
+       (and something other than errSecSuccess is returned), and this argument is non-NULL,
        a CFErrorRef is stored there further describing the nature and circumstances
        of the failure. The caller must CFRelease() this error object when done with it.
        a CFErrorRef is stored there further describing the nature and circumstances
        of the failure. The caller must CFRelease() this error object when done with it.
-       @result Upon success, noErr. Upon error, an OSStatus value documented in
+       @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in
        CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecRequirementCreateWithString(CFStringRef text, SecCSFlags flags,
        CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecRequirementCreateWithString(CFStringRef text, SecCSFlags flags,
@@ -104,7 +104,7 @@ OSStatus SecRequirementCreateWithStringAndErrors(CFStringRef text, SecCSFlags fl
        @param data On successful return, contains a reference to a CFData object
        containing a binary blob that can be fed to SecRequirementCreateWithData
        to recreate a SecRequirement object with identical behavior.
        @param data On successful return, contains a reference to a CFData object
        containing a binary blob that can be fed to SecRequirementCreateWithData
        to recreate a SecRequirement object with identical behavior.
-       @result Upon success, noErr. Upon error, an OSStatus value documented in
+       @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in
        CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecRequirementCopyData(SecRequirementRef requirement, SecCSFlags flags,
        CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecRequirementCopyData(SecRequirementRef requirement, SecCSFlags flags,
@@ -126,7 +126,7 @@ OSStatus SecRequirementCopyData(SecRequirementRef requirement, SecCSFlags flags,
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param text On successful return, contains a reference to a CFString object
        containing a text representation of the requirement.
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param text On successful return, contains a reference to a CFString object
        containing a text representation of the requirement.
-       @result Upon success, noErr. Upon error, an OSStatus value documented in
+       @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in
        CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecRequirementCopyString(SecRequirementRef requirement, SecCSFlags flags,
        CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecRequirementCopyString(SecRequirementRef requirement, SecCSFlags flags,
index 44055769cdd548eff8916d603218caefa8997240..17dc575fd64b3b1748341660a08b8117bec1c547 100644 (file)
@@ -45,7 +45,7 @@ extern "C" {
        NULL requirements are not allowed in the dictionary.
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param requirementSet Upon success, receives a CFData object 
        NULL requirements are not allowed in the dictionary.
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param requirementSet Upon success, receives a CFData object 
-       @result Upon success, noErr. Upon error, an OSStatus value documented in
+       @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in
        CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecRequirementsCreateFromRequirements(CFDictionaryRef requirements, SecCSFlags flags,
        CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecRequirementsCreateFromRequirements(CFDictionaryRef requirements, SecCSFlags flags,
@@ -62,7 +62,7 @@ OSStatus SecRequirementsCreateFromRequirements(CFDictionaryRef requirements, Sec
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param requirements Upon success, a dictionary containing each requirement contained
        in requirementSet. The keys are CFNumbers indicating the requirement type.
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param requirements Upon success, a dictionary containing each requirement contained
        in requirementSet. The keys are CFNumbers indicating the requirement type.
-       @result Upon success, noErr. Upon error, an OSStatus value documented in
+       @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in
        CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecRequirementsCopyRequirements(CFDataRef requirementSet, SecCSFlags flags,
        CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecRequirementsCopyRequirements(CFDataRef requirementSet, SecCSFlags flags,
@@ -81,10 +81,10 @@ OSStatus SecRequirementsCopyRequirements(CFDataRef requirementSet, SecCSFlags fl
        the result of parsing text. Depending on the input string and flags, the result
        can be a SecRequirementRef (for a single requirement) or a CFDataRef for a requirement set.
        @param errors An optional pointer to a CFErrorRef variable. If the call fails
        the result of parsing text. Depending on the input string and flags, the result
        can be a SecRequirementRef (for a single requirement) or a CFDataRef for a requirement set.
        @param errors An optional pointer to a CFErrorRef variable. If the call fails
-       (and something other than noErr is returned), and this argument is non-NULL,
+       (and something other than errSecSuccess is returned), and this argument is non-NULL,
        a CFErrorRef is stored there further describing the nature and circumstances
        of the failure. The caller must CFRelease() this error object when done with it.
        a CFErrorRef is stored there further describing the nature and circumstances
        of the failure. The caller must CFRelease() this error object when done with it.
-       @result Upon success, noErr. Upon error, an OSStatus value documented in
+       @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in
        CSCommon.h or certain other Security framework headers.
 */
 enum {
        CSCommon.h or certain other Security framework headers.
 */
 enum {
@@ -114,7 +114,7 @@ OSStatus SecRequirementsCreateWithString(CFStringRef text, SecCSFlags flags,
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param text On successful return, contains a reference to a CFString object
        containing a text representation of the requirement.
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param text On successful return, contains a reference to a CFString object
        containing a text representation of the requirement.
-       @result Upon success, noErr. Upon error, an OSStatus value documented in
+       @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in
        CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecRequirementsCopyString(CFTypeRef input, SecCSFlags flags, CFStringRef *text);
        CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecRequirementsCopyString(CFTypeRef input, SecCSFlags flags, CFStringRef *text);
@@ -130,7 +130,7 @@ OSStatus SecRequirementsCopyString(CFTypeRef input, SecCSFlags flags, CFStringRe
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param requirement On successful return, contains a reference to a SecRequirement
        object that behaves identically to the one the data blob was obtained from.
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param requirement On successful return, contains a reference to a SecRequirement
        object that behaves identically to the one the data blob was obtained from.
-       @result Upon success, noErr. Upon error, an OSStatus value documented in
+       @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in
        CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecRequirementCreateWithResource(CFURLRef resource, SecCSFlags flags,
        CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecRequirementCreateWithResource(CFURLRef resource, SecCSFlags flags,
@@ -151,7 +151,7 @@ OSStatus SecRequirementCreateWithResource(CFURLRef resource, SecCSFlags flags,
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param requirement On successful return, contains a reference to a SecRequirement
        object that requires group membership to pass validation.
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param requirement On successful return, contains a reference to a SecRequirement
        object that requires group membership to pass validation.
-       @result Upon success, noErr. Upon error, an OSStatus value documented in
+       @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in
        CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecRequirementCreateGroup(CFStringRef groupName, SecCertificateRef anchor,
        CSCommon.h or certain other Security framework headers.
 */
 OSStatus SecRequirementCreateGroup(CFStringRef groupName, SecCertificateRef anchor,
@@ -171,7 +171,7 @@ OSStatus SecRequirementCreateGroup(CFStringRef groupName, SecCertificateRef anch
        @param context An optional CFDictionary containing additional context made available
        to the requirement program's evaluation. NULL is equivalent to an empty dictionary.
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param context An optional CFDictionary containing additional context made available
        to the requirement program's evaluation. NULL is equivalent to an empty dictionary.
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
-       @result Upon success, noErr. Failure to pass the check returns errSecCSReqFailed.
+       @result Upon success, errSecSuccess. Failure to pass the check returns errSecCSReqFailed.
        All other returns indicate errors as documented in CSCommon.h or certain other
        Security framework headers.
        
        All other returns indicate errors as documented in CSCommon.h or certain other
        Security framework headers.
        
index 7cb5a17e6613030822852dc47fc6b098fdcf686e..f0a67ccccc0894367b6ef817107a8f25054bdf31 100644 (file)
@@ -60,6 +60,7 @@ OSStatus SecStaticCodeCreateWithPath(CFURLRef path, SecCSFlags flags, SecStaticC
 const CFStringRef kSecCodeAttributeArchitecture =      CFSTR("architecture");
 const CFStringRef kSecCodeAttributeSubarchitecture =CFSTR("subarchitecture");
 const CFStringRef kSecCodeAttributeBundleVersion =     CFSTR("bundleversion");
 const CFStringRef kSecCodeAttributeArchitecture =      CFSTR("architecture");
 const CFStringRef kSecCodeAttributeSubarchitecture =CFSTR("subarchitecture");
 const CFStringRef kSecCodeAttributeBundleVersion =     CFSTR("bundleversion");
+const CFStringRef kSecCodeAttributeUniversalFileOffset =       CFSTR("UniversalFileOffset");
 
 OSStatus SecStaticCodeCreateWithPathAndAttributes(CFURLRef path, SecCSFlags flags, CFDictionaryRef attributes,
        SecStaticCodeRef *staticCodeRef)
 
 OSStatus SecStaticCodeCreateWithPathAndAttributes(CFURLRef path, SecCSFlags flags, CFDictionaryRef attributes,
        SecStaticCodeRef *staticCodeRef)
@@ -71,8 +72,10 @@ OSStatus SecStaticCodeCreateWithPathAndAttributes(CFURLRef path, SecCSFlags flag
        std::string version; // holds memory placed into ctx
        if (attributes) {
                std::string archName;
        std::string version; // holds memory placed into ctx
        if (attributes) {
                std::string archName;
-               int archNumber, subarchNumber;
-               if (cfscan(attributes, "{%O=%s}", kSecCodeAttributeArchitecture, &archName)) {
+               int archNumber, subarchNumber, offset;
+               if (cfscan(attributes, "{%O=%d}", kSecCodeAttributeUniversalFileOffset, &offset)) {
+                       ctx.offset = offset;
+               } else if (cfscan(attributes, "{%O=%s}", kSecCodeAttributeArchitecture, &archName)) {
                        ctx.arch = Architecture(archName.c_str());
                } else if (cfscan(attributes, "{%O=%d,%O=%d}",
                                kSecCodeAttributeArchitecture, &archNumber, kSecCodeAttributeSubarchitecture, &subarchNumber))
                        ctx.arch = Architecture(archName.c_str());
                } else if (cfscan(attributes, "{%O=%d,%O=%d}",
                                kSecCodeAttributeArchitecture, &archNumber, kSecCodeAttributeSubarchitecture, &subarchNumber))
@@ -92,85 +95,6 @@ OSStatus SecStaticCodeCreateWithPathAndAttributes(CFURLRef path, SecCSFlags flag
 //
 // Check static validity of a StaticCode
 //
 //
 // Check static validity of a StaticCode
 //
-static void validate(SecStaticCode *code, const SecRequirement *req, SecCSFlags flags);
-static void validateNested(string location, const SecRequirement *req, SecCSFlags flags, string exclude = "/");
-
-static void validate(SecStaticCode *code, const SecRequirement *req, SecCSFlags flags)
-{
-       try {
-               code->validateNonResourceComponents();  // also validates the CodeDirectory
-               if (!(flags & kSecCSDoNotValidateExecutable))
-                       code->validateExecutable();
-               if (!(flags & kSecCSDoNotValidateResources))
-                       code->validateResources();
-               if (req)
-                       code->validateRequirement(req->requirement(), errSecCSReqFailed);
-               if (flags & kSecCSCheckNestedCode)
-                       if (CFURLRef baseUrl = code->resourceBase()) {
-                               // CFBundle has no orderly enumerator of these things, so this is somewhat ad-hoc.
-                               // (It should be augmented by information in ResourceDirectory.)
-                               string base = cfString(baseUrl) + "/";
-                               validateNested(base + "Frameworks", req, flags);
-                               validateNested(base + "SharedFrameworks", req, flags);
-                               validateNested(base + "PlugIns", req, flags);
-                               validateNested(base + "Plug-ins", req, flags);
-                               validateNested(base + "XPCServices", req, flags);
-                               validateNested(base + "MacOS", req, flags, code->mainExecutablePath()); // helpers
-                       }
-       } catch (CSError &err) {
-               if (Universal *fat = code->diskRep()->mainExecutableImage())    // Mach-O
-                       if (MachO *mach = fat->architecture()) {
-                               err.augment(kSecCFErrorArchitecture, CFTempString(mach->architecture().displayName()));
-                               delete mach;
-                       }
-               throw;
-       } catch (const MacOSError &err) {
-               // add architecture information if we can get it
-               if (Universal *fat = code->diskRep()->mainExecutableImage())
-                       if (MachO *mach = fat->architecture()) {
-                               CFTempString arch(mach->architecture().displayName());
-                               delete mach;
-                               CSError::throwMe(err.error, kSecCFErrorArchitecture, arch);
-                       }
-               // else just pass it on
-               throw;
-       }
-}
-
-static void validateNested(string location, const SecRequirement *req, SecCSFlags flags, string exclude)
-{
-       DIR *dir = opendir(location.c_str());
-       if (dir == 0) {
-               if (errno == ENOENT)    // nothing there (okay)
-                       return;
-               UnixError::throwMe();
-       }
-       while (struct dirent *dp = readdir(dir)) {
-               switch (dp->d_type) {
-               case DT_REG:
-               case DT_LNK:
-               case DT_DIR:
-                       break;
-               default:
-                       continue;
-               }
-               if (dp->d_name[0] == '.')
-                       continue;
-               string path = location + "/" + dp->d_name;
-               if (path == exclude)    // main executable; skip
-                       continue;
-               try {
-                       SecPointer<SecStaticCode> code = new SecStaticCode(DiskRep::bestGuess(path));
-                       validate(code, req, flags);
-               } catch (CSError &err) {
-                       err.augment(kSecCFErrorPath, CFTempURL(path));
-                       throw;
-               }
-       }
-       closedir(dir);
-}
-
-
 OSStatus SecStaticCodeCheckValidity(SecStaticCodeRef staticCodeRef, SecCSFlags flags,
        SecRequirementRef requirementRef)
 {
 OSStatus SecStaticCodeCheckValidity(SecStaticCodeRef staticCodeRef, SecCSFlags flags,
        SecRequirementRef requirementRef)
 {
@@ -193,12 +117,7 @@ OSStatus SecStaticCodeCheckValidityWithErrors(SecStaticCodeRef staticCodeRef, Se
        SecPointer<SecStaticCode> code = SecStaticCode::requiredStatic(staticCodeRef);
        const SecRequirement *req = SecRequirement::optional(requirementRef);
        DTRACK(CODESIGN_EVAL_STATIC, code, (char*)code->mainExecutablePath().c_str());
        SecPointer<SecStaticCode> code = SecStaticCode::requiredStatic(staticCodeRef);
        const SecRequirement *req = SecRequirement::optional(requirementRef);
        DTRACK(CODESIGN_EVAL_STATIC, code, (char*)code->mainExecutablePath().c_str());
-       if (flags & kSecCSCheckAllArchitectures) {
-               SecStaticCode::AllArchitectures archs(code);
-               while (SecPointer<SecStaticCode> scode = archs())
-                       validate(scode, req, flags);
-       } else
-               validate(code, req, flags);
+       code->staticValidate(flags, req);
 
        END_CSAPI_ERRORS
 }
 
        END_CSAPI_ERRORS
 }
@@ -273,8 +192,6 @@ OSStatus SecCodeSetDetachedSignature(SecStaticCodeRef codeRef, CFDataRef signatu
        checkFlags(flags);
        SecPointer<SecStaticCode> code = SecStaticCode::requiredStatic(codeRef);
 
        checkFlags(flags);
        SecPointer<SecStaticCode> code = SecStaticCode::requiredStatic(codeRef);
 
-       if (signature)
-               CFRetain(signature);    // own a reference...
        code->detachedSignature(signature); // ... and pass it to the code
        code->resetValidity();
 
        code->detachedSignature(signature); // ... and pass it to the code
        code->resetValidity();
 
@@ -299,3 +216,20 @@ OSStatus SecCodeMapMemory(SecStaticCodeRef codeRef, SecCSFlags flags)
 
        END_CSAPI
 }
 
        END_CSAPI
 }
+
+
+//
+// Attach a callback block to a code object
+//
+OSStatus SecStaticCodeSetCallback(SecStaticCodeRef codeRef, SecCSFlags flags, SecCodeCallback *old, SecCodeCallback monitor)
+{
+       BEGIN_CSAPI
+
+       checkFlags(flags);
+       SecStaticCode *code = SecStaticCode::requiredStatic(codeRef);
+       if (old)
+               *old = code->monitor();
+       code->setMonitor(monitor);
+
+       END_CSAPI
+}
index 8d0f68a94793e66549f471d59a82f674f24d97ce..ba083b41f4bc16bd2fada1197ad6bc8b43a20b32 100644 (file)
@@ -73,7 +73,7 @@ CFTypeID SecStaticCodeGetTypeID(void);
        @param attributes A CFDictionary containing additional attributes of the code sought.
        @param staticCode On successful return, contains a reference to the StaticCode object
        representing the code at path. Unchanged on error.
        @param attributes A CFDictionary containing additional attributes of the code sought.
        @param staticCode On successful return, contains a reference to the StaticCode object
        representing the code at path. Unchanged on error.
-       @result Upon success, noErr. Upon error, an OSStatus value documented in
+       @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in
        CSCommon.h or certain other Security framework headers.
        
        @constant kSecCodeAttributeArchitecture Specifies the Mach-O architecture of code desired.
        CSCommon.h or certain other Security framework headers.
        
        @constant kSecCodeAttributeArchitecture Specifies the Mach-O architecture of code desired.
@@ -85,9 +85,11 @@ CFTypeID SecStaticCodeGetTypeID(void);
        (using the kSecCodeAttributeArchitecture key), specifies any sub-architecture by number.
        This key is ignored if no main architecture is specified; if it is specified by name; or
        if the code is not in Mach-O form.
        (using the kSecCodeAttributeArchitecture key), specifies any sub-architecture by number.
        This key is ignored if no main architecture is specified; if it is specified by name; or
        if the code is not in Mach-O form.
+       @constant kSecCodeAttributeUniversalFileOffset The offset of a Mach-O specific slice of a universal Mach-O file.
 */
 extern const CFStringRef kSecCodeAttributeArchitecture;
 extern const CFStringRef kSecCodeAttributeSubarchitecture;
 */
 extern const CFStringRef kSecCodeAttributeArchitecture;
 extern const CFStringRef kSecCodeAttributeSubarchitecture;
+extern const CFStringRef kSecCodeAttributeUniversalFileOffset;
 extern const CFStringRef kSecCodeAttributeBundleVersion;
 
 OSStatus SecStaticCodeCreateWithPath(CFURLRef path, SecCSFlags flags, SecStaticCodeRef *staticCode);
 extern const CFStringRef kSecCodeAttributeBundleVersion;
 
 OSStatus SecStaticCodeCreateWithPath(CFURLRef path, SecCSFlags flags, SecStaticCodeRef *staticCode);
@@ -128,10 +130,10 @@ OSStatus SecStaticCodeCreateWithPathAndAttributes(CFURLRef path, SecCSFlags flag
        the staticCode object must satisfy to be considered valid. If NULL, no additional
        requirements are imposed.
        @param errors An optional pointer to a CFErrorRef variable. If the call fails
        the staticCode object must satisfy to be considered valid. If NULL, no additional
        requirements are imposed.
        @param errors An optional pointer to a CFErrorRef variable. If the call fails
-       (something other than noErr is returned), and this argument is non-NULL,
+       (something other than errSecSuccess is returned), and this argument is non-NULL,
        a CFErrorRef is stored there further describing the nature and circumstances
        of the failure. The caller must CFRelease() this error object when done with it.
        a CFErrorRef is stored there further describing the nature and circumstances
        of the failure. The caller must CFRelease() this error object when done with it.
-       @result If validation succeeds, noErr. If validation fails, an OSStatus value
+       @result If validation succeeds, errSecSuccess. If validation fails, an OSStatus value
        documented in CSCommon.h or certain other Security framework headers.
 */
 enum {
        documented in CSCommon.h or certain other Security framework headers.
 */
 enum {
index 1f0d74c5d17219e43590e1b9536e8fcd55f1b1db..e40f0dfa120b7d98492042c22fff89e331d215d0 100644 (file)
@@ -37,8 +37,26 @@ extern "C" {
 
 
 /*
 
 
 /*
- * Currently empty
+       @function SecCodeSetCallback
+       For a given Code or StaticCode object, specify a block that is invoked at certain
+       stages of a validation operation. The block is only invoked for validations of this
+       particular object. Note that validation outcomes are cached in the API object, and
+       repeated validations will not generally result in the same set of callbacks.
+       Only one callback can be active for each API object. A new call to SecCodeSetCallback
+       replaces the previous callback.
+       
+       @param code A Code or StaticCode object whose validation should be monitored.
+       @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
+       @param old A pointer to a block pointer that receives any previously registered callback.
+               Pass NULL if you are not interested in any previous value.
+       @param callback A block to be synchronously invoked at certain stages of API operation.
+               Pass NULL to disable callbacks for this code object. The block must be available to
+               be invoked, possibly repeatedly, for as long as the code object exists or it is superseded
+               by another call to this API, whichever happens earlier.
+               From your block, return NULL to continue normal operation. Return a CFTypeRef object of
+               suitable value for the reported stage to intervene.
  */
  */
+OSStatus SecStaticCodeSetCallback(SecStaticCodeRef code, SecCSFlags flag, SecCodeCallback *olds, SecCodeCallback callback);
 
 
 #ifdef __cplusplus
 
 
 #ifdef __cplusplus
index cb01bbb42231a7fe70893b455c83236c2119799a..e30eb909440be3f7c5e2e791552d8aadbe81ba5d 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2009 Apple Inc. All rights reserved.
+ * Copyright (c) 2009-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 
 #include <CoreFoundation/CoreFoundation.h>
 #include <CoreFoundation/CFRuntime.h>
 
 #include <CoreFoundation/CoreFoundation.h>
 #include <CoreFoundation/CFRuntime.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
-
 #include <IOKit/IOKitLib.h>
 #include <IOKit/IOCFUnserialize.h>
 #include <IOKit/IOKitLib.h>
 #include <IOKit/IOCFUnserialize.h>
-
 #include <System/sys/codesign.h>
 #include <System/sys/codesign.h>
-
+#include <bsm/libbsm.h>
+#include <inttypes.h>
 #include <pthread.h>
 #include <pthread.h>
+#include <sys/sysctl.h>
 
 
-#include <bsm/libbsm.h>
+#include "SecCode.h"
+#include "SecCodePriv.h"
+#include "SecRequirement.h"
 
 #include "SecTask.h"
 
 #include "SecTask.h"
+#include "SecTaskPriv.h"
+
 
 struct __SecTask {
        CFRuntimeBase base;
 
        pid_t pid;
 
 
 struct __SecTask {
        CFRuntimeBase base;
 
        pid_t pid;
 
+       audit_token_t *token;
+       audit_token_t token_storage;
+
        /* Track whether we've loaded entitlements independently since after the
         * load, entitlements may legitimately be NULL */
        Boolean entitlementsLoaded;
        /* Track whether we've loaded entitlements independently since after the
         * load, entitlements may legitimately be NULL */
        Boolean entitlementsLoaded;
@@ -64,11 +70,23 @@ static void SecTaskFinalize(CFTypeRef cfTask)
        }
 }
 
        }
 }
 
+
+// Define PRIdPID (proper printf format string for pid_t)
+#define PRIdPID PRId32
+
 static CFStringRef SecTaskCopyDebugDescription(CFTypeRef cfTask)
 {
 static CFStringRef SecTaskCopyDebugDescription(CFTypeRef cfTask)
 {
-       SecTaskRef task = (SecTaskRef) cfTask;
-
-       return CFStringCreateWithFormat(CFGetAllocator(task), NULL, CFSTR("<SecTask %p>"), task);
+    SecTaskRef task = (SecTaskRef) cfTask;
+    const char *task_name;
+    int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, task->pid};
+    struct kinfo_proc kp;
+    size_t len = sizeof(kp);
+    if (sysctl(mib, 4, &kp, &len, NULL, 0) == -1 || len == 0)
+        task_name = strerror(errno);
+    else
+        task_name = kp.kp_proc.p_comm;
+
+    return CFStringCreateWithFormat(CFGetAllocator(task), NULL, CFSTR("%s[%" PRIdPID "]"), task_name, task->pid);
 }
 
 static void SecTaskRegisterClass(void)
 }
 
 static void SecTaskRegisterClass(void)
@@ -109,23 +127,21 @@ static SecTaskRef SecTaskCreateWithPID(CFAllocatorRef allocator, pid_t pid)
        }
 
        return task;
        }
 
        return task;
-
 }
 
 SecTaskRef SecTaskCreateWithAuditToken(CFAllocatorRef allocator, audit_token_t token)
 {
 }
 
 SecTaskRef SecTaskCreateWithAuditToken(CFAllocatorRef allocator, audit_token_t token)
 {
-       pid_t pid;
+       SecTaskRef task;
 
 
-       audit_token_to_au32(token,
-                           /* auidp */ NULL,
-                           /* euidp */ NULL,
-                           /* egidp */ NULL,
-                           /* ruidp */ NULL,
-                           /* rgidp */ NULL,
-                           /* pidp  */ &pid,
-                           /* asidp */ NULL,
-                           /* tidp  */ NULL);
-       return SecTaskCreateWithPID(allocator, pid);
+       task = SecTaskCreateWithPID(allocator, audit_token_to_pid(token));
+       if (task != NULL) {
+#if 0
+               task->token_storage = token;
+               task->token = &task->token_storage;
+#endif
+       }
+
+       return task;
 }
 
 SecTaskRef SecTaskCreateFromSelf(CFAllocatorRef allocator)
 }
 
 SecTaskRef SecTaskCreateFromSelf(CFAllocatorRef allocator)
@@ -133,6 +149,38 @@ SecTaskRef SecTaskCreateFromSelf(CFAllocatorRef allocator)
        return SecTaskCreateWithPID(allocator, getpid());
 }
 
        return SecTaskCreateWithPID(allocator, getpid());
 }
 
+/*
+ * Determine if the given task meets a specified requirement.
+ */
+OSStatus
+SecTaskValidateForRequirement(SecTaskRef task, CFStringRef requirement)
+{
+    OSStatus status;
+    SecCodeRef code = NULL;
+    SecRequirementRef req = NULL;
+    pid_t pid = task->pid;
+    if (pid <= 0) {
+        return errSecParam;
+    }
+    status = SecCodeCreateWithPID(pid, kSecCSDefaultFlags, &code);
+    //syslog(LOG_NOTICE, "SecTaskValidateForRequirement: SecCodeCreateWithPID=%d", status);
+    if (!status) {
+        status = SecRequirementCreateWithString(requirement,
+                                                kSecCSDefaultFlags, &req);
+        //syslog(LOG_NOTICE, "SecTaskValidateForRequirement: SecRequirementCreateWithString=%d", status);
+    }
+    if (!status) {
+        status = SecCodeCheckValidity(code, kSecCSDefaultFlags, req);
+        //syslog(LOG_NOTICE, "SecTaskValidateForRequirement: SecCodeCheckValidity=%d", status);
+    }
+    if (req)
+        CFRelease(req);
+    if (code)
+        CFRelease(code);
+
+    return status;
+}
+
 static CFRange myMakeRange(CFIndex loc, CFIndex len) {
        CFRange r = {.location = loc, .length = len };
        return r;
 static CFRange myMakeRange(CFIndex loc, CFIndex len) {
        CFRange r = {.location = loc, .length = len };
        return r;
@@ -142,6 +190,15 @@ struct csheader {
        uint32_t length;
 };
 
        uint32_t length;
 };
 
+static int
+csops_task(SecTaskRef task, int ops, void *blob, size_t size)
+{
+       if (task->token)
+               return csops_audittoken(task->pid, ops, blob, size, task->token);
+       else
+               return csops(task->pid, ops, blob, size);
+}
+
 static int SecTaskLoadEntitlements(SecTaskRef task, CFErrorRef *error)
 {
        CFMutableDataRef data = NULL;
 static int SecTaskLoadEntitlements(SecTaskRef task, CFErrorRef *error)
 {
        CFMutableDataRef data = NULL;
@@ -149,7 +206,7 @@ static int SecTaskLoadEntitlements(SecTaskRef task, CFErrorRef *error)
        uint32_t bufferlen;
        int ret;
 
        uint32_t bufferlen;
        int ret;
 
-       ret = csops(task->pid, CS_OPS_ENTITLEMENTS_BLOB, &header, sizeof(header));
+       ret = csops_task(task, CS_OPS_ENTITLEMENTS_BLOB, &header, sizeof(header));
        if (ret != -1 || errno != ERANGE) {
                /* no entitlements */
                task->entitlementsLoaded = true;
        if (ret != -1 || errno != ERANGE) {
                /* no entitlements */
                task->entitlementsLoaded = true;
@@ -168,7 +225,7 @@ static int SecTaskLoadEntitlements(SecTaskRef task, CFErrorRef *error)
                goto out;
        }
        CFDataSetLength(data, bufferlen);
                goto out;
        }
        CFDataSetLength(data, bufferlen);
-       ret = csops(task->pid, CS_OPS_ENTITLEMENTS_BLOB, CFDataGetMutableBytePtr(data), bufferlen);
+       ret = csops_task(task, CS_OPS_ENTITLEMENTS_BLOB, CFDataGetMutableBytePtr(data), bufferlen);
        if (ret) {
                ret = errno;
                goto out;
        if (ret) {
                ret = errno;
                goto out;
diff --git a/libsecurity_codesigning/lib/SecTaskPriv.h b/libsecurity_codesigning/lib/SecTaskPriv.h
new file mode 100644 (file)
index 0000000..80bc047
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013 Apple Inc. All Rights Reserved.
+ * 
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef _SECURITY_SECTASKPRIV_H_
+#define _SECURITY_SECTASKPRIV_H_
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecTask.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*!
+    @function SecTaskValidateForRequirement
+    @abstract Validate a SecTask instance for a specified requirement.
+    @param task The SecTask instance to validate.
+    @param requirement A requirement string to be validated.
+    @result An error code of type OSStatus. Returns errSecSuccess if the
+    task satisfies the requirement.
+*/
+OSStatus SecTaskValidateForRequirement(SecTaskRef task, CFStringRef requirement);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_SECURITY_SECTASKPRIV_H_ */
index 7c51c792cce91acc10d62b98a5ac4107d68da317..a26a1fee33a0456ad3426013d744b12c3c17d63a 100644 (file)
@@ -29,9 +29,9 @@
 #include "reqmaker.h"
 #include "drmaker.h"
 #include "reqdumper.h"
 #include "reqmaker.h"
 #include "drmaker.h"
 #include "reqdumper.h"
+#include "reqparser.h"
 #include "sigblob.h"
 #include "resources.h"
 #include "sigblob.h"
 #include "resources.h"
-#include "renum.h"
 #include "detachedrep.h"
 #include "csdatabase.h"
 #include "csutilities.h"
 #include "detachedrep.h"
 #include "csdatabase.h"
 #include "csutilities.h"
@@ -55,13 +55,29 @@ namespace CodeSigning {
 using namespace UnixPlusPlus;
 
 
 using namespace UnixPlusPlus;
 
 
+//
+// Map a component slot number to a suitable error code for a failure
+//
+static inline OSStatus errorForSlot(CodeDirectory::SpecialSlot slot)
+{
+       switch (slot) {
+       case cdInfoSlot:
+               return errSecCSInfoPlistFailed;
+       case cdResourceDirSlot:
+               return errSecCSResourceDirectoryFailed;
+       default:
+               return errSecCSSignatureFailed;
+       }
+}
+
+
 //
 // Construct a SecStaticCode object given a disk representation object
 //
 SecStaticCode::SecStaticCode(DiskRep *rep)
        : mRep(rep),
          mValidated(false), mExecutableValidated(false), mResourcesValidated(false), mResourcesValidContext(NULL),
 //
 // Construct a SecStaticCode object given a disk representation object
 //
 SecStaticCode::SecStaticCode(DiskRep *rep)
        : mRep(rep),
          mValidated(false), mExecutableValidated(false), mResourcesValidated(false), mResourcesValidContext(NULL),
-         mDesignatedReq(NULL), mGotResourceBase(false), mEvalDetails(NULL)
+         mDesignatedReq(NULL), mGotResourceBase(false), mMonitor(NULL), mEvalDetails(NULL)
 {
        CODESIGN_STATIC_CREATE(this, rep);
        checkForSystemSignature();
 {
        CODESIGN_STATIC_CREATE(this, rep);
        checkForSystemSignature();
@@ -105,15 +121,29 @@ CFHashCode SecStaticCode::hash()
 }
 
 
 }
 
 
+//
+// Invoke a stage monitor if registered
+//
+CFTypeRef SecStaticCode::reportEvent(CFStringRef stage, CFDictionaryRef info)
+{
+       if (mMonitor)
+               return mMonitor(this->handle(false), stage, info);
+       else
+               return NULL;
+}
+
+
 //
 // Attach a detached signature.
 //
 void SecStaticCode::detachedSignature(CFDataRef sigData)
 {
        if (sigData) {
 //
 // Attach a detached signature.
 //
 void SecStaticCode::detachedSignature(CFDataRef sigData)
 {
        if (sigData) {
+               mDetachedSig = sigData;
                mRep = new DetachedRep(sigData, mRep->base(), "explicit detached");
                CODESIGN_STATIC_ATTACH_EXPLICIT(this, mRep);
        } else {
                mRep = new DetachedRep(sigData, mRep->base(), "explicit detached");
                CODESIGN_STATIC_ATTACH_EXPLICIT(this, mRep);
        } else {
+               mDetachedSig = NULL;
                mRep = mRep->base();
                CODESIGN_STATIC_ATTACH_EXPLICIT(this, NULL);
        }
                mRep = mRep->base();
                CODESIGN_STATIC_ATTACH_EXPLICIT(this, NULL);
        }
@@ -127,14 +157,17 @@ void SecStaticCode::detachedSignature(CFDataRef sigData)
 //
 void SecStaticCode::checkForSystemSignature()
 {
 //
 void SecStaticCode::checkForSystemSignature()
 {
-       if (!this->isSigned())
-               try {
-                       if (RefPointer<DiskRep> dsig = signatureDatabase().findCode(mRep)) {
-                               CODESIGN_STATIC_ATTACH_SYSTEM(this, dsig);
-                               mRep = dsig;
+       if (!this->isSigned()) {
+               SignatureDatabase db;
+               if (db.isOpen())
+                       try {
+                               if (RefPointer<DiskRep> dsig = db.findCode(mRep)) {
+                                       CODESIGN_STATIC_ATTACH_SYSTEM(this, dsig);
+                                       mRep = dsig;
+                               }
+                       } catch (...) {
                        }
                        }
-               } catch (...) {
-               }
+       }
 }
 
 
 }
 
 
@@ -189,8 +222,7 @@ void SecStaticCode::resetValidity()
 {
        CODESIGN_EVAL_STATIC_RESET(this);
        mValidated = false;
 {
        CODESIGN_EVAL_STATIC_RESET(this);
        mValidated = false;
-       mExecutableValidated = false;
-       mResourcesValidated = false;
+       mExecutableValidated = mResourcesValidated = false;
        if (mResourcesValidContext) {
                delete mResourcesValidContext;
                mResourcesValidContext = NULL;
        if (mResourcesValidContext) {
                delete mResourcesValidContext;
                mResourcesValidContext = NULL;
@@ -230,12 +262,12 @@ CFDataRef SecStaticCode::component(CodeDirectory::SpecialSlot slot, OSStatus fai
                        if (validated()) // if the directory has been validated...
                                if (!codeDirectory()->validateSlot(CFDataGetBytePtr(data), // ... and it's no good
                                                CFDataGetLength(data), -slot))
                        if (validated()) // if the directory has been validated...
                                if (!codeDirectory()->validateSlot(CFDataGetBytePtr(data), // ... and it's no good
                                                CFDataGetLength(data), -slot))
-                                       MacOSError::throwMe(fail); // ... then bail
+                                       MacOSError::throwMe(errorForSlot(slot)); // ... then bail
                        cache = data;   // it's okay, cache it
                } else {        // absent, mark so
                        if (validated())        // if directory has been validated...
                                if (codeDirectory()->slotIsPresent(-slot)) // ... and the slot is NOT missing
                        cache = data;   // it's okay, cache it
                } else {        // absent, mark so
                        if (validated())        // if directory has been validated...
                                if (codeDirectory()->slotIsPresent(-slot)) // ... and the slot is NOT missing
-                                       MacOSError::throwMe(fail);      // was supposed to be there
+                                       MacOSError::throwMe(errorForSlot(slot));        // was supposed to be there
                        cache = CFDataRef(kCFNull);             // white lie
                }
        }
                        cache = CFDataRef(kCFNull);             // white lie
                }
        }
@@ -311,12 +343,11 @@ void SecStaticCode::validateDirectory()
                        // perform validation (or die trying)
                        CODESIGN_EVAL_STATIC_DIRECTORY(this);
                        mValidationExpired = verifySignature();
                        // perform validation (or die trying)
                        CODESIGN_EVAL_STATIC_DIRECTORY(this);
                        mValidationExpired = verifySignature();
-                       component(cdInfoSlot, errSecCSInfoPlistFailed); // force load of Info Dictionary (if any)
                        for (CodeDirectory::SpecialSlot slot = codeDirectory()->maxSpecialSlot(); slot >= 1; --slot)
                                if (mCache[slot])       // if we already loaded that resource...
                        for (CodeDirectory::SpecialSlot slot = codeDirectory()->maxSpecialSlot(); slot >= 1; --slot)
                                if (mCache[slot])       // if we already loaded that resource...
-                                       validateComponent(slot); // ... then check it now
+                                       validateComponent(slot, errorForSlot(slot)); // ... then check it now
                        mValidated = true;                      // we've done the deed...
                        mValidated = true;                      // we've done the deed...
-                       mValidationResult = noErr;      // ... and it was good
+                       mValidationResult = errSecSuccess;      // ... and it was good
                } catch (const CommonError &err) {
                        mValidated = true;
                        mValidationResult = err.osStatus();
                } catch (const CommonError &err) {
                        mValidated = true;
                        mValidationResult = err.osStatus();
@@ -328,7 +359,7 @@ void SecStaticCode::validateDirectory()
                        throw;
                }
        assert(validated());
                        throw;
                }
        assert(validated());
-       if (mValidationResult == noErr) {
+       if (mValidationResult == errSecSuccess) {
                if (mValidationExpired)
                        if ((apiFlags() & kSecCSConsiderExpiration)
                                        || (codeDirectory()->flags & kSecCodeSignatureForceExpiration))
                if (mValidationExpired)
                        if ((apiFlags() & kSecCSConsiderExpiration)
                                        || (codeDirectory()->flags & kSecCodeSignatureForceExpiration))
@@ -414,7 +445,7 @@ bool SecStaticCode::verifySignature()
        // internal signing time (as specified by the signer; optional)
        mSigningTime = 0;       // "not present" marker (nobody could code sign on Jan 1, 2001 :-)
        switch (OSStatus rc = CMSDecoderCopySignerSigningTime(cms, 0, &mSigningTime)) {
        // internal signing time (as specified by the signer; optional)
        mSigningTime = 0;       // "not present" marker (nobody could code sign on Jan 1, 2001 :-)
        switch (OSStatus rc = CMSDecoderCopySignerSigningTime(cms, 0, &mSigningTime)) {
-       case noErr:
+       case errSecSuccess:
        case errSecSigningTimeMissing:
                break;
        default:
        case errSecSigningTimeMissing:
                break;
        default:
@@ -424,7 +455,7 @@ bool SecStaticCode::verifySignature()
        // certified signing time (as specified by a TSA; optional)
        mSigningTimestamp = 0;
        switch (OSStatus rc = CMSDecoderCopySignerTimestamp(cms, 0, &mSigningTimestamp)) {
        // certified signing time (as specified by a TSA; optional)
        mSigningTimestamp = 0;
        switch (OSStatus rc = CMSDecoderCopySignerTimestamp(cms, 0, &mSigningTimestamp)) {
-       case noErr:
+       case errSecSuccess:
        case errSecTimestampMissing:
                break;
        default:
        case errSecTimestampMissing:
                break;
        default:
@@ -447,7 +478,7 @@ bool SecStaticCode::verifySignature()
                SecTrustResultType trustResult;
                MacOSError::check(SecTrustEvaluate(mTrust, &trustResult));
                MacOSError::check(SecTrustGetResult(mTrust, &trustResult, &mCertChain.aref(), &mEvalDetails));
                SecTrustResultType trustResult;
                MacOSError::check(SecTrustEvaluate(mTrust, &trustResult));
                MacOSError::check(SecTrustGetResult(mTrust, &trustResult, &mCertChain.aref(), &mEvalDetails));
-               CODESIGN_EVAL_STATIC_SIGNATURE_RESULT(this, trustResult, mCertChain ? CFArrayGetCount(mCertChain) : 0);
+               CODESIGN_EVAL_STATIC_SIGNATURE_RESULT(this, trustResult, mCertChain ? (int)CFArrayGetCount(mCertChain) : 0);
                switch (trustResult) {
                case kSecTrustResultProceed:
                case kSecTrustResultUnspecified:
                switch (trustResult) {
                case kSecTrustResultProceed:
                case kSecTrustResultUnspecified:
@@ -483,15 +514,6 @@ bool SecStaticCode::verifySignature()
                                        MacOSError::check(CMSDecoderCopySignerTimestampCertificates(cms, 0, &tsCerts.aref()));
                                        CFIndex tsn = CFArrayGetCount(tsCerts);
                                        bool good = tsn > 0 && isAppleCA(SecCertificateRef(CFArrayGetValueAtIndex(tsCerts, tsn-1)));
                                        MacOSError::check(CMSDecoderCopySignerTimestampCertificates(cms, 0, &tsCerts.aref()));
                                        CFIndex tsn = CFArrayGetCount(tsCerts);
                                        bool good = tsn > 0 && isAppleCA(SecCertificateRef(CFArrayGetValueAtIndex(tsCerts, tsn-1)));
-#ifndef WORKAROUND_12007637
-                                       // TS certificates are reordered weirdly; check them all
-                                       for (CFIndex n = 0; n < tsn; n++)
-                                               if (SecCertificateRef tsRoot = SecCertificateRef(CFArrayGetValueAtIndex(tsCerts, n)))
-                                                       if ((good = isAppleCA(tsRoot))) {
-                                                               secdebug("BUG", "Apple root at TS cert %ld", n);
-                                                               break;
-                                                       }
-#endif //WORKAROUND_12007637
                                        if (!good)
                                                MacOSError::throwMe(CSSMERR_TP_NOT_TRUSTED);
                                }
                                        if (!good)
                                                MacOSError::throwMe(CSSMERR_TP_NOT_TRUSTED);
                                }
@@ -590,16 +612,16 @@ void SecStaticCode::validateExecutable()
                                fd.seek(fat->archOffset());
                        size_t pageSize = cd->pageSize ? (1 << cd->pageSize) : 0;
                        size_t remaining = cd->codeLimit;
                                fd.seek(fat->archOffset());
                        size_t pageSize = cd->pageSize ? (1 << cd->pageSize) : 0;
                        size_t remaining = cd->codeLimit;
-                       for (size_t slot = 0; slot < cd->nCodeSlots; ++slot) {
+                       for (uint32_t slot = 0; slot < cd->nCodeSlots; ++slot) {
                                size_t size = min(remaining, pageSize);
                                if (!cd->validateSlot(fd, size, slot)) {
                                size_t size = min(remaining, pageSize);
                                if (!cd->validateSlot(fd, size, slot)) {
-                                       CODESIGN_EVAL_STATIC_EXECUTABLE_FAIL(this, slot);
+                                       CODESIGN_EVAL_STATIC_EXECUTABLE_FAIL(this, (int)slot);
                                        MacOSError::throwMe(errSecCSSignatureFailed);
                                }
                                remaining -= size;
                        }
                        mExecutableValidated = true;
                                        MacOSError::throwMe(errSecCSSignatureFailed);
                                }
                                remaining -= size;
                        }
                        mExecutableValidated = true;
-                       mExecutableValidResult = noErr;
+                       mExecutableValidResult = errSecSuccess;
                } catch (const CommonError &err) {
                        mExecutableValidated = true;
                        mExecutableValidResult = err.osStatus();
                } catch (const CommonError &err) {
                        mExecutableValidated = true;
                        mExecutableValidResult = err.osStatus();
@@ -612,21 +634,27 @@ void SecStaticCode::validateExecutable()
                }
        }
        assert(validatedExecutable());
                }
        }
        assert(validatedExecutable());
-       if (mExecutableValidResult != noErr)
+       if (mExecutableValidResult != errSecSuccess)
                MacOSError::throwMe(mExecutableValidResult);
 }
 
 
 //
                MacOSError::throwMe(mExecutableValidResult);
 }
 
 
 //
-// Perform static validation of sealed resources.
+// Perform static validation of sealed resources and nested code.
 //
 // This performs a whole-code static resource scan and effectively
 // computes a concordance between what's on disk and what's in the ResourceDirectory.
 // Any unsanctioned difference causes an error.
 //
 //
 // This performs a whole-code static resource scan and effectively
 // computes a concordance between what's on disk and what's in the ResourceDirectory.
 // Any unsanctioned difference causes an error.
 //
-void SecStaticCode::validateResources()
+void SecStaticCode::validateResources(SecCSFlags flags)
 {
 {
-       if (!validatedResources()) {
+       // do we have a superset of this requested validation cached?
+       bool doit = true;
+       if (mResourcesValidated) {      // have cached outcome
+               if (!(flags & kSecCSCheckNestedCode) || mResourcesDeep) // was deep or need no deep scan
+                       doit = false;
+       }
+       if (doit) {
                try {
                        // sanity first
                        CFDictionaryRef sealedResources = resourceDictionary();
                try {
                        // sanity first
                        CFDictionaryRef sealedResources = resourceDictionary();
@@ -642,25 +670,32 @@ void SecStaticCode::validateResources()
                                        return;                                 // no resources, not sealed - fine (no work)
                
                        // found resources, and they are sealed
                                        return;                                 // no resources, not sealed - fine (no work)
                
                        // found resources, and they are sealed
-                       CFDictionaryRef rules = cfget<CFDictionaryRef>(sealedResources, "rules");
-                       CFDictionaryRef files = cfget<CFDictionaryRef>(sealedResources, "files");
                        DTRACK(CODESIGN_EVAL_STATIC_RESOURCES, this,
                        DTRACK(CODESIGN_EVAL_STATIC_RESOURCES, this,
-                               (char*)this->mainExecutablePath().c_str(), int(CFDictionaryGetCount(files)));
-               
-                       // make a shallow copy of the ResourceDirectory so we can "check off" what we find
-                       CFRef<CFMutableDictionaryRef> resourceMap = makeCFMutableDictionary(files);
+                               (char*)this->mainExecutablePath().c_str(), 0);
                
                        // scan through the resources on disk, checking each against the resourceDirectory
                        mResourcesValidContext = new CollectingContext(*this);          // collect all failures in here
                
                        // scan through the resources on disk, checking each against the resourceDirectory
                        mResourcesValidContext = new CollectingContext(*this);          // collect all failures in here
-                       ResourceBuilder resources(cfString(this->resourceBase()), rules, codeDirectory()->hashType);
-                       mRep->adjustResources(resources);
-                       string path;
-                       ResourceBuilder::Rule *rule;
-               
-                       while (resources.next(path, rule)) {
-                               validateResource(path, *mResourcesValidContext);
-                               CFDictionaryRemoveValue(resourceMap, CFTempString(path));
+                       CFDictionaryRef rules;
+                       CFDictionaryRef files;
+                       uint32_t version;
+                       if (CFDictionaryGetValue(sealedResources, CFSTR("files2"))) {   // have V2 signature
+                               rules = cfget<CFDictionaryRef>(sealedResources, "rules2");
+                               files = cfget<CFDictionaryRef>(sealedResources, "files2");
+                               version = 2;
+                       } else {        // only V1 available
+                               rules = cfget<CFDictionaryRef>(sealedResources, "rules");
+                               files = cfget<CFDictionaryRef>(sealedResources, "files");
+                               version = 1;
                        }
                        }
+                       if (!rules || !files)
+                               MacOSError::throwMe(errSecCSResourcesInvalid);
+                       __block CFRef<CFMutableDictionaryRef> resourceMap = makeCFMutableDictionary(files);
+                       ResourceBuilder resources(cfString(this->resourceBase()), rules, codeDirectory()->hashType);
+                       diskRep()->adjustResources(resources);
+                       resources.scan(^(FTSENT *ent, uint32_t ruleFlags, const char *relpath, ResourceBuilder::Rule *rule) {
+                               validateResource(files, relpath, *mResourcesValidContext, flags, version);
+                               CFDictionaryRemoveValue(resourceMap, CFTempString(relpath));
+                       });
                        
                        if (CFDictionaryGetCount(resourceMap) > 0) {
                                secdebug("staticCode", "%p sealed resource(s) not found in code", this);
                        
                        if (CFDictionaryGetCount(resourceMap) > 0) {
                                secdebug("staticCode", "%p sealed resource(s) not found in code", this);
@@ -669,16 +704,18 @@ void SecStaticCode::validateResources()
                        
                        // now check for any errors found in the reporting context
                        mResourcesValidated = true;
                        
                        // now check for any errors found in the reporting context
                        mResourcesValidated = true;
-                       if (mResourcesValidContext->osStatus() != noErr)
+                       mResourcesDeep = flags & kSecCSCheckNestedCode;
+                       if (mResourcesValidContext->osStatus() != errSecSuccess)
                                mResourcesValidContext->throwMe();
                                mResourcesValidContext->throwMe();
-
                } catch (const CommonError &err) {
                        mResourcesValidated = true;
                } catch (const CommonError &err) {
                        mResourcesValidated = true;
+                       mResourcesDeep = flags & kSecCSCheckNestedCode;
                        mResourcesValidResult = err.osStatus();
                        throw;
                } catch (...) {
                        secdebug("staticCode", "%p executable validation threw non-common exception", this);
                        mResourcesValidated = true;
                        mResourcesValidResult = err.osStatus();
                        throw;
                } catch (...) {
                        secdebug("staticCode", "%p executable validation threw non-common exception", this);
                        mResourcesValidated = true;
+                       mResourcesDeep = flags & kSecCSCheckNestedCode;
                        mResourcesValidResult = errSecCSInternalError;
                        throw;
                }
                        mResourcesValidResult = errSecCSInternalError;
                        throw;
                }
@@ -686,7 +723,7 @@ void SecStaticCode::validateResources()
        assert(validatedResources());
        if (mResourcesValidResult)
                MacOSError::throwMe(mResourcesValidResult);
        assert(validatedResources());
        if (mResourcesValidResult)
                MacOSError::throwMe(mResourcesValidResult);
-       if (mResourcesValidContext->osStatus() != noErr)
+       if (mResourcesValidContext->osStatus() != errSecSuccess)
                mResourcesValidContext->throwMe();
 }
 
                mResourcesValidContext->throwMe();
 }
 
@@ -735,11 +772,11 @@ CFDictionaryRef SecStaticCode::entitlements()
        return mEntitlements;
 }
 
        return mEntitlements;
 }
 
-CFDictionaryRef SecStaticCode::resourceDictionary()
+CFDictionaryRef SecStaticCode::resourceDictionary(bool check /* = true */)
 {
        if (mResourceDict)      // cached
                return mResourceDict;
 {
        if (mResourceDict)      // cached
                return mResourceDict;
-       if (CFRef<CFDictionaryRef> dict = getDictionary(cdResourceDirSlot, errSecCSSignatureFailed))
+       if (CFRef<CFDictionaryRef> dict = getDictionary(cdResourceDirSlot, check))
                if (cfscan(dict, "{rules=%Dn,files=%Dn}")) {
                        secdebug("staticCode", "%p loaded ResourceDict %p",
                                this, mResourceDict.get());
                if (cfscan(dict, "{rules=%Dn,files=%Dn}")) {
                        secdebug("staticCode", "%p loaded ResourceDict %p",
                                this, mResourceDict.get());
@@ -771,11 +808,12 @@ CFURLRef SecStaticCode::resourceBase()
 // This will force load and validation, which means that it will perform basic
 // validation if it hasn't been done yet.
 //
 // This will force load and validation, which means that it will perform basic
 // validation if it hasn't been done yet.
 //
-CFDictionaryRef SecStaticCode::getDictionary(CodeDirectory::SpecialSlot slot, OSStatus fail /* = errSecCSSignatureFailed */)
+CFDictionaryRef SecStaticCode::getDictionary(CodeDirectory::SpecialSlot slot, bool check /* = true */)
 {
 {
-       validateDirectory();
-       if (CFDataRef infoData = component(slot, fail)) {
-               validateComponent(slot, fail);
+       if (check)
+               validateDirectory();
+       if (CFDataRef infoData = component(slot)) {
+               validateComponent(slot);
                if (CFDictionaryRef dict = makeCFDictionaryFrom(infoData))
                        return dict;
                else
                if (CFDictionaryRef dict = makeCFDictionaryFrom(infoData))
                        return dict;
                else
@@ -808,6 +846,8 @@ CFDataRef SecStaticCode::resource(string path, ValidationContext &ctx)
                        ResourceSeal seal = file;
                        if (!resourceBase())    // no resources in DiskRep
                                MacOSError::throwMe(errSecCSResourcesNotFound);
                        ResourceSeal seal = file;
                        if (!resourceBase())    // no resources in DiskRep
                                MacOSError::throwMe(errSecCSResourcesNotFound);
+                       if (seal.nested())
+                               MacOSError::throwMe(errSecCSResourcesNotSealed);        // (it's nested code)
                        CFRef<CFURLRef> fullpath = makeCFURL(path, false, resourceBase());
                        if (CFRef<CFDataRef> data = cfLoadFile(fullpath)) {
                                MakeHash<CodeDirectory> hasher(this->codeDirectory());
                        CFRef<CFURLRef> fullpath = makeCFURL(path, false, resourceBase());
                        if (CFRef<CFDataRef> data = cfLoadFile(fullpath)) {
                                MakeHash<CodeDirectory> hasher(this->codeDirectory());
@@ -836,15 +876,25 @@ CFDataRef SecStaticCode::resource(string path)
 }
 
 
 }
 
 
-void SecStaticCode::validateResource(string path, ValidationContext &ctx)
+void SecStaticCode::validateResource(CFDictionaryRef files, string path, ValidationContext &ctx, SecCSFlags flags, uint32_t version)
 {
 {
-       if (CFDictionaryRef rdict = resourceDictionary()) {
-               if (CFTypeRef file = cfget(rdict, "files.%s", path.c_str())) {
-                       ResourceSeal seal = file;
-                       if (!resourceBase())    // no resources in DiskRep
-                               MacOSError::throwMe(errSecCSResourcesNotFound);
-                       CFRef<CFURLRef> fullpath = makeCFURL(path, false, resourceBase());
-                       AutoFileDesc fd(cfString(fullpath), O_RDONLY, FileDesc::modeMissingOk); // open optional filee
+       if (!resourceBase())    // no resources in DiskRep
+               MacOSError::throwMe(errSecCSResourcesNotFound);
+       CFRef<CFURLRef> fullpath = makeCFURL(path, false, resourceBase());
+       if (CFTypeRef file = CFDictionaryGetValue(files, CFTempString(path))) {
+               ResourceSeal seal = file;
+               if (seal.nested()) {
+                       validateNestedCode(fullpath, seal, flags);
+               } else if (seal.link()) {
+                       char target[PATH_MAX];
+                       ssize_t len = ::readlink(cfString(fullpath).c_str(), target, sizeof(target)-1);
+                       if (len < 0)
+                               UnixError::check(-1);
+                       target[len] = '\0';
+                       if (cfString(seal.link()) != target)
+                               ctx.reportProblem(errSecCSBadResource, kSecCFErrorResourceAltered, fullpath);
+               } else if (seal.hash()) {       // genuine file
+                       AutoFileDesc fd(cfString(fullpath), O_RDONLY, FileDesc::modeMissingOk); // open optional file
                        if (fd) {
                                MakeHash<CodeDirectory> hasher(this->codeDirectory());
                                hashFileData(fd, hasher.get());
                        if (fd) {
                                MakeHash<CodeDirectory> hasher(this->codeDirectory());
                                hashFileData(fd, hasher.get());
@@ -859,9 +909,44 @@ void SecStaticCode::validateResource(string path, ValidationContext &ctx)
                                        return;                 // validly missing
                        }
                } else
                                        return;                 // validly missing
                        }
                } else
-                       ctx.reportProblem(errSecCSBadResource, kSecCFErrorResourceAdded, CFTempURL(path, false, resourceBase()));
-       } else
-               MacOSError::throwMe(errSecCSResourcesNotSealed);
+                       ctx.reportProblem(errSecCSBadResource, kSecCFErrorResourceAltered, fullpath); // changed type
+               return;
+       }
+       if (version == 1) {             // version 1 ignores symlinks altogether
+               char target[PATH_MAX];
+               if (::readlink(cfString(fullpath).c_str(), target, sizeof(target)) > 0)
+                       return;
+       }
+       ctx.reportProblem(errSecCSBadResource, kSecCFErrorResourceAdded, CFTempURL(path, false, resourceBase()));
+}
+
+void SecStaticCode::validateNestedCode(CFURLRef path, const ResourceSeal &seal, SecCSFlags flags)
+{
+       CFRef<SecRequirementRef> req;
+       if (SecRequirementCreateWithString(seal.requirement(), kSecCSDefaultFlags, &req.aref()))
+               MacOSError::throwMe(errSecCSResourcesInvalid);
+       
+       // recursively verify this nested code
+       try {
+               if (!(flags & kSecCSCheckNestedCode))
+                       flags |= kSecCSBasicValidateOnly;
+               SecPointer<SecStaticCode> code = new SecStaticCode(DiskRep::bestGuess(cfString(path)));
+               code->setMonitor(this->monitor());
+               code->staticValidate(flags, SecRequirement::required(req));
+       } catch (CSError &err) {
+               if (err.error == errSecCSReqFailed) {
+                       mResourcesValidContext->reportProblem(errSecCSBadNestedCode, kSecCFErrorResourceAltered, path);
+                       return;
+               }
+               err.augment(kSecCFErrorPath, path);
+               throw;
+       } catch (const MacOSError &err) {
+               if (err.error == errSecCSReqFailed) {
+                       mResourcesValidContext->reportProblem(errSecCSBadNestedCode, kSecCFErrorResourceAltered, path);
+                       return;
+               }
+               CSError::throwMe(err.error, kSecCFErrorPath, path);
+       }
 }
 
 
 }
 
 
@@ -884,9 +969,12 @@ bool SecStaticCode::flag(uint32_t tested)
 //
 const Requirements *SecStaticCode::internalRequirements()
 {
 //
 const Requirements *SecStaticCode::internalRequirements()
 {
-       if (CFDataRef req = component(cdRequirementsSlot))
-               return (const Requirements *)CFDataGetBytePtr(req);
-       else
+       if (CFDataRef reqData = component(cdRequirementsSlot)) {
+               const Requirements *req = (const Requirements *)CFDataGetBytePtr(reqData);
+               if (!req->validateBlob())
+                       MacOSError::throwMe(errSecCSReqInvalid);
+               return req;
+       } else
                return NULL;
 }
 
                return NULL;
 }
 
@@ -928,13 +1016,19 @@ const Requirement *SecStaticCode::designatedRequirement()
 const Requirement *SecStaticCode::defaultDesignatedRequirement()
 {
        if (flag(kSecCodeSignatureAdhoc)) {
 const Requirement *SecStaticCode::defaultDesignatedRequirement()
 {
        if (flag(kSecCodeSignatureAdhoc)) {
-               // adhoc signature: return a plain cdhash requirement
-               Requirement::Maker maker;
-               SHA1 hash;
-               hash(codeDirectory(), codeDirectory()->length());
-               SHA1::Digest digest;
-               hash.finish(digest);
-               maker.cdhash(digest);
+               // adhoc signature: return a cdhash requirement for all architectures
+               __block Requirement::Maker maker;
+               Requirement::Maker::Chain chain(maker, opOr);
+               
+               // insert cdhash requirement for all architectures
+               chain.add();
+               maker.cdhash(this->cdHash());
+               handleOtherArchitectures(^(SecStaticCode *subcode) {
+                       if (CFDataRef cdhash = subcode->cdHash()) {
+                               chain.add();
+                               maker.cdhash(cdhash);
+                       }
+               });
                return maker.make();
        } else {
                // full signature: Gin up full context and let DRMaker do its thing
                return maker.make();
        } else {
                // full signature: Gin up full context and let DRMaker do its thing
@@ -954,7 +1048,7 @@ const Requirement *SecStaticCode::defaultDesignatedRequirement()
 // Validate a SecStaticCode against the internal requirement of a particular type.
 //
 void SecStaticCode::validateRequirements(SecRequirementType type, SecStaticCode *target,
 // Validate a SecStaticCode against the internal requirement of a particular type.
 //
 void SecStaticCode::validateRequirements(SecRequirementType type, SecStaticCode *target,
-       OSStatus nullError /* = noErr */)
+       OSStatus nullError /* = errSecSuccess */)
 {
        DTRACK(CODESIGN_EVAL_STATIC_INTREQ, this, type, target, nullError);
        if (const Requirement *req = internalRequirement(type))
 {
        DTRACK(CODESIGN_EVAL_STATIC_INTREQ, this, type, target, nullError);
        if (const Requirement *req = internalRequirement(type))
@@ -1037,6 +1131,7 @@ CFDictionaryRef SecStaticCode::signingInformation(SecCSFlags flags)
        // Add the generic attributes that we always include
        //
        CFDictionaryAddValue(dict, kSecCodeInfoIdentifier, CFTempString(this->identifier()));
        // Add the generic attributes that we always include
        //
        CFDictionaryAddValue(dict, kSecCodeInfoIdentifier, CFTempString(this->identifier()));
+       CFDictionaryAddValue(dict, kSecCodeInfoFlags, CFTempNumber(this->codeDirectory(false)->flags.get()));
        CFDictionaryAddValue(dict, kSecCodeInfoFormat, CFTempString(this->format()));
        CFDictionaryAddValue(dict, kSecCodeInfoSource, CFTempString(this->signatureSource()));
        CFDictionaryAddValue(dict, kSecCodeInfoUnique, this->cdHash());
        CFDictionaryAddValue(dict, kSecCodeInfoFormat, CFTempString(this->format()));
        CFDictionaryAddValue(dict, kSecCodeInfoSource, CFTempString(this->signatureSource()));
        CFDictionaryAddValue(dict, kSecCodeInfoUnique, this->cdHash());
@@ -1053,47 +1148,51 @@ CFDictionaryRef SecStaticCode::signingInformation(SecCSFlags flags)
        //
        // kSecCSSigningInformation adds information about signing certificates and chains
        //
        //
        // kSecCSSigningInformation adds information about signing certificates and chains
        //
-       if (flags & kSecCSSigningInformation) {
-               if (CFArrayRef certs = this->certificates())
-               CFDictionaryAddValue(dict, kSecCodeInfoCertificates, certs);
-               if (CFDataRef sig = this->signature())
-                       CFDictionaryAddValue(dict, kSecCodeInfoCMS, sig);
-               if (mTrust)
-                       CFDictionaryAddValue(dict, kSecCodeInfoTrust, mTrust);
-               if (CFAbsoluteTime time = this->signingTime())
-                       if (CFRef<CFDateRef> date = CFDateCreate(NULL, time))
-                               CFDictionaryAddValue(dict, kSecCodeInfoTime, date);
-               if (CFAbsoluteTime time = this->signingTimestamp())
-                       if (CFRef<CFDateRef> date = CFDateCreate(NULL, time))
-                               CFDictionaryAddValue(dict, kSecCodeInfoTimestamp, date);
-       }
+       if (flags & kSecCSSigningInformation)
+               try {
+                       if (CFArrayRef certs = this->certificates())
+                               CFDictionaryAddValue(dict, kSecCodeInfoCertificates, certs);
+                       if (CFDataRef sig = this->signature())
+                               CFDictionaryAddValue(dict, kSecCodeInfoCMS, sig);
+                       if (mTrust)
+                               CFDictionaryAddValue(dict, kSecCodeInfoTrust, mTrust);
+                       if (CFAbsoluteTime time = this->signingTime())
+                               if (CFRef<CFDateRef> date = CFDateCreate(NULL, time))
+                                       CFDictionaryAddValue(dict, kSecCodeInfoTime, date);
+                       if (CFAbsoluteTime time = this->signingTimestamp())
+                               if (CFRef<CFDateRef> date = CFDateCreate(NULL, time))
+                                       CFDictionaryAddValue(dict, kSecCodeInfoTimestamp, date);
+               } catch (...) { }
        
        //
        // kSecCSRequirementInformation adds information on requirements
        //
        
        //
        // kSecCSRequirementInformation adds information on requirements
        //
-       if (flags & kSecCSRequirementInformation) {
-               if (const Requirements *reqs = this->internalRequirements()) {
-                       CFDictionaryAddValue(dict, kSecCodeInfoRequirements,
-                               CFTempString(Dumper::dump(reqs)));
-                       CFDictionaryAddValue(dict, kSecCodeInfoRequirementData, CFTempData(*reqs));
-               }
-               
-               const Requirement *dreq = this->designatedRequirement();
-               CFRef<SecRequirementRef> dreqRef = (new SecRequirement(dreq))->handle();
-               CFDictionaryAddValue(dict, kSecCodeInfoDesignatedRequirement, dreqRef);
-               if (this->internalRequirement(kSecDesignatedRequirementType)) { // explicit
-                       CFRef<SecRequirementRef> ddreqRef = (new SecRequirement(this->defaultDesignatedRequirement(), true))->handle();
-                       CFDictionaryAddValue(dict, kSecCodeInfoImplicitDesignatedRequirement, ddreqRef);
-               } else {        // implicit
-                       CFDictionaryAddValue(dict, kSecCodeInfoImplicitDesignatedRequirement, dreqRef);
-               }
+       if (flags & kSecCSRequirementInformation)
+               try {
+                       if (const Requirements *reqs = this->internalRequirements()) {
+                               CFDictionaryAddValue(dict, kSecCodeInfoRequirements,
+                                       CFTempString(Dumper::dump(reqs)));
+                               CFDictionaryAddValue(dict, kSecCodeInfoRequirementData, CFTempData(*reqs));
+                       }
+                       
+                       const Requirement *dreq = this->designatedRequirement();
+                       CFRef<SecRequirementRef> dreqRef = (new SecRequirement(dreq))->handle();
+                       CFDictionaryAddValue(dict, kSecCodeInfoDesignatedRequirement, dreqRef);
+                       if (this->internalRequirement(kSecDesignatedRequirementType)) { // explicit
+                               CFRef<SecRequirementRef> ddreqRef = (new SecRequirement(this->defaultDesignatedRequirement(), true))->handle();
+                               CFDictionaryAddValue(dict, kSecCodeInfoImplicitDesignatedRequirement, ddreqRef);
+                       } else {        // implicit
+                               CFDictionaryAddValue(dict, kSecCodeInfoImplicitDesignatedRequirement, dreqRef);
+                       }
+               } catch (...) { }
                
                
-          if (CFDataRef ent = this->component(cdEntitlementSlot)) {
-                  CFDictionaryAddValue(dict, kSecCodeInfoEntitlements, ent);
-                  if (CFDictionaryRef entdict = this->entitlements())
-                               CFDictionaryAddValue(dict, kSecCodeInfoEntitlementsDict, entdict);
-               }
-       }
+               try {
+                  if (CFDataRef ent = this->component(cdEntitlementSlot)) {
+                          CFDictionaryAddValue(dict, kSecCodeInfoEntitlements, ent);
+                          if (CFDictionaryRef entdict = this->entitlements())
+                                       CFDictionaryAddValue(dict, kSecCodeInfoEntitlementsDict, entdict);
+                       }
+               } catch (...) { }
        
        //
        // kSecCSInternalInformation adds internal information meant to be for Apple internal
        
        //
        // kSecCSInternalInformation adds internal information meant to be for Apple internal
@@ -1101,13 +1200,14 @@ CFDictionaryRef SecStaticCode::signingInformation(SecCSFlags flags)
        // to reliably transmit through the API wall so that code outside the Security.framework
        // can use it without having to play nasty tricks to get it.
        //
        // to reliably transmit through the API wall so that code outside the Security.framework
        // can use it without having to play nasty tricks to get it.
        //
-       if (flags & kSecCSInternalInformation) {
-               if (mDir)
-                       CFDictionaryAddValue(dict, kSecCodeInfoCodeDirectory, mDir);
-               CFDictionaryAddValue(dict, kSecCodeInfoCodeOffset, CFTempNumber(mRep->signingBase()));
-               if (CFDictionaryRef resources = resourceDictionary())
-                       CFDictionaryAddValue(dict, kSecCodeInfoResourceDirectory, resources);
-       }
+       if (flags & kSecCSInternalInformation)
+               try {
+                       if (mDir)
+                               CFDictionaryAddValue(dict, kSecCodeInfoCodeDirectory, mDir);
+                       CFDictionaryAddValue(dict, kSecCodeInfoCodeOffset, CFTempNumber(mRep->signingBase()));
+               if (CFRef<CFDictionaryRef> rdict = getDictionary(cdResourceDirSlot, false))     // suppress validation
+                       CFDictionaryAddValue(dict, kSecCodeInfoResourceDirectory, rdict);
+               } catch (...) { }
        
        
        //
        
        
        //
@@ -1137,7 +1237,7 @@ void SecStaticCode::ValidationContext::reportProblem(OSStatus rc, CFStringRef ty
 
 void SecStaticCode::CollectingContext::reportProblem(OSStatus rc, CFStringRef type, CFTypeRef value)
 {
 
 void SecStaticCode::CollectingContext::reportProblem(OSStatus rc, CFStringRef type, CFTypeRef value)
 {
-       if (mStatus == noErr)
+       if (mStatus == errSecSuccess)
                mStatus = rc;                   // record first failure for eventual error return
        if (type) {
                if (!mCollection)
                mStatus = rc;                   // record first failure for eventual error return
        if (type) {
                if (!mCollection)
@@ -1156,59 +1256,97 @@ void SecStaticCode::CollectingContext::reportProblem(OSStatus rc, CFStringRef ty
 
 void SecStaticCode::CollectingContext::throwMe()
 {
 
 void SecStaticCode::CollectingContext::throwMe()
 {
-       assert(mStatus != noErr);
+       assert(mStatus != errSecSuccess);
        throw CSError(mStatus, mCollection.retain());
 }
 
 
 //
        throw CSError(mStatus, mCollection.retain());
 }
 
 
 //
-// SecStaticCode::AllArchitectures produces SecStaticCode objects separately
-// for each architecture represented by a base object.
+// Master validation driver.
+// This is the static validation (only) driver for the API.
 //
 //
-// Performance note: This is a simple, straight-forward implementation that
-// does not heroically try to share resources between the code objects produced.
-// In practice, this means we'll re-open files and re-read resource files.
-// In exchange, we enter all the code paths in the normal way, and do not have
-// special sharing paths to worry about.
-// If a performance tool brings you here because you have *proof* of a performance
-// problem, consider digging up MachO and Universal (for sharing file descriptors),
-// and SecStaticCode (for sharing resource iterators). That ought to cover most of
-// the big chunks. If you're just offended by the simplicity of this implementation,
-// go play somewhere else.
+// SecStaticCode exposes an à la carte menu of topical validators applying
+// to a given object. The static validation API pulls the together reliably,
+// but it also adds two matrix dimensions: architecture (for "fat" Mach-O binaries)
+// and nested code. This function will crawl a suitable cross-section of this
+// validation matrix based on which options it is given, creating temporary
+// SecStaticCode objects on the fly to complete the task.
+// (The point, of course, is to do as little duplicate work as possible.)
 //
 //
-SecStaticCode::AllArchitectures::AllArchitectures(SecStaticCode *code)
-       : mBase(code)
+void SecStaticCode::staticValidate(SecCSFlags flags, const SecRequirement *req)
 {
 {
-       if (Universal *fat = code->diskRep()->mainExecutableImage()) {
-               fat->architectures(mArchitectures);
-               mCurrent = mArchitectures.begin();
-               mState = fatBinary;
-       } else {
-               mState = firstNonFat;
+       // core components: once per architecture (if any)
+       this->staticValidateCore(flags, req);
+       if (flags & kSecCSCheckAllArchitectures)
+               handleOtherArchitectures(^(SecStaticCode* subcode) {
+                       subcode->detachedSignature(this->mDetachedSig); // carry over explicit (but not implicit) architecture
+                       subcode->staticValidateCore(flags, req);
+               });
+       
+       // resources: once for all architectures
+       if (!(flags & kSecCSDoNotValidateResources))
+               this->validateResources(flags);
+
+       // allow monitor intervention
+       if (CFRef<CFTypeRef> veto = reportEvent(CFSTR("validated"), NULL)) {
+               if (CFGetTypeID(veto) == CFNumberGetTypeID())
+                       MacOSError::throwMe(cfNumber<OSStatus>(veto.as<CFNumberRef>()));
+               else
+                       MacOSError::throwMe(errSecCSBadCallbackValue);
        }
 }
 
        }
 }
 
-SecStaticCode *SecStaticCode::AllArchitectures::operator () ()
+void SecStaticCode::staticValidateCore(SecCSFlags flags, const SecRequirement *req)
 {
 {
-       switch (mState) {
-       case firstNonFat:
-               mState = atEnd;
-               return mBase;
-       case fatBinary:
-               {
-                       if (mCurrent == mArchitectures.end())
-                               return NULL;
-                       Architecture arch = *mCurrent++;
-                       if (arch == mBase->diskRep()->mainExecutableImage()->bestNativeArch()) {
-                               return mBase;
-                       } else {
-                               DiskRep::Context ctx;
-                               ctx.arch = arch;
-                               return new SecStaticCode(DiskRep::bestGuess(mBase->mainExecutablePath(), &ctx));
+       try {
+               this->validateNonResourceComponents();  // also validates the CodeDirectory
+               if (!(flags & kSecCSDoNotValidateExecutable))
+                       this->validateExecutable();
+               if (req)
+                       this->validateRequirement(req->requirement(), errSecCSReqFailed);
+    } catch (CSError &err) {
+        if (Universal *fat = this->diskRep()->mainExecutableImage())    // Mach-O
+            if (MachO *mach = fat->architecture()) {
+                err.augment(kSecCFErrorArchitecture, CFTempString(mach->architecture().displayName()));
+                delete mach;
+            }
+        throw;
+    } catch (const MacOSError &err) {
+        // add architecture information if we can get it
+        if (Universal *fat = this->diskRep()->mainExecutableImage())
+            if (MachO *mach = fat->architecture()) {
+                CFTempString arch(mach->architecture().displayName());
+                delete mach;
+                CSError::throwMe(err.error, kSecCFErrorArchitecture, arch);
+            }
+        throw;
+    }
+}
+
+
+//
+// A helper that generates SecStaticCode objects for all but the primary architecture
+// of a fat binary and calls a block on them.
+// If there's only one architecture (or this is an architecture-agnostic code),
+// nothing happens quickly.
+//
+void SecStaticCode::handleOtherArchitectures(void (^handle)(SecStaticCode* other))
+{
+       if (Universal *fat = this->diskRep()->mainExecutableImage()) {
+               Universal::Architectures architectures;
+               fat->architectures(architectures);
+               if (architectures.size() > 1) {
+                       DiskRep::Context ctx;
+                       size_t activeOffset = fat->archOffset();
+                       for (Universal::Architectures::const_iterator arch = architectures.begin(); arch != architectures.end(); ++arch) {
+                               ctx.offset = fat->archOffset(*arch);
+                               if (ctx.offset != activeOffset) {       // inactive architecture; check it
+                                       SecPointer<SecStaticCode> subcode = new SecStaticCode(DiskRep::bestGuess(this->mainExecutablePath(), &ctx));
+                                       subcode->detachedSignature(this->mDetachedSig); // carry over explicit (but not implicit) detached signature
+                                       handle(subcode);
+                               }
                        }
                }
                        }
                }
-       default:
-               return NULL;
        }
 }
 
        }
 }
 
index af255bad718a2231e3f2651188e3e49c325041dc..66b05ed01738c230beed8ac51a16458d59ebab02 100644 (file)
@@ -55,7 +55,7 @@ class SecCode;
 // Data accessors (returning CFDataRef, CFDictionaryRef, various pointers, etc.)
 // cache those values internally and return unretained(!) references ("Get" style)
 // that are valid as long as the SecStaticCode object's lifetime, or until
 // Data accessors (returning CFDataRef, CFDictionaryRef, various pointers, etc.)
 // cache those values internally and return unretained(!) references ("Get" style)
 // that are valid as long as the SecStaticCode object's lifetime, or until
-// resetValidity() is called, whichever is sooner. If you need to keep them,
+// resetValidity() is called, whichever is sooner. If you need to keep them longer,
 // retain or copy them as needed.
 //
 class SecStaticCode : public SecCFObject {
 // retain or copy them as needed.
 //
 class SecStaticCode : public SecCFObject {
@@ -77,7 +77,7 @@ protected:
        //
        class CollectingContext : public ValidationContext {
        public:
        //
        class CollectingContext : public ValidationContext {
        public:
-               CollectingContext(SecStaticCode &c) : code(c), mStatus(noErr) { }
+               CollectingContext(SecStaticCode &c) : code(c), mStatus(errSecSuccess) { }
                void reportProblem(OSStatus rc, CFStringRef type, CFTypeRef value);
                
                OSStatus osStatus()             { return mStatus; }
                void reportProblem(OSStatus rc, CFStringRef type, CFTypeRef value);
                
                OSStatus osStatus()             { return mStatus; }
@@ -97,7 +97,7 @@ public:
        
        // implicitly convert SecCodeRefs to their SecStaticCodeRefs
        static SecStaticCode *requiredStatic(SecStaticCodeRef ref);     // convert SecCodeRef
        
        // implicitly convert SecCodeRefs to their SecStaticCodeRefs
        static SecStaticCode *requiredStatic(SecStaticCodeRef ref);     // convert SecCodeRef
-       static SecCode *optionalDynamic(SecStaticCodeRef ref); // extract SecCodeRef or NULL
+       static SecCode *optionalDynamic(SecStaticCodeRef ref); // extract SecCodeRef or NULL if static
 
        SecStaticCode(DiskRep *rep);
     virtual ~SecStaticCode() throw();
 
        SecStaticCode(DiskRep *rep);
     virtual ~SecStaticCode() throw();
@@ -115,36 +115,43 @@ public:
        CFAbsoluteTime signingTimestamp();
        bool isSigned() { return codeDirectory(false) != NULL; }
        DiskRep *diskRep() { return mRep; }
        CFAbsoluteTime signingTimestamp();
        bool isSigned() { return codeDirectory(false) != NULL; }
        DiskRep *diskRep() { return mRep; }
+       bool isDetached() const { return mRep->base() != mRep; }
        std::string mainExecutablePath() { return mRep->mainExecutablePath(); }
        CFURLRef canonicalPath() const { return mRep->canonicalPath(); }
        std::string identifier() { return codeDirectory()->identifier(); }
        std::string format() const { return mRep->format(); }
        std::string signatureSource();
        std::string mainExecutablePath() { return mRep->mainExecutablePath(); }
        CFURLRef canonicalPath() const { return mRep->canonicalPath(); }
        std::string identifier() { return codeDirectory()->identifier(); }
        std::string format() const { return mRep->format(); }
        std::string signatureSource();
-       CFDataRef component(CodeDirectory::SpecialSlot slot, OSStatus fail = errSecCSSignatureFailed);
-       CFDictionaryRef infoDictionary();
+       virtual CFDataRef component(CodeDirectory::SpecialSlot slot, OSStatus fail = errSecCSSignatureFailed);
+       virtual CFDictionaryRef infoDictionary();
+
        CFDictionaryRef entitlements();
 
        CFDictionaryRef entitlements();
 
-       CFDictionaryRef resourceDictionary();
+       CFDictionaryRef resourceDictionary(bool check = true);
        CFURLRef resourceBase();
        CFDataRef resource(std::string path);
        CFDataRef resource(std::string path, ValidationContext &ctx);
        CFURLRef resourceBase();
        CFDataRef resource(std::string path);
        CFDataRef resource(std::string path, ValidationContext &ctx);
-       void validateResource(std::string path, ValidationContext &ctx);
+       void validateResource(CFDictionaryRef files, std::string path, ValidationContext &ctx, SecCSFlags flags, uint32_t version);
        
        bool flag(uint32_t tested);
        
        bool flag(uint32_t tested);
+
+       SecCodeCallback monitor() const { return mMonitor; }
+       void setMonitor(SecCodeCallback monitor) { mMonitor = monitor; }
+       CFTypeRef reportEvent(CFStringRef stage, CFDictionaryRef info);
        
        void resetValidity();                                           // clear validation caches (if something may have changed)
        
        bool validated() const  { return mValidated; }
        bool valid() const
        
        void resetValidity();                                           // clear validation caches (if something may have changed)
        
        bool validated() const  { return mValidated; }
        bool valid() const
-               { assert(validated()); return mValidated && (mValidationResult == noErr); }
+               { assert(validated()); return mValidated && (mValidationResult == errSecSuccess); }
        bool validatedExecutable() const        { return mExecutableValidated; }
        bool validatedResources() const { return mResourcesValidated; }
 
        void validateDirectory();
        bool validatedExecutable() const        { return mExecutableValidated; }
        bool validatedResources() const { return mResourcesValidated; }
 
        void validateDirectory();
-       void validateComponent(CodeDirectory::SpecialSlot slot, OSStatus fail = errSecCSSignatureFailed);
+       virtual void validateComponent(CodeDirectory::SpecialSlot slot, OSStatus fail = errSecCSSignatureFailed);
        void validateNonResourceComponents();
        void validateNonResourceComponents();
-       void validateResources();
+       void validateResources(SecCSFlags flags);
        void validateExecutable();
        void validateExecutable();
+       void validateNestedCode(CFURLRef path, const ResourceSeal &seal, SecCSFlags flags);
        
        const Requirements *internalRequirements();
        const Requirement *internalRequirement(SecRequirementType type);
        
        const Requirements *internalRequirements();
        const Requirement *internalRequirement(SecRequirementType type);
@@ -152,7 +159,7 @@ public:
        const Requirement *defaultDesignatedRequirement();              // newly allocated (caller owns)
        
        void validateRequirements(SecRequirementType type, SecStaticCode *target,
        const Requirement *defaultDesignatedRequirement();              // newly allocated (caller owns)
        
        void validateRequirements(SecRequirementType type, SecStaticCode *target,
-               OSStatus nullError = noErr);                                                                            // target against my [type], throws
+               OSStatus nullError = errSecSuccess);                                                                            // target against my [type], throws
        void validateRequirement(const Requirement *req, OSStatus failure);             // me against [req], throws
        bool satisfiesRequirement(const Requirement *req, OSStatus failure);    // me against [req], returns on clean miss
        
        void validateRequirement(const Requirement *req, OSStatus failure);             // me against [req], throws
        bool satisfiesRequirement(const Requirement *req, OSStatus failure);    // me against [req], returns on clean miss
        
@@ -161,19 +168,23 @@ public:
        CFArrayRef certificates();                      // get the entire certificate chain
        
        CFDictionaryRef signingInformation(SecCSFlags flags); // omnibus information-gathering API (creates new dictionary)
        CFArrayRef certificates();                      // get the entire certificate chain
        
        CFDictionaryRef signingInformation(SecCSFlags flags); // omnibus information-gathering API (creates new dictionary)
-       
+
 public:
 public:
-       class AllArchitectures;
+       void staticValidate(SecCSFlags flags, const SecRequirement *req);
+       void staticValidateCore(SecCSFlags flags, const SecRequirement *req);
        
 protected:
        
 protected:
-       CFDictionaryRef getDictionary(CodeDirectory::SpecialSlot slot, OSStatus fail); // component value as a dictionary
+       CFDictionaryRef getDictionary(CodeDirectory::SpecialSlot slot, bool check = true); // component value as a dictionary
        bool verifySignature();
        CFTypeRef verificationPolicy(SecCSFlags flags);
 
        static void checkOptionalResource(CFTypeRef key, CFTypeRef value, void *context);
 
        bool verifySignature();
        CFTypeRef verificationPolicy(SecCSFlags flags);
 
        static void checkOptionalResource(CFTypeRef key, CFTypeRef value, void *context);
 
+       void handleOtherArchitectures(void (^handle)(SecStaticCode* other));
+
 private:
        RefPointer<DiskRep> mRep;                       // on-disk representation
 private:
        RefPointer<DiskRep> mRep;                       // on-disk representation
+       CFRef<CFDataRef> mDetachedSig;          // currently applied explicit detached signature
        
        // master validation state
        bool mValidated;                                        // core validation was attempted
        
        // master validation state
        bool mValidated;                                        // core validation was attempted
@@ -186,8 +197,9 @@ private:
 
        // static resource validation state (nested within mValidated/mValid)
        bool mResourcesValidated;                       // tried to validate resources
 
        // static resource validation state (nested within mValidated/mValid)
        bool mResourcesValidated;                       // tried to validate resources
-       OSStatus mResourcesValidResult;                 // outcome if mResourceValidated or..
-       CollectingContext *mResourcesValidContext;      // other outcome
+       bool mResourcesDeep;                            // cached validation was deep
+       OSStatus mResourcesValidResult;                 // outcome if mResourceValidated or...
+       CollectingContext *mResourcesValidContext;      // 
 
        // cached contents
        CFRef<CFDataRef> mDir;                          // code directory data
 
        // cached contents
        CFRef<CFDataRef> mDir;                          // code directory data
@@ -205,6 +217,8 @@ private:
        
        bool mGotResourceBase;                          // asked mRep for resourceBasePath
        CFRef<CFURLRef> mResourceBase;          // URL form of resource base directory
        
        bool mGotResourceBase;                          // asked mRep for resourceBasePath
        CFRef<CFURLRef> mResourceBase;          // URL form of resource base directory
+
+       SecCodeCallback mMonitor;                       // registered monitor callback
        
        // signature verification outcome (mTrust == NULL => not done yet)
        CFRef<SecTrustRef> mTrust;                      // outcome of crypto validation (valid or not)
        
        // signature verification outcome (mTrust == NULL => not done yet)
        CFRef<SecTrustRef> mTrust;                      // outcome of crypto validation (valid or not)
@@ -213,24 +227,6 @@ private:
 };
 
 
 };
 
 
-//
-// Given a SecStaticCode, create an iterator that produces SecStaticCodes
-// for all architectures encompassed by this static code reference.
-//
-class SecStaticCode::AllArchitectures : public SecPointer<SecStaticCode> {
-public:
-       AllArchitectures(SecStaticCode *code);
-       
-       SecStaticCode *operator () ();
-       
-private:
-       SecPointer<SecStaticCode> mBase;
-       enum { fatBinary, firstNonFat, atEnd } mState;
-       Universal::Architectures mArchitectures;
-       Universal::Architectures::const_iterator mCurrent;
-};
-
-
 } // end namespace CodeSigning
 } // end namespace Security
 
 } // end namespace CodeSigning
 } // end namespace Security
 
index fc38e53ce37808296310f7e822b7bdee8a735421..2a0ddbcdbe7e59e5df5d9a449b0ebb36d328b5e5 100644 (file)
@@ -83,21 +83,27 @@ const Result *parse(Source source, Result *(Parser::RequirementParser::*rule)(),
 //
 // Hook up each supported parsing action to the plugin interface
 //
 //
 // Hook up each supported parsing action to the plugin interface
 //
+static
 const Requirement *fileRequirement(FILE *source, string &errors)
 { return parse<StdioInputStream>(source, &Parser::RequirementParser::requirement, errors); }
 
 const Requirement *fileRequirement(FILE *source, string &errors)
 { return parse<StdioInputStream>(source, &Parser::RequirementParser::requirement, errors); }
 
+static
 const Requirement *stringRequirement(string source, string &errors)
 { return parse<StringInputStream>(source, &Parser::RequirementParser::requirement, errors); }
 
 const Requirement *stringRequirement(string source, string &errors)
 { return parse<StringInputStream>(source, &Parser::RequirementParser::requirement, errors); }
 
+static
 const Requirements *fileRequirements(FILE *source, string &errors)
 { return parse<StdioInputStream>(source, &Parser::RequirementParser::requirementSet, errors); }
 
 const Requirements *fileRequirements(FILE *source, string &errors)
 { return parse<StdioInputStream>(source, &Parser::RequirementParser::requirementSet, errors); }
 
+static
 const Requirements *stringRequirements(string source, string &errors)
 { return parse<StringInputStream>(source, &Parser::RequirementParser::requirementSet, errors); }
 
 const Requirements *stringRequirements(string source, string &errors)
 { return parse<StringInputStream>(source, &Parser::RequirementParser::requirementSet, errors); }
 
+static
 const BlobCore *fileGeneric(FILE *source, string &errors)
 { return parse<StdioInputStream>(source, &Parser::RequirementParser::autosense, errors); }
 
 const BlobCore *fileGeneric(FILE *source, string &errors)
 { return parse<StdioInputStream>(source, &Parser::RequirementParser::autosense, errors); }
 
+static
 const BlobCore *stringGeneric(string source, string &errors)
 { return parse<StringInputStream>(source, &Parser::RequirementParser::autosense, errors); }
 
 const BlobCore *stringGeneric(string source, string &errors)
 { return parse<StringInputStream>(source, &Parser::RequirementParser::autosense, errors); }
 
index fa5a8574e58d47a8efe0ff32d93ff52d5d412c93..41423fafe531e3e1dfca25955fdcda755c607f88 100644 (file)
@@ -60,6 +60,10 @@ BundleDiskRep::BundleDiskRep(CFBundleRef ref, const Context *ctx)
        CODESIGN_DISKREP_CREATE_BUNDLE_REF(this, ref, (void*)ctx, mExecRep);
 }
 
        CODESIGN_DISKREP_CREATE_BUNDLE_REF(this, ref, (void*)ctx, mExecRep);
 }
 
+BundleDiskRep::~BundleDiskRep()
+{
+}
+
 // common construction code
 void BundleDiskRep::setup(const Context *ctx)
 {
 // common construction code
 void BundleDiskRep::setup(const Context *ctx)
 {
@@ -110,16 +114,15 @@ void BundleDiskRep::setup(const Context *ctx)
        // do we have a real Info.plist here?
        if (CFRef<CFURLRef> infoURL = _CFBundleCopyInfoPlistURL(mBundle)) {
                // focus on the Info.plist (which we know exists) as the nominal "main executable" file
        // do we have a real Info.plist here?
        if (CFRef<CFURLRef> infoURL = _CFBundleCopyInfoPlistURL(mBundle)) {
                // focus on the Info.plist (which we know exists) as the nominal "main executable" file
-               if ((mMainExecutableURL = _CFBundleCopyInfoPlistURL(mBundle))) {
-                       mExecRep = new FileDiskRep(this->mainExecutablePath().c_str());
-                       if (packageVersion) {
-                               mInstallerPackage = true;
-                               mFormat = "installer package bundle";
-                       } else {
-                               mFormat = "bundle";
-                       }
-                       return;
+               mMainExecutableURL = infoURL;
+               mExecRep = new FileDiskRep(this->mainExecutablePath().c_str());
+               if (packageVersion) {
+                       mInstallerPackage = true;
+                       mFormat = "installer package bundle";
+               } else {
+                       mFormat = "bundle";
                }
                }
+               return;
        }
 
        // we're getting desperate here. Perhaps an oldish-style installer package? Look for a *.dist file
        }
 
        // we're getting desperate here. Perhaps an oldish-style installer package? Look for a *.dist file
@@ -257,7 +260,9 @@ CFDataRef BundleDiskRep::identification()
 //
 CFURLRef BundleDiskRep::canonicalPath()
 {
 //
 CFURLRef BundleDiskRep::canonicalPath()
 {
-       return CFBundleCopyBundleURL(mBundle);
+       if (CFURLRef url = CFBundleCopyBundleURL(mBundle))
+               return url;
+       CFError::throwMe();
 }
 
 string BundleDiskRep::mainExecutablePath()
 }
 
 string BundleDiskRep::mainExecutablePath()
@@ -273,17 +278,21 @@ string BundleDiskRep::resourcesRootPath()
 void BundleDiskRep::adjustResources(ResourceBuilder &builder)
 {
        // exclude entire contents of meta directory
 void BundleDiskRep::adjustResources(ResourceBuilder &builder)
 {
        // exclude entire contents of meta directory
-       builder.addExclusion("^" BUNDLEDISKREP_DIRECTORY "/");
+       builder.addExclusion("^" BUNDLEDISKREP_DIRECTORY "$");
+       builder.addExclusion("^" CODERESOURCES_LINK "$");       // ancient-ish symlink into it
 
        // exclude the store manifest directory
 
        // exclude the store manifest directory
-       builder.addExclusion("^" STORE_RECEIPT_DIRECTORY "/");
+       builder.addExclusion("^" STORE_RECEIPT_DIRECTORY "$");
        
        // exclude the main executable file
        string resources = resourcesRootPath();
        
        // exclude the main executable file
        string resources = resourcesRootPath();
+       if (resources.compare(resources.size() - 2, 2, "/.") == 0)      // chop trailing /.
+               resources = resources.substr(0, resources.size()-2);
        string executable = mainExecutablePath();
        string executable = mainExecutablePath();
-       if (!executable.compare(0, resources.length(), resources, 0, resources.length()))       // is prefix
+       if (!executable.compare(0, resources.length(), resources, 0, resources.length())
+               && executable[resources.length()] == '/')       // is proper directory prefix
                builder.addExclusion(string("^")
                builder.addExclusion(string("^")
-                       + ResourceBuilder::escapeRE(executable.substr(resources.length() + 1)) + "$");
+                       + ResourceBuilder::escapeRE(executable.substr(resources.length()+1)) + "$");
 }
 
 
 }
 
 
@@ -355,12 +364,19 @@ string BundleDiskRep::recommendedIdentifier(const SigningContext &)
        return canonicalIdentifier(cfString(this->canonicalPath()));
 }
 
        return canonicalIdentifier(cfString(this->canonicalPath()));
 }
 
-CFDictionaryRef BundleDiskRep::defaultResourceRules(const SigningContext &)
+CFDictionaryRef BundleDiskRep::defaultResourceRules(const SigningContext &ctx)
 {
 {
-       // consider the bundle's structure
+       // figure out the resource directory base. Clean up some gunk inserted by CFBundle in frameworks
        string rbase = this->resourcesRootPath();
        string rbase = this->resourcesRootPath();
+       size_t pos = rbase.find("/./"); // gratuitously inserted by CFBundle in some frameworks
+       while (pos != std::string::npos) {
+               rbase = rbase.replace(pos, 2, "", 0);
+               pos = rbase.find("/./");
+       }
        if (rbase.substr(rbase.length()-2, 2) == "/.")  // produced by versioned bundle implicit "Current" case
                rbase = rbase.substr(0, rbase.length()-2);      // ... so take it off for this
        if (rbase.substr(rbase.length()-2, 2) == "/.")  // produced by versioned bundle implicit "Current" case
                rbase = rbase.substr(0, rbase.length()-2);      // ... so take it off for this
+       
+       // find the resources directory relative to the resource base
        string resources = cfStringRelease(CFBundleCopyResourcesDirectoryURL(mBundle));
        if (resources == rbase)
                resources = "";
        string resources = cfStringRelease(CFBundleCopyResourcesDirectoryURL(mBundle));
        if (resources == rbase)
                resources = "";
@@ -379,13 +395,52 @@ CFDictionaryRef BundleDiskRep::defaultResourceRules(const SigningContext &)
                        (string("^") + resources + ".*\\.lproj/").c_str()
                );
        
                        (string("^") + resources + ".*\\.lproj/").c_str()
                );
        
-       // executable bundle rules
-       return cfmake<CFDictionaryRef>("{rules={"
-               "'^version.plist$' = #T"                                        // include version.plist
-               "%s = #T"                                                                       // include Resources
-               "%s = {optional=#T, weight=1000}"                       // make localizations optional
-               "%s = {omit=#T, weight=1100}"                           // exclude all locversion.plist files
+       // old (V1) executable bundle rules - compatible with before
+       if (ctx.signingFlags() & kSecCSSignV1)                          // *** must be exactly the same as before ***
+               return cfmake<CFDictionaryRef>("{rules={"
+                       "'^version.plist$' = #T"                    // include version.plist
+                       "%s = #T"                                   // include Resources
+                       "%s = {optional=#T, weight=1000}"           // make localizations optional
+                       "%s = {omit=#T, weight=1100}"               // exclude all locversion.plist files
+                       "}}",
+                       (string("^") + resources).c_str(),
+                       (string("^") + resources + ".*\\.lproj/").c_str(),
+                       (string("^") + resources + ".*\\.lproj/locversion.plist$").c_str()
+               );
+       
+       // FMJ (everything is a resource) rules
+       if (ctx.signingFlags() & kSecCSSignOpaque)                      // Full Metal Jacket - everything is a resource file
+               return cfmake<CFDictionaryRef>("{rules={"
+                       "'^.*' = #T"                                                            // everything is a resource
+                       "'^Info\\.plist$' = {omit=#T,weight=10}"        // explicitly exclude this for backward compatibility
+               "}}");
+       
+       // new (V2) executable bundle rules
+       return cfmake<CFDictionaryRef>("{"                                      // *** the new (V2) world ***
+               "rules={"                                                                               // old (V1; legacy) version
+                       "'^version.plist$' = #T"                                        // include version.plist
+                       "%s = #T"                                                                       // include Resources
+                       "%s = {optional=#T, weight=1000}"                       // make localizations optional
+                       "%s = {omit=#T, weight=1100}"                           // exclude all locversion.plist files
+               "},rules2={"
+                       "'^.*' = #T"                                                            // include everything as a resource, with the following exceptions
+                       "'^[^/]+$' = {nested=#T, weight=10}"            // files directly in Contents
+                       "'^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/' = {nested=#T, weight=10}" // dynamic repositories
+                       "'.*\\.dSYM($|/)' = {weight=11}"                        // but allow dSYM directories in code locations (parallel to their code)
+                       "'^(.*/)?\\.DS_Store$' = {omit=#T,weight=2000}" // ignore .DS_Store files
+                       "'^Info\\.plist$' = {omit=#T, weight=20}"       // excluded automatically now, but old systems need to be told
+                       "'^version\\.plist$' = {weight=20}"                     // include version.plist as resource
+                       "'^embedded\\.provisionprofile$' = {weight=20}" // include embedded.provisionprofile as resource
+                       "'^PkgInfo$' = {omit=#T, weight=20}"            // traditionally not included
+                       "%s = {weight=20}"                                                      // Resources override default nested (widgets)
+                       "%s = {optional=#T, weight=1000}"                       // make localizations optional
+                       "%s = {omit=#T, weight=1100}"                           // exclude all locversion.plist files
                "}}",
                "}}",
+                       
+               (string("^") + resources).c_str(),
+               (string("^") + resources + ".*\\.lproj/").c_str(),
+               (string("^") + resources + ".*\\.lproj/locversion.plist$").c_str(),
+                       
                (string("^") + resources).c_str(),
                (string("^") + resources + ".*\\.lproj/").c_str(),
                (string("^") + resources + ".*\\.lproj/locversion.plist$").c_str()
                (string("^") + resources).c_str(),
                (string("^") + resources + ".*\\.lproj/").c_str(),
                (string("^") + resources + ".*\\.lproj/locversion.plist$").c_str()
index bef1861b0a2ac667c6ddde0d22593207bd39cf90..6dfb12fb805d3cc95660c511e6cc21a9e3ae1820 100644 (file)
@@ -35,6 +35,7 @@ namespace CodeSigning {
 
 
 #define BUNDLEDISKREP_DIRECTORY                "_CodeSignature"
 
 
 #define BUNDLEDISKREP_DIRECTORY                "_CodeSignature"
+#define CODERESOURCES_LINK                     "CodeResources"
 #define STORE_RECEIPT_DIRECTORY                "_MASReceipt"
 
 
 #define STORE_RECEIPT_DIRECTORY                "_MASReceipt"
 
 
@@ -50,6 +51,7 @@ class BundleDiskRep : public DiskRep {
 public:
        BundleDiskRep(const char *path, const Context *ctx = NULL);
        BundleDiskRep(CFBundleRef ref, const Context *ctx = NULL);
 public:
        BundleDiskRep(const char *path, const Context *ctx = NULL);
        BundleDiskRep(CFBundleRef ref, const Context *ctx = NULL);
+       ~BundleDiskRep();
        
        CFDataRef component(CodeDirectory::SpecialSlot slot);
        CFDataRef identification();
        
        CFDataRef component(CodeDirectory::SpecialSlot slot);
        CFDataRef identification();
index ac17edbc4229db9fe62943c63404bd5c1887f028..e191779249ac4fe20c98b03a62577fd5cd0152aa 100644 (file)
@@ -48,7 +48,7 @@ CodeDirectory::Builder::Builder(HashAlgorithm digestAlgorithm)
          mScatterSize(0),
          mDir(NULL)
 {
          mScatterSize(0),
          mDir(NULL)
 {
-       mDigestLength = MakeHash<Builder>(this)->digestLength();
+       mDigestLength = (uint32_t)MakeHash<Builder>(this)->digestLength();
        mSpecial = (unsigned char *)calloc(cdSlotMax, mDigestLength);
 }
 
        mSpecial = (unsigned char *)calloc(cdSlotMax, mDigestLength);
 }
 
@@ -160,9 +160,9 @@ CodeDirectory *CodeDirectory::Builder::build()
        mDir->initialize(total);
        mDir->version = currentVersion;
        mDir->flags = mFlags;
        mDir->initialize(total);
        mDir->version = currentVersion;
        mDir->flags = mFlags;
-       mDir->nSpecialSlots = mSpecialSlots;
-       mDir->nCodeSlots = mCodeSlots;
-       mDir->codeLimit = mExecLength;
+       mDir->nSpecialSlots = (uint32_t)mSpecialSlots;
+       mDir->nCodeSlots = (uint32_t)mCodeSlots;
+       mDir->codeLimit = (uint32_t)mExecLength;
        mDir->hashType = mHashType;
        mDir->hashSize = mDigestLength;
        if (mPageSize) {
        mDir->hashType = mHashType;
        mDir->hashSize = mDigestLength;
        if (mPageSize) {
@@ -178,25 +178,25 @@ CodeDirectory *CodeDirectory::Builder::build()
        size_t offset = sizeof(CodeDirectory);
 
        if (mScatter) {
        size_t offset = sizeof(CodeDirectory);
 
        if (mScatter) {
-               mDir->scatterOffset = offset;
+               mDir->scatterOffset = (uint32_t)offset;
                memcpy(mDir->scatterVector(), mScatter, mScatterSize);
                offset += mScatterSize;
        }
 
                memcpy(mDir->scatterVector(), mScatter, mScatterSize);
                offset += mScatterSize;
        }
 
-       mDir->identOffset = offset;
+       mDir->identOffset = (uint32_t)offset;
        memcpy(mDir->identifier(), mIdentifier.c_str(), identLength);
        offset += identLength;
 
        // (add new flexibly-allocated fields here)
 
        memcpy(mDir->identifier(), mIdentifier.c_str(), identLength);
        offset += identLength;
 
        // (add new flexibly-allocated fields here)
 
-       mDir->hashOffset = offset + mSpecialSlots * mDigestLength;
+       mDir->hashOffset = (uint32_t)(offset + mSpecialSlots * mDigestLength);
        offset += (mSpecialSlots + mCodeSlots) * mDigestLength;
        assert(offset == total);        // matches allocated size
        
        // fill special slots
        offset += (mSpecialSlots + mCodeSlots) * mDigestLength;
        assert(offset == total);        // matches allocated size
        
        // fill special slots
-       memset((*mDir)[-mSpecialSlots], 0, mDigestLength * mSpecialSlots);
+       memset((*mDir)[(int)-mSpecialSlots], 0, mDigestLength * mSpecialSlots);
        for (size_t slot = 1; slot <= mSpecialSlots; ++slot)
        for (size_t slot = 1; slot <= mSpecialSlots; ++slot)
-               memcpy((*mDir)[-slot], specialSlot(slot), mDigestLength);
+               memcpy((*mDir)[(int)-slot], specialSlot((SpecialSlot)slot), mDigestLength);
        
        // fill code slots
        mExec.seek(mExecOffset);
        
        // fill code slots
        mExec.seek(mExecOffset);
index 3a050bbf158547ae0c87b1470b3fac53fcbe73c0..fd5e54b0c792853aa08871cea7e70a3ff3f40307 100644 (file)
@@ -59,9 +59,9 @@ public:
        size_t size();                                                          // calculate size
        CodeDirectory *build();                                         // build CodeDirectory and return it
 
        size_t size();                                                          // calculate size
        CodeDirectory *build();                                         // build CodeDirectory and return it
 
-private:
        DynamicHash *getHash() const { return CodeDirectory::hashFor(this->mHashType); }
        
        DynamicHash *getHash() const { return CodeDirectory::hashFor(this->mHashType); }
        
+private:
        Hashing::Byte *specialSlot(SpecialSlot slot)
                { assert(slot > 0 && slot <= cdSlotMax); return mSpecial + (slot - 1) * mDigestLength; }
        Hashing::Byte *specialSlot(SpecialSlot slot) const
        Hashing::Byte *specialSlot(SpecialSlot slot)
                { assert(slot > 0 && slot <= cdSlotMax); return mSpecial + (slot - 1) * mDigestLength; }
        Hashing::Byte *specialSlot(SpecialSlot slot) const
index 6ba10f26786556e5774af11ac337b3740d032fce..465b6f927936696dafd3cf01d23f462575ad84db 100644 (file)
@@ -212,7 +212,7 @@ void CFMDiskRep::Writer::flush()
        size_t start = LowLevelMemoryUtilities::alignUp(rep->signingLimit(), 16);
        Sentinel sentinel;
        sentinel.magic = EmbeddedSignatureBlob::typeMagic;
        size_t start = LowLevelMemoryUtilities::alignUp(rep->signingLimit(), 16);
        Sentinel sentinel;
        sentinel.magic = EmbeddedSignatureBlob::typeMagic;
-       sentinel.offset = start;
+       sentinel.offset = (uint32_t)start;
        AutoFileDesc fd(rep->path(), O_RDWR);
        fd.seek(start);
        fd.writeAll(mSigningData, mSigningData->length());
        AutoFileDesc fd(rep->path(), O_RDWR);
        fd.seek(start);
        fd.writeAll(mSigningData, mSigningData->length());
index 4b58413808d7523ef4e6999555dfe1f2ff2f8280..06f67a3239df23a7643a0b82de087df036a9b5fb 100644 (file)
@@ -143,19 +143,18 @@ void CodeDirectory::checkIntegrity() const
        // now check interior offsets for validity
        if (!stringAt(identOffset))
                MacOSError::throwMe(errSecCSSignatureFailed); // identifier out of blob range
        // now check interior offsets for validity
        if (!stringAt(identOffset))
                MacOSError::throwMe(errSecCSSignatureFailed); // identifier out of blob range
-       if (!contains(hashOffset - uint64_t(hashSize) * nSpecialSlots, hashSize * (uint64_t(nSpecialSlots) + nCodeSlots)))
+       if (!contains(hashOffset - int64_t(hashSize) * nSpecialSlots, hashSize * (int64_t(nSpecialSlots) + nCodeSlots)))
                MacOSError::throwMe(errSecCSSignatureFailed); // hash array out of blob range
        if (const Scatter *scatter = this->scatterVector()) {
                // the optional scatter vector is terminated with an element having (count == 0)
                unsigned int pagesConsumed = 0;
                MacOSError::throwMe(errSecCSSignatureFailed); // hash array out of blob range
        if (const Scatter *scatter = this->scatterVector()) {
                // the optional scatter vector is terminated with an element having (count == 0)
                unsigned int pagesConsumed = 0;
-               while (scatter->count) {
+               for (;; scatter++) {
                        if (!contains(scatter, sizeof(Scatter)))
                                MacOSError::throwMe(errSecCSSignatureFailed);
                        if (!contains(scatter, sizeof(Scatter)))
                                MacOSError::throwMe(errSecCSSignatureFailed);
+                       if (scatter->count == 0)
+                               break;
                        pagesConsumed += scatter->count;
                        pagesConsumed += scatter->count;
-                       scatter++;
                }
                }
-               if (!contains(scatter, sizeof(Scatter)))                        // (even sentinel must be in range)
-                       MacOSError::throwMe(errSecCSSignatureFailed);
                if (!contains((*this)[pagesConsumed-1], hashSize))      // referenced too many main hash slots
                        MacOSError::throwMe(errSecCSSignatureFailed);
        }
                if (!contains((*this)[pagesConsumed-1], hashSize))      // referenced too many main hash slots
                        MacOSError::throwMe(errSecCSSignatureFailed);
        }
@@ -217,8 +216,6 @@ DynamicHash *CodeDirectory::hashFor(HashAlgorithm hashType)
        switch (hashType) {
        case kSecCodeSignatureHashSHA1:                                         alg = kCCDigestSHA1; break;
        case kSecCodeSignatureHashSHA256:                                       alg = kCCDigestSHA256; break;
        switch (hashType) {
        case kSecCodeSignatureHashSHA1:                                         alg = kCCDigestSHA1; break;
        case kSecCodeSignatureHashSHA256:                                       alg = kCCDigestSHA256; break;
-       case kSecCodeSignatureHashPrestandardSkein160x256:      alg = kCCDigestSkein160; break;
-       case kSecCodeSignatureHashPrestandardSkein256x512:      alg = kCCDigestSkein256; break;
        default:
                MacOSError::throwMe(errSecCSSignatureUnsupported);
        }
        default:
                MacOSError::throwMe(errSecCSSignatureUnsupported);
        }
@@ -292,6 +289,8 @@ const SecCodeDirectoryFlagTable kSecCodeDirectoryFlagTable[] = {
        { "adhoc",              kSecCodeSignatureAdhoc,                 false },
        { "hard",               kSecCodeSignatureForceHard,             true },
        { "kill",               kSecCodeSignatureForceKill,             true },
        { "adhoc",              kSecCodeSignatureAdhoc,                 false },
        { "hard",               kSecCodeSignatureForceHard,             true },
        { "kill",               kSecCodeSignatureForceKill,             true },
-       { "expires",    kSecCodeSignatureForceExpiration, true },
+       { "expires",            kSecCodeSignatureForceExpiration,       true },
+       { "restrict",           kSecCodeSignatureRestrict,              true },
+       { "enforcement",        kSecCodeSignatureEnforcement,           true },
        { NULL }
 };
        { NULL }
 };
index 1cd9306b5a81007b906081d8945bc5b2308ea0dc..d07e05abb7abd6a8890ebe58a8e479b5e3c44d16 100644 (file)
@@ -35,7 +35,6 @@
 #include <Security/SecRequirementPriv.h>
 #include <Security/SecCodeSigner.h>
 #include <Security/SecBasePriv.h>
 #include <Security/SecRequirementPriv.h>
 #include <Security/SecCodeSigner.h>
 #include <Security/SecBasePriv.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 #include <security_utilities/globalizer.h>
 #include <security_utilities/seccfobject.h>
 #include <security_utilities/cfclass.h>
 #include <security_utilities/globalizer.h>
 #include <security_utilities/seccfobject.h>
 #include <security_utilities/cfclass.h>
@@ -94,9 +93,9 @@ OSStatus dbError(const SQLite3::Error &err);
     catch (const MacOSError &err) { return err.osStatus(); } \
     catch (const SQLite3::Error &err) { return dbError(err); } \
     catch (const CommonError &err) { return SecKeychainErrFromOSStatus(err.osStatus()); } \
     catch (const MacOSError &err) { return err.osStatus(); } \
     catch (const SQLite3::Error &err) { return dbError(err); } \
     catch (const CommonError &err) { return SecKeychainErrFromOSStatus(err.osStatus()); } \
-    catch (const std::bad_alloc &) { return memFullErr; } \
+    catch (const std::bad_alloc &) { return errSecAllocate; } \
     catch (...) { return errSecCSInternalError; } \
     catch (...) { return errSecCSInternalError; } \
-       return noErr;
+       return errSecSuccess;
        
 #define END_CSAPI_ERRORS \
        } \
        
 #define END_CSAPI_ERRORS \
        } \
@@ -109,9 +108,9 @@ OSStatus dbError(const SQLite3::Error &err);
     catch (const MacOSError &err) { return CSError::cfError(errors, err.osStatus()); } \
     catch (const SQLite3::Error &err) { return CSError::cfError(errors, dbError(err)); } \
     catch (const CommonError &err) { return CSError::cfError(errors, SecKeychainErrFromOSStatus(err.osStatus())); } \
     catch (const MacOSError &err) { return CSError::cfError(errors, err.osStatus()); } \
     catch (const SQLite3::Error &err) { return CSError::cfError(errors, dbError(err)); } \
     catch (const CommonError &err) { return CSError::cfError(errors, SecKeychainErrFromOSStatus(err.osStatus())); } \
-    catch (const std::bad_alloc &) { return CSError::cfError(errors, memFullErr); } \
+    catch (const std::bad_alloc &) { return CSError::cfError(errors, errSecAllocate); } \
     catch (...) { return CSError::cfError(errors, errSecCSInternalError); } \
     catch (...) { return CSError::cfError(errors, errSecCSInternalError); } \
-       return noErr;
+       return errSecSuccess;
        
 #define END_CSAPI1(bad)    } catch (...) { return bad; }
 
        
 #define END_CSAPI1(bad)    } catch (...) { return bad; }
 
@@ -127,7 +126,7 @@ OSStatus dbError(const SQLite3::Error &err);
     catch (const MacOSError &err) { CSError::cfError(errors, err.osStatus()); } \
     catch (const SQLite3::Error &err) { CSError::cfError(errors, dbError(err)); } \
     catch (const CommonError &err) { CSError::cfError(errors, SecKeychainErrFromOSStatus(err.osStatus())); } \
     catch (const MacOSError &err) { CSError::cfError(errors, err.osStatus()); } \
     catch (const SQLite3::Error &err) { CSError::cfError(errors, dbError(err)); } \
     catch (const CommonError &err) { CSError::cfError(errors, SecKeychainErrFromOSStatus(err.osStatus())); } \
-    catch (const std::bad_alloc &) { CSError::cfError(errors, memFullErr); } \
+    catch (const std::bad_alloc &) { CSError::cfError(errors, errSecAllocate); } \
     catch (...) { CSError::cfError(errors, errSecCSInternalError); } \
        return bad;
 
     catch (...) { CSError::cfError(errors, errSecCSInternalError); } \
        return bad;
 
index 5772ee6e30adfbef0340cafc04b9b935f179cfe2..b8b0e42f4f287f8ce5592e71809f7f6c64e63914 100644 (file)
@@ -79,7 +79,7 @@ const char schema[] = "\
 // Note that this isn't creating the schema; we do that on first write.
 //
 SignatureDatabase::SignatureDatabase(const char *path, int flags)
 // Note that this isn't creating the schema; we do that on first write.
 //
 SignatureDatabase::SignatureDatabase(const char *path, int flags)
-       : SQLite::Database(path, flags)
+       : SQLite::Database(path, flags, true)   // lenient open
 {
 }
 
 {
 }
 
@@ -99,8 +99,11 @@ FilterRep *SignatureDatabase::findCode(DiskRep *rep)
                                "select code.signature, global.signature from code, global \
                                 where code.identification = ?1 and code.global = global.id;");
                        query.bind(1) = identification.get();
                                "select code.signature, global.signature from code, global \
                                 where code.identification = ?1 and code.global = global.id;");
                        query.bind(1) = identification.get();
-                       if (query.nextRow())
-                               return new DetachedRep(query[0].data(), query[1].data(), rep, "system");
+                       if (query.nextRow()) {
+                               CFRef<CFDataRef> sig = query[0].data();
+                               CFRef<CFDataRef> gsig = query[1].data();
+                               return new DetachedRep(sig, gsig, rep, "system");
+                       }
                }
 
        // no joy
                }
 
        // no joy
@@ -115,6 +118,8 @@ FilterRep *SignatureDatabase::findCode(DiskRep *rep)
 //
 void SignatureDatabaseWriter::storeCode(const BlobCore *sig, const char *location)
 {
 //
 void SignatureDatabaseWriter::storeCode(const BlobCore *sig, const char *location)
 {
+       if (!this->isOpen())    // failed database open or creation
+               MacOSError::throwMe(errSecCSDBAccess);
        Transaction xa(*this, Transaction::exclusive);  // lock out everyone
        if (this->empty())
                this->execute(schema);                                  // initialize schema
        Transaction xa(*this, Transaction::exclusive);  // lock out everyone
        if (this->empty())
                this->execute(schema);                                  // initialize schema
index 95f8e1b104ee468d2616824cfd68317e8552a5dc..1d4b9d1916492c949afea60eed265fbb52237d85 100644 (file)
@@ -68,10 +68,6 @@ private:
 };
 
 
 };
 
 
-extern ModuleNexus<SignatureDatabase> signatureDatabase;
-extern ModuleNexus<SignatureDatabaseWriter> signatureDatabaseWriter;
-
-
 } // end namespace CodeSigning
 } // end namespace Security
 
 } // end namespace CodeSigning
 } // end namespace Security
 
index c67d9467bddb6c97e42b5a3f8e3b93651d79cb37..5913fd7dfea9687ce9ff6811a9f43ca9df1fe15d 100644 (file)
@@ -72,7 +72,7 @@ SecCode *GenericCode::locateGuest(CFDictionaryRef attributes)
                GuestChain guestPath;
                mach_msg_type_number_t guestPathLength;
                mach_port_t subport;
                GuestChain guestPath;
                mach_msg_type_number_t guestPathLength;
                mach_port_t subport;
-               CALL(host, findGuest, guestRef(), attrPtr, attrLength,
+               CALL(host, findGuest, guestRef(), attrPtr, (mach_msg_type_number_t)attrLength,
                        &guestPath, &guestPathLength, &subport);
                CODESIGN_GUEST_LOCATE_GENERIC(this, guestPath, guestPathLength, subport);
                SecPointer<SecCode> code = this;
                        &guestPath, &guestPathLength, &subport);
                CODESIGN_GUEST_LOCATE_GENERIC(this, guestPath, guestPathLength, subport);
                SecPointer<SecCode> code = this;
@@ -106,7 +106,7 @@ SecStaticCode *GenericCode::identifyGuest(SecCode *guest, CFDataRef *cdhashOut)
                SecPointer<GenericStaticCode> code = new GenericStaticCode(DiskRep::bestGuess(path, &ctx));
                CODESIGN_GUEST_IDENTIFY_GENERIC(iguest, iguest->guestRef(), code);
                if (cdhash) {
                SecPointer<GenericStaticCode> code = new GenericStaticCode(DiskRep::bestGuess(path, &ctx));
                CODESIGN_GUEST_IDENTIFY_GENERIC(iguest, iguest->guestRef(), code);
                if (cdhash) {
-                       CODESIGN_GUEST_CDHASH_GENERIC(iguest, (void *)CFDataGetBytePtr(cdhash), CFDataGetLength(cdhash));
+                       CODESIGN_GUEST_CDHASH_GENERIC(iguest, (void *)CFDataGetBytePtr(cdhash), (unsigned)CFDataGetLength(cdhash));
                        *cdhashOut = cdhash.yield();
                }
                return code.yield();
                        *cdhashOut = cdhash.yield();
                }
                return code.yield();
index 9821465db9645e6482c38e0ce331cc31ee0001ad..96f734182937c861d2298e72caf9a69297702618 100644 (file)
@@ -75,11 +75,23 @@ KernelStaticCode::KernelStaticCode()
 SecCode *KernelCode::locateGuest(CFDictionaryRef attributes)
 {
        if (CFTypeRef attr = CFDictionaryGetValue(attributes, kSecGuestAttributePid)) {
 SecCode *KernelCode::locateGuest(CFDictionaryRef attributes)
 {
        if (CFTypeRef attr = CFDictionaryGetValue(attributes, kSecGuestAttributePid)) {
-               if (CFDictionaryGetCount(attributes) != 1)
-                       MacOSError::throwMe(errSecCSUnsupportedGuestAttributes); // had more
-               if (CFGetTypeID(attr) == CFNumberGetTypeID())
-                       return (new ProcessCode(cfNumber<pid_t>(CFNumberRef(attr))))->retain();
-               MacOSError::throwMe(errSecCSInvalidAttributeValues);
+                RefPointer<PidDiskRep> diskRep = NULL;
+                
+                if (CFGetTypeID(attr) != CFNumberGetTypeID())
+                        MacOSError::throwMe(errSecCSInvalidAttributeValues);
+                
+                pid_t pid = cfNumber<pid_t>(CFNumberRef(attr));
+
+                if (CFDictionaryGetValue(attributes, kSecGuestAttributeDynamicCode) != NULL) {
+                        CFDataRef infoPlist = (CFDataRef)CFDictionaryGetValue(attributes, kSecGuestAttributeDynamicCodeInfoPlist);
+                        if (infoPlist && CFGetTypeID(infoPlist) != CFDataGetTypeID())
+                                MacOSError::throwMe(errSecCSInvalidAttributeValues);
+
+                                               try {
+                               diskRep = new PidDiskRep(pid, infoPlist);
+                                               } catch (...) { }
+                }
+                return (new ProcessCode(cfNumber<pid_t>(CFNumberRef(attr)), diskRep))->retain();
        } else
                MacOSError::throwMe(errSecCSUnsupportedGuestAttributes);
 }
        } else
                MacOSError::throwMe(errSecCSUnsupportedGuestAttributes);
 }
@@ -93,11 +105,23 @@ SecCode *KernelCode::locateGuest(CFDictionaryRef attributes)
 SecStaticCode *KernelCode::identifyGuest(SecCode *iguest, CFDataRef *cdhash)
 {
        if (ProcessCode *guest = dynamic_cast<ProcessCode *>(iguest)) {
 SecStaticCode *KernelCode::identifyGuest(SecCode *iguest, CFDataRef *cdhash)
 {
        if (ProcessCode *guest = dynamic_cast<ProcessCode *>(iguest)) {
+                
+                if (guest->pidBased()) {
+                       
+                        SecPointer<SecStaticCode> code = new ProcessDynamicCode(guest);
+
+                        SHA1::Digest kernelHash;
+                        MacOSError::check(::csops(guest->pid(), CS_OPS_CDHASH, kernelHash, sizeof(kernelHash)));
+                        *cdhash = makeCFData(kernelHash, sizeof(kernelHash));
+
+                        return code.yield();
+                }
+                
                char path[2 * MAXPATHLEN];      // reasonable upper limit
                if (::proc_pidpath(guest->pid(), path, sizeof(path))) {
                        off_t offset;
                        csops(guest, CS_OPS_PIDOFFSET, &offset, sizeof(offset));
                char path[2 * MAXPATHLEN];      // reasonable upper limit
                if (::proc_pidpath(guest->pid(), path, sizeof(path))) {
                        off_t offset;
                        csops(guest, CS_OPS_PIDOFFSET, &offset, sizeof(offset));
-                       SecPointer<SecStaticCode> code = new ProcessStaticCode(DiskRep::bestGuess(path, offset));
+                       SecPointer<SecStaticCode> code = new ProcessStaticCode(DiskRep::bestGuess(path, (size_t)offset));
                        CODESIGN_GUEST_IDENTIFY_PROCESS(guest, guest->pid(), code);
                        if (cdhash) {
                                SHA1::Digest kernelHash;
                        CODESIGN_GUEST_IDENTIFY_PROCESS(guest, guest->pid(), code);
                        if (cdhash) {
                                SHA1::Digest kernelHash;
index 0d14392ad4463342882a7f3126ad631014fb20a3..5d3b5878899964d73ebcd5b7eb9466be87033fda 100644 (file)
@@ -27,6 +27,7 @@
 #include "csprocess.h"
 #include "cskernel.h"
 #include <securityd_client/ssclient.h>
 #include "csprocess.h"
 #include "cskernel.h"
 #include <securityd_client/ssclient.h>
+#include <System/sys/codesign.h>
 
 namespace Security {
 namespace CodeSigning {
 
 namespace Security {
 namespace CodeSigning {
@@ -35,8 +36,8 @@ namespace CodeSigning {
 //
 // Construct a running process representation
 //
 //
 // Construct a running process representation
 //
-ProcessCode::ProcessCode(pid_t pid)
-       : GenericCode(KernelCode::active()), mPid(pid)
+ProcessCode::ProcessCode(pid_t pid, PidDiskRep *pidDiskRep /*= NULL */)
+       : GenericCode(KernelCode::active()), mPid(pid), mPidBased(pidDiskRep)
 {
 }
 
 {
 }
 
@@ -46,6 +47,41 @@ mach_port_t ProcessCode::getHostingPort()
        return SecurityServer::ClientSession().hostingPort(pid());
 }
 
        return SecurityServer::ClientSession().hostingPort(pid());
 }
 
+/*
+ *
+ */
+        
+ProcessDynamicCode::ProcessDynamicCode(ProcessCode *guest)
+        : SecStaticCode(guest->pidBased()), mGuest(guest)
+{
+}
+
+CFDataRef ProcessDynamicCode::component(CodeDirectory::SpecialSlot slot, OSStatus fail /* = errSecCSSignatureFailed */)
+{
+        if (slot == cdInfoSlot && !mGuest->pidBased()->supportInfoPlist())
+                return NULL;
+        else if (slot == cdResourceDirSlot)
+                return NULL;
+        return SecStaticCode::component(slot, fail);
+}
+
+CFDictionaryRef ProcessDynamicCode::infoDictionary()
+{
+        if (mGuest->pidBased()->supportInfoPlist())
+                return SecStaticCode::infoDictionary();
+        return makeCFDictionary(0);
+}
+
+void ProcessDynamicCode::validateComponent(CodeDirectory::SpecialSlot slot, OSStatus fail /* = errSecCSSignatureFailed */)
+{
+        if (slot == cdInfoSlot && !mGuest->pidBased()->supportInfoPlist())
+                return;
+        else if (slot == cdResourceDirSlot)
+                return;
+        SecStaticCode::validateComponent(slot, fail);
+}
+
 
 
+        
 } // CodeSigning
 } // Security
 } // CodeSigning
 } // Security
index 7fd6efc7a5c68eda4c59f2d272bcfbc60cbaa4fd..fcc908ab292f40a14d3be0d635f25db146e17ab2 100644 (file)
@@ -28,6 +28,8 @@
 #define _H_CSPROCESS
 
 #include "csgeneric.h"
 #define _H_CSPROCESS
 
 #include "csgeneric.h"
+#include "StaticCode.h"
+#include "PidDiskRep.h"
 #include <security_utilities/utilities.h>
 
 namespace Security {
 #include <security_utilities/utilities.h>
 
 namespace Security {
@@ -43,14 +45,17 @@ namespace CodeSigning {
 //
 class ProcessCode : public GenericCode {
 public:
 //
 class ProcessCode : public GenericCode {
 public:
-       ProcessCode(pid_t pid);
+       ProcessCode(pid_t pid, PidDiskRep *pidDiskRep = NULL);
+       ~ProcessCode() throw () { }
        
        pid_t pid() const { return mPid; }
        
        pid_t pid() const { return mPid; }
+        PidDiskRep *pidBased() const { return mPidBased; }
 
        mach_port_t getHostingPort();
 
 private:
        pid_t mPid;
 
        mach_port_t getHostingPort();
 
 private:
        pid_t mPid;
+       RefPointer<PidDiskRep> mPidBased;
 };
 
 
 };
 
 
@@ -58,7 +63,20 @@ private:
 // We don't need a GenericCode variant of ProcessCode
 //
 typedef SecStaticCode ProcessStaticCode;
 // We don't need a GenericCode variant of ProcessCode
 //
 typedef SecStaticCode ProcessStaticCode;
+        
+class ProcessDynamicCode : public SecStaticCode {
+public:
+       ProcessDynamicCode(ProcessCode *diskRep);
+
+        CFDataRef component(CodeDirectory::SpecialSlot slot, OSStatus fail = errSecCSSignatureFailed);
+        
+        CFDictionaryRef infoDictionary();
+        
+        void validateComponent(CodeDirectory::SpecialSlot slot, OSStatus fail = errSecCSSignatureFailed);
+private:
+        ProcessCode *mGuest;
 
 
+};
 
 } // end namespace CodeSigning
 } // end namespace Security
 
 } // end namespace CodeSigning
 } // end namespace Security
index c3d3d9268a8b297befbbea497fcd9a0b8e66442d..0f33281e5e7697b10a8f702eee0630e8e638d987 100644 (file)
@@ -101,7 +101,7 @@ bool certificateHasField(SecCertificateRef cert, const CSSM_OID &oid)
        assert(cert);
        CSSM_DATA *value;
        switch (OSStatus rc = SecCertificateCopyFirstFieldValue(cert, &oid, &value)) {
        assert(cert);
        CSSM_DATA *value;
        switch (OSStatus rc = SecCertificateCopyFirstFieldValue(cert, &oid, &value)) {
-       case noErr:
+       case errSecSuccess:
                MacOSError::check(SecCertificateReleaseFirstFieldValue(cert, &oid, value));
                return true;                                    // extension found by oid
        case errSecUnknownTag:
                MacOSError::check(SecCertificateReleaseFirstFieldValue(cert, &oid, value));
                return true;                                    // extension found by oid
        case errSecUnknownTag:
index ebe3590bea926a366ec943e555c41d25f72da81c..664d6e2c4f8ba7ca86e954cf6dd332631b6e9c27 100644 (file)
@@ -130,6 +130,7 @@ private:
 class MessageTrace {
 public:
        MessageTrace(const char *domain, const char *signature);
 class MessageTrace {
 public:
        MessageTrace(const char *domain, const char *signature);
+       ~MessageTrace() { ::asl_free(mAsl); }
        void add(const char *key, const char *format, ...);
        void send(const char *format, ...);
 
        void add(const char *key, const char *format, ...);
        void send(const char *format, ...);
 
index 348a8ed055b02decc905d6274fd52413013b3658..c7c5b8e3accdd3c640adf9ac269d4d5ce2cb9104 100644 (file)
@@ -39,7 +39,7 @@ namespace CodeSigning {
 // of EmbeddedSignatureBlobs.
 //
 DetachedRep::DetachedRep(CFDataRef sig, DiskRep *orig, const std::string &source)
 // of EmbeddedSignatureBlobs.
 //
 DetachedRep::DetachedRep(CFDataRef sig, DiskRep *orig, const std::string &source)
-       : FilterRep(orig), mSig(sig), mSource(source)
+       : FilterRep(orig), mSig(sig), mFull(true), mSource(source)
 {
        const BlobCore *sigBlob = reinterpret_cast<const BlobCore *>(CFDataGetBytePtr(sig));
        if (sigBlob->is<EmbeddedSignatureBlob>()) {             // architecture-less
 {
        const BlobCore *sigBlob = reinterpret_cast<const BlobCore *>(CFDataGetBytePtr(sig));
        if (sigBlob->is<EmbeddedSignatureBlob>()) {             // architecture-less
@@ -66,7 +66,7 @@ DetachedRep::DetachedRep(CFDataRef sig, DiskRep *orig, const std::string &source
 // and (optional) associated global blob. Just take them.
 //
 DetachedRep::DetachedRep(CFDataRef sig, CFDataRef gsig, DiskRep *orig, const std::string &source)
 // and (optional) associated global blob. Just take them.
 //
 DetachedRep::DetachedRep(CFDataRef sig, CFDataRef gsig, DiskRep *orig, const std::string &source)
-       : FilterRep(orig), mSig(sig), mGSig(gsig), mSource(source)
+       : FilterRep(orig), mSig(sig), mGSig(gsig), mFull(false), mSource(source)
 {
        const BlobCore *sigBlob = reinterpret_cast<const BlobCore *>(CFDataGetBytePtr(sig));
        mArch = EmbeddedSignatureBlob::specific(sigBlob);
 {
        const BlobCore *sigBlob = reinterpret_cast<const BlobCore *>(CFDataGetBytePtr(sig));
        mArch = EmbeddedSignatureBlob::specific(sigBlob);
index 9802b2e8a50a8048f0f39c562fa8b61d37524653..5851f2e035fa9ffba4517777eb909e5c4c664565 100644 (file)
@@ -53,10 +53,12 @@ public:
        
        CFDataRef component(CodeDirectory::SpecialSlot slot);
        
        
        CFDataRef component(CodeDirectory::SpecialSlot slot);
        
+       bool fullSignature() const { return mFull; }
        const std::string &source() const { return mSource; }
 
 private:
        const std::string &source() const { return mSource; }
 
 private:
-       CFRef<CFDataRef> mSig, mGSig;
+       CFCopyRef<CFDataRef> mSig, mGSig;
+       bool mFull;                                                             // full detached signature (explicitly given)
        const EmbeddedSignatureBlob *mArch;             // current architecture; points into mSignature
        const EmbeddedSignatureBlob *mGlobal;   // shared elements; points into mSignature
        std::string mSource;                                    // source description (readable)
        const EmbeddedSignatureBlob *mArch;             // current architecture; points into mSignature
        const EmbeddedSignatureBlob *mGlobal;   // shared elements; points into mSignature
        std::string mSource;                                    // source description (readable)
index 4a6beb5df13b9bce467fa27cde131ac8a1e6f95d..e5de06be354d5f5fd4da29203eb7864d6f61388f 100644 (file)
@@ -40,6 +40,8 @@
 namespace Security {
 namespace CodeSigning {
 
 namespace Security {
 namespace CodeSigning {
 
+class ResourceBuilder;
+
 
 //
 // DiskRep is an abstract interface to code somewhere located by
 
 //
 // DiskRep is an abstract interface to code somewhere located by
@@ -116,6 +118,7 @@ public:
        public:
                virtual std::string sdkPath(const std::string &path) const = 0;
                virtual bool isAdhoc() const = 0;
        public:
                virtual std::string sdkPath(const std::string &path) const = 0;
                virtual bool isAdhoc() const = 0;
+               virtual SecCSFlags signingFlags() const = 0;
        };
 
 protected:
        };
 
 protected:
index ac735edff384d2185f10dc3b61cecf799b3fee8c..b3ed84372777abaadc95d3d45a61ffac70b4e690 100644 (file)
@@ -47,7 +47,7 @@ MachORep::MachORep(const char *path, const Context *ctx)
 {
        if (ctx)
                if (ctx->offset)
 {
        if (ctx)
                if (ctx->offset)
-                       mExecutable = new Universal(fd(), ctx->offset);
+                       mExecutable = new Universal(fd(), (size_t)ctx->offset);
                else if (ctx->arch) {
                        auto_ptr<Universal> full(new Universal(fd()));
                        mExecutable = new Universal(fd(), full->archOffset(ctx->arch));
                else if (ctx->arch) {
                        auto_ptr<Universal> full(new Universal(fd()));
                        mExecutable = new Universal(fd(), full->archOffset(ctx->arch));
@@ -204,7 +204,7 @@ CFDataRef MachORep::infoPlist()
                if (const section *sect = macho->findSection("__TEXT", "__info_plist")) {
                        if (macho->is64()) {
                                const section_64 *sect64 = reinterpret_cast<const section_64 *>(sect);
                if (const section *sect = macho->findSection("__TEXT", "__info_plist")) {
                        if (macho->is64()) {
                                const section_64 *sect64 = reinterpret_cast<const section_64 *>(sect);
-                               info.take(macho->dataAt(macho->flip(sect64->offset), macho->flip(sect64->size)));
+                               info.take(macho->dataAt(macho->flip(sect64->offset), (size_t)macho->flip(sect64->size)));
                        } else {
                                info.take(macho->dataAt(macho->flip(sect->offset), macho->flip(sect->size)));
                        }
                        } else {
                                info.take(macho->dataAt(macho->flip(sect->offset), macho->flip(sect->size)));
                        }
diff --git a/libsecurity_codesigning/lib/piddiskrep.cpp b/libsecurity_codesigning/lib/piddiskrep.cpp
new file mode 100644 (file)
index 0000000..aafba02
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2012 Apple Computer, Inc. All Rights Reserved.
+ * 
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#include "piddiskrep.h"
+#include "sigblob.h"
+#include <sys/param.h>
+#include <sys/utsname.h>
+#include <System/sys/codesign.h>
+#include <libproc.h>
+#include <xpc/xpc.h>
+
+namespace Security {
+namespace CodeSigning {
+                
+using namespace UnixPlusPlus;
+        
+void
+PidDiskRep::fetchData(void)
+{
+       xpc_connection_t conn = xpc_connection_create("com.apple.CodeSigningHelper",
+                                                     dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
+       xpc_connection_set_event_handler(conn, ^(xpc_object_t object){ });
+       xpc_connection_resume(conn);
+       
+       xpc_object_t request = xpc_dictionary_create(NULL, NULL, 0);
+       assert(request != NULL);
+       xpc_dictionary_set_string(request, "command", "fetchData");
+       xpc_dictionary_set_int64(request, "pid", mPid);
+        
+       xpc_object_t reply = xpc_connection_send_message_with_reply_sync(conn, request);
+       if (reply && xpc_get_type(reply) == XPC_TYPE_DICTIONARY) {
+               const void *data;
+               size_t size;
+
+               if (!mInfoPlist) {
+                       data = xpc_dictionary_get_data(reply, "infoPlist", &size);
+                       if (data && size > 0 && size < 50 * 1024)
+                               mInfoPlist.take(CFDataCreate(NULL, (const UInt8 *)data, (CFIndex)size));
+               }
+               if (!mBundleURL) {
+                       data = xpc_dictionary_get_data(reply, "bundleURL", &size);
+                       if (data && size > 0 && size < 50 * 1024)
+                               mBundleURL.take(CFURLCreateWithBytes(NULL, (const UInt8 *)data, (CFIndex)size, kCFStringEncodingUTF8, NULL));
+               }
+       }
+       if (reply)
+               xpc_release(reply);
+
+       xpc_release(request);
+       xpc_release(conn);
+}
+
+
+PidDiskRep::PidDiskRep(pid_t pid, CFDataRef infoPlist)
+{
+        BlobCore header;
+        CODESIGN_DISKREP_CREATE_KERNEL(this);
+        
+        mPid = pid;
+        mInfoPlist = infoPlist;
+
+       fetchData();
+        
+        int rcent = ::csops(pid, CS_OPS_BLOB, &header, sizeof(header));
+        if (rcent == 0)
+                MacOSError::throwMe(errSecCSNoSuchCode);
+        
+        if (errno != ERANGE)
+                UnixError::throwMe(errno);
+
+        if (header.length() > 1024 * 1024)
+                MacOSError::throwMe(errSecCSNoSuchCode);
+        
+        uint32_t bufferLen = (uint32_t)header.length();
+        mBuffer = new uint8_t [bufferLen];
+        
+        UnixError::check(::csops(pid, CS_OPS_BLOB, mBuffer, bufferLen));
+
+        const BlobCore *b = (const BlobCore *)mBuffer;
+               if (b->magic() != kSecCodeMagicEmbeddedSignature)
+                       MacOSError::throwMe(errSecCSSignatureInvalid);
+        if (b->length() < sizeof(*b))
+                MacOSError::throwMe(errSecCSNoSuchCode);
+}
+
+PidDiskRep::~PidDiskRep()
+{
+        if (mBuffer)
+                delete [] mBuffer;
+}
+
+
+bool PidDiskRep::supportInfoPlist()
+{
+        return mInfoPlist;
+}
+
+
+CFDataRef PidDiskRep::component(CodeDirectory::SpecialSlot slot)
+{
+       if (slot == cdInfoSlot)
+                return mInfoPlist.retain();
+
+        EmbeddedSignatureBlob *b = (EmbeddedSignatureBlob *)this->blob();
+        return b->component(slot);
+}
+
+CFDataRef PidDiskRep::identification()
+{
+        return NULL;
+}
+
+
+CFURLRef PidDiskRep::canonicalPath()
+{
+        return mBundleURL.retain();
+}
+
+string PidDiskRep::recommendedIdentifier(const SigningContext &)
+{
+       return string("pid") + to_string(mPid);
+}
+
+size_t PidDiskRep::signingLimit()
+{
+        return 0;
+}
+
+string PidDiskRep::format()
+{
+        return "pid diskrep";
+}
+
+UnixPlusPlus::FileDesc &PidDiskRep::fd()
+{
+        UnixError::throwMe(EINVAL);
+}
+
+string PidDiskRep::mainExecutablePath()
+{
+        char path[MAXPATHLEN * 2];
+        if(::proc_pidpath(mPid, path, sizeof(path)) == 0)
+               UnixError::throwMe(errno);
+
+        return path;
+}
+                
+                
+} // end namespace CodeSigning
+} // end namespace Security
diff --git a/libsecurity_codesigning/lib/piddiskrep.h b/libsecurity_codesigning/lib/piddiskrep.h
new file mode 100644 (file)
index 0000000..b7f4215
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2012 Apple Computer, Inc. All Rights Reserved.
+ * 
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+//
+// PidDiskRep
+//
+#ifndef _H_PIDDISKREP
+#define _H_PIDDISKREP
+
+#include "diskrep.h"
+
+namespace Security {
+namespace CodeSigning {
+                
+                
+//
+// A KernelDiskRep represents a (the) kernel on disk.
+// It has no write support, so we can't sign the kernel,
+// which is fine since we unconditionally trust it anyway.
+//
+class PidDiskRep : public DiskRep {
+public:
+        PidDiskRep(pid_t pid, CFDataRef infoPlist);
+        ~PidDiskRep();
+        
+        CFDataRef component(CodeDirectory::SpecialSlot slot);
+        CFDataRef identification();
+        std::string mainExecutablePath();
+        CFURLRef canonicalPath();
+        size_t signingLimit();
+        std::string format();
+        UnixPlusPlus::FileDesc &fd();
+        
+        std::string recommendedIdentifier(const SigningContext &ctx);
+        
+        bool supportInfoPlist();
+private:
+        const BlobCore *blob() { return (const BlobCore *)mBuffer; }
+       void fetchData(void);
+        pid_t mPid;
+        uint8_t *mBuffer;
+        CFRef<CFDataRef> mInfoPlist;
+       CFRef<CFURLRef> mBundleURL;
+};
+                
+                
+} // end namespace CodeSigning
+} // end namespace Security
+
+#endif // !_H_PIDDISKREP
index de0207ddcbad5a4438eb53f5da8e5050c9b15989..1746799055ffecba91179161aa49f605d2af9756 100644 (file)
@@ -124,7 +124,7 @@ PolicyDatabase::~PolicyDatabase()
 // Quick-check the cache for a match.
 // Return true on a cache hit, false on failure to confirm a hit for any reason.
 //
 // Quick-check the cache for a match.
 // Return true on a cache hit, false on failure to confirm a hit for any reason.
 //
-bool PolicyDatabase::checkCache(CFURLRef path, AuthorityType type, CFMutableDictionaryRef result)
+bool PolicyDatabase::checkCache(CFURLRef path, AuthorityType type, SecAssessmentFlags flags, CFMutableDictionaryRef result)
 {
        // we currently don't use the cache for anything but execution rules
        if (type != kAuthorityExecute)
 {
        // we currently don't use the cache for anything but execution rules
        if (type != kAuthorityExecute)
@@ -132,7 +132,7 @@ bool PolicyDatabase::checkCache(CFURLRef path, AuthorityType type, CFMutableDict
        
        CFRef<SecStaticCodeRef> code;
        MacOSError::check(SecStaticCodeCreateWithPath(path, kSecCSDefaultFlags, &code.aref()));
        
        CFRef<SecStaticCodeRef> code;
        MacOSError::check(SecStaticCodeCreateWithPath(path, kSecCSDefaultFlags, &code.aref()));
-       if (SecStaticCodeCheckValidity(code, kSecCSBasicValidateOnly, NULL) != noErr)
+       if (SecStaticCodeCheckValidity(code, kSecCSBasicValidateOnly, NULL) != errSecSuccess)
                return false;   // quick pass - any error is a cache miss
        CFRef<CFDictionaryRef> info;
        MacOSError::check(SecCodeCopySigningInformation(code, kSecCSDefaultFlags, &info.aref()));
                return false;   // quick pass - any error is a cache miss
        CFRef<CFDictionaryRef> info;
        MacOSError::check(SecCodeCopySigningInformation(code, kSecCSDefaultFlags, &info.aref()));
@@ -154,11 +154,11 @@ bool PolicyDatabase::checkCache(CFURLRef path, AuthorityType type, CFMutableDict
                // we are overriding the assessement, since that force
                // the verdict to 'pass' at the end
 
                // we are overriding the assessement, since that force
                // the verdict to 'pass' at the end
 
-               if (allow && !overrideAssessment())
+               if (allow && !overrideAssessment(flags))
                    MacOSError::check(SecStaticCodeCheckValidity(code, kSecCSDefaultFlags, NULL));
 
                cfadd(result, "{%O=%B}", kSecAssessmentAssessmentVerdict, allow);
                    MacOSError::check(SecStaticCodeCheckValidity(code, kSecCSDefaultFlags, NULL));
 
                cfadd(result, "{%O=%B}", kSecAssessmentAssessmentVerdict, allow);
-               PolicyEngine::addAuthority(result, label, auth, kCFBooleanTrue);
+               PolicyEngine::addAuthority(flags, result, label, auth, kCFBooleanTrue);
                return true;
        }
        return false;
                return true;
        }
        return false;
@@ -199,12 +199,15 @@ std::string PolicyDatabase::featureLevel(const char *name)
 {
        SQLite::Statement feature(*this, "SELECT value FROM feature WHERE name=:name");
        feature.bind(":name") = name;
 {
        SQLite::Statement feature(*this, "SELECT value FROM feature WHERE name=:name");
        feature.bind(":name") = name;
-       if (feature.nextRow())
-               return feature[0].string();
-       else
-               return "";              // new feature (no level)
+       if (feature.nextRow()) {
+               if (const char *value = feature[0])
+                       return value;
+               else
+                       return "default";       // old engineering versions may have NULL values; tolerate this
+       }
+       return "";              // new feature (no level)
 }
 }
-    
+
 void PolicyDatabase::addFeature(const char *name, const char *value, const char *remarks)
 {
        SQLite::Statement feature(*this, "INSERT OR REPLACE INTO feature (name,value,remarks) VALUES(:name, :value, :remarks)");
 void PolicyDatabase::addFeature(const char *name, const char *value, const char *remarks)
 {
        SQLite::Statement feature(*this, "INSERT OR REPLACE INTO feature (name,value,remarks) VALUES(:name, :value, :remarks)");
@@ -217,9 +220,9 @@ void PolicyDatabase::addFeature(const char *name, const char *value, const char
 void PolicyDatabase::simpleFeature(const char *feature, void (^perform)())
 {
        if (!hasFeature(feature)) {
 void PolicyDatabase::simpleFeature(const char *feature, void (^perform)())
 {
        if (!hasFeature(feature)) {
-               addFeature(feature, "upgraded", "upgraded");
                SQLite::Transaction update(*this);
                perform();
                SQLite::Transaction update(*this);
                perform();
+               addFeature(feature, "upgraded", "upgraded");
                update.commit();
        }
 }
                update.commit();
        }
 }
@@ -228,7 +231,6 @@ void PolicyDatabase::simpleFeature(const char *feature, const char *sql)
 {
        simpleFeature(feature, ^{
                SQLite::Statement perform(*this, sql);
 {
        simpleFeature(feature, ^{
                SQLite::Statement perform(*this, sql);
-               addFeature(feature, "upgraded", "upgraded");
                perform.execute();
        });
 }
                perform.execute();
        });
 }
@@ -309,8 +311,9 @@ void PolicyDatabase::installExplicitSet(const char *authfile, const char *sigfil
                        if (sigfile)
                                if (FILE *sigs = fopen(sigfile, "r")) {
                                        unsigned count = 0;
                        if (sigfile)
                                if (FILE *sigs = fopen(sigfile, "r")) {
                                        unsigned count = 0;
+                                   SignatureDatabaseWriter db;
                                        while (const BlobCore *blob = BlobCore::readBlob(sigs)) {
                                        while (const BlobCore *blob = BlobCore::readBlob(sigs)) {
-                                               signatureDatabaseWriter().storeCode(blob, "<remote>");
+                                               db.storeCode(blob, "<remote>");
                                                count++;
                                        }
                                        secdebug("gkupgrade", "%d detached signature(s) loaded from override data", count);
                                                count++;
                                        }
                                        secdebug("gkupgrade", "%d detached signature(s) loaded from override data", count);
@@ -335,15 +338,24 @@ void PolicyDatabase::installExplicitSet(const char *authfile, const char *sigfil
                                " VALUES (:type, 1, :requirement, 'GKE', :filter, :flags, :path)");
                        for (CFIndex n = 0; n < count; n++) {
                                CFDictionary info(values[n], errSecCSDbCorrupt);
                                " VALUES (:type, 1, :requirement, 'GKE', :filter, :flags, :path)");
                        for (CFIndex n = 0; n < count; n++) {
                                CFDictionary info(values[n], errSecCSDbCorrupt);
+                               uint32_t flags = kAuthorityFlagWhitelist;
+                               if (CFNumberRef versionRef = info.get<CFNumberRef>("version")) {
+                                       int version = cfNumber<int>(versionRef);
+                                       if (version >= 2)
+                                               flags |= kAuthorityFlagWhitelistV2;
+                               }
                                insert.reset();
                                insert.bind(":type") = cfString(info.get<CFStringRef>(CFSTR("type")));
                                insert.bind(":path") = cfString(info.get<CFStringRef>(CFSTR("path")));
                                insert.bind(":requirement") = "cdhash H\"" + cfString(info.get<CFStringRef>(CFSTR("cdhash"))) + "\"";
                                insert.bind(":filter") = cfString(info.get<CFStringRef>(CFSTR("screen")));
                                insert.reset();
                                insert.bind(":type") = cfString(info.get<CFStringRef>(CFSTR("type")));
                                insert.bind(":path") = cfString(info.get<CFStringRef>(CFSTR("path")));
                                insert.bind(":requirement") = "cdhash H\"" + cfString(info.get<CFStringRef>(CFSTR("cdhash"))) + "\"";
                                insert.bind(":filter") = cfString(info.get<CFStringRef>(CFSTR("screen")));
-                               insert.bind(":flags") = kAuthorityFlagWhitelist;
+                               insert.bind(":flags").integer(flags);
                                insert();
                        }
                        
                                insert();
                        }
                        
+                       // we just changed the authority configuration at priority zero
+                       this->purgeObjects(0);
+                       
                        // update version and commit
                        addFeature("gke", authUUID.c_str(), "gke loaded");
                        loadAuth.commit();
                        // update version and commit
                        addFeature("gke", authUUID.c_str(), "gke loaded");
                        loadAuth.commit();
@@ -361,7 +373,7 @@ void PolicyDatabase::installExplicitSet(const char *authfile, const char *sigfil
 #define SP_ENABLED CFSTR("yes")
 #define SP_DISABLED CFSTR("no")
 
 #define SP_ENABLED CFSTR("yes")
 #define SP_DISABLED CFSTR("no")
 
-bool overrideAssessment()
+bool overrideAssessment(SecAssessmentFlags flags /* = 0 */)
 {
        static bool enabled = true;
        static dispatch_once_t once;
 {
        static bool enabled = true;
        static dispatch_once_t once;
@@ -370,6 +382,9 @@ bool overrideAssessment()
        static dispatch_queue_t queue;
        int check;
 
        static dispatch_queue_t queue;
        int check;
 
+       if (flags & kSecAssessmentFlagEnforce)  // explicitly disregard disables (force on)
+               return false;
+
        if (have_token && notify_check(token, &check) == NOTIFY_STATUS_OK && !check)
                return !enabled;
 
        if (have_token && notify_check(token, &check) == NOTIFY_STATUS_OK && !check)
                return !enabled;
 
index 643b4fe4f57ef2546d703ba8ed537a825a893c5b..5614f4fcb452642ed788258fa5fcf649c5c9e841 100644 (file)
@@ -23,6 +23,7 @@
 #ifndef _H_POLICYDB
 #define _H_POLICYDB
 
 #ifndef _H_POLICYDB
 #define _H_POLICYDB
 
+#include "SecAssessment.h"
 #include <security_utilities/globalizer.h>
 #include <security_utilities/hashing.h>
 #include <security_utilities/sqlite++.h>
 #include <security_utilities/globalizer.h>
 #include <security_utilities/hashing.h>
 #include <security_utilities/sqlite++.h>
@@ -38,6 +39,8 @@ namespace SQLite = SQLite3;
 static const char defaultDatabase[] = "/var/db/SystemPolicy";
 static const char visibleSecurityFlagFile[] = "/var/db/.sp_visible"; /* old duchess/emir style configration */
 static const char prefsFile[] = "/var/db/SystemPolicy-prefs.plist";
 static const char defaultDatabase[] = "/var/db/SystemPolicy";
 static const char visibleSecurityFlagFile[] = "/var/db/.sp_visible"; /* old duchess/emir style configration */
 static const char prefsFile[] = "/var/db/SystemPolicy-prefs.plist";
+static const char lastRejectFile[] = "/var/db/.LastGKReject";
+static const char lastApprovedFile[] = "/var/db/.LastGKApp";
 
 static const char gkeAuthFile[] = "/var/db/gke.auth";
 static const char gkeSigsFile[] = "/var/db/gke.sigs";
 
 static const char gkeAuthFile[] = "/var/db/gke.auth";
 static const char gkeSigsFile[] = "/var/db/gke.sigs";
@@ -77,6 +80,7 @@ enum {
        kAuthorityFlagDefault = 0x0002, // rule is part of the original default set
        kAuthorityFlagInhibitCache = 0x0004, // never cache outcome of this rule
        kAuthorityFlagWhitelist = 0x1000,       // whitelist override
        kAuthorityFlagDefault = 0x0002, // rule is part of the original default set
        kAuthorityFlagInhibitCache = 0x0004, // never cache outcome of this rule
        kAuthorityFlagWhitelist = 0x1000,       // whitelist override
+       kAuthorityFlagWhitelistV2 = 0x2000, // apply "deep" signature to this record
 };
 
 
 };
 
 
@@ -100,7 +104,7 @@ public:
        virtual ~PolicyDatabase();
        
 public:
        virtual ~PolicyDatabase();
        
 public:
-       bool checkCache(CFURLRef path, AuthorityType type, CFMutableDictionaryRef result);
+       bool checkCache(CFURLRef path, AuthorityType type, SecAssessmentFlags flags, CFMutableDictionaryRef result);
 
 public:
        void purgeAuthority();
 
 public:
        void purgeAuthority();
@@ -124,7 +128,7 @@ private:
 //
 // Check the system-wide overriding flag file
 //
 //
 // Check the system-wide overriding flag file
 //
-bool overrideAssessment();
+bool overrideAssessment(SecAssessmentFlags flags = 0);
 void setAssessment(bool masterSwitch);
 
 } // end namespace CodeSigning
 void setAssessment(bool masterSwitch);
 
 } // end namespace CodeSigning
index bbd91e0939e51ae9f26c8990047952707d74f8e5..31f1182197cd316f3e776e9173270fcd23837895 100644 (file)
@@ -63,7 +63,6 @@ enum {
 
 
 static void authorizeUpdate(SecAssessmentFlags flags, CFDictionaryRef context);
 
 
 static void authorizeUpdate(SecAssessmentFlags flags, CFDictionaryRef context);
-static void normalizeTarget(CFRef<CFTypeRef> &target, CFDictionary &context, std::string *signUnsigned = NULL);
 static bool codeInvalidityExceptions(SecStaticCodeRef code, CFMutableDictionaryRef result);
 static CFTypeRef installerPolicy() CF_RETURNS_RETAINED;
 
 static bool codeInvalidityExceptions(SecStaticCodeRef code, CFMutableDictionaryRef result);
 static CFTypeRef installerPolicy() CF_RETURNS_RETAINED;
 
@@ -90,7 +89,7 @@ void PolicyEngine::evaluate(CFURLRef path, AuthorityType type, SecAssessmentFlag
 
        switch (type) {
        case kAuthorityExecute:
 
        switch (type) {
        case kAuthorityExecute:
-               evaluateCode(path, kAuthorityExecute, flags, context, result);
+               evaluateCode(path, kAuthorityExecute, flags, context, result, true);
                break;
        case kAuthorityInstall:
                evaluateInstall(path, flags, context, result);
                break;
        case kAuthorityInstall:
                evaluateInstall(path, flags, context, result);
@@ -105,56 +104,7 @@ void PolicyEngine::evaluate(CFURLRef path, AuthorityType type, SecAssessmentFlag
 }
 
 
 }
 
 
-//
-// Whitelist pre-screen processing.
-// Whitelist-matching unsigned code is expensive since we have to generate a full code signature
-// just to see if we match a whitelist authority entry. This class generates a light(er)-weight
-// prescreen and matches it against a hint in an authority record generated from the (detached recorded)
-// code signature at time of whitelist recording.
-// This is just a heuristic to cheaply rule out guaranteed mismatches. When in doubt, we go ahead
-// and do the full work.
-//
-class WhitelistPrescreen {
-public:
-       WhitelistPrescreen(SecStaticCodeRef code)
-               : mRep(SecStaticCode::requiredStatic(code)->diskRep()) { }
-
-       bool reject(const char *screen, const char *remarks);
-       
-private:
-       std::string create(char type, SHA1 &hash);
-
-       RefPointer<DiskRep> mRep;       // DiskRep representing the code
-       std::string mScreen;    // calculated screen (on demand)
-};
-
-bool WhitelistPrescreen::reject(const char *screen, const char *remarks)
-{
-       if (!screen) {  // authority record has no screen to match - apply heuristic
-               if (remarks && mRep->mainExecutablePath() != remarks)   // not an allow record (or moved)
-                       return true;
-               else
-                       return false;   // can't rule out; proceed
-       }
-
-       if (mScreen.empty()) {
-               if (CFRef<CFDataRef> info = mRep->component(cdInfoSlot)) {
-                       SHA1 hash;
-                       hash.update(CFDataGetBytePtr(info), CFDataGetLength(info));
-                       mScreen = create('I', hash);
-               } else if (mRep->mainExecutableImage()) {
-                       mScreen = "N";
-               } else {
-                       SHA1 hash;
-                       hashFileData(mRep->mainExecutablePath().c_str(), &hash);
-                       mScreen = create('M', hash);
-               }
-       }
-
-       return screen != mScreen;
-}
-
-std::string WhitelistPrescreen::create(char type, SHA1 &hash)
+static std::string createWhitelistScreen(char type, SHA1 &hash)
 {
        SHA1::Digest digest;
        hash.finish(digest);
 {
        SHA1::Digest digest;
        hash.finish(digest);
@@ -165,32 +115,18 @@ std::string WhitelistPrescreen::create(char type, SHA1 &hash)
 }
 
 
 }
 
 
-//
-// Executable code.
-// Read from disk, evaluate properly, cache as indicated. The whole thing, so far.
-//
-void PolicyEngine::evaluateCode(CFURLRef path, AuthorityType type, SecAssessmentFlags flags, CFDictionaryRef context, CFMutableDictionaryRef result,
-       bool handleUnsignedCode /* = true */)
+void PolicyEngine::evaluateCodeItem(SecStaticCodeRef code, CFURLRef path, AuthorityType type, SecAssessmentFlags flags, bool nested, CFMutableDictionaryRef result)
 {
 {
-       FileQuarantine qtn(cfString(path).c_str());
-       if (qtn.flag(QTN_FLAG_HARD))
-               MacOSError::throwMe(errSecCSFileHardQuarantined);
-       
-       CFRef<SecStaticCodeRef> code;
-       MacOSError::check(SecStaticCodeCreateWithPath(path, kSecCSDefaultFlags, &code.aref()));
-       OSStatus rc = noErr;    // last validation error
        
        
-       const SecCSFlags validationFlags = kSecCSEnforceRevocationChecks;
-       
-       WhitelistPrescreen whitelistScreen(code); // pre-screening filter for whitelist pre-screening (only)
-
        SQLite::Statement query(*this,
                "SELECT allow, requirement, id, label, expires, flags, disabled, filter_unsigned, remarks FROM scan_authority"
                " WHERE type = :type"
                " ORDER BY priority DESC;");
        query.bind(":type").integer(type);
        SQLite::Statement query(*this,
                "SELECT allow, requirement, id, label, expires, flags, disabled, filter_unsigned, remarks FROM scan_authority"
                " WHERE type = :type"
                " ORDER BY priority DESC;");
        query.bind(":type").integer(type);
+       
        SQLite3::int64 latentID = 0;            // first (highest priority) disabled matching ID
        std::string latentLabel;                        // ... and associated label, if any
        SQLite3::int64 latentID = 0;            // first (highest priority) disabled matching ID
        std::string latentLabel;                        // ... and associated label, if any
+
        while (query.nextRow()) {
                bool allow = int(query[0]);
                const char *reqString = query[1];
        while (query.nextRow()) {
                bool allow = int(query[0]);
                const char *reqString = query[1];
@@ -199,90 +135,31 @@ void PolicyEngine::evaluateCode(CFURLRef path, AuthorityType type, SecAssessment
                double expires = query[4];
                sqlite3_int64 ruleFlags = query[5];
                SQLite3::int64 disabled = query[6];
                double expires = query[4];
                sqlite3_int64 ruleFlags = query[5];
                SQLite3::int64 disabled = query[6];
-               const char *filter = query[7];
-               const char *remarks = query[8];
+//             const char *filter = query[7];
+//             const char *remarks = query[8];
                
                CFRef<SecRequirementRef> requirement;
                MacOSError::check(SecRequirementCreateWithString(CFTempString(reqString), kSecCSDefaultFlags, &requirement.aref()));
                
                CFRef<SecRequirementRef> requirement;
                MacOSError::check(SecRequirementCreateWithString(CFTempString(reqString), kSecCSDefaultFlags, &requirement.aref()));
-               rc = SecStaticCodeCheckValidity(code, validationFlags, requirement);
-               
-               // ad-hoc sign unsigned code, skip of Gatekeeper is off or the rule is disabled; but always do it for whitelist recording
-               if (rc == errSecCSUnsigned && handleUnsignedCode && (!(disabled || overrideAssessment()) || SYSPOLICY_RECORDER_MODE_ENABLED())) {
-                       if (!SYSPOLICY_RECORDER_MODE_ENABLED()) {
-                               // apply whitelist pre-screening to speed things up for non-matches
-                               if (ruleFlags & kAuthorityFlagDefault)  // can't ever match standard rules with unsigned code
-                                       continue;
-                               if (whitelistScreen.reject(filter, remarks))    // apply whitelist pre-filter
-                                       continue;
-                       }
-                       try {
-                               // ad-hoc sign the code and attach the signature
-                               CFRef<CFDataRef> signature = CFDataCreateMutable(NULL, 0);
-                               CFTemp<CFDictionaryRef> arguments("{%O=%O, %O=#N}", kSecCodeSignerDetached, signature.get(), kSecCodeSignerIdentity);
-                               CFRef<SecCodeSignerRef> signer;
-                               MacOSError::check(SecCodeSignerCreate(arguments, kSecCSDefaultFlags, &signer.aref()));
-                               MacOSError::check(SecCodeSignerAddSignature(signer, code, kSecCSDefaultFlags));
-                               MacOSError::check(SecCodeSetDetachedSignature(code, signature, kSecCSDefaultFlags));
-                                                               
-                               // if we're in GKE recording mode, save that signature and report its location
-                               if (SYSPOLICY_RECORDER_MODE_ENABLED()) {
-                                       int status = recorder_code_unable;      // ephemeral signature (not recorded)
-                                       if (geteuid() == 0) {
-                                               CFRef<CFUUIDRef> uuid = CFUUIDCreate(NULL);
-                                               std::string sigfile = RECORDER_DIR + cfStringRelease(CFUUIDCreateString(NULL, uuid)) + ".tsig";
-                                               try {
-                                                       UnixPlusPlus::AutoFileDesc fd(sigfile, O_WRONLY | O_CREAT);
-                                                       fd.write(CFDataGetBytePtr(signature), CFDataGetLength(signature));
-                                                       status = recorder_code_adhoc;   // recorded signature
-                                                       SYSPOLICY_RECORDER_MODE_ADHOC_PATH(cfString(path).c_str(), type, sigfile.c_str());
-                                               } catch (...) { }
-                                       }
-
-                                       // now report the D probe itself
-                                       CFRef<CFDictionaryRef> info;
-                                       MacOSError::check(SecCodeCopySigningInformation(code, kSecCSDefaultFlags, &info.aref()));
-                                       CFDataRef cdhash = CFDataRef(CFDictionaryGetValue(info, kSecCodeInfoUnique));
-                                       SYSPOLICY_RECORDER_MODE(cfString(path).c_str(), type, "",
-                                               cdhash ? CFDataGetBytePtr(cdhash) : NULL, status);
-                               }
-                               
-                               // rerun the validation to update state
-                               rc = SecStaticCodeCheckValidity(code, validationFlags | kSecCSBasicValidateOnly, requirement);
-                       } catch (...) { }
+               switch (OSStatus rc = SecStaticCodeCheckValidity(code, kSecCSDefaultFlags, requirement)) {
+               case errSecSuccess:
+                       break;                                          // rule match; process below
+               case errSecCSReqFailed:
+                       continue;                                       // rule does not apply
+               default:
+                       MacOSError::throwMe(rc);        // general error; pass to caller
                }
                }
-
-               switch (rc) {
-               case noErr: // well signed and satisfies requirement...
-                       break;  // ... continue below
-               case errSecCSSignatureFailed:
-                       if (!codeInvalidityExceptions(code, result)) {
-                               if (SYSPOLICY_ASSESS_OUTCOME_BROKEN_ENABLED())
-                                       SYSPOLICY_ASSESS_OUTCOME_BROKEN(cfString(path).c_str(), type, false);
-                               MacOSError::throwMe(rc);
-                       }
-                       if (SYSPOLICY_ASSESS_OUTCOME_BROKEN_ENABLED())
-                               SYSPOLICY_ASSESS_OUTCOME_BROKEN(cfString(path).c_str(), type, true);
-                       // treat as unsigned to fix problems in the field
-               case errSecCSUnsigned:
-                       if (handleUnsignedCode) {
-                               cfadd(result, "{%O=#F}", kSecAssessmentAssessmentVerdict);
-                               addAuthority(result, "no usable signature");
-                       }
-                       return;
-               case errSecCSReqFailed: // requirement missed, but otherwise okay
+               
+               // if this rule is disabled, skip it but record the first matching one for posterity
+               if (disabled && latentID == 0) {
+                       latentID = id;
+                       latentLabel = label ? label : "";
                        continue;
                        continue;
-               default: // broken in some way; all tests will fail like this so bail out
-                       MacOSError::throwMe(rc);
-               }
-               if (disabled) {
-                       if (latentID == 0) {
-                               latentID = id;
-                               if (label)
-                                       latentLabel = label;
-                       }
-                       continue;       // the loop
                }
                }
-       
+               
+               // current rule is first rule (in priority order) that matched. Apply it
+               if (nested)     // success, nothing to record
+                       return;
+
                CFRef<CFDictionaryRef> info;    // as needed
                if (flags & kSecAssessmentFlagRequestOrigin) {
                        if (!info)
                CFRef<CFDictionaryRef> info;    // as needed
                if (flags & kSecAssessmentFlagRequestOrigin) {
                        if (!info)
@@ -320,13 +197,7 @@ void PolicyEngine::evaluateCode(CFURLRef path, AuthorityType type, SecAssessment
                        }
                }
                cfadd(result, "{%O=%B}", kSecAssessmentAssessmentVerdict, allow);
                        }
                }
                cfadd(result, "{%O=%B}", kSecAssessmentAssessmentVerdict, allow);
-               addAuthority(result, label, id);
-               return;
-       }
-
-       if (rc == errSecCSUnsigned) {   // skipped all applicable rules due to pre-screening
-               cfadd(result, "{%O=#F}", kSecAssessmentAssessmentVerdict);
-               addAuthority(result, "no usable signature");
+               addAuthority(flags, result, label, id);
                return;
        }
        
                return;
        }
        
@@ -347,7 +218,140 @@ void PolicyEngine::evaluateCode(CFURLRef path, AuthorityType type, SecAssessment
        if (!(flags & kSecAssessmentFlagNoCache))
                this->recordOutcome(code, false, type, this->julianNow() + NEGATIVE_HOLD, latentID);
        cfadd(result, "{%O=%B}", kSecAssessmentAssessmentVerdict, false);
        if (!(flags & kSecAssessmentFlagNoCache))
                this->recordOutcome(code, false, type, this->julianNow() + NEGATIVE_HOLD, latentID);
        cfadd(result, "{%O=%B}", kSecAssessmentAssessmentVerdict, false);
-       addAuthority(result, latentLabel.c_str(), latentID);
+       addAuthority(flags, result, latentLabel.c_str(), latentID);
+}
+
+
+bool PolicyEngine::temporarySigning(SecStaticCodeRef code, AuthorityType type, CFURLRef path, SecAssessmentFlags matchFlags)
+{
+       if (matchFlags == 0) {  // playback; consult authority table for matches
+               DiskRep *rep = SecStaticCode::requiredStatic(code)->diskRep();
+               std::string screen;
+               if (CFRef<CFDataRef> info = rep->component(cdInfoSlot)) {
+                       SHA1 hash;
+                       hash.update(CFDataGetBytePtr(info), CFDataGetLength(info));
+                       screen = createWhitelistScreen('I', hash);
+               } else if (rep->mainExecutableImage()) {
+                       screen = "N";
+               } else {
+                       SHA1 hash;
+                       hashFileData(rep->mainExecutablePath().c_str(), &hash);
+                       screen = createWhitelistScreen('M', hash);
+               }
+               SQLite::Statement query(*this,
+                       "SELECT flags FROM authority "
+                       "WHERE type = :type"
+                       " AND NOT flags & :flag"
+                       " AND CASE WHEN filter_unsigned IS NULL THEN remarks = :remarks ELSE filter_unsigned = :screen END");
+               query.bind(":type").integer(type);
+               query.bind(":flag").integer(kAuthorityFlagDefault);
+               query.bind(":screen") = screen;
+               query.bind(":remarks") = cfString(path);
+               if (!query.nextRow())   // guaranteed no matching rule
+                       return false;
+               matchFlags = SQLite3::int64(query[0]);
+       }
+
+       try {
+               // ad-hoc sign the code and attach the signature
+               CFRef<CFDataRef> signature = CFDataCreateMutable(NULL, 0);
+               CFTemp<CFDictionaryRef> arguments("{%O=%O, %O=#N}", kSecCodeSignerDetached, signature.get(), kSecCodeSignerIdentity);
+               CFRef<SecCodeSignerRef> signer;
+               MacOSError::check(SecCodeSignerCreate(arguments, (matchFlags & kAuthorityFlagWhitelistV2) ? kSecCSSignOpaque : kSecCSSignV1, &signer.aref()));
+               MacOSError::check(SecCodeSignerAddSignature(signer, code, kSecCSDefaultFlags));
+               MacOSError::check(SecCodeSetDetachedSignature(code, signature, kSecCSDefaultFlags));
+               
+               SecRequirementRef dr = NULL;
+               SecCodeCopyDesignatedRequirement(code, kSecCSDefaultFlags, &dr);
+               CFStringRef drs = NULL;
+               SecRequirementCopyString(dr, kSecCSDefaultFlags, &drs);
+
+               // if we're in GKE recording mode, save that signature and report its location
+               if (SYSPOLICY_RECORDER_MODE_ENABLED()) {
+                       int status = recorder_code_unable;      // ephemeral signature (not recorded)
+                       if (geteuid() == 0) {
+                               CFRef<CFUUIDRef> uuid = CFUUIDCreate(NULL);
+                               std::string sigfile = RECORDER_DIR + cfStringRelease(CFUUIDCreateString(NULL, uuid)) + ".tsig";
+                               try {
+                                       UnixPlusPlus::AutoFileDesc fd(sigfile, O_WRONLY | O_CREAT);
+                                       fd.write(CFDataGetBytePtr(signature), CFDataGetLength(signature));
+                                       status = recorder_code_adhoc;   // recorded signature
+                                       SYSPOLICY_RECORDER_MODE_ADHOC_PATH(cfString(path).c_str(), type, sigfile.c_str());
+                               } catch (...) { }
+                       }
+
+                       // now report the D probe itself
+                       CFRef<CFDictionaryRef> info;
+                       MacOSError::check(SecCodeCopySigningInformation(code, kSecCSDefaultFlags, &info.aref()));
+                       CFDataRef cdhash = CFDataRef(CFDictionaryGetValue(info, kSecCodeInfoUnique));
+                       SYSPOLICY_RECORDER_MODE(cfString(path).c_str(), type, "",
+                               cdhash ? CFDataGetBytePtr(cdhash) : NULL, status);
+               }
+               
+               return true;    // it worked; we're now (well) signed
+       } catch (...) { }
+       
+       return false;
+}
+
+
+//
+// Executable code.
+// Read from disk, evaluate properly, cache as indicated. The whole thing, so far.
+//
+void PolicyEngine::evaluateCode(CFURLRef path, AuthorityType type, SecAssessmentFlags flags, CFDictionaryRef context, CFMutableDictionaryRef result, bool handleUnsigned)
+{
+       FileQuarantine qtn(cfString(path).c_str());
+       if (qtn.flag(QTN_FLAG_HARD))
+               MacOSError::throwMe(errSecCSFileHardQuarantined);
+       
+       CFCopyRef<SecStaticCodeRef> code;
+       MacOSError::check(SecStaticCodeCreateWithPath(path, kSecCSDefaultFlags, &code.aref()));
+       
+       SecCSFlags validationFlags = kSecCSEnforceRevocationChecks;
+       
+       // first, perform a shallow check
+       OSStatus rc = SecStaticCodeCheckValidity(code, validationFlags, NULL);
+
+       if (rc == errSecCSSignatureFailed) {
+               if (!codeInvalidityExceptions(code, result)) {  // invalidly signed, no exceptions -> error
+                       if (SYSPOLICY_ASSESS_OUTCOME_BROKEN_ENABLED())
+                               SYSPOLICY_ASSESS_OUTCOME_BROKEN(cfString(path).c_str(), type, false);
+                       MacOSError::throwMe(rc);
+               }
+               // recognized exception - treat as unsigned
+               if (SYSPOLICY_ASSESS_OUTCOME_BROKEN_ENABLED())
+                       SYSPOLICY_ASSESS_OUTCOME_BROKEN(cfString(path).c_str(), type, true);
+               rc = errSecCSUnsigned;
+       }
+
+       if (rc == errSecCSUnsigned && handleUnsigned && (!overrideAssessment(flags) || SYSPOLICY_RECORDER_MODE_ENABLED())) {
+               if (temporarySigning(code, type, path, 0)) {
+                       rc = errSecSuccess;             // clear unsigned; we are now well-signed
+                       validationFlags |= kSecCSBasicValidateOnly;     // no need to re-validate deep contents
+               }
+       }
+       
+       MacOSError::check(SecStaticCodeSetCallback(code, kSecCSDefaultFlags, NULL, ^CFTypeRef (SecStaticCodeRef item, CFStringRef stage, CFDictionaryRef info) {
+               SecStaticCodeSetCallback(item, kSecCSDefaultFlags, NULL, NULL);         // clear callback to avoid unwanted recursion
+               evaluateCodeItem(item, path, type, flags, item != code, result);
+               if (CFTypeRef verdict = CFDictionaryGetValue(result, kSecAssessmentAssessmentVerdict))
+                       if (CFEqual(verdict, kCFBooleanFalse))
+                               return makeCFNumber(OSStatus(errSecCSVetoed));  // (signal nested-code policy failure, picked up below)
+               return NULL;
+       }));
+       switch (rc = SecStaticCodeCheckValidity(code, validationFlags | kSecCSCheckNestedCode, NULL)) {
+       case errSecSuccess:             // continue below
+               break;
+       case errSecCSUnsigned:
+               cfadd(result, "{%O=#F}", kSecAssessmentAssessmentVerdict);
+               addAuthority(flags, result, "no usable signature");
+               return;
+       case errSecCSVetoed:            // nested code rejected by rule book; result was filled out there
+               return;
+       default:
+               MacOSError::throwMe(rc);
+       }
 }
 
 
 }
 
 
@@ -363,9 +367,28 @@ void PolicyEngine::evaluateInstall(CFURLRef path, SecAssessmentFlags flags, CFDi
        Xar xar(cfString(path).c_str());
        if (!xar) {
                // follow the code signing path
        Xar xar(cfString(path).c_str());
        if (!xar) {
                // follow the code signing path
-               evaluateCode(path, type, flags, context, result);
+               evaluateCode(path, type, flags, context, result, true);
                return;
        }
                return;
        }
+
+       // check for recent explicit approval, using a bookmark's FileResourceIdentifierKey
+       if (CFRef<CFDataRef> bookmark = cfLoadFile(lastApprovedFile)) {
+               Boolean stale;
+               if (CFRef<CFURLRef> url = CFURLCreateByResolvingBookmarkData(NULL, bookmark,
+                       kCFBookmarkResolutionWithoutUIMask | kCFBookmarkResolutionWithoutMountingMask, NULL, NULL, &stale, NULL))
+                       if (CFRef<CFDataRef> savedIdent = CFDataRef(CFURLCreateResourcePropertyForKeyFromBookmarkData(NULL, kCFURLFileResourceIdentifierKey, bookmark)))
+                               if (CFRef<CFDateRef> savedMod = CFDateRef(CFURLCreateResourcePropertyForKeyFromBookmarkData(NULL, kCFURLContentModificationDateKey, bookmark))) {
+                                       CFRef<CFDataRef> currentIdent;
+                                       CFRef<CFDateRef> currentMod;
+                                       if (CFURLCopyResourcePropertyForKey(path, kCFURLFileResourceIdentifierKey, &currentIdent.aref(), NULL))
+                                               if (CFURLCopyResourcePropertyForKey(path, kCFURLContentModificationDateKey, &currentMod.aref(), NULL))
+                                                       if (CFEqual(savedIdent, currentIdent) && CFEqual(savedMod, currentMod)) {
+                                                               cfadd(result, "{%O=#T}", kSecAssessmentAssessmentVerdict);
+                                                               addAuthority(flags, result, "explicit preference");
+                                                               return;
+                                                       }
+                               }
+       }
        
        SQLite3::int64 latentID = 0;            // first (highest priority) disabled matching ID
        std::string latentLabel;                        // ... and associated label, if any
        
        SQLite3::int64 latentID = 0;            // first (highest priority) disabled matching ID
        std::string latentLabel;                        // ... and associated label, if any
@@ -373,8 +396,8 @@ void PolicyEngine::evaluateInstall(CFURLRef path, SecAssessmentFlags flags, CFDi
                // unsigned xar
                if (SYSPOLICY_ASSESS_OUTCOME_UNSIGNED_ENABLED())
                        SYSPOLICY_ASSESS_OUTCOME_UNSIGNED(cfString(path).c_str(), type);
                // unsigned xar
                if (SYSPOLICY_ASSESS_OUTCOME_UNSIGNED_ENABLED())
                        SYSPOLICY_ASSESS_OUTCOME_UNSIGNED(cfString(path).c_str(), type);
-               cfadd(result, "{%O=%B}", kSecAssessmentAssessmentVerdict, false);
-               addAuthority(result, "no usable signature");
+               cfadd(result, "{%O=#F}", kSecAssessmentAssessmentVerdict);
+               addAuthority(flags, result, "no usable signature");
                return;
        }
        if (CFRef<CFArrayRef> certs = xar.copyCertChain()) {
                return;
        }
        if (CFRef<CFArrayRef> certs = xar.copyCertChain()) {
@@ -421,7 +444,7 @@ void PolicyEngine::evaluateInstall(CFURLRef path, SecAssessmentFlags flags, CFDi
                        CFRef<SecRequirementRef> requirement;
                        MacOSError::check(SecRequirementCreateWithString(CFTempString(reqString), kSecCSDefaultFlags, &requirement.aref()));
                        switch (OSStatus rc = SecRequirementEvaluate(requirement, chain, NULL, kSecCSDefaultFlags)) {
                        CFRef<SecRequirementRef> requirement;
                        MacOSError::check(SecRequirementCreateWithString(CFTempString(reqString), kSecCSDefaultFlags, &requirement.aref()));
                        switch (OSStatus rc = SecRequirementEvaluate(requirement, chain, NULL, kSecCSDefaultFlags)) {
-                       case noErr: // success
+                       case errSecSuccess: // success
                                break;
                        case errSecCSReqFailed: // requirement missed, but otherwise okay
                                continue;
                                break;
                        case errSecCSReqFailed: // requirement missed, but otherwise okay
                                continue;
@@ -446,7 +469,7 @@ void PolicyEngine::evaluateInstall(CFURLRef path, SecAssessmentFlags flags, CFDi
 
                        // not adding to the object cache - we could, but it's not likely to be worth it
                        cfadd(result, "{%O=%B}", kSecAssessmentAssessmentVerdict, allow);
 
                        // not adding to the object cache - we could, but it's not likely to be worth it
                        cfadd(result, "{%O=%B}", kSecAssessmentAssessmentVerdict, allow);
-                       addAuthority(result, label, id);
+                       addAuthority(flags, result, label, id);
                        return;
                }
        }
                        return;
                }
        }
@@ -455,7 +478,7 @@ void PolicyEngine::evaluateInstall(CFURLRef path, SecAssessmentFlags flags, CFDi
        
        // no applicable authority. Deny by default
        cfadd(result, "{%O=#F}", kSecAssessmentAssessmentVerdict);
        
        // no applicable authority. Deny by default
        cfadd(result, "{%O=#F}", kSecAssessmentAssessmentVerdict);
-       addAuthority(result, latentLabel.c_str(), latentID);
+       addAuthority(flags, result, latentLabel.c_str(), latentID);
 }
 
 
 }
 
 
@@ -512,13 +535,13 @@ void PolicyEngine::evaluateDocOpen(CFURLRef path, SecAssessmentFlags flags, CFDi
                                || CFEqual(riskCategory, kLSRiskCategoryUnknown)
                                || CFEqual(riskCategory, kLSRiskCategoryMayContainUnsafeExecutable)) {
                                cfadd(result, "{%O=#T}", kSecAssessmentAssessmentVerdict);
                                || CFEqual(riskCategory, kLSRiskCategoryUnknown)
                                || CFEqual(riskCategory, kLSRiskCategoryMayContainUnsafeExecutable)) {
                                cfadd(result, "{%O=#T}", kSecAssessmentAssessmentVerdict);
-                               addAuthority(result, "_XProtect");
+                               addAuthority(flags, result, "_XProtect");
                        } else if (qtn.flag(QTN_FLAG_HARD)) {
                                MacOSError::throwMe(errSecCSFileHardQuarantined);
                        } else if (qtn.flag(QTN_FLAG_ASSESSMENT_OK)) {
                                cfadd(result, "{%O=#T}", kSecAssessmentAssessmentVerdict);
                        } else if (qtn.flag(QTN_FLAG_HARD)) {
                                MacOSError::throwMe(errSecCSFileHardQuarantined);
                        } else if (qtn.flag(QTN_FLAG_ASSESSMENT_OK)) {
                                cfadd(result, "{%O=#T}", kSecAssessmentAssessmentVerdict);
-                               addAuthority(result, "Prior Assessment");
-                       } else if (!overrideAssessment()) {             // no need to do more work if we're off
+                               addAuthority(flags, result, "Prior Assessment");
+                       } else if (!overrideAssessment(flags)) {                // no need to do more work if we're off
                                try {
                                        evaluateCode(path, kAuthorityExecute, flags, context, result, false);
                                } catch (...) {
                                try {
                                        evaluateCode(path, kAuthorityExecute, flags, context, result, false);
                                } catch (...) {
@@ -527,7 +550,7 @@ void PolicyEngine::evaluateDocOpen(CFURLRef path, SecAssessmentFlags flags, CFDi
                        }
                        if (CFDictionaryGetValue(result, kSecAssessmentAssessmentVerdict) == NULL) {    // no code signature to help us out
                           cfadd(result, "{%O=#F}", kSecAssessmentAssessmentVerdict);
                        }
                        if (CFDictionaryGetValue(result, kSecAssessmentAssessmentVerdict) == NULL) {    // no code signature to help us out
                           cfadd(result, "{%O=#F}", kSecAssessmentAssessmentVerdict);
-                          addAuthority(result, "_XProtect");
+                          addAuthority(flags, result, "_XProtect");
                        }
                        addToAuthority(result, kLSDownloadRiskCategoryKey, riskCategory);
                        return;
                        }
                        addToAuthority(result, kLSDownloadRiskCategoryKey, riskCategory);
                        return;
@@ -535,21 +558,21 @@ void PolicyEngine::evaluateDocOpen(CFURLRef path, SecAssessmentFlags flags, CFDi
        }
        // insufficient information from LS - deny by default
        cfadd(result, "{%O=#F}", kSecAssessmentAssessmentVerdict);
        }
        // insufficient information from LS - deny by default
        cfadd(result, "{%O=#F}", kSecAssessmentAssessmentVerdict);
-       addAuthority(result, "Insufficient Context");
+       addAuthority(flags, result, "Insufficient Context");
 }
 
 
 //
 // Result-creation helpers
 //
 }
 
 
 //
 // Result-creation helpers
 //
-void PolicyEngine::addAuthority(CFMutableDictionaryRef parent, const char *label, SQLite::int64 row, CFTypeRef cacheInfo)
+void PolicyEngine::addAuthority(SecAssessmentFlags flags, CFMutableDictionaryRef parent, const char *label, SQLite::int64 row, CFTypeRef cacheInfo)
 {
        CFRef<CFMutableDictionaryRef> auth = makeCFMutableDictionary();
        if (label && label[0])
                cfadd(auth, "{%O=%s}", kSecAssessmentAssessmentSource, label);
        if (row)
                CFDictionaryAddValue(auth, kSecAssessmentAssessmentAuthorityRow, CFTempNumber(row));
 {
        CFRef<CFMutableDictionaryRef> auth = makeCFMutableDictionary();
        if (label && label[0])
                cfadd(auth, "{%O=%s}", kSecAssessmentAssessmentSource, label);
        if (row)
                CFDictionaryAddValue(auth, kSecAssessmentAssessmentAuthorityRow, CFTempNumber(row));
-       if (overrideAssessment())
+       if (overrideAssessment(flags))
                CFDictionaryAddValue(auth, kSecAssessmentAssessmentAuthorityOverride, kDisabledOverride);
        if (cacheInfo)
                CFDictionaryAddValue(auth, kSecAssessmentAssessmentFromCache, cacheInfo);
                CFDictionaryAddValue(auth, kSecAssessmentAssessmentAuthorityOverride, kDisabledOverride);
        if (cacheInfo)
                CFDictionaryAddValue(auth, kSecAssessmentAssessmentFromCache, cacheInfo);
@@ -581,14 +604,20 @@ CFDictionaryRef PolicyEngine::add(CFTypeRef inTarget, AuthorityType type, SecAss
 
        switch (type) {
        case kAuthorityExecute:
 
        switch (type) {
        case kAuthorityExecute:
-               normalizeTarget(target, ctx, &filter_unsigned);
+               normalizeTarget(target, type, ctx, &filter_unsigned);
                // bookmarks are untrusted and just a hint to callers
                bookmark = ctx.get<CFDataRef>(kSecAssessmentRuleKeyBookmark);
                break;
        case kAuthorityInstall:
                if (inTarget && CFGetTypeID(inTarget) == CFURLGetTypeID()) {
                        // no good way to turn an installer file into a requirement. Pretend to succeeed so caller proceeds
                // bookmarks are untrusted and just a hint to callers
                bookmark = ctx.get<CFDataRef>(kSecAssessmentRuleKeyBookmark);
                break;
        case kAuthorityInstall:
                if (inTarget && CFGetTypeID(inTarget) == CFURLGetTypeID()) {
                        // no good way to turn an installer file into a requirement. Pretend to succeeed so caller proceeds
-                       return cfmake<CFDictionaryRef>("{%O=%O}", kSecAssessmentAssessmentAuthorityOverride, CFSTR("virtual install"));
+                       CFRef<CFArrayRef> properties = makeCFArray(2, kCFURLFileResourceIdentifierKey, kCFURLContentModificationDateKey);
+                       CFRef<CFErrorRef> error;
+                       if (CFRef<CFDataRef> bookmark = CFURLCreateBookmarkData(NULL, CFURLRef(inTarget), kCFURLBookmarkCreationMinimalBookmarkMask, properties, NULL, &error.aref())) {
+                               UnixPlusPlus::AutoFileDesc fd(lastApprovedFile, O_WRONLY | O_CREAT | O_TRUNC);
+                               fd.write(CFDataGetBytePtr(bookmark), CFDataGetLength(bookmark));
+                               return NULL;
+                       }
                }
                break;
        case kAuthorityOpenDoc:
                }
                break;
        case kAuthorityOpenDoc:
@@ -619,6 +648,7 @@ CFDictionaryRef PolicyEngine::add(CFTypeRef inTarget, AuthorityType type, SecAss
        bool allow = true;
        double expires = never;
        string remarks;
        bool allow = true;
        double expires = never;
        string remarks;
+       SQLite::uint64 dbFlags = kAuthorityFlagWhitelistV2;
        
        if (CFNumberRef pri = ctx.get<CFNumberRef>(kSecAssessmentUpdateKeyPriority))
                CFNumberGetValue(pri, kCFNumberDoubleType, &priority);
        
        if (CFNumberRef pri = ctx.get<CFNumberRef>(kSecAssessmentUpdateKeyPriority))
                CFNumberGetValue(pri, kCFNumberDoubleType, &priority);
@@ -636,8 +666,8 @@ CFDictionaryRef PolicyEngine::add(CFTypeRef inTarget, AuthorityType type, SecAss
        MacOSError::check(SecRequirementCopyString(target.as<SecRequirementRef>(), kSecCSDefaultFlags, &requirementText.aref()));
        SQLite::Transaction xact(*this, SQLite3::Transaction::deferred, "add_rule");
        SQLite::Statement insert(*this,
        MacOSError::check(SecRequirementCopyString(target.as<SecRequirementRef>(), kSecCSDefaultFlags, &requirementText.aref()));
        SQLite::Transaction xact(*this, SQLite3::Transaction::deferred, "add_rule");
        SQLite::Statement insert(*this,
-               "INSERT INTO authority (type, allow, requirement, priority, label, expires, filter_unsigned, remarks)"
-               "       VALUES (:type, :allow, :requirement, :priority, :label, :expires, :filter_unsigned, :remarks);");
+               "INSERT INTO authority (type, allow, requirement, priority, label, expires, filter_unsigned, remarks, flags)"
+               "       VALUES (:type, :allow, :requirement, :priority, :label, :expires, :filter_unsigned, :remarks, :flags);");
        insert.bind(":type").integer(type);
        insert.bind(":allow").integer(allow);
        insert.bind(":requirement") = requirementText.get();
        insert.bind(":type").integer(type);
        insert.bind(":allow").integer(allow);
        insert.bind(":requirement") = requirementText.get();
@@ -648,6 +678,7 @@ CFDictionaryRef PolicyEngine::add(CFTypeRef inTarget, AuthorityType type, SecAss
        insert.bind(":filter_unsigned") = filter_unsigned.empty() ? NULL : filter_unsigned.c_str();
        if (!remarks.empty())
                insert.bind(":remarks") = remarks;
        insert.bind(":filter_unsigned") = filter_unsigned.empty() ? NULL : filter_unsigned.c_str();
        if (!remarks.empty())
                insert.bind(":remarks") = remarks;
+       insert.bind(":flags").integer(dbFlags);
        insert.execute();
        SQLite::int64 newRow = this->lastInsert();
        if (bookmark) {
        insert.execute();
        SQLite::int64 newRow = this->lastInsert();
        if (bookmark) {
@@ -768,7 +799,7 @@ void PolicyEngine::selectRules(SQLite::Statement &action, std::string phrase, st
        CFDictionary ctx(context, errSecCSInvalidAttributeValues);
        CFCopyRef<CFTypeRef> target = inTarget;
        std::string filter_unsigned;    // ignored; used just to trigger ad-hoc signing
        CFDictionary ctx(context, errSecCSInvalidAttributeValues);
        CFCopyRef<CFTypeRef> target = inTarget;
        std::string filter_unsigned;    // ignored; used just to trigger ad-hoc signing
-       normalizeTarget(target, ctx, &filter_unsigned);
+       normalizeTarget(target, type, ctx, &filter_unsigned);
 
        string label;
        if (CFStringRef lab = ctx.get<CFStringRef>(kSecAssessmentUpdateKeyLabel))
 
        string label;
        if (CFStringRef lab = ctx.get<CFStringRef>(kSecAssessmentUpdateKeyLabel))
@@ -876,6 +907,18 @@ void PolicyEngine::recordOutcome(SecStaticCodeRef code, bool allow, AuthorityTyp
 }
 
 
 }
 
 
+//
+// Record a UI failure record after proper validation of the caller
+//
+void PolicyEngine::recordFailure(CFDictionaryRef info)
+{
+       CFRef<CFDataRef> infoData = makeCFData(info);
+       UnixPlusPlus::AutoFileDesc fd(lastRejectFile, O_WRONLY | O_CREAT | O_TRUNC);
+       fd.write(CFDataGetBytePtr(infoData), CFDataGetLength(infoData));
+       notify_post(kNotifySecAssessmentRecordingChange);
+}
+
+
 //
 // Perform update authorization processing.
 // Throws an exception if authorization is denied.
 //
 // Perform update authorization processing.
 // Throws an exception if authorization is denied.
@@ -907,14 +950,15 @@ static void authorizeUpdate(SecAssessmentFlags flags, CFDictionaryRef context)
 //
 // Perform common argument normalizations for update operations
 //
 //
 // Perform common argument normalizations for update operations
 //
-static void normalizeTarget(CFRef<CFTypeRef> &target, CFDictionary &context, std::string *signUnsigned)
+void PolicyEngine::normalizeTarget(CFRef<CFTypeRef> &target, AuthorityType type, CFDictionary &context, std::string *signUnsigned)
 {
        // turn CFURLs into (designated) SecRequirements
        if (target && CFGetTypeID(target) == CFURLGetTypeID()) {
                CFRef<SecStaticCodeRef> code;
 {
        // turn CFURLs into (designated) SecRequirements
        if (target && CFGetTypeID(target) == CFURLGetTypeID()) {
                CFRef<SecStaticCodeRef> code;
-               MacOSError::check(SecStaticCodeCreateWithPath(target.as<CFURLRef>(), kSecCSDefaultFlags, &code.aref()));
+               CFURLRef path = target.as<CFURLRef>();
+               MacOSError::check(SecStaticCodeCreateWithPath(path, kSecCSDefaultFlags, &code.aref()));
                switch (OSStatus rc = SecCodeCopyDesignatedRequirement(code, kSecCSDefaultFlags, (SecRequirementRef *)&target.aref())) {
                switch (OSStatus rc = SecCodeCopyDesignatedRequirement(code, kSecCSDefaultFlags, (SecRequirementRef *)&target.aref())) {
-               case noErr: {
+               case errSecSuccess: {
                        // use the *default* DR to avoid unreasonably wide DRs opening up Gatekeeper to attack
                        CFRef<CFDictionaryRef> info;
                        MacOSError::check(SecCodeCopySigningInformation(code, kSecCSRequirementInformation, &info.aref()));
                        // use the *default* DR to avoid unreasonably wide DRs opening up Gatekeeper to attack
                        CFRef<CFDictionaryRef> info;
                        MacOSError::check(SecCodeCopySigningInformation(code, kSecCSRequirementInformation, &info.aref()));
@@ -922,14 +966,7 @@ static void normalizeTarget(CFRef<CFTypeRef> &target, CFDictionary &context, std
                        }
                        break;
                case errSecCSUnsigned:
                        }
                        break;
                case errSecCSUnsigned:
-                       if (signUnsigned) {
-                               // Ad-hoc sign the code temporarily so we can get its code requirement
-                               CFRef<CFDataRef> signature = CFDataCreateMutable(NULL, 0);
-                               CFRef<SecCodeSignerRef> signer;
-                               CFTemp<CFDictionaryRef> arguments("{%O=%O, %O=#N}", kSecCodeSignerDetached, signature.get(), kSecCodeSignerIdentity);
-                               MacOSError::check(SecCodeSignerCreate(arguments, kSecCSDefaultFlags, &signer.aref()));
-                               MacOSError::check(SecCodeSignerAddSignature(signer, code, kSecCSDefaultFlags));
-                               MacOSError::check(SecCodeSetDetachedSignature(code, signature, kSecCSDefaultFlags));
+                       if (signUnsigned && temporarySigning(code, type, path, kAuthorityFlagWhitelistV2)) {    // ad-hoc signed the code temporarily
                                MacOSError::check(SecCodeCopyDesignatedRequirement(code, kSecCSDefaultFlags, (SecRequirementRef *)&target.aref()));
                                CFRef<CFDictionaryRef> info;
                                MacOSError::check(SecCodeCopySigningInformation(code, kSecCSInternalInformation, &info.aref()));
                                MacOSError::check(SecCodeCopyDesignatedRequirement(code, kSecCSDefaultFlags, (SecRequirementRef *)&target.aref()));
                                CFRef<CFDictionaryRef> info;
                                MacOSError::check(SecCodeCopySigningInformation(code, kSecCSInternalInformation, &info.aref()));
@@ -944,7 +981,7 @@ static void normalizeTarget(CFRef<CFTypeRef> &target, CFDictionary &context, std
                                // Ad-hoc sign the code in place (requiring a writable subject). This requires root privileges.
                                CFRef<SecCodeSignerRef> signer;
                                CFTemp<CFDictionaryRef> arguments("{%O=#N}", kSecCodeSignerIdentity);
                                // Ad-hoc sign the code in place (requiring a writable subject). This requires root privileges.
                                CFRef<SecCodeSignerRef> signer;
                                CFTemp<CFDictionaryRef> arguments("{%O=#N}", kSecCodeSignerIdentity);
-                               MacOSError::check(SecCodeSignerCreate(arguments, kSecCSDefaultFlags, &signer.aref()));
+                               MacOSError::check(SecCodeSignerCreate(arguments, kSecCSSignOpaque, &signer.aref()));
                                MacOSError::check(SecCodeSignerAddSignature(signer, code, kSecCSDefaultFlags));
                                MacOSError::check(SecCodeCopyDesignatedRequirement(code, kSecCSDefaultFlags, (SecRequirementRef *)&target.aref()));
                                break;
                                MacOSError::check(SecCodeSignerAddSignature(signer, code, kSecCSDefaultFlags));
                                MacOSError::check(SecCodeCopyDesignatedRequirement(code, kSecCSDefaultFlags, (SecRequirementRef *)&target.aref()));
                                break;
index 65ff6bf12f4bedbdd8b1fea28931e8cfbf4cbcef..af06f66049daa93f067a7af22f8dc65b5be412dc 100644 (file)
@@ -60,16 +60,21 @@ public:
        CFDictionaryRef disable(CFTypeRef target, AuthorityType type, SecAssessmentFlags flags, CFDictionaryRef context);
        CFDictionaryRef find(CFTypeRef target, AuthorityType type, SecAssessmentFlags flags, CFDictionaryRef context);
 
        CFDictionaryRef disable(CFTypeRef target, AuthorityType type, SecAssessmentFlags flags, CFDictionaryRef context);
        CFDictionaryRef find(CFTypeRef target, AuthorityType type, SecAssessmentFlags flags, CFDictionaryRef context);
 
+       void recordFailure(CFDictionaryRef info);
+
 public:
 public:
-       static void addAuthority(CFMutableDictionaryRef parent, const char *label, SQLite::int64 row = 0, CFTypeRef cacheInfo = NULL);
+       static void addAuthority(SecAssessmentFlags flags, CFMutableDictionaryRef parent, const char *label, SQLite::int64 row = 0, CFTypeRef cacheInfo = NULL);
        static void addToAuthority(CFMutableDictionaryRef parent, CFStringRef key, CFTypeRef value);
 
 private:
        static void addToAuthority(CFMutableDictionaryRef parent, CFStringRef key, CFTypeRef value);
 
 private:
-       void evaluateCode(CFURLRef path, AuthorityType type, SecAssessmentFlags flags, CFDictionaryRef context, CFMutableDictionaryRef result,
-               bool handleUnsignedCode = true);
+       void evaluateCode(CFURLRef path, AuthorityType type, SecAssessmentFlags flags, CFDictionaryRef context, CFMutableDictionaryRef result, bool handleUnsigned);
        void evaluateInstall(CFURLRef path, SecAssessmentFlags flags, CFDictionaryRef context, CFMutableDictionaryRef result);
        void evaluateDocOpen(CFURLRef path, SecAssessmentFlags flags, CFDictionaryRef context, CFMutableDictionaryRef result);
        
        void evaluateInstall(CFURLRef path, SecAssessmentFlags flags, CFDictionaryRef context, CFMutableDictionaryRef result);
        void evaluateDocOpen(CFURLRef path, SecAssessmentFlags flags, CFDictionaryRef context, CFMutableDictionaryRef result);
        
+       void evaluateCodeItem(SecStaticCodeRef code, CFURLRef path, AuthorityType type, SecAssessmentFlags flags, bool nested, CFMutableDictionaryRef result);
+       bool temporarySigning(SecStaticCodeRef code, AuthorityType type, CFURLRef path, SecAssessmentFlags matchFlags);
+       void normalizeTarget(CFRef<CFTypeRef> &target, AuthorityType type, CFDictionary &context, std::string *signUnsigned);
+       
        void selectRules(SQLite::Statement &action, std::string stanza, std::string table,
                CFTypeRef inTarget, AuthorityType type, SecAssessmentFlags flags, CFDictionaryRef context, std::string suffix = "");
        CFDictionaryRef manipulateRules(const std::string &stanza,
        void selectRules(SQLite::Statement &action, std::string stanza, std::string table,
                CFTypeRef inTarget, AuthorityType type, SecAssessmentFlags flags, CFDictionaryRef context, std::string suffix = "");
        CFDictionaryRef manipulateRules(const std::string &stanza,
diff --git a/libsecurity_codesigning/lib/renum.cpp b/libsecurity_codesigning/lib/renum.cpp
deleted file mode 100644 (file)
index a5b8e78..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
- * 
- * @APPLE_LICENSE_HEADER_START@
- * 
- * 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 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-
-//
-// renum - enumerator for code (usually bundle) resources
-//
-#include "renum.h"
-#include <security_utilities/unix++.h>
-#include <security_utilities/debugging.h>
-
-namespace Security {
-namespace CodeSigning {
-
-using namespace UnixPlusPlus;
-
-
-ResourceEnumerator::ResourceEnumerator(string path)
-       : mPath(path)
-{
-       assert(!mPath.empty());
-       const char * paths[2] = { path.c_str(), NULL };
-       mFTS = fts_open((char * const *)paths, FTS_PHYSICAL | FTS_COMFOLLOW | FTS_NOCHDIR, NULL);
-       if (!mFTS)
-               UnixError::throwMe();
-}
-
-ResourceEnumerator::~ResourceEnumerator()
-{
-       checkError(fts_close(mFTS));
-}
-
-
-FTSENT *ResourceEnumerator::next(string &path)
-{
-       while (FTSENT *ent = fts_read(mFTS)) {
-               switch (ent->fts_info) {
-               case FTS_F:
-                       path = ent->fts_path + mPath.size() + 1;        // skip prefix + "/"
-                       return ent;
-               case FTS_D:
-                       secdebug("rdirenum", "entering %s", ent->fts_path);
-                       break;
-               case FTS_DP:
-                       secdebug("rdirenum", "leaving %s", ent->fts_path);
-                       break;
-               case FTS_SL:
-                       secdebug("rdirenum", "symlink ignored: %s", ent->fts_path);
-                       break;
-               default:
-                       secdebug("rdirenum", "type %d (errno %d): %s",
-                               ent->fts_info, ent->fts_errno, ent->fts_path);
-                       break;
-               }
-       }
-       return NULL;
-}
-
-
-} // end namespace CodeSigning
-} // end namespace Security
diff --git a/libsecurity_codesigning/lib/renum.h b/libsecurity_codesigning/lib/renum.h
deleted file mode 100644 (file)
index 1d40983..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
- * 
- * @APPLE_LICENSE_HEADER_START@
- * 
- * 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 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-
-//
-// renum - enumerator for code (usually bundle) resources
-//
-#ifndef _H_RENUM
-#define _H_RENUM
-
-#include <fts.h>
-#include <string>
-
-namespace Security {
-namespace CodeSigning {
-
-
-//
-// A ResourceEnumerator front-ends FTS to scan out relevant resource
-// directory entries (ignoring irrelevant ones).
-// It also returns canonical resource paths (relative to the resource directory).
-//
-class ResourceEnumerator {
-public:
-       ResourceEnumerator(std::string path);
-       ~ResourceEnumerator();
-       
-       FTSENT *next(std::string &path);
-       
-private:
-       std::string mPath;
-       FTS *mFTS;
-};
-
-
-} // end namespace CodeSigning
-} // end namespace Security
-
-#endif // !_H_RENUM
index ceca15012fc2f3d6c01c06958aeae5b8d99f45a4..9b91ec530ce5f7d6f7d68037714115ed14810143 100644 (file)
@@ -187,7 +187,7 @@ void Dumper::expr(SyntaxLevel level)
                expr(slPrimary);
                break;
        case opCDHash:
                expr(slPrimary);
                break;
        case opCDHash:
-               print(" cdhash ");
+               print("cdhash ");
                hashData();
                break;
        case opInfoKeyField:
                hashData();
                break;
        case opInfoKeyField:
index cce6d48fbd0f0c8616dee0683931eb9a5cadf159..077eb90a35d8257b41fb819069be224abd75a4ee 100644 (file)
@@ -411,7 +411,7 @@ SecTrustSettingsResult Requirement::Interpreter::trustSetting(SecCertificateRef
                &result,                                                                // the actual setting
                &foundMatch, &foundAny                                  // optimization hints (not used)
                )) {
                &result,                                                                // the actual setting
                &foundMatch, &foundAny                                  // optimization hints (not used)
                )) {
-       case noErr:
+       case errSecSuccess:
                ::free(errors);
                if (foundMatch)
                        return result;
                ::free(errors);
                if (foundMatch)
                        return result;
index 31642a9429c066c457c3fb27c0d6ad3113d22d0a..0480a85ee3e6d4a39f7d88b172cb899d6c34f1d3 100644 (file)
@@ -48,7 +48,7 @@ void Requirement::Maker::require(size_t size)
        if (mPC + size > mSize) {
                mSize *= 2;
                if (mPC + size > mSize)
        if (mPC + size > mSize) {
                mSize *= 2;
                if (mPC + size > mSize)
-                       mSize = mPC + size;
+                       mSize = (Offset)(mPC + size);
                if (!(mBuffer = (Requirement *)realloc(mBuffer, mSize)))
                        UnixError::throwMe(ENOMEM);
        }
                if (!(mBuffer = (Requirement *)realloc(mBuffer, mSize)))
                        UnixError::throwMe(ENOMEM);
        }
@@ -135,6 +135,11 @@ void Requirement::Maker::cdhash(SHA1::Digest digest)
        putData(digest, SHA1::digestLength);
 }
 
        putData(digest, SHA1::digestLength);
 }
 
+void Requirement::Maker::cdhash(CFDataRef digest)
+{
+       put(opCDHash);
+       putData(CFDataGetBytePtr(digest), CFDataGetLength(digest));
+}
 
 
 void Requirement::Maker::copy(const Requirement *req)
 
 
 void Requirement::Maker::copy(const Requirement *req)
index ee1da109a801aa711b9128cb18da0964d4de5808..2209d1187635ae491203c4916538a6c92a3f2fad 100644 (file)
@@ -68,6 +68,7 @@ public:
        void infoKey(const std::string &key, const std::string &value);
        void ident(const std::string &identHash);
        void cdhash(SHA1::Digest digest);
        void infoKey(const std::string &key, const std::string &value);
        void ident(const std::string &identHash);
        void cdhash(SHA1::Digest digest);
+       void cdhash(CFDataRef digest);
        
        void copy(const void *data, size_t length)
                { memcpy(this->alloc(length), data, length); }
        
        void copy(const void *data, size_t length)
                { memcpy(this->alloc(length), data, length); }
@@ -79,7 +80,7 @@ public:
        //
        struct Label {
                const Offset pos;
        //
        struct Label {
                const Offset pos;
-               Label(const Maker &maker) : pos(maker.length()) { }
+               Label(const Maker &maker) : pos((const Offset)maker.length()) { }
        };
        void *insert(const Label &label, size_t length = sizeof(uint32_t));
        
        };
        void *insert(const Label &label, size_t length = sizeof(uint32_t));
        
@@ -96,16 +97,15 @@ public:
                Chain(Maker &myMaker, ExprOp op)
                        : Label(myMaker), maker(myMaker), mJoiner(op), mCount(0) { }
 
                Chain(Maker &myMaker, ExprOp op)
                        : Label(myMaker), maker(myMaker), mJoiner(op), mCount(0) { }
 
-               void add()
+               void add() const
                        { if (mCount++) maker.insert<ExprOp>(*this) = mJoiner; }
        
                Maker &maker;
                bool empty() const { return mCount == 0; }
                        { if (mCount++) maker.insert<ExprOp>(*this) = mJoiner; }
        
                Maker &maker;
                bool empty() const { return mCount == 0; }
-               unsigned count() const { return mCount; }
 
        private:
                ExprOp mJoiner;
 
        private:
                ExprOp mJoiner;
-               unsigned mCount;
+               mutable unsigned mCount;
        };
        
        
        };
        
        
index 2db501b463af5087f544a593f5ebdde501470f81..25d198dbf2808bdc25cd0a4e87916b9f74aff68c 100644 (file)
@@ -56,7 +56,7 @@ public:
 protected:
        void checkSize(size_t length)
        {
 protected:
        void checkSize(size_t length)
        {
-               if (mPC + length > mReq->length())
+               if (mPC + length < mPC || mPC + length > mReq->length())
                        MacOSError::throwMe(errSecCSReqInvalid);
        }
        
                        MacOSError::throwMe(errSecCSReqInvalid);
        }
        
index a503a42dc1d9b02416b74b37e1166138a1414c7b..418c416b4dd6941adfa84a500976933228cfe93e 100644 (file)
@@ -65,7 +65,7 @@ void Requirement::validate(const Requirement::Context &ctx, OSStatus failure /*
 
 bool Requirement::validates(const Requirement::Context &ctx, OSStatus failure /* = errSecCSReqFailed */) const
 {
 
 bool Requirement::validates(const Requirement::Context &ctx, OSStatus failure /* = errSecCSReqFailed */) const
 {
-       CODESIGN_EVAL_REQINT_START((void*)this, this->length());
+       CODESIGN_EVAL_REQINT_START((void*)this, (int)this->length());
        switch (kind()) {
        case exprForm:
                if (Requirement::Interpreter(this, &ctx).evaluate()) {
        switch (kind()) {
        case exprForm:
                if (Requirement::Interpreter(this, &ctx).evaluate()) {
@@ -105,7 +105,7 @@ SecCertificateRef Requirement::Context::cert(int ix) const
 unsigned int Requirement::Context::certCount() const
 {
        if (certs)
 unsigned int Requirement::Context::certCount() const
 {
        if (certs)
-               return CFArrayGetCount(certs);
+               return (unsigned int)CFArrayGetCount(certs);
        else
                return 0;
 }
        else
                return 0;
 }
index 785eb0a7b924a58857a965dd4f1faa3d4aa7d2ff..e5c50a49bedc7b652c8433be4a6ed22db0257502 100644 (file)
@@ -26,6 +26,8 @@
 //
 #include "resources.h"
 #include "csutilities.h"
 //
 #include "resources.h"
 #include "csutilities.h"
+#include <security_utilities/unix++.h>
+#include <security_utilities/debugging.h>
 #include <Security/CSCommon.h>
 #include <security_utilities/unix++.h>
 #include <security_utilities/cfmunge.h>
 #include <Security/CSCommon.h>
 #include <security_utilities/unix++.h>
 #include <security_utilities/cfmunge.h>
@@ -38,17 +40,25 @@ namespace CodeSigning {
 // Construction and maintainance
 //
 ResourceBuilder::ResourceBuilder(const std::string &root, CFDictionaryRef rulesDict, CodeDirectory::HashAlgorithm hashType)
 // Construction and maintainance
 //
 ResourceBuilder::ResourceBuilder(const std::string &root, CFDictionaryRef rulesDict, CodeDirectory::HashAlgorithm hashType)
-       : ResourceEnumerator(root), mHashType(hashType)
+       : mRoot(root), mHashType(hashType)
 {
 {
+       assert(!mRoot.empty());
+    if (mRoot.substr(mRoot.length()-2, 2) == "/.")  // produced by versioned bundle implicit "Current" case
+        mRoot = mRoot.substr(0, mRoot.length()-2);  // ... so take it off for this
+       const char * paths[2] = { mRoot.c_str(), NULL };
+       mFTS = fts_open((char * const *)paths, FTS_PHYSICAL | FTS_COMFOLLOW | FTS_NOCHDIR, NULL);
+       if (!mFTS)
+               UnixError::throwMe();
+       mRawRules = rulesDict;
        CFDictionary rules(rulesDict, errSecCSResourceRulesInvalid);
        rules.apply(this, &ResourceBuilder::addRule);
        CFDictionary rules(rulesDict, errSecCSResourceRulesInvalid);
        rules.apply(this, &ResourceBuilder::addRule);
-       mRawRules = rules;
 }
 
 ResourceBuilder::~ResourceBuilder()
 {
        for (Rules::iterator it = mRules.begin(); it != mRules.end(); ++it)
                delete *it;
 }
 
 ResourceBuilder::~ResourceBuilder()
 {
        for (Rules::iterator it = mRules.begin(); it != mRules.end(); ++it)
                delete *it;
+       UnixPlusPlus::checkError(fts_close(mFTS));
 }
 
 
 }
 
 
@@ -73,6 +83,12 @@ void ResourceBuilder::addRule(CFTypeRef key, CFTypeRef value)
                if (CFBooleanRef optRef = rule.get<CFBooleanRef>("optional"))
                        if (optRef == kCFBooleanTrue)
                                flags |= optional;
                if (CFBooleanRef optRef = rule.get<CFBooleanRef>("optional"))
                        if (optRef == kCFBooleanTrue)
                                flags |= optional;
+               if (CFBooleanRef nestRef = rule.get<CFBooleanRef>("nested"))
+                       if (nestRef == kCFBooleanTrue)
+                               flags |= nested;
+               if (CFBooleanRef topRef = rule.get<CFBooleanRef>("top"))
+                       if (topRef == kCFBooleanTrue)
+                               flags |= top;
        }
        addRule(new Rule(pattern, weight, flags));
 }
        }
        addRule(new Rule(pattern, weight, flags));
 }
@@ -82,64 +98,99 @@ void ResourceBuilder::addRule(CFTypeRef key, CFTypeRef value)
 // Locate the next non-ignored file, look up its rule, and return it.
 // Returns NULL when we're out of files.
 //
 // Locate the next non-ignored file, look up its rule, and return it.
 // Returns NULL when we're out of files.
 //
-FTSENT *ResourceBuilder::next(string &path, Rule * &rule)
+void ResourceBuilder::scan(Scanner next)
 {
 {
-       while (FTSENT *ent = ResourceEnumerator::next(path)) {
-               // find best matching rule
-               Rule *bestRule = NULL;
-               for (Rules::const_iterator it = mRules.begin(); it != mRules.end(); ++it) {
-                       Rule *rule = *it;
-                       if (rule->match(path.c_str())) {
-                               if (rule->flags & exclusion) {
-                                       bestRule = NULL;
-                                       break;
+       bool first = true;
+       while (FTSENT *ent = fts_read(mFTS)) {
+               const char *relpath = ent->fts_path + mRoot.size() + 1; // skip prefix + "/"
+               switch (ent->fts_info) {
+               case FTS_F:
+                       secdebug("rdirenum", "file %s", ent->fts_path);
+                       if (Rule *rule = findRule(relpath))
+                               if (!(rule->flags & (omitted | exclusion)))
+                                       next(ent, rule->flags, relpath, rule);
+                       break;
+               case FTS_SL:
+                       // symlinks cannot ever be nested code, so quietly convert to resource file
+                       secdebug("rdirenum", "symlink %s", ent->fts_path);
+                       if (Rule *rule = findRule(relpath))
+                               if (!(rule->flags & (omitted | exclusion)))
+                                       next(ent, rule->flags & ~nested, relpath, rule);
+                       break;
+               case FTS_D:
+                       secdebug("rdirenum", "entering %s", ent->fts_path);
+                       if (!first) {   // skip root directory (relpath invalid)
+                               if (Rule *rule = findRule(relpath)) {
+                                       if (rule->flags & nested) {
+                                               if (strchr(ent->fts_name, '.')) {       // nested, has extension -> treat as nested bundle
+                                                       next(ent, rule->flags, relpath, rule);
+                                                       fts_set(mFTS, ent, FTS_SKIP);
+                                               }
+                                       } else if (rule->flags & exclusion) {   // exclude the whole directory
+                                               fts_set(mFTS, ent, FTS_SKIP);
+                                       }
+                                       // else treat as normal directory and descend into it
                                }
                                }
-                               if (!bestRule || rule->weight > bestRule->weight)
-                                       bestRule = rule;
-               }
+                       }
+                       first = false;
+                       break;
+               case FTS_DP:
+                       secdebug("rdirenum", "leaving %s", ent->fts_path);
+                       break;
+               default:
+                       secdebug("rdirenum", "type %d (errno %d): %s",
+                               ent->fts_info, ent->fts_errno, ent->fts_path);
+                       break;
                }
                }
-               if (!bestRule || (bestRule->flags & omitted))
-                       continue;
-               rule = bestRule;
-               return ent;
        }
        }
-       return NULL;
 }
 
 
 //
 }
 
 
 //
-// Build the ResourceDirectory given the currently established rule set.
+// Check a single for for inclusion in the resource envelope
+//
+bool ResourceBuilder::includes(string path) const
+{
+       if (Rule *rule = findRule(path))
+               return !(rule->flags & (omitted | exclusion));
+       else
+               return false;
+}
+
+
+//
+// Find the best-matching resource rule for an alleged resource file.
+// Returns NULL if no rule matches, or an exclusion rule applies.
 //
 //
-CFDictionaryRef ResourceBuilder::build()
+ResourceBuilder::Rule *ResourceBuilder::findRule(string path) const
 {
 {
-       secdebug("codesign", "start building resource directory");
-       CFRef<CFMutableDictionaryRef> files = makeCFMutableDictionary();
-
-       string path;
-       Rule *rule;
-       while (FTSENT *ent = next(path, rule)) {
-               assert(rule);
-               CFRef<CFDataRef> hash = hashFile(ent->fts_accpath);
-               if (rule->flags == 0) { // default case - plain hash
-                       cfadd(files, "{%s=%O}", path.c_str(), hash.get());
-                       secdebug("csresource", "%s added simple (rule %p)", path.c_str(), rule);
-               } else {        // more complicated - use a sub-dictionary
-                       cfadd(files, "{%s={hash=%O,optional=%B}}",
-                               path.c_str(), hash.get(), rule->flags & optional);
-                       secdebug("csresource", "%s added complex (rule %p)", path.c_str(), rule);
+       Rule *bestRule = NULL;
+       secdebug("rscan", "test %s", path.c_str());
+       for (Rules::const_iterator it = mRules.begin(); it != mRules.end(); ++it) {
+               Rule *rule = *it;
+               secdebug("rscan", "try %s", rule->source.c_str());
+               if (rule->match(path.c_str())) {
+                       secdebug("rscan", "match");
+                       if (rule->flags & exclusion) {
+                               secdebug("rscan", "excluded");
+                               return rule;
+                       }
+                       if (!bestRule || rule->weight > bestRule->weight)
+                               bestRule = rule;
                }
        }
                }
        }
-       secdebug("codesign", "finished code directory with %d entries",
-               int(CFDictionaryGetCount(files)));
-       
-       return cfmake<CFDictionaryRef>("{rules=%O,files=%O}", mRawRules.get(), files.get());
+       secdebug("rscan", "choosing %s (%d,0x%x)",
+               bestRule ? bestRule->source.c_str() : "NOTHING",
+               bestRule ? bestRule->weight : 0,
+               bestRule ? bestRule->flags : 0);
+       return bestRule;
 }
 
 
 //
 // Hash a file and return a CFDataRef with the hash
 //
 }
 
 
 //
 // Hash a file and return a CFDataRef with the hash
 //
-CFDataRef ResourceBuilder::hashFile(const char *path)
+CFDataRef ResourceBuilder::hashFile(const char *path) const
 {
        UnixPlusPlus::AutoFileDesc fd(path);
        fd.fcntl(F_NOCACHE, true);              // turn off page caching (one-pass)
 {
        UnixPlusPlus::AutoFileDesc fd(path);
        fd.fcntl(F_NOCACHE, true);              // turn off page caching (one-pass)
@@ -155,7 +206,7 @@ CFDataRef ResourceBuilder::hashFile(const char *path)
 // Regex matching objects
 //
 ResourceBuilder::Rule::Rule(const std::string &pattern, unsigned w, uint32_t f)
 // Regex matching objects
 //
 ResourceBuilder::Rule::Rule(const std::string &pattern, unsigned w, uint32_t f)
-       : weight(w), flags(f)
+       : weight(w), flags(f), source(pattern)
 {
        if (::regcomp(this, pattern.c_str(), REG_EXTENDED | REG_NOSUB)) //@@@ REG_ICASE?
                MacOSError::throwMe(errSecCSResourceRulesInvalid);
 {
        if (::regcomp(this, pattern.c_str(), REG_EXTENDED | REG_NOSUB)) //@@@ REG_ICASE?
                MacOSError::throwMe(errSecCSResourceRulesInvalid);
@@ -198,16 +249,28 @@ std::string ResourceBuilder::escapeRE(const std::string &s)
 // Resource Seals
 //
 ResourceSeal::ResourceSeal(CFTypeRef it)
 // Resource Seals
 //
 ResourceSeal::ResourceSeal(CFTypeRef it)
+       : mDict(NULL), mHash(NULL), mRequirement(NULL), mLink(NULL), mFlags(0)
 {
        if (it == NULL)
                MacOSError::throwMe(errSecCSResourcesInvalid);
        if (CFGetTypeID(it) == CFDataGetTypeID()) {
                mHash = CFDataRef(it);
 {
        if (it == NULL)
                MacOSError::throwMe(errSecCSResourcesInvalid);
        if (CFGetTypeID(it) == CFDataGetTypeID()) {
                mHash = CFDataRef(it);
-               mOptional = false;
        } else {
        } else {
-               mOptional = false;
-               if (!cfscan(it, "{hash=%XO,?optional=%B}", &mHash, &mOptional))
+               int optional = 0;
+               mDict = CFDictionaryRef(it);
+               bool err;
+               if (CFDictionaryGetValue(mDict, CFSTR("requirement")))
+                       err = !cfscan(mDict, "{requirement=%SO,?optional=%B}", &mRequirement, &optional);
+               else if (CFDictionaryGetValue(mDict, CFSTR("symlink")))
+                       err = !cfscan(mDict, "{symlink=%SO,?optional=%B}", &mLink, &optional);
+               else
+                       err = !cfscan(mDict, "{hash=%XO,?optional=%B}", &mHash, &optional);
+               if (err)
                        MacOSError::throwMe(errSecCSResourcesInvalid);
                        MacOSError::throwMe(errSecCSResourcesInvalid);
+               if (optional)
+                       mFlags |= ResourceBuilder::optional;
+               if (mRequirement)
+                       mFlags |= ResourceBuilder::nested;
        }
 }
 
        }
 }
 
index 69c5851b6cb286b1d03b4565190f1eb8bfc4ba1f..749939da9ff4b6d118359ba21ed6fe1537bcb4bc 100644 (file)
@@ -27,7 +27,6 @@
 #ifndef _H_RSIGN
 #define _H_RSIGN
 
 #ifndef _H_RSIGN
 #define _H_RSIGN
 
-#include "renum.h"
 #include "codedirectory.h"
 #include <security_utilities/utilities.h>
 #include <security_utilities/cfutilities.h>
 #include "codedirectory.h"
 #include <security_utilities/utilities.h>
 #include <security_utilities/cfutilities.h>
@@ -35,6 +34,7 @@
 #include "regex.h"
 #include <CoreFoundation/CoreFoundation.h>
 #include <vector>
 #include "regex.h"
 #include <CoreFoundation/CoreFoundation.h>
 #include <vector>
+#include <fts.h>
 
 namespace Security {
 namespace CodeSigning {
 
 namespace Security {
 namespace CodeSigning {
@@ -43,20 +43,21 @@ namespace CodeSigning {
 //
 // The builder of ResourceDirectories.
 //
 //
 // The builder of ResourceDirectories.
 //
-// Note that this *is* a ResourceEnumerate, which can enumerate
+// Note that this *is* a ResourceEnumerator, which can enumerate
 // its source directory once (only).
 //
 // its source directory once (only).
 //
-class ResourceBuilder : public ResourceEnumerator {
+class ResourceBuilder {
+       NOCOPY(ResourceBuilder)
 public:
 public:
-       ResourceBuilder(const std::string &root, CFDictionaryRef rules, CodeDirectory::HashAlgorithm hashType);
+       ResourceBuilder(const std::string &root, CFDictionaryRef rulesDict, CodeDirectory::HashAlgorithm hashType);
        ~ResourceBuilder();
 
        ~ResourceBuilder();
 
-       CFDictionaryRef build();
-
-       enum Action {
+       enum {
                optional = 0x01,                                // may be absent at runtime
                omitted = 0x02,                                 // do not seal even if present
                optional = 0x01,                                // may be absent at runtime
                omitted = 0x02,                                 // do not seal even if present
-               exclusion = 0x04,                               // overriding exclusion (stop looking)
+               nested = 0x04,                                  // nested code (recursively signed)
+               exclusion = 0x10,                               // overriding exclusion (stop looking)
+               top = 0x20,                                             // special top directory handling
        };
        
        typedef unsigned int Weight;
        };
        
        typedef unsigned int Weight;
@@ -71,20 +72,29 @@ public:
                
                const Weight weight;
                const uint32_t flags;
                
                const Weight weight;
                const uint32_t flags;
+               std::string source;
        };
        void addRule(Rule *rule) { mRules.push_back(rule); }
        void addExclusion(const std::string &pattern) { mRules.insert(mRules.begin(), new Rule(pattern, 0, exclusion)); }
 
        static std::string escapeRE(const std::string &s);
        
        };
        void addRule(Rule *rule) { mRules.push_back(rule); }
        void addExclusion(const std::string &pattern) { mRules.insert(mRules.begin(), new Rule(pattern, 0, exclusion)); }
 
        static std::string escapeRE(const std::string &s);
        
-       FTSENT *next(std::string &path, Rule * &rule);  // enumerate next file and match rule
+       typedef void (^Scanner)(FTSENT *ent, uint32_t flags, const char *relpath, Rule *rule);
+       void scan(Scanner next);
+       bool includes(string path) const;
+       Rule *findRule(string path) const;
+
+       DynamicHash *getHash() const { return CodeDirectory::hashFor(this->mHashType); }
+       CFDataRef hashFile(const char *path) const;
+       
+       CFDictionaryRef rules() const { return mRawRules; }
 
 protected:
        void addRule(CFTypeRef key, CFTypeRef value);
 
 protected:
        void addRule(CFTypeRef key, CFTypeRef value);
-       CFDataRef hashFile(const char *path);
-       DynamicHash *getHash() const { return CodeDirectory::hashFor(this->mHashType); }
        
 private:
        
 private:
+       std::string mRoot;
+       FTS *mFTS;
        CFCopyRef<CFDictionaryRef> mRawRules;
        typedef std::vector<Rule *> Rules;
        Rules mRules;
        CFCopyRef<CFDictionaryRef> mRawRules;
        typedef std::vector<Rule *> Rules;
        Rules mRules;
@@ -104,11 +114,18 @@ public:
        bool operator ! () const { return mHash == NULL; }
        
        const SHA1::Byte *hash() const { return CFDataGetBytePtr(mHash); }
        bool operator ! () const { return mHash == NULL; }
        
        const SHA1::Byte *hash() const { return CFDataGetBytePtr(mHash); }
-       bool optional() const { return mOptional; }
+       bool nested() const { return mFlags & ResourceBuilder::nested; }
+       bool optional() const { return mFlags & ResourceBuilder::optional; }
+       CFDictionaryRef dict() const { return mDict; }
+       CFStringRef requirement() const { return mRequirement; }
+       CFStringRef link() const { return mLink; }
 
 private:
 
 private:
+       CFDictionaryRef mDict;
        CFDataRef mHash;
        CFDataRef mHash;
-       int mOptional;
+       CFStringRef mRequirement;
+       CFStringRef mLink;
+       uint32_t mFlags;
 };
 
 
 };
 
 
index 00c9147db149ca8ae0320b4da23365266c9e7ce0..d6f20463c4afda209dc552c98ce52e2694f47af7 100644 (file)
@@ -39,6 +39,7 @@ _SecCodeSetDetachedSignature
 _kSecCodeAttributeArchitecture
 _kSecCodeAttributeBundleVersion
 _kSecCodeAttributeSubarchitecture
 _kSecCodeAttributeArchitecture
 _kSecCodeAttributeBundleVersion
 _kSecCodeAttributeSubarchitecture
+_kSecCodeAttributeUniversalFileOffset
 _SecStaticCodeGetTypeID
 _SecStaticCodeCreateWithPath
 _SecStaticCodeCreateWithPathAndAttributes
 _SecStaticCodeGetTypeID
 _SecStaticCodeCreateWithPath
 _SecStaticCodeCreateWithPathAndAttributes
@@ -93,6 +94,7 @@ _kSecCodeInfoTime
 _kSecCodeInfoDesignatedRequirement
 _kSecCodeInfoEntitlements
 _kSecCodeInfoEntitlementsDict
 _kSecCodeInfoDesignatedRequirement
 _kSecCodeInfoEntitlements
 _kSecCodeInfoEntitlementsDict
+_kSecCodeInfoFlags
 _kSecCodeInfoFormat
 _kSecCodeInfoDigestAlgorithm
 _kSecCodeInfoIdentifier
 _kSecCodeInfoFormat
 _kSecCodeInfoDigestAlgorithm
 _kSecCodeInfoIdentifier
@@ -131,6 +133,7 @@ _SecTaskCreateWithAuditToken
 _SecTaskCreateFromSelf
 _SecTaskCopyValueForEntitlement
 _SecTaskCopyValuesForEntitlements
 _SecTaskCreateFromSelf
 _SecTaskCopyValueForEntitlement
 _SecTaskCopyValuesForEntitlements
+_SecTaskValidateForRequirement
 
 # Assessments
 _SecAssessmentCreate
 
 # Assessments
 _SecAssessmentCreate
@@ -156,6 +159,6 @@ _kSecAssessmentAssessmentAuthorityRow
 _kSecAssessmentAssessmentFromCache
 _kSecAssessmentAssessmentOriginator
 _kSecAssessmentAssessmentAuthorityOverride
 _kSecAssessmentAssessmentFromCache
 _kSecAssessmentAssessmentOriginator
 _kSecAssessmentAssessmentAuthorityOverride
+_kSecAssessmentAssessmentOriginalVerdict
 _kSecAssessmentAssessmentSource
 _kSecAssessmentAssessmentVerdict
 _kSecAssessmentAssessmentSource
 _kSecAssessmentAssessmentVerdict
-_kSecAssessmentContextKeyCertificates
index 95ad32dccd6f24d7a2167189f2553fbf015c09e0..a82a65485300b6862a8f99f4ab82195e608c5c01 100644 (file)
@@ -34,13 +34,15 @@ namespace CodeSigning {
 
 CFDataRef EmbeddedSignatureBlob::component(CodeDirectory::SpecialSlot slot) const
 {
 
 CFDataRef EmbeddedSignatureBlob::component(CodeDirectory::SpecialSlot slot) const
 {
-       if (const BlobCore *blob = this->find(slot))
-               if (CodeDirectory::slotAttributes(slot) & cdComponentIsBlob)
+       if (const BlobCore *blob = this->find(slot)) {
+               if (CodeDirectory::slotAttributes(slot) & cdComponentIsBlob) {
                        return makeCFData(*blob);       // is a native Blob
                        return makeCFData(*blob);       // is a native Blob
-               else if (const BlobWrapper *wrap = BlobWrapper::specific(blob))
+               } else if (const BlobWrapper *wrap = BlobWrapper::specific(blob)) {
                        return makeCFData(*wrap);
                        return makeCFData(*wrap);
-               else
+               } else {
                        MacOSError::throwMe(errSecCSSignatureInvalid);
                        MacOSError::throwMe(errSecCSSignatureInvalid);
+               }
+       }
        return NULL;
 }
 
        return NULL;
 }
 
index fc0c58f52fefdebabbf3944b52e68dfdac83bd47..968accf152f97ae68f7c6238e6c18713d8b0b7f2 100644 (file)
 #include <Security/CMSPrivate.h>
 #include <Security/CSCommonPriv.h>
 #include <CoreFoundation/CFBundlePriv.h>
 #include <Security/CMSPrivate.h>
 #include <Security/CSCommonPriv.h>
 #include <CoreFoundation/CFBundlePriv.h>
-#include "renum.h"
+#include "resources.h"
 #include "machorep.h"
 #include "machorep.h"
+#include "reqparser.h"
+#include "reqdumper.h"
 #include "csutilities.h"
 #include <security_utilities/unix++.h>
 #include <security_utilities/unixchild.h>
 #include "csutilities.h"
 #include <security_utilities/unix++.h>
 #include <security_utilities/unixchild.h>
@@ -51,6 +53,7 @@ void SecCodeSigner::Signer::sign(SecCSFlags flags)
 {
        rep = code->diskRep()->base();
        this->prepare(flags);
 {
        rep = code->diskRep()->base();
        this->prepare(flags);
+       
        PreSigningContext context(*this);
        if (Universal *fat = state.mNoMachO ? NULL : rep->mainExecutableImage()) {
                signMachO(fat, context);
        PreSigningContext context(*this);
        if (Universal *fat = state.mNoMachO ? NULL : rep->mainExecutableImage()) {
                signMachO(fat, context);
@@ -93,9 +96,13 @@ void SecCodeSigner::Signer::prepare(SecCSFlags flags)
        CFRef<CFDictionaryRef> infoDict;
        if (CFRef<CFDataRef> infoData = rep->component(cdInfoSlot))
                infoDict.take(makeCFDictionaryFrom(infoData));
        CFRef<CFDictionaryRef> infoDict;
        if (CFRef<CFDataRef> infoData = rep->component(cdInfoSlot))
                infoDict.take(makeCFDictionaryFrom(infoData));
+       
+       uint32_t inherit = code->isSigned() ? state.mPreserveMetadata : 0;
 
        // work out the canonical identifier
        identifier = state.mIdentifier;
 
        // work out the canonical identifier
        identifier = state.mIdentifier;
+       if (identifier.empty() && (inherit & kSecCodeSignerPreserveIdentifier))
+               identifier = code->identifier();
        if (identifier.empty()) {
                identifier = rep->recommendedIdentifier(state);
                if (identifier.find('.') == string::npos)
        if (identifier.empty()) {
                identifier = rep->recommendedIdentifier(state);
                if (identifier.find('.') == string::npos)
@@ -105,12 +112,19 @@ void SecCodeSigner::Signer::prepare(SecCSFlags flags)
                secdebug("signer", "using default identifier=%s", identifier.c_str());
        } else
                secdebug("signer", "using explicit identifier=%s", identifier.c_str());
                secdebug("signer", "using default identifier=%s", identifier.c_str());
        } else
                secdebug("signer", "using explicit identifier=%s", identifier.c_str());
+
+       entitlements = state.mEntitlementData;
+       if (!entitlements && (inherit & kSecCodeSignerPreserveEntitlements))
+               entitlements = code->component(cdEntitlementSlot);
        
        // work out the CodeDirectory flags word
        
        // work out the CodeDirectory flags word
-       if (state.mCdFlagsGiven) {
+       bool haveCdFlags = false;
+       if (!haveCdFlags && state.mCdFlagsGiven) {
                cdFlags = state.mCdFlags;
                secdebug("signer", "using explicit cdFlags=0x%x", cdFlags);
                cdFlags = state.mCdFlags;
                secdebug("signer", "using explicit cdFlags=0x%x", cdFlags);
-       } else {
+               haveCdFlags = true;
+       }
+       if (!haveCdFlags) {
                cdFlags = 0;
                if (infoDict)
                        if (CFTypeRef csflags = CFDictionaryGetValue(infoDict, CFSTR("CSFlags"))) {
                cdFlags = 0;
                if (infoDict)
                        if (CFTypeRef csflags = CFDictionaryGetValue(infoDict, CFSTR("CSFlags"))) {
@@ -122,10 +136,37 @@ void SecCodeSigner::Signer::prepare(SecCSFlags flags)
                                        secdebug("signer", "using text cdFlags=0x%x from Info.plist", cdFlags);
                                } else
                                        MacOSError::throwMe(errSecCSBadDictionaryFormat);
                                        secdebug("signer", "using text cdFlags=0x%x from Info.plist", cdFlags);
                                } else
                                        MacOSError::throwMe(errSecCSBadDictionaryFormat);
+                               haveCdFlags = true;
                        }
        }
                        }
        }
+       if (!haveCdFlags && (inherit & kSecCodeSignerPreserveFlags)) {
+               cdFlags = code->codeDirectory(false)->flags & ~kSecCodeSignatureAdhoc;
+               secdebug("signer", "using inherited cdFlags=0x%x", cdFlags);
+               haveCdFlags = true;
+       }
+       if (!haveCdFlags)
+               cdFlags = 0;
        if (state.mSigner == SecIdentityRef(kCFNull))   // ad-hoc signing requested...
                cdFlags |= kSecCodeSignatureAdhoc;      // ... so note that
        if (state.mSigner == SecIdentityRef(kCFNull))   // ad-hoc signing requested...
                cdFlags |= kSecCodeSignatureAdhoc;      // ... so note that
+
+       // prepare the internal requirements input
+       if (state.mRequirements) {
+               if (CFGetTypeID(state.mRequirements) == CFDataGetTypeID()) {            // binary form
+                       const Requirements *rp = (const Requirements *)CFDataGetBytePtr(state.mRequirements.as<CFDataRef>());
+                       if (!rp->validateBlob())
+                               MacOSError::throwMe(errSecCSReqInvalid);
+                       requirements = rp->clone();
+               } else if (CFGetTypeID(state.mRequirements) == CFStringGetTypeID()) { // text form
+                       CFRef<CFMutableStringRef> reqText = CFStringCreateMutableCopy(NULL, 0, state.mRequirements.as<CFStringRef>());
+                       // substitute $ variable tokens
+                       CFRange range = { 0, CFStringGetLength(reqText) };
+                       CFStringFindAndReplace(reqText, CFSTR("$self.identifier"), CFTempString(identifier), range, 0);
+                       requirements = parseRequirements(cfString(reqText));
+               } else
+                       MacOSError::throwMe(errSecCSInvalidObjectRef);
+       } else if (inherit & kSecCodeSignerPreserveRequirements)
+               if (const Requirements *rp = code->internalRequirements())
+                       requirements = rp->clone();
        
        // prepare the resource directory, if any
        string rpath = rep->resourcesRootPath();
        
        // prepare the resource directory, if any
        string rpath = rep->resourcesRootPath();
@@ -133,6 +174,11 @@ void SecCodeSigner::Signer::prepare(SecCSFlags flags)
                // explicitly given resource rules always win
                CFCopyRef<CFDictionaryRef> resourceRules = state.mResourceRules;
                
                // explicitly given resource rules always win
                CFCopyRef<CFDictionaryRef> resourceRules = state.mResourceRules;
                
+               // inherited rules come next (overriding embedded ones!)
+               if (!resourceRules && (inherit & kSecCodeSignerPreserveResourceRules))
+                       if (CFDictionaryRef oldRules = code->resourceDictionary(false))
+                               resourceRules = oldRules;
+               
                // embedded resource rules come next
                if (!resourceRules && infoDict)
                        if (CFTypeRef spec = CFDictionaryGetValue(infoDict, _kCFBundleResourceSpecificationKey)) {
                // embedded resource rules come next
                if (!resourceRules && infoDict)
                        if (CFTypeRef spec = CFDictionaryGetValue(infoDict, _kCFBundleResourceSpecificationKey)) {
@@ -143,16 +189,20 @@ void SecCodeSigner::Signer::prepare(SecCSFlags flags)
                                if (!resourceRules)     // embedded rules present but unacceptable
                                        MacOSError::throwMe(errSecCSResourceRulesInvalid);
                        }
                                if (!resourceRules)     // embedded rules present but unacceptable
                                        MacOSError::throwMe(errSecCSResourceRulesInvalid);
                        }
+               
+               // if we got one from anywhere (but the defaults), sanity-check it
+               if (resourceRules) {
+                       CFTypeRef rules = CFDictionaryGetValue(resourceRules, CFSTR("rules"));
+                       if (!rules || CFGetTypeID(rules) != CFDictionaryGetTypeID())
+                               MacOSError::throwMe(errSecCSResourceRulesInvalid);
+               }
 
                // finally, ask the DiskRep for its default
                if (!resourceRules)
                        resourceRules.take(rep->defaultResourceRules(state));
                
                // build the resource directory
 
                // finally, ask the DiskRep for its default
                if (!resourceRules)
                        resourceRules.take(rep->defaultResourceRules(state));
                
                // build the resource directory
-               ResourceBuilder resources(rpath, cfget<CFDictionaryRef>(resourceRules, "rules"), digestAlgorithm());
-               rep->adjustResources(resources);        // DiskRep-specific adjustments
-               CFRef<CFDictionaryRef> rdir = resources.build();
-               resourceDirectory.take(CFPropertyListCreateXMLData(NULL, rdir));
+               buildResources(rpath, resourceRules);
        }
        
        // screen and set the signing time
        }
        
        // screen and set the signing time
@@ -175,6 +225,121 @@ void SecCodeSigner::Signer::prepare(SecCSFlags flags)
 }
 
 
 }
 
 
+//
+// Collect the resource seal for a program.
+// This includes both sealed resources and information about nested code.
+//
+void SecCodeSigner::Signer::buildResources(std::string root, CFDictionaryRef rulesDict)
+{
+       typedef ResourceBuilder::Rule Rule;
+       
+       secdebug("codesign", "start building resource directory");
+       __block CFRef<CFMutableDictionaryRef> result = makeCFMutableDictionary();
+       
+       CFDictionaryRef rules = cfget<CFDictionaryRef>(rulesDict, "rules");
+       assert(rules);
+
+       CFDictionaryRef files2 = NULL;
+       if (!(state.signingFlags() & kSecCSSignV1)) {
+               CFCopyRef<CFDictionaryRef> rules2 = cfget<CFDictionaryRef>(rulesDict, "rules2");
+               if (!rules2) {
+                       // Clone V1 rules and add default nesting rules at weight 0 (overridden by anything in rules).
+                       // V1 rules typically do not cover these places so we'll prevail, but if they do, we defer to them.
+                       rules2 = cfmake<CFDictionaryRef>("{+%O"
+                               "'^[^/]+$' = {top=#T, weight=0}"                        // files directly in Contents
+                               "'^(Frameworks|SharedFrameworks|Plugins|Plug-ins|XPCServices|Helpers|MacOS)/' = {nested=#T, weight=0}" // exclude dynamic repositories
+                       "}", rules);
+               }
+               // build the modern (V2) resource seal
+               __block CFRef<CFMutableDictionaryRef> files = makeCFMutableDictionary();
+               ResourceBuilder resourceBuilder(root, rules2, digestAlgorithm());
+               ResourceBuilder &resources = resourceBuilder;   // (into block)
+               rep->adjustResources(resources);
+               resources.scan(^(FTSENT *ent, uint32_t ruleFlags, const char *relpath, Rule *rule) {
+                       CFRef<CFMutableDictionaryRef> seal;
+                       if (ruleFlags & ResourceBuilder::nested) {
+                               seal.take(signNested(ent, relpath));
+                       } else if (ent->fts_info == FTS_SL) {
+                               char target[PATH_MAX];
+                               ssize_t len = ::readlink(ent->fts_accpath, target, sizeof(target)-1);
+                               if (len < 0)
+                                       UnixError::check(-1);
+                               target[len] = '\0';
+                               seal.take(cfmake<CFMutableDictionaryRef>("{symlink=%s}", target));
+                       } else {
+                               seal.take(cfmake<CFMutableDictionaryRef>("{hash=%O}",
+                                       CFRef<CFDataRef>(resources.hashFile(ent->fts_accpath)).get()));
+                       }
+                       if (ruleFlags & ResourceBuilder::optional)
+                               CFDictionaryAddValue(seal, CFSTR("optional"), kCFBooleanTrue);
+                       CFTypeRef hash;
+                       if ((hash = CFDictionaryGetValue(seal, CFSTR("hash"))) && CFDictionaryGetCount(seal) == 1) // simple form
+                               CFDictionaryAddValue(files, CFTempString(relpath).get(), hash);
+                       else
+                               CFDictionaryAddValue(files, CFTempString(relpath).get(), seal.get());
+               });
+               CFDictionaryAddValue(result, CFSTR("rules2"), resourceBuilder.rules());
+               files2 = files;
+               CFDictionaryAddValue(result, CFSTR("files2"), files2);
+       }
+       
+       CFDictionaryAddValue(result, CFSTR("rules"), rules);    // preserve V1 rules in any case
+       if (!(state.signingFlags() & kSecCSSignNoV1)) {
+               // build the legacy (V1) resource seal
+               __block CFRef<CFMutableDictionaryRef> files = makeCFMutableDictionary();
+               ResourceBuilder resourceBuilder(root, rules, digestAlgorithm());
+               ResourceBuilder &resources = resourceBuilder;
+               rep->adjustResources(resources);        // DiskRep-specific adjustments
+               resources.scan(^(FTSENT *ent, uint32_t ruleFlags, const char *relpath, Rule *rule) {
+                       if (ent->fts_info == FTS_F) {
+                               CFRef<CFDataRef> hash;
+                               if (files2)     // try to get the hash from a previously-made version
+                                       if (CFTypeRef seal = CFDictionaryGetValue(files2, CFTempString(relpath))) {
+                                               if (CFGetTypeID(seal) == CFDataGetTypeID())
+                                                       hash = CFDataRef(seal);
+                                               else
+                                                       hash = CFDataRef(CFDictionaryGetValue(CFDictionaryRef(seal), CFSTR("hash")));
+                                       }
+                               if (!hash)
+                                       hash.take(resources.hashFile(ent->fts_accpath));
+                               if (ruleFlags == 0) {   // default case - plain hash
+                                       cfadd(files, "{%s=%O}", relpath, hash.get());
+                                       secdebug("csresource", "%s added simple (rule %p)", relpath, rule);
+                               } else {        // more complicated - use a sub-dictionary
+                                       cfadd(files, "{%s={hash=%O,optional=%B}}",
+                                               relpath, hash.get(), ruleFlags & ResourceBuilder::optional);
+                                       secdebug("csresource", "%s added complex (rule %p)", relpath, rule);
+                               }
+                       }
+               });
+               CFDictionaryAddValue(result, CFSTR("files"), files.get());
+       }
+       
+       resourceDirectory = result.get();
+       resourceDictData.take(makeCFData(resourceDirectory.get()));
+}
+
+
+//
+// Deal with one piece of nested code
+//
+CFMutableDictionaryRef SecCodeSigner::Signer::signNested(FTSENT *ent, const char *relpath)
+{
+       // sign nested code and collect nesting information
+       try {
+               SecPointer<SecStaticCode> code = new SecStaticCode(DiskRep::bestGuess(ent->fts_path));
+               if (state.signingFlags() & kSecCSSignNestedCode)
+                       this->state.sign(code, state.signingFlags());
+               std::string dr = Dumper::dump(code->designatedRequirement());
+               return cfmake<CFMutableDictionaryRef>("{requirement=%s,cdhash=%O}",
+                       Dumper::dump(code->designatedRequirement()).c_str(),
+                       code->cdHash());
+       } catch (const CommonError &err) {
+               CSError::throwMe(err.osStatus(), kSecCFErrorPath, CFTempURL(relpath, false, this->code->resourceBase()));
+       }
+}
+
+
 //
 // Sign a Mach-O binary, using liberal dollops of that special Mach-O magic sauce.
 // Note that this will deal just fine with non-fat Mach-O binaries, but it will
 //
 // Sign a Mach-O binary, using liberal dollops of that special Mach-O magic sauce.
 // Note that this will deal just fine with non-fat Mach-O binaries, but it will
@@ -195,7 +360,7 @@ void SecCodeSigner::Signer::signMachO(Universal *fat, const Requirement::Context
        for (MachOEditor::Iterator it = editor->begin(); it != editor->end(); ++it) {
                MachOEditor::Arch &arch = *it->second;
                arch.source.reset(fat->architecture(it->first));
        for (MachOEditor::Iterator it = editor->begin(); it != editor->end(); ++it) {
                MachOEditor::Arch &arch = *it->second;
                arch.source.reset(fat->architecture(it->first));
-               arch.ireqs(state.mRequirements, rep->defaultRequirements(&arch.architecture, state), context);
+               arch.ireqs(requirements, rep->defaultRequirements(&arch.architecture, state), context);
                if (editor->attribute(writerNoGlobal))  // can't store globally, add per-arch
                        populate(arch);
                populate(arch.cdbuilder, arch, arch.ireqs,
                if (editor->attribute(writerNoGlobal))  // can't store globally, add per-arch
                        populate(arch);
                populate(arch.cdbuilder, arch, arch.ireqs,
@@ -251,7 +416,7 @@ void SecCodeSigner::Signer::signArchitectureAgnostic(const Requirement::Context
                (new DetachedBlobWriter(*this)) : rep->writer();
        CodeDirectory::Builder builder(state.mDigestAlgorithm);
        InternalRequirements ireqs;
                (new DetachedBlobWriter(*this)) : rep->writer();
        CodeDirectory::Builder builder(state.mDigestAlgorithm);
        InternalRequirements ireqs;
-       ireqs(state.mRequirements, rep->defaultRequirements(NULL, state), context);
+       ireqs(requirements, rep->defaultRequirements(NULL, state), context);
        populate(*writer);
        populate(builder, *writer, ireqs, rep->signingBase(), rep->signingLimit());
        
        populate(*writer);
        populate(builder, *writer, ireqs, rep->signingBase(), rep->signingLimit());
        
@@ -277,8 +442,8 @@ void SecCodeSigner::Signer::signArchitectureAgnostic(const Requirement::Context
 //
 void SecCodeSigner::Signer::populate(DiskRep::Writer &writer)
 {
 //
 void SecCodeSigner::Signer::populate(DiskRep::Writer &writer)
 {
-       if (resourceDirectory)
-               writer.component(cdResourceDirSlot, resourceDirectory);
+       if (resourceDirectory && !state.mDryRun)
+               writer.component(cdResourceDirSlot, resourceDictData);
 }
 
 
 }
 
 
@@ -304,14 +469,14 @@ void SecCodeSigner::Signer::populate(CodeDirectory::Builder &builder, DiskRep::W
                builder.specialSlot(cdRequirementsSlot, data);
        }
        if (resourceDirectory)
                builder.specialSlot(cdRequirementsSlot, data);
        }
        if (resourceDirectory)
-               builder.specialSlot(cdResourceDirSlot, resourceDirectory);
+               builder.specialSlot(cdResourceDirSlot, resourceDictData);
 #if NOT_YET
        if (state.mApplicationData)
                builder.specialSlot(cdApplicationSlot, state.mApplicationData);
 #endif
 #if NOT_YET
        if (state.mApplicationData)
                builder.specialSlot(cdApplicationSlot, state.mApplicationData);
 #endif
-       if (state.mEntitlementData) {
-               writer.component(cdEntitlementSlot, state.mEntitlementData);
-               builder.specialSlot(cdEntitlementSlot, state.mEntitlementData);
+       if (entitlements) {
+               writer.component(cdEntitlementSlot, entitlements);
+               builder.specialSlot(cdEntitlementSlot, entitlements);
        }
        
        writer.addDiscretionary(builder);
        }
        
        writer.addDiscretionary(builder);
@@ -411,9 +576,9 @@ std::string SecCodeSigner::Signer::uniqueName() const
 {
        CFRef<CFDataRef> identification = rep->identification();
        const UInt8 *ident = CFDataGetBytePtr(identification);
 {
        CFRef<CFDataRef> identification = rep->identification();
        const UInt8 *ident = CFDataGetBytePtr(identification);
-       const unsigned int length = CFDataGetLength(identification);
+       const CFIndex length = CFDataGetLength(identification);
        string result;
        string result;
-       for (unsigned int n = 0; n < length; n++) {
+       for (CFIndex n = 0; n < length; n++) {
                char hex[3];
                snprintf(hex, sizeof(hex), "%02x", ident[n]);
                result += hex;
                char hex[3];
                snprintf(hex, sizeof(hex), "%02x", ident[n]);
                result += hex;
index 101f222fba49ea824671a5c041a2acbad6334b93..dbbd1b442e81f7d1e6f1da557dfd8725132d3f7e 100644 (file)
@@ -45,7 +45,9 @@ namespace CodeSigning {
 //
 class SecCodeSigner::Signer {
 public:
 //
 class SecCodeSigner::Signer {
 public:
-       Signer(SecCodeSigner &s, SecStaticCode *c) : state(s), code(c) { }
+       Signer(SecCodeSigner &s, SecStaticCode *c) : state(s), code(c), requirements(NULL) { }
+       ~Signer() { ::free((Requirements *)requirements); }
+
        void sign(SecCSFlags flags);
        void remove(SecCSFlags flags);
        
        void sign(SecCSFlags flags);
        void remove(SecCSFlags flags);
        
@@ -70,12 +72,20 @@ protected:
 
        uint32_t cdTextFlags(std::string text);         // convert text CodeDirectory flags
        std::string uniqueName() const;                         // derive unique string from rep
 
        uint32_t cdTextFlags(std::string text);         // convert text CodeDirectory flags
        std::string uniqueName() const;                         // derive unique string from rep
-       
+
+protected:
+       void buildResources(std::string root, CFDictionaryRef rules);
+       CFMutableDictionaryRef signNested(FTSENT *ent, const char *relpath);
+       CFDataRef hashFile(const char *path);
+
 private:
        RefPointer<DiskRep> rep;                // DiskRep of Code being signed
 private:
        RefPointer<DiskRep> rep;                // DiskRep of Code being signed
-       CFRef<CFDataRef> resourceDirectory;     // resource directory
+       CFRef<CFDictionaryRef> resourceDirectory;       // resource directory
+       CFRef<CFDataRef> resourceDictData; // XML form of resourceDirectory
        std::string identifier;                 // signing identifier
        std::string identifier;                 // signing identifier
+       CFRef<CFDataRef> entitlements;  // entitlements
        uint32_t cdFlags;                               // CodeDirectory flags
        uint32_t cdFlags;                               // CodeDirectory flags
+       const Requirements *requirements; // internal requirements ready-to-use
        size_t pagesize;                                // size of main executable pages
        CFAbsoluteTime signingTime;             // signing time for CMS signature (0 => none)
 };
        size_t pagesize;                                // size of main executable pages
        CFAbsoluteTime signingTime;             // signing time for CMS signature (0 => none)
 };
index d03d884e5ede3411717bbbd525c894416da899fe..74dd23cebe10014d064a0d313cb38af75cd799de 100644 (file)
@@ -29,7 +29,7 @@
 #include "SecCodeSigner.h"
 #include <Security/SecIdentity.h>
 #include <Security/CMSEncoder.h>
 #include "SecCodeSigner.h"
 #include <Security/SecIdentity.h>
 #include <Security/CMSEncoder.h>
-#include "renum.h"
+#include "resources.h"
 #include "csutilities.h"
 #include "drmaker.h"
 #include <security_utilities/unix++.h>
 #include "csutilities.h"
 #include "drmaker.h"
 #include <security_utilities/unix++.h>
@@ -67,7 +67,7 @@ void BlobWriter::component(CodeDirectory::SpecialSlot slot, CFDataRef data)
 void DetachedBlobWriter::flush()
 {
        EmbeddedSignatureBlob *blob = this->make();
 void DetachedBlobWriter::flush()
 {
        EmbeddedSignatureBlob *blob = this->make();
-       signer.code->detachedSignature(makeCFData(*blob));
+       signer.code->detachedSignature(CFTempData(*blob));
        signer.state.returnDetachedSignature(blob, signer);
        ::free(blob);
 }
        signer.state.returnDetachedSignature(blob, signer);
        ::free(blob);
 }
@@ -171,7 +171,7 @@ void MachOEditor::allocate()
        fork();
        wait();
        if (!Child::succeeded())
        fork();
        wait();
        if (!Child::succeeded())
-               UnixError::throwMe(ENOEXEC);    //@@@ how to signal "it din' work"?
+               MacOSError::throwMe(errSecCSHelperFailed);
        
        // open the new (temporary) Universal file
        {
        
        // open the new (temporary) Universal file
        {
@@ -197,9 +197,7 @@ void MachOEditor::parentAction()
                CODESIGN_ALLOCATE_VALIDATE((char*)mHelperPath, this->pid());
                // check code identity of an overridden allocation helper
                SecPointer<SecStaticCode> code = new SecStaticCode(DiskRep::bestGuess(mHelperPath));
                CODESIGN_ALLOCATE_VALIDATE((char*)mHelperPath, this->pid());
                // check code identity of an overridden allocation helper
                SecPointer<SecStaticCode> code = new SecStaticCode(DiskRep::bestGuess(mHelperPath));
-               code->validateDirectory();
-               code->validateExecutable();
-               code->validateResources();
+               code->staticValidate(kSecCSDefaultFlags, NULL);
                code->validateRequirement((const Requirement *)appleReq, errSecCSReqFailed);
        }
 }
                code->validateRequirement((const Requirement *)appleReq, errSecCSReqFailed);
        }
 }
@@ -219,11 +217,11 @@ void MachOEditor::childAction()
                asprintf(&ssize, "%zd", size);
 
                if (const char *arch = it->first.name()) {
                asprintf(&ssize, "%zd", size);
 
                if (const char *arch = it->first.name()) {
-                       CODESIGN_ALLOCATE_ARCH((char*)arch, size);
+                       CODESIGN_ALLOCATE_ARCH((char*)arch, (unsigned int)size);
                        arguments.push_back("-a");
                        arguments.push_back(arch);
                } else {
                        arguments.push_back("-a");
                        arguments.push_back(arch);
                } else {
-                       CODESIGN_ALLOCATE_ARCHN(it->first.cpuType(), it->first.cpuSubtype(), size);
+                       CODESIGN_ALLOCATE_ARCHN(it->first.cpuType(), it->first.cpuSubtype(), (unsigned int)size);
                        arguments.push_back("-A");
                        char *anum;
                        asprintf(&anum, "%d", it->first.cpuType());
                        arguments.push_back("-A");
                        char *anum;
                        asprintf(&anum, "%d", it->first.cpuType());
@@ -257,7 +255,7 @@ void MachOEditor::write(Arch &arch, EmbeddedSignatureBlob *blob)
 {
        if (size_t offset = arch.source->signingOffset()) {
                size_t signingLength = arch.source->signingLength();
 {
        if (size_t offset = arch.source->signingOffset()) {
                size_t signingLength = arch.source->signingLength();
-               CODESIGN_ALLOCATE_WRITE((char*)arch.architecture.name(), offset, blob->length(), signingLength);
+               CODESIGN_ALLOCATE_WRITE((char*)arch.architecture.name(), offset, (unsigned)blob->length(), (unsigned)signingLength);
                if (signingLength < blob->length())
                        MacOSError::throwMe(errSecCSCMSTooLarge);
                arch.source->seek(offset);
                if (signingLength < blob->length())
                        MacOSError::throwMe(errSecCSCMSTooLarge);
                arch.source->seek(offset);
index 3fdb081565ec78eddf78687ebdfbdb7d97af32e4..b4d3b193ecd4a72bd271d387c754bd0f08b1b1a9 100644 (file)
@@ -109,7 +109,7 @@ public:
        typedef ArchMap::iterator Iterator;
        ArchMap::iterator begin()               { return architecture.begin(); }
        ArchMap::iterator end()                 { return architecture.end(); }
        typedef ArchMap::iterator Iterator;
        ArchMap::iterator begin()               { return architecture.begin(); }
        ArchMap::iterator end()                 { return architecture.end(); }
-       unsigned count() const                  { return architecture.size(); }
+       unsigned count() const                  { return (unsigned)architecture.size(); }
        
        // methods needed for an actual implementation
        virtual void allocate() = 0;                    // interpass allocations
        
        // methods needed for an actual implementation
        virtual void allocate() = 0;                    // interpass allocations
index 12e5a99d93a343e4e55941252e5ed60a077ec1fc..4bb944349ef98855fe9128cc8cbcef81207b647b 100644 (file)
@@ -57,7 +57,7 @@ void DYLDCacheRep::setup()
 {
        mSigningData = NULL;
        if (mCache.totalSize() >= mCache.mapSize() + sizeof(BlobCore)) {
 {
        mSigningData = NULL;
        if (mCache.totalSize() >= mCache.mapSize() + sizeof(BlobCore)) {
-               const EmbeddedSignatureBlob *blob = mCache.at<const EmbeddedSignatureBlob>(mCache.mapSize());
+               const EmbeddedSignatureBlob *blob = mCache.at<const EmbeddedSignatureBlob>((uint32_t)mCache.mapSize());
                if (mCache.totalSize() >= mCache.mapSize() + blob->length())    // entire blob fits in file
                        mSigningData = blob;
        }
                if (mCache.totalSize() >= mCache.mapSize() + blob->length())    // entire blob fits in file
                        mSigningData = blob;
        }
@@ -159,9 +159,9 @@ void DYLDCacheRep::Writer::addDiscretionary(CodeDirectory::Builder &builder)
                const DYLDCache::Mapping dmap = rep->mCache.mapping(n);
                CodeDirectory::Scatter *scatter = builder.scatter() + n;
                scatter->targetOffset = dmap.address();
                const DYLDCache::Mapping dmap = rep->mCache.mapping(n);
                CodeDirectory::Scatter *scatter = builder.scatter() + n;
                scatter->targetOffset = dmap.address();
-               scatter->base = dmap.offset() / segmentedPageSize;
+               scatter->base = (uint32_t)(dmap.offset() / segmentedPageSize);
                assert(dmap.offset() % segmentedPageSize == 0);
                assert(dmap.offset() % segmentedPageSize == 0);
-               scatter->count = dmap.size() / segmentedPageSize;
+               scatter->count = (uint32_t)(dmap.size() / segmentedPageSize);
                assert(dmap.size() % segmentedPageSize == 0);
        }
 }
                assert(dmap.size() % segmentedPageSize == 0);
        }
 }
index f779db5698f31e1f0d877f4c731ba2fb31f31f5f..4a289f6323e73fcd2e86e5fed46ee6962eb90b45 100644 (file)
@@ -81,7 +81,7 @@ public:
                if (type == XPC_TYPE_DICTIONARY) {
                        obj = reply;
                        if (int64_t error = xpc_dictionary_get_int64(obj, "error"))
                if (type == XPC_TYPE_DICTIONARY) {
                        obj = reply;
                        if (int64_t error = xpc_dictionary_get_int64(obj, "error"))
-                               MacOSError::throwMe(error);
+                               MacOSError::throwMe((int)error);
                } else if (type == XPC_TYPE_ERROR) {
                        const char *s = xpc_copy_description(reply);
                        printf("Error returned: %s\n", s);
                } else if (type == XPC_TYPE_ERROR) {
                        const char *s = xpc_copy_description(reply);
                        printf("Error returned: %s\n", s);
@@ -100,8 +100,6 @@ public:
 static void copyCFDictionary(const void *key, const void *value, void *ctx)
 {
        CFMutableDictionaryRef target = CFMutableDictionaryRef(ctx);
 static void copyCFDictionary(const void *key, const void *value, void *ctx)
 {
        CFMutableDictionaryRef target = CFMutableDictionaryRef(ctx);
-       if (CFEqual(key, kSecAssessmentContextKeyCertificates)) // obsolete
-               return;
        if (CFGetTypeID(value) == CFURLGetTypeID()) {
                CFRef<CFStringRef> path = CFURLCopyFileSystemPath(CFURLRef(value), kCFURLPOSIXPathStyle);
                CFDictionaryAddValue(target, key, path);
        if (CFGetTypeID(value) == CFURLGetTypeID()) {
                CFRef<CFStringRef> path = CFURLCopyFileSystemPath(CFURLRef(value), kCFURLPOSIXPathStyle);
                CFDictionaryAddValue(target, key, path);
@@ -110,7 +108,7 @@ static void copyCFDictionary(const void *key, const void *value, void *ctx)
        }
 }
 
        }
 }
 
-void xpcEngineAssess(CFURLRef path, uint flags, CFDictionaryRef context, CFMutableDictionaryRef result)
+void xpcEngineAssess(CFURLRef path, SecAssessmentFlags flags, CFDictionaryRef context, CFMutableDictionaryRef result)
 {
        Message msg("assess");
        xpc_dictionary_set_string(msg, "path", cfString(path).c_str());
 {
        Message msg("assess");
        xpc_dictionary_set_string(msg, "path", cfString(path).c_str());
@@ -124,7 +122,7 @@ void xpcEngineAssess(CFURLRef path, uint flags, CFDictionaryRef context, CFMutab
        msg.send();
        
        if (int64_t error = xpc_dictionary_get_int64(msg, "error"))
        msg.send();
        
        if (int64_t error = xpc_dictionary_get_int64(msg, "error"))
-               MacOSError::throwMe(error);
+               MacOSError::throwMe((int)error);
 
        size_t resultLength;
        const void *resultData = xpc_dictionary_get_data(msg, "result", &resultLength);
 
        size_t resultLength;
        const void *resultData = xpc_dictionary_get_data(msg, "result", &resultLength);
@@ -134,7 +132,7 @@ void xpcEngineAssess(CFURLRef path, uint flags, CFDictionaryRef context, CFMutab
 }
 
 
 }
 
 
-CFDictionaryRef xpcEngineUpdate(CFTypeRef target, uint flags, CFDictionaryRef context)
+CFDictionaryRef xpcEngineUpdate(CFTypeRef target, SecAssessmentFlags flags, CFDictionaryRef context)
 {
        Message msg("update");
        // target can be NULL, a CFURLRef, a SecRequirementRef, or a CFNumberRef
 {
        Message msg("update");
        // target can be NULL, a CFURLRef, a SecRequirementRef, or a CFNumberRef
@@ -170,7 +168,7 @@ CFDictionaryRef xpcEngineUpdate(CFTypeRef target, uint flags, CFDictionaryRef co
                AuthorizationFree(localAuthorization, kAuthorizationFlagDefaults);
        
        if (int64_t error = xpc_dictionary_get_int64(msg, "error"))
                AuthorizationFree(localAuthorization, kAuthorizationFlagDefaults);
        
        if (int64_t error = xpc_dictionary_get_int64(msg, "error"))
-               MacOSError::throwMe(error);
+               MacOSError::throwMe((int)error);
        
        size_t resultLength;
        const void *resultData = xpc_dictionary_get_data(msg, "result", &resultLength);
        
        size_t resultLength;
        const void *resultData = xpc_dictionary_get_data(msg, "result", &resultLength);
@@ -187,5 +185,15 @@ bool xpcEngineControl(const char *control)
 }
 
 
 }
 
 
+void xpcEngineRecord(CFDictionaryRef info)
+{
+       Message msg("record");
+       CFRef<CFDataRef> infoData = makeCFData(CFDictionaryRef(info));
+       xpc_dictionary_set_data(msg, "info", CFDataGetBytePtr(infoData), CFDataGetLength(infoData));
+
+       msg.send();
+}
+
+
 } // end namespace CodeSigning
 } // end namespace Security
 } // end namespace CodeSigning
 } // end namespace Security
index e2edd01bb27f898ad2ccfe4bd7970e54c94daed0..0e64f478f18ed0c46d0ebcd6f522e113719f53d0 100644 (file)
@@ -32,10 +32,11 @@ namespace Security {
 namespace CodeSigning {
 
 
 namespace CodeSigning {
 
 
-void xpcEngineAssess(CFURLRef path, uint flags, CFDictionaryRef context, CFMutableDictionaryRef result);
-CFDictionaryRef xpcEngineUpdate(CFTypeRef target, uint flags, CFDictionaryRef context)
+void xpcEngineAssess(CFURLRef path, SecAssessmentFlags flags, CFDictionaryRef context, CFMutableDictionaryRef result);
+CFDictionaryRef xpcEngineUpdate(CFTypeRef target, SecAssessmentFlags flags, CFDictionaryRef context)
     CF_RETURNS_RETAINED;
 bool xpcEngineControl(const char *name);
     CF_RETURNS_RETAINED;
 bool xpcEngineControl(const char *name);
+void xpcEngineRecord(CFDictionaryRef info);
 
 
 } // end namespace CodeSigning
 
 
 } // end namespace CodeSigning
index d2402b652246a706febd9776baefbeacaf44a8ad..468ff3025976cf2f39a4ca69bc4df23da7ebb575 100644 (file)
@@ -70,8 +70,8 @@
                18B9658A1472FC5B005A4D2E /* reqinterp.h in Headers */ = {isa = PBXBuildFile; fileRef = C2C1DFBA0A2F80EB00D1B02B /* reqinterp.h */; settings = {ATTRIBUTES = (Public, ); }; };
                18B9658B1472FC5B005A4D2E /* reqparser.h in Headers */ = {isa = PBXBuildFile; fileRef = C2D383340A237F47005C63A2 /* reqparser.h */; settings = {ATTRIBUTES = (Public, ); }; };
                18B9658C1472FC9E005A4D2E /* codedirectory.h in Headers */ = {isa = PBXBuildFile; fileRef = C2D383170A237F47005C63A2 /* codedirectory.h */; settings = {ATTRIBUTES = (Public, ); }; };
                18B9658A1472FC5B005A4D2E /* reqinterp.h in Headers */ = {isa = PBXBuildFile; fileRef = C2C1DFBA0A2F80EB00D1B02B /* reqinterp.h */; settings = {ATTRIBUTES = (Public, ); }; };
                18B9658B1472FC5B005A4D2E /* reqparser.h in Headers */ = {isa = PBXBuildFile; fileRef = C2D383340A237F47005C63A2 /* reqparser.h */; settings = {ATTRIBUTES = (Public, ); }; };
                18B9658C1472FC9E005A4D2E /* codedirectory.h in Headers */ = {isa = PBXBuildFile; fileRef = C2D383170A237F47005C63A2 /* codedirectory.h */; settings = {ATTRIBUTES = (Public, ); }; };
-               18B965941472FE27005A4D2E /* renum.h in Headers */ = {isa = PBXBuildFile; fileRef = C2EF100F0A49BD89005A44BB /* renum.h */; settings = {ATTRIBUTES = (Public, ); }; };
                18B965951472FE30005A4D2E /* cdbuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = C2D383150A237F47005C63A2 /* cdbuilder.h */; settings = {ATTRIBUTES = (Public, ); }; };
                18B965951472FE30005A4D2E /* cdbuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = C2D383150A237F47005C63A2 /* cdbuilder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               BEC3A75C16F78D21003E5634 /* SecTaskPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = BEC3A75B16F78D21003E5634 /* SecTaskPriv.h */; };
                C200424D15D425D9004AE0A1 /* libsecurity_codesigning.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C200424915D425B7004AE0A1 /* libsecurity_codesigning.a */; };
                C200424E15D425D9004AE0A1 /* libsecurity_utilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C200424A15D425B7004AE0A1 /* libsecurity_utilities.a */; };
                C2093AA80BB0948000EB8599 /* reqreader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2093AA60BB0948000EB8599 /* reqreader.cpp */; };
                C200424D15D425D9004AE0A1 /* libsecurity_codesigning.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C200424915D425B7004AE0A1 /* libsecurity_codesigning.a */; };
                C200424E15D425D9004AE0A1 /* libsecurity_utilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C200424A15D425B7004AE0A1 /* libsecurity_utilities.a */; };
                C2093AA80BB0948000EB8599 /* reqreader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2093AA60BB0948000EB8599 /* reqreader.cpp */; };
                C2DC2DCB145F5CD000AD2A3A /* policyengine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C27360201432A61900A9A5FF /* policyengine.cpp */; };
                C2E2873D0B5D8D80009336A0 /* SecCodeHostLib.c in Sources */ = {isa = PBXBuildFile; fileRef = C2E2873C0B5D8D80009336A0 /* SecCodeHostLib.c */; };
                C2E911E20ADEBE3200275CB2 /* resources.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2E911E00ADEBE3200275CB2 /* resources.cpp */; };
                C2DC2DCB145F5CD000AD2A3A /* policyengine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C27360201432A61900A9A5FF /* policyengine.cpp */; };
                C2E2873D0B5D8D80009336A0 /* SecCodeHostLib.c in Sources */ = {isa = PBXBuildFile; fileRef = C2E2873C0B5D8D80009336A0 /* SecCodeHostLib.c */; };
                C2E911E20ADEBE3200275CB2 /* resources.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2E911E00ADEBE3200275CB2 /* resources.cpp */; };
-               C2EF10100A49BD89005A44BB /* renum.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2EF100E0A49BD89005A44BB /* renum.cpp */; };
                C2F4439A14C626D4000A01E6 /* quarantine++.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2F4439814C626D4000A01E6 /* quarantine++.cpp */; };
                C2F4439B14C626D4000A01E6 /* quarantine++.h in Headers */ = {isa = PBXBuildFile; fileRef = C2F4439914C626D4000A01E6 /* quarantine++.h */; };
                C2F6566E0BCBFB250078779E /* cserror.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2F6566C0BCBFB250078779E /* cserror.cpp */; };
                C2F4439A14C626D4000A01E6 /* quarantine++.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2F4439814C626D4000A01E6 /* quarantine++.cpp */; };
                C2F4439B14C626D4000A01E6 /* quarantine++.h in Headers */ = {isa = PBXBuildFile; fileRef = C2F4439914C626D4000A01E6 /* quarantine++.h */; };
                C2F6566E0BCBFB250078779E /* cserror.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2F6566C0BCBFB250078779E /* cserror.cpp */; };
                EB68B133150DB04400B4013D /* RequirementKeywords.h in Headers */ = {isa = PBXBuildFile; fileRef = EB68B10A150DAEBB00B4013D /* RequirementKeywords.h */; };
                EB68B134150DB04400B4013D /* RequirementLexer.hpp in Headers */ = {isa = PBXBuildFile; fileRef = EB68B10C150DAEBB00B4013D /* RequirementLexer.hpp */; };
                EB68B135150DB04400B4013D /* RequirementParser.hpp in Headers */ = {isa = PBXBuildFile; fileRef = EB68B10E150DAEBB00B4013D /* RequirementParser.hpp */; };
                EB68B133150DB04400B4013D /* RequirementKeywords.h in Headers */ = {isa = PBXBuildFile; fileRef = EB68B10A150DAEBB00B4013D /* RequirementKeywords.h */; };
                EB68B134150DB04400B4013D /* RequirementLexer.hpp in Headers */ = {isa = PBXBuildFile; fileRef = EB68B10C150DAEBB00B4013D /* RequirementLexer.hpp */; };
                EB68B135150DB04400B4013D /* RequirementParser.hpp in Headers */ = {isa = PBXBuildFile; fileRef = EB68B10E150DAEBB00B4013D /* RequirementParser.hpp */; };
+               EB976FB81684D7C500A68EE6 /* ANTLRUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB976F981684D77600A68EE6 /* ANTLRUtil.cpp */; };
+               EB976FB91684D7C500A68EE6 /* ASTFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB976F991684D77600A68EE6 /* ASTFactory.cpp */; };
+               EB976FBA1684D7C500A68EE6 /* ASTNULLType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB976F9A1684D77600A68EE6 /* ASTNULLType.cpp */; };
+               EB976FBB1684D7C500A68EE6 /* ASTRefCount.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB976F9B1684D77600A68EE6 /* ASTRefCount.cpp */; };
+               EB976FBC1684D7C500A68EE6 /* BaseAST.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB976F9C1684D77600A68EE6 /* BaseAST.cpp */; };
+               EB976FBD1684D7C500A68EE6 /* BitSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB976F9D1684D77600A68EE6 /* BitSet.cpp */; };
+               EB976FBE1684D7C500A68EE6 /* CharBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB976F9E1684D77600A68EE6 /* CharBuffer.cpp */; };
+               EB976FBF1684D7C500A68EE6 /* CharScanner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB976F9F1684D77600A68EE6 /* CharScanner.cpp */; };
+               EB976FC01684D7C500A68EE6 /* CommonAST.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB976FA01684D77600A68EE6 /* CommonAST.cpp */; };
+               EB976FC11684D7C500A68EE6 /* CommonASTWithHiddenTokens.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB976FA11684D77600A68EE6 /* CommonASTWithHiddenTokens.cpp */; };
+               EB976FC21684D7C500A68EE6 /* CommonHiddenStreamToken.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB976FA21684D77600A68EE6 /* CommonHiddenStreamToken.cpp */; };
+               EB976FC31684D7C500A68EE6 /* CommonToken.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB976FA31684D77600A68EE6 /* CommonToken.cpp */; };
+               EB976FC41684D7C500A68EE6 /* InputBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB976FA51684D77600A68EE6 /* InputBuffer.cpp */; };
+               EB976FC51684D7C500A68EE6 /* LLkParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB976FA61684D77600A68EE6 /* LLkParser.cpp */; };
+               EB976FC61684D7C500A68EE6 /* MismatchedCharException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB976FA81684D77600A68EE6 /* MismatchedCharException.cpp */; };
+               EB976FC71684D7C500A68EE6 /* MismatchedTokenException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB976FA91684D77600A68EE6 /* MismatchedTokenException.cpp */; };
+               EB976FC81684D7C500A68EE6 /* NoViableAltException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB976FAA1684D77600A68EE6 /* NoViableAltException.cpp */; };
+               EB976FC91684D7C500A68EE6 /* NoViableAltForCharException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB976FAB1684D77600A68EE6 /* NoViableAltForCharException.cpp */; };
+               EB976FCA1684D7C500A68EE6 /* Parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB976FAC1684D77600A68EE6 /* Parser.cpp */; };
+               EB976FCB1684D7C500A68EE6 /* RecognitionException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB976FAD1684D77600A68EE6 /* RecognitionException.cpp */; };
+               EB976FCC1684D7C500A68EE6 /* String.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB976FAE1684D77600A68EE6 /* String.cpp */; };
+               EB976FCD1684D7C500A68EE6 /* Token.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB976FAF1684D77600A68EE6 /* Token.cpp */; };
+               EB976FCE1684D7C500A68EE6 /* TokenBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB976FB01684D77600A68EE6 /* TokenBuffer.cpp */; };
+               EB976FCF1684D7C500A68EE6 /* TokenRefCount.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB976FB11684D77600A68EE6 /* TokenRefCount.cpp */; };
+               EB976FD01684D7C500A68EE6 /* TokenStreamBasicFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB976FB21684D77600A68EE6 /* TokenStreamBasicFilter.cpp */; };
+               EB976FD11684D7C500A68EE6 /* TokenStreamHiddenTokenFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB976FB31684D77600A68EE6 /* TokenStreamHiddenTokenFilter.cpp */; };
+               EB976FD21684D7C500A68EE6 /* TokenStreamRewriteEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB976FB41684D77600A68EE6 /* TokenStreamRewriteEngine.cpp */; };
+               EB976FD31684D7C500A68EE6 /* TokenStreamSelector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB976FB51684D77600A68EE6 /* TokenStreamSelector.cpp */; };
+               EB976FD41684D7C500A68EE6 /* TreeParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB976FB61684D77600A68EE6 /* TreeParser.cpp */; };
+               EBB9FF7A1682E51300FF9774 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = EBB9FF791682E51300FF9774 /* main.c */; };
+               EBB9FF7F1682E5A200FF9774 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EBB9FF7E1682E5A200FF9774 /* CoreFoundation.framework */; };
+               EBB9FFE21682E83600FF9774 /* com.apple.CodeSigningHelper.sb in CopyFiles */ = {isa = PBXBuildFile; fileRef = EBB9FF801682E65700FF9774 /* com.apple.CodeSigningHelper.sb */; };
+               EBDAF04F166D65FA0042CDCE /* piddiskrep.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EBDAF04D166D65FA0042CDCE /* piddiskrep.cpp */; };
+               EBDAF050166D65FA0042CDCE /* piddiskrep.h in Headers */ = {isa = PBXBuildFile; fileRef = EBDAF04E166D65FA0042CDCE /* piddiskrep.h */; };
+               EBF9A1581684E12700BCECA6 /* libsecurity_codesigning.plist in Copy OpenSourceVersions */ = {isa = PBXBuildFile; fileRef = EBF9A1551684E0F300BCECA6 /* libsecurity_codesigning.plist */; };
+               EBF9A15A1684E14100BCECA6 /* libsecurity_codesigning.txt in OpenSourceLicenses */ = {isa = PBXBuildFile; fileRef = EBF9A1561684E0F300BCECA6 /* libsecurity_codesigning.txt */; };
                FEB30C9310DAC89D00557BA2 /* SecTask.c in Sources */ = {isa = PBXBuildFile; fileRef = FEB30C9210DAC89D00557BA2 /* SecTask.c */; };
                FEB30CA410DAC97400557BA2 /* SecTask.h in Headers */ = {isa = PBXBuildFile; fileRef = FEB30C9410DAC8A500557BA2 /* SecTask.h */; settings = {ATTRIBUTES = (); }; };
 /* End PBXBuildFile section */
                FEB30C9310DAC89D00557BA2 /* SecTask.c in Sources */ = {isa = PBXBuildFile; fileRef = FEB30C9210DAC89D00557BA2 /* SecTask.c */; };
                FEB30CA410DAC97400557BA2 /* SecTask.h in Headers */ = {isa = PBXBuildFile; fileRef = FEB30C9410DAC8A500557BA2 /* SecTask.h */; settings = {ATTRIBUTES = (); }; };
 /* End PBXBuildFile section */
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                };
+               EBB9FFE11682E80A00FF9774 /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 8;
+                       dstPath = /System/Library/Sandbox/Profiles;
+                       dstSubfolderSpec = 0;
+                       files = (
+                               EBB9FFE21682E83600FF9774 /* com.apple.CodeSigningHelper.sb in CopyFiles */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+               EBF9A1501684E0DF00BCECA6 /* Copy OpenSourceVersions */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 8;
+                       dstPath = /usr/local/OpenSourceVersions;
+                       dstSubfolderSpec = 0;
+                       files = (
+                               EBF9A1581684E12700BCECA6 /* libsecurity_codesigning.plist in Copy OpenSourceVersions */,
+                       );
+                       name = "Copy OpenSourceVersions";
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+               EBF9A1591684E12C00BCECA6 /* OpenSourceLicenses */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 8;
+                       dstPath = /usr/local/OpenSourceLicenses;
+                       dstSubfolderSpec = 0;
+                       files = (
+                               EBF9A15A1684E14100BCECA6 /* libsecurity_codesigning.txt in OpenSourceLicenses */,
+                       );
+                       name = OpenSourceLicenses;
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
 /* End PBXCopyFilesBuildPhase section */
 
 /* Begin PBXFileReference section */
 /* End PBXCopyFilesBuildPhase section */
 
 /* Begin PBXFileReference section */
                184461A1146E9AD100B12992 /* lib.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = lib.xcconfig; sourceTree = "<group>"; };
                184461A2146E9AD100B12992 /* release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = release.xcconfig; sourceTree = "<group>"; };
                4CA1FEBE052A3C8100F22E42 /* libsecurity_codesigning.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libsecurity_codesigning.a; sourceTree = BUILT_PRODUCTS_DIR; };
                184461A1146E9AD100B12992 /* lib.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = lib.xcconfig; sourceTree = "<group>"; };
                184461A2146E9AD100B12992 /* release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = release.xcconfig; sourceTree = "<group>"; };
                4CA1FEBE052A3C8100F22E42 /* libsecurity_codesigning.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libsecurity_codesigning.a; sourceTree = BUILT_PRODUCTS_DIR; };
+               BEC3A75B16F78D21003E5634 /* SecTaskPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecTaskPriv.h; sourceTree = "<group>"; };
                C200424915D425B7004AE0A1 /* libsecurity_codesigning.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libsecurity_codesigning.a; path = ../../../usr/local/lib/libsecurity_codesigning.a; sourceTree = "<group>"; };
                C200424A15D425B7004AE0A1 /* libsecurity_utilities.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libsecurity_utilities.a; path = ../../../usr/local/lib/libsecurity_utilities.a; sourceTree = "<group>"; };
                C2093AA60BB0948000EB8599 /* reqreader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = reqreader.cpp; sourceTree = "<group>"; };
                C200424915D425B7004AE0A1 /* libsecurity_codesigning.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libsecurity_codesigning.a; path = ../../../usr/local/lib/libsecurity_codesigning.a; sourceTree = "<group>"; };
                C200424A15D425B7004AE0A1 /* libsecurity_utilities.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libsecurity_utilities.a; path = ../../../usr/local/lib/libsecurity_utilities.a; sourceTree = "<group>"; };
                C2093AA60BB0948000EB8599 /* reqreader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = reqreader.cpp; sourceTree = "<group>"; };
                C273601D1432A60B00A9A5FF /* policyengine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = policyengine.h; sourceTree = "<group>"; };
                C27360201432A61900A9A5FF /* policyengine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = policyengine.cpp; sourceTree = "<group>"; };
                C273606C1433F09000A9A5FF /* SecAssessment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = SecAssessment.cpp; sourceTree = "<group>"; };
                C273601D1432A60B00A9A5FF /* policyengine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = policyengine.h; sourceTree = "<group>"; };
                C27360201432A61900A9A5FF /* policyengine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = policyengine.cpp; sourceTree = "<group>"; };
                C273606C1433F09000A9A5FF /* SecAssessment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = SecAssessment.cpp; sourceTree = "<group>"; };
-               C273606D1433F09000A9A5FF /* SecAssessment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = SecAssessment.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
+               C273606D1433F09000A9A5FF /* SecAssessment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = SecAssessment.h; sourceTree = "<group>"; };
                C27360D41436866C00A9A5FF /* xpcengine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = xpcengine.cpp; sourceTree = "<group>"; };
                C27360D71436868600A9A5FF /* xpcengine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xpcengine.h; sourceTree = "<group>"; };
                C278A19B158AB2C300FA6767 /* gkhandmake */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = gkhandmake; sourceTree = "<group>"; };
                C27360D41436866C00A9A5FF /* xpcengine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = xpcengine.cpp; sourceTree = "<group>"; };
                C27360D71436868600A9A5FF /* xpcengine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xpcengine.h; sourceTree = "<group>"; };
                C278A19B158AB2C300FA6767 /* gkhandmake */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = gkhandmake; sourceTree = "<group>"; };
                C2E8AF260DE25CA7000F6D3B /* SecStaticCodePriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecStaticCodePriv.h; sourceTree = "<group>"; };
                C2E911E00ADEBE3200275CB2 /* resources.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = resources.cpp; sourceTree = "<group>"; };
                C2E911E10ADEBE3200275CB2 /* resources.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = resources.h; sourceTree = "<group>"; };
                C2E8AF260DE25CA7000F6D3B /* SecStaticCodePriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecStaticCodePriv.h; sourceTree = "<group>"; };
                C2E911E00ADEBE3200275CB2 /* resources.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = resources.cpp; sourceTree = "<group>"; };
                C2E911E10ADEBE3200275CB2 /* resources.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = resources.h; sourceTree = "<group>"; };
-               C2EF100E0A49BD89005A44BB /* renum.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = renum.cpp; sourceTree = "<group>"; };
-               C2EF100F0A49BD89005A44BB /* renum.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = renum.h; sourceTree = "<group>"; };
                C2F4439814C626D4000A01E6 /* quarantine++.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "quarantine++.cpp"; sourceTree = "<group>"; };
                C2F4439914C626D4000A01E6 /* quarantine++.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "quarantine++.h"; sourceTree = "<group>"; };
                C2F6071B107D575700A83618 /* codesign-watch.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; name = "codesign-watch.d"; path = "dtrace/codesign-watch.d"; sourceTree = SOURCE_ROOT; };
                C2F4439814C626D4000A01E6 /* quarantine++.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "quarantine++.cpp"; sourceTree = "<group>"; };
                C2F4439914C626D4000A01E6 /* quarantine++.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "quarantine++.h"; sourceTree = "<group>"; };
                C2F6071B107D575700A83618 /* codesign-watch.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; name = "codesign-watch.d"; path = "dtrace/codesign-watch.d"; sourceTree = SOURCE_ROOT; };
                EB68B10E150DAEBB00B4013D /* RequirementParser.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = RequirementParser.hpp; sourceTree = "<group>"; };
                EB68B10F150DAEBB00B4013D /* RequirementParserTokenTypes.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = RequirementParserTokenTypes.hpp; sourceTree = "<group>"; };
                EB68B110150DAEBB00B4013D /* RequirementParserTokenTypes.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = RequirementParserTokenTypes.txt; sourceTree = "<group>"; };
                EB68B10E150DAEBB00B4013D /* RequirementParser.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = RequirementParser.hpp; sourceTree = "<group>"; };
                EB68B10F150DAEBB00B4013D /* RequirementParserTokenTypes.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = RequirementParserTokenTypes.hpp; sourceTree = "<group>"; };
                EB68B110150DAEBB00B4013D /* RequirementParserTokenTypes.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = RequirementParserTokenTypes.txt; sourceTree = "<group>"; };
+               EB976F571684D77500A68EE6 /* ANTLRException.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ANTLRException.hpp; sourceTree = "<group>"; };
+               EB976F581684D77500A68EE6 /* ANTLRUtil.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ANTLRUtil.hpp; sourceTree = "<group>"; };
+               EB976F591684D77500A68EE6 /* AST.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = AST.hpp; sourceTree = "<group>"; };
+               EB976F5A1684D77500A68EE6 /* ASTArray.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ASTArray.hpp; sourceTree = "<group>"; };
+               EB976F5B1684D77500A68EE6 /* ASTFactory.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ASTFactory.hpp; sourceTree = "<group>"; };
+               EB976F5C1684D77500A68EE6 /* ASTNULLType.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ASTNULLType.hpp; sourceTree = "<group>"; };
+               EB976F5D1684D77500A68EE6 /* ASTPair.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ASTPair.hpp; sourceTree = "<group>"; };
+               EB976F5E1684D77500A68EE6 /* ASTRefCount.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ASTRefCount.hpp; sourceTree = "<group>"; };
+               EB976F5F1684D77500A68EE6 /* BaseAST.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = BaseAST.hpp; sourceTree = "<group>"; };
+               EB976F601684D77500A68EE6 /* BitSet.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = BitSet.hpp; sourceTree = "<group>"; };
+               EB976F611684D77500A68EE6 /* CharBuffer.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = CharBuffer.hpp; sourceTree = "<group>"; };
+               EB976F621684D77500A68EE6 /* CharInputBuffer.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = CharInputBuffer.hpp; sourceTree = "<group>"; };
+               EB976F631684D77500A68EE6 /* CharScanner.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = CharScanner.hpp; sourceTree = "<group>"; };
+               EB976F641684D77500A68EE6 /* CharStreamException.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = CharStreamException.hpp; sourceTree = "<group>"; };
+               EB976F651684D77500A68EE6 /* CharStreamIOException.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = CharStreamIOException.hpp; sourceTree = "<group>"; };
+               EB976F661684D77500A68EE6 /* CircularQueue.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = CircularQueue.hpp; sourceTree = "<group>"; };
+               EB976F671684D77500A68EE6 /* CommonAST.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = CommonAST.hpp; sourceTree = "<group>"; };
+               EB976F681684D77500A68EE6 /* CommonASTWithHiddenTokens.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = CommonASTWithHiddenTokens.hpp; sourceTree = "<group>"; };
+               EB976F691684D77500A68EE6 /* CommonHiddenStreamToken.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = CommonHiddenStreamToken.hpp; sourceTree = "<group>"; };
+               EB976F6A1684D77500A68EE6 /* CommonToken.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = CommonToken.hpp; sourceTree = "<group>"; };
+               EB976F6B1684D77500A68EE6 /* config.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = config.hpp; sourceTree = "<group>"; };
+               EB976F6C1684D77500A68EE6 /* InputBuffer.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = InputBuffer.hpp; sourceTree = "<group>"; };
+               EB976F6D1684D77500A68EE6 /* IOException.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = IOException.hpp; sourceTree = "<group>"; };
+               EB976F6E1684D77500A68EE6 /* LexerSharedInputState.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = LexerSharedInputState.hpp; sourceTree = "<group>"; };
+               EB976F6F1684D77500A68EE6 /* LLkParser.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = LLkParser.hpp; sourceTree = "<group>"; };
+               EB976F701684D77500A68EE6 /* Makefile.in */ = {isa = PBXFileReference; lastKnownFileType = text; path = Makefile.in; sourceTree = "<group>"; };
+               EB976F711684D77500A68EE6 /* MismatchedCharException.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = MismatchedCharException.hpp; sourceTree = "<group>"; };
+               EB976F721684D77500A68EE6 /* MismatchedTokenException.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = MismatchedTokenException.hpp; sourceTree = "<group>"; };
+               EB976F731684D77500A68EE6 /* NoViableAltException.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = NoViableAltException.hpp; sourceTree = "<group>"; };
+               EB976F741684D77500A68EE6 /* NoViableAltForCharException.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = NoViableAltForCharException.hpp; sourceTree = "<group>"; };
+               EB976F751684D77500A68EE6 /* Parser.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Parser.hpp; sourceTree = "<group>"; };
+               EB976F761684D77500A68EE6 /* ParserSharedInputState.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ParserSharedInputState.hpp; sourceTree = "<group>"; };
+               EB976F771684D77500A68EE6 /* RecognitionException.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = RecognitionException.hpp; sourceTree = "<group>"; };
+               EB976F781684D77500A68EE6 /* RefCount.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = RefCount.hpp; sourceTree = "<group>"; };
+               EB976F791684D77500A68EE6 /* SemanticException.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = SemanticException.hpp; sourceTree = "<group>"; };
+               EB976F7A1684D77500A68EE6 /* String.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = String.hpp; sourceTree = "<group>"; };
+               EB976F7B1684D77500A68EE6 /* Token.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Token.hpp; sourceTree = "<group>"; };
+               EB976F7C1684D77500A68EE6 /* TokenBuffer.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = TokenBuffer.hpp; sourceTree = "<group>"; };
+               EB976F7D1684D77500A68EE6 /* TokenRefCount.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = TokenRefCount.hpp; sourceTree = "<group>"; };
+               EB976F7E1684D77500A68EE6 /* TokenStream.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = TokenStream.hpp; sourceTree = "<group>"; };
+               EB976F7F1684D77500A68EE6 /* TokenStreamBasicFilter.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = TokenStreamBasicFilter.hpp; sourceTree = "<group>"; };
+               EB976F801684D77500A68EE6 /* TokenStreamException.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = TokenStreamException.hpp; sourceTree = "<group>"; };
+               EB976F811684D77500A68EE6 /* TokenStreamHiddenTokenFilter.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = TokenStreamHiddenTokenFilter.hpp; sourceTree = "<group>"; };
+               EB976F821684D77500A68EE6 /* TokenStreamIOException.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = TokenStreamIOException.hpp; sourceTree = "<group>"; };
+               EB976F831684D77500A68EE6 /* TokenStreamRecognitionException.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = TokenStreamRecognitionException.hpp; sourceTree = "<group>"; };
+               EB976F841684D77500A68EE6 /* TokenStreamRetryException.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = TokenStreamRetryException.hpp; sourceTree = "<group>"; };
+               EB976F851684D77500A68EE6 /* TokenStreamRewriteEngine.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = TokenStreamRewriteEngine.hpp; sourceTree = "<group>"; };
+               EB976F861684D77500A68EE6 /* TokenStreamSelector.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = TokenStreamSelector.hpp; sourceTree = "<group>"; };
+               EB976F871684D77500A68EE6 /* TokenWithIndex.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = TokenWithIndex.hpp; sourceTree = "<group>"; };
+               EB976F881684D77500A68EE6 /* TreeParser.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = TreeParser.hpp; sourceTree = "<group>"; };
+               EB976F891684D77500A68EE6 /* TreeParserSharedInputState.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = TreeParserSharedInputState.hpp; sourceTree = "<group>"; };
+               EB976F8A1684D77500A68EE6 /* AUTHORS */ = {isa = PBXFileReference; lastKnownFileType = text; name = AUTHORS; path = antlr2/AUTHORS; sourceTree = "<group>"; };
+               EB976F8B1684D77500A68EE6 /* ChangeLog */ = {isa = PBXFileReference; lastKnownFileType = text; name = ChangeLog; path = antlr2/ChangeLog; sourceTree = "<group>"; };
+               EB976F8E1684D77500A68EE6 /* antlr.bpr */ = {isa = PBXFileReference; lastKnownFileType = text; path = antlr.bpr; sourceTree = "<group>"; };
+               EB976F8F1684D77500A68EE6 /* antlr.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = antlr.cpp; sourceTree = "<group>"; };
+               EB976F901684D77500A68EE6 /* README */ = {isa = PBXFileReference; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
+               EB976F911684D77500A68EE6 /* doxygen.cfg */ = {isa = PBXFileReference; lastKnownFileType = text; name = doxygen.cfg; path = antlr2/doxygen.cfg; sourceTree = "<group>"; };
+               EB976F921684D77500A68EE6 /* Makefile.in */ = {isa = PBXFileReference; lastKnownFileType = text; name = Makefile.in; path = antlr2/Makefile.in; sourceTree = "<group>"; };
+               EB976F931684D77500A68EE6 /* README */ = {isa = PBXFileReference; lastKnownFileType = text; name = README; path = antlr2/README; sourceTree = "<group>"; };
+               EB976F951684D77500A68EE6 /* cr_stripper.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = cr_stripper.sh; sourceTree = "<group>"; };
+               EB976F961684D77500A68EE6 /* make_change_log.tcl */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = make_change_log.tcl; sourceTree = "<group>"; };
+               EB976F981684D77600A68EE6 /* ANTLRUtil.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ANTLRUtil.cpp; sourceTree = "<group>"; };
+               EB976F991684D77600A68EE6 /* ASTFactory.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ASTFactory.cpp; sourceTree = "<group>"; };
+               EB976F9A1684D77600A68EE6 /* ASTNULLType.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ASTNULLType.cpp; sourceTree = "<group>"; };
+               EB976F9B1684D77600A68EE6 /* ASTRefCount.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ASTRefCount.cpp; sourceTree = "<group>"; };
+               EB976F9C1684D77600A68EE6 /* BaseAST.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = BaseAST.cpp; sourceTree = "<group>"; };
+               EB976F9D1684D77600A68EE6 /* BitSet.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = BitSet.cpp; sourceTree = "<group>"; };
+               EB976F9E1684D77600A68EE6 /* CharBuffer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CharBuffer.cpp; sourceTree = "<group>"; };
+               EB976F9F1684D77600A68EE6 /* CharScanner.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CharScanner.cpp; sourceTree = "<group>"; };
+               EB976FA01684D77600A68EE6 /* CommonAST.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CommonAST.cpp; sourceTree = "<group>"; };
+               EB976FA11684D77600A68EE6 /* CommonASTWithHiddenTokens.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CommonASTWithHiddenTokens.cpp; sourceTree = "<group>"; };
+               EB976FA21684D77600A68EE6 /* CommonHiddenStreamToken.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CommonHiddenStreamToken.cpp; sourceTree = "<group>"; };
+               EB976FA31684D77600A68EE6 /* CommonToken.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CommonToken.cpp; sourceTree = "<group>"; };
+               EB976FA41684D77600A68EE6 /* dll.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = dll.cpp; sourceTree = "<group>"; };
+               EB976FA51684D77600A68EE6 /* InputBuffer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InputBuffer.cpp; sourceTree = "<group>"; };
+               EB976FA61684D77600A68EE6 /* LLkParser.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = LLkParser.cpp; sourceTree = "<group>"; };
+               EB976FA71684D77600A68EE6 /* Makefile.in */ = {isa = PBXFileReference; lastKnownFileType = text; path = Makefile.in; sourceTree = "<group>"; };
+               EB976FA81684D77600A68EE6 /* MismatchedCharException.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MismatchedCharException.cpp; sourceTree = "<group>"; };
+               EB976FA91684D77600A68EE6 /* MismatchedTokenException.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MismatchedTokenException.cpp; sourceTree = "<group>"; };
+               EB976FAA1684D77600A68EE6 /* NoViableAltException.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = NoViableAltException.cpp; sourceTree = "<group>"; };
+               EB976FAB1684D77600A68EE6 /* NoViableAltForCharException.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = NoViableAltForCharException.cpp; sourceTree = "<group>"; };
+               EB976FAC1684D77600A68EE6 /* Parser.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Parser.cpp; sourceTree = "<group>"; };
+               EB976FAD1684D77600A68EE6 /* RecognitionException.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = RecognitionException.cpp; sourceTree = "<group>"; };
+               EB976FAE1684D77600A68EE6 /* String.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = String.cpp; sourceTree = "<group>"; };
+               EB976FAF1684D77600A68EE6 /* Token.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Token.cpp; sourceTree = "<group>"; };
+               EB976FB01684D77600A68EE6 /* TokenBuffer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TokenBuffer.cpp; sourceTree = "<group>"; };
+               EB976FB11684D77600A68EE6 /* TokenRefCount.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TokenRefCount.cpp; sourceTree = "<group>"; };
+               EB976FB21684D77600A68EE6 /* TokenStreamBasicFilter.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TokenStreamBasicFilter.cpp; sourceTree = "<group>"; };
+               EB976FB31684D77600A68EE6 /* TokenStreamHiddenTokenFilter.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TokenStreamHiddenTokenFilter.cpp; sourceTree = "<group>"; };
+               EB976FB41684D77600A68EE6 /* TokenStreamRewriteEngine.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TokenStreamRewriteEngine.cpp; sourceTree = "<group>"; };
+               EB976FB51684D77600A68EE6 /* TokenStreamSelector.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TokenStreamSelector.cpp; sourceTree = "<group>"; };
+               EB976FB61684D77600A68EE6 /* TreeParser.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TreeParser.cpp; sourceTree = "<group>"; };
+               EB976FB71684D77600A68EE6 /* TODO */ = {isa = PBXFileReference; lastKnownFileType = text; name = TODO; path = antlr2/TODO; sourceTree = "<group>"; };
+               EBB9FF6F1682E51300FF9774 /* com.apple.CodeSigningHelper.xpc */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = com.apple.CodeSigningHelper.xpc; sourceTree = BUILT_PRODUCTS_DIR; };
+               EBB9FF701682E51300FF9774 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+               EBB9FF741682E51300FF9774 /* CodeSigningHelper-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "CodeSigningHelper-Info.plist"; sourceTree = "<group>"; };
+               EBB9FF791682E51300FF9774 /* main.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = "<group>"; };
+               EBB9FF7E1682E5A200FF9774 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/CoreFoundation.framework; sourceTree = DEVELOPER_DIR; };
+               EBB9FF801682E65700FF9774 /* com.apple.CodeSigningHelper.sb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = com.apple.CodeSigningHelper.sb; sourceTree = "<group>"; };
+               EBDAF04D166D65FA0042CDCE /* piddiskrep.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = piddiskrep.cpp; sourceTree = "<group>"; };
+               EBDAF04E166D65FA0042CDCE /* piddiskrep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = piddiskrep.h; sourceTree = "<group>"; };
+               EBF9A1551684E0F300BCECA6 /* libsecurity_codesigning.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = libsecurity_codesigning.plist; path = antlr2/libsecurity_codesigning.plist; sourceTree = "<group>"; };
+               EBF9A1561684E0F300BCECA6 /* libsecurity_codesigning.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = libsecurity_codesigning.txt; path = antlr2/libsecurity_codesigning.txt; sourceTree = "<group>"; };
+               EBF9A1571684E0F300BCECA6 /* LICENSE.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = LICENSE.txt; path = antlr2/LICENSE.txt; sourceTree = "<group>"; };
                FEB30C9210DAC89D00557BA2 /* SecTask.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecTask.c; sourceTree = "<group>"; };
                FEB30C9410DAC8A500557BA2 /* SecTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecTask.h; sourceTree = "<group>"; };
 /* End PBXFileReference section */
                FEB30C9210DAC89D00557BA2 /* SecTask.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecTask.c; sourceTree = "<group>"; };
                FEB30C9410DAC8A500557BA2 /* SecTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecTask.h; sourceTree = "<group>"; };
 /* End PBXFileReference section */
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               EBB9FF6C1682E51300FF9774 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               EBB9FF7F1682E5A200FF9774 /* CoreFoundation.framework in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
                4CA1FEA7052A3C3800F22E42 = {
                        isa = PBXGroup;
                        children = (
                4CA1FEA7052A3C3800F22E42 = {
                        isa = PBXGroup;
                        children = (
+                               EBB9FF7E1682E5A200FF9774 /* CoreFoundation.framework */,
                                C209697215BF57EB0093035F /* libsecurity_utilities.a */,
                                182BB4FC146F2823000BF1F3 /* libsecurityd.xcodeproj */,
                                4C308388053237100028A8C6 /* lib */,
                                1844619E146E9AD100B12992 /* config */,
                                C2D383F90A23A9D9005C63A2 /* cstemp */,
                                C209697215BF57EB0093035F /* libsecurity_utilities.a */,
                                182BB4FC146F2823000BF1F3 /* libsecurityd.xcodeproj */,
                                4C308388053237100028A8C6 /* lib */,
                                1844619E146E9AD100B12992 /* config */,
                                C2D383F90A23A9D9005C63A2 /* cstemp */,
+                               EB976F511684D73900A68EE6 /* antlr2 */,
+                               EBB9FF721682E51300FF9774 /* CodeSigningHelper */,
                                C2CC30EF0B8519CF005FA59D /* Frameworks */,
                                4CA1FEBF052A3C8100F22E42 /* Products */,
                        );
                                C2CC30EF0B8519CF005FA59D /* Frameworks */,
                                4CA1FEBF052A3C8100F22E42 /* Products */,
                        );
                                C2BC1F260B580D3A003EC9DC /* libintegrity.a */,
                                C2BC1F2F0B580D4B003EC9DC /* libcodehost.a */,
                                C209696015BF52040093035F /* gkunpack */,
                                C2BC1F260B580D3A003EC9DC /* libintegrity.a */,
                                C2BC1F2F0B580D4B003EC9DC /* libcodehost.a */,
                                C209696015BF52040093035F /* gkunpack */,
+                               EBB9FF6F1682E51300FF9774 /* com.apple.CodeSigningHelper.xpc */,
                        );
                        name = Products;
                        sourceTree = "<group>";
                        );
                        name = Products;
                        sourceTree = "<group>";
                                C2C3BCD10BA1E47E00E869D1 /* singlediskrep.cpp */,
                                C28342EC0E36719D00E54360 /* detachedrep.h */,
                                C28342EB0E36719D00E54360 /* detachedrep.cpp */,
                                C2C3BCD10BA1E47E00E869D1 /* singlediskrep.cpp */,
                                C28342EC0E36719D00E54360 /* detachedrep.h */,
                                C28342EB0E36719D00E54360 /* detachedrep.cpp */,
+                               EBDAF04D166D65FA0042CDCE /* piddiskrep.cpp */,
+                               EBDAF04E166D65FA0042CDCE /* piddiskrep.h */,
                        );
                        name = "Disk Representations";
                        sourceTree = "<group>";
                        );
                        name = "Disk Representations";
                        sourceTree = "<group>";
                                C200424915D425B7004AE0A1 /* libsecurity_codesigning.a */,
                                C200424A15D425B7004AE0A1 /* libsecurity_utilities.a */,
                                C2CC30A00B8519CC005FA59D /* CoreFoundation.framework */,
                                C200424915D425B7004AE0A1 /* libsecurity_codesigning.a */,
                                C200424A15D425B7004AE0A1 /* libsecurity_utilities.a */,
                                C2CC30A00B8519CC005FA59D /* CoreFoundation.framework */,
+                               EBB9FF701682E51300FF9774 /* Foundation.framework */,
                        );
                        name = Frameworks;
                        path = /System/Library/Frameworks;
                        );
                        name = Frameworks;
                        path = /System/Library/Frameworks;
                                C2E911E00ADEBE3200275CB2 /* resources.cpp */,
                                C259DFD50AD6D9BA00C9ACC6 /* sigblob.h */,
                                C259DFD40AD6D9BA00C9ACC6 /* sigblob.cpp */,
                                C2E911E00ADEBE3200275CB2 /* resources.cpp */,
                                C259DFD50AD6D9BA00C9ACC6 /* sigblob.h */,
                                C259DFD40AD6D9BA00C9ACC6 /* sigblob.cpp */,
-                               C2EF100F0A49BD89005A44BB /* renum.h */,
-                               C2EF100E0A49BD89005A44BB /* renum.cpp */,
                                C2A976A90B8A2E36008B4EA0 /* csutilities.h */,
                                C2A976A80B8A2E36008B4EA0 /* csutilities.cpp */,
                                C235340E145F1B050073F964 /* xar++.h */,
                                C2A976A90B8A2E36008B4EA0 /* csutilities.h */,
                                C2A976A80B8A2E36008B4EA0 /* csutilities.cpp */,
                                C235340E145F1B050073F964 /* xar++.h */,
                        path = cstemp;
                        sourceTree = BUILT_PRODUCTS_DIR;
                };
                        path = cstemp;
                        sourceTree = BUILT_PRODUCTS_DIR;
                };
+               EB976F511684D73900A68EE6 /* antlr2 */ = {
+                       isa = PBXGroup;
+                       children = (
+                               EB976F561684D77500A68EE6 /* antlr */,
+                               EB976F8A1684D77500A68EE6 /* AUTHORS */,
+                               EB976F8B1684D77500A68EE6 /* ChangeLog */,
+                               EB976F8C1684D77500A68EE6 /* contrib */,
+                               EB976F911684D77500A68EE6 /* doxygen.cfg */,
+                               EBF9A1551684E0F300BCECA6 /* libsecurity_codesigning.plist */,
+                               EBF9A1561684E0F300BCECA6 /* libsecurity_codesigning.txt */,
+                               EBF9A1571684E0F300BCECA6 /* LICENSE.txt */,
+                               EB976F921684D77500A68EE6 /* Makefile.in */,
+                               EB976F931684D77500A68EE6 /* README */,
+                               EB976F941684D77500A68EE6 /* scripts */,
+                               EB976F971684D77600A68EE6 /* src */,
+                               EB976FB71684D77600A68EE6 /* TODO */,
+                       );
+                       name = antlr2;
+                       sourceTree = "<group>";
+               };
+               EB976F561684D77500A68EE6 /* antlr */ = {
+                       isa = PBXGroup;
+                       children = (
+                               EB976F571684D77500A68EE6 /* ANTLRException.hpp */,
+                               EB976F581684D77500A68EE6 /* ANTLRUtil.hpp */,
+                               EB976F591684D77500A68EE6 /* AST.hpp */,
+                               EB976F5A1684D77500A68EE6 /* ASTArray.hpp */,
+                               EB976F5B1684D77500A68EE6 /* ASTFactory.hpp */,
+                               EB976F5C1684D77500A68EE6 /* ASTNULLType.hpp */,
+                               EB976F5D1684D77500A68EE6 /* ASTPair.hpp */,
+                               EB976F5E1684D77500A68EE6 /* ASTRefCount.hpp */,
+                               EB976F5F1684D77500A68EE6 /* BaseAST.hpp */,
+                               EB976F601684D77500A68EE6 /* BitSet.hpp */,
+                               EB976F611684D77500A68EE6 /* CharBuffer.hpp */,
+                               EB976F621684D77500A68EE6 /* CharInputBuffer.hpp */,
+                               EB976F631684D77500A68EE6 /* CharScanner.hpp */,
+                               EB976F641684D77500A68EE6 /* CharStreamException.hpp */,
+                               EB976F651684D77500A68EE6 /* CharStreamIOException.hpp */,
+                               EB976F661684D77500A68EE6 /* CircularQueue.hpp */,
+                               EB976F671684D77500A68EE6 /* CommonAST.hpp */,
+                               EB976F681684D77500A68EE6 /* CommonASTWithHiddenTokens.hpp */,
+                               EB976F691684D77500A68EE6 /* CommonHiddenStreamToken.hpp */,
+                               EB976F6A1684D77500A68EE6 /* CommonToken.hpp */,
+                               EB976F6B1684D77500A68EE6 /* config.hpp */,
+                               EB976F6C1684D77500A68EE6 /* InputBuffer.hpp */,
+                               EB976F6D1684D77500A68EE6 /* IOException.hpp */,
+                               EB976F6E1684D77500A68EE6 /* LexerSharedInputState.hpp */,
+                               EB976F6F1684D77500A68EE6 /* LLkParser.hpp */,
+                               EB976F701684D77500A68EE6 /* Makefile.in */,
+                               EB976F711684D77500A68EE6 /* MismatchedCharException.hpp */,
+                               EB976F721684D77500A68EE6 /* MismatchedTokenException.hpp */,
+                               EB976F731684D77500A68EE6 /* NoViableAltException.hpp */,
+                               EB976F741684D77500A68EE6 /* NoViableAltForCharException.hpp */,
+                               EB976F751684D77500A68EE6 /* Parser.hpp */,
+                               EB976F761684D77500A68EE6 /* ParserSharedInputState.hpp */,
+                               EB976F771684D77500A68EE6 /* RecognitionException.hpp */,
+                               EB976F781684D77500A68EE6 /* RefCount.hpp */,
+                               EB976F791684D77500A68EE6 /* SemanticException.hpp */,
+                               EB976F7A1684D77500A68EE6 /* String.hpp */,
+                               EB976F7B1684D77500A68EE6 /* Token.hpp */,
+                               EB976F7C1684D77500A68EE6 /* TokenBuffer.hpp */,
+                               EB976F7D1684D77500A68EE6 /* TokenRefCount.hpp */,
+                               EB976F7E1684D77500A68EE6 /* TokenStream.hpp */,
+                               EB976F7F1684D77500A68EE6 /* TokenStreamBasicFilter.hpp */,
+                               EB976F801684D77500A68EE6 /* TokenStreamException.hpp */,
+                               EB976F811684D77500A68EE6 /* TokenStreamHiddenTokenFilter.hpp */,
+                               EB976F821684D77500A68EE6 /* TokenStreamIOException.hpp */,
+                               EB976F831684D77500A68EE6 /* TokenStreamRecognitionException.hpp */,
+                               EB976F841684D77500A68EE6 /* TokenStreamRetryException.hpp */,
+                               EB976F851684D77500A68EE6 /* TokenStreamRewriteEngine.hpp */,
+                               EB976F861684D77500A68EE6 /* TokenStreamSelector.hpp */,
+                               EB976F871684D77500A68EE6 /* TokenWithIndex.hpp */,
+                               EB976F881684D77500A68EE6 /* TreeParser.hpp */,
+                               EB976F891684D77500A68EE6 /* TreeParserSharedInputState.hpp */,
+                       );
+                       name = antlr;
+                       path = antlr2/antlr;
+                       sourceTree = "<group>";
+               };
+               EB976F8C1684D77500A68EE6 /* contrib */ = {
+                       isa = PBXGroup;
+                       children = (
+                               EB976F8D1684D77500A68EE6 /* bcb4 */,
+                       );
+                       name = contrib;
+                       path = antlr2/contrib;
+                       sourceTree = "<group>";
+               };
+               EB976F8D1684D77500A68EE6 /* bcb4 */ = {
+                       isa = PBXGroup;
+                       children = (
+                               EB976F8E1684D77500A68EE6 /* antlr.bpr */,
+                               EB976F8F1684D77500A68EE6 /* antlr.cpp */,
+                               EB976F901684D77500A68EE6 /* README */,
+                       );
+                       path = bcb4;
+                       sourceTree = "<group>";
+               };
+               EB976F941684D77500A68EE6 /* scripts */ = {
+                       isa = PBXGroup;
+                       children = (
+                               EB976F951684D77500A68EE6 /* cr_stripper.sh */,
+                               EB976F961684D77500A68EE6 /* make_change_log.tcl */,
+                       );
+                       name = scripts;
+                       path = antlr2/scripts;
+                       sourceTree = "<group>";
+               };
+               EB976F971684D77600A68EE6 /* src */ = {
+                       isa = PBXGroup;
+                       children = (
+                               EB976F981684D77600A68EE6 /* ANTLRUtil.cpp */,
+                               EB976F991684D77600A68EE6 /* ASTFactory.cpp */,
+                               EB976F9A1684D77600A68EE6 /* ASTNULLType.cpp */,
+                               EB976F9B1684D77600A68EE6 /* ASTRefCount.cpp */,
+                               EB976F9C1684D77600A68EE6 /* BaseAST.cpp */,
+                               EB976F9D1684D77600A68EE6 /* BitSet.cpp */,
+                               EB976F9E1684D77600A68EE6 /* CharBuffer.cpp */,
+                               EB976F9F1684D77600A68EE6 /* CharScanner.cpp */,
+                               EB976FA01684D77600A68EE6 /* CommonAST.cpp */,
+                               EB976FA11684D77600A68EE6 /* CommonASTWithHiddenTokens.cpp */,
+                               EB976FA21684D77600A68EE6 /* CommonHiddenStreamToken.cpp */,
+                               EB976FA31684D77600A68EE6 /* CommonToken.cpp */,
+                               EB976FA41684D77600A68EE6 /* dll.cpp */,
+                               EB976FA51684D77600A68EE6 /* InputBuffer.cpp */,
+                               EB976FA61684D77600A68EE6 /* LLkParser.cpp */,
+                               EB976FA71684D77600A68EE6 /* Makefile.in */,
+                               EB976FA81684D77600A68EE6 /* MismatchedCharException.cpp */,
+                               EB976FA91684D77600A68EE6 /* MismatchedTokenException.cpp */,
+                               EB976FAA1684D77600A68EE6 /* NoViableAltException.cpp */,
+                               EB976FAB1684D77600A68EE6 /* NoViableAltForCharException.cpp */,
+                               EB976FAC1684D77600A68EE6 /* Parser.cpp */,
+                               EB976FAD1684D77600A68EE6 /* RecognitionException.cpp */,
+                               EB976FAE1684D77600A68EE6 /* String.cpp */,
+                               EB976FAF1684D77600A68EE6 /* Token.cpp */,
+                               EB976FB01684D77600A68EE6 /* TokenBuffer.cpp */,
+                               EB976FB11684D77600A68EE6 /* TokenRefCount.cpp */,
+                               EB976FB21684D77600A68EE6 /* TokenStreamBasicFilter.cpp */,
+                               EB976FB31684D77600A68EE6 /* TokenStreamHiddenTokenFilter.cpp */,
+                               EB976FB41684D77600A68EE6 /* TokenStreamRewriteEngine.cpp */,
+                               EB976FB51684D77600A68EE6 /* TokenStreamSelector.cpp */,
+                               EB976FB61684D77600A68EE6 /* TreeParser.cpp */,
+                       );
+                       name = src;
+                       path = antlr2/src;
+                       sourceTree = "<group>";
+               };
+               EBB9FF721682E51300FF9774 /* CodeSigningHelper */ = {
+                       isa = PBXGroup;
+                       children = (
+                               EBB9FF791682E51300FF9774 /* main.c */,
+                               EBB9FF801682E65700FF9774 /* com.apple.CodeSigningHelper.sb */,
+                               EBB9FF731682E51300FF9774 /* Supporting Files */,
+                       );
+                       path = CodeSigningHelper;
+                       sourceTree = "<group>";
+               };
+               EBB9FF731682E51300FF9774 /* Supporting Files */ = {
+                       isa = PBXGroup;
+                       children = (
+                               EBB9FF741682E51300FF9774 /* CodeSigningHelper-Info.plist */,
+                       );
+                       name = "Supporting Files";
+                       sourceTree = "<group>";
+               };
                FEB30C9110DAC6C400557BA2 /* Entitlements */ = {
                        isa = PBXGroup;
                        children = (
                                FEB30C9410DAC8A500557BA2 /* SecTask.h */,
                FEB30C9110DAC6C400557BA2 /* Entitlements */ = {
                        isa = PBXGroup;
                        children = (
                                FEB30C9410DAC8A500557BA2 /* SecTask.h */,
+                               BEC3A75B16F78D21003E5634 /* SecTaskPriv.h */,
                                FEB30C9210DAC89D00557BA2 /* SecTask.c */,
                        );
                        name = Entitlements;
                                FEB30C9210DAC89D00557BA2 /* SecTask.c */,
                        );
                        name = Entitlements;
                                18B9658B1472FC5B005A4D2E /* reqparser.h in Headers */,
                                18B9658C1472FC9E005A4D2E /* codedirectory.h in Headers */,
                                18B965951472FE30005A4D2E /* cdbuilder.h in Headers */,
                                18B9658B1472FC5B005A4D2E /* reqparser.h in Headers */,
                                18B9658C1472FC9E005A4D2E /* codedirectory.h in Headers */,
                                18B965951472FE30005A4D2E /* cdbuilder.h in Headers */,
-                               18B965941472FE27005A4D2E /* renum.h in Headers */,
                                EB68B133150DB04400B4013D /* RequirementKeywords.h in Headers */,
                                EB68B133150DB04400B4013D /* RequirementKeywords.h in Headers */,
+                               BEC3A75C16F78D21003E5634 /* SecTaskPriv.h in Headers */,
                                EB68B134150DB04400B4013D /* RequirementLexer.hpp in Headers */,
                                EB68B135150DB04400B4013D /* RequirementParser.hpp in Headers */,
                                FEB30CA410DAC97400557BA2 /* SecTask.h in Headers */,
                                EB68B134150DB04400B4013D /* RequirementLexer.hpp in Headers */,
                                EB68B135150DB04400B4013D /* RequirementParser.hpp in Headers */,
                                FEB30CA410DAC97400557BA2 /* SecTask.h in Headers */,
                                C24EABAB1421432800C16AA9 /* policydb.h in Headers */,
                                C2F4439B14C626D4000A01E6 /* quarantine++.h in Headers */,
                                C26763D814FD9EBE00A46EDF /* drmaker.h in Headers */,
                                C24EABAB1421432800C16AA9 /* policydb.h in Headers */,
                                C2F4439B14C626D4000A01E6 /* quarantine++.h in Headers */,
                                C26763D814FD9EBE00A46EDF /* drmaker.h in Headers */,
+                               EBDAF050166D65FA0042CDCE /* piddiskrep.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                4CA1FEBA052A3C8100F22E42 /* Sources */,
                                4CA1FEBB052A3C8100F22E42 /* Frameworks */,
                                1865FFD5147517A300FD79DF /* ShellScript */,
                                4CA1FEBA052A3C8100F22E42 /* Sources */,
                                4CA1FEBB052A3C8100F22E42 /* Frameworks */,
                                1865FFD5147517A300FD79DF /* ShellScript */,
+                               EBF9A1501684E0DF00BCECA6 /* Copy OpenSourceVersions */,
+                               EBF9A1591684E12C00BCECA6 /* OpenSourceLicenses */,
                        );
                        buildRules = (
                        );
                        );
                        buildRules = (
                        );
                        productReference = C2BC1F2F0B580D4B003EC9DC /* libcodehost.a */;
                        productType = "com.apple.product-type.library.static";
                };
                        productReference = C2BC1F2F0B580D4B003EC9DC /* libcodehost.a */;
                        productType = "com.apple.product-type.library.static";
                };
+               EBB9FF6E1682E51300FF9774 /* CodeSigningHelper */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = EBB9FF7B1682E51300FF9774 /* Build configuration list for PBXNativeTarget "CodeSigningHelper" */;
+                       buildPhases = (
+                               EBB9FF6B1682E51300FF9774 /* Sources */,
+                               EBB9FF6C1682E51300FF9774 /* Frameworks */,
+                               EBB9FFE11682E80A00FF9774 /* CopyFiles */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = CodeSigningHelper;
+                       productName = CodeSigningHelper;
+                       productReference = EBB9FF6F1682E51300FF9774 /* com.apple.CodeSigningHelper.xpc */;
+                       productType = "com.apple.product-type.bundle";
+               };
 /* End PBXNativeTarget section */
 
 /* Begin PBXProject section */
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
 /* End PBXNativeTarget section */
 
 /* Begin PBXProject section */
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0420;
+                               LastUpgradeCheck = 0500;
                        };
                        buildConfigurationList = C263E67909A2971B000043F1 /* Build configuration list for PBXProject "libsecurity_codesigning" */;
                        compatibilityVersion = "Xcode 3.2";
                        };
                        buildConfigurationList = C263E67909A2971B000043F1 /* Build configuration list for PBXProject "libsecurity_codesigning" */;
                        compatibilityVersion = "Xcode 3.2";
                                Japanese,
                                French,
                                German,
                                Japanese,
                                French,
                                German,
+                               en,
                        );
                        mainGroup = 4CA1FEA7052A3C3800F22E42;
                        productRefGroup = 4CA1FEBF052A3C8100F22E42 /* Products */;
                        );
                        mainGroup = 4CA1FEA7052A3C3800F22E42;
                        productRefGroup = 4CA1FEBF052A3C8100F22E42 /* Products */;
                                C26AC7090DAEB3A7005BFB40 /* DTrace */,
                                C26AC0EB143BCF01001C98CE /* SystemPolicy */,
                                C209695F15BF52040093035F /* gkunpack */,
                                C26AC7090DAEB3A7005BFB40 /* DTrace */,
                                C26AC0EB143BCF01001C98CE /* SystemPolicy */,
                                C209695F15BF52040093035F /* gkunpack */,
+                               EBB9FF6E1682E51300FF9774 /* CodeSigningHelper */,
                        );
                };
 /* End PBXProject section */
                        );
                };
 /* End PBXProject section */
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        shellPath = /bin/bash;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        shellPath = /bin/bash;
-                       shellScript = "antlr=/usr/local/bin/antlr.jar\nDEBUG=\"\"\nmkdir -p $SRCROOT/lib\nrm -f $SRCROOT/lib/Requirement{Parser,Lexer}*\njava -cp \"$antlr\" antlr.Tool -o $SRCROOT/lib $DEBUG requirements.grammar\nsed -n 's/^.*=\\(\".*\"\\)=.*$/        \\1,/p' $SRCROOT/lib/RequirementParserTokenTypes.txt >$SRCROOT/lib/RequirementKeywords.h\n";
+                       shellScript = "antlr=$SRCROOT/antlr2/antlr.jar\nDEBUG=\"\"\nmkdir -p $SRCROOT/lib\nrm -f $SRCROOT/lib/Requirement{Parser,Lexer}*\njava -cp \"$antlr\" antlr.Tool -o $SRCROOT/lib $DEBUG requirements.grammar\nsed -n 's/^.*=\\(\".*\"\\)=.*$/        \\1,/p' $SRCROOT/lib/RequirementParserTokenTypes.txt >$SRCROOT/lib/RequirementKeywords.h\n";
                };
                C2F24DFE14BCBBF200309FCD /* ShellScript */ = {
                        isa = PBXShellScriptBuildPhase;
                };
                C2F24DFE14BCBBF200309FCD /* ShellScript */ = {
                        isa = PBXShellScriptBuildPhase;
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               EB976FB81684D7C500A68EE6 /* ANTLRUtil.cpp in Sources */,
+                               EB976FB91684D7C500A68EE6 /* ASTFactory.cpp in Sources */,
+                               EB976FBA1684D7C500A68EE6 /* ASTNULLType.cpp in Sources */,
+                               EB976FBB1684D7C500A68EE6 /* ASTRefCount.cpp in Sources */,
+                               EB976FBC1684D7C500A68EE6 /* BaseAST.cpp in Sources */,
+                               EB976FBD1684D7C500A68EE6 /* BitSet.cpp in Sources */,
+                               EB976FBE1684D7C500A68EE6 /* CharBuffer.cpp in Sources */,
+                               EB976FBF1684D7C500A68EE6 /* CharScanner.cpp in Sources */,
+                               EB976FC01684D7C500A68EE6 /* CommonAST.cpp in Sources */,
+                               EB976FC11684D7C500A68EE6 /* CommonASTWithHiddenTokens.cpp in Sources */,
+                               EB976FC21684D7C500A68EE6 /* CommonHiddenStreamToken.cpp in Sources */,
+                               EB976FC31684D7C500A68EE6 /* CommonToken.cpp in Sources */,
+                               EB976FC41684D7C500A68EE6 /* InputBuffer.cpp in Sources */,
+                               EB976FC51684D7C500A68EE6 /* LLkParser.cpp in Sources */,
+                               EB976FC61684D7C500A68EE6 /* MismatchedCharException.cpp in Sources */,
+                               EB976FC71684D7C500A68EE6 /* MismatchedTokenException.cpp in Sources */,
+                               EB976FC81684D7C500A68EE6 /* NoViableAltException.cpp in Sources */,
+                               EB976FC91684D7C500A68EE6 /* NoViableAltForCharException.cpp in Sources */,
+                               EB976FCA1684D7C500A68EE6 /* Parser.cpp in Sources */,
+                               EB976FCB1684D7C500A68EE6 /* RecognitionException.cpp in Sources */,
+                               EB976FCC1684D7C500A68EE6 /* String.cpp in Sources */,
+                               EB976FCD1684D7C500A68EE6 /* Token.cpp in Sources */,
+                               EB976FCE1684D7C500A68EE6 /* TokenBuffer.cpp in Sources */,
+                               EB976FCF1684D7C500A68EE6 /* TokenRefCount.cpp in Sources */,
+                               EB976FD01684D7C500A68EE6 /* TokenStreamBasicFilter.cpp in Sources */,
+                               EB976FD11684D7C500A68EE6 /* TokenStreamHiddenTokenFilter.cpp in Sources */,
+                               EB976FD21684D7C500A68EE6 /* TokenStreamRewriteEngine.cpp in Sources */,
+                               EB976FD31684D7C500A68EE6 /* TokenStreamSelector.cpp in Sources */,
+                               EB976FD41684D7C500A68EE6 /* TreeParser.cpp in Sources */,
                                C2D3833C0A237F47005C63A2 /* bundlediskrep.cpp in Sources */,
                                C2D3833E0A237F47005C63A2 /* cdbuilder.cpp in Sources */,
                                C2D383400A237F47005C63A2 /* codedirectory.cpp in Sources */,
                                C2D3833C0A237F47005C63A2 /* bundlediskrep.cpp in Sources */,
                                C2D3833E0A237F47005C63A2 /* cdbuilder.cpp in Sources */,
                                C2D383400A237F47005C63A2 /* codedirectory.cpp in Sources */,
                                C2C1DFBB0A2F80EB00D1B02B /* reqinterp.cpp in Sources */,
                                C2C1DFC30A2F820500D1B02B /* reqmaker.cpp in Sources */,
                                C22463610B86210100626F1B /* antlrplugin.cpp in Sources */,
                                C2C1DFBB0A2F80EB00D1B02B /* reqinterp.cpp in Sources */,
                                C2C1DFC30A2F820500D1B02B /* reqmaker.cpp in Sources */,
                                C22463610B86210100626F1B /* antlrplugin.cpp in Sources */,
-                               C2EF10100A49BD89005A44BB /* renum.cpp in Sources */,
                                C2BD519C0A9392FD000FE43D /* machorep.cpp in Sources */,
                                C2C931B40AB8BA1200F83950 /* SecCodeHost.cpp in Sources */,
                                C2BD60FA0AC863FC0057FD3D /* csgeneric.cpp in Sources */,
                                C2BD519C0A9392FD000FE43D /* machorep.cpp in Sources */,
                                C2C931B40AB8BA1200F83950 /* SecCodeHost.cpp in Sources */,
                                C2BD60FA0AC863FC0057FD3D /* csgeneric.cpp in Sources */,
                                C26763D714FD9EBE00A46EDF /* drmaker.cpp in Sources */,
                                EB68B111150DAEEA00B4013D /* RequirementLexer.cpp in Sources */,
                                EB68B112150DAEEA00B4013D /* RequirementParser.cpp in Sources */,
                                C26763D714FD9EBE00A46EDF /* drmaker.cpp in Sources */,
                                EB68B111150DAEEA00B4013D /* RequirementLexer.cpp in Sources */,
                                EB68B112150DAEEA00B4013D /* RequirementParser.cpp in Sources */,
+                               EBDAF04F166D65FA0042CDCE /* piddiskrep.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               EBB9FF6B1682E51300FF9774 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               EBB9FF7A1682E51300FF9774 /* main.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
 /* End PBXSourcesBuildPhase section */
 
 /* Begin PBXTargetDependency section */
 /* End PBXSourcesBuildPhase section */
 
 /* Begin PBXTargetDependency section */
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNINITIALIZED_AUTOS = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNINITIALIZED_AUTOS = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
-                               MACOSX_DEPLOYMENT_TARGET = 10.8;
                                ONLY_ACTIVE_ARCH = YES;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                                SKIP_INSTALL = NO;
                                ONLY_ACTIVE_ARCH = YES;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                                SKIP_INSTALL = NO;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNINITIALIZED_AUTOS = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNINITIALIZED_AUTOS = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
-                               MACOSX_DEPLOYMENT_TARGET = 10.8;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                                SKIP_INSTALL = NO;
                        };
                                PRODUCT_NAME = "$(TARGET_NAME)";
                                SKIP_INSTALL = NO;
                        };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 184461A0146E9AD100B12992 /* debug.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 184461A0146E9AD100B12992 /* debug.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                               COPY_PHASE_STRIP = NO;
                                HEADER_SEARCH_PATHS = (
                                HEADER_SEARCH_PATHS = (
+                                       "$(PROJECT_DIR)/antlr2",
                                        "$(inherited)",
                                        "$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders",
                                );
                                        "$(inherited)",
                                        "$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders",
                                );
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 184461A2146E9AD100B12992 /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 184461A2146E9AD100B12992 /* release.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                               COPY_PHASE_STRIP = NO;
                                HEADER_SEARCH_PATHS = (
                                HEADER_SEARCH_PATHS = (
+                                       "$(PROJECT_DIR)/antlr2",
                                        "$(inherited)",
                                        "$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders",
                                );
                                        "$(inherited)",
                                        "$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders",
                                );
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 184461A1146E9AD100B12992 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 184461A1146E9AD100B12992 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                                HEADER_SEARCH_PATHS = (
                                        "$(PROJECT_DIR)/../include",
                                        "$(BUILT_PRODUCTS_DIR)/derived_src",
                                HEADER_SEARCH_PATHS = (
                                        "$(PROJECT_DIR)/../include",
                                        "$(BUILT_PRODUCTS_DIR)/derived_src",
                                        /usr/local/include,
                                );
                                TEMPDIR = "$(BUILT_PRODUCTS_DIR)/cstemp";
                                        /usr/local/include,
                                );
                                TEMPDIR = "$(BUILT_PRODUCTS_DIR)/cstemp";
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                                       "$(inherited)",
+                               );
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 184461A1146E9AD100B12992 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 184461A1146E9AD100B12992 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                                HEADER_SEARCH_PATHS = (
                                        "$(PROJECT_DIR)/../include",
                                        "$(BUILT_PRODUCTS_DIR)/derived_src",
                                HEADER_SEARCH_PATHS = (
                                        "$(PROJECT_DIR)/../include",
                                        "$(BUILT_PRODUCTS_DIR)/derived_src",
                                        /usr/local/include,
                                );
                                TEMPDIR = "$(BUILT_PRODUCTS_DIR)/cstemp";
                                        /usr/local/include,
                                );
                                TEMPDIR = "$(BUILT_PRODUCTS_DIR)/cstemp";
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                                       "$(inherited)",
+                               );
                        };
                        name = Release;
                };
                C26AC0ED143BCF01001C98CE /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                        };
                        name = Release;
                };
                C26AC0ED143BCF01001C98CE /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                        };
                        name = Debug;
                };
                C26AC0EF143BCF01001C98CE /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                        };
                        name = Debug;
                };
                C26AC0EF143BCF01001C98CE /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                        };
                        name = Release;
                };
                C26AC70A0DAEB3A8005BFB40 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                        };
                        name = Release;
                };
                C26AC70A0DAEB3A8005BFB40 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                        };
                        name = Debug;
                };
                C26AC70C0DAEB3A8005BFB40 /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                        };
                        name = Debug;
                };
                C26AC70C0DAEB3A8005BFB40 /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 184461A0146E9AD100B12992 /* debug.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 184461A0146E9AD100B12992 /* debug.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                SKIP_INSTALL = NO;
                        };
                        name = Debug;
                                SKIP_INSTALL = NO;
                        };
                        name = Debug;
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 184461A2146E9AD100B12992 /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 184461A2146E9AD100B12992 /* release.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                SKIP_INSTALL = NO;
                        };
                        name = Release;
                                SKIP_INSTALL = NO;
                        };
                        name = Release;
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 184461A0146E9AD100B12992 /* debug.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 184461A0146E9AD100B12992 /* debug.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                SKIP_INSTALL = NO;
                        };
                        name = Debug;
                                SKIP_INSTALL = NO;
                        };
                        name = Debug;
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 184461A2146E9AD100B12992 /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 184461A2146E9AD100B12992 /* release.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                SKIP_INSTALL = NO;
                        };
                        name = Release;
                                SKIP_INSTALL = NO;
                        };
                        name = Release;
                C2D383C10A23A8E3005C63A2 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                C2D383C10A23A8E3005C63A2 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                        };
                        name = Debug;
                };
                C2D383C30A23A8E3005C63A2 /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                        };
                        name = Debug;
                };
                C2D383C30A23A8E3005C63A2 /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                        };
                        name = Release;
                };
                C2E287480B5D8FD8009336A0 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                        };
                        name = Release;
                };
                C2E287480B5D8FD8009336A0 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                HEADER_SEARCH_PATHS = (
                                        "$(PROJECT_DIR)/../include",
                                        "$(BUILT_PRODUCTS_DIR)/derived_src",
                                HEADER_SEARCH_PATHS = (
                                        "$(PROJECT_DIR)/../include",
                                        "$(BUILT_PRODUCTS_DIR)/derived_src",
                C2E2874A0B5D8FD8009336A0 /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                C2E2874A0B5D8FD8009336A0 /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                HEADER_SEARCH_PATHS = (
                                        "$(PROJECT_DIR)/../include",
                                        "$(BUILT_PRODUCTS_DIR)/derived_src",
                                HEADER_SEARCH_PATHS = (
                                        "$(PROJECT_DIR)/../include",
                                        "$(BUILT_PRODUCTS_DIR)/derived_src",
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
+               EBB9FF7C1682E51300FF9774 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+                               CLANG_CXX_LIBRARY = "libc++";
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               COMBINE_HIDPI_IMAGES = YES;
+                               COPY_PHASE_STRIP = NO;
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "DEBUG=1",
+                                       "$(inherited)",
+                               );
+                               GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               INFOPLIST_FILE = "CodeSigningHelper/CodeSigningHelper-Info.plist";
+                               INSTALL_PATH = /System/Library/Frameworks/Security.framework/Versions/A/XPCServices;
+                               MACH_O_TYPE = mh_execute;
+                               ONLY_ACTIVE_ARCH = YES;
+                               PRODUCT_NAME = "com.apple.$(TARGET_NAME:rfc1034identifier)";
+                               SKIP_INSTALL = NO;
+                               WRAPPER_EXTENSION = xpc;
+                       };
+                       name = Debug;
+               };
+               EBB9FF7D1682E51300FF9774 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+                               CLANG_CXX_LIBRARY = "libc++";
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               COMBINE_HIDPI_IMAGES = YES;
+                               COPY_PHASE_STRIP = YES;
+                               DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               INFOPLIST_FILE = "CodeSigningHelper/CodeSigningHelper-Info.plist";
+                               INSTALL_PATH = /System/Library/Frameworks/Security.framework/Versions/A/XPCServices;
+                               MACH_O_TYPE = mh_execute;
+                               PRODUCT_NAME = "com.apple.$(TARGET_NAME:rfc1034identifier)";
+                               SKIP_INSTALL = NO;
+                               WRAPPER_EXTENSION = xpc;
+                       };
+                       name = Release;
+               };
 /* End XCBuildConfiguration section */
 
 /* Begin XCConfigurationList section */
 /* End XCBuildConfiguration section */
 
 /* Begin XCConfigurationList section */
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
+               EBB9FF7B1682E51300FF9774 /* Build configuration list for PBXNativeTarget "CodeSigningHelper" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               EBB9FF7C1682E51300FF9774 /* Debug */,
+                               EBB9FF7D1682E51300FF9774 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
 /* End XCConfigurationList section */
        };
        rootObject = 4CA1FEAB052A3C3800F22E42 /* Project object */;
 /* End XCConfigurationList section */
        };
        rootObject = 4CA1FEAB052A3C3800F22E42 /* Project object */;
index 56e9b5ac5d12e4535c0892177bc6a5daa65e189b..b584235e280906d93e99ce69ad7f3eee2e28d9a9 100644 (file)
@@ -495,16 +495,16 @@ void *ascMalloc(unsigned size)
        #ifdef  macintosh
 
        h = nil;
        #ifdef  macintosh
 
        h = nil;
-       err = noErr;
+       err = errSecSuccess;
 
        h = NewHandleSys(size);         // system heap is not paged
        do{
                HLockHi(h);                     // will move low in system heap
                err = MemError();
 
        h = NewHandleSys(size);         // system heap is not paged
        do{
                HLockHi(h);                     // will move low in system heap
                err = MemError();
-               if( err != noErr ) break;
+               if( err != errSecSuccess ) break;
                p = *h;
        }while(0);
                p = *h;
        }while(0);
-       if( err != noErr ){
+       if( err != errSecSuccess ){
            return NULL;
        }
        return p;
            return NULL;
        }
        return p;
index 23ae85afcecd7ecab693bbe7f58c81a3650f4dc5..56d89b60d7c1ec9bb5ebaa92fd946fa142c4f727 100644 (file)
@@ -58,7 +58,7 @@ void comMallocRegister(comMallocExternFcn *mallocExtern,
  * Call once at startup. The resulting comcryptObj can be reused multiple
  * times.
  */
  * Call once at startup. The resulting comcryptObj can be reused multiple
  * times.
  */
-comcryptObj comcryptAlloc()
+comcryptObj comcryptAlloc(void)
 {
        comcryptPriv    *cpriv = (comcryptPriv *) ascMalloc(sizeof(comcryptPriv));
 
 {
        comcryptPriv    *cpriv = (comcryptPriv *) ascMalloc(sizeof(comcryptPriv));
 
@@ -750,7 +750,7 @@ static comcryptReturn comcryptBlock(
         * We already wrote tokens and longcode to cipherText; verify we
         * didn't overrun
         */
         * We already wrote tokens and longcode to cipherText; verify we
         * didn't overrun
         */
-       totalCipherTextLen = (longCodePtr - startCtextPtr);
+       totalCipherTextLen = (unsigned)(longCodePtr - startCtextPtr);
        if(*cipherTextLen < totalCipherTextLen) {
                ddprintf(("comcryptBlock: short block (2)\n"));
                return CCR_OUTBUFFER_TOO_SMALL;
        if(*cipherTextLen < totalCipherTextLen) {
                ddprintf(("comcryptBlock: short block (2)\n"));
                return CCR_OUTBUFFER_TOO_SMALL;
@@ -1030,7 +1030,7 @@ static dcbReturn deComcryptBlock(
                numByteCodes = *byteCodePtr++;
                level2 = 1;
        }
                numByteCodes = *byteCodePtr++;
                level2 = 1;
        }
-       *blockSize = (byteCodePtr - cipherText) + numByteCodes;
+       *blockSize = (unsigned)(byteCodePtr - cipherText) + numByteCodes;
        if(*blockSize > cipherTextLen) {
                return DCB_SHORT;
        }
        if(*blockSize > cipherTextLen) {
                return DCB_SHORT;
        }
@@ -1439,6 +1439,6 @@ comcryptReturn deComcryptData(
                }
        }       /* main loop */
 
                }
        }       /* main loop */
 
-       *plainTextLen = plainText - outorigin;
+       *plainTextLen = (unsigned)(plainText - outorigin);
        return CCR_SUCCESS;
 }
        return CCR_SUCCESS;
 }
index 18dd646565aabf6e9599f21a809de2c4efe7af87..fefff98c1ca18a5fd4f97dc058edf6bc0e127946 100644 (file)
@@ -91,7 +91,7 @@ typedef void *comcryptObj;
  * Call once at startup. The resulting comcryptObj can be reused multiple
  * times.
  */
  * Call once at startup. The resulting comcryptObj can be reused multiple
  * times.
  */
-comcryptObj comcryptAlloc();
+comcryptObj comcryptAlloc(void);
 
 /*
  * Use this before starting every stream process
 
 /*
  * Use this before starting every stream process
index 079de5b3f7cecca01daac02a761a530bfac39418..bf1bb334742da1c30b9904897b8204385e8e27a5 100644 (file)
@@ -192,7 +192,7 @@ static giant cssmDataToGiant(
        const CSSM_DATA         &cdata)
 {
        char *rawOcts = (char *)cdata.Data;
        const CSSM_DATA         &cdata)
 {
        char *rawOcts = (char *)cdata.Data;
-       unsigned numBytes = cdata.Length;
+       unsigned numBytes = (unsigned)cdata.Length;
        unsigned numGiantDigits;
        int sign = 1;
        giant grtn;
        unsigned numGiantDigits;
        int sign = 1;
        giant grtn;
@@ -467,8 +467,8 @@ feeReturn feeDEREncodeElGamalSignature(
        }
 
        /* copy out  to caller */
        }
 
        /* copy out  to caller */
-       *encodedSig = (unsigned char *)fmalloc(encBlob.Length);
-       *encodedSigLen = encBlob.Length;
+       *encodedSig = (unsigned char *)fmalloc((unsigned)encBlob.Length);
+       *encodedSigLen = (unsigned)encBlob.Length;
        memmove(*encodedSig, encBlob.Data, encBlob.Length); 
        
        #if     PRINT_SIG_GIANTS
        memmove(*encodedSig, encBlob.Data, encBlob.Length); 
        
        #if     PRINT_SIG_GIANTS
@@ -507,8 +507,8 @@ feeReturn feeDEREncodeECDSASignature(
        }
 
        /* copy out  to caller */
        }
 
        /* copy out  to caller */
-       *encodedSig = (unsigned char *)fmalloc(encBlob.Length);
-       *encodedSigLen = encBlob.Length;
+       *encodedSig = (unsigned char *)fmalloc((unsigned)encBlob.Length);
+       *encodedSigLen = (unsigned)encBlob.Length;
        memmove(*encodedSig, encBlob.Data, encBlob.Length); 
        
        #if     PRINT_SIG_GIANTS
        memmove(*encodedSig, encBlob.Data, encBlob.Length); 
        
        #if     PRINT_SIG_GIANTS
@@ -630,8 +630,8 @@ feeReturn feeDEREncodePublicKey(
        }
 
        /* copy out */
        }
 
        /* copy out */
-       *keyBlob = (unsigned char *)fmalloc(encBlob.Length);
-       *keyBlobLen = encBlob.Length;
+       *keyBlob = (unsigned char *)fmalloc((unsigned)encBlob.Length);
+       *keyBlobLen = (unsigned)encBlob.Length;
        memmove(*keyBlob, encBlob.Data, encBlob.Length); 
        return FR_Success;
 }
        memmove(*keyBlob, encBlob.Data, encBlob.Length); 
        return FR_Success;
 }
@@ -666,8 +666,8 @@ feeReturn feeDEREncodePrivateKey(
        }
 
        /* copy out */
        }
 
        /* copy out */
-       *keyBlob = (unsigned char *)fmalloc(encBlob.Length);
-       *keyBlobLen = encBlob.Length;
+       *keyBlob = (unsigned char *)fmalloc((unsigned)encBlob.Length);
+       *keyBlobLen = (unsigned)encBlob.Length;
        memmove(*keyBlob, encBlob.Data, encBlob.Length); 
        return FR_Success;
 }
        memmove(*keyBlob, encBlob.Data, encBlob.Length); 
        return FR_Success;
 }
@@ -885,8 +885,8 @@ feeReturn feeDEREncodeX509PublicKey(
        }
 
        /* copy out */
        }
 
        /* copy out */
-       *x509Blob = (unsigned char *)fmalloc(encBlob.Length);
-       *x509BlobLen = encBlob.Length;
+       *x509Blob = (unsigned char *)fmalloc((unsigned)encBlob.Length);
+       *x509BlobLen = (unsigned)encBlob.Length;
        memmove(*x509Blob, encBlob.Data, encBlob.Length); 
        return FR_Success;
 }
        memmove(*x509Blob, encBlob.Data, encBlob.Length); 
        return FR_Success;
 }
@@ -918,7 +918,7 @@ feeReturn feeDERDecodeX509PublicKey(
        
        /* copy public key string - it's in bits here */
        CSSM_DATA *pubKey = &nssPubKeyInfo.subjectPublicKey;
        
        /* copy public key string - it's in bits here */
        CSSM_DATA *pubKey = &nssPubKeyInfo.subjectPublicKey;
-       unsigned keyLen = (pubKey->Length + 7) / 8;
+       unsigned keyLen =(unsigned) (pubKey->Length + 7) / 8;
        *pubBlob = (unsigned char *)fmalloc(keyLen);
        if(*pubBlob == NULL) {
                return FR_Memory;
        *pubBlob = (unsigned char *)fmalloc(keyLen);
        if(*pubBlob == NULL) {
                return FR_Memory;
@@ -988,8 +988,8 @@ feeReturn feeDEREncodeOpenSSLPrivateKey(
        }
 
        /* copy out */
        }
 
        /* copy out */
-       *openBlob = (unsigned char *)fmalloc(encPriv.Length);
-       *openBlobLen = encPriv.Length;
+       *openBlob = (unsigned char *)fmalloc((unsigned)encPriv.Length);
+       *openBlobLen = (unsigned)encPriv.Length;
        memmove(*openBlob, encPriv.Data, encPriv.Length); 
        return FR_Success;
 }
        memmove(*openBlob, encPriv.Data, encPriv.Length); 
        return FR_Success;
 }
@@ -1012,7 +1012,7 @@ feeReturn feeDERDecodeOpenSSLKey(
                return FR_BadKeyBlob;
        }
        
                return FR_BadKeyBlob;
        }
        
-       unsigned keyLen = ecdsaPrivKey.privateKey.Length;
+       unsigned keyLen = (unsigned)ecdsaPrivKey.privateKey.Length;
        if(keyLen == 0) {
                dbgLog(("NULL priv key data in PKCS8\n"));
        }
        if(keyLen == 0) {
                dbgLog(("NULL priv key data in PKCS8\n"));
        }
@@ -1039,7 +1039,7 @@ feeReturn feeDERDecodeOpenSSLKey(
 
        /* Public key, if it's there and caller wants it */
        if((ecdsaPrivKey.pubKey.Length != 0) && (pubBlob != NULL)) {
 
        /* Public key, if it's there and caller wants it */
        if((ecdsaPrivKey.pubKey.Length != 0) && (pubBlob != NULL)) {
-               *pubBlobLen = (ecdsaPrivKey.pubKey.Length + 7) / 8;
+               *pubBlobLen = (unsigned)(ecdsaPrivKey.pubKey.Length + 7) / 8;
                *pubBlob = (unsigned char *)fmalloc(*pubBlobLen);
                memmove(*pubBlob, ecdsaPrivKey.pubKey.Data, *pubBlobLen);
        }
                *pubBlob = (unsigned char *)fmalloc(*pubBlobLen);
                memmove(*pubBlob, ecdsaPrivKey.pubKey.Data, *pubBlobLen);
        }
@@ -1100,8 +1100,8 @@ feeReturn feeDEREncodePKCS8PrivateKey(
        }
 
        /* copy out */
        }
 
        /* copy out */
-       *pkcs8Blob = (unsigned char *)fmalloc(encPrivInfo.Length);
-       *pkcs8BlobLen = encPrivInfo.Length;
+       *pkcs8Blob = (unsigned char *)fmalloc((unsigned)encPrivInfo.Length);
+       *pkcs8BlobLen = (unsigned)encPrivInfo.Length;
        memmove(*pkcs8Blob, encPrivInfo.Data, encPrivInfo.Length); 
 errOut:
        if(encPriv) {
        memmove(*pkcs8Blob, encPrivInfo.Data, encPrivInfo.Length); 
 errOut:
        if(encPriv) {
@@ -1141,7 +1141,7 @@ feeReturn feeDERDecodePKCS8PrivateKey(
         * NSS_ECDSA_PrivateKey. 
         */
        frtn = feeDERDecodeOpenSSLKey((const unsigned char *)nssPrivKeyInfo.privateKey.Data,
         * NSS_ECDSA_PrivateKey. 
         */
        frtn = feeDERDecodeOpenSSLKey((const unsigned char *)nssPrivKeyInfo.privateKey.Data,
-               nssPrivKeyInfo.privateKey.Length, depth, 
+               (unsigned)nssPrivKeyInfo.privateKey.Length, depth, 
                privBlob, privBlobLen,
                pubBlob, pubBlobLen);
                
                privBlob, privBlobLen,
                pubBlob, pubBlobLen);
                
index c3b286da5a336ae8cf4eb890f71ec173c519bac6..90ae6c09f7043fe6ab69e70f0af89c01ff328225 100644 (file)
@@ -31,8 +31,7 @@
 #include "ckSHA1.h"
 #include <string.h>
 #include <stdlib.h>
 #include "ckSHA1.h"
 #include <string.h>
 #include <stdlib.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
-
+#include <Security/SecBase.h>
 #define kHMACSHA1DigestSize  20
 
 /* XXX These should really be in ckSHA1.h */
 #define kHMACSHA1DigestSize  20
 
 /* XXX These should really be in ckSHA1.h */
@@ -64,7 +63,7 @@ struct hmacLegacyContext {
        UInt8   k_opad[kSHA1BlockSize];
 };
 
        UInt8   k_opad[kSHA1BlockSize];
 };
 
-hmacLegacyContextRef hmacLegacyAlloc()
+hmacLegacyContextRef hmacLegacyAlloc(void)
 {
        hmacLegacyContextRef hmac = 
                (hmacLegacyContextRef)malloc(sizeof(struct hmacLegacyContext));
 {
        hmacLegacyContextRef hmac = 
                (hmacLegacyContextRef)malloc(sizeof(struct hmacLegacyContext));
@@ -96,7 +95,7 @@ OSStatus hmacLegacyInit(
        if(hmac->sha1Context == NULL) {
                hmac->sha1Context = sha1Alloc();
                if(hmac->sha1Context == NULL) {
        if(hmac->sha1Context == NULL) {
                hmac->sha1Context = sha1Alloc();
                if(hmac->sha1Context == NULL) {
-                       return memFullErr;
+                       return errSecAllocate;
                }
        }
        else {
                }
        }
        else {
@@ -105,7 +104,7 @@ OSStatus hmacLegacyInit(
        /* this implementation requires a 20-byte key */
        if (keyLen != kSHA1DigestSize) {
                /* FIXME */
        /* this implementation requires a 20-byte key */
        if (keyLen != kSHA1DigestSize) {
                /* FIXME */
-               return paramErr;
+               return errSecParam;
        }
        key = (UInt8*)keyPtr;
        
        }
        key = (UInt8*)keyPtr;
        
@@ -129,7 +128,7 @@ OSStatus hmacLegacyInit(
        memset (hmac->k_opad + keyLen, 0x5c, kSHA1BlockSize - keyLen);
        
        /* remainder happens in update */
        memset (hmac->k_opad + keyLen, 0x5c, kSHA1BlockSize - keyLen);
        
        /* remainder happens in update */
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus hmacLegacyUpdate(
 }
 
 OSStatus hmacLegacyUpdate(
@@ -153,7 +152,7 @@ OSStatus hmacLegacyUpdate(
        
        /* if there is another update coming, it gets added in to existing 
         * context; if the next step is a final, the current digest state is used. */
        
        /* if there is another update coming, it gets added in to existing 
         * context; if the next step is a final, the current digest state is used. */
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus hmacLegacyFinal(
 }
 
 OSStatus hmacLegacyFinal(
@@ -161,7 +160,7 @@ OSStatus hmacLegacyFinal(
        void *resultPtr)                // caller mallocs, must be HMACSHA1_OUT_SIZE bytes
 {
        memcpy (resultPtr, sha1Digest (hmac->sha1Context), kSHA1DigestSize);
        void *resultPtr)                // caller mallocs, must be HMACSHA1_OUT_SIZE bytes
 {
        memcpy (resultPtr, sha1Digest (hmac->sha1Context), kSHA1DigestSize);
-       return noErr;
+       return errSecSuccess;
 }
 
 #endif /* CRYPTKIT_HMAC_LEGACY */
 }
 
 #endif /* CRYPTKIT_HMAC_LEGACY */
index d611263e28d58adb52698370460ae5ecdaa59126..a2889fdba7275c0385e63ed0ef2e5371eece6af1 100644 (file)
@@ -33,7 +33,7 @@
 
 #if    CRYPTKIT_HMAC_LEGACY
 
 
 #if    CRYPTKIT_HMAC_LEGACY
 
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+#include <MacTypes.h>
 
 #ifdef __cplusplus
 extern "C" {
 
 #ifdef __cplusplus
 extern "C" {
@@ -46,7 +46,7 @@ extern "C" {
 struct hmacLegacyContext;
 typedef struct hmacLegacyContext *hmacLegacyContextRef;
 
 struct hmacLegacyContext;
 typedef struct hmacLegacyContext *hmacLegacyContextRef;
 
-hmacLegacyContextRef hmacLegacyAlloc();
+hmacLegacyContextRef hmacLegacyAlloc(void);
 void hmacLegacyFree(
        hmacLegacyContextRef hmac);
 OSStatus hmacLegacyInit(
 void hmacLegacyFree(
        hmacLegacyContextRef hmac);
 OSStatus hmacLegacyInit(
index 26bec08ebfa4ba48bafe03ef4b24e78058c00153..9774e600d8da9d8eb2c9e0e00655c15a58b80329 100644 (file)
@@ -94,7 +94,7 @@ void initCryptKit(void)
 /*
  * Shutdown.
  */
 /*
  * Shutdown.
  */
-void terminateCryptKit()
+void terminateCryptKit(void)
 {
        #if             GIANTS_VIA_STACK
        freeGiantStacks();
 {
        #if             GIANTS_VIA_STACK
        freeGiantStacks();
index a75b49ed4f39a8a12b183c5137d500720f0df734..bac245ca6dc7783cdcc0d301ecdda46346d09bbd 100644 (file)
@@ -157,7 +157,7 @@ typedef struct {
 #define CT_MONTGOMERY  0       /* a=1, b=0 */
 #define CT_WEIERSTRASS 1       /* c=0 */
 #define CT_GENERAL             4       /* other */
 #define CT_MONTGOMERY  0       /* a=1, b=0 */
 #define CT_WEIERSTRASS 1       /* c=0 */
 #define CT_GENERAL             4       /* other */
-#endif 0
+#endif /* 0 */
 
 /*
  * Obtain a malloc'd curveParams for a specified feeDepth.
 
 /*
  * Obtain a malloc'd curveParams for a specified feeDepth.
index 11617b127c774aba54569305b7b8b23fe46a7fb2..6592bf237485ecc26e3da6eed2ac4caa8307dc97 100644 (file)
@@ -43,7 +43,7 @@ void initCryptKit(void);
 /*
  * Shutdown.
  */
 /*
  * Shutdown.
  */
-void terminateCryptKit();
+void terminateCryptKit(void);
 
 #if    defined(NeXT) && !defined(WIN32)
 
 
 #if    defined(NeXT) && !defined(WIN32)
 
index 48e672d060021f0c019bab9359a833008483623d..e889bb009c1d74df3330686735bcd255b44eaddd 100644 (file)
@@ -463,6 +463,7 @@ feeReturn feePubKeyCreatePad(feePubKey myKey,
 
 #if    CRYPTKIT_HIGH_LEVEL_SIG
 
 
 #if    CRYPTKIT_HIGH_LEVEL_SIG
 
+#warning HLS
 /*
  * Generate digital signature, ElGamal style.
  */
 /*
  * Generate digital signature, ElGamal style.
  */
@@ -600,8 +601,11 @@ feeReturn feePubKeyCreateECDSASignature(feePubKey pubKey,
        return frtn;
 }
 #endif /* CRYPTKIT_ECDSA_ENABLE */
        return frtn;
 }
 #endif /* CRYPTKIT_ECDSA_ENABLE */
+#endif  /* CRYPTKIT_HIGH_LEVEL_SIG */
 #endif /* ECDSA_VERIFY_ONLY */
 
 #endif /* ECDSA_VERIFY_ONLY */
 
+#if    CRYPTKIT_HIGH_LEVEL_SIG
+
 #if    CRYPTKIT_ECDSA_ENABLE
 
 /*
 #if    CRYPTKIT_ECDSA_ENABLE
 
 /*
@@ -1262,7 +1266,7 @@ feeReturn feePubKeyInitFromDERPubBlob(feePubKey pubKey,
         pkinst->plus->twist  = CURVE_PLUS;
         pkinst->minus->twist = CURVE_MINUS;
         frtn = feeDERDecodePublicKey(keyBlob, 
         pkinst->plus->twist  = CURVE_PLUS;
         pkinst->minus->twist = CURVE_MINUS;
         frtn = feeDERDecodePublicKey(keyBlob, 
-               keyBlobLen,
+               (unsigned)keyBlobLen,
                &version,                       // currently unused
                &pkinst->cp,
                &pkinst->plus->x,
                &version,                       // currently unused
                &pkinst->cp,
                &pkinst->plus->x,
@@ -1293,7 +1297,7 @@ feeReturn feePubKeyInitFromDERPrivBlob(feePubKey pubKey,
        }
        memset(pkinst, 0, sizeof(pubKeyInst));
        frtn = feeDERDecodePrivateKey(keyBlob, 
        }
        memset(pkinst, 0, sizeof(pubKeyInst));
        frtn = feeDERDecodePrivateKey(keyBlob, 
-               keyBlobLen, 
+               (unsigned)keyBlobLen,
                &version,               // currently unused
                &pkinst->cp,
                &pkinst->privGiant);
                &version,               // currently unused
                &pkinst->cp,
                &pkinst->privGiant);
@@ -1371,7 +1375,7 @@ feeReturn feePubKeyInitFromX509Blob(
        unsigned xyStrLen = 0;
        
        /* obtain x/y and depth from X509 encoding */
        unsigned xyStrLen = 0;
        
        /* obtain x/y and depth from X509 encoding */
-       feeReturn frtn = feeDERDecodeX509PublicKey(keyBlob, keyBlobLen, &depth,
+       feeReturn frtn = feeDERDecodeX509PublicKey(keyBlob, (unsigned)keyBlobLen, &depth,
                &xyStr, &xyStrLen);
        if(frtn) {
                return frtn;
                &xyStr, &xyStrLen);
        if(frtn) {
                return frtn;
@@ -1394,7 +1398,7 @@ feeReturn feePubKeyInitFromPKCS8Blob(
        
        /* obtain x/y and depth from PKCS8 encoding */
        /* For now we ignore the possible public key string */
        
        /* obtain x/y and depth from PKCS8 encoding */
        /* For now we ignore the possible public key string */
-       feeReturn frtn = feeDERDecodePKCS8PrivateKey(keyBlob, keyBlobLen, &depth,
+       feeReturn frtn = feeDERDecodePKCS8PrivateKey(keyBlob, (unsigned)keyBlobLen, &depth,
                &privStr, &privStrLen, NULL, NULL);
        if(frtn) {
                return frtn;
                &privStr, &privStrLen, NULL, NULL);
        if(frtn) {
                return frtn;
@@ -1458,7 +1462,7 @@ feeReturn feePubKeyInitFromOpenSSLBlob(
        unsigned pubStrLen = 0;
        
        /* obtain x/y, public bit string, and depth from PKCS8 encoding */
        unsigned pubStrLen = 0;
        
        /* obtain x/y, public bit string, and depth from PKCS8 encoding */
-       feeReturn frtn = feeDERDecodeOpenSSLKey(keyBlob, keyBlobLen, &depth,
+       feeReturn frtn = feeDERDecodeOpenSSLKey(keyBlob, (unsigned)keyBlobLen, &depth,
                &privStr, &privStrLen, &pubStr, &pubStrLen);
        if(frtn) {
                return frtn;
                &privStr, &privStrLen, &pubStr, &pubStrLen);
        if(frtn) {
                return frtn;
index e9a3981555a0cd114b5fab90e84cd073c4f9bf8d..8b42e444687397bfd29a6de7c02959e2de35528c 100644 (file)
@@ -284,7 +284,7 @@ feeReturn feePubKeyVerifySignature(feePubKey pubKey,
        unsigned signatureLen);
        
 #if CRYPTKIT_ECDSA_ENABLE
        unsigned signatureLen);
        
 #if CRYPTKIT_ECDSA_ENABLE
-
+    
 /*
  * The following two routines are implemented using primitives in the
  * feeHash and feeECDSA objects.
 /*
  * The following two routines are implemented using primitives in the
  * feeHash and feeECDSA objects.
index 087323a364de53d8737b753884179dad0b0336a3..d4cd7ccdca26f00ca37248ff18148cdc2d4c2598 100644 (file)
@@ -82,7 +82,7 @@
 #endif
 #endif
 
 #endif
 #endif
 
-
+#if 0
 #if    FEE_DEBUG
 char printbuf1[200];
 char printbuf2[200];
 #if    FEE_DEBUG
 char printbuf1[200];
 char printbuf2[200];
@@ -109,6 +109,7 @@ void printGiantBuf2(giant x)
        }
 }
 #endif /* FEE_DEBUG */
        }
 }
 #endif /* FEE_DEBUG */
+#endif /* 0 */
 
 /******** debugging flags *********/
 
 
 /******** debugging flags *********/
 
@@ -138,7 +139,6 @@ void printGiantBuf2(giant x)
 #if    GIANT_MAC_DEBUG
 
 #include <string.h>
 #if    GIANT_MAC_DEBUG
 
 #include <string.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
 #include <TextUtils.h>
 
 /* this one needs a writable string */
 #include <TextUtils.h>
 
 /* this one needs a writable string */
@@ -253,7 +253,7 @@ void initGiantStacks(unsigned maxDigits)
 }
 
 /* called at shut down - free resources */ 
 }
 
 /* called at shut down - free resources */ 
-void freeGiantStacks()
+void freeGiantStacks(void)
 {
        int i;
        int j;
 {
        int i;
        int j;
index fa2443b75144840c91648c154f96ffdb80e8c6ff..67a32c5968fadf968642fb47102d518b46c377d4 100644 (file)
@@ -95,7 +95,7 @@ void initGiantStacks(unsigned maxDigits);
 /* 
  * Free giant stacks on shutdown.
  */
 /* 
  * Free giant stacks on shutdown.
  */
-void freeGiantStacks();
+void freeGiantStacks(void);
 
 #endif /* GIANTS_VIA_STACK */
 
 
 #endif /* GIANTS_VIA_STACK */
 
index 990c57f384739a993662ab93c25200ec312b221c..213e7793444aa952550b88900a3320ae74a03c86 100644 (file)
                0FD07C9DFE8A174411CD283A /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
                0FD07C9DFE8A174411CD283A /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0420;
+                               LastUpgradeCheck = 0500;
                        };
                        buildConfigurationList = C27AD33A0987FCDE001272E0 /* Build configuration list for PBXProject "libsecurity_cryptkit" */;
                        compatibilityVersion = "Xcode 3.2";
                        };
                        buildConfigurationList = C27AD33A0987FCDE001272E0 /* Build configuration list for PBXProject "libsecurity_cryptkit" */;
                        compatibilityVersion = "Xcode 3.2";
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB1F9146EF983000BF1F3 /* debug.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB1F9146EF983000BF1F3 /* debug.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                OTHER_CFLAGS = (
                                        "$(inherited)",
                                        "-DCK_SECURITY_BUILD",
                                OTHER_CFLAGS = (
                                        "$(inherited)",
                                        "-DCK_SECURITY_BUILD",
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB1FB146EF983000BF1F3 /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB1FB146EF983000BF1F3 /* release.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                OTHER_CFLAGS = (
                                        "$(inherited)",
                                        "-DCK_SECURITY_BUILD",
                                OTHER_CFLAGS = (
                                        "$(inherited)",
                                        "-DCK_SECURITY_BUILD",
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB1F9146EF983000BF1F3 /* debug.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB1F9146EF983000BF1F3 /* debug.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                OTHER_CFLAGS = "-DCK_STANDALONE_BUILD";
                        };
                        name = Debug;
                                OTHER_CFLAGS = "-DCK_STANDALONE_BUILD";
                        };
                        name = Debug;
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB1FB146EF983000BF1F3 /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB1FB146EF983000BF1F3 /* release.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                OTHER_CFLAGS = "-DCK_STANDALONE_BUILD";
                        };
                        name = Release;
                                OTHER_CFLAGS = "-DCK_STANDALONE_BUILD";
                        };
                        name = Release;
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB1F9146EF983000BF1F3 /* debug.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB1F9146EF983000BF1F3 /* debug.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                OTHER_CFLAGS = "-DCK_MINIMUM_SIG_BUILD";
                        };
                        name = Debug;
                                OTHER_CFLAGS = "-DCK_MINIMUM_SIG_BUILD";
                        };
                        name = Debug;
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB1FB146EF983000BF1F3 /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB1FB146EF983000BF1F3 /* release.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                OTHER_CFLAGS = "-DCK_MINIMUM_SIG_BUILD";
                        };
                        name = Release;
                                OTHER_CFLAGS = "-DCK_MINIMUM_SIG_BUILD";
                        };
                        name = Release;
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB1FA146EF983000BF1F3 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB1FA146EF983000BF1F3 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB1FA146EF983000BF1F3 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB1FA146EF983000BF1F3 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
index a04931319bcc22e52f301f9237a78e22c929decb..29608bbcb31e26c337f410d0d60d54a0136e8ee4 100644 (file)
@@ -167,7 +167,7 @@ void *Attachment::upcallRealloc(CSSM_HANDLE handle, void *mem, size_t size)
 void *Attachment::upcallCalloc(CSSM_HANDLE handle, size_t num, size_t size)
 {
     BEGIN_API
 void *Attachment::upcallCalloc(CSSM_HANDLE handle, size_t num, size_t size)
 {
     BEGIN_API
-    return HandleObject::find<Attachment>(handle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).calloc(num, size);
+    return HandleObject::find<Attachment>(handle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).calloc(size, num);
     END_API1(NULL)
 }
 
     END_API1(NULL)
 }
 
@@ -175,7 +175,8 @@ CSSM_RETURN Attachment::upcallCcToHandle(CSSM_CC_HANDLE handle,
                                          CSSM_MODULE_HANDLE *modHandle)
 {
     BEGIN_API
                                          CSSM_MODULE_HANDLE *modHandle)
 {
     BEGIN_API
-    Required(modHandle) = HandleObject::find<HandleContext>(handle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).attachment.handle();
+#warning Cast from CSSM_CC_HANDLE to CSSM_HANDLE
+    Required(modHandle) = HandleObject::find<HandleContext>((CSSM_HANDLE)handle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).attachment.handle();
     END_API(CSP)
 }
 
     END_API(CSP)
 }
 
index 4a1e954da5d0a9d641f6baa77d787a0ce6c5b8bb..d31eb4063803d41d18b232ee0843b439d50cbcc8 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2000-2013 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  *
  * cssmapple.h -- CSSM features specific to Apple's Implementation
  * @APPLE_LICENSE_HEADER_END@
  *
  * cssmapple.h -- CSSM features specific to Apple's Implementation
@@ -120,7 +120,7 @@ enum
 enum {
        CSSM_ACL_AUTHORIZATION_CHANGE_ACL = CSSM_ACL_AUTHORIZATION_TAG_VENDOR_DEFINED_START,
        CSSM_ACL_AUTHORIZATION_CHANGE_OWNER,
 enum {
        CSSM_ACL_AUTHORIZATION_CHANGE_ACL = CSSM_ACL_AUTHORIZATION_TAG_VENDOR_DEFINED_START,
        CSSM_ACL_AUTHORIZATION_CHANGE_OWNER,
-       
+
        // the "pre-auth" tags form a contiguous range of (up to) 64K pre-authorizations
        CSSM_ACL_AUTHORIZATION_PREAUTH_BASE =
                CSSM_ACL_AUTHORIZATION_TAG_VENDOR_DEFINED_START + 0x1000000,
        // the "pre-auth" tags form a contiguous range of (up to) 64K pre-authorizations
        CSSM_ACL_AUTHORIZATION_PREAUTH_BASE =
                CSSM_ACL_AUTHORIZATION_TAG_VENDOR_DEFINED_START + 0x1000000,
@@ -190,7 +190,7 @@ enum {      /* preauth tracking state */
        CSSM_ACL_PREAUTH_TRACKING_COUNT_MASK    = 0xff,         /* mask for count status */
        CSSM_ACL_PREAUTH_TRACKING_BLOCKED               = 0,            /* retries exhausted; the slot is blocked */
        /* 0 .. 255 is a count of (re)tries remaining */
        CSSM_ACL_PREAUTH_TRACKING_COUNT_MASK    = 0xff,         /* mask for count status */
        CSSM_ACL_PREAUTH_TRACKING_BLOCKED               = 0,            /* retries exhausted; the slot is blocked */
        /* 0 .. 255 is a count of (re)tries remaining */
-       
+
        /* bits or'ed into any count given */
        CSSM_ACL_PREAUTH_TRACKING_UNKNOWN               = 0x40000000, /* status of slot is unknown (ignore count) */
        CSSM_ACL_PREAUTH_TRACKING_AUTHORIZED    = 0x80000000 /* the slot is currently authorized (or'ed in) */
        /* bits or'ed into any count given */
        CSSM_ACL_PREAUTH_TRACKING_UNKNOWN               = 0x40000000, /* status of slot is unknown (ignore count) */
        CSSM_ACL_PREAUTH_TRACKING_AUTHORIZED    = 0x80000000 /* the slot is currently authorized (or'ed in) */
@@ -208,7 +208,7 @@ enum
 {
     CSSM_ALGID_APPLE_YARROW = CSSM_ALGID_VENDOR_DEFINED,
        CSSM_ALGID_AES,                         /* RijnDael */
 {
     CSSM_ALGID_APPLE_YARROW = CSSM_ALGID_VENDOR_DEFINED,
        CSSM_ALGID_AES,                         /* RijnDael */
-       CSSM_ALGID_FEE,                         /* FEE Key Generation */ 
+       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_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 */
@@ -255,7 +255,7 @@ enum {
        /* X509 SubjectPublicKeyInfo */
        CSSM_KEYBLOB_RAW_FORMAT_X509 = CSSM_KEYBLOB_RAW_FORMAT_VENDOR_DEFINED,
        /* OpenSSH v1 */
        /* X509 SubjectPublicKeyInfo */
        CSSM_KEYBLOB_RAW_FORMAT_X509 = CSSM_KEYBLOB_RAW_FORMAT_VENDOR_DEFINED,
        /* OpenSSH v1 */
-       CSSM_KEYBLOB_RAW_FORMAT_OPENSSH,                
+       CSSM_KEYBLOB_RAW_FORMAT_OPENSSH,
        /* openssl-style DSA private key */
        CSSM_KEYBLOB_RAW_FORMAT_OPENSSL,
        /* OpenSSH v2 */
        /* openssl-style DSA private key */
        CSSM_KEYBLOB_RAW_FORMAT_OPENSSL,
        /* OpenSSH v2 */
@@ -266,7 +266,7 @@ enum {
 enum
 {
     CSSM_CUSTOM_COMMON_ERROR_EXTENT = 0x00e0,
 enum
 {
     CSSM_CUSTOM_COMMON_ERROR_EXTENT = 0x00e0,
-    
+
     CSSM_ERRCODE_NO_USER_INTERACTION =                         0x00e0,
     CSSM_ERRCODE_USER_CANCELED =                                       0x00e1,
        CSSM_ERRCODE_SERVICE_NOT_AVAILABLE =                    0x00e2,
     CSSM_ERRCODE_NO_USER_INTERACTION =                         0x00e0,
     CSSM_ERRCODE_USER_CANCELED =                                       0x00e1,
        CSSM_ERRCODE_SERVICE_NOT_AVAILABLE =                    0x00e2,
@@ -283,7 +283,7 @@ enum {
        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_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_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,
@@ -331,18 +331,18 @@ enum {
 enum {
        CSSMERR_CSP_APPLE_ADD_APPLICATION_ACL_SUBJECT = CSSM_CSP_PRIVATE_ERROR + 0,
        /*
 enum {
        CSSMERR_CSP_APPLE_ADD_APPLICATION_ACL_SUBJECT = CSSM_CSP_PRIVATE_ERROR + 0,
        /*
-        * An attempt was made to use a public key which is incomplete due to 
+        * An attempt was made to use a public key which is incomplete due to
         * the lack of algorithm-specific parameters.
         */
        CSSMERR_CSP_APPLE_PUBLIC_KEY_INCOMPLETE = CSSM_CSP_PRIVATE_ERROR + 1,
         * the lack of algorithm-specific parameters.
         */
        CSSMERR_CSP_APPLE_PUBLIC_KEY_INCOMPLETE = CSSM_CSP_PRIVATE_ERROR + 1,
-       
+
        /* a code signature match failed */
        CSSMERR_CSP_APPLE_SIGNATURE_MISMATCH = CSSM_CSP_PRIVATE_ERROR + 2,
        /* a code signature match failed */
        CSSMERR_CSP_APPLE_SIGNATURE_MISMATCH = CSSM_CSP_PRIVATE_ERROR + 2,
-       
+
        /* Key StartDate/EndDate invalid */
        CSSMERR_CSP_APPLE_INVALID_KEY_START_DATE = CSSM_CSP_PRIVATE_ERROR + 3,
        CSSMERR_CSP_APPLE_INVALID_KEY_END_DATE = CSSM_CSP_PRIVATE_ERROR + 4,
        /* Key StartDate/EndDate invalid */
        CSSMERR_CSP_APPLE_INVALID_KEY_START_DATE = CSSM_CSP_PRIVATE_ERROR + 3,
        CSSMERR_CSP_APPLE_INVALID_KEY_END_DATE = CSSM_CSP_PRIVATE_ERROR + 4,
-       
+
        /* Keychain Syncing error codes */
        CSSMERR_CSPDL_APPLE_DL_CONVERSION_ERROR = CSSM_CSP_PRIVATE_ERROR + 5,
 
        /* Keychain Syncing error codes */
        CSSMERR_CSPDL_APPLE_DL_CONVERSION_ERROR = CSSM_CSP_PRIVATE_ERROR + 5,
 
@@ -372,10 +372,10 @@ enum {
        // The input parameter is a CSSM_BOOL, where TRUE turns autocommit on
        // and FALSE turns it off.
        CSSM_APPLEFILEDL_TOGGLE_AUTOCOMMIT,
        // 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,
        // Commit any pending changes to the database.
        CSSM_APPLEFILEDL_COMMIT,
-       
+
        // Rollback and discard any pending changes to the database.
        CSSM_APPLEFILEDL_ROLLBACK
 };
        // Rollback and discard any pending changes to the database.
        CSSM_APPLEFILEDL_ROLLBACK
 };
@@ -393,27 +393,27 @@ enum
           was neither NULL nor a pointer to a valid CSSM_APPLEDL_OPEN_PARAMETERS
           structure. */
        CSSMERR_APPLEDL_INVALID_OPEN_PARAMETERS =               CSSM_DL_PRIVATE_ERROR + 0,
           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 the disk was full */
        CSSMERR_APPLEDL_DISK_FULL =                                     CSSM_DL_PRIVATE_ERROR + 1,
-       
+
        /* an operation failed because a disk quota was exceeded */
        CSSMERR_APPLEDL_QUOTA_EXCEEDED =                                CSSM_DL_PRIVATE_ERROR + 2,
        /* an operation failed because a disk quota 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,
        /* 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,
     /* 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,
     /* 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,    
+    CSSMERR_APPLEDL_INCOMPATIBLE_KEY_BLOB =                    CSSM_DL_PRIVATE_ERROR + 7,
 };
 
 /* Apple X509TP private error codes. */
 };
 
 /* Apple X509TP private error codes. */
-enum 
+enum
 {
        /* Host name mismatch */
        CSSMERR_APPLETP_HOSTNAME_MISMATCH =                             CSSM_TP_PRIVATE_ERROR + 0,
 {
        /* Host name mismatch */
        CSSMERR_APPLETP_HOSTNAME_MISMATCH =                             CSSM_TP_PRIVATE_ERROR + 0,
@@ -472,7 +472,7 @@ enum
        /* S/MIME, leaf with empty subject name and no email addrs
         * in SubjectAltName */
        CSSMERR_APPLETP_SMIME_NO_EMAIL_ADDRS =                  CSSM_TP_PRIVATE_ERROR + 28,
        /* S/MIME, leaf with empty subject name and no email addrs
         * in SubjectAltName */
        CSSMERR_APPLETP_SMIME_NO_EMAIL_ADDRS =                  CSSM_TP_PRIVATE_ERROR + 28,
-       /* S/MIME, leaf with empty subject name, SubjectAltName 
+       /* S/MIME, leaf with empty subject name, SubjectAltName
         * not critical */
        CSSMERR_APPLETP_SMIME_SUBJ_ALT_NAME_NOT_CRIT =  CSSM_TP_PRIVATE_ERROR + 29,
        /* Appropriate SSL ExtendedKeyUsage not found */
         * not critical */
        CSSMERR_APPLETP_SMIME_SUBJ_ALT_NAME_NOT_CRIT =  CSSM_TP_PRIVATE_ERROR + 29,
        /* Appropriate SSL ExtendedKeyUsage not found */
@@ -521,22 +521,24 @@ enum
        CSSMERR_APPLETP_CODE_SIGN_DEVELOPMENT =                 CSSM_TP_PRIVATE_ERROR + 51,
        /* Illegal cert chain length for Resource Signing  */
        CSSMERR_APPLETP_RS_BAD_CERT_CHAIN_LENGTH =              CSSM_TP_PRIVATE_ERROR + 52,
        CSSMERR_APPLETP_CODE_SIGN_DEVELOPMENT =                 CSSM_TP_PRIVATE_ERROR + 51,
        /* Illegal cert chain length for Resource Signing  */
        CSSMERR_APPLETP_RS_BAD_CERT_CHAIN_LENGTH =              CSSM_TP_PRIVATE_ERROR + 52,
-       /* bad extended key usage for Resource Signing */
+       /* Bad extended key usage for Resource Signing */
        CSSMERR_APPLETP_RS_BAD_EXTENDED_KEY_USAGE =             CSSM_TP_PRIVATE_ERROR + 53,
        /* Trust Setting: deny */
        CSSMERR_APPLETP_TRUST_SETTING_DENY =                    CSSM_TP_PRIVATE_ERROR + 54,
        CSSMERR_APPLETP_RS_BAD_EXTENDED_KEY_USAGE =             CSSM_TP_PRIVATE_ERROR + 53,
        /* Trust Setting: deny */
        CSSMERR_APPLETP_TRUST_SETTING_DENY =                    CSSM_TP_PRIVATE_ERROR + 54,
-       /* invalid empty SubjectName */
+       /* Invalid empty SubjectName */
        CSSMERR_APPLETP_INVALID_EMPTY_SUBJECT =                 CSSM_TP_PRIVATE_ERROR + 55,
        CSSMERR_APPLETP_INVALID_EMPTY_SUBJECT =                 CSSM_TP_PRIVATE_ERROR + 55,
-       /* unknown critical Qualified Cert Statement ID */
+       /* Unknown critical Qualified Cert Statement ID */
        CSSMERR_APPLETP_UNKNOWN_QUAL_CERT_STATEMENT =   CSSM_TP_PRIVATE_ERROR + 56,
        /* Missing required extension */
        CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION =    CSSM_TP_PRIVATE_ERROR + 57,
        /* Extended key usage not marked critical */
        CSSMERR_APPLETP_UNKNOWN_QUAL_CERT_STATEMENT =   CSSM_TP_PRIVATE_ERROR + 56,
        /* Missing required extension */
        CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION =    CSSM_TP_PRIVATE_ERROR + 57,
        /* Extended key usage not marked critical */
-       CSSMERR_APPLETP_EXT_KEYUSAGE_NOT_CRITICAL =     CSSM_TP_PRIVATE_ERROR + 58
+       CSSMERR_APPLETP_EXT_KEYUSAGE_NOT_CRITICAL =     CSSM_TP_PRIVATE_ERROR + 58,
+       /* Required name or identifier not present */
+       CSSMERR_APPLETP_IDENTIFIER_MISSING =            CSSM_TP_PRIVATE_ERROR + 59
 };
 
 /* Apple .mac TP private error codes. */
 };
 
 /* Apple .mac TP private error codes. */
-enum 
+enum
 {
        /* cert request queued */
        CSSMERR_APPLE_DOTMAC_REQ_QUEUED =                               CSSM_TP_PRIVATE_ERROR + 100,
 {
        /* cert request queued */
        CSSMERR_APPLE_DOTMAC_REQ_QUEUED =                               CSSM_TP_PRIVATE_ERROR + 100,
@@ -663,13 +665,13 @@ enum
           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,
           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,
-       
+
        /* Return the SecurityServer database handle for the database specified by the DLDBHandle */
        CSSM_APPLECSPDL_DB_GET_HANDLE =         6,
        /* Return the SecurityServer database handle for the database specified by the DLDBHandle */
        CSSM_APPLECSPDL_DB_GET_HANDLE =         6,
-       
+
        /* Given a CSSM_KEY for the CSPDL, return the SecurityServer key handle */
        CSSM_APPLESCPDL_CSP_GET_KEYHANDLE =     7,
        /* Given a CSSM_KEY for the CSPDL, return the SecurityServer key handle */
        CSSM_APPLESCPDL_CSP_GET_KEYHANDLE =     7,
-       
+
        CSSM_APPLE_PRIVATE_CSPDL_CODE_8 = 8,
        CSSM_APPLE_PRIVATE_CSPDL_CODE_9 = 9,
        CSSM_APPLE_PRIVATE_CSPDL_CODE_10 = 10,
        CSSM_APPLE_PRIVATE_CSPDL_CODE_8 = 8,
        CSSM_APPLE_PRIVATE_CSPDL_CODE_9 = 9,
        CSSM_APPLE_PRIVATE_CSPDL_CODE_10 = 10,
@@ -679,13 +681,15 @@ enum
        CSSM_APPLE_PRIVATE_CSPDL_CODE_14 = 14,
        CSSM_APPLE_PRIVATE_CSPDL_CODE_15 = 15,
        CSSM_APPLE_PRIVATE_CSPDL_CODE_16 = 16,
        CSSM_APPLE_PRIVATE_CSPDL_CODE_14 = 14,
        CSSM_APPLE_PRIVATE_CSPDL_CODE_15 = 15,
        CSSM_APPLE_PRIVATE_CSPDL_CODE_16 = 16,
-       
-       /* Given a CSSM_KEY_PTR in any format, obtain the SHA-1 hash of the 
-        * associated key blob. 
+    CSSM_APPLE_PRIVATE_CSPDL_CODE_17 = 17,
+    CSSM_APPLE_PRIVATE_CSPDL_CODE_18 = 18,
+
+       /* Given a CSSM_KEY_PTR in any format, obtain the SHA-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. */
         * 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   
+       CSSM_APPLECSP_KEYDIGEST =                       0x100
 };
 
 
 };
 
 
@@ -712,7 +716,7 @@ typedef struct cssm_applecspdl_db_change_password_parameters
 /* Custom wrapped key formats */
 enum {
        CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM = 100,
 /* Custom wrapped key formats */
 enum {
        CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM = 100,
-       CSSM_KEYBLOB_WRAPPED_FORMAT_OPENSSL,                    // traditional openssl 
+       CSSM_KEYBLOB_WRAPPED_FORMAT_OPENSSL,                    // traditional openssl
        CSSM_KEYBLOB_WRAPPED_FORMAT_OPENSSH1                    // OpenSSH v1
 };
 
        CSSM_KEYBLOB_WRAPPED_FORMAT_OPENSSH1                    // OpenSSH v1
 };
 
@@ -724,61 +728,61 @@ enum {
 };
 
 enum {
 };
 
 enum {
-       /* 
+       /*
         * Public Key attribute for use with CSSM_ALGID_FEED.
         */
         * Public Key attribute for use with CSSM_ALGID_FEED.
         */
-    CSSM_ATTRIBUTE_PUBLIC_KEY =                
+    CSSM_ATTRIBUTE_PUBLIC_KEY =
                        (CSSM_ATTRIBUTE_DATA_KEY | (CSSM_ATTRIBUTE_VENDOR_DEFINED + 0)),
                        (CSSM_ATTRIBUTE_DATA_KEY | (CSSM_ATTRIBUTE_VENDOR_DEFINED + 0)),
-                       
+
        /*
         * FEE key attributes.
         * See CSSM_FEE_PRIME_TYPE_xxx, CSSM_FEE_CURVE_TYPE_xxx enums, below.
         */
        /*
         * FEE key attributes.
         * See CSSM_FEE_PRIME_TYPE_xxx, CSSM_FEE_CURVE_TYPE_xxx enums, below.
         */
-       CSSM_ATTRIBUTE_FEE_PRIME_TYPE = 
+       CSSM_ATTRIBUTE_FEE_PRIME_TYPE =
                        (CSSM_ATTRIBUTE_DATA_UINT32 | (CSSM_ATTRIBUTE_VENDOR_DEFINED + 1)),
                        (CSSM_ATTRIBUTE_DATA_UINT32 | (CSSM_ATTRIBUTE_VENDOR_DEFINED + 1)),
-       CSSM_ATTRIBUTE_FEE_CURVE_TYPE = 
+       CSSM_ATTRIBUTE_FEE_CURVE_TYPE =
                        (CSSM_ATTRIBUTE_DATA_UINT32 | (CSSM_ATTRIBUTE_VENDOR_DEFINED + 2)),
                        (CSSM_ATTRIBUTE_DATA_UINT32 | (CSSM_ATTRIBUTE_VENDOR_DEFINED + 2)),
-                       
+
        /*
         * Apple Secure Compression (ComCryption) optimization.
         * See CSSM_ASC_OPTIMIZE_xxx, enums, below.
         */
        /*
         * Apple Secure Compression (ComCryption) optimization.
         * See CSSM_ASC_OPTIMIZE_xxx, enums, below.
         */
-       CSSM_ATTRIBUTE_ASC_OPTIMIZATION = 
+       CSSM_ATTRIBUTE_ASC_OPTIMIZATION =
                        (CSSM_ATTRIBUTE_DATA_UINT32 | (CSSM_ATTRIBUTE_VENDOR_DEFINED + 3)),
                        (CSSM_ATTRIBUTE_DATA_UINT32 | (CSSM_ATTRIBUTE_VENDOR_DEFINED + 3)),
-                       
+
        /*
         * RSA blinding. Value is integer, nonzero (blinding on) or zero.
         */
        /*
         * RSA blinding. Value is integer, nonzero (blinding on) or zero.
         */
-       CSSM_ATTRIBUTE_RSA_BLINDING = 
+       CSSM_ATTRIBUTE_RSA_BLINDING =
                        (CSSM_ATTRIBUTE_DATA_UINT32 | (CSSM_ATTRIBUTE_VENDOR_DEFINED + 4)),
                        (CSSM_ATTRIBUTE_DATA_UINT32 | (CSSM_ATTRIBUTE_VENDOR_DEFINED + 4)),
-                       
+
        /*
         * Additional public key from which to obtain algorithm-specific
         * parameters.
         */
        /*
         * Additional public key from which to obtain algorithm-specific
         * parameters.
         */
-       CSSM_ATTRIBUTE_PARAM_KEY = 
+       CSSM_ATTRIBUTE_PARAM_KEY =
                        (CSSM_ATTRIBUTE_DATA_KEY | (CSSM_ATTRIBUTE_VENDOR_DEFINED + 5)),
                        (CSSM_ATTRIBUTE_DATA_KEY | (CSSM_ATTRIBUTE_VENDOR_DEFINED + 5)),
-                       
+
        /*
         * Prompt string for CSSM_ALGID_SECURE_PASSPHRASE key acquisition.
        /*
         * Prompt string for CSSM_ALGID_SECURE_PASSPHRASE key acquisition.
-        * Data is a UTF8-encoded external representation of a CFString. 
+        * Data is a UTF8-encoded external representation of a CFString.
         */
         */
-       CSSM_ATTRIBUTE_PROMPT = 
+       CSSM_ATTRIBUTE_PROMPT =
                        (CSSM_ATTRIBUTE_DATA_CSSM_DATA | (CSSM_ATTRIBUTE_VENDOR_DEFINED + 6)),
 
        /*
         * Alert panel title for CSSM_ALGID_SECURE_PASSPHRASE key acquisition.
                        (CSSM_ATTRIBUTE_DATA_CSSM_DATA | (CSSM_ATTRIBUTE_VENDOR_DEFINED + 6)),
 
        /*
         * Alert panel title for CSSM_ALGID_SECURE_PASSPHRASE key acquisition.
-        * Data is a UTF8-encoded external representation of a CFString. 
+        * Data is a UTF8-encoded external representation of a CFString.
         */
         */
-       CSSM_ATTRIBUTE_ALERT_TITLE = 
+       CSSM_ATTRIBUTE_ALERT_TITLE =
                        (CSSM_ATTRIBUTE_DATA_CSSM_DATA | (CSSM_ATTRIBUTE_VENDOR_DEFINED + 7)),
 
        /*
                        (CSSM_ATTRIBUTE_DATA_CSSM_DATA | (CSSM_ATTRIBUTE_VENDOR_DEFINED + 7)),
 
        /*
-        * Boolean to specify whether secure passphrase is being used to encrypt or to 
-        * recover data. In the former case the user will be prompted to enter the 
+        * Boolean to specify whether secure passphrase is being used to encrypt or to
+        * recover data. In the former case the user will be prompted to enter the
         * passphrase twice. Value is integer, nonzero (verify passphrase) or zero.
         */
         * passphrase twice. Value is integer, nonzero (verify passphrase) or zero.
         */
-       CSSM_ATTRIBUTE_VERIFY_PASSPHRASE = 
+       CSSM_ATTRIBUTE_VERIFY_PASSPHRASE =
                        (CSSM_ATTRIBUTE_DATA_UINT32 | (CSSM_ATTRIBUTE_VENDOR_DEFINED + 8))
 
 };
                        (CSSM_ATTRIBUTE_DATA_UINT32 | (CSSM_ATTRIBUTE_VENDOR_DEFINED + 8))
 
 };
@@ -826,7 +830,7 @@ enum {
         * still valid) due to the lack of algorithm-specific parameters.
         */
        CSSM_KEYATTR_PARTIAL                    = 0x00010000,
         * still valid) due to the lack of algorithm-specific parameters.
         */
        CSSM_KEYATTR_PARTIAL                    = 0x00010000,
-       
+
        /*
         * When set, public keys are stored encrypted. Default is to store
         * public keys in the clear. AppleCSPDL only.
        /*
         * When set, public keys are stored encrypted. Default is to store
         * public keys in the clear. AppleCSPDL only.
@@ -842,32 +846,32 @@ typedef struct {
        const CSSM_OID          *oid;
 } CSSM_APPLE_TP_NAME_OID;
 
        const CSSM_OID          *oid;
 } CSSM_APPLE_TP_NAME_OID;
 
-/* 
+/*
  * Certificate request passed to CSSM_TP_SubmitCredRequest() in the
  * CSSM_TP_AUTHORITY_REQUEST_TYPE.Requests field. Used for requesting
  * both locally-generated certs (CSSMOID_APPLE_TP_LOCAL_CERT_GEN) and
  * Certificate request passed to CSSM_TP_SubmitCredRequest() in the
  * CSSM_TP_AUTHORITY_REQUEST_TYPE.Requests field. Used for requesting
  * both locally-generated certs (CSSMOID_APPLE_TP_LOCAL_CERT_GEN) and
- * cert signing requests (CSSMOID_APPLE_TP_CSR_GEN). 
+ * cert signing requests (CSSMOID_APPLE_TP_CSR_GEN).
  */
 typedef struct {
        CSSM_CSP_HANDLE                 cspHand;                // sign with this CSP
        CSSM_CL_HANDLE                  clHand;                 // and this CL
        uint32                                  serialNumber;
        uint32                                  numSubjectNames;// size subjectNames[]
  */
 typedef struct {
        CSSM_CSP_HANDLE                 cspHand;                // sign with this CSP
        CSSM_CL_HANDLE                  clHand;                 // and this CL
        uint32                                  serialNumber;
        uint32                                  numSubjectNames;// size subjectNames[]
-       CSSM_APPLE_TP_NAME_OID  *subjectNames;  
-       
+       CSSM_APPLE_TP_NAME_OID  *subjectNames;
+
        /*
         * Issuer name can be expressed in the simplified CSSM_APPLE_TP_NAME_OID
        /*
         * Issuer name can be expressed in the simplified CSSM_APPLE_TP_NAME_OID
-        * array, as is the subject name, or as an CSSM_X509_NAME, which is 
-        * typically obtained from a signing cert. 
-        * Exactly one of {issuerNames, issuerNameX509} must be non-NULL. 
+        * array, as is the subject name, or as an CSSM_X509_NAME, which is
+        * typically obtained from a signing cert.
+        * Exactly one of {issuerNames, issuerNameX509} must be non-NULL.
         */
        uint32                                  numIssuerNames; // size issuerNames[]
         */
        uint32                                  numIssuerNames; // size issuerNames[]
-       CSSM_APPLE_TP_NAME_OID  *issuerNames;   // optional; NULL implies root 
+       CSSM_APPLE_TP_NAME_OID  *issuerNames;   // optional; NULL implies root
                                                                                        //    (signer == subject)
                                                                                        //    (signer == subject)
-       CSSM_X509_NAME_PTR              issuerNameX509;         
+       CSSM_X509_NAME_PTR              issuerNameX509;
        const CSSM_KEY                  *certPublicKey;
        const CSSM_KEY                  *issuerPrivateKey;
        const CSSM_KEY                  *certPublicKey;
        const CSSM_KEY                  *issuerPrivateKey;
-       
+
        /* Unfortunately there is no practical way to map any algorithm
         * to its appropriate OID, and we need both.... */
        CSSM_ALGORITHMS                 signatureAlg;   // e.g., CSSM_ALGID_SHA1WithRSA
        /* Unfortunately there is no practical way to map any algorithm
         * to its appropriate OID, and we need both.... */
        CSSM_ALGORITHMS                 signatureAlg;   // e.g., CSSM_ALGID_SHA1WithRSA
@@ -876,16 +880,16 @@ typedef struct {
        uint32                                  notAfter;
        uint32                                  numExtensions;
        CE_DataAndType                  *extensions;    // optional
        uint32                                  notAfter;
        uint32                                  numExtensions;
        CE_DataAndType                  *extensions;    // optional
-       
-       /* 
+
+       /*
         * Optional challenge string for CSSMOID_APPLE_TP_CSR_GEN.
         */
        const char                              *challengeString;
 } CSSM_APPLE_TP_CERT_REQUEST;
 
         * Optional challenge string for CSSMOID_APPLE_TP_CSR_GEN.
         */
        const char                              *challengeString;
 } CSSM_APPLE_TP_CERT_REQUEST;
 
-/* 
- * Options for X509TP's CSSM_TP_CertGroupVerify for policy CSSMOID_APPLE_TP_SSL. 
- * A pointer to, and length of, one of these is optionally placed in 
+/*
+ * Options for X509TP's CSSM_TP_CertGroupVerify for policy CSSMOID_APPLE_TP_SSL.
+ * A pointer to, and length of, one of these is optionally placed in
  * CSSM_TP_VERIFY_CONTEXT.Cred->Policy.PolicyIds[n].FieldValue.
  */
 #define CSSM_APPLE_TP_SSL_OPTS_VERSION         1
  * CSSM_TP_VERIFY_CONTEXT.Cred->Policy.PolicyIds[n].FieldValue.
  */
 #define CSSM_APPLE_TP_SSL_OPTS_VERSION         1
@@ -900,23 +904,23 @@ typedef struct {
 typedef struct {
        uint32      Version;        // CSSM_APPLE_TP_SSL_OPTS_VERSION
 
 typedef struct {
        uint32      Version;        // CSSM_APPLE_TP_SSL_OPTS_VERSION
 
-       /* 
-        * The domain name of the server (e.g., "store.apple.com".) In the 
-        * SSL and TLS protocols, this must match the common name of the 
+       /*
+        * The domain name of the server (e.g., "store.apple.com".) In the
+        * SSL and TLS protocols, this must match the common name of the
         * subject cert. Expressed as a C string, optionally NULL terminated
         * if it is NULL terminated, the length field should include the NULL).
         */
        uint32      ServerNameLen;
        const char  *ServerName;    // optional
         * subject cert. Expressed as a C string, optionally NULL terminated
         * if it is NULL terminated, the length field should include the NULL).
         */
        uint32      ServerNameLen;
        const char  *ServerName;    // optional
-       
+
        /* new fields for struct version 1 */
        uint32          Flags;
 } CSSM_APPLE_TP_SSL_OPTIONS;
 
        /* new fields for struct version 1 */
        uint32          Flags;
 } CSSM_APPLE_TP_SSL_OPTIONS;
 
-/* 
- * Options for X509TP's CSSM_TP_CertGroupVerify for policy 
- * CSSMOID_APPLE_TP_REVOCATION_CRL. A pointer to, and length of, one 
- * of these is optionally placed in 
+/*
+ * Options for X509TP's CSSM_TP_CertGroupVerify for policy
+ * CSSMOID_APPLE_TP_REVOCATION_CRL. A pointer to, and length of, one
+ * of these is optionally placed in
  * CSSM_TP_VERIFY_CONTEXT.Cred->Policy.PolicyIds[n].FieldValue.
  */
 #define CSSM_APPLE_TP_CRL_OPTS_VERSION         0
  * CSSM_TP_VERIFY_CONTEXT.Cred->Policy.PolicyIds[n].FieldValue.
  */
 #define CSSM_APPLE_TP_CRL_OPTS_VERSION         0
@@ -924,7 +928,7 @@ typedef struct {
 typedef uint32 CSSM_APPLE_TP_CRL_OPT_FLAGS;
 enum {
        // require CRL verification for each cert; default is "try"
 typedef uint32 CSSM_APPLE_TP_CRL_OPT_FLAGS;
 enum {
        // require CRL verification for each cert; default is "try"
-       CSSM_TP_ACTION_REQUIRE_CRL_PER_CERT     = 0x00000001,   
+       CSSM_TP_ACTION_REQUIRE_CRL_PER_CERT     = 0x00000001,
        // enable fetch from network
        CSSM_TP_ACTION_FETCH_CRL_FROM_NET               = 0x00000002,
        // if set and positive OCSP verify for given cert, no further revocation
        // enable fetch from network
        CSSM_TP_ACTION_FETCH_CRL_FROM_NET               = 0x00000002,
        // if set and positive OCSP verify for given cert, no further revocation
@@ -937,33 +941,33 @@ enum {
 typedef struct {
        uint32                                  Version;        // CSSM_APPLE_TP_CRL_OPTS_VERSION
        CSSM_APPLE_TP_CRL_OPT_FLAGS     CrlFlags;
 typedef struct {
        uint32                                  Version;        // CSSM_APPLE_TP_CRL_OPTS_VERSION
        CSSM_APPLE_TP_CRL_OPT_FLAGS     CrlFlags;
-       
+
        /*
         * When non-NULL, store CRLs fetched from net here.
        /*
         * When non-NULL, store CRLs fetched from net here.
-        * This is most likely a pointer to one of the  
+        * This is most likely a pointer to one of the
         * CSSM_TP_CALLERAUTH_CONTEXT.DBList entries but that
         * is not a strict requirement.
         */
        CSSM_DL_DB_HANDLE_PTR           crlStore;
 } CSSM_APPLE_TP_CRL_OPTIONS;
 
         * CSSM_TP_CALLERAUTH_CONTEXT.DBList entries but that
         * is not a strict requirement.
         */
        CSSM_DL_DB_HANDLE_PTR           crlStore;
 } CSSM_APPLE_TP_CRL_OPTIONS;
 
-/* 
- * Options for X509TP's CSSM_TP_CertGroupVerify for policy 
- * CSSMOID_APPLE_TP_SMIME. A pointer to, and length of, one 
- * of these is optionally placed in 
+/*
+ * Options for X509TP's CSSM_TP_CertGroupVerify for policy
+ * CSSMOID_APPLE_TP_SMIME. A pointer to, and length of, one
+ * of these is optionally placed in
  * CSSM_TP_VERIFY_CONTEXT.Cred->Policy.PolicyIds[n].FieldValue.
  */
 #define CSSM_APPLE_TP_SMIME_OPTS_VERSION               0
 typedef struct {
        uint32      Version;        // CSSM_APPLE_TP_SMIME_OPTS_VERSION
 
  * CSSM_TP_VERIFY_CONTEXT.Cred->Policy.PolicyIds[n].FieldValue.
  */
 #define CSSM_APPLE_TP_SMIME_OPTS_VERSION               0
 typedef struct {
        uint32      Version;        // CSSM_APPLE_TP_SMIME_OPTS_VERSION
 
-       /* 
+       /*
         * Intended usage of the leaf cert. The cert's KeyUsage extension,
         * if present, must be a superset of this.
         */
        CE_KeyUsage     IntendedUsage;
         * Intended usage of the leaf cert. The cert's KeyUsage extension,
         * if present, must be a superset of this.
         */
        CE_KeyUsage     IntendedUsage;
-       
-       /* 
+
+       /*
         * The email address of the sender. If there is an email address
         * in the sender's cert, that email address must match this one.
         * Both (email address in the cert, and this one) are optional.
         * The email address of the sender. If there is an email address
         * in the sender's cert, that email address must match this one.
         * Both (email address in the cert, and this one) are optional.
@@ -977,18 +981,18 @@ typedef struct {
 
 /*
  * Optional ActionData for all X509TP CertGroupVerify policies.
 
 /*
  * Optional ActionData for all X509TP CertGroupVerify policies.
- * A pointer to, and length of, one of these is optionally placed in 
+ * A pointer to, and length of, one of these is optionally placed in
  * CSSM_TP_VERIFY_CONTEXT.ActionData.
  */
 typedef uint32 CSSM_APPLE_TP_ACTION_FLAGS;
 enum {
        CSSM_TP_ACTION_ALLOW_EXPIRED            = 0x00000001,   // allow expired certs
  * CSSM_TP_VERIFY_CONTEXT.ActionData.
  */
 typedef uint32 CSSM_APPLE_TP_ACTION_FLAGS;
 enum {
        CSSM_TP_ACTION_ALLOW_EXPIRED            = 0x00000001,   // allow expired certs
-       CSSM_TP_ACTION_LEAF_IS_CA                       = 0x00000002,   // first cert is a CA 
+       CSSM_TP_ACTION_LEAF_IS_CA                       = 0x00000002,   // first cert is a CA
        CSSM_TP_ACTION_FETCH_CERT_FROM_NET      = 0x00000004,   // enable net fetch of CA cert
        CSSM_TP_ACTION_ALLOW_EXPIRED_ROOT       = 0x00000008,   // allow expired roots
        CSSM_TP_ACTION_REQUIRE_REV_PER_CERT     = 0x00000010,   // require positive revocation
                                                                                                                //   check per cert
        CSSM_TP_ACTION_FETCH_CERT_FROM_NET      = 0x00000004,   // enable net fetch of CA cert
        CSSM_TP_ACTION_ALLOW_EXPIRED_ROOT       = 0x00000008,   // allow expired roots
        CSSM_TP_ACTION_REQUIRE_REV_PER_CERT     = 0x00000010,   // require positive revocation
                                                                                                                //   check per cert
-       CSSM_TP_ACTION_TRUST_SETTINGS           = 0x00000020,   // use TrustSettings instead of 
+       CSSM_TP_ACTION_TRUST_SETTINGS           = 0x00000020,   // use TrustSettings instead of
                                                                                                                //   anchors
        CSSM_TP_ACTION_IMPLICIT_ANCHORS         = 0x00000040    // properly self-signed certs are
                                                                                                                //   treated as anchors implicitly
                                                                                                                //   anchors
        CSSM_TP_ACTION_IMPLICIT_ANCHORS         = 0x00000040    // properly self-signed certs are
                                                                                                                //   treated as anchors implicitly
@@ -1002,13 +1006,13 @@ typedef struct {
 
 /*
  * Per-cert evidence returned from CSSM_TP_CertGroupVerify.
 
 /*
  * Per-cert evidence returned from CSSM_TP_CertGroupVerify.
- * An array of these is presented in CSSM_TP_VERIFY_CONTEXT_RESULT.Evidence[2]. 
+ * An array of these is presented in CSSM_TP_VERIFY_CONTEXT_RESULT.Evidence[2].
  * Same number of these as in the cert group in Evidence[1].
  */
  * Same number of these as in the cert group in Evidence[1].
  */
+
 /* First, an array of bits indicating various status of the cert. */
 typedef uint32 CSSM_TP_APPLE_CERT_STATUS;
 /* First, an array of bits indicating various status of the cert. */
 typedef uint32 CSSM_TP_APPLE_CERT_STATUS;
-enum 
+enum
 {
        CSSM_CERT_STATUS_EXPIRED                        = 0x00000001,
        CSSM_CERT_STATUS_NOT_VALID_YET          = 0x00000002,
 {
        CSSM_CERT_STATUS_EXPIRED                        = 0x00000001,
        CSSM_CERT_STATUS_NOT_VALID_YET          = 0x00000002,
@@ -1034,21 +1038,21 @@ typedef struct {
        CSSM_TP_APPLE_CERT_STATUS       StatusBits;
        uint32                                          NumStatusCodes;
        CSSM_RETURN                             *StatusCodes;
        CSSM_TP_APPLE_CERT_STATUS       StatusBits;
        uint32                                          NumStatusCodes;
        CSSM_RETURN                             *StatusCodes;
-       
+
        /* index into raw cert group or AnchorCerts depending on IS_IN_ANCHORS */
        /* index into raw cert group or AnchorCerts depending on IS_IN_ANCHORS */
-       uint32                                          Index;   
-       
+       uint32                                          Index;
+
        /* nonzero if cert came from a DLDB */
        CSSM_DL_DB_HANDLE                       DlDbHandle;
        CSSM_DB_UNIQUE_RECORD_PTR       UniqueRecord;
 } CSSM_TP_APPLE_EVIDENCE_INFO;
 
 /*
        /* nonzero if cert came from a DLDB */
        CSSM_DL_DB_HANDLE                       DlDbHandle;
        CSSM_DB_UNIQUE_RECORD_PTR       UniqueRecord;
 } CSSM_TP_APPLE_EVIDENCE_INFO;
 
 /*
- * CSSM_TP_VERIFY_CONTEXT_RESULT.Evidence[0], basically defines which version/flavor 
+ * CSSM_TP_VERIFY_CONTEXT_RESULT.Evidence[0], basically defines which version/flavor
  * of remaining evidence is.
  */
 #define CSSM_TP_APPLE_EVIDENCE_VERSION         0
  * of remaining evidence is.
  */
 #define CSSM_TP_APPLE_EVIDENCE_VERSION         0
-typedef struct 
+typedef struct
 {
        uint32          Version;
 } CSSM_TP_APPLE_EVIDENCE_HEADER;
 {
        uint32          Version;
 } CSSM_TP_APPLE_EVIDENCE_HEADER;
@@ -1068,7 +1072,7 @@ typedef struct
  */
 
 #define CSSM_EVIDENCE_FORM_APPLE_CUSTOM                0x80000000
  */
 
 #define CSSM_EVIDENCE_FORM_APPLE_CUSTOM                0x80000000
-enum 
+enum
 {
        CSSM_EVIDENCE_FORM_APPLE_HEADER         = CSSM_EVIDENCE_FORM_APPLE_CUSTOM + 0,
        CSSM_EVIDENCE_FORM_APPLE_CERTGROUP      = CSSM_EVIDENCE_FORM_APPLE_CUSTOM + 1,
 {
        CSSM_EVIDENCE_FORM_APPLE_HEADER         = CSSM_EVIDENCE_FORM_APPLE_CUSTOM + 0,
        CSSM_EVIDENCE_FORM_APPLE_CERTGROUP      = CSSM_EVIDENCE_FORM_APPLE_CUSTOM + 1,
@@ -1077,13 +1081,13 @@ enum
 
 /* AppleX509CL extensions: passthrough ids */
 enum {
 
 /* AppleX509CL extensions: passthrough ids */
 enum {
-       /* 
+       /*
         * Obtain a signed Certificate Signing Request.
         * Input = CSSM_APPLE_CL_CSR_REQUEST
         * Output = allocated CSSM_DATA which points to a DER-encoded CSR.
         */
        CSSM_APPLEX509CL_OBTAIN_CSR,
         * Obtain a signed Certificate Signing Request.
         * Input = CSSM_APPLE_CL_CSR_REQUEST
         * Output = allocated CSSM_DATA which points to a DER-encoded CSR.
         */
        CSSM_APPLEX509CL_OBTAIN_CSR,
-       
+
        /*
         * Perform signature verify of a CSR.
         * Input:  CSSM_DATA referring to a DER-encoded CSR.
        /*
         * Perform signature verify of a CSR.
         * Input:  CSSM_DATA referring to a DER-encoded CSR.
@@ -1094,13 +1098,13 @@ enum {
 };
 
 /*
 };
 
 /*
- * Used in CL's CSSM_APPLEX509_OBTAIN_CSR Passthrough. This is the 
- * input; the output is a CSSM_DATA * containing the signed and 
+ * Used in CL's CSSM_APPLEX509_OBTAIN_CSR Passthrough. This is the
+ * input; the output is a CSSM_DATA * containing the signed and
  * DER-encoded CSR.
  */
 typedef struct {
  * DER-encoded CSR.
  */
 typedef struct {
-       CSSM_X509_NAME_PTR              subjectNameX509;                
-       
+       CSSM_X509_NAME_PTR              subjectNameX509;
+
        /* Unfortunately there is no practical way to map any algorithm
         * to its appropriate OID, and we need both.... */
        CSSM_ALGORITHMS                 signatureAlg;   // e.g., CSSM_ALGID_SHA1WithRSA
        /* Unfortunately there is no practical way to map any algorithm
         * to its appropriate OID, and we need both.... */
        CSSM_ALGORITHMS                 signatureAlg;   // e.g., CSSM_ALGID_SHA1WithRSA
@@ -1109,15 +1113,15 @@ typedef struct {
        CSSM_CSP_HANDLE                 cspHand;                // sign with this CSP
        const CSSM_KEY                  *subjectPublicKey;
        const CSSM_KEY                  *subjectPrivateKey;
        CSSM_CSP_HANDLE                 cspHand;                // sign with this CSP
        const CSSM_KEY                  *subjectPublicKey;
        const CSSM_KEY                  *subjectPrivateKey;
-       
-       /* 
+
+       /*
         * Optional challenge string.
         */
        const char                              *challengeString;
 } CSSM_APPLE_CL_CSR_REQUEST;
 
 /*
         * Optional challenge string.
         */
        const char                              *challengeString;
 } CSSM_APPLE_CL_CSR_REQUEST;
 
 /*
- * When a CRL with no NextUpdate field is encountered, we use this time 
+ * When a CRL with no NextUpdate field is encountered, we use this time
  * as the NextUpdate attribute when storing in a DB. It represents the
  * virtual end of time in CSSM_TIMESTRING form.
  */
  * as the NextUpdate attribute when storing in a DB. It represents the
  * virtual end of time in CSSM_TIMESTRING form.
  */
index a60479d3850c2b82b2813d770394046e2cf92ba1..4b008fd4084fb87fd5e85de965f0c88ddbff1183 100644 (file)
@@ -98,6 +98,10 @@ enum
 
        // query a DB to see if a relation exists
        CSSM_APPLECSPDL_DB_RELATION_EXISTS = CSSM_APPLE_PRIVATE_CSPDL_CODE_16,
 
        // query a DB to see if a relation exists
        CSSM_APPLECSPDL_DB_RELATION_EXISTS = CSSM_APPLE_PRIVATE_CSPDL_CODE_16,
+    
+    // stash a DB key
+    CSSM_APPLECSPDL_DB_STASH = CSSM_APPLE_PRIVATE_CSPDL_CODE_17,
+    CSSM_APPLECSPDL_DB_STASH_CHECK = CSSM_APPLE_PRIVATE_CSPDL_CODE_18
        
 };
 
        
 };
 
index 3b016365a274a5af0fca2e6a8e3a508ef280f53f..3f3f120f93188adf54a85cd825ccb83f4b469033 100644 (file)
@@ -94,7 +94,7 @@ private:
 
 inline HandleContext &enterContext(CSSM_CC_HANDLE h)
 {
 
 inline HandleContext &enterContext(CSSM_CC_HANDLE h)
 {
-    return HandleObject::findAndLock<HandleContext>(h, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE);
+    return HandleObject::findAndLock<HandleContext>((CSSM_HANDLE)h, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE);
 }
 
 
 }
 
 
index 92a2a1f28edbba471d8f91230497114f88f54853..62e0b4b07c0b27536df45bd398cdd0dc80bd9e86 100644 (file)
@@ -71,7 +71,7 @@ public:
     void remove(const ModuleCallback &cb) { callbackSet.erase(cb); }
 
     unsigned int callbackCount() const { return callbackSet.size(); }
     void remove(const ModuleCallback &cb) { callbackSet.erase(cb); }
 
     unsigned int callbackCount() const { return callbackSet.size(); }
-    unsigned int attachmentCount() const { return attachmentMap.size(); }
+    unsigned int attachmentCount() const { return (int)attachmentMap.size(); }
 
        void safeLock()         { if (!isThreadSafe()) mLock.lock(); }
        void safeUnlock()       { if (!isThreadSafe()) mLock.unlock(); }
 
        void safeLock()         { if (!isThreadSafe()) mLock.lock(); }
        void safeUnlock()       { if (!isThreadSafe()) mLock.unlock(); }
index 25d45ae3545b0cf5d3d94d3671fdf1e4808968cc..becc8e0692f01911b0f098b9bd54998c31dca398 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 1999-2001,2003-2004,2008 Apple Inc. All Rights Reserved.
- * 
+ * Copyright (c) 1999-2001,2003-2004,2008-2013 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  *
  * oidsbase.h -- Basic Object Identifier Macros and Data Types.
  * @APPLE_LICENSE_HEADER_END@
  *
  * oidsbase.h -- Basic Object Identifier Macros and Data Types.
@@ -57,21 +57,21 @@ representation is implied */
 #define INTEL_X509_LDAPSTRING_DATATYPE 2
 
 #define OID_ISO_CCITT_DIR_SERVICE                      85
 #define INTEL_X509_LDAPSTRING_DATATYPE 2
 
 #define OID_ISO_CCITT_DIR_SERVICE                      85
-#define OID_DS                                         OID_ISO_CCITT_DIR_SERVICE 
+#define OID_DS                                         OID_ISO_CCITT_DIR_SERVICE
 #define OID_DS_LENGTH                                  1
 #define OID_DS_LENGTH                                  1
-#define OID_ATTR_TYPE                                  OID_DS, 4                
+#define OID_ATTR_TYPE                                  OID_DS, 4
 #define OID_ATTR_TYPE_LENGTH                           OID_DS_LENGTH + 1
 #define OID_ATTR_TYPE_LENGTH                           OID_DS_LENGTH + 1
-#define OID_EXTENSION                                  OID_DS, 29          
+#define OID_EXTENSION                                  OID_DS, 29
 #define OID_EXTENSION_LENGTH                           OID_DS_LENGTH + 1
 #define OID_ISO_STANDARD                               40
 #define OID_EXTENSION_LENGTH                           OID_DS_LENGTH + 1
 #define OID_ISO_STANDARD                               40
-#define OID_ISO_MEMBER                                         42                     
+#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_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 
+#define OID_OIW                                                OID_ISO_IDENTIFIED_ORG, 14
 
 #define OID_ITU_RFCDATA_MEMBER_LENGTH          1
 #define OID_ITU_RFCDATA                                                9
 
 #define OID_ITU_RFCDATA_MEMBER_LENGTH          1
 #define OID_ITU_RFCDATA                                                9
@@ -152,7 +152,7 @@ representation is implied */
 #define OID_ETSI_LENGTH                                                2
 #define OID_ETSI_QCS                                           0x04, 0x00, 0x8E, 0x46, 0x01
 #define OID_ETSI_QCS_LENGTH                                    5
 #define OID_ETSI_LENGTH                                                2
 #define OID_ETSI_QCS                                           0x04, 0x00, 0x8E, 0x46, 0x01
 #define OID_ETSI_QCS_LENGTH                                    5
-       
+
 #define OID_OIW_SECSIG                                 OID_OIW, 3
 #define OID_OIW_LENGTH                                 2
 #define OID_OIW_SECSIG_LENGTH                          OID_OIW_LENGTH +1
 #define OID_OIW_SECSIG                                 OID_OIW, 3
 #define OID_OIW_LENGTH                                 2
 #define OID_OIW_SECSIG_LENGTH                          OID_OIW_LENGTH +1
@@ -179,11 +179,11 @@ representation is implied */
 /*
  * Apple-specific OID bases
  */
 /*
  * Apple-specific OID bases
  */
-/* 
+
+/*
  * apple OBJECT IDENTIFIER ::=
  *     { iso(1) member-body(2) US(840) 113635 }
  * 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
  * BER = 06 06 2A 86 48 86 F7 63
  */
 #define APPLE_OID                              OID_US, 0x86, 0xf7, 0x63
@@ -203,8 +203,8 @@ representation is implied */
  *             { appleDataSecurity 1 }
  *      { 1 2 840 113635 100 1 }
  *
  *             { appleDataSecurity 1 }
  *      { 1 2 840 113635 100 1 }
  *
- * BER = 06 08 2A 86 48 86 F7 63 64 01 
- */ 
+ * 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
 
 #define APPLE_TP_OID                   APPLE_ADS_OID, 1
 #define APPLE_TP_OID_LENGTH            APPLE_ADS_OID_LENGTH + 1
 
@@ -219,7 +219,7 @@ representation is implied */
 #define APPLE_ALG_OID_LENGTH   APPLE_ADS_OID_LENGTH + 1
 
 /*
 #define APPLE_ALG_OID_LENGTH   APPLE_ADS_OID_LENGTH + 1
 
 /*
- * appleDotMacCertificate OBJECT IDENTIFIER ::= 
+ * appleDotMacCertificate OBJECT IDENTIFIER ::=
  *             { appleDataSecurity 3 }
  *      { 1 2 840 113635 100 3 }
  */
  *             { appleDataSecurity 3 }
  *      { 1 2 840 113635 100 3 }
  */
@@ -229,7 +229,7 @@ representation is implied */
 /*
  * Basis of Policy OIDs for .mac TP requests
  *
 /*
  * Basis of Policy OIDs for .mac TP requests
  *
- * dotMacCertificateRequest OBJECT IDENTIFIER ::= 
+ * dotMacCertificateRequest OBJECT IDENTIFIER ::=
  *             { appleDotMacCertificate 1 }
  *      { 1 2 840 113635 100 3 1 }
  */
  *             { appleDotMacCertificate 1 }
  *      { 1 2 840 113635 100 3 1 }
  */
@@ -239,7 +239,7 @@ representation is implied */
 /*
  * Basis of .mac Certificate Extensions
  *
 /*
  * Basis of .mac Certificate Extensions
  *
- * dotMacCertificateExtension OBJECT IDENTIFIER ::= 
+ * dotMacCertificateExtension OBJECT IDENTIFIER ::=
  *             { appleDotMacCertificate 2 }
  *      { 1 2 840 113635 100 3 2 }
  */
  *             { appleDotMacCertificate 2 }
  *      { 1 2 840 113635 100 3 2 }
  */
@@ -249,7 +249,7 @@ representation is implied */
 /*
  * Basis of .mac Certificate request OID/value identifiers
  *
 /*
  * Basis of .mac Certificate request OID/value identifiers
  *
- * dotMacCertificateRequestValues OBJECT IDENTIFIER ::= 
+ * dotMacCertificateRequestValues OBJECT IDENTIFIER ::=
  *             { appleDotMacCertificate 3 }
  *      { 1 2 840 113635 100 3 3 }
  */
  *             { appleDotMacCertificate 3 }
  *      { 1 2 840 113635 100 3 3 }
  */
@@ -259,16 +259,16 @@ representation is implied */
 /*
  * Basis of Apple-specific extended key usages
  *
 /*
  * Basis of Apple-specific extended key usages
  *
- * appleExtendedKeyUsage OBJECT IDENTIFIER ::= 
+ * appleExtendedKeyUsage OBJECT IDENTIFIER ::=
  *             { appleDataSecurity 4 }
  *      { 1 2 840 113635 100 4 }
  */
 #define APPLE_EKU_OID                                  APPLE_ADS_OID, 4
 #define APPLE_EKU_OID_LENGTH                   APPLE_ADS_OID_LENGTH + 1
 
  *             { appleDataSecurity 4 }
  *      { 1 2 840 113635 100 4 }
  */
 #define APPLE_EKU_OID                                  APPLE_ADS_OID, 4
 #define APPLE_EKU_OID_LENGTH                   APPLE_ADS_OID_LENGTH + 1
 
-/* 
+/*
  * Basis of Apple Code Signing extended key usages
  * Basis of Apple Code Signing extended key usages
- * appleCodeSigning  OBJECT IDENTIFIER ::= 
+ * appleCodeSigning  OBJECT IDENTIFIER ::=
  *             { appleExtendedKeyUsage 1 }
  *      { 1 2 840 113635 100 4 1 }
  */
  *             { appleExtendedKeyUsage 1 }
  *      { 1 2 840 113635 100 4 1 }
  */
@@ -279,7 +279,7 @@ representation is implied */
 
 /*
  * Basis of Apple-specific Certificate Policy identifiers
 
 /*
  * Basis of Apple-specific Certificate Policy identifiers
- * appleCertificatePolicies OBJECT IDENTIFIER ::= 
+ * appleCertificatePolicies OBJECT IDENTIFIER ::=
  *             { appleDataSecurity 5 }
  *             { 1 2 840 113635 100 5 }
  */
  *             { appleDataSecurity 5 }
  *             { 1 2 840 113635 100 5 }
  */
@@ -288,7 +288,7 @@ representation is implied */
 
 /*
  * Base for MacAppStore Certificate Policy identifiers
 
 /*
  * Base for MacAppStore Certificate Policy identifiers
- * macAppStoreCertificatePolicyIDs OBJECT IDENTIFIER ::= 
+ * macAppStoreCertificatePolicyIDs OBJECT IDENTIFIER ::=
  *             { appleCertificatePolicies 6 }
  *             { 1 2 840 113635 100 5 6 }
  */
  *             { appleCertificatePolicies 6 }
  *             { 1 2 840 113635 100 5 6 }
  */
@@ -297,7 +297,7 @@ representation is implied */
 
 /*
  * MacAppStore receipt verification Certificate Policy identifier
 
 /*
  * MacAppStore receipt verification Certificate Policy identifier
- * macAppStoreReceiptCertificatePolicyID OBJECT IDENTIFIER ::= 
+ * macAppStoreReceiptCertificatePolicyID OBJECT IDENTIFIER ::=
  *             { appleCertificatePolicies 6 1 }
  *             { 1 2 840 113635 100 5 6 1 }
  */
  *             { appleCertificatePolicies 6 1 }
  *             { 1 2 840 113635 100 5 6 1 }
  */
@@ -306,7 +306,7 @@ representation is implied */
 
 /*
  * Base for AppleID Certificate Policy identifiers
 
 /*
  * Base for AppleID Certificate Policy identifiers
- * macAppStoreCertificatePolicyIDs OBJECT IDENTIFIER ::= 
+ * macAppStoreCertificatePolicyIDs OBJECT IDENTIFIER ::=
  *             { appleCertificatePolicies 7 }
  *             { 1 2 840 113635 100 5 7 }
  */
  *             { appleCertificatePolicies 7 }
  *             { 1 2 840 113635 100 5 7 }
  */
@@ -315,18 +315,37 @@ representation is implied */
 
 /*
  * AppleID Sharing Certificate Policy identifier
 
 /*
  * AppleID Sharing Certificate Policy identifier
- * appleIDSharingPolicyID OBJECT IDENTIFIER ::= 
+ * appleIDSharingPolicyID OBJECT IDENTIFIER ::=
  *             { appleCertificatePolicies 7 1 }
  *             { 1 2 840 113635 100 5 7 1 }
  */
 #define APPLE_CERT_POLICIES_APPLEID_SHARING            APPLE_CERT_POLICIES_APPLEID, 1
 #define APPLE_CERT_POLICIES_APPLEID_SHARING_LENGTH     APPLE_CERT_POLICIES_APPLEID_LENGTH + 1
 
  *             { appleCertificatePolicies 7 1 }
  *             { 1 2 840 113635 100 5 7 1 }
  */
 #define APPLE_CERT_POLICIES_APPLEID_SHARING            APPLE_CERT_POLICIES_APPLEID, 1
 #define APPLE_CERT_POLICIES_APPLEID_SHARING_LENGTH     APPLE_CERT_POLICIES_APPLEID_LENGTH + 1
 
+/*
+ * Apple Mobile Store Signing Policy identifier
+ *
+ * appleDemoContentReleaseSigningID ::= { appleCertificatePolicies 12}
+ *     { 1 2 840 113635 100 5 12  }
+ */
+#define APPLE_CERT_POLICIES_MOBILE_STORE_SIGNING               APPLE_CERT_POLICIES, 12
+#define APPLE_CERT_POLICIES_MOBILE_STORE_SIGNING_LENGTH        APPLE_CERT_POLICIES_LENGTH + 1
+
+/*
+ * Apple Test Mobile Store Signing Policy identifier
+ *
+ * appleDemoContentTestSigningID ::= { appleDemoContentReleaseSigningID 1}
+ *     { 1 2 840 113635 100 5 12 1 }
+ */
+#define APPLE_CERT_POLICIES_TEST_MOBILE_STORE_SIGNING          APPLE_CERT_POLICIES, 12, 1
+#define APPLE_CERT_POLICIES_TEST_MOBILE_STORE_SIGNING_LENGTH   APPLE_CERT_POLICIES_LENGTH + 2
+
+
 /* -------------------------------------------------------------------------*/
 
 /*
  * Basis of Apple-specific certificate extensions
 /* -------------------------------------------------------------------------*/
 
 /*
  * Basis of Apple-specific certificate extensions
- * appleCertificateExtensions OBJECT IDENTIFIER ::= 
+ * appleCertificateExtensions OBJECT IDENTIFIER ::=
  *             { appleDataSecurity 6 }
  *             { 1 2 840 113635 100 6 }
  */
  *             { appleDataSecurity 6 }
  *             { 1 2 840 113635 100 6 }
  */
@@ -335,7 +354,7 @@ representation is implied */
 
 /*
  * Basis of Apple-specific Code Signing certificate extensions
 
 /*
  * Basis of Apple-specific Code Signing certificate extensions
- * appleCertificateExtensionCodeSigning OBJECT IDENTIFIER ::= 
+ * appleCertificateExtensionCodeSigning OBJECT IDENTIFIER ::=
  *             { appleCertificateExtensions 1 }
  *             { 1 2 840 113635 100 6 1 }
  */
  *             { appleCertificateExtensions 1 }
  *             { 1 2 840 113635 100 6 1 }
  */
@@ -353,7 +372,7 @@ representation is implied */
 
 /*
  * Basis of Apple-specific Intermediate Certificate extensions
 
 /*
  * Basis of Apple-specific Intermediate Certificate extensions
- * appleCertificateExtensionIntermediateMarker OBJECT IDENTIFIER ::= 
+ * appleCertificateExtensionIntermediateMarker OBJECT IDENTIFIER ::=
  *             { appleCertificateExtensions 2 }
  *             { 1 2 840 113635 100 6 2 }
  */
  *             { appleCertificateExtensions 2 }
  *             { 1 2 840 113635 100 6 2 }
  */
@@ -362,36 +381,36 @@ representation is implied */
 
 /*
  * Marker for the WWDR Intermediate Certificate
 
 /*
  * Marker for the WWDR Intermediate Certificate
- * appleCertificateExtensionWWDRIntermediate OBJECT IDENTIFIER ::= 
+ * appleCertificateExtensionWWDRIntermediate OBJECT IDENTIFIER ::=
  *             { appleCertificateExtensionIntermediateMarker 1 }
  *             { 1 2 840 113635 100 6 2 1 }
  */
 #define APPLE_EXTENSION_WWDR_INTERMEDIATE           APPLE_EXTENSION_INTERMEDIATE_MARKER, 1
  *             { appleCertificateExtensionIntermediateMarker 1 }
  *             { 1 2 840 113635 100 6 2 1 }
  */
 #define APPLE_EXTENSION_WWDR_INTERMEDIATE           APPLE_EXTENSION_INTERMEDIATE_MARKER, 1
-#define APPLE_EXTENSION_WWDR_INTERMEDIATE_LENGTH    APPLE_EXTENSION_OID_LENGTH + 1
+#define APPLE_EXTENSION_WWDR_INTERMEDIATE_LENGTH    APPLE_EXTENSION_INTERMEDIATE_MARKER_LENGTH  + 1
 
 /*
  * Marker for the iTunes Store Intermediate Certificate
 
 /*
  * Marker for the iTunes Store Intermediate Certificate
- * appleCertificateExtensioniTunesStoreIntermediate OBJECT IDENTIFIER ::= 
+ * appleCertificateExtensioniTunesStoreIntermediate OBJECT IDENTIFIER ::=
  *             { appleCertificateExtensionIntermediateMarker 2 }
  *             { 1 2 840 113635 100 6 2 2 }
  */
 #define APPLE_EXTENSION_ITMS_INTERMEDIATE           APPLE_EXTENSION_INTERMEDIATE_MARKER, 2
  *             { appleCertificateExtensionIntermediateMarker 2 }
  *             { 1 2 840 113635 100 6 2 2 }
  */
 #define APPLE_EXTENSION_ITMS_INTERMEDIATE           APPLE_EXTENSION_INTERMEDIATE_MARKER, 2
-#define APPLE_EXTENSION_ITMS_INTERMEDIATE_LENGTH    APPLE_EXTENSION_OID_LENGTH + 1
+#define APPLE_EXTENSION_ITMS_INTERMEDIATE_LENGTH    APPLE_EXTENSION_INTERMEDIATE_MARKER_LENGTH + 1
 
 /*
  * Marker for the Application Integration Intermediate Certificate
 
 /*
  * Marker for the Application Integration Intermediate Certificate
- * appleCertificateExtensionApplicationIntegrationIntermediate OBJECT IDENTIFIER ::= 
+ * appleCertificateExtensionApplicationIntegrationIntermediate OBJECT IDENTIFIER ::=
  *             { appleCertificateExtensionIntermediateMarker 3 }
  *             { 1 2 840 113635 100 6 2 3 }
  */
 #define APPLE_EXTENSION_AAI_INTERMEDIATE           APPLE_EXTENSION_INTERMEDIATE_MARKER, 3
  *             { appleCertificateExtensionIntermediateMarker 3 }
  *             { 1 2 840 113635 100 6 2 3 }
  */
 #define APPLE_EXTENSION_AAI_INTERMEDIATE           APPLE_EXTENSION_INTERMEDIATE_MARKER, 3
-#define APPLE_EXTENSION_AAI_INTERMEDIATE_LENGTH    APPLE_EXTENSION_OID_LENGTH + 1
+#define APPLE_EXTENSION_AAI_INTERMEDIATE_LENGTH    APPLE_EXTENSION_INTERMEDIATE_MARKER_LENGTH + 1
 
 
-/* 
- *  Apple Apple ID Intermediate Marker (New subCA, no longer shared with push notification server cert issuer 
+/*
+ *  Apple Apple ID Intermediate Marker (New subCA, no longer shared with push notification server cert issuer
  *
  *
- *  appleCertificateExtensionAppleIDIntermediate ::= 
- *    { appleCertificateExtensionIntermediateMarker 7 }                                
+ *  appleCertificateExtensionAppleIDIntermediate ::=
+ *    { appleCertificateExtensionIntermediateMarker 7 }
  *    { 1 2 840 113635 100 6 2 7 }
  *
  *  shared intermediate OID is APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID
  *    { 1 2 840 113635 100 6 2 7 }
  *
  *  shared intermediate OID is APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID
@@ -399,18 +418,37 @@ representation is implied */
  *  Same as APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID_2 on iOS
 */
 #define APPLE_EXTENSION_APPLEID_INTERMEDIATE           APPLE_EXTENSION_INTERMEDIATE_MARKER, 7
  *  Same as APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID_2 on iOS
 */
 #define APPLE_EXTENSION_APPLEID_INTERMEDIATE           APPLE_EXTENSION_INTERMEDIATE_MARKER, 7
-#define APPLE_EXTENSION_APPLEID_INTERMEDIATE_LENGTH    APPLE_EXTENSION_OID_LENGTH + 1
+#define APPLE_EXTENSION_APPLEID_INTERMEDIATE_LENGTH    APPLE_EXTENSION_INTERMEDIATE_MARKER_LENGTH + 1
+
+/*
+ *  Apple System Integration 2 Intermediate Marker (New subCA)
+ *
+ *  appleCertificateExtensionSystemIntegration2Intermediate ::=
+ *    { appleCertificateExtensionIntermediateMarker 10 }
+ *    { 1 2 840 113635 100 6 2 10 }
+*/
+#define APPLE_EXTENSION_SYSINT2_INTERMEDIATE           APPLE_EXTENSION_INTERMEDIATE_MARKER, 10
+#define APPLE_EXTENSION_SYSINT2_INTERMEDIATE_LENGTH    APPLE_EXTENSION_INTERMEDIATE_MARKER_LENGTH + 1
+
+/*
+ *  Apple Secure Escrow Service Marker
+ *
+ *  appleEscrowService ::= { appleCertificateExtensions 23 1 }
+ *    { 1 2 840 113635 100 6 23 1 }
+ */
+#define APPLE_EXTENSION_ESCROW_SERVICE                 APPLE_EXTENSION_OID, 23, 1
+#define APPLE_EXTENSION_ESCROW_SERVICE_LENGTH          APPLE_EXTENSION_OID_LENGTH + 2
 
 /*
  * Marker for the AppleID Sharing Certificate
 
 /*
  * Marker for the AppleID Sharing Certificate
- * appleID OBJECT IDENTIFIER ::= 
+ * appleID OBJECT IDENTIFIER ::=
  *             { appleExtendedKeyUsage 7}
  *             { 1 2 840 113635 100 4 7 }
  */
 
 #define APPLE_EXTENSION_APPLEID_SHARING                                APPLE_EKU_OID, 7
 #define APPLE_EXTENSION_APPLEID_SHARING_LENGTH         APPLE_EKU_OID_LENGTH + 1
  *             { appleExtendedKeyUsage 7}
  *             { 1 2 840 113635 100 4 7 }
  */
 
 #define APPLE_EXTENSION_APPLEID_SHARING                                APPLE_EKU_OID, 7
 #define APPLE_EXTENSION_APPLEID_SHARING_LENGTH         APPLE_EKU_OID_LENGTH + 1
-       
+
 /*
  * Netscape OIDs.
  */
 /*
  * Netscape OIDs.
  */
index 6e533cc20051e9b73b760cec67ce3e2bef19ca64..70838512554e0de6bf074cbbc39b10afac9c55a7 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2000-2004,2008-2013 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -38,7 +38,7 @@
 /* required until PR-3347430 Security/cdsa/cdsa/oidscert.h is checked
  * into TOT - pending public API review */
 extern "C" {
 /* required until PR-3347430 Security/cdsa/cdsa/oidscert.h is checked
  * into TOT - pending public API review */
 extern "C" {
-       extern const CSSM_OID CSSMOID_X509V1IssuerNameStd, 
+       extern const CSSM_OID CSSMOID_X509V1IssuerNameStd,
                CSSMOID_X509V1SubjectNameStd;
 }
 
                CSSMOID_X509V1SubjectNameStd;
 }
 
@@ -77,7 +77,7 @@ static const uint8
        X509V3CertificateExtensionsCStruct[]            = {INTEL_X509V3_CERT_R08, 21, INTEL_X509_C_DATATYPE},
        X509V1SubjectNameStd[]                                          = {INTEL_X509V3_CERT_R08, 22},
        X509V1IssuerNameStd[]                                           = {INTEL_X509V3_CERT_R08, 23},
        X509V3CertificateExtensionsCStruct[]            = {INTEL_X509V3_CERT_R08, 21, INTEL_X509_C_DATATYPE},
        X509V1SubjectNameStd[]                                          = {INTEL_X509V3_CERT_R08, 22},
        X509V1IssuerNameStd[]                                           = {INTEL_X509V3_CERT_R08, 23},
-       
+
        /* Signature OID Fields */
        X509V1SignatureStruct[]                                         = {INTEL_X509V3_SIGN_R08, 0},
        X509V1SignatureCStruct[]                                        = {INTEL_X509V3_SIGN_R08, 0, INTEL_X509_C_DATATYPE},
        /* Signature OID Fields */
        X509V1SignatureStruct[]                                         = {INTEL_X509V3_SIGN_R08, 0},
        X509V1SignatureCStruct[]                                        = {INTEL_X509V3_SIGN_R08, 0, INTEL_X509_C_DATATYPE},
@@ -87,7 +87,7 @@ static const uint8
        X509V1SignatureAlgorithmTBS[]                           = {INTEL_X509V3_SIGN_R08, 10},
        X509V1SignatureAlgorithmParameters[]            = {INTEL_X509V3_SIGN_R08, 3},
        X509V1Signature[]                                                       = {INTEL_X509V3_SIGN_R08, 2},
        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},
        /* Extension OID Fields */
        SubjectSignatureBitmap[]                                        = {INTEL_X509V3_CERT_PRIVATE_EXTENSIONS, 1},
        SubjectPicture[]                                                        = {INTEL_X509V3_CERT_PRIVATE_EXTENSIONS, 2},
@@ -99,7 +99,7 @@ const CSSM_OID
 
        /* Certificate OIDS */
        CSSMOID_X509V3SignedCertificate                         = {INTEL_X509V3_CERT_R08_LENGTH+1,  (uint8 *)X509V3SignedCertificate},
 
        /* Certificate OIDS */
        CSSMOID_X509V3SignedCertificate                         = {INTEL_X509V3_CERT_R08_LENGTH+1,  (uint8 *)X509V3SignedCertificate},
-       CSSMOID_X509V3SignedCertificateCStruct          = {INTEL_X509V3_CERT_R08_LENGTH+2,  
+       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},
                                                                                                        (uint8 *)X509V3SignedCertificateCStruct},
        CSSMOID_X509V3Certificate                                       = {INTEL_X509V3_CERT_R08_LENGTH+1,  (uint8 *)X509V3Certificate},
        CSSMOID_X509V3CertificateCStruct                        = {INTEL_X509V3_CERT_R08_LENGTH+2,  (uint8 *)X509V3CertificateCStruct},
@@ -116,34 +116,34 @@ const CSSM_OID
        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_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,  
+       CSSMOID_X509V1SubjectPublicKeyCStruct           = {INTEL_X509V3_CERT_R08_LENGTH+2,
                                                                                                        (uint8 *)X509V1SubjectPublicKeyCStruct},
                                                                                                        (uint8 *)X509V1SubjectPublicKeyCStruct},
-       CSSMOID_X509V1SubjectPublicKeyAlgorithm         = {INTEL_X509V3_CERT_R08_LENGTH+1,  
+       CSSMOID_X509V1SubjectPublicKeyAlgorithm         = {INTEL_X509V3_CERT_R08_LENGTH+1,
                                                                                                        (uint8 *)X509V1SubjectPublicKeyAlgorithm},
                                                                                                        (uint8 *)X509V1SubjectPublicKeyAlgorithm},
-       CSSMOID_X509V1SubjectPublicKeyAlgorithmParameters = {INTEL_X509V3_CERT_R08_LENGTH+1,  
+       CSSMOID_X509V1SubjectPublicKeyAlgorithmParameters = {INTEL_X509V3_CERT_R08_LENGTH+1,
                                                                                                        (uint8 *)X509V1SubjectPublicKeyAlgorithmParameters},
        CSSMOID_X509V1SubjectPublicKey                          = {INTEL_X509V3_CERT_R08_LENGTH+1,  (uint8 *)X509V1SubjectPublicKey},
                                                                                                        (uint8 *)X509V1SubjectPublicKeyAlgorithmParameters},
        CSSMOID_X509V1SubjectPublicKey                          = {INTEL_X509V3_CERT_R08_LENGTH+1,  (uint8 *)X509V1SubjectPublicKey},
-       CSSMOID_X509V1CertificateIssuerUniqueId         = {INTEL_X509V3_CERT_R08_LENGTH+1,  
+       CSSMOID_X509V1CertificateIssuerUniqueId         = {INTEL_X509V3_CERT_R08_LENGTH+1,
                                                                                                        (uint8 *)X509V1CertificateIssuerUniqueId},
                                                                                                        (uint8 *)X509V1CertificateIssuerUniqueId},
-       CSSMOID_X509V1CertificateSubjectUniqueId        = {INTEL_X509V3_CERT_R08_LENGTH+1,  
+       CSSMOID_X509V1CertificateSubjectUniqueId        = {INTEL_X509V3_CERT_R08_LENGTH+1,
                                                                                                        (uint8 *)X509V1CertificateSubjectUniqueId},
                                                                                                        (uint8 *)X509V1CertificateSubjectUniqueId},
-       CSSMOID_X509V3CertificateExtensionsStruct       = {INTEL_X509V3_CERT_R08_LENGTH+1,  
+       CSSMOID_X509V3CertificateExtensionsStruct       = {INTEL_X509V3_CERT_R08_LENGTH+1,
                                                                                                        (uint8 *)X509V3CertificateExtensionsStruct},
                                                                                                        (uint8 *)X509V3CertificateExtensionsStruct},
-       CSSMOID_X509V3CertificateExtensionsCStruct  = {INTEL_X509V3_CERT_R08_LENGTH+2,  
+       CSSMOID_X509V3CertificateExtensionsCStruct  = {INTEL_X509V3_CERT_R08_LENGTH+2,
                                                                                                        (uint8 *)X509V3CertificateExtensionsCStruct},
                                                                                                        (uint8 *)X509V3CertificateExtensionsCStruct},
-       CSSMOID_X509V3CertificateNumberOfExtensions = {INTEL_X509V3_CERT_R08_LENGTH+1,  
+       CSSMOID_X509V3CertificateNumberOfExtensions = {INTEL_X509V3_CERT_R08_LENGTH+1,
                                                                                                        (uint8 *)X509V3CertificateNumberOfExtensions},
                                                                                                        (uint8 *)X509V3CertificateNumberOfExtensions},
-       CSSMOID_X509V3CertificateExtensionStruct        = {INTEL_X509V3_CERT_R08_LENGTH+1,  
+       CSSMOID_X509V3CertificateExtensionStruct        = {INTEL_X509V3_CERT_R08_LENGTH+1,
                                                                                                        (uint8 *)X509V3CertificateExtensionStruct},
                                                                                                        (uint8 *)X509V3CertificateExtensionStruct},
-       CSSMOID_X509V3CertificateExtensionCStruct       = {INTEL_X509V3_CERT_R08_LENGTH+2,  
+       CSSMOID_X509V3CertificateExtensionCStruct       = {INTEL_X509V3_CERT_R08_LENGTH+2,
                                                                                                        (uint8 *)X509V3CertificateExtensionCStruct},
                                                                                                        (uint8 *)X509V3CertificateExtensionCStruct},
-       CSSMOID_X509V3CertificateExtensionId            = {INTEL_X509V3_CERT_R08_LENGTH+1,  
+       CSSMOID_X509V3CertificateExtensionId            = {INTEL_X509V3_CERT_R08_LENGTH+1,
                                                                                                        (uint8 *)X509V3CertificateExtensionId},
                                                                                                        (uint8 *)X509V3CertificateExtensionId},
-       CSSMOID_X509V3CertificateExtensionCritical  = {INTEL_X509V3_CERT_R08_LENGTH+1,  
+       CSSMOID_X509V3CertificateExtensionCritical  = {INTEL_X509V3_CERT_R08_LENGTH+1,
                                                                                                        (uint8 *)X509V3CertificateExtensionCritical},
                                                                                                        (uint8 *)X509V3CertificateExtensionCritical},
-       CSSMOID_X509V3CertificateExtensionType          = {INTEL_X509V3_CERT_R08_LENGTH+1,  
+       CSSMOID_X509V3CertificateExtensionType          = {INTEL_X509V3_CERT_R08_LENGTH+1,
                                                                                                        (uint8 *)X509V3CertificateExtensionType},
                                                                                                        (uint8 *)X509V3CertificateExtensionType},
-       CSSMOID_X509V3CertificateExtensionValue         = {INTEL_X509V3_CERT_R08_LENGTH+1,  
+       CSSMOID_X509V3CertificateExtensionValue         = {INTEL_X509V3_CERT_R08_LENGTH+1,
                                                                                                        (uint8 *)X509V3CertificateExtensionValue},
 
        /* Signature OID Fields */
                                                                                                        (uint8 *)X509V3CertificateExtensionValue},
 
        /* Signature OID Fields */
@@ -151,10 +151,10 @@ const CSSM_OID
        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_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,  
+       CSSMOID_X509V1SignatureAlgorithmParameters      = {INTEL_X509V3_SIGN_R08_LENGTH+1,
                                                                                                        (uint8 *)X509V1SignatureAlgorithmParameters},
        CSSMOID_X509V1Signature                                         = {INTEL_X509V3_SIGN_R08_LENGTH+1,  (uint8 *)X509V1Signature},
                                                                                                        (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},
        /* 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},
@@ -165,8 +165,8 @@ const CSSM_OID
 /***
  *** Apple addenda.
  ***/
 /***
  *** Apple addenda.
  ***/
-/* 
+
+/*
  * Standard Cert extensions.
  */
 static const uint8
  * Standard Cert extensions.
  */
 static const uint8
@@ -196,7 +196,7 @@ static const uint8
        OID_BiometricInfo[]                                     = { OID_PE, 2 },
        OID_QC_Statements[]                                     = { OID_PE, 3 },
        OID_SubjectInfoAccess[]                         = { OID_PE, 11 },
        OID_BiometricInfo[]                                     = { OID_PE, 2 },
        OID_QC_Statements[]                                     = { OID_PE, 3 },
        OID_SubjectInfoAccess[]                         = { OID_PE, 11 },
-       
+
        /* Individual OIDS appearing in an ExtendedKeyUsage extension */
        OID_ExtendedKeyUsageAny[]                       = { OID_EXTENSION, 37, 0 },
        OID_KP_ServerAuth[]                                     = { OID_KP, 1 },
        /* Individual OIDS appearing in an ExtendedKeyUsage extension */
        OID_ExtendedKeyUsageAny[]                       = { OID_EXTENSION, 37, 0 },
        OID_KP_ServerAuth[]                                     = { OID_KP, 1 },
@@ -210,7 +210,7 @@ static const uint8
        OID_KERBv5_PKINIT_KP_KDC[]                      = { OID_KERBv5_PKINIT, 5 },
        /* IPSec */
        OID_EKU_IPSec[]                                         = { 0x2B, 0x06, 0x01, 0x05, 0x05, 0x08, 0x02, 0x02 },
        OID_KERBv5_PKINIT_KP_KDC[]                      = { OID_KERBv5_PKINIT, 5 },
        /* IPSec */
        OID_EKU_IPSec[]                                         = { 0x2B, 0x06, 0x01, 0x05, 0x05, 0x08, 0x02, 0x02 },
-       
+
        /* .mac Certificate Extended Key Use values */
        OID_DOTMAC_CERT_EXTENSION[]             = { APPLE_DOTMAC_CERT_EXTEN_OID },
        OID_DOTMAC_CERT_IDENTITY[]              = { APPLE_DOTMAC_CERT_EXTEN_OID, 1 },
        /* .mac Certificate Extended Key Use values */
        OID_DOTMAC_CERT_EXTENSION[]             = { APPLE_DOTMAC_CERT_EXTEN_OID },
        OID_DOTMAC_CERT_IDENTITY[]              = { APPLE_DOTMAC_CERT_EXTEN_OID, 1 },
@@ -223,6 +223,9 @@ static const uint8
        OID_APPLE_EKU_ICHAT_SIGNING[]           = { APPLE_EKU_OID, 2 },
        OID_APPLE_EKU_ICHAT_ENCRYPTION[]        = { APPLE_EKU_OID, 3 },
        OID_APPLE_EKU_SYSTEM_IDENTITY[]         = { APPLE_EKU_OID, 4 },
        OID_APPLE_EKU_ICHAT_SIGNING[]           = { APPLE_EKU_OID, 2 },
        OID_APPLE_EKU_ICHAT_ENCRYPTION[]        = { APPLE_EKU_OID, 3 },
        OID_APPLE_EKU_SYSTEM_IDENTITY[]         = { APPLE_EKU_OID, 4 },
+       OID_APPLE_EKU_PASSBOOK_SIGNING[]        = { APPLE_EKU_OID, 14 },
+       OID_APPLE_EKU_PROFILE_SIGNING[]         = { APPLE_EKU_OID, 16 },
+       OID_APPLE_EKU_QA_PROFILE_SIGNING[]      = { APPLE_EKU_OID, 17 },
        /* Apple cert policies */
        OID_APPLE_CERT_POLICY[]                         = { APPLE_CERT_POLICIES, 1 },
        OID_DOTMAC_CERT_POLICY[]                        = { APPLE_CERT_POLICIES, 2 },
        /* Apple cert policies */
        OID_APPLE_CERT_POLICY[]                         = { APPLE_CERT_POLICIES, 1 },
        OID_DOTMAC_CERT_POLICY[]                        = { APPLE_CERT_POLICIES, 2 },
@@ -231,20 +234,25 @@ static const uint8
        OID_APPLE_CERT_POLICY_MACAPPSTORE_RECEIPT[] = { APPLE_CERT_POLICIES_MACAPPSTORE_RECEIPT },
        OID_APPLE_CERT_POLICY_APPLEID[] = { APPLE_CERT_POLICIES_APPLEID },
        OID_APPLE_CERT_POLICY_APPLEID_SHARING[] = { APPLE_CERT_POLICIES_APPLEID_SHARING },
        OID_APPLE_CERT_POLICY_MACAPPSTORE_RECEIPT[] = { APPLE_CERT_POLICIES_MACAPPSTORE_RECEIPT },
        OID_APPLE_CERT_POLICY_APPLEID[] = { APPLE_CERT_POLICIES_APPLEID },
        OID_APPLE_CERT_POLICY_APPLEID_SHARING[] = { APPLE_CERT_POLICIES_APPLEID_SHARING },
-       
+       OID_APPLE_CERT_POLICY_MOBILE_STORE_SIGNING[] = { APPLE_CERT_POLICIES_MOBILE_STORE_SIGNING },
+       OID_APPLE_CERT_POLICY_TEST_MOBILE_STORE_SIGNING[] = { APPLE_CERT_POLICIES_TEST_MOBILE_STORE_SIGNING },
+
     /* Apple-specific extensions */
     OID_APPLE_EXTENSION[]                              = { APPLE_EXTENSION_OID },
     OID_APPLE_EXTENSION_CODE_SIGNING[]         = { APPLE_EXTENSION_CODE_SIGNING },
     OID_APPLE_EXTENSION_APPLE_SIGNING[]                = { APPLE_EXTENSION_CODE_SIGNING, 1 },
     OID_APPLE_EXTENSION_ADC_DEV_SIGNING[]      = { APPLE_EXTENSION_CODE_SIGNING, 2 },
     OID_APPLE_EXTENSION_ADC_APPLE_SIGNING[]    = { APPLE_EXTENSION_CODE_SIGNING, 3 },
     /* Apple-specific extensions */
     OID_APPLE_EXTENSION[]                              = { APPLE_EXTENSION_OID },
     OID_APPLE_EXTENSION_CODE_SIGNING[]         = { APPLE_EXTENSION_CODE_SIGNING },
     OID_APPLE_EXTENSION_APPLE_SIGNING[]                = { APPLE_EXTENSION_CODE_SIGNING, 1 },
     OID_APPLE_EXTENSION_ADC_DEV_SIGNING[]      = { APPLE_EXTENSION_CODE_SIGNING, 2 },
     OID_APPLE_EXTENSION_ADC_APPLE_SIGNING[]    = { APPLE_EXTENSION_CODE_SIGNING, 3 },
+    OID_APPLE_EXTENSION_PASSBOOK_SIGNING[]     = { APPLE_EXTENSION_CODE_SIGNING, 16 },
        OID_APPLE_EXTENSION_MACAPPSTORE_RECEIPT[] = { APPLE_EXTENSION_MACAPPSTORE_RECEIPT },
        OID_APPLE_EXTENSION_INTERMEDIATE_MARKER[] = { APPLE_EXTENSION_INTERMEDIATE_MARKER },
        OID_APPLE_EXTENSION_WWDR_INTERMEDIATE[] = { APPLE_EXTENSION_WWDR_INTERMEDIATE },
        OID_APPLE_EXTENSION_ITMS_INTERMEDIATE[] = { APPLE_EXTENSION_ITMS_INTERMEDIATE },
        OID_APPLE_EXTENSION_AAI_INTERMEDIATE[] = { APPLE_EXTENSION_AAI_INTERMEDIATE },
        OID_APPLE_EXTENSION_APPLEID_INTERMEDIATE[] = { APPLE_EXTENSION_APPLEID_INTERMEDIATE },
        OID_APPLE_EXTENSION_MACAPPSTORE_RECEIPT[] = { APPLE_EXTENSION_MACAPPSTORE_RECEIPT },
        OID_APPLE_EXTENSION_INTERMEDIATE_MARKER[] = { APPLE_EXTENSION_INTERMEDIATE_MARKER },
        OID_APPLE_EXTENSION_WWDR_INTERMEDIATE[] = { APPLE_EXTENSION_WWDR_INTERMEDIATE },
        OID_APPLE_EXTENSION_ITMS_INTERMEDIATE[] = { APPLE_EXTENSION_ITMS_INTERMEDIATE },
        OID_APPLE_EXTENSION_AAI_INTERMEDIATE[] = { APPLE_EXTENSION_AAI_INTERMEDIATE },
        OID_APPLE_EXTENSION_APPLEID_INTERMEDIATE[] = { APPLE_EXTENSION_APPLEID_INTERMEDIATE },
-       OID_APPLE_EXTENSION_APPLEID_SHARING[]   = { APPLE_EXTENSION_APPLEID_SHARING }
+       OID_APPLE_EXTENSION_APPLEID_SHARING[]   = { APPLE_EXTENSION_APPLEID_SHARING },
+       OID_APPLE_EXTENSION_SYSINT2_INTERMEDIATE[] = { APPLE_EXTENSION_SYSINT2_INTERMEDIATE },
+       OID_APPLE_EXTENSION_ESCROW_SERVICE[] = { APPLE_EXTENSION_ESCROW_SERVICE }
 ;
 
 #define OID_PKCS_CE_LENGTH     OID_EXTENSION_LENGTH + 1
 ;
 
 #define OID_PKCS_CE_LENGTH     OID_EXTENSION_LENGTH + 1
@@ -312,6 +320,10 @@ CSSMOID_APPLEID_CERT_POLICY                        = { APPLE_CERT_POLICIES_APPLEID_LENGTH,
                                                                                (uint8 *)OID_APPLE_CERT_POLICY_APPLEID },
 CSSMOID_APPLEID_SHARING_CERT_POLICY    = { APPLE_CERT_POLICIES_APPLEID_SHARING_LENGTH,
                                                                                (uint8 *)OID_APPLE_CERT_POLICY_APPLEID_SHARING },
                                                                                (uint8 *)OID_APPLE_CERT_POLICY_APPLEID },
 CSSMOID_APPLEID_SHARING_CERT_POLICY    = { APPLE_CERT_POLICIES_APPLEID_SHARING_LENGTH,
                                                                                (uint8 *)OID_APPLE_CERT_POLICY_APPLEID_SHARING },
+CSSMOID_MOBILE_STORE_SIGNING_POLICY = { APPLE_CERT_POLICIES_MOBILE_STORE_SIGNING_LENGTH,
+                                                                               (uint8 *)OID_APPLE_CERT_POLICY_MOBILE_STORE_SIGNING },
+CSSMOID_TEST_MOBILE_STORE_SIGNING_POLICY       = { APPLE_CERT_POLICIES_TEST_MOBILE_STORE_SIGNING_LENGTH,
+                                                                               (uint8 *)OID_APPLE_CERT_POLICY_TEST_MOBILE_STORE_SIGNING },
 CSSMOID_APPLE_EKU_CODE_SIGNING         = { APPLE_EKU_CODE_SIGNING_LENGTH,
                                                                                (uint8 *)OID_APPLE_EKU_CODE_SIGNING },
 CSSMOID_APPLE_EKU_CODE_SIGNING_DEV     = { APPLE_EKU_CODE_SIGNING_LENGTH + 1,
 CSSMOID_APPLE_EKU_CODE_SIGNING         = { APPLE_EKU_CODE_SIGNING_LENGTH,
                                                                                (uint8 *)OID_APPLE_EKU_CODE_SIGNING },
 CSSMOID_APPLE_EKU_CODE_SIGNING_DEV     = { APPLE_EKU_CODE_SIGNING_LENGTH + 1,
@@ -324,6 +336,12 @@ CSSMOID_APPLE_EKU_ICHAT_ENCRYPTION = { APPLE_EKU_OID_LENGTH + 1,
                                                                                (uint8 *)OID_APPLE_EKU_ICHAT_ENCRYPTION },
 CSSMOID_APPLE_EKU_SYSTEM_IDENTITY      = { APPLE_EKU_OID_LENGTH + 1,
                                                                                (uint8 *)OID_APPLE_EKU_SYSTEM_IDENTITY },
                                                                                (uint8 *)OID_APPLE_EKU_ICHAT_ENCRYPTION },
 CSSMOID_APPLE_EKU_SYSTEM_IDENTITY      = { APPLE_EKU_OID_LENGTH + 1,
                                                                                (uint8 *)OID_APPLE_EKU_SYSTEM_IDENTITY },
+CSSMOID_APPLE_EKU_PASSBOOK_SIGNING     = { APPLE_EKU_OID_LENGTH + 1,
+                                                                               (uint8 *)OID_APPLE_EKU_PASSBOOK_SIGNING },
+CSSMOID_APPLE_EKU_PROFILE_SIGNING      = { APPLE_EKU_OID_LENGTH + 1,
+                                                                               (uint8 *)OID_APPLE_EKU_PROFILE_SIGNING },
+CSSMOID_APPLE_EKU_QA_PROFILE_SIGNING   = { APPLE_EKU_OID_LENGTH + 1,
+                                                                               (uint8 *)OID_APPLE_EKU_QA_PROFILE_SIGNING },
 CSSMOID_APPLE_EXTENSION                                = { APPLE_EXTENSION_OID_LENGTH,
                                                                                (uint8 *)OID_APPLE_EXTENSION },
 CSSMOID_APPLE_EXTENSION_CODE_SIGNING           = { APPLE_EXTENSION_CODE_SIGNING_LENGTH,
 CSSMOID_APPLE_EXTENSION                                = { APPLE_EXTENSION_OID_LENGTH,
                                                                                (uint8 *)OID_APPLE_EXTENSION },
 CSSMOID_APPLE_EXTENSION_CODE_SIGNING           = { APPLE_EXTENSION_CODE_SIGNING_LENGTH,
@@ -334,31 +352,37 @@ CSSMOID_APPLE_EXTENSION_ADC_DEV_SIGNING           = { APPLE_EXTENSION_CODE_SIGNING_LENGTH
                                                                                                (uint8 *)OID_APPLE_EXTENSION_ADC_DEV_SIGNING },
 CSSMOID_APPLE_EXTENSION_ADC_APPLE_SIGNING      = { APPLE_EXTENSION_CODE_SIGNING_LENGTH + 3,
                                                                                                (uint8 *)OID_APPLE_EXTENSION_ADC_DEV_SIGNING },
                                                                                                (uint8 *)OID_APPLE_EXTENSION_ADC_DEV_SIGNING },
 CSSMOID_APPLE_EXTENSION_ADC_APPLE_SIGNING      = { APPLE_EXTENSION_CODE_SIGNING_LENGTH + 3,
                                                                                                (uint8 *)OID_APPLE_EXTENSION_ADC_DEV_SIGNING },
+CSSMOID_APPLE_EXTENSION_PASSBOOK_SIGNING       = { APPLE_EXTENSION_CODE_SIGNING_LENGTH + 1,
+                                                                                               (uint8 *)OID_APPLE_EXTENSION_PASSBOOK_SIGNING },
 CSSMOID_APPLE_EXTENSION_MACAPPSTORE_RECEIPT    = { APPLE_EXTENSION_MACAPPSTORE_RECEIPT_LENGTH,
                                                                                                (uint8 *)OID_APPLE_EXTENSION_MACAPPSTORE_RECEIPT },
 CSSMOID_APPLE_EXTENSION_INTERMEDIATE_MARKER   = { APPLE_EXTENSION_INTERMEDIATE_MARKER_LENGTH,
                                                                                                (uint8 *)OID_APPLE_EXTENSION_INTERMEDIATE_MARKER },
 CSSMOID_APPLE_EXTENSION_MACAPPSTORE_RECEIPT    = { APPLE_EXTENSION_MACAPPSTORE_RECEIPT_LENGTH,
                                                                                                (uint8 *)OID_APPLE_EXTENSION_MACAPPSTORE_RECEIPT },
 CSSMOID_APPLE_EXTENSION_INTERMEDIATE_MARKER   = { APPLE_EXTENSION_INTERMEDIATE_MARKER_LENGTH,
                                                                                                (uint8 *)OID_APPLE_EXTENSION_INTERMEDIATE_MARKER },
-CSSMOID_APPLE_EXTENSION_WWDR_INTERMEDIATE     = { APPLE_EXTENSION_WWDR_INTERMEDIATE_LENGTH + 1,
+CSSMOID_APPLE_EXTENSION_WWDR_INTERMEDIATE     = { APPLE_EXTENSION_WWDR_INTERMEDIATE_LENGTH,
                                                                                                (uint8 *)OID_APPLE_EXTENSION_WWDR_INTERMEDIATE },
                                                                                                (uint8 *)OID_APPLE_EXTENSION_WWDR_INTERMEDIATE },
-CSSMOID_APPLE_EXTENSION_ITMS_INTERMEDIATE     = { APPLE_EXTENSION_ITMS_INTERMEDIATE_LENGTH + 1,
+CSSMOID_APPLE_EXTENSION_ITMS_INTERMEDIATE     = { APPLE_EXTENSION_ITMS_INTERMEDIATE_LENGTH,
                                                                                                (uint8 *)OID_APPLE_EXTENSION_ITMS_INTERMEDIATE },
                                                                                                (uint8 *)OID_APPLE_EXTENSION_ITMS_INTERMEDIATE },
-CSSMOID_APPLE_EXTENSION_AAI_INTERMEDIATE      = { APPLE_EXTENSION_AAI_INTERMEDIATE_LENGTH + 1,
+CSSMOID_APPLE_EXTENSION_AAI_INTERMEDIATE      = { APPLE_EXTENSION_AAI_INTERMEDIATE_LENGTH,
                                                                                                (uint8 *)OID_APPLE_EXTENSION_AAI_INTERMEDIATE },
                                                                                                (uint8 *)OID_APPLE_EXTENSION_AAI_INTERMEDIATE },
-CSSMOID_APPLE_EXTENSION_APPLEID_INTERMEDIATE    = { APPLE_EXTENSION_APPLEID_INTERMEDIATE_LENGTH + 1,
+CSSMOID_APPLE_EXTENSION_APPLEID_INTERMEDIATE    = { APPLE_EXTENSION_APPLEID_INTERMEDIATE_LENGTH,
                                                                                                (uint8 *)OID_APPLE_EXTENSION_APPLEID_INTERMEDIATE },
                                                                                                (uint8 *)OID_APPLE_EXTENSION_APPLEID_INTERMEDIATE },
-CSSMOID_APPLE_EXTENSION_APPLEID_SHARING               = { APPLE_EXTENSION_APPLEID_INTERMEDIATE_LENGTH + 1,
-                                                                                               (uint8 *)OID_APPLE_EXTENSION_APPLEID_SHARING }
+CSSMOID_APPLE_EXTENSION_APPLEID_SHARING         = { APPLE_EXTENSION_APPLEID_SHARING_LENGTH + 1,
+                                                                                               (uint8 *)OID_APPLE_EXTENSION_APPLEID_SHARING },
+CSSMOID_APPLE_EXTENSION_SYSINT2_INTERMEDIATE    = { APPLE_EXTENSION_SYSINT2_INTERMEDIATE_LENGTH,
+                                                                                               (uint8 *)OID_APPLE_EXTENSION_SYSINT2_INTERMEDIATE },
+CSSMOID_APPLE_EXTENSION_ESCROW_SERVICE          = { APPLE_EXTENSION_ESCROW_SERVICE_LENGTH + 1,
+                                                                                               (uint8 *)OID_APPLE_EXTENSION_ESCROW_SERVICE }
 ;
 
 /* Apple Intermediate Marker OIDs */
 #define APPLE_CERT_EXT_INTERMEDIATE_MARKER APPLE_CERT_EXT, 2
 /* Apple Apple ID Intermediate Marker */
 #define APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID APPLE_CERT_EXT_INTERMEDIATE_MARKER, 3
 ;
 
 /* Apple Intermediate Marker OIDs */
 #define APPLE_CERT_EXT_INTERMEDIATE_MARKER APPLE_CERT_EXT, 2
 /* Apple Apple ID Intermediate Marker */
 #define APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID APPLE_CERT_EXT_INTERMEDIATE_MARKER, 3
-/* 
- *  Apple Apple ID Intermediate Marker (New subCA, no longer shared with push notification server cert issuer 
+/*
+ *  Apple Apple ID Intermediate Marker (New subCA, no longer shared with push notification server cert issuer
  *
  *
- *  appleCertificateExtensionAppleIDIntermediate ::= 
- *    { appleCertificateExtensionIntermediateMarker 7 }                                
+ *  appleCertificateExtensionAppleIDIntermediate ::=
+ *    { appleCertificateExtensionIntermediateMarker 7 }
  *    { 1 2 840 113635 100 6 2 7 }
  */
 #define APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID_2 APPLE_CERT_EXT_INTERMEDIATE_MARKER, 7
  *    { 1 2 840 113635 100 6 2 7 }
  */
 #define APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID_2 APPLE_CERT_EXT_INTERMEDIATE_MARKER, 7
@@ -372,7 +396,7 @@ CSSMOID_APPLE_EXTENSION_APPLEID_SHARING               = { APPLE_EXTENSION_APPLEI
  *     BER = 06 08 60 86 48 01 86 F8 42 01 01
  */
 static const uint8     OID_NetscapeCertType[]          = {NETSCAPE_CERT_EXTEN, 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        = 
+const CSSM_OID CSSMOID_NetscapeCertType        =
        {NETSCAPE_CERT_EXTEN_LENGTH + 1, (uint8 *)OID_NetscapeCertType};
 
 /*
        {NETSCAPE_CERT_EXTEN_LENGTH + 1, (uint8 *)OID_NetscapeCertType};
 
 /*
@@ -383,23 +407,23 @@ const CSSM_OID    CSSMOID_NetscapeCertType        =
 static const uint8  OID_NetscapeCertSequence[]  =  { NETSCAPE_BASE_OID, 2, 5 };
 const CSSM_OID CSSMOID_NetscapeCertSequence            =
        { NETSCAPE_BASE_OID_LEN + 2, (uint8 *)OID_NetscapeCertSequence };
 static const uint8  OID_NetscapeCertSequence[]  =  { NETSCAPE_BASE_OID, 2, 5 };
 const CSSM_OID CSSMOID_NetscapeCertSequence            =
        { NETSCAPE_BASE_OID_LEN + 2, (uint8 *)OID_NetscapeCertSequence };
-/* 
+
+/*
  * Netscape version of ServerGatedCrypto ExtendedKeyUse.
  * OID { 2 16 840 1 113730 4 1 }
  */
 static const uint8 OID_Netscape_SGC[] = {NETSCAPE_CERT_POLICY, 1};
  * Netscape version of ServerGatedCrypto ExtendedKeyUse.
  * OID { 2 16 840 1 113730 4 1 }
  */
 static const uint8 OID_Netscape_SGC[] = {NETSCAPE_CERT_POLICY, 1};
-const CSSM_OID CSSMOID_NetscapeSGC     = 
+const CSSM_OID CSSMOID_NetscapeSGC     =
        {NETSCAPE_CERT_POLICY_LENGTH + 1, (uint8 *)OID_Netscape_SGC};
 
        {NETSCAPE_CERT_POLICY_LENGTH + 1, (uint8 *)OID_Netscape_SGC};
 
-/* 
+/*
  * Microsoft version of ServerGatedCrypto ExtendedKeyUse.
  * OID { 1 3 6 1 4 1 311 10 3 3 }
  */
 static const uint8 OID_Microsoft_SGC[] = {0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x0A, 0x03, 0x03};
  * Microsoft version of ServerGatedCrypto ExtendedKeyUse.
  * OID { 1 3 6 1 4 1 311 10 3 3 }
  */
 static const uint8 OID_Microsoft_SGC[] = {0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x0A, 0x03, 0x03};
-const CSSM_OID CSSMOID_MicrosoftSGC    = 
+const CSSM_OID CSSMOID_MicrosoftSGC    =
        {10, (uint8 *)OID_Microsoft_SGC};
        {10, (uint8 *)OID_Microsoft_SGC};
-       
+
 /*
  * .mac Certificate Extended Key Use values.
  */
 /*
  * .mac Certificate Extended Key Use values.
  */
index 0731c7cae184e82975e10734e27af765cea8b693..ff50039fa5a1006d723b59bdb21a5d42d593beaa 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 1999-2004,2008 Apple Inc. All Rights Reserved.
- * 
+ * Copyright (c) 1999-2004,2008-2013 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  *
  * oidscert.h -- Object Identifiers for X509 Certificate Library
  * @APPLE_LICENSE_HEADER_END@
  *
  * oidscert.h -- Object Identifiers for X509 Certificate Library
@@ -54,135 +54,143 @@ extern "C" {
 /* Certificate OIDS */
 extern const CSSM_OID
 
 /* Certificate OIDS */
 extern const CSSM_OID
 
-       CSSMOID_X509V3SignedCertificate DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_X509V3SignedCertificateCStruct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_X509V3Certificate DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_X509V3CertificateCStruct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_X509V1Version DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_X509V1SerialNumber DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
+       CSSMOID_X509V3SignedCertificate DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_X509V3SignedCertificateCStruct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_X509V3Certificate DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_X509V3CertificateCStruct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_X509V1Version DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_X509V1SerialNumber DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_X509V1IssuerName DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,                         // normalized & encoded
        CSSMOID_X509V1IssuerNameStd DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,              // encoded
        CSSMOID_X509V1IssuerNameCStruct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,  // CSSM_X509_NAME
        CSSMOID_X509V1IssuerName DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,                         // normalized & encoded
        CSSMOID_X509V1IssuerNameStd DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,              // encoded
        CSSMOID_X509V1IssuerNameCStruct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,  // CSSM_X509_NAME
-       CSSMOID_X509V1IssuerNameLDAP DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_X509V1ValidityNotBefore DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_X509V1ValidityNotAfter DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
+       CSSMOID_X509V1IssuerNameLDAP DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_X509V1ValidityNotBefore DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_X509V1ValidityNotAfter DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_X509V1SubjectName DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,                        // normalized & encoded
        CSSMOID_X509V1SubjectNameStd DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,             // encoded
        CSSMOID_X509V1SubjectNameCStruct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,         // CSSM_X509_NAME
        CSSMOID_X509V1SubjectName DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,                        // normalized & encoded
        CSSMOID_X509V1SubjectNameStd DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,             // encoded
        CSSMOID_X509V1SubjectNameCStruct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,         // CSSM_X509_NAME
-       CSSMOID_X509V1SubjectNameLDAP DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_CSSMKeyStruct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_X509V1SubjectPublicKeyCStruct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_X509V1SubjectPublicKeyAlgorithm DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_X509V1SubjectPublicKeyAlgorithmParameters DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_X509V1SubjectPublicKey DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_X509V1CertificateIssuerUniqueId DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_X509V1CertificateSubjectUniqueId DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_X509V3CertificateExtensionsStruct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_X509V3CertificateExtensionsCStruct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_X509V3CertificateNumberOfExtensions DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_X509V3CertificateExtensionStruct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_X509V3CertificateExtensionCStruct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_X509V3CertificateExtensionId DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_X509V3CertificateExtensionCritical DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_X509V3CertificateExtensionType DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_X509V3CertificateExtensionValue DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       
+       CSSMOID_X509V1SubjectNameLDAP DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_CSSMKeyStruct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_X509V1SubjectPublicKeyCStruct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_X509V1SubjectPublicKeyAlgorithm DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_X509V1SubjectPublicKeyAlgorithmParameters DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_X509V1SubjectPublicKey DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_X509V1CertificateIssuerUniqueId DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_X509V1CertificateSubjectUniqueId DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_X509V3CertificateExtensionsStruct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_X509V3CertificateExtensionsCStruct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_X509V3CertificateNumberOfExtensions DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_X509V3CertificateExtensionStruct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_X509V3CertificateExtensionCStruct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_X509V3CertificateExtensionId DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_X509V3CertificateExtensionCritical DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_X509V3CertificateExtensionType DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_X509V3CertificateExtensionValue DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+
        /* Signature OID Fields */
        /* Signature OID Fields */
-       CSSMOID_X509V1SignatureStruct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_X509V1SignatureCStruct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_X509V1SignatureAlgorithm DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_X509V1SignatureAlgorithmTBS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_X509V1SignatureAlgorithmParameters DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_X509V1Signature DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       
+       CSSMOID_X509V1SignatureStruct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_X509V1SignatureCStruct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_X509V1SignatureAlgorithm DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_X509V1SignatureAlgorithmTBS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_X509V1SignatureAlgorithmParameters DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_X509V1Signature DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+
        /* Extension OID Fields */
        /* Extension OID Fields */
-       CSSMOID_SubjectSignatureBitmap DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_SubjectPicture DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_SubjectEmailAddress DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
+       CSSMOID_SubjectSignatureBitmap DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_SubjectPicture DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_SubjectEmailAddress DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_UseExemptions DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
 
        CSSMOID_UseExemptions DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
 
-/*** 
+/***
  *** Apple addenda
  ***/
  *** Apple addenda
  ***/
-/* 
+
+/*
  * Standard Cert and CRL extensions.
  */
 extern const CSSM_OID
  * Standard Cert and CRL extensions.
  */
 extern const CSSM_OID
-       CSSMOID_SubjectDirectoryAttributes DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_SubjectKeyIdentifier DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_KeyUsage DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_PrivateKeyUsagePeriod DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_SubjectAltName DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_IssuerAltName DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_BasicConstraints DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_CrlNumber DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_CrlReason DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_HoldInstructionCode DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_InvalidityDate DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_DeltaCrlIndicator DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_IssuingDistributionPoint DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_IssuingDistributionPoints DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_CertIssuer DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_NameConstraints DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_CrlDistributionPoints DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_CertificatePolicies DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_PolicyMappings DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_PolicyConstraints DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_AuthorityKeyIdentifier DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_ExtendedKeyUsage DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_InhibitAnyPolicy DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_AuthorityInfoAccess DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_BiometricInfo DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_QC_Statements DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_SubjectInfoAccess DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_ExtendedKeyUsageAny DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_ServerAuth DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_ClientAuth DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_ExtendedUseCodeSigning DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_EmailProtection DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_TimeStamping DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_OCSPSigning DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_KERBv5_PKINIT_KP_CLIENT_AUTH DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_KERBv5_PKINIT_KP_KDC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_EKU_IPSec DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_DOTMAC_CERT_EXTENSION DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_DOTMAC_CERT_IDENTITY DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_DOTMAC_CERT_EMAIL_SIGN DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_DOTMAC_CERT_EMAIL_ENCRYPT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_CERT_POLICY DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_DOTMAC_CERT_POLICY DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_ADC_CERT_POLICY DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
+       CSSMOID_SubjectDirectoryAttributes DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_SubjectKeyIdentifier DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_KeyUsage DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_PrivateKeyUsagePeriod DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_SubjectAltName DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_IssuerAltName DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_BasicConstraints DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_CrlNumber DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_CrlReason DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_HoldInstructionCode DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_InvalidityDate DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_DeltaCrlIndicator DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_IssuingDistributionPoint DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_IssuingDistributionPoints DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_CertIssuer DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_NameConstraints DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_CrlDistributionPoints DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_CertificatePolicies DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_PolicyMappings DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_PolicyConstraints DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_AuthorityKeyIdentifier DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_ExtendedKeyUsage DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_InhibitAnyPolicy DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_AuthorityInfoAccess DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_BiometricInfo DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_QC_Statements DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_SubjectInfoAccess DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_ExtendedKeyUsageAny DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_ServerAuth DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_ClientAuth DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_ExtendedUseCodeSigning DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_EmailProtection DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_TimeStamping DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_OCSPSigning DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_KERBv5_PKINIT_KP_CLIENT_AUTH DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_KERBv5_PKINIT_KP_KDC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_EKU_IPSec DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_DOTMAC_CERT_EXTENSION DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_DOTMAC_CERT_IDENTITY DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_DOTMAC_CERT_EMAIL_SIGN DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_DOTMAC_CERT_EMAIL_ENCRYPT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_CERT_POLICY DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_DOTMAC_CERT_POLICY DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_ADC_CERT_POLICY DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_MACAPPSTORE_CERT_POLICY DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_MACAPPSTORE_RECEIPT_CERT_POLICY DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_APPLEID_CERT_POLICY DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_APPLEID_SHARING_CERT_POLICY DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_MACAPPSTORE_CERT_POLICY DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_MACAPPSTORE_RECEIPT_CERT_POLICY DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_APPLEID_CERT_POLICY DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_APPLEID_SHARING_CERT_POLICY DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
-       CSSMOID_APPLE_EKU_CODE_SIGNING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,  
-       CSSMOID_APPLE_EKU_CODE_SIGNING_DEV DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_EKU_RESOURCE_SIGNING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_EKU_ICHAT_SIGNING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_EKU_ICHAT_ENCRYPTION DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_EKU_SYSTEM_IDENTITY DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_EXTENSION DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_EXTENSION_CODE_SIGNING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_EXTENSION_APPLE_SIGNING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_APPLE_EXTENSION_ADC_DEV_SIGNING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
+       CSSMOID_MOBILE_STORE_SIGNING_POLICY DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_TEST_MOBILE_STORE_SIGNING_POLICY DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_EKU_CODE_SIGNING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_EKU_CODE_SIGNING_DEV DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_EKU_RESOURCE_SIGNING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_EKU_ICHAT_SIGNING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_EKU_ICHAT_ENCRYPTION DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_EKU_SYSTEM_IDENTITY DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_EKU_PASSBOOK_SIGNING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_EKU_PROFILE_SIGNING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_EKU_QA_PROFILE_SIGNING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_EXTENSION DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_EXTENSION_CODE_SIGNING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_EXTENSION_APPLE_SIGNING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_EXTENSION_ADC_DEV_SIGNING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_APPLE_EXTENSION_ADC_APPLE_SIGNING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_APPLE_EXTENSION_ADC_APPLE_SIGNING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_EXTENSION_PASSBOOK_SIGNING  DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_APPLE_EXTENSION_MACAPPSTORE_RECEIPT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_APPLE_EXTENSION_INTERMEDIATE_MARKER DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_APPLE_EXTENSION_WWDR_INTERMEDIATE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_APPLE_EXTENSION_ITMS_INTERMEDIATE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_APPLE_EXTENSION_AAI_INTERMEDIATE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_APPLE_EXTENSION_APPLEID_INTERMEDIATE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_APPLE_EXTENSION_MACAPPSTORE_RECEIPT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_APPLE_EXTENSION_INTERMEDIATE_MARKER DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_APPLE_EXTENSION_WWDR_INTERMEDIATE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_APPLE_EXTENSION_ITMS_INTERMEDIATE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_APPLE_EXTENSION_AAI_INTERMEDIATE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_APPLE_EXTENSION_APPLEID_INTERMEDIATE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
-       CSSMOID_APPLE_EXTENSION_APPLEID_SHARING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
+       CSSMOID_APPLE_EXTENSION_APPLEID_SHARING DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_EXTENSION_SYSINT2_INTERMEDIATE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_APPLE_EXTENSION_ESCROW_SERVICE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
 ;
 ;
-       
+
 /*
  * Netscape extensions.
  */
 /*
  * Netscape extensions.
  */
-extern const CSSM_OID  
-       CSSMOID_NetscapeCertType DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
-       CSSMOID_NetscapeCertSequence DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, 
+extern const CSSM_OID
+       CSSMOID_NetscapeCertType DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
+       CSSMOID_NetscapeCertSequence DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,
        CSSMOID_NetscapeSGC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
 
 extern const CSSM_OID CSSMOID_MicrosoftSGC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
        CSSMOID_NetscapeSGC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
 
 extern const CSSM_OID CSSMOID_MicrosoftSGC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
@@ -190,7 +198,7 @@ extern const CSSM_OID CSSMOID_MicrosoftSGC DEPRECATED_IN_MAC_OS_X_VERSION_10_7_A
 /*
  * Field values for CSSMOID_NetscapeCertType DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,  a bit string.
  * Assumes a 16 bit field, even though currently only 8 bits
 /*
  * Field values for CSSMOID_NetscapeCertType DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER,  a bit string.
  * Assumes a 16 bit field, even though currently only 8 bits
- * are defined. 
+ * are defined.
  */
 #define CE_NCT_SSL_Client      0x8000
 #define CE_NCT_SSL_Server      0x4000
  */
 #define CE_NCT_SSL_Client      0x8000
 #define CE_NCT_SSL_Server      0x4000
index 7b2165812c4e774d1d073d05140539a6c3ea3373..b57487a13a5632d3f2f244370d861f547ae0d59c 100644 (file)
@@ -173,7 +173,7 @@ CSSM_CSP_CreateRandomGenContext (CSSM_CSP_HANDLE CSPHandle,
     maker.setup(Length, CSSMERR_CSP_INVALID_ATTR_OUTPUT_SIZE);
     maker.make();
     maker.put(CSSM_ATTRIBUTE_SEED, 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);
+    maker.put(CSSM_ATTRIBUTE_OUTPUT_SIZE, (uint32_t)Length);
     Required(NewContextHandle) = maker(CSSM_ALGCLASS_RANDOMGEN, AlgorithmID);
     END_API(CSSM)
 }
     Required(NewContextHandle) = maker(CSSM_ALGCLASS_RANDOMGEN, AlgorithmID);
     END_API(CSSM)
 }
@@ -291,7 +291,8 @@ CSSM_GetContext (CSSM_CC_HANDLE CCHandle,
                  CSSM_CONTEXT_PTR *ContextP)
 {
     BEGIN_API
                  CSSM_CONTEXT_PTR *ContextP)
 {
     BEGIN_API
-    HandleContext &context = HandleObject::find<HandleContext>(CCHandle, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE);
+#warning Cast from CSSM_CC_HANDLE to CSSM_HANDLE
+    HandleContext &context = HandleObject::find<HandleContext>((CSSM_HANDLE)CCHandle, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE);
     Context *newContext = new(context.attachment) Context(context.type(), context.algorithm());
     try {
         newContext->CSPHandle = context.attachment.handle();
     Context *newContext = new(context.attachment) Context(context.type(), context.algorithm());
     try {
         newContext->CSPHandle = context.attachment.handle();
@@ -325,7 +326,8 @@ CSSM_SetContext (CSSM_CC_HANDLE CCHandle,
 {
     BEGIN_API
     const Context &source = Context::required(ContextP);
 {
     BEGIN_API
     const Context &source = Context::required(ContextP);
-    HandleContext &context = HandleObject::find<HandleContext>(CCHandle, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE);
+#warning Cast from CSSM_CC_HANDLE to CSSM_HANDLE
+    HandleContext &context = HandleObject::find<HandleContext>((CSSM_HANDLE)CCHandle, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE);
 
     CSSM_CONTEXT_ATTRIBUTE *oldAttributes = context.ContextAttributes;
     uint32 oldCount = context.NumberOfAttributes;
 
     CSSM_CONTEXT_ATTRIBUTE *oldAttributes = context.ContextAttributes;
     uint32 oldCount = context.NumberOfAttributes;
@@ -390,7 +392,8 @@ CSSM_UpdateContextAttributes (CSSM_CC_HANDLE CCHandle,
                               const CSSM_CONTEXT_ATTRIBUTE *ContextAttributes)
 {
     BEGIN_API
                               const CSSM_CONTEXT_ATTRIBUTE *ContextAttributes)
 {
     BEGIN_API
-    HandleContext &context = HandleObject::find<HandleContext>(CCHandle, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE);
+#warning Cast from CSSM_CC_HANDLE to CSSM_HANDLE
+    HandleContext &context = HandleObject::find<HandleContext>((CSSM_HANDLE)CCHandle, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE);
     context.mergeAttributes(ContextAttributes, NumberAttributes);
     END_API(CSSM)
 }
     context.mergeAttributes(ContextAttributes, NumberAttributes);
     END_API(CSSM)
 }
@@ -405,7 +408,8 @@ CSSM_DeleteContextAttributes (CSSM_CC_HANDLE CCHandle,
     if (NumberOfAttributes == 0)
         return CSSM_OK;        // I suppose
     Required(ContextAttributes); // preflight
     if (NumberOfAttributes == 0)
         return CSSM_OK;        // I suppose
     Required(ContextAttributes); // preflight
-    HandleContext &context = HandleObject::find<HandleContext>(CCHandle, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE);
+#warning Cast from CSSM_CC_HANDLE to CSSM_HANDLE
+    HandleContext &context = HandleObject::find<HandleContext>((CSSM_HANDLE)CCHandle, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE);
     for (uint32 n = 0; n < NumberOfAttributes; n++)
         context.deleteAttribute(ContextAttributes[n].AttributeType);
     END_API(CSSM)
     for (uint32 n = 0; n < NumberOfAttributes; n++)
         context.deleteAttribute(ContextAttributes[n].AttributeType);
     END_API(CSSM)
@@ -421,7 +425,8 @@ CSSM_DigestDataClone (CSSM_CC_HANDLE ccHandle,
                       CSSM_CC_HANDLE *newCCHandle)
 {
        BEGIN_API
                       CSSM_CC_HANDLE *newCCHandle)
 {
        BEGIN_API
-    HandleContext &context = HandleObject::findAndLock<HandleContext>(ccHandle, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE);
+#warning Cast from CSSM_CC_HANDLE to CSSM_HANDLE
+    HandleContext &context = HandleObject::findAndLock<HandleContext>((CSSM_HANDLE)ccHandle, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE);
        TransitLock _(context.attachment);
     HandleContext *newContext =
        new(context.attachment) HandleContext(context.attachment, context.type(), context.algorithm());
        TransitLock _(context.attachment);
     HandleContext *newContext =
        new(context.attachment) HandleContext(context.attachment, context.type(), context.algorithm());
index 3683c4ff514753a3d62443e6674124c4b1bfc550..05657e73717e9d8fcf6dd56f52865b8329d1649f 100644 (file)
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0420;
+                               LastUpgradeCheck = 0500;
                        };
                        buildConfigurationList = C27AD3480987FCDE001272E0 /* Build configuration list for PBXProject "libsecurity_cssm" */;
                        compatibilityVersion = "Xcode 3.2";
                        };
                        buildConfigurationList = C27AD3480987FCDE001272E0 /* Build configuration list for PBXProject "libsecurity_cssm" */;
                        compatibilityVersion = "Xcode 3.2";
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1879B4A2146DAE33007E536C /* debug.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1879B4A2146DAE33007E536C /* debug.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                                       "-Wno-error=#warnings",
+                                       "$(inherited)",
+                               );
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1879B4A4146DAE33007E536C /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1879B4A4146DAE33007E536C /* release.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                                       "-Wno-error=#warnings",
+                                       "$(inherited)",
+                               );
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1879B4A3146DAE33007E536C /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1879B4A3146DAE33007E536C /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1879B4A3146DAE33007E536C /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1879B4A3146DAE33007E536C /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
index dbe9ecec611c45a294d432ad28bfd2426fe5e2ad..4d640ebd15f6561b8abb251ea386944da9792089 100644 (file)
@@ -540,7 +540,7 @@ ModifiedTable::writeIndexSection(WriteSection &tableSection, uint32 offset)
        uint32 indexSectionOffset = offset;
        offset += AtomSize;
        
        uint32 indexSectionOffset = offset;
        offset += AtomSize;
        
-       offset = tableSection.put(offset, mIndexMap.size());
+       offset = tableSection.put(offset, (uint32)mIndexMap.size());
        
        // leave room for the array of offsets to the indexes
        uint32 indexOffsetOffset = offset;
        
        // leave room for the array of offsets to the indexes
        uint32 indexOffsetOffset = offset;
@@ -871,7 +871,7 @@ DbVersion::DbVersion(const AppleDatabase &db, const RefPointer <AtomicBufferedFi
        off_t bytesRead = 0;
        const uint8 *ptr = mBufferedFile->read(0, aLength, bytesRead);
        mBufferedFile->close();
        off_t bytesRead = 0;
        const uint8 *ptr = mBufferedFile->read(0, aLength, bytesRead);
        mBufferedFile->close();
-       mDatabase = ReadSection(ptr, bytesRead);
+       mDatabase = ReadSection(ptr, (size_t)bytesRead);
        open();
 }
 
        open();
 }
 
@@ -1424,7 +1424,7 @@ DbModifier::getDbVersion(bool force)
             off_t bytesRead = 0;
             const uint8 *ptr = atomicBufferedFile->read(length - AtomSize,
                 AtomSize, bytesRead);
             off_t bytesRead = 0;
             const uint8 *ptr = atomicBufferedFile->read(length - AtomSize,
                 AtomSize, bytesRead);
-            ReadSection aVersionSection(ptr, bytesRead);
+            ReadSection aVersionSection(ptr, (size_t)bytesRead);
             uint32 aVersionId = aVersionSection[0];
 
             /* If the version stamp hasn't changed the old mDbVersion is still
             uint32 aVersionId = aVersionSection[0];
 
             /* If the version stamp hasn't changed the old mDbVersion is still
@@ -1650,7 +1650,7 @@ DbModifier::writeAuthSection(uint32 inSectionOffset)
 uint32
 DbModifier::writeSchemaSection(uint32 inSectionOffset)
 {
 uint32
 DbModifier::writeSchemaSection(uint32 inSectionOffset)
 {
-       uint32 aTableCount = mModifiedTableMap.size();
+       uint32 aTableCount = (uint32) mModifiedTableMap.size();
        WriteSection aTableSection(Allocator::standard(),
                                                           OffsetTables + AtomSize * aTableCount);
        // Set aTableSection to the correct size.
        WriteSection aTableSection(Allocator::standard(),
                                                           OffsetTables + AtomSize * aTableCount);
        // Set aTableSection to the correct size.
index 1c37c4da3b0f422963a684bb5ce8440738dc71ec..7ff71756842fbb383d297196aff532e7a2b4540d 100644 (file)
@@ -72,7 +72,7 @@ AtomicFile::AtomicFile(const std::string &inPath) :
                        // compute the name of the lock file for this file
                        CC_SHA1_CTX ctx;
                        CC_SHA1_Init(&ctx);
                        // compute the name of the lock file for this file
                        CC_SHA1_CTX ctx;
                        CC_SHA1_Init(&ctx);
-                       CC_SHA1_Update(&ctx, (const void*) mFile.c_str(), mFile.length());
+                       CC_SHA1_Update(&ctx, (const void*) mFile.c_str(), (CC_LONG)mFile.length());
                        u_int8_t digest[CC_SHA1_DIGEST_LENGTH];
                        CC_SHA1_Final(digest, &ctx);
 
                        u_int8_t digest[CC_SHA1_DIGEST_LENGTH];
                        CC_SHA1_Final(digest, &ctx);
 
@@ -230,54 +230,49 @@ AtomicFile::pathSplit(const std::string &inFull, std::string &outDir, std::strin
        }
 }
 
        }
 }
 
-static std::string RemoveDoubleSlashes(const std::string &path)
-{
-       std::string result;
-       unsigned i;
-       for (i = 0; i < path.length(); ++i)
-       {
-               result += path[i];
-               if ((i < path.length() - 2) && path[i] == '/' && path[i + 1] == '/')
-               {
-                       i += 1; // skip a second '/'
-               }
-       }
-       
-       return result;
-}
-
-
-
 //
 // Make sure the directory up to inDir exists inDir *must* end in a slash.
 //
 void
 AtomicFile::mkpath(const std::string &inDir, mode_t mode)
 {
 //
 // Make sure the directory up to inDir exists inDir *must* end in a slash.
 //
 void
 AtomicFile::mkpath(const std::string &inDir, mode_t mode)
 {
-       for (std::string::size_type pos = 0; (pos = inDir.find('/', pos + 1)) != std::string::npos;)
-       {
-               std::string path = inDir.substr(0, pos);
-               const char *cpath = path.c_str();
-               struct stat sb;
-               if (::stat(cpath, &sb))
-               {
-                       // if we are creating a path in the user's home directory, override the user's mode
-                       std::string homedir = getenv("HOME");
-                       
-                       // canonicalize the path (remove double slashes)
-                       string canonPath = RemoveDoubleSlashes(cpath);
-                       
-                       if (canonPath.find(homedir, 0) == 0)
-                       {
-                               mode = 0700;
-                       }
-                       
-                       if (errno != ENOENT || ::mkdir(cpath, mode))
-                               UnixError::throwMe(errno);
-               }
-               else if (!S_ISDIR(sb.st_mode))
-                       CssmError::throwMe(CSSM_ERRCODE_OS_ACCESS_DENIED);  // @@@ Should be is a directory
-       }
+    // see if the file already exists and is a directory
+    struct stat st;
+    int result = stat(inDir.c_str(), &st);
+    
+    if (result == 0) // file exists
+    {
+        if ((st.st_mode & S_IFDIR) == 0)
+        {
+            // whatever was there, it wasn't a directory.  That's really bad, so complain
+            syslog(LOG_ALERT, "Needed a directory at %s, but the file that was there was not one.\n", inDir.c_str());
+            UnixError::throwMe(ENOTDIR);
+        }
+    }
+    else
+    {
+        // the file did not exist, try to create it
+        result = mkpath_np(inDir.c_str(), 0777); // make the directory with umask
+        if (result != 0)
+        {
+            // mkpath_np does not set errno, you have to look at the result.
+            UnixError::throwMe(result);
+        }
+    }
+    
+    // Double check and see if we got what we hoped for
+    result = stat(inDir.c_str(), &st);
+    if (result != 0)
+    {
+        UnixError::throwMe(errno);
+    }
+    
+    if ((st.st_mode & S_IFDIR) == 0)
+    {
+        // we didn't create a dictionary?  That's curious...
+        syslog(LOG_ALERT, "Failed to create a directory when we asked for one to be created at %s\n", inDir.c_str());
+        UnixError::throwMe(ENOTDIR);
+    }
 }
 
 int
 }
 
 int
@@ -465,7 +460,7 @@ AtomicBufferedFile::unloadBuffer()
        }
        else
        {
        }
        else
        {
-               munmap(mBuffer, mLength);
+               munmap(mBuffer, (size_t)mLength);
        }
 }
 
        }
 }
 
@@ -483,7 +478,7 @@ AtomicBufferedFile::loadBuffer()
                lseek(mFileRef, 0, SEEK_SET);
                ssize_t pos = 0;
                
                lseek(mFileRef, 0, SEEK_SET);
                ssize_t pos = 0;
                
-               ssize_t bytesToRead = mLength;
+               ssize_t bytesToRead = (ssize_t)mLength;
                while (bytesToRead > 0)
                {
                        ssize_t bytesRead = ::read(mFileRef, mBuffer + pos, bytesToRead);
                while (bytesToRead > 0)
                {
                        ssize_t bytesRead = ::read(mFileRef, mBuffer + pos, bytesToRead);
@@ -507,7 +502,7 @@ AtomicBufferedFile::loadBuffer()
        else
        {
                // mmap the buffer into place
        else
        {
                // mmap the buffer into place
-               mBuffer = (uint8*) mmap(NULL, mLength, PROT_READ, MAP_PRIVATE, mFileRef, 0);
+               mBuffer = (uint8*) mmap(NULL, (size_t)mLength, PROT_READ, MAP_PRIVATE, mFileRef, 0);
                if (mBuffer == (uint8*) -1)
                {
                        int error = errno;
                if (mBuffer == (uint8*) -1)
                {
                        int error = errno;
@@ -546,7 +541,7 @@ AtomicBufferedFile::read(off_t inOffset, off_t inLength, off_t &outLength)
        
        secdebug("atomicfile", "%p allocated %s buffer %p size %qd", this, mPath.c_str(), mBuffer, bytesLeft);
        
        
        secdebug("atomicfile", "%p allocated %s buffer %p size %qd", this, mPath.c_str(), mBuffer, bytesLeft);
        
-       ssize_t maxEnd = inOffset + inLength;
+       off_t maxEnd = inOffset + inLength;
        if (maxEnd > mLength)
        {
                maxEnd = mLength;
        if (maxEnd > mLength)
        {
                maxEnd = mLength;
@@ -616,7 +611,7 @@ AtomicTempFile::create(mode_t mode)
     
     // put the dir into a canonical form
     string dir = mFile.dir();
     
     // put the dir into a canonical form
     string dir = mFile.dir();
-    int i = dir.length() - 1;
+    int i = (int)dir.length() - 1;
     
     // walk backwards until we get to a non / character
     while (i >= 0 && dir[i] == '/')
     
     // walk backwards until we get to a non / character
     while (i >= 0 && dir[i] == '/')
index 9625505596e717eb40f075deed0fd57b94bd114b..eb94691a1a40301e935fd1bae577720950a3c850 100644 (file)
@@ -55,10 +55,10 @@ public:
        // Return a bufferedFile containing current version of the file for reading.
        RefPointer<AtomicBufferedFile> read();
 
        // Return a bufferedFile containing current version of the file for reading.
        RefPointer<AtomicBufferedFile> read();
 
-       string path() const { return mPath; }
-       string dir() const { return mDir; }
-       string file() const { return mFile; }
-       string lockFileName() { return mLockFilePath; }
+       const string& path() const { return mPath; }
+       const string& dir() const { return mDir; }
+       const string& file() const { return mFile; }
+       const string& lockFileName() { return mLockFilePath; }
 
        mode_t mode() const;
        bool isOnLocalFileSystem() {return mIsLocalFileSystem;}
 
        mode_t mode() const;
        bool isOnLocalFileSystem() {return mIsLocalFileSystem;}
index f476af5e561ba26c95cba1bd211dcb1ecf0d8807..d31a87752ce0cd786bb63a54369b0ef5c522cb58 100644 (file)
@@ -87,7 +87,7 @@ DbIndexKey::operator < (const DbIndexKey &other) const
 {
        // compare the values of the attributes in the keys
        
 {
        // compare the values of the attributes in the keys
        
-       uint32 numAttributes = mIndex.mAttributes.size();
+       uint32 numAttributes = (uint32) mIndex.mAttributes.size();
        uint32 valueOffset1 = 0, valueOffset2 = 0;
        
        for (uint32 i = 0; i < numAttributes; i++) {
        uint32 valueOffset1 = 0, valueOffset2 = 0;
        
        for (uint32 i = 0; i < numAttributes; i++) {
@@ -204,7 +204,7 @@ DbConstIndex::matchesQuery(const CSSM_QUERY &query, DbQueryKey *&queryKey) const
        // 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
        
        // 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;
+       long lastIndex;
        for (lastIndex = mAttributes.size() - 1; (lastIndex >= 0) && (attributeUsed[lastIndex] == ~(uint32)0);
                lastIndex--);
                
        for (lastIndex = mAttributes.size() - 1; (lastIndex >= 0) && (attributeUsed[lastIndex] == ~(uint32)0);
                lastIndex--);
                
@@ -311,8 +311,8 @@ DbMutableIndex::DbMutableIndex(const DbConstIndex &index)
        
        const ReadSection &tableSection = index.mTable.getTableSection();
        
        
        const ReadSection &tableSection = index.mTable.getTableSection();
        
-       uint32 numRecords = index.mKeyOffsetVector.size();
-       for (uint32 i = 0; i < numRecords; i++) {
+       size_t numRecords = index.mKeyOffsetVector.size();
+       for (size_t i = 0; i < numRecords; i++) {
                uint32 recordNumber = index.mRecordNumberVector.at(i);
                uint32 keyOffset = index.mKeyOffsetVector.at(i);
                uint32 keySize = tableSection.at(keyOffset);
                uint32 recordNumber = index.mRecordNumberVector.at(i);
                uint32 keyOffset = index.mKeyOffsetVector.at(i);
                uint32 keySize = tableSection.at(keyOffset);
@@ -356,10 +356,10 @@ DbMutableIndex::insertRecord(uint32 recordNumber, const ReadSection &packedRecor
        // the record; detect and handle this separately since we can avoid an
        // expensive recursive technique.
        
        // the record; detect and handle this separately since we can avoid an
        // expensive recursive technique.
        
-       uint32 numAttributes = mAttributes.size();
+       size_t numAttributes = mAttributes.size();
        bool allSingleValued = true;
        
        bool allSingleValued = true;
        
-       for (uint32 i = 0; i < numAttributes; i++) {
+       for (size_t 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,
                uint32 numValues = mAttributes[i]->getNumberOfValues(packedRecord);
                if (numValues == 0) {
                        // record does not have value required by index; for a unique index,
@@ -447,11 +447,11 @@ DbMutableIndex::writeIndex(WriteSection &ws, uint32 offset)
        offset = ws.put(offset, mIndexId);
        offset = ws.put(offset, mIsUniqueIndex ? 1 : 0);
        
        offset = ws.put(offset, mIndexId);
        offset = ws.put(offset, mIsUniqueIndex ? 1 : 0);
        
-       offset = ws.put(offset, mAttributes.size());
+       offset = ws.put(offset, (uint32)mAttributes.size());
        for (uint32 i = 0; i < mAttributes.size(); i++)
                offset = ws.put(offset, mAttributes[i]->attributeId());
 
        for (uint32 i = 0; i < mAttributes.size(); i++)
                offset = ws.put(offset, mAttributes[i]->attributeId());
 
-       offset = ws.put(offset, mMap.size());
+       offset = ws.put(offset, (uint32)mMap.size());
        
        // reserve space for the array of offsets to key data
        uint32 keyPtrOffset = offset;
        
        // reserve space for the array of offsets to key data
        uint32 keyPtrOffset = offset;
index fba7fc0b4c7a3db04a9217f72ea3efa9469c9726..47e924e7102f2d422fadddfd06f691741dc68754 100644 (file)
@@ -113,7 +113,7 @@ SInt32Value::pack(WriteSection &ws, uint32 &offset) const
 
 DoubleValue::DoubleValue(const ReadSection &rs, uint32 &offset)
 {
 
 DoubleValue::DoubleValue(const ReadSection &rs, uint32 &offset)
 {
-       Range r(offset, size());
+       Range r(offset, (uint32)size());
        mValue = *reinterpret_cast<const double *>(rs.range(r));
        offset += size();
 }
        mValue = *reinterpret_cast<const double *>(rs.range(r));
        offset += size();
 }
@@ -140,7 +140,7 @@ DoubleValue::~DoubleValue()
 void
 DoubleValue::pack(WriteSection &ws, uint32 &offset) const
 {
 void
 DoubleValue::pack(WriteSection &ws, uint32 &offset) const
 {
-       offset = ws.put(offset, size(), bytes());
+       offset = ws.put(offset, (uint32)size(), bytes());
 }
 
 //
 }
 
 //
@@ -150,8 +150,8 @@ DoubleValue::pack(WriteSection &ws, uint32 &offset) const
 BlobValue::BlobValue(const ReadSection &rs, uint32 &offset)
 {
        Length = rs.at(offset);
 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);
+       Data = const_cast<uint8 *>(rs.range(Range(offset + AtomSize, (uint32)Length)));
+       offset = ReadSection::align((uint32)(offset + Length + AtomSize));
 }
 
 BlobValue::BlobValue(const CSSM_DATA &data)
 }
 
 BlobValue::BlobValue(const CSSM_DATA &data)
@@ -166,8 +166,8 @@ BlobValue::~BlobValue()
 void
 BlobValue::pack(WriteSection &ws, uint32 &offset) const
 {
 void
 BlobValue::pack(WriteSection &ws, uint32 &offset) const
 {
-       offset = ws.put(offset, Length);
-       offset = ws.put(offset, Length, Data);
+       offset = ws.put(offset, (uint32)Length);
+       offset = ws.put(offset, (uint32)Length, Data);
 }
 
 BlobValue::Comparator::~Comparator()
 }
 
 BlobValue::Comparator::~Comparator()
@@ -190,7 +190,7 @@ bool
 BlobValue::evaluate(const CssmData &inData1, const CssmData &inData2, CSSM_DB_OPERATOR op,
        Comparator compare)
 {
 BlobValue::evaluate(const CssmData &inData1, const CssmData &inData2, CSSM_DB_OPERATOR op,
        Comparator compare)
 {
-       uint32 length1 = inData1.Length, length2 = inData2.Length;
+       uint32 length1 = (uint32)inData1.Length, length2 = (uint32)inData2.Length;
        const uint8 *data1 = inData1.Data;
        const uint8 *data2 = inData2.Data;
        
        const uint8 *data1 = inData1.Data;
        const uint8 *data2 = inData2.Data;
        
@@ -262,8 +262,8 @@ BlobValue::evaluate(const CssmData &inData1, const CssmData &inData2, CSSM_DB_OP
 TimeDateValue::TimeDateValue(const ReadSection &rs, uint32 &offset)
 {
        Length = kTimeDateSize;
 TimeDateValue::TimeDateValue(const ReadSection &rs, uint32 &offset)
 {
        Length = kTimeDateSize;
-       Data = const_cast<uint8 *>(rs.range(Range(offset, Length)));
-       offset = ReadSection::align(offset + Length);
+       Data = const_cast<uint8 *>(rs.range(Range(offset, (uint32)Length)));
+       offset = ReadSection::align(offset + (uint32)Length);
 }
 
 TimeDateValue::TimeDateValue(const CSSM_DATA &data)
 }
 
 TimeDateValue::TimeDateValue(const CSSM_DATA &data)
@@ -280,7 +280,7 @@ TimeDateValue::~TimeDateValue()
 void
 TimeDateValue::pack(WriteSection &ws, uint32 &offset) const
 {
 void
 TimeDateValue::pack(WriteSection &ws, uint32 &offset) const
 {
-       offset = ws.put(offset, Length, Data);
+       offset = ws.put(offset, (uint32)Length, Data);
 }
 
 bool
 }
 
 bool
@@ -303,15 +303,15 @@ TimeDateValue::isValidDate() const
                return false;
                
        uint32 hour = rangeValue(8, 2);
                return false;
                
        uint32 hour = rangeValue(8, 2);
-       if (hour < 0 || hour > 23)
+       if (hour > 23)
                return false;
                
        uint32 minute = rangeValue(10, 2);
                return false;
                
        uint32 minute = rangeValue(10, 2);
-       if (minute < 0 || minute > 59)
+       if (minute > 59)
                return false;
 
        uint32 second = rangeValue(12, 2);
                return false;
 
        uint32 second = rangeValue(12, 2);
-       if (second < 0 || second > 59)
+       if (second > 59)
                return false;           
 
        return true;
                return false;           
 
        return true;
@@ -403,7 +403,7 @@ BigNumValue::compare(const uint8 *a, const uint8 *b, int length)
 bool
 BigNumValue::evaluate(const BigNumValue &other, CSSM_DB_OPERATOR op) const
 {
 bool
 BigNumValue::evaluate(const BigNumValue &other, CSSM_DB_OPERATOR op) const
 {
-       uint32 length1 = Length, length2 = other.Length;
+       uint32 length1 = (uint32)Length, length2 = (uint32)other.Length;
        uint8 sign1 = length1 ? (Data[0] & kSignBit) : 0;
        uint8 sign2 = length2 ? (other.Data[0] & kSignBit) : 0;
        
        uint8 sign1 = length1 ? (Data[0] & kSignBit) : 0;
        uint8 sign2 = length2 ? (other.Data[0] & kSignBit) : 0;
        
@@ -470,7 +470,7 @@ MultiUInt32Value::MultiUInt32Value(const CSSM_DATA &data)
        if (data.Length & (sizeof(uint32) - 1))
                CssmError::throwMe(CSSMERR_DL_INVALID_VALUE);
                
        if (data.Length & (sizeof(uint32) - 1))
                CssmError::throwMe(CSSMERR_DL_INVALID_VALUE);
                
-       mNumValues = data.Length / sizeof(uint32);
+       mNumValues = (uint32)(data.Length / sizeof(uint32));
        mValues = reinterpret_cast<uint32 *>(data.Data);
        mOwnsValues = false;
 }
        mValues = reinterpret_cast<uint32 *>(data.Data);
        mOwnsValues = false;
 }
index d5ee1be467cf6441be7fa9fb1173ec51f589e931..9fc54a90b0bcb7c0b3fd02ea2e47cef0cd0f541f 100644 (file)
@@ -128,7 +128,7 @@ MetaRecord::createAttribute(const string *inAttributeName,
                                                        CSSM_DB_ATTRIBUTE_FORMAT inAttributeFormat)
 {
        // Index of new element is current size of vector
                                                        CSSM_DB_ATTRIBUTE_FORMAT inAttributeFormat)
 {
        // Index of new element is current size of vector
-    uint32 anAttributeIndex = mAttributeVector.size();
+    uint32 anAttributeIndex = (uint32)mAttributeVector.size();
     bool aInsertedAttributeName = false;
     bool aInsertedAttributeOID = false;
     bool aInsertedAttributeID = false;
     bool aInsertedAttributeName = false;
     bool aInsertedAttributeOID = false;
     bool aInsertedAttributeID = false;
@@ -180,12 +180,12 @@ MetaRecord::packRecord(WriteSection &inWriteSection,
 {
     uint32 aDataSize;
     if (inData)
 {
     uint32 aDataSize;
     if (inData)
-        aDataSize = inData->Length;
+        aDataSize = (uint32)inData->Length;
     else
         aDataSize = 0;
 
     inWriteSection.put(OffsetDataSize, aDataSize);
     else
         aDataSize = 0;
 
     inWriteSection.put(OffsetDataSize, aDataSize);
-    uint32 anOffset = OffsetAttributeOffsets + AtomSize * mAttributeVector.size();
+    uint32 anOffset = (uint32)(OffsetAttributeOffsets + AtomSize * mAttributeVector.size());
     if (aDataSize)
         anOffset = inWriteSection.put(anOffset, aDataSize, inData->Data);
 
     if (aDataSize)
         anOffset = inWriteSection.put(anOffset, aDataSize, inData->Data);
 
@@ -451,7 +451,7 @@ MetaRecord::updateRecord(const ReadSection &inReadSection,
        if (inData)
        {
                // prepare to write new data
        if (inData)
        {
                // prepare to write new data
-        aDataSize = inData->Length;
+        aDataSize = (uint32)inData->Length;
                aDataData = inData->Data;
        }
     else
                aDataData = inData->Data;
        }
     else
@@ -464,7 +464,7 @@ MetaRecord::updateRecord(const ReadSection &inReadSection,
        }
 
        // compute the data offset; this will keep a running total of the record size
        }
 
        // compute the data offset; this will keep a running total of the record size
-    uint32 anOffset = OffsetAttributeOffsets + AtomSize * mAttributeVector.size();
+        uint32 anOffset = (uint32)(OffsetAttributeOffsets + AtomSize * mAttributeVector.size());
        
        // write the appropriate data to the new record
        inWriteSection.put(OffsetDataSize, aDataSize);
        
        // write the appropriate data to the new record
        inWriteSection.put(OffsetDataSize, aDataSize);
@@ -475,7 +475,7 @@ MetaRecord::updateRecord(const ReadSection &inReadSection,
        
        auto_array<CssmDbAttributeData> attributeData(mAttributeVector.size());
 
        
        auto_array<CssmDbAttributeData> attributeData(mAttributeVector.size());
 
-       for (uint32 anAttributeIndex = mAttributeVector.size(); anAttributeIndex-- > 0; )
+       for (size_t anAttributeIndex = mAttributeVector.size(); anAttributeIndex-- > 0; )
        {
                // unpack the old attribute data for this attribute index
                const MetaAttribute &attribute = *mAttributeVector[anAttributeIndex];
        {
                // unpack the old attribute data for this attribute index
                const MetaAttribute &attribute = *mAttributeVector[anAttributeIndex];
index 610ccb0651b5230258bee46bfe2034647d04b5eb..b71a77dda696585bf909cc2ba4f9e9797c6f5b4c 100644 (file)
@@ -99,7 +99,7 @@ public:
 
        Range dataRange(const ReadSection &inReadSection) const
        {
 
        Range dataRange(const ReadSection &inReadSection) const
        {
-        return Range(OffsetAttributeOffsets + mAttributeVector.size() * AtomSize,
+        return Range((uint32)(OffsetAttributeOffsets + mAttributeVector.size() * AtomSize),
                                         inReadSection[OffsetDataSize]);
        }
 
                                         inReadSection[OffsetDataSize]);
        }
 
index be2a5e7559ae575b00e7eaedb0fde50b4a2fd33e..de095ea9db9dc24e39c0f074cad57e74b0278085 100644 (file)
@@ -45,7 +45,7 @@ uint32 WriteSection::put(uint32 inOffset, uint32 inLength, const uint8 *inData)
 
 void WriteSection::grow(size_t inNewCapacity)
 {
 
 void WriteSection::grow(size_t inNewCapacity)
 {
-       size_t n = CheckUInt32Multiply(mCapacity, 2);
+       size_t n = CheckUInt32Multiply((uint32)mCapacity, 2);
        size_t aNewCapacity = max(n, inNewCapacity);
        mAddress = reinterpret_cast<uint8 *>(mAllocator.realloc(mAddress, aNewCapacity));
        memset(mAddress + mCapacity, 0, aNewCapacity - mCapacity);
        size_t aNewCapacity = max(n, inNewCapacity);
        mAddress = reinterpret_cast<uint8 *>(mAllocator.realloc(mAddress, aNewCapacity));
        memset(mAddress + mCapacity, 0, aNewCapacity - mCapacity);
index 10f971fa144bfb43aa5ae235ac43143ff878d1ef..8c5240fa7ddbd03b8fb487ed69ab928e3411bb68 100644 (file)
@@ -72,7 +72,7 @@ public:
     ReadSection(const uint8 *inAddress, size_t inLength) :
            mAddress(const_cast<uint8 *>(inAddress)), mLength(inLength) {}
                
     ReadSection(const uint8 *inAddress, size_t inLength) :
            mAddress(const_cast<uint8 *>(inAddress)), mLength(inLength) {}
                
-    uint32 size() const { return mLength; }
+    uint32 size() const { return (uint32)mLength; }
 
     uint32 at(uint32 inOffset) const
     {
 
     uint32 at(uint32 inOffset) const
     {
index 2937d1ec5280806bf148b92ef786a2b6033f2c01..244133c7a3f9b126b728a47a7a15f3997b0aab8c 100644 (file)
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0420;
+                               LastUpgradeCheck = 0500;
                        };
                        buildConfigurationList = C27AD3600987FCDE001272E0 /* Build configuration list for PBXProject "libsecurity_filedb" */;
                        compatibilityVersion = "Xcode 3.2";
                        };
                        buildConfigurationList = C27AD3600987FCDE001272E0 /* Build configuration list for PBXProject "libsecurity_filedb" */;
                        compatibilityVersion = "Xcode 3.2";
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB207146F043D000BF1F3 /* debug.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB207146F043D000BF1F3 /* debug.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB209146F043D000BF1F3 /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB209146F043D000BF1F3 /* release.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB208146F043D000BF1F3 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB208146F043D000BF1F3 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB208146F043D000BF1F3 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB208146F043D000BF1F3 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
diff --git a/libsecurity_keychain/Security b/libsecurity_keychain/Security
new file mode 120000 (symlink)
index 0000000..945c9b4
--- /dev/null
@@ -0,0 +1 @@
+.
\ No newline at end of file
index a3bb5de2ecbf0900ef504776fe346dfc1a362df4..150ca350493f5fd0c96e5457c97c0147e89e4cc7 100644 (file)
@@ -412,7 +412,7 @@ void ACL::makeSubject()
        case appListForm: {
                // threshold(1 of n+1) of { app1, ..., appn, PROMPT }
                chunkFree(mSubjectForm, allocator);     // release previous
        case appListForm: {
                // threshold(1 of n+1) of { app1, ..., appn, PROMPT }
                chunkFree(mSubjectForm, allocator);     // release previous
-               uint32 appCount = mAppList.size();
+               uint32 appCount = (uint32)mAppList.size();
                mSubjectForm = new(allocator) TypedList(allocator, CSSM_ACL_SUBJECT_TYPE_THRESHOLD,
                        new(allocator) ListElement(1),
                        new(allocator) ListElement(appCount + 1));
                mSubjectForm = new(allocator) TypedList(allocator, CSSM_ACL_SUBJECT_TYPE_THRESHOLD,
                        new(allocator) ListElement(1),
                        new(allocator) ListElement(appCount + 1));
index a4cb3672d1e62417d52db76cc0004f67fd04bd47..cd76f67d2a192f90023a123020ad9e693ef3e467 100644 (file)
@@ -31,7 +31,7 @@
 #include <security_cdsa_utilities/uniformrandom.h>
 #include <security_cdsa_client/aclclient.h>
 #include <vector>
 #include <security_cdsa_utilities/uniformrandom.h>
 #include <security_cdsa_client/aclclient.h>
 #include <vector>
-
+#include <SecBase.h>
 using namespace KeychainCore;
 using namespace CssmClient;
 
 using namespace KeychainCore;
 using namespace CssmClient;
 
@@ -240,7 +240,7 @@ void Access::copyOwnerAndAcl(CSSM_ACL_OWNER_PROTOTYPE * &ownerResult,
 {
        StLock<Mutex>_(mMutex);
        Allocator& alloc = Allocator::standard();
 {
        StLock<Mutex>_(mMutex);
        Allocator& alloc = Allocator::standard();
-       int count = mAcls.size() - 1;   // one will be owner, others are acls
+       unsigned long count = mAcls.size() - 1; // one will be owner, others are acls
        AclOwnerPrototype owner;
        CssmAutoPtr<AclEntryInfo> acls = new(alloc) AclEntryInfo[count];
        AclEntryInfo *aclp = acls;      // -> next unfilled acl element
        AclOwnerPrototype owner;
        CssmAutoPtr<AclEntryInfo> acls = new(alloc) AclEntryInfo[count];
        AclEntryInfo *aclp = acls;      // -> next unfilled acl element
@@ -258,7 +258,7 @@ void Access::copyOwnerAndAcl(CSSM_ACL_OWNER_PROTOTYPE * &ownerResult,
 
        // commit output
        ownerResult = new(alloc) AclOwnerPrototype(owner);
 
        // commit output
        ownerResult = new(alloc) AclOwnerPrototype(owner);
-       aclCount = count;
+       aclCount = (uint32)count;
        aclsResult = acls.release();
 }
 
        aclsResult = acls.release();
 }
 
@@ -297,7 +297,7 @@ void Access::add(ACL *newAcl)
 {
        StLock<Mutex>_(mMutex);
        if (&newAcl->access != this)
 {
        StLock<Mutex>_(mMutex);
        if (&newAcl->access != this)
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
        assert(!mAcls[newAcl->entryHandle()]);
        mAcls[newAcl->entryHandle()] = newAcl;
 }
        assert(!mAcls[newAcl->entryHandle()]);
        mAcls[newAcl->entryHandle()] = newAcl;
 }
index 07a49e6a8d83656f13e026c8647307d4b270fde3..6c9320bc9b504090891a33521426dc5d64a6a2c9 100644 (file)
@@ -35,7 +35,6 @@
 #include <algorithm>
 #include <list>
 
 #include <algorithm>
 #include <list>
 
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
 #include "Globals.h"
 #include <security_keychain/SecCFTypes.h>
 #include <securityd_client/SharedMemoryCommon.h>
 #include "Globals.h"
 #include <security_keychain/SecCFTypes.h>
 #include <securityd_client/SharedMemoryCommon.h>
@@ -161,7 +160,7 @@ void CCallbackMgr::AlertClients(const list<CallbackInfo> &eventCallbacks,
                                 const Item &inItem)
 {
     secdebug("kcnotify", "dispatch event %ld pid %d keychain %p item %p",
                                 const Item &inItem)
 {
     secdebug("kcnotify", "dispatch event %ld pid %d keychain %p item %p",
-        inEvent, inPid, &inKeychain, !!inItem ? &*inItem : NULL);
+        (unsigned long)inEvent, inPid, &inKeychain, !!inItem ? &*inItem : NULL);
 
        // Iterate through callbacks, looking for those registered for inEvent
        const SecKeychainEventMask theMask = 1U << inEvent;
 
        // Iterate through callbacks, looking for those registered for inEvent
        const SecKeychainEventMask theMask = 1U << inEvent;
index b035ff9af2e40062df6a4bd6d1f801484dec753f..93eb0aa1a42c0f04cea2bc68c091099d37d53fa8 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2002-2007 Apple Inc. All Rights Reserved.
+ * Copyright (c) 2002-2007,2012 Apple Inc. All Rights Reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -34,9 +34,8 @@
 #include <security_keychain/KeyItem.h>
 #include <security_keychain/KCCursor.h>
 #include <vector>
 #include <security_keychain/KeyItem.h>
 #include <security_keychain/KCCursor.h>
 #include <vector>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
-//#include "CLFieldsCommon.h"
-
+#include <CommonCrypto/CommonDigestSPI.h>
+#include <SecBase.h>
 
 using namespace KeychainCore;
 
 
 using namespace KeychainCore;
 
@@ -50,16 +49,17 @@ Certificate::Certificate(const CSSM_DATA &data, CSSM_CERT_TYPE type, CSSM_CERT_E
        ItemImpl(CSSM_DL_DB_RECORD_X509_CERTIFICATE, reinterpret_cast<SecKeychainAttributeList *>(NULL), UInt32(data.Length), reinterpret_cast<const void *>(data.Data)),
        mHaveTypeAndEncoding(true),
        mPopulated(false),
        ItemImpl(CSSM_DL_DB_RECORD_X509_CERTIFICATE, reinterpret_cast<SecKeychainAttributeList *>(NULL), UInt32(data.Length), reinterpret_cast<const void *>(data.Data)),
        mHaveTypeAndEncoding(true),
        mPopulated(false),
-    mType(type),
-    mEncoding(encoding),
-    mCL(clForType(type)),
+       mType(type),
+       mEncoding(encoding),
+       mCL(clForType(type)),
        mCertHandle(0),
        mV1SubjectPublicKeyCStructValue(NULL),
        mCertHandle(0),
        mV1SubjectPublicKeyCStructValue(NULL),
-    mV1SubjectNameCStructValue(NULL),
-    mV1IssuerNameCStructValue(NULL)
+       mV1SubjectNameCStructValue(NULL),
+       mV1IssuerNameCStructValue(NULL),
+       mSha1Hash(NULL)
 {
        if (data.Length == 0 || data.Data == NULL)
 {
        if (data.Length == 0 || data.Data == NULL)
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
 }
 
 // db item constructor
 }
 
 // db item constructor
@@ -67,11 +67,12 @@ Certificate::Certificate(const Keychain &keychain, const PrimaryKey &primaryKey,
        ItemImpl(keychain, primaryKey, uniqueId),
        mHaveTypeAndEncoding(false),
        mPopulated(false),
        ItemImpl(keychain, primaryKey, uniqueId),
        mHaveTypeAndEncoding(false),
        mPopulated(false),
-    mCL(NULL),
+       mCL(NULL),
        mCertHandle(0),
        mV1SubjectPublicKeyCStructValue(NULL),
        mCertHandle(0),
        mV1SubjectPublicKeyCStructValue(NULL),
-    mV1SubjectNameCStructValue(NULL),
-    mV1IssuerNameCStructValue(NULL)
+       mV1SubjectNameCStructValue(NULL),
+       mV1IssuerNameCStructValue(NULL),
+       mSha1Hash(NULL)
 {
 }
 
 {
 }
 
@@ -101,11 +102,12 @@ Certificate::Certificate(const Keychain &keychain, const PrimaryKey &primaryKey)
        ItemImpl(keychain, primaryKey),
        mHaveTypeAndEncoding(false),
        mPopulated(false),
        ItemImpl(keychain, primaryKey),
        mHaveTypeAndEncoding(false),
        mPopulated(false),
-    mCL(NULL),
+       mCL(NULL),
        mCertHandle(0),
        mV1SubjectPublicKeyCStructValue(NULL),
        mCertHandle(0),
        mV1SubjectPublicKeyCStructValue(NULL),
-    mV1SubjectNameCStructValue(NULL),
-    mV1IssuerNameCStructValue(NULL)
+       mV1SubjectNameCStructValue(NULL),
+       mV1IssuerNameCStructValue(NULL),
+       mSha1Hash(NULL)
 {
        // @@@ In this case we don't know the type...
 }
 {
        // @@@ In this case we don't know the type...
 }
@@ -114,17 +116,19 @@ Certificate::Certificate(Certificate &certificate) :
        ItemImpl(certificate),
        mHaveTypeAndEncoding(certificate.mHaveTypeAndEncoding),
        mPopulated(false /* certificate.mPopulated */),
        ItemImpl(certificate),
        mHaveTypeAndEncoding(certificate.mHaveTypeAndEncoding),
        mPopulated(false /* certificate.mPopulated */),
-    mType(certificate.mType),
-    mEncoding(certificate.mEncoding),
-    mCL(certificate.mCL),
+       mType(certificate.mType),
+       mEncoding(certificate.mEncoding),
+       mCL(certificate.mCL),
        mCertHandle(0),
        mV1SubjectPublicKeyCStructValue(NULL),
        mCertHandle(0),
        mV1SubjectPublicKeyCStructValue(NULL),
-    mV1SubjectNameCStructValue(NULL),
-    mV1IssuerNameCStructValue(NULL)
+       mV1SubjectNameCStructValue(NULL),
+       mV1IssuerNameCStructValue(NULL),
+       mSha1Hash(NULL)
 {
 }
 
 {
 }
 
-Certificate::~Certificate() throw()
+Certificate::~Certificate()
+try
 {
        if (mV1SubjectPublicKeyCStructValue)
                releaseFieldValue(CSSMOID_X509V1SubjectPublicKeyCStruct, mV1SubjectPublicKeyCStructValue);
 {
        if (mV1SubjectPublicKeyCStructValue)
                releaseFieldValue(CSSMOID_X509V1SubjectPublicKeyCStruct, mV1SubjectPublicKeyCStructValue);
@@ -132,11 +136,17 @@ Certificate::~Certificate() throw()
        if (mCertHandle && mCL)
                CSSM_CL_CertAbortCache(mCL->handle(), mCertHandle);
 
        if (mCertHandle && mCL)
                CSSM_CL_CertAbortCache(mCL->handle(), mCertHandle);
 
-    if (mV1SubjectNameCStructValue)
-        releaseFieldValue(CSSMOID_X509V1SubjectNameCStruct, mV1SubjectNameCStructValue);
+       if (mV1SubjectNameCStructValue)
+               releaseFieldValue(CSSMOID_X509V1SubjectNameCStruct, mV1SubjectNameCStructValue);
+
+       if (mV1IssuerNameCStructValue)
+               releaseFieldValue(CSSMOID_X509V1IssuerNameCStruct, mV1IssuerNameCStructValue);
 
 
-    if (mV1IssuerNameCStructValue)
-        releaseFieldValue(CSSMOID_X509V1IssuerNameCStruct, mV1IssuerNameCStructValue);
+       if (mSha1Hash)
+               CFRelease(mSha1Hash);
+}
+catch (...)
+{
 }
 
 CSSM_HANDLE
 }
 
 CSSM_HANDLE
@@ -711,7 +721,7 @@ Certificate::data()
                /* new data allocated by CSPDL, implicitly freed by CssmDataContainer */
                mUniqueId->get(NULL, &_data);
                /* this saves a copy to be freed at destruction and to be passed to caller */
                /* new data allocated by CSPDL, implicitly freed by CssmDataContainer */
                mUniqueId->get(NULL, &_data);
                /* this saves a copy to be freed at destruction and to be passed to caller */
-               setData(_data.length(), _data.data());
+               setData((UInt32)_data.length(), _data.data());
                return *mData.get();
        }
 
                return *mData.get();
        }
 
@@ -722,6 +732,12 @@ Certificate::data()
        return *data;
 }
 
        return *data;
 }
 
+CFHashCode Certificate::hash()
+{
+       (void)data();  // ensure that mData is set up
+       return ItemImpl::hash();
+}
+
 CSSM_CERT_TYPE
 Certificate::type()
 {
 CSSM_CERT_TYPE
 Certificate::type()
 {
@@ -766,6 +782,27 @@ Certificate::algorithmID()
        return algid;
 }
 
        return algid;
 }
 
+CFDataRef
+Certificate::sha1Hash()
+{
+       StLock<Mutex>_(mMutex);
+       if (!mSha1Hash) {
+               SecCertificateRef certRef = handle(false);
+               CFAllocatorRef allocRef = (certRef) ? CFGetAllocator(certRef) : NULL;
+               CSSM_DATA certData = data();
+               if (certData.Length == 0 || !certData.Data) {
+                       MacOSError::throwMe(errSecDataNotAvailable);
+               }
+               const UInt8 *dataPtr = (const UInt8 *)certData.Data;
+               CFIndex dataLen = (CFIndex)certData.Length;
+               CFMutableDataRef digest = CFDataCreateMutable(allocRef, CC_SHA1_DIGEST_LENGTH);
+               CFDataSetLength(digest, CC_SHA1_DIGEST_LENGTH);
+               CCDigest(kCCDigestSHA1, dataPtr, dataLen, CFDataGetMutableBytePtr(digest));
+               mSha1Hash = digest;
+       }
+       return mSha1Hash; /* object is owned by our instance; caller should NOT release it */
+}
+
 CFStringRef
 Certificate::commonName()
 {
 CFStringRef
 Certificate::commonName()
 {
@@ -918,12 +955,6 @@ Certificate::operator == (Certificate &other)
        return data() == other.data();
 }
 
        return data() == other.data();
 }
 
-bool
-Certificate::equal(SecCFObject &other)
-{
-    return (*this) == (Certificate &)other;
-}
-
 void
 Certificate::update()
 {
 void
 Certificate::update()
 {
@@ -1247,13 +1278,13 @@ Boolean Certificate::isSelfSigned()
        StLock<Mutex>_(mMutex);
        CSSM_DATA_PTR issuer = NULL;
        CSSM_DATA_PTR subject = NULL;
        StLock<Mutex>_(mMutex);
        CSSM_DATA_PTR issuer = NULL;
        CSSM_DATA_PTR subject = NULL;
-       OSStatus ortn = noErr;
+       OSStatus ortn = errSecSuccess;
        Boolean brtn = false;
 
        issuer  = copyFirstFieldValue(CSSMOID_X509V1IssuerNameStd);
        subject = copyFirstFieldValue(CSSMOID_X509V1SubjectNameStd);
        if((issuer == NULL) || (subject == NULL)) {
        Boolean brtn = false;
 
        issuer  = copyFirstFieldValue(CSSMOID_X509V1IssuerNameStd);
        subject = copyFirstFieldValue(CSSMOID_X509V1SubjectNameStd);
        if((issuer == NULL) || (subject == NULL)) {
-               ortn = paramErr;
+               ortn = errSecParam;
        }
        else if((issuer->Length == subject->Length) &&
                !memcmp(issuer->Data, subject->Data, issuer->Length)) {
        }
        else if((issuer->Length == subject->Length) &&
                !memcmp(issuer->Data, subject->Data, issuer->Length)) {
index 320dc7f4ab2fcb76ffdf9992084903279e78ea88..7731b45578e043d9bba8e3ee5a697be012542f0e 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2002-2007 Apple Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2002-2007,2012 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -65,7 +65,7 @@ public:
        static Certificate* make(const Keychain &keychain, const PrimaryKey &primaryKey);
 
        Certificate(Certificate &certificate);
        static Certificate* make(const Keychain &keychain, const PrimaryKey &primaryKey);
 
        Certificate(Certificate &certificate);
-    virtual ~Certificate() throw();
+    virtual ~Certificate();
 
        virtual void update();
        virtual Item copyTo(const Keychain &keychain, Access *newAccess = NULL);
 
        virtual void update();
        virtual Item copyTo(const Keychain &keychain, Access *newAccess = NULL);
@@ -74,6 +74,7 @@ public:
     const CssmData &data();
     CSSM_CERT_TYPE type();
        CSSM_CERT_ENCODING encoding();
     const CssmData &data();
     CSSM_CERT_TYPE type();
        CSSM_CERT_ENCODING encoding();
+       CFDataRef sha1Hash();
        CFStringRef commonName();
        CFStringRef distinguishedName(const CSSM_OID *sourceOid, const CSSM_OID *componentOid);
        CFStringRef copyFirstEmailAddress();
        CFStringRef commonName();
        CFStringRef distinguishedName(const CSSM_OID *sourceOid, const CSSM_OID *componentOid);
        CFStringRef copyFirstEmailAddress();
@@ -102,8 +103,8 @@ public:
 
        bool operator < (Certificate &other);
        bool operator == (Certificate &other);
 
        bool operator < (Certificate &other);
        bool operator == (Certificate &other);
-
-       bool equal(SecCFObject &other);
+       
+       virtual CFHashCode hash();
 
 public:
        CSSM_DATA_PTR copyFirstFieldValue(const CSSM_OID &field);
 
 public:
        CSSM_DATA_PTR copyFirstFieldValue(const CSSM_OID &field);
@@ -137,6 +138,7 @@ private:
        CSSM_DATA_PTR mV1SubjectPublicKeyCStructValue; // Hack to prevent algorithmID() from leaking.
     CSSM_DATA_PTR mV1SubjectNameCStructValue;
     CSSM_DATA_PTR mV1IssuerNameCStructValue;
        CSSM_DATA_PTR mV1SubjectPublicKeyCStructValue; // Hack to prevent algorithmID() from leaking.
     CSSM_DATA_PTR mV1SubjectNameCStructValue;
     CSSM_DATA_PTR mV1IssuerNameCStructValue;
+       CFDataRef mSha1Hash;
 };
 
 } // end namespace KeychainCore
 };
 
 } // end namespace KeychainCore
index 6bd86579e8d7db75fd2cc21fc5da0cee4aea8c1d..44b834007ccb0ca98b786d3006cdc5213adef5d3 100644 (file)
 #include <Security/SecKey.h>
 #include <Security/SecKeyPriv.h>
 #include <Security/cssmapi.h>
 #include <Security/SecKey.h>
 #include <Security/SecKeyPriv.h>
 #include <Security/cssmapi.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 #include <string.h>
 #include <dotMacTp.h>
 #include <Security/oidsattr.h>
 #include <security_utilities/simpleprefs.h>
 #include <string.h>
 #include <dotMacTp.h>
 #include <Security/oidsattr.h>
 #include <security_utilities/simpleprefs.h>
+#include <SecBase.h>
 
 /* one top-level prefs file for all of .mac cert requests */
 #define DOT_MAC_REQ_PREFS      "com.apple.security.certreq"
 
 /* one top-level prefs file for all of .mac cert requests */
 #define DOT_MAC_REQ_PREFS      "com.apple.security.certreq"
@@ -66,6 +66,7 @@
 /*
  * Compare two CSSM_DATAs (or two CSSM_OIDs), return true if identical.
  */
 /*
  * Compare two CSSM_DATAs (or two CSSM_OIDs), return true if identical.
  */
+static
 bool nssCompareCssmData(
        const CSSM_DATA *data1,
        const CSSM_DATA *data2)
 bool nssCompareCssmData(
        const CSSM_DATA *data1,
        const CSSM_DATA *data2)
@@ -166,7 +167,7 @@ CertificateRequest::CertificateRequest(const CSSM_OID &policy,
             nssCompareCssmData(&CSSMOID_DOTMAC_CERT_REQ_EMAIL_ENCRYPT, &policy) ||
             nssCompareCssmData(&CSSMOID_DOTMAC_CERT_REQ_SHARED_SERVICES, &policy))) {
                certReqDbg("CertificateRequest(): unknown policy oid");
             nssCompareCssmData(&CSSMOID_DOTMAC_CERT_REQ_EMAIL_ENCRYPT, &policy) ||
             nssCompareCssmData(&CSSMOID_DOTMAC_CERT_REQ_SHARED_SERVICES, &policy))) {
                certReqDbg("CertificateRequest(): unknown policy oid");
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
        }
        if(privateKeyItemRef) {
                mPrivKey = privateKeyItemRef;
        }
        if(privateKeyItemRef) {
                mPrivKey = privateKeyItemRef;
@@ -187,7 +188,7 @@ CertificateRequest::CertificateRequest(const CSSM_OID &policy,
                const SecCertificateRequestAttribute *attr = &attributeList->attr[dex];
                
                if((attr->oid.Data == NULL) || (attr->value.Data == NULL)) {
                const SecCertificateRequestAttribute *attr = &attributeList->attr[dex];
                
                if((attr->oid.Data == NULL) || (attr->value.Data == NULL)) {
-                       MacOSError::throwMe(paramErr);
+                       MacOSError::throwMe(errSecParam);
                }
                if(nssCompareCssmData(&CSSMOID_DOTMAC_CERT_REQ_VALUE_USERNAME, &attr->oid)) {
             CSSM_DATA userName = { 0, NULL };
                }
                if(nssCompareCssmData(&CSSMOID_DOTMAC_CERT_REQ_VALUE_USERNAME, &attr->oid)) {
             CSSM_DATA userName = { 0, NULL };
@@ -225,7 +226,7 @@ CertificateRequest::CertificateRequest(const CSSM_OID &policy,
                
                else {
                        certReqDbg("CertificateRequest(): unknown name/value oid");
                
                else {
                        certReqDbg("CertificateRequest(): unknown name/value oid");
-                       MacOSError::throwMe(paramErr);
+                       MacOSError::throwMe(errSecParam);
                }
        }
        if(mCertState == CRS_Reconstructed) {
                }
        }
        if(mCertState == CRS_Reconstructed) {
@@ -280,7 +281,7 @@ void CertificateRequest::submit(
                /* shouldn't be here, we already validated policy in constructor */
                assert(0);
                certReqDbg("CertificateRequest::submit(): bad policy");
                /* shouldn't be here, we already validated policy in constructor */
                assert(0);
                certReqDbg("CertificateRequest::submit(): bad policy");
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
        }
 }
 
        }
 }
 
@@ -305,17 +306,17 @@ void CertificateRequest::submitDotMac(
        
        if(mCertState != CRS_New) {
                certReqDbg("CertificateRequest: can only submit a new request");
        
        if(mCertState != CRS_New) {
                certReqDbg("CertificateRequest: can only submit a new request");
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
        }
        if((mUserName.data() == NULL) || (mPassword.data() == NULL)) {
                certReqDbg("CertificateRequest: user name and password required");
        }
        if((mUserName.data() == NULL) || (mPassword.data() == NULL)) {
                certReqDbg("CertificateRequest: user name and password required");
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
        }
 
        /* get keys and CSP handle in CSSM terms */
        if((mPrivKey == NULL) || (mPubKey == NULL)) {
                certReqDbg("CertificateRequest: pub and priv keys required");
        }
 
        /* get keys and CSP handle in CSSM terms */
        if((mPrivKey == NULL) || (mPubKey == NULL)) {
                certReqDbg("CertificateRequest: pub and priv keys required");
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
        }
        ortn = SecKeyGetCSSMKey(mPrivKey, &privKey);
        if(ortn) {
        }
        ortn = SecKeyGetCSSMKey(mPrivKey, &privKey);
        if(ortn) {
@@ -338,8 +339,8 @@ void CertificateRequest::submitDotMac(
        tvp.type = CSSMOID_CommonName;
        tvp.valueType = BER_TAG_PKIX_UTF8_STRING;
        CssmAutoData fullUserName(mAlloc);
        tvp.type = CSSMOID_CommonName;
        tvp.valueType = BER_TAG_PKIX_UTF8_STRING;
        CssmAutoData fullUserName(mAlloc);
-       unsigned nameLen = mUserName.length();
-       unsigned domainLen = mDomain.length();
+       size_t nameLen = mUserName.length();
+       size_t domainLen = mDomain.length();
        fullUserName.malloc(nameLen + 1 + domainLen);
        tvp.value = fullUserName.get();
        memmove(tvp.value.Data, mUserName.data(), nameLen);
        fullUserName.malloc(nameLen + 1 + domainLen);
        tvp.value = fullUserName.get();
        memmove(tvp.value.Data, mUserName.data(), nameLen);
@@ -483,7 +484,7 @@ void CertificateRequest::getResult(
                /* shouldn't be here, we already validated policy in constructor */
                assert(0);
                certReqDbg("CertificateRequest::getResult(): bad policy");
                /* shouldn't be here, we already validated policy in constructor */
                assert(0);
                certReqDbg("CertificateRequest::getResult(): bad policy");
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
        }
 }
 
        }
 }
 
@@ -539,22 +540,22 @@ void CertificateRequest::getResultDotMac(
                        }
                        if(resultSet == NULL) {
                                certReqDbg("***CSSM_TP_RetrieveCredResult OK, but no result set");
                        }
                        if(resultSet == NULL) {
                                certReqDbg("***CSSM_TP_RetrieveCredResult OK, but no result set");
-                               MacOSError::throwMe(internalComponentErr);
+                               MacOSError::throwMe(errSecInternalComponent);
                        }
                        if(resultSet->NumberOfResults != 1) {
                                certReqDbg("***CSSM_TP_RetrieveCredResult OK, NumberOfResults (%lu)",
                                        (unsigned long)resultSet->NumberOfResults);
                        }
                        if(resultSet->NumberOfResults != 1) {
                                certReqDbg("***CSSM_TP_RetrieveCredResult OK, NumberOfResults (%lu)",
                                        (unsigned long)resultSet->NumberOfResults);
-                               MacOSError::throwMe(internalComponentErr);
+                               MacOSError::throwMe(errSecInternalComponent);
                        }
                        if(resultSet->Results == NULL) {
                                certReqDbg("***CSSM_TP_RetrieveCredResult OK, but empty result set");
                        }
                        if(resultSet->Results == NULL) {
                                certReqDbg("***CSSM_TP_RetrieveCredResult OK, but empty result set");
-                               MacOSError::throwMe(internalComponentErr);
+                               MacOSError::throwMe(errSecInternalComponent);
                        }
                        certReqDbg("getResultDotMac: polled server, SUCCESS");
                        CSSM_DATA_PTR result = (CSSM_DATA_PTR)resultSet->Results;
                        if(result->Data == NULL) {
                                certReqDbg("***CSSM_TP_RetrieveCredResult OK, but empty result");
                        }
                        certReqDbg("getResultDotMac: polled server, SUCCESS");
                        CSSM_DATA_PTR result = (CSSM_DATA_PTR)resultSet->Results;
                        if(result->Data == NULL) {
                                certReqDbg("***CSSM_TP_RetrieveCredResult OK, but empty result");
-                               MacOSError::throwMe(internalComponentErr);
+                               MacOSError::throwMe(errSecInternalComponent);
                        }
                        mCertData.copy(*result);
                        certData = mCertData.get();
                        }
                        mCertData.copy(*result);
                        certData = mCertData.get();
@@ -575,7 +576,7 @@ void CertificateRequest::getResultDotMac(
                default:
                        /* what do we do with this? */
                        certReqDbg("CertificateRequest::getResultDotMac(): bad state");
                default:
                        /* what do we do with this? */
                        certReqDbg("CertificateRequest::getResultDotMac(): bad state");
-                       MacOSError::throwMe(internalComponentErr);
+                       MacOSError::throwMe(errSecInternalComponent);
        }
        
        /*
        }
        
        /*
@@ -617,8 +618,8 @@ CFStringRef CertificateRequest::createPolicyKey()
        char oidstr[MAX_OID_LEN];
        unsigned char *inp = (unsigned char *)mPolicy.data();
        char *outp = oidstr;
        char oidstr[MAX_OID_LEN];
        unsigned char *inp = (unsigned char *)mPolicy.data();
        char *outp = oidstr;
-       unsigned len = mPolicy.length();
-       for(unsigned dex=0; dex<len; dex++) {
+       CFIndex len = mPolicy.length();
+       for(CFIndex dex=0; dex<len; dex++) {
                sprintf(outp, "%02X ", *inp++);
                outp += 3;
        }
                sprintf(outp, "%02X ", *inp++);
                outp += 3;
        }
@@ -691,10 +692,10 @@ OSStatus CertificateRequest::storeResults(
        delete policyDict;
        
        /* prefs --> disk */
        delete policyDict;
        
        /* prefs --> disk */
-       OSStatus ortn = noErr;
+       OSStatus ortn = errSecSuccess;
        if(!prefsDict->writePlistToPrefs(DOT_MAC_REQ_PREFS, Dictionary::US_User)) {
                certReqDbg("storeResults: error writing prefs to disk");
        if(!prefsDict->writePlistToPrefs(DOT_MAC_REQ_PREFS, Dictionary::US_User)) {
                certReqDbg("storeResults: error writing prefs to disk");
-               ortn = ioErr;
+               ortn = errSecIO;
        }
        delete prefsDict;
        return ortn;
        }
        delete prefsDict;
        return ortn;
@@ -763,8 +764,8 @@ void CertificateRequest::removeResults()
  * user. Always throws: either 
  * CSSMERR_APPLE_DOTMAC_REQ_IS_PENDING  -- request pending
  * CSSMERR_APPLE_DOTMAC_NO_REQ_PENDING  -- no request pending
  * user. Always throws: either 
  * CSSMERR_APPLE_DOTMAC_REQ_IS_PENDING  -- request pending
  * CSSMERR_APPLE_DOTMAC_NO_REQ_PENDING  -- no request pending
- * paramErr -- no user, no password
- * other gross errors, e.g. ioErr for server connection failure
+ * errSecParam -- no user, no password
+ * other gross errors, e.g. errSecIO for server connection failure
  *
  * The distinguishing features about this TP request are:
  *
  *
  * The distinguishing features about this TP request are:
  *
@@ -790,7 +791,7 @@ void CertificateRequest::postPendingRequest()
        assert(mCertState == CRS_Reconstructed);
        if((mUserName.data() == NULL) || (mPassword.data() == NULL)) {
                certReqDbg("postPendingRequest: user name and password required");
        assert(mCertState == CRS_Reconstructed);
        if((mUserName.data() == NULL) || (mPassword.data() == NULL)) {
                certReqDbg("postPendingRequest: user name and password required");
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
        }
        
        /* Fill in the CSSM_APPLE_DOTMAC_TP_CERT_REQUEST */
        }
        
        /* Fill in the CSSM_APPLE_DOTMAC_TP_CERT_REQUEST */
@@ -846,7 +847,7 @@ void CertificateRequest::postPendingRequest()
                case CSSM_OK:
                        /* should never happen */
                        certReqDbg("postPendingRequest: unexpected success!");
                case CSSM_OK:
                        /* should never happen */
                        certReqDbg("postPendingRequest: unexpected success!");
-                       crtn = internalComponentErr;
+                       crtn = errSecInternalComponent;
                        break;
                default:
                        certReqDbg("postPendingRequest: unexpected rtn %lu", (unsigned long)crtn);
                        break;
                default:
                        certReqDbg("postPendingRequest: unexpected rtn %lu", (unsigned long)crtn);
index b3aa90452f729c62e5916de5bce9406803c4e799..d5d774e932089c73be0e3abc4513eac3bab0dfad 100644 (file)
@@ -29,7 +29,6 @@
 #include <Security/oidsattr.h>
 #include <Security/SecCertificate.h>
 #include <Security/SecCertificatePriv.h>
 #include <Security/oidsattr.h>
 #include <Security/SecCertificate.h>
 #include <Security/SecCertificatePriv.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 #include "SecCertificateOIDs.h"
 #include "CertificateValues.h"
 #include "SecCertificateP.h"
 #include "SecCertificateOIDs.h"
 #include "CertificateValues.h"
 #include "SecCertificateP.h"
 #include <CoreFoundation/CFNumber.h>
 #include "SecCertificateP.h"
 
 #include <CoreFoundation/CFNumber.h>
 #include "SecCertificateP.h"
 
+/* FIXME including SecCertificateInternalP.h here produces errors; investigate */
+extern "C" CFDataRef SecCertificateCopyIssuerSequenceP(SecCertificateRefP certificate);
+extern "C" CFDataRef SecCertificateCopySubjectSequenceP(SecCertificateRefP certificate);
+
 extern "C" void appendProperty(CFMutableArrayRef properties, CFStringRef propertyType, CFStringRef label, CFTypeRef value);
 
 extern CFStringRef kSecPropertyKeyType;
 extern "C" void appendProperty(CFMutableArrayRef properties, CFStringRef propertyType, CFStringRef label, CFTypeRef value);
 
 extern CFStringRef kSecPropertyKeyType;
@@ -169,7 +172,7 @@ CFDictionaryRef CertificateValues::copyFieldValues(CFArrayRef keys, CFErrorRef *
                CFRelease(additionalValues);
        }
 
                CFRelease(additionalValues);
        }
 
-       CFAbsoluteTime notBefore = SecCertificateNotValidBefore(certificateP);
+       CFAbsoluteTime notBefore = SecCertificateNotValidBeforeP(certificateP);
        CFNumberRef notBeforeRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &notBefore);
        if (notBeforeRef)
        {
        CFNumberRef notBeforeRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &notBefore);
        if (notBeforeRef)
        {
@@ -180,7 +183,7 @@ CFDictionaryRef CertificateValues::copyFieldValues(CFArrayRef keys, CFErrorRef *
                CFRelease(additionalValues);
        }
 
                CFRelease(additionalValues);
        }
 
-       CFAbsoluteTime notAfter = SecCertificateNotValidAfter(certificateP);
+       CFAbsoluteTime notAfter = SecCertificateNotValidAfterP(certificateP);
        CFNumberRef notAfterRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &notAfter);
        if (notAfterRef)
        {
        CFNumberRef notAfterRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &notAfter);
        if (notAfterRef)
        {
@@ -357,54 +360,99 @@ CFStringRef CertificateValues::remapLabelToKey(CFStringRef label)
 
 CFDataRef CertificateValues::copySerialNumber(CFErrorRef *error)
 {
 
 CFDataRef CertificateValues::copySerialNumber(CFErrorRef *error)
 {
-    CFDataRef result = NULL;
+       CFDataRef result = NULL;
        SecCertificateRefP certificateP = getSecCertificateRefP(error);
 
        SecCertificateRefP certificateP = getSecCertificateRefP(error);
 
-    if (certificateP)
-    {
-        result = SecCertificateCopySerialNumberP(certificateP);
-        CFRelease(certificateP);
-    }
-    return result;
+       if (certificateP)
+       {
+               result = SecCertificateCopySerialNumberP(certificateP);
+               CFRelease(certificateP);
+       }
+       return result;
 }
 
 }
 
-CFDataRef CertificateValues::getNormalizedIssuerContent(CFErrorRef *error)
+CFDataRef CertificateValues::copyNormalizedIssuerContent(CFErrorRef *error)
 {
 {
-       // We wrap with SecDERItemCopySequence, since SecItemCopyMatching expects it
-    CFDataRef result = NULL;
+       CFDataRef result = NULL;
        SecCertificateRefP certificateP = getSecCertificateRefP(error);
        SecCertificateRefP certificateP = getSecCertificateRefP(error);
-    if (certificateP)
-    {
-        result = SecCertificateGetNormalizedIssuer(certificateP);
-        CFRelease(certificateP);
-    }
-    return result;
+       if (certificateP)
+       {
+               result = SecCertificateCopyNormalizedIssuerSequence(certificateP);
+               CFRelease(certificateP);
+       }
+       return result;
 }
 
 }
 
-CFDataRef CertificateValues::getNormalizedSubjectContent(CFErrorRef *error)
+CFDataRef CertificateValues::copyNormalizedSubjectContent(CFErrorRef *error)
 {
 {
-       // We wrap with SecDERItemCopySequence, since SecItemCopyMatching expects it
-    CFDataRef result = NULL;
+       CFDataRef result = NULL;
        SecCertificateRefP certificateP = getSecCertificateRefP(error);
        SecCertificateRefP certificateP = getSecCertificateRefP(error);
-    if (certificateP)
-    {
-        result = SecCertificateGetNormalizedSubject(certificateP);
-        CFRelease(certificateP);
-    }
-    return result;
+       if (certificateP)
+       {
+               result = SecCertificateCopyNormalizedSubjectSequence(certificateP);
+               CFRelease(certificateP);
+       }
+       return result;
 }
 
 }
 
-bool CertificateValues::SecCertificateIsValidX(CFAbsoluteTime verifyTime, CFErrorRef *error)
+CFDataRef CertificateValues::copyIssuerSequence(CFErrorRef *error)
 {
 {
-       // We wrap with SecDERItemCopySequence, since SecItemCopyMatching expects it
-    bool result = NULL;
+       CFDataRef result = NULL;
        SecCertificateRefP certificateP = getSecCertificateRefP(error);
        SecCertificateRefP certificateP = getSecCertificateRefP(error);
-    if (certificateP)
-    {
-        result = SecCertificateIsValid(certificateP, verifyTime);
-        CFRelease(certificateP);
-    }
-    return result;
+       if (certificateP)
+       {
+               result = SecCertificateCopyIssuerSequenceP(certificateP);
+               CFRelease(certificateP);
+       }
+       return result;
+}
+
+CFDataRef CertificateValues::copySubjectSequence(CFErrorRef *error)
+{
+       CFDataRef result = NULL;
+       SecCertificateRefP certificateP = getSecCertificateRefP(error);
+       if (certificateP)
+       {
+               result = SecCertificateCopySubjectSequenceP(certificateP);
+               CFRelease(certificateP);
+       }
+       return result;
+}
+
+bool CertificateValues::isValid(CFAbsoluteTime verifyTime, CFErrorRef *error)
+{
+       bool result = NULL;
+       SecCertificateRefP certificateP = getSecCertificateRefP(error);
+       if (certificateP)
+       {
+               result = SecCertificateIsValidP(certificateP, verifyTime);
+               CFRelease(certificateP);
+       }
+       return result;
+}
+
+CFAbsoluteTime CertificateValues::notValidBefore(CFErrorRef *error)
+{
+       CFAbsoluteTime result = 0;
+       SecCertificateRefP certificateP = getSecCertificateRefP(error);
+       if (certificateP)
+       {
+               result = SecCertificateNotValidBeforeP(certificateP);
+               CFRelease(certificateP);
+       }
+       return result;
+}
+
+CFAbsoluteTime CertificateValues::notValidAfter(CFErrorRef *error)
+{
+       CFAbsoluteTime result = 0;
+       SecCertificateRefP certificateP = getSecCertificateRefP(error);
+       if (certificateP)
+       {
+               result = SecCertificateNotValidAfterP(certificateP);
+               CFRelease(certificateP);
+       }
+       return result;
 }
 
 SecCertificateRefP CertificateValues::getSecCertificateRefP(CFErrorRef *error)
 }
 
 SecCertificateRefP CertificateValues::getSecCertificateRefP(CFErrorRef *error)
index 3a10cea3862cbe5a04d00b05030ac57283603554..a080a385d0cf998378db6c5365772de72867aa7e 100644 (file)
@@ -1,15 +1,15 @@
 /*
  * Copyright (c) 2002-2010 Apple Inc. All Rights Reserved.
 /*
  * Copyright (c) 2002-2010 Apple Inc. All Rights Reserved.
- * 
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -49,9 +49,13 @@ public:
        static CFStringRef remapLabelToKey(CFStringRef label);
        CFDictionaryRef copyFieldValues(CFArrayRef keys, CFErrorRef *error);
        CFDataRef copySerialNumber(CFErrorRef *error);
        static CFStringRef remapLabelToKey(CFStringRef label);
        CFDictionaryRef copyFieldValues(CFArrayRef keys, CFErrorRef *error);
        CFDataRef copySerialNumber(CFErrorRef *error);
-       CFDataRef getNormalizedIssuerContent(CFErrorRef *error);
-       CFDataRef getNormalizedSubjectContent(CFErrorRef *error);
-    bool SecCertificateIsValidX(CFAbsoluteTime verifyTime, CFErrorRef *error);
+       CFDataRef copyNormalizedIssuerContent(CFErrorRef *error);
+       CFDataRef copyNormalizedSubjectContent(CFErrorRef *error);
+       CFDataRef copyIssuerSequence(CFErrorRef *error);
+       CFDataRef copySubjectSequence(CFErrorRef *error);
+       bool isValid(CFAbsoluteTime verifyTime, CFErrorRef *error);
+       CFAbsoluteTime notValidBefore(CFErrorRef *error);
+       CFAbsoluteTime notValidAfter(CFErrorRef *error);
 
 private:
 
 
 private:
 
index 7043a1bb22408cb3c15dd7cfb03e0c4e1a04e652..20b08095c47c4e0181fec4a798dc81a22e056ee0 100644 (file)
@@ -242,7 +242,7 @@ DLDbListCFPref::loadPropertyList(bool force)
                void *buffer = reinterpret_cast<void *>(CFDataGetMutableBytePtr(xmlData));
                if (!buffer)
                        break;
                void *buffer = reinterpret_cast<void *>(CFDataGetMutableBytePtr(xmlData));
                if (!buffer)
                        break;
-               ssize_t bytesRead = read(fd, buffer, theSize);
+               ssize_t bytesRead = read(fd, buffer, (size_t)theSize);
                if (bytesRead != theSize)
                        break;
 
                if (bytesRead != theSize)
                        break;
 
@@ -678,6 +678,11 @@ static void check_app_sandbox()
                        if (status) {
                                syslog(LOG_ERR, "Keychain sandbox consume extension error: s=%d p=%s %m\n", status, path);
                        }
                        if (status) {
                                syslog(LOG_ERR, "Keychain sandbox consume extension error: s=%d p=%s %m\n", status, path);
                        }
+            status = sandbox_release_fs_extension(xpc_string_get_string_ptr(extension));
+            if (status) {
+                               syslog(LOG_ERR, "Keychain sandbox release extension error: s=%d p=%s %m\n", status, path);
+                       }
+
                        return (bool)true;
                });
                
                        return (bool)true;
                });
                
@@ -702,7 +707,7 @@ string DLDbListCFPref::ExpandTildesInPath(const string &inPath)
        });
        
        if ((short)inPath.find("~/",0,2) == 0)
        });
        
        if ((short)inPath.find("~/",0,2) == 0)
-        return getPwInfo(kHomeDir) + inPath.substr(1);
+        return getPwInfo(kHomeDir) + inPath.substr(1, inPath.length() - 1);
     else
         return inPath;
 }
     else
         return inPath;
 }
index f176396187cd0f425bb31a66c77e3341202484db..f49a48c4b864da513c35884875949865a8074ed1 100644 (file)
@@ -64,3 +64,10 @@ const AccessCredentials * Globals::smartcardItemCredentials()
        
 }      // namespace KeychainCore
 }      // namespace Security
        
 }      // namespace KeychainCore
 }      // namespace Security
+
+
+
+extern "C" bool GetServerMode()
+{
+       return Security::KeychainCore::gServerMode;
+}
index 7e5f01f8155f163c85e67e79d6c341433b2dda50..7c484adc658a46fffa582274661e92439f04fbbe 100644 (file)
@@ -70,4 +70,6 @@ extern bool gServerMode;
 
 } // end namespace Security
 
 
 } // end namespace Security
 
+extern "C" bool GetServerMode();
+
 #endif // !_SECURITY_GLOBALS_H_
 #endif // !_SECURITY_GLOBALS_H_
index 52c72ac2d99ff713bc08b59f78e1dccf75d04400..ea6b96eae90a94c1369b4a44cdc88a8c2b892014 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <security_cdsa_utilities/KeySchema.h>
 #include <security_keychain/KCCursor.h>
 
 #include <security_cdsa_utilities/KeySchema.h>
 #include <security_keychain/KCCursor.h>
+#include <string.h>
 
 using namespace KeychainCore;
 
 
 using namespace KeychainCore;
 
@@ -85,9 +86,50 @@ Identity::operator == (const Identity &other) const
        return (mCertificate == other.mCertificate && mPrivateKey == other.mPrivateKey);
 }
 
        return (mCertificate == other.mCertificate && mPrivateKey == other.mPrivateKey);
 }
 
-bool
-Identity::equal(SecCFObject &other)
+bool Identity::equal(SecCFObject &other)
 {
 {
-    return (*this) == (const Identity &)other;
+       CFHashCode this_hash = hash();
+       CFHashCode other_hash = other.hash();
+       return (this_hash == other_hash);
+}
+
+CFHashCode Identity::hash()
+{
+       CFHashCode result = SecCFObject::hash();
+       
+          
+    struct keyAndCertHash
+    {
+        CFHashCode keyHash;
+        CFHashCode certHash;
+    };
+    
+    struct keyAndCertHash hashes;
+    memset(&hashes, 0, sizeof(struct keyAndCertHash));
+       
+       KeyItem* pKeyItem = mPrivateKey.get();
+       if (NULL != pKeyItem)
+       {
+               hashes.keyHash = pKeyItem->hash();
+       }
+       
+       Certificate* pCert = mCertificate.get();
+       if (NULL != pCert)
+       {
+               hashes.certHash = pCert->hash();
+       }
+       
+       if (hashes.keyHash != 0 || hashes.certHash != 0)
+       {
+        
+               CFDataRef temp_data = CFDataCreateWithBytesNoCopy(NULL, (const UInt8 *)&hashes, sizeof(struct keyAndCertHash), kCFAllocatorNull);
+               if (NULL != temp_data)
+               {
+                       result = CFHash(temp_data);     
+                       CFRelease(temp_data);
+               }
+       }
+
+       return result;
 }
 
 }
 
index b39a3c268c8ecb2123b6d314fa5d11b4f5e00694..5ea548bdb551a184b2a0c13b0ba3f8ce4f540f98 100644 (file)
@@ -54,6 +54,7 @@ public:
        bool operator == (const Identity &other) const;
 
        bool equal(SecCFObject &other);
        bool operator == (const Identity &other) const;
 
        bool equal(SecCFObject &other);
+    CFHashCode hash();
 
 private:
        SecPointer<KeyItem> mPrivateKey;
 
 private:
        SecPointer<KeyItem> mPrivateKey;
index 764dce18570d5b3338160c080c4c84afd96c72e3..d8a55b9385879ba0a3c57bd2399823f9cb82f6fc 100644 (file)
@@ -72,7 +72,7 @@ IdentityCursorPolicyAndID::findPreferredIdentity()
        uint32_t iprfValue = 'iprf'; // value is specified in host byte order, since kSecTypeItemAttr has type uint32 in the db schema
        SecKeychainAttribute sAttrs[] = {
                { kSecTypeItemAttr, sizeof(uint32_t), &iprfValue },
        uint32_t iprfValue = 'iprf'; // value is specified in host byte order, since kSecTypeItemAttr has type uint32 in the db schema
        SecKeychainAttribute sAttrs[] = {
                { kSecTypeItemAttr, sizeof(uint32_t), &iprfValue },
-               { kSecServiceItemAttr, strlen(idUTF8), (char *)idUTF8 }
+               { kSecServiceItemAttr, (UInt32)strlen(idUTF8), (char *)idUTF8 }
        };
        SecKeychainAttributeList sAttrList = { sizeof(sAttrs) / sizeof(sAttrs[0]), sAttrs };
 
        };
        SecKeychainAttributeList sAttrList = { sizeof(sAttrs) / sizeof(sAttrs[0]), sAttrs };
 
index 032dea039eddd597a5d468cdec0a73bf4da312bf..eac4dcab2d50201a1926d3c99e2b0e8ab7f8241d 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2000-2004,2012-2013 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
 #include "Globals.h"
 #include <security_cdsa_utilities/Schema.h>
 #include "KCEventNotifier.h"
 #include "Globals.h"
 #include <security_cdsa_utilities/Schema.h>
 #include "KCEventNotifier.h"
+#include "KCExceptions.h"
 #include "cssmdatetime.h"
 #include <security_cdsa_client/keychainacl.h>
 #include <security_utilities/osxcode.h>
 #include <security_utilities/trackingallocator.h>
 #include <Security/SecKeychainItemPriv.h>
 #include <Security/cssmapple.h>
 #include "cssmdatetime.h"
 #include <security_cdsa_client/keychainacl.h>
 #include <security_utilities/osxcode.h>
 #include <security_utilities/trackingallocator.h>
 #include <Security/SecKeychainItemPriv.h>
 #include <Security/cssmapple.h>
+#include <CommonCrypto/CommonDigest.h>
 
 #define SENDACCESSNOTIFICATIONS 1
 
 //%%% schema indexes should be defined in Schema.h
 
 #define SENDACCESSNOTIFICATIONS 1
 
 //%%% schema indexes should be defined in Schema.h
+#define _kSecAppleSharePasswordItemClass               'ashp'
 #define APPLEDB_CSSM_PRINTNAME_ATTRIBUTE        1   /* schema index for label attribute of keys or certificates */
 #define APPLEDB_GENERIC_PRINTNAME_ATTRIBUTE     7   /* schema index for label attribute of password items */
 #define IS_PASSWORD_ITEM_CLASS(X)             ( (X) == kSecInternetPasswordItemClass || \
                                                 (X) == kSecGenericPasswordItemClass || \
 #define APPLEDB_CSSM_PRINTNAME_ATTRIBUTE        1   /* schema index for label attribute of keys or certificates */
 #define APPLEDB_GENERIC_PRINTNAME_ATTRIBUTE     7   /* schema index for label attribute of password items */
 #define IS_PASSWORD_ITEM_CLASS(X)             ( (X) == kSecInternetPasswordItemClass || \
                                                 (X) == kSecGenericPasswordItemClass || \
-                                                (X) == kSecAppleSharePasswordItemClass ) ? 1 : 0
+                                                (X) == _kSecAppleSharePasswordItemClass ) ? 1 : 0
 
 using namespace KeychainCore;
 using namespace CSSMDateTimeUtils;
 
 using namespace KeychainCore;
 using namespace CSSMDateTimeUtils;
@@ -62,6 +65,7 @@ using namespace CSSMDateTimeUtils;
 ItemImpl::ItemImpl(SecItemClass itemClass, OSType itemCreator, UInt32 length, const void* data, bool dontDoAttributes)
        : mDbAttributes(new DbAttributes()),
        mKeychain(NULL),
 ItemImpl::ItemImpl(SecItemClass itemClass, OSType itemCreator, UInt32 length, const void* data, bool dontDoAttributes)
        : mDbAttributes(new DbAttributes()),
        mKeychain(NULL),
+       secd_PersistentRef(NULL),
        mDoNotEncrypt(false),
        mInCache(false),
        mMutex(Mutex::recursive)
        mDoNotEncrypt(false),
        mInCache(false),
        mMutex(Mutex::recursive)
@@ -78,6 +82,7 @@ ItemImpl::ItemImpl(SecItemClass itemClass, OSType itemCreator, UInt32 length, co
 ItemImpl::ItemImpl(SecItemClass itemClass, SecKeychainAttributeList *attrList, UInt32 length, const void* data)
        : mDbAttributes(new DbAttributes()),
        mKeychain(NULL),
 ItemImpl::ItemImpl(SecItemClass itemClass, SecKeychainAttributeList *attrList, UInt32 length, const void* data)
        : mDbAttributes(new DbAttributes()),
        mKeychain(NULL),
+       secd_PersistentRef(NULL),
        mDoNotEncrypt(false),
        mInCache(false),
        mMutex(Mutex::recursive)
        mDoNotEncrypt(false),
        mInCache(false),
        mMutex(Mutex::recursive)
@@ -88,7 +93,7 @@ ItemImpl::ItemImpl(SecItemClass itemClass, SecKeychainAttributeList *attrList, U
 
        mDbAttributes->recordType(Schema::recordTypeFor(itemClass));
 
 
        mDbAttributes->recordType(Schema::recordTypeFor(itemClass));
 
-       if(attrList) 
+       if(attrList)
        {
                for(UInt32 i=0; i < attrList->count; i++)
                {
        {
                for(UInt32 i=0; i < attrList->count; i++)
                {
@@ -100,14 +105,14 @@ ItemImpl::ItemImpl(SecItemClass itemClass, SecKeychainAttributeList *attrList, U
 // DbItemImpl constructor
 ItemImpl::ItemImpl(const Keychain &keychain, const PrimaryKey &primaryKey, const DbUniqueRecord &uniqueId)
        : mUniqueId(uniqueId), mKeychain(keychain), mPrimaryKey(primaryKey),
 // DbItemImpl constructor
 ItemImpl::ItemImpl(const Keychain &keychain, const PrimaryKey &primaryKey, const DbUniqueRecord &uniqueId)
        : mUniqueId(uniqueId), mKeychain(keychain), mPrimaryKey(primaryKey),
-       mDoNotEncrypt(false), mInCache(false),
+       secd_PersistentRef(NULL), mDoNotEncrypt(false), mInCache(false),
        mMutex(Mutex::recursive)
 {
 }
 
 // PrimaryKey ItemImpl constructor
 ItemImpl::ItemImpl(const Keychain &keychain, const PrimaryKey &primaryKey)
        mMutex(Mutex::recursive)
 {
 }
 
 // PrimaryKey ItemImpl constructor
 ItemImpl::ItemImpl(const Keychain &keychain, const PrimaryKey &primaryKey)
-       : mKeychain(keychain), mPrimaryKey(primaryKey), mDoNotEncrypt(false),
+: mKeychain(keychain), mPrimaryKey(primaryKey),        secd_PersistentRef(NULL), mDoNotEncrypt(false),
        mInCache(false),
        mMutex(Mutex::recursive)
 {
        mInCache(false),
        mMutex(Mutex::recursive)
 {
@@ -130,13 +135,14 @@ ItemImpl* ItemImpl::make(const Keychain &keychain, const PrimaryKey &primaryKey)
 }
 
 
 }
 
 
-       
+
 // Constructor used when copying an item to a keychain.
 
 ItemImpl::ItemImpl(ItemImpl &item) :
        mData(item.modifiedData() ? NULL : new CssmDataContainer()),
        mDbAttributes(new DbAttributes()),
        mKeychain(NULL),
 // Constructor used when copying an item to a keychain.
 
 ItemImpl::ItemImpl(ItemImpl &item) :
        mData(item.modifiedData() ? NULL : new CssmDataContainer()),
        mDbAttributes(new DbAttributes()),
        mKeychain(NULL),
+       secd_PersistentRef(NULL),
        mDoNotEncrypt(false),
        mInCache(false),
        mMutex(Mutex::recursive)
        mDoNotEncrypt(false),
        mInCache(false),
        mMutex(Mutex::recursive)
@@ -147,13 +153,13 @@ ItemImpl::ItemImpl(ItemImpl &item) :
        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.
        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;
                        }
                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);
                if (schemaAttributes == NULL)
                        // the source item is invalid
                        MacOSError::throwMe(errSecInvalidItemRef);
@@ -165,7 +171,7 @@ ItemImpl::ItemImpl(ItemImpl &item) :
        }
 
     // @@@ We don't deal with modified attributes.
        }
 
     // @@@ We don't deal with modified attributes.
-       
+
        if (item.modifiedData())
                // the copied data comes from the source item
                mData = new CssmDataContainer(item.modifiedData()->Data,
        if (item.modifiedData())
                // the copied data comes from the source item
                mData = new CssmDataContainer(item.modifiedData()->Data,
@@ -174,6 +180,9 @@ ItemImpl::ItemImpl(ItemImpl &item) :
 
 ItemImpl::~ItemImpl()
 {
 
 ItemImpl::~ItemImpl()
 {
+       if (secd_PersistentRef) {
+               CFRelease(secd_PersistentRef);
+       }
 }
 
 
 }
 
 
@@ -185,7 +194,7 @@ ItemImpl::getMutexForObject()
        {
                return mKeychain->getKeychainMutex();
        }
        {
                return mKeychain->getKeychainMutex();
        }
-       
+
        return NULL;
 }
 
        return NULL;
 }
 
@@ -227,13 +236,13 @@ ItemImpl::defaultAttributeValue(const CSSM_DB_ATTRIBUTE_INFO &info)
                case CSSM_DB_ATTRIBUTE_FORMAT_SINT32:
                case CSSM_DB_ATTRIBUTE_FORMAT_UINT32:
                        return defaultFourBytes;
                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_REAL:
                        return defaultEightBytes;
-                       
+
                case CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE:
                        return defaultTime;
                case CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE:
                        return defaultTime;
-                       
+
                default:
                        return defaultZeroBytes;
        }
                default:
                        return defaultZeroBytes;
        }
@@ -272,7 +281,7 @@ PrimaryKey ItemImpl::addWithCopyInfo (Keychain &keychain, bool isCopy)
                        setAttribute(schema->attributeInfoFor(recordType, kSecModDateItemAttr), date);
                }
        }
                        setAttribute(schema->attributeInfoFor(recordType, kSecModDateItemAttr), date);
                }
        }
-       
+
     // If the label (PrintName) attribute isn't specified, set a default label.
     if (!mDoNotEncrypt && !mDbAttributes->find(Schema::attributeInfo(kSecLabelItemAttr)))
     {
     // If the label (PrintName) attribute isn't specified, set a default label.
     if (!mDoNotEncrypt && !mDbAttributes->find(Schema::attributeInfo(kSecLabelItemAttr)))
     {
@@ -329,7 +338,7 @@ PrimaryKey ItemImpl::addWithCopyInfo (Keychain &keychain, bool isCopy)
                        }
                }
        }
                        }
                }
        }
-       
+
        Db db(keychain->database());
        if (mDoNotEncrypt)
        {
        Db db(keychain->database());
        if (mDoNotEncrypt)
        {
@@ -343,11 +352,11 @@ PrimaryKey ItemImpl::addWithCopyInfo (Keychain &keychain, bool isCopy)
                {
                        CssmError::throwMe(CSSMERR_CSSM_INVALID_POINTER);
                }
                {
                        CssmError::throwMe(CSSMERR_CSSM_INVALID_POINTER);
                }
-               
+
                SSDb ssDb(impl);
 
                TrackingAllocator allocator(Allocator::standard());
                SSDb ssDb(impl);
 
                TrackingAllocator allocator(Allocator::standard());
-                
+
                // hhs replaced with the new aclFactory class
                AclFactory aclFactory;
                const AccessCredentials *nullCred = aclFactory.nullCred();
                // hhs replaced with the new aclFactory class
                AclFactory aclFactory;
                const AccessCredentials *nullCred = aclFactory.nullCred();
@@ -358,7 +367,7 @@ PrimaryKey ItemImpl::addWithCopyInfo (Keychain &keychain, bool isCopy)
                        CssmDbAttributeData *data = mDbAttributes->find(Schema::attributeInfo(kSecLabelItemAttr));
                        string printName = data ? CssmData::overlay(data->Value[0]).toString() : "keychain item";
                        access = new Access(printName);
                        CssmDbAttributeData *data = mDbAttributes->find(Schema::attributeInfo(kSecLabelItemAttr));
                        string printName = data ? CssmData::overlay(data->Value[0]).toString() : "keychain item";
                        access = new Access(printName);
-                       
+
                        // special case for "iTools" password - allow anyone to decrypt the item
                        if (recordType == CSSM_DL_DB_RECORD_GENERIC_PASSWORD)
                        {
                        // special case for "iTools" password - allow anyone to decrypt the item
                        if (recordType == CSSM_DL_DB_RECORD_GENERIC_PASSWORD)
                        {
@@ -392,7 +401,7 @@ PrimaryKey ItemImpl::addWithCopyInfo (Keychain &keychain, bool isCopy)
                        ResourceControlContext prototype;
                        maker.initialOwner(prototype, nullCred);
                        SSGroup ssGroup(ssDb, &prototype);
                        ResourceControlContext prototype;
                        maker.initialOwner(prototype, nullCred);
                        SSGroup ssGroup(ssDb, &prototype);
-                       
+
                        try
                        {
                                // Insert the record using the newly created group.
                        try
                        {
                                // Insert the record using the newly created group.
@@ -484,8 +493,8 @@ ItemImpl::update()
 {
        StLock<Mutex>_(mMutex);
        if (!mKeychain)
 {
        StLock<Mutex>_(mMutex);
        if (!mKeychain)
-               MacOSError::throwMe(errSecNoSuchKeychain); 
-               
+               MacOSError::throwMe(errSecNoSuchKeychain);
+
        // Don't update if nothing changed.
        if (!isModified())
                return;
        // Don't update if nothing changed.
        if (!isModified())
                return;
@@ -509,7 +518,7 @@ ItemImpl::update()
                CSSM_DB_RECORD_ATTRIBUTE_DATA attrData;
                memset (&attrData, 0, sizeof (attrData));
                attrData.DataRecordType = aRecordType;
                CSSM_DB_RECORD_ATTRIBUTE_DATA attrData;
                memset (&attrData, 0, sizeof (attrData));
                attrData.DataRecordType = aRecordType;
-               
+
                mUniqueId->modifyWithoutEncryption(aRecordType,
                                                                                   &attrData,
                                                                                   mData.get(),
                mUniqueId->modifyWithoutEncryption(aRecordType,
                                                                                   &attrData,
                                                                                   mData.get(),
@@ -523,7 +532,7 @@ ItemImpl::update()
                {
                        CssmError::throwMe(CSSMERR_CSSM_INVALID_POINTER);
                }
                {
                        CssmError::throwMe(CSSMERR_CSSM_INVALID_POINTER);
                }
-               
+
                SSDbUniqueRecord ssUniqueId(impl);
 
                // @@@ Share this instance
                SSDbUniqueRecord ssUniqueId(impl);
 
                // @@@ Share this instance
@@ -684,7 +693,7 @@ ItemImpl::setAttribute(const CssmDbAttributeInfo &info, const CssmPolyData &data
                mDbAttributes->recordType(mPrimaryKey->recordType());
        }
 
                mDbAttributes->recordType(mPrimaryKey->recordType());
        }
 
-       uint32 length = data.Length;
+       size_t length = data.Length;
        const void *buf = reinterpret_cast<const void *>(data.Data);
     uint8 timeString[16];
 
        const void *buf = reinterpret_cast<const void *>(data.Data);
     uint8 timeString[16];
 
@@ -736,12 +745,12 @@ ItemImpl::modifyContent(const SecKeychainAttributeList *attrList, UInt32 dataLen
                        mDbAttributes->add(Schema::attributeInfo(attrTag), CssmData(attrList->attr[ix].data,  attrList->attr[ix].length));
                }
        }
                        mDbAttributes->add(Schema::attributeInfo(attrTag), CssmData(attrList->attr[ix].data,  attrList->attr[ix].length));
                }
        }
-       
+
        if(inData)
        {
                mData = new CssmDataContainer(inData, dataLength);
        }
        if(inData)
        {
                mData = new CssmDataContainer(inData, dataLength);
        }
-       
+
        update();
 }
 
        update();
 }
 
@@ -761,7 +770,7 @@ ItemImpl::getContent(SecItemClass *itemClass, SecKeychainAttributeList *attrList
 
     if (itemClass)
                *itemClass = Schema::itemClassFor(recordType());
 
     if (itemClass)
                *itemClass = Schema::itemClassFor(recordType());
-    
+
     bool getDataFromDatabase = mKeychain && mPrimaryKey;
     if (getDataFromDatabase) // are we attached to a database?
     {
     bool getDataFromDatabase = mKeychain && mPrimaryKey;
     if (getDataFromDatabase) // are we attached to a database?
     {
@@ -769,14 +778,14 @@ ItemImpl::getContent(SecItemClass *itemClass, SecKeychainAttributeList *attrList
 
                // get the number of attributes requested by the caller
                UInt32 attrCount = attrList ? attrList->count : 0;
 
                // get the number of attributes requested by the caller
                UInt32 attrCount = attrList ? attrList->count : 0;
-    
+
         // make a DBAttributes structure and populate it
         DbAttributes dbAttributes(mUniqueId->database(), attrCount);
         for (UInt32 ix = 0; ix < attrCount; ++ix)
         {
             dbAttributes.add(Schema::attributeInfo(attrList->attr[ix].tag));
         }
         // make a DBAttributes structure and populate it
         DbAttributes dbAttributes(mUniqueId->database(), attrCount);
         for (UInt32 ix = 0; ix < attrCount; ++ix)
         {
             dbAttributes.add(Schema::attributeInfo(attrList->attr[ix].tag));
         }
-        
+
         // request the data from the database (since we are a reference "item" and the data is really stored there)
         CssmDataContainer itemData;
                getContent(&dbAttributes, outData ? &itemData : NULL);
         // request the data from the database (since we are a reference "item" and the data is really stored there)
         CssmDataContainer itemData;
                getContent(&dbAttributes, outData ? &itemData : NULL);
@@ -786,16 +795,16 @@ ItemImpl::getContent(SecItemClass *itemClass, SecKeychainAttributeList *attrList
         {
             if (dbAttributes.at(ix).NumberOfValues > 0)
             {
         {
             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;
-    
+                attrList->attr[ix].data = dbAttributes.at(ix).Value[0].Data;
+                attrList->attr[ix].length = (UInt32)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
             {
                 // 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].data = NULL;
                 attrList->attr[ix].length = 0;
             }
         }
                 attrList->attr[ix].length = 0;
             }
         }
@@ -805,9 +814,9 @@ ItemImpl::getContent(SecItemClass *itemClass, SecKeychainAttributeList *attrList
                {
                        *outData=itemData.data();
                        itemData.Data = NULL;
                {
                        *outData=itemData.data();
                        itemData.Data = NULL;
-                       
+
                        if (length)
                        if (length)
-                               *length=itemData.length();
+                               *length=(UInt32)itemData.length();
                        itemData.Length = 0;
                }
     }
                        itemData.Length = 0;
                }
     }
@@ -873,7 +882,7 @@ ItemImpl::modifyAttributesAndData(const SecKeychainAttributeList *attrList, UInt
             }
 
             CssmDbAttributeInfo info=mKeychain->attributeInfoFor(recordType, attrTag);
             }
 
             CssmDbAttributeInfo info=mKeychain->attributeInfoFor(recordType, attrTag);
-                                                       
+
                        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)
                        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)
@@ -882,12 +891,12 @@ ItemImpl::modifyAttributesAndData(const SecKeychainAttributeList *attrList, UInt
                                mDbAttributes->add(info);
                }
        }
                                mDbAttributes->add(info);
                }
        }
-       
+
        if(inData)
        {
                mData = new CssmDataContainer(inData, dataLength);
        }
        if(inData)
        {
                mData = new CssmDataContainer(inData, dataLength);
        }
-       
+
        update();
 }
 
        update();
 }
 
@@ -919,7 +928,7 @@ ItemImpl::getAttributesAndData(SecKeychainAttributeInfo *info, SecItemClass *ite
                CssmDbAttributeData &record = dbAttributes.add();
                record.Info.AttributeNameFormat=CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER;
                record.Info.Label.AttributeID=info->tag[ix];
                CssmDbAttributeData &record = dbAttributes.add();
                record.Info.AttributeNameFormat=CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER;
                record.Info.Label.AttributeID=info->tag[ix];
-    
+
         if (record.Info.Label.AttributeID == kSecLabelItemAttr)
         {
             // must remap a caller-supplied label attribute tag for password items, since it isn't in the schema
         if (record.Info.Label.AttributeID == kSecLabelItemAttr)
         {
             // must remap a caller-supplied label attribute tag for password items, since it isn't in the schema
@@ -937,23 +946,23 @@ ItemImpl::getAttributesAndData(SecKeychainAttributeInfo *info, SecItemClass *ite
                SecKeychainAttribute *attr=reinterpret_cast<SecKeychainAttribute *>(malloc(sizeof(SecKeychainAttribute)*attrCount));
                theList->count=attrCount;
                theList->attr=attr;
                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];
                for (UInt32 ix = 0; ix < attrCount; ++ix)
                {
                        attr[ix].tag=info->tag[ix];
-        
+
                        if (dbAttributes.at(ix).NumberOfValues > 0)
                        {
                        if (dbAttributes.at(ix).NumberOfValues > 0)
                        {
-                               attr[ix].data = dbAttributes.at(ix).Value[0].Data;      
-                               attr[ix].length = dbAttributes.at(ix).Value[0].Length;
-       
+                               attr[ix].data = dbAttributes.at(ix).Value[0].Data;
+                               attr[ix].length = (UInt32)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
                        {
                                // 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].data = NULL;
                                attr[ix].length = 0;
                        }
                }
                                attr[ix].length = 0;
                        }
                }
@@ -964,10 +973,10 @@ ItemImpl::getAttributesAndData(SecKeychainAttributeInfo *info, SecItemClass *ite
        {
                *outData=itemData.data();
                itemData.Data=NULL;
        {
                *outData=itemData.data();
                itemData.Data=NULL;
-               
-               if (length) *length=itemData.length();
+
+               if (length) *length=(UInt32)itemData.length();
                itemData.Length=0;
                itemData.Length=0;
-                               
+
 #if SENDACCESSNOTIFICATIONS
                secdebug("kcnotify", "ItemImpl::getAttributesAndData(%p, %p, %p, %p, %p) retrieved data",
                        info, itemClass, attrList, length, outData);
 #if SENDACCESSNOTIFICATIONS
                secdebug("kcnotify", "ItemImpl::getAttributesAndData(%p, %p, %p, %p, %p) retrieved data",
                        info, itemClass, attrList, length, outData);
@@ -975,7 +984,7 @@ ItemImpl::getAttributesAndData(SecKeychainAttributeInfo *info, SecItemClass *ite
                KCEventNotifier::PostKeychainEvent(kSecDataAccessEvent, mKeychain, this);
 #endif
        }
                KCEventNotifier::PostKeychainEvent(kSecDataAccessEvent, mKeychain, this);
 #endif
        }
-       
+
 }
 
 void
 }
 
 void
@@ -1016,7 +1025,7 @@ ItemImpl::getAttribute(SecKeychainAttribute& attr, UInt32 *actualLength)
 
        if (!mKeychain)
                MacOSError::throwMe(errSecNoSuchAttr);
 
        if (!mKeychain)
                MacOSError::throwMe(errSecNoSuchAttr);
-               
+
        dbUniqueRecord();
        DbAttributes dbAttributes(mUniqueId->database(), 1);
        dbAttributes.add(Schema::attributeInfo(attr.tag));
        dbUniqueRecord();
        DbAttributes dbAttributes(mUniqueId->database(), 1);
        dbAttributes.add(Schema::attributeInfo(attr.tag));
@@ -1029,7 +1038,7 @@ ItemImpl::getAttributeFrom(CssmDbAttributeData *data, SecKeychainAttribute &attr
 {
        StLock<Mutex>_(mMutex);
     static const uint32 zero = 0;
 {
        StLock<Mutex>_(mMutex);
     static const uint32 zero = 0;
-    uint32 length;
+    UInt32 length;
     const void *buf = NULL;
 
     // Temporary storage for buf.
     const void *buf = NULL;
 
     // Temporary storage for buf.
@@ -1057,7 +1066,7 @@ ItemImpl::getAttributeFrom(CssmDbAttributeData *data, SecKeychainAttribute &attr
        }
     else // Get the first value
     {
        }
     else // Get the first value
     {
-        length = data->Value[0].Length;
+        length = (UInt32)data->Value[0].Length;
         buf = data->Value[0].Data;
 
         if (data->format() == CSSM_DB_ATTRIBUTE_FORMAT_SINT32)
         buf = data->Value[0].Data;
 
         if (data->format() == CSSM_DB_ATTRIBUTE_FORMAT_SINT32)
@@ -1173,7 +1182,7 @@ void ItemImpl::getLocalContent(SecKeychainAttributeList *attributeList, UInt32 *
                        MacOSError::throwMe(errSecDataNotAvailable);
 
                // Copy the data out of our internal cached copy.
                        MacOSError::throwMe(errSecDataNotAvailable);
 
                // Copy the data out of our internal cached copy.
-               uint32 length = data->Length;
+               UInt32 length = (UInt32)data->Length;
                *outData = allocator.malloc(length);
                memcpy(*outData, data->Data, length);
                if (outLength)
                *outData = allocator.malloc(length);
                memcpy(*outData, data->Data, length);
                if (outLength)
@@ -1193,7 +1202,7 @@ void ItemImpl::getLocalContent(SecKeychainAttributeList *attributeList, UInt32 *
                        if (data && data->NumberOfValues > 0)
                        {
                                // Copy the data out of our internal cached copy.
                        if (data && data->NumberOfValues > 0)
                        {
                                // Copy the data out of our internal cached copy.
-                               uint32 length = data->Value[0].Length;
+                               UInt32 length = (UInt32)data->Value[0].Length;
                                attribute.data = allocator.malloc(length);
                                memcpy(attribute.data, data->Value[0].Data, length);
                                attribute.length = length;
                                attribute.data = allocator.malloc(length);
                                memcpy(attribute.data, data->Value[0].Data, length);
                                attribute.length = length;
@@ -1228,7 +1237,7 @@ ItemImpl::getContent(DbAttributes *dbAttributes, CssmDataContainer *itemData)
                        {
                                CssmError::throwMe(CSSMERR_CSSM_INVALID_POINTER);
                        }
                        {
                                CssmError::throwMe(CSSMERR_CSSM_INVALID_POINTER);
                        }
-                       
+
                        SSDbUniqueRecord ssUniqueId(impl);
                        const AccessCredentials *autoPrompt = globals().itemCredentials();
                        ssUniqueId->get(dbAttributes, itemData, autoPrompt);
                        SSDbUniqueRecord ssUniqueId(impl);
                        const AccessCredentials *autoPrompt = globals().itemCredentials();
                        ssUniqueId->get(dbAttributes, itemData, autoPrompt);
@@ -1236,7 +1245,7 @@ ItemImpl::getContent(DbAttributes *dbAttributes, CssmDataContainer *itemData)
                }
        }
 
                }
        }
 
-    mUniqueId->get(dbAttributes, itemData); 
+    mUniqueId->get(dbAttributes, itemData);
 }
 
 bool
 }
 
 bool
@@ -1261,9 +1270,45 @@ void ItemImpl::willRead()
 {
 }
 
 {
 }
 
+Item ItemImpl::makeFromPersistentReference(const CFDataRef persistentRef, bool *isIdentityRef)
+{
+       CssmData dictData((void*)::CFDataGetBytePtr(persistentRef), ::CFDataGetLength(persistentRef));
+       NameValueDictionary dict(dictData);
+
+       Keychain keychain;
+       Item item = (ItemImpl *) NULL;
+
+       if (isIdentityRef) {
+               *isIdentityRef = (dict.FindByName(IDENTITY_KEY) != 0) ? true : false;
+       }
+
+       // make sure we have a database identifier
+       if (dict.FindByName(SSUID_KEY) != 0)
+       {
+               DLDbIdentifier dlDbIdentifier = NameValueDictionary::MakeDLDbIdentifierFromNameValueDictionary(dict);
+               DLDbIdentifier newDlDbIdentifier(dlDbIdentifier.ssuid(),
+                               DLDbListCFPref::ExpandTildesInPath(dlDbIdentifier.dbName()).c_str(),
+                               dlDbIdentifier.dbLocation());
+
+               keychain = globals().storageManager.keychain(newDlDbIdentifier);
+
+               const NameValuePair* aDictItem = dict.FindByName(ITEM_KEY);
+               if (aDictItem && keychain)
+               {
+                       PrimaryKey primaryKey(aDictItem->Value());
+                       item = keychain->item(primaryKey);
+               }
+       }
+       KCThrowIf_( !item, errSecItemNotFound );
+       return item;
+}
 
 
-void ItemImpl::copyPersistentReference(CFDataRef &outDataRef)
+void ItemImpl::copyPersistentReference(CFDataRef &outDataRef, bool isSecIdentityRef)
 {
 {
+       if (secd_PersistentRef) {
+               outDataRef = secd_PersistentRef;
+               return;
+       }
        StLock<Mutex>_(mMutex);
     // item must be in a keychain and have a primary key to be persistent
     if (!mKeychain || !mPrimaryKey) {
        StLock<Mutex>_(mMutex);
     // item must be in a keychain and have a primary key to be persistent
     if (!mKeychain || !mPrimaryKey) {
@@ -1279,6 +1324,12 @@ void ItemImpl::copyPersistentReference(CFDataRef &outDataRef)
     CssmData* pKey = mPrimaryKey;
     dict.Insert (new NameValuePair(ITEM_KEY, *pKey));
 
     CssmData* pKey = mPrimaryKey;
     dict.Insert (new NameValuePair(ITEM_KEY, *pKey));
 
+       if (isSecIdentityRef) {
+               uint32_t value = -1;
+               CssmData valueData((void*)&value, sizeof(value));
+               dict.Insert (new NameValuePair(IDENTITY_KEY, valueData));
+       }
+
     // flatten the NameValueDictionary
     CssmData dictData;
     dict.Export(dictData);
     // flatten the NameValueDictionary
     CssmData dictData;
     dict.Export(dictData);
@@ -1297,7 +1348,7 @@ void ItemImpl::copyRecordIdentifier(CSSM_DATA &data)
  * Obtain blob used to bind a keychain item to an Extended Attribute record.
  * We just use the PrimaryKey blob as the default. Note that for standard Items,
  * this can cause the loss of extended attribute bindings if a Primary Key
  * Obtain blob used to bind a keychain item to an Extended Attribute record.
  * We just use the PrimaryKey blob as the default. Note that for standard Items,
  * this can cause the loss of extended attribute bindings if a Primary Key
- * attribute changes. 
+ * attribute changes.
  */
 const CssmData &ItemImpl::itemID()
 {
  */
 const CssmData &ItemImpl::itemID()
 {
@@ -1309,6 +1360,76 @@ const CssmData &ItemImpl::itemID()
        return *mPrimaryKey;
 }
 
        return *mPrimaryKey;
 }
 
+bool ItemImpl::equal(SecCFObject &other)
+{
+       // First check to see if both items have a primary key and
+       // if the primary key is the same.  If so then these
+       // items must be equal
+    ItemImpl& other_item = (ItemImpl&)other;
+       if (mPrimaryKey != NULL && mPrimaryKey == other_item.mPrimaryKey)
+       {
+               return true;
+       }
+
+       // The primary keys do not match so do a CFHash of the
+       // data of the item and compare those for equality
+       CFHashCode this_hash = hash();
+       CFHashCode other_hash = other.hash();
+       return (this_hash == other_hash);
+}
+
+CFHashCode ItemImpl::hash()
+{
+       CFHashCode result = SecCFObject::hash();
+
+       StLock<Mutex>_(mMutex);
+       RefPointer<CssmDataContainer> data_to_hash;
+
+       // Use the item data for the hash
+       if (mData && *mData)
+       {
+               data_to_hash = mData;
+       }
+
+       // If there is no primary key AND not data ????
+       // just return the 'old' hash value which is the
+       // object pointer.
+       if (NULL != data_to_hash.get())
+       {
+               CFDataRef temp_data = NULL;
+               unsigned char digest[CC_SHA256_DIGEST_LENGTH];
+
+               if (data_to_hash->length() < 80)
+               {
+                       // If it is less than 80 bytes then CFData can be used
+                       temp_data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
+                               (const UInt8 *)data_to_hash->data(), data_to_hash->length(), kCFAllocatorNull);
+
+               }
+               // CFData truncates its hash value to 80 bytes. ????
+               // In order to do the 'right thing' a SHA 256 hash will be used to
+               // include all of the data
+               else
+               {
+                       memset(digest, 0, CC_SHA256_DIGEST_LENGTH);
+
+                       CC_SHA256((const void *)data_to_hash->data(), (CC_LONG)data_to_hash->length(), digest);
+
+                       temp_data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
+                               (const UInt8 *)digest, CC_SHA256_DIGEST_LENGTH, kCFAllocatorNull);
+               }
+
+               if (NULL != temp_data)
+               {
+                       result = CFHash(temp_data);
+                       CFRelease(temp_data);
+               }
+
+       }
+
+       return result;
+}
+
 
 void ItemImpl::postItemEvent(SecKeychainEvent theEvent)
 {
 
 void ItemImpl::postItemEvent(SecKeychainEvent theEvent)
 {
@@ -1339,7 +1460,7 @@ Item::Item(SecItemClass itemClass, OSType itemCreator, UInt32 length, const void
                        || itemClass == CSSM_DL_DB_RECORD_SYMMETRIC_KEY)
                        MacOSError::throwMe(errSecNoSuchClass); /* @@@ errSecInvalidClass */
        }
                        || itemClass == CSSM_DL_DB_RECORD_SYMMETRIC_KEY)
                        MacOSError::throwMe(errSecNoSuchClass); /* @@@ errSecInvalidClass */
        }
-       
+
        *this = new ItemImpl(itemClass, itemCreator, length, data, inhibitCheck);
 }
 
        *this = new ItemImpl(itemClass, itemCreator, length, data, inhibitCheck);
 }
 
@@ -1371,7 +1492,7 @@ Item::Item(const Keychain &keychain, const PrimaryKey &primaryKey)
                   || primaryKey->recordType() == CSSM_DL_DB_RECORD_SYMMETRIC_KEY)
                ? KeyItem::make(keychain, primaryKey)
                : primaryKey->recordType() == CSSM_DL_DB_RECORD_EXTENDED_ATTRIBUTE
                   || primaryKey->recordType() == CSSM_DL_DB_RECORD_SYMMETRIC_KEY)
                ? KeyItem::make(keychain, primaryKey)
                : primaryKey->recordType() == CSSM_DL_DB_RECORD_EXTENDED_ATTRIBUTE
-                  ? ExtendedAttribute::make(keychain, primaryKey) 
+                  ? ExtendedAttribute::make(keychain, primaryKey)
                   : ItemImpl::make(keychain, primaryKey))
 {
 }
                   : ItemImpl::make(keychain, primaryKey))
 {
 }
@@ -1386,12 +1507,42 @@ Item::Item(ItemImpl &item)
                ? new KeyItem(safer_cast<KeyItem &>(item))
                : item.recordType() == CSSM_DL_DB_RECORD_EXTENDED_ATTRIBUTE
                  ? new ExtendedAttribute(safer_cast<ExtendedAttribute &>(item))
                ? new KeyItem(safer_cast<KeyItem &>(item))
                : item.recordType() == CSSM_DL_DB_RECORD_EXTENDED_ATTRIBUTE
                  ? new ExtendedAttribute(safer_cast<ExtendedAttribute &>(item))
-                 : new ItemImpl(item)) 
+                 : new ItemImpl(item))
 {
 }
 
 {
 }
 
-CFIndex GetItemRetainCount(Item& item)
+CFIndex KeychainCore::GetItemRetainCount(Item& item)
 {
        return CFGetRetainCount(item->handle(false));
 }
 
 {
        return CFGetRetainCount(item->handle(false));
 }
 
+void ItemImpl::setPersistentRef(CFDataRef ref)
+{
+       if (secd_PersistentRef) {
+               CFRelease(secd_PersistentRef);
+       }
+       secd_PersistentRef = ref;
+       CFRetain(ref);
+}
+
+CFDataRef ItemImpl::getPersistentRef()
+{
+       return secd_PersistentRef;
+}
+
+
+
+bool ItemImpl::mayDelete()
+{
+    ObjectImpl* uniqueIDImpl = mUniqueId.get();
+    
+    if (uniqueIDImpl != NULL)
+    {
+        bool result = mUniqueId->isIdle();
+        return result;
+    }
+    else
+    {
+        return true;
+    }
+}
index 339273601357f9734a104125149833c627b58250..712b4f59226c511bc9a1a6ff12531a820e06705a 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2000-2004,2012-2013 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -53,25 +53,30 @@ protected:
 
        // new item constructors
     ItemImpl(SecItemClass itemClass, OSType itemCreator, UInt32 length, const void* data, bool inhibitCheck = false);
 
        // new item constructors
     ItemImpl(SecItemClass itemClass, OSType itemCreator, UInt32 length, const void* data, bool inhibitCheck = false);
-       
+
        ItemImpl(SecItemClass itemClass, SecKeychainAttributeList *attrList, UInt32 length, const void* data);
 
        ItemImpl(SecItemClass itemClass, SecKeychainAttributeList *attrList, UInt32 length, const void* data);
 
-       // db item contstructor
+       // db item constructor
     ItemImpl(const Keychain &keychain, const PrimaryKey &primaryKey, const CssmClient::DbUniqueRecord &uniqueId);
 
     ItemImpl(const Keychain &keychain, const PrimaryKey &primaryKey, const CssmClient::DbUniqueRecord &uniqueId);
 
-       // PrimaryKey item contstructor
+       // PrimaryKey item constructor
     ItemImpl(const Keychain &keychain, const PrimaryKey &primaryKey);
 
 public:
 
        static ItemImpl* make(const Keychain &keychain, const PrimaryKey &primaryKey, const CssmClient::DbUniqueRecord &uniqueId);
        static ItemImpl* make(const Keychain &keychain, const PrimaryKey &primaryKey);
     ItemImpl(const Keychain &keychain, const PrimaryKey &primaryKey);
 
 public:
 
        static ItemImpl* make(const Keychain &keychain, const PrimaryKey &primaryKey, const CssmClient::DbUniqueRecord &uniqueId);
        static ItemImpl* make(const Keychain &keychain, const PrimaryKey &primaryKey);
-       
+
        ItemImpl(ItemImpl &item);
 
        // Return true if we got the attribute, false if we only got the actualLength.
        void getAttributeFrom(CssmDbAttributeData *data, SecKeychainAttribute &attr,  UInt32 *actualLength);
        void getClass(SecKeychainAttribute &attr,  UInt32 *actualLength);
        ItemImpl(ItemImpl &item);
 
        // Return true if we got the attribute, false if we only got the actualLength.
        void getAttributeFrom(CssmDbAttributeData *data, SecKeychainAttribute &attr,  UInt32 *actualLength);
        void getClass(SecKeychainAttribute &attr,  UInt32 *actualLength);
+
+       // For iOS keys
+       void setPersistentRef(CFDataRef ref);
+       // returns NULL for securityd keys, or the (non-NULL) persistent ref for iOS keys
+       CFDataRef getPersistentRef();
        
        PrimaryKey addWithCopyInfo(Keychain &keychain, bool isCopy);
        Mutex* getMutexForObject();
        
        PrimaryKey addWithCopyInfo(Keychain &keychain, bool isCopy);
        Mutex* getMutexForObject();
@@ -93,7 +98,7 @@ public:
        virtual void update();
 
        void aboutToDestruct();
        virtual void update();
 
        void aboutToDestruct();
-       
+
        // put a copy of the item into a given keychain
        virtual Item copyTo(const Keychain &keychain, Access *newAccess = NULL);
 
        // put a copy of the item into a given keychain
        virtual Item copyTo(const Keychain &keychain, Access *newAccess = NULL);
 
@@ -111,7 +116,7 @@ public:
 
        void getAttribute(SecKeychainAttribute& attr,  UInt32 *actualLength);
        void getData(CssmDataContainer& outData);
 
        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);
        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);
@@ -135,7 +140,8 @@ public:
        virtual void willRead();
 
     // create a persistent reference to this item
        virtual void willRead();
 
     // create a persistent reference to this item
-    void copyPersistentReference(CFDataRef &outDataRef);
+    void copyPersistentReference(CFDataRef &outDataRef, bool isSecIdentityRef=false);
+       static Item makeFromPersistentReference(const CFDataRef persistentRef, bool *isIdentityRef=NULL);
 
        // for keychain syncing
        void doNotEncrypt () {mDoNotEncrypt = true;}
 
        // for keychain syncing
        void doNotEncrypt () {mDoNotEncrypt = true;}
@@ -149,18 +155,27 @@ public:
 
        /* For binding to extended attributes. */
        virtual const CssmData &itemID();
 
        /* For binding to extended attributes. */
        virtual const CssmData &itemID();
+
+       /* Overrides for SecCFObject methods */
+       bool equal(SecCFObject &other);
+    virtual CFHashCode hash();
        
        
+    bool mayDelete();
+    
 protected:
        // new item members
 protected:
        // new item members
-    RefPointer<CssmDataContainer> mData;
-    auto_ptr<CssmClient::DbAttributes> mDbAttributes;
+       RefPointer<CssmDataContainer> mData;
+       auto_ptr<CssmClient::DbAttributes> mDbAttributes;
        SecPointer<Access> mAccess;
 
        // db item members
        SecPointer<Access> mAccess;
 
        // db item members
-    CssmClient::DbUniqueRecord mUniqueId;
+       CssmClient::DbUniqueRecord mUniqueId;
        Keychain mKeychain;
        Keychain mKeychain;
-    PrimaryKey mPrimaryKey;
-       
+       PrimaryKey mPrimaryKey;
+
+       // non-NULL only for secd items (managed by secd, not securityd)
+       CFDataRef secd_PersistentRef;
+
 private:
        // keychain syncing flags
        bool mDoNotEncrypt;
 private:
        // keychain syncing flags
        bool mDoNotEncrypt;
@@ -186,10 +201,13 @@ public:
        Item(ItemImpl &item);
 };
 
        Item(ItemImpl &item);
 };
 
+
 CFIndex GetItemRetainCount(Item& item);
 
 } // end namespace KeychainCore
 
 } // end namespace Security
 
 CFIndex GetItemRetainCount(Item& item);
 
 } // end namespace KeychainCore
 
 } // end namespace Security
 
+
+
 #endif // !_SECURITY_ITEM_H_
 #endif // !_SECURITY_ITEM_H_
index 0464edfd141677b0a4105f06369cf8572f02756c..48bba91f45efe40192dfc1af410a45edf4b3eab4 100644 (file)
@@ -34,8 +34,8 @@
 #include "cssmdatetime.h"
 #include "Globals.h"
 #include "StorageManager.h"
 #include "cssmdatetime.h"
 #include "Globals.h"
 #include "StorageManager.h"
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 #include <Security/SecKeychainItemPriv.h>
 #include <Security/SecKeychainItemPriv.h>
+#include <SecBase.h>
 
 using namespace KeychainCore;
 using namespace CssmClient;
 
 using namespace KeychainCore;
 using namespace CssmClient;
@@ -158,7 +158,7 @@ KCCursorImpl::KCCursorImpl(const StorageManager::KeychainList &searchList, const
                
                // the class attribute
                if (foundClassAttribute || attr->length != sizeof(SecItemClass))
                
                // the class attribute
                if (foundClassAttribute || attr->length != sizeof(SecItemClass))
-                       MacOSError::throwMe(paramErr); // We have 2 different 'clas' attributes
+                       MacOSError::throwMe(errSecParam); // We have 2 different 'clas' attributes
 
                recordType(Schema::recordTypeFor(*reinterpret_cast<SecItemClass *>(attr->data)));
                foundClassAttribute=true;
 
                recordType(Schema::recordTypeFor(*reinterpret_cast<SecItemClass *>(attr->data)));
                foundClassAttribute=true;
@@ -169,7 +169,7 @@ KCCursorImpl::~KCCursorImpl() throw()
 {
 }
 
 {
 }
 
-static ModuleNexus<Mutex> gActivationMutex;
+//static ModuleNexus<Mutex> gActivationMutex;
 
 bool
 KCCursorImpl::next(Item &item)
 
 bool
 KCCursorImpl::next(Item &item)
@@ -196,22 +196,10 @@ KCCursorImpl::next(Item &item)
                        
                        try
                        {
                        
                        try
                        {
-            /*  WARNING:  THIS SECTION IS CRITICAL.
-                If multiple threads are attempting to activate
-                the same database at the same time, the global
-                system database queue will reflect the most recent
-                activation rather than the activation which was
-                created by this thread.
-                
-                We could protect the database structures, but that's not the
-                right answer because it's perfectly legal to have
-                more than one context.  That would basically just
-                make a big lock around CDSA, which is a performance
-                nightmare.  Instead, we protect the PROCESS under
-                which databases are activated.
-            */
-            
-                StLock<Mutex> _(gActivationMutex()); // force serialization of cursor creation
+                // StLock<Mutex> _(gActivationMutex()); // force serialization of cursor creation
+                Keychain &kc = *mCurrent;
+                Mutex* mutex = kc->getKeychainMutex();
+                StLock<Mutex> _(*mutex);
                                (*mCurrent)->database()->activate();
                                mDbCursor = DbCursor((*mCurrent)->database(), *this);
                        }
                                (*mCurrent)->database()->activate();
                                mDbCursor = DbCursor((*mCurrent)->database(), *this);
                        }
@@ -221,6 +209,10 @@ KCCursorImpl::next(Item &item)
                        }
                }
 
                        }
                }
 
+        Keychain &kc = *mCurrent;
+        Mutex* mutex = kc->getKeychainMutex();
+        StLock<Mutex> _(*mutex);
+        
                bool gotRecord;
                try
                {
                bool gotRecord;
                try
                {
@@ -295,6 +287,22 @@ KCCursorImpl::next(Item &item)
        }
 
        // Go though Keychain since item might already exist.
        }
 
        // Go though Keychain since item might already exist.
+    Keychain &kc = *mCurrent;
+    StLock<Mutex> _mutexLocker(*kc->getKeychainMutex());
        item = (*mCurrent)->item(dbAttributes.recordType(), uniqueId);
        return true;
 }
        item = (*mCurrent)->item(dbAttributes.recordType(), uniqueId);
        return true;
 }
+
+
+
+bool KCCursorImpl::mayDelete()
+{
+    if (mDbCursor.get() != NULL)
+    {
+        return mDbCursor->isIdle();
+    }
+    else
+    {
+        return true;
+    }
+}
index a25e225c373eff50dc1843f84e072fad5e998b8c..67ab482cdb50779d3ce192a9b1f6b9314076e52b 100644 (file)
@@ -49,7 +49,8 @@ protected:
 public:
        virtual ~KCCursorImpl() throw();
        bool next(Item &item);
 public:
        virtual ~KCCursorImpl() throw();
        bool next(Item &item);
-
+    bool mayDelete();
+    
 private:
        StorageManager::KeychainList mSearchList;
        StorageManager::KeychainList::iterator mCurrent;
 private:
        StorageManager::KeychainList mSearchList;
        StorageManager::KeychainList::iterator mCurrent;
index 3c62f782d6b118c41de2c9bfdde8206da3ab28d5..de97a67f04fe5843cf8c8be4f5f48d2e70068b06 100644 (file)
@@ -28,9 +28,8 @@
 #ifndef _SECURITY_KCEXCEPTIONS_H_
 #define _SECURITY_KCEXCEPTIONS_H_
 
 #ifndef _SECURITY_KCEXCEPTIONS_H_
 #define _SECURITY_KCEXCEPTIONS_H_
 
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 #include <security_utilities/errors.h>
 #include <security_utilities/errors.h>
-
+#include <SecBase.h>
 #ifdef lock
 #undef lock
 #endif
 #ifdef lock
 #undef lock
 #endif
@@ -52,7 +51,7 @@ namespace KeychainCore
 
 /*     remove RequiredParam when cdsa does namespaces
 template <class T>
 
 /*     remove RequiredParam when cdsa does namespaces
 template <class T>
-inline T &Required(T *ptr,OSStatus err = paramErr)
+inline T &Required(T *ptr,OSStatus err = errSecParam)
 {
     return Required(ptr,err);
 }
 {
     return Required(ptr,err);
 }
@@ -62,13 +61,13 @@ template <class T>
 inline void KCThrowIfMemFail_(const T *ptr)
 {
     if (ptr==NULL)
 inline void KCThrowIfMemFail_(const T *ptr)
 {
     if (ptr==NULL)
-               MacOSError::throwMe(memFullErr);
+               MacOSError::throwMe(errSecAllocate);
 }
 
 inline void KCThrowIf_(OSStatus theErr)
 {
        // will also work for OSErr
 }
 
 inline void KCThrowIf_(OSStatus theErr)
 {
        // will also work for OSErr
-    if (theErr!=noErr)
+    if (theErr!=errSecSuccess)
         MacOSError::throwMe(theErr);
 }
 
         MacOSError::throwMe(theErr);
 }
 
@@ -82,12 +81,12 @@ inline void KCThrowIf_(bool test,OSStatus theErr)
 inline void KCThrowParamErrIf_(bool test)
 {
     if (test)
 inline void KCThrowParamErrIf_(bool test)
 {
     if (test)
-        MacOSError::throwMe(paramErr);
+        MacOSError::throwMe(errSecParam);
 }
 
 inline void KCUnimplemented_()
 {
 }
 
 inline void KCUnimplemented_()
 {
-       MacOSError::throwMe(unimpErr);
+       MacOSError::throwMe(errSecUnimplemented);
 }
 
 } // end namespace KeychainCore
 }
 
 } // end namespace KeychainCore
index 76583502cffe01371899ea18c69398ff2a38a98f..6bfaf438bf52d6fb8c2b986e3aba6c60ecfb2727 100644 (file)
@@ -25,8 +25,7 @@
 #define _SECURITY_KCUTILITIES_H_
 
 #include <security_utilities/errors.h>
 #define _SECURITY_KCUTILITIES_H_
 
 #include <security_utilities/errors.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
-
+#include <SecBase.h>
 namespace Security
 {
 
 namespace Security
 {
 
@@ -34,7 +33,7 @@ namespace Security
 // Helpers for memory pointer validation
 //
 template <class T>
 // Helpers for memory pointer validation
 //
 template <class T>
-inline T &RequiredParam(T *ptr,OSStatus err = paramErr)
+inline T &RequiredParam(T *ptr,OSStatus err = errSecParam)
 {
     if (ptr == NULL)
         MacOSError::throwMe(err);
 {
     if (ptr == NULL)
         MacOSError::throwMe(err);
index 0b7149d0770188d89a009a29f39ba4a597a8dd61..84db4ef93787d7006b746093257b9ca861dc9bc9 100644 (file)
@@ -25,7 +25,6 @@
 // KeyItem.cpp
 //
 #include <security_keychain/KeyItem.h>
 // KeyItem.cpp
 //
 #include <security_keychain/KeyItem.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 #include <Security/cssmtype.h>
 #include <security_keychain/Access.h>
 #include <security_keychain/Keychains.h>
 #include <Security/cssmtype.h>
 #include <security_keychain/Access.h>
 #include <security_keychain/Keychains.h>
@@ -37,6 +36,8 @@
 
 #include <security_keychain/Globals.h>
 #include "KCEventNotifier.h"
 
 #include <security_keychain/Globals.h>
 #include "KCEventNotifier.h"
+#include <CommonCrypto/CommonDigest.h>
+#include <SecBase.h>
 
 // @@@ This needs to be shared.
 static CSSM_DB_NAME_ATTR(kInfoKeyPrintName, kSecKeyPrintName, (char*) "PrintName", 0, NULL, BLOB);
 
 // @@@ This needs to be shared.
 static CSSM_DB_NAME_ATTR(kInfoKeyPrintName, kSecKeyPrintName, (char*) "PrintName", 0, NULL, BLOB);
@@ -96,7 +97,7 @@ KeyItem::KeyItem(const CssmClient::Key &key) :
        mPubKeyHash(Allocator::standard())
 {
        if (key->keyClass() > CSSM_KEYCLASS_SESSION_KEY)
        mPubKeyHash(Allocator::standard())
 {
        if (key->keyClass() > CSSM_KEYCLASS_SESSION_KEY)
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
 }
 
 KeyItem::~KeyItem()
 }
 
 KeyItem::~KeyItem()
@@ -125,14 +126,18 @@ KeyItem::copyTo(const Keychain &keychain, Access *newAccess)
        SSDb ssDb(dbImpl);
 
        /* Make sure mKey is valid. */
        SSDb ssDb(dbImpl);
 
        /* Make sure mKey is valid. */
-       key();
+       const CSSM_KEY *cssmKey = key();
+       if (cssmKey && (0==(cssmKey->KeyHeader.KeyAttr & CSSM_KEYATTR_EXTRACTABLE)))
+       {
+               MacOSError::throwMe(errSecDataNotAvailable);
+       }
 
        // Generate a random label to use initially
        CssmClient::CSP appleCsp(gGuidAppleCSP);
        CssmClient::Random random(appleCsp, CSSM_ALGID_APPLE_YARROW);
        uint8 labelBytes[20];
        CssmData label(labelBytes, sizeof(labelBytes));
 
        // Generate a random label to use initially
        CssmClient::CSP appleCsp(gGuidAppleCSP);
        CssmClient::Random random(appleCsp, CSSM_ALGID_APPLE_YARROW);
        uint8 labelBytes[20];
        CssmData label(labelBytes, sizeof(labelBytes));
-       random.generate(label, label.Length);
+       random.generate(label, (uint32)label.Length);
 
        /* Set up the ACL for the new key. */
        SecPointer<Access> access;
 
        /* Set up the ACL for the new key. */
        SecPointer<Access> access;
@@ -149,7 +154,7 @@ KeyItem::copyTo(const Keychain &keychain, Access *newAccess)
        /* make a random IV */
        uint8 ivBytes[8];
        CssmData iv(ivBytes, sizeof(ivBytes));
        /* make a random IV */
        uint8 ivBytes[8];
        CssmData iv(ivBytes, sizeof(ivBytes));
-       random.generate(iv, iv.length());
+       random.generate(iv, (uint32)iv.length());
 
        /* Extract the key by wrapping it with the wrapping key. */
        CssmClient::WrapKey wrap(csp(), CSSM_ALGID_3DES_3KEY_EDE);
 
        /* Extract the key by wrapping it with the wrapping key. */
        CssmClient::WrapKey wrap(csp(), CSSM_ALGID_3DES_3KEY_EDE);
@@ -247,7 +252,7 @@ KeyItem::importTo(const Keychain &keychain, Access *newAccess, SecKeychainAttrib
        CssmClient::Random random(appleCsp, CSSM_ALGID_APPLE_YARROW);
        uint8 labelBytes[20];
        CssmData label(labelBytes, sizeof(labelBytes));
        CssmClient::Random random(appleCsp, CSSM_ALGID_APPLE_YARROW);
        uint8 labelBytes[20];
        CssmData label(labelBytes, sizeof(labelBytes));
-       random.generate(label, label.Length);
+       random.generate(label, (uint32)label.Length);
 
        /* Set up the ACL for the new key. */
        SecPointer<Access> access;
 
        /* Set up the ACL for the new key. */
        SecPointer<Access> access;
@@ -264,7 +269,7 @@ KeyItem::importTo(const Keychain &keychain, Access *newAccess, SecKeychainAttrib
        /* make a random IV */
        uint8 ivBytes[8];
        CssmData iv(ivBytes, sizeof(ivBytes));
        /* make a random IV */
        uint8 ivBytes[8];
        CssmData iv(ivBytes, sizeof(ivBytes));
-       random.generate(iv, iv.length());
+       random.generate(iv, (uint32)iv.length());
 
        /* Extract the key by wrapping it with the wrapping key. */
        CssmClient::WrapKey wrap(csp(), CSSM_ALGID_3DES_3KEY_EDE);
 
        /* Extract the key by wrapping it with the wrapping key. */
        CssmClient::WrapKey wrap(csp(), CSSM_ALGID_3DES_3KEY_EDE);
@@ -372,7 +377,7 @@ KeyItem::didModify()
 PrimaryKey
 KeyItem::add(Keychain &keychain)
 {
 PrimaryKey
 KeyItem::add(Keychain &keychain)
 {
-       MacOSError::throwMe(unimpErr);
+       MacOSError::throwMe(errSecUnimplemented);
 }
 
 CssmClient::SSDbUniqueRecord
 }
 
 CssmClient::SSDbUniqueRecord
@@ -495,7 +500,7 @@ KeyItem::getCredentials(
        case kSecCredentialTypeNoUI:
                return factory.nullCred();
        default:
        case kSecCredentialTypeNoUI:
                return factory.nullCred();
        default:
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
        }
 }
 
        }
 }
 
@@ -547,7 +552,7 @@ KeyItem::createPair(
        CssmClient::Random random(appleCsp, CSSM_ALGID_APPLE_YARROW);
        uint8 labelBytes[20];
        CssmData label(labelBytes, sizeof(labelBytes));
        CssmClient::Random random(appleCsp, CSSM_ALGID_APPLE_YARROW);
        uint8 labelBytes[20];
        CssmData label(labelBytes, sizeof(labelBytes));
-       random.generate(label, label.Length);
+       random.generate(label, (uint32)label.Length);
 
        // Create a Access::Maker for the initial owner of the private key.
        ResourceControlContext rcc;
 
        // Create a Access::Maker for the initial owner of the private key.
        ResourceControlContext rcc;
@@ -983,7 +988,7 @@ KeyItem::generateWithAttributes(const SecKeychainAttributeList *attrList,
 
                // Generate a random label to use initially
                CssmClient::Random random(appleCsp, CSSM_ALGID_APPLE_YARROW);
 
                // Generate a random label to use initially
                CssmClient::Random random(appleCsp, CSSM_ALGID_APPLE_YARROW);
-               random.generate(label, label.Length);
+               random.generate(label, (uint32)label.Length);
                plabel = &label;
        }
        else
                plabel = &label;
        }
        else
@@ -1158,9 +1163,10 @@ KeyItem::generate(Keychain keychain,
 void KeyItem::RawSign(SecPadding padding, CSSM_DATA dataToSign, const AccessCredentials *credentials, CSSM_DATA& signature)
 {
        CSSM_ALGORITHMS baseAlg = key()->header().algorithm();
 void KeyItem::RawSign(SecPadding padding, CSSM_DATA dataToSign, const AccessCredentials *credentials, CSSM_DATA& signature)
 {
        CSSM_ALGORITHMS baseAlg = key()->header().algorithm();
-       if ((baseAlg != CSSM_ALGID_RSA) && (baseAlg != CSSM_ALGID_ECDSA))
+
+    if ((baseAlg != CSSM_ALGID_RSA) && (baseAlg != CSSM_ALGID_ECDSA))
        {
        {
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
        }
 
        CSSM_ALGORITHMS paddingAlg = CSSM_PADDING_PKCS1;
        }
 
        CSSM_ALGORITHMS paddingAlg = CSSM_PADDING_PKCS1;
@@ -1216,9 +1222,9 @@ void KeyItem::RawSign(SecPadding padding, CSSM_DATA dataToSign, const AccessCred
 void KeyItem::RawVerify(SecPadding padding, CSSM_DATA dataToVerify, const AccessCredentials *credentials, CSSM_DATA sig)
 {
        CSSM_ALGORITHMS baseAlg = key()->header().algorithm();
 void KeyItem::RawVerify(SecPadding padding, CSSM_DATA dataToVerify, const AccessCredentials *credentials, CSSM_DATA sig)
 {
        CSSM_ALGORITHMS baseAlg = key()->header().algorithm();
-       if ((baseAlg != CSSM_ALGID_RSA) && (baseAlg != CSSM_ALGID_ECDSA))
+    if ((baseAlg != CSSM_ALGID_RSA) && (baseAlg != CSSM_ALGID_ECDSA))
        {
        {
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
        }
 
        CSSM_ALGORITHMS paddingAlg = CSSM_PADDING_PKCS1;
        }
 
        CSSM_ALGORITHMS paddingAlg = CSSM_PADDING_PKCS1;
@@ -1273,7 +1279,7 @@ void KeyItem::Encrypt(SecPadding padding, CSSM_DATA dataToEncrypt, const AccessC
        CSSM_ALGORITHMS baseAlg = key()->header().algorithm();
        if (baseAlg != CSSM_ALGID_RSA)
        {
        CSSM_ALGORITHMS baseAlg = key()->header().algorithm();
        if (baseAlg != CSSM_ALGID_RSA)
        {
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
        }
 
        CSSM_ALGORITHMS paddingAlg = CSSM_PADDING_PKCS1;
        }
 
        CSSM_ALGORITHMS paddingAlg = CSSM_PADDING_PKCS1;
@@ -1312,7 +1318,7 @@ void KeyItem::Decrypt(SecPadding padding, CSSM_DATA dataToDecrypt, const AccessC
        CSSM_ALGORITHMS baseAlg = key()->header().algorithm();
        if (baseAlg != CSSM_ALGID_RSA)
        {
        CSSM_ALGORITHMS baseAlg = key()->header().algorithm();
        if (baseAlg != CSSM_ALGID_RSA)
        {
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
        }
 
        CSSM_ALGORITHMS paddingAlg = CSSM_PADDING_PKCS1;
        }
 
        CSSM_ALGORITHMS paddingAlg = CSSM_PADDING_PKCS1;
@@ -1348,3 +1354,47 @@ void KeyItem::Decrypt(SecPadding padding, CSSM_DATA dataToDecrypt, const AccessC
     }
 }
 
     }
 }
 
+CFHashCode KeyItem::hash()
+{
+       CFHashCode result = 0;
+       const CSSM_KEY *cssmKey = key();
+       if (NULL != cssmKey)
+       {
+               unsigned char digest[CC_SHA256_DIGEST_LENGTH];
+               
+               CFIndex size_of_data = sizeof(CSSM_KEYHEADER) +  cssmKey->KeyData.Length;
+               
+               CFMutableDataRef temp_cfdata = CFDataCreateMutable(kCFAllocatorDefault, size_of_data);
+               if (NULL == temp_cfdata)
+               {
+                       return result;
+               }
+               
+               CFDataAppendBytes(temp_cfdata, (const UInt8 *)cssmKey, sizeof(CSSM_KEYHEADER));
+               CFDataAppendBytes(temp_cfdata, cssmKey->KeyData.Data, cssmKey->KeyData.Length);
+
+               if (size_of_data < 80)
+               {
+                       // If it is less than 80 bytes then CFData can be used
+                       result = CFHash(temp_cfdata);
+                       CFRelease(temp_cfdata);
+               }
+               // CFData truncates its hash value to 80 bytes. ????
+               // In order to do the 'right thing' a SHA 256 hash will be used to
+               // include all of the data
+               else
+               {
+                       memset(digest, 0, CC_SHA256_DIGEST_LENGTH);
+
+                       CC_SHA256((const void *)CFDataGetBytePtr(temp_cfdata), (CC_LONG)CFDataGetLength(temp_cfdata), digest);
+
+                       CFDataRef data_to_hash = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
+                               (const UInt8 *)digest, CC_SHA256_DIGEST_LENGTH, kCFAllocatorNull);
+                       result = CFHash(data_to_hash);
+                       CFRelease(data_to_hash);
+                       CFRelease(temp_cfdata);
+               }
+       }
+       return result;
+}
+
index 6011fcbb3e8c2bd923d0da734e4b650b9439b35c..ae50ec802d226257bb9b4a8feb9a2245e5f6d5ea 100644 (file)
@@ -123,6 +123,8 @@ public:
        void RawVerify(SecPadding padding, CSSM_DATA dataToVerify, const AccessCredentials *credentials, CSSM_DATA signature);
        void Encrypt(SecPadding padding, CSSM_DATA dataToEncrypt, const AccessCredentials *credentials, CSSM_DATA& encryptedData);
        void Decrypt(SecPadding padding, CSSM_DATA dataToEncrypt, const AccessCredentials *credentials, CSSM_DATA& encryptedData);
        void RawVerify(SecPadding padding, CSSM_DATA dataToVerify, const AccessCredentials *credentials, CSSM_DATA signature);
        void Encrypt(SecPadding padding, CSSM_DATA dataToEncrypt, const AccessCredentials *credentials, CSSM_DATA& encryptedData);
        void Decrypt(SecPadding padding, CSSM_DATA dataToEncrypt, const AccessCredentials *credentials, CSSM_DATA& encryptedData);
+       
+       virtual CFHashCode hash();
 
 protected:
        virtual PrimaryKey add(Keychain &keychain);
 
 protected:
        virtual PrimaryKey add(Keychain &keychain);
index d6fa704b4bff1f8d141ef180d89da65d7ba6e110..b83383e2ac6f997d419aee9488ff26298d2f658b 100644 (file)
@@ -35,7 +35,6 @@
 #include <security_cdsa_utilities/Schema.h>
 #include <security_cdsa_client/keychainacl.h>
 #include <security_cdsa_utilities/cssmacl.h>
 #include <security_cdsa_utilities/Schema.h>
 #include <security_cdsa_client/keychainacl.h>
 #include <security_cdsa_utilities/cssmacl.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 #include <security_cdsa_utilities/cssmdb.h>
 #include <security_utilities/trackingallocator.h>
 #include <security_keychain/SecCFTypes.h>
 #include <security_cdsa_utilities/cssmdb.h>
 #include <security_utilities/trackingallocator.h>
 #include <security_keychain/SecCFTypes.h>
@@ -59,7 +58,7 @@ static dispatch_once_t SecKeychainSystemKeychainChecked;
 OSStatus SecKeychainSystemKeychainCheckWouldDeadlock()
 {
     dispatch_once(&SecKeychainSystemKeychainChecked, ^{});
 OSStatus SecKeychainSystemKeychainCheckWouldDeadlock()
 {
     dispatch_once(&SecKeychainSystemKeychainChecked, ^{});
-    return noErr;
+    return errSecSuccess;
 }
 
 using namespace KeychainCore;
 }
 
 using namespace KeychainCore;
@@ -155,7 +154,13 @@ KeychainSchemaImpl::~KeychainSchemaImpl()
 {
        try
        {
 {
        try
        {
-               for_each_map_delete(mPrimaryKeyInfoMap.begin(), mPrimaryKeyInfoMap.end());
+        map<CSSM_DB_RECORDTYPE, CssmAutoDbRecordAttributeInfo *>::iterator it = mPrimaryKeyInfoMap.begin();
+        while (it != mPrimaryKeyInfoMap.end())
+        {
+            delete it->second;
+            it++;
+        }
+               // for_each_map_delete(mPrimaryKeyInfoMap.begin(), mPrimaryKeyInfoMap.end());
        }
        catch(...)
        {
        }
        catch(...)
        {
@@ -228,7 +233,7 @@ KeychainSchemaImpl::getAttributeInfoForRecordType(CSSM_DB_RECORDTYPE recordType,
 
        SecKeychainAttributeInfo *theList=reinterpret_cast<SecKeychainAttributeInfo *>(malloc(sizeof(SecKeychainAttributeInfo)));
        
 
        SecKeychainAttributeInfo *theList=reinterpret_cast<SecKeychainAttributeInfo *>(malloc(sizeof(SecKeychainAttributeInfo)));
        
-       UInt32 capacity=rmap.size();
+       size_t capacity=rmap.size();
        UInt32 *tagBuf=reinterpret_cast<UInt32 *>(malloc(capacity*sizeof(UInt32)));
        UInt32 *formatBuf=reinterpret_cast<UInt32 *>(malloc(capacity*sizeof(UInt32)));
        UInt32 i=0;
        UInt32 *tagBuf=reinterpret_cast<UInt32 *>(malloc(capacity*sizeof(UInt32)));
        UInt32 *formatBuf=reinterpret_cast<UInt32 *>(malloc(capacity*sizeof(UInt32)));
        UInt32 i=0;
@@ -292,19 +297,25 @@ KeychainSchemaImpl::didCreateRelation(CSSM_DB_RECORDTYPE relationID,
                && relationID < CSSM_DB_RECORDTYPE_SCHEMA_END)
                return;
 
                && relationID < CSSM_DB_RECORDTYPE_SCHEMA_END)
                return;
 
+    // if our schema is already in the map, return
+    if (mPrimaryKeyInfoMap.find(relationID) != mPrimaryKeyInfoMap.end())
+    {
+        return;
+    }
+    
        RelationInfoMap &rim = mDatabaseInfoMap[relationID];
        for (uint32 ix = 0; ix < inNumberOfAttributes; ++ix)
                rim[pAttributeInfo[ix].AttributeId] = pAttributeInfo[ix].DataType;
 
        RelationInfoMap &rim = mDatabaseInfoMap[relationID];
        for (uint32 ix = 0; ix < inNumberOfAttributes; ++ix)
                rim[pAttributeInfo[ix].AttributeId] = pAttributeInfo[ix].DataType;
 
-       CssmAutoDbRecordAttributeInfo &infos =
-               *new CssmAutoDbRecordAttributeInfo();
+       CssmAutoDbRecordAttributeInfo *infos = new CssmAutoDbRecordAttributeInfo();
+    
        mPrimaryKeyInfoMap.
        mPrimaryKeyInfoMap.
-               insert(PrimaryKeyInfoMap::value_type(relationID, &infos));
-       infos.DataRecordType = relationID;
+               insert(PrimaryKeyInfoMap::value_type(relationID, infos));
+       infos->DataRecordType = relationID;
        for (uint32 ix = 0; ix < inNumberOfIndexes; ++ix)
                if (pIndexInfo[ix].IndexType == CSSM_DB_INDEX_UNIQUE)
                {
        for (uint32 ix = 0; ix < inNumberOfIndexes; ++ix)
                if (pIndexInfo[ix].IndexType == CSSM_DB_INDEX_UNIQUE)
                {
-                       CssmDbAttributeInfo &info = infos.add();
+                       CssmDbAttributeInfo &info = infos->add();
                        info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER;
                        info.Label.AttributeID = pIndexInfo[ix].AttributeId;
                        info.AttributeFormat = rim[info.Label.AttributeID];
                        info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER;
                        info.Label.AttributeID = pIndexInfo[ix].AttributeId;
                        info.AttributeFormat = rim[info.Label.AttributeID];
@@ -312,6 +323,14 @@ KeychainSchemaImpl::didCreateRelation(CSSM_DB_RECORDTYPE relationID,
 }
 
 
 }
 
 
+
+KeychainSchema::~KeychainSchema()
+
+{
+}
+
+
+
 struct Event
 {
        SecKeychainEvent eventCode;
 struct Event
 {
        SecKeychainEvent eventCode;
@@ -345,7 +364,7 @@ static void check_system_keychain()
                keychain_check_server_address.sun_family = AF_UNIX;
                if (strlcpy(keychain_check_server_address.sun_path, SYSTEM_KEYCHAIN_CHECK_UNIX_DOMAIN_SOCKET_NAME, sizeof(keychain_check_server_address.sun_path)) > sizeof(keychain_check_server_address.sun_path)) {
                        // It would be nice if we could compile time assert this
                keychain_check_server_address.sun_family = AF_UNIX;
                if (strlcpy(keychain_check_server_address.sun_path, SYSTEM_KEYCHAIN_CHECK_UNIX_DOMAIN_SOCKET_NAME, sizeof(keychain_check_server_address.sun_path)) > sizeof(keychain_check_server_address.sun_path)) {
                        // It would be nice if we could compile time assert this
-                       syslog(LOG_ERR, "Socket path too long, max length %d, your length %d", sizeof(keychain_check_server_address.sun_path), strlen(SYSTEM_KEYCHAIN_CHECK_UNIX_DOMAIN_SOCKET_NAME));
+                       syslog(LOG_ERR, "Socket path too long, max length %lu, your length %lu", (unsigned long)sizeof(keychain_check_server_address.sun_path), (unsigned long)strlen(SYSTEM_KEYCHAIN_CHECK_UNIX_DOMAIN_SOCKET_NAME));
                        close(server_fd);
                        return;
                }
                        close(server_fd);
                        return;
                }
@@ -578,92 +597,29 @@ KeychainImpl::unlock(ConstStringPtr password)
 }
 
 void
 }
 
 void
-KeychainImpl::getSettings(uint32 &outIdleTimeOut, bool &outLockOnSleep)
+KeychainImpl::stash()
 {
 {
-       StLock<Mutex>_(mMutex);
+       StLock<Mutex>_(mMutex);
        
        
-       mDb->getSettings(outIdleTimeOut, outLockOnSleep);
+       mDb->stash();
 }
 
 }
 
-void KeychainImpl::markBlobForDotMacSyncUpdate(CssmData& data)
+void
+KeychainImpl::stashCheck()
 {
 {
-       // find the plist for dot mac
-       CFArrayRef dictionaries = (CFArrayRef) CFPreferencesCopyValue(CFSTR("KeychainSyncList"),
-                                                                                                                                       CFSTR("com.apple.keychainsync"),
-                                                                                                                                       kCFPreferencesCurrentUser,
-                                                                                                                                       kCFPreferencesAnyHost);
-
-       if (dictionaries == NULL) // no such preference?  The user doesn't .Mac
-       {
-               return;
-       }
-       
-       CFStringRef currentPath = CFStringCreateWithCString(NULL, name(), kCFStringEncodingUTF8);
-       
-       // in each dictionary look for the path to the current keychain
-       CFIndex i;
-       CFIndex count = CFArrayGetCount(dictionaries);
-       
-       // make a mutable copy of the array
-       CFMutableArrayRef mutableDictionaries = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
-       for (i = 0; i < count; ++i)
-       {
-               CFMutableDictionaryRef d = (CFMutableDictionaryRef) CFDictionaryCreateMutableCopy(NULL, 0, (CFDictionaryRef) CFArrayGetValueAtIndex(dictionaries, i));
-               CFArrayAppendValue(mutableDictionaries, d);
-        CFRelease(d);
-       }
-       
-       // clean up what we don't need anymore
-       CFRelease(dictionaries);
-       
-       bool somethingChanged = false;
-       
-       for (i = 0; i < count; ++i)
-       {
-               CFMutableDictionaryRef d = (CFMutableDictionaryRef) CFArrayGetValueAtIndex(mutableDictionaries, i);
-               
-               // get the path and expand any tildes
-               CFStringRef path = (CFStringRef) CFDictionaryGetValue(d, CFSTR("DbName"));
-               CFIndex length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(path), kCFStringEncodingUTF8);
-               char buffer[length + 1]; // adjust for NULL termination
-               CFStringGetCString(path, buffer, sizeof(buffer), kCFStringEncodingUTF8);
-               string fullPath = buffer;
-               fullPath = DLDbListCFPref::ExpandTildesInPath(fullPath);
-               path = CFStringCreateWithCString(NULL, fullPath.c_str(), kCFStringEncodingUTF8);
-               
-               if (CFStringCompare(path, currentPath, 0) == kCFCompareEqualTo)
-               {
-                       // if the value already exists, don't worry about it
-                       CFDataRef oldBlob = (CFDataRef) CFDictionaryGetValue(d, CFSTR("DbOldBlob"));
-                       if (oldBlob == NULL)
-                       {
-                               // CFify the blob
-                               CFDataRef theBlob = (CFDataRef) CFDataCreate(NULL, (uint8*) data.data(), data.length());
-                               CFDictionaryAddValue(d, CFSTR("DbOldBlob"), theBlob);
-                               CFRelease(theBlob);
-                               
-                               CFPreferencesSetValue(CFSTR("KeychainSyncList"),
-                                                                         mutableDictionaries,
-                                                                         CFSTR("com.apple.keychainsync"),
-                                                                         kCFPreferencesCurrentUser,
-                                                                         kCFPreferencesAnyHost);
-                               somethingChanged = true;
-                       }
-               }
-       }
+       StLock<Mutex>_(mMutex);
        
        
-    CFRelease(currentPath);
+       mDb->stashCheck();
+}
 
 
-       CFRelease(mutableDictionaries);
+void
+KeychainImpl::getSettings(uint32 &outIdleTimeOut, bool &outLockOnSleep)
+{
+       StLock<Mutex>_(mMutex);
        
        
-       if (somethingChanged)
-       {
-               CFPreferencesSynchronize(CFSTR("com.apple.keychainsync"), kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
-       }
+       mDb->getSettings(outIdleTimeOut, outLockOnSleep);
 }
 
 }
 
-
-
 void
 KeychainImpl::setSettings(uint32 inIdleTimeOut, bool inLockOnSleep)
 {
 void
 KeychainImpl::setSettings(uint32 inIdleTimeOut, bool inLockOnSleep)
 {
@@ -682,10 +638,6 @@ KeychainImpl::setSettings(uint32 inIdleTimeOut, bool inLockOnSleep)
                mDb->copyBlob(oldBlob.get());
        
        mDb->setSettings(inIdleTimeOut, inLockOnSleep);
                mDb->copyBlob(oldBlob.get());
        
        mDb->setSettings(inIdleTimeOut, inLockOnSleep);
-       
-       // if we got here, nothing threw underneath.  Send the results off to .Mac heaven
-       if (!isSmartcard)
-               markBlobForDotMacSyncUpdate(oldBlob.get());
 }
 
 void 
 }
 
 void 
@@ -722,10 +674,6 @@ KeychainImpl::changePassphrase(UInt32 oldPasswordLength, const void *oldPassword
                mDb->copyBlob(oldBlob.get());
        
        mDb->changePassphrase(&cred);
                mDb->copyBlob(oldBlob.get());
        
        mDb->changePassphrase(&cred);
-       
-       // if we got here, nothing threw underneath.  Send the results off to .Mac heaven
-       if (!isSmartcard)
-               markBlobForDotMacSyncUpdate(oldBlob.get());
 }
 
 void
 }
 
 void
@@ -768,7 +716,7 @@ KeychainImpl::authenticate(const CSSM_ACCESS_CREDENTIALS *cred)
        if (!exists())
                MacOSError::throwMe(errSecNoSuchKeychain);
 
        if (!exists())
                MacOSError::throwMe(errSecNoSuchKeychain);
 
-       MacOSError::throwMe(unimpErr);
+       MacOSError::throwMe(errSecUnimplemented);
 }
 
 UInt32
 }
 
 UInt32
@@ -1321,6 +1269,12 @@ Keychain::Keychain()
        });
 }
 
        });
 }
 
+Keychain::~Keychain()
+{
+}
+
+
+
 Keychain
 Keychain::optional(SecKeychainRef handle)
 {
 Keychain
 Keychain::optional(SecKeychainRef handle)
 {
@@ -1331,7 +1285,7 @@ Keychain::optional(SecKeychainRef handle)
 }
 
 
 }
 
 
-CFIndex GetKeychainRetainCount(Keychain& kc)
+CFIndex KeychainCore::GetKeychainRetainCount(Keychain& kc)
 {
        CFTypeRef ref = kc->handle(false);
        return CFGetRetainCount(ref);
 {
        CFTypeRef ref = kc->handle(false);
        return CFGetRetainCount(ref);
@@ -1370,3 +1324,7 @@ KeychainImpl::defaultCredentials()
 
 
 
 
 
 
+bool KeychainImpl::mayDelete()
+{
+    return true;
+}
index f2ebaa54cc3432b34cf86a3fc66c3264be3e2510..f6b64f8feac315568f3a75eba25e59ea3f9afb96 100644 (file)
@@ -98,7 +98,8 @@ public:
     KeychainSchema() {}
     KeychainSchema(KeychainSchemaImpl *impl) : RefPointer<KeychainSchemaImpl>(impl) {}
     KeychainSchema(const CssmClient::Db &db) : RefPointer<KeychainSchemaImpl>(new KeychainSchemaImpl(db)) {}
     KeychainSchema() {}
     KeychainSchema(KeychainSchemaImpl *impl) : RefPointer<KeychainSchemaImpl>(impl) {}
     KeychainSchema(const CssmClient::Db &db) : RefPointer<KeychainSchemaImpl>(new KeychainSchemaImpl(db)) {}
-
+    ~KeychainSchema();
+    
        bool operator <(const KeychainSchema &other) const
        { return ptr && other.ptr ? *ptr < *other.ptr : ptr < other.ptr; }
        bool operator ==(const KeychainSchema &other) const
        bool operator <(const KeychainSchema &other) const
        { return ptr && other.ptr ? *ptr < *other.ptr : ptr < other.ptr; }
        bool operator ==(const KeychainSchema &other) const
@@ -127,8 +128,6 @@ protected:
        void didUpdate(const Item &inItem, PrimaryKey &oldPK,
                PrimaryKey &newPK);
        void completeAdd(Item &item, PrimaryKey &key);
        void didUpdate(const Item &inItem, PrimaryKey &oldPK,
                PrimaryKey &newPK);
        void completeAdd(Item &item, PrimaryKey &key);
-       
-       void markBlobForDotMacSyncUpdate(CssmData &data);
 
 public:
     virtual ~KeychainImpl();
 
 public:
     virtual ~KeychainImpl();
@@ -157,6 +156,8 @@ public:
     void unlock();
        void unlock(const CssmData &password);
     void unlock(ConstStringPtr password); // @@@ This has a length limit, we should remove it.
     void unlock();
        void unlock(const CssmData &password);
     void unlock(ConstStringPtr password); // @@@ This has a length limit, we should remove it.
+    void stash();
+    void stashCheck();
 
        void getSettings(uint32 &outIdleTimeOut, bool &outLockOnSleep);
        void setSettings(uint32 inIdleTimeOut, bool inLockOnSleep);
 
        void getSettings(uint32 &outIdleTimeOut, bool &outLockOnSleep);
        void setSettings(uint32 inIdleTimeOut, bool inLockOnSleep);
@@ -213,6 +214,8 @@ public:
        
        void addItem(const PrimaryKey &primaryKey, ItemImpl *dbItemImpl);
 
        
        void addItem(const PrimaryKey &primaryKey, ItemImpl *dbItemImpl);
 
+    bool mayDelete();
+
 private:
        void removeItem(const PrimaryKey &primaryKey, ItemImpl *inItemImpl);
        ItemImpl *_lookupItem(const PrimaryKey &primaryKey);
 private:
        void removeItem(const PrimaryKey &primaryKey, ItemImpl *inItemImpl);
        ItemImpl *_lookupItem(const PrimaryKey &primaryKey);
@@ -244,6 +247,7 @@ class Keychain : public SecPointer<KeychainImpl>
 public:
     Keychain();
     Keychain(KeychainImpl *impl) : SecPointer<KeychainImpl>(impl) {}
 public:
     Keychain();
     Keychain(KeychainImpl *impl) : SecPointer<KeychainImpl>(impl) {}
+    ~Keychain();
 
        static Keychain optional(SecKeychainRef handle); 
 
 
        static Keychain optional(SecKeychainRef handle); 
 
index fc9cc2b775f93d22779c1b0e101626066f232be4..28b648bcec67d8cc443e2f01df0ac5f60aa024c2 100644 (file)
@@ -48,7 +48,7 @@ enum
     errSecMisc_memFullErr            = -108,
     errSecMisc_dirNFErr              = -120,    /* The directory could not be found. */
     errSecMisc_volGoneErr            = -124,    /* The server volume is no longer available. It may have been disconnected. */
     errSecMisc_memFullErr            = -108,
     errSecMisc_dirNFErr              = -120,    /* The directory could not be found. */
     errSecMisc_volGoneErr            = -124,    /* The server volume is no longer available. It may have been disconnected. */
-       errSecMisc_userCanceledErr               = -128,        /* The operation was cancelled by the user. */
+       errSecMisc_userCanceledErr               = -128,        // The operation was cancelled by the user.
     errSecMisc_resNotFound           = -192,    /* A required resource could not be found. */
     errSecMisc_resFNotFound          = -193,    /* A required resource is missing or damaged. */
     errSecMisc_icNoURLErr            = -673,    /* The specified location (URL) is an unknown type, or does not contain enough information. */
     errSecMisc_resNotFound           = -192,    /* A required resource could not be found. */
     errSecMisc_resFNotFound          = -193,    /* A required resource is missing or damaged. */
     errSecMisc_icNoURLErr            = -673,    /* The specified location (URL) is an unknown type, or does not contain enough information. */
index 327e7e67e12ff7cd920ecd6ece5f60448926e9d5..345fc849e250a1a891e40f7e95fe04691a12bd7a 100644 (file)
@@ -97,7 +97,7 @@ PasswordImpl::getData(UInt32 *length, const void **data)
             mItem->getData(outData);
             if (length && data)
             {
             mItem->getData(outData);
             if (length && data)
             {
-                *length=outData.length();
+                *length=(uint32)outData.length();
                 outData.Length=0;
                 *data=outData.data();
                 outData.Data=NULL;
                 outData.Length=0;
                 *data=outData.data();
                 outData.Data=NULL;
index 2957cac9063aa240ecf6d060a81f54043cc8fc15..b86f973559b38abf41619d590efcaaa92ea653b8 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2002-2004 Apple Computer, Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2002-2004,2012 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
 #define MAX_OID_SIZE                           32
 
 //%%FIXME: need to use a common copy of this utility function
 #define MAX_OID_SIZE                           32
 
 //%%FIXME: need to use a common copy of this utility function
+static
 CFStringRef SecDERItemCopyOIDDecimalRepresentation(uint8 *oid, size_t oidLen)
 {
        if (oidLen == 0)
 CFStringRef SecDERItemCopyOIDDecimalRepresentation(uint8 *oid, size_t oidLen)
 {
        if (oidLen == 0)
-        return CFSTR("<NULL>");
-       
+               return CFSTR("<NULL>");
+
        if (oidLen > MAX_OID_SIZE)
        if (oidLen > MAX_OID_SIZE)
-        return CFSTR("Oid too long");
-       
-    CFMutableStringRef result = CFStringCreateMutable(kCFAllocatorDefault, 0);
-       
+               return CFSTR("Oid too long");
+
+       CFMutableStringRef result = CFStringCreateMutable(kCFAllocatorDefault, 0);
+
        // The first two levels are encoded into one byte, since the root level
        // has only 3 nodes (40*x + y).  However if x = joint-iso-itu-t(2) then
        // y may be > 39, so we have to add special-case handling for this.
        // The first two levels are encoded into one byte, since the root level
        // has only 3 nodes (40*x + y).  However if x = joint-iso-itu-t(2) then
        // y may be > 39, so we have to add special-case handling for this.
@@ -54,17 +55,17 @@ CFStringRef SecDERItemCopyOIDDecimalRepresentation(uint8 *oid, size_t oidLen)
                y += (x - 2) * 40;
                x = 2;
        }
                y += (x - 2) * 40;
                x = 2;
        }
-    CFStringAppendFormat(result, NULL, CFSTR("%u.%u"), x, y);
-       
-       uint32_t value = 0;
+       CFStringAppendFormat(result, NULL, CFSTR("%u.%u"), x, y);
+
+       unsigned long value = 0;
        for (x = 1; x < oidLen; ++x)
        {
                value = (value << 7) | (oid[x] & 0x7F);
        for (x = 1; x < oidLen; ++x)
        {
                value = (value << 7) | (oid[x] & 0x7F);
-        /* @@@ value may not span more than 4 bytes. */
-        /* A max number of 20 values is allowed. */
+               /* @@@ value may not span more than 4 bytes. */
+               /* A max number of 20 values is allowed. */
                if (!(oid[x] & 0x80))
                {
                if (!(oid[x] & 0x80))
                {
-            CFStringAppendFormat(result, NULL, CFSTR(".%lu"), value);
+                       CFStringAppendFormat(result, NULL, CFSTR(".%lu"), value);
                        value = 0;
                }
        }
                        value = 0;
                }
        }
@@ -80,7 +81,7 @@ Policy::Policy(TP supportingTp, const CssmOid &policyOid)
       mValue(Allocator::standard()),
       mAuxValue(Allocator::standard())
 {
       mValue(Allocator::standard()),
       mAuxValue(Allocator::standard())
 {
-    // value is as yet unimplemented
+       // value is as yet unimplemented
        secdebug("policy", "Policy() this %p", this);
 }
 
        secdebug("policy", "Policy() this %p", this);
 }
 
@@ -92,18 +93,18 @@ Policy::~Policy() throw()
 void Policy::setValue(const CssmData &value)
 {
        StLock<Mutex>_(mMutex);
 void Policy::setValue(const CssmData &value)
 {
        StLock<Mutex>_(mMutex);
-    mValue = value;
-    mAuxValue.reset();
+       mValue = value;
+       mAuxValue.reset();
 
 
-    // Certain policy values may contain an embedded pointer. Ask me how I feel about that.
-    if (mOid == CSSMOID_APPLE_TP_SSL ||
-        mOid == CSSMOID_APPLE_TP_EAP ||
-        mOid == CSSMOID_APPLE_TP_IP_SEC ||
-        mOid == CSSMOID_APPLE_TP_APPLEID_SHARING)
-    {
-        CSSM_APPLE_TP_SSL_OPTIONS *opts = (CSSM_APPLE_TP_SSL_OPTIONS *)value.data();
-        if (opts->Version == CSSM_APPLE_TP_SSL_OPTS_VERSION)
-        {
+       // Certain policy values may contain an embedded pointer. Ask me how I feel about that.
+       if (mOid == CSSMOID_APPLE_TP_SSL ||
+               mOid == CSSMOID_APPLE_TP_EAP ||
+               mOid == CSSMOID_APPLE_TP_IP_SEC ||
+               mOid == CSSMOID_APPLE_TP_APPLEID_SHARING)
+       {
+               CSSM_APPLE_TP_SSL_OPTIONS *opts = (CSSM_APPLE_TP_SSL_OPTIONS *)value.data();
+               if (opts->Version == CSSM_APPLE_TP_SSL_OPTS_VERSION)
+               {
                        if (opts->ServerNameLen > 0)
                        {
                                // Copy auxiliary data, then update the embedded pointer to reference our copy
                        if (opts->ServerNameLen > 0)
                        {
                                // Copy auxiliary data, then update the embedded pointer to reference our copy
@@ -118,12 +119,13 @@ void Policy::setValue(const CssmData &value)
                                        reinterpret_cast<char*>(NULL);
                        }
                }
                                        reinterpret_cast<char*>(NULL);
                        }
                }
-    }
-    else if (mOid == CSSMOID_APPLE_TP_SMIME ||
-             mOid == CSSMOID_APPLE_TP_ICHAT)
-    {
-        CSSM_APPLE_TP_SMIME_OPTIONS *opts = (CSSM_APPLE_TP_SMIME_OPTIONS *)value.data();
-        if (opts->Version == CSSM_APPLE_TP_SMIME_OPTS_VERSION)
+       }
+       else if (mOid == CSSMOID_APPLE_TP_SMIME ||
+                       mOid == CSSMOID_APPLE_TP_ICHAT ||
+                       mOid == CSSMOID_APPLE_TP_PASSBOOK_SIGNING)
+       {
+               CSSM_APPLE_TP_SMIME_OPTIONS *opts = (CSSM_APPLE_TP_SMIME_OPTIONS *)value.data();
+               if (opts->Version == CSSM_APPLE_TP_SMIME_OPTS_VERSION)
                {
                        if (opts->SenderEmailLen > 0)
                        {
                {
                        if (opts->SenderEmailLen > 0)
                        {
@@ -139,17 +141,20 @@ void Policy::setValue(const CssmData &value)
                                        reinterpret_cast<char*>(NULL);
                        }
                }
                                        reinterpret_cast<char*>(NULL);
                        }
                }
-    }
+       }
 }
 
 void Policy::setProperties(CFDictionaryRef properties)
 {
        // Set the policy value based on the provided dictionary keys.
 }
 
 void Policy::setProperties(CFDictionaryRef properties)
 {
        // Set the policy value based on the provided dictionary keys.
+       if (properties == NULL)
+               return;
+
        if (mOid == CSSMOID_APPLE_TP_SSL ||
        if (mOid == CSSMOID_APPLE_TP_SSL ||
-        mOid == CSSMOID_APPLE_TP_EAP ||
-        mOid == CSSMOID_APPLE_TP_IP_SEC ||
+               mOid == CSSMOID_APPLE_TP_EAP ||
+               mOid == CSSMOID_APPLE_TP_IP_SEC ||
                mOid == CSSMOID_APPLE_TP_APPLEID_SHARING)
                mOid == CSSMOID_APPLE_TP_APPLEID_SHARING)
-    {
+       {
                CSSM_APPLE_TP_SSL_OPTIONS options = { CSSM_APPLE_TP_SSL_OPTS_VERSION, 0, NULL, 0 };
                char *buf = NULL;
                CFStringRef nameStr = NULL;
                CSSM_APPLE_TP_SSL_OPTIONS options = { CSSM_APPLE_TP_SSL_OPTS_VERSION, 0, NULL, 0 };
                char *buf = NULL;
                CFStringRef nameStr = NULL;
@@ -158,7 +163,7 @@ void Policy::setProperties(CFDictionaryRef properties)
                        if (buf) {
                                if (CFStringGetCString(nameStr, buf, MAXPATHLEN, kCFStringEncodingUTF8)) {
                                        options.ServerName = buf;
                        if (buf) {
                                if (CFStringGetCString(nameStr, buf, MAXPATHLEN, kCFStringEncodingUTF8)) {
                                        options.ServerName = buf;
-                                       options.ServerNameLen = strlen(buf)+1; // include terminating null
+                                       options.ServerNameLen = (unsigned)(strlen(buf)+1); // include terminating null
                                }
                        }
                }
                                }
                        }
                }
@@ -172,9 +177,10 @@ void Policy::setProperties(CFDictionaryRef properties)
 
                if (buf) free(buf);
        }
 
                if (buf) free(buf);
        }
-    else if (mOid == CSSMOID_APPLE_TP_SMIME ||
-             mOid == CSSMOID_APPLE_TP_ICHAT)
-    {
+       else if (mOid == CSSMOID_APPLE_TP_SMIME ||
+                       mOid == CSSMOID_APPLE_TP_ICHAT ||
+                       mOid == CSSMOID_APPLE_TP_PASSBOOK_SIGNING)
+       {
                CSSM_APPLE_TP_SMIME_OPTIONS options = { CSSM_APPLE_TP_SMIME_OPTS_VERSION, 0, 0, NULL };
                char *buf = NULL;
                CFStringRef nameStr = NULL;
                CSSM_APPLE_TP_SMIME_OPTIONS options = { CSSM_APPLE_TP_SMIME_OPTS_VERSION, 0, 0, NULL };
                char *buf = NULL;
                CFStringRef nameStr = NULL;
@@ -182,8 +188,20 @@ void Policy::setProperties(CFDictionaryRef properties)
                        buf = (char *)malloc(MAXPATHLEN);
                        if (buf) {
                                if (CFStringGetCString(nameStr, buf, MAXPATHLEN, kCFStringEncodingUTF8)) {
                        buf = (char *)malloc(MAXPATHLEN);
                        if (buf) {
                                if (CFStringGetCString(nameStr, buf, MAXPATHLEN, kCFStringEncodingUTF8)) {
+                                       CFStringRef teamIDStr = NULL;
+                                       if (CFDictionaryGetValueIfPresent(properties, (const void *)kSecPolicyTeamIdentifier, (const void **)&teamIDStr)) {
+                                               char *buf2 = (char *)malloc(MAXPATHLEN);
+                                               if (buf2) {
+                                                       if (CFStringGetCString(teamIDStr, buf2, MAXPATHLEN, kCFStringEncodingUTF8)) {
+                                                               /* append tab separator and team identifier */
+                                                               strlcat(buf, "\t", MAXPATHLEN);
+                                                               strlcat(buf, buf2, MAXPATHLEN);
+                                                       }
+                                                       free(buf2);
+                                               }
+                                       }
                                        options.SenderEmail = buf;
                                        options.SenderEmail = buf;
-                                       options.SenderEmailLen = strlen(buf)+1; // include terminating null
+                                       options.SenderEmailLen = (unsigned)(strlen(buf)+1); // include terminating null
                                }
                        }
                }
                                }
                        }
                }
@@ -221,35 +239,47 @@ void Policy::setProperties(CFDictionaryRef properties)
 
                if (buf) free(buf);
     }
 
                if (buf) free(buf);
     }
-       
+
 }
 
 CFDictionaryRef Policy::properties()
 {
        // Builds and returns a dictionary which the caller must release.
 }
 
 CFDictionaryRef Policy::properties()
 {
        // Builds and returns a dictionary which the caller must release.
-       CSSM_DATA value = this->value();
        CFMutableDictionaryRef properties = CFDictionaryCreateMutable(NULL, 0,
                &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
        if (!properties) return NULL;
        CFMutableDictionaryRef properties = CFDictionaryCreateMutable(NULL, 0,
                &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
        if (!properties) return NULL;
-       
+
        // kSecPolicyOid
        CFStringRef oidStr = SecDERItemCopyOIDDecimalRepresentation((uint8*)mOid.data(), mOid.length());
        if (oidStr) {
                CFDictionarySetValue(properties, (const void *)kSecPolicyOid, (const void *)oidStr);
                CFRelease(oidStr);
        }
        // kSecPolicyOid
        CFStringRef oidStr = SecDERItemCopyOIDDecimalRepresentation((uint8*)mOid.data(), mOid.length());
        if (oidStr) {
                CFDictionarySetValue(properties, (const void *)kSecPolicyOid, (const void *)oidStr);
                CFRelease(oidStr);
        }
-       
+
        // kSecPolicyName
        // kSecPolicyName
-    if (mAuxValue) {
+       if (mAuxValue) {
                CFStringRef nameStr = CFStringCreateWithBytes(NULL,
                        (const UInt8 *)reinterpret_cast<char*>(mAuxValue.data()),
                        (CFIndex)mAuxValue.length(), kCFStringEncodingUTF8, false);
                if (nameStr) {
                CFStringRef nameStr = CFStringCreateWithBytes(NULL,
                        (const UInt8 *)reinterpret_cast<char*>(mAuxValue.data()),
                        (CFIndex)mAuxValue.length(), kCFStringEncodingUTF8, false);
                if (nameStr) {
-                       CFDictionarySetValue(properties, (const void *)kSecPolicyName, (const void *)nameStr);
+                       if (mOid == CSSMOID_APPLE_TP_PASSBOOK_SIGNING) {
+                               CFArrayRef strs = CFStringCreateArrayBySeparatingStrings(kCFAllocatorDefault, nameStr, CFSTR("\t"));
+                               if (strs) {
+                                       CFIndex count = CFArrayGetCount(strs);
+                                       if (count > 0)
+                                               CFDictionarySetValue(properties, (const void *)kSecPolicyName, (const void *)CFArrayGetValueAtIndex(strs, 0));
+                                       if (count > 1)
+                                               CFDictionarySetValue(properties, (const void *)kSecPolicyTeamIdentifier, (const void *)CFArrayGetValueAtIndex(strs, 1));
+                                       CFRelease(strs);
+                               }
+                       }
+                       else {
+                               CFDictionarySetValue(properties, (const void *)kSecPolicyName, (const void *)nameStr);
+                       }
                        CFRelease(nameStr);
                }
        }
                        CFRelease(nameStr);
                }
        }
-       
+
        // kSecPolicyClient
        if (mValue) {
                if (mOid == CSSMOID_APPLE_TP_SSL ||
        // kSecPolicyClient
        if (mValue) {
                if (mOid == CSSMOID_APPLE_TP_SSL ||
@@ -263,7 +293,7 @@ CFDictionaryRef Policy::properties()
                        }
                }
        }
                        }
                }
        }
-       
+
        // key usage flags (currently only for S/MIME and iChat policies)
        if (mValue) {
                if (mOid == CSSMOID_APPLE_TP_SMIME ||
        // key usage flags (currently only for S/MIME and iChat policies)
        if (mValue) {
                if (mOid == CSSMOID_APPLE_TP_SMIME ||
@@ -298,16 +328,11 @@ CFDictionaryRef Policy::properties()
 bool Policy::operator < (const Policy& other) const
 {
     //@@@ inefficient
 bool Policy::operator < (const Policy& other) const
 {
     //@@@ inefficient
-    return oid() < other.oid() ||
-        oid() == other.oid() && value() < other.value();
+    return (oid() < other.oid()) ||
+        (oid() == other.oid() && value() < other.value());
 }
 
 bool Policy::operator == (const Policy& other) const
 {
     return oid() == other.oid() && value() == other.value();
 }
 }
 
 bool Policy::operator == (const Policy& other) const
 {
     return oid() == other.oid() && value() == other.value();
 }
-
-bool Policy::equal(SecCFObject &other)
-{
-    return (*this) == (const Policy &)other;
-}
index 8dfc4ed2b7e6a7bc56b2d71b3d03e3f0b2e73f43..69e0687a946698cedd318a56acf03879334ae43a 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2002-2004 Apple Computer, Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2002-2004,2012 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -53,25 +53,23 @@ public:
        SECCFFUNCTIONS(Policy, SecPolicyRef, errSecInvalidItemRef, gTypes().Policy)
 
     Policy(TP supportingTp, const CssmOid &policyOid);
        SECCFFUNCTIONS(Policy, SecPolicyRef, errSecInvalidItemRef, gTypes().Policy)
 
     Policy(TP supportingTp, const CssmOid &policyOid);
-    
+
 public:
     virtual ~Policy() throw();
 public:
     virtual ~Policy() throw();
-    
+
     TP &tp()                                                   { return mTp; }
     const TP &tp() const                               { return mTp; }
     const CssmOid &oid() const                 { return mOid; }
     const CssmData &value() const              { return mValue; }
        CssmOwnedData &value()                          { return mValue; }
     TP &tp()                                                   { return mTp; }
     const TP &tp() const                               { return mTp; }
     const CssmOid &oid() const                 { return mOid; }
     const CssmData &value() const              { return mValue; }
        CssmOwnedData &value()                          { return mValue; }
-       
+
     void setValue(const CssmData &value);
        void setProperties(CFDictionaryRef properties);
        CFDictionaryRef properties();
     void setValue(const CssmData &value);
        void setProperties(CFDictionaryRef properties);
        CFDictionaryRef properties();
-    
+
     bool operator < (const Policy& other) const;
     bool operator == (const Policy& other) const;
 
     bool operator < (const Policy& other) const;
     bool operator == (const Policy& other) const;
 
-    bool equal(SecCFObject &other);
-
 private:
     TP                                 mTp;                    // TP module for this Policy
     CssmAutoData               mOid;                   // OID for this policy
 private:
     TP                                 mTp;                    // TP module for this Policy
     CssmAutoData               mOid;                   // OID for this policy
index 522530fa620095f6448dbd8512bad908bf1628e4..242d65f2ffadfa7a122fe57ddb973c7074cba03f 100644 (file)
@@ -1,15 +1,15 @@
 /*
  * Copyright (c) 2002-2004,2012 Apple Inc. All Rights Reserved.
 /*
  * Copyright (c) 2002-2004,2012 Apple Inc. All Rights Reserved.
- * 
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -58,7 +58,7 @@ static const CssmOid *theOidList[] = {
        static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_PACKAGE_SIGNING),
        static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_REVOCATION_CRL),
        static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_REVOCATION_OCSP),
        static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_PACKAGE_SIGNING),
        static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_REVOCATION_CRL),
        static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_REVOCATION_OCSP),
-       static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT),    
+       static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT),
        static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_APPLEID_SHARING),
        static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_TIMESTAMPING),
        NULL    // sentinel
        static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_APPLEID_SHARING),
        static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_TIMESTAMPING),
        NULL    // sentinel
@@ -106,3 +106,13 @@ bool PolicyCursor::next(SecPointer<Policy> &policy)
     }
     return false;      // end of table, no more matches
 }
     }
     return false;      // end of table, no more matches
 }
+
+//
+// Return a new policy instance for an OID, outside of cursor iteration
+//
+void PolicyCursor::policy(const CSSM_OID* oid, SecPointer<Policy> &policy)
+{
+       const CssmOid *policyOid = static_cast<const CssmOid *>(oid);
+       policy = new Policy(theOneTP(), *policyOid);
+}
+
index 10a9c8470ec10989cf86d01798442860bc4fb605..84fbf73a614f19e5d67d4e9110af2bc1946fd5f2 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2002-2004 Apple Computer, Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2002-2004,2012 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -48,10 +48,12 @@ class PolicyCursor : public SecCFObject
 public:
        SECCFFUNCTIONS(PolicyCursor, SecPolicySearchRef, errSecInvalidSearchRef, gTypes().PolicyCursor)
 
 public:
        SECCFFUNCTIONS(PolicyCursor, SecPolicySearchRef, errSecInvalidSearchRef, gTypes().PolicyCursor)
 
-    PolicyCursor(const CSSM_OID* oid, const CSSM_DATA* value);
+       PolicyCursor(const CSSM_OID* oid, const CSSM_DATA* value);
        virtual ~PolicyCursor() throw();
        bool next(SecPointer<Policy> &policy);
 
        virtual ~PolicyCursor() throw();
        bool next(SecPointer<Policy> &policy);
 
+       static void policy(const CSSM_OID* oid, SecPointer<Policy> &policy);
+
 private:
     //CFArrayRef        mKeychainSearchList;
     //SecKeyUsage  mKeyUsage;
 private:
     //CFArrayRef        mKeychainSearchList;
     //SecKeyUsage  mKeyUsage;
@@ -59,7 +61,7 @@ private:
     CssmAutoData               mOid;
     bool                               mOidGiven;
     // value ignored (for now?)
     CssmAutoData               mOid;
     bool                               mOidGiven;
     // value ignored (for now?)
-    
+
 #if 1  // quick version -- using built-in policy list
 
     int                                        mSearchPos;     // next untried table entry
 #if 1  // quick version -- using built-in policy list
 
     int                                        mSearchPos;     // next untried table entry
index 92390f132cf62f83d3e42ce5808798cfd830ef72..dfd407a60860aa89d852ee1cbf1a8bd806f9c9be 100644 (file)
@@ -52,13 +52,13 @@ PrimaryKeyImpl::PrimaryKeyImpl(const DbAttributes &primaryKeyAttrs) : mMutex(Mut
        }
 
        // Careful with exceptions
        }
 
        // Careful with exceptions
-       Data = mAllocator.alloc<uint8>(Length);
+       Data = mAllocator.alloc<uint8>((UInt32)Length);
        uint8 *p = Data;
 
        putUInt32(p, primaryKeyAttrs.recordType());
        for (uint32 ix = 0; ix < primaryKeyAttrs.size(); ++ix)
        {
        uint8 *p = Data;
 
        putUInt32(p, primaryKeyAttrs.recordType());
        for (uint32 ix = 0; ix < primaryKeyAttrs.size(); ++ix)
        {
-               uint32 len = primaryKeyAttrs.at(ix).Value[0].Length;
+               UInt32 len = (UInt32)primaryKeyAttrs.at(ix).Value[0].Length;
                putUInt32(p, len);
                memcpy(p, primaryKeyAttrs.at(ix).Value[0].Data, len);
                p += len;
                putUInt32(p, len);
                memcpy(p, primaryKeyAttrs.at(ix).Value[0].Data, len);
                p += len;
@@ -73,7 +73,7 @@ PrimaryKeyImpl::createCursor(const Keychain &keychain)
 
        // @@@ Set up cursor to find item with this.
        uint8 *p = Data;
 
        // @@@ Set up cursor to find item with this.
        uint8 *p = Data;
-       uint32 left = Length;
+       uint32 left = (uint32)Length;
        if (left < sizeof(*p))
                MacOSError::throwMe(errSecNoSuchAttr); // XXX Not really but whatever.
 
        if (left < sizeof(*p))
                MacOSError::throwMe(errSecNoSuchAttr); // XXX Not really but whatever.
 
@@ -129,6 +129,6 @@ CSSM_DB_RECORDTYPE
 PrimaryKeyImpl::recordType() const
 {
        uint8 *data = Data;
 PrimaryKeyImpl::recordType() const
 {
        uint8 *data = Data;
-       uint32 length = Length;
+       uint32 length = (uint32)Length;
        return getUInt32(data, length);
 }
        return getUInt32(data, length);
 }
index 3aeeb27de256eff555b34a1fb74b26908909594e..d0a98f8fb818b08dc70d8660f867bb31b4971d91 100644 (file)
@@ -142,7 +142,7 @@ OSStatus SecACLCopyContents(SecACLRef acl,
 {
        CSSM_ACL_KEYCHAIN_PROMPT_SELECTOR cdsaPromptSelector;
        memset(&cdsaPromptSelector, 0, sizeof(cdsaPromptSelector));
 {
        CSSM_ACL_KEYCHAIN_PROMPT_SELECTOR cdsaPromptSelector;
        memset(&cdsaPromptSelector, 0, sizeof(cdsaPromptSelector));
-       OSStatus err = noErr;
+       OSStatus err = errSecSuccess;
        
        err = SecACLCopySimpleContents(acl, applicationList, description, &cdsaPromptSelector);
        *promptSelector = cdsaPromptSelector.flags;
        
        err = SecACLCopySimpleContents(acl, applicationList, description, &cdsaPromptSelector);
        *promptSelector = cdsaPromptSelector.flags;
@@ -204,10 +204,10 @@ OSStatus SecACLGetAuthorizations(SecACLRef acl,
        BEGIN_SECAPI
        AclAuthorizationSet auths = ACL::required(acl)->authorizations();
        if (Required(tagCount) < auths.size()) {        // overflow
        BEGIN_SECAPI
        AclAuthorizationSet auths = ACL::required(acl)->authorizations();
        if (Required(tagCount) < auths.size()) {        // overflow
-               *tagCount = auths.size();                               // report size required
-               CssmError::throwMe(paramErr);
+               *tagCount = (uint32)auths.size();                               // report size required
+               CssmError::throwMe(errSecParam);
        }
        }
-       *tagCount = auths.size();
+       *tagCount = (uint32)auths.size();
        copy(auths.begin(), auths.end(), tags);
        END_SECAPI
 }
        copy(auths.begin(), auths.end(), tags);
        END_SECAPI
 }
@@ -221,7 +221,7 @@ CFArrayRef SecACLCopyAuthorizations(SecACLRef acl)
        }
        
        AclAuthorizationSet auths = ACL::required(acl)->authorizations();
        }
        
        AclAuthorizationSet auths = ACL::required(acl)->authorizations();
-       uint32 numAuths = auths.size();                         
+       uint32 numAuths = (uint32)auths.size();                         
        
     CSSM_ACL_AUTHORIZATION_TAG* tags = new CSSM_ACL_AUTHORIZATION_TAG[numAuths];
     int i;
        
     CSSM_ACL_AUTHORIZATION_TAG* tags = new CSSM_ACL_AUTHORIZATION_TAG[numAuths];
     int i;
@@ -231,7 +231,7 @@ CFArrayRef SecACLCopyAuthorizations(SecACLRef acl)
     }
        
        OSStatus err = SecACLGetAuthorizations(acl, tags, &numAuths);
     }
        
        OSStatus err = SecACLGetAuthorizations(acl, tags, &numAuths);
-       if (noErr != err)
+       if (errSecSuccess != err)
        {
                
                return result;
        {
                
                return result;
@@ -275,9 +275,9 @@ OSStatus SecACLUpdateAuthorizations(SecACLRef acl, CFArrayRef authorizations)
 {
        if (NULL == acl || NULL == authorizations)
        {
 {
        if (NULL == acl || NULL == authorizations)
        {
-               return paramErr;
+               return errSecParam;
        }
        }
-       uint32 tagCount = CFArrayGetCount(authorizations);
+       uint32 tagCount = (uint32)CFArrayGetCount(authorizations);
        
        size_t tagSize = (tagCount * sizeof(CSSM_ACL_AUTHORIZATION_TAG));
        
        
        size_t tagSize = (tagCount * sizeof(CSSM_ACL_AUTHORIZATION_TAG));
        
index ada2817bbcc681be78849d2c0c8755a6035e6c54..fdc92ba56d808b92cb9f391d4c7c2850bf725f86 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2002-2004 Apple Computer, Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2002-2004,2013 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
+#include <SecBase.h>
 #include <Security/SecAccess.h>
 #include <Security/SecAccessPriv.h>
 #include <Security/SecAccess.h>
 #include <Security/SecAccessPriv.h>
+#include <Security/SecTrustedApplication.h>
+#include <Security/SecTrustedApplicationPriv.h>
 #include <security_keychain/Access.h>
 #include "SecBridge.h"
 #include <sys/param.h>
 
 #include <security_keychain/Access.h>
 #include "SecBridge.h"
 #include <sys/param.h>
 
+#undef secdebug
+#include <utilities/SecCFWrappers.h>
+
+
 /* No restrictions. Permission to perform all operations on
    the resource or available to an ACL owner.  */
 
 /* No restrictions. Permission to perform all operations on
    the resource or available to an ACL owner.  */
 
@@ -49,7 +56,7 @@ CFTypeRef kSecACLAuthorizationDerive = (CFTypeRef)(CFSTR("ACLAuthorizationDerive
 /* Defined authorization tag values for Keychain */
 
 
 /* Defined authorization tag values for Keychain */
 
 
-       
+
 CFTypeRef kSecACLAuthorizationKeychainCreate = (CFTypeRef)(CFSTR("ACLAuthorizationKeychainCreate"));
 CFTypeRef kSecACLAuthorizationKeychainDelete = (CFTypeRef)(CFSTR("ACLAuthorizationKeychainDelete"));
 CFTypeRef kSecACLAuthorizationKeychainItemRead = (CFTypeRef)(CFSTR("ACLAuthorizationKeychainItemRead"));
 CFTypeRef kSecACLAuthorizationKeychainCreate = (CFTypeRef)(CFSTR("ACLAuthorizationKeychainCreate"));
 CFTypeRef kSecACLAuthorizationKeychainDelete = (CFTypeRef)(CFSTR("ACLAuthorizationKeychainDelete"));
 CFTypeRef kSecACLAuthorizationKeychainItemRead = (CFTypeRef)(CFSTR("ACLAuthorizationKeychainItemRead"));
@@ -63,7 +70,7 @@ CFTypeRef kSecACLAuthorizationChangeOwner = (CFTypeRef)(CFSTR("ACLAuthorizationC
 
 static CFArrayRef copyTrustedAppListFromBundle(CFStringRef bundlePath, CFStringRef trustedAppListFileName);
 
 
 static CFArrayRef copyTrustedAppListFromBundle(CFStringRef bundlePath, CFStringRef trustedAppListFileName);
 
-static CFStringRef gKeys[] = 
+static CFStringRef gKeys[] =
 {
        (CFStringRef)kSecACLAuthorizationAny,
        (CFStringRef)kSecACLAuthorizationLogin,
 {
        (CFStringRef)kSecACLAuthorizationAny,
        (CFStringRef)kSecACLAuthorizationLogin,
@@ -86,10 +93,10 @@ static CFStringRef gKeys[] =
        (CFStringRef)kSecACLAuthorizationKeychainItemInsert,
        (CFStringRef)kSecACLAuthorizationKeychainItemModify,
        (CFStringRef)kSecACLAuthorizationKeychainItemDelete,
        (CFStringRef)kSecACLAuthorizationKeychainItemInsert,
        (CFStringRef)kSecACLAuthorizationKeychainItemModify,
        (CFStringRef)kSecACLAuthorizationKeychainItemDelete,
-       
+
        (CFStringRef)kSecACLAuthorizationChangeACL,
        (CFStringRef)kSecACLAuthorizationChangeOwner
        (CFStringRef)kSecACLAuthorizationChangeACL,
        (CFStringRef)kSecACLAuthorizationChangeOwner
-       
+
 };
 
 static sint32 gValues[] =
 };
 
 static sint32 gValues[] =
@@ -117,51 +124,54 @@ static sint32 gValues[] =
        CSSM_ACL_AUTHORIZATION_CHANGE_OWNER
 };
 
        CSSM_ACL_AUTHORIZATION_CHANGE_OWNER
 };
 
+static
 CFDictionaryRef CreateStringToNumDictionary()
 {
        int numItems = (sizeof(gValues) / sizeof(sint32));
 CFDictionaryRef CreateStringToNumDictionary()
 {
        int numItems = (sizeof(gValues) / sizeof(sint32));
-       CFMutableDictionaryRef tempDict = CFDictionaryCreateMutable(kCFAllocatorDefault, numItems, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);     
-       
+       CFMutableDictionaryRef tempDict = CFDictionaryCreateMutable(kCFAllocatorDefault, numItems, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+
        for (int iCnt = 0; iCnt < numItems; iCnt++)
        {
                sint32 aNumber = gValues[iCnt];
                CFNumberRef aNum = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &aNumber);
        for (int iCnt = 0; iCnt < numItems; iCnt++)
        {
                sint32 aNumber = gValues[iCnt];
                CFNumberRef aNum = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &aNumber);
-                               
+
                CFStringRef aString = gKeys[iCnt];
                CFDictionaryAddValue(tempDict, aString, aNum);
                CFStringRef aString = gKeys[iCnt];
                CFDictionaryAddValue(tempDict, aString, aNum);
-               CFRelease(aNum);                
+               CFRelease(aNum);
        }
        }
-       
+
        CFDictionaryRef result = CFDictionaryCreateCopy(kCFAllocatorDefault, tempDict);
        CFRelease(tempDict);
        return result;
        CFDictionaryRef result = CFDictionaryCreateCopy(kCFAllocatorDefault, tempDict);
        CFRelease(tempDict);
        return result;
-       
+
 }
 
 }
 
+static
 CFDictionaryRef CreateNumToStringDictionary()
 {
        int numItems = (sizeof(gValues) / sizeof(sint32));
 CFDictionaryRef CreateNumToStringDictionary()
 {
        int numItems = (sizeof(gValues) / sizeof(sint32));
-       
-       CFMutableDictionaryRef tempDict = CFDictionaryCreateMutable(kCFAllocatorDefault, numItems, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);   
-       
+
+       CFMutableDictionaryRef tempDict = CFDictionaryCreateMutable(kCFAllocatorDefault, numItems, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+
        for (int iCnt = 0; iCnt < numItems; iCnt++)
        {
                sint32 aNumber = gValues[iCnt];
        for (int iCnt = 0; iCnt < numItems; iCnt++)
        {
                sint32 aNumber = gValues[iCnt];
-               CFNumberRef aNum = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &aNumber);          
-               
+               CFNumberRef aNum = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &aNumber);
+
                CFStringRef aString = gKeys[iCnt];
                CFDictionaryAddValue(tempDict, aNum, aString);
                CFRelease(aNum);
                CFStringRef aString = gKeys[iCnt];
                CFDictionaryAddValue(tempDict, aNum, aString);
                CFRelease(aNum);
-       
+
        }
        }
-       
+
        CFDictionaryRef result = CFDictionaryCreateCopy(kCFAllocatorDefault, tempDict);
        CFRelease(tempDict);
        return result;
 }
 
 
        CFDictionaryRef result = CFDictionaryCreateCopy(kCFAllocatorDefault, tempDict);
        CFRelease(tempDict);
        return result;
 }
 
 
-
+/* TODO: This should be in some header */
+sint32 GetACLAuthorizationTagFromString(CFStringRef aclStr);
 sint32 GetACLAuthorizationTagFromString(CFStringRef aclStr)
 {
        if (NULL == aclStr)
 sint32 GetACLAuthorizationTagFromString(CFStringRef aclStr)
 {
        if (NULL == aclStr)
@@ -171,14 +181,14 @@ sint32 GetACLAuthorizationTagFromString(CFStringRef aclStr)
 #endif
                return 0;
        }
 #endif
                return 0;
        }
-       
+
        static CFDictionaryRef gACLMapping = NULL;
        static CFDictionaryRef gACLMapping = NULL;
-       
+
        if (NULL == gACLMapping)
        {
                gACLMapping = CreateStringToNumDictionary();
        }
        if (NULL == gACLMapping)
        {
                gACLMapping = CreateStringToNumDictionary();
        }
-                          
+
        sint32 result = 0;
        CFNumberRef valueResult = (CFNumberRef)CFDictionaryGetValue(gACLMapping, aclStr);
        if (NULL != valueResult)
        sint32 result = 0;
        CFNumberRef valueResult = (CFNumberRef)CFDictionaryGetValue(gACLMapping, aclStr);
        if (NULL != valueResult)
@@ -187,29 +197,31 @@ sint32 GetACLAuthorizationTagFromString(CFStringRef aclStr)
                {
                        return 0;
                }
                {
                        return 0;
                }
-          
+
        }
        else
        {
                return 0;
        }
        }
        else
        {
                return 0;
        }
-       
+
        return result;
        return result;
-               
+
 }
 
 }
 
+/* TODO: This should be in some header */
+CFStringRef GetAuthStringFromACLAuthorizationTag(sint32 tag);
 CFStringRef GetAuthStringFromACLAuthorizationTag(sint32 tag)
 {
        static CFDictionaryRef gTagMapping = NULL;
        CFNumberRef aNum = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tag);
 CFStringRef GetAuthStringFromACLAuthorizationTag(sint32 tag)
 {
        static CFDictionaryRef gTagMapping = NULL;
        CFNumberRef aNum = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tag);
-                       
+
        if (NULL == gTagMapping)
        {
                gTagMapping = CreateNumToStringDictionary();
        }
        if (NULL == gTagMapping)
        {
                gTagMapping = CreateNumToStringDictionary();
        }
-       
+
        CFStringRef result = (CFStringRef)kSecACLAuthorizationAny;
        CFStringRef result = (CFStringRef)kSecACLAuthorizationAny;
-       
+
        if (NULL != gTagMapping && CFDictionaryContainsKey(gTagMapping, aNum))
        {
                result = (CFStringRef)CFDictionaryGetValue(gTagMapping, aNum);
        if (NULL != gTagMapping && CFDictionaryContainsKey(gTagMapping, aNum))
        {
                result = (CFStringRef)CFDictionaryGetValue(gTagMapping, aNum);
@@ -271,90 +283,90 @@ OSStatus SecAccessCreateFromOwnerAndACL(const CSSM_ACL_OWNER_PROTOTYPE *owner,
 SecAccessRef SecAccessCreateWithOwnerAndACL(uid_t userId, gid_t groupId, SecAccessOwnerType ownerType, CFArrayRef acls, CFErrorRef *error)
 {
        SecAccessRef result = NULL;
 SecAccessRef SecAccessCreateWithOwnerAndACL(uid_t userId, gid_t groupId, SecAccessOwnerType ownerType, CFArrayRef acls, CFErrorRef *error)
 {
        SecAccessRef result = NULL;
-               
-       CSSM_ACL_PROCESS_SUBJECT_SELECTOR selector = 
+
+       CSSM_ACL_PROCESS_SUBJECT_SELECTOR selector =
        {
                CSSM_ACL_PROCESS_SELECTOR_CURRENT_VERSION,      // selector version
        {
                CSSM_ACL_PROCESS_SELECTOR_CURRENT_VERSION,      // selector version
-               ownerType,      
-               userId,                         
-               groupId                                 
+               ownerType,
+               userId,
+               groupId
        };
        };
-       
+
        CSSM_LIST_ELEMENT subject2 = { NULL, 0 };
        subject2.Element.Word.Data = (UInt8 *)&selector;
        subject2.Element.Word.Length = sizeof(selector);
        CSSM_LIST_ELEMENT subject2 = { NULL, 0 };
        subject2.Element.Word.Data = (UInt8 *)&selector;
        subject2.Element.Word.Length = sizeof(selector);
-       CSSM_LIST_ELEMENT subject1 = 
+       CSSM_LIST_ELEMENT subject1 =
        {
                &subject2, CSSM_ACL_SUBJECT_TYPE_PROCESS, CSSM_LIST_ELEMENT_WORDID
        };
        {
                &subject2, CSSM_ACL_SUBJECT_TYPE_PROCESS, CSSM_LIST_ELEMENT_WORDID
        };
-       
+
        CFIndex numAcls = 0;
        CFIndex numAcls = 0;
-       
+
        if (NULL != acls)
        {
                numAcls = CFArrayGetCount(acls);
        if (NULL != acls)
        {
                numAcls = CFArrayGetCount(acls);
-       }       
-       
+       }
+
 #ifndef NDEBUG
 #ifndef NDEBUG
-       CFStringRef debugStr = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, 
-               CFSTR("SecAccessCreateWithOwnerAndACL: processing %d acls"), numAcls);
+       CFStringRef debugStr = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
+               CFSTR("SecAccessCreateWithOwnerAndACL: processing %d acls"), (int)numAcls);
        CFShow(debugStr);
        CFRelease(debugStr);
 #endif
        CFShow(debugStr);
        CFRelease(debugStr);
 #endif
-       
+
        CSSM_ACL_AUTHORIZATION_TAG rights[numAcls];
        memset(rights, 0, sizeof(rights));
        CSSM_ACL_AUTHORIZATION_TAG rights[numAcls];
        memset(rights, 0, sizeof(rights));
-       
+
        for (CFIndex iCnt = 0; iCnt < numAcls; iCnt++)
        {
                CFStringRef aclStr = (CFStringRef)CFArrayGetValueAtIndex(acls, iCnt);
        for (CFIndex iCnt = 0; iCnt < numAcls; iCnt++)
        {
                CFStringRef aclStr = (CFStringRef)CFArrayGetValueAtIndex(acls, iCnt);
-               
+
 #ifndef NDEBUG
 #ifndef NDEBUG
-               debugStr = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, 
-                       CFSTR("SecAccessCreateWithOwnerAndACL: acls[%d] = %@"), iCnt, aclStr);
-                       
+               debugStr = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
+                       CFSTR("SecAccessCreateWithOwnerAndACL: acls[%d] = %@"), (int)iCnt, aclStr);
+
                CFShow(debugStr);
                CFRelease(debugStr);
 #endif
                CFShow(debugStr);
                CFRelease(debugStr);
 #endif
-               
+
                CSSM_ACL_AUTHORIZATION_TAG aTag = GetACLAuthorizationTagFromString(aclStr);
                CSSM_ACL_AUTHORIZATION_TAG aTag = GetACLAuthorizationTagFromString(aclStr);
-               
+
 #ifndef NDEBUG
 #ifndef NDEBUG
-               debugStr = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, 
-                       CFSTR("SecAccessCreateWithOwnerAndACL: rights[%d] = %d"), iCnt, aTag);
-                       
+               debugStr = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
+                       CFSTR("SecAccessCreateWithOwnerAndACL: rights[%d] = %d"), (int)iCnt, aTag);
+
                CFShow(debugStr);
                CFRelease(debugStr);
 #endif
                CFShow(debugStr);
                CFRelease(debugStr);
 #endif
-               
+
                rights[iCnt] = aTag;
        }
                rights[iCnt] = aTag;
        }
-       
-       
+
+
        for (CFIndex iCnt = 0; iCnt < numAcls; iCnt++)
        {
 #ifndef NDEBUG
        for (CFIndex iCnt = 0; iCnt < numAcls; iCnt++)
        {
 #ifndef NDEBUG
-               debugStr = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, 
-                       CFSTR("SecAccessCreateWithOwnerAndACL: rights[%d]  = %d"), iCnt, rights[iCnt]);
-                       
+               debugStr = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
+                       CFSTR("SecAccessCreateWithOwnerAndACL: rights[%d]  = %d"), (int)iCnt, rights[iCnt]);
+
                CFShow(debugStr);
                CFRelease(debugStr);
 #endif
                CFShow(debugStr);
                CFRelease(debugStr);
 #endif
-               
+
 
        }
 
        }
-       
-       CSSM_ACL_OWNER_PROTOTYPE owner = 
+
+       CSSM_ACL_OWNER_PROTOTYPE owner =
        {
                // TypedSubject
                { CSSM_LIST_TYPE_UNKNOWN, &subject1, &subject2 },
                // Delegate
                false
        };
        {
                // TypedSubject
                { CSSM_LIST_TYPE_UNKNOWN, &subject1, &subject2 },
                // Delegate
                false
        };
-       
-       
+
+
        // ACL entries (any number, just one here)
        // ACL entries (any number, just one here)
-       CSSM_ACL_ENTRY_INFO acl_rights[] = 
+       CSSM_ACL_ENTRY_INFO acl_rights[] =
        {
                {
                        // prototype
        {
                {
                        // prototype
@@ -363,16 +375,16 @@ SecAccessRef SecAccessCreateWithOwnerAndACL(uid_t userId, gid_t groupId, SecAcce
                                { CSSM_LIST_TYPE_UNKNOWN, &subject1, &subject2 },
                                false,  // Delegate
                                // rights for this entry
                                { CSSM_LIST_TYPE_UNKNOWN, &subject1, &subject2 },
                                false,  // Delegate
                                // rights for this entry
-                               { sizeof(rights) / sizeof(rights[0]), rights },
+                               { (uint32)(sizeof(rights) / sizeof(rights[0])), rights },
                                // rest is defaulted
                        }
                }
        };
                                // rest is defaulted
                        }
                }
        };
-       
-       OSStatus err = SecAccessCreateFromOwnerAndACL(&owner, 
+
+       OSStatus err = SecAccessCreateFromOwnerAndACL(&owner,
                sizeof(acl_rights) / sizeof(acl_rights[0]), acl_rights, &result);
                sizeof(acl_rights) / sizeof(acl_rights[0]), acl_rights, &result);
-               
-       if (noErr != err)
+
+       if (errSecSuccess != err)
        {
                result = NULL;
                if (NULL != error)
        {
                result = NULL;
                if (NULL != error)
@@ -380,7 +392,7 @@ SecAccessRef SecAccessCreateWithOwnerAndACL(uid_t userId, gid_t groupId, SecAcce
                        *error  = CFErrorCreate(kCFAllocatorDefault, CFSTR("FIX ME"), err, NULL);
                }
        }
                        *error  = CFErrorCreate(kCFAllocatorDefault, CFSTR("FIX ME"), err, NULL);
                }
        }
-       return result;          
+       return result;
 }
 
 
 }
 
 
@@ -402,11 +414,11 @@ OSStatus SecAccessCopyOwnerAndACL(SecAccessRef accessRef, uid_t* userId, gid_t*
        CSSM_ACL_ENTRY_INFO_PTR acls = NULL;
        uint32 aclCount = 0;
        OSStatus result = SecAccessGetOwnerAndACL(accessRef, &owner, &aclCount, &acls);
        CSSM_ACL_ENTRY_INFO_PTR acls = NULL;
        uint32 aclCount = 0;
        OSStatus result = SecAccessGetOwnerAndACL(accessRef, &owner, &aclCount, &acls);
-       if (noErr != result )
+       if (errSecSuccess != result )
        {
                return result;
        }
        {
                return result;
        }
-       
+
        if (NULL != owner)
        {
                CSSM_LIST_ELEMENT_PTR listHead = owner->TypedSubject.Head;
        if (NULL != owner)
        {
                CSSM_LIST_ELEMENT_PTR listHead = owner->TypedSubject.Head;
@@ -423,23 +435,23 @@ OSStatus SecAccessCopyOwnerAndACL(SecAccessRef accessRef, uid_t* userId, gid_t*
                                        {
                                                *userId = (uid_t)selectorPtr->uid;
                                        }
                                        {
                                                *userId = (uid_t)selectorPtr->uid;
                                        }
-                                       
+
                                        if (NULL != groupId)
                                        {
                                                *groupId = (gid_t)selectorPtr->gid;
                                        }
                                        if (NULL != groupId)
                                        {
                                                *groupId = (gid_t)selectorPtr->gid;
                                        }
-                                       
+
                                        if (NULL != ownerType)
                                        {
                                                *ownerType = (SecAccessOwnerType)selectorPtr->mask;
                                        }
                                }
                        }
                                        if (NULL != ownerType)
                                        {
                                                *ownerType = (SecAccessOwnerType)selectorPtr->mask;
                                        }
                                }
                        }
-                       
+
                }
                }
-               
+
        }
        }
-       
+
        if (NULL != aclList)
        {
 #ifndef NDEBUG
        if (NULL != aclList)
        {
 #ifndef NDEBUG
@@ -450,9 +462,9 @@ OSStatus SecAccessCopyOwnerAndACL(SecAccessRef accessRef, uid_t* userId, gid_t*
                CSSM_ACL_OWNER_PROTOTYPE_PTR protoPtr = NULL;
                uint32 numAcls = 0L;
                CSSM_ACL_ENTRY_INFO_PTR aclEntry = NULL;
                CSSM_ACL_OWNER_PROTOTYPE_PTR protoPtr = NULL;
                uint32 numAcls = 0L;
                CSSM_ACL_ENTRY_INFO_PTR aclEntry = NULL;
-                       
+
                result = SecAccessGetOwnerAndACL(accessRef, &protoPtr, &numAcls, &aclEntry);
                result = SecAccessGetOwnerAndACL(accessRef, &protoPtr, &numAcls, &aclEntry);
-               if (noErr == result)
+               if (errSecSuccess == result)
                {
 #ifndef NDEBUG
                        CFStringRef tempStr = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("SecAccessCopyOwnerAndACL: numAcls = %d"), numAcls);
                {
 #ifndef NDEBUG
                        CFStringRef tempStr = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("SecAccessCopyOwnerAndACL: numAcls = %d"), numAcls);
@@ -465,18 +477,18 @@ OSStatus SecAccessCopyOwnerAndACL(SecAccessRef accessRef, uid_t* userId, gid_t*
                                CSSM_ACL_ENTRY_PROTOTYPE prototype = aclEntry[iCnt].EntryPublicInfo;
                                CSSM_AUTHORIZATIONGROUP authGroup = prototype.Authorization;
                                int numAuthTags = (int)authGroup.NumberOfAuthTags;
                                CSSM_ACL_ENTRY_PROTOTYPE prototype = aclEntry[iCnt].EntryPublicInfo;
                                CSSM_AUTHORIZATIONGROUP authGroup = prototype.Authorization;
                                int numAuthTags = (int)authGroup.NumberOfAuthTags;
-                               
+
                                for (int jCnt = 0; jCnt < numAuthTags; jCnt++)
                                {
                                for (int jCnt = 0; jCnt < numAuthTags; jCnt++)
                                {
-                                       
+
                                        sint32 aTag = authGroup.AuthTags[jCnt];
                                        CFStringRef aString = GetAuthStringFromACLAuthorizationTag(aTag);
                                        sint32 aTag = authGroup.AuthTags[jCnt];
                                        CFStringRef aString = GetAuthStringFromACLAuthorizationTag(aTag);
-                                                                               
+
                                        CFArrayAppendValue(stringArray, aString);
                                }
                        }
                }
                                        CFArrayAppendValue(stringArray, aString);
                                }
                        }
                }
-               
+
                if (NULL != stringArray)
                {
                        if (0 < CFArrayGetCount(stringArray))
                if (NULL != stringArray)
                {
                        if (0 < CFArrayGetCount(stringArray))
@@ -486,8 +498,8 @@ OSStatus SecAccessCopyOwnerAndACL(SecAccessRef accessRef, uid_t* userId, gid_t*
                        CFRelease(stringArray);
                }
        }
                        CFRelease(stringArray);
                }
        }
-       
-       return result;  
+
+       return result;
 }
 
 /*!
 }
 
 /*!
@@ -517,7 +529,7 @@ CFArrayRef SecAccessCopyMatchingACLList(SecAccessRef accessRef, CFTypeRef author
        CFArrayRef result = NULL;
        CSSM_ACL_AUTHORIZATION_TAG tag = GetACLAuthorizationTagFromString((CFStringRef)authorizationTag);
        OSStatus err = SecAccessCopySelectedACLList(accessRef, tag, &result);
        CFArrayRef result = NULL;
        CSSM_ACL_AUTHORIZATION_TAG tag = GetACLAuthorizationTagFromString((CFStringRef)authorizationTag);
        OSStatus err = SecAccessCopySelectedACLList(accessRef, tag, &result);
-       if (noErr != err)
+       if (errSecSuccess != err)
        {
                result = NULL;
        }
        {
                result = NULL;
        }
@@ -536,23 +548,23 @@ CFArrayRef copyTrustedAppListFromBundle(CFStringRef bundlePath, CFStringRef trus
        CFMutableStringRef trustedAppListFileNameWithoutExtension = NULL;
 
     // Make a CFURLRef from the CFString representation of the bundleÕs path.
        CFMutableStringRef trustedAppListFileNameWithoutExtension = NULL;
 
     // Make a CFURLRef from the CFString representation of the bundleÕs path.
-    bundleURL = CFURLCreateWithFileSystemPath( 
+    bundleURL = CFURLCreateWithFileSystemPath(
         kCFAllocatorDefault,bundlePath,kCFURLPOSIXPathStyle,true);
 
        CFRange wholeStrRange;
         kCFAllocatorDefault,bundlePath,kCFURLPOSIXPathStyle,true);
 
        CFRange wholeStrRange;
-    
+
        if (!bundleURL)
         goto xit;
        if (!bundleURL)
         goto xit;
-        
+
     // Make a bundle instance using the URLRef.
     secBundle = CFBundleCreate(kCFAllocatorDefault,bundleURL);
     if (!secBundle)
         goto xit;
 
     // Make a bundle instance using the URLRef.
     secBundle = CFBundleCreate(kCFAllocatorDefault,bundleURL);
     if (!secBundle)
         goto xit;
 
-       trustedAppListFileNameWithoutExtension =                                
+       trustedAppListFileNameWithoutExtension =
                CFStringCreateMutableCopy(NULL,CFStringGetLength(trustedAppListFileName),trustedAppListFileName);
        wholeStrRange = CFStringFind(trustedAppListFileName,CFSTR(".plist"),0);
                CFStringCreateMutableCopy(NULL,CFStringGetLength(trustedAppListFileName),trustedAppListFileName);
        wholeStrRange = CFStringFind(trustedAppListFileName,CFSTR(".plist"),0);
-       
+
        CFStringDelete(trustedAppListFileNameWithoutExtension,wholeStrRange);
 
     // Look for a resource in the bundle by name and type
        CFStringDelete(trustedAppListFileNameWithoutExtension,wholeStrRange);
 
     // Look for a resource in the bundle by name and type
@@ -562,18 +574,18 @@ CFArrayRef copyTrustedAppListFromBundle(CFStringRef bundlePath, CFStringRef trus
 
     if ( trustedAppListFileNameWithoutExtension )
                CFRelease(trustedAppListFileNameWithoutExtension);
 
     if ( trustedAppListFileNameWithoutExtension )
                CFRelease(trustedAppListFileNameWithoutExtension);
-               
+
        if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault,trustedAppsURL,&xmlDataRef,NULL,NULL,&errorCode))
         goto xit;
        if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault,trustedAppsURL,&xmlDataRef,NULL,NULL,&errorCode))
         goto xit;
-        
+
        trustedAppsPlist = CFPropertyListCreateFromXMLData(kCFAllocatorDefault,xmlDataRef,kCFPropertyListImmutable,&errorString);
     trustedAppList = (CFArrayRef)trustedAppsPlist;
        trustedAppsPlist = CFPropertyListCreateFromXMLData(kCFAllocatorDefault,xmlDataRef,kCFPropertyListImmutable,&errorString);
     trustedAppList = (CFArrayRef)trustedAppsPlist;
-    
+
 xit:
     if (bundleURL)
 xit:
     if (bundleURL)
-        CFRelease(bundleURL);  
+        CFRelease(bundleURL);
     if (secBundle)
     if (secBundle)
-        CFRelease(secBundle);  
+        CFRelease(secBundle);
     if (trustedAppsURL)
         CFRelease(trustedAppsURL);
     if (xmlDataRef)
     if (trustedAppsURL)
         CFRelease(trustedAppsURL);
     if (xmlDataRef)
@@ -586,21 +598,21 @@ xit:
 
 OSStatus SecAccessCreateWithTrustedApplications(CFStringRef trustedApplicationsPListPath, CFStringRef accessLabel, Boolean allowAny, SecAccessRef* returnedAccess)
 {
 
 OSStatus SecAccessCreateWithTrustedApplications(CFStringRef trustedApplicationsPListPath, CFStringRef accessLabel, Boolean allowAny, SecAccessRef* returnedAccess)
 {
-       OSStatus err = noErr;
+       OSStatus err = errSecSuccess;
        SecAccessRef accessToReturn=nil;
        CFMutableArrayRef trustedApplications=nil;
        SecAccessRef accessToReturn=nil;
        CFMutableArrayRef trustedApplications=nil;
-       
+
        if (!allowAny) // use default access ("confirm access")
        {
                // make an exception list of applications you want to trust,
                // which are allowed to access the item without requiring user confirmation
                SecTrustedApplicationRef myself=NULL, someOther=NULL;
         CFArrayRef trustedAppListFromBundle=NULL;
        if (!allowAny) // use default access ("confirm access")
        {
                // make an exception list of applications you want to trust,
                // which are allowed to access the item without requiring user confirmation
                SecTrustedApplicationRef myself=NULL, someOther=NULL;
         CFArrayRef trustedAppListFromBundle=NULL;
-        
-        trustedApplications=CFArrayCreateMutable(kCFAllocatorDefault,0,&kCFTypeArrayCallBacks); 
+
+        trustedApplications=CFArrayCreateMutable(kCFAllocatorDefault,0,&kCFTypeArrayCallBacks);
         err = SecTrustedApplicationCreateFromPath(NULL, &myself);
         if (!err)
         err = SecTrustedApplicationCreateFromPath(NULL, &myself);
         if (!err)
-            CFArrayAppendValue(trustedApplications,myself); 
+            CFArrayAppendValue(trustedApplications,myself);
 
                CFURLRef url = CFURLCreateWithFileSystemPath(NULL, trustedApplicationsPListPath, kCFURLPOSIXPathStyle, 0);
                CFStringRef leafStr = NULL;
 
                CFURLRef url = CFURLCreateWithFileSystemPath(NULL, trustedApplicationsPListPath, kCFURLPOSIXPathStyle, 0);
                CFStringRef leafStr = NULL;
@@ -621,22 +633,52 @@ OSStatus SecAccessCreateWithTrustedApplications(CFStringRef trustedApplicationsP
                        CFRelease(bndlPathURL);
         if (trustedAppListFromBundle)
         {
                        CFRelease(bndlPathURL);
         if (trustedAppListFromBundle)
         {
-                   int ix,top;
+            CFIndex ix,top;
             char buffer[MAXPATHLEN];
             top = CFArrayGetCount(trustedAppListFromBundle);
             for (ix=0;ix<top;ix++)
             {
                 CFStringRef filename = (CFStringRef)CFArrayGetValueAtIndex(trustedAppListFromBundle,ix);
                 CFIndex stringLength = CFStringGetLength(filename);
             char buffer[MAXPATHLEN];
             top = CFArrayGetCount(trustedAppListFromBundle);
             for (ix=0;ix<top;ix++)
             {
                 CFStringRef filename = (CFStringRef)CFArrayGetValueAtIndex(trustedAppListFromBundle,ix);
                 CFIndex stringLength = CFStringGetLength(filename);
-                CFIndex usedBufLen; 
+                CFIndex usedBufLen;
 
                 if (stringLength != CFStringGetBytes(filename,CFRangeMake(0,stringLength),kCFStringEncodingUTF8,0,
                     false,(UInt8 *)&buffer,MAXPATHLEN, &usedBufLen))
                     break;
                 buffer[usedBufLen] = 0;
 
                 if (stringLength != CFStringGetBytes(filename,CFRangeMake(0,stringLength),kCFStringEncodingUTF8,0,
                     false,(UInt8 *)&buffer,MAXPATHLEN, &usedBufLen))
                     break;
                 buffer[usedBufLen] = 0;
-                err = SecTrustedApplicationCreateFromPath(buffer,&someOther);
+                               //
+                               // Support specification of trusted applications by either
+                               // a full pathname or a code requirement string.
+                               //
+                               if (buffer[0]=='/')
+                               {
+                                       err = SecTrustedApplicationCreateFromPath(buffer,&someOther);
+                               }
+                               else
+                               {
+                                       char *buf = NULL;
+                                       CFStringRef reqStr = filename;
+                                       CFArrayRef descArray = CFStringCreateArrayBySeparatingStrings(NULL, reqStr, CFSTR("\""));
+                                       if (descArray && (CFArrayGetCount(descArray) > 1))
+                                       {
+                                               CFStringRef descStr = (CFStringRef) CFArrayGetValueAtIndex(descArray, 1);
+                                               if (descStr)
+                                                       buf = CFStringToCString(descStr);
+                                       }
+                                       SecRequirementRef reqRef = NULL;
+                                       err = SecRequirementCreateWithString(reqStr, kSecCSDefaultFlags, &reqRef);
+                                       if (!err)
+                                               err = SecTrustedApplicationCreateFromRequirement((const char *)buf, reqRef, &someOther);
+                                       if (buf)
+                                               free(buf);
+                                       CFReleaseSafe(reqRef);
+                                       CFReleaseSafe(descArray);
+                               }
                 if (!err)
                 if (!err)
-                    CFArrayAppendValue(trustedApplications,someOther); 
+                    CFArrayAppendValue(trustedApplications,someOther);
+
+                               if (someOther)
+                                       CFReleaseNull(someOther);
             }
             CFRelease(trustedAppListFromBundle);
         }
             }
             CFRelease(trustedAppListFromBundle);
         }
index 299de8371ecc69597235ed63edaa10955540c14c..42af692dfd8d91072a9a8d0f4059989a1dfd1f43 100644 (file)
@@ -21,6 +21,7 @@
  * @APPLE_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
+#include <Security/SecBase.h>
 #include <Security/SecBasePriv.h>
 #include <Security/SecKeychainPriv.h>
 #include <security_utilities/threading.h>
 #include <Security/SecBasePriv.h>
 #include <Security/SecKeychainPriv.h>
 #include <security_utilities/threading.h>
@@ -51,7 +52,7 @@ SecCopyErrorMessageString(OSStatus status, void *reserved)
                        else
                        {
                                // no error message found, so format a faked-up error message from the status
                        else
                        {
                                // no error message found, so format a faked-up error message from the status
-                               result = CFStringCreateWithFormat(NULL, NULL, CFSTR("OSStatus %d"), status);
+                               result = CFStringCreateWithFormat(NULL, NULL, CFSTR("OSStatus %d"), (int)status);
                        }
                }
                
                        }
                }
                
@@ -136,7 +137,7 @@ copyErrorMessageFromBundle(OSStatus status,CFStringRef tableName)
         goto xit;
        
     // Convert status to Int32 string representation, e.g. "-25924"
         goto xit;
        
     // Convert status to Int32 string representation, e.g. "-25924"
-    keyString = CFStringCreateWithFormat (kCFAllocatorDefault,NULL,CFSTR("%d"),status);
+    keyString = CFStringCreateWithFormat (kCFAllocatorDefault,NULL,CFSTR("%d"),(int)status);
     if (!keyString)
         goto xit;
 
     if (!keyString)
         goto xit;
 
@@ -165,7 +166,7 @@ OSStatus SecKeychainErrFromOSStatus(OSStatus osStatus)
                        case CSSM_ERRCODE_SERVICE_NOT_AVAILABLE:
                                return errSecNotAvailable;
                        case CSSM_ERRCODE_USER_CANCELED:
                        case CSSM_ERRCODE_SERVICE_NOT_AVAILABLE:
                                return errSecNotAvailable;
                        case CSSM_ERRCODE_USER_CANCELED:
-                               return userCanceledErr;
+                               return errSecUserCanceled;
                        case CSSM_ERRCODE_OPERATION_AUTH_DENIED:
                                return errSecAuthFailed;
                        case CSSM_ERRCODE_NO_USER_INTERACTION:
                        case CSSM_ERRCODE_OPERATION_AUTH_DENIED:
                                return errSecAuthFailed;
                        case CSSM_ERRCODE_NO_USER_INTERACTION:
@@ -173,7 +174,7 @@ OSStatus SecKeychainErrFromOSStatus(OSStatus osStatus)
                        case CSSM_ERRCODE_IN_DARK_WAKE:
                                return errSecInDarkWake;
                        case CSSM_ERRCODE_OS_ACCESS_DENIED:
                        case CSSM_ERRCODE_IN_DARK_WAKE:
                                return errSecInDarkWake;
                        case CSSM_ERRCODE_OS_ACCESS_DENIED:
-                return wrPermErr;
+                return errSecWrPerm;
                        case CSSM_ERRCODE_INSUFFICIENT_CLIENT_IDENTIFICATION:
                                return errSecInsufficientClientID;
                        case CSSM_ERRCODE_DEVICE_RESET:
                        case CSSM_ERRCODE_INSUFFICIENT_CLIENT_IDENTIFICATION:
                                return errSecInsufficientClientID;
                        case CSSM_ERRCODE_DEVICE_RESET:
@@ -296,7 +297,7 @@ OSStatus SecKeychainErrFromOSStatus(OSStatus osStatus)
                case CSSMERR_DL_DATASTORE_ALREADY_EXISTS:
                        return errSecDuplicateKeychain;
                case CSSMERR_APPLEDL_DISK_FULL:
                case CSSMERR_DL_DATASTORE_ALREADY_EXISTS:
                        return errSecDuplicateKeychain;
                case CSSMERR_APPLEDL_DISK_FULL:
-                       return dskFulErr;
+                       return errSecDskFull;
                case CSSMERR_DL_INVALID_OPEN_PARAMETERS: 
                case CSSMERR_APPLEDL_INVALID_OPEN_PARAMETERS:
                case CSSMERR_APPLE_DOTMAC_REQ_SERVER_PARAM:
                case CSSMERR_DL_INVALID_OPEN_PARAMETERS: 
                case CSSMERR_APPLEDL_INVALID_OPEN_PARAMETERS:
                case CSSMERR_APPLE_DOTMAC_REQ_SERVER_PARAM:
@@ -309,7 +310,7 @@ OSStatus SecKeychainErrFromOSStatus(OSStatus osStatus)
                case CSSMERR_TP_OS_ACCESS_DENIED: 
                case CSSMERR_AC_OS_ACCESS_DENIED: 
                case CSSMERR_CL_OS_ACCESS_DENIED:
                case CSSMERR_TP_OS_ACCESS_DENIED: 
                case CSSMERR_AC_OS_ACCESS_DENIED: 
                case CSSMERR_CL_OS_ACCESS_DENIED:
-                       return wrPermErr;
+                       return errSecWrPerm;
                case CSSMERR_CSSM_BUFFER_TOO_SMALL:
                        return errSecBufferTooSmall;
                case CSSMERR_CSSM_FUNCTION_NOT_IMPLEMENTED:
                case CSSMERR_CSSM_BUFFER_TOO_SMALL:
                        return errSecBufferTooSmall;
                case CSSMERR_CSSM_FUNCTION_NOT_IMPLEMENTED:
@@ -450,7 +451,7 @@ OSStatus SecKeychainErrFromOSStatus(OSStatus osStatus)
                case CSSMERR_AC_USER_CANCELED:
                case CSSMERR_CL_USER_CANCELED:
                case CSSMERR_DL_USER_CANCELED:
                case CSSMERR_AC_USER_CANCELED:
                case CSSMERR_CL_USER_CANCELED:
                case CSSMERR_DL_USER_CANCELED:
-                       return userCanceledErr;
+                       return errSecUserCanceled;
                case CSSMERR_CSSM_NO_USER_INTERACTION:
                case CSSMERR_CSP_NO_USER_INTERACTION:
                case CSSMERR_TP_NO_USER_INTERACTION:
                case CSSMERR_CSSM_NO_USER_INTERACTION:
                case CSSMERR_CSP_NO_USER_INTERACTION:
                case CSSMERR_TP_NO_USER_INTERACTION:
index 9255e2c3bb7d1a4bb424cc734376844a01f452a0..69f42d29a409cf0e5217adc962d824bbf1e3df92 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2000-2010 Apple Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2000-2013 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
 /*!
        @header SecBase
  * @APPLE_LICENSE_HEADER_END@
  */
 
 /*!
        @header SecBase
-       SecBase contains common declarations for the Security functions. 
+       SecBase contains common declarations for the Security functions.
 */
 
 #ifndef _SECURITY_SECBASE_H_
 #define _SECURITY_SECBASE_H_
 
 #include <CoreFoundation/CFBase.h>
 */
 
 #ifndef _SECURITY_SECBASE_H_
 #define _SECURITY_SECBASE_H_
 
 #include <CoreFoundation/CFBase.h>
+#include <AvailabilityMacros.h>
+
+#if defined(__clang__)
+#define SEC_DEPRECATED_ATTRIBUTE DEPRECATED_ATTRIBUTE
+#else
+#define SEC_DEPRECATED_ATTRIBUTE
+#endif
 
 #if defined(__cplusplus)
 extern "C" {
 
 #if defined(__cplusplus)
 extern "C" {
@@ -64,12 +71,12 @@ typedef OSType SecKeychainAttrType;
 
 /*!
     @struct SecKeychainAttribute
 
 /*!
     @struct SecKeychainAttribute
-    @abstract Contains keychain attributes. 
+    @abstract Contains keychain attributes.
     @field tag A 4-byte attribute tag.
     @field length The length of the buffer pointed to by data.
     @field data A pointer to the attribute data.
 */
     @field tag A 4-byte attribute tag.
     @field length The length of the buffer pointed to by data.
     @field data A pointer to the attribute data.
 */
-struct SecKeychainAttribute 
+struct SecKeychainAttribute
 {
     SecKeychainAttrType        tag;
     UInt32 length;
 {
     SecKeychainAttrType        tag;
     UInt32 length;
@@ -89,7 +96,7 @@ typedef SecKeychainAttribute *SecKeychainAttributePtr;
     @field count An unsigned 32-bit integer that represents the number of keychain attributes in the array.
     @field attr A pointer to the first keychain attribute in the array.
 */
     @field count An unsigned 32-bit integer that represents the number of keychain attributes in the array.
     @field attr A pointer to the first keychain attribute in the array.
 */
-struct SecKeychainAttributeList 
+struct SecKeychainAttributeList
 {
     UInt32 count;
     SecKeychainAttribute *attr;
 {
     UInt32 count;
     SecKeychainAttribute *attr;
@@ -153,11 +160,11 @@ typedef struct OpaqueSecPasswordRef *SecPasswordRef;
 
 /*!
     @typedef SecKeychainAttributeInfo
 
 /*!
     @typedef SecKeychainAttributeInfo
-    @abstract Represents an attribute. 
-    @field count The number of tag-format pairs in the respective arrays. 
+    @abstract Represents an attribute.
+    @field count The number of tag-format pairs in the respective arrays.
     @field tag A pointer to the first attribute tag in the array.
     @field format A pointer to the first CSSM_DB_ATTRIBUTE_FORMAT in the array.
     @field tag A pointer to the first attribute tag in the array.
     @field format A pointer to the first CSSM_DB_ATTRIBUTE_FORMAT in the array.
-    @discussion Each tag and format item form a pair.  
+    @discussion Each tag and format item form a pair.
 */
 struct SecKeychainAttributeInfo
 {
 */
 struct SecKeychainAttributeInfo
 {
@@ -177,12 +184,19 @@ typedef struct SecKeychainAttributeInfo  SecKeychainAttributeInfo;
 CFStringRef SecCopyErrorMessageString(OSStatus status, void *reserved);
 
 /*!
 CFStringRef SecCopyErrorMessageString(OSStatus status, void *reserved);
 
 /*!
-@enum Security Error Codes 
+@enum Security Error Codes
 @abstract Result codes returned from Security framework functions.
 @constant errSecSuccess No error.
 @constant errSecUnimplemented Function or operation not implemented.
 @abstract Result codes returned from Security framework functions.
 @constant errSecSuccess No error.
 @constant errSecUnimplemented Function or operation not implemented.
+@constant errSecDskFull Disk Full error.
+@constant errSecIO I/O error.
 @constant errSecParam One or more parameters passed to a function were not valid.
 @constant errSecParam One or more parameters passed to a function were not valid.
+@constant errSecWrPerm Write permissions error.
 @constant errSecAllocate Failed to allocate memory.
 @constant errSecAllocate Failed to allocate memory.
+@constant errSecUserCanceled User canceled the operation.
+@constant errSecBadReq Bad parameter or invalid state for operation.
+@constant errSecInternalComponent
+@constant errSecCoreFoundationUnknown
 @constant errSecNotAvailable No keychain is available.
 @constant errSecReadOnly Read only error.
 @constant errSecAuthFailed Authorization/Authentication failed.
 @constant errSecNotAvailable No keychain is available.
 @constant errSecReadOnly Read only error.
 @constant errSecAuthFailed Authorization/Authentication failed.
@@ -224,7 +238,7 @@ CFStringRef SecCopyErrorMessageString(OSStatus status, void *reserved);
 @constant errSecPassphraseRequired Passphrase is required for import/export.
 @constant errSecInvalidPasswordRef The password reference was invalid.
 @constant errSecInvalidTrustSettings The Trust Settings Record was corrupted.
 @constant errSecPassphraseRequired Passphrase is required for import/export.
 @constant errSecInvalidPasswordRef The password reference was invalid.
 @constant errSecInvalidTrustSettings The Trust Settings Record was corrupted.
-@constant errSecNoTrustSettings No Trust Settings were found. 
+@constant errSecNoTrustSettings No Trust Settings were found.
 @constant errSecPkcs12VerifyFailure MAC verification failed during PKCS12 Import.
 @constant errSecDecode Unable to decode the provided data.
 
 @constant errSecPkcs12VerifyFailure MAC verification failed during PKCS12 Import.
 @constant errSecDecode Unable to decode the provided data.
 
@@ -242,8 +256,17 @@ enum
 {
     errSecSuccess                = 0,       /* No error. */
     errSecUnimplemented          = -4,      /* Function or operation not implemented. */
 {
     errSecSuccess                = 0,       /* No error. */
     errSecUnimplemented          = -4,      /* Function or operation not implemented. */
+    errSecDskFull                = -34,
+    errSecIO                     = -36,     /*I/O error (bummers)*/
+
     errSecParam                  = -50,     /* One or more parameters passed to a function were not valid. */
     errSecParam                  = -50,     /* One or more parameters passed to a function were not valid. */
+    errSecWrPerm                 = -61,     /* write permissions error*/
     errSecAllocate               = -108,    /* Failed to allocate memory. */
     errSecAllocate               = -108,    /* Failed to allocate memory. */
+    errSecUserCanceled           = -128,    /* User canceled the operation. */
+    errSecBadReq                 = -909,    /* Bad parameter or invalid state for operation. */
+
+    errSecInternalComponent      = -2070,
+    errSecCoreFoundationUnknown  = -4960,
 
     errSecNotAvailable           = -25291,     /* No keychain is available. You may need to restart your computer. */
     errSecReadOnly               = -25292,     /* This keychain cannot be modified. */
 
     errSecNotAvailable           = -25291,     /* No keychain is available. You may need to restart your computer. */
     errSecReadOnly               = -25292,     /* This keychain cannot be modified. */
@@ -274,8 +297,8 @@ enum
     errSecDataNotModifiable      = -25317,     /* The contents of this item cannot be modified. */
     errSecCreateChainFailed      = -25318,     /* One or more certificates required to validate this certificate cannot be found. */
     errSecInvalidPrefsDomain     = -25319,     /* The specified preferences domain is not valid. */
     errSecDataNotModifiable      = -25317,     /* The contents of this item cannot be modified. */
     errSecCreateChainFailed      = -25318,     /* One or more certificates required to validate this certificate cannot be found. */
     errSecInvalidPrefsDomain     = -25319,     /* The specified preferences domain is not valid. */
-    errSecInDarkWake            = -25320,      /* In dark wake, no UI possible */
-       
+    errSecInDarkWake             = -25320,     /* In dark wake, no UI possible */
+
        errSecACLNotSimple           = -25240,  /* The specified access control list is not in standard (simple) form. */
        errSecPolicyNotFound         = -25241,  /* The specified policy cannot be found. */
        errSecInvalidTrustSetting    = -25242,  /* The specified trust setting is invalid. */
        errSecACLNotSimple           = -25240,  /* The specified access control list is not in standard (simple) form. */
        errSecPolicyNotFound         = -25241,  /* The specified policy cannot be found. */
        errSecInvalidTrustSetting    = -25242,  /* The specified trust setting is invalid. */
@@ -292,7 +315,7 @@ enum
        errSecNoTrustSettings        = -25263,  /* No Trust Settings were found. */
        errSecPkcs12VerifyFailure    = -25264,  /* MAC verification failed during PKCS12 import (wrong password?) */
        errSecNotSigner              = -26267,  /* A certificate was not signed by its proposed parent. */
        errSecNoTrustSettings        = -25263,  /* No Trust Settings were found. */
        errSecPkcs12VerifyFailure    = -25264,  /* MAC verification failed during PKCS12 import (wrong password?) */
        errSecNotSigner              = -26267,  /* A certificate was not signed by its proposed parent. */
-       
+
        errSecDecode                 = -26275,  /* Unable to decode the provided data. */
 
        errSecServiceNotAvailable                       = -67585,       /* The required service is not available. */
        errSecDecode                 = -26275,  /* Unable to decode the provided data. */
 
        errSecServiceNotAvailable                       = -67585,       /* The required service is not available. */
@@ -311,8 +334,8 @@ enum
        errSecFileTooBig                                                = -67597,       /* The file is too big. */
        errSecInvalidDatabaseBlob                       = -67598,       /* The specified database has an invalid blob. */
        errSecInvalidKeyBlob                                    = -67599,       /* The specified database has an invalid key blob. */
        errSecFileTooBig                                                = -67597,       /* The file is too big. */
        errSecInvalidDatabaseBlob                       = -67598,       /* The specified database has an invalid blob. */
        errSecInvalidKeyBlob                                    = -67599,       /* The specified database has an invalid key blob. */
-       errSecIncompatibleDatabaseBlob          = -67600,       /* The specified database has an incompatible blob. */ 
-       errSecIncompatibleKeyBlob                       = -67601,       /* The specified database has an incompatible key blob. */   
+       errSecIncompatibleDatabaseBlob          = -67600,       /* The specified database has an incompatible blob. */
+       errSecIncompatibleKeyBlob                       = -67601,       /* The specified database has an incompatible key blob. */
        errSecHostNameMismatch                          = -67602,       /* A host name mismatch has occurred. */
        errSecUnknownCriticalExtensionFlag      = -67603,       /* There is an unknown critical extension flag. */
        errSecNoBasicConstraints                        = -67604,       /* No basic constraints were found. */
        errSecHostNameMismatch                          = -67602,       /* A host name mismatch has occurred. */
        errSecUnknownCriticalExtensionFlag      = -67603,       /* There is an unknown critical extension flag. */
        errSecNoBasicConstraints                        = -67604,       /* No basic constraints were found. */
@@ -381,7 +404,7 @@ enum
        errSecNotInitialized                                            = -67667,       /* A function was called without initializing CSSM. */
        errSecInvalidHandleUsage                                = -67668,       /* The CSSM handle does not match with the service type. */
        errSecPVCReferentNotFound                               = -67669,       /* A reference to the calling module was not found in the list of authorized callers. */
        errSecNotInitialized                                            = -67667,       /* A function was called without initializing CSSM. */
        errSecInvalidHandleUsage                                = -67668,       /* The CSSM handle does not match with the service type. */
        errSecPVCReferentNotFound                               = -67669,       /* A reference to the calling module was not found in the list of authorized callers. */
-       errSecFunctionIntegrityFail                             = -67670,       /* A function address was not within the verified module. */    
+       errSecFunctionIntegrityFail                             = -67670,       /* A function address was not within the verified module. */
        errSecInternalError                                             = -67671,       /* An internal error has occurred. */
        errSecMemoryError                                                       = -67672,       /* A memory error has occurred. */
        errSecInvalidData                                                       = -67673,       /* Invalid data was encountered. */
        errSecInternalError                                             = -67671,       /* An internal error has occurred. */
        errSecMemoryError                                                       = -67672,       /* A memory error has occurred. */
        errSecInvalidData                                                       = -67673,       /* Invalid data was encountered. */
index 61ba69ff77ccf4e6e7d73f734bc4fc38baa39160..c043906cd0590a1cb63b055d9c858f4935fcefdc 100644 (file)
@@ -135,7 +135,7 @@ static size_t SecBase64Encode_(  unsigned char const *src
 
     if(lineLen > 0)
     {
 
     if(lineLen > 0)
     {
-        unsigned    numLines    =   (total + (lineLen - 1)) / lineLen;
+        size_t    numLines    =   (total + (lineLen - 1)) / lineLen;
 
         total += 2 * (numLines - 1);
     }
 
         total += 2 * (numLines - 1);
     }
index 5626f81e154f30c5866185517ed494bf1861c8e4..cd2c25d809b99378c57f2cf5e264f9c2a1cc8f63 100644 (file)
@@ -45,13 +45,13 @@ using namespace KeychainCore;
 //     END_API3(name, bad) // like END_API1, with API name as debug scope for printing function result
 //
 #define BEGIN_SECAPI \
 //     END_API3(name, bad) // like END_API1, with API name as debug scope for printing function result
 //
 #define BEGIN_SECAPI \
-    OSStatus __secapiresult = noErr; \
+    OSStatus __secapiresult = errSecSuccess; \
        try {
 #define END_SECAPI }\
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); } \
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); } \
        try {
 #define END_SECAPI }\
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); } \
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); } \
-       catch (const std::bad_alloc &) { __secapiresult=memFullErr; } \
-       catch (...) { __secapiresult=internalComponentErr; } \
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; } \
+       catch (...) { __secapiresult=errSecInternalComponent; } \
     return __secapiresult;
 #define END_SECAPI1(BAD_RETURN_VAL) \
        } \
     return __secapiresult;
 #define END_SECAPI1(BAD_RETURN_VAL) \
        } \
index 1f0494b73ae9369124e8a2839d11109599e320c1..01e0e9820900071013583415bb81fdeaf7c5b0e7 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2002-2010 Apple Inc. All Rights Reserved.
+ * Copyright (c) 2002-2013 Apple Inc. All Rights Reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 #include <sys/param.h>
 #include "CertificateValues.h"
 #include "SecCertificateP.h"
 #include <sys/param.h>
 #include "CertificateValues.h"
 #include "SecCertificateP.h"
+//
+//#include "AppleBaselineEscrowCertificates.h"
+//
+//######################################################################
+//%%% start workaround: rdar://14292830
+//######################################################################
+
+#ifndef sec_AppleBaselineEscrowCertificates_h
+#define sec_AppleBaselineEscrowCertificates_h
+
+struct RootRecord
+{
+       size_t  _length;
+       UInt8*  _bytes;
+};
+
+/* ==========================================================================
+    Production Escrow Certificates
+   ========================================================================== */
+
+static const UInt8 kProductionEscrowRootGM[] = {
+       0x30,0x82,0x03,0xD0,0x30,0x82,0x02,0xB8,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x64,
+       0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,
+       0x79,0x31,0x0C,0x30,0x0A,0x06,0x03,0x55,0x04,0x05,0x13,0x03,0x31,0x30,0x30,0x31,
+       0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,
+       0x06,0x03,0x55,0x04,0x0A,0x13,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x6E,0x63,
+       0x2E,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0B,0x13,0x1D,0x41,0x70,0x70,0x6C,
+       0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,
+       0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,
+       0x04,0x03,0x13,0x16,0x45,0x73,0x63,0x72,0x6F,0x77,0x20,0x53,0x65,0x72,0x76,0x69,
+       0x63,0x65,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x33,
+       0x30,0x38,0x30,0x32,0x32,0x33,0x32,0x34,0x34,0x34,0x5A,0x17,0x0D,0x32,0x33,0x30,
+       0x38,0x30,0x32,0x32,0x33,0x32,0x34,0x34,0x34,0x5A,0x30,0x79,0x31,0x0C,0x30,0x0A,
+       0x06,0x03,0x55,0x04,0x05,0x13,0x03,0x31,0x30,0x30,0x31,0x0B,0x30,0x09,0x06,0x03,
+       0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,
+       0x13,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x26,0x30,0x24,
+       0x06,0x03,0x55,0x04,0x0B,0x13,0x1D,0x41,0x70,0x70,0x6C,0x65,0x20,0x43,0x65,0x72,
+       0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,
+       0x72,0x69,0x74,0x79,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x03,0x13,0x16,0x45,
+       0x73,0x63,0x72,0x6F,0x77,0x20,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x20,0x52,0x6F,
+       0x6F,0x74,0x20,0x43,0x41,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,
+       0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,
+       0x0A,0x02,0x82,0x01,0x01,0x00,0xD0,0xA3,0xF4,0x56,0x7D,0x3F,0x46,0x31,0xD2,0x56,
+       0xA0,0xDF,0x42,0xA0,0x29,0x83,0x1E,0xB9,0x82,0xB5,0xA5,0xFF,0x3E,0xDE,0xB5,0x0F,
+       0x4A,0x8A,0x28,0x60,0xCF,0x75,0xB4,0xA0,0x70,0x7C,0xF5,0xE2,0x94,0xF3,0x22,0x02,
+       0xC8,0x81,0xCE,0x34,0xC7,0x66,0x6A,0x18,0xAA,0xB4,0xFD,0x6D,0xB0,0x0B,0xDD,0x4A,
+       0xDD,0xCF,0xE0,0x08,0x1B,0x1C,0xA6,0xDB,0xBA,0xB2,0xC1,0xA4,0x10,0x5F,0x35,0x4F,
+       0x8B,0x8B,0x7A,0xA3,0xDB,0x3C,0xF6,0x54,0x95,0x42,0xAD,0x2A,0x3B,0xFE,0x06,0x8C,
+       0xE1,0x92,0xF1,0x60,0x97,0x58,0x1B,0xD9,0x8F,0xBE,0xFB,0x46,0x4C,0x29,0x5C,0x1C,
+       0xF0,0x20,0xB6,0x2B,0xA5,0x12,0x09,0x9B,0x28,0x41,0x34,0x97,0x9F,0xF3,0x88,0x4B,
+       0x69,0x72,0xEA,0x3A,0x27,0xB0,0x50,0x1D,0x88,0x29,0x0D,0xBB,0xED,0x04,0xA2,0x11,
+       0xCF,0x0C,0x5B,0x65,0x61,0x35,0xBD,0xF2,0x0D,0xFC,0xE2,0xB9,0x20,0xD3,0xB7,0x03,
+       0x70,0x39,0xD5,0xE0,0x86,0x7C,0x04,0xCC,0xC9,0xA1,0x85,0xB4,0x9B,0xBC,0x88,0x4E,
+       0xD7,0xAD,0x5C,0xFF,0x2C,0x0D,0x80,0x8E,0x51,0x39,0x20,0x8B,0xAF,0x1E,0x46,0x95,
+       0xFA,0x0D,0x1B,0xD2,0xBF,0x80,0xE0,0x9F,0x6D,0x4A,0xF5,0x31,0x67,0x18,0x11,0xA5,
+       0x63,0x27,0x08,0xEE,0xD9,0x07,0x29,0xD0,0xD4,0x36,0x91,0x5B,0xFB,0x4A,0x0B,0x07,
+       0xD1,0x0D,0x79,0x16,0x6E,0x16,0x02,0x23,0x80,0xC6,0x15,0x07,0x6D,0xA0,0x06,0xB6,
+       0x45,0x90,0xB0,0xAE,0xA4,0xAD,0x0E,0x75,0x04,0x2B,0x2B,0x78,0xF1,0x57,0x84,0x23,
+       0x87,0x24,0xEC,0x58,0xC4,0xF1,0x02,0x03,0x01,0x00,0x01,0xA3,0x63,0x30,0x61,0x30,
+       0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,
+       0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,
+       0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xFD,0x78,0x96,0x53,0x80,
+       0xD6,0xF6,0xDC,0xA6,0xC3,0x59,0x06,0x38,0xED,0x79,0x3E,0x8F,0x50,0x1B,0x50,0x30,
+       0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xFD,0x78,0x96,0x53,
+       0x80,0xD6,0xF6,0xDC,0xA6,0xC3,0x59,0x06,0x38,0xED,0x79,0x3E,0x8F,0x50,0x1B,0x50,
+       0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,
+       0x82,0x01,0x01,0x00,0x71,0x15,0xCA,0x87,0xD0,0x2D,0xB5,0x18,0xD5,0x35,0x7A,0xCD,
+       0xDF,0x62,0x28,0xF0,0x0B,0x63,0x4D,0x4E,0x02,0xBA,0x3D,0xB8,0xB4,0x37,0xEA,0xB0,
+       0x93,0x93,0xAB,0x1C,0xFD,0x9F,0xE8,0x72,0xBF,0xF3,0xDB,0xE6,0xAD,0x16,0xFE,0x71,
+       0x61,0xA8,0x5A,0xD0,0x58,0x0F,0x65,0x7A,0x57,0x7A,0xE0,0x34,0x80,0x8E,0xBB,0x41,
+       0x01,0xE7,0xB0,0x3B,0xF7,0x2B,0x3A,0x6D,0x44,0x2A,0x3A,0x04,0x52,0xFA,0x2B,0x7B,
+       0x3B,0x21,0xDD,0x0C,0x70,0x3D,0xFB,0x45,0xC6,0x79,0x68,0x62,0xE2,0x89,0xB8,0x25,
+       0xEE,0x63,0x76,0x02,0xB2,0x22,0xE9,0x53,0x85,0x68,0x3E,0x75,0xB6,0x0B,0x65,0xE9,
+       0x1C,0xBA,0x84,0x93,0xB0,0x8A,0xEF,0xB5,0x1A,0x12,0xE4,0x8F,0xAE,0xD5,0x5C,0xA1,
+       0x05,0x4A,0x01,0xBC,0x6F,0xF9,0x58,0x5E,0xF7,0x04,0x61,0xEE,0xF5,0xC6,0xA0,0x1B,
+       0x44,0x2E,0x5A,0x3A,0x59,0xA1,0xB3,0xB0,0xF4,0xB6,0xCB,0xE0,0x6C,0x2B,0x59,0x8A,
+       0xFB,0x6A,0xE0,0xA2,0x57,0x09,0x79,0xC1,0xDD,0xFB,0x84,0x86,0xEB,0x66,0x29,0x73,
+       0xAE,0xBF,0x58,0xAE,0x47,0x4D,0x48,0x37,0xD6,0xB1,0x8C,0x5F,0x26,0x5F,0xB5,0x26,
+       0x07,0x0B,0x85,0xB7,0x36,0x37,0x14,0xCF,0x5E,0x55,0xA5,0x3C,0xF3,0x1E,0x79,0x50,
+       0xBB,0x85,0x3B,0xB2,0x94,0x68,0xB0,0x25,0x4F,0x75,0xEC,0xF0,0xF9,0xC0,0x5A,0x2D,
+       0xE5,0xED,0x67,0xCD,0x88,0x55,0xA0,0x42,0xDE,0x78,0xBC,0xFE,0x30,0xB1,0x62,0x2D,
+       0xE1,0xFD,0xEC,0x75,0x03,0xA6,0x1F,0x7C,0xC4,0x3A,0x4A,0x59,0xFE,0x77,0xC3,0x99,
+       0x96,0x87,0x44,0xC3,
+};
+
+static struct RootRecord kProductionEscrowRootRecord = {sizeof(kProductionEscrowRootGM), (UInt8*)kProductionEscrowRootGM};
+static struct RootRecord* kProductionEscrowRoots[] = {&kProductionEscrowRootRecord};
+static const int kNumberOfProductionEscrowRoots = (int)(sizeof(kProductionEscrowRoots)/sizeof(kProductionEscrowRoots[0]));
+
+static struct RootRecord kBaseLineEscrowRootRecord = {sizeof(kProductionEscrowRootGM), (UInt8*)kProductionEscrowRootGM};
+static struct RootRecord* kBaseLineEscrowRoots[] = {&kBaseLineEscrowRootRecord};
+static const int kNumberOfBaseLineEscrowRoots = (int)(sizeof(kBaseLineEscrowRoots)/sizeof(kBaseLineEscrowRoots[0]));
+
+
+#endif
+//######################################################################
+//%%% end workaround: rdar://14292830
+////######################################################################
+
 
 extern CSSM_KEYUSE ConvertArrayToKeyUsage(CFArrayRef usage);
 
 
 extern CSSM_KEYUSE ConvertArrayToKeyUsage(CFArrayRef usage);
 
+#define SEC_CONST_DECL(k,v) CFTypeRef k = (CFTypeRef)(CFSTR(v));
+
+SEC_CONST_DECL (kSecCertificateProductionEscrowKey, "ProductionEscrowKey");
+SEC_CONST_DECL (kSecCertificateEscrowFileName, "AppleESCertificates");
+
 
 using namespace CssmClient;
 
 
 using namespace CssmClient;
 
@@ -86,12 +190,12 @@ SecCertificateCreateWithData(CFAllocatorRef allocator, CFDataRef data)
                SecPointer<Certificate> certificatePtr(new Certificate(cssmCertData, CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER));
                certificate = certificatePtr->handle();
 
                SecPointer<Certificate> certificatePtr(new Certificate(cssmCertData, CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER));
                certificate = certificatePtr->handle();
 
-               __secapiresult=noErr;
+               __secapiresult=errSecSuccess;
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
-       catch (const std::bad_alloc &) { __secapiresult=memFullErr; }
-       catch (...) { __secapiresult=internalComponentErr; }
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
+       catch (...) { __secapiresult=errSecInternalComponent; }
     return certificate;
 }
 
     return certificate;
 }
 
@@ -121,7 +225,7 @@ CFDataRef
 SecCertificateCopyData(SecCertificateRef certificate)
 {
        CFDataRef data = NULL;
 SecCertificateCopyData(SecCertificateRef certificate)
 {
        CFDataRef data = NULL;
-    OSStatus __secapiresult;
+    OSStatus __secapiresult = errSecSuccess;
        try {
                CssmData output = Certificate::required(certificate)->data();
                CFIndex length = (CFIndex)output.length();
        try {
                CssmData output = Certificate::required(certificate)->data();
                CFIndex length = (CFIndex)output.length();
@@ -129,15 +233,30 @@ SecCertificateCopyData(SecCertificateRef certificate)
                if (length && bytes) {
                        data = CFDataCreate(NULL, bytes, length);
                }
                if (length && bytes) {
                        data = CFDataCreate(NULL, bytes, length);
                }
-               __secapiresult=noErr;
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
-       catch (const std::bad_alloc &) { __secapiresult=memFullErr; }
-       catch (...) { __secapiresult=internalComponentErr; }
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
+       catch (...) { __secapiresult=errSecInternalComponent; }
+    return data;
+}
+
+CFDataRef
+SecCertificateGetSHA1Digest(SecCertificateRef certificate)
+{
+       CFDataRef data = NULL;
+    OSStatus __secapiresult = errSecSuccess;
+       try {
+               data = Certificate::required(certificate)->sha1Hash();
+       }
+       catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
+       catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
+       catch (...) { __secapiresult=errSecInternalComponent; }
     return data;
 }
 
     return data;
 }
 
+
 OSStatus
 SecCertificateGetType(SecCertificateRef certificate, CSSM_CERT_TYPE *certificateType)
 {
 OSStatus
 SecCertificateGetType(SecCertificateRef certificate, CSSM_CERT_TYPE *certificateType)
 {
@@ -235,12 +354,12 @@ SecCertificateCopySubjectSummary(SecCertificateRef certificate)
        try {
                Certificate::required(certificate)->inferLabel(false, &summary);
 
        try {
                Certificate::required(certificate)->inferLabel(false, &summary);
 
-               __secapiresult=noErr;
+               __secapiresult=errSecSuccess;
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
-       catch (const std::bad_alloc &) { __secapiresult=memFullErr; }
-       catch (...) { __secapiresult=internalComponentErr; }
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
+       catch (...) { __secapiresult=errSecInternalComponent; }
     return summary;
 }
 
     return summary;
 }
 
@@ -450,7 +569,7 @@ SecDigestGetData (CSSM_ALGORITHMS alg, CSSM_DATA* digest, const CSSM_DATA* data)
        BEGIN_SECAPI
        // sanity checking
        if (!digest || !digest->Data || !digest->Length || !data || !data->Data || !data->Length)
        BEGIN_SECAPI
        // sanity checking
        if (!digest || !digest->Data || !digest->Length || !data || !data->Data || !data->Length)
-               return paramErr;
+               return errSecParam;
 
        CSP csp(gGuidAppleCSP);
        Digest context(csp, alg);
 
        CSP csp(gGuidAppleCSP);
        Digest context(csp, alg);
@@ -537,15 +656,15 @@ SecCertificateCopyPreferred(
        SecCertificateRef certRef = NULL;
        CSSM_KEYUSE keyUse = ConvertArrayToKeyUsage(keyUsage);
        OSStatus status = SecCertificateCopyPreference(name, keyUse, &certRef);
        SecCertificateRef certRef = NULL;
        CSSM_KEYUSE keyUse = ConvertArrayToKeyUsage(keyUsage);
        OSStatus status = SecCertificateCopyPreference(name, keyUse, &certRef);
-       if (status != noErr && keyUse != CSSM_KEYUSE_ANY)
+       if (status != errSecSuccess && keyUse != CSSM_KEYUSE_ANY)
                status = SecCertificateCopyPreference(name, CSSM_KEYUSE_ANY, &certRef);
                status = SecCertificateCopyPreference(name, CSSM_KEYUSE_ANY, &certRef);
-       if (status != noErr && keyUse != 0)
+       if (status != errSecSuccess && keyUse != 0)
                status = SecCertificateCopyPreference(name, 0, &certRef);
 
        return certRef;
 }
 
                status = SecCertificateCopyPreference(name, 0, &certRef);
 
        return certRef;
 }
 
-OSStatus
+static OSStatus
 SecCertificateFindPreferenceItemWithNameAndKeyUsage(
        CFTypeRef keychainOrArray,
        CFStringRef name,
 SecCertificateFindPreferenceItemWithNameAndKeyUsage(
        CFTypeRef keychainOrArray,
        CFStringRef name,
@@ -567,7 +686,7 @@ SecCertificateFindPreferenceItemWithNameAndKeyUsage(
        }
     size_t idUTF8Len = strlen(idUTF8);
     if (!idUTF8Len)
        }
     size_t idUTF8Len = strlen(idUTF8);
     if (!idUTF8Len)
-        MacOSError::throwMe(paramErr);
+        MacOSError::throwMe(errSecParam);
 
     CssmData service(const_cast<char *>(idUTF8), idUTF8Len);
     cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecServiceItemAttr), service);
 
     CssmData service(const_cast<char *>(idUTF8), idUTF8Len);
     cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecServiceItemAttr), service);
@@ -585,6 +704,7 @@ SecCertificateFindPreferenceItemWithNameAndKeyUsage(
     END_SECAPI
 }
 
     END_SECAPI
 }
 
+static
 OSStatus SecCertificateDeletePreferenceItemWithNameAndKeyUsage(
        CFTypeRef keychainOrArray,
        CFStringRef name,
 OSStatus SecCertificateDeletePreferenceItemWithNameAndKeyUsage(
        CFTypeRef keychainOrArray,
        CFStringRef name,
@@ -600,14 +720,14 @@ OSStatus SecCertificateDeletePreferenceItemWithNameAndKeyUsage(
        SecKeychainItemRef item = NULL;
        int count = 0, maxUsages = 12;
        while (++count <= maxUsages &&
        SecKeychainItemRef item = NULL;
        int count = 0, maxUsages = 12;
        while (++count <= maxUsages &&
-                       (status = SecCertificateFindPreferenceItemWithNameAndKeyUsage(keychainOrArray, name, keyUsage, &item)) == noErr) {
+                       (status = SecCertificateFindPreferenceItemWithNameAndKeyUsage(keychainOrArray, name, keyUsage, &item)) == errSecSuccess) {
                status = SecKeychainItemDelete(item);
                CFRelease(item);
                item = NULL;
        }
 
        // it's not an error if the item isn't found
                status = SecKeychainItemDelete(item);
                CFRelease(item);
                item = NULL;
        }
 
        // it's not an error if the item isn't found
-       return (status == errSecItemNotFound) ? noErr : status;
+       return (status == errSecItemNotFound) ? errSecSuccess : status;
 }
 
 OSStatus SecCertificateSetPreference(
 }
 
 OSStatus SecCertificateSetPreference(
@@ -617,7 +737,7 @@ OSStatus SecCertificateSetPreference(
     CFDateRef date)
 {
        if (!name) {
     CFDateRef date)
 {
        if (!name) {
-               return paramErr;
+               return errSecParam;
        }
        if (!certificate) {
                // treat NULL certificate as a request to clear the preference
        }
        if (!certificate) {
                // treat NULL certificate as a request to clear the preference
@@ -735,7 +855,7 @@ OSStatus SecCertificateSetPreferred(
 CFDictionaryRef SecCertificateCopyValues(SecCertificateRef certificate, CFArrayRef keys, CFErrorRef *error)
 {
        CFDictionaryRef result = NULL;
 CFDictionaryRef SecCertificateCopyValues(SecCertificateRef certificate, CFArrayRef keys, CFErrorRef *error)
 {
        CFDictionaryRef result = NULL;
-    OSStatus __secapiresult;
+       OSStatus __secapiresult;
        try
        {
                CertificateValues cv(certificate);
        try
        {
                CertificateValues cv(certificate);
@@ -744,9 +864,9 @@ CFDictionaryRef SecCertificateCopyValues(SecCertificateRef certificate, CFArrayR
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
-       catch (const std::bad_alloc &) { __secapiresult=memFullErr; }
-       catch (...) { __secapiresult=internalComponentErr; }
-    return result;
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
+       catch (...) { __secapiresult=errSecInternalComponent; }
+       return result;
 }
 
 CFStringRef SecCertificateCopyLongDescription(CFAllocatorRef alloc, SecCertificateRef certificate, CFErrorRef *error)
 }
 
 CFStringRef SecCertificateCopyLongDescription(CFAllocatorRef alloc, SecCertificateRef certificate, CFErrorRef *error)
@@ -757,27 +877,27 @@ CFStringRef SecCertificateCopyLongDescription(CFAllocatorRef alloc, SecCertifica
 CFStringRef SecCertificateCopyShortDescription(CFAllocatorRef alloc, SecCertificateRef certificate, CFErrorRef *error)
 {
        CFStringRef result = NULL;
 CFStringRef SecCertificateCopyShortDescription(CFAllocatorRef alloc, SecCertificateRef certificate, CFErrorRef *error)
 {
        CFStringRef result = NULL;
-    OSStatus __secapiresult;
+       OSStatus __secapiresult;
        try
        {
                __secapiresult = SecCertificateInferLabel(certificate, &result);
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
        try
        {
                __secapiresult = SecCertificateInferLabel(certificate, &result);
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
-       catch (const std::bad_alloc &) { __secapiresult=memFullErr; }
-       catch (...) { __secapiresult=internalComponentErr; }
-       if (error!=NULL && __secapiresult!=noErr)
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
+       catch (...) { __secapiresult=errSecInternalComponent; }
+       if (error!=NULL && __secapiresult!=errSecSuccess)
        {
                *error = CFErrorCreate(kCFAllocatorDefault, kCFErrorDomainOSStatus,
                        __secapiresult ? __secapiresult : CSSM_ERRCODE_INTERNAL_ERROR, NULL);
        }
        {
                *error = CFErrorCreate(kCFAllocatorDefault, kCFErrorDomainOSStatus,
                        __secapiresult ? __secapiresult : CSSM_ERRCODE_INTERNAL_ERROR, NULL);
        }
-    return result;
+       return result;
 }
 
 CFDataRef SecCertificateCopySerialNumber(SecCertificateRef certificate, CFErrorRef *error)
 {
        CFDataRef result = NULL;
 }
 
 CFDataRef SecCertificateCopySerialNumber(SecCertificateRef certificate, CFErrorRef *error)
 {
        CFDataRef result = NULL;
-    OSStatus __secapiresult;
+       OSStatus __secapiresult;
        try
        {
                CertificateValues cv(certificate);
        try
        {
                CertificateValues cv(certificate);
@@ -786,61 +906,143 @@ CFDataRef SecCertificateCopySerialNumber(SecCertificateRef certificate, CFErrorR
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
-       catch (const std::bad_alloc &) { __secapiresult=memFullErr; }
-       catch (...) { __secapiresult=internalComponentErr; }
-    return result;
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
+       catch (...) { __secapiresult=errSecInternalComponent; }
+       return result;
 }
 
 CFDataRef SecCertificateCopyNormalizedIssuerContent(SecCertificateRef certificate, CFErrorRef *error)
 {
        CFDataRef result = NULL;
 }
 
 CFDataRef SecCertificateCopyNormalizedIssuerContent(SecCertificateRef certificate, CFErrorRef *error)
 {
        CFDataRef result = NULL;
-    OSStatus __secapiresult;
+       OSStatus __secapiresult;
        try
        {
                CertificateValues cv(certificate);
        try
        {
                CertificateValues cv(certificate);
-               result = cv.getNormalizedIssuerContent(error);
+               result = cv.copyNormalizedIssuerContent(error);
                __secapiresult=0;
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
                __secapiresult=0;
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
-       catch (const std::bad_alloc &) { __secapiresult=memFullErr; }
-       catch (...) { __secapiresult=internalComponentErr; }
-    return result;
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
+       catch (...) { __secapiresult=errSecInternalComponent; }
+       return result;
 }
 
 CFDataRef SecCertificateCopyNormalizedSubjectContent(SecCertificateRef certificate, CFErrorRef *error)
 {
        CFDataRef result = NULL;
 }
 
 CFDataRef SecCertificateCopyNormalizedSubjectContent(SecCertificateRef certificate, CFErrorRef *error)
 {
        CFDataRef result = NULL;
-    OSStatus __secapiresult;
+       OSStatus __secapiresult;
        try
        {
                CertificateValues cv(certificate);
        try
        {
                CertificateValues cv(certificate);
-               result = cv.getNormalizedSubjectContent(error);
+               result = cv.copyNormalizedSubjectContent(error);
                __secapiresult=0;
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
                __secapiresult=0;
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
-       catch (const std::bad_alloc &) { __secapiresult=memFullErr; }
-       catch (...) { __secapiresult=internalComponentErr; }
-    return result;
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
+       catch (...) { __secapiresult=errSecInternalComponent; }
+       return result;
 }
 
 }
 
-bool SecCertificateIsValidX(SecCertificateRef certificate, CFAbsoluteTime verifyTime)
+CFDataRef SecCertificateCopyIssuerSequence(SecCertificateRef certificate)
+{
+       CFDataRef result = NULL;
+       OSStatus __secapiresult;
+       try
+       {
+               CertificateValues cv(certificate);
+               result = cv.copyIssuerSequence(NULL);
+               __secapiresult=0;
+       }
+       catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
+       catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
+       catch (...) { __secapiresult=errSecInternalComponent; }
+       return result;
+}
+
+CFDataRef SecCertificateCopySubjectSequence(SecCertificateRef certificate)
+{
+       CFDataRef result = NULL;
+       OSStatus __secapiresult;
+       try
+       {
+               CertificateValues cv(certificate);
+               result = cv.copySubjectSequence(NULL);
+               __secapiresult=0;
+       }
+       catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
+       catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
+       catch (...) { __secapiresult=errSecInternalComponent; }
+       return result;
+}
+
+bool SecCertificateIsValid(SecCertificateRef certificate, CFAbsoluteTime verifyTime)
 {
        bool result = NULL;
 {
        bool result = NULL;
-    OSStatus __secapiresult;
+       OSStatus __secapiresult;
        try
        {
        try
        {
-        CFErrorRef error = NULL;
+               CFErrorRef error = NULL;
                CertificateValues cv(certificate);
                CertificateValues cv(certificate);
-               result = cv.SecCertificateIsValidX(verifyTime, &error);
+               result = cv.isValid(verifyTime, &error);
+               if (error) CFRelease(error);
                __secapiresult=0;
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
                __secapiresult=0;
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
-       catch (const std::bad_alloc &) { __secapiresult=memFullErr; }
-       catch (...) { __secapiresult=internalComponentErr; }
-    return result;
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
+       catch (...) { __secapiresult=errSecInternalComponent; }
+       return result;
+}
+
+/*
+ * deprecated function name
+ */
+bool SecCertificateIsValidX(SecCertificateRef certificate, CFAbsoluteTime verifyTime)
+{
+       return SecCertificateIsValid(certificate, verifyTime);
+}
+
+
+CFAbsoluteTime SecCertificateNotValidBefore(SecCertificateRef certificate)
+{
+       CFAbsoluteTime result = 0;
+       OSStatus __secapiresult;
+       try
+       {
+               CFErrorRef error = NULL;
+               CertificateValues cv(certificate);
+               result = cv.notValidBefore(&error);
+               if (error) CFRelease(error);
+               __secapiresult=0;
+       }
+       catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
+       catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
+       catch (...) { __secapiresult=errSecInternalComponent; }
+       return result;
+}
+
+CFAbsoluteTime SecCertificateNotValidAfter(SecCertificateRef certificate)
+{
+       CFAbsoluteTime result = 0;
+       OSStatus __secapiresult;
+       try
+       {
+               CFErrorRef error = NULL;
+               CertificateValues cv(certificate);
+               result = cv.notValidAfter(&error);
+               if (error) CFRelease(error);
+               __secapiresult=0;
+       }
+       catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
+       catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
+       catch (...) { __secapiresult=errSecInternalComponent; }
+       return result;
 }
 
 /* new in 10.8 */
 }
 
 /* new in 10.8 */
@@ -856,12 +1058,12 @@ SecCertificateRef SecCertificateCreateWithBytes(CFAllocatorRef allocator,
                SecPointer<Certificate> certificatePtr(new Certificate(cssmCertData, CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER));
                certificate = certificatePtr->handle();
 
                SecPointer<Certificate> certificatePtr(new Certificate(cssmCertData, CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER));
                certificate = certificatePtr->handle();
 
-               __secapiresult=noErr;
+               __secapiresult=errSecSuccess;
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
-       catch (const std::bad_alloc &) { __secapiresult=memFullErr; }
-       catch (...) { __secapiresult=internalComponentErr; }
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
+       catch (...) { __secapiresult=errSecInternalComponent; }
        return certificate;
 }
 
        return certificate;
 }
 
@@ -873,12 +1075,12 @@ CFIndex SecCertificateGetLength(SecCertificateRef certificate)
        try {
                CssmData output = Certificate::required(certificate)->data();
                length = (CFIndex)output.length();
        try {
                CssmData output = Certificate::required(certificate)->data();
                length = (CFIndex)output.length();
-               __secapiresult=noErr;
+               __secapiresult=errSecSuccess;
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
-       catch (const std::bad_alloc &) { __secapiresult=memFullErr; }
-       catch (...) { __secapiresult=internalComponentErr; }
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
+       catch (...) { __secapiresult=errSecInternalComponent; }
        return length;
 }
 
        return length;
 }
 
@@ -890,12 +1092,135 @@ const UInt8 *SecCertificateGetBytePtr(SecCertificateRef certificate)
        try {
                CssmData output = Certificate::required(certificate)->data();
                bytes = (const UInt8 *)output.data();
        try {
                CssmData output = Certificate::required(certificate)->data();
                bytes = (const UInt8 *)output.data();
-               __secapiresult=noErr;
+               __secapiresult=errSecSuccess;
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
-       catch (const std::bad_alloc &) { __secapiresult=memFullErr; }
-       catch (...) { __secapiresult=internalComponentErr; }
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
+       catch (...) { __secapiresult=errSecInternalComponent; }
        return bytes;
 }
 
        return bytes;
 }
 
+static CFArrayRef CopyEscrowCertificates(CFErrorRef *error)
+{
+       // Return array of CFDataRef certificates.
+    CFArrayRef result = NULL;
+       int iCnt;
+       int numRoots = 0;
+
+       // Get the hard coded set of production roots
+       // static struct RootRecord* kProductionEscrowRoots[] = {&kOldEscrowRootRecord, &kProductionEscrowRootRecord};
+
+       numRoots = kNumberOfProductionEscrowRoots;
+       CFDataRef productionCerts[numRoots];
+       struct RootRecord* pRootRecord = NULL;
+
+       for (iCnt = 0; iCnt < numRoots; iCnt++)
+       {
+               pRootRecord = kProductionEscrowRoots[iCnt];
+               if (NULL != pRootRecord && pRootRecord->_length > 0 && NULL != pRootRecord->_bytes)
+               {
+                       productionCerts[iCnt] = CFDataCreate(kCFAllocatorDefault, pRootRecord->_bytes, pRootRecord->_length);
+               }
+       }
+       result = CFArrayCreate(kCFAllocatorDefault, (const void **)productionCerts, numRoots, &kCFTypeArrayCallBacks);
+       for (iCnt = 0; iCnt < numRoots; iCnt++)
+       {
+               if (NULL != productionCerts[iCnt])
+               {
+                       CFRelease(productionCerts[iCnt]);
+               }
+       }
+
+       return result;
+}
+
+/* new in 10.9 */
+CFArrayRef SecCertificateCopyEscrowRoots(SecCertificateEscrowRootType escrowRootType)
+{
+       CFArrayRef result = NULL;
+       int iCnt;
+       int numRoots = 0;
+       CFDataRef certData = NULL;
+
+       // The request is for the base line certificates.
+       // Use the hard coded data to generate the return array
+       if (kSecCertificateBaselineEscrowRoot == escrowRootType)
+       {
+               // Get the hard coded set of roots
+               numRoots = kNumberOfBaseLineEscrowRoots;
+           SecCertificateRef baseLineCerts[numRoots];
+           struct RootRecord* pRootRecord = NULL;
+
+           for (iCnt = 0; iCnt < numRoots; iCnt++)
+           {
+               pRootRecord = kBaseLineEscrowRoots[iCnt];
+               if (NULL != pRootRecord && pRootRecord->_length > 0 && NULL != pRootRecord->_bytes)
+               {
+                               certData = CFDataCreate(kCFAllocatorDefault, pRootRecord->_bytes, pRootRecord->_length);
+                               if (NULL != certData)
+                               {
+                                       baseLineCerts[iCnt] = SecCertificateCreateWithData(kCFAllocatorDefault, certData);
+                                       CFRelease(certData);
+                               }
+               }
+           }
+               result = CFArrayCreate(kCFAllocatorDefault, (const void **)baseLineCerts, numRoots, &kCFTypeArrayCallBacks);
+               for (iCnt = 0; iCnt < numRoots; iCnt++)
+               {
+                       if (NULL != baseLineCerts[iCnt])
+                       {
+                               CFRelease(baseLineCerts[iCnt]);
+                       }
+               }
+       }
+       // The request is for the current certificates.
+       else if (kSecCertificateProductionEscrowRoot == escrowRootType)
+       {
+               CFErrorRef error = NULL;
+               CFArrayRef cert_datas = CopyEscrowCertificates(&error);
+               if (NULL != error || NULL == cert_datas || 0 == (numRoots = (int)CFArrayGetCount(cert_datas)))
+               {
+                       if (NULL != error)
+                       {
+                               CFRelease(error);
+                       }
+
+                       if (NULL != cert_datas)
+                       {
+                               CFRelease(cert_datas);
+                       }
+                       return result;
+               }
+
+               SecCertificateRef assetCerts[numRoots];
+               for (iCnt = 0; iCnt < numRoots; iCnt++)
+               {
+                       certData = (CFDataRef)CFArrayGetValueAtIndex(cert_datas, iCnt);
+                       if (NULL != certData)
+                       {
+                               SecCertificateRef aCertRef = SecCertificateCreateWithData(kCFAllocatorDefault, certData);
+                               assetCerts[iCnt] = aCertRef;
+                       }
+                       else
+                       {
+                               assetCerts[iCnt] = NULL;
+                       }
+               }
+
+               if (numRoots > 0)
+               {
+                       result = CFArrayCreate(kCFAllocatorDefault, (const void **)assetCerts, numRoots, &kCFTypeArrayCallBacks);
+                       for (iCnt = 0; iCnt < numRoots; iCnt++)
+                       {
+                               if (NULL != assetCerts[iCnt])
+                               {
+                                       CFRelease(assetCerts[iCnt]);
+                               }
+                       }
+               }
+               CFRelease(cert_datas);
+       }
+    return result;
+}
+
index 2e43b9bf3c08335f3ecfd9267a6394dee1cbc889..e50c9c25d878e02598100be7a6e2dc2c1cc3cc10 100644 (file)
@@ -158,7 +158,7 @@ OSStatus SecCertificateGetType(SecCertificateRef certificate, CSSM_CERT_TYPE *ce
         For example:
         const CSSM_X509_NAME *subject = NULL;
         OSStatus status = SecCertificateGetSubject(certificate, &subject);
         For example:
         const CSSM_X509_NAME *subject = NULL;
         OSStatus status = SecCertificateGetSubject(certificate, &subject);
-        if ( (status == noErr) && (subject != NULL) ) {
+        if ( (status == errSecSuccess) && (subject != NULL) ) {
             // subject is valid
         }
           This API is deprecated in 10.7. Please use the SecCertificateCopyValues API instead. 
             // subject is valid
         }
           This API is deprecated in 10.7. Please use the SecCertificateCopyValues API instead. 
@@ -176,7 +176,7 @@ OSStatus SecCertificateGetSubject(SecCertificateRef certificate, const CSSM_X509
         For example:
         const CSSM_X509_NAME *issuer = NULL;
         OSStatus status = SecCertificateGetIssuer(certificate, &issuer);
         For example:
         const CSSM_X509_NAME *issuer = NULL;
         OSStatus status = SecCertificateGetIssuer(certificate, &issuer);
-        if ( (status == noErr) && (issuer != NULL) ) {
+        if ( (status == errSecSuccess) && (issuer != NULL) ) {
             // issuer is valid
         }
                This API is deprecated in 10.7. Please use the SecCertificateCopyValues API instead. 
             // issuer is valid
         }
                This API is deprecated in 10.7. Please use the SecCertificateCopyValues API instead. 
index fde9bb43d61172199ca938a23cc95a3a0779a913..598dcdf96a6eea4f50e1f72bd28080b0c7cdd395 100644 (file)
@@ -49,7 +49,7 @@ SecCertificateBundleImport(
 {
     BEGIN_SECAPI
 
 {
     BEGIN_SECAPI
 
-       MacOSError::throwMe(unimpErr);//%%%for now
+       MacOSError::throwMe(errSecUnimplemented);//%%%for now
 
     END_SECAPI
 }
 
     END_SECAPI
 }
@@ -64,7 +64,7 @@ SecCertificateBundleExport(
 {
     BEGIN_SECAPI
 
 {
     BEGIN_SECAPI
 
-       MacOSError::throwMe(unimpErr);//%%%for now
+       MacOSError::throwMe(errSecUnimplemented);//%%%for now
 
     END_SECAPI
 }
 
     END_SECAPI
 }
index 1c6b26927311bd71166bd15573c4141919c7ab90..7296c532da75b7ff17841b145f07783c56d3298e 100644 (file)
@@ -1,15 +1,15 @@
 /*
  * Copyright (c) 2007-2010 Apple Inc. All Rights Reserved.
 /*
  * Copyright (c) 2007-2010 Apple Inc. All Rights Reserved.
- * 
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -56,10 +56,10 @@ CFArrayRef SecCertificateGetCAIssuers(SecCertificateRefP certificate);
 void SecCertificateShow(SecCertificateRefP certificate);
 
 /* Return the DER encoded issuer sequence for the receiving certificates issuer. */
 void SecCertificateShow(SecCertificateRefP certificate);
 
 /* Return the DER encoded issuer sequence for the receiving certificates issuer. */
-CFDataRef SecCertificateCopyIssuerSequence(SecCertificateRefP certificate);
+CFDataRef SecCertificateCopyIssuerSequenceP(SecCertificateRefP certificate);
 
 /* Return the DER encoded subject sequence for the receiving certificates subject. */
 
 /* Return the DER encoded subject sequence for the receiving certificates subject. */
-CFDataRef SecCertificateCopySubjectSequence(SecCertificateRefP certificate);
+CFDataRef SecCertificateCopySubjectSequenceP(SecCertificateRefP certificate);
 
 /* Return the content of a DER encoded X.501 name (without the tag and length
    fields) for the receiving certificates issuer. */
 
 /* Return the content of a DER encoded X.501 name (without the tag and length
    fields) for the receiving certificates issuer. */
index 2fe84161ab8b60eadddf42c29320fa13c30e0967..d841d41fb0ab9a293db98d1793d68da2723d185d 100644 (file)
 #include "SecItem.h"
 #include "SecItemPriv.h"
 #include <stdbool.h>
 #include "SecItem.h"
 #include "SecItemPriv.h"
 #include <stdbool.h>
-#include "debuggingP.h"
 #include <stdlib.h>
 #include <libkern/OSByteOrder.h>
 #include <ctype.h>
 #include "SecInternalP.h"
 #include "SecBase64P.h"
 
 #include <stdlib.h>
 #include <libkern/OSByteOrder.h>
 #include <ctype.h>
 #include "SecInternalP.h"
 #include "SecBase64P.h"
 
+#include <security_utilities/debugging.h>
+
 typedef struct SecCertificateExtension {
        DERItem extnID;
     bool critical;
 typedef struct SecCertificateExtension {
        DERItem extnID;
     bool critical;
@@ -266,9 +267,9 @@ static Boolean SecCertificateEqual(CFTypeRef cf1, CFTypeRef cf2) {
    of signature. */
 static CFHashCode SecCertificateHash(CFTypeRef cf) {
     SecCertificateRefP certificate = (SecCertificateRefP)cf;
    of signature. */
 static CFHashCode SecCertificateHash(CFTypeRef cf) {
     SecCertificateRefP certificate = (SecCertificateRefP)cf;
-       uint32_t der_length = certificate->_der.length;
-       uint32_t sig_length = certificate->_signature.length;
-       uint32_t ix = (sig_length > 4) ? sig_length - 4 : 0;
+       DERSize der_length = certificate->_der.length;
+       DERSize sig_length = certificate->_signature.length;
+       DERSize ix = (sig_length > 4) ? sig_length - 4 : 0;
        CFHashCode hashCode = 0;
        for (; ix < sig_length; ++ix)
                hashCode = (hashCode << 8) + certificate->_signature.data[ix];
        CFHashCode hashCode = 0;
        for (; ix < sig_length; ++ix)
                hashCode = (hashCode << 8) + certificate->_signature.data[ix];
@@ -360,7 +361,7 @@ static OSStatus parseGeneralNamesContent(const DERItem *generalNamesContent,
                        return status;
        }
     require_quiet(drtn == DR_EndOfSequence, badDER);
                        return status;
        }
     require_quiet(drtn == DR_EndOfSequence, badDER);
-       return noErr;
+       return errSecSuccess;
 
 badDER:
        return errSecInvalidCertificate;
 
 badDER:
        return errSecInvalidCertificate;
@@ -466,7 +467,7 @@ static OSStatus parseGeneralNameContentProperty(DERTag tag,
                goto badDER;
                break;
        }
                goto badDER;
                break;
        }
-       return noErr;
+       return errSecSuccess;
 badDER:
        return errSecInvalidCertificate;
 }
 badDER:
        return errSecInvalidCertificate;
 }
@@ -502,7 +503,7 @@ static OSStatus parseGeneralNamesContent(const DERItem *generalNamesContent,
     }
        *count = generalNamesCount;
        *name = generalNames;
     }
        *count = generalNamesCount;
        *name = generalNames;
-       return noErr;
+       return errSecSuccess;
 
 badDER:
        if (generalNames)
 
 badDER:
        if (generalNames)
@@ -518,7 +519,7 @@ static OSStatus parseGeneralNames(const DERItem *generalNames,
     require_quiet(generalNamesContent.tag == ASN1_CONSTR_SEQUENCE,
         badDER);
     parseGeneralNamesContent(&generalNamesContent.content, count, name);
     require_quiet(generalNamesContent.tag == ASN1_CONSTR_SEQUENCE,
         badDER);
     parseGeneralNamesContent(&generalNamesContent.content, count, name);
-    return noErr;
+    return errSecSuccess;
 badDER:
        return errSecInvalidCertificate;
 }
 badDER:
        return errSecInvalidCertificate;
 }
@@ -553,7 +554,7 @@ static OSStatus parseRDNContent(const DERItem *rdnSetContent, void *context,
        }
        require_quiet(drtn == DR_EndOfSequence, badDER);
 
        }
        require_quiet(drtn == DR_EndOfSequence, badDER);
 
-       return noErr;
+       return errSecSuccess;
 badDER:
        return errSecInvalidCertificate;
 }
 badDER:
        return errSecInvalidCertificate;
 }
@@ -573,7 +574,7 @@ static OSStatus parseX501NameContent(const DERItem *x501NameContent, void *conte
        }
        require_quiet(drtn == DR_EndOfSequence, badDER);
 
        }
        require_quiet(drtn == DR_EndOfSequence, badDER);
 
-       return noErr;
+       return errSecSuccess;
 
 badDER:
        return errSecInvalidCertificate;
 
 badDER:
        return errSecInvalidCertificate;
@@ -606,7 +607,7 @@ static void SecCEPSubjectKeyIdentifier(SecCertificateRefP certificate,
 
        return;
 badDER:
 
        return;
 badDER:
-       secdebug(NULL, "Invalid SubjectKeyIdentifier Extension");
+       secdebug("cert", "Invalid SubjectKeyIdentifier Extension");
 }
 
 static void SecCEPKeyUsage(SecCertificateRefP certificate,
 }
 
 static void SecCEPKeyUsage(SecCertificateRefP certificate,
@@ -680,7 +681,7 @@ static void SecCEPBasicConstraints(SecCertificateRefP certificate,
     return;
 badDER:
     certificate->_basicConstraints.present = false;
     return;
 badDER:
     certificate->_basicConstraints.present = false;
-       secdebug(NULL, "Invalid BasicConstraints Extension");
+       secdebug("cert", "Invalid BasicConstraints Extension");
 }
 
 static void SecCEPCrlDistributionPoints(SecCertificateRefP certificate,
 }
 
 static void SecCEPCrlDistributionPoints(SecCertificateRefP certificate,
@@ -734,14 +735,14 @@ static void SecCEPCertificatePolicies(SecCertificateRefP certificate,
     }
     certificate->_certificatePolicies.present = true;
     certificate->_certificatePolicies.critical = extn->critical;
     }
     certificate->_certificatePolicies.present = true;
     certificate->_certificatePolicies.critical = extn->critical;
-    certificate->_certificatePolicies.numPolicies = policy_count;
+    certificate->_certificatePolicies.numPolicies = (uint32_t)policy_count;
     certificate->_certificatePolicies.policies = policies;
        return;
 badDER:
     if (policies)
         free(policies);
     certificate->_certificatePolicies.present = false;
     certificate->_certificatePolicies.policies = policies;
        return;
 badDER:
     if (policies)
         free(policies);
     certificate->_certificatePolicies.present = false;
-       secdebug(NULL, "Invalid CertificatePolicies Extension");
+       secdebug("cert", "Invalid CertificatePolicies Extension");
 }
 
 /*
 }
 
 /*
@@ -792,7 +793,7 @@ badDER:
         free(mappings);
     CFReleaseSafe(mappings);
     certificate->_policyMappings.present = false;
         free(mappings);
     CFReleaseSafe(mappings);
     certificate->_policyMappings.present = false;
-       secdebug(NULL, "Invalid CertificatePolicies Extension");
+       secdebug("cert", "Invalid CertificatePolicies Extension");
 }
 #else
 static void SecCEPPolicyMappings(SecCertificateRefP certificate,
 }
 #else
 static void SecCEPPolicyMappings(SecCertificateRefP certificate,
@@ -838,7 +839,7 @@ static void SecCEPPolicyMappings(SecCertificateRefP certificate,
 badDER:
     CFReleaseSafe(mappings);
     certificate->_policyMappings = NULL;
 badDER:
     CFReleaseSafe(mappings);
     certificate->_policyMappings = NULL;
-       secdebug(NULL, "Invalid CertificatePolicies Extension");
+       secdebug("cert", "Invalid CertificatePolicies Extension");
 }
 #endif
 
 }
 #endif
 
@@ -876,7 +877,7 @@ static void SecCEPAuthorityKeyIdentifier(SecCertificateRefP certificate,
 
        return;
 badDER:
 
        return;
 badDER:
-       secdebug(NULL, "Invalid AuthorityKeyIdentifier Extension");
+       secdebug("cert", "Invalid AuthorityKeyIdentifier Extension");
 }
 
 static void SecCEPPolicyConstraints(SecCertificateRefP certificate,
 }
 
 static void SecCEPPolicyConstraints(SecCertificateRefP certificate,
@@ -908,7 +909,7 @@ static void SecCEPPolicyConstraints(SecCertificateRefP certificate,
     return;
 badDER:
     certificate->_policyConstraints.present = false;
     return;
 badDER:
     certificate->_policyConstraints.present = false;
-       secdebug(NULL, "Invalid PolicyConstraints Extension");
+       secdebug("cert", "Invalid PolicyConstraints Extension");
 }
 
 static void SecCEPExtendedKeyUsage(SecCertificateRefP certificate,
 }
 
 static void SecCEPExtendedKeyUsage(SecCertificateRefP certificate,
@@ -930,7 +931,7 @@ static void SecCEPInhibitAnyPolicy(SecCertificateRefP certificate,
     return;
 badDER:
     certificate->_inhibitAnyPolicySkipCerts = UINT32_MAX;
     return;
 badDER:
     certificate->_inhibitAnyPolicySkipCerts = UINT32_MAX;
-       secdebug(NULL, "Invalid InhibitAnyPolicy Extension");
+       secdebug("cert", "Invalid InhibitAnyPolicy Extension");
 }
 
 /*
 }
 
 /*
@@ -999,7 +1000,7 @@ static void SecCEPAuthorityInfoAccess(SecCertificateRefP certificate,
         }
         default:
             secdebug("cert", "bad general name for id-ad-ocsp AccessDescription t: 0x%02x v: %.*s",
         }
         default:
             secdebug("cert", "bad general name for id-ad-ocsp AccessDescription t: 0x%02x v: %.*s",
-                generalNameContent.tag, generalNameContent.content.length, generalNameContent.content.data);
+                generalNameContent.tag, (int)generalNameContent.content.length, generalNameContent.content.data);
             goto badDER;
             break;
         }
             goto badDER;
             break;
         }
@@ -1664,7 +1665,7 @@ CFStringRef SecDERItemCopyOIDDecimalRepresentation(CFAllocatorRef allocator,
         /* A max number of 20 values is allowed. */
                if (!(oid->data[x] & 0x80))
                {
         /* A max number of 20 values is allowed. */
                if (!(oid->data[x] & 0x80))
                {
-            CFStringAppendFormat(result, NULL, CFSTR(".%lu"), value);
+            CFStringAppendFormat(result, NULL, CFSTR(".%lu"), (unsigned long)value);
                        value = 0;
                }
        }
                        value = 0;
                }
        }
@@ -1681,7 +1682,7 @@ static CFStringRef copyLocalizedOidDescription(CFAllocatorRef allocator,
     /* Build the key we use to lookup the localized OID description. */
     CFMutableStringRef oidKey = CFStringCreateMutable(allocator,
         oid->length * 3 + 5);
     /* Build the key we use to lookup the localized OID description. */
     CFMutableStringRef oidKey = CFStringCreateMutable(allocator,
         oid->length * 3 + 5);
-    CFStringAppendFormat(oidKey, NULL, CFSTR("06 %02X"), oid->length);
+    CFStringAppendFormat(oidKey, NULL, CFSTR("06 %02lX"), (unsigned long)oid->length);
     DERSize ix;
     for (ix = 0; ix < oid->length; ++ix)
         CFStringAppendFormat(oidKey, NULL, CFSTR(" %02X"), oid->data[ix]);
     DERSize ix;
     for (ix = 0; ix < oid->length; ++ix)
         CFStringAppendFormat(oidKey, NULL, CFSTR(" %02X"), oid->data[ix]);
@@ -1889,7 +1890,7 @@ CFAbsoluteTime SecAbsoluteTimeFromDateContent(DERTag tag, const uint8_t *bytes,
 
     secdebug("dateparse",
         "date %.*s year: %04d-%02d-%02d %02d:%02d:%02.f %+05.f",
 
     secdebug("dateparse",
         "date %.*s year: %04d-%02d-%02d %02d:%02d:%02.f %+05.f",
-        length, bytes, gdate.year, gdate.month,
+        (int)length, bytes, (int)gdate.year, gdate.month,
         gdate.day, gdate.hour, gdate.minute, gdate.second,
         timeZoneOffset / 60);
 
         gdate.day, gdate.hour, gdate.minute, gdate.second,
         timeZoneOffset / 60);
 
@@ -2168,7 +2169,7 @@ static CFStringRef copyDERThingContentDescription(CFAllocatorRef allocator,
         /* "format string for undisplayed field data with a given DER tag" */
         return printableOnly ? NULL : CFStringCreateWithFormat(allocator, NULL,
             CFSTR("not displayed (tag = %d; length %d)"),
         /* "format string for undisplayed field data with a given DER tag" */
         return printableOnly ? NULL : CFStringCreateWithFormat(allocator, NULL,
             CFSTR("not displayed (tag = %d; length %d)"),
-            tag, derThing->length);
+            tag, (int)derThing->length);
        }
 }
 
        }
 }
 
@@ -2230,7 +2231,7 @@ static OSStatus appendRDNProperty(void *context, const DERItem *rdnType,
        if (label) {
                appendDERThingProperty(properties, label, rdnValue);
                CFRelease(label);
        if (label) {
                appendDERThingProperty(properties, label, rdnValue);
                CFRelease(label);
-               return noErr;
+               return errSecSuccess;
        } else {
                return errSecInvalidCertificate;
        }
        } else {
                return errSecInvalidCertificate;
        }
@@ -3310,7 +3311,7 @@ static OSStatus obtainSummaryFromX501Name(void *context,
         const char tfm[] = "Thawte Freemail Member";
         if ((value->length == sizeof(tfm) + 1) &&
               !memcmp(value->data + 2, tfm, sizeof(tfm) - 1)) {
         const char tfm[] = "Thawte Freemail Member";
         if ((value->length == sizeof(tfm) + 1) &&
               !memcmp(value->data + 2, tfm, sizeof(tfm) - 1)) {
-            return noErr;
+            return errSecSuccess;
         }
         stype = kSummaryTypeCommonName;
     } else if (DEROidCompare(type, &oidOrganizationalUnitName)) {
         }
         stype = kSummaryTypeCommonName;
     } else if (DEROidCompare(type, &oidOrganizationalUnitName)) {
@@ -3342,7 +3343,7 @@ static OSStatus obtainSummaryFromX501Name(void *context,
         CFReleaseSafe(string);
     }
 
         CFReleaseSafe(string);
     }
 
-       return noErr;
+       return errSecSuccess;
 }
 
 CFStringRef SecCertificateCopySubjectSummaryP(SecCertificateRefP certificate) {
 }
 
 CFStringRef SecCertificateCopySubjectSummaryP(SecCertificateRefP certificate) {
@@ -3429,7 +3430,7 @@ static CFAbsoluteTime SecCertificateGetChainsFirstValidity(
     return latest;
 }
 
     return latest;
 }
 
-bool SecCertificateIsValid(SecCertificateRefP certificate,
+bool SecCertificateIsValidP(SecCertificateRefP certificate,
        CFAbsoluteTime verifyTime) {
        check(certificate);
     return certificate->_notBefore <= verifyTime &&
        CFAbsoluteTime verifyTime) {
        check(certificate);
     return certificate->_notBefore <= verifyTime &&
@@ -3440,11 +3441,11 @@ CFIndex SecCertificateVersion(SecCertificateRefP certificate) {
        return certificate->_version + 1;
 }
 
        return certificate->_version + 1;
 }
 
-CFAbsoluteTime SecCertificateNotValidBefore(SecCertificateRefP certificate) {
+CFAbsoluteTime SecCertificateNotValidBeforeP(SecCertificateRefP certificate) {
        return certificate->_notBefore;
 }
 
        return certificate->_notBefore;
 }
 
-CFAbsoluteTime SecCertificateNotValidAfter(SecCertificateRefP certificate) {
+CFAbsoluteTime SecCertificateNotValidAfterP(SecCertificateRefP certificate) {
        return certificate->_notAfter;
 }
 
        return certificate->_notAfter;
 }
 
@@ -3629,21 +3630,27 @@ CFDataRef SecCertificateCopySerialNumberP(
     return certificate->_serialNumber;
 }
 
     return certificate->_serialNumber;
 }
 
+/*
+ * Accessor for normalized issuer content
+ */
 CFDataRef SecCertificateGetNormalizedIssuerContent(
     SecCertificateRefP certificate) {
     return certificate->_normalizedIssuer;
 }
 
 CFDataRef SecCertificateGetNormalizedIssuerContent(
     SecCertificateRefP certificate) {
     return certificate->_normalizedIssuer;
 }
 
+/*
+ * Accessor for normalized subject content
+ */
 CFDataRef SecCertificateGetNormalizedSubjectContent(
     SecCertificateRefP certificate) {
 CFDataRef SecCertificateGetNormalizedSubjectContent(
     SecCertificateRefP certificate) {
-       DERItem tmpdi;
-       tmpdi.data = (DERByte *)CFDataGetBytePtr(certificate->_normalizedSubject);
-       tmpdi.length = CFDataGetLength(certificate->_normalizedSubject);
-
-    return SecDERItemCopySequence(&tmpdi);
+    return certificate->_normalizedSubject;
 }
 
 }
 
-CFDataRef SecCertificateGetNormalizedIssuer(
+/*
+ * Returns DER-encoded normalized issuer sequence
+ * for use with SecItemCopyMatching; caller must release
+ */
+CFDataRef SecCertificateCopyNormalizedIssuerSequence(
     SecCertificateRefP certificate) {
        DERItem tmpdi;
        tmpdi.data = (DERByte *)CFDataGetBytePtr(certificate->_normalizedIssuer);
     SecCertificateRefP certificate) {
        DERItem tmpdi;
        tmpdi.data = (DERByte *)CFDataGetBytePtr(certificate->_normalizedIssuer);
@@ -3652,12 +3659,21 @@ CFDataRef SecCertificateGetNormalizedIssuer(
     return SecDERItemCopySequence(&tmpdi);
 }
 
     return SecDERItemCopySequence(&tmpdi);
 }
 
-CFDataRef SecCertificateGetNormalizedSubject(
+/*
+ * Returns DER-encoded normalized subject sequence
+ * for use with SecItemCopyMatching; caller must release
+ */
+CFDataRef SecCertificateCopyNormalizedSubjectSequence(
     SecCertificateRefP certificate) {
     SecCertificateRefP certificate) {
-    return certificate->_normalizedSubject;
+       DERItem tmpdi;
+       tmpdi.data = (DERByte *)CFDataGetBytePtr(certificate->_normalizedSubject);
+       tmpdi.length = CFDataGetLength(certificate->_normalizedSubject);
+
+    return SecDERItemCopySequence(&tmpdi);
 }
 
 /* Verify that certificate was signed by issuerKey. */
 }
 
 /* Verify that certificate was signed by issuerKey. */
+static
 OSStatus SecCertificateIsSignedByP(SecCertificateRefP certificate,
        SecKeyRefP issuerKey) {
     /* Setup algId in SecAsn1AlgId format. */
 OSStatus SecCertificateIsSignedByP(SecCertificateRefP certificate,
        SecKeyRefP issuerKey) {
     /* Setup algId in SecAsn1AlgId format. */
@@ -3678,7 +3694,7 @@ OSStatus SecCertificateIsSignedByP(SecCertificateRefP certificate,
        }
 #endif
 
        }
 #endif
 
-    return noErr;
+    return errSecSuccess;
 }
 
 #if 0
 }
 
 #if 0
@@ -3744,7 +3760,7 @@ static OSStatus SecCertificateIsIssuedBy(SecCertificateRefP certificate,
                return errSecNotSigner;
        }
 
                return errSecNotSigner;
        }
 
-    return noErr;
+    return errSecSuccess;
 }
 
 static OSStatus _SecCertificateSetParent(SecCertificateRefP certificate,
 }
 
 static OSStatus _SecCertificateSetParent(SecCertificateRefP certificate,
@@ -3760,7 +3776,7 @@ static OSStatus _SecCertificateSetParent(SecCertificateRefP certificate,
     OSStatus status = SecCertificateIsIssuedBy(certificate, issuer,
         signatureCheckOnly);
 #else
     OSStatus status = SecCertificateIsIssuedBy(certificate, issuer,
         signatureCheckOnly);
 #else
-       OSStatus status = noErr;
+       OSStatus status = errSecSuccess;
 #endif
     if (!status) {
         if (CFEqual(certificate, issuer)) {
 #endif
     if (!status) {
         if (CFEqual(certificate, issuer)) {
@@ -3768,7 +3784,7 @@ static OSStatus _SecCertificateSetParent(SecCertificateRefP certificate,
                however we do record that we are properly self signed. */
             certificate->_isSelfSigned = kSecSelfSignedTrue;
             secdebug("cert", "set self as parent");
                however we do record that we are properly self signed. */
             certificate->_isSelfSigned = kSecSelfSignedTrue;
             secdebug("cert", "set self as parent");
-            return noErr;
+            return errSecSuccess;
         }
 
         CFRetain(issuer);
         }
 
         CFRetain(issuer);
@@ -3850,7 +3866,7 @@ OSStatus SecCertificateCompleteChain(SecCertificateRefP certificate,
     for (;;) {
         if (certificate->_parent == NULL) {
             if (SecCertificateIsSelfSigned(certificate))
     for (;;) {
         if (certificate->_parent == NULL) {
             if (SecCertificateIsSelfSigned(certificate))
-                return noErr;
+                return errSecSuccess;
             if (!other_certificates ||
                 !SecCertificateSetParentFrom(certificate, other_certificates,\
                     false)) {
             if (!other_certificates ||
                 !SecCertificateSetParentFrom(certificate, other_certificates,\
                     false)) {
@@ -3876,7 +3892,7 @@ static OSStatus appendIPAddressesFromGeneralNames(void *context,
                        return errSecInvalidCertificate;
                }
        }
                        return errSecInvalidCertificate;
                }
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 CFArrayRef SecCertificateCopyIPAddresses(SecCertificateRefP certificate) {
 }
 
 CFArrayRef SecCertificateCopyIPAddresses(SecCertificateRefP certificate) {
@@ -3909,7 +3925,7 @@ static OSStatus appendDNSNamesFromGeneralNames(void *context, SecCEGeneralNameTy
                        return errSecInvalidCertificate;
                }
        }
                        return errSecInvalidCertificate;
                }
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 /* Return true if the passed in string matches the
 }
 
 /* Return true if the passed in string matches the
@@ -4016,7 +4032,7 @@ static OSStatus appendDNSNamesFromX501Name(void *context, const DERItem *type,
                        return errSecInvalidCertificate;
                }
        }
                        return errSecInvalidCertificate;
                }
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 /* Not everything returned by this function is going to be a proper DNS name,
 }
 
 /* Not everything returned by this function is going to be a proper DNS name,
@@ -4026,7 +4042,7 @@ CFArrayRef SecCertificateCopyDNSNames(SecCertificateRefP certificate) {
        /* These can exist in the subject alt name or in the subject. */
        CFMutableArrayRef dnsNames = CFArrayCreateMutable(kCFAllocatorDefault,
                0, &kCFTypeArrayCallBacks);
        /* These can exist in the subject alt name or in the subject. */
        CFMutableArrayRef dnsNames = CFArrayCreateMutable(kCFAllocatorDefault,
                0, &kCFTypeArrayCallBacks);
-       OSStatus status = noErr;
+       OSStatus status = errSecSuccess;
        if (certificate->_subjectAltName) {
                status = parseGeneralNames(&certificate->_subjectAltName->extnValue,
                        dnsNames, appendDNSNamesFromGeneralNames);
        if (certificate->_subjectAltName) {
                status = parseGeneralNames(&certificate->_subjectAltName->extnValue,
                        dnsNames, appendDNSNamesFromGeneralNames);
@@ -4069,7 +4085,7 @@ static OSStatus appendRFC822NamesFromGeneralNames(void *context,
                        return errSecInvalidCertificate;
                }
        }
                        return errSecInvalidCertificate;
                }
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 static OSStatus appendRFC822NamesFromX501Name(void *context, const DERItem *type,
 }
 
 static OSStatus appendRFC822NamesFromX501Name(void *context, const DERItem *type,
@@ -4085,14 +4101,14 @@ static OSStatus appendRFC822NamesFromX501Name(void *context, const DERItem *type
                        return errSecInvalidCertificate;
                }
        }
                        return errSecInvalidCertificate;
                }
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 CFArrayRef SecCertificateCopyRFC822Names(SecCertificateRefP certificate) {
        /* These can exist in the subject alt name or in the subject. */
        CFMutableArrayRef rfc822Names = CFArrayCreateMutable(kCFAllocatorDefault,
                0, &kCFTypeArrayCallBacks);
 }
 
 CFArrayRef SecCertificateCopyRFC822Names(SecCertificateRefP certificate) {
        /* These can exist in the subject alt name or in the subject. */
        CFMutableArrayRef rfc822Names = CFArrayCreateMutable(kCFAllocatorDefault,
                0, &kCFTypeArrayCallBacks);
-       OSStatus status = noErr;
+       OSStatus status = errSecSuccess;
        if (certificate->_subjectAltName) {
                status = parseGeneralNames(&certificate->_subjectAltName->extnValue,
                        rfc822Names, appendRFC822NamesFromGeneralNames);
        if (certificate->_subjectAltName) {
                status = parseGeneralNames(&certificate->_subjectAltName->extnValue,
                        rfc822Names, appendRFC822NamesFromGeneralNames);
@@ -4121,7 +4137,7 @@ static OSStatus appendCommonNamesFromX501Name(void *context,
                        return errSecInvalidCertificate;
                }
        }
                        return errSecInvalidCertificate;
                }
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 CFArrayRef SecCertificateCopyCommonNames(SecCertificateRefP certificate) {
 }
 
 CFArrayRef SecCertificateCopyCommonNames(SecCertificateRefP certificate) {
@@ -4150,7 +4166,7 @@ static OSStatus appendOrganizationFromX501Name(void *context,
                        return errSecInvalidCertificate;
                }
        }
                        return errSecInvalidCertificate;
                }
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 CFArrayRef SecCertificateCopyOrganization(SecCertificateRefP certificate) {
 }
 
 CFArrayRef SecCertificateCopyOrganization(SecCertificateRefP certificate) {
@@ -4217,7 +4233,7 @@ static OSStatus appendNTPrincipalNamesFromGeneralNames(void *context,
             CFRelease(string);
                }
        }
             CFRelease(string);
                }
        }
-       return noErr;
+       return errSecSuccess;
 
 badDER:
     return errSecInvalidCertificate;
 
 badDER:
     return errSecInvalidCertificate;
@@ -4227,7 +4243,7 @@ badDER:
 CFArrayRef SecCertificateCopyNTPrincipalNames(SecCertificateRefP certificate) {
        CFMutableArrayRef ntPrincipalNames = CFArrayCreateMutable(kCFAllocatorDefault,
                0, &kCFTypeArrayCallBacks);
 CFArrayRef SecCertificateCopyNTPrincipalNames(SecCertificateRefP certificate) {
        CFMutableArrayRef ntPrincipalNames = CFArrayCreateMutable(kCFAllocatorDefault,
                0, &kCFTypeArrayCallBacks);
-       OSStatus status = noErr;
+       OSStatus status = errSecSuccess;
        if (certificate->_subjectAltName) {
                status = parseGeneralNames(&certificate->_subjectAltName->extnValue,
                        ntPrincipalNames, appendNTPrincipalNamesFromGeneralNames);
        if (certificate->_subjectAltName) {
                status = parseGeneralNames(&certificate->_subjectAltName->extnValue,
                        ntPrincipalNames, appendNTPrincipalNamesFromGeneralNames);
@@ -4332,7 +4348,7 @@ static OSStatus appendToRFC2253String(void *context,
 
     CFReleaseSafe(oid);
 
 
     CFReleaseSafe(oid);
 
-       return noErr;
+       return errSecSuccess;
 }
 
 CFStringRef SecCertificateCopySubjectString(SecCertificateRefP certificate) {
 }
 
 CFStringRef SecCertificateCopySubjectString(SecCertificateRefP certificate) {
@@ -4349,19 +4365,19 @@ static OSStatus appendToCompanyNameString(void *context,
        const DERItem *type, const DERItem *value, CFIndex rdnIX) {
        CFMutableStringRef string = (CFMutableStringRef)context;
     if (CFStringGetLength(string) != 0)
        const DERItem *type, const DERItem *value, CFIndex rdnIX) {
        CFMutableStringRef string = (CFMutableStringRef)context;
     if (CFStringGetLength(string) != 0)
-        return noErr;
+        return errSecSuccess;
 
     if (!DEROidCompare(type, &oidOrganizationName))
 
     if (!DEROidCompare(type, &oidOrganizationName))
-        return noErr;
+        return errSecSuccess;
 
     CFStringRef raw;
     raw = copyDERThingDescription(kCFAllocatorDefault, value, true);
     if (!raw)
 
     CFStringRef raw;
     raw = copyDERThingDescription(kCFAllocatorDefault, value, true);
     if (!raw)
-        return noErr;
+        return errSecSuccess;
     CFStringAppend(string, raw);
     CFRelease(raw);
 
     CFStringAppend(string, raw);
     CFRelease(raw);
 
-       return noErr;
+       return errSecSuccess;
 }
 
 CFStringRef SecCertificateCopyCompanyName(SecCertificateRefP certificate) {
 }
 
 CFStringRef SecCertificateCopyCompanyName(SecCertificateRefP certificate) {
@@ -4393,12 +4409,12 @@ out:
     return NULL;
 }
 
     return NULL;
 }
 
-CFDataRef SecCertificateCopyIssuerSequence(
+CFDataRef SecCertificateCopyIssuerSequenceP(
     SecCertificateRefP certificate) {
     return SecDERItemCopySequence(&certificate->_issuer);
 }
 
     SecCertificateRefP certificate) {
     return SecDERItemCopySequence(&certificate->_issuer);
 }
 
-CFDataRef SecCertificateCopySubjectSequence(
+CFDataRef SecCertificateCopySubjectSequenceP(
     SecCertificateRefP certificate) {
     return SecDERItemCopySequence(&certificate->_subject);
 }
     SecCertificateRefP certificate) {
     return SecDERItemCopySequence(&certificate->_subject);
 }
@@ -4423,14 +4439,14 @@ SecKeyRefP SecCertificateCopyPublicKeyP(SecCertificateRefP certificate) {
                publicKey = SecKeyCreateRSAPublicKey(kCFAllocatorDefault,
                        keyData->data, keyData->length, kSecKeyEncodingPkcs1);
     } else {
                publicKey = SecKeyCreateRSAPublicKey(kCFAllocatorDefault,
                        keyData->data, keyData->length, kSecKeyEncodingPkcs1);
     } else {
-               secdebug(NULL, "Unsupported algorithm oid");
+               secdebug("cert", "Unsupported algorithm oid");
        }
 #endif
 
     return publicKey;
 }
 
        }
 #endif
 
     return publicKey;
 }
 
-CFDataRef SecCertificateGetSHA1Digest(SecCertificateRefP certificate) {
+CFDataRef SecCertificateGetSHA1DigestP(SecCertificateRefP certificate) {
     if (!certificate->_sha1Digest) {
                certificate->_sha1Digest =
                        SecSHA1DigestCreate(CFGetAllocator(certificate),
     if (!certificate->_sha1Digest) {
                certificate->_sha1Digest =
                        SecSHA1DigestCreate(CFGetAllocator(certificate),
@@ -4442,7 +4458,7 @@ CFDataRef SecCertificateGetSHA1Digest(SecCertificateRefP certificate) {
 
 CFDataRef SecCertificateCopyIssuerSHA1Digest(SecCertificateRefP certificate) {
     CFDataRef digest = NULL;
 
 CFDataRef SecCertificateCopyIssuerSHA1Digest(SecCertificateRefP certificate) {
     CFDataRef digest = NULL;
-    CFDataRef issuer = SecCertificateCopyIssuerSequence(certificate);
+    CFDataRef issuer = SecCertificateCopyIssuerSequenceP(certificate);
     if (issuer) {
         digest = SecSHA1DigestCreate(kCFAllocatorDefault,
             CFDataGetBytePtr(issuer), CFDataGetLength(issuer));
     if (issuer) {
         digest = SecSHA1DigestCreate(kCFAllocatorDefault,
             CFDataGetBytePtr(issuer), CFDataGetLength(issuer));
@@ -4456,6 +4472,21 @@ CFDataRef SecCertificateCopyPublicKeySHA1Digest(SecCertificateRefP certificate)
         certificate->_pubKeyDER.data, certificate->_pubKeyDER.length);
 }
 
         certificate->_pubKeyDER.data, certificate->_pubKeyDER.length);
 }
 
+CFDataRef SecCertificateCopyPublicKeySHA1DigestFromCertificateData(CFAllocatorRef allocator,
+       CFDataRef der_certificate)
+{
+       CFDataRef result = NULL;
+       SecCertificateRefP iosCertRef = SecCertificateCreateWithDataP(allocator, der_certificate);
+       if (NULL == iosCertRef)
+       {
+               return result;
+       }
+       
+       result = SecCertificateCopyPublicKeySHA1Digest(iosCertRef);
+       CFRelease(iosCertRef);
+       return result;  
+}
+
 CFDataRef SecCertificateGetAuthorityKeyID(SecCertificateRefP certificate) {
        if (!certificate->_authorityKeyID &&
                certificate->_authorityKeyIdentifier.length) {
 CFDataRef SecCertificateGetAuthorityKeyID(SecCertificateRefP certificate) {
        if (!certificate->_authorityKeyID &&
                certificate->_authorityKeyIdentifier.length) {
index 05893080c326ba6a13f99e08d310d078f3920bcc..9a49ca60586d732d713ffb272376c134fed2a725 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2006-2009 Apple Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2006-2009,2012 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -87,14 +87,26 @@ CFStringRef SecCertificateCopySubjectSummaryP(SecCertificateRefP certificate)
 
 /*!
        @function SecCertificateIsValid
 
 /*!
        @function SecCertificateIsValid
-       @abstract 
+       @abstract Returns true if the given certificate is valid
+       at the specified verifyTime.
     @param certificate SecCertificate object created with
     SecCertificateCreateWithDataP().
        @result DER encoded X.509 certificate.
 */
     @param certificate SecCertificate object created with
     SecCertificateCreateWithDataP().
        @result DER encoded X.509 certificate.
 */
-bool SecCertificateIsValid(SecCertificateRefP certificate, CFAbsoluteTime verifyTime)
+bool SecCertificateIsValidP(SecCertificateRefP certificate, CFAbsoluteTime verifyTime)
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0);
 
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0);
 
+/*!
+       @function SecCertificateCopyPublicKeySHA1DigestFromCertificateData
+       @abstract Returns the SHA1 hasj of the public key of a certificate or NULL
+    @param allocator CFAllocator to allocate the certificate with.
+    @param certificate DER encoded X.509 certificate.
+       @result SHA1 hasj of the public key of a certificate or NULL
+*/
+CFDataRef SecCertificateCopyPublicKeySHA1DigestFromCertificateData(CFAllocatorRef allocator,
+       CFDataRef der_certificate);
+       
+
 #if defined(__cplusplus)
 }
 #endif
 #if defined(__cplusplus)
 }
 #endif
index e1a9cbbb6bfec316a1057821c93684eed67b674b..157032af67399915e3f6a68d878813f7de6133b4 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2002-2004,2012 Apple Inc. All Rights Reserved.
+ * Copyright (c) 2002-2004,2012-2013 Apple Inc. All Rights Reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 extern "C" {
 #endif
 
 extern "C" {
 #endif
 
+typedef uint32_t SecCertificateEscrowRootType;
+enum {
+    kSecCertificateBaselineEscrowRoot = 0,
+    kSecCertificateProductionEscrowRoot = 1,
+};
+
+extern CFTypeRef kSecCertificateProductionEscrowKey;
+extern CFTypeRef kSecCertificateEscrowFileName;
+
+
 /* Return a certificate for the DER representation of this certificate.
    Return NULL if the passed-in data is not a valid DER-encoded X.509
    certificate. */
 /* Return a certificate for the DER representation of this certificate.
    Return NULL if the passed-in data is not a valid DER-encoded X.509
    certificate. */
@@ -48,6 +58,9 @@ CFIndex SecCertificateGetLength(SecCertificateRef certificate);
 /* Return the bytes of the DER representation of this certificate. */
 const UInt8 *SecCertificateGetBytePtr(SecCertificateRef certificate);
 
 /* Return the bytes of the DER representation of this certificate. */
 const UInt8 *SecCertificateGetBytePtr(SecCertificateRef certificate);
 
+/* Return the SHA-1 hash of this certificate. */
+CFDataRef SecCertificateGetSHA1Digest(SecCertificateRef certificate);
+
 /* Deprecated; use SecCertificateCopyCommonName() instead. */
 OSStatus SecCertificateGetCommonName(SecCertificateRef certificate, CFStringRef *commonName);
 
 /* Deprecated; use SecCertificateCopyCommonName() instead. */
 OSStatus SecCertificateGetCommonName(SecCertificateRef certificate, CFStringRef *commonName);
 
@@ -130,6 +143,12 @@ OSStatus SecCertificateReleaseFirstFieldValue(SecCertificateRef certificate, con
 OSStatus SecCertificateCopySubjectComponent(SecCertificateRef certificate, const CSSM_OID *component,
        CFStringRef *result);
 
 OSStatus SecCertificateCopySubjectComponent(SecCertificateRef certificate, const CSSM_OID *component,
        CFStringRef *result);
 
+/* Return the DER encoded issuer sequence for the certificate's issuer. */
+CFDataRef SecCertificateCopyIssuerSequence(SecCertificateRef certificate);
+
+/* Return the DER encoded subject sequence for the certificate's subject. */
+CFDataRef SecCertificateCopySubjectSequence(SecCertificateRef certificate);
+
 
 /*     Convenience functions for searching.
 */
 
 /*     Convenience functions for searching.
 */
@@ -161,17 +180,57 @@ OSStatus SecKeychainSearchCreateForCertificateByEmail(CFTypeRef keychainOrArray,
 CSSM_RETURN SecDigestGetData(CSSM_ALGORITHMS alg, CSSM_DATA* digest, const CSSM_DATA* data);
 
 /* Return true iff certificate is valid as of verifyTime. */
 CSSM_RETURN SecDigestGetData(CSSM_ALGORITHMS alg, CSSM_DATA* digest, const CSSM_DATA* data);
 
 /* Return true iff certificate is valid as of verifyTime. */
-bool SecCertificateIsValidX(SecCertificateRef certificate, CFAbsoluteTime verifyTime);
+/* DEPRECATED: Use SecCertificateIsValid instead. */
+bool SecCertificateIsValidX(SecCertificateRef certificate, CFAbsoluteTime verifyTime)
+    __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_7, __MAC_10_9, __IPHONE_NA, __IPHONE_NA);
+
+/*!
+       @function SecCertificateIsValid
+       @abstract Check certificate validity on a given date.
+       @param certificate A certificate reference.
+       @result Returns true if the specified date falls within the certificate's validity period, false otherwise.
+*/
+bool SecCertificateIsValid(SecCertificateRef certificate, CFAbsoluteTime verifyTime)
+       __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_2_0);
 
 
-/* NOT EXPORTED YET; copied from SecurityInterface but could be useful in the future.
-CSSM_CSP_HANDLE        SecGetAppleCSPHandle();
-CSSM_CL_HANDLE SecGetAppleCLHandle();
+/*!
+       @function SecCertificateNotValidBefore
+       @abstract Obtain the starting date of the given certificate.
+       @param certificate A certificate reference.
+       @result Returns the absolute time at which the given certificate becomes valid,
+       or 0 if this value could not be obtained.
 */
 */
+CFAbsoluteTime SecCertificateNotValidBefore(SecCertificateRef certificate)
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_2_0);
 
 
-/* determine whether a cert is self-signed */
-OSStatus SecCertificateIsSelfSigned(
-       SecCertificateRef certRef,
-       Boolean *isSelfSigned);         /* RETURNED */
+/*!
+       @function SecCertificateNotValidAfter
+       @abstract Obtain the expiration date of the given certificate.
+       @param certificate A certificate reference.
+       @result Returns the absolute time at which the given certificate expires,
+       or 0 if this value could not be obtained.
+*/
+CFAbsoluteTime SecCertificateNotValidAfter(SecCertificateRef certificate)
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_2_0);
+
+/*!
+       @function SecCertificateIsSelfSigned
+       @abstract Determine if the given certificate is self-signed.
+       @param certRef A certificate reference.
+       @param isSelfSigned Will be set to true on return if the certificate is self-signed, false otherwise.
+       @result A result code. Returns errSecSuccess if the certificate's status can be determined.
+*/
+OSStatus SecCertificateIsSelfSigned(SecCertificateRef certRef, Boolean *isSelfSigned)
+    __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
+
+/*!
+       @function SecCertificateCopyEscrowRoots
+       @abstract Retrieve the array of valid escrow certificates for a given root type.
+       @param escrowRootType An enumerated type indicating which root type to return.
+       @result An array of zero or more escrow certificates matching the provided type.
+*/
+CFArrayRef SecCertificateCopyEscrowRoots(SecCertificateEscrowRootType escrowRootType)
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
 
 
 #if defined(__cplusplus)
 
 
 #if defined(__cplusplus)
index 4feedbe6c46dd17ab4f906cae63f8104376d00cd..b28984111500990751bedb8d884ae843f78621a5 100644 (file)
@@ -79,7 +79,7 @@ const UInt8 *SecCertificateGetBytePtrP(SecCertificateRefP certificate);
 #pragma mark -
 #pragma mark Certificate Accessors
 
 #pragma mark -
 #pragma mark Certificate Accessors
 
-CFDataRef SecCertificateGetSHA1Digest(SecCertificateRefP certificate);
+CFDataRef SecCertificateGetSHA1DigestP(SecCertificateRefP certificate);
 
 CFDataRef SecCertificateCopyIssuerSHA1Digest(SecCertificateRefP certificate);
 
 
 CFDataRef SecCertificateCopyIssuerSHA1Digest(SecCertificateRefP certificate);
 
@@ -148,8 +148,9 @@ CFStringRef SecCertificateCopyCompanyName(SecCertificateRefP certificate);
 
 /* X.509 Certificate Version: 1, 2 or 3. */
 CFIndex SecCertificateVersion(SecCertificateRefP certificate);
 
 /* X.509 Certificate Version: 1, 2 or 3. */
 CFIndex SecCertificateVersion(SecCertificateRefP certificate);
-CFAbsoluteTime SecCertificateNotValidBefore(SecCertificateRefP certificate);
-CFAbsoluteTime SecCertificateNotValidAfter(SecCertificateRefP certificate);
+
+CFAbsoluteTime SecCertificateNotValidBeforeP(SecCertificateRefP certificate);
+CFAbsoluteTime SecCertificateNotValidAfterP(SecCertificateRefP certificate);
 
 /* Return true iff certificate is self signed and has a basic constraints
    extension indicating that it's a certificate authority. */
 
 /* Return true iff certificate is self signed and has a basic constraints
    extension indicating that it's a certificate authority. */
@@ -173,8 +174,8 @@ CFArrayRef SecCertificateDataArrayCopyArray(CFArrayRef certificates);
 CFDataRef SecCertificateGetNormalizedIssuerContent(SecCertificateRefP certificate);
 CFDataRef SecCertificateGetNormalizedSubjectContent(SecCertificateRefP certificate);
 
 CFDataRef SecCertificateGetNormalizedIssuerContent(SecCertificateRefP certificate);
 CFDataRef SecCertificateGetNormalizedSubjectContent(SecCertificateRefP certificate);
 
-CFDataRef SecCertificateGetNormalizedIssuer(SecCertificateRefP certificate);
-CFDataRef SecCertificateGetNormalizedSubject(SecCertificateRefP certificate);
+CFDataRef SecCertificateCopyNormalizedIssuerSequence(SecCertificateRefP certificate);
+CFDataRef SecCertificateCopyNormalizedSubjectSequence(SecCertificateRefP certificate);
 
 #if defined(__cplusplus)
 }
 
 #if defined(__cplusplus)
 }
index 26f7080940379272d8ab966bc9268e330daeae92..81353eb8cea277b2397b3db59869033f1d379217 100644 (file)
@@ -137,7 +137,7 @@ OSStatus SecCertificateRequestGetResult(
                switch(numItems) {
                        case 0:
                                certReqDbg("SecCertificateRequestGetResult: import zero items");
                switch(numItems) {
                        case 0:
                                certReqDbg("SecCertificateRequestGetResult: import zero items");
-                               MacOSError::throwMe(internalComponentErr);
+                               MacOSError::throwMe(errSecInternalComponent);
                        default:
                                certReqDbg("SecCertificateRequestGetResult: import %d items", 
                                        (int)numItems);
                        default:
                                certReqDbg("SecCertificateRequestGetResult: import %d items", 
                                        (int)numItems);
index e4769d4a4a4fc1ad60230c97c73ef494891a4547..cbbb3ca8104fc92062dc3928f6266ec77cc5a692 100644 (file)
@@ -82,7 +82,7 @@ CFTypeID SecCertificateRequestGetTypeID(void);
           kSecAppleKeyItemClass.
        @param attributeList An optional list of OIDs for the certificate request.
        @param certRequest A returned reference to the certificate request. Call CFRelease when done with this certificate request.
           kSecAppleKeyItemClass.
        @param attributeList An optional list of OIDs for the certificate request.
        @param certRequest A returned reference to the certificate request. Call CFRelease when done with this certificate request.
-       @result noErr 0 No error.
+       @result errSecSuccess 0 No error.
 */
 OSStatus SecCertificateRequestCreate(
         const CSSM_OID *policy,
 */
 OSStatus SecCertificateRequestCreate(
         const CSSM_OID *policy,
@@ -104,7 +104,7 @@ OSStatus SecCertificateRequestCreate(
        @param certRequest A reference to the certificate request.
        @param estimatedTime The number of estimated seconds before the result 
           can be retrieved.
        @param certRequest A reference to the certificate request.
        @param estimatedTime The number of estimated seconds before the result 
           can be retrieved.
-       @result noErr 0 No error.
+       @result errSecSuccess 0 No error.
 */
 OSStatus SecCertificateRequestSubmit(
         SecCertificateRequestRef certRequest,
 */
 OSStatus SecCertificateRequestSubmit(
         SecCertificateRequestRef certRequest,
@@ -116,7 +116,7 @@ OSStatus SecCertificateRequestSubmit(
        certificate request item reference.
     @param certRequestRef A reference to a submitted request.
        @param requestType The returned request type.
        certificate request item reference.
     @param certRequestRef A reference to a submitted request.
        @param requestType The returned request type.
-    @result noErr 0 No error.
+    @result errSecSuccess 0 No error.
 */
 OSStatus SecCertificateRequestGetType(
         SecCertificateRequestRef certRequestRef,
 */
 OSStatus SecCertificateRequestGetType(
         SecCertificateRequestRef certRequestRef,
@@ -136,7 +136,7 @@ OSStatus SecCertificateRequestGetType(
        @param certficateRef The returned certificate reference for a 
           CSSM_TP_AUTHORITY_REQUEST_CERTISSUE only. All other request types return 
           NULL here. Call CFRelease when done with this certificate reference.
        @param certficateRef The returned certificate reference for a 
           CSSM_TP_AUTHORITY_REQUEST_CERTISSUE only. All other request types return 
           NULL here. Call CFRelease when done with this certificate reference.
-    @result noErr 0 No error.
+    @result errSecSuccess 0 No error.
 */
 OSStatus SecCertificateRequestGetResult(
         SecCertificateRequestRef certRequestRef,
 */
 OSStatus SecCertificateRequestGetResult(
         SecCertificateRequestRef certRequestRef,
@@ -177,7 +177,7 @@ OSStatus SecCertificateFindRequest(
        Get policy-specific data following a SecCertificateRequestSubmit.
     @param certRequestRef A reference for the submitted request.
     @param data Policy-specific data.
        Get policy-specific data following a SecCertificateRequestSubmit.
     @param certRequestRef A reference for the submitted request.
     @param data Policy-specific data.
-    @result noErr 0 No error.
+    @result errSecSuccess 0 No error.
 */
 
 OSStatus SecCertificateRequestGetData(
 */
 
 OSStatus SecCertificateRequestGetData(
index 56cff615a1079717a815b9199298a02b04b2d06b..ce4e3de5ccef950ff8509af956fad910ee7a9e44 100644 (file)
 #include "SecImportExportPem.h"
 #include "SecExternalRep.h"
 #include "SecImportExportUtils.h"
 #include "SecImportExportPem.h"
 #include "SecExternalRep.h"
 #include "SecImportExportUtils.h"
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 #include <security_utilities/errors.h>
 #include <Security/SecIdentity.h>
 #include <Security/SecIdentityPriv.h>
 #include <Security/SecItem.h>
 #include <security_utilities/errors.h>
 #include <Security/SecIdentity.h>
 #include <Security/SecIdentityPriv.h>
 #include <Security/SecItem.h>
-
+#include <Security/SecBase.h>
 using namespace Security;
 using namespace KeychainCore;
 
 using namespace Security;
 using namespace KeychainCore;
 
@@ -108,20 +107,20 @@ OSStatus SecKeychainItemExport(
        
        /* some basic input validation */
        if(keychainItemOrArray == NULL) {
        
        /* some basic input validation */
        if(keychainItemOrArray == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        if(keyParams != NULL) {
                /* can't specify explicit passphrase and ask for secure one */
                if( (keyParams->passphrase != NULL) &&
        }
        if(keyParams != NULL) {
                /* can't specify explicit passphrase and ask for secure one */
                if( (keyParams->passphrase != NULL) &&
-                   (keyParams->flags & kSecKeySecurePassphrase != 0)) {
-                       return paramErr;
+                   ((keyParams->flags & kSecKeySecurePassphrase) != 0)) {
+                       return errSecParam;
                }
        }
        
        unsigned numKeys                        = 0;
        unsigned numCerts                       = 0;
        unsigned numTotalExports        = 0;
                }
        }
        
        unsigned numKeys                        = 0;
        unsigned numCerts                       = 0;
        unsigned numTotalExports        = 0;
-       OSStatus ortn                           = noErr;
+       OSStatus ortn                           = errSecSuccess;
        SecExportRep *rep                       = NULL;                         // common temp variable
        CFMutableDataRef outputData = NULL;
        const char *pemHeader           = "UNKNOWN";
        SecExportRep *rep                       = NULL;                         // common temp variable
        CFMutableDataRef outputData = NULL;
        const char *pemHeader           = "UNKNOWN";
@@ -148,10 +147,10 @@ OSStatus SecKeychainItemExport(
                goto errOut;
        }
        catch(...) {
                goto errOut;
        }
        catch(...) {
-               ortn = paramErr;
+               ortn = errSecParam;
                goto errOut;
        }
                goto errOut;
        }
-       numTotalExports = CFArrayGetCount(exportReps);
+       numTotalExports = (unsigned int)CFArrayGetCount(exportReps);
        assert((numCerts + numKeys) == numTotalExports);
        if((numTotalExports > 1) && (outputFormat == kSecFormatUnknown)) {
                /* default aggregate format is PEM sequence */
        assert((numCerts + numKeys) == numTotalExports);
        if((numTotalExports > 1) && (outputFormat == kSecFormatUnknown)) {
                /* default aggregate format is PEM sequence */
@@ -235,7 +234,7 @@ OSStatus SecKeychainItemExport(
                                }
                                if((numTotalExports != 1) || (foundCount != 1)) {
                                        SecImpExpDbg("Export single item format with other than one item");
                                }
                                if((numTotalExports != 1) || (foundCount != 1)) {
                                        SecImpExpDbg("Export single item format with other than one item");
-                                       ortn = paramErr;
+                                       ortn = errSecParam;
                                        goto errOut;
                                }
                                assert(CFArrayGetCount(exportReps) == 1);
                                        goto errOut;
                                }
                                assert(CFArrayGetCount(exportReps) == 1);
@@ -247,7 +246,7 @@ OSStatus SecKeychainItemExport(
                default:
                        SecImpExpDbg("SecKeychainItemExport: bad format (%u)", 
                                (unsigned)outputFormat);
                default:
                        SecImpExpDbg("SecKeychainItemExport: bad format (%u)", 
                                (unsigned)outputFormat);
-                       ortn = paramErr;
+                       ortn = errSecParam;
                        goto errOut;
        }
        
                        goto errOut;
        }
        
@@ -257,7 +256,7 @@ OSStatus SecKeychainItemExport(
         * if exportRep has a non-NULL pemParamLines (which can only happen if we're
         * exporting a single item). 
         */
         * if exportRep has a non-NULL pemParamLines (which can only happen if we're
         * exporting a single item). 
         */
-       if(ortn == noErr) {
+       if(ortn == errSecSuccess) {
                if(outputFormat == kSecFormatPEMSequence) {
                        *exportedData = outputData;
                        outputData = NULL;              
                if(outputFormat == kSecFormatPEMSequence) {
                        *exportedData = outputData;
                        outputData = NULL;              
@@ -297,7 +296,7 @@ errOut:
                return SecKeychainErrFromOSStatus(ortn);
        }
        else {
                return SecKeychainErrFromOSStatus(ortn);
        }
        else {
-               return noErr;
+               return errSecSuccess;
        }
        
        END_IMP_EXP_SECAPI
        }
        
        END_IMP_EXP_SECAPI
index 672932a9155bde85dc403e0c7b20931396109a94..fe681e16b3c5d5b7e7d5c7d287a67be320aad488 100644 (file)
 #include "SecImportExportCrypto.h"
 #include "SecImportExportOpenSSH.h"
 #include <security_utilities/errors.h>
 #include "SecImportExportCrypto.h"
 #include "SecImportExportOpenSSH.h"
 #include <security_utilities/errors.h>
+#include <Security/SecBase.h>
 #include <Security/SecKeyPriv.h>
 #include <Security/SecCertificate.h>
 #include <Security/cssmapi.h>
 #include <Security/SecKeyPriv.h>
 #include <Security/SecCertificate.h>
 #include <Security/cssmapi.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 
 using namespace Security;
 using namespace KeychainCore;
 
 using namespace Security;
 using namespace KeychainCore;
@@ -235,7 +235,7 @@ OSStatus SecExport::Key::exportRep(
         * Remaining formats just do a NULL key wrap. Figure out the appropriate
         * CDSA-specific format and wrap parameters. 
         */
         * Remaining formats just do a NULL key wrap. Figure out the appropriate
         * CDSA-specific format and wrap parameters. 
         */
-       OSStatus ortn = noErr;
+       OSStatus ortn = errSecSuccess;
        CSSM_KEYBLOB_FORMAT blobForm;
        
        switch(mExternType) {
        CSSM_KEYBLOB_FORMAT blobForm;
        
        switch(mExternType) {
@@ -388,7 +388,7 @@ OSStatus SecExport::Cert::exportRep(
        CFDataAppendBytes(outData, CFDataGetBytePtr(cdata), CFDataGetLength(cdata));
        CFRelease(cdata);
        *pemHeader = PEM_STRING_X509;
        CFDataAppendBytes(outData, CFDataGetBytePtr(cdata), CFDataGetLength(cdata));
        CFRelease(cdata);
        *pemHeader = PEM_STRING_X509;
-       return noErr;
+       return errSecSuccess;
 }
        
 #pragma mark --- SecImportRep: Representation of an external object on import ---
 }
        
 #pragma mark --- SecImportRep: Representation of an external object on import ---
@@ -445,7 +445,7 @@ OSStatus SecImportRep::importRep(
                   
        /* app could conceivably botch these with crafty PEM hacking */
        if((mExternal == NULL) || (CFDataGetLength(mExternal) == 0)) {
                   
        /* app could conceivably botch these with crafty PEM hacking */
        if((mExternal == NULL) || (CFDataGetLength(mExternal) == 0)) {
-               return paramErr;
+               return errSecParam;
        }
        
        /* handle the easy ones first */
        }
        
        /* handle the easy ones first */
@@ -477,7 +477,7 @@ OSStatus SecImportRep::importRep(
        if((mExternType == kSecItemTypeCertificate) || 
           (mExternType == kSecItemTypeAggregate)) {
                SecImpExpDbg("SecImportRep::importRep screwup");
        if((mExternType == kSecItemTypeCertificate) || 
           (mExternType == kSecItemTypeAggregate)) {
                SecImpExpDbg("SecImportRep::importRep screwup");
-               return unimpErr;
+               return errSecUnimplemented;
        }
 
        /* 
        }
 
        /* 
@@ -500,7 +500,7 @@ OSStatus SecImportRep::importRep(
                        break;
        }
        
                        break;
        }
        
-       OSStatus ortn = noErr;
+       OSStatus ortn = errSecSuccess;
        
        switch(mExternFormat) {
                case kSecFormatOpenSSL:
        
        switch(mExternFormat) {
                case kSecFormatOpenSSL:
@@ -527,7 +527,7 @@ OSStatus SecImportRep::importRep(
                default:
                        return errSecUnknownFormat;
        }
                default:
                        return errSecUnknownFormat;
        }
-       if((ortn == noErr) && (keyImportState == PIS_AllowOne)) {
+       if((ortn == errSecSuccess) && (keyImportState == PIS_AllowOne)) {
                /* reached our limit */
                keyImportState = PIS_NoMore;
        }
                /* reached our limit */
                keyImportState = PIS_NoMore;
        }
index 7886b542b199ca0465a04c22b4180516cf8ab550..4b671032a87e20ef4832b031394b87882a8d11eb 100644 (file)
@@ -55,7 +55,7 @@ int SecFDERecoveryWrapCRSKWithPubKey(const uint8_t *crsk, size_t crskLen,
 CFDataRef SecFDERecoveryUnwrapCRSKWithPrivKey(SecKeychainRef keychain, const FVPrivateKeyHeader *inHeader)
 {
        CFDataRef result = NULL;
 CFDataRef SecFDERecoveryUnwrapCRSKWithPrivKey(SecKeychainRef keychain, const FVPrivateKeyHeader *inHeader)
 {
        CFDataRef result = NULL;
-       OSStatus __secapiresult;
+       OSStatus __secapiresult = 0;
 
        try
        {
 
        try
        {
@@ -63,9 +63,9 @@ CFDataRef SecFDERecoveryUnwrapCRSKWithPrivKey(SecKeychainRef keychain, const FVP
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
-       catch (const std::bad_alloc &) { __secapiresult=memFullErr; }
-       catch (...) { __secapiresult=internalComponentErr; }
-       secdebug("FDERecovery", "SecFDERecoveryUnwrapCRSKWithPrivKey: %ld", __secapiresult);
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
+       catch (...) { __secapiresult=errSecInternalComponent; }
+       secdebug("FDERecovery", "SecFDERecoveryUnwrapCRSKWithPrivKey: %d", (int)__secapiresult);
        return result;
 }
 
        return result;
 }
 
@@ -101,7 +101,7 @@ static void encodePrivateKeyHeader(const CssmData &inBlob, CFDataRef certificate
        CssmData *cssmData = reinterpret_cast<CssmData *>(outData);
        
        assert(cssmData->Length <= sizeof(outHeader.publicKeyHash));
        CssmData *cssmData = reinterpret_cast<CssmData *>(outData);
        
        assert(cssmData->Length <= sizeof(outHeader.publicKeyHash));
-       outHeader.publicKeyHashSize = cssmData->Length;
+       outHeader.publicKeyHashSize = (uint32_t)cssmData->Length;
        memcpy(outHeader.publicKeyHash, cssmData->Data, cssmData->Length);
        fCSP.allocator().free(cssmData->Data);
        fCSP.allocator().free(cssmData);
        memcpy(outHeader.publicKeyHash, cssmData->Data, cssmData->Length);
        fCSP.allocator().free(cssmData->Data);
        fCSP.allocator().free(cssmData);
@@ -113,7 +113,7 @@ static void encodePrivateKeyHeader(const CssmData &inBlob, CFDataRef certificate
        CssmAutoData remData(fCSP.allocator());
        encrypt.padding(CSSM_PADDING_PKCS1);
        
        CssmAutoData remData(fCSP.allocator());
        encrypt.padding(CSSM_PADDING_PKCS1);
        
-       outHeader.encryptedBlobSize = encrypt.encrypt(inBlob, clearBuf, remData.get());
+       outHeader.encryptedBlobSize = (uint32_t)encrypt.encrypt(inBlob, clearBuf, remData.get());
        if (outHeader.encryptedBlobSize > sizeof(outHeader.encryptedBlob))
                secdebug("FDERecovery", "encodePrivateKeyHeader: encrypted blob too big: %d", outHeader.encryptedBlobSize);
 }
        if (outHeader.encryptedBlobSize > sizeof(outHeader.encryptedBlob))
                secdebug("FDERecovery", "encodePrivateKeyHeader: encrypted blob too big: %d", outHeader.encryptedBlobSize);
 }
index 49a740c2d773f1ac95eaddfad58401bef4723a03..86c5fca81be84d3f7a721aa06465eb3da2935bcb 100644 (file)
 #include <fcntl.h>
 #include <sys/types.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/types.h>
 #include <unistd.h>
-#include <debuggingP.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 #include <errno.h>
 #include <errno.h>
+#include <dlfcn.h>
+#include <string.h>
+#include <CoreFoundation/CFBundlePriv.h>
+
+#include <utilities/debugging.h>
 
 /* Security.framework's bundle id. */
 static CFStringRef kSecFrameworkBundleID = CFSTR("com.apple.Security");
 
 /* Security.framework's bundle id. */
 static CFStringRef kSecFrameworkBundleID = CFSTR("com.apple.Security");
@@ -63,7 +66,15 @@ bool SecAsn1OidCompare(const SecAsn1Oid *oid1, const SecAsn1Oid *oid2) {
 #endif
 
 static void SecFrameworkBundleLookup(void) {
 #endif
 
 static void SecFrameworkBundleLookup(void) {
-    kSecFrameworkBundle = CFBundleGetBundleWithIdentifier(kSecFrameworkBundleID);
+       // figure out the path to our executable
+       Dl_info info;
+       dladdr("", &info);
+       
+       // make a file URL from the returned string
+       CFURLRef urlRef = CFURLCreateFromFileSystemRepresentation(NULL, (const UInt8*) info.dli_fname, strlen(info.dli_fname), false);
+       kSecFrameworkBundle = _CFBundleCreateWithExecutableURLIfLooksLikeBundle(NULL, urlRef);
+       CFRelease(urlRef);
+
     if (kSecFrameworkBundle)
         CFRetain(kSecFrameworkBundle);
 }
     if (kSecFrameworkBundle)
         CFRetain(kSecFrameworkBundle);
 }
@@ -88,7 +99,7 @@ CFURLRef SecFrameworkCopyResourceURL(CFStringRef resourceName,
         url = CFBundleCopyResourceURL(kSecFrameworkBundle, resourceName,
                        resourceType, subDirName);
                if (!url) {
         url = CFBundleCopyResourceURL(kSecFrameworkBundle, resourceName,
                        resourceType, subDirName);
                if (!url) {
-            secdebug(NULL, "resource: %@.%@ in %@ not found", resourceName,
+            secdebug("SecFramework", "resource: %@.%@ in %@ not found", resourceName,
                 resourceType, subDirName);
                }
     }
                 resourceType, subDirName);
                }
     }
@@ -106,7 +117,7 @@ CFDataRef SecFrameworkCopyResourceContents(CFStringRef resourceName,
         SInt32 error;
         if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault,
             url, &data, NULL, NULL, &error)) {
         SInt32 error;
         if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault,
             url, &data, NULL, NULL, &error)) {
-            secdebug(NULL, "read: %@: %d", error);
+            secdebug("SecFramework", "read: %d", (int)error);
         }
         CFRelease(url);
     }
         }
         CFRelease(url);
     }
@@ -120,7 +131,7 @@ CFDataRef SecSHA1DigestCreate(CFAllocatorRef allocator,
        CFMutableDataRef digest = CFDataCreateMutable(allocator,
                CC_SHA1_DIGEST_LENGTH);
        CFDataSetLength(digest, CC_SHA1_DIGEST_LENGTH);
        CFMutableDataRef digest = CFDataCreateMutable(allocator,
                CC_SHA1_DIGEST_LENGTH);
        CFDataSetLength(digest, CC_SHA1_DIGEST_LENGTH);
-       CC_SHA1(data, length, CFDataGetMutableBytePtr(digest));
+       CC_SHA1(data, (CC_LONG)length, CFDataGetMutableBytePtr(digest));
        return digest;
 }
 
        return digest;
 }
 
@@ -172,7 +183,7 @@ static void SecDevRandomOpen(void) {
 
 int SecRandomCopyBytes(SecRandomRef rnd, size_t count, uint8_t *bytes) {
     if (rnd != kSecRandomDefault)
 
 int SecRandomCopyBytes(SecRandomRef rnd, size_t count, uint8_t *bytes) {
     if (rnd != kSecRandomDefault)
-        return paramErr;
+        return errSecParam;
     pthread_once(&kSecDevRandomOpen, SecDevRandomOpen);
     if (kSecRandomFD < 0)
         return -1;
     pthread_once(&kSecDevRandomOpen, SecDevRandomOpen);
     if (kSecRandomFD < 0)
         return -1;
index 64ea8efa62f7fece5b1163f6fbf21991c5cffdb4..2c249db7e2a869de42fd5ca45e3e0ef4d5166c6b 100644 (file)
@@ -1,15 +1,15 @@
 /*
  * Copyright (c) 2002-2010 Apple Inc. All Rights Reserved.
 /*
  * Copyright (c) 2002-2010 Apple Inc. All Rights Reserved.
- * 
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -53,15 +53,15 @@ OSStatus SecIdentityDeletePreferenceItemWithNameAndKeyUsage(
 
 
 CSSM_KEYUSE ConvertArrayToKeyUsage(CFArrayRef usage)
 
 
 CSSM_KEYUSE ConvertArrayToKeyUsage(CFArrayRef usage)
-{              
+{
        CFIndex count = 0;
        CSSM_KEYUSE result = (CSSM_KEYUSE) 0;
        CFIndex count = 0;
        CSSM_KEYUSE result = (CSSM_KEYUSE) 0;
-               
+
        if ((NULL == usage) || (0 == (count = CFArrayGetCount(usage))))
        {
                return result;
        }
        if ((NULL == usage) || (0 == (count = CFArrayGetCount(usage))))
        {
                return result;
        }
-       
+
        for (CFIndex iCnt = 0; iCnt < count; iCnt++)
        {
                CFStringRef keyUsageStr = NULL;
        for (CFIndex iCnt = 0; iCnt < count; iCnt++)
        {
                CFStringRef keyUsageStr = NULL;
@@ -116,7 +116,7 @@ SecIdentityGetTypeID(void)
 
 OSStatus
 SecIdentityCopyCertificate(
 
 OSStatus
 SecIdentityCopyCertificate(
-            SecIdentityRef identityRef, 
+            SecIdentityRef identityRef,
             SecCertificateRef *certificateRef)
 {
     BEGIN_SECAPI
             SecCertificateRef *certificateRef)
 {
     BEGIN_SECAPI
@@ -130,7 +130,7 @@ SecIdentityCopyCertificate(
 
 OSStatus
 SecIdentityCopyPrivateKey(
 
 OSStatus
 SecIdentityCopyPrivateKey(
-            SecIdentityRef identityRef, 
+            SecIdentityRef identityRef,
             SecKeyRef *privateKeyRef)
 {
     BEGIN_SECAPI
             SecKeyRef *privateKeyRef)
 {
     BEGIN_SECAPI
@@ -172,12 +172,12 @@ SecIdentityCreate(
                SecPointer<Identity> identityPtr(new Identity(keyItemPtr, certificatePtr));
                identityRef = identityPtr->handle();
 
                SecPointer<Identity> identityPtr(new Identity(keyItemPtr, certificatePtr));
                identityRef = identityPtr->handle();
 
-               __secapiresult=noErr;
+               __secapiresult=errSecSuccess;
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
-       catch (const std::bad_alloc &) { __secapiresult=memFullErr; }
-       catch (...) { __secapiresult=internalComponentErr; }
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
+       catch (...) { __secapiresult=errSecInternalComponent; }
        return identityRef;
 }
 
        return identityRef;
 }
 
@@ -212,13 +212,14 @@ SecIdentityCompare(
        END_SECAPI1(kCFCompareGreaterThan);
 }
 
        END_SECAPI1(kCFCompareGreaterThan);
 }
 
+static
 CFArrayRef _SecIdentityCopyPossiblePaths(
     CFStringRef name)
 {
     // utility function to build and return an array of possible paths for the given name.
     // if name is not a URL, this returns a single-element array.
     // if name is a URL, the array may contain 1..N elements, one for each level of the path hierarchy.
 CFArrayRef _SecIdentityCopyPossiblePaths(
     CFStringRef name)
 {
     // utility function to build and return an array of possible paths for the given name.
     // if name is not a URL, this returns a single-element array.
     // if name is a URL, the array may contain 1..N elements, one for each level of the path hierarchy.
-    
+
     CFMutableArrayRef names = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
     if (!name) {
         return names;
     CFMutableArrayRef names = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
     if (!name) {
         return names;
@@ -227,45 +228,52 @@ CFArrayRef _SecIdentityCopyPossiblePaths(
     CFArrayAppendValue(names, name);
 
     CFURLRef url = CFURLCreateWithString(NULL, name, NULL);
     CFArrayAppendValue(names, name);
 
     CFURLRef url = CFURLCreateWithString(NULL, name, NULL);
-    if (url && CFURLCanBeDecomposed(url)) {
-        // first, remove the query portion of this URL, if any
-        CFStringRef qs = CFURLCopyQueryString(url, NULL);
-        if (qs) {
-            CFMutableStringRef newName = CFStringCreateMutableCopy(NULL, oldLength, name);
-            if (newName) {
-                CFIndex qsLength = CFStringGetLength(qs) + 1; // include the '?'
-                CFStringDelete(newName, CFRangeMake(oldLength-qsLength, qsLength));
-                CFRelease(url);
-                url = CFURLCreateWithString(NULL, newName, NULL);
-                CFArraySetValueAtIndex(names, 0, newName);
-                CFRelease(newName);
-            }
-            CFRelease(qs);
-        }
-        // now add an entry for each level of the path
-        while (url) {
-            CFURLRef parent = CFURLCreateCopyDeletingLastPathComponent(NULL, url);
-            if (parent) {
-                CFStringRef parentURLString = CFURLGetString(parent);
-                if (parentURLString) {
-                    CFIndex newLength = CFStringGetLength(parentURLString);
-                    // check that string length has decreased as expected; for file URLs,
-                    // CFURLCreateCopyDeletingLastPathComponent can insert './' or '../'
-                    if ((newLength >= oldLength) || (!CFStringHasPrefix(name, parentURLString))) {
-                        CFRelease(parent);
-                        CFRelease(url);
-                        break;
-                    }
-                    oldLength = newLength;
-                    CFArrayAppendValue(names, parentURLString);
-                }
-            }
-            CFRelease(url);
-            url = parent;
-        }
-               // finally, add wildcard entries for each subdomain
-               url = CFURLCreateWithString(NULL, name, NULL);
-               if (url && CFURLCanBeDecomposed(url)) {
+    if (url) {
+               if (CFURLCanBeDecomposed(url)) {
+                       // first, remove the query portion of this URL, if any
+                       CFStringRef qs = CFURLCopyQueryString(url, NULL);
+                       if (qs) {
+                               CFMutableStringRef newName = CFStringCreateMutableCopy(NULL, oldLength, name);
+                               if (newName) {
+                                       CFIndex qsLength = CFStringGetLength(qs) + 1; // include the '?'
+                                       CFStringDelete(newName, CFRangeMake(oldLength-qsLength, qsLength));
+                                       CFRelease(url);
+                                       url = CFURLCreateWithString(NULL, newName, NULL);
+                                       CFArraySetValueAtIndex(names, 0, newName);
+                                       CFRelease(newName);
+                               }
+                               CFRelease(qs);
+                       }
+                       // now add an entry for each level of the path
+                       while (url) {
+                               CFURLRef parent = CFURLCreateCopyDeletingLastPathComponent(NULL, url);
+                               if (parent) {
+                                       CFStringRef parentURLString = CFURLGetString(parent);
+                                       if (parentURLString) {
+                                               CFIndex newLength = CFStringGetLength(parentURLString);
+                                               // check that string length has decreased as expected; for file URLs,
+                                               // CFURLCreateCopyDeletingLastPathComponent can insert './' or '../'
+                                               if ((newLength >= oldLength) || (!CFStringHasPrefix(name, parentURLString))) {
+                                                       CFRelease(parent);
+                                                       CFRelease(url);
+                                                       break;
+                                               }
+                                               oldLength = newLength;
+                                               CFArrayAppendValue(names, parentURLString);
+                                       }
+                               }
+                               CFRelease(url);
+                               url = parent;
+                       }
+               }
+               else {
+                       CFRelease(url);
+               }
+       }
+       // finally, add wildcard entries for each subdomain
+       url = CFURLCreateWithString(NULL, name, NULL);
+       if (url) {
+               if (CFURLCanBeDecomposed(url)) {
                        CFStringRef netLocString = CFURLCopyNetLocation(url);
                        if (netLocString) {
                                // first strip off port number, if present
                        CFStringRef netLocString = CFURLCopyNetLocation(url);
                        if (netLocString) {
                                // first strip off port number, if present
@@ -300,13 +308,14 @@ CFArrayRef _SecIdentityCopyPossiblePaths(
                                CFRelease(hostnameArray);
                                CFRelease(netLocString);
                        }
                                CFRelease(hostnameArray);
                                CFRelease(netLocString);
                        }
-                       CFRelease(url);
                }
                }
-    }
-    
+               CFRelease(url);
+       }
+
     return names;
 }
 
     return names;
 }
 
+static
 OSStatus _SecIdentityCopyPreferenceMatchingName(
     CFStringRef name,
     CSSM_KEYUSE keyUsage,
 OSStatus _SecIdentityCopyPreferenceMatchingName(
     CFStringRef name,
     CSSM_KEYUSE keyUsage,
@@ -349,7 +358,7 @@ OSStatus _SecIdentityCopyPreferenceMatchingName(
                CFRelease(pItemRef);
        if (status)
                return status;
                CFRelease(pItemRef);
        if (status)
                return status;
-    
+
     // filter on valid issuers, if provided
     if (validIssuers) {
         //%%%TBI
     // filter on valid issuers, if provided
     if (validIssuers) {
         //%%%TBI
@@ -377,9 +386,9 @@ SecIdentityRef SecIdentityCopyPreferred(CFStringRef name, CFArrayRef keyUsage, C
        SecIdentityRef identityRef = NULL;
        CSSM_KEYUSE keyUse = ConvertArrayToKeyUsage(keyUsage);
        OSStatus status = SecIdentityCopyPreference(name, keyUse, validIssuers, &identityRef);
        SecIdentityRef identityRef = NULL;
        CSSM_KEYUSE keyUse = ConvertArrayToKeyUsage(keyUsage);
        OSStatus status = SecIdentityCopyPreference(name, keyUse, validIssuers, &identityRef);
-       if (status != noErr && keyUse != CSSM_KEYUSE_ANY)
+       if (status != errSecSuccess && keyUse != CSSM_KEYUSE_ANY)
                status = SecIdentityCopyPreference(name, CSSM_KEYUSE_ANY, validIssuers, &identityRef);
                status = SecIdentityCopyPreference(name, CSSM_KEYUSE_ANY, validIssuers, &identityRef);
-       if (status != noErr && keyUse != 0)
+       if (status != errSecSuccess && keyUse != 0)
                status = SecIdentityCopyPreference(name, 0, validIssuers, &identityRef);
 
        return identityRef;
                status = SecIdentityCopyPreference(name, 0, validIssuers, &identityRef);
 
        return identityRef;
@@ -462,12 +471,12 @@ OSStatus SecIdentityCopyPreference(
                 syslog(LOG_NOTICE, "lookup complete; will use: \"%s\" for \"%s\"\n", labelBuf, nameBuf);
                 free(nameBuf);
             }
                 syslog(LOG_NOTICE, "lookup complete; will use: \"%s\" for \"%s\"\n", labelBuf, nameBuf);
                 free(nameBuf);
             }
-            
+
             free(labelBuf);
             free(serviceBuf);
         }
 
             free(labelBuf);
             free(serviceBuf);
         }
 
-        if (status == noErr) {
+        if (status == errSecSuccess) {
             break; // match found
         }
     }
             break; // match found
         }
     }
@@ -484,7 +493,7 @@ OSStatus SecIdentitySetPreference(
     CSSM_KEYUSE keyUsage)
 {
        if (!name) {
     CSSM_KEYUSE keyUsage)
 {
        if (!name) {
-               return paramErr;
+               return errSecParam;
        }
        if (!identity) {
                // treat NULL identity as a request to clear the preference
        }
        if (!identity) {
                // treat NULL identity as a request to clear the preference
@@ -551,7 +560,7 @@ OSStatus SecIdentitySetPreference(
     item->setAttribute(Schema::attributeInfo(kSecAccountItemAttr), account);
        item->setAttribute(Schema::attributeInfo(kSecScriptCodeItemAttr), (sint32)keyUsage);
     item->setAttribute(Schema::attributeInfo(kSecLabelItemAttr), service);
     item->setAttribute(Schema::attributeInfo(kSecAccountItemAttr), account);
        item->setAttribute(Schema::attributeInfo(kSecScriptCodeItemAttr), (sint32)keyUsage);
     item->setAttribute(Schema::attributeInfo(kSecLabelItemAttr), service);
-    
+
        // generic attribute (store persistent certificate reference)
        CFDataRef pItemRef = nil;
     certificate->copyPersistentReference(pItemRef);
        // generic attribute (store persistent certificate reference)
        CFDataRef pItemRef = nil;
     certificate->copyPersistentReference(pItemRef);
@@ -588,7 +597,7 @@ OSStatus SecIdentitySetPreference(
     END_SECAPI
 }
 
     END_SECAPI
 }
 
-OSStatus 
+OSStatus
 SecIdentitySetPreferred(SecIdentityRef identity, CFStringRef name, CFArrayRef keyUsage)
 {
        CSSM_KEYUSE keyUse = ConvertArrayToKeyUsage(keyUsage);
 SecIdentitySetPreferred(SecIdentityRef identity, CFStringRef name, CFArrayRef keyUsage)
 {
        CSSM_KEYUSE keyUse = ConvertArrayToKeyUsage(keyUsage);
@@ -616,7 +625,7 @@ SecIdentityFindPreferenceItem(
        }
     size_t idUTF8Len = strlen(idUTF8);
     if (!idUTF8Len)
        }
     size_t idUTF8Len = strlen(idUTF8);
     if (!idUTF8Len)
-        MacOSError::throwMe(paramErr);
+        MacOSError::throwMe(errSecParam);
 
     CssmData service(const_cast<char *>(idUTF8), idUTF8Len);
     cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecServiceItemAttr), service);
 
     CssmData service(const_cast<char *>(idUTF8), idUTF8Len);
     cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecServiceItemAttr), service);
@@ -654,7 +663,7 @@ SecIdentityFindPreferenceItemWithNameAndKeyUsage(
        }
     size_t idUTF8Len = strlen(idUTF8);
     if (!idUTF8Len)
        }
     size_t idUTF8Len = strlen(idUTF8);
     if (!idUTF8Len)
-        MacOSError::throwMe(paramErr);
+        MacOSError::throwMe(errSecParam);
 
     CssmData service(const_cast<char *>(idUTF8), idUTF8Len);
     cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecServiceItemAttr), service);
 
     CssmData service(const_cast<char *>(idUTF8), idUTF8Len);
     cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecServiceItemAttr), service);
@@ -682,22 +691,23 @@ OSStatus SecIdentityDeletePreferenceItemWithNameAndKeyUsage(
        // maxUsages represents the most matches there could theoretically be, so
        // cut things off at that point if we're still finding items (if they can't
        // be deleted for some reason, we'd never break out of the loop.)
        // maxUsages represents the most matches there could theoretically be, so
        // cut things off at that point if we're still finding items (if they can't
        // be deleted for some reason, we'd never break out of the loop.)
-       
+
        OSStatus status;
        SecKeychainItemRef item = NULL;
        int count = 0, maxUsages = 12;
        while (++count <= maxUsages &&
        OSStatus status;
        SecKeychainItemRef item = NULL;
        int count = 0, maxUsages = 12;
        while (++count <= maxUsages &&
-                       (status = SecIdentityFindPreferenceItemWithNameAndKeyUsage(keychainOrArray, name, keyUsage, &item)) == noErr) {
+                       (status = SecIdentityFindPreferenceItemWithNameAndKeyUsage(keychainOrArray, name, keyUsage, &item)) == errSecSuccess) {
                status = SecKeychainItemDelete(item);
                CFRelease(item);
                item = NULL;
        }
                status = SecKeychainItemDelete(item);
                CFRelease(item);
                item = NULL;
        }
-       
+
        // it's not an error if the item isn't found
        // it's not an error if the item isn't found
-       return (status == errSecItemNotFound) ? noErr : status;
+       return (status == errSecItemNotFound) ? errSecSuccess : status;
 }
 
 
 }
 
 
+static
 OSStatus _SecIdentityAddPreferenceItemWithName(
        SecKeychainRef keychainRef,
        SecIdentityRef identityRef,
 OSStatus _SecIdentityAddPreferenceItemWithName(
        SecKeychainRef keychainRef,
        SecIdentityRef identityRef,
@@ -708,7 +718,7 @@ OSStatus _SecIdentityAddPreferenceItemWithName(
     // caller must handle exceptions
 
        if (!identityRef || !idString)
     // caller must handle exceptions
 
        if (!identityRef || !idString)
-               return paramErr;
+               return errSecParam;
        SecPointer<Certificate> cert(Identity::required(identityRef)->certificate());
        Item item(kSecGenericPasswordItemClass, 'aapl', 0, NULL, false);
        sint32 keyUsage = 0;
        SecPointer<Certificate> cert(Identity::required(identityRef)->certificate());
        Item item(kSecGenericPasswordItemClass, 'aapl', 0, NULL, false);
        sint32 keyUsage = 0;
@@ -776,7 +786,7 @@ OSStatus _SecIdentityAddPreferenceItemWithName(
     catch(...) {
         keychain = globals().storageManager.defaultKeychainUI(item);
     }
     catch(...) {
         keychain = globals().storageManager.defaultKeychainUI(item);
     }
-       
+
        try {
                keychain->add(item);
        }
        try {
                keychain->add(item);
        }
@@ -807,7 +817,7 @@ OSStatus SecIdentityAddPreferenceItem(
 
     BEGIN_SECAPI
 
 
     BEGIN_SECAPI
 
-    OSStatus status = internalComponentErr;
+    OSStatus status = errSecInternalComponent;
     CFArrayRef names = _SecIdentityCopyPossiblePaths(idString);
     if (!names) {
         return status;
     CFArrayRef names = _SecIdentityCopyPossiblePaths(idString);
     if (!names) {
         return status;
@@ -822,8 +832,8 @@ OSStatus SecIdentityAddPreferenceItem(
         }
         catch (const MacOSError &err)   { status=err.osStatus(); }
         catch (const CommonError &err)  { status=SecKeychainErrFromOSStatus(err.osStatus()); }
         }
         catch (const MacOSError &err)   { status=err.osStatus(); }
         catch (const CommonError &err)  { status=SecKeychainErrFromOSStatus(err.osStatus()); }
-        catch (const std::bad_alloc &)  { status=memFullErr; }
-        catch (...)                     { status=internalComponentErr; }
+        catch (const std::bad_alloc &)  { status=errSecAllocate; }
+        catch (...)                     { status=errSecInternalComponent; }
     }
     if (total > 2) {
                Boolean setDomainDefaultIdentity = FALSE;
     }
     if (total > 2) {
                Boolean setDomainDefaultIdentity = FALSE;
@@ -838,15 +848,15 @@ OSStatus SecIdentityAddPreferenceItem(
                }
                if (setDomainDefaultIdentity) {
                        // add item for domain (second-to-last element in array, e.g. "*.apple.com")
                }
                if (setDomainDefaultIdentity) {
                        // add item for domain (second-to-last element in array, e.g. "*.apple.com")
-                       OSStatus tmpStatus = noErr;
+                       OSStatus tmpStatus = errSecSuccess;
                        CFStringRef aName = (CFStringRef)CFArrayGetValueAtIndex(names, total-2);
                        try {
                                tmpStatus = _SecIdentityAddPreferenceItemWithName(keychainRef, identityRef, aName, itemRef);
                        }
                        catch (const MacOSError &err)   { tmpStatus=err.osStatus(); }
                        catch (const CommonError &err)  { tmpStatus=SecKeychainErrFromOSStatus(err.osStatus()); }
                        CFStringRef aName = (CFStringRef)CFArrayGetValueAtIndex(names, total-2);
                        try {
                                tmpStatus = _SecIdentityAddPreferenceItemWithName(keychainRef, identityRef, aName, itemRef);
                        }
                        catch (const MacOSError &err)   { tmpStatus=err.osStatus(); }
                        catch (const CommonError &err)  { tmpStatus=SecKeychainErrFromOSStatus(err.osStatus()); }
-                       catch (const std::bad_alloc &)  { tmpStatus=memFullErr; }
-                       catch (...)                     { tmpStatus=internalComponentErr; }
+                       catch (const std::bad_alloc &)  { tmpStatus=errSecAllocate; }
+                       catch (...)                     { tmpStatus=errSecInternalComponent; }
                }
     }
 
                }
     }
 
@@ -864,7 +874,7 @@ OSStatus SecIdentityUpdatePreferenceItem(
     BEGIN_SECAPI
 
        if (!itemRef || !identityRef)
     BEGIN_SECAPI
 
        if (!itemRef || !identityRef)
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
        SecPointer<Certificate> certificate(Identity::required(identityRef)->certificate());
        Item prefItem = ItemImpl::required(itemRef);
 
        SecPointer<Certificate> certificate(Identity::required(identityRef)->certificate());
        Item prefItem = ItemImpl::required(itemRef);
 
@@ -932,7 +942,7 @@ OSStatus SecIdentityCopyFromPreferenceItem(
     BEGIN_SECAPI
 
        if (!itemRef || !identityRef)
     BEGIN_SECAPI
 
        if (!itemRef || !identityRef)
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
        Item prefItem = ItemImpl::required(itemRef);
 
        // get persistent certificate reference
        Item prefItem = ItemImpl::required(itemRef);
 
        // get persistent certificate reference
@@ -971,7 +981,7 @@ OSStatus SecIdentityCopyFromPreferenceItem(
 /* plist domain (in /Library/Preferences) */
 #define IDENTITY_DOMAIN                "com.apple.security.systemidentities"
 
 /* plist domain (in /Library/Preferences) */
 #define IDENTITY_DOMAIN                "com.apple.security.systemidentities"
 
-/* 
+/*
  * Our plist is a dictionary whose entries have the following format:
  * key   = domain name as CFString
  * value = public key hash as CFData
  * Our plist is a dictionary whose entries have the following format:
  * key   = domain name as CFString
  * value = public key hash as CFData
@@ -979,14 +989,14 @@ OSStatus SecIdentityCopyFromPreferenceItem(
 
 #define SYSTEM_KEYCHAIN_PATH   kSystemKeychainDir "/" kSystemKeychainName
 
 
 #define SYSTEM_KEYCHAIN_PATH   kSystemKeychainDir "/" kSystemKeychainName
 
-/* 
+/*
  * All accesses to system identities and its associated plist are
  * protected by this lock.
  */
 ModuleNexus<Mutex> systemIdentityLock;
 
 OSStatus SecIdentityCopySystemIdentity(
  * All accesses to system identities and its associated plist are
  * protected by this lock.
  */
 ModuleNexus<Mutex> systemIdentityLock;
 
 OSStatus SecIdentityCopySystemIdentity(
-   CFStringRef domain,          
+   CFStringRef domain,
    SecIdentityRef *idRef,
    CFStringRef *actualDomain) /* optional */
 {
    SecIdentityRef *idRef,
    CFStringRef *actualDomain) /* optional */
 {
@@ -994,16 +1004,16 @@ OSStatus SecIdentityCopySystemIdentity(
 
        StLock<Mutex> _(systemIdentityLock());
        auto_ptr<Dictionary> identDict;
 
        StLock<Mutex> _(systemIdentityLock());
        auto_ptr<Dictionary> identDict;
-       
+
        /* get top-level dictionary - if not present, we're done */
        Dictionary* d = Dictionary::CreateDictionary(IDENTITY_DOMAIN, Dictionary::US_System);
        if (d == NULL)
        {
                return errSecNotAvailable;
        }
        /* get top-level dictionary - if not present, we're done */
        Dictionary* d = Dictionary::CreateDictionary(IDENTITY_DOMAIN, Dictionary::US_System);
        if (d == NULL)
        {
                return errSecNotAvailable;
        }
-       
+
        identDict.reset(d);
        identDict.reset(d);
-       
+
        /* see if there's an entry for specified domain */
        CFDataRef entryValue = identDict->getDataValue(domain);
        if(entryValue == NULL) {
        /* see if there's an entry for specified domain */
        CFDataRef entryValue = identDict->getDataValue(domain);
        if(entryValue == NULL) {
@@ -1015,22 +1025,22 @@ OSStatus SecIdentityCopySystemIdentity(
                        /* no default identity */
                        MacOSError::throwMe(errSecItemNotFound);
                }
                        /* no default identity */
                        MacOSError::throwMe(errSecItemNotFound);
                }
-               
+
                /* remember that we're not fetching the requested domain */
                domain = kSecIdentityDomainDefault;
        }
                /* remember that we're not fetching the requested domain */
                domain = kSecIdentityDomainDefault;
        }
-       
+
        /* open system keychain - error here is fatal */
        Keychain systemKc = globals().storageManager.make(SYSTEM_KEYCHAIN_PATH, false);
        CFRef<SecKeychainRef> systemKcRef(systemKc->handle());
        StorageManager::KeychainList keychains;
        globals().storageManager.optionalSearchList(systemKcRef, keychains);
        /* open system keychain - error here is fatal */
        Keychain systemKc = globals().storageManager.make(SYSTEM_KEYCHAIN_PATH, false);
        CFRef<SecKeychainRef> systemKcRef(systemKc->handle());
        StorageManager::KeychainList keychains;
        globals().storageManager.optionalSearchList(systemKcRef, keychains);
-       
+
        /* search for specified cert */
        SecKeychainAttributeList        attrList;
        SecKeychainAttribute            attr;
        attr.tag        = kSecPublicKeyHashItemAttr;
        /* search for specified cert */
        SecKeychainAttributeList        attrList;
        SecKeychainAttribute            attr;
        attr.tag        = kSecPublicKeyHashItemAttr;
-       attr.length     = CFDataGetLength(entryValue);
+       attr.length     = (UInt32)CFDataGetLength(entryValue);
        attr.data       = (void *)CFDataGetBytePtr(entryValue);
        attrList.count  = 1;
        attrList.attr   = &attr;
        attr.data       = (void *)CFDataGetBytePtr(entryValue);
        attrList.count  = 1;
        attrList.attr   = &attr;
@@ -1040,7 +1050,7 @@ OSStatus SecIdentityCopySystemIdentity(
        if(!cursor->next(certItem)) {
                MacOSError::throwMe(errSecItemNotFound);
        }
        if(!cursor->next(certItem)) {
                MacOSError::throwMe(errSecItemNotFound);
        }
-       
+
        /* found the cert; try matching with key to cook up identity */
        SecPointer<Certificate> certificate(static_cast<Certificate *>(certItem.get()));
        SecPointer<Identity> identity(new Identity(keychains, certificate));
        /* found the cert; try matching with key to cook up identity */
        SecPointer<Certificate> certificate(static_cast<Certificate *>(certItem.get()));
        SecPointer<Identity> identity(new Identity(keychains, certificate));
@@ -1055,7 +1065,7 @@ OSStatus SecIdentityCopySystemIdentity(
 }
 
 OSStatus SecIdentitySetSystemIdentity(
 }
 
 OSStatus SecIdentitySetSystemIdentity(
-   CFStringRef domain,     
+   CFStringRef domain,
    SecIdentityRef idRef)
 {
     BEGIN_SECAPI
    SecIdentityRef idRef)
 {
     BEGIN_SECAPI
@@ -1064,7 +1074,7 @@ OSStatus SecIdentitySetSystemIdentity(
        if(geteuid() != 0) {
                MacOSError::throwMe(errSecAuthFailed);
        }
        if(geteuid() != 0) {
                MacOSError::throwMe(errSecAuthFailed);
        }
-       
+
        auto_ptr<MutableDictionary> identDict;
        MutableDictionary *d = MutableDictionary::CreateMutableDictionary(IDENTITY_DOMAIN, Dictionary::US_System);
        if (d)
        auto_ptr<MutableDictionary> identDict;
        MutableDictionary *d = MutableDictionary::CreateMutableDictionary(IDENTITY_DOMAIN, Dictionary::US_System);
        if (d)
@@ -1075,11 +1085,11 @@ OSStatus SecIdentitySetSystemIdentity(
        {
                if(idRef == NULL) {
                        /* nothing there, nothing to set - done */
        {
                if(idRef == NULL) {
                        /* nothing there, nothing to set - done */
-                       return noErr;
+                       return errSecSuccess;
                }
                identDict.reset(new MutableDictionary());
        }
                }
                identDict.reset(new MutableDictionary());
        }
-       
+
        if(idRef == NULL) {
                /* Just delete the possible entry for this domain */
                identDict->removeValue(domain);
        if(idRef == NULL) {
                /* Just delete the possible entry for this domain */
                identDict->removeValue(domain);
@@ -1089,16 +1099,16 @@ OSStatus SecIdentitySetSystemIdentity(
                SecPointer<Identity> identity(Identity::required(idRef));
                SecPointer<Certificate> cert = identity->certificate();
                const CssmData &pubKeyHash = cert->publicKeyHash();
                SecPointer<Identity> identity(Identity::required(idRef));
                SecPointer<Certificate> cert = identity->certificate();
                const CssmData &pubKeyHash = cert->publicKeyHash();
-               CFRef<CFDataRef> pubKeyHashData(CFDataCreate(NULL, pubKeyHash.Data, 
+               CFRef<CFDataRef> pubKeyHashData(CFDataCreate(NULL, pubKeyHash.Data,
                        pubKeyHash.Length));
                        pubKeyHash.Length));
-               
+
                /* add/replace to dictionary */
                identDict->setValue(domain, pubKeyHashData);
        }
                /* add/replace to dictionary */
                identDict->setValue(domain, pubKeyHashData);
        }
-       
+
        /* flush to disk */
        if(!identDict->writePlistToPrefs(IDENTITY_DOMAIN, Dictionary::US_System)) {
        /* flush to disk */
        if(!identDict->writePlistToPrefs(IDENTITY_DOMAIN, Dictionary::US_System)) {
-               MacOSError::throwMe(ioErr);
+               MacOSError::throwMe(errSecIO);
        }
 
     END_SECAPI
        }
 
     END_SECAPI
index 23a1f9d95092395d93c62f48c254e4b6c5b8ee99..df3fa5f4a9f715e193ef7602f841c0b12bc25550 100644 (file)
@@ -1,15 +1,15 @@
 /*
  * Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
 /*
  * Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
- * 
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  *
  * @APPLE_LICENSE_HEADER_END@
  *
- * SecImport.cpp - high-level facility for importing Sec layer objects. 
+ * SecImport.cpp - high-level facility for importing Sec layer objects.
  */
 
 #include "SecImportExport.h"
  */
 
 #include "SecImportExport.h"
@@ -29,8 +29,7 @@
 #include "SecImportExportUtils.h"
 #include <security_cdsa_utils/cuCdsaUtils.h>
 #include <security_utilities/globalizer.h>
 #include "SecImportExportUtils.h"
 #include <security_cdsa_utils/cuCdsaUtils.h>
 #include <security_utilities/globalizer.h>
-
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+#include <Security/SecBase.h>
 
 #define SecImpInferDbg(args...)        secdebug("SecImpInfer", ## args)
 
 
 #define SecImpInferDbg(args...)        secdebug("SecImpInfer", ## args)
 
@@ -40,11 +39,11 @@ using namespace KeychainCore;
 /*
  * Do our best to ensure that a SecImportRep's type and format are known.
  * A return of true means that both format and type (and, if the item
 /*
  * Do our best to ensure that a SecImportRep's type and format are known.
  * A return of true means that both format and type (and, if the item
- * is a raw public or private key, the algorithm) are known. 
+ * is a raw public or private key, the algorithm) are known.
  */
 static bool impExpInferTypeAndFormat(
        SecImportRep            *rep,
  */
 static bool impExpInferTypeAndFormat(
        SecImportRep            *rep,
-       CFStringRef                     fileStr,        
+       CFStringRef                     fileStr,
        SecExternalFormat   inputFormat,
        SecExternalItemType     itemType)
 {
        SecExternalFormat   inputFormat,
        SecExternalItemType     itemType)
 {
@@ -71,7 +70,7 @@ static bool impExpInferTypeAndFormat(
                        case kSecFormatUnknown:
                                break;
                        case kSecFormatPKCS7:
                        case kSecFormatUnknown:
                                break;
                        case kSecFormatPKCS7:
-                       case kSecFormatPKCS12:          
+                       case kSecFormatPKCS12:
                        case kSecFormatPEMSequence:
                        case kSecFormatNetscapeCertSequence:
                                rep->mExternType = kSecItemTypeAggregate;
                        case kSecFormatPEMSequence:
                        case kSecFormatNetscapeCertSequence:
                                rep->mExternType = kSecItemTypeAggregate;
@@ -79,7 +78,7 @@ static bool impExpInferTypeAndFormat(
                        case kSecFormatRawKey:
                                rep->mExternType = kSecItemTypeSessionKey;
                                break;
                        case kSecFormatRawKey:
                                rep->mExternType = kSecItemTypeSessionKey;
                                break;
-                       case kSecFormatX509Cert:        
+                       case kSecFormatX509Cert:
                                rep->mExternType = kSecItemTypeCertificate;
                                break;
                        case kSecFormatWrappedPKCS8:
                                rep->mExternType = kSecItemTypeCertificate;
                                break;
                        case kSecFormatWrappedPKCS8:
@@ -98,7 +97,7 @@ static bool impExpInferTypeAndFormat(
                                break;
                }
        }
                                break;
                }
        }
-          
+
        /* some formats can be inferred from type */
        if(rep->mExternFormat == kSecFormatUnknown) {
                SecExternalItemType thisType;
        /* some formats can be inferred from type */
        if(rep->mExternFormat == kSecFormatUnknown) {
                SecExternalItemType thisType;
@@ -119,9 +118,9 @@ static bool impExpInferTypeAndFormat(
                                break;
                }
        }
                                break;
                }
        }
-       
-       /* 
-        * Wrapped private keys don't need algorithm 
+
+       /*
+        * Wrapped private keys don't need algorithm
         * Some formats implies algorithm
         */
        bool isWrapped = false;
         * Some formats implies algorithm
         */
        bool isWrapped = false;
@@ -141,7 +140,7 @@ static bool impExpInferTypeAndFormat(
                default:
                        break;
        }
                default:
                        break;
        }
-       
+
        /* Are we there yet? */
        bool done = true;
        if((rep->mExternType   == kSecItemTypeUnknown) ||
        /* Are we there yet? */
        bool done = true;
        if((rep->mExternType   == kSecItemTypeUnknown) ||
@@ -163,7 +162,7 @@ static bool impExpInferTypeAndFormat(
        }
        if(!done) {
                /* infer from filename if possible */
        }
        if(!done) {
                /* infer from filename if possible */
-               done = impExpImportParseFileExten(fileStr, &rep->mExternFormat, 
+               done = impExpImportParseFileExten(fileStr, &rep->mExternFormat,
                        &rep->mExternType);
        }
        if(done) {
                        &rep->mExternType);
        }
        if(done) {
@@ -172,13 +171,14 @@ static bool impExpInferTypeAndFormat(
 
        /* invoke black magic: try decoding various forms */
        return impExpImportGuessByExamination(rep->mExternal, &rep->mExternFormat,
 
        /* invoke black magic: try decoding various forms */
        return impExpImportGuessByExamination(rep->mExternal, &rep->mExternFormat,
-               &rep->mExternType, &rep->mKeyAlg);      
+               &rep->mExternType, &rep->mKeyAlg);
 }
 }
-       
+
 class CSPDLMaker
 {
 protected:
        CSSM_CSP_HANDLE mHandle;
 class CSPDLMaker
 {
 protected:
        CSSM_CSP_HANDLE mHandle;
+    RecursiveMutex mMutex;
 
 public:
        CSPDLMaker() : mHandle(cuCspStartup(CSSM_FALSE)) {}
 
 public:
        CSPDLMaker() : mHandle(cuCspStartup(CSSM_FALSE)) {}
@@ -192,28 +192,28 @@ OSStatus SecKeychainItemImport(
        CFStringRef                                                     fileNameOrExtension,    // optional
        SecExternalFormat                                       *inputFormat,                   // optional, IN/OUT
        SecExternalItemType                                     *itemType,                              // optional, IN/OUT
        CFStringRef                                                     fileNameOrExtension,    // optional
        SecExternalFormat                                       *inputFormat,                   // optional, IN/OUT
        SecExternalItemType                                     *itemType,                              // optional, IN/OUT
-       SecItemImportExportFlags                        flags, 
+       SecItemImportExportFlags                        flags,
        const SecKeyImportExportParameters  *keyParams,                         // optional
        SecKeychainRef                                          importKeychain,                 // optional
        CFArrayRef                                                      *outItems)                              /* optional */
 {
        BEGIN_IMP_EXP_SECAPI
        const SecKeyImportExportParameters  *keyParams,                         // optional
        SecKeychainRef                                          importKeychain,                 // optional
        CFArrayRef                                                      *outItems)                              /* optional */
 {
        BEGIN_IMP_EXP_SECAPI
-       
+
        bool                            isPem;
        bool                            isPem;
-       OSStatus                        ortn = noErr;
-       OSStatus                        pem_ortn = noErr;
+       OSStatus                        ortn = errSecSuccess;
+       OSStatus                        pem_ortn = errSecSuccess;
        SecImportRep            *rep = NULL;
        SecExternalFormat   callerInputFormat;
        SecExternalItemType callerItemType;
        CSSM_CSP_HANDLE         cspHand = 0;
        CFIndex                         dex;
        CFStringRef                     ourFileStr = NULL;
        SecImportRep            *rep = NULL;
        SecExternalFormat   callerInputFormat;
        SecExternalItemType callerItemType;
        CSSM_CSP_HANDLE         cspHand = 0;
        CFIndex                         dex;
        CFStringRef                     ourFileStr = NULL;
-       
+
        if((importedData == NULL) || (CFDataGetLength(importedData) == 0)) {
        if((importedData == NULL) || (CFDataGetLength(importedData) == 0)) {
-               return paramErr;
+               return errSecParam;
        }
        /* all other args are optional */
        }
        /* all other args are optional */
-       
+
        if(inputFormat) {
                callerInputFormat = *inputFormat;
        }
        if(inputFormat) {
                callerInputFormat = *inputFormat;
        }
@@ -226,18 +226,18 @@ OSStatus SecKeychainItemImport(
        else {
                callerItemType = kSecItemTypeUnknown;
        }
        else {
                callerItemType = kSecItemTypeUnknown;
        }
-       
+
        CFIndex numReps = 0;
        SecExternalFormat tempFormat = callerInputFormat;
        SecExternalItemType tempType = callerItemType;
        ImpPrivKeyImportState keyImportState = PIS_NoLimit;
 
        CFMutableArrayRef importReps = CFArrayCreateMutable(NULL, 0, NULL);
        CFIndex numReps = 0;
        SecExternalFormat tempFormat = callerInputFormat;
        SecExternalItemType tempType = callerItemType;
        ImpPrivKeyImportState keyImportState = PIS_NoLimit;
 
        CFMutableArrayRef importReps = CFArrayCreateMutable(NULL, 0, NULL);
-       CFMutableArrayRef createdKcItems = CFArrayCreateMutable(NULL, 0, 
+       CFMutableArrayRef createdKcItems = CFArrayCreateMutable(NULL, 0,
                &kCFTypeArrayCallBacks);
        /* subsequent errors to errOut: */
                &kCFTypeArrayCallBacks);
        /* subsequent errors to errOut: */
-       
-       /* 
+
+       /*
         * importedData --> one or more SecImportReps.
         * Note successful PEM decode can override caller's inputFormat and/or itemType.
         */
         * importedData --> one or more SecImportReps.
         * Note successful PEM decode can override caller's inputFormat and/or itemType.
         */
@@ -254,9 +254,9 @@ OSStatus SecKeychainItemImport(
                }
        }
        else {
                }
        }
        else {
-               /* 
-                * Strip off possible .pem extension in case there's another one in 
-                * front of it 
+               /*
+                * Strip off possible .pem extension in case there's another one in
+                * front of it
                 */
                assert(CFArrayGetCount(importReps) >= 1);
                if(fileNameOrExtension) {
                 */
                assert(CFArrayGetCount(importReps) >= 1);
                if(fileNameOrExtension) {
@@ -269,13 +269,13 @@ OSStatus SecKeychainItemImport(
                        }
                }
        }
                        }
                }
        }
-       
-       /* 
-        * Ensure we know type and format (and, for raw keys, algorithm) of each item. 
+
+       /*
+        * Ensure we know type and format (and, for raw keys, algorithm) of each item.
         */
         */
-       numReps = CFArrayGetCount(importReps);  
+       numReps = CFArrayGetCount(importReps);
        if(numReps > 1) {
        if(numReps > 1) {
-               /* 
+               /*
                 * Incoming kSecFormatPEMSequence, caller specs are useless now.
                 * Hopefully the PEM parsing disclosed the info we'll need.
                 */
                 * Incoming kSecFormatPEMSequence, caller specs are useless now.
                 * Hopefully the PEM parsing disclosed the info we'll need.
                 */
@@ -305,15 +305,15 @@ OSStatus SecKeychainItemImport(
        else {
                cspHand = gCSPHandle();
        }
        else {
                cspHand = gCSPHandle();
        }
-       
+
        if(keyParams && (keyParams->flags & kSecKeyImportOnlyOne)) {
                keyImportState = PIS_AllowOne;
        }
        if(keyParams && (keyParams->flags & kSecKeyImportOnlyOne)) {
                keyImportState = PIS_AllowOne;
        }
-       
-       /* Everything looks good: Go */ 
+
+       /* Everything looks good: Go */
        for(CFIndex dex=0; dex<numReps; dex++) {
                rep = (SecImportRep *)CFArrayGetValueAtIndex(importReps, dex);
        for(CFIndex dex=0; dex<numReps; dex++) {
                rep = (SecImportRep *)CFArrayGetValueAtIndex(importReps, dex);
-               ortn = rep->importRep(importKeychain, cspHand, flags, keyParams, 
+               ortn = rep->importRep(importKeychain, cspHand, flags, keyParams,
                        keyImportState, createdKcItems);
                if(ortn) {
                        goto errOut;
                        keyImportState, createdKcItems);
                if(ortn) {
                        goto errOut;
@@ -345,7 +345,7 @@ OSStatus SecKeychainItemImport(
                        *itemType = rep->mExternType;
                }
        }
                        *itemType = rep->mExternType;
                }
        }
-       if((ortn == noErr) && (outItems != NULL)) {
+       if((ortn == errSecSuccess) && (outItems != NULL)) {
                /* return the array */
                *outItems = createdKcItems;
                createdKcItems = NULL;
                /* return the array */
                *outItems = createdKcItems;
                createdKcItems = NULL;
@@ -376,8 +376,8 @@ errOut:
                /* error occurred importing as PEM, and no other rep was imported */
                return SecKeychainErrFromOSStatus(pem_ortn);
        }
                /* error occurred importing as PEM, and no other rep was imported */
                return SecKeychainErrFromOSStatus(pem_ortn);
        }
-       return noErr;
-       
+       return errSecSuccess;
+
        END_IMP_EXP_SECAPI
 }
 
        END_IMP_EXP_SECAPI
 }
 
@@ -386,17 +386,17 @@ OSStatus SecItemImport(
        CFStringRef                                                     fileNameOrExtension,    /* optional */
        SecExternalFormat                                       *inputFormat,                   /* optional, IN/OUT */
        SecExternalItemType                                     *itemType,                              /* optional, IN/OUT */
        CFStringRef                                                     fileNameOrExtension,    /* optional */
        SecExternalFormat                                       *inputFormat,                   /* optional, IN/OUT */
        SecExternalItemType                                     *itemType,                              /* optional, IN/OUT */
-       SecItemImportExportFlags                        flags, 
+       SecItemImportExportFlags                        flags,
        const SecItemImportExportKeyParameters  *keyParams,                             /* optional */
        SecKeychainRef                                          importKeychain,                 /* optional */
        CFArrayRef                                                      *outItems)
 {
        const SecItemImportExportKeyParameters  *keyParams,                             /* optional */
        SecKeychainRef                                          importKeychain,                 /* optional */
        CFArrayRef                                                      *outItems)
 {
-       
+
        SecKeyImportExportParameters* oldStructPtr = NULL;
        SecKeyImportExportParameters oldStruct;
        memset(&oldStruct, 0, sizeof(oldStruct));
        SecKeyImportExportParameters* oldStructPtr = NULL;
        SecKeyImportExportParameters oldStruct;
        memset(&oldStruct, 0, sizeof(oldStruct));
-       
-       
+
+
        if (NULL != keyParams)
        {
                if (ConvertSecKeyImportExportParametersToSecImportExportKeyParameters(NULL,
        if (NULL != keyParams)
        {
                if (ConvertSecKeyImportExportParametersToSecImportExportKeyParameters(NULL,
@@ -405,8 +405,8 @@ OSStatus SecItemImport(
                        oldStructPtr = &oldStruct;
                }
        }
                        oldStructPtr = &oldStruct;
                }
        }
-       
-       return SecKeychainItemImport(importedData, fileNameOrExtension, inputFormat, 
+
+       return SecKeychainItemImport(importedData, fileNameOrExtension, inputFormat,
                itemType, flags, oldStructPtr, importKeychain, outItems);
 }
 
                itemType, flags, oldStructPtr, importKeychain, outItems);
 }
 
index ed7a949fddcd81eda166198188ff13ba76d53a9e..705632236ecd9f6d3bc96a46b0c116e28a04ee3c 100644 (file)
@@ -1,15 +1,15 @@
 /*
  * Copyright (c) 2007-2010 Apple Inc. All Rights Reserved.
 /*
  * Copyright (c) 2007-2010 Apple Inc. All Rights Reserved.
- * 
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -56,7 +56,7 @@ static void collect_certs(const void *key, const void *value, void *context)
         CFDataRef cert_bytes = CFDictionaryGetValue(value, CFSTR("cert"));
         if (!cert_bytes)
             return;
         CFDataRef cert_bytes = CFDictionaryGetValue(value, CFSTR("cert"));
         if (!cert_bytes)
             return;
-        SecCertificateRef cert = 
+        SecCertificateRef cert =
             SecCertificateCreateWithData(kCFAllocatorDefault, cert_bytes);
         if (!cert)
             return;
             SecCertificateCreateWithData(kCFAllocatorDefault, cert_bytes);
         if (!cert)
             return;
@@ -71,10 +71,10 @@ typedef struct {
     CFArrayRef certs;
 } build_trust_chains_context;
 
     CFArrayRef certs;
 } build_trust_chains_context;
 
-static void build_trust_chains(const void *key, const void *value, 
+static void build_trust_chains(const void *key, const void *value,
     void *context)
 {
     void *context)
 {
-    CFMutableDictionaryRef identity_dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 
+    CFMutableDictionaryRef identity_dict = CFDictionaryCreateMutable(kCFAllocatorDefault,
         0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
     SecKeyRef private_key = NULL;
     SecCertificateRef cert = NULL;
         0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
     SecKeyRef private_key = NULL;
     SecCertificateRef cert = NULL;
@@ -92,7 +92,7 @@ static void build_trust_chains(const void *key, const void *value,
     /* p12import only passes up rsa keys */
 //FIXME: needs SecKeyCreateRSAPrivateKey implementation
 //#if 0
     /* p12import only passes up rsa keys */
 //FIXME: needs SecKeyCreateRSAPrivateKey implementation
 //#if 0
-//     private_key = SecKeyCreateRSAPrivateKey(kCFAllocatorDefault, 
+//     private_key = SecKeyCreateRSAPrivateKey(kCFAllocatorDefault,
 //        CFDataGetBytePtr(key_bytes), CFDataGetLength(key_bytes),
 //        kSecKeyEncodingPkcs1);
 //#endif
 //        CFDataGetBytePtr(key_bytes), CFDataGetLength(key_bytes),
 //        kSecKeyEncodingPkcs1);
 //#endif
@@ -102,7 +102,7 @@ static void build_trust_chains(const void *key, const void *value,
     identity = SecIdentityCreate(kCFAllocatorDefault, cert, private_key);
        if(!identity) goto out; //require(identity, out);
     CFDictionarySetValue(identity_dict, kSecImportItemIdentity, identity);
     identity = SecIdentityCreate(kCFAllocatorDefault, cert, private_key);
        if(!identity) goto out; //require(identity, out);
     CFDictionarySetValue(identity_dict, kSecImportItemIdentity, identity);
-    
+
     eval_chain = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
        if(!eval_chain) goto out; //require(eval_chain, out);
     CFArrayAppendValue(eval_chain, cert);
     eval_chain = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
        if(!eval_chain) goto out; //require(eval_chain, out);
     CFArrayAppendValue(eval_chain, cert);
@@ -115,7 +115,7 @@ static void build_trust_chains(const void *key, const void *value,
        if(!trust) goto out; //require(trust, out);
     SecTrustEvaluate(trust, &result);
     CFDictionarySetValue(identity_dict, kSecImportItemTrust, trust);
        if(!trust) goto out; //require(trust, out);
     SecTrustEvaluate(trust, &result);
     CFDictionarySetValue(identity_dict, kSecImportItemTrust, trust);
-    
+
     cert_chain = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
        if(!cert_chain) goto out; //require(cert_chain, out);
     CFIndex cert_chain_length = SecTrustGetCertificateCount(trust);
     cert_chain = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
        if(!cert_chain) goto out; //require(cert_chain, out);
     CFIndex cert_chain_length = SecTrustGetCertificateCount(trust);
@@ -123,7 +123,7 @@ static void build_trust_chains(const void *key, const void *value,
     for (i = 0; i < cert_chain_length; i++)
         CFArrayAppendValue(cert_chain, SecTrustGetCertificateAtIndex(trust, i));
     CFDictionarySetValue(identity_dict, kSecImportItemCertChain, cert_chain);
     for (i = 0; i < cert_chain_length; i++)
         CFArrayAppendValue(cert_chain, SecTrustGetCertificateAtIndex(trust, i));
     CFDictionarySetValue(identity_dict, kSecImportItemCertChain, cert_chain);
-    
+
     CFArrayAppendValue(a_build_trust_chains_context->identities, identity_dict);
 out:
     CFReleaseSafe(identity_dict);
     CFArrayAppendValue(a_build_trust_chains_context->identities, identity_dict);
 out:
     CFReleaseSafe(identity_dict);
@@ -143,7 +143,7 @@ OSStatus SecPKCS12Import(CFDataRef pkcs12_data, CFDictionaryRef options, CFArray
        // SecKeychainItemImport API, which supports importing items into a
        // specified keychain with initial access control settings for keys.
        //
        // SecKeychainItemImport API, which supports importing items into a
        // specified keychain with initial access control settings for keys.
        //
-       OSStatus status = noErr;
+       OSStatus status = errSecSuccess;
        SecExternalFormat inputFormat = kSecFormatPKCS12;
        SecExternalItemType itemType = kSecItemTypeAggregate;
        SecItemImportExportFlags flags = 0; /* don't know if it's PEM armoured */
        SecExternalFormat inputFormat = kSecFormatPKCS12;
        SecExternalItemType itemType = kSecItemTypeAggregate;
        SecItemImportExportFlags flags = 0; /* don't know if it's PEM armoured */
@@ -166,12 +166,12 @@ OSStatus SecPKCS12Import(CFDataRef pkcs12_data, CFDictionaryRef options, CFArray
                if (importPassword)
                        CFRetain(importPassword);
        }
                if (importPassword)
                        CFRetain(importPassword);
        }
-       
+
        if (!importKeychain) {
                // SecKeychainItemImport requires a keychain, so use default
                status = SecKeychainCopyDefault(&importKeychain);
        }
        if (!importKeychain) {
                // SecKeychainItemImport requires a keychain, so use default
                status = SecKeychainCopyDefault(&importKeychain);
        }
-       
+
        memset(&keyParams, 0, sizeof(SecKeyImportExportParameters));
        keyParams.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION;
        keyParams.passphrase = importPassword;
        memset(&keyParams, 0, sizeof(SecKeyImportExportParameters));
        keyParams.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION;
        keyParams.passphrase = importPassword;
@@ -181,11 +181,11 @@ OSStatus SecPKCS12Import(CFDataRef pkcs12_data, CFDictionaryRef options, CFArray
                                                                   NULL,                /* no filename */
                                                                   &inputFormat,
                                                                   &itemType,
                                                                   NULL,                /* no filename */
                                                                   &inputFormat,
                                                                   &itemType,
-                                                                  flags, 
+                                                                  flags,
                                                                   &keyParams,
                                                                   importKeychain,
                                                                   &tmpItems);
                                                                   &keyParams,
                                                                   importKeychain,
                                                                   &tmpItems);
-       
+
        // build an array of all non-identity certificates which were imported
        if (!status) {
                certs = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
        // build an array of all non-identity certificates which were imported
        if (!status) {
                certs = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
@@ -198,7 +198,7 @@ OSStatus SecPKCS12Import(CFDataRef pkcs12_data, CFDictionaryRef options, CFArray
                        }
                }
        }
                        }
                }
        }
-       
+
        // now build the output items (array of dictionaries)
        if (!status) {
                identities = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
        // now build the output items (array of dictionaries)
        if (!status) {
                identities = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
@@ -208,14 +208,14 @@ OSStatus SecPKCS12Import(CFDataRef pkcs12_data, CFDictionaryRef options, CFArray
                        CFTypeID itemID = CFGetTypeID(anItem);
                        if (itemID == SecIdentityGetTypeID()) {
                                CFMutableDictionaryRef itemDict;
                        CFTypeID itemID = CFGetTypeID(anItem);
                        if (itemID == SecIdentityGetTypeID()) {
                                CFMutableDictionaryRef itemDict;
-                               itemDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 
+                               itemDict = CFDictionaryCreateMutable(kCFAllocatorDefault,
                                                                                                         0,
                                                                                                         &kCFTypeDictionaryKeyCallBacks,
                                                                                                         &kCFTypeDictionaryValueCallBacks);
 
                                SecCertificateRef itemCert = NULL;
                                status = SecIdentityCopyCertificate((SecIdentityRef)anItem, &itemCert);
                                                                                                         0,
                                                                                                         &kCFTypeDictionaryKeyCallBacks,
                                                                                                         &kCFTypeDictionaryValueCallBacks);
 
                                SecCertificateRef itemCert = NULL;
                                status = SecIdentityCopyCertificate((SecIdentityRef)anItem, &itemCert);
-                               
+
                                // label
                                if (!status) {
                                        CFStringRef label = SecCertificateCopySubjectSummary(itemCert);
                                // label
                                if (!status) {
                                        CFStringRef label = SecCertificateCopySubjectSummary(itemCert);
@@ -234,7 +234,7 @@ OSStatus SecPKCS12Import(CFDataRef pkcs12_data, CFDictionaryRef options, CFArray
                                                status = SecKeyGetCSSMKey(itemKey, &cssmKey);
                                                if (!status) {
                                                        unsigned char hash[CC_SHA1_DIGEST_LENGTH];
                                                status = SecKeyGetCSSMKey(itemKey, &cssmKey);
                                                if (!status) {
                                                        unsigned char hash[CC_SHA1_DIGEST_LENGTH];
-                                                       CC_SHA1(cssmKey->KeyData.Data, cssmKey->KeyData.Length, &hash[0]);
+                                                       CC_SHA1(cssmKey->KeyData.Data, (CC_LONG)cssmKey->KeyData.Length, &hash[0]);
                                                        CFDataRef digest = CFDataCreate(NULL, (const UInt8 *)hash, CC_SHA1_DIGEST_LENGTH);
                                                        if (digest) {
                                                                CFDictionaryAddValue(itemDict, kSecImportItemKeyID, digest);
                                                        CFDataRef digest = CFDataCreate(NULL, (const UInt8 *)hash, CC_SHA1_DIGEST_LENGTH);
                                                        if (digest) {
                                                                CFDictionaryAddValue(itemDict, kSecImportItemKeyID, digest);
@@ -267,18 +267,18 @@ OSStatus SecPKCS12Import(CFDataRef pkcs12_data, CFDictionaryRef options, CFArray
                                        CFDictionaryAddValue(itemDict, kSecImportItemCertChain, certArray);
                                        CFRelease(certArray);
                                }
                                        CFDictionaryAddValue(itemDict, kSecImportItemCertChain, certArray);
                                        CFRelease(certArray);
                                }
-                               
+
                                // identity
                                CFDictionaryAddValue(itemDict, kSecImportItemIdentity, anItem);
                                // identity
                                CFDictionaryAddValue(itemDict, kSecImportItemIdentity, anItem);
-                               
+
                                if (itemCert)
                                if (itemCert)
-                                       CFRelease(itemCert);                            
+                                       CFRelease(itemCert);
                                CFArrayAppendValue(identities, itemDict);
                                CFRelease(itemDict);
                        }
                }
        }
                                CFArrayAppendValue(identities, itemDict);
                                CFRelease(itemDict);
                        }
                }
        }
-       
+
        if (items)
                *items = identities;
        else if (identities)
        if (items)
                *items = identities;
        else if (identities)
@@ -294,16 +294,16 @@ OSStatus SecPKCS12Import(CFDataRef pkcs12_data, CFDictionaryRef options, CFArray
                CFRelease(importAccess);
        if (importPassword)
                CFRelease(importPassword);
                CFRelease(importAccess);
        if (importPassword)
                CFRelease(importPassword);
-       
+
        return status;
        return status;
-       
+
 //FIXME: needs SecAsn1Coder implementation
 #if 0
     pkcs12_context context = {};
     SecAsn1CoderCreate(&context.coder);
     if (options)
         context.passphrase = CFDictionaryGetValue(options, kSecImportExportPassphrase);
 //FIXME: needs SecAsn1Coder implementation
 #if 0
     pkcs12_context context = {};
     SecAsn1CoderCreate(&context.coder);
     if (options)
         context.passphrase = CFDictionaryGetValue(options, kSecImportExportPassphrase);
-    context.items = CFDictionaryCreateMutable(kCFAllocatorDefault, 
+    context.items = CFDictionaryCreateMutable(kCFAllocatorDefault,
         0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
     int status = p12decode(&context, pkcs12_data);
     if (!status) {
         0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
     int status = p12decode(&context, pkcs12_data);
     if (!status) {
@@ -314,22 +314,22 @@ OSStatus SecPKCS12Import(CFDataRef pkcs12_data, CFDictionaryRef options, CFArray
         build_trust_chains_context a_build_trust_chains_context = { identities, certs };
         CFDictionaryApplyFunction(context.items, build_trust_chains, &a_build_trust_chains_context);
         CFReleaseSafe(certs);
         build_trust_chains_context a_build_trust_chains_context = { identities, certs };
         CFDictionaryApplyFunction(context.items, build_trust_chains, &a_build_trust_chains_context);
         CFReleaseSafe(certs);
-        
+
         /* ignoring certs that weren't picked up as part of the certchain for found keys */
         /* ignoring certs that weren't picked up as part of the certchain for found keys */
-        
+
         *items = identities;
     }
 
     CFReleaseSafe(context.items);
     SecAsn1CoderRelease(context.coder);
         *items = identities;
     }
 
     CFReleaseSafe(context.items);
     SecAsn1CoderRelease(context.coder);
-    
+
     switch (status) {
     switch (status) {
-    case p12_noErr: return noErr;
+    case p12_noErr: return errSecSuccess;
     case p12_passwordErr: return errSecAuthFailed;
     case p12_decodeErr: return errSecDecode;
     default: return errSecInternal;
     };
     case p12_passwordErr: return errSecAuthFailed;
     case p12_decodeErr: return errSecDecode;
     default: return errSecInternal;
     };
-    return noErr;
+    return errSecSuccess;
 #endif
 }
 
 #endif
 }
 
index 14530643a054382125bdb69e931612b64489e426..f32a88c8966108c777e18e6fcd29ea1b021c583c 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2000-2010 Apple Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2000-2010,2013 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -43,19 +43,19 @@ extern "C" {
  */
 enum
 {
  */
 enum
 {
-       /* 
-        * When importing: unknown format 
+       /*
+        * When importing: unknown format
         * When exporting: default format for item
         */
        kSecFormatUnknown = 0,
 
         * When exporting: default format for item
         */
        kSecFormatUnknown = 0,
 
-       /* 
+       /*
         * Public and Private Key formats.
         * Default for export is kSecFormatOpenSSL.
         */
        kSecFormatOpenSSL,                              /* a.k.a. X509 for public keys */
        kSecFormatSSH,                                  /* OpenSSH v.1 */
         * Public and Private Key formats.
         * Default for export is kSecFormatOpenSSL.
         */
        kSecFormatOpenSSL,                              /* a.k.a. X509 for public keys */
        kSecFormatSSH,                                  /* OpenSSH v.1 */
-       kSecFormatBSAFE,        
+       kSecFormatBSAFE,
 
        /* Symmetric Key Formats */
        kSecFormatRawKey,                               /* raw unformatted key bits; default */
 
        /* Symmetric Key Formats */
        kSecFormatRawKey,                               /* raw unformatted key bits; default */
@@ -65,7 +65,7 @@ enum
        kSecFormatWrappedOpenSSL,               /* traditional openssl */
        kSecFormatWrappedSSH,                   /* OpenSSH v.1 */
        kSecFormatWrappedLSH,
        kSecFormatWrappedOpenSSL,               /* traditional openssl */
        kSecFormatWrappedSSH,                   /* OpenSSH v.1 */
        kSecFormatWrappedLSH,
-       
+
        /* Formats for certificates */
        kSecFormatX509Cert,                             /* DER encoded; default */
 
        /* Formats for certificates */
        kSecFormatX509Cert,                             /* DER encoded; default */
 
@@ -75,7 +75,7 @@ enum
        kSecFormatPKCS7,                                /* sequence of certs */
        kSecFormatPKCS12,                               /* set of certs and private keys */
        kSecFormatNetscapeCertSequence, /* sequence of certs, form netscape-cert-sequence */
        kSecFormatPKCS7,                                /* sequence of certs */
        kSecFormatPKCS12,                               /* set of certs and private keys */
        kSecFormatNetscapeCertSequence, /* sequence of certs, form netscape-cert-sequence */
-       
+
        /* Added in Mac OS X 10.5 */
        kSecFormatSSHv2                                 /* OpenSSH v.2. Note that OpenSSH v2 private keys
                                                                         * are in format kSecFormatOpenSSL or
        /* Added in Mac OS X 10.5 */
        kSecFormatSSHv2                                 /* OpenSSH v.2. Note that OpenSSH v2 private keys
                                                                         * are in format kSecFormatOpenSSL or
@@ -83,8 +83,8 @@ enum
 };
 typedef uint32_t SecExternalFormat;
 
 };
 typedef uint32_t SecExternalFormat;
 
-/* 
- * Indication of basic item type when importing. 
+/*
+ * Indication of basic item type when importing.
  */
 enum {
        kSecItemTypeUnknown,                    /* caller doesn't know what this is */
  */
 enum {
        kSecItemTypeUnknown,                    /* caller doesn't know what this is */
@@ -102,29 +102,29 @@ typedef uint32_t SecExternalItemType;
 enum
 {
        kSecItemPemArmour                       = 0x00000001,   /* exported blob is PEM formatted */
 enum
 {
        kSecItemPemArmour                       = 0x00000001,   /* exported blob is PEM formatted */
-}; 
+};
 typedef uint32_t SecItemImportExportFlags;
 
 /*
  * SecKeyRef-specific flags, specified in SecKeyImportExportParameters.flags
  */
 typedef uint32_t SecItemImportExportFlags;
 
 /*
  * SecKeyRef-specific flags, specified in SecKeyImportExportParameters.flags
  */
-enum 
+enum
 {
        /*
         * When true, prevents the importing of more than one private key
         * in a given SecKeychainItemImport().
         */
        kSecKeyImportOnlyOne            = 0x00000001,
 {
        /*
         * When true, prevents the importing of more than one private key
         * in a given SecKeychainItemImport().
         */
        kSecKeyImportOnlyOne            = 0x00000001,
-       
-       /* 
+
+       /*
         * When true, passphrase for import/export is obtained by user prompt
         * instead of by caller-supplied data (SecKeyImportExportParameters.passphrase).
         * This is the preferred method for obtaining a user-supplied passphrase
         * When true, passphrase for import/export is obtained by user prompt
         * instead of by caller-supplied data (SecKeyImportExportParameters.passphrase).
         * This is the preferred method for obtaining a user-supplied passphrase
-        * as it avoids having the cleartext passphrase appear in the app's 
+        * as it avoids having the cleartext passphrase appear in the app's
         * address space at any time.
         */
        kSecKeySecurePassphrase         = 0x00000002,
         * address space at any time.
         */
        kSecKeySecurePassphrase         = 0x00000002,
-       
+
        /*
         * When true, imported private keys will have no Access Control List
         * (ACL) attached to them. In the absence of both this bit and the accessRef
        /*
         * When true, imported private keys will have no Access Control List
         * (ACL) attached to them. In the absence of both this bit and the accessRef
@@ -134,7 +134,7 @@ enum
        kSecKeyNoAccessControl          = 0x00000004
 };
 typedef uint32_t SecKeyImportExportFlags;
        kSecKeyNoAccessControl          = 0x00000004
 };
 typedef uint32_t SecKeyImportExportFlags;
+
 /*
  * Version of a SecKeyImportExportParameters.
  */
 /*
  * Version of a SecKeyImportExportParameters.
  */
@@ -143,7 +143,7 @@ typedef uint32_t SecKeyImportExportFlags;
 /*
  * Parameters specific to SecKeyRefs.
  */
 /*
  * Parameters specific to SecKeyRefs.
  */
-typedef struct 
+typedef struct
 {
        /* for import and export */
        uint32_t                                version;                /* SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION */
 {
        /* for import and export */
        uint32_t                                version;                /* SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION */
@@ -153,17 +153,17 @@ typedef struct
                                                                                         *    CFStringRef and CFDataRef. */
        CFStringRef                             alertTitle;             /* title of secure passphrase alert panel */
        CFStringRef                             alertPrompt;    /* prompt in secure passphrase alert panel */
                                                                                         *    CFStringRef and CFDataRef. */
        CFStringRef                             alertTitle;             /* title of secure passphrase alert panel */
        CFStringRef                             alertPrompt;    /* prompt in secure passphrase alert panel */
-       
+
        /* for import only */
        /* for import only */
-       SecAccessRef                    accessRef;              /* specifies the initial ACL of imported 
+       SecAccessRef                    accessRef;              /* specifies the initial ACL of imported
                                                                                         *    key(s) */
                                                                                         *    key(s) */
-       CSSM_KEYUSE                             keyUsage;               /* CSSM_KEYUSE_DECRYPT, CSSM_KEYUSE_SIGN, 
+       CSSM_KEYUSE                             keyUsage;               /* CSSM_KEYUSE_DECRYPT, CSSM_KEYUSE_SIGN,
                                                                                         *    etc. */
        CSSM_KEYATTR_FLAGS              keyAttributes;  /* CSSM_KEYATTR_PERMANENT, etc. */
 } SecKeyImportExportParameters;
 
 
                                                                                         *    etc. */
        CSSM_KEYATTR_FLAGS              keyAttributes;  /* CSSM_KEYATTR_PERMANENT, etc. */
 } SecKeyImportExportParameters;
 
 
-typedef struct 
+typedef struct
 {
        /* for import and export */
        uint32_t                                version;                /* SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION */
 {
        /* for import and export */
        uint32_t                                version;                /* SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION */
@@ -171,33 +171,40 @@ typedef struct
        CFTypeRef                               passphrase;             /* kSecFormatPKCS12, kSecFormatWrapped*
                                                                                         *    formats only. Legal types are
                                                                                         *    CFStringRef and CFDataRef. */
        CFTypeRef                               passphrase;             /* kSecFormatPKCS12, kSecFormatWrapped*
                                                                                         *    formats only. Legal types are
                                                                                         *    CFStringRef and CFDataRef. */
-       CFStringRef                             alertTitle;             /* title of s ecure passphrase alert panel */
+       CFStringRef                             alertTitle;             /* title of secure passphrase alert panel */
        CFStringRef                             alertPrompt;    /* prompt in secure passphrase alert panel */
        CFStringRef                             alertPrompt;    /* prompt in secure passphrase alert panel */
-       
+
        /* for import only */
        /* for import only */
-       SecAccessRef                    accessRef;              /* specifies the initial ACL of imported 
+       SecAccessRef                    accessRef;              /* specifies the initial ACL of imported
                                                                                         *    key(s) */
                                                                                         *    key(s) */
-       CFArrayRef                              keyUsage;               /*      An Array containing item from SecItem.h i.e 
-                                                                                               kSecAttrCanEncrypt;, kSecAttrCanDecrypt, kSecAttrCanDerive, etc
-                                                                                       */
-                                                                                       
-       CFArrayRef                              keyAttributes;  /* CSSM_KEYATTR_PERMANENT, etc. */
+       CFArrayRef                              keyUsage;               /* An Array containing usage attributes from SecItem.h, e.g.
+                                                                                          kSecAttrCanEncrypt;, kSecAttrCanDecrypt, kSecAttrCanDerive, etc.
+                                                                                        */
+
+       CFArrayRef                              keyAttributes;  /* An array containing zero or more key attributes
+                                                                                          for an imported key. Possible values (from SecItem.h):
+                                                                                          kSecAttrIsPermanent, kSecAttrIsSensitive, kSecAttrIsExtractable
+                                                                                          Pass NULL in this field to use default attributes:
+                                                                                          - kSecAttrIsPermanent if a keychain is specified
+                                                                                          - kSecAttrIsSensitive for private keys
+                                                                                          - kSecAttrIsExtractable by default
+                                                                                        */
 } SecItemImportExportKeyParameters;
 
 /*
  * SecKeychainItemExport()
  *
 } SecItemImportExportKeyParameters;
 
 /*
  * SecKeychainItemExport()
  *
- * This function takes one or more SecKeychainItemRefs and creates an 
- * external representation of the item(s) in the form of a CFDataRef. 
- * Caller specifies the format of the external representation via a 
- * SecExternalFormat enum. Caller may specify kSecFormatUnknown for 
- * the format, in which case a the default format for the item 
+ * This function takes one or more SecKeychainItemRefs and creates an
+ * external representation of the item(s) in the form of a CFDataRef.
+ * Caller specifies the format of the external representation via a
+ * SecExternalFormat enum. Caller may specify kSecFormatUnknown for
+ * the format, in which case a the default format for the item
  * being exported is used (as described in the SecExternalFormat enums).
  * being exported is used (as described in the SecExternalFormat enums).
- * PEM armouring is optional and is specified by the kSecItemPemArmour 
- * flag in importFlags. 
+ * PEM armouring is optional and is specified by the kSecItemPemArmour
+ * flag in importFlags.
  *
  *
- * If exactly one item is to be exported, the keychainItemOrArray argument 
- * can be a SecKeychainItem. Otherwise this argument is a CFArrayRef 
+ * If exactly one item is to be exported, the keychainItemOrArray argument
+ * can be a SecKeychainItem. Otherwise this argument is a CFArrayRef
  * containing a number of SecKeychainItems.
  *
  * The following SecKeychainItems may be exported:
  * containing a number of SecKeychainItems.
  *
  * The following SecKeychainItems may be exported:
@@ -210,51 +217,51 @@ typedef struct
  * Key-related SecKeyImportExportParameters fields
  * -----------------------------------------------
  *
  * Key-related SecKeyImportExportParameters fields
  * -----------------------------------------------
  *
- * When exporting SecKeyRefs in one of the wrapped formats 
- * (kSecFormatWrappedOpenSSL, kSecFormatWrappedSSH, 
- * kSecFormatWrappedPKCS8), or in PKCS12 format, caller must 
- * either explicitly specify the passphrase field or set 
+ * When exporting SecKeyRefs in one of the wrapped formats
+ * (kSecFormatWrappedOpenSSL, kSecFormatWrappedSSH,
+ * kSecFormatWrappedPKCS8), or in PKCS12 format, caller must
+ * either explicitly specify the passphrase field or set
  * the kSecKeySecurePassphrase bit in SecKeyImportExportFlags.
  *
  * If kSecKeySecurePassphrase is selected, caller can optionally
  * the kSecKeySecurePassphrase bit in SecKeyImportExportFlags.
  *
  * If kSecKeySecurePassphrase is selected, caller can optionally
- * specify strings for the passphrase panel's title bar and for 
- * the prompt which appears in the panel via the alertTitle and 
+ * specify strings for the passphrase panel's title bar and for
+ * the prompt which appears in the panel via the alertTitle and
  * alertPrompt fields in SecKeyImportExportParameters.
  *
  * If an explicit passphrase is specified, note that PKCS12
  * explicitly requires that passphrases are in Unicode format;
  * passing in a CFStringRef as the passphrase is the safest way
  * alertPrompt fields in SecKeyImportExportParameters.
  *
  * If an explicit passphrase is specified, note that PKCS12
  * explicitly requires that passphrases are in Unicode format;
  * passing in a CFStringRef as the passphrase is the safest way
- * to ensure that this requirement is met (and that the result 
+ * to ensure that this requirement is met (and that the result
  * will be compatible with other implementations). If a CFDataRef
  * will be compatible with other implementations). If a CFDataRef
- * is supplied as the passphrase for a PKCS12 export operation, 
+ * is supplied as the passphrase for a PKCS12 export operation,
  * the referent data is assumed to be in UTF8 form and will be
  * the referent data is assumed to be in UTF8 form and will be
- * converted as appropriate. 
+ * converted as appropriate.
  *
  * If no key items are being exported, the keyParams argument may be NULL.
  * @discussion This API has been deprecated. Please us the SecItemExport API instead.
  */
 OSStatus SecKeychainItemExport(
        CFTypeRef                                                       keychainItemOrArray,
  *
  * If no key items are being exported, the keyParams argument may be NULL.
  * @discussion This API has been deprecated. Please us the SecItemExport API instead.
  */
 OSStatus SecKeychainItemExport(
        CFTypeRef                                                       keychainItemOrArray,
-       SecExternalFormat                                       outputFormat,   
+       SecExternalFormat                                       outputFormat,
        SecItemImportExportFlags                        flags,                          /* kSecItemPemArmor, etc. */
        const SecKeyImportExportParameters  *keyParams,                 /* optional */
        CFDataRef                                                       *exportedData)          /* external representation returned here */
                DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
        SecItemImportExportFlags                        flags,                          /* kSecItemPemArmor, etc. */
        const SecKeyImportExportParameters  *keyParams,                 /* optional */
        CFDataRef                                                       *exportedData)          /* external representation returned here */
                DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-                                                                                                       
+
 /*
  * SecItemExport()
  *
 /*
  * SecItemExport()
  *
- * This function takes one or more SecItemRefs and creates an 
- * external representation of the item(s) in the form of a CFDataRef. 
- * Caller specifies the format of the external representation via a 
- * SecExternalFormat enum. Caller may specify kSecFormatUnknown for 
- * the format, in which case a the default format for the item 
+ * This function takes one or more SecItemRefs and creates an
+ * external representation of the item(s) in the form of a CFDataRef.
+ * Caller specifies the format of the external representation via a
+ * SecExternalFormat enum. Caller may specify kSecFormatUnknown for
+ * the format, in which case a the default format for the item
  * being exported is used (as described in the SecExternalFormat enums).
  * being exported is used (as described in the SecExternalFormat enums).
- * PEM armouring is optional and is specified by the kSecItemPemArmour 
- * flag in importFlags. 
+ * PEM armouring is optional and is specified by the kSecItemPemArmour
+ * flag in importFlags.
  *
  *
- * If exactly one item is to be exported, the keychainItemOrArray argument 
- * can be a SecKeychainItem. Otherwise this argument is a CFArrayRef 
+ * If exactly one item is to be exported, the keychainItemOrArray argument
+ * can be a SecKeychainItem. Otherwise this argument is a CFArrayRef
  * containing a number of SecKeychainItems.
  *
  * The following SecKeychainItems may be exported:
  * containing a number of SecKeychainItems.
  *
  * The following SecKeychainItems may be exported:
@@ -267,32 +274,32 @@ OSStatus SecKeychainItemExport(
  * Key-related SecItemExport fields
  * -----------------------------------------------
  *
  * Key-related SecItemExport fields
  * -----------------------------------------------
  *
- * When exporting SecKeyRefs in one of the wrapped formats 
- * (kSecFormatWrappedOpenSSL, kSecFormatWrappedSSH, 
- * kSecFormatWrappedPKCS8), or in PKCS12 format, caller must 
- * either explicitly specify the passphrase field or set 
+ * When exporting SecKeyRefs in one of the wrapped formats
+ * (kSecFormatWrappedOpenSSL, kSecFormatWrappedSSH,
+ * kSecFormatWrappedPKCS8), or in PKCS12 format, caller must
+ * either explicitly specify the passphrase field or set
  * the kSecKeySecurePassphrase bit in SecKeyImportExportFlags.
  *
  * If kSecKeySecurePassphrase is selected, caller can optionally
  * the kSecKeySecurePassphrase bit in SecKeyImportExportFlags.
  *
  * If kSecKeySecurePassphrase is selected, caller can optionally
- * specify strings for the passphrase panel's title bar and for 
- * the prompt which appears in the panel via the alertTitle and 
+ * specify strings for the passphrase panel's title bar and for
+ * the prompt which appears in the panel via the alertTitle and
  * alertPrompt fields in SecItemImportExportKeyParameters.
  *
  * If an explicit passphrase is specified, note that PKCS12
  * explicitly requires that passphrases are in Unicode format;
  * passing in a CFStringRef as the passphrase is the safest way
  * alertPrompt fields in SecItemImportExportKeyParameters.
  *
  * If an explicit passphrase is specified, note that PKCS12
  * explicitly requires that passphrases are in Unicode format;
  * passing in a CFStringRef as the passphrase is the safest way
- * to ensure that this requirement is met (and that the result 
+ * to ensure that this requirement is met (and that the result
  * will be compatible with other implementations). If a CFDataRef
  * will be compatible with other implementations). If a CFDataRef
- * is supplied as the passphrase for a PKCS12 export operation, 
+ * is supplied as the passphrase for a PKCS12 export operation,
  * the referent data is assumed to be in UTF8 form and will be
  * the referent data is assumed to be in UTF8 form and will be
- * converted as appropriate. 
+ * converted as appropriate.
  *
  * If no key items are being exported, the keyParams argument may be NULL.
  *
  * If no key items are being exported, the keyParams argument may be NULL.
- * 
+ *
  */
 OSStatus SecItemExport(
        CFTypeRef                                                       secItemOrArray,
  */
 OSStatus SecItemExport(
        CFTypeRef                                                       secItemOrArray,
-       SecExternalFormat                                       outputFormat,   
+       SecExternalFormat                                       outputFormat,
        SecItemImportExportFlags                        flags,                          /* kSecItemPemArmor, etc. */
        const SecItemImportExportKeyParameters  *keyParams,                     /* optional */
        CFDataRef                                                       *exportedData)          /* external representation returned here */
        SecItemImportExportFlags                        flags,                          /* kSecItemPemArmor, etc. */
        const SecItemImportExportKeyParameters  *keyParams,                     /* optional */
        CFDataRef                                                       *exportedData)          /* external representation returned here */
@@ -300,104 +307,104 @@ OSStatus SecItemExport(
 /*
  * SecKeychainItemImport()
  *
 /*
  * SecKeychainItemImport()
  *
- * This function takes a CFDataRef containing the external representation 
- * of one or more objects and creates SecKeychainItems corresponding to 
- * those objects and optionally imports those SecKeychainItems into a 
- * specified keychain. The format of the incoming representation is 
+ * This function takes a CFDataRef containing the external representation
+ * of one or more objects and creates SecKeychainItems corresponding to
+ * those objects and optionally imports those SecKeychainItems into a
+ * specified keychain. The format of the incoming representation is
  * specified by one or more of the following:
  *
  * specified by one or more of the following:
  *
- * -- A SecExternalFormat. This optional in/out argument is used when 
- *    the caller knows exactly what format the external representation 
- *    is in. It's also used to return to the caller the format which the 
- *    function actually determines the external representation to be in. 
+ * -- A SecExternalFormat. This optional in/out argument is used when
+ *    the caller knows exactly what format the external representation
+ *    is in. It's also used to return to the caller the format which the
+ *    function actually determines the external representation to be in.
  *    A value of kSecFormatUnknown is specified on entry when the caller
  *    A value of kSecFormatUnknown is specified on entry when the caller
- *    wishes to know the inferred format on return. 
+ *    wishes to know the inferred format on return.
  *
  * -- A SecExternalItemType - optional, in/out. Used to specify what kind
  *    of item is in the incoming representation, if known by the caller.
  *
  * -- A SecExternalItemType - optional, in/out. Used to specify what kind
  *    of item is in the incoming representation, if known by the caller.
- *    It's also used to return to the caller the item type which the 
- *    function actually determines the external representation to contain. 
+ *    It's also used to return to the caller the item type which the
+ *    function actually determines the external representation to contain.
  *    A value of kSecItemTypeUnknown is specified on entry when the caller
  *    wishes to know the inferred item type on return.
  *
  *    A value of kSecItemTypeUnknown is specified on entry when the caller
  *    wishes to know the inferred item type on return.
  *
- * -- fileNameOrExtension, a CFStringRef. This optional argument contains 
- *    the name of the file from which the external representation was 
- *    obtained; it can also be simply an extension like CFSTR(".p7r"). 
- *    This is a convenience for apps like KeychainAccess which can import a 
- *    number of different formats. 
+ * -- fileNameOrExtension, a CFStringRef. This optional argument contains
+ *    the name of the file from which the external representation was
+ *    obtained; it can also be simply an extension like CFSTR(".p7r").
+ *    This is a convenience for apps like KeychainAccess which can import a
+ *    number of different formats.
  *
  *
- * The SecKeychainItemImport() call does its best to figure out what is 
+ * The SecKeychainItemImport() call does its best to figure out what is
  * in an incoming external item given the info provided by the above three
  * arguments. In most cases, SecKeychainItemImport() can even figure out
  * what's in an external item if none of these are specified, but it would
  * in an incoming external item given the info provided by the above three
  * arguments. In most cases, SecKeychainItemImport() can even figure out
  * what's in an external item if none of these are specified, but it would
- * be unwise for an application to count on that ability. 
+ * be unwise for an application to count on that ability.
  *
  *
- * PEM formatting is determined internally via inspection of the incoming 
- * data, so the kSecItemPemArmuor in the flags field is ignored. 
+ * PEM formatting is determined internally via inspection of the incoming
+ * data, so the kSecItemPemArmuor in the flags field is ignored.
  *
  *
- * Zero, one, or both of the following occurs upon successful completion 
+ * Zero, one, or both of the following occurs upon successful completion
  * of this function:
  *
  * of this function:
  *
- * -- The imported item(s) is (are) imported to the specified importKeychain. 
+ * -- The imported item(s) is (are) imported to the specified importKeychain.
  *    If importKeychain is NULL, this step does not occur.
  *    If importKeychain is NULL, this step does not occur.
- * 
- * -- The imported item(s) is (are) returned to the caller via the 
+ *
+ * -- The imported item(s) is (are) returned to the caller via the
  *    CRArrayRef *outItems argument. If outItems is NULL, this step
  *    does not occur. If outItems is NON-NULL, then *outItems will be
  *    a CFArrayRef containing a number of SecKeychainItems upon return.
  *    Caller must CFRelease the result.
  *    CRArrayRef *outItems argument. If outItems is NULL, this step
  *    does not occur. If outItems is NON-NULL, then *outItems will be
  *    a CFArrayRef containing a number of SecKeychainItems upon return.
  *    Caller must CFRelease the result.
- * 
+ *
  * The possible types of returned SecKeychainItems are:
  *
  *   SecCertificateRef
  *   SecKeyRef
  *   SecIdentityRef
  *
  * The possible types of returned SecKeychainItems are:
  *
  *   SecCertificateRef
  *   SecKeyRef
  *   SecIdentityRef
  *
- * Note that when importing a PKCS12 blob, typically one SecIdentityRef 
- * and zero or more additional SecCertificateRefs are returned in 
- * outItems. No SecKeyRefs will appear there unless a key 
- * is found in the incoming blob with does not have a matching 
+ * Note that when importing a PKCS12 blob, typically one SecIdentityRef
+ * and zero or more additional SecCertificateRefs are returned in
+ * outItems. No SecKeyRefs will appear there unless a key
+ * is found in the incoming blob with does not have a matching
  * certificate.
  *
  * certificate.
  *
- * A typical case in which an app specifies the outItems 
- * argument and a NULL for importKeychain is when the app wishes to 
- * perform some user interaction, perhaps on a per-item basis, before 
- * committing to actually import the item(s). In this case, if the app 
- * does wish to proceed with the import, the standard import calls 
- * (SecCertificateAddToKeychain(), SecKeyAddToKeychain (implementation 
+ * A typical case in which an app specifies the outItems
+ * argument and a NULL for importKeychain is when the app wishes to
+ * perform some user interaction, perhaps on a per-item basis, before
+ * committing to actually import the item(s). In this case, if the app
+ * does wish to proceed with the import, the standard import calls
+ * (SecCertificateAddToKeychain(), SecKeyAddToKeychain (implementation
  * TBD)) would be used.
  *
  * Passing in NULL for both outItems and importKeychain
  * is a perfectly acceptable way of using this function to determine,
  * in a non-intrusive way, what is inside a given data blob. No effect
  * TBD)) would be used.
  *
  * Passing in NULL for both outItems and importKeychain
  * is a perfectly acceptable way of using this function to determine,
  * in a non-intrusive way, what is inside a given data blob. No effect
- * other than returning inputFormat and/or itemType occurs in this 
- * case. 
+ * other than returning inputFormat and/or itemType occurs in this
+ * case.
+
  *
  * Key-related SecKeyImportExportParameters fields
  * -----------------------------------------------
  *
  * If importKeychain is NULL, the kSecKeyImportOnlyOne bit in the flags
  * argument is ignored. Otherwise, if the kSecKeyImportOnlyOne bit is set, and
  *
  * Key-related SecKeyImportExportParameters fields
  * -----------------------------------------------
  *
  * If importKeychain is NULL, the kSecKeyImportOnlyOne bit in the flags
  * argument is ignored. Otherwise, if the kSecKeyImportOnlyOne bit is set, and
- * there is more than one key in the incoming external representation, no 
+ * there is more than one key in the incoming external representation, no
  * items will be imported to the specified keychain and errSecMultipleKeys will
  * items will be imported to the specified keychain and errSecMultipleKeys will
- * be returned. 
- * 
+ * be returned.
+ *
  * The accessRef field allows the caller to specify the initial SecAccessRef
  * The accessRef field allows the caller to specify the initial SecAccessRef
- * for imported private keys. If more than one private key is being imported, 
- * all private keys get the same initial SecAccessRef. If this field is NULL 
- * when private keys are being imported, then the ACL attached to imported 
- * private keys depends on the kSecKeyNoAccessControl bit in the specified 
+ * for imported private keys. If more than one private key is being imported,
+ * all private keys get the same initial SecAccessRef. If this field is NULL
+ * when private keys are being imported, then the ACL attached to imported
+ * private keys depends on the kSecKeyNoAccessControl bit in the specified
  * keyParams->flags. If this bit is 0, or keyParams is NULL, the default ACL
  * keyParams->flags. If this bit is 0, or keyParams is NULL, the default ACL
- * will be used. If this bit is 1, no ACL will be attached to imported 
+ * will be used. If this bit is 1, no ACL will be attached to imported
  * private keys.
  *
  * keyUsage and keyAttributes specify the low-level usage and attribute flags
  * of imported keys. Each is a word of bits. The default value for keyUsage
  * private keys.
  *
  * keyUsage and keyAttributes specify the low-level usage and attribute flags
  * of imported keys. Each is a word of bits. The default value for keyUsage
- * (used when keyParams is NULL or if keyParams->keyUsage is zero) is 
+ * (used when keyParams is NULL or if keyParams->keyUsage is zero) is
  * CSSM_KEYUSE_ANY. The default value for keyAttributes defaults is
  * CSSM_KEYUSE_ANY. The default value for keyAttributes defaults is
- * CSSM_KEYATTR_SENSITIVE | CSSM_KEYATTR_EXTRACTABLE; the CSSM_KEYATTR_PERMANENT 
- * bit is also added to the default if a non-NULL importKeychain is provided. 
+ * CSSM_KEYATTR_SENSITIVE | CSSM_KEYATTR_EXTRACTABLE; the CSSM_KEYATTR_PERMANENT
+ * bit is also added to the default if a non-NULL importKeychain is provided.
  *
  * The following are valid bits in keyAttributes:
  *
  *
  * The following are valid bits in keyAttributes:
  *
@@ -407,36 +414,36 @@ OSStatus SecItemExport(
  *
  * If the CSSM_KEYATTR_PERMANENT is set then the importKeychain argument must
  * be valid or errSecInvalidKeychain will be returned if in fact any keys are found
  *
  * If the CSSM_KEYATTR_PERMANENT is set then the importKeychain argument must
  * be valid or errSecInvalidKeychain will be returned if in fact any keys are found
- * in the external representation. 
+ * in the external representation.
  *
  * Note that if the caller does not set the CSSM_KEYATTR_EXTRACTABLE, this key
  * will never be able to be extracted from the keychain in any form, not even
  *
  * Note that if the caller does not set the CSSM_KEYATTR_EXTRACTABLE, this key
  * will never be able to be extracted from the keychain in any form, not even
- * in wrapped form. The CSSM_KEYATTR_SENSITIVE indicates that the key can only 
- * be extracted in wrapped form. 
+ * in wrapped form. The CSSM_KEYATTR_SENSITIVE indicates that the key can only
+ * be extracted in wrapped form.
  *
  *
- * The CSSM_KEYATTR_RETURN_xxx bits are always forced to 
+ * The CSSM_KEYATTR_RETURN_xxx bits are always forced to
  * CSSM_KEYATTR_RETURN_REF regardless of the specified keyAttributes
  * CSSM_KEYATTR_RETURN_REF regardless of the specified keyAttributes
- * field. 
+ * field.
  *
  *
- * When importing SecKeyRefs in one of the wrapped formats 
- * (kSecFormatWrappedOpenSSL, kSecFormatWrappedSSH, 
- * kSecFormatWrappedPKCS8), or in PKCS12 format, caller must 
- * either explicitly specify the passphrase field or set 
+ * When importing SecKeyRefs in one of the wrapped formats
+ * (kSecFormatWrappedOpenSSL, kSecFormatWrappedSSH,
+ * kSecFormatWrappedPKCS8), or in PKCS12 format, caller must
+ * either explicitly specify the passphrase field or set
  * the kSecKeySecurePassphrase bit in SecKeyImportExportFlags.
  *
  * If kSecKeySecurePassphrase is selected, caller can optionally
  * the kSecKeySecurePassphrase bit in SecKeyImportExportFlags.
  *
  * If kSecKeySecurePassphrase is selected, caller can optionally
- * specify strings for the passphrase panel's title bar and for 
- * the prompt which appears in the panel via the alertTitle and 
+ * specify strings for the passphrase panel's title bar and for
+ * the prompt which appears in the panel via the alertTitle and
  * alertPrompt fields in SecKeyImportExportParameters.
  *
  * If an explicit passphrase is specified, note that PKCS12
  * explicitly requires that passphrases are in Unicode format;
  * passing in a CFStringRef as the passphrase is the safest way
  * alertPrompt fields in SecKeyImportExportParameters.
  *
  * If an explicit passphrase is specified, note that PKCS12
  * explicitly requires that passphrases are in Unicode format;
  * passing in a CFStringRef as the passphrase is the safest way
- * to ensure that this requirement is met (and that the result 
+ * to ensure that this requirement is met (and that the result
  * will be compatible with other implementations). If a CFDataRef
  * will be compatible with other implementations). If a CFDataRef
- * is supplied as the passphrase for a PKCS12 export operation, 
+ * is supplied as the passphrase for a PKCS12 export operation,
  * the referent data is assumed to be in UTF8 form and will be
  * the referent data is assumed to be in UTF8 form and will be
- * converted as appropriate. 
+ * converted as appropriate.
 
  * If no key items are being imported, the keyParams argument may be NULL.
  *
 
  * If no key items are being imported, the keyParams argument may be NULL.
  *
@@ -450,165 +457,176 @@ OSStatus SecKeychainItemImport(
        CFStringRef                                                     fileNameOrExtension,    /* optional */
        SecExternalFormat                                       *inputFormat,                   /* optional, IN/OUT */
        SecExternalItemType                                     *itemType,                              /* optional, IN/OUT */
        CFStringRef                                                     fileNameOrExtension,    /* optional */
        SecExternalFormat                                       *inputFormat,                   /* optional, IN/OUT */
        SecExternalItemType                                     *itemType,                              /* optional, IN/OUT */
-       SecItemImportExportFlags                        flags, 
+       SecItemImportExportFlags                        flags,
        const SecKeyImportExportParameters  *keyParams,                         /* optional */
        SecKeychainRef                                          importKeychain,                 /* optional */
        CFArrayRef                                                      *outItems)                                                      /* optional */
                DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
        const SecKeyImportExportParameters  *keyParams,                         /* optional */
        SecKeychainRef                                          importKeychain,                 /* optional */
        CFArrayRef                                                      *outItems)                                                      /* optional */
                DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-                                       
+
 /*
  * SecItemImport()
  *
 /*
  * SecItemImport()
  *
- * This function takes a CFDataRef containing the external representation 
- * of one or more objects and creates SecKeychainItems corresponding to 
- * those objects and optionally imports those SecKeychainItems into a 
- * specified keychain. The format of the incoming representation is 
+ * This function takes a CFDataRef containing the external representation
+ * of one or more objects and creates SecKeychainItems corresponding to
+ * those objects and optionally imports those SecKeychainItems into a
+ * specified keychain. The format of the incoming representation is
  * specified by one or more of the following:
  *
  * specified by one or more of the following:
  *
- * -- A SecExternalFormat. This optional in/out argument is used when 
- *    the caller knows exactly what format the external representation 
- *    is in. It's also used to return to the caller the format which the 
- *    function actually determines the external representation to be in. 
+ * -- A SecExternalFormat. This optional in/out argument is used when
+ *    the caller knows exactly what format the external representation
+ *    is in. It's also used to return to the caller the format which the
+ *    function actually determines the external representation to be in.
  *    A value of kSecFormatUnknown is specified on entry when the caller
  *    A value of kSecFormatUnknown is specified on entry when the caller
- *    wishes to know the inferred format on return. 
+ *    wishes to know the inferred format on return.
  *
  * -- A SecExternalItemType - optional, in/out. Used to specify what kind
  *    of item is in the incoming representation, if known by the caller.
  *
  * -- A SecExternalItemType - optional, in/out. Used to specify what kind
  *    of item is in the incoming representation, if known by the caller.
- *    It's also used to return to the caller the item type which the 
- *    function actually determines the external representation to contain. 
+ *    It's also used to return to the caller the item type which the
+ *    function actually determines the external representation to contain.
  *    A value of kSecItemTypeUnknown is specified on entry when the caller
  *    wishes to know the inferred item type on return.
  *
  *    A value of kSecItemTypeUnknown is specified on entry when the caller
  *    wishes to know the inferred item type on return.
  *
- * -- fileNameOrExtension, a CFStringRef. This optional argument contains 
- *    the name of the file from which the external representation was 
- *    obtained; it can also be simply an extension like CFSTR(".p7r"). 
- *    This is a convenience for apps like KeychainAccess which can import a 
- *    number of different formats. 
+ * -- fileNameOrExtension, a CFStringRef. This optional argument contains
+ *    the name of the file from which the external representation was
+ *    obtained; it can also be simply an extension like CFSTR(".p7r").
+ *    This is a convenience for apps like KeychainAccess which can import a
+ *    number of different formats.
  *
  *
- * The SecItemImport() call does its best to figure out what is 
+ * The SecItemImport() call does its best to figure out what is
  * in an incoming external item given the info provided by the above three
  * arguments. In most cases, SecItemImport() can even figure out
  * what's in an external item if none of these are specified, but it would
  * in an incoming external item given the info provided by the above three
  * arguments. In most cases, SecItemImport() can even figure out
  * what's in an external item if none of these are specified, but it would
- * be unwise for an application to count on that ability. 
+ * be unwise for an application to count on that ability.
  *
  *
- * PEM formatting is determined internally via inspection of the incoming 
- * data, so the kSecItemPemArmuor in the flags field is ignored. 
+ * PEM formatting is determined internally via inspection of the incoming
+ * data, so the kSecItemPemArmuor in the flags field is ignored.
  *
  *
- * Zero, one, or both of the following occurs upon successful completion 
+ * Zero, one, or both of the following occurs upon successful completion
  * of this function:
  *
  * of this function:
  *
- * -- The imported item(s) is (are) imported to the specified importKeychain. 
+ * -- The imported item(s) is (are) imported to the specified importKeychain.
  *    If importKeychain is NULL, this step does not occur.
  *    If importKeychain is NULL, this step does not occur.
- * 
- * -- The imported item(s) is (are) returned to the caller via the 
+ *
+ * -- The imported item(s) is (are) returned to the caller via the
  *    CRArrayRef *outItems argument. If outItems is NULL, this step
  *    does not occur. If outItems is NON-NULL, then *outItems will be
  *    a CFArrayRef containing a number of SecKeychainItems upon return.
  *    Caller must CFRelease the result.
  *    CRArrayRef *outItems argument. If outItems is NULL, this step
  *    does not occur. If outItems is NON-NULL, then *outItems will be
  *    a CFArrayRef containing a number of SecKeychainItems upon return.
  *    Caller must CFRelease the result.
- * 
+ *
  * The possible types of returned SecKeychainItems are:
  *
  *   SecCertificateRef
  *   SecKeyRef
  *   SecIdentityRef
  *
  * The possible types of returned SecKeychainItems are:
  *
  *   SecCertificateRef
  *   SecKeyRef
  *   SecIdentityRef
  *
- * Note that when importing a PKCS12 blob, typically one SecIdentityRef 
- * and zero or more additional SecCertificateRefs are returned in 
- * outItems. No SecKeyRefs will appear there unless a key 
- * is found in the incoming blob with does not have a matching 
+ * Note that when importing a PKCS12 blob, typically one SecIdentityRef
+ * and zero or more additional SecCertificateRefs are returned in
+ * outItems. No SecKeyRefs will appear there unless a key
+ * is found in the incoming blob with does not have a matching
  * certificate.
  *
  * certificate.
  *
- * A typical case in which an app specifies the outItems 
- * argument and a NULL for importKeychain is when the app wishes to 
- * perform some user interaction, perhaps on a per-item basis, before 
- * committing to actually import the item(s). In this case, if the app 
- * does wish to proceed with the import, the standard import calls 
- * (SecCertificateAddToKeychain(), SecKeyAddToKeychain (implementation 
+ * A typical case in which an app specifies the outItems
+ * argument and a NULL for importKeychain is when the app wishes to
+ * perform some user interaction, perhaps on a per-item basis, before
+ * committing to actually import the item(s). In this case, if the app
+ * does wish to proceed with the import, the standard import calls
+ * (SecCertificateAddToKeychain(), SecKeyAddToKeychain (implementation
  * TBD)) would be used.
  *
  * Passing in NULL for both outItems and importKeychain
  * is a perfectly acceptable way of using this function to determine,
  * in a non-intrusive way, what is inside a given data blob. No effect
  * TBD)) would be used.
  *
  * Passing in NULL for both outItems and importKeychain
  * is a perfectly acceptable way of using this function to determine,
  * in a non-intrusive way, what is inside a given data blob. No effect
- * other than returning inputFormat and/or itemType occurs in this 
- * case. 
+ * other than returning inputFormat and/or itemType occurs in this
+ * case.
+
  *
  * Key-related SecItemImportExportKeyParameters fields
  * -----------------------------------------------
  *
  * If importKeychain is NULL, the kSecKeyImportOnlyOne bit in the flags
  * argument is ignored. Otherwise, if the kSecKeyImportOnlyOne bit is set, and
  *
  * Key-related SecItemImportExportKeyParameters fields
  * -----------------------------------------------
  *
  * If importKeychain is NULL, the kSecKeyImportOnlyOne bit in the flags
  * argument is ignored. Otherwise, if the kSecKeyImportOnlyOne bit is set, and
- * there is more than one key in the incoming external representation, no 
+ * there is more than one key in the incoming external representation, no
  * items will be imported to the specified keychain and errSecMultipleKeys will
  * items will be imported to the specified keychain and errSecMultipleKeys will
- * be returned. 
- * 
+ * be returned.
+ *
  * The accessRef field allows the caller to specify the initial SecAccessRef
  * The accessRef field allows the caller to specify the initial SecAccessRef
- * for imported private keys. If more than one private key is being imported, 
- * all private keys get the same initial SecAccessRef. If this field is NULL 
- * when private keys are being imported, then the ACL attached to imported 
- * private keys depends on the kSecKeyNoAccessControl bit in the specified 
+ * for imported private keys. If more than one private key is being imported,
+ * all private keys get the same initial SecAccessRef. If this field is NULL
+ * when private keys are being imported, then the ACL attached to imported
+ * private keys depends on the kSecKeyNoAccessControl bit in the specified
  * keyParams->flags. If this bit is 0, or keyParams is NULL, the default ACL
  * keyParams->flags. If this bit is 0, or keyParams is NULL, the default ACL
- * will be used. If this bit is 1, no ACL will be attached to imported 
+ * will be used. If this bit is 1, no ACL will be attached to imported
  * private keys.
  *
  * keyUsage and keyAttributes specify the low-level usage and attribute flags
  * private keys.
  *
  * keyUsage and keyAttributes specify the low-level usage and attribute flags
- * of imported keys. Each is a word of bits. The default value for keyUsage
- * (used when keyParams is NULL or if keyParams->keyUsage is zero) is 
- * CSSM_KEYUSE_ANY. The default value for keyAttributes defaults is
- * CSSM_KEYATTR_SENSITIVE | CSSM_KEYATTR_EXTRACTABLE; the CSSM_KEYATTR_PERMANENT 
- * bit is also added to the default if a non-NULL importKeychain is provided. 
- *
- * The following are valid bits in keyAttributes:
- *
- *   CSSM_KEYATTR_PERMANENT
- *   CSSM_KEYATTR_SENSITIVE
- *   CSSM_KEYATTR_EXTRACTABLE
- *
- * If the CSSM_KEYATTR_PERMANENT is set then the importKeychain argument must
- * be valid or errSecInvalidKeychain will be returned if in fact any keys are found
- * in the external representation. 
- *
- * Note that if the caller does not set the CSSM_KEYATTR_EXTRACTABLE, this key
- * will never be able to be extracted from the keychain in any form, not even
- * in wrapped form. The CSSM_KEYATTR_SENSITIVE indicates that the key can only 
- * be extracted in wrapped form. 
- *
- * The CSSM_KEYATTR_RETURN_xxx bits are always forced to 
- * CSSM_KEYATTR_RETURN_REF regardless of the specified keyAttributes
- * field. 
- *
- * When importing SecKeyRefs in one of the wrapped formats 
- * (kSecFormatWrappedOpenSSL, kSecFormatWrappedSSH, 
- * kSecFormatWrappedPKCS8), or in PKCS12 format, caller must 
- * either explicitly specify the passphrase field or set 
+ * of imported keys. These fields contain a CFArray whose values are constants
+ * from SecItem.h.
+ *
+ * Possible values in the keyUsage array:
+ *
+ *   kSecAttrCanEncrypt
+ *   kSecAttrCanDecrypt
+ *   kSecAttrCanDerive
+ *   kSecAttrCanSign
+ *   kSecAttrCanVerify
+ *   kSecAttrCanWrap
+ *   kSecAttrCanUnwrap
+ *
+ * If keyUsage is set to NULL, then any key usage is permitted.
+ *
+ * Possible values in the keyAttributes array:
+ *
+ *   kSecAttrIsPermanent
+ *   kSecAttrIsSensitive
+ *   kSecAttrIsExtractable
+ *
+ * If keyAttributes is set to NULL, then default values are used:
+ *   kSecAttrIsPermanent if an import keychain is specified
+ *   kSecAttrIsSensitive for non-public keys
+ *   kSecAttrIsExtractable
+ *
+ * If the kSecAttrIsPermanent attribute is set, then the
+ * importKeychain argument must be valid or errSecInvalidKeychain
+ * will be returned even if keys were able to be imported.
+ *
+ * Note that if the caller provides a keyAttributes array but
+ * does not set kSecAttrIsExtractable, this key will never be
+ * able to be extracted from the keychain in any form, not even
+ * in wrapped form. kSecAttrIsSensitive indicates that the key
+ * can only be extracted in wrapped form.
+ *
+ * When importing SecKeyRefs in one of the wrapped formats
+ * (kSecFormatWrappedOpenSSL, kSecFormatWrappedSSH,
+ * kSecFormatWrappedPKCS8), or in PKCS12 format, caller must
+ * either explicitly specify the passphrase field or set
  * the kSecKeySecurePassphrase bit in SecKeyImportExportFlags.
  *
  * If kSecKeySecurePassphrase is selected, caller can optionally
  * the kSecKeySecurePassphrase bit in SecKeyImportExportFlags.
  *
  * If kSecKeySecurePassphrase is selected, caller can optionally
- * specify strings for the passphrase panel's title bar and for 
- * the prompt which appears in the panel via the alertTitle and 
+ * specify strings for the passphrase panel's title bar and for
+ * the prompt which appears in the panel via the alertTitle and
  * alertPrompt fields in SecItemImportExportKeyParameters.
  *
  * If an explicit passphrase is specified, note that PKCS12
  * explicitly requires that passphrases are in Unicode format;
  * passing in a CFStringRef as the passphrase is the safest way
  * alertPrompt fields in SecItemImportExportKeyParameters.
  *
  * If an explicit passphrase is specified, note that PKCS12
  * explicitly requires that passphrases are in Unicode format;
  * passing in a CFStringRef as the passphrase is the safest way
- * to ensure that this requirement is met (and that the result 
+ * to ensure that this requirement is met (and that the result
  * will be compatible with other implementations). If a CFDataRef
  * will be compatible with other implementations). If a CFDataRef
- * is supplied as the passphrase for a PKCS12 export operation, 
+ * is supplied as the passphrase for a PKCS12 export operation,
  * the referent data is assumed to be in UTF8 form and will be
  * the referent data is assumed to be in UTF8 form and will be
- * converted as appropriate. 
+ * converted as appropriate.
 
  * If no key items are being imported, the keyParams argument may be NULL.
  *
  * The SecItemImportExportFlags argument is currently unused; caller should pass
  * in 0.
 
  * If no key items are being imported, the keyParams argument may be NULL.
  *
  * The SecItemImportExportFlags argument is currently unused; caller should pass
  * in 0.
- */    
-                               
+ */
+
 OSStatus SecItemImport(
        CFDataRef                                                       importedData,
        CFStringRef                                                     fileNameOrExtension,    /* optional */
        SecExternalFormat                                       *inputFormat,                   /* optional, IN/OUT */
        SecExternalItemType                                     *itemType,                              /* optional, IN/OUT */
 OSStatus SecItemImport(
        CFDataRef                                                       importedData,
        CFStringRef                                                     fileNameOrExtension,    /* optional */
        SecExternalFormat                                       *inputFormat,                   /* optional, IN/OUT */
        SecExternalItemType                                     *itemType,                              /* optional, IN/OUT */
-       SecItemImportExportFlags                        flags, 
+       SecItemImportExportFlags                        flags,
        const SecItemImportExportKeyParameters  *keyParams,                             /* optional */
        SecKeychainRef                                          importKeychain,                 /* optional */
        CFArrayRef                                                      *outItems)                              /* optional */
        const SecItemImportExportKeyParameters  *keyParams,                             /* optional */
        SecKeychainRef                                          importKeychain,                 /* optional */
        CFArrayRef                                                      *outItems)                              /* optional */
index 2f1bafad2d3df6e078ad432c890df6f381482a59..6440c796727628d4dd40162fba2c21a5b0a48109 100644 (file)
@@ -29,8 +29,8 @@
 #include "SecImportExportUtils.h"
 #include "SecNetscapeTemplates.h"
 #include "Certificate.h"
 #include "SecImportExportUtils.h"
 #include "SecNetscapeTemplates.h"
 #include "Certificate.h"
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 #include <security_pkcs12/SecPkcs12.h>
 #include <security_pkcs12/SecPkcs12.h>
+#include <Security/SecBase.h>
 #include <Security/SecCmsDecoder.h>
 #include <Security/SecCmsEncoder.h>
 #include <Security/SecCmsMessage.h>
 #include <Security/SecCmsDecoder.h>
 #include <Security/SecCmsEncoder.h>
 #include <Security/SecCmsMessage.h>
@@ -55,7 +55,7 @@ OSStatus impExpPkcs12Export(
        CFMutableDataRef                                        outData)                // output appended here
 {
        SecPkcs12CoderRef   p12Coder;
        CFMutableDataRef                                        outData)                // output appended here
 {
        SecPkcs12CoderRef   p12Coder;
-       OSStatus                        ortn = noErr;
+       OSStatus                        ortn = errSecSuccess;
        CFMutableArrayRef   exportItems;                        // SecKeychainItemRefs
        CFDataRef                       tmpData = NULL;
        CSSM_CSP_HANDLE         cspHand;
        CFMutableArrayRef   exportItems;                        // SecKeychainItemRefs
        CFDataRef                       tmpData = NULL;
        CSSM_CSP_HANDLE         cspHand;
@@ -187,14 +187,14 @@ OSStatus impExpPkcs7Export(
        
        if(numCerts == 0) {
                SecImpExpDbg("impExpPkcs7Export: no certs to export");
        
        if(numCerts == 0) {
                SecImpExpDbg("impExpPkcs7Export: no certs to export");
-               return noErr;
+               return errSecSuccess;
        }
        
     /* create the message object */
     SecCmsMessageRef cmsg = SecCmsMessageCreate(NULL);
     if(cmsg == NULL) {
                SecImpExpDbg("impExpPkcs7Export: SecCmsMessageCreate failure");
        }
        
     /* create the message object */
     SecCmsMessageRef cmsg = SecCmsMessageCreate(NULL);
     if(cmsg == NULL) {
                SecImpExpDbg("impExpPkcs7Export: SecCmsMessageCreate failure");
-               return internalComponentErr;
+               return errSecInternalComponent;
        }
 
        /* get first cert */
        }
 
        /* get first cert */
@@ -202,7 +202,7 @@ OSStatus impExpPkcs7Export(
        assert(exportRep != NULL);
        if(exportRep->externType() != kSecItemTypeCertificate) {
                SecImpExpDbg("impExpPkcs7Export: non-cert item");
        assert(exportRep != NULL);
        if(exportRep->externType() != kSecItemTypeCertificate) {
                SecImpExpDbg("impExpPkcs7Export: non-cert item");
-               ortn = paramErr;
+               ortn = errSecParam;
                goto errOut;
        }
        certRef = (SecCertificateRef)exportRep->kcItem();
                goto errOut;
        }
        certRef = (SecCertificateRef)exportRep->kcItem();
@@ -211,7 +211,7 @@ OSStatus impExpPkcs7Export(
     sigd = SecCmsSignedDataCreateCertsOnly(cmsg, certRef, false);
        if(sigd == NULL) {
                SecImpExpDbg("impExpPkcs7Export: SecCmsSignedDataCreateCertsOnly failure");
     sigd = SecCmsSignedDataCreateCertsOnly(cmsg, certRef, false);
        if(sigd == NULL) {
                SecImpExpDbg("impExpPkcs7Export: SecCmsSignedDataCreateCertsOnly failure");
-               ortn = internalComponentErr;
+               ortn = errSecInternalComponent;
                goto errOut;
        }
 
                goto errOut;
        }
 
@@ -220,7 +220,7 @@ OSStatus impExpPkcs7Export(
                assert(exportRep != NULL);
                if(exportRep->externType() != kSecItemTypeCertificate) {
                        SecImpExpDbg("impExpPkcs7Export: non-cert item");
                assert(exportRep != NULL);
                if(exportRep->externType() != kSecItemTypeCertificate) {
                        SecImpExpDbg("impExpPkcs7Export: non-cert item");
-                       ortn = paramErr;
+                       ortn = errSecParam;
                        goto errOut;
                }
                certRef = (SecCertificateRef)exportRep->kcItem();
                        goto errOut;
                }
                certRef = (SecCertificateRef)exportRep->kcItem();
@@ -234,7 +234,7 @@ OSStatus impExpPkcs7Export(
     cinfo = SecCmsMessageGetContentInfo(cmsg);
        if(cinfo == NULL) {
                SecImpExpDbg("impExpPkcs7Export: SecCmsMessageGetContentInfo returned NULL");
     cinfo = SecCmsMessageGetContentInfo(cmsg);
        if(cinfo == NULL) {
                SecImpExpDbg("impExpPkcs7Export: SecCmsMessageGetContentInfo returned NULL");
-               ortn = internalComponentErr;
+               ortn = errSecInternalComponent;
                goto errOut;
        }
     ortn = SecCmsContentInfoSetContentSignedData(cmsg, cinfo, sigd);
                goto errOut;
        }
     ortn = SecCmsContentInfoSetContentSignedData(cmsg, cinfo, sigd);
@@ -245,7 +245,7 @@ OSStatus impExpPkcs7Export(
     cinfo = SecCmsSignedDataGetContentInfo(sigd);
        if(cinfo == NULL) {
                SecImpExpDbg("impExpPkcs7Export: SecCmsSignedDataGetContentInfo returned NULL");
     cinfo = SecCmsSignedDataGetContentInfo(sigd);
        if(cinfo == NULL) {
                SecImpExpDbg("impExpPkcs7Export: SecCmsSignedDataGetContentInfo returned NULL");
-               ortn = internalComponentErr;
+               ortn = errSecInternalComponent;
                goto errOut;
        }
     ortn = SecCmsContentInfoSetContentData(cmsg, cinfo, NULL, 
                goto errOut;
        }
     ortn = SecCmsContentInfoSetContentData(cmsg, cinfo, NULL, 
@@ -361,7 +361,7 @@ OSStatus impExpPkcs12Import(
        }
        else {
                if(cspHand == CSSM_INVALID_HANDLE) {
        }
        else {
                if(cspHand == CSSM_INVALID_HANDLE) {
-                       ortn = paramErr;
+                       ortn = errSecParam;
                        goto errOut;
                }
                ortn = SecPkcs12SetCspHandle(p12Coder, cspHand);
                        goto errOut;
                }
                ortn = SecPkcs12SetCspHandle(p12Coder, cspHand);
@@ -582,7 +582,7 @@ OSStatus impExpPkcs12Import(
                                SecIdentityRef idRef = NULL;
                                ortn = SecIdentityCreateWithCertificate(importKeychain,
                                        importedCertRef, &idRef);
                                SecIdentityRef idRef = NULL;
                                ortn = SecIdentityCreateWithCertificate(importKeychain,
                                        importedCertRef, &idRef);
-                               if(ortn == noErr) {
+                               if(ortn == errSecSuccess) {
                                        /*
                                         * Got one!
                                         * 
                                        /*
                                         * Got one!
                                         * 
@@ -652,14 +652,14 @@ errOut:
        */
 #if 0
        if(privKeys) {
        */
 #if 0
        if(privKeys) {
-               if(ortn == noErr) {             // TBD OR keys are SecKeyRefs
+               if(ortn == errSecSuccess) {             // TBD OR keys are SecKeyRefs
                        numKeys = CFArrayGetCount(privKeys);
                        for(dex=0; dex<numKeys; dex++) {
                                SecKeyRef keyRef;
                                CSSM_KEY_PTR privKey = 
                                        (CSSM_KEY_PTR)CFArrayGetValueAtIndex(privKeys, dex);
                                assert(privKey != NULL);
                        numKeys = CFArrayGetCount(privKeys);
                        for(dex=0; dex<numKeys; dex++) {
                                SecKeyRef keyRef;
                                CSSM_KEY_PTR privKey = 
                                        (CSSM_KEY_PTR)CFArrayGetValueAtIndex(privKeys, dex);
                                assert(privKey != NULL);
-                               if(ortn == noErr) {
+                               if(ortn == errSecSuccess) {
                                        /* only do this on complete success so far */
                                        ortn = SecKeyCreateWithCSSMKey(privKey, &keyRef);
                                        if(ortn) {
                                        /* only do this on complete success so far */
                                        ortn = SecKeyCreateWithCSSMKey(privKey, &keyRef);
                                        if(ortn) {
@@ -707,7 +707,7 @@ OSStatus impExpPkcs7Import(
     int                                                i;
     SECOidTag                          contentTypeTag;
     OSStatus                           result;
     int                                                i;
     SECOidTag                          contentTypeTag;
     OSStatus                           result;
-       OSStatus                                ourRtn = noErr;
+       OSStatus                                ourRtn = errSecSuccess;
 
     /* decode the message */
     result = SecCmsDecoderCreate (NULL, NULL, NULL, NULL, NULL, NULL, NULL, &decoderContext);
 
     /* decode the message */
     result = SecCmsDecoderCreate (NULL, NULL, NULL, NULL, NULL, NULL, NULL, &decoderContext);
@@ -836,7 +836,7 @@ OSStatus impExpNetscapeCertImport(
                        return ortn;
                }
        } 
                        return ortn;
                }
        } 
-       return noErr;
+       return errSecSuccess;
 }
 
 #pragma mark --- Utilities ---
 }
 
 #pragma mark --- Utilities ---
@@ -846,7 +846,7 @@ OSStatus impExpImportCertCommon(
        SecKeychainRef          importKeychain, // optional
        CFMutableArrayRef       outArray)               // optional, append here 
 {
        SecKeychainRef          importKeychain, // optional
        CFMutableArrayRef       outArray)               // optional, append here 
 {
-       OSStatus ortn = noErr;
+       OSStatus ortn = errSecSuccess;
        SecCertificateRef certRef;
        
        if (!cdata)
        SecCertificateRef certRef;
        
        if (!cdata)
index 5094769ee2adb02f449bf85da4e0204059255253..d72d2e61406989daf766427bf7cb7a16dd15ec2f 100644 (file)
@@ -41,7 +41,6 @@
 #include <security_cdsa_client/securestorage.h>
 #include <security_cdsa_client/dlclient.h>
 #include <Security/cssmapi.h>
 #include <security_cdsa_client/securestorage.h>
 #include <security_cdsa_client/dlclient.h>
 #include <Security/cssmapi.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 
 /*
  * Key attrribute names and values.
 
 /*
  * Key attrribute names and values.
@@ -94,7 +93,7 @@ static CSSM_RETURN impExpSetKeyLabel(
        SecItemClass itemClass = (cssmKey->KeyHeader.KeyClass == 
                CSSM_KEYCLASS_PRIVATE_KEY) ? kSecPrivateKeyItemClass :
                        kSecPublicKeyItemClass;
        SecItemClass itemClass = (cssmKey->KeyHeader.KeyClass == 
                CSSM_KEYCLASS_PRIVATE_KEY) ? kSecPrivateKeyItemClass :
                        kSecPublicKeyItemClass;
-       SecKeychainAttribute kcAttr = {kSecKeyLabel, existKeyLabel->Length, existKeyLabel->Data};
+       SecKeychainAttribute kcAttr = {kSecKeyLabel, (UInt32)existKeyLabel->Length, existKeyLabel->Data};
        SecKeychainAttributeList kcAttrList = {1, &kcAttr};
        SecKeychainSearchRef srchRef = NULL;
        OSStatus ortn;
        SecKeychainAttributeList kcAttrList = {1, &kcAttr};
        SecKeychainSearchRef srchRef = NULL;
        OSStatus ortn;
@@ -115,9 +114,9 @@ static CSSM_RETURN impExpSetKeyLabel(
        }
        #ifndef NDEBUG
        ortn = SecKeychainSearchCopyNext(srchRef, &itemRef);
        }
        #ifndef NDEBUG
        ortn = SecKeychainSearchCopyNext(srchRef, &itemRef);
-       if(ortn == noErr) {
+       if(ortn == errSecSuccess) {
                SecImpExpDbg("impExpSetKeyLabel: found second key with same label!");
                SecImpExpDbg("impExpSetKeyLabel: found second key with same label!");
-               crtn = internalComponentErr;
+               crtn = errSecInternalComponent;
                goto errOut;
        }
        #endif  /* NDEBUG */
                goto errOut;
        }
        #endif  /* NDEBUG */
@@ -125,10 +124,10 @@ static CSSM_RETURN impExpSetKeyLabel(
        /* modify two attributes... */
        SecKeychainAttribute modAttrs[2];
        modAttrs[0].tag    = kSecKeyLabel;
        /* modify two attributes... */
        SecKeychainAttribute modAttrs[2];
        modAttrs[0].tag    = kSecKeyLabel;
-       modAttrs[0].length = keyDigest.Length;
+       modAttrs[0].length = (UInt32)keyDigest.Length;
        modAttrs[0].data   = keyDigest.Data;
        modAttrs[1].tag    = kSecKeyPrintName;
        modAttrs[0].data   = keyDigest.Data;
        modAttrs[1].tag    = kSecKeyPrintName;
-       modAttrs[1].length = newPrintName->Length;
+       modAttrs[1].length = (UInt32)newPrintName->Length;
        modAttrs[1].data   = newPrintName->Data;
        kcAttrList.count = 2;
        kcAttrList.attr = modAttrs;
        modAttrs[1].data   = newPrintName->Data;
        kcAttrList.count = 2;
        kcAttrList.attr = modAttrs;
@@ -261,7 +260,7 @@ OSStatus impExpKeyNotify(
                        recordType = CSSM_DL_DB_RECORD_SYMMETRIC_KEY;
                        break;
                default:
                        recordType = CSSM_DL_DB_RECORD_SYMMETRIC_KEY;
                        break;
                default:
-                       return paramErr;
+                       return errSecParam;
        }
        assert(importKeychain != NULL);
        Keychain keychain = KeychainImpl::required(importKeychain);
        }
        assert(importKeychain != NULL);
        Keychain keychain = KeychainImpl::required(importKeychain);
@@ -293,7 +292,7 @@ OSStatus impExpKeyNotify(
        Item keyItem = keychain->item(recordType, uniqueId);
        keychain->postEvent(kSecAddEvent, keyItem);
 
        Item keyItem = keychain->item(recordType, uniqueId);
        keychain->postEvent(kSecAddEvent, keyItem);
 
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -457,7 +456,7 @@ OSStatus impExpImportKeyCommon(
                crtn = impExpAddContextAttribute(ccHand, 
                        CSSM_ATTRIBUTE_EFFECTIVE_BITS,
                        sizeof(uint32),
                crtn = impExpAddContextAttribute(ccHand, 
                        CSSM_ATTRIBUTE_EFFECTIVE_BITS,
                        sizeof(uint32),
-                       (void *)unwrapParams->effectiveKeySizeInBits);
+                       (void *)((size_t) unwrapParams->effectiveKeySizeInBits));
                if(crtn) {
                        SecImpExpDbg("impExpImportKeyCommon: CSSM_UpdateContextAttributes error");
                        goto errOut;
                if(crtn) {
                        SecImpExpDbg("impExpImportKeyCommon: CSSM_UpdateContextAttributes error");
                        goto errOut;
@@ -472,7 +471,7 @@ OSStatus impExpImportKeyCommon(
                crtn = impExpAddContextAttribute(ccHand, 
                        CSSM_ATTRIBUTE_ROUNDS,
                        sizeof(uint32),
                crtn = impExpAddContextAttribute(ccHand, 
                        CSSM_ATTRIBUTE_ROUNDS,
                        sizeof(uint32),
-                       (void *)unwrapParams->rounds);
+                       (void *)((size_t)unwrapParams->rounds));
                if(crtn) {
                        SecImpExpDbg("impExpImportKeyCommon: CSSM_UpdateContextAttributes error");
                        goto errOut;
                if(crtn) {
                        SecImpExpDbg("impExpImportKeyCommon: CSSM_UpdateContextAttributes error");
                        goto errOut;
@@ -490,7 +489,7 @@ OSStatus impExpImportKeyCommon(
                        crtn = impExpAddContextAttribute(ccHand, 
                                CSSM_ATTRIBUTE_BLOCK_SIZE,
                                sizeof(uint32),
                        crtn = impExpAddContextAttribute(ccHand, 
                                CSSM_ATTRIBUTE_BLOCK_SIZE,
                                sizeof(uint32),
-                               (void *)unwrapParams->blockSizeInBits);
+                               (void *)((size_t)unwrapParams->blockSizeInBits));
                        if(crtn) {
                                SecImpExpDbg("impExpImportKeyCommon: CSSM_UpdateContextAttributes error");
                                goto errOut;
                        if(crtn) {
                                SecImpExpDbg("impExpImportKeyCommon: CSSM_UpdateContextAttributes error");
                                goto errOut;
@@ -678,7 +677,7 @@ CSSM_RETURN impExpExportKeyCommon(
                crtn = impExpAddContextAttribute(ccHand,
                        CSSM_ATTRIBUTE_WRAPPED_KEY_FORMAT,
                        sizeof(uint32),         
                crtn = impExpAddContextAttribute(ccHand,
                        CSSM_ATTRIBUTE_WRAPPED_KEY_FORMAT,
                        sizeof(uint32),         
-                       (void *)wrapFormat);
+                       (void *)((size_t)wrapFormat));
                if(crtn) {
                        SecImpExpDbg("impExpExportKeyCommon AddContextAttribute error (1)");
                        CSSM_DeleteContext(ccHand);
                if(crtn) {
                        SecImpExpDbg("impExpExportKeyCommon AddContextAttribute error (1)");
                        CSSM_DeleteContext(ccHand);
@@ -690,7 +689,7 @@ CSSM_RETURN impExpExportKeyCommon(
                crtn = impExpAddContextAttribute(ccHand,
                        blobAttrType,
                        sizeof(uint32),         
                crtn = impExpAddContextAttribute(ccHand,
                        blobAttrType,
                        sizeof(uint32),         
-                       (void *)blobForm);
+                       (void *)((size_t)blobForm));
                if(crtn) {
                        SecImpExpDbg("impExpExportKeyCommon AddContextAttribute error");
                        return crtn;
                if(crtn) {
                        SecImpExpDbg("impExpExportKeyCommon AddContextAttribute error");
                        return crtn;
@@ -701,7 +700,6 @@ CSSM_RETURN impExpExportKeyCommon(
        if(descData) {
                dData = *descData;
        }
        if(descData) {
                dData = *descData;
        }
-       memset(wrappedKey, 0, sizeof(wrappedKey));
 
        crtn = CSSM_WrapKey(ccHand,
                creds,
 
        crtn = CSSM_WrapKey(ccHand,
                creds,
index e2142775542d2e3cb80a636ec2708adf9f679b69..7ab90d1c5f2ead1bc2f4c3d7b08d250cecb772e7 100644 (file)
@@ -34,7 +34,6 @@
 #include <ctype.h>
 #include <CommonCrypto/CommonDigest.h> /* for CC_MD5_DIGEST_LENGTH */
 #include <security_utilities/debugging.h>
 #include <ctype.h>
 #include <CommonCrypto/CommonDigest.h> /* for CC_MD5_DIGEST_LENGTH */
 #include <security_utilities/debugging.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 #include <security_cdsa_utils/cuCdsaUtils.h>
 
 #define SecSSHDbg(args...)     secdebug("openssh", ## args)
 #include <security_cdsa_utils/cuCdsaUtils.h>
 
 #define SecSSHDbg(args...)     secdebug("openssh", ## args)
@@ -164,7 +163,7 @@ static char *genPrintName(
        const char *header,             // e.g. SSHv2_PUB_KEY_NAME
        const char *comment)    // optional, from key 
 {
        const char *header,             // e.g. SSHv2_PUB_KEY_NAME
        const char *comment)    // optional, from key 
 {
-       unsigned totalLen = strlen(header) + 1;
+       size_t totalLen = strlen(header) + 1;
        if(comment) {
                /* append ": <comment>" */
                totalLen += strlen(comment);
        if(comment) {
                /* append ": <comment>" */
                totalLen += strlen(comment);
@@ -252,7 +251,7 @@ static char *opensshV1PrivComment(
         * (numBits + 7)/8 bytes of data
         */
        /* length: ID string, NULL, Cipher, 4-byte spare */
         * (numBits + 7)/8 bytes of data
         */
        /* length: ID string, NULL, Cipher, 4-byte spare */
-       unsigned len = strlen(authfile_id_string);
+       size_t len = strlen(authfile_id_string);
        if(keyLen < (len + 6)) {
                return NULL;
        }
        if(keyLen < (len + 6)) {
                return NULL;
        }
@@ -304,7 +303,7 @@ char *impExpOpensshInferPrintName(
        SecExternalFormat externFormat)
 {
        const unsigned char *key = (const unsigned char *)CFDataGetBytePtr(external);
        SecExternalFormat externFormat)
 {
        const unsigned char *key = (const unsigned char *)CFDataGetBytePtr(external);
-       unsigned keyLen = CFDataGetLength(external);
+       unsigned keyLen = (unsigned)CFDataGetLength(external);
        switch(externType) {
                case kSecItemTypePublicKey:
                        switch(externFormat) {
        switch(externType) {
                case kSecItemTypePublicKey:
                        switch(externFormat) {
@@ -358,7 +357,7 @@ void impExpOpensshInferDescData(
                NULL,                   // don't need the data
                NULL);
        if(ortn) {
                NULL,                   // don't need the data
                NULL);
        if(ortn) {
-               SecSSHDbg("SecKeychainItemCopyAttributesAndData returned %ld", ortn);
+               SecSSHDbg("SecKeychainItemCopyAttributesAndData returned %ld", (unsigned long)ortn);
                return;
        }
        /* subsequent errors to errOut: */
                return;
        }
        /* subsequent errors to errOut: */
@@ -460,7 +459,7 @@ static CSSM_RETURN openSSHv1DeriveKey(
        memset(&seed, 0, sizeof(seed));
        if(cfPhrase != NULL) {
                /* TBD - caller-supplied empty passphrase means "export in the clear" */
        memset(&seed, 0, sizeof(seed));
        if(cfPhrase != NULL) {
                /* TBD - caller-supplied empty passphrase means "export in the clear" */
-               unsigned len = CFDataGetLength(cfPhrase);
+               size_t len = CFDataGetLength(cfPhrase);
                seed.Param.Data = (uint8 *)malloc(len);
                seed.Param.Length = len;
                memmove(seed.Param.Data, CFDataGetBytePtr(cfPhrase), len);
                seed.Param.Data = (uint8 *)malloc(len);
                seed.Param.Length = len;
                memmove(seed.Param.Data, CFDataGetBytePtr(cfPhrase), len);
@@ -533,7 +532,7 @@ OSStatus impExpWrappedOpenSSHImport(
 
        assert(cspHand != 0);
        if(keyParams == NULL) {
 
        assert(cspHand != 0);
        if(keyParams == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        memset(&unwrapParams, 0, sizeof(unwrapParams));
 
        }
        memset(&unwrapParams, 0, sizeof(unwrapParams));
 
@@ -588,7 +587,7 @@ OSStatus impExpWrappedOpenSSHExport(
        CSSM_RETURN crtn;
        
        if(keyParams == NULL) {
        CSSM_RETURN crtn;
        
        if(keyParams == NULL) {
-               return paramErr;
+               return errSecParam;
        }
 
        /* we need a CSPDL handle - try to get it from the key */       
        }
 
        /* we need a CSPDL handle - try to get it from the key */       
index e504aef509d30b8d7e1b95b0b71a0b2822312bee..95958f4cf9edbbc2dfc348c10d3287ae864f64ed 100644 (file)
@@ -28,7 +28,6 @@
 #include "SecImportExportUtils.h"
 #include <security_cdsa_utils/cuEnc64.h>
 #include <security_cdsa_utils/cuPem.h>
 #include "SecImportExportUtils.h"
 #include <security_cdsa_utils/cuEnc64.h>
 #include <security_cdsa_utils/cuPem.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
@@ -46,7 +45,7 @@ static const char *findStr(
 {
        /* probably not the hottest string search algorithm... */
        const char *cp;
 {
        /* probably not the hottest string search algorithm... */
        const char *cp;
-       unsigned srchStrLen = strlen(str);
+       unsigned srchStrLen = (unsigned)strlen(str);
        char c = str[0];
        
        /* last char * we can search in inText for start of str */
        char c = str[0];
        
        /* last char * we can search in inText for start of str */
@@ -98,7 +97,7 @@ static const char *getLine(
        }
        unsigned linelen;
        if(newline) {
        }
        unsigned linelen;
        if(newline) {
-               linelen = newline - inText;
+               linelen = (unsigned)(newline - inText);
        }
        else {
                linelen = *consumed;
        }
        else {
                linelen = *consumed;
@@ -163,7 +162,7 @@ static OSStatus impExpImportSinglePEM(
        const char *currLine = NULL;            // mallocd by getLine()
        const char *lastCp = currCp;
        CFMutableArrayRef pemParamLines = NULL;
        const char *currLine = NULL;            // mallocd by getLine()
        const char *lastCp = currCp;
        CFMutableArrayRef pemParamLines = NULL;
-       OSStatus ortn = noErr;
+       OSStatus ortn = errSecSuccess;
        CFDataRef cdata = NULL;
        Security::KeychainCore::SecImportRep *rep = NULL;
        const char *start64;
        CFDataRef cdata = NULL;
        Security::KeychainCore::SecImportRep *rep = NULL;
        const char *start64;
@@ -181,7 +180,7 @@ static OSStatus impExpImportSinglePEM(
        const char *startLine = findStr(currCp, lenToGo, "-----BEGIN");
        if(startLine != NULL) {
                /* possibly skip over leading garbage */
        const char *startLine = findStr(currCp, lenToGo, "-----BEGIN");
        if(startLine != NULL) {
                /* possibly skip over leading garbage */
-               consumed = startLine - currCp;
+               consumed = (unsigned)(startLine - currCp);
                lenToGo -= consumed;
                currCp = startLine;
                
                lenToGo -= consumed;
                currCp = startLine;
                
@@ -235,7 +234,7 @@ static OSStatus impExpImportSinglePEM(
                lastCp = currCp;
                
                bool skipThis = false;
                lastCp = currCp;
                
                bool skipThis = false;
-               unsigned lineLen = strlen(currLine);
+               unsigned lineLen = (unsigned)strlen(currLine);
                if(lineLen == 0) {
                        /* empty line */
                        skipThis = true;
                if(lineLen == 0) {
                        /* empty line */
                        skipThis = true;
@@ -297,7 +296,7 @@ static OSStatus impExpImportSinglePEM(
                        ortn = errSecUnsupportedFormat;
                        goto errOut;
                }
                        ortn = errSecUnsupportedFormat;
                        goto errOut;
                }
-               base64Len = end64 - start64;
+               base64Len = (unsigned)(end64 - start64);
        }
        /* else no END, no reason to complain about that as long as base64 decode works OK */
        
        }
        /* else no END, no reason to complain about that as long as base64 decode works OK */
        
@@ -315,7 +314,7 @@ static OSStatus impExpImportSinglePEM(
                pemParamLines);
        CFArrayAppendValue(importReps, rep);
        CFRelease(cdata);               // SecImportRep holds ref
                pemParamLines);
        CFArrayAppendValue(importReps, rep);
        CFRelease(cdata);               // SecImportRep holds ref
-       return noErr;
+       return errSecSuccess;
        
 errOut:
        if(pemParamLines != NULL) {
        
 errOut:
        if(pemParamLines != NULL) {
@@ -340,7 +339,7 @@ OSStatus impExpParsePemToImportRefs(
         */
        const char *currCp = (const char *)CFDataGetBytePtr(importedData);
        const char *cp = currCp;
         */
        const char *currCp = (const char *)CFDataGetBytePtr(importedData);
        const char *cp = currCp;
-       unsigned lenToGo = CFDataGetLength(importedData);
+       unsigned lenToGo = (unsigned)CFDataGetLength(importedData);
        OSStatus ortn;
        
        *isPem = false;
        OSStatus ortn;
        
        *isPem = false;
@@ -351,13 +350,13 @@ OSStatus impExpParsePemToImportRefs(
                if (!isspace(*cp)) {
                        // it's not a space.  Is it a non-ascii character?
                        if (!isascii(*cp)) {
                if (!isspace(*cp)) {
                        // it's not a space.  Is it a non-ascii character?
                        if (!isascii(*cp)) {
-                               return noErr;
+                               return errSecSuccess;
                        }
                        
                        // is it a control character?
                        if (iscntrl(*cp))
                        {
                        }
                        
                        // is it a control character?
                        if (iscntrl(*cp))
                        {
-                               return noErr;
+                               return errSecSuccess;
                        }
                        
                        // no, mark that an acceptable character was encountered and keep going
                        }
                        
                        // no, mark that an acceptable character was encountered and keep going
@@ -367,7 +366,7 @@ OSStatus impExpParsePemToImportRefs(
 
        if (allBlanks)
        {
 
        if (allBlanks)
        {
-               return noErr;
+               return errSecSuccess;
        }
        
        /* search for START line */
        }
        
        /* search for START line */
@@ -376,14 +375,14 @@ OSStatus impExpParsePemToImportRefs(
                /* Assume one item, raw base64 */
                SecImpInferDbg("impExpParsePemToImportRefs no PEM headers, assuming raw base64");
                ortn = impExpImportSinglePEM(currCp, lenToGo, importReps);
                /* Assume one item, raw base64 */
                SecImpInferDbg("impExpParsePemToImportRefs no PEM headers, assuming raw base64");
                ortn = impExpImportSinglePEM(currCp, lenToGo, importReps);
-               if(ortn == noErr) {
+               if(ortn == errSecSuccess) {
                        *isPem = true;
                }
                return ortn;
        }
 
        /* break up input into chunks between START and END lines */
                        *isPem = true;
                }
                return ortn;
        }
 
        /* break up input into chunks between START and END lines */
-       ortn = noErr;
+       ortn = errSecSuccess;
        bool gotSomePem = false;
        do {
                /* get to beginning of START line */
        bool gotSomePem = false;
        do {
                /* get to beginning of START line */
@@ -391,7 +390,7 @@ OSStatus impExpParsePemToImportRefs(
                if(startLine == NULL) {
                        break;
                }
                if(startLine == NULL) {
                        break;
                }
-               unsigned consumed = startLine - currCp;
+               unsigned consumed = (unsigned)(startLine - currCp);
                assert(consumed <= lenToGo);
                lenToGo -= consumed;
                currCp  += consumed;
                assert(consumed <= lenToGo);
                lenToGo -= consumed;
                currCp  += consumed;
@@ -400,7 +399,7 @@ OSStatus impExpParsePemToImportRefs(
                const char *endLine = findStr(currCp+10, lenToGo, "-----END");
                unsigned toDecode = lenToGo;
                if(endLine) {
                const char *endLine = findStr(currCp+10, lenToGo, "-----END");
                unsigned toDecode = lenToGo;
                if(endLine) {
-                       consumed = endLine - startLine;
+                       consumed = (unsigned)(endLine - startLine);
                        assert(consumed <= lenToGo);
                        currCp  += consumed;
                        lenToGo -= consumed;
                        assert(consumed <= lenToGo);
                        currCp  += consumed;
                        lenToGo -= consumed;
@@ -409,7 +408,7 @@ OSStatus impExpParsePemToImportRefs(
                        const char *tmpLine = getLine(endLine, lenToGo, &consumed);
                        assert((tmpLine != NULL) && (tmpLine[0] != 0));
                        /* don't decode the terminators */
                        const char *tmpLine = getLine(endLine, lenToGo, &consumed);
                        assert((tmpLine != NULL) && (tmpLine[0] != 0));
                        /* don't decode the terminators */
-                       toDecode = endLine - startLine + strlen(tmpLine);
+                       toDecode = (unsigned)(endLine - startLine + strlen(tmpLine));
                        free((void *)tmpLine);
                        
                        /* skip past END line and newlines */
                        free((void *)tmpLine);
                        
                        /* skip past END line and newlines */
@@ -428,7 +427,7 @@ OSStatus impExpParsePemToImportRefs(
                }
                gotSomePem = true;
        } while(lenToGo != 0);
                }
                gotSomePem = true;
        } while(lenToGo != 0);
-       if(ortn == noErr) {
+       if(ortn == errSecSuccess) {
                if(gotSomePem) {
                        *isPem = true;
                }
                if(gotSomePem) {
                        *isPem = true;
                }
@@ -455,16 +454,16 @@ OSStatus impExpPemEncodeExportRep(
        
        char headerLine[200];
        if(strlen(pemHeader) > 150) {
        
        char headerLine[200];
        if(strlen(pemHeader) > 150) {
-               return paramErr;
+               return errSecParam;
        }
 
        /* First base64 encode */
        }
 
        /* First base64 encode */
-       enc = cuEnc64WithLines(CFDataGetBytePtr(derData), CFDataGetLength(derData), 
+       enc = cuEnc64WithLines(CFDataGetBytePtr(derData), (unsigned)CFDataGetLength(derData),
                64, &encLen);
        if(enc == NULL) {
                /* malloc error is actually the only known failure */
                SecImpExpDbg("impExpPemEncodeExportRep: cuEnc64WithLines failure");
                64, &encLen);
        if(enc == NULL) {
                /* malloc error is actually the only known failure */
                SecImpExpDbg("impExpPemEncodeExportRep: cuEnc64WithLines failure");
-               return memFullErr;
+               return errSecAllocate;
        }
        
        /* strip off trailing NULL */
        }
        
        /* strip off trailing NULL */
@@ -500,6 +499,6 @@ OSStatus impExpPemEncodeExportRep(
        sprintf(headerLine, "-----END %s-----\n", pemHeader);
        CFDataAppendBytes(outData, (const UInt8 *)headerLine, strlen(headerLine));
        free((void *)enc);
        sprintf(headerLine, "-----END %s-----\n", pemHeader);
        CFDataAppendBytes(outData, (const UInt8 *)headerLine, strlen(headerLine));
        free((void *)enc);
-       return noErr;
+       return errSecSuccess;
 }
        
 }
        
index 451ed93399d23724aa67a671ed158ed73caba62a..bf515717c4fa57a5e3c6a8117cfc31f05d0f7a56 100644 (file)
@@ -47,7 +47,7 @@ extern "C" {
 /*
  * PEM decode incoming data, appending SecImportRep's to specified array.
  * Returned SecImportReps may or may not have a known type and format. 
 /*
  * PEM decode incoming data, appending SecImportRep's to specified array.
  * Returned SecImportReps may or may not have a known type and format. 
- * IF incoming data is not PEM or base64, we return noErr with *isPem false.
+ * IF incoming data is not PEM or base64, we return errSecSuccess with *isPem false.
  */
 OSStatus impExpParsePemToImportRefs(
        CFDataRef                       importedData,
  */
 OSStatus impExpParsePemToImportRefs(
        CFDataRef                       importedData,
index 9e3f21e25e155f123b08aedb3c31513f1b6b5de2..04a217bdc1cf93ab4cc8cf58f7de9cbc9d5b5547 100644 (file)
@@ -41,7 +41,6 @@
 #include "SecPkcs8Templates.h"
 #include "SecImportExportUtils.h"
 #include "SecImportExportCrypto.h"
 #include "SecPkcs8Templates.h"
 #include "SecImportExportUtils.h"
 #include "SecImportExportCrypto.h"
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 #include <security_pkcs12/pkcs12Utils.h>
 #include <security_pkcs12/pkcs12Crypto.h>
 #include <security_asn1/SecNssCoder.h>
 #include <security_pkcs12/pkcs12Utils.h>
 #include <security_pkcs12/pkcs12Crypto.h>
 #include <security_asn1/SecNssCoder.h>
@@ -56,6 +55,7 @@
 #include <security_cdsa_utils/cuCdsaUtils.h>
 #include <openssl/pem.h>
 #include <assert.h>
 #include <security_cdsa_utils/cuCdsaUtils.h>
 #include <openssl/pem.h>
 #include <assert.h>
+#include <Security/SecBase.h>
 
 #define SecPkcs8Dbg(args...)   secdebug("SecPkcs8", ## args)
 
 
 #define SecPkcs8Dbg(args...)   secdebug("SecPkcs8", ## args)
 
@@ -98,7 +98,7 @@ static CSSM_RETURN pkcs5_v15_genKey(
        
        memset(&seed, 0, sizeof(seed));
        if(cfPhrase != NULL) {
        
        memset(&seed, 0, sizeof(seed));
        if(cfPhrase != NULL) {
-               unsigned len = CFDataGetLength(cfPhrase);
+               size_t len = CFDataGetLength(cfPhrase);
                coder.allocItem(seed.Param, len);
                memmove(seed.Param.Data, CFDataGetBytePtr(cfPhrase), len);
                CFRelease(cfPhrase);
                coder.allocItem(seed.Param, len);
                memmove(seed.Param.Data, CFDataGetBytePtr(cfPhrase), len);
                CFRelease(cfPhrase);
@@ -224,7 +224,7 @@ static OSStatus pkcs5_DES_params(
        }
        unwrapParams->encrPad  = CSSM_PADDING_PKCS7;
        unwrapParams->encrMode = CSSM_ALGMODE_CBCPadIV8;
        }
        unwrapParams->encrPad  = CSSM_PADDING_PKCS7;
        unwrapParams->encrMode = CSSM_ALGMODE_CBCPadIV8;
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -286,7 +286,7 @@ static OSStatus pkcs5_RC2_params(
                SecPkcs8Dbg("PKCS8: NO RC2 DEFAULT KEYSIZE!");
                return errSecUnknownFormat;
        }
                SecPkcs8Dbg("PKCS8: NO RC2 DEFAULT KEYSIZE!");
                return errSecUnknownFormat;
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -342,7 +342,7 @@ static OSStatus pkcs5_RC5_params(
                SecPkcs8Dbg("PKCS8: NO RC5 DEFAULT KEYSIZE!");
                return errSecUnknownFormat;
        }
                SecPkcs8Dbg("PKCS8: NO RC5 DEFAULT KEYSIZE!");
                return errSecUnknownFormat;
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 /* 
 }
 
 /* 
@@ -382,7 +382,7 @@ static CSSM_RETURN pbkdf2DeriveKey(
        /* subsequent errors to errOut: */
 
        if(cfPhrase != NULL) {
        /* subsequent errors to errOut: */
 
        if(cfPhrase != NULL) {
-               unsigned len = CFDataGetLength(cfPhrase);
+               size_t len = CFDataGetLength(cfPhrase);
                coder.allocItem(pbeParams.Passphrase, len);
                memmove(pbeParams.Passphrase.Data, 
                        CFDataGetBytePtr(cfPhrase), len);
                coder.allocItem(pbeParams.Passphrase, len);
                memmove(pbeParams.Passphrase.Data, 
                        CFDataGetBytePtr(cfPhrase), len);
@@ -641,7 +641,7 @@ static CSSM_RETURN pkcs12_genKey(
                } 
                catch(...) {
                        SecPkcs8Dbg("PKCS8: p12ImportPassPhrase threw");
                } 
                catch(...) {
                        SecPkcs8Dbg("PKCS8: p12ImportPassPhrase threw");
-                       crtn = memFullErr;
+                       crtn = errSecAllocate;
                        goto errOut;
                }
                CFRelease(phraseStr);
                        goto errOut;
                }
                CFRelease(phraseStr);
@@ -837,7 +837,7 @@ OSStatus impExpPkcs8Export(
        const CSSM_KEY                                  *cssmKey;
        
        if(keyParams == NULL) {
        const CSSM_KEY                                  *cssmKey;
        
        if(keyParams == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        assert(secKey != NULL);
        assert(outData != NULL);
        }
        assert(secKey != NULL);
        assert(outData != NULL);
index d00ce3d849e45e76d10714ddad8c060102aa9d25..ab5e0af1bea4a5c4b3044a76326b3568de99d5ec 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2004,2013 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  *
  * SecImportExportUtils.cpp - misc. utilities for import/export module
  * @APPLE_LICENSE_HEADER_END@
  *
  * SecImportExportUtils.cpp - misc. utilities for import/export module
@@ -29,8 +29,7 @@
 #include "SecIdentityPriv.h"
 #include "SecItem.h"
 #include <security_cdsa_utils/cuCdsaUtils.h>
 #include "SecIdentityPriv.h"
 #include "SecItem.h"
 #include <security_cdsa_utils/cuCdsaUtils.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
-
+#include <Security/SecBase.h>
 #pragma mark --- Debug support ---
 
 #ifndef NDEBUG
 #pragma mark --- Debug support ---
 
 #ifndef NDEBUG
@@ -72,9 +71,9 @@ const char *impExpExtItemTypeStr(
 }
 #endif  /* NDEBUG */
 
 }
 #endif  /* NDEBUG */
 
-/* 
- * Parse file extension and attempt to map it to format and type. Returns true 
- * on success. 
+/*
+ * Parse file extension and attempt to map it to format and type. Returns true
+ * on success.
  */
 bool impExpImportParseFileExten(
        CFStringRef                     fstr,
  */
 bool impExpImportParseFileExten(
        CFStringRef                     fstr,
@@ -85,14 +84,14 @@ bool impExpImportParseFileExten(
                /* nothing to work with */
                return false;
        }
                /* nothing to work with */
                return false;
        }
-       if(CFStringHasSuffix(fstr, CFSTR(".cer")) || 
+       if(CFStringHasSuffix(fstr, CFSTR(".cer")) ||
           CFStringHasSuffix(fstr, CFSTR(".crt"))) {
                *inputFormat = kSecFormatX509Cert;
                *itemType = kSecItemTypeCertificate;
                SecImpInferDbg("Inferring kSecFormatX509Cert from file name");
                return true;
        }
           CFStringHasSuffix(fstr, CFSTR(".crt"))) {
                *inputFormat = kSecFormatX509Cert;
                *itemType = kSecItemTypeCertificate;
                SecImpInferDbg("Inferring kSecFormatX509Cert from file name");
                return true;
        }
-       if(CFStringHasSuffix(fstr, CFSTR(".p12")) || 
+       if(CFStringHasSuffix(fstr, CFSTR(".p12")) ||
           CFStringHasSuffix(fstr, CFSTR(".pfx"))) {
                *inputFormat = kSecFormatPKCS12;
                *itemType = kSecItemTypeAggregate;
           CFStringHasSuffix(fstr, CFSTR(".pfx"))) {
                *inputFormat = kSecFormatPKCS12;
                *itemType = kSecItemTypeAggregate;
@@ -134,7 +133,7 @@ bool impExpImportParseFileExten(
        CFRelease(exten);
        return ortn;
 }
        CFRelease(exten);
        return ortn;
 }
-       
+
 /* do a [NSString stringByDeletingPathExtension] equivalent */
 CFStringRef impExpImportDeleteExtension(
        CFStringRef                     fileStr)
 /* do a [NSString stringByDeletingPathExtension] equivalent */
 CFStringRef impExpImportDeleteExtension(
        CFStringRef                     fileStr)
@@ -144,8 +143,8 @@ CFStringRef impExpImportDeleteExtension(
        if(fileStrData == NULL) {
                return NULL;
        }
        if(fileStrData == NULL) {
                return NULL;
        }
-       
-       CFURLRef urlRef = CFURLCreateFromFileSystemRepresentation(NULL, 
+
+       CFURLRef urlRef = CFURLCreateFromFileSystemRepresentation(NULL,
                CFDataGetBytePtr(fileStrData), CFDataGetLength(fileStrData), false);
        if(urlRef == NULL) {
                CFRelease(fileStrData);
                CFDataGetBytePtr(fileStrData), CFDataGetLength(fileStrData), false);
        if(urlRef == NULL) {
                CFRelease(fileStrData);
@@ -166,11 +165,11 @@ CFStringRef impExpImportDeleteExtension(
 #pragma mark --- mapping of external format to CDSA formats ---
 
 /*
 #pragma mark --- mapping of external format to CDSA formats ---
 
 /*
- * For the record, here is the mapping of SecExternalFormat, algorithm, and key 
- * class to CSSM-style key format (CSSM_KEYBLOB_FORMAT - 
- * CSSM_KEYBLOB_RAW_FORMAT_X509, etc). The entries in the table are the 
+ * For the record, here is the mapping of SecExternalFormat, algorithm, and key
+ * class to CSSM-style key format (CSSM_KEYBLOB_FORMAT -
+ * CSSM_KEYBLOB_RAW_FORMAT_X509, etc). The entries in the table are the
  * last component of a CSSM_KEYBLOB_FORMAT. Format kSecFormatUnknown means
  * last component of a CSSM_KEYBLOB_FORMAT. Format kSecFormatUnknown means
- * "default for specified class and algorithm", which is currently the 
+ * "default for specified class and algorithm", which is currently the
  * same as kSecFormatOpenSSL.
  *
  *                                                                   algorithm/class
  * same as kSecFormatOpenSSL.
  *
  *                                                                   algorithm/class
@@ -187,7 +186,7 @@ CFStringRef impExpImportDeleteExtension(
  * The only external format supported for ECDSA and ECDH keys is kSecFormatOpenSSL,
  * which translates to OPENSSL for private keys and X509 for public keys.
  */
  * The only external format supported for ECDSA and ECDH keys is kSecFormatOpenSSL,
  * which translates to OPENSSL for private keys and X509 for public keys.
  */
+
 /* Arrays expressing the above table. */
 
 /* l.s. dimension is pub/priv for one alg */
 /* Arrays expressing the above table. */
 
 /* l.s. dimension is pub/priv for one alg */
@@ -196,8 +195,8 @@ typedef struct {
        CSSM_KEYBLOB_FORMAT pub;
 } algForms;
 
        CSSM_KEYBLOB_FORMAT pub;
 } algForms;
 
-/* 
- * indices into array of algForms defining all algs' formats for a given  
+/*
+ * indices into array of algForms defining all algs' formats for a given
  * SecExternalFormat
  */
 #define SIE_ALG_RSA            0
  * SecExternalFormat
  */
 #define SIE_ALG_RSA            0
@@ -208,7 +207,7 @@ typedef struct {
 #define SIE_NUM_ALGS   (SIE_ALG_LAST + 1)
 
 /* kSecFormatOpenSSL */
 #define SIE_NUM_ALGS   (SIE_ALG_LAST + 1)
 
 /* kSecFormatOpenSSL */
-static algForms opensslAlgForms[SIE_NUM_ALGS] = 
+static algForms opensslAlgForms[SIE_NUM_ALGS] =
 {
        { CSSM_KEYBLOB_RAW_FORMAT_PKCS1,        CSSM_KEYBLOB_RAW_FORMAT_X509 },         // RSA
        { CSSM_KEYBLOB_RAW_FORMAT_OPENSSL,  CSSM_KEYBLOB_RAW_FORMAT_X509 },             // DSA
 {
        { CSSM_KEYBLOB_RAW_FORMAT_PKCS1,        CSSM_KEYBLOB_RAW_FORMAT_X509 },         // RSA
        { CSSM_KEYBLOB_RAW_FORMAT_OPENSSL,  CSSM_KEYBLOB_RAW_FORMAT_X509 },             // DSA
@@ -217,7 +216,7 @@ static algForms opensslAlgForms[SIE_NUM_ALGS] =
 };
 
 /* kSecFormatBSAFE */
 };
 
 /* kSecFormatBSAFE */
-static algForms bsafeAlgForms[SIE_NUM_ALGS] = 
+static algForms bsafeAlgForms[SIE_NUM_ALGS] =
 {
        { CSSM_KEYBLOB_RAW_FORMAT_PKCS8,        CSSM_KEYBLOB_RAW_FORMAT_PKCS1 },        // RSA
        { CSSM_KEYBLOB_RAW_FORMAT_FIPS186,  CSSM_KEYBLOB_RAW_FORMAT_FIPS186 },  // DSA
 {
        { CSSM_KEYBLOB_RAW_FORMAT_PKCS8,        CSSM_KEYBLOB_RAW_FORMAT_PKCS1 },        // RSA
        { CSSM_KEYBLOB_RAW_FORMAT_FIPS186,  CSSM_KEYBLOB_RAW_FORMAT_FIPS186 },  // DSA
@@ -226,7 +225,7 @@ static algForms bsafeAlgForms[SIE_NUM_ALGS] =
 };
 
 /* kSecFormatSSH (v1) */
 };
 
 /* kSecFormatSSH (v1) */
-static algForms ssh1AlgForms[SIE_NUM_ALGS] = 
+static algForms ssh1AlgForms[SIE_NUM_ALGS] =
 {
        { CSSM_KEYBLOB_RAW_FORMAT_OPENSSH,      CSSM_KEYBLOB_RAW_FORMAT_OPENSSH },      // RSA only
        { CSSM_KEYBLOB_RAW_FORMAT_NONE,         CSSM_KEYBLOB_RAW_FORMAT_NONE },         // DSA not supported
 {
        { CSSM_KEYBLOB_RAW_FORMAT_OPENSSH,      CSSM_KEYBLOB_RAW_FORMAT_OPENSSH },      // RSA only
        { CSSM_KEYBLOB_RAW_FORMAT_NONE,         CSSM_KEYBLOB_RAW_FORMAT_NONE },         // DSA not supported
@@ -235,7 +234,7 @@ static algForms ssh1AlgForms[SIE_NUM_ALGS] =
 };
 
 /* kSecFormatSSHv2 */
 };
 
 /* kSecFormatSSHv2 */
-static algForms ssh2AlgForms[SIE_NUM_ALGS] = 
+static algForms ssh2AlgForms[SIE_NUM_ALGS] =
 {
        { CSSM_KEYBLOB_RAW_FORMAT_NONE,         CSSM_KEYBLOB_RAW_FORMAT_OPENSSH2 },     // RSA - public only
        { CSSM_KEYBLOB_RAW_FORMAT_NONE,         CSSM_KEYBLOB_RAW_FORMAT_OPENSSH2 },     // DSA - public only
 {
        { CSSM_KEYBLOB_RAW_FORMAT_NONE,         CSSM_KEYBLOB_RAW_FORMAT_OPENSSH2 },     // RSA - public only
        { CSSM_KEYBLOB_RAW_FORMAT_NONE,         CSSM_KEYBLOB_RAW_FORMAT_OPENSSH2 },     // DSA - public only
@@ -260,13 +259,13 @@ OSStatus impExpKeyForm(
                /* FIXME ensure caller hasn't specified bogus format */
                *cssmForm = CSSM_KEYBLOB_RAW_FORMAT_NONE;
                *cssmClass = CSSM_KEYCLASS_SESSION_KEY;
                /* FIXME ensure caller hasn't specified bogus format */
                *cssmForm = CSSM_KEYBLOB_RAW_FORMAT_NONE;
                *cssmClass = CSSM_KEYCLASS_SESSION_KEY;
-               return noErr;
+               return errSecSuccess;
        }
        if(externForm == kSecFormatUnknown) {
                /* default is openssl */
                externForm = kSecFormatOpenSSL;
        }
        }
        if(externForm == kSecFormatUnknown) {
                /* default is openssl */
                externForm = kSecFormatOpenSSL;
        }
-       
+
        unsigned algDex;
        switch(alg) {
                case CSSM_ALGID_RSA:
        unsigned algDex;
        switch(alg) {
                case CSSM_ALGID_RSA:
@@ -320,12 +319,12 @@ OSStatus impExpKeyForm(
        }
        else {
                *cssmForm = form;
        }
        else {
                *cssmForm = form;
-               return noErr;
+               return errSecSuccess;
        }
 }
 
 /*
        }
 }
 
 /*
- * Given a raw key blob and zero to three known parameters (type, format, 
+ * Given a raw key blob and zero to three known parameters (type, format,
  * algorithm), figure out all parameters. Used for private and public keys.
  */
 static bool impExpGuessKeyParams(
  * algorithm), figure out all parameters. Used for private and public keys.
  */
 static bool impExpGuessKeyParams(
@@ -335,13 +334,13 @@ static bool impExpGuessKeyParams(
        CSSM_ALGORITHMS                 *keyAlg)                        // IN/OUT
 {
        /* CSSM alg list: RSA, DSA, DH, ECDSA */
        CSSM_ALGORITHMS                 *keyAlg)                        // IN/OUT
 {
        /* CSSM alg list: RSA, DSA, DH, ECDSA */
-       CSSM_ALGORITHMS minAlg           = CSSM_ALGID_RSA;      
+       CSSM_ALGORITHMS minAlg           = CSSM_ALGID_RSA;
        CSSM_ALGORITHMS maxAlg           = CSSM_ALGID_ECDSA;
        SecExternalFormat minForm    = kSecFormatOpenSSL;               // then SSH, BSAFE, then...
        SecExternalFormat maxForm    = kSecFormatSSHv2;
        SecExternalItemType minType  = kSecItemTypePrivateKey;  // just two
        SecExternalItemType maxType  = kSecItemTypePublicKey;
        CSSM_ALGORITHMS maxAlg           = CSSM_ALGID_ECDSA;
        SecExternalFormat minForm    = kSecFormatOpenSSL;               // then SSH, BSAFE, then...
        SecExternalFormat maxForm    = kSecFormatSSHv2;
        SecExternalItemType minType  = kSecItemTypePrivateKey;  // just two
        SecExternalItemType maxType  = kSecItemTypePublicKey;
-       
+
        switch(*externForm) {
                case kSecFormatUnknown:
                        break;                                                          // run through all formats
        switch(*externForm) {
                case kSecFormatUnknown:
                        break;                                                          // run through all formats
@@ -376,7 +375,7 @@ static bool impExpGuessKeyParams(
                default:
                        return false;
        }
                default:
                        return false;
        }
-       
+
        CSSM_ALGORITHMS theAlg;
        SecExternalFormat theForm;
        SecExternalItemType theType;
        CSSM_ALGORITHMS theAlg;
        SecExternalFormat theForm;
        SecExternalItemType theType;
@@ -384,7 +383,7 @@ static bool impExpGuessKeyParams(
        if(cspHand == 0) {
                return CSSMERR_CSSM_ADDIN_LOAD_FAILED;
        }
        if(cspHand == 0) {
                return CSSMERR_CSSM_ADDIN_LOAD_FAILED;
        }
-       
+
        /*
         * Iterate through all set of enabled {alg, type, format}.
         * We do not assume that any of the enums are sequential hence this
        /*
         * Iterate through all set of enabled {alg, type, format}.
         * We do not assume that any of the enums are sequential hence this
@@ -394,7 +393,7 @@ static bool impExpGuessKeyParams(
        for(theAlg=minAlg; ; ) {
                for(theForm=minForm; ; ) {
                        for(theType=minType; ; ) {
        for(theAlg=minAlg; ; ) {
                for(theForm=minForm; ; ) {
                        for(theType=minType; ; ) {
-                               
+
                                /* do super lightweight null unwrap to parse */
                                OSStatus ortn = impExpImportRawKey(keyData,
                                        theForm, theType, theAlg,
                                /* do super lightweight null unwrap to parse */
                                OSStatus ortn = impExpImportRawKey(keyData,
                                        theForm, theType, theAlg,
@@ -404,21 +403,21 @@ static bool impExpGuessKeyParams(
                                        NULL,           // no key params
                                        NULL,           // no printName
                                        NULL);          // no returned items
                                        NULL,           // no key params
                                        NULL,           // no printName
                                        NULL);          // no returned items
-                               if(ortn == noErr) {
+                               if(ortn == errSecSuccess) {
                                        *externForm = theForm;
                                        *itemType = theType;
                                        *keyAlg = theAlg;
                                        ourRtn = true;
                                        goto done;
                                }
                                        *externForm = theForm;
                                        *itemType = theType;
                                        *keyAlg = theAlg;
                                        ourRtn = true;
                                        goto done;
                                }
-                               
+
                                /* next type or break if we're done */
                                if(theType == maxType) {
                                        break;
                                }
                                else switch(theType) {
                                /* next type or break if we're done */
                                if(theType == maxType) {
                                        break;
                                }
                                else switch(theType) {
-                                       case kSecItemTypePrivateKey: 
-                                               theType = kSecItemTypePublicKey; 
+                                       case kSecItemTypePrivateKey:
+                                               theType = kSecItemTypePublicKey;
                                                break;
                                        default:
                                                assert(0);
                                                break;
                                        default:
                                                assert(0);
@@ -432,11 +431,11 @@ static bool impExpGuessKeyParams(
                                break;
                        }
                        else switch(theForm) {
                                break;
                        }
                        else switch(theForm) {
-                               case kSecFormatOpenSSL: 
-                                       theForm = kSecFormatSSH; 
+                               case kSecFormatOpenSSL:
+                                       theForm = kSecFormatSSH;
                                        break;
                                        break;
-                               case kSecFormatSSH: 
-                                       theForm = kSecFormatBSAFE; 
+                               case kSecFormatSSH:
+                                       theForm = kSecFormatBSAFE;
                                        break;
                                case kSecFormatBSAFE:
                                        theForm = kSecFormatSSHv2;
                                        break;
                                case kSecFormatBSAFE:
                                        theForm = kSecFormatSSHv2;
@@ -447,17 +446,17 @@ static bool impExpGuessKeyParams(
                                        goto done;
                        }
                }               /* for each format */
                                        goto done;
                        }
                }               /* for each format */
-               
+
                /* next alg or break if we're done */
                if(theAlg == maxAlg) {
                        break;
                }
                else switch(theAlg) {
                /* next alg or break if we're done */
                if(theAlg == maxAlg) {
                        break;
                }
                else switch(theAlg) {
-                       case CSSM_ALGID_RSA: 
-                               theAlg = CSSM_ALGID_DSA; 
+                       case CSSM_ALGID_RSA:
+                               theAlg = CSSM_ALGID_DSA;
                                break;
                                break;
-                       case CSSM_ALGID_DSA: 
-                               theAlg = CSSM_ALGID_DH; 
+                       case CSSM_ALGID_DSA:
+                               theAlg = CSSM_ALGID_DH;
                                break;
                        case CSSM_ALGID_DH:
                                theAlg = CSSM_ALGID_ECDSA;
                                break;
                        case CSSM_ALGID_DH:
                                theAlg = CSSM_ALGID_ECDSA;
@@ -476,22 +475,22 @@ done:
 
 /*
  * Guess an incoming blob's type, format and (for keys only) algorithm
 
 /*
  * Guess an incoming blob's type, format and (for keys only) algorithm
- * by examining its contents. Returns true on success, in which case 
- * *inputFormat, *itemType, and *keyAlg are all valid. Caller optionally 
+ * by examining its contents. Returns true on success, in which case
+ * *inputFormat, *itemType, and *keyAlg are all valid. Caller optionally
  * passes in valid values any number of these as a clue.
  */
 bool impExpImportGuessByExamination(
        CFDataRef                       inData,
  * passes in valid values any number of these as a clue.
  */
 bool impExpImportGuessByExamination(
        CFDataRef                       inData,
-       SecExternalFormat   *inputFormat,       // may be kSecFormatUnknown on entry 
-       SecExternalItemType     *itemType,              // may be kSecItemTypeUnknown on entry 
+       SecExternalFormat   *inputFormat,       // may be kSecFormatUnknown on entry
+       SecExternalItemType     *itemType,              // may be kSecItemTypeUnknown on entry
        CSSM_ALGORITHMS         *keyAlg)                // CSSM_ALGID_NONE - unknown
 {
        if( ( (*inputFormat == kSecFormatUnknown) ||
        CSSM_ALGORITHMS         *keyAlg)                // CSSM_ALGID_NONE - unknown
 {
        if( ( (*inputFormat == kSecFormatUnknown) ||
-             (*inputFormat == kSecFormatX509Cert) 
+             (*inputFormat == kSecFormatX509Cert)
                ) &&
           ( (*itemType == kSecItemTypeUnknown) ||
                 (*itemType == kSecItemTypeCertificate) ) ) {
                ) &&
           ( (*itemType == kSecItemTypeUnknown) ||
                 (*itemType == kSecItemTypeCertificate) ) ) {
-               /* 
+               /*
                 * See if it parses as a cert
                 */
                CSSM_CL_HANDLE clHand = cuClStartup();
                 * See if it parses as a cert
                 */
                CSSM_CL_HANDLE clHand = cuClStartup();
@@ -500,7 +499,7 @@ bool impExpImportGuessByExamination(
                }
                CSSM_HANDLE cacheHand;
                CSSM_RETURN crtn;
                }
                CSSM_HANDLE cacheHand;
                CSSM_RETURN crtn;
-               CSSM_DATA cdata = { CFDataGetLength(inData), 
+               CSSM_DATA cdata = { CFDataGetLength(inData),
                                                    (uint8 *)CFDataGetBytePtr(inData) };
                crtn = CSSM_CL_CertCache(clHand, &cdata, &cacheHand);
                bool brtn = false;
                                                    (uint8 *)CFDataGetBytePtr(inData) };
                crtn = CSSM_CL_CertCache(clHand, &cdata, &cacheHand);
                bool brtn = false;
@@ -517,9 +516,9 @@ bool impExpImportGuessByExamination(
                }
        }
        /* TBD: need way to inquire of P12 lib if this is a valid-looking PFX */
                }
        }
        /* TBD: need way to inquire of P12 lib if this is a valid-looking PFX */
-       
+
        if( ( (*inputFormat == kSecFormatUnknown) ||
        if( ( (*inputFormat == kSecFormatUnknown) ||
-             (*inputFormat == kSecFormatNetscapeCertSequence) 
+             (*inputFormat == kSecFormatNetscapeCertSequence)
                ) &&
           ( (*itemType == kSecItemTypeUnknown) ||
                 (*itemType == kSecItemTypeAggregate) ) ) {
                ) &&
           ( (*itemType == kSecItemTypeUnknown) ||
                 (*itemType == kSecItemTypeAggregate) ) ) {
@@ -532,7 +531,7 @@ bool impExpImportGuessByExamination(
                        return true;
                }
        }
                        return true;
                }
        }
-       
+
        /* See if it's a key */
        return impExpGuessKeyParams(inData, inputFormat, itemType, keyAlg);
 }
        /* See if it's a key */
        return impExpGuessKeyParams(inData, inputFormat, itemType, keyAlg);
 }
@@ -549,8 +548,8 @@ CSSM_RETURN impExpAddContextAttribute(CSSM_CC_HANDLE CCHandle,
        uint32 AttributeLength,
        const void *AttributePtr)
 {
        uint32 AttributeLength,
        const void *AttributePtr)
 {
-       CSSM_CONTEXT_ATTRIBUTE          newAttr;        
-       
+       CSSM_CONTEXT_ATTRIBUTE          newAttr;
+
        newAttr.AttributeType     = AttributeType;
        newAttr.AttributeLength   = AttributeLength;
        newAttr.Attribute.Data    = (CSSM_DATA_PTR)AttributePtr;
        newAttr.AttributeType     = AttributeType;
        newAttr.AttributeLength   = AttributeLength;
        newAttr.Attribute.Data    = (CSSM_DATA_PTR)AttributePtr;
@@ -572,14 +571,14 @@ void impExpFreeCssmMemory(
        memFuncs.free_func(p, memFuncs.AllocRef);
 }
 
        memFuncs.free_func(p, memFuncs.AllocRef);
 }
 
-/* 
+/*
  * Calculate digest of any CSSM_KEY. Unlike older implementations
  * Calculate digest of any CSSM_KEY. Unlike older implementations
- * of this logic, you can actually calculate the public key hash 
+ * of this logic, you can actually calculate the public key hash
  * on any class of key, any format, raw CSP or CSPDL (though if
  * you're using the CSPDL, the key has to be a reference key
  * in that CSPDL session).
  *
  * on any class of key, any format, raw CSP or CSPDL (though if
  * you're using the CSPDL, the key has to be a reference key
  * in that CSPDL session).
  *
- * Caller must free keyDigest->Data using impExpFreeCssmMemory() since 
+ * Caller must free keyDigest->Data using impExpFreeCssmMemory() since
  * this is allocated by the CSP's app-specified allocator.
  */
 CSSM_RETURN impExpKeyDigest(
  * this is allocated by the CSP's app-specified allocator.
  */
 CSSM_RETURN impExpKeyDigest(
@@ -589,7 +588,7 @@ CSSM_RETURN impExpKeyDigest(
 {
        CSSM_DATA_PTR   localDigest;
        CSSM_CC_HANDLE  ccHand;
 {
        CSSM_DATA_PTR   localDigest;
        CSSM_CC_HANDLE  ccHand;
-       
+
        CSSM_RETURN crtn = CSSM_CSP_CreatePassThroughContext(cspHand,
                key,
                &ccHand);
        CSSM_RETURN crtn = CSSM_CSP_CreatePassThroughContext(cspHand,
                key,
                &ccHand);
@@ -604,8 +603,8 @@ CSSM_RETURN impExpKeyDigest(
                SecImpExpDbg("CSSM_CSP_PassThrough(KEY_DIGEST) failure");
        }
        else {
                SecImpExpDbg("CSSM_CSP_PassThrough(KEY_DIGEST) failure");
        }
        else {
-               /* 
-                * Give caller the Data referent and we'll free the 
+               /*
+                * Give caller the Data referent and we'll free the
                 * CSSM_DATA struct itswelf.
                 */
                *keyDigest = *localDigest;
                 * CSSM_DATA struct itswelf.
                 */
                *keyDigest = *localDigest;
@@ -614,12 +613,12 @@ CSSM_RETURN impExpKeyDigest(
        CSSM_DeleteContext(ccHand);
        return crtn;
 }
        CSSM_DeleteContext(ccHand);
        return crtn;
 }
-       
+
 
 /*
  * Given a CFTypeRef passphrase which may be a CFDataRef or a CFStringRef,
  * return a refcounted CFStringRef suitable for use with the PKCS12 library.
 
 /*
  * Given a CFTypeRef passphrase which may be a CFDataRef or a CFStringRef,
  * return a refcounted CFStringRef suitable for use with the PKCS12 library.
- * PKCS12 passphrases in CFData format must be UTF8 encoded. 
+ * PKCS12 passphrases in CFData format must be UTF8 encoded.
  */
 OSStatus impExpPassphraseToCFString(
        CFTypeRef   passin,
  */
 OSStatus impExpPassphraseToCFString(
        CFTypeRef   passin,
@@ -629,29 +628,29 @@ OSStatus impExpPassphraseToCFString(
                CFStringRef passInStr = (CFStringRef)passin;
                CFRetain(passInStr);
                *passout = passInStr;
                CFStringRef passInStr = (CFStringRef)passin;
                CFRetain(passInStr);
                *passout = passInStr;
-               return noErr;
+               return errSecSuccess;
        }
        else if(CFGetTypeID(passin) == CFDataGetTypeID()) {
                CFDataRef cfData = (CFDataRef)passin;
                CFIndex len = CFDataGetLength(cfData);
        }
        else if(CFGetTypeID(passin) == CFDataGetTypeID()) {
                CFDataRef cfData = (CFDataRef)passin;
                CFIndex len = CFDataGetLength(cfData);
-               CFStringRef cfStr = CFStringCreateWithBytes(NULL, 
+               CFStringRef cfStr = CFStringCreateWithBytes(NULL,
                        CFDataGetBytePtr(cfData), len, kCFStringEncodingUTF8, true);
                if(cfStr == NULL) {
                        SecImpExpDbg("Passphrase not in UTF8 format");
                        CFDataGetBytePtr(cfData), len, kCFStringEncodingUTF8, true);
                if(cfStr == NULL) {
                        SecImpExpDbg("Passphrase not in UTF8 format");
-                       return paramErr;
+                       return errSecParam;
                }
                *passout = cfStr;
                }
                *passout = cfStr;
-               return noErr;
+               return errSecSuccess;
        }
        else {
                SecImpExpDbg("Passphrase not CFData or CFString");
        }
        else {
                SecImpExpDbg("Passphrase not CFData or CFString");
-               return paramErr;
+               return errSecParam;
        }
 }
 
 /*
  * Given a CFTypeRef passphrase which may be a CFDataRef or a CFStringRef,
        }
 }
 
 /*
  * Given a CFTypeRef passphrase which may be a CFDataRef or a CFStringRef,
- * return a refcounted CFDataRef whose bytes are suitable for use with 
+ * return a refcounted CFDataRef whose bytes are suitable for use with
  * PKCS5 (v1.5 and v2.0) key derivation.
  */
 OSStatus impExpPassphraseToCFData(
  * PKCS5 (v1.5 and v2.0) key derivation.
  */
 OSStatus impExpPassphraseToCFData(
@@ -662,54 +661,54 @@ OSStatus impExpPassphraseToCFData(
                CFDataRef passInData = (CFDataRef)passin;
                CFRetain(passInData);
                *passout = passInData;
                CFDataRef passInData = (CFDataRef)passin;
                CFRetain(passInData);
                *passout = passInData;
-               return noErr;
+               return errSecSuccess;
        }
        else if(CFGetTypeID(passin) == CFStringGetTypeID()) {
                CFStringRef passInStr = (CFStringRef)passin;
                CFDataRef outData;
                outData = CFStringCreateExternalRepresentation(NULL,
        }
        else if(CFGetTypeID(passin) == CFStringGetTypeID()) {
                CFStringRef passInStr = (CFStringRef)passin;
                CFDataRef outData;
                outData = CFStringCreateExternalRepresentation(NULL,
-                       passInStr, 
+                       passInStr,
                        kCFStringEncodingUTF8,
                        kCFStringEncodingUTF8,
-                       0);             // lossByte 0 ==> no loss allowed 
-               if(outData == NULL) {                   
+                       0);             // lossByte 0 ==> no loss allowed
+               if(outData == NULL) {
                        /* Well try with lossy conversion */
                        SecImpExpDbg("Trying lossy conversion of CFString passphrase to UTF8");
                        outData = CFStringCreateExternalRepresentation(NULL,
                        /* Well try with lossy conversion */
                        SecImpExpDbg("Trying lossy conversion of CFString passphrase to UTF8");
                        outData = CFStringCreateExternalRepresentation(NULL,
-                               passInStr, 
+                               passInStr,
                                kCFStringEncodingUTF8,
                                kCFStringEncodingUTF8,
-                               1);             
+                               1);
                        if(outData == NULL) {
                                SecImpExpDbg("Failure on conversion of CFString passphrase to UTF8");
                                /* what do we do now, Batman? */
                        if(outData == NULL) {
                                SecImpExpDbg("Failure on conversion of CFString passphrase to UTF8");
                                /* what do we do now, Batman? */
-                               return paramErr;
+                               return errSecParam;
                        }
                }
                *passout = outData;
                        }
                }
                *passout = outData;
-               return noErr;
+               return errSecSuccess;
        }
        else {
                SecImpExpDbg("Passphrase not CFData or CFString");
        }
        else {
                SecImpExpDbg("Passphrase not CFData or CFString");
-               return paramErr;
+               return errSecParam;
        }
 }
 
        }
 }
 
-/* 
-* Add a CFString to a crypto context handle. 
+/*
+* Add a CFString to a crypto context handle.
 */
 static CSSM_RETURN impExpAddStringAttr(
 */
 static CSSM_RETURN impExpAddStringAttr(
-       CSSM_CC_HANDLE ccHand, 
+       CSSM_CC_HANDLE ccHand,
        CFStringRef str,
        CSSM_ATTRIBUTE_TYPE attrType)
 {
        /* CFStrings are passed as external rep in UTF8 encoding by convention */
        CFDataRef outData;
        outData = CFStringCreateExternalRepresentation(NULL,
        CFStringRef str,
        CSSM_ATTRIBUTE_TYPE attrType)
 {
        /* CFStrings are passed as external rep in UTF8 encoding by convention */
        CFDataRef outData;
        outData = CFStringCreateExternalRepresentation(NULL,
-               str, kCFStringEncodingUTF8,     0);             // lossByte 0 ==> no loss allowed 
+               str, kCFStringEncodingUTF8,     0);             // lossByte 0 ==> no loss allowed
        if(outData == NULL) {
                SecImpExpDbg("impExpAddStringAttr: bad string format");
        if(outData == NULL) {
                SecImpExpDbg("impExpAddStringAttr: bad string format");
-               return paramErr;
+               return errSecParam;
        }
        }
-       
+
        CSSM_DATA attrData;
        attrData.Data = (uint8 *)CFDataGetBytePtr(outData);
        attrData.Length = CFDataGetLength(outData);
        CSSM_DATA attrData;
        attrData.Data = (uint8 *)CFDataGetBytePtr(outData);
        attrData.Length = CFDataGetLength(outData);
@@ -723,7 +722,7 @@ static CSSM_RETURN impExpAddStringAttr(
 }
 
 /*
 }
 
 /*
- * Generate a secure passphrase key. Caller must eventually CSSM_FreeKey the result. 
+ * Generate a secure passphrase key. Caller must eventually CSSM_FreeKey the result.
  */
 static CSSM_RETURN impExpCreatePassKey(
        const SecKeyImportExportParameters *keyParams,  // required
  */
 static CSSM_RETURN impExpCreatePassKey(
        const SecKeyImportExportParameters *keyParams,  // required
@@ -736,14 +735,14 @@ static CSSM_RETURN impExpCreatePassKey(
        uint32 verifyAttr;
        CSSM_DATA dummyLabel;
        CSSM_KEY_PTR ourKey = NULL;
        uint32 verifyAttr;
        CSSM_DATA dummyLabel;
        CSSM_KEY_PTR ourKey = NULL;
-       
+
        SecImpExpDbg("Generating secure passphrase key");
        ourKey = (CSSM_KEY_PTR)malloc(sizeof(CSSM_KEY));
        if(ourKey == NULL) {
        SecImpExpDbg("Generating secure passphrase key");
        ourKey = (CSSM_KEY_PTR)malloc(sizeof(CSSM_KEY));
        if(ourKey == NULL) {
-               return memFullErr;
+               return errSecAllocate;
        }
        memset(ourKey, 0, sizeof(CSSM_KEY));
        }
        memset(ourKey, 0, sizeof(CSSM_KEY));
-       
+
        crtn = CSSM_CSP_CreateKeyGenContext(cspHand,
                CSSM_ALGID_SECURE_PASSPHRASE,
                4,                              // keySizeInBits must be non zero
        crtn = CSSM_CSP_CreateKeyGenContext(cspHand,
                CSSM_ALGID_SECURE_PASSPHRASE,
                4,                              // keySizeInBits must be non zero
@@ -758,18 +757,18 @@ static CSSM_RETURN impExpCreatePassKey(
                return crtn;
        }
        /* subsequent errors to errOut: */
                return crtn;
        }
        /* subsequent errors to errOut: */
-       
+
        /* additional context attributes specific to this type of key gen */
        assert(keyParams != NULL);                      // or we wouldn't be here
        if(keyParams->alertTitle != NULL) {
        /* additional context attributes specific to this type of key gen */
        assert(keyParams != NULL);                      // or we wouldn't be here
        if(keyParams->alertTitle != NULL) {
-               crtn = impExpAddStringAttr(ccHand, keyParams->alertTitle, 
+               crtn = impExpAddStringAttr(ccHand, keyParams->alertTitle,
                        CSSM_ATTRIBUTE_ALERT_TITLE);
                if(crtn) {
                        goto errOut;
                }
        }
        if(keyParams->alertPrompt != NULL) {
                        CSSM_ATTRIBUTE_ALERT_TITLE);
                if(crtn) {
                        goto errOut;
                }
        }
        if(keyParams->alertPrompt != NULL) {
-               crtn = impExpAddStringAttr(ccHand, keyParams->alertPrompt, 
+               crtn = impExpAddStringAttr(ccHand, keyParams->alertPrompt,
                        CSSM_ATTRIBUTE_PROMPT);
                if(crtn) {
                        goto errOut;
                        CSSM_ATTRIBUTE_PROMPT);
                if(crtn) {
                        goto errOut;
@@ -777,7 +776,7 @@ static CSSM_RETURN impExpCreatePassKey(
        }
        verifyAttr = (verifyPhrase == VP_Export) ? 1 : 0;
        crtn = impExpAddContextAttribute(ccHand, CSSM_ATTRIBUTE_VERIFY_PASSPHRASE,
        }
        verifyAttr = (verifyPhrase == VP_Export) ? 1 : 0;
        crtn = impExpAddContextAttribute(ccHand, CSSM_ATTRIBUTE_VERIFY_PASSPHRASE,
-               sizeof(uint32), (const void *)verifyAttr);
+               sizeof(uint32), (const void *)((size_t) verifyAttr));
        if(crtn) {
                SecImpExpDbg("impExpCreatePassKey: CSSM_UpdateContextAttributes error");
                goto errOut;
        if(crtn) {
                SecImpExpDbg("impExpCreatePassKey: CSSM_UpdateContextAttributes error");
                goto errOut;
@@ -805,26 +804,26 @@ errOut:
        }
        return crtn;
 }
        }
        return crtn;
 }
-       
+
 /*
 /*
- * Obtain passphrase, given a SecKeyImportExportParameters. 
+ * Obtain passphrase, given a SecKeyImportExportParameters.
  *
  *
- * Passphrase comes from one of two places: app-specified, in 
+ * Passphrase comes from one of two places: app-specified, in
  * SecKeyImportExportParameters.passphrase (either as CFStringRef
  * or CFDataRef); or via the secure passphrase mechanism.
  *
  * Passphrase is returned in AT MOST one of two forms:
  *
  * SecKeyImportExportParameters.passphrase (either as CFStringRef
  * or CFDataRef); or via the secure passphrase mechanism.
  *
  * Passphrase is returned in AT MOST one of two forms:
  *
- * -- Secure passphrase is returned as a CSSM_KEY_PTR, which the 
- *    caller must CSSM_FreeKey later as well as free()ing the actual 
- *    CSSM_KEY_PTR. 
- * -- CFTypeRef for app-supplied passphrases. This can be one of 
+ * -- Secure passphrase is returned as a CSSM_KEY_PTR, which the
+ *    caller must CSSM_FreeKey later as well as free()ing the actual
+ *    CSSM_KEY_PTR.
+ * -- CFTypeRef for app-supplied passphrases. This can be one of
  *    two types:
  *
  *    -- CFStringRef, for use with P12
  *    two types:
  *
  *    -- CFStringRef, for use with P12
- *    -- CFDataRef, for more general use (e.g. for PKCS5). 
- *   
- *    In either case the caller must CFRelease the result.    
+ *    -- CFDataRef, for more general use (e.g. for PKCS5).
+ *
+ *    In either case the caller must CFRelease the result.
  */
 OSStatus impExpPassphraseCommon(
        const SecKeyImportExportParameters *keyParams,
  */
 OSStatus impExpPassphraseCommon(
        const SecKeyImportExportParameters *keyParams,
@@ -835,7 +834,7 @@ OSStatus impExpPassphraseCommon(
        CSSM_KEY_PTR                    *passKey)               // mallocd and RETURNED
 {
        assert(keyParams != NULL);
        CSSM_KEY_PTR                    *passKey)               // mallocd and RETURNED
 {
        assert(keyParams != NULL);
-       
+
        /* Give precedence to secure passphrase */
        if(keyParams->flags & kSecKeySecurePassphrase) {
                assert(passKey != NULL);
        /* Give precedence to secure passphrase */
        if(keyParams->flags & kSecKeySecurePassphrase) {
                assert(passKey != NULL);
@@ -847,19 +846,19 @@ OSStatus impExpPassphraseCommon(
                assert(phrase != NULL);
                switch(phraseForm) {
                        case SPF_String:
                assert(phrase != NULL);
                switch(phraseForm) {
                        case SPF_String:
-                               ortn = impExpPassphraseToCFString(keyParams->passphrase, 
+                               ortn = impExpPassphraseToCFString(keyParams->passphrase,
                                        (CFStringRef *)&phraseOut);
                                break;
                        case SPF_Data:
                                        (CFStringRef *)&phraseOut);
                                break;
                        case SPF_Data:
-                               ortn = impExpPassphraseToCFData(keyParams->passphrase, 
+                               ortn = impExpPassphraseToCFData(keyParams->passphrase,
                                        (CFDataRef *)&phraseOut);
                                break;
                        default:
                                /* only called internally */
                                assert(0);
                                        (CFDataRef *)&phraseOut);
                                break;
                        default:
                                /* only called internally */
                                assert(0);
-                               ortn = paramErr;
+                               ortn = errSecParam;
                }
                }
-               if(ortn == noErr) {
+               if(ortn == errSecSuccess) {
                        *phrase = phraseOut;
                }
                return ortn;
                        *phrase = phraseOut;
                }
                return ortn;
@@ -869,55 +868,88 @@ OSStatus impExpPassphraseCommon(
        }
 }
 
        }
 }
 
-CSSM_KEYATTR_FLAGS ConvertArrayToKeyAttributes(SecKeyRef aKey, CFArrayRef usage)
+static void ToggleKeyAttribute(
+       CFArrayRef keyAttrs,
+       CFTypeRef attr,
+       CSSM_KEYATTR_FLAGS mask,
+       CSSM_KEYATTR_FLAGS &result)
+{
+       // If the keyAttrs array contains the given attribute,
+       // set the corresponding keyattr flags, otherwise clear them.
+       // (Note: caller verifies that keyAttrs is not NULL.)
+       CFIndex numItems = CFArrayGetCount(keyAttrs);
+       result &= ~(mask);
+       if (numItems > 0) {
+               CFRange range = CFRangeMake(0, numItems);
+               if (CFArrayContainsValue(keyAttrs, range, attr))
+                       result |= mask;
+       }
+}
+
+CSSM_KEYATTR_FLAGS ConvertArrayToKeyAttributes(SecKeyRef aKey, CFArrayRef keyAttrs)
 {
        CSSM_KEYATTR_FLAGS result = CSSM_KEYATTR_RETURN_DEFAULT;
 {
        CSSM_KEYATTR_FLAGS result = CSSM_KEYATTR_RETURN_DEFAULT;
-       if (NULL == aKey)
-       {
-               return result;
+
+       if (aKey) {
+               const CSSM_KEY* cssmKey = NULL;
+               if (errSecSuccess == SecKeyGetCSSMKey(aKey, &cssmKey))
+                       result = cssmKey->KeyHeader.KeyAttr;
        }
        }
-       OSStatus err = noErr;
-       
-       const CSSM_KEY* cssmKey = NULL;
-       err = SecKeyGetCSSMKey(aKey, &cssmKey);
-       if (noErr != err)
-       {
+
+       if (!keyAttrs)
                return result;
                return result;
-       }
-       
-       result = cssmKey->KeyHeader.KeyAttr;
-       
-       if (NULL != usage)
-       {
-               CFTypeRef item = NULL;
-               CFIndex numItems = CFArrayGetCount(usage);
-               for (CFIndex iCnt = 0L; iCnt < numItems; iCnt++)
-               {
-                       item = (CFTypeRef)CFArrayGetValueAtIndex(usage, iCnt);
-                       if (CFEqual(item, kSecAttrIsPermanent))
-                       {
-                               result |= CSSM_KEYATTR_PERMANENT;
-                       }
-                       /*
-                        Currently the kSecAttrIsModifiable is private.  Does this need to be
-                        made public?
-                       else if (CFEqual(item, kSecAttrIsModifiable))
-                       {
-                               result |= CSSM_KEYATTR_MODIFIABLE;
+
+       CFMutableArrayRef attrs = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+       CFIndex idx, count = CFArrayGetCount(keyAttrs);
+       for (idx=0; idx<count; idx++) {
+               CFTypeRef attr = (CFTypeRef) CFArrayGetValueAtIndex(keyAttrs, idx);
+               if (attr && (CFNumberGetTypeID() == CFGetTypeID(attr))) {
+                       // Convert numeric CSSM keyattr values to equivalent attribute constants
+                       uint32 value;
+                       if (CFNumberGetValue((CFNumberRef)attr, kCFNumberSInt32Type, &value)) {
+                               switch (value) {
+                                       case CSSM_KEYATTR_SENSITIVE:
+                                               attr = kSecAttrIsSensitive;
+                                               break;
+                                       case CSSM_KEYATTR_EXTRACTABLE:
+                                               attr = kSecAttrIsExtractable;
+                                               break;
+                                       case CSSM_KEYATTR_PERMANENT:
+                                               attr = kSecAttrIsPermanent;
+                                               break;
+                                       default:
+                                               attr = NULL;
+                                               break;
+                               }
                        }
                        }
-                       */
                }
                }
+               if (attr)
+                       CFArrayAppendValue(attrs, attr);
        }
        }
-       
-       return result;  
-       
+
+       // Set key attribute flag in result if present in the array, otherwise clear
+       ToggleKeyAttribute(attrs, kSecAttrIsSensitive, CSSM_KEYATTR_SENSITIVE, result);
+       ToggleKeyAttribute(attrs, kSecAttrIsExtractable, CSSM_KEYATTR_EXTRACTABLE, result);
+       ToggleKeyAttribute(attrs, kSecAttrIsPermanent, CSSM_KEYATTR_PERMANENT, result);
+
+       // if caller specified an attributes array which omitted kSecAttrIsExtractable,
+       // this implies the sensitive attribute; force it on so that at least one bit
+       // is set. If our result is 0, this is indistinguishable from the case where
+       // no key attributes were specified, causing a default bitmask to be used
+       // in subsequent import code.
+
+       if (0==(result & CSSM_KEYATTR_EXTRACTABLE))
+               result |= CSSM_KEYATTR_SENSITIVE;
+
+       CFRelease(attrs);
+       return result;
 }
 
 Boolean ConvertSecKeyImportExportParametersToSecImportExportKeyParameters(SecKeyRef aKey,
        const SecItemImportExportKeyParameters* newPtr, SecKeyImportExportParameters* oldPtr)
 {
        Boolean result = false;
 }
 
 Boolean ConvertSecKeyImportExportParametersToSecImportExportKeyParameters(SecKeyRef aKey,
        const SecItemImportExportKeyParameters* newPtr, SecKeyImportExportParameters* oldPtr)
 {
        Boolean result = false;
-       
+
        if (NULL != oldPtr && NULL != newPtr)
        {
                oldPtr->version = newPtr->version;
        if (NULL != oldPtr && NULL != newPtr)
        {
                oldPtr->version = newPtr->version;
index dc30157ef61335675ca4433be40d81ccf3bae840..7190ba17ea0f6b564c1a8719ef2383d38e4bac0d 100644 (file)
@@ -50,8 +50,8 @@ extern "C" {
        } \
        catch (const MacOSError &err) { return err.osStatus(); } \
        catch (const CommonError &err) { return SecKeychainErrFromOSStatus(err.osStatus()); } \
        } \
        catch (const MacOSError &err) { return err.osStatus(); } \
        catch (const CommonError &err) { return SecKeychainErrFromOSStatus(err.osStatus()); } \
-       catch (const std::bad_alloc &) { return memFullErr; }\
-       catch (...) { return internalComponentErr; }
+       catch (const std::bad_alloc &) { return errSecAllocate; }\
+       catch (...) { return errSecInternalComponent; }
 
 /* 
  * Debug support.
 
 /* 
  * Debug support.
index 2fd7bbfdfba1094f1b229888d150911fb4c585af..0d315de77de5a68cda6fda677477862ad4f887fe 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2007 Apple Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2007-2013 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -39,6 +39,10 @@ extern "C" {
 #define CFReleaseNull(CF) { CFTypeRef _cf = (CF); \
        if (_cf) { (CF) = NULL; CFRelease(_cf); } }
 
 #define CFReleaseNull(CF) { CFTypeRef _cf = (CF); \
        if (_cf) { (CF) = NULL; CFRelease(_cf); } }
 
+#define AssignOrReleaseResult(CF,OUT) { \
+       CFTypeRef _cf = (CF), *_out = (OUT); \
+       if (_out) { *_out = _cf; } else { if (_cf) CFRelease(_cf); } }
+
 #define DICT_DECLARE(MAXVALUES) \
        CFIndex numValues = 0, maxValues = (MAXVALUES); \
        const void *keys[maxValues]; \
 #define DICT_DECLARE(MAXVALUES) \
        CFIndex numValues = 0, maxValues = (MAXVALUES); \
        const void *keys[maxValues]; \
index 53644f1f24306a13562a9d42530b4ff6c5e9799c..00bb4c41b6fb22c4440940c8f8b1a378d3eb2237 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2006-2010,2012 Apple Inc. All Rights Reserved.
+ * Copyright (c) 2006-2013 Apple Inc. All Rights Reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  */
 
 #include "SecBridge.h"
  */
 
 #include "SecBridge.h"
-#include <security_utilities/cfutilities.h>
+#include "SecInternal.h"
 #include <CoreFoundation/CoreFoundation.h>
 #include <CoreFoundation/CoreFoundation.h>
+#include <security_utilities/cfutilities.h>
+#include <Security/SecBase.h>
 #include <Security/SecKeychainItem.h>
 #include <Security/SecCertificate.h>
 #include <sys/param.h>
 #include <Security/SecKeychainItem.h>
 #include <Security/SecCertificate.h>
 #include <sys/param.h>
 #include "SecItem.h"
 #include "SecItemPriv.h"
 #include "SecIdentitySearchPriv.h"
 #include "SecItem.h"
 #include "SecItemPriv.h"
 #include "SecIdentitySearchPriv.h"
+#include "SecKeychainPriv.h"
 #include "SecCertificatePriv.h"
 #include "SecCertificatePrivP.h"
 #include "TrustAdditions.h"
 
 #include <AssertMacros.h>
 #include "SecCertificatePriv.h"
 #include "SecCertificatePrivP.h"
 #include "TrustAdditions.h"
 
 #include <AssertMacros.h>
+#include <syslog.h>
+
+#include <Security/SecTrustedApplication.h>
+#include <Security/SecTrustedApplicationPriv.h>
+#include <Security/SecCode.h>
+#include <Security/SecCodePriv.h>
+#include <Security/SecRequirement.h>
+
+const uint8_t kUUIDStringLength = 36;
 
 OSStatus SecItemAdd_osx(CFDictionaryRef attributes, CFTypeRef *result);
 OSStatus SecItemCopyMatching_osx(CFDictionaryRef query, CFTypeRef *result);
 
 OSStatus SecItemAdd_osx(CFDictionaryRef attributes, CFTypeRef *result);
 OSStatus SecItemCopyMatching_osx(CFDictionaryRef query, CFTypeRef *result);
@@ -47,6 +59,48 @@ OSStatus SecItemAdd_ios(CFDictionaryRef attributes, CFTypeRef *result);
 OSStatus SecItemCopyMatching_ios(CFDictionaryRef query, CFTypeRef *result);
 OSStatus SecItemUpdate_ios(CFDictionaryRef query, CFDictionaryRef attributesToUpdate);
 OSStatus SecItemDelete_ios(CFDictionaryRef query);
 OSStatus SecItemCopyMatching_ios(CFDictionaryRef query, CFTypeRef *result);
 OSStatus SecItemUpdate_ios(CFDictionaryRef query, CFDictionaryRef attributesToUpdate);
 OSStatus SecItemDelete_ios(CFDictionaryRef query);
+
+CFTypeRef SecItemCreateFromAttributeDictionary(CFDictionaryRef refAttributes);
+CFTypeRef SecItemCopyMergedResults(CFDictionaryRef query, CFTypeRef result_osx, CFTypeRef result_ios);
+OSStatus SecItemValidateAppleApplicationGroupAccess(CFStringRef group);
+CFDictionaryRef SecItemCopyTranslatedAttributes(CFDictionaryRef inOSXDict, CFTypeRef itemClass,
+       bool iOSOut, bool pruneMatch, bool pruneSync, bool pruneReturn, bool pruneData, bool pruneAccess);
+}
+
+static void secitemlog(int priority, const char *format, ...)
+{
+#ifndef NDEBUG
+       // log everything
+#else
+       if (priority < LOG_NOTICE) // log warnings and errors
+#endif
+       {
+               va_list list;
+               va_start(list, format);
+               vsyslog(priority, format, list);
+               va_end(list);
+       }
+}
+
+static void secitemshow(CFTypeRef obj, const char *context)
+{
+#ifndef NDEBUG
+       CFStringRef desc = CFCopyDescription(obj);
+       if (!desc) return;
+
+       CFIndex length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(desc), kCFStringEncodingUTF8) + 1;
+       char* buffer = (char*) malloc(length);
+       if (buffer) {
+               Boolean converted = CFStringGetCString(desc, buffer, length, kCFStringEncodingUTF8);
+               if (converted) {
+                       const char *prefix = (context) ? context : "";
+                       const char *separator = (context) ? " " : "";
+                       secitemlog(LOG_NOTICE, "%s%s%s", prefix, separator, buffer);
+               }
+               free(buffer);
+       }
+       CFRelease(desc);
+#endif
 }
 
 
 }
 
 
@@ -219,7 +273,8 @@ static KeyAlgorithmInfo gKeyTypes[] = {
        { &kSecAttrKeyTypeRC4, CSSM_ALGID_RC4 },
        { &kSecAttrKeyTypeRC2, CSSM_ALGID_RC2 },
        { &kSecAttrKeyTypeCAST, CSSM_ALGID_CAST },
        { &kSecAttrKeyTypeRC4, CSSM_ALGID_RC4 },
        { &kSecAttrKeyTypeRC2, CSSM_ALGID_RC2 },
        { &kSecAttrKeyTypeCAST, CSSM_ALGID_CAST },
-       { &kSecAttrKeyTypeECDSA, CSSM_ALGID_ECDSA }
+       { &kSecAttrKeyTypeECDSA, CSSM_ALGID_ECDSA },
+       { &kSecAttrKeyTypeEC, CSSM_ALGID_ECDSA }
 };
 
 static const int kNumberOfKeyTypes = sizeof(gKeyTypes) / sizeof (KeyAlgorithmInfo);
 };
 
 static const int kNumberOfKeyTypes = sizeof(gKeyTypes) / sizeof (KeyAlgorithmInfo);
@@ -282,7 +337,7 @@ static InternalAttributeListInfo gGenericPasswordAttributes[] =
 
 static const int kNumberOfGenericPasswordAttributes = sizeof(gGenericPasswordAttributes) / sizeof (InternalAttributeListInfo);
 
 
 static const int kNumberOfGenericPasswordAttributes = sizeof(gGenericPasswordAttributes) / sizeof (InternalAttributeListInfo);
 
-
+#if 0
 static InternalAttributeListInfo gInternetPasswordAttributes[] =
 {
        { kSecCreationDateItemAttr, &kSecAttrCreationDate, kDateRepresentation },
 static InternalAttributeListInfo gInternetPasswordAttributes[] =
 {
        { kSecCreationDateItemAttr, &kSecAttrCreationDate, kDateRepresentation },
@@ -303,7 +358,7 @@ static InternalAttributeListInfo gInternetPasswordAttributes[] =
 };
 
 static const int kNumberOfInternetPasswordAttributes = sizeof(gInternetPasswordAttributes) / sizeof (InternalAttributeListInfo);
 };
 
 static const int kNumberOfInternetPasswordAttributes = sizeof(gInternetPasswordAttributes) / sizeof (InternalAttributeListInfo);
-
+#endif
 
 static InternalAttributeListInfo gCertificateAttributes[] =
 {
 
 static InternalAttributeListInfo gCertificateAttributes[] =
 {
@@ -328,7 +383,7 @@ static InternalAttributeListInfo gKeyAttributes[] =
     { kSecKeyPermanent, &kSecAttrIsPermanent, kBooleanRepresentation },
 //  { kSecKeyPrivate, /* not yet exposed by SecItem */, kBooleanRepresentation },
 //  { kSecKeyModifiable, /* not yet exposed by SecItem */, kBooleanRepresentation },
     { kSecKeyPermanent, &kSecAttrIsPermanent, kBooleanRepresentation },
 //  { kSecKeyPrivate, /* not yet exposed by SecItem */, kBooleanRepresentation },
 //  { kSecKeyModifiable, /* not yet exposed by SecItem */, kBooleanRepresentation },
-    { kSecKeyLabel, &kSecAttrApplicationLabel, kStringRepresentation }, // this contains the hash of the key (or the public key hash, if asymmetric)
+    { kSecKeyLabel, &kSecAttrApplicationLabel, kDataRepresentation }, // this contains the hash of the key (or the public key hash, if asymmetric) as a CFData. Legacy keys may contain a UUID as a CFString
     { kSecKeyApplicationTag, &kSecAttrApplicationTag, kDataRepresentation },
 //  { kSecKeyKeyCreator, /* not yet exposed by SecItem */, kStringRepresentation }, // this is the GUID of the CSP that owns this key
     { kSecKeyKeyType, &kSecAttrKeyType, kStringRepresentation }, // algorithm type is given as a string constant (e.g. kSecAttrKeyTypeAES)
     { kSecKeyApplicationTag, &kSecAttrApplicationTag, kDataRepresentation },
 //  { kSecKeyKeyCreator, /* not yet exposed by SecItem */, kStringRepresentation }, // this is the GUID of the CSP that owns this key
     { kSecKeyKeyType, &kSecAttrKeyType, kStringRepresentation }, // algorithm type is given as a string constant (e.g. kSecAttrKeyTypeAES)
@@ -368,7 +423,7 @@ static void* CloneDataByType(ItemRepresentation type, CFTypeRef value, UInt32& l
                        char* buffer = (char*) malloc(maxLength);
                        Boolean converted = CFStringGetCString((CFStringRef) value, buffer, maxLength, kCFStringEncodingUTF8);
                        if (converted) {
                        char* buffer = (char*) malloc(maxLength);
                        Boolean converted = CFStringGetCString((CFStringRef) value, buffer, maxLength, kCFStringEncodingUTF8);
                        if (converted) {
-                               length = strlen(buffer);
+                               length = (UInt32)strlen(buffer);
                        }
                        else {
                                length = 0;
                        }
                        else {
                                length = 0;
@@ -380,11 +435,27 @@ static void* CloneDataByType(ItemRepresentation type, CFTypeRef value, UInt32& l
 
                case kDataRepresentation:
                {
 
                case kDataRepresentation:
                {
+                       if (CFStringGetTypeID() == CFGetTypeID(value)) {
+                // We may have a string here, since the key label may be a GUID for the symmetric keys
+                CFIndex maxLength = CFStringGetMaximumSizeForEncoding(CFStringGetLength((CFStringRef) value), kCFStringEncodingUTF8) + 1;
+                char* buffer = (char*) malloc(maxLength);
+                Boolean converted = CFStringGetCString((CFStringRef) value, buffer, maxLength, kCFStringEncodingUTF8);
+                if (converted) {
+                    length = (UInt32)strlen(buffer);
+                }
+                else {
+                    length = 0;
+                    free(buffer);
+                    buffer = NULL;
+                }
+                return buffer;
+                       }
+
                        if (CFDataGetTypeID() != CFGetTypeID(value)) {
                                length = 0;
                                return NULL;
                        }
                        if (CFDataGetTypeID() != CFGetTypeID(value)) {
                                length = 0;
                                return NULL;
                        }
-                       length = CFDataGetLength((CFDataRef) value);
+                       length = (UInt32)CFDataGetLength((CFDataRef) value);
                        uint8_t* buffer = (uint8_t*) malloc(length);
                        CFDataGetBytes((CFDataRef) value, CFRangeMake(0, length), buffer);
                        return buffer;
                        uint8_t* buffer = (uint8_t*) malloc(length);
                        CFDataGetBytes((CFDataRef) value, CFRangeMake(0, length), buffer);
                        return buffer;
@@ -429,7 +500,7 @@ static void* CloneDataByType(ItemRepresentation type, CFTypeRef value, UInt32& l
                        }
                        char* buffer = (char*) calloc(1, 32); // max length of a CSSM date string
                        CSSMDateTimeUtils::CFDateToCssmDate((CFDateRef) value, buffer);
                        }
                        char* buffer = (char*) calloc(1, 32); // max length of a CSSM date string
                        CSSMDateTimeUtils::CFDateToCssmDate((CFDateRef) value, buffer);
-                       length = strlen(buffer);
+                       length = (UInt32)strlen(buffer);
                        return buffer;
                }
 
                        return buffer;
                }
 
@@ -460,7 +531,7 @@ _ConvertNewFormatToOldFormat(
        attrList = (SecKeychainAttributeList*) calloc(1, sizeof(SecKeychainAttributeList));
 
        // make storage to extract the dictionary items
        attrList = (SecKeychainAttributeList*) calloc(1, sizeof(SecKeychainAttributeList));
 
        // make storage to extract the dictionary items
-       int itemsInDictionary = CFDictionaryGetCount(dictionaryRef);
+       CFIndex itemsInDictionary = CFDictionaryGetCount(dictionaryRef);
        CFTypeRef keys[itemsInDictionary];
        CFTypeRef values[itemsInDictionary];
 
        CFTypeRef keys[itemsInDictionary];
        CFTypeRef values[itemsInDictionary];
 
@@ -470,8 +541,8 @@ _ConvertNewFormatToOldFormat(
        CFDictionaryGetKeysAndValues(dictionaryRef, keys, values);
 
        // count the number of items we are interested in
        CFDictionaryGetKeysAndValues(dictionaryRef, keys, values);
 
        // count the number of items we are interested in
-       int count = 0;
-       int i;
+       CFIndex count = 0;
+       CFIndex i;
 
        // since this is one of those nasty order n^2 loops, we cache as much stuff as possible so that
        // we don't pay the price for this twice
 
        // since this is one of those nasty order n^2 loops, we cache as much stuff as possible so that
        // we don't pay the price for this twice
@@ -502,7 +573,7 @@ _ConvertNewFormatToOldFormat(
        }
 
        // now we can make the result array
        }
 
        // now we can make the result array
-       attrList->count = count;
+       attrList->count = (UInt32)count;
        attrList->attr = (SecKeychainAttribute*) malloc(sizeof(SecKeychainAttribute) * count);
 
        // fill out the array
        attrList->attr = (SecKeychainAttribute*) malloc(sizeof(SecKeychainAttribute) * count);
 
        // fill out the array
@@ -520,7 +591,7 @@ _ConvertNewFormatToOldFormat(
                }
        }
 
                }
        }
 
-       return noErr;
+       return errSecSuccess;
 }
 
 
 }
 
 
@@ -545,7 +616,7 @@ _ConvertOldFormatToNewFormat(
        }
 
        OSStatus result = SecKeychainItemCopyContent(itemRef, NULL, &list, NULL, NULL);
        }
 
        OSStatus result = SecKeychainItemCopyContent(itemRef, NULL, &list, NULL, NULL);
-       if (result != noErr)
+       if (result != errSecSuccess)
        {
                dictionaryRef = NULL;
                free(list.attr);
        {
                dictionaryRef = NULL;
                free(list.attr);
@@ -620,7 +691,7 @@ _ConvertOldFormatToNewFormat(
                                                        stringRef = (CFStringRef) kSecAttrKeyTypeCAST;
                                                        break;
                                                case CSSM_ALGID_ECDSA :
                                                        stringRef = (CFStringRef) kSecAttrKeyTypeCAST;
                                                        break;
                                                case CSSM_ALGID_ECDSA :
-                                                       stringRef = (CFStringRef) kSecAttrKeyTypeECDSA;
+                                                       stringRef = (CFStringRef) kSecAttrKeyTypeEC;
                                                        break;
                                                default :
                                                        stringRef = CFStringCreateWithFormat(allocator, NULL, CFSTR("%d"), keyAlgValue);
                                                        break;
                                                default :
                                                        stringRef = CFStringCreateWithFormat(allocator, NULL, CFSTR("%d"), keyAlgValue);
@@ -646,11 +717,20 @@ _ConvertOldFormatToNewFormat(
 
                        case kDataRepresentation:
                        {
 
                        case kDataRepresentation:
                        {
-                               CFDataRef dataRef = CFDataCreate(allocator, (UInt8*) list.attr[i].data, list.attr[i].length);
-                               if (dataRef == NULL)
-                                       dataRef = (CFDataRef) CFRetain(kCFNull);
-                               CFDictionaryAddValue(dictionaryRef, *(info[i].newItemType), dataRef);
-                               CFRelease(dataRef);
+                if ((info[i].oldItemType == kSecKeyLabel) && (list.attr[i].length == kUUIDStringLength)) {
+                                       // It's possible that there could be a string here because the key label may have a UUID
+                                       CFStringRef stringRef = CFStringCreateWithBytes(allocator, (UInt8*)list.attr[i].data, list.attr[i].length, kCFStringEncodingUTF8, FALSE);
+                                       if (stringRef == NULL)
+                                               stringRef = (CFStringRef) CFRetain(kCFNull);
+                                       CFDictionaryAddValue(dictionaryRef, *(info[i].newItemType), stringRef);
+                                       CFRelease(stringRef);
+                    break;
+                }
+                CFDataRef dataRef = CFDataCreate(allocator, (UInt8*) list.attr[i].data, list.attr[i].length);
+                if (dataRef == NULL)
+                    dataRef = (CFDataRef) CFRetain(kCFNull);
+                CFDictionaryAddValue(dictionaryRef, *(info[i].newItemType), dataRef);
+                CFRelease(dataRef);
                        }
                        break;
 
                        }
                        break;
 
@@ -708,7 +788,7 @@ _CreateAttributesDictionaryFromGenericPasswordItem(
        // do the basic allocations
        CFMutableDictionaryRef dict = NULL;
        OSStatus result = _ConvertOldFormatToNewFormat(allocator, gGenericPasswordAttributes, kNumberOfGenericPasswordAttributes, item, dict);
        // do the basic allocations
        CFMutableDictionaryRef dict = NULL;
        OSStatus result = _ConvertOldFormatToNewFormat(allocator, gGenericPasswordAttributes, kNumberOfGenericPasswordAttributes, item, dict);
-       if (result == noErr) // did we complete OK
+       if (result == errSecSuccess) // did we complete OK
        {
                CFDictionaryAddValue(dict, kSecClass, kSecClassGenericPassword);
        }
        {
                CFDictionaryAddValue(dict, kSecClass, kSecClassGenericPassword);
        }
@@ -733,14 +813,14 @@ _CreateAttributesDictionaryFromCertificateItem(
        // do the basic allocations
        CFMutableDictionaryRef dict = NULL;
        OSStatus result = _ConvertOldFormatToNewFormat(allocator, gCertificateAttributes, kNumberOfCertificateAttributes, item, dict);
        // do the basic allocations
        CFMutableDictionaryRef dict = NULL;
        OSStatus result = _ConvertOldFormatToNewFormat(allocator, gCertificateAttributes, kNumberOfCertificateAttributes, item, dict);
-       if (result == noErr) // did we complete OK
+       if (result == errSecSuccess) // did we complete OK
        {
                CFDictionaryAddValue(dict, kSecClass, kSecClassCertificate);
        }
 
        *dictionary = dict;
 
        {
                CFDictionaryAddValue(dict, kSecClass, kSecClassCertificate);
        }
 
        *dictionary = dict;
 
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -767,14 +847,14 @@ _CreateAttributesDictionaryFromKeyItem(
        // do the basic allocations
        CFMutableDictionaryRef dict = NULL;
        OSStatus result = _ConvertOldFormatToNewFormat(allocator, gKeyAttributes, kNumberOfKeyAttributes, item, dict);
        // do the basic allocations
        CFMutableDictionaryRef dict = NULL;
        OSStatus result = _ConvertOldFormatToNewFormat(allocator, gKeyAttributes, kNumberOfKeyAttributes, item, dict);
-       if (result == noErr) // did we complete OK
+       if (result == errSecSuccess) // did we complete OK
        {
                CFDictionaryAddValue(dict, kSecClass, kSecClassKey);
        }
 
        *dictionary = dict;
 
        {
                CFDictionaryAddValue(dict, kSecClass, kSecClassKey);
        }
 
        *dictionary = dict;
 
-       return noErr;
+       return errSecSuccess;
 #endif
 
        CFMutableDictionaryRef dict = CFDictionaryCreateMutable(allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
 #endif
 
        CFMutableDictionaryRef dict = CFDictionaryCreateMutable(allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
@@ -798,7 +878,7 @@ _CreateAttributesDictionaryFromKeyItem(
     case kSecGenericPasswordItemClass:
                itemID = CSSM_DL_DB_RECORD_GENERIC_PASSWORD;
                break;
     case kSecGenericPasswordItemClass:
                itemID = CSSM_DL_DB_RECORD_GENERIC_PASSWORD;
                break;
-    case kSecAppleSharePasswordItemClass:
+    case 'ashp': /* kSecAppleSharePasswordItemClass */
                itemID = CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD;
                break;
        default:
                itemID = CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD;
                break;
        default:
@@ -858,7 +938,7 @@ _CreateAttributesDictionaryFromKeyItem(
                                                        stringRef = (CFStringRef) kSecAttrKeyClassSymmetric;
                                                        break;
                                                default:
                                                        stringRef = (CFStringRef) kSecAttrKeyClassSymmetric;
                                                        break;
                                                default:
-                                                       stringRef = CFStringCreateWithFormat(allocator, NULL, CFSTR("%d"), keyRecordValue);
+                                                       stringRef = CFStringCreateWithFormat(allocator, NULL, CFSTR("%u"), (unsigned int)keyRecordValue);
                                                        break;
                                        }
                                        if (stringRef) {
                                                        break;
                                        }
                                        if (stringRef) {
@@ -897,10 +977,10 @@ _CreateAttributesDictionaryFromKeyItem(
                                                        stringRef = (CFStringRef) kSecAttrKeyTypeCAST;
                                                        break;
                                                case CSSM_ALGID_ECDSA :
                                                        stringRef = (CFStringRef) kSecAttrKeyTypeCAST;
                                                        break;
                                                case CSSM_ALGID_ECDSA :
-                                                       stringRef = (CFStringRef) kSecAttrKeyTypeECDSA;
+                                                       stringRef = (CFStringRef) kSecAttrKeyTypeEC;
                                                        break;
                                                default :
                                                        break;
                                                default :
-                                                       stringRef = CFStringCreateWithFormat(allocator, NULL, CFSTR("%d"), keyAlgValue);
+                                                       stringRef = CFStringCreateWithFormat(allocator, NULL, CFSTR("%u"), (unsigned int)keyAlgValue);
                                                        retainString = false;
                                                        break;
                                        }
                                                        retainString = false;
                                                        break;
                                        }
@@ -909,7 +989,7 @@ _CreateAttributesDictionaryFromKeyItem(
                                                CFDictionaryAddValue(dict, *(intInfo->newItemType), stringRef);
                                                CFRelease(stringRef);
                                        }
                                                CFDictionaryAddValue(dict, *(intInfo->newItemType), stringRef);
                                                CFRelease(stringRef);
                                        }
-                               }
+                }
                                else {
                                        // normal case: attribute contains a string
                                        stringRef = CFStringCreateWithBytes(allocator, (UInt8*)attribute->data, attribute->length, kCFStringEncodingUTF8, FALSE);
                                else {
                                        // normal case: attribute contains a string
                                        stringRef = CFStringCreateWithBytes(allocator, (UInt8*)attribute->data, attribute->length, kCFStringEncodingUTF8, FALSE);
@@ -923,6 +1003,16 @@ _CreateAttributesDictionaryFromKeyItem(
 
                        case kDataRepresentation:
                        {
 
                        case kDataRepresentation:
                        {
+                if ((intInfo->oldItemType == kSecKeyLabel) && (attribute->length == kUUIDStringLength)) {
+                                       // It's possible that there could be a string here because the key label may have a UUID
+                    CFStringRef stringRef = CFStringCreateWithBytes(allocator, (UInt8*)attribute->data, attribute->length, kCFStringEncodingUTF8, FALSE);
+                                       if (stringRef == NULL)
+                                               stringRef = (CFStringRef) CFRetain(kCFNull);
+                                       CFDictionaryAddValue(dict, *(intInfo->newItemType), stringRef);
+                                       CFRelease(stringRef);
+                    break;
+                }
+
                                CFDataRef dataRef = CFDataCreate(allocator, (UInt8*)attribute->data, attribute->length);
                                if (dataRef == NULL)
                                        dataRef = (CFDataRef) CFRetain(kCFNull);
                                CFDataRef dataRef = CFDataCreate(allocator, (UInt8*)attribute->data, attribute->length);
                                if (dataRef == NULL)
                                        dataRef = (CFDataRef) CFRetain(kCFNull);
@@ -1238,7 +1328,7 @@ _CreateAttributesDictionaryFromItem(
                        *dictionary = NULL;
                        break;
        }
                        *dictionary = NULL;
                        break;
        }
-       return paramErr;
+       return errSecParam;
 }
 
 
 }
 
 
@@ -1279,14 +1369,14 @@ _CFDataCreateAttribute(
        SecKeychainAttrType tag,
        SecKeychainAttributePtr attr)
 {
        SecKeychainAttrType tag,
        SecKeychainAttributePtr attr)
 {
-       OSStatus status = noErr;
+       OSStatus status = errSecSuccess;
        CFRange range;
 
        // set the attribute tag
        attr->tag = tag;
 
        // determine the attribute length
        CFRange range;
 
        // set the attribute tag
        attr->tag = tag;
 
        // determine the attribute length
-       attr->length = CFDataGetLength(data);
+       attr->length = (UInt32) CFDataGetLength(data);
        range = CFRangeMake(0, (CFIndex)attr->length);
 
        // allocate memory for the attribute bytes
        range = CFRangeMake(0, (CFIndex)attr->length);
 
        // allocate memory for the attribute bytes
@@ -1314,7 +1404,7 @@ _CFStringCreateAttribute(
        SecKeychainAttrType tag,
        SecKeychainAttributePtr attr)
 {
        SecKeychainAttrType tag,
        SecKeychainAttributePtr attr)
 {
-       OSStatus status = noErr;
+       OSStatus status = errSecSuccess;
        CFRange range;
 
        // set the attribute tag
        CFRange range;
 
        // set the attribute tag
@@ -1341,7 +1431,7 @@ malloc_failed:
  * _CreateSecKeychainGenericPasswordAttributeListFromDictionary creates a SecKeychainAttributeList
  * from the attribute key/values in attrDictionary.
  *
  * _CreateSecKeychainGenericPasswordAttributeListFromDictionary creates a SecKeychainAttributeList
  * from the attribute key/values in attrDictionary.
  *
- * If this function returns noErr, the pointer to the SecKeychainAttributeList
+ * If this function returns errSecSuccess, the pointer to the SecKeychainAttributeList
  * must be freed by the caller with _FreeAttrList()
  */
 static OSStatus
  * must be freed by the caller with _FreeAttrList()
  */
 static OSStatus
@@ -1357,7 +1447,7 @@ _CreateSecKeychainGenericPasswordAttributeListFromDictionary(
  * _CreateSecKeychainCertificateAttributeListFromDictionary creates a SecKeychainAttributeList
  * from the attribute key/values in attrDictionary.
  *
  * _CreateSecKeychainCertificateAttributeListFromDictionary creates a SecKeychainAttributeList
  * from the attribute key/values in attrDictionary.
  *
- * If this function returns noErr, the pointer to the SecKeychainAttributeList
+ * If this function returns errSecSuccess, the pointer to the SecKeychainAttributeList
  * must be freed by the caller with _FreeAttrList()
  */
 static OSStatus
  * must be freed by the caller with _FreeAttrList()
  */
 static OSStatus
@@ -1373,7 +1463,7 @@ _CreateSecKeychainCertificateAttributeListFromDictionary(
  * _CreateSecKeychainKeyAttributeListFromDictionary creates a SecKeychainAttributeList
  * from the attribute key/values in attrDictionary.
  *
  * _CreateSecKeychainKeyAttributeListFromDictionary creates a SecKeychainAttributeList
  * from the attribute key/values in attrDictionary.
  *
- * If this function returns noErr, the pointer to the SecKeychainAttributeList
+ * If this function returns errSecSuccess, the pointer to the SecKeychainAttributeList
  * must be freed by the caller with _FreeAttrList()
  */
 static OSStatus
  * must be freed by the caller with _FreeAttrList()
  */
 static OSStatus
@@ -1444,7 +1534,13 @@ _CreateSecKeychainKeyAttributeListFromDictionary(
 
        // [3] get the kSecKeyLabel string
        if (CFDictionaryGetValueIfPresent(attrDictionary, kSecAttrApplicationLabel, (const void **)&value) && value) {
 
        // [3] get the kSecKeyLabel string
        if (CFDictionaryGetValueIfPresent(attrDictionary, kSecAttrApplicationLabel, (const void **)&value) && value) {
-               status = _CFStringCreateAttribute((CFStringRef)value, kSecKeyLabel, &attrListPtr->attr[attrListPtr->count]);
+        if (CFStringGetTypeID() == CFGetTypeID(value))
+            status = _CFStringCreateAttribute((CFStringRef)value, kSecKeyLabel, &attrListPtr->attr[attrListPtr->count]);
+        else if (CFDataGetTypeID() == CFGetTypeID(value))
+            status = _CFDataCreateAttribute((CFDataRef)value, kSecKeyLabel, &attrListPtr->attr[attrListPtr->count]);
+        else
+            status = errSecParam;
+
                require_noerr_quiet(status, CFStringCreateAttribute_failed);
 
                ++attrListPtr->count;
                require_noerr_quiet(status, CFStringCreateAttribute_failed);
 
                ++attrListPtr->count;
@@ -1457,7 +1553,7 @@ _CreateSecKeychainKeyAttributeListFromDictionary(
                else if (CFDataGetTypeID() == CFGetTypeID(value))
                        status = _CFDataCreateAttribute((CFDataRef)value, kSecKeyApplicationTag, &attrListPtr->attr[attrListPtr->count]);
                else
                else if (CFDataGetTypeID() == CFGetTypeID(value))
                        status = _CFDataCreateAttribute((CFDataRef)value, kSecKeyApplicationTag, &attrListPtr->attr[attrListPtr->count]);
                else
-                       status = paramErr;
+                       status = errSecParam;
 
                require_noerr_quiet(status, CFDataCreateAttribute_failed);
                ++attrListPtr->count;
 
                require_noerr_quiet(status, CFDataCreateAttribute_failed);
                ++attrListPtr->count;
@@ -1607,7 +1703,7 @@ _CreateSecKeychainKeyAttributeListFromDictionary(
        // return the pointer to the attrList
        *attrList = attrListPtr;
 
        // return the pointer to the attrList
        *attrList = attrListPtr;
 
-       return ( noErr );
+       return ( errSecSuccess );
 
        /***************/
 
 
        /***************/
 
@@ -1626,12 +1722,46 @@ calloc_attrListPtr_failed:
 #endif
 }
 
 #endif
 }
 
+static CFTypeRef copyNumber(CFTypeRef obj)
+{
+    if (!obj)
+        return NULL;
+
+    CFTypeID tid = CFGetTypeID(obj);
+    if (tid == CFNumberGetTypeID())
+    {
+        CFRetain(obj);
+        return obj;
+    }
+
+    if (tid == CFBooleanGetTypeID())
+    {
+        SInt32 value = CFBooleanGetValue((CFBooleanRef)obj);
+        return CFNumberCreate(0, kCFNumberSInt32Type, &value);
+    }
+
+    if (tid == CFStringGetTypeID())
+    {
+        SInt32 value = CFStringGetIntValue((CFStringRef)obj);
+        CFStringRef t = CFStringCreateWithFormat(0, 0, CFSTR("%ld"), (long) value);
+        /* If a string converted to an int isn't equal to the int printed as
+         a string, return a NULL instead. */
+        if (!CFEqual(t, obj))
+        {
+            CFRelease(t);
+            return NULL;
+        }
+        CFRelease(t);
+        return CFNumberCreate(0, kCFNumberSInt32Type, &value);
+    }
+    return NULL;
+}
 
 /*
  * _CreateSecKeychainInternetPasswordAttributeListFromDictionary creates a SecKeychainAttributeList
  * from the attribute key/values in attrDictionary.
  *
 
 /*
  * _CreateSecKeychainInternetPasswordAttributeListFromDictionary creates a SecKeychainAttributeList
  * from the attribute key/values in attrDictionary.
  *
- * If this function returns noErr, the pointer to the SecKeychainAttributeList
+ * If this function returns errSecSuccess, the pointer to the SecKeychainAttributeList
  * must be freed by the caller with _FreeAttrList()
  */
 static OSStatus
  * must be freed by the caller with _FreeAttrList()
  */
 static OSStatus
@@ -1691,9 +1821,12 @@ _CreateSecKeychainInternetPasswordAttributeListFromDictionary(
                attrListPtr->attr[attrListPtr->count].data = malloc(sizeof(UInt16));
                require_action(attrListPtr->attr[attrListPtr->count].data != NULL, malloc_port_failed, status = errSecBufferTooSmall);
 
                attrListPtr->attr[attrListPtr->count].data = malloc(sizeof(UInt16));
                require_action(attrListPtr->attr[attrListPtr->count].data != NULL, malloc_port_failed, status = errSecBufferTooSmall);
 
+        CFTypeRef num = copyNumber(value);
+               require_action(num != NULL, CFStringCreateAttribute_failed, status = errSecParam);
                attrListPtr->attr[attrListPtr->count].tag = kSecPortItemAttr;
                attrListPtr->attr[attrListPtr->count].length = sizeof(UInt16);
                attrListPtr->attr[attrListPtr->count].tag = kSecPortItemAttr;
                attrListPtr->attr[attrListPtr->count].length = sizeof(UInt16);
-               CFNumberGetValue((CFNumberRef)value, kCFNumberSInt16Type, attrListPtr->attr[attrListPtr->count].data);
+               CFNumberGetValue((CFNumberRef)num, kCFNumberSInt16Type, attrListPtr->attr[attrListPtr->count].data);
+        CFRelease(num);
 
                ++attrListPtr->count;
        }
 
                ++attrListPtr->count;
        }
@@ -1751,9 +1884,12 @@ _CreateSecKeychainInternetPasswordAttributeListFromDictionary(
                attrListPtr->attr[attrListPtr->count].data = malloc(sizeof(UInt32));
                require_action(attrListPtr->attr[attrListPtr->count].data != NULL, malloc_port_failed, status = errSecBufferTooSmall);
 
                attrListPtr->attr[attrListPtr->count].data = malloc(sizeof(UInt32));
                require_action(attrListPtr->attr[attrListPtr->count].data != NULL, malloc_port_failed, status = errSecBufferTooSmall);
 
+        CFTypeRef num = copyNumber(value);
+               require_action(num != NULL, CFStringCreateAttribute_failed, status = errSecParam);
                attrListPtr->attr[attrListPtr->count].tag = kSecCreatorItemAttr;
                attrListPtr->attr[attrListPtr->count].length = sizeof(UInt32);
                attrListPtr->attr[attrListPtr->count].tag = kSecCreatorItemAttr;
                attrListPtr->attr[attrListPtr->count].length = sizeof(UInt32);
-               CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, attrListPtr->attr[attrListPtr->count].data);
+               CFNumberGetValue((CFNumberRef)num, kCFNumberSInt32Type, attrListPtr->attr[attrListPtr->count].data);
+        CFRelease(num);
 
                ++attrListPtr->count;
        }
 
                ++attrListPtr->count;
        }
@@ -1763,9 +1899,12 @@ _CreateSecKeychainInternetPasswordAttributeListFromDictionary(
                attrListPtr->attr[attrListPtr->count].data = malloc(sizeof(UInt32));
                require_action(attrListPtr->attr[attrListPtr->count].data != NULL, malloc_port_failed, status = errSecBufferTooSmall);
 
                attrListPtr->attr[attrListPtr->count].data = malloc(sizeof(UInt32));
                require_action(attrListPtr->attr[attrListPtr->count].data != NULL, malloc_port_failed, status = errSecBufferTooSmall);
 
+        CFTypeRef num = copyNumber(value);
+               require_action(num != NULL, CFStringCreateAttribute_failed, status = errSecParam);
                attrListPtr->attr[attrListPtr->count].tag = kSecTypeItemAttr;
                attrListPtr->attr[attrListPtr->count].length = sizeof(UInt32);
                attrListPtr->attr[attrListPtr->count].tag = kSecTypeItemAttr;
                attrListPtr->attr[attrListPtr->count].length = sizeof(UInt32);
-               CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, attrListPtr->attr[attrListPtr->count].data);
+               CFNumberGetValue((CFNumberRef)num, kCFNumberSInt32Type, attrListPtr->attr[attrListPtr->count].data);
+        CFRelease(num);
 
                ++attrListPtr->count;
        }
 
                ++attrListPtr->count;
        }
@@ -1797,7 +1936,7 @@ _CreateSecKeychainInternetPasswordAttributeListFromDictionary(
        // return the pointer to the attrList
        *attrList = attrListPtr;
 
        // return the pointer to the attrList
        *attrList = attrListPtr;
 
-       return ( noErr );
+       return ( errSecSuccess );
 
        /***************/
 
 
        /***************/
 
@@ -1820,7 +1959,7 @@ calloc_attrListPtr_failed:
  * _CreateSecKeychainAttributeListFromDictionary creates a SecKeychainAttributeList
  * from the attribute key/values in attrDictionary for the specified item class.
  *
  * _CreateSecKeychainAttributeListFromDictionary creates a SecKeychainAttributeList
  * from the attribute key/values in attrDictionary for the specified item class.
  *
- * If this function returns noErr, the pointer to the SecKeychainAttributeList
+ * If this function returns errSecSuccess, the pointer to the SecKeychainAttributeList
  * must be freed by the caller with _FreeAttrList()
  */
 static OSStatus
  * must be freed by the caller with _FreeAttrList()
  */
 static OSStatus
@@ -1848,7 +1987,7 @@ _CreateSecKeychainAttributeListFromDictionary(
                default:
                        break;
        }
                default:
                        break;
        }
-       return paramErr;
+       return errSecParam;
 }
 
 
 }
 
 
@@ -1869,7 +2008,7 @@ _AppNameFromSecTrustedApplication(
 
        // get the data for item's application/tool
        status = SecTrustedApplicationCopyData(appRef, &appDataRef);
 
        // get the data for item's application/tool
        status = SecTrustedApplicationCopyData(appRef, &appDataRef);
-       if ( status == noErr ) {
+       if ( status == errSecSuccess ) {
                CFStringRef path;
 
                // convert it to a CFString potentially containing the path
                CFStringRef path;
 
                // convert it to a CFString potentially containing the path
@@ -1971,7 +2110,7 @@ _SecIdentityCopyPublicKey(
                CFRelease(publicKey);
 
 error_exit:
                CFRelease(publicKey);
 
 error_exit:
-       if (status != noErr) {
+       if (status != errSecSuccess) {
                if (publicKeyRef)
                        *publicKeyRef = NULL;
                if (publicKey)
                if (publicKeyRef)
                        *publicKeyRef = NULL;
                if (publicKey)
@@ -2074,7 +2213,7 @@ _SafeSecKeychainItemDelete(
 
                // create SecTrustedApplicationRef for current application/tool
                status = SecTrustedApplicationCreateFromPath(NULL, &currentAppRef);
 
                // create SecTrustedApplicationRef for current application/tool
                status = SecTrustedApplicationCreateFromPath(NULL, &currentAppRef);
-               require((status == noErr) && (currentAppRef != NULL), SecTrustedApplicationCreateFromPathFailed);
+               require((status == errSecSuccess) && (currentAppRef != NULL), SecTrustedApplicationCreateFromPathFailed);
 
                // copy the name out
                currentAppName = _AppNameFromSecTrustedApplication(CFGetAllocator(itemRef), currentAppRef);
 
                // copy the name out
                currentAppName = _AppNameFromSecTrustedApplication(CFGetAllocator(itemRef), currentAppRef);
@@ -2112,16 +2251,16 @@ SecKeychainItemCopyAccessFailed:
        return status;
 }
 
        return status;
 }
 
-OSStatus
+static OSStatus
 _UpdateKeychainItem(CFTypeRef item, CFDictionaryRef changedAttributes)
 {
        // This function updates a single keychain item, which may be specified as
        // a reference, persistent reference or attribute dictionary, with the
        // attributes provided.
 
 _UpdateKeychainItem(CFTypeRef item, CFDictionaryRef changedAttributes)
 {
        // This function updates a single keychain item, which may be specified as
        // a reference, persistent reference or attribute dictionary, with the
        // attributes provided.
 
-       OSStatus status = noErr;
+       OSStatus status = errSecSuccess;
        if (!item) {
        if (!item) {
-               return paramErr;
+               return errSecParam;
        }
 
        SecItemClass itemClass;
        }
 
        SecItemClass itemClass;
@@ -2207,7 +2346,7 @@ _UpdateKeychainItem(CFTypeRef item, CFDictionaryRef changedAttributes)
        // update item
        status = SecKeychainItemModifyContent(itemToUpdate,
                                (changeAttrList->count == 0) ? NULL : changeAttrList,
        // update item
        status = SecKeychainItemModifyContent(itemToUpdate,
                                (changeAttrList->count == 0) ? NULL : changeAttrList,
-                               (theData != NULL) ? CFDataGetLength(theData) : 0,
+                               (theData != NULL) ? (UInt32)CFDataGetLength(theData) : 0,
                                (theData != NULL) ? CFDataGetBytePtrVoid(theData) : NULL);
 
        // one more thing... update access?
                                (theData != NULL) ? CFDataGetBytePtrVoid(theData) : NULL);
 
        // one more thing... update access?
@@ -2222,7 +2361,7 @@ update_failed:
        return status;
 }
 
        return status;
 }
 
-OSStatus
+static OSStatus
 _DeleteKeychainItem(CFTypeRef item)
 {
        // This function deletes a single keychain item, which may be specified as
 _DeleteKeychainItem(CFTypeRef item)
 {
        // This function deletes a single keychain item, which may be specified as
@@ -2230,9 +2369,9 @@ _DeleteKeychainItem(CFTypeRef item)
        // delete non-keychain items or aggregate items (such as a SecIdentityRef);
        // it is assumed that the caller will pass identity components separately.
 
        // delete non-keychain items or aggregate items (such as a SecIdentityRef);
        // it is assumed that the caller will pass identity components separately.
 
-       OSStatus status = noErr;
+       OSStatus status = errSecSuccess;
        if (!item) {
        if (!item) {
-               return paramErr;
+               return errSecParam;
        }
 
        SecKeychainItemRef itemToDelete = NULL;
        }
 
        SecKeychainItemRef itemToDelete = NULL;
@@ -2270,10 +2409,10 @@ _DeleteKeychainItem(CFTypeRef item)
        return status;
 }
 
        return status;
 }
 
-OSStatus
+static OSStatus
 _DeleteIdentity(SecIdentityRef identity)
 {
 _DeleteIdentity(SecIdentityRef identity)
 {
-       OSStatus status, result = noErr;
+       OSStatus status, result = errSecSuccess;
        SecKeyRef privateKey = NULL;
        SecCertificateRef certificate = NULL;
 
        SecKeyRef privateKey = NULL;
        SecCertificateRef certificate = NULL;
 
@@ -2302,28 +2441,28 @@ _DeleteIdentity(SecIdentityRef identity)
        return result;
 }
 
        return result;
 }
 
-OSStatus
+static OSStatus
 _UpdateAggregateStatus(OSStatus newStatus, OSStatus curStatus, OSStatus baseStatus)
 {
        // This function is used when atomically processing multiple items,
        // where an overall error result must be returned for the entire operation.
 _UpdateAggregateStatus(OSStatus newStatus, OSStatus curStatus, OSStatus baseStatus)
 {
        // This function is used when atomically processing multiple items,
        // where an overall error result must be returned for the entire operation.
-       // When newStatus is something other than noErr, we want to keep the "most
+       // When newStatus is something other than errSecSuccess, we want to keep the "most
        // interesting" status (which usually will be newStatus, unless curStatus is
        // already set; in that case, newStatus can trump curStatus only by being
        // something different than baseStatus.)
 
        OSStatus result = curStatus;
 
        // interesting" status (which usually will be newStatus, unless curStatus is
        // already set; in that case, newStatus can trump curStatus only by being
        // something different than baseStatus.)
 
        OSStatus result = curStatus;
 
-       if (newStatus != noErr) {
+       if (newStatus != errSecSuccess) {
                result = newStatus;
                result = newStatus;
-               if (curStatus != noErr) {
+               if (curStatus != errSecSuccess) {
                        result = (newStatus != baseStatus) ? newStatus : curStatus;
                }
        }
        return result;
 }
 
                        result = (newStatus != baseStatus) ? newStatus : curStatus;
                }
        }
        return result;
 }
 
-void
+static void
 _AddDictValueToOtherDict(const void *key, const void *value, void *context)
 {
        // CFDictionaryApplierFunction
 _AddDictValueToOtherDict(const void *key, const void *value, void *context)
 {
        // CFDictionaryApplierFunction
@@ -2429,6 +2568,64 @@ _ConvertItemClass(const void* item, const void* keyClass, Boolean *isIdentity)
        return itemClass;
 }
 
        return itemClass;
 }
 
+static SecItemClass
+_ItemClassFromItemList(CFArrayRef itemList)
+{
+       // Given a list of items (standard or persistent references),
+       // determine whether they all have the same item class. Returns
+       // the item class, or 0 if multiple classes in list.
+       SecItemClass result = 0;
+       CFIndex index, count = (itemList) ? CFArrayGetCount(itemList) : 0;
+       for (index=0; index < count; index++) {
+               CFTypeRef item = (CFTypeRef) CFArrayGetValueAtIndex(itemList, index);
+               if (item) {
+                       SecKeychainItemRef itemRef = NULL;
+                       OSStatus status;
+                       if (CFGetTypeID(item) == CFDataGetTypeID()) {
+                               // persistent reference, resolve first
+                               status = SecKeychainItemCopyFromPersistentReference((CFDataRef)item, &itemRef);
+                       }
+                       else {
+                               itemRef = (SecKeychainItemRef) CFRetain(item);
+                       }
+                       if (itemRef) {
+                               SecItemClass itemClass = 0;
+                               CFTypeID itemTypeID = CFGetTypeID(itemRef);
+                               if (itemTypeID == SecIdentityGetTypeID() || itemTypeID == SecCertificateGetTypeID()) {
+                                       // Identities and certificates have the same underlying item class
+                                       itemClass = kSecCertificateItemClass;
+                               }
+                               else if (itemTypeID == SecKeychainItemGetTypeID()) {
+                                       // Reference to item in a keychain
+                                       status = SecKeychainItemCopyAttributesAndData(itemRef, NULL, &itemClass, NULL, NULL, NULL);
+                               }
+                               else if (itemTypeID == SecKeyGetTypeID()) {
+                                       // SecKey that isn't stored in a keychain
+                                       // %%% will need to change this code when SecKey is no longer CSSM-based %%%
+                                       const CSSM_KEY *cssmKey;
+                                       status = SecKeyGetCSSMKey((SecKeyRef)itemRef, &cssmKey);
+                                       if (status == errSecSuccess) {
+                                               if (cssmKey->KeyHeader.KeyClass == CSSM_KEYCLASS_PUBLIC_KEY)
+                                                       itemClass = kSecPublicKeyItemClass;
+                                               else if (cssmKey->KeyHeader.KeyClass == CSSM_KEYCLASS_PRIVATE_KEY)
+                                                       itemClass = kSecPrivateKeyItemClass;
+                                               else
+                                                       itemClass = kSecSymmetricKeyItemClass;
+                                       }
+                               }
+                               CFRelease(itemRef);
+                               if (itemClass != 0) {
+                                       if (result != 0 && result != itemClass) {
+                                               return 0; // different item classes in list; bail out
+                                       }
+                                       result = itemClass;
+                               }
+                       }
+               }
+       }
+       return result;
+}
+
 // SecItemParams contains a validated set of input parameters, as well as a
 // search reference and attribute list built from those parameters. It is
 // designed to be allocated with _CreateSecItemParamsFromDictionary, and
 // SecItemParams contains a validated set of input parameters, as well as a
 // search reference and attribute list built from those parameters. It is
 // designed to be allocated with _CreateSecItemParamsFromDictionary, and
@@ -2462,18 +2659,20 @@ struct SecItemParams {
        CFTypeRef serialNumber;                         // value for kSecAttrSerialNumber (may be NULL)
        CFTypeRef search;                                       // search reference for this query (SecKeychainSearchRef or SecIdentitySearchRef)
        CFTypeRef assumedKeyClass;                      // if no kSecAttrKeyClass provided, holds the current class we're searching for
        CFTypeRef serialNumber;                         // value for kSecAttrSerialNumber (may be NULL)
        CFTypeRef search;                                       // search reference for this query (SecKeychainSearchRef or SecIdentitySearchRef)
        CFTypeRef assumedKeyClass;                      // if no kSecAttrKeyClass provided, holds the current class we're searching for
+       CFIndex itemListIndex;                          // if no search reference but we have itemList, holds index of next item to return
        SecKeychainAttributeList *attrList;     // attribute list for this query
        SecAccessRef access;                            // access reference (for SecItemAdd only, not used to find items)
        CFDataRef itemData;                                     // item data (for SecItemAdd only, not used to find items)
        SecKeychainAttributeList *attrList;     // attribute list for this query
        SecAccessRef access;                            // access reference (for SecItemAdd only, not used to find items)
        CFDataRef itemData;                                     // item data (for SecItemAdd only, not used to find items)
-       CFTypeRef itemRef;                                      // item reference (to add, update or delete, depending on context)
-       CFDataRef itemPersistentRef;            // item persistent reference (to add, update or delete, depending on context)
+       CFTypeRef itemRef;                                      // item reference (to find, add, update or delete, depending on context)
+       SecIdentityRef identityRef;                     // identity reference (input as kSecValueRef)
+       CFDataRef itemPersistentRef;            // item persistent reference (to find, add, update or delete, depending on context)
 };
 
 static OSStatus
 _ValidateDictionaryEntry(CFDictionaryRef dict, CFTypeRef key, const void **value, CFTypeID expectedTypeID, CFTypeID altTypeID)
 {
        if (!dict || !key || !value || !expectedTypeID)
 };
 
 static OSStatus
 _ValidateDictionaryEntry(CFDictionaryRef dict, CFTypeRef key, const void **value, CFTypeID expectedTypeID, CFTypeID altTypeID)
 {
        if (!dict || !key || !value || !expectedTypeID)
-               return paramErr;
+               return errSecParam;
 
        if (!CFDictionaryGetValueIfPresent(dict, key, value)) {
                // value was not provided for this key (not an error!)
 
        if (!CFDictionaryGetValueIfPresent(dict, key, value)) {
                // value was not provided for this key (not an error!)
@@ -2481,7 +2680,7 @@ _ValidateDictionaryEntry(CFDictionaryRef dict, CFTypeRef key, const void **value
        }
        else if (!(*value)) {
                // provided value is NULL (also not an error!)
        }
        else if (!(*value)) {
                // provided value is NULL (also not an error!)
-               return noErr;
+               return errSecSuccess;
        }
        else {
                CFTypeID actualTypeID = CFGetTypeID(*value);
        }
        else {
                CFTypeID actualTypeID = CFGetTypeID(*value);
@@ -2491,7 +2690,7 @@ _ValidateDictionaryEntry(CFDictionaryRef dict, CFTypeRef key, const void **value
                                (actualTypeID == SecKeyGetTypeID() || actualTypeID == SecCertificateGetTypeID())) {
                                // provided value is a "floating" reference which is not yet in a keychain
                                CFRetain(*value);
                                (actualTypeID == SecKeyGetTypeID() || actualTypeID == SecCertificateGetTypeID())) {
                                // provided value is a "floating" reference which is not yet in a keychain
                                CFRetain(*value);
-                               return noErr;
+                               return errSecSuccess;
                        }
                        return errSecItemInvalidValue;
                }
                        }
                        return errSecItemInvalidValue;
                }
@@ -2500,7 +2699,7 @@ _ValidateDictionaryEntry(CFDictionaryRef dict, CFTypeRef key, const void **value
                        CFRetain(*value);
                }
        }
                        CFRetain(*value);
                }
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 static void
 }
 
 static void
@@ -2526,6 +2725,7 @@ _FreeSecItemParams(SecItemParams *itemParams)
        if (itemParams->access) CFRelease(itemParams->access);
        if (itemParams->itemData) CFRelease(itemParams->itemData);
        if (itemParams->itemRef) CFRelease(itemParams->itemRef);
        if (itemParams->access) CFRelease(itemParams->access);
        if (itemParams->itemData) CFRelease(itemParams->itemData);
        if (itemParams->itemRef) CFRelease(itemParams->itemRef);
+       if (itemParams->identityRef) CFRelease(itemParams->identityRef);
        if (itemParams->itemPersistentRef) CFRelease(itemParams->itemPersistentRef);
 
        _FreeAttrList(itemParams->attrList);
        if (itemParams->itemPersistentRef) CFRelease(itemParams->itemPersistentRef);
 
        _FreeAttrList(itemParams->attrList);
@@ -2540,8 +2740,8 @@ _CreateSecItemParamsFromDictionary(CFDictionaryRef dict, OSStatus *error)
        CFTypeRef value = NULL;
        SecItemParams *itemParams = (SecItemParams *) malloc(sizeof(SecItemParams));
 
        CFTypeRef value = NULL;
        SecItemParams *itemParams = (SecItemParams *) malloc(sizeof(SecItemParams));
 
-       require_action(itemParams != NULL, error_exit, status = memFullErr);
-       require_action(dict && (CFDictionaryGetTypeID() == CFGetTypeID(dict)), error_exit, status = paramErr);
+       require_action(itemParams != NULL, error_exit, status = errSecAllocate);
+       require_action(dict && (CFDictionaryGetTypeID() == CFGetTypeID(dict)), error_exit, status = errSecParam);
 
        memset(itemParams, 0, sizeof(SecItemParams));
        itemParams->query = (CFDictionaryRef) CFRetain(dict);
 
        memset(itemParams, 0, sizeof(SecItemParams));
        itemParams->query = (CFDictionaryRef) CFRetain(dict);
@@ -2563,33 +2763,16 @@ _CreateSecItemParamsFromDictionary(CFDictionaryRef dict, OSStatus *error)
        require_noerr(status = _ValidateDictionaryEntry(dict, kSecAttrService, (const void **)&itemParams->service, CFStringGetTypeID(), NULL), error_exit);
        require_noerr(status = _ValidateDictionaryEntry(dict, kSecAttrKeyClass, (const void **)&itemParams->keyClass, CFStringGetTypeID(), NULL), error_exit);
 
        require_noerr(status = _ValidateDictionaryEntry(dict, kSecAttrService, (const void **)&itemParams->service, CFStringGetTypeID(), NULL), error_exit);
        require_noerr(status = _ValidateDictionaryEntry(dict, kSecAttrKeyClass, (const void **)&itemParams->keyClass, CFStringGetTypeID(), NULL), error_exit);
 
-       // must have an item class, unless we have an item list to add
-       if (!CFDictionaryGetValueIfPresent(dict, kSecClass, (const void**) &value) && !itemParams->useItems)
-               require_action(false, error_exit, status = errSecItemClassMissing);
-       else if (value) {
-               itemParams->itemClass = _ConvertItemClass(value, itemParams->keyClass, &itemParams->returnIdentity);
-               if (itemParams->itemClass == kSecSymmetricKeyItemClass && !itemParams->keyClass) {
-                       itemParams->assumedKeyClass = kSecAttrKeyClassSymmetric; // no key class specified, so start with symmetric key class; will search the others later
-               }
-               require_action(!(itemParams->itemClass == 0), error_exit, status = errSecItemClassMissing);
-       }
-
-       itemParams->keyUsage = _CssmKeyUsageFromQuery(dict);
-       itemParams->trustedOnly = CFDictionaryGetValueIfPresent(dict, kSecMatchTrustedOnly, (const void **)&value) && value && CFEqual(kCFBooleanTrue, value);
-       itemParams->issuerAndSNToMatch = (itemParams->issuer != NULL && itemParams->serialNumber != NULL);
-
-       // other input attributes, used for SecItemAdd but not for finding items
-       require_noerr(status = _ValidateDictionaryEntry(dict, kSecAttrAccess, (const void **)&itemParams->access, SecAccessGetTypeID(), NULL), error_exit);
-       if (itemParams->access == NULL) {
-               // check for the old definition of kSecAttrAccess from SecItem-shim (see <rdar://7987447>)
-               require_noerr(status = _ValidateDictionaryEntry(dict, CFSTR("kSecAttrAccess"), (const void **)&itemParams->access, SecAccessGetTypeID(), NULL), error_exit);
-       }
-
        // validate the payload (password, key or certificate data), used for SecItemAdd but not for finding items
        require_noerr(status = _ValidateDictionaryEntry(dict, kSecValueData, (const void **)&itemParams->itemData, CFDataGetTypeID(), CFStringGetTypeID()), error_exit);
 
        // validate item references
        // validate the payload (password, key or certificate data), used for SecItemAdd but not for finding items
        require_noerr(status = _ValidateDictionaryEntry(dict, kSecValueData, (const void **)&itemParams->itemData, CFDataGetTypeID(), CFStringGetTypeID()), error_exit);
 
        // validate item references
-       require_noerr(status = _ValidateDictionaryEntry(dict, kSecValueRef, (const void **)&itemParams->itemRef, SecKeychainItemGetTypeID(), NULL), error_exit);
+       require_noerr(status = _ValidateDictionaryEntry(dict, kSecValueRef, (const void **)&itemParams->itemRef, SecKeychainItemGetTypeID(), SecIdentityGetTypeID()), error_exit);
+       if (itemParams->itemRef && (CFGetTypeID(itemParams->itemRef) == SecIdentityGetTypeID())) {
+               itemParams->identityRef = (SecIdentityRef)itemParams->itemRef;
+               itemParams->itemRef = NULL;
+               SecIdentityCopyCertificate(itemParams->identityRef, (SecCertificateRef *)&itemParams->itemRef);
+       }
        require_noerr(status = _ValidateDictionaryEntry(dict, kSecValuePersistentRef, (const void **)&itemParams->itemPersistentRef, CFDataGetTypeID(), NULL), error_exit);
        if (itemParams->itemRef || itemParams->itemPersistentRef) {
                // Caller is trying to add or find an item by reference.
        require_noerr(status = _ValidateDictionaryEntry(dict, kSecValuePersistentRef, (const void **)&itemParams->itemPersistentRef, CFDataGetTypeID(), NULL), error_exit);
        if (itemParams->itemRef || itemParams->itemPersistentRef) {
                // Caller is trying to add or find an item by reference.
@@ -2617,6 +2800,35 @@ _CreateSecItemParamsFromDictionary(CFDictionaryRef dict, OSStatus *error)
                if (itemParams->itemPersistentRef) CFArrayAppendValue((CFMutableArrayRef)itemParams->itemList, itemParams->itemPersistentRef);
        }
 
                if (itemParams->itemPersistentRef) CFArrayAppendValue((CFMutableArrayRef)itemParams->itemList, itemParams->itemPersistentRef);
        }
 
+       // must have an explicit item class, unless one of the following is true:
+       //   - we have an item list to add or search (kSecUseItemList)
+       //   - we have an item reference or persistent reference for the thing we want to look up
+       // Note that both of these cases will set itemParams->useItems.
+       // If we have an item list to match (kSecMatchItemList), that still requires an item class,
+       // so we can perform a search and see if the results match items in the list.
+       //
+       if (!CFDictionaryGetValueIfPresent(dict, kSecClass, (const void**) &value) && !itemParams->useItems) {
+               require_action(false, error_exit, status = errSecItemClassMissing);
+       }
+       else if (value) {
+               itemParams->itemClass = _ConvertItemClass(value, itemParams->keyClass, &itemParams->returnIdentity);
+               if (itemParams->itemClass == kSecSymmetricKeyItemClass && !itemParams->keyClass) {
+                       itemParams->assumedKeyClass = kSecAttrKeyClassSymmetric; // no key class specified, so start with symmetric key class; will search the others later
+               }
+               require_action(!(itemParams->itemClass == 0 && !itemParams->useItems), error_exit, status = errSecItemClassMissing);
+       }
+
+       itemParams->keyUsage = _CssmKeyUsageFromQuery(dict);
+       itemParams->trustedOnly = CFDictionaryGetValueIfPresent(dict, kSecMatchTrustedOnly, (const void **)&value) && value && CFEqual(kCFBooleanTrue, value);
+       itemParams->issuerAndSNToMatch = (itemParams->issuer != NULL && itemParams->serialNumber != NULL);
+
+       // other input attributes, used for SecItemAdd but not for finding items
+       require_noerr(status = _ValidateDictionaryEntry(dict, kSecAttrAccess, (const void **)&itemParams->access, SecAccessGetTypeID(), NULL), error_exit);
+       if (itemParams->access == NULL) {
+               // check for the old definition of kSecAttrAccess from SecItem-shim (see <rdar://7987447>)
+               require_noerr(status = _ValidateDictionaryEntry(dict, CFSTR("kSecAttrAccess"), (const void **)&itemParams->access, SecAccessGetTypeID(), NULL), error_exit);
+       }
+
        // determine how to return the result
        itemParams->numResultTypes = 0;
        itemParams->returningRef = CFDictionaryGetValueIfPresent(dict, kSecReturnRef, (const void **)&value) && value && CFEqual(kCFBooleanTrue, value);
        // determine how to return the result
        itemParams->numResultTypes = 0;
        itemParams->returningRef = CFDictionaryGetValueIfPresent(dict, kSecReturnRef, (const void **)&value) && value && CFEqual(kCFBooleanTrue, value);
@@ -2654,9 +2866,13 @@ _CreateSecItemParamsFromDictionary(CFDictionaryRef dict, OSStatus *error)
                require_noerr(status, error_exit);
        }
 
                require_noerr(status, error_exit);
        }
 
-       // if useItems was provided, we don't need an attribute list or a search reference for adding, although we definitely need one for searching
-       if (itemParams->useItems && itemParams->itemClass == 0) {
-               require_action(false, error_exit, status = noErr); // all done here
+       // if we already have an item list (to add or find items in), we don't need an item class, attribute list or a search reference
+       if (itemParams->useItems) {
+               if (itemParams->itemClass == 0) {
+                       itemParams->itemClass = _ItemClassFromItemList(itemParams->useItems);
+               }
+               status = errSecSuccess;
+               goto error_exit; // all done here
        }
 
        // build a SecKeychainAttributeList from the query dictionary for the specified item class
        }
 
        // build a SecKeychainAttributeList from the query dictionary for the specified item class
@@ -2667,7 +2883,7 @@ _CreateSecItemParamsFromDictionary(CFDictionaryRef dict, OSStatus *error)
                // searching for certificates by email address
                char *nameBuf = (char*)malloc(MAXPATHLEN);
                if (!nameBuf) {
                // searching for certificates by email address
                char *nameBuf = (char*)malloc(MAXPATHLEN);
                if (!nameBuf) {
-                       status = memFullErr;
+                       status = errSecAllocate;
                }
                else if (CFStringGetCString((CFStringRef)itemParams->emailAddrToMatch, nameBuf, (CFIndex)MAXPATHLEN-1, kCFStringEncodingUTF8)) {
                        status = SecKeychainSearchCreateForCertificateByEmail(itemParams->searchList, (const char *)nameBuf, (SecKeychainSearchRef*)&itemParams->search);
                }
                else if (CFStringGetCString((CFStringRef)itemParams->emailAddrToMatch, nameBuf, (CFIndex)MAXPATHLEN-1, kCFStringEncodingUTF8)) {
                        status = SecKeychainSearchCreateForCertificateByEmail(itemParams->searchList, (const char *)nameBuf, (SecKeychainSearchRef*)&itemParams->search);
@@ -2719,7 +2935,7 @@ error_exit:
 }
 
 
 }
 
 
-OSStatus
+static OSStatus
 _ImportKey(
        SecKeyRef keyRef,
        SecKeychainRef keychainRef,
 _ImportKey(
        SecKeyRef keyRef,
        SecKeychainRef keychainRef,
@@ -2760,7 +2976,7 @@ _ImportKey(
        END_SECAPI
 }
 
        END_SECAPI
 }
 
-Boolean
+static Boolean
 _CanIgnoreLeafStatusCodes(CSSM_TP_APPLE_EVIDENCE_INFO *evidence)
 {
        /* Check for ignorable status codes in leaf certificate's evidence */
 _CanIgnoreLeafStatusCodes(CSSM_TP_APPLE_EVIDENCE_INFO *evidence)
 {
        /* Check for ignorable status codes in leaf certificate's evidence */
@@ -2783,8 +2999,8 @@ _CanIgnoreLeafStatusCodes(CSSM_TP_APPLE_EVIDENCE_INFO *evidence)
        return result;
 }
 
        return result;
 }
 
-OSStatus
-_FilterWithPolicy(SecPolicyRef policy, SecCertificateRef cert)
+static OSStatus
+_FilterWithPolicy(SecPolicyRef policy, CFDateRef date, SecCertificateRef cert)
 {
        CFDictionaryRef props = NULL;
        CFArrayRef keychains = NULL;
 {
        CFDictionaryRef props = NULL;
        CFArrayRef keychains = NULL;
@@ -2797,12 +3013,18 @@ _FilterWithPolicy(SecPolicyRef policy, SecCertificateRef cert)
        CSSM_TP_APPLE_EVIDENCE_INFO *evidence = NULL;
        Boolean needChain = false;
        OSStatus status;
        CSSM_TP_APPLE_EVIDENCE_INFO *evidence = NULL;
        Boolean needChain = false;
        OSStatus status;
-       if (!policy || !cert) return paramErr;
+       if (!policy || !cert) return errSecParam;
 
        certs = CFArrayCreate(NULL, (const void **)&cert, (CFIndex)1, &kCFTypeArrayCallBacks);
        status = SecTrustCreateWithCertificates(certs, policy, &trust);
        if(status) goto cleanup;
 
 
        certs = CFArrayCreate(NULL, (const void **)&cert, (CFIndex)1, &kCFTypeArrayCallBacks);
        status = SecTrustCreateWithCertificates(certs, policy, &trust);
        if(status) goto cleanup;
 
+       /* Set evaluation date, if specified (otherwise current date is implied) */
+       if (date && (CFGetTypeID(date) == CFDateGetTypeID())) {
+               status = SecTrustSetVerifyDate(trust, date);
+               if(status) goto cleanup;
+       }
+
        /* Check whether this is the X509 Basic policy, which means chain building */
        props = SecPolicyCopyProperties(policy);
        if (props) {
        /* Check whether this is the X509 Basic policy, which means chain building */
        props = SecPolicyCopyProperties(policy);
        if (props) {
@@ -2854,7 +3076,7 @@ _FilterWithPolicy(SecPolicyRef policy, SecCertificateRef cert)
        if((evidence != NULL) && _CanIgnoreLeafStatusCodes(evidence) &&
           ((evidence[0].StatusBits & CSSM_CERT_STATUS_EXPIRED) == 0) &&
           ((evidence[0].StatusBits & CSSM_CERT_STATUS_NOT_VALID_YET) == 0)) {
        if((evidence != NULL) && _CanIgnoreLeafStatusCodes(evidence) &&
           ((evidence[0].StatusBits & CSSM_CERT_STATUS_EXPIRED) == 0) &&
           ((evidence[0].StatusBits & CSSM_CERT_STATUS_NOT_VALID_YET) == 0)) {
-               status = noErr;
+               status = errSecSuccess;
        }
        else {
                status = errSecCertificateCannotOperate;
        }
        else {
                status = errSecCertificateCannotOperate;
@@ -2871,10 +3093,10 @@ cleanup:
        return status;
 }
 
        return status;
 }
 
-OSStatus
+static OSStatus
 _FilterWithDate(CFTypeRef validOnDate, SecCertificateRef cert)
 {
 _FilterWithDate(CFTypeRef validOnDate, SecCertificateRef cert)
 {
-       if (!validOnDate || !cert) return paramErr;
+       if (!validOnDate || !cert) return errSecParam;
 
        CFAbsoluteTime at, nb, na;
        if (CFGetTypeID(validOnDate) == CFDateGetTypeID())
 
        CFAbsoluteTime at, nb, na;
        if (CFGetTypeID(validOnDate) == CFDateGetTypeID())
@@ -2882,35 +3104,25 @@ _FilterWithDate(CFTypeRef validOnDate, SecCertificateRef cert)
        else
                at = CFAbsoluteTimeGetCurrent();
 
        else
                at = CFAbsoluteTimeGetCurrent();
 
-       OSStatus status = noErr;
-       SecCertificateRefP certP = NULL;
-       CFDataRef certData = SecCertificateCopyData(cert);
-       if (certData) {
-               certP = SecCertificateCreateWithDataP(kCFAllocatorDefault, certData);
-       }
-       if (certP) {
-               nb = SecCertificateNotValidBefore(certP);
-               na = SecCertificateNotValidAfter(certP);
+       OSStatus status = errSecSuccess;
+       nb = SecCertificateNotValidBefore(cert);
+       na = SecCertificateNotValidAfter(cert);
 
 
-               if(at < nb)
-                       status = errSecCertificateNotValidYet;
-               else if (at > na)
-                       status = errSecCertificateExpired;
-       }
-       else {
+       if (nb == 0 || na == 0 || nb == na)
                status = errSecCertificateCannotOperate;
                status = errSecCertificateCannotOperate;
-       }
+       else if (at < nb)
+               status = errSecCertificateNotValidYet;
+       else if (at > na)
+               status = errSecCertificateExpired;
 
 
-       if(certData) CFRelease(certData);
-       if(certP) CFRelease(certP);
        return status;
 }
 
        return status;
 }
 
-OSStatus
+static OSStatus
 _FilterWithTrust(Boolean trustedOnly, SecCertificateRef cert)
 {
 _FilterWithTrust(Boolean trustedOnly, SecCertificateRef cert)
 {
-       if (!cert) return paramErr;
-       if (!trustedOnly) return noErr;
+       if (!cert) return errSecParam;
+       if (!trustedOnly) return errSecSuccess;
 
        CFArrayRef certArray = CFArrayCreate(NULL, (const void**)&cert, 1, &kCFTypeArrayCallBacks);
        SecPolicyRef policy = SecPolicyCreateWithOID(kSecPolicyAppleX509Basic);
 
        CFArrayRef certArray = CFArrayCreate(NULL, (const void**)&cert, 1, &kCFTypeArrayCallBacks);
        SecPolicyRef policy = SecPolicyCreateWithOID(kSecPolicyAppleX509Basic);
@@ -2938,7 +3150,42 @@ _FilterWithTrust(Boolean trustedOnly, SecCertificateRef cert)
        return status;
 }
 
        return status;
 }
 
-OSStatus
+static SecKeychainItemRef
+CopyResolvedKeychainItem(CFTypeRef item)
+{
+       SecKeychainItemRef kcItem = NULL;
+       OSStatus status;
+       if (item) {
+               if (CFGetTypeID(item) == CFDataGetTypeID()) {
+                       // persistent reference, resolve first
+                       status = SecKeychainItemCopyFromPersistentReference((CFDataRef)item, &kcItem);
+               }
+               else {
+                       // normal reference
+                       kcItem = (SecKeychainItemRef) CFRetain(item);
+               }
+               if (kcItem) {
+                       // ask for the item's class:
+                       // will return an error if the item has been deleted
+                       SecItemClass itemClass;
+                       SecKeychainItemRef certRef = NULL;
+                       if (CFGetTypeID(kcItem) == SecIdentityGetTypeID()) {
+                               status = SecIdentityCopyCertificate((SecIdentityRef)kcItem, (SecCertificateRef *)&certRef);
+                       }
+                       status = SecKeychainItemCopyAttributesAndData((certRef) ? certRef : kcItem, NULL, &itemClass, NULL, NULL, NULL);
+                       if (certRef) {
+                               CFRelease(certRef);
+                       }
+                       if (status) {
+                               CFRelease(kcItem);
+                               kcItem = NULL;
+                       }
+               }
+       }
+       return kcItem;
+}
+
+static OSStatus
 UpdateKeychainSearchAndCopyNext(SecItemParams *params, CFTypeRef *item)
 {
        // This function refreshes the search parameters in the specific case where
 UpdateKeychainSearchAndCopyNext(SecItemParams *params, CFTypeRef *item)
 {
        // This function refreshes the search parameters in the specific case where
@@ -2976,12 +3223,12 @@ UpdateKeychainSearchAndCopyNext(SecItemParams *params, CFTypeRef *item)
        }
 
        // Rebuild the attribute list for the new key class.
        }
 
        // Rebuild the attribute list for the new key class.
-       if (_CreateSecKeychainAttributeListFromDictionary(dict, params->itemClass, &params->attrList) == noErr) {
+       if (_CreateSecKeychainAttributeListFromDictionary(dict, params->itemClass, &params->attrList) == errSecSuccess) {
                // Create a new search reference for the new attribute list.
                if (SecKeychainSearchCreateFromAttributes(params->searchList,
                        params->itemClass,
                        (params->attrList->count == 0) ? NULL : params->attrList,
                // Create a new search reference for the new attribute list.
                if (SecKeychainSearchCreateFromAttributes(params->searchList,
                        params->itemClass,
                        (params->attrList->count == 0) ? NULL : params->attrList,
-                       (SecKeychainSearchRef*)&params->search) == noErr) {
+                       (SecKeychainSearchRef*)&params->search) == errSecSuccess) {
                        // Return the first matching item from the new search.
                        // We won't come back here again until there are no more matching items for this search.
                        status = SecKeychainSearchCopyNext((SecKeychainSearchRef)params->search, (SecKeychainItemRef*)item);
                        // Return the first matching item from the new search.
                        // We won't come back here again until there are no more matching items for this search.
                        status = SecKeychainSearchCopyNext((SecKeychainSearchRef)params->search, (SecKeychainItemRef*)item);
@@ -2991,7 +3238,7 @@ UpdateKeychainSearchAndCopyNext(SecItemParams *params, CFTypeRef *item)
 }
 
 
 }
 
 
-OSStatus
+static OSStatus
 SecItemSearchCopyNext(SecItemParams *params, CFTypeRef *item)
 {
        // Generic "copy next match" function for SecKeychainSearchRef or SecIdentitySearchRef.
 SecItemSearchCopyNext(SecItemParams *params, CFTypeRef *item)
 {
        // Generic "copy next match" function for SecKeychainSearchRef or SecIdentitySearchRef.
@@ -3010,13 +3257,35 @@ SecItemSearchCopyNext(SecItemParams *params, CFTypeRef *item)
                while (status == errSecItemNotFound && params->assumedKeyClass != NULL)
                        status = UpdateKeychainSearchAndCopyNext(params, item);
        }
                while (status == errSecItemNotFound && params->assumedKeyClass != NULL)
                        status = UpdateKeychainSearchAndCopyNext(params, item);
        }
+       else if (typeID == 0 && (params->useItems || params->itemList)) {
+               // No search available, but there is an item list available.
+               // Return the next candidate item from the caller's item list
+               CFArrayRef itemList = (params->useItems) ? params->useItems : params->itemList;
+               CFIndex count = CFArrayGetCount(itemList);
+               *item = (CFTypeRef) NULL;
+               if (params->itemListIndex < count) {
+                       *item = (CFTypeRef)CFArrayGetValueAtIndex(itemList, params->itemListIndex++);
+                       if (*item) {
+                               // Potentially resolve persistent item references here, and
+                               // verify the item reference we're about to hand back is still
+                               // valid (it could have been deleted from the keychain while
+                               // our query was holding onto the itemList).
+                               *item = CopyResolvedKeychainItem(*item);
+                               if (*item && (CFGetTypeID(*item) == SecIdentityGetTypeID())) {
+                                       // Persistent reference resolved to an identity, so return that type.
+                                       params->returnIdentity = true;
+                               }
+                       }
+               }
+               status = (*item) ? errSecSuccess : errSecItemNotFound;
+       }
        else {
                status = errSecItemNotFound;
        }
        return status;
 }
 
        else {
                status = errSecItemNotFound;
        }
        return status;
 }
 
-OSStatus
+static OSStatus
 FilterCandidateItem(CFTypeRef *item, SecItemParams *itemParams, SecIdentityRef *identity)
 {
        if (!item || *item == NULL || !itemParams)
 FilterCandidateItem(CFTypeRef *item, SecItemParams *itemParams, SecIdentityRef *identity)
 {
        if (!item || *item == NULL || !itemParams)
@@ -3095,9 +3364,9 @@ FilterCandidateItem(CFTypeRef *item, SecItemParams *itemParams, SecIdentityRef *
                        // certificate item is part of an identity; proceed to next check
                }
                if (itemParams->policy) {
                        // certificate item is part of an identity; proceed to next check
                }
                if (itemParams->policy) {
-                       status = _FilterWithPolicy(itemParams->policy, (SecCertificateRef) *item);
+                       status = _FilterWithPolicy(itemParams->policy, (CFDateRef)itemParams->validOnDate, (SecCertificateRef) *item);
                        if (status) goto filterOut;
                        if (status) goto filterOut;
-                       // certificate item is valid for specified policy
+                       // certificate item is valid for specified policy (and optionally specified date)
                }
                if (itemParams->validOnDate) {
                        status = _FilterWithDate(itemParams->validOnDate, (SecCertificateRef) *item);
                }
                if (itemParams->validOnDate) {
                        status = _FilterWithDate(itemParams->validOnDate, (SecCertificateRef) *item);
@@ -3125,11 +3394,11 @@ FilterCandidateItem(CFTypeRef *item, SecItemParams *itemParams, SecIdentityRef *
                                continue;
                        }
                        if (CFDataGetTypeID() == CFGetTypeID(anItem) &&
                                continue;
                        }
                        if (CFDataGetTypeID() == CFGetTypeID(anItem) &&
-                               noErr == SecKeychainItemCopyFromPersistentReference((CFDataRef)anItem, &realItem)) {
+                               errSecSuccess == SecKeychainItemCopyFromPersistentReference((CFDataRef)anItem, &realItem)) {
                                anItem = realItem;
                        }
                        if (SecIdentityGetTypeID() == CFGetTypeID(anItem) &&
                                anItem = realItem;
                        }
                        if (SecIdentityGetTypeID() == CFGetTypeID(anItem) &&
-                               noErr == SecIdentityCopyCertificate((SecIdentityRef)anItem, &aCert)) {
+                               errSecSuccess == SecIdentityCopyCertificate((SecIdentityRef)anItem, &aCert)) {
                                anItem = aCert;
                        }
                        if (CFEqual(anItem, (CFTypeRef) *item)) {
                                anItem = aCert;
                        }
                        if (CFEqual(anItem, (CFTypeRef) *item)) {
@@ -3157,7 +3426,7 @@ FilterCandidateItem(CFTypeRef *item, SecItemParams *itemParams, SecIdentityRef *
        }
 
        // if we get here, consider the item a match
        }
 
        // if we get here, consider the item a match
-       return noErr;
+       return errSecSuccess;
 
 filterOut:
        if (commonName) {
 
 filterOut:
        if (commonName) {
@@ -3174,7 +3443,7 @@ filterOut:
        return errSecItemNotFound;
 }
 
        return errSecItemNotFound;
 }
 
-OSStatus
+static OSStatus
 AddItemResults(SecKeychainItemRef item,
        SecIdentityRef identity,
        SecItemParams *itemParams,
 AddItemResults(SecKeychainItemRef item,
        SecIdentityRef identity,
        SecItemParams *itemParams,
@@ -3204,17 +3473,17 @@ AddItemResults(SecKeychainItemRef item,
        // Note that we allocate *items if needed.
 
        if (!item || !itemParams || !result)
        // Note that we allocate *items if needed.
 
        if (!item || !itemParams || !result)
-               return paramErr;
+               return errSecParam;
 
        if (itemParams->maxMatches > 1) {
                // if we can return more than one item, we must have an array
                if (!items)
 
        if (itemParams->maxMatches > 1) {
                // if we can return more than one item, we must have an array
                if (!items)
-                       return paramErr;
+                       return errSecParam;
                else if (*items == NULL)
                        *items = CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks);
        }
 
                else if (*items == NULL)
                        *items = CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks);
        }
 
-       OSStatus tmpStatus, status = noErr;
+       OSStatus tmpStatus, status = errSecSuccess;
        CFMutableArrayRef itemArray = (items) ? *items : NULL;
        CFMutableDictionaryRef itemDict = NULL;
        if (itemParams->numResultTypes > 1) {
        CFMutableArrayRef itemArray = (items) ? *items : NULL;
        CFMutableDictionaryRef itemDict = NULL;
        if (itemParams->numResultTypes > 1) {
@@ -3237,8 +3506,12 @@ AddItemResults(SecKeychainItemRef item,
 
        if (itemParams->returningPersistentRef) {
                CFDataRef persistentRef;
 
        if (itemParams->returningPersistentRef) {
                CFDataRef persistentRef;
-               tmpStatus = SecKeychainItemCreatePersistentReference(item, &persistentRef);
-               if (tmpStatus == noErr) {
+               SecKeychainItemRef tmpItem = item;
+               if (itemParams->identityRef) {
+                       tmpItem = (SecKeychainItemRef)itemParams->identityRef;
+               }
+               tmpStatus = SecKeychainItemCreatePersistentReference(tmpItem, &persistentRef);
+               if (tmpStatus == errSecSuccess) {
                        if (itemDict) {
                                CFDictionaryAddValue(itemDict, kSecValuePersistentRef, persistentRef);
                        }
                        if (itemDict) {
                                CFDictionaryAddValue(itemDict, kSecValuePersistentRef, persistentRef);
                        }
@@ -3250,7 +3523,7 @@ AddItemResults(SecKeychainItemRef item,
                        }
                        CFRelease(persistentRef);
                }
                        }
                        CFRelease(persistentRef);
                }
-               else if (status == noErr) {
+               else if (status == errSecSuccess) {
                        status = tmpStatus;
                }
        }
                        status = tmpStatus;
                }
        }
@@ -3259,7 +3532,7 @@ AddItemResults(SecKeychainItemRef item,
                UInt32 length;
                void *data;
                tmpStatus = SecKeychainItemCopyContent(item, NULL, NULL, &length, &data);
                UInt32 length;
                void *data;
                tmpStatus = SecKeychainItemCopyContent(item, NULL, NULL, &length, &data);
-               if (tmpStatus == noErr) {
+               if (tmpStatus == errSecSuccess) {
                        CFDataRef dataRef = CFDataCreate(allocator, (UInt8 *)data, length);
                        if (itemDict) {
                                CFDictionaryAddValue(itemDict, kSecValueData, dataRef);
                        CFDataRef dataRef = CFDataCreate(allocator, (UInt8 *)data, length);
                        if (itemDict) {
                                CFDictionaryAddValue(itemDict, kSecValueData, dataRef);
@@ -3273,7 +3546,7 @@ AddItemResults(SecKeychainItemRef item,
                        CFRelease(dataRef);
                        (void) SecKeychainItemFreeContent(NULL, data);
                }
                        CFRelease(dataRef);
                        (void) SecKeychainItemFreeContent(NULL, data);
                }
-               else if (status == noErr) {
+               else if (status == errSecSuccess) {
                        status = tmpStatus;
                }
        }
                        status = tmpStatus;
                }
        }
@@ -3300,7 +3573,7 @@ AddItemResults(SecKeychainItemRef item,
                        }
                        CFRelease(attrsDict);
                }
                        }
                        CFRelease(attrsDict);
                }
-               if (tmpStatus && (status == noErr)) {
+               if (tmpStatus && (status == errSecSuccess)) {
                        status = tmpStatus;
                }
        }
                        status = tmpStatus;
                }
        }
@@ -3322,86 +3595,833 @@ AddItemResults(SecKeychainItemRef item,
        return status;
 }
 
        return status;
 }
 
+CFDataRef _SecItemGetPersistentReference(CFTypeRef raw_item)
+{
+       try {
+               Item item = ItemImpl::required((SecKeychainItemRef)raw_item);
+               return item->getPersistentRef();
+       } catch(...) {
+               return NULL;
+       }
+}
 
 /******************************************************************************/
 #pragma mark SecItem API functions
 /******************************************************************************/
 
 
 /******************************************************************************/
 #pragma mark SecItem API functions
 /******************************************************************************/
 
+//
+// Approximate result of using iOS sec's copyNumber, 0 return could be zero, or error.
+//
+static SInt32 readNumber(CFTypeRef obj) {
+    CFTypeID tid = CFGetTypeID(obj);
+    SInt32 v = 0;
+    if (tid == CFNumberGetTypeID()) {
+        CFNumberGetValue((CFNumberRef)obj, kCFNumberSInt32Type, &v);
+        return v;
+    } else if (tid == CFBooleanGetTypeID()) {
+        v = CFBooleanGetValue((CFBooleanRef)obj);
+        return v;
+    } else if (tid == CFStringGetTypeID()) {
+        v = CFStringGetIntValue((CFStringRef)obj);
+        CFStringRef t = CFStringCreateWithFormat(0, 0, CFSTR("%ld"), (long)v);
+        /* If a string converted to an int isn't equal to the int printed as
+         a string, return a CFStringRef instead. */
+        if (!CFEqual(t, obj)) {
+            CFRelease(t);
+            return 0;
+        }
+        CFRelease(t);
+        return v;
+    } else
+        return NULL;
+}
+
+//
+// Function to ensure the syncable keychain is unlocked.
+// Currently, this means unlocking the login keychain,
+// which will also unlock the keybag as a side effect.
+//
+static OSStatus SecItemUnlockSynchronizableKeychain()
+{
+       SecKeychainRef keychain = NULL;
+       OSStatus status = SecKeychainCopyLogin(&keychain);
+       if (!status) {
+               status = SecKeychainUnlock(keychain, 0, NULL, false);
+       }
+       CFReleaseSafe(keychain);
+       return status;
+}
+
+//
+// Function to check whether the kSecAttrSynchronizable flag is set in the query.
+//
 static Boolean SecItemSynchronizable(CFDictionaryRef query)
 {
 static Boolean SecItemSynchronizable(CFDictionaryRef query)
 {
-    static dispatch_once_t onceToken;
-    static Boolean synchronizable = false;
+       CFTypeRef value = CFDictionaryGetValue(query, kSecAttrSynchronizable);
+       Boolean result = (value && readNumber(value));
 
 
-    //sudo defaults write /Library/Preferences/com.apple.security SecItemSynchronizable -bool YES
-    dispatch_once(&onceToken, ^{
-               CFTypeRef sync = (CFNumberRef)CFPreferencesCopyValue(CFSTR("SecItemSynchronizable"), CFSTR("com.apple.security"), kCFPreferencesAnyUser, kCFPreferencesCurrentHost);
+       return result;
+}
 
 
-        if (sync && CFGetTypeID(sync) == CFBooleanGetTypeID()) {
-            synchronizable = CFBooleanGetValue((CFBooleanRef)sync);
-            CFRelease(sync);
-        }
-    });
+//
+// Function to check whether the kSecAttrSynchronizable flag is set in the query,
+// and has the special value of kSecAttrSynchronizableAny.
+//
+static Boolean SecItemSynchronizableAny(CFDictionaryRef query)
+{
+       CFTypeRef value = CFDictionaryGetValue(query, kSecAttrSynchronizable);
+       if (value) {
+               return (CFGetTypeID(value) == CFStringGetTypeID() &&
+                               CFEqual(value, kSecAttrSynchronizableAny));
+       }
+       return false;
+}
+
+//
+// Function to check whether the kSecAttrSynchronizable attribute is being updated.
+//
+static Boolean SecItemHasSynchronizableUpdate(Boolean synchronizable, CFDictionaryRef changes)
+{
+       CFTypeRef newValue = CFDictionaryGetValue(changes, kSecAttrSynchronizable);
+       if (!newValue)
+               return false;
+
+       Boolean new_sync = readNumber(newValue);
+       Boolean old_sync = synchronizable;
+
+       return (old_sync != new_sync);
+}
 
 
-    if (synchronizable) {
-        CFTypeRef value = NULL;
-        return (_ValidateDictionaryEntry(query, kSecAttrSynchronizable, (const void**)&value, CFBooleanGetTypeID(), NULL) == noErr && value && CFEqual(kCFBooleanTrue, value));
+//
+// Returns true if keychain syncing is globally enabled.
+//
+static Boolean SecItemSyncEnabled()
+{
+       static dispatch_once_t onceToken;
+       static Boolean syncEnabled = true;
+
+       //sudo defaults write /Library/Preferences/com.apple.security SecItemSynchronizable -bool YES
+       dispatch_once(&onceToken, ^{
+                       CFTypeRef sync = (CFNumberRef)CFPreferencesCopyValue(CFSTR("SecItemSynchronizable"), CFSTR("com.apple.security"), kCFPreferencesAnyUser, kCFPreferencesCurrentHost);
+
+                       if (sync && CFGetTypeID(sync) == CFBooleanGetTypeID()) {
+                       syncEnabled = CFBooleanGetValue((CFBooleanRef)sync);
+                       CFRelease(sync);
+                       }
+                       });
+
+       return syncEnabled;
+}
+
+//
+// Function to check whether a synchronizable persistent reference was provided.
+//
+static Boolean SecItemHasSynchronizablePersistentReference(CFDictionaryRef query)
+{
+       CFTypeRef value = CFDictionaryGetValue(query, kSecValuePersistentRef);
+       if (value) {
+               /* Synchronizable persistent ref consists of the sqlite rowid and 4-byte class value */
+               const CFIndex kSynchronizablePersistentRefLength = sizeof(int64_t) + 4;
+               return (CFGetTypeID(value) == CFDataGetTypeID() &&
+                               CFDataGetLength((CFDataRef)value) == kSynchronizablePersistentRefLength);
+       }
+       return false;
+}
+
+//
+// Function to apply changes to a mutable dictionary.
+// (CFDictionaryApplierFunction, called by CFDictionaryApplyFunction)
+//
+static void SecItemApplyChanges(const void *key, const void *value, void *context)
+{
+       CFMutableDictionaryRef dict = (CFMutableDictionaryRef) context;
+       if (!dict) return;
+
+       CFDictionarySetValue(dict, key, value);
+}
+
+//
+// Function to change matching items from non-syncable to syncable
+// (if toSyncable is true), otherwise from syncable to non-syncable.
+// This currently moves items between keychain containers.
+//
+static OSStatus SecItemChangeSynchronizability(CFDictionaryRef query, CFDictionaryRef changes, Boolean toSyncable)
+{
+       // Note: the input query dictionary is a mutable copy of the query originally
+       // provided by the caller as the first parameter to SecItemUpdate. It may not
+       // specify returning attributes or data, but we will need both to make a copy.
+       //
+       CFDictionaryRemoveValue((CFMutableDictionaryRef)query, kSecReturnRef);
+       CFDictionaryRemoveValue((CFMutableDictionaryRef)query, kSecReturnPersistentRef);
+       CFDictionaryRemoveValue((CFMutableDictionaryRef)query, kSecReturnData);
+       CFDictionarySetValue((CFMutableDictionaryRef)query, kSecReturnAttributes, kCFBooleanTrue);
+       if (NULL == CFDictionaryGetValue(changes, kSecValueData))
+               CFDictionarySetValue((CFMutableDictionaryRef)query, kSecReturnData, kCFBooleanTrue);
+
+       CFTypeRef result;
+       OSStatus status;
+       if (toSyncable)
+               status = SecItemCopyMatching_osx(query, &result);
+       else
+               status = SecItemCopyMatching_ios(query, &result);
+
+       if (status)
+               return status;
+       if (!result)
+               return errSecItemNotFound;
+
+       CFMutableArrayRef items;
+       if (CFGetTypeID(result) != CFArrayGetTypeID()) {
+               items = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+               CFArrayAppendValue(items, result);
+               CFRelease(result);
+       }
+       else {
+               items = (CFMutableArrayRef)result;
+       }
+
+       CFIndex idx, count = (items) ? CFArrayGetCount(items) : 0;
+       int priority = LOG_DEBUG;
+       OSStatus err = 0;
+       for (idx = 0; idx < count; idx++) {
+               CFDictionaryRef dict = (CFDictionaryRef) CFArrayGetValueAtIndex(items, idx);
+               CFMutableDictionaryRef item = (CFMutableDictionaryRef)
+                       SecItemCopyTranslatedAttributes(dict,
+                               CFDictionaryGetValue(query, kSecClass),
+                               (toSyncable) ? true : false /*iOSOut*/,
+                               true /*pruneMatch*/,
+                               true /*pruneSync*/,
+                               true /*pruneReturn*/,
+                               false /*pruneData*/,
+                               (toSyncable) ? true : false /*pruneAccess*/);
+               // hold onto the query before applying changes, in case the item already exists.
+               // note that we cannot include the creation or modification dates from our
+               // found item in this query, as they may not match the item in the other keychain.
+               CFMutableDictionaryRef itemQuery = CFDictionaryCreateMutableCopy(NULL, 0, item);
+               CFDictionaryRemoveValue(itemQuery, kSecAttrCreationDate);
+               CFDictionaryRemoveValue(itemQuery, kSecAttrModificationDate);
+               // apply changes to the item dictionary that we will pass to SecItemAdd
+               CFDictionaryApplyFunction(changes, SecItemApplyChanges, item);
+               if (toSyncable) {
+                       CFDictionarySetValue(item, kSecAttrSynchronizable, kCFBooleanTrue);
+                       status = SecItemAdd_ios(item, NULL);
+                       secitemlog(priority, "ChangeSync: SecItemAdd_ios=%d", status);
+                       if (errSecDuplicateItem == status) {
+                               // find and apply changes to the existing syncable item.
+                               CFDictionarySetValue(itemQuery, kSecAttrSynchronizable, kCFBooleanTrue);
+                               status = SecItemUpdate_ios(itemQuery, changes);
+                               secitemlog(priority, "ChangeSync: SecItemUpdate_ios=%d", status);
+                       }
+                       if (errSecSuccess == status) {
+                               CFDictionarySetValue(itemQuery, kSecAttrSynchronizable, kCFBooleanFalse);
+                               status = SecItemDelete_osx(itemQuery);
+                               secitemlog(priority, "ChangeSync: SecItemDelete_osx=%d", status);
+                       }
+               }
+               else {
+                       CFDictionarySetValue(item, kSecAttrSynchronizable, kCFBooleanFalse);
+                       status = SecItemAdd_osx(item, NULL);
+                       secitemlog(priority, "ChangeSync: SecItemAdd_osx=%d", status);
+                       if (errSecDuplicateItem == status) {
+                               // find and apply changes to the existing non-syncable item.
+                               CFDictionarySetValue(itemQuery, kSecAttrSynchronizable, kCFBooleanFalse);
+                               status = SecItemUpdate_osx(itemQuery, changes);
+                               secitemlog(priority, "ChangeSync: SecItemUpdate_osx=%d", status);
+                       }
+                       if (errSecSuccess == status) {
+                               CFDictionarySetValue(itemQuery, kSecAttrSynchronizable, kCFBooleanTrue);
+                               status = SecItemDelete_ios(itemQuery);
+                               secitemlog(priority, "ChangeSync: SecItemDelete_ios=%d", status);
+                       }
+               }
+               CFReleaseSafe(item);
+               CFReleaseSafe(itemQuery);
+               if (status)
+                       err = status;
+       }
+       CFReleaseSafe(items);
+
+       return err;
+}
+
+
+extern "C" {
+
+CFTypeRef
+SecItemCreateFromAttributeDictionary(CFDictionaryRef refAttributes) {
+       CFTypeRef ref = NULL;
+       CFStringRef key_class_string = (CFStringRef)CFDictionaryGetValue(refAttributes, kSecClass);
+       SecItemClass key_class;
+       bool key_class_found = false;
+
+       if (CFEqual(key_class_string, kSecClassGenericPassword)) {
+               key_class = kSecGenericPasswordItemClass;
+               key_class_found = true;
+       }
+       if (CFEqual(key_class_string, kSecClassInternetPassword)) {
+               key_class = kSecInternetPasswordItemClass;
+               key_class_found = true;
+       }
+
+       if (key_class_found) {
+               // we carry v_Data around here so the *_ios calls can find it and locate
+               // their own data.   Putting things in the attribute list doesn't help as
+               // the osx keychainitem and item calls bail when they don't see a keychain
+               // object.   If we need to make them work we either have to bridge them, or
+               // find a way to craft a workable keychain object.   #if'ed code left below
+               // in case we need to go down that path.
+
+               struct SecKeychainAttributeList *attrs = (struct SecKeychainAttributeList *)malloc(sizeof(struct SecKeychainAttributeList) + sizeof(struct SecKeychainAttribute) * 0);
+               attrs->attr = (struct SecKeychainAttribute *)(attrs + 1);
+               attrs->count = 0;
+               CFTypeRef v;
+#if 0
+               // The C++ string objects need to last at least as long as the attr struct.
+               string account;
+
+               v = CFDictionaryGetValue(refAttributes, CFSTR("mdat"));
+               if (v) {
+                       attrs->attr[attrs->count].tag = kSecModDateItemAttr;
+                       // XXX need to convert to YYYYMMDDhhmmSSZ
+                       attrs->attr[attrs->count].data = (void*)"19690223140232Z";
+                       attrs->attr[attrs->count].length = strlen((char*)(attrs->attr[attrs->count].data));
+                       attrs->count++;
+               }
+               v = CFDictionaryGetValue(refAttributes, CFSTR("cdat"));
+               if (v) {
+                       attrs->attr[attrs->count].tag = kSecCreationDateItemAttr;
+                       // XXX need to convert to YYYYMMDDhhmmSSZ
+                       attrs->attr[attrs->count].data = (void*)"19690223140232Z";
+                       attrs->attr[attrs->count].length = strlen((char*)(attrs->attr[attrs->count].data));
+                       attrs->count++;
+               }
+
+               v = CFDictionaryGetValue(refAttributes, CFSTR("acct"));
+               if (v) {
+                       attrs->attr[attrs->count].tag = kSecAccountItemAttr;
+                       account = cfString((CFStringRef)v);
+                       attrs->attr[attrs->count].data = (void*)(account.c_str());
+                       attrs->attr[attrs->count].length = account.length();
+                       attrs->count++;
+               }
+
+               // class isn't treated as an attribute by the creation API
+
+               v = CFDictionaryGetValue(refAttributes, CFSTR("svce"));
+               if (v) {
+                       attrs->attr[attrs->count].tag = kSecServiceItemAttr;
+                       account = cfString((CFStringRef)v);
+                       attrs->attr[attrs->count].data = (void*)(account.c_str());
+                       attrs->attr[attrs->count].length = account.length();
+                       attrs->count++;
+               }
+
+               v = CFDictionaryGetValue(refAttributes, CFSTR("acct"));
+               if (v) {
+                       attrs->attr[attrs->count].tag = kSecLabelItemAttr;
+                       account = cfString((CFStringRef)v);
+                       attrs->attr[attrs->count].data = (void*)(account.c_str());
+                       attrs->attr[attrs->count].length = account.length();
+                       attrs->count++;
+               }
+#endif
+               Item item = Item(key_class, attrs, 0, "");
+               ItemImpl *real_item = item.get();
+               v = CFDictionaryGetValue(refAttributes, kSecValuePersistentRef);
+               if (v) {
+                       real_item->setPersistentRef((CFDataRef)v);
+               }
+               ref = real_item->handle();
+       } else {
+               // keys, certs, identities are not currently sync'able.
+               ref = NULL;
+       }
+       return ref;
+}
+
+/*
+ * SecItemValidateAppleApplicationGroupAccess determines if the caller
+ * is a member of the specified application group, and is signed by Apple.
+ */
+OSStatus
+SecItemValidateAppleApplicationGroupAccess(CFStringRef group)
+{
+       SecTrustedApplicationRef app = NULL;
+       SecRequirementRef requirement = NULL;
+       SecCodeRef code = NULL;
+       OSStatus status = errSecParam;
+
+       if (group) {
+               CFIndex length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(group), kCFStringEncodingUTF8) + 1;
+               char* buffer = (char*) malloc(length);
+               if (buffer) {
+                       if (CFStringGetCString(group, buffer, length, kCFStringEncodingUTF8)) {
+                               status = SecTrustedApplicationCreateApplicationGroup(buffer, NULL, &app);
+                       }
+                       free(buffer);
+               } else {
+                       status = errSecMemoryError;
+               }
+       }
+       if (!status) {
+               status = SecTrustedApplicationCopyRequirement(app, &requirement);
+       }
+       if (!status) {
+               status = SecCodeCopySelf(kSecCSDefaultFlags, &code);
+       }
+       if (!status) {
+               status = SecCodeCheckValidity(code, kSecCSDefaultFlags, requirement);
+       }
+
+       CFReleaseSafe(code);
+       CFReleaseSafe(requirement);
+       CFReleaseSafe(app);
+       return status;
+}
+
+/*
+ * SecItemCopyTranslatedAttributes accepts a user-provided attribute dictionary
+ * and attempts to return a sanitized copy for passing to the underlying
+ * platform-specific implementation code.
+ *
+ * If iOSOut is true, one or more translations may apply:
+ *   - SecKeychain refs are removed, since there aren't multiple keychains
+ *   - SecPolicy refs are removed, since they can't be externalized
+ *   - SecAccess refs are removed, and potentially translated to entitlements
+ *
+ * If pruneMatch is true, kSecMatch* attributes are removed; this avoids
+ * parameter errors due to strict input checks in secd, which only permits
+ * these constants for calls to SecItemCopyMatching.
+ *
+ * If pruneSync is true, the kSecAttrSynchronizable attribute is removed.
+ * This permits a query to be reused for non-synchronizable items, or to
+ * resolve a search based on a persistent item reference for iOS.
+ *
+ * If pruneReturn is true, kSecReturn* attributes are removed; this avoids
+ * parameter errors due to strict input checks in secd, which do not permit
+ * these constants for calls to SecItemUpdate.
+ */
+CFDictionaryRef
+SecItemCopyTranslatedAttributes(CFDictionaryRef inOSXDict, CFTypeRef itemClass,
+       bool iOSOut, bool pruneMatch, bool pruneSync, bool pruneReturn, bool pruneData, bool pruneAccess)
+{
+       CFMutableDictionaryRef result = CFDictionaryCreateMutableCopy(NULL, 0, inOSXDict);
+       if (result == NULL) {
+               return result;
+       }
+
+       if (pruneSync) {
+               CFDictionaryRemoveValue(result, kSecAttrSynchronizable);
+       }
+
+       if (pruneMatch) {
+               /* Match constants are only supported on iOS for SecItemCopyMatching,
+                * and will generate an error if passed to other SecItem API functions;
+                * on OS X, they're just ignored if not applicable for the context.
+                */
+               CFDictionaryRemoveValue(result, kSecMatchPolicy);
+               CFDictionaryRemoveValue(result, kSecMatchItemList);
+               CFDictionaryRemoveValue(result, kSecMatchSearchList);
+               CFDictionaryRemoveValue(result, kSecMatchIssuers);
+               CFDictionaryRemoveValue(result, kSecMatchEmailAddressIfPresent);
+               CFDictionaryRemoveValue(result, kSecMatchSubjectContains);
+               CFDictionaryRemoveValue(result, kSecMatchCaseInsensitive);
+               CFDictionaryRemoveValue(result, kSecMatchTrustedOnly);
+               CFDictionaryRemoveValue(result, kSecMatchValidOnDate);
+               CFDictionaryRemoveValue(result, kSecMatchLimit);
+               CFDictionaryRemoveValue(result, kSecMatchLimitOne);
+               CFDictionaryRemoveValue(result, kSecMatchLimitAll);
+       }
+
+       if (pruneReturn) {
+               /* Return constants are not supported on iOS for SecItemUpdate,
+                * where they will generate an error; on OS X, they're just ignored
+                * if not applicable for the context.
+                */
+               CFDictionaryRemoveValue(result, kSecReturnData);
+               CFDictionaryRemoveValue(result, kSecReturnAttributes);
+               CFDictionaryRemoveValue(result, kSecReturnRef);
+               CFDictionaryRemoveValue(result, kSecReturnPersistentRef);
+       }
+
+       if (pruneData) {
+               /* Searching on data is not supported. */
+               CFDictionaryRemoveValue(result, kSecValueData);
+       }
+
+    if (pruneAccess) {
+        /* Searching on access lists is not supported */
+        CFDictionaryRemoveValue(result, kSecAttrAccess);
+    }
+
+       if (iOSOut) {
+               /* Remove kSecMatchSearchList (value is array of SecKeychainRef);
+                * cannot specify a keychain search list on iOS
+                */
+               CFDictionaryRemoveValue(result, kSecMatchSearchList);
+
+               /* Remove kSecUseKeychain (value is a SecKeychainRef);
+                * cannot specify a keychain on iOS
+                */
+               CFDictionaryRemoveValue(result, kSecUseKeychain);
+
+               /* Remove kSecMatchPolicy (value is a SecPolicyRef);
+                * TODO: need a way to externalize and restore a policy instance
+                */
+               CFDictionaryRemoveValue(result, kSecMatchPolicy);
+
+               /* Potentially translate kSecAttrAccess (value is a SecAccessRef),
+                * unless kSecAttrAccessGroup has already been specified.
+                */
+               SecAccessRef access = (SecAccessRef) CFDictionaryGetValue(result, kSecAttrAccess);
+               CFStringRef accessGroup = (CFStringRef) CFDictionaryGetValue(result, kSecAttrAccessGroup);
+               if (access != NULL && accessGroup == NULL) {
+                       /* Translate "InternetAccounts" application group to an access group */
+                       if (errSecSuccess == SecItemValidateAppleApplicationGroupAccess(CFSTR("InternetAccounts"))) {
+                               /* The caller is a valid member of the application group. */
+                               CFStringRef groupName = CFSTR("appleaccount");
+                               CFTypeRef value = CFDictionaryGetValue(result, kSecAttrAuthenticationType);
+                               if (value && CFEqual(value, kSecAttrAuthenticationTypeHTMLForm)) {
+                                       groupName = CFSTR("com.apple.cfnetwork");
+                               }
+                               CFDictionarySetValue(result, kSecAttrAccessGroup, groupName);
+                       }
+               }
+               CFDictionaryRemoveValue(result, kSecAttrAccess);
+
+               /* If item is specified by direct reference, and this is an iOS search,
+                * replace it with a persistent reference.
+                */
+        CFTypeRef directRef = CFDictionaryGetValue(result, kSecValueRef);
+               if (directRef) {
+                       CFDataRef persistentRef = _SecItemGetPersistentReference(directRef);
+                       if (persistentRef) {
+                CFDictionarySetValue(result, kSecValuePersistentRef, persistentRef);
+                       }
+                       CFDictionaryRemoveValue(result, kSecValueRef);
+               }
+
+               /* If item is specified by persistent reference, and this is an iOS search,
+                * remove the synchronizable attribute as it will be rejected by secd.
+                */
+               CFTypeRef persistentRef = CFDictionaryGetValue(result, kSecValuePersistentRef);
+               if (persistentRef) {
+                       CFDictionaryRemoveValue(result, kSecAttrSynchronizable);
+               }
+
+               /* Remove kSecAttrModificationDate; this should never be used as criteria
+                * for a search, or to add/modify an item. (If we are cloning an item
+                * and want to keep its modification date, we don't call this function.)
+                * It turns out that some clients are using the full attributes dictionary
+                * returned by SecItemCopyMatching as a query to find the same item later,
+                * which won't work once the item is updated.
+                */
+               CFDictionaryRemoveValue(result, kSecAttrModificationDate);
     }
     }
+       else {
+               /* iOS doesn't add the class attribute, so we must do it here. */
+               if (itemClass)
+                       CFDictionarySetValue(result, kSecClass, itemClass);
 
 
-    return synchronizable;
+               /* Remove attributes which are not part of the OS X database schema. */
+               CFDictionaryRemoveValue(result, kSecAttrAccessible);
+               CFDictionaryRemoveValue(result, kSecAttrAccessGroup);
+               CFDictionaryRemoveValue(result, kSecAttrSynchronizable);
+               CFDictionaryRemoveValue(result, kSecAttrTombstone);
+       }
+
+       return result;
+}
+
+/*
+ * SecItemCopyMergedResults takes two input objects, which may be containers,
+ * and returns a retained object which merges the results. Merging depends on the
+ * result type. If each result is valid and is not an array, then only one match was
+ * requested; in that case, the syncable (ios) match is preferred.
+ *
+ * FIXME: There are some edge cases still to deal with; e.g. if the OSX search specified a
+ * particular keychain to search, we do not want to merge in any IOS results. Also, may need
+ * to filter out duplicates if two items differ only in the sync attribute.
+ */
+CFTypeRef
+SecItemCopyMergedResults(CFDictionaryRef query, CFTypeRef result_osx, CFTypeRef result_ios)
+{
+       CFTypeID id_osx = (result_osx) ? CFGetTypeID(result_osx) : 0;
+       CFTypeID id_ios = (result_ios) ? CFGetTypeID(result_ios) : 0;
+       CFTypeID id_array = CFArrayGetTypeID();
+       if ((id_osx == id_array) && (id_ios == id_array)) {
+               // Fold the arrays into one.
+               CFMutableArrayRef results = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+               CFArrayAppendArray(results, (CFArrayRef)result_ios, CFRangeMake(0, CFArrayGetCount((CFArrayRef)result_ios)));
+               CFArrayAppendArray(results, (CFArrayRef)result_osx, CFRangeMake(0, CFArrayGetCount((CFArrayRef)result_osx)));
+               return results;
+       }
+       // Result type is not an array, so only one match can be returned.
+       return (id_ios) ? CFRetain(result_ios) : CFRetain(result_osx);
 }
 
 }
 
+} /* extern "C" */
+
+
 OSStatus
 SecItemCopyMatching(CFDictionaryRef query, CFTypeRef *result)
 {
 OSStatus
 SecItemCopyMatching(CFDictionaryRef query, CFTypeRef *result)
 {
-       if (!query || !result)
-               return paramErr;
+       secitemlog(LOG_NOTICE, "SecItemCopyMatching");
+       if (!query) {
+               return errSecParam;
+       }
+       secitemshow(query, "SecItemCopyMatching query:");
+
+       OSStatus status_osx = errSecItemNotFound, status_ios = errSecItemNotFound;
+       CFTypeRef result_osx = NULL, result_ios = NULL;
+       Boolean sync_enabled = SecItemSyncEnabled();
+       Boolean search_ios = SecItemSynchronizable(query);
+       Boolean merge_search = SecItemSynchronizableAny(query);
+       Boolean persistref_ios = SecItemHasSynchronizablePersistentReference(query);
+
+       if (sync_enabled && (merge_search || persistref_ios || search_ios)) {
+               CFDictionaryRef attrs_ios = SecItemCopyTranslatedAttributes(query,
+                       CFDictionaryGetValue(query, kSecClass), true, false, false, false, true, true);
+               if (!attrs_ios) {
+                       status_ios = errSecParam;
+               }
+               else {
+            SecItemUnlockSynchronizableKeychain();
+            status_ios = SecItemCopyMatching_ios(attrs_ios, &result_ios);
+                       CFRelease(attrs_ios);
+               }
+               secitemlog(LOG_NOTICE, "SecItemCopyMatching_ios result: %d", status_ios);
+               if (!merge_search || persistref_ios) {
+                       AssignOrReleaseResult(result_ios, result);
+                       return status_ios; // no need to search non-syncable keychains
+               }
+       }
 
 
-    if (SecItemSynchronizable(query)) {
-       return SecItemCopyMatching_ios(query, result);
-    }
+       CFDictionaryRef attrs_osx = SecItemCopyTranslatedAttributes(query,
+               CFDictionaryGetValue(query, kSecClass), false, false, true, false, true, true);
+       if (!attrs_osx) {
+               status_osx = errSecParam;
+       }
+       else {
+               status_osx = SecItemCopyMatching_osx(attrs_osx, &result_osx);
+               CFRelease(attrs_osx);
+       }
+       secitemlog(LOG_NOTICE, "SecItemCopyMatching_osx result: %d", status_osx);
+
+       // If one of the searches failed to occur or produce results, we can eliminate it
+       if (result_ios == NULL) {
+               AssignOrReleaseResult(result_osx, result);
+               return status_osx; // we can only have non-syncable results
+       }
+       if (result_osx == NULL) {
+               AssignOrReleaseResult(result_ios, result);
+               return status_ios; // we can only have syncable results
+       }
 
 
-    return SecItemCopyMatching_osx(query, result);
+       // If we get here, need to merge results
+       CFTypeRef result_merged = SecItemCopyMergedResults(query, result_osx, result_ios);
+       CFReleaseSafe(result_osx);
+       CFReleaseSafe(result_ios);
+       AssignOrReleaseResult(result_merged, result);
+
+       if (status_osx == status_ios) {
+               return status_osx; // both searches produced the same result
+       }
+       else if (!status_osx || !status_ios) {
+               return errSecSuccess; // one of the searches succeeded
+       }
+       else if (status_osx == errSecItemNotFound) {
+               return status_ios; // this failure was more interesting
+       }
+       return status_osx;
 }
 
 OSStatus
 SecItemAdd(CFDictionaryRef attributes, CFTypeRef *result)
 {
 }
 
 OSStatus
 SecItemAdd(CFDictionaryRef attributes, CFTypeRef *result)
 {
-       if (!attributes)
-               return paramErr;
-       else if (result)
+       secitemlog(LOG_NOTICE, "SecItemAdd");
+       if (!attributes) {
+               return errSecParam;
+       }
+       else if (result) {
                *result = NULL;
                *result = NULL;
+       }
+       secitemshow(attributes, "SecItemAdd attrs:");
 
 
-    if (SecItemSynchronizable(attributes)) {
-        return SecItemAdd_ios(attributes, result);
-    }
+       OSStatus status_osx, status_ios;
+       CFTypeRef result_osx = NULL, result_ios = NULL;
+       Boolean sync_enabled = SecItemSyncEnabled();
+       Boolean add_ios = SecItemSynchronizable(attributes);
+
+       if (sync_enabled && add_ios) {
+               CFDictionaryRef attrs_ios = SecItemCopyTranslatedAttributes(attributes,
+                       NULL, true, true, false, false, false, false);
+               if (!attrs_ios) {
+                       status_ios = errSecParam;
+               }
+               else {
+            SecItemUnlockSynchronizableKeychain();
+            status_ios = SecItemAdd_ios(attrs_ios, &result_ios);
+                       CFRelease(attrs_ios);
+               }
+               secitemlog(LOG_NOTICE, "SecItemAdd_ios result: %d", status_ios);
+               if (result)
+                       *result = result_ios;
+               else
+                       CFReleaseSafe(result_ios);
+               return status_ios;
+       }
 
 
-    return SecItemAdd_osx(attributes, result);
+       CFDictionaryRef attrs_osx = SecItemCopyTranslatedAttributes(attributes,
+               NULL, false, false, true, false, false, false);
+       if (!attrs_osx) {
+               status_osx = errSecParam;
+       }
+       else {
+               status_osx = SecItemAdd_osx(attrs_osx, &result_osx);
+               CFRelease(attrs_osx);
+       }
+       secitemlog(LOG_NOTICE, "SecItemAdd_osx result: %d", status_osx);
+       if (result)
+               *result = result_osx;
+       else
+               CFReleaseSafe(result_osx);
+       return status_osx;
 }
 
 OSStatus
 SecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate)
 {
 }
 
 OSStatus
 SecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate)
 {
-       if (!query || !attributesToUpdate)
-               return paramErr;
+       secitemlog(LOG_NOTICE, "SecItemUpdate");
+       if (!query || !attributesToUpdate) {
+               return errSecParam;
+       }
+       secitemshow(query, "SecItemUpdate query:");
+       secitemshow(attributesToUpdate, "SecItemUpdate attrs:");
+
+       OSStatus status_osx = errSecItemNotFound, status_ios = errSecItemNotFound;
+       Boolean sync_enabled = SecItemSyncEnabled();
+       Boolean search_ios = SecItemSynchronizable(query);
+       Boolean merge_search = SecItemSynchronizableAny(query);
+       Boolean persistref_ios = SecItemHasSynchronizablePersistentReference(query);
+
+       if (sync_enabled && (merge_search || persistref_ios || search_ios)) {
+               CFDictionaryRef attrs_ios = SecItemCopyTranslatedAttributes(query,
+                       CFDictionaryGetValue(query, kSecClass), true, true, false, true, true, true);
+               if (!attrs_ios) {
+                       status_ios = errSecParam;
+               }
+               else {
+                       SecItemUnlockSynchronizableKeychain();
+            if (SecItemHasSynchronizableUpdate(true, attributesToUpdate))
+                status_ios = SecItemChangeSynchronizability(attrs_ios, attributesToUpdate, false);
+            else
+                status_ios = SecItemUpdate_ios(attrs_ios, attributesToUpdate);
+                       CFRelease(attrs_ios);
+               }
+               secitemlog(LOG_NOTICE, "SecItemUpdate_ios result: %d", status_ios);
+               if (!merge_search || persistref_ios)
+                       return status_ios;
+       }
 
 
-    if (SecItemSynchronizable(query)) {
-       return SecItemUpdate_ios(query, attributesToUpdate);
-    }
+       CFDictionaryRef attrs_osx = SecItemCopyTranslatedAttributes(query,
+               CFDictionaryGetValue(query, kSecClass), false, false, true, true, true, true);
+       if (!attrs_osx) {
+               status_osx = errSecParam;
+       }
+       else {
+               if (SecItemHasSynchronizableUpdate(false, attributesToUpdate))
+                       status_osx = SecItemChangeSynchronizability(attrs_osx, attributesToUpdate, true);
+               else
+                       status_osx = SecItemUpdate_osx(attrs_osx, attributesToUpdate);
 
 
-    return SecItemUpdate_osx(query, attributesToUpdate);
+               CFRelease(attrs_osx);
+       }
+       secitemlog(LOG_NOTICE, "SecItemUpdate_osx result: %d", status_osx);
+       if (merge_search) {
+               // Harmonize the result of the update attempts.
+               if (status_osx == status_ios) {
+                       // both updates produced the same result
+                       return status_ios;
+               }
+               else if (!status_osx || !status_ios) {
+                       // one of the updates succeeded, but the other failed
+                       if (status_osx == errSecItemNotFound || status_ios == errSecItemNotFound)
+                               return errSecSuccess; // item only found in one keychain
+                       else
+                               return (status_osx) ? status_osx : status_ios; // return the error
+               }
+               else if (status_osx == errSecItemNotFound) {
+                       // both updates failed, status_ios failure is more interesting
+                       // since the item was actually found
+                       return status_ios;
+               }
+       }
+       return status_osx;
 }
 
 OSStatus
 SecItemDelete(CFDictionaryRef query)
 {
 }
 
 OSStatus
 SecItemDelete(CFDictionaryRef query)
 {
-       if (!query)
-               return paramErr;
+       secitemlog(LOG_NOTICE, "SecItemDelete");
+       if (!query) {
+               return errSecParam;
+       }
+       secitemshow(query, "SecItemDelete query:");
+
+       OSStatus status_osx = errSecItemNotFound, status_ios = errSecItemNotFound;
+       Boolean sync_enabled = SecItemSyncEnabled();
+       Boolean search_ios = SecItemSynchronizable(query);
+       Boolean merge_search = SecItemSynchronizableAny(query);
+       Boolean persistref_ios = SecItemHasSynchronizablePersistentReference(query);
+
+       if (sync_enabled && (merge_search || persistref_ios || search_ios)) {
+               CFDictionaryRef attrs_ios = SecItemCopyTranslatedAttributes(query,
+                       NULL, true, true, false, true, true, true);
+               if (!attrs_ios) {
+                       status_ios = errSecParam;
+               }
+               else {
+            SecItemUnlockSynchronizableKeychain();
+            status_ios = SecItemDelete_ios(attrs_ios);
+                       CFRelease(attrs_ios);
+               }
+               secitemlog(LOG_NOTICE, "SecItemDelete_ios result: %d", status_ios);
+               if (!merge_search || persistref_ios)
+                       return status_ios;
+       }
 
 
-    if (SecItemSynchronizable(query)) {
-        return SecItemDelete_ios(query);
-    }
+       CFDictionaryRef attrs_osx = SecItemCopyTranslatedAttributes(query,
+               NULL, false, false, true, true, true, true);
+       if (!attrs_osx) {
+               status_osx = errSecParam;
+       }
+       else {
+               status_osx = SecItemDelete_osx(attrs_osx);
+               CFRelease(attrs_osx);
+       }
+       secitemlog(LOG_NOTICE, "SecItemDelete_osx result: %d", status_osx);
 
 
-    return SecItemDelete_osx(query);
+       if (merge_search) {
+               // Harmonize the result of the delete attempts.
+               if (status_osx == status_ios) {
+                       // both deletes produced the same result
+                       return status_ios;
+               }
+               else if (!status_osx || !status_ios) {
+                       // one of the deletes succeeded, but the other failed
+                       if (status_osx == errSecItemNotFound || status_ios == errSecItemNotFound)
+                               return errSecSuccess; // item only found in one keychain
+                       else
+                               return (status_osx) ? status_osx : status_ios; // return the error
+               }
+               else if (status_osx == errSecItemNotFound) {
+                       // both deletes failed, status_ios failure is more interesting
+                       // since the item was actually found
+                       return status_ios;
+               }
+       }
+       return status_osx;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -3410,7 +4430,7 @@ SecItemCopyMatching_osx(
        CFTypeRef *result)
 {
        if (!query || !result)
        CFTypeRef *result)
 {
        if (!query || !result)
-               return paramErr;
+               return errSecParam;
        else
                *result = NULL;
 
        else
                *result = NULL;
 
@@ -3419,7 +4439,7 @@ SecItemCopyMatching_osx(
        CFMutableArrayRef itemArray = NULL;
        SecKeychainItemRef item = NULL;
        SecIdentityRef identity = NULL;
        CFMutableArrayRef itemArray = NULL;
        SecKeychainItemRef item = NULL;
        SecIdentityRef identity = NULL;
-       OSStatus tmpStatus, status = noErr;
+       OSStatus tmpStatus, status = errSecSuccess;
 
        // validate input query parameters and create the search reference
        SecItemParams *itemParams = _CreateSecItemParamsFromDictionary(query, &status);
 
        // validate input query parameters and create the search reference
        SecItemParams *itemParams = _CreateSecItemParamsFromDictionary(query, &status);
@@ -3427,7 +4447,7 @@ SecItemCopyMatching_osx(
 
        // find the next match until we hit maxMatches, or no more matches found
        while ( !(!itemParams->returnAllMatches && matchCount >= itemParams->maxMatches) &&
 
        // find the next match until we hit maxMatches, or no more matches found
        while ( !(!itemParams->returnAllMatches && matchCount >= itemParams->maxMatches) &&
-                       SecItemSearchCopyNext(itemParams, (CFTypeRef*)&item) == noErr) {
+                       SecItemSearchCopyNext(itemParams, (CFTypeRef*)&item) == errSecSuccess) {
 
                if (FilterCandidateItem((CFTypeRef*)&item, itemParams, &identity))
                        continue; // move on to next item
 
                if (FilterCandidateItem((CFTypeRef*)&item, itemParams, &identity))
                        continue; // move on to next item
@@ -3435,7 +4455,7 @@ SecItemCopyMatching_osx(
                ++matchCount; // we have a match
 
                tmpStatus = AddItemResults(item, identity, itemParams, allocator, &itemArray, result);
                ++matchCount; // we have a match
 
                tmpStatus = AddItemResults(item, identity, itemParams, allocator, &itemArray, result);
-               if (tmpStatus && (status == noErr))
+               if (tmpStatus && (status == errSecSuccess))
                        status = tmpStatus;
 
                if (item) {
                        status = tmpStatus;
 
                if (item) {
@@ -3448,11 +4468,11 @@ SecItemCopyMatching_osx(
                }
        }
 
                }
        }
 
-       if (status == noErr)
+       if (status == errSecSuccess)
                status = (matchCount > 0) ? errSecSuccess : errSecItemNotFound;
 
 error_exit:
                status = (matchCount > 0) ? errSecSuccess : errSecItemNotFound;
 
 error_exit:
-       if (status != noErr && result != NULL && *result != NULL) {
+       if (status != errSecSuccess && result != NULL && *result != NULL) {
                CFRelease(*result);
                *result = NULL;
        }
                CFRelease(*result);
                *result = NULL;
        }
@@ -3470,7 +4490,7 @@ SecItemCopyDisplayNames(
        Required(items);
        Required(displayNames);
     //%%%TBI
        Required(items);
        Required(displayNames);
     //%%%TBI
-    return unimpErr;
+    return errSecUnimplemented;
     END_SECAPI
 }
 
     END_SECAPI
 }
 
@@ -3480,14 +4500,14 @@ SecItemAdd_osx(
        CFTypeRef *result)
 {
        if (!attributes)
        CFTypeRef *result)
 {
        if (!attributes)
-               return paramErr;
+               return errSecParam;
        else if (result)
                *result = NULL;
 
        CFAllocatorRef allocator = CFGetAllocator(attributes);
        CFMutableArrayRef itemArray = NULL;
        SecKeychainItemRef item = NULL;
        else if (result)
                *result = NULL;
 
        CFAllocatorRef allocator = CFGetAllocator(attributes);
        CFMutableArrayRef itemArray = NULL;
        SecKeychainItemRef item = NULL;
-       OSStatus tmpStatus, status = noErr;
+       OSStatus tmpStatus, status = errSecSuccess;
 
        // validate input attribute parameters
        SecItemParams *itemParams = _CreateSecItemParamsFromDictionary(attributes, &status);
 
        // validate input attribute parameters
        SecItemParams *itemParams = _CreateSecItemParamsFromDictionary(attributes, &status);
@@ -3503,7 +4523,7 @@ SecItemAdd_osx(
                // create a single keychain item specified by the input attributes
                status = SecKeychainItemCreateFromContent(itemParams->itemClass,
                        itemParams->attrList,
                // create a single keychain item specified by the input attributes
                status = SecKeychainItemCreateFromContent(itemParams->itemClass,
                        itemParams->attrList,
-                       (itemParams->itemData) ? CFDataGetLength(itemParams->itemData) : 0,
+                       (itemParams->itemData) ? (UInt32)CFDataGetLength(itemParams->itemData) : 0,
                        (itemParams->itemData) ? CFDataGetBytePtrVoid(itemParams->itemData) : NULL,
                        itemParams->keychain,
                        itemParams->access,
                        (itemParams->itemData) ? CFDataGetBytePtrVoid(itemParams->itemData) : NULL,
                        itemParams->keychain,
                        itemParams->access,
@@ -3514,7 +4534,7 @@ SecItemAdd_osx(
                if (result) {
                        itemParams->maxMatches = 1; // in case kSecMatchLimit was set to > 1
                        tmpStatus = AddItemResults(item, NULL, itemParams, allocator, &itemArray, result);
                if (result) {
                        itemParams->maxMatches = 1; // in case kSecMatchLimit was set to > 1
                        tmpStatus = AddItemResults(item, NULL, itemParams, allocator, &itemArray, result);
-                       if (tmpStatus && (status == noErr))
+                       if (tmpStatus && (status == errSecSuccess))
                                status = tmpStatus;
                }
                CFRelease(item);
                                status = tmpStatus;
                }
                CFRelease(item);
@@ -3525,9 +4545,9 @@ SecItemAdd_osx(
                // -- SecKeychainItemRef items are in a keychain (by definition), but may be copied to another keychain.
                // -- CFDataRef items are a persistent reference; the represented item may be copied to another keychain.
                //
                // -- SecKeychainItemRef items are in a keychain (by definition), but may be copied to another keychain.
                // -- CFDataRef items are a persistent reference; the represented item may be copied to another keychain.
                //
-               OSStatus aggregateStatus = noErr;
+               OSStatus aggregateStatus = errSecSuccess;
                CFIndex ix, count = CFArrayGetCount(itemParams->useItems);
                CFIndex ix, count = CFArrayGetCount(itemParams->useItems);
-               itemParams->maxMatches = (count > 1) ? count : 2; // force results to always be returned as an array
+               itemParams->maxMatches = (count > 1) ? (int)count : 2; // force results to always be returned as an array
                for (ix=0; ix < count; ix++) {
                        CFTypeRef anItem = (CFTypeRef) CFArrayGetValueAtIndex(itemParams->useItems, ix);
                        if (anItem) {
                for (ix=0; ix < count; ix++) {
                        CFTypeRef anItem = (CFTypeRef) CFArrayGetValueAtIndex(itemParams->useItems, ix);
                        if (anItem) {
@@ -3543,7 +4563,7 @@ SecItemAdd_osx(
                                        // SecKeyRef item
                                        SecKeychainRef itemKeychain = NULL;
                                        tmpStatus = SecKeychainItemCopyKeychain((SecKeychainItemRef)anItem, &itemKeychain);
                                        // SecKeyRef item
                                        SecKeychainRef itemKeychain = NULL;
                                        tmpStatus = SecKeychainItemCopyKeychain((SecKeychainItemRef)anItem, &itemKeychain);
-                                       if (tmpStatus == noErr) {
+                                       if (tmpStatus == errSecSuccess) {
                                                // key was in a keychain, so we can attempt to copy it
                                                SecKeychainItemRef itemCopy = NULL;
                                                tmpStatus = SecKeychainItemCreateCopy((SecKeychainItemRef)anItem, itemParams->keychain, itemParams->access, &itemCopy);
                                                // key was in a keychain, so we can attempt to copy it
                                                SecKeychainItemRef itemCopy = NULL;
                                                tmpStatus = SecKeychainItemCreateCopy((SecKeychainItemRef)anItem, itemParams->keychain, itemParams->access, &itemCopy);
@@ -3586,7 +4606,7 @@ SecItemAdd_osx(
                                        // CFDataRef item (persistent reference)
                                        SecKeychainItemRef realItem = NULL;
                                        tmpStatus = SecKeychainItemCopyFromPersistentReference((CFDataRef)anItem, &realItem);
                                        // CFDataRef item (persistent reference)
                                        SecKeychainItemRef realItem = NULL;
                                        tmpStatus = SecKeychainItemCopyFromPersistentReference((CFDataRef)anItem, &realItem);
-                                       if (tmpStatus == noErr) {
+                                       if (tmpStatus == errSecSuccess) {
                                                // persistent reference resolved to a keychain item, so we can attempt to copy it
                                                SecKeychainItemRef itemCopy = NULL;
                                                tmpStatus = SecKeychainItemCreateCopy(realItem, itemParams->keychain, itemParams->access, &itemCopy);
                                                // persistent reference resolved to a keychain item, so we can attempt to copy it
                                                SecKeychainItemRef itemCopy = NULL;
                                                tmpStatus = SecKeychainItemCreateCopy(realItem, itemParams->keychain, itemParams->access, &itemCopy);
@@ -3608,7 +4628,7 @@ SecItemAdd_osx(
        } // end processing multiple items
 
 error_exit:
        } // end processing multiple items
 
 error_exit:
-       if (status != noErr && result != NULL && *result != NULL) {
+       if (status != errSecSuccess && result != NULL && *result != NULL) {
                CFRelease(*result);
                *result = NULL;
        }
                CFRelease(*result);
                *result = NULL;
        }
@@ -3623,12 +4643,12 @@ SecItemUpdate_osx(
        CFDictionaryRef attributesToUpdate)
 {
        if (!query || !attributesToUpdate)
        CFDictionaryRef attributesToUpdate)
 {
        if (!query || !attributesToUpdate)
-               return paramErr;
+               return errSecParam;
 
        // run the provided query to get a list of items to update
        CFTypeRef results = NULL;
        OSStatus status = SecItemCopyMatching(query, &results);
 
        // run the provided query to get a list of items to update
        CFTypeRef results = NULL;
        OSStatus status = SecItemCopyMatching(query, &results);
-       if (status != noErr)
+       if (status != errSecSuccess)
                return status; // nothing was matched, or the query was bad
 
        CFArrayRef items = NULL;
                return status; // nothing was matched, or the query was bad
 
        CFArrayRef items = NULL;
@@ -3640,13 +4660,13 @@ SecItemUpdate_osx(
                CFRelease(results);
        }
 
                CFRelease(results);
        }
 
-       OSStatus result = noErr;
+       OSStatus result = errSecSuccess;
        CFIndex ix, count = CFArrayGetCount(items);
        for (ix=0; ix < count; ix++) {
                CFTypeRef anItem = (CFTypeRef) CFArrayGetValueAtIndex(items, ix);
                if (anItem) {
                        status = _UpdateKeychainItem(anItem, attributesToUpdate);
        CFIndex ix, count = CFArrayGetCount(items);
        for (ix=0; ix < count; ix++) {
                CFTypeRef anItem = (CFTypeRef) CFArrayGetValueAtIndex(items, ix);
                if (anItem) {
                        status = _UpdateKeychainItem(anItem, attributesToUpdate);
-                       result = _UpdateAggregateStatus(status, result, noErr);
+                       result = _UpdateAggregateStatus(status, result, errSecSuccess);
                }
        }
 
                }
        }
 
@@ -3661,12 +4681,12 @@ SecItemDelete_osx(
        CFDictionaryRef query)
 {
        if (!query)
        CFDictionaryRef query)
 {
        if (!query)
-               return paramErr;
+               return errSecParam;
 
        // run the provided query to get a list of items to delete
        CFTypeRef results = NULL;
 
        // run the provided query to get a list of items to delete
        CFTypeRef results = NULL;
-       OSStatus status = SecItemCopyMatching(query, &results);
-       if (status != noErr)
+       OSStatus status = SecItemCopyMatching_osx(query, &results);
+       if (status != errSecSuccess)
                return status; // nothing was matched, or the query was bad
 
        CFArrayRef items = NULL;
                return status; // nothing was matched, or the query was bad
 
        CFArrayRef items = NULL;
@@ -3678,7 +4698,7 @@ SecItemDelete_osx(
                CFRelease(results);
        }
 
                CFRelease(results);
        }
 
-       OSStatus result = noErr;
+       OSStatus result = errSecSuccess;
        CFIndex ix, count = CFArrayGetCount(items);
        for (ix=0; ix < count; ix++) {
                CFTypeRef anItem = (CFTypeRef) CFArrayGetValueAtIndex(items, ix);
        CFIndex ix, count = CFArrayGetCount(items);
        for (ix=0; ix < count; ix++) {
                CFTypeRef anItem = (CFTypeRef) CFArrayGetValueAtIndex(items, ix);
@@ -3689,7 +4709,7 @@ SecItemDelete_osx(
                        else {
                                status = _DeleteKeychainItem(anItem);
                        }
                        else {
                                status = _DeleteKeychainItem(anItem);
                        }
-                       result = _UpdateAggregateStatus(status, result, noErr);
+                       result = _UpdateAggregateStatus(status, result, errSecSuccess);
                }
        }
 
                }
        }
 
index f2d03ba7c1d5b2f85aef863e149f788f094169fc..b07aba9ef549455d0257d2edf3536055f13567b9 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2006-2010,2012 Apple Inc. All Rights Reserved.
+ * Copyright (c) 2006-2013 Apple Inc. All Rights Reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -81,7 +81,9 @@ extern const CFTypeRef kSecClassIdentity
         below lists the currently defined attributes for each item class:
 
         kSecClassGenericPassword item attributes:
         below lists the currently defined attributes for each item class:
 
         kSecClassGenericPassword item attributes:
-        kSecAttrAccess
+        kSecAttrAccess (OS X only)
+        kSecAttrAccessGroup (iOS; also OS X if kSecAttrSynchronizable specified)
+        kSecAttrAccessible (iOS; also OS X if kSecAttrSynchronizable specified)
         kSecAttrCreationDate
         kSecAttrModificationDate
         kSecAttrDescription
         kSecAttrCreationDate
         kSecAttrModificationDate
         kSecAttrDescription
@@ -96,7 +98,9 @@ extern const CFTypeRef kSecClassIdentity
         kSecAttrGeneric
 
         kSecClassInternetPassword item attributes:
         kSecAttrGeneric
 
         kSecClassInternetPassword item attributes:
-        kSecAttrAccess
+        kSecAttrAccess (OS X only)
+        kSecAttrAccessGroup (iOS; also OS X if kSecAttrSynchronizable specified)
+        kSecAttrAccessible (iOS; also OS X if kSecAttrSynchronizable specified)
         kSecAttrCreationDate
         kSecAttrModificationDate
         kSecAttrDescription
         kSecAttrCreationDate
         kSecAttrModificationDate
         kSecAttrDescription
@@ -125,7 +129,9 @@ extern const CFTypeRef kSecClassIdentity
         kSecAttrPublicKeyHash
 
         kSecClassKey item attributes:
         kSecAttrPublicKeyHash
 
         kSecClassKey item attributes:
-        kSecAttrAccess
+        kSecAttrAccess (OS X only)
+        kSecAttrAccessGroup (iOS only)
+        kSecAttrAccessible (iOS only)
         kSecAttrKeyClass
         kSecAttrLabel
         kSecAttrApplicationLabel
         kSecAttrKeyClass
         kSecAttrLabel
         kSecAttrApplicationLabel
@@ -158,8 +164,84 @@ extern const CFTypeRef kSecClassIdentity
         certificate, this class shares attributes of both kSecClassKey and
         kSecClassCertificate.
 
         certificate, this class shares attributes of both kSecClassKey and
         kSecClassCertificate.
 
-    @constant kSecAttrAccess Specifies a dictionary key whose value
-        is a SecAccessRef describing the access control settings for this item.
+     @constant kSecAttrAccessible Specifies a dictionary key whose value
+     indicates when your application needs access to an item's data.  You
+     should choose the most restrictive option that meets your application's
+     needs to allow the system to protect that item in the best way possible.
+     See the "kSecAttrAccessible Value Constants" section for a list of
+     values which can be specified.
+     IMPORTANT: This attribute is currently not supported for OS X keychain
+     items, unless the kSecAttrSynchronizable attribute is also present. If
+     both attributes are specified on either OS X or iOS, the value for the
+     kSecAttrAccessible key may only be one whose name does not end with
+     "ThisDeviceOnly", as those cannot sync to another device.
+
+     @constant kSecAttrAccess Specifies a dictionary key whose value
+     is a SecAccessRef describing the access control settings for this item.
+     This key is available on OS X only.
+
+     @constant kSecAttrAccessGroup Specifies a dictionary key whose value is
+     a CFStringRef indicating which access group a item is in.  The access
+     groups that a particular application has membership in are determined by
+     two entitlements for that application.  The application-identifier
+     entitlement contains the application's single access group, unless
+     there is a keychain-access-groups entitlement present.  The latter
+     has as its value a list of access groups; the first item in this list
+     is the default access group. Unless a specific access group is provided
+     as the value of kSecAttrAccessGroup when SecItemAdd is called, new items
+     are created in the application's default access group.  Specifying this
+     attribute in SecItemCopyMatching, SecItemUpdate, or SecItemDelete calls
+     limits the search to the specified access group (of which the calling
+     application must be a member to obtain matching results.)  To share
+     keychain items between multiple applications, each application must have
+     a common group listed in its keychain-access-groups entitlement, and each
+     must specify this shared access group name as the value for the
+     kSecAttrAccessGroup key in the dictionary passed to SecItem functions.
+
+     @constant kSecAttrSynchronizable Specifies a dictionary key whose value is
+     a CFBooleanRef indicating whether the item in question can be synchronized.
+     To add a new item which can be synced to other devices, or to obtain
+     synchronizable results from a query, supply this key with a value of
+     kCFBooleanTrue. If the key is not supplied, or has a value of
+     kCFBooleanFalse, then no synchronizable items will be added or returned.
+     A predefined value, kSecAttrSynchronizableAny, may be provided instead of
+     kCFBooleanTrue if both synchronizable and non-synchronizable results are
+     desired.
+
+     IMPORTANT: Specifying the kSecAttrSynchronizable key has several caveats:
+
+         - Updating or deleting items using the kSecAttrSynchronizable key will
+           affect all copies of the item, not just the one on your local device.
+           Be sure that it makes sense to use the same password on all devices
+           before deciding to make a password synchronizable.
+         - Only password items can currently be synchronized. Keychain syncing
+           is not supported for certificates or cryptographic keys.
+         - Items stored or obtained using the kSecAttrSynchronizable key cannot
+           specify SecAccessRef-based access control with kSecAttrAccess. If a
+           password is intended to be shared between multiple applications, the
+           kSecAttrAccessGroup key must be specified, and each application
+           using this password must have a 'keychain-access-groups' entitlement
+           with the specified access group value.
+         - Items stored or obtained using the kSecAttrSynchronizable key may
+           not also specify a kSecAttrAccessible value which is incompatible
+           with syncing (namely, those whose names end with "ThisDeviceOnly".)
+         - Items stored or obtained using the kSecAttrSynchronizable key cannot
+           be specified by reference. You must pass kSecReturnAttributes and/or
+           kSecReturnData to retrieve results; kSecReturnRef is currently not
+           supported for synchronizable items.
+         - Persistent references to synchronizable items should be avoided;
+           while they may work locally, they cannot be moved between devices,
+           and may not resolve if the item is modified on some other device.
+         - When specifying a query that uses the kSecAttrSynchronizable key,
+           search keys are limited to the item's class and attributes.
+           The only search constant which may be used is kSecMatchLimit; other
+           constants using the kSecMatch prefix are not supported at this time.
+
+     @constant kSecAttrSynchronizableAny Specifies that both synchronizable and
+     non-synchronizable results should be returned from this query. This may be
+     used as a value for the kSecAttrSynchronizable dictionary key in a call to
+     SecItemCopyMatching, SecItemUpdate, or SecItemDelete.
+
         @constant kSecAttrCreationDate (read-only) Specifies a dictionary key whose
         value is the item's creation date. You use this key to get a value
         of type CFDateRef that represents the date the item was created.
         @constant kSecAttrCreationDate (read-only) Specifies a dictionary key whose
         value is the item's creation date. You use this key to get a value
         of type CFDateRef that represents the date the item was created.
@@ -275,10 +357,17 @@ extern const CFTypeRef kSecClassIdentity
         kSecAttrLabel (which is intended to be human-readable). This attribute
         is used to look up a key programmatically; in particular, for keys of
         class kSecAttrKeyClassPublic and kSecAttrKeyClassPrivate, the value of
         kSecAttrLabel (which is intended to be human-readable). This attribute
         is used to look up a key programmatically; in particular, for keys of
         class kSecAttrKeyClassPublic and kSecAttrKeyClassPrivate, the value of
-        this attribute is the hash of the public key.
+        this attribute is the hash of the public key. This item is a type of CFDataRef.
+        Legacy keys may contain a UUID in this field as a CFStringRef.
         @constant kSecAttrIsPermanent Specifies a dictionary key whose value is a
         CFBooleanRef indicating whether the key in question will be stored
         permanently.
         @constant kSecAttrIsPermanent Specifies a dictionary key whose value is a
         CFBooleanRef indicating whether the key in question will be stored
         permanently.
+        @constant kSecAttrIsSensitive Specifies a dictionary key whose value is a
+        CFBooleanRef indicating that the key in question can only be exported
+        in a wrapped (encrypted) format.
+        @constant kSecAttrIsExtractable Specifies a dictionary key whose value is a
+        CFBooleanRef indicating whether the key in question can be exported from
+        its keychain container.
         @constant kSecAttrApplicationTag Specifies a dictionary key whose value is a
         CFDataRef containing private tag data.
         @constant kSecAttrKeyType Specifies a dictionary key whose value is a
         @constant kSecAttrApplicationTag Specifies a dictionary key whose value is a
         CFDataRef containing private tag data.
         @constant kSecAttrKeyType Specifies a dictionary key whose value is a
@@ -318,8 +407,16 @@ extern const CFTypeRef kSecClassIdentity
         CFBooleanRef indicating whether the key in question can be used to
         unwrap another key.
 */
         CFBooleanRef indicating whether the key in question can be used to
         unwrap another key.
 */
+extern const CFTypeRef kSecAttrAccessible
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0);
 extern const CFTypeRef kSecAttrAccess
        __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
 extern const CFTypeRef kSecAttrAccess
        __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+extern const CFTypeRef kSecAttrAccessGroup
+       __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_3_0);
+extern const CFTypeRef kSecAttrSynchronizable
+       __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern const CFTypeRef kSecAttrSynchronizableAny
+       __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
 extern const CFTypeRef kSecAttrCreationDate
        __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
 extern const CFTypeRef kSecAttrModificationDate
 extern const CFTypeRef kSecAttrCreationDate
        __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
 extern const CFTypeRef kSecAttrModificationDate
@@ -376,6 +473,10 @@ extern const CFTypeRef kSecAttrApplicationLabel
        __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
 extern const CFTypeRef kSecAttrIsPermanent
        __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
        __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
 extern const CFTypeRef kSecAttrIsPermanent
        __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
+extern const CFTypeRef kSecAttrIsSensitive
+       __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
+extern const CFTypeRef kSecAttrIsExtractable
+       __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
 extern const CFTypeRef kSecAttrApplicationTag
        __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
 extern const CFTypeRef kSecAttrKeyType
 extern const CFTypeRef kSecAttrApplicationTag
        __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
 extern const CFTypeRef kSecAttrKeyType
@@ -405,6 +506,58 @@ extern const CFTypeRef kSecAttrCanWrap
 extern const CFTypeRef kSecAttrCanUnwrap
        __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
 
 extern const CFTypeRef kSecAttrCanUnwrap
        __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
 
+/*!
+    @enum kSecAttrAccessible Value Constants
+    @discussion Predefined item attribute constants used to get or set values
+        in a dictionary. The kSecAttrAccessible constant is the key and its
+        value is one of the constants defined here.
+        When asking SecItemCopyMatching to return the item's data, the error
+        errSecInteractionNotAllowed will be returned if the item's data is not
+        available until a device unlock occurs.
+    @constant kSecAttrAccessibleWhenUnlocked Item data can only be accessed
+        while the device is unlocked. This is recommended for items that only
+        need be accesible while the application is in the foreground.  Items
+        with this attribute will migrate to a new device when using encrypted
+        backups.
+    @constant kSecAttrAccessibleAfterFirstUnlock Item data can only be
+        accessed once the device has been unlocked after a restart.  This is
+        recommended for items that need to be accesible by background
+        applications. Items with this attribute will migrate to a new device
+        when using encrypted backups.
+    @constant kSecAttrAccessibleAlways Item data can always be accessed
+        regardless of the lock state of the device.  This is not recommended
+        for anything except system use. Items with this attribute will migrate
+        to a new device when using encrypted backups.
+    @constant kSecAttrAccessibleWhenUnlockedThisDeviceOnly Item data can only
+        be accessed while the device is unlocked. This is recommended for items
+        that only need be accesible while the application is in the foreground.
+        Items with this attribute will never migrate to a new device, so after
+        a backup is restored to a new device, these items will be missing.
+    @constant kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly Item data can
+        only be accessed once the device has been unlocked after a restart.
+        This is recommended for items that need to be accessible by background
+        applications. Items with this attribute will never migrate to a new
+        device, so after a backup is restored to a new device these items will
+        be missing.
+    @constant kSecAttrAccessibleAlwaysThisDeviceOnly Item data can always
+        be accessed regardless of the lock state of the device.  This option
+        is not recommended for anything except system use. Items with this
+        attribute will never migrate to a new device, so after a backup is
+        restored to a new device, these items will be missing.
+*/
+extern const CFTypeRef kSecAttrAccessibleWhenUnlocked
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0);
+extern const CFTypeRef kSecAttrAccessibleAfterFirstUnlock
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0);
+extern const CFTypeRef kSecAttrAccessibleAlways
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0);
+extern const CFTypeRef kSecAttrAccessibleWhenUnlockedThisDeviceOnly
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0);
+extern const CFTypeRef kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0);
+extern const CFTypeRef kSecAttrAccessibleAlwaysThisDeviceOnly
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0);
+
 /*!
         @enum kSecAttrProtocol Value Constants
         @discussion Predefined item attribute constants used to get or set values
 /*!
         @enum kSecAttrProtocol Value Constants
         @discussion Predefined item attribute constants used to get or set values
@@ -564,7 +717,8 @@ extern const CFTypeRef kSecAttrKeyClassSymmetric
         @constant kSecAttrKeyTypeRC4
         @constant kSecAttrKeyTypeRC2
         @constant kSecAttrKeyTypeCAST
         @constant kSecAttrKeyTypeRC4
         @constant kSecAttrKeyTypeRC2
         @constant kSecAttrKeyTypeCAST
-        @constant kSecAttrKeyTypeECDSA
+     @constant kSecAttrKeyTypeECDSA (deprecated; use kSecAttrKeyTypeEC instead.)
+     @constant kSecAttrKeyTypeEC
 */
 extern const CFTypeRef kSecAttrKeyTypeRSA
        __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0);
 */
 extern const CFTypeRef kSecAttrKeyTypeRSA
        __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0);
@@ -584,6 +738,8 @@ extern const CFTypeRef kSecAttrKeyTypeCAST
        __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
 extern const CFTypeRef kSecAttrKeyTypeECDSA
        __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
        __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
 extern const CFTypeRef kSecAttrKeyTypeECDSA
        __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+extern const CFTypeRef kSecAttrKeyTypeEC
+       __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0);
 
 /*!
         @enum kSecAttrPRF Value Constants
 
 /*!
         @enum kSecAttrPRF Value Constants
index 274a165e9e53c4f2bb8b957f7d902612899ce294..cba8c4efcfdf5fc44c393116c307d3b41abcad06 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2006-2008,2010 Apple Inc. All Rights Reserved.
+ * Copyright (c) 2006-2013 Apple Inc. All Rights Reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -106,6 +106,8 @@ SEC_CONST_DECL (kSecAttrHasCustomIcon, "cusi");
 SEC_CONST_DECL (kSecAttrCRLType, "crlt");
 SEC_CONST_DECL (kSecAttrCRLEncoding, "crle");
 SEC_CONST_DECL (kSecAttrSynchronizable, "sync");
 SEC_CONST_DECL (kSecAttrCRLType, "crlt");
 SEC_CONST_DECL (kSecAttrCRLEncoding, "crle");
 SEC_CONST_DECL (kSecAttrSynchronizable, "sync");
+SEC_CONST_DECL (kSecAttrSynchronizableAny, "syna");
+SEC_CONST_DECL (kSecAttrTombstone, "tomb");
 
 /* Search Constants */
 SEC_CONST_DECL (kSecMatchPolicy, "m_Policy");
 
 /* Search Constants */
 SEC_CONST_DECL (kSecMatchPolicy, "m_Policy");
@@ -142,6 +144,14 @@ SEC_CONST_DECL (kSecValuePersistentRef, "v_PersistentRef");
 SEC_CONST_DECL (kSecUseItemList, "u_ItemList");
 SEC_CONST_DECL (kSecUseKeychain, "u_Keychain");
 
 SEC_CONST_DECL (kSecUseItemList, "u_ItemList");
 SEC_CONST_DECL (kSecUseKeychain, "u_Keychain");
 
+/* kSecAttrAccessible Value Constants. */
+SEC_CONST_DECL (kSecAttrAccessibleWhenUnlocked, "ak");
+SEC_CONST_DECL (kSecAttrAccessibleAfterFirstUnlock, "ck");
+SEC_CONST_DECL (kSecAttrAccessibleAlways, "dk");
+SEC_CONST_DECL (kSecAttrAccessibleWhenUnlockedThisDeviceOnly, "aku");
+SEC_CONST_DECL (kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, "cku");
+SEC_CONST_DECL (kSecAttrAccessibleAlwaysThisDeviceOnly, "dku");
+
 /* kSecAttrProtocol Value Constants. */
 SEC_CONST_DECL (kSecAttrProtocolFTP, "ftp ");
 SEC_CONST_DECL (kSecAttrProtocolFTPAccount, "ftpa");
 /* kSecAttrProtocol Value Constants. */
 SEC_CONST_DECL (kSecAttrProtocolFTP, "ftp ");
 SEC_CONST_DECL (kSecAttrProtocolFTPAccount, "ftpa");
@@ -203,6 +213,7 @@ SEC_CONST_DECL (kSecAttrKeyTypeRSA, "42");
 SEC_CONST_DECL (kSecAttrKeyTypeDSA, "43");
 SEC_CONST_DECL (kSecAttrKeyTypeCAST, "56");
 SEC_CONST_DECL (kSecAttrKeyTypeECDSA, "73");
 SEC_CONST_DECL (kSecAttrKeyTypeDSA, "43");
 SEC_CONST_DECL (kSecAttrKeyTypeCAST, "56");
 SEC_CONST_DECL (kSecAttrKeyTypeECDSA, "73");
+SEC_CONST_DECL (kSecAttrKeyTypeEC, "73"); /* rdar://13326326 */
 SEC_CONST_DECL (kSecAttrKeyTypeAES, "2147483649"); /* <Security/cssmapple.h> */
 
 SEC_CONST_DECL (kSecAttrPRFHmacAlgSHA1, "hsha1");
 SEC_CONST_DECL (kSecAttrKeyTypeAES, "2147483649"); /* <Security/cssmapple.h> */
 
 SEC_CONST_DECL (kSecAttrPRFHmacAlgSHA1, "hsha1");
index 3165aa942e8caeebabb3e89efcbcc9b7287cabb7..9b1fb7f0d73bd15cbbe8c775b93b5cd0c70fc53c 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2006-2011 Apple Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2006-2013 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
 #ifndef _SECURITY_SECITEMPRIV_H_
 #define _SECURITY_SECITEMPRIV_H_
 
 #ifndef _SECURITY_SECITEMPRIV_H_
 #define _SECURITY_SECITEMPRIV_H_
 
+#include <CoreFoundation/CFDictionary.h>
+#include <CoreFoundation/CFData.h>
+#include <CoreFoundation/CFError.h>
+#include <Security/SecTask.h>
 
 #if defined(__cplusplus)
 extern "C" {
 #endif
 
 #if defined(__cplusplus)
 extern "C" {
 #endif
-       
+
        /*!
         @enum Class Value Constants (Private)
         @discussion Predefined item class constants used to get or set values in
        /*!
         @enum Class Value Constants (Private)
         @discussion Predefined item class constants used to get or set values in
@@ -43,15 +47,15 @@ extern "C" {
         @constant kSecClassAppleSharePassword Specifies AppleShare password items.
         */
        extern const CFTypeRef kSecClassAppleSharePassword;
         @constant kSecClassAppleSharePassword Specifies AppleShare password items.
         */
        extern const CFTypeRef kSecClassAppleSharePassword;
-       
+
        /*!
         @enum Attribute Key Constants (Private)
         @discussion Predefined item attribute keys used to get or set values in a
         dictionary. Not all attributes apply to each item class. The table
         below lists the currently defined attributes for each item class:
        /*!
         @enum Attribute Key Constants (Private)
         @discussion Predefined item attribute keys used to get or set values in a
         dictionary. Not all attributes apply to each item class. The table
         below lists the currently defined attributes for each item class:
-        
+
         kSecClassGenericPassword item attributes:
         kSecClassGenericPassword item attributes:
-        kSecAttrAccessGroup (private)
+        kSecAttrAccessGroup
         kSecAttrCreationDate
         kSecAttrModificationDate
         kSecAttrDescription
         kSecAttrCreationDate
         kSecAttrModificationDate
         kSecAttrDescription
@@ -68,9 +72,9 @@ extern "C" {
         kSecAttrAccount
         kSecAttrService
         kSecAttrGeneric
         kSecAttrAccount
         kSecAttrService
         kSecAttrGeneric
-        
+
         kSecClassInternetPassword item attributes:
         kSecClassInternetPassword item attributes:
-        kSecAttrAccessGroup (private)
+        kSecAttrAccessGroup
         kSecAttrCreationDate
         kSecAttrModificationDate
         kSecAttrDescription
         kSecAttrCreationDate
         kSecAttrModificationDate
         kSecAttrDescription
@@ -91,9 +95,9 @@ extern "C" {
         kSecAttrAuthenticationType
         kSecAttrPort
         kSecAttrPath
         kSecAttrAuthenticationType
         kSecAttrPort
         kSecAttrPath
-        
+
         kSecClassAppleSharePassword item attributes:
         kSecClassAppleSharePassword item attributes:
-        kSecAttrAccessGroup (private)
+        kSecAttrAccessGroup
         kSecAttrCreationDate
         kSecAttrModificationDate
         kSecAttrDescription
         kSecAttrCreationDate
         kSecAttrModificationDate
         kSecAttrDescription
@@ -111,9 +115,9 @@ extern "C" {
         kSecAttrVolume
         kSecAttrAddress
         kSecAttrAFPServerSignature
         kSecAttrVolume
         kSecAttrAddress
         kSecAttrAFPServerSignature
-        
+
         kSecClassCertificate item attributes:
         kSecClassCertificate item attributes:
-        kSecAttrAccessGroup (private)
+        kSecAttrAccessGroup
         kSecAttrCertificateType
         kSecAttrCertificateEncoding
         kSecAttrLabel
         kSecAttrCertificateType
         kSecAttrCertificateEncoding
         kSecAttrLabel
@@ -123,9 +127,9 @@ extern "C" {
         kSecAttrSerialNumber
         kSecAttrSubjectKeyID
         kSecAttrPublicKeyHash
         kSecAttrSerialNumber
         kSecAttrSubjectKeyID
         kSecAttrPublicKeyHash
-        
+
         kSecClassKey item attributes:
         kSecClassKey item attributes:
-        kSecAttrAccessGroup (private)
+        kSecAttrAccessGroup
         kSecAttrKeyClass
         kSecAttrLabel
         kSecAttrAlias (private)
         kSecAttrKeyClass
         kSecAttrLabel
         kSecAttrAlias (private)
@@ -153,12 +157,12 @@ extern "C" {
         kSecAttrCanVerifyRecover (private)
         kSecAttrCanWrap
         kSecAttrCanUnwrap
         kSecAttrCanVerifyRecover (private)
         kSecAttrCanWrap
         kSecAttrCanUnwrap
-        
+
         kSecClassIdentity item attributes:
         Since an identity is the combination of a private key and a
         certificate, this class shares attributes of both kSecClassKey and
         kSecClassCertificate.
         kSecClassIdentity item attributes:
         Since an identity is the combination of a private key and a
         certificate, this class shares attributes of both kSecClassKey and
         kSecClassCertificate.
-        
+
         @constant kSecAttrScriptCode Specifies a dictionary key whose value is the
         item's script code attribute. You use this tag to set or get a value
         of type CFNumberRef that represents a script code for this item's
         @constant kSecAttrScriptCode Specifies a dictionary key whose value is the
         item's script code attribute. You use this tag to set or get a value
         of type CFNumberRef that represents a script code for this item's
@@ -216,29 +220,20 @@ extern "C" {
         @constant kSecAttrEndDate Specifies a dictionary key whose value is a
         CFDateRef indicating the last date on which this key may be used.
         If kSecAttrEndDate is not present, the restriction does not apply.
         @constant kSecAttrEndDate Specifies a dictionary key whose value is a
         CFDateRef indicating the last date on which this key may be used.
         If kSecAttrEndDate is not present, the restriction does not apply.
-        @constant kSecAttrIsSensitive Specifies a dictionary key whose value
-        is a CFBooleanRef indicating whether the key in question must be wrapped
-        with an algorithm other than CSSM_ALGID_NONE.
         @constant kSecAttrWasAlwaysSensitive Specifies a dictionary key whose value
         is a CFBooleanRef indicating that the key in question has always been
         marked as sensitive.
         @constant kSecAttrWasAlwaysSensitive Specifies a dictionary key whose value
         is a CFBooleanRef indicating that the key in question has always been
         marked as sensitive.
-        @constant kSecAttrIsExtractable Specifies a dictionary key whose value
-        is a CFBooleanRef indicating whether the key in question may be wrapped.
         @constant kSecAttrWasNeverExtractable Specifies a dictionary key whose value
         is a CFBooleanRef indicating that the key in question has never been
         marked as extractable.
         @constant kSecAttrWasNeverExtractable Specifies a dictionary key whose value
         is a CFBooleanRef indicating that the key in question has never been
         marked as extractable.
-        @constant kSecAttrCanSignRecover Specifies a dictionary key whole value is a
+        @constant kSecAttrCanSignRecover Specifies a dictionary key whose value is a
         CFBooleanRef indicating whether the key in question can be used to
         perform sign recovery.
         CFBooleanRef indicating whether the key in question can be used to
         perform sign recovery.
-        @constant kSecAttrCanVerifyRecover Specifies a dictionary key whole value is
+        @constant kSecAttrCanVerifyRecover Specifies a dictionary key whose value is
         a CFBooleanRef indicating whether the key in question can be used to
         perform verify recovery.
         a CFBooleanRef indicating whether the key in question can be used to
         perform verify recovery.
-        @constant kSecAttrAccessGroup Specifies a dictionary key whole value is
-        a CFStringRef indicating which access group a item is in.  The access
-        groups that a particular application has access to are determined by
-        an entitlement in that application.
-        @constant kSecAttrSynchronizable Specifies a dictionary key whose value is
-        a CFBooleanRef indicating that the item in question can be synchronized.
+        @constant kSecAttrTombstone Specifies a dictionary key whose value is
+        a CFBooleanRef indicating that the item in question is a tombstone.
         */
        extern CFTypeRef kSecAttrScriptCode;
        extern CFTypeRef kSecAttrAlias;
         */
        extern CFTypeRef kSecAttrScriptCode;
        extern CFTypeRef kSecAttrAlias;
@@ -253,15 +248,12 @@ extern "C" {
        extern CFTypeRef kSecAttrIsModifiable;
        extern CFTypeRef kSecAttrStartDate;
        extern CFTypeRef kSecAttrEndDate;
        extern CFTypeRef kSecAttrIsModifiable;
        extern CFTypeRef kSecAttrStartDate;
        extern CFTypeRef kSecAttrEndDate;
-       extern CFTypeRef kSecAttrIsSensitive;
        extern CFTypeRef kSecAttrWasAlwaysSensitive;
        extern CFTypeRef kSecAttrWasAlwaysSensitive;
-       extern CFTypeRef kSecAttrIsExtractable;
        extern CFTypeRef kSecAttrWasNeverExtractable;
        extern CFTypeRef kSecAttrCanSignRecover;
        extern CFTypeRef kSecAttrCanVerifyRecover;
        extern CFTypeRef kSecAttrWasNeverExtractable;
        extern CFTypeRef kSecAttrCanSignRecover;
        extern CFTypeRef kSecAttrCanVerifyRecover;
-       extern CFTypeRef kSecAttrAccessGroup;
-       extern CFTypeRef kSecAttrSynchronizable;
-       
+       extern CFTypeRef kSecAttrTombstone;
+
        /*!
         @function SecItemCopyDisplayNames
         @abstract Returns an array containing unique display names for each of the
        /*!
         @function SecItemCopyDisplayNames
         @abstract Returns an array containing unique display names for each of the
@@ -279,7 +271,7 @@ extern "C" {
         be unique across the set of provided items.
         */
        OSStatus SecItemCopyDisplayNames(CFArrayRef items, CFArrayRef *displayNames);
         be unique across the set of provided items.
         */
        OSStatus SecItemCopyDisplayNames(CFArrayRef items, CFArrayRef *displayNames);
-       
+
        /*!
         @function SecItemDeleteAll
         @abstract Removes all items from the keychain and added root certificates
        /*!
         @function SecItemDeleteAll
         @abstract Removes all items from the keychain and added root certificates
@@ -287,7 +279,16 @@ extern "C" {
         @result A result code. See "Security Error Codes" (SecBase.h).
         */
        OSStatus SecItemDeleteAll(void);
         @result A result code. See "Security Error Codes" (SecBase.h).
         */
        OSStatus SecItemDeleteAll(void);
-       
+
+/* Called by clients to push sync circle and message changes to us.
+   Requires caller to have the kSecEntitlementSyncKeychain entitlement. */
+bool _SecKeychainSyncUpdate(CFDictionaryRef updates, CFErrorRef *error);
+
+CFDataRef _SecItemGetPersistentReference(CFTypeRef raw_item);
+
+bool _SecKeychainBackupSyncable(CFDataRef keybag, CFDataRef password, CFDictionaryRef backup_in, CFDictionaryRef *backup_out);
+bool _SecKeychainRestoreSyncable(CFDataRef keybag, CFDataRef password, CFDictionaryRef backup_in);
+
 #if defined(__cplusplus)
 }
 #endif
 #if defined(__cplusplus)
 }
 #endif
index 9d924915f86419f4dd3ea9c876bf5da52a7199ca..a08bdd15506c979756405412143cd7cc683de84d 100644 (file)
@@ -57,8 +57,7 @@ SecKeyGetTypeID(void)
        END_SECAPI1(_kCFRuntimeNotATypeID)
 }
 
        END_SECAPI1(_kCFRuntimeNotATypeID)
 }
 
-OSStatus
-SecKeyCreatePair(
+static OSStatus SecKeyCreatePairInternal(
        SecKeychainRef keychainRef,
        CSSM_ALGORITHMS algorithm,
        uint32 keySizeInBits,
        SecKeychainRef keychainRef,
        CSSM_ALGORITHMS algorithm,
        uint32 keySizeInBits,
@@ -77,6 +76,9 @@ SecKeyCreatePair(
        SecPointer<Access> theAccess(initialAccess ? Access::required(initialAccess) : new Access("<key>"));
        SecPointer<KeyItem> pubItem, privItem;
 
        SecPointer<Access> theAccess(initialAccess ? Access::required(initialAccess) : new Access("<key>"));
        SecPointer<KeyItem> pubItem, privItem;
 
+    Mutex *keychainMutex = keychain->getKeychainMutex();
+    StLock<Mutex> _(*keychainMutex);
+    
        KeyItem::createPair(keychain,
         algorithm,
         keySizeInBits,
        KeyItem::createPair(keychain,
         algorithm,
         keySizeInBits,
@@ -98,6 +100,28 @@ SecKeyCreatePair(
        END_SECAPI
 }
 
        END_SECAPI
 }
 
+OSStatus
+SecKeyCreatePair(
+       SecKeychainRef keychainRef,
+       CSSM_ALGORITHMS algorithm,
+       uint32 keySizeInBits,
+       CSSM_CC_HANDLE contextHandle,
+       CSSM_KEYUSE publicKeyUsage,
+       uint32 publicKeyAttr,
+       CSSM_KEYUSE privateKeyUsage,
+       uint32 privateKeyAttr,
+       SecAccessRef initialAccess,
+       SecKeyRef* publicKeyRef,
+       SecKeyRef* privateKeyRef)
+{
+    OSStatus result = SecKeyCreatePairInternal(keychainRef, algorithm, keySizeInBits, contextHandle, publicKeyUsage,
+                                               publicKeyAttr, privateKeyUsage, privateKeyAttr, initialAccess, publicKeyRef, privateKeyRef);
+    
+    return result;
+}
+
+
+
 OSStatus
 SecKeyGetCSSMKey(SecKeyRef key, const CSSM_KEY **cssmKey)
 {
 OSStatus
 SecKeyGetCSSMKey(SecKeyRef key, const CSSM_KEY **cssmKey)
 {
@@ -142,7 +166,7 @@ SecKeyGetAlgorithmId(SecKeyRef key)
 {
        const CSSM_KEY *cssmKey;
 
 {
        const CSSM_KEY *cssmKey;
 
-       if (SecKeyGetCSSMKey(key, &cssmKey) != noErr)
+       if (SecKeyGetCSSMKey(key, &cssmKey) != errSecSuccess)
                return kSecNullAlgorithmID;
 
        switch (cssmKey->KeyHeader.AlgorithmId) {
                return kSecNullAlgorithmID;
 
        switch (cssmKey->KeyHeader.AlgorithmId) {
@@ -215,7 +239,7 @@ SecKeyImportPair(
        END_SECAPI
 }
 
        END_SECAPI
 }
 
-OSStatus
+static OSStatus
 SecKeyGenerateWithAttributes(
        SecKeychainAttributeList* attrList,
        SecKeychainRef keychainRef,
 SecKeyGenerateWithAttributes(
        SecKeychainAttributeList* attrList,
        SecKeychainRef keychainRef,
@@ -285,12 +309,12 @@ SecKeyCreate(CFAllocatorRef allocator,
        try {
                //FIXME: needs implementation
 
        try {
                //FIXME: needs implementation
 
-               __secapiresult=noErr;
+               __secapiresult=errSecSuccess;
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
-       catch (const std::bad_alloc &) { __secapiresult=memFullErr; }
-       catch (...) { __secapiresult=internalComponentErr; }
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
+       catch (...) { __secapiresult=errSecInternalComponent; }
        return keyRef;
 }
 
        return keyRef;
 }
 
@@ -324,11 +348,11 @@ static u_int32_t ConvertCFStringToInteger(CFStringRef ref)
        }
 
        // figure out the size of the string
        }
 
        // figure out the size of the string
-       int numChars = CFStringGetMaximumSizeForEncoding(CFStringGetLength(ref), kCFStringEncodingUTF8);
+       CFIndex numChars = CFStringGetMaximumSizeForEncoding(CFStringGetLength(ref), kCFStringEncodingUTF8);
        char buffer[numChars];
        if (!CFStringGetCString(ref, buffer, numChars, kCFStringEncodingUTF8))
        {
        char buffer[numChars];
        if (!CFStringGetCString(ref, buffer, numChars, kCFStringEncodingUTF8))
        {
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
        }
 
        return atoi(buffer);
        }
 
        return atoi(buffer);
@@ -347,16 +371,17 @@ static OSStatus CheckAlgorithmType(CFDictionaryRef parameters, CSSM_ALGORITHMS &
 
        if (CFEqual(ktype, kSecAttrKeyTypeRSA)) {
                algorithms = CSSM_ALGID_RSA;
 
        if (CFEqual(ktype, kSecAttrKeyTypeRSA)) {
                algorithms = CSSM_ALGID_RSA;
-               return noErr;
-       } else if(CFEqual(ktype, kSecAttrKeyTypeECDSA)) {
+               return errSecSuccess;
+       } else if(CFEqual(ktype, kSecAttrKeyTypeECDSA) ||
+                       CFEqual(ktype, kSecAttrKeyTypeEC)) {
                algorithms = CSSM_ALGID_ECDSA;
                algorithms = CSSM_ALGID_ECDSA;
-               return noErr;
+               return errSecSuccess;
        } else if(CFEqual(ktype, kSecAttrKeyTypeAES)) {
                algorithms = CSSM_ALGID_AES;
        } else if(CFEqual(ktype, kSecAttrKeyTypeAES)) {
                algorithms = CSSM_ALGID_AES;
-               return noErr;
+               return errSecSuccess;
        } else if(CFEqual(ktype, kSecAttrKeyType3DES)) {
                algorithms = CSSM_ALGID_3DES;
        } else if(CFEqual(ktype, kSecAttrKeyType3DES)) {
                algorithms = CSSM_ALGID_3DES;
-               return noErr;
+               return errSecSuccess;
        } else {
                return errSecUnsupportedAlgorithm;
        }
        } else {
                return errSecUnsupportedAlgorithm;
        }
@@ -383,20 +408,20 @@ static OSStatus GetKeySize(CFDictionaryRef parameters, CSSM_ALGORITHMS algorithm
     switch (algorithms) {
     case CSSM_ALGID_ECDSA:
         if(keySizeInBits == kSecDefaultKeySize) keySizeInBits = kSecp256r1;
     switch (algorithms) {
     case CSSM_ALGID_ECDSA:
         if(keySizeInBits == kSecDefaultKeySize) keySizeInBits = kSecp256r1;
-        if(keySizeInBits == kSecp192r1 || keySizeInBits == kSecp256r1 || keySizeInBits == kSecp384r1 || keySizeInBits == kSecp521r1 ) return noErr;
+        if(keySizeInBits == kSecp192r1 || keySizeInBits == kSecp256r1 || keySizeInBits == kSecp384r1 || keySizeInBits == kSecp521r1 ) return errSecSuccess;
         break;
     case CSSM_ALGID_RSA:
                          if(keySizeInBits % 8) return errSecParam;
         if(keySizeInBits == kSecDefaultKeySize) keySizeInBits = 2048;
         break;
     case CSSM_ALGID_RSA:
                          if(keySizeInBits % 8) return errSecParam;
         if(keySizeInBits == kSecDefaultKeySize) keySizeInBits = 2048;
-        if(keySizeInBits >= kSecRSAMin && keySizeInBits <= kSecRSAMax) return noErr;
+        if(keySizeInBits >= kSecRSAMin && keySizeInBits <= kSecRSAMax) return errSecSuccess;
         break;
     case CSSM_ALGID_AES:
         if(keySizeInBits == kSecDefaultKeySize) keySizeInBits = kSecAES128;
         break;
     case CSSM_ALGID_AES:
         if(keySizeInBits == kSecDefaultKeySize) keySizeInBits = kSecAES128;
-        if(keySizeInBits == kSecAES128 || keySizeInBits == kSecAES192 || keySizeInBits == kSecAES256) return noErr;
+        if(keySizeInBits == kSecAES128 || keySizeInBits == kSecAES192 || keySizeInBits == kSecAES256) return errSecSuccess;
         break;
     case CSSM_ALGID_3DES:
         if(keySizeInBits == kSecDefaultKeySize) keySizeInBits = kSec3DES192;
         break;
     case CSSM_ALGID_3DES:
         if(keySizeInBits == kSecDefaultKeySize) keySizeInBits = kSec3DES192;
-        if(keySizeInBits == kSec3DES192) return noErr;
+        if(keySizeInBits == kSec3DES192) return errSecSuccess;
         break;
     default:
         break;
         break;
     default:
         break;
@@ -502,7 +527,7 @@ static OSStatus ScanDictionaryForParameters(CFDictionaryRef parameters, void* at
                }
        }
 
                }
        }
 
-       return noErr;
+       return errSecSuccess;
 }
 
 
 }
 
 
@@ -528,7 +553,7 @@ static OSStatus GetKeyParameters(CFDictionaryRef parameters, int keySize, bool i
 
        // look for modifiers in the general dictionary
        OSStatus result = ScanDictionaryForParameters(parameters, attributePointers);
 
        // look for modifiers in the general dictionary
        OSStatus result = ScanDictionaryForParameters(parameters, attributePointers);
-       if (result != noErr)
+       if (result != errSecSuccess)
        {
                return result;
        }
        {
                return result;
        }
@@ -554,8 +579,8 @@ static OSStatus GetKeyParameters(CFDictionaryRef parameters, int keySize, bool i
                }
 
                // pull any additional parameters out of this dictionary
                }
 
                // pull any additional parameters out of this dictionary
-               result = ScanDictionaryForParameters(parameters, attributePointers);
-               if (result != noErr)
+               result = ScanDictionaryForParameters((CFDictionaryRef)dType, attributePointers);
+               if (result != errSecSuccess)
                {
                        return result;
                }
                {
                        return result;
                }
@@ -605,7 +630,7 @@ static OSStatus GetKeyParameters(CFDictionaryRef parameters, int keySize, bool i
 
        attrs |= CSSM_KEYATTR_PERMANENT;
 
 
        attrs |= CSSM_KEYATTR_PERMANENT;
 
-       return noErr;
+       return errSecSuccess;
 }
 
 
 }
 
 
@@ -626,25 +651,25 @@ static OSStatus MakeKeyGenParametersFromDictionary(CFDictionaryRef parameters,
        OSStatus result;
 
        result = CheckAlgorithmType(parameters, algorithms);
        OSStatus result;
 
        result = CheckAlgorithmType(parameters, algorithms);
-       if (result != noErr)
+       if (result != errSecSuccess)
        {
                return result;
        }
 
        result = GetKeySize(parameters, algorithms, keySizeInBits);
        {
                return result;
        }
 
        result = GetKeySize(parameters, algorithms, keySizeInBits);
-       if (result != noErr)
+       if (result != errSecSuccess)
        {
                return result;
        }
 
        {
                return result;
        }
 
-       result = GetKeyParameters(parameters, keySizeInBits, false, privateKeyUse, privateKeyAttr, publicKeyLabelRef, publicKeyAttributeTagRef);
-       if (result != noErr)
+       result = GetKeyParameters(parameters, keySizeInBits, false, privateKeyUse, privateKeyAttr, privateKeyLabelRef, privateKeyAttributeTagRef);
+       if (result != errSecSuccess)
        {
                return result;
        }
 
        {
                return result;
        }
 
-       result = GetKeyParameters(parameters, keySizeInBits, true, publicKeyUse, publicKeyAttr, privateKeyLabelRef, privateKeyAttributeTagRef);
-       if (result != noErr)
+       result = GetKeyParameters(parameters, keySizeInBits, true, publicKeyUse, publicKeyAttr, publicKeyLabelRef, publicKeyAttributeTagRef);
+       if (result != errSecSuccess)
        {
                return result;
        }
        {
                return result;
        }
@@ -655,10 +680,10 @@ static OSStatus MakeKeyGenParametersFromDictionary(CFDictionaryRef parameters,
        }
        else if (SecAccessGetTypeID() != CFGetTypeID(initialAccess))
        {
        }
        else if (SecAccessGetTypeID() != CFGetTypeID(initialAccess))
        {
-               return paramErr;
+               return errSecParam;
        }
 
        }
 
-       return noErr;
+       return errSecSuccess;
 }
 
 
 }
 
 
@@ -678,7 +703,7 @@ static OSStatus SetKeyLabelAndTag(SecKeyRef keyRef, CFTypeRef label, CFDataRef t
 
        if (numToModify == 0)
        {
 
        if (numToModify == 0)
        {
-               return noErr;
+               return errSecSuccess;
        }
 
        SecKeychainAttributeList attrList;
        }
 
        SecKeychainAttributeList attrList;
@@ -699,18 +724,18 @@ static OSStatus SetKeyLabelAndTag(SecKeyRef keyRef, CFTypeRef label, CFDataRef t
                                        UnixError::throwMe(ENOMEM);
                                }
                                if (!CFStringGetCString(label_string, static_cast<char *>(attributes[i].data), buffer_length, kCFStringEncodingUTF8)) {
                                        UnixError::throwMe(ENOMEM);
                                }
                                if (!CFStringGetCString(label_string, static_cast<char *>(attributes[i].data), buffer_length, kCFStringEncodingUTF8)) {
-                                       MacOSError::throwMe(paramErr);
+                                       MacOSError::throwMe(errSecParam);
                                }
                        }
                                }
                        }
-                       attributes[i].length = strlen(static_cast<char *>(attributes[i].data));
+                       attributes[i].length = (UInt32)strlen(static_cast<char *>(attributes[i].data));
                } else if (CFDataGetTypeID() == CFGetTypeID(label)) {
                        // 10.6 bug compatibility
                        CFDataRef label_data = static_cast<CFDataRef>(label);
                        attributes[i].tag = kSecKeyLabel;
                        attributes[i].data = (void*) CFDataGetBytePtr(label_data);
                } else if (CFDataGetTypeID() == CFGetTypeID(label)) {
                        // 10.6 bug compatibility
                        CFDataRef label_data = static_cast<CFDataRef>(label);
                        attributes[i].tag = kSecKeyLabel;
                        attributes[i].data = (void*) CFDataGetBytePtr(label_data);
-                       attributes[i].length = CFDataGetLength(label_data);
+                       attributes[i].length = (UInt32)CFDataGetLength(label_data);
                } else {
                } else {
-                       MacOSError::throwMe(paramErr);
+                       MacOSError::throwMe(errSecParam);
                }
                i++;
        }
                }
                i++;
        }
@@ -719,7 +744,7 @@ static OSStatus SetKeyLabelAndTag(SecKeyRef keyRef, CFTypeRef label, CFDataRef t
        {
                attributes[i].tag = kSecKeyApplicationTag;
                attributes[i].data = (void*) CFDataGetBytePtr(tag);
        {
                attributes[i].tag = kSecKeyApplicationTag;
                attributes[i].data = (void*) CFDataGetBytePtr(tag);
-               attributes[i].length = CFDataGetLength(tag);
+               attributes[i].length = (UInt32)CFDataGetLength(tag);
                i++;
        }
 
                i++;
        }
 
@@ -762,7 +787,7 @@ SecKeyGeneratePair(
                                                                                                                 publicKeyAttributeTagRef, privateKeyUse, privateKeyAttr, privateKeyLabelRef, privateKeyAttributeTagRef,
                                                                                                                 initialAccess);
 
                                                                                                                 publicKeyAttributeTagRef, privateKeyUse, privateKeyAttr, privateKeyLabelRef, privateKeyAttributeTagRef,
                                                                                                                 initialAccess);
 
-       if (result != noErr)
+       if (result != errSecSuccess)
        {
                return result;
        }
        {
                return result;
        }
@@ -776,7 +801,7 @@ SecKeyGeneratePair(
 
        // do the key generation
        result = SecKeyCreatePair(keychain, algorithms, keySizeInBits, 0, publicKeyUse, publicKeyAttr, privateKeyUse, privateKeyAttr, initialAccess, publicKey, privateKey);
 
        // do the key generation
        result = SecKeyCreatePair(keychain, algorithms, keySizeInBits, 0, publicKeyUse, publicKeyAttr, privateKeyUse, privateKeyAttr, initialAccess, publicKey, privateKey);
-       if (result != noErr)
+       if (result != errSecSuccess)
        {
                return result;
        }
        {
                return result;
        }
@@ -820,6 +845,17 @@ SecKeyRawSign(
        END_SECAPI
 }
 
        END_SECAPI
 }
 
+OSStatus SecKeyRawVerifyOSX(
+    SecKeyRef           key,            /* Public key */
+       SecPadding          padding,            /* kSecPaddingNone or kSecPaddingPKCS1 */
+       const uint8_t       *signedData,        /* signature over this data */
+       size_t              signedDataLen,      /* length of dataToSign */
+       const uint8_t       *sig,                       /* signature */
+       size_t              sigLen)
+{
+    return SecKeyRawVerify(key,padding,signedData,signedDataLen,sig,sigLen);
+}
+
 /* new in 10.6 */
 OSStatus
 SecKeyRawVerify(
 /* new in 10.6 */
 OSStatus
 SecKeyRawVerify(
@@ -950,12 +986,12 @@ SecKeyGetBlockSize(SecKeyRef key)
                                blockSize = 16; /* FIXME: revisit this */
                                break;
                }
                                blockSize = 16; /* FIXME: revisit this */
                                break;
                }
-               __secapiresult=noErr;
+               __secapiresult=errSecSuccess;
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
-       catch (const std::bad_alloc &) { __secapiresult=memFullErr; }
-       catch (...) { __secapiresult=internalComponentErr; }
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
+       catch (...) { __secapiresult=errSecInternalComponent; }
        return blockSize;
 }
 
        return blockSize;
 }
 
@@ -1034,7 +1070,8 @@ utilGetKeyParametersFromCFDict(CFDictionaryRef parameters, CSSM_ALGORITHMS *algo
         *algorithm = CSSM_ALGID_DSA;
         *keySizeInBits = 128;
          *keyClass = CSSM_KEYCLASS_PRIVATE_KEY;
         *algorithm = CSSM_ALGID_DSA;
         *keySizeInBits = 128;
          *keyClass = CSSM_KEYCLASS_PRIVATE_KEY;
-    } else if(CFEqual(algorithmDictValue, kSecAttrKeyTypeECDSA)) {
+    } else if(CFEqual(algorithmDictValue, kSecAttrKeyTypeECDSA) ||
+            CFEqual(algorithmDictValue, kSecAttrKeyTypeEC)) {
         *algorithm = CSSM_ALGID_ECDSA;
         *keySizeInBits = 128;
         *keyClass = CSSM_KEYCLASS_PRIVATE_KEY;
         *algorithm = CSSM_ALGID_ECDSA;
         *keySizeInBits = 128;
         *keyClass = CSSM_KEYCLASS_PRIVATE_KEY;
@@ -1093,7 +1130,7 @@ utilCopyDefaultKeyLabel(void)
 SecKeyRef
 SecKeyGenerateSymmetric(CFDictionaryRef parameters, CFErrorRef *error)
 {
 SecKeyRef
 SecKeyGenerateSymmetric(CFDictionaryRef parameters, CFErrorRef *error)
 {
-       OSStatus result = paramErr; // default result for an early exit
+       OSStatus result = errSecParam; // default result for an early exit
        SecKeyRef key = NULL;
        SecKeychainRef keychain = NULL;
        SecAccessRef access;
        SecKeyRef key = NULL;
        SecKeychainRef keychain = NULL;
        SecAccessRef access;
@@ -1193,9 +1230,9 @@ SecKeyGenerateSymmetric(CFDictionaryRef parameters, CFErrorRef *error)
                        appTagBuf[0]=0;
 
                SecKeychainAttribute attrs[] = {
                        appTagBuf[0]=0;
 
                SecKeychainAttribute attrs[] = {
-                       { kSecKeyPrintName, strlen(labelBuf), (char *)labelBuf },
-                       { kSecKeyLabel, strlen(appLabelBuf), (char *)appLabelBuf },
-                       { kSecKeyApplicationTag, strlen(appTagBuf), (char *)appTagBuf } };
+                       { kSecKeyPrintName, (UInt32)strlen(labelBuf), (char *)labelBuf },
+                       { kSecKeyLabel, (UInt32)strlen(appLabelBuf), (char *)appLabelBuf },
+                       { kSecKeyApplicationTag, (UInt32)strlen(appTagBuf), (char *)appTagBuf } };
                SecKeychainAttributeList attributes = { sizeof(attrs) / sizeof(attrs[0]), attrs };
                if (!appTag) --attributes.count;
 
                SecKeychainAttributeList attributes = { sizeof(attrs) / sizeof(attrs[0]), attrs };
                if (!appTag) --attributes.count;
 
@@ -1283,7 +1320,7 @@ SecKeyGeneratePairAsync(CFDictionaryRef parametersWhichMightBeMutiable, dispatch
                OSStatus status = SecKeyGeneratePair(parameters, &publicKey, &privateKey);
                dispatch_async(deliveryQueue, ^{
                        CFErrorRef error = NULL;
                OSStatus status = SecKeyGeneratePair(parameters, &publicKey, &privateKey);
                dispatch_async(deliveryQueue, ^{
                        CFErrorRef error = NULL;
-                       if (noErr != status) {
+                       if (errSecSuccess != status) {
                                error = CFErrorCreate(NULL, kCFErrorDomainOSStatus, status, NULL);
                        }
                        result(publicKey, privateKey, error);
                                error = CFErrorCreate(NULL, kCFErrorDomainOSStatus, status, NULL);
                        }
                        result(publicKey, privateKey, error);
@@ -1368,6 +1405,9 @@ SecKeyDeriveFromPassword(CFStringRef password, CFDictionaryRef parameters, CFErr
         algorithm = kCCPRFHmacAlgSHA384;
     } else if(CFEqual(algorithmDictValue, kSecAttrPRFHmacAlgSHA512)) {
         algorithm = kCCPRFHmacAlgSHA512;
         algorithm = kCCPRFHmacAlgSHA384;
     } else if(CFEqual(algorithmDictValue, kSecAttrPRFHmacAlgSHA512)) {
         algorithm = kCCPRFHmacAlgSHA512;
+    } else {
+#warning "This else clause is here to prevent the use of unitialized variable, but really, this should return an error, without leaking."
+        algorithm = kCCPRFHmacAlgSHA1;
     }
 
     if(rounds == 0) {
     }
 
     if(rounds == 0) {
@@ -1376,6 +1416,7 @@ SecKeyDeriveFromPassword(CFStringRef password, CFDictionaryRef parameters, CFErr
 
 
     if(CCKeyDerivationPBKDF(kCCPBKDF2, thePassword, passwordLen, salt, saltLen, algorithm, rounds, derivedKey, derivedKeyLen)) {
 
 
     if(CCKeyDerivationPBKDF(kCCPBKDF2, thePassword, passwordLen, salt, saltLen, algorithm, rounds, derivedKey, derivedKeyLen)) {
+#warning "Aren't we leaking salt and thePassword when this fail???"
         *error = CFErrorCreate(NULL, kCFErrorDomainOSStatus, errSecInternalError, NULL);
         return NULL;
     }
         *error = CFErrorCreate(NULL, kCFErrorDomainOSStatus, errSecInternalError, NULL);
         return NULL;
     }
@@ -1637,17 +1678,17 @@ static OSStatus SecKeyGetDigestInfo(SecKeyRef key, const SecAsn1AlgId *algId,
 
     if (digestData) {
         if(dataLen>UINT32_MAX) /* Check for overflow with CC_LONG cast */
 
     if (digestData) {
         if(dataLen>UINT32_MAX) /* Check for overflow with CC_LONG cast */
-            return paramErr;
+            return errSecParam;
         digestFcn(data, (CC_LONG)dataLen, &digestInfo[offset]);
         *digestInfoLen = offset + digestLen;
     } else {
         if (dataLen != digestLen)
         digestFcn(data, (CC_LONG)dataLen, &digestInfo[offset]);
         *digestInfoLen = offset + digestLen;
     } else {
         if (dataLen != digestLen)
-            return paramErr;
+            return errSecParam;
         memcpy(&digestInfo[offset], data, dataLen);
         *digestInfoLen = offset + dataLen;
     }
 
         memcpy(&digestInfo[offset], data, dataLen);
         *digestInfoLen = offset + dataLen;
     }
 
-    return noErr;
+    return errSecSuccess;
 }
 
 OSStatus SecKeyVerifyDigest(
 }
 
 OSStatus SecKeyVerifyDigest(
@@ -1761,7 +1802,7 @@ void secdump(const unsigned char *data, unsigned long len)
 }
 #endif
 
 }
 #endif
 
-OSStatus _SecKeyCopyPublicBytes(SecKeyRef key, CFDataRef* publicBytes)
+OSStatus SecKeyCopyPublicBytes(SecKeyRef key, CFDataRef* publicBytes)
 {
        CFIndex keyAlgId;
 #if TARGET_OS_EMBEDDED
 {
        CFIndex keyAlgId;
 #if TARGET_OS_EMBEDDED
@@ -1769,114 +1810,155 @@ OSStatus _SecKeyCopyPublicBytes(SecKeyRef key, CFDataRef* publicBytes)
 #else
        keyAlgId = SecKeyGetAlgorithmId(key);
 #endif
 #else
        keyAlgId = SecKeyGetAlgorithmId(key);
 #endif
-       if (kSecRSAAlgorithmID == keyAlgId) {
+
+       OSStatus ecStatus = errSecParam;
+       CFDataRef tempPublicData = NULL;
+       CFDataRef headerlessPublicData = NULL;
+       CFIndex headerLength = 0;
+    const UInt8* pData_Ptr = NULL;
+
+       if (kSecRSAAlgorithmID == keyAlgId) 
+       {
                return SecItemExport(key, kSecFormatBSAFE, 0, NULL, publicBytes);
        }
                return SecItemExport(key, kSecFormatBSAFE, 0, NULL, publicBytes);
        }
-       if (kSecECDSAAlgorithmID == keyAlgId) {
-               OSStatus ecStatus = errSecParam;
-               *publicBytes = NULL;
-               uint8 headerBytes[] = { 0x30,0x59,0x30,0x13,0x06,0x07,0x2a,0x86,
-                                       0x48,0xce,0x3d,0x02,0x01,0x06,0x08,0x2a,
-                                       0x86,0x48,0xce,0x3d,0x03,0x01,0x07,0x03,
-                                       0x42,0x00 };
-               uint8 altHdrBytes[] = { 0x30,0x81,0x9b,0x30,0x10,0x06,0x07,0x2a,
-                                       0x86,0x48,0xce,0x3d,0x02,0x01,0x06,0x05,
-                                       0x2b,0x81,0x04,0x00,0x23,0x03,0x81,0x86,
-                                       0x00};
-
-               const size_t headerLen = sizeof(headerBytes);
-               const size_t altHdrLen = sizeof(altHdrBytes);
-               CFDataRef requiredPublicHeader = NULL;
-               CFDataRef tempPublicData = NULL;
-               CFDataRef publicDataHeader = NULL;
-               CFDataRef headerlessPublicData = NULL;
+
+       if (kSecECDSAAlgorithmID == keyAlgId) 
+       {       
+               // First export the key so there is access to the underlying key material
                ecStatus = SecItemExport(key, kSecFormatOpenSSL, 0, NULL, &tempPublicData);
                ecStatus = SecItemExport(key, kSecFormatOpenSSL, 0, NULL, &tempPublicData);
-               if(ecStatus != errSecSuccess) {
+               if(ecStatus != errSecSuccess)
+               {
                        secdebug("key", "SecKeyCopyPublicBytes: SecItemExport error (%d) for ECDSA public key %p",
                                        ecStatus, (uintptr_t)key);
                        secdebug("key", "SecKeyCopyPublicBytes: SecItemExport error (%d) for ECDSA public key %p",
                                        ecStatus, (uintptr_t)key);
-                       goto failEC;
-               }
-               requiredPublicHeader = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, headerBytes, headerLen, kCFAllocatorNull);
-               if (!requiredPublicHeader) {
-                       secdebug("key", "SecKeyCopyPublicBytes: requiredPublicHeader is nil (1)");
-                       goto failEC;
-               }
-               publicDataHeader = _CFDataCreateReferenceFromRange(kCFAllocatorDefault,
-                               tempPublicData, CFRangeMake(0, headerLen));
-               if (!publicDataHeader) {
-                       secdebug("key", "SecKeyCopyPublicBytes: publicDataHeader is nil (1)");
-                       goto failEC;
-               }
-               headerlessPublicData = _CFDataCreateCopyFromRange(kCFAllocatorDefault,
-                               tempPublicData, CFRangeMake(headerLen, CFDataGetLength(tempPublicData) - headerLen));
-               if (!headerlessPublicData) {
-                       secdebug("key", "SecKeyCopyPublicBytes: headerlessPublicData is nil (1)");
-                       goto failEC;
-               }
-               if(!_CFDataEquals(publicDataHeader, requiredPublicHeader)) {
-                       CFRelease(publicDataHeader);
-                       CFRelease(headerlessPublicData);
-                       CFRelease(requiredPublicHeader);
-                       requiredPublicHeader = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, altHdrBytes, altHdrLen, kCFAllocatorNull);
-                       if (!requiredPublicHeader) {
-                               secdebug("key", "SecKeyCopyPublicBytes: requiredPublicHeader is nil (2)");
-                               goto failEC;
-                       }
-                       publicDataHeader = _CFDataCreateReferenceFromRange(kCFAllocatorDefault,
-                                       tempPublicData, CFRangeMake(0, altHdrLen));
-                       if (!publicDataHeader) {
-                               secdebug("key", "SecKeyCopyPublicBytes: publicDataHeader is nil (2)");
-                               goto failEC;
-                       }
-                       headerlessPublicData = _CFDataCreateCopyFromRange(kCFAllocatorDefault,
-                                       tempPublicData, CFRangeMake(altHdrLen, CFDataGetLength(tempPublicData) - altHdrLen));
-                       if (!headerlessPublicData) {
-                               secdebug("key", "SecKeyCopyPublicBytes: headerlessPublicData is nil (2)");
-                               goto failEC;
-                       }
-               }
-               if(!_CFDataEquals(publicDataHeader, requiredPublicHeader)) {
-                       #if ECDSA_DEBUG
-                       CFIndex dataLen = CFDataGetLength(tempPublicData);
-                       const UInt8 *dataPtr = CFDataGetBytePtr(tempPublicData);
-                       syslog(LOG_NOTICE, "Public key data (with header):");
-                       secdump((const unsigned char *)dataPtr,(unsigned long)dataLen);
-                       dataLen = CFDataGetLength(requiredPublicHeader);
-                       dataPtr = CFDataGetBytePtr(requiredPublicHeader);
-                       syslog(LOG_NOTICE, "Required header:");
-                       secdump((const unsigned char *)dataPtr,(unsigned long)dataLen);
-                       dataLen = CFDataGetLength(publicDataHeader);
-                       dataPtr = CFDataGetBytePtr(publicDataHeader);
-                       syslog(LOG_NOTICE, "Actual header:");
-                       secdump((const unsigned char *)dataPtr,(unsigned long)dataLen);
-                       #endif
-                       secdebug("key", "_SecKeyCopyPublicBytes: public data header mismatch");
-                       goto failEC;
-               }
-               if(publicBytes) {
-                       *publicBytes = headerlessPublicData;
-                       ecStatus = errSecSuccess;
+                                       
+               return ecStatus;
+        }
+
+               
+        // Get a pointer to the first byte of the exported data
+        pData_Ptr = CFDataGetBytePtr(tempPublicData);
+
+        // the first byte should be a sequence 0x30
+        if (*pData_Ptr != 0x30)
+        {
+            secdebug("key", "SecKeyCopyPublicBytes: exported data is invalid");
+             if (NULL != tempPublicData)
+                   CFRelease(tempPublicData);
+
+                       ecStatus = errSecParam;
+               return ecStatus;
+        }
+
+        // move past the sequence byte
+        pData_Ptr++;
+
+        // Check to see if the high bit is set which
+        // indicates that the length will be at least 
+        // two bytes.  If the high bit is set then
+        // The lower seven bits specifies the number of
+       // bytes used for the length.  The additonal 1
+       // is for the current byte. Otherwise just move past the 
+       // single length byte
+        pData_Ptr += (*pData_Ptr & 0x80) ? ((*pData_Ptr & 0x7F) + 1) : 1;
+
+        // The current byte should be a sequence 0x30
+        if (*pData_Ptr != 0x30)
+        {
+               secdebug("key", "SecKeyCopyPublicBytes: Could not find the key sequence");
+             if (NULL != tempPublicData)
+                   CFRelease(tempPublicData);
+       
+                       ecStatus = errSecParam;
+
+               return ecStatus;
+        }
+
+        // The next bytes will always be the same
+        // 0x30 = SEQUENCE
+        // XX Length Byte
+        // 0x06 OBJECT ID
+        // 0x07 Length Byte
+        // ECDSA public KEY OID value 0x2a,0x86,0x48,0xce,0x3d,0x02,0x01
+        // 0x06 OBJECT ID
+        // This is a total of 12 bytes
+        pData_Ptr += 12;
+
+        // Next byte is the length of the ECDSA curve OID
+        // Move past the length byte and the curve OID
+        pData_Ptr += (((int)*pData_Ptr) + 1);
+
+        // Should be at a BINARY String which is specifed by a 0x3
+        if (*pData_Ptr != 0x03)
+        {
+               secdebug("key", "SecKeyCopyPublicBytes: Invalid key structure");
+             if (NULL != tempPublicData)
+                   CFRelease(tempPublicData);
+       
+                       ecStatus = errSecParam;
+
+               return ecStatus;
+        }
+
+        // Move past the BINARY String specifier 0x03
+        pData_Ptr++;
+
+
+        // Check to see if the high bit is set which
+        // indicates that the length will be at least 
+        // two bytes.  If the high bit is set then
+        // The lower seven bits specifies the number of
+       // bytes used for the length.  The additonal 1
+       // is for the current byte. Otherwise just move past the 
+       // single length byte
+        pData_Ptr += (*pData_Ptr & 0x80) ? ((*pData_Ptr & 0x7F) + 1) : 1;
+
+        // Move past the beginning marker for the BINARY String 0x00
+        pData_Ptr++;
+
+        // pData_Ptr now points to the first bytes of the key material
+        headerLength = (CFIndex)(((intptr_t)pData_Ptr) -  ((intptr_t)CFDataGetBytePtr(tempPublicData)));       
+        
+        headerlessPublicData = _CFDataCreateCopyFromRange(kCFAllocatorDefault,
+            tempPublicData, CFRangeMake(headerLength, CFDataGetLength(tempPublicData) - headerLength));
+        
+        if (!headerlessPublicData)
+        {
+                       printf("SecKeyCopyPublicBytes: headerlessPublicData is nil (1)\n");
+                if (NULL != tempPublicData)
+                   CFRelease(tempPublicData);
+       
+                       ecStatus = errSecParam;
+
+               return ecStatus;
                }
                }
+        
+        if (publicBytes)
+        {
+               *publicBytes = headerlessPublicData;
+        }
 
 
-failEC:
-               if(requiredPublicHeader) CFRelease(requiredPublicHeader);
-               if(publicDataHeader) CFRelease(publicDataHeader);
-               if(tempPublicData) CFRelease(tempPublicData);
-               return ecStatus;
-       }
-       return errSecParam;
+        ecStatus = errSecSuccess;
+        
+        if (NULL != tempPublicData)
+            CFRelease(tempPublicData);
+            
+        return ecStatus;
+      }
+
+  return errSecParam;
 }
 
 }
 
+
 CFDataRef SecECKeyCopyPublicBits(SecKeyRef key)
 {
     CFDataRef exportedKey;
 CFDataRef SecECKeyCopyPublicBits(SecKeyRef key)
 {
     CFDataRef exportedKey;
-    if(_SecKeyCopyPublicBytes(key, &exportedKey) != noErr) {
+    if(SecKeyCopyPublicBytes(key, &exportedKey) != errSecSuccess) {
         exportedKey = NULL;
     }
     return exportedKey;
 }
 
         exportedKey = NULL;
     }
     return exportedKey;
 }
 
-SecKeyRef _SecKeyCreateFromPublicData(CFAllocatorRef allocator, CFIndex algorithmID, CFDataRef publicBytes)
+SecKeyRef SecKeyCreateFromPublicData(CFAllocatorRef allocator, CFIndex algorithmID, CFDataRef publicBytes)
 {
     SecExternalFormat externalFormat = kSecFormatOpenSSL;
     SecExternalItemType externalItemType = kSecItemTypePublicKey;
 {
     SecExternalFormat externalFormat = kSecFormatOpenSSL;
     SecExternalItemType externalItemType = kSecItemTypePublicKey;
@@ -1939,14 +2021,6 @@ SecKeyRef SecKeyCreateRSAPublicKey(CFAllocatorRef allocator,
 
     } else if(kSecKeyEncodingRSAPublicParams == encoding) {
         /* SecRSAPublicKeyParams format; we must encode as PKCS1. */
 
     } else if(kSecKeyEncodingRSAPublicParams == encoding) {
         /* SecRSAPublicKeyParams format; we must encode as PKCS1. */
-    #if !TARGET_OS_EMBEDDED
-        typedef struct SecRSAPublicKeyParams {
-            uint8_t             *modulus;                      /* modulus */
-            CFIndex             modulusLength;
-            uint8_t             *exponent;                     /* public exponent */
-            CFIndex             exponentLength;
-        } SecRSAPublicKeyParams;
-    #endif
                SecRSAPublicKeyParams *params = (SecRSAPublicKeyParams *)keyData;
                DERSize m_size = params->modulusLength;
                DERSize e_size = params->exponentLength;
                SecRSAPublicKeyParams *params = (SecRSAPublicKeyParams *)keyData;
                DERSize m_size = params->modulusLength;
                DERSize e_size = params->exponentLength;
@@ -1986,7 +2060,7 @@ SecKeyRef SecKeyCreateRSAPublicKey(CFAllocatorRef allocator,
         /* unsupported encoding */
         return NULL;
     }
         /* unsupported encoding */
         return NULL;
     }
-    SecKeyRef publicKey = _SecKeyCreateFromPublicData(allocator, kSecRSAAlgorithmID, pubKeyData);
+    SecKeyRef publicKey = SecKeyCreateFromPublicData(allocator, kSecRSAAlgorithmID, pubKeyData);
     CFRelease(pubKeyData);
     return publicKey;
 }
     CFRelease(pubKeyData);
     return publicKey;
 }
@@ -1996,6 +2070,7 @@ SecKeyRef SecKeyCreateRSAPublicKey(CFAllocatorRef allocator,
 // Given a CSSM public key, copy its modulus and/or exponent data.
 // Caller is responsible for releasing the returned CFDataRefs.
 //
 // Given a CSSM public key, copy its modulus and/or exponent data.
 // Caller is responsible for releasing the returned CFDataRefs.
 //
+static
 OSStatus _SecKeyCopyRSAPublicModulusAndExponent(SecKeyRef key, CFDataRef *modulus, CFDataRef *exponent)
 {
        const CSSM_KEY          *pubKey;
 OSStatus _SecKeyCopyRSAPublicModulusAndExponent(SecKeyRef key, CFDataRef *modulus, CFDataRef *exponent)
 {
        const CSSM_KEY          *pubKey;
@@ -2004,7 +2079,7 @@ OSStatus _SecKeyCopyRSAPublicModulusAndExponent(SecKeyRef key, CFDataRef *modulu
        OSStatus                result;
 
     result = SecKeyGetCSSMKey(key, &pubKey);
        OSStatus                result;
 
     result = SecKeyGetCSSMKey(key, &pubKey);
-       if(result != noErr) {
+       if(result != errSecSuccess) {
                return result;
        }
        hdr = &pubKey->KeyHeader;
                return result;
        }
        hdr = &pubKey->KeyHeader;
@@ -2107,3 +2182,58 @@ CFDataRef SecKeyCopyExponent(SecKeyRef key)
     return exponentData;
 }
 
     return exponentData;
 }
 
+SecKeyRef SecKeyCreatePublicFromPrivate(SecKeyRef privateKey) {
+    OSStatus status = errSecParam;
+    
+    CFDataRef serializedPublic = NULL;
+
+    status = SecKeyCopyPublicBytes(privateKey, &serializedPublic);
+    if ((status == errSecSuccess) && (serializedPublic != NULL)) {
+        SecKeyRef publicKeyRef = SecKeyCreateFromPublicData(kCFAllocatorDefault, SecKeyGetAlgorithmId(privateKey), serializedPublic);
+        CFRelease(serializedPublic);
+        if (publicKeyRef != NULL) {
+            return publicKeyRef;
+        }
+    }
+
+    const void *keys[]      = { kSecClass, kSecValueRef, kSecReturnAttributes };
+    const void *values[]    = { kSecClassKey, privateKey,  kCFBooleanTrue };
+    CFDictionaryRef query= CFDictionaryCreate(NULL, keys, values,
+                                              (sizeof(values) / sizeof(*values)),
+                                              &kCFTypeDictionaryKeyCallBacks,
+                                              &kCFTypeDictionaryValueCallBacks);
+    CFTypeRef foundItem = NULL;
+    status = SecItemCopyMatching(query, &foundItem);
+    
+    if (status == errSecSuccess) {
+        if (CFGetTypeID(foundItem) == CFDictionaryGetTypeID()) {
+            CFMutableDictionaryRef query2 = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+            CFDictionaryAddValue(query2, kSecClass, kSecClassKey);
+            CFDictionaryAddValue(query2, kSecAttrKeyClass, kSecAttrKeyClassPublic);
+            CFDictionaryAddValue(query2, kSecAttrApplicationLabel, CFDictionaryGetValue((CFDictionaryRef)foundItem, kSecAttrApplicationLabel));
+            CFDictionaryAddValue(query2, kSecReturnRef, kCFBooleanTrue);
+
+            CFTypeRef foundKey = NULL;
+            status = SecItemCopyMatching(query2, &foundKey);
+            if (status == errSecSuccess) {
+                if (CFGetTypeID(foundKey) == SecKeyGetTypeID()) {
+                    CFRelease(query);
+                    CFRelease(query2);
+                    CFRelease(foundItem);
+                    return (SecKeyRef)foundKey;
+                } else {
+                    status = errSecItemNotFound;
+                }
+            }
+            CFRelease(query2);
+            
+        } else {
+            status = errSecItemNotFound;
+        }
+        CFRelease(foundItem);
+    }
+   
+    CFRelease(query);
+    return NULL;
+}
+
index f5e7625c287fbc57c6ff40ef259a700d40a073fa..84fa4169adfd59d825fda30372445e66667020c2 100644 (file)
@@ -1,15 +1,15 @@
 /*
  * Copyright (c) 2002-2010 Apple, Inc. All Rights Reserved.
 /*
  * Copyright (c) 2002-2010 Apple, Inc. All Rights Reserved.
- * 
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -62,7 +62,7 @@ extern "C" {
     attributes of this key can be modified.
     @constant kSecKeyLabel type blob, for private and public keys
     this contains the hash of the public key.  This is used to
     attributes of this key can be modified.
     @constant kSecKeyLabel type blob, for private and public keys
     this contains the hash of the public key.  This is used to
-    associate certificates and keys.  It's value matches the value
+    associate certificates and keys.  Its value matches the value
     of the kSecPublicKeyHashItemAttr of a certificate and it's used
     to construct an identity from a certificate and a key.
     For symmetric keys this is whatever the creator of the key
     of the kSecPublicKeyHashItemAttr of a certificate and it's used
     to construct an identity from a certificate and a key.
     For symmetric keys this is whatever the creator of the key
@@ -71,7 +71,7 @@ extern "C" {
     @constant kSecKeyKeyCreator type data, the data points to a
     CSSM_GUID structure representing the moduleid of the csp owning
     this key.
     @constant kSecKeyKeyCreator type data, the data points to a
     CSSM_GUID structure representing the moduleid of the csp owning
     this key.
-    @constant kSecKeyKeyType type uint32, value a CSSM_ALGORITHMS
+    @constant kSecKeyKeyType type uint32, value is a CSSM_ALGORITHMS
     representing the algorithm associated with this key.
     @constant kSecKeyKeySizeInBits type uint32, value is the number
     of bits in this key.
     representing the algorithm associated with this key.
     @constant kSecKeyKeySizeInBits type uint32, value is the number
     of bits in this key.
@@ -106,11 +106,11 @@ extern "C" {
     @constant kSecKeySignRecover type uint32.
     @constant kSecKeyVerifyRecover type uint32.
     key can unwrap other keys.
     @constant kSecKeySignRecover type uint32.
     @constant kSecKeyVerifyRecover type uint32.
     key can unwrap other keys.
-    @constant kSecKeyWrap type uint32, value is nonzero iff this 
+    @constant kSecKeyWrap type uint32, value is nonzero iff this
     key can wrap other keys.
     @constant kSecKeyUnwrap type uint32, value is nonzero iff this
     key can unwrap other keys.
     key can wrap other keys.
     @constant kSecKeyUnwrap type uint32, value is nonzero iff this
     key can unwrap other keys.
-       @discussion 
+       @discussion
        The use of these enumerations has been deprecated.  Please
        use the equivalent items defined in SecItem.h
        @@@.
        The use of these enumerations has been deprecated.  Please
        use the equivalent items defined in SecItem.h
        @@@.
@@ -197,23 +197,23 @@ enum
     @abstract Supported key lengths.
 */
 typedef uint32_t SecKeySizes;
     @abstract Supported key lengths.
 */
 typedef uint32_t SecKeySizes;
-enum 
+enum
 {
     kSecDefaultKeySize  = 0,
 {
     kSecDefaultKeySize  = 0,
-    
+
     // Symmetric Keysizes - default is currently kSecAES128 for AES.
     kSec3DES192         = 192,
     kSecAES128          = 128,
     kSecAES192          = 192,
     kSecAES256          = 256,
     // Symmetric Keysizes - default is currently kSecAES128 for AES.
     kSec3DES192         = 192,
     kSecAES128          = 128,
     kSecAES192          = 192,
     kSecAES256          = 256,
+
     // Supported ECC Keys for Suite-B from RFC 4492 section 5.1.1.
     // default is currently kSecp256r1
     kSecp192r1          = 192,
     kSecp256r1          = 256,
     kSecp384r1          = 384,
     kSecp521r1          = 521,  // Yes, 521
     // Supported ECC Keys for Suite-B from RFC 4492 section 5.1.1.
     // default is currently kSecp256r1
     kSecp192r1          = 192,
     kSecp256r1          = 256,
     kSecp384r1          = 384,
     kSecp521r1          = 521,  // Yes, 521
-    
+
     // Boundaries for RSA KeySizes - default is currently 2048
                // RSA keysizes must be multiples of 8
     kSecRSAMin          = 1024,
     // Boundaries for RSA KeySizes - default is currently 2048
                // RSA keysizes must be multiples of 8
     kSecRSAMin          = 1024,
@@ -256,7 +256,7 @@ OSStatus SecKeyCreatePair(
         CSSM_KEYUSE privateKeyUsage,
         uint32 privateKeyAttr,
         SecAccessRef initialAccess,
         CSSM_KEYUSE privateKeyUsage,
         uint32 privateKeyAttr,
         SecAccessRef initialAccess,
-        SecKeyRef* publicKey, 
+        SecKeyRef* publicKey,
         SecKeyRef* privateKey)
                DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
 
         SecKeyRef* privateKey)
                DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
 
@@ -288,7 +288,7 @@ OSStatus SecKeyGenerate(
 /*!
     @function SecKeyGetCSSMKey
     @abstract Returns a pointer to the CSSM_KEY for the given key item reference.
 /*!
     @function SecKeyGetCSSMKey
     @abstract Returns a pointer to the CSSM_KEY for the given key item reference.
-    @param key A keychain key item reference. The key item must be of class type kSecAppleKeyItemClass.
+    @param key A keychain key item reference. The key item must be of class type kSecPublicKeyItemClass, kSecPrivateKeyItemClass, or kSecSymmetricKeyItemClass.
     @param cssmKey On return, a pointer to a CSSM_KEY structure for the given key. This pointer remains valid until the key reference is released. The caller should not attempt to modify or free this data.
     @result A result code. See "Security Error Codes" (SecBase.h).
     @discussion  The CSSM_KEY is valid until the key item reference is released. This API is deprecated in 10.7. Its use should no longer be needed.
     @param cssmKey On return, a pointer to a CSSM_KEY structure for the given key. This pointer remains valid until the key reference is released. The caller should not attempt to modify or free this data.
     @result A result code. See "Security Error Codes" (SecBase.h).
     @discussion  The CSSM_KEY is valid until the key item reference is released. This API is deprecated in 10.7. Its use should no longer be needed.
@@ -325,10 +325,10 @@ OSStatus SecKeyGetCredentials(
 
 /*!
     @function SecKeyGetBlockSize
 
 /*!
     @function SecKeyGetBlockSize
-    @abstract Decrypt a block of ciphertext. 
+    @abstract Decrypt a block of ciphertext.
     @param key The key for which the block length is requested.
     @result The block length of the key in bytes.
     @param key The key for which the block length is requested.
     @result The block length of the key in bytes.
-    @discussion If for example key is an RSA key the value returned by 
+    @discussion If for example key is an RSA key the value returned by
     this function is the size of the modulus.
  */
 size_t SecKeyGetBlockSize(SecKeyRef key)
     this function is the size of the modulus.
  */
 size_t SecKeyGetBlockSize(SecKeyRef key)
@@ -337,8 +337,8 @@ size_t SecKeyGetBlockSize(SecKeyRef key)
 /*!
  @function     SecKeyGenerateSymmetric
  @abstract     Generates a random symmetric key with the specified length
 /*!
  @function     SecKeyGenerateSymmetric
  @abstract     Generates a random symmetric key with the specified length
- and algorithm type.  
+ and algorithm type.
+
  @param parameters A dictionary containing one or more key-value pairs.
  See the discussion sections below for a complete overview of options.
  @param error An optional pointer to a CFErrorRef. This value is set
  @param parameters A dictionary containing one or more key-value pairs.
  See the discussion sections below for a complete overview of options.
  @param error An optional pointer to a CFErrorRef. This value is set
@@ -346,16 +346,16 @@ size_t SecKeyGetBlockSize(SecKeyRef key)
  releasing the CFErrorRef.
  @result On return, a SecKeyRef reference to the symmetric key, or
  NULL if the key could not be created.
  releasing the CFErrorRef.
  @result On return, a SecKeyRef reference to the symmetric key, or
  NULL if the key could not be created.
+
  @discussion In order to generate a symmetric key, the parameters dictionary
  must at least contain the following keys:
  @discussion In order to generate a symmetric key, the parameters dictionary
  must at least contain the following keys:
+
  * kSecAttrKeyType with a value of kSecAttrKeyTypeAES or any other
  kSecAttrKeyType defined in SecItem.h
  * kSecAttrKeySizeInBits with a value being a CFNumberRef containing
  the requested key size in bits.  Example sizes for AES keys are:
  128, 192, 256, 512.
  * kSecAttrKeyType with a value of kSecAttrKeyTypeAES or any other
  kSecAttrKeyType defined in SecItem.h
  * kSecAttrKeySizeInBits with a value being a CFNumberRef containing
  the requested key size in bits.  Example sizes for AES keys are:
  128, 192, 256, 512.
+
  To store the generated symmetric key in a keychain, set these keys:
  * kSecUseKeychain (value is a SecKeychainRef)
  * kSecAttrLabel (a user-visible label whose value is a CFStringRef,
  To store the generated symmetric key in a keychain, set these keys:
  * kSecUseKeychain (value is a SecKeychainRef)
  * kSecAttrLabel (a user-visible label whose value is a CFStringRef,
@@ -363,50 +363,50 @@ size_t SecKeyGetBlockSize(SecKeyRef key)
  * kSecAttrApplicationLabel (a label defined by your application, whose
  value is a CFStringRef and which can be used to find this key in a
  subsequent call to SecItemCopyMatching, e.g. "ID-1234567890-9876-0151")
  * kSecAttrApplicationLabel (a label defined by your application, whose
  value is a CFStringRef and which can be used to find this key in a
  subsequent call to SecItemCopyMatching, e.g. "ID-1234567890-9876-0151")
+
  To specify the generated key's access control settings, set this key:
  * kSecAttrAccess (value is a SecAccessRef)
  To specify the generated key's access control settings, set this key:
  * kSecAttrAccess (value is a SecAccessRef)
+
  The keys below may be optionally set in the parameters dictionary
  (with a CFBooleanRef value) to override the default usage values:
  The keys below may be optionally set in the parameters dictionary
  (with a CFBooleanRef value) to override the default usage values:
+
  * kSecAttrCanEncrypt (defaults to true if not explicitly specified)
  * kSecAttrCanDecrypt (defaults to true if not explicitly specified)
  * kSecAttrCanWrap (defaults to true if not explicitly specified)
  * kSecAttrCanUnwrap (defaults to true if not explicitly specified)
  * kSecAttrCanEncrypt (defaults to true if not explicitly specified)
  * kSecAttrCanDecrypt (defaults to true if not explicitly specified)
  * kSecAttrCanWrap (defaults to true if not explicitly specified)
  * kSecAttrCanUnwrap (defaults to true if not explicitly specified)
+
 */
 SecKeyRef SecKeyGenerateSymmetric(CFDictionaryRef parameters, CFErrorRef *error)
 */
 SecKeyRef SecKeyGenerateSymmetric(CFDictionaryRef parameters, CFErrorRef *error)
-       __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); 
-       
+       __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+
 
 /*!
  @function     SecKeyCreateFromData
 
 /*!
  @function     SecKeyCreateFromData
- @abstract     Creates a symmetric key with the given data and sets the 
- algorithm type specified.  
+ @abstract     Creates a symmetric key with the given data and sets the
+ algorithm type specified.
+
  @param parameters A dictionary containing one or more key-value pairs.
  See the discussion sections below for a complete overview of options.
  @result On return, a SecKeyRef reference to the symmetric key.
  @param parameters A dictionary containing one or more key-value pairs.
  See the discussion sections below for a complete overview of options.
  @result On return, a SecKeyRef reference to the symmetric key.
+
  @discussion In order to generate a symmetric key the parameters dictionary must
  at least contain the following keys:
  @discussion In order to generate a symmetric key the parameters dictionary must
  at least contain the following keys:
+
  * kSecAttrKeyType with a value of kSecAttrKeyTypeAES or any other
  kSecAttrKeyType defined in SecItem.h
  * kSecAttrKeyType with a value of kSecAttrKeyTypeAES or any other
  kSecAttrKeyType defined in SecItem.h
+
  The keys below may be optionally set in the parameters dictionary
  (with a CFBooleanRef value) to override the default usage values:
  The keys below may be optionally set in the parameters dictionary
  (with a CFBooleanRef value) to override the default usage values:
+
  * kSecAttrCanEncrypt (defaults to true if not explicitly specified)
  * kSecAttrCanDecrypt (defaults to true if not explicitly specified)
  * kSecAttrCanWrap (defaults to true if not explicitly specified)
  * kSecAttrCanUnwrap (defaults to true if not explicitly specified)
  * kSecAttrCanEncrypt (defaults to true if not explicitly specified)
  * kSecAttrCanDecrypt (defaults to true if not explicitly specified)
  * kSecAttrCanWrap (defaults to true if not explicitly specified)
  * kSecAttrCanUnwrap (defaults to true if not explicitly specified)
+
 */
 SecKeyRef SecKeyCreateFromData(CFDictionaryRef parameters,
        CFDataRef keyData, CFErrorRef *error)
 */
 SecKeyRef SecKeyCreateFromData(CFDictionaryRef parameters,
        CFDataRef keyData, CFErrorRef *error)
-       __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); 
+       __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
 
 
 /*!
 
 
 /*!
@@ -417,20 +417,20 @@ SecKeyRef SecKeyCreateFromData(CFDictionaryRef parameters,
  the result code will be errSecSuccess, and the output parameters will
  contain the public SecKeyRef and private SecKeyRef. It is the caller's
  responsibility to CFRelease these key references when finished with them.
  the result code will be errSecSuccess, and the output parameters will
  contain the public SecKeyRef and private SecKeyRef. It is the caller's
  responsibility to CFRelease these key references when finished with them.
+
  @discussion In order to generate a keypair the parameters dictionary must
  at least contain the following keys:
  @discussion In order to generate a keypair the parameters dictionary must
  at least contain the following keys:
+
  * kSecAttrKeyType with a value of kSecAttrKeyTypeRSA or any other
  kSecAttrKeyType defined in SecItem.h
  * kSecAttrKeySizeInBits with a value being a CFNumberRef containing
  the requested key size in bits.  Example sizes for RSA keys are:
  512, 768, 1024, 2048.
  * kSecAttrKeyType with a value of kSecAttrKeyTypeRSA or any other
  kSecAttrKeyType defined in SecItem.h
  * kSecAttrKeySizeInBits with a value being a CFNumberRef containing
  the requested key size in bits.  Example sizes for RSA keys are:
  512, 768, 1024, 2048.
+
  Setting the following attributes explicitly will override the defaults below.
  See SecItem.h for detailed information on these attributes including the types
  of the values.
  Setting the following attributes explicitly will override the defaults below.
  See SecItem.h for detailed information on these attributes including the types
  of the values.
+
  * kSecAttrLabel default NULL
  * kSecUseKeychain default NULL, which specifies the default keychain
  * kSecAttrApplicationTag default NULL
  * kSecAttrLabel default NULL
  * kSecUseKeychain default NULL, which specifies the default keychain
  * kSecAttrApplicationTag default NULL
@@ -442,7 +442,7 @@ SecKeyRef SecKeyCreateFromData(CFDictionaryRef parameters,
  * kSecAttrCanVerify default false for private keys, true for public keys
  * kSecAttrCanWrap default false for private keys, true for public keys
  * kSecAttrCanUnwrap default true for private keys, false for public keys
  * kSecAttrCanVerify default false for private keys, true for public keys
  * kSecAttrCanWrap default false for private keys, true for public keys
  * kSecAttrCanUnwrap default true for private keys, false for public keys
+
 */
 OSStatus SecKeyGeneratePair(CFDictionaryRef parameters,
        SecKeyRef *publicKey, SecKeyRef *privateKey)
 */
 OSStatus SecKeyGeneratePair(CFDictionaryRef parameters,
        SecKeyRef *publicKey, SecKeyRef *privateKey)
@@ -467,23 +467,23 @@ typedef void (^SecKeyGeneratePairBlock)(SecKeyRef publicKey, SecKeyRef privateKe
  @param deliveryQueue A dispatch queue to be used to deliver the results.
  @param result A callback function to result when the operation has completed.
  @result On success the function returns NULL.
  @param deliveryQueue A dispatch queue to be used to deliver the results.
  @param result A callback function to result when the operation has completed.
  @result On success the function returns NULL.
+
  @discussion In order to generate a keypair the parameters dictionary must
  at least contain the following keys:
  @discussion In order to generate a keypair the parameters dictionary must
  at least contain the following keys:
+
  * kSecAttrKeyType with a value being kSecAttrKeyTypeRSA or any other
  kSecAttrKeyType defined in SecItem.h
  * kSecAttrKeySizeInBits with a value being a CFNumberRef or CFStringRef
  containing the requested key size in bits.  Example sizes for RSA
  keys are: 512, 768, 1024, 2048.
  * kSecAttrKeyType with a value being kSecAttrKeyTypeRSA or any other
  kSecAttrKeyType defined in SecItem.h
  * kSecAttrKeySizeInBits with a value being a CFNumberRef or CFStringRef
  containing the requested key size in bits.  Example sizes for RSA
  keys are: 512, 768, 1024, 2048.
+
  The values below may be set either in the top-level dictionary or in a
  dictionary that is the value of the kSecPrivateKeyAttrs or
  kSecPublicKeyAttrs key in the top-level dictionary.  Setting these
  attributes explicitly will override the defaults below.  See SecItem.h
  for detailed information on these attributes including the types of
  the values.
  The values below may be set either in the top-level dictionary or in a
  dictionary that is the value of the kSecPrivateKeyAttrs or
  kSecPublicKeyAttrs key in the top-level dictionary.  Setting these
  attributes explicitly will override the defaults below.  See SecItem.h
  for detailed information on these attributes including the types of
  the values.
+
  * kSecAttrLabel default NULL
  * kSecAttrIsPermanent if this key is present and has a Boolean
  value of true, the key or key pair will be added to the default
  * kSecAttrLabel default NULL
  * kSecAttrIsPermanent if this key is present and has a Boolean
  value of true, the key or key pair will be added to the default
@@ -497,11 +497,11 @@ typedef void (^SecKeyGeneratePairBlock)(SecKeyRef publicKey, SecKeyRef privateKe
  * kSecAttrCanVerify default false for private keys, true for public keys
  * kSecAttrCanWrap default false for private keys, true for public keys
  * kSecAttrCanUnwrap default true for private keys, false for public keys
  * kSecAttrCanVerify default false for private keys, true for public keys
  * kSecAttrCanWrap default false for private keys, true for public keys
  * kSecAttrCanUnwrap default true for private keys, false for public keys
+
 */
 void SecKeyGeneratePairAsync(CFDictionaryRef parameters,
        dispatch_queue_t deliveryQueue, SecKeyGeneratePairBlock result)
 */
 void SecKeyGeneratePairAsync(CFDictionaryRef parameters,
        dispatch_queue_t deliveryQueue, SecKeyGeneratePairBlock result)
-       __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);      
+       __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
 
 #endif /* __BLOCKS__ */
 
 
 #endif /* __BLOCKS__ */
 
@@ -510,51 +510,51 @@ void SecKeyGeneratePairAsync(CFDictionaryRef parameters,
 /*!
  @function SecKeyDeriveFromPassword
  @abstract Derives a symmetric key from a password.
 /*!
  @function SecKeyDeriveFromPassword
  @abstract Derives a symmetric key from a password.
+
  @param password The password from which the keyis to be derived.
  @param parameters A dictionary containing one or more key-value pairs.
  @param error If the call fails this will contain the error code.
  @param password The password from which the keyis to be derived.
  @param parameters A dictionary containing one or more key-value pairs.
  @param error If the call fails this will contain the error code.
+
  @discussion In order to derive a key the parameters dictionary must contain at least contain the following keys:
  * kSecAttrSalt        - a CFData for the salt value for mixing in the pseudo-random rounds.
  * kSecAttrPRF - the algorithm to use for the pseudo-random-function.
    If 0, this defaults to kSecAttrPRFHmacAlgSHA1. Possible values are:
  @discussion In order to derive a key the parameters dictionary must contain at least contain the following keys:
  * kSecAttrSalt        - a CFData for the salt value for mixing in the pseudo-random rounds.
  * kSecAttrPRF - the algorithm to use for the pseudo-random-function.
    If 0, this defaults to kSecAttrPRFHmacAlgSHA1. Possible values are:
+
  * kSecAttrPRFHmacAlgSHA1
  * kSecAttrPRFHmacAlgSHA224
  * kSecAttrPRFHmacAlgSHA256
  * kSecAttrPRFHmacAlgSHA384
  * kSecAttrPRFHmacAlgSHA512
  * kSecAttrPRFHmacAlgSHA1
  * kSecAttrPRFHmacAlgSHA224
  * kSecAttrPRFHmacAlgSHA256
  * kSecAttrPRFHmacAlgSHA384
  * kSecAttrPRFHmacAlgSHA512
-  
+
  * kSecAttrRounds - the number of rounds to call the pseudo random function.
    If 0, a count will be computed to average 1/10 of a second.
  * kSecAttrKeySizeInBits with a value being a CFNumberRef
    containing the requested key size in bits.  Example sizes for RSA keys are:
    512, 768, 1024, 2048.
  * kSecAttrRounds - the number of rounds to call the pseudo random function.
    If 0, a count will be computed to average 1/10 of a second.
  * kSecAttrKeySizeInBits with a value being a CFNumberRef
    containing the requested key size in bits.  Example sizes for RSA keys are:
    512, 768, 1024, 2048.
-  
+
  @result On success a SecKeyRef is returned.  On failure this result is NULL and the
  error parameter contains the reason.
  @result On success a SecKeyRef is returned.  On failure this result is NULL and the
  error parameter contains the reason.
+
 */
 SecKeyRef SecKeyDeriveFromPassword(CFStringRef password,
        CFDictionaryRef parameters, CFErrorRef *error)
 */
 SecKeyRef SecKeyDeriveFromPassword(CFStringRef password,
        CFDictionaryRef parameters, CFErrorRef *error)
-       __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); 
+       __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
 
 /*!
  @function SecKeyWrapSymmetric
  @abstract Wraps a symmetric key with a symmetric key.
 
 /*!
  @function SecKeyWrapSymmetric
  @abstract Wraps a symmetric key with a symmetric key.
+
  @param keyToWrap The key which is to be wrapped.
  @param wrappingKey The key wrapping key.
  #param parameters The parameter list to use for wrapping the key.
  @param error If the call fails this will contain the error code.
  @param keyToWrap The key which is to be wrapped.
  @param wrappingKey The key wrapping key.
  #param parameters The parameter list to use for wrapping the key.
  @param error If the call fails this will contain the error code.
+
  @result On success a CFDataRef is returned.  On failure this result is NULL and the
  error parameter contains the reason.
  @result On success a CFDataRef is returned.  On failure this result is NULL and the
  error parameter contains the reason.
+
  @discussion In order to wrap a key the parameters dictionary may contain the following key:
  * kSecSalt    - a CFData for the salt value for the encrypt.
  @discussion In order to wrap a key the parameters dictionary may contain the following key:
  * kSecSalt    - a CFData for the salt value for the encrypt.
+
 */
 CFDataRef SecKeyWrapSymmetric(SecKeyRef keyToWrap,
        SecKeyRef wrappingKey, CFDictionaryRef parameters, CFErrorRef *error)
 */
 CFDataRef SecKeyWrapSymmetric(SecKeyRef keyToWrap,
        SecKeyRef wrappingKey, CFDictionaryRef parameters, CFErrorRef *error)
@@ -563,18 +563,18 @@ CFDataRef SecKeyWrapSymmetric(SecKeyRef keyToWrap,
 /*!
  @function SecKeyUnwrapSymmetric
  @abstract Unwrap a wrapped symmetric key.
 /*!
  @function SecKeyUnwrapSymmetric
  @abstract Unwrap a wrapped symmetric key.
+
  @param keyToUnwrap The wrapped key to unwrap.
  @param unwrappingKey The key unwrapping key.
  #param parameters The parameter list to use for unwrapping the key.
  @param error If the call fails this will contain the error code.
  @param keyToUnwrap The wrapped key to unwrap.
  @param unwrappingKey The key unwrapping key.
  #param parameters The parameter list to use for unwrapping the key.
  @param error If the call fails this will contain the error code.
+
  @result On success a SecKeyRef is returned.  On failure this result is NULL and the
  error parameter contains the reason.
  @result On success a SecKeyRef is returned.  On failure this result is NULL and the
  error parameter contains the reason.
+
  @discussion In order to unwrap a key the parameters dictionary may contain the following key:
  * kSecSalt    - a CFData for the salt value for the decrypt.
  @discussion In order to unwrap a key the parameters dictionary may contain the following key:
  * kSecSalt    - a CFData for the salt value for the decrypt.
+
 */
 SecKeyRef SecKeyUnwrapSymmetric(CFDataRef *keyToUnwrap,
        SecKeyRef unwrappingKey, CFDictionaryRef parameters, CFErrorRef *error)
 */
 SecKeyRef SecKeyUnwrapSymmetric(CFDataRef *keyToUnwrap,
        SecKeyRef unwrappingKey, CFDictionaryRef parameters, CFErrorRef *error)
index 4e20e195c8c8d0d0abbd3ee063225eb0f7fa8280..f65a90af9e384d40e8cbb5219779e1acc7e12791 100644 (file)
 extern "C" {
 #endif
 
 extern "C" {
 #endif
 
+typedef struct SecRSAPublicKeyParams {
+    uint8_t             *modulus;                      /* modulus */
+    CFIndex             modulusLength;
+    uint8_t             *exponent;                     /* public exponent */
+    CFIndex             exponentLength;
+} SecRSAPublicKeyParams;
+
 typedef uint32_t SecKeyEncoding;
 enum {
     /* Typically only used for symmetric keys. */
 typedef uint32_t SecKeyEncoding;
 enum {
     /* Typically only used for symmetric keys. */
@@ -397,6 +404,39 @@ SecKeyRef SecKeyCreateRSAPublicKey(CFAllocatorRef allocator,
 CFDataRef SecKeyCopyModulus(SecKeyRef rsaPublicKey);
 CFDataRef SecKeyCopyExponent(SecKeyRef rsaPublicKey);
 
 CFDataRef SecKeyCopyModulus(SecKeyRef rsaPublicKey);
 CFDataRef SecKeyCopyExponent(SecKeyRef rsaPublicKey);
 
+/*!
+ @function SecKeyCopyPublicBytes
+ @abstract Gets the bits of a public key
+ @param key Key to retrieve the bits.
+ @param publicBytes An out parameter to receive the public key bits
+ @result Errors if any when retrieving the public key bits..
+ */
+OSStatus SecKeyCopyPublicBytes(SecKeyRef key, CFDataRef* publicBytes);
+
+/*!
+       @function SecKeyCreatePublicFromPrivate
+       @abstract Create a public SecKeyRef from a private SecKeyRef
+       @param privateKey The private SecKeyRef for which you want the public key
+       @result A public SecKeyRef, or NULL if the conversion failed
+       @discussion This is a "best attempt" function, hence the SPI nature. If the public
+    key bits are not in memory, it attempts to load from the keychain. If the public
+    key was not tracked on the keychain, it will fail.
+*/
+SecKeyRef SecKeyCreatePublicFromPrivate(SecKeyRef privateKey);
+
+/*!
+       @function SecKeyCreateFromPublicData
+*/
+SecKeyRef SecKeyCreateFromPublicData(CFAllocatorRef allocator, CFIndex algorithmID, CFDataRef publicBytes);
+
+OSStatus SecKeyRawVerifyOSX(
+                SecKeyRef           key,
+                SecPadding          padding,
+                const uint8_t       *signedData,
+                size_t              signedDataLen,
+                const uint8_t       *sig,
+                size_t              sigLen);
+    
 #if defined(__cplusplus)
 }
 #endif
 #if defined(__cplusplus)
 }
 #endif
index 473bc16bc00822e8f9271fab6f3c98a6e1eceb33..ceaffd81a6cab5203525d6ba657475a9f6409690 100644 (file)
@@ -47,10 +47,10 @@ OSStatus
 SecKeychainGetVersion(UInt32 *returnVers)
 {
     if (!returnVers)
 SecKeychainGetVersion(UInt32 *returnVers)
 {
     if (!returnVers)
-               return noErr;
+               return errSecSuccess;
 
        *returnVers = 0x02028000;
 
        *returnVers = 0x02028000;
-       return noErr;
+       return errSecSuccess;
 }
 
 
 }
 
 
@@ -92,8 +92,8 @@ SecKeychainCreate(const char *pathName, UInt32 passwordLength, const void *passw
        Boolean promptUser, SecAccessRef initialAccess, SecKeychainRef *keychainRef)
 {
     BEGIN_SECAPI
        Boolean promptUser, SecAccessRef initialAccess, SecKeychainRef *keychainRef)
 {
     BEGIN_SECAPI
-
-       KCThrowParamErrIf_(!pathName);
+    
+    KCThrowParamErrIf_(!pathName);
        Keychain keychain = globals().storageManager.make(pathName);
 
        // @@@ the call to StorageManager::make above leaves keychain the the cache.
        Keychain keychain = globals().storageManager.make(pathName);
 
        // @@@ the call to StorageManager::make above leaves keychain the the cache.
@@ -229,7 +229,7 @@ OSStatus SecKeychainResetLogin(UInt32 passwordLength, const void* password, Bool
                        globals().storageManager.resetKeychain(resetSearchList);
 
                        // Create the login keychain without UI
                        globals().storageManager.resetKeychain(resetSearchList);
 
                        // Create the login keychain without UI
-                       globals().storageManager.login(userName.length(), userName.c_str(), passwordLength, password);
+                       globals().storageManager.login((UInt32)userName.length(), userName.c_str(), passwordLength, password);
                        
                        // Set it as the default
                        Keychain keychain = globals().storageManager.loginKeychain();
                        
                        // Set it as the default
                        Keychain keychain = globals().storageManager.loginKeychain();
@@ -242,6 +242,8 @@ OSStatus SecKeychainResetLogin(UInt32 passwordLength, const void* password, Bool
                        globals().storageManager.makeLoginAuthUI(NULL);
                }
 
                        globals().storageManager.makeLoginAuthUI(NULL);
                }
 
+        SecurityServer::ClientSession().resetKeyStorePassphrase(password ? CssmData(const_cast<void *>(password), passwordLength) : CssmData());
+
                // Post a "list changed" event after a reset, so apps can refresh their list.
                // Make sure we are not holding mLock when we post this event.
                KCEventNotifier::PostKeychainEvent(kSecKeychainListChangedEvent);
                // Post a "list changed" event after a reset, so apps can refresh their list.
                // Make sure we are not holding mLock when we post this event.
                KCEventNotifier::PostKeychainEvent(kSecKeychainListChangedEvent);
@@ -379,7 +381,7 @@ SecKeychainGetPath(SecKeychainRef keychainRef, UInt32 *ioPathLength, char *pathN
        RequiredParam(ioPathLength);
 
     const char *name = Keychain::optional(keychainRef)->name();
        RequiredParam(ioPathLength);
 
     const char *name = Keychain::optional(keychainRef)->name();
-       UInt32 nameLen = strlen(name);
+       UInt32 nameLen = (UInt32)strlen(name);
        UInt32 callersLen = *ioPathLength;
        *ioPathLength = nameLen;
        if (nameLen+1 > callersLen)  // if the client's buffer is too small (including null-termination), throw
        UInt32 callersLen = *ioPathLength;
        *ioPathLength = nameLen;
        if (nameLen+1 > callersLen)  // if the client's buffer is too small (including null-termination), throw
@@ -598,7 +600,7 @@ SecKeychainFindInternetPassword(CFTypeRef keychainOrArray, UInt32 serverNameLeng
        {
                CssmDataContainer outData;
                item->getData(outData);
        {
                CssmDataContainer outData;
                item->getData(outData);
-               *passwordLength=outData.length();
+               *passwordLength=(UInt32)outData.length();
                outData.Length=0;
                *passwordData=outData.data();
                outData.Data=NULL;
                outData.Length=0;
                *passwordData=outData.data();
                outData.Data=NULL;
@@ -697,7 +699,7 @@ SecKeychainFindGenericPassword(CFTypeRef keychainOrArray, UInt32 serviceNameLeng
        {
                CssmDataContainer outData;
                item->getData(outData);
        {
                CssmDataContainer outData;
                item->getData(outData);
-               *passwordLength=outData.length();
+               *passwordLength=(UInt32)outData.length();
                outData.Length=0;
                *passwordData=outData.data();
                outData.Data=NULL;
                outData.Length=0;
                *passwordData=outData.data();
                outData.Data=NULL;
@@ -765,7 +767,7 @@ SecKeychainCopyAccess(SecKeychainRef keychainRef, SecAccessRef *accessRef)
 {
        BEGIN_SECAPI
 
 {
        BEGIN_SECAPI
 
-       MacOSError::throwMe(unimpErr);//%%%for now
+       MacOSError::throwMe(errSecUnimplemented);//%%%for now
 
        END_SECAPI
 }
 
        END_SECAPI
 }
@@ -776,7 +778,7 @@ SecKeychainSetAccess(SecKeychainRef keychainRef, SecAccessRef accessRef)
 {
        BEGIN_SECAPI
 
 {
        BEGIN_SECAPI
 
-       MacOSError::throwMe(unimpErr);//%%%for now
+       MacOSError::throwMe(errSecUnimplemented);//%%%for now
 
        END_SECAPI
 }
 
        END_SECAPI
 }
@@ -815,7 +817,11 @@ SecKeychainLogin(UInt32 nameLength, const void* name, UInt32 passwordLength, con
 
        try
        {
 
        try
        {
-               globals().storageManager.login(nameLength, name,  passwordLength, password);
+               if (password) {
+            globals().storageManager.login(nameLength, name,  passwordLength, password);
+        } else {
+            globals().storageManager.stashLogin();
+        }
        }
        catch (CommonError &e)
        {
        }
        catch (CommonError &e)
        {
@@ -832,6 +838,28 @@ SecKeychainLogin(UInt32 nameLength, const void* name, UInt32 passwordLength, con
     END_SECAPI
 }
 
     END_SECAPI
 }
 
+OSStatus SecKeychainStash()
+{
+    BEGIN_SECAPI
+    
+       try
+       {
+               globals().storageManager.stashKeychain();
+       }
+       catch (CommonError &e)
+       {
+               if (e.osStatus() == CSSMERR_DL_OPERATION_AUTH_DENIED)
+               {
+                       return errSecAuthFailed;
+               }
+               else
+               {
+                       return e.osStatus();
+               }
+       }
+       
+    END_SECAPI
+}
 
 OSStatus
 SecKeychainLogout()
 
 OSStatus
 SecKeychainLogout()
@@ -912,7 +940,7 @@ OSStatus SecKeychainRecodeKeychain(SecKeychainRef keychainRef, CFArrayRef dbBlob
        size_t space = sizeof(uint8) + (dbBlobArrayCount * sizeof(SecurityServer::DbHandle));
        void *dataPtr = (void*)malloc(space);
        if ( !dataPtr )
        size_t space = sizeof(uint8) + (dbBlobArrayCount * sizeof(SecurityServer::DbHandle));
        void *dataPtr = (void*)malloc(space);
        if ( !dataPtr )
-               return memFullErr;
+               return errSecAllocate;
        //
        // Get a DbHandle(IPCDbHandle) from securityd for each blob in the array that we'll authenticate with.
        //
        //
        // Get a DbHandle(IPCDbHandle) from securityd for each blob in the array that we'll authenticate with.
        //
@@ -939,7 +967,7 @@ OSStatus SecKeychainRecodeKeychain(SecKeychainRef keychainRef, CFArrayRef dbBlob
        const CssmData data(const_cast<UInt8 *>((uint8*)dataPtr), space);
        Boolean recodeFailed = false;
        
        const CssmData data(const_cast<UInt8 *>((uint8*)dataPtr), space);
        Boolean recodeFailed = false;
        
-       int errCode=noErr;
+       int errCode=errSecSuccess;
        
        try
     {
        
        try
     {
@@ -1098,3 +1126,16 @@ OSStatus SecKeychainCleanupHandles()
        END_SECAPI // which causes the handle cache cleanup routine to run
 }
 
        END_SECAPI // which causes the handle cache cleanup routine to run
 }
 
+OSStatus SecKeychainVerifyKeyStorePassphrase(uint32_t retries)
+{
+    BEGIN_SECAPI
+    SecurityServer::ClientSession().verifyKeyStorePassphrase(retries);
+    END_SECAPI
+}
+
+OSStatus SecKeychainChangeKeyStorePassphrase()
+{
+    BEGIN_SECAPI
+    SecurityServer::ClientSession().changeKeyStorePassphrase();
+    END_SECAPI
+}
\ No newline at end of file
index eebfc21fa18876cb147615195e92733d26efa399..992cce8e0a13bfa6b7d2364c56da55471a933ee0 100644 (file)
@@ -303,7 +303,7 @@ OSStatus SecKeychainGetVersion(UInt32 *returnVers);
        of this keychain.
        @param pathName The POSIX path to a keychain.
     @param keychain On return, a pointer to the keychain reference. The memory that keychain occupies must be released by calling CFRelease when finished with it.
        of this keychain.
        @param pathName The POSIX path to a keychain.
     @param keychain On return, a pointer to the keychain reference. The memory that keychain occupies must be released by calling CFRelease when finished with it.
-       @result A result code.  See "Security Error Codes" (SecBase.h). In addition, paramErr (-50) may be returned if the keychain parameter is invalid (NULL).
+       @result A result code.  See "Security Error Codes" (SecBase.h). In addition, errSecParam (-50) may be returned if the keychain parameter is invalid (NULL).
 */
 OSStatus SecKeychainOpen(const char *pathName, SecKeychainRef *keychain);
 
 */
 OSStatus SecKeychainOpen(const char *pathName, SecKeychainRef *keychain);
 
@@ -316,7 +316,7 @@ OSStatus SecKeychainOpen(const char *pathName, SecKeychainRef *keychain);
        @param promptUser A boolean representing whether to display a password dialog to the user.
        @param initialAccess An access reference.
     @param keychain On return, a pointer to a keychain reference. The memory that keychain occupies must be released by calling CFRelease when finished with it.
        @param promptUser A boolean representing whether to display a password dialog to the user.
        @param initialAccess An access reference.
     @param keychain On return, a pointer to a keychain reference. The memory that keychain occupies must be released by calling CFRelease when finished with it.
-       @result A result code.  See "Security Error Codes" (SecBase.h). In addition, paramErr (-50) may be returned if the keychain parameter is invalid (NULL).
+       @result A result code.  See "Security Error Codes" (SecBase.h). In addition, errSecParam (-50) may be returned if the keychain parameter is invalid (NULL).
 */
 OSStatus SecKeychainCreate(const char *pathName, UInt32 passwordLength, const void *password, Boolean promptUser, SecAccessRef initialAccess, SecKeychainRef *keychain);
 
 */
 OSStatus SecKeychainCreate(const char *pathName, UInt32 passwordLength, const void *password, Boolean promptUser, SecAccessRef initialAccess, SecKeychainRef *keychain);
 
@@ -349,7 +349,7 @@ OSStatus SecKeychainCopySettings(SecKeychainRef keychain, SecKeychainSettings *o
 /*!
        @function SecKeychainUnlock
        @abstract Unlocks the specified keychain.
 /*!
        @function SecKeychainUnlock
        @abstract Unlocks the specified keychain.
-    @param keychain A reference to the keychain to unlock. Pass NULL to specify the default keychain. If you pass NULL and the default keychain is currently locked, the keychain will appear as the default choice. If you pass a locked keychain, SecKeychainUnlock will use the password provided to unlock it. If the default keychain is currently unlocked, SecKeychainUnlock returns noErr
+    @param keychain A reference to the keychain to unlock. Pass NULL to specify the default keychain. If you pass NULL and the default keychain is currently locked, the keychain will appear as the default choice. If you pass a locked keychain, SecKeychainUnlock will use the password provided to unlock it. If the default keychain is currently unlocked, SecKeychainUnlock returns errSecSuccess
        @param passwordLength An unsigned 32-bit integer representing the length of the password buffer.
        @param password A buffer containing the password for the keychain. Pass NULL if the user password is unknown. In this case, SecKeychainUnlock displays the Unlock Keychain dialog box, and the authentication user interface associated with the keychain about to be unlocked.
        @param usePassword A boolean indicating whether the password parameter is used.  You should pass TRUE if it is used or FALSE if it is ignored.
        @param passwordLength An unsigned 32-bit integer representing the length of the password buffer.
        @param password A buffer containing the password for the keychain. Pass NULL if the user password is unknown. In this case, SecKeychainUnlock displays the Unlock Keychain dialog box, and the authentication user interface associated with the keychain about to be unlocked.
        @param usePassword A boolean indicating whether the password parameter is used.  You should pass TRUE if it is used or FALSE if it is ignored.
@@ -385,7 +385,7 @@ OSStatus SecKeychainCopyDefault(SecKeychainRef *keychain);
        @function SecKeychainSetDefault
        @abstract Sets the default keychain. 
        @param keychain A reference to the keychain to set as default.
        @function SecKeychainSetDefault
        @abstract Sets the default keychain. 
        @param keychain A reference to the keychain to set as default.
-       @result A result code.  See "Security Error Codes" (SecBase.h). In addition, paramErr (-50) may be returned if the keychain parameter is invalid (NULL).
+       @result A result code.  See "Security Error Codes" (SecBase.h). In addition, errSecParam (-50) may be returned if the keychain parameter is invalid (NULL).
 */
 OSStatus SecKeychainSetDefault(SecKeychainRef keychain);
 
 */
 OSStatus SecKeychainSetDefault(SecKeychainRef keychain);
 
@@ -393,7 +393,7 @@ OSStatus SecKeychainSetDefault(SecKeychainRef keychain);
        @function SecKeychainCopySearchList
        @abstract Retrieves a keychain search list.
        @param searchList The returned list of keychains to search. When finished with the array, you must call CFRelease() to release the memory.
        @function SecKeychainCopySearchList
        @abstract Retrieves a keychain search list.
        @param searchList The returned list of keychains to search. When finished with the array, you must call CFRelease() to release the memory.
-       @result A result code.  See "Security Error Codes" (SecBase.h). In addition, paramErr (-50) may be returned if the keychain list is not specified (NULL).
+       @result A result code.  See "Security Error Codes" (SecBase.h). In addition, errSecParam (-50) may be returned if the keychain list is not specified (NULL).
 */
 OSStatus SecKeychainCopySearchList(CFArrayRef *searchList);
 
 */
 OSStatus SecKeychainCopySearchList(CFArrayRef *searchList);
 
@@ -401,7 +401,7 @@ OSStatus SecKeychainCopySearchList(CFArrayRef *searchList);
        @function SecKeychainSetSearchList
        @abstract Specifies the list of keychains to use in a keychain search list.
        @param searchList The list of keychains to use in a search list when the SecKeychainCopySearchList function is called. An empty array clears the search list.
        @function SecKeychainSetSearchList
        @abstract Specifies the list of keychains to use in a keychain search list.
        @param searchList The list of keychains to use in a search list when the SecKeychainCopySearchList function is called. An empty array clears the search list.
-       @result A result code.  See "Security Error Codes" (SecBase.h). In addition, paramErr (-50) may be returned if the keychain list is not specified (NULL).
+       @result A result code.  See "Security Error Codes" (SecBase.h). In addition, errSecParam (-50) may be returned if the keychain list is not specified (NULL).
 */
 OSStatus SecKeychainSetSearchList(CFArrayRef searchList);
 
 */
 OSStatus SecKeychainSetSearchList(CFArrayRef searchList);
 
@@ -451,7 +451,7 @@ OSStatus SecKeychainGetPath(SecKeychainRef keychain, UInt32 *ioPathLength, char
     @param keychain A keychain reference.
        @param itemID The relation identifier of the item tags (an itemID is a CSSM_DB_RECORDTYPE defined in cssmtype.h).
        @param info On return, a pointer to the keychain attribute information. User should call the SecKeychainFreeAttributeInfo function to release the structure when done with it. 
     @param keychain A keychain reference.
        @param itemID The relation identifier of the item tags (an itemID is a CSSM_DB_RECORDTYPE defined in cssmtype.h).
        @param info On return, a pointer to the keychain attribute information. User should call the SecKeychainFreeAttributeInfo function to release the structure when done with it. 
-    @result A result code.  See "Security Error Codes" (SecBase.h). In addition, paramErr (-50) may be returned if not enough valid parameters were supplied (NULL).
+    @result A result code.  See "Security Error Codes" (SecBase.h). In addition, errSecParam (-50) may be returned if not enough valid parameters were supplied (NULL).
        @discussion Warning, this call returns more attributes than are support by the old style Keychain API and passing them into older calls will yield an invalid attribute error. The recommended call to retrieve the attribute values is the SecKeychainItemCopyAttributesAndData function.
 */
 OSStatus SecKeychainAttributeInfoForItemID(SecKeychainRef keychain,  UInt32 itemID, SecKeychainAttributeInfo **info);
        @discussion Warning, this call returns more attributes than are support by the old style Keychain API and passing them into older calls will yield an invalid attribute error. The recommended call to retrieve the attribute values is the SecKeychainItemCopyAttributesAndData function.
 */
 OSStatus SecKeychainAttributeInfoForItemID(SecKeychainRef keychain,  UInt32 itemID, SecKeychainAttributeInfo **info);
@@ -460,7 +460,7 @@ OSStatus SecKeychainAttributeInfoForItemID(SecKeychainRef keychain,  UInt32 item
        @function SecKeychainFreeAttributeInfo
        @abstract Releases the memory acquired by calling the SecKeychainAttributeInfoForItemID function.
        @param info A pointer to the keychain attribute information to release.
        @function SecKeychainFreeAttributeInfo
        @abstract Releases the memory acquired by calling the SecKeychainAttributeInfoForItemID function.
        @param info A pointer to the keychain attribute information to release.
-    @result A result code.  See "Security Error Codes" (SecBase.h). In addition, paramErr (-50) may be returned if not enough valid parameters were supplied (NULL).
+    @result A result code.  See "Security Error Codes" (SecBase.h). In addition, errSecParam (-50) may be returned if not enough valid parameters were supplied (NULL).
 */
 OSStatus SecKeychainFreeAttributeInfo(SecKeychainAttributeInfo *info);
 
 */
 OSStatus SecKeychainFreeAttributeInfo(SecKeychainAttributeInfo *info);
 
index 62a4b06709a49dda15b62e6ed71df9e03055b961..9b0633b836727833a29b7276fa5f205ff1bf8ab2 100644 (file)
@@ -75,7 +75,7 @@ OSStatus SecKeychainAddIToolsPassword(SecKeychainRef keychain, UInt32 accountNam
                                        for (CFIndex n = 0; n < size; n++) {
                                                CFStringRef path = (CFStringRef)CFArrayGetValueAtIndex(list, n);
                                                CFRef<SecTrustedApplicationRef> app;
                                        for (CFIndex n = 0; n < size; n++) {
                                                CFStringRef path = (CFStringRef)CFArrayGetValueAtIndex(list, n);
                                                CFRef<SecTrustedApplicationRef> app;
-                                               if (SecTrustedApplicationCreateFromPath(cfString(path).c_str(), &app.aref()) == noErr)
+                                               if (SecTrustedApplicationCreateFromPath(cfString(path).c_str(), &app.aref()) == errSecSuccess)
                                                        CFArrayAppendValue(apps, app);
                                        }
                                }
                                                        CFArrayAppendValue(apps, app);
                                        }
                                }
@@ -89,7 +89,7 @@ OSStatus SecKeychainAddIToolsPassword(SecKeychainRef keychain, UInt32 accountNam
        SecKeychainAttribute attrs[] = {
                { kSecLabelItemAttr, accountNameLength, (char *)accountName },  // use the account name as the label for display purposes [3787371]
                { kSecAccountItemAttr, accountNameLength, (char *)accountName },
        SecKeychainAttribute attrs[] = {
                { kSecLabelItemAttr, accountNameLength, (char *)accountName },  // use the account name as the label for display purposes [3787371]
                { kSecAccountItemAttr, accountNameLength, (char *)accountName },
-               { kSecServiceItemAttr, strlen(serviceUTF8), (char *)serviceUTF8 }
+               { kSecServiceItemAttr, (UInt32)strlen(serviceUTF8), (char *)serviceUTF8 }
        };
        SecKeychainAttributeList attributes = { sizeof(attrs) / sizeof(attrs[0]), attrs };
 
        };
        SecKeychainAttributeList attributes = { sizeof(attrs) / sizeof(attrs[0]), attrs };
 
index 7865067ba9bd9f908d04196cb1cb9c1dce71513e..1056f16a0f2a236d41c5696c7d7536092e948058 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2000-2004,2012-2013 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
+#include <Security/SecBase.h>
 #include <Security/SecKeychainItem.h>
 #include <Security/SecKeychainItemPriv.h>
 
 #include <security_keychain/Keychains.h>
 #include <security_keychain/KeyItem.h>
 #include <security_keychain/Item.h>
 #include <Security/SecKeychainItem.h>
 #include <Security/SecKeychainItemPriv.h>
 
 #include <security_keychain/Keychains.h>
 #include <security_keychain/KeyItem.h>
 #include <security_keychain/Item.h>
+#include <security_keychain/Certificate.h>
+#include <security_keychain/Identity.h>
 #include <security_keychain/KCCursor.h> // @@@ Remove this when SecKeychainItemFindFirst moves to SecKeychainSearch
 
 #include <securityd_client/dictionary.h>
 #include <security_keychain/KCCursor.h> // @@@ Remove this when SecKeychainItemFindFirst moves to SecKeychainSearch
 
 #include <securityd_client/dictionary.h>
@@ -44,6 +47,7 @@
 // Note: Login ACLs are not hooked into this layer;
 // modules or attachments have no Sec* layer representation.
 //
 // Note: Login ACLs are not hooked into this layer;
 // modules or attachments have no Sec* layer representation.
 //
+static
 RefPointer<AclBearer> aclBearer(CFTypeRef itemRef)
 {
        // well, exactly what kind of something are you?
 RefPointer<AclBearer> aclBearer(CFTypeRef itemRef)
 {
        // well, exactly what kind of something are you?
@@ -174,14 +178,14 @@ SecKeychainItemDelete(SecKeychainItemRef itemRef)
                Keychain keychain = item->keychain();
                // item must be persistent.
                KCThrowIf_( !keychain, errSecInvalidItemRef );
                Keychain keychain = item->keychain();
                // item must be persistent.
                KCThrowIf_( !keychain, errSecInvalidItemRef );
-               
+
                /*
                 * Before deleting the item, delete any existing Extended Attributes.
                 */
                OSStatus ortn;
                CFArrayRef attrNames = NULL;
                ortn = SecKeychainItemCopyAllExtendedAttributes(itemRef, &attrNames, NULL);
                /*
                 * Before deleting the item, delete any existing Extended Attributes.
                 */
                OSStatus ortn;
                CFArrayRef attrNames = NULL;
                ortn = SecKeychainItemCopyAllExtendedAttributes(itemRef, &attrNames, NULL);
-               if(ortn == noErr) {
+               if(ortn == errSecSuccess) {
                        CFIndex numAttrs = CFArrayGetCount(attrNames);
                        for(CFIndex dex=0; dex<numAttrs; dex++) {
                                CFStringRef attrName = (CFStringRef)CFArrayGetValueAtIndex(attrNames, dex);
                        CFIndex numAttrs = CFArrayGetCount(attrNames);
                        for(CFIndex dex=0; dex<numAttrs; dex++) {
                                CFStringRef attrName = (CFStringRef)CFArrayGetValueAtIndex(attrNames, dex);
@@ -189,9 +193,9 @@ SecKeychainItemDelete(SecKeychainItemRef itemRef)
                                SecKeychainItemSetExtendedAttribute(itemRef, attrName, NULL);
                        }
                }
                                SecKeychainItemSetExtendedAttribute(itemRef, attrName, NULL);
                        }
                }
-               
+
                /* now delete the item */
                /* now delete the item */
-        keychain->deleteItem( item ); 
+        keychain->deleteItem( item );
        END_SECAPI
 }
 
        END_SECAPI
 }
 
@@ -206,7 +210,7 @@ SecKeychainItemCopyKeychain(SecKeychainItemRef itemRef, SecKeychainRef* keychain
                {
                        MacOSError::throwMe(errSecNoSuchKeychain);
                }
                {
                        MacOSError::throwMe(errSecNoSuchKeychain);
                }
-               
+
                Required(keychainRef) = kc->handle();
        END_SECAPI
 }
                Required(keychainRef) = kc->handle();
        END_SECAPI
 }
@@ -241,7 +245,8 @@ SecKeychainItemGetDLDBHandle(SecKeychainItemRef itemRef, CSSM_DL_DB_HANDLE* dldb
        END_SECAPI
 }
 
        END_SECAPI
 }
 
-
+#if 0
+static
 OSStatus SecAccessCreateFromObject(CFTypeRef sourceRef,
        SecAccessRef *accessRef)
 {
 OSStatus SecAccessCreateFromObject(CFTypeRef sourceRef,
        SecAccessRef *accessRef)
 {
@@ -255,12 +260,14 @@ OSStatus SecAccessCreateFromObject(CFTypeRef sourceRef,
 
 /*!
  */
 
 /*!
  */
+static
 OSStatus SecAccessModifyObject(SecAccessRef accessRef, CFTypeRef sourceRef)
 {
        BEGIN_SECAPI
        Access::required(accessRef)->setAccess(*aclBearer(sourceRef), true);
        END_SECAPI
 }
 OSStatus SecAccessModifyObject(SecAccessRef accessRef, CFTypeRef sourceRef)
 {
        BEGIN_SECAPI
        Access::required(accessRef)->setAccess(*aclBearer(sourceRef), true);
        END_SECAPI
 }
+#endif
 
 OSStatus
 SecKeychainItemCopyAccess(SecKeychainItemRef itemRef, SecAccessRef* accessRef)
 
 OSStatus
 SecKeychainItemCopyAccess(SecKeychainItemRef itemRef, SecAccessRef* accessRef)
@@ -283,12 +290,12 @@ SecKeychainItemSetAccess(SecKeychainItemRef itemRef, SecAccessRef accessRef)
        Access::required(accessRef)->setAccess(*aclBearer(reinterpret_cast<CFTypeRef>(itemRef)), true);
 
        ItemImpl::required(itemRef)->postItemEvent (kSecUpdateEvent);
        Access::required(accessRef)->setAccess(*aclBearer(reinterpret_cast<CFTypeRef>(itemRef)), true);
 
        ItemImpl::required(itemRef)->postItemEvent (kSecUpdateEvent);
-       
+
     END_SECAPI
 }
 
 /*  Sets an item's data for legacy "KC" CoreServices APIs.
     END_SECAPI
 }
 
 /*  Sets an item's data for legacy "KC" CoreServices APIs.
-    Note this version sets the data, but doesn't update the item 
+    Note this version sets the data, but doesn't update the item
     as the KC behavior dictates.
 */
 OSStatus SecKeychainItemSetData(SecKeychainItemRef itemRef, UInt32 length, const void* data)
     as the KC behavior dictates.
 */
 OSStatus SecKeychainItemSetData(SecKeychainItemRef itemRef, UInt32 length, const void* data)
@@ -306,18 +313,18 @@ OSStatus SecKeychainItemGetData(SecKeychainItemRef itemRef, UInt32 maxLength, vo
     BEGIN_SECAPI
                /* The caller either needs to specify data and maxLength or an actualLength, so we return either the data itself or the actual length of the data or both.  */
                if (!((data && maxLength) || actualLength))
     BEGIN_SECAPI
                /* The caller either needs to specify data and maxLength or an actualLength, so we return either the data itself or the actual length of the data or both.  */
                if (!((data && maxLength) || actualLength))
-                       MacOSError::throwMe(paramErr);
+                       MacOSError::throwMe(errSecParam);
 
         CssmDataContainer aData;
         ItemImpl::required(itemRef)->getData(aData);
         if (actualLength)
 
         CssmDataContainer aData;
         ItemImpl::required(itemRef)->getData(aData);
         if (actualLength)
-            *actualLength = aData.length();
-    
+            *actualLength = (UInt32)aData.length();
+
                if (data)
                {
                        // Make sure the buffer is big enough
                        if (aData.length() > maxLength)
                if (data)
                {
                        // Make sure the buffer is big enough
                        if (aData.length() > maxLength)
-                               MacOSError::throwMe(errKCBufferTooSmall);
+                               MacOSError::throwMe(errSecBufferTooSmall);
                        memcpy(data, aData.data(), aData.length());
                }
        END_SECAPI
                        memcpy(data, aData.data(), aData.length());
                }
        END_SECAPI
@@ -382,7 +389,7 @@ OSStatus SecKeychainItemSetAttribute(SecKeychainItemRef itemRef, SecKeychainAttr
 }
 
 /*  Finds a keychain item for legacy "KC" CoreServices APIs.
 }
 
 /*  Finds a keychain item for legacy "KC" CoreServices APIs.
-    Note: This version doesn't take a SecItemClass because 
+    Note: This version doesn't take a SecItemClass because
             SecKeychainSearchCreateFromAttributes() requires it.
     @@@ This should move to SecKeychainSearch.cpp
 */
             SecKeychainSearchCreateFromAttributes() requires it.
     @@@ This should move to SecKeychainSearch.cpp
 */
@@ -394,11 +401,11 @@ OSStatus SecKeychainItemFindFirst(SecKeychainRef keychainRef, const SecKeychainA
             cursor = KeychainImpl::required(keychainRef)->createCursor(attrList);
         else
             cursor = globals().storageManager.createCursor(attrList);
             cursor = KeychainImpl::required(keychainRef)->createCursor(attrList);
         else
             cursor = globals().storageManager.createCursor(attrList);
-    
+
         Item item;
         if (!cursor->next(item))
         Item item;
         if (!cursor->next(item))
-            return errKCItemNotFound;
-    
+            return errSecItemNotFound;
+
         *itemRef=item->handle();
         if (searchRef)
             *searchRef=cursor->handle();
         *itemRef=item->handle();
         if (searchRef)
             *searchRef=cursor->handle();
@@ -409,8 +416,17 @@ OSStatus SecKeychainItemCreatePersistentReference(SecKeychainItemRef itemRef, CF
 {
     BEGIN_SECAPI
                KCThrowParamErrIf_(!itemRef || !persistentItemRef);
 {
     BEGIN_SECAPI
                KCThrowParamErrIf_(!itemRef || !persistentItemRef);
-               Item item = ItemImpl::required(itemRef);
-        item->copyPersistentReference(*persistentItemRef);
+               Item item;
+               bool isIdentityRef = (CFGetTypeID(itemRef) == SecIdentityGetTypeID()) ? true : false;
+               if (isIdentityRef) {
+                       SecPointer<Certificate> certificatePtr(Identity::required((SecIdentityRef)itemRef)->certificate());
+                       SecCertificateRef certificateRef = certificatePtr->handle(false);
+                       item = ItemImpl::required((SecKeychainItemRef)certificateRef);
+               }
+               else {
+                       item = ItemImpl::required(itemRef);
+               }
+        item->copyPersistentReference(*persistentItemRef, isIdentityRef);
        END_SECAPI
 }
 
        END_SECAPI
 }
 
@@ -418,34 +434,22 @@ OSStatus SecKeychainItemCopyFromPersistentReference(CFDataRef persistentItemRef,
 {
     BEGIN_SECAPI
                KCThrowParamErrIf_(!persistentItemRef || !itemRef);
 {
     BEGIN_SECAPI
                KCThrowParamErrIf_(!persistentItemRef || !itemRef);
-               // make a NameValueDictionary from the data we received
-               CssmData dictData((void*)::CFDataGetBytePtr(persistentItemRef), ::CFDataGetLength(persistentItemRef));
-               NameValueDictionary dict(dictData);
-
-               Keychain keychain;
-               Item item;
-
-               // make sure we have a database identifier
-               if (dict.FindByName(SSUID_KEY) != 0)
-               {
-                       DLDbIdentifier dlDbIdentifier = NameValueDictionary::MakeDLDbIdentifierFromNameValueDictionary(dict);
-                       DLDbIdentifier newDlDbIdentifier(dlDbIdentifier.ssuid(),
-                               DLDbListCFPref::ExpandTildesInPath(dlDbIdentifier.dbName()).c_str(),
-                               dlDbIdentifier.dbLocation());
-
-                       keychain = globals().storageManager.keychain(newDlDbIdentifier);
-                       
-                       const NameValuePair* aDictItem = dict.FindByName(ITEM_KEY);
-                       if (aDictItem && keychain)
-                       {
-                               PrimaryKey primaryKey(aDictItem->Value());
-                               item = keychain->item(primaryKey);
-                       }
-                       // We can safely release the global API lock now since keychain and item
-                       // are CFRetained and will be until they go out of scope.
+               CFTypeRef result = NULL;
+               bool isIdentityRef = false;
+               Item item = ItemImpl::makeFromPersistentReference(persistentItemRef, &isIdentityRef);
+               if (isIdentityRef) {
+                       // item was stored as an identity, attempt to reconstitute it
+                       SecPointer<Certificate> certificatePtr(static_cast<Certificate *>(item.get()));
+                       StorageManager::KeychainList keychains;
+                       globals().storageManager.optionalSearchList(NULL, keychains);
+                       SecPointer<Identity> identityPtr(new Identity(keychains, certificatePtr));
+                       result = identityPtr->handle();
+                       KCThrowIf_( !result, errSecItemNotFound );
+               }
+               if (!result) {
+                       result = item->handle();
                }
                }
-               KCThrowIf_( !item, errSecItemNotFound );
-               *itemRef = item->handle();
+               *itemRef = (SecKeychainItemRef) result;
        END_SECAPI
 }
 
        END_SECAPI
 }
 
@@ -472,31 +476,31 @@ SecKeychainItemCopyFromRecordIdentifier(SecKeychainRef keychainRef,
                Keychain keychain = KeychainImpl::optional (keychainRef);
                RequiredParam (itemRef);
                RequiredParam (recordIdentifier);
                Keychain keychain = KeychainImpl::optional (keychainRef);
                RequiredParam (itemRef);
                RequiredParam (recordIdentifier);
-               
+
                Db db(keychain->database());
                Db db(keychain->database());
-               
+
                // make a raw database call to get the data
                CSSM_DL_DB_HANDLE dbHandle = db.handle ();
                CSSM_DB_UNIQUE_RECORD uniqueRecord;
                // make a raw database call to get the data
                CSSM_DL_DB_HANDLE dbHandle = db.handle ();
                CSSM_DB_UNIQUE_RECORD uniqueRecord;
-               
+
                // according to source, we should be able to reconsitute the uniqueRecord
                // from the data we earlier retained
                // according to source, we should be able to reconsitute the uniqueRecord
                // from the data we earlier retained
-               
+
                // prepare the record id
                memset (&uniqueRecord, 0, sizeof (uniqueRecord));
                uniqueRecord.RecordIdentifier.Data = (uint8*) CFDataGetBytePtr (recordIdentifier);
                uniqueRecord.RecordIdentifier.Length = CFDataGetLength (recordIdentifier);
                // prepare the record id
                memset (&uniqueRecord, 0, sizeof (uniqueRecord));
                uniqueRecord.RecordIdentifier.Data = (uint8*) CFDataGetBytePtr (recordIdentifier);
                uniqueRecord.RecordIdentifier.Length = CFDataGetLength (recordIdentifier);
-               
+
                // convert this unique id to a CSSM_DB_UNIQUE_RECORD that works for the CSP/DL
                CSSM_DB_UNIQUE_RECORD_PTR outputUniqueRecordPtr;
                CSSM_RETURN result;
                result = CSSM_DL_PassThrough (dbHandle, CSSM_APPLECSPDL_DB_CONVERT_RECORD_IDENTIFIER, &uniqueRecord, (void**) &outputUniqueRecordPtr);
                KCThrowIf_(result != 0, errSecItemNotFound);
                // convert this unique id to a CSSM_DB_UNIQUE_RECORD that works for the CSP/DL
                CSSM_DB_UNIQUE_RECORD_PTR outputUniqueRecordPtr;
                CSSM_RETURN result;
                result = CSSM_DL_PassThrough (dbHandle, CSSM_APPLECSPDL_DB_CONVERT_RECORD_IDENTIFIER, &uniqueRecord, (void**) &outputUniqueRecordPtr);
                KCThrowIf_(result != 0, errSecItemNotFound);
-               
+
                // from this, get the record type
                CSSM_DB_RECORD_ATTRIBUTE_DATA attributeData;
                memset (&attributeData, 0, sizeof (attributeData));
                // from this, get the record type
                CSSM_DB_RECORD_ATTRIBUTE_DATA attributeData;
                memset (&attributeData, 0, sizeof (attributeData));
-               
+
                result = CSSM_DL_DataGetFromUniqueRecordId (dbHandle, outputUniqueRecordPtr, &attributeData, NULL);
                KCThrowIf_(result != 0, errSecItemNotFound);
                CSSM_DB_RECORDTYPE recordType = attributeData.DataRecordType;
                result = CSSM_DL_DataGetFromUniqueRecordId (dbHandle, outputUniqueRecordPtr, &attributeData, NULL);
                KCThrowIf_(result != 0, errSecItemNotFound);
                CSSM_DB_RECORDTYPE recordType = attributeData.DataRecordType;
@@ -524,7 +528,7 @@ OSStatus SecKeychainItemCreateFromEncryptedContent(SecItemClass itemClass,
 
                RequiredParam (localID);
                RequiredParam (keychainRef);
 
                RequiredParam (localID);
                RequiredParam (keychainRef);
-               
+
         Item item(itemClass, (uint32) 0, length, data, true);
                if (initialAccess)
                        item->setAccess(Access::required(initialAccess));
         Item item(itemClass, (uint32) 0, length, data, true);
                if (initialAccess)
                        item->setAccess(Access::required(initialAccess));
@@ -563,7 +567,7 @@ OSStatus SecKeychainItemCreateFromEncryptedContent(SecItemClass itemClass,
                                                Schema::X509CertificateSchemaAttributeList,
                                                Schema::X509CertificateSchemaIndexCount,
                                                Schema::X509CertificateSchemaIndexList);
                                                Schema::X509CertificateSchemaAttributeList,
                                                Schema::X509CertificateSchemaIndexCount,
                                                Schema::X509CertificateSchemaIndexList);
-                                       
+
                                        // add the item again
                                        keychain->add(item);
                                }
                                        // add the item again
                                        keychain->add(item);
                                }
@@ -576,10 +580,10 @@ OSStatus SecKeychainItemCreateFromEncryptedContent(SecItemClass itemClass,
 
         if (itemRef)
                *itemRef = item->handle();
 
         if (itemRef)
                *itemRef = item->handle();
-               
+
                CSSM_DATA recordID;
                item->copyRecordIdentifier (recordID);
                CSSM_DATA recordID;
                item->copyRecordIdentifier (recordID);
-               
+
                *localID = CFDataCreate(kCFAllocatorDefault, (UInt8*) recordID.Data, recordID.Length);
                free (recordID.Data);
        END_SECAPI
                *localID = CFDataCreate(kCFAllocatorDefault, (UInt8*) recordID.Data, recordID.Length);
                free (recordID.Data);
        END_SECAPI
index 5ca4379dfe54d8f2602fd66d6298d33746af7e29..2d3e744623f33efe78669dfcab4e34210572abae 100644 (file)
@@ -1,15 +1,14 @@
-/*
- * Copyright (c) 2000-2008 Apple Inc. All Rights Reserved.
- * 
+/* * Copyright (c) 2000-2008,2012 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +16,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -31,6 +30,7 @@
 #ifndef _SECURITY_SECKEYCHAINITEM_H_
 #define _SECURITY_SECKEYCHAINITEM_H_
 
 #ifndef _SECURITY_SECKEYCHAINITEM_H_
 #define _SECURITY_SECKEYCHAINITEM_H_
 
+#include <AvailabilityMacros.h>
 #include <CoreFoundation/CFData.h>
 #include <Security/SecBase.h>
 #include <Security/cssmapple.h>
 #include <CoreFoundation/CFData.h>
 #include <Security/SecBase.h>
 #include <Security/cssmapple.h>
@@ -51,21 +51,22 @@ typedef FourCharCode        SecItemClass;
        @constant kSecInternetPasswordItemClass Indicates that the item is an Internet password.
        @constant kSecGenericPasswordItemClass Indicates that the item is a generic password.
        @constant kSecAppleSharePasswordItemClass Indicates that the item is an AppleShare password.
        @constant kSecInternetPasswordItemClass Indicates that the item is an Internet password.
        @constant kSecGenericPasswordItemClass Indicates that the item is a generic password.
        @constant kSecAppleSharePasswordItemClass Indicates that the item is an AppleShare password.
+               Note: AppleShare passwords are no longer used by OS X, starting in Leopard (10.5). Use of this item class is deprecated in OS X 10.9 and later; kSecInternetPasswordItemClass should be used instead when storing or looking up passwords for an Apple Filing Protocol (AFP) server.
        @constant kSecCertificateItemClass Indicates that the item is a digital certificate.
        @constant kSecPublicKeyItemClass Indicates that the item is a public key.
        @constant kSecPrivateKeyItemClass Indicates that the item is a private key.
        @constant kSecSymmetricKeyItemClass Indicates that the item is a symmetric key.
        @constant kSecCertificateItemClass Indicates that the item is a digital certificate.
        @constant kSecPublicKeyItemClass Indicates that the item is a public key.
        @constant kSecPrivateKeyItemClass Indicates that the item is a private key.
        @constant kSecSymmetricKeyItemClass Indicates that the item is a symmetric key.
-       @discussion The SecItemClass enumeration defines constants your application can use to specify the type of the keychain item you wish to create, dispose, add, delete, update, copy, or locate. You can also use these constants with the tag constant SecItemAttr. 
+       @discussion The SecItemClass enumeration defines constants your application can use to specify the type of the keychain item you wish to create, dispose, add, delete, update, copy, or locate. You can also use these constants with the tag constant SecItemAttr.
 */
 enum
 {
     kSecInternetPasswordItemClass   = 'inet',
     kSecGenericPasswordItemClass    = 'genp',
 */
 enum
 {
     kSecInternetPasswordItemClass   = 'inet',
     kSecGenericPasswordItemClass    = 'genp',
-    kSecAppleSharePasswordItemClass = 'ashp',
-    kSecCertificateItemClass        = CSSM_DL_DB_RECORD_X509_CERTIFICATE,
-    kSecPublicKeyItemClass          = CSSM_DL_DB_RECORD_PUBLIC_KEY,
-    kSecPrivateKeyItemClass         = CSSM_DL_DB_RECORD_PRIVATE_KEY,
-    kSecSymmetricKeyItemClass       = CSSM_DL_DB_RECORD_SYMMETRIC_KEY
+    kSecAppleSharePasswordItemClass   CF_ENUM_DEPRECATED(10_0, 10_9, NA, NA) = 'ashp',
+    kSecCertificateItemClass        = 0x80001000,
+    kSecPublicKeyItemClass          = 0x0000000F,
+    kSecPrivateKeyItemClass         = 0x00000010,
+    kSecSymmetricKeyItemClass       = 0x00000011
 };
 
 /*!
 };
 
 /*!
@@ -82,14 +83,14 @@ typedef FourCharCode SecItemAttr;
        @constant kSecModDateItemAttr (read-only) Identifies the modification date attribute. You use this tag to get a value of type string that represents the last time the item was updated, expressed in Zulu Time format ("YYYYMMDDhhmmSSZ"). This format is identical to CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE (cssmtype.h). When specifying the modification date as input to a function (e.g. SecKeychainSearchCreateFromAttributes), you may alternatively provide a numeric value of type UInt32 or SInt64, expressed as seconds since 1/1/1904 (DateTimeUtils.h).
        @constant kSecDescriptionItemAttr Identifies the description attribute. You use this tag to set or get a value of type string that represents a user-visible string describing this particular kind of item (e.g. "disk image password").
        @constant kSecCommentItemAttr Identifies the comment attribute. You use this tag to set or get a value of type string that represents a user-editable string containing comments for this item.
        @constant kSecModDateItemAttr (read-only) Identifies the modification date attribute. You use this tag to get a value of type string that represents the last time the item was updated, expressed in Zulu Time format ("YYYYMMDDhhmmSSZ"). This format is identical to CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE (cssmtype.h). When specifying the modification date as input to a function (e.g. SecKeychainSearchCreateFromAttributes), you may alternatively provide a numeric value of type UInt32 or SInt64, expressed as seconds since 1/1/1904 (DateTimeUtils.h).
        @constant kSecDescriptionItemAttr Identifies the description attribute. You use this tag to set or get a value of type string that represents a user-visible string describing this particular kind of item (e.g. "disk image password").
        @constant kSecCommentItemAttr Identifies the comment attribute. You use this tag to set or get a value of type string that represents a user-editable string containing comments for this item.
-       @constant kSecCreatorItemAttr Identifies the creator attribute. You use this tag to set or get a value of type FourCharCode that represents the item's creator. 
-       @constant kSecTypeItemAttr Identifies the type attribute. You use this tag to set or get a value of type FourCharCode that represents the item's type. 
+       @constant kSecCreatorItemAttr Identifies the creator attribute. You use this tag to set or get a value of type FourCharCode that represents the item's creator.
+       @constant kSecTypeItemAttr Identifies the type attribute. You use this tag to set or get a value of type FourCharCode that represents the item's type.
        @constant kSecScriptCodeItemAttr Identifies the script code attribute. You use this tag to set or get a value of type ScriptCode that represents the script code for all strings. (Note: use of this attribute is deprecated; string attributes should always be stored in UTF-8 encoding.)
        @constant kSecScriptCodeItemAttr Identifies the script code attribute. You use this tag to set or get a value of type ScriptCode that represents the script code for all strings. (Note: use of this attribute is deprecated; string attributes should always be stored in UTF-8 encoding.)
-       @constant kSecLabelItemAttr Identifies the label attribute. You use this tag to set or get a value of type string that represents a user-editable string containing the label for this item. 
-       @constant kSecInvisibleItemAttr Identifies the invisible attribute. You use this tag to set or get a value of type Boolean that indicates whether the item is invisible (i.e. should not be displayed). 
+       @constant kSecLabelItemAttr Identifies the label attribute. You use this tag to set or get a value of type string that represents a user-editable string containing the label for this item.
+       @constant kSecInvisibleItemAttr Identifies the invisible attribute. You use this tag to set or get a value of type Boolean that indicates whether the item is invisible (i.e. should not be displayed).
        @constant kSecNegativeItemAttr Identifies the negative attribute. You use this tag to set or get a value of type Boolean that indicates whether there is a valid password associated with this keychain item. This is useful if your application doesn't want a password for some particular service to be stored in the keychain, but prefers that it always be entered by the user. The item (typically invisible and with zero-length data) acts as a placeholder to say "don't use me."
        @constant kSecCustomIconItemAttr Identifies the custom icon attribute. You use this tag to set or get a value of type Boolean that indicates whether the item has an application-specific icon. To do this, you must also set the attribute value identified by the tag kSecTypeItemAttr to a file type for which there is a corresponding icon in the desktop database, and set the attribute value identified by the tag kSecCreatorItemAttr to an appropriate application creator type. If a custom icon corresponding to the item's type and creator can be found in the desktop database, it will be displayed by Keychain Access. Otherwise, default icons are used. (Note: use of this attribute is deprecated; custom icons for keychain items are not supported in Mac OS X.)
        @constant kSecNegativeItemAttr Identifies the negative attribute. You use this tag to set or get a value of type Boolean that indicates whether there is a valid password associated with this keychain item. This is useful if your application doesn't want a password for some particular service to be stored in the keychain, but prefers that it always be entered by the user. The item (typically invisible and with zero-length data) acts as a placeholder to say "don't use me."
        @constant kSecCustomIconItemAttr Identifies the custom icon attribute. You use this tag to set or get a value of type Boolean that indicates whether the item has an application-specific icon. To do this, you must also set the attribute value identified by the tag kSecTypeItemAttr to a file type for which there is a corresponding icon in the desktop database, and set the attribute value identified by the tag kSecCreatorItemAttr to an appropriate application creator type. If a custom icon corresponding to the item's type and creator can be found in the desktop database, it will be displayed by Keychain Access. Otherwise, default icons are used. (Note: use of this attribute is deprecated; custom icons for keychain items are not supported in Mac OS X.)
-       @constant kSecAccountItemAttr Identifies the account attribute. You use this tag to set or get a string that represents the user account. This attribute applies to generic, Internet, and AppleShare password items. 
+       @constant kSecAccountItemAttr Identifies the account attribute. You use this tag to set or get a string that represents the user account. This attribute applies to generic, Internet, and AppleShare password items.
        @constant kSecServiceItemAttr Identifies the service attribute. You use this tag to set or get a string that represents the service associated with this item. This attribute is unique to generic password items.
        @constant kSecGenericItemAttr Identifies the generic attribute. You use this tag to set or get a value of untyped bytes that represents a user-defined attribute.  This attribute is unique to generic password items.
        @constant kSecSecurityDomainItemAttr Identifies the security domain attribute. You use this tag to set or get a value that represents the Internet security domain. This attribute is unique to Internet password items.
        @constant kSecServiceItemAttr Identifies the service attribute. You use this tag to set or get a string that represents the service associated with this item. This attribute is unique to generic password items.
        @constant kSecGenericItemAttr Identifies the generic attribute. You use this tag to set or get a value of untyped bytes that represents a user-defined attribute.  This attribute is unique to generic password items.
        @constant kSecSecurityDomainItemAttr Identifies the security domain attribute. You use this tag to set or get a value that represents the Internet security domain. This attribute is unique to Internet password items.
@@ -97,9 +98,9 @@ typedef FourCharCode SecItemAttr;
        @constant kSecAuthenticationTypeItemAttr Identifies the authentication type attribute. You use this tag to set or get a value of type SecAuthenticationType that represents the Internet authentication scheme. This attribute is unique to Internet password items.
        @constant kSecPortItemAttr Identifies the port attribute. You use this tag to set or get a value of type UInt32 that represents the Internet port number. This attribute is unique to Internet password items.
        @constant kSecPathItemAttr Identifies the path attribute. You use this tag to set or get a string value that represents the path. This attribute is unique to Internet password items.
        @constant kSecAuthenticationTypeItemAttr Identifies the authentication type attribute. You use this tag to set or get a value of type SecAuthenticationType that represents the Internet authentication scheme. This attribute is unique to Internet password items.
        @constant kSecPortItemAttr Identifies the port attribute. You use this tag to set or get a value of type UInt32 that represents the Internet port number. This attribute is unique to Internet password items.
        @constant kSecPathItemAttr Identifies the path attribute. You use this tag to set or get a string value that represents the path. This attribute is unique to Internet password items.
-       @constant kSecVolumeItemAttr Identifies the volume attribute. You use this tag to set or get a string value that represents the AppleShare volume. This attribute is unique to AppleShare password items.
-       @constant kSecAddressItemAttr Identifies the address attribute. You use this tag to set or get a string value that represents the AppleTalk zone name, or the IP or domain name that represents the server address. This attribute is unique to AppleShare password items.
-       @constant kSecSignatureItemAttr Identifies the server signature attribute. You use this tag to set or get a value of type SecAFPServerSignature that represents the server signature block. This attribute is unique to AppleShare password items.
+       @constant kSecVolumeItemAttr Identifies the volume attribute. You use this tag to set or get a string value that represents the AppleShare volume. This attribute is unique to AppleShare password items. Note: AppleShare passwords are no longer used by OS X as of Leopard (10.5); Internet password items are used instead.
+       @constant kSecAddressItemAttr Identifies the address attribute. You use this tag to set or get a string value that represents the AppleTalk zone name, or the IP or domain name that represents the server address. This attribute is unique to AppleShare password items. Note: AppleShare passwords are no longer used by OS X as of Leopard (10.5); Internet password items are used instead.
+       @constant kSecSignatureItemAttr Identifies the server signature attribute. You use this tag to set or get a value of type SecAFPServerSignature that represents the server signature block. This attribute is unique to AppleShare password items. Note: AppleShare passwords are no longer used by OS X as of Leopard (10.5); Internet password items are used instead.
        @constant kSecProtocolItemAttr Identifies the protocol attribute. You use this tag to set or get a value of type SecProtocolType that represents the Internet protocol. This attribute applies to AppleShare and Internet password items.
        @constant kSecCertificateType Indicates a CSSM_CERT_TYPE type.
        @constant kSecCertificateEncoding Indicates a CSSM_CERT_ENCODING type.
        @constant kSecProtocolItemAttr Identifies the protocol attribute. You use this tag to set or get a value of type SecProtocolType that represents the Internet protocol. This attribute applies to AppleShare and Internet password items.
        @constant kSecCertificateType Indicates a CSSM_CERT_TYPE type.
        @constant kSecCertificateEncoding Indicates a CSSM_CERT_ENCODING type.
@@ -109,7 +110,7 @@ typedef FourCharCode SecItemAttr;
        @discussion To obtain information about a certificate, use the CDSA Certificate Library (CL) API. To obtain information about a key, use the SecKeyGetCSSMKey function and the CDSA Cryptographic Service Provider (CSP) API.
 */
 enum
        @discussion To obtain information about a certificate, use the CDSA Certificate Library (CL) API. To obtain information about a key, use the SecKeyGetCSSMKey function and the CDSA Cryptographic Service Provider (CSP) API.
 */
 enum
-{                                                                                      
+{
     kSecCreationDateItemAttr           = 'cdat',
     kSecModDateItemAttr                                = 'mdat',
     kSecDescriptionItemAttr                    = 'desc',
     kSecCreationDateItemAttr           = 'cdat',
     kSecModDateItemAttr                                = 'mdat',
     kSecDescriptionItemAttr                    = 'desc',
@@ -168,7 +169,7 @@ CFTypeID SecKeychainItemGetTypeID(void);
        @param length The length of the buffer pointed to by data.
        @param data Pointer to a buffer containing the data to store. Pass NULL if you don't need to modify the data.
     @result A result code. See "Security Error Codes" (SecBase.h).
        @param length The length of the buffer pointed to by data.
        @param data Pointer to a buffer containing the data to store. Pass NULL if you don't need to modify the data.
     @result A result code. See "Security Error Codes" (SecBase.h).
-       @discussion The keychain item is written to the keychain's permanent data store. If the keychain item has not previously been added to a keychain, a call to the SecKeychainItemModifyContent function does nothing and returns noErr.
+       @discussion The keychain item is written to the keychain's permanent data store. If the keychain item has not previously been added to a keychain, a call to the SecKeychainItemModifyContent function does nothing and returns errSecSuccess.
 */
 OSStatus SecKeychainItemModifyAttributesAndData(SecKeychainItemRef itemRef, const SecKeychainAttributeList *attrList, UInt32 length, const void *data);
 
 */
 OSStatus SecKeychainItemModifyAttributesAndData(SecKeychainItemRef itemRef, const SecKeychainAttributeList *attrList, UInt32 length, const void *data);
 
@@ -182,7 +183,7 @@ OSStatus SecKeychainItemModifyAttributesAndData(SecKeychainItemRef itemRef, cons
        @param initialAccess A reference to the access for this keychain item.
     @param keychainRef A reference to the keychain in which to add the item.
        @param itemRef On return, a pointer to a reference to the newly created keychain item (optional). When the item reference is no longer required, call CFRelease to deallocate memory occupied by the item.
        @param initialAccess A reference to the access for this keychain item.
     @param keychainRef A reference to the keychain in which to add the item.
        @param itemRef On return, a pointer to a reference to the newly created keychain item (optional). When the item reference is no longer required, call CFRelease to deallocate memory occupied by the item.
-    @result A result code. See "Security Error Codes" (SecBase.h). In addition, paramErr (-50) may be returned if not enough valid parameters are supplied, or memFullErr (-108) if there is not enough memory in the current heap zone to create the object.
+    @result A result code. See "Security Error Codes" (SecBase.h). In addition, errSecParam (-50) may be returned if not enough valid parameters are supplied, or errSecAllocate (-108) if there is not enough memory in the current heap zone to create the object.
 */
 OSStatus SecKeychainItemCreateFromContent(SecItemClass itemClass, SecKeychainAttributeList *attrList,
                UInt32 length, const void *data, SecKeychainRef keychainRef,
 */
 OSStatus SecKeychainItemCreateFromContent(SecItemClass itemClass, SecKeychainAttributeList *attrList,
                UInt32 length, const void *data, SecKeychainRef keychainRef,
@@ -207,7 +208,7 @@ OSStatus SecKeychainItemModifyContent(SecKeychainItemRef itemRef, const SecKeych
        @param attrList On input, the list of attributes to retrieve. On output, the attributes are filled in. Pass NULL if you don't need to retrieve any attributes. You must call SecKeychainItemFreeContent when you no longer need the attributes.
        @param length On return, the length of the buffer pointed to by outData.
        @param outData On return, a pointer to a buffer containing the data in this item. Pass NULL if you don't need to retrieve the data. You must call SecKeychainItemFreeContent when you no longer need the data.
        @param attrList On input, the list of attributes to retrieve. On output, the attributes are filled in. Pass NULL if you don't need to retrieve any attributes. You must call SecKeychainItemFreeContent when you no longer need the attributes.
        @param length On return, the length of the buffer pointed to by outData.
        @param outData On return, a pointer to a buffer containing the data in this item. Pass NULL if you don't need to retrieve the data. You must call SecKeychainItemFreeContent when you no longer need the data.
-    @result A result code. See "Security Error Codes" (SecBase.h). In addition, paramErr (-50) may be returned if not enough valid parameters are supplied.
+    @result A result code. See "Security Error Codes" (SecBase.h). In addition, errSecParam (-50) may be returned if not enough valid parameters are supplied.
 */
 OSStatus SecKeychainItemCopyContent(SecKeychainItemRef itemRef, SecItemClass *itemClass, SecKeychainAttributeList *attrList, UInt32 *length, void **outData);
 
 */
 OSStatus SecKeychainItemCopyContent(SecKeychainItemRef itemRef, SecItemClass *itemClass, SecKeychainAttributeList *attrList, UInt32 *length, void **outData);
 
@@ -228,7 +229,7 @@ OSStatus SecKeychainItemFreeContent(SecKeychainAttributeList *attrList, void *da
        @param attrList On return, a pointer to the list of retrieved attributes. Pass NULL if you don't need to retrieve any attributes. You must call SecKeychainItemFreeAttributesAndData when you no longer need this list.
        @param length On return, the length of the buffer pointed to by outData.
        @param outData On return, a pointer to a buffer containing the data in this item. Pass NULL if you don't need to retrieve the data. You must call SecKeychainItemFreeAttributesAndData when you no longer need the data.
        @param attrList On return, a pointer to the list of retrieved attributes. Pass NULL if you don't need to retrieve any attributes. You must call SecKeychainItemFreeAttributesAndData when you no longer need this list.
        @param length On return, the length of the buffer pointed to by outData.
        @param outData On return, a pointer to a buffer containing the data in this item. Pass NULL if you don't need to retrieve the data. You must call SecKeychainItemFreeAttributesAndData when you no longer need the data.
-    @result A result code. See "Security Error Codes" (SecBase.h). In addition, paramErr (-50) may be returned if not enough valid parameters are supplied.
+    @result A result code. See "Security Error Codes" (SecBase.h). In addition, errSecParam (-50) may be returned if not enough valid parameters are supplied.
 */
 OSStatus SecKeychainItemCopyAttributesAndData(SecKeychainItemRef itemRef, SecKeychainAttributeInfo *info, SecItemClass *itemClass, SecKeychainAttributeList **attrList, UInt32 *length, void **outData);
 
 */
 OSStatus SecKeychainItemCopyAttributesAndData(SecKeychainItemRef itemRef, SecKeychainAttributeInfo *info, SecItemClass *itemClass, SecKeychainAttributeList **attrList, UInt32 *length, void **outData);
 
@@ -246,13 +247,13 @@ OSStatus SecKeychainItemFreeAttributesAndData(SecKeychainAttributeList *attrList
        @abstract Deletes a keychain item from the default keychain's permanent data store.
        @param itemRef A keychain item reference of the item to delete.
     @result A result code. See "Security Error Codes" (SecBase.h).
        @abstract Deletes a keychain item from the default keychain's permanent data store.
        @param itemRef A keychain item reference of the item to delete.
     @result A result code. See "Security Error Codes" (SecBase.h).
-       @discussion 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 the CFRelease function when you are completely finished with an item.       
+       @discussion If itemRef has not previously been added to the keychain, SecKeychainItemDelete does nothing and returns errSecSuccess. IMPORTANT: SecKeychainItemDelete does not dispose the memory occupied by the item reference itself; use the CFRelease function when you are completely finished with an item.
 */
 OSStatus SecKeychainItemDelete(SecKeychainItemRef itemRef);
 
 /*!
        @function SecKeychainItemCopyKeychain
 */
 OSStatus SecKeychainItemDelete(SecKeychainItemRef itemRef);
 
 /*!
        @function SecKeychainItemCopyKeychain
-       @abstract Copies an existing keychain reference from a keychain item.   
+       @abstract Copies an existing keychain reference from a keychain item.
        @param itemRef A keychain item reference.
        @param keychainRef On return, the keychain reference for the specified item. Release this reference by calling the CFRelease function.
     @result A result code. See "Security Error Codes" (SecBase.h).
        @param itemRef A keychain item reference.
        @param keychainRef On return, the keychain reference for the specified item. Release this reference by calling the CFRelease function.
     @result A result code. See "Security Error Codes" (SecBase.h).
index 02f955dd69d22dde322ef49c418b674c23d3560b..a23b47cd5a28c6e470b82fa92882f9339ea5ca9a 100644 (file)
@@ -68,7 +68,7 @@ static void cfStringToData(
                kCFStringEncodingUTF8, 0);
        if(cfData == NULL) {
                /* can't convert to UTF8!? */
                kCFStringEncodingUTF8, 0);
        if(cfData == NULL) {
                /* can't convert to UTF8!? */
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
        }
        dst.copy(CFDataGetBytePtr(cfData), CFDataGetLength(cfData)); 
        CFRelease(cfData);
        }
        dst.copy(CFDataGetBytePtr(cfData), CFDataGetLength(cfData)); 
        CFRelease(cfData);
@@ -110,10 +110,10 @@ static bool lookupExtendedAttr(
        attrs[0].length = sizeof(UInt32);
        attrs[0].data   = (void *)&recType;
        attrs[1].tag    = kExtendedAttrItemIDAttr;
        attrs[0].length = sizeof(UInt32);
        attrs[0].data   = (void *)&recType;
        attrs[1].tag    = kExtendedAttrItemIDAttr;
-       attrs[1].length = itemID.Length;
+       attrs[1].length = (UInt32)itemID.Length;
        attrs[1].data   = itemID.Data;
        attrs[2].tag    = kExtendedAttrAttributeNameAttr;
        attrs[1].data   = itemID.Data;
        attrs[2].tag    = kExtendedAttrAttributeNameAttr;
-       attrs[2].length = nameCData.Length;
+       attrs[2].length = (UInt32)nameCData.Length;
        attrs[2].data   = nameCData.Data;
        SecKeychainAttributeList attrList = {3, attrs};
        
        attrs[2].data   = nameCData.Data;
        SecKeychainAttributeList attrList = {3, attrs};
        
@@ -143,7 +143,7 @@ OSStatus SecKeychainItemSetExtendedAttribute(
     BEGIN_SECAPI
        
        if((itemRef == NULL) || (attrName == NULL)) {
     BEGIN_SECAPI
        
        if((itemRef == NULL) || (attrName == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        
        /* is there already a matching ExtendedAttribute item? */
        }
        
        /* is there already a matching ExtendedAttribute item? */
@@ -155,7 +155,7 @@ OSStatus SecKeychainItemSetExtendedAttribute(
                        return errSecNoSuchAttr;
                }
                foundItem->keychain()->deleteItem(foundItem);
                        return errSecNoSuchAttr;
                }
                foundItem->keychain()->deleteItem(foundItem);
-               return noErr;
+               return errSecSuccess;
        }
 
        CSSM_DATA attrCValue = {CFDataGetLength(attrValue), (uint8 *)CFDataGetBytePtr(attrValue)};
        }
 
        CSSM_DATA attrCValue = {CFDataGetLength(attrValue), (uint8 *)CFDataGetBytePtr(attrValue)};
@@ -190,7 +190,7 @@ OSStatus SecKeychainItemCopyExtendedAttribute(
     BEGIN_SECAPI
        
        if((itemRef == NULL) || (attrName == NULL) || (attrValue == NULL)) {
     BEGIN_SECAPI
        
        if((itemRef == NULL) || (attrName == NULL) || (attrValue == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        
        Item foundItem;
        }
        
        Item foundItem;
@@ -228,7 +228,7 @@ OSStatus SecKeychainItemCopyAllExtendedAttributes(
     BEGIN_SECAPI
        
        if((itemRef == NULL) || (attrNames == NULL)) {
     BEGIN_SECAPI
        
        if((itemRef == NULL) || (attrNames == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
 
        isItemRefCapable(itemRef);
        }
 
        isItemRefCapable(itemRef);
@@ -252,7 +252,7 @@ OSStatus SecKeychainItemCopyAllExtendedAttributes(
        attrs[0].length = sizeof(UInt32);
        attrs[0].data   = (void *)&recType;
        attrs[1].tag    = kExtendedAttrItemIDAttr;
        attrs[0].length = sizeof(UInt32);
        attrs[0].data   = (void *)&recType;
        attrs[1].tag    = kExtendedAttrItemIDAttr;
-       attrs[1].length = itemID.Length;
+       attrs[1].length = (UInt32)itemID.Length;
        attrs[1].data   = itemID.Data;
        SecKeychainAttributeList attrList = {2, attrs};
        
        attrs[1].data   = itemID.Data;
        SecKeychainAttributeList attrList = {2, attrs};
        
@@ -261,7 +261,7 @@ OSStatus SecKeychainItemCopyAllExtendedAttributes(
        
        CFMutableArrayRef outNames = NULL;
        CFMutableArrayRef outValues = NULL;
        
        CFMutableArrayRef outNames = NULL;
        CFMutableArrayRef outValues = NULL;
-       OSStatus ourRtn = noErr;
+       OSStatus ourRtn = errSecSuccess;
        
        KCCursor cursor(kcList, CSSM_DL_DB_RECORD_EXTENDED_ATTRIBUTE, &attrList);
        for(;;) {
        
        KCCursor cursor(kcList, CSSM_DL_DB_RECORD_EXTENDED_ATTRIBUTE, &attrList);
        for(;;) {
@@ -329,7 +329,7 @@ OSStatus SecKeychainItemCopyAllExtendedAttributes(
                                        break;
                                default:
                                        /* should never happen, right? */
                                        break;
                                default:
                                        /* should never happen, right? */
-                                       MacOSError::throwMe(internalComponentErr);
+                                       MacOSError::throwMe(errSecInternalComponent);
                        }
                }
                ItemImpl::freeAttributesAndData(attrList, NULL);
                        }
                }
                ItemImpl::freeAttributesAndData(attrList, NULL);
index e67620c8bef7083aaf6e4e6b642bda941ff7881a..9ec5b60a219c5f33e584c8a181cc5a0aef8fcd1b 100644 (file)
@@ -124,7 +124,7 @@ OSStatus SecKeychainItemCopyFromRecordIdentifier(SecKeychainRef keychain,
        @param attrList on output, an attribute list with the attributes specified by info. You must call SecKeychainItemFreeAttributesAndData() when you no longer need this list.
        @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. You must call SecKeychainItemFreeAttributesAndData() when you no longer need the data.
        @param attrList on output, an attribute list with the attributes specified by info. You must call SecKeychainItemFreeAttributesAndData() when you no longer need this list.
        @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. You must call SecKeychainItemFreeAttributesAndData() when you no longer need the data.
-    @result A result code.  See "Security Error Codes" (SecBase.h). In addition, paramErr (-50) may be returned if not enough valid parameters are supplied.
+    @result A result code.  See "Security Error Codes" (SecBase.h). In addition, errSecParam (-50) may be returned if not enough valid parameters are supplied.
 */
 OSStatus SecKeychainItemCopyAttributesAndEncryptedData(SecKeychainItemRef itemRef, SecKeychainAttributeInfo *info,
                                                                                                           SecItemClass *itemClass, SecKeychainAttributeList **attrList,
 */
 OSStatus SecKeychainItemCopyAttributesAndEncryptedData(SecKeychainItemRef itemRef, SecKeychainAttributeInfo *info,
                                                                                                           SecItemClass *itemClass, SecKeychainAttributeList **attrList,
@@ -138,7 +138,7 @@ OSStatus SecKeychainItemCopyAttributesAndEncryptedData(SecKeychainItemRef itemRe
        @param length The length of the buffer pointed to by data.
        @param data Pointer to a buffer containing the data to store.
     @result A result code.  See "Security Error Codes" (SecBase.h).
        @param length The length of the buffer pointed to by data.
        @param data Pointer to a buffer containing the data to store.
     @result A result code.  See "Security Error Codes" (SecBase.h).
-       @discussion The keychain item is written to the keychain's permanent data store. If the keychain item has not previously been added to a keychain, a call to the SecKeychainItemModifyContent function does nothing and returns noErr.
+       @discussion The keychain item is written to the keychain's permanent data store. If the keychain item has not previously been added to a keychain, a call to the SecKeychainItemModifyContent function does nothing and returns errSecSuccess.
 */
 OSStatus SecKeychainItemModifyEncryptedData(SecKeychainItemRef itemRef, UInt32 length, const void *data);
 
 */
 OSStatus SecKeychainItemModifyEncryptedData(SecKeychainItemRef itemRef, UInt32 length, const void *data);
 
@@ -152,7 +152,7 @@ OSStatus SecKeychainItemModifyEncryptedData(SecKeychainItemRef itemRef, UInt32 l
        @param initialAccess A reference to the access for this keychain item.
        @param itemRef On return, a pointer to a reference to the newly created keychain item (optional). When the item reference is no longer required, call CFRelease to deallocate memory occupied by the item.
        @param itemLocalID On return, the item's local ID data (optional). When the local ID data reference is no longer required, call CFRelease to deallocate memory occupied by the reference.
        @param initialAccess A reference to the access for this keychain item.
        @param itemRef On return, a pointer to a reference to the newly created keychain item (optional). When the item reference is no longer required, call CFRelease to deallocate memory occupied by the item.
        @param itemLocalID On return, the item's local ID data (optional). When the local ID data reference is no longer required, call CFRelease to deallocate memory occupied by the reference.
-    @result A result code.  See "Security Error Codes" (SecBase.h). In addition, paramErr (-50) may be returned if not enough valid parameters are supplied, or memFullErr (-108) if there is not enough memory in the current heap zone to create the object.
+    @result A result code.  See "Security Error Codes" (SecBase.h). In addition, errSecParam (-50) may be returned if not enough valid parameters are supplied, or errSecAllocate (-108) if there is not enough memory in the current heap zone to create the object.
 */
 OSStatus SecKeychainItemCreateFromEncryptedContent(SecItemClass itemClass, UInt32 length, const void *data,
                                                                                                   SecKeychainRef keychainRef, SecAccessRef initialAccess,
 */
 OSStatus SecKeychainItemCreateFromEncryptedContent(SecItemClass itemClass, UInt32 length, const void *data,
                                                                                                   SecKeychainRef keychainRef, SecAccessRef initialAccess,
index 35445a85f117f70e9f2fd16291199082c6745074..aa7ce0b2f3eadaa27a1a768d458d69875f5252df 100644 (file)
@@ -54,10 +54,14 @@ OSStatus SecKeychainRemoveFromSearchList(SecKeychainRef keychainRef);
 
 /* Login keychain support */
 OSStatus SecKeychainLogin(UInt32 nameLength, const void* name, UInt32 passwordLength, const void* password);
 
 /* Login keychain support */
 OSStatus SecKeychainLogin(UInt32 nameLength, const void* name, UInt32 passwordLength, const void* password);
+OSStatus SecKeychainStash();
 OSStatus SecKeychainLogout();
 OSStatus SecKeychainCopyLogin(SecKeychainRef *keychainRef);
 OSStatus SecKeychainResetLogin(UInt32 passwordLength, const void* password, Boolean resetSearchList);
 
 OSStatus SecKeychainLogout();
 OSStatus SecKeychainCopyLogin(SecKeychainRef *keychainRef);
 OSStatus SecKeychainResetLogin(UInt32 passwordLength, const void* password, Boolean resetSearchList);
 
+OSStatus SecKeychainVerifyKeyStorePassphrase(uint32_t retries);
+OSStatus SecKeychainChangeKeyStorePassphrase();
+
 /* Keychain synchronization */
 enum {
   kSecKeychainNotSynchronized = 0,
 /* Keychain synchronization */
 enum {
   kSecKeychainNotSynchronized = 0,
index 0463c31099d4d734a72e0b140ff2db08b6e02bbb..f6e2e497208015fc18c30a5be14c305ce6c9754f 100644 (file)
@@ -30,7 +30,8 @@
 #include <Security/Authorization.h>
 #include <Security/AuthorizationTagsPriv.h>
 
 #include <Security/Authorization.h>
 #include <Security/AuthorizationTagsPriv.h>
 
-CFTypeID
+#if 0
+static CFTypeID
 SecPasswordGetTypeID(void)
 {
        BEGIN_SECAPI
 SecPasswordGetTypeID(void)
 {
        BEGIN_SECAPI
@@ -39,6 +40,7 @@ SecPasswordGetTypeID(void)
     
        END_SECAPI1(_kCFRuntimeNotATypeID)
 }
     
        END_SECAPI1(_kCFRuntimeNotATypeID)
 }
+#endif
 
 OSStatus
 SecGenericPasswordCreate(SecKeychainAttributeList *searchAttrList, SecKeychainAttributeList *itemAttrList, SecPasswordRef *itemRef)
 
 OSStatus
 SecGenericPasswordCreate(SecKeychainAttributeList *searchAttrList, SecKeychainAttributeList *itemAttrList, SecPasswordRef *itemRef)
@@ -70,7 +72,7 @@ SecPasswordAction(SecPasswordRef itemRef, CFTypeRef message, UInt32 flags, UInt3
     Password passwordRef = PasswordImpl::required(itemRef);
     
     void *passwordData = NULL;
     Password passwordRef = PasswordImpl::required(itemRef);
     
     void *passwordData = NULL;
-    uint32_t passwordLength = 0;
+    UInt32 passwordLength = 0;
        bool gotPassword = false;
 
     // no flags has no meaning, and there is no apparent default
        bool gotPassword = false;
 
     // no flags has no meaning, and there is no apparent default
@@ -108,7 +110,7 @@ SecPasswordAction(SecPasswordRef itemRef, CFTypeRef message, UInt32 flags, UInt3
             
                 // check mItem whether it's got data
                 if (passwordRef->getData(length, data))
             
                 // check mItem whether it's got data
                 if (passwordRef->getData(length, data))
-                    return noErr;
+                    return errSecSuccess;
             }
             
             // User might cancel here, immediately return that too (it will be thrown)            
             }
             
             // User might cancel here, immediately return that too (it will be thrown)            
@@ -121,6 +123,11 @@ SecPasswordAction(SecPasswordRef itemRef, CFTypeRef message, UInt32 flags, UInt3
     {
         AuthorizationRef authRef;
         OSStatus status = AuthorizationCreate(NULL,NULL,0,&authRef);
     {
         AuthorizationRef authRef;
         OSStatus status = AuthorizationCreate(NULL,NULL,0,&authRef);
+        if (status != errSecSuccess)
+        {
+            MacOSError::throwMe(status);
+        }
+        
         AuthorizationItem right = { NULL, 0, NULL, 0 };
         AuthorizationItemSet rightSet = { 1, &right };
         uint32_t reason, tries;
         AuthorizationItem right = { NULL, 0, NULL, 0 };
         AuthorizationItemSet rightSet = { 1, &right };
         uint32_t reason, tries;
@@ -161,9 +168,12 @@ SecPasswordAction(SecPasswordRef itemRef, CFTypeRef message, UInt32 flags, UInt3
         else
             right.name = "com.apple.builtin.generic-unlock";
 
         else
             right.name = "com.apple.builtin.generic-unlock";
 
-        AuthorizationItem envRights[5] = { { AGENT_HINT_RETRY_REASON, sizeof(reason), &reason, 0 },
+        bool showPassword = false;
+        
+        AuthorizationItem envRights[6] = { { AGENT_HINT_RETRY_REASON, sizeof(reason), &reason, 0 },
                                             { AGENT_HINT_TRIES, sizeof(tries), &tries, 0 },
                                             { AGENT_HINT_CUSTOM_PROMPT, messageData ? strlen(messageData) : 0, const_cast<char*>(messageData), 0 },
                                             { AGENT_HINT_TRIES, sizeof(tries), &tries, 0 },
                                             { AGENT_HINT_CUSTOM_PROMPT, messageData ? strlen(messageData) : 0, const_cast<char*>(messageData), 0 },
+                                            { AGENT_HINT_ALLOW_SHOW_PASSWORD, showPassword ? strlen("YES") : strlen("NO"), const_cast<char *>(showPassword ? "YES" : "NO"), 0 },
                                             { AGENT_HINT_SHOW_ADD_TO_KEYCHAIN, keychain ? strlen("YES") : strlen("NO"), const_cast<char *>(keychain ? "YES" : "NO"), 0 },
                                             { AGENT_ADD_TO_KEYCHAIN, addToKeychain ? strlen("YES") : strlen("NO"), const_cast<char *>(addToKeychain ? "YES" : "NO"), 0 } };
                                             
                                             { AGENT_HINT_SHOW_ADD_TO_KEYCHAIN, keychain ? strlen("YES") : strlen("NO"), const_cast<char *>(keychain ? "YES" : "NO"), 0 },
                                             { AGENT_ADD_TO_KEYCHAIN, addToKeychain ? strlen("YES") : strlen("NO"), const_cast<char *>(addToKeychain ? "YES" : "NO"), 0 } };
                                             
@@ -199,7 +209,7 @@ SecPasswordAction(SecPasswordRef itemRef, CFTypeRef message, UInt32 flags, UInt3
                 if (!strcmp(AGENT_PASSWORD, item.name))
                 {
                                        gotPassword = true;
                 if (!strcmp(AGENT_PASSWORD, item.name))
                 {
                                        gotPassword = true;
-                    passwordLength = item.valueLength;
+                    passwordLength = (UInt32)item.valueLength;
 
                     if (passwordLength)
                     {
 
                     if (passwordLength)
                     {
@@ -214,7 +224,7 @@ SecPasswordAction(SecPasswordRef itemRef, CFTypeRef message, UInt32 flags, UInt3
                     if (data) 
                         *data = passwordData;
                                                
                     if (data) 
                         *data = passwordData;
                                                
-                                       secdebug("SecPassword", "Got password (%d,%p).", passwordLength, passwordData);
+                                       secdebug("SecPassword", "Got password (%u,%p).", (unsigned int)passwordLength, passwordData);
                 }
                 else if (!strcmp(AGENT_ADD_TO_KEYCHAIN, item.name))
                 {
                 }
                 else if (!strcmp(AGENT_ADD_TO_KEYCHAIN, item.name))
                 {
@@ -238,9 +248,17 @@ SecPasswordAction(SecPasswordRef itemRef, CFTypeRef message, UInt32 flags, UInt3
             if (gotPassword)
                                passwordRef->setData(passwordLength, passwordData);
                        if (flags & kSecPasswordSet)
             if (gotPassword)
                                passwordRef->setData(passwordLength, passwordData);
                        if (flags & kSecPasswordSet)
+            {
                                passwordRef->save();
                                passwordRef->save();
+                gotPassword = true;
+            }
                }
     }
 
                }
     }
 
+    if (!gotPassword)
+    {
+        return errAuthorizationDenied;
+    }
+    
     END_SECAPI
 }
     END_SECAPI
 }
index 0678ae7af98c3c5f18ce59220168f0baa2b9b3d7..bfbe5285ad45d164a027a6c8890ecf5a39811f1b 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2002-2010 Apple Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2002-2013 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -27,6 +27,8 @@
 #include <Security/SecItem.h>
 #include <Security/SecPolicy.h>
 #include <Security/SecPolicyPriv.h>
 #include <Security/SecItem.h>
 #include <Security/SecPolicy.h>
 #include <Security/SecPolicyPriv.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecCertificatePriv.h>
 #include <security_keychain/Policies.h>
 #include <security_keychain/PolicyCursor.h>
 #include "SecBridge.h"
 #include <security_keychain/Policies.h>
 #include <security_keychain/PolicyCursor.h>
 #include "SecBridge.h"
@@ -49,10 +51,20 @@ SEC_CONST_DECL (kSecPolicyApplePackageSigning, "1.2.840.113635.100.1.17");
 SEC_CONST_DECL (kSecPolicyAppleIDValidation, "1.2.840.113635.100.1.18");
 SEC_CONST_DECL (kSecPolicyMacAppStoreReceipt, "1.2.840.113635.100.1.19");
 SEC_CONST_DECL (kSecPolicyAppleTimeStamping, "1.2.840.113635.100.1.20");
 SEC_CONST_DECL (kSecPolicyAppleIDValidation, "1.2.840.113635.100.1.18");
 SEC_CONST_DECL (kSecPolicyMacAppStoreReceipt, "1.2.840.113635.100.1.19");
 SEC_CONST_DECL (kSecPolicyAppleTimeStamping, "1.2.840.113635.100.1.20");
+SEC_CONST_DECL (kSecPolicyAppleRevocation, "1.2.840.113635.100.1.21");
+SEC_CONST_DECL (kSecPolicyApplePassbookSigning, "1.2.840.113635.100.1.22");
+SEC_CONST_DECL (kSecPolicyAppleMobileStore, "1.2.840.113635.100.1.23");
+SEC_CONST_DECL (kSecPolicyAppleEscrowService, "1.2.840.113635.100.1.24");
+SEC_CONST_DECL (kSecPolicyAppleProfileSigner, "1.2.840.113635.100.1.25");
+SEC_CONST_DECL (kSecPolicyAppleQAProfileSigner, "1.2.840.113635.100.1.26");
+SEC_CONST_DECL (kSecPolicyAppleTestMobileStore, "1.2.840.113635.100.1.27");
+
 
 SEC_CONST_DECL (kSecPolicyOid, "SecPolicyOid");
 SEC_CONST_DECL (kSecPolicyName, "SecPolicyName");
 SEC_CONST_DECL (kSecPolicyClient, "SecPolicyClient");
 
 SEC_CONST_DECL (kSecPolicyOid, "SecPolicyOid");
 SEC_CONST_DECL (kSecPolicyName, "SecPolicyName");
 SEC_CONST_DECL (kSecPolicyClient, "SecPolicyClient");
+SEC_CONST_DECL (kSecPolicyRevocationFlags, "SecPolicyRevocationFlags");
+SEC_CONST_DECL (kSecPolicyTeamIdentifier, "SecPolicyTeamIdentifier");
 
 SEC_CONST_DECL (kSecPolicyKU_DigitalSignature, "CE_KU_DigitalSignature");
 SEC_CONST_DECL (kSecPolicyKU_NonRepudiation, "CE_KU_NonRepudiation");
 
 SEC_CONST_DECL (kSecPolicyKU_DigitalSignature, "CE_KU_DigitalSignature");
 SEC_CONST_DECL (kSecPolicyKU_NonRepudiation, "CE_KU_NonRepudiation");
@@ -64,6 +76,11 @@ SEC_CONST_DECL (kSecPolicyKU_CRLSign, "CE_KU_CRLSign");
 SEC_CONST_DECL (kSecPolicyKU_EncipherOnly, "CE_KU_EncipherOnly");
 SEC_CONST_DECL (kSecPolicyKU_DecipherOnly, "CE_KU_DecipherOnly");
 
 SEC_CONST_DECL (kSecPolicyKU_EncipherOnly, "CE_KU_EncipherOnly");
 SEC_CONST_DECL (kSecPolicyKU_DecipherOnly, "CE_KU_DecipherOnly");
 
+// Private functions
+
+SecPolicyRef SecPolicyCreateWithSecAsn1Oid(SecAsn1Oid *oidPtr);
+extern "C" { CFArrayRef SecPolicyCopyEscrowRootCertificates(void); }
+
 //
 // CF boilerplate
 //
 //
 // CF boilerplate
 //
@@ -82,16 +99,16 @@ SecPolicyGetTypeID(void)
 OSStatus
 SecPolicyGetOID(SecPolicyRef policyRef, CSSM_OID* oid)
 {
 OSStatus
 SecPolicyGetOID(SecPolicyRef policyRef, CSSM_OID* oid)
 {
-    BEGIN_SECAPI
-    Required(oid) = Policy::required(policyRef)->oid();
+       BEGIN_SECAPI
+       Required(oid) = Policy::required(policyRef)->oid();
        END_SECAPI
 }
 
 OSStatus
 SecPolicyGetValue(SecPolicyRef policyRef, CSSM_DATA* value)
 {
        END_SECAPI
 }
 
 OSStatus
 SecPolicyGetValue(SecPolicyRef policyRef, CSSM_DATA* value)
 {
-    BEGIN_SECAPI
-    Required(value) = Policy::required(policyRef)->value();
+       BEGIN_SECAPI
+       Required(value) = Policy::required(policyRef)->value();
        END_SECAPI
 }
 
        END_SECAPI
 }
 
@@ -116,8 +133,8 @@ OSStatus
 SecPolicySetValue(SecPolicyRef policyRef, const CSSM_DATA *value)
 {
        BEGIN_SECAPI
 SecPolicySetValue(SecPolicyRef policyRef, const CSSM_DATA *value)
 {
        BEGIN_SECAPI
-    Required(value);
-    const CssmData newValue(value->Data, value->Length);
+       Required(value);
+       const CssmData newValue(value->Data, value->Length);
        Policy::required(policyRef)->setValue(newValue);
        END_SECAPI
 }
        Policy::required(policyRef)->setValue(newValue);
        END_SECAPI
 }
@@ -133,15 +150,15 @@ SecPolicySetProperties(SecPolicyRef policyRef, CFDictionaryRef properties)
 OSStatus
 SecPolicyGetTPHandle(SecPolicyRef policyRef, CSSM_TP_HANDLE* tpHandle)
 {
 OSStatus
 SecPolicyGetTPHandle(SecPolicyRef policyRef, CSSM_TP_HANDLE* tpHandle)
 {
-    BEGIN_SECAPI
-    Required(tpHandle) = Policy::required(policyRef)->tp()->handle();
+       BEGIN_SECAPI
+       Required(tpHandle) = Policy::required(policyRef)->tp()->handle();
        END_SECAPI
 }
 
 OSStatus
 SecPolicyCopyAll(CSSM_CERT_TYPE certificateType, CFArrayRef* policies)
 {
        END_SECAPI
 }
 
 OSStatus
 SecPolicyCopyAll(CSSM_CERT_TYPE certificateType, CFArrayRef* policies)
 {
-    BEGIN_SECAPI
+       BEGIN_SECAPI
        Required(policies);
        CFMutableArrayRef currPolicies = NULL;
        currPolicies = CFArrayCreateMutable(NULL, 0, NULL);
        Required(policies);
        CFMutableArrayRef currPolicies = NULL;
        currPolicies = CFArrayCreateMutable(NULL, 0, NULL);
@@ -166,10 +183,10 @@ SecPolicyCopy(CSSM_CERT_TYPE certificateType, const CSSM_OID *policyOID, SecPoli
 {
        Required(policy);
        Required(policyOID);
 {
        Required(policy);
        Required(policyOID);
-       
+
        SecPolicySearchRef srchRef = NULL;
        OSStatus ortn;
        SecPolicySearchRef srchRef = NULL;
        OSStatus ortn;
-       
+
        ortn = SecPolicySearchCreate(certificateType, policyOID, NULL, &srchRef);
        if(ortn) {
                return ortn;
        ortn = SecPolicySearchCreate(certificateType, policyOID, NULL, &srchRef);
        if(ortn) {
                return ortn;
@@ -183,51 +200,50 @@ SecPolicyCopy(CSSM_CERT_TYPE certificateType, const CSSM_OID *policyOID, SecPoli
 SecPolicyRef
 SecPolicyCreateBasicX509(void)
 {
 SecPolicyRef
 SecPolicyCreateBasicX509(void)
 {
-    // return a SecPolicyRef object for the X.509 Basic policy
-    SecPolicyRef policy = nil;
-    SecPolicySearchRef policySearch = nil;
-    OSStatus status = SecPolicySearchCreate(CSSM_CERT_X_509v3, &CSSMOID_APPLE_X509_BASIC, NULL, &policySearch);
-    if (!status) {
-        status = SecPolicySearchCopyNext(policySearch, &policy);
-    }
+       // return a SecPolicyRef object for the X.509 Basic policy
+       SecPolicyRef policy = nil;
+       SecPolicySearchRef policySearch = nil;
+       OSStatus status = SecPolicySearchCreate(CSSM_CERT_X_509v3, &CSSMOID_APPLE_X509_BASIC, NULL, &policySearch);
+       if (!status) {
+               status = SecPolicySearchCopyNext(policySearch, &policy);
+       }
        if (policySearch) {
                CFRelease(policySearch);
        }
        if (policySearch) {
                CFRelease(policySearch);
        }
-    return policy;
+       return policy;
 }
 
 /* new in 10.6 */
 SecPolicyRef
 SecPolicyCreateSSL(Boolean server, CFStringRef hostname)
 {
 }
 
 /* new in 10.6 */
 SecPolicyRef
 SecPolicyCreateSSL(Boolean server, CFStringRef hostname)
 {
-    // return a SecPolicyRef object for the SSL policy, given hostname and client options
-    SecPolicyRef policy = nil;
-    SecPolicySearchRef policySearch = nil;
-    OSStatus status = SecPolicySearchCreate(CSSM_CERT_X_509v3, &CSSMOID_APPLE_TP_SSL, NULL, &policySearch);
-    if (!status) {
-        status = SecPolicySearchCopyNext(policySearch, &policy);
-    }
-    if (!status && policy) {
-        // set options for client-side or server-side policy evaluation
+       // return a SecPolicyRef object for the SSL policy, given hostname and client options
+       SecPolicyRef policy = nil;
+       SecPolicySearchRef policySearch = nil;
+       OSStatus status = SecPolicySearchCreate(CSSM_CERT_X_509v3, &CSSMOID_APPLE_TP_SSL, NULL, &policySearch);
+       if (!status) {
+               status = SecPolicySearchCopyNext(policySearch, &policy);
+       }
+       if (!status && policy) {
+               // set options for client-side or server-side policy evaluation
                char *strbuf = NULL;
                const char *hostnamestr = NULL;
                if (hostname) {
                char *strbuf = NULL;
                const char *hostnamestr = NULL;
                if (hostname) {
-                       CFIndex strbuflen = 0;
                        hostnamestr = CFStringGetCStringPtr(hostname, kCFStringEncodingUTF8);
                        if (hostnamestr == NULL) {
                        hostnamestr = CFStringGetCStringPtr(hostname, kCFStringEncodingUTF8);
                        if (hostnamestr == NULL) {
-                               strbuflen = CFStringGetLength(hostname)*6;
-                               strbuf = (char *)malloc(strbuflen+1);
-                               if (CFStringGetCString(hostname, strbuf, strbuflen, kCFStringEncodingUTF8)) {
+                CFIndex maxLen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(hostname), kCFStringEncodingUTF8) + 1;
+                               strbuf = (char *)malloc(maxLen);
+                               if (CFStringGetCString(hostname, strbuf, maxLen, kCFStringEncodingUTF8)) {
                                        hostnamestr = strbuf;
                                }
                        }
                }
                                        hostnamestr = strbuf;
                                }
                        }
                }
-        uint32 hostnamelen = (hostnamestr) ? strlen(hostnamestr) : 0;
+        uint32 hostnamelen = (hostnamestr) ? (uint32)strlen(hostnamestr) : 0;
         uint32 flags = (!server) ? CSSM_APPLE_TP_SSL_CLIENT : 0;
         CSSM_APPLE_TP_SSL_OPTIONS opts = {CSSM_APPLE_TP_SSL_OPTS_VERSION, hostnamelen, hostnamestr, flags};
         CSSM_DATA data = {sizeof(opts), (uint8*)&opts};
         SecPolicySetValue(policy, &data);
         uint32 flags = (!server) ? CSSM_APPLE_TP_SSL_CLIENT : 0;
         CSSM_APPLE_TP_SSL_OPTIONS opts = {CSSM_APPLE_TP_SSL_OPTS_VERSION, hostnamelen, hostnamestr, flags};
         CSSM_DATA data = {sizeof(opts), (uint8*)&opts};
         SecPolicySetValue(policy, &data);
-               
+
                if (strbuf) {
                        free(strbuf);
                }
                if (strbuf) {
                        free(strbuf);
                }
@@ -235,37 +251,61 @@ SecPolicyCreateSSL(Boolean server, CFStringRef hostname)
        if (policySearch) {
                CFRelease(policySearch);
        }
        if (policySearch) {
                CFRelease(policySearch);
        }
-    return policy;
+       return policy;
+}
+
+SecPolicyRef
+SecPolicyCreateWithSecAsn1Oid(SecAsn1Oid *oidPtr)
+{
+       SecPolicyRef policy = NULL;
+       try {
+               SecPointer<Policy> policyObj;
+               PolicyCursor::policy(oidPtr, policyObj);
+               policy = policyObj->handle();
+       }
+       catch (...) {}
+
+       return policy;
 }
 
 /* new in 10.7 */
 SecPolicyRef
 SecPolicyCreateWithOID(CFTypeRef policyOID)
 {
 }
 
 /* new in 10.7 */
 SecPolicyRef
 SecPolicyCreateWithOID(CFTypeRef policyOID)
 {
-       //%%% FIXME: allow policyOID to be a CFDataRef or a CFStringRef for an arbitrary OID
        // for now, we only accept the policy constants that are defined in SecPolicy.h
        CFStringRef oidStr = (CFStringRef)policyOID;
        CSSM_OID *oidPtr = NULL;
        SecPolicyRef policy = NULL;
        // for now, we only accept the policy constants that are defined in SecPolicy.h
        CFStringRef oidStr = (CFStringRef)policyOID;
        CSSM_OID *oidPtr = NULL;
        SecPolicyRef policy = NULL;
-       const void* oidmap[] = {
-               kSecPolicyAppleX509Basic, &CSSMOID_APPLE_X509_BASIC,
-               kSecPolicyAppleSSL, &CSSMOID_APPLE_TP_SSL,
-               kSecPolicyAppleSMIME, &CSSMOID_APPLE_TP_SMIME,
-               kSecPolicyAppleEAP, &CSSMOID_APPLE_TP_EAP,
-               kSecPolicyAppleIPsec, &CSSMOID_APPLE_TP_IP_SEC,
-               kSecPolicyAppleiChat, &CSSMOID_APPLE_TP_ICHAT,
-               kSecPolicyApplePKINITClient, &CSSMOID_APPLE_TP_PKINIT_CLIENT,
-               kSecPolicyApplePKINITServer, &CSSMOID_APPLE_TP_PKINIT_SERVER,
-               kSecPolicyAppleCodeSigning, &CSSMOID_APPLE_TP_CODE_SIGNING,
-               kSecPolicyMacAppStoreReceipt, &CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT,
-               kSecPolicyAppleIDValidation, &CSSMOID_APPLE_TP_APPLEID_SHARING,
-               kSecPolicyAppleTimeStamping, &CSSMOID_APPLE_TP_TIMESTAMPING
+       struct oidmap_entry_t {
+               const CFTypeRef oidstr;
+               const SecAsn1Oid *oidptr;
        };
        };
-       unsigned int i, oidmaplen = sizeof(oidmap) / sizeof(oidmap[0]);
-       for (i=0; i<oidmaplen*2; i+=2) {
-               CFStringRef str = (CFStringRef)oidmap[i];
+       const oidmap_entry_t oidmap[] = {
+               { kSecPolicyAppleX509Basic, &CSSMOID_APPLE_X509_BASIC },
+               { kSecPolicyAppleSSL, &CSSMOID_APPLE_TP_SSL },
+               { kSecPolicyAppleSMIME, &CSSMOID_APPLE_TP_SMIME },
+               { kSecPolicyAppleEAP, &CSSMOID_APPLE_TP_EAP },
+               { kSecPolicyAppleIPsec, &CSSMOID_APPLE_TP_IP_SEC },
+               { kSecPolicyAppleiChat, &CSSMOID_APPLE_TP_ICHAT },
+               { kSecPolicyApplePKINITClient, &CSSMOID_APPLE_TP_PKINIT_CLIENT },
+               { kSecPolicyApplePKINITServer, &CSSMOID_APPLE_TP_PKINIT_SERVER },
+               { kSecPolicyAppleCodeSigning, &CSSMOID_APPLE_TP_CODE_SIGNING },
+               { kSecPolicyMacAppStoreReceipt, &CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT },
+               { kSecPolicyAppleIDValidation, &CSSMOID_APPLE_TP_APPLEID_SHARING },
+               { kSecPolicyAppleTimeStamping, &CSSMOID_APPLE_TP_TIMESTAMPING },
+               { kSecPolicyAppleRevocation, &CSSMOID_APPLE_TP_REVOCATION },
+               { kSecPolicyApplePassbookSigning, &CSSMOID_APPLE_TP_PASSBOOK_SIGNING },
+               { kSecPolicyAppleMobileStore, &CSSMOID_APPLE_TP_MOBILE_STORE },
+               { kSecPolicyAppleEscrowService, &CSSMOID_APPLE_TP_ESCROW_SERVICE },
+               { kSecPolicyAppleProfileSigner, &CSSMOID_APPLE_TP_PROFILE_SIGNING },
+               { kSecPolicyAppleQAProfileSigner, &CSSMOID_APPLE_TP_QA_PROFILE_SIGNING },
+               { kSecPolicyAppleTestMobileStore, &CSSMOID_APPLE_TP_TEST_MOBILE_STORE },
+       };
+       unsigned int i, oidmaplen = sizeof(oidmap) / sizeof(oidmap_entry_t);
+       for (i=0; i<oidmaplen; i++) {
+               CFStringRef str = (CFStringRef) oidmap[i].oidstr;
                if (CFStringCompare(str, oidStr, 0) == kCFCompareEqualTo) {
                if (CFStringCompare(str, oidStr, 0) == kCFCompareEqualTo) {
-                       oidPtr = (CSSM_OID*)oidmap[i+1];
+                       oidPtr = (CSSM_OID*)oidmap[i].oidptr;
                        break;
                }
        }
                        break;
                }
        }
@@ -276,6 +316,41 @@ SecPolicyCreateWithOID(CFTypeRef policyOID)
                        status = SecPolicySearchCopyNext(policySearch, &policy);
                        CFRelease(policySearch);
                }
                        status = SecPolicySearchCopyNext(policySearch, &policy);
                        CFRelease(policySearch);
                }
+               if (!policy && CFEqual(policyOID, kSecPolicyAppleRevocation)) {
+                       policy = SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod);
+               }
+               if (!policy) {
+                       policy = SecPolicyCreateWithSecAsn1Oid((SecAsn1Oid*)oidPtr);
+               }
        }
        return policy;
 }
        }
        return policy;
 }
+
+/* new in 10.9 */
+SecPolicyRef
+SecPolicyCreateWithProperties(CFTypeRef policyIdentifier, CFDictionaryRef properties)
+{
+       SecPolicyRef policy = SecPolicyCreateWithOID(policyIdentifier);
+       SecPolicySetProperties(policy, properties);
+
+       return policy;
+}
+
+/* new in 10.9 */
+SecPolicyRef
+SecPolicyCreateRevocation(CFOptionFlags revocationFlags)
+{
+       // return a SecPolicyRef object for the unified revocation policy
+       SecAsn1Oid *oidPtr = (SecAsn1Oid*)&CSSMOID_APPLE_TP_REVOCATION;
+       SecPolicyRef policy = SecPolicyCreateWithSecAsn1Oid(oidPtr);
+       //%%% FIXME set policy value with revocationFlags
+
+       return policy;
+}
+
+/* new in 10.9 ***FIXME*** TO BE REMOVED */
+CFArrayRef SecPolicyCopyEscrowRootCertificates(void)
+{
+       return SecCertificateCopyEscrowRoots(kSecCertificateProductionEscrowRoot);
+}
+
index 8ed90c8bd2d1f0b52677d7dc5b64c638270ea943..d100c166a51d49970552f16921a6e7bea1c44633 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2002-2010 Apple Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2002-2013 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
 /*!
  * @APPLE_LICENSE_HEADER_END@
  */
 
 /*!
-    @header SecPolicy
-    The functions provided in SecPolicy.h provide an interface to various
+       @header SecPolicy
+       The functions provided in SecPolicy.h provide an interface to various
        X.509 certificate trust policies.
 */
 
        X.509 certificate trust policies.
 */
 
 #include <CoreFoundation/CFBase.h>
 #include <CoreFoundation/CFDictionary.h>
 #include <Security/SecBase.h>
 #include <CoreFoundation/CFBase.h>
 #include <CoreFoundation/CFDictionary.h>
 #include <Security/SecBase.h>
-#include <Security/cssmtype.h>
 
 #if defined(__cplusplus)
 extern "C" {
 #endif
 
 /*!
 
 #if defined(__cplusplus)
 extern "C" {
 #endif
 
 /*!
-    @enum Policy Constants
-    @discussion Predefined constants used to specify a policy.
+       @enum Policy Constants
+       @discussion Predefined constants used to specify a policy.
        @constant kSecPolicyAppleX509Basic
        @constant kSecPolicyAppleSSL
        @constant kSecPolicyAppleSMIME
        @constant kSecPolicyAppleX509Basic
        @constant kSecPolicyAppleSSL
        @constant kSecPolicyAppleSMIME
@@ -54,45 +53,200 @@ extern "C" {
        @constant kSecPolicyMacAppStoreReceipt
        @constant kSecPolicyAppleIDValidation
        @constant kSecPolicyAppleTimeStamping
        @constant kSecPolicyMacAppStoreReceipt
        @constant kSecPolicyAppleIDValidation
        @constant kSecPolicyAppleTimeStamping
+       @constant kSecPolicyAppleRevocation
+       @constant kSecPolicyApplePassbookSigning
 */
 extern CFTypeRef kSecPolicyAppleX509Basic
 */
 extern CFTypeRef kSecPolicyAppleX509Basic
-    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0);
 extern CFTypeRef kSecPolicyAppleSSL
 extern CFTypeRef kSecPolicyAppleSSL
-    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0);
 extern CFTypeRef kSecPolicyAppleSMIME
 extern CFTypeRef kSecPolicyAppleSMIME
-    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0);
 extern CFTypeRef kSecPolicyAppleEAP
 extern CFTypeRef kSecPolicyAppleEAP
-    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0);
 extern CFTypeRef kSecPolicyAppleIPsec
 extern CFTypeRef kSecPolicyAppleIPsec
-    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0);
 extern CFTypeRef kSecPolicyAppleiChat
 extern CFTypeRef kSecPolicyAppleiChat
-    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+    __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_7, __MAC_10_9, __IPHONE_NA, __IPHONE_NA);
 extern CFTypeRef kSecPolicyApplePKINITClient
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
 extern CFTypeRef kSecPolicyApplePKINITServer
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
 extern CFTypeRef kSecPolicyAppleCodeSigning
 extern CFTypeRef kSecPolicyApplePKINITClient
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
 extern CFTypeRef kSecPolicyApplePKINITServer
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
 extern CFTypeRef kSecPolicyAppleCodeSigning
-    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0);
 extern CFTypeRef kSecPolicyMacAppStoreReceipt
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
 extern CFTypeRef kSecPolicyAppleIDValidation
 extern CFTypeRef kSecPolicyMacAppStoreReceipt
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
 extern CFTypeRef kSecPolicyAppleIDValidation
-    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0);
 extern CFTypeRef kSecPolicyAppleTimeStamping
 extern CFTypeRef kSecPolicyAppleTimeStamping
-    __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_NA);
+    __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_7_0);
+extern CFTypeRef kSecPolicyAppleRevocation
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFTypeRef kSecPolicyApplePassbookSigning
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
 
 /*!
     @enum Policy Value Constants
 
 /*!
     @enum Policy Value Constants
-    @discussion Predefined property key constants used to get or set values in
+    @abstract Predefined property key constants used to get or set values in
         a dictionary for a policy instance.
         a dictionary for a policy instance.
-
+    @discussion
         All policies will have the following read-only value:
             kSecPolicyOid       (the policy object identifier)
 
         Additional policy values which your code can optionally set:
             kSecPolicyName      (name which must be matched)
         All policies will have the following read-only value:
             kSecPolicyOid       (the policy object identifier)
 
         Additional policy values which your code can optionally set:
             kSecPolicyName      (name which must be matched)
-            kSecPolicyClient   (evaluate for client, rather than server)
+            kSecPolicyClient    (evaluate for client, rather than server)
+            kSecPolicyRevocationFlags (only valid for a revocation policy)
+
+    @constant kSecPolicyOid Specifies the policy OID (value is a CFStringRef)
+    @constant kSecPolicyName Specifies a CFStringRef (or CFArrayRef of same)
+        containing a name which must be matched in the certificate to satisfy
+        this policy. For SSL/TLS, EAP, and IPSec policies, this specifies the
+        server name which must match the common name of the certificate.
+        For S/MIME, this specifies the RFC822 email address.
+        For Passbook signing, this specifies the pass signer.
+    @constant kSecPolicyClient Specifies a CFBooleanRef value that indicates
+        this evaluation should be for a client certificate. If not set (or
+        false), the policy evaluates the certificate as a server certificate.
+    @constant kSecPolicyRevocationFlags Specifies a CFNumberRef that holds a
+        kCFNumberCFIndexType bitmask value. See "Revocation Policy Constants"
+        for a description of individual bits in this value.
+    @constant kSecPolicyTeamIdentifier Specifies a CFStringRef containing a
+        team identifier which must be matched in the certificate to satisfy
+        this policy. For the Passbook signing policy, this string must match
+        the Organizational Unit field of the certificate subject.
+ */
+extern CFTypeRef kSecPolicyOid
+       __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0);
+extern CFTypeRef kSecPolicyName
+       __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0);
+extern CFTypeRef kSecPolicyClient
+       __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0);
+extern CFTypeRef kSecPolicyRevocationFlags
+       __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFTypeRef kSecPolicyTeamIdentifier
+       __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+
+
+/*!
+    @function SecPolicyGetTypeID
+    @abstract Returns the type identifier of SecPolicy instances.
+    @result The CFTypeID of SecPolicy instances.
+*/
+CFTypeID SecPolicyGetTypeID(void)
+       __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_2_0);
+
+/*!
+    @function SecPolicyCopyProperties
+    @abstract Returns a dictionary of this policy's properties.
+    @param policyRef A policy reference.
+    @result A properties dictionary. See "Policy Value Constants" for a list
+    of currently defined property keys. It is the caller's responsibility to
+    CFRelease this reference when it is no longer needed.
+    @result A result code. See "Security Error Codes" (SecBase.h).
+    @discussion This function returns the properties for a policy, as set by the
+    policy's construction function or by a prior call to SecPolicySetProperties.
+*/
+CFDictionaryRef SecPolicyCopyProperties(SecPolicyRef policyRef)
+       __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0);
+
+/*!
+    @function SecPolicyCreateBasicX509
+    @abstract Returns a policy object for the default X.509 policy.
+    @result A policy object. The caller is responsible for calling CFRelease
+    on this when it is no longer needed.
+*/
+SecPolicyRef SecPolicyCreateBasicX509(void)
+       __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
+
+/*!
+    @function SecPolicyCreateSSL
+    @abstract Returns a policy object for evaluating SSL certificate chains.
+    @param server Passing true for this parameter creates a policy for SSL
+    server certificates.
+    @param hostname (Optional) If present, the policy will require the specified
+    hostname to match the hostname in the leaf certificate.
+    @result A policy object. The caller is responsible for calling CFRelease
+    on this when it is no longer needed.
+*/
+SecPolicyRef SecPolicyCreateSSL(Boolean server, CFStringRef hostname)
+       __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
+
+/*!
+       @enum Revocation Policy Constants
+       @abstract Predefined constants which allow you to specify how revocation
+       checking will be performed for a trust evaluation.
+       @constant kSecRevocationOCSPMethod If this flag is set, perform revocation
+       checking using OCSP (Online Certificate Status Protocol).
+       @constant kSecRevocationCRLMethod If this flag is set, perform revocation
+       checking using the CRL (Certificate Revocation List) method.
+       @constant kSecRevocationPreferCRL If this flag is set, then CRL revocation
+       checking will be preferred over OCSP (by default, OCSP is preferred.)
+       Note that this flag only matters if both revocation methods are specified.
+       @constant kSecRevocationRequirePositiveResponse If this flag is set, then
+       the policy will fail unless a verified positive response is obtained. If
+       the flag is not set, revocation checking is done on a "best attempt" basis,
+       where failure to reach the server is not considered fatal.
+       @constant kSecRevocationNetworkAccessDisabled If this flag is set, then
+       no network access is performed; only locally cached replies are consulted.
+       @constant kSecRevocationUseAnyAvailableMethod Specifies that either
+       OCSP or CRL may be used, depending on the method(s) specified in the
+       certificate and the value of kSecRevocationPreferCRL.
+ */
+enum {
+       kSecRevocationOCSPMethod = (1 << 0),
+       kSecRevocationCRLMethod = (1 << 1),
+       kSecRevocationPreferCRL = (1 << 2),
+       kSecRevocationRequirePositiveResponse = (1 << 3),
+       kSecRevocationNetworkAccessDisabled = (1 << 4),
+       kSecRevocationUseAnyAvailableMethod = (kSecRevocationOCSPMethod |
+               kSecRevocationCRLMethod)
+};
+
+/*!
+       @function SecPolicyCreateRevocation
+       @abstract Returns a policy object for checking revocation of certificates.
+       @result A policy object. The caller is responsible for calling CFRelease
+       on this when it is no longer needed.
+       @param revocationFlags Flags to specify revocation checking options.
+       @discussion Use this function to create a revocation policy with behavior
+       specified by revocationFlags. See the "Revocation Policy Constants" section
+       for a description of these flags. Note: it is usually not necessary to
+       create a revocation policy yourself unless you wish to override default
+       system behavior (e.g. to force a particular method, or to disable
+       revocation checking entirely.)
+*/
+SecPolicyRef SecPolicyCreateRevocation(CFOptionFlags revocationFlags)
+       __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
 
 
-        Policy values may also specify CFBooleanRef key usage constraints:
+/*!
+       @function SecPolicyCreateWithProperties
+       @abstract Returns a policy object based on an object identifier for the
+       policy type. See the "Policy Constants" section for a list of defined
+       policy object identifiers.
+       @param policyIdentifier The identifier for the desired policy type.
+       @param properties (Optional) A properties dictionary. See "Policy Value
+       Constants" for a list of currently defined property keys.
+       @result The returned policy reference, or NULL if the policy could not be
+       created.
+*/
+SecPolicyRef SecPolicyCreateWithProperties(CFTypeRef policyIdentifier,
+       CFDictionaryRef properties)
+       __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+
+
+/*
+ *  Legacy functions (OS X only)
+ */
+#if TARGET_OS_MAC && !TARGET_OS_IPHONE
+#include <Security/cssmtype.h>
+
+/*!
+    @enum Policy Value Constants (OS X)
+    @discussion Predefined property key constants used to get or set values in
+        a dictionary for a policy instance.
+
+        Some policy values may specify CFBooleanRef key usage constraints:
             kSecPolicyKU_DigitalSignature
             kSecPolicyKU_NonRepudiation
             kSecPolicyKU_KeyEncipherment
             kSecPolicyKU_DigitalSignature
             kSecPolicyKU_NonRepudiation
             kSecPolicyKU_KeyEncipherment
@@ -102,33 +256,27 @@ extern CFTypeRef kSecPolicyAppleTimeStamping
             kSecPolicyKU_CRLSign
             kSecPolicyKU_EncipherOnly
             kSecPolicyKU_DecipherOnly
             kSecPolicyKU_CRLSign
             kSecPolicyKU_EncipherOnly
             kSecPolicyKU_DecipherOnly
-            
-        Note that these policy values cover certificate-level purpose
-        definitions, in contrast to the key-level definitions in
-        SecItem.h. For example, a key in a certificate might be
-        acceptable for CRL signing, but not NonRepudiation. In either
-        case, this key would definitely have (via SecItem.h) the ability
-        to sign; it is the *context* of signing that is defined further
-        in these policy constants. Similarly, a key might be able to do
-        both encryption and decryption, but the certificate in which it
-        resides might have a decipher-only certificate policy in
-        certificate A, but not in certificate B. These policy values
-        refine the key's attributes within the context of the
-        certificate.
-        
-        They correspond to values defined in RFC 5280, section 4.2.1.3
-        (Key Usage) which define the purpose of a key contained in a
-        certificate, in contrast to section 4.1.2.7 which define what a
-        key is capable of.
-    @constant kSecPolicyOid Specifies the policy OID (value is a CFStringRef)
-    @constant kSecPolicyName Specifies a CFStringRef containing a name which
-        must be matched in the certificate to satisfy this policy. For SSL/TLS,
-        this specifies the server name which must match the common name of the
-        certificate. For S/MIME, this specifies the RFC822 email address.
-    @constant kSecPolicyClient Specifies a CFBooleanRef value that indicates
-        this evaluation should be for a client certificate. If not set (or
-        false), the policy evaluates the certificate for the server.
+
+        kSecPolicyKU policy values define certificate-level key purposes,
+        in contrast to the key-level definitions in SecItem.h
+
+        For example, a key in a certificate might be acceptable to use for
+        signing a CRL, but not for signing another certificate. In either
+        case, this key would have the ability to sign (i.e. kSecAttrCanSign
+        is true), but may only sign for specific purposes allowed by these
+        policy constants. Similarly, a public key might have the capability
+        to perform encryption or decryption, but the certificate in which it
+        resides might have a decipher-only certificate policy.
+
+        These constants correspond to values defined in RFC 5280, section
+        4.2.1.3 (Key Usage) which define the purpose of a key contained in a
+        certificate, in contrast to section 4.1.2.7 which define the uses that
+        a key is capable of.
+
+        Note: these constants are not available on iOS. Your code should
+        avoid direct reliance on these values for making policy decisions
+        and use higher level policies where possible.
+
     @constant kSecPolicyKU_DigitalSignature Specifies that the certificate must
         have a key usage that allows it to be used for signing.
     @constant kSecPolicyKU_NonRepudiation Specifies that the certificate must
     @constant kSecPolicyKU_DigitalSignature Specifies that the certificate must
         have a key usage that allows it to be used for signing.
     @constant kSecPolicyKU_NonRepudiation Specifies that the certificate must
@@ -147,14 +295,7 @@ extern CFTypeRef kSecPolicyAppleTimeStamping
         have a key usage that permits it to be used for encryption only.
     @constant kSecPolicyKU_DecipherOnly Specifies that the certificate must
         have a key usage that permits it to be used for decryption only.
         have a key usage that permits it to be used for encryption only.
     @constant kSecPolicyKU_DecipherOnly Specifies that the certificate must
         have a key usage that permits it to be used for decryption only.
-*/
-extern CFTypeRef kSecPolicyOid
-    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
-extern CFTypeRef kSecPolicyName
-       __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
-extern CFTypeRef kSecPolicyClient
-       __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
-
+ */
 extern CFTypeRef kSecPolicyKU_DigitalSignature
        __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
 extern CFTypeRef kSecPolicyKU_NonRepudiation
 extern CFTypeRef kSecPolicyKU_DigitalSignature
        __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
 extern CFTypeRef kSecPolicyKU_NonRepudiation
@@ -174,124 +315,90 @@ extern CFTypeRef kSecPolicyKU_EncipherOnly
 extern CFTypeRef kSecPolicyKU_DecipherOnly
        __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
 
 extern CFTypeRef kSecPolicyKU_DecipherOnly
        __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
 
-
 /*!
 /*!
-    @function SecPolicyGetTypeID
-    @abstract Returns the type identifier of SecPolicy instances.
-    @result The CFTypeID of SecPolicy instances.
+       @function SecPolicyCreateWithOID
+       @abstract Returns a policy object based on an object identifier for the
+       policy type. See the "Policy Constants" section for a list of defined
+       policy object identifiers.
+       @param policyOID The OID of the desired policy.
+       @result The returned policy reference, or NULL if the policy could not be
+       created.
+       @discussion This function is deprecated in Mac OS X 10.9 and later;
+       use SecPolicyCreateWithProperties (or a more specific policy creation
+       function) instead.
 */
 */
-CFTypeID SecPolicyGetTypeID(void)
-    __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_2_0);
+SecPolicyRef SecPolicyCreateWithOID(CFTypeRef policyOID)
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_7, __MAC_10_9, __IPHONE_NA, __IPHONE_NA);
 
 /*!
 
 /*!
-    @function SecPolicyGetOID
-    @abstract Returns a policy's object identifier.
-    @param policyRef A policy reference.
-    @param oid On return, a pointer to the policy's object identifier.
-    @result A result code. See "Security Error Codes" (SecBase.h).
+       @function SecPolicyGetOID
+       @abstract Returns a policy's object identifier.
+       @param policyRef A policy reference.
+       @param oid On return, a pointer to the policy's object identifier.
+       @result A result code. See "Security Error Codes" (SecBase.h).
        @discussion This function is deprecated in Mac OS X 10.7 and later;
        use SecPolicyCopyProperties instead.
 */
 OSStatus SecPolicyGetOID(SecPolicyRef policyRef, CSSM_OID *oid)
        @discussion This function is deprecated in Mac OS X 10.7 and later;
        use SecPolicyCopyProperties instead.
 */
 OSStatus SecPolicyGetOID(SecPolicyRef policyRef, CSSM_OID *oid)
-       DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA);
 
 /*!
 
 /*!
-    @function SecPolicyGetValue
-    @abstract Returns a policy's value.
-    @param policyRef A policy reference.
-    @param value On return, a pointer to the policy's value.
-    @result A result code. See "Security Error Codes" (SecBase.h).
+       @function SecPolicyGetValue
+       @abstract Returns a policy's value.
+       @param policyRef A policy reference.
+       @param value On return, a pointer to the policy's value.
+       @result A result code. See "Security Error Codes" (SecBase.h).
        @discussion This function is deprecated in Mac OS X 10.7 and later;
        use SecPolicyCopyProperties instead.
 */
 OSStatus SecPolicyGetValue(SecPolicyRef policyRef, CSSM_DATA *value)
        @discussion This function is deprecated in Mac OS X 10.7 and later;
        use SecPolicyCopyProperties instead.
 */
 OSStatus SecPolicyGetValue(SecPolicyRef policyRef, CSSM_DATA *value)
-       DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA);
 
 /*!
 
 /*!
-    @function SecPolicyCopyProperties
-    @abstract Returns a dictionary of this policy's properties.
-    @param policyRef A policy reference.
-    @result A properties dictionary. See "Policy Value Constants" for a list
-    of currently defined property keys. It is the caller's responsibility to
-    CFRelease this reference when it is no longer needed.
-    @result A result code. See "Security Error Codes" (SecBase.h).
-       @discussion This function returns the properties for a policy, as set by the
-       policy's construction function or by a prior call to SecPolicySetProperties.
-*/
-CFDictionaryRef SecPolicyCopyProperties(SecPolicyRef policyRef)
-    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
-
-/*!
-    @function SecPolicySetValue
-    @abstract Sets a policy's value.
-    @param policyRef A policy reference.
-    @param value The value to be set into the policy object, replacing any
+       @function SecPolicySetValue
+       @abstract Sets a policy's value.
+       @param policyRef A policy reference.
+       @param value The value to be set into the policy object, replacing any
        previous value.
        previous value.
-    @result A result code. See "Security Error Codes" (SecBase.h).
-       @discussion This function is deprecated in Mac OS X 10.7 and later;
-       use SecPolicySetProperties instead.
+       @result A result code. See "Security Error Codes" (SecBase.h).
+       @discussion This function is deprecated in Mac OS X 10.7 and later. Policy
+       instances should be considered read-only; in cases where your code would
+       consider changing properties of a policy, it should instead create a new
+       policy instance with the desired properties.
 */
 OSStatus SecPolicySetValue(SecPolicyRef policyRef, const CSSM_DATA *value)
 */
 OSStatus SecPolicySetValue(SecPolicyRef policyRef, const CSSM_DATA *value)
-       DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA);
 
 /*!
 
 /*!
-    @function SecPolicySetProperties
-    @abstract Sets a policy's properties.
-    @param policyRef A policy reference.
-    @param properties A properties dictionary. See "Policy Value Constants"
-    for a list of currently defined property keys. This dictionary replaces the
-    policy's existing properties, if any. Note that the policy OID (specified
-    by kSecPolicyOid) is a read-only property of the policy and cannot be set.
-    @result A result code. See "Security Error Codes" (SecBase.h).
+       @function SecPolicySetProperties
+       @abstract Sets a policy's properties.
+       @param policyRef A policy reference.
+       @param properties A properties dictionary. See "Policy Value Constants"
+       for a list of currently defined property keys. This dictionary replaces the
+       policy's existing properties, if any. Note that the policy OID (specified
+       by kSecPolicyOid) is a read-only property of the policy and cannot be set.
+       @result A result code. See "Security Error Codes" (SecBase.h).
+       @discussion This function is deprecated in Mac OS X 10.9 and later. Policy
+       instances should be considered read-only; in cases where your code would
+       consider changing properties of a policy, it should instead create a new
+       policy instance with the desired properties.
 */
 OSStatus SecPolicySetProperties(SecPolicyRef policyRef,
        CFDictionaryRef properties)
 */
 OSStatus SecPolicySetProperties(SecPolicyRef policyRef,
        CFDictionaryRef properties)
-    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_7, __MAC_10_9, __IPHONE_NA, __IPHONE_NA);
 
 /*!
 
 /*!
-    @function SecPolicyGetTPHandle
-    @abstract Returns the CSSM trust policy handle for the given policy.
-    @param policyRef A policy reference.
-    @param tpHandle On return, a pointer to a value of type CSSM_TP_HANDLE.
-    @result A result code. See "Security Error Codes" (SecBase.h).
+       @function SecPolicyGetTPHandle
+       @abstract Returns the CSSM trust policy handle for the given policy.
+       @param policyRef A policy reference.
+       @param tpHandle On return, a pointer to a value of type CSSM_TP_HANDLE.
+       @result A result code. See "Security Error Codes" (SecBase.h).
        @discussion This function is deprecated in Mac OS X 10.7 and later.
 */
 OSStatus SecPolicyGetTPHandle(SecPolicyRef policyRef, CSSM_TP_HANDLE *tpHandle)
        @discussion This function is deprecated in Mac OS X 10.7 and later.
 */
 OSStatus SecPolicyGetTPHandle(SecPolicyRef policyRef, CSSM_TP_HANDLE *tpHandle)
-       DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-
-/*!
-    @function SecPolicyCreateBasicX509
-    @abstract Returns a policy object for the default X.509 policy.
-    @result A policy object. The caller is responsible for calling CFRelease
-       on this when it is no longer needed.
-*/
-SecPolicyRef SecPolicyCreateBasicX509(void)
-    __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
-
-/*!
-    @function SecPolicyCreateSSL
-    @abstract Returns a policy object for evaluating SSL certificate chains.
-       @param server Passing true for this parameter creates a policy for SSL
-       server certificates.
-       @param hostname (Optional) If present, the policy will require the specified
-       hostname to match the hostname in the leaf certificate.
-    @result A policy object. The caller is responsible for calling CFRelease
-       on this when it is no longer needed.
-*/
-SecPolicyRef SecPolicyCreateSSL(Boolean server, CFStringRef hostname)
-    __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA);
 
 
-/*!
-       @function SecPolicyCreateWithOID
-       @abstract Returns a policy object based on an object identifier for the
-       policy type. See the "Policy Constants" section for a list of defined
-       policy object identifiers.
-    @param policyOID The OID of the desired policy.
-       @result The returned policy reference, or NULL if the policy could not be
-       created.
-*/
-SecPolicyRef SecPolicyCreateWithOID(CFTypeRef policyOID)
-    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0);
+#endif /* TARGET_OS_MAC && !TARGET_OS_IPHONE */
 
 
 #if defined(__cplusplus)
 
 
 #if defined(__cplusplus)
index 95a10a51d1d61400cac7778878c3528297fa4db4..cdc6fd8c2c9f2f9c74fed5cd80666def582ecfe5 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2003-2010 Apple Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2003-2013 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
 /*!
  * @APPLE_LICENSE_HEADER_END@
  */
 
 /*!
-       @header SecPolicy
-       The functions provided in SecPolicy implement a representation of a particular trust policy.
+       @header SecPolicyPriv
+       Private part of SecPolicy.h
 */
 
 #ifndef _SECURITY_SECPOLICYPRIV_H_
 */
 
 #ifndef _SECURITY_SECPOLICYPRIV_H_
 extern "C" {
 #endif
 
 extern "C" {
 #endif
 
+/*!
+       @enum Policy Constants (Private)
+       @discussion Predefined constants used to specify a policy.
+       @constant kSecPolicyAppleMobileStore
+       @constant kSecPolicyAppleEscrowService
+       @constant kSecPolicyAppleProfileSigner
+       @constant kSecPolicyAppleQAProfileSigner
+       @constant kSecPolicyAppleTestMobileStore
+
+*/
+extern CFTypeRef kSecPolicyAppleMobileStore
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFTypeRef kSecPolicyAppleEscrowService
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFTypeRef kSecPolicyAppleProfileSigner
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFTypeRef kSecPolicyAppleQAProfileSigner
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFTypeRef kSecPolicyAppleTestMobileStore
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+
 /*!
        @function SecPolicyCopy
        @abstract Returns a copy of a policy reference based on certificate type and OID.
 /*!
        @function SecPolicyCopy
        @abstract Returns a copy of a policy reference based on certificate type and OID.
@@ -48,7 +69,7 @@ extern "C" {
        to obtain a policy reference, use one of the SecPolicyCreate* functions in SecPolicy.h.
 */
 OSStatus SecPolicyCopy(CSSM_CERT_TYPE certificateType, const CSSM_OID *policyOID, SecPolicyRef* policy)
        to obtain a policy reference, use one of the SecPolicyCreate* functions in SecPolicy.h.
 */
 OSStatus SecPolicyCopy(CSSM_CERT_TYPE certificateType, const CSSM_OID *policyOID, SecPolicyRef* policy)
-       DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3, __MAC_10_7, __IPHONE_NA, __IPHONE_NA);
 
 /*!
        @function SecPolicyCopyAll
 
 /*!
        @function SecPolicyCopyAll
@@ -63,7 +84,8 @@ OSStatus SecPolicyCopy(CSSM_CERT_TYPE certificateType, const CSSM_OID *policyOID
        for each desired policy from the list of supported OID constants in SecPolicy.h.)
 */
 OSStatus SecPolicyCopyAll(CSSM_CERT_TYPE certificateType, CFArrayRef* policies)
        for each desired policy from the list of supported OID constants in SecPolicy.h.)
 */
 OSStatus SecPolicyCopyAll(CSSM_CERT_TYPE certificateType, CFArrayRef* policies)
-       DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3, __MAC_10_7, __IPHONE_NA, __IPHONE_NA);
+
 
 #if defined(__cplusplus)
 }
 
 #if defined(__cplusplus)
 }
index c4899e9817ad2852a9b72f4ba35099ff48ed5f38..a97a60d3e7d5fac660bfafcb251700150e728ce1 100644 (file)
 extern "C" {
 #endif
 
 extern "C" {
 #endif
 
-typedef struct SecRSAPublicKeyParams {
-       uint8_t             *modulus;                   /* modulus */
-       CFIndex             modulusLength;
-       uint8_t             *exponent;                  /* public exponent */
-       CFIndex             exponentLength;
-} SecRSAPublicKeyParams;
-
 /* Given an RSA public key in encoded form return a SecKeyRef representing
    that key. Supported encodings are kSecKeyEncodingPkcs1. */
 SecKeyRef SecKeyCreateRSAPublicKey(CFAllocatorRef allocator,
 /* Given an RSA public key in encoded form return a SecKeyRef representing
    that key. Supported encodings are kSecKeyEncodingPkcs1. */
 SecKeyRef SecKeyCreateRSAPublicKey(CFAllocatorRef allocator,
index 2996866a2756086eb884b80e06a678426b1b1133..f52d979a45e5085d7df4000120d9bdb5f74060d7 100644 (file)
  * SecFramework.c - generic non API class specific functions
  */
 
  * SecFramework.c - generic non API class specific functions
  */
 
-#define SEC_BUILDER
+#define SEC_BUILDER 1
 
 //#include "SecFramework.h"
 #include <strings.h>
 #include <CoreFoundation/CFBundle.h>
 #include <CoreFoundation/CFURLAccess.h>
 
 //#include "SecFramework.h"
 #include <strings.h>
 #include <CoreFoundation/CFBundle.h>
 #include <CoreFoundation/CFURLAccess.h>
-#include "SecRandom.h"
-#include "/usr/local/include/CommonCrypto/CommonRandomSPI.h"
+#include "SecRandomP.h"
+#include <CommonCrypto/CommonRandomSPI.h>
 #include <stdlib.h>
 #include <stdlib.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 
 /* Default random ref for /dev/random. */
 const SecRandomRef kSecRandomDefault = NULL;
 
 /* Default random ref for /dev/random. */
 const SecRandomRef kSecRandomDefault = NULL;
@@ -42,7 +41,7 @@ const SecRandomRef kSecRandomDefault = NULL;
 
 int SecRandomCopyBytes(SecRandomRef rnd, size_t count, uint8_t *bytes) {
     if (rnd != kSecRandomDefault)
 
 int SecRandomCopyBytes(SecRandomRef rnd, size_t count, uint8_t *bytes) {
     if (rnd != kSecRandomDefault)
-        return paramErr;
+        return errSecParam;
     return CCRandomCopyBytes(kCCRandomDefault, bytes, count);
 }
 
     return CCRandomCopyBytes(kCCRandomDefault, bytes, count);
 }
 
index 12bf5062951856fd9a39cc572f54c56c59cb53cd..f59c09759147076a62fff41f62af9bebe907b336 100644 (file)
@@ -129,8 +129,6 @@ static void secNormalize(CFMutableStringRef theString, CFLocaleRef theLocale)
 #define RETURN_KEY_SIZE 16
 #define MAXANSWERBUFF 4096
 #define PBKDF_ROUNDS 100000
 #define RETURN_KEY_SIZE 16
 #define MAXANSWERBUFF 4096
 #define PBKDF_ROUNDS 100000
-static uint8_t salt[16] = { 0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x1F };
-static int saltLen = sizeof(salt);
 
 static SecKeyRef secDeriveKeyFromAnswers(CFArrayRef answers, CFLocaleRef theLocale)
 {
 
 static SecKeyRef secDeriveKeyFromAnswers(CFArrayRef answers, CFLocaleRef theLocale)
 {
@@ -235,7 +233,7 @@ digestString(CFStringRef str)
 static CFDataRef
 b64encode(CFDataRef input)
 {
 static CFDataRef
 b64encode(CFDataRef input)
 {
-       CFDataRef retval;
+       CFDataRef retval = NULL;
     CFErrorRef error = NULL;
        SecTransformRef encodeTrans = SecEncodeTransformCreate(kSecBase64Encoding, &error);
     if(error == NULL) SecTransformSetAttribute(encodeTrans, kSecTransformInputAttributeName, input, &error);
     CFErrorRef error = NULL;
        SecTransformRef encodeTrans = SecEncodeTransformCreate(kSecBase64Encoding, &error);
     if(error == NULL) SecTransformSetAttribute(encodeTrans, kSecTransformInputAttributeName, input, &error);
@@ -247,7 +245,7 @@ b64encode(CFDataRef input)
 static CFDataRef
 b64decode(CFDataRef input)
 {
 static CFDataRef
 b64decode(CFDataRef input)
 {
-       CFDataRef retval;
+       CFDataRef retval = NULL;
     CFErrorRef error = NULL;
        SecTransformRef decodeTrans = SecDecodeTransformCreate(kSecBase64Encoding, &error);
     if(error == NULL) SecTransformSetAttribute(decodeTrans, kSecTransformInputAttributeName, input, &error);
     CFErrorRef error = NULL;
        SecTransformRef decodeTrans = SecDecodeTransformCreate(kSecBase64Encoding, &error);
     if(error == NULL) SecTransformSetAttribute(decodeTrans, kSecTransformInputAttributeName, input, &error);
@@ -351,7 +349,7 @@ SecWrapRecoveryPasswordWithAnswers(CFStringRef password, CFArrayRef questions, C
        CFLocaleRef theLocale = CFLocaleCopyCurrent();
     CFStringRef theLocaleString = CFLocaleGetIdentifier(theLocale);
     
        CFLocaleRef theLocale = CFLocaleCopyCurrent();
     CFStringRef theLocaleString = CFLocaleGetIdentifier(theLocale);
     
-    int ix, limit;
+    CFIndex ix, limit;
     
     if (!password || !questions || !answers)
                return NULL;
     
     if (!password || !questions || !answers)
                return NULL;
@@ -442,7 +440,7 @@ SecUnwrapRecoveryPasswordWithAnswers(CFDictionaryRef recref, CFArrayRef answers)
  */
  
 CFStringRef 
  */
  
 CFStringRef 
-SecCreateRecoveryPassword()
+SecCreateRecoveryPassword(void)
 {
        CFStringRef result = NULL;
        CFErrorRef error = NULL;
 {
        CFStringRef result = NULL;
        CFErrorRef error = NULL;
index 6981c246bddf07b1eba6a74c073c194eb8d5a0c5..fdc8d1c8009664ba7b3c403a38a330792e1f85dd 100644 (file)
@@ -92,7 +92,7 @@ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
 */
     
 CFStringRef
 */
     
 CFStringRef
-SecCreateRecoveryPassword()
+SecCreateRecoveryPassword(void)
 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); 
 
 
 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); 
 
 
index 2f021da4d6030f06159732d2bac276924179e8c3..be9b7000c426d932ba4810a191dd2e4f9cc6f2d8 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2002-2010 Apple Inc. All Rights Reserved.
+ * Copyright (c) 2002-2010,2012 Apple Inc. All Rights Reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 #include "Trust.h"
 #include <security_keychain/SecTrustSettingsPriv.h>
 #include "SecBridge.h"
 #include "Trust.h"
 #include <security_keychain/SecTrustSettingsPriv.h>
 #include "SecBridge.h"
+#include "SecInternal.h"
 #include "SecTrustSettings.h"
 #include "SecCertificatePriv.h"
 #include <security_utilities/cfutilities.h>
 #include "SecTrustSettings.h"
 #include "SecCertificatePriv.h"
 #include <security_utilities/cfutilities.h>
+#include <security_utilities/cfmunge.h>
 #include <CoreFoundation/CoreFoundation.h>
 
 #include <CoreFoundation/CoreFoundation.h>
 
+// forward declarations
+CFArrayRef SecTrustCopyDetails(SecTrustRef trust);
+static CFDictionaryRef SecTrustGetExceptionForCertificateAtIndex(SecTrustRef trust, CFIndex ix);
+static void SecTrustCheckException(const void *key, const void *value, void *context);
+
+typedef struct SecTrustCheckExceptionContext {
+       CFDictionaryRef exception;
+       bool exceptionNotFound;
+} SecTrustCheckExceptionContext;
+
+// public trust result constants
+CFTypeRef kSecTrustEvaluationDate           = CFSTR("TrustEvaluationDate");
+CFTypeRef kSecTrustExtendedValidation       = CFSTR("TrustExtendedValidation");
+CFTypeRef kSecTrustOrganizationName         = CFSTR("Organization");
+CFTypeRef kSecTrustResultValue              = CFSTR("TrustResultValue");
+CFTypeRef kSecTrustRevocationChecked        = CFSTR("TrustRevocationChecked");
+CFTypeRef kSecTrustRevocationValidUntilDate = CFSTR("TrustExpirationDate");
+CFTypeRef kSecTrustResultDetails            = CFSTR("TrustResultDetails");
 
 //
 // CF boilerplate
 
 //
 // CF boilerplate
@@ -49,14 +69,14 @@ CFTypeID SecTrustGetTypeID(void)
 // Sec* API bridge functions
 //
 OSStatus SecTrustCreateWithCertificates(
 // Sec* API bridge functions
 //
 OSStatus SecTrustCreateWithCertificates(
-       CFArrayRef certificates,
+       CFTypeRef certificates,
        CFTypeRef policies,
        SecTrustRef *trustRef)
 {
        CFTypeRef policies,
        SecTrustRef *trustRef)
 {
-    BEGIN_SECAPI
+       BEGIN_SECAPI
        Required(trustRef);
        Required(trustRef);
-    *trustRef = (new Trust(certificates, policies))->handle();
-    END_SECAPI
+       *trustRef = (new Trust(certificates, policies))->handle();
+       END_SECAPI
 }
 
 OSStatus
 }
 
 OSStatus
@@ -115,16 +135,16 @@ OSStatus SecTrustSetAnchorCertificatesOnly(SecTrustRef trust, Boolean anchorCert
 
 OSStatus SecTrustSetKeychains(SecTrustRef trust, CFTypeRef keychainOrArray)
 {
 
 OSStatus SecTrustSetKeychains(SecTrustRef trust, CFTypeRef keychainOrArray)
 {
-    BEGIN_SECAPI
-       StorageManager::KeychainList keychains;
+       BEGIN_SECAPI
+               StorageManager::KeychainList keychains;
        // avoid unnecessary global initializations if an empty array is passed in
        if (!( (keychainOrArray != NULL) &&
        // avoid unnecessary global initializations if an empty array is passed in
        if (!( (keychainOrArray != NULL) &&
-              (CFGetTypeID(keychainOrArray) == CFArrayGetTypeID()) &&
-              (CFArrayGetCount((CFArrayRef)keychainOrArray) == 0) )) {
+                               (CFGetTypeID(keychainOrArray) == CFArrayGetTypeID()) &&
+                               (CFArrayGetCount((CFArrayRef)keychainOrArray) == 0) )) {
                globals().storageManager.optionalSearchList(keychainOrArray, keychains);
        }
                globals().storageManager.optionalSearchList(keychainOrArray, keychains);
        }
-    Trust::required(trust)->searchLibs(keychains);
-    END_SECAPI
+       Trust::required(trust)->searchLibs(keychains);
+       END_SECAPI
 }
 
 
 }
 
 
@@ -139,30 +159,74 @@ OSStatus SecTrustSetVerifyDate(SecTrustRef trust, CFDateRef verifyDate)
 CFAbsoluteTime SecTrustGetVerifyTime(SecTrustRef trust)
 {
        CFAbsoluteTime verifyTime = 0;
 CFAbsoluteTime SecTrustGetVerifyTime(SecTrustRef trust)
 {
        CFAbsoluteTime verifyTime = 0;
-    OSStatus __secapiresult;
+       OSStatus __secapiresult = errSecSuccess;
        try {
                CFRef<CFDateRef> verifyDate = Trust::required(trust)->time();
                verifyTime = CFDateGetAbsoluteTime(verifyDate);
        try {
                CFRef<CFDateRef> verifyDate = Trust::required(trust)->time();
                verifyTime = CFDateGetAbsoluteTime(verifyDate);
-
-               __secapiresult=noErr;
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
-       catch (const std::bad_alloc &) { __secapiresult=memFullErr; }
-       catch (...) { __secapiresult=internalComponentErr; }
-    return verifyTime;
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
+       catch (...) { __secapiresult=errSecInternalComponent; }
+       return verifyTime;
 }
 
 }
 
-OSStatus SecTrustEvaluate(SecTrustRef trustRef, SecTrustResultType *resultP)
+
+
+OSStatus SecTrustEvaluate(SecTrustRef trust, SecTrustResultType *resultP)
 {
 {
-    BEGIN_SECAPI
-    Trust *trust = Trust::required(trustRef);
-    trust->evaluate();
-    if (resultP) {
-        *resultP = trust->result();
-        secdebug("SecTrustEvaluate", "SecTrustEvaluate trust result = %d", (int)*resultP);
-    }
-    END_SECAPI
+       SecTrustResultType trustResult = kSecTrustResultInvalid;
+       CFArrayRef exceptions = NULL;
+       OSStatus __secapiresult = errSecSuccess;
+       try {
+               Trust *trustObj = Trust::required(trust);
+               trustObj->evaluate();
+               trustResult = trustObj->result();
+               exceptions = trustObj->exceptions();
+       }
+       catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
+       catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
+       catch (...) { __secapiresult=errSecInternalComponent; }
+
+       if (__secapiresult) {
+               return __secapiresult;
+       }
+
+       /* post-process trust result based on exceptions */
+       if (trustResult == kSecTrustResultUnspecified) {
+               /* If leaf is in exceptions -> proceed, otherwise unspecified. */
+               if (SecTrustGetExceptionForCertificateAtIndex(trust, 0))
+                       trustResult = kSecTrustResultProceed;
+       }
+       else if (trustResult == kSecTrustResultRecoverableTrustFailure && exceptions) {
+               /* If we have exceptions get details and match to exceptions. */
+               CFArrayRef details = SecTrustCopyDetails(trust);
+               if (details) {
+                       CFIndex pathLength = CFArrayGetCount(details);
+                       struct SecTrustCheckExceptionContext context = {};
+                       CFIndex ix;
+                       for (ix = 0; ix < pathLength; ++ix) {
+                               CFDictionaryRef detail = (CFDictionaryRef)CFArrayGetValueAtIndex(details, ix);
+                       //      if ((ix == 0) && CFDictionaryContainsKey(detail, kSecPolicyCheckBlackListedLeaf))
+                       //              trustResult = kSecTrustResultFatalTrustFailure;
+                               context.exception = SecTrustGetExceptionForCertificateAtIndex(trust, ix);
+                               CFDictionaryApplyFunction(detail, SecTrustCheckException, &context);
+                               if (context.exceptionNotFound) {
+                                       break;
+                               }
+                       }
+                       if (!context.exceptionNotFound)
+                               trustResult = kSecTrustResultProceed;
+               }
+       }
+
+
+       secdebug("SecTrustEvaluate", "SecTrustEvaluate trust result = %d", (int)trustResult);
+       if (resultP) {
+               *resultP = trustResult;
+       }
+       return __secapiresult;
 }
 
 OSStatus SecTrustEvaluateAsync(SecTrustRef trust,
 }
 
 OSStatus SecTrustEvaluateAsync(SecTrustRef trust,
@@ -173,7 +237,8 @@ OSStatus SecTrustEvaluateAsync(SecTrustRef trust,
                try {
                        Trust *trustObj = Trust::required(trust);
                        trustObj->evaluate();
                try {
                        Trust *trustObj = Trust::required(trust);
                        trustObj->evaluate();
-                       result(trust, trustObj->result());
+                       SecTrustResultType trustResult = trustObj->result();
+                       result(trust, trustResult);
                }
                catch (...) {
                        result(trust, kSecTrustResultInvalid);
                }
                catch (...) {
                        result(trust, kSecTrustResultInvalid);
@@ -219,7 +284,7 @@ OSStatus SecTrustCopyExtendedResult(SecTrustRef trust, CFDictionaryRef *result)
     BEGIN_SECAPI
        Trust *trustObj = Trust::required(trust);
        if (result == nil)
     BEGIN_SECAPI
        Trust *trustObj = Trust::required(trust);
        if (result == nil)
-               return paramErr;
+               return errSecParam;
        trustObj->extendedResult(*result);
     END_SECAPI
 }
        trustObj->extendedResult(*result);
     END_SECAPI
 }
@@ -239,42 +304,76 @@ OSStatus SecTrustGetCssmResult(SecTrustRef trust, CSSM_TP_VERIFY_CONTEXT_RESULT_
 //
 OSStatus SecTrustGetCssmResultCode(SecTrustRef trustRef, OSStatus *result)
 {
 //
 OSStatus SecTrustGetCssmResultCode(SecTrustRef trustRef, OSStatus *result)
 {
-    BEGIN_SECAPI
-       Trust *trust = Trust::required(trustRef);
+       BEGIN_SECAPI
+               Trust *trust = Trust::required(trustRef);
        if (trust->result() == kSecTrustResultInvalid)
        if (trust->result() == kSecTrustResultInvalid)
-               return paramErr;
+               return errSecParam;
        else
                Required(result) = trust->cssmResultCode();
        else
                Required(result) = trust->cssmResultCode();
-    END_SECAPI
+       END_SECAPI
 }
 
 OSStatus SecTrustGetTPHandle(SecTrustRef trust, CSSM_TP_HANDLE *handle)
 {
 }
 
 OSStatus SecTrustGetTPHandle(SecTrustRef trust, CSSM_TP_HANDLE *handle)
 {
-    BEGIN_SECAPI
-    Required(handle) = Trust::required(trust)->getTPHandle();
-    END_SECAPI
+       BEGIN_SECAPI
+               Required(handle) = Trust::required(trust)->getTPHandle();
+       END_SECAPI
 }
 
 OSStatus SecTrustCopyPolicies(SecTrustRef trust, CFArrayRef *policies)
 {
 }
 
 OSStatus SecTrustCopyPolicies(SecTrustRef trust, CFArrayRef *policies)
 {
-    BEGIN_SECAPI
-    CFArrayRef currentPolicies = Trust::required(trust)->policies();
+       BEGIN_SECAPI
+               CFArrayRef currentPolicies = Trust::required(trust)->policies();
        if (currentPolicies != NULL)
        {
                CFRetain(currentPolicies);
        }
 
        if (currentPolicies != NULL)
        {
                CFRetain(currentPolicies);
        }
 
-    Required(policies) =  currentPolicies;
-    END_SECAPI
+       Required(policies) = currentPolicies;
+       END_SECAPI
+}
+
+OSStatus SecTrustSetNetworkFetchAllowed(SecTrustRef trust, Boolean allowFetch)
+{
+       BEGIN_SECAPI
+       Trust *trustObj = Trust::required(trust);
+       Trust::NetworkPolicy netPolicy = (allowFetch) ?
+               Trust::useNetworkEnabled : Trust::useNetworkDisabled;
+       trustObj->networkPolicy(netPolicy);
+       END_SECAPI
+}
+
+OSStatus SecTrustGetNetworkFetchAllowed(SecTrustRef trust, Boolean *allowFetch)
+{
+       BEGIN_SECAPI
+       Boolean allowed = false;
+       Trust *trustObj = Trust::required(trust);
+       Trust::NetworkPolicy netPolicy = trustObj->networkPolicy();
+       if (netPolicy == Trust::useNetworkDefault) {
+               // network fetch is enabled by default for SSL only
+               allowed = trustObj->policySpecified(trustObj->policies(), CSSMOID_APPLE_TP_SSL);
+       } else {
+               // caller has explicitly set the network policy
+               allowed = (netPolicy == Trust::useNetworkEnabled);
+       }
+       Required(allowFetch) = allowed;
+       END_SECAPI
+}
+
+OSStatus SecTrustSetOCSPResponse(SecTrustRef trust, CFTypeRef responseData)
+{
+       BEGIN_SECAPI
+       Trust::required(trust)->responses(responseData);
+       END_SECAPI
 }
 
 OSStatus SecTrustCopyCustomAnchorCertificates(SecTrustRef trust, CFArrayRef *anchorCertificates)
 {
 }
 
 OSStatus SecTrustCopyCustomAnchorCertificates(SecTrustRef trust, CFArrayRef *anchorCertificates)
 {
-    BEGIN_SECAPI
-    CFRef<CFArrayRef> customAnchors(Trust::required(trust)->anchors());
-    Required(anchorCertificates) = (customAnchors) ?
-        (const CFArrayRef)CFRetain(customAnchors) : (const CFArrayRef)NULL;
-    END_SECAPI
+       BEGIN_SECAPI
+       CFArrayRef customAnchors = Trust::required(trust)->anchors();
+       Required(anchorCertificates) = (customAnchors) ?
+               (const CFArrayRef)CFRetain(customAnchors) : (const CFArrayRef)NULL;
+       END_SECAPI
 }
 
 //
 }
 
 //
@@ -282,13 +381,13 @@ OSStatus SecTrustCopyCustomAnchorCertificates(SecTrustRef trust, CFArrayRef *anc
 //
 OSStatus SecTrustCopyAnchorCertificates(CFArrayRef *anchorCertificates)
 {
 //
 OSStatus SecTrustCopyAnchorCertificates(CFArrayRef *anchorCertificates)
 {
-    BEGIN_SECAPI
+       BEGIN_SECAPI
 
        return SecTrustSettingsCopyUnrestrictedRoots(
 
        return SecTrustSettingsCopyUnrestrictedRoots(
-               true, true, true,               /* all domains */
-               anchorCertificates);
+                       true, true, true,               /* all domains */
+                       anchorCertificates);
 
 
-    END_SECAPI
+       END_SECAPI
 }
 
 /* new in 10.6 */
 }
 
 /* new in 10.6 */
@@ -298,7 +397,7 @@ SecKeyRef SecTrustCopyPublicKey(SecTrustRef trust)
        CFArrayRef certChain = NULL;
        CFArrayRef evidenceChain = NULL;
        CSSM_TP_APPLE_EVIDENCE_INFO *statusChain = NULL;
        CFArrayRef certChain = NULL;
        CFArrayRef evidenceChain = NULL;
        CSSM_TP_APPLE_EVIDENCE_INFO *statusChain = NULL;
-    OSStatus __secapiresult;
+       OSStatus __secapiresult = errSecSuccess;
        try {
                Trust *trustObj = Trust::required(trust);
                if (trustObj->result() == kSecTrustResultInvalid)
        try {
                Trust *trustObj = Trust::required(trust);
                if (trustObj->result() == kSecTrustResultInvalid)
@@ -306,12 +405,11 @@ SecKeyRef SecTrustCopyPublicKey(SecTrustRef trust)
                if (trustObj->evidence() == nil)
                        trustObj->buildEvidence(certChain, TPEvidenceInfo::overlayVar(statusChain));
                evidenceChain = trustObj->evidence();
                if (trustObj->evidence() == nil)
                        trustObj->buildEvidence(certChain, TPEvidenceInfo::overlayVar(statusChain));
                evidenceChain = trustObj->evidence();
-               __secapiresult=noErr;
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
-       catch (const std::bad_alloc &) { __secapiresult=memFullErr; }
-       catch (...) { __secapiresult=internalComponentErr; }
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
+       catch (...) { __secapiresult=errSecInternalComponent; }
 
        if (certChain)
                CFRelease(certChain);
 
        if (certChain)
                CFRelease(certChain);
@@ -323,7 +421,7 @@ SecKeyRef SecTrustCopyPublicKey(SecTrustRef trust)
                }
                // do not release evidenceChain, as it is owned by the trust object.
        }
                }
                // do not release evidenceChain, as it is owned by the trust object.
        }
-    return pubKey;
+       return pubKey;
 }
 
 /* new in 10.6 */
 }
 
 /* new in 10.6 */
@@ -333,20 +431,22 @@ CFIndex SecTrustGetCertificateCount(SecTrustRef trust)
        CFArrayRef certChain = NULL;
        CFArrayRef evidenceChain = NULL;
        CSSM_TP_APPLE_EVIDENCE_INFO *statusChain = NULL;
        CFArrayRef certChain = NULL;
        CFArrayRef evidenceChain = NULL;
        CSSM_TP_APPLE_EVIDENCE_INFO *statusChain = NULL;
-    OSStatus __secapiresult;
+    OSStatus __secapiresult = errSecSuccess;
        try {
                Trust *trustObj = Trust::required(trust);
        try {
                Trust *trustObj = Trust::required(trust);
-               if (trustObj->result() == kSecTrustResultInvalid)
-                       MacOSError::throwMe(errSecTrustNotAvailable);
+               if (trustObj->result() == kSecTrustResultInvalid) {
+                       trustObj->evaluate();
+                       if (trustObj->result() == kSecTrustResultInvalid)
+                               MacOSError::throwMe(errSecTrustNotAvailable);
+               }
                if (trustObj->evidence() == nil)
                        trustObj->buildEvidence(certChain, TPEvidenceInfo::overlayVar(statusChain));
                evidenceChain = trustObj->evidence();
                if (trustObj->evidence() == nil)
                        trustObj->buildEvidence(certChain, TPEvidenceInfo::overlayVar(statusChain));
                evidenceChain = trustObj->evidence();
-               __secapiresult=noErr;
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
-       catch (const std::bad_alloc &) { __secapiresult=memFullErr; }
-       catch (...) { __secapiresult=internalComponentErr; }
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
+       catch (...) { __secapiresult=errSecInternalComponent; }
 
        if (certChain)
                CFRelease(certChain);
 
        if (certChain)
                CFRelease(certChain);
@@ -364,20 +464,22 @@ SecCertificateRef SecTrustGetCertificateAtIndex(SecTrustRef trust, CFIndex ix)
        CFArrayRef certChain = NULL;
        CFArrayRef evidenceChain = NULL;
        CSSM_TP_APPLE_EVIDENCE_INFO *statusChain = NULL;
        CFArrayRef certChain = NULL;
        CFArrayRef evidenceChain = NULL;
        CSSM_TP_APPLE_EVIDENCE_INFO *statusChain = NULL;
-    OSStatus __secapiresult;
+    OSStatus __secapiresult = errSecSuccess;
        try {
                Trust *trustObj = Trust::required(trust);
        try {
                Trust *trustObj = Trust::required(trust);
-               if (trustObj->result() == kSecTrustResultInvalid)
-                       MacOSError::throwMe(errSecTrustNotAvailable);
+               if (trustObj->result() == kSecTrustResultInvalid) {
+                       trustObj->evaluate();
+                       if (trustObj->result() == kSecTrustResultInvalid)
+                               MacOSError::throwMe(errSecTrustNotAvailable);
+               }
                if (trustObj->evidence() == nil)
                        trustObj->buildEvidence(certChain, TPEvidenceInfo::overlayVar(statusChain));
                evidenceChain = trustObj->evidence();
                if (trustObj->evidence() == nil)
                        trustObj->buildEvidence(certChain, TPEvidenceInfo::overlayVar(statusChain));
                evidenceChain = trustObj->evidence();
-               __secapiresult=noErr;
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
        }
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
-       catch (const std::bad_alloc &) { __secapiresult=memFullErr; }
-       catch (...) { __secapiresult=internalComponentErr; }
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
+       catch (...) { __secapiresult=errSecInternalComponent; }
 
        if (certChain)
                CFRelease(certChain);
 
        if (certChain)
                CFRelease(certChain);
@@ -395,6 +497,243 @@ SecCertificateRef SecTrustGetCertificateAtIndex(SecTrustRef trust, CFIndex ix)
        return certificate;
 }
 
        return certificate;
 }
 
+
+static CFStringRef kSecCertificateDetailSHA1Digest = CFSTR("SHA1Digest");
+static CFStringRef kSecCertificateDetailStatusCodes = CFSTR("StatusCodes");
+
+static void
+_AppendStatusCode(CFMutableArrayRef array, OSStatus statusCode)
+{
+       if (!array)
+               return;
+       SInt32 num = statusCode;
+       CFNumberRef numRef = CFNumberCreate(NULL, kCFNumberSInt32Type, &num);
+       if (!numRef)
+               return;
+       CFArrayAppendValue(array, numRef);
+       CFRelease(numRef);
+}
+
+CFArrayRef SecTrustCopyDetails(SecTrustRef trust)
+{
+       // This function returns an array of dictionaries, one per certificate,
+       // holding status info for each certificate in the evaluated chain.
+       //
+       CFIndex count, chainLen = 0;
+       CFArrayRef certChain = NULL;
+       CFMutableArrayRef details = NULL;
+       CSSM_TP_APPLE_EVIDENCE_INFO *statusChain = NULL;
+    OSStatus __secapiresult = errSecSuccess;
+       try {
+               Trust *trustObj = Trust::required(trust);
+               if (trustObj->result() == kSecTrustResultInvalid) {
+                       trustObj->evaluate();
+                       if (trustObj->result() == kSecTrustResultInvalid)
+                               MacOSError::throwMe(errSecTrustNotAvailable);
+               }
+               trustObj->buildEvidence(certChain, TPEvidenceInfo::overlayVar(statusChain));
+       }
+       catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
+       catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
+       catch (...) { __secapiresult=errSecInternalComponent; }
+
+       if (certChain) {
+               chainLen = CFArrayGetCount(certChain);
+               CFRelease(certChain);
+       }
+       if (statusChain) {
+               details = CFArrayCreateMutable(NULL, chainLen, &kCFTypeArrayCallBacks);
+               for (count = 0; count < chainLen; count++) {
+                       CFMutableDictionaryRef certDict = CFDictionaryCreateMutable(kCFAllocatorDefault,
+                               0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+                       CFMutableArrayRef statusCodes = CFArrayCreateMutable(kCFAllocatorDefault,
+                               0, &kCFTypeArrayCallBacks);
+                       CSSM_TP_APPLE_EVIDENCE_INFO *evInfo = &statusChain[count];
+                       CSSM_TP_APPLE_CERT_STATUS statBits = evInfo->StatusBits;
+
+                       // translate status bits
+                       if (statBits & CSSM_CERT_STATUS_EXPIRED)
+                               _AppendStatusCode(statusCodes, errSecCertificateExpired);
+                       if (statBits & CSSM_CERT_STATUS_NOT_VALID_YET)
+                               _AppendStatusCode(statusCodes, errSecCertificateNotValidYet);
+                       if (statBits & CSSM_CERT_STATUS_TRUST_SETTINGS_DENY)
+                               _AppendStatusCode(statusCodes, errSecTrustSettingDeny);
+
+                       // translate status codes
+                       unsigned int i;
+                       for (i = 0; i < evInfo->NumStatusCodes; i++) {
+                               CSSM_RETURN scode = evInfo->StatusCodes[i];
+                               _AppendStatusCode(statusCodes, (OSStatus)scode);
+                       }
+
+                       CFDictionarySetValue(certDict, kSecCertificateDetailStatusCodes, statusCodes);
+                       CFRelease(statusCodes);
+                       CFArrayAppendValue(details, certDict);
+                       CFRelease(certDict);
+               }
+       }
+       return details;
+}
+
+static CFDictionaryRef SecTrustGetExceptionForCertificateAtIndex(SecTrustRef trust, CFIndex ix)
+{
+       CFArrayRef exceptions = NULL;
+    OSStatus __secapiresult = errSecSuccess;
+       try {
+               exceptions = Trust::required(trust)->exceptions();
+       }
+       catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
+       catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
+       catch (...) { __secapiresult=errSecInternalComponent; }
+
+       if (!exceptions || ix >= CFArrayGetCount(exceptions))
+               return NULL;
+       CFDictionaryRef exception = (CFDictionaryRef)CFArrayGetValueAtIndex(exceptions, ix);
+       if (CFGetTypeID(exception) != CFDictionaryGetTypeID())
+               return NULL;
+
+       SecCertificateRef certificate = SecTrustGetCertificateAtIndex(trust, ix);
+       if (!certificate)
+               return NULL;
+
+       /* If the exception contains the current certificate's sha1Digest in the
+          kSecCertificateDetailSHA1Digest key then we use it otherwise we ignore it. */
+       CFDataRef sha1Digest = SecCertificateGetSHA1Digest(certificate);
+       CFTypeRef digestValue = CFDictionaryGetValue(exception, kSecCertificateDetailSHA1Digest);
+       if (!digestValue || !CFEqual(sha1Digest, digestValue))
+               exception = NULL;
+
+       return exception;
+}
+
+static void SecTrustCheckException(const void *key, const void *value, void *context)
+{
+       struct SecTrustCheckExceptionContext *cec = (struct SecTrustCheckExceptionContext *)context;
+       if (cec->exception) {
+               CFTypeRef exceptionValue = CFDictionaryGetValue(cec->exception, key);
+               if (!exceptionValue || !CFEqual(value, exceptionValue)) {
+                       cec->exceptionNotFound = true;
+               }
+       } else {
+               cec->exceptionNotFound = true;
+       }
+}
+
+/* new in 10.9 */
+CFDataRef SecTrustCopyExceptions(SecTrustRef trust)
+{
+       CFArrayRef details = SecTrustCopyDetails(trust);
+       CFIndex pathLength = details ? CFArrayGetCount(details) : 0;
+       CFMutableArrayRef exceptions = CFArrayCreateMutable(kCFAllocatorDefault,
+                       pathLength, &kCFTypeArrayCallBacks);
+       CFIndex ix;
+       for (ix = 0; ix < pathLength; ++ix) {
+               CFDictionaryRef detail = (CFDictionaryRef)CFArrayGetValueAtIndex(details, ix);
+               CFIndex detailCount = CFDictionaryGetCount(detail);
+               CFMutableDictionaryRef exception;
+               if (ix == 0 || detailCount > 0) {
+                       exception = CFDictionaryCreateMutableCopy(kCFAllocatorDefault,
+                               detailCount + 1, detail);
+                       SecCertificateRef certificate = SecTrustGetCertificateAtIndex(trust, ix);
+                       CFDataRef digest = SecCertificateGetSHA1Digest(certificate);
+                       if (digest) {
+                               CFDictionaryAddValue(exception, kSecCertificateDetailSHA1Digest, digest);
+                       }
+               } else {
+                       /* Add empty exception dictionaries for non leaf certs which have no exceptions
+                        * to save space.
+                        */
+                       exception = (CFMutableDictionaryRef)CFDictionaryCreate(kCFAllocatorDefault,
+                               NULL, NULL, 0,
+                               &kCFTypeDictionaryKeyCallBacks,
+                               &kCFTypeDictionaryValueCallBacks);
+               }
+               CFArrayAppendValue(exceptions, exception);
+               CFReleaseNull(exception);
+       }
+       CFReleaseSafe(details);
+
+       /* Remove any trailing empty dictionaries to save even more space (we skip the leaf
+          since it will never be empty). */
+       for (ix = pathLength; ix-- > 1;) {
+               CFDictionaryRef exception = (CFDictionaryRef)CFArrayGetValueAtIndex(exceptions, ix);
+               if (CFDictionaryGetCount(exception) == 0) {
+                       CFArrayRemoveValueAtIndex(exceptions, ix);
+               } else {
+                       break;
+               }
+       }
+
+       CFDataRef encodedExceptions = CFPropertyListCreateData(kCFAllocatorDefault,
+                       exceptions, kCFPropertyListBinaryFormat_v1_0, 0, NULL);
+       CFRelease(exceptions);
+
+       return encodedExceptions;
+}
+
+/* new in 10.9 */
+bool SecTrustSetExceptions(SecTrustRef trust, CFDataRef encodedExceptions)
+{
+       CFArrayRef exceptions;
+       exceptions = (CFArrayRef)CFPropertyListCreateWithData(kCFAllocatorDefault,
+               encodedExceptions, kCFPropertyListImmutable, NULL, NULL);
+       if (exceptions && CFGetTypeID(exceptions) != CFArrayGetTypeID()) {
+               CFRelease(exceptions);
+               exceptions = NULL;
+       }
+
+       OSStatus __secapiresult = errSecSuccess;
+       try {
+               Trust::required(trust)->exceptions(exceptions);
+       }
+       catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
+       catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
+       catch (...) { __secapiresult=errSecInternalComponent; }
+
+       /* If there is a valid exception entry for our current leaf we're golden. */
+       if (SecTrustGetExceptionForCertificateAtIndex(trust, 0))
+               return true;
+
+       /* The passed in exceptions didn't match our current leaf, so we discard it. */
+       try {
+               Trust::required(trust)->exceptions(NULL);
+               __secapiresult = errSecSuccess;
+       }
+       catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
+       catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
+       catch (...) { __secapiresult=errSecInternalComponent; }
+
+       return false;
+}
+
+/* new in 10.9 */
+CFDictionaryRef
+SecTrustCopyResult(SecTrustRef trust)
+{
+       CFDictionaryRef result = NULL;
+       try {
+               result = Trust::required(trust)->results();
+               // merge details into result
+               CFArrayRef details = SecTrustCopyDetails(trust);
+               if (details) {
+                       CFDictionarySetValue((CFMutableDictionaryRef)result,
+                               kSecTrustResultDetails, details);
+                       CFRelease(details);
+               }
+       }
+       catch (...) {
+               if (result) {
+                       CFRelease(result);
+                       result = NULL;
+               }
+       }
+       return result;
+}
+
 /* new in 10.7 */
 CFArrayRef
 SecTrustCopyProperties(SecTrustRef trust)
 /* new in 10.7 */
 CFArrayRef
 SecTrustCopyProperties(SecTrustRef trust)
@@ -409,7 +748,7 @@ SecTrustCopyProperties(SecTrustRef trust)
                        CFRelease(result);
                        result = NULL;
                }
                        CFRelease(result);
                        result = NULL;
                }
-       };
+       }
        return result;
 }
 
        return result;
 }
 
@@ -446,7 +785,7 @@ OSStatus SecTrustGetUserTrust(SecCertificateRef certificate,
 
 //
 // The public setter, also deprecated; it maps to the appropriate
 
 //
 // The public setter, also deprecated; it maps to the appropriate
-// Trust Settings call if possible, else throws unimpErr.
+// Trust Settings call if possible, else throws errSecUnimplemented.
 //
 OSStatus SecTrustSetUserTrust(SecCertificateRef certificate,
     SecPolicyRef policy, SecTrustUserSetting trustSetting)
 //
 OSStatus SecTrustSetUserTrust(SecCertificateRef certificate,
     SecPolicyRef policy, SecTrustUserSetting trustSetting)
@@ -474,7 +813,7 @@ OSStatus SecTrustSetUserTrust(SecCertificateRef certificate,
                        tsResult = kSecTrustSettingsResultDeny;
                        break;
                default:
                        tsResult = kSecTrustSettingsResultDeny;
                        break;
                default:
-                       return unimpErr;
+                       return errSecUnimplemented;
        }
 
        /* make a usage constraints dictionary */
        }
 
        /* make a usage constraints dictionary */
index 82243de03fedb1dffe2c93be7638a321686f7560..67f3fb03e05aca7fac465bbffdda86d5a3566cca 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2002-2010 Apple Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2002-2010,2012-2013 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
 /*!
  * @APPLE_LICENSE_HEADER_END@
  */
 
 /*!
-       @header SecTrust
-       The functions and data types in SecTrust implement trust computation
+    @header SecTrust
+    The functions and data types in SecTrust implement trust computation
     and allow the caller to apply trust decisions to the evaluation.
     and allow the caller to apply trust decisions to the evaluation.
-*/
+ */
 
 #ifndef _SECURITY_SECTRUST_H_
 #define _SECURITY_SECTRUST_H_
 
 #include <Security/SecBase.h>
 
 #ifndef _SECURITY_SECTRUST_H_
 #define _SECURITY_SECTRUST_H_
 
 #include <Security/SecBase.h>
-#include <Security/cssmtype.h>
-#include <Security/cssmapple.h>
 #include <CoreFoundation/CoreFoundation.h>
 #include <AvailabilityMacros.h>
 
 #include <CoreFoundation/CoreFoundation.h>
 #include <AvailabilityMacros.h>
 
-
 #if defined(__cplusplus)
 extern "C" {
 #endif
 
 /*!
 #if defined(__cplusplus)
 extern "C" {
 #endif
 
 /*!
-       @typedef SecTrustResultType
-       @abstract Specifies the trust result type.
-       @constant kSecTrustResultInvalid Indicates an invalid setting or result.
-       @constant kSecTrustResultProceed Indicates you may proceed.  This value
+    @typedef SecTrustResultType
+    @abstract Specifies the trust result type.
+    @discussion SecTrustResultType results have two dimensions.  They specify
+    both whether evaluation suceeded and whether this is because of a user
+    decision.  The commonly expected result is kSecTrustResultUnspecified,
+    which indicates a positive result that wasn't decided by the user.  The
+    common failure is kSecTrustResultRecoverableTrustFailure, which means a
+    negative result.  kSecTrustResultProceed and kSecTrustResultDeny are the
+    positive and negative result respectively when decided by the user.  User
+    decisions are persisted through the use of SecTrustCopyExceptions() and
+    SecTrustSetExceptions().  Finally, kSecTrustResultFatalTrustFailure is a
+    negative result that must not be circumvented.
+    @constant kSecTrustResultInvalid Indicates an invalid setting or result.
+    This result usually means that SecTrustEvaluate has not yet been called.
+    @constant kSecTrustResultProceed Indicates you may proceed.  This value
     may be returned by the SecTrustEvaluate function or stored as part of
     may be returned by the SecTrustEvaluate function or stored as part of
-    the user trust settings. 
-       @constant kSecTrustResultConfirm Indicates confirmation with the user
-    is required before proceeding.  This value may be returned by the
-    SecTrustEvaluate function or stored as part of the user trust settings. 
-       @constant kSecTrustResultDeny Indicates a user-configured deny; do not
+    the user trust settings.
+    @constant kSecTrustResultConfirm Indicates confirmation with the user
+    is required before proceeding.  Important: this value is no longer returned
+    or supported by SecTrustEvaluate or the SecTrustSettings API starting in
+    OS X 10.5; its use is deprecated in OS X 10.9 and later, as well as in iOS.
+    @constant kSecTrustResultDeny Indicates a user-configured deny; do not
     proceed. This value may be returned by the SecTrustEvaluate function
     proceed. This value may be returned by the SecTrustEvaluate function
-    or stored as part of the user trust settings. 
-       @constant kSecTrustResultUnspecified Indicates user intent is unknown.
-    This value may be returned by the SecTrustEvaluate function or stored
-    as part of the user trust settings. 
-       @constant kSecTrustResultRecoverableTrustFailure Indicates a trust
-    framework failure; retry after fixing inputs. This value may be returned
+    or stored as part of the user trust settings.
+    @constant kSecTrustResultUnspecified Indicates the evaluation succeeded
+    and the certificate is implicitly trusted, but user intent was not
+    explicitly specified.  This value may be returned by the SecTrustEvaluate
+    function or stored as part of the user trust settings.
+    @constant kSecTrustResultRecoverableTrustFailure Indicates a trust policy
+    failure which can be overridden by the user.  This value may be returned
     by the SecTrustEvaluate function but not stored as part of the user
     by the SecTrustEvaluate function but not stored as part of the user
-    trust settings. 
-       @constant kSecTrustResultFatalTrustFailure Indicates a trust framework
-    failure; no "easy" fix. This value may be returned by the
+    trust settings.
+    @constant kSecTrustResultFatalTrustFailure Indicates a trust failure
+    which cannot be overridden by the user.  This value may be returned by the
     SecTrustEvaluate function but not stored as part of the user trust
     settings.
     SecTrustEvaluate function but not stored as part of the user trust
     settings.
-       @constant kSecTrustResultOtherError Indicates a failure other than that
+    @constant kSecTrustResultOtherError Indicates a failure other than that
     of trust evaluation. This value may be returned by the SecTrustEvaluate
     function but not stored as part of the user trust settings.
  */
     of trust evaluation. This value may be returned by the SecTrustEvaluate
     function but not stored as part of the user trust settings.
  */
+
 typedef uint32_t SecTrustResultType;
 enum {
 typedef uint32_t SecTrustResultType;
 enum {
-    kSecTrustResultInvalid,
-    kSecTrustResultProceed,
-    kSecTrustResultConfirm,
-    kSecTrustResultDeny,
-    kSecTrustResultUnspecified,
-    kSecTrustResultRecoverableTrustFailure,
-    kSecTrustResultFatalTrustFailure,
-    kSecTrustResultOtherError
+    kSecTrustResultInvalid = 0,
+    kSecTrustResultProceed = 1,
+    kSecTrustResultConfirm CF_ENUM_DEPRECATED(10_0, 10_9, NA, NA) = 2,
+    kSecTrustResultDeny = 3,
+    kSecTrustResultUnspecified = 4,
+    kSecTrustResultRecoverableTrustFailure = 5,
+    kSecTrustResultFatalTrustFailure = 6,
+    kSecTrustResultOtherError = 7
 };
 
 /*!
 };
 
 /*!
-       @typedef SecTrustUserSetting
-       @abstract Specifies user-specified trust settings.
-*/
-typedef SecTrustResultType SecTrustUserSetting;
-       
-/*!
-       @typedef SecTrustOptionFlags
-       @abstract Options for customizing trust evaluation.
-       @constant kSecTrustOptionAllowExpired Allow expired certs.
-       @constant kSecTrustOptionLeafIsCA Allow CA as leaf certificate.
-       @constant kSecTrustOptionFetchIssuerFromNet Allow network fetch of CA cert.
-       @constant kSecTrustOptionAllowExpiredRoot Allow expired roots.
-       @constant kSecTrustOptionRequireRevPerCert Require positive revocation
-       check per certificate.
-       @constant kSecTrustOptionUseTrustSettings Use TrustSettings instead of
-       anchors.
-       @constant kSecTrustOptionImplicitAnchors Properly self-signed certs are
-       treated as anchors implicitly.
+    @typedef SecTrustRef
+    @abstract CFType used for performing X.509 certificate trust evaluations.
  */
  */
-typedef uint32_t SecTrustOptionFlags;
-enum {
-       kSecTrustOptionAllowExpired       = 0x00000001,
-       kSecTrustOptionLeafIsCA           = 0x00000002,
-       kSecTrustOptionFetchIssuerFromNet = 0x00000004,
-       kSecTrustOptionAllowExpiredRoot   = 0x00000008,
-       kSecTrustOptionRequireRevPerCert  = 0x00000010,
-       kSecTrustOptionUseTrustSettings   = 0x00000020, 
-       kSecTrustOptionImplicitAnchors    = 0x00000040
-};
+typedef struct __SecTrust *SecTrustRef;
 
 /*!
     @enum Trust Property Constants
 
 /*!
     @enum Trust Property Constants
-    @discussion Predefined property key constants used to obtain values in
-        a dictionary of trust evaluation results.
-       @constant kSecPropertyTypeTitle Specifies a key whose value is a
-               CFStringRef containing the title (display name) of this certificate.
-       @constant kSecPropertyTypeError Specifies a key whose value is a
-               CFStringRef containing the reason for a trust evaluation failure.
-*/
+    @discussion Predefined key constants used to obtain values in a
+        per-certificate dictionary of trust evaluation results,
+        as retrieved from a call to SecTrustCopyProperties.
+    @constant kSecPropertyTypeTitle Specifies a key whose value is a
+        CFStringRef containing the title (display name) of this certificate.
+    @constant kSecPropertyTypeError Specifies a key whose value is a
+        CFStringRef containing the reason for a trust evaluation failure.
+ */
 extern CFTypeRef kSecPropertyTypeTitle
 extern CFTypeRef kSecPropertyTypeTitle
-    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0);
 extern CFTypeRef kSecPropertyTypeError
 extern CFTypeRef kSecPropertyTypeError
-    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
-
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0);
 
 /*!
 
 /*!
-       @typedef SecTrustRef
-       @abstract A pointer to an opaque trust management structure.
-*/
-typedef struct OpaqueSecTrustRef *SecTrustRef;
+    @enum Trust Result Constants
+    @discussion Predefined key constants used to obtain values in a
+        dictionary of trust evaluation results for a certificate chain,
+        as retrieved from a call to SecTrustCopyResult.
+    @constant kSecTrustEvaluationDate
+        This key will be present if a trust evaluation has been performed
+        and results are available. Its value is a CFDateRef representing
+        when the evaluation for this trust object took place.
+    @constant kSecTrustExtendedValidation
+        This key will be present and have a value of kCFBooleanTrue
+        if this chain was validated for EV.
+    @constant kSecTrustOrganizationName
+        Organization name field of subject of leaf certificate. This
+        field is meant to be displayed to the user as the validated
+        name of the company or entity that owns the certificate if the
+        kSecTrustExtendedValidation key is present.
+    @constant kSecTrustResultValue
+        This key will be present if a trust evaluation has been performed.
+        Its value is a CFNumberRef representing the SecTrustResultType result
+        for the evaluation.
+    @constant kSecTrustRevocationChecked
+        This key will be present iff this chain had its revocation checked.
+        The value will be a kCFBooleanTrue if revocation checking was
+        successful and none of the certificates in the chain were revoked.
+        The value will be kCFBooleanFalse if no current revocation status
+        could be obtained for one or more certificates in the chain due
+        to connection problems or timeouts.  This is a hint to a client
+        to retry revocation checking at a later time.
+    @constant kSecTrustRevocationValidUntilDate
+        This key will be present iff kSecTrustRevocationChecked has a
+        value of kCFBooleanTrue. The value will be a CFDateRef representing
+        the earliest date at which the revocation info for one of the
+        certificates in this chain might change.
+ */
+extern CFTypeRef kSecTrustEvaluationDate
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFTypeRef kSecTrustExtendedValidation
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFTypeRef kSecTrustOrganizationName
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFTypeRef kSecTrustResultValue
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFTypeRef kSecTrustRevocationChecked
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFTypeRef kSecTrustRevocationValidUntilDate
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
 
 #ifdef __BLOCKS__
 /*!
 
 #ifdef __BLOCKS__
 /*!
-       @typedef SecTrustCallback
-       @abstract Delivers the result from an asynchronous trust evaluation.
+    @typedef SecTrustCallback
+    @abstract Delivers the result from an asynchronous trust evaluation.
     @param trustRef A reference to the trust object which has been evaluated.
     @param trustResult The trust result of the evaluation. Additional status
     @param trustRef A reference to the trust object which has been evaluated.
     @param trustResult The trust result of the evaluation. Additional status
-       information can be obtained by calling SecTrustCopyProperties().
-*/
+    information can be obtained by calling SecTrustCopyProperties().
+ */
 typedef void (^SecTrustCallback)(SecTrustRef trustRef, SecTrustResultType trustResult);
 typedef void (^SecTrustCallback)(SecTrustRef trustRef, SecTrustResultType trustResult);
-#endif
+#endif /* __BLOCKS__ */
+
 
 /*!
 
 /*!
-       @function SecTrustGetTypeID
-       @abstract Returns the type identifier of SecTrust instances.
-       @result The CFTypeID of SecTrust instances.
-*/
+    @function SecTrustGetTypeID
+    @abstract Returns the type identifier of SecTrust instances.
+    @result The CFTypeID of SecTrust instances.
+ */
 CFTypeID SecTrustGetTypeID(void)
     __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_2_0);
 
 /*!
 CFTypeID SecTrustGetTypeID(void)
     __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_2_0);
 
 /*!
-       @function SecTrustCreateWithCertificates
-       @abstract Creates a trust object based on the given certificates and
+    @function SecTrustCreateWithCertificates
+    @abstract Creates a trust object based on the given certificates and
     policies.
     policies.
-    @param certificates The group of certificates to verify.
+    @param certificates The group of certificates to verify.  This can either
+    be a CFArrayRef of SecCertificateRef objects or a single SecCertificateRef
     @param policies An array of one or more policies. You may pass a
     SecPolicyRef to represent a single policy.
     @param policies An array of one or more policies. You may pass a
     SecPolicyRef to represent a single policy.
-       @param trustRef On return, a pointer to the trust management reference.
-       @result A result code.  See "Security Error Codes" (SecBase.h).
+    @param trust On return, a pointer to the trust management reference.
+    @result A result code.  See "Security Error Codes" (SecBase.h).
     @discussion If multiple policies are passed in, all policies must verify
     for the chain to be considered valid.
     @discussion If multiple policies are passed in, all policies must verify
     for the chain to be considered valid.
-*/
-OSStatus SecTrustCreateWithCertificates(CFArrayRef certificates,
-    CFTypeRef policies, SecTrustRef *trustRef)
+ */
+OSStatus SecTrustCreateWithCertificates(CFTypeRef certificates,
+    CFTypeRef policies, SecTrustRef *trust)
     __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_2_0);
 
     __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_2_0);
 
-
 /*!
     @function SecTrustSetPolicies
 /*!
     @function SecTrustSetPolicies
-    @abstract Set (replace) the set of policies to evaluate.
-    @param trust The reference to the trust to change.
+    @abstract Set the policies for which trust should be verified.
+    @param trust A trust reference.
     @param policies An array of one or more policies. You may pass a
     SecPolicyRef to represent a single policy.
     @result A result code. See "Security Error Codes" (SecBase.h).
     @param policies An array of one or more policies. You may pass a
     SecPolicyRef to represent a single policy.
     @result A result code. See "Security Error Codes" (SecBase.h).
-*/    
+    @discussion This function will invalidate the existing trust result,
+    requiring a fresh evaluation for the newly-set policies.
+ */
 OSStatus SecTrustSetPolicies(SecTrustRef trust, CFTypeRef policies)
 OSStatus SecTrustSetPolicies(SecTrustRef trust, CFTypeRef policies)
-    __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_NA);
+    __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_6_0);
 
 /*!
 
 /*!
-       @function SecTrustSetOptions
-       @abstract Sets optional flags and data for customizing a trust evaluation.
-       @param trustRef The reference to the trust to change.
-       @param options Flags to change evaluation behavior for this trust.
-       @result A result code. See "Security Error Codes" (SecBase.h).
+    @function SecTrustCopyPolicies
+    @abstract Returns an array of policies used for this evaluation.
+    @param trust  A reference to a trust object.
+    @param policies On return, an array of policies used by this trust.
+    Call the CFRelease function to release this reference.
+    @result A result code. See "Security Error Codes" (SecBase.h).
  */
  */
-OSStatus SecTrustSetOptions(SecTrustRef trustRef, SecTrustOptionFlags options)
-    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+OSStatus SecTrustCopyPolicies(SecTrustRef trust, CFArrayRef *policies)
+    __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_7_0);
 
 /*!
 
 /*!
-       @function SecTrustSetParameters
-       @abstract Sets the action and action data for a trust object.
-       @param trustRef The reference to the trust to change.
-       @param action A trust action.
-       @param actionData A reference to data associated with this action.
-       @result A result code. See "Security Error Codes" (SecBase.h).
-       @discussion This function is deprecated in Mac OS X 10.7 and later;
-       use SecTrustSetOptions instead.
+    @function SecTrustSetNetworkFetchAllowed
+    @abstract Specifies whether a trust evaluation is permitted to fetch missing
+    intermediate certificates from the network.
+    @param trust A trust reference.
+    @param allowFetch If true, and a certificate's issuer is not present in the
+    trust reference but its network location is known, the evaluation is permitted
+    to attempt to download it automatically. Pass false to disable network fetch
+    for this trust evaluation.
+    @result A result code. See "Security Error Codes" (SecBase.h).
+    @discussion By default, network fetch of missing certificates is enabled if
+    the trust evaluation includes the SSL policy, otherwise it is disabled.
  */
  */
-OSStatus SecTrustSetParameters(SecTrustRef trustRef,
-       CSSM_TP_ACTION action, CFDataRef actionData)
-       DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-       
-/*!
-       @function SecTrustSetAnchorCertificates
-       @abstract Sets the anchor certificates for a given trust.
-       @param trust A reference to a trust object.
-       @param anchorCertificates An array of anchor certificates.
-       @result A result code.  See "Security Error Codes" (SecBase.h).
+OSStatus SecTrustSetNetworkFetchAllowed(SecTrustRef trust,
+    Boolean allowFetch)
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+
+/*!
+    @function SecTrustGetNetworkFetchAllowed
+    @abstract Returns whether a trust evaluation is permitted to fetch missing
+    intermediate certificates from the network.
+    @param trust A trust reference.
+    @param allowFetch On return, the boolean pointed to by this parameter is
+    set to true if the evaluation is permitted to download missing certificates.
+    @result A result code. See "Security Error Codes" (SecBase.h).
+    @discussion By default, network fetch of missing certificates is enabled if
+    the trust evaluation includes the SSL policy, otherwise it is disabled.
+ */
+OSStatus SecTrustGetNetworkFetchAllowed(SecTrustRef trust,
+    Boolean *allowFetch)
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+
+/*!
+    @function SecTrustSetAnchorCertificates
+    @abstract Sets the anchor certificates for a given trust.
+    @param trust A reference to a trust object.
+    @param anchorCertificates An array of anchor certificates.
+    @result A result code.  See "Security Error Codes" (SecBase.h).
     @discussion Calling this function without also calling
     SecTrustSetAnchorCertificatesOnly() will disable trusting any
     anchors other than the ones in anchorCertificates.
     @discussion Calling this function without also calling
     SecTrustSetAnchorCertificatesOnly() will disable trusting any
     anchors other than the ones in anchorCertificates.
-*/
+ */
 OSStatus SecTrustSetAnchorCertificates(SecTrustRef trust,
     CFArrayRef anchorCertificates)
     __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_2_0);
 
 /*!
 OSStatus SecTrustSetAnchorCertificates(SecTrustRef trust,
     CFArrayRef anchorCertificates)
     __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_2_0);
 
 /*!
-       @function SecTrustSetAnchorCertificatesOnly
-       @abstract Reenables trusting anchor certificates in addition to those
+    @function SecTrustSetAnchorCertificatesOnly
+    @abstract Reenables trusting anchor certificates in addition to those
     passed in via the SecTrustSetAnchorCertificates API.
     passed in via the SecTrustSetAnchorCertificates API.
-       @param trust A reference to a trust object.
-       @param anchorCertificatesOnly If true, disables trusting any anchors other
+    @param trust A reference to a trust object.
+    @param anchorCertificatesOnly If true, disables trusting any anchors other
     than the ones passed in via SecTrustSetAnchorCertificates().  If false,
     the built in anchor certificates are also trusted.
     than the ones passed in via SecTrustSetAnchorCertificates().  If false,
     the built in anchor certificates are also trusted.
-       @result A result code.  See "Security Error Codes" (SecBase.h).
-*/
+    @result A result code.  See "Security Error Codes" (SecBase.h).
+ */
 OSStatus SecTrustSetAnchorCertificatesOnly(SecTrustRef trust,
     Boolean anchorCertificatesOnly)
     __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
 
 /*!
 OSStatus SecTrustSetAnchorCertificatesOnly(SecTrustRef trust,
     Boolean anchorCertificatesOnly)
     __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
 
 /*!
-       @function SecTrustSetKeychains
-       @abstract Sets the keychains for a given trust object.
-       @param trust A reference to a trust object.
-    @param keychainOrArray A reference to an array of keychains to search, a 
-       single keychain, or NULL to use the default keychain search list.
-       @result A result code. See "Security Error Codes" (SecBase.h).
-       @discussion By default, the user's keychain search list and the system
-       anchors keychain are searched for certificates to complete the chain. You 
-       can specify a zero-element array if you do not want any keychains searched.
-*/
-OSStatus SecTrustSetKeychains(SecTrustRef trust, CFTypeRef keychainOrArray)
-    __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_NA);
+    @function SecTrustCopyCustomAnchorCertificates
+    @abstract Returns an array of custom anchor certificates used by a given
+    trust, as set by a prior call to SecTrustSetAnchorCertificates, or NULL if
+    no custom anchors have been specified.
+    @param trust  A reference to a trust object.
+    @param anchors On return, an array of custom anchor certificates (roots)
+    used by this trust, or NULL if no custom anchors have been specified. Call
+    the CFRelease function to release this reference.
+    @result A result code. See "Security Error Codes" (SecBase.h).
+ */
+OSStatus SecTrustCopyCustomAnchorCertificates(SecTrustRef trust,
+    CFArrayRef *anchors)
+    __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_7_0);
 
 /*!
 
 /*!
-       @function SecTrustSetVerifyDate
-       @abstract Set the date for which the trust should be verified.
-       @param trust A reference to a trust object.
-       @param verifyDate The date for which to verify trust.
-       @result A result code.  See "Security Error Codes" (SecBase.h).
+    @function SecTrustSetVerifyDate
+    @abstract Set the date for which the trust should be verified.
+    @param trust A reference to a trust object.
+    @param verifyDate The date for which to verify trust.
+    @result A result code.  See "Security Error Codes" (SecBase.h).
     @discussion This function lets you evaluate certificate validity for a
     @discussion This function lets you evaluate certificate validity for a
-       given date (for example, to determine if a signature was valid on the date
-       it was signed, even if the certificate has since expired.) If this function
-       is not called, the time at which SecTrustEvaluate() is called is used
-       implicitly as the verification time.
-*/
+    given date (for example, to determine if a signature was valid on the date
+    it was signed, even if the certificate has since expired.) If this function
+    is not called, the time at which SecTrustEvaluate() is called is used
+    implicitly as the verification time.
+ */
 OSStatus SecTrustSetVerifyDate(SecTrustRef trust, CFDateRef verifyDate)
     __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_2_0);
 
 /*!
 OSStatus SecTrustSetVerifyDate(SecTrustRef trust, CFDateRef verifyDate)
     __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_2_0);
 
 /*!
-       @function SecTrustGetVerifyTime
-       @abstract Returns the verify time.
-       @param trust A reference to the trust object being verified.
-       @result A CFAbsoluteTime value representing the time at which certificates
-       should be checked for validity.
+    @function SecTrustGetVerifyTime
+    @abstract Returns the verify time.
+    @param trust A reference to the trust object being verified.
+    @result A CFAbsoluteTime value representing the time at which certificates
+    should be checked for validity.
     @discussion This function retrieves the verification time for the given
     @discussion This function retrieves the verification time for the given
-       trust reference, as set by a prior call to SecTrustSetVerifyDate(). If the
-       verification time has not been set, this function returns a value of 0,
-       indicating that the current date/time is implicitly used for verification.
-*/
+    trust reference, as set by a prior call to SecTrustSetVerifyDate(). If the
+    verification time has not been set, this function returns a value of 0,
+    indicating that the current date/time is implicitly used for verification.
+ */
 CFAbsoluteTime SecTrustGetVerifyTime(SecTrustRef trust)
     __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
 
 /*!
 CFAbsoluteTime SecTrustGetVerifyTime(SecTrustRef trust)
     __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
 
 /*!
-       @function SecTrustEvaluate
-       @abstract Evaluates a trust reference synchronously.
-       @param trust A reference to the trust object to evaluate.
-       @param result A pointer to a result type.
-       @result A result code. See "Security Error Codes" (SecBase.h).  
+    @function SecTrustEvaluate
+    @abstract Evaluates a trust reference synchronously.
+    @param trust A reference to the trust object to evaluate.
+    @param result A pointer to a result type.
+    @result A result code. See "Security Error Codes" (SecBase.h).
     @discussion This function will completely evaluate trust before returning,
     @discussion This function will completely evaluate trust before returning,
-       possibly including network access to fetch intermediate certificates or to
-       perform revocation checking. Since this function can block during those
-       operations, you should call it from within a function that is placed on a
-       dispatch queue, or in a separate thread from your application's main
-       run loop. Alternatively, you can use the SecTrustEvaluateAsync() function
-       in Mac OS X 10.7 and later.
-*/
+    possibly including network access to fetch intermediate certificates or to
+    perform revocation checking. Since this function can block during those
+    operations, you should call it from within a function that is placed on a
+    dispatch queue, or in a separate thread from your application's main
+    run loop. Alternatively, you can use the SecTrustEvaluateAsync function.
+ */
 OSStatus SecTrustEvaluate(SecTrustRef trust, SecTrustResultType *result)
     __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_2_0);
 
 #ifdef __BLOCKS__
 /*!
 OSStatus SecTrustEvaluate(SecTrustRef trust, SecTrustResultType *result)
     __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_2_0);
 
 #ifdef __BLOCKS__
 /*!
-       @function SecTrustEvaluateAsync
-       @abstract Evaluates a trust reference asynchronously.
-       @param trust A reference to the trust object to evaluate.
-       @param queue A dispatch queue on which the result callback should be
-       executed. Pass NULL to use the current dispatch queue.
-       @param result A SecTrustCallback block which will be executed when the
-       trust evaluation is complete.
-       @result A result code. See "Security Error Codes" (SecBase.h).  
-*/
+    @function SecTrustEvaluateAsync
+    @abstract Evaluates a trust reference asynchronously.
+    @param trust A reference to the trust object to evaluate.
+    @param queue A dispatch queue on which the result callback should be
+    executed. Pass NULL to use the current dispatch queue.
+    @param result A SecTrustCallback block which will be executed when the
+    trust evaluation is complete.
+    @result A result code. See "Security Error Codes" (SecBase.h).
+ */
 OSStatus SecTrustEvaluateAsync(SecTrustRef trust,
 OSStatus SecTrustEvaluateAsync(SecTrustRef trust,
-       dispatch_queue_t queue, SecTrustCallback result)
-    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+    dispatch_queue_t queue, SecTrustCallback result)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0);
 #endif
 
 /*!
 #endif
 
 /*!
-       @function SecTrustGetResult
-       @abstract Returns detailed information on the outcome of an evaluation.
-       @param trustRef A reference to a trust object.
-       @param result A pointer to the result from the call to SecTrustEvaluate.
-       @param certChain On return, a pointer to the certificate chain used to
-       validate the input certificate. Call the CFRelease function to release
-       this pointer.
-       @param statusChain On return, a pointer to the status of the certificate
-       chain. Do not attempt to free this pointer; it remains valid until the
-       trust is destroyed or the next call to SecTrustEvaluate.
-       @result A result code. See "Security Error Codes" (SecBase.h).
-       @discussion This function is deprecated in Mac OS X 10.7 and later.
-       To get the complete certificate chain, use SecTrustGetCertificateCount and
-       SecTrustGetCertificateAtIndex. To get detailed status information for each
-       certificate, use SecTrustCopyProperties. To get the overall trust result
-       for the evaluation, use SecTrustGetTrustResult.
-*/
-OSStatus SecTrustGetResult(SecTrustRef trustRef, SecTrustResultType *result,
-       CFArrayRef *certChain, CSSM_TP_APPLE_EVIDENCE_INFO **statusChain)
-       DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-
-/*!
-       @function SecTrustGetCssmResult
-       @abstract Gets the CSSM trust result.
-       @param trust A reference to a trust.
-       @param result On return, a pointer to the CSSM trust result.
-       @result A result code. See "Security Error Codes" (SecBase.h).
-       @discussion This function is deprecated in Mac OS X 10.7 and later.
-       To get detailed status information for each certificate, use
-       SecTrustCopyProperties. To get the overall trust result for the evaluation,
-       use SecTrustGetTrustResult.
-*/
-OSStatus SecTrustGetCssmResult(SecTrustRef trust,
-       CSSM_TP_VERIFY_CONTEXT_RESULT_PTR *result)
-       DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-
-/*!
-       @function SecTrustGetCssmResultCode
-       @abstract Gets the result code from the most recent call to SecTrustEvaluate
-       for the specified trust.
-       @param trust A reference to a trust.
-       @param resultCode On return, the result code produced by the most recent
-       evaluation of the given trust (cssmerr.h). The value of resultCode is
-       undefined if SecTrustEvaluate has not been called.
-       @result A result code. See "Security Error Codes" (SecBase.h). Returns
-       errSecTrustNotAvailable if SecTrustEvaluate has not been called for the
-       specified trust.
-       @discussion This function is deprecated in Mac OS X 10.7 and later.
-       To get detailed status information for each certificate, use
-       SecTrustCopyProperties. To get the overall trust result for the evaluation,
-       use SecTrustGetTrustResult.
-*/
-OSStatus SecTrustGetCssmResultCode(SecTrustRef trust, OSStatus *resultCode)
-       DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-
-/*!
-       @function SecTrustGetTrustResult
-       @param trustRef A reference to a trust object.
-       @param result A pointer to the result from the most recent call to
-       SecTrustEvaluate for this trust reference. If SecTrustEvaluate has not been
-       called, the result is kSecTrustResultInvalid.
-       @result A result code. See "Security Error Codes" (SecBase.h).
-       @discussion This function replaces SecTrustGetResult for the purpose of
-       obtaining the current evaluation result of a given trust reference.
-*/
-OSStatus SecTrustGetTrustResult(SecTrustRef trustRef,
-       SecTrustResultType *result)
-    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
-
-/*!
-       @function SecTrustGetTPHandle
-       @abstract Gets the CSSM trust handle
-       @param trust A reference to a trust.
-       @param handle On return, a CSSM trust handle.
-       @result A result code. See "Security Error Codes" (SecBase.h).
-       @discussion This function is deprecated in Mac OS X 10.7 and later.
-*/
-OSStatus SecTrustGetTPHandle(SecTrustRef trust, CSSM_TP_HANDLE *handle)
-       DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-
-/*!
-    @function SecTrustCopyPolicies
-    @abstract Returns an array of policies used by a given trust.
-    @param trust  A reference to a trust object.
-    @param policies On return, an array of policies used by this trust.
-       Call the CFRelease function to release this reference.
-    @result A result code. See "Security Error Codes" (SecBase.h).
-*/    
-OSStatus SecTrustCopyPolicies(SecTrustRef trust, CFArrayRef *policies)
-    __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_NA);
-
-/*!
-    @function SecTrustCopyCustomAnchorCertificates
-    @abstract Returns an array of custom anchor certificates used by a given
-       trust, as set by a prior call to SecTrustSetAnchorCertificates, or NULL if
-       no custom anchors have been specified.
-    @param trust  A reference to a trust.
-    @param anchors On return, an array of custom anchor certificates (roots)
-       used by this trust, or NULL if no custom anchors have been specified. Call
-       the CFRelease function to release this reference.
-    @result A result code. See "Security Error Codes" (SecBase.h).
-*/    
-OSStatus SecTrustCopyCustomAnchorCertificates(SecTrustRef trust,
-       CFArrayRef *anchors)
-    __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
-
-/*!
-    @function SecTrustCopyAnchorCertificates
-    @abstract Returns an array of default anchor (root) certificates used by
-       the system.
-    @param anchors On return, an array containing the system's default anchors
-       (roots). Call the CFRelease function to release this pointer.
+    @function SecTrustGetTrustResult
+    @param trust A reference to a trust object.
+    @param result A pointer to the result from the most recent call to
+    SecTrustEvaluate for this trust reference. If SecTrustEvaluate has not been
+    called or trust parameters have changed, the result is kSecTrustResultInvalid.
     @result A result code. See "Security Error Codes" (SecBase.h).
     @result A result code. See "Security Error Codes" (SecBase.h).
-*/
-OSStatus SecTrustCopyAnchorCertificates(CFArrayRef *anchors)
-    __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_NA);
+    @discussion This function replaces SecTrustGetResult for the purpose of
+    obtaining the current evaluation result of a given trust reference.
+ */
+OSStatus SecTrustGetTrustResult(SecTrustRef trust,
+    SecTrustResultType *result)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0);
 
 /*!
 
 /*!
-       @function SecTrustCopyPublicKey
-       @abstract Return the public key for the leaf certificate after trust has 
-       been evaluated.
-       @param trust A reference to the trust object which has been evaluated.
-       @result The certificate's public key, or NULL if it the public key could
-       not be extracted (this can happen with DSA certificate chains if the
+    @function SecTrustCopyPublicKey
+    @abstract Return the public key for a leaf certificate after it has
+    been evaluated.
+    @param trust A reference to the trust object which has been evaluated.
+    @result The certificate's public key, or NULL if it the public key could
+    not be extracted (this can happen with DSA certificate chains if the
     parameters in the chain cannot be found).  The caller is responsible
     for calling CFRelease on the returned key when it is no longer needed.
     parameters in the chain cannot be found).  The caller is responsible
     for calling CFRelease on the returned key when it is no longer needed.
-*/
+ */
 SecKeyRef SecTrustCopyPublicKey(SecTrustRef trust)
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0);
 
 /*!
 SecKeyRef SecTrustCopyPublicKey(SecTrustRef trust)
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0);
 
 /*!
-       @function SecTrustGetCertificateCount
-       @abstract Returns the number of certificates in an evaluated certificate
+    @function SecTrustGetCertificateCount
+    @abstract Returns the number of certificates in an evaluated certificate
     chain.
     chain.
-       @param trust Reference to a trust object.
-       @result The number of certificates in the trust chain.  This function will
-    return 1 if the trust has not been evaluated, and the number of
-    certificates in the chain including the anchor if it has.
-*/
+    @param trust A reference to a trust object.
+    @result The number of certificates in the trust chain, including the anchor.
+    @discussion Important: if the trust reference has not yet been evaluated,
+    this function will evaluate it first before returning. If speed is critical,
+    you may want to call SecTrustGetTrustResult first to make sure that a
+    result other than kSecTrustResultInvalid is present for the trust object.
+ */
 CFIndex SecTrustGetCertificateCount(SecTrustRef trust)
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0);
 
 /*!
 CFIndex SecTrustGetCertificateCount(SecTrustRef trust)
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0);
 
 /*!
-       @function SecTrustGetCertificateAtIndex
-       @abstract Returns a certificate from the trust chain.
-       @param trust Reference to a trust object.
-       @param ix The index of the requested certificate.  Indices run from 0
+    @function SecTrustGetCertificateAtIndex
+    @abstract Returns a certificate from the trust chain.
+    @param trust Reference to a trust object.
+    @param ix The index of the requested certificate.  Indices run from 0
     (leaf) to the anchor (or last certificate found if no anchor was found).
     The leaf cert (index 0) is always present regardless of whether the trust
     reference has been evaluated or not.
     (leaf) to the anchor (or last certificate found if no anchor was found).
     The leaf cert (index 0) is always present regardless of whether the trust
     reference has been evaluated or not.
-       @result A SecCertificateRef for the requested certificate.
-*/
+    @result A SecCertificateRef for the requested certificate.
+ */
 SecCertificateRef SecTrustGetCertificateAtIndex(SecTrustRef trust, CFIndex ix)
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0);
 SecCertificateRef SecTrustGetCertificateAtIndex(SecTrustRef trust, CFIndex ix)
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0);
-       
+
 /*!
 /*!
-       @function SecTrustCopyProperties
-       @abstract Return a property array for this trust evaluation.
-       @param trust A reference to the trust object. If the trust has not been
-       evaluated, the returned property array will be empty.
+    @function SecTrustCopyExceptions
+    @abstract Returns an opaque cookie which will allow future evaluations
+    of the current certificate to succeed.
+    @param trust A reference to an evaluated trust object.
+    @result An opaque cookie which when passed to SecTrustSetExceptions() will
+    cause a call to SecTrustEvaluate() return kSecTrustResultProceed.  This
+    will happen upon subsequent evaluation of the current certificate unless
+    some new error starts happening that wasn't being reported when the cookie
+    was returned from this function (for example, if the certificate expires
+    then evaluation will start failing again until a new cookie is obtained.)
+    @discussion Normally this API should only be called once the errors have
+    been presented to the user and the user decided to trust the current
+    certificate chain regardless of the errors being presented, for the
+    current application/server/protocol combination.
+ */
+CFDataRef SecTrustCopyExceptions(SecTrustRef trust)
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0);
+
+/*!
+    @function SecTrustSetExceptions
+    @abstract Set a trust cookie to be used for evaluating this certificate chain.
+    @param trust A reference to a trust object.
+    @param exceptions An exceptions cookie as returned by a call to
+    SecTrustCopyExceptions() in the past.
+    @result Upon calling SecTrustEvaluate(), any failures that where present at the
+    time the exceptions object was created are ignored, and instead of returning
+    kSecTrustResultRecoverableTrustFailure, kSecTrustResultProceed will be returned
+    (if the certificate for which exceptions was created matches the current leaf
+    certificate).
+    @result Returns true if the exceptions cookies was valid and matches the current
+    leaf certificate, false otherwise.  This function will invalidate the existing
+    trust result, requiring a subsequent evaluation for the newly-set exceptions.
+    Note that this function returning true doesn't mean the caller can skip calling
+    SecTrustEvaluate, as there may be new errors since the exceptions cookie was
+    created (for example, a certificate may have subsequently expired.)
+    @discussion Clients of this interface will need to establish the context of this
+    exception to later decide when this exception cookie is to be used.
+    Examples of this context would be the server we are connecting to, the ssid
+    of the wireless network for which this cert is needed, the account for which
+    this cert should be considered valid, and so on.
+ */
+bool SecTrustSetExceptions(SecTrustRef trust, CFDataRef exceptions)
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0);
+
+/*!
+    @function SecTrustCopyProperties
+    @abstract Return a property array for this trust evaluation.
+    @param trust A reference to a trust object. If the trust has not been
+    evaluated, the returned property array will be empty.
     @result A property array. It is the caller's responsibility to CFRelease
     the returned array when it is no longer needed.
     @result A property array. It is the caller's responsibility to CFRelease
     the returned array when it is no longer needed.
-       @discussion This function returns an ordered array of CFDictionaryRef
-       instances for each certificate in the chain. Indices run from 0 (leaf) to
-    the anchor (or last certificate found if no anchor was found). The property
-       at index 0 of the array may also include general information about the
-       entire chain's validity in the context of this trust evaluation. See the
-       "Trust Property Constants" section for a list of currently defined keys.
-*/
+    @discussion This function returns an ordered array of CFDictionaryRef
+    instances for each certificate in the chain. Indices run from 0 (leaf) to
+    the anchor (or last certificate found if no anchor was found.) See the
+    "Trust Property Constants" section for a list of currently defined keys.
+ */
 CFArrayRef SecTrustCopyProperties(SecTrustRef trust)
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0);
 
 CFArrayRef SecTrustCopyProperties(SecTrustRef trust)
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0);
 
+/*!
+    @function SecTrustCopyResult
+    @abstract Returns a dictionary containing information about the
+    evaluated certificate chain for use by clients.
+    @param trust A reference to a trust object.
+    @result A dictionary with various fields that can be displayed to the user,
+    or NULL if no additional info is available or the trust has not yet been
+    validated.  The caller is responsible for calling CFRelease on the value
+    returned when it is no longer needed.
+    @discussion Returns a dictionary for the overall trust evaluation. See the
+    "Trust Result Constants" section for a list of currently defined keys.
+ */
+CFDictionaryRef SecTrustCopyResult(SecTrustRef trust)
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+
+/*!
+    @function SecTrustSetOCSPResponse
+    @abstract Attach OCSPResponse data to a trust object.
+    @param trust A reference to a trust object.
+    @param responseData This may be either a CFData object containing a single
+    DER-encoded OCSPResponse (per RFC 2560), or a CFArray of these.
+    @result A result code. See "Security Error Codes" (SecBase.h).
+    @discussion Allows the caller to provide OCSPResponse data (which may be
+    obtained during a TLS/SSL handshake, per RFC 3546) as input to a trust
+    evaluation. If this data is available, it can obviate the need to contact
+    an OCSP server for current revocation information.
+ */
+OSStatus SecTrustSetOCSPResponse(SecTrustRef trust, CFTypeRef responseData)
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+
+
+/*
+ *  Legacy functions (OS X only)
+ */
+#if TARGET_OS_MAC && !TARGET_OS_IPHONE
+#include <Security/cssmtype.h>
+#include <Security/cssmapple.h>
+
+/*!
+    @typedef SecTrustUserSetting
+    @abstract Specifies a user-specified trust setting value.
+    @discussion Deprecated in OS X 10.9. User trust settings are managed by
+    functions in SecTrustSettings.h (starting with OS X 10.5), and by the
+    SecTrustCopyExceptions and SecTrustSetExceptions functions (starting with
+    iOS 4 and OS X 10.9). The latter two functions are recommended for both OS X
+    and iOS, as they avoid the need to explicitly specify these values.
+ */
+typedef SecTrustResultType SecTrustUserSetting
+    __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_9, __IPHONE_NA, __IPHONE_NA);
+
+/*!
+    @typedef SecTrustOptionFlags
+    @abstract Options for customizing trust evaluation.
+    @constant kSecTrustOptionAllowExpired Allow expired certificates.
+    @constant kSecTrustOptionLeafIsCA Allow CA as leaf certificate.
+    @constant kSecTrustOptionFetchIssuerFromNet Allow network fetch of CA cert.
+    @constant kSecTrustOptionAllowExpiredRoot Allow expired roots.
+    @constant kSecTrustOptionRequireRevPerCert Require positive revocation
+    check per certificate.
+    @constant kSecTrustOptionUseTrustSettings Use TrustSettings instead of
+    anchors.
+    @constant kSecTrustOptionImplicitAnchors Properly self-signed certs are
+    treated as anchors implicitly.
+ */
+typedef uint32_t SecTrustOptionFlags;
+enum {
+    kSecTrustOptionAllowExpired       = 0x00000001,
+    kSecTrustOptionLeafIsCA           = 0x00000002,
+    kSecTrustOptionFetchIssuerFromNet = 0x00000004,
+    kSecTrustOptionAllowExpiredRoot   = 0x00000008,
+    kSecTrustOptionRequireRevPerCert  = 0x00000010,
+    kSecTrustOptionUseTrustSettings   = 0x00000020,
+    kSecTrustOptionImplicitAnchors    = 0x00000040
+};
+
+/*!
+    @function SecTrustSetOptions
+    @abstract Sets optional flags for customizing a trust evaluation.
+    @param trustRef A trust reference.
+    @param options Flags to change evaluation behavior for this trust.
+    @result A result code. See "Security Error Codes" (SecBase.h).
+    @discussion This function is not available on iOS. Use SecTrustSetExceptions
+    and SecTrustCopyExceptions to modify default trust results, and
+    SecTrustSetNetworkFetchAllowed to specify whether missing CA certificates
+    can be fetched from the network.
+ */
+OSStatus SecTrustSetOptions(SecTrustRef trustRef, SecTrustOptionFlags options)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+
+/*!
+    @function SecTrustSetParameters
+    @abstract Sets the action and action data for a trust object.
+    @param trustRef The reference to the trust to change.
+    @param action A trust action.
+    @param actionData A reference to data associated with this action.
+    @result A result code. See "Security Error Codes" (SecBase.h).
+    @discussion This function is deprecated in OS X 10.7 and later, where it
+    was replaced by SecTrustSetOptions, and is not available on iOS. Your code
+    should use SecTrustSetExceptions and SecTrustCopyExceptions to modify default
+    trust results, and SecTrustSetNetworkFetchAllowed to specify whether missing
+    CA certificates can be fetched from the network.
+ */
+OSStatus SecTrustSetParameters(SecTrustRef trustRef,
+    CSSM_TP_ACTION action, CFDataRef actionData)
+    __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA);
+
+/*!
+    @function SecTrustSetKeychains
+    @abstract Sets the keychains for a given trust object.
+    @param trust A reference to a trust object.
+    @param keychainOrArray A reference to an array of keychains to search, a
+    single keychain, or NULL to use the default keychain search list.
+    @result A result code. See "Security Error Codes" (SecBase.h).
+    @discussion By default, the user's keychain search list and the system
+    anchors keychain are searched for certificates to complete the chain. You
+    can specify a zero-element array if you do not want any keychains searched.
+    Note: this function is not applicable to iOS.
+ */
+OSStatus SecTrustSetKeychains(SecTrustRef trust, CFTypeRef keychainOrArray)
+    __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_NA);
+
+/*!
+    @function SecTrustGetResult
+    @abstract Returns detailed information on the outcome of an evaluation.
+    @param trustRef A reference to a trust object.
+    @param result A pointer to the result from the call to SecTrustEvaluate.
+    @param certChain On return, a pointer to the certificate chain used to
+    validate the input certificate. Call the CFRelease function to release
+    this pointer.
+    @param statusChain On return, a pointer to the status of the certificate
+    chain. Do not attempt to free this pointer; it remains valid until the
+    trust is destroyed or the next call to SecTrustEvaluate.
+    @result A result code. See "Security Error Codes" (SecBase.h).
+    @discussion This function is deprecated in OS X 10.7 and later,
+    and is not available on iOS.
+    To get the complete certificate chain, use SecTrustGetCertificateCount and
+    SecTrustGetCertificateAtIndex. To get detailed status information for each
+    certificate, use SecTrustCopyProperties. To get the overall trust result
+    for the evaluation, use SecTrustGetTrustResult.
+ */
+OSStatus SecTrustGetResult(SecTrustRef trustRef, SecTrustResultType *result,
+    CFArrayRef *certChain, CSSM_TP_APPLE_EVIDENCE_INFO **statusChain)
+    __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA);
+
+/*!
+    @function SecTrustGetCssmResult
+    @abstract Gets the CSSM trust result.
+    @param trust A reference to a trust.
+    @param result On return, a pointer to the CSSM trust result.
+    @result A result code. See "Security Error Codes" (SecBase.h).
+    @discussion This function is deprecated in OS X 10.7 and later,
+    and is not available on iOS.
+    To get detailed status information for each certificate, use
+    SecTrustCopyProperties. To get the overall trust result for the evaluation,
+    use SecTrustGetTrustResult.
+ */
+OSStatus SecTrustGetCssmResult(SecTrustRef trust,
+    CSSM_TP_VERIFY_CONTEXT_RESULT_PTR *result)
+    __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA);
+
+/*!
+    @function SecTrustGetCssmResultCode
+    @abstract Gets the result code from the most recent call to SecTrustEvaluate
+    for the specified trust.
+    @param trust A reference to a trust.
+    @param resultCode On return, the result code produced by the most recent
+    evaluation of the given trust (cssmerr.h). The value of resultCode is
+    undefined if SecTrustEvaluate has not been called.
+    @result A result code. See "Security Error Codes" (SecBase.h). Returns
+    errSecTrustNotAvailable if SecTrustEvaluate has not been called for the
+    specified trust.
+    @discussion This function is deprecated in OS X 10.7 and later,
+    and is not available on iOS.
+    To get detailed status information for each certificate, use
+    SecTrustCopyProperties. To get the overall trust result for the evaluation,
+    use SecTrustGetTrustResult.
+ */
+OSStatus SecTrustGetCssmResultCode(SecTrustRef trust, OSStatus *resultCode)
+    __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA);
+
+/*!
+    @function SecTrustGetTPHandle
+    @abstract Gets the CSSM trust handle
+    @param trust A reference to a trust.
+    @param handle On return, a CSSM trust handle.
+    @result A result code. See "Security Error Codes" (SecBase.h).
+    @discussion This function is deprecated in OS X 10.7 and later.
+ */
+OSStatus SecTrustGetTPHandle(SecTrustRef trust, CSSM_TP_HANDLE *handle)
+    __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA);
+
+/*!
+    @function SecTrustCopyAnchorCertificates
+    @abstract Returns an array of default anchor (root) certificates used by
+    the system.
+    @param anchors On return, an array containing the system's default anchors
+    (roots). Call the CFRelease function to release this pointer.
+    @result A result code. See "Security Error Codes" (SecBase.h).
+    @discussion This function is not available on iOS, as certificate data
+    for system-trusted roots is currently unavailable on that platform.
+ */
+OSStatus SecTrustCopyAnchorCertificates(CFArrayRef *anchors)
+    __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_NA);
+
+#endif /* TARGET_OS_MAC && !TARGET_OS_IPHONE */
+
 
 #if defined(__cplusplus)
 }
 
 #if defined(__cplusplus)
 }
index 3089f1f40349a45ca973e0c4e55ab70744ad7b2c..2244a018627977d65e7843d3b333b02cb6c371eb 100644 (file)
@@ -1,15 +1,15 @@
 /*
  * Copyright (c) 2003-2010 Apple Inc. All Rights Reserved.
 /*
  * Copyright (c) 2003-2010 Apple Inc. All Rights Reserved.
- * 
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -69,8 +69,8 @@ OSStatus SecTrustGetUserTrust(SecCertificateRef certificate, SecPolicyRef policy
        @param trustSetting The user-specified trust settings.
        @result A result code. See "Security Error Codes" (SecBase.h).
        @availability Mac OS X version 10.4. Deprecated in Mac OS X version 10.5.
        @param trustSetting The user-specified trust settings.
        @result A result code. See "Security Error Codes" (SecBase.h).
        @availability Mac OS X version 10.4. Deprecated in Mac OS X version 10.5.
-       @discussion as of Mac OS version 10.5, this will result in a call to 
-        SecTrustSettingsSetTrustSettings(). 
+       @discussion as of Mac OS version 10.5, this will result in a call to
+        SecTrustSettingsSetTrustSettings().
 */
 OSStatus SecTrustSetUserTrust(SecCertificateRef certificate, SecPolicyRef policy, SecTrustUserSetting trustSetting)
        /*DEPRECATED_IN_MAC_OS_X_VERSION_10_5_AND_LATER*/;
 */
 OSStatus SecTrustSetUserTrust(SecCertificateRef certificate, SecPolicyRef policy, SecTrustUserSetting trustSetting)
        /*DEPRECATED_IN_MAC_OS_X_VERSION_10_5_AND_LATER*/;
@@ -85,7 +85,7 @@ OSStatus SecTrustSetUserTrust(SecCertificateRef certificate, SecPolicyRef policy
 
        @This is the private version of what used to be SecTrustSetUserTrust(); it operates
         on UserTrust entries as that function used to. The current SecTrustSetUserTrust()
 
        @This is the private version of what used to be SecTrustSetUserTrust(); it operates
         on UserTrust entries as that function used to. The current SecTrustSetUserTrust()
-        function operated on Trust Settings. 
+        function operated on Trust Settings.
 */
 OSStatus SecTrustSetUserTrustLegacy(SecCertificateRef certificate, SecPolicyRef policy, SecTrustUserSetting trustSetting);
 
 */
 OSStatus SecTrustSetUserTrustLegacy(SecCertificateRef certificate, SecPolicyRef policy, SecTrustUserSetting trustSetting);
 
@@ -111,15 +111,34 @@ OSStatus SecTrustGetCSSMAnchorCertificates(const CSSM_DATA **cssmAnchors, uint32
        errSecTrustNotAvailable is returned. If the certificate is not an extended validation certificate, there is
        no extended result data and errSecDataNotAvailable is returned. Currently, only one dictionary key is defined
        (kSecEVOrganizationName).
        errSecTrustNotAvailable is returned. If the certificate is not an extended validation certificate, there is
        no extended result data and errSecDataNotAvailable is returned. Currently, only one dictionary key is defined
        (kSecEVOrganizationName).
+
+       Note: this function will be deprecated in a future release of OS X. Your
+       code should use SecTrustCopyResult to obtain the trust results dictionary.
 */
 */
-OSStatus SecTrustCopyExtendedResult(SecTrustRef trust, CFDictionaryRef *result);
+OSStatus SecTrustCopyExtendedResult(SecTrustRef trust, CFDictionaryRef *result)
+       __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
+
+
+/*!
+    @enum Trust Result Constants
+    @discussion Predefined key constants used to obtain values in a
+        dictionary of trust evaluation results for a certificate chain,
+        as retrieved from a call to SecTrustCopyResult.
+
+    @constant kSecTrustResultDetails
+        This key will be present if a trust evaluation has been performed.
+        Its value is a CFArrayRef of CFDictionaryRef representing detailed
+        status info for each certificate in the completed chain.
+ */
+extern CFTypeRef kSecTrustResultDetails
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_NA);
 
 
 /*
  * Preference-related strings for Revocation policies.
  */
 
 
 /*
  * Preference-related strings for Revocation policies.
  */
-/* 
+
+/*
  * Preference domain, i.e., the name of a plist in ~/Library/Preferences or in
  * /Library/Preferences
  */
  * Preference domain, i.e., the name of a plist in ~/Library/Preferences or in
  * /Library/Preferences
  */
@@ -132,12 +151,12 @@ OSStatus SecTrustCopyExtendedResult(SecTrustRef trust, CFDictionaryRef *result);
   #define kSecRevocationBestAttempt                    CFSTR("BestAttempt")
   #define kSecRevocationRequireIfPresent       CFSTR("RequireIfPresent")
   #define kSecRevocationRequireForAll          CFSTR("RequireForAll")
   #define kSecRevocationBestAttempt                    CFSTR("BestAttempt")
   #define kSecRevocationRequireIfPresent       CFSTR("RequireIfPresent")
   #define kSecRevocationRequireForAll          CFSTR("RequireForAll")
-  
+
 /* Which first if both enabled? */
 #define kSecRevocationWhichFirst                       CFSTR("RevocationFirst")
   #define kSecRevocationOcspFirst                      CFSTR("OCSP")
   #define kSecRevocationCrlFirst                       CFSTR("CRL")
 /* Which first if both enabled? */
 #define kSecRevocationWhichFirst                       CFSTR("RevocationFirst")
   #define kSecRevocationOcspFirst                      CFSTR("OCSP")
   #define kSecRevocationCrlFirst                       CFSTR("CRL")
-  
+
 /* boolean: A "this policy is sufficient per cert" for each */
 #define kSecRevocationOCSPSufficientPerCert    CFSTR("OCSPSufficientPerCert")
 #define kSecRevocationCRLSufficientPerCert     CFSTR("CRLSufficientPerCert")
 /* boolean: A "this policy is sufficient per cert" for each */
 #define kSecRevocationOCSPSufficientPerCert    CFSTR("OCSPSufficientPerCert")
 #define kSecRevocationCRLSufficientPerCert     CFSTR("CRLSufficientPerCert")
@@ -145,10 +164,9 @@ OSStatus SecTrustCopyExtendedResult(SecTrustRef trust, CFDictionaryRef *result);
 /* local OCSP responder URI, value arbitrary string value */
 #define kSecOCSPLocalResponder                         CFSTR("OCSPLocalResponder")
 
 /* local OCSP responder URI, value arbitrary string value */
 #define kSecOCSPLocalResponder                         CFSTR("OCSPLocalResponder")
 
-/* Extended trust result keys */
-#define kSecEVOrganizationName                         CFSTR("Organization")                   /* validated EV organization name */
-#define kSecTrustEvaluationDate                                CFSTR("TrustEvaluationDate")    /* date when this trust evaluation took place */
-#define kSecTrustExpirationDate                                CFSTR("TrustExpirationDate")    /* date after which the trust result should be re-evaluated */
+/* Extended trust result keys (now in public API) */
+#define kSecEVOrganizationName                         kSecTrustOrganizationName
+#define kSecTrustExpirationDate                                kSecTrustRevocationValidUntilDate
 
 #if defined(__cplusplus)
 }
 
 #if defined(__cplusplus)
 }
index 7963726d91beab91a056d1bbdd0426b29a0fd1e1..15dedbea67774d194d7292605961c8a28ab86016 100644 (file)
@@ -37,7 +37,6 @@
 #include "Trust.h"
 #include "SecKeychainPriv.h"
 #include "Globals.h"
 #include "Trust.h"
 #include "SecKeychainPriv.h"
 #include "Globals.h"
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 #include <security_utilities/threading.h>
 #include <security_utilities/globalizer.h> 
 #include <security_utilities/errors.h> 
 #include <security_utilities/threading.h>
 #include <security_utilities/globalizer.h> 
 #include <security_utilities/errors.h> 
        OSStatus __secapiresult; \
        try {
 #define END_RCSAPI             \
        OSStatus __secapiresult; \
        try {
 #define END_RCSAPI             \
-               __secapiresult=noErr; \
+               __secapiresult=errSecSuccess; \
        } \
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); } \
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); } \
        } \
        catch (const MacOSError &err) { __secapiresult=err.osStatus(); } \
        catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); } \
-       catch (const std::bad_alloc &) { __secapiresult=memFullErr; } \
-       catch (...) { __secapiresult=internalComponentErr; } \
+       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; } \
+       catch (...) { __secapiresult=errSecInternalComponent; } \
        return __secapiresult;
 
 #define END_RCSAPI0            \
        return __secapiresult;
 
 #define END_RCSAPI0            \
@@ -191,15 +190,15 @@ static TrustSettings *tsGetGlobalTrustSettings(
        assert(globalTrustSettings[domain] == NULL);
        
        /* try to find one */
        assert(globalTrustSettings[domain] == NULL);
        
        /* try to find one */
-       OSStatus result = noErr;
+       OSStatus result = errSecSuccess;
        TrustSettings *ts = NULL;
        /* don't create; trim if found */
        result = TrustSettings::CreateTrustSettings(domain, CREATE_NO, TRIM_YES, ts);
        TrustSettings *ts = NULL;
        /* don't create; trim if found */
        result = TrustSettings::CreateTrustSettings(domain, CREATE_NO, TRIM_YES, ts);
-       if(result != noErr && result != errSecNoTrustSettings) {
+       if(result != errSecSuccess && result != errSecNoTrustSettings) {
                /* gross error */
                MacOSError::throwMe(result);
        }
                /* gross error */
                MacOSError::throwMe(result);
        }
-       else if (result != noErr) {
+       else if (result != errSecSuccess) {
                /* 
                 * No TrustSettings for this domain, actually a fairly common case. 
                 * Optimize: don't bother trying this again.
                /* 
                 * No TrustSettings for this domain, actually a fairly common case. 
                 * Optimize: don't bother trying this again.
@@ -243,7 +242,7 @@ static OSStatus tsTrustSettingsCallback (
        trustSettingsDbg("tsTrustSettingsCallback, event %d", (int)keychainEvent);
        if(keychainEvent != kSecTrustSettingsChangedEvent) {
                /* should not happen, right? */
        trustSettingsDbg("tsTrustSettingsCallback, event %d", (int)keychainEvent);
        if(keychainEvent != kSecTrustSettingsChangedEvent) {
                /* should not happen, right? */
-               return noErr;
+               return errSecSuccess;
        }
        if(info->pid == getpid()) {
                /* 
        }
        if(info->pid == getpid()) {
                /* 
@@ -254,7 +253,7 @@ static OSStatus tsTrustSettingsCallback (
        else {
                tsPurgeCache();
        }
        else {
                tsPurgeCache();
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 /* 
 }
 
 /* 
@@ -269,7 +268,7 @@ static void tsRegisterCallback()
        OSStatus ortn = SecKeychainAddCallback(tsTrustSettingsCallback, 
                kSecTrustSettingsChangedEventMask, NULL);
        if(ortn) {
        OSStatus ortn = SecKeychainAddCallback(tsTrustSettingsCallback, 
                kSecTrustSettingsChangedEventMask, NULL);
        if(ortn) {
-               trustSettingsDbg("tsRegisterCallback: SecKeychainAddCallback returned %ld", ortn);
+               trustSettingsDbg("tsRegisterCallback: SecKeychainAddCallback returned %d", (int)ortn);
                /* Not sure how this could ever happen - maybe if there is no run loop active? */
        }
        sutRegisteredCallback = true;
                /* Not sure how this could ever happen - maybe if there is no run loop active? */
        }
        sutRegisteredCallback = true;
@@ -325,7 +324,7 @@ static OSStatus tsCopyTrustSettings(
        if (result == errSecNoTrustSettings) {
                return errSecItemNotFound;
        }
        if (result == errSecNoTrustSettings) {
                return errSecItemNotFound;
        }
-       else if (result != noErr) {
+       else if (result != errSecSuccess) {
                return result;
        }
        
                return result;
        }
        
@@ -407,7 +406,7 @@ static OSStatus tsCopyCertsCommon(
        CFRetain(*certArray);
        trustSettingsDbg("tsCopyCertsCommon: %ld certs found",
                CFArrayGetCount(outArray));
        CFRetain(*certArray);
        trustSettingsDbg("tsCopyCertsCommon: %ld certs found",
                CFArrayGetCount(outArray));
-       return noErr;
+       return errSecSuccess;
 }
 
 #pragma mark --- SPI functions ---
 }
 
 #pragma mark --- SPI functions ---
@@ -518,14 +517,14 @@ OSStatus SecTrustSettingsEvaluateCert(
                        trustSettingsDbg("SecTrustSettingsEvaluateCert: found in domain %d", domain);
                        *foundAnyEntry = true;
                        *foundMatchingEntry = true;
                        trustSettingsDbg("SecTrustSettingsEvaluateCert: found in domain %d", domain);
                        *foundAnyEntry = true;
                        *foundMatchingEntry = true;
-                       return noErr;
+                       return errSecSuccess;
                }
                foundAny |= foundAnyHere;
        }
        trustSettingsDbg("SecTrustSettingsEvaluateCert: NOT FOUND");
        *foundAnyEntry = foundAny;
        *foundMatchingEntry = false;
                }
                foundAny |= foundAnyHere;
        }
        trustSettingsDbg("SecTrustSettingsEvaluateCert: NOT FOUND");
        *foundAnyEntry = foundAny;
        *foundMatchingEntry = false;
-       return noErr;
+       return errSecSuccess;
        END_RCSAPI
 }
 
        END_RCSAPI
 }
 
@@ -630,7 +629,7 @@ CFStringRef SecTrustSettingsCertHashStrFromData(
                return NULL;
        }
 
                return NULL;
        }
 
-       CC_SHA1(cert, certLen, digest);
+       CC_SHA1(cert, (CC_LONG)certLen, digest);
 
        for(dex=0; dex<CC_SHA1_DIGEST_LENGTH; dex++) {
                unsigned c = *inp++;
 
        for(dex=0; dex<CC_SHA1_DIGEST_LENGTH; dex++) {
                unsigned c = *inp++;
@@ -662,7 +661,7 @@ OSStatus SecTrustSettingsSetTrustSettingsExternal(
        TrustSettings* ts;
        
        result = TrustSettings::CreateTrustSettings(kSecTrustSettingsDomainMemory, settingsIn, ts);
        TrustSettings* ts;
        
        result = TrustSettings::CreateTrustSettings(kSecTrustSettingsDomainMemory, settingsIn, ts);
-       if (result != noErr) {
+       if (result != errSecSuccess) {
                return result;
        }
        
                return result;
        }
        
@@ -672,7 +671,7 @@ OSStatus SecTrustSettingsSetTrustSettingsExternal(
                ts->setTrustSettings(certRef, trustSettingsDictOrArray);        
        }
        *settingsOut = ts->createExternal();
                ts->setTrustSettings(certRef, trustSettingsDictOrArray);        
        }
        *settingsOut = ts->createExternal();
-       return noErr;
+       return errSecSuccess;
 
        END_RCSAPI
 }
 
        END_RCSAPI
 }
@@ -687,7 +686,7 @@ OSStatus SecTrustSettingsCopyTrustSettings(
        TS_REQUIRED(trustSettings)
 
        OSStatus result = tsCopyTrustSettings(certRef, domain, trustSettings, NULL);
        TS_REQUIRED(trustSettings)
 
        OSStatus result = tsCopyTrustSettings(certRef, domain, trustSettings, NULL);
-       if (result == noErr && *trustSettings == NULL) {
+       if (result == errSecSuccess && *trustSettings == NULL) {
                result = errSecItemNotFound; /* documented result if no trust settings exist */
        }
        return result;
                result = errSecItemNotFound; /* documented result if no trust settings exist */
        }
        return result;
@@ -701,7 +700,7 @@ OSStatus SecTrustSettingsCopyModificationDate(
        TS_REQUIRED(modificationDate)
 
        OSStatus result = tsCopyTrustSettings(certRef, domain, NULL, modificationDate); 
        TS_REQUIRED(modificationDate)
 
        OSStatus result = tsCopyTrustSettings(certRef, domain, NULL, modificationDate); 
-       if (result == noErr && *modificationDate == NULL) {
+       if (result == errSecSuccess && *modificationDate == NULL) {
                result = errSecItemNotFound; /* documented result if no trust settings exist */
        }
        return result;
                result = errSecItemNotFound; /* documented result if no trust settings exist */
        }
        return result;
@@ -725,7 +724,7 @@ OSStatus SecTrustSettingsSetTrustSettings(
        TrustSettings* ts;
        
        result = TrustSettings::CreateTrustSettings(domain, CREATE_YES, TRIM_NO, ts);
        TrustSettings* ts;
        
        result = TrustSettings::CreateTrustSettings(domain, CREATE_YES, TRIM_NO, ts);
-       if (result != noErr) {
+       if (result != errSecSuccess) {
                return result;
        }
        
                return result;
        }
        
@@ -734,7 +733,7 @@ OSStatus SecTrustSettingsSetTrustSettings(
        ts->setTrustSettings(certRef, trustSettingsDictOrArray);
        ts->flushToDisk();
        tsTrustSettingsChanged();
        ts->setTrustSettings(certRef, trustSettingsDictOrArray);
        ts->flushToDisk();
        tsTrustSettingsChanged();
-       return noErr;
+       return errSecSuccess;
 
        END_RCSAPI
 }
 
        END_RCSAPI
 }
@@ -755,7 +754,7 @@ OSStatus SecTrustSettingsRemoveTrustSettings(
        TrustSettings* ts;
        
        result = TrustSettings::CreateTrustSettings(domain, CREATE_NO, TRIM_NO, ts);
        TrustSettings* ts;
        
        result = TrustSettings::CreateTrustSettings(domain, CREATE_NO, TRIM_NO, ts);
-       if (result != noErr) {
+       if (result != errSecSuccess) {
                return result;
        }
 
                return result;
        }
 
@@ -767,7 +766,7 @@ OSStatus SecTrustSettingsRemoveTrustSettings(
        ts->deleteTrustSettings(cert);
        ts->flushToDisk();
        tsTrustSettingsChanged();
        ts->deleteTrustSettings(cert);
        ts->flushToDisk();
        tsTrustSettingsChanged();
-       return noErr;
+       return errSecSuccess;
 
        END_RCSAPI
 }
 
        END_RCSAPI
 }
@@ -785,7 +784,7 @@ OSStatus SecTrustSettingsCopyCertificates(
        TrustSettings* ts;
        
        result = TrustSettings::CreateTrustSettings(domain, CREATE_NO, TRIM_NO, ts);
        TrustSettings* ts;
        
        result = TrustSettings::CreateTrustSettings(domain, CREATE_NO, TRIM_NO, ts);
-       if (result != noErr) {
+       if (result != errSecSuccess) {
                return result;
        }
 
                return result;
        }
 
@@ -847,14 +846,14 @@ OSStatus SecTrustSettingsCreateExternalRepresentation(
        TrustSettings* ts;
        
        result = TrustSettings::CreateTrustSettings(domain, CREATE_NO, TRIM_NO, ts);
        TrustSettings* ts;
        
        result = TrustSettings::CreateTrustSettings(domain, CREATE_NO, TRIM_NO, ts);
-       if (result != noErr) {
+       if (result != errSecSuccess) {
                return result;
        }
 
        auto_ptr<TrustSettings>_(ts);
 
        *trustSettings = ts->createExternal();
                return result;
        }
 
        auto_ptr<TrustSettings>_(ts);
 
        *trustSettings = ts->createExternal();
-       return noErr;
+       return errSecSuccess;
 
        END_RCSAPI
 }
 
        END_RCSAPI
 }
@@ -877,7 +876,7 @@ OSStatus SecTrustSettingsImportExternalRepresentation(
        TrustSettings* ts;
        
        result = TrustSettings::CreateTrustSettings(domain, trustSettings, ts);
        TrustSettings* ts;
        
        result = TrustSettings::CreateTrustSettings(domain, trustSettings, ts);
-       if (result != noErr) {
+       if (result != errSecSuccess) {
                return result;
        }
 
                return result;
        }
 
@@ -885,7 +884,7 @@ OSStatus SecTrustSettingsImportExternalRepresentation(
 
        ts->flushToDisk();
        tsTrustSettingsChanged();
 
        ts->flushToDisk();
        tsTrustSettingsChanged();
-       return noErr;
+       return errSecSuccess;
 
        END_RCSAPI
 }
 
        END_RCSAPI
 }
index c291a63770a76979d066646311780121430829cd..3b41c457447f077a7d297836f1568599c181f804 100644 (file)
@@ -1,15 +1,15 @@
 /*
  * Copyright (c) 2002-2004 Apple Computer, Inc. All Rights Reserved.
 /*
  * Copyright (c) 2002-2004 Apple Computer, Inc. All Rights Reserved.
- * 
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -28,8 +28,8 @@
 
 #include "SecBridge.h"
 
 
 #include "SecBridge.h"
 
-        
-        
+
+
 static inline CssmData cfData(CFDataRef data)
 {
     return CssmData(const_cast<UInt8 *>(CFDataGetBytePtr(data)),
 static inline CssmData cfData(CFDataRef data)
 {
     return CssmData(const_cast<UInt8 *>(CFDataGetBytePtr(data)),
@@ -71,8 +71,9 @@ OSStatus SecTrustedApplicationSetData(SecTrustedApplicationRef appRef,
        CFDataRef dataRef)
 {
        BEGIN_SECAPI
        CFDataRef dataRef)
 {
        BEGIN_SECAPI
-       secdebug("UNIMP", "legacy SecTrustedApplicationSetData not re-implemented");
-//     TrustedApplication::required(appRef)->data(cfData(dataRef));
+       if (!dataRef)
+               return errSecParam;
+       TrustedApplication::required(appRef)->data(dataRef);
        END_SECAPI
 }
 
        END_SECAPI
 }
 
@@ -92,7 +93,7 @@ SecTrustedApplicationValidateWithPath(SecTrustedApplicationRef appRef, const cha
 // Convert from/to external data representation
 //
 OSStatus SecTrustedApplicationCopyExternalRepresentation(
 // Convert from/to external data representation
 //
 OSStatus SecTrustedApplicationCopyExternalRepresentation(
-       SecTrustedApplicationRef appRef, 
+       SecTrustedApplicationRef appRef,
        CFDataRef *externalRef)
 {
        BEGIN_SECAPI
        CFDataRef *externalRef)
 {
        BEGIN_SECAPI
@@ -117,7 +118,7 @@ SecTrustedApplicationMakeEquivalent(SecTrustedApplicationRef oldRef,
 {
        BEGIN_SECAPI
        if (flags & ~kSecApplicationValidFlags)
 {
        BEGIN_SECAPI
        if (flags & ~kSecApplicationValidFlags)
-               return paramErr;
+               return errSecParam;
        SecurityServer::ClientSession ss(Allocator::standard(), Allocator::standard());
        TrustedApplication *oldApp = TrustedApplication::required(oldRef);
        TrustedApplication *newApp = TrustedApplication::required(newRef);
        SecurityServer::ClientSession ss(Allocator::standard(), Allocator::standard());
        TrustedApplication *oldApp = TrustedApplication::required(oldRef);
        TrustedApplication *newApp = TrustedApplication::required(newRef);
@@ -131,7 +132,7 @@ SecTrustedApplicationRemoveEquivalence(SecTrustedApplicationRef appRef, UInt32 f
 {
        BEGIN_SECAPI
        if (flags & ~kSecApplicationValidFlags)
 {
        BEGIN_SECAPI
        if (flags & ~kSecApplicationValidFlags)
-               return paramErr;
+               return errSecParam;
        SecurityServer::ClientSession ss(Allocator::standard(), Allocator::standard());
        TrustedApplication *app = TrustedApplication::required(appRef);
        ss.removeCodeEquivalence(app->legacyHash(), app->path(),
        SecurityServer::ClientSession ss(Allocator::standard(), Allocator::standard());
        TrustedApplication *app = TrustedApplication::required(appRef);
        ss.removeCodeEquivalence(app->legacyHash(), app->path(),
@@ -148,19 +149,19 @@ OSStatus
 SecTrustedApplicationIsUpdateCandidate(const char *installroot, const char *path)
 {
     BEGIN_SECAPI
 SecTrustedApplicationIsUpdateCandidate(const char *installroot, const char *path)
 {
     BEGIN_SECAPI
-       
+
        // strip installroot
        if (installroot) {
                size_t rootlen = strlen(installroot);
                if (!strncmp(installroot, path, rootlen))
                        path += rootlen - 1;    // keep the slash
        }
        // strip installroot
        if (installroot) {
                size_t rootlen = strlen(installroot);
                if (!strncmp(installroot, path, rootlen))
                        path += rootlen - 1;    // keep the slash
        }
-               
+
        // look up in database
        static ModuleNexus<PathDatabase> paths;
        static ModuleNexus<RecursiveMutex> mutex;
        StLock<Mutex>_(mutex());
        // look up in database
        static ModuleNexus<PathDatabase> paths;
        static ModuleNexus<RecursiveMutex> mutex;
        StLock<Mutex>_(mutex());
-       
+
        if (!paths()[path])
                return CSSMERR_DL_RECORD_NOT_FOUND;     // whatever
     END_SECAPI
        if (!paths()[path])
                return CSSMERR_DL_RECORD_NOT_FOUND;     // whatever
     END_SECAPI
@@ -196,7 +197,7 @@ OSStatus SecTrustedApplicationCreateFromRequirement(const char *description,
        if (description == NULL)
                description = "csreq://";       // default to "generic requirement"
        SecPointer<TrustedApplication> app = new TrustedApplication(description, requirement);
        if (description == NULL)
                description = "csreq://";       // default to "generic requirement"
        SecPointer<TrustedApplication> app = new TrustedApplication(description, requirement);
-       Required(appRef) = app->handle();       
+       Required(appRef) = app->handle();
        END_SECAPI
 }
 
        END_SECAPI
 }
 
index 68acb0d309e7b7463a51b1fce2381208eb698e99..62a71d0f4a50bbe18284d791a2e741639ea1cd81 100644 (file)
@@ -1,15 +1,15 @@
 /*
  * Copyright (c) 2002-2004 Apple Computer, Inc. All Rights Reserved.
 /*
  * Copyright (c) 2002-2004 Apple Computer, Inc. All Rights Reserved.
- * 
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
index 400e808de602ba19710e742a0e5d14871bf54666..8d04231059a2123e347a5c6854233a6ae5771181 100644 (file)
@@ -34,7 +34,6 @@
 #include <security_asn1/SecNssCoder.h>
 #include <security_cdsa_utils/cuCdsaUtils.h>
 #include <security_utilities/devrandom.h>
 #include <security_asn1/SecNssCoder.h>
 #include <security_cdsa_utils/cuCdsaUtils.h>
 #include <security_utilities/devrandom.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 
 #include <assert.h>
 
 
 #include <assert.h>
 
@@ -193,7 +192,7 @@ static OSStatus opensslPbeParams(
                        return errSecUnknownFormat;
                }
        }
                        return errSecUnknownFormat;
                }
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 /* 
 }
 
 /* 
@@ -230,7 +229,7 @@ static OSStatus deriveKeyOpensslWrap(
        
        memset(&seed, 0, sizeof(seed));
        if(cfPhrase != NULL) {
        
        memset(&seed, 0, sizeof(seed));
        if(cfPhrase != NULL) {
-               unsigned len = CFDataGetLength(cfPhrase);
+               size_t len = CFDataGetLength(cfPhrase);
                coder.allocItem(seed.Param, len);
                memmove(seed.Param.Data, CFDataGetBytePtr(cfPhrase), len);
                CFRelease(cfPhrase);
                coder.allocItem(seed.Param, len);
                memmove(seed.Param.Data, CFDataGetBytePtr(cfPhrase), len);
                CFRelease(cfPhrase);
@@ -294,7 +293,7 @@ OSStatus SecImportRep::importWrappedKeyOpenssl(
        assert(cspHand != 0);
        
        if(keyParams == NULL) {
        assert(cspHand != 0);
        
        if(keyParams == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        
        OSStatus                                ortn;
        }
        
        OSStatus                                ortn;
@@ -389,7 +388,7 @@ OSStatus impExpWrappedKeyOpenSslExport(
        char                                    ivStr[3];
        
        if(keyParams == NULL) {
        char                                    ivStr[3];
        
        if(keyParams == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        
        /* we need a CSPDL handle - try to get it from the key */       
        }
        
        /* we need a CSPDL handle - try to get it from the key */       
index d0d53c7ab816f7230910650ee90d54beb2525645..c9e35458bc16269d7b8c3944db96b903f2fe6754 100644 (file)
@@ -67,6 +67,7 @@
 #include <Security/SecTrustedApplication.h>
 #include <Security/SecTrustSettings.h>
 #include <Security/SecImportExport.h>
 #include <Security/SecTrustedApplication.h>
 #include <Security/SecTrustSettings.h>
 #include <Security/SecImportExport.h>
+#include <Security/SecRandom.h>
 
 /* Code Signing */
 #include <Security/SecStaticCode.h>
 
 /* Code Signing */
 #include <Security/SecStaticCode.h>
index 4ecee452dc1f81da9d7a6d2b5104a47f875c9a1c..0c46e0c7307dbe82826e82207f4a498d21526532 100644 (file)
@@ -37,7 +37,6 @@
 #include <sys/param.h>
 #include <syslog.h>
 #include <pwd.h>
 #include <sys/param.h>
 #include <syslog.h>
 #include <pwd.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 #include <algorithm>
 #include <string>
 #include <stdio.h>
 #include <algorithm>
 #include <string>
 #include <stdio.h>
@@ -110,6 +109,24 @@ static bool isAppSandboxed()
        return result;
 }
 
        return result;
 }
 
+static bool shouldAddToSearchList(const DLDbIdentifier &dLDbIdentifier)
+{
+       // Creation of a private keychain should not modify the search list: rdar://13529331
+       // However, we want to ensure the login and System keychains are in
+       // the search list if that is not the case when they are created.
+       // Note that App Sandbox apps may not modify the list in either case.
+
+       bool loginOrSystemKeychain = false;
+       const char *dbname = dLDbIdentifier.dbName();
+       if (dbname) {
+               if ((!strcmp(dbname, "/Library/Keychains/System.keychain")) ||
+                       (strstr(dbname, "/login.keychain")) ) {
+                       loginOrSystemKeychain = true;
+               }
+       }
+       return (loginOrSystemKeychain && !isAppSandboxed());
+}
+
 
 StorageManager::StorageManager() :
        mSavedList(defaultPreferenceDomain()),
 
 StorageManager::StorageManager() :
        mSavedList(defaultPreferenceDomain()),
@@ -150,9 +167,7 @@ StorageManager::keychain(const DLDbIdentifier &dLDbIdentifier)
 
        if (gServerMode) {
                secdebug("servermode", "keychain reference in server mode");
 
        if (gServerMode) {
                secdebug("servermode", "keychain reference in server mode");
-        const char *dbname = dLDbIdentifier.dbName();
-        if (!dbname || (strcmp(dbname, SYSTEM_ROOT_STORE_PATH)!=0))
-            return Keychain();
+               return Keychain();
        }
 
        // The keychain is not in our cache.  Create it.
        }
 
        // The keychain is not in our cache.  Create it.
@@ -218,7 +233,7 @@ StorageManager::makeKeychain(const DLDbIdentifier &dLDbIdentifier, bool add)
 
        Keychain theKeychain = keychain(dLDbIdentifier);
        bool post = false;
 
        Keychain theKeychain = keychain(dLDbIdentifier);
        bool post = false;
-       bool updateList = (add && !isAppSandboxed());
+       bool updateList = (add && shouldAddToSearchList(dLDbIdentifier));
 
        if (updateList)
        {
 
        if (updateList)
        {
@@ -262,7 +277,7 @@ StorageManager::created(const Keychain &keychain)
 
     DLDbIdentifier dLDbIdentifier = keychain->dlDbIdentifier();
        bool defaultChanged = false;
 
     DLDbIdentifier dLDbIdentifier = keychain->dlDbIdentifier();
        bool defaultChanged = false;
-       bool updateList = (!isAppSandboxed());
+       bool updateList = shouldAddToSearchList(dLDbIdentifier);
 
        if (updateList)
        {
 
        if (updateList)
        {
@@ -351,7 +366,7 @@ StorageManager::defaultKeychain(const Keychain &keychain)
        // Only set a keychain as the default if we own it and can read/write it,
        // and our uid allows modifying the directory for that preference domain.
        if (!keychainOwnerPermissionsValidForDomain(keychain->name(), mDomain))
        // Only set a keychain as the default if we own it and can read/write it,
        // and our uid allows modifying the directory for that preference domain.
        if (!keychainOwnerPermissionsValidForDomain(keychain->name(), mDomain))
-               MacOSError::throwMe(wrPermErr);
+               MacOSError::throwMe(errSecWrPerm);
 
        DLDbIdentifier oldDefaultId;
        DLDbIdentifier newDefaultId(keychain->dlDbIdentifier());
 
        DLDbIdentifier oldDefaultId;
        DLDbIdentifier newDefaultId(keychain->dlDbIdentifier());
@@ -566,7 +581,7 @@ void StorageManager::renameUnique(Keychain keychain, CFStringRef newName)
             newNameCFStr = CFStringCreateMutable(NULL, MAXPATHLEN);
             if ( newNameCFStr )
             {
             newNameCFStr = CFStringCreateMutable(NULL, MAXPATHLEN);
             if ( newNameCFStr )
             {
-                CFStringAppendFormat(newNameCFStr, NULL, CFSTR("%s%d"), &newNameCString, index);
+                CFStringAppendFormat(newNameCFStr, NULL, CFSTR("%s%d"), newNameCString, index);
                 CFStringAppend(newNameCFStr, CFSTR(kKeychainSuffix));  // add .keychain
                 char toUseBuff2[MAXPATHLEN];
                 if ( CFStringGetCString(newNameCFStr, toUseBuff2, MAXPATHLEN, kCFStringEncodingUTF8) ) // make sure it fits in MAXPATHLEN, etc.
                 CFStringAppend(newNameCFStr, CFSTR(kKeychainSuffix));  // add .keychain
                 char toUseBuff2[MAXPATHLEN];
                 if ( CFStringGetCString(newNameCFStr, toUseBuff2, MAXPATHLEN, kCFStringEncodingUTF8) ) // make sure it fits in MAXPATHLEN, etc.
@@ -648,8 +663,23 @@ void StorageManager::removeKeychainFromSyncList (const DLDbIdentifier &id)
                        return; // something is really wrong if this is taken
                }
 
                        return; // something is really wrong if this is taken
                }
 
-               CFStringRef vExpanded = MakeExpandedPath (CFStringGetCStringPtr (v, 0));
+        char* stringBuffer = NULL;
+        const char* pathString = CFStringGetCStringPtr(v, 0);
+        if (pathString == 0)
+        {
+            CFIndex maxLen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(v), kCFStringEncodingUTF8) + 1;
+            stringBuffer = (char*) malloc(maxLen);
+            CFStringGetCString(v, stringBuffer, maxLen, kCFStringEncodingUTF8);
+            pathString = stringBuffer;
+        }
+        
+               CFStringRef vExpanded = MakeExpandedPath(pathString);
                CFComparisonResult result = CFStringCompare (vExpanded, idString.get(), 0);
                CFComparisonResult result = CFStringCompare (vExpanded, idString.get(), 0);
+        if (stringBuffer != NULL)
+        {
+            free(stringBuffer);
+        }
+        
                CFRelease (vExpanded);
 
                if (result == 0)
                CFRelease (vExpanded);
 
                if (result == 0)
@@ -932,7 +962,7 @@ StorageManager::optionalSearchList(CFTypeRef keychainOrArray, KeychainList &keyc
                else if (typeID == gTypes().KeychainImpl.typeID)
                        keychainList.push_back(KeychainImpl::required(SecKeychainRef(keychainOrArray)));
                else
                else if (typeID == gTypes().KeychainImpl.typeID)
                        keychainList.push_back(KeychainImpl::required(SecKeychainRef(keychainOrArray)));
                else
-                       MacOSError::throwMe(paramErr);
+                       MacOSError::throwMe(errSecParam);
        }
 }
 
        }
 }
 
@@ -1003,7 +1033,7 @@ void StorageManager::login(AuthorizationRef authRef, UInt32 nameLength, const ch
     AuthorizationItemSet* info = NULL;
     OSStatus result = AuthorizationCopyInfo(authRef, NULL, &info);     // get the results of the copy rights call.
     Boolean created = false;
     AuthorizationItemSet* info = NULL;
     OSStatus result = AuthorizationCopyInfo(authRef, NULL, &info);     // get the results of the copy rights call.
     Boolean created = false;
-    if ( result == noErr && info->count )
+    if ( result == errSecSuccess && info->count )
     {
         // Grab the password from the auth context (info) and create the keychain...
         //
     {
         // Grab the password from the auth context (info) and create the keychain...
         //
@@ -1015,7 +1045,7 @@ void StorageManager::login(AuthorizationRef authRef, UInt32 nameLength, const ch
                 // creates the login keychain with the specified password
                 try
                 {
                 // creates the login keychain with the specified password
                 try
                 {
-                    login(nameLength, name, currItem->valueLength, currItem->value);
+                    login(nameLength, name, (UInt32)currItem->valueLength, currItem->value);
                     created = true;
                 }
                 catch(...)
                     created = true;
                 }
                 catch(...)
@@ -1038,7 +1068,7 @@ void StorageManager::login(ConstStringPtr name, ConstStringPtr password)
        StLock<Mutex>_(mMutex);
 
     if ( name == NULL || password == NULL )
        StLock<Mutex>_(mMutex);
 
     if ( name == NULL || password == NULL )
-        MacOSError::throwMe(paramErr);
+        MacOSError::throwMe(errSecParam);
 
        login(name[0], name + 1, password[0], password + 1);
 }
 
        login(name[0], name + 1, password[0], password + 1);
 }
@@ -1049,7 +1079,7 @@ void StorageManager::login(UInt32 nameLength, const void *name,
        if (passwordLength != 0 && password == NULL)
        {
                secdebug("KCLogin", "StorageManager::login: invalid argument (NULL password)");
        if (passwordLength != 0 && password == NULL)
        {
                secdebug("KCLogin", "StorageManager::login: invalid argument (NULL password)");
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
        }
 
        DLDbIdentifier loginDLDbIdentifier;
        }
 
        DLDbIdentifier loginDLDbIdentifier;
@@ -1072,7 +1102,7 @@ void StorageManager::login(UInt32 nameLength, const void *name,
     struct passwd *pw = getpwuid(uid);
     if (pw == NULL) {
         secdebug("KCLogin", "StorageManager::login: invalid argument (NULL uid)");
     struct passwd *pw = getpwuid(uid);
     if (pw == NULL) {
         secdebug("KCLogin", "StorageManager::login: invalid argument (NULL uid)");
-        MacOSError::throwMe(paramErr);
+        MacOSError::throwMe(errSecParam);
     }
     char *userName = pw->pw_name;
 
     }
     char *userName = pw->pw_name;
 
@@ -1276,7 +1306,7 @@ void StorageManager::login(UInt32 nameLength, const void *name,
     //***************************************************************
     // all our preflight fixups are finally done, so we can now attempt to unlock the login keychain
 
     //***************************************************************
     // all our preflight fixups are finally done, so we can now attempt to unlock the login keychain
 
-    OSStatus loginResult = noErr;
+    OSStatus loginResult = errSecSuccess;
        if (!loginUnlocked) {
         try
         {
        if (!loginUnlocked) {
         try
         {
@@ -1307,7 +1337,72 @@ void StorageManager::login(UInt32 nameLength, const void *name,
         }
     }
 
         }
     }
 
-    if (loginResult != noErr) {
+    if (loginResult != errSecSuccess) {
+        MacOSError::throwMe(loginResult);
+    }
+}
+
+void StorageManager::stashLogin()
+{
+    OSStatus loginResult = errSecSuccess;
+    
+    DLDbIdentifier loginDLDbIdentifier;
+    {
+        mSavedList.revert(true);
+        loginDLDbIdentifier = mSavedList.loginDLDbIdentifier();
+    }
+    
+       secdebug("KCLogin", "StorageManager::stash: loginDLDbIdentifier is %s", (loginDLDbIdentifier) ? loginDLDbIdentifier.dbName() : "<NULL>");
+       if (!loginDLDbIdentifier)
+               MacOSError::throwMe(errSecNoSuchKeychain);
+    
+    try
+    {
+        CssmData empty;
+        Keychain theKeychain(keychain(loginDLDbIdentifier));
+        secdebug("KCLogin", "Attempting to use stash for login keychain \"%s\"",
+                 (theKeychain) ? theKeychain->name() : "<NULL>");
+        theKeychain->stashCheck();
+    }
+    catch(const CssmError &e)
+    {
+        loginResult = e.osStatus(); // save this result
+    }
+    
+    
+    if (loginResult != errSecSuccess) {
+        MacOSError::throwMe(loginResult);
+    }
+}
+
+void StorageManager::stashKeychain()
+{
+    OSStatus loginResult = errSecSuccess;
+    
+    DLDbIdentifier loginDLDbIdentifier;
+    {
+        mSavedList.revert(true);
+        loginDLDbIdentifier = mSavedList.loginDLDbIdentifier();
+    }
+    
+       secdebug("KCLogin", "StorageManager::stash: loginDLDbIdentifier is %s", (loginDLDbIdentifier) ? loginDLDbIdentifier.dbName() : "<NULL>");
+       if (!loginDLDbIdentifier)
+               MacOSError::throwMe(errSecNoSuchKeychain);
+    
+    try
+    {
+        Keychain theKeychain(keychain(loginDLDbIdentifier));
+        secdebug("KCLogin", "Attempting to stash login keychain \"%s\"",
+                 (theKeychain) ? theKeychain->name() : "<NULL>");
+        theKeychain->stash();
+    }
+    catch(const CssmError &e)
+    {
+        loginResult = e.osStatus(); // save this result
+    }
+
+
+    if (loginResult != errSecSuccess) {
         MacOSError::throwMe(loginResult);
     }
 }
         MacOSError::throwMe(loginResult);
     }
 }
@@ -1420,7 +1515,7 @@ Keychain StorageManager::make(const char *pathName, bool add)
                                        if (!uid) uid = getuid();
                                        struct passwd *pw = getpwuid(uid);
                                        if (!pw)
                                        if (!uid) uid = getuid();
                                        struct passwd *pw = getpwuid(uid);
                                        if (!pw)
-                                               MacOSError::throwMe(paramErr);
+                                               MacOSError::throwMe(errSecParam);
                                        homeDir = pw->pw_dir;
                                }
                                fullPathName = homeDir;
                                        homeDir = pw->pw_dir;
                                }
                                fullPathName = homeDir;
@@ -1455,7 +1550,7 @@ Keychain StorageManager::makeLoginAuthUI(const Item *item)
     // The user can cancel out of the operation, or create a new login keychain.
     // If auto-login is turned off, the user will be asked for their login password.
     //
     // The user can cancel out of the operation, or create a new login keychain.
     // If auto-login is turned off, the user will be asked for their login password.
     //
-    OSStatus result = noErr;
+    OSStatus result = errSecSuccess;
     Keychain keychain; // We return this keychain.
     //
     // Set up the Auth ref to bring up UI.
     Keychain keychain; // We return this keychain.
     //
     // Set up the Auth ref to bring up UI.
@@ -1479,7 +1574,7 @@ Keychain StorageManager::makeLoginAuthUI(const Item *item)
                //
                // 1st Hint (optional): The keychain item's account attribute string.
                //                                              When item is specified, we assume an 'add' operation is being attempted.
                //
                // 1st Hint (optional): The keychain item's account attribute string.
                //                                              When item is specified, we assume an 'add' operation is being attempted.
-               char buff[255];
+               char buff[256];
                UInt32 actLen = 0;
                SecKeychainAttribute attr = { kSecAccountItemAttr, 255, &buff };
                if ( item )
                UInt32 actLen = 0;
                SecKeychainAttribute attr = { kSecAccountItemAttr, 255, &buff };
                if ( item )
@@ -1496,8 +1591,8 @@ Keychain StorageManager::makeLoginAuthUI(const Item *item)
                currItem->name = AGENT_HINT_ATTR_NAME;  // name str that identifies this hint as attr name
                if ( actLen )   // Fill in the hint if we have an account attr
                {
                currItem->name = AGENT_HINT_ATTR_NAME;  // name str that identifies this hint as attr name
                if ( actLen )   // Fill in the hint if we have an account attr
                {
-                       if ( actLen > 255 )
-                               buff[255] = 0;
+                       if ( actLen >= sizeof(buff) )
+                               buff[sizeof(buff)-1] = 0;
                        else
                                buff[actLen] = 0;
                        currItem->valueLength = strlen(buff)+1;
                        else
                                buff[actLen] = 0;
                        currItem->valueLength = strlen(buff)+1;
@@ -1613,7 +1708,7 @@ Keychain StorageManager::makeLoginAuthUI(const Item *item)
                catch (...) // can throw if no existing login.keychain is found
                {
                }
                catch (...) // can throw if no existing login.keychain is found
                {
                }
-               login(authRef, userName.length(), userName.c_str()); // Create login.keychain
+               login(authRef, (UInt32)userName.length(), userName.c_str()); // Create login.keychain
                keychain = loginKeychain(); // Get newly-created login keychain
                defaultKeychain(keychain);      // Set it to be the default
 
                keychain = loginKeychain(); // Get newly-created login keychain
                defaultKeychain(keychain);      // Set it to be the default
 
index e8b1877592378291d2f6b185adf4ce8f25a99e69..1c3bee09ee21c7ab0b1002fc08350ea080abac82 100644 (file)
@@ -123,6 +123,8 @@ public:
     void login(AuthorizationRef authRef, UInt32 nameLength, const char* name);
        void login(ConstStringPtr name, ConstStringPtr password);
        void login(UInt32 nameLength, const void *name, UInt32 passwordLength, const void *password);
     void login(AuthorizationRef authRef, UInt32 nameLength, const char* name);
        void login(ConstStringPtr name, ConstStringPtr password);
        void login(UInt32 nameLength, const void *name, UInt32 passwordLength, const void *password);
+    void stashLogin();
+    void stashKeychain();
        void logout();
        void changeLoginPassword(ConstStringPtr oldPassword, ConstStringPtr newPassword);
        void changeLoginPassword(UInt32 oldPasswordLength, const void *oldPassword,  UInt32 newPasswordLength, const void *newPassword);
        void logout();
        void changeLoginPassword(ConstStringPtr oldPassword, ConstStringPtr newPassword);
        void changeLoginPassword(UInt32 oldPasswordLength, const void *oldPassword,  UInt32 newPasswordLength, const void *newPassword);
index 92236a0b54c89b1bc43aa9b90fe5699f41c688f3..e22acfbac4b770b6384f3862ffc2c09b798ffee9 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2002-2010 Apple Inc. All Rights Reserved.
+ * Copyright (c) 2002-2010,2012 Apple Inc. All Rights Reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -34,6 +34,7 @@
 #include "SecBridge.h"
 #include "TrustAdditions.h"
 #include "TrustKeychains.h"
 #include "SecBridge.h"
 #include "TrustAdditions.h"
 #include "TrustKeychains.h"
+#include <security_cdsa_client/dlclient.h>
 
 
 using namespace Security;
 
 
 using namespace Security;
@@ -74,12 +75,16 @@ class TrustKeychains
 public:
        TrustKeychains();
        ~TrustKeychains()       {}
 public:
        TrustKeychains();
        ~TrustKeychains()       {}
-       CSSM_DL_DB_HANDLE       rootStoreHandle()       { return mRootStore ? mRootStore->database()->handle() : nullCSSMDLDBHandle; }
+       CSSM_DL_DB_HANDLE       rootStoreHandle()       { return mRootStoreHandle; }
        CSSM_DL_DB_HANDLE       systemKcHandle()        { return mSystem ? mSystem->database()->handle() : nullCSSMDLDBHandle; }
        CSSM_DL_DB_HANDLE       systemKcHandle()        { return mSystem ? mSystem->database()->handle() : nullCSSMDLDBHandle; }
-       Keychain                        &rootStore()            { return mRootStore; }
        Keychain                        &systemKc()                     { return mSystem; }
        Keychain                        &systemKc()                     { return mSystem; }
+       Keychain                        &rootStore()            { return *mRootStore; }
+
 private:
 private:
-       Keychain                        mRootStore;
+       DL*                                     mRootStoreDL;
+       Db*                                     mRootStoreDb;
+       Keychain*                       mRootStore;
+       CSSM_DL_DB_HANDLE       mRootStoreHandle;
        Keychain                        mSystem;
 };
 
        Keychain                        mSystem;
 };
 
@@ -91,10 +96,25 @@ private:
 static ModuleNexus<TrustKeychains> trustKeychains;
 static ModuleNexus<RecursiveMutex> trustKeychainsMutex;
 
 static ModuleNexus<TrustKeychains> trustKeychains;
 static ModuleNexus<RecursiveMutex> trustKeychainsMutex;
 
+extern "C" bool GetServerMode();
+
 TrustKeychains::TrustKeychains() :
 TrustKeychains::TrustKeychains() :
-       mRootStore(globals().storageManager.make(SYSTEM_ROOT_STORE_PATH, false)),
+       mRootStoreHandle(nullCSSMDLDBHandle),
        mSystem(globals().storageManager.make(ADMIN_CERT_STORE_PATH, false))
 {
        mSystem(globals().storageManager.make(ADMIN_CERT_STORE_PATH, false))
 {
+       if (GetServerMode()) // in server mode?  Don't make a keychain for the root store
+       {
+               mRootStoreDL = new DL(gGuidAppleFileDL),
+               mRootStoreDb = new Db(*mRootStoreDL, SYSTEM_ROOT_STORE_PATH),
+               (*mRootStoreDb)->activate();
+               mRootStoreHandle = (*mRootStoreDb)->handle();
+       }
+       else
+       {
+               mRootStore = new Keychain(globals().storageManager.make(SYSTEM_ROOT_STORE_PATH, false));
+               (*mRootStore)->database()->activate();
+               mRootStoreHandle = (*mRootStore)->database()->handle();
+       }
 }
 
 RecursiveMutex& SecTrustKeychainsGetMutex()
 }
 
 RecursiveMutex& SecTrustKeychainsGetMutex()
@@ -110,10 +130,12 @@ RecursiveMutex& SecTrustKeychainsGetMutex()
 Trust::Trust(CFTypeRef certificates, CFTypeRef policies)
     : mTP(gGuidAppleX509TP), mAction(CSSM_TP_ACTION_DEFAULT),
       mCerts(cfArrayize(certificates)), mPolicies(cfArrayize(policies)),
 Trust::Trust(CFTypeRef certificates, CFTypeRef policies)
     : mTP(gGuidAppleX509TP), mAction(CSSM_TP_ACTION_DEFAULT),
       mCerts(cfArrayize(certificates)), mPolicies(cfArrayize(policies)),
-      mResult(kSecTrustResultInvalid), mUsingTrustSettings(false),
-      mAnchorPolicy(useAnchorsDefault), mSearchLibsSet(false),
-      mSearchLibs(NULL), mMutex(Mutex::recursive)
+      mSearchLibs(NULL), mSearchLibsSet(false), mResult(kSecTrustResultInvalid),
+      mUsingTrustSettings(false), mAnchorPolicy(useAnchorsDefault), mMutex(Mutex::recursive)
 {
 {
+       if (!mPolicies) {
+               mPolicies.take(CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks));
+       }
 }
 
 
 }
 
 
@@ -126,6 +148,8 @@ Trust::~Trust()
        if (mSearchLibs) {
                delete mSearchLibs;
        }
        if (mSearchLibs) {
                delete mSearchLibs;
        }
+    
+    mPolicies = NULL;
 }
 
 
 }
 
 
@@ -167,12 +191,14 @@ CSSM_TP_VERIFY_CONTEXT_RESULT_PTR Trust::cssmResult()
 
 
 // SecCertificateRef -> CssmData
 
 
 // SecCertificateRef -> CssmData
+static
 CssmData cfCertificateData(SecCertificateRef certificate)
 {
     return Certificate::required(certificate)->data();
 }
 
 // SecPolicyRef -> CssmField (CFDataRef/NULL or oid/value of a SecPolicy)
 CssmData cfCertificateData(SecCertificateRef certificate)
 {
     return Certificate::required(certificate)->data();
 }
 
 // SecPolicyRef -> CssmField (CFDataRef/NULL or oid/value of a SecPolicy)
+static
 CssmField cfField(SecPolicyRef item)
 {
        SecPointer<Policy> policy = Policy::required(SecPolicyRef(item));
 CssmField cfField(SecPolicyRef item)
 {
        SecPointer<Policy> policy = Policy::required(SecPolicyRef(item));
@@ -180,11 +206,14 @@ CssmField cfField(SecPolicyRef item)
 }
 
 // SecKeychain -> CssmDlDbHandle
 }
 
 // SecKeychain -> CssmDlDbHandle
+#if 0
+static
 CSSM_DL_DB_HANDLE cfKeychain(SecKeychainRef ref)
 {
        Keychain keychain = KeychainImpl::required(ref);
        return keychain->database()->handle();
 }
 CSSM_DL_DB_HANDLE cfKeychain(SecKeychainRef ref)
 {
        Keychain keychain = KeychainImpl::required(ref);
        return keychain->database()->handle();
 }
+#endif
 
 #if !defined(NDEBUG)
 void showCertSKID(const void *value, void *context);
 
 #if !defined(NDEBUG)
 void showCertSKID(const void *value, void *context);
@@ -280,50 +309,72 @@ void Trust::evaluate(bool disableEV)
                actionDataP->ActionFlags |= CSSM_TP_ACTION_TRUST_SETTINGS;
        }
 
                actionDataP->ActionFlags |= CSSM_TP_ACTION_TRUST_SETTINGS;
        }
 
-       if (policySpecified(mPolicies, CSSMOID_APPLE_TP_SSL)) {
-               // enable network cert fetch for SSL only: <rdar://7422356>
-               actionDataP->ActionFlags |= CSSM_TP_ACTION_FETCH_CERT_FROM_NET;
+       if (mNetworkPolicy == useNetworkDefault) {
+               if (policySpecified(mPolicies, CSSMOID_APPLE_TP_SSL)) {
+                       // enable network cert fetch for SSL only: <rdar://7422356>
+                       actionDataP->ActionFlags |= CSSM_TP_ACTION_FETCH_CERT_FROM_NET;
+               }
        }
        }
+       else if (mNetworkPolicy == useNetworkEnabled)
+               actionDataP->ActionFlags |= CSSM_TP_ACTION_FETCH_CERT_FROM_NET;
+       else if (mNetworkPolicy == useNetworkDisabled)
+               actionDataP->ActionFlags &= ~(CSSM_TP_ACTION_FETCH_CERT_FROM_NET);
 
     /*
         * Policies (one at least, please).
         * For revocation policies, see if any have been explicitly specified...
         */
        CFMutableArrayRef allPolicies = NULL;
 
     /*
         * Policies (one at least, please).
         * For revocation policies, see if any have been explicitly specified...
         */
        CFMutableArrayRef allPolicies = NULL;
-       uint32 numSpecAdded = 0;
-       uint32 numPrefAdded = 0;
+       uint32 numRevocationAdded = 0;
        bool requirePerCert = (actionDataP->ActionFlags & CSSM_TP_ACTION_REQUIRE_REV_PER_CERT);
        bool requirePerCert = (actionDataP->ActionFlags & CSSM_TP_ACTION_REQUIRE_REV_PER_CERT);
-       if (isEVCandidate || requirePerCert) {
-               // force revocation checking for this evaluation
-               secdebug("evTrust", "Trust::evaluate() forcing OCSP/CRL revocation checking");
-               allPolicies = forceRevocationPolicies(numPrefAdded, context.allocator, requirePerCert);
+
+       // If a new unified revocation policy was explicitly specified,
+       // convert into old-style individual OCSP and CRL policies.
+       // Note that the caller could configure revocation policy options
+       // to explicitly disable both methods, so 0 policies might be added,
+       // in which case we must no longer consider the cert an EV candidate.
+
+       allPolicies = convertRevocationPolicy(numRevocationAdded, context.allocator);
+       if (allPolicies) {
+               // caller has explicitly set the revocation policy they want to use
+               secdebug("evTrust", "Trust::evaluate() using explicit revocation policy (%d)",
+                       numRevocationAdded);
+               if (numRevocationAdded == 0)
+                       isEVCandidate = false;
        }
        else if (mAnchors && (CFArrayGetCount(mAnchors)==0) && (searchLibs().size()==0)) {
        }
        else if (mAnchors && (CFArrayGetCount(mAnchors)==0) && (searchLibs().size()==0)) {
-               // caller explicitly provided empty anchors and no keychain list;
+               // caller explicitly provided empty anchors and no keychain list,
+               // and did not explicitly specify the revocation policy;
                // override global revocation check setting for this evaluation
                // override global revocation check setting for this evaluation
+               secdebug("evTrust", "Trust::evaluate() has empty anchors and no keychains");
                allPolicies = NULL; // use only mPolicies
                allPolicies = NULL; // use only mPolicies
+               isEVCandidate = false;
+       }
+       else if (isEVCandidate || requirePerCert) {
+               // force revocation checking for this evaluation
+               secdebug("evTrust", "Trust::evaluate() forcing OCSP/CRL revocation check");
+               allPolicies = forceRevocationPolicies(numRevocationAdded,
+                       context.allocator, requirePerCert);
        }
        else if(!(revocationPolicySpecified(mPolicies))) {
        }
        else if(!(revocationPolicySpecified(mPolicies))) {
-               /*
-                * None specified in mPolicies; see if any specified via SPI.
-                */
-               allPolicies = addSpecifiedRevocationPolicies(numSpecAdded, context.allocator);
-               if(allPolicies == NULL) {
-                       /*
-                        * None there; try preferences.
-                        */
-                       allPolicies = Trust::addPreferenceRevocationPolicies(numPrefAdded,
-                               context.allocator);
-               }
-
+               // none specified in mPolicies; try preferences
+               allPolicies = addPreferenceRevocationPolicies(numRevocationAdded,
+                       context.allocator);
        }
        }
-       if(allPolicies == NULL) {
-               allPolicies = CFMutableArrayRef(CFArrayRef(mPolicies));
+       if (allPolicies == NULL) {
+               // use mPolicies; no revocation checking will be performed
+               secdebug("evTrust", "Trust::evaluate() will not perform revocation check");
+               CFIndex numPolicies = CFArrayGetCount(mPolicies);
+               CFAllocatorRef allocator = CFGetAllocator(mPolicies);
+               allPolicies = CFArrayCreateMutableCopy(allocator, numPolicies, mPolicies);
        }
        orderRevocationPolicies(allPolicies);
     CFToVector<CssmField, SecPolicyRef, cfField> policies(allPolicies);
        }
        orderRevocationPolicies(allPolicies);
     CFToVector<CssmField, SecPolicyRef, cfField> policies(allPolicies);
+#if 0
+       // error exit here if empty policies are not supported
     if (policies.empty())
         MacOSError::throwMe(CSSMERR_TP_INVALID_POLICY_IDENTIFIERS);
     if (policies.empty())
         MacOSError::throwMe(CSSMERR_TP_INVALID_POLICY_IDENTIFIERS);
+#endif
     context.setPolicies(policies, policies);
 
        // anchor certificates (if caller provides them, or if cert requires EV)
     context.setPolicies(policies, policies);
 
        // anchor certificates (if caller provides them, or if cert requires EV)
@@ -399,7 +450,7 @@ void Trust::evaluate(bool disableEV)
                                /* Oh well, at least we got the root store DB */
                        }
                }
                                /* Oh well, at least we got the root store DB */
                        }
                }
-               context.setDlDbList(dlDbList.size(), &dlDbList[0]);
+               context.setDlDbList((uint32)dlDbList.size(), &dlDbList[0]);
        }
 
     // verification time
        }
 
     // verification time
@@ -420,7 +471,7 @@ void Trust::evaluate(bool disableEV)
     // Go TP!
     try {
         mTP->certGroupVerify(subjectCertGroup, context, &mTpResult);
     // Go TP!
     try {
         mTP->certGroupVerify(subjectCertGroup, context, &mTpResult);
-        mTpReturn = noErr;
+        mTpReturn = errSecSuccess;
     } catch (CommonError &err) {
         mTpReturn = err.osStatus();
         secdebug("trusteval", "certGroupVerify exception: %d", (int)mTpReturn);
     } catch (CommonError &err) {
         mTpReturn = err.osStatus();
         secdebug("trusteval", "certGroupVerify exception: %d", (int)mTpReturn);
@@ -452,12 +503,12 @@ void Trust::evaluate(bool disableEV)
                CFRelease(fullChain);
        }
 
                CFRelease(fullChain);
        }
 
-       /* Clean up Policies we created implicitly */
-       if(numSpecAdded) {
-               freeSpecifiedRevocationPolicies(allPolicies, numSpecAdded, context.allocator);
-       }
-       if(numPrefAdded) {
-               Trust::freePreferenceRevocationPolicies(allPolicies, numPrefAdded, context.allocator);
+       if (allPolicies) {
+               /* clean up revocation policies we created implicitly */
+               if(numRevocationAdded) {
+                       freeAddedRevocationPolicyData(allPolicies, numRevocationAdded, context.allocator);
+               }
+               CFRelease(allPolicies);
        }
 
        if (holdSearchList) {
        }
 
        if (holdSearchList) {
@@ -481,7 +532,6 @@ static const CSSM_RETURN recoverableErrors[] =
        CSSMERR_TP_NOT_TRUSTED,
        CSSMERR_TP_VERIFICATION_FAILURE,
        CSSMERR_TP_VERIFY_ACTION_FAILED,
        CSSMERR_TP_NOT_TRUSTED,
        CSSMERR_TP_VERIFICATION_FAILURE,
        CSSMERR_TP_VERIFY_ACTION_FAILED,
-       CSSMERR_TP_INVALID_CERTIFICATE,
        CSSMERR_TP_INVALID_REQUEST_INPUTS,
        CSSMERR_TP_CERT_EXPIRED,
        CSSMERR_TP_CERT_NOT_VALID_YET,
        CSSMERR_TP_INVALID_REQUEST_INPUTS,
        CSSMERR_TP_CERT_EXPIRED,
        CSSMERR_TP_CERT_NOT_VALID_YET,
@@ -508,6 +558,7 @@ static const CSSM_RETURN recoverableErrors[] =
        CSSMERR_APPLETP_INCOMPLETE_REVOCATION_CHECK,
        CSSMERR_APPLETP_NETWORK_FAILURE,
        CSSMERR_APPLETP_OCSP_RESP_TRY_LATER,
        CSSMERR_APPLETP_INCOMPLETE_REVOCATION_CHECK,
        CSSMERR_APPLETP_NETWORK_FAILURE,
        CSSMERR_APPLETP_OCSP_RESP_TRY_LATER,
+       CSSMERR_APPLETP_IDENTIFIER_MISSING,
 };
 #define NUM_RECOVERABLE_ERRORS (sizeof(recoverableErrors) / sizeof(CSSM_RETURN))
 
 };
 #define NUM_RECOVERABLE_ERRORS (sizeof(recoverableErrors) / sizeof(CSSM_RETURN))
 
@@ -528,7 +579,7 @@ SecTrustResultType Trust::diagnoseOutcome()
        }
 
     switch (mTpReturn) {
        }
 
     switch (mTpReturn) {
-    case noErr:                                                                        // peachy
+    case errSecSuccess:                                                                        // peachy
                if (mUsingTrustSettings)
                {
                        if (chainLength)
                if (mUsingTrustSettings)
                {
                        if (chainLength)
@@ -613,17 +664,17 @@ void Trust::evaluateUserTrust(const CertGroup &chain,
 
     // now walk the chain, leaf-to-root, checking for user settings
        TrustStore &store = gStore();
 
     // now walk the chain, leaf-to-root, checking for user settings
        TrustStore &store = gStore();
-       SecPointer<Policy> policy =
-               Policy::required(SecPolicyRef(CFArrayGetValueAtIndex(mPolicies, 0)));
+       SecPointer<Policy> policy = (CFArrayGetCount(mPolicies)) ?
+               Policy::required(SecPolicyRef(CFArrayGetValueAtIndex(mPolicies, 0))) : NULL;
        for (mResultIndex = 0;
        for (mResultIndex = 0;
-                       mResult == kSecTrustResultUnspecified && mResultIndex < mCertChain.size();
+                       mResult == kSecTrustResultUnspecified && mResultIndex < mCertChain.size() && policy;
                        mResultIndex++) {
                if (!mCertChain[mResultIndex]) {
                        assert(false);
                        continue;
                }
                mResult = store.find(mCertChain[mResultIndex], policy, searchLibs());
                        mResultIndex++) {
                if (!mCertChain[mResultIndex]) {
                        assert(false);
                        continue;
                }
                mResult = store.find(mCertChain[mResultIndex], policy, searchLibs());
-               secdebug("trusteval", "trustResult=%lu from cert %lu", mResult, (unsigned long)mResultIndex);
+               secdebug("trusteval", "trustResult=%d from cert %d", (int)mResult, (int)mResultIndex);
        }
 }
 
        }
 }
 
@@ -741,7 +792,7 @@ CFArrayRef Trust::properties()
                                CFDictionarySetValue(dict, (const void *)kSecPropertyTypeTitle, (const void *)title);
                                CFRelease(title);
                        }
                                CFDictionarySetValue(dict, (const void *)kSecPropertyTypeTitle, (const void *)title);
                                CFRelease(title);
                        }
-                       if (idx == 0 && mTpReturn != noErr) {
+                       if (idx == 0 && mTpReturn != errSecSuccess) {
                                CFStringRef error = SecCopyErrorMessageString(mTpReturn, NULL);
                                if (error) {
                                        CFDictionarySetValue(dict, (const void *)kSecPropertyTypeError, (const void *)error);
                                CFStringRef error = SecCopyErrorMessageString(mTpReturn, NULL);
                                if (error) {
                                        CFDictionarySetValue(dict, (const void *)kSecPropertyTypeError, (const void *)error);
@@ -756,12 +807,54 @@ CFArrayRef Trust::properties()
        return properties;
 }
 
        return properties;
 }
 
+//
+// Return dictionary of evaluation results
+//
+CFDictionaryRef Trust::results()
+{
+       // Builds and returns a dictionary which the caller must release.
+       StLock<Mutex>_(mMutex);
+       CFMutableDictionaryRef results = CFDictionaryCreateMutable(NULL, 0,
+                       &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+
+       // kSecTrustResultValue
+       CFNumberRef numValue = CFNumberCreate(NULL, kCFNumberSInt32Type, &mResult);
+       if (numValue) {
+               CFDictionarySetValue(results, (const void *)kSecTrustResultValue, (const void *)numValue);
+               CFRelease(numValue);
+       }
+       if (mResult == kSecTrustResultInvalid || !mExtendedResult)
+               return results; // we have nothing more to add
+
+       // kSecTrustEvaluationDate
+       CFTypeRef evaluationDate;
+       if (CFDictionaryGetValueIfPresent(mExtendedResult, kSecTrustEvaluationDate, &evaluationDate))
+               CFDictionarySetValue(results, (const void *)kSecTrustEvaluationDate, (const void *)evaluationDate);
+
+       // kSecTrustExtendedValidation, kSecTrustOrganizationName
+       CFTypeRef organizationName;
+       if (CFDictionaryGetValueIfPresent(mExtendedResult, kSecEVOrganizationName, &organizationName)) {
+               CFDictionarySetValue(results, (const void *)kSecTrustOrganizationName, (const void *)organizationName);
+               CFDictionarySetValue(results, (const void *)kSecTrustExtendedValidation, (const void *)kCFBooleanTrue);
+       }
+
+       // kSecTrustRevocationChecked, kSecTrustRevocationValidUntilDate
+       CFTypeRef expirationDate;
+       if (CFDictionaryGetValueIfPresent(mExtendedResult, kSecTrustExpirationDate, &expirationDate)) {
+               CFDictionarySetValue(results, (const void *)kSecTrustRevocationValidUntilDate, (const void *)expirationDate);
+               CFDictionarySetValue(results, (const void *)kSecTrustRevocationChecked, (const void *)kCFBooleanTrue);
+       }
+
+       return results;
+}
+
 
 
 //* ===========================================================================
 //* We need a way to compare two CSSM_DL_DB_HANDLEs WITHOUT using a operator
 //* overload
 //* ===========================================================================
 
 
 //* ===========================================================================
 //* We need a way to compare two CSSM_DL_DB_HANDLEs WITHOUT using a operator
 //* overload
 //* ===========================================================================
+static
 bool Compare_CSSM_DL_DB_HANDLE(const CSSM_DL_DB_HANDLE &h1, const CSSM_DL_DB_HANDLE &h2)
 {
     return (h1.DLHandle == h2.DLHandle && h1.DBHandle == h2.DBHandle);
 bool Compare_CSSM_DL_DB_HANDLE(const CSSM_DL_DB_HANDLE &h1, const CSSM_DL_DB_HANDLE &h2)
 {
     return (h1.DLHandle == h2.DLHandle && h1.DBHandle == h2.DBHandle);
index 755c6ae7dc3bfd2917ac8935534d998efbde17af..344f81f4a355edecc9eb0d3c586fe65b74a35be4 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2002-2004 Apple Computer, Inc. All Rights Reserved.
+ * Copyright (c) 2002-2010,2012 Apple Inc. All Rights Reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -63,6 +63,12 @@ public:
                useAnchorsOnly                  // SetTrustAnchorCertificatesOnly value = true
        };
 
                useAnchorsOnly                  // SetTrustAnchorCertificatesOnly value = true
        };
 
+       enum NetworkPolicy {
+               useNetworkDefault,              // default policy: network fetch enabled only for SSL
+               useNetworkDisabled,             // explicitly disable network use for any policy
+               useNetworkEnabled               // explicitly enable network use for any policy
+       };
+
        // set (or reset) more input parameters
        void policies(CFTypeRef policies)                       { mPolicies.take(cfArrayize(policies)); }
        void action(CSSM_TP_ACTION action)                      { mAction = action; }
        // set (or reset) more input parameters
        void policies(CFTypeRef policies)                       { mPolicies.take(cfArrayize(policies)); }
        void action(CSSM_TP_ACTION action)                      { mAction = action; }
@@ -70,92 +76,102 @@ public:
        void time(CFDateRef verifyTime)                         { mVerifyTime = verifyTime; }
        void anchors(CFArrayRef anchorList)                     { mAnchors.take(cfArrayize(anchorList)); }
        void anchorPolicy(AnchorPolicy policy)          { mAnchorPolicy = policy; }
        void time(CFDateRef verifyTime)                         { mVerifyTime = verifyTime; }
        void anchors(CFArrayRef anchorList)                     { mAnchors.take(cfArrayize(anchorList)); }
        void anchorPolicy(AnchorPolicy policy)          { mAnchorPolicy = policy; }
+       void networkPolicy(NetworkPolicy policy)        { mNetworkPolicy = policy; }
+       void exceptions(CFArrayRef exceptions)          { mExceptions.take(cfArrayize(exceptions)); }
+       void responses(CFTypeRef responseData)          { mResponses.take(cfArrayize(responseData)); }
 
        StorageManager::KeychainList &searchLibs(bool init=true);
        void searchLibs(StorageManager::KeychainList &libs);
 
        // perform evaluation
 
        StorageManager::KeychainList &searchLibs(bool init=true);
        void searchLibs(StorageManager::KeychainList &libs);
 
        // perform evaluation
-    void evaluate(bool disableEV=false);
+       void evaluate(bool disableEV=false);
+
+       // update evaluation results
+       void setResult(SecTrustResultType result)       { mResult = result; }
 
        // get at evaluation results
 
        // get at evaluation results
-    void buildEvidence(CFArrayRef &certChain, TPEvidenceInfo * &statusChain);
-    CSSM_TP_VERIFY_CONTEXT_RESULT_PTR cssmResult();
+       void buildEvidence(CFArrayRef &certChain, TPEvidenceInfo * &statusChain);
+       CSSM_TP_VERIFY_CONTEXT_RESULT_PTR cssmResult();
        void extendedResult(CFDictionaryRef &extendedResult);
        CFArrayRef properties();
        void extendedResult(CFDictionaryRef &extendedResult);
        CFArrayRef properties();
+       CFDictionaryRef results();
 
 
-    SecTrustResultType result() const                  { return mResult; }
+       SecTrustResultType result() const                       { return mResult; }
        OSStatus cssmResultCode() const                         { return mTpReturn; }
        OSStatus cssmResultCode() const                         { return mTpReturn; }
-    TP getTPHandle() const                                             { return mTP; }
+       TP getTPHandle() const                                          { return mTP; }
        CFArrayRef evidence() const                                     { return mEvidenceReturned; }
        CFArrayRef evidence() const                                     { return mEvidenceReturned; }
-    CFArrayRef policies() const                                        { return mPolicies; }
-    CFArrayRef anchors() const                                 { return mAnchors; }
+       CFArrayRef policies() const                                     { return mPolicies; }
+       CFArrayRef anchors() const                                      { return mAnchors; }
        CFDateRef time() const                                          { return mVerifyTime; }
        CFDateRef time() const                                          { return mVerifyTime; }
+       AnchorPolicy anchorPolicy() const                       { return mAnchorPolicy; }
+       NetworkPolicy networkPolicy() const                     { return mNetworkPolicy; }
+       CFArrayRef exceptions() const                           { return mExceptions; }
 
        // an independent release function for TP evidence results
        // (yes, we could hand this out to the C layer if desired)
        static void releaseTPEvidence(TPVerifyResult &result, Allocator &allocator);
 
 private:
 
        // an independent release function for TP evidence results
        // (yes, we could hand this out to the C layer if desired)
        static void releaseTPEvidence(TPVerifyResult &result, Allocator &allocator);
 
 private:
-    SecTrustResultType diagnoseOutcome();
-    void evaluateUserTrust(const CertGroup &certs,
-        const CSSM_TP_APPLE_EVIDENCE_INFO *info,
+       SecTrustResultType diagnoseOutcome();
+       void evaluateUserTrust(const CertGroup &certs,
+                       const CSSM_TP_APPLE_EVIDENCE_INFO *info,
                CFCopyRef<CFArrayRef> anchors);
        void clearResults();
 
        Keychain keychainByDLDb(const CSSM_DL_DB_HANDLE &handle);
 
        /* revocation policy support */
                CFCopyRef<CFArrayRef> anchors);
        void clearResults();
 
        Keychain keychainByDLDb(const CSSM_DL_DB_HANDLE &handle);
 
        /* revocation policy support */
-       CFMutableArrayRef       addSpecifiedRevocationPolicies(uint32 &numAdded,
-                                                       Allocator &alloc);
-       void                            freeSpecifiedRevocationPolicies(CFArrayRef policies,
-                                                       uint32 numAdded,
-                                                       Allocator &alloc);
        CFMutableArrayRef       addPreferenceRevocationPolicies(uint32 &numAdded,
                                                        Allocator &alloc);
        CFMutableArrayRef       addPreferenceRevocationPolicies(uint32 &numAdded,
                                                        Allocator &alloc);
-       void                            freePreferenceRevocationPolicies(CFArrayRef policies,
+       void                            freeAddedRevocationPolicyData(CFArrayRef policies,
                                                        uint32 numAdded,
                                                        Allocator &alloc);
                                                        uint32 numAdded,
                                                        Allocator &alloc);
-    CFDictionaryRef     defaultRevocationSettings();
+       CFDictionaryRef     defaultRevocationSettings();
 
 
+public:
        bool                            policySpecified(CFArrayRef policies, const CSSM_OID &inOid);
        bool                            revocationPolicySpecified(CFArrayRef policies);
        void                            orderRevocationPolicies(CFMutableArrayRef policies);
        bool                            policySpecified(CFArrayRef policies, const CSSM_OID &inOid);
        bool                            revocationPolicySpecified(CFArrayRef policies);
        void                            orderRevocationPolicies(CFMutableArrayRef policies);
+       CFMutableArrayRef       convertRevocationPolicy(uint32 &numAdded, Allocator &alloc);
        CFMutableArrayRef       forceRevocationPolicies(uint32 &numAdded,
                                                        Allocator &alloc,
                                                        bool requirePerCert=false);
 
 private:
        CFMutableArrayRef       forceRevocationPolicies(uint32 &numAdded,
                                                        Allocator &alloc,
                                                        bool requirePerCert=false);
 
 private:
-    TP mTP;                                                    // our TP
-
-    // input arguments: set up before evaluate()
-    CSSM_TP_ACTION mAction;                    // TP action to verify
-    CFRef<CFDataRef> mActionData;      // action data
-    CFRef<CFDateRef> mVerifyTime;      // verification "now"
-    CFRef<CFArrayRef> mCerts;          // certificates to verify (item 1 is subject)
-    CFRef<CFArrayRef> mPolicies;       // array of policy objects to control verification
-    CFRef<CFArrayRef> mAnchors;                // array of anchor certs
-    StorageManager::KeychainList *mSearchLibs; // array of databases to search
-    bool mSearchLibsSet;                       // true if mSearchLibs has been initialized
-
-    // evaluation results: set as a result of evaluate()
-    SecTrustResultType mResult;                // result classification
-    uint32 mResultIndex;                       // which result cert made the decision?
-    OSStatus mTpReturn;                                // return code from TP Verify
-    TPVerifyResult mTpResult;          // result of latest TP verify
-
-    vector< SecPointer<Certificate> > mCertChain; // distilled certificate chain
-
-    // information returned to caller but owned by us
-    CFRef<CFArrayRef> mEvidenceReturned;       // evidence chain returned
+       TP mTP;                                                 // our TP
+
+       // input arguments: set up before evaluate()
+       CSSM_TP_ACTION mAction;                 // TP action to verify
+       CFRef<CFDataRef> mActionData;   // action data
+       CFRef<CFArrayRef> mExceptions;  // trust exceptions
+       CFRef<CFArrayRef> mResponses;   // array of OCSP response data (optional)
+       CFRef<CFDateRef> mVerifyTime;   // verification "now"
+       CFRef<CFArrayRef> mCerts;               // certificates to verify (item 1 is subject)
+       CFRef<CFArrayRef> mPolicies;    // array of policy objects to control verification
+       CFRef<CFArrayRef> mAnchors;             // array of anchor certs
+       StorageManager::KeychainList *mSearchLibs; // array of databases to search
+       bool mSearchLibsSet;                    // true if mSearchLibs has been initialized
+
+       // evaluation results: set as a result of evaluate()
+       SecTrustResultType mResult;             // result classification
+       uint32 mResultIndex;                    // which result cert made the decision?
+       OSStatus mTpReturn;                             // return code from TP Verify
+       TPVerifyResult mTpResult;               // result of latest TP verify
+
+       vector< SecPointer<Certificate> > mCertChain; // distilled certificate chain
+
+       // information returned to caller but owned by us
+       CFRef<CFArrayRef> mEvidenceReturned;    // evidence chain returned
        CFRef<CFArrayRef> mAllowedAnchors;              // array of permitted anchor certificates
        CFRef<CFArrayRef> mFilteredCerts;               // array of certificates to verify, post-filtering
        CFRef<CFArrayRef> mAllowedAnchors;              // array of permitted anchor certificates
        CFRef<CFArrayRef> mFilteredCerts;               // array of certificates to verify, post-filtering
-    CFRef<CFDictionaryRef> mExtendedResult;    // dictionary of extended results
+       CFRef<CFDictionaryRef> mExtendedResult; // dictionary of extended results
 
        bool mUsingTrustSettings;       // true if built-in anchors will be trusted
        AnchorPolicy mAnchorPolicy;     // policy for trusting passed-in and/or built-in anchors
 
        bool mUsingTrustSettings;       // true if built-in anchors will be trusted
        AnchorPolicy mAnchorPolicy;     // policy for trusting passed-in and/or built-in anchors
+       NetworkPolicy mNetworkPolicy;   // policy for allowing network use during evaluation
 
 public:
 
 public:
-    static ModuleNexus<TrustStore> gStore;
+       static ModuleNexus<TrustStore> gStore;
 
 private:
        Mutex mMutex;
 
 private:
        Mutex mMutex;
index 0f36410c96462704f901c4b190d8e22b905d16f7..0e13278c8cacde42c150f00e907dac71e4f1a3d8 100644 (file)
@@ -41,6 +41,7 @@
 #include <AvailabilityMacros.h>
 #include <CoreFoundation/CoreFoundation.h>
 #include <CommonCrypto/CommonDigest.h>
 #include <AvailabilityMacros.h>
 #include <CoreFoundation/CoreFoundation.h>
 #include <CommonCrypto/CommonDigest.h>
+#include <Security/SecBase.h>
 #include <Security/Security.h>
 #include <Security/cssmtype.h>
 #include <Security/cssmapplePriv.h>            // for CSSM_APPLE_TP_OCSP_OPTIONS, CSSM_APPLE_TP_OCSP_OPT_FLAGS
 #include <Security/Security.h>
 #include <Security/cssmtype.h>
 #include <Security/cssmapplePriv.h>            // for CSSM_APPLE_TP_OCSP_OPTIONS, CSSM_APPLE_TP_OCSP_OPT_FLAGS
@@ -58,8 +59,8 @@
        } /* status is only set on error */ \
        catch (const MacOSError &err) { status=err.osStatus(); } \
        catch (const CommonError &err) { status=SecKeychainErrFromOSStatus(err.osStatus()); } \
        } /* status is only set on error */ \
        catch (const MacOSError &err) { status=err.osStatus(); } \
        catch (const CommonError &err) { status=SecKeychainErrFromOSStatus(err.osStatus()); } \
-       catch (const std::bad_alloc &) { status=memFullErr; } \
-       catch (...) { status=internalComponentErr; }
+       catch (const std::bad_alloc &) { status=errSecAllocate; } \
+       catch (...) { status=errSecInternalComponent; }
 
 //
 // Static constants
 
 //
 // Static constants
@@ -99,7 +100,7 @@ static CFDataRef dataWithContentsOfFile(const char *fileName)
        int rtn;
        int fd;
        struct stat     sb;
        int rtn;
        int fd;
        struct stat     sb;
-       off_t fileSize;
+       size_t fileSize;
        UInt8 *fileData = NULL;
        CFDataRef outCFData = NULL;
 
        UInt8 *fileData = NULL;
        CFDataRef outCFData = NULL;
 
@@ -111,16 +112,16 @@ static CFDataRef dataWithContentsOfFile(const char *fileName)
        if(rtn)
                goto errOut;
 
        if(rtn)
                goto errOut;
 
-       fileSize = sb.st_size;
+       fileSize = (size_t)sb.st_size;
        fileData = (UInt8 *) malloc(fileSize);
        if(fileData == NULL)
                goto errOut;
 
        fileData = (UInt8 *) malloc(fileSize);
        if(fileData == NULL)
                goto errOut;
 
-       rtn = lseek(fd, 0, SEEK_SET);
+       rtn = (int)lseek(fd, 0, SEEK_SET);
        if(rtn < 0)
                goto errOut;
 
        if(rtn < 0)
                goto errOut;
 
-       rtn = read(fd, fileData, fileSize);
+       rtn = (int)read(fd, fileData, fileSize);
        if(rtn != (int)fileSize) {
                rtn = EIO;
        } else {
        if(rtn != (int)fileSize) {
                rtn = EIO;
        } else {
@@ -141,14 +142,14 @@ static SecKeychainRef systemRootStore()
 {
     SecKeychainStatus keychainStatus = 0;
     SecKeychainRef systemRoots = NULL;
 {
     SecKeychainStatus keychainStatus = 0;
     SecKeychainRef systemRoots = NULL;
-       OSStatus status = noErr;
+       OSStatus status = errSecSuccess;
        // note: Sec* APIs are not re-entrant due to the API lock
        // status = SecKeychainOpen(SYSTEM_ROOTS_PLIST_SYSTEM_PATH, &systemRoots);
        BEGIN_SECAPI_INTERNAL_CALL
        systemRoots=globals().storageManager.make(SYSTEM_ROOTS_PLIST_SYSTEM_PATH, false)->handle();
        END_SECAPI_INTERNAL_CALL
 
        // note: Sec* APIs are not re-entrant due to the API lock
        // status = SecKeychainOpen(SYSTEM_ROOTS_PLIST_SYSTEM_PATH, &systemRoots);
        BEGIN_SECAPI_INTERNAL_CALL
        systemRoots=globals().storageManager.make(SYSTEM_ROOTS_PLIST_SYSTEM_PATH, false)->handle();
        END_SECAPI_INTERNAL_CALL
 
-       // SecKeychainOpen will return noErr even if the file didn't exist on disk.
+       // SecKeychainOpen will return errSecSuccess even if the file didn't exist on disk.
        // We need to do a further check using SecKeychainGetStatus().
     if (!status && systemRoots) {
                // note: Sec* APIs are not re-entrant due to the API lock
        // We need to do a further check using SecKeychainGetStatus().
     if (!status && systemRoots) {
                // note: Sec* APIs are not re-entrant due to the API lock
@@ -165,7 +166,7 @@ static SecKeychainRef systemRootStore()
                BEGIN_SECAPI_INTERNAL_CALL
                systemRoots=globals().storageManager.make(X509ANCHORS_SYSTEM_PATH, false)->handle();
                END_SECAPI_INTERNAL_CALL
                BEGIN_SECAPI_INTERNAL_CALL
                systemRoots=globals().storageManager.make(X509ANCHORS_SYSTEM_PATH, false)->handle();
                END_SECAPI_INTERNAL_CALL
-        // SecKeychainOpen will return noErr even if the file didn't exist on disk.
+        // SecKeychainOpen will return errSecSuccess even if the file didn't exist on disk.
                // We need to do a further check using SecKeychainGetStatus().
         if (!status && systemRoots) {
                        // note: Sec* APIs are not re-entrant due to the API lock
                // We need to do a further check using SecKeychainGetStatus().
         if (!status && systemRoots) {
                        // note: Sec* APIs are not re-entrant due to the API lock
@@ -207,7 +208,7 @@ static CFDictionaryRef dictionaryWithContentsOfPlistFile(const char *fileName)
 static CFStringRef organizationNameForCertificate(SecCertificateRef certificate)
 {
     CFStringRef organizationName = nil;
 static CFStringRef organizationNameForCertificate(SecCertificateRef certificate)
 {
     CFStringRef organizationName = nil;
-       OSStatus status = noErr;
+       OSStatus status = errSecSuccess;
 
 #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4
     CSSM_OID_PTR oidPtr = (CSSM_OID_PTR) &CSSMOID_OrganizationName;
 
 #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4
     CSSM_OID_PTR oidPtr = (CSSM_OID_PTR) &CSSMOID_OrganizationName;
@@ -376,7 +377,7 @@ static SecCertificateRef _rootCertificateWithSubjectOfCertificate(SecCertificate
     // get data+length for the provided certificate
     CSSM_CL_HANDLE clHandle = 0;
     CSSM_DATA certData = { 0, NULL };
     // get data+length for the provided certificate
     CSSM_CL_HANDLE clHandle = 0;
     CSSM_DATA certData = { 0, NULL };
-       OSStatus status = noErr;
+       OSStatus status = errSecSuccess;
        // note: Sec* APIs are not re-entrant due to the API lock
        // status = SecCertificateGetCLHandle(certificate, &clHandle);
        BEGIN_SECAPI_INTERNAL_CALL
        // note: Sec* APIs are not re-entrant due to the API lock
        // status = SecCertificateGetCLHandle(certificate, &clHandle);
        BEGIN_SECAPI_INTERNAL_CALL
@@ -423,18 +424,18 @@ static SecCertificateRef _rootCertificateWithSubjectOfCertificate(SecCertificate
             uint8 buf[CC_SHA1_DIGEST_LENGTH];
             CSSM_DATA digest = { sizeof(buf), buf };
                        if (!cssmKey || !cssmKey->KeyData.Data || !cssmKey->KeyData.Length) {
             uint8 buf[CC_SHA1_DIGEST_LENGTH];
             CSSM_DATA digest = { sizeof(buf), buf };
                        if (!cssmKey || !cssmKey->KeyData.Data || !cssmKey->KeyData.Length) {
-                               status = paramErr;
+                               status = errSecParam;
                        } else {
                        } else {
-                               CC_SHA1(cssmKey->KeyData.Data, cssmKey->KeyData.Length, buf);
+                               CC_SHA1(cssmKey->KeyData.Data, (CC_LONG)cssmKey->KeyData.Length, buf);
                        }
             if (!status) {
                 // set up attribute vector (each attribute consists of {tag, length, pointer})
                 // we want to match on the public key hash and the normalized subject name
                 // as well as ensure that the issuer matches the subject
                 SecKeychainAttribute attrs[] = {
                        }
             if (!status) {
                 // set up attribute vector (each attribute consists of {tag, length, pointer})
                 // we want to match on the public key hash and the normalized subject name
                 // as well as ensure that the issuer matches the subject
                 SecKeychainAttribute attrs[] = {
-                    { kSecPublicKeyHashItemAttr, digest.Length, (void *)digest.Data },
-                    { kSecSubjectItemAttr, subjectDataPtr->Length, (void *)subjectDataPtr->Data },
-                    { kSecIssuerItemAttr, subjectDataPtr->Length, (void *)subjectDataPtr->Data }
+                    { kSecPublicKeyHashItemAttr, (UInt32)digest.Length, (void *)digest.Data },
+                    { kSecSubjectItemAttr, (UInt32)subjectDataPtr->Length, (void *)subjectDataPtr->Data },
+                    { kSecIssuerItemAttr, (UInt32)subjectDataPtr->Length, (void *)subjectDataPtr->Data }
                 };
                 const SecKeychainAttributeList attributes = { sizeof(attrs) / sizeof(attrs[0]), attrs };
                 SecKeychainSearchRef searchRef = NULL;
                 };
                 const SecKeychainAttributeList attributes = { sizeof(attrs) / sizeof(attrs[0]), attrs };
                 SecKeychainSearchRef searchRef = NULL;
@@ -494,7 +495,7 @@ static void logSKID(const char *msg, const CssmData &subjectKeyID)
 void showCertSKID(const void *value, void *context)
 {
        SecCertificateRef certificate = (SecCertificateRef)value;
 void showCertSKID(const void *value, void *context)
 {
        SecCertificateRef certificate = (SecCertificateRef)value;
-       OSStatus status = noErr;
+       OSStatus status = errSecSuccess;
        BEGIN_SECAPI_INTERNAL_CALL
        const CssmData &subjectKeyID = Certificate::required(certificate)->subjectKeyIdentifier();
        logSKID("subjectKeyID: ", subjectKeyID);
        BEGIN_SECAPI_INTERNAL_CALL
        const CssmData &subjectKeyID = Certificate::required(certificate)->subjectKeyIdentifier();
        logSKID("subjectKeyID: ", subjectKeyID);
@@ -509,7 +510,7 @@ void showCertSKID(const void *value, void *context)
 static SecCertificateRef _rootCertificateWithSubjectKeyIDOfCertificate(SecCertificateRef certificate)
 {
     SecCertificateRef resultCert = NULL;
 static SecCertificateRef _rootCertificateWithSubjectKeyIDOfCertificate(SecCertificateRef certificate)
 {
     SecCertificateRef resultCert = NULL;
-       OSStatus status = noErr;
+       OSStatus status = errSecSuccess;
 
     if (!certificate)
         return NULL;
 
     if (!certificate)
         return NULL;
@@ -544,6 +545,7 @@ static SecCertificateRef _rootCertificateWithSubjectKeyIDOfCertificate(SecCertif
 // returns an array of possible root certificates (SecCertificateRef instances)
 // for the given EV OID (a hex string); caller must release the array
 //
 // returns an array of possible root certificates (SecCertificateRef instances)
 // for the given EV OID (a hex string); caller must release the array
 //
+static
 CFArrayRef _possibleRootCertificatesForOidString(CFStringRef oidString)
 {
        StLock<Mutex> _(SecTrustKeychainsGetMutex());
 CFArrayRef _possibleRootCertificatesForOidString(CFStringRef oidString)
 {
        StLock<Mutex> _(SecTrustKeychainsGetMutex());
@@ -564,7 +566,7 @@ CFArrayRef _possibleRootCertificatesForOidString(CFStringRef oidString)
        CFIndex hashCount = CFArrayGetCount(possibleCertificateHashes);
        secdebug("evTrust", "_possibleRootCertificatesForOidString: %d possible hashes", (int)hashCount);
 
        CFIndex hashCount = CFArrayGetCount(possibleCertificateHashes);
        secdebug("evTrust", "_possibleRootCertificatesForOidString: %d possible hashes", (int)hashCount);
 
-       OSStatus status = noErr;
+       OSStatus status = errSecSuccess;
        SecKeychainSearchRef searchRef = NULL;
        // note: Sec* APIs are not re-entrant due to the API lock
        // status = SecKeychainSearchCreateFromAttributes(systemRoots, kSecCertificateItemClass, NULL, &searchRef);
        SecKeychainSearchRef searchRef = NULL;
        // note: Sec* APIs are not re-entrant due to the API lock
        // status = SecKeychainSearchCreateFromAttributes(systemRoots, kSecCertificateItemClass, NULL, &searchRef);
@@ -602,9 +604,9 @@ CFArrayRef _possibleRootCertificatesForOidString(CFStringRef oidString)
                                uint8 buf[CC_SHA1_DIGEST_LENGTH];
                                CSSM_DATA digest = { sizeof(buf), buf };
                                if (!certData.Data || !certData.Length) {
                                uint8 buf[CC_SHA1_DIGEST_LENGTH];
                                CSSM_DATA digest = { sizeof(buf), buf };
                                if (!certData.Data || !certData.Length) {
-                                       status = paramErr;
+                                       status = errSecParam;
                                } else {
                                } else {
-                                       CC_SHA1(certData.Data, certData.Length, buf);
+                                       CC_SHA1(certData.Data, (CC_LONG)certData.Length, buf);
                                }
                                if (!status) {
                                        CFDataRef hashData = CFDataCreateWithBytesNoCopy(NULL, digest.Data, digest.Length, kCFAllocatorNull);
                                }
                                if (!status) {
                                        CFDataRef hashData = CFDataCreateWithBytesNoCopy(NULL, digest.Data, digest.Length, kCFAllocatorNull);
@@ -660,7 +662,7 @@ CFArrayRef _allowedRootCertificatesForOidString(CFStringRef oidString)
                                        &foundMatch,    /* foundMatchingEntry */
                                        &foundAny);             /* foundAnyEntry */
 
                                        &foundMatch,    /* foundMatchingEntry */
                                        &foundAny);             /* foundAnyEntry */
 
-                               if (status == noErr) {
+                               if (status == errSecSuccess) {
                                        secdebug("evTrust", "_allowedRootCertificatesForOidString: cert %lu has result %d from domain %d",
                                                idx, (int)result, (int)foundDomain);
                                        // Root certificates must be trusted by the system (and not have
                                        secdebug("evTrust", "_allowedRootCertificatesForOidString: cert %lu has result %d from domain %d",
                                                idx, (int)result, (int)foundDomain);
                                        // Root certificates must be trusted by the system (and not have
@@ -866,7 +868,7 @@ CFArrayRef allowedEVRootsForLeafCertificate(CFArrayRef certificates)
     CSSM_CL_HANDLE clHandle = 0;
     CSSM_DATA certData = { 0, NULL };
     SecCertificateRef certRef = (SecCertificateRef) CFArrayGetValueAtIndex(certificates, 0);
     CSSM_CL_HANDLE clHandle = 0;
     CSSM_DATA certData = { 0, NULL };
     SecCertificateRef certRef = (SecCertificateRef) CFArrayGetValueAtIndex(certificates, 0);
-       OSStatus status = noErr;
+       OSStatus status = errSecSuccess;
        // note: Sec* APIs are not re-entrant due to the API lock
        // status = SecCertificateGetCLHandle(certRef, &clHandle);
        BEGIN_SECAPI_INTERNAL_CALL
        // note: Sec* APIs are not re-entrant due to the API lock
        // status = SecCertificateGetCLHandle(certRef, &clHandle);
        BEGIN_SECAPI_INTERNAL_CALL
@@ -913,6 +915,7 @@ CFArrayRef allowedEVRootsForLeafCertificate(CFArrayRef certificates)
 // or NULL if the certificate chain did not meet all EV criteria. (Caller must
 // release the result if not NULL.)
 //
 // or NULL if the certificate chain did not meet all EV criteria. (Caller must
 // release the result if not NULL.)
 //
+static
 CFDictionaryRef extendedValidationResults(CFArrayRef certChain, SecTrustResultType trustResult, OSStatus tpResult)
 {
        // This function is intended to be called after the "regular" TP evaluation
 CFDictionaryRef extendedValidationResults(CFArrayRef certChain, SecTrustResultType trustResult, OSStatus tpResult)
 {
        // This function is intended to be called after the "regular" TP evaluation
@@ -970,7 +973,7 @@ CFDictionaryRef extendedValidationResults(CFArrayRef certChain, SecTrustResultTy
        CSSM_OID_PTR oidPtr = (CSSM_OID_PTR) &CSSMOID_CertificatePolicies;
     for (chainIndex = 1; hasRequiredExtensions && chainLen > 2 && chainIndex < chainLen - 1; chainIndex++) {
         SecCertificateRef intermediateCert = (SecCertificateRef) CFArrayGetValueAtIndex(certChain, chainIndex);
        CSSM_OID_PTR oidPtr = (CSSM_OID_PTR) &CSSMOID_CertificatePolicies;
     for (chainIndex = 1; hasRequiredExtensions && chainLen > 2 && chainIndex < chainLen - 1; chainIndex++) {
         SecCertificateRef intermediateCert = (SecCertificateRef) CFArrayGetValueAtIndex(certChain, chainIndex);
-               OSStatus status = noErr;
+               OSStatus status = errSecSuccess;
                // note: Sec* APIs are not re-entrant due to the API lock
                // status = SecCertificateGetCLHandle(intermediateCert, &clHandle);
                BEGIN_SECAPI_INTERNAL_CALL
                // note: Sec* APIs are not re-entrant due to the API lock
                // status = SecCertificateGetCLHandle(intermediateCert, &clHandle);
                BEGIN_SECAPI_INTERNAL_CALL
index 3703274030f8de4723a72c1fe94e0da04d738e62..14cfb34051e3e11c8d145625fa92a6ae2b4baf26 100644 (file)
 
 #include <security_utilities/threading.h>
 #include <Security/cssmtype.h>
 
 #include <security_utilities/threading.h>
 #include <Security/cssmtype.h>
-
+/*
 #if defined(__cplusplus)
 extern "C" {
 #endif 
 #if defined(__cplusplus)
 extern "C" {
 #endif 
+*/
 
 /*!
  @function SecTrustKeychainsGetMutex
 
 /*!
  @function SecTrustKeychainsGetMutex
@@ -43,11 +44,12 @@ extern "C" {
  common global mutex for managing access to trust keychains (i.e. the root certificate store).
  */
 RecursiveMutex& SecTrustKeychainsGetMutex();
  common global mutex for managing access to trust keychains (i.e. the root certificate store).
  */
 RecursiveMutex& SecTrustKeychainsGetMutex();
-       
+
+/*
 #if defined(__cplusplus)
 }
 #endif
 #if defined(__cplusplus)
 }
 #endif
-
+*/
 
 #endif /* _TRUST_KEYCHAINS_H_ */
 
 
 #endif /* _TRUST_KEYCHAINS_H_ */
 
index 4817eabbeec5f92c708750643b33cea9cf3afc72..9816df52e9811c8df5c87e64733bf8a52272ede3 100644 (file)
@@ -1,15 +1,15 @@
 /*
  * Copyright (c) 2002-2004 Apple Computer, Inc. All Rights Reserved.
 /*
  * Copyright (c) 2002-2004 Apple Computer, Inc. All Rights Reserved.
- * 
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
-/* 
+/*
 * TrustRevocation.cpp - private revocation policy manipulation
 */
 
 * TrustRevocation.cpp - private revocation policy manipulation
 */
 
 #include <Security/cssmapplePriv.h>
 #include <Security/oidsalg.h>
 
 #include <Security/cssmapplePriv.h>
 #include <Security/oidsalg.h>
 
-/* 
+/*
  * These may go into an SPI header for the SecTrust object.
  */
 typedef enum {
        /* this revocation policy disabled */
  * These may go into an SPI header for the SecTrust object.
  */
 typedef enum {
        /* this revocation policy disabled */
-       kSecDisabled,                   
+       kSecDisabled,
        /* try, but tolerate inability to complete */
        /* try, but tolerate inability to complete */
-       kSecBestAttempt,        
+       kSecBestAttempt,
        /* require successful revocation check if certificate indicates
      * the policy is supported */
        kSecRequireIfPresentInCertificate,
        /* require successful revocation check if certificate indicates
      * the policy is supported */
        kSecRequireIfPresentInCertificate,
@@ -50,7 +50,7 @@ typedef enum {
 
 using namespace KeychainCore;
 
 
 using namespace KeychainCore;
 
-/* 
+/*
  * Given an app-specified array of Policies, determine if at least one of them
  * matches the given policy OID.
  */
  * Given an app-specified array of Policies, determine if at least one of them
  * matches the given policy OID.
  */
@@ -71,7 +71,7 @@ bool Trust::policySpecified(CFArrayRef policies, const CSSM_OID &inOid)
        return false;
 }
 
        return false;
 }
 
-/* 
+/*
  * Given an app-specified array of Policies, determine if at least one of them
  * is an explicit revocation policy.
  */
  * Given an app-specified array of Policies, determine if at least one of them
  * is an explicit revocation policy.
  */
@@ -95,21 +95,83 @@ bool Trust::revocationPolicySpecified(CFArrayRef policies)
        return false;
 }
 
        return false;
 }
 
-CFMutableArrayRef Trust::addSpecifiedRevocationPolicies(
-       uint32 &numAdded, 
+/*
+ * Replace a unified revocation policy instance in the mPolicies array
+ * with specific instances of the OCSP and/or CRL policies which the TP
+ * module understands. Returns a (possibly) modified copy of the mPolicies
+ * array, which the caller is responsible for releasing.
+ */
+CFMutableArrayRef Trust::convertRevocationPolicy(
+       uint32 &numAdded,
        Allocator &alloc)
 {
        Allocator &alloc)
 {
-       /* policies specified by SPI not implemented */
-       return NULL;
-}
+       numAdded = 0;
+       if (!mPolicies) {
+               return NULL;
+       }
+       CFIndex numPolicies = CFArrayGetCount(mPolicies);
+       CFAllocatorRef allocator = CFGetAllocator(mPolicies);
+       CFMutableArrayRef policies = CFArrayCreateMutableCopy(allocator, numPolicies, mPolicies);
+       SecPolicyRef revPolicy = NULL;
+       for(CFIndex dex=0; dex<numPolicies; dex++) {
+               SecPolicyRef secPol = (SecPolicyRef)CFArrayGetValueAtIndex(policies, dex);
+               SecPointer<Policy> pol = Policy::required(SecPolicyRef(secPol));
+               const CssmOid &oid = pol->oid();
+               if(oid == CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION)) {
+                       CFRetain(secPol);
+                       if (revPolicy)
+                               CFRelease(revPolicy);
+                       revPolicy = secPol;
+                       CFArrayRemoveValueAtIndex(policies, dex--);
+                       numPolicies--;
+               }
+       }
+       if(!revPolicy) {
+               CFRelease(policies);
+               return NULL;
+       }
 
 
-void Trust::freeSpecifiedRevocationPolicies(
-       CFArrayRef policies,
-       uint32 numAdded, 
-       Allocator &alloc)
-{
-       /* shouldn't be called */
-       MacOSError::throwMe(unimpErr);
+       SecPointer<Policy> ocspPolicy;
+       SecPointer<Policy> crlPolicy;
+
+       // fetch policy value
+       CFIndex policyValue = kSecRevocationUseAnyAvailableMethod; //%%%FIXME
+       CFRelease(revPolicy); // all done with this policy reference
+       if (policyValue & kSecRevocationOCSPMethod) {
+               /* cook up a new Policy object */
+               ocspPolicy = new Policy(mTP, CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_OCSP));
+               CSSM_APPLE_TP_OCSP_OPT_FLAGS ocspFlags = CSSM_TP_ACTION_OCSP_SUFFICIENT;
+               CSSM_APPLE_TP_OCSP_OPTIONS opts;
+               memset(&opts, 0, sizeof(opts));
+               opts.Version = CSSM_APPLE_TP_OCSP_OPTS_VERSION;
+               opts.Flags = ocspFlags;
+
+               /* Policy manages its own copy of this data */
+               CSSM_DATA optData = {sizeof(opts), (uint8 *)&opts};
+               ocspPolicy->value() = optData;
+
+               /* Policies array retains the Policy object */
+               CFArrayAppendValue(policies, ocspPolicy->handle(false));
+               numAdded++;
+       }
+       if (policyValue & kSecRevocationCRLMethod) {
+               /* cook up a new Policy object */
+               crlPolicy = new Policy(mTP, CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_CRL));
+               CSSM_APPLE_TP_CRL_OPT_FLAGS crlFlags = 0;
+               CSSM_APPLE_TP_CRL_OPTIONS opts;
+               memset(&opts, 0, sizeof(opts));
+               opts.Version = CSSM_APPLE_TP_CRL_OPTS_VERSION;
+               opts.CrlFlags = crlFlags;
+
+               /* Policy manages its own copy of this data */
+               CSSM_DATA optData = {sizeof(opts), (uint8 *)&opts};
+               crlPolicy->value() = optData;
+
+               /* Policies array retains the Policy object */
+               CFArrayAppendValue(policies, crlPolicy->handle(false));
+               numAdded++;
+       }
+       return policies;
 }
 
 static SecRevocationPolicyStyle parseRevStyle(CFStringRef val)
 }
 
 static SecRevocationPolicyStyle parseRevStyle(CFStringRef val)
@@ -163,12 +225,12 @@ CFDictionaryRef Trust::defaultRevocationSettings()
                &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
 }
 
                &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
 }
 
-CFMutableArrayRef Trust::addPreferenceRevocationPolicies( 
-       uint32 &numAdded, 
+CFMutableArrayRef Trust::addPreferenceRevocationPolicies(
+       uint32 &numAdded,
        Allocator &alloc)
 {
        numAdded = 0;
        Allocator &alloc)
 {
        numAdded = 0;
-       
+
        /* any per-user prefs? */
        Dictionary* pd = Dictionary::CreateDictionary(kSecRevocationDomain, Dictionary::US_User, true);
        if (pd)
        /* any per-user prefs? */
        Dictionary* pd = Dictionary::CreateDictionary(kSecRevocationDomain, Dictionary::US_User, true);
        if (pd)
@@ -187,19 +249,19 @@ CFMutableArrayRef Trust::addPreferenceRevocationPolicies(
                        pd = NULL;
                }
        }
                        pd = NULL;
                }
        }
-       
+
     if(pd == NULL)
     {
         CFDictionaryRef tempDict = defaultRevocationSettings();
         if (tempDict == NULL)
             return NULL;
     if(pd == NULL)
     {
         CFDictionaryRef tempDict = defaultRevocationSettings();
         if (tempDict == NULL)
             return NULL;
-        
+
         pd = new Dictionary(tempDict);
         CFRelease(tempDict);
     }
         pd = new Dictionary(tempDict);
         CFRelease(tempDict);
     }
-    
+
        auto_ptr<Dictionary> prefsDict(pd);
        auto_ptr<Dictionary> prefsDict(pd);
-       
+
        bool doOcsp = false;
        bool doCrl = false;
        CFStringRef val;
        bool doOcsp = false;
        bool doCrl = false;
        CFStringRef val;
@@ -207,7 +269,7 @@ CFMutableArrayRef Trust::addPreferenceRevocationPolicies(
        SecRevocationPolicyStyle crlStyle = kSecBestAttempt;
        SecPointer<Policy> ocspPolicy;
        SecPointer<Policy> crlPolicy;
        SecRevocationPolicyStyle crlStyle = kSecBestAttempt;
        SecPointer<Policy> ocspPolicy;
        SecPointer<Policy> crlPolicy;
-       
+
        /* Are any revocation policies enabled? */
        val = prefsDict->getStringValue(kSecRevocationOcspStyle);
        if(val != NULL) {
        /* Are any revocation policies enabled? */
        val = prefsDict->getStringValue(kSecRevocationOcspStyle);
        if(val != NULL) {
@@ -226,7 +288,7 @@ CFMutableArrayRef Trust::addPreferenceRevocationPolicies(
        if(!doCrl && !doOcsp) {
                return NULL;
        }
        if(!doCrl && !doOcsp) {
                return NULL;
        }
-       
+
        /* which policy first? */
        bool ocspFirst = true;          // default if both present
        if(doCrl && doOcsp) {
        /* which policy first? */
        bool ocspFirst = true;          // default if both present
        if(doCrl && doOcsp) {
@@ -236,19 +298,25 @@ CFMutableArrayRef Trust::addPreferenceRevocationPolicies(
                }
        }
 
                }
        }
 
+       /* Must have at least one caller-specified policy
+        * (if they didn't specify any, it's a no-op evaluation, and if they wanted
+        * revocation checking only, that policy would already be in mPolicies) */
+       if (!mPolicies || !CFArrayGetCount(mPolicies))
+               return NULL;
+
        /* We're adding something to mPolicies, so make a copy we can work with */
        CFMutableArrayRef policies = CFArrayCreateMutableCopy(NULL, 0, mPolicies);
        if(policies == NULL) {
                throw std::bad_alloc();
        }
        /* We're adding something to mPolicies, so make a copy we can work with */
        CFMutableArrayRef policies = CFArrayCreateMutableCopy(NULL, 0, mPolicies);
        if(policies == NULL) {
                throw std::bad_alloc();
        }
-       
+
        if(doOcsp) {
                /* Cook up a new Policy object */
                ocspPolicy = new Policy(mTP, CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_OCSP));
                CSSM_APPLE_TP_OCSP_OPTIONS opts;
                memset(&opts, 0, sizeof(opts));
                opts.Version = CSSM_APPLE_TP_OCSP_OPTS_VERSION;
        if(doOcsp) {
                /* Cook up a new Policy object */
                ocspPolicy = new Policy(mTP, CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_OCSP));
                CSSM_APPLE_TP_OCSP_OPTIONS opts;
                memset(&opts, 0, sizeof(opts));
                opts.Version = CSSM_APPLE_TP_OCSP_OPTS_VERSION;
-               
+
                /* Now fill in the OCSP-related blanks */
                switch(ocspStyle) {
                        case kSecDisabled:
                /* Now fill in the OCSP-related blanks */
                switch(ocspStyle) {
                        case kSecDisabled:
@@ -264,11 +332,11 @@ CFMutableArrayRef Trust::addPreferenceRevocationPolicies(
                                opts.Flags |= CSSM_TP_ACTION_OCSP_REQUIRE_PER_CERT;
                                break;
                }
                                opts.Flags |= CSSM_TP_ACTION_OCSP_REQUIRE_PER_CERT;
                                break;
                }
-               
+
                if(prefsDict->getBoolValue(kSecRevocationOCSPSufficientPerCert)) {
                        opts.Flags |= CSSM_TP_ACTION_OCSP_SUFFICIENT;
                }
                if(prefsDict->getBoolValue(kSecRevocationOCSPSufficientPerCert)) {
                        opts.Flags |= CSSM_TP_ACTION_OCSP_SUFFICIENT;
                }
-               
+
                val = prefsDict->getStringValue(kSecOCSPLocalResponder);
                if(val != NULL) {
                        CFDataRef cfData = CFStringCreateExternalRepresentation(NULL,
                val = prefsDict->getStringValue(kSecOCSPLocalResponder);
                if(val != NULL) {
                        CFDataRef cfData = CFStringCreateExternalRepresentation(NULL,
@@ -280,13 +348,13 @@ CFMutableArrayRef Trust::addPreferenceRevocationPolicies(
                        memmove(opts.LocalResponder->Data, CFDataGetBytePtr(cfData), len);
                        CFRelease(cfData);
                }
                        memmove(opts.LocalResponder->Data, CFDataGetBytePtr(cfData), len);
                        CFRelease(cfData);
                }
-               
+
                /* Policy manages its own copy of this data */
                CSSM_DATA optData = {sizeof(opts), (uint8 *)&opts};
                ocspPolicy->value() = optData;
                numAdded++;
        }
                /* Policy manages its own copy of this data */
                CSSM_DATA optData = {sizeof(opts), (uint8 *)&opts};
                ocspPolicy->value() = optData;
                numAdded++;
        }
-       
+
        if(doCrl) {
                /* Cook up a new Policy object */
                crlPolicy = new Policy(mTP, CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_CRL));
        if(doCrl) {
                /* Cook up a new Policy object */
                crlPolicy = new Policy(mTP, CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_CRL));
@@ -319,7 +387,7 @@ CFMutableArrayRef Trust::addPreferenceRevocationPolicies(
                crlPolicy->value() = optData;
                numAdded++;
        }
                crlPolicy->value() = optData;
                numAdded++;
        }
-       
+
        /* append in order */
        if(doOcsp) {
                if(doCrl) {
        /* append in order */
        if(doOcsp) {
                if(doCrl) {
@@ -346,11 +414,13 @@ CFMutableArrayRef Trust::addPreferenceRevocationPolicies(
 }
 
 /*
 }
 
 /*
- * Called when we created the last numAdded Policies in the specified Policy array 
+ * Called when we created the last numAdded Policies in the specified Policy array
+ * (only frees the policy data associated with the extra policies that we inserted;
+ * this does not free the policies array itself.)
  */
  */
-void Trust::freePreferenceRevocationPolicies(
+void Trust::freeAddedRevocationPolicyData(
        CFArrayRef policies,
        CFArrayRef policies,
-       uint32 numAdded, 
+       uint32 numAdded,
        Allocator &alloc)
 {
        uint32 numPolicies = (uint32)CFArrayGetCount(policies);
        Allocator &alloc)
 {
        uint32 numPolicies = (uint32)CFArrayGetCount(policies);
@@ -365,7 +435,7 @@ void Trust::freePreferenceRevocationPolicies(
                Policy *pol = Policy::required(secPol);
                const CssmOid &oid = pol->oid();                // required
                const CssmData &optData = pol->value(); // optional
                Policy *pol = Policy::required(secPol);
                const CssmOid &oid = pol->oid();                // required
                const CssmData &optData = pol->value(); // optional
-               
+
                if(optData.Data) {
                        if(oid == CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_CRL)) {
                                /* currently no CRL-specific policy data */
                if(optData.Data) {
                        if(oid == CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_CRL)) {
                                /* currently no CRL-specific policy data */
@@ -382,7 +452,6 @@ void Trust::freePreferenceRevocationPolicies(
                        // managed by Policy alloc.free(optData.Data);
                }
        }
                        // managed by Policy alloc.free(optData.Data);
                }
        }
-       CFRelease(policies);
 }
 
 /*
 }
 
 /*
@@ -494,8 +563,8 @@ void Trust::orderRevocationPolicies(
  *
  * Caller is responsible for releasing the returned policies array.
  */
  *
  * Caller is responsible for releasing the returned policies array.
  */
-CFMutableArrayRef Trust::forceRevocationPolicies( 
-       uint32 &numAdded, 
+CFMutableArrayRef Trust::forceRevocationPolicies(
+       uint32 &numAdded,
        Allocator &alloc,
        bool requirePerCert)
 {
        Allocator &alloc,
        bool requirePerCert)
 {
@@ -506,7 +575,7 @@ CFMutableArrayRef Trust::forceRevocationPolicies(
        bool hasOcspPolicy = false;
        bool hasCrlPolicy = false;
        numAdded = 0;
        bool hasOcspPolicy = false;
        bool hasCrlPolicy = false;
        numAdded = 0;
-       
+
        ocspFlags = CSSM_TP_ACTION_OCSP_SUFFICIENT;
        crlFlags = CSSM_TP_ACTION_FETCH_CRL_FROM_NET | CSSM_TP_ACTION_CRL_SUFFICIENT;
        if (requirePerCert) {
        ocspFlags = CSSM_TP_ACTION_OCSP_SUFFICIENT;
        crlFlags = CSSM_TP_ACTION_FETCH_CRL_FROM_NET | CSSM_TP_ACTION_CRL_SUFFICIENT;
        if (requirePerCert) {
@@ -550,7 +619,7 @@ CFMutableArrayRef Trust::forceRevocationPolicies(
                        }
                        hasCrlPolicy = true;
                }
                        }
                        hasCrlPolicy = true;
                }
-       }       
+       }
 
        /* We're potentially adding something to mPolicies, so make a copy we can work with */
        CFMutableArrayRef policies = CFArrayCreateMutableCopy(NULL, 0, mPolicies);
 
        /* We're potentially adding something to mPolicies, so make a copy we can work with */
        CFMutableArrayRef policies = CFArrayCreateMutableCopy(NULL, 0, mPolicies);
@@ -565,7 +634,7 @@ CFMutableArrayRef Trust::forceRevocationPolicies(
                memset(&opts, 0, sizeof(opts));
                opts.Version = CSSM_APPLE_TP_OCSP_OPTS_VERSION;
                opts.Flags = ocspFlags;
                memset(&opts, 0, sizeof(opts));
                opts.Version = CSSM_APPLE_TP_OCSP_OPTS_VERSION;
                opts.Flags = ocspFlags;
-               
+
                /* Check prefs dict for local responder info */
                Dictionary *prefsDict = NULL;
                try { /* per-user prefs */
                /* Check prefs dict for local responder info */
                Dictionary *prefsDict = NULL;
                try { /* per-user prefs */
@@ -603,15 +672,15 @@ CFMutableArrayRef Trust::forceRevocationPolicies(
                /* Policy manages its own copy of the options data */
                CSSM_DATA optData = {sizeof(opts), (uint8 *)&opts};
                ocspPolicy->value() = optData;
                /* Policy manages its own copy of the options data */
                CSSM_DATA optData = {sizeof(opts), (uint8 *)&opts};
                ocspPolicy->value() = optData;
-               
+
                /* Policies array retains the Policy object */
                CFArrayAppendValue(policies, ocspPolicy->handle(false));
                numAdded++;
                /* Policies array retains the Policy object */
                CFArrayAppendValue(policies, ocspPolicy->handle(false));
                numAdded++;
-               
+
                if(prefsDict != NULL)
                        delete prefsDict;
        }
                if(prefsDict != NULL)
                        delete prefsDict;
        }
-       
+
        if(!hasCrlPolicy) {
                /* Cook up a new Policy object */
                crlPolicy = new Policy(mTP, CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_CRL));
        if(!hasCrlPolicy) {
                /* Cook up a new Policy object */
                crlPolicy = new Policy(mTP, CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_CRL));
@@ -623,7 +692,7 @@ CFMutableArrayRef Trust::forceRevocationPolicies(
                /* Policy manages its own copy of this data */
                CSSM_DATA optData = {sizeof(opts), (uint8 *)&opts};
                crlPolicy->value() = optData;
                /* Policy manages its own copy of this data */
                CSSM_DATA optData = {sizeof(opts), (uint8 *)&opts};
                crlPolicy->value() = optData;
-               
+
                /* Policies array retains the Policy object */
                CFArrayAppendValue(policies, crlPolicy->handle(false));
                numAdded++;
                /* Policies array retains the Policy object */
                CFArrayAppendValue(policies, crlPolicy->handle(false));
                numAdded++;
index 83d2d8b64153e0e1996324d26123cca54dd71a77..47cf13d5c61b8ebe466d4e48c057d752ebff0eaa 100644 (file)
@@ -36,8 +36,8 @@
 #include "SecPolicyPriv.h"
 #include "Certificate.h"
 #include "cssmdatetime.h"
 #include "SecPolicyPriv.h"
 #include "Certificate.h"
 #include "cssmdatetime.h"
+#include <Security/SecBase.h>
 #include "SecTrustedApplicationPriv.h"
 #include "SecTrustedApplicationPriv.h"
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 #include <security_utilities/errors.h> 
 #include <security_utilities/debugging.h>
 #include <security_utilities/logging.h>
 #include <security_utilities/errors.h> 
 #include <security_utilities/debugging.h>
 #include <security_utilities/logging.h>
@@ -314,6 +314,7 @@ static void tsSetModDate(
 }
 
 /* make sure a presumed CFNumber can be converted to a 32-bit number */
 }
 
 /* make sure a presumed CFNumber can be converted to a 32-bit number */
+static
 bool tsIsGoodCfNum(CFNumberRef cfn, SInt32 *num = NULL)
 {
        if(cfn == NULL) {
 bool tsIsGoodCfNum(CFNumberRef cfn, SInt32 *num = NULL)
 {
        if(cfn == NULL) {
@@ -372,7 +373,7 @@ OSStatus TrustSettings::CreateTrustSettings(
 
        Allocator &alloc = Allocator::standard();
        CSSM_DATA fileData = {0, NULL};
 
        Allocator &alloc = Allocator::standard();
        CSSM_DATA fileData = {0, NULL};
-       OSStatus ortn = noErr;
+       OSStatus ortn = errSecSuccess;
        struct stat sb;
        const char *path;
 
        struct stat sb;
        const char *path;
 
@@ -403,7 +404,7 @@ OSStatus TrustSettings::CreateTrustSettings(
                        break;
                default:
                        delete t;
                        break;
                default:
                        delete t;
-                       return paramErr;
+                       return errSecParam;
        }
        if(ortn) {
                if(create) {
        }
        if(ortn) {
                if(create) {
@@ -427,7 +428,7 @@ OSStatus TrustSettings::CreateTrustSettings(
        t->validatePropList(trim);
        
        ts = t;
        t->validatePropList(trim);
        
        ts = t;
-       return noErr;
+       return errSecSuccess;
 }
 
 /* 
 }
 
 /* 
@@ -446,7 +447,7 @@ OSStatus TrustSettings::CreateTrustSettings(
                        break;
                case kSecTrustSettingsDomainSystem:             /* no can do, that implies writing to it */
                default:
                        break;
                case kSecTrustSettingsDomainSystem:             /* no can do, that implies writing to it */
                default:
-                       return paramErr;
+                       return errSecParam;
        }
 
        TrustSettings* t = new TrustSettings(domain);
        }
 
        TrustSettings* t = new TrustSettings(domain);
@@ -461,7 +462,7 @@ OSStatus TrustSettings::CreateTrustSettings(
        t->mDirty = true;
        
        ts = t;
        t->mDirty = true;
        
        ts = t;
-       return noErr;
+       return errSecSuccess;
 }
 
 
 }
 
 
@@ -506,7 +507,7 @@ void TrustSettings::flushToDisk()
        if(mPropList == NULL) {
                trustSettingsDbg("flushToDisk, domain %d, trimmed!", (int)mDomain);
                assert(0);
        if(mPropList == NULL) {
                trustSettingsDbg("flushToDisk, domain %d, trimmed!", (int)mDomain);
                assert(0);
-               MacOSError::throwMe(internalComponentErr);
+               MacOSError::throwMe(errSecInternalComponent);
        }
        switch(mDomain) {
                case kSecTrustSettingsDomainSystem:
        }
        switch(mDomain) {
                case kSecTrustSettingsDomainSystem:
@@ -514,7 +515,7 @@ void TrustSettings::flushToDisk()
                /* caller shouldn't even try this */
                default:
                        trustSettingsDbg("flushToDisk, bad domain (%d)", (int)mDomain);
                /* caller shouldn't even try this */
                default:
                        trustSettingsDbg("flushToDisk, bad domain (%d)", (int)mDomain);
-                       MacOSError::throwMe(internalComponentErr);
+                       MacOSError::throwMe(errSecInternalComponent);
                case kSecTrustSettingsDomainUser:
                case kSecTrustSettingsDomainAdmin:
                        break;
                case kSecTrustSettingsDomainUser:
                case kSecTrustSettingsDomainAdmin:
                        break;
@@ -536,7 +537,7 @@ void TrustSettings::flushToDisk()
                if(!xmlData) {
                        /* we've been very careful; this should never happen */
                        trustSettingsDbg("flushToDisk, domain %d: error converting to XML", (int)mDomain);
                if(!xmlData) {
                        /* we've been very careful; this should never happen */
                        trustSettingsDbg("flushToDisk, domain %d: error converting to XML", (int)mDomain);
-                       MacOSError::throwMe(internalComponentErr);
+                       MacOSError::throwMe(errSecInternalComponent);
                }
                cssmXmlData.Data = (uint8 *)CFDataGetBytePtr(xmlData);
                cssmXmlData.Length = CFDataGetLength(xmlData);
                }
                cssmXmlData.Data = (uint8 *)CFDataGetBytePtr(xmlData);
                cssmXmlData.Length = CFDataGetLength(xmlData);
@@ -553,7 +554,7 @@ void TrustSettings::flushToDisk()
        if(ortn) {
                trustSettingsDbg("flushToDisk, domain %d: AuthorizationCreate returned %ld", 
                        (int)mDomain, (long)ortn);
        if(ortn) {
                trustSettingsDbg("flushToDisk, domain %d: AuthorizationCreate returned %ld", 
                        (int)mDomain, (long)ortn);
-               MacOSError::throwMe(internalComponentErr);
+               MacOSError::throwMe(errSecInternalComponent);
        }
        AuthorizationExternalForm authExt;
        CSSM_DATA authBlob = {sizeof(authExt), (uint8 *)&authExt};
        }
        AuthorizationExternalForm authExt;
        CSSM_DATA authBlob = {sizeof(authExt), (uint8 *)&authExt};
@@ -561,7 +562,7 @@ void TrustSettings::flushToDisk()
        if(ortn) {
                trustSettingsDbg("flushToDisk, domain %d: AuthorizationMakeExternalForm returned %ld", 
                        (int)mDomain, (long)ortn);
        if(ortn) {
                trustSettingsDbg("flushToDisk, domain %d: AuthorizationMakeExternalForm returned %ld", 
                        (int)mDomain, (long)ortn);
-               ortn = internalComponentErr;
+               ortn = errSecInternalComponent;
                goto errOut;
        }
        
                goto errOut;
        }
        
@@ -590,7 +591,7 @@ CFDataRef TrustSettings::createExternal()
        if(xmlData == NULL) {
                trustSettingsDbg("createExternal, domain %d: error converting to XML",
                        (int)mDomain);
        if(xmlData == NULL) {
                trustSettingsDbg("createExternal, domain %d: error converting to XML",
                        (int)mDomain);
-               MacOSError::throwMe(internalComponentErr);
+               MacOSError::throwMe(errSecInternalComponent);
        }
        return xmlData;
 }
        }
        return xmlData;
 }
@@ -1040,7 +1041,7 @@ void TrustSettings::setTrustSettings(
                certDict = CFDictionaryCreateMutable(NULL, kSecTrustRecordNumCertDictKeys,
                        &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
                if(certDict == NULL) {
                certDict = CFDictionaryCreateMutable(NULL, kSecTrustRecordNumCertDictKeys,
                        &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
                if(certDict == NULL) {
-                       MacOSError::throwMe(memFullErr);
+                       MacOSError::throwMe(errSecAllocate);
                }
                CFDictionaryAddValue(certDict, kTrustRecordIssuer, issuer);
                CFDictionaryAddValue(certDict, kTrustRecordSerialNumber, serial);
                }
                CFDictionaryAddValue(certDict, kTrustRecordIssuer, issuer);
                CFDictionaryAddValue(certDict, kTrustRecordSerialNumber, serial);
@@ -1155,7 +1156,7 @@ CFArrayRef TrustSettings::validateApiTrustSettings(
                /* trivial case, only valid for roots */
                if(!isSelfSigned) {
                        trustSettingsDbg("validateApiUsageConstraints: !isSelfSigned, no settings");
                /* trivial case, only valid for roots */
                if(!isSelfSigned) {
                        trustSettingsDbg("validateApiUsageConstraints: !isSelfSigned, no settings");
-                       MacOSError::throwMe(paramErr);
+                       MacOSError::throwMe(errSecParam);
                }
                return CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks);
        }
                }
                return CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks);
        }
@@ -1171,13 +1172,13 @@ CFArrayRef TrustSettings::validateApiTrustSettings(
        }
        else {
                trustSettingsDbg("validateApiUsageConstraints: bad trustSettingsDictOrArray");
        }
        else {
                trustSettingsDbg("validateApiUsageConstraints: bad trustSettingsDictOrArray");
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
        }
        
        CFIndex numSpecs = CFArrayGetCount(tmpInArray);
        CFMutableArrayRef outArray = CFArrayCreateMutable(NULL, numSpecs, &kCFTypeArrayCallBacks);
        CSSM_OID oid;
        }
        
        CFIndex numSpecs = CFArrayGetCount(tmpInArray);
        CFMutableArrayRef outArray = CFArrayCreateMutable(NULL, numSpecs, &kCFTypeArrayCallBacks);
        CSSM_OID oid;
-       OSStatus ortn = noErr;
+       OSStatus ortn = errSecSuccess;
        SecPolicyRef certPolicy;
        SecTrustedApplicationRef certApp;
        
        SecPolicyRef certPolicy;
        SecTrustedApplicationRef certApp;
        
@@ -1196,7 +1197,7 @@ CFArrayRef TrustSettings::validateApiTrustSettings(
                CFDictionaryRef ucDict = (CFDictionaryRef)CFArrayGetValueAtIndex(tmpInArray, dex);
                if(CFGetTypeID(ucDict) != CFDictionaryGetTypeID()) {
                        trustSettingsDbg("validateAppPolicyArray: malformed usageConstraint dictionary");
                CFDictionaryRef ucDict = (CFDictionaryRef)CFArrayGetValueAtIndex(tmpInArray, dex);
                if(CFGetTypeID(ucDict) != CFDictionaryGetTypeID()) {
                        trustSettingsDbg("validateAppPolicyArray: malformed usageConstraint dictionary");
-                       ortn = paramErr;
+                       ortn = errSecParam;
                        break;
                }
                
                        break;
                }
                
@@ -1205,7 +1206,7 @@ CFArrayRef TrustSettings::validateApiTrustSettings(
                if(certPolicy != NULL) {
                        if(CFGetTypeID(certPolicy) != SecPolicyGetTypeID()) {
                                trustSettingsDbg("validateAppPolicyArray: malformed certPolicy");
                if(certPolicy != NULL) {
                        if(CFGetTypeID(certPolicy) != SecPolicyGetTypeID()) {
                                trustSettingsDbg("validateAppPolicyArray: malformed certPolicy");
-                               ortn = paramErr;
+                               ortn = errSecParam;
                                break;
                        }
                        ortn = SecPolicyGetOID(certPolicy, &oid);
                                break;
                        }
                        ortn = SecPolicyGetOID(certPolicy, &oid);
@@ -1221,7 +1222,7 @@ CFArrayRef TrustSettings::validateApiTrustSettings(
                if(certApp != NULL) {
                        if(CFGetTypeID(certApp) != SecTrustedApplicationGetTypeID()) {
                                trustSettingsDbg("validateAppPolicyArray: malformed certApp");
                if(certApp != NULL) {
                        if(CFGetTypeID(certApp) != SecTrustedApplicationGetTypeID()) {
                                trustSettingsDbg("validateAppPolicyArray: malformed certApp");
-                               ortn = paramErr;
+                               ortn = errSecParam;
                                break;
                        }
                        ortn = SecTrustedApplicationCopyExternalRepresentation(certApp, &appData);
                                break;
                        }
                        ortn = SecTrustedApplicationCopyExternalRepresentation(certApp, &appData);
@@ -1236,20 +1237,20 @@ CFArrayRef TrustSettings::validateApiTrustSettings(
                if(policyStr != NULL) {
                        if(CFGetTypeID(policyStr) != CFStringGetTypeID()) {
                                trustSettingsDbg("validateAppPolicyArray: malformed policyStr");
                if(policyStr != NULL) {
                        if(CFGetTypeID(policyStr) != CFStringGetTypeID()) {
                                trustSettingsDbg("validateAppPolicyArray: malformed policyStr");
-                               ortn = paramErr;
+                               ortn = errSecParam;
                                break;
                        }
                }
                allowedErr = (CFNumberRef)CFDictionaryGetValue(ucDict, kSecTrustSettingsAllowedError);
                if(!tsIsGoodCfNum(allowedErr)) {
                        trustSettingsDbg("validateAppPolicyArray: malformed allowedErr");
                                break;
                        }
                }
                allowedErr = (CFNumberRef)CFDictionaryGetValue(ucDict, kSecTrustSettingsAllowedError);
                if(!tsIsGoodCfNum(allowedErr)) {
                        trustSettingsDbg("validateAppPolicyArray: malformed allowedErr");
-                       ortn = paramErr;
+                       ortn = errSecParam;
                        break;
                }
                resultType = (CFNumberRef)CFDictionaryGetValue(ucDict, kSecTrustSettingsResult);
                if(!tsIsGoodCfNum(resultType, &resultNum)) {
                        trustSettingsDbg("validateAppPolicyArray: malformed resultType");
                        break;
                }
                resultType = (CFNumberRef)CFDictionaryGetValue(ucDict, kSecTrustSettingsResult);
                if(!tsIsGoodCfNum(resultType, &resultNum)) {
                        trustSettingsDbg("validateAppPolicyArray: malformed resultType");
-                       ortn = paramErr;
+                       ortn = errSecParam;
                        break;
                }
                result = resultNum;
                        break;
                }
                result = resultNum;
@@ -1258,7 +1259,7 @@ CFArrayRef TrustSettings::validateApiTrustSettings(
                keyUsage   = (CFNumberRef)CFDictionaryGetValue(ucDict, kSecTrustSettingsKeyUsage);
                if(!tsIsGoodCfNum(keyUsage)) {
                        trustSettingsDbg("validateAppPolicyArray: malformed keyUsage");
                keyUsage   = (CFNumberRef)CFDictionaryGetValue(ucDict, kSecTrustSettingsKeyUsage);
                if(!tsIsGoodCfNum(keyUsage)) {
                        trustSettingsDbg("validateAppPolicyArray: malformed keyUsage");
-                       ortn = paramErr;
+                       ortn = errSecParam;
                        break;
                }
                
                        break;
                }
                
@@ -1292,18 +1293,18 @@ CFArrayRef TrustSettings::validateApiTrustSettings(
                        /* let's be really picky on this one */
                        switch(result) {
                                case kSecTrustSettingsResultInvalid:
                        /* let's be really picky on this one */
                        switch(result) {
                                case kSecTrustSettingsResultInvalid:
-                                       ortn = paramErr;
+                                       ortn = errSecParam;
                                        break;
                                case kSecTrustSettingsResultTrustRoot:
                                        if(!isSelfSigned) {
                                                trustSettingsDbg("validateAppPolicyArray: TrustRoot, !isSelfSigned");
                                        break;
                                case kSecTrustSettingsResultTrustRoot:
                                        if(!isSelfSigned) {
                                                trustSettingsDbg("validateAppPolicyArray: TrustRoot, !isSelfSigned");
-                                               ortn = paramErr;
+                                               ortn = errSecParam;
                                        }
                                        break;
                                case kSecTrustSettingsResultTrustAsRoot:
                                        if(isSelfSigned) {
                                                trustSettingsDbg("validateAppPolicyArray: TrustAsRoot, isSelfSigned");
                                        }
                                        break;
                                case kSecTrustSettingsResultTrustAsRoot:
                                        if(isSelfSigned) {
                                                trustSettingsDbg("validateAppPolicyArray: TrustAsRoot, isSelfSigned");
-                                               ortn = paramErr;
+                                               ortn = errSecParam;
                                        }
                                        break;
                                case kSecTrustSettingsResultDeny:
                                        }
                                        break;
                                case kSecTrustSettingsResultDeny:
@@ -1311,7 +1312,7 @@ CFArrayRef TrustSettings::validateApiTrustSettings(
                                        break;
                                default:
                                        trustSettingsDbg("validateAppPolicyArray: bogus resultType");
                                        break;
                                default:
                                        trustSettingsDbg("validateAppPolicyArray: bogus resultType");
-                                       ortn = paramErr;
+                                       ortn = errSecParam;
                                        break;
                        }
                        if(ortn) {
                                        break;
                        }
                        if(ortn) {
@@ -1323,7 +1324,7 @@ CFArrayRef TrustSettings::validateApiTrustSettings(
                        /* no resultType; default of TrustRoot only valid for root */
                        if(!isSelfSigned) {
                                trustSettingsDbg("validateAppPolicyArray: default result, !isSelfSigned");
                        /* no resultType; default of TrustRoot only valid for root */
                        if(!isSelfSigned) {
                                trustSettingsDbg("validateAppPolicyArray: default result, !isSelfSigned");
-                               ortn = paramErr;
+                               ortn = errSecParam;
                                break;
                        }
                }
                                break;
                        }
                }
index 6bd4651d6fc12a23727a150743b92acc2af1f99f..66fc59dd2d1113427aa6d0eeadbccfd397a17af6 100644 (file)
@@ -35,7 +35,6 @@
 #include <sys/param.h>
 #include <sys/stat.h>
 #include <sys/fcntl.h>
 #include <sys/param.h>
 #include <sys/stat.h>
 #include <sys/fcntl.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 
 /* 
  * Preferred location for user root store is ~/Library/Keychain/UserRootCerts.keychain. 
 
 /* 
  * Preferred location for user root store is ~/Library/Keychain/UserRootCerts.keychain. 
@@ -72,17 +71,17 @@ int tsReadFile(
        if(rtn) {
                goto errOut;
        }
        if(rtn) {
                goto errOut;
        }
-       size = sb.st_size;
+       size = (unsigned)sb.st_size;
        fileData.Data = (uint8 *)alloc.malloc(size);
        if(fileData.Data == NULL) {
                rtn = ENOMEM;
                goto errOut;
        }
        fileData.Data = (uint8 *)alloc.malloc(size);
        if(fileData.Data == NULL) {
                rtn = ENOMEM;
                goto errOut;
        }
-       rtn = lseek(fd, 0, SEEK_SET);
+       rtn = (int)lseek(fd, 0, SEEK_SET);
        if(rtn < 0) {
                goto errOut;
        }
        if(rtn < 0) {
                goto errOut;
        }
-       rtn = read(fd, fileData.Data, (size_t)size);
+       rtn = (int)read(fd, fileData.Data, (size_t)size);
        if(rtn != (int)size) {
                rtn = EIO;
        }
        if(rtn != (int)size) {
                rtn = EIO;
        }
index 6746d654fcd8c43c426a573e7161a5072ad39eb8..f2aae0b171dce47abe0898f94825d4e3006cec99 100644 (file)
 #include <security_utilities/alloc.h>
 #include <string>
 #include <CoreFoundation/CoreFoundation.h>
 #include <security_utilities/alloc.h>
 #include <string>
 #include <CoreFoundation/CoreFoundation.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 
 #define CFRELEASE(cf)          if(cf) { CFRelease(cf); }
 
 
 #define CFRELEASE(cf)          if(cf) { CFRelease(cf); }
 
-#define TS_REQUIRED(arg)       if(arg == NULL) { return paramErr; }
+#define TS_REQUIRED(arg)       if(arg == NULL) { return errSecParam; }
 
 namespace Security
 {
 
 namespace Security
 {
index d30997bec3942a4fa46098091d64e2e70f1b4477..716ea3bc54903641c647a46a7b1e9bbda751d12a 100644 (file)
@@ -1,15 +1,15 @@
 /*
  * Copyright (c) 2002-2004 Apple Computer, Inc. All Rights Reserved.
 /*
  * Copyright (c) 2002-2004 Apple Computer, Inc. All Rights Reserved.
- * 
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -54,7 +54,7 @@ SecTrustUserSetting TrustStore::find(Certificate *cert, Policy *policy,
        StorageManager::KeychainList &keychainList)
 {
        StLock<Mutex> _(mMutex);
        StorageManager::KeychainList &keychainList)
 {
        StLock<Mutex> _(mMutex);
-       
+
        if (Item item = findItem(cert, policy, keychainList)) {
                // Make sure that the certificate is available in some keychain,
                // to provide a basis for editing the trust setting that we're returning.
        if (Item item = findItem(cert, policy, keychainList)) {
                // Make sure that the certificate is available in some keychain,
                // to provide a basis for editing the trust setting that we're returning.
@@ -99,7 +99,7 @@ SecTrustUserSetting TrustStore::find(Certificate *cert, Policy *policy,
 void TrustStore::assign(Certificate *cert, Policy *policy, SecTrustUserSetting trust)
 {
        StLock<Mutex> _(mMutex);
 void TrustStore::assign(Certificate *cert, Policy *policy, SecTrustUserSetting trust)
 {
        StLock<Mutex> _(mMutex);
-       
+
        TrustData trustData = { UserTrustItem::currentVersion, trust };
        Keychain defaultKeychain = Keychain::optional(NULL);
        Keychain trustLocation = defaultKeychain;       // default keychain, unless trust entry found
        TrustData trustData = { UserTrustItem::currentVersion, trust };
        Keychain defaultKeychain = Keychain::optional(NULL);
        Keychain trustLocation = defaultKeychain;       // default keychain, unless trust entry found
@@ -162,40 +162,47 @@ void TrustStore::assign(Certificate *cert, Policy *policy, SecTrustUserSetting t
 Item TrustStore::findItem(Certificate *cert, Policy *policy,
        StorageManager::KeychainList &keychainList)
 {
 Item TrustStore::findItem(Certificate *cert, Policy *policy,
        StorageManager::KeychainList &keychainList)
 {
+       // As of OS X 10.5, user trust records are no longer stored in keychains.
+       // SecTrustSetUserTrust was replaced with SecTrustSettingsSetTrustSettings,
+       // which stores per-user trust in a separate root-owned file. This method,
+       // however, would continue to find old trust records created prior to 10.5.
+       // Since those are increasingly unlikely to exist (and cannot be edited),
+       // we no longer need or want to look for them anymore.
+       return ((ItemImpl*)NULL);
+
        StLock<Mutex> _(mMutex);
        StLock<Mutex> _(mMutex);
-       
+
        try {
                SecKeychainAttribute attrs[2];
                CssmAutoData certIndex(Allocator::standard());
                UserTrustItem::makeCertIndex(cert, certIndex);
                attrs[0].tag = kSecTrustCertAttr;
        try {
                SecKeychainAttribute attrs[2];
                CssmAutoData certIndex(Allocator::standard());
                UserTrustItem::makeCertIndex(cert, certIndex);
                attrs[0].tag = kSecTrustCertAttr;
-               attrs[0].length = certIndex.length();
+               attrs[0].length = (UInt32)certIndex.length();
                attrs[0].data = certIndex.data();
                const CssmOid &policyOid = policy->oid();
                attrs[1].tag = kSecTrustPolicyAttr;
                attrs[0].data = certIndex.data();
                const CssmOid &policyOid = policy->oid();
                attrs[1].tag = kSecTrustPolicyAttr;
-               attrs[1].length = policyOid.length();
+               attrs[1].length = (UInt32)policyOid.length();
                attrs[1].data = policyOid.data();
                SecKeychainAttributeList attrList = { 2, attrs };
                KCCursor cursor(keychainList, CSSM_DL_DB_RECORD_USER_TRUST, &attrList);
                Item item;
                if (cursor->next(item))
                        return item;
                attrs[1].data = policyOid.data();
                SecKeychainAttributeList attrList = { 2, attrs };
                KCCursor cursor(keychainList, CSSM_DL_DB_RECORD_USER_TRUST, &attrList);
                Item item;
                if (cursor->next(item))
                        return item;
-               else
-                       return NULL;
-       } catch (const CommonError &error) {
-               return NULL;    // no trust schema, no records, no error
        }
        }
+       catch (const CommonError &error) {}
+
+       return ((ItemImpl*)NULL);       // no trust schema, no records, no error
 }
 
 void TrustStore::getCssmRootCertificates(CertGroup &rootCerts)
 {
        StLock<Mutex> _(mMutex);
 }
 
 void TrustStore::getCssmRootCertificates(CertGroup &rootCerts)
 {
        StLock<Mutex> _(mMutex);
-       
+
        if (!mRootsValid)
                loadRootCertificates();
        rootCerts = CertGroup(CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_BER, CSSM_CERTGROUP_DATA);
        rootCerts.blobCerts() = &mRoots[0];
        if (!mRootsValid)
                loadRootCertificates();
        rootCerts = CertGroup(CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_BER, CSSM_CERTGROUP_DATA);
        rootCerts.blobCerts() = &mRoots[0];
-       rootCerts.count() = mRoots.size();
+       rootCerts.count() = (uint32)mRoots.size();
 }
 
 //
 }
 
 //
@@ -204,11 +211,11 @@ void TrustStore::getCssmRootCertificates(CertGroup &rootCerts)
 void TrustStore::loadRootCertificates()
 {
        StLock<Mutex> _(mMutex);
 void TrustStore::loadRootCertificates()
 {
        StLock<Mutex> _(mMutex);
-       
+
        CFRef<CFArrayRef> anchors;
        OSStatus ortn;
 
        CFRef<CFArrayRef> anchors;
        OSStatus ortn;
 
-       /* 
+       /*
         * Get the current set of all positively trusted anchors.
         */
        ortn = SecTrustSettingsCopyUnrestrictedRoots(
         * Get the current set of all positively trusted anchors.
         */
        ortn = SecTrustSettingsCopyUnrestrictedRoots(
@@ -228,7 +235,7 @@ void TrustStore::loadRootCertificates()
                crtn = SecCertificateGetData(certRef, &certData);
                if(crtn) {
                        CssmError::throwMe(crtn);
                crtn = SecCertificateGetData(certRef, &certData);
                if(crtn) {
                        CssmError::throwMe(crtn);
-               }       
+               }
                size += certData.Length;
        }
        mRootBytes.length(size);
                size += certData.Length;
        }
        mRootBytes.length(size);
index b4603feda84a980181ccf930c26bc2b2bd7dcc2a..6d91146ae238fcd7c583ca7b8028772f77a2bad2 100644 (file)
@@ -1,15 +1,15 @@
 /*
  * Copyright (c) 2002-2004 Apple Computer, Inc. All Rights Reserved.
 /*
  * Copyright (c) 2002-2004 Apple Computer, Inc. All Rights Reserved.
- * 
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -65,7 +65,7 @@ TrustedApplication::TrustedApplication(const std::string &path)
 
 
 //
 
 
 //
-// Create a TrustedAppliation for the calling process
+// Create a TrustedApplication for the calling process
 //
 TrustedApplication::TrustedApplication()
 {
 //
 TrustedApplication::TrustedApplication()
 {
@@ -94,7 +94,7 @@ TrustedApplication::TrustedApplication(const std::string &path, SecRequirementRe
 }
 
 
 }
 
 
-TrustedApplication::~TrustedApplication() 
+TrustedApplication::~TrustedApplication()
 { /* virtual */ }
 
 
 { /* virtual */ }
 
 
@@ -127,6 +127,13 @@ CFDataRef TrustedApplication::externalForm() const
        return data.yield();
 }
 
        return data.yield();
 }
 
+void TrustedApplication::data(CFDataRef data)
+{
+       const char *p = (const char *)CFDataGetBytePtr(data);
+       const std::string path(p, p + CFDataGetLength(data));
+       RefPointer<OSXCode> code(OSXCode::at(path));
+       mForm = new CodeSignatureAclSubject(OSXVerifier(code));
+}
 
 //
 // Direct verification interface.
 
 //
 // Direct verification interface.
@@ -142,7 +149,7 @@ bool TrustedApplication::verifyToDisk(const char *path)
                                kSecCSDefaultFlags, &ondisk.aref()));
                else
                        MacOSError::check(SecCodeCopySelf(kSecCSDefaultFlags, (SecCodeRef *)&ondisk.aref()));
                                kSecCSDefaultFlags, &ondisk.aref()));
                else
                        MacOSError::check(SecCodeCopySelf(kSecCSDefaultFlags, (SecCodeRef *)&ondisk.aref()));
-               return SecStaticCodeCheckValidity(ondisk, kSecCSDefaultFlags, requirement) == noErr;
+               return SecStaticCodeCheckValidity(ondisk, kSecCSDefaultFlags, requirement) == errSecSuccess;
        } else {
                secdebug("trustedapp", "%p validating hash against path %s", this, path);
                RefPointer<OSXCode> code = path ? OSXCode::at(path) : OSXCode::main();
        } else {
                secdebug("trustedapp", "%p validating hash against path %s", this, path);
                RefPointer<OSXCode> code = path ? OSXCode::at(path) : OSXCode::main();
index efdaf5d8681cbb56d7e6d13015264170b85eb76b..70073d3c99e4915ba64b5acc15b771a407c0bc08 100644 (file)
@@ -1,15 +1,15 @@
 /*
  * Copyright (c) 2002-2004 Apple Computer, Inc. All Rights Reserved.
 /*
  * Copyright (c) 2002-2004 Apple Computer, Inc. All Rights Reserved.
- * 
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -61,9 +61,10 @@ public:
        const char *path() const { return mForm->path().c_str(); }
        CssmData legacyHash() const     { return CssmData::wrap(mForm->legacyHash(), SHA1::digestLength); }
        SecRequirementRef requirement() const { return mForm->requirement(); }
        const char *path() const { return mForm->path().c_str(); }
        CssmData legacyHash() const     { return CssmData::wrap(mForm->legacyHash(), SHA1::digestLength); }
        SecRequirementRef requirement() const { return mForm->requirement(); }
-       
+
+       void data(CFDataRef data);
        CFDataRef externalForm() const;
        CFDataRef externalForm() const;
-       
+
        CssmList makeSubject(Allocator &allocator);
 
        bool verifyToDisk(const char *path);            // verify against on-disk image
        CssmList makeSubject(Allocator &allocator);
 
        bool verifyToDisk(const char *path);            // verify against on-disk image
@@ -86,7 +87,7 @@ public:
 private:
     bool mQualifyAll;
     set<std::string> mPaths;
 private:
     bool mQualifyAll;
     set<std::string> mPaths;
-       
+
        bool lookup(const std::string &path);
 };
 
        bool lookup(const std::string &path);
 };
 
index 1e05dfb057c01e35a6f95ae87c33041c500eedfe..54aa8447727ca62271d1d75764078bb6a28a07fa 100644 (file)
 #include <string.h>
 #include <stdio.h>
 #include <security_utilities/errors.h>
 #include <string.h>
 #include <stdio.h>
 #include <security_utilities/errors.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 #include <CoreFoundation/CFDate.h>
 #include <CoreFoundation/CFTimeZone.h>
 #include <ctype.h>
 #include <stdlib.h>
 #include <CoreFoundation/CFDate.h>
 #include <CoreFoundation/CFTimeZone.h>
 #include <ctype.h>
 #include <stdlib.h>
-
+#include <SecBase.h>
 namespace Security
 {
 
 namespace Security
 {
 
@@ -79,7 +78,7 @@ void
 TimeStringToMacLongDateTime (const CSSM_DATA &inUTCTime, sint64 &outMacDate)
 {
        char            szTemp[5];
 TimeStringToMacLongDateTime (const CSSM_DATA &inUTCTime, sint64 &outMacDate)
 {
        char            szTemp[5];
-       unsigned        len;
+       size_t          len;
        int             isUtc;
        sint32          x;
        sint32          i;
        int             isUtc;
        sint32          x;
        sint32          i;
@@ -90,7 +89,7 @@ TimeStringToMacLongDateTime (const CSSM_DATA &inUTCTime, sint64 &outMacDate)
 
        if ((inUTCTime.Data == NULL) || (inUTCTime.Length == 0))
     {
 
        if ((inUTCTime.Data == NULL) || (inUTCTime.Length == 0))
     {
-       MacOSError::throwMe(paramErr);
+       MacOSError::throwMe(errSecParam);
        }
 
        /* tolerate NULL terminated or not */
        }
 
        /* tolerate NULL terminated or not */
@@ -107,7 +106,7 @@ TimeStringToMacLongDateTime (const CSSM_DATA &inUTCTime, sint64 &outMacDate)
                        isUtc = 0;
                        break;
                default:                                                // unknown format 
                        isUtc = 0;
                        break;
                default:                                                // unknown format 
-            MacOSError::throwMe(paramErr);
+            MacOSError::throwMe(errSecParam);
        }
 
        cp = (char *)inUTCTime.Data;
        }
 
        cp = (char *)inUTCTime.Data;
@@ -115,13 +114,13 @@ TimeStringToMacLongDateTime (const CSSM_DATA &inUTCTime, sint64 &outMacDate)
        /* check that all characters except last are digits */
     for(i=0; i<(sint32)(len - 1); i++) {
                if ( !(isdigit(cp[i])) ) {
        /* check that all characters except last are digits */
     for(i=0; i<(sint32)(len - 1); i++) {
                if ( !(isdigit(cp[i])) ) {
-            MacOSError::throwMe(paramErr);
+            MacOSError::throwMe(errSecParam);
                }
        }
 
        /* check last character is a 'Z' */
        if(cp[len - 1] != 'Z' ) {
                }
        }
 
        /* check last character is a 'Z' */
        if(cp[len - 1] != 'Z' ) {
-        MacOSError::throwMe(paramErr);
+        MacOSError::throwMe(errSecParam);
        }
 
        /* YEAR */
        }
 
        /* YEAR */
@@ -148,7 +147,7 @@ TimeStringToMacLongDateTime (const CSSM_DATA &inUTCTime, sint64 &outMacDate)
                        x += 100;
                }
                else if(x < 70) {
                        x += 100;
                }
                else if(x < 70) {
-            MacOSError::throwMe(paramErr);
+            MacOSError::throwMe(errSecParam);
                }
                /* else century 20, OK */
 
                }
                /* else century 20, OK */
 
@@ -166,7 +165,7 @@ TimeStringToMacLongDateTime (const CSSM_DATA &inUTCTime, sint64 &outMacDate)
        x = atoi( szTemp );
        /* in the string, months are from 1 to 12 */
        if((x > 12) || (x <= 0)) {
        x = atoi( szTemp );
        /* in the string, months are from 1 to 12 */
        if((x > 12) || (x <= 0)) {
-        MacOSError::throwMe(paramErr);
+        MacOSError::throwMe(errSecParam);
        }
        /* in a tm, 0 to 11 */
        //tmp->tm_mon = x - 1;
        }
        /* in a tm, 0 to 11 */
        //tmp->tm_mon = x - 1;
@@ -179,7 +178,7 @@ TimeStringToMacLongDateTime (const CSSM_DATA &inUTCTime, sint64 &outMacDate)
        x = atoi( szTemp );
        /* 1..31 in both formats */
        if((x > 31) || (x <= 0)) {
        x = atoi( szTemp );
        /* 1..31 in both formats */
        if((x > 31) || (x <= 0)) {
-        MacOSError::throwMe(paramErr);
+        MacOSError::throwMe(errSecParam);
        }
        //tmp->tm_mday = x;
        date.day = x;
        }
        //tmp->tm_mday = x;
        date.day = x;
@@ -190,7 +189,7 @@ TimeStringToMacLongDateTime (const CSSM_DATA &inUTCTime, sint64 &outMacDate)
        szTemp[2] = '\0';
        x = atoi( szTemp );
        if((x > 23) || (x < 0)) {
        szTemp[2] = '\0';
        x = atoi( szTemp );
        if((x > 23) || (x < 0)) {
-        MacOSError::throwMe(paramErr);
+        MacOSError::throwMe(errSecParam);
        }
        //tmp->tm_hour = x;
        date.hour = x;
        }
        //tmp->tm_hour = x;
        date.hour = x;
@@ -201,7 +200,7 @@ TimeStringToMacLongDateTime (const CSSM_DATA &inUTCTime, sint64 &outMacDate)
        szTemp[2] = '\0';
        x = atoi( szTemp );
        if((x > 59) || (x < 0)) {
        szTemp[2] = '\0';
        x = atoi( szTemp );
        if((x > 59) || (x < 0)) {
-        MacOSError::throwMe(paramErr);
+        MacOSError::throwMe(errSecParam);
        }
        //tmp->tm_min = x;
        date.minute = x;
        }
        //tmp->tm_min = x;
        date.minute = x;
@@ -212,7 +211,7 @@ TimeStringToMacLongDateTime (const CSSM_DATA &inUTCTime, sint64 &outMacDate)
        szTemp[2] = '\0';
        x = atoi( szTemp );
        if((x > 59) || (x < 0)) {
        szTemp[2] = '\0';
        x = atoi( szTemp );
        if((x > 59) || (x < 0)) {
-        MacOSError::throwMe(paramErr);
+        MacOSError::throwMe(errSecParam);
        }
        //tmp->tm_sec = x;
        date.second = x;
        }
        //tmp->tm_sec = x;
        date.second = x;
@@ -265,7 +264,7 @@ void MacLongDateTimeToTimeString(const sint64 &inMacDate,
                 date.hour, date.minute, int(date.second));
     }
     else
                 date.hour, date.minute, int(date.second));
     }
     else
-        MacOSError::throwMe(paramErr);
+        MacOSError::throwMe(errSecParam);
 }
 
 void
 }
 
 void
@@ -301,7 +300,8 @@ CssmDateStringToCFDate(const char *cssmDate, unsigned int len, CFDateRef *outCFD
        CFGregorianDate gd;
        CFTimeInterval ti=0;
        char szTemp[5];
        CFGregorianDate gd;
        CFTimeInterval ti=0;
        char szTemp[5];
-       unsigned isUtc=0, isLocal=0, x, i;
+       unsigned isUtc=0, isLocal=0, i;
+        int x;
        unsigned noSeconds=0;
        char *cp;
 
        unsigned noSeconds=0;
        char *cp;
 
diff --git a/libsecurity_keychain/lib/debuggingP.c b/libsecurity_keychain/lib/debuggingP.c
deleted file mode 100644 (file)
index 34ca70d..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (c) 2006-2010 Apple Inc. All Rights Reserved.
- * 
- * @APPLE_LICENSE_HEADER_START@
- * 
- * 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 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-
-
-/* 
- * debugging.c - non-trivial debug support
- */
-#include <security_utilities/debugging.h>
-#include <CoreFoundation/CFSet.h>
-#include <CoreFoundation/CFString.h>
-
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <pthread.h>
-#include <asl.h>
-
-#if !defined(NDEBUG)
-#define MAX_SCOPE_LENGTH  12
-
-static CFStringRef copyScopeName(const char *scope, CFIndex scopeLen) {
-       if (scopeLen > MAX_SCOPE_LENGTH)
-               scopeLen = MAX_SCOPE_LENGTH - 1;
-       return CFStringCreateWithBytes(kCFAllocatorDefault, (const UInt8 *)scope,
-               scopeLen, kCFStringEncodingUTF8, false);
-}
-
-pthread_once_t __security_debug_once = PTHREAD_ONCE_INIT;
-static const char *gDebugScope;
-static CFMutableSetRef scopeSet;
-static bool negate = false;
-
-static void __security_debug_init(void) {
-       const char *cur_scope = gDebugScope = getenv("DEBUGSCOPE");
-       if (cur_scope) {
-               if (!strcmp(cur_scope, "all")) {
-                       scopeSet = NULL;
-                       negate = true;
-               } else if (!strcmp(cur_scope, "none")) {
-                       scopeSet = NULL;
-                       negate = false;
-               } else {
-                       scopeSet = CFSetCreateMutable(kCFAllocatorDefault, 0,
-                               &kCFTypeSetCallBacks);
-                       if (cur_scope[0] == '-') {
-                               negate = true;
-                               cur_scope++;
-                       } else {
-                               negate = false;
-                       }
-
-                       const char *sep;
-                       while ((sep = strchr(cur_scope, ','))) {
-                               CFStringRef scopeName = copyScopeName(cur_scope,
-                                       sep - cur_scope);
-                               CFSetAddValue(scopeSet, scopeName);
-                               CFRelease(scopeName);
-                               cur_scope = sep + 1;
-                       }
-
-                       CFStringRef scopeName = copyScopeName(cur_scope,
-                               strlen(cur_scope));
-                       CFSetAddValue(scopeSet, scopeName);
-                       CFRelease(scopeName);
-               }
-       } else {
-               scopeSet = NULL;
-               negate = false;
-       }
-}
-
-#endif
-
-void __security_debug(const char *scope, const char *function,
-    const char *file, int line, const char *format, ...)
-{
-#if !defined(NDEBUG)
-       pthread_once(&__security_debug_once, __security_debug_init);
-
-       CFStringRef scopeName = NULL;
-       /* Scope NULL is always enabled. */
-       if (scope) {
-               /* Check if the scope is enabled. */
-               if (scopeSet) {
-                       scopeName = copyScopeName(scope, strlen(scope));
-                       if (negate == CFSetContainsValue(scopeSet, scopeName)) {
-                               CFRelease(scopeName);
-                               return;
-                       }
-               } else if (!negate) {
-                       return;
-               }
-       }
-
-       CFStringRef formatStr = CFStringCreateWithCString(kCFAllocatorDefault,
-               format, kCFStringEncodingUTF8);
-       va_list args;
-       va_start(args, format);
-       CFStringRef message = CFStringCreateWithFormatAndArguments(
-               kCFAllocatorDefault, NULL, formatStr, args);
-       va_end(args);
-       time_t now = time(NULL);
-       char *date = ctime(&now);
-       date[19] = '\0';
-       CFStringRef logStr = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
-               CFSTR("%s %-*s %s %@\n"), date + 4, MAX_SCOPE_LENGTH - 1,
-        scope ? scope : "", function, message);
-       CFShow(logStr);
-    char logMsg[4096];
-    if (CFStringGetCString(logStr, logMsg, sizeof(logMsg), kCFStringEncodingUTF8)) {
-#if 0
-        asl_log(NULL, NULL, ASL_LEVEL_INFO, logMsg);
-#else
-        aslmsg msg = asl_new(ASL_TYPE_MSG);
-        if (scope) {
-            asl_set(msg, ASL_KEY_FACILITY, scope);
-        }
-        asl_set(msg, ASL_KEY_LEVEL, ASL_STRING_INFO);
-        asl_set(msg, ASL_KEY_MSG, logMsg);
-        asl_send(NULL, msg);
-        asl_free(msg);
-#endif
-    }
-       CFRelease(logStr);
-       CFRelease(message);
-       CFRelease(formatStr);
-       if (scopeName)
-               CFRelease(scopeName);
-#endif
-}
diff --git a/libsecurity_keychain/lib/debuggingP.h b/libsecurity_keychain/lib/debuggingP.h
deleted file mode 100644 (file)
index 7dcd55a..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2006-2007,2009-2010 Apple Inc. All Rights Reserved.
- * 
- * @APPLE_LICENSE_HEADER_START@
- * 
- * 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 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/* 
- * debugging.h - non-trivial debug support
- */
-#ifndef _SECURITY_UTILITIES_DEBUGGING_H_
-#define _SECURITY_UTILITIES_DEBUGGING_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern void __security_debug(const char *scope, const char *function,
-    const char *file, int line, const char *format, ...);
-
-#if !defined(NDEBUG)
-# define secdebug(scope,...)   __security_debug(scope, __FUNCTION__, \
-    __FILE__, __LINE__, __VA_ARGS__)
-#else
-# define secdebug(scope, format...)    /* nothing */
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SECURITY_UTILITIES_DEBUGGING_H_ */
index d1490c938b10eacf6f1e55144939aa3cdd871a81..02cb5131b40c6cb9b42b3e39320d301f41b923c6 100644 (file)
@@ -130,7 +130,7 @@ bool DefaultCredentials::unlockKey(const UnlockReferralRecord &ref, const Keycha
        try {
                // form the query
                SecKeychainAttribute attributes[1] = {
        try {
                // form the query
                SecKeychainAttribute attributes[1] = {
-                       { kSecKeyLabel, ref.keyLabel().length(), ref.keyLabel().data() }
+                       { kSecKeyLabel, (UInt32)ref.keyLabel().length(), ref.keyLabel().data() }
                };
                SecKeychainAttributeList search = { 1, attributes };
                CSSM_DB_RECORDTYPE recordType =
                };
                SecKeychainAttributeList search = { 1, attributes };
                CSSM_DB_RECORDTYPE recordType =
index cad9839710d2faac396ccf7147b660ecc408d040..9658bb6c5a1f1e346b79e63b4a9611faeb0b9672 100644 (file)
@@ -1,15 +1,15 @@
 #
 #
-# Copyright (c) 2003-2010 Apple Inc. All Rights Reserved.
+# Copyright (c) 2003-2013 Apple Inc. All Rights Reserved.
 #
 # @APPLE_LICENSE_HEADER_START@
 #
 # @APPLE_LICENSE_HEADER_START@
-# 
+#
 # 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 2.0 (the 'License'). You may not use this file except in
 # compliance with the License. Please obtain a copy of the License at
 # http://www.opensource.apple.com/apsl/ and read it before using this
 # file.
 # 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 2.0 (the 'License'). You may not use this file except in
 # compliance with the License. Please obtain a copy of the License at
 # http://www.opensource.apple.com/apsl/ 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,
 # 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,
@@ -17,7 +17,7 @@
 # FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 # Please see the License for the specific language governing rights and
 # limitations under the License.
 # FITNESS 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_LICENSE_HEADER_END@
 #
 _cssmErrorString
 # @APPLE_LICENSE_HEADER_END@
 #
 _cssmErrorString
@@ -201,9 +201,13 @@ _kSecPolicyAppleCodeSigning
 _kSecPolicyMacAppStoreReceipt
 _kSecPolicyAppleIDValidation
 _kSecPolicyAppleTimeStamping
 _kSecPolicyMacAppStoreReceipt
 _kSecPolicyAppleIDValidation
 _kSecPolicyAppleTimeStamping
+_kSecPolicyAppleRevocation
+_kSecPolicyApplePassbookSigning
 _kSecPolicyOid
 _kSecPolicyName
 _kSecPolicyClient
 _kSecPolicyOid
 _kSecPolicyName
 _kSecPolicyClient
+_kSecPolicyRevocationFlags
+_kSecPolicyTeamIdentifier
 _kSecPolicyKU_DigitalSignature
 _kSecPolicyKU_NonRepudiation
 _kSecPolicyKU_KeyEncipherment
 _kSecPolicyKU_DigitalSignature
 _kSecPolicyKU_NonRepudiation
 _kSecPolicyKU_KeyEncipherment
@@ -344,6 +348,13 @@ _kSecOIDX509V3SignedCertificate
 _kSecOIDX509V3SignedCertificateCStruct
 _kSecOIDSRVName
 _kSecRandomDefault
 _kSecOIDX509V3SignedCertificateCStruct
 _kSecOIDSRVName
 _kSecRandomDefault
+_kSecTrustEvaluationDate
+_kSecTrustExtendedValidation
+_kSecTrustOrganizationName
+_kSecTrustResultDetails
+_kSecTrustResultValue
+_kSecTrustRevocationChecked
+_kSecTrustRevocationValidUntilDate
 _SecACLCopySimpleContents
 _SecACLCreateFromSimpleContents
 _SecACLCreateWithSimpleContents
 _SecACLCopySimpleContents
 _SecACLCreateFromSimpleContents
 _SecACLCreateWithSimpleContents
@@ -394,6 +405,7 @@ _SecCertificateGetData
 _SecCertificateGetEmailAddress
 _SecCertificateGetIssuer
 _SecCertificateGetLength
 _SecCertificateGetEmailAddress
 _SecCertificateGetIssuer
 _SecCertificateGetLength
+_SecCertificateGetSHA1Digest
 _SecCertificateGetSubject
 _SecCertificateGetType
 _SecCertificateGetTypeID
 _SecCertificateGetSubject
 _SecCertificateGetType
 _SecCertificateGetTypeID
@@ -451,6 +463,7 @@ _kSecAttrKeyTypeRC4
 _kSecAttrKeyTypeRC2
 _kSecAttrKeyTypeCAST
 _kSecAttrKeyTypeECDSA
 _kSecAttrKeyTypeRC2
 _kSecAttrKeyTypeCAST
 _kSecAttrKeyTypeECDSA
+_kSecAttrKeyTypeEC
 _kSecAttrPRF
 _kSecAttrPRFHmacAlgSHA1
 _kSecAttrPRFHmacAlgSHA224
 _kSecAttrPRF
 _kSecAttrPRFHmacAlgSHA1
 _kSecAttrPRFHmacAlgSHA224
@@ -596,8 +609,10 @@ _SecPasswordSetInitialAccess
 _SecPasswordAction
 _SecPKCS12Import
 _SecPolicyCreateBasicX509
 _SecPasswordAction
 _SecPKCS12Import
 _SecPolicyCreateBasicX509
+_SecPolicyCreateRevocation
 _SecPolicyCreateSSL
 _SecPolicyCreateWithOID
 _SecPolicyCreateSSL
 _SecPolicyCreateWithOID
+_SecPolicyCreateWithProperties
 _SecPolicyGetOID
 _SecPolicyGetTPHandle
 _SecPolicyGetTypeID
 _SecPolicyGetOID
 _SecPolicyGetTPHandle
 _SecPolicyGetTypeID
@@ -612,10 +627,12 @@ _SecPolicyCopyProperties
 _SecPolicySetProperties
 _SecTrustCopyAnchorCertificates
 _SecTrustCopyCustomAnchorCertificates
 _SecPolicySetProperties
 _SecTrustCopyAnchorCertificates
 _SecTrustCopyCustomAnchorCertificates
+_SecTrustCopyExceptions
 _SecTrustCopyExtendedResult
 _SecTrustCopyPolicies
 _SecTrustCopyProperties
 _SecTrustCopyPublicKey
 _SecTrustCopyExtendedResult
 _SecTrustCopyPolicies
 _SecTrustCopyProperties
 _SecTrustCopyPublicKey
+_SecTrustCopyResult
 _SecTrustCreateWithCertificates
 _SecTrustEvaluate
 _SecTrustEvaluateAsync
 _SecTrustCreateWithCertificates
 _SecTrustEvaluate
 _SecTrustEvaluateAsync
@@ -624,16 +641,19 @@ _SecTrustGetCertificateCount
 _SecTrustGetCSSMAnchorCertificates
 _SecTrustGetCssmResult
 _SecTrustGetCssmResultCode
 _SecTrustGetCSSMAnchorCertificates
 _SecTrustGetCssmResult
 _SecTrustGetCssmResultCode
+_SecTrustGetNetworkFetchAllowed
 _SecTrustGetResult
 _SecTrustGetTrustResult
 _SecTrustGetTPHandle
 _SecTrustGetTypeID
 _SecTrustGetUserTrust
 _SecTrustGetVerifyTime
 _SecTrustGetResult
 _SecTrustGetTrustResult
 _SecTrustGetTPHandle
 _SecTrustGetTypeID
 _SecTrustGetUserTrust
 _SecTrustGetVerifyTime
-_SecTrustKeychainsGetMutex
 _SecTrustSetAnchorCertificates
 _SecTrustSetAnchorCertificatesOnly
 _SecTrustSetAnchorCertificates
 _SecTrustSetAnchorCertificatesOnly
+_SecTrustSetExceptions
 _SecTrustSetKeychains
 _SecTrustSetKeychains
+_SecTrustSetNetworkFetchAllowed
+_SecTrustSetOCSPResponse
 _SecTrustSetOptions
 _SecTrustSetParameters
 _SecTrustSetPolicies
 _SecTrustSetOptions
 _SecTrustSetParameters
 _SecTrustSetPolicies
index 1e170bffe7fdbe1d3c9f99c1f308413477365c3e..2171d75d0d9d85ae465720e9f570a211909ecf3b 100644 (file)
@@ -6,3 +6,9 @@ VERSIONING_SYSTEM = apple-generic;
 DEAD_CODE_STRIPPING = YES;
 
 ARCHS = $(ARCHS_STANDARD_32_64_BIT)
 DEAD_CODE_STRIPPING = YES;
 
 ARCHS = $(ARCHS_STANDARD_32_64_BIT)
+
+// Debug symbols should be on obviously
+GCC_GENERATE_DEBUGGING_SYMBOLS = YES
+COPY_PHASE_STRIP = NO
+STRIP_STYLE = debugging
+STRIP_INSTALLED_PRODUCT = NO
index 937d177552d7c32bc7eea9753d7d6523f1f0ea72..47555cf5ce157140e769b2e16f93723b761e7281 100644 (file)
@@ -1,3 +1,2 @@
 GCC_OPTIMIZATION_LEVEL = 0
 GCC_PREPROCESSOR_DEFINITIONS = DEBUG=1 $(inherited)
 GCC_OPTIMIZATION_LEVEL = 0
 GCC_PREPROCESSOR_DEFINITIONS = DEBUG=1 $(inherited)
-COPY_PHASE_STRIP = NO
index c847a544503286a75e001cb0d428dd5bb87f9da2..18b501cb010d97200d059028540570d74464e953 100644 (file)
@@ -17,7 +17,9 @@ ALWAYS_SEARCH_USER_PATHS = NO
 
 GCC_C_LANGUAGE_STANDARD = gnu99
 
 
 GCC_C_LANGUAGE_STANDARD = gnu99
 
-WARNING_CFLAGS = -Wmost -Wno-four-char-constants -Wno-unknown-pragmas $(inherited)
+GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+
+WARNING_CFLAGS = -Wno-error=#warnings -Wmost -Wno-four-char-constants -Wno-unknown-pragmas $(inherited)
 
 GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO
 
 
 GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO
 
index 3110dcb5b93f17bd64177e01d5adf4243c5562ae..088ded92a81006819c31d49f1dc81025b210663d 100644 (file)
@@ -1,2 +1,2 @@
+GCC_OPTIMIZATION_LEVEL = s
 GCC_PREPROCESSOR_DEFINITIONS = NDEBUG=1 $(inherited)
 GCC_PREPROCESSOR_DEFINITIONS = NDEBUG=1 $(inherited)
-COPY_PHASE_STRIP = YES
index 1fdf11690549bd9e8525e22018a476cc8b54237d..bcffddc3788cb633d93f51fe85e186f09eff998f 100644 (file)
                053BA30A091C00A400A7007A /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
                053BA30A091C00A400A7007A /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0430;
+                               LastUpgradeCheck = 0500;
                        };
                        buildConfigurationList = 4CD81A7109BE1FD2000A9641 /* Build configuration list for PBXProject "libDER" */;
                        compatibilityVersion = "Xcode 3.2";
                        };
                        buildConfigurationList = 4CD81A7109BE1FD2000A9641 /* Build configuration list for PBXProject "libDER" */;
                        compatibilityVersion = "Xcode 3.2";
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1828EAA114E334E200BE00C2 /* debug.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1828EAA114E334E200BE00C2 /* debug.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1828EAA314E334E200BE00C2 /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1828EAA314E334E200BE00C2 /* release.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1828EAA114E334E200BE00C2 /* debug.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1828EAA114E334E200BE00C2 /* debug.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1828EAA314E334E200BE00C2 /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1828EAA314E334E200BE00C2 /* release.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1828EAA114E334E200BE00C2 /* debug.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1828EAA114E334E200BE00C2 /* debug.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1828EAA314E334E200BE00C2 /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1828EAA314E334E200BE00C2 /* release.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1828EAA214E334E200BE00C2 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1828EAA214E334E200BE00C2 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1828EAA214E334E200BE00C2 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1828EAA214E334E200BE00C2 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
index c22fe9859e55bc106b05bd02900152922312298b..819c97c4f2548f419abf352a7517ce001cc944de 100644 (file)
@@ -390,8 +390,11 @@ DERReturn DERParseSequenceContent(
                                
                                /* is this the end? */
                                if(itemDex == numItems) {
                                
                                /* is this the end? */
                                if(itemDex == numItems) {
-                                       /* normal termination */
-                                       return DR_Success;
+                                       /* normal termination if we consumed everything */
+                                       if (currDecoded.content.data + currDecoded.content.length == content->data + content->length)
+                                               return DR_Success;
+                                       else
+                                               return DR_DecodeError;
                                }
                                else {
                                        /* on to next item */ 
                                }
                                else {
                                        /* on to next item */ 
index 14c99ddd95e14653dd6454f5a53ba0bb9fae0cca..8f4077196259f0e2e37be0fe01ed1223f3fce87e 100644 (file)
  */
 #define APPLE_EKU_CODE_SIGNING                 APPLE_EKU_OID, 1
 #define APPLE_EKU_APPLE_ID              APPLE_EKU_OID, 7
  */
 #define APPLE_EKU_CODE_SIGNING                 APPLE_EKU_OID, 1
 #define APPLE_EKU_APPLE_ID              APPLE_EKU_OID, 7
+#define APPLE_EKU_SHOEBOX               APPLE_EKU_OID, 14
+#define APPLE_EKU_PROFILE_SIGNING       APPLE_EKU_OID, 16
+#define APPLE_EKU_QA_PROFILE_SIGNING    APPLE_EKU_OID, 17
+
 
 /*
 
 /*
- * Basis of Apple-specific Certific Policy IDs.
+ * Basis of Apple-specific Certificate Policy IDs.
  * appleCertificatePolicies OBJECT IDENTIFIER ::= 
  *             { appleDataSecurity 5 }
  *             { 1 2 840 113635 100 5 }
  */
 #define APPLE_CERT_POLICIES                            APPLE_ADS_OID, 5
 
  * appleCertificatePolicies OBJECT IDENTIFIER ::= 
  *             { appleDataSecurity 5 }
  *             { 1 2 840 113635 100 5 }
  */
 #define APPLE_CERT_POLICIES                            APPLE_ADS_OID, 5
 
+#define APPLE_CERT_POLICY_MOBILE_STORE APPLE_CERT_POLICIES, 12
+
+#define APPLE_CERT_POLICY_TEST_MOBILE_STORE APPLE_CERT_POLICY_MOBILE_STORE, 1
+
 /*
  * Basis of Apple-specific Signing extensions
  *             { appleDataSecurity 6 }
 /*
  * Basis of Apple-specific Signing extensions
  *             { appleDataSecurity 6 }
  */
 #define APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID_2 APPLE_CERT_EXT_INTERMEDIATE_MARKER, 7
 
  */
 #define APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID_2 APPLE_CERT_EXT_INTERMEDIATE_MARKER, 7
 
+#define APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID_SYSTEM_INTEGRATION_2 APPLE_CERT_EXT_INTERMEDIATE_MARKER, 10
+
+#define APPLE_CERT_EXT_APPLE_PUSH_MARKER    APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID, 2
+
+
+#define APPLE_CERT_EXTENSION_CODESIGNING        APPLE_CERT_EXT, 1
 
 /* Secure Boot Embedded Image3 value,
    co-opted by desktop for "Apple Released Code Signature", without value */
 
 /* Secure Boot Embedded Image3 value,
    co-opted by desktop for "Apple Released Code Signature", without value */
-#define APPLE_SBOOT_CERT_EXTEN_SBOOT_SPEC_OID  APPLE_ADS_OID, 6, 1, 1
-/* iPhone Provisioning Profile Signing leaf */
-#define APPLE_PROVISIONING_PROFILE_OID APPLE_ADS_OID, 6, 2, 2, 1
+#define APPLE_SBOOT_CERT_EXTEN_SBOOT_SPEC_OID  APPLE_CERT_EXTENSION_CODESIGNING, 1
+/* iPhone Provisioning Profile Signing leaf - on the intermediate marker arc? */
+#define APPLE_PROVISIONING_PROFILE_OID APPLE_CERT_EXT_INTERMEDIATE_MARKER, 1
 /* iPhone Application Signing leaf */
 /* iPhone Application Signing leaf */
-#define APPLE_APP_SIGINING_OID APPLE_ADS_OID, 6, 1, 3
+#define APPLE_APP_SIGINING_OID          APPLE_CERT_EXTENSION_CODESIGNING, 3
+/* Shoebox card signing leaf */
+#define APPLE_INSTALLER_PACKAGE_SIGNING_EXTERNAL_OID       APPLE_CERT_EXTENSION_CODESIGNING, 16
+
+#define APPLE_ESCROW_ARC APPLE_CERT_EXT, 23
+
+#define APPLE_ESCROW_POLICY_OID APPLE_ESCROW_ARC, 1
+
+#define APPLE_CERT_EXTENSTION_APPLE_ID_VALIDATION_RECORD_SIGNING       APPLE_CERT_EXT, 25
 
 /*
  * Netscape OIDs.
 
 /*
  * Netscape OIDs.
@@ -359,9 +381,19 @@ static const DERByte
     _oidAppleSecureBootCertSpec[]   = { APPLE_SBOOT_CERT_EXTEN_SBOOT_SPEC_OID },
     _oidAppleProvisioningProfile[]  = {APPLE_PROVISIONING_PROFILE_OID },
     _oidAppleApplicationSigning[]   = { APPLE_APP_SIGINING_OID },
     _oidAppleSecureBootCertSpec[]   = { APPLE_SBOOT_CERT_EXTEN_SBOOT_SPEC_OID },
     _oidAppleProvisioningProfile[]  = {APPLE_PROVISIONING_PROFILE_OID },
     _oidAppleApplicationSigning[]   = { APPLE_APP_SIGINING_OID },
+    _oidAppleInstallerPackagingSigningExternal[]       = { APPLE_INSTALLER_PACKAGE_SIGNING_EXTERNAL_OID },
     _oidAppleExtendedKeyUsageAppleID[] = { APPLE_EKU_APPLE_ID },
     _oidAppleExtendedKeyUsageAppleID[] = { APPLE_EKU_APPLE_ID },
+    _oidAppleExtendedKeyUsageShoebox[] = { APPLE_EKU_SHOEBOX },
+    _oidAppleExtendedKeyUsageProfileSigning[] = { APPLE_EKU_PROFILE_SIGNING },
+    _oidAppleExtendedKeyUsageQAProfileSigning[] = { APPLE_EKU_QA_PROFILE_SIGNING },
     _oidAppleIntmMarkerAppleID[] = { APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID },
     _oidAppleIntmMarkerAppleID[] = { APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID },
-    _oidAppleIntmMarkerAppleID2[] = {APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID_2 };
+    _oidAppleIntmMarkerAppleID2[] = {APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID_2 },
+    _oidApplePushServiceClient[]   =   { APPLE_CERT_EXT_APPLE_PUSH_MARKER, 2 },
+       _oidApplePolicyMobileStore[]  = { APPLE_CERT_POLICY_MOBILE_STORE },
+       _oidApplePolicyTestMobileStore[] = { APPLE_CERT_POLICY_TEST_MOBILE_STORE },
+       _oidApplePolicyEscrowService[] = { APPLE_ESCROW_POLICY_OID },
+       _oidAppleCertExtensionAppleIDRecordValidationSigning[] = { APPLE_CERT_EXTENSTION_APPLE_ID_VALIDATION_RECORD_SIGNING },
+       _oidAppleIntmMarkerAppleSystemIntg2[] =  {APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID_SYSTEM_INTEGRATION_2};
 
 const DERItem
     oidSubjectKeyIdentifier         = { (DERByte *)_oidSubjectKeyIdentifier,
 
 const DERItem
     oidSubjectKeyIdentifier         = { (DERByte *)_oidSubjectKeyIdentifier,
@@ -455,13 +487,35 @@ const DERItem
     oidAppleProvisioningProfile     = { (DERByte *)_oidAppleProvisioningProfile,
                                         sizeof(_oidAppleProvisioningProfile) },
     oidAppleApplicationSigning      = { (DERByte *)_oidAppleApplicationSigning,
     oidAppleProvisioningProfile     = { (DERByte *)_oidAppleProvisioningProfile,
                                         sizeof(_oidAppleProvisioningProfile) },
     oidAppleApplicationSigning      = { (DERByte *)_oidAppleApplicationSigning,
-                                        sizeof(_oidAppleApplicationSigning) },
+                                         sizeof(_oidAppleApplicationSigning) },
+    oidAppleInstallerPackagingSigningExternal          = { (DERByte *)_oidAppleInstallerPackagingSigningExternal,
+                                                            sizeof(_oidAppleInstallerPackagingSigningExternal) },
     oidAppleExtendedKeyUsageAppleID = { (DERByte *)_oidAppleExtendedKeyUsageAppleID,
                                         sizeof(_oidAppleExtendedKeyUsageAppleID) },
     oidAppleExtendedKeyUsageAppleID = { (DERByte *)_oidAppleExtendedKeyUsageAppleID,
                                         sizeof(_oidAppleExtendedKeyUsageAppleID) },
+    oidAppleExtendedKeyUsageShoebox = { (DERByte *)_oidAppleExtendedKeyUsageShoebox,
+                                        sizeof(_oidAppleExtendedKeyUsageShoebox) },
+    oidAppleExtendedKeyUsageProfileSigning  
+                                     = { (DERByte *)_oidAppleExtendedKeyUsageProfileSigning,
+                                        sizeof(_oidAppleExtendedKeyUsageProfileSigning) },
+    oidAppleExtendedKeyUsageQAProfileSigning
+                                    = { (DERByte *)_oidAppleExtendedKeyUsageQAProfileSigning,
+                                        sizeof(_oidAppleExtendedKeyUsageQAProfileSigning) },
     oidAppleIntmMarkerAppleID       = { (DERByte *)_oidAppleIntmMarkerAppleID,
                                         sizeof(_oidAppleIntmMarkerAppleID) },
     oidAppleIntmMarkerAppleID2      = { (DERByte *)_oidAppleIntmMarkerAppleID2,
     oidAppleIntmMarkerAppleID       = { (DERByte *)_oidAppleIntmMarkerAppleID,
                                         sizeof(_oidAppleIntmMarkerAppleID) },
     oidAppleIntmMarkerAppleID2      = { (DERByte *)_oidAppleIntmMarkerAppleID2,
-                                        sizeof(_oidAppleIntmMarkerAppleID2) };
+                                        sizeof(_oidAppleIntmMarkerAppleID2) },
+    oidApplePushServiceClient       = { (DERByte *)_oidAppleIntmMarkerAppleID2,
+                                        sizeof(_oidAppleIntmMarkerAppleID2) },
+       oidApplePolicyMobileStore               = { (DERByte *)_oidApplePolicyMobileStore,
+                                                                               sizeof(_oidApplePolicyMobileStore)},
+       oidApplePolicyTestMobileStore   = { (DERByte *)_oidApplePolicyTestMobileStore,
+                                                                               sizeof(_oidApplePolicyTestMobileStore)},
+       oidApplePolicyEscrowService             = { (DERByte *)_oidApplePolicyEscrowService,
+                                                                               sizeof(_oidApplePolicyEscrowService)},
+       oidAppleCertExtensionAppleIDRecordValidationSigning = { (DERByte *)_oidAppleCertExtensionAppleIDRecordValidationSigning,
+                                                                               sizeof(_oidAppleCertExtensionAppleIDRecordValidationSigning)},
+       oidAppleIntmMarkerAppleSystemIntg2 = { (DERByte *) _oidAppleIntmMarkerAppleSystemIntg2,
+                                                                               sizeof(_oidAppleIntmMarkerAppleSystemIntg2)};
 
 
 bool DEROidCompare(const DERItem *oid1, const DERItem *oid2) {
 
 
 bool DEROidCompare(const DERItem *oid1, const DERItem *oid2) {
index 98a75079a9d41f870bef196af05828ce711c486e..e9faf5a61aaa682221b66897a2d8273a2eece435 100644 (file)
@@ -88,9 +88,19 @@ extern const DERItem
        oidAppleSecureBootCertSpec,
     oidAppleProvisioningProfile,
     oidAppleApplicationSigning,
        oidAppleSecureBootCertSpec,
     oidAppleProvisioningProfile,
     oidAppleApplicationSigning,
+    oidAppleInstallerPackagingSigningExternal,
     oidAppleExtendedKeyUsageAppleID,
     oidAppleExtendedKeyUsageAppleID,
+    oidAppleExtendedKeyUsageShoebox,
+    oidAppleExtendedKeyUsageProfileSigning,
+    oidAppleExtendedKeyUsageQAProfileSigning,
     oidAppleIntmMarkerAppleID,
     oidAppleIntmMarkerAppleID,
-    oidAppleIntmMarkerAppleID2;
+    oidAppleIntmMarkerAppleID2,
+    oidApplePushServiceClient,
+       oidApplePolicyMobileStore,
+    oidApplePolicyTestMobileStore,
+       oidApplePolicyEscrowService,
+       oidAppleCertExtensionAppleIDRecordValidationSigning,
+       oidAppleIntmMarkerAppleSystemIntg2;
 
 /* Compare two decoded OIDs.  Returns true iff they are equivalent. */
 bool DEROidCompare(const DERItem *oid1, const DERItem *oid2);
 
 /* Compare two decoded OIDs.  Returns true iff they are equivalent. */
 bool DEROidCompare(const DERItem *oid1, const DERItem *oid2);
index 078df72d1bb9e786d4444a1fc3c1e6341a6677b9..fec82702201cba9488fdc4ad3c7fc9312bf3495c 100644 (file)
@@ -23,7 +23,7 @@ int writeFile(
        if(fd <= 0) {
                return errno;
        }
        if(fd <= 0) {
                return errno;
        }
-       rtn = write(fd, bytes, (size_t)numBytes);
+       rtn = (int)write(fd, bytes, (size_t)numBytes);
        if(rtn != (int)numBytes) {
                if(rtn >= 0) {
                        fprintf(stderr, "writeFile: short write\n");
        if(rtn != (int)numBytes) {
                if(rtn >= 0) {
                        fprintf(stderr, "writeFile: short write\n");
@@ -49,7 +49,7 @@ int readFile(
        int fd;
        char *buf;
        struct stat     sb;
        int fd;
        char *buf;
        struct stat     sb;
-       size_t size;
+       unsigned size;
        
        *numBytes = 0;
        *bytes = NULL;
        
        *numBytes = 0;
        *bytes = NULL;
@@ -61,14 +61,14 @@ int readFile(
        if(rtn) {
                goto errOut;
        }
        if(rtn) {
                goto errOut;
        }
-       size = (size_t) sb.st_size;
+       size = (unsigned) sb.st_size;
        buf = (char *)malloc(size);
        if(buf == NULL) {
                rtn = ENOMEM;
                goto errOut;
        }
        buf = (char *)malloc(size);
        if(buf == NULL) {
                rtn = ENOMEM;
                goto errOut;
        }
-       rtn = read(fd, buf, (size_t)size);
-       if(rtn != (int)size) {
+       rtn = (int)read(fd, buf, size);
+       if(rtn != size) {
                if(rtn >= 0) {
                        fprintf(stderr, "readFile: short read\n");
                }
                if(rtn >= 0) {
                        fprintf(stderr, "readFile: short read\n");
                }
index 34cacfb7fd42eae08c9f75063a9349fa9483fcc0..6269ebb893f7dd52b4c6df3069e2fd0d1886e963 100644 (file)
@@ -17,7 +17,7 @@
 
 static int indentLevel = 0;
 
 
 static int indentLevel = 0;
 
-void doIndent()
+void doIndent(void)
 {
        int i;
        for (i = 0; i<indentLevel; i++) {
 {
        int i;
        for (i = 0; i<indentLevel; i++) {
@@ -25,12 +25,12 @@ void doIndent()
        }
 } /* indent */
 
        }
 } /* indent */
 
-void incrIndent()
+void incrIndent(void)
 {
        indentLevel += 3;
 }
 
 {
        indentLevel += 3;
 }
 
-void decrIndent()
+void decrIndent(void)
 {
        indentLevel -= 3;
 }
 {
        indentLevel -= 3;
 }
@@ -40,10 +40,10 @@ void decrIndent()
 void printHex(
        DERItem *item)
 {
 void printHex(
        DERItem *item)
 {
-       unsigned dex;
-       unsigned toPrint = item->length;
+       unsigned long dex;
+       unsigned long toPrint = item->length;
        
        
-       printf("<%u> ", item->length);
+       printf("<%lu> ", item->length);
        if(toPrint > TO_PRINT_MAX) {
                toPrint = TO_PRINT_MAX;
        }
        if(toPrint > TO_PRINT_MAX) {
                toPrint = TO_PRINT_MAX;
        }
@@ -59,8 +59,8 @@ void printHex(
 void printBitString(
        DERItem *item)
 {
 void printBitString(
        DERItem *item)
 {
-       unsigned dex;
-       unsigned toPrint = item->length;
+       DERSize dex;
+       DERSize toPrint = item->length;
        DERItem bitStringBytes;
        DERByte numUnused;
        DERReturn drtn;
        DERItem bitStringBytes;
        DERByte numUnused;
        DERReturn drtn;
@@ -71,7 +71,7 @@ void printBitString(
                return;
        }
 
                return;
        }
 
-       printf("<%u, %u> ", bitStringBytes.length, numUnused);
+       printf("<%lu, %lu> ", (unsigned long)bitStringBytes.length, (unsigned long)numUnused);
        toPrint = bitStringBytes.length;
        if(toPrint > TO_PRINT_MAX) {
                toPrint = TO_PRINT_MAX;
        toPrint = bitStringBytes.length;
        if(toPrint > TO_PRINT_MAX) {
                toPrint = TO_PRINT_MAX;
@@ -107,14 +107,14 @@ void printString(
 void printHeader(
        const char *label)
 {
 void printHeader(
        const char *label)
 {
-       unsigned numPrinted;
+       size_t numPrinted;
        
        doIndent();
        printf("%s", label);
        numPrinted = indentLevel + strlen(label);
        if(numPrinted < COLON_COLUMN) {
        
        doIndent();
        printf("%s", label);
        numPrinted = indentLevel + strlen(label);
        if(numPrinted < COLON_COLUMN) {
-               unsigned numSpaces = COLON_COLUMN - numPrinted;
-               unsigned dex;
+               size_t numSpaces = COLON_COLUMN - numPrinted;
+               size_t dex;
                for(dex=0; dex<numSpaces; dex++) {
                        putchar(' ');
                }
                for(dex=0; dex<numSpaces; dex++) {
                        putchar(' ');
                }
index b003e8aa44cedb464300d3f46d00e90849464055..9ed0b4a4f59f2a5ef7f435d314896d7187cffa9d 100644 (file)
@@ -15,9 +15,9 @@
 extern "C" {
 #endif
 
 extern "C" {
 #endif
 
-void doIndent();
-void incrIndent();
-void decrIndent();
+void doIndent(void);
+void incrIndent(void);
+void decrIndent(void);
 void printHex(DERItem *item);
 void printBitString(DERItem *item);
 void printString(DERItem *item);
 void printHex(DERItem *item);
 void printBitString(DERItem *item);
 void printString(DERItem *item);
index 84f97c4937f3d1a8b5277fb27e8d1151f389c0b5..2f87ea5371791d6bfc83fd91248ccf00d4051759 100644 (file)
                05AE954A0AA748580076501C /* SecImportExportOpenSSH.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 05AE95480AA748570076501C /* SecImportExportOpenSSH.cpp */; };
                05FB016805E54A3A00A5194C /* SecNetscapeTemplates.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 05FB016605E54A3A00A5194C /* SecNetscapeTemplates.cpp */; };
                05FB016905E54A3A00A5194C /* SecNetscapeTemplates.h in Headers */ = {isa = PBXBuildFile; fileRef = 05FB016705E54A3A00A5194C /* SecNetscapeTemplates.h */; };
                05AE954A0AA748580076501C /* SecImportExportOpenSSH.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 05AE95480AA748570076501C /* SecImportExportOpenSSH.cpp */; };
                05FB016805E54A3A00A5194C /* SecNetscapeTemplates.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 05FB016605E54A3A00A5194C /* SecNetscapeTemplates.cpp */; };
                05FB016905E54A3A00A5194C /* SecNetscapeTemplates.h in Headers */ = {isa = PBXBuildFile; fileRef = 05FB016705E54A3A00A5194C /* SecNetscapeTemplates.h */; };
+               0CBD509A16C3246D00713B6C /* kc-40-seckey.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CBD509816C3246D00713B6C /* kc-40-seckey.c */; };
+               0CBD509B16C3246D00713B6C /* kc-41-sececkey.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CBD509916C3246D00713B6C /* kc-41-sececkey.c */; };
                182BB5CD146FF72B000BF1F3 /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5297A731112CB13800EAA0C0 /* libDER.a */; };
                182BB5CD146FF72B000BF1F3 /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5297A731112CB13800EAA0C0 /* libDER.a */; };
+               188BB546171DD8B5009D22CE /* si-33-keychain-backup.c in Sources */ = {isa = PBXBuildFile; fileRef = 188BB53F171DD774009D22CE /* si-33-keychain-backup.c */; };
                1B11967B062F4C1800F3B659 /* SecKeychainSearchPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 1B11967A062F4C1800F3B659 /* SecKeychainSearchPriv.h */; settings = {ATTRIBUTES = (); }; };
                30E17F5B062B0A25004208EB /* SecIdentitySearchPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 30E17F5A062B0A25004208EB /* SecIdentitySearchPriv.h */; settings = {ATTRIBUTES = (); }; };
                407AC2C0066661620030E07D /* SecPassword.h in Headers */ = {isa = PBXBuildFile; fileRef = 407AC2BE066661620030E07D /* SecPassword.h */; settings = {ATTRIBUTES = (); }; };
                1B11967B062F4C1800F3B659 /* SecKeychainSearchPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 1B11967A062F4C1800F3B659 /* SecKeychainSearchPriv.h */; settings = {ATTRIBUTES = (); }; };
                30E17F5B062B0A25004208EB /* SecIdentitySearchPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 30E17F5A062B0A25004208EB /* SecIdentitySearchPriv.h */; settings = {ATTRIBUTES = (); }; };
                407AC2C0066661620030E07D /* SecPassword.h in Headers */ = {isa = PBXBuildFile; fileRef = 407AC2BE066661620030E07D /* SecPassword.h */; settings = {ATTRIBUTES = (); }; };
@@ -88,7 +91,6 @@
                521DC5801125FEE300937BF2 /* SecCertificateP.h in Headers */ = {isa = PBXBuildFile; fileRef = 521DC57E1125FEE300937BF2 /* SecCertificateP.h */; settings = {ATTRIBUTES = (Private, ); }; };
                52200F8B14F2B87F00F7F6E7 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AA31456E134B716B00133245 /* CoreFoundation.framework */; };
                5261C28A112F0D570047EF8B /* SecFrameworkP.c in Sources */ = {isa = PBXBuildFile; fileRef = 5261C289112F0D570047EF8B /* SecFrameworkP.c */; };
                521DC5801125FEE300937BF2 /* SecCertificateP.h in Headers */ = {isa = PBXBuildFile; fileRef = 521DC57E1125FEE300937BF2 /* SecCertificateP.h */; settings = {ATTRIBUTES = (Private, ); }; };
                52200F8B14F2B87F00F7F6E7 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AA31456E134B716B00133245 /* CoreFoundation.framework */; };
                5261C28A112F0D570047EF8B /* SecFrameworkP.c in Sources */ = {isa = PBXBuildFile; fileRef = 5261C289112F0D570047EF8B /* SecFrameworkP.c */; };
-               5261C2E2112F19BA0047EF8B /* debuggingP.c in Sources */ = {isa = PBXBuildFile; fileRef = 5261C2E1112F19BA0047EF8B /* debuggingP.c */; };
                5261C310112F1C560047EF8B /* SecBase64P.c in Sources */ = {isa = PBXBuildFile; fileRef = 5261C30F112F1C560047EF8B /* SecBase64P.c */; };
                52B609D914F55B6800134209 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52B609D814F55B6800134209 /* Foundation.framework */; };
                52B609E314F55BFA00134209 /* timestampclient.m in Sources */ = {isa = PBXBuildFile; fileRef = 52B609E214F55BFA00134209 /* timestampclient.m */; };
                5261C310112F1C560047EF8B /* SecBase64P.c in Sources */ = {isa = PBXBuildFile; fileRef = 5261C30F112F1C560047EF8B /* SecBase64P.c */; };
                52B609D914F55B6800134209 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52B609D814F55B6800134209 /* Foundation.framework */; };
                52B609E314F55BFA00134209 /* timestampclient.m in Sources */ = {isa = PBXBuildFile; fileRef = 52B609E214F55BFA00134209 /* timestampclient.m */; };
                52C23EF81135AE5100E079D2 /* SecCertificatePrivP.h in Headers */ = {isa = PBXBuildFile; fileRef = 52C23EF71135AE5100E079D2 /* SecCertificatePrivP.h */; settings = {ATTRIBUTES = (Private, ); }; };
                52E950CD1509B47000DA6511 /* tsaDERUtilities.c in Sources */ = {isa = PBXBuildFile; fileRef = 52E950CC1509B47000DA6511 /* tsaDERUtilities.c */; };
                52E950D61509B48D00DA6511 /* tsaDERUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 52E950D51509B48D00DA6511 /* tsaDERUtilities.h */; settings = {ATTRIBUTES = (Private, ); }; };
                52C23EF81135AE5100E079D2 /* SecCertificatePrivP.h in Headers */ = {isa = PBXBuildFile; fileRef = 52C23EF71135AE5100E079D2 /* SecCertificatePrivP.h */; settings = {ATTRIBUTES = (Private, ); }; };
                52E950CD1509B47000DA6511 /* tsaDERUtilities.c in Sources */ = {isa = PBXBuildFile; fileRef = 52E950CC1509B47000DA6511 /* tsaDERUtilities.c */; };
                52E950D61509B48D00DA6511 /* tsaDERUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 52E950D51509B48D00DA6511 /* tsaDERUtilities.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               52FB42C2113F056D006D3B0A /* debuggingP.h in Headers */ = {isa = PBXBuildFile; fileRef = 52FB42C1113F056D006D3B0A /* debuggingP.h */; };
                52FB44A91146D769006D3B0A /* SecCertificateOIDs.h in Headers */ = {isa = PBXBuildFile; fileRef = 52FB44A81146D769006D3B0A /* SecCertificateOIDs.h */; settings = {ATTRIBUTES = (); }; };
                AA31456F134B716B00133245 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AA31456E134B716B00133245 /* CoreFoundation.framework */; };
                BE296DBF0EAC299C00FD22BE /* SecImportExport.c in Sources */ = {isa = PBXBuildFile; fileRef = BE296DBE0EAC299C00FD22BE /* SecImportExport.c */; };
                52FB44A91146D769006D3B0A /* SecCertificateOIDs.h in Headers */ = {isa = PBXBuildFile; fileRef = 52FB44A81146D769006D3B0A /* SecCertificateOIDs.h */; settings = {ATTRIBUTES = (); }; };
                AA31456F134B716B00133245 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AA31456E134B716B00133245 /* CoreFoundation.framework */; };
                BE296DBF0EAC299C00FD22BE /* SecImportExport.c in Sources */ = {isa = PBXBuildFile; fileRef = BE296DBE0EAC299C00FD22BE /* SecImportExport.c */; };
                05AE95480AA748570076501C /* SecImportExportOpenSSH.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SecImportExportOpenSSH.cpp; sourceTree = "<group>"; };
                05FB016605E54A3A00A5194C /* SecNetscapeTemplates.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SecNetscapeTemplates.cpp; sourceTree = "<group>"; };
                05FB016705E54A3A00A5194C /* SecNetscapeTemplates.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecNetscapeTemplates.h; sourceTree = "<group>"; };
                05AE95480AA748570076501C /* SecImportExportOpenSSH.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SecImportExportOpenSSH.cpp; sourceTree = "<group>"; };
                05FB016605E54A3A00A5194C /* SecNetscapeTemplates.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SecNetscapeTemplates.cpp; sourceTree = "<group>"; };
                05FB016705E54A3A00A5194C /* SecNetscapeTemplates.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecNetscapeTemplates.h; sourceTree = "<group>"; };
+               0CBD509716C3242200713B6C /* libsecurity_keychain_regressions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurity_keychain_regressions.a; sourceTree = BUILT_PRODUCTS_DIR; };
+               0CBD509816C3246D00713B6C /* kc-40-seckey.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "kc-40-seckey.c"; path = "regressions/kc-40-seckey.c"; sourceTree = "<group>"; };
+               0CBD509916C3246D00713B6C /* kc-41-sececkey.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "kc-41-sececkey.c"; path = "regressions/kc-41-sececkey.c"; sourceTree = "<group>"; };
+               0CBD509C16C324B100713B6C /* keychain_regressions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = keychain_regressions.h; path = regressions/keychain_regressions.h; sourceTree = "<group>"; };
                182BB224146F063C000BF1F3 /* base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = base.xcconfig; sourceTree = "<group>"; };
                182BB225146F063C000BF1F3 /* debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = debug.xcconfig; sourceTree = "<group>"; };
                182BB226146F063C000BF1F3 /* lib.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = lib.xcconfig; sourceTree = "<group>"; };
                182BB227146F063C000BF1F3 /* release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = release.xcconfig; sourceTree = "<group>"; };
                182BB30C146F0AE6000BF1F3 /* libsecurity_utilities.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libsecurity_utilities.xcodeproj; path = ../libsecurity_utilities/libsecurity_utilities.xcodeproj; sourceTree = "<group>"; };
                182BB224146F063C000BF1F3 /* base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = base.xcconfig; sourceTree = "<group>"; };
                182BB225146F063C000BF1F3 /* debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = debug.xcconfig; sourceTree = "<group>"; };
                182BB226146F063C000BF1F3 /* lib.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = lib.xcconfig; sourceTree = "<group>"; };
                182BB227146F063C000BF1F3 /* release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = release.xcconfig; sourceTree = "<group>"; };
                182BB30C146F0AE6000BF1F3 /* libsecurity_utilities.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libsecurity_utilities.xcodeproj; path = ../libsecurity_utilities/libsecurity_utilities.xcodeproj; sourceTree = "<group>"; };
+               188BB53F171DD774009D22CE /* si-33-keychain-backup.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "si-33-keychain-backup.c"; path = "regressions/si-33-keychain-backup.c"; sourceTree = "<group>"; };
                1B11967A062F4C1800F3B659 /* SecKeychainSearchPriv.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecKeychainSearchPriv.h; sourceTree = "<group>"; };
                30E17F5A062B0A25004208EB /* SecIdentitySearchPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecIdentitySearchPriv.h; path = lib/SecIdentitySearchPriv.h; sourceTree = SOURCE_ROOT; };
                407AC2BE066661620030E07D /* SecPassword.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecPassword.h; sourceTree = "<group>"; };
                1B11967A062F4C1800F3B659 /* SecKeychainSearchPriv.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecKeychainSearchPriv.h; sourceTree = "<group>"; };
                30E17F5A062B0A25004208EB /* SecIdentitySearchPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecIdentitySearchPriv.h; path = lib/SecIdentitySearchPriv.h; sourceTree = SOURCE_ROOT; };
                407AC2BE066661620030E07D /* SecPassword.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecPassword.h; sourceTree = "<group>"; };
                        name = Import/Export;
                        sourceTree = "<group>";
                };
                        name = Import/Export;
                        sourceTree = "<group>";
                };
+               0CBD4FF916C323E800713B6C /* regressions */ = {
+                       isa = PBXGroup;
+                       children = (
+                               0CBD509C16C324B100713B6C /* keychain_regressions.h */,
+                               0CBD509816C3246D00713B6C /* kc-40-seckey.c */,
+                               0CBD509916C3246D00713B6C /* kc-41-sececkey.c */,
+                               188BB53F171DD774009D22CE /* si-33-keychain-backup.c */,
+                       );
+                       name = regressions;
+                       sourceTree = "<group>";
+               };
                182BB223146F063C000BF1F3 /* config */ = {
                        isa = PBXGroup;
                        children = (
                182BB223146F063C000BF1F3 /* config */ = {
                        isa = PBXGroup;
                        children = (
                        children = (
                                182BB30C146F0AE6000BF1F3 /* libsecurity_utilities.xcodeproj */,
                                5297A586112B78BB00EAA0C0 /* libDER.xcodeproj */,
                        children = (
                                182BB30C146F0AE6000BF1F3 /* libsecurity_utilities.xcodeproj */,
                                5297A586112B78BB00EAA0C0 /* libDER.xcodeproj */,
+                               0CBD4FF916C323E800713B6C /* regressions */,
                                C2AA2B41052E099D006D0211 /* lib */,
                                182BB223146F063C000BF1F3 /* config */,
                                52200F9914F2B93700F7F6E7 /* xpc-tsa */,
                                C2AA2B41052E099D006D0211 /* lib */,
                                182BB223146F063C000BF1F3 /* config */,
                                52200F9914F2B93700F7F6E7 /* xpc-tsa */,
                                4CA1FEBE052A3C8100F22E42 /* libsecurity_keychain.a */,
                                4C5719C812FB5E9E00B31F85 /* XPCKeychainSandboxCheck.xpc */,
                                52200F8F14F2B88000F7F6E7 /* XPCTimeStampingService.xpc */,
                                4CA1FEBE052A3C8100F22E42 /* libsecurity_keychain.a */,
                                4C5719C812FB5E9E00B31F85 /* XPCKeychainSandboxCheck.xpc */,
                                52200F8F14F2B88000F7F6E7 /* XPCTimeStampingService.xpc */,
+                               0CBD509716C3242200713B6C /* libsecurity_keychain_regressions.a */,
                        );
                        name = Products;
                        sourceTree = "<group>";
                        );
                        name = Products;
                        sourceTree = "<group>";
                                52BA735E112231C70012875E /* CertificateValues.h in Headers */,
                                521DC5801125FEE300937BF2 /* SecCertificateP.h in Headers */,
                                52C23EF81135AE5100E079D2 /* SecCertificatePrivP.h in Headers */,
                                52BA735E112231C70012875E /* CertificateValues.h in Headers */,
                                521DC5801125FEE300937BF2 /* SecCertificateP.h in Headers */,
                                52C23EF81135AE5100E079D2 /* SecCertificatePrivP.h in Headers */,
-                               52FB42C2113F056D006D3B0A /* debuggingP.h in Headers */,
                                52E950D61509B48D00DA6511 /* tsaDERUtilities.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                                52E950D61509B48D00DA6511 /* tsaDERUtilities.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
 /* End PBXHeadersBuildPhase section */
 
 /* Begin PBXNativeTarget section */
 /* End PBXHeadersBuildPhase section */
 
 /* Begin PBXNativeTarget section */
+               0CBD500016C3242200713B6C /* libsecurity_keychain_regressions */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 0CBD509416C3242200713B6C /* Build configuration list for PBXNativeTarget "libsecurity_keychain_regressions" */;
+                       buildPhases = (
+                               0CBD504416C3242200713B6C /* Sources */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = libsecurity_keychain_regressions;
+                       productName = libsecurity_keychain;
+                       productReference = 0CBD509716C3242200713B6C /* libsecurity_keychain_regressions.a */;
+                       productType = "com.apple.product-type.library.static";
+               };
                4C5719C712FB5E9E00B31F85 /* XPCKeychainSandboxCheck */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = 4C5719CF12FB5E9F00B31F85 /* Build configuration list for PBXNativeTarget "XPCKeychainSandboxCheck" */;
                4C5719C712FB5E9E00B31F85 /* XPCKeychainSandboxCheck */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = 4C5719CF12FB5E9F00B31F85 /* Build configuration list for PBXNativeTarget "XPCKeychainSandboxCheck" */;
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0420;
+                               LastUpgradeCheck = 0500;
                        };
                        buildConfigurationList = C27AD3810987FCDE001272E0 /* Build configuration list for PBXProject "libsecurity_keychain" */;
                        compatibilityVersion = "Xcode 3.2";
                        };
                        buildConfigurationList = C27AD3810987FCDE001272E0 /* Build configuration list for PBXProject "libsecurity_keychain" */;
                        compatibilityVersion = "Xcode 3.2";
                                4CA1FEBD052A3C8100F22E42 /* libsecurity_keychain */,
                                4C5719C712FB5E9E00B31F85 /* XPCKeychainSandboxCheck */,
                                52200F8714F2B87F00F7F6E7 /* XPCTimeStampingService */,
                                4CA1FEBD052A3C8100F22E42 /* libsecurity_keychain */,
                                4C5719C712FB5E9E00B31F85 /* XPCKeychainSandboxCheck */,
                                52200F8714F2B87F00F7F6E7 /* XPCTimeStampingService */,
+                               0CBD500016C3242200713B6C /* libsecurity_keychain_regressions */,
                        );
                };
 /* End PBXProject section */
                        );
                };
 /* End PBXProject section */
 /* End PBXReferenceProxy section */
 
 /* Begin PBXSourcesBuildPhase section */
 /* End PBXReferenceProxy section */
 
 /* Begin PBXSourcesBuildPhase section */
+               0CBD504416C3242200713B6C /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               0CBD509B16C3246D00713B6C /* kc-41-sececkey.c in Sources */,
+                               188BB546171DD8B5009D22CE /* si-33-keychain-backup.c in Sources */,
+                               0CBD509A16C3246D00713B6C /* kc-40-seckey.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                4C5719C512FB5E9E00B31F85 /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                4C5719C512FB5E9E00B31F85 /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                                52BA735D112231C70012875E /* CertificateValues.cpp in Sources */,
                                521DC57F1125FEE300937BF2 /* SecCertificateP.c in Sources */,
                                5261C28A112F0D570047EF8B /* SecFrameworkP.c in Sources */,
                                52BA735D112231C70012875E /* CertificateValues.cpp in Sources */,
                                521DC57F1125FEE300937BF2 /* SecCertificateP.c in Sources */,
                                5261C28A112F0D570047EF8B /* SecFrameworkP.c in Sources */,
-                               5261C2E2112F19BA0047EF8B /* debuggingP.c in Sources */,
                                5261C310112F1C560047EF8B /* SecBase64P.c in Sources */,
                                4885CFF811C8182D0093ECF6 /* SecRecoveryPassword.c in Sources */,
                                52B88DFB11DD0D2D005BCA6B /* SecFDERecoveryAsymmetricCrypto.cpp in Sources */,
                                5261C310112F1C560047EF8B /* SecBase64P.c in Sources */,
                                4885CFF811C8182D0093ECF6 /* SecRecoveryPassword.c in Sources */,
                                52B88DFB11DD0D2D005BCA6B /* SecFDERecoveryAsymmetricCrypto.cpp in Sources */,
 /* End PBXTargetDependency section */
 
 /* Begin XCBuildConfiguration section */
 /* End PBXTargetDependency section */
 
 /* Begin XCBuildConfiguration section */
+               0CBD509516C3242200713B6C /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 182BB225146F063C000BF1F3 /* debug.xcconfig */;
+                       buildSettings = {
+                               WARNING_CFLAGS = (
+                                       "$(inherited)",
+                                       "-Wno-error=overloaded-virtual",
+                               );
+                       };
+                       name = Debug;
+               };
+               0CBD509616C3242200713B6C /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 182BB227146F063C000BF1F3 /* release.xcconfig */;
+                       buildSettings = {
+                               WARNING_CFLAGS = (
+                                       "$(inherited)",
+                                       "-Wno-error=overloaded-virtual",
+                               );
+                       };
+                       name = Release;
+               };
                4C5719CB12FB5E9F00B31F85 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB225146F063C000BF1F3 /* debug.xcconfig */;
                        buildSettings = {
                4C5719CB12FB5E9F00B31F85 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB225146F063C000BF1F3 /* debug.xcconfig */;
                        buildSettings = {
+                               CODE_SIGN_IDENTITY = "-";
+                               COMBINE_HIDPI_IMAGES = YES;
                                GCC_MODEL_TUNING = G5;
                                INFOPLIST_FILE = "xpc/XPCKeychainSandboxCheck-Info.plist";
                                GCC_MODEL_TUNING = G5;
                                INFOPLIST_FILE = "xpc/XPCKeychainSandboxCheck-Info.plist";
-                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/XPCServices/";
+                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/Versions/${FRAMEWORK_VERSION}/XPCServices";
                                PRODUCT_NAME = XPCKeychainSandboxCheck;
                                PRODUCT_NAME = XPCKeychainSandboxCheck;
+                               PROVISIONING_PROFILE = "";
                                SKIP_INSTALL = NO;
                                WRAPPER_EXTENSION = xpc;
                        };
                                SKIP_INSTALL = NO;
                                WRAPPER_EXTENSION = xpc;
                        };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB227146F063C000BF1F3 /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB227146F063C000BF1F3 /* release.xcconfig */;
                        buildSettings = {
+                               CODE_SIGN_IDENTITY = "-";
+                               COMBINE_HIDPI_IMAGES = YES;
                                GCC_MODEL_TUNING = G5;
                                INFOPLIST_FILE = "xpc/XPCKeychainSandboxCheck-Info.plist";
                                GCC_MODEL_TUNING = G5;
                                INFOPLIST_FILE = "xpc/XPCKeychainSandboxCheck-Info.plist";
-                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/XPCServices/";
+                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/Versions/${FRAMEWORK_VERSION}/XPCServices";
                                PRODUCT_NAME = XPCKeychainSandboxCheck;
                                PRODUCT_NAME = XPCKeychainSandboxCheck;
+                               PROVISIONING_PROFILE = "";
                                SKIP_INSTALL = NO;
                                WRAPPER_EXTENSION = xpc;
                        };
                                SKIP_INSTALL = NO;
                                WRAPPER_EXTENSION = xpc;
                        };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB225146F063C000BF1F3 /* debug.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB225146F063C000BF1F3 /* debug.xcconfig */;
                        buildSettings = {
+                               CODE_SIGN_IDENTITY = "-";
+                               COMBINE_HIDPI_IMAGES = YES;
                                GCC_MODEL_TUNING = G5;
                                INFOPLIST_FILE = "xpc-tsa/XPCTimeStampingService-Info.plist";
                                GCC_MODEL_TUNING = G5;
                                INFOPLIST_FILE = "xpc-tsa/XPCTimeStampingService-Info.plist";
-                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/XPCServices/";
+                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/Versions/${FRAMEWORK_VERSION}/XPCServices";
                                PRODUCT_NAME = XPCTimeStampingService;
                                PRODUCT_NAME = XPCTimeStampingService;
+                               PROVISIONING_PROFILE = "";
                                SKIP_INSTALL = NO;
                                WRAPPER_EXTENSION = xpc;
                        };
                                SKIP_INSTALL = NO;
                                WRAPPER_EXTENSION = xpc;
                        };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB227146F063C000BF1F3 /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB227146F063C000BF1F3 /* release.xcconfig */;
                        buildSettings = {
+                               CODE_SIGN_IDENTITY = "-";
+                               COMBINE_HIDPI_IMAGES = YES;
                                GCC_MODEL_TUNING = G5;
                                INFOPLIST_FILE = "xpc-tsa/XPCTimeStampingService-Info.plist";
                                GCC_MODEL_TUNING = G5;
                                INFOPLIST_FILE = "xpc-tsa/XPCTimeStampingService-Info.plist";
-                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/XPCServices/";
+                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/Versions/${FRAMEWORK_VERSION}/XPCServices";
                                PRODUCT_NAME = XPCTimeStampingService;
                                PRODUCT_NAME = XPCTimeStampingService;
+                               PROVISIONING_PROFILE = "";
                                SKIP_INSTALL = NO;
                                WRAPPER_EXTENSION = xpc;
                        };
                                SKIP_INSTALL = NO;
                                WRAPPER_EXTENSION = xpc;
                        };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB225146F063C000BF1F3 /* debug.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB225146F063C000BF1F3 /* debug.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                HEADER_SEARCH_PATHS = (
                                        "$(inherited)",
                                        "$(PROJECT_DIR)/libDER",
                                );
                                HEADER_SEARCH_PATHS = (
                                        "$(inherited)",
                                        "$(PROJECT_DIR)/libDER",
                                );
+                               WARNING_CFLAGS = (
+                                       "$(inherited)",
+                                       "-Wno-error=overloaded-virtual",
+                               );
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB227146F063C000BF1F3 /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB227146F063C000BF1F3 /* release.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                HEADER_SEARCH_PATHS = (
                                        "$(inherited)",
                                        "$(PROJECT_DIR)/libDER",
                                );
                                HEADER_SEARCH_PATHS = (
                                        "$(inherited)",
                                        "$(PROJECT_DIR)/libDER",
                                );
+                               WARNING_CFLAGS = (
+                                       "$(inherited)",
+                                       "-Wno-error=overloaded-virtual",
+                               );
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB226146F063C000BF1F3 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB226146F063C000BF1F3 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB226146F063C000BF1F3 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB226146F063C000BF1F3 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Release;
                };
 /* End XCBuildConfiguration section */
 
 /* Begin XCConfigurationList section */
                        };
                        name = Release;
                };
 /* End XCBuildConfiguration section */
 
 /* Begin XCConfigurationList section */
+               0CBD509416C3242200713B6C /* Build configuration list for PBXNativeTarget "libsecurity_keychain_regressions" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               0CBD509516C3242200713B6C /* Debug */,
+                               0CBD509616C3242200713B6C /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
                4C5719CF12FB5E9F00B31F85 /* Build configuration list for PBXNativeTarget "XPCKeychainSandboxCheck" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                4C5719CF12FB5E9F00B31F85 /* Build configuration list for PBXNativeTarget "XPCKeychainSandboxCheck" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
diff --git a/libsecurity_keychain/regressions/kc-40-seckey.c b/libsecurity_keychain/regressions/kc-40-seckey.c
new file mode 100644 (file)
index 0000000..fdc2114
--- /dev/null
@@ -0,0 +1,499 @@
+/*
+ *  si-40-seckey.c
+ *  Security
+ *
+ *  Created by Michael Brouwer on 1/29/07.
+ *  Copyright (c) 2007-2009 Apple Inc. All Rights Reserved.
+ *
+ */
+
+#include <TargetConditionals.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/Security.h>
+#include <Security/SecRandom.h>
+#include <CommonCrypto/CommonDigest.h>
+#include <Security/SecKeyPriv.h>
+
+#if 0
+#include <Security/SecCertificate.h>
+#include <Security/SecCertificateInternal.h>
+#include <Security/SecKey.h>
+#include <Security/SecKeyPriv.h>
+#include <Security/SecItem.h>
+#include <Security/SecAsn1Types.h>
+#include <Security/oidsalg.h>
+#include <libDER/libDER.h>
+#include <stdlib.h>
+#include <unistd.h>
+#endif
+
+#include "keychain_regressions.h"
+#include "utilities/SecCFRelease.h"
+
+#if TARGET_OS_IPHONE
+static void testdigestandsignalg(SecKeyRef privKey, SecKeyRef pubKey, const SecAsn1AlgId *algId) {
+    uint8_t dataToDigest[256];
+    size_t dataToDigestLen = sizeof(dataToDigest);
+    size_t sigLen = SecKeyGetSize(privKey, kSecKeySignatureSize);
+    uint8_t sig[sigLen];
+
+    DERItem oid;
+    oid.length = algId->algorithm.Length;
+    oid.data = algId->algorithm.Data;
+
+    /* Get the oid in decimal for display purposes. */
+    CFStringRef oidStr = SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault, &oid);
+       char oidBuf[40];
+    CFStringGetCString(oidStr, oidBuf, sizeof(oidBuf), kCFStringEncodingUTF8);
+    CFRelease(oidStr);
+
+       SKIP: {
+        OSStatus status;
+
+        /* Time to sign. */
+        ok_status(status = SecKeyDigestAndSign(privKey, algId, dataToDigest, dataToDigestLen,
+            sig, &sigLen), "digest and sign %s with %ld bit RSA key", oidBuf, sigLen * 8);
+
+        skip("SecKeyDigestAndSign failed", 3, status == errSecSuccess);
+
+        /* Verify the signature we just made. */
+        ok_status(SecKeyDigestAndVerify(pubKey, algId, dataToDigest, dataToDigestLen,
+            sig, sigLen), "digest and verify");
+        /* Invalidate the signature. */
+        sig[0] ^= 0xff;
+        is_status(SecKeyDigestAndVerify(pubKey, algId, dataToDigest, dataToDigestLen,
+            sig, sigLen), errSSLCrypto, "digest and verify bad sig");
+        sig[0] ^= 0xff;
+        dataToDigest[0] ^= 0xff;
+        is_status(SecKeyDigestAndVerify(pubKey, algId, dataToDigest, dataToDigestLen,
+            sig, sigLen), errSSLCrypto, "digest and verify bad digest");
+    }
+}
+
+static void testdigestandsign(SecKeyRef privKey, SecKeyRef pubKey) {
+    static const SecAsn1Oid *oids[] = {
+        &CSSMOID_SHA1WithRSA,
+        &CSSMOID_SHA224WithRSA,
+        &CSSMOID_SHA256WithRSA,
+        &CSSMOID_SHA384WithRSA,
+        &CSSMOID_SHA512WithRSA,
+#if 0
+        &CSSMOID_SHA1WithRSA_OIW,
+        &CSSMOID_SHA1WithDSA,          // BSAFE
+        &CSSMOID_SHA1WithDSA_CMS,      // X509/CMS
+        &CSSMOID_SHA1WithDSA_JDK,      // JDK 1.1
+#endif
+    };
+
+
+    uint32_t ix;
+    SecAsn1AlgId algId = {};
+    for (ix = 0; ix < sizeof(oids) / sizeof(*oids); ++ix) {
+        if (oids[ix]) {
+            algId.algorithm = *oids[ix];
+        } else {
+            algId.algorithm.Length = 0;
+            algId.algorithm.Data = NULL;
+        }
+
+        testdigestandsignalg(privKey, pubKey, &algId);
+    }
+}
+#endif
+
+#if 0
+static void dump_bytes(uint8_t* bytes, size_t amount)
+{
+    while (amount > 0) {
+        printf("0x%02x ", *bytes);
+        ++bytes;
+        --amount;
+    }
+}
+#endif
+
+
+#if !TARGET_OS_IPHONE
+#define kEncryptDecryptTestCount 0
+#else
+#define kEncryptDecryptTestCount 5
+static void test_encrypt_decrypt(SecKeyRef pubKey, SecKeyRef privKey, uint32_t padding, size_t keySizeInBytes)
+{
+    SKIP: {
+        size_t max_len = keySizeInBytes;
+        switch (padding) {
+            case kSecPaddingNone: max_len = keySizeInBytes; break;
+            case kSecPaddingOAEP: max_len = keySizeInBytes - 2 - 2 * CC_SHA1_DIGEST_LENGTH; break;
+            case kSecPaddingPKCS1: max_len = keySizeInBytes - 11; break;
+            default: skip("what is the max_len for this padding?", 5, false);
+        }
+
+        uint8_t secret[max_len + 1], encrypted_secret[keySizeInBytes], decrypted_secret[keySizeInBytes];
+        uint8_t *secret_ptr = secret;
+        size_t secret_len = max_len;
+        size_t encrypted_secret_len = sizeof(encrypted_secret);
+        size_t decrypted_secret_len = sizeof(decrypted_secret);
+        memset(decrypted_secret, 0xff, decrypted_secret_len);
+        SecRandomCopyBytes(kSecRandomDefault, sizeof(secret), secret);
+
+        // zero pad, no accidental second zero byte
+        if (padding == kSecPaddingNone) {
+            secret[0] = 0;
+            secret[1] = 128;
+        }
+
+        is_status(SecKeyEncrypt(pubKey, padding,
+                                secret, sizeof(secret),
+                                encrypted_secret, &encrypted_secret_len), errSecParam, "encrypt secret (overflow)");
+        ok_status(SecKeyEncrypt(pubKey, padding,
+                                secret, secret_len,
+                                encrypted_secret, &encrypted_secret_len), "encrypt secret");
+
+        ok_status(SecKeyDecrypt(privKey, padding,
+                                encrypted_secret, encrypted_secret_len,
+                                decrypted_secret, &decrypted_secret_len), "decrypt secret");
+
+        // zero padding is removed on decode
+        if (padding == kSecPaddingNone) {
+            secret_len--;
+            secret_ptr++;
+        }
+
+        ok(decrypted_secret_len == secret_len, "correct length");
+        ok_status(memcmp(secret_ptr, decrypted_secret, secret_len), "verify secret");
+    }
+}
+#endif
+
+
+
+#if !TARGET_OS_IPHONE
+/* This is part of Security.framework on iOS */
+
+enum {
+    // kSecKeyKeySizeInBits        = 0, // already exists on osx
+    kSecKeySignatureSize        = 101,
+    kSecKeyEncryptedDataSize    = 102,
+    // More might belong here, but we aren't settled on how
+    // to take into account padding and/or digest types.
+};
+
+static
+size_t SecKeyGetSize(SecKeyRef key, int whichSize)
+{
+    size_t result = SecKeyGetBlockSize(key);
+
+    /* This is only RSA */
+    if (whichSize == kSecKeyKeySizeInBits)
+        result *= 8;
+
+    return result;
+}
+#endif
+
+#define kKeyGenTestCount (11 + (3*kEncryptDecryptTestCount))
+static void testkeygen(size_t keySizeInBits) {
+       SecKeyRef pubKey = NULL, privKey = NULL;
+       size_t keySizeInBytes = (keySizeInBits + 7) / 8;
+       CFNumberRef kzib;
+
+       kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keySizeInBits);
+       CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+       CFDictionaryAddValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
+       CFDictionaryAddValue(kgp, kSecAttrKeySizeInBits, kzib);
+
+       OSStatus status;
+       ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
+              "Generate %ld bit (%ld byte) RSA keypair", keySizeInBits,
+              keySizeInBytes);
+       CFRelease(kzib);
+       CFRelease(kgp);
+
+       SKIP: {
+        skip("keygen failed", 8, status == errSecSuccess);
+               ok(pubKey, "pubkey returned");
+               ok(privKey, "privKey returned");
+               is(SecKeyGetSize(pubKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "public key size is ok");
+               is(SecKeyGetSize(privKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "private key size is ok");
+
+               /* Sign something. */
+               uint8_t something[keySizeInBytes];
+        size_t something_len = keySizeInBytes - 11;
+        SecRandomCopyBytes(kSecRandomDefault, sizeof(something), something);
+               uint8_t sig[keySizeInBytes];
+               size_t sigLen = sizeof(sig);
+#if TARGET_OS_IPHONE
+        /* TODO: This is returning another error on OS X */
+               is_status(SecKeyRawSign(privKey, kSecPaddingPKCS1,
+                                something, something_len + 1, sig, &sigLen),
+                                errSecParam, "sign overflow");
+#endif
+               ok_status(SecKeyRawSign(privKey, kSecPaddingPKCS1,
+                       something, something_len, sig, &sigLen), "sign something");
+               ok_status(SecKeyRawVerify(pubKey, kSecPaddingPKCS1,
+                       something, something_len, sig, sigLen), "verify sig on something");
+
+        // Torture test ASN.1 encoder by setting high bit to 1.
+        uint8_t digest[CC_SHA512_DIGEST_LENGTH] = {
+            0x80, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+            0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+            0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+            0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+            0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+            0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+            0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+        };
+#if TARGET_OS_IPHONE
+        /* Thoses tests are making sure that MD2 and MD5 are NOT supported,
+            but they still are on OS X */
+
+        //CC_MD2(something, sizeof(something), digest);
+               ok_status(!SecKeyRawSign(privKey, kSecPaddingPKCS1MD2,
+                       digest, CC_MD2_DIGEST_LENGTH, sig, &sigLen),
+                  "don't sign md2 digest");   //FAIL
+               ok_status(!SecKeyRawVerify(pubKey, kSecPaddingPKCS1MD2,
+                       digest, CC_MD2_DIGEST_LENGTH, sig, sigLen),
+                  "verify sig on md2 digest fails");  //FAIL
+
+        //CC_MD5(something, sizeof(something), digest);
+               sigLen = sizeof(sig);
+               ok_status(!SecKeyRawSign(privKey, kSecPaddingPKCS1MD5,
+                       digest, CC_MD5_DIGEST_LENGTH, sig, &sigLen),
+            "don't sign md5 digest"); //FAIL
+               ok_status(!SecKeyRawVerify(pubKey, kSecPaddingPKCS1MD5,
+                       digest, CC_MD5_DIGEST_LENGTH, sig, sigLen),
+            "verify sig on md5 digest fails"); //FAIL
+#endif
+
+        //CCDigest(kCCDigestSHA1, something, sizeof(something), digest);
+               sigLen = sizeof(sig);
+               ok_status(SecKeyRawSign(privKey, kSecPaddingPKCS1SHA1,
+                       digest, CC_SHA1_DIGEST_LENGTH, sig, &sigLen),
+            "sign sha1 digest");
+               ok_status(SecKeyRawVerify(pubKey, kSecPaddingPKCS1SHA1,
+                       digest, CC_SHA1_DIGEST_LENGTH, sig, sigLen),
+            "verify sig on sha1 digest");
+
+#if TARGET_OS_IPHONE
+        /* The assumptions in these tests are just wrong on OS X */
+               uint8_t signature[keySizeInBytes], *ptr = signature;
+               size_t signature_len = sizeof(signature);
+               ok_status(SecKeyEncrypt(pubKey, kSecPaddingNone, sig, sigLen, signature, &signature_len), "inspect signature");
+               is(signature_len, keySizeInBytes - 1, "got signature");  // FAIL for 2056
+               while(*ptr && ((size_t)(ptr - signature) < signature_len)) ptr++;
+               is(signature + signature_len - ptr, 16 /* length(\0 || OID_SHA1) */ + CC_SHA1_DIGEST_LENGTH, "successful decode");
+#endif
+
+#if TARGET_OS_IPHONE
+        /* Those are not supported on OS X */
+        /* PKCS1 padding is 00 01 PAD * 8 or more 00 data.
+           data is SEQ { SEQ { OID NULL } BIT STRING 00 DIGEST }
+           So min data + pad overhead is 11 + 9 + oidlen
+           oidlen = 11 for the sha2 family of oids, so we have 29 bytes; or
+           232 bits of minimum overhead.  */
+        const size_t pkcs1Overhead = 232;
+        if (keySizeInBits > 224 + pkcs1Overhead) {
+            //CC_SHA224(something, sizeof(something), digest);
+            sigLen = sizeof(sig);
+            ok_status(SecKeyRawSign(privKey, kSecPaddingPKCS1SHA224,
+                                    digest, CC_SHA224_DIGEST_LENGTH, sig, &sigLen),
+                      "sign sha224 digest");
+            ok_status(SecKeyRawVerify(pubKey, kSecPaddingPKCS1SHA224,
+                                      digest, CC_SHA224_DIGEST_LENGTH, sig, sigLen),
+                      "verify sig on sha224 digest");
+        }
+
+        if (keySizeInBits > 256 + pkcs1Overhead) {
+            //CC_SHA256(something, sizeof(something), digest);
+            sigLen = sizeof(sig);
+            ok_status(SecKeyRawSign(privKey, kSecPaddingPKCS1SHA256,
+                                    digest, CC_SHA256_DIGEST_LENGTH, sig, &sigLen),
+                      "sign sha256 digest");
+            ok_status(SecKeyRawVerify(pubKey, kSecPaddingPKCS1SHA256,
+                                      digest, CC_SHA256_DIGEST_LENGTH, sig, sigLen),
+                      "verify sig on sha256 digest");
+        }
+
+        if (keySizeInBits > 384 + pkcs1Overhead) {
+            //CC_SHA384(something, sizeof(something), digest);
+            sigLen = sizeof(sig);
+            ok_status(SecKeyRawSign(privKey, kSecPaddingPKCS1SHA384,
+                                    digest, CC_SHA384_DIGEST_LENGTH, sig, &sigLen),
+                      "sign sha384 digest");
+            ok_status(SecKeyRawVerify(pubKey, kSecPaddingPKCS1SHA384,
+                                      digest, CC_SHA384_DIGEST_LENGTH, sig, sigLen),
+                      "verify sig on sha384 digest");
+        }
+
+        if (keySizeInBits > 512 + pkcs1Overhead) {
+            //CC_SHA512(something, sizeof(something), digest);
+            sigLen = sizeof(sig);
+            ok_status(SecKeyRawSign(privKey, kSecPaddingPKCS1SHA512,
+                                    digest, CC_SHA512_DIGEST_LENGTH, sig, &sigLen),
+                      "sign sha512 digest");
+            ok_status(SecKeyRawVerify(pubKey, kSecPaddingPKCS1SHA512,
+                                      digest, CC_SHA512_DIGEST_LENGTH, sig, sigLen),
+                      "verify sig on sha512 digest");
+        }
+
+        test_encrypt_decrypt(pubKey, privKey, kSecPaddingNone, keySizeInBytes);
+        test_encrypt_decrypt(pubKey, privKey, kSecPaddingPKCS1, keySizeInBytes);
+        test_encrypt_decrypt(pubKey, privKey, kSecPaddingOAEP, keySizeInBytes);
+
+        testdigestandsign(privKey, pubKey);
+#endif
+
+               const void *privkeys[] = {
+                       kSecValueRef
+               };
+               const void *privvalues[] = {
+                       privKey
+               };
+               CFDictionaryRef privitem = CFDictionaryCreate(NULL, privkeys, privvalues,
+               sizeof(privkeys) / sizeof(*privkeys), NULL, NULL);
+#if TARGET_OS_IPHONE
+        /* OS X: keys are always added to the keychain when generated */
+               ok_status(SecItemAdd(privitem, NULL), "add private key"); //FAIL
+#endif
+        ok_status(SecItemDelete(privitem), "delete private key");
+               CFReleaseNull(privitem);
+
+               const void *pubkeys[] = {
+                       kSecValueRef
+               };
+               const void *pubvalues[] = {
+                       pubKey
+               };
+               CFDictionaryRef pubitem = CFDictionaryCreate(NULL, pubkeys, pubvalues,
+               sizeof(pubkeys) / sizeof(*pubkeys), NULL, NULL);
+#if TARGET_OS_IPHONE
+        /* OS X: keys are always added to the keychain when generated */
+               ok_status(SecItemAdd(pubitem, NULL), "add public key"); //FAIL
+#endif
+        ok_status(SecItemDelete(pubitem), "delete public key");
+               CFReleaseNull(pubitem);
+
+               /* Cleanup. */
+               CFReleaseNull(pubKey);
+               CFReleaseNull(privKey);
+       }
+}
+
+#define kKeyGen2TestCount 11
+static void testkeygen2(size_t keySizeInBits) {
+       SecKeyRef pubKey = NULL, privKey = NULL;
+       size_t keySizeInBytes = (keySizeInBits + 7) / 8;
+       CFNumberRef kzib;
+
+    CFUUIDRef ourUUID = CFUUIDCreate(kCFAllocatorDefault);
+    CFStringRef uuidString = CFUUIDCreateString(kCFAllocatorDefault, ourUUID);
+    CFMutableStringRef publicName = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, uuidString);
+    CFMutableStringRef privateName = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, uuidString);
+
+    CFReleaseNull(ourUUID);
+    CFReleaseNull(uuidString);
+
+    CFStringAppend(publicName, CFSTR("-Public-40"));
+    CFStringAppend(privateName, CFSTR("-Private-40"));
+       CFMutableDictionaryRef pubd = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+       CFMutableDictionaryRef privd = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+
+       CFDictionaryAddValue(pubd, kSecAttrLabel, publicName);
+       CFDictionaryAddValue(privd, kSecAttrLabel, privateName);
+
+       kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keySizeInBits);
+       CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+       CFDictionaryAddValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
+       CFDictionaryAddValue(kgp, kSecAttrKeySizeInBits, kzib);
+       CFDictionaryAddValue(kgp, kSecAttrIsPermanent, kCFBooleanTrue);
+       CFDictionaryAddValue(kgp, kSecPublicKeyAttrs, pubd);
+       CFDictionaryAddValue(kgp, kSecPrivateKeyAttrs, privd);
+
+       OSStatus status;
+       ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
+              "Generate %ld bit (%ld byte) persistent RSA keypair",
+              keySizeInBits, keySizeInBytes);
+       CFRelease(kzib);
+       CFRelease(kgp);
+
+       SKIP: {
+        skip("keygen failed", 8, status == errSecSuccess);
+               ok(pubKey, "pubkey returned");
+               ok(privKey, "privKey returned");
+               is(SecKeyGetSize(pubKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "public key size is ok");
+               is(SecKeyGetSize(privKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "private key size is ok");
+
+               SecKeyRef pubKey2, privKey2;
+               CFDictionaryAddValue(pubd, kSecClass, kSecClassKey);
+               CFDictionaryAddValue(pubd, kSecReturnRef, kCFBooleanTrue);
+               CFDictionaryAddValue(privd, kSecClass, kSecClassKey);
+               CFDictionaryAddValue(privd, kSecReturnRef, kCFBooleanTrue);
+        CFDictionaryAddValue(privd, kSecAttrCanSign, kCFBooleanTrue);
+               ok_status(SecItemCopyMatching(pubd, (CFTypeRef *)&pubKey2),
+                       "retrieve pub key by label");
+               ok_status(SecItemCopyMatching(privd, (CFTypeRef *)&privKey2),
+                       "retrieve priv key by label and kSecAttrCanSign");
+
+               /* Sign something. */
+               uint8_t something[50] = {0x80, 0xbe, 0xef, 0xba, 0xd0, };
+               uint8_t sig[keySizeInBytes];
+               size_t sigLen = keySizeInBytes;
+               ok_status(SecKeyRawSign(privKey2, kSecPaddingPKCS1,
+                       something, sizeof(something), sig, &sigLen), "sign something");
+               ok_status(SecKeyRawVerify(pubKey2, kSecPaddingPKCS1,
+                       something, sizeof(something), sig, sigLen), "verify sig on something");
+
+#if TARGET_OS_IPHONE
+        /* SecKeyEncrypt does not return errSecParam on OS X in that case */
+        sigLen = keySizeInBytes;
+               is_status(SecKeyEncrypt(pubKey2, kSecPaddingPKCS1SHA1,
+                       something, sizeof(something), sig, &sigLen), errSecParam,
+            "encrypt something with invalid padding");
+#endif
+
+               /* Cleanup. */
+               CFReleaseNull(pubKey2);
+               CFReleaseNull(privKey2);
+
+        /* delete from keychain - note: do it before releasing publicName and privateName
+         because pubd and privd have no retain/release callbacks */
+        ok_status(SecItemDelete(pubd), "delete generated pub key");
+        ok_status(SecItemDelete(privd), "delete generated priv key");
+       }
+
+       /* Cleanup. */
+       CFReleaseNull(pubKey);
+       CFReleaseNull(privKey);
+
+    CFReleaseNull(publicName);
+    CFReleaseNull(privateName);
+
+       CFRelease(pubd);
+       CFRelease(privd);
+}
+
+/* Test basic add delete update copy matching stuff. */
+#define kTestCount ((2 * kKeyGenTestCount) + kKeyGen2TestCount)
+static void tests(void)
+{
+       /* Comment out lines below for testing generating all common key sizes,
+          disabled now for speed reasons. */
+       //testkeygen(512);
+       //testkeygen(768);
+       testkeygen(1024);
+       testkeygen(2056); // Stranged sized for edge cases in padding.
+       //testkeygen(2048);
+       //testkeygen(4096);
+
+    testkeygen2(1024); // lots of FAIL!
+}
+
+int kc_40_seckey(int argc, char *const *argv)
+{
+       plan_tests(kTestCount);
+
+       tests();
+
+       return 0;
+}
diff --git a/libsecurity_keychain/regressions/kc-41-sececkey.c b/libsecurity_keychain/regressions/kc-41-sececkey.c
new file mode 100644 (file)
index 0000000..0e6be61
--- /dev/null
@@ -0,0 +1,343 @@
+//
+//  si-41-sececkey.c
+//  regressions
+//
+//  Created by Mitch Adler on 5/20/11.
+//  Copyright 2011 Apple Inc. All rights reserved.
+//
+
+/*
+ *  si-40-seckey.c
+ *  Security
+ *
+ *  Created by Michael Brouwer on 1/29/07.
+ *  Copyright (c) 2007-2009 Apple Inc. All Rights Reserved.
+ *
+ */
+#include <TargetConditionals.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/Security.h>
+#include <Security/SecKeyPriv.h>
+
+#if 0
+#include <Security/SecCertificate.h>
+#include <Security/SecCertificateInternal.h>
+#include <Security/SecKey.h>
+#include <Security/SecKeyPriv.h>
+#include <Security/SecItem.h>
+#include <Security/SecAsn1Types.h>
+#include <Security/oidsalg.h>
+#include <Security/SecureTransport.h>
+#include <Security/SecRandom.h>
+#include <CommonCrypto/CommonDigest.h>
+#include <libDER/libDER.h>
+#include <stdlib.h>
+#include <unistd.h>
+#endif
+
+
+#include "keychain_regressions.h"
+#include "utilities/SecCFRelease.h"
+
+
+#if TARGET_OS_IPHONE
+static void testdigestandsignalg(SecKeyRef privKey, SecKeyRef pubKey, const SecAsn1AlgId *algId) {
+    uint8_t dataToDigest[256];
+    size_t dataToDigestLen = sizeof(dataToDigest);
+    size_t sigLen = SecKeyGetSize(privKey, kSecKeySignatureSize);
+    uint8_t sig[sigLen];
+
+    DERItem oid;
+    oid.length = algId->algorithm.Length;
+    oid.data = algId->algorithm.Data;
+
+    /* Get the oid in decimal for display purposes. */
+    CFStringRef oidStr = SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault, &oid);
+       char oidBuf[40];
+    CFStringGetCString(oidStr, oidBuf, sizeof(oidBuf), kCFStringEncodingUTF8);
+    CFRelease(oidStr);
+
+SKIP: {
+    OSStatus status;
+
+    /* Time to sign. */
+    ok_status(status = SecKeyDigestAndSign(privKey, algId, dataToDigest, dataToDigestLen,
+                                           sig, &sigLen),
+              "digest and sign %s with %ld bit RSA key", oidBuf, sigLen * 8);
+
+    skip("SecKeyDigestAndSign failed", 3, status == errSecSuccess);
+
+    /* Verify the signature we just made. */
+    ok_status(SecKeyDigestAndVerify(pubKey, algId, dataToDigest, dataToDigestLen,
+                                    sig, sigLen), "digest and verify");
+    /* Invalidate the signature. */
+    sig[0] ^= 0xff;
+    is_status(SecKeyDigestAndVerify(pubKey, algId, dataToDigest, dataToDigestLen,
+                                    sig, sigLen), errSSLCrypto, "digest and verify bad sig");
+    sig[0] ^= 0xff;
+    dataToDigest[0] ^= 0xff;
+    is_status(SecKeyDigestAndVerify(pubKey, algId, dataToDigest, dataToDigestLen,
+                                    sig, sigLen), errSSLCrypto, "digest and verify bad digest");
+}
+}
+
+static void testdigestandsign(SecKeyRef privKey, SecKeyRef pubKey) {
+    static const SecAsn1Oid *oids[] = {
+        &CSSMOID_ECDSA_WithSHA1,
+#if 0
+        &CSSMOID_ECDSA_WithSHA224,
+        &CSSMOID_ECDSA_WithSHA256,
+        &CSSMOID_ECDSA_WithSHA384,
+        &CSSMOID_ECDSA_WithSHA512,
+#endif
+    };
+
+    uint32_t ix;
+    SecAsn1AlgId algId = {};
+    for (ix = 0; ix < sizeof(oids) / sizeof(*oids); ++ix) {
+        if (oids[ix]) {
+            algId.algorithm = *oids[ix];
+        } else {
+            algId.algorithm.Length = 0;
+            algId.algorithm.Data = NULL;
+        }
+
+        testdigestandsignalg(privKey, pubKey, &algId);
+    }
+}
+#endif
+
+
+#if !TARGET_OS_IPHONE
+/* This is part of Security.framework on iOS */
+
+enum {
+    // kSecKeyKeySizeInBits        = 0, // already exists on osx
+    kSecKeySignatureSize        = 101,
+    kSecKeyEncryptedDataSize    = 102,
+    // More might belong here, but we aren't settled on how
+    // to take into account padding and/or digest types.
+};
+
+static
+size_t SecKeyGetSize(SecKeyRef key, int whichSize)
+{
+    /* SecKeyGetBlockSize return the signature size on OS X -- smh */
+    size_t result = SecKeyGetBlockSize(key);
+
+    result = (result - 2)/2 - 3;
+
+    /* in this test, this is always an ECDSA key */
+    switch (whichSize) {
+        case kSecKeyEncryptedDataSize:
+            result = 0;
+            break;
+        case kSecKeySignatureSize:
+            result = (result >= 66 ? 9 : 8) + 2 * result;
+            break;
+        case kSecKeyKeySizeInBits:
+            if (result >= 66)
+                return 521;
+    }
+
+    if (whichSize == kSecKeyKeySizeInBits)
+        result *= 8;
+
+    return result;
+
+}
+#endif
+
+
+static void testkeygen(size_t keySizeInBits) {
+       SecKeyRef pubKey = NULL, privKey = NULL;
+       size_t keySizeInBytes = (keySizeInBits + 7) / 8;
+       CFNumberRef kzib;
+
+       kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keySizeInBits);
+       CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+       CFDictionaryAddValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeEC);
+       CFDictionaryAddValue(kgp, kSecAttrKeySizeInBits, kzib);
+
+       OSStatus status;
+       ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
+              "Generate %ld bit (%ld byte) EC keypair", keySizeInBits,
+              keySizeInBytes);
+       CFRelease(kzib);
+       CFRelease(kgp);
+
+SKIP: {
+    skip("keygen failed", 8, status == errSecSuccess);
+    ok(pubKey, "pubkey returned");
+    ok(privKey, "privKey returned");
+    is(SecKeyGetSize(pubKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "public key size is ok");
+    is(SecKeyGetSize(privKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "private key size is ok");
+
+    /* Sign something. */
+    uint8_t something[20] = {0x80, 0xbe, 0xef, 0xba, 0xd0, };
+    uint8_t sig[8+2*keySizeInBytes];
+    size_t sigLen = sizeof(sig);
+    ok_status(SecKeyRawSign(privKey, kSecPaddingNone,
+                            something, sizeof(something), sig, &sigLen), "sign something");
+    ok_status(SecKeyRawVerify(pubKey, kSecPaddingNone,
+                              something, sizeof(something), sig, sigLen), "verify sig on something");
+
+#if TARGET_OS_IPHONE
+    testdigestandsign(privKey, pubKey);
+#endif
+
+    const void *privkeys[] = {
+        kSecValueRef
+    };
+    const void *privvalues[] = {
+        privKey
+    };
+    CFDictionaryRef privitem = CFDictionaryCreate(NULL, privkeys, privvalues,
+                                                  sizeof(privkeys) / sizeof(*privkeys), NULL, NULL);
+#if TARGET_OS_IPHONE
+    ok_status(SecItemAdd(privitem, NULL), "add private key");
+#endif
+    ok_status(SecItemDelete(privitem), "delete private key");
+    CFReleaseNull(privitem);
+
+    const void *pubkeys[] = {
+        kSecValueRef
+    };
+    const void *pubvalues[] = {
+        pubKey
+    };
+    CFDictionaryRef pubitem = CFDictionaryCreate(NULL, pubkeys, pubvalues,
+                                                 sizeof(pubkeys) / sizeof(*pubkeys), NULL, NULL);
+#if TARGET_OS_IPHONE
+    ok_status(SecItemAdd(pubitem, NULL), "add public key");
+#endif
+    ok_status(SecItemDelete(pubitem), "delete public key");
+    CFReleaseNull(pubitem);
+
+    /* Cleanup. */
+    CFReleaseNull(pubKey);
+    CFReleaseNull(privKey);
+}
+}
+
+
+static void testkeygen2(size_t keySizeInBits) {
+       SecKeyRef pubKey = NULL, privKey = NULL;
+       size_t keySizeInBytes = (keySizeInBits + 7) / 8;
+       CFNumberRef kzib;
+
+    CFUUIDRef ourUUID = CFUUIDCreate(kCFAllocatorDefault);
+    CFStringRef uuidString = CFUUIDCreateString(kCFAllocatorDefault, ourUUID);
+    CFMutableStringRef publicName = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, uuidString);
+    CFMutableStringRef privateName = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, uuidString);
+
+    CFReleaseNull(ourUUID);
+    CFReleaseNull(uuidString);
+
+    CFStringAppend(publicName, CFSTR("-Public-41"));
+    CFStringAppend(privateName, CFSTR("-Private-41"));
+
+       CFMutableDictionaryRef pubd = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+       CFMutableDictionaryRef privd = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+       CFDictionaryAddValue(pubd, kSecAttrLabel, publicName);
+       CFDictionaryAddValue(privd, kSecAttrLabel, privateName);
+
+       kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keySizeInBits);
+       CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+       CFDictionaryAddValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeEC);
+       CFDictionaryAddValue(kgp, kSecAttrKeySizeInBits, kzib);
+       CFDictionaryAddValue(kgp, kSecAttrIsPermanent, kCFBooleanTrue);
+       CFDictionaryAddValue(kgp, kSecPublicKeyAttrs, pubd);
+       CFDictionaryAddValue(kgp, kSecPrivateKeyAttrs, privd);
+
+       OSStatus status;
+       ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
+              "Generate %ld bit (%ld byte) persistent RSA keypair",
+              keySizeInBits, keySizeInBytes);
+       CFRelease(kzib);
+       CFRelease(kgp);
+
+SKIP: {
+    skip("keygen failed", 8, status == errSecSuccess);
+    ok(pubKey, "pubkey returned");
+    ok(privKey, "privKey returned");
+    is(SecKeyGetSize(pubKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "public key size is ok");
+    is(SecKeyGetSize(privKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "private key size is ok");
+
+    SecKeyRef pubKey2, privKey2;
+    CFDictionaryAddValue(pubd, kSecClass, kSecClassKey);
+    CFDictionaryAddValue(pubd, kSecReturnRef, kCFBooleanTrue);
+    CFDictionaryAddValue(privd, kSecClass, kSecClassKey);
+    CFDictionaryAddValue(privd, kSecReturnRef, kCFBooleanTrue);
+    CFDictionaryAddValue(privd, kSecAttrCanSign, kCFBooleanTrue);
+    ok_status(SecItemCopyMatching(pubd, (CFTypeRef *)&pubKey2),
+              "retrieve pub key by label");
+    ok(pubKey2, "got valid object");
+    ok_status(SecItemCopyMatching(privd, (CFTypeRef *)&privKey2),
+              "retrieve priv key by label and kSecAttrCanSign");
+    ok(privKey2, "got valid object");
+
+    /* Sign something. */
+    uint8_t something[20] = {0x80, 0xbe, 0xef, 0xba, 0xd0, };
+    size_t sigLen = SecKeyGetSize(privKey2, kSecKeySignatureSize);
+    uint8_t sig[sigLen];
+    ok_status(SecKeyRawSign(privKey2, kSecPaddingPKCS1,
+                            something, sizeof(something), sig, &sigLen), "sign something");
+    ok_status(SecKeyRawVerify(pubKey2, kSecPaddingPKCS1,
+                              something, sizeof(something), sig, sigLen), "verify sig on something");
+
+    /* Cleanup. */
+    CFReleaseNull(pubKey2);
+    CFReleaseNull(privKey2);
+}
+
+    /* delete from keychain - note: do it before releasing publicName and privateName
+       because pubd and privd have no retain/release callbacks */
+    ok_status(SecItemDelete(pubd), "delete generated pub key");
+    ok_status(SecItemDelete(privd), "delete generated priv key");
+
+       /* Cleanup. */
+       CFReleaseNull(pubKey);
+       CFReleaseNull(privKey);
+
+    CFReleaseNull(publicName);
+    CFReleaseNull(privateName);
+
+       CFRelease(pubd);
+       CFRelease(privd);
+}
+
+
+/* Test basic add delete update copy matching stuff. */
+static void tests(void)
+{
+       testkeygen(192);
+#if TARGET_OS_IPHONE
+       testkeygen(224);
+#endif
+       testkeygen(256);
+       testkeygen(384);
+       testkeygen(521);
+
+    testkeygen2(192);
+#if TARGET_OS_IPHONE
+    testkeygen2(224);
+#endif
+       testkeygen2(256);
+       testkeygen2(384);
+       testkeygen2(521);
+
+}
+
+int kc_41_sececkey(int argc, char *const *argv)
+{
+#if TARGET_OS_IPHONE
+       plan_tests(140);
+#else
+       plan_tests(88);
+#endif
+
+       tests();
+
+       return 0;
+}
diff --git a/libsecurity_keychain/regressions/keychain_regressions.h b/libsecurity_keychain/regressions/keychain_regressions.h
new file mode 100644 (file)
index 0000000..97e2279
--- /dev/null
@@ -0,0 +1,9 @@
+/* To add a test:
+ 1) add it here
+ 2) Add it as command line argument for SecurityTest.app in the Release and Debug schemes
+ */
+#include <test/testmore.h>
+
+ONE_TEST(kc_40_seckey)
+ONE_TEST(kc_41_sececkey)
+ONE_TEST(si_33_keychain_backup)
diff --git a/libsecurity_keychain/regressions/si-33-keychain-backup.c b/libsecurity_keychain/regressions/si-33-keychain-backup.c
new file mode 100644 (file)
index 0000000..f48d626
--- /dev/null
@@ -0,0 +1,91 @@
+//
+//  si-33-keychain-backup.c
+//  libsecurity_keychain
+//
+//  Created by Wade Benson on 4/16/13.
+//
+//
+
+#include <TargetConditionals.h>
+#include <stdio.h>
+
+#include "keychain_regressions.h"
+#include <Security/SecBase.h>
+#include <Security/SecItem.h>
+#include <Security/SecItemPriv.h>
+#include <libaks.h>
+#include <AssertMacros.h>
+
+
+static CFDataRef create_keybag(keybag_handle_t bag_type, CFDataRef password)
+{
+    keybag_handle_t handle = bad_keybag_handle;
+    
+    if (aks_create_bag(NULL, 0, bag_type, &handle) == 0) {
+        void * keybag = NULL;
+        int keybag_size = 0;
+        if (aks_save_bag(handle, &keybag, &keybag_size) == 0) {
+            return CFDataCreate(kCFAllocatorDefault, keybag, keybag_size);
+        }
+    }
+    
+    return CFDataCreate(kCFAllocatorDefault, NULL, 0);
+}
+
+/* Test low level keychain migration from device to device interface. */
+static void tests(void)
+{
+    int v_eighty = 80;
+    CFNumberRef eighty = CFNumberCreate(NULL, kCFNumberSInt32Type, &v_eighty);
+    const char *v_data = "test";
+    CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data));
+    CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFTypeRef result = NULL;
+    CFDictionaryAddValue(query, kSecClass, kSecClassInternetPassword);
+    CFDictionaryAddValue(query, kSecAttrServer, CFSTR("members.spamcop.net"));
+    CFDictionaryAddValue(query, kSecAttrAccount, CFSTR("smith"));
+    CFDictionaryAddValue(query, kSecAttrPort, eighty);
+    CFDictionaryAddValue(query, kSecAttrProtocol, kSecAttrProtocolHTTP);
+    CFDictionaryAddValue(query, kSecAttrAuthenticationType, kSecAttrAuthenticationTypeDefault);
+    CFDictionaryAddValue(query, kSecValueData, pwdata);
+    CFDictionaryAddValue(query, kSecAttrSynchronizable, kCFBooleanTrue);
+    
+    CFDataRef keybag = NULL, password = NULL;
+    
+    keybag = create_keybag(kAppleKeyStoreAsymmetricBackupBag, password);
+    
+    SecItemDelete(query);
+    
+    // add syncable item
+    ok_status(SecItemAdd(query, NULL), "add internet password");
+    
+    ok_status(SecItemCopyMatching(query, &result), "find item we are about to destroy");
+    if (result) { CFRelease(result); result = NULL; }
+
+    CFDictionaryRef backup = NULL;
+    
+    ok_status(_SecKeychainBackupSyncable(keybag, password, NULL, &backup), "export items");
+    
+    ok_status(SecItemDelete(query), "delete item we backed up");
+    is_status(SecItemCopyMatching(query, &result), errSecItemNotFound, "find item we are about to destroy");
+    if (result) { CFRelease(result); result = NULL; }
+    
+    ok_status(_SecKeychainRestoreSyncable(keybag, password, backup), "import items");
+    
+    ok_status(SecItemCopyMatching(query, &result), "find restored item");
+    if (result) { CFRelease(result); result = NULL; }
+    
+    ok_status(SecItemDelete(query), "delete restored item");
+    
+    if (backup) { CFRelease(backup); }
+}
+
+int si_33_keychain_backup(int argc, char *const *argv)
+{
+       plan_tests(8);
+    
+    
+       tests();
+    
+       return 0;
+}
index cac30d545b83600168dfd8299ac07f1d2f341f1a..198fd005e80e85c7a0bf4721f7ec8685607893be 100644 (file)
@@ -60,13 +60,14 @@ xpc_object_t home = NULL;
 extern xpc_object_t
 xpc_create_reply_with_format(xpc_object_t original, const char * format, ...);
 
 extern xpc_object_t
 xpc_create_reply_with_format(xpc_object_t original, const char * format, ...);
 
+static
 xpc_object_t create_keychain_search_list_for(xpc_connection_t peer, SecPreferencesDomain domain)
 {
     CFArrayRef keychains = NULL;
     pid_t peer_pid = xpc_connection_get_pid(peer);
     OSStatus status = SecKeychainCopyDomainSearchListFunctionPointer(domain, &keychains);
 xpc_object_t create_keychain_search_list_for(xpc_connection_t peer, SecPreferencesDomain domain)
 {
     CFArrayRef keychains = NULL;
     pid_t peer_pid = xpc_connection_get_pid(peer);
     OSStatus status = SecKeychainCopyDomainSearchListFunctionPointer(domain, &keychains);
-    if (noErr != status) {
-        syslog(LOG_ERR, "Unable to get keychain search list (domain=%d) on behalf of %d, status=0x%lx", domain, peer_pid, status);
+    if (errSecSuccess != status) {
+        syslog(LOG_ERR, "Unable to get keychain search list (domain=%d) on behalf of %d, status=0x%lx", domain, peer_pid, (unsigned long)status);
         return NULL;
     }
     
         return NULL;
     }
     
@@ -79,8 +80,8 @@ xpc_object_t create_keychain_search_list_for(xpc_connection_t peer, SecPreferenc
         SecKeychainRef keychain = (SecKeychainRef)CFArrayGetValueAtIndex(keychains, i);
         UInt32 length = MAXPATHLEN;
         OSStatus status = SecKeychainGetPathFunctionPointer(keychain, &length, path);
         SecKeychainRef keychain = (SecKeychainRef)CFArrayGetValueAtIndex(keychains, i);
         UInt32 length = MAXPATHLEN;
         OSStatus status = SecKeychainGetPathFunctionPointer(keychain, &length, path);
-        if (noErr != status) {
-            syslog(LOG_ERR, "Unable to get path for keychain#%ld of %ld on behalf of %d, status=0x%lx", i, n_keychains, peer_pid, status);
+        if (errSecSuccess != status) {
+            syslog(LOG_ERR, "Unable to get path for keychain#%ld of %ld on behalf of %d, status=0x%lx", i, n_keychains, peer_pid, (unsigned long)status);
             continue;
         }
         xpc_object_t path_as_xpc_string = xpc_string_create(path);
             continue;
         }
         xpc_object_t path_as_xpc_string = xpc_string_create(path);
@@ -91,11 +92,13 @@ xpc_object_t create_keychain_search_list_for(xpc_connection_t peer, SecPreferenc
     return paths;
 }
 
     return paths;
 }
 
+static
 bool keychain_domain_needs_writes(const char *domain_name)
 {
        return (0 == strcmp("kSecPreferencesDomainUser", domain_name) || 0 == strcmp("kSecPreferencesDomainDynamic", domain_name));
 }
 
 bool keychain_domain_needs_writes(const char *domain_name)
 {
        return (0 == strcmp("kSecPreferencesDomainUser", domain_name) || 0 == strcmp("kSecPreferencesDomainDynamic", domain_name));
 }
 
+static
 void _set_keychain_search_lists_for_domain(xpc_connection_t peer, xpc_object_t all_domains, char *domain_name, SecPreferencesDomain domain_enum)
 {
     xpc_object_t keychains_for_domain = create_keychain_search_list_for(peer, domain_enum);
 void _set_keychain_search_lists_for_domain(xpc_connection_t peer, xpc_object_t all_domains, char *domain_name, SecPreferencesDomain domain_enum)
 {
     xpc_object_t keychains_for_domain = create_keychain_search_list_for(peer, domain_enum);
@@ -109,6 +112,7 @@ void _set_keychain_search_lists_for_domain(xpc_connection_t peer, xpc_object_t a
 
 #define SET_KEYCHAIN_SEARCH_LISTS_FOR_DOMAIN(peer, all_domains, domain) _set_keychain_search_lists_for_domain(peer, all_domains, #domain, domain);
 
 
 #define SET_KEYCHAIN_SEARCH_LISTS_FOR_DOMAIN(peer, all_domains, domain) _set_keychain_search_lists_for_domain(peer, all_domains, #domain, domain);
 
+static
 xpc_object_t create_keychain_search_lists(xpc_connection_t peer)
 {
        xpc_object_t all_domains = xpc_dictionary_create(NULL, NULL, 0);
 xpc_object_t create_keychain_search_lists(xpc_connection_t peer)
 {
        xpc_object_t all_domains = xpc_dictionary_create(NULL, NULL, 0);
@@ -122,6 +126,7 @@ xpc_object_t create_keychain_search_lists(xpc_connection_t peer)
 }
 
 
 }
 
 
+static
 xpc_object_t create_keychain_and_lock_paths(xpc_connection_t peer, xpc_object_t keychain_path_dict)
 {
        pid_t peer_pid = xpc_connection_get_pid(peer);
 xpc_object_t create_keychain_and_lock_paths(xpc_connection_t peer, xpc_object_t keychain_path_dict)
 {
        pid_t peer_pid = xpc_connection_get_pid(peer);
@@ -161,7 +166,7 @@ xpc_object_t create_keychain_and_lock_paths(xpc_connection_t peer, xpc_object_t
             strcpy(buffer, path);
             
             if (path != NULL) {
             strcpy(buffer, path);
             
             if (path != NULL) {
-                int i = strlen(buffer) - 1;
+                ptrdiff_t i = strlen(buffer) - 1;
                 while (i >= 0 && buffer[i] != '/') {
                     i -= 1;
                 }
                 while (i >= 0 && buffer[i] != '/') {
                     i -= 1;
                 }
@@ -191,7 +196,7 @@ xpc_object_t create_keychain_and_lock_paths(xpc_connection_t peer, xpc_object_t
 
             CC_SHA1_CTX sha1Context;
             CC_SHA1_Init(&sha1Context);
 
             CC_SHA1_CTX sha1Context;
             CC_SHA1_Init(&sha1Context);
-            CC_SHA1_Update(&sha1Context, base, strlen(base));
+            CC_SHA1_Update(&sha1Context, base, (CC_LONG)strlen(base));
             
             unsigned char sha1_result_bytes[CC_SHA1_DIGEST_LENGTH];
             
             
             unsigned char sha1_result_bytes[CC_SHA1_DIGEST_LENGTH];
             
@@ -211,6 +216,7 @@ xpc_object_t create_keychain_and_lock_paths(xpc_connection_t peer, xpc_object_t
        return return_paths_dict;
 }
 
        return return_paths_dict;
 }
 
+static
 xpc_object_t create_one_sandbox_extension(xpc_object_t path, uint64_t extension_flags)
 {
        char *sandbox_extension = NULL;
 xpc_object_t create_one_sandbox_extension(xpc_object_t path, uint64_t extension_flags)
 {
        char *sandbox_extension = NULL;
@@ -225,6 +231,7 @@ xpc_object_t create_one_sandbox_extension(xpc_object_t path, uint64_t extension_
        return NULL;
 }
 
        return NULL;
 }
 
+static
 xpc_object_t create_all_sandbox_extensions(xpc_object_t path_dict)
 {
     xpc_object_t extensions = xpc_array_create(NULL, 0);
 xpc_object_t create_all_sandbox_extensions(xpc_object_t path_dict)
 {
     xpc_object_t extensions = xpc_array_create(NULL, 0);
@@ -254,6 +261,7 @@ xpc_object_t create_all_sandbox_extensions(xpc_object_t path_dict)
     return extensions;
 }
 
     return extensions;
 }
 
+static
 void handle_request_event(struct connection_info *info, xpc_object_t event)
 {
     xpc_connection_t peer = xpc_dictionary_get_connection(event);
 void handle_request_event(struct connection_info *info, xpc_object_t event)
 {
     xpc_connection_t peer = xpc_dictionary_get_connection(event);
@@ -322,6 +330,7 @@ void handle_request_event(struct connection_info *info, xpc_object_t event)
     }
 }
 
     }
 }
 
+static
 void finalize_connection(void *not_used)
 {
 #ifdef XPC_HANDLES_IDLE_TIMEOUT
 void finalize_connection(void *not_used)
 {
 #ifdef XPC_HANDLES_IDLE_TIMEOUT
@@ -329,7 +338,8 @@ void finalize_connection(void *not_used)
 #endif
 }
 
 #endif
 }
 
-void handle_connection_event(const xpc_connection_t peer) 
+static
+void handle_connection_event(const xpc_connection_t peer)
 {
 #ifndef XPC_HANDLES_IDLE_TIMEOUT
     __sync_add_and_fetch(&current_connections, 1);
 {
 #ifndef XPC_HANDLES_IDLE_TIMEOUT
     __sync_add_and_fetch(&current_connections, 1);
@@ -376,10 +386,10 @@ int main(int argc, const char *argv[])
         home_dir = pwd->pw_dir; // look it up in directory services, sort of...
     }
 
         home_dir = pwd->pw_dir; // look it up in directory services, sort of...
     }
 
-    int home_dir_length = strlen(home_dir);
-    int path_to_plist_length = strlen(g_path_to_plist);
+    size_t home_dir_length = strlen(home_dir);
+    size_t path_to_plist_length = strlen(g_path_to_plist);
     
     
-    int total_length = home_dir_length + path_to_plist_length + 1; // compensate for terminating zero
+    size_t total_length = home_dir_length + path_to_plist_length + 1; // compensate for terminating zero
     if (total_length > PATH_MAX) {
         // someone is spoofing us, just exit
         return -1;
     if (total_length > PATH_MAX) {
         // someone is spoofing us, just exit
         return -1;
index 90195a677466691ef9177a5884a162c4b8ee78aa..779283245d87a47ecab09292a8e12efe14eab194 100644 (file)
@@ -116,7 +116,7 @@ static void WriteFileSystemItemHeader (CFMutableDataRef data, const FileSystemEn
        // write the name
        const char* name = fsi->GetName ();
        secdebug ("manifest", "\tAdding header for %s", name);
        // write the name
        const char* name = fsi->GetName ();
        secdebug ("manifest", "\tAdding header for %s", name);
-       int len = strlen (name);
+       uint16_t len = (uint16_t)strlen (name);
        AppendUInt16 (data, len);
        CFDataAppendBytes (data, (UInt8*) name, len);
        AppendUInt32 (data, fsi->GetUID ());
        AppendUInt16 (data, len);
        CFDataAppendBytes (data, (UInt8*) name, len);
        AppendUInt32 (data, fsi->GetUID ());
@@ -135,8 +135,8 @@ AppleManifest::AppleManifest ()
 AppleManifest::~AppleManifest ()
 {
        // release our interest in the signers
 AppleManifest::~AppleManifest ()
 {
        // release our interest in the signers
-       int signerCount = mSignerList.size ();
-       
+       int signerCount = (int)mSignerList.size ();
+
        int i;
        for (i = 0; i < signerCount; ++i)
        {
        int i;
        for (i = 0; i < signerCount; ++i)
        {
@@ -303,7 +303,7 @@ void AppleManifest::CreateManifest (CFMutableDataRef manifest, ManifestInternal&
 void AppleManifest::AddSignersToCmsMessage (SecCmsMessageRef cmsMessage, SecCmsSignedDataRef signedData)
 {
        // add signers for each of our signers
 void AppleManifest::AddSignersToCmsMessage (SecCmsMessageRef cmsMessage, SecCmsSignedDataRef signedData)
 {
        // add signers for each of our signers
-       int numSigners = mSignerList.size ();
+       int numSigners = (int)mSignerList.size ();
        
        int i;
        for (i = 0; i < numSigners; ++i)
        
        int i;
        for (i = 0; i < numSigners; ++i)
@@ -442,7 +442,7 @@ static u_int64_t ReconstructUInt64 (uint32& finger, const uint8* data)
 static u_int32_t ReconstructUInt32 (uint32& finger, const uint8* data)
 {
        unsigned i;
 static u_int32_t ReconstructUInt32 (uint32& finger, const uint8* data)
 {
        unsigned i;
-       u_int64_t r = 0;
+       u_int32_t r = 0;
        
        for (i = 0; i < sizeof (u_int32_t); ++i)
        {
        
        for (i = 0; i < sizeof (u_int32_t); ++i)
        {
@@ -457,8 +457,8 @@ static u_int32_t ReconstructUInt32 (uint32& finger, const uint8* data)
 static u_int16_t ReconstructUInt16 (uint32& finger, const uint8* data)
 {
        unsigned i;
 static u_int16_t ReconstructUInt16 (uint32& finger, const uint8* data)
 {
        unsigned i;
-       u_int64_t r = 0;
-       
+       u_int16_t r = 0;
+
        for (i = 0; i < sizeof (u_int16_t); ++i)
        {
                r = (r << 8) | data[finger++];
        for (i = 0; i < sizeof (u_int16_t); ++i)
        {
                r = (r << 8) | data[finger++];
@@ -514,7 +514,7 @@ void AppleManifest::ReconstructDataBlob (uint32 &finger, const uint8* data, Mani
        secdebug ("manifest", "Reconstructing data blob.");
        item = new ManifestDataBlobItem ();
        u_int64_t length = ReconstructUInt64 (finger, data);
        secdebug ("manifest", "Reconstructing data blob.");
        item = new ManifestDataBlobItem ();
        u_int64_t length = ReconstructUInt64 (finger, data);
-       item->SetLength (length);
+       item->SetLength ((size_t)length);
        item->SetDigest ((SHA1Digest*) (data + finger));
        finger += kSHA1DigestSize;
 }
        item->SetDigest ((SHA1Digest*) (data + finger));
        finger += kSHA1DigestSize;
 }
@@ -586,7 +586,8 @@ void AppleManifest::ReconstructManifestItemList (uint32 &finger, const uint8* da
 {
        uint32 start = finger;
        u_int64_t length = ReconstructUInt64 (finger, data);
 {
        uint32 start = finger;
        u_int64_t length = ReconstructUInt64 (finger, data);
-       uint32 end = start + length;
+#warning Casting from uint64 to uint32, this is ripe for overflow.
+       uint32 end = (uint32)(start + length);
        
        while (finger < end)
        {
        
        while (finger < end)
        {
@@ -722,7 +723,7 @@ void AppleManifest::Verify (CFDataRef data, SecManifestTrustSetupCallback setupC
                        MacOSError::check (result);
                        
                        result = SecPolicySearchCopyNext (search, &policy);
                        MacOSError::check (result);
                        
                        result = SecPolicySearchCopyNext (search, &policy);
-                       if (result != noErr)
+                       if (result != errSecSuccess)
                        {
                                MacOSError::throwMe (errSecManifestNoPolicy);
                        }
                        {
                                MacOSError::throwMe (errSecManifestNoPolicy);
                        }
@@ -797,7 +798,7 @@ void AppleManifest::Verify (CFDataRef data, SecManifestTrustSetupCallback setupC
                                        }
                                        
                                        result = SecTrustEvaluate (trustRef, &resultType);
                                        }
                                        
                                        result = SecTrustEvaluate (trustRef, &resultType);
-                                       if (result != noErr)
+                                       if (result != errSecSuccess)
                                        {
                                                MacOSError::throwMe (result);
                                        }
                                        {
                                                MacOSError::throwMe (result);
                                        }
@@ -827,7 +828,7 @@ void AppleManifest::Verify (CFDataRef data, SecManifestTrustSetupCallback setupC
                if (manifest != NULL)
                {
                        CSSM_DATA_PTR message = SecCmsMessageGetContent (cmsMessage);
                if (manifest != NULL)
                {
                        CSSM_DATA_PTR message = SecCmsMessageGetContent (cmsMessage);
-                       ReconstructManifest (message->Data, message->Length, *manifest);
+                       ReconstructManifest (message->Data, (uint32)message->Length, *manifest);
                }
                
                SecCmsMessageDestroy (cmsMessage);
                }
                
                SecCmsMessageDestroy (cmsMessage);
index 43c91ed9b5b547c199baa24c1ceee5feccf1fd97..a0bd62f324441e83170e5caab916e95034f13b78 100644 (file)
@@ -26,7 +26,6 @@
 
 #include <Security/Security.h>
 #include <security_utilities/security_utilities.h>
 
 #include <Security/Security.h>
 #include <security_utilities/security_utilities.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 #include <security_cdsa_utilities/cssmbridge.h>
 #include <Security/cssmapplePriv.h>
 
 #include <security_cdsa_utilities/cssmbridge.h>
 #include <Security/cssmapplePriv.h>
 
@@ -132,13 +131,13 @@ SecPolicyRef Download::GetPolicy ()
 
        // get the policy for resource signing
        result = SecPolicySearchCreate (CSSM_CERT_X_509v3, &CSSMOID_APPLE_TP_RESOURCE_SIGN, NULL, &search);
 
        // get the policy for resource signing
        result = SecPolicySearchCreate (CSSM_CERT_X_509v3, &CSSMOID_APPLE_TP_RESOURCE_SIGN, NULL, &search);
-       if (result != noErr)
+       if (result != errSecSuccess)
        {
                MacOSError::throwMe (result);
        }
        
        result = SecPolicySearchCopyNext (search, &policy);
        {
                MacOSError::throwMe (result);
        }
        
        result = SecPolicySearchCopyNext (search, &policy);
-       if (result != noErr)
+       if (result != errSecSuccess)
        {
                MacOSError::throwMe (result);
        }
        {
                MacOSError::throwMe (result);
        }
@@ -276,7 +275,7 @@ void Download::Initialize (CFDataRef ticket,
                        }
                        
                        result = SecTrustEvaluate (trustRef, &resultType);
                        }
                        
                        result = SecTrustEvaluate (trustRef, &resultType);
-                       if (result != noErr)
+                       if (result != errSecSuccess)
                        {
                                MacOSError::throwMe (errSecureDownloadInvalidTicket);
                        }
                        {
                                MacOSError::throwMe (errSecureDownloadInvalidTicket);
                        }
@@ -335,7 +334,7 @@ SecCmsMessageRef Download::GetCmsMessageFromData (CFDataRef data)
 }
 
 
 }
 
 
-
+static 
 size_t MinSizeT (size_t a, size_t b)
 {
        // return the smaller of a and b
 size_t MinSizeT (size_t a, size_t b)
 {
        // return the smaller of a and b
@@ -376,7 +375,7 @@ void Download::UpdateWithData (CFDataRef data)
                size_t bytesToHash = MinSizeT (bytesLeftToHash, dataLength);
                
                // hash the data
                size_t bytesToHash = MinSizeT (bytesLeftToHash, dataLength);
                
                // hash the data
-               CC_SHA256_Update (&mSHA256Context, finger, bytesToHash);
+               CC_SHA256_Update (&mSHA256Context, finger, (CC_LONG)bytesToHash);
                
                // update the pointers
                mBytesInCurrentDigest += bytesToHash;
                
                // update the pointers
                mBytesInCurrentDigest += bytesToHash;
index 27a5531d932ee561458b930cc23e66d3b6c43999..e7442d2f04179c693278c246829c417471ccf50c 100644 (file)
@@ -35,7 +35,6 @@
 #include <security_utilities/cfutilities.h>
 #include <fts.h>
 #include <fcntl.h>
 #include <security_utilities/cfutilities.h>
 #include <fts.h>
 #include <fcntl.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 #include <CommonCrypto/CommonDigest.h>
 
 #include "Manifest.h"
 #include <CommonCrypto/CommonDigest.h>
 
 #include "Manifest.h"
@@ -185,7 +184,7 @@ void ManifestItemList::AddDataObject (CFDataRef object)
        const UInt8* data = CFDataGetBytePtr (object);
        CFIndex length = CFDataGetLength (object);
        
        const UInt8* data = CFDataGetBytePtr (object);
        CFIndex length = CFDataGetLength (object);
        
-       CC_SHA1_Update (&digestContext, data, length);
+       CC_SHA1_Update (&digestContext, data, (CC_LONG)length);
        CC_SHA1_Final (digest, &digestContext);
        
        ManifestDataBlobItem* db = new ManifestDataBlobItem ();
        CC_SHA1_Final (digest, &digestContext);
        
        ManifestDataBlobItem* db = new ManifestDataBlobItem ();
@@ -278,7 +277,7 @@ void ManifestItemList::AddObject (CFTypeRef object, CFArrayRef exceptionList)
 void RootItemList::Compare (RootItemList& item, bool compareOwnerAndGroup)
 {
        // the number of items in the list has to be the same
 void RootItemList::Compare (RootItemList& item, bool compareOwnerAndGroup)
 {
        // the number of items in the list has to be the same
-       unsigned numItems = size ();
+       unsigned numItems = (unsigned)size ();
 
        if (numItems != item.size ())
        {
 
        if (numItems != item.size ())
        {
@@ -324,7 +323,7 @@ bool CompareManifestFileItems::operator () (ManifestItem *a, ManifestItem *b)
 
 void FileSystemItemList::Compare (FileSystemItemList &a, bool compareOwnerAndGroup)
 {
 
 void FileSystemItemList::Compare (FileSystemItemList &a, bool compareOwnerAndGroup)
 {
-       unsigned numItems = size ();
+       unsigned numItems = (unsigned)size ();
        
        if (numItems != a.size ())
        {
        
        if (numItems != a.size ())
        {
@@ -372,7 +371,7 @@ void ManifestInternal::CompareManifests (ManifestInternal& m1,  ManifestInternal
 {
        if ((options & ~kSecManifestVerifyOwnerAndGroup) != 0)
        {
 {
        if ((options & ~kSecManifestVerifyOwnerAndGroup) != 0)
        {
-               MacOSError::throwMe (unimpErr); // we don't support these options
+               MacOSError::throwMe (errSecUnimplemented); // we don't support these options
        }
        
        m1.mManifestItems.Compare (m2.mManifestItems, (bool) options & kSecManifestVerifyOwnerAndGroup);
        }
        
        m1.mManifestItems.Compare (m2.mManifestItems, (bool) options & kSecManifestVerifyOwnerAndGroup);
@@ -694,7 +693,7 @@ void ManifestFileItem::ComputeRepresentations (struct stat &st, bool hasAppleDou
                
                resourceForkName = mPath;
                // walk back to find the beginning of the path and insert ._
                
                resourceForkName = mPath;
                // walk back to find the beginning of the path and insert ._
-               int i = resourceForkName.length () - 1;
+                int i = (int)resourceForkName.length () - 1;
                while (i >= 0 && resourceForkName[i] != '/')
                {
                        i -= 1;
                while (i >= 0 && resourceForkName[i] != '/')
                {
                        i -= 1;
@@ -756,7 +755,7 @@ void ManifestFileItem::ComputeDigestForAppleDoubleResourceFork (char* name, SHA1
        }
        
        u_int8_t *buffer = new u_int8_t[st.st_size];
        }
        
        u_int8_t *buffer = new u_int8_t[st.st_size];
-       ssize_t bytesRead = read (fileNo, buffer, st.st_size);
+       ssize_t bytesRead = read (fileNo, buffer, (size_t)st.st_size);
        close (fileNo);
        
        if (bytesRead != st.st_size)
        close (fileNo);
        
        if (bytesRead != st.st_size)
@@ -797,7 +796,7 @@ void ManifestFileItem::ComputeDigestForAppleDoubleResourceFork (char* name, SHA1
        fileLength = length;
 
        // digest the data
        fileLength = length;
 
        // digest the data
-       CC_SHA1_Update (&digestContext, buffer + offset, length);
+       CC_SHA1_Update (&digestContext, buffer + offset, (CC_LONG)length);
        
        // compute the SHA1 hash
        CC_SHA1_Final (digest, &digestContext);
        
        // compute the SHA1 hash
        CC_SHA1_Final (digest, &digestContext);
@@ -822,7 +821,7 @@ void ManifestFileItem::ComputeDigestForFile (char* name, SHA1Digest &digest, siz
                UnixError::throwMe ();
        }
        
                UnixError::throwMe ();
        }
        
-       fileLength = st.st_size;
+       fileLength = (size_t)st.st_size;
 
        if (st.st_size != 0)
        {
 
        if (st.st_size != 0)
        {
@@ -833,7 +832,7 @@ void ManifestFileItem::ComputeDigestForFile (char* name, SHA1Digest &digest, siz
                while ((bytesRead = read (fileNo, buffer, kReadChunkSize)) != 0)
                {
                        // digest the read data
                while ((bytesRead = read (fileNo, buffer, kReadChunkSize)) != 0)
                {
                        // digest the read data
-                       CC_SHA1_Update (&digestContext, buffer, bytesRead);
+                       CC_SHA1_Update (&digestContext, buffer, (CC_LONG)bytesRead);
                }
                
                // compute the SHA1 hash
                }
                
                // compute the SHA1 hash
@@ -1077,7 +1076,7 @@ ManifestSymLinkItem::~ManifestSymLinkItem ()
 void ManifestSymLinkItem::ComputeRepresentation ()
 {
        char path [FILENAME_MAX];
 void ManifestSymLinkItem::ComputeRepresentation ()
 {
        char path [FILENAME_MAX];
-       int result = readlink (mPath.c_str (), path, sizeof (path));
+       int result = (int)readlink (mPath.c_str (), path, sizeof (path));
        secdebug ("manifest", "Read content %s for %s", path, mPath.c_str ());
        
        // create a digest context
        secdebug ("manifest", "Read content %s for %s", path, mPath.c_str ());
        
        // create a digest context
index 8ebc18e85d8a8258a838341eabfa0f8120d19a75..3f5d259120469bcc93d3f0967fc60dcf50dfda3c 100644 (file)
@@ -3,8 +3,7 @@
 #include "Manifest.h"
 #include <security_utilities/seccfobject.h>
 #include <security_cdsa_utilities/cssmbridge.h>
 #include "Manifest.h"
 #include <security_utilities/seccfobject.h>
 #include <security_cdsa_utilities/cssmbridge.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
-
+#include <../sec/Security/SecBase.h>
 /*
  * Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
  * 
 /*
  * Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
  * 
@@ -34,9 +33,9 @@
 #define API_END \
        } \
        catch (const MacOSError &err) { return err.osStatus(); } \
 #define API_END \
        } \
        catch (const MacOSError &err) { return err.osStatus(); } \
-       catch (const std::bad_alloc &) { return memFullErr; } \
-       catch (...) { return internalComponentErr; } \
-    return noErr;
+       catch (const std::bad_alloc &) { return errSecAllocate; } \
+       catch (...) { return errSecInternalComponent; } \
+    return errSecSuccess;
 
 #define API_END_GENERIC_CATCH          } catch (...) { return; }
 
 
 #define API_END_GENERIC_CATCH          } catch (...) { return; }
 
@@ -48,7 +47,7 @@ OSStatus SecManifestGetVersion (UInt32 *version)
 {
        secdebug ("manifest", "SecManifestGetVersion");
        *version = 0x01000000;
 {
        secdebug ("manifest", "SecManifestGetVersion");
        *version = 0x01000000;
-       return noErr;
+       return errSecSuccess;
 }
 
 
 }
 
 
@@ -149,7 +148,7 @@ OSStatus SecManifestCreateSignature(SecManifestRef manifest, UInt32 options, CFD
        
        if (options != 0)
        {
        
        if (options != 0)
        {
-               return unimpErr;
+               return errSecUnimplemented;
        }
        
        // check to see if there is a serializer present
        }
        
        // check to see if there is a serializer present
index dd531c1e6404dc696e894715c78e557a30e45a9c..4d031f18d08d2e4fcdd409cc1fbed1c68312185e 100644 (file)
@@ -23,9 +23,8 @@
 
 #include <Security/Security.h>
 #include <security_utilities/security_utilities.h>
 
 #include <Security/Security.h>
 #include <security_utilities/security_utilities.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 #include <security_cdsa_utilities/cssmbridge.h>
 #include <security_cdsa_utilities/cssmbridge.h>
-
+#include <../sec/Security/SecBase.h>
 #include "Download.h"
 #include "SecureDownload.h"
 
 #include "Download.h"
 #include "SecureDownload.h"
 
@@ -36,9 +35,9 @@
 #define API_END \
        } \
        catch (const MacOSError &err) { return err.osStatus(); } \
 #define API_END \
        } \
        catch (const MacOSError &err) { return err.osStatus(); } \
-       catch (const std::bad_alloc &) { return memFullErr; } \
-       catch (...) { return internalComponentErr; } \
-    return noErr;
+       catch (const std::bad_alloc &) { return errSecAllocate; } \
+       catch (...) { return errSecInternalComponent; } \
+    return errSecSuccess;
 
 #define API_END_GENERIC_CATCH          } catch (...) { return; }
 
 
 #define API_END_GENERIC_CATCH          } catch (...) { return; }
 
index 91930bf4e9b064f78a32571411c09bbcd5fcb966..025346bddb93e1872bea2f9e3be3a91ea204ddf1 100644 (file)
@@ -42,7 +42,7 @@ extern "C" {
                                2:  Pass the ticket to SecureDownloadCreateWithTicket.  On error, call
                                        SecureDownloadGetTrustRef to return data that will help you figure
                                        out why the ticket was bad.
                                2:  Pass the ticket to SecureDownloadCreateWithTicket.  On error, call
                                        SecureDownloadGetTrustRef to return data that will help you figure
                                        out why the ticket was bad.
-                               3:  If SecureDownloadCreateWithTicket returns noErr, call SecureDownloadCopyURLs
+                               3:  If SecureDownloadCreateWithTicket returns errSecSuccess, call SecureDownloadCopyURLs
                                        to return a list of data download locations.  Begin downloading data from
                                        the first URL in the list.  If that download fails, try downloading from
                                        the second URL, and so forth.
                                        to return a list of data download locations.  Begin downloading data from
                                        the first URL in the list.  If that download fails, try downloading from
                                        the second URL, and so forth.
index 3b79d63cde2799424dc42ea0d14b5517b67fbdfd..a12dd14c30a715469feead9cbc7d4b8514870690 100644 (file)
@@ -7,9 +7,9 @@
 //        cc -g -framework CoreFoundation -o $@ $^
 //
 
 //        cc -g -framework CoreFoundation -o $@ $^
 //
 
-#define DEBUG 0
+#define LOCAL_DEBUG 0
 
 
-#if DEBUG
+#if LOCAL_DEBUG
 extern CFDataRef read_data(char* path);
 #endif
 
 extern CFDataRef read_data(char* path);
 #endif
 
@@ -22,7 +22,7 @@ extern CFDataRef read_data(char* path);
 
 struct parseState {
        CFDictionaryRef namespaces; // array of dictionaries of namespace declarations
 
 struct parseState {
        CFDictionaryRef namespaces; // array of dictionaries of namespace declarations
-#if DEBUG
+#if LOCAL_DEBUG
        char* prefix;
 #endif
        CFMutableArrayRef plists;       // array of all resource plists
        char* prefix;
 #endif
        CFMutableArrayRef plists;       // array of all resource plists
@@ -624,7 +624,7 @@ static void _parseXMLNode(const void *value, void *context) {
                                        }
                                }
                        }
                                        }
                                }
                        }
-#if DEBUG
+#if LOCAL_DEBUG
                        cfprintf(stderr, "%sELEM:\t%@\t[%@]\n", state->prefix, name, ns);
 #endif
                }
                        cfprintf(stderr, "%sELEM:\t%@\t[%@]\n", state->prefix, name, ns);
 #endif
                }
@@ -633,7 +633,7 @@ static void _parseXMLNode(const void *value, void *context) {
        } else if (type == kCFXMLNodeTypeWhitespace) {
                // do nothing
        } else {
        } else if (type == kCFXMLNodeTypeWhitespace) {
                // do nothing
        } else {
-#if DEBUG
+#if LOCAL_DEBUG
                CFStringRef str = CFXMLNodeGetString(node);
                cfprintf(stderr, "%s% 4d:\t%@\n", state->prefix, type, str);
 #endif
                CFStringRef str = CFXMLNodeGetString(node);
                cfprintf(stderr, "%s% 4d:\t%@\n", state->prefix, type, str);
 #endif
@@ -645,11 +645,11 @@ static void _parseXMLNode(const void *value, void *context) {
                struct parseState local;
                memcpy(&local, state, sizeof(struct parseState));
                local.namespaces = namespaces;
                struct parseState local;
                memcpy(&local, state, sizeof(struct parseState));
                local.namespaces = namespaces;
-#if DEBUG
+#if LOCAL_DEBUG
                asprintf(&local.prefix, "%s  ", state->prefix);
 #endif
                CFTreeApplyFunctionToChildren(tree, _parseXMLNode, &local);
                asprintf(&local.prefix, "%s  ", state->prefix);
 #endif
                CFTreeApplyFunctionToChildren(tree, _parseXMLNode, &local);
-#if DEBUG
+#if LOCAL_DEBUG
                free(local.prefix);
 #endif
        }
                free(local.prefix);
 #endif
        }
@@ -665,7 +665,7 @@ CFPropertyListRef _SecureDownloadParseTicketXML(CFDataRef xmlData) {
        
        struct parseState state;
        memset(&state, 0, sizeof(state));
        
        struct parseState state;
        memset(&state, 0, sizeof(state));
-#if DEBUG
+#if LOCAL_DEBUG
        state.prefix = "";
 #endif
        state.plists = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
        state.prefix = "";
 #endif
        state.plists = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
@@ -851,7 +851,7 @@ CFDataRef _SecureDownloadCreateTicketXML(CFPropertyListRef plist) {
        return data;
 }
 
        return data;
 }
 
-#if DEBUG
+#if LOCAL_DEBUG
 #include <unistd.h>
 int main(int argc, char* argv[]) {
 
 #include <unistd.h>
 int main(int argc, char* argv[]) {
 
index f2bcc4e48f42af9c73e44a118970d22aa543cbe2..9c983fe6bd7b8b77331d5710b311f675b57577bb 100644 (file)
                0867D690FE84028FC02AAC07 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
                0867D690FE84028FC02AAC07 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0420;
+                               LastUpgradeCheck = 0500;
                        };
                        buildConfigurationList = C27AD39A0987FCDE001272E0 /* Build configuration list for PBXProject "libsecurity_manifest" */;
                        compatibilityVersion = "Xcode 3.2";
                        };
                        buildConfigurationList = C27AD39A0987FCDE001272E0 /* Build configuration list for PBXProject "libsecurity_manifest" */;
                        compatibilityVersion = "Xcode 3.2";
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB31E146F0F07000BF1F3 /* debug.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB31E146F0F07000BF1F3 /* debug.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+                               WARNING_CFLAGS = (
+                                       "-Wno-error=#warnings",
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                                       "$(inherited)",
+                               );
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB320146F0F07000BF1F3 /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB320146F0F07000BF1F3 /* release.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+                               WARNING_CFLAGS = (
+                                       "-Wno-error=#warnings",
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                                       "$(inherited)",
+                               );
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB31F146F0F07000BF1F3 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB31F146F0F07000BF1F3 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB31F146F0F07000BF1F3 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB31F146F0F07000BF1F3 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
index 5cc0f6e4c3197a2b1df404a026b1c3afe6de5602..70892bb4fdc2e73a725dac6de2f7c2fb225a44c8 100644 (file)
@@ -48,7 +48,7 @@ MDSAttrParser::MDSAttrParser(
                mDefaults(NULL)
 {
        /* Only task here is to cook up a CFBundle for the specified path */
                mDefaults(NULL)
 {
        /* Only task here is to cook up a CFBundle for the specified path */
-       unsigned pathLen = strlen(bundlePath);
+       size_t pathLen = strlen(bundlePath);
        CFURLRef url = CFURLCreateFromFileSystemRepresentation(NULL,
                (unsigned char *)bundlePath,
                pathLen,
        CFURLRef url = CFURLCreateFromFileSystemRepresentation(NULL,
                (unsigned char *)bundlePath,
                pathLen,
@@ -218,19 +218,47 @@ void MDSAttrParser::logFileError(
        CFStringRef errStr,             // optional if you have it
        SInt32 *errNo)                  // optional if you have it
 {
        CFStringRef errStr,             // optional if you have it
        SInt32 *errNo)                  // optional if you have it
 {
-       const char *cerrStr = NULL;
        CFStringRef urlStr = CFURLGetString(fileUrl);
        const char *cUrlStr = CFStringGetCStringPtr(urlStr, kCFStringEncodingUTF8);
        CFStringRef urlStr = CFURLGetString(fileUrl);
        const char *cUrlStr = CFStringGetCStringPtr(urlStr, kCFStringEncodingUTF8);
-       
+       char* stringBuffer = NULL;
+    
+    if (cUrlStr == NULL)
+    {
+        CFIndex maxLen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(urlStr), kCFStringEncodingUTF8) + 1;
+        stringBuffer = (char*) malloc(maxLen);
+        CFStringGetCString(urlStr, stringBuffer, maxLen, kCFStringEncodingUTF8);
+        cUrlStr = stringBuffer;
+    }
+    
        if(errStr) {
        if(errStr) {
-               cerrStr = CFStringGetCStringPtr(errStr, kCFStringEncodingUTF8);
+        const char *cerrStr = CFStringGetCStringPtr(errStr, kCFStringEncodingUTF8);
+        char* sbuf2 = NULL;
+        
+        if (cerrStr == NULL)
+        {
+            CFIndex maxLen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(errStr), kCFStringEncodingUTF8) + 1;
+            sbuf2 = (char*) malloc(maxLen);
+            CFStringGetCString(urlStr, sbuf2, maxLen, kCFStringEncodingUTF8);
+            cUrlStr = sbuf2;
+        }
+    
                Syslog::alert("MDS: %s: bundle %s url %s: error %s",
                        op, mPath, cUrlStr, cerrStr);
                Syslog::alert("MDS: %s: bundle %s url %s: error %s",
                        op, mPath, cUrlStr, cerrStr);
+        
+        if (sbuf2 != NULL)
+        {
+            free(sbuf2);
+        }
        }
        else {
                Syslog::alert("MDS: %s: bundle %s url %s: error %d",
        }
        else {
                Syslog::alert("MDS: %s: bundle %s url %s: error %d",
-                       op, mPath, cUrlStr, errNo ? *errNo : 0);
+                       op, mPath, cUrlStr, (int)(errNo ? *errNo : 0));
        }
        }
+    
+    if (stringBuffer != NULL)
+    {
+        free(stringBuffer);
+    }
 }
         
 /*
 }
         
 /*
index eef5e2f4de8267f953a35b723a1125276b673afe..c94a902c44bcc106fc81545b1efcdbcf2f325d13 100644 (file)
@@ -644,7 +644,7 @@ static bool isNumericStr(
 }
 
 /* convert ASCII hex digit - assumed validated already */
 }
 
 /* convert ASCII hex digit - assumed validated already */
-unsigned char hexDigit(
+static unsigned char hexDigit(
        unsigned char d)
 {
        if((d >= '0') && (d <= '9')) {
        unsigned char d)
 {
        if((d >= '0') && (d <= '9')) {
index 8bbcfeea005e5cbcf6bdb9da55556d20a06b7d33..426f7a6c23bf74f6044909918873f40bb5e9e031 100644 (file)
@@ -63,7 +63,7 @@ MDSDictionary::MDSDictionary(
                NULL,           // desiredProperties
                &uerr);
        if(!brtn) {
                NULL,           // desiredProperties
                &uerr);
        if(!brtn) {
-               Syslog::alert("Error reading MDS file %s: %d", mUrlPath, uerr);
+               Syslog::alert("Error reading MDS file %s: %d", mUrlPath, (int)uerr);
                CssmError::throwMe(CSSMERR_CSSM_MDS_ERROR);
        }
        
                CssmError::throwMe(CSSMERR_CSSM_MDS_ERROR);
        }
        
@@ -250,7 +250,7 @@ bool MDSDictionary::lookupToDbAttr(
                                break;
                        }
                        CFArrayRef cfArray = (CFArrayRef)value;
                                break;
                        }
                        CFArrayRef cfArray = (CFArrayRef)value;
-                       numValues = CFArrayGetCount(cfArray);
+                       numValues = (uint32)CFArrayGetCount(cfArray);
                        if(numValues == 0) {
                                /* degenerate case, legal - right? Can AppleDatabase do this? */
                                srcPtr = NULL;
                        if(numValues == 0) {
                                /* degenerate case, legal - right? Can AppleDatabase do this? */
                                srcPtr = NULL;
index 6e854fd551a8307bf0341e65df77d4bbecdeb0ea..8fcb9fa2c905d0fe78c5c8a380331687321189c7 100644 (file)
@@ -74,7 +74,7 @@ static const AppleDatabaseTableName kTableNames[] = {
     TABLE(MDS_CDSADIR_KR_PRIMARY_RECORDTYPE),
        
     // marker for the end of the list
     TABLE(MDS_CDSADIR_KR_PRIMARY_RECORDTYPE),
        
     // marker for the end of the list
-    { ~0UL, NULL }
+    { ~0U, NULL }
 };
 
 MDSModule &
 };
 
 MDSModule &
index 4f2f74106ff00ae083b8a89c2004a75b41ed302a..2c19f9b30705e51983d2d54a684a17d80e5ae4b9 100644 (file)
 #include <time.h>
 #include <string>
 #include <unistd.h>
 #include <time.h>
 #include <string>
 #include <unistd.h>
+#include <syslog.h>
 
 using namespace CssmClient;
 
 
 using namespace CssmClient;
 
-
-/* 
+/*
  * The layout of the various MDS DB files on disk is as follows:
  *
  * /var/db/mds                         -- owner = root, mode = 01777, world writable, sticky
  * The layout of the various MDS DB files on disk is as follows:
  *
  * /var/db/mds                         -- owner = root, mode = 01777, world writable, sticky
@@ -142,7 +142,14 @@ static std::string GetMDSBaseDBDir(bool isRoot)
        else
        {
                char strBuffer[PATH_MAX + 1];
        else
        {
                char strBuffer[PATH_MAX + 1];
-               confstr(_CS_DARWIN_USER_CACHE_DIR, strBuffer, sizeof(strBuffer));
+               size_t result = confstr(_CS_DARWIN_USER_CACHE_DIR, strBuffer, sizeof(strBuffer));
+               if (result == 0)
+               {
+                       // we have an error, log it
+                       syslog(LOG_CRIT, "confstr on _CS_DARWIN_USER_CACHE_DIR returned an error.");
+                       CssmError::throwMe(CSSM_ERRCODE_MDS_ERROR);
+               }
+                       
                retValue = strBuffer;
        }
        
                retValue = strBuffer;
        }
        
@@ -582,7 +589,6 @@ MDSSession::install ()
        //
        mModule.setServerMode();
        
        //
        mModule.setServerMode();
        
-       int sysFdLock = -1;
        try {
                /* ensure MDS base directory exists with correct permissions */
                if(createDir(MDS_BASE_DB_DIR, MDS_SYSTEM_UID, MDS_BASE_DB_DIR_MODE)) {
        try {
                /* ensure MDS base directory exists with correct permissions */
                if(createDir(MDS_BASE_DB_DIR, MDS_SYSTEM_UID, MDS_BASE_DB_DIR_MODE)) {
@@ -596,7 +602,9 @@ MDSSession::install ()
                        CssmError::throwMe(CSSMERR_DL_OS_ACCESS_DENIED);
                }
 
                        CssmError::throwMe(CSSMERR_DL_OS_ACCESS_DENIED);
                }
 
-               if(!obtainLock(MDS_INSTALL_LOCK_PATH, sysFdLock, DB_LOCK_TIMEOUT)) {
+        LockHelper lh;
+        
+               if(!lh.obtainLock(MDS_INSTALL_LOCK_PATH, DB_LOCK_TIMEOUT)) {
                        CssmError::throwMe(CSSM_ERRCODE_MDS_ERROR);
                }
 
                        CssmError::throwMe(CSSM_ERRCODE_MDS_ERROR);
                }
 
@@ -625,12 +633,8 @@ MDSSession::install ()
                dbFiles.updateSystemDbInfo(MDS_SYSTEM_PATH, MDS_BUNDLE_PATH);
        }
        catch(...) {
                dbFiles.updateSystemDbInfo(MDS_SYSTEM_PATH, MDS_BUNDLE_PATH);
        }
        catch(...) {
-               if(sysFdLock != -1) {
-                       releaseLock(sysFdLock);
-               }
                throw;
        }
                throw;
        }
-       releaseLock(sysFdLock);
 }
 
 //
 }
 
 //
@@ -756,16 +760,15 @@ void MDSSession::GetDbNameFromHandle(CSSM_DB_HANDLE DBHandle,
 // right away if the lock cannot be obtained.
 //
 bool
 // right away if the lock cannot be obtained.
 //
 bool
-MDSSession::obtainLock(
+MDSSession::LockHelper::obtainLock(
        const char *lockFile,   // e.g. MDS_INSTALL_LOCK_PATH
        const char *lockFile,   // e.g. MDS_INSTALL_LOCK_PATH
-       int &fd,                                // IN/OUT
        int timeout)                    // default 0
 {
        int timeout)                    // default 0
 {
-       fd = -1;
+       mFD = -1;
        for(;;) {
                secdebug("mdslock", "obtainLock: calling open(%s)", lockFile);
        for(;;) {
                secdebug("mdslock", "obtainLock: calling open(%s)", lockFile);
-               fd = open(lockFile, O_EXLOCK | O_CREAT | O_RDWR, 0644);
-               if(fd == -1) {
+               mFD = open(lockFile, O_EXLOCK | O_CREAT | O_RDWR, 0644);
+               if(mFD == -1) {
                        int err = errno;
                        secdebug("mdslock", "obtainLock: open error %d", errno);
                        if(err == EINTR) {
                        int err = errno;
                        secdebug("mdslock", "obtainLock: open error %d", errno);
                        if(err == EINTR) {
@@ -792,14 +795,17 @@ MDSSession::obtainLock(
 // does not hold the lock, this method does nothing.
 //
 
 // does not hold the lock, this method does nothing.
 //
 
-void
-MDSSession::releaseLock(int &fd)
+MDSSession::LockHelper::~LockHelper()
 {
        secdebug("mdslock", "releaseLock");
 {
        secdebug("mdslock", "releaseLock");
-       assert(fd != -1);
-       flock(fd, LOCK_UN);
-       close(fd);
-       fd = -1;
+    if (mFD == -1)
+    {
+        return;
+    }
+    
+       flock(mFD, LOCK_UN);
+       close(mFD);
+       mFD = -1;
 }
 
 /* given DB file name, fill in fully specified path */
 }
 
 /* given DB file name, fill in fully specified path */
@@ -832,7 +838,7 @@ static bool isBundle(
                        return false;
        }
        int suffixLen = strlen(MDS_BUNDLE_EXTEN);
                        return false;
        }
        int suffixLen = strlen(MDS_BUNDLE_EXTEN);
-       int len = strlen(dp->d_name);
+       size_t len = strlen(dp->d_name);
        
        return (len >= suffixLen) && 
               !strcmp(dp->d_name + len - suffixLen, MDS_BUNDLE_EXTEN);
        
        return (len >= suffixLen) && 
               !strcmp(dp->d_name + len - suffixLen, MDS_BUNDLE_EXTEN);
@@ -944,7 +950,7 @@ static void safeCopyFile(
                /* copy */
                char buf[COPY_BUF_SIZE];
                while(1) {
                /* copy */
                char buf[COPY_BUF_SIZE];
                while(1) {
-                       int bytesRead = read(srcFd, buf, COPY_BUF_SIZE);
+                       ssize_t bytesRead = read(srcFd, buf, COPY_BUF_SIZE);
                        if(bytesRead == 0) {
                                break;
                        }
                        if(bytesRead == 0) {
                                break;
                        }
@@ -953,7 +959,7 @@ static void safeCopyFile(
                                MSDebug("Error %d reading system DB file %s\n", error, fromPath);
                                UnixError::throwMe(error);
                        }
                                MSDebug("Error %d reading system DB file %s\n", error, fromPath);
                                UnixError::throwMe(error);
                        }
-                       int bytesWritten = write(destFd, buf, bytesRead);
+                       ssize_t bytesWritten = write(destFd, buf, bytesRead);
                        if(bytesWritten < 0) {
                                error = errno;
                                MSDebug("Error %d writing user DB file %s\n", error, tmpToPath);
                        if(bytesWritten < 0) {
                                error = errno;
                                MSDebug("Error %d writing user DB file %s\n", error, tmpToPath);
@@ -1084,8 +1090,9 @@ void MDSSession::updateDataBases()
        }
 
        /* always release userLockFd no matter what happens */
        }
 
        /* always release userLockFd no matter what happens */
-       int userLockFd = -1;
-       if(!obtainLock(userDbLockPath.c_str(), userLockFd, DB_LOCK_TIMEOUT)) {
+    LockHelper lh;
+
+       if(!lh.obtainLock(userDbLockPath.c_str(), DB_LOCK_TIMEOUT)) {
                CssmError::throwMe(CSSM_ERRCODE_MDS_ERROR);
        }
        try {
                CssmError::throwMe(CSSM_ERRCODE_MDS_ERROR);
        }
        try {
@@ -1138,7 +1145,6 @@ void MDSSession::updateDataBases()
                                 */
                                MSDebug("doFilesExist(purge) error; using system DBs");
                                mModule.setDbPath(MDS_SYSTEM_DB_DIR);
                                 */
                                MSDebug("doFilesExist(purge) error; using system DBs");
                                mModule.setDbPath(MDS_SYSTEM_DB_DIR);
-                               releaseLock(userLockFd);
                                return;
                        }
                }
                                return;
                        }
                }
@@ -1162,11 +1168,9 @@ void MDSSession::updateDataBases()
                mModule.setDbPath(userDBFileDir.c_str());
        }       /* main block protected by mLockFd */
        catch(...) {
                mModule.setDbPath(userDBFileDir.c_str());
        }       /* main block protected by mLockFd */
        catch(...) {
-               releaseLock(userLockFd);
                throw;
        }
        mModule.lastScanIsNow();
                throw;
        }
        mModule.lastScanIsNow();
-       releaseLock(userLockFd);
 }
 
 /*
 }
 
 /*
@@ -1647,13 +1651,13 @@ void MDSSession::DbFilesInfo::removeOutdatedPlugins()
         * We have a vector of plugins to be deleted. Remove all records from both
         * DBs associated with the plugins, as specified by guid.
         */
         * We have a vector of plugins to be deleted. Remove all records from both
         * DBs associated with the plugins, as specified by guid.
         */
-       unsigned numRecords = tbdRecords.size();
-       for(unsigned i=0; i<numRecords; i++) {
+       size_t numRecords = tbdRecords.size();
+       for(size_t i=0; i<numRecords; i++) {
                TbdRecord *tbdRecord = tbdRecords[i];
                mSession.removeRecordsForGuid(tbdRecord->guid(), objDbHand());
                mSession.removeRecordsForGuid(tbdRecord->guid(), directDbHand());
        }
                TbdRecord *tbdRecord = tbdRecords[i];
                mSession.removeRecordsForGuid(tbdRecord->guid(), objDbHand());
                mSession.removeRecordsForGuid(tbdRecord->guid(), directDbHand());
        }
-       for(unsigned i=0; i<numRecords; i++) {
+       for(size_t i=0; i<numRecords; i++) {
                delete tbdRecords[i];
        }
 }
                delete tbdRecords[i];
        }
 }
index 07b539f56a5a96662e6ec28dd393412eadff2a0e..a7c2c6da7e62ea59f9e5c7bd00c2af9c32ed839a 100644 (file)
@@ -135,13 +135,20 @@ public:
                time_t mLaterTimestamp;
        };      /* DbFilesInfo */
 private:
                time_t mLaterTimestamp;
        };      /* DbFilesInfo */
 private:
-       bool obtainLock(
-               const char *lockFile,
-               int &fd, 
-               int timeout = 0);
-       void releaseLock(
-               int &fd);
-       
+    class LockHelper
+    {
+    private:
+        int mFD;
+
+    public:
+        LockHelper() : mFD(-1) {}
+        ~LockHelper();
+
+        bool obtainLock(
+            const char *lockFile,
+            int timeout = 0);
+       };
+
        /* given DB file name, fill in fully specified path */
        void dbFullPath(
                const char *dbName,
        /* given DB file name, fill in fully specified path */
        void dbFullPath(
                const char *dbName,
index d0c451235fabd73b9f2214c4471f671bc9476eaf..aacdcf6014ed502c0be33f2cedf3f07c85fa7cc5 100644 (file)
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0420;
+                               LastUpgradeCheck = 0500;
                        };
                        buildConfigurationList = C27AD3A80987FCDE001272E0 /* Build configuration list for PBXProject "libsecurity_mds" */;
                        compatibilityVersion = "Xcode 3.2";
                        };
                        buildConfigurationList = C27AD3A80987FCDE001272E0 /* Build configuration list for PBXProject "libsecurity_mds" */;
                        compatibilityVersion = "Xcode 3.2";
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB35F146F11F1000BF1F3 /* debug.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB35F146F11F1000BF1F3 /* debug.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                               WARNING_CFLAGS = (
+                                       "$(inherited)",
+                                       "-Wno-error=overloaded-virtual",
+                               );
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB361146F11F1000BF1F3 /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB361146F11F1000BF1F3 /* release.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                               WARNING_CFLAGS = (
+                                       "$(inherited)",
+                                       "-Wno-error=overloaded-virtual",
+                               );
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB360146F11F1000BF1F3 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB360146F11F1000BF1F3 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB360146F11F1000BF1F3 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB360146F11F1000BF1F3 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
index 9445b49a1734ed52edc421e3d85b3b5d8047a120..8c8e73a37116d5656e0f548846319b826cd7f3c8 100644 (file)
@@ -32,8 +32,7 @@
 #include <security_utilities/mach++.h>
 #include <security_utilities/unix++.h>
 #include <security_ocspd/ocspd.h>                      /* MIG interface */
 #include <security_utilities/mach++.h>
 #include <security_utilities/unix++.h>
 #include <security_ocspd/ocspd.h>                      /* MIG interface */
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
-
+#include <Security/SecBase.h>
 class ocspdGlobals
 {
 public:
 class ocspdGlobals
 {
 public:
@@ -113,7 +112,7 @@ CSSM_RETURN ocspdFetch(
                return CSSMERR_TP_INTERNAL_ERROR;
        }
 
                return CSSMERR_TP_INTERNAL_ERROR;
        }
 
-       krtn = ocsp_client_ocspdFetch(serverPort, ocspdReq.Data, ocspdReq.Length,
+       krtn = ocsp_client_ocspdFetch(serverPort, ocspdReq.Data, (mach_msg_type_number_t)ocspdReq.Length,
                (void **)&rtnData, &rtnLen);
        if(krtn) {
                ocspdErrorLog("ocspdFetch: RPC returned %d\n", krtn);
                (void **)&rtnData, &rtnLen);
        if(krtn) {
                ocspdErrorLog("ocspdFetch: RPC returned %d\n", krtn);
@@ -146,7 +145,7 @@ CSSM_RETURN ocspdCacheFlush(
                ocspdErrorLog("ocspdCacheFlush: OCSPD server error\n");
                return CSSMERR_TP_INTERNAL_ERROR;
        }
                ocspdErrorLog("ocspdCacheFlush: OCSPD server error\n");
                return CSSMERR_TP_INTERNAL_ERROR;
        }
-       krtn = ocsp_client_ocspdCacheFlush(serverPort, certID.Data, certID.Length);
+       krtn = ocsp_client_ocspdCacheFlush(serverPort, certID.Data, (mach_msg_type_number_t)certID.Length);
        if(krtn) {
                ocspdErrorLog("ocspdCacheFlush: RPC returned %d\n", krtn);
                return CSSMERR_APPLETP_OCSP_UNAVAILABLE;
        if(krtn) {
                ocspdErrorLog("ocspdCacheFlush: RPC returned %d\n", krtn);
                return CSSMERR_APPLETP_OCSP_UNAVAILABLE;
@@ -198,7 +197,7 @@ CSSM_RETURN ocspdCertFetch(
                return CSSMERR_TP_INTERNAL_ERROR;
        }
        
                return CSSMERR_TP_INTERNAL_ERROR;
        }
        
-       krtn = ocsp_client_certFetch(serverPort, certURL.Data, certURL.Length,
+       krtn = ocsp_client_certFetch(serverPort, certURL.Data, (mach_msg_type_number_t)certURL.Length,
                (void **)&rtnData, &rtnLen);
        if(krtn) {
                ocspdErrorLog("ocspdCertFetch: RPC returned %d\n", krtn);
                (void **)&rtnData, &rtnLen);
        if(krtn) {
                ocspdErrorLog("ocspdCertFetch: RPC returned %d\n", krtn);
@@ -246,10 +245,10 @@ CSSM_RETURN ocspdCRLFetch(
                return CSSMERR_TP_INTERNAL_ERROR;
        }
        
                return CSSMERR_TP_INTERNAL_ERROR;
        }
        
-       krtn = ocsp_client_crlFetch(serverPort, crlURL.Data, crlURL.Length,
-               crlIssuer ? crlIssuer->Data : NULL, crlIssuer ? crlIssuer->Length : 0,
+       krtn = ocsp_client_crlFetch(serverPort, crlURL.Data, (mach_msg_type_number_t)crlURL.Length,
+               crlIssuer ? crlIssuer->Data : NULL, crlIssuer ? (mach_msg_type_number_t)crlIssuer->Length : 0,
                cacheReadEnable, cacheWriteEnable,
                cacheReadEnable, cacheWriteEnable,
-               verifyTime, strlen(verifyTime),
+               verifyTime, (mach_msg_type_number_t)strlen(verifyTime),
                (void **)&rtnData, &rtnLen);
        if(krtn) {
                ocspdErrorLog("ocspdCRLFetch: RPC returned %d\n", krtn);
                (void **)&rtnData, &rtnLen);
        if(krtn) {
                ocspdErrorLog("ocspdCRLFetch: RPC returned %d\n", krtn);
@@ -293,10 +292,10 @@ CSSM_RETURN ocspdCRLStatus(
        }
 
        krtn = ocsp_client_crlStatus(serverPort,
        }
 
        krtn = ocsp_client_crlStatus(serverPort,
-               serialNumber.Data, serialNumber.Length,
-               issuers.Data, issuers.Length,
-               crlIssuer ? crlIssuer->Data : NULL, crlIssuer ? crlIssuer->Length : 0,
-               crlURL ? crlURL->Data : NULL, crlURL ? crlURL->Length : 0);
+               serialNumber.Data, (mach_msg_type_number_t)serialNumber.Length,
+               issuers.Data, (mach_msg_type_number_t)issuers.Length,
+               crlIssuer ? crlIssuer->Data : NULL, crlIssuer ? (mach_msg_type_number_t)crlIssuer->Length : 0,
+               crlURL ? crlURL->Data : NULL, crlURL ? (mach_msg_type_number_t)crlURL->Length : 0);
 
        return krtn;
 }
 
        return krtn;
 }
@@ -348,7 +347,7 @@ CSSM_RETURN ocspdCRLFlush(
                return CSSMERR_TP_INTERNAL_ERROR;
        }
        
                return CSSMERR_TP_INTERNAL_ERROR;
        }
        
-       krtn = ocsp_client_crlFlush(serverPort, crlURL.Data, crlURL.Length);
+       krtn = ocsp_client_crlFlush(serverPort, crlURL.Data, (mach_msg_type_number_t)crlURL.Length);
        if(krtn) {
                ocspdErrorLog("ocspdCRLFlush: RPC returned %d\n", krtn);
                return CSSMERR_APPLETP_NETWORK_FAILURE;
        if(krtn) {
                ocspdErrorLog("ocspdCRLFlush: RPC returned %d\n", krtn);
                return CSSMERR_APPLETP_NETWORK_FAILURE;
@@ -375,7 +374,7 @@ OSStatus ocspdTrustSettingsRead(
        } 
        catch(...) {
                ocspdErrorLog("ocspdTrustSettingsRead: OCSPD server error\n");
        } 
        catch(...) {
                ocspdErrorLog("ocspdTrustSettingsRead: OCSPD server error\n");
-               return internalComponentErr;
+               return errSecInternalComponent;
        }
        
        krtn = ocsp_client_trustSettingsRead(serverPort, domain,
        }
        
        krtn = ocsp_client_trustSettingsRead(serverPort, domain,
@@ -396,7 +395,7 @@ OSStatus ocspdTrustSettingsRead(
        trustSettings.Length = rtnLen;
        memmove(trustSettings.Data, rtnData, rtnLen);
        mig_deallocate((vm_address_t)rtnData, rtnLen);
        trustSettings.Length = rtnLen;
        memmove(trustSettings.Data, rtnData, rtnLen);
        mig_deallocate((vm_address_t)rtnData, rtnLen);
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -418,16 +417,16 @@ OSStatus ocspdTrustSettingsWrite(
        } 
        catch(...) {
                ocspdErrorLog("ocspdTrustSettingsWrite: OCSPD server error\n");
        } 
        catch(...) {
                ocspdErrorLog("ocspdTrustSettingsWrite: OCSPD server error\n");
-               return internalComponentErr;
+               return errSecInternalComponent;
        }
 
        krtn = ocsp_client_trustSettingsWrite(serverPort, clientPort, domain,
        }
 
        krtn = ocsp_client_trustSettingsWrite(serverPort, clientPort, domain,
-               authBlob.Data, authBlob.Length,
-               trustSettings.Data, trustSettings.Length,
+               authBlob.Data, (mach_msg_type_number_t)authBlob.Length,
+               trustSettings.Data, (mach_msg_type_number_t)trustSettings.Length,
                &ortn);
        if(krtn) {
                ocspdErrorLog("ocspdTrustSettingsWrite: RPC returned %d\n", krtn);
                &ortn);
        if(krtn) {
                ocspdErrorLog("ocspdTrustSettingsWrite: RPC returned %d\n", krtn);
-               return internalComponentErr;
+               return errSecInternalComponent;
        }
        return ortn;
 }
        }
        return ortn;
 }
index 8b4cb16f17706f61a439ba408af432c90786444e..05ffc186d10e917276b01ce882f59f377c707aa3 100644 (file)
@@ -108,9 +108,9 @@ const CSSM_DATA *OCSPClientCertID::encode()
        certID.algId.parameters.Length = sizeof(nullParam);
 
        /* SHA1(issuerName) */
        certID.algId.parameters.Length = sizeof(nullParam);
 
        /* SHA1(issuerName) */
-       ocspdSha1(mIssuerName.Data, mIssuerName.Length, issuerNameHash);
+       ocspdSha1(mIssuerName.Data, (CC_LONG)mIssuerName.Length, issuerNameHash);
        /* SHA1(issuer public key) */
        /* SHA1(issuer public key) */
-       ocspdSha1(mIssuerPubKey.Data, mIssuerPubKey.Length, pubKeyHash);
+       ocspdSha1(mIssuerPubKey.Data, (CC_LONG)mIssuerPubKey.Length, pubKeyHash);
        
        /* build the CertID from those components */
        certID.issuerNameHash.Data = issuerNameHash;
        
        /* build the CertID from those components */
        certID.issuerNameHash.Data = issuerNameHash;
@@ -171,11 +171,11 @@ bool OCSPClientCertID::compareToExist(
        }
        
        /* generate digests using exist's hash algorithm */
        }
        
        /* generate digests using exist's hash algorithm */
-       hf(mIssuerName.Data, mIssuerName.Length, digest);
+       hf(mIssuerName.Data, (CC_LONG)mIssuerName.Length, digest);
        if(!ocspdCompareCssmData(&digestData, &exist.issuerNameHash)) {
                return false;
        }
        if(!ocspdCompareCssmData(&digestData, &exist.issuerNameHash)) {
                return false;
        }
-       hf(mIssuerPubKey.Data, mIssuerPubKey.Length, digest);
+       hf(mIssuerPubKey.Data, (CC_LONG)mIssuerPubKey.Length, digest);
        if(!ocspdCompareCssmData(&digestData, &exist.issuerPubKeyHash)) {
                return false;
        }
        if(!ocspdCompareCssmData(&digestData, &exist.issuerPubKeyHash)) {
                return false;
        }
@@ -260,11 +260,13 @@ OCSPSingleResponse::~OCSPSingleResponse()
 }
 
 /*** Extensions-specific accessors ***/
 }
 
 /*** Extensions-specific accessors ***/
+#if 0 /* unused ? */
 const CSSM_DATA *OCSPSingleResponse::*crlUrl()
 {
        /* TBD */
        return NULL;
 }
 const CSSM_DATA *OCSPSingleResponse::*crlUrl()
 {
        /* TBD */
        return NULL;
 }
+#endif
 
 const CSSM_DATA *OCSPSingleResponse::crlNum()
 {
 
 const CSSM_DATA *OCSPSingleResponse::crlNum()
 {
index bb1af0aeb418d73ae1e732e4d9825da407b73ce6..c6680e85fb2e4f4391829f01081dc7cada38997b 100644 (file)
@@ -24,7 +24,7 @@
 #define _OCSPD_TYPES_H_
 
 #include <mach/mach_types.h>
 #define _OCSPD_TYPES_H_
 
 #include <mach/mach_types.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+#include <MacTypes.h>
 
 /* Explicitly enable MIG type checking per Radar 4735696 */
 #undef __MigTypeCheck
 
 /* Explicitly enable MIG type checking per Radar 4735696 */
 #undef __MigTypeCheck
index 537c568004c03eb7d2b412222201a5b940d05188..d3280c33f43c97abc1be5749083bcd7b14ab442b 100644 (file)
@@ -143,7 +143,7 @@ CFAbsoluteTime genTimeToCFAbsTime(
        }
        
        uint8 *timeStr = strData->Data;
        }
        
        uint8 *timeStr = strData->Data;
-       uint32 timeStrLen = strData->Length;
+       size_t timeStrLen = strData->Length;
        
        /* tolerate NULL terminated or not */
        if(timeStr[timeStrLen - 1] == '\0') {
        
        /* tolerate NULL terminated or not */
        if(timeStr[timeStrLen - 1] == '\0') {
@@ -152,7 +152,7 @@ CFAbsoluteTime genTimeToCFAbsTime(
        
        /* start with a fresh editable copy */
        uint8 *str = (uint8 *)malloc(timeStrLen);
        
        /* start with a fresh editable copy */
        uint8 *str = (uint8 *)malloc(timeStrLen);
-       unsigned strLen = 0;
+       uint32 strLen = 0;
        
        /* 
         * If there is a decimal point, strip it and all trailing digits off
        
        /* 
         * If there is a decimal point, strip it and all trailing digits off
@@ -164,7 +164,7 @@ CFAbsoluteTime genTimeToCFAbsTime(
        int hoursOffset = 0;
        bool minusOffset = false;
        bool isGMT = false;
        int hoursOffset = 0;
        bool minusOffset = false;
        bool isGMT = false;
-       int toGo = timeStrLen;
+       size_t toGo = timeStrLen;
        
        do {
                if(*inCp == '.') {
        
        do {
                if(*inCp == '.') {
@@ -198,7 +198,7 @@ CFAbsoluteTime genTimeToCFAbsTime(
                        if(*inCp == '-') {
                                minusOffset = true;
                        }
                        if(*inCp == '-') {
                                minusOffset = true;
                        }
-                       *inCp++;
+                       inCp++;
                        hoursOffset = (10 * (inCp[0] - '0')) + (inCp[1] - '0');
                        toGo -= 2;
                        if(toGo) {
                        hoursOffset = (10 * (inCp[0] - '0')) + (inCp[1] - '0');
                        toGo -= 2;
                        if(toGo) {
index 9bf2228234a28909024372df784a24cc7421eec7..7d2fdc151ee892b006b5d01586216f1e4916021d 100644 (file)
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0420;
+                               LastUpgradeCheck = 0500;
                        };
                        buildConfigurationList = C27AD3BA0987FCDF001272E0 /* Build configuration list for PBXProject "libsecurity_ocspd" */;
                        compatibilityVersion = "Xcode 3.2";
                        };
                        buildConfigurationList = C27AD3BA0987FCDF001272E0 /* Build configuration list for PBXProject "libsecurity_ocspd" */;
                        compatibilityVersion = "Xcode 3.2";
                C27AD3AF0987FCDF001272E0 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                C27AD3AF0987FCDF001272E0 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                INSTALLHDRS_SCRIPT_PHASE = YES;
                        };
                        name = Debug;
                                INSTALLHDRS_SCRIPT_PHASE = YES;
                        };
                        name = Debug;
                C27AD3B10987FCDF001272E0 /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                C27AD3B10987FCDF001272E0 /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                INSTALLHDRS_SCRIPT_PHASE = YES;
                        };
                        name = Release;
                                INSTALLHDRS_SCRIPT_PHASE = YES;
                        };
                        name = Release;
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844612C146E894C00B12992 /* debug.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844612C146E894C00B12992 /* debug.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/security_ocspd;
                                SKIP_INSTALL = NO;
                        };
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/security_ocspd;
                                SKIP_INSTALL = NO;
                        };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844612E146E894C00B12992 /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844612E146E894C00B12992 /* release.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/security_ocspd;
                                SKIP_INSTALL = NO;
                        };
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/security_ocspd;
                                SKIP_INSTALL = NO;
                        };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844612D146E894C00B12992 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844612D146E894C00B12992 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844612D146E894C00B12992 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1844612D146E894C00B12992 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
index ce30b4c87ebaa5319d84b2c1dc412f2901939e93..ab4ee729409922d8f919bf14d734514fcf76bd10 100644 (file)
@@ -29,7 +29,6 @@
 #include "pkcs12BagAttrs.h"
 #include "pkcs12SafeBag.h"
 #include "pkcs12Utils.h"
 #include "pkcs12BagAttrs.h"
 #include "pkcs12SafeBag.h"
 #include "pkcs12Utils.h"
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 #include <security_cdsa_utilities/cssmerrors.h>
 #include <Security/SecBasePriv.h>
 
 #include <security_cdsa_utilities/cssmerrors.h>
 #include <Security/SecBasePriv.h>
 
        } \
        catch (const MacOSError &err) { return err.osStatus(); } \
        catch (const CommonError &err) { return SecKeychainErrFromOSStatus(err.osStatus()); } \
        } \
        catch (const MacOSError &err) { return err.osStatus(); } \
        catch (const CommonError &err) { return SecKeychainErrFromOSStatus(err.osStatus()); } \
-       catch (const std::bad_alloc &) { return memFullErr; } \
-       catch (...) { return internalComponentErr; } \
-    return noErr;
+       catch (const std::bad_alloc &) { return errSecAllocate; } \
+       catch (...) { return errSecInternalComponent; } \
+    return errSecSuccess;
 
 /* catch incoming NULL parameters */
 static inline void required(
        const void *param)
 {
        if(param == NULL) {
 
 /* catch incoming NULL parameters */
 static inline void required(
        const void *param)
 {
        if(param == NULL) {
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
        }
 }
 
        }
 }
 
@@ -75,7 +74,7 @@ static inline P12BagAttrsStandAlone *P12AttrsCast(
        SecPkcs12AttrsRef attrs)
 {
        if(attrs == NULL) {
        SecPkcs12AttrsRef attrs)
 {
        if(attrs == NULL) {
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
        }
        return reinterpret_cast<P12BagAttrsStandAlone *>(attrs);
 }
        }
        return reinterpret_cast<P12BagAttrsStandAlone *>(attrs);
 }
@@ -336,7 +335,7 @@ OSStatus SecPkcs12CopyCertificate(
        P12Coder *p12coder = P12CoderCast(coder);
        required(secCert);
        /* others are optional - if NULL, we don't return that param */
        P12Coder *p12coder = P12CoderCast(coder);
        required(secCert);
        /* others are optional - if NULL, we don't return that param */
-       P12CertBag *bag = p12coder->getCert(certNum);
+       P12CertBag *bag = p12coder->getCert((unsigned)certNum);
        *secCert = bag->getSecCert();
        
        /* now the optional attrs */
        *secCert = bag->getSecCert();
        
        /* now the optional attrs */
@@ -379,7 +378,7 @@ OSStatus SecPkcs12CopyCrl(
        P12Coder *p12coder = P12CoderCast(coder);
        required(crl);
        /* others are optional - if NULL, we don't return that param */
        P12Coder *p12coder = P12CoderCast(coder);
        required(crl);
        /* others are optional - if NULL, we don't return that param */
-       P12CrlBag *bag = p12coder->getCrl(crlNum);
+       P12CrlBag *bag = p12coder->getCrl((unsigned)crlNum);
        *crl = p12CssmDataToCf(bag->crlData());
        
        /* now the optional attrs */
        *crl = p12CssmDataToCf(bag->crlData());
        
        /* now the optional attrs */
@@ -419,7 +418,7 @@ OSStatus SecPkcs12CopyPrivateKey(
 {
        BEGIN_P12API
        /*P12Coder *p12coder = P12CoderCast(coder); */
 {
        BEGIN_P12API
        /*P12Coder *p12coder = P12CoderCast(coder); */
-       return unimpErr;
+       return errSecUnimplemented;
        END_P12API
 }
 
        END_P12API
 }
 
@@ -435,7 +434,7 @@ OSStatus SecPkcs12GetCssmPrivateKey(
        P12Coder *p12coder = P12CoderCast(coder);
        required(privateKey);
        /* others are optional - if NULL, we don't return that param */
        P12Coder *p12coder = P12CoderCast(coder);
        required(privateKey);
        /* others are optional - if NULL, we don't return that param */
-       P12KeyBag *bag = p12coder->getKey(keyNum);
+       P12KeyBag *bag = p12coder->getKey((unsigned)keyNum);
        *privateKey = bag->key();
        
        /* now the optional attrs */
        *privateKey = bag->key();
        
        /* now the optional attrs */
@@ -484,7 +483,7 @@ OSStatus SecPkcs12CopyOpaqueBlob(
        required(opaqueBlob);
        
        /* others are optional - if NULL, we don't return that param */
        required(opaqueBlob);
        
        /* others are optional - if NULL, we don't return that param */
-       P12OpaqueBag *bag = p12coder->getOpaque(blobNum);
+       P12OpaqueBag *bag = p12coder->getOpaque((unsigned)blobNum);
        *opaqueBlob = p12CssmDataToCf(bag->blob());
        *blobOid    = p12CssmDataToCf(bag->oid());
        
        *opaqueBlob = p12CssmDataToCf(bag->blob());
        *blobOid    = p12CssmDataToCf(bag->oid());
        
@@ -600,6 +599,7 @@ OSStatus SecPkcs12AddPrivateKey(
        END_P12API
 }
 
        END_P12API
 }
 
+#if 0 /* Unused */
 OSStatus SecPkcs12AddCssmPrivateKey(
        SecPkcs12CoderRef               coder,
        CSSM_KEY_PTR                    cssmKey,                        
 OSStatus SecPkcs12AddCssmPrivateKey(
        SecPkcs12CoderRef               coder,
        CSSM_KEY_PTR                    cssmKey,                        
@@ -617,6 +617,7 @@ OSStatus SecPkcs12AddCssmPrivateKey(
        
        END_P12API
 }
        
        END_P12API
 }
+#endif
 
 OSStatus SecPkcs12AddOpaqueBlob(
        SecPkcs12CoderRef               coder,
 
 OSStatus SecPkcs12AddOpaqueBlob(
        SecPkcs12CoderRef               coder,
@@ -716,7 +717,7 @@ OSStatus SecPkcs12AttrsGetAttr(
        P12BagAttrsStandAlone *bagAttrs = P12AttrsCast(attrs);
        required(attrOid);
        required(attrValues);
        P12BagAttrsStandAlone *bagAttrs = P12AttrsCast(attrs);
        required(attrOid);
        required(attrValues);
-       bagAttrs->getAttr(attrNum, attrOid, attrValues);
+       bagAttrs->getAttr((unsigned)attrNum, attrOid, attrValues);
        END_P12API
 }
 
        END_P12API
 }
 
index 5c3ba582b5e86deafcfc977224df88fa84932473..73c5ca72ce271569badff61b8697741150957a51 100644 (file)
@@ -32,8 +32,7 @@
 #include "pkcs12Utils.h"
 #include <security_asn1/nssUtils.h>
 #include <assert.h>
 #include "pkcs12Utils.h"
 #include <security_asn1/nssUtils.h>
 #include <assert.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
-
+#include <Security/SecBase.h>
 /* 
  * Copying constructor used by P12SafeBag during encoding
  */
 /* 
  * Copying constructor used by P12SafeBag during encoding
  */
@@ -85,7 +84,7 @@ void P12BagAttrs::addAttr(
 {
        NSS_Attribute *newAttr = reallocAttrs(numAttrs() + 1);
        p12CfDataToCssm(attrOid, newAttr->attrType, mCoder);
 {
        NSS_Attribute *newAttr = reallocAttrs(numAttrs() + 1);
        p12CfDataToCssm(attrOid, newAttr->attrType, mCoder);
-       unsigned numVals = CFArrayGetCount(attrValues);
+       uint32 numVals = (uint32)CFArrayGetCount(attrValues);
        newAttr->attrValue = (CSSM_DATA **)p12NssNullArray(numVals, mCoder);
        for(unsigned dex=0; dex<numVals; dex++) {
                CSSM_DATA *dstVal = (CSSM_DATA *)mCoder.malloc(sizeof(CSSM_DATA));
        newAttr->attrValue = (CSSM_DATA **)p12NssNullArray(numVals, mCoder);
        for(unsigned dex=0; dex<numVals; dex++) {
                CSSM_DATA *dstVal = (CSSM_DATA *)mCoder.malloc(sizeof(CSSM_DATA));
@@ -105,7 +104,7 @@ void P12BagAttrs::getAttr(
        CFArrayRef                      *attrValues)    // RETURNED
 {
        if(attrNum >= numAttrs()) {
        CFArrayRef                      *attrValues)    // RETURNED
 {
        if(attrNum >= numAttrs()) {
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
        }
        NSS_Attribute *attr = mAttrs[attrNum];
        *attrOid = p12CssmDataToCf(attr->attrType);
        }
        NSS_Attribute *attr = mAttrs[attrNum];
        *attrOid = p12CssmDataToCf(attr->attrType);
@@ -135,7 +134,7 @@ NSS_Attribute *P12BagAttrs::reallocAttrs(
        unsigned curSize = numAttrs();
        assert(numNewAttrs > curSize);
        NSS_Attribute **newAttrs = 
        unsigned curSize = numAttrs();
        assert(numNewAttrs > curSize);
        NSS_Attribute **newAttrs = 
-               (NSS_Attribute **)p12NssNullArray(numNewAttrs, mCoder);
+               (NSS_Attribute **)p12NssNullArray((uint32)numNewAttrs, mCoder);
        for(unsigned dex=0; dex<curSize; dex++) {
                newAttrs[dex] = mAttrs[dex];
        }
        for(unsigned dex=0; dex<curSize; dex++) {
                newAttrs[dex] = mAttrs[dex];
        }
index d2be98a20209892dd90458453cbd9886a1acec35..4784e7b3b40ceb27dff73e9189d60d3c37e23a36 100644 (file)
@@ -30,9 +30,8 @@
 #include "pkcs12Utils.h"
 #include <Security/cssmerr.h>
 #include <security_cdsa_utils/cuCdsaUtils.h>
 #include "pkcs12Utils.h"
 #include <Security/cssmerr.h>
 #include <security_cdsa_utils/cuCdsaUtils.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 #include <Security/oidsalg.h>
 #include <Security/oidsalg.h>
-
+#include <Security/SecBase.h>
 /*
  * Default encryption parameters
  */
 /*
  * Default encryption parameters
  */
@@ -279,29 +278,29 @@ void P12Coder::setEncrPassKey(
 /* getters */
 unsigned P12Coder::numCerts()
 {
 /* getters */
 unsigned P12Coder::numCerts()
 {
-       return mCerts.size();
+       return (unsigned)mCerts.size();
 }
 
 unsigned P12Coder::numCrls()
 {
 }
 
 unsigned P12Coder::numCrls()
 {
-       return mCrls.size();
+       return (unsigned)mCrls.size();
 }
 
 unsigned P12Coder::numKeys()
 {
 }
 
 unsigned P12Coder::numKeys()
 {
-       return mKeys.size();
+       return (unsigned)mKeys.size();
 }
 
 unsigned P12Coder::numOpaqueBlobs()
 {
 }
 
 unsigned P12Coder::numOpaqueBlobs()
 {
-       return mOpaques.size();
+       return (unsigned)mOpaques.size();
 }
 
 P12CertBag *P12Coder::getCert(
        unsigned                                dex)
 {
        if(mCerts.size() < (dex + 1)) {
 }
 
 P12CertBag *P12Coder::getCert(
        unsigned                                dex)
 {
        if(mCerts.size() < (dex + 1)) {
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
        }
        return mCerts[dex];
 }
        }
        return mCerts[dex];
 }
@@ -310,7 +309,7 @@ P12CrlBag *P12Coder::getCrl(
        unsigned                                dex)
 {
        if(mCrls.size() < (dex + 1)) {
        unsigned                                dex)
 {
        if(mCrls.size() < (dex + 1)) {
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
        }
        return mCrls[dex];
 }
        }
        return mCrls[dex];
 }
@@ -319,7 +318,7 @@ P12KeyBag *P12Coder::getKey(
        unsigned                                dex)
 {
        if(mKeys.size() < (dex + 1)) {
        unsigned                                dex)
 {
        if(mKeys.size() < (dex + 1)) {
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
        }
        return mKeys[dex];
 }
        }
        return mKeys[dex];
 }
@@ -328,7 +327,7 @@ P12OpaqueBag *P12Coder::getOpaque(
        unsigned                                dex)
 {
        if(mOpaques.size() < (dex + 1)) {
        unsigned                                dex)
 {
        if(mOpaques.size() < (dex + 1)) {
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
        }
        return mOpaques[dex];
 }
        }
        return mOpaques[dex];
 }
@@ -367,7 +366,7 @@ void P12Coder::integrityMode(
        SecPkcs12Mode                   mode)
 {
        if(mode != kSecPkcs12ModePassword) {
        SecPkcs12Mode                   mode)
 {
        if(mode != kSecPkcs12ModePassword) {
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
        }
        mIntegrityMode = mode;
 }
        }
        mIntegrityMode = mode;
 }
@@ -376,7 +375,7 @@ void P12Coder::privacyMode(
        SecPkcs12Mode                   mode)
 {
        if(mode != kSecPkcs12ModePassword) {
        SecPkcs12Mode                   mode)
 {
        if(mode != kSecPkcs12ModePassword) {
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
        }
        mPrivacyMode = mode;
 }
        }
        mPrivacyMode = mode;
 }
index a1ad288e3ec66da325a511a0f21f4d7fa98b5e13..d99c3998e3f6587566eee358e61cb5e354c1a88e 100644 (file)
@@ -43,8 +43,8 @@
 #include "pkcs12Templates.h"
 #include "pkcs12Utils.h"
 #include <Security/cssmerr.h>
 #include "pkcs12Templates.h"
 #include "pkcs12Utils.h"
 #include <Security/cssmerr.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 #include <Security/oidsattr.h>
 #include <Security/oidsattr.h>
+#include <Security/SecBase.h>
 
 void P12Coder::encode(
        CFDataRef                               *cpfx)          // RETURNED
 
 void P12Coder::encode(
        CFDataRef                               *cpfx)          // RETURNED
@@ -148,7 +148,7 @@ void P12Coder::authSafeBuild(
 
        if(numContents == 0) {
                p12ErrorLog("authSafeBuild: no contents\n");
 
        if(numContents == 0) {
                p12ErrorLog("authSafeBuild: no contents\n");
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
        }
        
        NSS_P7_DecodedContentInfo **contents = 
        }
        
        NSS_P7_DecodedContentInfo **contents = 
@@ -159,7 +159,7 @@ void P12Coder::authSafeBuild(
        NSS_P12_SafeBag **safeBags;
 
        /* certs & crls */
        NSS_P12_SafeBag **safeBags;
 
        /* certs & crls */
-       unsigned numBags = mCerts.size() + mCrls.size();
+       unsigned numBags = (unsigned)(mCerts.size() + mCrls.size());
        p12EncodeLog("authSafeBuild : %u certs + CRLS", numBags);
        if(numBags) {
                safeBags = (NSS_P12_SafeBag **)p12NssNullArray(numBags, localCdr);
        p12EncodeLog("authSafeBuild : %u certs + CRLS", numBags);
        if(numBags) {
                safeBags = (NSS_P12_SafeBag **)p12NssNullArray(numBags, localCdr);
@@ -175,7 +175,7 @@ void P12Coder::authSafeBuild(
        }
        
        /* shrouded keys - encrypted at bag level */
        }
        
        /* shrouded keys - encrypted at bag level */
-       numBags = mKeys.size();
+       numBags = (unsigned)mKeys.size();
        if(numBags) {
                p12EncodeLog("authSafeBuild : %u keys", numBags);
                safeBags = (NSS_P12_SafeBag **)p12NssNullArray(numBags, localCdr);
        if(numBags) {
                p12EncodeLog("authSafeBuild : %u keys", numBags);
                safeBags = (NSS_P12_SafeBag **)p12NssNullArray(numBags, localCdr);
@@ -188,7 +188,7 @@ void P12Coder::authSafeBuild(
        }
        
        /* opaque */
        }
        
        /* opaque */
-       numBags = mOpaques.size();
+       numBags = (unsigned)mOpaques.size();
        if(numBags) {
                p12EncodeLog("authSafeBuild : %u opaques", numBags);
                safeBags = (NSS_P12_SafeBag **)p12NssNullArray(numBags, localCdr);
        if(numBags) {
                p12EncodeLog("authSafeBuild : %u opaques", numBags);
                safeBags = (NSS_P12_SafeBag **)p12NssNullArray(numBags, localCdr);
index cd8bebc937bf2376438ee3c48ce2a14c365f1816..5373fc0d0518ae6902a52dc251318d9552f71980 100644 (file)
@@ -33,7 +33,6 @@
 #include <Security/cssmerr.h>
 #include <security_cdsa_utils/cuDbUtils.h>                     // cuAddCrlToDb()
 #include <security_asn1/nssUtils.h>
 #include <Security/cssmerr.h>
 #include <security_cdsa_utils/cuDbUtils.h>                     // cuAddCrlToDb()
 #include <security_asn1/nssUtils.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 #include <security_cdsa_utilities/KeySchema.h>                 /* private API */
 #include <security_keychain/SecImportExportCrypto.h>   /* private API */
 
 #include <security_cdsa_utilities/KeySchema.h>                 /* private API */
 #include <security_keychain/SecImportExportCrypto.h>   /* private API */
 
@@ -56,7 +55,7 @@ void P12Coder::storeDecodeResults()
                        OSStatus ortn = SecCertificateAddToKeychain(secCert, mKeychain);
                        CFRelease(secCert);
                        switch(ortn) {
                        OSStatus ortn = SecCertificateAddToKeychain(secCert, mKeychain);
                        CFRelease(secCert);
                        switch(ortn) {
-                               case noErr:                                     // normal 
+                               case errSecSuccess:                                     // normal
                                        p12DecodeLog("cert added to keychain");
                                        break;
                                case errSecDuplicateItem:       // dup cert, OK< skip
                                        p12DecodeLog("cert added to keychain");
                                        break;
                                case errSecDuplicateItem:       // dup cert, OK< skip
@@ -162,7 +161,7 @@ void P12Coder::notifyKeyImport()
                CssmData &labelData = CssmData::overlay(keyBag->label());
                OSStatus ortn = impExpKeyNotify(mKeychain, labelData, *keyBag->key());
                if(ortn) {
                CssmData &labelData = CssmData::overlay(keyBag->label());
                OSStatus ortn = impExpKeyNotify(mKeychain, labelData, *keyBag->key());
                if(ortn) {
-                       p12ErrorLog("notifyKeyImport: impExpKeyNotify returned %ld\n", ortn);
+                       p12ErrorLog("notifyKeyImport: impExpKeyNotify returned %ld\n", (unsigned long)ortn);
                        MacOSError::throwMe(ortn);
                }
        }
                        MacOSError::throwMe(ortn);
                }
        }
@@ -202,7 +201,7 @@ void P12Coder::exportKeychainItems(
                const void *item = CFArrayGetValueAtIndex(items, dex);
                if(item == NULL) {
                        p12ErrorLog("exportKeychainItems: NULL item\n");
                const void *item = CFArrayGetValueAtIndex(items, dex);
                if(item == NULL) {
                        p12ErrorLog("exportKeychainItems: NULL item\n");
-                       MacOSError::throwMe(paramErr);
+                       MacOSError::throwMe(errSecParam);
                }
                CFTypeID itemType = CFGetTypeID(item);
                if(itemType == SecCertificateGetTypeID()) {
                }
                CFTypeID itemType = CFGetTypeID(item);
                if(itemType == SecCertificateGetTypeID()) {
@@ -213,7 +212,7 @@ void P12Coder::exportKeychainItems(
                }
                else {
                        p12ErrorLog("exportKeychainItems: unknown item\n");
                }
                else {
                        p12ErrorLog("exportKeychainItems: unknown item\n");
-                       MacOSError::throwMe(paramErr);          
+                       MacOSError::throwMe(errSecParam);               
                }
        }
 }
                }
        }
 }
@@ -246,10 +245,10 @@ static OSStatus attrNameToInt(
                const CSSM_DB_SCHEMA_ATTRIBUTE_INFO *info = &attrList[dex];
                if(!strcmp(name, info->AttributeName)) {
                        *attrInt = info->AttributeId;
                const CSSM_DB_SCHEMA_ATTRIBUTE_INFO *info = &attrList[dex];
                if(!strcmp(name, info->AttributeName)) {
                        *attrInt = info->AttributeId;
-                       return noErr;
+                       return errSecSuccess;
                }
        }
                }
        }
-       return paramErr;
+       return errSecParam;
 }
 
 void P12Coder::addSecKey(
 }
 
 void P12Coder::addSecKey(
@@ -315,7 +314,7 @@ void P12Coder::addSecKey(
                }
                else {
                        p12ErrorLog("addSecKey: unexpected attr tag\n");
                }
                else {
                        p12ErrorLog("addSecKey: unexpected attr tag\n");
-                       MacOSError::throwMe(paramErr);          
+                       MacOSError::throwMe(errSecParam);               
                        
                }
        }
                        
                }
        }
@@ -412,7 +411,7 @@ void P12Coder::addSecCert(
                                break;
                        default:
                                p12ErrorLog("addSecCert: unexpected attr tag\n");
                                break;
                        default:
                                p12ErrorLog("addSecCert: unexpected attr tag\n");
-                               MacOSError::throwMe(paramErr);          
+                               MacOSError::throwMe(errSecParam);               
                        
                }
        }
                        
                }
        }
index a19bb2fb8a3eff6eb2e86a472a1ea42567413293..4a58131144ec45e020edcec41669dab57a3f8105 100644 (file)
@@ -139,7 +139,7 @@ void P12SafeBag::friendlyName(
        }
        
        /* convert unicode to byte array */
        }
        
        /* convert unicode to byte array */
-       unsigned flen = len * sizeof(UniChar);
+       unsigned flen = (unsigned)(len * sizeof(UniChar));
        mCoder.allocItem(mFriendlyName, flen);
        unsigned char *cp = mFriendlyName.Data;
        for(CFIndex dex=0; dex<len; dex++) {
        mCoder.allocItem(mFriendlyName, flen);
        unsigned char *cp = mFriendlyName.Data;
        for(CFIndex dex=0; dex<len; dex++) {
@@ -206,7 +206,7 @@ CFStringRef P12SafeBag::friendlyName()
        assert((mFriendlyName.Length & 1) == 0);
        
        /* convert byte array to unicode */
        assert((mFriendlyName.Length & 1) == 0);
        
        /* convert byte array to unicode */
-       unsigned strLen = mFriendlyName.Length / 2;
+       unsigned long strLen = mFriendlyName.Length / 2;
        UniChar *uc = (UniChar *)malloc(strLen * sizeof(UniChar));
        const uint8 *inp = mFriendlyName.Data;
        UniChar *outp = uc;
        UniChar *uc = (UniChar *)malloc(strLen * sizeof(UniChar));
        const uint8 *inp = mFriendlyName.Data;
        UniChar *outp = uc;
index 813406ec5484e45520ef8086560ed330bb22eab0..e2040dcde94a93f5f9834857a9e67c68c8049f3a 100644 (file)
@@ -39,7 +39,6 @@
 #include <Security/oidsattr.h>
 #include <Security/oidsalg.h>
 #include <Security/cssmapple.h>
 #include <Security/oidsattr.h>
 #include <Security/oidsalg.h>
 #include <Security/cssmapple.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 
 /* malloc a NULL-ed array of pointers of size num+1 */
 void **p12NssNullArray(
 
 /* malloc a NULL-ed array of pointers of size num+1 */
 void **p12NssNullArray(
@@ -62,7 +61,7 @@ bool p12DataToInt(
                u = 0;
                return true;
        }
                u = 0;
                return true;
        }
-       uint32 len = cdata.Length;
+       CSSM_SIZE len = cdata.Length;
        if(len > sizeof(uint32)) {
                return false;
        }
        if(len > sizeof(uint32)) {
                return false;
        }
@@ -824,9 +823,9 @@ void p12ImportPassPhrase(
                inPhrase, kCFStringEncodingUTF8, 0);
        if(cfData == NULL) {
                p12ErrorLog("***p12ImportPassPhrase: can't convert passphrase to UTF8\n");
                inPhrase, kCFStringEncodingUTF8, 0);
        if(cfData == NULL) {
                p12ErrorLog("***p12ImportPassPhrase: can't convert passphrase to UTF8\n");
-               MacOSError::throwMe(paramErr);
+               MacOSError::throwMe(errSecParam);
        }
        }
-       unsigned keyLen = CFDataGetLength(cfData);
+       CFIndex keyLen = CFDataGetLength(cfData);
        coder.allocItem(outPhrase, keyLen);
        memmove(outPhrase.Data, CFDataGetBytePtr(cfData), keyLen);
        CFRelease(cfData);
        coder.allocItem(outPhrase, keyLen);
        memmove(outPhrase.Data, CFDataGetBytePtr(cfData), keyLen);
        CFRelease(cfData);
index d27b264f2f4bb119164c22fa222c8f45a451c30e..342d7f565d76f7965a4620f913f78686f0345ab1 100644 (file)
@@ -33,7 +33,6 @@
 #include <security_pkcs12/pkcs12Templates.h>
 #include <Security/cssmerr.h>
 #include <CoreFoundation/CoreFoundation.h>
 #include <security_pkcs12/pkcs12Templates.h>
 #include <Security/cssmerr.h>
 #include <CoreFoundation/CoreFoundation.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 
 #ifdef __cplusplus
 extern "C" {
 
 #ifdef __cplusplus
 extern "C" {
@@ -175,7 +174,7 @@ void p12ImportPassPhrase(
  * P12_ENCODE_ERR only occurs on DER-encode which should never fail. 
  */
 #define P12_DECODE_ERR         errSecUnknownFormat
  * P12_ENCODE_ERR only occurs on DER-encode which should never fail. 
  */
 #define P12_DECODE_ERR         errSecUnknownFormat
-#define P12_ENCODE_ERR         internalComponentErr
+#define P12_ENCODE_ERR         errSecInternalComponent
 #define P12_THROW_DECODE       MacOSError::throwMe(P12_DECODE_ERR)
 #define P12_THROW_ENCODE       MacOSError::throwMe(P12_ENCODE_ERR)
 
 #define P12_THROW_DECODE       MacOSError::throwMe(P12_DECODE_ERR)
 #define P12_THROW_ENCODE       MacOSError::throwMe(P12_ENCODE_ERR)
 
index 37d42ddfac9a5264b80d1403c3d0d636cc1e4c21..4bd7dc03feb825faf43efb5bb0fea58be601cfd2 100644 (file)
                0592AC85041551E100003D05 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
                0592AC85041551E100003D05 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0420;
+                               LastUpgradeCheck = 0500;
                        };
                        buildConfigurationList = C27AD3C80987FCDF001272E0 /* Build configuration list for PBXProject "libsecurity_pkcs12" */;
                        compatibilityVersion = "Xcode 3.2";
                        };
                        buildConfigurationList = C27AD3C80987FCDF001272E0 /* Build configuration list for PBXProject "libsecurity_pkcs12" */;
                        compatibilityVersion = "Xcode 3.2";
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB3D8146F1F86000BF1F3 /* debug.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB3D8146F1F86000BF1F3 /* debug.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB3DA146F1F86000BF1F3 /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB3DA146F1F86000BF1F3 /* release.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB3D9146F1F86000BF1F3 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB3D9146F1F86000BF1F3 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB3D9146F1F86000BF1F3 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB3D9146F1F86000BF1F3 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
index 574b6c9b33c9091f09f076cd912b96c5d74995fd..dc9a5de3bcb518527605dd54a4230ffd07f83bb2 100644 (file)
@@ -242,7 +242,7 @@ SDCSPSession::DeriveKey(CSSM_CC_HANDLE ccHandle,
                {
                        // special interpretation: take DLDBHandle -> DbHandle from params
                        clientSession().extractMasterKey(ClientSession::toIPCHandle(database), context,
                {
                        // special interpretation: take DLDBHandle -> DbHandle from params
                        clientSession().extractMasterKey(ClientSession::toIPCHandle(database), context,
-                               getDatabase(param.interpretedAs<CSSM_DL_DB_HANDLE>(CSSMERR_CSP_INVALID_ATTR_DL_DB_HANDLE)),
+                               (DbHandle)getDatabase(param.interpretedAs<CSSM_DL_DB_HANDLE>(CSSMERR_CSP_INVALID_ATTR_DL_DB_HANDLE)),
                                keyUsage, keyAttr, cred, owner, keyHandle, derivedKey.header());
                }
                break;
                                keyUsage, keyAttr, cred, owner, keyHandle, derivedKey.header());
                }
                break;
index 25850f329dcb17584c460b92e2766e9bb1abebb0..3eaafd8b476f2048dbcb3eecc2ffc5ee6018c23b 100644 (file)
@@ -282,7 +282,7 @@ size_t SDSignatureContext::outputSize(bool final, size_t inSize)
                        /* FIXME - what to use for inSize here - we don't want to 
                         * interrogate mDigest, as that would result in another RPC...
                         * and signature size is not related to input size...right? */
                        /* FIXME - what to use for inSize here - we don't want to 
                         * interrogate mDigest, as that would result in another RPC...
                         * and signature size is not related to input size...right? */
-                       inSize,
+                       (uint32)inSize,
                        true);
                ssCryptDebug("===sig outputSize(RPC) %u", (unsigned)outSize);
                return (size_t)outSize;
                        true);
                ssCryptDebug("===sig outputSize(RPC) %u", (unsigned)outSize);
                return (size_t)outSize;
@@ -428,7 +428,7 @@ SDCryptContext::outputSize(bool final, size_t inSize)
                /* out-of-band case, ask CSP via SS */
                uint32 outSize = clientSession().getOutputSize(*mContext, 
                        mKeyHandle, 
                /* out-of-band case, ask CSP via SS */
                uint32 outSize = clientSession().getOutputSize(*mContext, 
                        mKeyHandle, 
-                       inBufSize + inSize,
+                       (uint32)(inBufSize + inSize),
                        encoding());
                ssCryptDebug("   ===outSize(RPC) %u", (unsigned)outSize);
                return (size_t)outSize;
                        encoding());
                ssCryptDebug("   ===outSize(RPC) %u", (unsigned)outSize);
                return (size_t)outSize;
@@ -470,7 +470,7 @@ SDCryptContext::final(CssmData &out)
        if(!inSize) return;
 
        const CssmData in(const_cast<void *>(mNullDigest.digestPtr()), inSize);
        if(!inSize) return;
 
        const CssmData in(const_cast<void *>(mNullDigest.digestPtr()), inSize);
-       IFDEBUG(unsigned origOutSize = out.length());
+       IFDEBUG(size_t origOutSize = out.length());
        if (encoding()) {
                clientSession().encrypt(*mContext, mKeyHandle, in, out);
        }
        if (encoding()) {
                clientSession().encrypt(*mContext, mKeyHandle, in, out);
        }
@@ -518,7 +518,7 @@ size_t SDDigestContext::outputSize(bool final, size_t inSize)
                return 0;
        }
        else {
                return 0;
        }
        else {
-               return (size_t)mDigest->getOutputSize(inSize);
+               return (size_t)mDigest->getOutputSize((uint32)inSize);
        }
 }
 
        }
 }
 
@@ -573,7 +573,7 @@ size_t SDMACContext::outputSize(bool final, size_t inSize)
                /* out-of-band case, ask CSP via SS */
                uint32 outSize = clientSession().getOutputSize(*mContext, 
                        mKeyHandle, 
                /* out-of-band case, ask CSP via SS */
                uint32 outSize = clientSession().getOutputSize(*mContext, 
                        mKeyHandle, 
-                       inSize + mNullDigest.digestSizeInBytes(),
+                       (uint32)(inSize + mNullDigest.digestSizeInBytes()),
                        true);
                ssCryptDebug("===mac outputSize(RPC) %u", (unsigned)outSize);
                return (size_t)outSize;
                        true);
                ssCryptDebug("===mac outputSize(RPC) %u", (unsigned)outSize);
                return (size_t)outSize;
index b47843f6a37e11a017ca6188dd9e2b0d27d788e5..e52140e43e65f8ee52a95da0cec911108b6cdfd2 100644 (file)
@@ -96,7 +96,6 @@ private:
        /* alg-dependent, calculated at init time */
        CSSM_ALGORITHMS mSigAlg;                // raw signature alg
        CSSM_ALGORITHMS mDigestAlg;             // digest
        /* alg-dependent, calculated at init time */
        CSSM_ALGORITHMS mSigAlg;                // raw signature alg
        CSSM_ALGORITHMS mDigestAlg;             // digest
-       CSSM_ALGORITHMS mOrigAlg;               // caller's context alg
        
        /* exactly one of these is used to collect updates */
        NullDigest                      *mNullDigest;
        
        /* exactly one of these is used to collect updates */
        NullDigest                      *mNullDigest;
index ac064947d96da1daeb13845e89e0d4007ac294aa..00a597746f4300327e580b42d6435e865a3aa639 100644 (file)
@@ -141,7 +141,7 @@ SDDLSession::Authenticate(CSSM_DB_HANDLE inDbHandle,
                           CSSM_DB_ACCESS_TYPE inAccessRequest,
                           const AccessCredentials &inAccessCred)
 {
                           CSSM_DB_ACCESS_TYPE inAccessRequest,
                           const AccessCredentials &inAccessCred)
 {
-    mClientSession.authenticateDb(inDbHandle, inAccessRequest, &inAccessCred);
+    mClientSession.authenticateDb((DbHandle)inDbHandle, inAccessRequest, &inAccessCred);
 }
 
 
 }
 
 
index 3fffcc702b298a465d12acc0ba993c944ac9bffb..a6bc5c427f580d675eb9204b91fc33358e0aca44 100644 (file)
@@ -147,7 +147,6 @@ SDKey::SDKey(SDDLSession &session, CssmKey &ioKey, KeyHandle hKey, CSSM_DB_HANDL
                         CssmData &keyBlob)
 : ReferencedKey(session.mSDCSPDLSession),
 mAllocator(session.allocator()), mKeyHandle(hKey), mRecord(record),
                         CssmData &keyBlob)
 : ReferencedKey(session.mSDCSPDLSession),
 mAllocator(session.allocator()), mKeyHandle(hKey), mRecord(record),
-mRecordType(recordType),
 mClientSession(session.clientSession())
 {
        CssmKey::Header &header = ioKey.header();
 mClientSession(session.clientSession())
 {
        CssmKey::Header &header = ioKey.header();
index 7cb870a15f7e6f373e128df6f4a8185de9e1c38a..2103bba2e1eded41fba20296580b3af492c58faf 100644 (file)
@@ -78,7 +78,6 @@ private:
        SecurityServer::KeyHandle mKeyHandle;
        CSSM_DB_HANDLE mDatabase;
        SecurityServer::RecordHandle mRecord;
        SecurityServer::KeyHandle mKeyHandle;
        CSSM_DB_HANDLE mDatabase;
        SecurityServer::RecordHandle mRecord;
-       CSSM_DB_RECORDTYPE mRecordType;
        SecurityServer::ClientSession &mClientSession;
 };
 
        SecurityServer::ClientSession &mClientSession;
 };
 
index 0754ad71b9268080e18bc3f4d403cb57235cfb05..4d506670f43a193c9ba5ba139ad4f91a05bc2643 100644 (file)
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0420;
+                               LastUpgradeCheck = 0500;
                        };
                        buildConfigurationList = C27AD3DE0987FCDF001272E0 /* Build configuration list for PBXProject "libsecurity_sd_cspdl" */;
                        compatibilityVersion = "Xcode 3.2";
                        };
                        buildConfigurationList = C27AD3DE0987FCDF001272E0 /* Build configuration list for PBXProject "libsecurity_sd_cspdl" */;
                        compatibilityVersion = "Xcode 3.2";
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB3C8146F1DE0000BF1F3 /* debug.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB3C8146F1DE0000BF1F3 /* debug.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                               WARNING_CFLAGS = (
+                                       "$(inherited)",
+                                       "-Wno-error=overloaded-virtual",
+                               );
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB3CA146F1DE0000BF1F3 /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB3CA146F1DE0000BF1F3 /* release.xcconfig */;
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                               WARNING_CFLAGS = (
+                                       "$(inherited)",
+                                       "-Wno-error=overloaded-virtual",
+                               );
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB3C9146F1DE0000BF1F3 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB3C9146F1DE0000BF1F3 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB3C9146F1DE0000BF1F3 /* lib.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB3C9146F1DE0000BF1F3 /* lib.xcconfig */;
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
index 1984b499c0f9f3d47eee932995d83ff4fff6c1d0..28ea8fd89301af1f189e964fc3d1c81889d5adc7 100644 (file)
@@ -194,7 +194,7 @@ SecCertificateRef CERT_FindUserCertByUsage(SecKeychainRef keychainOrArray,
     attrs[1].data = nickname;
 #else
     attrs[1].tag = kSecSerialNumberItemAttr;
     attrs[1].data = nickname;
 #else
     attrs[1].tag = kSecSerialNumberItemAttr;
-    attrs[1].length = strlen(serialNumber)+1;
+    attrs[1].length = (UInt32)strlen(serialNumber)+1;
     attrs[1].data = (uint8 *)serialNumber;
 #endif
     SecKeychainAttributeList attrList = { 0, attrs };
     attrs[1].data = (uint8 *)serialNumber;
 #endif
     SecKeychainAttributeList attrList = { 0, attrs };
@@ -765,7 +765,7 @@ loser:
 CFTypeRef
 CERT_PolicyForCertUsage(SECCertUsage certUsage)
 {
 CFTypeRef
 CERT_PolicyForCertUsage(SECCertUsage certUsage)
 {
-    SecPolicySearchRef search;
+    SecPolicySearchRef search = NULL;
     SecPolicyRef policy = NULL;
     const CSSM_OID *policyOID;
     OSStatus rv;
     SecPolicyRef policy = NULL;
     const CSSM_OID *policyOID;
     OSStatus rv;
@@ -808,6 +808,6 @@ CERT_PolicyForCertUsage(SECCertUsage certUsage)
        goto loser;
 
 loser:
        goto loser;
 
 loser:
-    CFRelease(search);
+    if(search) CFRelease(search);
     return policy;
 }
     return policy;
 }
index 0ee039dc0f5ad4b9866dcef6d3e325818f02fc3f..6e8a3ebaf1a5b0d0a8af283cc119702c085ee656 100644 (file)
@@ -536,6 +536,9 @@ const SecAsn1Template NSS_SMIMEKEAParamTemplateAllParams[] = {
        { 0 }
 };
 
        { 0 }
 };
 
+/*TODO: this should be in some header */
+const SecAsn1Template *
+nss_cms_get_kea_template(SecCmsKEATemplateSelector whichTemplate);
 const SecAsn1Template *
 nss_cms_get_kea_template(SecCmsKEATemplateSelector whichTemplate)
 {
 const SecAsn1Template *
 nss_cms_get_kea_template(SecCmsKEATemplateSelector whichTemplate)
 {
index 6e896ff32ce72e2987b953c4476675b6ab10eed7..6165481b0fe5047c136a045faab9f14e230825a9 100644 (file)
@@ -83,7 +83,7 @@ SecCmsAttributeCreate(PRArenaPool *poolp, SECOidTag oidtag, CSSM_DATA_PTR value,
        goto loser;
 
     if (value != NULL) {
        goto loser;
 
     if (value != NULL) {
-       if ((copiedvalue = SECITEM_AllocItem(poolp, NULL, value->Length)) == NULL)
+       if ((copiedvalue = SECITEM_AllocItem(poolp, NULL, (unsigned int)value->Length)) == NULL)
            goto loser;
 
        if (SECITEM_CopyItem(poolp, copiedvalue, value) != SECSuccess)
            goto loser;
 
        if (SECITEM_CopyItem(poolp, copiedvalue, value) != SECSuccess)
index 60ee4501617f14a2f9cc6a5802527fdbea2b8a8d..02ec08733086aae3d30ae749e123587b4310b27c 100644 (file)
@@ -98,7 +98,7 @@ static long
 DER_GetInteger(SECItem *it)
 {
     long ival = 0;
 DER_GetInteger(SECItem *it)
 {
     long ival = 0;
-    unsigned len = it->Length;
+    CSSM_SIZE len = it->Length;
     unsigned char *cp = it->Data;
     unsigned long overflow = 0x1ffUL << (((sizeof(ival) - 1) * 8) - 1);
     unsigned long ofloinit;
     unsigned char *cp = it->Data;
     unsigned long overflow = 0x1ffUL << (((sizeof(ival) - 1) * 8) - 1);
     unsigned long ofloinit;
@@ -615,7 +615,7 @@ SecCmsCipherContextDestroy(SecCmsCipherContextRef cc)
     PORT_Free(cc);
 }
 
     PORT_Free(cc);
 }
 
-unsigned int
+static unsigned int
 SecCmsCipherContextLength(SecCmsCipherContextRef cc, unsigned int input_len, Boolean final, Boolean encrypt)
 {
     CSSM_QUERY_SIZE_DATA dataBlockSize[2] = { { input_len, 0 }, { input_len, 0 } };
 SecCmsCipherContextLength(SecCmsCipherContextRef cc, unsigned int input_len, Boolean final, Boolean encrypt)
 {
     CSSM_QUERY_SIZE_DATA dataBlockSize[2] = { { input_len, 0 }, { input_len, 0 } };
@@ -655,7 +655,7 @@ size_t
 SecCmsCipherContextDecryptLength(SecCmsCipherContextRef cc, size_t input_len, Boolean final)
 {
 #if 1
 SecCmsCipherContextDecryptLength(SecCmsCipherContextRef cc, size_t input_len, Boolean final)
 {
 #if 1
-    return SecCmsCipherContextLength(cc, input_len, final, PR_FALSE);
+    return SecCmsCipherContextLength(cc, (unsigned int)input_len, final, PR_FALSE);
 #else
     int blocks, block_size;
 
 #else
     int blocks, block_size;
 
@@ -717,7 +717,7 @@ size_t
 SecCmsCipherContextEncryptLength(SecCmsCipherContextRef cc, size_t input_len, Boolean final)
 {
 #if 1
 SecCmsCipherContextEncryptLength(SecCmsCipherContextRef cc, size_t input_len, Boolean final)
 {
 #if 1
-    return SecCmsCipherContextLength(cc, input_len, final, PR_TRUE);
+    return SecCmsCipherContextLength(cc, (unsigned int)input_len, final, PR_TRUE);
 #else
     int blocks, block_size;
     int pad_size;
 #else
     int blocks, block_size;
     int pad_size;
@@ -761,7 +761,7 @@ SecCmsCipherContextEncryptLength(SecCmsCipherContextRef cc, size_t input_len, Bo
 }
 
 
 }
 
 
-OSStatus
+static OSStatus
 SecCmsCipherContextCrypt(SecCmsCipherContextRef cc, unsigned char *output,
                  size_t *output_len_p, size_t max_output_len,
                  const unsigned char *input, size_t input_len,
 SecCmsCipherContextCrypt(SecCmsCipherContextRef cc, unsigned char *output,
                  size_t *output_len_p, size_t max_output_len,
                  const unsigned char *input, size_t input_len,
index 732c3307010ce2f974ada59790a6d694b28801df..f9ce1257a244860326c7fedb665495a4b9683f90 100644 (file)
@@ -421,7 +421,7 @@ nss_cms_decoder_work_data(SecCmsDecoderRef p7dcx,
     SecCmsContentInfoRef cinfo;
     unsigned char *buf = NULL;
     unsigned char *dest;
     SecCmsContentInfoRef cinfo;
     unsigned char *buf = NULL;
     unsigned char *dest;
-    unsigned int offset;
+    CSSM_SIZE offset;
     OSStatus rv;
     CSSM_DATA_PTR storage;
     
     OSStatus rv;
     CSSM_DATA_PTR storage;
     
index df9d463fa85a25787978cf6bf8271c33c30b6e79..edfe98e2b38ce43140a3eb1d3270f25e102d2089 100644 (file)
@@ -43,6 +43,8 @@
 #include <security_asn1/secerr.h>
 #include <Security/cssmapi.h>
 
 #include <security_asn1/secerr.h>
 #include <Security/cssmapi.h>
 
+#include <Security/SecCmsDigestContext.h>
+
 
 struct SecCmsDigestContextStr {
     Boolean            saw_contents;
 
 struct SecCmsDigestContextStr {
     Boolean            saw_contents;
@@ -90,8 +92,15 @@ SecCmsDigestContextStartMultiple(SECAlgorithmID **digestalgs)
         * but we cannot know that until later.
         */
        if (digobj)
         * but we cannot know that until later.
         */
        if (digobj)
-           CSSM_DigestDataInit(digobj);
-
+        {
+            CSSM_RETURN result;
+           result = CSSM_DigestDataInit(digobj);
+            if (result != CSSM_OK)
+            {
+                goto loser;
+            }
+        }
+        
        cmsdigcx->digobjs[cmsdigcx->digcnt] = digobj;
        cmsdigcx->digcnt++;
     }
        cmsdigcx->digobjs[cmsdigcx->digcnt] = digobj;
        cmsdigcx->digcnt++;
     }
@@ -156,7 +165,7 @@ SecCmsDigestContextCancel(SecCmsDigestContextRef cmsdigcx)
  *  into an array of CSSM_DATAs (allocated on poolp)
  */
 OSStatus
  *  into an array of CSSM_DATAs (allocated on poolp)
  */
 OSStatus
-SecCmsDigestContextFinishMultiple(SecCmsDigestContextRef cmsdigcx, PLArenaPool *poolp,
+SecCmsDigestContextFinishMultiple(SecCmsDigestContextRef cmsdigcx, SecArenaPoolRef poolp,
                            CSSM_DATA_PTR **digestsp)
 {
     CSSM_CC_HANDLE digobj;
                            CSSM_DATA_PTR **digestsp)
 {
     CSSM_CC_HANDLE digobj;
@@ -176,11 +185,11 @@ SecCmsDigestContextFinishMultiple(SecCmsDigestContextRef cmsdigcx, PLArenaPool *
        goto cleanup;
     }
 
        goto cleanup;
     }
 
-    mark = PORT_ArenaMark (poolp);
+    mark = PORT_ArenaMark ((PLArenaPool *)poolp);
 
     /* allocate digest array & CSSM_DATAs on arena */
 
     /* allocate digest array & CSSM_DATAs on arena */
-    digests = (CSSM_DATA_PTR *)PORT_ArenaAlloc(poolp, (cmsdigcx->digcnt+1) * sizeof(CSSM_DATA_PTR));
-    digest = (CSSM_DATA_PTR)PORT_ArenaZAlloc(poolp, cmsdigcx->digcnt * sizeof(CSSM_DATA));
+    digests = (CSSM_DATA_PTR *)PORT_ArenaAlloc((PLArenaPool *)poolp, (cmsdigcx->digcnt+1) * sizeof(CSSM_DATA_PTR));
+    digest = (CSSM_DATA_PTR)PORT_ArenaZAlloc((PLArenaPool *)poolp, cmsdigcx->digcnt * sizeof(CSSM_DATA));
     if (digests == NULL || digest == NULL) {
        goto loser;
     }
     if (digests == NULL || digest == NULL) {
        goto loser;
     }
@@ -188,16 +197,26 @@ SecCmsDigestContextFinishMultiple(SecCmsDigestContextRef cmsdigcx, PLArenaPool *
     for (i = 0; i < cmsdigcx->digcnt; i++, digest++) {
        digobj = cmsdigcx->digobjs[i];
        CSSM_QUERY_SIZE_DATA dataSize;
     for (i = 0; i < cmsdigcx->digcnt; i++, digest++) {
        digobj = cmsdigcx->digobjs[i];
        CSSM_QUERY_SIZE_DATA dataSize;
-       CSSM_QuerySize(digobj, CSSM_FALSE, 1, &dataSize);
+       rv = CSSM_QuerySize(digobj, CSSM_FALSE, 1, &dataSize);
+        if (rv != CSSM_OK)
+        {
+            goto loser;
+        }
+        
        int diglength = dataSize.SizeOutputBlock;
        
        if (digobj)
        {
        int diglength = dataSize.SizeOutputBlock;
        
        if (digobj)
        {
-           digest->Data = (unsigned char*)PORT_ArenaAlloc(poolp, diglength);
+           digest->Data = (unsigned char*)PORT_ArenaAlloc((PLArenaPool *)poolp, diglength);
            if (digest->Data == NULL)
                goto loser;
            digest->Length = diglength;
            if (digest->Data == NULL)
                goto loser;
            digest->Length = diglength;
-           CSSM_DigestDataFinal(digobj, digest);
+           rv = CSSM_DigestDataFinal(digobj, digest);
+            if (rv != CSSM_OK)
+            {
+                goto loser;
+            }
+            
            CSSM_DeleteContext(digobj);
        }
        else
            CSSM_DeleteContext(digobj);
        }
        else
@@ -215,9 +234,9 @@ SecCmsDigestContextFinishMultiple(SecCmsDigestContextRef cmsdigcx, PLArenaPool *
 
 loser:
     if (rv == SECSuccess)
 
 loser:
     if (rv == SECSuccess)
-       PORT_ArenaUnmark(poolp, mark);
+       PORT_ArenaUnmark((PLArenaPool *)poolp, mark);
     else
     else
-       PORT_ArenaRelease(poolp, mark);
+       PORT_ArenaRelease((PLArenaPool *)poolp, mark);
 
 cleanup:
     if (cmsdigcx->digcnt > 0) {
 
 cleanup:
     if (cmsdigcx->digcnt > 0) {
@@ -244,7 +263,7 @@ SecCmsDigestContextFinishSingle(SecCmsDigestContextRef cmsdigcx, SecArenaPoolRef
        goto loser;
 
     /* get the digests into arena, then copy the first digest into poolp */
        goto loser;
 
     /* get the digests into arena, then copy the first digest into poolp */
-    if (SecCmsDigestContextFinishMultiple(cmsdigcx, arena, &dp) != SECSuccess)
+    if (SecCmsDigestContextFinishMultiple(cmsdigcx, (SecArenaPoolRef)arena, &dp) != SECSuccess)
        goto loser;
 
     /* now copy it into poolp */
        goto loser;
 
     /* now copy it into poolp */
index 9b39c78a73ad276754b6d73ad45d2ff6bd6c67e2..0f4d9f42e0d0f22c73d0465d20ec82dc34662ded 100644 (file)
@@ -763,7 +763,7 @@ static OSStatus cmsNullWrapKey(
 /*
  * Free memory via specified plugin's app-level allocator
  */
 /*
  * Free memory via specified plugin's app-level allocator
  */
-void cmsFreeCssmMemory(
+static void cmsFreeCssmMemory(
     CSSM_HANDLE        hand,
     void       *p)
 {
     CSSM_HANDLE        hand,
     void       *p)
 {
@@ -1276,7 +1276,7 @@ SecCmsUtilDecryptSymKeyECDH(
      * Decode keyEncAlg.params to get KEK algorithm and IV
      */ 
     pool = PORT_NewArena(1024);
      * Decode keyEncAlg.params to get KEK algorithm and IV
      */ 
     pool = PORT_NewArena(1024);
-    if(pool = NULL) {
+    if(pool == NULL) {
        goto loser;
     }
     memset(&keyAlgParam, 0, sizeof(keyAlgParam));
        goto loser;
     }
     memset(&keyAlgParam, 0, sizeof(keyAlgParam));
index 3eee676120a2bb5a2ef4194e85074b91908c5522..dbecfbef7ffd2ef871c583fa41bc74575ff45f27 100644 (file)
@@ -45,8 +45,9 @@
 #include <security_asn1/secerr.h>
 #include <Security/SecKeyPriv.h>
 #include <Security/SecCertificatePriv.h>
 #include <security_asn1/secerr.h>
 #include <Security/SecKeyPriv.h>
 #include <Security/SecCertificatePriv.h>
+#include <Security/SecCmsRecipientInfo.h>
 
 
-Boolean
+static Boolean
 nss_cmsrecipientinfo_usessubjectkeyid(SecCmsRecipientInfoRef ri)
 {
     if (ri->recipientInfoType == SecCmsRecipientInfoIDKeyTrans) {
 nss_cmsrecipientinfo_usessubjectkeyid(SecCmsRecipientInfoRef ri)
 {
     if (ri->recipientInfoType == SecCmsRecipientInfoIDKeyTrans) {
@@ -60,7 +61,7 @@ nss_cmsrecipientinfo_usessubjectkeyid(SecCmsRecipientInfoRef ri)
 }
 
 
 }
 
 
-SecCmsRecipientInfoRef
+static SecCmsRecipientInfoRef
 nss_cmsrecipientinfo_create(SecCmsMessageRef cmsg, SecCmsRecipientIDSelector type,
                             SecCertificateRef cert, SecPublicKeyRef pubKey, 
                             CSSM_DATA_PTR subjKeyID)
 nss_cmsrecipientinfo_create(SecCmsMessageRef cmsg, SecCmsRecipientIDSelector type,
                             SecCertificateRef cert, SecPublicKeyRef pubKey, 
                             CSSM_DATA_PTR subjKeyID)
index 4e14124d854ee691f5fbcb45b353ea271d6aa0e5..e987374a76563cba3848ca32878daf7132a3c3d5 100644 (file)
@@ -251,6 +251,7 @@ xit:
 
 #include <Security/SecAsn1Templates.h>
 
 
 #include <Security/SecAsn1Templates.h>
 
+#ifndef NDEBUG
 static OSStatus decodeDERUTF8String(const CSSM_DATA_PTR content, char *statusstr, size_t strsz)
 {
     // The statusString should use kSecAsn1SequenceOfUTF8StringTemplate, but doesn't
 static OSStatus decodeDERUTF8String(const CSSM_DATA_PTR content, char *statusstr, size_t strsz)
 {
     // The statusString should use kSecAsn1SequenceOfUTF8StringTemplate, but doesn't
@@ -273,6 +274,7 @@ xit:
         SecAsn1CoderRelease(coder);
     return status;
 }
         SecAsn1CoderRelease(coder);
     return status;
 }
+#endif
 
 static OSStatus validateTSAResponseAndAddTimeStamp(SecCmsSignerInfoRef signerinfo, CSSM_DATA_PTR tsaResponse,
     uint64_t expectedNonce)
 
 static OSStatus validateTSAResponseAndAddTimeStamp(SecCmsSignerInfoRef signerinfo, CSSM_DATA_PTR tsaResponse,
     uint64_t expectedNonce)
@@ -282,7 +284,9 @@ static OSStatus validateTSAResponseAndAddTimeStamp(SecCmsSignerInfoRef signerinf
     SecAsn1TimeStampRespDER respDER = {{{0}},};
     SecAsn1TSAPKIStatusInfo *tsastatus = NULL;
     int respstatus = -1;
     SecAsn1TimeStampRespDER respDER = {{{0}},};
     SecAsn1TSAPKIStatusInfo *tsastatus = NULL;
     int respstatus = -1;
+#ifndef NDEBUG
     int failinfo = -1;
     int failinfo = -1;
+#endif
 
     require_action(tsaResponse && tsaResponse->Data && tsaResponse->Length, xit, status = errSecTimestampMissing);
 
 
     require_action(tsaResponse && tsaResponse->Data && tsaResponse->Length, xit, status = errSecTimestampMissing);
 
index 2ebac87f9765f151f76670c41421df08c8c186ff..4071fe39851528ab03756772c0b1d4a5ecca2cc3 100644 (file)
@@ -130,7 +130,7 @@ DER_UTCTimeToCFDate(const CSSM_DATA_PTR utcTime, CFAbsoluteTime *date)
         goto loser;
     }
 
         goto loser;
     }
 
-    gdate.year = year + 1900;
+    gdate.year = (SInt32)(year + 1900);
     gdate.month = month;
     gdate.day = mday;
     gdate.hour = hour;
     gdate.month = month;
     gdate.day = mday;
     gdate.hour = hour;
@@ -438,7 +438,7 @@ SecCmsSignerInfoSign(SecCmsSignerInfoRef signerinfo, CSSM_DATA_PTR digest, CSSM_
                        &encoded_attrs) == NULL)
            goto loser;
 
                        &encoded_attrs) == NULL)
            goto loser;
 
-       rv = SEC_SignData(&signature, encoded_attrs.Data, encoded_attrs.Length, 
+       rv = SEC_SignData(&signature, encoded_attrs.Data, (int)encoded_attrs.Length,
                          privkey, digestalgtag, pubkAlgTag);
        PORT_FreeArena(tmppoolp, PR_FALSE); /* awkward memory management :-( */
     } else {
                          privkey, digestalgtag, pubkAlgTag);
        PORT_FreeArena(tmppoolp, PR_FALSE); /* awkward memory management :-( */
     } else {
@@ -548,6 +548,7 @@ static void debugShowSigningCertificate(SecCmsSignerInfoRef signerinfo)
             dprintf("SecCmsSignerInfoVerify: cn: %s\n", ccn);
             free(ccn);
         }
             dprintf("SecCmsSignerInfoVerify: cn: %s\n", ccn);
             free(ccn);
         }
+        CFRelease(cn);
     }
 #endif
 }
     }
 #endif
 }
@@ -661,7 +662,7 @@ SecCmsSignerInfoVerify(SecCmsSignerInfoRef signerinfo, CSSM_DATA_PTR digest, CSS
            goto loser;
        }
 
            goto loser;
        }
 
-       vs = (VFY_VerifyData (encoded_attrs.Data, encoded_attrs.Length,
+       vs = (VFY_VerifyData (encoded_attrs.Data, (int)encoded_attrs.Length,
                        publickey, &(signerinfo->encDigest),
                        digestAlgTag, digestEncAlgTag,
                        signerinfo->cmsg->pwfn_arg) != SECSuccess) ? SecCmsVSBadSignature : SecCmsVSGoodSignature;
                        publickey, &(signerinfo->encDigest),
                        digestAlgTag, digestEncAlgTag,
                        signerinfo->cmsg->pwfn_arg) != SECSuccess) ? SecCmsVSBadSignature : SecCmsVSGoodSignature;
@@ -953,7 +954,7 @@ SecCmsSignerInfoGetSignerCommonName(SecCmsSignerInfoRef sinfo)
     if ((signercert = SecCmsSignerInfoGetSigningCertificate(sinfo, NULL)) == NULL)
        return NULL;
 
     if ((signercert = SecCmsSignerInfoGetSigningCertificate(sinfo, NULL)) == NULL)
        return NULL;
 
-    SecCertificateGetCommonName(signercert, &commonName);
+    SecCertificateCopyCommonName(signercert, &commonName);
 
     return commonName;
 }
 
     return commonName;
 }
index 80bd279219daa9ce792a0755d44ac7cf69af8861..020460cf61815096733b0440b71a87789b0e4c36 100644 (file)
@@ -36,7 +36,7 @@
  */
 
 #include <Security/SecCmsEncoder.h> /* @@@ Remove this when we move the Encoder method. */
  */
 
 #include <Security/SecCmsEncoder.h> /* @@@ Remove this when we move the Encoder method. */
-
+#include <Security/SecCmsSignerInfo.h>
 #include "cmslocal.h"
 
 #include "secitem.h"
 #include "cmslocal.h"
 
 #include "secitem.h"
index c6ec7aa3e025e4afc62d1c03c66deafaa0bda42f..fd31af5ab33f9c3f2f2d943dea1287e9207dc0e3 100644 (file)
@@ -137,7 +137,7 @@ SECITEM_ReallocItem(PRArenaPool *arena, SECItem *item, unsigned int oldlen,
 SECComparison
 SECITEM_CompareItem(const SECItem *a, const SECItem *b)
 {
 SECComparison
 SECITEM_CompareItem(const SECItem *a, const SECItem *b)
 {
-    unsigned m;
+    CSSM_SIZE m;
     SECComparison rv;
 
     m = ( ( a->Length < b->Length ) ? a->Length : b->Length );
     SECComparison rv;
 
     m = ( ( a->Length < b->Length ) ? a->Length : b->Length );
index 283c54dfd541694b497f58c5a304e41709ec5241..0853144c2234fee970fda90cfea88cd43be496eb 100644 (file)
@@ -1227,6 +1227,7 @@ loser:
     return rtn;
 }
 
     return rtn;
 }
 
+#if 0
 SECStatus
 SECOID_AddEntry(SECItem *oid, char *description, CSSM_ALGORITHMS cssmAlgorithm) {
     SECOidData *oiddp;
 SECStatus
 SECOID_AddEntry(SECItem *oid, char *description, CSSM_ALGORITHMS cssmAlgorithm) {
     SECOidData *oiddp;
@@ -1284,6 +1285,7 @@ loser:
     pthread_mutex_unlock(&oid_hash_mutex);    
     return srtn;
 }
     pthread_mutex_unlock(&oid_hash_mutex);    
     return srtn;
 }
+#endif
        
 
 /* normal static table processing */
        
 
 /* normal static table processing */
index db3707fd8c982030f81debfa8b148ed5f3b9f4d2..eacec1a08d2ab547359dcb56b25fc0645fc862ae 100644 (file)
@@ -330,7 +330,7 @@ SecSMIMEEncryptionPossible(void)
 }
 
 
 }
 
 
-static int
+static unsigned long
 nss_SMIME_FindCipherForSMIMECap(NSSSMIMECapability *cap)
 {
     int i;
 nss_SMIME_FindCipherForSMIMECap(NSSSMIMECapability *cap)
 {
     int i;
@@ -776,6 +776,7 @@ extern const char __nss_smime_rcsid[];
 extern const char __nss_smime_sccsid[];
 #endif
 
 extern const char __nss_smime_sccsid[];
 #endif
 
+#if 0 /* -- unused */
 Boolean
 NSSSMIME_VersionCheck(const char *importedVersion)
 {
 Boolean
 NSSSMIME_VersionCheck(const char *importedVersion)
 {
@@ -798,4 +799,4 @@ NSSSMIME_VersionCheck(const char *importedVersion)
     return NSS_VersionCheck(importedVersion);
 #endif
 }
     return NSS_VersionCheck(importedVersion);
 #endif
 }
-
+#endif
index a2d05662d2a9bebae67c448e854d6692e35765e0..e894fc7406081759d2516aa605f72b22c8ca8537 100644 (file)
@@ -1,15 +1,15 @@
 /*
  * Copyright (c) 2012 Apple Computer, Inc. All Rights Reserved.
 /*
  * Copyright (c) 2012 Apple Computer, Inc. All Rights Reserved.
- * 
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  *
  * tsaSupport.c -  ASN1 templates Time Stamping Authority requests and responses
  * @APPLE_LICENSE_HEADER_END@
  *
  * tsaSupport.c -  ASN1 templates Time Stamping Authority requests and responses
@@ -67,7 +67,7 @@ extern const SecAsn1Template kSecAsn1TSATSTInfoTemplate[];
 extern OSStatus impExpImportCertCommon(
        const CSSM_DATA         *cdata,
        SecKeychainRef          importKeychain, // optional
 extern OSStatus impExpImportCertCommon(
        const CSSM_DATA         *cdata,
        SecKeychainRef          importKeychain, // optional
-       CFMutableArrayRef       outArray);              // optional, append here 
+       CFMutableArrayRef       outArray);              // optional, append here
 
 #pragma mark ----- Debug Logs -----
 
 
 #pragma mark ----- Debug Logs -----
 
@@ -149,7 +149,7 @@ static OSStatus remapHTTPErrorCodes(OSStatus status)
         return status;
     }
     return status;
         return status;
     }
     return status;
-   
+
 }
 
 static void printDataAsHex(const char *title, const CSSM_DATA *d, unsigned maxToPrint) // 0 means print it all
 }
 
 static void printDataAsHex(const char *title, const CSSM_DATA *d, unsigned maxToPrint) // 0 means print it all
@@ -163,7 +163,7 @@ static void printDataAsHex(const char *title, const CSSM_DATA *d, unsigned maxTo
     size_t bufferSize;
     int offset, sz = 0;
     const int wrapwid = 24;     // large enough so SHA-1 hashes fit on one line...
     size_t bufferSize;
     int offset, sz = 0;
     const int wrapwid = 24;     // large enough so SHA-1 hashes fit on one line...
-    
+
     if ((maxToPrint != 0) && (len > maxToPrint))
     {
         len = maxToPrint;
     if ((maxToPrint != 0) && (len > maxToPrint))
     {
         len = maxToPrint;
@@ -172,7 +172,7 @@ static void printDataAsHex(const char *title, const CSSM_DATA *d, unsigned maxTo
 
     bufferSize = wrapwid+3*len;
     buffer = (char *)malloc(bufferSize);
 
     bufferSize = wrapwid+3*len;
     buffer = (char *)malloc(bufferSize);
-    
+
     offset = sprintf(buffer, "%s [len = %u]\n", title, len);
     dtprintf("%s", buffer);
     offset = 0;
     offset = sprintf(buffer, "%s [len = %u]\n", title, len);
     dtprintf("%s", buffer);
     offset = 0;
@@ -187,11 +187,11 @@ static void printDataAsHex(const char *title, const CSSM_DATA *d, unsigned maxTo
             sz = 0;
         }
     }
             sz = 0;
         }
     }
-    
+
     sz=sprintf(buffer + offset, more?" ...\n":"\n");
         offset += sz;
     buffer[offset+1]=0;
     sz=sprintf(buffer + offset, more?" ...\n":"\n");
         offset += sz;
     buffer[offset+1]=0;
-    
+
 //    fprintf(stderr, "%s", buffer);
     dtprintf("%s", buffer);
 #endif
 //    fprintf(stderr, "%s", buffer);
     dtprintf("%s", buffer);
 #endif
@@ -228,13 +228,13 @@ char *cfStringToChar(CFStringRef inStr)
     char *result = NULL;
     const char *str = NULL;
 
     char *result = NULL;
     const char *str = NULL;
 
-    if (!inStr)
+       if (!inStr)
         return strdup("");     // return a null string
 
         return strdup("");     // return a null string
 
-    // quick path first
-    if ((str = CFStringGetCStringPtr(inStr, kCFStringEncodingUTF8))) {
+       // quick path first
+       if ((str = CFStringGetCStringPtr(inStr, kCFStringEncodingUTF8))) {
         result = strdup(str);
         result = strdup(str);
-    } else {
+       } else {
         // need to extract into buffer
         CFIndex length = CFStringGetLength(inStr);  // in 16-bit character units
         CFIndex bytesToAllocate = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1;
         // need to extract into buffer
         CFIndex length = CFStringGetLength(inStr);  // in 16-bit character units
         CFIndex bytesToAllocate = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1;
@@ -242,15 +242,17 @@ char *cfStringToChar(CFStringRef inStr)
         if (!CFStringGetCString(inStr, result, bytesToAllocate, kCFStringEncodingUTF8))
             result[0] = 0;
     }
         if (!CFStringGetCString(inStr, result, bytesToAllocate, kCFStringEncodingUTF8))
             result[0] = 0;
     }
-
-    return result;
+    
+       return result;
 }
 
 /* Oids longer than this are considered invalid. */
 #define MAX_OID_SIZE                           32
 
 }
 
 /* Oids longer than this are considered invalid. */
 #define MAX_OID_SIZE                           32
 
+#ifndef NDEBUG
+/* FIXME: There are other versions of this in SecCertifcate.c and SecCertificateP.c */
 static CFStringRef SecDERItemCopyOIDDecimalRepresentation(CFAllocatorRef allocator, const CSSM_OID *oid)
 static CFStringRef SecDERItemCopyOIDDecimalRepresentation(CFAllocatorRef allocator, const CSSM_OID *oid)
-{      
+{
        if (oid->Length == 0)
         return CFSTR("<NULL>");
 
        if (oid->Length == 0)
         return CFSTR("<NULL>");
 
@@ -280,12 +282,13 @@ static CFStringRef SecDERItemCopyOIDDecimalRepresentation(CFAllocatorRef allocat
         /* A max number of 20 values is allowed. */
                if (!(oid->Data[x] & 0x80))
                {
         /* A max number of 20 values is allowed. */
                if (!(oid->Data[x] & 0x80))
                {
-            CFStringAppendFormat(result, NULL, CFSTR(".%lu"), value);
+            CFStringAppendFormat(result, NULL, CFSTR(".%lu"), (unsigned long)value);
                        value = 0;
                }
        }
        return result;
 }
                        value = 0;
                }
        }
        return result;
 }
+#endif
 
 static void debugSaveCertificates(CSSM_DATA **outCerts)
 {
 
 static void debugSaveCertificates(CSSM_DATA **outCerts)
 {
@@ -432,32 +435,32 @@ static OSStatus checkForNonDERResponse(const unsigned char *resp, size_t respLen
 {
     /*
         Good start is something like 30 82 0c 03 30 15 02 01  00 30 10 0c 0e 4f 70 65
 {
     /*
         Good start is something like 30 82 0c 03 30 15 02 01  00 30 10 0c 0e 4f 70 65
-    
+
         URL:    http://timestamp-int.corp.apple.com/signserver/process?TimeStampSigner
         Resp:   Http/1.1 Service Unavailable
         URL:    http://timestamp-int.corp.apple.com/signserver/process?TimeStampSigner
         Resp:   Http/1.1 Service Unavailable
-        
+
         URL:    http://timestamp-int.corp.apple.com/ts01
         Resp:   blank
         URL:    http://timestamp-int.corp.apple.com/ts01
         Resp:   blank
-        
+
         URL:    http://cutandtaste.com/404 (or other forced 404 site)
         Resp:   404
     */
         URL:    http://cutandtaste.com/404 (or other forced 404 site)
         Resp:   404
     */
-    
+
     OSStatus status = noErr;
     const char ader[2] = { 0x30, 0x82 };
     char *respStr = NULL;
     size_t maxlen = 0;
     size_t badResponseCount;
     OSStatus status = noErr;
     const char ader[2] = { 0x30, 0x82 };
     char *respStr = NULL;
     size_t maxlen = 0;
     size_t badResponseCount;
-    
+
     const char *badResponses[] =
     {
         "<!DOCTYPE html>",
         "Http/1.1 Service Unavailable",
         "blank"
     };
     const char *badResponses[] =
     {
         "<!DOCTYPE html>",
         "Http/1.1 Service Unavailable",
         "blank"
     };
-    
+
     require_action(resp && respLen, xit, status = errSecTimestampServiceNotAvailable);
     require_action(resp && respLen, xit, status = errSecTimestampServiceNotAvailable);
-    
+
     // This is usual case
     if ((respLen > 1) && (memcmp(resp, ader, 2)==0))    // might be good; pass on to DER decoder
         return noErr;
     // This is usual case
     if ((respLen > 1) && (memcmp(resp, ader, 2)==0))    // might be good; pass on to DER decoder
         return noErr;
@@ -471,14 +474,14 @@ static OSStatus checkForNonDERResponse(const unsigned char *resp, size_t respLen
     // Prevent a large response from allocating a ton of memory
     if (respLen > maxlen)
         respLen = maxlen;
     // Prevent a large response from allocating a ton of memory
     if (respLen > maxlen)
         respLen = maxlen;
-        
+
     respStr = (char *)malloc(respLen+1);
     strlcpy(respStr, (const char *)resp, respLen);
     respStr = (char *)malloc(respLen+1);
     strlcpy(respStr, (const char *)resp, respLen);
-    
+
     for (ix = 0; ix < badResponseCount; ++ix)
         if (strcmp(respStr, badResponses[ix])==0)
             return errSecTimestampServiceNotAvailable;
     for (ix = 0; ix < badResponseCount; ++ix)
         if (strcmp(respStr, badResponses[ix])==0)
             return errSecTimestampServiceNotAvailable;
-        
+
 xit:
     if (respStr)
         free((void *)respStr);
 xit:
     if (respStr)
         free((void *)respStr);
@@ -487,7 +490,7 @@ xit:
 }
 
 static OSStatus sendTSARequestWithXPC(const unsigned char *tsaReq, size_t tsaReqLength, const unsigned char *tsaURL, unsigned char **tsaResp, size_t *tsaRespLength)
 }
 
 static OSStatus sendTSARequestWithXPC(const unsigned char *tsaReq, size_t tsaReqLength, const unsigned char *tsaURL, unsigned char **tsaResp, size_t *tsaRespLength)
-{    
+{
     __block OSStatus result = noErr;
     int timeoutInSeconds = 15;
     extern xpc_object_t xpc_create_with_format(const char * format, ...);
     __block OSStatus result = noErr;
     int timeoutInSeconds = 15;
     extern xpc_object_t xpc_create_with_format(const char * format, ...);
@@ -503,7 +506,7 @@ static OSStatus sendTSARequestWithXPC(const unsigned char *tsaReq, size_t tsaReq
         if (XPC_TYPE_ERROR == xtype)
         {    tsaDebug("default: connection error: %s\n", xpc_dictionary_get_string(event, XPC_ERROR_KEY_DESCRIPTION)); }
         else
         if (XPC_TYPE_ERROR == xtype)
         {    tsaDebug("default: connection error: %s\n", xpc_dictionary_get_string(event, XPC_ERROR_KEY_DESCRIPTION)); }
         else
-         {   tsaDebug("default: unexpected connection event %p\n", event); } 
+         {   tsaDebug("default: unexpected connection event %p\n", event); }
     });
 
     xpc_connection_resume(con);
     });
 
     xpc_connection_resume(con);
@@ -534,14 +537,14 @@ static OSStatus sendTSARequestWithXPC(const unsigned char *tsaReq, size_t tsaReq
         free(debug);
          */
 #endif
         free(debug);
          */
 #endif
-        
+
         xpc_object_t xpcTimeStampReply = xpc_dictionary_get_value(reply, "TimeStampReply");
         size_t xpcTSRLength = xpc_data_get_length(xpcTimeStampReply);
         tsaDebug("xpcTSRLength: %ld bytes of response\n", xpcTSRLength);
 
         xpc_object_t xpcTimeStampError = xpc_dictionary_get_value(reply, "TimeStampError");
         xpc_object_t xpcTimeStampStatus = xpc_dictionary_get_value(reply, "TimeStampStatus");
         xpc_object_t xpcTimeStampReply = xpc_dictionary_get_value(reply, "TimeStampReply");
         size_t xpcTSRLength = xpc_data_get_length(xpcTimeStampReply);
         tsaDebug("xpcTSRLength: %ld bytes of response\n", xpcTSRLength);
 
         xpc_object_t xpcTimeStampError = xpc_dictionary_get_value(reply, "TimeStampError");
         xpc_object_t xpcTimeStampStatus = xpc_dictionary_get_value(reply, "TimeStampStatus");
-        
+
         if (xpcTimeStampError || xpcTimeStampStatus)
         {
 #ifndef NDEBUG
         if (xpcTimeStampError || xpcTimeStampStatus)
         {
 #ifndef NDEBUG
@@ -561,7 +564,7 @@ static OSStatus sendTSARequestWithXPC(const unsigned char *tsaReq, size_t tsaReq
                 tsaDebug("xpcTimeStampStatus: %d\n", (int)result);
             }
         }
                 tsaDebug("xpcTimeStampStatus: %d\n", (int)result);
             }
         }
-        
+
         result = remapHTTPErrorCodes(result);
 
         if ((result == noErr) && tsaResp && tsaRespLength)
         result = remapHTTPErrorCodes(result);
 
         if ((result == noErr) && tsaResp && tsaRespLength)
@@ -592,14 +595,14 @@ static OSStatus sendTSARequestWithXPC(const unsigned char *tsaReq, size_t tsaReq
         dispatch_semaphore_signal(waitSemaphore);
         dispatch_release(waitSemaphore);
     });
         dispatch_semaphore_signal(waitSemaphore);
         dispatch_release(waitSemaphore);
     });
-    
+
     { tsaDebug("waiting up to %d seconds for response from XPC\n", timeoutInSeconds); }
        dispatch_semaphore_wait(waitSemaphore, finishTime);
 
        dispatch_release(waitSemaphore);
     xpc_release(tsaReqData);
     xpc_release(message);
     { tsaDebug("waiting up to %d seconds for response from XPC\n", timeoutInSeconds); }
        dispatch_semaphore_wait(waitSemaphore, finishTime);
 
        dispatch_release(waitSemaphore);
     xpc_release(tsaReqData);
     xpc_release(message);
-    
+
     { tsaDebug("sendTSARequestWithXPC exit\n"); }
 
     return result;
     { tsaDebug("sendTSARequestWithXPC exit\n"); }
 
     return result;
@@ -621,7 +624,7 @@ CFMutableDictionaryRef SecCmsTSAGetDefaultContext(CFErrorRef *error)
     // Caller responsible for retain/release
     // <rdar://problem/11077440> Update SecCmsTSAGetDefaultContext with actual URL for Apple Timestamp server
     //      URL will be in TimeStampingPrefs.plist
     // Caller responsible for retain/release
     // <rdar://problem/11077440> Update SecCmsTSAGetDefaultContext with actual URL for Apple Timestamp server
     //      URL will be in TimeStampingPrefs.plist
-    
+
     CFBundleRef secFWbundle = NULL;
     CFURLRef resourceURL = NULL;
     CFDataRef resourceData = NULL;
     CFBundleRef secFWbundle = NULL;
     CFURLRef resourceURL = NULL;
     CFDataRef resourceData = NULL;
@@ -631,7 +634,7 @@ CFMutableDictionaryRef SecCmsTSAGetDefaultContext(CFErrorRef *error)
     CFOptionFlags options = 0;
     CFPropertyListFormat format = 0;
     OSStatus status = noErr;
     CFOptionFlags options = 0;
     CFPropertyListFormat format = 0;
     OSStatus status = noErr;
-    
+
     require_action(secFWbundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.security")), xit, status = errSecInternalError);
     require_action(resourceURL = CFBundleCopyResourceURL(secFWbundle, CFSTR("TimeStampingPrefs"), CFSTR("plist"), NULL),
         xit, status = errSecInvalidPrefsDomain);
     require_action(secFWbundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.security")), xit, status = errSecInternalError);
     require_action(resourceURL = CFBundleCopyResourceURL(secFWbundle, CFSTR("TimeStampingPrefs"), CFSTR("plist"), NULL),
         xit, status = errSecInvalidPrefsDomain);
@@ -642,7 +645,7 @@ CFMutableDictionaryRef SecCmsTSAGetDefaultContext(CFErrorRef *error)
 
     prefs = CFPropertyListCreateWithData(kCFAllocatorDefault, resourceData, options, &format, error);
     require_action(prefs && (CFGetTypeID(prefs)==CFDictionaryGetTypeID()), xit, status = errSecInvalidPrefsDomain);
 
     prefs = CFPropertyListCreateWithData(kCFAllocatorDefault, resourceData, options, &format, error);
     require_action(prefs && (CFGetTypeID(prefs)==CFDictionaryGetTypeID()), xit, status = errSecInvalidPrefsDomain);
-    
+
     contextDict = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, prefs);
 
     if (error)
     contextDict = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, prefs);
 
     if (error)
@@ -669,7 +672,7 @@ static CFDataRef _SecTSARequestCopyDEREncoding(SecAsn1TSAMessageImprint *message
     // Returns DER encoded TimeStampReq
     // Modeled on _SecOCSPRequestCopyDEREncoding
     // The Timestamp Authority supports 64 bit nonces (or more possibly)
     // Returns DER encoded TimeStampReq
     // Modeled on _SecOCSPRequestCopyDEREncoding
     // The Timestamp Authority supports 64 bit nonces (or more possibly)
-    
+
     SecAsn1CoderRef             coder = NULL;
     uint8_t                     version = 1;
     SecAsn1Item                 vers = {1, &version};
     SecAsn1CoderRef             coder = NULL;
     uint8_t                     version = 1;
     SecAsn1Item                 vers = {1, &version};
@@ -680,14 +683,14 @@ static CFDataRef _SecTSARequestCopyDEREncoding(SecAsn1TSAMessageImprint *message
     uint64_t                    nonceVal = OSSwapHostToBigConstInt64(nonce);
     SecAsn1Item                 nonceItem = {sizeof(uint64_t), (unsigned char *)&nonceVal};
 
     uint64_t                    nonceVal = OSSwapHostToBigConstInt64(nonce);
     SecAsn1Item                 nonceItem = {sizeof(uint64_t), (unsigned char *)&nonceVal};
 
-    uint8_t OID_FakePolicy_Data[] = { 0x2A, 0x03, 0x04, 0x05, 0x06};   
+    uint8_t OID_FakePolicy_Data[] = { 0x2A, 0x03, 0x04, 0x05, 0x06};
     const CSSM_OID fakePolicyOID = {sizeof(OID_FakePolicy_Data),OID_FakePolicy_Data};
 
     tsreq.version = vers;
 
     tsreq.messageImprint = *messageImprint;
     tsreq.certReq = certReq;
     const CSSM_OID fakePolicyOID = {sizeof(OID_FakePolicy_Data),OID_FakePolicy_Data};
 
     tsreq.version = vers;
 
     tsreq.messageImprint = *messageImprint;
     tsreq.certReq = certReq;
-    
+
     // skip reqPolicy, extensions for now - FAKES - jch
     tsreq.reqPolicy = fakePolicyOID;    //policyID;
 
     // skip reqPolicy, extensions for now - FAKES - jch
     tsreq.reqPolicy = fakePolicyOID;    //policyID;
 
@@ -695,7 +698,7 @@ static CFDataRef _SecTSARequestCopyDEREncoding(SecAsn1TSAMessageImprint *message
 
     // Encode the request
     require_noerr(SecAsn1CoderCreate(&coder), errOut);
 
     // Encode the request
     require_noerr(SecAsn1CoderCreate(&coder), errOut);
-    
+
     SecAsn1Item encoded;
     require_noerr(SecAsn1EncodeItem(coder, &tsreq,
         &kSecAsn1TSATimeStampReqTemplate, &encoded), errOut);
     SecAsn1Item encoded;
     require_noerr(SecAsn1EncodeItem(coder, &tsreq,
         &kSecAsn1TSATimeStampReqTemplate, &encoded), errOut);
@@ -713,7 +716,7 @@ OSStatus SecTSAResponseCopyDEREncoding(SecAsn1CoderRef coder, const CSSM_DATA *t
 {
     // Partially decode the response
     OSStatus status = paramErr;
 {
     // Partially decode the response
     OSStatus status = paramErr;
-    
+
     require(tsaResponse && respDER, errOut);
     require_noerr(SecAsn1DecodeData(coder, tsaResponse,
         &kSecAsn1TSATimeStampRespTemplateDER, respDER), errOut);
     require(tsaResponse && respDER, errOut);
     require_noerr(SecAsn1DecodeData(coder, tsaResponse,
         &kSecAsn1TSATimeStampRespTemplateDER, respDER), errOut);
@@ -734,10 +737,10 @@ OSStatus SecCmsTSADefaultCallback(CFTypeRef context, void *messageImprintV, uint
     CFDataRef cfreq = NULL;
     unsigned char *tsaURL = NULL;
     bool noCerts = false;
     CFDataRef cfreq = NULL;
     unsigned char *tsaURL = NULL;
     bool noCerts = false;
-    
+
     if (!context || CFGetTypeID(context)!=CFDictionaryGetTypeID())
         return paramErr;
     if (!context || CFGetTypeID(context)!=CFDictionaryGetTypeID())
         return paramErr;
-        
+
     SecAsn1TSAMessageImprint *messageImprint = (SecAsn1TSAMessageImprint *)messageImprintV;
     if (!messageImprint || !signedDERBlob)
         return paramErr;
     SecAsn1TSAMessageImprint *messageImprint = (SecAsn1TSAMessageImprint *)messageImprintV;
     if (!messageImprint || !signedDERBlob)
         return paramErr;
@@ -764,31 +767,31 @@ OSStatus SecCmsTSADefaultCallback(CFTypeRef context, void *messageImprintV, uint
     {
         tsaReq = CFDataGetBytePtr(cfreq);
         tsaReqLength = CFDataGetLength(cfreq);
     {
         tsaReq = CFDataGetBytePtr(cfreq);
         tsaReqLength = CFDataGetLength(cfreq);
-        
+
 #ifndef NDEBUG
         CFShow(cfreq);
         tsaWriteFileX("/tmp/tsareq.req", tsaReq, tsaReqLength);
 #endif
     }
 #ifndef NDEBUG
         CFShow(cfreq);
         tsaWriteFileX("/tmp/tsareq.req", tsaReq, tsaReqLength);
 #endif
     }
-    
+
     CFStringRef url = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)context, kTSAContextKeyURL);
     if (!url)
     {
         tsaDebug("[TSA] missing URL for TSA (key: %s)\n", "kTSAContextKeyURL");
         goto xit;
     }
     CFStringRef url = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)context, kTSAContextKeyURL);
     if (!url)
     {
         tsaDebug("[TSA] missing URL for TSA (key: %s)\n", "kTSAContextKeyURL");
         goto xit;
     }
-    
+
     /*
         If debugging, look at special values in the context to mess things up
     */
     /*
         If debugging, look at special values in the context to mess things up
     */
-    
+
     CFBooleanRef cfBadReq = (CFBooleanRef)CFDictionaryGetValue((CFDictionaryRef)context, kTSADebugContextKeyBadReq);
     if (cfBadReq && CFBooleanGetValue(cfBadReq))
     {
         tsaDebug("[TSA] Forcing bad TS Request by truncating length from %ld to %ld\n", tsaReqLength, (tsaReqLength-4));
         tsaReqLength -= 4;
     }
     CFBooleanRef cfBadReq = (CFBooleanRef)CFDictionaryGetValue((CFDictionaryRef)context, kTSADebugContextKeyBadReq);
     if (cfBadReq && CFBooleanGetValue(cfBadReq))
     {
         tsaDebug("[TSA] Forcing bad TS Request by truncating length from %ld to %ld\n", tsaReqLength, (tsaReqLength-4));
         tsaReqLength -= 4;
     }
-    
+
     // need to extract into buffer
     CFIndex length = CFStringGetLength(url);        // in 16-bit character units
     tsaURL = malloc(6 * length + 1);                // pessimistic
     // need to extract into buffer
     CFIndex length = CFStringGetLength(url);        // in 16-bit character units
     tsaURL = malloc(6 * length + 1);                // pessimistic
@@ -807,9 +810,9 @@ OSStatus SecCmsTSADefaultCallback(CFTypeRef context, void *messageImprintV, uint
 
     signedDERBlob->Data = tsaResp;
     signedDERBlob->Length = tsaRespLength;
 
     signedDERBlob->Data = tsaResp;
     signedDERBlob->Length = tsaRespLength;
-    
+
     result = noErr;
     result = noErr;
-    
+
 xit:
     if (tsaURL)
         free((void *)tsaURL);
 xit:
     if (tsaURL)
         free((void *)tsaURL);
@@ -826,7 +829,7 @@ static OSStatus convertGeneralizedTimeToCFAbsoluteTime(const char *timeStr, CFAb
     /*
         See http://userguide.icu-project.org/formatparse/datetime for date/time format.
         The "Z" signal a GMT time, but CFDateFormatterGetAbsoluteTimeFromString returns
     /*
         See http://userguide.icu-project.org/formatparse/datetime for date/time format.
         The "Z" signal a GMT time, but CFDateFormatterGetAbsoluteTimeFromString returns
-        values based on local time. 
+        values based on local time.
     */
 
     OSStatus result = noErr;
     */
 
     OSStatus result = noErr;
@@ -851,13 +854,13 @@ static OSStatus convertGeneralizedTimeToCFAbsoluteTime(const char *timeStr, CFAb
     }
 
 xit:
     }
 
 xit:
-    if (formatter) 
+    if (formatter)
         CFRelease(formatter);
         CFRelease(formatter);
-    if (time_string) 
+    if (time_string)
         CFRelease(time_string);
         CFRelease(time_string);
-    if (gmt) 
+    if (gmt)
         CFRelease(gmt);
         CFRelease(gmt);
-    
+
     return result;
 }
 
     return result;
 }
 
@@ -870,11 +873,11 @@ static OSStatus SecTSAValidateTimestamp(const SecAsn1TSATSTInfo *tstInfo, CSSM_D
     SecCertificateRef signingCertificate = NULL;
 
     require(tstInfo && signingCerts && (tstInfo->genTime.Length < 16), xit);
     SecCertificateRef signingCertificate = NULL;
 
     require(tstInfo && signingCerts && (tstInfo->genTime.Length < 16), xit);
-    
+
     // Find the leaf signingCert
     // Find the leaf signingCert
-    require_noerr(result = SecCertificateCreateFromData(*signingCerts, 
+    require_noerr(result = SecCertificateCreateFromData(*signingCerts,
         CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER, &signingCertificate), xit);
         CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER, &signingCertificate), xit);
-    
+
     memcpy(timeStr, tstInfo->genTime.Data, tstInfo->genTime.Length);
     timeStr[tstInfo->genTime.Length] = 0;
     require_noerr(convertGeneralizedTimeToCFAbsoluteTime(timeStr, &genTime), xit);
     memcpy(timeStr, tstInfo->genTime.Data, tstInfo->genTime.Length);
     timeStr[tstInfo->genTime.Length] = 0;
     require_noerr(convertGeneralizedTimeToCFAbsoluteTime(timeStr, &genTime), xit);
@@ -895,12 +898,12 @@ static OSStatus verifyTSTInfo(const CSSM_DATA_PTR content, CSSM_DATA **signingCe
 
     if (!tstInfo)
         return SECFailure;
 
     if (!tstInfo)
         return SECFailure;
-        
+
     require_noerr(SecAsn1CoderCreate(&coder), xit);
     require_noerr(SecAsn1CoderCreate(&coder), xit);
-    require_noerr(SecAsn1Decode(coder, content->Data, content->Length, 
+    require_noerr(SecAsn1Decode(coder, content->Data, content->Length,
                kSecAsn1TSATSTInfoTemplate, tstInfo), xit);
     displayTSTInfo(tstInfo);
                kSecAsn1TSATSTInfoTemplate, tstInfo), xit);
     displayTSTInfo(tstInfo);
-    
+
     // Check the nonce
     if (tstInfo->nonce.Data && expectedNonce!=0)
     {
     // Check the nonce
     if (tstInfo->nonce.Data && expectedNonce!=0)
     {
@@ -909,7 +912,7 @@ static OSStatus verifyTSTInfo(const CSSM_DATA_PTR content, CSSM_DATA **signingCe
             dtprintf("verifyTSTInfo nonce: actual: %lld, expected: %lld\n", nonce, expectedNonce);
         require_action(expectedNonce==nonce, xit, status = errSecTimestampRejection);
     }
             dtprintf("verifyTSTInfo nonce: actual: %lld, expected: %lld\n", nonce, expectedNonce);
         require_action(expectedNonce==nonce, xit, status = errSecTimestampRejection);
     }
-    
+
     status = SecTSAValidateTimestamp(tstInfo, signingCerts, timestampTime);
     dtprintf("SecTSAValidateTimestamp result: %ld\n", (long)status);
 
     status = SecTSAValidateTimestamp(tstInfo, signingCerts, timestampTime);
     dtprintf("SecTSAValidateTimestamp result: %ld\n", (long)status);
 
@@ -960,11 +963,11 @@ static void debugShowCertEvidenceInfo(uint16_t certCount, const CSSM_TP_APPLE_EV
         {
                        dtprintf(" ( ");
                        statusBitTest(cs, CSSM_CERT_STATUS_EXPIRED, "EXPIRED");
         {
                        dtprintf(" ( ");
                        statusBitTest(cs, CSSM_CERT_STATUS_EXPIRED, "EXPIRED");
-                       statusBitTest(cs, CSSM_CERT_STATUS_NOT_VALID_YET, 
+                       statusBitTest(cs, CSSM_CERT_STATUS_NOT_VALID_YET,
                                "NOT_VALID_YET");
                                "NOT_VALID_YET");
-                       statusBitTest(cs, CSSM_CERT_STATUS_IS_IN_INPUT_CERTS, 
+                       statusBitTest(cs, CSSM_CERT_STATUS_IS_IN_INPUT_CERTS,
                                "IS_IN_INPUT_CERTS");
                                "IS_IN_INPUT_CERTS");
-                       statusBitTest(cs, CSSM_CERT_STATUS_IS_IN_ANCHORS, 
+                       statusBitTest(cs, CSSM_CERT_STATUS_IS_IN_ANCHORS,
                                "IS_IN_ANCHORS");
                        statusBitTest(cs, CSSM_CERT_STATUS_IS_ROOT, "IS_ROOT");
                        statusBitTest(cs, CSSM_CERT_STATUS_IS_FROM_NET, "IS_FROM_NET");
                                "IS_IN_ANCHORS");
                        statusBitTest(cs, CSSM_CERT_STATUS_IS_ROOT, "IS_ROOT");
                        statusBitTest(cs, CSSM_CERT_STATUS_IS_FROM_NET, "IS_FROM_NET");
@@ -978,7 +981,7 @@ static void debugShowCertEvidenceInfo(uint16_t certCount, const CSSM_TP_APPLE_EV
                uint16_t jx;
         for (jx=0; pstatuscode && (jx<info->NumStatusCodes); jx++, ++pstatuscode)
             dtprintf("%s  ", cssmErrorString(*pstatuscode));
                uint16_t jx;
         for (jx=0; pstatuscode && (jx<info->NumStatusCodes); jx++, ++pstatuscode)
             dtprintf("%s  ", cssmErrorString(*pstatuscode));
-               
+
                dtprintf("\n");
                dtprintf("      Index: %u\n", info->Index);
        }
                dtprintf("\n");
                dtprintf("      Index: %u\n", info->Index);
        }
@@ -986,9 +989,9 @@ static void debugShowCertEvidenceInfo(uint16_t certCount, const CSSM_TP_APPLE_EV
 #endif
 }
 
 #endif
 }
 
+#ifndef NDEBUG
 static const char *trustResultTypeString(SecTrustResultType trustResultType)
 {
 static const char *trustResultTypeString(SecTrustResultType trustResultType)
 {
-#ifndef NDEBUG
     switch (trustResultType)
     {
     case kSecTrustResultProceed:                    return "TrustResultProceed";
     switch (trustResultType)
     {
     case kSecTrustResultProceed:                    return "TrustResultProceed";
@@ -1001,9 +1004,9 @@ static const char *trustResultTypeString(SecTrustResultType trustResultType)
     case kSecTrustResultOtherError:                 return "TrustResultOtherError";
     default:                                        return "TrustResultUnknown";
     }
     case kSecTrustResultOtherError:                 return "TrustResultOtherError";
     default:                                        return "TrustResultUnknown";
     }
-#endif
     return "";
 }
     return "";
 }
+#endif
 
 static OSStatus verifySigners(SecCmsSignedDataRef signedData, int numberOfSigners)
 {
 
 static OSStatus verifySigners(SecCmsSignedDataRef signedData, int numberOfSigners)
 {
@@ -1011,8 +1014,9 @@ static OSStatus verifySigners(SecCmsSignedDataRef signedData, int numberOfSigner
     // Also <rdar://problem/11077708> Properly handle revocation information of timestamping certificate
 
     SecPolicyRef policy = NULL;
     // Also <rdar://problem/11077708> Properly handle revocation information of timestamping certificate
 
     SecPolicyRef policy = NULL;
-    int result, rx;
-    
+    int result=errSecInternalError;
+    int rx;
+
     require(policy = SecPolicyCreateWithOID(kSecPolicyAppleTimeStamping), xit);
     int jx;
     for (jx = 0; jx < numberOfSigners; ++jx)
     require(policy = SecPolicyCreateWithOID(kSecPolicyAppleTimeStamping), xit);
     int jx;
     for (jx = 0; jx < numberOfSigners; ++jx)
@@ -1022,7 +1026,7 @@ static OSStatus verifySigners(SecCmsSignedDataRef signedData, int numberOfSigner
         CFDictionaryRef extendedResult = NULL;
         CFArrayRef certChain = NULL;
         uint16_t certCount = 0;
         CFDictionaryRef extendedResult = NULL;
         CFArrayRef certChain = NULL;
         uint16_t certCount = 0;
-        
+
         CSSM_TP_APPLE_EVIDENCE_INFO *statusChain = NULL;
 
         // SecCmsSignedDataVerifySignerInfo returns trustRef, which we can call SecTrustEvaluate on
         CSSM_TP_APPLE_EVIDENCE_INFO *statusChain = NULL;
 
         // SecCmsSignedDataVerifySignerInfo returns trustRef, which we can call SecTrustEvaluate on
@@ -1069,12 +1073,12 @@ static OSStatus verifySigners(SecCmsSignedDataRef signedData, int numberOfSigner
                        }
             break;
                }
                        }
             break;
                }
-    
+
         rx = SecTrustGetResult(trustRef, &trustResultType, &certChain, &statusChain);
         dtprintf("[%s] SecTrustGetResult: result: %d, type: %d\n", __FUNCTION__,rx, trustResultType);
         certCount = certChain?CFArrayGetCount(certChain):0;
         debugShowCertEvidenceInfo(certCount, statusChain);
         rx = SecTrustGetResult(trustRef, &trustResultType, &certChain, &statusChain);
         dtprintf("[%s] SecTrustGetResult: result: %d, type: %d\n", __FUNCTION__,rx, trustResultType);
         certCount = certChain?CFArrayGetCount(certChain):0;
         debugShowCertEvidenceInfo(certCount, statusChain);
-        
+
         rx = SecTrustCopyExtendedResult(trustRef, &extendedResult);
         dtprintf("[%s] SecTrustCopyExtendedResult: result: %d\n", __FUNCTION__, rx);
         if (extendedResult)
         rx = SecTrustCopyExtendedResult(trustRef, &extendedResult);
         dtprintf("[%s] SecTrustCopyExtendedResult: result: %d\n", __FUNCTION__, rx);
         if (extendedResult)
@@ -1082,7 +1086,7 @@ static OSStatus verifySigners(SecCmsSignedDataRef signedData, int numberOfSigner
             debugShowExtendedTrustResult(jx, extendedResult);
             CFRelease(extendedResult);
         }
             debugShowExtendedTrustResult(jx, extendedResult);
             CFRelease(extendedResult);
         }
-        
+
         if (trustRef)
             CFRelease (trustRef);
      }
         if (trustRef)
             CFRelease (trustRef);
      }
@@ -1096,13 +1100,13 @@ xit:
 static OSStatus impExpImportCertUnCommon(
        const CSSM_DATA         *cdata,
        SecKeychainRef          importKeychain, // optional
 static OSStatus impExpImportCertUnCommon(
        const CSSM_DATA         *cdata,
        SecKeychainRef          importKeychain, // optional
-       CFMutableArrayRef       outArray)               // optional, append here 
+       CFMutableArrayRef       outArray)               // optional, append here
 {
     // The only difference between this and impExpImportCertCommon is that we append to outArray
     // before attempting to add to the keychain
        OSStatus status = noErr;
        SecCertificateRef certRef = NULL;
 {
     // The only difference between this and impExpImportCertCommon is that we append to outArray
     // before attempting to add to the keychain
        OSStatus status = noErr;
        SecCertificateRef certRef = NULL;
-       
+
     require_action(cdata, xit, status = errSecUnsupportedFormat);
 
        /* Pass kCFAllocatorNull as bytesDeallocator to assure the bytes aren't freed */
     require_action(cdata, xit, status = errSecUnsupportedFormat);
 
        /* Pass kCFAllocatorNull as bytesDeallocator to assure the bytes aren't freed */
@@ -1166,19 +1170,15 @@ static const char *cfabsoluteTimeToString(CFAbsoluteTime abstime)
 static OSStatus setTSALeafValidityDates(SecCmsSignerInfoRef signerinfo)
 {
     OSStatus status = noErr;
 static OSStatus setTSALeafValidityDates(SecCmsSignerInfoRef signerinfo)
 {
     OSStatus status = noErr;
-    
+
     if (!signerinfo->timestampCertList || (CFArrayGetCount(signerinfo->timestampCertList) == 0))
         return SecCmsVSSigningCertNotFound;
     if (!signerinfo->timestampCertList || (CFArrayGetCount(signerinfo->timestampCertList) == 0))
         return SecCmsVSSigningCertNotFound;
-        
+
     SecCertificateRef tsaLeaf = (SecCertificateRef)CFArrayGetValueAtIndex(signerinfo->timestampCertList, 0);
     SecCertificateRef tsaLeaf = (SecCertificateRef)CFArrayGetValueAtIndex(signerinfo->timestampCertList, 0);
-    
-       CFDataRef certData = SecCertificateCopyData(tsaLeaf);
-    SecCertificateRefP certP = certData?SecCertificateCreateWithDataP(kCFAllocatorDefault, certData):NULL;
+    require_action(tsaLeaf, xit, status = errSecCertificateCannotOperate);
 
 
-    require_action(certP, xit, status = errSecCertificateCannotOperate);
-       
-    signerinfo->tsaLeafNotBefore = SecCertificateNotValidBefore(certP); /* Start date for Timestamp Authority leaf */
-    signerinfo->tsaLeafNotAfter = SecCertificateNotValidAfter(certP);   /* Expiration date for Timestamp Authority leaf */
+    signerinfo->tsaLeafNotBefore = SecCertificateNotValidBefore(tsaLeaf); /* Start date for Timestamp Authority leaf */
+    signerinfo->tsaLeafNotAfter = SecCertificateNotValidAfter(tsaLeaf);   /* Expiration date for Timestamp Authority leaf */
 
     const char *nbefore = cfabsoluteTimeToString(signerinfo->tsaLeafNotBefore);
     const char *nafter = cfabsoluteTimeToString(signerinfo->tsaLeafNotAfter);
 
     const char *nbefore = cfabsoluteTimeToString(signerinfo->tsaLeafNotBefore);
     const char *nafter = cfabsoluteTimeToString(signerinfo->tsaLeafNotAfter);
@@ -1196,15 +1196,12 @@ static OSStatus setTSALeafValidityDates(SecCmsSignerInfoRef signerinfo)
 */
 
 xit:
 */
 
 xit:
-       if (certData) CFRelease(certData);
-       if (certP) CFRelease(certP);
-
     return status;
 }
 
 /*
     From RFC 3161: Time-Stamp Protocol (TSP),August 2001, APPENDIX B:
     return status;
 }
 
 /*
     From RFC 3161: Time-Stamp Protocol (TSP),August 2001, APPENDIX B:
-    
+
     B) The validity of the digital signature may then be verified in the
         following way:
 
     B) The validity of the digital signature may then be verified in the
         following way:
 
@@ -1238,7 +1235,7 @@ OSStatus decodeTimeStampToken(SecCmsSignerInfoRef signerinfo, CSSM_DATA_PTR inDa
         We update signerinfo with timestamp and tsa certificate chain.
         encDigest is the original signed blob, which we must hash and compare.
         inData comes from the unAuthAttr section of the CMS message
         We update signerinfo with timestamp and tsa certificate chain.
         encDigest is the original signed blob, which we must hash and compare.
         inData comes from the unAuthAttr section of the CMS message
-    
+
         These are set in signerinfo as side effects:
             timestampTime -
             timestampCertList
         These are set in signerinfo as side effects:
             timestampTime -
             timestampCertList
@@ -1254,10 +1251,9 @@ OSStatus decodeTimeStampToken(SecCmsSignerInfoRef signerinfo, CSSM_DATA_PTR inDa
     OSStatus                result = errSecUnknownFormat;
     CSSM_DATA               **signingCerts = NULL;
 
     OSStatus                result = errSecUnknownFormat;
     CSSM_DATA               **signingCerts = NULL;
 
-    OSStatus currentPORTErr = PORT_GetError();
-    dtprintf("decodeTimeStampToken top: PORT_GetError() %d -----\n", (int)currentPORTErr);
+    dtprintf("decodeTimeStampToken top: PORT_GetError() %d -----\n", PORT_GetError());
     PORT_SetError(0);
     PORT_SetError(0);
-    
+
     /* decode the message */
     require_noerr(result = SecCmsDecoderCreate (NULL, NULL, NULL, NULL, NULL, NULL, NULL, &decoderContext), xit);
     result = SecCmsDecoderUpdate(decoderContext, inData->Data, inData->Length);
     /* decode the message */
     require_noerr(result = SecCmsDecoderCreate (NULL, NULL, NULL, NULL, NULL, NULL, NULL, &decoderContext), xit);
     result = SecCmsDecoderUpdate(decoderContext, inData->Data, inData->Length);
@@ -1267,12 +1263,12 @@ OSStatus decodeTimeStampToken(SecCmsSignerInfoRef signerinfo, CSSM_DATA_PTR inDa
         SecCmsDecoderDestroy(decoderContext);
         goto xit;
        }
         SecCmsDecoderDestroy(decoderContext);
         goto xit;
        }
-       
+
     require_noerr(result = SecCmsDecoderFinish(decoderContext, &cmsMessage), xit);
 
     // process the results
     contentLevelCount = SecCmsMessageContentLevelCount(cmsMessage);
     require_noerr(result = SecCmsDecoderFinish(decoderContext, &cmsMessage), xit);
 
     // process the results
     contentLevelCount = SecCmsMessageContentLevelCount(cmsMessage);
-    
+
     if (encDigest)
         printDataAsHex("encDigest",encDigest, 0);
 
     if (encDigest)
         printDataAsHex("encDigest",encDigest, 0);
 
@@ -1282,17 +1278,17 @@ OSStatus decodeTimeStampToken(SecCmsSignerInfoRef signerinfo, CSSM_DATA_PTR inDa
         // get content information
         contentInfo = SecCmsMessageContentLevel (cmsMessage, ix);
         contentTypeTag = SecCmsContentInfoGetContentTypeTag (contentInfo);
         // get content information
         contentInfo = SecCmsMessageContentLevel (cmsMessage, ix);
         contentTypeTag = SecCmsContentInfoGetContentTypeTag (contentInfo);
-        
+
         // After 2nd round, contentInfo.content.data is the TSTInfo
 
         debugShowContentTypeOID(contentInfo);
         // After 2nd round, contentInfo.content.data is the TSTInfo
 
         debugShowContentTypeOID(contentInfo);
-        
+
         switch (contentTypeTag)
         {
         case SEC_OID_PKCS7_SIGNED_DATA:
         {
             require((signedData = (SecCmsSignedDataRef)SecCmsContentInfoGetContent(contentInfo)) != NULL, xit);
         switch (contentTypeTag)
         {
         case SEC_OID_PKCS7_SIGNED_DATA:
         {
             require((signedData = (SecCmsSignedDataRef)SecCmsContentInfoGetContent(contentInfo)) != NULL, xit);
-            
+
             debugShowSignerInfo(signedData);
 
             SECAlgorithmID **digestAlgorithms = SecCmsSignedDataGetDigestAlgs(signedData);
             debugShowSignerInfo(signedData);
 
             SECAlgorithmID **digestAlgorithms = SecCmsSignedDataGetDigestAlgs(signedData);
@@ -1349,11 +1345,11 @@ OSStatus decodeTimeStampToken(SecCmsSignerInfoRef signerinfo, CSSM_DATA_PTR inDa
             result = verifySigners(signedData, numberOfSigners);
             if (result)
                 dtprintf("verifySigners failed: %ld\n", (long)result);   // warning
             result = verifySigners(signedData, numberOfSigners);
             if (result)
                 dtprintf("verifySigners failed: %ld\n", (long)result);   // warning
-                
-            
+
+
             if (result)     // remap to SecCmsVSTimestampNotTrusted ?
                 goto xit;
             if (result)     // remap to SecCmsVSTimestampNotTrusted ?
                 goto xit;
-                
+
             break;
         }
         case SEC_OID_PKCS9_SIGNING_CERTIFICATE:
             break;
         }
         case SEC_OID_PKCS9_SIGNING_CERTIFICATE:
@@ -1361,7 +1357,7 @@ OSStatus decodeTimeStampToken(SecCmsSignerInfoRef signerinfo, CSSM_DATA_PTR inDa
             dtprintf("SEC_OID_PKCS9_SIGNING_CERTIFICATE seen\n");
             break;
         }
             dtprintf("SEC_OID_PKCS9_SIGNING_CERTIFICATE seen\n");
             break;
         }
-        
+
         case SEC_OID_PKCS9_ID_CT_TSTInfo:
         {
             SecAsn1TSATSTInfo tstInfo = {{0},};
         case SEC_OID_PKCS9_ID_CT_TSTInfo:
         {
             SecAsn1TSATSTInfo tstInfo = {{0},};
@@ -1379,8 +1375,7 @@ OSStatus decodeTimeStampToken(SecCmsSignerInfoRef signerinfo, CSSM_DATA_PTR inDa
         }
         case SEC_OID_OTHER:
         {
         }
         case SEC_OID_OTHER:
         {
-            char *otherContent = (char *)SecCmsContentInfoGetContent (contentInfo);
-            dtprintf("otherContent : %p\n", otherContent);
+            dtprintf("otherContent : %p\n", (char *)SecCmsContentInfoGetContent (contentInfo));
             break;
         }
         default:
             break;
         }
         default:
diff --git a/libsecurity_ssl/Security b/libsecurity_ssl/Security
new file mode 120000 (symlink)
index 0000000..945c9b4
--- /dev/null
@@ -0,0 +1 @@
+.
\ No newline at end of file
diff --git a/libsecurity_ssl/Security/CipherSuite.h b/libsecurity_ssl/Security/CipherSuite.h
deleted file mode 100644 (file)
index bed5e68..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (c) 1999-2002,2005-2007,2010-2012 Apple Inc. All Rights Reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * 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 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/*
- * CipherSuite.h - SSL Cipher Suite definitions.
- */
-
-#ifndef _SECURITY_CIPHERSUITE_H_
-#define _SECURITY_CIPHERSUITE_H_
-
-/* fetch Uint32 */
-#include <CoreFoundation/CFBase.h>
-#include <TargetConditionals.h>
-
-/*
- * Defined as enum for debugging, but in the protocol
- * it is actually exactly two bytes
- */
-#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
-/* 32-bit value on OS X */
-typedef uint32_t SSLCipherSuite;
-#else
-/* 16-bit value on iOS */
-typedef uint16_t SSLCipherSuite;
-#endif
-
-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,
-
-       /* TLS addenda using AES, per RFC 3268 */
-       TLS_RSA_WITH_AES_128_CBC_SHA      =                     0x002F,
-       TLS_DH_DSS_WITH_AES_128_CBC_SHA   =                     0x0030,
-       TLS_DH_RSA_WITH_AES_128_CBC_SHA   =                     0x0031,
-       TLS_DHE_DSS_WITH_AES_128_CBC_SHA  =                     0x0032,
-       TLS_DHE_RSA_WITH_AES_128_CBC_SHA  =                     0x0033,
-       TLS_DH_anon_WITH_AES_128_CBC_SHA  =                     0x0034,
-       TLS_RSA_WITH_AES_256_CBC_SHA      =                     0x0035,
-       TLS_DH_DSS_WITH_AES_256_CBC_SHA   =                     0x0036,
-       TLS_DH_RSA_WITH_AES_256_CBC_SHA   =                     0x0037,
-       TLS_DHE_DSS_WITH_AES_256_CBC_SHA  =                     0x0038,
-       TLS_DHE_RSA_WITH_AES_256_CBC_SHA  =                     0x0039,
-       TLS_DH_anon_WITH_AES_256_CBC_SHA  =                     0x003A,
-
-       /* ECDSA addenda, RFC 4492 */
-       TLS_ECDH_ECDSA_WITH_NULL_SHA           =        0xC001,
-       TLS_ECDH_ECDSA_WITH_RC4_128_SHA        =        0xC002,
-       TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA   =        0xC003,
-       TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA    =        0xC004,
-       TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA    =        0xC005,
-       TLS_ECDHE_ECDSA_WITH_NULL_SHA          =        0xC006,
-       TLS_ECDHE_ECDSA_WITH_RC4_128_SHA       =        0xC007,
-       TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA  =        0xC008,
-       TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA   =        0xC009,
-       TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA   =        0xC00A,
-       TLS_ECDH_RSA_WITH_NULL_SHA             =        0xC00B,
-       TLS_ECDH_RSA_WITH_RC4_128_SHA          =        0xC00C,
-       TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA     =        0xC00D,
-       TLS_ECDH_RSA_WITH_AES_128_CBC_SHA      =        0xC00E,
-       TLS_ECDH_RSA_WITH_AES_256_CBC_SHA      =        0xC00F,
-       TLS_ECDHE_RSA_WITH_NULL_SHA            =        0xC010,
-       TLS_ECDHE_RSA_WITH_RC4_128_SHA         =        0xC011,
-       TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA    =        0xC012,
-       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA     =        0xC013,
-       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA     =        0xC014,
-       TLS_ECDH_anon_WITH_NULL_SHA            =        0xC015,
-       TLS_ECDH_anon_WITH_RC4_128_SHA         =        0xC016,
-       TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA    =        0xC017,
-       TLS_ECDH_anon_WITH_AES_128_CBC_SHA     =        0xC018,
-       TLS_ECDH_anon_WITH_AES_256_CBC_SHA     =        0xC019,
-
-    /* TLS 1.2 addenda, RFC 5246 */
-
-    /* Initial state. */
-    TLS_NULL_WITH_NULL_NULL                   = 0x0000,
-
-    /* Server provided RSA certificate for key exchange. */
-    TLS_RSA_WITH_NULL_MD5                     = 0x0001,
-    TLS_RSA_WITH_NULL_SHA                     = 0x0002,
-    TLS_RSA_WITH_RC4_128_MD5                  = 0x0004,
-    TLS_RSA_WITH_RC4_128_SHA                  = 0x0005,
-    TLS_RSA_WITH_3DES_EDE_CBC_SHA             = 0x000A,
-    //TLS_RSA_WITH_AES_128_CBC_SHA              = 0x002F,
-    //TLS_RSA_WITH_AES_256_CBC_SHA              = 0x0035,
-    TLS_RSA_WITH_NULL_SHA256                  = 0x003B,
-    TLS_RSA_WITH_AES_128_CBC_SHA256           = 0x003C,
-    TLS_RSA_WITH_AES_256_CBC_SHA256           = 0x003D,
-
-    /* Server-authenticated (and optionally client-authenticated) Diffie-Hellman. */
-    TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA          = 0x000D,
-    TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA          = 0x0010,
-    TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA         = 0x0013,
-    TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA         = 0x0016,
-    //TLS_DH_DSS_WITH_AES_128_CBC_SHA           = 0x0030,
-    //TLS_DH_RSA_WITH_AES_128_CBC_SHA           = 0x0031,
-    //TLS_DHE_DSS_WITH_AES_128_CBC_SHA          = 0x0032,
-    //TLS_DHE_RSA_WITH_AES_128_CBC_SHA          = 0x0033,
-    //TLS_DH_DSS_WITH_AES_256_CBC_SHA           = 0x0036,
-    //TLS_DH_RSA_WITH_AES_256_CBC_SHA           = 0x0037,
-    //TLS_DHE_DSS_WITH_AES_256_CBC_SHA          = 0x0038,
-    //TLS_DHE_RSA_WITH_AES_256_CBC_SHA          = 0x0039,
-    TLS_DH_DSS_WITH_AES_128_CBC_SHA256        = 0x003E,
-    TLS_DH_RSA_WITH_AES_128_CBC_SHA256        = 0x003F,
-    TLS_DHE_DSS_WITH_AES_128_CBC_SHA256       = 0x0040,
-    TLS_DHE_RSA_WITH_AES_128_CBC_SHA256       = 0x0067,
-    TLS_DH_DSS_WITH_AES_256_CBC_SHA256        = 0x0068,
-    TLS_DH_RSA_WITH_AES_256_CBC_SHA256        = 0x0069,
-    TLS_DHE_DSS_WITH_AES_256_CBC_SHA256       = 0x006A,
-    TLS_DHE_RSA_WITH_AES_256_CBC_SHA256       = 0x006B,
-
-    /* Completely anonymous Diffie-Hellman */
-    TLS_DH_anon_WITH_RC4_128_MD5              = 0x0018,
-    TLS_DH_anon_WITH_3DES_EDE_CBC_SHA         = 0x001B,
-    //TLS_DH_anon_WITH_AES_128_CBC_SHA          = 0x0034,
-    //TLS_DH_anon_WITH_AES_256_CBC_SHA          = 0x003A,
-    TLS_DH_anon_WITH_AES_128_CBC_SHA256       = 0x006C,
-    TLS_DH_anon_WITH_AES_256_CBC_SHA256       = 0x006D,
-
-    /* Addenda from rfc 5288 AES Galois Counter Mode (GCM) Cipher Suites
-       for TLS. */
-    TLS_RSA_WITH_AES_128_GCM_SHA256           = 0x009C,
-    TLS_RSA_WITH_AES_256_GCM_SHA384           = 0x009D,
-    TLS_DHE_RSA_WITH_AES_128_GCM_SHA256       = 0x009E,
-    TLS_DHE_RSA_WITH_AES_256_GCM_SHA384       = 0x009F,
-    TLS_DH_RSA_WITH_AES_128_GCM_SHA256        = 0x00A0,
-    TLS_DH_RSA_WITH_AES_256_GCM_SHA384        = 0x00A1,
-    TLS_DHE_DSS_WITH_AES_128_GCM_SHA256       = 0x00A2,
-    TLS_DHE_DSS_WITH_AES_256_GCM_SHA384       = 0x00A3,
-    TLS_DH_DSS_WITH_AES_128_GCM_SHA256        = 0x00A4,
-    TLS_DH_DSS_WITH_AES_256_GCM_SHA384        = 0x00A5,
-    TLS_DH_anon_WITH_AES_128_GCM_SHA256       = 0x00A6,
-    TLS_DH_anon_WITH_AES_256_GCM_SHA384       = 0x00A7,
-
-    /* Addenda from rfc 5289  Elliptic Curve Cipher Suites with
-       HMAC SHA-256/384. */
-    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256   = 0xC023,
-    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384   = 0xC024,
-    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256    = 0xC025,
-    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384    = 0xC026,
-    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256     = 0xC027,
-    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384     = 0xC028,
-    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256      = 0xC029,
-    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384      = 0xC02A,
-
-    /* Addenda from rfc 5289  Elliptic Curve Cipher Suites with
-       SHA-256/384 and AES Galois Counter Mode (GCM) */
-    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256   = 0xC02B,
-    TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384   = 0xC02C,
-    TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256    = 0xC02D,
-    TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384    = 0xC02E,
-    TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256     = 0xC02F,
-    TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384     = 0xC030,
-    TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256      = 0xC031,
-    TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384      = 0xC032,
-
-    /* RFC 5746 - Secure Renegotiation */
-    TLS_EMPTY_RENEGOTIATION_INFO_SCSV         = 0x00FF,
-       /*
-        * Tags for SSL 2 cipher kinds which are not specified
-        * for SSL 3.
-        */
-    SSL_RSA_WITH_RC2_CBC_MD5 =                  0xFF80,
-    SSL_RSA_WITH_IDEA_CBC_MD5 =                 0xFF81,
-    SSL_RSA_WITH_DES_CBC_MD5 =                  0xFF82,
-    SSL_RSA_WITH_3DES_EDE_CBC_MD5 =             0xFF83,
-    SSL_NO_SUCH_CIPHERSUITE =                   0xFFFF
-};
-
-#endif /* !_SECURITY_CIPHERSUITE_H_ */
diff --git a/libsecurity_ssl/Security/SecureTransport.h b/libsecurity_ssl/Security/SecureTransport.h
deleted file mode 100644 (file)
index e8e2080..0000000
+++ /dev/null
@@ -1,1333 +0,0 @@
-/*
- * Copyright (c) 1999-2002,2005-2012 Apple Inc. All Rights Reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * 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 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/*
- * SecureTransport.h - Public API for Apple SSL/TLS Implementation
- */
-
-#ifndef _SECURITY_SECURETRANSPORT_H_
-#define _SECURITY_SECURETRANSPORT_H_
-
-/*
- * This file describes the public API for an implementation of the
- * Secure Socket Layer, V. 3.0, Transport Layer Security, V. 1.0 to V. 1.2
- * and Datagram Transport Layer Security V. 1.0
- *
- * There are 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 in the form of an SSLConnectionRef.
- *
- * 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. A SSLContextRef cannot
- * be reused for multiple sessions.
- */
-
-#include <CoreFoundation/CFArray.h>
-#include <Security/CipherSuite.h>
-#include <Security/SecTrust.h>
-#include <sys/types.h>
-#include <Availability.h>
-
-#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 = 0,                /* no protocol negotiated/specified; use default */
-       kSSLProtocol3       = 2,                                /* SSL 3.0 */
-       kTLSProtocol1       = 4,                                /* TLS 1.0 */
-    kTLSProtocol11      = 7,                           /* TLS 1.1 */
-    kTLSProtocol12      = 8,                           /* TLS 1.2 */
-    kDTLSProtocol1      = 9,                /* DTLS 1.0 */
-
-    /* DEPRECATED on iOS */
-    kSSLProtocol2       = 1,                           /* SSL 2.0 */
-    kSSLProtocol3Only   = 3,                /* SSL 3.0 Only */
-    kTLSProtocol1Only   = 5,                /* TLS 1.0 Only */
-    kSSLProtocolAll     = 6,                /* All TLS supported protocols */
-
-} SSLProtocol;
-
-/* SSL session options */
-typedef enum {
-       /*
-        * Set this option to enable returning from SSLHandshake (with a result of
-        * errSSLServerAuthCompleted) when the server authentication portion of the
-        * handshake is complete. This disable certificate verification and
-        * provides an opportunity to perform application-specific server
-        * verification before deciding to continue.
-        */
-       kSSLSessionOptionBreakOnServerAuth,
-       /*
-        * Set this option to enable returning from SSLHandshake (with a result of
-        * errSSLClientCertRequested) when the server requests a client certificate.
-        */
-       kSSLSessionOptionBreakOnCertRequested,
-    /*
-     * This option is the same as kSSLSessionOptionBreakOnServerAuth but applies
-     * to the case where SecureTransport is the server and the client has presented
-     * its certificates allowing the server to verify whether these should be
-     * allowed to authenticate.
-     */
-    kSSLSessionOptionBreakOnClientAuth
-} SSLSessionOption;
-
-/* 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;
-
-/*
- * Status of client certificate exchange (which is optional
- * for both server and client).
- */
-typedef enum {
-       /* Server hasn't asked for a cert. Client hasn't sent one. */
-       kSSLClientCertNone,
-       /* Server has asked for a cert, but client didn't send it. */
-       kSSLClientCertRequested,
-       /*
-        * Server side: We asked for a cert, client sent one, we validated
-        *                              it OK. App can inspect the cert via
-        *                              SSLGetPeerCertificates().
-        * Client side: server asked for one, we sent it.
-        */
-       kSSLClientCertSent,
-       /*
-        * Client sent a cert but failed validation. Server side only.
-        * Server app can inspect the cert via SSLGetPeerCertificates().
-        */
-       kSSLClientCertRejected
-} SSLClientCertificateState;
-
-/*
- * 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 errSSLWouldBlock, 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 */
-                                                        size_t                         *dataLength);   /* IN/OUT */
-typedef OSStatus
-(*SSLWriteFunc)                        (SSLConnectionRef       connection,
-                                                        const void             *data,
-                                                        size_t                         *dataLength);   /* IN/OUT */
-
-
-/*************************************************
- *** OSStatus values unique to SecureTransport ***
- *************************************************/
-
-/*
-    Note: the comments that appear after these errors are used to create SecErrorMessages.strings.
-    The comments must not be multi-line, and should be in a form meaningful to an end user. If
-    a different or additional comment is needed, it can be put in the header doc format, or on a
-    line that does not start with errZZZ.
-*/
-
-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 */
-
-       /* fatal errors detected by peer */
-       errSSLPeerUnexpectedMsg         = -9819,        /* unexpected message received */
-       errSSLPeerBadRecordMac          = -9820,        /* bad MAC */
-       errSSLPeerDecryptionFail        = -9821,        /* decryption failed */
-       errSSLPeerRecordOverflow        = -9822,        /* record overflow */
-       errSSLPeerDecompressFail        = -9823,        /* decompression failure */
-       errSSLPeerHandshakeFail         = -9824,        /* handshake failure */
-       errSSLPeerBadCert                       = -9825,        /* misc. bad certificate */
-       errSSLPeerUnsupportedCert       = -9826,        /* bad unsupported cert format */
-       errSSLPeerCertRevoked           = -9827,        /* certificate revoked */
-       errSSLPeerCertExpired           = -9828,        /* certificate expired */
-       errSSLPeerCertUnknown           = -9829,        /* unknown certificate */
-       errSSLIllegalParam                      = -9830,        /* illegal parameter */
-       errSSLPeerUnknownCA             = -9831,        /* unknown Cert Authority */
-       errSSLPeerAccessDenied          = -9832,        /* access denied */
-       errSSLPeerDecodeError           = -9833,        /* decoding error */
-       errSSLPeerDecryptError          = -9834,        /* decryption error */
-       errSSLPeerExportRestriction     = -9835,        /* export restriction */
-       errSSLPeerProtocolVersion       = -9836,        /* bad protocol version */
-       errSSLPeerInsufficientSecurity = -9837, /* insufficient security */
-       errSSLPeerInternalError         = -9838,        /* internal error */
-       errSSLPeerUserCancelled         = -9839,        /* user canceled */
-       errSSLPeerNoRenegotiation       = -9840,        /* no renegotiation allowed */
-
-       /* non-fatal result codes */
-       errSSLPeerAuthCompleted     = -9841,    /* peer cert is valid, or was ignored if verification disabled */
-       errSSLClientCertRequested       = -9842,        /* server has requested a client cert */
-
-       /* more errors detected by us */
-       errSSLHostNameMismatch          = -9843,        /* peer host name mismatch */
-       errSSLConnectionRefused         = -9844,        /* peer dropped connection before responding */
-       errSSLDecryptionFail            = -9845,        /* decryption failure */
-       errSSLBadRecordMac                      = -9846,        /* bad MAC */
-       errSSLRecordOverflow            = -9847,        /* record overflow */
-       errSSLBadConfiguration          = -9848,        /* configuration error */
-       errSSLLast                                      = -9849,        /* end of range, to be deleted */
-
-};
-
-/* DEPRECATED aliases for errSSLPeerAuthCompleted */
-#define errSSLServerAuthCompleted      errSSLPeerAuthCompleted
-#define errSSLClientAuthCompleted      errSSLPeerAuthCompleted
-
-typedef enum
-{
-    kSSLServerSide,
-    kSSLClientSide
-} SSLProtocolSide;
-
-typedef enum
-{
-    kSSLStreamType,
-    kSSLDatagramType
-} SSLConnectionType;
-
-/******************
- *** Public API ***
- ******************/
-
-/*
- * Secure Transport APIs require a SSLContextRef, which is an opaque
- * reference to the SSL session and its parameters. On Mac OS X 10.7
- * and earlier versions, a new context is created using SSLNewContext,
- * and is disposed by calling SSLDisposeContext.
- *
- * On i0S 5.0 and later, as well as Mac OS X versions after 10.7, the
- * SSLContextRef is a true CFType object with retain-release semantics.
- * New code should create a new context using SSLCreateContext (instead
- * of SSLNewContext), and dispose the context by calling CFRelease
- * (instead of SSLDisposeContext) when finished with it.
- */
-
-/*
- * Return the CFTypeID for SSLContext objects.
- */
-CFTypeID
-SSLContextGetTypeID(void)
-       __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0);
-
-/*
- * Create a new instance of an SSLContextRef using the specified allocator.
- */
-SSLContextRef
-SSLCreateContext(CFAllocatorRef alloc, SSLProtocolSide protocolSide, SSLConnectionType connectionType)
-       __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0);
-
-
-#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
-/*
- * Create a new session context.
- *
- * ==========================
- * MAC OS X ONLY (DEPRECATED)
- * ==========================
- * NOTE: this function is not available on iOS, and should be considered
- * deprecated on Mac OS X. Your code should use SSLCreateContext instead.
- */
-OSStatus
-SSLNewContext                          (Boolean                        isServer,
-                                                        SSLContextRef          *contextPtr)    /* RETURNED */
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_NA);
-
-/*
- * Dispose of a session context.
- *
- * ==========================
- * MAC OS X ONLY (DEPRECATED)
- * ==========================
- * NOTE: this function is not available on iOS, and should be considered
- * deprecated on Mac OS X. Your code should use CFRelease to dispose a session
- * created with SSLCreateContext.
- */
-OSStatus
-SSLDisposeContext                      (SSLContextRef          context)
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_NA);
-
-#endif /* MAC OS X */
-
-/*
- * Determine the state of an SSL/DTLS session.
- */
-OSStatus
-SSLGetSessionState                     (SSLContextRef          context,
-                                                        SSLSessionState        *state)         /* RETURNED */
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
-
-/*
- * Set options for an SSL session. Must be called prior to SSLHandshake();
- * subsequently cannot be called while session is active.
- */
-OSStatus
-SSLSetSessionOption                    (SSLContextRef          context,
-                                                        SSLSessionOption       option,
-                                                        Boolean                        value)
-       __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_5_0);
-
-/*
- * Determine current value for the specified option in a given SSL session.
- */
-OSStatus
-SSLGetSessionOption                    (SSLContextRef          context,
-                                                        SSLSessionOption       option,
-                                                        Boolean                        *value)
-       __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_5_0);
-
-/********************************************************************
- *** Session context configuration, common to client and servers. ***
- ********************************************************************/
-
-/*
- * Specify functions which do the network I/O. Must be called prior
- * to SSLHandshake(); subsequently cannot be called while a session is
- * active.
- */
-OSStatus
-SSLSetIOFuncs                          (SSLContextRef          context,
-                                                        SSLReadFunc            readFunc,
-                                                        SSLWriteFunc           writeFunc)
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
-
-/*
- * Set the minimum SSL protocol version allowed. Optional.
- * The default is the lower supported protocol.
- *
- * This can only be called when no session is active.
- *
- * For TLS contexts, legal values for minVersion are :
- *             kSSLProtocol3
- *             kTLSProtocol1
- *             kTLSProtocol11
- *             kTLSProtocol12
- *
- * For DTLS contexts, legal values for minVersion are :
- *      kDTLSProtocol1
- */
-OSStatus
-SSLSetProtocolVersionMin  (SSLContextRef      context,
-                           SSLProtocol        minVersion)
-    __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0);
-
-/*
- * Get minimum protocol version allowed
- */
-OSStatus
-SSLGetProtocolVersionMin  (SSLContextRef      context,
-                           SSLProtocol        *minVersion)
-    __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0);
-
-/*
- * Set the maximum SSL protocol version allowed. Optional.
- * The default is the highest supported protocol.
- *
- * This can only be called when no session is active.
- *
- * For TLS contexts, legal values for minVersion are :
- *             kSSLProtocol3
- *             kTLSProtocol1
- *             kTLSProtocol11
- *             kTLSProtocol12
- *
- * For DTLS contexts, legal values for minVersion are :
- *      kDTLSProtocol1
- */
-OSStatus
-SSLSetProtocolVersionMax  (SSLContextRef      context,
-                           SSLProtocol        maxVersion)
-    __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0);
-
-/*
- * Get maximum protocol version allowed
- */
-OSStatus
-SSLGetProtocolVersionMax  (SSLContextRef      context,
-                           SSLProtocol        *maxVersion)
-    __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0);
-
-
-#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
-/*
- * Set allowed SSL protocol versions. Optional.
- * Specifying kSSLProtocolAll for SSLSetProtocolVersionEnabled results in
- * specified 'enable' boolean to be applied to all supported protocols.
- * The default is "all supported protocols are enabled".
- * This can only be called when no session is active.
- *
- * Legal values for protocol are :
- *             kSSLProtocol2
- *             kSSLProtocol3
- *             kTLSProtocol1
- *             kSSLProtocolAll
- *
- * ==========================
- * MAC OS X ONLY (DEPRECATED)
- * ==========================
- * NOTE: this function is not available on iOS, and should be considered
- * deprecated on Mac OS X. You can use SSLSetProtocolVersionMin and/or
- * SSLSetProtocolVersionMax to specify which protocols are enabled.
- */
-OSStatus
-SSLSetProtocolVersionEnabled (SSLContextRef    context,
-                                                        SSLProtocol            protocol,
-                                                        Boolean                        enable)
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_NA);
-
-/*
- * Obtain a value specified in SSLSetProtocolVersionEnabled.
- *
- * ==========================
- * MAC OS X ONLY (DEPRECATED)
- * ==========================
- * NOTE: this function is not available on iOS, and should be considered
- * deprecated on Mac OS X. You can use SSLGetProtocolVersionMin and/or
- * SSLGetProtocolVersionMax to check whether a protocol is enabled.
- */
-OSStatus
-SSLGetProtocolVersionEnabled(SSLContextRef             context,
-                                                        SSLProtocol            protocol,
-                                                        Boolean                        *enable)        /* RETURNED */
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_NA);
-
-/*
- * Get/set SSL protocol version; optional. Default is kSSLProtocolUnknown,
- * in which case the highest possible version is attempted, but a lower
- * version is accepted if the peer requires it.
- * SSLSetProtocolVersion cannot be called when a session is active.
- *
- * ==========================
- * MAC OS X ONLY (DEPRECATED)
- * ==========================
- * NOTE: this function is not available on iOS, and deprecated on Mac OS X 10.8.
- * Use SSLSetProtocolVersionMin and/or SSLSetProtocolVersionMax to specify
- * which protocols are enabled.
- */
-OSStatus
-SSLSetProtocolVersion          (SSLContextRef          context,
-                                                        SSLProtocol            version)
-       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_8,__IPHONE_NA,__IPHONE_NA);
-
-/*
- * Obtain the protocol version specified in SSLSetProtocolVersion.
- * If SSLSetProtocolVersionEnabled() has been called for this session,
- * SSLGetProtocolVersion() may return paramErr if the protocol enable
- * state can not be represented by the SSLProtocol enums (e.g.,
- * SSL2 and TLS1 enabled, SSL3 disabled).
- *
- * ==========================
- * MAC OS X ONLY (DEPRECATED)
- * ==========================
- * NOTE: this function is not available on iOS, and deprecated on Mac OS X 10.8.
- * Use SSLGetProtocolVersionMin and/or SSLGetProtocolVersionMax to check
- * whether a protocol is enabled.
- */
-OSStatus
-SSLGetProtocolVersion          (SSLContextRef          context,
-                                                        SSLProtocol            *protocol)      /* RETURNED */
-       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_8,__IPHONE_NA,__IPHONE_NA);
-
-#endif /* MAC OS X */
-
-/*
- * 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 certRefs[0]. Specifying a root cert is optional; if it's
- * not specified, the root cert which verifies the cert chain specified
- * here must be present in the system-wide set of trusted anchor certs.
- *
- * The certRefs argument is a CFArray containing SecCertificateRefs,
- * except for certRefs[0], which is a SecIdentityRef.
- *
- * Must be called prior to SSLHandshake(), or immediately after
- * SSLHandshake has returned errSSLClientCertRequested (i.e. before the
- * handshake is resumed by calling SSLHandshake again.)
- *
- * SecureTransport assumes the following:
- *
- *  -- The certRef references remain valid for the lifetime of the session.
- *  -- The certificate specified in certRefs[0] is capable of signing.
- *  -- The required capabilities of the certRef[0], and of the optional cert
- *     specified in SSLSetEncryptionCertificate (see below), are highly
- *     dependent on the application. For example, to work as a server with
- *     Netscape clients, the cert specified here must be capable of both
- *     signing and encrypting.
- */
-OSStatus
-SSLSetCertificate                      (SSLContextRef          context,
-                                                        CFArrayRef                     certRefs)
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
-
-/*
- * 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)
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
-
-OSStatus
-SSLGetConnection                       (SSLContextRef          context,
-                                                        SSLConnectionRef       *connection)
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
-
-/*
- * Specify the fully qualified doman name of the peer, e.g., "store.apple.com."
- * Optional; used to verify the common name field in peer's certificate.
- * Name is in the form of a C string; NULL termination optional, i.e.,
- * peerName[peerNameLen+1] may or may not have a NULL. In any case peerNameLen
- * is the number of bytes of the peer domain name.
- */
-OSStatus
-SSLSetPeerDomainName           (SSLContextRef          context,
-                                                        const char                     *peerName,
-                                                        size_t                         peerNameLen)
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
-
-/*
- * Determine the buffer size needed for SSLGetPeerDomainName().
- */
-OSStatus
-SSLGetPeerDomainNameLength     (SSLContextRef          context,
-                                                        size_t                         *peerNameLen)   // RETURNED
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
-
-/*
- * Obtain the value specified in SSLSetPeerDomainName().
- */
-OSStatus
-SSLGetPeerDomainName           (SSLContextRef          context,
-                                                        char                           *peerName,              // returned here
-                                                        size_t                         *peerNameLen)   // IN/OUT
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
-
-/*
- * Specify the Datagram TLS Hello Cookie.
- * This is to be called for server side only and is optional.
- * The default is a zero len cookie. The maximum cookieLen is 32 bytes.
- */
-OSStatus
-SSLSetDatagramHelloCookie      (SSLContextRef          dtlsContext,
-                             const void         *cookie,
-                             size_t             cookieLen)
-       __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0);
-
-/*
- * Specify the maximum record size, including all DTLS record headers.
- * This should be set appropriately to avoid fragmentation
- * of Datagrams during handshake, as fragmented datagrams may
- * be dropped by some network.
- * This is for Datagram TLS only
- */
-OSStatus
-SSLSetMaxDatagramRecordSize (SSLContextRef             dtlsContext,
-                             size_t             maxSize)
-       __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0);
-
-/*
- * Get the maximum record size, including all Datagram TLS record headers.
- * This is for Datagram TLS only
- */
-OSStatus
-SSLGetMaxDatagramRecordSize (SSLContextRef             dtlsContext,
-                             size_t             *maxSize)
-       __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0);
-
-/*
- * 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 */
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
-
-/*
- * 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,
-                                                         size_t                                *numCiphers)
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
-
-OSStatus
-SSLGetSupportedCiphers          (SSLContextRef                 context,
-                                                         SSLCipherSuite                *ciphers,               /* RETURNED */
-                                                         size_t                                *numCiphers)    /* IN/OUT */
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
-
-/*
- * Specify a (typically) 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,
-                                                        size_t                                 numCiphers)
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
-
-/*
- * 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,
-                                                        size_t                                 *numCiphers)
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
-
-OSStatus
-SSLGetEnabledCiphers           (SSLContextRef                  context,
-                                                        SSLCipherSuite                 *ciphers,               /* RETURNED */
-                                                        size_t                                 *numCiphers)    /* IN/OUT */
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
-
-
-#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
-/*
- * Enable/disable peer certificate chain validation. Default is enabled.
- * If caller disables, it is the caller's responsibility to call
- * SSLCopyPeerCertificates() upon successful completion of the handshake
- * and then to perform external validation of the peer certificate
- * chain before proceeding with data transfer.
- *
- * ==========================
- * MAC OS X ONLY (DEPRECATED)
- * ==========================
- * NOTE: this function is not available on iOS, and should be considered
- * deprecated on Mac OS X. To disable peer certificate chain validation, you
- * can instead use SSLSetSessionOption to set kSSLSessionOptionBreakOnServerAuth
- * to true. This will disable verification and cause SSLHandshake to return with
- * an errSSLServerAuthCompleted result when the peer certificates have been
- * received; at that time, you can choose to evaluate peer trust yourself, or
- * simply call SSLHandshake again to proceed with the handshake.
- */
-OSStatus
-SSLSetEnableCertVerify         (SSLContextRef                  context,
-                                                        Boolean                                enableVerify)
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_NA);
-
-/*
- * Check whether peer certificate chain validation is enabled.
- *
- * ==========================
- * MAC OS X ONLY (DEPRECATED)
- * ==========================
- * NOTE: this function is not available on iOS, and should be considered
- * deprecated on Mac OS X. To check whether peer certificate chain validation
- * is enabled in a context, call SSLGetSessionOption to obtain the value of
- * the kSSLSessionOptionBreakOnServerAuth session option flag. If the value
- * of this option flag is true, then verification is disabled.
- */
-OSStatus
-SSLGetEnableCertVerify         (SSLContextRef                  context,
-                                                        Boolean                                *enableVerify)  /* RETURNED */
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_NA);
-
-/*
- * Specify the option of ignoring certificates' "expired" times.
- * This is a common failure in the real SSL world. Default setting for this
- * flag is false, meaning expired certs result in an errSSLCertExpired error.
- *
- * ==========================
- * MAC OS X ONLY (DEPRECATED)
- * ==========================
- * NOTE: this function is not available on iOS, and should be considered
- * deprecated on Mac OS X. To ignore expired certificate errors, first disable
- * Secure Transport's automatic verification of peer certificates by calling
- * SSLSetSessionOption to set kSSLSessionOptionBreakOnServerAuth to true. When
- * SSLHandshake subsequently returns an errSSLServerAuthCompleted result,
- * your code should obtain the SecTrustRef for the peer's certificates and
- * perform a custom trust evaluation with SecTrust APIs (see SecTrust.h).
- * The SecTrustSetOptions function allows you to specify that the expiration
- * status of certificates should be ignored for this evaluation.
- *
- * Example:
- *
- *     status = SSLSetSessionOption(ctx, kSSLSessionOptionBreakOnServerAuth, true);
- *     do {
- *             status = SSLHandshake(ctx);
- *
- *             if (status == errSSLServerAuthCompleted) {
- *                     SecTrustRef peerTrust = NULL;
- *                     status = SSLCopyPeerTrust(ctx, &peerTrust);
- *                     if (status == noErr) {
- *                             SecTrustResultType trustResult;
- *                             // set flag to allow expired certificates
- *                             SecTrustSetOptions(peerTrust, kSecTrustOptionAllowExpired);
- *                             status = SecTrustEvaluate(peerTrust, &trustResult);
- *                             if (status == noErr) {
- *                                     // A "proceed" result means the cert is explicitly trusted,
- *                                     // e.g. "Always Trust" was clicked;
- *                                     // "Unspecified" means the cert has no explicit trust settings,
- *                                     // but is implicitly OK since it chains back to a trusted root.
- *                                     // Any other result means the cert is not trusted.
- *                                     //
- *                                     if (trustResult == kSecTrustResultProceed ||
- *                                             trustResult == kSecTrustResultUnspecified) {
- *                                             // certificate is trusted
- *                                             status = errSSLWouldBlock; // so we call SSLHandshake again
- *                                     } else if (trustResult == kSecTrustResultRecoverableTrustFailure) {
- *                                             // not trusted, for some reason other than being expired;
- *                                             // could ask the user whether to allow the connection here
- *                                             //
- *                                             status = errSSLXCertChainInvalid;
- *                                     } else {
- *                                             // cannot use this certificate (fatal)
- *                                             status = errSSLBadCert;
- *                                     }
- *                             }
- *                             if (peerTrust) {
- *                                     CFRelease(peerTrust);
- *                             }
- *                     }
- *             } // errSSLServerAuthCompleted
- *
- *     } while (status == errSSLWouldBlock);
- *
- */
-OSStatus
-SSLSetAllowsExpiredCerts       (SSLContextRef          context,
-                                                        Boolean                        allowsExpired)
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_NA);
-
-/*
- * Obtain the current value of an SSLContext's "allowExpiredCerts" flag.
- *
- * ==========================
- * MAC OS X ONLY (DEPRECATED)
- * ==========================
- * NOTE: this function is not available on iOS, and should be considered
- * deprecated on Mac OS X.
- */
-OSStatus
-SSLGetAllowsExpiredCerts       (SSLContextRef          context,
-                                                        Boolean                        *allowsExpired) /* RETURNED */
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_NA);
-
-/*
- * Similar to SSLSetAllowsExpiredCerts, SSLSetAllowsExpiredRoots allows the
- * option of ignoring "expired" status for root certificates only.
- * Default setting is false, i.e., expired root certs result in an
- * errSSLCertExpired error.
- *
- * ==========================
- * MAC OS X ONLY (DEPRECATED)
- * ==========================
- * NOTE: this function is not available on iOS, and should be considered
- * deprecated on Mac OS X. To ignore expired certificate errors, first disable
- * Secure Transport's automatic verification of peer certificates by calling
- * SSLSetSessionOption to set kSSLSessionOptionBreakOnServerAuth to true. When
- * SSLHandshake subsequently returns an errSSLServerAuthCompleted result,
- * your code should obtain the SecTrustRef for the peer's certificates and
- * perform a custom trust evaluation with SecTrust APIs (see SecTrust.h).
- * The SecTrustSetOptions function allows you to specify that the expiration
- * status of certificates should be ignored for this evaluation.
- *
- * See the description of the SSLSetAllowsExpiredCerts function (above)
- * for a code example. The kSecTrustOptionAllowExpiredRoot option can be used
- * instead of kSecTrustOptionAllowExpired to allow expired roots only.
- */
-OSStatus
-SSLSetAllowsExpiredRoots       (SSLContextRef          context,
-                                                        Boolean                        allowsExpired)
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_NA);
-
-/*
- * Obtain the current value of an SSLContext's "allow expired roots" flag.
- *
- * ==========================
- * MAC OS X ONLY (DEPRECATED)
- * ==========================
- * NOTE: this function is not available on iOS, and should be considered
- * deprecated on Mac OS X.
- */
-OSStatus
-SSLGetAllowsExpiredRoots       (SSLContextRef          context,
-                                                        Boolean                        *allowsExpired) /* RETURNED */
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_NA);
-
-/*
- * 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.
- *
- * ==========================
- * MAC OS X ONLY (DEPRECATED)
- * ==========================
- * NOTE: this function is not available on iOS, and should be considered
- * deprecated on Mac OS X. To ignore unknown root cert errors, first disable
- * Secure Transport's automatic verification of peer certificates by calling
- * SSLSetSessionOption to set kSSLSessionOptionBreakOnServerAuth to true. When
- * SSLHandshake subsequently returns an errSSLServerAuthCompleted result,
- * your code should obtain the SecTrustRef for the peer's certificates and
- * perform a custom trust evaluation with SecTrust APIs (see SecTrust.h).
- *
- * See the description of the SSLSetAllowsExpiredCerts function (above)
- * for a code example. Note that an unknown root certificate will cause
- * SecTrustEvaluate to report kSecTrustResultRecoverableTrustFailure as the
- * trust result.
- */
-OSStatus
-SSLSetAllowsAnyRoot                    (SSLContextRef          context,
-                                                        Boolean                        anyRoot)
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_NA);
-
-/*
- * Obtain the current value of an SSLContext's "allow any root" flag.
- *
- * ==========================
- * MAC OS X ONLY (DEPRECATED)
- * ==========================
- * NOTE: this function is not available on iOS, and should be considered
- * deprecated on Mac OS X.
- */
-OSStatus
-SSLGetAllowsAnyRoot                    (SSLContextRef          context,
-                                                        Boolean                        *anyRoot) /* RETURNED */
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_NA);
-
-/*
- * Augment or replace the system's default trusted root certificate set
- * for this session. If replaceExisting is true, the specified roots will
- * be the only roots which are trusted during this session. If replaceExisting
- * is false, the specified roots will be added to the current set of trusted
- * root certs. If this function has never been called, the current trusted
- * root set is the same as the system's default trusted root set.
- * Successive calls with replaceExisting false result in accumulation
- * of additional root certs.
- *
- * The trustedRoots array contains SecCertificateRefs.
- *
- * ==========================
- * MAC OS X ONLY (DEPRECATED)
- * ==========================
- * NOTE: this function is not available on iOS, and should be considered
- * deprecated on Mac OS X. To trust specific roots in a session, first disable
- * Secure Transport's automatic verification of peer certificates by calling
- * SSLSetSessionOption to set kSSLSessionOptionBreakOnServerAuth to true. When
- * SSLHandshake subsequently returns an errSSLServerAuthCompleted result,
- * your code should obtain the SecTrustRef for the peer's certificates and
- * perform a custom trust evaluation with SecTrust APIs (see SecTrust.h).
- *
- * See the description of the SSLSetAllowsExpiredCerts function (above)
- * for a code example. You can call SecTrustSetAnchorCertificates to
- * augment the system's trusted root set, or SecTrustSetAnchorCertificatesOnly
- * to make these the only trusted roots, prior to calling SecTrustEvaluate.
- */
-OSStatus
-SSLSetTrustedRoots                     (SSLContextRef          context,
-                                                        CFArrayRef             trustedRoots,
-                                                        Boolean                        replaceExisting)
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_NA);
-
-/*
- * Obtain an array of SecCertificateRefs representing the current
- * set of trusted roots. If SSLSetTrustedRoots() has never been called
- * for this session, this returns the system's default root set.
- *
- * Caller must CFRelease the returned CFArray.
- *
- * ==========================
- * MAC OS X ONLY (DEPRECATED)
- * ==========================
- * NOTE: this function is not available on iOS, and should be considered
- * deprecated on Mac OS X. To get the current set of trusted roots, call the
- * SSLCopyPeerTrust function to obtain the SecTrustRef for the peer certificate
- * chain, then SecTrustCopyCustomAnchorCertificates (see SecTrust.h).
- */
-OSStatus
-SSLCopyTrustedRoots                    (SSLContextRef          context,
-                                                        CFArrayRef             *trustedRoots)  /* RETURNED */
-       __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
-
-/*
- * Request peer certificates. Valid anytime, subsequent to a handshake attempt.
- *
- * The certs argument is a CFArray containing SecCertificateRefs.
- * Caller must CFRelease the returned array.
- *
- * The cert at index 0 of the returned array is the subject (end
- * entity) cert; the root cert (or the closest cert to it) is at
- * the end of the returned array.
- *
- * ==========================
- * MAC OS X ONLY (DEPRECATED)
- * ==========================
- * NOTE: this function is not available on iOS, and should be considered
- * deprecated on Mac OS X. To get peer certificates, call SSLCopyPeerTrust
- * to obtain the SecTrustRef for the peer certificate chain, then use the
- * SecTrustGetCertificateCount and SecTrustGetCertificateAtIndex functions
- * to retrieve individual certificates in the chain (see SecTrust.h).
- */
-OSStatus
-SSLCopyPeerCertificates                (SSLContextRef          context,
-                                                        CFArrayRef                     *certs)         /* RETURNED */
-       __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
-
-#endif /* MAC OS X */
-
-/*
- * Obtain a SecTrustRef representing peer certificates. Valid anytime,
- * subsequent to a handshake attempt. Caller must CFRelease the returned
- * trust reference.
- *
- * The returned trust reference will have already been evaluated for you,
- * unless one of the following is true:
- * - Your code has disabled automatic certificate verification, by calling
- *   SSLSetSessionOption to set kSSLSessionOptionBreakOnServerAuth to true.
- * - Your code has called SSLSetPeerID, and this session has been resumed
- *   from an earlier cached session.
- *
- * In these cases, your code should call SecTrustEvaluate prior to
- * examining the peer certificate chain or trust results (see SecTrust.h).
- *
- * NOTE: if you have not called SSLHandshake at least once prior to
- * calling this function, the returned trust reference will be NULL.
- */
-OSStatus
-SSLCopyPeerTrust                       (SSLContextRef          context,
-                                                        SecTrustRef            *trust)         /* RETURNED */
-       __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_5_0);
-
-/*
- * 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.
- *
- * SecureTransport allocates its own copy of the incoming peerID. The
- * data provided in *peerID, while opaque to SecureTransport, is used
- * in a byte-for-byte compare to other previous peerID values set by the
- * current application. Matching peerID blobs result in SecureTransport
- * attempting to resume an SSL session with the same parameters as used
- * in the previous session which specified the same peerID bytes.
- */
-OSStatus
-SSLSetPeerID                           (SSLContextRef          context,
-                                                        const void             *peerID,
-                                                        size_t                         peerIDLen)
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
-
-/*
- * Obtain current PeerID. Returns NULL pointer, zero length if
- * SSLSetPeerID has not been called for this context.
- */
-OSStatus
-SSLGetPeerID                           (SSLContextRef          context,
-                                                        const void             **peerID,
-                                                        size_t                         *peerIDLen)
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
-
-/*
- * 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)
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
-
-
-/********************************************************
- *** Session context configuration, server side only. ***
- ********************************************************/
-
-/*
- * 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.
- *
- *  -- 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.
- *
- * The certRefs argument is a CFArray containing SecCertificateRefs,
- * except for certRefs[0], which is a SecIdentityRef.
- *
- * The following assumptions are made:
- *
- *  -- The certRefs references remains valid for the lifetime of the
- *     connection.
- *  -- The specified certRefs[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 RSA keys 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 SSLSetEnabledCiphers() call.
- */
-OSStatus
-SSLSetEncryptionCertificate    (SSLContextRef          context,
-                                                        CFArrayRef                     certRefs)
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
-
-/*
- * Specify requirements for client-side authentication.
- * Optional; Default is kNeverAuthenticate.
- *
- * 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)
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
-
-/*
- * Add a DER-encoded distinguished name to list of acceptable names
- * to be specified in requests for client certificates.
- */
-OSStatus
-SSLAddDistinguishedName                (SSLContextRef          context,
-                                                        const void             *derDN,
-                                                        size_t                         derDNLen)
-       __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_5_0);
-
-
-#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
-/*
- * Add a SecCertificateRef, or a CFArray of them, to a server's list
- * of acceptable Certificate Authorities (CAs) to present to the client
- * when client authentication is performed.
- *
- * If replaceExisting is true, the specified certificate(s) will replace
- * a possible existing list of acceptable CAs. If replaceExisting is
- * false, the specified certificate(s) will be appended to the existing
- * list of acceptable CAs, if any.
- *
- * Returns paramErr if this is called on a SSLContextRef which
- * is configured as a client, or when a session is active.
- *
- * NOTE: this function is currently not available on iOS.
- */
-OSStatus
-SSLSetCertificateAuthorities(SSLContextRef             context,
-                                                        CFTypeRef                      certificateOrArray,
-                                                        Boolean                        replaceExisting)
-       __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
-
-/*
- * Obtain the certificates specified in SSLSetCertificateAuthorities(),
- * if any. Returns a NULL array if SSLSetCertificateAuthorities() has not
- * been called.
- * Caller must CFRelease the returned array.
- *
- * NOTE: this function is currently not available on iOS.
- */
-OSStatus
-SSLCopyCertificateAuthorities(SSLContextRef            context,
-                                                         CFArrayRef            *certificates)  /* RETURNED */
-       __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
-
-#endif /* MAC OS X */
-
-/*
- * Obtain the list of acceptable distinguished names as provided by
- * a server (if the SSLContextRef is configured as a client), or as
- * specified by SSLSetCertificateAuthorities (if the SSLContextRef
- * is configured as a server).
- * The returned array contains CFDataRefs, each of which represents
- * one DER-encoded RDN.
- *
- * Caller must CFRelease the returned array.
- */
-OSStatus
-SSLCopyDistinguishedNames      (SSLContextRef          context,
-                                                        CFArrayRef                     *names)
-       __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_5_0);
-
-/*
- * Obtain client certificate exchange status. Can be called
- * any time. Reflects the *last* client certificate state change;
- * subsequent to a renegotiation attempt by either peer, the state
- * is reset to kSSLClientCertNone.
- */
-OSStatus
-SSLGetClientCertificateState   (SSLContextRef                          context,
-                                                                SSLClientCertificateState      *clientState)
-       __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_5_0);
-
-
-#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
-/*
- * Specify Diffie-Hellman parameters. Optional; if we are configured to allow
- * for D-H ciphers and a D-H cipher is negotiated, and this function has not
- * been called, a set of process-wide parameters will be calculated. However
- * that can take a long time (30 seconds).
- *
- * NOTE: this function is currently not available on iOS.
- */
-OSStatus SSLSetDiffieHellmanParams     (SSLContextRef                  context,
-                                                                        const void                     *dhParams,
-                                                                        size_t                                 dhParamsLen)
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_NA);
-
-/*
- * Return parameter block specified in SSLSetDiffieHellmanParams.
- * Returned data is not copied and belongs to the SSLContextRef.
- *
- * NOTE: this function is currently not available on iOS.
- */
-OSStatus SSLGetDiffieHellmanParams     (SSLContextRef                  context,
-                                                                        const void                     **dhParams,
-                                                                        size_t                                 *dhParamsLen)
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_NA);
-
-/*
- * Enable/Disable RSA blinding. This feature thwarts a known timing
- * attack to which RSA keys are vulnerable; enabling it is a tradeoff
- * between performance and security. The default for RSA blinding is
- * enabled.
- *
- * ==========================
- * MAC OS X ONLY (DEPRECATED)
- * ==========================
- * NOTE: this function is not available on iOS, and should be considered
- * deprecated on Mac OS X. RSA blinding is enabled unconditionally, as
- * it prevents a known way for an attacker to recover the private key,
- * and the performance gain of disabling it is negligible.
- */
-OSStatus SSLSetRsaBlinding                     (SSLContextRef                  context,
-                                                                        Boolean                                blinding)
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_NA);
-
-OSStatus SSLGetRsaBlinding                     (SSLContextRef                  context,
-                                                                        Boolean                                *blinding)
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_NA);
-
-#endif /* MAC OS X */
-
-/*******************************
- ******** I/O Functions ********
- *******************************/
-
-/*
- * Note: depending on the configuration of the underlying I/O
- * connection, all SSL I/O functions can return errSSLWouldBlock,
- * 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 did not end in a root.
- *
- *  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; the peer's
- *  cert chain is available via SSLCopyPeerTrust or SSLCopyPeerCertificates.
- *
- *  Other interesting result codes:
- *
- *  errSSLPeerAuthCompleted: Peer's cert chain is valid, or was ignored if
- *      cert verification was disabled via SSLSetEnableCertVerify. The application
- *      may decide to continue with the handshake (by calling SSLHandshake
- *      again), or close the connection at this point.
- *
- *  errSSLClientCertRequested: The server has requested a client certificate.
- *      The client may choose to examine the server's certificate and
- *      distinguished name list, then optionally call SSLSetCertificate prior
- *      to resuming the handshake by calling SSLHandshake again.
- *
- * 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)
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
-
-/*
- * 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,
-                                                        size_t                         dataLength,
-                                                        size_t                         *processed)             /* RETURNED */
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
-
-/*
- * 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 */
-                                                        size_t                         dataLength,
-                                                        size_t                         *processed)             /* RETURNED */
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
-
-/*
- * Determine how much data the client can be guaranteed to
- * obtain via SSLRead() without blocking or causing any low-level
- * read operations to occur.
- */
-OSStatus
-SSLGetBufferedReadSize         (SSLContextRef context,
-                                                        size_t *bufSize)                                       /* RETURNED */
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
-
-/*
- * Determine how much data the application can be guaranteed to write
- * with SSLWrite() without causing fragmentation. The value is based on
- * the maximum Datagram Record size defined by the application with
- * SSLSetMaxDatagramRecordSize(), minus the DTLS Record header size.
- */
-OSStatus
-SSLGetDatagramWriteSize                (SSLContextRef dtlsContext,
-                                                        size_t *bufSize)
-       __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0);
-
-/*
- * Terminate current SSL session.
- */
-OSStatus
-SSLClose                                       (SSLContextRef          context)
-       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* !_SECURITY_SECURETRANSPORT_H_ */
diff --git a/libsecurity_ssl/Security/SecureTransportPriv.h b/libsecurity_ssl/Security/SecureTransportPriv.h
deleted file mode 100644 (file)
index 467da93..0000000
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
- * Copyright (c) 1999-2001,2005-2012 Apple Inc. All Rights Reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * 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 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/*
- * SecureTransportPriv.h - Apple-private exported routines
- */
-
-#ifndef        _SECURE_TRANSPORT_PRIV_H_
-#define _SECURE_TRANSPORT_PRIV_H_      1
-
-#include <Security/SecureTransport.h>
-#include <Security/SecTrust.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* The size of of client- and server-generated random numbers in hello messages. */
-#define SSL_CLIENT_SRVR_RAND_SIZE              32
-
-/* The size of the pre-master and master secrets. */
-#define SSL_RSA_PREMASTER_SECRET_SIZE  48
-#define SSL_MASTER_SECRET_SIZE                 48
-
-/*
- * For the following three functions, *size is the available
- * buffer size on entry and the actual size of the data returned
- * on return. The above consts are for convenience.
- */
-OSStatus SSLInternalMasterSecret(
-   SSLContextRef context,
-   void *secret,         // mallocd by caller, SSL_MASTER_SECRET_SIZE
-   size_t *secretSize);  // in/out
-
-OSStatus SSLInternalServerRandom(
-   SSLContextRef context,
-   void *randBuf,                      // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
-   size_t *randSize);  // in/out
-
-OSStatus SSLInternalClientRandom(
-   SSLContextRef context,
-   void *randBuf,              // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
-   size_t *randSize);  // in/out
-
-/*
- * Obtain the sizes of the currently negotiated HMAC digest, session
- * key, and session key IV.
- */
-OSStatus SSLGetCipherSizes(
-       SSLContextRef context,
-       size_t *digestSize,
-       size_t *symmetricKeySize,
-       size_t *ivSize);
-
-OSStatus SSLInternal_PRF(
-   SSLContextRef context,
-   const void *secret,
-   size_t secretLen,
-   const void *label,
-   size_t labelLen,
-   const void *seed,
-   size_t seedLen,
-   void *out,                  // mallocd by caller, length >= outLen
-   size_t outLen);
-
-/*
- * Obtain a SecTrustRef representing peer certificates. Valid anytime,
- * subsequent to a handshake attempt. The returned SecTrustRef is valid
- * only as long as the SSLContextRef is.
- */
-OSStatus
-SSLGetPeerSecTrust                     (SSLContextRef          context,
-                                                        SecTrustRef            *secTrust);     /* RETURNED */
-
-/*
- * Obtain resumable session info. Can be called anytime subsequent to
- * handshake attempt.
- *
- * if sessionWasResumed is True on return, the session is indeed a
- * resumed session; the sessionID (an opaque blob generated by the
- * server) is returned in *sessionID. The length of the sessionID
- * is returned in *sessionIDLength. Caller must allocate the
- * sessionID buffer; it max size is MAX_SESSION_ID_LENGTH bytes.
- */
-#define MAX_SESSION_ID_LENGTH  32
-
-OSStatus
-SSLGetResumableSessionInfo     (
-       SSLContextRef   context,
-       Boolean                 *sessionWasResumed,             // RETURNED
-       void                    *sessionID,                             // RETURNED, mallocd by caller
-       size_t                  *sessionIDLength);              // IN/OUT
-
-/*
- * Getters for SSLSetCertificate() and SSLSetEncryptionCertificate()
- */
-OSStatus
-SSLGetCertificate (
-       SSLContextRef   context,
-       CFArrayRef              *certRefs);                             // RETURNED, *not* retained
-
-OSStatus
-SSLGetEncryptionCertificate (
-       SSLContextRef   context,
-       CFArrayRef              *certRefs);                             // RETURNED, *not* retained
-
-/*
- * Getter for SSLSetClientSideAuthenticate()
- */
-OSStatus
-SSLGetClientSideAuthenticate (
-       SSLContextRef   context,
-       SSLAuthenticate *auth);                                 // RETURNED
-
-/*
- * Get/set array of trusted leaf certificates.
- *
- * If none have been set previously with SSLSetTrustedLeafCertificates(),
- * then SSLCopyTrustedLeafCertificates() will return NULL with noErr.
- */
-OSStatus
-SSLSetTrustedLeafCertificates (
-       SSLContextRef   context,
-       CFArrayRef              certRefs);
-
-OSStatus
-SSLCopyTrustedLeafCertificates (
-       SSLContextRef   context,
-       CFArrayRef              *certRefs);                             // RETURNED, caller must release
-
-/*
- * Get/set enable of anonymous ciphers. Default is enabled.
- *
- * SSLSetAllowAnonymousCiphers() returns badReqErr if SSLSetEnabledCiphers()
- * has already been called.
- *
- * The enable state set by SSLSetAllowAnonymousCiphers() is ignored if
- * SSLSetEnabledCiphers() is called after SSLSetAllowAnonymousCiphers() is
- * called, i.e., SSLSetEnabledCiphers() overrides SSLSetAllowAnonymousCiphers().
- *
- * NOTE: "Anonymous" ciphers include those ciphers that perform no encryption,
- * as well as ciphers that perform no authentication, since neither are secure.
- */
-OSStatus
-SSLSetAllowAnonymousCiphers(
-       SSLContextRef   context,
-       Boolean                 enable);
-
-OSStatus
-SSLGetAllowAnonymousCiphers(
-       SSLContextRef   context,
-       Boolean                 *enable);
-
-/*
- * Override the default session cache timeout for a cache entry created for
- * the current session.
- */
-OSStatus
-SSLSetSessionCacheTimeout(
-       SSLContextRef context,
-       uint32_t timeoutInSeconds);
-
-/*
- * Callback function for EAP-style PAC-based session resumption.
- * This function is called by SecureTransport to obtain the
- * master secret.
- */
-typedef void (*SSLInternalMasterSecretFunction)(
-       SSLContextRef ctx,
-       const void *arg,                /* opaque to SecureTransport; app-specific */
-       void *secret,                   /* mallocd by caller, SSL_MASTER_SECRET_SIZE */
-       size_t *secretLength);  /* in/out */
-
-/*
- * Register a callback for obtaining the master_secret when performing
- * PAC-based session resumption. At the time the callback is called,
- * the following are guaranteed to be valid:
- *
- *  -- serverRandom (via SSLInternalServerRandom())
- *  -- clientRandom (via SSLInternalClientRandom())
- *  -- negotiated protocol version (via SSLGetNegotiatedProtocolVersion())
- *  -- negotiated CipherSuite (via SSLGetNegotiatedCipher())
- *
- * Currently, PAC-based session resumption is only implemented on
- * the client side for Deployment builds.
- *
- * On the client side, this callback occurs if/when the server sends a
- * ChangeCipherSpec message immediately following its ServerHello
- * message (i.e., it's skipped the entire Key Exchange phase of
- * negotiation).
- *
- * On the server side (Development builds only) this callback occurs
- * immediately upon receipt of the Client Hello message, before we send
- * the Server Hello.
- */
-OSStatus
-SSLInternalSetMasterSecretFunction(
-       SSLContextRef ctx,
-       SSLInternalMasterSecretFunction mFunc,
-       const void *arg);               /* opaque to SecureTransport; app-specific */
-
-/*
- * Provide an opaque SessionTicket for use in PAC-based session
- * resumption. Client side only. The provided ticket is sent in
- * the ClientHello message as a SessionTicket extension.
- * The maximum ticketLength is 2**16-1.
- */
-OSStatus SSLInternalSetSessionTicket(
-   SSLContextRef ctx,
-   const void *ticket,
-   size_t ticketLength);
-
-/*
- * Support for specifying and obtaining ECC curves, used with the ECDH-based
- * ciphersuites.
- */
-
-/*
- * These are the named curves from RFC 4492
- * section 5.1.1, with the exception of SSL_Curve_None which means
- * "ECDSA not negotiated".
- */
-typedef enum
-{
-       SSL_Curve_None = -1,
-
-    SSL_Curve_sect163k1 = 1,
-    SSL_Curve_sect163r1 = 2,
-    SSL_Curve_sect163r2 = 3,
-    SSL_Curve_sect193r1 = 4,
-    SSL_Curve_sect193r2 = 5,
-    SSL_Curve_sect233k1 = 6,
-    SSL_Curve_sect233r1 = 7,
-    SSL_Curve_sect239k1 = 8,
-    SSL_Curve_sect283k1 = 9,
-    SSL_Curve_sect283r1 = 10,
-    SSL_Curve_sect409k1 = 11,
-    SSL_Curve_sect409r1 = 12,
-    SSL_Curve_sect571k1 = 13,
-    SSL_Curve_sect571r1 = 14,
-    SSL_Curve_secp160k1 = 15,
-    SSL_Curve_secp160r1 = 16,
-    SSL_Curve_secp160r2 = 17,
-    SSL_Curve_secp192k1 = 18,
-    SSL_Curve_secp192r1 = 19,
-    SSL_Curve_secp224k1 = 20,
-    SSL_Curve_secp224r1 = 21,
-    SSL_Curve_secp256k1 = 22,
-
-    /* These are the ones we actually support */
-       SSL_Curve_secp256r1 = 23,
-       SSL_Curve_secp384r1 = 24,
-       SSL_Curve_secp521r1 = 25
-} SSL_ECDSA_NamedCurve;
-
-/*
- * Obtain the SSL_ECDSA_NamedCurve negotiated during a handshake.
- * Returns paramErr if no ECDH-related ciphersuite was negotiated.
- */
-extern OSStatus SSLGetNegotiatedCurve(
-   SSLContextRef ctx,
-   SSL_ECDSA_NamedCurve *namedCurve);    /* RETURNED */
-
-/*
- * Obtain the number of currently enabled SSL_ECDSA_NamedCurves.
- */
-extern OSStatus SSLGetNumberOfECDSACurves(
-   SSLContextRef ctx,
-   unsigned *numCurves);                               /* RETURNED */
-
-/*
- * Obtain the ordered list of currently enabled SSL_ECDSA_NamedCurves.
- * Caller allocates returned array and specifies its size (in
- * SSL_ECDSA_NamedCurves) in *numCurves on entry; *numCurves
- * is the actual size of the returned array on successful return.
- */
-extern OSStatus SSLGetECDSACurves(
-   SSLContextRef ctx,
-   SSL_ECDSA_NamedCurve *namedCurves,  /* RETURNED */
-   unsigned *numCurves);                               /* IN/OUT */
-
-/*
- * Specify ordered list of allowable named curves.
- */
-extern OSStatus SSLSetECDSACurves(
-   SSLContextRef ctx,
-   const SSL_ECDSA_NamedCurve *namedCurves,
-   unsigned numCurves);
-
-/*
- * Server-specified client authentication mechanisms.
- */
-typedef enum {
-       /* doesn't appear on the wire */
-       SSLClientAuthNone = -1,
-       /* RFC 2246 7.4.6 */
-       SSLClientAuth_RSASign = 1,
-       SSLClientAuth_DSSSign = 2,
-       SSLClientAuth_RSAFixedDH = 3,
-       SSLClientAuth_DSS_FixedDH = 4,
-       /* RFC 4492 5.5 */
-       SSLClientAuth_ECDSASign = 64,
-       SSLClientAuth_RSAFixedECDH = 65,
-       SSLClientAuth_ECDSAFixedECDH = 66
-} SSLClientAuthenticationType;
-
-/* TLS 1.2 Signature Algorithms extension values for hash field. */
-typedef enum {
-    SSL_HashAlgorithmNone = 0,
-    SSL_HashAlgorithmMD5 = 1,
-    SSL_HashAlgorithmSHA1 = 2,
-    SSL_HashAlgorithmSHA224 = 3,
-    SSL_HashAlgorithmSHA256 = 4,
-    SSL_HashAlgorithmSHA384 = 5,
-    SSL_HashAlgorithmSHA512 = 6
-} SSL_HashAlgorithm;
-
-/* TLS 1.2 Signature Algorithms extension values for signature field. */
-typedef enum {
-    SSL_SignatureAlgorithmAnonymous = 0,
-    SSL_SignatureAlgorithmRSA = 1,
-    SSL_SignatureAlgorithmDSA = 2,
-    SSL_SignatureAlgorithmECDSA = 3
-} SSL_SignatureAlgorithm;
-
-typedef struct {
-    SSL_HashAlgorithm hash;
-    SSL_SignatureAlgorithm signature;
-} SSLSignatureAndHashAlgorithm;
-
-/*
- * Obtain the number of client authentication mechanisms specified by
- * the server in its Certificate Request message.
- * Returns paramErr if server hasn't sent a Certificate Request message
- * (i.e., client certificate state is kSSLClientCertNone).
- */
-extern OSStatus SSLGetNumberOfClientAuthTypes(
-       SSLContextRef ctx,
-       unsigned *numTypes);
-
-/*
- * Obtain the client authentication mechanisms specified by
- * the server in its Certificate Request message.
- * Caller allocates returned array and specifies its size (in
- * SSLClientAuthenticationTypes) in *numType on entry; *numTypes
- * is the actual size of the returned array on successful return.
- */
-extern OSStatus SSLGetClientAuthTypes(
-   SSLContextRef ctx,
-   SSLClientAuthenticationType *authTypes,             /* RETURNED */
-   unsigned *numTypes);                                                        /* IN/OUT */
-
-/*
- * Obtain the SSLClientAuthenticationType actually performed.
- * Only valid if client certificate state is kSSLClientCertSent
- * or kSSLClientCertRejected; SSLClientAuthNone is returned as
- * the negotiated auth type otherwise.
- */
-extern OSStatus SSLGetNegotiatedClientAuthType(
-   SSLContextRef ctx,
-   SSLClientAuthenticationType *authType);             /* RETURNED */
-
-/*
- * Obtain the number of supported_signature_algorithms specified by
- * the server in its Certificate Request message.
- * Returns paramErr if server hasn't sent a Certificate Request message
- * (i.e., client certificate state is kSSLClientCertNone).
- */
-extern OSStatus SSLGetNumberOfSignatureAlgorithms(
-    SSLContextRef ctx,
-    unsigned *numSigAlgs);
-
-/*
- * Obtain the supported_signature_algorithms specified by
- * the server in its Certificate Request message.
- * Caller allocates returned array and specifies its size (in
- * SSLClientAuthenticationTypes) in *numType on entry; *numTypes
- * is the actual size of the returned array on successful return.
- */
-extern OSStatus SSLGetSignatureAlgorithms(
-    SSLContextRef ctx,
-    SSLSignatureAndHashAlgorithm *sigAlgs,             /* RETURNED */
-    unsigned *numSigAlgs);                                                     /* IN/OUT */
-
-/*
- * Create a new Datagram TLS session context.
- * Use in place of SSLNewContext to create a DTLS session.
- * Deprecated: please use the allocator based functions, when available.
- */
-OSStatus
-SSLNewDatagramContext          (Boolean                        isServer,
-                             SSLContextRef             *dtlsContextPtr);       /* RETURNED */
-
-
-
-/* Private SSL session options */
-typedef enum {
-       /*
-        * This option can be used to enable sending the first byte
-        * of application data in its own SSL record in order to
-        * mitigate a known-IV weakness, a.k.a. the BEAST attack.
-        */
-       kSSLSessionOptionSendOneByteRecord = -1
-} SSLPrivateSessionOption;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SECURE_TRANSPORT_PRIV_H_ */
index 1e170bffe7fdbe1d3c9f99c1f308413477365c3e..2171d75d0d9d85ae465720e9f570a211909ecf3b 100644 (file)
@@ -6,3 +6,9 @@ VERSIONING_SYSTEM = apple-generic;
 DEAD_CODE_STRIPPING = YES;
 
 ARCHS = $(ARCHS_STANDARD_32_64_BIT)
 DEAD_CODE_STRIPPING = YES;
 
 ARCHS = $(ARCHS_STANDARD_32_64_BIT)
+
+// Debug symbols should be on obviously
+GCC_GENERATE_DEBUGGING_SYMBOLS = YES
+COPY_PHASE_STRIP = NO
+STRIP_STYLE = debugging
+STRIP_INSTALLED_PRODUCT = NO
index 937d177552d7c32bc7eea9753d7d6523f1f0ea72..53107c2494809efdb6a57fdc2d817786119cc6a1 100644 (file)
@@ -1,3 +1,4 @@
 GCC_OPTIMIZATION_LEVEL = 0
 GCC_PREPROCESSOR_DEFINITIONS = DEBUG=1 $(inherited)
 GCC_OPTIMIZATION_LEVEL = 0
 GCC_PREPROCESSOR_DEFINITIONS = DEBUG=1 $(inherited)
-COPY_PHASE_STRIP = NO
+
+GCC_TREAT_WARNINGS_AS_ERRORS = YES
diff --git a/libsecurity_ssl/config/kext.xcconfig b/libsecurity_ssl/config/kext.xcconfig
new file mode 100644 (file)
index 0000000..1cafefd
--- /dev/null
@@ -0,0 +1,29 @@
+#include "base.xcconfig"
+
+PRODUCT_NAME = $(TARGET_NAME)
+EXECUTABLE_PREFIX =
+
+CODE_SIGN_IDENTITY =
+
+HEADER_SEARCH_PATHS = $(PROJECT_DIR) $(PROJECT_DIR)/../utilities $(SYSTEM_LIBRARY_DIR)/Frameworks/Kernel.framework/Headers $(SYSTEM_LIBRARY_DIR)/Frameworks/Kernel.framework/PrivateHeaders
+
+SKIP_INSTALL = YES
+
+ALWAYS_SEARCH_USER_PATHS = YES
+
+GCC_ENABLE_KERNEL_DEVELOPMENT = YES
+GCC_C_LANGUAGE_STANDARD = gnu99
+
+WARNING_CFLAGS = -Wmost -Wno-four-char-constants -Wno-unknown-pragmas $(inherited)
+
+OTHER_CFLAGS = -DKERNEL $(inherited)
+
+GCC_SYMBOLS_PRIVATE_EXTERN = NO
+GCC_WARN_64_TO_32_BIT_CONVERSION = YES
+GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES
+GCC_WARN_ABOUT_RETURN_TYPE = YES
+GCC_WARN_UNUSED_VARIABLE = YES
+
+LINK_WITH_STANDARD_LIBRARIES = NO
+
+SUPPORTED_PLATFORMS = macosx iphoneos
index 0651e308fc6eebde63e5846015a45dd015b18e9d..2fe95ad56de972a9c44600ee5e414453ef69595e 100644 (file)
@@ -5,9 +5,9 @@ EXECUTABLE_PREFIX =
 
 CODE_SIGN_IDENTITY = 
 
 
 CODE_SIGN_IDENTITY = 
 
-HEADER_SEARCH_PATHS[sdk=macosx*] = $(PROJECT_DIR) $(PROJECT_DIR)/../libsecurity_asn1 $(PROJECT_DIR)/../libsecurity_keychain/libDER $(BUILT_PRODUCTS_DIR) $(PROJECT_DIR)/../sec $(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Headers $(inherited)
+HEADER_SEARCH_PATHS[sdk=macosx*] = $(PROJECT_DIR) $(PROJECT_DIR)/../regressions $(PROJECT_DIR)/../include $(BUILT_PRODUCTS_DIR)/derived_src $(PROJECT_DIR)/../utilities $(PROJECT_DIR)/../libsecurity_keychain/ $(PROJECT_DIR)/../libsecurity_keychain/libDER $(BUILT_PRODUCTS_DIR) $(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Headers $(inherited)
 
 
-HEADER_SEARCH_PATHS[sdk=iphone*] = $(PROJECT_DIR) $(PROJECT_DIR)/../libsecurity_asn1 $(BUILT_PRODUCTS_DIR)$(INDIGO_INSTALL_PATH_PREFIX)/usr/local/include $(inherited)
+HEADER_SEARCH_PATHS[sdk=iphone*] = $(PROJECT_DIR) $(PROJECT_DIR)/../regressions $(PROJECT_DIR)/../utilities $(PROJECT_DIR)/../libsecurity_asn1 $(PROJECT_DIR)/../libDER $(PROJECT_DIR)/../sec $(BUILT_PRODUCTS_DIR)$(INDIGO_INSTALL_PATH_PREFIX)/usr/local/include $(inherited)
 
 SKIP_INSTALL = YES
 
 
 SKIP_INSTALL = YES
 
@@ -27,4 +27,4 @@ GCC_WARN_UNUSED_VARIABLE = YES
 
 SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator
 
 
 SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator
 
-GCC_PREPROCESSOR_DEFINITIONS[sdk=iphonesimulator*] = INDIGO=1 $(inherited)
\ No newline at end of file
+GCC_PREPROCESSOR_DEFINITIONS[sdk=iphonesimulator*] = INDIGO=1 $(inherited)
index 3110dcb5b93f17bd64177e01d5adf4243c5562ae..088ded92a81006819c31d49f1dc81025b210663d 100644 (file)
@@ -1,2 +1,2 @@
+GCC_OPTIMIZATION_LEVEL = s
 GCC_PREPROCESSOR_DEFINITIONS = NDEBUG=1 $(inherited)
 GCC_PREPROCESSOR_DEFINITIONS = NDEBUG=1 $(inherited)
-COPY_PHASE_STRIP = YES
diff --git a/libsecurity_ssl/config/tests.xcconfig b/libsecurity_ssl/config/tests.xcconfig
new file mode 100644 (file)
index 0000000..551eb22
--- /dev/null
@@ -0,0 +1,25 @@
+#include "base.xcconfig"
+
+PRODUCT_NAME = $(TARGET_NAME)
+EXECUTABLE_PREFIX = 
+
+CODE_SIGN_IDENTITY = 
+
+GCC_C_LANGUAGE_STANDARD = gnu99
+
+WARNING_CFLAGS = -Wmost -Wno-four-char-constants -Wno-unknown-pragmas $(inherited)
+
+GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO
+
+GCC_SYMBOLS_PRIVATE_EXTERN = NO
+GCC_WARN_64_TO_32_BIT_CONVERSION = YES
+GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES
+GCC_WARN_ABOUT_RETURN_TYPE = YES
+GCC_WARN_UNUSED_VARIABLE = YES
+
+SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator
+
+GCC_PREPROCESSOR_DEFINITIONS[sdk=iphonesimulator*] = INDIGO=1 $(inherited)
+
+INSTALL_PATH = $(SDKROOT)/usr/local/bin
+INSTALL_PATH_ACTUAL[sdk=iphonesimulator*] = /usr/local/bin
diff --git a/libsecurity_ssl/dtlsEcho/README b/libsecurity_ssl/dtlsEcho/README
new file mode 100644 (file)
index 0000000..ea0e9f6
--- /dev/null
@@ -0,0 +1 @@
+DTLS echo client/server over udp.
diff --git a/libsecurity_ssl/dtlsEcho/dtlsEchoClient.c b/libsecurity_ssl/dtlsEcho/dtlsEchoClient.c
new file mode 100644 (file)
index 0000000..f8f0bfc
--- /dev/null
@@ -0,0 +1,295 @@
+/*
+ *  dtlsEchoClient.c
+ *  Security
+ *
+ *  Created by Fabrice Gautier on 1/31/11.
+ *  Copyright 2011 Apple, Inc. All rights reserved.
+ *
+ */
+
+#include <Security/Security.h>
+#include <Security/SecBase.h>
+
+#include "../sslViewer/sslAppUtils.h"
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h> /* close() */
+#include <string.h> /* memset() */
+#include <fcntl.h>
+#include <time.h>
+
+#ifdef NO_SERVER
+#include <securityd/spi.h>
+#endif
+
+#include "ssl-utils.h"
+
+#define SERVER "127.0.0.1"
+//#define SERVER "17.201.58.114"
+#define PORT 23232
+#define BUFLEN 128
+#define COUNT 10
+
+#if 0
+static void dumppacket(const unsigned char *data, unsigned long len)
+{
+    unsigned long i;
+    for(i=0;i<len;i++)
+    {
+        if((i&0xf)==0) printf("%04lx :",i);
+        printf(" %02x", data[i]);
+        if((i&0xf)==0xf) printf("\n");
+    }
+    printf("\n");
+}
+#endif
+
+/* 2K should be enough for everybody */
+#define MTU 2048
+static unsigned char readBuffer[MTU];
+static unsigned int  readOff=0;
+static size_t        readLeft=0;
+
+static
+OSStatus SocketRead(
+                    SSLConnectionRef   connection,
+                    void                               *data,
+                    size_t                             *dataLength)
+{
+    int fd = (int)connection;
+    ssize_t len;
+    uint8_t *d=readBuffer;
+
+    if(readLeft==0)
+    {
+        len = read(fd, readBuffer, MTU);
+
+        if(len>0) {
+            readOff=0;
+            readLeft=(size_t) len;
+            printf("SocketRead: %ld bytes... epoch: %02x seq=%02x%02x\n",
+                   len, d[4], d[9], d[10]);
+
+        } else {
+            int theErr = errno;
+            switch(theErr) {
+                case EAGAIN:
+                    //printf("SocketRead: EAGAIN\n");
+                    *dataLength=0;
+                    /* nonblocking, no data */
+                    return errSSLWouldBlock;
+                default:
+                    perror("SocketRead");
+                    return errSecIO;
+            }
+        }
+    }
+
+    if(readLeft<*dataLength) {
+        *dataLength=readLeft;
+    }
+
+    memcpy(data, readBuffer+readOff, *dataLength);
+    readLeft-=*dataLength;
+    readOff+=*dataLength;
+
+    return errSecSuccess;
+
+}
+
+static
+OSStatus SocketWrite(
+                     SSLConnectionRef   connection,
+                     const void         *data,
+                     size_t                    *dataLength)    /* IN/OUT */
+{
+    int fd = (int)connection;
+    ssize_t len;
+    OSStatus err = errSecSuccess;
+    const uint8_t *d=data;
+
+#if 0
+    if((rand()&3)==1) {
+
+        /* drop 1/8th packets */
+        printf("SocketWrite: Drop %ld bytes... epoch: %02x seq=%02x%02x\n",
+               *dataLength, d[4], d[9], d[10]);
+        return errSecSuccess;
+
+    }
+#endif
+
+    len = send(fd, data, *dataLength, 0);
+
+    if(len>0) {
+        *dataLength=(size_t)len;
+        printf("SocketWrite: Sent %ld bytes... epoch: %02x seq=%02x%02x\n",
+               len, d[4], d[9], d[10]);
+        return err;
+    }
+
+    int theErr = errno;
+    switch(theErr) {
+        case EAGAIN:
+            /* nonblocking, no data */
+            err = errSSLWouldBlock;
+            break;
+        default:
+            perror("SocketWrite");
+            err = errSecIO;
+            break;
+    }
+
+    return err;
+
+}
+
+
+int main(int argc, char **argv)
+{
+    int fd;
+    struct sockaddr_in sa;
+
+    if ((fd=socket(AF_INET, SOCK_DGRAM, 0))==-1) {
+        perror("socket");
+        exit(-1);
+    }
+
+#ifdef NO_SERVER
+# if DEBUG
+    securityd_init();
+# endif
+#endif
+
+    memset((char *) &sa, 0, sizeof(sa));
+    sa.sin_family = AF_INET;
+    sa.sin_port = htons(PORT);
+    if (inet_aton(SERVER, &sa.sin_addr)==0) {
+        fprintf(stderr, "inet_aton() failed\n");
+        exit(1);
+    }
+
+    time_t seed=time(NULL);
+//    time_t seed=1298952499;
+    srand((unsigned)seed);
+    printf("Random drop initialized with seed = %lu\n", seed);
+
+    if(connect(fd, (struct sockaddr *)&sa, sizeof(sa))==-1)
+    {
+        perror("connect");
+        return errno;
+    }
+
+    /* Change to non blocking io */
+    fcntl(fd, F_SETFL, O_NONBLOCK);
+
+    SSLConnectionRef c=(SSLConnectionRef)(intptr_t)fd;
+
+
+    OSStatus            ortn;
+    SSLContextRef       ctx = NULL;
+
+    SSLClientCertificateState certState;
+    SSLCipherSuite negCipher;
+    SSLProtocol negVersion;
+
+       /*
+        * Set up a SecureTransport session.
+        */
+       ortn = SSLNewDatagramContext(false, &ctx);
+       if(ortn) {
+               printSslErrStr("SSLNewDatagramContext", ortn);
+               return ortn;
+       }
+       ortn = SSLSetIOFuncs(ctx, SocketRead, SocketWrite);
+       if(ortn) {
+               printSslErrStr("SSLSetIOFuncs", ortn);
+               return ortn;
+       }
+
+    ortn = SSLSetConnection(ctx, c);
+       if(ortn) {
+               printSslErrStr("SSLSetConnection", ortn);
+               return ortn;
+       }
+
+    ortn = SSLSetMaxDatagramRecordSize(ctx, 600);
+    if(ortn) {
+               printSslErrStr("SSLSetMaxDatagramRecordSize", ortn);
+        return ortn;
+       }
+
+    /* Lets not verify the cert, which is a random test cert */
+    ortn = SSLSetEnableCertVerify(ctx, false);
+    if(ortn) {
+        printSslErrStr("SSLSetEnableCertVerify", ortn);
+        return ortn;
+    }
+
+    ortn = SSLSetCertificate(ctx, server_chain());
+    if(ortn) {
+        printSslErrStr("SSLSetCertificate", ortn);
+        return ortn;
+    }
+
+    do {
+               ortn = SSLHandshake(ctx);
+           if(ortn == errSSLWouldBlock) {
+               /* keep UI responsive */
+               sslOutputDot();
+           }
+    } while (ortn == errSSLWouldBlock);
+
+
+    SSLGetClientCertificateState(ctx, &certState);
+       SSLGetNegotiatedCipher(ctx, &negCipher);
+       SSLGetNegotiatedProtocolVersion(ctx, &negVersion);
+
+    int count;
+    size_t len, readLen, writeLen;
+    char buffer[BUFLEN];
+
+    count = 0;
+    while(count<COUNT) {
+        int timeout = 10000;
+
+        snprintf(buffer, BUFLEN, "Message %d", count);
+        len = strlen(buffer);
+
+        ortn=SSLWrite(ctx, buffer, len, &writeLen);
+        if(ortn) {
+            printSslErrStr("SSLWrite", ortn);
+            break;
+        }
+        printf("Wrote %lu bytes\n", writeLen);
+
+        count++;
+
+        do {
+            ortn=SSLRead(ctx, buffer, BUFLEN, &readLen);
+        } while((ortn==errSSLWouldBlock) && (timeout--));
+        if(ortn==errSSLWouldBlock) {
+            printf("Echo timeout...\n");
+            continue;
+        }
+        if(ortn) {
+                printSslErrStr("SSLRead", ortn);
+                break;
+        }
+        buffer[readLen]=0;
+        printf("Received %lu bytes: %s\n", readLen, buffer);
+
+     }
+
+    SSLClose(ctx);
+
+    SSLDisposeContext(ctx);
+
+    return ortn;
+}
diff --git a/libsecurity_ssl/dtlsEcho/dtlsEchoServer.c b/libsecurity_ssl/dtlsEcho/dtlsEchoServer.c
new file mode 100644 (file)
index 0000000..5108f7e
--- /dev/null
@@ -0,0 +1,310 @@
+/*
+ *  dtlsEchoServer.c
+ *  Security
+ *
+ *  Created by Fabrice Gautier on 1/31/11.
+ *  Copyright 2011 Apple, Inc. All rights reserved.
+ *
+ */
+
+#include <Security/Security.h>
+#include <Security/SecBase.h>
+
+#include "../sslViewer/sslAppUtils.h"
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h> /* close() */
+#include <string.h> /* memset() */
+#include <fcntl.h>
+#include <time.h>
+
+#ifdef NO_SERVER
+#include <securityd/spi.h>
+#endif
+
+#define PORT 23232
+
+#include "ssl-utils.h"
+
+static void dumppacket(const unsigned char *data, unsigned long len)
+{
+    unsigned long i;
+    for(i=0;i<len;i++)
+    {
+        if((i&0xf)==0) printf("%04lx :",i);
+        printf(" %02x", data[i]);
+        if((i&0xf)==0xf) printf("\n");
+    }
+    printf("\n");
+}
+
+
+/* 2K should be enough for everybody */
+#define MTU 2048
+static unsigned char readBuffer[MTU];
+static unsigned int  readOff=0;
+static size_t        readLeft=0;
+
+static
+OSStatus SocketRead(
+                    SSLConnectionRef   connection,
+                    void                               *data,
+                    size_t                             *dataLength)
+{
+    int fd = (int)connection;
+    ssize_t len;
+    uint8_t *d=readBuffer;
+
+    if(readLeft==0)
+    {
+        len = read(fd, readBuffer, MTU);
+
+        if(len>0) {
+            readOff=0;
+            readLeft=(size_t) len;
+            printf("SocketRead: %ld bytes... epoch: %02x seq=%02x%02x\n",
+                   len, d[4], d[9], d[10]);
+        } else {
+            int theErr = errno;
+            switch(theErr) {
+                case EAGAIN:
+                    // printf("SocketRead: EAGAIN\n");
+                    *dataLength=0;
+                    /* nonblocking, no data */
+                    return errSSLWouldBlock;
+                default:
+                    perror("SocketRead");
+                    return errSecIO;
+            }
+        }
+    }
+
+    if(readLeft<*dataLength) {
+        *dataLength=readLeft;
+    }
+
+    memcpy(data, readBuffer+readOff, *dataLength);
+    readLeft-=*dataLength;
+    readOff+=*dataLength;
+
+
+    return errSecSuccess;
+
+}
+
+
+static
+OSStatus SocketWrite(
+                     SSLConnectionRef   connection,
+                     const void         *data,
+                     size_t                    *dataLength)    /* IN/OUT */
+{
+    int fd = (int)connection;
+    ssize_t len;
+    OSStatus err = errSecSuccess;
+    const uint8_t *d=data;
+
+#if 1
+    if((rand()&3)==1) {
+        /* drop 1/8 packets */
+        printf("SocketWrite: Drop %ld bytes... epoch: %02x seq=%02x%02x\n",
+               *dataLength, d[4], d[9], d[10]);
+        return errSecSuccess;
+    }
+#endif
+
+    len = send(fd, data, *dataLength, 0);
+
+    if(len>0) {
+        *dataLength=(size_t)len;
+
+        printf("SocketWrite: Sent %ld bytes... epoch: %02x seq=%02x%02x\n",
+               len, d[4], d[9], d[10]);
+
+        return err;
+    }
+
+    int theErr = errno;
+    switch(theErr) {
+        case EAGAIN:
+            /* nonblocking, no data */
+            err = errSSLWouldBlock;
+            break;
+        default:
+            perror("SocketWrite");
+            err = errSecIO;
+            break;
+    }
+
+    return err;
+
+}
+
+
+int main(int argc, char **argv)
+{
+    struct sockaddr_in sa; /* server address for bind */
+    struct sockaddr_in ca; /* client address for connect */
+    int fd;
+    ssize_t l;
+
+#ifdef NO_SERVER
+# if DEBUG
+    securityd_init();
+# endif
+#endif
+
+    if ((fd=socket(AF_INET, SOCK_DGRAM, 0))==-1) {
+        perror("socket");
+        return errno;
+    }
+
+    time_t seed=time(NULL);
+//    time_t seed=1298952496;
+    srand((unsigned)seed);
+    printf("Random drop initialized with seed = %lu\n", seed);
+
+    memset((char *) &sa, 0, sizeof(sa));
+    sa.sin_family = AF_INET;
+    sa.sin_port = htons(PORT);
+    sa.sin_addr.s_addr = htonl(INADDR_ANY);
+
+    if(bind (fd, (struct sockaddr *)&sa, sizeof(sa))==-1)
+    {
+        perror("bind");
+        return errno;
+    }
+
+    printf("Waiting for first packet...\n");
+    /* PEEK only... */
+    socklen_t slen=sizeof(ca);
+    char b;
+    if((l=recvfrom(fd, &b, 1, MSG_PEEK, (struct sockaddr *)&ca, &slen))==-1)
+    {
+        perror("recvfrom");
+        return errno;
+    }
+
+    printf("Received packet from %s (%ld), connecting...\n", inet_ntoa(ca.sin_addr), l);
+
+    if(connect(fd, (struct sockaddr *)&ca, sizeof(ca))==-1)
+    {
+        perror("connect");
+        return errno;
+    }
+
+    /* Change to non blocking */
+    fcntl(fd, F_SETFL, O_NONBLOCK);
+
+
+    SSLConnectionRef c=(SSLConnectionRef)(intptr_t)fd;
+
+
+    OSStatus            ortn;
+    SSLContextRef       ctx = NULL;
+
+    SSLClientCertificateState certState;
+    SSLCipherSuite negCipher;
+
+       /*
+        * Set up a SecureTransport session.
+        */
+       ortn = SSLNewDatagramContext(true, &ctx);
+       if(ortn) {
+               printSslErrStr("SSLNewDatagramContext", ortn);
+               return ortn;
+       }
+
+       ortn = SSLSetIOFuncs(ctx, SocketRead, SocketWrite);
+       if(ortn) {
+               printSslErrStr("SSLSetIOFuncs", ortn);
+        return ortn;
+       }
+
+    ortn = SSLSetConnection(ctx, c);
+       if(ortn) {
+               printSslErrStr("SSLSetConnection", ortn);
+               return ortn;
+       }
+
+    ortn = SSLSetDatagramHelloCookie(ctx, &ca, 32);
+    if(ortn) {
+               printSslErrStr("SSLSetDatagramHelloCookie", ortn);
+        return ortn;
+       }
+
+    ortn = SSLSetMaxDatagramRecordSize(ctx, 600);
+    if(ortn) {
+               printSslErrStr("SSLSetMaxDatagramRecordSize", ortn);
+        return ortn;
+       }
+
+    /* Lets not verify the cert, which is a random test cert */
+    ortn = SSLSetEnableCertVerify(ctx, false);
+    if(ortn) {
+        printSslErrStr("SSLSetEnableCertVerify", ortn);
+        return ortn;
+    }
+
+    ortn = SSLSetCertificate(ctx, server_chain());
+    if(ortn) {
+        printSslErrStr("SSLSetCertificate", ortn);
+        return ortn;
+    }
+
+    ortn = SSLSetClientSideAuthenticate(ctx, kAlwaysAuthenticate);
+    if(ortn) {
+        printSslErrStr("SSLSetCertificate", ortn);
+        return ortn;
+    }
+
+    printf("Server Handshake...\n");
+    do {
+               ortn = SSLHandshake(ctx);
+           if(ortn == errSSLWouldBlock) {
+               /* keep UI responsive */
+               sslOutputDot();
+           }
+    } while (ortn == errSSLWouldBlock);
+
+    if(ortn) {
+        printSslErrStr("SSLHandshake", ortn);
+        return ortn;
+    }
+
+    SSLGetClientCertificateState(ctx, &certState);
+       SSLGetNegotiatedCipher(ctx, &negCipher);
+
+    printf("Server Handshake done. Cipher is %s\n", sslGetCipherSuiteString(negCipher));
+
+    unsigned char buffer[MTU];
+    size_t len, readLen;
+
+    while(1) {
+        while((ortn=SSLRead(ctx, buffer, MTU, &readLen))==errSSLWouldBlock);
+        if(ortn) {
+            printSslErrStr("SSLRead", ortn);
+            break;
+        }
+        buffer[readLen]=0;
+        printf("Received %lu bytes:\n", readLen);
+        dumppacket(buffer, readLen);
+
+        ortn=SSLWrite(ctx, buffer, readLen, &len);
+        if(ortn) {
+            printSslErrStr("SSLRead", ortn);
+            break;
+        }
+        printf("Echoing %lu bytes\n", len);
+    }
+
+    SSLDisposeContext(ctx);
+
+    return ortn;
+}
diff --git a/libsecurity_ssl/lib/CipherSuite.h b/libsecurity_ssl/lib/CipherSuite.h
new file mode 100644 (file)
index 0000000..8c578d6
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+ * Copyright (c) 1999-2002,2005-2007,2010-2012 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * CipherSuite.h - SSL Cipher Suite definitions.
+ */
+
+#ifndef _SECURITY_CIPHERSUITE_H_
+#define _SECURITY_CIPHERSUITE_H_
+
+#include <TargetConditionals.h>
+#include <stdint.h>
+
+/*
+ * Defined as enum for debugging, but in the protocol
+ * it is actually exactly two bytes
+ */
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+/* 32-bit value on OS X */
+typedef uint32_t SSLCipherSuite;
+#else
+/* 16-bit value on iOS */
+typedef uint16_t SSLCipherSuite;
+#endif
+
+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,
+
+       /* TLS addenda using AES, per RFC 3268 */
+       TLS_RSA_WITH_AES_128_CBC_SHA      =                     0x002F,
+       TLS_DH_DSS_WITH_AES_128_CBC_SHA   =                     0x0030,
+       TLS_DH_RSA_WITH_AES_128_CBC_SHA   =                     0x0031,
+       TLS_DHE_DSS_WITH_AES_128_CBC_SHA  =                     0x0032,
+       TLS_DHE_RSA_WITH_AES_128_CBC_SHA  =                     0x0033,
+       TLS_DH_anon_WITH_AES_128_CBC_SHA  =                     0x0034,
+       TLS_RSA_WITH_AES_256_CBC_SHA      =                     0x0035,
+       TLS_DH_DSS_WITH_AES_256_CBC_SHA   =                     0x0036,
+       TLS_DH_RSA_WITH_AES_256_CBC_SHA   =                     0x0037,
+       TLS_DHE_DSS_WITH_AES_256_CBC_SHA  =                     0x0038,
+       TLS_DHE_RSA_WITH_AES_256_CBC_SHA  =                     0x0039,
+       TLS_DH_anon_WITH_AES_256_CBC_SHA  =                     0x003A,
+
+       /* ECDSA addenda, RFC 4492 */
+       TLS_ECDH_ECDSA_WITH_NULL_SHA           =        0xC001,
+       TLS_ECDH_ECDSA_WITH_RC4_128_SHA        =        0xC002,
+       TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA   =        0xC003,
+       TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA    =        0xC004,
+       TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA    =        0xC005,
+       TLS_ECDHE_ECDSA_WITH_NULL_SHA          =        0xC006,
+       TLS_ECDHE_ECDSA_WITH_RC4_128_SHA       =        0xC007,
+       TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA  =        0xC008,
+       TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA   =        0xC009,
+       TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA   =        0xC00A,
+       TLS_ECDH_RSA_WITH_NULL_SHA             =        0xC00B,
+       TLS_ECDH_RSA_WITH_RC4_128_SHA          =        0xC00C,
+       TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA     =        0xC00D,
+       TLS_ECDH_RSA_WITH_AES_128_CBC_SHA      =        0xC00E,
+       TLS_ECDH_RSA_WITH_AES_256_CBC_SHA      =        0xC00F,
+       TLS_ECDHE_RSA_WITH_NULL_SHA            =        0xC010,
+       TLS_ECDHE_RSA_WITH_RC4_128_SHA         =        0xC011,
+       TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA    =        0xC012,
+       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA     =        0xC013,
+       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA     =        0xC014,
+       TLS_ECDH_anon_WITH_NULL_SHA            =        0xC015,
+       TLS_ECDH_anon_WITH_RC4_128_SHA         =        0xC016,
+       TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA    =        0xC017,
+       TLS_ECDH_anon_WITH_AES_128_CBC_SHA     =        0xC018,
+       TLS_ECDH_anon_WITH_AES_256_CBC_SHA     =        0xC019,
+
+    /* TLS 1.2 addenda, RFC 5246 */
+
+    /* Initial state. */
+    TLS_NULL_WITH_NULL_NULL                   = 0x0000,
+
+    /* Server provided RSA certificate for key exchange. */
+    TLS_RSA_WITH_NULL_MD5                     = 0x0001,
+    TLS_RSA_WITH_NULL_SHA                     = 0x0002,
+    TLS_RSA_WITH_RC4_128_MD5                  = 0x0004,
+    TLS_RSA_WITH_RC4_128_SHA                  = 0x0005,
+    TLS_RSA_WITH_3DES_EDE_CBC_SHA             = 0x000A,
+    //TLS_RSA_WITH_AES_128_CBC_SHA              = 0x002F,
+    //TLS_RSA_WITH_AES_256_CBC_SHA              = 0x0035,
+    TLS_RSA_WITH_NULL_SHA256                  = 0x003B,
+    TLS_RSA_WITH_AES_128_CBC_SHA256           = 0x003C,
+    TLS_RSA_WITH_AES_256_CBC_SHA256           = 0x003D,
+
+    /* Server-authenticated (and optionally client-authenticated) Diffie-Hellman. */
+    TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA          = 0x000D,
+    TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA          = 0x0010,
+    TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA         = 0x0013,
+    TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA         = 0x0016,
+    //TLS_DH_DSS_WITH_AES_128_CBC_SHA           = 0x0030,
+    //TLS_DH_RSA_WITH_AES_128_CBC_SHA           = 0x0031,
+    //TLS_DHE_DSS_WITH_AES_128_CBC_SHA          = 0x0032,
+    //TLS_DHE_RSA_WITH_AES_128_CBC_SHA          = 0x0033,
+    //TLS_DH_DSS_WITH_AES_256_CBC_SHA           = 0x0036,
+    //TLS_DH_RSA_WITH_AES_256_CBC_SHA           = 0x0037,
+    //TLS_DHE_DSS_WITH_AES_256_CBC_SHA          = 0x0038,
+    //TLS_DHE_RSA_WITH_AES_256_CBC_SHA          = 0x0039,
+    TLS_DH_DSS_WITH_AES_128_CBC_SHA256        = 0x003E,
+    TLS_DH_RSA_WITH_AES_128_CBC_SHA256        = 0x003F,
+    TLS_DHE_DSS_WITH_AES_128_CBC_SHA256       = 0x0040,
+    TLS_DHE_RSA_WITH_AES_128_CBC_SHA256       = 0x0067,
+    TLS_DH_DSS_WITH_AES_256_CBC_SHA256        = 0x0068,
+    TLS_DH_RSA_WITH_AES_256_CBC_SHA256        = 0x0069,
+    TLS_DHE_DSS_WITH_AES_256_CBC_SHA256       = 0x006A,
+    TLS_DHE_RSA_WITH_AES_256_CBC_SHA256       = 0x006B,
+
+    /* Completely anonymous Diffie-Hellman */
+    TLS_DH_anon_WITH_RC4_128_MD5              = 0x0018,
+    TLS_DH_anon_WITH_3DES_EDE_CBC_SHA         = 0x001B,
+    //TLS_DH_anon_WITH_AES_128_CBC_SHA          = 0x0034,
+    //TLS_DH_anon_WITH_AES_256_CBC_SHA          = 0x003A,
+    TLS_DH_anon_WITH_AES_128_CBC_SHA256       = 0x006C,
+    TLS_DH_anon_WITH_AES_256_CBC_SHA256       = 0x006D,
+
+    /* Addendum from RFC 4279, TLS PSK */
+
+    TLS_PSK_WITH_RC4_128_SHA                  = 0x008A,
+    TLS_PSK_WITH_3DES_EDE_CBC_SHA             = 0x008B,
+    TLS_PSK_WITH_AES_128_CBC_SHA              = 0x008C,
+    TLS_PSK_WITH_AES_256_CBC_SHA              = 0x008D,
+    TLS_DHE_PSK_WITH_RC4_128_SHA              = 0x008E,
+    TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA         = 0x008F,
+    TLS_DHE_PSK_WITH_AES_128_CBC_SHA          = 0x0090,
+    TLS_DHE_PSK_WITH_AES_256_CBC_SHA          = 0x0091,
+    TLS_RSA_PSK_WITH_RC4_128_SHA              = 0x0092,
+    TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA         = 0x0093,
+    TLS_RSA_PSK_WITH_AES_128_CBC_SHA          = 0x0094,
+    TLS_RSA_PSK_WITH_AES_256_CBC_SHA          = 0x0095,
+
+    /* RFC 4785 - Pre-Shared Key (PSK) Ciphersuites with NULL Encryption */
+
+    TLS_PSK_WITH_NULL_SHA                     = 0x002C,
+    TLS_DHE_PSK_WITH_NULL_SHA                 = 0x002D,
+    TLS_RSA_PSK_WITH_NULL_SHA                 = 0x002E,
+
+    /* Addenda from rfc 5288 AES Galois Counter Mode (GCM) Cipher Suites
+       for TLS. */
+    TLS_RSA_WITH_AES_128_GCM_SHA256           = 0x009C,
+    TLS_RSA_WITH_AES_256_GCM_SHA384           = 0x009D,
+    TLS_DHE_RSA_WITH_AES_128_GCM_SHA256       = 0x009E,
+    TLS_DHE_RSA_WITH_AES_256_GCM_SHA384       = 0x009F,
+    TLS_DH_RSA_WITH_AES_128_GCM_SHA256        = 0x00A0,
+    TLS_DH_RSA_WITH_AES_256_GCM_SHA384        = 0x00A1,
+    TLS_DHE_DSS_WITH_AES_128_GCM_SHA256       = 0x00A2,
+    TLS_DHE_DSS_WITH_AES_256_GCM_SHA384       = 0x00A3,
+    TLS_DH_DSS_WITH_AES_128_GCM_SHA256        = 0x00A4,
+    TLS_DH_DSS_WITH_AES_256_GCM_SHA384        = 0x00A5,
+    TLS_DH_anon_WITH_AES_128_GCM_SHA256       = 0x00A6,
+    TLS_DH_anon_WITH_AES_256_GCM_SHA384       = 0x00A7,
+
+    /* RFC 5487 - PSK with SHA-256/384 and AES GCM */
+    TLS_PSK_WITH_AES_128_GCM_SHA256           = 0x00A8,
+    TLS_PSK_WITH_AES_256_GCM_SHA384           = 0x00A9,
+    TLS_DHE_PSK_WITH_AES_128_GCM_SHA256       = 0x00AA,
+    TLS_DHE_PSK_WITH_AES_256_GCM_SHA384       = 0x00AB,
+    TLS_RSA_PSK_WITH_AES_128_GCM_SHA256       = 0x00AC,
+    TLS_RSA_PSK_WITH_AES_256_GCM_SHA384       = 0x00AD,
+
+    TLS_PSK_WITH_AES_128_CBC_SHA256           = 0x00AE,
+    TLS_PSK_WITH_AES_256_CBC_SHA384           = 0x00AF,
+    TLS_PSK_WITH_NULL_SHA256                  = 0x00B0,
+    TLS_PSK_WITH_NULL_SHA384                  = 0x00B1,
+
+    TLS_DHE_PSK_WITH_AES_128_CBC_SHA256       = 0x00B2,
+    TLS_DHE_PSK_WITH_AES_256_CBC_SHA384       = 0x00B3,
+    TLS_DHE_PSK_WITH_NULL_SHA256              = 0x00B4,
+    TLS_DHE_PSK_WITH_NULL_SHA384              = 0x00B5,
+
+    TLS_RSA_PSK_WITH_AES_128_CBC_SHA256       = 0x00B6,
+    TLS_RSA_PSK_WITH_AES_256_CBC_SHA384       = 0x00B7,
+    TLS_RSA_PSK_WITH_NULL_SHA256              = 0x00B8,
+    TLS_RSA_PSK_WITH_NULL_SHA384              = 0x00B9,
+
+
+    /* Addenda from rfc 5289  Elliptic Curve Cipher Suites with
+       HMAC SHA-256/384. */
+    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256   = 0xC023,
+    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384   = 0xC024,
+    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256    = 0xC025,
+    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384    = 0xC026,
+    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256     = 0xC027,
+    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384     = 0xC028,
+    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256      = 0xC029,
+    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384      = 0xC02A,
+
+    /* Addenda from rfc 5289  Elliptic Curve Cipher Suites with
+       SHA-256/384 and AES Galois Counter Mode (GCM) */
+    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256   = 0xC02B,
+    TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384   = 0xC02C,
+    TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256    = 0xC02D,
+    TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384    = 0xC02E,
+    TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256     = 0xC02F,
+    TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384     = 0xC030,
+    TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256      = 0xC031,
+    TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384      = 0xC032,
+
+    /* RFC 5746 - Secure Renegotiation */
+    TLS_EMPTY_RENEGOTIATION_INFO_SCSV         = 0x00FF,
+       /*
+        * Tags for SSL 2 cipher kinds which are not specified
+        * for SSL 3.
+        */
+    SSL_RSA_WITH_RC2_CBC_MD5 =                  0xFF80,
+    SSL_RSA_WITH_IDEA_CBC_MD5 =                 0xFF81,
+    SSL_RSA_WITH_DES_CBC_MD5 =                  0xFF82,
+    SSL_RSA_WITH_3DES_EDE_CBC_MD5 =             0xFF83,
+    SSL_NO_SUCH_CIPHERSUITE =                   0xFFFF
+};
+
+#endif /* !_SECURITY_CIPHERSUITE_H_ */
diff --git a/libsecurity_ssl/lib/SSLRecordInternal.c b/libsecurity_ssl/lib/SSLRecordInternal.c
new file mode 100644 (file)
index 0000000..ac07e44
--- /dev/null
@@ -0,0 +1,706 @@
+//
+//  SSLRecordInternal.c
+//  Security
+//
+//  Created by Fabrice Gautier on 10/25/11.
+//  Copyright (c) 2011 Apple, Inc. All rights reserved.
+//
+
+/* THIS FILE CONTAINS KERNEL CODE */
+
+#include "sslBuildFlags.h"
+#include "SSLRecordInternal.h"
+#include "sslDebug.h"
+#include "cipherSpecs.h"
+#include "symCipher.h"
+#include "sslUtils.h"
+#include "tls_record.h"
+
+#include <AssertMacros.h>
+#include <string.h>
+
+#include <inttypes.h>
+
+#define DEFAULT_BUFFER_SIZE 4096
+
+
+/*
+ * Redirect SSLBuffer-based I/O call to user-supplied I/O.
+ */
+static
+int sslIoRead(SSLBuffer                        buf,
+              size_t                           *actualLength,
+              struct SSLRecordInternalContext  *ctx)
+{
+       size_t  dataLength = buf.length;
+       int     ortn;
+
+       *actualLength = 0;
+       ortn = (ctx->read)(ctx->ioRef,
+                       buf.data,
+                       &dataLength);
+       *actualLength = dataLength;
+       return ortn;
+}
+
+static
+int sslIoWrite(SSLBuffer                       buf,
+               size_t                          *actualLength,
+               struct SSLRecordInternalContext *ctx)
+{
+       size_t  dataLength = buf.length;
+       int     ortn;
+
+       *actualLength = 0;
+       ortn = (ctx->write)(ctx->ioRef,
+                        buf.data,
+                        &dataLength);
+       *actualLength = dataLength;
+       return ortn;
+}
+
+
+static int
+SSLDisposeCipherSuite(CipherContext *cipher, struct SSLRecordInternalContext *ctx)
+{   int      err;
+
+       /* symmetric encryption context */
+       if(cipher->symCipher) {
+               if ((err = cipher->symCipher->finish(cipher->cipherCtx)) != 0) {
+                       return err;
+               }
+       }
+
+       /* per-record hash/hmac context */
+       ctx->sslTslCalls->freeMac(cipher);
+
+    return 0;
+}
+
+
+
+/* common for sslv3 and tlsv1, except for the computeMac callout */
+int SSLVerifyMac(uint8_t type,
+                 SSLBuffer *data,
+                 uint8_t *compareMAC,
+                 struct SSLRecordInternalContext *ctx)
+{
+       int        err;
+    uint8_t           macData[SSL_MAX_DIGEST_LEN];
+    SSLBuffer       secret, mac;
+
+    secret.data = ctx->readCipher.macSecret;
+    secret.length = ctx->readCipher.macRef->hash->digestSize;
+    mac.data = macData;
+    mac.length = ctx->readCipher.macRef->hash->digestSize;
+
+       check(ctx->sslTslCalls != NULL);
+    if ((err = ctx->sslTslCalls->computeMac(type,
+                                            *data,
+                                            mac,
+                                            &ctx->readCipher,
+                                            ctx->readCipher.sequenceNum,
+                                            ctx)) != 0)
+        return err;
+
+    if ((memcmp(mac.data, compareMAC, mac.length)) != 0) {
+               sslErrorLog("SSLVerifyMac: Mac verify failure\n");
+        return errSSLRecordProtocol;
+    }
+    return 0;
+}
+
+#include "cipherSpecs.h"
+#include "symCipher.h"
+
+static const HashHmacReference *sslCipherSuiteGetHashHmacReference(uint16_t selectedCipher)
+{
+    HMAC_Algs alg = sslCipherSuiteGetMacAlgorithm(selectedCipher);
+
+    switch (alg) {
+        case HA_Null:
+            return &HashHmacNull;
+        case HA_MD5:
+            return &HashHmacMD5;
+        case HA_SHA1:
+            return &HashHmacSHA1;
+        case HA_SHA256:
+            return &HashHmacSHA256;
+        case HA_SHA384:
+            return &HashHmacSHA384;
+        default:
+            sslErrorLog("Invalid hashAlgorithm %d", alg);
+            check(0);
+            return &HashHmacNull;
+    }
+}
+
+static const SSLSymmetricCipher *sslCipherSuiteGetSymmetricCipher(uint16_t selectedCipher)
+{
+
+    SSL_CipherAlgorithm alg = sslCipherSuiteGetSymmetricCipherAlgorithm(selectedCipher);
+    switch(alg) {
+        case SSL_CipherAlgorithmNull:
+            return &SSLCipherNull;
+#if ENABLE_RC2
+        case SSL_CipherAlgorithmRC2_128:
+            return &SSLCipherRC2_128;
+#endif
+#if ENABLE_RC4
+        case SSL_CipherAlgorithmRC4_128:
+            return &SSLCipherRC4_128;
+#endif
+#if ENABLE_DES
+        case SSL_CipherAlgorithmDES_CBC:
+            return &SSLCipherDES_CBC;
+#endif
+        case SSL_CipherAlgorithm3DES_CBC:
+            return &SSLCipher3DES_CBC;
+        case SSL_CipherAlgorithmAES_128_CBC:
+            return &SSLCipherAES_128_CBC;
+        case SSL_CipherAlgorithmAES_256_CBC:
+            return &SSLCipherAES_256_CBC;
+#if ENABLE_AES_GCM
+        case SSL_CipherAlgorithmAES_128_GCM:
+            return &SSLCipherAES_128_GCM;
+        case SSL_CipherAlgorithmAES_256_GCM:
+            return &SSLCipherAES_256_GCM;
+#endif
+        default:
+            check(0);
+            return &SSLCipherNull;
+    }
+}
+
+static void InitCipherSpec(struct SSLRecordInternalContext *ctx, uint16_t selectedCipher)
+{
+    SSLRecordCipherSpec *dst = &ctx->selectedCipherSpec;
+
+    ctx->selectedCipher = selectedCipher;
+    dst->cipher = sslCipherSuiteGetSymmetricCipher(selectedCipher);
+    dst->macAlgorithm = sslCipherSuiteGetHashHmacReference(selectedCipher);
+};
+
+/* Entry points to Record Layer */
+
+static int SSLRecordReadInternal(SSLRecordContextRef ref, SSLRecord *rec)
+{   int        err;
+    size_t          len, contentLen;
+    uint8_t           *charPtr;
+    SSLBuffer       readData, cipherFragment;
+    size_t          head=5;
+    int             skipit=0;
+    struct SSLRecordInternalContext *ctx = ref;
+
+    if(ctx->isDTLS)
+        head+=8;
+
+    if (!ctx->partialReadBuffer.data || ctx->partialReadBuffer.length < head)
+    {   if (ctx->partialReadBuffer.data)
+        if ((err = SSLFreeBuffer(&ctx->partialReadBuffer)) != 0)
+        {
+            return err;
+        }
+        if ((err = SSLAllocBuffer(&ctx->partialReadBuffer,
+                                  DEFAULT_BUFFER_SIZE)) != 0)
+        {
+            return err;
+        }
+    }
+
+    if (ctx->negProtocolVersion == SSL_Version_Undetermined) {
+        if (ctx->amountRead < 1)
+        {   readData.length = 1 - ctx->amountRead;
+            readData.data = ctx->partialReadBuffer.data + ctx->amountRead;
+            len = readData.length;
+            err = sslIoRead(readData, &len, ctx);
+            if(err != 0)
+            {   if (err == errSSLRecordWouldBlock) {
+                ctx->amountRead += len;
+                return err;
+            }
+            else {
+                /* abort */
+                err = errSSLRecordClosedAbort;
+#if 0 // TODO: revisit this in the transport layer
+                if((ctx->protocolSide == kSSLClientSide) &&
+                   (ctx->amountRead == 0) &&
+                   (len == 0)) {
+                    /*
+                     * Detect "server refused to even try to negotiate"
+                     * error, when the server drops the connection before
+                     * sending a single byte.
+                     */
+                    switch(ctx->state) {
+                        case SSL_HdskStateServerHello:
+                            sslHdskStateDebug("Server dropped initial connection\n");
+                            err = errSSLConnectionRefused;
+                            break;
+                        default:
+                            break;
+                    }
+                }
+#endif
+                return err;
+            }
+            }
+            ctx->amountRead += len;
+        }
+    }
+
+    if (ctx->amountRead < head)
+    {   readData.length = head - ctx->amountRead;
+        readData.data = ctx->partialReadBuffer.data + ctx->amountRead;
+        len = readData.length;
+        err = sslIoRead(readData, &len, ctx);
+        if(err != 0)
+        {
+                       switch(err) {
+                               case errSSLRecordWouldBlock:
+                                       ctx->amountRead += len;
+                                       break;
+#if    SSL_ALLOW_UNNOTICED_DISCONNECT
+                               case errSSLClosedGraceful:
+                                       /* 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 == SSL_HdskStateClientReady)) {  /* handshake done */
+                                           /*
+                                                * This means that the server has disconnected 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 errSSLClosedGraceful error. Paranoid
+                                                * clients can detect it and handle it however they
+                                                * want to.
+                                                */
+                                               SSLChangeHdskState(ctx, SSL_HdskStateNoNotifyClose);
+                                               err = errSSLClosedNoNotify;
+                                               break;
+                                       }
+                                       else {
+                                               /* illegal disconnect */
+                                               err = errSSLClosedAbort;
+                                               /* and drop thru to default: fatal alert */
+                                       }
+#endif /* SSL_ALLOW_UNNOTICED_DISCONNECT */
+                               default:
+                                       break;
+            }
+            return err;
+        }
+        ctx->amountRead += len;
+    }
+
+    check(ctx->amountRead >= head);
+
+    charPtr = ctx->partialReadBuffer.data;
+    rec->contentType = *charPtr++;
+    if (rec->contentType < SSL_RecordTypeV3_Smallest ||
+        rec->contentType > SSL_RecordTypeV3_Largest)
+        return errSSLRecordProtocol;
+
+    rec->protocolVersion = (SSLProtocolVersion)SSLDecodeInt(charPtr, 2);
+    charPtr += 2;
+
+    if(rec->protocolVersion == DTLS_Version_1_0)
+    {
+        sslUint64 seqNum;
+        SSLDecodeUInt64(charPtr, 8, &seqNum);
+        charPtr += 8;
+        sslLogRecordIo("Read DTLS Record %016llx (seq is: %016llx)",
+                       seqNum, ctx->readCipher.sequenceNum);
+
+        /* if the epoch of the record is different of current read cipher, just drop it */
+        if((seqNum>>48)!=(ctx->readCipher.sequenceNum>>48)) {
+            skipit=1;
+        } else {
+            ctx->readCipher.sequenceNum=seqNum;
+        }
+    }
+
+    contentLen = SSLDecodeInt(charPtr, 2);
+    charPtr += 2;
+    if (contentLen > (16384 + 2048))    /* Maximum legal length of an
+                                                                                * SSLCipherText payload */
+    {
+        return errSSLRecordRecordOverflow;
+    }
+
+    if (ctx->partialReadBuffer.length < head + contentLen)
+    {   if ((err = SSLReallocBuffer(&ctx->partialReadBuffer, head + contentLen)) != 0)
+    {
+        return err;
+    }
+    }
+
+    if (ctx->amountRead < head + contentLen)
+    {   readData.length = head + contentLen - ctx->amountRead;
+        readData.data = ctx->partialReadBuffer.data + ctx->amountRead;
+        len = readData.length;
+        err = sslIoRead(readData, &len, ctx);
+        if(err != 0)
+        {   if (err == errSSLRecordWouldBlock)
+            ctx->amountRead += len;
+            return err;
+        }
+        ctx->amountRead += len;
+    }
+
+    check(ctx->amountRead >= head + contentLen);
+
+    cipherFragment.data = ctx->partialReadBuffer.data + head;
+    cipherFragment.length = contentLen;
+
+    ctx->amountRead = 0;        /* We've used all the data in the cache */
+
+    /* We dont decrypt if we were told to skip this record */
+    if(skipit) {
+        return errSSLRecordUnexpectedRecord;
+    }
+       /*
+        * 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 */
+       check(ctx->sslTslCalls != NULL);
+    if ((err = ctx->sslTslCalls->decryptRecord(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)) != 0)
+    {
+        return err;
+    }
+    memcpy(rec->contents.data, cipherFragment.data, cipherFragment.length);
+
+
+    return 0;
+}
+
+static int SSLRecordWriteInternal(SSLRecordContextRef ref, SSLRecord rec)
+{
+    int err;
+    struct SSLRecordInternalContext *ctx = ref;
+
+    err=ctx->sslTslCalls->writeRecord(rec, ctx);
+
+    check_noerr(err);
+
+    return err;
+}
+
+/* Record Layer Entry Points */
+
+static int
+SSLRollbackInternalRecordLayerWriteCipher(SSLRecordContextRef ref)
+{
+    int err;
+    struct SSLRecordInternalContext *ctx = ref;
+
+    if ((err = SSLDisposeCipherSuite(&ctx->writePending, ctx)) != 0)
+        return err;
+
+    ctx->writePending = ctx->writeCipher;
+    ctx->writeCipher = ctx->prevCipher;
+
+    /* Zero out old data */
+    memset(&ctx->prevCipher, 0, sizeof(CipherContext));
+
+    return 0;
+}
+
+static int
+SSLAdvanceInternalRecordLayerWriteCipher(SSLRecordContextRef ref)
+{
+    int err;
+    struct SSLRecordInternalContext *ctx = ref;
+
+    if ((err = SSLDisposeCipherSuite(&ctx->prevCipher, ctx)) != 0)
+        return err;
+
+    ctx->prevCipher = ctx->writeCipher;
+    ctx->writeCipher = ctx->writePending;
+
+    /* Zero out old data */
+    memset(&ctx->writePending, 0, sizeof(CipherContext));
+
+    return 0;
+}
+
+static int
+SSLAdvanceInternalRecordLayerReadCipher(SSLRecordContextRef ref)
+{
+    struct SSLRecordInternalContext *ctx = ref;
+    int err;
+
+    if ((err = SSLDisposeCipherSuite(&ctx->readCipher, ctx)) != 0)
+        return err;
+
+    ctx->readCipher = ctx->readPending;
+    memset(&ctx->readPending, 0, sizeof(CipherContext));       /* Zero out old data */
+
+    return 0;
+}
+
+static int
+SSLInitInternalRecordLayerPendingCiphers(SSLRecordContextRef ref, uint16_t selectedCipher, bool isServer, SSLBuffer key)
+{   int        err;
+    uint8_t         *keyDataProgress, *keyPtr, *ivPtr;
+    CipherContext   *serverPending, *clientPending;
+
+    struct SSLRecordInternalContext *ctx = ref;
+
+    InitCipherSpec(ctx, selectedCipher);
+
+    ctx->readPending.macRef = ctx->selectedCipherSpec.macAlgorithm;
+    ctx->writePending.macRef = ctx->selectedCipherSpec.macAlgorithm;
+    ctx->readPending.symCipher = ctx->selectedCipherSpec.cipher;
+    ctx->writePending.symCipher = ctx->selectedCipherSpec.cipher;
+    /* This need to be reinitialized because the whole thing is zeroed sometimes */
+    ctx->readPending.encrypting = 0;
+    ctx->writePending.encrypting = 1;
+
+    if(ctx->negProtocolVersion == DTLS_Version_1_0)
+    {
+        ctx->readPending.sequenceNum = (ctx->readPending.sequenceNum & (0xffffULL<<48)) + (1ULL<<48);
+        ctx->writePending.sequenceNum = (ctx->writePending.sequenceNum & (0xffffULL<<48)) + (1ULL<<48);
+    } else {
+        ctx->writePending.sequenceNum = 0;
+        ctx->readPending.sequenceNum = 0;
+    }
+
+    if (isServer)
+    {   serverPending = &ctx->writePending;
+        clientPending = &ctx->readPending;
+    }
+    else
+    {   serverPending = &ctx->readPending;
+        clientPending = &ctx->writePending;
+    }
+
+    /* Check the size of the 'key' buffer - <rdar://problem/11204357> */
+    if(key.length != ctx->selectedCipherSpec.macAlgorithm->hash->digestSize*2
+                   + ctx->selectedCipherSpec.cipher->params->keySize*2
+                   + ctx->selectedCipherSpec.cipher->params->ivSize*2)
+    {
+        return errSSLRecordInternal;
+    }
+
+    keyDataProgress = key.data;
+    memcpy(clientPending->macSecret, keyDataProgress,
+           ctx->selectedCipherSpec.macAlgorithm->hash->digestSize);
+    keyDataProgress += ctx->selectedCipherSpec.macAlgorithm->hash->digestSize;
+    memcpy(serverPending->macSecret, keyDataProgress,
+           ctx->selectedCipherSpec.macAlgorithm->hash->digestSize);
+    keyDataProgress += ctx->selectedCipherSpec.macAlgorithm->hash->digestSize;
+
+    if (ctx->selectedCipherSpec.cipher->params->cipherType == aeadCipherType)
+        goto skipInit;
+
+    /* init the reusable-per-record MAC contexts */
+    err = ctx->sslTslCalls->initMac(clientPending);
+    if(err) {
+        goto fail;
+    }
+    err = ctx->sslTslCalls->initMac(serverPending);
+    if(err) {
+        goto fail;
+    }
+
+    keyPtr = keyDataProgress;
+    keyDataProgress += ctx->selectedCipherSpec.cipher->params->keySize;
+    /* Skip server write key to get to IV */
+    ivPtr = keyDataProgress + ctx->selectedCipherSpec.cipher->params->keySize;
+    if ((err = ctx->selectedCipherSpec.cipher->c.cipher.initialize(clientPending->symCipher->params, clientPending->encrypting, keyPtr, ivPtr,
+                                                                   &clientPending->cipherCtx)) != 0)
+        goto fail;
+    keyPtr = keyDataProgress;
+    keyDataProgress += ctx->selectedCipherSpec.cipher->params->keySize;
+    /* Skip client write IV to get to server write IV */
+    ivPtr = keyDataProgress + ctx->selectedCipherSpec.cipher->params->ivSize;
+    if ((err = ctx->selectedCipherSpec.cipher->c.cipher.initialize(serverPending->symCipher->params, serverPending->encrypting, keyPtr, ivPtr,
+                                                                   &serverPending->cipherCtx)) != 0)
+        goto fail;
+
+skipInit:
+    /* 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 = 0;
+
+fail:
+    return err;
+}
+
+static int
+SSLSetInternalRecordLayerProtocolVersion(SSLRecordContextRef ref, SSLProtocolVersion negVersion)
+{
+    struct SSLRecordInternalContext *ctx = ref;
+
+    switch(negVersion) {
+        case SSL_Version_3_0:
+            ctx->sslTslCalls = &Ssl3RecordCallouts;
+            break;
+        case TLS_Version_1_0:
+        case TLS_Version_1_1:
+        case DTLS_Version_1_0:
+        case TLS_Version_1_2:
+            ctx->sslTslCalls = &Tls1RecordCallouts;
+            break;
+        case SSL_Version_2_0:
+        case SSL_Version_Undetermined:
+        default:
+            return errSSLRecordNegotiation;
+    }
+    ctx->negProtocolVersion = negVersion;
+
+    return 0;
+}
+
+static int
+SSLRecordFreeInternal(SSLRecordContextRef ref, SSLRecord rec)
+{
+    return SSLFreeBuffer(&rec.contents);
+}
+
+static int
+SSLRecordServiceWriteQueueInternal(SSLRecordContextRef ref)
+{
+    int             err = 0, werr = 0;
+    size_t          written = 0;
+    SSLBuffer       buf;
+    WaitingRecord   *rec;
+    struct SSLRecordInternalContext *ctx= ref;
+
+    while (!werr && ((rec = ctx->recordWriteQueue) != 0))
+    {   buf.data = rec->data + rec->sent;
+        buf.length = rec->length - rec->sent;
+        werr = sslIoWrite(buf, &written, ctx);
+        rec->sent += written;
+        if (rec->sent >= rec->length)
+        {
+            check(rec->sent == rec->length);
+            check(err == 0);
+            ctx->recordWriteQueue = rec->next;
+                       sslFree(rec);
+        }
+        if (err) {
+            check_noerr(err);
+            return err;
+        }
+    }
+
+    return werr;
+}
+
+/***** Internal Record Layer APIs *****/
+
+SSLRecordContextRef
+SSLCreateInternalRecordLayer(bool dtls)
+{
+    struct SSLRecordInternalContext *ctx;
+
+    ctx = sslMalloc(sizeof(struct SSLRecordInternalContext));
+    if(ctx==NULL)
+        return NULL;
+
+    memset(ctx, 0, sizeof(struct SSLRecordInternalContext));
+
+    ctx->negProtocolVersion = SSL_Version_Undetermined;
+
+    ctx->sslTslCalls = &Ssl3RecordCallouts;
+    ctx->recordWriteQueue = NULL;
+
+    InitCipherSpec(ctx, TLS_NULL_WITH_NULL_NULL);
+
+    ctx->writeCipher.macRef    = ctx->selectedCipherSpec.macAlgorithm;
+    ctx->readCipher.macRef     = ctx->selectedCipherSpec.macAlgorithm;
+    ctx->readCipher.symCipher  = ctx->selectedCipherSpec.cipher;
+    ctx->writeCipher.symCipher = ctx->selectedCipherSpec.cipher;
+    ctx->readCipher.encrypting = 0;
+    ctx->writeCipher.encrypting = 1;
+
+    ctx->isDTLS = dtls;
+
+    return ctx;
+
+}
+
+int
+SSLSetInternalRecordLayerIOFuncs(
+                                 SSLRecordContextRef ref,
+                                 SSLIOReadFunc    readFunc,
+                                 SSLIOWriteFunc   writeFunc)
+{
+    struct SSLRecordInternalContext *ctx = ref;
+
+    ctx->read = readFunc;
+    ctx->write = writeFunc;
+
+    return 0;
+}
+
+int
+SSLSetInternalRecordLayerConnection(
+                                    SSLRecordContextRef ref,
+                                    SSLIOConnectionRef ioRef)
+{
+    struct SSLRecordInternalContext *ctx = ref;
+
+    ctx->ioRef = ioRef;
+
+    return 0;
+}
+
+void
+SSLDestroyInternalRecordLayer(SSLRecordContextRef ref)
+{
+    struct SSLRecordInternalContext *ctx = ref;
+       WaitingRecord   *waitRecord, *next;
+
+    /* RecordContext cleanup : */
+    SSLFreeBuffer(&ctx->partialReadBuffer);
+    waitRecord = ctx->recordWriteQueue;
+    while (waitRecord)
+    {   next = waitRecord->next;
+        sslFree(waitRecord);
+        waitRecord = next;
+    }
+
+
+    /* Cleanup cipher structs */
+    SSLDisposeCipherSuite(&ctx->readCipher, ctx);
+    SSLDisposeCipherSuite(&ctx->writeCipher, ctx);
+    SSLDisposeCipherSuite(&ctx->readPending, ctx);
+    SSLDisposeCipherSuite(&ctx->writePending, ctx);
+    SSLDisposeCipherSuite(&ctx->prevCipher, ctx);
+
+    sslFree(ctx);
+
+}
+
+struct SSLRecordFuncs SSLRecordLayerInternal =
+{
+    .read  = SSLRecordReadInternal,
+    .write = SSLRecordWriteInternal,
+    .initPendingCiphers = SSLInitInternalRecordLayerPendingCiphers,
+    .advanceWriteCipher = SSLAdvanceInternalRecordLayerWriteCipher,
+    .advanceReadCipher = SSLAdvanceInternalRecordLayerReadCipher,
+    .rollbackWriteCipher = SSLRollbackInternalRecordLayerWriteCipher,
+    .setProtocolVersion = SSLSetInternalRecordLayerProtocolVersion,
+    .free = SSLRecordFreeInternal,
+    .serviceWriteQueue = SSLRecordServiceWriteQueueInternal,
+};
+
diff --git a/libsecurity_ssl/lib/SSLRecordInternal.h b/libsecurity_ssl/lib/SSLRecordInternal.h
new file mode 100644 (file)
index 0000000..4e9082c
--- /dev/null
@@ -0,0 +1,57 @@
+//
+//  SSLRecordInternal.h
+//  Security
+//
+//  Created by Fabrice Gautier on 10/25/11.
+//  Copyright (c) 2011 Apple, Inc. All rights reserved.
+//
+
+
+/* This header should be kernel compatible */
+
+#ifndef _SSLRECORDINTERNAL_H_
+#define _SSLRECORDINTERNAL_H_ 1
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "sslTypes.h"
+
+typedef void *         SSLIOConnectionRef;
+
+typedef int
+(*SSLIOReadFunc)                       (SSLIOConnectionRef     connection,
+                                                        void                           *data,                  /* owned by
+                                                                                                                                * caller, data
+                                                                                                                                * RETURNED */
+                                                        size_t                         *dataLength);   /* IN/OUT */
+typedef int
+(*SSLIOWriteFunc)                      (SSLIOConnectionRef     connection,
+                                                        const void             *data,
+                                                        size_t                         *dataLength);   /* IN/OUT */
+
+
+/* Record layer creation functions, called from the SSLContext layer */
+
+SSLRecordContextRef
+SSLCreateInternalRecordLayer(bool dtls);
+
+int
+SSLSetInternalRecordLayerIOFuncs(
+    SSLRecordContextRef ctx,
+    SSLIOReadFunc       readFunc,
+    SSLIOWriteFunc      writeFunc);
+
+int
+SSLSetInternalRecordLayerConnection(
+    SSLRecordContextRef ctx,
+    SSLIOConnectionRef  ioRef);
+
+void
+SSLDestroyInternalRecordLayer(SSLRecordContextRef ctx);
+
+
+extern struct SSLRecordFuncs SSLRecordLayerInternal;
+
+#endif
diff --git a/libsecurity_ssl/lib/SecureTransport.h b/libsecurity_ssl/lib/SecureTransport.h
new file mode 100644 (file)
index 0000000..856d7f1
--- /dev/null
@@ -0,0 +1,1348 @@
+/*
+ * Copyright (c) 1999-2002,2005-2012 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * SecureTransport.h - Public API for Apple SSL/TLS Implementation
+ */
+
+#ifndef _SECURITY_SECURETRANSPORT_H_
+#define _SECURITY_SECURETRANSPORT_H_
+
+/*
+ * This file describes the public API for an implementation of the
+ * Secure Socket Layer, V. 3.0, Transport Layer Security, V. 1.0 to V. 1.2
+ * and Datagram Transport Layer Security V. 1.0
+ *
+ * There are 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 in the form of an SSLConnectionRef.
+ *
+ * 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. A SSLContextRef cannot
+ * be reused for multiple sessions.
+ */
+
+#include <CoreFoundation/CFArray.h>
+#include <Security/CipherSuite.h>
+#include <Security/SecTrust.h>
+#include <sys/types.h>
+#include <Availability.h>
+
+#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 connection (socket, endpoint, etc.) */
+typedef const void *           SSLConnectionRef;
+
+/* SSL Protocol version */
+typedef enum {
+       kSSLProtocolUnknown = 0,                /* no protocol negotiated/specified; use default */
+       kSSLProtocol3       = 2,                                /* SSL 3.0 */
+       kTLSProtocol1       = 4,                                /* TLS 1.0 */
+    kTLSProtocol11      = 7,                           /* TLS 1.1 */
+    kTLSProtocol12      = 8,                           /* TLS 1.2 */
+    kDTLSProtocol1      = 9,                /* DTLS 1.0 */
+
+    /* DEPRECATED on iOS */
+    kSSLProtocol2       = 1,                           /* SSL 2.0 */
+    kSSLProtocol3Only   = 3,                /* SSL 3.0 Only */
+    kTLSProtocol1Only   = 5,                /* TLS 1.0 Only */
+    kSSLProtocolAll     = 6,                /* All TLS supported protocols */
+
+} SSLProtocol;
+
+/* SSL session options */
+typedef enum {
+       /*
+        * Set this option to enable returning from SSLHandshake (with a result of
+        * errSSLServerAuthCompleted) when the server authentication portion of the
+        * handshake is complete. This disable certificate verification and
+        * provides an opportunity to perform application-specific server
+        * verification before deciding to continue.
+        */
+       kSSLSessionOptionBreakOnServerAuth,
+       /*
+        * Set this option to enable returning from SSLHandshake (with a result of
+        * errSSLClientCertRequested) when the server requests a client certificate.
+        */
+       kSSLSessionOptionBreakOnCertRequested,
+    /*
+     * This option is the same as kSSLSessionOptionBreakOnServerAuth but applies
+     * to the case where SecureTransport is the server and the client has presented
+     * its certificates allowing the server to verify whether these should be
+     * allowed to authenticate.
+     */
+    kSSLSessionOptionBreakOnClientAuth,
+    /*
+     * Enable/Disable TLS False Start
+     * When enabled, False Start will only be performed if a adequate cipher-suite is
+     * negotiated.
+     */
+    kSSLSessionOptionFalseStart,
+    /*
+     * Enable/Disable 1/n-1 record splitting for BEAST attack mitigation.
+     * When enabled, record splitting will only be performed for TLS 1.0 connections
+     * using a block cipher.
+     */
+    kSSLSessionOptionSendOneByteRecord,
+
+} SSLSessionOption;
+
+/* 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;
+
+/*
+ * Status of client certificate exchange (which is optional
+ * for both server and client).
+ */
+typedef enum {
+       /* Server hasn't asked for a cert. Client hasn't sent one. */
+       kSSLClientCertNone,
+       /* Server has asked for a cert, but client didn't send it. */
+       kSSLClientCertRequested,
+       /*
+        * Server side: We asked for a cert, client sent one, we validated
+        *                              it OK. App can inspect the cert via
+        *                              SSLGetPeerCertificates().
+        * Client side: server asked for one, we sent it.
+        */
+       kSSLClientCertSent,
+       /*
+        * Client sent a cert but failed validation. Server side only.
+        * Server app can inspect the cert via SSLGetPeerCertificates().
+        */
+       kSSLClientCertRejected
+} SSLClientCertificateState;
+
+/*
+ * 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 errSSLWouldBlock, 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 */
+                                                        size_t                         *dataLength);   /* IN/OUT */
+typedef OSStatus
+(*SSLWriteFunc)                        (SSLConnectionRef       connection,
+                                                        const void             *data,
+                                                        size_t                         *dataLength);   /* IN/OUT */
+
+
+/*************************************************
+ *** OSStatus values unique to SecureTransport ***
+ *************************************************/
+
+/*
+    Note: the comments that appear after these errors are used to create SecErrorMessages.strings.
+    The comments must not be multi-line, and should be in a form meaningful to an end user. If
+    a different or additional comment is needed, it can be put in the header doc format, or on a
+    line that does not start with errZZZ.
+*/
+
+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 */
+
+       /* fatal errors detected by peer */
+       errSSLPeerUnexpectedMsg         = -9819,        /* unexpected message received */
+       errSSLPeerBadRecordMac          = -9820,        /* bad MAC */
+       errSSLPeerDecryptionFail        = -9821,        /* decryption failed */
+       errSSLPeerRecordOverflow        = -9822,        /* record overflow */
+       errSSLPeerDecompressFail        = -9823,        /* decompression failure */
+       errSSLPeerHandshakeFail         = -9824,        /* handshake failure */
+       errSSLPeerBadCert                       = -9825,        /* misc. bad certificate */
+       errSSLPeerUnsupportedCert       = -9826,        /* bad unsupported cert format */
+       errSSLPeerCertRevoked           = -9827,        /* certificate revoked */
+       errSSLPeerCertExpired           = -9828,        /* certificate expired */
+       errSSLPeerCertUnknown           = -9829,        /* unknown certificate */
+       errSSLIllegalParam                      = -9830,        /* illegal parameter */
+       errSSLPeerUnknownCA             = -9831,        /* unknown Cert Authority */
+       errSSLPeerAccessDenied          = -9832,        /* access denied */
+       errSSLPeerDecodeError           = -9833,        /* decoding error */
+       errSSLPeerDecryptError          = -9834,        /* decryption error */
+       errSSLPeerExportRestriction     = -9835,        /* export restriction */
+       errSSLPeerProtocolVersion       = -9836,        /* bad protocol version */
+       errSSLPeerInsufficientSecurity = -9837, /* insufficient security */
+       errSSLPeerInternalError         = -9838,        /* internal error */
+       errSSLPeerUserCancelled         = -9839,        /* user canceled */
+       errSSLPeerNoRenegotiation       = -9840,        /* no renegotiation allowed */
+
+       /* non-fatal result codes */
+       errSSLPeerAuthCompleted     = -9841,    /* peer cert is valid, or was ignored if verification disabled */
+       errSSLClientCertRequested       = -9842,        /* server has requested a client cert */
+
+       /* more errors detected by us */
+       errSSLHostNameMismatch          = -9843,        /* peer host name mismatch */
+       errSSLConnectionRefused         = -9844,        /* peer dropped connection before responding */
+       errSSLDecryptionFail            = -9845,        /* decryption failure */
+       errSSLBadRecordMac                      = -9846,        /* bad MAC */
+       errSSLRecordOverflow            = -9847,        /* record overflow */
+       errSSLBadConfiguration          = -9848,        /* configuration error */
+       errSSLUnexpectedRecord      = -9849,    /* unexpected (skipped) record in DTLS */
+};
+
+/* DEPRECATED aliases for errSSLPeerAuthCompleted */
+#define errSSLServerAuthCompleted      errSSLPeerAuthCompleted
+#define errSSLClientAuthCompleted      errSSLPeerAuthCompleted
+
+/* DEPRECATED alias for the end of the error range */
+#define errSSLLast errSSLUnexpectedRecord
+
+typedef enum
+{
+    kSSLServerSide,
+    kSSLClientSide
+} SSLProtocolSide;
+
+typedef enum
+{
+    kSSLStreamType,
+    kSSLDatagramType
+} SSLConnectionType;
+
+/******************
+ *** Public API ***
+ ******************/
+
+/*
+ * Secure Transport APIs require a SSLContextRef, which is an opaque
+ * reference to the SSL session and its parameters. On Mac OS X 10.7
+ * and earlier versions, a new context is created using SSLNewContext,
+ * and is disposed by calling SSLDisposeContext.
+ *
+ * On i0S 5.0 and later, as well as Mac OS X versions after 10.7, the
+ * SSLContextRef is a true CFType object with retain-release semantics.
+ * New code should create a new context using SSLCreateContext (instead
+ * of SSLNewContext), and dispose the context by calling CFRelease
+ * (instead of SSLDisposeContext) when finished with it.
+ */
+
+/*
+ * Return the CFTypeID for SSLContext objects.
+ */
+CFTypeID
+SSLContextGetTypeID(void)
+       __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0);
+
+/*
+ * Create a new instance of an SSLContextRef using the specified allocator.
+ */
+SSLContextRef
+SSLCreateContext(CFAllocatorRef alloc, SSLProtocolSide protocolSide, SSLConnectionType connectionType)
+       __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0);
+
+
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+/*
+ * Create a new session context.
+ *
+ * ==========================
+ * MAC OS X ONLY (DEPRECATED)
+ * ==========================
+ * NOTE: this function is not available on iOS, and should be considered
+ * deprecated on Mac OS X. Your code should use SSLCreateContext instead.
+ */
+OSStatus
+SSLNewContext                          (Boolean                        isServer,
+                                                        SSLContextRef          *contextPtr)    /* RETURNED */
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_NA,__IPHONE_NA);
+
+/*
+ * Dispose of a session context.
+ *
+ * ==========================
+ * MAC OS X ONLY (DEPRECATED)
+ * ==========================
+ * NOTE: this function is not available on iOS, and should be considered
+ * deprecated on Mac OS X. Your code should use CFRelease to dispose a session
+ * created with SSLCreateContext.
+ */
+OSStatus
+SSLDisposeContext                      (SSLContextRef          context)
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_NA,__IPHONE_NA);
+
+#endif /* MAC OS X */
+
+/*
+ * Determine the state of an SSL/DTLS session.
+ */
+OSStatus
+SSLGetSessionState                     (SSLContextRef          context,
+                                                        SSLSessionState        *state)         /* RETURNED */
+       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
+
+/*
+ * Set options for an SSL session. Must be called prior to SSLHandshake();
+ * subsequently cannot be called while session is active.
+ */
+OSStatus
+SSLSetSessionOption                    (SSLContextRef          context,
+                                                        SSLSessionOption       option,
+                                                        Boolean                        value)
+       __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_5_0);
+
+/*
+ * Determine current value for the specified option in a given SSL session.
+ */
+OSStatus
+SSLGetSessionOption                    (SSLContextRef          context,
+                                                        SSLSessionOption       option,
+                                                        Boolean                        *value)
+       __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_5_0);
+
+/********************************************************************
+ *** Session context configuration, common to client and servers. ***
+ ********************************************************************/
+
+/*
+ * Specify functions which do the network I/O. Must be called prior
+ * to SSLHandshake(); subsequently cannot be called while a session is
+ * active.
+ */
+OSStatus
+SSLSetIOFuncs                          (SSLContextRef          context,
+                                                        SSLReadFunc            readFunc,
+                                                        SSLWriteFunc           writeFunc)
+       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
+
+/*
+ * Set the minimum SSL protocol version allowed. Optional.
+ * The default is the lower supported protocol.
+ *
+ * This can only be called when no session is active.
+ *
+ * For TLS contexts, legal values for minVersion are :
+ *             kSSLProtocol3
+ *             kTLSProtocol1
+ *             kTLSProtocol11
+ *             kTLSProtocol12
+ *
+ * For DTLS contexts, legal values for minVersion are :
+ *      kDTLSProtocol1
+ */
+OSStatus
+SSLSetProtocolVersionMin  (SSLContextRef      context,
+                           SSLProtocol        minVersion)
+    __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0);
+
+/*
+ * Get minimum protocol version allowed
+ */
+OSStatus
+SSLGetProtocolVersionMin  (SSLContextRef      context,
+                           SSLProtocol        *minVersion)
+    __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0);
+
+/*
+ * Set the maximum SSL protocol version allowed. Optional.
+ * The default is the highest supported protocol.
+ *
+ * This can only be called when no session is active.
+ *
+ * For TLS contexts, legal values for minVersion are :
+ *             kSSLProtocol3
+ *             kTLSProtocol1
+ *             kTLSProtocol11
+ *             kTLSProtocol12
+ *
+ * For DTLS contexts, legal values for minVersion are :
+ *      kDTLSProtocol1
+ */
+OSStatus
+SSLSetProtocolVersionMax  (SSLContextRef      context,
+                           SSLProtocol        maxVersion)
+    __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0);
+
+/*
+ * Get maximum protocol version allowed
+ */
+OSStatus
+SSLGetProtocolVersionMax  (SSLContextRef      context,
+                           SSLProtocol        *maxVersion)
+    __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0);
+
+
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+/*
+ * Set allowed SSL protocol versions. Optional.
+ * Specifying kSSLProtocolAll for SSLSetProtocolVersionEnabled results in
+ * specified 'enable' boolean to be applied to all supported protocols.
+ * The default is "all supported protocols are enabled".
+ * This can only be called when no session is active.
+ *
+ * Legal values for protocol are :
+ *             kSSLProtocol2
+ *             kSSLProtocol3
+ *             kTLSProtocol1
+ *             kSSLProtocolAll
+ *
+ * ==========================
+ * MAC OS X ONLY (DEPRECATED)
+ * ==========================
+ * NOTE: this function is not available on iOS, and should be considered
+ * deprecated on Mac OS X. You can use SSLSetProtocolVersionMin and/or
+ * SSLSetProtocolVersionMax to specify which protocols are enabled.
+ */
+OSStatus
+SSLSetProtocolVersionEnabled (SSLContextRef    context,
+                                                        SSLProtocol            protocol,
+                                                        Boolean                        enable)
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_NA,__IPHONE_NA);
+
+/*
+ * Obtain a value specified in SSLSetProtocolVersionEnabled.
+ *
+ * ==========================
+ * MAC OS X ONLY (DEPRECATED)
+ * ==========================
+ * NOTE: this function is not available on iOS, and should be considered
+ * deprecated on Mac OS X. You can use SSLGetProtocolVersionMin and/or
+ * SSLGetProtocolVersionMax to check whether a protocol is enabled.
+ */
+OSStatus
+SSLGetProtocolVersionEnabled(SSLContextRef             context,
+                                                        SSLProtocol            protocol,
+                                                        Boolean                        *enable)        /* RETURNED */
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_NA,__IPHONE_NA);
+
+/*
+ * Get/set SSL protocol version; optional. Default is kSSLProtocolUnknown,
+ * in which case the highest possible version is attempted, but a lower
+ * version is accepted if the peer requires it.
+ * SSLSetProtocolVersion cannot be called when a session is active.
+ *
+ * ==========================
+ * MAC OS X ONLY (DEPRECATED)
+ * ==========================
+ * NOTE: this function is not available on iOS, and deprecated on Mac OS X 10.8.
+ * Use SSLSetProtocolVersionMin and/or SSLSetProtocolVersionMax to specify
+ * which protocols are enabled.
+ */
+OSStatus
+SSLSetProtocolVersion          (SSLContextRef          context,
+                                                        SSLProtocol            version)
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_8,__IPHONE_NA,__IPHONE_NA);
+
+/*
+ * Obtain the protocol version specified in SSLSetProtocolVersion.
+ * If SSLSetProtocolVersionEnabled() has been called for this session,
+ * SSLGetProtocolVersion() may return errSecParam if the protocol enable
+ * state can not be represented by the SSLProtocol enums (e.g.,
+ * SSL2 and TLS1 enabled, SSL3 disabled).
+ *
+ * ==========================
+ * MAC OS X ONLY (DEPRECATED)
+ * ==========================
+ * NOTE: this function is not available on iOS, and deprecated on Mac OS X 10.8.
+ * Use SSLGetProtocolVersionMin and/or SSLGetProtocolVersionMax to check
+ * whether a protocol is enabled.
+ */
+OSStatus
+SSLGetProtocolVersion          (SSLContextRef          context,
+                                                        SSLProtocol            *protocol)      /* RETURNED */
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_8,__IPHONE_NA,__IPHONE_NA);
+
+#endif /* MAC OS X */
+
+/*
+ * 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 certRefs[0]. Specifying a root cert is optional; if it's
+ * not specified, the root cert which verifies the cert chain specified
+ * here must be present in the system-wide set of trusted anchor certs.
+ *
+ * The certRefs argument is a CFArray containing SecCertificateRefs,
+ * except for certRefs[0], which is a SecIdentityRef.
+ *
+ * Must be called prior to SSLHandshake(), or immediately after
+ * SSLHandshake has returned errSSLClientCertRequested (i.e. before the
+ * handshake is resumed by calling SSLHandshake again.)
+ *
+ * SecureTransport assumes the following:
+ *
+ *  -- The certRef references remain valid for the lifetime of the session.
+ *  -- The certificate specified in certRefs[0] is capable of signing.
+ *  -- The required capabilities of the certRef[0], and of the optional cert
+ *     specified in SSLSetEncryptionCertificate (see below), are highly
+ *     dependent on the application. For example, to work as a server with
+ *     Netscape clients, the cert specified here must be capable of both
+ *     signing and encrypting.
+ */
+OSStatus
+SSLSetCertificate                      (SSLContextRef          context,
+                                                        CFArrayRef                     certRefs)
+       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
+
+/*
+ * 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)
+       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
+
+OSStatus
+SSLGetConnection                       (SSLContextRef          context,
+                                                        SSLConnectionRef       *connection)
+       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
+
+/*
+ * Specify the fully qualified doman name of the peer, e.g., "store.apple.com."
+ * Optional; used to verify the common name field in peer's certificate.
+ * Name is in the form of a C string; NULL termination optional, i.e.,
+ * peerName[peerNameLen+1] may or may not have a NULL. In any case peerNameLen
+ * is the number of bytes of the peer domain name.
+ */
+OSStatus
+SSLSetPeerDomainName           (SSLContextRef          context,
+                                                        const char                     *peerName,
+                                                        size_t                         peerNameLen)
+       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
+
+/*
+ * Determine the buffer size needed for SSLGetPeerDomainName().
+ */
+OSStatus
+SSLGetPeerDomainNameLength     (SSLContextRef          context,
+                                                        size_t                         *peerNameLen)   // RETURNED
+       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
+
+/*
+ * Obtain the value specified in SSLSetPeerDomainName().
+ */
+OSStatus
+SSLGetPeerDomainName           (SSLContextRef          context,
+                                                        char                           *peerName,              // returned here
+                                                        size_t                         *peerNameLen)   // IN/OUT
+       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
+
+/*
+ * Specify the Datagram TLS Hello Cookie.
+ * This is to be called for server side only and is optional.
+ * The default is a zero len cookie. The maximum cookieLen is 32 bytes.
+ */
+OSStatus
+SSLSetDatagramHelloCookie      (SSLContextRef          dtlsContext,
+                             const void         *cookie,
+                             size_t             cookieLen)
+       __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0);
+
+/*
+ * Specify the maximum record size, including all DTLS record headers.
+ * This should be set appropriately to avoid fragmentation
+ * of Datagrams during handshake, as fragmented datagrams may
+ * be dropped by some network.
+ * This is for Datagram TLS only
+ */
+OSStatus
+SSLSetMaxDatagramRecordSize (SSLContextRef             dtlsContext,
+                             size_t             maxSize)
+       __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0);
+
+/*
+ * Get the maximum record size, including all Datagram TLS record headers.
+ * This is for Datagram TLS only
+ */
+OSStatus
+SSLGetMaxDatagramRecordSize (SSLContextRef             dtlsContext,
+                             size_t             *maxSize)
+       __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0);
+
+/*
+ * 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 */
+       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
+
+/*
+ * 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,
+                                                         size_t                                *numCiphers)
+       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
+
+OSStatus
+SSLGetSupportedCiphers          (SSLContextRef                 context,
+                                                         SSLCipherSuite                *ciphers,               /* RETURNED */
+                                                         size_t                                *numCiphers)    /* IN/OUT */
+       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
+
+/*
+ * Specify a (typically) 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,
+                                                        size_t                                 numCiphers)
+       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
+
+/*
+ * 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,
+                                                        size_t                                 *numCiphers)
+       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
+
+OSStatus
+SSLGetEnabledCiphers           (SSLContextRef                  context,
+                                                        SSLCipherSuite                 *ciphers,               /* RETURNED */
+                                                        size_t                                 *numCiphers)    /* IN/OUT */
+       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
+
+
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+/*
+ * Enable/disable peer certificate chain validation. Default is enabled.
+ * If caller disables, it is the caller's responsibility to call
+ * SSLCopyPeerCertificates() upon successful completion of the handshake
+ * and then to perform external validation of the peer certificate
+ * chain before proceeding with data transfer.
+ *
+ * ==========================
+ * MAC OS X ONLY (DEPRECATED)
+ * ==========================
+ * NOTE: this function is not available on iOS, and should be considered
+ * deprecated on Mac OS X. To disable peer certificate chain validation, you
+ * can instead use SSLSetSessionOption to set kSSLSessionOptionBreakOnServerAuth
+ * to true. This will disable verification and cause SSLHandshake to return with
+ * an errSSLServerAuthCompleted result when the peer certificates have been
+ * received; at that time, you can choose to evaluate peer trust yourself, or
+ * simply call SSLHandshake again to proceed with the handshake.
+ */
+OSStatus
+SSLSetEnableCertVerify         (SSLContextRef                  context,
+                                                        Boolean                                enableVerify)
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_NA,__IPHONE_NA);
+
+/*
+ * Check whether peer certificate chain validation is enabled.
+ *
+ * ==========================
+ * MAC OS X ONLY (DEPRECATED)
+ * ==========================
+ * NOTE: this function is not available on iOS, and should be considered
+ * deprecated on Mac OS X. To check whether peer certificate chain validation
+ * is enabled in a context, call SSLGetSessionOption to obtain the value of
+ * the kSSLSessionOptionBreakOnServerAuth session option flag. If the value
+ * of this option flag is true, then verification is disabled.
+ */
+OSStatus
+SSLGetEnableCertVerify         (SSLContextRef                  context,
+                                                        Boolean                                *enableVerify)  /* RETURNED */
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_NA,__IPHONE_NA);
+
+/*
+ * Specify the option of ignoring certificates' "expired" times.
+ * This is a common failure in the real SSL world. Default setting for this
+ * flag is false, meaning expired certs result in an errSSLCertExpired error.
+ *
+ * ==========================
+ * MAC OS X ONLY (DEPRECATED)
+ * ==========================
+ * NOTE: this function is not available on iOS, and should be considered
+ * deprecated on Mac OS X. To ignore expired certificate errors, first disable
+ * Secure Transport's automatic verification of peer certificates by calling
+ * SSLSetSessionOption to set kSSLSessionOptionBreakOnServerAuth to true. When
+ * SSLHandshake subsequently returns an errSSLServerAuthCompleted result,
+ * your code should obtain the SecTrustRef for the peer's certificates and
+ * perform a custom trust evaluation with SecTrust APIs (see SecTrust.h).
+ * The SecTrustSetOptions function allows you to specify that the expiration
+ * status of certificates should be ignored for this evaluation.
+ *
+ * Example:
+ *
+ *     status = SSLSetSessionOption(ctx, kSSLSessionOptionBreakOnServerAuth, true);
+ *     do {
+ *             status = SSLHandshake(ctx);
+ *
+ *             if (status == errSSLServerAuthCompleted) {
+ *                     SecTrustRef peerTrust = NULL;
+ *                     status = SSLCopyPeerTrust(ctx, &peerTrust);
+ *                     if (status == errSecSuccess) {
+ *                             SecTrustResultType trustResult;
+ *                             // set flag to allow expired certificates
+ *                             SecTrustSetOptions(peerTrust, kSecTrustOptionAllowExpired);
+ *                             status = SecTrustEvaluate(peerTrust, &trustResult);
+ *                             if (status == errSecSuccess) {
+ *                                     // A "proceed" result means the cert is explicitly trusted,
+ *                                     // e.g. "Always Trust" was clicked;
+ *                                     // "Unspecified" means the cert has no explicit trust settings,
+ *                                     // but is implicitly OK since it chains back to a trusted root.
+ *                                     // Any other result means the cert is not trusted.
+ *                                     //
+ *                                     if (trustResult == kSecTrustResultProceed ||
+ *                                             trustResult == kSecTrustResultUnspecified) {
+ *                                             // certificate is trusted
+ *                                             status = errSSLWouldBlock; // so we call SSLHandshake again
+ *                                     } else if (trustResult == kSecTrustResultRecoverableTrustFailure) {
+ *                                             // not trusted, for some reason other than being expired;
+ *                                             // could ask the user whether to allow the connection here
+ *                                             //
+ *                                             status = errSSLXCertChainInvalid;
+ *                                     } else {
+ *                                             // cannot use this certificate (fatal)
+ *                                             status = errSSLBadCert;
+ *                                     }
+ *                             }
+ *                             if (peerTrust) {
+ *                                     CFRelease(peerTrust);
+ *                             }
+ *                     }
+ *             } // errSSLServerAuthCompleted
+ *
+ *     } while (status == errSSLWouldBlock);
+ *
+ */
+OSStatus
+SSLSetAllowsExpiredCerts       (SSLContextRef          context,
+                                                        Boolean                        allowsExpired)
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_NA,__IPHONE_NA);
+
+/*
+ * Obtain the current value of an SSLContext's "allowExpiredCerts" flag.
+ *
+ * ==========================
+ * MAC OS X ONLY (DEPRECATED)
+ * ==========================
+ * NOTE: this function is not available on iOS, and should be considered
+ * deprecated on Mac OS X.
+ */
+OSStatus
+SSLGetAllowsExpiredCerts       (SSLContextRef          context,
+                                                        Boolean                        *allowsExpired) /* RETURNED */
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_NA,__IPHONE_NA);
+
+/*
+ * Similar to SSLSetAllowsExpiredCerts, SSLSetAllowsExpiredRoots allows the
+ * option of ignoring "expired" status for root certificates only.
+ * Default setting is false, i.e., expired root certs result in an
+ * errSSLCertExpired error.
+ *
+ * ==========================
+ * MAC OS X ONLY (DEPRECATED)
+ * ==========================
+ * NOTE: this function is not available on iOS, and should be considered
+ * deprecated on Mac OS X. To ignore expired certificate errors, first disable
+ * Secure Transport's automatic verification of peer certificates by calling
+ * SSLSetSessionOption to set kSSLSessionOptionBreakOnServerAuth to true. When
+ * SSLHandshake subsequently returns an errSSLServerAuthCompleted result,
+ * your code should obtain the SecTrustRef for the peer's certificates and
+ * perform a custom trust evaluation with SecTrust APIs (see SecTrust.h).
+ * The SecTrustSetOptions function allows you to specify that the expiration
+ * status of certificates should be ignored for this evaluation.
+ *
+ * See the description of the SSLSetAllowsExpiredCerts function (above)
+ * for a code example. The kSecTrustOptionAllowExpiredRoot option can be used
+ * instead of kSecTrustOptionAllowExpired to allow expired roots only.
+ */
+OSStatus
+SSLSetAllowsExpiredRoots       (SSLContextRef          context,
+                                                        Boolean                        allowsExpired)
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_NA,__IPHONE_NA);
+
+/*
+ * Obtain the current value of an SSLContext's "allow expired roots" flag.
+ *
+ * ==========================
+ * MAC OS X ONLY (DEPRECATED)
+ * ==========================
+ * NOTE: this function is not available on iOS, and should be considered
+ * deprecated on Mac OS X.
+ */
+OSStatus
+SSLGetAllowsExpiredRoots       (SSLContextRef          context,
+                                                        Boolean                        *allowsExpired) /* RETURNED */
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_NA,__IPHONE_NA);
+
+/*
+ * 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.
+ *
+ * ==========================
+ * MAC OS X ONLY (DEPRECATED)
+ * ==========================
+ * NOTE: this function is not available on iOS, and should be considered
+ * deprecated on Mac OS X. To ignore unknown root cert errors, first disable
+ * Secure Transport's automatic verification of peer certificates by calling
+ * SSLSetSessionOption to set kSSLSessionOptionBreakOnServerAuth to true. When
+ * SSLHandshake subsequently returns an errSSLServerAuthCompleted result,
+ * your code should obtain the SecTrustRef for the peer's certificates and
+ * perform a custom trust evaluation with SecTrust APIs (see SecTrust.h).
+ *
+ * See the description of the SSLSetAllowsExpiredCerts function (above)
+ * for a code example. Note that an unknown root certificate will cause
+ * SecTrustEvaluate to report kSecTrustResultRecoverableTrustFailure as the
+ * trust result.
+ */
+OSStatus
+SSLSetAllowsAnyRoot                    (SSLContextRef          context,
+                                                        Boolean                        anyRoot)
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_NA,__IPHONE_NA);
+
+/*
+ * Obtain the current value of an SSLContext's "allow any root" flag.
+ *
+ * ==========================
+ * MAC OS X ONLY (DEPRECATED)
+ * ==========================
+ * NOTE: this function is not available on iOS, and should be considered
+ * deprecated on Mac OS X.
+ */
+OSStatus
+SSLGetAllowsAnyRoot                    (SSLContextRef          context,
+                                                        Boolean                        *anyRoot) /* RETURNED */
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_NA,__IPHONE_NA);
+
+/*
+ * Augment or replace the system's default trusted root certificate set
+ * for this session. If replaceExisting is true, the specified roots will
+ * be the only roots which are trusted during this session. If replaceExisting
+ * is false, the specified roots will be added to the current set of trusted
+ * root certs. If this function has never been called, the current trusted
+ * root set is the same as the system's default trusted root set.
+ * Successive calls with replaceExisting false result in accumulation
+ * of additional root certs.
+ *
+ * The trustedRoots array contains SecCertificateRefs.
+ *
+ * ==========================
+ * MAC OS X ONLY (DEPRECATED)
+ * ==========================
+ * NOTE: this function is not available on iOS, and should be considered
+ * deprecated on Mac OS X. To trust specific roots in a session, first disable
+ * Secure Transport's automatic verification of peer certificates by calling
+ * SSLSetSessionOption to set kSSLSessionOptionBreakOnServerAuth to true. When
+ * SSLHandshake subsequently returns an errSSLServerAuthCompleted result,
+ * your code should obtain the SecTrustRef for the peer's certificates and
+ * perform a custom trust evaluation with SecTrust APIs (see SecTrust.h).
+ *
+ * See the description of the SSLSetAllowsExpiredCerts function (above)
+ * for a code example. You can call SecTrustSetAnchorCertificates to
+ * augment the system's trusted root set, or SecTrustSetAnchorCertificatesOnly
+ * to make these the only trusted roots, prior to calling SecTrustEvaluate.
+ */
+OSStatus
+SSLSetTrustedRoots                     (SSLContextRef          context,
+                                                        CFArrayRef             trustedRoots,
+                                                        Boolean                        replaceExisting)
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_NA,__IPHONE_NA);
+
+/*
+ * Obtain an array of SecCertificateRefs representing the current
+ * set of trusted roots. If SSLSetTrustedRoots() has never been called
+ * for this session, this returns the system's default root set.
+ *
+ * Caller must CFRelease the returned CFArray.
+ *
+ * ==========================
+ * MAC OS X ONLY (DEPRECATED)
+ * ==========================
+ * NOTE: this function is not available on iOS, and should be considered
+ * deprecated on Mac OS X. To get the current set of trusted roots, call the
+ * SSLCopyPeerTrust function to obtain the SecTrustRef for the peer certificate
+ * chain, then SecTrustCopyCustomAnchorCertificates (see SecTrust.h).
+ */
+OSStatus
+SSLCopyTrustedRoots                    (SSLContextRef          context,
+                                                        CFArrayRef             *trustedRoots)  /* RETURNED */
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5,__MAC_10_9,__IPHONE_NA,__IPHONE_NA);
+
+/*
+ * Request peer certificates. Valid anytime, subsequent to a handshake attempt.
+ *
+ * The certs argument is a CFArray containing SecCertificateRefs.
+ * Caller must CFRelease the returned array.
+ *
+ * The cert at index 0 of the returned array is the subject (end
+ * entity) cert; the root cert (or the closest cert to it) is at
+ * the end of the returned array.
+ *
+ * ==========================
+ * MAC OS X ONLY (DEPRECATED)
+ * ==========================
+ * NOTE: this function is not available on iOS, and should be considered
+ * deprecated on Mac OS X. To get peer certificates, call SSLCopyPeerTrust
+ * to obtain the SecTrustRef for the peer certificate chain, then use the
+ * SecTrustGetCertificateCount and SecTrustGetCertificateAtIndex functions
+ * to retrieve individual certificates in the chain (see SecTrust.h).
+ */
+OSStatus
+SSLCopyPeerCertificates                (SSLContextRef          context,
+                                                        CFArrayRef                     *certs)         /* RETURNED */
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5,__MAC_10_9,__IPHONE_NA,__IPHONE_NA);
+
+#endif /* MAC OS X */
+
+/*
+ * Obtain a SecTrustRef representing peer certificates. Valid anytime,
+ * subsequent to a handshake attempt. Caller must CFRelease the returned
+ * trust reference.
+ *
+ * The returned trust reference will have already been evaluated for you,
+ * unless one of the following is true:
+ * - Your code has disabled automatic certificate verification, by calling
+ *   SSLSetSessionOption to set kSSLSessionOptionBreakOnServerAuth to true.
+ * - Your code has called SSLSetPeerID, and this session has been resumed
+ *   from an earlier cached session.
+ *
+ * In these cases, your code should call SecTrustEvaluate prior to
+ * examining the peer certificate chain or trust results (see SecTrust.h).
+ *
+ * NOTE: if you have not called SSLHandshake at least once prior to
+ * calling this function, the returned trust reference will be NULL.
+ */
+OSStatus
+SSLCopyPeerTrust                       (SSLContextRef          context,
+                                                        SecTrustRef            *trust)         /* RETURNED */
+       __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_5_0);
+
+/*
+ * 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.
+ *
+ * SecureTransport allocates its own copy of the incoming peerID. The
+ * data provided in *peerID, while opaque to SecureTransport, is used
+ * in a byte-for-byte compare to other previous peerID values set by the
+ * current application. Matching peerID blobs result in SecureTransport
+ * attempting to resume an SSL session with the same parameters as used
+ * in the previous session which specified the same peerID bytes.
+ */
+OSStatus
+SSLSetPeerID                           (SSLContextRef          context,
+                                                        const void             *peerID,
+                                                        size_t                         peerIDLen)
+       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
+
+/*
+ * Obtain current PeerID. Returns NULL pointer, zero length if
+ * SSLSetPeerID has not been called for this context.
+ */
+OSStatus
+SSLGetPeerID                           (SSLContextRef          context,
+                                                        const void             **peerID,
+                                                        size_t                         *peerIDLen)
+       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
+
+/*
+ * 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)
+       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
+
+
+/********************************************************
+ *** Session context configuration, server side only. ***
+ ********************************************************/
+
+/*
+ * 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.
+ *
+ *  -- 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.
+ *
+ * The certRefs argument is a CFArray containing SecCertificateRefs,
+ * except for certRefs[0], which is a SecIdentityRef.
+ *
+ * The following assumptions are made:
+ *
+ *  -- The certRefs references remains valid for the lifetime of the
+ *     connection.
+ *  -- The specified certRefs[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 RSA keys 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 SSLSetEnabledCiphers() call.
+ */
+OSStatus
+SSLSetEncryptionCertificate    (SSLContextRef          context,
+                                                        CFArrayRef                     certRefs)
+       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
+
+/*
+ * Specify requirements for client-side authentication.
+ * Optional; Default is kNeverAuthenticate.
+ *
+ * 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)
+       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
+
+/*
+ * Add a DER-encoded distinguished name to list of acceptable names
+ * to be specified in requests for client certificates.
+ */
+OSStatus
+SSLAddDistinguishedName                (SSLContextRef          context,
+                                                        const void             *derDN,
+                                                        size_t                         derDNLen)
+       __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_5_0);
+
+
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+/*
+ * Add a SecCertificateRef, or a CFArray of them, to a server's list
+ * of acceptable Certificate Authorities (CAs) to present to the client
+ * when client authentication is performed.
+ *
+ * If replaceExisting is true, the specified certificate(s) will replace
+ * a possible existing list of acceptable CAs. If replaceExisting is
+ * false, the specified certificate(s) will be appended to the existing
+ * list of acceptable CAs, if any.
+ *
+ * Returns errSecParam if this is called on a SSLContextRef which
+ * is configured as a client, or when a session is active.
+ *
+ * NOTE: this function is currently not available on iOS.
+ */
+OSStatus
+SSLSetCertificateAuthorities(SSLContextRef             context,
+                                                        CFTypeRef                      certificateOrArray,
+                                                        Boolean                        replaceExisting)
+       __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
+
+/*
+ * Obtain the certificates specified in SSLSetCertificateAuthorities(),
+ * if any. Returns a NULL array if SSLSetCertificateAuthorities() has not
+ * been called.
+ * Caller must CFRelease the returned array.
+ *
+ * NOTE: this function is currently not available on iOS.
+ */
+OSStatus
+SSLCopyCertificateAuthorities(SSLContextRef            context,
+                                                         CFArrayRef            *certificates)  /* RETURNED */
+       __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
+
+#endif /* MAC OS X */
+
+/*
+ * Obtain the list of acceptable distinguished names as provided by
+ * a server (if the SSLContextRef is configured as a client), or as
+ * specified by SSLSetCertificateAuthorities (if the SSLContextRef
+ * is configured as a server).
+ * The returned array contains CFDataRefs, each of which represents
+ * one DER-encoded RDN.
+ *
+ * Caller must CFRelease the returned array.
+ */
+OSStatus
+SSLCopyDistinguishedNames      (SSLContextRef          context,
+                                                        CFArrayRef                     *names)
+       __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_5_0);
+
+/*
+ * Obtain client certificate exchange status. Can be called
+ * any time. Reflects the *last* client certificate state change;
+ * subsequent to a renegotiation attempt by either peer, the state
+ * is reset to kSSLClientCertNone.
+ */
+OSStatus
+SSLGetClientCertificateState   (SSLContextRef                          context,
+                                                                SSLClientCertificateState      *clientState)
+       __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_5_0);
+
+
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+/*
+ * Specify Diffie-Hellman parameters. Optional; if we are configured to allow
+ * for D-H ciphers and a D-H cipher is negotiated, and this function has not
+ * been called, a set of process-wide parameters will be calculated. However
+ * that can take a long time (30 seconds).
+ *
+ * NOTE: this function is currently not available on iOS.
+ */
+OSStatus SSLSetDiffieHellmanParams     (SSLContextRef                  context,
+                                                                        const void                     *dhParams,
+                                                                        size_t                                 dhParamsLen)
+       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_NA);
+
+/*
+ * Return parameter block specified in SSLSetDiffieHellmanParams.
+ * Returned data is not copied and belongs to the SSLContextRef.
+ *
+ * NOTE: this function is currently not available on iOS.
+ */
+OSStatus SSLGetDiffieHellmanParams     (SSLContextRef                  context,
+                                                                        const void                     **dhParams,
+                                                                        size_t                                 *dhParamsLen)
+       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_NA);
+
+/*
+ * Enable/Disable RSA blinding. This feature thwarts a known timing
+ * attack to which RSA keys are vulnerable; enabling it is a tradeoff
+ * between performance and security. The default for RSA blinding is
+ * enabled.
+ *
+ * ==========================
+ * MAC OS X ONLY (DEPRECATED)
+ * ==========================
+ * NOTE: this function is not available on iOS, and should be considered
+ * deprecated on Mac OS X. RSA blinding is enabled unconditionally, as
+ * it prevents a known way for an attacker to recover the private key,
+ * and the performance gain of disabling it is negligible.
+ */
+OSStatus SSLSetRsaBlinding                     (SSLContextRef                  context,
+                                                                        Boolean                                blinding)
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_NA,__IPHONE_NA);
+
+OSStatus SSLGetRsaBlinding                     (SSLContextRef                  context,
+                                                                        Boolean                                *blinding)
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_NA,__IPHONE_NA);
+
+#endif /* MAC OS X */
+
+/*******************************
+ ******** I/O Functions ********
+ *******************************/
+
+/*
+ * Note: depending on the configuration of the underlying I/O
+ * connection, all SSL I/O functions can return errSSLWouldBlock,
+ * 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 did not end in a root.
+ *
+ *  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; the peer's
+ *  cert chain is available via SSLCopyPeerTrust or SSLCopyPeerCertificates.
+ *
+ *  Other interesting result codes:
+ *
+ *  errSSLPeerAuthCompleted: Peer's cert chain is valid, or was ignored if
+ *      cert verification was disabled via SSLSetEnableCertVerify. The application
+ *      may decide to continue with the handshake (by calling SSLHandshake
+ *      again), or close the connection at this point.
+ *
+ *  errSSLClientCertRequested: The server has requested a client certificate.
+ *      The client may choose to examine the server's certificate and
+ *      distinguished name list, then optionally call SSLSetCertificate prior
+ *      to resuming the handshake by calling SSLHandshake again.
+ *
+ * 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)
+       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
+
+/*
+ * 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,
+                                                        size_t                         dataLength,
+                                                        size_t                         *processed)             /* RETURNED */
+       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
+
+/*
+ * 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 */
+                                                        size_t                         dataLength,
+                                                        size_t                         *processed)             /* RETURNED */
+       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
+
+/*
+ * Determine how much data the client can be guaranteed to
+ * obtain via SSLRead() without blocking or causing any low-level
+ * read operations to occur.
+ */
+OSStatus
+SSLGetBufferedReadSize         (SSLContextRef context,
+                                                        size_t *bufSize)                                       /* RETURNED */
+       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
+
+/*
+ * Determine how much data the application can be guaranteed to write
+ * with SSLWrite() without causing fragmentation. The value is based on
+ * the maximum Datagram Record size defined by the application with
+ * SSLSetMaxDatagramRecordSize(), minus the DTLS Record header size.
+ */
+OSStatus
+SSLGetDatagramWriteSize                (SSLContextRef dtlsContext,
+                                                        size_t *bufSize)
+       __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0);
+
+/*
+ * Terminate current SSL session.
+ */
+OSStatus
+SSLClose                                       (SSLContextRef          context)
+       __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_SECURITY_SECURETRANSPORT_H_ */
diff --git a/libsecurity_ssl/lib/SecureTransportPriv.h b/libsecurity_ssl/lib/SecureTransportPriv.h
new file mode 100644 (file)
index 0000000..01035af
--- /dev/null
@@ -0,0 +1,758 @@
+/*
+ * Copyright (c) 1999-2001,2005-2012 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * SecureTransportPriv.h - Apple-private exported routines
+ */
+
+#ifndef        _SECURE_TRANSPORT_PRIV_H_
+#define _SECURE_TRANSPORT_PRIV_H_      1
+
+#include <Security/SecureTransport.h>
+#include <Security/SecTrust.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "sslTypes.h"
+
+/* Create an SSL Context with an external record layer - eg: kernel accelerated layer */
+SSLContextRef
+SSLCreateContextWithRecordFuncs(CFAllocatorRef alloc,
+                                SSLProtocolSide protocolSide,
+                                SSLConnectionType connectionType,
+                                const struct SSLRecordFuncs *recFuncs);
+
+/* Set the external record layer context */
+OSStatus
+SSLSetRecordContext         (SSLContextRef          ctx,
+                             SSLRecordContextRef    recCtx);
+
+/* The size of of client- and server-generated random numbers in hello messages. */
+#define SSL_CLIENT_SRVR_RAND_SIZE              32
+
+/* The size of the pre-master and master secrets. */
+#define SSL_RSA_PREMASTER_SECRET_SIZE  48
+#define SSL_MASTER_SECRET_SIZE                 48
+
+/*
+ * For the following three functions, *size is the available
+ * buffer size on entry and the actual size of the data returned
+ * on return. The above consts are for convenience.
+ */
+OSStatus SSLInternalMasterSecret(
+   SSLContextRef context,
+   void *secret,         // mallocd by caller, SSL_MASTER_SECRET_SIZE
+   size_t *secretSize);  // in/out
+
+OSStatus SSLInternalServerRandom(
+   SSLContextRef context,
+   void *randBuf,                      // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
+   size_t *randSize);  // in/out
+
+OSStatus SSLInternalClientRandom(
+   SSLContextRef context,
+   void *randBuf,              // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
+   size_t *randSize);  // in/out
+
+/*
+ * Obtain the sizes of the currently negotiated HMAC digest, session
+ * key, and session key IV.
+ */
+OSStatus SSLGetCipherSizes(
+       SSLContextRef context,
+       size_t *digestSize,
+       size_t *symmetricKeySize,
+       size_t *ivSize);
+
+OSStatus SSLInternal_PRF(
+   SSLContextRef context,
+   const void *secret,
+   size_t secretLen,
+   const void *label,
+   size_t labelLen,
+   const void *seed,
+   size_t seedLen,
+   void *out,                  // mallocd by caller, length >= outLen
+   size_t outLen);
+
+/*
+ * Obtain a SecTrustRef representing peer certificates. Valid anytime,
+ * subsequent to a handshake attempt. The returned SecTrustRef is valid
+ * only as long as the SSLContextRef is.
+ */
+OSStatus
+SSLGetPeerSecTrust                     (SSLContextRef          context,
+                                                        SecTrustRef            *secTrust);     /* RETURNED */
+
+/*
+ * Obtain resumable session info. Can be called anytime subsequent to
+ * handshake attempt.
+ *
+ * if sessionWasResumed is True on return, the session is indeed a
+ * resumed session; the sessionID (an opaque blob generated by the
+ * server) is returned in *sessionID. The length of the sessionID
+ * is returned in *sessionIDLength. Caller must allocate the
+ * sessionID buffer; it max size is MAX_SESSION_ID_LENGTH bytes.
+ */
+#define MAX_SESSION_ID_LENGTH  32
+
+OSStatus
+SSLGetResumableSessionInfo     (
+       SSLContextRef   context,
+       Boolean                 *sessionWasResumed,             // RETURNED
+       void                    *sessionID,                             // RETURNED, mallocd by caller
+       size_t                  *sessionIDLength);              // IN/OUT
+
+/*
+ * Getters for SSLSetCertificate() and SSLSetEncryptionCertificate()
+ */
+OSStatus
+SSLGetCertificate (
+       SSLContextRef   context,
+       CFArrayRef              *certRefs);                             // RETURNED, *not* retained
+
+OSStatus
+SSLGetEncryptionCertificate (
+       SSLContextRef   context,
+       CFArrayRef              *certRefs);                             // RETURNED, *not* retained
+
+/*
+ * Getter for SSLSetClientSideAuthenticate()
+ */
+OSStatus
+SSLGetClientSideAuthenticate (
+       SSLContextRef   context,
+       SSLAuthenticate *auth);                                 // RETURNED
+
+/*
+ * Get/set array of trusted leaf certificates.
+ *
+ * If none have been set previously with SSLSetTrustedLeafCertificates(),
+ * then SSLCopyTrustedLeafCertificates() will return NULL with errSecSuccess.
+ */
+OSStatus
+SSLSetTrustedLeafCertificates (
+       SSLContextRef   context,
+       CFArrayRef              certRefs);
+
+OSStatus
+SSLCopyTrustedLeafCertificates (
+       SSLContextRef   context,
+       CFArrayRef              *certRefs);                             // RETURNED, caller must release
+
+/*
+ * Get/set enable of anonymous ciphers. Default is enabled.
+ *
+ * SSLSetAllowAnonymousCiphers() returns errSecBadReq if SSLSetEnabledCiphers()
+ * has already been called.
+ *
+ * The enable state set by SSLSetAllowAnonymousCiphers() is ignored if
+ * SSLSetEnabledCiphers() is called after SSLSetAllowAnonymousCiphers() is
+ * called, i.e., SSLSetEnabledCiphers() overrides SSLSetAllowAnonymousCiphers().
+ *
+ * NOTE: "Anonymous" ciphers include those ciphers that perform no encryption,
+ * as well as ciphers that perform no authentication, since neither are secure.
+ */
+OSStatus
+SSLSetAllowAnonymousCiphers(
+       SSLContextRef   context,
+       Boolean                 enable);
+
+OSStatus
+SSLGetAllowAnonymousCiphers(
+       SSLContextRef   context,
+       Boolean                 *enable);
+
+/*
+ * Override the default session cache timeout for a cache entry created for
+ * the current session.
+ */
+OSStatus
+SSLSetSessionCacheTimeout(
+       SSLContextRef context,
+       uint32_t timeoutInSeconds);
+
+/*
+ * Callback function for EAP-style PAC-based session resumption.
+ * This function is called by SecureTransport to obtain the
+ * master secret.
+ */
+typedef void (*SSLInternalMasterSecretFunction)(
+       SSLContextRef ctx,
+       const void *arg,                /* opaque to SecureTransport; app-specific */
+       void *secret,                   /* mallocd by caller, SSL_MASTER_SECRET_SIZE */
+       size_t *secretLength);  /* in/out */
+
+/*
+ * Register a callback for obtaining the master_secret when performing
+ * PAC-based session resumption. At the time the callback is called,
+ * the following are guaranteed to be valid:
+ *
+ *  -- serverRandom (via SSLInternalServerRandom())
+ *  -- clientRandom (via SSLInternalClientRandom())
+ *  -- negotiated protocol version (via SSLGetNegotiatedProtocolVersion())
+ *  -- negotiated CipherSuite (via SSLGetNegotiatedCipher())
+ *
+ * Currently, PAC-based session resumption is only implemented on
+ * the client side for Deployment builds.
+ *
+ * On the client side, this callback occurs if/when the server sends a
+ * ChangeCipherSpec message immediately following its ServerHello
+ * message (i.e., it's skipped the entire Key Exchange phase of
+ * negotiation).
+ *
+ * On the server side (Development builds only) this callback occurs
+ * immediately upon receipt of the Client Hello message, before we send
+ * the Server Hello.
+ */
+OSStatus
+SSLInternalSetMasterSecretFunction(
+       SSLContextRef ctx,
+       SSLInternalMasterSecretFunction mFunc,
+       const void *arg);               /* opaque to SecureTransport; app-specific */
+
+/*
+ * Provide an opaque SessionTicket for use in PAC-based session
+ * resumption. Client side only. The provided ticket is sent in
+ * the ClientHello message as a SessionTicket extension.
+ * The maximum ticketLength is 2**16-1.
+ */
+OSStatus SSLInternalSetSessionTicket(
+   SSLContextRef ctx,
+   const void *ticket,
+   size_t ticketLength);
+
+/*
+ * Support for specifying and obtaining ECC curves, used with the ECDH-based
+ * ciphersuites.
+ */
+
+/*
+ * These are the named curves from RFC 4492
+ * section 5.1.1, with the exception of SSL_Curve_None which means
+ * "ECDSA not negotiated".
+ */
+typedef enum
+{
+       SSL_Curve_None = -1,
+
+    SSL_Curve_sect163k1 = 1,
+    SSL_Curve_sect163r1 = 2,
+    SSL_Curve_sect163r2 = 3,
+    SSL_Curve_sect193r1 = 4,
+    SSL_Curve_sect193r2 = 5,
+    SSL_Curve_sect233k1 = 6,
+    SSL_Curve_sect233r1 = 7,
+    SSL_Curve_sect239k1 = 8,
+    SSL_Curve_sect283k1 = 9,
+    SSL_Curve_sect283r1 = 10,
+    SSL_Curve_sect409k1 = 11,
+    SSL_Curve_sect409r1 = 12,
+    SSL_Curve_sect571k1 = 13,
+    SSL_Curve_sect571r1 = 14,
+    SSL_Curve_secp160k1 = 15,
+    SSL_Curve_secp160r1 = 16,
+    SSL_Curve_secp160r2 = 17,
+    SSL_Curve_secp192k1 = 18,
+    SSL_Curve_secp192r1 = 19,
+    SSL_Curve_secp224k1 = 20,
+    SSL_Curve_secp224r1 = 21,
+    SSL_Curve_secp256k1 = 22,
+
+    /* These are the ones we actually support */
+       SSL_Curve_secp256r1 = 23,
+       SSL_Curve_secp384r1 = 24,
+       SSL_Curve_secp521r1 = 25
+} SSL_ECDSA_NamedCurve;
+
+/*
+ * Obtain the SSL_ECDSA_NamedCurve negotiated during a handshake.
+ * Returns errSecParam if no ECDH-related ciphersuite was negotiated.
+ */
+extern OSStatus SSLGetNegotiatedCurve(
+   SSLContextRef ctx,
+   SSL_ECDSA_NamedCurve *namedCurve);    /* RETURNED */
+
+/*
+ * Obtain the number of currently enabled SSL_ECDSA_NamedCurves.
+ */
+extern OSStatus SSLGetNumberOfECDSACurves(
+   SSLContextRef ctx,
+   unsigned *numCurves);                               /* RETURNED */
+
+/*
+ * Obtain the ordered list of currently enabled SSL_ECDSA_NamedCurves.
+ * Caller allocates returned array and specifies its size (in
+ * SSL_ECDSA_NamedCurves) in *numCurves on entry; *numCurves
+ * is the actual size of the returned array on successful return.
+ */
+extern OSStatus SSLGetECDSACurves(
+   SSLContextRef ctx,
+   SSL_ECDSA_NamedCurve *namedCurves,  /* RETURNED */
+   unsigned *numCurves);                               /* IN/OUT */
+
+/*
+ * Specify ordered list of allowable named curves.
+ */
+extern OSStatus SSLSetECDSACurves(
+   SSLContextRef ctx,
+   const SSL_ECDSA_NamedCurve *namedCurves,
+   unsigned numCurves);
+
+/*
+ * Server-specified client authentication mechanisms.
+ */
+typedef enum {
+       /* doesn't appear on the wire */
+       SSLClientAuthNone = -1,
+       /* RFC 2246 7.4.6 */
+       SSLClientAuth_RSASign = 1,
+       SSLClientAuth_DSSSign = 2,
+       SSLClientAuth_RSAFixedDH = 3,
+       SSLClientAuth_DSS_FixedDH = 4,
+       /* RFC 4492 5.5 */
+       SSLClientAuth_ECDSASign = 64,
+       SSLClientAuth_RSAFixedECDH = 65,
+       SSLClientAuth_ECDSAFixedECDH = 66
+} SSLClientAuthenticationType;
+
+/* TLS 1.2 Signature Algorithms extension values for hash field. */
+typedef enum {
+    SSL_HashAlgorithmNone = 0,
+    SSL_HashAlgorithmMD5 = 1,
+    SSL_HashAlgorithmSHA1 = 2,
+    SSL_HashAlgorithmSHA224 = 3,
+    SSL_HashAlgorithmSHA256 = 4,
+    SSL_HashAlgorithmSHA384 = 5,
+    SSL_HashAlgorithmSHA512 = 6
+} SSL_HashAlgorithm;
+
+/* TLS 1.2 Signature Algorithms extension values for signature field. */
+typedef enum {
+    SSL_SignatureAlgorithmAnonymous = 0,
+    SSL_SignatureAlgorithmRSA = 1,
+    SSL_SignatureAlgorithmDSA = 2,
+    SSL_SignatureAlgorithmECDSA = 3
+} SSL_SignatureAlgorithm;
+
+typedef struct {
+    SSL_HashAlgorithm hash;
+    SSL_SignatureAlgorithm signature;
+} SSLSignatureAndHashAlgorithm;
+
+/*
+ * Obtain the number of client authentication mechanisms specified by
+ * the server in its Certificate Request message.
+ * Returns errSecParam if server hasn't sent a Certificate Request message
+ * (i.e., client certificate state is kSSLClientCertNone).
+ */
+extern OSStatus SSLGetNumberOfClientAuthTypes(
+       SSLContextRef ctx,
+       unsigned *numTypes);
+
+/*
+ * Obtain the client authentication mechanisms specified by
+ * the server in its Certificate Request message.
+ * Caller allocates returned array and specifies its size (in
+ * SSLClientAuthenticationTypes) in *numType on entry; *numTypes
+ * is the actual size of the returned array on successful return.
+ */
+extern OSStatus SSLGetClientAuthTypes(
+   SSLContextRef ctx,
+   SSLClientAuthenticationType *authTypes,             /* RETURNED */
+   unsigned *numTypes);                                                        /* IN/OUT */
+
+/*
+ * Obtain the SSLClientAuthenticationType actually performed.
+ * Only valid if client certificate state is kSSLClientCertSent
+ * or kSSLClientCertRejected; SSLClientAuthNone is returned as
+ * the negotiated auth type otherwise.
+ */
+extern OSStatus SSLGetNegotiatedClientAuthType(
+   SSLContextRef ctx,
+   SSLClientAuthenticationType *authType);             /* RETURNED */
+
+/*
+ * Obtain the number of supported_signature_algorithms specified by
+ * the server in its Certificate Request message.
+ * Returns errSecParam if server hasn't sent a Certificate Request message
+ * (i.e., client certificate state is kSSLClientCertNone).
+ */
+extern OSStatus SSLGetNumberOfSignatureAlgorithms(
+    SSLContextRef ctx,
+    unsigned *numSigAlgs);
+
+/*
+ * Obtain the supported_signature_algorithms specified by
+ * the server in its Certificate Request message.
+ * Caller allocates returned array and specifies its size (in
+ * SSLClientAuthenticationTypes) in *numType on entry; *numTypes
+ * is the actual size of the returned array on successful return.
+ */
+extern OSStatus SSLGetSignatureAlgorithms(
+    SSLContextRef ctx,
+    SSLSignatureAndHashAlgorithm *sigAlgs,             /* RETURNED */
+    unsigned *numSigAlgs);                                                     /* IN/OUT */
+
+/* PSK SPIs */
+
+/* Set the Shared Secret for PSK CipherSuite.
+   This need to be set before the handshake starts. */
+OSStatus SSLSetPSKSharedSecret(SSLContextRef ctx,
+                               const void *secret,
+                               size_t secretLen);
+
+/* Set the Client identity for PSK CipherSuite.
+   This need to be set before the handshake starts.
+   Only useful for client side.*/
+OSStatus SSLSetPSKIdentity(SSLContextRef ctx,
+                           const void *pskIdentity,
+                           size_t pskIdentityLen);
+
+/* For client side, get the identity previously set by SSLSetPSKIdentity.
+   For server side, get the identity provided by the client during the handshake.
+   Might be NULL if not set. identity is owned by the SSLContext and is invalid once
+   the SSLContext is released.
+ */
+OSStatus SSLGetPSKIdentity(SSLContextRef ctx,
+                           const void **pskIdentity,
+                           size_t *pskIdentityLen);
+    
+#if TARGET_OS_IPHONE
+
+/* Following are SPIs on iOS */
+
+/*
+ * Set allowed SSL protocol versions. Optional.
+ * Specifying kSSLProtocolAll for SSLSetProtocolVersionEnabled results in
+ * specified 'enable' boolean to be applied to all supported protocols.
+ * The default is "all supported protocols are enabled".
+ * This can only be called when no session is active.
+ *
+ * Legal values for protocol are :
+ *             kSSLProtocol2
+ *             kSSLProtocol3
+ *             kTLSProtocol1
+ *             kSSLProtocolAll
+ *
+ * This is deprecated in favor of SSLSetProtocolVersionMax/SSLSetProtocolVersionMin
+ */
+OSStatus
+_SSLSetProtocolVersionEnabled (SSLContextRef   context,
+                              SSLProtocol              protocol,
+                               Boolean                 enable);
+
+/*
+ * Obtain a value specified in SSLSetProtocolVersionEnabled.
+ *
+ * This is deprecated in favor of SSLGetProtocolVersionMax/SSLGetProtocolVersionMin
+ */
+OSStatus
+_SSLGetProtocolVersionEnabled(SSLContextRef            context,
+                             SSLProtocol               protocol,
+                              Boolean                  *enable);               /* RETURNED */
+
+/*
+ * Get/set SSL protocol version; optional. Default is kSSLProtocolUnknown,
+ * in which case the highest possible version (currently kTLSProtocol1)
+ * is attempted, but a lower version is accepted if the peer requires it.
+ *
+ * SSLSetProtocolVersion can not be called when a session is active.
+ *
+ * This is deprecated in favor of SSLSetProtocolVersionEnabled.
+ *
+ * This is deprecated in favor of SSLSetProtocolVersionMax/SSLSetProtocolVersionMin
+ */
+OSStatus
+_SSLSetProtocolVersion         (SSLContextRef          context,
+                             SSLProtocol               version);
+
+/*
+ * Obtain the protocol version specified in SSLSetProtocolVersion.
+ * This is deprecated in favor of SSLGetProtocolVersionEnabled.
+ * If SSLSetProtocolVersionEnabled() has been called for this session,
+ * SSLGetProtocolVersion() may return errSecParam if the protocol enable
+ * state can not be represented by the SSLProtocol enums (e.g.,
+ * SSL2 and TLS1 enabled, SSL3 disabled).
+ *
+ * This is deprecated in favor of SSLGetProtocolVersionMax/SSLGetProtocolVersionMin
+ */
+OSStatus
+_SSLGetProtocolVersion         (SSLContextRef          context,
+                             SSLProtocol               *protocol);             /* RETURNED */
+
+/* API REVIEW:
+ The following 15 calls were used to change the behaviour of the trust
+ evaluation of the certificate chain.
+ The proper alternative is to break out of the handshake, get the
+ peer's SecTrustRef with SSLCopyPeerTrust and evaluate that.
+ */
+
+/*
+ * Enable/disable peer certificate chain validation. Default is enabled.
+ * If caller disables, it is the caller's responsibility to call
+ * SSLCopyPeerTrust() upon successful completion of the handshake
+ * and then to perform external validation of the peer certificate
+ * chain before proceeding with data transfer.
+ */
+OSStatus
+_SSLSetEnableCertVerify                (SSLContextRef                  context,
+                             Boolean                           enableVerify);
+
+OSStatus
+_SSLGetEnableCertVerify                (SSLContextRef                  context,
+                             Boolean                           *enableVerify); /* RETURNED */
+
+/*
+ * 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
+_SSLSetAllowsExpiredCerts      (SSLContextRef          context,
+                             Boolean                   allowsExpired);
+
+/*
+ * Obtain the current value of an SSLContext's "allowExpiredCerts" flag.
+ */
+OSStatus
+_SSLGetAllowsExpiredCerts      (SSLContextRef          context,
+                             Boolean                   *allowsExpired); /* RETURNED */
+
+/*
+ * Similar to SSLSetAllowsExpiredCerts(), this function allows the
+ * option of ignoring "expired" status for root certificates only.
+ * Default is false, i.e., expired root certs result in an
+ * errSSLCertExpired error.
+ */
+OSStatus
+_SSLSetAllowsExpiredRoots      (SSLContextRef          context,
+                             Boolean                   allowsExpired);
+
+OSStatus
+_SSLGetAllowsExpiredRoots      (SSLContextRef          context,
+                             Boolean                   *allowsExpired); /* 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
+_SSLSetAllowsAnyRoot                   (SSLContextRef          context,
+                                 Boolean                       anyRoot);
+
+/*
+ * Obtain the current value of an SSLContext's "allow any root" flag.
+ */
+OSStatus
+_SSLGetAllowsAnyRoot                   (SSLContextRef          context,
+                                 Boolean                       *anyRoot); /* RETURNED */
+
+/*
+ * Augment or replace the system's default trusted root certificate set
+ * for this session. If replaceExisting is true, the specified roots will
+ * be the only roots which are trusted during this session. If replaceExisting
+ * is false, the specified roots will be added to the current set of trusted
+ * root certs. If this function has never been called, the current trusted
+ * root set is the same as the system's default trusted root set.
+ * Successive calls with replaceExisting false result in accumulation
+ * of additional root certs.
+ *
+ * The trustedRoots array contains SecCertificateRefs.
+ */
+OSStatus
+_SSLSetTrustedRoots                    (SSLContextRef          context,
+                             CFArrayRef                trustedRoots,
+                             Boolean                   replaceExisting);
+
+/*
+ * Obtain an array of SecCertificateRefs representing the current
+ * set of trusted roots. If SSLSetTrustedRoots() has never been called
+ * for this session, this returns the system's default root set.
+ *
+ * Caller must CFRelease the returned CFArray.
+ */
+OSStatus
+_SSLCopyTrustedRoots                   (SSLContextRef          context,
+                                 CFArrayRef            *trustedRoots); /* RETURNED */
+
+/*
+ * Add a SecCertificateRef, or a CFArray of them, to a server's list
+ * of acceptable Certificate Authorities (CAs) to present to the client
+ * when client authentication is performed.
+ *
+ * If replaceExisting is true, the specified certificate(s) will replace
+ * a possible existing list of acceptable CAs. If replaceExisting is
+ * false, the specified certificate(s) will be appended to the existing
+ * list of acceptable CAs, if any.
+ *
+ * Returns errSecParam is this is called on an SSLContextRef which
+ * is configured as a client, or when a session is active.
+ */
+OSStatus
+_SSLSetCertificateAuthorities(SSLContextRef            context,
+                             CFTypeRef                 certificateOrArray,
+                              Boolean                  replaceExisting);
+
+/*
+ * Obtain the certificates specified in SSLSetCertificateAuthorities(),
+ * if any. Returns a NULL array if SSLSetCertificateAuthorities() has not
+ * been called.
+ * Caller must CFRelease the returned array.
+ */
+
+OSStatus
+_SSLCopyCertificateAuthorities(SSLContextRef           context,
+                              CFArrayRef               *certificates); /* RETURNED */
+
+/*
+ * Request peer certificates. Valid anytime, subsequent to
+ * a handshake attempt.
+ *
+ * The certs argument is a CFArray containing SecCertificateRefs.
+ * Caller must CFRelease the returned array.
+ *
+ * The cert at index 0 of the returned array is the subject (end
+ * entity) cert; the root cert (or the closest cert to it) is at
+ * the end of the returned array.
+ */
+/* API REVIEW:
+ This should be removed so that applications are not tempted to
+ use this to evaluate trust, they should use the SecTrustRef returned
+ by SSLCopyPeerTrust instead.
+ But this maybe useful to know which certs where returned by the server
+ vs which where pulled internally.
+ This would be a debug feature, so we deprecate this in iOS. There
+ should be an API in SecTrust to allow getting the original certificates
+ for debug purpose.
+ */
+OSStatus
+_SSLCopyPeerCertificates               (SSLContextRef          context,
+                             CFArrayRef                        *certs);        /* RETURNED */
+
+/*
+ * Specify Diffie-Hellman parameters. Optional; if we are configured to allow
+ * for D-H ciphers and a D-H cipher is negotiated, and this function has not
+ * been called, a set of process-wide parameters will be calculated. However
+ * that can take a long time (30 seconds).
+ */
+OSStatus _SSLSetDiffieHellmanParams    (SSLContextRef                  context,
+                                     const void                        *dhParams,
+                                     size_t                                    dhParamsLen);
+
+/*
+ * Return parameter block specified in SSLSetDiffieHellmanParams.
+ * Returned data is not copied and belongs to the SSLContextRef.
+ */
+OSStatus _SSLGetDiffieHellmanParams    (SSLContextRef                  context,
+                                     const void                        **dhParams,
+                                     size_t                                    *dhParamsLen);
+
+/*
+ * Enable/Disable RSA blinding. This feature thwarts a known timing
+ * attack to which RSA keys are vulnerable; enabling it is a tradeoff
+ * between performance and security. The default for RSA blinding is
+ * enabled.
+ */
+OSStatus _SSLSetRsaBlinding                    (SSLContextRef                  context,
+                                     Boolean                           blinding);
+
+OSStatus _SSLGetRsaBlinding                    (SSLContextRef                  context,
+                                     Boolean                           *blinding);
+
+/*
+ * Create a new SSL/TLS session context.
+ * Deprecated: please use the allocator based functions, when available.
+ */
+OSStatus
+_SSLNewContext                         (Boolean                        isServer,
+                             SSLContextRef             *tlsContextPtr);     /* RETURNED */
+
+/*
+ * Dispose of an SSLContextRef.  This is effectivly a CFRelease.
+ * Deprecated.
+ */
+OSStatus
+_SSLDisposeContext                     (SSLContextRef          context);
+
+/* We redefine the names of all SPIs to avoid collision with unavailable APIs */
+#define SSLSetProtocolVersionEnabled _SSLSetProtocolVersionEnabled
+#define SSLGetProtocolVersionEnabled _SSLGetProtocolVersionEnabled
+#define SSLSetProtocolVersion _SSLSetProtocolVersion
+#define SSLGetProtocolVersion _SSLGetProtocolVersion
+#define SSLSetEnableCertVerify _SSLSetEnableCertVerify
+#define SSLGetEnableCertVerify _SSLGetEnableCertVerify
+#define SSLSetAllowsExpiredCerts _SSLSetAllowsExpiredCerts
+#define SSLGetAllowsExpiredCerts _SSLGetAllowsExpiredCerts
+#define SSLSetAllowsExpiredRoots _SSLSetAllowsExpiredRoots
+#define SSLGetAllowsExpiredRoots _SSLGetAllowsExpiredRoots
+#define SSLSetAllowsAnyRoot _SSLSetAllowsAnyRoot
+#define SSLGetAllowsAnyRoot _SSLGetAllowsAnyRoot
+#define SSLSetTrustedRoots _SSLSetTrustedRoots
+#define SSLCopyTrustedRoots _SSLCopyTrustedRoots
+#define SSLSetCertificateAuthorities _SSLSetCertificateAuthorities
+#define SSLCopyCertificateAuthorities _SSLCopyCertificateAuthorities
+#define SSLCopyPeerCertificates _SSLCopyPeerCertificates
+#define SSLSetDiffieHellmanParams _SSLSetDiffieHellmanParams
+#define SSLGetDiffieHellmanParams _SSLGetDiffieHellmanParams
+#define SSLSetRsaBlinding   _SSLSetRsaBlinding
+#define SSLGetRsaBlinding      _SSLGetRsaBlinding
+#define SSLNewContext _SSLNewContext
+#define SSLNewDatagramContext _SSLNewDatagramContext
+#define SSLDisposeContext _SSLDisposeContext
+
+#endif /* TARGET_OS_IPHONE */
+
+
+/*
+ * Create a new Datagram TLS session context.
+ * Use in place of SSLNewContext to create a DTLS session.
+ * Deprecated: please use the allocator based functions, when available.
+ * Also note: the symbol is prefixed with underscore in iOS (historical)
+ */
+OSStatus
+SSLNewDatagramContext          (Boolean                        isServer,
+                             SSLContextRef             *dtlsContextPtr);       /* RETURNED */
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _SECURE_TRANSPORT_PRIV_H_ */
index b31364d536afcbfeea0ec3dcf5800174238ff12b..fb5a1b3b767daa9b91673545590e6d8f393ae15f 100644 (file)
@@ -59,8 +59,8 @@
 #include <Security/oidsalg.h>
 #include <Security/oidscert.h>
 
 #include <Security/oidsalg.h>
 #include <Security/oidscert.h>
 
-#pragma mark -
-#pragma mark Utilities
+// MARK: -
+// MARK: Utilities
 
 /*
  * Set up a Raw symmetric key with specified algorithm and key bits.
 
 /*
  * Set up a Raw symmetric key with specified algorithm and key bits.
@@ -99,7 +99,7 @@ OSStatus sslSetUpSymmKey(
        hdr->KeyAttr = CSSM_KEYATTR_MODIFIABLE | CSSM_KEYATTR_EXTRACTABLE;
        hdr->KeyUsage = keyUse;
        hdr->WrapAlgorithmId = CSSM_ALGID_NONE;
        hdr->KeyAttr = CSSM_KEYATTR_MODIFIABLE | CSSM_KEYATTR_EXTRACTABLE;
        hdr->KeyUsage = keyUse;
        hdr->WrapAlgorithmId = CSSM_ALGID_NONE;
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -129,7 +129,7 @@ OSStatus sslFreeKey(
                *kcItem = NULL;
        }
        #endif
                *kcItem = NULL;
        }
        #endif
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -160,7 +160,7 @@ OSStatus attachToCsp(SSLContext *ctx)
 {
        assert(ctx != NULL);
        if(ctx->cspHand != 0) {
 {
        assert(ctx != NULL);
        if(ctx->cspHand != 0) {
-               return noErr;
+               return errSecSuccess;
        }
        else {
                return errSSLModuleAttach;
        }
        else {
                return errSSLModuleAttach;
@@ -174,7 +174,7 @@ OSStatus attachToCl(SSLContext *ctx)
 {
        assert(ctx != NULL);
        if(ctx->clHand != 0) {
 {
        assert(ctx != NULL);
        if(ctx->clHand != 0) {
-               return noErr;
+               return errSecSuccess;
        }
        else {
                return errSSLModuleAttach;
        }
        else {
                return errSSLModuleAttach;
@@ -185,7 +185,7 @@ OSStatus attachToTp(SSLContext *ctx)
 {
        assert(ctx != NULL);
        if(ctx->tpHand != 0) {
 {
        assert(ctx != NULL);
        if(ctx->tpHand != 0) {
-               return noErr;
+               return errSecSuccess;
        }
        else {
                return errSSLModuleAttach;
        }
        else {
                return errSSLModuleAttach;
@@ -205,7 +205,7 @@ OSStatus attachToAll(SSLContext *ctx)
           return errSSLModuleAttach;
        }
        else {
           return errSSLModuleAttach;
        }
        else {
-               return noErr;
+               return errSecSuccess;
        }
 }
 
        }
 }
 
@@ -227,7 +227,7 @@ OSStatus detachFromAll(SSLContext *ctx)
                ctx->clHand = 0;
        }
        #endif  /* 0 */
                ctx->clHand = 0;
        }
        #endif  /* 0 */
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -300,8 +300,8 @@ static OSStatus sslGetKeyParts(
     return NULL;
 }
 
     return NULL;
 }
 
-#pragma mark -
-#pragma mark CSSM_DATA routines
+// MARK: -
+// MARK: CSSM_DATA routines
 
 CSSM_DATA_PTR stMallocCssmData(
        size_t size)
 
 CSSM_DATA_PTR stMallocCssmData(
        size_t size)
@@ -350,15 +350,15 @@ OSStatus stSetUpCssmData(
        if(data->Length == 0) {
                data->Data = (uint8 *)stAppMalloc(length, NULL);
                if(data->Data == NULL) {
        if(data->Length == 0) {
                data->Data = (uint8 *)stAppMalloc(length, NULL);
                if(data->Data == NULL) {
-                       return memFullErr;
+                       return errSecAllocate;
                }
        }
        else if(data->Length < length) {
                sslErrorLog("stSetUpCssmData: length too small\n");
                }
        }
        else if(data->Length < length) {
                sslErrorLog("stSetUpCssmData: length too small\n");
-               return memFullErr;
+               return errSecAllocate;
        }
        data->Length = length;
        }
        data->Length = length;
-       return noErr;
+       return errSecSuccess;
 }
 
 /* All signature ops are "raw", with digest step done by us */
 }
 
 /* All signature ops are "raw", with digest step done by us */
@@ -367,7 +367,7 @@ static OSStatus sslKeyToSigAlg(
        CSSM_ALGORITHMS *sigAlg)        /* RETURNED */
 
 {
        CSSM_ALGORITHMS *sigAlg)        /* RETURNED */
 
 {
-       OSStatus ortn = noErr;
+       OSStatus ortn = errSecSuccess;
        switch(cssmKey->KeyHeader.AlgorithmId) {
                case CSSM_ALGID_RSA:
                        *sigAlg = CSSM_ALGID_RSA;
        switch(cssmKey->KeyHeader.AlgorithmId) {
                case CSSM_ALGID_RSA:
                        *sigAlg = CSSM_ALGID_RSA;
@@ -385,8 +385,8 @@ static OSStatus sslKeyToSigAlg(
        return ortn;
 }
 
        return ortn;
 }
 
-#pragma mark -
-#pragma mark Public CSP Functions
+// MARK: -
+// MARK: Public CSP Functions
 
 /*
  * Raw RSA/DSA sign/verify.
 
 /*
  * Raw RSA/DSA sign/verify.
@@ -485,7 +485,7 @@ OSStatus sslRawSign(
        }
        else {
                *actualBytes = sigData.Length;
        }
        else {
                *actualBytes = sigData.Length;
-               serr = noErr;
+               serr = errSecSuccess;
        }
        if(sigHand != 0) {
                CSSM_DeleteContext(sigHand);
        }
        if(sigHand != 0) {
                CSSM_DeleteContext(sigHand);
@@ -552,7 +552,7 @@ OSStatus sslRawVerify(
                serr = errSSLCrypto;
        }
        else {
                serr = errSSLCrypto;
        }
        else {
-               serr = noErr;
+               serr = errSecSuccess;
        }
        if(sigHand != 0) {
                CSSM_DeleteContext(sigHand);
        }
        if(sigHand != 0) {
                CSSM_DeleteContext(sigHand);
@@ -657,7 +657,7 @@ OSStatus sslRsaEncrypt(
                                memmove(cipherText + toMoveCtext, remData.Data,
                                        toMoveRem);
                        }
                                memmove(cipherText + toMoveCtext, remData.Data,
                                        toMoveRem);
                        }
-                       serr = noErr;
+                       serr = errSecSuccess;
                }
        }
        else {
                }
        }
        else {
@@ -794,7 +794,7 @@ OSStatus sslRsaDecrypt(
                                memmove(plainText + toMovePtext, remData.Data,
                                        toMoveRem);
                        }
                                memmove(plainText + toMovePtext, remData.Data,
                                        toMoveRem);
                        }
-                       serr = noErr;
+                       serr = errSecSuccess;
                }
        }
        else {
                }
        }
        else {
@@ -851,7 +851,7 @@ OSStatus sslGetMaxSigSize(
        const CSSM_KEY  *privKey,
        uint32_t                *maxSigSize)
 {
        const CSSM_KEY  *privKey,
        uint32_t                *maxSigSize)
 {
-       OSStatus ortn = noErr;
+       OSStatus ortn = errSecSuccess;
        assert(privKey != NULL);
        assert(privKey->KeyHeader.KeyClass == CSSM_KEYCLASS_PRIVATE_KEY);
        switch(privKey->KeyHeader.AlgorithmId) {
        assert(privKey != NULL);
        assert(privKey->KeyHeader.KeyClass == CSSM_KEYCLASS_PRIVATE_KEY);
        switch(privKey->KeyHeader.AlgorithmId) {
@@ -1021,7 +1021,7 @@ OSStatus sslGetPubKeyFromBits(
        /* the rest is boilerplate, cook up a good-looking public key */
        key = (CSSM_KEY_PTR)sslMalloc(sizeof(CSSM_KEY));
        if(key == NULL) {
        /* the rest is boilerplate, cook up a good-looking public key */
        key = (CSSM_KEY_PTR)sslMalloc(sizeof(CSSM_KEY));
        if(key == NULL) {
-               return memFullErr;
+               return errSecAllocate;
        }
        memset(key, 0, sizeof(CSSM_KEY));
        hdr = &key->KeyHeader;
        }
        memset(key, 0, sizeof(CSSM_KEY));
        hdr = &key->KeyHeader;
@@ -1059,7 +1059,7 @@ OSStatus sslGetPubKeyFromBits(
     hdr->LogicalKeySizeInBits = keySize.EffectiveKeySizeInBits;
     *pubKey = key;
     *cspHand = ctx->cspHand;
     hdr->LogicalKeySizeInBits = keySize.EffectiveKeySizeInBits;
     *pubKey = key;
     *cspHand = ctx->cspHand;
-       return noErr;
+       return errSecSuccess;
 
 abort:
        /* note this frees the blob */
 
 abort:
        /* note this frees the blob */
@@ -1082,7 +1082,7 @@ static OSStatus sslNullUnwrapKey(
        CSSM_ACCESS_CREDENTIALS creds;
        CSSM_DATA labelData = {4, (uint8 *)"none"};
        uint32 keyAttr;
        CSSM_ACCESS_CREDENTIALS creds;
        CSSM_DATA labelData = {4, (uint8 *)"none"};
        uint32 keyAttr;
-       OSStatus ortn = noErr;
+       OSStatus ortn = errSecSuccess;
 
        memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
        memset(refKey, 0, sizeof(CSSM_KEY));
 
        memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
        memset(refKey, 0, sizeof(CSSM_KEY));
@@ -1142,7 +1142,7 @@ static OSStatus sslNullWrapKey(
        CSSM_CC_HANDLE ccHand;
        CSSM_ACCESS_CREDENTIALS creds;
        uint32 keyAttr;
        CSSM_CC_HANDLE ccHand;
        CSSM_ACCESS_CREDENTIALS creds;
        uint32 keyAttr;
-       OSStatus ortn = noErr;
+       OSStatus ortn = errSecSuccess;
 
        memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
        memset(rawKey, 0, sizeof(CSSM_KEY));
 
        memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
        memset(rawKey, 0, sizeof(CSSM_KEY));
@@ -1180,8 +1180,8 @@ static OSStatus sslNullWrapKey(
        return crtn;
 }
 
        return crtn;
 }
 
-#pragma mark -
-#pragma mark Public Certificate Functions
+// MARK: -
+// MARK: Public Certificate Functions
 
 /*
  * Given a DER-encoded cert, obtain its public key as a CSSM_KEY_PTR.
 
 /*
  * Given a DER-encoded cert, obtain its public key as a CSSM_KEY_PTR.
@@ -1225,7 +1225,7 @@ OSStatus sslPubKeyFromCert(
        }
        else {
                pubKey->cspHand = ctx->cspHand;
        }
        else {
                pubKey->cspHand = ctx->cspHand;
-               return noErr;
+               return errSecSuccess;
        }
 }
 
        }
 }
 
@@ -1295,7 +1295,7 @@ static void sslReleaseArray(
        CFMutableArrayRef certGroup = CFArrayCreateMutable(NULL, numCerts,
                &kCFTypeArrayCallBacks);
        if(certGroup == NULL) {
        CFMutableArrayRef certGroup = CFArrayCreateMutable(NULL, numCerts,
                &kCFTypeArrayCallBacks);
        if(certGroup == NULL) {
-               return memFullErr;
+               return errSecAllocate;
        }
        /* subsequent errors to errOut: */
 
        }
        /* subsequent errors to errOut: */
 
@@ -1402,7 +1402,7 @@ static void sslReleaseArray(
        kcList = CFArrayCreateMutable(NULL, 0, NULL);
        if(kcList == NULL) {
                sslErrorLog("***sslVerifyCertChain: error creating null kcList\n");
        kcList = CFArrayCreateMutable(NULL, 0, NULL);
        if(kcList == NULL) {
                sslErrorLog("***sslVerifyCertChain: error creating null kcList\n");
-               serr = memFullErr;
+               serr = errSecAllocate;
                goto errOut;
        }
        serr = SecTrustSetKeychains(theTrust, kcList);
                goto errOut;
        }
        serr = SecTrustSetKeychains(theTrust, kcList);
@@ -1426,7 +1426,7 @@ static void sslReleaseArray(
 
        if(!ctx->enableCertVerify) {
                /* trivial case, this is caller's responsibility */
 
        if(!ctx->enableCertVerify) {
                /* trivial case, this is caller's responsibility */
-               serr = noErr;
+               serr = errSecSuccess;
                goto errOut;
        }
 
                goto errOut;
        }
 
@@ -1436,7 +1436,7 @@ static void sslReleaseArray(
        if(ctx->trustedLeafCerts) {
                if (sslGetMatchingCertInArray((SecCertificateRef)CFArrayGetValueAtIndex(certGroup, 0),
                        ctx->trustedLeafCerts)) {
        if(ctx->trustedLeafCerts) {
                if (sslGetMatchingCertInArray((SecCertificateRef)CFArrayGetValueAtIndex(certGroup, 0),
                        ctx->trustedLeafCerts)) {
-                       serr = noErr;
+                       serr = errSecSuccess;
                        goto errOut;
                }
        }
                        goto errOut;
                }
        }
@@ -1483,7 +1483,7 @@ static void sslReleaseArray(
                        case CSSMERR_TP_INVALID_ANCHOR_CERT:
                                /* root found but we don't trust it */
                                if(ctx->allowAnyRoot) {
                        case CSSMERR_TP_INVALID_ANCHOR_CERT:
                                /* root found but we don't trust it */
                                if(ctx->allowAnyRoot) {
-                                       serr = noErr;
+                                       serr = errSecSuccess;
                                        sslErrorLog("***Warning: accepting unknown root cert\n");
                                }
                                else {
                                        sslErrorLog("***Warning: accepting unknown root cert\n");
                                }
                                else {
@@ -1494,7 +1494,7 @@ static void sslReleaseArray(
                                /* no root, not even in implicit SSL roots */
                                if(ctx->allowAnyRoot) {
                                        sslErrorLog("***Warning: accepting unverified cert chain\n");
                                /* no root, not even in implicit SSL roots */
                                if(ctx->allowAnyRoot) {
                                        sslErrorLog("***Warning: accepting unverified cert chain\n");
-                                       serr = noErr;
+                                       serr = errSecSuccess;
                                }
                                else {
                                        serr = errSSLNoRootCert;
                                }
                                else {
                                        serr = errSSLNoRootCert;
@@ -1562,8 +1562,8 @@ void stPrintCdsaError(const char *op, CSSM_RETURN crtn)
 }
 #endif
 
 }
 #endif
 
-#pragma mark -
-#pragma mark Diffie-Hellman Support
+// MARK: -
+// MARK: Diffie-Hellman Support
 
 /*
  * Generate a Diffie-Hellman key pair. Algorithm parameters always
 
 /*
  * Generate a Diffie-Hellman key pair. Algorithm parameters always
@@ -1593,7 +1593,7 @@ OSStatus sslDhGenKeyPairClient(
                return ortn;
        }
        ortn = sslDhGenerateKeyPair(ctx, &sParam, prime->length * 8, publicKey, privateKey);
                return ortn;
        }
        ortn = sslDhGenerateKeyPair(ctx, &sParam, prime->length * 8, publicKey, privateKey);
-       SSLFreeBuffer(&sParam, ctx);
+       SSLFreeBuffer(&sParam);
        return ortn;
 }
 
        return ortn;
 }
 
@@ -1607,7 +1607,7 @@ OSStatus sslDhGenerateKeyPair(
        CSSM_RETURN             crtn;
        CSSM_CC_HANDLE  ccHandle;
        CSSM_DATA               labelData = {8, (uint8 *)"tempKey"};
        CSSM_RETURN             crtn;
        CSSM_CC_HANDLE  ccHandle;
        CSSM_DATA               labelData = {8, (uint8 *)"tempKey"};
-       OSStatus                ortn = noErr;
+       OSStatus                ortn = errSecSuccess;
        CSSM_DATA               cParamBlob;
 
        assert(ctx != NULL);
        CSSM_DATA               cParamBlob;
 
        assert(ctx != NULL);
@@ -1672,7 +1672,7 @@ OSStatus sslDhKeyExchange(
        CSSM_CC_HANDLE                  ccHandle;
        CSSM_DATA                               labelData = {8, (uint8 *)"tempKey"};
        CSSM_KEY                                derivedKey;
        CSSM_CC_HANDLE                  ccHandle;
        CSSM_DATA                               labelData = {8, (uint8 *)"tempKey"};
        CSSM_KEY                                derivedKey;
-       OSStatus                                ortn = noErr;
+       OSStatus                                ortn = errSecSuccess;
 
        assert(ctx != NULL);
        assert(ctx->cspHand != 0);
 
        assert(ctx != NULL);
        assert(ctx->cspHand != 0);
@@ -1723,8 +1723,8 @@ OSStatus sslDhKeyExchange(
        return ortn;
 }
 
        return ortn;
 }
 
-#pragma mark -
-#pragma mark *** ECDSA support ***
+// MARK: -
+// MARK: *** ECDSA support ***
 
 /* specify either 32-bit integer or a pointer as an added attribute value */
 typedef enum {
 
 /* specify either 32-bit integer or a pointer as an added attribute value */
 typedef enum {
@@ -1776,14 +1776,14 @@ OSStatus sslEcdhGenerateKeyPair(
        CSSM_RETURN             crtn;
        CSSM_CC_HANDLE  ccHandle = 0;
        CSSM_DATA               labelData = {8, (uint8 *)"ecdsaKey"};
        CSSM_RETURN             crtn;
        CSSM_CC_HANDLE  ccHandle = 0;
        CSSM_DATA               labelData = {8, (uint8 *)"ecdsaKey"};
-       OSStatus                ortn = noErr;
+       OSStatus                ortn = errSecSuccess;
        CSSM_KEY                pubKey;
        uint32                  keySizeInBits;
 
        assert(ctx != NULL);
        assert(ctx->cspHand != 0);
        sslFreeKey(ctx->ecdhPrivCspHand, &ctx->ecdhPrivate, NULL);
        CSSM_KEY                pubKey;
        uint32                  keySizeInBits;
 
        assert(ctx != NULL);
        assert(ctx->cspHand != 0);
        sslFreeKey(ctx->ecdhPrivCspHand, &ctx->ecdhPrivate, NULL);
-    SSLFreeBuffer(&ctx->ecdhExchangePublic, ctx);
+    SSLFreeBuffer(&ctx->ecdhExchangePublic);
 
        switch(namedCurve) {
                case SSL_Curve_secp256r1:
 
        switch(namedCurve) {
                case SSL_Curve_secp256r1:
@@ -1890,7 +1890,7 @@ OSStatus sslEcdhKeyExchange(
        CSSM_CC_HANDLE                  ccHandle;
        CSSM_DATA                               labelData = {8, (uint8 *)"tempKey"};
        CSSM_KEY                                derivedKey;
        CSSM_CC_HANDLE                  ccHandle;
        CSSM_DATA                               labelData = {8, (uint8 *)"tempKey"};
        CSSM_KEY                                derivedKey;
-       OSStatus                                ortn = noErr;
+       OSStatus                                ortn = errSecSuccess;
        CSSM_KEY                                rawKey;
        bool                                    useRefKeys = false;
        uint32                                  keyAttr;
        CSSM_KEY                                rawKey;
        bool                                    useRefKeys = false;
        uint32                                  keyAttr;
@@ -2046,7 +2046,7 @@ errOut:
        CSSM_DeleteContext(ccHandle);
        if(useRefKeys) {
                if(pubKeyBits.length) {
        CSSM_DeleteContext(ccHandle);
        if(useRefKeys) {
                if(pubKeyBits.length) {
-                       SSLFreeBuffer(&pubKeyBits, ctx);
+                       SSLFreeBuffer(&pubKeyBits);
                }
                if(rawKey.KeyData.Length) {
                        CSSM_FreeKey(ctx->ecdhPrivCspHand, NULL, &rawKey, CSSM_FALSE);
                }
                if(rawKey.KeyData.Length) {
                        CSSM_FreeKey(ctx->ecdhPrivCspHand, NULL, &rawKey, CSSM_FALSE);
@@ -2072,13 +2072,13 @@ OSStatus sslVerifySelectedCipher(
        const SSLCipherSpec *selectedCipherSpec)
 {
        if(ctx->protocolSide == kSSLClientSide) {
        const SSLCipherSpec *selectedCipherSpec)
 {
        if(ctx->protocolSide == kSSLClientSide) {
-               return noErr;
+               return errSecSuccess;
        }
        #if     SSL_PAC_SERVER_ENABLE
        if((ctx->masterSecretCallback != NULL) &&
           (ctx->sessionTicket.data != NULL)) {
                /* EAP via PAC resumption; we can do it */
        }
        #if     SSL_PAC_SERVER_ENABLE
        if((ctx->masterSecretCallback != NULL) &&
           (ctx->sessionTicket.data != NULL)) {
                /* EAP via PAC resumption; we can do it */
-               return noErr;
+               return errSecSuccess;
        }
        #endif  /* SSL_PAC_SERVER_ENABLE */
 
        }
        #endif  /* SSL_PAC_SERVER_ENABLE */
 
@@ -2119,7 +2119,7 @@ OSStatus sslVerifySelectedCipher(
                        return errSSLInternal;
     }
        if(requireAlg == CSSM_ALGID_NONE) {
                        return errSSLInternal;
     }
        if(requireAlg == CSSM_ALGID_NONE) {
-               return noErr;
+               return errSecSuccess;
        }
 
        /* private signing key required */
        }
 
        /* private signing key required */
@@ -2140,7 +2140,7 @@ OSStatus sslVerifySelectedCipher(
                        return errSSLBadConfiguration;
                }
        }
                        return errSSLBadConfiguration;
                }
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 #endif /* USE_CDSA_CRYPTO */
 }
 
 #endif /* USE_CDSA_CRYPTO */
index 6dc76a09686b8784eb78fe07d0711551f75ef9f8..4ef22b4f8347f519ea9511bc3f862b6a2b8b5fa4 100644 (file)
@@ -58,6 +58,8 @@
 #include <pthread.h>
 #include <string.h>
 
 #include <pthread.h>
 #include <string.h>
 
+#include <utilities/SecIOFormat.h>
+
 /* default time-to-live in cache, in seconds */
 #define QUICK_CACHE_TEST       0
 #if            QUICK_CACHE_TEST
 /* default time-to-live in cache, in seconds */
 #define QUICK_CACHE_TEST       0
 #if            QUICK_CACHE_TEST
@@ -143,7 +145,7 @@ static SessionCacheEntry *SessionCacheEntryCreate(
        }
        serr = SSLCopyBuffer(sessionData, &entry->mSessionData);
        if(serr) {
        }
        serr = SSLCopyBuffer(sessionData, &entry->mSessionData);
        if(serr) {
-        SSLFreeBuffer(&entry->mKey, NULL);
+        SSLFreeBuffer(&entry->mKey);
         sslFree (entry);
         return NULL;
        }
         sslFree (entry);
         return NULL;
        }
@@ -157,8 +159,8 @@ static SessionCacheEntry *SessionCacheEntryCreate(
 static void SessionCacheEntryDelete(SessionCacheEntry *entry)
 {
        sslLogSessCacheDebug("~SessionCacheEntryDelete() %p", entry);
 static void SessionCacheEntryDelete(SessionCacheEntry *entry)
 {
        sslLogSessCacheDebug("~SessionCacheEntryDelete() %p", entry);
-       SSLFreeBuffer(&entry->mKey, NULL);              // no SSLContext
-       SSLFreeBuffer(&entry->mSessionData, NULL);
+       SSLFreeBuffer(&entry->mKey);            // no SSLContext
+       SSLFreeBuffer(&entry->mSessionData);
     sslFree(entry);
 }
 
     sslFree(entry);
 }
 
@@ -191,7 +193,7 @@ static bool SessionCacheEntryIsStaleNow(SessionCacheEntry *entry)
 static OSStatus SessionCacheEntrySetSessionData(SessionCacheEntry *entry,
        const SSLBuffer *data)
 {
 static OSStatus SessionCacheEntrySetSessionData(SessionCacheEntry *entry,
        const SSLBuffer *data)
 {
-       SSLFreeBuffer(&entry->mSessionData, NULL);
+       SSLFreeBuffer(&entry->mSessionData);
        return SSLCopyBuffer(data, &entry->mSessionData);
 }
 
        return SSLCopyBuffer(data, &entry->mSessionData);
 }
 
@@ -251,7 +253,7 @@ static OSStatus SessionCacheAddEntry(
                  */
                 sslLogSessCacheDebug("SessionCache::addEntry CACHE HIT "
                     "entry = %p", entry);
                  */
                 sslLogSessCacheDebug("SessionCache::addEntry CACHE HIT "
                     "entry = %p", entry);
-                return noErr;
+                return errSecSuccess;
             }
             else {
                 sslLogSessCacheDebug("SessionCache::addEntry CACHE REPLACE "
             }
             else {
                 sslLogSessCacheDebug("SessionCache::addEntry CACHE REPLACE "
@@ -281,7 +283,7 @@ static OSStatus SessionCacheAddEntry(
     entry->next = cache->head;
     cache->head = entry;
 
     entry->next = cache->head;
     cache->head = entry;
 
-       return noErr;
+       return errSecSuccess;
 }
 
 static OSStatus SessionCacheLookupEntry(
 }
 
 static OSStatus SessionCacheLookupEntry(
@@ -330,11 +332,11 @@ static OSStatus SessionCacheDeleteEntry(
                        #endif
             *current = entry->next;
             SessionCacheEntryDelete(entry);
                        #endif
             *current = entry->next;
             SessionCacheEntryDelete(entry);
-            return noErr;
+            return errSecSuccess;
                }
        }
 
                }
        }
 
-    return noErr;
+    return errSecSuccess;
 }
 
 /* cleanup, delete stale entries */
 }
 
 /* cleanup, delete stale entries */
@@ -415,9 +417,9 @@ OSStatus sslGetSession (
     {
         serr = SessionCacheLookupEntry(cache, &sessionKey, sessionData);
 
     {
         serr = SessionCacheLookupEntry(cache, &sessionKey, sessionData);
 
-        sslLogSessCacheDebug("sslGetSession(%d, %p): %ld",
+        sslLogSessCacheDebug("sslGetSession(%d, %p): %d",
             (int)sessionKey.length, sessionKey.data,
             (int)sessionKey.length, sessionKey.data,
-            serr);
+            (int)serr);
         if(!serr) {
             cachePrint(NULL, &sessionKey, sessionData);
         }
         if(!serr) {
             cachePrint(NULL, &sessionKey, sessionData);
         }
@@ -452,7 +454,7 @@ OSStatus sslDeleteSession (
 OSStatus sslCleanupSession(void)
 {
     SessionCache *cache = SessionCacheGetLockedInstance();
 OSStatus sslCleanupSession(void)
 {
     SessionCache *cache = SessionCacheGetLockedInstance();
-       OSStatus serr = noErr;
+       OSStatus serr = errSecSuccess;
        bool moreToGo = false;
 
     if (!cache)
        bool moreToGo = false;
 
     if (!cache)
index f3394255ddea71506df8acbc97513d27aa436ce3..0daa945bd8accfa8cba42ff10e89f17e5b0dc47a 100644 (file)
  * cipherSpecs.c - SSLCipherSpec declarations
  */
 
  * cipherSpecs.c - SSLCipherSpec declarations
  */
 
-#include "ssl.h"
+/* THIS FILE CONTAINS KERNEL CODE */
+
 #include "CipherSuite.h"
 #include "CipherSuite.h"
-#include "sslContext.h"
-#include "cryptType.h"
-#include "symCipher.h"
 #include "cipherSpecs.h"
 #include "cipherSpecs.h"
-#include "sslDebug.h"
-#include "sslMemory.h"
-#include "sslDebug.h"
-#include "sslUtils.h"
-#include "sslPriv.h"
-#include "sslCrypto.h"
-
-#include <string.h>
-#include <TargetConditionals.h>
-
-#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
-
-#define ENABLE_ECDH                                            1
-
-#define ENABLE_AES_GCM          0
-
-#if    APPLE_DH
-#define ENABLE_DH_ANON                 1
-#define ENABLE_DH_EPHEM_RSA            1
-#if USE_CDSA_CRYPTO
-#define ENABLE_DH_EPHEM_DSA            1
-#else
-#define ENABLE_DH_EPHEM_DSA            0
-#endif
-#else
-#define ENABLE_DH_ANON                 0
-#define ENABLE_DH_EPHEM_RSA            0
-#define ENABLE_DH_EPHEM_DSA            0
-#endif /* APPLE_DH */
-
-extern const SSLSymmetricCipher SSLCipherNull;         /* in sslNullCipher.c */
-
-/*
- * The symmetric ciphers currently supported (in addition to the
- * NULL cipher in nullciph.c).
- */
-#if    ENABLE_DES
-static const SSLSymmetricCipher SSLCipherDES_CBC = {
-    kCCKeySizeDES,      /* Key size in bytes */
-    kCCKeySizeDES,      /* Secret key size = 64 bits */
-    kCCBlockSizeDES,      /* IV size */
-    kCCBlockSizeDES,      /* Block size */
-    kCCAlgorithmDES,
-    CCSymmInit,
-    CCSymmEncryptDecrypt,
-    CCSymmEncryptDecrypt,
-    CCSymmFinish
-};
-
-static const SSLSymmetricCipher SSLCipherDES40_CBC = {
-    kCCKeySizeDES,      /* Key size in bytes */
-    5,                  /* Secret key size = 40 bits */
-    kCCBlockSizeDES,      /* IV size */
-    kCCBlockSizeDES,      /* Block size */
-    kCCAlgorithmDES,
-    CCSymmInit,
-    CCSymmEncryptDecrypt,
-    CCSymmEncryptDecrypt,
-    CCSymmFinish
-};
-#endif /* ENABLE_DES */
-
-#if    ENABLE_3DES
-static const SSLSymmetricCipher SSLCipher3DES_CBC = {
-    kCCKeySize3DES,     /* Key size in bytes */
-    kCCKeySize3DES,     /* Secret key size = 192 bits */
-    kCCBlockSize3DES,      /* IV size */
-    kCCBlockSize3DES,      /* Block size */
-    kCCAlgorithm3DES,
-    CCSymmInit,
-    CCSymmEncryptDecrypt,
-    CCSymmEncryptDecrypt,
-    CCSymmFinish
-};
-#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 */
-    kCCAlgorithmRC4,
-    CCSymmInit,
-    CCSymmEncryptDecrypt,
-    CCSymmEncryptDecrypt,
-    CCSymmFinish
-};
-
-static const SSLSymmetricCipher SSLCipherRC4_128 = {
-    16,         /* Key size in bytes */
-    16,         /* Secret key size = 128 bits */
-    0,          /* IV size */
-    0,          /* Block size */
-    kCCAlgorithmRC4,
-    CCSymmInit,
-    CCSymmEncryptDecrypt,
-    CCSymmEncryptDecrypt,
-    CCSymmFinish
-};
-#endif /* ENABLE_RC4 */
-
-#if            ENABLE_RC2
-static const SSLSymmetricCipher SSLCipherRC2_40 = {
-    kCCKeySizeMaxRC2,         /* Key size in bytes */
-    5,                        /* Secret key size = 40 bits */
-    kCCBlockSizeRC2,          /* IV size */
-    kCCBlockSizeRC2,          /* Block size */
-    kCCAlgorithmRC2,
-    CCSymmInit,
-    CCSymmEncryptDecrypt,
-    CCSymmEncryptDecrypt,
-    CCSymmFinish
-};
-
-static const SSLSymmetricCipher SSLCipherRC2_128 = {
-    kCCKeySizeMaxRC2,         /* Key size in bytes */
-    kCCKeySizeMaxRC2,          /* Secret key size = 128 bits */
-    kCCBlockSizeRC2,          /* IV size */
-    kCCBlockSizeRC2,          /* Block size */
-    kCCAlgorithmRC2,
-    CCSymmInit,
-    CCSymmEncryptDecrypt,
-    CCSymmEncryptDecrypt,
-    CCSymmFinish
-};
-#endif /* ENABLE_RC2*/
-
-#if            ENABLE_AES
-static const SSLSymmetricCipher SSLCipherAES_128_CBC = {
-    kCCKeySizeAES128,         /* Key size in bytes */
-    kCCKeySizeAES128,                  /* Secret key size */
-    kCCBlockSizeAES128,                        /* IV size */
-    kCCBlockSizeAES128,                        /* Block size */
-    kCCAlgorithmAES128,
-    CCSymmInit,
-    CCSymmEncryptDecrypt,
-    CCSymmEncryptDecrypt,
-    CCSymmFinish
-};
-#endif /* ENABLE_AES */
-
-#if ENABLE_AES256
-static const SSLSymmetricCipher SSLCipherAES_256_CBC = {
-    kCCKeySizeAES256,         /* Key size in bytes */
-    kCCKeySizeAES256,                  /* Secret key size */
-    kCCBlockSizeAES128,                        /* IV size - still 128 bits */
-    kCCBlockSizeAES128,                        /* Block size - still 128 bits */
-    kCCAlgorithmAES128,
-    CCSymmInit,
-    CCSymmEncryptDecrypt,
-    CCSymmEncryptDecrypt,
-    CCSymmFinish
-};
-#endif /* ENABLE_AES256 */
-
-#if ENABLE_AES
-static const SSLSymmetricCipher SSLCipherAES_128_GCM = {
-    kCCKeySizeAES128,         /* Key size in bytes */
-    kCCKeySizeAES128,                  /* Secret key size */
-    kCCBlockSizeAES128,                        /* IV size */
-    kCCBlockSizeAES128,                        /* Block size */
-    kCCAlgorithmAES128,
-    CCSymmInit,
-    CCSymmEncryptDecrypt,
-    CCSymmEncryptDecrypt,
-    CCSymmFinish
-};
-#endif /* ENABLE_AES_GCM */
-
-#if ENABLE_AES256
-static const SSLSymmetricCipher SSLCipherAES_256_GCM = {
-    kCCKeySizeAES256,         /* Key size in bytes */
-    kCCKeySizeAES256,                  /* Secret key size */
-    kCCBlockSizeAES128,                        /* IV size - still 128 bits */
-    kCCBlockSizeAES128,                        /* Block size - still 128 bits */
-    kCCAlgorithmAES128,
-    CCSymmInit,
-    CCSymmEncryptDecrypt,
-    CCSymmEncryptDecrypt,
-    CCSymmFinish
-};
-#endif /* ENABLE_AES256_GCM */
+#include "sslTypes.h"
 
 /*
 
 
 /*
 
@@ -261,184 +68,11 @@ DH_anon w/ AES are preferred over DHE_RSA when enabled, all others at the bottom
     19 SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA
     18 SSL_DH_anon_WITH_RC4_128_MD5
     17 SSL_DH_anon_EXPORT_WITH_RC4_40_MD5
     19 SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA
     18 SSL_DH_anon_WITH_RC4_128_MD5
     17 SSL_DH_anon_EXPORT_WITH_RC4_40_MD5
-
  */
 
  */
 
-/*
- * 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 SSLCipherSuite KnownCipherSuites[] = {
-#if ENABLE_AES_GCM
-    TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
-    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
-#endif
-    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
-    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
-    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
-    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
-    TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
-    TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
-#if ENABLE_AES_GCM
-    TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
-    TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
-#endif
-    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
-    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
-    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
-    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
-    TLS_ECDHE_RSA_WITH_RC4_128_SHA,
-    TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
-#if ENABLE_ECDH
-#if ENABLE_AES_GCM
-    TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
-    TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
-#endif
-    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
-    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
-#if ENABLE_AES_GCM
-    TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,
-    TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
-#endif
-    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,
-    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
-    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
-    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
-    TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
-    TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
-    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
-    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
-    TLS_ECDH_RSA_WITH_RC4_128_SHA,
-    TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
-#endif
-#if ENABLE_AES_GCM
-    TLS_RSA_WITH_AES_256_GCM_SHA384,
-    TLS_RSA_WITH_AES_128_GCM_SHA256,
-#endif
-    TLS_RSA_WITH_AES_256_CBC_SHA256,
-    TLS_RSA_WITH_AES_128_CBC_SHA256,
-    TLS_RSA_WITH_AES_128_CBC_SHA,
-    SSL_RSA_WITH_RC4_128_SHA,
-    SSL_RSA_WITH_RC4_128_MD5,
-    TLS_RSA_WITH_AES_256_CBC_SHA,
-    SSL_RSA_WITH_3DES_EDE_CBC_SHA,
-#if ENABLE_SSLV2
-    SSL_RSA_WITH_3DES_EDE_CBC_MD5,
-#endif
-#if ENABLE_DES
-    SSL_RSA_WITH_DES_CBC_SHA,
-#endif
-#if ENABLE_SSLV2
-    SSL_RSA_WITH_DES_CBC_MD5,
-#endif
-    SSL_RSA_EXPORT_WITH_RC4_40_MD5,
-#if ENABLE_DES
-    SSL_RSA_EXPORT_WITH_DES40_CBC_SHA,
-#endif
-#if ENABLE_RC2
-    SSL_RSA_WITH_RC2_CBC_MD5,
-    SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
-#endif
-#if ENABLE_AES_GCM
-#  if ENABLE_DH_EPHEM_DSA
-    TLS_DHE_DSS_WITH_AES_256_GCM_SHA384,
-#  endif // ENABLE_DH_EPHEM_DSA
-    TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
-#  if ENABLE_DH_EPHEM_DSA
-    TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,
-#  endif // ENABLE_DH_EPHEM_DSA
-    TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
-#endif // ENABLE_AES_GCM
-#if ENABLE_DH_EPHEM_DSA
-    TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,
-#endif
-    TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
-#if ENABLE_DH_EPHEM_DSA
-    TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,
-#endif
-    TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
-#if ENABLE_DH_EPHEM_DSA
-    TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
-#endif
-    TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
-#if ENABLE_DH_EPHEM_DSA
-    TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
-#endif
-    TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
-    SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
-#if ENABLE_DES
-    SSL_DHE_RSA_WITH_DES_CBC_SHA,
-    SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
-#endif
-#if ENABLE_DH_EPHEM_DSA
-    SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
-#if ENABLE_DES
-    SSL_DHE_DSS_WITH_DES_CBC_SHA,
-#endif
-    SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,
-#endif
-    TLS_DH_anon_WITH_AES_256_GCM_SHA384,
-    TLS_DH_anon_WITH_AES_128_GCM_SHA256,
-    TLS_DH_anon_WITH_AES_128_CBC_SHA256,
-    TLS_DH_anon_WITH_AES_256_CBC_SHA256,
-    TLS_DH_anon_WITH_AES_128_CBC_SHA,
-    TLS_DH_anon_WITH_AES_256_CBC_SHA,
-    SSL_DH_anon_WITH_RC4_128_MD5,
-    SSL_DH_anon_WITH_3DES_EDE_CBC_SHA,
-#if ENABLE_DES
-    SSL_DH_anon_WITH_DES_CBC_SHA,
-#endif
-    SSL_DH_anon_EXPORT_WITH_RC4_40_MD5,
-#if ENABLE_DES
-    SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA,
-#endif
-       TLS_ECDHE_ECDSA_WITH_NULL_SHA,
-       TLS_ECDHE_RSA_WITH_NULL_SHA,
-#if ENABLE_ECDH
-    TLS_ECDH_ECDSA_WITH_NULL_SHA,
-       TLS_ECDH_RSA_WITH_NULL_SHA,
-#endif
-    TLS_RSA_WITH_NULL_SHA256,
-    SSL_RSA_WITH_NULL_SHA,
-    SSL_RSA_WITH_NULL_MD5
-
-#if 0
-    /* We don't support these yet. */
-    TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
-    TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
-    TLS_RSA_WITH_RC4_128_SHA,
-    TLS_RSA_WITH_3DES_EDE_CBC_SHA,
-    TLS_RSA_WITH_RC4_128_MD5,
-    TLS_DH_DSS_WITH_AES_256_GCM_SHA384,
-    TLS_DH_DSS_WITH_AES_128_GCM_SHA256,
-    TLS_DH_RSA_WITH_AES_256_GCM_SHA384,
-    TLS_DH_RSA_WITH_AES_128_GCM_SHA256,
-    TLS_DH_DSS_WITH_AES_256_CBC_SHA256,
-    TLS_DH_RSA_WITH_AES_256_CBC_SHA256,
-    TLS_DH_DSS_WITH_AES_128_CBC_SHA256,
-    TLS_DH_RSA_WITH_AES_128_CBC_SHA256,
-    TLS_DH_DSS_WITH_AES_256_CBC_SHA,
-    TLS_DH_RSA_WITH_AES_256_CBC_SHA,
-       TLS_DH_DSS_WITH_AES_128_CBC_SHA,
-    TLS_DH_RSA_WITH_AES_128_CBC_SHA,
-    TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA,
-    TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA,
-    TLS_ECDH_anon_WITH_AES_256_CBC_SHA,
-       TLS_ECDH_anon_WITH_AES_128_CBC_SHA,
-    TLS_ECDH_anon_WITH_RC4_128_SHA,
-    TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA,
-    TLS_ECDH_anon_WITH_NULL_SHA,
-#endif
-};
-
-static const unsigned CipherSuiteCount = sizeof(KnownCipherSuites) / sizeof(*KnownCipherSuites);
-
-static KeyExchangeMethod sslCipherSuiteGetKeyExchangeMethod(SSLCipherSuite cipherSuite) {
+KeyExchangeMethod sslCipherSuiteGetKeyExchangeMethod(SSLCipherSuite cipherSuite)
+{
     switch (cipherSuite) {
         case TLS_NULL_WITH_NULL_NULL:
             return SSL_NULL_auth;
     switch (cipherSuite) {
         case TLS_NULL_WITH_NULL_NULL:
             return SSL_NULL_auth;
@@ -589,9 +223,46 @@ static KeyExchangeMethod sslCipherSuiteGetKeyExchangeMethod(SSLCipherSuite ciphe
         case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
             return SSL_ECDH_anon;
 
         case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
             return SSL_ECDH_anon;
 
+        case TLS_PSK_WITH_NULL_SHA:
+        case TLS_PSK_WITH_RC4_128_SHA:
+        case TLS_PSK_WITH_3DES_EDE_CBC_SHA:
+        case TLS_PSK_WITH_AES_128_CBC_SHA:
+        case TLS_PSK_WITH_AES_256_CBC_SHA:
+        case TLS_PSK_WITH_AES_128_GCM_SHA256:
+        case TLS_PSK_WITH_AES_256_GCM_SHA384:
+        case TLS_PSK_WITH_AES_128_CBC_SHA256:
+        case TLS_PSK_WITH_AES_256_CBC_SHA384:
+        case TLS_PSK_WITH_NULL_SHA256:
+        case TLS_PSK_WITH_NULL_SHA384:
+            return TLS_PSK;
+
+        case TLS_DHE_PSK_WITH_NULL_SHA:
+        case TLS_DHE_PSK_WITH_RC4_128_SHA:
+        case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
+        case TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
+        case TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
+        case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
+        case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
+        case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
+        case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
+        case TLS_DHE_PSK_WITH_NULL_SHA256:
+        case TLS_DHE_PSK_WITH_NULL_SHA384:
+            return TLS_DHE_PSK;
+
+        case TLS_RSA_PSK_WITH_NULL_SHA:
+        case TLS_RSA_PSK_WITH_RC4_128_SHA:
+        case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
+        case TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
+        case TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
+        case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
+        case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
+        case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
+        case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
+        case TLS_RSA_PSK_WITH_NULL_SHA256:
+        case TLS_RSA_PSK_WITH_NULL_SHA384:
+            return TLS_RSA_PSK;
+
         default:
         default:
-            sslErrorLog("Invalid cipherSuite %02hX", cipherSuite);
-            assert(0);
             return SSL_NULL_auth;
     }
 }
             return SSL_NULL_auth;
     }
 }
@@ -622,13 +293,12 @@ static SSL_SignatureAlgorithm sslCipherSuiteGetSignatureAlgorithm(SSLCipherSuite
         case SSL_ECDH_ECDSA:
             return SSL_SignatureAlgorithmECDSA;
         default:
         case SSL_ECDH_ECDSA:
             return SSL_SignatureAlgorithmECDSA;
         default:
-            sslErrorLog("Invalid cipherSuite %02hX", cipherSuite);
-            assert(0);
             return SSL_SignatureAlgorithmAnonymous;
     }
 }
 #endif
 
             return SSL_SignatureAlgorithmAnonymous;
     }
 }
 #endif
 
+#if 0
 static SSLProtocolVersion sslCipherSuiteGetMinSupportedTLSVersion(SSLCipherSuite cipherSuite) {
     switch (cipherSuite) {
         case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
 static SSLProtocolVersion sslCipherSuiteGetMinSupportedTLSVersion(SSLCipherSuite cipherSuite) {
     switch (cipherSuite) {
         case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
@@ -745,16 +415,15 @@ static SSLProtocolVersion sslCipherSuiteGetMinSupportedTLSVersion(SSLCipherSuite
         case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
             return TLS_Version_1_2;
         default:
         case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
             return TLS_Version_1_2;
         default:
-            sslErrorLog("Invalid cipherSuite %02hX", cipherSuite);
-            assert(0);
             return TLS_Version_1_2;
     }
 }
             return TLS_Version_1_2;
     }
 }
+#endif
 
 
-static SSL_HashAlgorithm sslCipherSuiteGetHashAlgorithm(SSLCipherSuite cipherSuite) {
+HMAC_Algs sslCipherSuiteGetMacAlgorithm(SSLCipherSuite cipherSuite) {
     switch (cipherSuite) {
         case TLS_NULL_WITH_NULL_NULL:
     switch (cipherSuite) {
         case TLS_NULL_WITH_NULL_NULL:
-            return SSL_HashAlgorithmNone;
+            return HA_Null;
         case SSL_RSA_WITH_RC2_CBC_MD5:
         case SSL_RSA_WITH_DES_CBC_MD5:
         case SSL_RSA_WITH_3DES_EDE_CBC_MD5:
         case SSL_RSA_WITH_RC2_CBC_MD5:
         case SSL_RSA_WITH_DES_CBC_MD5:
         case SSL_RSA_WITH_3DES_EDE_CBC_MD5:
@@ -764,7 +433,7 @@ static SSL_HashAlgorithm sslCipherSuiteGetHashAlgorithm(SSLCipherSuite cipherSui
         case TLS_RSA_WITH_RC4_128_MD5:
         case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
         case TLS_DH_anon_WITH_RC4_128_MD5:
         case TLS_RSA_WITH_RC4_128_MD5:
         case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
         case TLS_DH_anon_WITH_RC4_128_MD5:
-            return SSL_HashAlgorithmMD5;
+            return HA_MD5;
         case TLS_RSA_WITH_NULL_SHA:
         case SSL_RSA_WITH_IDEA_CBC_SHA:
         case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
         case TLS_RSA_WITH_NULL_SHA:
         case SSL_RSA_WITH_IDEA_CBC_SHA:
         case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
@@ -825,7 +494,22 @@ static SSL_HashAlgorithm sslCipherSuiteGetHashAlgorithm(SSLCipherSuite cipherSui
         case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
         case TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
         case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
         case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
         case TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
         case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
-            return SSL_HashAlgorithmSHA1;
+        case TLS_PSK_WITH_NULL_SHA:
+        case TLS_PSK_WITH_RC4_128_SHA:
+        case TLS_PSK_WITH_3DES_EDE_CBC_SHA:
+        case TLS_PSK_WITH_AES_128_CBC_SHA:
+        case TLS_PSK_WITH_AES_256_CBC_SHA:
+        case TLS_DHE_PSK_WITH_NULL_SHA:
+        case TLS_DHE_PSK_WITH_RC4_128_SHA:
+        case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
+        case TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
+        case TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
+        case TLS_RSA_PSK_WITH_NULL_SHA:
+        case TLS_RSA_PSK_WITH_RC4_128_SHA:
+        case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
+        case TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
+        case TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
+            return HA_SHA1;
         case TLS_RSA_WITH_NULL_SHA256:
         case TLS_RSA_WITH_AES_128_CBC_SHA256:
         case TLS_RSA_WITH_AES_256_CBC_SHA256:
         case TLS_RSA_WITH_NULL_SHA256:
         case TLS_RSA_WITH_AES_128_CBC_SHA256:
         case TLS_RSA_WITH_AES_256_CBC_SHA256:
@@ -853,7 +537,16 @@ static SSL_HashAlgorithm sslCipherSuiteGetHashAlgorithm(SSLCipherSuite cipherSui
         case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
         case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
         case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
         case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
         case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
         case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
-            return SSL_HashAlgorithmSHA256;
+        case TLS_PSK_WITH_AES_128_GCM_SHA256:
+        case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
+        case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
+        case TLS_PSK_WITH_AES_128_CBC_SHA256:
+        case TLS_PSK_WITH_NULL_SHA256:
+        case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
+        case TLS_DHE_PSK_WITH_NULL_SHA256:
+        case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
+        case TLS_RSA_PSK_WITH_NULL_SHA256:
+            return HA_SHA256;
         case TLS_RSA_WITH_AES_256_GCM_SHA384:
         case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
         case TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
         case TLS_RSA_WITH_AES_256_GCM_SHA384:
         case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
         case TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
@@ -868,175 +561,35 @@ static SSL_HashAlgorithm sslCipherSuiteGetHashAlgorithm(SSLCipherSuite cipherSui
         case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
         case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
         case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
         case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
         case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
         case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
-            return SSL_HashAlgorithmSHA384;
+        case TLS_PSK_WITH_AES_256_GCM_SHA384:
+        case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
+        case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
+        case TLS_PSK_WITH_AES_256_CBC_SHA384:
+        case TLS_PSK_WITH_NULL_SHA384:
+        case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
+        case TLS_DHE_PSK_WITH_NULL_SHA384:
+        case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
+        case TLS_RSA_PSK_WITH_NULL_SHA384:
+            return HA_SHA384;
         default:
         default:
-            sslErrorLog("Invalid cipherSuite %02hX", cipherSuite);
-            assert(0);
-            return SSL_HashAlgorithmNone;
+            return HA_Null;
     }
 }
 
     }
 }
 
-static const HashHmacReference* sslCipherSuiteGetHashHmacReference(SSLCipherSuite cipherSuite) {
-    switch (sslCipherSuiteGetHashAlgorithm(cipherSuite)) {
-        case SSL_HashAlgorithmNone:
-            return &HashHmacNull;
-        case SSL_HashAlgorithmMD5:
-            return &HashHmacMD5;
-        case SSL_HashAlgorithmSHA1:
-            return &HashHmacSHA1;
-        case SSL_HashAlgorithmSHA256:
-            return &HashHmacSHA256;
-        case SSL_HashAlgorithmSHA384:
-            return &HashHmacSHA384;
-        default:
-            sslErrorLog("Invalid hashAlgorithm %02hX", cipherSuite);
-            assert(0);
-            return &HashHmacNull;
-    }
-}
-
-static const SSLSymmetricCipher *sslCipherSuiteGetSymmetricCipher(SSLCipherSuite cipherSuite) {
-    switch (cipherSuite) {
-        case TLS_NULL_WITH_NULL_NULL:
-        case TLS_RSA_WITH_NULL_MD5:
-        case TLS_RSA_WITH_NULL_SHA:
-        case TLS_RSA_WITH_NULL_SHA256:
-        case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
-        case TLS_ECDH_ECDSA_WITH_NULL_SHA:
-        case TLS_ECDHE_ECDSA_WITH_NULL_SHA:
-        case TLS_ECDH_RSA_WITH_NULL_SHA:
-        case TLS_ECDHE_RSA_WITH_NULL_SHA:
-        case TLS_ECDH_anon_WITH_NULL_SHA:
-            return &SSLCipherNull;
-#if ENABLE_RC4
-        case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
-        case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
-            return &SSLCipherRC4_40;
-#endif
-#if ENABLE_RC2
-        case SSL_RSA_WITH_RC2_CBC_MD5:
-        case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
-            return &SSLCipherRC2_40;
-#endif
-#if ENABLE_IDEA
-        case SSL_RSA_WITH_IDEA_CBC_SHA:
-            return &SSLCipherIDEA_CBC;
-#endif
-#if ENABLE_DES
-        case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
-        case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
-        case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
-        case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
-        case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
-        case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
-            return &SSLCipherDES40_CBC;
-        case SSL_RSA_WITH_DES_CBC_MD5:
-        case SSL_RSA_WITH_DES_CBC_SHA:
-        case SSL_DH_DSS_WITH_DES_CBC_SHA:
-        case SSL_DH_RSA_WITH_DES_CBC_SHA:
-        case SSL_DHE_DSS_WITH_DES_CBC_SHA:
-        case SSL_DHE_RSA_WITH_DES_CBC_SHA:
-        case SSL_DH_anon_WITH_DES_CBC_SHA:
-            return &SSLCipherDES_CBC;
-#endif
-#if ENABLE_FORTEZZA
-        case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
-            return &SSLCipherFORTEZZA_CBC;
-#endif
-#if ENABLE_RC4
-        case TLS_RSA_WITH_RC4_128_MD5:
-        case TLS_RSA_WITH_RC4_128_SHA:
-        case TLS_DH_anon_WITH_RC4_128_MD5:
-        case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
-        case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
-        case TLS_ECDH_RSA_WITH_RC4_128_SHA:
-        case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
-        case TLS_ECDH_anon_WITH_RC4_128_SHA:
-            return &SSLCipherRC4_128;
-#endif
-        case SSL_RSA_WITH_3DES_EDE_CBC_MD5:
-        case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
-        case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
-        case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
-        case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
-        case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
-        case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA:
-        case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
-        case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
-        case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
-        case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
-        case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
-            return &SSLCipher3DES_CBC;
-        case TLS_RSA_WITH_AES_128_CBC_SHA:
-        case TLS_RSA_WITH_AES_128_CBC_SHA256:
-        case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
-        case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
-        case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
-        case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
-        case TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
-        case TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
-        case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
-        case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
-        case TLS_DH_anon_WITH_AES_128_CBC_SHA:
-        case TLS_DH_anon_WITH_AES_128_CBC_SHA256:
-        case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
-        case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
-        case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
-        case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
-        case TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
-        case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
-        case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
-        case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
-        case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
-            return &SSLCipherAES_128_CBC;
-        case TLS_RSA_WITH_AES_256_CBC_SHA:
-        case TLS_RSA_WITH_AES_256_CBC_SHA256:
-        case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
-        case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
-        case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
-        case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
-        case TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
-        case TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
-        case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
-        case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
-        case TLS_DH_anon_WITH_AES_256_CBC_SHA:
-        case TLS_DH_anon_WITH_AES_256_CBC_SHA256:
-        case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
-        case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
-        case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
-        case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
-        case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
-        case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
-        case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
-        case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
-        case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
-            return &SSLCipherAES_256_CBC;
-        case TLS_RSA_WITH_AES_128_GCM_SHA256:
-        case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
-        case TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
-        case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
-        case TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
-        case TLS_DH_anon_WITH_AES_128_GCM_SHA256:
-        case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
-        case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
-        case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
-        case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
-            return &SSLCipherAES_128_GCM;
-        case TLS_RSA_WITH_AES_256_GCM_SHA384:
-        case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
-        case TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
-        case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
-        case TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
-        case TLS_DH_anon_WITH_AES_256_GCM_SHA384:
-        case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
-        case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
-        case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
-        case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
-            return &SSLCipherAES_256_GCM;
+uint8_t sslCipherSuiteGetMacSize(SSLCipherSuite cipherSuite) {
+    switch (sslCipherSuiteGetMacAlgorithm(cipherSuite)) {
+        case HA_Null:
+            return 0;
+        case HA_MD5:
+            return 16;
+        case HA_SHA1:
+            return 20;
+        case HA_SHA256:
+            return 32;
+        case HA_SHA384:
+            return 48;
         default:
         default:
-            sslErrorLog("Invalid cipherSuite %02hX", cipherSuite);
-            assert(0);
-            return &SSLCipherNull;
+            return 0;
     }
 }
 
     }
 }
 
@@ -1052,6 +605,15 @@ SSL_CipherAlgorithm sslCipherSuiteGetSymmetricCipherAlgorithm(SSLCipherSuite cip
         case TLS_ECDH_RSA_WITH_NULL_SHA:
         case TLS_ECDHE_RSA_WITH_NULL_SHA:
         case TLS_ECDH_anon_WITH_NULL_SHA:
         case TLS_ECDH_RSA_WITH_NULL_SHA:
         case TLS_ECDHE_RSA_WITH_NULL_SHA:
         case TLS_ECDH_anon_WITH_NULL_SHA:
+        case TLS_PSK_WITH_NULL_SHA:
+        case TLS_DHE_PSK_WITH_NULL_SHA:
+        case TLS_RSA_PSK_WITH_NULL_SHA:
+        case TLS_PSK_WITH_NULL_SHA256:
+        case TLS_PSK_WITH_NULL_SHA384:
+        case TLS_DHE_PSK_WITH_NULL_SHA256:
+        case TLS_DHE_PSK_WITH_NULL_SHA384:
+        case TLS_RSA_PSK_WITH_NULL_SHA256:
+        case TLS_RSA_PSK_WITH_NULL_SHA384:
             return SSL_CipherAlgorithmNull;
         case SSL_RSA_WITH_RC2_CBC_MD5:
             return SSL_CipherAlgorithmRC2_128;
             return SSL_CipherAlgorithmNull;
         case SSL_RSA_WITH_RC2_CBC_MD5:
             return SSL_CipherAlgorithmRC2_128;
@@ -1071,6 +633,9 @@ SSL_CipherAlgorithm sslCipherSuiteGetSymmetricCipherAlgorithm(SSLCipherSuite cip
         case TLS_ECDH_RSA_WITH_RC4_128_SHA:
         case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
         case TLS_ECDH_anon_WITH_RC4_128_SHA:
         case TLS_ECDH_RSA_WITH_RC4_128_SHA:
         case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
         case TLS_ECDH_anon_WITH_RC4_128_SHA:
+        case TLS_PSK_WITH_RC4_128_SHA:
+        case TLS_DHE_PSK_WITH_RC4_128_SHA:
+        case TLS_RSA_PSK_WITH_RC4_128_SHA:
             return SSL_CipherAlgorithmRC4_128;
         case SSL_RSA_WITH_3DES_EDE_CBC_MD5:
         case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
             return SSL_CipherAlgorithmRC4_128;
         case SSL_RSA_WITH_3DES_EDE_CBC_MD5:
         case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
@@ -1084,6 +649,9 @@ SSL_CipherAlgorithm sslCipherSuiteGetSymmetricCipherAlgorithm(SSLCipherSuite cip
         case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
         case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
         case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
         case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
         case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
         case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
+        case TLS_PSK_WITH_3DES_EDE_CBC_SHA:
+        case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
+        case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
             return SSL_CipherAlgorithm3DES_CBC;
         case TLS_RSA_WITH_AES_128_CBC_SHA:
         case TLS_RSA_WITH_AES_128_CBC_SHA256:
             return SSL_CipherAlgorithm3DES_CBC;
         case TLS_RSA_WITH_AES_128_CBC_SHA:
         case TLS_RSA_WITH_AES_128_CBC_SHA256:
@@ -1106,6 +674,12 @@ SSL_CipherAlgorithm sslCipherSuiteGetSymmetricCipherAlgorithm(SSLCipherSuite cip
         case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
         case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
         case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
         case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
         case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
         case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
+        case TLS_PSK_WITH_AES_128_CBC_SHA:
+        case TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
+        case TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
+        case TLS_PSK_WITH_AES_128_CBC_SHA256:
+        case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
+        case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
             return SSL_CipherAlgorithmAES_128_CBC;
         case TLS_RSA_WITH_AES_256_CBC_SHA:
         case TLS_RSA_WITH_AES_256_CBC_SHA256:
             return SSL_CipherAlgorithmAES_128_CBC;
         case TLS_RSA_WITH_AES_256_CBC_SHA:
         case TLS_RSA_WITH_AES_256_CBC_SHA256:
@@ -1128,6 +702,12 @@ SSL_CipherAlgorithm sslCipherSuiteGetSymmetricCipherAlgorithm(SSLCipherSuite cip
         case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
         case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
         case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
         case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
         case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
         case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
+        case TLS_PSK_WITH_AES_256_CBC_SHA:
+        case TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
+        case TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
+        case TLS_PSK_WITH_AES_256_CBC_SHA384:
+        case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
+        case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
             return SSL_CipherAlgorithmAES_256_CBC;
         case TLS_RSA_WITH_AES_128_GCM_SHA256:
         case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
             return SSL_CipherAlgorithmAES_256_CBC;
         case TLS_RSA_WITH_AES_128_GCM_SHA256:
         case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
@@ -1139,6 +719,9 @@ SSL_CipherAlgorithm sslCipherSuiteGetSymmetricCipherAlgorithm(SSLCipherSuite cip
         case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
         case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
         case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
         case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
         case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
         case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
+        case TLS_PSK_WITH_AES_128_GCM_SHA256:
+        case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
+        case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
             return SSL_CipherAlgorithmAES_128_GCM;
         case TLS_RSA_WITH_AES_256_GCM_SHA384:
         case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
             return SSL_CipherAlgorithmAES_128_GCM;
         case TLS_RSA_WITH_AES_256_GCM_SHA384:
         case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
@@ -1150,440 +733,58 @@ SSL_CipherAlgorithm sslCipherSuiteGetSymmetricCipherAlgorithm(SSLCipherSuite cip
         case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
         case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
         case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
         case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
         case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
         case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
+        case TLS_PSK_WITH_AES_256_GCM_SHA384:
+        case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
+        case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
             return SSL_CipherAlgorithmAES_256_GCM;
         default:
             return SSL_CipherAlgorithmNull;
     }
 }
 
             return SSL_CipherAlgorithmAES_256_GCM;
         default:
             return SSL_CipherAlgorithmNull;
     }
 }
 
-/*
- * Given a valid ctx->validCipherSpecs array, calculate how many of those
- * cipherSpecs are *not* SSLv2 only, storing result in
- * ctx->numValidNonSSLv2Specs. ClientHello routines need this to set
- * up outgoing cipherSpecs arrays correctly.
- *
- * Also determines if any ECDSA/ECDH ciphers are enabled; we need to know
- * that when creating a hello message.
- */
-static void sslAnalyzeCipherSpecs(SSLContext *ctx)
-{
-       unsigned                dex;
-       const SSLCipherSuite *cipherSuite;
-
-#if ENABLE_SSLV2
-       ctx->numValidNonSSLv2Suites = 0;
-#endif
-       cipherSuite = &ctx->validCipherSuites[0];
-       ctx->ecdsaEnable = false;
-       for(dex=0; dex<ctx->numValidCipherSuites; dex++, cipherSuite++) {
-#if ENABLE_SSLV2
-               if(!CIPHER_SPEC_IS_SSLv2(*cipherSuite)) {
-                       ctx->numValidNonSSLv2Suites++;
-               }
-#endif
-               switch(sslCipherSuiteGetKeyExchangeMethod(*cipherSuite)) {
-                       case SSL_ECDH_ECDSA:
-                       case SSL_ECDHE_ECDSA:
-                       case SSL_ECDH_RSA:
-                       case SSL_ECDHE_RSA:
-                       case SSL_ECDH_anon:
-                               ctx->ecdsaEnable = true;
-                               break;
-                       default:
-                               break;
-               }
-       }
-}
-
-/*
- * Build ctx->validCipherSpecs as a copy of KnownCipherSpecs, assuming that
- * validCipherSpecs is currently not valid (i.e., SSLSetEnabledCiphers() has
- * not been called).
- */
-OSStatus sslBuildCipherSuiteArray(SSLContext *ctx)
-{
-       size_t          size;
-       unsigned        dex;
-
-       assert(ctx != NULL);
-       assert(ctx->validCipherSuites == NULL);
-
-       ctx->numValidCipherSuites = CipherSuiteCount;
-       size = CipherSuiteCount * sizeof(SSLCipherSpec);
-       ctx->validCipherSuites = (SSLCipherSuite *)sslMalloc(size);
-       if(ctx->validCipherSuites == NULL) {
-               ctx->numValidCipherSuites = 0;
-               return memFullErr;
-       }
-
-       /*
-        * Trim out inappropriate ciphers:
-        *  -- trim anonymous ciphers if !ctx->anonCipherEnable (default)
-        *  -- trim ECDSA ciphers for server side if appropriate
-        *  -- trim ECDSA ciphers if TLSv1 disable or SSLv2 enabled (since
-        *     we MUST do the Client Hello extensions to make these ciphers
-        *     work reliably)
-        *  -- trim 40 and 56-bit ciphers if !ctx->weakCipherEnable (default)
-        *  -- trim ciphers incompatible with our private key in server mode
-        *  -- trim RC4 ciphers if DTLSv1 enable
-        */
-       SSLCipherSuite *dst = ctx->validCipherSuites;
-       const SSLCipherSuite *src = KnownCipherSuites;
-
-       bool trimECDSA = false;
-       if((ctx->protocolSide == kSSLServerSide) && !SSL_ECDSA_SERVER) {
-               trimECDSA = true;
-       }
-       if(ctx->minProtocolVersion == SSL_Version_2_0
-       || ctx->maxProtocolVersion == SSL_Version_3_0) {
-        /* We trim ECDSA cipher suites if SSL2 is enabled or
-           The maximum allowed protocol is SSL3.  Note that this
-           won't trim ECDSA cipherspecs for DTLS which should be
-           the right thing to do here. */
-               trimECDSA = true;
-       }
-
-    bool trimRC4 = ctx->isDTLS;
-
-    bool trimDHE = (ctx->protocolSide == kSSLServerSide) &&
-        !ctx->dhParamsEncoded.length;
-
-       for(dex=0; dex<CipherSuiteCount; dex++) {
-        KeyExchangeMethod kem = sslCipherSuiteGetKeyExchangeMethod(*src);
-        const SSLSymmetricCipher *cipher = sslCipherSuiteGetSymmetricCipher(*src);
-        SSLProtocolVersion minVersion = sslCipherSuiteGetMinSupportedTLSVersion(*src);
-
-        /* Trim according to supported versions */
-        if(((ctx->isDTLS) && (minVersion>TLS_Version_1_1)) ||  /* DTLS is like TLS.1.1 */
-            (minVersion > ctx->maxProtocolVersion))
-        {
-            ctx->numValidCipherSuites--;
-            src++;
-            continue;
-        }
-
-        /* First skip ECDSA ciphers as appropriate */
-               switch(kem) {
-                       case SSL_ECDH_ECDSA:
-                       case SSL_ECDHE_ECDSA:
-                       case SSL_ECDH_RSA:
-                       case SSL_ECDHE_RSA:
-                       case SSL_ECDH_anon:
-                               if(trimECDSA) {
-                                       /* Skip this one */
-                                       ctx->numValidCipherSuites--;
-                                       src++;
-                                       continue;
-                               }
-                               else {
-                                       break;
-                               }
-                       default:
-                               break;
-               }
-
-               if(!ctx->anonCipherEnable) {
-                       /* trim out the anonymous (and null-cipher) ciphers */
-                       if(cipher == &SSLCipherNull) {
-                               /* skip this one */
-                               ctx->numValidCipherSuites--;
-                               src++;
-                               continue;
-                       }
-                       switch(kem) {
-                               case SSL_DH_anon:
-                               case SSL_DH_anon_EXPORT:
-                               case SSL_ECDH_anon:
-                                       /* skip this one */
-                                       ctx->numValidCipherSuites--;
-                                       src++;
-                                       continue;
-                               default:
-                                       break;
-                       }
-               }
-
-               if (false
-                       /* trim out 40 and 56 bit ciphers (considered unsafe to use) */
-#if ENABLE_RC4
-                       || (cipher == &SSLCipherRC4_40)
-#endif
-#if ENABLE_RC2
-                       || (cipher == &SSLCipherRC2_40)
-#endif
-#if ENABLE_DES
-                       || (cipher == &SSLCipherDES_CBC)
-                       || (cipher == &SSLCipherDES40_CBC)
-#endif
-                       ) {
-                               /* skip this one */
-                               ctx->numValidCipherSuites--;
-                               src++;
-                               continue;
-               }
-
-               if(ctx->protocolSide == kSSLServerSide && ctx->signingPrivKeyRef != NULL) {
-                       /* in server mode, trim out ciphers incompatible with our private key */
-                       SSLCipherSpec testCipherSpec = {
-                               .cipherSpec = *src,
-                               .keyExchangeMethod = kem,
-                               .cipher = cipher
-                       };
-                       if(sslVerifySelectedCipher(ctx, &testCipherSpec) != noErr) {
-                               /* skip this one */
-                               ctx->numValidCipherSuites--;
-                               src++;
-                               continue;
-                       }
-               }
-
-        if (trimDHE) {
-                       switch(kem) {
-                               case SSL_DHE_DSS:
-                               case SSL_DHE_DSS_EXPORT:
-                               case SSL_DHE_RSA:
-                               case SSL_DHE_RSA_EXPORT:
-                                       /* skip this one */
-                                       ctx->numValidCipherSuites--;
-                                       src++;
-                                       continue;
-                               default:
-                                       break;
-                       }
-               }
-
-        if (trimRC4 && cipher && (cipher->keyAlg == kCCAlgorithmRC4)) {
-            ctx->numValidCipherSuites--;
-            src++;
-            continue;
-        }
-
-               /* This one is good to go */
-        *dst++ = *src++;
-       }
-       sslAnalyzeCipherSpecs(ctx);
-       return noErr;
-}
-
-/*
- * Convert an array of SSLCipherSuites (which is always KnownCipherSpecs)
- * to an array of SSLCipherSuites.
- */
-static OSStatus
-cipherSuitesToCipherSuites(
-                          size_t                               numCipherSuites,
-                          const SSLCipherSuite *cipherSuites,
-                          SSLCipherSuite               *ciphers,               /* RETURNED */
-                          size_t                               *numCiphers)    /* IN/OUT */
-{
-       if(*numCiphers < numCipherSuites) {
-               return errSSLBufferOverflow;
-       }
-    memcpy(ciphers, cipherSuites, numCipherSuites * sizeof(SSLCipherSuite));
-       *numCiphers = numCipherSuites;
-       return noErr;
-}
-
-/***
- *** Publicly 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,
-                                                         size_t                *numCiphers)
-{
-       if((ctx == NULL) || (numCiphers == NULL)) {
-               return paramErr;
-       }
-       *numCiphers = CipherSuiteCount;
-       return noErr;
-}
-
-OSStatus
-SSLGetSupportedCiphers          (SSLContextRef         ctx,
-                                                         SSLCipherSuite        *ciphers,               /* RETURNED */
-                                                         size_t                        *numCiphers)    /* IN/OUT */
-{
-       if((ctx == NULL) || (ciphers == NULL) || (numCiphers == NULL)) {
-               return paramErr;
-       }
-       return cipherSuitesToCipherSuites(CipherSuiteCount,
-               KnownCipherSuites,
-               ciphers,
-               numCiphers);
-}
-
-/*
- * Specify a (typically) 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,
-                                                        size_t                                 numCiphers)
-{
-       size_t          size;
-       unsigned                callerDex;
-       unsigned                validDex;
-       unsigned                tableDex;
-
-       if((ctx == NULL) || (ciphers == NULL) || (numCiphers == 0)) {
-               return paramErr;
-       }
-       if(sslIsSessionActive(ctx)) {
-               /* can't do this with an active session */
-               return badReqErr;
-       }
-       ctx->numValidCipherSuites = 0;
-       size = numCiphers * sizeof(SSLCipherSuite);
-       ctx->validCipherSuites = (SSLCipherSuite *)sslMalloc(size);
-       if(ctx->validCipherSuites == NULL) {
-               return memFullErr;
-       }
-
-       /*
-        * Run thru caller's specs, finding a matching SSLCipherSpec for each one.
-        * If caller specifies one we don't know about, skip it.
-        */
-       for(callerDex=0, validDex=0; callerDex<numCiphers; callerDex++) {
-               /* find matching CipherSpec in our known table */
-               int foundOne = 0;
-               for(tableDex=0; tableDex<CipherSuiteCount; tableDex++) {
-                       if(ciphers[callerDex] == KnownCipherSuites[tableDex]) {
-                ctx->validCipherSuites[validDex++] = KnownCipherSuites[tableDex];
-                               ctx->numValidCipherSuites++;
-                               foundOne = 1;
-                               break;
-                       }
-               }
-               if(!foundOne) {
-                       /* caller specified one we don't implement */
-            sslErrorLog("SSLSetEnabledCiphers: invalid cipher suite %04hX",
-                               ciphers[callerDex]);
-                       #if 0
-                       sslFree(ctx->validCipherSuites);
-                       ctx->validCipherSuites = NULL;
-                       ctx->numValidCipherSuites = 0;
-                       return errSSLBadCipherSuite;
-                       #endif
-               }
-       }
-
-       /* success */
-       sslAnalyzeCipherSpecs(ctx);
-       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,
-                                                        size_t                                 *numCiphers)
-{
-       if((ctx == NULL) || (numCiphers == NULL)) {
-               return paramErr;
-       }
-       if(ctx->validCipherSuites == NULL) {
-               /* hasn't been set; build default array temporarily */
-               OSStatus status = sslBuildCipherSuiteArray(ctx);
-               if(!status) {
-                       *numCiphers = ctx->numValidCipherSuites;
-                       /* put things back as we found them */
-                       sslFree(ctx->validCipherSuites);
-                       ctx->validCipherSuites = NULL;
-                       ctx->numValidCipherSuites = 0;
-               } else {
-                       /* unable to build default array; use known cipher count */
-                       *numCiphers = CipherSuiteCount;
-               }
-       }
-       else {
-               /* caller set via SSLSetEnabledCiphers */
-               *numCiphers = ctx->numValidCipherSuites;
-       }
-       return noErr;
-}
-
-OSStatus
-SSLGetEnabledCiphers           (SSLContextRef                  ctx,
-                                                        SSLCipherSuite                 *ciphers,               /* RETURNED */
-                                                        size_t                                 *numCiphers)    /* IN/OUT */
-{
-       if((ctx == NULL) || (ciphers == NULL) || (numCiphers == NULL)) {
-               return paramErr;
-       }
-       if(ctx->validCipherSuites == NULL) {
-               /* hasn't been set; build default array temporarily */
-               OSStatus status = sslBuildCipherSuiteArray(ctx);
-               if(!status) {
-                       status = cipherSuitesToCipherSuites(ctx->numValidCipherSuites,
-                               ctx->validCipherSuites,
-                               ciphers,
-                               numCiphers);
-                       /* put things back as we found them */
-                       sslFree(ctx->validCipherSuites);
-                       ctx->validCipherSuites = NULL;
-                       ctx->numValidCipherSuites = 0;
-               } else {
-                       /* unable to build default array; use known cipher suite array */
-                       status = cipherSuitesToCipherSuites(CipherSuiteCount,
-                               KnownCipherSuites,
-                               ciphers,
-                               numCiphers);
-               }
-               return status;
-       }
-       else {
-               /* use the ones specified in SSLSetEnabledCiphers() */
-               return cipherSuitesToCipherSuites(ctx->numValidCipherSuites,
-                       ctx->validCipherSuites,
-                       ciphers,
-                       numCiphers);
-       }
+uint8_t sslCipherSuiteGetSymmetricCipherKeySize(SSLCipherSuite cipherSuite) {
+    SSL_CipherAlgorithm alg = sslCipherSuiteGetSymmetricCipherAlgorithm(cipherSuite);
+
+    switch (alg) {
+        case SSL_CipherAlgorithmNull:
+            return 0;
+        case SSL_CipherAlgorithmDES_CBC:
+            return 8;
+        case SSL_CipherAlgorithmRC2_128:
+        case SSL_CipherAlgorithmRC4_128:
+        case SSL_CipherAlgorithmAES_128_CBC:
+        case SSL_CipherAlgorithmAES_128_GCM:
+            return 16;
+        case SSL_CipherAlgorithm3DES_CBC:
+            return 24;
+        case SSL_CipherAlgorithmAES_256_CBC:
+        case SSL_CipherAlgorithmAES_256_GCM:
+            return 32;
+        default:
+            return 0;
+    }
 }
 
 }
 
-/***
- *** End of publically exported functions declared in SecureTransport.h
- ***/
 
 
-void InitCipherSpec(SSLContext *ctx)
-{
-    SSLCipherSpec *dst = &ctx->selectedCipherSpec;
-    dst->cipherSpec = ctx->selectedCipher;
-    dst->cipher = sslCipherSuiteGetSymmetricCipher(ctx->selectedCipher);
-    dst->isExportable = dst->cipher->secretKeySize < 6 ? Exportable : NotExportable;
-    dst->keyExchangeMethod = sslCipherSuiteGetKeyExchangeMethod(ctx->selectedCipher);
-    dst->macAlgorithm = sslCipherSuiteGetHashHmacReference(ctx->selectedCipher);
-};
-
-OSStatus
-FindCipherSpec(SSLContext *ctx)
-{
-       unsigned i;
-
-    assert(ctx != NULL);
-    assert(ctx->validCipherSuites != NULL);
-
-    for (i=0; i<ctx->numValidCipherSuites; i++)
-    {
-        if (ctx->validCipherSuites[i] == ctx->selectedCipher) {
-            InitCipherSpec(ctx);
-            /* make sure we're configured to handle this one */
-            return sslVerifySelectedCipher(ctx, &ctx->selectedCipherSpec);
-        }
+/* Same function for block and iv size */
+uint8_t sslCipherSuiteGetSymmetricCipherBlockIvSize(SSLCipherSuite cipherSuite) {
+    SSL_CipherAlgorithm alg = sslCipherSuiteGetSymmetricCipherAlgorithm(cipherSuite);
+
+    switch (alg) {
+        case SSL_CipherAlgorithmNull:
+        case SSL_CipherAlgorithmRC4_128:
+            return 0;
+        case SSL_CipherAlgorithmDES_CBC:
+        case SSL_CipherAlgorithm3DES_CBC:
+        case SSL_CipherAlgorithmRC2_128:
+            return 8;
+        case SSL_CipherAlgorithmAES_128_CBC:
+        case SSL_CipherAlgorithmAES_128_GCM:
+        case SSL_CipherAlgorithmAES_256_CBC:
+        case SSL_CipherAlgorithmAES_256_GCM:
+            return 16;
+        default:
+            return 0;
     }
     }
-    /* Not found */
-    return errSSLNegotiation;
 }
 }
+
index a41364359e6b9d1b6633ba50b33463c83d94a864..4e51a81e1458ef4f01b6b01e331954eb42831ef2 100644 (file)
@@ -31,9 +31,6 @@
 #include <stdint.h>
 #include "CipherSuite.h"
 
 #include <stdint.h>
 #include "CipherSuite.h"
 
-#include "sslContext.h"
-#include "cryptType.h"
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -51,25 +48,53 @@ typedef enum {
     SSL_CipherAlgorithmAES_256_GCM,
 } SSL_CipherAlgorithm;
 
     SSL_CipherAlgorithmAES_256_GCM,
 } SSL_CipherAlgorithm;
 
-SSL_CipherAlgorithm sslCipherSuiteGetSymmetricCipherAlgorithm(SSLCipherSuite cipherSuite);
+/* The HMAC algorithms we support */
+typedef enum {
+    HA_Null = 0,               // i.e., uninitialized
+    HA_SHA1,
+    HA_MD5,
+    HA_SHA256,
+    HA_SHA384
+} HMAC_Algs;
 
 
-/*
- * Build ctx->validCipherSuites as a copy of all known CipherSpecs.
- */
-extern OSStatus sslBuildCipherSuiteArray(SSLContext *ctx);
+typedef enum
+{   SSL_NULL_auth,
+    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,
 
 
-/*
- * Initialize ctx->selectedCipherSpec based on ctx->selectedCipher.
- * ctx->selectedCipher MUST be a valid supported cipherSuite.
- */
-void InitCipherSpec(SSLContext *ctx);
+    /* ECDSA addenda, RFC 4492 */
+    SSL_ECDH_ECDSA,
+    SSL_ECDHE_ECDSA,
+    SSL_ECDH_RSA,
+    SSL_ECDHE_RSA,
+    SSL_ECDH_anon,
 
 
-/*
- * Given a valid ctx->selectedCipher and ctx->validCipherSuites, set
- * ctx->selectedCipherSpec as appropriate. Return an error if
- * ctx->selectedCipher could not be set as the current ctx->selectedCipherSpec.
- */
-OSStatus FindCipherSpec(SSLContext *ctx);
+    /* PSK, RFC 4279 */
+    TLS_PSK,
+    TLS_DHE_PSK,
+    TLS_RSA_PSK,
+    
+} KeyExchangeMethod;
+
+
+HMAC_Algs sslCipherSuiteGetMacAlgorithm(SSLCipherSuite cipherSuite);
+SSL_CipherAlgorithm sslCipherSuiteGetSymmetricCipherAlgorithm(SSLCipherSuite cipherSuite);
+KeyExchangeMethod sslCipherSuiteGetKeyExchangeMethod(SSLCipherSuite cipherSuite);
+
+uint8_t sslCipherSuiteGetMacSize(SSLCipherSuite cipherSuite);
+uint8_t sslCipherSuiteGetSymmetricCipherKeySize(SSLCipherSuite cipherSuite);
+uint8_t sslCipherSuiteGetSymmetricCipherBlockIvSize(SSLCipherSuite cipherSuite);
 
 /*
  * Determine if an SSLCipherSuite is SSLv2 only.
 
 /*
  * Determine if an SSLCipherSuite is SSLv2 only.
index 79e966bff7c6d81e5d5d364cd10d3e4791912ab7..5424a69abb98c621fbd29a473b23f14e226e4522 100644 (file)
  */
 
 /*
  */
 
 /*
- * cryptType.h - Crypto structures and routines
+ * cryptType.h - CipherSpec and CipherContext structures
  */
 
 #ifndef _CRYPTTYPE_H_
 #define _CRYPTTYPE_H_ 1
 
  */
 
 #ifndef _CRYPTTYPE_H_
 #define _CRYPTTYPE_H_ 1
 
-#include <Security/CipherSuite.h>
-#include "sslPriv.h"
-#include "sslContext.h"
+// #include <Security/CipherSuite.h>
 #include "tls_hmac.h"
 #include "tls_hmac.h"
-#include <CommonCrypto/CommonCryptor.h>
+#include "tls_hashhmac.h"
+#include "symCipher.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 
 #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;
-
-typedef OSStatus (*HashInit)(SSLBuffer *digestCtx, SSLContext *sslCtx);
-typedef OSStatus (*HashUpdate)(SSLBuffer *digestCtx, const SSLBuffer *data);
-/* HashFinal also does HashClose */
-typedef OSStatus (*HashFinal)(SSLBuffer *digestCtx, SSLBuffer *digest);
-typedef OSStatus (*HashClose)(SSLBuffer *digestCtx, SSLContext *sslCtx);
-typedef OSStatus (*HashClone)(const SSLBuffer *src, SSLBuffer *dest);
-typedef struct
-{   UInt32      contextSize;
-    UInt32      digestSize;
-    UInt32      macPadSize;
-    HashInit    init;
-    HashUpdate  update;
-    HashFinal   final;
-       HashClose       close;
-    HashClone   clone;
-} HashReference;
-
 /*
 /*
- * TLS addenda:
- *     -- new struct HashHmacReference
- *     -- structs which used to use HashReference now use HashHmacReference
- *     -- new union HashHmacContext, used in CipherContext.
+ * An SSLRecordContext contains four of these - one for each of {read,write} and for
+ * {current, pending}.
  */
  */
-typedef struct {
-       const HashReference     *hash;
-       const HMACReference     *hmac;
-} HashHmacReference;
-
-typedef union {
-       SSLBuffer                       hashCtx;
-       HMACContextRef          hmacCtx;
-} HashHmacContext;
-
-/* these are declared in tls_hmac.c */
-extern const HashHmacReference HashHmacNull;
-extern const HashHmacReference HashHmacMD5;
-extern const HashHmacReference HashHmacSHA1;
-extern const HashHmacReference HashHmacSHA256;
-extern const HashHmacReference HashHmacSHA384;
+typedef struct CipherContext
+{
+    const HashHmacReference    *macRef;                        /* HMAC (TLS) or digest (SSL) */
+    const SSLSymmetricCipher   *symCipher;
 
 
-/*
- * Hack to avoid circular dependency with tls_ssl.h.
- */
-struct _SslTlsCallouts;
+    /* this is a context which is reused once per record */
+    HashHmacContext                            macCtx;
+    /*
+     * Crypto context (eg: for CommonCrypto-based symmetric ciphers, this will be a CCCryptorRef)
+     */
+    SymCipherContext            cipherCtx;
 
 
-/*
- * All symmetric ciphers go thru CDSA, via these callouts.
- */
-struct CipherContext;
-typedef struct CipherContext CipherContext;
+    /* encrypt or decrypt. needed in CDSASymmInit, may not be needed anymore (TODO)*/
+    uint8_t                                            encrypting;
 
 
-typedef OSStatus (*SSLKeyFunc)(
-       uint8_t *key,
-       uint8_t *iv,
-       CipherContext *cipherCtx,
-       SSLContext *ctx);
-typedef OSStatus (*SSLCryptFunc)(
-       const uint8_t *src,
-       uint8_t *dest,
-       size_t len,
-       CipherContext *cipherCtx,
-       SSLContext *ctx);
-typedef OSStatus (*SSLFinishFunc)(
-       CipherContext *cipherCtx,
-       SSLContext *ctx);
+    uint64_t                           sequenceNum;
+    uint8_t                                    ready;
 
 
-typedef enum
-{   NotExportable = 0,
-    Exportable = 1
-} Exportability;
+    /* in SSL2 mode, the macSecret is the same size as the
+     * cipher key - which is 24 bytes in the 3DES case. */
+    uint8_t                                            macSecret[48 /* SSL_MAX_DIGEST_LEN */];
+} CipherContext;
 
 
-/*
- * Statically defined description of a symmetric sipher.
- */
-typedef struct {
-    uint8_t            keySize;            /* Sizes are in bytes */
-    uint8_t            secretKeySize;
-    uint8_t            ivSize;
-    uint8_t            blockSize;
-    CCAlgorithm         keyAlg;
-    SSLKeyFunc         initialize;
-    SSLCryptFunc       encrypt;
-    SSLCryptFunc       decrypt;
-    SSLFinishFunc      finish;
-} SSLSymmetricCipher;
-
-#define MAX_MAC_PADDING        48      /* MD5 MAC padding size = 48 bytes */
-#define MASTER_SECRET_LEN      48      /* master secret = 3 x MD5 hashes concatenated */
-
-/* SSL V2 - mac secret is the size of symmetric key, not digest */
-#define MAX_SYMKEY_SIZE                24
-
-typedef enum
-{   SSL_NULL_auth,
-    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,
-
-       /* ECDSA addenda, RFC 4492 */
-       SSL_ECDH_ECDSA,
-       SSL_ECDHE_ECDSA,
-       SSL_ECDH_RSA,
-       SSL_ECDHE_RSA,
-       SSL_ECDH_anon
-} KeyExchangeMethod;
-
-typedef struct {
-    SSLCipherSuite                     cipherSpec;
-    Exportability                      isExportable;
-    KeyExchangeMethod                  keyExchangeMethod;
-    const HashHmacReference     *macAlgorithm;
-    const SSLSymmetricCipher   *cipher;
-} SSLCipherSpec;
-
-extern const SSLCipherMapping SSL2CipherMap[];
-extern const unsigned SSL2CipherMapCount;
-
-/* Default size of server-generated Diffie-Hellman parameters and keys */
-#ifdef NDEBUG
-#define SSL_DH_DEFAULT_PRIME_SIZE      1024                    /* in bits */
-#else
-#define SSL_DH_DEFAULT_PRIME_SIZE      512                             /* in bits */
-#endif
-#define SSL_DH_DEFAULT_GENERATOR    2               /* only embedded uses this */
 #ifdef __cplusplus
 }
 #endif
 #ifdef __cplusplus
 }
 #endif
index cb6b51a9ded9cde85d5b352291bc5b95d2222898..4f18d590f2f543ebe34a54021bb3c16fa9c847b3 100644 (file)
@@ -64,7 +64,7 @@ SecureTransportCore::~SecureTransportCore()
 void SecureTransportCore::open()
 {
     switch (OSStatus err = SSLHandshake(mContext)) {
 void SecureTransportCore::open()
 {
     switch (OSStatus err = SSLHandshake(mContext)) {
-    case noErr:
+    case errSecSuccess:
     case errSSLWouldBlock:
         secdebug("ssl", "%p open, state=%d", this, state());
         return;
     case errSSLWouldBlock:
         secdebug("ssl", "%p open, state=%d", this, state());
         return;
@@ -104,7 +104,7 @@ size_t SecureTransportCore::read(void *data, size_t length)
         return 0;
     size_t bytesRead;
     switch (OSStatus err = SSLRead(mContext, data, length, &bytesRead)) {
         return 0;
     size_t bytesRead;
     switch (OSStatus err = SSLRead(mContext, data, length, &bytesRead)) {
-    case noErr:                                        // full read
+    case errSecSuccess:                                        // 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 errSSLWouldBlock:             // partial read
         return bytesRead;              // (may be zero in non-blocking scenarios)
     case errSSLClosedGraceful: // means end-of-data, but we may still return some
@@ -129,7 +129,7 @@ size_t SecureTransportCore::write(const void *data, size_t length)
         return 0;
     size_t bytesWritten;
     switch (OSStatus err = SSLWrite(mContext, data, length, &bytesWritten)) {
         return 0;
     size_t bytesWritten;
     switch (OSStatus err = SSLWrite(mContext, data, length, &bytesWritten)) {
-    case noErr:
+    case errSecSuccess:
         return bytesWritten;
     case errSSLWouldBlock:
         return 0;      // no data, no error, no fuss
         return bytesWritten;
     case errSSLWouldBlock:
         return 0;      // no data, no error, no fuss
@@ -149,7 +149,7 @@ bool SecureTransportCore::continueHandshake()
         // still in handshake mode; prod it along
         secdebug("ssl", "%p continuing handshake", this);
         switch (OSStatus err = SSLHandshake(mContext)) {
         // still in handshake mode; prod it along
         secdebug("ssl", "%p continuing handshake", this);
         switch (OSStatus err = SSLHandshake(mContext)) {
-        case noErr:
+        case errSecSuccess:
         case errSSLWouldBlock:
             break;
         default:
         case errSSLWouldBlock:
             break;
         default:
@@ -263,7 +263,7 @@ OSStatus SecureTransportCore::sslReadFunc(SSLConnectionRef connection,
         *length = stc->ioRead(data, lengthRequested);
         secdebug("sslconio", "%p read %lu of %lu bytes", stc, *length, lengthRequested);
         if (*length == lengthRequested)        // full deck
         *length = stc->ioRead(data, lengthRequested);
         secdebug("sslconio", "%p read %lu of %lu bytes", stc, *length, lengthRequested);
         if (*length == lengthRequested)        // full deck
-            return noErr;
+            return errSecSuccess;
         else if (stc->ioAtEnd()) {
             secdebug("sslconio", "%p end of source input, returning %lu bytes",
                 stc, *length);
         else if (stc->ioAtEnd()) {
             secdebug("sslconio", "%p end of source input, returning %lu bytes",
                 stc, *length);
@@ -292,7 +292,7 @@ OSStatus SecureTransportCore::sslWriteFunc(SSLConnectionRef connection,
         size_t lengthRequested = *length;
         *length = stc->ioWrite(data, lengthRequested);
         secdebug("sslconio", "%p wrote %lu of %lu bytes", stc, *length, lengthRequested);
         size_t lengthRequested = *length;
         *length = stc->ioWrite(data, lengthRequested);
         secdebug("sslconio", "%p wrote %lu of %lu bytes", stc, *length, lengthRequested);
-        return *length == lengthRequested ? OSStatus(noErr) : OSStatus(errSSLWouldBlock);
+        return *length == lengthRequested ? OSStatus(errSecSuccess) : OSStatus(errSSLWouldBlock);
     } catch (const CommonError &err) {
         *length = 0;
         return err.osStatus();
     } catch (const CommonError &err) {
         *length = 0;
         return err.osStatus();
index 5ec3427ab5e7572484d2706db3ac393372fd4dcd..c434036aab2d73a05330707fce0546ebcd4f3197 100644 (file)
@@ -20,7 +20,6 @@ _SSLGetNegotiatedProtocolVersion
 _SSLGetNumberEnabledCiphers
 _SSLGetNumberOfSignatureAlgorithms
 _SSLGetNumberSupportedCiphers
 _SSLGetNumberEnabledCiphers
 _SSLGetNumberOfSignatureAlgorithms
 _SSLGetNumberSupportedCiphers
-_SSLGetPeerCertificates
 _SSLCopyPeerCertificates
 _SSLCopyPeerTrust
 _SSLGetPeerDomainName
 _SSLCopyPeerCertificates
 _SSLCopyPeerTrust
 _SSLGetPeerDomainName
@@ -37,7 +36,6 @@ _SSLGetSessionOption
 _SSLGetSessionState
 _SSLGetSignatureAlgorithms
 _SSLGetSupportedCiphers
 _SSLGetSessionState
 _SSLGetSignatureAlgorithms
 _SSLGetSupportedCiphers
-_SSLGetTrustedRoots
 _SSLCopyTrustedRoots
 _SSLSetTrustedLeafCertificates
 _SSLCopyTrustedLeafCertificates
 _SSLCopyTrustedRoots
 _SSLSetTrustedLeafCertificates
 _SSLCopyTrustedLeafCertificates
index b60a77d6d01371adeb78aad146c0a8e52f14ae77..c9987a3edd37366175a183645ab4e0fee32f766f 100644 (file)
@@ -31,6 +31,6 @@
 #include "SecureTransport.h"
 #include "sslPriv.h"
 
 #include "SecureTransport.h"
 #include "sslPriv.h"
 
-#include <MacErrors.h>
+#include <Security/SecBase.h>
 
 #endif /* _SSL_SSL_H_ */
 
 #endif /* _SSL_SSL_H_ */
index 3b9f18f17167cd4ca468be5a9721cb3c04eae3cc..dc32edfb9c22c0b1cf586f67ea7b96809dbb7823 100644 (file)
 #include <strings.h>
 #include <stddef.h>
 
 #include <strings.h>
 #include <stddef.h>
 
-/*
- * ssl3WriteRecord does not send alerts on failure, out of the assumption/fear
- * that this might result in a loop (since sending an alert causes ssl3WriteRecord
- * to be called).
- *
- * As far as I can tell, we can use this same routine for SSLv3 and TLSv1, as long
- * as we're not trying to use the "variable length padding" feature of TLSv1.
- * OpenSSL doesn't use that feature; for now, neither will we. Thus this routine
- * is used for the SslTlsCallouts.writeRecord function for both protocols.
- */
-OSStatus ssl3WriteRecord(
-       SSLRecord rec,
-       SSLContext *ctx)
-{
-       OSStatus        err;
-    int             padding = 0, i;
-    WaitingRecord   *out = NULL, *queue;
-    SSLBuffer       payload, mac;
-    UInt8           *charPtr;
-    UInt16          payloadSize,blockSize;
-    int             head = 5;
-
-       switch(rec.protocolVersion) {
-        case DTLS_Version_1_0:
-            head += 8;
-               case SSL_Version_3_0:
-               case TLS_Version_1_0:
-        case TLS_Version_1_1:
-        case TLS_Version_1_2:
-                       break;
-               default:
-                       assert(0);
-                       return errSSLInternal;
-       }
-    assert(rec.contents.length <= 16384);
-
-    sslLogRecordIo("type = %02x, ver = %04x, len = %ld, seq = %08x_%08x",
-                   rec.contentType, rec.protocolVersion, rec.contents.length,
-                   ctx->writeCipher.sequenceNum.high, ctx->writeCipher.sequenceNum.low);
-
-    /* Allocate enough room for the transmitted record, which will be:
-     *  5 bytes of header (13 for DTLS) +
-     *  IV [block cipher and TLS1.1 or DTLS 1.0 only]
-     *  encrypted contents +
-     *  macLength +
-     *  padding [block ciphers only] +
-     *  padding length field (1 byte) [block ciphers only]
-     */
-    payloadSize = (UInt16) (rec.contents.length + ctx->writeCipher.macRef->hash->digestSize);
-    blockSize = ctx->writeCipher.symCipher->blockSize;
-    if (blockSize > 0)
-    {
-        padding = blockSize - (payloadSize % blockSize) - 1;
-        payloadSize += padding + 1;
-        /* TLS 1.1 and DTLS 1.0 have an extra block for IV */
-        if(ctx->negProtocolVersion >= TLS_Version_1_1) {
-            payloadSize += blockSize;
-        }
-    }
-
-       out = (WaitingRecord *)sslMalloc(offsetof(WaitingRecord, data) +
-               head + payloadSize);
-       out->next = NULL;
-       out->sent = 0;
-       out->length = head + payloadSize;
-
-    charPtr = out->data;
-    *(charPtr++) = rec.contentType;
-    charPtr = SSLEncodeInt(charPtr, rec.protocolVersion, 2);
-
-    /* DTLS sequence number */
-    if(rec.protocolVersion == DTLS_Version_1_0)
-        charPtr = SSLEncodeUInt64(charPtr,ctx->writeCipher.sequenceNum);
-
-    charPtr = SSLEncodeInt(charPtr, payloadSize, 2);
-
-    /* Also for DTLS */
-    if((ctx->negProtocolVersion >= TLS_Version_1_1) && (blockSize>0))
-    {
-        SSLBuffer randomIV;
-        randomIV.data = charPtr;
-        randomIV.length = blockSize;
-        if((err = sslRand(ctx, &randomIV)) != 0)
-            return err;
-        charPtr += blockSize;
-    }
-
-    /* Copy the contents into the output buffer */
-    memcpy(charPtr, rec.contents.data, rec.contents.length);
-    payload.data = charPtr;
-    payload.length = rec.contents.length;
-
-    charPtr += rec.contents.length;
-    /* MAC immediately follows data */
-    mac.data = charPtr;
-    mac.length = ctx->writeCipher.macRef->hash->digestSize;
-    charPtr += mac.length;
-
-    /* MAC the data */
-    if (mac.length > 0)     /* Optimize away null case */
-    {
-               assert(ctx->sslTslCalls != NULL);
-        if ((err = ctx->sslTslCalls->computeMac(rec.contentType,
-                               payload,
-                               mac,
-                               &ctx->writeCipher,
-                               ctx->writeCipher.sequenceNum,
-                               ctx)) != 0)
-            goto fail;
-    }
-
-    /* For TLS 1.1 and DTLS, we would need to specify the IV, but instead
-     we are clever like this: since the IV is just one block in front,
-     we encrypt it with the rest of the data. The actual transmitted IV
-     is the result of the encryption, with whatever internal IV is used.
-     This method is explained in the TLS 1.1 RFC */
-    if(ctx->negProtocolVersion >= TLS_Version_1_1)
-    {
-        if(blockSize > 0)
-            payload.data -= blockSize;
-    }
-
-    /* Update payload to reflect encrypted data: IV, 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 */
-    if ((err = ctx->writeCipher.symCipher->encrypt(payload.data,
-               payload.data, payload.length,
-               &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 noErr;
-
-fail:
-       /*
-        * Only for if we fail between when the WaitingRecord is allocated and when
-        * it is queued
-        */
-       sslFree(out);
-    return err;
-}
-
-static OSStatus ssl3DecryptRecord(
-       UInt8 type,
-       SSLBuffer *payload,
-       SSLContext *ctx)
-{
-       OSStatus    err;
-    SSLBuffer   content;
-
-    if ((ctx->readCipher.symCipher->blockSize > 0) &&
-        ((payload->length % ctx->readCipher.symCipher->blockSize) != 0))
-    {   SSLFatalSessionAlert(SSL_AlertUnexpectedMsg, ctx);
-        return errSSLProtocol;
-    }
-
-    /* Decrypt in place */
-    if ((err = ctx->readCipher.symCipher->decrypt(payload->data,
-               payload->data, payload->length,
-               &ctx->readCipher,
-               ctx)) != 0)
-    {
-        /* Complies with TLS 1.1 - But we do it for every protocol version */
-        SSLFatalSessionAlert(SSL_AlertBadRecordMac, ctx);
-        return err;
-    }
-
-       /* Locate content within decrypted payload */
-    content.data = payload->data;
-    content.length = payload->length - ctx->readCipher.macRef->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)
-        {
-            /* Complies with TLS 1.1 - But we do it for every protocol version */
-            SSLFatalSessionAlert(SSL_AlertBadRecordMac, ctx);
-               sslErrorLog("DecryptSSLRecord: bad padding length (%d)\n",
-                       (unsigned)payload->data[payload->length - 1]);
-            return errSSLDecryptionFail;
-        }
-        content.length -= 1 + payload->data[payload->length - 1];
-                                               /* Remove block size padding */
-    }
-
-       /* Verify MAC on payload */
-    if (ctx->readCipher.macRef->hash->digestSize > 0)
-               /* Optimize away MAC for null case */
-        if ((err = SSLVerifyMac(type, &content,
-                               payload->data + content.length, ctx)) != 0)
-        {   SSLFatalSessionAlert(SSL_AlertBadRecordMac, ctx);
-            return errSSLBadRecordMac;
-        }
-
-    *payload = content;     /* Modify payload buffer to indicate content length */
-
-    return noErr;
-}
-
-/* initialize a per-CipherContext HashHmacContext for use in MACing each record */
-static OSStatus ssl3InitMac (
-       CipherContext *cipherCtx,               // macRef, macSecret valid on entry
-                                                                       // macCtx valid on return
-       SSLContext *ctx)
-{
-       const HashReference *hash;
-       SSLBuffer *hashCtx;
-       OSStatus serr;
-
-       assert(cipherCtx->macRef != NULL);
-       hash = cipherCtx->macRef->hash;
-       assert(hash != NULL);
-
-       hashCtx = &cipherCtx->macCtx.hashCtx;
-       if(hashCtx->data != NULL) {
-               SSLFreeBuffer(hashCtx, ctx);
-       }
-       serr = SSLAllocBuffer(hashCtx, hash->contextSize, ctx);
-       if(serr) {
-               return serr;
-       }
-       return noErr;
-}
-
-static OSStatus ssl3FreeMac (
-       CipherContext *cipherCtx)
-{
-       SSLBuffer *hashCtx;
-
-       assert(cipherCtx != NULL);
-       /* this can be called on a completely zeroed out CipherContext... */
-       if(cipherCtx->macRef == NULL) {
-               return noErr;
-       }
-       hashCtx = &cipherCtx->macCtx.hashCtx;
-       if(hashCtx->data != NULL) {
-               sslFree(hashCtx->data);
-               hashCtx->data = NULL;
-       }
-       hashCtx->length = 0;
-       return noErr;
-}
-
-static OSStatus ssl3ComputeMac (
-       UInt8 type,
-       SSLBuffer data,
-       SSLBuffer mac,                                  // caller mallocs data
-       CipherContext *cipherCtx,               // assumes macCtx, macRef
-       sslUint64 seqNo,
-       SSLContext *ctx)
-{
-       OSStatus        err;
-    UInt8           innerDigestData[SSL_MAX_DIGEST_LEN];
-    UInt8           scratchData[11], *charPtr;
-    SSLBuffer       digest, digestCtx, scratch;
-       SSLBuffer               secret;
-
-    const HashReference        *hash;
-
-       assert(cipherCtx != NULL);
-       assert(cipherCtx->macRef != NULL);
-       hash = cipherCtx->macRef->hash;
-       assert(hash != NULL);
-    assert(hash->macPadSize <= MAX_MAC_PADDING);
-    assert(hash->digestSize <= SSL_MAX_DIGEST_LEN);
-       digestCtx = cipherCtx->macCtx.hashCtx;          // may be NULL, for null cipher
-       secret.data = cipherCtx->macSecret;
-       secret.length = hash->digestSize;
-
-       /* init'd early in SSLNewContext() */
-    assert(SSLMACPad1[0] == 0x36 && SSLMACPad2[0] == 0x5C);
-
-       /*
-        * MAC = hash( MAC_write_secret + pad_2 +
-        *                     hash( MAC_write_secret + pad_1 + seq_num + type +
-        *                               length + content )
-        *                       )
-        */
-    if ((err = hash->init(&digestCtx, ctx)) != 0)
-        goto exit;
-    if ((err = hash->update(&digestCtx, &secret)) != 0)    /* MAC secret */
-        goto exit;
-    scratch.data = (UInt8 *)SSLMACPad1;
-    scratch.length = hash->macPadSize;
-    if ((err = hash->update(&digestCtx, &scratch)) != 0)   /* pad1 */
-        goto exit;
-    charPtr = scratchData;
-    charPtr = SSLEncodeUInt64(charPtr, seqNo);
-    *charPtr++ = type;
-    charPtr = SSLEncodeSize(charPtr, data.length, 2);
-    scratch.data = scratchData;
-    scratch.length = 11;
-    assert(charPtr = scratchData+11);
-    if ((err = hash->update(&digestCtx, &scratch)) != 0)
-                                                                               /* sequenceNo, type & length */
-        goto exit;
-    if ((err = hash->update(&digestCtx, &data)) != 0)      /* content */
-        goto exit;
-    digest.data = innerDigestData;
-    digest.length = hash->digestSize;
-    if ((err = hash->final(&digestCtx, &digest)) != 0)         /* figure inner digest */
-        goto exit;
-
-    if ((err = hash->init(&digestCtx, ctx)) != 0)
-        goto exit;
-    if ((err = hash->update(&digestCtx, &secret)) != 0)    /* MAC secret */
-        goto exit;
-    scratch.data = (UInt8 *)SSLMACPad2;
-    scratch.length = hash->macPadSize;
-    if ((err = hash->update(&digestCtx, &scratch)) != 0)   /* pad2 */
-        goto exit;
-    if ((err = hash->update(&digestCtx, &digest)) != 0)    /* inner digest */
-        goto exit;
-    if ((err = hash->final(&digestCtx, &mac)) != 0)     /* figure the mac */
-        goto exit;
-
-    err = noErr; /* redundant, I know */
-
-exit:
-    return err;
-}
-
 #define LOG_GEN_KEY    0
 
 /*
 #define LOG_GEN_KEY    0
 
 /*
@@ -436,11 +93,11 @@ static OSStatus ssl3GenerateKeyMaterial (
 
     md5Context.data = 0;
     shaContext.data = 0;
 
     md5Context.data = 0;
     shaContext.data = 0;
-    if ((err = ReadyHash(&SSLHashMD5, &md5Context, ctx)) != 0)
-        goto fail;
-    if ((err = ReadyHash(&SSLHashSHA1, &shaContext, ctx)) != 0)
+    if ((err = ReadyHash(&SSLHashMD5, &md5Context)) != 0)
         goto fail;
         goto fail;
-
+    if ((err = ReadyHash(&SSLHashSHA1, &shaContext)) != 0)
+        goto fail;  
+    
     keyProgress = key.data;
     remaining = key.length;
 
     keyProgress = key.data;
     remaining = key.length;
 
@@ -475,103 +132,25 @@ static OSStatus ssl3GenerateKeyMaterial (
 
                if(remaining > 0) {
                        /* at top of loop, this was done in ReadyHash() */
 
                if(remaining > 0) {
                        /* at top of loop, this was done in ReadyHash() */
-                       if ((err = SSLHashMD5.init(&md5Context, ctx)) != 0)
+                       if ((err = SSLHashMD5.init(&md5Context)) != 0)
                                goto fail;
                                goto fail;
-                       if ((err = SSLHashSHA1.init(&shaContext, ctx)) != 0)
+                       if ((err = SSLHashSHA1.init(&shaContext)) != 0)
                                goto fail;
                }
     }
 
     assert(remaining == 0 && keyProgress == (key.data + key.length));
                                goto fail;
                }
     }
 
     assert(remaining == 0 && keyProgress == (key.data + key.length));
-    err = noErr;
+    err = errSecSuccess;
 fail:
 fail:
-    SSLFreeBuffer(&md5Context, ctx);
-    SSLFreeBuffer(&shaContext, ctx);
-
+    SSLFreeBuffer(&md5Context);
+    SSLFreeBuffer(&shaContext);
+    
        #if     LOG_GEN_KEY
        printf("GenerateKey: DONE\n");
        #endif
     return err;
 }
 
        #if     LOG_GEN_KEY
        printf("GenerateKey: DONE\n");
        #endif
     return err;
 }
 
-static OSStatus ssl3GenerateExportKeyAndIv (
-       SSLContext *ctx,                                // clientRandom, serverRandom valid
-       const SSLBuffer clientWriteKey,
-       const SSLBuffer serverWriteKey,
-       SSLBuffer finalClientWriteKey,  // RETURNED, mallocd by caller
-       SSLBuffer finalServerWriteKey,  // RETURNED, mallocd by caller
-       SSLBuffer finalClientIV,                // RETURNED, mallocd by caller
-       SSLBuffer finalServerIV)                // RETURNED, mallocd by caller
-{
-       OSStatus err;
-       SSLBuffer hashCtx, serverRandom, clientRandom;
-
-       /* random blobs are 32 bytes */
-       serverRandom.data = ctx->serverRandom;
-       serverRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
-       clientRandom.data = ctx->clientRandom;
-       clientRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
-
-       if ((err = SSLAllocBuffer(&hashCtx, SSLHashMD5.contextSize, ctx)) != 0)
-               return err;
-       /* client write key */
-       if ((err = SSLHashMD5.init(&hashCtx, ctx)) != 0)
-               goto fail;
-       if ((err = SSLHashMD5.update(&hashCtx, &clientWriteKey)) != 0)
-               goto fail;
-       if ((err = SSLHashMD5.update(&hashCtx, &clientRandom)) != 0)
-               goto fail;
-       if ((err = SSLHashMD5.update(&hashCtx, &serverRandom)) != 0)
-               goto fail;
-       finalClientWriteKey.length = 16;
-       if ((err = SSLHashMD5.final(&hashCtx, &finalClientWriteKey)) != 0)
-               goto fail;
-
-       /* optional client IV */
-       if (ctx->selectedCipherSpec.cipher->ivSize > 0)
-       {   if ((err = SSLHashMD5.init(&hashCtx, ctx)) != 0)
-                       goto fail;
-               if ((err = SSLHashMD5.update(&hashCtx, &clientRandom)) != 0)
-                       goto fail;
-               if ((err = SSLHashMD5.update(&hashCtx, &serverRandom)) != 0)
-                       goto fail;
-               finalClientIV.length = 16;
-               if ((err = SSLHashMD5.final(&hashCtx, &finalClientIV)) != 0)
-                       goto fail;
-       }
-
-       /* server write key */
-       if ((err = SSLHashMD5.init(&hashCtx, ctx)) != 0)
-               goto fail;
-       if ((err = SSLHashMD5.update(&hashCtx, &serverWriteKey)) != 0)
-               goto fail;
-       if ((err = SSLHashMD5.update(&hashCtx, &serverRandom)) != 0)
-               goto fail;
-       if ((err = SSLHashMD5.update(&hashCtx, &clientRandom)) != 0)
-               goto fail;
-       finalServerWriteKey.length = 16;
-       if ((err = SSLHashMD5.final(&hashCtx, &finalServerWriteKey)) != 0)
-               goto fail;
-
-       /* optional server IV */
-       if (ctx->selectedCipherSpec.cipher->ivSize > 0)
-       {   if ((err = SSLHashMD5.init(&hashCtx, ctx)) != 0)
-                       goto fail;
-               if ((err = SSLHashMD5.update(&hashCtx, &serverRandom)) != 0)
-                       goto fail;
-               if ((err = SSLHashMD5.update(&hashCtx, &clientRandom)) != 0)
-                       goto fail;
-               finalServerIV.length = 16;
-               if ((err = SSLHashMD5.final(&hashCtx, &finalServerIV)) != 0)
-                       goto fail;
-       }
-
-    err = noErr;
-fail:
-    SSLFreeBuffer(&hashCtx, ctx);
-    return err;
-}
-
 /*
  * On entry: clientRandom, serverRandom, preMasterSecret valid
  * On return: masterSecret valid
 /*
  * On entry: clientRandom, serverRandom, preMasterSecret valid
  * On return: masterSecret valid
@@ -586,9 +165,9 @@ static OSStatus ssl3GenerateMasterSecret (
     int         i;
 
     md5State.data = shaState.data = 0;
     int         i;
 
     md5State.data = shaState.data = 0;
-    if ((err = SSLAllocBuffer(&md5State, SSLHashMD5.contextSize, ctx)) != 0)
+    if ((err = SSLAllocBuffer(&md5State, SSLHashMD5.contextSize)))
         goto fail;
         goto fail;
-    if ((err = SSLAllocBuffer(&shaState, SSLHashSHA1.contextSize, ctx)) != 0)
+    if ((err = SSLAllocBuffer(&shaState, SSLHashSHA1.contextSize)))
         goto fail;
 
     clientRandom.data = ctx->clientRandom;
         goto fail;
 
     clientRandom.data = ctx->clientRandom;
@@ -601,9 +180,9 @@ static OSStatus ssl3GenerateMasterSecret (
     masterProgress = ctx->masterSecret;
 
     for (i = 1; i <= 3; i++)
     masterProgress = ctx->masterSecret;
 
     for (i = 1; i <= 3; i++)
-    {   if ((err = SSLHashMD5.init(&md5State, ctx)) != 0)
+    {   if ((err = SSLHashMD5.init(&md5State)) != 0)
             goto fail;
             goto fail;
-        if ((err = SSLHashSHA1.init(&shaState, ctx)) != 0)
+        if ((err = SSLHashSHA1.init(&shaState)) != 0)
             goto fail;
 
         leaderData[0] = leaderData[1] = leaderData[2] = 0x40 + i;   /* 'A', 'B', etc. */
             goto fail;
 
         leaderData[0] = leaderData[1] = leaderData[2] = 0x40 + i;   /* 'A', 'B', etc. */
@@ -631,10 +210,10 @@ static OSStatus ssl3GenerateMasterSecret (
         masterProgress += 16;
     }
 
         masterProgress += 16;
     }
 
-    err = noErr;
+    err = errSecSuccess;
 fail:
 fail:
-    SSLFreeBuffer(&shaState, ctx);
-    SSLFreeBuffer(&md5State, ctx);
+    SSLFreeBuffer(&shaState);
+    SSLFreeBuffer(&md5State);
     return err;
 }
 
     return err;
 }
 
@@ -683,9 +262,9 @@ ssl3CalculateFinishedMessage(
     hash.length = 20;
     if ((err = SSLHashSHA1.final(&shaMsgState, &hash)) != 0)
         goto fail;
     hash.length = 20;
     if ((err = SSLHashSHA1.final(&shaMsgState, &hash)) != 0)
         goto fail;
-    if ((err = SSLHashMD5.init(&md5MsgState, ctx)) != 0)
+    if ((err = SSLHashMD5.init(&md5MsgState)) != 0)
         goto fail;
         goto fail;
-    if ((err = SSLHashSHA1.init(&shaMsgState, ctx)) != 0)
+    if ((err = SSLHashSHA1.init(&shaMsgState)) != 0)
         goto fail;
     input.data = ctx->masterSecret;
     input.length = SSL_MASTER_SECRET_SIZE;
         goto fail;
     input.data = ctx->masterSecret;
     input.length = SSL_MASTER_SECRET_SIZE;
@@ -732,17 +311,17 @@ static OSStatus ssl3ComputeFinishedMac (
 
     shaMsgState.data = 0;
     md5MsgState.data = 0;
 
     shaMsgState.data = 0;
     md5MsgState.data = 0;
-    if ((serr = CloneHashState(&SSLHashSHA1, &ctx->shaState, &shaMsgState, ctx)) != 0)
+    if ((serr = CloneHashState(&SSLHashSHA1, &ctx->shaState, &shaMsgState)) != 0)
         goto fail;
         goto fail;
-    if ((serr = CloneHashState(&SSLHashMD5, &ctx->md5State, &md5MsgState, ctx)) != 0)
+    if ((serr = CloneHashState(&SSLHashMD5, &ctx->md5State, &md5MsgState)) != 0)
         goto fail;
 
        serr = ssl3CalculateFinishedMessage(ctx, finished, shaMsgState, md5MsgState,
                isServer ? SSL_Finished_Sender_Server : SSL_Finished_Sender_Client);
 
 fail:
         goto fail;
 
        serr = ssl3CalculateFinishedMessage(ctx, finished, shaMsgState, md5MsgState,
                isServer ? SSL_Finished_Sender_Server : SSL_Finished_Sender_Client);
 
 fail:
-    SSLFreeBuffer(&shaMsgState, ctx);
-    SSLFreeBuffer(&md5MsgState, ctx);
+    SSLFreeBuffer(&shaMsgState);
+    SSLFreeBuffer(&md5MsgState);
 
     return serr;
 }
 
     return serr;
 }
@@ -758,9 +337,9 @@ static OSStatus ssl3ComputeCertVfyMac (
 
     shaMsgState.data = 0;
     md5MsgState.data = 0;
 
     shaMsgState.data = 0;
     md5MsgState.data = 0;
-    if ((serr = CloneHashState(&SSLHashSHA1, &ctx->shaState, &shaMsgState, ctx)) != 0)
+    if ((serr = CloneHashState(&SSLHashSHA1, &ctx->shaState, &shaMsgState)) != 0)
         goto fail;
         goto fail;
-    if ((serr = CloneHashState(&SSLHashMD5, &ctx->md5State, &md5MsgState, ctx)) != 0)
+    if ((serr = CloneHashState(&SSLHashMD5, &ctx->md5State, &md5MsgState)) != 0)
         goto fail;
 
     assert(finished->length >= SSL_MD5_DIGEST_LEN + SSL_SHA1_DIGEST_LEN);
         goto fail;
 
     assert(finished->length >= SSL_MD5_DIGEST_LEN + SSL_SHA1_DIGEST_LEN);
@@ -769,20 +348,14 @@ static OSStatus ssl3ComputeCertVfyMac (
        serr = ssl3CalculateFinishedMessage(ctx, *finished, shaMsgState, md5MsgState, 0);
 
 fail:
        serr = ssl3CalculateFinishedMessage(ctx, *finished, shaMsgState, md5MsgState, 0);
 
 fail:
-    SSLFreeBuffer(&shaMsgState, ctx);
-    SSLFreeBuffer(&md5MsgState, ctx);
+    SSLFreeBuffer(&shaMsgState);
+    SSLFreeBuffer(&md5MsgState);
 
     return serr;
 }
 
 const SslTlsCallouts Ssl3Callouts = {
 
     return serr;
 }
 
 const SslTlsCallouts Ssl3Callouts = {
-       ssl3DecryptRecord,
-       ssl3WriteRecord,
-       ssl3InitMac,
-       ssl3FreeMac,
-       ssl3ComputeMac,
        ssl3GenerateKeyMaterial,
        ssl3GenerateKeyMaterial,
-       ssl3GenerateExportKeyAndIv,
        ssl3GenerateMasterSecret,
        ssl3ComputeFinishedMac,
        ssl3ComputeCertVfyMac
        ssl3GenerateMasterSecret,
        ssl3ComputeFinishedMac,
        ssl3ComputeCertVfyMac
diff --git a/libsecurity_ssl/lib/ssl3RecordCallouts.c b/libsecurity_ssl/lib/ssl3RecordCallouts.c
new file mode 100644 (file)
index 0000000..e9604f4
--- /dev/null
@@ -0,0 +1,440 @@
+/*
+ * Copyright (c) 2002,2005-2007,2010-2011 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * ssl3RecordCallouts.c - SSLv3-specific routines for SslTlsCallouts.
+ */
+
+/* THIS FILE CONTAINS KERNEL CODE */
+
+#include <AssertMacros.h>
+#include <string.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#ifdef KERNEL
+#include <sys/types.h>
+#else
+#include <stddef.h>
+#endif
+
+#include "sslDebug.h"
+#include "sslMemory.h"
+#include "sslUtils.h"
+#include "sslRand.h"
+
+#include "tls_record.h"
+
+
+/*
+ * ssl3WriteRecord does not send alerts on failure, out of the assumption/fear
+ * that this might result in a loop (since sending an alert causes ssl3WriteRecord
+ * to be called).
+ *
+ * As far as I can tell, we can use this same routine for SSLv3 and TLSv1, as long
+ * as we're not trying to use the "variable length padding" feature of TLSv1.
+ * OpenSSL doesn't use that feature; for now, neither will we. Thus this routine
+ * is used for the SslTlsCallouts.writeRecord function for both protocols.
+ */
+int ssl3WriteRecord(
+       SSLRecord rec,
+       struct SSLRecordInternalContext *ctx)
+{
+       int        err;
+    int             padding = 0, i;
+    WaitingRecord   *out = NULL, *queue;
+    SSLBuffer       payload, mac;
+    uint8_t           *charPtr;
+    uint16_t          payloadSize,blockSize = 0;
+    int             head = 5;
+
+       switch(rec.protocolVersion) {
+        case DTLS_Version_1_0:
+            head += 8;
+               case SSL_Version_3_0:
+               case TLS_Version_1_0:
+        case TLS_Version_1_1:
+        case TLS_Version_1_2:
+                       break;
+               default:
+                       check(0);
+                       return errSSLRecordInternal;
+       }
+    check(rec.contents.length <= 16384);
+
+    sslLogRecordIo("type = %02x, ver = %04x, len = %ld, seq = %016llx",
+                   rec.contentType, rec.protocolVersion, rec.contents.length,
+                   ctx->writeCipher.sequenceNum);
+
+    /* Allocate enough room for the transmitted record, which will be:
+     *  5 bytes of header (13 for DTLS) +
+     *  IV [block cipher and TLS1.1 or DTLS 1.0 only]
+     *  encrypted contents +
+     *  macLength +
+     *  padding [block ciphers only] +
+     *  padding length field (1 byte) [block ciphers only]
+     */
+    payloadSize = (uint16_t) rec.contents.length;
+    CipherType cipherType = ctx->writeCipher.symCipher->params->cipherType;
+    const Cipher *cipher = &ctx->writeCipher.symCipher->c.cipher;
+    const AEADCipher *aead = &ctx->writeCipher.symCipher->c.aead;
+    blockSize = ctx->writeCipher.symCipher->params->blockSize;
+    switch (cipherType) {
+        case blockCipherType:
+            payloadSize += ctx->writeCipher.macRef->hash->digestSize;
+            padding = blockSize - (payloadSize % blockSize) - 1;
+            payloadSize += padding + 1;
+            /* TLS 1.1, TLS1.2 and DTLS 1.0 have an extra block for IV */
+            if(ctx->negProtocolVersion >= TLS_Version_1_1) {
+                payloadSize += blockSize;
+            }
+            break;
+        case streamCipherType:
+            payloadSize += ctx->writeCipher.macRef->hash->digestSize;
+            break;
+        case aeadCipherType:
+            /* AES_GCM doesn't need padding. */
+            payloadSize += aead->macSize;
+            break;
+        default:
+            check(0);
+                       return errSSLRecordInternal;
+    }
+
+       out = (WaitingRecord *)sslMalloc(offsetof(WaitingRecord, data) +
+               head + payloadSize);
+       out->next = NULL;
+       out->sent = 0;
+       out->length = head + payloadSize;
+
+    charPtr = out->data;
+    *(charPtr++) = rec.contentType;
+    charPtr = SSLEncodeInt(charPtr, rec.protocolVersion, 2);
+
+    /* DTLS sequence number */
+    if(rec.protocolVersion == DTLS_Version_1_0)
+        charPtr = SSLEncodeUInt64(charPtr,ctx->writeCipher.sequenceNum);
+
+    charPtr = SSLEncodeInt(charPtr, payloadSize, 2);
+
+    /* Also for DTLS */
+    if((ctx->negProtocolVersion >= TLS_Version_1_1) &&
+       (cipherType == blockCipherType))
+    {
+        SSLBuffer randomIV;
+        randomIV.data = charPtr;
+        randomIV.length = blockSize;
+        if((err = sslRand(&randomIV)) != 0)
+            return err;
+        charPtr += blockSize;
+    }
+    if (cipherType == aeadCipherType) {
+        /* Encode the explicit iv, for AES_GCM we just use the 8 byte
+           sequenceNum as the explicitIV.
+           Ideally this needs to be done in the algorithm itself, by an
+           extra function pointer in AEADCipher.  */
+        charPtr = SSLEncodeUInt64(charPtr,ctx->writeCipher.sequenceNum);
+        /* TODO: If we ever add any mode other than GCM this code might have
+           to be different. */
+        /* TODO: Pass 4 byte implicit and 8 byte explicit IV to cipher */
+        //err = ctx->writeCipher.symCipher->c.aead.setIV(charPtr, &ctx->writeCipher, ctx);
+    }
+
+    /* Copy the contents into the output buffer */
+    memcpy(charPtr, rec.contents.data, rec.contents.length);
+    payload.data = charPtr;
+    payload.length = rec.contents.length;
+
+    charPtr += rec.contents.length;
+
+    /* MAC the data */
+    if (cipherType != aeadCipherType) {
+        /* MAC immediately follows data */
+        mac.data = charPtr;
+        mac.length = ctx->writeCipher.macRef->hash->digestSize;
+        charPtr += mac.length;
+        if (mac.length > 0)     /* Optimize away null case */
+        {
+            check(ctx->sslTslCalls != NULL);
+            if ((err = ctx->sslTslCalls->computeMac(rec.contentType,
+                    payload,
+                    mac,
+                    &ctx->writeCipher,
+                    ctx->writeCipher.sequenceNum,
+                    ctx)) != 0)
+                goto fail;
+        }
+    }
+
+    /* For TLS 1.1 and DTLS, we would need to specifiy the IV, but instead
+     we are clever like this: since the IV is just one block in front,
+     we encrypt it with the rest of the data. The actual transmitted IV
+     is the result of the encryption, with whatever internal IV is used.
+     This method is explained in the TLS 1.1 RFC */
+    if(ctx->negProtocolVersion >= TLS_Version_1_1 &&
+       cipherType == blockCipherType)
+    {
+            payload.data -= blockSize;
+    }
+
+    /* Update payload to reflect encrypted data: IV, contents, mac & padding */
+    payload.length = payloadSize;
+
+
+    switch (cipherType) {
+        case blockCipherType:
+            /* 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 */
+            for (i = 1; i <= padding + 1; ++i)
+                payload.data[payload.length - i] = padding;
+            /* DROPTRHOUGH */
+        case streamCipherType:
+            /* Encrypt the data */
+            if ((err = cipher->encrypt(payload.data,
+                payload.data, payload.length, ctx->writeCipher.cipherCtx)) != 0)
+                goto fail;
+            break;
+        case aeadCipherType:
+            check(0);
+            break;
+        default:
+            check(0);
+                       return errSSLRecordInternal;
+    }
+
+    /* 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 0;
+
+fail:
+       /*
+        * Only for if we fail between when the WaitingRecord is allocated and when
+        * it is queued
+        */
+       sslFree(out);
+    return err;
+}
+
+static int ssl3DecryptRecord(
+       uint8_t type,
+       SSLBuffer *payload,
+       struct SSLRecordInternalContext *ctx)
+{
+       int    err;
+    SSLBuffer   content;
+
+    CipherType cipherType = ctx->readCipher.symCipher->params->cipherType;
+    const Cipher *c = &ctx->readCipher.symCipher->c.cipher;
+    switch (cipherType) {
+        case blockCipherType:
+            if ((payload->length % ctx->readCipher.symCipher->params->blockSize) != 0)
+            {
+                return errSSLRecordDecryptionFail;
+            }
+            /* DROPTHROUGH */
+        case streamCipherType:
+            /* Decrypt in place */
+            err = c->decrypt(payload->data, payload->data,
+                             payload->length, ctx->readCipher.cipherCtx);
+            break;
+        case aeadCipherType:
+        default:
+            check(0);
+                       return errSSLRecordInternal;
+    }
+    if (err != 0)
+    {
+        return errSSLRecordDecryptionFail;
+    }
+
+       /* Locate content within decrypted payload */
+    content.data = payload->data;
+    content.length = payload->length - ctx->readCipher.macRef->hash->digestSize;
+    if (cipherType == blockCipherType)
+    {   /* padding can't be equal to or more than a block */
+        if (payload->data[payload->length - 1] >= ctx->readCipher.symCipher->params->blockSize)
+        {
+               sslErrorLog("DecryptSSLRecord: bad padding length (%d)\n",
+                       (unsigned)payload->data[payload->length - 1]);
+            return errSSLRecordDecryptionFail;
+        }
+        content.length -= 1 + payload->data[payload->length - 1];
+                                               /* Remove block size padding */
+    }
+
+       /* Verify MAC on payload */
+    if (ctx->readCipher.macRef->hash->digestSize > 0)
+               /* Optimize away MAC for null case */
+        if ((err = SSLVerifyMac(type, &content,
+                               payload->data + content.length, ctx)) != 0)
+        {
+            return errSSLRecordBadRecordMac;
+        }
+
+    *payload = content;     /* Modify payload buffer to indicate content length */
+
+    return 0;
+}
+
+/* initialize a per-CipherContext HashHmacContext for use in MACing each record */
+static int ssl3InitMac (
+       CipherContext *cipherCtx)               // macRef, macSecret valid on entry
+                                                                       // macCtx valid on return
+{
+       const HashReference *hash;
+       SSLBuffer *hashCtx;
+       int serr;
+
+       check(cipherCtx->macRef != NULL);
+       hash = cipherCtx->macRef->hash;
+       check(hash != NULL);
+
+       hashCtx = &cipherCtx->macCtx.hashCtx;
+       if(hashCtx->data != NULL) {
+               SSLFreeBuffer(hashCtx);
+       }
+       serr = SSLAllocBuffer(hashCtx, hash->contextSize);
+       if(serr) {
+               return serr;
+       }
+       return 0;
+}
+
+static int ssl3FreeMac (
+       CipherContext *cipherCtx)
+{
+       SSLBuffer *hashCtx;
+
+       check(cipherCtx != NULL);
+       /* this can be called on a completely zeroed out CipherContext... */
+       if(cipherCtx->macRef == NULL) {
+               return 0;
+       }
+       hashCtx = &cipherCtx->macCtx.hashCtx;
+       if(hashCtx->data != NULL) {
+               sslFree(hashCtx->data);
+               hashCtx->data = NULL;
+       }
+       hashCtx->length = 0;
+       return 0;
+}
+
+static int ssl3ComputeMac (
+       uint8_t type,
+       SSLBuffer data,
+       SSLBuffer mac,                                  // caller mallocs data
+       CipherContext *cipherCtx,               // assumes macCtx, macRef
+       sslUint64 seqNo,
+       struct SSLRecordInternalContext *ctx)
+{
+       int        err;
+    uint8_t           innerDigestData[SSL_MAX_DIGEST_LEN];
+    uint8_t           scratchData[11], *charPtr;
+    SSLBuffer       digest, digestCtx, scratch;
+       SSLBuffer               secret;
+
+    const HashReference        *hash;
+
+       check(cipherCtx != NULL);
+       check(cipherCtx->macRef != NULL);
+       hash = cipherCtx->macRef->hash;
+       check(hash != NULL);
+    check(hash->macPadSize <= MAX_MAC_PADDING);
+    check(hash->digestSize <= SSL_MAX_DIGEST_LEN);
+       digestCtx = cipherCtx->macCtx.hashCtx;          // may be NULL, for null cipher
+       secret.data = cipherCtx->macSecret;
+       secret.length = hash->digestSize;
+
+       /* init'd early in SSLNewContext() */
+    check(SSLMACPad1[0] == 0x36 && SSLMACPad2[0] == 0x5C);
+
+       /*
+        * MAC = hash( MAC_write_secret + pad_2 +
+        *                     hash( MAC_write_secret + pad_1 + seq_num + type +
+        *                               length + content )
+        *                       )
+        */
+    if ((err = hash->init(&digestCtx)) != 0)
+        goto exit;
+    if ((err = hash->update(&digestCtx, &secret)) != 0)    /* MAC secret */
+        goto exit;
+    scratch.data = (uint8_t *)SSLMACPad1;
+    scratch.length = hash->macPadSize;
+    if ((err = hash->update(&digestCtx, &scratch)) != 0)   /* pad1 */
+        goto exit;
+    charPtr = scratchData;
+    charPtr = SSLEncodeUInt64(charPtr, seqNo);
+    *charPtr++ = type;
+    charPtr = SSLEncodeSize(charPtr, data.length, 2);
+    scratch.data = scratchData;
+    scratch.length = 11;
+    check(charPtr = scratchData+11);
+    if ((err = hash->update(&digestCtx, &scratch)) != 0)
+                                                                               /* sequenceNo, type & length */
+        goto exit;
+    if ((err = hash->update(&digestCtx, &data)) != 0)      /* content */
+        goto exit;
+    digest.data = innerDigestData;
+    digest.length = hash->digestSize;
+    if ((err = hash->final(&digestCtx, &digest)) != 0)         /* figure inner digest */
+        goto exit;
+
+    if ((err = hash->init(&digestCtx)) != 0)
+        goto exit;
+    if ((err = hash->update(&digestCtx, &secret)) != 0)    /* MAC secret */
+        goto exit;
+    scratch.data = (uint8_t *)SSLMACPad2;
+    scratch.length = hash->macPadSize;
+    if ((err = hash->update(&digestCtx, &scratch)) != 0)   /* pad2 */
+        goto exit;
+    if ((err = hash->update(&digestCtx, &digest)) != 0)    /* inner digest */
+        goto exit;
+    if ((err = hash->final(&digestCtx, &mac)) != 0)     /* figure the mac */
+        goto exit;
+
+    err = 0; /* redundant, I know */
+
+exit:
+    return err;
+}
+
+
+const SslRecordCallouts Ssl3RecordCallouts = {
+       ssl3DecryptRecord,
+       ssl3WriteRecord,
+       ssl3InitMac,
+       ssl3FreeMac,
+       ssl3ComputeMac,
+};
index f2b4689c19c9a4486170ab21fe00d8a34ee48b79..55e3c28ef4e40f7475dc490796c56cf524fa7542 100644 (file)
@@ -78,7 +78,7 @@ SSLDetectCertRejected(
 
 OSStatus
 SSLProcessAlert(SSLRecord rec, SSLContext *ctx)
 
 OSStatus
 SSLProcessAlert(SSLRecord rec, SSLContext *ctx)
-{   OSStatus            err = noErr;
+{   OSStatus            err = errSecSuccess;
     AlertLevel          level;
     AlertDescription    desc;
     uint8_t             *charPtr;
     AlertLevel          level;
     AlertDescription    desc;
     uint8_t             *charPtr;
@@ -108,7 +108,7 @@ SSLProcessAlert(SSLRecord rec, SSLContext *ctx)
         if (level == SSL_AlertLevelFatal) {
                        /* explicit fatal errror */
                        fatal = true;
         if (level == SSL_AlertLevelFatal) {
                        /* explicit fatal errror */
                        fatal = true;
-            sslHdskMsgDebug("***Fatal alert %d received\n", desc);
+            sslErrorLog("***Fatal alert %d received\n", desc);
         }
         SSLDetectCertRejected(ctx, desc);
 
         }
         SSLDetectCertRejected(ctx, desc);
 
@@ -191,7 +191,7 @@ SSLProcessAlert(SSLRecord rec, SSLContext *ctx)
             case SSL_AlertCloseNotify:
                                /* the clean "we're done" case */
                 SSLClose(ctx);
             case SSL_AlertCloseNotify:
                                /* the clean "we're done" case */
                 SSLClose(ctx);
-                err = noErr;
+                err = errSecSuccess;
                 break;
             case SSL_AlertNoCert_RESERVED:
                 if((ctx->state == SSL_HdskStateClientCert) &&
                 break;
             case SSL_AlertNoCert_RESERVED:
                 if((ctx->state == SSL_HdskStateClientCert) &&
@@ -225,7 +225,7 @@ SSLProcessAlert(SSLRecord rec, SSLContext *ctx)
                                        err = errSSLFatalAlert;
                                }
                                else {
                                        err = errSSLFatalAlert;
                                }
                                else {
-                                       err = noErr;
+                                       err = errSecSuccess;
                                }
                 break;
         }
                                }
                 break;
         }
@@ -248,7 +248,7 @@ SSLSendAlert(AlertLevel level, AlertDescription desc, SSLContext *ctx)
        switch(ctx->negProtocolVersion) {
                case SSL_Version_Undetermined:
                        /* Too early in negotiation to send an alert */
        switch(ctx->negProtocolVersion) {
                case SSL_Version_Undetermined:
                        /* Too early in negotiation to send an alert */
-                       return noErr;
+                       return errSecSuccess;
                case SSL_Version_2_0:
                        /* shouldn't be here */
                        assert(0);
                case SSL_Version_2_0:
                        /* shouldn't be here */
                        assert(0);
@@ -258,21 +258,20 @@ SSLSendAlert(AlertLevel level, AlertDescription desc, SSLContext *ctx)
        }
        if(ctx->sentFatalAlert) {
                /* no more alerts allowed */
        }
        if(ctx->sentFatalAlert) {
                /* no more alerts allowed */
-               return noErr;
+               return errSecSuccess;
        }
     if ((err = SSLEncodeAlert(&rec, level, desc, ctx)) != 0)
         return err;
        }
     if ((err = SSLEncodeAlert(&rec, level, desc, ctx)) != 0)
         return err;
-       assert(ctx->sslTslCalls != NULL);
        SSLLogAlertMsg(desc, true);
        SSLLogAlertMsg(desc, true);
-    if ((err = ctx->sslTslCalls->writeRecord(rec, ctx)) != 0)
+    if ((err = SSLWriteRecord(rec, ctx)) != 0)
         return err;
         return err;
-    if ((err = SSLFreeBuffer(&rec.contents, ctx)) != 0)
+    if ((err = SSLFreeBuffer(&rec.contents)))
         return err;
     if(desc == SSL_AlertCloseNotify) {
                /* no more alerts allowed */
                ctx->sentFatalAlert = true;
        }
         return err;
     if(desc == SSL_AlertCloseNotify) {
                /* no more alerts allowed */
                ctx->sentFatalAlert = true;
        }
-    return noErr;
+    return errSecSuccess;
 }
 
 static OSStatus
 }
 
 static OSStatus
@@ -282,12 +281,12 @@ SSLEncodeAlert(SSLRecord *rec, AlertLevel level, AlertDescription desc, SSLConte
        rec->protocolVersion = ctx->negProtocolVersion;
        rec->contentType = SSL_RecordTypeAlert;
     rec->contents.length = 2;
        rec->protocolVersion = ctx->negProtocolVersion;
        rec->contentType = SSL_RecordTypeAlert;
     rec->contents.length = 2;
-    if ((err = SSLAllocBuffer(&rec->contents, 2, ctx)) != 0)
+    if ((err = SSLAllocBuffer(&rec->contents, 2)))
         return err;
     rec->contents.data[0] = level;
     rec->contents.data[1] = desc;
 
         return err;
     rec->contents.data[0] = level;
     rec->contents.data[1] = desc;
 
-    return noErr;
+    return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
index df938a6c8cdf700986b7a9aeee9f14ca26e832ab..63fc16168a02b42835341dce2b05e57537c7eeae 100644 (file)
@@ -128,7 +128,7 @@ OSStatus sslEncodeRsaBlob(
     encBlob = SEC_ASN1EncodeItem(pool, &dest, &nssPubKey,
         kSecAsn1RSAPublicKeyPKCS1Template);
        if (!encBlob)
     encBlob = SEC_ASN1EncodeItem(pool, &dest, &nssPubKey,
         kSecAsn1RSAPublicKeyPKCS1Template);
        if (!encBlob)
-               srtn = memFullErr;
+               srtn = errSecAllocate;
     else {
         /* copy out to caller */
         srtn = SSLCopyBufferFromData(encBlob->Data, encBlob->Length, blob);
     else {
         /* copy out to caller */
         srtn = SSLCopyBufferFromData(encBlob->Data, encBlob->Length, blob);
@@ -224,7 +224,7 @@ OSStatus sslEncodeDhParams(
     encBlob = SEC_ASN1EncodeItem(pool, &dest, &dhParams,
         kSecAsn1DHParameterTemplate);
        if (!encBlob)
     encBlob = SEC_ASN1EncodeItem(pool, &dest, &dhParams,
         kSecAsn1DHParameterTemplate);
        if (!encBlob)
-               srtn = memFullErr;
+               srtn = errSecAllocate;
     else {
         /* copy out to caller */
         srtn = SSLCopyBufferFromData(encBlob->Data, encBlob->Length, blob);
     else {
         /* copy out to caller */
         srtn = SSLCopyBufferFromData(encBlob->Data, encBlob->Length, blob);
@@ -329,7 +329,7 @@ OSStatus sslEcdsaPubKeyBits(
 {
        SecAsn1CoderRef coder = NULL;
        CSSM_X509_SUBJECT_PUBLIC_KEY_INFO subjPubKeyInfo;
 {
        SecAsn1CoderRef coder = NULL;
        CSSM_X509_SUBJECT_PUBLIC_KEY_INFO subjPubKeyInfo;
-       OSStatus ortn = noErr;
+       OSStatus ortn = errSecSuccess;
 
        CSSM_KEYHEADER *hdr = &pubKey->KeyHeader;
        if(hdr->AlgorithmId != CSSM_ALGID_ECDSA) {
 
        CSSM_KEYHEADER *hdr = &pubKey->KeyHeader;
        if(hdr->AlgorithmId != CSSM_ALGID_ECDSA) {
index 85c58b6ebb8c7eef878baee6bbcc35abfa3165d7..081e8726a5df8ccd3b7056a46d30ead0544b05eb 100644 (file)
@@ -40,8 +40,8 @@
 #include <CoreFoundation/CoreFoundation.h>
 #include <Security/SecCertificate.h>
 #include <Security/SecCertificatePriv.h>
 #include <CoreFoundation/CoreFoundation.h>
 #include <Security/SecCertificate.h>
 #include <Security/SecCertificatePriv.h>
-#include <Security/SecInternal.h>
 #include <Security/oidsalg.h>
 #include <Security/oidsalg.h>
+#include "utilities/SecCFRelease.h"
 
 
 OSStatus
 
 
 OSStatus
@@ -89,7 +89,7 @@ SSLEncodeCertificate(SSLRecord *certificate, SSLContext *ctx)
     certificate->contentType = SSL_RecordTypeHandshake;
     certificate->protocolVersion = ctx->negProtocolVersion;
     head = SSLHandshakeHeaderSize(certificate);
     certificate->contentType = SSL_RecordTypeHandshake;
     certificate->protocolVersion = ctx->negProtocolVersion;
     head = SSLHandshakeHeaderSize(certificate);
-    if ((err = SSLAllocBuffer(&certificate->contents, totalLength + head + 3, ctx)) != 0)
+    if ((err = SSLAllocBuffer(&certificate->contents, totalLength + head + 3)))
         return err;
 
     charPtr = SSLEncodeHandshakeHeader(ctx, certificate, SSL_HdskCert, totalLength+3);
         return err;
 
     charPtr = SSLEncodeHandshakeHeader(ctx, certificate, SSL_HdskCert, totalLength+3);
@@ -134,7 +134,7 @@ SSLEncodeCertificate(SSLRecord *certificate, SSLContext *ctx)
        if(certCount == 0) {
                sslCertDebug("...sending empty cert msg");
        }
        if(certCount == 0) {
                sslCertDebug("...sending empty cert msg");
        }
-    return noErr;
+    return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -168,9 +168,9 @@ SSLProcessCertificate(SSLBuffer message, SSLContext *ctx)
 #ifdef USE_SSLCERTIFICATE
                cert = (SSLCertificate *)sslMalloc(sizeof(SSLCertificate));
                if(cert == NULL) {
 #ifdef USE_SSLCERTIFICATE
                cert = (SSLCertificate *)sslMalloc(sizeof(SSLCertificate));
                if(cert == NULL) {
-                       return memFullErr;
+                       return errSecAllocate;
                }
                }
-        if ((err = SSLAllocBuffer(&cert->derCert, certLen, ctx)) != 0)
+        if ((err = SSLAllocBuffer(&cert->derCert, certLen)
         {   sslFree(cert);
             return err;
         }
         {   sslFree(cert);
             return err;
         }
@@ -184,7 +184,7 @@ SSLProcessCertificate(SSLBuffer message, SSLContext *ctx)
                        certChain = CFArrayCreateMutable(kCFAllocatorDefault, 0,
                                &kCFTypeArrayCallBacks);
                        if (certChain == NULL) {
                        certChain = CFArrayCreateMutable(kCFAllocatorDefault, 0,
                                &kCFTypeArrayCallBacks);
                        if (certChain == NULL) {
-                               return memFullErr;
+                               return errSecAllocate;
                        }
                        if (ctx->peerCert) {
                                sslDebugLog("SSLProcessCertificate: releasing existing cert chain\n");
                        }
                        if (ctx->peerCert) {
                                sslDebugLog("SSLProcessCertificate: releasing existing cert chain\n");
@@ -193,20 +193,20 @@ SSLProcessCertificate(SSLBuffer message, SSLContext *ctx)
                        ctx->peerCert = certChain;
                }
                cert = SecCertificateCreateWithBytes(NULL, p, certLen);
                        ctx->peerCert = certChain;
                }
                cert = SecCertificateCreateWithBytes(NULL, p, certLen);
-               #if SSL_DEBUG
+               #if SSL_DEBUG && !TARGET_OS_IPHONE
                {
                        /* print cert name when debugging; leave disabled otherwise */
                        CFStringRef certName = NULL;
                        OSStatus status = SecCertificateInferLabel(cert, &certName);
                        char buf[1024];
                {
                        /* print cert name when debugging; leave disabled otherwise */
                        CFStringRef certName = NULL;
                        OSStatus status = SecCertificateInferLabel(cert, &certName);
                        char buf[1024];
-                       if (!certName || !CFStringGetCString(certName, buf, 1024-1, kCFStringEncodingUTF8)) { buf[0]=0; }
-                       sslDebugLog("SSLProcessCertificate: received \"%s\" (%ld bytes)\n", buf, certLen);
+                       if (status || !certName || !CFStringGetCString(certName, buf, 1024-1, kCFStringEncodingUTF8)) { buf[0]=0; }
+                       sslDebugLog("SSLProcessCertificate: err=%d, received \"%s\" (%ld bytes)\n",(int) status, buf, certLen);
                        CFReleaseSafe(certName);
                }
                #endif
                if (cert == NULL) {
                        sslErrorLog("SSLProcessCertificate: unable to create cert ref from data\n");
                        CFReleaseSafe(certName);
                }
                #endif
                if (cert == NULL) {
                        sslErrorLog("SSLProcessCertificate: unable to create cert ref from data\n");
-                       return memFullErr;
+                       return errSecAllocate;
                }
         p += certLen;
                /* Insert forwards; root cert will be last in linked list */
                }
         p += certLen;
                /* Insert forwards; root cert will be last in linked list */
@@ -225,7 +225,7 @@ SSLProcessCertificate(SSLBuffer message, SSLContext *ctx)
                         * we tried to authenticate, client doesn't have a cert, and
                         * app doesn't require it. OK.
                         */
                         * we tried to authenticate, client doesn't have a cert, and
                         * app doesn't require it. OK.
                         */
-                       return noErr;
+                       return errSecSuccess;
                }
                else {
                        AlertDescription desc;
                }
                else {
                        AlertDescription desc;
@@ -260,7 +260,7 @@ SSLProcessCertificate(SSLBuffer message, SSLContext *ctx)
         SSLFatalSessionAlert(desc, ctx);
     }
 
         SSLFatalSessionAlert(desc, ctx);
     }
 
-    if (err == noErr) {
+    if (err == errSecSuccess) {
         if(ctx->peerPubKey != NULL) {
             /* renegotiating - free old key first */
             sslFreePubKey(&ctx->peerPubKey);
         if(ctx->peerPubKey != NULL) {
             /* renegotiating - free old key first */
             sslFreePubKey(&ctx->peerPubKey);
@@ -343,7 +343,7 @@ SSLEncodeCertificateRequest(SSLRecord *request, SSLContext *ctx)
 
     request->protocolVersion = ctx->negProtocolVersion;
     head = SSLHandshakeHeaderSize(request);
 
     request->protocolVersion = ctx->negProtocolVersion;
     head = SSLHandshakeHeaderSize(request);
-    if ((err = SSLAllocBuffer(&request->contents, msgLen + head, ctx)) != 0)
+    if ((err = SSLAllocBuffer(&request->contents, msgLen + head)))
         return err;
 
     charPtr = SSLEncodeHandshakeHeader(ctx, request, SSL_HdskCertRequest, msgLen);
         return err;
 
     charPtr = SSLEncodeHandshakeHeader(ctx, request, SSL_HdskCertRequest, msgLen);
@@ -392,7 +392,7 @@ SSLEncodeCertificateRequest(SSLRecord *request, SSLContext *ctx)
     }
 
     assert(charPtr == request->contents.data + request->contents.length);
     }
 
     assert(charPtr == request->contents.data + request->contents.length);
-    return noErr;
+    return errSecSuccess;
 }
 
 #define SSL_ENABLE_ECDSA_SIGN_AUTH                     0
 }
 
 #define SSL_ENABLE_ECDSA_SIGN_AUTH                     0
@@ -492,11 +492,11 @@ SSLProcessCertificateRequest(SSLBuffer message, SSLContext *ctx)
                sslErrorLog("SSLProcessCertificateRequest: dnListLen error 2\n");
                return errSSLProtocol;
        }
                sslErrorLog("SSLProcessCertificateRequest: dnListLen error 2\n");
                return errSSLProtocol;
        }
-        if ((err = SSLAllocBuffer(&dnBuf, sizeof(DNListElem), ctx)) != 0)
+        if ((err = SSLAllocBuffer(&dnBuf, sizeof(DNListElem))))
             return err;
         dn = (DNListElem*)dnBuf.data;
             return err;
         dn = (DNListElem*)dnBuf.data;
-        if ((err = SSLAllocBuffer(&dn->derDN, dnLen, ctx)) != 0)
-        {   SSLFreeBuffer(&dnBuf, ctx);
+        if ((err = SSLAllocBuffer(&dn->derDN, dnLen)))
+        {   SSLFreeBuffer(&dnBuf);
             return err;
         }
         memcpy(dn->derDN.data, charPtr, dnLen);
             return err;
         }
         memcpy(dn->derDN.data, charPtr, dnLen);
@@ -508,7 +508,7 @@ SSLProcessCertificateRequest(SSLBuffer message, SSLContext *ctx)
 
     assert(charPtr == message.data + message.length);
 
 
     assert(charPtr == message.data + message.length);
 
-    return noErr;
+    return errSecSuccess;
 }
 
 
 }
 
 
@@ -536,7 +536,7 @@ OSStatus FindCertSigAlg(SSLContext *ctx,
         //Let's only support SHA1 and SHA256. SHA384 does not work with 512 bits RSA keys
         // We should actually test against what the client cert can do.
         if((alg->hash==SSL_HashAlgorithmSHA1) || (alg->hash==SSL_HashAlgorithmSHA256)) {
         //Let's only support SHA1 and SHA256. SHA384 does not work with 512 bits RSA keys
         // We should actually test against what the client cert can do.
         if((alg->hash==SSL_HashAlgorithmSHA1) || (alg->hash==SSL_HashAlgorithmSHA256)) {
-            return noErr;
+            return errSecSuccess;
         }
     }
     // We could not find a supported signature and hash algorithm
         }
     }
     // We could not find a supported signature and hash algorithm
@@ -600,7 +600,7 @@ SSLEncodeCertificateVerify(SSLRecord *certVerify, SSLContext *ctx)
     if ((err = ctx->sslTslCalls->computeCertVfyMac(ctx, &hashDataBuf, sigAlg.hash)) != 0)
         goto fail;
 
     if ((err = ctx->sslTslCalls->computeCertVfyMac(ctx, &hashDataBuf, sigAlg.hash)) != 0)
         goto fail;
 
-    if ((err = SSLAllocBuffer(&certVerify->contents, outputLen, ctx)) != 0)
+    if ((err = SSLAllocBuffer(&certVerify->contents, outputLen)) != 0)
         goto fail;
 
     /* Sign now to get the actual length */
         goto fail;
 
     /* Sign now to get the actual length */
@@ -652,7 +652,7 @@ SSLEncodeCertificateVerify(SSLRecord *certVerify, SSLContext *ctx)
         len = outputLen+2;
     }
        if(err) {
         len = outputLen+2;
     }
        if(err) {
-               sslErrorLog("SSLEncodeCertificateVerify: unable to sign data (error %d)\n", err);
+               sslErrorLog("SSLEncodeCertificateVerify: unable to sign data (error %d)\n", (int)err);
                goto fail;
        }
     // At this point:
                goto fail;
        }
     // At this point:
@@ -666,7 +666,7 @@ SSLEncodeCertificateVerify(SSLRecord *certVerify, SSLContext *ctx)
 
     assert(charPtr==(certVerify->contents.data+head));
 
 
     assert(charPtr==(certVerify->contents.data+head));
 
-    err = noErr;
+    err = errSecSuccess;
 
 fail:
 
 
 fail:
 
@@ -700,15 +700,15 @@ SSLProcessCertificateVerify(SSLBuffer message, SSLContext *ctx)
         switch (sigAlg.hash) {
             case SSL_HashAlgorithmSHA256:
                 algId.algorithm = CSSMOID_SHA256WithRSA;
         switch (sigAlg.hash) {
             case SSL_HashAlgorithmSHA256:
                 algId.algorithm = CSSMOID_SHA256WithRSA;
-                if(ctx->selectedCipherSpec.macAlgorithm->hmac->alg == HA_SHA384) {
+                if(ctx->selectedCipherSpecParams.macAlg == HA_SHA384) {
                     sslErrorLog("SSLProcessCertificateVerify: inconsistent hash, HA_SHA384\n");
                     return errSSLInternal;
                 }
                 break;
             case SSL_HashAlgorithmSHA384:
                 algId.algorithm = CSSMOID_SHA384WithRSA;
                     sslErrorLog("SSLProcessCertificateVerify: inconsistent hash, HA_SHA384\n");
                     return errSSLInternal;
                 }
                 break;
             case SSL_HashAlgorithmSHA384:
                 algId.algorithm = CSSMOID_SHA384WithRSA;
-                if(ctx->selectedCipherSpec.macAlgorithm->hmac->alg != HA_SHA384) {
-                    sslErrorLog("SSLProcessCertificateVerify: inconsistent hash, %d not HA_SHA384\n", ctx->selectedCipherSpec.macAlgorithm->hmac->alg);
+                if(ctx->selectedCipherSpecParams.macAlg != HA_SHA384) {
+                    sslErrorLog("SSLProcessCertificateVerify: inconsistent hash, %d not HA_SHA384\n", ctx->selectedCipherSpecParams.macAlg);
                     return errSSLInternal;
                 }
                 break;
                     return errSSLInternal;
                 }
                 break;
@@ -781,7 +781,7 @@ SSLProcessCertificateVerify(SSLBuffer message, SSLContext *ctx)
                SSLFatalSessionAlert(SSL_AlertDecryptError, ctx);
                goto fail;
        }
                SSLFatalSessionAlert(SSL_AlertDecryptError, ctx);
                goto fail;
        }
-    err = noErr;
+    err = errSecSuccess;
 
 fail:
     return err;
 
 fail:
     return err;
index eb830f8982560130f2a9918ff1e2e246cba502c1..bd28353ef9a5e3927b297d76fbf7db3ecde45966 100644 (file)
@@ -30,7 +30,7 @@
 #include "sslMemory.h"
 #include "sslAlertMessage.h"
 #include "sslDebug.h"
 #include "sslMemory.h"
 #include "sslAlertMessage.h"
 #include "sslDebug.h"
-#include "cipherSpecs.h"
+#include "sslCipherSpecs.h"
 
 #include <assert.h>
 #include <string.h>
 
 #include <assert.h>
 #include <string.h>
 OSStatus
 SSLEncodeChangeCipherSpec(SSLRecord *rec, SSLContext *ctx)
 {   OSStatus          err;
 OSStatus
 SSLEncodeChangeCipherSpec(SSLRecord *rec, SSLContext *ctx)
 {   OSStatus          err;
-
-    assert(ctx->writePending.ready);
-
+    
+    assert(ctx->writePending_ready);
+    
     sslLogNegotiateDebug("===Sending changeCipherSpec msg");
     rec->contentType = SSL_RecordTypeChangeCipher;
        assert(ctx->negProtocolVersion >= SSL_Version_3_0);
     rec->protocolVersion = ctx->negProtocolVersion;
     rec->contents.length = 1;
     sslLogNegotiateDebug("===Sending changeCipherSpec msg");
     rec->contentType = SSL_RecordTypeChangeCipher;
        assert(ctx->negProtocolVersion >= SSL_Version_3_0);
     rec->protocolVersion = ctx->negProtocolVersion;
     rec->contents.length = 1;
-    if ((err = SSLAllocBuffer(&rec->contents, 1, ctx)) != 0)
+    if ((err = SSLAllocBuffer(&rec->contents, 1)))
         return err;
     rec->contents.data[0] = 1;
 
     ctx->messageQueueContainsChangeCipherSpec=true;
 
         return err;
     rec->contents.data[0] = 1;
 
     ctx->messageQueueContainsChangeCipherSpec=true;
 
-    return noErr;
+    return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -96,44 +96,26 @@ SSLProcessChangeCipherSpec(SSLRecord rec, SSLContext *ctx)
                SSLChangeHdskState(ctx, SSL_HdskStateChangeCipherSpec);
        }
 
                SSLChangeHdskState(ctx, SSL_HdskStateChangeCipherSpec);
        }
 
-    if (!ctx->readPending.ready || ctx->state != SSL_HdskStateChangeCipherSpec)
+    if (!ctx->readPending_ready || ctx->state != SSL_HdskStateChangeCipherSpec)
     {
         if(ctx->isDTLS)
             return errSSLWouldBlock;
 
         SSLFatalSessionAlert(SSL_AlertUnexpectedMsg, ctx);
        sslErrorLog("***bad changeCipherSpec msg: readPending.ready %d state %d\n",
     {
         if(ctx->isDTLS)
             return errSSLWouldBlock;
 
         SSLFatalSessionAlert(SSL_AlertUnexpectedMsg, ctx);
        sslErrorLog("***bad changeCipherSpec msg: readPending.ready %d state %d\n",
-               (unsigned)ctx->readPending.ready, (unsigned)ctx->state);
+               (unsigned)ctx->readPending_ready, (unsigned)ctx->state);
         return errSSLProtocol;
     }
 
     sslLogNegotiateDebug("===Processing changeCipherSpec msg");
 
     /* Install new cipher spec on read side */
         return errSSLProtocol;
     }
 
     sslLogNegotiateDebug("===Processing changeCipherSpec msg");
 
     /* Install new cipher spec on read side */
-    if ((err = SSLDisposeCipherSuite(&ctx->readCipher, ctx)) != 0)
+    if ((err = ctx->recFuncs->advanceReadCipher(ctx->recCtx)) != 0)
     {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
         return err;
     }
     {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
         return err;
     }
-    ctx->readCipher = ctx->readPending;
-    ctx->readCipher.ready = 0;      /* Can't send data until Finished is sent */
+    ctx->readCipher_ready = 0;      /* Can't send data until Finished is sent */
     SSLChangeHdskState(ctx, SSL_HdskStateFinished);
     SSLChangeHdskState(ctx, SSL_HdskStateFinished);
-    memset(&ctx->readPending, 0, sizeof(CipherContext));       /* Zero out old data */
-    return noErr;
+    return errSecSuccess;
 }
 
 }
 
-OSStatus
-SSLDisposeCipherSuite(CipherContext *cipher, SSLContext *ctx)
-{   OSStatus      err;
-
-       /* symmetric encryption context */
-       if(cipher->symCipher) {
-               if ((err = cipher->symCipher->finish(cipher, ctx)) != 0) {
-                       return err;
-               }
-       }
-
-       /* per-record hash/hmac context */
-       ctx->sslTslCalls->freeMac(cipher);
-
-    return noErr;
-}
diff --git a/libsecurity_ssl/lib/sslCipherSpecs.c b/libsecurity_ssl/lib/sslCipherSpecs.c
new file mode 100644 (file)
index 0000000..ca52036
--- /dev/null
@@ -0,0 +1,661 @@
+/*
+ * Copyright (c) 1999-2001,2005-2011 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * cipherSpecs.c - SSLCipherSpec declarations
+ */
+
+#include "sslBuildFlags.h"
+#include "CipherSuite.h"
+#include "sslContext.h"
+#include "sslCipherSpecs.h"
+#include "sslDebug.h"
+#include "sslMemory.h"
+#include "sslDebug.h"
+#include "sslUtils.h"
+#include "sslPriv.h"
+#include "sslCrypto.h"
+
+#include <string.h>
+#include <assert.h>
+#include <Security/SecBase.h>
+#include <utilities/array_size.h>
+
+#include <TargetConditionals.h>
+
+
+#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
+
+#define ENABLE_ECDH                    1
+#define ENABLE_AES_GCM                  0
+
+#define ENABLE_PSK                      1
+
+#if    APPLE_DH
+#define ENABLE_DH_ANON                 1
+#define ENABLE_DH_EPHEM_RSA            1
+#if USE_CDSA_CRYPTO
+#define ENABLE_DH_EPHEM_DSA            1
+#else
+#define ENABLE_DH_EPHEM_DSA            0
+#endif
+#else
+#define ENABLE_DH_ANON                 0
+#define ENABLE_DH_EPHEM_RSA            0
+#define ENABLE_DH_EPHEM_DSA            0
+#endif /* APPLE_DH */
+
+/*
+ * List of all CipherSpecs we implement. Depending on a context's
+ * exportable flag, not all of these might be available for use.
+ */
+/* Order by preference, domestic first */
+static const SSLCipherSuite KnownCipherSuites[] = {
+#if ENABLE_AES_GCM
+    TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+#endif
+    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
+    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
+    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+    TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
+    TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
+#if ENABLE_AES_GCM
+    TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+    TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+#endif
+    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
+    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
+    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+    TLS_ECDHE_RSA_WITH_RC4_128_SHA,
+    TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
+#if ENABLE_ECDH
+#if ENABLE_AES_GCM
+    TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
+    TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
+#endif
+    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
+    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
+#if ENABLE_AES_GCM
+    TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,
+    TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
+#endif
+    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,
+    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
+    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
+    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
+    TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
+    TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
+    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
+    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
+    TLS_ECDH_RSA_WITH_RC4_128_SHA,
+    TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
+#endif
+#if ENABLE_AES_GCM
+    TLS_RSA_WITH_AES_256_GCM_SHA384,
+    TLS_RSA_WITH_AES_128_GCM_SHA256,
+#endif
+    TLS_RSA_WITH_AES_256_CBC_SHA256,
+    TLS_RSA_WITH_AES_128_CBC_SHA256,
+    TLS_RSA_WITH_AES_128_CBC_SHA,
+    SSL_RSA_WITH_RC4_128_SHA,
+    SSL_RSA_WITH_RC4_128_MD5,
+    TLS_RSA_WITH_AES_256_CBC_SHA,
+    SSL_RSA_WITH_3DES_EDE_CBC_SHA,
+#if ENABLE_SSLV2
+    SSL_RSA_WITH_3DES_EDE_CBC_MD5,
+#endif
+#if ENABLE_DES
+    SSL_RSA_WITH_DES_CBC_SHA,
+#endif
+#if ENABLE_SSLV2
+    SSL_RSA_WITH_DES_CBC_MD5,
+#endif
+#if ENABLE_RC2
+    SSL_RSA_WITH_RC2_CBC_MD5,
+#endif
+#if ENABLE_AES_GCM
+#  if ENABLE_DH_EPHEM_DSA
+    TLS_DHE_DSS_WITH_AES_256_GCM_SHA384,
+#  endif // ENABLE_DH_EPHEM_DSA
+    TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
+#  if ENABLE_DH_EPHEM_DSA
+    TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,
+#  endif // ENABLE_DH_EPHEM_DSA
+    TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
+#endif // ENABLE_AES_GCM
+#if ENABLE_DH_EPHEM_DSA
+    TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,
+#endif
+    TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
+#if ENABLE_DH_EPHEM_DSA
+    TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,
+#endif
+    TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
+#if ENABLE_DH_EPHEM_DSA
+    TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
+#endif
+    TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
+#if ENABLE_DH_EPHEM_DSA
+    TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
+#endif
+    TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
+    SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
+#if ENABLE_DES
+    SSL_DHE_RSA_WITH_DES_CBC_SHA,
+#endif
+#if ENABLE_DH_EPHEM_DSA
+    SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
+#if ENABLE_DES
+    SSL_DHE_DSS_WITH_DES_CBC_SHA,
+#endif
+#endif
+#if ENABLE_AES_GCM
+    TLS_DH_anon_WITH_AES_256_GCM_SHA384,
+    TLS_DH_anon_WITH_AES_128_GCM_SHA256,
+#endif
+    TLS_DH_anon_WITH_AES_128_CBC_SHA256,
+    TLS_DH_anon_WITH_AES_256_CBC_SHA256,
+    TLS_DH_anon_WITH_AES_128_CBC_SHA,
+    TLS_DH_anon_WITH_AES_256_CBC_SHA,
+    SSL_DH_anon_WITH_RC4_128_MD5,
+    SSL_DH_anon_WITH_3DES_EDE_CBC_SHA,
+#if ENABLE_DES
+    SSL_DH_anon_WITH_DES_CBC_SHA,
+#endif
+    TLS_ECDHE_ECDSA_WITH_NULL_SHA,
+    TLS_ECDHE_RSA_WITH_NULL_SHA,
+#if ENABLE_ECDH
+    TLS_ECDH_ECDSA_WITH_NULL_SHA,
+    TLS_ECDH_RSA_WITH_NULL_SHA,
+#endif
+
+#if ENABLE_PSK
+    TLS_PSK_WITH_AES_256_CBC_SHA384,
+    TLS_PSK_WITH_AES_128_CBC_SHA256,
+    TLS_PSK_WITH_AES_256_CBC_SHA,
+    TLS_PSK_WITH_AES_128_CBC_SHA,
+    TLS_PSK_WITH_RC4_128_SHA,
+    TLS_PSK_WITH_3DES_EDE_CBC_SHA,
+    TLS_PSK_WITH_NULL_SHA384,
+    TLS_PSK_WITH_NULL_SHA256,
+    TLS_PSK_WITH_NULL_SHA,
+#endif
+
+    TLS_RSA_WITH_NULL_SHA256,
+    SSL_RSA_WITH_NULL_SHA,
+    SSL_RSA_WITH_NULL_MD5
+
+#if 0
+    /* We don't support these yet. */
+    TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
+    TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
+    TLS_RSA_WITH_RC4_128_SHA,
+    TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+    TLS_RSA_WITH_RC4_128_MD5,
+    TLS_DH_DSS_WITH_AES_256_GCM_SHA384,
+    TLS_DH_DSS_WITH_AES_128_GCM_SHA256,
+    TLS_DH_RSA_WITH_AES_256_GCM_SHA384,
+    TLS_DH_RSA_WITH_AES_128_GCM_SHA256,
+    TLS_DH_DSS_WITH_AES_256_CBC_SHA256,
+    TLS_DH_RSA_WITH_AES_256_CBC_SHA256,
+    TLS_DH_DSS_WITH_AES_128_CBC_SHA256,
+    TLS_DH_RSA_WITH_AES_128_CBC_SHA256,
+    TLS_DH_DSS_WITH_AES_256_CBC_SHA,
+    TLS_DH_RSA_WITH_AES_256_CBC_SHA,
+       TLS_DH_DSS_WITH_AES_128_CBC_SHA,
+    TLS_DH_RSA_WITH_AES_128_CBC_SHA,
+    TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA,
+    TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA,
+    TLS_ECDH_anon_WITH_AES_256_CBC_SHA,
+       TLS_ECDH_anon_WITH_AES_128_CBC_SHA,
+    TLS_ECDH_anon_WITH_RC4_128_SHA,
+    TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA,
+    TLS_ECDH_anon_WITH_NULL_SHA,
+#endif
+};
+
+static const unsigned CipherSuiteCount = array_size(KnownCipherSuites);
+
+
+/*
+ * Given a valid ctx->validCipherSpecs array, calculate how many of those
+ * cipherSpecs are *not* SSLv2 only, storing result in
+ * ctx->numValidNonSSLv2Specs. ClientHello routines need this to set
+ * up outgoing cipherSpecs arrays correctly.
+ *
+ * Also determines if any ECDSA/ECDH ciphers are enabled; we need to know
+ * that when creating a hello message.
+ */
+static void sslAnalyzeCipherSpecs(SSLContext *ctx)
+{
+       unsigned                dex;
+       const SSLCipherSuite *cipherSuite;
+
+#if ENABLE_SSLV2
+       ctx->numValidNonSSLv2Suites = 0;
+#endif
+       cipherSuite = &ctx->validCipherSuites[0];
+       ctx->ecdsaEnable = false;
+       for(dex=0; dex<ctx->numValidCipherSuites; dex++, cipherSuite++) {
+#if ENABLE_SSLV2
+               if(!CIPHER_SPEC_IS_SSLv2(*cipherSuite)) {
+                       ctx->numValidNonSSLv2Suites++;
+               }
+#endif
+               switch(sslCipherSuiteGetKeyExchangeMethod(*cipherSuite)) {
+                       case SSL_ECDH_ECDSA:
+                       case SSL_ECDHE_ECDSA:
+                       case SSL_ECDH_RSA:
+                       case SSL_ECDHE_RSA:
+                       case SSL_ECDH_anon:
+                               ctx->ecdsaEnable = true;
+                               break;
+                       default:
+                               break;
+               }
+       }
+}
+
+/*
+ * Build ctx->validCipherSpecs as a copy of KnownCipherSpecs, assuming that
+ * validCipherSpecs is currently not valid (i.e., SSLSetEnabledCiphers() has
+ * not been called).
+ */
+OSStatus sslBuildCipherSuiteArray(SSLContext *ctx)
+{
+       size_t          size;
+       unsigned        dex;
+
+       assert(ctx != NULL);
+       assert(ctx->validCipherSuites == NULL);
+
+       ctx->numValidCipherSuites = CipherSuiteCount;
+       size = CipherSuiteCount * sizeof(SSLCipherSuite);
+       ctx->validCipherSuites = (SSLCipherSuite *)sslMalloc(size);
+       if(ctx->validCipherSuites == NULL) {
+               ctx->numValidCipherSuites = 0;
+               return errSecAllocate;
+       }
+
+       /*
+        * Trim out inappropriate ciphers:
+        *  -- trim anonymous ciphers if !ctx->anonCipherEnable
+        *  -- trim ECDSA ciphers for server side if appropriate
+        *  -- trim ECDSA ciphers if TLSv1 disable or SSLv2 enabled (since
+        *     we MUST do the Client Hello extensions to make these ciphers
+        *     work reliably)
+         *  -- trim Stream ciphers if DTLSv1 enable
+        */
+       SSLCipherSuite *dst = ctx->validCipherSuites;
+       const SSLCipherSuite *src = KnownCipherSuites;
+
+       bool trimECDSA = false;
+       if((ctx->protocolSide == kSSLServerSide) && !SSL_ECDSA_SERVER) {
+               trimECDSA = true;
+       }
+       if(ctx->minProtocolVersion == SSL_Version_2_0
+       || ctx->maxProtocolVersion == SSL_Version_3_0) {
+        /* We trim ECDSA cipher suites if SSL2 is enabled or
+           The maximum allowed protocol is SSL3.  Note that this
+           won't trim ECDSA cipherspecs for DTLS which should be
+           the right thing to do here. */
+               trimECDSA = true;
+       }
+
+    /* trim Stream Ciphers for DTLS */
+    bool trimRC4 = ctx->isDTLS;
+
+    bool trimDHE = (ctx->protocolSide == kSSLServerSide) &&
+        !ctx->dhParamsEncoded.length;
+
+       for(dex=0; dex<CipherSuiteCount; dex++) {
+        KeyExchangeMethod kem = sslCipherSuiteGetKeyExchangeMethod(*src);
+        uint8_t keySize = sslCipherSuiteGetSymmetricCipherKeySize(*src);
+        HMAC_Algs mac = sslCipherSuiteGetMacAlgorithm(*src);
+        SSL_CipherAlgorithm cipher = sslCipherSuiteGetSymmetricCipherAlgorithm(*src);
+               /* First skip ECDSA ciphers as appropriate */
+               switch(kem) {
+                       case SSL_ECDH_ECDSA:
+                       case SSL_ECDHE_ECDSA:
+                       case SSL_ECDH_RSA:
+                       case SSL_ECDHE_RSA:
+                       case SSL_ECDH_anon:
+                               if(trimECDSA) {
+                                       /* Skip this one */
+                                       ctx->numValidCipherSuites--;
+                                       src++;
+                                       continue;
+                               }
+                               else {
+                                       break;
+                               }
+                       default:
+                               break;
+               }
+               if(!ctx->anonCipherEnable) {
+                       /* trim out the anonymous (and null-auth-cipher) ciphers */
+                       if(mac == HA_Null) {
+                /* skip this one */
+                               ctx->numValidCipherSuites--;
+                               src++;
+                               continue;
+                       }
+                       switch(kem) {
+                               case SSL_DH_anon:
+                               case SSL_DH_anon_EXPORT:
+                               case SSL_ECDH_anon:
+                                       /* skip this one */
+                                       ctx->numValidCipherSuites--;
+                                       src++;
+                                       continue;
+                               default:
+                                       break;
+                       }
+               }
+        if(ctx->falseStartEnabled) {
+            switch(kem){
+                case SSL_ECDHE_ECDSA:
+                case SSL_ECDHE_RSA:
+                case SSL_DHE_RSA:
+                case SSL_DHE_DSS:
+                    /* Ok for false start */
+                    break;
+                default:
+                                       /* Not ok, skip */
+                                       ctx->numValidCipherSuites--;
+                                       src++;
+                                       continue;
+            }
+            switch(cipher) {
+                case SSL_CipherAlgorithmAES_128_CBC:
+                case SSL_CipherAlgorithmAES_128_GCM:
+                case SSL_CipherAlgorithmAES_256_CBC:
+                case SSL_CipherAlgorithmAES_256_GCM:
+                case SSL_CipherAlgorithmRC4_128:
+                    /* Ok for false start */
+                    break;
+                default:
+                                       /* Not ok, skip*/
+                                       ctx->numValidCipherSuites--;
+                                       src++;
+                                       continue;
+            }
+        }
+
+        /* This will skip the simple DES cipher suites, but not the NULL cipher ones */
+        if (keySize == 8)
+        {
+            /* skip this one */
+            ctx->numValidCipherSuites--;
+            src++;
+            continue;
+        }
+
+        /* Trim PSK ciphersuites, they need to be enabled explicitely */
+        if (kem==TLS_PSK) {
+            ctx->numValidCipherSuites--;
+            src++;
+            continue;
+        }
+
+        if (trimDHE) {
+                       switch(kem) {
+                               case SSL_DHE_DSS:
+                               case SSL_DHE_DSS_EXPORT:
+                               case SSL_DHE_RSA:
+                               case SSL_DHE_RSA_EXPORT:
+                                       /* skip this one */
+                                       ctx->numValidCipherSuites--;
+                                       src++;
+                                       continue;
+                               default:
+                                       break;
+                       }
+               }
+
+        if (trimRC4 && (cipher==SSL_CipherAlgorithmRC4_128)) {
+            ctx->numValidCipherSuites--;
+            src++;
+            continue;
+        }
+
+        if(cipher==SSL_CipherAlgorithmNull) {
+            ctx->numValidCipherSuites--;
+            src++;
+            continue;
+        }
+
+        /* This one is good to go */
+        *dst++ = *src++;
+       }
+       sslAnalyzeCipherSpecs(ctx);
+       return errSecSuccess;
+}
+
+/*
+ * Convert an array of SSLCipherSuites (which is always KnownCipherSpecs)
+ * to an array of SSLCipherSuites.
+ */
+static OSStatus
+cipherSuitesToCipherSuites(
+                          size_t                               numCipherSuites,
+                          const SSLCipherSuite *cipherSuites,
+                          SSLCipherSuite               *ciphers,               /* RETURNED */
+                          size_t                               *numCiphers)    /* IN/OUT */
+{
+       if(*numCiphers < numCipherSuites) {
+               return errSSLBufferOverflow;
+       }
+    memcpy(ciphers, cipherSuites, numCipherSuites * sizeof(SSLCipherSuite));
+       *numCiphers = numCipherSuites;
+       return errSecSuccess;
+}
+
+/***
+ *** 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,
+                                                         size_t                *numCiphers)
+{
+       if((ctx == NULL) || (numCiphers == NULL)) {
+               return errSecParam;
+       }
+       *numCiphers = CipherSuiteCount;
+       return errSecSuccess;
+}
+
+OSStatus
+SSLGetSupportedCiphers          (SSLContextRef         ctx,
+                                                         SSLCipherSuite        *ciphers,               /* RETURNED */
+                                                         size_t                        *numCiphers)    /* IN/OUT */
+{
+       if((ctx == NULL) || (ciphers == NULL) || (numCiphers == NULL)) {
+               return errSecParam;
+       }
+       return cipherSuitesToCipherSuites(CipherSuiteCount,
+               KnownCipherSuites,
+               ciphers,
+               numCiphers);
+}
+
+/*
+ * Specify a (typically) 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 NOT the same as the complete set of supported
+ * SSLCipherSuites as obtained by SSLGetSupportedCiphers().
+ */
+OSStatus
+SSLSetEnabledCiphers           (SSLContextRef                  ctx,
+                                                        const SSLCipherSuite   *ciphers,
+                                                        size_t                                 numCiphers)
+{
+       size_t size;
+    size_t foundCiphers=0;
+       unsigned callerDex;
+       unsigned tableDex;
+
+       if((ctx == NULL) || (ciphers == NULL) || (numCiphers == 0)) {
+               return errSecParam;
+       }
+       if(sslIsSessionActive(ctx)) {
+               /* can't do this with an active session */
+               return errSecBadReq;
+       }
+       size = numCiphers * sizeof(SSLCipherSuite);
+       ctx->validCipherSuites = (SSLCipherSuite *)sslMalloc(size);
+       if(ctx->validCipherSuites == NULL) {
+               ctx->numValidCipherSuites = 0;
+               return errSecAllocate;
+       }
+
+       /*
+        * Run thru caller's specs, keep only the supported ones.
+        */
+    for(callerDex=0; callerDex<numCiphers; callerDex++) {
+        /* find matching CipherSpec in our known table */
+        for(tableDex=0; tableDex<CipherSuiteCount; tableDex++) {
+            if(ciphers[callerDex] == KnownCipherSuites[tableDex]) {
+                ctx->validCipherSuites[foundCiphers] = KnownCipherSuites[tableDex];
+                foundCiphers++;
+                break;
+            }
+        }
+       }
+
+    if(foundCiphers==0) {
+        /* caller specified only unsupported ciphersuites */
+        sslFree(ctx->validCipherSuites);
+        ctx->validCipherSuites = NULL;
+        return errSSLBadCipherSuite;
+    }
+    
+       /* success */
+       ctx->numValidCipherSuites = foundCiphers;
+       sslAnalyzeCipherSpecs(ctx);
+       return errSecSuccess;
+}
+
+/*
+ * 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,
+                                                        size_t                                 *numCiphers)
+{
+       if((ctx == NULL) || (numCiphers == NULL)) {
+               return errSecParam;
+       }
+       if(ctx->validCipherSuites == NULL) {
+               /* hasn't been set; use default */
+               *numCiphers = CipherSuiteCount;
+       }
+       else {
+               /* caller set via SSLSetEnabledCiphers */
+               *numCiphers = ctx->numValidCipherSuites;
+       }
+       return errSecSuccess;
+}
+
+OSStatus
+SSLGetEnabledCiphers           (SSLContextRef                  ctx,
+                                                        SSLCipherSuite                 *ciphers,               /* RETURNED */
+                                                        size_t                                 *numCiphers)    /* IN/OUT */
+{
+       if((ctx == NULL) || (ciphers == NULL) || (numCiphers == NULL)) {
+               return errSecParam;
+       }
+       if(ctx->validCipherSuites == NULL) {
+               /* hasn't been set; use default */
+               return cipherSuitesToCipherSuites(CipherSuiteCount,
+                       KnownCipherSuites,
+                       ciphers,
+                       numCiphers);
+       }
+       else {
+               /* use the ones specified in SSLSetEnabledCiphers() */
+               return cipherSuitesToCipherSuites(ctx->numValidCipherSuites,
+                       ctx->validCipherSuites,
+                       ciphers,
+                       numCiphers);
+       }
+}
+
+/***
+ *** End of publically exported functions declared in SecureTransport.h
+ ***/
+
+void InitCipherSpecParams(SSLContext *ctx)
+{
+    SSLCipherSpecParams *dst = &ctx->selectedCipherSpecParams;
+    dst->cipherSpec = ctx->selectedCipher;
+    dst->macSize = sslCipherSuiteGetMacSize(ctx->selectedCipher);
+    dst->macAlg = sslCipherSuiteGetMacAlgorithm(ctx->selectedCipher);
+    dst->keySize = sslCipherSuiteGetSymmetricCipherKeySize(ctx->selectedCipher);
+    dst->blockSize = sslCipherSuiteGetSymmetricCipherBlockIvSize(ctx->selectedCipher);
+    dst->ivSize = dst->blockSize;
+    dst->keyExchangeMethod = sslCipherSuiteGetKeyExchangeMethod(ctx->selectedCipher);
+};
+
+
+OSStatus
+FindCipherSpec(SSLContext *ctx)
+{
+       unsigned i;
+
+    assert(ctx != NULL);
+    assert(ctx->validCipherSuites != NULL);
+
+    for (i=0; i<ctx->numValidCipherSuites; i++)
+    {
+        if (ctx->validCipherSuites[i] == ctx->selectedCipher) {
+            InitCipherSpecParams(ctx);
+            /* Make sure we're configured to handle this cipherSuite. */
+            return sslVerifySelectedCipher(ctx);
+        }
+    }
+    /* Not found */
+    return errSSLNegotiation;
+}
diff --git a/libsecurity_ssl/lib/sslCipherSpecs.h b/libsecurity_ssl/lib/sslCipherSpecs.h
new file mode 100644 (file)
index 0000000..724d9d1
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1999-2001,2005-2007,2010-2011 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * cipherSpecs.h - SSLCipherSpec declarations
+ */
+
+#ifndef        _SSL_CIPHER_SPECS_H_
+#define _SSL_CIPHER_SPECS_H_
+
+#include "sslContext.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+    /*
+ * Build ctx->validCipherSuites as a copy of all known CipherSpecs.
+ */
+OSStatus sslBuildCipherSuiteArray(SSLContext *ctx);
+
+/*
+ * Initialize dst based on selectedCipher.
+ */
+void InitCipherSpecParams(SSLContext *ctx);
+
+/*
+ * Given a valid ctx->selectedCipher and ctx->validCipherSuites, set
+ * ctx->selectedCipherSpec as appropriate. Return an error if
+ * ctx->selectedCipher could not be set as the current ctx->selectedCipherSpec.
+ */
+OSStatus FindCipherSpec(SSLContext *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CIPHER_SPECS_H_ */
index 599996d5c5c6ef082f13cd6314d5493f99c57eec..c041afaac6a1ecb9fc324c576a420d0108ebd8d7 100644 (file)
  * sslContext.c - SSLContext accessors
  */
 
  * sslContext.c - SSLContext accessors
  */
 
+#include "SecureTransport.h"
+
+#include "SSLRecordInternal.h"
+#include "SecureTransportPriv.h"
+#include "appleSession.h"
 #include "ssl.h"
 #include "ssl.h"
+#include "sslCipherSpecs.h"
 #include "sslContext.h"
 #include "sslContext.h"
-#include "sslMemory.h"
-#include "sslDigests.h"
-#include "sslDebug.h"
 #include "sslCrypto.h"
 #include "sslCrypto.h"
+#include "sslDebug.h"
+#include "sslDigests.h"
+#include "sslKeychain.h"
+#include "sslMemory.h"
+#include "sslUtils.h"
 
 
-#include "SecureTransport.h"
-
+#include <AssertMacros.h>
 #include <CoreFoundation/CFData.h>
 #include <CoreFoundation/CFPreferences.h>
 #include <CoreFoundation/CFData.h>
 #include <CoreFoundation/CFPreferences.h>
-
+#include <Security/SecCertificate.h>
+#include <Security/SecCertificatePriv.h>
 #include <Security/SecTrust.h>
 #include <Security/SecTrust.h>
-#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
-#include <Security/oidsalg.h>
 #include <Security/SecTrustSettingsPriv.h>
 #include <Security/SecTrustSettingsPriv.h>
-#endif
-
-#include "sslKeychain.h"
-#include "sslUtils.h"
-#include "cipherSpecs.h"
-#include "appleSession.h"
-#include "SecureTransportPriv.h"
-#include <string.h>
+#include <Security/oidsalg.h>
+#include "utilities/SecCFRelease.h"
 #include <pthread.h>
 #include <pthread.h>
-#include <Security/SecCertificate.h>
-#include <Security/SecCertificatePriv.h>
+#include <string.h>
+
+#if TARGET_OS_IPHONE
 #include <Security/SecCertificateInternal.h>
 #include <Security/SecCertificateInternal.h>
-#include <Security/SecInternal.h>
-#include <Security/SecTrust.h>
+#else
 #include <Security/oidsalg.h>
 #include <Security/oidsalg.h>
+#include <Security/oidscert.h>
 #include <Security/SecTrustSettingsPriv.h>
 #include <Security/SecTrustSettingsPriv.h>
-#include <AssertMacros.h>
+#endif
+
 
 static void sslFreeDnList(
        SSLContext *ctx)
 
 static void sslFreeDnList(
        SSLContext *ctx)
@@ -66,8 +68,8 @@ static void sslFreeDnList(
 
     dn = ctx->acceptableDNList;
     while (dn)
 
     dn = ctx->acceptableDNList;
     while (dn)
-    {
-       SSLFreeBuffer(&dn->derDN, ctx);
+    {   
+       SSLFreeBuffer(&dn->derDN);
         nextDN = dn->next;
         sslFree(dn);
         dn = nextDN;
         nextDN = dn->next;
         sslFree(dn);
         dn = nextDN;
@@ -75,8 +77,21 @@ static void sslFreeDnList(
     ctx->acceptableDNList = NULL;
 }
 
     ctx->acceptableDNList = NULL;
 }
 
-#define min(a,b)       ( ((a) < (b)) ? (a) : (b) )
-#define max(a,b)       ( ((a) > (b)) ? (a) : (b) )
+
+Boolean sslIsSessionActive(const SSLContext *ctx)
+{
+       assert(ctx != NULL);
+       switch(ctx->state) {
+               case SSL_HdskStateUninit:
+               case SSL_HdskStateServerUninit:
+               case SSL_HdskStateClientUninit:
+               case SSL_HdskStateGracefulClose:
+               case SSL_HdskStateErrorClose:
+                       return false;
+               default:
+                       return true;
+       }
+}
 
 /*
  * Minimum and maximum supported versions
 
 /*
  * Minimum and maximum supported versions
@@ -108,6 +123,10 @@ static CFStringRef _sslContextDescribe(CFTypeRef arg);
 
 static void _SSLContextReadDefault()
 {
 
 static void _SSLContextReadDefault()
 {
+       /* 0 = disabled, 1 = split every write, 2 = split second and subsequent writes */
+    /* Enabled by default, this make cause some interop issues, see <rdar://problem/12307662> and <rdar://problem/12323307> */
+    const int defaultSplitDefaultValue = 2;
+
        CFTypeRef value = (CFTypeRef)CFPreferencesCopyValue(CFSTR("SSLWriteSplit"),
                                                        CFSTR("com.apple.security"),
                                                        kCFPreferencesAnyUser,
        CFTypeRef value = (CFTypeRef)CFPreferencesCopyValue(CFSTR("SSLWriteSplit"),
                                                        CFSTR("com.apple.security"),
                                                        kCFPreferencesAnyUser,
@@ -117,15 +136,15 @@ static void _SSLContextReadDefault()
                        kSplitDefaultValue = CFBooleanGetValue((CFBooleanRef)value) ? 1 : 0;
                else if (CFGetTypeID(value) == CFNumberGetTypeID()) {
                        if (!CFNumberGetValue((CFNumberRef)value, kCFNumberIntType, &kSplitDefaultValue))
                        kSplitDefaultValue = CFBooleanGetValue((CFBooleanRef)value) ? 1 : 0;
                else if (CFGetTypeID(value) == CFNumberGetTypeID()) {
                        if (!CFNumberGetValue((CFNumberRef)value, kCFNumberIntType, &kSplitDefaultValue))
-                               kSplitDefaultValue = 0;
+                               kSplitDefaultValue = defaultSplitDefaultValue;
                }
                if (kSplitDefaultValue < 0 || kSplitDefaultValue > 2) {
                }
                if (kSplitDefaultValue < 0 || kSplitDefaultValue > 2) {
-                       kSplitDefaultValue = 0;
+                       kSplitDefaultValue = defaultSplitDefaultValue;
                }
                CFRelease(value);
        }
        else {
                }
                CFRelease(value);
        }
        else {
-               kSplitDefaultValue = 0;
+               kSplitDefaultValue = defaultSplitDefaultValue;
        }
 }
 
        }
 }
 
@@ -160,20 +179,38 @@ SSLNewContext                             (Boolean                        isServer,
                                                         SSLContextRef          *contextPtr)    /* RETURNED */
 {
        if(contextPtr == NULL) {
                                                         SSLContextRef          *contextPtr)    /* RETURNED */
 {
        if(contextPtr == NULL) {
-               return paramErr;
+               return errSecParam;
        }
 
        *contextPtr = SSLCreateContext(kCFAllocatorDefault, isServer?kSSLServerSide:kSSLClientSide, kSSLStreamType);
 
        if (*contextPtr == NULL)
        }
 
        *contextPtr = SSLCreateContext(kCFAllocatorDefault, isServer?kSSLServerSide:kSSLClientSide, kSSLStreamType);
 
        if (*contextPtr == NULL)
-               return memFullErr;
+               return errSecAllocate;
 
 
-       return noErr;
+       return errSecSuccess;
 }
 
 SSLContextRef SSLCreateContext(CFAllocatorRef alloc, SSLProtocolSide protocolSide, SSLConnectionType connectionType)
 {
 }
 
 SSLContextRef SSLCreateContext(CFAllocatorRef alloc, SSLProtocolSide protocolSide, SSLConnectionType connectionType)
 {
-       OSStatus        serr = noErr;
+    SSLContextRef ctx;
+    
+    ctx = SSLCreateContextWithRecordFuncs(alloc, protocolSide, connectionType, &SSLRecordLayerInternal);
+    
+    if(ctx==NULL)
+        return NULL;
+    
+    ctx->recCtx = SSLCreateInternalRecordLayer(connectionType);
+    if(ctx->recCtx==NULL) {
+       CFRelease(ctx);
+               return NULL;
+    }
+    
+    return ctx;
+}
+
+SSLContextRef SSLCreateContextWithRecordFuncs(CFAllocatorRef alloc, SSLProtocolSide protocolSide, SSLConnectionType connectionType, const struct SSLRecordFuncs *recFuncs)
+{
+       OSStatus        serr = errSecSuccess;
        SSLContext *ctx = (SSLContext*) _CFRuntimeCreateInstance(alloc, SSLContextGetTypeID(), sizeof(SSLContext) - sizeof(CFRuntimeBase), NULL);
 
        if(ctx == NULL) {
        SSLContext *ctx = (SSLContext*) _CFRuntimeCreateInstance(alloc, SSLContextGetTypeID(), sizeof(SSLContext) - sizeof(CFRuntimeBase), NULL);
 
        if(ctx == NULL) {
@@ -204,18 +241,11 @@ SSLContextRef SSLCreateContext(CFAllocatorRef alloc, SSLProtocolSide protocolSid
        /* Default value so we can send and receive hello msgs */
        ctx->sslTslCalls = &Ssl3Callouts;
 
        /* Default value so we can send and receive hello msgs */
        ctx->sslTslCalls = &Ssl3Callouts;
 
-    /* Initialize the cipher state to NULL_WITH_NULL_NULL */
+    ctx->recFuncs = recFuncs;
 
 
+    /* Initialize the cipher state to NULL_WITH_NULL_NULL */
     ctx->selectedCipher        = TLS_NULL_WITH_NULL_NULL;
     ctx->selectedCipher        = TLS_NULL_WITH_NULL_NULL;
-    InitCipherSpec(ctx);
-    ctx->writeCipher.macRef    = ctx->selectedCipherSpec.macAlgorithm;
-    ctx->readCipher.macRef     = ctx->selectedCipherSpec.macAlgorithm;
-    ctx->readCipher.symCipher  = ctx->selectedCipherSpec.cipher;
-    ctx->writeCipher.symCipher = ctx->selectedCipherSpec.cipher;
-
-       /* these two are invariant */
-    ctx->writeCipher.encrypting = 1;
-    ctx->writePending.encrypting = 1;
+    InitCipherSpecParams(ctx);
 
     /* this gets init'd on first call to SSLHandshake() */
     ctx->validCipherSuites = NULL;
 
     /* this gets init'd on first call to SSLHandshake() */
     ctx->validCipherSuites = NULL;
@@ -274,21 +304,17 @@ SSLContextRef SSLCreateContext(CFAllocatorRef alloc, SSLProtocolSide protocolSid
        ctx->ecdhPeerCurve = SSL_Curve_None;            /* until we negotiate one */
        ctx->negAuthType = SSLClientAuthNone;           /* ditto */
 
        ctx->ecdhPeerCurve = SSL_Curve_None;            /* until we negotiate one */
        ctx->negAuthType = SSLClientAuthNone;           /* ditto */
 
-    ctx->recordWriteQueue = NULL;
     ctx->messageWriteQueue = NULL;
 
     if(connectionType==kSSLDatagramType) {
     ctx->messageWriteQueue = NULL;
 
     if(connectionType==kSSLDatagramType) {
-       ctx->minProtocolVersion = MINIMUM_DATAGRAM_VERSION;
-       ctx->maxProtocolVersion = MAXIMUM_DATAGRAM_VERSION;
+        ctx->minProtocolVersion = MINIMUM_DATAGRAM_VERSION;
+        ctx->maxProtocolVersion = MAXIMUM_DATAGRAM_VERSION;
         ctx->isDTLS = true;
        }
 
     ctx->secure_renegotiation = false;
 
         ctx->isDTLS = true;
        }
 
     ctx->secure_renegotiation = false;
 
-#ifdef USE_CDSA_CRYPTO
-errOut:
-#endif /* USE_CDSA_CRYPTO */
-       if (serr != noErr) {
+       if (serr != errSecSuccess) {
                CFRelease(ctx);
                ctx = NULL;
     }
                CFRelease(ctx);
                ctx = NULL;
     }
@@ -300,11 +326,11 @@ SSLNewDatagramContext       (Boolean                      isServer,
                                                         SSLContextRef          *contextPtr)    /* RETURNED */
 {
        if (contextPtr == NULL)
                                                         SSLContextRef          *contextPtr)    /* RETURNED */
 {
        if (contextPtr == NULL)
-               return paramErr;
+               return errSecParam;
        *contextPtr = SSLCreateContext(kCFAllocatorDefault, isServer?kSSLServerSide:kSSLClientSide, kSSLDatagramType);
        if (*contextPtr == NULL)
        *contextPtr = SSLCreateContext(kCFAllocatorDefault, isServer?kSSLServerSide:kSSLClientSide, kSSLDatagramType);
        if (*contextPtr == NULL)
-               return memFullErr;
-    return noErr;
+               return errSecAllocate;
+    return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -316,13 +342,13 @@ OSStatus
 SSLDisposeContext                              (SSLContextRef context)
 {
     if(context == NULL) {
 SSLDisposeContext                              (SSLContextRef context)
 {
     if(context == NULL) {
-        return paramErr;
+        return errSecParam;
     }
        CFRelease(context);
     }
        CFRelease(context);
-       return noErr;
+       return errSecSuccess;
 }
 
 }
 
-CFStringRef _sslContextDescribe(CFTypeRef arg)
+CF_RETURNS_RETAINED CFStringRef _sslContextDescribe(CFTypeRef arg)
 {
     SSLContext* ctx = (SSLContext*) arg;
 
 {
     SSLContext* ctx = (SSLContext*) arg;
 
@@ -347,7 +373,6 @@ CFHashCode _sslContextHash(CFTypeRef arg)
 void _sslContextDestroy(CFTypeRef arg)
 {
        SSLContext* ctx = (SSLContext*) arg;
 void _sslContextDestroy(CFTypeRef arg)
 {
        SSLContext* ctx = (SSLContext*) arg;
-       WaitingRecord   *waitRecord, *next;
 
 #if USE_SSLCERTIFICATE
        sslDeleteCertificateChain(ctx->localCert, ctx);
 
 #if USE_SSLCERTIFICATE
        sslDeleteCertificateChain(ctx->localCert, ctx);
@@ -364,33 +389,26 @@ void _sslContextDestroy(CFTypeRef arg)
     /* Free the last handshake message flight */
     SSLResetFlight(ctx);
 
     /* Free the last handshake message flight */
     SSLResetFlight(ctx);
 
-    SSLFreeBuffer(&ctx->partialReadBuffer, ctx);
-       if(ctx->peerSecTrust) {
+    if(ctx->peerSecTrust) {
                CFRelease(ctx->peerSecTrust);
                ctx->peerSecTrust = NULL;
        }
                CFRelease(ctx->peerSecTrust);
                ctx->peerSecTrust = NULL;
        }
-    waitRecord = ctx->recordWriteQueue;
-    while (waitRecord)
-    {   next = waitRecord->next;
-               sslFree(waitRecord);
-        waitRecord = next;
-    }
-    SSLFreeBuffer(&ctx->sessionTicket, ctx);
-
+    SSLFreeBuffer(&ctx->sessionTicket);
+    
        #if APPLE_DH
        #if APPLE_DH
-    SSLFreeBuffer(&ctx->dhParamsEncoded, ctx);
+    SSLFreeBuffer(&ctx->dhParamsEncoded);
 #ifdef USE_CDSA_CRYPTO
        sslFreeKey(ctx->cspHand, &ctx->dhPrivate, NULL);
 #else
     if (ctx->secDHContext)
         SecDHDestroy(ctx->secDHContext);
 #endif /* !USE_CDSA_CRYPTO */
 #ifdef USE_CDSA_CRYPTO
        sslFreeKey(ctx->cspHand, &ctx->dhPrivate, NULL);
 #else
     if (ctx->secDHContext)
         SecDHDestroy(ctx->secDHContext);
 #endif /* !USE_CDSA_CRYPTO */
-    SSLFreeBuffer(&ctx->dhPeerPublic, ctx);
-    SSLFreeBuffer(&ctx->dhExchangePublic, ctx);
+    SSLFreeBuffer(&ctx->dhPeerPublic);
+    SSLFreeBuffer(&ctx->dhExchangePublic);
     #endif     /* APPLE_DH */
 
     #endif     /* APPLE_DH */
 
-    SSLFreeBuffer(&ctx->ecdhPeerPublic, ctx);
-    SSLFreeBuffer(&ctx->ecdhExchangePublic, ctx);
+    SSLFreeBuffer(&ctx->ecdhPeerPublic);
+    SSLFreeBuffer(&ctx->ecdhExchangePublic);
 #if USE_CDSA_CRYPTO
        if(ctx->ecdhPrivCspHand == ctx->cspHand) {
                sslFreeKey(ctx->ecdhPrivCspHand, &ctx->ecdhPrivate, NULL);
 #if USE_CDSA_CRYPTO
        if(ctx->ecdhPrivCspHand == ctx->cspHand) {
                sslFreeKey(ctx->ecdhPrivCspHand, &ctx->ecdhPrivate, NULL);
@@ -398,28 +416,27 @@ void _sslContextDestroy(CFTypeRef arg)
        /* else we got this key from a SecKeyRef, no free needed */
 #endif
 
        /* else we got this key from a SecKeyRef, no free needed */
 #endif
 
-       CloseHash(&SSLHashSHA1, &ctx->shaState, ctx);
-       CloseHash(&SSLHashMD5,  &ctx->md5State, ctx);
-       CloseHash(&SSLHashSHA256,  &ctx->sha256State, ctx);
-       CloseHash(&SSLHashSHA384,  &ctx->sha512State, ctx);
+    /* Only destroy if we were using the internal record layer */
+    if(ctx->recFuncs==&SSLRecordLayerInternal)
+        SSLDestroyInternalRecordLayer(ctx->recCtx);
+
+       CloseHash(&SSLHashSHA1, &ctx->shaState);
+       CloseHash(&SSLHashMD5,  &ctx->md5State);
+       CloseHash(&SSLHashSHA256,  &ctx->sha256State);
+       CloseHash(&SSLHashSHA384,  &ctx->sha512State);
 
 
-    SSLFreeBuffer(&ctx->sessionID, ctx);
-    SSLFreeBuffer(&ctx->peerID, ctx);
-    SSLFreeBuffer(&ctx->resumableSession, ctx);
-    SSLFreeBuffer(&ctx->preMasterSecret, ctx);
-    SSLFreeBuffer(&ctx->partialReadBuffer, ctx);
-    SSLFreeBuffer(&ctx->fragmentedMessageCache, ctx);
-    SSLFreeBuffer(&ctx->receivedDataBuffer, ctx);
+    SSLFreeBuffer(&ctx->sessionID);
+    SSLFreeBuffer(&ctx->peerID);
+    SSLFreeBuffer(&ctx->resumableSession);
+    SSLFreeBuffer(&ctx->preMasterSecret);
+    SSLFreeBuffer(&ctx->fragmentedMessageCache);
+    SSLFreeBuffer(&ctx->receivedDataBuffer);
 
        if(ctx->peerDomainName) {
                sslFree(ctx->peerDomainName);
                ctx->peerDomainName = NULL;
                ctx->peerDomainNameLen = 0;
        }
 
        if(ctx->peerDomainName) {
                sslFree(ctx->peerDomainName);
                ctx->peerDomainName = NULL;
                ctx->peerDomainNameLen = 0;
        }
-    SSLDisposeCipherSuite(&ctx->readCipher, ctx);
-    SSLDisposeCipherSuite(&ctx->writeCipher, ctx);
-    SSLDisposeCipherSuite(&ctx->readPending, ctx);
-    SSLDisposeCipherSuite(&ctx->writePending, ctx);
 
        sslFree(ctx->validCipherSuites);
        ctx->validCipherSuites = NULL;
 
        sslFree(ctx->validCipherSuites);
        ctx->validCipherSuites = NULL;
@@ -472,8 +489,11 @@ void _sslContextDestroy(CFTypeRef arg)
     }
        sslFreeDnList(ctx);
 
     }
        sslFreeDnList(ctx);
 
-    SSLFreeBuffer(&ctx->ownVerifyData, ctx);
-    SSLFreeBuffer(&ctx->peerVerifyData, ctx);
+    SSLFreeBuffer(&ctx->ownVerifyData);
+    SSLFreeBuffer(&ctx->peerVerifyData);
+
+    SSLFreeBuffer(&ctx->pskIdentity);
+    SSLFreeBuffer(&ctx->pskSharedSecret);
 
     memset(((uint8_t*) ctx) + sizeof(CFRuntimeBase), 0, sizeof(SSLContext) - sizeof(CFRuntimeBase));
 
 
     memset(((uint8_t*) ctx) + sizeof(CFRuntimeBase), 0, sizeof(SSLContext) - sizeof(CFRuntimeBase));
 
@@ -490,7 +510,7 @@ SSLGetSessionState                  (SSLContextRef          context,
        SSLSessionState rtnState = kSSLIdle;
 
        if(context == NULL) {
        SSLSessionState rtnState = kSSLIdle;
 
        if(context == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        *state = rtnState;
        switch(context->state) {
        }
        *state = rtnState;
        switch(context->state) {
@@ -512,13 +532,13 @@ SSLGetSessionState                        (SSLContextRef          context,
                        break;
                default:
                        assert((context->state >= SSL_HdskStateServerHello) &&
                        break;
                default:
                        assert((context->state >= SSL_HdskStateServerHello) &&
-                               (context->state <= SSL2_HdskStateServerFinished));
+                               (context->state <= SSL_HdskStateFinished));
                        rtnState = kSSLHandshake;
                        break;
 
        }
        *state = rtnState;
                        rtnState = kSSLHandshake;
                        break;
 
        }
        *state = rtnState;
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -529,13 +549,13 @@ SSLSetSessionOption                       (SSLContextRef          context,
                                                         SSLSessionOption       option,
                                                         Boolean                        value)
 {
                                                         SSLSessionOption       option,
                                                         Boolean                        value)
 {
-       if(context == NULL) {
-               return paramErr;
-       }
-       if(sslIsSessionActive(context)) {
-               /* can't do this with an active session */
-               return badReqErr;
-       }
+    if(context == NULL) {
+       return errSecParam;
+    }
+    if(sslIsSessionActive(context)) {
+       /* can't do this with an active session */
+       return errSecBadReq;
+    }
     switch(option) {
         case kSSLSessionOptionBreakOnServerAuth:
             context->breakOnServerAuth = value;
     switch(option) {
         case kSSLSessionOptionBreakOnServerAuth:
             context->breakOnServerAuth = value;
@@ -548,14 +568,17 @@ SSLSetSessionOption                       (SSLContextRef          context,
             context->breakOnClientAuth = value;
             context->enableCertVerify = !value;
             break;
             context->breakOnClientAuth = value;
             context->enableCertVerify = !value;
             break;
-               case kSSLSessionOptionSendOneByteRecord:
-                       context->oneByteRecordEnable = value;
-                       break;
-        default:
-            return paramErr;
+        case kSSLSessionOptionSendOneByteRecord:
+            context->oneByteRecordEnable = value;
+            break;
+        case kSSLSessionOptionFalseStart:
+            context->falseStartEnabled = value;
+            break;
+        default: 
+            return errSecParam;
     }
 
     }
 
-    return noErr;
+    return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -566,9 +589,9 @@ SSLGetSessionOption                 (SSLContextRef          context,
                                                         SSLSessionOption       option,
                                                         Boolean                        *value)
 {
                                                         SSLSessionOption       option,
                                                         Boolean                        *value)
 {
-       if(context == NULL || value == NULL) {
-               return paramErr;
-       }
+    if(context == NULL || value == NULL) {
+        return errSecParam;
+    }
     switch(option) {
         case kSSLSessionOptionBreakOnServerAuth:
             *value = context->breakOnServerAuth;
     switch(option) {
         case kSSLSessionOptionBreakOnServerAuth:
             *value = context->breakOnServerAuth;
@@ -579,32 +602,99 @@ SSLGetSessionOption                       (SSLContextRef          context,
         case kSSLSessionOptionBreakOnClientAuth:
             *value = context->breakOnClientAuth;
             break;
         case kSSLSessionOptionBreakOnClientAuth:
             *value = context->breakOnClientAuth;
             break;
-               case kSSLSessionOptionSendOneByteRecord:
-                       *value = context->oneByteRecordEnable;
-                       break;
+        case kSSLSessionOptionSendOneByteRecord:
+            *value = context->oneByteRecordEnable;
+            break;
+        case kSSLSessionOptionFalseStart:
+            *value = context->falseStartEnabled;
+            break;
         default:
         default:
-            return paramErr;
+            return errSecParam;
     }
 
     }
 
-    return noErr;
+    return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
-SSLSetIOFuncs                          (SSLContextRef          ctx,
+SSLSetRecordContext         (SSLContextRef          ctx,
+                             SSLRecordContextRef    recCtx)
+{
+       if(ctx == NULL) {
+               return errSecParam;
+       }
+       if(sslIsSessionActive(ctx)) {
+               /* can't do this with an active session */
+               return errSecBadReq;
+       }
+    ctx->recCtx = recCtx;
+    return errSecSuccess;
+}
+
+/* Those two trampolines are used to make the connetion between
+   the record layer IO callbacks and the user provided IO callbacks.
+   Those are currently necessary because the record layer read/write callbacks
+   have different prototypes that the user callbacks advertised in the API.
+   They have different prototypes because the record layer callback have to build in kernelland.
+
+   This situation is not desirable. So we should figure out a way to get rid of them.
+ */
+static int IORead(SSLIOConnectionRef   connection,
+                  void                                 *data,
+                  size_t                       *dataLength)
+{
+    OSStatus rc;
+    SSLContextRef ctx = connection;
+
+
+    rc = ctx->ioCtx.read(ctx->ioCtx.ioRef, data, dataLength);
+
+    /* We may need to translate error codes at this layer */
+    if(rc==errSSLWouldBlock) {
+        rc=errSSLRecordWouldBlock;
+    }
+
+    return rc;
+}
+
+static int IOWrite(SSLIOConnectionRef  connection,
+                   const void          *data,
+                   size_t                      *dataLength)
+{
+    OSStatus rc;
+    SSLContextRef ctx = connection;
+
+    rc = ctx->ioCtx.write(ctx->ioCtx.ioRef, data, dataLength);
+
+    /* We may need to translate error codes at this layer */
+    if(rc==errSSLWouldBlock) {
+        rc=errSSLRecordWouldBlock;
+    }
+    return rc;
+}
+
+
+OSStatus 
+SSLSetIOFuncs                          (SSLContextRef          ctx, 
                                                         SSLReadFunc            readFunc,
                                                         SSLWriteFunc           writeFunc)
 {
        if(ctx == NULL) {
                                                         SSLReadFunc            readFunc,
                                                         SSLWriteFunc           writeFunc)
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        }
+    if(ctx->recFuncs!=&SSLRecordLayerInternal) {
+        /* Can Only do this with the internal record layer */
+        check(0);
+        return errSecBadReq;
+    }
        if(sslIsSessionActive(ctx)) {
                /* can't do this with an active session */
        if(sslIsSessionActive(ctx)) {
                /* can't do this with an active session */
-               return badReqErr;
+               return errSecBadReq;
        }
 
        }
 
-       ctx->ioCtx.read = readFunc;
-       ctx->ioCtx.write = writeFunc;
-       return noErr;
+    ctx->ioCtx.read=readFunc;
+    ctx->ioCtx.write=writeFunc;
+
+    return SSLSetInternalRecordLayerIOFuncs(ctx->recCtx, IORead, IOWrite);
 }
 
 OSStatus
 }
 
 OSStatus
@@ -612,15 +702,22 @@ SSLSetConnection                  (SSLContextRef          ctx,
                                                         SSLConnectionRef       connection)
 {
        if(ctx == NULL) {
                                                         SSLConnectionRef       connection)
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        }
+    if(ctx->recFuncs!=&SSLRecordLayerInternal) {
+        /* Can Only do this with the internal record layer */
+        check(0);
+        return errSecBadReq;
+    }
        if(sslIsSessionActive(ctx)) {
                /* can't do this with an active session */
        if(sslIsSessionActive(ctx)) {
                /* can't do this with an active session */
-               return badReqErr;
+               return errSecBadReq;
        }
 
        }
 
-       ctx->ioCtx.ioRef = connection;
-    return noErr;
+    /* Need to keep a copy of it this layer for the Get function */
+    ctx->ioCtx.ioRef = connection;
+
+    return SSLSetInternalRecordLayerConnection(ctx->recCtx, ctx);
 }
 
 OSStatus
 }
 
 OSStatus
@@ -628,10 +725,10 @@ SSLGetConnection                  (SSLContextRef          ctx,
                                                         SSLConnectionRef       *connection)
 {
        if((ctx == NULL) || (connection == NULL)) {
                                                         SSLConnectionRef       *connection)
 {
        if((ctx == NULL) || (connection == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        *connection = ctx->ioCtx.ioRef;
        }
        *connection = ctx->ioCtx.ioRef;
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -640,11 +737,11 @@ SSLSetPeerDomainName              (SSLContextRef          ctx,
                                                         size_t                         peerNameLen)
 {
        if(ctx == NULL) {
                                                         size_t                         peerNameLen)
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        if(sslIsSessionActive(ctx)) {
                /* can't do this with an active session */
        }
        if(sslIsSessionActive(ctx)) {
                /* can't do this with an active session */
-               return badReqErr;
+               return errSecBadReq;
        }
 
        /* free possible existing name */
        }
 
        /* free possible existing name */
@@ -655,11 +752,11 @@ SSLSetPeerDomainName              (SSLContextRef          ctx,
        /* copy in */
        ctx->peerDomainName = (char *)sslMalloc(peerNameLen);
        if(ctx->peerDomainName == NULL) {
        /* copy in */
        ctx->peerDomainName = (char *)sslMalloc(peerNameLen);
        if(ctx->peerDomainName == NULL) {
-               return memFullErr;
+               return errSecAllocate;
        }
        memmove(ctx->peerDomainName, peerName, peerNameLen);
        ctx->peerDomainNameLen = peerNameLen;
        }
        memmove(ctx->peerDomainName, peerName, peerNameLen);
        ctx->peerDomainNameLen = peerNameLen;
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -670,10 +767,10 @@ SSLGetPeerDomainNameLength        (SSLContextRef          ctx,
                                                         size_t                         *peerNameLen)   // RETURNED
 {
        if(ctx == NULL) {
                                                         size_t                         *peerNameLen)   // RETURNED
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        *peerNameLen = ctx->peerDomainNameLen;
        }
        *peerNameLen = ctx->peerDomainNameLen;
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -682,14 +779,14 @@ SSLGetPeerDomainName              (SSLContextRef          ctx,
                                                         size_t                         *peerNameLen)   // IN/OUT
 {
        if(ctx == NULL) {
                                                         size_t                         *peerNameLen)   // IN/OUT
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        if(*peerNameLen < ctx->peerDomainNameLen) {
                return errSSLBufferOverflow;
        }
        memmove(peerName, ctx->peerDomainName, ctx->peerDomainNameLen);
        *peerNameLen = ctx->peerDomainNameLen;
        }
        if(*peerNameLen < ctx->peerDomainNameLen) {
                return errSSLBufferOverflow;
        }
        memmove(peerName, ctx->peerDomainName, ctx->peerDomainNameLen);
        *peerNameLen = ctx->peerDomainNameLen;
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -700,30 +797,30 @@ SSLSetDatagramHelloCookie   (SSLContextRef        ctx,
     OSStatus err;
 
     if(ctx == NULL) {
     OSStatus err;
 
     if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
 
        }
 
-    if(!ctx->isDTLS) return paramErr;
+    if(!ctx->isDTLS) return errSecParam;
 
        if((ctx == NULL) || (cookieLen>32)) {
 
        if((ctx == NULL) || (cookieLen>32)) {
-               return paramErr;
+               return errSecParam;
        }
        if(sslIsSessionActive(ctx)) {
                /* can't do this with an active session */
        }
        if(sslIsSessionActive(ctx)) {
                /* can't do this with an active session */
-               return badReqErr;
+               return errSecBadReq;
        }
 
        /* free possible existing cookie */
        if(ctx->dtlsCookie.data) {
        }
 
        /* free possible existing cookie */
        if(ctx->dtlsCookie.data) {
-        SSLFreeBuffer(&ctx->dtlsCookie, ctx);
+        SSLFreeBuffer(&ctx->dtlsCookie);
        }
 
        /* copy in */
        }
 
        /* copy in */
-    if((err=SSLAllocBuffer(&ctx->dtlsCookie, cookieLen, ctx))!=noErr)
+    if((err=SSLAllocBuffer(&ctx->dtlsCookie, cookieLen)))
        return err;
 
        memmove(ctx->dtlsCookie.data, cookie, cookieLen);
        return err;
 
        memmove(ctx->dtlsCookie.data, cookie, cookieLen);
-    return noErr;
+    return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -731,25 +828,25 @@ SSLSetMaxDatagramRecordSize (SSLContextRef                ctx,
                              size_t             maxSize)
 {
 
                              size_t             maxSize)
 {
 
-    if(ctx == NULL) return paramErr;
-    if(!ctx->isDTLS) return paramErr;
-    if(maxSize < MIN_ALLOWED_DTLS_MTU) return paramErr;
+    if(ctx == NULL) return errSecParam;
+    if(!ctx->isDTLS) return errSecParam;
+    if(maxSize < MIN_ALLOWED_DTLS_MTU) return errSecParam;
 
     ctx->mtu = maxSize;
 
 
     ctx->mtu = maxSize;
 
-    return noErr;
+    return errSecSuccess;
 }
 
 OSStatus
 SSLGetMaxDatagramRecordSize (SSLContextRef             ctx,
                              size_t             *maxSize)
 {
 }
 
 OSStatus
 SSLGetMaxDatagramRecordSize (SSLContextRef             ctx,
                              size_t             *maxSize)
 {
-    if(ctx == NULL) return paramErr;
-    if(!ctx->isDTLS) return paramErr;
+    if(ctx == NULL) return errSecParam;
+    if(!ctx->isDTLS) return errSecParam;
 
     *maxSize = ctx->mtu;
 
 
     *maxSize = ctx->mtu;
 
-    return noErr;
+    return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -773,13 +870,16 @@ OSStatus
 SSLGetDatagramWriteSize                (SSLContextRef ctx,
                                                         size_t *bufSize)
 {
 SSLGetDatagramWriteSize                (SSLContextRef ctx,
                                                         size_t *bufSize)
 {
-    if(ctx == NULL) return paramErr;
-    if(!ctx->isDTLS) return paramErr;
-    if(bufSize == NULL) return paramErr;
+    if(ctx == NULL) return errSecParam;
+    if(!ctx->isDTLS) return errSecParam;
+    if(bufSize == NULL) return errSecParam;
 
     size_t max_fragment_size = ctx->mtu-13; /* 13 = dtls record header */
 
 
     size_t max_fragment_size = ctx->mtu-13; /* 13 = dtls record header */
 
-    UInt16 blockSize = ctx->writeCipher.symCipher->blockSize;
+    SSLCipherSpecParams *currCipher = &ctx->selectedCipherSpecParams;
+
+    size_t blockSize = currCipher->blockSize;
+    size_t macSize = currCipher->macSize;
 
     if (blockSize > 0) {
         /* max_fragment_size must be a multiple of blocksize */
 
     if (blockSize > 0) {
         /* max_fragment_size must be a multiple of blocksize */
@@ -789,14 +889,14 @@ SSLGetDatagramWriteSize           (SSLContextRef ctx,
     }
 
     /* less the mac size */
     }
 
     /* less the mac size */
-    max_fragment_size -= ctx->writeCipher.macRef->hash->digestSize;
+    max_fragment_size -= macSize;
 
     /* Thats just a sanity check */
     assert(max_fragment_size<ctx->mtu);
 
     *bufSize = max_fragment_size;
 
 
     /* Thats just a sanity check */
     assert(max_fragment_size<ctx->mtu);
 
     *bufSize = max_fragment_size;
 
-    return noErr;
+    return errSecSuccess;
 }
 
 static SSLProtocolVersion SSLProtocolToProtocolVersion(SSLProtocol protocol) {
 }
 
 static SSLProtocolVersion SSLProtocolToProtocolVersion(SSLProtocol protocol) {
@@ -833,7 +933,7 @@ OSStatus
 SSLSetProtocolVersionMin  (SSLContextRef      ctx,
                            SSLProtocol        minVersion)
 {
 SSLSetProtocolVersionMin  (SSLContextRef      ctx,
                            SSLProtocol        minVersion)
 {
-    if(ctx == NULL) return paramErr;
+    if(ctx == NULL) return errSecParam;
 
     SSLProtocolVersion version = SSLProtocolToProtocolVersion(minVersion);
     if (ctx->isDTLS) {
 
     SSLProtocolVersion version = SSLProtocolToProtocolVersion(minVersion);
     if (ctx->isDTLS) {
@@ -850,24 +950,24 @@ SSLSetProtocolVersionMin  (SSLContextRef      ctx,
     }
     ctx->minProtocolVersion = version;
 
     }
     ctx->minProtocolVersion = version;
 
-    return noErr;
+    return errSecSuccess;
 }
 
 OSStatus
 SSLGetProtocolVersionMin  (SSLContextRef      ctx,
                            SSLProtocol        *minVersion)
 {
 }
 
 OSStatus
 SSLGetProtocolVersionMin  (SSLContextRef      ctx,
                            SSLProtocol        *minVersion)
 {
-    if(ctx == NULL) return paramErr;
+    if(ctx == NULL) return errSecParam;
 
     *minVersion = SSLProtocolVersionToProtocol(ctx->minProtocolVersion);
 
     *minVersion = SSLProtocolVersionToProtocol(ctx->minProtocolVersion);
-    return noErr;
+    return errSecSuccess;
 }
 
 OSStatus
 SSLSetProtocolVersionMax  (SSLContextRef      ctx,
                            SSLProtocol        maxVersion)
 {
 }
 
 OSStatus
 SSLSetProtocolVersionMax  (SSLContextRef      ctx,
                            SSLProtocol        maxVersion)
 {
-    if(ctx == NULL) return paramErr;
+    if(ctx == NULL) return errSecParam;
 
     SSLProtocolVersion version = SSLProtocolToProtocolVersion(maxVersion);
     if (ctx->isDTLS) {
 
     SSLProtocolVersion version = SSLProtocolToProtocolVersion(maxVersion);
     if (ctx->isDTLS) {
@@ -884,19 +984,20 @@ SSLSetProtocolVersionMax  (SSLContextRef      ctx,
     }
     ctx->maxProtocolVersion = version;
 
     }
     ctx->maxProtocolVersion = version;
 
-    return noErr;
+    return errSecSuccess;
 }
 
 OSStatus
 SSLGetProtocolVersionMax  (SSLContextRef      ctx,
                            SSLProtocol        *maxVersion)
 {
 }
 
 OSStatus
 SSLGetProtocolVersionMax  (SSLContextRef      ctx,
                            SSLProtocol        *maxVersion)
 {
-    if(ctx == NULL) return paramErr;
+    if(ctx == NULL) return errSecParam;
 
     *maxVersion = SSLProtocolVersionToProtocol(ctx->maxProtocolVersion);
 
     *maxVersion = SSLProtocolVersionToProtocol(ctx->maxProtocolVersion);
-    return noErr;
+    return errSecSuccess;
 }
 
 }
 
+#define max(x,y) ((x)<(y)?(y):(x))
 
 OSStatus
 SSLSetProtocolVersionEnabled(SSLContextRef     ctx,
 
 OSStatus
 SSLSetProtocolVersionEnabled(SSLContextRef     ctx,
@@ -904,11 +1005,11 @@ SSLSetProtocolVersionEnabled(SSLContextRef     ctx,
                                                         Boolean                        enable)
 {
        if(ctx == NULL) {
                                                         Boolean                        enable)
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        if(sslIsSessionActive(ctx) || ctx->isDTLS) {
                /* Can't do this with an active session, nor with a DTLS session */
        }
        if(sslIsSessionActive(ctx) || ctx->isDTLS) {
                /* Can't do this with an active session, nor with a DTLS session */
-               return badReqErr;
+               return errSecBadReq;
        }
     if (protocol == kSSLProtocolAll) {
         if (enable) {
        }
     if (protocol == kSSLProtocolAll) {
         if (enable) {
@@ -922,7 +1023,7 @@ SSLSetProtocolVersionEnabled(SSLContextRef     ctx,
                SSLProtocolVersion version = SSLProtocolToProtocolVersion(protocol);
         if (enable) {
                        if (version < MINIMUM_STREAM_VERSION || version > MAXIMUM_STREAM_VERSION) {
                SSLProtocolVersion version = SSLProtocolToProtocolVersion(protocol);
         if (enable) {
                        if (version < MINIMUM_STREAM_VERSION || version > MAXIMUM_STREAM_VERSION) {
-                               return paramErr;
+                               return errSecParam;
                        }
             if (version > ctx->maxProtocolVersion) {
                 ctx->maxProtocolVersion = version;
                        }
             if (version > ctx->maxProtocolVersion) {
                 ctx->maxProtocolVersion = version;
@@ -934,7 +1035,7 @@ SSLSetProtocolVersionEnabled(SSLContextRef     ctx,
             }
         } else {
                        if (version < SSL_Version_2_0 || version > MAXIMUM_STREAM_VERSION) {
             }
         } else {
                        if (version < SSL_Version_2_0 || version > MAXIMUM_STREAM_VERSION) {
-                               return paramErr;
+                               return errSecParam;
                        }
                        /* Disabling a protocol version now resets the minimum acceptable
                         * version to the next higher version. This means it's no longer
                        }
                        /* Disabling a protocol version now resets the minimum acceptable
                         * version to the next higher version. This means it's no longer
@@ -967,7 +1068,7 @@ SSLSetProtocolVersionEnabled(SSLContextRef     ctx,
         }
     }
 
         }
     }
 
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -976,11 +1077,11 @@ SSLGetProtocolVersionEnabled(SSLContextRef               ctx,
                                                         Boolean                        *enable)                /* RETURNED */
 {
        if(ctx == NULL) {
                                                         Boolean                        *enable)                /* RETURNED */
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        if(ctx->isDTLS) {
                /* Can't do this with a DTLS session */
        }
        if(ctx->isDTLS) {
                /* Can't do this with a DTLS session */
-               return badReqErr;
+               return errSecBadReq;
        }
        switch(protocol) {
                case kSSLProtocol2:
        }
        switch(protocol) {
                case kSSLProtocol2:
@@ -999,9 +1100,9 @@ SSLGetProtocolVersionEnabled(SSLContextRef                 ctx,
                        && ctx->maxProtocolVersion >= MAXIMUM_STREAM_VERSION);
                        break;
                default:
                        && ctx->maxProtocolVersion >= MAXIMUM_STREAM_VERSION);
                        break;
                default:
-                       return paramErr;
+                       return errSecParam;
        }
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 /* deprecated */
 }
 
 /* deprecated */
@@ -1010,11 +1111,11 @@ SSLSetProtocolVersion           (SSLContextRef          ctx,
                                                         SSLProtocol            version)
 {
        if(ctx == NULL) {
                                                         SSLProtocol            version)
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        if(sslIsSessionActive(ctx) || ctx->isDTLS) {
                /* Can't do this with an active session, nor with a DTLS session */
        }
        if(sslIsSessionActive(ctx) || ctx->isDTLS) {
                /* Can't do this with an active session, nor with a DTLS session */
-               return badReqErr;
+               return errSecBadReq;
        }
 
        switch(version) {
        }
 
        switch(version) {
@@ -1051,10 +1152,10 @@ SSLSetProtocolVersion           (SSLContextRef          ctx,
             ctx->maxProtocolVersion = MAXIMUM_STREAM_VERSION;
                        break;
                default:
             ctx->maxProtocolVersion = MAXIMUM_STREAM_VERSION;
                        break;
                default:
-                       return paramErr;
+                       return errSecParam;
        }
 
        }
 
-    return noErr;
+    return errSecSuccess;
 }
 
 /* deprecated */
 }
 
 /* deprecated */
@@ -1063,7 +1164,7 @@ SSLGetProtocolVersion             (SSLContextRef          ctx,
                                                         SSLProtocol            *protocol)              /* RETURNED */
 {
        if(ctx == NULL) {
                                                         SSLProtocol            *protocol)              /* RETURNED */
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        /* translate array of booleans to public value; not all combinations
         * are legal (i.e., meaningful) for this call */
        }
        /* translate array of booleans to public value; not all combinations
         * are legal (i.e., meaningful) for this call */
@@ -1071,19 +1172,19 @@ SSLGetProtocolVersion           (SSLContextRef          ctx,
         if(ctx->minProtocolVersion == MINIMUM_STREAM_VERSION) {
             /* traditional 'all enabled' */
             *protocol = kSSLProtocolAll;
         if(ctx->minProtocolVersion == MINIMUM_STREAM_VERSION) {
             /* traditional 'all enabled' */
             *protocol = kSSLProtocolAll;
-            return noErr;
+            return errSecSuccess;
                }
        } else if (ctx->maxProtocolVersion == TLS_Version_1_1) {
         if(ctx->minProtocolVersion == MINIMUM_STREAM_VERSION) {
             /* traditional 'all enabled' */
             *protocol = kTLSProtocol11;
                }
        } else if (ctx->maxProtocolVersion == TLS_Version_1_1) {
         if(ctx->minProtocolVersion == MINIMUM_STREAM_VERSION) {
             /* traditional 'all enabled' */
             *protocol = kTLSProtocol11;
-            return noErr;
+            return errSecSuccess;
         }
        } else if (ctx->maxProtocolVersion == TLS_Version_1_0) {
         if(ctx->minProtocolVersion == MINIMUM_STREAM_VERSION) {
             /* TLS1.1 and below enabled */
             *protocol = kTLSProtocol1;
         }
        } else if (ctx->maxProtocolVersion == TLS_Version_1_0) {
         if(ctx->minProtocolVersion == MINIMUM_STREAM_VERSION) {
             /* TLS1.1 and below enabled */
             *protocol = kTLSProtocol1;
-            return noErr;
+            return errSecSuccess;
         } else if(ctx->minProtocolVersion == TLS_Version_1_0) {
                *protocol = kTLSProtocol1Only;
                }
         } else if(ctx->minProtocolVersion == TLS_Version_1_0) {
                *protocol = kTLSProtocol1Only;
                }
@@ -1092,11 +1193,11 @@ SSLGetProtocolVersion           (SSLContextRef          ctx,
             /* Could also return kSSLProtocol3Only since
                MINIMUM_STREAM_VERSION == SSL_Version_3_0. */
             *protocol = kSSLProtocol3;
             /* Could also return kSSLProtocol3Only since
                MINIMUM_STREAM_VERSION == SSL_Version_3_0. */
             *protocol = kSSLProtocol3;
-                       return noErr;
+                       return errSecSuccess;
                }
        }
 
                }
        }
 
-    return paramErr;
+    return errSecParam;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -1104,10 +1205,10 @@ SSLGetNegotiatedProtocolVersion         (SSLContextRef          ctx,
                                                                         SSLProtocol            *protocol) /* RETURNED */
 {
        if(ctx == NULL) {
                                                                         SSLProtocol            *protocol) /* RETURNED */
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        *protocol = SSLProtocolVersionToProtocol(ctx->negProtocolVersion);
        }
        *protocol = SSLProtocolVersionToProtocol(ctx->negProtocolVersion);
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -1115,16 +1216,16 @@ SSLSetEnableCertVerify          (SSLContextRef          ctx,
                                                         Boolean                        enableVerify)
 {
        if(ctx == NULL) {
                                                         Boolean                        enableVerify)
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        sslCertDebug("SSLSetEnableCertVerify %s",
                enableVerify ? "true" : "false");
        if(sslIsSessionActive(ctx)) {
                /* can't do this with an active session */
        }
        sslCertDebug("SSLSetEnableCertVerify %s",
                enableVerify ? "true" : "false");
        if(sslIsSessionActive(ctx)) {
                /* can't do this with an active session */
-               return badReqErr;
+               return errSecBadReq;
        }
        ctx->enableCertVerify = enableVerify;
        }
        ctx->enableCertVerify = enableVerify;
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -1132,10 +1233,10 @@ SSLGetEnableCertVerify          (SSLContextRef          ctx,
                                                        Boolean                         *enableVerify)
 {
        if(ctx == NULL) {
                                                        Boolean                         *enableVerify)
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        *enableVerify = ctx->enableCertVerify;
        }
        *enableVerify = ctx->enableCertVerify;
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -1143,16 +1244,16 @@ SSLSetAllowsExpiredCerts(SSLContextRef          ctx,
                                                 Boolean                        allowExpired)
 {
        if(ctx == NULL) {
                                                 Boolean                        allowExpired)
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        sslCertDebug("SSLSetAllowsExpiredCerts %s",
                allowExpired ? "true" : "false");
        if(sslIsSessionActive(ctx)) {
                /* can't do this with an active session */
        }
        sslCertDebug("SSLSetAllowsExpiredCerts %s",
                allowExpired ? "true" : "false");
        if(sslIsSessionActive(ctx)) {
                /* can't do this with an active session */
-               return badReqErr;
+               return errSecBadReq;
        }
        ctx->allowExpiredCerts = allowExpired;
        }
        ctx->allowExpiredCerts = allowExpired;
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -1160,10 +1261,10 @@ SSLGetAllowsExpiredCerts        (SSLContextRef          ctx,
                                                         Boolean                        *allowExpired)
 {
        if(ctx == NULL) {
                                                         Boolean                        *allowExpired)
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        *allowExpired = ctx->allowExpiredCerts;
        }
        *allowExpired = ctx->allowExpiredCerts;
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -1171,16 +1272,16 @@ SSLSetAllowsExpiredRoots(SSLContextRef          ctx,
                                                 Boolean                        allowExpired)
 {
        if(ctx == NULL) {
                                                 Boolean                        allowExpired)
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        sslCertDebug("SSLSetAllowsExpiredRoots %s",
                allowExpired ? "true" : "false");
        if(sslIsSessionActive(ctx)) {
                /* can't do this with an active session */
        }
        sslCertDebug("SSLSetAllowsExpiredRoots %s",
                allowExpired ? "true" : "false");
        if(sslIsSessionActive(ctx)) {
                /* can't do this with an active session */
-               return badReqErr;
+               return errSecBadReq;
        }
        ctx->allowExpiredRoots = allowExpired;
        }
        ctx->allowExpiredRoots = allowExpired;
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -1188,10 +1289,10 @@ SSLGetAllowsExpiredRoots        (SSLContextRef          ctx,
                                                         Boolean                        *allowExpired)
 {
        if(ctx == NULL) {
                                                         Boolean                        *allowExpired)
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        *allowExpired = ctx->allowExpiredRoots;
        }
        *allowExpired = ctx->allowExpiredRoots;
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus SSLSetAllowsAnyRoot(
 }
 
 OSStatus SSLSetAllowsAnyRoot(
@@ -1199,11 +1300,11 @@ OSStatus SSLSetAllowsAnyRoot(
        Boolean                 anyRoot)
 {
        if(ctx == NULL) {
        Boolean                 anyRoot)
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        sslCertDebug("SSLSetAllowsAnyRoot %s",  anyRoot ? "true" : "false");
        ctx->allowAnyRoot = anyRoot;
        }
        sslCertDebug("SSLSetAllowsAnyRoot %s",  anyRoot ? "true" : "false");
        ctx->allowAnyRoot = anyRoot;
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -1212,13 +1313,13 @@ SSLGetAllowsAnyRoot(
        Boolean                 *anyRoot)
 {
        if(ctx == NULL) {
        Boolean                 *anyRoot)
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        *anyRoot = ctx->allowAnyRoot;
        }
        *anyRoot = ctx->allowAnyRoot;
-       return noErr;
+       return errSecSuccess;
 }
 
 }
 
-#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+#if !TARGET_OS_IPHONE
 /* obtain the system roots sets for this app, policy SSL */
 static OSStatus sslDefaultSystemRoots(
        SSLContextRef ctx,
 /* obtain the system roots sets for this app, policy SSL */
 static OSStatus sslDefaultSystemRoots(
        SSLContextRef ctx,
@@ -1226,9 +1327,8 @@ static OSStatus sslDefaultSystemRoots(
 
 {
        return SecTrustSettingsCopyQualifiedCerts(&CSSMOID_APPLE_TP_SSL,
 
 {
        return SecTrustSettingsCopyQualifiedCerts(&CSSMOID_APPLE_TP_SSL,
-               NULL, true,     // application - us
                ctx->peerDomainName,
                ctx->peerDomainName,
-               ctx->peerDomainNameLen,
+               (uint32_t)ctx->peerDomainNameLen,
                (ctx->protocolSide == kSSLServerSide) ?
                        /* server verifies, client encrypts */
                        CSSM_KEYUSE_VERIFY : CSSM_KEYUSE_ENCRYPT,
                (ctx->protocolSide == kSSLServerSide) ?
                        /* server verifies, client encrypts */
                        CSSM_KEYUSE_VERIFY : CSSM_KEYUSE_ENCRYPT,
@@ -1243,11 +1343,11 @@ SSLSetTrustedRoots                      (SSLContextRef          ctx,
 {
 #ifdef USE_CDSA_CRYPTO
        if(ctx == NULL) {
 {
 #ifdef USE_CDSA_CRYPTO
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        if(sslIsSessionActive(ctx)) {
                /* can't do this with an active session */
        }
        if(sslIsSessionActive(ctx)) {
                /* can't do this with an active session */
-               return badReqErr;
+               return errSecBadReq;
        }
 
        if(replaceExisting) {
        }
 
        if(replaceExisting) {
@@ -1256,7 +1356,7 @@ SSLSetTrustedRoots                        (SSLContextRef          ctx,
             CFRetain(trustedRoots);
         CFReleaseSafe(ctx->trustedCerts);
                ctx->trustedCerts = trustedRoots;
             CFRetain(trustedRoots);
         CFReleaseSafe(ctx->trustedCerts);
                ctx->trustedCerts = trustedRoots;
-               return noErr;
+               return errSecSuccess;
        }
 
        /* adding new trusted roots - to either our existing set, or the system set */
        }
 
        /* adding new trusted roots - to either our existing set, or the system set */
@@ -1281,12 +1381,12 @@ SSLSetTrustedRoots                      (SSLContextRef          ctx,
        CFArrayAppendArray(newRoots, existingRoots, existRange);
        CFRelease(existingRoots);
        ctx->trustedCerts = newRoots;
        CFArrayAppendArray(newRoots, existingRoots, existRange);
        CFRelease(existingRoots);
        ctx->trustedCerts = newRoots;
-       return noErr;
+       return errSecSuccess;
 
 #else
        if (sslIsSessionActive(ctx)) {
                /* can't do this with an active session */
 
 #else
        if (sslIsSessionActive(ctx)) {
                /* can't do this with an active session */
-               return badReqErr;
+               return errSecBadReq;
        }
        sslCertDebug("SSLSetTrustedRoot  numCerts %d  replaceExist %s",
                (int)CFArrayGetCount(trustedRoots), replaceExisting ? "true" : "false");
        }
        sslCertDebug("SSLSetTrustedRoot  numCerts %d  replaceExist %s",
                (int)CFArrayGetCount(trustedRoots), replaceExisting ? "true" : "false");
@@ -1306,10 +1406,10 @@ SSLSetTrustedRoots                      (SSLContextRef          ctx,
             errOut);
     }
 
             errOut);
     }
 
-    return noErr;
+    return errSecSuccess;
 
 errOut:
 
 errOut:
-    return memFullErr;
+    return errSecAllocate;
 #endif /* !USE_CDSA_CRYPTO */
 }
 
 #endif /* !USE_CDSA_CRYPTO */
 }
 
@@ -1318,56 +1418,32 @@ SSLCopyTrustedRoots                     (SSLContextRef          ctx,
                                                         CFArrayRef             *trustedRoots)  /* RETURNED */
 {
        if(ctx == NULL || trustedRoots == NULL) {
                                                         CFArrayRef             *trustedRoots)  /* RETURNED */
 {
        if(ctx == NULL || trustedRoots == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        if(ctx->trustedCerts != NULL) {
                *trustedRoots = ctx->trustedCerts;
                CFRetain(ctx->trustedCerts);
        }
        if(ctx->trustedCerts != NULL) {
                *trustedRoots = ctx->trustedCerts;
                CFRetain(ctx->trustedCerts);
-               return noErr;
+               return errSecSuccess;
        }
 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
        /* use default system roots */
     return sslDefaultSystemRoots(ctx, trustedRoots);
 #else
     *trustedRoots = NULL;
        }
 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
        /* use default system roots */
     return sslDefaultSystemRoots(ctx, trustedRoots);
 #else
     *trustedRoots = NULL;
-    return noErr;
+    return errSecSuccess;
 #endif
 }
 
 #endif
 }
 
-/* legacy version, caller must CFRelease each cert */
-OSStatus
-SSLGetTrustedRoots                     (SSLContextRef          ctx,
-                                                        CFArrayRef             *trustedRoots)  /* RETURNED */
-{
-       OSStatus ortn;
-
-       if((ctx == NULL) || (trustedRoots == NULL)) {
-               return paramErr;
-       }
-
-       ortn = SSLCopyTrustedRoots(ctx, trustedRoots);
-       if(ortn) {
-               return ortn;
-       }
-       /* apply the legacy bug */
-       CFIndex numCerts = CFArrayGetCount(*trustedRoots);
-       CFIndex dex;
-       for(dex=0; dex<numCerts; dex++) {
-               CFRetain(CFArrayGetValueAtIndex(*trustedRoots, dex));
-       }
-       return noErr;
-}
-
 OSStatus
 SSLSetTrustedLeafCertificates  (SSLContextRef          ctx,
                                                                 CFArrayRef             trustedCerts)
 {
        if(ctx == NULL) {
 OSStatus
 SSLSetTrustedLeafCertificates  (SSLContextRef          ctx,
                                                                 CFArrayRef             trustedCerts)
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        if(sslIsSessionActive(ctx)) {
                /* can't do this with an active session */
        }
        if(sslIsSessionActive(ctx)) {
                /* can't do this with an active session */
-               return badReqErr;
+               return errSecBadReq;
        }
 
        if(ctx->trustedLeafCerts) {
        }
 
        if(ctx->trustedLeafCerts) {
@@ -1375,7 +1451,7 @@ SSLSetTrustedLeafCertificates     (SSLContextRef          ctx,
        }
        ctx->trustedLeafCerts = trustedCerts;
        CFRetain(trustedCerts);
        }
        ctx->trustedLeafCerts = trustedCerts;
        CFRetain(trustedCerts);
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -1383,15 +1459,15 @@ SSLCopyTrustedLeafCertificates  (SSLContextRef          ctx,
                                                                 CFArrayRef             *trustedCerts)  /* RETURNED */
 {
        if(ctx == NULL) {
                                                                 CFArrayRef             *trustedCerts)  /* RETURNED */
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        if(ctx->trustedLeafCerts != NULL) {
                *trustedCerts = ctx->trustedLeafCerts;
                CFRetain(ctx->trustedCerts);
        }
        if(ctx->trustedLeafCerts != NULL) {
                *trustedCerts = ctx->trustedLeafCerts;
                CFRetain(ctx->trustedCerts);
-               return noErr;
+               return errSecSuccess;
        }
        *trustedCerts = NULL;
        }
        *trustedCerts = NULL;
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -1399,11 +1475,11 @@ SSLSetClientSideAuthenticate    (SSLContext                     *ctx,
                                                                 SSLAuthenticate        auth)
 {
        if(ctx == NULL) {
                                                                 SSLAuthenticate        auth)
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        if(sslIsSessionActive(ctx)) {
                /* can't do this with an active session */
        }
        if(sslIsSessionActive(ctx)) {
                /* can't do this with an active session */
-               return badReqErr;
+               return errSecBadReq;
        }
        ctx->clientAuth = auth;
        switch(auth) {
        }
        ctx->clientAuth = auth;
        switch(auth) {
@@ -1415,7 +1491,7 @@ SSLSetClientSideAuthenticate      (SSLContext                     *ctx,
                        ctx->tryClientAuth = true;
                        break;
        }
                        ctx->tryClientAuth = true;
                        break;
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -1423,10 +1499,10 @@ SSLGetClientSideAuthenticate    (SSLContext                     *ctx,
                                                                 SSLAuthenticate        *auth)  /* RETURNED */
 {
        if(ctx == NULL || auth == NULL) {
                                                                 SSLAuthenticate        *auth)  /* RETURNED */
 {
        if(ctx == NULL || auth == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        *auth = ctx->clientAuth;
        }
        *auth = ctx->clientAuth;
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -1434,10 +1510,10 @@ SSLGetClientCertificateState    (SSLContextRef                          ctx,
                                                                 SSLClientCertificateState      *clientState)
 {
        if(ctx == NULL) {
                                                                 SSLClientCertificateState      *clientState)
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        *clientState = ctx->clientCertState;
        }
        *clientState = ctx->clientCertState;
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -1451,7 +1527,7 @@ SSLSetCertificate                 (SSLContextRef          ctx,
         * -- validate cert chain
         */
        if(ctx == NULL) {
         * -- validate cert chain
         */
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
 
        /* can't do this with an active session */
        }
 
        /* can't do this with an active session */
@@ -1459,13 +1535,13 @@ SSLSetCertificate                       (SSLContextRef          ctx,
           /* kSSLClientCertRequested implies client side */
           (ctx->clientCertState != kSSLClientCertRequested))
        {
           /* kSSLClientCertRequested implies client side */
           (ctx->clientCertState != kSSLClientCertRequested))
        {
-                       return badReqErr;
+                       return errSecBadReq;
        }
     CFReleaseNull(ctx->localCertArray);
        /* changing the client cert invalidates negotiated auth type */
        ctx->negAuthType = SSLClientAuthNone;
        if(certRefs == NULL) {
        }
     CFReleaseNull(ctx->localCertArray);
        /* changing the client cert invalidates negotiated auth type */
        ctx->negAuthType = SSLClientAuthNone;
        if(certRefs == NULL) {
-               return noErr; // we have cleared the cert, as requested
+               return errSecSuccess; // we have cleared the cert, as requested
        }
        OSStatus ortn = parseIncomingCerts(ctx,
                certRefs,
        }
        OSStatus ortn = parseIncomingCerts(ctx,
                certRefs,
@@ -1473,7 +1549,7 @@ SSLSetCertificate                 (SSLContextRef          ctx,
                &ctx->signingPubKey,
                &ctx->signingPrivKeyRef,
                &ctx->ourSignerAlg);
                &ctx->signingPubKey,
                &ctx->signingPrivKeyRef,
                &ctx->ourSignerAlg);
-       if(ortn == noErr) {
+       if(ortn == errSecSuccess) {
                ctx->localCertArray = certRefs;
                CFRetain(certRefs);
                /* client cert was changed, must update auth type */
                ctx->localCertArray = certRefs;
                CFRetain(certRefs);
                /* client cert was changed, must update auth type */
@@ -1493,11 +1569,11 @@ SSLSetEncryptionCertificate     (SSLContextRef          ctx,
         * -- validate cert chain
         */
        if(ctx == NULL) {
         * -- validate cert chain
         */
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        if(sslIsSessionActive(ctx)) {
                /* can't do this with an active session */
        }
        if(sslIsSessionActive(ctx)) {
                /* can't do this with an active session */
-               return badReqErr;
+               return errSecBadReq;
        }
     CFReleaseNull(ctx->encryptCertArray);
        OSStatus ortn = parseIncomingCerts(ctx,
        }
     CFReleaseNull(ctx->encryptCertArray);
        OSStatus ortn = parseIncomingCerts(ctx,
@@ -1506,7 +1582,7 @@ SSLSetEncryptionCertificate       (SSLContextRef          ctx,
                &ctx->encryptPubKey,
                &ctx->encryptPrivKeyRef,
                NULL);                  /* Signer alg */
                &ctx->encryptPubKey,
                &ctx->encryptPrivKeyRef,
                NULL);                  /* Signer alg */
-       if(ortn == noErr) {
+       if(ortn == errSecSuccess) {
                ctx->encryptCertArray = certRefs;
                CFRetain(certRefs);
        }
                ctx->encryptCertArray = certRefs;
                CFRetain(certRefs);
        }
@@ -1517,20 +1593,20 @@ OSStatus SSLGetCertificate(SSLContextRef                ctx,
                                                   CFArrayRef                   *certRefs)
 {
        if(ctx == NULL) {
                                                   CFArrayRef                   *certRefs)
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        *certRefs = ctx->localCertArray;
        }
        *certRefs = ctx->localCertArray;
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus SSLGetEncryptionCertificate(SSLContextRef             ctx,
                                                                     CFArrayRef                 *certRefs)
 {
        if(ctx == NULL) {
 }
 
 OSStatus SSLGetEncryptionCertificate(SSLContextRef             ctx,
                                                                     CFArrayRef                 *certRefs)
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        *certRefs = ctx->encryptCertArray;
        }
        *certRefs = ctx->encryptCertArray;
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -1544,21 +1620,21 @@ SSLSetPeerID                            (SSLContext             *ctx,
        if((ctx == NULL) ||
           (peerID == NULL) ||
           (peerIDLen == 0)) {
        if((ctx == NULL) ||
           (peerID == NULL) ||
           (peerIDLen == 0)) {
-               return paramErr;
+               return errSecParam;
        }
        if(sslIsSessionActive(ctx) &&
         /* kSSLClientCertRequested implies client side */
         (ctx->clientCertState != kSSLClientCertRequested))
     {
        }
        if(sslIsSessionActive(ctx) &&
         /* kSSLClientCertRequested implies client side */
         (ctx->clientCertState != kSSLClientCertRequested))
     {
-               return badReqErr;
+               return errSecBadReq;
        }
        }
-       SSLFreeBuffer(&ctx->peerID, ctx);
-       serr = SSLAllocBuffer(&ctx->peerID, peerIDLen, ctx);
+       SSLFreeBuffer(&ctx->peerID);
+       serr = SSLAllocBuffer(&ctx->peerID, peerIDLen);
        if(serr) {
                return serr;
        }
        memmove(ctx->peerID.data, peerID, peerIDLen);
        if(serr) {
                return serr;
        }
        memmove(ctx->peerID.data, peerID, peerIDLen);
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -1568,7 +1644,7 @@ SSLGetPeerID                              (SSLContextRef          ctx,
 {
        *peerID = ctx->peerID.data;                     // may be NULL
        *peerIDLen = ctx->peerID.length;
 {
        *peerID = ctx->peerID.data;                     // may be NULL
        *peerIDLen = ctx->peerID.length;
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -1576,13 +1652,13 @@ SSLGetNegotiatedCipher          (SSLContextRef          ctx,
                                                         SSLCipherSuite         *cipherSuite)
 {
        if(ctx == NULL) {
                                                         SSLCipherSuite         *cipherSuite)
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        if(!sslIsSessionActive(ctx)) {
        }
        if(!sslIsSessionActive(ctx)) {
-               return badReqErr;
+               return errSecBadReq;
        }
        *cipherSuite = (SSLCipherSuite)ctx->selectedCipher;
        }
        *cipherSuite = (SSLCipherSuite)ctx->selectedCipher;
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -1598,22 +1674,22 @@ SSLAddDistinguishedName(
     OSStatus        err;
 
        if(ctx == NULL) {
     OSStatus        err;
 
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        if(sslIsSessionActive(ctx)) {
        }
        if(sslIsSessionActive(ctx)) {
-               return badReqErr;
+               return errSecBadReq;
        }
 
        dn = (DNListElem *)sslMalloc(sizeof(DNListElem));
        if(dn == NULL) {
        }
 
        dn = (DNListElem *)sslMalloc(sizeof(DNListElem));
        if(dn == NULL) {
-               return memFullErr;
+               return errSecAllocate;
        }
        }
-    if ((err = SSLAllocBuffer(&dn->derDN, derDNLen, ctx)) != 0)
+    if ((err = SSLAllocBuffer(&dn->derDN, derDNLen)))
         return err;
     memcpy(dn->derDN.data, derDN, derDNLen);
     dn->next = ctx->acceptableDNList;
     ctx->acceptableDNList = dn;
         return err;
     memcpy(dn->derDN.data, derDN, derDNLen);
     dn->next = ctx->acceptableDNList;
     ctx->acceptableDNList = dn;
-    return noErr;
+    return errSecSuccess;
 }
 
 /* single-cert version of SSLSetCertificateAuthorities() */
 }
 
 /* single-cert version of SSLSetCertificateAuthorities() */
@@ -1621,26 +1697,42 @@ static OSStatus
 sslAddCA(SSLContextRef         ctx,
                 SecCertificateRef      cert)
 {
 sslAddCA(SSLContextRef         ctx,
                 SecCertificateRef      cert)
 {
-       OSStatus ortn = paramErr;
-       CFDataRef subjectName;
+       OSStatus ortn = errSecParam;
 
     /* Get subject from certificate. */
 
     /* Get subject from certificate. */
-    require(subjectName = SecCertificateCopySubjectSequence(cert), errOut);
+#if TARGET_OS_IPHONE
+    CFDataRef subjectName = NULL;
+    subjectName = SecCertificateCopySubjectSequence(cert);
+    require(subjectName, errOut);
+#else
+    CSSM_DATA_PTR subjectName = NULL;
+    ortn = SecCertificateCopyFirstFieldValue(cert, &CSSMOID_X509V1SubjectNameStd, &subjectName);
+    require_noerr(ortn, errOut);
+#endif
+
        /* add to acceptableCAs as cert, creating array if necessary */
        if(ctx->acceptableCAs == NULL) {
                require(ctx->acceptableCAs = CFArrayCreateMutable(NULL, 0,
             &kCFTypeArrayCallBacks), errOut);
                if(ctx->acceptableCAs == NULL) {
        /* add to acceptableCAs as cert, creating array if necessary */
        if(ctx->acceptableCAs == NULL) {
                require(ctx->acceptableCAs = CFArrayCreateMutable(NULL, 0,
             &kCFTypeArrayCallBacks), errOut);
                if(ctx->acceptableCAs == NULL) {
-                       return memFullErr;
+                       return errSecAllocate;
                }
        }
        CFArrayAppendValue(ctx->acceptableCAs, cert);
 
        /* then add this cert's subject name to acceptableDNList */
                }
        }
        CFArrayAppendValue(ctx->acceptableCAs, cert);
 
        /* then add this cert's subject name to acceptableDNList */
-       ortn = SSLAddDistinguishedName(ctx, CFDataGetBytePtr(subjectName),
-        CFDataGetLength(subjectName));
+#if TARGET_OS_IPHONE
+       ortn = SSLAddDistinguishedName(ctx,
+                                   CFDataGetBytePtr(subjectName),
+                                   CFDataGetLength(subjectName));
+#else
+    ortn = SSLAddDistinguishedName(ctx, subjectName->Data, subjectName->Length);
+#endif
+
 errOut:
 errOut:
+#if TARGET_OS_IPHONE
     CFReleaseSafe(subjectName);
     CFReleaseSafe(subjectName);
+#endif
        return ortn;
 }
 
        return ortn;
 }
 
@@ -1655,11 +1747,11 @@ SSLSetCertificateAuthorities(SSLContextRef              ctx,
                                                         Boolean                        replaceExisting)
 {
        CFTypeID itemType;
                                                         Boolean                        replaceExisting)
 {
        CFTypeID itemType;
-       OSStatus ortn = noErr;
+       OSStatus ortn = errSecSuccess;
 
        if((ctx == NULL) || sslIsSessionActive(ctx) ||
           (ctx->protocolSide != kSSLServerSide)) {
 
        if((ctx == NULL) || sslIsSessionActive(ctx) ||
           (ctx->protocolSide != kSSLServerSide)) {
-               return paramErr;
+               return errSecParam;
        }
        if(replaceExisting) {
                sslFreeDnList(ctx);
        }
        if(replaceExisting) {
                sslFreeDnList(ctx);
@@ -1684,7 +1776,7 @@ SSLSetCertificateAuthorities(SSLContextRef                ctx,
                for(dex=0; dex<numCerts; dex++) {
                        SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(cfa, dex);
                        if(CFGetTypeID(cert) != SecCertificateGetTypeID()) {
                for(dex=0; dex<numCerts; dex++) {
                        SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(cfa, dex);
                        if(CFGetTypeID(cert) != SecCertificateGetTypeID()) {
-                               return paramErr;
+                               return errSecParam;
                        }
                        ortn = sslAddCA(ctx, cert);
                        if(ortn) {
                        }
                        ortn = sslAddCA(ctx, cert);
                        if(ortn) {
@@ -1693,7 +1785,7 @@ SSLSetCertificateAuthorities(SSLContextRef                ctx,
                }
        }
        else {
                }
        }
        else {
-               ortn = paramErr;
+               ortn = errSecParam;
        }
        return ortn;
 }
        }
        return ortn;
 }
@@ -1710,15 +1802,15 @@ SSLCopyCertificateAuthorities(SSLContextRef             ctx,
                                                          CFArrayRef            *certificates)  /* RETURNED */
 {
        if((ctx == NULL) || (certificates == NULL)) {
                                                          CFArrayRef            *certificates)  /* RETURNED */
 {
        if((ctx == NULL) || (certificates == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        if(ctx->acceptableCAs == NULL) {
                *certificates = NULL;
        }
        if(ctx->acceptableCAs == NULL) {
                *certificates = NULL;
-               return noErr;
+               return errSecSuccess;
        }
        *certificates = ctx->acceptableCAs;
        CFRetain(ctx->acceptableCAs);
        }
        *certificates = ctx->acceptableCAs;
        CFRetain(ctx->acceptableCAs);
-       return noErr;
+       return errSecSuccess;
 }
 
 
 }
 
 
@@ -1736,11 +1828,11 @@ SSLCopyDistinguishedNames       (SSLContextRef          ctx,
        DNListElem *dn;
 
        if((ctx == NULL) || (names == NULL)) {
        DNListElem *dn;
 
        if((ctx == NULL) || (names == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        if(ctx->acceptableDNList == NULL) {
                *names = NULL;
        }
        if(ctx->acceptableDNList == NULL) {
                *names = NULL;
-               return noErr;
+               return errSecSuccess;
        }
        outArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
        dn = ctx->acceptableDNList;
        }
        outArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
        dn = ctx->acceptableDNList;
@@ -1751,7 +1843,7 @@ SSLCopyDistinguishedNames (SSLContextRef          ctx,
                dn = dn->next;
        }
        *names = outArray;
                dn = dn->next;
        }
        *names = outArray;
-       return noErr;
+       return errSecSuccess;
 }
 
 
 }
 
 
@@ -1759,6 +1851,7 @@ SSLCopyDistinguishedNames (SSLContextRef          ctx,
  * Request peer certificates. Valid anytime, subsequent to
  * a handshake attempt.
  * Common code for SSLGetPeerCertificates() and SSLCopyPeerCertificates().
  * Request peer certificates. Valid anytime, subsequent to
  * a handshake attempt.
  * Common code for SSLGetPeerCertificates() and SSLCopyPeerCertificates().
+ * TODO: the 'legacy' argument is not used anymore.
  */
 static OSStatus
 sslCopyPeerCertificates                (SSLContextRef          ctx,
  */
 static OSStatus
 sslCopyPeerCertificates                (SSLContextRef          ctx,
@@ -1766,7 +1859,7 @@ sslCopyPeerCertificates           (SSLContextRef          ctx,
                                                         Boolean                        legacy)
 {
        if(ctx == NULL) {
                                                         Boolean                        legacy)
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
 
 #ifdef USE_SSLCERTIFICATE
        }
 
 #ifdef USE_SSLCERTIFICATE
@@ -1786,12 +1879,12 @@ sslCopyPeerCertificates         (SSLContextRef          ctx,
         */
        numCerts = SSLGetCertificateChainLength(ctx->peerCert);
        if(numCerts == 0) {
         */
        numCerts = SSLGetCertificateChainLength(ctx->peerCert);
        if(numCerts == 0) {
-               return noErr;
+               return errSecSuccess;
        }
        ca = CFArrayCreateMutable(kCFAllocatorDefault,
                (CFIndex)numCerts, &kCFTypeArrayCallBacks);
        if(ca == NULL) {
        }
        ca = CFArrayCreateMutable(kCFAllocatorDefault,
                (CFIndex)numCerts, &kCFTypeArrayCallBacks);
        if(ca == NULL) {
-               return memFullErr;
+               return errSecAllocate;
        }
 
        /*
        }
 
        /*
@@ -1823,13 +1916,13 @@ sslCopyPeerCertificates         (SSLContextRef          ctx,
 #else
        if (!ctx->peerCert) {
                *certs = NULL;
 #else
        if (!ctx->peerCert) {
                *certs = NULL;
-               return badReqErr;
+               return errSecBadReq;
        }
 
     CFArrayRef ca = CFArrayCreateCopy(kCFAllocatorDefault, ctx->peerCert);
     *certs = ca;
     if (ca == NULL) {
        }
 
     CFArrayRef ca = CFArrayCreateCopy(kCFAllocatorDefault, ctx->peerCert);
     *certs = ca;
     if (ca == NULL) {
-        return memFullErr;
+        return errSecAllocate;
     }
 
        if (legacy) {
     }
 
        if (legacy) {
@@ -1840,7 +1933,7 @@ sslCopyPeerCertificates           (SSLContextRef          ctx,
        }
 #endif
 
        }
 #endif
 
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -1850,13 +1943,19 @@ SSLCopyPeerCertificates         (SSLContextRef          ctx,
        return sslCopyPeerCertificates(ctx, certs, false);
 }
 
        return sslCopyPeerCertificates(ctx, certs, false);
 }
 
+#if !TARGET_OS_IPHONE
+// Permanently removing from iOS, keep for OSX (deprecated), removed from headers.
+// <rdar://problem/14215831> Mailsmith Crashes While Getting New Mail Under Mavericks Developer Preview
 OSStatus
 OSStatus
-SSLGetPeerCertificates         (SSLContextRef          ctx,
-                                                        CFArrayRef                     *certs)
- {
-        return sslCopyPeerCertificates(ctx, certs, true);
- }
-
+SSLGetPeerCertificates (SSLContextRef ctx,
+                        CFArrayRef *certs);
+OSStatus
+SSLGetPeerCertificates (SSLContextRef ctx,
+                        CFArrayRef *certs)
+{
+    return sslCopyPeerCertificates(ctx, certs, true);
+}
+#endif
 
 /*
  * Specify Diffie-Hellman parameters. Optional; if we are configured to allow
 
 /*
  * Specify Diffie-Hellman parameters. Optional; if we are configured to allow
@@ -1871,12 +1970,12 @@ OSStatus SSLSetDiffieHellmanParams(
 {
 #if APPLE_DH
        if(ctx == NULL) {
 {
 #if APPLE_DH
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        if(sslIsSessionActive(ctx)) {
        }
        if(sslIsSessionActive(ctx)) {
-               return badReqErr;
+               return errSecBadReq;
        }
        }
-       SSLFreeBuffer(&ctx->dhParamsEncoded, ctx);
+       SSLFreeBuffer(&ctx->dhParamsEncoded);
 #if !USE_CDSA_CRYPTO
     if (ctx->secDHContext)
         SecDHDestroy(ctx->secDHContext);
 #if !USE_CDSA_CRYPTO
     if (ctx->secDHContext)
         SecDHDestroy(ctx->secDHContext);
@@ -1902,13 +2001,13 @@ OSStatus SSLGetDiffieHellmanParams(
 {
 #if APPLE_DH
        if(ctx == NULL) {
 {
 #if APPLE_DH
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        *dhParams = ctx->dhParamsEncoded.data;
        *dhParamsLen = ctx->dhParamsEncoded.length;
        }
        *dhParams = ctx->dhParamsEncoded.data;
        *dhParamsLen = ctx->dhParamsEncoded.length;
-       return noErr;
+       return errSecSuccess;
 #else
 #else
-    return unimpErr;
+    return errSecUnimplemented;
 #endif /* APPLE_DH */
 }
 
 #endif /* APPLE_DH */
 }
 
@@ -1917,10 +2016,10 @@ OSStatus SSLSetRsaBlinding(
        Boolean                 blinding)
 {
        if(ctx == NULL) {
        Boolean                 blinding)
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        ctx->rsaBlindingEnable = blinding;
        }
        ctx->rsaBlindingEnable = blinding;
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus SSLGetRsaBlinding(
 }
 
 OSStatus SSLGetRsaBlinding(
@@ -1928,10 +2027,10 @@ OSStatus SSLGetRsaBlinding(
        Boolean                 *blinding)
 {
        if(ctx == NULL) {
        Boolean                 *blinding)
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        *blinding = ctx->rsaBlindingEnable;
        }
        *blinding = ctx->rsaBlindingEnable;
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -1939,9 +2038,9 @@ SSLCopyPeerTrust(
     SSLContextRef              ctx,
     SecTrustRef        *trust) /* RETURNED */
 {
     SSLContextRef              ctx,
     SecTrustRef        *trust) /* RETURNED */
 {
-       OSStatus status = noErr;
+       OSStatus status = errSecSuccess;
        if (ctx == NULL || trust == NULL)
        if (ctx == NULL || trust == NULL)
-               return paramErr;
+               return errSecParam;
 
        /* Create a SecTrustRef if this was a resumed session and we
           didn't have one yet. */
 
        /* Create a SecTrustRef if this was a resumed session and we
           didn't have one yet. */
@@ -1961,9 +2060,9 @@ OSStatus SSLGetPeerSecTrust(
        SSLContextRef   ctx,
        SecTrustRef             *trust) /* RETURNED */
 {
        SSLContextRef   ctx,
        SecTrustRef             *trust) /* RETURNED */
 {
-    OSStatus status = noErr;
+    OSStatus status = errSecSuccess;
        if (ctx == NULL || trust == NULL)
        if (ctx == NULL || trust == NULL)
-               return paramErr;
+               return errSecParam;
 
        /* Create a SecTrustRef if this was a resumed session and we
           didn't have one yet. */
 
        /* Create a SecTrustRef if this was a resumed session and we
           didn't have one yet. */
@@ -1982,14 +2081,14 @@ OSStatus SSLInternalMasterSecret(
    size_t *secretSize)  // in/out
 {
        if((ctx == NULL) || (secret == NULL) || (secretSize == NULL)) {
    size_t *secretSize)  // in/out
 {
        if((ctx == NULL) || (secret == NULL) || (secretSize == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        if(*secretSize < SSL_MASTER_SECRET_SIZE) {
        }
        if(*secretSize < SSL_MASTER_SECRET_SIZE) {
-               return paramErr;
+               return errSecParam;
        }
        memmove(secret, ctx->masterSecret, SSL_MASTER_SECRET_SIZE);
        *secretSize = SSL_MASTER_SECRET_SIZE;
        }
        memmove(secret, ctx->masterSecret, SSL_MASTER_SECRET_SIZE);
        *secretSize = SSL_MASTER_SECRET_SIZE;
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus SSLInternalServerRandom(
 }
 
 OSStatus SSLInternalServerRandom(
@@ -1998,14 +2097,14 @@ OSStatus SSLInternalServerRandom(
    size_t *randSize)   // in/out
 {
        if((ctx == NULL) || (randBuf == NULL) || (randSize == NULL)) {
    size_t *randSize)   // in/out
 {
        if((ctx == NULL) || (randBuf == NULL) || (randSize == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        if(*randSize < SSL_CLIENT_SRVR_RAND_SIZE) {
        }
        if(*randSize < SSL_CLIENT_SRVR_RAND_SIZE) {
-               return paramErr;
+               return errSecParam;
        }
        memmove(randBuf, ctx->serverRandom, SSL_CLIENT_SRVR_RAND_SIZE);
        *randSize = SSL_CLIENT_SRVR_RAND_SIZE;
        }
        memmove(randBuf, ctx->serverRandom, SSL_CLIENT_SRVR_RAND_SIZE);
        *randSize = SSL_CLIENT_SRVR_RAND_SIZE;
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus SSLInternalClientRandom(
 }
 
 OSStatus SSLInternalClientRandom(
@@ -2014,33 +2113,34 @@ OSStatus SSLInternalClientRandom(
    size_t *randSize)   // in/out
 {
        if((ctx == NULL) || (randBuf == NULL) || (randSize == NULL)) {
    size_t *randSize)   // in/out
 {
        if((ctx == NULL) || (randBuf == NULL) || (randSize == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        if(*randSize < SSL_CLIENT_SRVR_RAND_SIZE) {
        }
        if(*randSize < SSL_CLIENT_SRVR_RAND_SIZE) {
-               return paramErr;
+               return errSecParam;
        }
        memmove(randBuf, ctx->clientRandom, SSL_CLIENT_SRVR_RAND_SIZE);
        *randSize = SSL_CLIENT_SRVR_RAND_SIZE;
        }
        memmove(randBuf, ctx->clientRandom, SSL_CLIENT_SRVR_RAND_SIZE);
        *randSize = SSL_CLIENT_SRVR_RAND_SIZE;
-       return noErr;
+       return errSecSuccess;
 }
 
 }
 
+/* This is used by EAP 802.1x */
 OSStatus SSLGetCipherSizes(
        SSLContextRef ctx,
        size_t *digestSize,
        size_t *symmetricKeySize,
        size_t *ivSize)
 {
 OSStatus SSLGetCipherSizes(
        SSLContextRef ctx,
        size_t *digestSize,
        size_t *symmetricKeySize,
        size_t *ivSize)
 {
-       const SSLCipherSpec *currCipher;
-
-       if((ctx == NULL) || (digestSize == NULL) ||
+       const SSLCipherSpecParams *currCipher;
+       
+       if((ctx == NULL) || (digestSize == NULL) || 
           (symmetricKeySize == NULL) || (ivSize == NULL)) {
           (symmetricKeySize == NULL) || (ivSize == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        }
-       currCipher = &ctx->selectedCipherSpec;
-       *digestSize = currCipher->macAlgorithm->hash->digestSize;
-       *symmetricKeySize = currCipher->cipher->secretKeySize;
-       *ivSize = currCipher->cipher->ivSize;
-       return noErr;
+       currCipher = &ctx->selectedCipherSpecParams;
+       *digestSize = currCipher->macSize;
+       *symmetricKeySize = currCipher->keySize;
+       *ivSize = currCipher->ivSize;
+       return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -2053,13 +2153,13 @@ SSLGetResumableSessionInfo(
        if((ctx == NULL) || (sessionWasResumed == NULL) ||
           (sessionID == NULL) || (sessionIDLength == NULL) ||
           (*sessionIDLength < MAX_SESSION_ID_LENGTH)) {
        if((ctx == NULL) || (sessionWasResumed == NULL) ||
           (sessionID == NULL) || (sessionIDLength == NULL) ||
           (*sessionIDLength < MAX_SESSION_ID_LENGTH)) {
-               return paramErr;
+               return errSecParam;
        }
        if(ctx->sessionMatch) {
                *sessionWasResumed = true;
                if(ctx->sessionID.length > *sessionIDLength) {
                        /* really should never happen - means ID > 32 */
        }
        if(ctx->sessionMatch) {
                *sessionWasResumed = true;
                if(ctx->sessionID.length > *sessionIDLength) {
                        /* really should never happen - means ID > 32 */
-                       return paramErr;
+                       return errSecParam;
                }
                if(ctx->sessionID.length) {
                        /*
                }
                if(ctx->sessionID.length) {
                        /*
@@ -2074,7 +2174,7 @@ SSLGetResumableSessionInfo(
                *sessionWasResumed = false;
                *sessionIDLength = 0;
        }
                *sessionWasResumed = false;
                *sessionIDLength = 0;
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -2086,17 +2186,17 @@ SSLSetAllowAnonymousCiphers(
        Boolean                 enable)
 {
        if(ctx == NULL) {
        Boolean                 enable)
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        if(sslIsSessionActive(ctx)) {
        }
        if(sslIsSessionActive(ctx)) {
-               return badReqErr;
+               return errSecBadReq;
        }
        if(ctx->validCipherSuites != NULL) {
                /* SSLSetEnabledCiphers() has already been called */
        }
        if(ctx->validCipherSuites != NULL) {
                /* SSLSetEnabledCiphers() has already been called */
-               return badReqErr;
+               return errSecBadReq;
        }
        ctx->anonCipherEnable = enable;
        }
        ctx->anonCipherEnable = enable;
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -2105,13 +2205,13 @@ SSLGetAllowAnonymousCiphers(
        Boolean                 *enable)
 {
        if((ctx == NULL) || (enable == NULL)) {
        Boolean                 *enable)
 {
        if((ctx == NULL) || (enable == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        if(sslIsSessionActive(ctx)) {
        }
        if(sslIsSessionActive(ctx)) {
-               return badReqErr;
+               return errSecBadReq;
        }
        *enable = ctx->anonCipherEnable;
        }
        *enable = ctx->anonCipherEnable;
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -2124,10 +2224,10 @@ SSLSetSessionCacheTimeout(
        uint32_t timeoutInSeconds)
 {
        if(ctx == NULL) {
        uint32_t timeoutInSeconds)
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        ctx->sessionCacheTimeout = timeoutInSeconds;
        }
        ctx->sessionCacheTimeout = timeoutInSeconds;
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -2141,11 +2241,11 @@ SSLInternalSetMasterSecretFunction(
        const void *arg)                /* opaque to SecureTransport; app-specific */
 {
        if(ctx == NULL) {
        const void *arg)                /* opaque to SecureTransport; app-specific */
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        ctx->masterSecretCallback = mFunc;
        ctx->masterSecretArg = arg;
        }
        ctx->masterSecretCallback = mFunc;
        ctx->masterSecretArg = arg;
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -2167,17 +2267,17 @@ OSStatus SSLInternalSetSessionTicket(
    size_t ticketLength)
 {
        if(ctx == NULL) {
    size_t ticketLength)
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        if(sslIsSessionActive(ctx)) {
                /* can't do this with an active session */
        }
        if(sslIsSessionActive(ctx)) {
                /* can't do this with an active session */
-               return badReqErr;
+               return errSecBadReq;
        }
        if(ticketLength > 0xffff) {
                /* extension data encoded with a 2-byte length! */
        }
        if(ticketLength > 0xffff) {
                /* extension data encoded with a 2-byte length! */
-               return paramErr;
+               return errSecParam;
        }
        }
-       SSLFreeBuffer(&ctx->sessionTicket, NULL);
+       SSLFreeBuffer(&ctx->sessionTicket);
        return SSLCopyBufferFromData(ticket, ticketLength, &ctx->sessionTicket);
 }
 
        return SSLCopyBufferFromData(ticket, ticketLength, &ctx->sessionTicket);
 }
 
@@ -2187,20 +2287,20 @@ OSStatus SSLInternalSetSessionTicket(
 
 /*
  * Obtain the SSL_ECDSA_NamedCurve negotiated during a handshake.
 
 /*
  * Obtain the SSL_ECDSA_NamedCurve negotiated during a handshake.
- * Returns paramErr if no ECDH-related ciphersuite was negotiated.
+ * Returns errSecParam if no ECDH-related ciphersuite was negotiated.
  */
 OSStatus SSLGetNegotiatedCurve(
    SSLContextRef ctx,
    SSL_ECDSA_NamedCurve *namedCurve)    /* RETURNED */
 {
        if((ctx == NULL) || (namedCurve == NULL)) {
  */
 OSStatus SSLGetNegotiatedCurve(
    SSLContextRef ctx,
    SSL_ECDSA_NamedCurve *namedCurve)    /* RETURNED */
 {
        if((ctx == NULL) || (namedCurve == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        if(ctx->ecdhPeerCurve == SSL_Curve_None) {
        }
        if(ctx->ecdhPeerCurve == SSL_Curve_None) {
-               return paramErr;
+               return errSecParam;
        }
        *namedCurve = ctx->ecdhPeerCurve;
        }
        *namedCurve = ctx->ecdhPeerCurve;
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -2211,10 +2311,10 @@ OSStatus SSLGetNumberOfECDSACurves(
    unsigned *numCurves)        /* RETURNED */
 {
        if((ctx == NULL) || (numCurves == NULL)) {
    unsigned *numCurves)        /* RETURNED */
 {
        if((ctx == NULL) || (numCurves == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        *numCurves = ctx->ecdhNumCurves;
        }
        *numCurves = ctx->ecdhNumCurves;
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -2226,15 +2326,15 @@ OSStatus SSLGetECDSACurves(
    unsigned *numCurves)                                                /* IN/OUT */
 {
        if((ctx == NULL) || (namedCurves == NULL) || (numCurves == NULL)) {
    unsigned *numCurves)                                                /* IN/OUT */
 {
        if((ctx == NULL) || (namedCurves == NULL) || (numCurves == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        if(*numCurves < ctx->ecdhNumCurves) {
        }
        if(*numCurves < ctx->ecdhNumCurves) {
-               return paramErr;
+               return errSecParam;
        }
        memmove(namedCurves, ctx->ecdhCurves,
                (ctx->ecdhNumCurves * sizeof(SSL_ECDSA_NamedCurve)));
        *numCurves = ctx->ecdhNumCurves;
        }
        memmove(namedCurves, ctx->ecdhCurves,
                (ctx->ecdhNumCurves * sizeof(SSL_ECDSA_NamedCurve)));
        *numCurves = ctx->ecdhNumCurves;
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -2246,24 +2346,24 @@ OSStatus SSLSetECDSACurves(
    unsigned numCurves)
 {
        if((ctx == NULL) || (namedCurves == NULL) || (numCurves == 0)) {
    unsigned numCurves)
 {
        if((ctx == NULL) || (namedCurves == NULL) || (numCurves == 0)) {
-               return paramErr;
+               return errSecParam;
        }
        if(numCurves > SSL_ECDSA_NUM_CURVES) {
        }
        if(numCurves > SSL_ECDSA_NUM_CURVES) {
-               return paramErr;
+               return errSecParam;
        }
        if(sslIsSessionActive(ctx)) {
                /* can't do this with an active session */
        }
        if(sslIsSessionActive(ctx)) {
                /* can't do this with an active session */
-               return badReqErr;
+               return errSecBadReq;
        }
        memmove(ctx->ecdhCurves, namedCurves, (numCurves * sizeof(SSL_ECDSA_NamedCurve)));
        ctx->ecdhNumCurves = numCurves;
        }
        memmove(ctx->ecdhCurves, namedCurves, (numCurves * sizeof(SSL_ECDSA_NamedCurve)));
        ctx->ecdhNumCurves = numCurves;
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
  * Obtain the number of client authentication mechanisms specified by
  * the server in its Certificate Request message.
 }
 
 /*
  * Obtain the number of client authentication mechanisms specified by
  * the server in its Certificate Request message.
- * Returns paramErr if server hasn't sent a Certificate Request message
+ * Returns errSecParam if server hasn't sent a Certificate Request message
  * (i.e., client certificate state is kSSLClientCertNone).
  */
 OSStatus SSLGetNumberOfClientAuthTypes(
  * (i.e., client certificate state is kSSLClientCertNone).
  */
 OSStatus SSLGetNumberOfClientAuthTypes(
@@ -2271,10 +2371,10 @@ OSStatus SSLGetNumberOfClientAuthTypes(
        unsigned *numTypes)
 {
        if((ctx == NULL) || (ctx->clientCertState == kSSLClientCertNone)) {
        unsigned *numTypes)
 {
        if((ctx == NULL) || (ctx->clientCertState == kSSLClientCertNone)) {
-               return paramErr;
+               return errSecParam;
        }
        *numTypes = ctx->numAuthTypes;
        }
        *numTypes = ctx->numAuthTypes;
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -2290,28 +2390,28 @@ OSStatus SSLGetClientAuthTypes(
    unsigned *numTypes)                                                 /* IN/OUT */
 {
        if((ctx == NULL) || (ctx->clientCertState == kSSLClientCertNone)) {
    unsigned *numTypes)                                                 /* IN/OUT */
 {
        if((ctx == NULL) || (ctx->clientCertState == kSSLClientCertNone)) {
-               return paramErr;
+               return errSecParam;
        }
        memmove(authTypes, ctx->clientAuthTypes,
                ctx->numAuthTypes * sizeof(SSLClientAuthenticationType));
        *numTypes = ctx->numAuthTypes;
        }
        memmove(authTypes, ctx->clientAuthTypes,
                ctx->numAuthTypes * sizeof(SSLClientAuthenticationType));
        *numTypes = ctx->numAuthTypes;
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
  * Obtain the SSLClientAuthenticationType actually performed.
  * Only valid if client certificate state is kSSLClientCertSent
 }
 
 /*
  * Obtain the SSLClientAuthenticationType actually performed.
  * Only valid if client certificate state is kSSLClientCertSent
- * or kSSLClientCertRejected; returns paramErr otherwise.
+ * or kSSLClientCertRejected; returns errSecParam otherwise.
  */
 OSStatus SSLGetNegotiatedClientAuthType(
    SSLContextRef ctx,
    SSLClientAuthenticationType *authType)              /* RETURNED */
 {
        if(ctx == NULL) {
  */
 OSStatus SSLGetNegotiatedClientAuthType(
    SSLContextRef ctx,
    SSLClientAuthenticationType *authType)              /* RETURNED */
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        *authType = ctx->negAuthType;
        }
        *authType = ctx->negAuthType;
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -2328,7 +2428,7 @@ OSStatus SSLUpdateNegotiatedClientAuthType(
        SSLContextRef ctx)
 {
        if(ctx == NULL) {
        SSLContextRef ctx)
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        /*
         * See if we have a signing cert that matches one of the
        }
        /*
         * See if we have a signing cert that matches one of the
@@ -2381,7 +2481,7 @@ OSStatus SSLUpdateNegotiatedClientAuthType(
                }       /* parsing authTypes */
        }       /* we have a signing key */
 
                }       /* parsing authTypes */
        }       /* we have a signing key */
 
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus SSLGetNumberOfSignatureAlgorithms(
 }
 
 OSStatus SSLGetNumberOfSignatureAlgorithms(
@@ -2389,10 +2489,10 @@ OSStatus SSLGetNumberOfSignatureAlgorithms(
     unsigned *numSigAlgs)
 {
        if((ctx == NULL) || (ctx->clientCertState == kSSLClientCertNone)) {
     unsigned *numSigAlgs)
 {
        if((ctx == NULL) || (ctx->clientCertState == kSSLClientCertNone)) {
-               return paramErr;
+               return errSecParam;
        }
        *numSigAlgs = ctx->numServerSigAlgs;
        }
        *numSigAlgs = ctx->numServerSigAlgs;
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus SSLGetSignatureAlgorithms(
 }
 
 OSStatus SSLGetSignatureAlgorithms(
@@ -2401,10 +2501,88 @@ OSStatus SSLGetSignatureAlgorithms(
     unsigned *numSigAlgs)                                                      /* IN/OUT */
 {
        if((ctx == NULL) || (ctx->clientCertState == kSSLClientCertNone)) {
     unsigned *numSigAlgs)                                                      /* IN/OUT */
 {
        if((ctx == NULL) || (ctx->clientCertState == kSSLClientCertNone)) {
-               return paramErr;
+               return errSecParam;
        }
        memmove(sigAlgs, ctx->serverSigAlgs,
             ctx->numServerSigAlgs * sizeof(SSLSignatureAndHashAlgorithm));
        *numSigAlgs = ctx->numServerSigAlgs;
        }
        memmove(sigAlgs, ctx->serverSigAlgs,
             ctx->numServerSigAlgs * sizeof(SSLSignatureAndHashAlgorithm));
        *numSigAlgs = ctx->numServerSigAlgs;
-       return noErr;
+       return errSecSuccess;
+}
+
+/* PSK SPIs */
+OSStatus SSLSetPSKSharedSecret(SSLContextRef ctx,
+                               const void *secret,
+                               size_t secretLen)
+{
+    if(ctx == NULL) return errSecParam;
+
+    if(ctx->pskSharedSecret.data)
+        SSLFreeBuffer(&ctx->pskSharedSecret);
+
+    if(SSLCopyBufferFromData(secret, secretLen, &ctx->pskSharedSecret))
+        return errSecAllocate;
+
+    return errSecSuccess;
+}
+
+OSStatus SSLSetPSKIdentity(SSLContextRef ctx,
+                           const void *pskIdentity,
+                           size_t pskIdentityLen)
+{
+    if((ctx == NULL) || (pskIdentity == NULL) || (pskIdentityLen == 0)) return errSecParam;
+
+    if(ctx->pskIdentity.data)
+        SSLFreeBuffer(&ctx->pskIdentity);
+
+    if(SSLCopyBufferFromData(pskIdentity, pskIdentityLen, &ctx->pskIdentity))
+        return errSecAllocate;
+
+    return errSecSuccess;
+
+}
+
+OSStatus SSLGetPSKIdentity(SSLContextRef ctx,
+                           const void **pskIdentity,
+                           size_t *pskIdentityLen)
+{
+    if((ctx == NULL) || (pskIdentity == NULL) || (pskIdentityLen == NULL)) return errSecParam;
+
+    *pskIdentity=ctx->pskIdentity.data;
+    *pskIdentityLen=ctx->pskIdentity.length;
+    return errSecSuccess;
+}
+
+
+#ifdef USE_SSLCERTIFICATE
+
+size_t
+SSLGetCertificateChainLength(const SSLCertificate *c)
+{
+       size_t rtn = 0;
+
+    while (c)
+    {
+       rtn++;
+        c = c->next;
+    }
+    return rtn;
+}
+
+OSStatus sslDeleteCertificateChain(
+                                   SSLCertificate              *certs,
+                                   SSLContext                  *ctx)
+{
+       SSLCertificate          *cert;
+       SSLCertificate          *nextCert;
+
+       assert(ctx != NULL);
+       cert=certs;
+       while(cert != NULL) {
+               nextCert = cert->next;
+               SSLFreeBuffer(&cert->derCert);
+               sslFree(cert);
+               cert = nextCert;
+       }
+       return errSecSuccess;
 }
 }
+#endif /* USE_SSLCERTIFICATE */
index 45d1175a7054cf83d0612b1b36a4b4efef6aebdb..eee676cc7829e4829233b01a84344cf3b3a61a27 100644 (file)
 #ifndef _SSLCONTEXT_H_
 #define _SSLCONTEXT_H_ 1
 
 #ifndef _SSLCONTEXT_H_
 #define _SSLCONTEXT_H_ 1
 
-#include "ssl.h"
 #include "SecureTransport.h"
 #include "sslBuildFlags.h"
 
 #ifdef USE_CDSA_CRYPTO
 #include <Security/cssmtype.h>
 #else
 #include "SecureTransport.h"
 #include "sslBuildFlags.h"
 
 #ifdef USE_CDSA_CRYPTO
 #include <Security/cssmtype.h>
 #else
-#if TARGET_OS_IOS
+#if TARGET_OS_IPHONE
 #include <Security/SecDH.h>
 #include <Security/SecKeyInternal.h>
 #else
 #include <Security/SecDH.h>
 #include <Security/SecKeyInternal.h>
 #else
-typedef struct OpaqueSecDHContext *SecDHContext;
+#include "../sec/Security/SecDH.h"  // hack to get SecDH.
+// typedef struct OpaqueSecDHContext *SecDHContext;
 #endif
 #include <corecrypto/ccec.h>
 #endif
 
 #endif
 #include <corecrypto/ccec.h>
 #endif
 
-#include <CommonCrypto/CommonCryptor.h>
 #include <CoreFoundation/CFRuntime.h>
 #include <CoreFoundation/CFRuntime.h>
+#include <AssertMacros.h>
 
 #include "sslPriv.h"
 #include "tls_ssl.h"
 #include "sslDigests.h"
 
 #include "sslPriv.h"
 #include "tls_ssl.h"
 #include "sslDigests.h"
-
+#include "sslRecord.h"
+#include "cipherSpecs.h"
 
 #ifdef __cplusplus
 extern "C" {
 
 #ifdef __cplusplus
 extern "C" {
@@ -64,63 +65,27 @@ typedef struct
 
 
 #ifdef USE_SSLCERTIFICATE
 
 
 #ifdef USE_SSLCERTIFICATE
+
 /*
  * An element in a certificate chain.
  */
 typedef struct SSLCertificate
 /*
  * An element in a certificate chain.
  */
 typedef struct SSLCertificate
-{
-       struct SSLCertificate   *next;
+{   
+    struct SSLCertificate   *next;
     SSLBuffer               derCert;
 } SSLCertificate;
 
     SSLBuffer               derCert;
 } SSLCertificate;
 
-#endif
-
-#include "cryptType.h"
-
-/*
- * An SSLContext contains four of these - one for each of {read,write} and for
- * {current, pending}.
- */
-struct CipherContext
-{
-
-       const HashHmacReference         *macRef;                        /* HMAC (TLS) or digest (SSL) */
-    const SSLSymmetricCipher   *symCipher;
-
-       /* this is a context which is reused once per record */
-    HashHmacContext                            macCtx;
-
-    /*
-     * Crypto context for CommonCrypto-based symmetric ciphers
-     */
-    CCCryptorRef                       cryptorRef;
+size_t SSLGetCertificateChainLength(
+    const SSLCertificate *c);
+OSStatus sslDeleteCertificateChain(
+    SSLCertificate             *certs,
+    SSLContext                         *ctx);
 
 
-       /* needed in CDSASymmInit */
-       uint8_t                                         encrypting;
+#endif /* USE_SSLCERTIFICATE */
 
 
-    sslUint64                                  sequenceNum;
-    uint8_t                                    ready;
-
-       /* in SSL2 mode, the macSecret is the same size as the
-        * cipher key - which is 24 bytes in the 3DES case. */
-       uint8_t                                         macSecret[SSL_MAX_DIGEST_LEN];
-};
-/* typedef in cryptType.h */
 
 #include "sslHandshake.h"
 
 
 #include "sslHandshake.h"
 
-typedef struct WaitingRecord
-{   struct WaitingRecord    *next;
-    size_t                  sent;
-       /*
-        * These two fields replace a dynamically allocated SSLBuffer;
-        * the payload to write is contained in the variable-length
-        * array data[].
-        */
-       size_t                                  length;
-       UInt8                                   data[1];
-} WaitingRecord;
-
 typedef struct WaitingMessage
 {
     struct WaitingMessage *next;
 typedef struct WaitingMessage
 {
     struct WaitingMessage *next;
@@ -151,7 +116,7 @@ typedef struct SSLPrivKey
 
 #else /* !USE_CDSA_CRYPTO */
 
 
 #else /* !USE_CDSA_CRYPTO */
 
-#if TARGET_OS_IOS
+#if TARGET_OS_IPHONE
 typedef struct __SecKey SSLPubKey;
 typedef struct __SecKey SSLPrivKey;
 #else
 typedef struct __SecKey SSLPubKey;
 typedef struct __SecKey SSLPrivKey;
 #else
@@ -166,12 +131,25 @@ typedef struct OpaqueSecKeyRef SSLPrivKey;
 
 #endif
 
 
 #endif
 
+typedef struct {
+    SSLCipherSuite                           cipherSpec;
+    KeyExchangeMethod                        keyExchangeMethod;
+    uint8_t                           keySize;  /* size in bytes */
+    uint8_t                           ivSize;
+    uint8_t                           blockSize;
+    uint8_t                           macSize;
+    HMAC_Algs                         macAlg;
+} SSLCipherSpecParams;
+
 struct SSLContext
 {
        CFRuntimeBase           _base;
     IOContext           ioCtx;
 
 struct SSLContext
 {
        CFRuntimeBase           _base;
     IOContext           ioCtx;
 
-       /*
+    const struct SSLRecordFuncs *recFuncs;
+    SSLRecordContextRef recCtx;
+    
+       /* 
         * Prior to successful protocol negotiation, negProtocolVersion
         * is SSL_Version_Undetermined. Subsequent to successful
         * negotiation, negProtocolVersion contains the actual over-the-wire
         * Prior to successful protocol negotiation, negProtocolVersion
         * is SSL_Version_Undetermined. Subsequent to successful
         * negotiation, negProtocolVersion contains the actual over-the-wire
@@ -313,15 +291,16 @@ struct SSLContext
 
        char                            *peerDomainName;
        size_t                          peerDomainNameLen;
 
        char                            *peerDomainName;
        size_t                          peerDomainNameLen;
-
-    CipherContext       readCipher;
-    CipherContext       writeCipher;
-    CipherContext       readPending;
-    CipherContext       writePending;
-    CipherContext       prevCipher;             /* previous write cipher context, used for retransmit */
-
+       
+    uint8_t             readCipher_ready;
+    uint8_t             writeCipher_ready;
+    uint8_t             readPending_ready;
+    uint8_t             writePending_ready;
+    uint8_t             prevCipher_ready;             /* previous write cipher context, used for retransmit */
+    
     uint16_t            selectedCipher;                        /* currently selected */
     uint16_t            selectedCipher;                        /* currently selected */
-    SSLCipherSpec       selectedCipherSpec;     /* ditto */
+    SSLCipherSpecParams selectedCipherSpecParams;     /* ditto */
+
     SSLCipherSuite             *validCipherSuites;             /* context's valid suites */
     size_t              numValidCipherSuites;  /* size of validCipherSuites */
 #if ENABLE_SSLV2
     SSLCipherSuite             *validCipherSuites;             /* context's valid suites */
     size_t              numValidCipherSuites;  /* size of validCipherSuites */
 #if ENABLE_SSLV2
@@ -362,12 +341,8 @@ struct SSLContext
     /* Queue a full flight of messages */
     WaitingMessage      *messageWriteQueue;
     Boolean             messageQueueContainsChangeCipherSpec;
     /* Queue a full flight of messages */
     WaitingMessage      *messageWriteQueue;
     Boolean             messageQueueContainsChangeCipherSpec;
-       /* Record layer fields */
-    SSLBuffer                  partialReadBuffer;
-    size_t              amountRead;
-
+    
        /* Transport layer fields */
        /* Transport layer fields */
-    WaitingRecord       *recordWriteQueue;
     SSLBuffer                  receivedDataBuffer;
     size_t              receivedDataPos;
 
     SSLBuffer                  receivedDataBuffer;
     size_t              receivedDataPos;
 
@@ -430,10 +405,25 @@ struct SSLContext
     Boolean             secure_renegotiation_received;
     SSLBuffer           ownVerifyData;
     SSLBuffer           peerVerifyData;
     Boolean             secure_renegotiation_received;
     SSLBuffer           ownVerifyData;
     SSLBuffer           peerVerifyData;
+
+    /* RFC 4279: TLS PSK */
+    SSLBuffer           pskSharedSecret;
+    SSLBuffer           pskIdentity;
+
+    /* TLS False Start */
+    Boolean             falseStartEnabled; //FalseStart enabled (by API call)
 };
 
 OSStatus SSLUpdateNegotiatedClientAuthType(SSLContextRef ctx);
 
 };
 
 OSStatus SSLUpdateNegotiatedClientAuthType(SSLContextRef ctx);
 
+Boolean sslIsSessionActive(const SSLContext *ctx);
+
+static inline bool sslVersionIsLikeTls12(SSLContext *ctx)
+{
+    check(ctx->negProtocolVersion!=SSL_Version_Undetermined);
+    return ctx->isDTLS ? ctx->negProtocolVersion > DTLS_Version_1_0 : ctx->negProtocolVersion >= TLS_Version_1_2;
+}
+
 #ifdef __cplusplus
 }
 #endif
 #ifdef __cplusplus
 }
 #endif
index b9a3b2cd6e358b7a129e1ec55757fa238212a37f..f3a9216b00c409b75e8fdf10aca33663f07d3000 100644 (file)
 #include <CoreFoundation/CFString.h>
 #include <Security/SecKey.h>
 #include <Security/SecKeyPriv.h>
 #include <CoreFoundation/CFString.h>
 #include <Security/SecKey.h>
 #include <Security/SecKeyPriv.h>
-#include <Security/SecKeyInternal.h>
 #include <corecrypto/ccdh.h>
 #include <corecrypto/ccec.h>
 #include <corecrypto/ccrng.h>
 #include <Security/SecCertificate.h>
 #include <Security/SecPolicy.h>
 #include <corecrypto/ccdh.h>
 #include <corecrypto/ccec.h>
 #include <corecrypto/ccrng.h>
 #include <Security/SecCertificate.h>
 #include <Security/SecPolicy.h>
-#include <Security/SecRSAKey.h>
 #include <Security/SecTrust.h>
 #include <AssertMacros.h>
 #include <Security/SecTrust.h>
 #include <AssertMacros.h>
-#include <Security/SecInternal.h>
+#include "utilities/SecCFRelease.h"
+
+#if TARGET_OS_IPHONE
+#include <Security/SecKeyInternal.h>
+#include <Security/SecRSAKey.h>
+#include <Security/SecECKey.h>
+#endif
 
 #ifndef        _SSL_KEYCHAIN_H_
 #include "sslKeychain.h"
 
 #ifndef        _SSL_KEYCHAIN_H_
 #include "sslKeychain.h"
 #include <libDER/asn1Types.h>
 #include <Security/SecRandom.h>
 #endif
 #include <libDER/asn1Types.h>
 #include <Security/SecRandom.h>
 #endif
-#include <Security/SecECKey.h>
 
 #include <string.h>
 #include <stdlib.h>
 #include <assert.h>
 
 
 #include <string.h>
 #include <stdlib.h>
 #include <assert.h>
 
-#if TARGET_OS_IOS
+#if TARGET_OS_IPHONE
 #define CCRNGSTATE ccrng_seckey
 #else
 /* extern struct ccrng_state *ccDRBGGetRngState(); */
 #define CCRNGSTATE ccrng_seckey
 #else
 /* extern struct ccrng_state *ccDRBGGetRngState(); */
@@ -83,7 +86,7 @@ extern OSStatus sslFreePubKey(SSLPubKey **pubKey)
        if (pubKey && *pubKey) {
                CFReleaseNull(SECKEYREF(*pubKey));
        }
        if (pubKey && *pubKey) {
                CFReleaseNull(SECKEYREF(*pubKey));
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -94,7 +97,7 @@ extern OSStatus sslFreePrivKey(SSLPrivKey **privKey)
        if (privKey && *privKey) {
                CFReleaseNull(SECKEYREF(*privKey));
        }
        if (privKey && *privKey) {
                CFReleaseNull(SECKEYREF(*privKey));
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -102,7 +105,7 @@ extern OSStatus sslFreePrivKey(SSLPrivKey **privKey)
  */
 CFIndex sslPubKeyGetAlgorithmID(SSLPubKey *pubKey)
 {
  */
 CFIndex sslPubKeyGetAlgorithmID(SSLPubKey *pubKey)
 {
-#if TARGET_OS_IOS
+#if TARGET_OS_IPHONE
        return SecKeyGetAlgorithmID(SECKEYREF(pubKey));
 #else
        return SecKeyGetAlgorithmId(SECKEYREF(pubKey));
        return SecKeyGetAlgorithmID(SECKEYREF(pubKey));
 #else
        return SecKeyGetAlgorithmId(SECKEYREF(pubKey));
@@ -114,7 +117,7 @@ CFIndex sslPubKeyGetAlgorithmID(SSLPubKey *pubKey)
  */
 CFIndex sslPrivKeyGetAlgorithmID(SSLPrivKey *privKey)
 {
  */
 CFIndex sslPrivKeyGetAlgorithmID(SSLPrivKey *privKey)
 {
-#if TARGET_OS_IOS
+#if TARGET_OS_IPHONE
        return SecKeyGetAlgorithmID(SECKEYREF(privKey));
 #else
        return SecKeyGetAlgorithmId(SECKEYREF(privKey));
        return SecKeyGetAlgorithmID(SECKEYREF(privKey));
 #else
        return SecKeyGetAlgorithmId(SECKEYREF(privKey));
@@ -156,7 +159,7 @@ OSStatus sslRawSign(
                &giSigLen);
        *actualBytes = giSigLen;
 
                &giSigLen);
        *actualBytes = giSigLen;
 
-       return rsaStatus ? rsaStatusToSSL(rsaStatus) : noErr;
+       return rsaStatus ? rsaStatusToSSL(rsaStatus) : errSecSuccess;
 #else
 
        size_t inOutSigLen = sigLen;
 #else
 
        size_t inOutSigLen = sigLen;
@@ -167,7 +170,7 @@ OSStatus sslRawSign(
         plainText, plainTextLen, sig, &inOutSigLen);
 
        if (status) {
         plainText, plainTextLen, sig, &inOutSigLen);
 
        if (status) {
-               sslErrorLog("sslRawSign: SecKeyRawSign failed (error %d)\n", status);
+               sslErrorLog("sslRawSign: SecKeyRawSign failed (error %d)\n", (int)status);
        }
 
     /* Since the KeyExchange already allocated modulus size bytes we'll
        }
 
     /* Since the KeyExchange already allocated modulus size bytes we'll
@@ -205,7 +208,7 @@ OSStatus sslRsaSign(
                                     plainText, plainTextLen, sig, &inOutSigLen);
 
        if (status) {
                                     plainText, plainTextLen, sig, &inOutSigLen);
 
        if (status) {
-               sslErrorLog("sslRsaSign: SecKeySignDigest failed (error %d)\n", status);
+               sslErrorLog("sslRsaSign: SecKeySignDigest failed (error %d)\n", (int) status);
        }
 
     /* Since the KeyExchange already allocated modulus size bytes we'll
        }
 
     /* Since the KeyExchange already allocated modulus size bytes we'll
@@ -240,13 +243,13 @@ OSStatus sslRawVerify(
                sig,
                sigLen);
 
                sig,
                sigLen);
 
-       return rsaStatus ? rsaStatusToSSL(rsaStatus) : noErr;
+       return rsaStatus ? rsaStatusToSSL(rsaStatus) : errSecSuccess;
 #else
        OSStatus status = SecKeyRawVerify(SECKEYREF(pubKey), kSecPaddingPKCS1,
         plainText, plainTextLen, sig, sigLen);
 
        if (status) {
 #else
        OSStatus status = SecKeyRawVerify(SECKEYREF(pubKey), kSecPaddingPKCS1,
         plainText, plainTextLen, sig, sigLen);
 
        if (status) {
-               sslErrorLog("sslRawVerify: SecKeyRawVerify failed (error %d)\n", status);
+               sslErrorLog("sslRawVerify: SecKeyRawVerify failed (error %d)\n", (int) status);
        }
 
        return status;
        }
 
        return status;
@@ -267,7 +270,7 @@ OSStatus sslRsaVerify(
                            plainText, plainTextLen, sig, sigLen);
 
        if (status) {
                            plainText, plainTextLen, sig, sigLen);
 
        if (status) {
-               sslErrorLog("sslRsaVerify: SecKeyVerifyDigest failed (error %d)\n", status);
+               sslErrorLog("sslRsaVerify: SecKeyVerifyDigest failed (error %d)\n", (int) status);
        }
 
        return status;
        }
 
        return status;
@@ -301,7 +304,7 @@ OSStatus sslRsaEncrypt(
                &giCipherTextLen);
        *actualBytes = giCipherTextLen;
 
                &giCipherTextLen);
        *actualBytes = giCipherTextLen;
 
-       return rsaStatus ? rsaStatusToSSL(rsaStatus) : noErr;
+       return rsaStatus ? rsaStatusToSSL(rsaStatus) : errSecSuccess;
 #else
     size_t ctlen = cipherTextLen;
 
 #else
     size_t ctlen = cipherTextLen;
 
@@ -310,8 +313,8 @@ OSStatus sslRsaEncrypt(
 #if RSA_PUB_KEY_USAGE_HACK
        /* Force key usage to allow encryption with public key */
        #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
 #if RSA_PUB_KEY_USAGE_HACK
        /* Force key usage to allow encryption with public key */
        #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
-       const CSSM_KEY_PTR cssmKey = NULL;
-       if (SecKeyGetCSSMKey(SECKEYREF(pubKey), &cssmKey)==noErr && cssmKey)
+       CSSM_KEY *cssmKey = NULL;
+       if (SecKeyGetCSSMKey(SECKEYREF(pubKey), (const CSSM_KEY **)&cssmKey)==errSecSuccess && cssmKey)
                cssmKey->KeyHeader.KeyUsage |= CSSM_KEYUSE_ENCRYPT;
        #endif
 #endif
                cssmKey->KeyHeader.KeyUsage |= CSSM_KEYUSE_ENCRYPT;
        #endif
 #endif
@@ -320,7 +323,7 @@ OSStatus sslRsaEncrypt(
         plainText, plainTextLen, cipherText, &ctlen);
 
        if (status) {
         plainText, plainTextLen, cipherText, &ctlen);
 
        if (status) {
-               sslErrorLog("sslRsaEncrypt: SecKeyEncrypt failed (error %d)\n", status);
+               sslErrorLog("sslRsaEncrypt: SecKeyEncrypt failed (error %d)\n", (int)status);
        }
 
     /* Since the KeyExchange already allocated modulus size bytes we'll
        }
 
     /* Since the KeyExchange already allocated modulus size bytes we'll
@@ -336,9 +339,9 @@ OSStatus sslRsaEncrypt(
     if (actualBytes)
         *actualBytes = ctlen;
 
     if (actualBytes)
         *actualBytes = ctlen;
 
-    if (status)
-        sslErrorLog("***sslRsaEncrypt: error %d\n", status);
-
+    if (status) {
+        sslErrorLog("***sslRsaEncrypt: error %d\n", (int)status);
+    }
     return status;
 #endif
 }
     return status;
 #endif
 }
@@ -367,7 +370,7 @@ OSStatus sslRsaDecrypt(
                &giPlainTextLen);
        *actualBytes = giPlainTextLen;
 
                &giPlainTextLen);
        *actualBytes = giPlainTextLen;
 
-       return rsaStatus ? rsaStatusToSSL(rsaStatus) : noErr;
+       return rsaStatus ? rsaStatusToSSL(rsaStatus) : errSecSuccess;
 #else
        size_t ptlen = plainTextLen;
 
 #else
        size_t ptlen = plainTextLen;
 
@@ -378,7 +381,7 @@ OSStatus sslRsaDecrypt(
        *actualBytes = ptlen;
 
     if (status) {
        *actualBytes = ptlen;
 
     if (status) {
-        sslErrorLog("sslRsaDecrypt: SecKeyDecrypt failed (error %d)\n", status);
+        sslErrorLog("sslRsaDecrypt: SecKeyDecrypt failed (error %d)\n", (int)status);
        }
 
        return status;
        }
 
        return status;
@@ -435,7 +438,7 @@ OSStatus sslGetMaxSigSize(
     *maxSigSize = SecKeyGetBlockSize(SECKEYREF(privKey));
 #endif
 
     *maxSigSize = SecKeyGetBlockSize(SECKEYREF(privKey));
 #endif
 
-       return noErr;
+       return errSecSuccess;
 }
 
 #if 0
 }
 
 #if 0
@@ -451,7 +454,7 @@ static OSStatus sslGiantToBuffer(
        OSStatus status;
 
        ioLen = serializeGiantBytes(g);
        OSStatus status;
 
        ioLen = serializeGiantBytes(g);
-       status = SSLAllocBuffer(buffer, ioLen, ctx);
+       status = SSLAllocBuffer(buffer, ioLen);
        if (status)
                return status;
        chars = buffer->data;
        if (status)
                return status;
        chars = buffer->data;
@@ -459,7 +462,7 @@ static OSStatus sslGiantToBuffer(
        /* Serialize the giant g into chars. */
        giReturn = serializeGiant(g, chars, &ioLen);
        if(giReturn) {
        /* Serialize the giant g into chars. */
        giReturn = serializeGiant(g, chars, &ioLen);
        if(giReturn) {
-               SSLFreeBuffer(buffer, ctx);
+               SSLFreeBuffer(buffer);
                return giReturnToSSL(giReturn);
        }
 
                return giReturnToSSL(giReturn);
        }
 
@@ -493,7 +496,7 @@ OSStatus sslGetPubKeyBits(
 
        status = sslGiantToBuffer(ctx, &pubKey->rsaKey.e.g, exponent);
        if(status) {
 
        status = sslGiantToBuffer(ctx, &pubKey->rsaKey.e.g, exponent);
        if(status) {
-               SSLFreeBuffer(modulus, ctx);
+               SSLFreeBuffer(modulus);
                return status;
        }
 
                return status;
        }
 
@@ -512,7 +515,7 @@ OSStatus sslGetPubKeyFromBits(
        SSLPubKey           **pubKey)        // mallocd and RETURNED
 {
        if (!pubKey)
        SSLPubKey           **pubKey)        // mallocd and RETURNED
 {
        if (!pubKey)
-               return paramErr;
+               return errSecParam;
 #if 0
        SSLPubKey *key;
        RSAStatus rsaStatus;
 #if 0
        SSLPubKey *key;
        RSAStatus rsaStatus;
@@ -530,7 +533,7 @@ OSStatus sslGetPubKeyFromBits(
        }
 
        *pubKey = key;
        }
 
        *pubKey = key;
-       return noErr;
+       return errSecSuccess;
 #else
        check(pubKey);
        SecRSAPublicKeyParams params = {
 #else
        check(pubKey);
        SecRSAPublicKeyParams params = {
@@ -539,8 +542,8 @@ OSStatus sslGetPubKeyFromBits(
        };
 #if SSL_DEBUG
        sslDebugLog("Creating RSA pub key from modulus=%p len=%lu exponent=%p len=%lu\n",
        };
 #if SSL_DEBUG
        sslDebugLog("Creating RSA pub key from modulus=%p len=%lu exponent=%p len=%lu\n",
-                       (uintptr_t)modulus->data, modulus->length,
-                       (uintptr_t)exponent->data, exponent->length);
+                       modulus->data, modulus->length,
+                       exponent->data, exponent->length);
 #endif
        SecKeyRef key = SecKeyCreateRSAPublicKey(NULL, (const uint8_t *)&params,
                        sizeof(params), kSecKeyEncodingRSAPublicParams);
 #endif
        SecKeyRef key = SecKeyCreateRSAPublicKey(NULL, (const uint8_t *)&params,
                        sizeof(params), kSecKeyEncodingRSAPublicParams);
@@ -549,16 +552,15 @@ OSStatus sslGetPubKeyFromBits(
                return errSSLCrypto;
        }
 #if SSL_DEBUG
                return errSSLCrypto;
        }
 #if SSL_DEBUG
-       size_t blocksize = SecKeyGetBlockSize(key);
-       sslDebugLog("sslGetPubKeyFromBits: RSA pub key block size=%lu\n", blocksize);
+       sslDebugLog("sslGetPubKeyFromBits: RSA pub key block size=%lu\n", SecKeyGetBlockSize(key));
 #endif
        *pubKey = (SSLPubKey*)key;
 #endif
        *pubKey = (SSLPubKey*)key;
-       return noErr;
+       return errSecSuccess;
 #endif
 }
 
 #endif
 }
 
-#pragma mark -
-#pragma mark Public Certificate Functions
+// MARK: -
+// MARK: Public Certificate Functions
 
 #ifdef USE_SSLCERTIFICATE
 
 
 #ifdef USE_SSLCERTIFICATE
 
@@ -617,7 +619,7 @@ OSStatus sslPubKeyFromCert(
        if(drtn)
                return errSSLBadCert;
 
        if(drtn)
                return errSSLBadCert;
 
-#if TARGET_OS_IOS
+#if TARGET_OS_IPHONE
     /* Now we have the public key in pkcs1 format.  Let's make a public key
        object out of it. */
     key = sslMalloc(sizeof(*key));
     /* Now we have the public key in pkcs1 format.  Let's make a public key
        object out of it. */
     key = sslMalloc(sizeof(*key));
@@ -638,7 +640,7 @@ OSStatus sslPubKeyFromCert(
        }
 
        *pubKey = key;
        }
 
        *pubKey = key;
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -656,13 +658,13 @@ OSStatus sslPubKeyFromCert(
        const SSLCertificate    *certChain,
        bool                                    arePeerCerts)
 {
        const SSLCertificate    *certChain,
        bool                                    arePeerCerts)
 {
-       OSStatus ortn = noErr;
+       OSStatus ortn = errSecSuccess;
 
     assert(certChain);
 
     /* No point checking our own certs, our clients can do that. */
     if (!arePeerCerts)
 
     assert(certChain);
 
     /* No point checking our own certs, our clients can do that. */
     if (!arePeerCerts)
-        return noErr;
+        return errSecSuccess;
 
     CertVerifyReturn cvrtn;
     /* @@@ Add real cert checking. */
 
     CertVerifyReturn cvrtn;
     /* @@@ Add real cert checking. */
@@ -693,7 +695,7 @@ sslCreateSecTrust(
        bool                                    arePeerCerts,
     SecTrustRef             *pTrust)   /* RETURNED */
 {
        bool                                    arePeerCerts,
     SecTrustRef             *pTrust)   /* RETURNED */
 {
-       OSStatus status = memFullErr;
+       OSStatus status = errSecAllocate;
        CFStringRef peerDomainName = NULL;
        CFTypeRef policies = NULL;
        SecTrustRef trust = NULL;
        CFStringRef peerDomainName = NULL;
        CFTypeRef policies = NULL;
        SecTrustRef trust = NULL;
@@ -732,7 +734,7 @@ sslCreateSecTrust(
             ctx->trustedCertsOnly), errOut);
     }
 
             ctx->trustedCertsOnly), errOut);
     }
 
-    status = noErr;
+    status = errSecSuccess;
 
 errOut:
        CFReleaseSafe(peerDomainName);
 
 errOut:
        CFReleaseSafe(peerDomainName);
@@ -746,6 +748,7 @@ errOut:
 /* Return the first certificate reference from the supplied array
  * whose data matches the given certificate, or NULL if none match.
  */
 /* Return the first certificate reference from the supplied array
  * whose data matches the given certificate, or NULL if none match.
  */
+static
 SecCertificateRef
 sslGetMatchingCertInArray(
        SecCertificateRef       certRef,
 SecCertificateRef
 sslGetMatchingCertInArray(
        SecCertificateRef       certRef,
@@ -805,7 +808,7 @@ extern OSStatus sslVerifyCertChain(
 
        if (!ctx->enableCertVerify) {
                /* trivial case, this is caller's responsibility */
 
        if (!ctx->enableCertVerify) {
                /* trivial case, this is caller's responsibility */
-               status = noErr;
+               status = errSecSuccess;
                goto errOut;
        }
 
                goto errOut;
        }
 
@@ -816,7 +819,7 @@ extern OSStatus sslVerifyCertChain(
             /* cert chain valid, no special UserTrust assignments */
         case kSecTrustResultProceed:
             /* cert chain valid AND user explicitly trusts this */
             /* cert chain valid, no special UserTrust assignments */
         case kSecTrustResultProceed:
             /* cert chain valid AND user explicitly trusts this */
-            status = noErr;
+            status = errSecSuccess;
             break;
         case kSecTrustResultDeny:
         case kSecTrustResultConfirm:
             break;
         case kSecTrustResultDeny:
         case kSecTrustResultConfirm:
@@ -824,7 +827,7 @@ extern OSStatus sslVerifyCertChain(
         default:
             if(ctx->allowAnyRoot) {
                 sslErrorLog("***Warning: accepting unverified cert chain\n");
         default:
             if(ctx->allowAnyRoot) {
                 sslErrorLog("***Warning: accepting unverified cert chain\n");
-                status = noErr;
+                status = errSecSuccess;
             }
             else {
                                /*
             }
             else {
                                /*
@@ -833,7 +836,7 @@ extern OSStatus sslVerifyCertChain(
                                if(ctx->trustedLeafCerts) {
                                        if (sslGetMatchingCertInArray((SecCertificateRef)CFArrayGetValueAtIndex(certChain, 0),
                                                                ctx->trustedLeafCerts)) {
                                if(ctx->trustedLeafCerts) {
                                        if (sslGetMatchingCertInArray((SecCertificateRef)CFArrayGetValueAtIndex(certChain, 0),
                                                                ctx->trustedLeafCerts)) {
-                                               status = noErr;
+                                               status = errSecSuccess;
                                                goto errOut;
                                        }
                                }
                                                goto errOut;
                                        }
                                }
@@ -869,30 +872,28 @@ extern OSStatus sslCopyPeerPubKey(
        SSLContext                              *ctx,
        SSLPubKey               **pubKey)
 {
        SSLContext                              *ctx,
        SSLPubKey               **pubKey)
 {
-    OSStatus status = noErr;
-
     check(pubKey);
     check(ctx->peerSecTrust);
 
     check(pubKey);
     check(ctx->peerSecTrust);
 
+#if !TARGET_OS_IPHONE
+    /* This is not required on iOS, but still required on osx */
     if (!ctx->enableCertVerify) {
     if (!ctx->enableCertVerify) {
+        OSStatus status;
         SecTrustResultType result;
         SecTrustResultType result;
-        require_noerr(status = SecTrustEvaluate(ctx->peerSecTrust, &result),
-            errOut);
+        verify_noerr_action(status = SecTrustEvaluate(ctx->peerSecTrust, &result),
+            return status);
        }
        }
+#endif
 
     SecKeyRef key = SecTrustCopyPublicKey(ctx->peerSecTrust);
     if (!key) {
                sslErrorLog("sslCopyPeerPubKey: %s, ctx->peerSecTrust=%p\n",
 
     SecKeyRef key = SecTrustCopyPublicKey(ctx->peerSecTrust);
     if (!key) {
                sslErrorLog("sslCopyPeerPubKey: %s, ctx->peerSecTrust=%p\n",
-                       "SecTrustCopyPublicKey failed", (uintptr_t)ctx->peerSecTrust);
+                       "SecTrustCopyPublicKey failed", ctx->peerSecTrust);
                return errSSLBadCert;
        }
     *pubKey = (SSLPubKey*)key;
 
                return errSSLBadCert;
        }
     *pubKey = (SSLPubKey*)key;
 
-errOut:
-       if (status) {
-               sslErrorLog("sslCopyPeerPubKey: error %d\n", status);
-       }
-       return status;
+    return errSecSuccess;
 }
 
 #endif /* !USE_SSLCERTIFICATE */
 }
 
 #endif /* !USE_SSLCERTIFICATE */
@@ -915,84 +916,79 @@ void stPrintCdsaError(const char *op, OSStatus crtn)
  * ctx->selectedCipherSpec to a (supposedly) valid value, and from
  * sslBuildCipherSpecArray(), in server mode (pre-negotiation) only.
  */
  * ctx->selectedCipherSpec to a (supposedly) valid value, and from
  * sslBuildCipherSpecArray(), in server mode (pre-negotiation) only.
  */
-OSStatus sslVerifySelectedCipher(
-       SSLContext *ctx,
-       const SSLCipherSpec *selectedCipherSpec)
+OSStatus sslVerifySelectedCipher(SSLContext *ctx)
 {
 {
-       if(ctx->protocolSide == kSSLClientSide) {
-               return noErr;
-       }
-       #if     SSL_PAC_SERVER_ENABLE
-       if((ctx->masterSecretCallback != NULL) &&
-          (ctx->sessionTicket.data != NULL)) {
-               /* EAP via PAC resumption; we can do it */
-               return noErr;
-       }
-       #endif  /* SSL_PAC_SERVER_ENABLE */
-
-       CFIndex requireAlg;
-    if(selectedCipherSpec == NULL) {
-               sslErrorLog("sslVerifySelectedCipher: no selected cipher\n");
-        return errSSLInternal;
+    if(ctx->protocolSide == kSSLClientSide) {
+        return errSecSuccess;
     }
     }
-    switch (selectedCipherSpec->keyExchangeMethod) {
-               case SSL_RSA:
+#if SSL_PAC_SERVER_ENABLE
+    if((ctx->masterSecretCallback != NULL) &&
+       (ctx->sessionTicket.data != NULL)) {
+            /* EAP via PAC resumption; we can do it */
+       return errSecSuccess;
+    }
+#endif /* SSL_PAC_SERVER_ENABLE */
+
+    CFIndex requireAlg;
+    switch (ctx->selectedCipherSpecParams.keyExchangeMethod) {
+        case SSL_RSA:
         case SSL_RSA_EXPORT:
         case SSL_RSA_EXPORT:
-               case SSL_DH_RSA:
-               case SSL_DH_RSA_EXPORT:
-               case SSL_DHE_RSA:
-               case SSL_DHE_RSA_EXPORT:
-                       requireAlg = kSecRSAAlgorithmID;
-                       break;
-               case SSL_DHE_DSS:
-               case SSL_DHE_DSS_EXPORT:
-               case SSL_DH_DSS:
-               case SSL_DH_DSS_EXPORT:
-                       requireAlg = kSecDSAAlgorithmID;
-                       break;
-               case SSL_DH_anon:
-               case SSL_DH_anon_EXPORT:
-                       requireAlg = kSecNullAlgorithmID; /* no signing key */
-                       break;
-               /*
-                * When SSL_ECDSA_SERVER is true and we support ECDSA on the server side,
-                * we'll need to add some logic here...
-                */
-               #if SSL_ECDSA_SERVER
+       case SSL_DH_RSA:
+       case SSL_DH_RSA_EXPORT:
+       case SSL_DHE_RSA:
+       case SSL_DHE_RSA_EXPORT:
+            requireAlg = kSecRSAAlgorithmID;
+            break;
+       case SSL_DHE_DSS:
+       case SSL_DHE_DSS_EXPORT:
+       case SSL_DH_DSS:
+       case SSL_DH_DSS_EXPORT:
+            requireAlg = kSecDSAAlgorithmID;
+            break;
+       case SSL_DH_anon:
+       case SSL_DH_anon_EXPORT:
+        case TLS_PSK:
+            requireAlg = kSecNullAlgorithmID; /* no signing key */
+            break;
+        /*
+         * When SSL_ECDSA_SERVER is true and we support ECDSA on the server side,
+         * we'll need to add some logic here...
+         */
+#if SSL_ECDSA_SERVER
         case SSL_ECDHE_ECDSA:
         case SSL_ECDHE_RSA:
         case SSL_ECDH_ECDSA:
         case SSL_ECDH_RSA:
         case SSL_ECDH_anon:
         case SSL_ECDHE_ECDSA:
         case SSL_ECDHE_RSA:
         case SSL_ECDH_ECDSA:
         case SSL_ECDH_RSA:
         case SSL_ECDH_anon:
-                       requireAlg = kSecECDSAAlgorithmID;
+            requireAlg = kSecECDSAAlgorithmID;
             break;
             break;
-               #endif
+#endif
 
 
-               default:
-                       /* needs update per cipherSpecs.c */
-                       assert(0);
-                       sslErrorLog("sslVerifySelectedCipher: unknown key exchange method\n");
-                       return errSSLInternal;
+       default:
+            /* needs update per cipherSpecs.c */
+            assert(0);
+            sslErrorLog("sslVerifySelectedCipher: unknown key exchange method\n");
+            return errSSLInternal;
     }
 
     }
 
-       if(requireAlg == kSecNullAlgorithmID) {
-               return noErr;
-       }
+    if(requireAlg == kSecNullAlgorithmID) {
+       return errSecSuccess;
+    }
 
 
-       /* private signing key required */
-       if(ctx->signingPrivKeyRef == NULL) {
-               sslErrorLog("sslVerifySelectedCipher: no signing key\n");
-               return errSSLBadConfiguration;
-       }
+    /* private signing key required */
+    if(ctx->signingPrivKeyRef == NULL) {
+       sslErrorLog("sslVerifySelectedCipher: no signing key\n");
+       return errSSLBadConfiguration;
+    }
 
     /* Check the alg of our signing key. */
     CFIndex keyAlg = sslPrivKeyGetAlgorithmID(ctx->signingPrivKeyRef);
     if (requireAlg != keyAlg) {
 
     /* Check the alg of our signing key. */
     CFIndex keyAlg = sslPrivKeyGetAlgorithmID(ctx->signingPrivKeyRef);
     if (requireAlg != keyAlg) {
-                       sslErrorLog("sslVerifySelectedCipher: signing key alg mismatch\n");
-                       return errSSLBadConfiguration;
+       sslErrorLog("sslVerifySelectedCipher: signing key alg mismatch\n");
+       return errSSLBadConfiguration;
     }
 
     }
 
-       return noErr;
+    return errSecSuccess;
 }
 
 #if APPLE_DH
 }
 
 #if APPLE_DH
@@ -1032,7 +1028,7 @@ OSStatus sslDecodeDhParams(
        SSLBuffer               *prime,                 /* Output - wire format */
        SSLBuffer               *generator)     /* Output - wire format */
 {
        SSLBuffer               *prime,                 /* Output - wire format */
        SSLBuffer               *generator)     /* Output - wire format */
 {
-    OSStatus ortn = noErr;
+    OSStatus ortn = errSecSuccess;
     DERReturn drtn;
        DERItem paramItem = {(DERByte *)blob->data, blob->length};
        DER_DHParams decodedParams;
     DERReturn drtn;
        DERItem paramItem = {(DERByte *)blob->data, blob->length};
        DER_DHParams decodedParams;
@@ -1057,7 +1053,7 @@ OSStatus sslEncodeDhParams(SSLBuffer        *blob,                        /* data mallocd and RETURNE
                            const SSLBuffer     *prime,                 /* Wire format */
                            const SSLBuffer     *generator)     /* Wire format */
 {
                            const SSLBuffer     *prime,                 /* Wire format */
                            const SSLBuffer     *generator)     /* Wire format */
 {
-    OSStatus ortn = noErr;
+    OSStatus ortn = errSecSuccess;
     DER_DHParams derParams =
     {
         .p = {
     DER_DHParams derParams =
     {
         .p = {
@@ -1106,16 +1102,16 @@ OSStatus sslDhCreateKey(SSLContext *ctx)
         ctx->dhParamsEncoded.length, &ctx->secDHContext))
             return errSSLCrypto;
 
         ctx->dhParamsEncoded.length, &ctx->secDHContext))
             return errSSLCrypto;
 
-    return noErr;
+    return errSecSuccess;
 }
 
 OSStatus sslDhGenerateKeyPair(SSLContext *ctx)
 {
 }
 
 OSStatus sslDhGenerateKeyPair(SSLContext *ctx)
 {
-    OSStatus ortn = noErr;
-
-    require_noerr(ortn = SSLAllocBuffer(&ctx->dhExchangePublic,
-        SecDHGetMaxKeyLength(ctx->secDHContext), ctx), out);
-    require_noerr(ortn = SecDHGenerateKeypair(ctx->secDHContext,
+    OSStatus ortn = errSecSuccess;
+    
+    require_noerr(ortn = SSLAllocBuffer(&ctx->dhExchangePublic, 
+        SecDHGetMaxKeyLength(ctx->secDHContext)), out);
+    require_noerr(ortn = SecDHGenerateKeypair(ctx->secDHContext, 
         ctx->dhExchangePublic.data, &ctx->dhExchangePublic.length), out);
 
 out:
         ctx->dhExchangePublic.data, &ctx->dhExchangePublic.length), out);
 
 out:
@@ -1125,7 +1121,7 @@ out:
 
 OSStatus sslDhKeyExchange(SSLContext *ctx)
 {
 
 OSStatus sslDhKeyExchange(SSLContext *ctx)
 {
-    OSStatus ortn = noErr;
+    OSStatus ortn = errSecSuccess;
 
        if (ctx == NULL ||
         ctx->secDHContext == NULL ||
 
        if (ctx == NULL ||
         ctx->secDHContext == NULL ||
@@ -1135,15 +1131,15 @@ OSStatus sslDhKeyExchange(SSLContext *ctx)
                return errSSLProtocol;
        }
 
                return errSSLProtocol;
        }
 
-    require_noerr(ortn = SSLAllocBuffer(&ctx->preMasterSecret,
-        SecDHGetMaxKeyLength(ctx->secDHContext), ctx), out);
-    require_noerr(ortn = SecDHComputeKey(ctx->secDHContext,
-        ctx->dhPeerPublic.data, ctx->dhPeerPublic.length,
+    require_noerr(ortn = SSLAllocBuffer(&ctx->preMasterSecret, 
+        SecDHGetMaxKeyLength(ctx->secDHContext)), out);
+    require_noerr(ortn = SecDHComputeKey(ctx->secDHContext, 
+        ctx->dhPeerPublic.data, ctx->dhPeerPublic.length, 
         ctx->preMasterSecret.data, &ctx->preMasterSecret.length), out);
 
        return ortn;
 out:
         ctx->preMasterSecret.data, &ctx->preMasterSecret.length), out);
 
        return ortn;
 out:
-       sslErrorLog("sslDhKeyExchange: failed to compute key (error %d)\n", ortn);
+       sslErrorLog("sslDhKeyExchange: failed to compute key (error %d)\n", (int)ortn);
        return ortn;
 }
 
        return ortn;
 }
 
@@ -1163,7 +1159,7 @@ OSStatus sslEcdsaPeerCurve(
         sslErrorLog("sslEcdsaPeerCurve: no named curve for public key\n");
         return errSSLProtocol;
     }
         sslErrorLog("sslEcdsaPeerCurve: no named curve for public key\n");
         return errSSLProtocol;
     }
-    return noErr;
+    return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -1176,7 +1172,7 @@ OSStatus sslEcdhGenerateKeyPair(
        SSLContext *ctx,
        SSL_ECDSA_NamedCurve namedCurve)
 {
        SSLContext *ctx,
        SSL_ECDSA_NamedCurve namedCurve)
 {
-       OSStatus ortn = noErr;
+       OSStatus ortn = errSecSuccess;
 
     ccec_const_cp_t cp;
        switch (namedCurve) {
 
     ccec_const_cp_t cp;
        switch (namedCurve) {
@@ -1198,13 +1194,13 @@ OSStatus sslEcdhGenerateKeyPair(
 
     ccec_generate_key(cp, CCRNGSTATE, ctx->ecdhContext);
     size_t pub_size = ccec_export_pub_size(ctx->ecdhContext);
 
     ccec_generate_key(cp, CCRNGSTATE, ctx->ecdhContext);
     size_t pub_size = ccec_export_pub_size(ctx->ecdhContext);
-    SSLFreeBuffer(&ctx->ecdhExchangePublic, ctx);
+    SSLFreeBuffer(&ctx->ecdhExchangePublic);
     require_noerr(ortn = SSLAllocBuffer(&ctx->ecdhExchangePublic,
     require_noerr(ortn = SSLAllocBuffer(&ctx->ecdhExchangePublic,
-                                        pub_size, ctx), errOut);
+                                        pub_size), errOut);
     ccec_export_pub(ctx->ecdhContext, ctx->ecdhExchangePublic.data);
 
        sslDebugLog("sslEcdhGenerateKeyPair: pub key size=%ld, data=%p\n",
     ccec_export_pub(ctx->ecdhContext, ctx->ecdhExchangePublic.data);
 
        sslDebugLog("sslEcdhGenerateKeyPair: pub key size=%ld, data=%p\n",
-               pub_size, (uintptr_t)ctx->ecdhExchangePublic.data);
+               pub_size, ctx->ecdhExchangePublic.data);
 
 errOut:
        return ortn;
 
 errOut:
        return ortn;
@@ -1222,12 +1218,12 @@ OSStatus sslEcdhKeyExchange(
        SSLContext              *ctx,
        SSLBuffer               *exchanged)
 {
        SSLContext              *ctx,
        SSLBuffer               *exchanged)
 {
-       OSStatus ortn = noErr;
+       OSStatus ortn = errSecSuccess;
     CFDataRef pubKeyData = NULL;
     const unsigned char *pubKeyBits;
     unsigned long pubKeyLen;
 
     CFDataRef pubKeyData = NULL;
     const unsigned char *pubKeyBits;
     unsigned long pubKeyLen;
 
-       switch(ctx->selectedCipherSpec.keyExchangeMethod) {
+       switch(ctx->selectedCipherSpecParams.keyExchangeMethod) {
                case SSL_ECDHE_ECDSA:
                case SSL_ECDHE_RSA:
                        /* public key passed in as CSSM_DATA *Param */
                case SSL_ECDHE_ECDSA:
                case SSL_ECDHE_RSA:
                        /* public key passed in as CSSM_DATA *Param */
@@ -1261,7 +1257,7 @@ OSStatus sslEcdhKeyExchange(
                default:
                        /* shouldn't be here */
                        sslErrorLog("sslEcdhKeyExchange: unknown keyExchangeMethod (%d)\n",
                default:
                        /* shouldn't be here */
                        sslErrorLog("sslEcdhKeyExchange: unknown keyExchangeMethod (%d)\n",
-                               ctx->selectedCipherSpec.keyExchangeMethod);
+                               ctx->selectedCipherSpecParams.keyExchangeMethod);
                        assert(0);
                        ortn = errSSLInternal;
                        goto errOut;
                        assert(0);
                        ortn = errSSLInternal;
                        goto errOut;
@@ -1271,11 +1267,11 @@ OSStatus sslEcdhKeyExchange(
     ccec_pub_ctx_decl(ccn_sizeof(521), pubKey);
     ccec_import_pub(cp, pubKeyLen, pubKeyBits, pubKey);
     size_t len = 1 + 2 * ccec_ccn_size(cp);
     ccec_pub_ctx_decl(ccn_sizeof(521), pubKey);
     ccec_import_pub(cp, pubKeyLen, pubKeyBits, pubKey);
     size_t len = 1 + 2 * ccec_ccn_size(cp);
-    require_noerr(ortn = SSLAllocBuffer(exchanged, len, NULL), errOut);
+    require_noerr(ortn = SSLAllocBuffer(exchanged, len), errOut);
     require_noerr(ccec_compute_key(ctx->ecdhContext, pubKey,  &exchanged->length, exchanged->data), errOut);
 
        sslDebugLog("sslEcdhKeyExchange: exchanged key length=%ld, data=%p\n",
     require_noerr(ccec_compute_key(ctx->ecdhContext, pubKey,  &exchanged->length, exchanged->data), errOut);
 
        sslDebugLog("sslEcdhKeyExchange: exchanged key length=%ld, data=%p\n",
-               exchanged->length, (uintptr_t)exchanged->data);
+               exchanged->length, exchanged->data);
 
 errOut:
     CFReleaseSafe(pubKeyData);
 
 errOut:
     CFReleaseSafe(pubKeyData);
index 9fa6876096e206d1cb2ccc8b77a1359a24a20dfa..fc4beaf128034e4bd36ad258529194580559cf7b 100644 (file)
@@ -188,8 +188,7 @@ OSStatus sslGetPubKeyFromBits(
        SSLPubKey           **pubKey);       // mallocd and RETURNED
 
 OSStatus sslVerifySelectedCipher(
        SSLPubKey           **pubKey);       // mallocd and RETURNED
 
 OSStatus sslVerifySelectedCipher(
-       SSLContext              *ctx,
-       const SSLCipherSpec *selectedCipherSpec);
+       SSLContext              *ctx);
 
 #if APPLE_DH
 int sslDhGenerateParams(SSLContext *ctx, uint32_t g, size_t prime_size,
 
 #if APPLE_DH
 int sslDhGenerateParams(SSLContext *ctx, uint32_t g, size_t prime_size,
index 75629a1af194cde2a12621ef9f831aa0399d4dc4..4923eec268fad5cf1b40a6b38a91522c64fe7ea5 100644 (file)
 #ifndef        _SSL_DEBUG_H_
 #define _SSL_DEBUG_H_
 
 #ifndef        _SSL_DEBUG_H_
 #define _SSL_DEBUG_H_
 
-#include "sslContext.h"
-#include <security_utilities/debugging.h>
-#include <assert.h>
+#ifdef KERNEL
+/* TODO: support secdebug in the kernel */
+#define secdebug(x...)
+#else /* KERNEL */
+#include <utilities/debugging.h>
+#endif
 
 #ifndef        NDEBUG
 
 #ifndef        NDEBUG
-#include <stdio.h>
+#include <AssertMacros.h>
 #endif
 
 #endif
 
-/* If SSL_USE_SYSLOG is defined and not 0, use syslog() for debug
- * logging in addition to invoking the secdebug macro (which, as of
- * Snow Leopard, emits a static dtrace probe instead of an actual
- * log message.)
- */
-#ifndef SSL_USE_SYSLOG
-#define SSL_USE_SYSLOG 0
-#endif
 
 
-#if SSL_USE_SYSLOG
-#include <syslog.h>
-#define ssl_secdebug(scope, format...) \
-{ \
-       syslog(LOG_NOTICE, format); \
-       secdebug(scope, format); \
-}
-#else
-#define ssl_secdebug(scope, format...) \
-       secdebug(scope, format)
-#endif
+#define ssl_secdebug secdebug
 
 #ifndef NDEBUG
 
 
 #ifndef NDEBUG
 
@@ -113,9 +98,6 @@ NDEBUG */
 
 #ifdef NDEBUG
 
 
 #ifdef NDEBUG
 
-#define SSLChangeHdskState(ctx, newState) { ctx->state=newState; }
-#define SSLLogHdskMsg(msg, sent)
-
 /* all errors logged to stdout for DEBUG config only */
 #define sslErrorLog(args...)
 #define sslDebugLog(args...)
 /* all errors logged to stdout for DEBUG config only */
 #define sslErrorLog(args...)
 #define sslDebugLog(args...)
@@ -123,11 +105,6 @@ NDEBUG */
 
 #else
 
 
 #else
 
-#include "sslAlertMessage.h"
-
-extern void SSLLogHdskMsg(SSLHandshakeType msg, char sent);
-extern char *hdskStateToStr(SSLHandshakeState state);
-extern void SSLChangeHdskState(SSLContext *ctx, SSLHandshakeState newState);
 extern void SSLDump(const unsigned char *data, unsigned long len);
 
 /* extra debug logging of non-error conditions, if SSL_DEBUG is defined */
 extern void SSLDump(const unsigned char *data, unsigned long len);
 
 /* extra debug logging of non-error conditions, if SSL_DEBUG is defined */
@@ -148,7 +125,7 @@ extern void SSLDump(const unsigned char *data, unsigned long len);
 #ifdef NDEBUG
 #define ASSERT(s)
 #else
 #ifdef NDEBUG
 #define ASSERT(s)
 #else
-#define ASSERT(s)      assert(s)
+#define ASSERT(s)      check(s)
 #endif
 
 #endif /* _SSL_DEBUG_H_ */
 #endif
 
 #endif /* _SSL_DEBUG_H_ */
index 5377efddeb7d159fb2e5a4a84dfd8f3c0fb98d57..9531f5b98fee38addd4b3fe7487db3727fd64044 100644 (file)
  * sslDigests.c - Interface between SSL and SHA, MD5 digest implementations
  */
 
  * sslDigests.c - Interface between SSL and SHA, MD5 digest implementations
  */
 
-#include "sslContext.h"
-#include "cryptType.h"
 #include "sslMemory.h"
 #include "sslDigests.h"
 #include "sslMemory.h"
 #include "sslDigests.h"
-#include "sslDebug.h"
-
-#include <CommonCrypto/CommonDigest.h>
-#include <string.h>
+#include <Security/SecBase.h>
 
 #define DIGEST_PRINT           0
 #if            DIGEST_PRINT
 
 #define DIGEST_PRINT           0
 #if            DIGEST_PRINT
 #define dgprintf(s)
 #endif
 
 #define dgprintf(s)
 #endif
 
-const UInt8 SSLMACPad1[MAX_MAC_PADDING] =
-{
-       0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-       0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-       0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-       0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-       0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-       0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36
-};
-
-const UInt8 SSLMACPad2[MAX_MAC_PADDING] =
-{
-       0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,
-       0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,
-       0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,
-       0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,
-       0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,
-       0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C
-};
 
 /*
  * Public general hash functions
 
 /*
  * Public general hash functions
@@ -71,13 +47,12 @@ const UInt8 SSLMACPad2[MAX_MAC_PADDING] =
  */
 OSStatus
 CloneHashState(
  */
 OSStatus
 CloneHashState(
-       const HashReference *ref,
-       const SSLBuffer *state,
-       SSLBuffer *newState,
-       SSLContext *ctx)
-{
+       const HashReference *ref, 
+       const SSLBuffer *state, 
+       SSLBuffer *newState)
+{   
        OSStatus      err;
        OSStatus      err;
-    if ((err = SSLAllocBuffer(newState, ref->contextSize, ctx)) != 0)
+    if ((err = SSLAllocBuffer(newState, ref->contextSize)))
         return err;
        return ref->clone(state, newState);
 }
         return err;
        return ref->clone(state, newState);
 }
@@ -86,326 +61,28 @@ CloneHashState(
  * Wrapper for HashReference.init.
  */
 OSStatus
  * Wrapper for HashReference.init.
  */
 OSStatus
-ReadyHash(const HashReference *ref, SSLBuffer *state, SSLContext *ctx)
-{
+ReadyHash(const HashReference *ref, SSLBuffer *state)
+{   
        OSStatus      err;
        OSStatus      err;
-    if ((err = SSLAllocBuffer(state, ref->contextSize, ctx)) != 0)
+    if ((err = SSLAllocBuffer(state, ref->contextSize)))
         return err;
         return err;
-    return ref->init(state, ctx);
+    return ref->init(state);
 }
 
 /*
  * Wrapper for HashReference.close. Tolerates NULL state and frees it if it's
  * there.
  */
 }
 
 /*
  * Wrapper for HashReference.close. Tolerates NULL state and frees it if it's
  * there.
  */
-OSStatus CloseHash(const HashReference *ref, SSLBuffer *state, SSLContext *ctx)
+OSStatus CloseHash(const HashReference *ref, SSLBuffer *state)
 {
        OSStatus serr;
 
        if(state->data == NULL) {
 {
        OSStatus serr;
 
        if(state->data == NULL) {
-               return noErr;
+               return errSecSuccess;
        }
        }
-       serr = ref->close(state, ctx);
+       serr = ref->close(state);
        if(serr) {
                return serr;
        }
        if(serr) {
                return serr;
        }
-       return SSLFreeBuffer(state, ctx);
-}
-
-
-/*** NULL ***/
-static OSStatus HashNullInit(SSLBuffer *digestCtx, SSLContext *sslCtx) {
-       return noErr;
-}
-static OSStatus HashNullUpdate(SSLBuffer *digestCtx, const SSLBuffer *data) {
-       return noErr;
-}
-static OSStatus HashNullFinal(SSLBuffer *digestCtx, SSLBuffer *digest) {
-       return noErr;
-}
-static OSStatus HashNullClose(SSLBuffer *digestCtx, SSLContext *sslCtx) {
-       return noErr;
-}
-static OSStatus HashNullClone(const SSLBuffer *src, SSLBuffer *dest) {
-       return noErr;
-}
-
-/*** MD5 ***/
-static OSStatus HashMD5Init(SSLBuffer *digestCtx, SSLContext *sslCtx)
-{
-       assert(digestCtx->length >= sizeof(CC_MD5_CTX));
-       CC_MD5_CTX *ctx = (CC_MD5_CTX *)digestCtx->data;
-       CC_MD5_Init(ctx);
-       dgprintf(("###HashMD5Init  ctx %p\n", ctx));
-    return noErr;
-}
-
-static OSStatus HashMD5Update(SSLBuffer *digestCtx, const SSLBuffer *data)
-{
-    /* 64 bits cast: safe, SSL records are always smaller than 2^32 bytes */
-       assert(digestCtx->length >= sizeof(CC_MD5_CTX));
-       CC_MD5_CTX *ctx = (CC_MD5_CTX *)digestCtx->data;
-       CC_MD5_Update(ctx, data->data, (CC_LONG)data->length);
-    return noErr;
-}
-
-static OSStatus HashMD5Final(SSLBuffer *digestCtx, SSLBuffer *digest)
-{
-       assert(digestCtx->length >= sizeof(CC_MD5_CTX));
-       CC_MD5_CTX *ctx = (CC_MD5_CTX *)digestCtx->data;
-       dgprintf(("###HashMD5Final  ctx %p\n", ctx));
-       assert(digest->length >= CC_MD5_DIGEST_LENGTH);
-       //if (digest->length < CC_MD5_DIGEST_LENGTH)
-       //      return errSSLCrypto;
-       CC_MD5_Final(digest->data, ctx);
-       digest->length = CC_MD5_DIGEST_LENGTH;
-    return noErr;
-}
-
-static OSStatus HashMD5Close(SSLBuffer *digestCtx, SSLContext *sslCtx)
-{
-       assert(digestCtx->length >= sizeof(CC_MD5_CTX));
-    return noErr;
-}
-
-static OSStatus HashMD5Clone(const SSLBuffer *src, SSLBuffer *dst)
-{
-       CC_MD5_CTX *srcCtx;
-       CC_MD5_CTX *dstCtx;
-
-       assert(src->length >= sizeof(CC_MD5_CTX));
-       assert(dst->length >= sizeof(CC_MD5_CTX));
-
-       srcCtx = (CC_MD5_CTX *)src->data;
-       dstCtx = (CC_MD5_CTX *)dst->data;
-       dgprintf(("###HashMD5Clone  srcCtx %p  dstCtx %p\n", srcCtx, dstCtx));
-
-       memcpy(dstCtx, srcCtx, sizeof(CC_MD5_CTX));
-       return noErr;
-}
-
-/*** SHA1 ***/
-static OSStatus HashSHA1Init(SSLBuffer *digestCtx, SSLContext *sslCtx)
-{
-       assert(digestCtx->length >= sizeof(CC_SHA1_CTX));
-       CC_SHA1_CTX *ctx = (CC_SHA1_CTX *)digestCtx->data;
-       CC_SHA1_Init(ctx);
-       dgprintf(("###HashSHA1Init  ctx %p\n", ctx));
-    return noErr;
-}
-
-static OSStatus HashSHA1Update(SSLBuffer *digestCtx, const SSLBuffer *data)
-{
-    /* 64 bits cast: safe, SSL records are always smaller than 2^32 bytes */
-       assert(digestCtx->length >= sizeof(CC_SHA1_CTX));
-       CC_SHA1_CTX *ctx = (CC_SHA1_CTX *)digestCtx->data;
-       CC_SHA1_Update(ctx, data->data, (CC_LONG)data->length);
-    return noErr;
-}
-
-static OSStatus HashSHA1Final(SSLBuffer *digestCtx, SSLBuffer *digest)
-{
-       assert(digestCtx->length >= sizeof(CC_SHA1_CTX));
-       CC_SHA1_CTX *ctx = (CC_SHA1_CTX *)digestCtx->data;
-       dgprintf(("###HashSHA1Final  ctx %p\n", ctx));
-       assert(digest->length >= CC_SHA1_DIGEST_LENGTH);
-       //if (digest->length < CC_SHA1_DIGEST_LENGTH)
-       //      return errSSLCrypto;
-       CC_SHA1_Final(digest->data, ctx);
-       digest->length = CC_SHA1_DIGEST_LENGTH;
-    return noErr;
-}
-
-static OSStatus HashSHA1Close(SSLBuffer *digestCtx, SSLContext *sslCtx)
-{
-       assert(digestCtx->length >= sizeof(CC_SHA1_CTX));
-    return noErr;
-}
-
-static OSStatus HashSHA1Clone(const SSLBuffer *src, SSLBuffer *dst)
-{
-       CC_SHA1_CTX *srcCtx;
-       CC_SHA1_CTX *dstCtx;
-
-       assert(src->length >= sizeof(CC_SHA1_CTX));
-       assert(dst->length >= sizeof(CC_SHA1_CTX));
-
-       srcCtx = (CC_SHA1_CTX *)src->data;
-       dstCtx = (CC_SHA1_CTX *)dst->data;
-       dgprintf(("###HashSHA1Clone  srcCtx %p  dstCtx %p\n", srcCtx, dstCtx));
-
-       memcpy(dstCtx, srcCtx, sizeof(CC_SHA1_CTX));
-       return noErr;
-}
-
-/*** SHA256 ***/
-static OSStatus HashSHA256Init(SSLBuffer *digestCtx, SSLContext *sslCtx)
-{
-       assert(digestCtx->length >= sizeof(CC_SHA256_CTX));
-       CC_SHA256_CTX *ctx = (CC_SHA256_CTX *)digestCtx->data;
-       CC_SHA256_Init(ctx);
-       dgprintf(("###HashSHA256Init  ctx %p\n", ctx));
-    return noErr;
-}
-
-static OSStatus HashSHA256Update(SSLBuffer *digestCtx, const SSLBuffer *data)
-{
-    /* 64 bits cast: safe, SSL records are always smaller than 2^32 bytes */
-    assert(digestCtx->length >= sizeof(CC_SHA256_CTX));
-       CC_SHA256_CTX *ctx = (CC_SHA256_CTX *)digestCtx->data;
-       CC_SHA256_Update(ctx, data->data, (CC_LONG)data->length);
-    return noErr;
-}
-
-static OSStatus HashSHA256Final(SSLBuffer *digestCtx, SSLBuffer *digest)
-{
-       assert(digestCtx->length >= sizeof(CC_SHA256_CTX));
-       CC_SHA256_CTX *ctx = (CC_SHA256_CTX *)digestCtx->data;
-       dgprintf(("###HashSHA256Final  ctx %p\n", ctx));
-       assert(digest->length >= CC_SHA256_DIGEST_LENGTH);
-       //if (digest->length < CC_SHA256_DIGEST_LENGTH)
-       //      return errSSLCrypto;
-       CC_SHA256_Final(digest->data, ctx);
-       digest->length = CC_SHA256_DIGEST_LENGTH;
-    return noErr;
-}
-
-static OSStatus HashSHA256Close(SSLBuffer *digestCtx, SSLContext *sslCtx)
-{
-       assert(digestCtx->length >= sizeof(CC_SHA256_CTX));
-    return noErr;
-}
-
-static OSStatus HashSHA256Clone(const SSLBuffer *src, SSLBuffer *dst)
-{
-       CC_SHA256_CTX *srcCtx;
-       CC_SHA256_CTX *dstCtx;
-
-       assert(src->length >= sizeof(CC_SHA256_CTX));
-       assert(dst->length >= sizeof(CC_SHA256_CTX));
-
-       srcCtx = (CC_SHA256_CTX *)src->data;
-       dstCtx = (CC_SHA256_CTX *)dst->data;
-       dgprintf(("###HashSHA256Clone  srcCtx %p  dstCtx %p\n", srcCtx, dstCtx));
-
-       memcpy(dstCtx, srcCtx, sizeof(CC_SHA256_CTX));
-       return noErr;
-}
-
-/*** SHA384 ***/
-static OSStatus HashSHA384Init(SSLBuffer *digestCtx, SSLContext *sslCtx)
-{
-       assert(digestCtx->length >= sizeof(CC_SHA512_CTX));
-       CC_SHA512_CTX *ctx = (CC_SHA512_CTX *)digestCtx->data;
-       CC_SHA384_Init(ctx);
-       dgprintf(("###HashSHA384Init  ctx %p\n", ctx));
-    return noErr;
-}
-
-static OSStatus HashSHA384Update(SSLBuffer *digestCtx, const SSLBuffer *data)
-{
-    /* 64 bits cast: safe, SSL records are always smaller than 2^32 bytes */
-    assert(digestCtx->length >= sizeof(CC_SHA512_CTX));
-       CC_SHA512_CTX *ctx = (CC_SHA512_CTX *)digestCtx->data;
-       CC_SHA384_Update(ctx, data->data, (CC_LONG)data->length);
-    return noErr;
-}
-
-static OSStatus HashSHA384Final(SSLBuffer *digestCtx, SSLBuffer *digest)
-{
-       assert(digestCtx->length >= sizeof(CC_SHA512_CTX));
-       CC_SHA512_CTX *ctx = (CC_SHA512_CTX *)digestCtx->data;
-       dgprintf(("###HashSHA384Final  ctx %p\n", ctx));
-       assert(digest->length >= CC_SHA384_DIGEST_LENGTH);
-       //if (digest->length < CC_SHA384_DIGEST_LENGTH)
-       //      return errSSLCrypto;
-       CC_SHA384_Final(digest->data, ctx);
-       digest->length = CC_SHA384_DIGEST_LENGTH;
-    return noErr;
-}
-
-static OSStatus HashSHA384Close(SSLBuffer *digestCtx, SSLContext *sslCtx)
-{
-       assert(digestCtx->length >= sizeof(CC_SHA512_CTX));
-    return noErr;
+       return SSLFreeBuffer(state);
 }
 }
-
-static OSStatus HashSHA384Clone(const SSLBuffer *src, SSLBuffer *dst)
-{
-       CC_SHA512_CTX *srcCtx;
-       CC_SHA512_CTX *dstCtx;
-
-       assert(src->length >= sizeof(CC_SHA512_CTX));
-       assert(dst->length >= sizeof(CC_SHA512_CTX));
-
-       srcCtx = (CC_SHA512_CTX *)src->data;
-       dstCtx = (CC_SHA512_CTX *)dst->data;
-       dgprintf(("###HashSHA384Clone  srcCtx %p  dstCtx %p\n", srcCtx, dstCtx));
-
-       memcpy(dstCtx, srcCtx, sizeof(CC_SHA512_CTX));
-       return noErr;
-}
-
-/*
- * These are the handles by which the bulk of digesting work
- * is done.
- */
-const HashReference SSLHashNull =
-       {
-               0,
-               0,
-               0,
-               HashNullInit,
-               HashNullUpdate,
-               HashNullFinal,
-               HashNullClose,
-               HashNullClone
-       };
-
-const HashReference SSLHashMD5 =
-       {
-               sizeof(CC_MD5_CTX),
-               CC_MD5_DIGEST_LENGTH,
-               48,
-               HashMD5Init,
-               HashMD5Update,
-               HashMD5Final,
-               HashMD5Close,
-               HashMD5Clone
-       };
-
-const HashReference SSLHashSHA1 =
-       {
-               sizeof(CC_SHA1_CTX),
-               CC_SHA1_DIGEST_LENGTH,
-               40,
-               HashSHA1Init,
-               HashSHA1Update,
-               HashSHA1Final,
-               HashSHA1Close,
-               HashSHA1Clone
-       };
-
-const HashReference SSLHashSHA256 =
-    {
-        sizeof(CC_SHA256_CTX),
-        CC_SHA256_DIGEST_LENGTH,
-        CC_SHA256_BLOCK_BYTES,
-        HashSHA256Init,
-        HashSHA256Update,
-        HashSHA256Final,
-        HashSHA256Close,
-        HashSHA256Clone
-    };
-
-const HashReference SSLHashSHA384 =
-    {
-        sizeof(CC_SHA512_CTX),
-        CC_SHA384_DIGEST_LENGTH,
-        CC_SHA384_BLOCK_BYTES,
-        HashSHA384Init,
-        HashSHA384Update,
-        HashSHA384Final,
-        HashSHA384Close,
-        HashSHA384Clone
-    };
index e3c7a1edcf0c15690debca574b314e6ca833ace0..e2994951f9f08e2c30a12799a0995bbb900a8d85 100644 (file)
 #ifndef        _SSL_DIGESTS_H_
 #define _SSL_DIGESTS_H_        1
 
 #ifndef        _SSL_DIGESTS_H_
 #define _SSL_DIGESTS_H_        1
 
-#include "cryptType.h"
+#include <MacTypes.h>
+#include "sslMemory.h"
+#include "tls_digest.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-/*
- * These numbers show up all over the place...might as well hard code 'em once.
- */
-#define SSL_MD5_DIGEST_LEN      16
-#define SSL_SHA1_DIGEST_LEN     20
-#define SSL_SHA256_DIGEST_LEN  32
-#define SSL_SHA384_DIGEST_LEN  48
-#define SSL_MAX_DIGEST_LEN      48 /* >= SSL_MD5_DIGEST_LEN + SSL_SHA1_DIGEST_LEN */
-
-extern const UInt8 SSLMACPad1[], SSLMACPad2[];
-
-extern const HashReference SSLHashNull;
-extern const HashReference SSLHashMD5;
-extern const HashReference SSLHashSHA1;
-extern const HashReference SSLHashSHA256;
-extern const HashReference SSLHashSHA384;
-
 extern OSStatus CloneHashState(
        const HashReference *ref,
        const SSLBuffer *state,
 extern OSStatus CloneHashState(
        const HashReference *ref,
        const SSLBuffer *state,
-       SSLBuffer *newState,
-       SSLContext *ctx);
+       SSLBuffer *newState);
 extern OSStatus ReadyHash(
 extern OSStatus ReadyHash(
-       const HashReference *ref,
-       SSLBuffer *state,
-       SSLContext *ctx);
+       const HashReference *ref, 
+       SSLBuffer *state);
 extern OSStatus CloseHash(
 extern OSStatus CloseHash(
-       const HashReference *ref,
-       SSLBuffer *state,
-       SSLContext *ctx);
+       const HashReference *ref, 
+       SSLBuffer *state);
 
 #ifdef __cplusplus
 }
 
 #ifdef __cplusplus
 }
index 9844c6f39f6d44444900211b5a5870ed37e0d013..6914908e182191144711d34c7568debfd51d5439 100644 (file)
 #include "sslUtils.h"
 #include "sslDebug.h"
 #include "sslCrypto.h"
 #include "sslUtils.h"
 #include "sslDebug.h"
 #include "sslCrypto.h"
-
+#include "sslRand.h"
 #include "sslDigests.h"
 #include "sslDigests.h"
+#include "sslCipherSpecs.h"
 #include "cipherSpecs.h"
 
 #include "cipherSpecs.h"
 
+#include <utilities/SecIOFormat.h>
+
+#include <AssertMacros.h>
 #include <string.h>
 #include <assert.h>
 #include <inttypes.h>
 #include <string.h>
 #include <assert.h>
 #include <inttypes.h>
 #define PRIstatus "ld"
 #endif
 
 #define PRIstatus "ld"
 #endif
 
+
+uint8_t *
+SSLEncodeHandshakeHeader(SSLContext *ctx, SSLRecord *rec, SSLHandshakeType type, size_t msglen)
+{
+    uint8_t *charPtr;
+
+    charPtr = rec->contents.data;
+    *charPtr++ = type;
+    charPtr = SSLEncodeSize(charPtr, msglen, 3);
+
+    if(rec->protocolVersion == DTLS_Version_1_0) {
+        charPtr = SSLEncodeInt(charPtr, ctx->hdskMessageSeq, 2);
+        /* fragmentation -- we encode header as if unfragmented,
+         actual fragmentation happens at lower layer. */
+        charPtr = SSLEncodeInt(charPtr, 0, 3);
+        charPtr = SSLEncodeSize(charPtr, msglen, 3);
+    }
+
+    return charPtr;
+}
+
 static OSStatus SSLProcessHandshakeMessage(SSLHandshakeMsg message, SSLContext *ctx);
 
 static OSStatus
 SSLUpdateHandshakeMacs(const SSLBuffer *messageData, SSLContext *ctx)
 {
 static OSStatus SSLProcessHandshakeMessage(SSLHandshakeMsg message, SSLContext *ctx);
 
 static OSStatus
 SSLUpdateHandshakeMacs(const SSLBuffer *messageData, SSLContext *ctx)
 {
-    OSStatus err = errSecParam;
+    OSStatus err = errSSLInternal;
     bool do_md5 = false;
     bool do_sha1 = false;
     bool do_sha256 = false;
     bool do_md5 = false;
     bool do_sha1 = false;
     bool do_sha256 = false;
@@ -97,7 +122,7 @@ SSLUpdateHandshakeMacs(const SSLBuffer *messageData, SSLContext *ctx)
         (err = SSLHashSHA384.update(&ctx->sha512State, messageData)) != 0)
         goto done;
 
         (err = SSLHashSHA384.update(&ctx->sha512State, messageData)) != 0)
         goto done;
 
-    sslLogNegotiateDebug("%s protocol: %02X max: %02X cipher: %02X%s%s",
+    sslLogNegotiateDebug("%s protocol: %02X max: %02X cipher: %02X%s%s%s%s",
                          ctx->protocolSide == kSSLClientSide ? "client" : "server",
                          ctx->negProtocolVersion,
                          ctx->maxProtocolVersion,
                          ctx->protocolSide == kSSLClientSide ? "client" : "server",
                          ctx->negProtocolVersion,
                          ctx->maxProtocolVersion,
@@ -123,8 +148,7 @@ SSLProcessHandshakeRecord(SSLRecord rec, SSLContext *ctx)
     {
                size_t origLen = ctx->fragmentedMessageCache.length;
                if ((err = SSLReallocBuffer(&ctx->fragmentedMessageCache,
     {
                size_t origLen = ctx->fragmentedMessageCache.length;
                if ((err = SSLReallocBuffer(&ctx->fragmentedMessageCache,
-                    ctx->fragmentedMessageCache.length + rec.contents.length,
-                    ctx)) != 0)
+                    ctx->fragmentedMessageCache.length + rec.contents.length)) != 0)
         {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
             return err;
         }
         {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
             return err;
         }
@@ -181,7 +205,7 @@ SSLProcessHandshakeRecord(SSLRecord rec, SSLContext *ctx)
     if (remaining > 0)      /* Fragmented handshake message */
     {   /* If there isn't a cache, allocate one */
         if (ctx->fragmentedMessageCache.data == 0)
     if (remaining > 0)      /* Fragmented handshake message */
     {   /* If there isn't a cache, allocate one */
         if (ctx->fragmentedMessageCache.data == 0)
-        {   if ((err = SSLAllocBuffer(&ctx->fragmentedMessageCache, remaining, ctx)) != 0)
+        {   if ((err = SSLAllocBuffer(&ctx->fragmentedMessageCache, remaining)))
             {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
                 return err;
             }
             {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
                 return err;
             }
@@ -192,13 +216,13 @@ SSLProcessHandshakeRecord(SSLRecord rec, SSLContext *ctx)
         }
     }
     else if (ctx->fragmentedMessageCache.data != 0)
         }
     }
     else if (ctx->fragmentedMessageCache.data != 0)
-    {   if ((err = SSLFreeBuffer(&ctx->fragmentedMessageCache, ctx)) != 0)
+    {   if ((err = SSLFreeBuffer(&ctx->fragmentedMessageCache)))
         {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
             return err;
         }
     }
 
         {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
             return err;
         }
     }
 
-    return noErr;
+    return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -228,6 +252,7 @@ DTLSProcessHandshakeRecord(SSLRecord rec, SSLContext *ctx)
             /* flush it - record is too small */
             sslErrorLog("DTLSProcessHandshakeRecord: remaining too small (%lu out of %lu)\n", remaining, rec.contents.length);
             assert(0); // keep this assert until we find a test case that triggers it
             /* flush it - record is too small */
             sslErrorLog("DTLSProcessHandshakeRecord: remaining too small (%lu out of %lu)\n", remaining, rec.contents.length);
             assert(0); // keep this assert until we find a test case that triggers it
+            err = errSSLProtocol;
             goto flushit;
         }
 
             goto flushit;
         }
 
@@ -241,8 +266,8 @@ DTLSProcessHandshakeRecord(SSLRecord rec, SSLContext *ctx)
         remaining -= head;
 
         SSLLogHdskMsg(msgtype, 0);
         remaining -= head;
 
         SSLLogHdskMsg(msgtype, 0);
-        sslHdskMsgDebug("DTLS Hdsk Record: type=%lu, len=%lu, seq=%lu (%lu), f_ofs=%lu, f_len=%lu, remaining=%lu",
-                             msgtype, msglen, msgseq, ctx->hdskMessageSeqNext, fragofs, fraglen, remaining);
+        sslHdskMsgDebug("DTLS Hdsk Record: type=%u, len=%u, seq=%u (%u), f_ofs=%u, f_len=%u, remaining=%u",
+                             msgtype, (int)msglen, (int)msgseq, (int)ctx->hdskMessageSeqNext, (int)fragofs, (int)fraglen, (int)remaining);
 
         if(
            ((fraglen+fragofs) > msglen)
 
         if(
            ((fraglen+fragofs) > msglen)
@@ -257,7 +282,7 @@ DTLSProcessHandshakeRecord(SSLRecord rec, SSLContext *ctx)
             // assert(0); // keep this assert until we find a test case that triggers it
             // This is a recoverable error, we just drop this fragment.
             // TODO: this should probably trigger a retransmit
             // assert(0); // keep this assert until we find a test case that triggers it
             // This is a recoverable error, we just drop this fragment.
             // TODO: this should probably trigger a retransmit
-            err = noErr;
+            err = errSecSuccess;
             goto flushit;
         }
 
             goto flushit;
         }
 
@@ -266,7 +291,7 @@ DTLSProcessHandshakeRecord(SSLRecord rec, SSLContext *ctx)
             sslHdskMsgDebug("Allocating hdsk buf for msg type %d", msgtype);
             assert(ctx->hdskMessageCurrent.contents.data==NULL);
             assert(ctx->hdskMessageCurrent.contents.length==0);
             sslHdskMsgDebug("Allocating hdsk buf for msg type %d", msgtype);
             assert(ctx->hdskMessageCurrent.contents.data==NULL);
             assert(ctx->hdskMessageCurrent.contents.length==0);
-            if((err=SSLAllocBuffer(&(ctx->hdskMessageCurrent.contents), msglen, ctx))!=0) {
+            if((err=SSLAllocBuffer(&(ctx->hdskMessageCurrent.contents), msglen))) {
                 SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
                 return err;
             }
                 SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
                 return err;
             }
@@ -314,19 +339,19 @@ DTLSProcessHandshakeRecord(SSLRecord rec, SSLContext *ctx)
                     goto flushit;
                 }
 
                     goto flushit;
                 }
 
-                sslHdskMsgDebug("Hashing %d bytes of msg seq %ld\n", messageData->length, msgseq);
+                sslHdskMsgDebug("Hashing %d bytes of msg seq %d\n", (int)messageData->length, (int)msgseq);
             }
 
             sslHdskMsgDebug("processed message of type %d", msgtype);
 
             if ((err = SSLAdvanceHandshake(msgtype, ctx)) != 0)
             {
             }
 
             sslHdskMsgDebug("processed message of type %d", msgtype);
 
             if ((err = SSLAdvanceHandshake(msgtype, ctx)) != 0)
             {
-                sslErrorLog("AdvanceHandshake error: %"PRIstatus"\n", err);
+                sslErrorLog("AdvanceHandshake error: %" PRIdOSStatus "\n", err);
                 goto flushit;
             }
 
             /* Free the buffer for current message, and reset offset */
                 goto flushit;
             }
 
             /* Free the buffer for current message, and reset offset */
-            SSLFreeBuffer(&(ctx->hdskMessageCurrent.contents), ctx);
+            SSLFreeBuffer(&(ctx->hdskMessageCurrent.contents));
             ctx->hdskMessageCurrentOfs=0;
 
             /* If we successfully processed a message, we wait for the next one */
             ctx->hdskMessageCurrentOfs=0;
 
             /* If we successfully processed a message, we wait for the next one */
@@ -337,13 +362,13 @@ DTLSProcessHandshakeRecord(SSLRecord rec, SSLContext *ctx)
         sslHdskMsgDebug("remaining = %ld", remaining);
     }
 
         sslHdskMsgDebug("remaining = %ld", remaining);
     }
 
-    return noErr;
+    return errSecSuccess;
 
 flushit:
     sslErrorLog("DTLSProcessHandshakeRecord: flusing record (err=%"PRIstatus")\n", err);
 
     /* This will flush the current handshake message */
 
 flushit:
     sslErrorLog("DTLSProcessHandshakeRecord: flusing record (err=%"PRIstatus")\n", err);
 
     /* This will flush the current handshake message */
-    SSLFreeBuffer(&(ctx->hdskMessageCurrent.contents), ctx);
+    SSLFreeBuffer(&(ctx->hdskMessageCurrent.contents));
     ctx->hdskMessageCurrentOfs=0;
 
     return err;
     ctx->hdskMessageCurrentOfs=0;
 
     return err;
@@ -361,8 +386,10 @@ DTLSRetransmit(SSLContext *ctx)
 
     /* go back to previous cipher if retransmitting a flight including changecipherspec */
     if(ctx->messageQueueContainsChangeCipherSpec) {
 
     /* go back to previous cipher if retransmitting a flight including changecipherspec */
     if(ctx->messageQueueContainsChangeCipherSpec) {
-        ctx->writePending = ctx->writeCipher;
-        ctx->writeCipher = ctx->prevCipher;
+        OSStatus err;
+        err = ctx->recFuncs->rollbackWriteCipher(ctx->recCtx);
+        if(err)
+            return err;
     }
 
     /* set timeout deadline */
     }
 
     /* set timeout deadline */
@@ -377,7 +404,7 @@ static OSStatus
 SSLProcessHandshakeMessage(SSLHandshakeMsg message, SSLContext *ctx)
 {   OSStatus      err;
 
 SSLProcessHandshakeMessage(SSLHandshakeMsg message, SSLContext *ctx)
 {   OSStatus      err;
 
-    err = noErr;
+    err = errSecSuccess;
     SSLLogHdskMsg(message.type, 0);
     switch (message.type)
     {   case SSL_HdskHelloRequest:
     SSLLogHdskMsg(message.type, 0);
     switch (message.type)
     {   case SSL_HdskHelloRequest:
@@ -392,8 +419,7 @@ SSLProcessHandshakeMessage(SSLHandshakeMsg message, SSLContext *ctx)
             err = SSLProcessClientHello(message.contents, ctx);
             break;
         case SSL_HdskServerHello:
             err = SSLProcessClientHello(message.contents, ctx);
             break;
         case SSL_HdskServerHello:
-            if (ctx->state != SSL_HdskStateServerHello &&
-                ctx->state != SSL_HdskStateServerHelloUnknownVersion)
+            if (ctx->state != SSL_HdskStateServerHello)
                 goto wrongMessage;
             err = SSLProcessServerHello(message.contents, ctx);
             break;
                 goto wrongMessage;
             err = SSLProcessServerHello(message.contents, ctx);
             break;
@@ -512,7 +538,7 @@ SSLResumeServerSide(
 
        SSLChangeHdskState(ctx, SSL_HdskStateChangeCipherSpec);
 
 
        SSLChangeHdskState(ctx, SSL_HdskStateChangeCipherSpec);
 
-       return noErr;
+       return errSecSuccess;
 
 }
 
 
 }
 
@@ -539,9 +565,8 @@ SSLAdvanceHandshake(SSLHandshakeType processed, SSLContext *ctx)
                        ctx->certReceived = 0;
                        ctx->x509Requested = 0;
                        ctx->clientCertState = kSSLClientCertNone;
                        ctx->certReceived = 0;
                        ctx->x509Requested = 0;
                        ctx->clientCertState = kSSLClientCertNone;
-                       ctx->readCipher.ready = 0;
-                       ctx->writeCipher.ready = 0;
-                       ctx->wroteAppData = 0;
+                       ctx->readCipher_ready = 0;
+                       ctx->writeCipher_ready = 0;
             if ((err = SSLPrepareAndQueueMessage(SSLEncodeClientHello, ctx)) != 0)
                 return err;
             SSLChangeHdskState(ctx, SSL_HdskStateServerHello);
             if ((err = SSLPrepareAndQueueMessage(SSLEncodeClientHello, ctx)) != 0)
                 return err;
             SSLChangeHdskState(ctx, SSL_HdskStateServerHello);
@@ -610,7 +635,7 @@ SSLAdvanceHandshake(SSLHandshakeType processed, SSLContext *ctx)
                             return err;
                         }
                                                ctx->sessionMatch = 1;
                             return err;
                         }
                                                ctx->sessionMatch = 1;
-                                               SSLFreeBuffer(&sessionIdentifier, ctx);
+                                               SSLFreeBuffer(&sessionIdentifier);
 
                                                /* queue up remaining messages to finish handshake */
                                                if((err = SSLResumeServerSide(ctx)) != 0)
 
                                                /* queue up remaining messages to finish handshake */
                                                if((err = SSLResumeServerSide(ctx)) != 0)
@@ -621,13 +646,13 @@ SSLAdvanceHandshake(SSLHandshakeType processed, SSLContext *ctx)
                                                sslLogResumSessDebug(
                                                        "===FAILED TO RESUME SSL3 server-side session");
                                        }
                                                sslLogResumSessDebug(
                                                        "===FAILED TO RESUME SSL3 server-side session");
                                        }
-                    if ((err = SSLFreeBuffer(&sessionIdentifier, ctx)) != 0 ||
+                    if ((err = SSLFreeBuffer(&sessionIdentifier)) != 0 ||
                         (err = SSLDeleteSessionData(ctx)) != 0)
                     {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
                         return err;
                     }
                 }
                         (err = SSLDeleteSessionData(ctx)) != 0)
                     {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
                         return err;
                     }
                 }
-                if ((err = SSLFreeBuffer(&ctx->sessionID, ctx)) != 0)
+                if ((err = SSLFreeBuffer(&ctx->sessionID)) != 0)
                 {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
                     return err;
                 }
                 {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
                     return err;
                 }
@@ -640,10 +665,10 @@ SSLAdvanceHandshake(SSLHandshakeType processed, SSLContext *ctx)
             if (ctx->peerID.data != 0)
             {   /* Ignore errors; just treat as uncached session */
                 assert(ctx->sessionID.data == 0);
             if (ctx->peerID.data != 0)
             {   /* Ignore errors; just treat as uncached session */
                 assert(ctx->sessionID.data == 0);
-                err = SSLAllocBuffer(&ctx->sessionID, SSL_SESSION_ID_LEN, ctx);
+                err = SSLAllocBuffer(&ctx->sessionID, SSL_SESSION_ID_LEN);
                 if (err == 0)
                 if (err == 0)
-                {
-                       if((err = sslRand(ctx, &ctx->sessionID)) != 0)
+                {   
+                    if((err = sslRand(&ctx->sessionID)) != 0)
                     {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
                         return err;
                     }
                     {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
                         return err;
                     }
@@ -652,11 +677,11 @@ SSLAdvanceHandshake(SSLHandshakeType processed, SSLContext *ctx)
 
             if ((err = SSLPrepareAndQueueMessage(SSLEncodeServerHello, ctx)) != 0)
                 return err;
 
             if ((err = SSLPrepareAndQueueMessage(SSLEncodeServerHello, ctx)) != 0)
                 return err;
-            switch (ctx->selectedCipherSpec.keyExchangeMethod)
+            switch (ctx->selectedCipherSpecParams.keyExchangeMethod)
             {   case SSL_NULL_auth:
                #if             APPLE_DH
                 case SSL_DH_anon:
             {   case SSL_NULL_auth:
                #if             APPLE_DH
                 case SSL_DH_anon:
-                case SSL_DH_anon_EXPORT:
+                case SSL_ECDH_anon:
                        if(ctx->clientAuth == kAlwaysAuthenticate) {
                                /* app requires this; abort */
                                SSLFatalSessionAlert(SSL_AlertHandshakeFail, ctx);
                        if(ctx->clientAuth == kAlwaysAuthenticate) {
                                /* app requires this; abort */
                                SSLFatalSessionAlert(SSL_AlertHandshakeFail, ctx);
@@ -666,7 +691,19 @@ SSLAdvanceHandshake(SSLHandshakeType processed, SSLContext *ctx)
                                        /* DH server side needs work */
                     break;
                 #endif /* APPLE_DH */
                                        /* DH server side needs work */
                     break;
                 #endif /* APPLE_DH */
-                default:        /* everything else */
+                case TLS_PSK:
+                    /* skip the cert */
+                    break;
+
+                case SSL_RSA:
+                case SSL_DH_DSS:
+                case SSL_DH_RSA:
+                case SSL_DHE_DSS:
+                case SSL_DHE_RSA:
+                case SSL_ECDH_ECDSA:
+                case SSL_ECDHE_ECDSA:
+                case SSL_ECDH_RSA:
+                case SSL_ECDHE_RSA:
                                        if(ctx->localCert == NULL) {
                                                /* no cert but configured for, and negotiated, a
                                                 * ciphersuite which requires one */
                                        if(ctx->localCert == NULL) {
                                                /* no cert but configured for, and negotiated, a
                                                 * ciphersuite which requires one */
@@ -677,6 +714,10 @@ SSLAdvanceHandshake(SSLHandshakeType processed, SSLContext *ctx)
                                                        ctx)) != 0)
                         return err;
                     break;
                                                        ctx)) != 0)
                         return err;
                     break;
+
+                default:        /* everything else */
+                    sslErrorLog("SSLAdvanceHandshake: Unsupported KEM!\n");
+                    return errSSLInternal;
             }
                        /*
                         * At this point we decide whether to send a server key exchange
             }
                        /*
                         * At this point we decide whether to send a server key exchange
@@ -687,25 +728,18 @@ SSLAdvanceHandshake(SSLHandshakeType processed, SSLContext *ctx)
                         */
                        {
                                bool doServerKeyExch = false;
                         */
                        {
                                bool doServerKeyExch = false;
-                               switch(ctx->selectedCipherSpec.keyExchangeMethod) {
-                                       case SSL_RSA_EXPORT:
-                                       #if !SSL_SERVER_KEYEXCH_HACK
-                                       /* the "proper" way - app decides. */
+                               switch(ctx->selectedCipherSpecParams.keyExchangeMethod) {
                                        case SSL_RSA:
                                        case SSL_RSA:
-                                       #endif
                                                if(ctx->encryptPrivKeyRef != NULL) {
                                                        doServerKeyExch = true;
                                                }
                                                break;
                                        case SSL_DH_anon:
                                                if(ctx->encryptPrivKeyRef != NULL) {
                                                        doServerKeyExch = true;
                                                }
                                                break;
                                        case SSL_DH_anon:
-                                       case SSL_DH_anon_EXPORT:
                                        case SSL_DHE_RSA:
                                        case SSL_DHE_RSA:
-                                       case SSL_DHE_RSA_EXPORT:
                                        case SSL_DHE_DSS:
                                        case SSL_DHE_DSS:
-                                       case SSL_DHE_DSS_EXPORT:
                                                doServerKeyExch = true;
                                                break;
                                                doServerKeyExch = true;
                                                break;
-                                       default:
+                                       default: /* In all other cases, we don't send a ServerkeyExchange message */
                                                break;
                                }
                                if(doServerKeyExch) {
                                                break;
                                }
                                if(doServerKeyExch) {
@@ -755,7 +789,7 @@ SSLAdvanceHandshake(SSLHandshakeType processed, SSLContext *ctx)
                     if ((err = SSLInstallSessionFromData(ctx->resumableSession,
                                                        ctx)) != 0 ||
                         (err = SSLInitPendingCiphers(ctx)) != 0 ||
                     if ((err = SSLInstallSessionFromData(ctx->resumableSession,
                                                        ctx)) != 0 ||
                         (err = SSLInitPendingCiphers(ctx)) != 0 ||
-                        (err = SSLFreeBuffer(&sessionIdentifier, ctx)) != 0)
+                        (err = SSLFreeBuffer(&sessionIdentifier)) != 0)
                     {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
                         return err;
                     }
                     {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
                         return err;
                     }
@@ -767,29 +801,24 @@ SSLAdvanceHandshake(SSLHandshakeType processed, SSLContext *ctx)
                                        sslLogResumSessDebug("===FAILED TO RESUME SSL3 client-side "
                                                        "session");
                                }
                                        sslLogResumSessDebug("===FAILED TO RESUME SSL3 client-side "
                                                        "session");
                                }
-                if ((err = SSLFreeBuffer(&sessionIdentifier, ctx)) != 0)
+                if ((err = SSLFreeBuffer(&sessionIdentifier)) != 0)
                 {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
                     return err;
                 }
             }
                 {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
                     return err;
                 }
             }
-            switch (ctx->selectedCipherSpec.keyExchangeMethod)
-            {
+            switch (ctx->selectedCipherSpecParams.keyExchangeMethod)
+            {   
                /* these require a key exchange message */
                case SSL_NULL_auth:
                 case SSL_DH_anon:
                /* these require a key exchange message */
                case SSL_NULL_auth:
                 case SSL_DH_anon:
-                case SSL_DH_anon_EXPORT:
                     SSLChangeHdskState(ctx, SSL_HdskStateKeyExchange);
                     break;
                 case SSL_RSA:
                 case SSL_DH_DSS:
                     SSLChangeHdskState(ctx, SSL_HdskStateKeyExchange);
                     break;
                 case SSL_RSA:
                 case SSL_DH_DSS:
-                case SSL_DH_DSS_EXPORT:
                 case SSL_DH_RSA:
                 case SSL_DH_RSA:
-                case SSL_DH_RSA_EXPORT:
                 case SSL_RSA_EXPORT:
                 case SSL_DHE_DSS:
                 case SSL_RSA_EXPORT:
                 case SSL_DHE_DSS:
-                case SSL_DHE_DSS_EXPORT:
                 case SSL_DHE_RSA:
                 case SSL_DHE_RSA:
-                case SSL_DHE_RSA_EXPORT:
                 case SSL_Fortezza:
                                case SSL_ECDH_ECDSA:
                                case SSL_ECDHE_ECDSA:
                 case SSL_Fortezza:
                                case SSL_ECDH_ECDSA:
                                case SSL_ECDHE_ECDSA:
@@ -797,6 +826,9 @@ SSLAdvanceHandshake(SSLHandshakeType processed, SSLContext *ctx)
                                case SSL_ECDHE_RSA:
                     SSLChangeHdskState(ctx, SSL_HdskStateCert);
                     break;
                                case SSL_ECDHE_RSA:
                     SSLChangeHdskState(ctx, SSL_HdskStateCert);
                     break;
+                case TLS_PSK:
+                    SSLChangeHdskState(ctx, SSL_HdskStateHelloDone);
+                    break;
                 default:
                     assert("Unknown key exchange method");
                     break;
                 default:
                     assert("Unknown key exchange method");
                     break;
@@ -804,7 +836,7 @@ SSLAdvanceHandshake(SSLHandshakeType processed, SSLContext *ctx)
             break;
         case SSL_HdskCert:
             if (ctx->state == SSL_HdskStateCert)
             break;
         case SSL_HdskCert:
             if (ctx->state == SSL_HdskStateCert)
-                switch (ctx->selectedCipherSpec.keyExchangeMethod)
+                switch (ctx->selectedCipherSpecParams.keyExchangeMethod)
                 {   case SSL_RSA:
                        /*
                         * I really think the two RSA cases should be
                 {   case SSL_RSA:
                        /*
                         * I really think the two RSA cases should be
@@ -813,19 +845,14 @@ SSLAdvanceHandshake(SSLHandshakeType processed, SSLContext *ctx)
                         * Note this isn't the same as SSL_SERVER_KEYEXCH_HACK;
                         * we're a client here.
                         */
                         * Note this isn't the same as SSL_SERVER_KEYEXCH_HACK;
                         * we're a client here.
                         */
-                       case SSL_RSA_EXPORT:
                     case SSL_DH_DSS:
                     case SSL_DH_DSS:
-                    case SSL_DH_DSS_EXPORT:
                     case SSL_DH_RSA:
                     case SSL_DH_RSA:
-                    case SSL_DH_RSA_EXPORT:
                                        case SSL_ECDH_ECDSA:
                                        case SSL_ECDH_RSA:
                         SSLChangeHdskState(ctx, SSL_HdskStateHelloDone);
                         break;
                     case SSL_DHE_DSS:
                                        case SSL_ECDH_ECDSA:
                                        case SSL_ECDH_RSA:
                         SSLChangeHdskState(ctx, SSL_HdskStateHelloDone);
                         break;
                     case SSL_DHE_DSS:
-                    case SSL_DHE_DSS_EXPORT:
                     case SSL_DHE_RSA:
                     case SSL_DHE_RSA:
-                    case SSL_DHE_RSA_EXPORT:
                     case SSL_Fortezza:
                                        case SSL_ECDHE_ECDSA:
                                        case SSL_ECDHE_RSA:
                     case SSL_Fortezza:
                                        case SSL_ECDHE_ECDSA:
                                        case SSL_ECDHE_RSA:
@@ -914,7 +941,7 @@ SSLAdvanceHandshake(SSLHandshakeType processed, SSLContext *ctx)
                 return err;
             }
                        memset(ctx->preMasterSecret.data, 0, ctx->preMasterSecret.length);
                 return err;
             }
                        memset(ctx->preMasterSecret.data, 0, ctx->preMasterSecret.length);
-            if ((err = SSLFreeBuffer(&ctx->preMasterSecret, ctx)) != 0) {
+            if ((err = SSLFreeBuffer(&ctx->preMasterSecret))) {
                 return err;
                        }
             if (ctx->certSent) {
                 return err;
                        }
             if (ctx->certSent) {
@@ -950,7 +977,7 @@ SSLAdvanceHandshake(SSLHandshakeType processed, SSLContext *ctx)
                 return err;
             }
                        memset(ctx->preMasterSecret.data, 0, ctx->preMasterSecret.length);
                 return err;
             }
                        memset(ctx->preMasterSecret.data, 0, ctx->preMasterSecret.length);
-            if ((err = SSLFreeBuffer(&ctx->preMasterSecret, ctx)) != 0)
+            if ((err = SSLFreeBuffer(&ctx->preMasterSecret)))
                 return err;
             if (ctx->certReceived) {
                 SSLChangeHdskState(ctx, SSL_HdskStateClientCertVerify);
                 return err;
             if (ctx->certReceived) {
                 SSLChangeHdskState(ctx, SSL_HdskStateClientCertVerify);
@@ -961,11 +988,12 @@ SSLAdvanceHandshake(SSLHandshakeType processed, SSLContext *ctx)
             break;
         case SSL_HdskFinished:
             /* Handshake is over; enable data transfer on read channel */
             break;
         case SSL_HdskFinished:
             /* 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;
+            ctx->readCipher_ready = 1;
+            /* If writePending is set, we haven't yet sent a finished message; 
                         * send it */
                         * send it */
-            if (ctx->writePending.ready != 0)
-            {   if ((err = SSLPrepareAndQueueMessage(SSLEncodeChangeCipherSpec,
+            /* Note: If using session resumption, the client will hit this, otherwise the server will */
+            if (ctx->writePending_ready != 0)
+            {   if ((err = SSLPrepareAndQueueMessage(SSLEncodeChangeCipherSpec, 
                                                ctx)) != 0)
                     return err;
                 if ((err = SSLPrepareAndQueueMessage(SSLEncodeFinishedMessage,
                                                ctx)) != 0)
                     return err;
                 if ((err = SSLPrepareAndQueueMessage(SSLEncodeFinishedMessage,
@@ -1037,9 +1065,9 @@ SSLPrepareAndQueueMessage(EncodeMessageFunc msgFunc, SSLContext *ctx)
         queue->next = out;
     }
 
         queue->next = out;
     }
 
-    return noErr;
+    return errSecSuccess;
 fail:
 fail:
-    SSLFreeBuffer(&rec.contents, ctx);
+    SSLFreeBuffer(&rec.contents);
     return err;
 }
 
     return err;
 }
 
@@ -1048,62 +1076,57 @@ OSStatus SSLSendMessage(SSLRecord rec, SSLContext *ctx)
 {
     OSStatus err;
 
 {
     OSStatus err;
 
-    assert(ctx->sslTslCalls != NULL);
 
 
-    if ((err = ctx->sslTslCalls->writeRecord(rec, ctx)) != 0)
+    if ((err = SSLWriteRecord(rec, ctx)) != 0)
         return err;
     if(rec.contentType == SSL_RecordTypeChangeCipher) {
         /* Install new cipher spec on write side */
         return err;
     if(rec.contentType == SSL_RecordTypeChangeCipher) {
         /* Install new cipher spec on write side */
-        if ((err = SSLDisposeCipherSuite(&ctx->writeCipher, ctx)) != 0)
+        /* Can't send data until Finished is sent */
+        ctx->writeCipher_ready = 0;
+       ctx->wroteAppData = 0;
+
+        if ((err = ctx->recFuncs->advanceWriteCipher(ctx->recCtx)) != 0)
         {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
             return err;
         }
         {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
             return err;
         }
-        ctx->prevCipher = ctx->writeCipher;
-        ctx->writeCipher = ctx->writePending;
-        /* Can't send data until Finished is sent */
-        ctx->writeCipher.ready = 0;
-               ctx->wroteAppData = 0;
 
 
-        /* Zero out old data */
-        memset(&ctx->writePending, 0, sizeof(CipherContext));
-        ctx->writePending.encrypting = 1;
+        /* pending cipher is invalid now - this is currently used to figure out if we need
+           to send out the last flight */
+        ctx->writePending_ready = 0;
 
         /* TODO: that should only happen after Finished message is sent. <rdar://problem/9682471> */
 
         /* TODO: that should only happen after Finished message is sent. <rdar://problem/9682471> */
-        ctx->writeCipher.ready = 1;
+        ctx->writeCipher_ready = 1;
     }
 
     }
 
-    return noErr;
+    return errSecSuccess;
 }
 
 static
 OSStatus DTLSSendMessage(SSLRecord rec, SSLContext *ctx)
 {
 }
 
 static
 OSStatus DTLSSendMessage(SSLRecord rec, SSLContext *ctx)
 {
-    OSStatus err=noErr;
-
-    assert(ctx->sslTslCalls != NULL);
+    OSStatus err=errSecSuccess;
 
     if(rec.contentType != SSL_RecordTypeHandshake) {
 
     if(rec.contentType != SSL_RecordTypeHandshake) {
-        sslHdskMsgDebug("Not fragmenting message type=%d len=%d\n", rec.contentType, rec.contents.length);
-        if ((err = ctx->sslTslCalls->writeRecord(rec, ctx)) != 0)
+        sslHdskMsgDebug("Not fragmenting message type=%d len=%d\n", (int)rec.contentType, (int)rec.contents.length);
+        if ((err = SSLWriteRecord(rec, ctx)) != 0)
             return err;
         if(rec.contentType == SSL_RecordTypeChangeCipher) {
             return err;
         if(rec.contentType == SSL_RecordTypeChangeCipher) {
+                       /* Can't send data until Finished is sent */
+            ctx->writeCipher_ready = 0;
+            ctx->wroteAppData = 0;
+
             /* Install new cipher spec on write side */
             /* Install new cipher spec on write side */
-            if ((err = SSLDisposeCipherSuite(&ctx->writeCipher, ctx)) != 0)
+            if ((err = ctx->recFuncs->advanceWriteCipher(ctx->recCtx)) != 0)
             {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
                 return err;
             }
             {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
                 return err;
             }
-            ctx->prevCipher = ctx->writeCipher;
-            ctx->writeCipher = ctx->writePending;
-                       /* Can't send data until Finished is sent */
-            ctx->writeCipher.ready = 0;
-                       ctx->wroteAppData = 0;
 
 
-                       /* Zero out old data */
-            memset(&ctx->writePending, 0, sizeof(CipherContext));
-                       ctx->writePending.encrypting = 1;
+            /* pending cipher is invalid now - this is currently used to figure out if we need
+             to send out the last flight */
+            ctx->writePending_ready = 0;
 
             /* TODO: that should only happen after Finished message is sent. See <rdar://problem/9682471> */
 
             /* TODO: that should only happen after Finished message is sent. See <rdar://problem/9682471> */
-            ctx->writeCipher.ready = 1;
+            ctx->writeCipher_ready = 1;
 
         }
     } else {
 
         }
     } else {
@@ -1117,7 +1140,7 @@ OSStatus DTLSSendMessage(SSLRecord rec, SSLContext *ctx)
         (void) seq; // Suppress warnings
         size_t ofs = 0;
 
         (void) seq; // Suppress warnings
         size_t ofs = 0;
 
-        sslHdskMsgDebug("Fragmenting msg seq %ld (rl=%d, ml=%d)", seq, rec.contents.length,
+        sslHdskMsgDebug("Fragmenting msg seq %d (rl=%d, ml=%d)", (int)seq, (int)rec.contents.length,
                         SSLDecodeInt(rec.contents.data+1, 3));
 
 
                         SSLDecodeInt(rec.contents.data+1, 3));
 
 
@@ -1126,7 +1149,7 @@ OSStatus DTLSSendMessage(SSLRecord rec, SSLContext *ctx)
 
         fragrec.contentType = rec.contentType;
         fragrec.protocolVersion = rec.protocolVersion;
 
         fragrec.contentType = rec.contentType;
         fragrec.protocolVersion = rec.protocolVersion;
-        if((err=SSLAllocBuffer(&fragrec.contents, fraglen + msghead, ctx))!=0)
+        if((err=SSLAllocBuffer(&fragrec.contents, fraglen + msghead)))
             return err;
 
         /* copy the constant part of the header */
             return err;
 
         /* copy the constant part of the header */
@@ -1134,20 +1157,20 @@ OSStatus DTLSSendMessage(SSLRecord rec, SSLContext *ctx)
 
         while(len>fraglen) {
 
 
         while(len>fraglen) {
 
-            sslHdskMsgDebug("Fragmenting msg seq %ld (o=%d,l=%d)", seq, ofs, fraglen);
+            sslHdskMsgDebug("Fragmenting msg seq %d (o=%d,l=%d)", (int)seq, (int)ofs, (int)fraglen);
 
             /* fragment offset and fragment length */
             SSLEncodeSize(fragrec.contents.data+6, ofs, 3);
             SSLEncodeSize(fragrec.contents.data+9, fraglen, 3);
             /* copy the payload */
             memcpy(fragrec.contents.data+msghead, rec.contents.data+msghead+ofs, fraglen);
 
             /* fragment offset and fragment length */
             SSLEncodeSize(fragrec.contents.data+6, ofs, 3);
             SSLEncodeSize(fragrec.contents.data+9, fraglen, 3);
             /* copy the payload */
             memcpy(fragrec.contents.data+msghead, rec.contents.data+msghead+ofs, fraglen);
-            if ((err = ctx->sslTslCalls->writeRecord(fragrec, ctx)) != 0)
+            if ((err = SSLWriteRecord(fragrec, ctx)) != 0)
                 goto cleanup;
             len-=fraglen;
             ofs+=fraglen;
         }
 
                 goto cleanup;
             len-=fraglen;
             ofs+=fraglen;
         }
 
-        sslHdskMsgDebug("Fragmenting msg seq %ld - Last Fragment (o=%d,l=%d)", seq, ofs, len);
+        sslHdskMsgDebug("Fragmenting msg seq %d - Last Fragment (o=%d,l=%d)", (int)seq, (int)ofs, (int)len);
 
         /* last fragment */
         /* fragment offset and fragment length */
 
         /* last fragment */
         /* fragment offset and fragment length */
@@ -1156,11 +1179,11 @@ OSStatus DTLSSendMessage(SSLRecord rec, SSLContext *ctx)
         /* copy the payload */
         memcpy(fragrec.contents.data+msghead, rec.contents.data+msghead+ofs, len);
         fragrec.contents.length=len+msghead;
         /* copy the payload */
         memcpy(fragrec.contents.data+msghead, rec.contents.data+msghead+ofs, len);
         fragrec.contents.length=len+msghead;
-        err = ctx->sslTslCalls->writeRecord(fragrec, ctx);
+        err = SSLWriteRecord(fragrec, ctx);
 
     cleanup:
         /* Free the allocated fragment buffer */
 
     cleanup:
         /* Free the allocated fragment buffer */
-        SSLFreeBuffer(&fragrec.contents, ctx);
+        SSLFreeBuffer(&fragrec.contents);
 
     }
 
 
     }
 
@@ -1175,14 +1198,12 @@ OSStatus SSLResetFlight(SSLContext *ctx)
     WaitingMessage *next;
     int n=0;
 
     WaitingMessage *next;
     int n=0;
 
-    assert(ctx->sslTslCalls != NULL);
-
     queue=ctx->messageWriteQueue;
     ctx->messageQueueContainsChangeCipherSpec=false;
 
     while(queue) {
         n++;
     queue=ctx->messageWriteQueue;
     ctx->messageQueueContainsChangeCipherSpec=false;
 
     while(queue) {
         n++;
-        err = SSLFreeBuffer(&queue->rec.contents, ctx);
+        err = SSLFreeBuffer(&queue->rec.contents);
         if (err != 0)
             goto fail;
         next=queue->next;
         if (err != 0)
             goto fail;
         next=queue->next;
@@ -1192,21 +1213,18 @@ OSStatus SSLResetFlight(SSLContext *ctx)
 
     ctx->messageWriteQueue=NULL;
 
 
     ctx->messageWriteQueue=NULL;
 
-    return noErr;
+    return errSecSuccess;
 fail:
 fail:
-    assert(0);
+    check_noerr(err);
     return err;
 }
 
     return err;
 }
 
-
 OSStatus SSLSendFlight(SSLContext *ctx)
 {
     OSStatus err;
     WaitingMessage  *queue;
     int n=0;
 
 OSStatus SSLSendFlight(SSLContext *ctx)
 {
     OSStatus err;
     WaitingMessage  *queue;
     int n=0;
 
-    assert(ctx->sslTslCalls != NULL);
-
     queue=ctx->messageWriteQueue;
 
     while(queue) {
     queue=ctx->messageWriteQueue;
 
     while(queue) {
@@ -1221,9 +1239,9 @@ OSStatus SSLSendFlight(SSLContext *ctx)
         n++;
     }
 
         n++;
     }
 
-    return noErr;
+    return errSecSuccess;
 fail:
 fail:
-    assert(0);
+    check_noerr(err);
     return err;
 }
 
     return err;
 }
 
@@ -1243,9 +1261,27 @@ SSL3ReceiveSSL2ClientHello(SSLRecord rec, SSLContext *ctx)
     if ((err = SSLAdvanceHandshake(SSL_HdskClientHello, ctx)) != 0)
         return err;
 
     if ((err = SSLAdvanceHandshake(SSL_HdskClientHello, ctx)) != 0)
         return err;
 
-    return noErr;
+    return errSecSuccess;
+}
+
+/*
+ * Determine max enabled protocol, i.e., the one we try to negotiate for.
+ * Only returns an error (errSecParam) if NO protocols are enabled, which can
+ * in fact happen by malicious or ignorant use of SSLSetProtocolVersionEnabled().
+ */
+OSStatus sslGetMaxProtVersion(
+                              SSLContext                       *ctx,
+                              SSLProtocolVersion       *version)       // RETURNED
+{
+    /* This check is here until SSLSetProtocolVersionEnabled() is gone .*/
+    if (ctx->maxProtocolVersion == SSL_Version_Undetermined)
+        return errSecBadReq;
+
+    *version = ctx->maxProtocolVersion;
+    return errSecSuccess;
 }
 
 }
 
+
 /* log changes in handshake state */
 #ifndef        NDEBUG
 #include <stdio.h>
 /* log changes in handshake state */
 #ifndef        NDEBUG
 #include <stdio.h>
@@ -1269,8 +1305,6 @@ char *hdskStateToStr(SSLHandshakeState state)
                        return "NoNotifyClose";
                case SSL_HdskStateServerHello:
                        return "ServerHello";
                        return "NoNotifyClose";
                case SSL_HdskStateServerHello:
                        return "ServerHello";
-               case SSL_HdskStateServerHelloUnknownVersion:
-                       return "ServerHelloUnknownVersion";
                case SSL_HdskStateKeyExchange:
                        return "KeyExchange";
                case SSL_HdskStateCert:
                case SSL_HdskStateKeyExchange:
                        return "KeyExchange";
                case SSL_HdskStateCert:
@@ -1287,16 +1321,6 @@ char *hdskStateToStr(SSLHandshakeState state)
                        return "ChangeCipherSpec";
                case SSL_HdskStateFinished:
                        return "Finished";
                        return "ChangeCipherSpec";
                case SSL_HdskStateFinished:
                        return "Finished";
-               case SSL2_HdskStateClientMasterKey:
-                       return "SSL2_ClientMasterKey";
-               case SSL2_HdskStateClientFinished:
-                       return "SSL2_ClientFinished";
-               case SSL2_HdskStateServerHello:
-                       return "SSL2_ServerHello";
-               case SSL2_HdskStateServerVerify:
-                       return "SSL2_ServerVerify";
-               case SSL2_HdskStateServerFinished:
-                       return "SSL2_ServerFinished";
                case SSL_HdskStateServerReady:
                        return "SSL_ServerReady";
                case SSL_HdskStateClientReady:
                case SSL_HdskStateServerReady:
                        return "SSL_ServerReady";
                case SSL_HdskStateClientReady:
@@ -1307,16 +1331,13 @@ char *hdskStateToStr(SSLHandshakeState state)
        }
 }
 
        }
 }
 
+/* This is a macro in Release mode */
 void SSLChangeHdskState(SSLContext *ctx, SSLHandshakeState newState)
 {
 void SSLChangeHdskState(SSLContext *ctx, SSLHandshakeState newState)
 {
-       /* FIXME - this ifndef should not be necessary */
-       #ifndef NDEBUG
        sslHdskStateDebug("...hdskState = %s", hdskStateToStr(newState));
        sslHdskStateDebug("...hdskState = %s", hdskStateToStr(newState));
-       #endif
        ctx->state = newState;
 }
 
        ctx->state = newState;
 }
 
-
 /* log handshake messages */
 
 static char *hdskMsgToStr(SSLHandshakeType msg)
 /* log handshake messages */
 
 static char *hdskMsgToStr(SSLHandshakeType msg)
index 2101e743ae39953e1b8db477a0395a7dc10d7783..2a36f16644683641ada94f6759682e32dfa0f240 100644 (file)
@@ -22,7 +22,6 @@
 #ifndef _SSLHANDSHAKE_H_
 #define _SSLHANDSHAKE_H_
 
 #ifndef _SSLHANDSHAKE_H_
 #define _SSLHANDSHAKE_H_
 
-#include "cryptType.h"
 #include "sslRecord.h"
 
 #ifdef __cplusplus
 #include "sslRecord.h"
 
 #ifdef __cplusplus
@@ -115,8 +114,6 @@ typedef enum
                                                                                 *   notify msg */
     /* remainder must be consecutive */
     SSL_HdskStateServerHello,           /* must get server hello; client hello sent */
                                                                                 *   notify msg */
     /* remainder must be consecutive */
     SSL_HdskStateServerHello,           /* must get server hello; client hello sent */
-    SSL_HdskStateServerHelloUnknownVersion,
-                                                                               /* Could get SSL 2 or SSL 3 server hello back */
     SSL_HdskStateKeyExchange,           /* must get key exchange; cipher spec
                                                                                 *   requires it */
     SSL_HdskStateCert,                 /* may get certificate or certificate
     SSL_HdskStateKeyExchange,           /* must get key exchange; cipher spec
                                                                                 *   requires it */
     SSL_HdskStateCert,                 /* may get certificate or certificate
@@ -130,11 +127,6 @@ typedef enum
     SSL_HdskStateChangeCipherSpec,      /* time to change the cipher spec */
     SSL_HdskStateFinished,              /* must get a finished message in the
                                                                                 *   new cipher spec */
     SSL_HdskStateChangeCipherSpec,      /* time to change the cipher spec */
     SSL_HdskStateFinished,              /* must get a finished message in the
                                                                                 *   new cipher spec */
-    SSL2_HdskStateClientMasterKey,
-    SSL2_HdskStateClientFinished,
-    SSL2_HdskStateServerHello,
-    SSL2_HdskStateServerVerify,
-    SSL2_HdskStateServerFinished,
     SSL_HdskStateServerReady,          /* ready for I/O; server side */
     SSL_HdskStateClientReady           /* ready for I/O; client side */
 } SSLHandshakeState;
     SSL_HdskStateServerReady,          /* ready for I/O; server side */
     SSL_HdskStateClientReady           /* ready for I/O; client side */
 } SSLHandshakeState;
@@ -144,6 +136,14 @@ typedef struct
     SSLBuffer           contents;
 } SSLHandshakeMsg;
 
     SSLBuffer           contents;
 } SSLHandshakeMsg;
 
+
+uint8_t *SSLEncodeHandshakeHeader(
+    SSLContext *ctx,
+    SSLRecord *rec,
+    SSLHandshakeType type,
+    size_t msglen);
+
+
 #define SSL_Finished_Sender_Server  0x53525652
 #define SSL_Finished_Sender_Client  0x434C4E54
 
 #define SSL_Finished_Sender_Server  0x53525652
 #define SSL_Finished_Sender_Client  0x434C4E54
 
@@ -158,11 +158,20 @@ OSStatus DTLSRetransmit(SSLContext *ctx);
 OSStatus SSLResetFlight(SSLContext *ctx);
 OSStatus SSLSendFlight(SSLContext *ctx);
 
 OSStatus SSLResetFlight(SSLContext *ctx);
 OSStatus SSLSendFlight(SSLContext *ctx);
 
+OSStatus sslGetMaxProtVersion(SSLContext *ctx, SSLProtocolVersion      *version);      // RETURNED
+
+#ifdef NDEBUG
+#define SSLChangeHdskState(ctx, newState) { ctx->state=newState; }
+#define SSLLogHdskMsg(msg, sent)
+#else
+void SSLChangeHdskState(SSLContext *ctx, SSLHandshakeState newState);
+void SSLLogHdskMsg(SSLHandshakeType msg, char sent);
+char *hdskStateToStr(SSLHandshakeState state);
+#endif
 
 /** sslChangeCipher.c **/
 OSStatus SSLEncodeChangeCipherSpec(SSLRecord *rec, SSLContext *ctx);
 OSStatus SSLProcessChangeCipherSpec(SSLRecord rec, SSLContext *ctx);
 
 /** sslChangeCipher.c **/
 OSStatus SSLEncodeChangeCipherSpec(SSLRecord *rec, SSLContext *ctx);
 OSStatus SSLProcessChangeCipherSpec(SSLRecord rec, SSLContext *ctx);
-OSStatus SSLDisposeCipherSuite(CipherContext *cipher, SSLContext *ctx);
 
 /** sslCert.c **/
 OSStatus SSLEncodeCertificate(SSLRecord *certificate, SSLContext *ctx);
 
 /** sslCert.c **/
 OSStatus SSLEncodeCertificate(SSLRecord *certificate, SSLContext *ctx);
index a1c82066a601090e9777910298133ccaaef45d95..5a3f3a2fc8f8009f10c8c6c2ed3784db5c9394de 100644 (file)
@@ -64,8 +64,7 @@ SSLEncodeFinishedMessage(SSLRecord *finished, SSLContext *ctx)
     finished->contentType = SSL_RecordTypeHandshake;
        /* msg = type + 3 bytes len + finishedSize */
     head = SSLHandshakeHeaderSize(finished);
     finished->contentType = SSL_RecordTypeHandshake;
        /* msg = type + 3 bytes len + finishedSize */
     head = SSLHandshakeHeaderSize(finished);
-    if ((err = SSLAllocBuffer(&finished->contents, finishedSize + head,
-                       ctx)) != 0)
+    if ((err = SSLAllocBuffer(&finished->contents, finishedSize + head)) != 0)
         return err;
 
     p = SSLEncodeHandshakeHeader(ctx, finished, SSL_HdskFinished, finishedSize);
         return err;
 
     p = SSLEncodeHandshakeHeader(ctx, finished, SSL_HdskFinished, finishedSize);
@@ -80,7 +79,7 @@ SSLEncodeFinishedMessage(SSLRecord *finished, SSLContext *ctx)
         return err;
 
     /* Keep this around for secure renegotiation */
         return err;
 
     /* Keep this around for secure renegotiation */
-    SSLFreeBuffer(&ctx->ownVerifyData, ctx);
+    SSLFreeBuffer(&ctx->ownVerifyData);
     return SSLCopyBuffer(&finishedMsg, &ctx->ownVerifyData);
 }
 
     return SSLCopyBuffer(&finishedMsg, &ctx->ownVerifyData);
 }
 
@@ -110,7 +109,7 @@ SSLProcessFinished(SSLBuffer message, SSLContext *ctx)
         return errSSLProtocol;
     }
     expectedFinished.data = 0;
         return errSSLProtocol;
     }
     expectedFinished.data = 0;
-    if ((err = SSLAllocBuffer(&expectedFinished, finishedSize, ctx)) != 0)
+    if ((err = SSLAllocBuffer(&expectedFinished, finishedSize)))
         return err;
     isServerMsg = (ctx->protocolSide == kSSLServerSide) ? false : true;
     if ((err = ctx->sslTslCalls->computeFinishedMac(ctx, expectedFinished, isServerMsg)) != 0)
         return err;
     isServerMsg = (ctx->protocolSide == kSSLServerSide) ? false : true;
     if ((err = ctx->sslTslCalls->computeFinishedMac(ctx, expectedFinished, isServerMsg)) != 0)
@@ -124,11 +123,11 @@ SSLProcessFinished(SSLBuffer message, SSLContext *ctx)
     }
 
     /* Keep this around for secure renegotiation */
     }
 
     /* Keep this around for secure renegotiation */
-    SSLFreeBuffer(&ctx->peerVerifyData, ctx);
+    SSLFreeBuffer(&ctx->peerVerifyData);
     err = SSLCopyBuffer(&expectedFinished, &ctx->peerVerifyData);
 
 fail:
     err = SSLCopyBuffer(&expectedFinished, &ctx->peerVerifyData);
 
 fail:
-    SSLFreeBuffer(&expectedFinished, ctx);
+    SSLFreeBuffer(&expectedFinished);
     return err;
 }
 
     return err;
 }
 
@@ -141,12 +140,12 @@ SSLEncodeServerHelloDone(SSLRecord *helloDone, SSLContext *ctx)
        assert(ctx->negProtocolVersion >= SSL_Version_3_0);
     helloDone->protocolVersion = ctx->negProtocolVersion;
     head = SSLHandshakeHeaderSize(helloDone);
        assert(ctx->negProtocolVersion >= SSL_Version_3_0);
     helloDone->protocolVersion = ctx->negProtocolVersion;
     head = SSLHandshakeHeaderSize(helloDone);
-    if ((err = SSLAllocBuffer(&helloDone->contents, head, ctx)) != 0)
+    if ((err = SSLAllocBuffer(&helloDone->contents, head)))
         return err;
 
     SSLEncodeHandshakeHeader(ctx, helloDone, SSL_HdskServerHelloDone, 0); /* Message has 0 length */
 
         return err;
 
     SSLEncodeHandshakeHeader(ctx, helloDone, SSL_HdskServerHelloDone, 0); /* Message has 0 length */
 
-    return noErr;
+    return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -156,5 +155,5 @@ SSLProcessServerHelloDone(SSLBuffer message, SSLContext *ctx)
        sslErrorLog("SSLProcessServerHelloDone: nonzero msg len\n");
         return errSSLProtocol;
     }
        sslErrorLog("SSLProcessServerHelloDone: nonzero msg len\n");
         return errSSLProtocol;
     }
-    return noErr;
+    return errSecSuccess;
 }
 }
index 8b303d6b101b544fe31f6246d0889df55cc600ba..81daee815b993d69bd1b38e8c353698995105cd9 100644 (file)
 #include "sslUtils.h"
 #include "sslDebug.h"
 #include "sslCrypto.h"
 #include "sslUtils.h"
 #include "sslDebug.h"
 #include "sslCrypto.h"
-
+#include "sslRand.h"
 #include "sslDigests.h"
 #include "sslDigests.h"
-#include "cipherSpecs.h"
+#include "sslCipherSpecs.h"
 
 #include <string.h>
 
 #include <string.h>
+#include <time.h>
+#include <assert.h>
+
+#include <inttypes.h>
+
+/*
+ * Given a protocol version sent by peer, determine if we accept that version
+ * and downgrade if appropriate (which can not be done for the client side).
+ */
+static
+OSStatus sslVerifyProtVersion(
+    SSLContext                         *ctx,
+    SSLProtocolVersion peerVersion,    // sent by peer
+    SSLProtocolVersion         *negVersion)    // final negotiated version if return success
+{
+    if ((ctx->isDTLS)
+        ? peerVersion > ctx->minProtocolVersion
+        : peerVersion < ctx->minProtocolVersion) {
+        return errSSLNegotiation;
+    }
+    if ((ctx->isDTLS)
+        ? peerVersion < ctx->maxProtocolVersion
+        : peerVersion > ctx->maxProtocolVersion) {
+        if (ctx->protocolSide == kSSLClientSide) {
+            return errSSLNegotiation;
+        }
+        *negVersion = ctx->maxProtocolVersion;
+    } else {
+        *negVersion = peerVersion;
+    }
+
+    return errSecSuccess;
+}
+
 
 /* IE treats null session id as valid; two consecutive sessions with NULL ID
  * are considered a match. Workaround: when resumable sessions are disabled,
 
 /* IE treats null session id as valid; two consecutive sessions with NULL ID
  * are considered a match. Workaround: when resumable sessions are disabled,
@@ -66,16 +100,16 @@ SSLEncodeServerHello(SSLRecord *serverHello, SSLContext *ctx)
     msglen = 38 + sessionIDLen;
 
        /* this was set to a known quantity in SSLProcessClientHello */
     msglen = 38 + sessionIDLen;
 
        /* this was set to a known quantity in SSLProcessClientHello */
-       assert(ctx->negProtocolVersion != SSL_Version_Undetermined);
+       check(ctx->negProtocolVersion != SSL_Version_Undetermined);
        /* should not be here in this case */
        /* should not be here in this case */
-       assert(ctx->negProtocolVersion != SSL_Version_2_0);
+       check(ctx->negProtocolVersion != SSL_Version_2_0);
        sslLogNegotiateDebug("===SSL3 server: sending version %d_%d",
                ctx->negProtocolVersion >> 8, ctx->negProtocolVersion & 0xff);
        sslLogNegotiateDebug("...sessionIDLen = %d", sessionIDLen);
     serverHello->protocolVersion = ctx->negProtocolVersion;
     serverHello->contentType = SSL_RecordTypeHandshake;
     head = SSLHandshakeHeaderSize(serverHello);
        sslLogNegotiateDebug("===SSL3 server: sending version %d_%d",
                ctx->negProtocolVersion >> 8, ctx->negProtocolVersion & 0xff);
        sslLogNegotiateDebug("...sessionIDLen = %d", sessionIDLen);
     serverHello->protocolVersion = ctx->negProtocolVersion;
     serverHello->contentType = SSL_RecordTypeHandshake;
     head = SSLHandshakeHeaderSize(serverHello);
-    if ((err = SSLAllocBuffer(&serverHello->contents, msglen + head, ctx)) != 0)
+    if ((err = SSLAllocBuffer(&serverHello->contents, msglen + head)))
         return err;
 
     charPtr = SSLEncodeHandshakeHeader(ctx, serverHello, SSL_HdskServerHello, msglen);
         return err;
 
     charPtr = SSLEncodeHandshakeHeader(ctx, serverHello, SSL_HdskServerHello, msglen);
@@ -109,7 +143,7 @@ SSLEncodeServerHello(SSLRecord *serverHello, SSLContext *ctx)
                SSLBuffer rb;
                rb.data = charPtr;
                rb.length = SSL_NULL_ID_LEN;
                SSLBuffer rb;
                rb.data = charPtr;
                rb.length = SSL_NULL_ID_LEN;
-               sslRand(ctx, &rb);
+               sslRand(&rb);
        }
        #else
     if (sessionIDLen > 0)
        }
        #else
     if (sessionIDLen > 0)
@@ -120,11 +154,11 @@ SSLEncodeServerHello(SSLRecord *serverHello, SSLContext *ctx)
     *(charPtr++) = 0;      /* Null compression */
 
     sslLogNegotiateDebug("ssl3: server specifying cipherSuite 0x%lx",
     *(charPtr++) = 0;      /* Null compression */
 
     sslLogNegotiateDebug("ssl3: server specifying cipherSuite 0x%lx",
-               (UInt32)ctx->selectedCipher);
+               (unsigned long)ctx->selectedCipher);
 
     assert(charPtr == serverHello->contents.data + serverHello->contents.length);
 
 
     assert(charPtr == serverHello->contents.data + serverHello->contents.length);
 
-    return noErr;
+    return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -143,7 +177,7 @@ SSLEncodeServerHelloVerifyRequest(SSLRecord *helloVerifyRequest, SSLContext *ctx
     helloVerifyRequest->protocolVersion = DTLS_Version_1_0;
     helloVerifyRequest->contentType = SSL_RecordTypeHandshake;
     head = SSLHandshakeHeaderSize(helloVerifyRequest);
     helloVerifyRequest->protocolVersion = DTLS_Version_1_0;
     helloVerifyRequest->contentType = SSL_RecordTypeHandshake;
     head = SSLHandshakeHeaderSize(helloVerifyRequest);
-    if ((err = SSLAllocBuffer(&helloVerifyRequest->contents, msglen + head, ctx)) != 0)
+    if ((err = SSLAllocBuffer(&helloVerifyRequest->contents, msglen + head)))
         return err;
 
     charPtr = SSLEncodeHandshakeHeader(ctx, helloVerifyRequest, SSL_HdskHelloVerifyRequest, msglen);
         return err;
 
     charPtr = SSLEncodeHandshakeHeader(ctx, helloVerifyRequest, SSL_HdskHelloVerifyRequest, msglen);
@@ -156,7 +190,7 @@ SSLEncodeServerHelloVerifyRequest(SSLRecord *helloVerifyRequest, SSLContext *ctx
 
     assert(charPtr == (helloVerifyRequest->contents.data + helloVerifyRequest->contents.length));
 
 
     assert(charPtr == (helloVerifyRequest->contents.data + helloVerifyRequest->contents.length));
 
-    return noErr;
+    return errSecSuccess;
 }
 
 
 }
 
 
@@ -187,14 +221,14 @@ SSLProcessServerHelloVerifyRequest(SSLBuffer message, SSLContext *ctx)
     }
 
     cookieLen = *p++;
     }
 
     cookieLen = *p++;
-    sslLogNegotiateDebug("cookieLen = %d, msglen=%d\n", cookieLen, message.length);
+    sslLogNegotiateDebug("cookieLen = %d, msglen=%d\n", (int)cookieLen, (int)message.length);
     /* TODO: hardcoded '15' again */
     if (message.length < (3 + cookieLen)) {
        sslErrorLog("SSLProcessServerHelloVerifyRequest: msg len error 2\n");
         return errSSLProtocol;
     }
 
     /* TODO: hardcoded '15' again */
     if (message.length < (3 + cookieLen)) {
        sslErrorLog("SSLProcessServerHelloVerifyRequest: msg len error 2\n");
         return errSSLProtocol;
     }
 
-    err = SSLAllocBuffer(&ctx->dtlsCookie, cookieLen, ctx);
+    err = SSLAllocBuffer(&ctx->dtlsCookie, cookieLen);
     if (err == 0)
         memcpy(ctx->dtlsCookie.data, p, cookieLen);
 
     if (err == 0)
         memcpy(ctx->dtlsCookie.data, p, cookieLen);
 
@@ -285,9 +319,11 @@ SSLProcessServerHelloExtensions(SSLContext *ctx, UInt16 extensionsLen, UInt8 *p)
         p+=extLen;
     }
 
         p+=extLen;
     }
 
-    return noErr;
+    return errSecSuccess;
 }
 
 }
 
+
+
 OSStatus
 SSLProcessServerHello(SSLBuffer message, SSLContext *ctx)
 {   OSStatus            err;
 OSStatus
 SSLProcessServerHello(SSLBuffer message, SSLContext *ctx)
 {   OSStatus            err;
@@ -327,6 +363,11 @@ SSLProcessServerHello(SSLBuffer message, SSLContext *ctx)
                default:
                        return errSSLNegotiation;
        }
                default:
                        return errSSLNegotiation;
        }
+    err = ctx->recFuncs->setProtocolVersion(ctx->recCtx, negVersion);
+    if(err) {
+        return err;
+    }
+
     sslLogNegotiateDebug("===SSL3 client: negVersion is %d_%d",
                (negVersion >> 8) & 0xff, negVersion & 0xff);
 
     sslLogNegotiateDebug("===SSL3 client: negVersion is %d_%d",
                (negVersion >> 8) & 0xff, negVersion & 0xff);
 
@@ -341,8 +382,8 @@ SSLProcessServerHello(SSLBuffer message, SSLContext *ctx)
     if (sessionIDLen > 0 && ctx->peerID.data != 0)
     {   /* Don't die on error; just treat it as an uncached session */
         if (ctx->sessionID.data)
     if (sessionIDLen > 0 && ctx->peerID.data != 0)
     {   /* Don't die on error; just treat it as an uncached session */
         if (ctx->sessionID.data)
-            SSLFreeBuffer(&ctx->sessionID, ctx);
-        err = SSLAllocBuffer(&ctx->sessionID, sessionIDLen, ctx);
+            SSLFreeBuffer(&ctx->sessionID);
+        err = SSLAllocBuffer(&ctx->sessionID, sessionIDLen);
         if (err == 0)
             memcpy(ctx->sessionID.data, p, sessionIDLen);
     }
         if (err == 0)
             memcpy(ctx->sessionID.data, p, sessionIDLen);
     }
@@ -357,7 +398,7 @@ SSLProcessServerHello(SSLBuffer message, SSLContext *ctx)
     }
 
     if (*p++ != 0)      /* Compression */
     }
 
     if (*p++ != 0)      /* Compression */
-        return unimpErr;
+        return errSecUnimplemented;
 
     /* Process ServerHello extensions */
     extensionsLen = message.length - (38 + sessionIDLen);
 
     /* Process ServerHello extensions */
     extensionsLen = message.length - (38 + sessionIDLen);
@@ -375,6 +416,7 @@ SSLProcessServerHello(SSLBuffer message, SSLContext *ctx)
     if(ctx->secure_renegotiation_received)
         ctx->secure_renegotiation = true;
 
     if(ctx->secure_renegotiation_received)
         ctx->secure_renegotiation = true;
 
+    
        /*
         * Note: the server MAY send a SSL_HE_EC_PointFormats extension if
         * we've negotiated an ECDSA ciphersuite...but
        /*
         * Note: the server MAY send a SSL_HE_EC_PointFormats extension if
         * we've negotiated an ECDSA ciphersuite...but
@@ -386,7 +428,7 @@ SSLProcessServerHello(SSLBuffer message, SSLContext *ctx)
         * IF we ever support other point formats, we have to parse the extension
         * to see what the server supports.
         */
         * IF we ever support other point formats, we have to parse the extension
         * to see what the server supports.
         */
-    return noErr;
+    return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -436,7 +478,10 @@ SSLEncodeClientHello(SSLRecord *clientHello, SSLContext *ctx)
 
     length = 39 + 2*numCipherSuites + sessionIDLen;
 
 
     length = 39 + 2*numCipherSuites + sessionIDLen;
 
-       err = sslGetMaxProtVersion(ctx, &clientHello->protocolVersion);
+    /* We always use the max enabled version in the ClientHello.client_version,
+       even in the renegotiation case. This value is saved in the context so it
+       can be used in the RSA key exchange */
+       err = sslGetMaxProtVersion(ctx, &ctx->clientReqProtocol);
        if(err) {
                /* we don't have a protocol enabled */
                goto err_exit;
        if(err) {
                /* we don't have a protocol enabled */
                goto err_exit;
@@ -445,10 +490,19 @@ SSLEncodeClientHello(SSLRecord *clientHello, SSLContext *ctx)
     /* RFC 5746: If are starting a new handshake, so we didnt received this yet */
     ctx->secure_renegotiation_received = false;
 
     /* RFC 5746: If are starting a new handshake, so we didnt received this yet */
     ctx->secure_renegotiation_received = false;
 
-    /* If we already negotiated the protocol version previously,
-     we should just use that */
+    /* This is the protocol version used at the record layer, If we already
+     negotiated the protocol version previously, we should just use that,
+     otherwise we use the the minimum supported version.
+     We do not always use the minimum version because some TLS only servers
+     will reject an SSL 3 version in client_hello.
+    */
     if(ctx->negProtocolVersion != SSL_Version_Undetermined) {
         clientHello->protocolVersion = ctx->negProtocolVersion;
     if(ctx->negProtocolVersion != SSL_Version_Undetermined) {
         clientHello->protocolVersion = ctx->negProtocolVersion;
+    } else {
+        if(ctx->minProtocolVersion<TLS_Version_1_0 && ctx->maxProtocolVersion>=TLS_Version_1_0)
+            clientHello->protocolVersion = TLS_Version_1_0;
+        else
+            clientHello->protocolVersion = ctx->minProtocolVersion;
     }
 
 #if ENABLE_DTLS
     }
 
 #if ENABLE_DTLS
@@ -471,7 +525,7 @@ SSLEncodeClientHello(SSLRecord *clientHello, SSLContext *ctx)
     }
 
     /* prepare for optional ClientHello extensions */
     }
 
     /* prepare for optional ClientHello extensions */
-       if((clientHello->protocolVersion >= TLS_Version_1_0) &&
+       if((ctx->clientReqProtocol >= TLS_Version_1_0) &&
           (ctx->peerDomainName != NULL) &&
           (ctx->peerDomainNameLen != 0)) {
                serverNameLen = 2 +     /* extension type */
           (ctx->peerDomainName != NULL) &&
           (ctx->peerDomainNameLen != 0)) {
                serverNameLen = 2 +     /* extension type */
@@ -488,7 +542,7 @@ SSLEncodeClientHello(SSLRecord *clientHello, SSLContext *ctx)
                                                   ctx->sessionTicket.length;
                totalExtenLen += sessionTicketLen;
        }
                                                   ctx->sessionTicket.length;
                totalExtenLen += sessionTicketLen;
        }
-       if((clientHello->protocolVersion >= TLS_Version_1_0) &&
+       if((ctx->clientReqProtocol >= TLS_Version_1_0) &&
           (ctx->ecdsaEnable)) {
                /* Two more extensions: point format, supported curves */
                pointFormatLen = 2 +    /* extension type */
           (ctx->ecdsaEnable)) {
                /* Two more extensions: point format, supported curves */
                pointFormatLen = 2 +    /* extension type */
@@ -502,8 +556,8 @@ SSLEncodeClientHello(SSLRecord *clientHello, SSLContext *ctx)
                totalExtenLen += (pointFormatLen + suppCurveLen);
        }
     if(ctx->isDTLS
                totalExtenLen += (pointFormatLen + suppCurveLen);
        }
     if(ctx->isDTLS
-       ? clientHello->protocolVersion < DTLS_Version_1_0
-       : clientHello->protocolVersion >= TLS_Version_1_2) {
+       ? ctx->clientReqProtocol < DTLS_Version_1_0
+       : ctx->clientReqProtocol >= TLS_Version_1_2) {
         signatureAlgorithmsLen = 2 +   /* extension type */
                                  2 +   /* 2-byte vector length, extension_data */
                                  2 +    /* length of signatureAlgorithms list */
         signatureAlgorithmsLen = 2 +   /* extension type */
                                  2 +   /* 2-byte vector length, extension_data */
                                  2 +    /* length of signatureAlgorithms list */
@@ -531,16 +585,16 @@ SSLEncodeClientHello(SSLRecord *clientHello, SSLContext *ctx)
 
     clientHello->contentType = SSL_RecordTypeHandshake;
     head = SSLHandshakeHeaderSize(clientHello);
 
     clientHello->contentType = SSL_RecordTypeHandshake;
     head = SSLHandshakeHeaderSize(clientHello);
-    if ((err = SSLAllocBuffer(&clientHello->contents, length + head, ctx)) != 0)
+    if ((err = SSLAllocBuffer(&clientHello->contents, length + head)))
         goto err_exit;
 
     p = SSLEncodeHandshakeHeader(ctx, clientHello, SSL_HdskClientHello, length);
 
         goto err_exit;
 
     p = SSLEncodeHandshakeHeader(ctx, clientHello, SSL_HdskClientHello, length);
 
-    p = SSLEncodeInt(p, clientHello->protocolVersion, 2);
+    p = SSLEncodeInt(p, ctx->clientReqProtocol, 2);
 
        sslLogNegotiateDebug("===SSL3 client: proclaiming max protocol "
                "%d_%d capable ONLY",
 
        sslLogNegotiateDebug("===SSL3 client: proclaiming max protocol "
                "%d_%d capable ONLY",
-               clientHello->protocolVersion >> 8, clientHello->protocolVersion & 0xff);
+               ctx->clientReqProtocol >> 8, ctx->clientReqProtocol & 0xff);
    if ((err = SSLEncodeRandom(p, ctx)) != 0)
     {   goto err_exit;
     }
    if ((err = SSLEncodeRandom(p, ctx)) != 0)
     {   goto err_exit;
     }
@@ -552,14 +606,14 @@ SSLEncodeClientHello(SSLRecord *clientHello, SSLContext *ctx)
     }
     p += sessionIDLen;
 #if ENABLE_DTLS
     }
     p += sessionIDLen;
 #if ENABLE_DTLS
-    if (clientHello->protocolVersion == DTLS_Version_1_0) {
+    if (ctx->clientReqProtocol == DTLS_Version_1_0) {
         /* TODO: Add the cookie ! Currently: size=0 -> no cookie */
         *p++ = ctx->dtlsCookie.length;
         if(ctx->dtlsCookie.length) {
             memcpy(p, ctx->dtlsCookie.data, ctx->dtlsCookie.length);
             p+=ctx->dtlsCookie.length;
         }
         /* TODO: Add the cookie ! Currently: size=0 -> no cookie */
         *p++ = ctx->dtlsCookie.length;
         if(ctx->dtlsCookie.length) {
             memcpy(p, ctx->dtlsCookie.data, ctx->dtlsCookie.length);
             p+=ctx->dtlsCookie.length;
         }
-        sslLogNegotiateDebug("==DTLS Hello: cookie len = %d\n",ctx->dtlsCookie.length);
+        sslLogNegotiateDebug("==DTLS Hello: cookie len = %d\n",(int)ctx->dtlsCookie.length);
     }
 #endif
 
     }
 #endif
 
@@ -670,7 +724,7 @@ SSLEncodeClientHello(SSLRecord *clientHello, SSLContext *ctx)
         }
     }
 
         }
     }
 
-    sslLogNegotiateDebug("Client Hello : data=%p p=%p len=%08x\n", clientHello->contents.data, p, clientHello->contents.length);
+    sslLogNegotiateDebug("Client Hello : data=%p p=%p len=%08lx\n", clientHello->contents.data, p, (unsigned long)clientHello->contents.length);
 
     assert(p == clientHello->contents.data + clientHello->contents.length);
 
 
     assert(p == clientHello->contents.data + clientHello->contents.length);
 
@@ -679,9 +733,9 @@ SSLEncodeClientHello(SSLRecord *clientHello, SSLContext *ctx)
 
 err_exit:
        if (err != 0) {
 
 err_exit:
        if (err != 0) {
-               SSLFreeBuffer(&clientHello->contents, ctx);
+               SSLFreeBuffer(&clientHello->contents);
        }
        }
-       SSLFreeBuffer(&sessionIdentifier, ctx);
+       SSLFreeBuffer(&sessionIdentifier);
 
        return err;
 }
 
        return err;
 }
@@ -725,6 +779,10 @@ SSLProcessClientHello(SSLBuffer message, SSLContext *ctx)
                        return errSSLNegotiation;
        }
        ctx->negProtocolVersion = negVersion;
                        return errSSLNegotiation;
        }
        ctx->negProtocolVersion = negVersion;
+    err = ctx->recFuncs->setProtocolVersion(ctx->recCtx, negVersion);
+    if(err) {
+        return err;
+    }
     sslLogNegotiateDebug("===SSL3 server: negVersion is %d_%d",
                negVersion >> 8, negVersion & 0xff);
 
     sslLogNegotiateDebug("===SSL3 server: negVersion is %d_%d",
                negVersion >> 8, negVersion & 0xff);
 
@@ -738,7 +796,7 @@ SSLProcessClientHello(SSLBuffer message, SSLContext *ctx)
        /* FIXME peerID is never set on server side.... */
     if (sessionIDLen > 0 && ctx->peerID.data != 0)
     {   /* Don't die on error; just treat it as an uncacheable session */
        /* FIXME peerID is never set on server side.... */
     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);
+        err = SSLAllocBuffer(&ctx->sessionID, sessionIDLen);
         if (err == 0)
             memcpy(ctx->sessionID.data, charPtr, sessionIDLen);
     }
         if (err == 0)
             memcpy(ctx->sessionID.data, charPtr, sessionIDLen);
     }
@@ -842,7 +900,7 @@ SSLProcessClientHello(SSLBuffer message, SSLContext *ctx)
 #if            SSL_PAC_SERVER_ENABLE
 
                                case SSL_HE_SessionTicket:
 #if            SSL_PAC_SERVER_ENABLE
 
                                case SSL_HE_SessionTicket:
-                                       SSLFreeBuffer(&ctx->sessionTicket, NULL);
+                                       SSLFreeBuffer(&ctx->sessionTicket);
                                        SSLCopyBufferFromData(charPtr, extenLen, &ctx->sessionTicket);
                                        sslEapDebug("Saved %lu bytes of sessionTicket from ClientHello",
                                                (unsigned long)extenLen);
                                        SSLCopyBufferFromData(charPtr, extenLen, &ctx->sessionTicket);
                                        sslEapDebug("Saved %lu bytes of sessionTicket from ClientHello",
                                                (unsigned long)extenLen);
@@ -874,7 +932,10 @@ SSLProcessClientHello(SSLBuffer message, SSLContext *ctx)
                                }
                                case SSL_HE_SignatureAlgorithms:
                                {
                                }
                                case SSL_HE_SignatureAlgorithms:
                                {
-                                       UInt8 *cp = charPtr, *end = charPtr + extenLen;
+                                       UInt8 *cp = charPtr;
+#ifndef NDEBUG
+                    UInt8 *end = charPtr + extenLen;
+#endif
                     UInt32 sigAlgsSize = SSLDecodeInt(cp, 2);
                                        cp += 2;
 
                     UInt32 sigAlgsSize = SSLDecodeInt(cp, 2);
                                        cp += 2;
 
@@ -917,7 +978,16 @@ proceed:
     if ((err = SSLInitMessageHashes(ctx)) != 0)
         return err;
 
     if ((err = SSLInitMessageHashes(ctx)) != 0)
         return err;
 
-    return noErr;
+    return errSecSuccess;
+}
+
+static
+OSStatus sslTime(uint32_t *tim)
+{
+       time_t t;
+       time(&t);
+       *tim = (uint32_t)t;
+       return errSecSuccess;
 }
 
 OSStatus
 }
 
 OSStatus
@@ -931,30 +1001,30 @@ SSLEncodeRandom(unsigned char *p, SSLContext *ctx)
     SSLEncodeInt(p, now, 4);
     randomData.data = p+4;
     randomData.length = 28;
     SSLEncodeInt(p, now, 4);
     randomData.data = p+4;
     randomData.length = 28;
-       if((err = sslRand(ctx, &randomData)) != 0)
+       if((err = sslRand(&randomData)) != 0)
         return err;
         return err;
-    return noErr;
+    return errSecSuccess;
 }
 
 OSStatus
 SSLInitMessageHashes(SSLContext *ctx)
 {   OSStatus          err;
 
 }
 
 OSStatus
 SSLInitMessageHashes(SSLContext *ctx)
 {   OSStatus          err;
 
-    if ((err = CloseHash(&SSLHashSHA1, &ctx->shaState, ctx)) != 0)
+    if ((err = CloseHash(&SSLHashSHA1, &ctx->shaState)) != 0)
         return err;
         return err;
-    if ((err = CloseHash(&SSLHashMD5,  &ctx->md5State, ctx)) != 0)
+    if ((err = CloseHash(&SSLHashMD5,  &ctx->md5State)) != 0)
         return err;
         return err;
-    if ((err = CloseHash(&SSLHashSHA256,  &ctx->sha256State, ctx)) != 0)
+    if ((err = CloseHash(&SSLHashSHA256,  &ctx->sha256State)) != 0)
         return err;
         return err;
-    if ((err = CloseHash(&SSLHashSHA384,  &ctx->sha512State, ctx)) != 0)
+    if ((err = CloseHash(&SSLHashSHA384,  &ctx->sha512State)) != 0)
         return err;
         return err;
-    if ((err = ReadyHash(&SSLHashSHA1, &ctx->shaState, ctx)) != 0)
+    if ((err = ReadyHash(&SSLHashSHA1, &ctx->shaState)) != 0)
         return err;
         return err;
-    if ((err = ReadyHash(&SSLHashMD5,  &ctx->md5State, ctx)) != 0)
+    if ((err = ReadyHash(&SSLHashMD5,  &ctx->md5State)) != 0)
         return err;
         return err;
-    if ((err = ReadyHash(&SSLHashSHA256,  &ctx->sha256State, ctx)) != 0)
+    if ((err = ReadyHash(&SSLHashSHA256,  &ctx->sha256State)) != 0)
         return err;
         return err;
-    if ((err = ReadyHash(&SSLHashSHA384,  &ctx->sha512State, ctx)) != 0)
+    if ((err = ReadyHash(&SSLHashSHA384,  &ctx->sha512State)) != 0)
         return err;
         return err;
-    return noErr;
+    return errSecSuccess;
 }
 }
index a0e5549b2bd3a2e0b5d90c5e682479ebf02f370b..7d92517c4560825928839a9aabc7dd8d5a97e259 100644 (file)
 #include "sslDebug.h"
 #include "sslUtils.h"
 #include "sslCrypto.h"
 #include "sslDebug.h"
 #include "sslUtils.h"
 #include "sslCrypto.h"
-
+#include "sslRand.h"
 #include "sslDigests.h"
 
 #include <assert.h>
 #include <string.h>
 
 #include <stdio.h>
 #include "sslDigests.h"
 
 #include <assert.h>
 #include <string.h>
 
 #include <stdio.h>
-
+#include <utilities/SecCFRelease.h>
 #include <corecrypto/ccdh_gp.h>
 
 #ifdef USE_CDSA_CRYPTO
 #include <corecrypto/ccdh_gp.h>
 
 #ifdef USE_CDSA_CRYPTO
-//#include <security_utilities/globalizer.h>
-//#include <security_utilities/threading.h>
+//#include <utilities/globalizer.h>
+//#include <utilities/threading.h>
 #include <Security/cssmapi.h>
 #include <Security/SecKeyPriv.h>
 #include "ModuleAttacher.h"
 #else
 #include <Security/cssmapi.h>
 #include <Security/SecKeyPriv.h>
 #include "ModuleAttacher.h"
 #else
-#include <Security/SecRSAKey.h>
 #include <AssertMacros.h>
 #include <Security/oidsalg.h>
 #if APPLE_DH
 
 #include <AssertMacros.h>
 #include <Security/oidsalg.h>
 #if APPLE_DH
 
+#if TARGET_OS_IPHONE
+#include <Security/SecRSAKey.h>
+#endif
 
 static OSStatus SSLGenServerDHParamsAndKey(SSLContext *ctx);
 static size_t SSLEncodedDHKeyParamsLen(SSLContext *ctx);
 
 static OSStatus SSLGenServerDHParamsAndKey(SSLContext *ctx);
 static size_t SSLEncodedDHKeyParamsLen(SSLContext *ctx);
@@ -62,10 +64,8 @@ static OSStatus SSLEncodeDHKeyParams(SSLContext *ctx, uint8_t *charPtr);
 #endif /* APPLE_DH */
 #endif /* USE_CDSA_CRYPTO */
 
 #endif /* APPLE_DH */
 #endif /* USE_CDSA_CRYPTO */
 
-#include <pthread.h>
-
-#pragma mark -
-#pragma mark Forward Static Declarations
+// MARK: -
+// MARK: Forward Static Declarations
 
 #if APPLE_DH
 #if USE_CDSA_CRYPTO
 
 #if APPLE_DH
 #if USE_CDSA_CRYPTO
@@ -108,8 +108,8 @@ static void dumpBuf(const char *name, SSLBuffer *buf)
 
 #if    APPLE_DH
 
 
 #if    APPLE_DH
 
-#pragma mark -
-#pragma mark Local Diffie-Hellman Parameter Generator
+// MARK: -
+// MARK: Local Diffie-Hellman Parameter Generator
 
 /*
  * Process-wide server-supplied Diffie-Hellman parameters.
 
 /*
  * Process-wide server-supplied Diffie-Hellman parameters.
@@ -128,8 +128,8 @@ struct ServerDhParams
 
 #endif /* APPLE_DH */
 
 
 #endif /* APPLE_DH */
 
-#pragma mark -
-#pragma mark RSA Key Exchange
+// MARK: -
+// MARK: RSA Key Exchange
 
 /*
  * Client RSA Key Exchange msgs actually start with a two-byte
 
 /*
  * Client RSA Key Exchange msgs actually start with a two-byte
@@ -160,8 +160,8 @@ SSLEncodeRSAKeyParams(SSLBuffer *keyParams, SSLPubKey *key, SSLContext *ctx)
                &modulus,
                &exponent);
        if(err) {
                &modulus,
                &exponent);
        if(err) {
-               SSLFreeBuffer(&modulus, ctx);
-               SSLFreeBuffer(&exponent, ctx);
+               SSLFreeBuffer(&modulus);
+               SSLFreeBuffer(&exponent);
                return err;
        }
 
                return err;
        }
 
@@ -177,9 +177,9 @@ SSLEncodeRSAKeyParams(SSLBuffer *keyParams, SSLPubKey *key, SSLContext *ctx)
     memcpy(charPtr, exponent.data, exponent.length);
 
        /* these were mallocd by sslGetPubKeyBits() */
     memcpy(charPtr, exponent.data, exponent.length);
 
        /* these were mallocd by sslGetPubKeyBits() */
-       SSLFreeBuffer(&modulus, ctx);
-       SSLFreeBuffer(&exponent, ctx);
-    return noErr;
+       SSLFreeBuffer(&modulus);
+       SSLFreeBuffer(&exponent);
+    return errSecSuccess;
 #else
     CFDataRef modulus = SecKeyCopyModulus(SECKEYREF(key));
     if (!modulus) {
 #else
     CFDataRef modulus = SecKeyCopyModulus(SECKEYREF(key));
     if (!modulus) {
@@ -198,8 +198,10 @@ SSLEncodeRSAKeyParams(SSLBuffer *keyParams, SSLPubKey *key, SSLContext *ctx)
        sslDebugLog("SSLEncodeRSAKeyParams: modulus len=%ld, exponent len=%ld\n",
                modulusLength, exponentLength);
     OSStatus err;
        sslDebugLog("SSLEncodeRSAKeyParams: modulus len=%ld, exponent len=%ld\n",
                modulusLength, exponentLength);
     OSStatus err;
-    if ((err = SSLAllocBuffer(keyParams,
-                       modulusLength + exponentLength + 4, ctx)) != 0) {
+    if ((err = SSLAllocBuffer(keyParams, 
+                       modulusLength + exponentLength + 4)) != 0) {
+        CFReleaseSafe(exponent);
+        CFReleaseSafe(modulus);
         return err;
        }
     uint8_t *charPtr = keyParams->data;
         return err;
        }
     uint8_t *charPtr = keyParams->data;
@@ -210,7 +212,7 @@ SSLEncodeRSAKeyParams(SSLBuffer *keyParams, SSLPubKey *key, SSLContext *ctx)
     memcpy(charPtr, CFDataGetBytePtr(exponent), exponentLength);
     CFRelease(modulus);
     CFRelease(exponent);
     memcpy(charPtr, CFDataGetBytePtr(exponent), exponentLength);
     CFRelease(modulus);
     CFRelease(exponent);
-    return noErr;
+    return errSecSuccess;
 #endif
 }
 
 #endif
 }
 
@@ -218,20 +220,19 @@ static OSStatus
 SSLEncodeRSAPremasterSecret(SSLContext *ctx)
 {   SSLBuffer           randData;
     OSStatus            err;
 SSLEncodeRSAPremasterSecret(SSLContext *ctx)
 {   SSLBuffer           randData;
     OSStatus            err;
-    SSLProtocolVersion maxVersion;
 
 
-    if ((err = SSLAllocBuffer(&ctx->preMasterSecret,
-                       SSL_RSA_PREMASTER_SECRET_SIZE, ctx)) != 0)
+    if ((err = SSLAllocBuffer(&ctx->preMasterSecret, 
+                       SSL_RSA_PREMASTER_SECRET_SIZE)) != 0)
         return err;
 
        assert(ctx->negProtocolVersion >= SSL_Version_3_0);
         return err;
 
        assert(ctx->negProtocolVersion >= SSL_Version_3_0);
-       sslGetMaxProtVersion(ctx, &maxVersion);
-    SSLEncodeInt(ctx->preMasterSecret.data, maxVersion, 2);
+
+    SSLEncodeInt(ctx->preMasterSecret.data, ctx->clientReqProtocol, 2);
     randData.data = ctx->preMasterSecret.data+2;
     randData.length = SSL_RSA_PREMASTER_SECRET_SIZE - 2;
     randData.data = ctx->preMasterSecret.data+2;
     randData.length = SSL_RSA_PREMASTER_SECRET_SIZE - 2;
-    if ((err = sslRand(ctx, &randData)) != 0)
+    if ((err = sslRand(&randData)) != 0)
         return err;
         return err;
-    return noErr;
+    return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -282,7 +283,7 @@ SSLSignServerKeyExchangeTls12(SSLContext *ctx, SSLSignatureAndHashAlgorithm sigA
     hashOut.data = hashes;
     hashOut.length = hashRef->digestSize;
 
     hashOut.data = hashes;
     hashOut.length = hashRef->digestSize;
 
-    if ((err = ReadyHash(hashRef, &hashCtx, ctx)) != 0)
+    if ((err = ReadyHash(hashRef, &hashCtx)) != 0)
         goto fail;
     if ((err = hashRef->update(&hashCtx, &clientRandom)) != 0)
         goto fail;
         goto fail;
     if ((err = hashRef->update(&hashCtx, &clientRandom)) != 0)
         goto fail;
@@ -319,8 +320,8 @@ SSLSignServerKeyExchangeTls12(SSLContext *ctx, SSLSignatureAndHashAlgorithm sigA
        }
 
 fail:
        }
 
 fail:
-    SSLFreeBuffer(&signedHashes, ctx);
-    SSLFreeBuffer(&hashCtx, ctx);
+    SSLFreeBuffer(&signedHashes);
+    SSLFreeBuffer(&hashCtx);
     return err;
 }
 
     return err;
 }
 
@@ -348,7 +349,7 @@ SSLSignServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer exchangeParams,
         hash.data = &hashes[0];
         hash.length = SSL_MD5_DIGEST_LEN;
 
         hash.data = &hashes[0];
         hash.length = SSL_MD5_DIGEST_LEN;
 
-        if ((err = ReadyHash(&SSLHashMD5, &hashCtx, ctx)) != 0)
+        if ((err = ReadyHash(&SSLHashMD5, &hashCtx)) != 0)
             goto fail;
         if ((err = SSLHashMD5.update(&hashCtx, &clientRandom)) != 0)
             goto fail;
             goto fail;
         if ((err = SSLHashMD5.update(&hashCtx, &clientRandom)) != 0)
             goto fail;
@@ -358,7 +359,7 @@ SSLSignServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer exchangeParams,
             goto fail;
         if ((err = SSLHashMD5.final(&hashCtx, &hash)) != 0)
             goto fail;
             goto fail;
         if ((err = SSLHashMD5.final(&hashCtx, &hash)) != 0)
             goto fail;
-        if ((err = SSLFreeBuffer(&hashCtx, ctx)) != 0)
+        if ((err = SSLFreeBuffer(&hashCtx)) != 0)
             goto fail;
     }
     else {
             goto fail;
     }
     else {
@@ -368,7 +369,7 @@ SSLSignServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer exchangeParams,
     }
     hash.data = &hashes[SSL_MD5_DIGEST_LEN];
     hash.length = SSL_SHA1_DIGEST_LEN;
     }
     hash.data = &hashes[SSL_MD5_DIGEST_LEN];
     hash.length = SSL_SHA1_DIGEST_LEN;
-    if ((err = ReadyHash(&SSLHashSHA1, &hashCtx, ctx)) != 0)
+    if ((err = ReadyHash(&SSLHashSHA1, &hashCtx)) != 0)
     goto fail;
     if ((err = SSLHashSHA1.update(&hashCtx, &clientRandom)) != 0)
     goto fail;
     goto fail;
     if ((err = SSLHashSHA1.update(&hashCtx, &clientRandom)) != 0)
     goto fail;
@@ -378,7 +379,7 @@ SSLSignServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer exchangeParams,
     goto fail;
     if ((err = SSLHashSHA1.final(&hashCtx, &hash)) != 0)
     goto fail;
     goto fail;
     if ((err = SSLHashSHA1.final(&hashCtx, &hash)) != 0)
     goto fail;
-    if ((err = SSLFreeBuffer(&hashCtx, ctx)) != 0)
+    if ((err = SSLFreeBuffer(&hashCtx)) != 0)
     goto fail;
 
 
     goto fail;
 
 
@@ -394,7 +395,7 @@ SSLSignServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer exchangeParams,
     }
 
 fail:
     }
 
 fail:
-    SSLFreeBuffer(&hashCtx, ctx);
+    SSLFreeBuffer(&hashCtx);
 
     return err;
 }
 
     return err;
 }
@@ -422,7 +423,7 @@ OSStatus FindSigAlg(SSLContext *ctx,
         //Let's only support SHA1 and SHA256. SHA384 does not work with 512 bits keys.
         // We should actually test against what the cert can do.
         if((alg->hash==SSL_HashAlgorithmSHA1) || (alg->hash==SSL_HashAlgorithmSHA256)) {
         //Let's only support SHA1 and SHA256. SHA384 does not work with 512 bits keys.
         // We should actually test against what the cert can do.
         if((alg->hash==SSL_HashAlgorithmSHA1) || (alg->hash==SSL_HashAlgorithmSHA256)) {
-            return noErr;
+            return errSecSuccess;
         }
     }
     // We could not find a supported signature and hash algorithm
         }
     }
     // We could not find a supported signature and hash algorithm
@@ -455,7 +456,7 @@ SSLEncodeSignedServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx)
 
 
        /* Set up parameter block to hash ==> exchangeParams */
 
 
        /* Set up parameter block to hash ==> exchangeParams */
-       switch(ctx->selectedCipherSpec.keyExchangeMethod) {
+       switch(ctx->selectedCipherSpecParams.keyExchangeMethod) {
                case SSL_RSA:
         case SSL_RSA_EXPORT:
                        /*
                case SSL_RSA:
         case SSL_RSA_EXPORT:
                        /*
@@ -488,7 +489,7 @@ SSLEncodeSignedServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx)
                                return err;
                        }
             size_t len = SSLEncodedDHKeyParamsLen(ctx);
                                return err;
                        }
             size_t len = SSLEncodedDHKeyParamsLen(ctx);
-                       err = SSLAllocBuffer(&exchangeParams, len, ctx);
+                       err = SSLAllocBuffer(&exchangeParams, len);
                        if(err) {
                                goto fail;
                        }
                        if(err) {
                                goto fail;
                        }
@@ -512,7 +513,7 @@ SSLEncodeSignedServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx)
     if(err) {
         goto fail;
     }
     if(err) {
         goto fail;
     }
-    err = SSLAllocBuffer(&signature, maxSigLen, ctx);
+    err = SSLAllocBuffer(&signature, maxSigLen);
     if(err) {
         goto fail;
     }
     if(err) {
         goto fail;
     }
@@ -543,7 +544,7 @@ SSLEncodeSignedServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx)
        /* package it all up */
     keyExch->protocolVersion = ctx->negProtocolVersion;
     keyExch->contentType = SSL_RecordTypeHandshake;
        /* package it all up */
     keyExch->protocolVersion = ctx->negProtocolVersion;
     keyExch->contentType = SSL_RecordTypeHandshake;
-    if ((err = SSLAllocBuffer(&keyExch->contents, outputLen+head, ctx)) != 0)
+    if ((err = SSLAllocBuffer(&keyExch->contents, outputLen+head)) != 0)
         goto fail;
 
     charPtr = SSLEncodeHandshakeHeader(ctx, keyExch, SSL_HdskServerKeyExchange, outputLen);
         goto fail;
 
     charPtr = SSLEncodeHandshakeHeader(ctx, keyExch, SSL_HdskServerKeyExchange, outputLen);
@@ -562,11 +563,11 @@ SSLEncodeSignedServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx)
     assert((charPtr + actSigLen) ==
                   (keyExch->contents.data + keyExch->contents.length));
 
     assert((charPtr + actSigLen) ==
                   (keyExch->contents.data + keyExch->contents.length));
 
-    err = noErr;
+    err = errSecSuccess;
 
 fail:
 
 fail:
-    SSLFreeBuffer(&exchangeParams, ctx);
-    SSLFreeBuffer(&signature, ctx);
+    SSLFreeBuffer(&exchangeParams);
+    SSLFreeBuffer(&signature);
     return err;
 }
 
     return err;
 }
 
@@ -596,8 +597,8 @@ SSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer signedPa
                dataToSignLen = SSL_SHA1_DIGEST_LEN + SSL_MD5_DIGEST_LEN;
                hashOut.data = hashes;
                hashOut.length = SSL_MD5_DIGEST_LEN;
                dataToSignLen = SSL_SHA1_DIGEST_LEN + SSL_MD5_DIGEST_LEN;
                hashOut.data = hashes;
                hashOut.length = SSL_MD5_DIGEST_LEN;
-
-               if ((err = ReadyHash(&SSLHashMD5, &hashCtx, ctx)) != 0)
+               
+               if ((err = ReadyHash(&SSLHashMD5, &hashCtx)) != 0)
                        goto fail;
                if ((err = SSLHashMD5.update(&hashCtx, &clientRandom)) != 0)
                        goto fail;
                        goto fail;
                if ((err = SSLHashMD5.update(&hashCtx, &clientRandom)) != 0)
                        goto fail;
@@ -616,10 +617,10 @@ SSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer signedPa
 
        hashOut.data = hashes + SSL_MD5_DIGEST_LEN;
     hashOut.length = SSL_SHA1_DIGEST_LEN;
 
        hashOut.data = hashes + SSL_MD5_DIGEST_LEN;
     hashOut.length = SSL_SHA1_DIGEST_LEN;
-    if ((err = SSLFreeBuffer(&hashCtx, ctx)) != 0)
+    if ((err = SSLFreeBuffer(&hashCtx)) != 0)
         goto fail;
 
         goto fail;
 
-    if ((err = ReadyHash(&SSLHashSHA1, &hashCtx, ctx)) != 0)
+    if ((err = ReadyHash(&SSLHashSHA1, &hashCtx)) != 0)
         goto fail;
     if ((err = SSLHashSHA1.update(&hashCtx, &clientRandom)) != 0)
         goto fail;
         goto fail;
     if ((err = SSLHashSHA1.update(&hashCtx, &clientRandom)) != 0)
         goto fail;
@@ -627,6 +628,7 @@ SSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer signedPa
         goto fail;
     if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
         goto fail;
         goto fail;
     if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
         goto fail;
+        goto fail;
     if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
         goto fail;
 
     if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
         goto fail;
 
@@ -643,8 +645,8 @@ SSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer signedPa
        }
 
 fail:
        }
 
 fail:
-    SSLFreeBuffer(&signedHashes, ctx);
-    SSLFreeBuffer(&hashCtx, ctx);
+    SSLFreeBuffer(&signedHashes);
+    SSLFreeBuffer(&hashCtx);
     return err;
 
 }
     return err;
 
 }
@@ -694,7 +696,7 @@ SSLVerifySignedServerKeyExchangeTls12(SSLContext *ctx, SSLSignatureAndHashAlgori
     hashOut.data = hashes;
     hashOut.length = hashRef->digestSize;
 
     hashOut.data = hashes;
     hashOut.length = hashRef->digestSize;
 
-    if ((err = ReadyHash(hashRef, &hashCtx, ctx)) != 0)
+    if ((err = ReadyHash(hashRef, &hashCtx)) != 0)
         goto fail;
     if ((err = hashRef->update(&hashCtx, &clientRandom)) != 0)
         goto fail;
         goto fail;
     if ((err = hashRef->update(&hashCtx, &clientRandom)) != 0)
         goto fail;
@@ -729,8 +731,8 @@ SSLVerifySignedServerKeyExchangeTls12(SSLContext *ctx, SSLSignatureAndHashAlgori
        }
 
 fail:
        }
 
 fail:
-    SSLFreeBuffer(&signedHashes, ctx);
-    SSLFreeBuffer(&hashCtx, ctx);
+    SSLFreeBuffer(&signedHashes);
+    SSLFreeBuffer(&hashCtx);
     return err;
 
 }
     return err;
 
 }
@@ -757,7 +759,7 @@ SSLDecodeSignedServerKeyExchange(SSLBuffer message, SSLContext *ctx)
        /* first extract the key-exchange-method-specific parameters */
     uint8_t *charPtr = message.data;
        uint8_t *endCp = charPtr + message.length;
        /* first extract the key-exchange-method-specific parameters */
     uint8_t *charPtr = message.data;
        uint8_t *endCp = charPtr + message.length;
-       switch(ctx->selectedCipherSpec.keyExchangeMethod) {
+       switch(ctx->selectedCipherSpecParams.keyExchangeMethod) {
                case SSL_RSA:
         case SSL_RSA_EXPORT:
                        modulusLen = SSLDecodeInt(charPtr, 2);
                case SSL_RSA:
         case SSL_RSA_EXPORT:
                        modulusLen = SSLDecodeInt(charPtr, 2);
@@ -844,7 +846,7 @@ SSLDecodeSignedServerKeyExchange(SSLBuffer message, SSLContext *ctx)
         goto fail;
 
        /* Signature matches; now replace server key with new key (RSA only) */
         goto fail;
 
        /* Signature matches; now replace server key with new key (RSA only) */
-       switch(ctx->selectedCipherSpec.keyExchangeMethod) {
+       switch(ctx->selectedCipherSpecParams.keyExchangeMethod) {
                case SSL_RSA:
         case SSL_RSA_EXPORT:
                {
                case SSL_RSA:
         case SSL_RSA_EXPORT:
                {
@@ -889,24 +891,9 @@ SSLDecodeRSAKeyExchange(SSLBuffer keyExchange, SSLContext *ctx)
        SSLPrivKey                      *keyRef = NULL;
 
        assert(ctx->protocolSide == kSSLServerSide);
        SSLPrivKey                      *keyRef = NULL;
 
        assert(ctx->protocolSide == kSSLServerSide);
-
-       #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->encryptPrivKeyRef) {
-                       useEncryptKey = true;
-               }
-       #endif  /* SSL_SERVER_KEYEXCH_HACK */
+    if (ctx->encryptPrivKeyRef) {
+               useEncryptKey = true;
+    }
        if (useEncryptKey) {
                keyRef  = ctx->encryptPrivKeyRef;
                /* FIXME: when 3420180 is implemented, pick appropriate creds here */
        if (useEncryptKey) {
                keyRef  = ctx->encryptPrivKeyRef;
                /* FIXME: when 3420180 is implemented, pick appropriate creds here */
@@ -940,7 +927,7 @@ SSLDecodeRSAKeyExchange(SSLBuffer keyExchange, SSLContext *ctx)
                        (unsigned)localKeyModulusLen, (unsigned)keyExchange.length);
         return errSSLProtocol;
        }
                        (unsigned)localKeyModulusLen, (unsigned)keyExchange.length);
         return errSSLProtocol;
        }
-    err = SSLAllocBuffer(&ctx->preMasterSecret, SSL_RSA_PREMASTER_SECRET_SIZE, ctx);
+    err = SSLAllocBuffer(&ctx->preMasterSecret, SSL_RSA_PREMASTER_SECRET_SIZE);
        if(err != 0) {
         return err;
        }
        if(err != 0) {
         return err;
        }
@@ -973,7 +960,7 @@ SSLDecodeRSAKeyExchange(SSLBuffer keyExchange, SSLContext *ctx)
                SSL_RSA_PREMASTER_SECRET_SIZE,  // plaintext buf available
                &outputLen);
 
                SSL_RSA_PREMASTER_SECRET_SIZE,  // plaintext buf available
                &outputLen);
 
-       if(err != noErr) {
+       if(err != errSecSuccess) {
                /* possible Bleichenbacher attack */
                sslLogNegotiateDebug("SSLDecodeRSAKeyExchange: RSA decrypt fail");
        }
                /* possible Bleichenbacher attack */
                sslLogNegotiateDebug("SSLDecodeRSAKeyExchange: RSA decrypt fail");
        }
@@ -982,7 +969,7 @@ SSLDecodeRSAKeyExchange(SSLBuffer keyExchange, SSLContext *ctx)
        err = errSSLProtocol;                                                   // not passed back to caller
     }
 
        err = errSSLProtocol;                                                   // not passed back to caller
     }
 
-       if(err == noErr) {
+       if(err == errSecSuccess) {
                /*
                 * Two legal values here - the one we actually negotiated (which is
                 * technically incorrect but not uncommon), and the one the client
                /*
                 * Two legal values here - the one we actually negotiated (which is
                 * technically incorrect but not uncommon), and the one the client
@@ -996,7 +983,7 @@ SSLDecodeRSAKeyExchange(SSLBuffer keyExchange, SSLContext *ctx)
                        err = errSSLProtocol;
                }
     }
                        err = errSSLProtocol;
                }
     }
-       if(err != noErr) {
+       if(err != errSecSuccess) {
                /*
                 * Obfuscate failures for defense against Bleichenbacher and
                 * Klima-Pokorny-Rosa attacks.
                /*
                 * Obfuscate failures for defense against Bleichenbacher and
                 * Klima-Pokorny-Rosa attacks.
@@ -1006,11 +993,11 @@ SSLDecodeRSAKeyExchange(SSLBuffer keyExchange, SSLContext *ctx)
                tmpBuf.data   = ctx->preMasterSecret.data + 2;
                tmpBuf.length = SSL_RSA_PREMASTER_SECRET_SIZE - 2;
                /* must ignore failures here */
                tmpBuf.data   = ctx->preMasterSecret.data + 2;
                tmpBuf.length = SSL_RSA_PREMASTER_SECRET_SIZE - 2;
                /* must ignore failures here */
-               sslRand(ctx, &tmpBuf);
+               sslRand(&tmpBuf);
        }
 
        /* in any case, save premaster secret (good or bogus) and proceed */
        }
 
        /* in any case, save premaster secret (good or bogus) and proceed */
-    return noErr;
+    return errSecSuccess;
 }
 
 static OSStatus
 }
 
 static OSStatus
@@ -1049,9 +1036,9 @@ SSLEncodeRSAKeyExchange(SSLRecord *keyExchange, SSLContext *ctx)
        #endif
     head = SSLHandshakeHeaderSize(keyExchange);
     bufLen = msglen + head;
        #endif
     head = SSLHandshakeHeaderSize(keyExchange);
     bufLen = msglen + head;
-    if ((err = SSLAllocBuffer(&keyExchange->contents,
-               bufLen,ctx)) != 0)
-    {
+    if ((err = SSLAllocBuffer(&keyExchange->contents, 
+               bufLen)) != 0)
+    {   
         return err;
     }
        dst = keyExchange->contents.data + head;
         return err;
     }
        dst = keyExchange->contents.data + head;
@@ -1082,20 +1069,20 @@ SSLEncodeRSAKeyExchange(SSLRecord *keyExchange, SSLContext *ctx)
                peerKeyModulusLen,
                &outputLen);
        if(err) {
                peerKeyModulusLen,
                &outputLen);
        if(err) {
-               sslErrorLog("SSLEncodeRSAKeyExchange: error %d\n", err);
+               sslErrorLog("SSLEncodeRSAKeyExchange: error %d\n", (int)err);
                return err;
        }
 
     assert(outputLen == (encodeLen ? msglen - 2 : msglen));
 
                return err;
        }
 
     assert(outputLen == (encodeLen ? msglen - 2 : msglen));
 
-    return noErr;
+    return errSecSuccess;
 }
 
 
 #if APPLE_DH
 
 }
 
 
 #if APPLE_DH
 
-#pragma mark -
-#pragma mark Diffie-Hellman Key Exchange
+// MARK: -
+// MARK: Diffie-Hellman Key Exchange
 
 /*
  * Diffie-Hellman setup, server side. On successful return, the
 
 /*
  * Diffie-Hellman setup, server side. On successful return, the
@@ -1148,7 +1135,7 @@ SSLGenServerDHParamsAndKey(
 #if USE_CDSA_CRYPTO
        /* generate per-session D-H key pair */
        sslFreeKey(ctx->cspHand, &ctx->dhPrivate, NULL);
 #if USE_CDSA_CRYPTO
        /* generate per-session D-H key pair */
        sslFreeKey(ctx->cspHand, &ctx->dhPrivate, NULL);
-       SSLFreeBuffer(&ctx->dhExchangePublic, ctx);
+       SSLFreeBuffer(&ctx->dhExchangePublic);
        ctx->dhPrivate = (CSSM_KEY *)sslMalloc(sizeof(CSSM_KEY));
        CSSM_KEY pubKey;
        ortn = sslDhGenerateKeyPair(ctx,
        ctx->dhPrivate = (CSSM_KEY *)sslMalloc(sizeof(CSSM_KEY));
        CSSM_KEY pubKey;
        ortn = sslDhGenerateKeyPair(ctx,
@@ -1167,7 +1154,7 @@ SSLGenServerDHParamsAndKey(
     }
     return sslDhGenerateKeyPair(ctx);
 #endif
     }
     return sslDhGenerateKeyPair(ctx);
 #endif
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -1219,7 +1206,7 @@ SSLEncodeDHKeyParams(
        dumpBuf("server generator", &generator);
        dumpBuf("server pub key", &ctx->dhExchangePublic);
 
        dumpBuf("server generator", &generator);
        dumpBuf("server pub key", &ctx->dhExchangePublic);
 
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -1231,7 +1218,7 @@ SSLDecodeDHKeyParams(
        uint8_t **charPtr,              // IN/OUT
        size_t length)
 {
        uint8_t **charPtr,              // IN/OUT
        size_t length)
 {
-       OSStatus        err = noErr;
+       OSStatus        err = errSecSuccess;
     SSLBuffer       prime;
     SSLBuffer       generator;
 
     SSLBuffer       prime;
     SSLBuffer       generator;
 
@@ -1239,8 +1226,8 @@ SSLDecodeDHKeyParams(
     uint8_t *endCp = *charPtr + length;
 
        /* Allow reuse via renegotiation */
     uint8_t *endCp = *charPtr + length;
 
        /* Allow reuse via renegotiation */
-       SSLFreeBuffer(&ctx->dhPeerPublic, ctx);
-
+       SSLFreeBuffer(&ctx->dhPeerPublic);
+       
        /* Prime, with a two-byte length */
        UInt32 len = SSLDecodeInt(*charPtr, 2);
        (*charPtr) += 2;
        /* Prime, with a two-byte length */
        UInt32 len = SSLDecodeInt(*charPtr, 2);
        (*charPtr) += 2;
@@ -1270,7 +1257,7 @@ SSLDecodeDHKeyParams(
        /* peer public key, with a two-byte length */
        len = SSLDecodeInt(*charPtr, 2);
        (*charPtr) += 2;
        /* peer public key, with a two-byte length */
        len = SSLDecodeInt(*charPtr, 2);
        (*charPtr) += 2;
-       err = SSLAllocBuffer(&ctx->dhPeerPublic, len, ctx);
+       err = SSLAllocBuffer(&ctx->dhPeerPublic, len);
        if(err) {
                return err;
        }
        if(err) {
                return err;
        }
@@ -1278,8 +1265,8 @@ SSLDecodeDHKeyParams(
        (*charPtr) += len;
 
        dumpBuf("client peer pub", &ctx->dhPeerPublic);
        (*charPtr) += len;
 
        dumpBuf("client peer pub", &ctx->dhPeerPublic);
-       dumpBuf("client prime", &ctx->dhParamsPrime);
-       dumpBuf("client generator", &ctx->dhParamsGenerator);
+    // dumpBuf("client prime", &ctx->dhParamsPrime);
+       //  dumpBuf("client generator", &ctx->dhParamsGenerator);
 
        return err;
 }
 
        return err;
 }
@@ -1349,7 +1336,7 @@ out:
 static OSStatus
 SSLEncodeDHanonServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx)
 {
 static OSStatus
 SSLEncodeDHanonServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx)
 {
-       OSStatus            ortn = noErr;
+       OSStatus            ortn = errSecSuccess;
     int                 head;
 
        assert(ctx->negProtocolVersion >= SSL_Version_3_0);
     int                 head;
 
        assert(ctx->negProtocolVersion >= SSL_Version_3_0);
@@ -1368,7 +1355,7 @@ SSLEncodeDHanonServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx)
        keyExch->protocolVersion = ctx->negProtocolVersion;
        keyExch->contentType = SSL_RecordTypeHandshake;
     head = SSLHandshakeHeaderSize(keyExch);
        keyExch->protocolVersion = ctx->negProtocolVersion;
        keyExch->contentType = SSL_RecordTypeHandshake;
     head = SSLHandshakeHeaderSize(keyExch);
-       if ((ortn = SSLAllocBuffer(&keyExch->contents, length+head, ctx)) != 0)
+       if ((ortn = SSLAllocBuffer(&keyExch->contents, length+head)))
                return ortn;
 
     uint8_t *charPtr = SSLEncodeHandshakeHeader(ctx, keyExch, SSL_HdskServerKeyExchange, length);
                return ortn;
 
     uint8_t *charPtr = SSLEncodeHandshakeHeader(ctx, keyExch, SSL_HdskServerKeyExchange, length);
@@ -1380,7 +1367,7 @@ SSLEncodeDHanonServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx)
 static OSStatus
 SSLDecodeDHanonServerKeyExchange(SSLBuffer message, SSLContext *ctx)
 {
 static OSStatus
 SSLDecodeDHanonServerKeyExchange(SSLBuffer message, SSLContext *ctx)
 {
-       OSStatus        err = noErr;
+       OSStatus        err = errSecSuccess;
 
        assert(ctx->protocolSide == kSSLClientSide);
     if (message.length < 6) {
 
        assert(ctx->protocolSide == kSSLClientSide);
     if (message.length < 6) {
@@ -1390,7 +1377,7 @@ SSLDecodeDHanonServerKeyExchange(SSLBuffer message, SSLContext *ctx)
     }
     uint8_t *charPtr = message.data;
        err = SSLDecodeDHKeyParams(ctx, &charPtr, message.length);
     }
     uint8_t *charPtr = message.data;
        err = SSLDecodeDHKeyParams(ctx, &charPtr, message.length);
-       if(err == noErr) {
+       if(err == errSecSuccess) {
                if((message.data + message.length) != charPtr) {
                        err = errSSLProtocol;
                }
                if((message.data + message.length) != charPtr) {
                        err = errSSLProtocol;
                }
@@ -1401,7 +1388,7 @@ SSLDecodeDHanonServerKeyExchange(SSLBuffer message, SSLContext *ctx)
 static OSStatus
 SSLDecodeDHClientKeyExchange(SSLBuffer keyExchange, SSLContext *ctx)
 {
 static OSStatus
 SSLDecodeDHClientKeyExchange(SSLBuffer keyExchange, SSLContext *ctx)
 {
-       OSStatus        ortn = noErr;
+       OSStatus        ortn = errSecSuccess;
     unsigned int    publicLen;
 
        assert(ctx->protocolSide == kSSLServerSide);
     unsigned int    publicLen;
 
        assert(ctx->protocolSide == kSSLServerSide);
@@ -1422,15 +1409,15 @@ SSLDecodeDHClientKeyExchange(SSLBuffer keyExchange, SSLContext *ctx)
         return errSSLProtocol;
     }
     */
         return errSSLProtocol;
     }
     */
-       SSLFreeBuffer(&ctx->dhPeerPublic, ctx); // allow reuse via renegotiation
-       ortn = SSLAllocBuffer(&ctx->dhPeerPublic, publicLen, ctx);
+       SSLFreeBuffer(&ctx->dhPeerPublic);      // allow reuse via renegotiation
+       ortn = SSLAllocBuffer(&ctx->dhPeerPublic, publicLen);
        if(ortn) {
                return ortn;
        }
        memmove(ctx->dhPeerPublic.data, charPtr, publicLen);
 
        /* DH Key exchange, result --> premaster secret */
        if(ortn) {
                return ortn;
        }
        memmove(ctx->dhPeerPublic.data, charPtr, publicLen);
 
        /* DH Key exchange, result --> premaster secret */
-       SSLFreeBuffer(&ctx->preMasterSecret, ctx);
+       SSLFreeBuffer(&ctx->preMasterSecret);
 #if USE_CDSA_CRYPTO
        ortn = sslDhKeyExchange(ctx, ctx->dhParamsPrime.length * 8,
                &ctx->preMasterSecret);
 #if USE_CDSA_CRYPTO
        ortn = sslDhKeyExchange(ctx, ctx->dhParamsPrime.length * 8,
                &ctx->preMasterSecret);
@@ -1459,7 +1446,7 @@ SSLEncodeDHClientKeyExchange(SSLRecord *keyExchange, SSLContext *ctx)
 
     outputLen = ctx->dhExchangePublic.length + 2;
     head = SSLHandshakeHeaderSize(keyExchange);
 
     outputLen = ctx->dhExchangePublic.length + 2;
     head = SSLHandshakeHeaderSize(keyExchange);
-    if ((err = SSLAllocBuffer(&keyExchange->contents,outputLen + head,ctx)) != 0)
+    if ((err = SSLAllocBuffer(&keyExchange->contents,outputLen + head)))
         return err;
 
     uint8_t *charPtr = SSLEncodeHandshakeHeader(ctx, keyExchange, SSL_HdskClientKeyExchange, outputLen);
         return err;
 
     uint8_t *charPtr = SSLEncodeHandshakeHeader(ctx, keyExchange, SSL_HdskClientKeyExchange, outputLen);
@@ -1470,13 +1457,13 @@ SSLEncodeDHClientKeyExchange(SSLRecord *keyExchange, SSLContext *ctx)
        dumpBuf("client pub key", &ctx->dhExchangePublic);
        dumpBuf("client premaster", &ctx->preMasterSecret);
 
        dumpBuf("client pub key", &ctx->dhExchangePublic);
        dumpBuf("client premaster", &ctx->preMasterSecret);
 
-    return noErr;
+    return errSecSuccess;
 }
 
 #endif /* APPLE_DH */
 
 }
 
 #endif /* APPLE_DH */
 
-#pragma mark -
-#pragma mark ECDSA Key Exchange
+// MARK: -
+// MARK: ECDSA Key Exchange
 
 /*
  * Given the server's ECDH curve params and public key, generate our
 
 /*
  * Given the server's ECDH curve params and public key, generate our
@@ -1503,7 +1490,7 @@ SSLGenClientECDHKeyAndExchange(SSLContext *ctx)
 
     assert(ctx->protocolSide == kSSLClientSide);
 
 
     assert(ctx->protocolSide == kSSLClientSide);
 
-       switch(ctx->selectedCipherSpec.keyExchangeMethod) {
+       switch(ctx->selectedCipherSpecParams.keyExchangeMethod) {
                case SSL_ECDHE_ECDSA:
                case SSL_ECDHE_RSA:
                        /* Server sent us an ephemeral key with peer curve specified */
                case SSL_ECDHE_ECDSA:
                case SSL_ECDHE_RSA:
                        /* Server sent us an ephemeral key with peer curve specified */
@@ -1548,7 +1535,7 @@ SSLGenClientECDHKeyAndExchange(SSLContext *ctx)
 #if USE_CDSA_CRYPTO
                //assert(ctx->cspHand != 0);
                sslFreeKey(ctx->cspHand, &ctx->ecdhPrivate, NULL);
 #if USE_CDSA_CRYPTO
                //assert(ctx->cspHand != 0);
                sslFreeKey(ctx->cspHand, &ctx->ecdhPrivate, NULL);
-               SSLFreeBuffer(&ctx->ecdhExchangePublic, ctx);
+               SSLFreeBuffer(&ctx->ecdhExchangePublic);
                ortn = SecKeyGetCSSMKey(ctx->signingPrivKeyRef, (const CSSM_KEY **)&ctx->ecdhPrivate);
                if(ortn) {
                        return ortn;
                ortn = SecKeyGetCSSMKey(ctx->signingPrivKeyRef, (const CSSM_KEY **)&ctx->ecdhPrivate);
                if(ortn) {
                        return ortn;
@@ -1580,7 +1567,7 @@ SSLGenClientECDHKeyAndExchange(SSLContext *ctx)
        if(ortn) {
                return ortn;
        }
        if(ortn) {
                return ortn;
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 
 }
 
 
@@ -1593,7 +1580,7 @@ SSLDecodeECDHKeyParams(
        uint8_t **charPtr,              // IN/OUT
        size_t length)
 {
        uint8_t **charPtr,              // IN/OUT
        size_t length)
 {
-       OSStatus        err = noErr;
+       OSStatus        err = errSecSuccess;
 
        sslEcdsaDebug("+++ Decoding ECDH Server Key Exchange");
 
 
        sslEcdsaDebug("+++ Decoding ECDH Server Key Exchange");
 
@@ -1601,7 +1588,7 @@ SSLDecodeECDHKeyParams(
     uint8_t *endCp = *charPtr + length;
 
        /* Allow reuse via renegotiation */
     uint8_t *endCp = *charPtr + length;
 
        /* Allow reuse via renegotiation */
-       SSLFreeBuffer(&ctx->ecdhPeerPublic, ctx);
+       SSLFreeBuffer(&ctx->ecdhPeerPublic);
 
        /*** ECParameters - just a curveType and a named curve ***/
 
 
        /*** ECParameters - just a curveType and a named curve ***/
 
@@ -1648,7 +1635,7 @@ SSLDecodeECDHKeyParams(
        if((*charPtr + len) > endCp) {
                return errSSLProtocol;
        }
        if((*charPtr + len) > endCp) {
                return errSSLProtocol;
        }
-       err = SSLAllocBuffer(&ctx->ecdhPeerPublic, len, ctx);
+       err = SSLAllocBuffer(&ctx->ecdhPeerPublic, len);
        if(err) {
                return err;
        }
        if(err) {
                return err;
        }
@@ -1696,7 +1683,7 @@ SSLEncodeECDHClientKeyExchange(SSLRecord *keyExchange, SSLContext *ctx)
        assert(ctx->negProtocolVersion >= SSL_Version_3_0);
     keyExchange->protocolVersion = ctx->negProtocolVersion;
     head = SSLHandshakeHeaderSize(keyExchange);
        assert(ctx->negProtocolVersion >= SSL_Version_3_0);
     keyExchange->protocolVersion = ctx->negProtocolVersion;
     head = SSLHandshakeHeaderSize(keyExchange);
-    if ((err = SSLAllocBuffer(&keyExchange->contents,outputLen + head,ctx)) != 0)
+    if ((err = SSLAllocBuffer(&keyExchange->contents,outputLen + head)))
         return err;
 
     uint8_t *charPtr = SSLEncodeHandshakeHeader(ctx, keyExchange, SSL_HdskClientKeyExchange, outputLen);
         return err;
 
     uint8_t *charPtr = SSLEncodeHandshakeHeader(ctx, keyExchange, SSL_HdskClientKeyExchange, outputLen);
@@ -1712,16 +1699,108 @@ SSLEncodeECDHClientKeyExchange(SSLRecord *keyExchange, SSLContext *ctx)
 
        dumpBuf("client pub key", &ctx->ecdhExchangePublic);
        dumpBuf("client premaster", &ctx->preMasterSecret);
 
        dumpBuf("client pub key", &ctx->ecdhExchangePublic);
        dumpBuf("client premaster", &ctx->preMasterSecret);
-    return noErr;
+    return errSecSuccess;
+}
+
+
+
+static OSStatus
+SSLDecodePSKClientKeyExchange(SSLBuffer keyExchange, SSLContext *ctx)
+{
+       OSStatus        ortn = errSecSuccess;
+    unsigned int    identityLen;
+
+       assert(ctx->protocolSide == kSSLServerSide);
+
+       /* this message simply contains the client's PSK identity */
+       uint8_t *charPtr = keyExchange.data;
+    identityLen = SSLDecodeInt(charPtr, 2);
+       charPtr += 2;
+
+       SSLFreeBuffer(&ctx->pskIdentity);       // allow reuse via renegotiation
+       ortn = SSLAllocBuffer(&ctx->pskIdentity, identityLen);
+       if(ortn) {
+               return ortn;
+       }
+       memmove(ctx->pskIdentity.data, charPtr, identityLen);
+
+    /* TODO: At this point we know the identity of the PSK client,
+      we should break out of the handshake, so we can select the appropriate
+      PreShared secret. As this stands, the preshared secret needs to be known
+      before the handshake starts. */
+
+    size_t n=ctx->pskSharedSecret.length;
+
+    if(n==0) return errSSLBadConfiguration;
+
+    if ((ortn = SSLAllocBuffer(&ctx->preMasterSecret, 2*(n+2))) != 0)
+        return ortn;
+
+    uint8_t *p=ctx->preMasterSecret.data;
+
+    p = SSLEncodeInt(p, n, 2);
+    memset(p, 0, n); p+=n;
+    p = SSLEncodeInt(p, n, 2);
+    memcpy(p, ctx->pskSharedSecret.data, n);
+
+    dumpBuf("server premaster (PSK)", &ctx->preMasterSecret);
+
+       return ortn;
+}
+
+
+static OSStatus
+SSLEncodePSKClientKeyExchange(SSLRecord *keyExchange, SSLContext *ctx)
+{
+    OSStatus            err;
+    size_t                             outputLen;
+    int                 head;
+
+       assert(ctx->protocolSide == kSSLClientSide);
+
+       outputLen = ctx->pskIdentity.length+2;
+
+    keyExchange->contentType = SSL_RecordTypeHandshake;
+       assert(ctx->negProtocolVersion >= SSL_Version_3_0);
+    keyExchange->protocolVersion = ctx->negProtocolVersion;
+    head = SSLHandshakeHeaderSize(keyExchange);
+    if ((err = SSLAllocBuffer(&keyExchange->contents,outputLen + head)))
+        return err;
+
+    uint8_t *charPtr = SSLEncodeHandshakeHeader(ctx, keyExchange, SSL_HdskClientKeyExchange, outputLen);
+
+       charPtr = SSLEncodeSize(charPtr, ctx->pskIdentity.length, 2);
+       memcpy(charPtr, ctx->pskIdentity.data, ctx->pskIdentity.length);
+
+
+    /* We better have a pskSharedSecret already */
+    size_t n=ctx->pskSharedSecret.length;
+
+    if(n==0) return errSSLBadConfiguration;
+
+    if ((err = SSLAllocBuffer(&ctx->preMasterSecret, 2*(n+2))) != 0)
+        return err;
+
+    uint8_t *p=ctx->preMasterSecret.data;
+
+    p = SSLEncodeInt(p, n, 2);
+    memset(p, 0, n); p+=n;
+    p = SSLEncodeInt(p, n, 2);
+    memcpy(p, ctx->pskSharedSecret.data, n);
+
+    dumpBuf("client premaster (PSK)", &ctx->preMasterSecret);
+
+    return errSecSuccess;
 }
 
 }
 
-#pragma mark -
-#pragma mark Public Functions
+
+// MARK: -
+// MARK: Public Functions
 OSStatus
 SSLEncodeServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx)
 {   OSStatus      err;
 OSStatus
 SSLEncodeServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx)
 {   OSStatus      err;
-
-    switch (ctx->selectedCipherSpec.keyExchangeMethod)
+    
+    switch (ctx->selectedCipherSpecParams.keyExchangeMethod)
     {   case SSL_RSA:
         case SSL_RSA_EXPORT:
         #if            APPLE_DH
     {   case SSL_RSA:
         case SSL_RSA_EXPORT:
         #if            APPLE_DH
@@ -1741,18 +1820,18 @@ SSLEncodeServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx)
             break;
         #endif
         default:
             break;
         #endif
         default:
-            return unimpErr;
+            return errSecUnimplemented;
     }
 
     }
 
-    return noErr;
+    return errSecSuccess;
 }
 
 OSStatus
 SSLProcessServerKeyExchange(SSLBuffer message, SSLContext *ctx)
 {
        OSStatus      err;
 }
 
 OSStatus
 SSLProcessServerKeyExchange(SSLBuffer message, SSLContext *ctx)
 {
        OSStatus      err;
-
-    switch (ctx->selectedCipherSpec.keyExchangeMethod) {
+    
+    switch (ctx->selectedCipherSpecParams.keyExchangeMethod) {
                case SSL_RSA:
         case SSL_RSA_EXPORT:
         #if            APPLE_DH
                case SSL_RSA:
         case SSL_RSA_EXPORT:
         #if            APPLE_DH
@@ -1772,7 +1851,7 @@ SSLProcessServerKeyExchange(SSLBuffer message, SSLContext *ctx)
             break;
         #endif
         default:
             break;
         #endif
         default:
-            err = unimpErr;
+            err = errSecUnimplemented;
                        break;
     }
 
                        break;
     }
 
@@ -1782,10 +1861,10 @@ SSLProcessServerKeyExchange(SSLBuffer message, SSLContext *ctx)
 OSStatus
 SSLEncodeKeyExchange(SSLRecord *keyExchange, SSLContext *ctx)
 {   OSStatus      err;
 OSStatus
 SSLEncodeKeyExchange(SSLRecord *keyExchange, SSLContext *ctx)
 {   OSStatus      err;
-
-       assert(ctx->protocolSide == kSSLClientSide);
-
-       switch (ctx->selectedCipherSpec.keyExchangeMethod) {
+    
+    assert(ctx->protocolSide == kSSLClientSide);
+    
+    switch (ctx->selectedCipherSpecParams.keyExchangeMethod) {
                case SSL_RSA:
                case SSL_RSA_EXPORT:
                        sslDebugLog("SSLEncodeKeyExchange: RSA method\n");
                case SSL_RSA:
                case SSL_RSA_EXPORT:
                        sslDebugLog("SSLEncodeKeyExchange: RSA method\n");
@@ -1810,10 +1889,13 @@ SSLEncodeKeyExchange(SSLRecord *keyExchange, SSLContext *ctx)
                        sslDebugLog("SSLEncodeKeyExchange: ECDH method\n");
                        err = SSLEncodeECDHClientKeyExchange(keyExchange, ctx);
                        break;
                        sslDebugLog("SSLEncodeKeyExchange: ECDH method\n");
                        err = SSLEncodeECDHClientKeyExchange(keyExchange, ctx);
                        break;
+        case TLS_PSK:
+            err = SSLEncodePSKClientKeyExchange(keyExchange, ctx);
+            break;
                default:
                default:
-                       sslDebugLog("SSLEncodeKeyExchange: unknown method (%d)\n",
-                                       ctx->selectedCipherSpec.keyExchangeMethod);
-                       err = unimpErr;
+                       sslErrorLog("SSLEncodeKeyExchange: unknown method (%d)\n",
+                                       ctx->selectedCipherSpecParams.keyExchangeMethod);
+                       err = errSecUnimplemented;
        }
 
        return err;
        }
 
        return err;
@@ -1822,187 +1904,66 @@ SSLEncodeKeyExchange(SSLRecord *keyExchange, SSLContext *ctx)
 OSStatus
 SSLProcessKeyExchange(SSLBuffer keyExchange, SSLContext *ctx)
 {   OSStatus      err;
 OSStatus
 SSLProcessKeyExchange(SSLBuffer keyExchange, SSLContext *ctx)
 {   OSStatus      err;
-
-       switch (ctx->selectedCipherSpec.keyExchangeMethod)
-       {   case SSL_RSA:
-               case SSL_RSA_EXPORT:
-                       sslDebugLog("SSLProcessKeyExchange: processing RSA key exchange (%d)\n",
-                                       ctx->selectedCipherSpec.keyExchangeMethod);
-                       if ((err = SSLDecodeRSAKeyExchange(keyExchange, ctx)) != 0)
-                               return err;
-                       break;
-#if            APPLE_DH
-               case SSL_DH_anon:
+    
+    switch (ctx->selectedCipherSpecParams.keyExchangeMethod)
+    {   case SSL_RSA:
+        case SSL_RSA_EXPORT:
+            if ((err = SSLDecodeRSAKeyExchange(keyExchange, ctx)) != 0)
+                return err;
+            break;
+               #if             APPLE_DH
+        case SSL_DH_anon:
                case SSL_DHE_DSS:
                case SSL_DHE_DSS_EXPORT:
                case SSL_DHE_RSA:
                case SSL_DHE_RSA_EXPORT:
                case SSL_DH_anon_EXPORT:
                        sslDebugLog("SSLProcessKeyExchange: processing DH key exchange (%d)\n",
                case SSL_DHE_DSS:
                case SSL_DHE_DSS_EXPORT:
                case SSL_DHE_RSA:
                case SSL_DHE_RSA_EXPORT:
                case SSL_DH_anon_EXPORT:
                        sslDebugLog("SSLProcessKeyExchange: processing DH key exchange (%d)\n",
-                                       ctx->selectedCipherSpec.keyExchangeMethod);
+                                       ctx->selectedCipherSpecParams.keyExchangeMethod);
                        if ((err = SSLDecodeDHClientKeyExchange(keyExchange, ctx)) != 0)
                                return err;
                        break;
 #endif
                        if ((err = SSLDecodeDHClientKeyExchange(keyExchange, ctx)) != 0)
                                return err;
                        break;
 #endif
+        case TLS_PSK:
+                       if ((err = SSLDecodePSKClientKeyExchange(keyExchange, ctx)) != 0)
+                               return err;
+                       break;
                default:
                        sslErrorLog("SSLProcessKeyExchange: unknown keyExchangeMethod (%d)\n",
                default:
                        sslErrorLog("SSLProcessKeyExchange: unknown keyExchangeMethod (%d)\n",
-                                       ctx->selectedCipherSpec.keyExchangeMethod);
-                       return unimpErr;
+                                       ctx->selectedCipherSpecParams.keyExchangeMethod);
+                       return errSecUnimplemented;
        }
 
        }
 
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus
 SSLInitPendingCiphers(SSLContext *ctx)
 {   OSStatus        err;
     SSLBuffer       key;
 }
 
 OSStatus
 SSLInitPendingCiphers(SSLContext *ctx)
 {   OSStatus        err;
     SSLBuffer       key;
-    uint8_t         *keyDataProgress, *keyPtr, *ivPtr;
     int             keyDataLen;
     int             keyDataLen;
-    CipherContext   *serverPending, *clientPending;
-
+        
+    err = errSecSuccess;
     key.data = 0;
 
     key.data = 0;
 
-    ctx->readPending.macRef = ctx->selectedCipherSpec.macAlgorithm;
-    ctx->writePending.macRef = ctx->selectedCipherSpec.macAlgorithm;
-    ctx->readPending.symCipher = ctx->selectedCipherSpec.cipher;
-    ctx->writePending.symCipher = ctx->selectedCipherSpec.cipher;
-
-    if(ctx->negProtocolVersion == DTLS_Version_1_0)
-    {
-        ctx->readPending.sequenceNum.high = (ctx->readPending.sequenceNum.high & (0xffff<<16)) + (1<<16);
-        ctx->writePending.sequenceNum.high = (ctx->writePending.sequenceNum.high & (0xffff<<16)) + (1<<16);
-    } else {
-        ctx->writePending.sequenceNum.high=0;
-        ctx->readPending.sequenceNum.high=0;
-    }
-    ctx->readPending.sequenceNum.low = 0;
-    ctx->writePending.sequenceNum.low = 0;
-
-    keyDataLen = ctx->selectedCipherSpec.macAlgorithm->hash->digestSize +
-                     ctx->selectedCipherSpec.cipher->secretKeySize;
-    if (ctx->selectedCipherSpec.isExportable == NotExportable)
-        keyDataLen += ctx->selectedCipherSpec.cipher->ivSize;
+    keyDataLen = ctx->selectedCipherSpecParams.macSize +
+                    ctx->selectedCipherSpecParams.keySize +
+                    ctx->selectedCipherSpecParams.ivSize;
     keyDataLen *= 2;        /* two of everything */
 
     keyDataLen *= 2;        /* two of everything */
 
-    if ((err = SSLAllocBuffer(&key, keyDataLen, ctx)) != 0)
+    if ((err = SSLAllocBuffer(&key, keyDataLen)))
         return err;
        assert(ctx->sslTslCalls != NULL);
     if ((err = ctx->sslTslCalls->generateKeyMaterial(key, ctx)) != 0)
         goto fail;
         return err;
        assert(ctx->sslTslCalls != NULL);
     if ((err = ctx->sslTslCalls->generateKeyMaterial(key, ctx)) != 0)
         goto fail;
-
-    if (ctx->protocolSide == kSSLServerSide)
-    {   serverPending = &ctx->writePending;
-        clientPending = &ctx->readPending;
-    }
-    else
-    {   serverPending = &ctx->readPending;
-        clientPending = &ctx->writePending;
-    }
-
-    keyDataProgress = key.data;
-    memcpy(clientPending->macSecret, keyDataProgress,
-               ctx->selectedCipherSpec.macAlgorithm->hash->digestSize);
-    keyDataProgress += ctx->selectedCipherSpec.macAlgorithm->hash->digestSize;
-    memcpy(serverPending->macSecret, keyDataProgress,
-               ctx->selectedCipherSpec.macAlgorithm->hash->digestSize);
-    keyDataProgress += ctx->selectedCipherSpec.macAlgorithm->hash->digestSize;
-
-       /* init the reusable-per-record MAC contexts */
-       err = ctx->sslTslCalls->initMac(clientPending, ctx);
-       if(err) {
-               goto fail;
-       }
-       err = ctx->sslTslCalls->initMac(serverPending, ctx);
-       if(err) {
-               goto fail;
-       }
-
-    if (ctx->selectedCipherSpec.isExportable == NotExportable)
-    {   keyPtr = keyDataProgress;
-        keyDataProgress += ctx->selectedCipherSpec.cipher->secretKeySize;
-        /* Skip server write key to get to IV */
-               UInt8 ivSize = ctx->selectedCipherSpec.cipher->ivSize;
-
-               if (ivSize == 0)
-               {
-                       ivPtr = NULL;
-               }
-               else
-               {
-                       ivPtr = keyDataProgress + ctx->selectedCipherSpec.cipher->secretKeySize;
-               }
-
-        if ((err = ctx->selectedCipherSpec.cipher->initialize(keyPtr, ivPtr,
-                                    clientPending, ctx)) != 0)
-            goto fail;
-        keyPtr = keyDataProgress;
-        keyDataProgress += ctx->selectedCipherSpec.cipher->secretKeySize;
-        /* Skip client write IV to get to server write IV */
-               if (ivSize == 0)
-               {
-                       ivPtr = NULL;
-               }
-               else
-               {
-                       ivPtr = keyDataProgress + ctx->selectedCipherSpec.cipher->ivSize;
-               }
-
-        if ((err = ctx->selectedCipherSpec.cipher->initialize(keyPtr, ivPtr,
-                                    serverPending, ctx)) != 0)
-            goto fail;
-    }
-    else {
-        uint8_t                clientExportKey[16], serverExportKey[16],
-                                       clientExportIV[16],  serverExportIV[16];
-        SSLBuffer   clientWrite, serverWrite;
-        SSLBuffer      finalClientWrite, finalServerWrite;
-               SSLBuffer       finalClientIV, finalServerIV;
-
-        assert(ctx->selectedCipherSpec.cipher->keySize <= 16);
-        assert(ctx->selectedCipherSpec.cipher->ivSize <= 16);
-
-               /* Inputs to generateExportKeyAndIv are clientRandom, serverRandom,
-                *    clientWriteKey, serverWriteKey. The first two are already present
-                *    in ctx.
-                * Outputs are a key and IV for each of {server, client}.
-                */
-        clientWrite.data = keyDataProgress;
-        clientWrite.length = ctx->selectedCipherSpec.cipher->secretKeySize;
-        serverWrite.data = keyDataProgress + clientWrite.length;
-        serverWrite.length = ctx->selectedCipherSpec.cipher->secretKeySize;
-               finalClientWrite.data = clientExportKey;
-               finalServerWrite.data   = serverExportKey;
-               finalClientIV.data      = clientExportIV;
-               finalServerIV.data      = serverExportIV;
-               finalClientWrite.length = 16;
-               finalServerWrite.length = 16;
-               /* these can be zero */
-               finalClientIV.length    = ctx->selectedCipherSpec.cipher->ivSize;
-               finalServerIV.length    = ctx->selectedCipherSpec.cipher->ivSize;
-
-               assert(ctx->sslTslCalls != NULL);
-               err = ctx->sslTslCalls->generateExportKeyAndIv(ctx, clientWrite, serverWrite,
-                       finalClientWrite, finalServerWrite, finalClientIV, finalServerIV);
-               if(err) {
-                       goto fail;
-               }
-        if ((err = ctx->selectedCipherSpec.cipher->initialize(clientExportKey,
-                               clientExportIV, clientPending, ctx)) != 0)
-            goto fail;
-        if ((err = ctx->selectedCipherSpec.cipher->initialize(serverExportKey,
-                               serverExportIV, 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 = noErr;
+    
+    if((err = ctx->recFuncs->initPendingCiphers(ctx->recCtx, ctx->selectedCipher, (ctx->protocolSide==kSSLServerSide), key)) != 0)
+        goto fail;
+    
+    ctx->writePending_ready = 1;
+    ctx->readPending_ready = 1;
+    
 fail:
 fail:
-    SSLFreeBuffer(&key, ctx);
+    SSLFreeBuffer(&key);
     return err;
 }
     return err;
 }
index a72fe824f1d0adc1785fb0dd4f42d8f8c918104d..5e80e622b3d48d1fac1905b440d07dede3c81ead 100644 (file)
@@ -39,7 +39,7 @@
 #include <Security/SecPolicy.h>
 #include <Security/SecTrust.h>
 #endif /* !USE_CDSA_CRYPTO */
 #include <Security/SecPolicy.h>
 #include <Security/SecTrust.h>
 #endif /* !USE_CDSA_CRYPTO */
-#include <Security/SecInternal.h>
+#include "utilities/SecCFRelease.h"
 
 #include "sslDebug.h"
 #include "sslKeychain.h"
 
 #include "sslDebug.h"
 #include "sslKeychain.h"
@@ -47,6 +47,9 @@
 #include <string.h>
 #include <assert.h>
 
 #include <string.h>
 #include <assert.h>
 
+#if TARGET_OS_IPHONE
+#include "utilities/SecCFRelease.h"
+#endif
 
 #ifdef USE_SSLCERTIFICATE
 
 
 #ifdef USE_SSLCERTIFICATE
 
@@ -80,16 +83,16 @@ static OSStatus secCertToSslCert(
 
        thisSslCert = (SSLCertificate *)sslMalloc(sizeof(SSLCertificate));
        if(thisSslCert == NULL) {
 
        thisSslCert = (SSLCertificate *)sslMalloc(sizeof(SSLCertificate));
        if(thisSslCert == NULL) {
-               return memFullErr;
+               return errSecAllocate;
        }
        if(SSLAllocBuffer(&thisSslCert->derCert, certData.Length,
                        ctx)) {
        }
        if(SSLAllocBuffer(&thisSslCert->derCert, certData.Length,
                        ctx)) {
-               return memFullErr;
+               return errSecAllocate;
        }
        memcpy(thisSslCert->derCert.data, certData.Data, certData.Length);
        thisSslCert->derCert.length = certData.Length;
        *sslCert = thisSslCert;
        }
        memcpy(thisSslCert->derCert.data, certData.Data, certData.Length);
        thisSslCert->derCert.length = certData.Length;
        *sslCert = thisSslCert;
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -124,7 +127,7 @@ static OSStatus sslCertSignerAlg(
        if(!cssmOidToAlg(&algId->algorithm, &sigAlg)) {
                /* Only way this could happen is if we're given a bad cert */
                sslErrorLog("sslCertSignerAlg() bad sigAlg OID\n");
        if(!cssmOidToAlg(&algId->algorithm, &sigAlg)) {
                /* Only way this could happen is if we're given a bad cert */
                sslErrorLog("sslCertSignerAlg() bad sigAlg OID\n");
-               ortn = paramErr;
+               ortn = errSecParam;
                goto errOut;
        }
 
                goto errOut;
        }
 
@@ -158,7 +161,7 @@ static OSStatus sslCertSignerAlg(
                        break;
                default:
                        sslErrorLog("sslCertSignerAlg() unknown sigAlg\n");
                        break;
                default:
                        sslErrorLog("sslCertSignerAlg() unknown sigAlg\n");
-                       ortn = paramErr;
+                       ortn = errSecParam;
                        break;
        }
 errOut:
                        break;
        }
 errOut:
@@ -222,11 +225,11 @@ parseIncomingCerts(
        identity = (SecIdentityRef)CFArrayGetValueAtIndex(certs, 0);
        if(identity == NULL) {
                sslErrorLog("parseIncomingCerts: bad cert array (1)\n");
        identity = (SecIdentityRef)CFArrayGetValueAtIndex(certs, 0);
        if(identity == NULL) {
                sslErrorLog("parseIncomingCerts: bad cert array (1)\n");
-               return paramErr;
+               return errSecParam;
        }
        if(CFGetTypeID(identity) != SecIdentityGetTypeID()) {
                sslErrorLog("parseIncomingCerts: bad cert array (2)\n");
        }
        if(CFGetTypeID(identity) != SecIdentityGetTypeID()) {
                sslErrorLog("parseIncomingCerts: bad cert array (2)\n");
-               return paramErr;
+               return errSecParam;
        }
 
        /*
        }
 
        /*
@@ -287,11 +290,11 @@ parseIncomingCerts(
                certRef = (SecCertificateRef)CFArrayGetValueAtIndex(certs, cert);
                if(certRef == NULL) {
                        sslErrorLog("parseIncomingCerts: bad cert array (5)\n");
                certRef = (SecCertificateRef)CFArrayGetValueAtIndex(certs, cert);
                if(certRef == NULL) {
                        sslErrorLog("parseIncomingCerts: bad cert array (5)\n");
-                       return paramErr;
+                       return errSecParam;
                }
                if(CFGetTypeID(certRef) != SecCertificateGetTypeID()) {
                        sslErrorLog("parseIncomingCerts: bad cert array (6)\n");
                }
                if(CFGetTypeID(certRef) != SecCertificateGetTypeID()) {
                        sslErrorLog("parseIncomingCerts: bad cert array (6)\n");
-                       return paramErr;
+                       return errSecParam;
                }
 
                /* Extract cert, convert to local format.
                }
 
                /* Extract cert, convert to local format.
@@ -308,7 +311,7 @@ parseIncomingCerts(
 
        /* SUCCESS */
        *destCert = certChain;
 
        /* SUCCESS */
        *destCert = certChain;
-       return noErr;
+       return errSecSuccess;
 
        /* free certChain, everything in it, other vars, return ortn */
        sslDeleteCertificateChain(certChain, ctx);
 
        /* free certChain, everything in it, other vars, return ortn */
        sslDeleteCertificateChain(certChain, ctx);
@@ -335,7 +338,6 @@ parseIncomingCerts(
        SecKeyRef                       pubKey = NULL;          /* Retained */
        SecKeyRef           privKey = NULL;             /* Retained */
        SecTrustRef         trust = NULL;               /* Retained */
        SecKeyRef                       pubKey = NULL;          /* Retained */
        SecKeyRef           privKey = NULL;             /* Retained */
        SecTrustRef         trust = NULL;               /* Retained */
-       SecTrustResultType      trustResult;
 
        assert(ctx != NULL);
        assert(destCertChain != NULL);          /* though its referent may be NULL */
 
        assert(ctx != NULL);
        assert(destCertChain != NULL);          /* though its referent may be NULL */
@@ -363,12 +365,12 @@ parseIncomingCerts(
        identity = (SecIdentityRef)CFArrayGetValueAtIndex(certs, 0);
        if (identity == NULL) {
                sslErrorLog("parseIncomingCerts: bad cert array (1)\n");
        identity = (SecIdentityRef)CFArrayGetValueAtIndex(certs, 0);
        if (identity == NULL) {
                sslErrorLog("parseIncomingCerts: bad cert array (1)\n");
-               ortn = paramErr;
+               ortn = errSecParam;
                goto errOut;
        }
        if (CFGetTypeID(identity) != SecIdentityGetTypeID()) {
                sslErrorLog("parseIncomingCerts: bad cert array (2)\n");
                goto errOut;
        }
        if (CFGetTypeID(identity) != SecIdentityGetTypeID()) {
                sslErrorLog("parseIncomingCerts: bad cert array (2)\n");
-               ortn = paramErr;
+               ortn = errSecParam;
                goto errOut;
        }
 
                goto errOut;
        }
 
@@ -394,7 +396,7 @@ parseIncomingCerts(
        certChain = CFArrayCreateMutable(kCFAllocatorDefault, numCerts,
                &kCFTypeArrayCallBacks);
        if (!certChain) {
        certChain = CFArrayCreateMutable(kCFAllocatorDefault, numCerts,
                &kCFTypeArrayCallBacks);
        if (!certChain) {
-               ortn = memFullErr;
+               ortn = errSecAllocate;
                goto errOut;
        }
        CFArrayAppendValue(certChain, leafCert);
                goto errOut;
        }
        CFArrayAppendValue(certChain, leafCert);
@@ -403,12 +405,12 @@ parseIncomingCerts(
                        (SecCertificateRef)CFArrayGetValueAtIndex(certs, ix);
                if (intermediate == NULL) {
                        sslErrorLog("parseIncomingCerts: bad cert array (5)\n");
                        (SecCertificateRef)CFArrayGetValueAtIndex(certs, ix);
                if (intermediate == NULL) {
                        sslErrorLog("parseIncomingCerts: bad cert array (5)\n");
-                       ortn = paramErr;
+                       ortn = errSecParam;
                        goto errOut;
                }
                if (CFGetTypeID(intermediate) != SecCertificateGetTypeID()) {
                        sslErrorLog("parseIncomingCerts: bad cert array (6)\n");
                        goto errOut;
                }
                if (CFGetTypeID(intermediate) != SecCertificateGetTypeID()) {
                        sslErrorLog("parseIncomingCerts: bad cert array (6)\n");
-                       ortn = paramErr;
+                       ortn = errSecParam;
                        goto errOut;
                }
 
                        goto errOut;
                }
 
@@ -416,7 +418,7 @@ parseIncomingCerts(
        }
 
        /* Obtain public key from cert */
        }
 
        /* Obtain public key from cert */
-#if TARGET_OS_IOS
+#if TARGET_OS_IPHONE
        ortn = SecTrustCreateWithCertificates(certChain, NULL, &trust);
 #else
        {
        ortn = SecTrustCreateWithCertificates(certChain, NULL, &trust);
 #else
        {
@@ -440,18 +442,27 @@ parseIncomingCerts(
                        (int)ortn);
                goto errOut;
        }
                        (int)ortn);
                goto errOut;
        }
-       ortn = SecTrustEvaluate(trust, &trustResult);
-       if (ortn) {
-               sslErrorLog("parseIncomingCerts: SecTrustEvaluate err %d\n",
-                       (int)ortn);
-               goto errOut;
-       }
+
+
+#if !TARGET_OS_IPHONE
+    /* This is not required on iOS, but still required on osx */
+    SecTrustResultType trustResult;
+    ortn = SecTrustEvaluate(trust, &trustResult);
+    if (ortn) {
+        sslErrorLog("parseIncomingCerts: SecTrustEvaluate err %d\n",
+                    (int)ortn);
+        goto errOut;
+    }
+#endif
+
+
        pubKey = SecTrustCopyPublicKey(trust);
        pubKey = SecTrustCopyPublicKey(trust);
-       if (pubKey == NULL) {
-               sslErrorLog("parseIncomingCerts: SecTrustCopyPublicKey failed\n");
-               ortn = -67712; // errSecInvalidKeyRef
-               goto errOut;
-       }
+    if (!pubKey) {
+        /* We parsed the private key succesfully but could not get the public key: return an error */
+        sslErrorLog("parseIncomingCerts: SecTrustCopyPublicKey failed\n");
+        ortn = errSecParam;
+        goto errOut;
+    }
 
        /* SUCCESS */
 errOut:
 
        /* SUCCESS */
 errOut:
index e56afbd8c0abc0acb65642a3ecaafebba90b491a..5e88deaeeb85bbb69f1390b005173c3ff3a0fadb 100644 (file)
  * sslMemory.c - Memory allocator implementation
  */
 
  * sslMemory.c - Memory allocator implementation
  */
 
+/* THIS FILE CONTAINS KERNEL CODE */
+
 #include "sslMemory.h"
 #include "sslMemory.h"
-#include "sslContext.h"
 #include "sslDebug.h"
 
 #include "sslDebug.h"
 
-#pragma mark -
-#pragma mark Basic low-level malloc/free
+#include <string.h>                    /* memset */
+#include <AssertMacros.h>
+
+// MARK: -
+// MARK: Basic low-level malloc/free
 
 /*
  * For now, all allocs/frees go thru here.
  */
 
 /*
  * For now, all allocs/frees go thru here.
  */
-#include <string.h>                    /* memset */
+
+#ifdef KERNEL
+
+/* BSD Malloc */
+#include <sys/malloc.h>
+#include <IOKit/IOLib.h>
+#include <libkern/libkern.h>
+
+/* Define this for debugging sslMalloc and sslFree */
+//#define SSL_CANARIS
+
+void *
+sslMalloc(size_t length)
+{
+    void *p;
+
+#ifdef SSL_CANARIS
+    length+=8;
+#endif
+    
+    p = _MALLOC(length, M_TEMP, M_WAITOK);
+    check(p);
+    
+    if(p==NULL)
+        return p;
+    
+#ifdef SSL_CANARIS
+    *(uint32_t *)p=(uint32_t)length-8;
+    printf("sslMalloc @%p of 0x%08lx bytes\n", p, length-8);
+    *(uint32_t *)(p+length-4)=0xdeadbeed;
+    p+=4;
+#endif
+
+    return p;
+}
+
+void
+sslFree(void *p)
+{
+       if(p != NULL) {
+
+#ifdef SSL_CANARIS
+        p=p-4;
+        uint32_t len=*(uint32_t *)p;
+        uint32_t marker=*(uint32_t *)(p+4+len);
+        printf("sslFree @%p len=0x%08x\n", p, len);
+        if(marker!=0xdeadbeef)
+            panic("Buffer overflow in SSL!\n");
+#endif
+        
+        _FREE(p, M_TEMP);
+       }
+}
+
+void *
+sslRealloc(void *oldPtr, size_t oldLen, size_t newLen)
+{
+    /* _REALLOC is in sys/malloc.h but is only exported in debug kernel */
+    /* return _REALLOC(oldPtr, newLen, M_TEMP, M_NOWAIT); */
+
+    /* FIXME */
+    void *newPtr;
+    if(newLen>oldLen) {
+        newPtr=sslMalloc(newLen);
+        if(newPtr) {
+            memcpy(newPtr, oldPtr, oldLen);
+            sslFree(oldPtr);
+        }
+    } else {
+        newPtr=oldPtr;
+    }
+    return newPtr;
+}
+
+#else
+
 #include <stdlib.h>
 
 void *
 #include <stdlib.h>
 
 void *
@@ -46,8 +125,8 @@ sslMalloc(size_t length)
 
 void
 sslFree(void *p)
 
 void
 sslFree(void *p)
-{
-       if(p != nil) {
+{   
+       if(p != NULL) {
                free(p);
        }
 }
                free(p);
        }
 }
@@ -58,58 +137,64 @@ sslRealloc(void *oldPtr, size_t oldLen, size_t newLen)
        return realloc(oldPtr, newLen);
 }
 
        return realloc(oldPtr, newLen);
 }
 
-#pragma mark -
-#pragma mark SSLBuffer-level alloc/free
+#endif
 
 
-OSStatus SSLAllocBuffer(
+// MARK: -
+// MARK: SSLBuffer-level alloc/free
+
+int SSLAllocBuffer(
        SSLBuffer *buf,
        SSLBuffer *buf,
-       size_t length,
-       const SSLContext *ctx)                  // currently unused
+       size_t length)
 {
 {
-       buf->data = (UInt8 *)sslMalloc(length);
+       buf->data = (uint8_t *)sslMalloc(length);
        if(buf->data == NULL) {
        if(buf->data == NULL) {
+        sslErrorLog("SSLAllocBuffer: NULL buf!\n");
+        check(0);
                buf->length = 0;
                buf->length = 0;
-               return memFullErr;
+               return -1;
        }
     buf->length = length;
        }
     buf->length = length;
-    return noErr;
+    return 0;
 }
 
 }
 
-OSStatus
-SSLFreeBuffer(SSLBuffer *buf, const SSLContext *ctx)
-{
+int
+SSLFreeBuffer(SSLBuffer *buf)
+{   
        if(buf == NULL) {
                sslErrorLog("SSLFreeBuffer: NULL buf!\n");
        if(buf == NULL) {
                sslErrorLog("SSLFreeBuffer: NULL buf!\n");
-               return errSSLInternal;
+        check(0);
+               return -1;
        }
     sslFree(buf->data);
     buf->data = NULL;
     buf->length = 0;
        }
     sslFree(buf->data);
     buf->data = NULL;
     buf->length = 0;
-    return noErr;
+    return 0;
 }
 
 }
 
-OSStatus
-SSLReallocBuffer(SSLBuffer *buf, size_t newSize, const SSLContext *ctx)
-{
-       buf->data = (UInt8 *)sslRealloc(buf->data, buf->length, newSize);
+int
+SSLReallocBuffer(SSLBuffer *buf, size_t newSize)
+{   
+       buf->data = (uint8_t *)sslRealloc(buf->data, buf->length, newSize);
        if(buf->data == NULL) {
        if(buf->data == NULL) {
+        sslErrorLog("SSLReallocBuffer: NULL buf!\n");
+        check(0);
                buf->length = 0;
                buf->length = 0;
-               return memFullErr;
+               return -1;
        }
        buf->length = newSize;
        }
        buf->length = newSize;
-       return noErr;
+       return 0;
 }
 
 }
 
-#pragma mark -
-#pragma mark Convenience routines
+// MARK: -
+// MARK: Convenience routines
 
 
-UInt8 *sslAllocCopy(
-       const UInt8 *src,
+uint8_t *sslAllocCopy(
+       const uint8_t *src,
        size_t len)
 {
        size_t len)
 {
-       UInt8 *dst;
-
-       dst = (UInt8 *)sslMalloc(len);
+       uint8_t *dst;
+       
+       dst = (uint8_t *)sslMalloc(len);
        if(dst == NULL) {
                return NULL;
        }
        if(dst == NULL) {
                return NULL;
        }
@@ -117,15 +202,17 @@ UInt8 *sslAllocCopy(
        return dst;
 }
 
        return dst;
 }
 
-OSStatus SSLAllocCopyBuffer(
-       const SSLBuffer *src,
-       SSLBuffer **dst)                // buffer and data mallocd and returned
-{
-       OSStatus serr;
-
+int SSLAllocCopyBuffer(
+       const SSLBuffer *src, 
+       SSLBuffer **dst)                // buffer and data mallocd and returned 
+{   
+       int serr;
+       
        SSLBuffer *rtn = (SSLBuffer *)sslMalloc(sizeof(SSLBuffer));
        if(rtn == NULL) {
        SSLBuffer *rtn = (SSLBuffer *)sslMalloc(sizeof(SSLBuffer));
        if(rtn == NULL) {
-               return memFullErr;
+        sslErrorLog("SSLAllocCopyBuffer: NULL buf!\n");
+        check(0);
+               return -1;
        }
        serr = SSLCopyBuffer(src, rtn);
        if(serr) {
        }
        serr = SSLCopyBuffer(src, rtn);
        if(serr) {
@@ -137,23 +224,25 @@ OSStatus SSLAllocCopyBuffer(
        return serr;
 }
 
        return serr;
 }
 
-OSStatus SSLCopyBufferFromData(
+int SSLCopyBufferFromData(
        const void *src,
        size_t len,
        const void *src,
        size_t len,
-       SSLBuffer *dst)         // data mallocd and returned
-{
-       dst->data = sslAllocCopy((const UInt8 *)src, len);
+       SSLBuffer *dst)         // data mallocd and returned 
+{   
+       dst->data = sslAllocCopy((const uint8_t *)src, len);
        if(dst->data == NULL) {
        if(dst->data == NULL) {
-               return memFullErr;
+        sslErrorLog("SSLCopyBufferFromData: NULL buf!\n");
+        check(0);
+               return -1;
        }
     dst->length = len;
        }
     dst->length = len;
-    return noErr;
+    return 0;
 }
 
 }
 
-OSStatus SSLCopyBuffer(
-       const SSLBuffer *src,
-       SSLBuffer *dst)         // data mallocd and returned
-{
+int SSLCopyBuffer(
+       const SSLBuffer *src, 
+       SSLBuffer *dst)         // data mallocd and returned 
+{   
        return SSLCopyBufferFromData(src->data, src->length, dst);
 }
 
        return SSLCopyBufferFromData(src->data, src->length, dst);
 }
 
index 1defb2d3956bd3edf54324bca6e9b96242495a03..132670e812ea9cbf691e1497a7661c1723d935d8 100644 (file)
  */
 
 /*
  */
 
 /*
- * sslMemory.h - Memory allocator declarations
+ * sslMemory.h - SSLBuffer and Memory allocator declarations
  */
 
  */
 
+/* This header should be kernel safe */
+
 #ifndef _SSLMEMORY_H_
 #define _SSLMEMORY_H_ 1
 
 #ifndef _SSLMEMORY_H_
 #define _SSLMEMORY_H_ 1
 
-#include "sslContext.h"
-#include "sslPriv.h"
+#include "sslTypes.h"
 
 #ifdef __cplusplus
 extern "C" {
 
 #ifdef __cplusplus
 extern "C" {
@@ -45,27 +46,29 @@ void *sslRealloc(void *oldPtr, size_t oldLen, size_t newLen);
 /*
  * SSLBuffer-oriented allocators
  */
 /*
  * SSLBuffer-oriented allocators
  */
-OSStatus SSLAllocBuffer(SSLBuffer *buf, size_t length, const SSLContext *ctx);
-OSStatus SSLFreeBuffer(SSLBuffer *buf, const SSLContext *ctx);
-OSStatus SSLReallocBuffer(SSLBuffer *buf, size_t newSize, const SSLContext *ctx);
+int SSLAllocBuffer(SSLBuffer *buf, size_t length);
+int SSLFreeBuffer(SSLBuffer *buf);
+int SSLReallocBuffer(SSLBuffer *buf, size_t newSize);
 
 /*
  * Convenience routines
  */
 
 /*
  * Convenience routines
  */
-UInt8 *sslAllocCopy(const UInt8 *src, size_t len);
-OSStatus SSLAllocCopyBuffer(
-       const SSLBuffer *src,
-       SSLBuffer **dst);               // buffer itself and data mallocd and returned
-OSStatus SSLCopyBufferFromData(
+uint8_t *sslAllocCopy(const uint8_t *src, size_t len);
+int SSLAllocCopyBuffer(
+       const SSLBuffer *src, 
+       SSLBuffer **dst);               // buffer itself and data mallocd and returned 
+int SSLCopyBufferFromData(
        const void *src,
        size_t len,
        const void *src,
        size_t len,
-       SSLBuffer *dst);                // data mallocd and returned
-OSStatus SSLCopyBuffer(
-       const SSLBuffer *src,
+       SSLBuffer *dst);                // data mallocd and returned 
+int SSLCopyBuffer(
+       const SSLBuffer *src, 
        SSLBuffer *dst);                // data mallocd and returned
 
 #ifdef __cplusplus
 }
 #endif
 
        SSLBuffer *dst);                // data mallocd and returned
 
 #ifdef __cplusplus
 }
 #endif
 
+#define SET_SSL_BUFFER(buf, d, l)   do { (buf).data = (d); (buf).length = (l); } while (0)
+
 #endif
 #endif
index 29b7273b745a36645ffe38fec73627ab287a2df5..8c5bfa606976a408899ef7b20dbe5133d15d9d2d 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
-#include "sslContext.h"
+/* THIS FILE CONTAINS KERNEL CODE */
 
 
-#include <string.h>
+#include "symCipher.h"
 
 
-static OSStatus NullInit(
-       uint8_t *key,
-       uint8_t *iv,
-       CipherContext *cipherCtx,
-       SSLContext *ctx);
-static OSStatus NullCrypt(
-       const uint8_t *src,
-       uint8_t *dest,
-    size_t len,
-       CipherContext *cipherCtx,
-       SSLContext *ctx);
-static OSStatus NullFinish(
-       CipherContext *cipherCtx,
-       SSLContext *ctx);
-
-extern const SSLSymmetricCipher SSLCipherNull;
+#include <string.h>
 
 
-const SSLSymmetricCipher SSLCipherNull = {
-    0,          /* Key size in bytes (ignoring parity) */
-    0,          /* Secret key size */
-    0,          /* IV size */
-    0,          /* Block size */
-    -1,         /* CC cipher (unused by Null*) */
-    NullInit,
-    NullCrypt,
-    NullCrypt,
-    NullFinish
+const SSLSymmetricCipherParams SSLCipherNullParams = {
+    .keyAlg = SSL_CipherAlgorithmNull,
+    .ivSize = 0,
+    .blockSize = 0,
+    .keySize = 0,
+    .cipherType = streamCipherType,
 };
 
 };
 
-static OSStatus NullInit(
+static int NullInit(
+    const SSLSymmetricCipherParams *cipher,
+    int encrypting,
        uint8_t *key,
        uint8_t *iv,
        uint8_t *key,
        uint8_t *iv,
-       CipherContext *cipherCtx,
-       SSLContext *ctx)
+       SymCipherContext *cipherCtx)
 {
 {
-       return noErr;
+       return 0;
 }
 
 }
 
-static OSStatus NullCrypt(
-       const uint8_t *src,
+static int NullCrypt(
+       const uint8_t *src, 
        uint8_t *dest,
     size_t len,
        uint8_t *dest,
     size_t len,
-       CipherContext *cipherCtx,
-       SSLContext *ctx)
-{
+       SymCipherContext cipherCt)
+{   
        if (src != dest)
         memcpy(dest, src, len);
        if (src != dest)
         memcpy(dest, src, len);
-    return noErr;
+    return 0;
 }
 
 }
 
-static OSStatus NullFinish(
-       CipherContext *cipherCtx,
-       SSLContext *ctx)
-{
-       return noErr;
+static int NullFinish(
+       SymCipherContext cipherCtx)
+{   
+       return 0;
 }
 }
+
+const SSLSymmetricCipher SSLCipherNull = {
+    .params = &SSLCipherNullParams,
+    .c.cipher = {
+        .initialize = NullInit,
+        .encrypt = NullCrypt,
+        .decrypt = NullCrypt
+    },
+    .finish = NullFinish
+};
index 84b505df96cbff4a3ceb81b7af97531705b9beeb..444726bad80d00317f4e398e728c61f2ee864907 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "sslBuildFlags.h"
 #include "SecureTransportPriv.h"
 
 #include "sslBuildFlags.h"
 #include "SecureTransportPriv.h"
+#include "sslTypes.h"
 
 #ifdef __cplusplus
 extern "C" {
 
 #ifdef __cplusplus
 extern "C" {
@@ -45,39 +46,7 @@ extern "C" {
 #define SSL_ECDSA_SERVER       0
 
 /*
 #define SSL_ECDSA_SERVER       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
-{   size_t  length;
-    uint8_t *data;
-} SSLBuffer;
-
-/*
- * We can make this more Mac-like as well...
- */
-typedef struct
-{   uint32_t  high;
-    uint32_t  low;
-}   sslUint64;
-
-
-typedef enum
-{
-       /* This value never appears in the actual protocol */
-       SSL_Version_Undetermined = 0,
-       /* actual protocol values */
-    SSL_Version_2_0 = 0x0002,
-    SSL_Version_3_0 = 0x0300,
-       TLS_Version_1_0 = 0x0301,               /* TLS 1.0 == SSL 3.1 */
-    TLS_Version_1_1 = 0x0302,
-    TLS_Version_1_2 = 0x0303,
-    DTLS_Version_1_0 = 0xfeff,
-} SSLProtocolVersion;
-
-/*
- * Clients see an opaque SSLContextRef; internal code uses the
+ * Clients see an opaque SSLContextRef; internal code uses the 
  * following typedef.
  */
 typedef struct SSLContext SSLContext;
  * following typedef.
  */
 typedef struct SSLContext SSLContext;
diff --git a/libsecurity_ssl/lib/sslRand.c b/libsecurity_ssl/lib/sslRand.c
new file mode 100644 (file)
index 0000000..0c221c0
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 1999-2001,2005-2008,2010-2011 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * sslRand.c - Randomness
+ */
+
+/* THIS FILE CONTAINS KERNEL CODE */
+
+#include "sslRand.h"
+#include "sslDebug.h"
+#include <AssertMacros.h>
+
+#ifdef KERNEL
+
+void read_random(void* buffer, u_int numBytes);
+
+#else
+
+#include <TargetConditionals.h>
+
+#ifdef TARGET_OS_EMBEDDED
+#include <Security/SecRandom.h>
+#else
+static
+int sslRandMacOSX(void *data, size_t len)
+{
+    static int random_fd = -1;
+
+    if (random_fd == -1) {
+        random_fd = open("/dev/random", O_RDONLY);
+        if (random_fd == -1) {
+            sslErrorLog("sslRand: error opening /dev/random: %s\n",
+                        strerror(errno));
+            return -1;
+        }
+    }
+
+    ssize_t bytesRead = read(random_fd, data, len);
+    if (bytesRead != len) {
+        sslErrorLog("sslRand: error reading %lu bytes from /dev/random: %s\n",
+                    len, strerror(errno));
+        serr = -1;
+    }
+
+    return serr;
+}
+#endif /* TARGET_OS_EMBEDDED */
+
+#endif /* KERNEL */
+
+/*
+ * Common RNG function.
+ */
+int sslRand(SSLBuffer *buf)
+{
+       check(buf != NULL);
+       check(buf->data != NULL);
+
+       if(buf->length == 0) {
+               sslErrorLog("sslRand: zero buf->length\n");
+               return 0;
+       }
+
+#ifdef KERNEL
+    read_random(buf->data, (u_int)buf->length);
+    return 0;
+#else
+#ifdef TARGET_OS_EMBEDDED
+       return SecRandomCopyBytes(kSecRandomDefault, buf->length, buf->data);
+#else
+    return sslRandMacOSX(ctx, buf);
+#endif
+#endif
+}
diff --git a/libsecurity_ssl/lib/sslRand.h b/libsecurity_ssl/lib/sslRand.h
new file mode 100644 (file)
index 0000000..f2f1544
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2000-2001,2005-2007,2010-2011 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * sslRand.h
+ */
+
+#ifndef _SSLRAND_H_
+#define _SSLRAND_H_ 1
+
+#include "sslTypes.h"
+
+/*
+ * Common RNG function.
+ */
+int sslRand(SSLBuffer *buf);
+
+#endif
index f426cf23ed0f3a8edbc770a1570000b53f2cb3c0..35f58180a894a8675f119f10b09b01630b51a208 100644 (file)
  * sslRecord.c - Encryption, decryption and MACing of data
 */
 
  * sslRecord.c - Encryption, decryption and MACing of data
 */
 
+#include <SecureTransport.h>
 #include "ssl.h"
 #include "ssl.h"
-
 #include "sslRecord.h"
 #include "sslMemory.h"
 #include "sslRecord.h"
 #include "sslMemory.h"
-#include "cryptType.h"
 #include "sslContext.h"
 #include "sslAlertMessage.h"
 #include "sslDebug.h"
 #include "sslUtils.h"
 #include "sslDigests.h"
 #include "sslContext.h"
 #include "sslAlertMessage.h"
 #include "sslDebug.h"
 #include "sslUtils.h"
 #include "sslDigests.h"
+#include "SSLRecordInternal.h"
 
 #include <string.h>
 #include <assert.h>
 
 
 #include <string.h>
 #include <assert.h>
 
+#include <utilities/SecIOFormat.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
 /*
  * 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
  */
 #define SSL_ALLOW_UNNOTICED_DISCONNECT 1
 
  */
 #define SSL_ALLOW_UNNOTICED_DISCONNECT 1
 
-/* ReadSSLRecord
- *  Attempt to read & decrypt an SSL record.
- */
-OSStatus
-SSLReadRecord(SSLRecord *rec, SSLContext *ctx)
-{   OSStatus        err;
-    size_t          len, contentLen;
-    UInt8           *charPtr;
-    SSLBuffer       readData, cipherFragment;
-    size_t          head=5;
-    int             skipit=0;
 
 
-#if ENABLE_DTLS
-    if(ctx->isDTLS)
-        head+=8;
-#endif
-
-    if (!ctx->partialReadBuffer.data || ctx->partialReadBuffer.length < head)
-    {   if (ctx->partialReadBuffer.data)
-            if ((err = SSLFreeBuffer(&ctx->partialReadBuffer, ctx)) != 0)
-            {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
-                return err;
-            }
-        if ((err = SSLAllocBuffer(&ctx->partialReadBuffer,
-                               DEFAULT_BUFFER_SIZE, ctx)) != 0)
-        {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
-            return err;
-        }
-    }
-
-    if (ctx->negProtocolVersion == SSL_Version_Undetermined) {
-        if (ctx->amountRead < 1)
-        {   readData.length = 1 - ctx->amountRead;
-            readData.data = ctx->partialReadBuffer.data + ctx->amountRead;
-            len = readData.length;
-            err = sslIoRead(readData, &len, ctx);
-            if(err != 0)
-            {   if (err == errSSLWouldBlock) {
-                                       ctx->amountRead += len;
-                                       return err;
-                               }
-                else {
-                                       /* abort */
-                                       err = errSSLClosedAbort;
-                                       if((ctx->protocolSide == kSSLClientSide) &&
-                                          (ctx->amountRead == 0) &&
-                                          (len == 0)) {
-                                               /*
-                                                * Detect "server refused to even try to negotiate"
-                                                * error, when the server drops the connection before
-                                                * sending a single byte.
-                                                */
-                                               switch(ctx->state) {
-                                                       case SSL_HdskStateServerHello:
-                                                       case SSL_HdskStateServerHelloUnknownVersion:
-                                                               sslHdskStateDebug("Server dropped initial connection\n");
-                                                               err = errSSLConnectionRefused;
-                                                               break;
-                                                       default:
-                                                               break;
-                                               }
-                                       }
-                    SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
-                                       return err;
-                               }
-            }
-            ctx->amountRead += len;
-        }
-    }
-
-    if (ctx->amountRead < head)
-    {   readData.length = head - ctx->amountRead;
-        readData.data = ctx->partialReadBuffer.data + ctx->amountRead;
-        len = readData.length;
-        err = sslIoRead(readData, &len, ctx);
-        if(err != 0)
-        {
-                       switch(err) {
-                               case errSSLWouldBlock:
-                                       ctx->amountRead += len;
-                                       break;
-                               #if     SSL_ALLOW_UNNOTICED_DISCONNECT
-                               case errSSLClosedGraceful:
-                                       /* 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 == SSL_HdskStateClientReady)) {  /* handshake done */
-                                           /*
-                                                * This means that the server has disconnected 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 errSSLClosedGraceful error. Paranoid
-                                                * clients can detect it and handle it however they
-                                                * want to.
-                                                */
-                                               SSLChangeHdskState(ctx, SSL_HdskStateNoNotifyClose);
-                                               err = errSSLClosedNoNotify;
-                                               break;
-                                       }
-                                       else {
-                                               /* illegal disconnect */
-                                               err = errSSLClosedAbort;
-                                               /* and drop thru to default: fatal alert */
-                                       }
-                               #endif  /* SSL_ALLOW_UNNOTICED_DISCONNECT */
-                               default:
-                                       SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
-                                       break;
-                               }
-            return err;
-        }
-        ctx->amountRead += len;
-    }
-
-    assert(ctx->amountRead >= head);
-
-    charPtr = ctx->partialReadBuffer.data;
-    rec->contentType = *charPtr++;
-    if (rec->contentType < SSL_RecordTypeV3_Smallest ||
-        rec->contentType > SSL_RecordTypeV3_Largest)
-        return errSSLProtocol;
-
-    rec->protocolVersion = (SSLProtocolVersion)SSLDecodeInt(charPtr, 2);
-    charPtr += 2;
-
-#if ENABLE_DTLS
-    if(rec->protocolVersion == DTLS_Version_1_0)
-    {
-        sslUint64 seqNum;
-        SSLDecodeUInt64(charPtr, 8, &seqNum);
-        charPtr += 8;
-        sslLogRecordIo("Read DTLS Record %08x_%08x (seq is: %08x_%08x)",
-               seqNum.high, seqNum.low,
-               ctx->readCipher.sequenceNum.high,ctx->readCipher.sequenceNum.low);
-
-        /* if the epoch of the record is different of current read cipher, just drop it */
-        if((seqNum.high>>8)!=(ctx->readCipher.sequenceNum.high>>8)) {
-            skipit=1;
-        } else {
-            ctx->readCipher.sequenceNum.high=seqNum.high;
-            ctx->readCipher.sequenceNum.low=seqNum.low;
-        }
-    }
-#endif
-
-    contentLen = SSLDecodeInt(charPtr, 2);
-    charPtr += 2;
-    if (contentLen > (16384 + 2048))    /* Maximum legal length of an
-                                                                                * SSLCipherText payload */
-    {   SSLFatalSessionAlert(SSL_AlertRecordOverflow, ctx);
-        return errSSLProtocol;
+static OSStatus errorTranslate(int recordErr)
+{
+    switch(recordErr) {
+        case errSecSuccess:
+            return errSecSuccess;
+        case errSSLRecordInternal:
+            return errSSLInternal;
+        case errSSLRecordWouldBlock:
+            return errSSLWouldBlock;
+        case errSSLRecordProtocol:
+            return errSSLProtocol;
+        case errSSLRecordNegotiation:
+            return errSSLNegotiation;
+        case errSSLRecordClosedAbort:
+            return errSSLClosedAbort;
+        case errSSLRecordConnectionRefused:
+            return errSSLConnectionRefused;
+        case errSSLRecordDecryptionFail:
+            return errSSLDecryptionFail;
+        case errSSLRecordBadRecordMac:
+            return errSSLBadRecordMac;
+        case errSSLRecordRecordOverflow:
+            return errSSLRecordOverflow;
+        case errSSLRecordUnexpectedRecord:
+            return errSSLUnexpectedRecord;
+        default:
+            sslErrorLog("unknown error code returned in sslErrorTranslate: %d\n", recordErr);
+            return recordErr;
     }
     }
+}
 
 
-    /* Dont check this if we are going to drop an old packet:
-      we dont know if the digestSize is the correct one */
-       if (!skipit && contentLen < ctx->readCipher.macRef->hash->digestSize)
-       {
-               SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
-               return errSSLClosedAbort;
-       }
+/* SSLWriteRecord
+ *  Attempt to encrypt and queue an SSL record.
+ */
+OSStatus
+SSLWriteRecord(SSLRecord rec, SSLContext *ctx)
+{
+    OSStatus    err;
 
 
-    if (ctx->partialReadBuffer.length < head + contentLen)
-    {   if ((err = SSLReallocBuffer(&ctx->partialReadBuffer, head + contentLen, ctx)) != 0)
-        {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
-            return err;
-        }
-    }
+    err=errorTranslate(ctx->recFuncs->write(ctx->recCtx, rec));
 
 
-    if (ctx->amountRead < head + contentLen)
-    {   readData.length = head + contentLen - ctx->amountRead;
-        readData.data = ctx->partialReadBuffer.data + ctx->amountRead;
-        len = readData.length;
-        err = sslIoRead(readData, &len, ctx);
-        if(err != 0)
-        {   if (err == errSSLWouldBlock)
-                ctx->amountRead += len;
-            else
-                SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
-            return err;
-        }
-        ctx->amountRead += len;
+    switch(err) {
+        case errSecSuccess:
+            break;
+        default:
+            sslErrorLog("unexpected error code returned in SSLWriteRecord: %d\n", (int)err);
+            break;
     }
 
     }
 
-    assert(ctx->amountRead >= head + contentLen);
-
-    cipherFragment.data = ctx->partialReadBuffer.data + head;
-    cipherFragment.length = contentLen;
-
-    ctx->amountRead = 0;        /* We've used all the data in the cache */
+    return err;
+}
 
 
-    /* We dont decrypt if we were told to skip this record */
-    if(skipit) {
-        DTLSRetransmit(ctx);
-        return errSSLWouldBlock;
-    }
-       /*
-        * 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).
-        */
-       assert(ctx->sslTslCalls != NULL);
-    if ((err = ctx->sslTslCalls->decryptRecord(rec->contentType,
-                       &cipherFragment, ctx)) != 0)
-        return err;
+/* SSLFreeRecord
+ *  Free a record returned by SSLReadRecord.
+ */
+OSStatus
+SSLFreeRecord(SSLRecord rec, SSLContext *ctx)
+{
+    return ctx->recFuncs->free(ctx->recCtx, rec);
+}
 
 
-       /*
-        * We appear to have sucessfully received a record; increment the
-        * sequence number
-        */
-    IncrementUInt64(&ctx->readCipher.sequenceNum);
+/* SSLReadRecord
+ *  Attempt to read & decrypt an SSL record.
+ *  Record content should be freed using SSLFreeRecord
+ */
+OSStatus
+SSLReadRecord(SSLRecord *rec, SSLContext *ctx)
+{   OSStatus        err;
 
 
-       /* Allocate a buffer to return the plaintext in and return it */
-    if ((err = SSLAllocBuffer(&rec->contents, cipherFragment.length, ctx)) != 0)
-    {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
-        return err;
+    err=errorTranslate(ctx->recFuncs->read(ctx->recCtx, rec));
+
+    switch(err) {
+        case errSecSuccess:
+        case errSSLWouldBlock:
+            break;
+        case errSSLUnexpectedRecord:
+            DTLSRetransmit(ctx);
+            break;
+        case errSSLDecryptionFail:
+        case errSSLBadRecordMac:
+            /* We never send a Decryption Failed alert, instead we send the BadRecordMac alert */
+            /* This is TLS 1.1 compliant - Do it for all protocols versions. */
+            /* Except for DTLS where we do not send any alert. */
+            if(ctx->isDTLS) {
+                /* This will ensure we try to read again before returning to the caller
+                   We do NOT want to use errSSLWouldBlock here, as this should only indicate
+                   the IO read callback status */
+                err=errSSLUnexpectedRecord;
+            } else {
+                SSLFatalSessionAlert(SSL_AlertBadRecordMac, ctx);
+            }
+            break;
+        case errSSLInternal:
+            SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
+            break;
+        case errSSLRecordOverflow:
+            SSLFatalSessionAlert(SSL_AlertRecordOverflow, ctx);
+            break;
+        case errSSLClosedAbort:
+        case errSSLConnectionRefused:
+            SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+            break;
+        default:
+            sslErrorLog("unknown error code returned in SSLReadRecord: %d\n", (int)err);
+            SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+            break;
     }
     }
-    memcpy(rec->contents.data, cipherFragment.data, cipherFragment.length);
-
 
 
-    return noErr;
+    return err;
 }
 
 }
 
-/* common for sslv3 and tlsv1, except for the computeMac callout */
-OSStatus SSLVerifyMac(
-       UInt8 type,
-       SSLBuffer *data,
-       UInt8 *compareMAC,
-       SSLContext *ctx)
+OSStatus SSLServiceWriteQueue(SSLContext *ctx)
 {
 {
-       OSStatus        err;
-    UInt8           macData[SSL_MAX_DIGEST_LEN];
-    SSLBuffer       secret, mac;
-
-    secret.data = ctx->readCipher.macSecret;
-    secret.length = ctx->readCipher.macRef->hash->digestSize;
-    mac.data = macData;
-    mac.length = ctx->readCipher.macRef->hash->digestSize;
-
-       assert(ctx->sslTslCalls != NULL);
-    if ((err = ctx->sslTslCalls->computeMac(type,
-                       *data,
-                       mac,
-                       &ctx->readCipher,
-                       ctx->readCipher.sequenceNum,
-                       ctx)) != 0)
-        return err;
-
-    if ((memcmp(mac.data, compareMAC, mac.length)) != 0) {
-               sslErrorLog("ssl3VerifyMac: Mac verify failure\n");
-        return errSSLProtocol;
-    }
-    return noErr;
+    return errorTranslate(ctx->recFuncs->serviceWriteQueue(ctx->recCtx));
 }
 }
-
-
index 5a2d3b0b8b9c7bcb55f36298b53b5dedc93a309d..6f46807470a9e93242f5bdcfde93a8850bb33b1c 100644 (file)
 extern "C" {
 #endif
 
 extern "C" {
 #endif
 
-enum
-{   SSL_RecordTypeV2_0,
-    SSL_RecordTypeV3_Smallest = 20,
-    SSL_RecordTypeChangeCipher = 20,
-    SSL_RecordTypeAlert = 21,
-    SSL_RecordTypeHandshake = 22,
-    SSL_RecordTypeAppData = 23,
-    SSL_RecordTypeV3_Largest = 23
-};
-
-typedef struct
-{   UInt8                   contentType;
-    SSLProtocolVersion      protocolVersion;
-    SSLBuffer               contents;
-} SSLRecord;
-
-/*
- * Slightly smaller that 16384 to make room for a MAC in an SSL 2.0
- * 3-byte header record
+/* 
+ * Slightly smaller that 16384 to make room for a MAC in an SSL 2.0 
+ * 3-byte header record 
  */
 #define MAX_RECORD_LENGTH   16300
 
  */
 #define MAX_RECORD_LENGTH   16300
 
-#define DEFAULT_BUFFER_SIZE 4096
+OSStatus SSLWriteRecord(
+    SSLRecord  rec,
+    SSLContext         *ctx);
+
+OSStatus SSLFreeRecord(
+    SSLRecord  rec,
+    SSLContext         *ctx);
 
 OSStatus SSLReadRecord(
        SSLRecord       *rec,
        SSLContext      *ctx);
 
 
 OSStatus SSLReadRecord(
        SSLRecord       *rec,
        SSLContext      *ctx);
 
-OSStatus SSLVerifyMac(
-       UInt8           type,
-       SSLBuffer       *data,
-       UInt8           *compareMAC,
-       SSLContext      *ctx);
+OSStatus SSLServiceWriteQueue(
+    SSLContext  *ctx);
 
 #ifdef __cplusplus
 }
 
 #ifdef __cplusplus
 }
index 49cdafe6644dc7660cdbeb6d22bd075d4ab51700..5d527f5ce72f994646d14a086731ba6e43901c34 100644 (file)
@@ -27,7 +27,7 @@
 #include "sslMemory.h"
 #include "sslUtils.h"
 #include "sslDebug.h"
 #include "sslMemory.h"
 #include "sslUtils.h"
 #include "sslDebug.h"
-#include "cipherSpecs.h"
+#include "sslCipherSpecs.h"
 #include "appleSession.h"
 
 #include <assert.h>
 #include "appleSession.h"
 
 #include <assert.h>
@@ -35,7 +35,7 @@
 #include <stddef.h>
 #include <Security/SecCertificate.h>
 #include <Security/SecCertificatePriv.h>
 #include <stddef.h>
 #include <Security/SecCertificate.h>
 #include <Security/SecCertificatePriv.h>
-#include <Security/SecInternal.h>
+#include "utilities/SecCFRelease.h"
 
 typedef struct
 {   size_t              sessionIDLen;
 
 typedef struct
 {   size_t              sessionIDLen;
@@ -89,7 +89,7 @@ SSLAddSessionData(const SSLContext *ctx)
        for (ix = 0; ix < certCount; ++ix) {
                SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(certChain, ix);
                #if SSL_DEBUG
        for (ix = 0; ix < certCount; ++ix) {
                SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(certChain, ix);
                #if SSL_DEBUG
-               sslDebugLog("SSLAddSessionData: got cert %d of %d\n", ix+1, certCount);
+               sslDebugLog("SSLAddSessionData: got cert %d of %d\n", (int)ix+1, (int)certCount);
                if (!cert || CFGetTypeID(cert) != SecCertificateGetTypeID()) {
                        sslErrorLog("SSLAddSessionData: non-cert in peerCert array!\n");
                }
                if (!cert || CFGetTypeID(cert) != SecCertificateGetTypeID()) {
                        sslErrorLog("SSLAddSessionData: non-cert in peerCert array!\n");
                }
@@ -98,20 +98,20 @@ SSLAddSessionData(const SSLContext *ctx)
        }
 #endif
 
        }
 #endif
 
-       if ((err = SSLAllocBuffer(&sessionID, sessionIDLen, ctx)) != 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;
-       session->padding = 0;
-
-       certDest = session->certs;
+    if ((err = SSLAllocBuffer(&sessionID, sessionIDLen)))
+        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;
+    session->padding = 0;
+       
+    certDest = session->certs;
 
 #ifdef USE_SSLCERTIFICATE
        cert = ctx->peerCert;
 
 #ifdef USE_SSLCERTIFICATE
        cert = ctx->peerCert;
@@ -127,20 +127,20 @@ SSLAddSessionData(const SSLContext *ctx)
                size_t certLength = (size_t)SecCertificateGetLength(certRef);
                const uint8_t *certBytes = SecCertificateGetBytePtr(certRef);
 
                size_t certLength = (size_t)SecCertificateGetLength(certRef);
                const uint8_t *certBytes = SecCertificateGetBytePtr(certRef);
 
-               #if SSL_DEBUG
+               #if SSL_DEBUG && !TARGET_OS_IPHONE
                /* print cert name when debugging; leave disabled otherwise */
                CFStringRef certName = NULL;
                OSStatus status = SecCertificateInferLabel(certRef, &certName);
                char buf[1024];
                /* print cert name when debugging; leave disabled otherwise */
                CFStringRef certName = NULL;
                OSStatus status = SecCertificateInferLabel(certRef, &certName);
                char buf[1024];
-               if (!certName || !CFStringGetCString(certName, buf, 1024-1, kCFStringEncodingUTF8)) { buf[0]=0; }
+               if (status || !certName || !CFStringGetCString(certName, buf, 1024-1, kCFStringEncodingUTF8)) { buf[0]=0; }
                sslDebugLog("SSLAddSessionData: flattening \"%s\" (%ld bytes)\n", buf, certLength);
                CFReleaseSafe(certName);
                #endif
 
                if (!certBytes || !certLength) {
                        sslErrorLog("SSLAddSessionData: invalid certificate at index %d of %d (length=%ld, data=%p)\n",
                sslDebugLog("SSLAddSessionData: flattening \"%s\" (%ld bytes)\n", buf, certLength);
                CFReleaseSafe(certName);
                #endif
 
                if (!certBytes || !certLength) {
                        sslErrorLog("SSLAddSessionData: invalid certificate at index %d of %d (length=%ld, data=%p)\n",
-                                       ix, certCount-1, certLength, (const uintptr_t)certBytes);
-                       err = paramErr; /* if we have a bad cert, don't add session to cache */
+                                       (int)ix, (int)certCount-1, certLength, certBytes);
+                       err = errSecParam; /* if we have a bad cert, don't add session to cache */
                }
                else {
                        certDest = SSLEncodeSize(certDest, certLength, 4);
                }
                else {
                        certDest = SSLEncodeSize(certDest, certLength, 4);
@@ -150,10 +150,8 @@ SSLAddSessionData(const SSLContext *ctx)
        }
 #endif
 
        }
 #endif
 
-       if (!err) {
-               err = sslAddSession(ctx->peerID, sessionID, ctx->sessionCacheTimeout);
-       }
-       SSLFreeBuffer(&sessionID, ctx);
+    err = sslAddSession(ctx->peerID, sessionID, ctx->sessionCacheTimeout);
+    SSLFreeBuffer(&sessionID);
 
        return err;
 }
 
        return err;
 }
@@ -200,10 +198,10 @@ SSLRetrieveSessionID(
     ResumableSession    *session;
 
     session = (ResumableSession*) sessionData.data;
     ResumableSession    *session;
 
     session = (ResumableSession*) sessionData.data;
-    if ((err = SSLAllocBuffer(identifier, session->sessionIDLen, ctx)) != 0)
+    if ((err = SSLAllocBuffer(identifier, session->sessionIDLen)))
         return err;
     memcpy(identifier->data, session->sessionID, session->sessionIDLen);
         return err;
     memcpy(identifier->data, session->sessionID, session->sessionIDLen);
-    return noErr;
+    return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -218,7 +216,7 @@ SSLRetrieveSessionProtocolVersion(
 
     session = (ResumableSession*) sessionData.data;
     *version = session->protocolVersion;
 
     session = (ResumableSession*) sessionData.data;
     *version = session->protocolVersion;
-    return noErr;
+    return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -307,13 +305,13 @@ SSLInstallSessionFromData(const SSLBuffer sessionData, SSLContext *ctx)
 #ifdef USE_SSLCERTIFICATE
                cert = (SSLCertificate *)sslMalloc(sizeof(SSLCertificate));
                if(cert == NULL) {
 #ifdef USE_SSLCERTIFICATE
                cert = (SSLCertificate *)sslMalloc(sizeof(SSLCertificate));
                if(cert == NULL) {
-                       return memFullErr;
+                       return errSecAllocate;
                }
         cert->next = 0;
         certLen = SSLDecodeInt(storedCertProgress, 4);
         storedCertProgress += 4;
                }
         cert->next = 0;
         certLen = SSLDecodeInt(storedCertProgress, 4);
         storedCertProgress += 4;
-        if ((err = SSLAllocBuffer(&cert->derCert, certLen, ctx)) != 0)
-        {
+        if ((err = SSLAllocBuffer(&cert->derCert, certLen)
+        {   
                        sslFree(cert);
             return err;
         }
                        sslFree(cert);
             return err;
         }
@@ -330,13 +328,13 @@ SSLInstallSessionFromData(const SSLBuffer sessionData, SSLContext *ctx)
                cert = SecCertificateCreateWithBytes(NULL, storedCertProgress, certLen);
                #if SSL_DEBUG
                sslDebugLog("SSLInstallSessionFromData: creating cert with bytes=%p len=%lu\n",
                cert = SecCertificateCreateWithBytes(NULL, storedCertProgress, certLen);
                #if SSL_DEBUG
                sslDebugLog("SSLInstallSessionFromData: creating cert with bytes=%p len=%lu\n",
-                       (uintptr_t)storedCertProgress, certLen);
+                       storedCertProgress, certLen);
                if (!cert || CFGetTypeID(cert) != SecCertificateGetTypeID()) {
                        sslErrorLog("SSLInstallSessionFromData: SecCertificateCreateWithBytes failed\n");
                }
                #endif
                if(cert == NULL) {
                if (!cert || CFGetTypeID(cert) != SecCertificateGetTypeID()) {
                        sslErrorLog("SSLInstallSessionFromData: SecCertificateCreateWithBytes failed\n");
                }
                #endif
                if(cert == NULL) {
-                       return memFullErr;
+                       return errSecAllocate;
                }
         storedCertProgress += certLen;
                /* @@@ This is almost the same code as in sslCert.c: SSLProcessCertificate() */
                }
         storedCertProgress += certLen;
                /* @@@ This is almost the same code as in sslCert.c: SSLProcessCertificate() */
@@ -345,7 +343,11 @@ SSLInstallSessionFromData(const SSLBuffer sessionData, SSLContext *ctx)
                                session->certCount, &kCFTypeArrayCallBacks);
             if (!certChain) {
                                CFRelease(cert);
                                session->certCount, &kCFTypeArrayCallBacks);
             if (!certChain) {
                                CFRelease(cert);
-                               return memFullErr;
+                               return errSecAllocate;
+                       }
+            if (ctx->peerCert) {
+                               sslDebugLog("SSLInstallSessionFromData: releasing existing cert chain\n");
+                               CFRelease(ctx->peerCert);
                        }
                        ctx->peerCert = certChain;
                }
                        }
                        ctx->peerCert = certChain;
                }
@@ -355,5 +357,5 @@ SSLInstallSessionFromData(const SSLBuffer sessionData, SSLContext *ctx)
 #endif
     }
 
 #endif
     }
 
-    return noErr;
+    return errSecSuccess;
 }
 }
index 7fa35cb38a35a783157a1ee57190fc9fc143678c..311bedd87157f78c63ff58f8bb1cdd90078c8ca8 100644 (file)
 #include "sslAlertMessage.h"
 #include "sslSession.h"
 #include "sslDebug.h"
 #include "sslAlertMessage.h"
 #include "sslSession.h"
 #include "sslDebug.h"
-#include "cipherSpecs.h"
+#include "sslCipherSpecs.h"
 #include "sslUtils.h"
 
 #include <assert.h>
 #include <string.h>
 
 #include "sslUtils.h"
 
 #include <assert.h>
 #include <string.h>
 
+#include <utilities/SecIOFormat.h>
+
 #ifndef        NDEBUG
 static inline void sslIoTrace(
        const char *op,
 #ifndef        NDEBUG
 static inline void sslIoTrace(
        const char *op,
@@ -45,8 +47,8 @@ static inline void sslIoTrace(
        size_t moved,
        OSStatus stat)
 {
        size_t moved,
        OSStatus stat)
 {
-       sslLogRecordIo("===%s: req %4lu moved %4lu status %ld",
-               op, req, moved, stat);
+       sslLogRecordIo("===%s: req %4lu moved %4lu status %d",
+               op, req, moved, (int)stat);
 }
 #else
 #define sslIoTrace(op, req, moved, stat)
 }
 #else
 #define sslIoTrace(op, req, moved, stat)
@@ -57,9 +59,36 @@ extern int kSplitDefaultValue;
 static OSStatus SSLProcessProtocolMessage(SSLRecord *rec, SSLContext *ctx);
 static OSStatus SSLHandshakeProceed(SSLContext *ctx);
 static OSStatus SSLInitConnection(SSLContext *ctx);
 static OSStatus SSLProcessProtocolMessage(SSLRecord *rec, SSLContext *ctx);
 static OSStatus SSLHandshakeProceed(SSLContext *ctx);
 static OSStatus SSLInitConnection(SSLContext *ctx);
-static OSStatus SSLServiceWriteQueue(SSLContext *ctx);
 
 
-OSStatus
+static Boolean isFalseStartAllowed(SSLContext *ctx)
+{
+    SSL_CipherAlgorithm c=sslCipherSuiteGetSymmetricCipherAlgorithm(ctx->selectedCipher);
+    KeyExchangeMethod kem=sslCipherSuiteGetKeyExchangeMethod(ctx->selectedCipher);
+    
+    
+    /* Whitelisting allowed ciphers, kem and client auth type */
+    return
+        (
+            (c==SSL_CipherAlgorithmAES_128_CBC) ||
+            (c==SSL_CipherAlgorithmAES_128_GCM) ||
+            (c==SSL_CipherAlgorithmAES_256_CBC) ||
+            (c==SSL_CipherAlgorithmAES_256_GCM) ||
+            (c==SSL_CipherAlgorithmRC4_128)
+        ) && (
+            (kem==SSL_ECDHE_ECDSA) ||
+            (kem==SSL_ECDHE_RSA) ||
+            (kem==SSL_DHE_RSA) ||
+            (kem==SSL_DHE_DSS)
+        ) && (
+            (ctx->negAuthType==SSLClientAuthNone) ||
+            (ctx->negAuthType==SSLClientAuth_DSSSign) ||
+            (ctx->negAuthType==SSLClientAuth_RSASign) ||
+            (ctx->negAuthType==SSLClientAuth_ECDSASign)
+        );
+}
+
+
+OSStatus 
 SSLWrite(
        SSLContext                      *ctx,
        const void *            data,
 SSLWrite(
        SSLContext                      *ctx,
        const void *            data,
@@ -73,7 +102,7 @@ SSLWrite(
 
        sslLogRecordIo("SSLWrite top");
     if((ctx == NULL) || (bytesWritten == NULL)) {
 
        sslLogRecordIo("SSLWrite top");
     if((ctx == NULL) || (bytesWritten == NULL)) {
-       return paramErr;
+       return errSecParam;
     }
     dataLen = dataLength;
     processed = 0;        /* Initialize in case we return with errSSLWouldBlock */
     }
     dataLen = dataLength;
     processed = 0;        /* Initialize in case we return with errSSLWouldBlock */
@@ -92,8 +121,8 @@ SSLWrite(
         default:
                        if(ctx->state < SSL_HdskStateServerHello) {
                                /* not ready for I/O, and handshake not in progress */
         default:
                        if(ctx->state < SSL_HdskStateServerHello) {
                                /* not ready for I/O, and handshake not in progress */
-                               sslIoTrace("SSLWrite", dataLength, 0, badReqErr);
-                               return badReqErr;
+                               sslIoTrace("SSLWrite", dataLength, 0, errSecBadReq);
+                               return errSecBadReq;
                        }
                        /* handshake in progress; will call SSLHandshakeProceed below */
                        break;
                        }
                        /* handshake in progress; will call SSLHandshakeProceed below */
                        break;
@@ -101,8 +130,12 @@ SSLWrite(
 
     /* First, we have to wait until the session is ready to send data,
         so the encryption keys and such have been established. */
 
     /* First, we have to wait until the session is ready to send data,
         so the encryption keys and such have been established. */
-    err = noErr;
-    while (ctx->writeCipher.ready == 0)
+    err = errSecSuccess; 
+    while (!(
+              (ctx->state==SSL_HdskStateServerReady) ||
+              (ctx->state==SSL_HdskStateClientReady) ||
+              (ctx->writeCipher_ready &&  ctx->falseStartEnabled && isFalseStartAllowed(ctx))
+            ))
     {   if ((err = SSLHandshakeProceed(ctx)) != 0)
             goto exit;
     }
     {   if ((err = SSLHandshakeProceed(ctx)) != 0)
             goto exit;
     }
@@ -140,9 +173,8 @@ SSLWrite(
             rec.contents.length = dataLen;
         else
             rec.contents.length = MAX_RECORD_LENGTH;
             rec.contents.length = dataLen;
         else
             rec.contents.length = MAX_RECORD_LENGTH;
-
-       assert(ctx->sslTslCalls != NULL);
-       if ((err = ctx->sslTslCalls->writeRecord(rec, ctx)) != 0)
+        
+        if ((err = SSLWriteRecord(rec, ctx)) != 0)
             goto exit;
         processed += rec.contents.length;
         dataLen -= rec.contents.length;
             goto exit;
         processed += rec.contents.length;
         dataLen -= rec.contents.length;
@@ -152,12 +184,13 @@ SSLWrite(
     /* All the data has been advanced to the write queue */
     *bytesWritten = processed;
     if ((err = SSLServiceWriteQueue(ctx)) == 0) {
     /* All the data has been advanced to the write queue */
     *bytesWritten = processed;
     if ((err = SSLServiceWriteQueue(ctx)) == 0) {
-               err = noErr;
+               err = errSecSuccess;
        }
 exit:
        switch(err) {
        }
 exit:
        switch(err) {
-               case noErr:
+               case errSecSuccess:
                case errSSLWouldBlock:
                case errSSLWouldBlock:
+        case errSSLUnexpectedRecord:
                case errSSLServerAuthCompleted: /* == errSSLClientAuthCompleted */
                case errSSLClientCertRequested:
                case errSSLClosedGraceful:
                case errSSLServerAuthCompleted: /* == errSSLClientAuthCompleted */
                case errSSLClientCertRequested:
                case errSSLClosedGraceful:
@@ -187,7 +220,7 @@ SSLRead     (
 
        sslLogRecordIo("SSLRead top");
     if((ctx == NULL) || (data == NULL) || (processed == NULL)) {
 
        sslLogRecordIo("SSLRead top");
     if((ctx == NULL) || (data == NULL) || (processed == NULL)) {
-       return paramErr;
+       return errSecParam;
     }
     bufSize = dataLength;
     *processed = 0;        /* Initialize in case we return with errSSLWouldBlock */
     }
     bufSize = dataLength;
     *processed = 0;        /* Initialize in case we return with errSSLWouldBlock */
@@ -210,8 +243,8 @@ readRetry:
 
     /* First, we have to wait until the session is ready to receive data,
         so the encryption keys and such have been established. */
 
     /* First, we have to wait until the session is ready to receive data,
         so the encryption keys and such have been established. */
-    err = noErr;
-    while (ctx->readCipher.ready == 0) {
+    err = errSecSuccess;
+    while (ctx->readCipher_ready == 0) {
                if ((err = SSLHandshakeProceed(ctx)) != 0) {
             goto exit;
                }
                if ((err = SSLHandshakeProceed(ctx)) != 0) {
             goto exit;
                }
@@ -222,7 +255,7 @@ readRetry:
                if (err != errSSLWouldBlock) {
             goto exit;
                }
                if (err != errSSLWouldBlock) {
             goto exit;
                }
-        err = noErr; /* Write blocking shouldn't stop attempts to read */
+        err = errSecSuccess; /* Write blocking shouldn't stop attempts to read */
     }
 
     remaining = bufSize;
     }
 
     remaining = bufSize;
@@ -244,7 +277,7 @@ readRetry:
 
     if (ctx->receivedDataBuffer.data != 0 &&
         ctx->receivedDataPos >= ctx->receivedDataBuffer.length)
 
     if (ctx->receivedDataBuffer.data != 0 &&
         ctx->receivedDataPos >= ctx->receivedDataBuffer.length)
-    {   SSLFreeBuffer(&ctx->receivedDataBuffer, ctx);
+    {   SSLFreeBuffer(&ctx->receivedDataBuffer);
         ctx->receivedDataBuffer.data = 0;
         ctx->receivedDataPos = 0;
     }
         ctx->receivedDataBuffer.data = 0;
         ctx->receivedDataPos = 0;
     }
@@ -268,16 +301,8 @@ readRetry:
                 remaining -= rec.contents.length;
                 charPtr += rec.contents.length;
                 *processed += rec.contents.length;
                 remaining -= rec.contents.length;
                 charPtr += rec.contents.length;
                 *processed += rec.contents.length;
-                /* COMPILER BUG!
-                 * This:
-                 * if ((err = SSLFreeBuffer(rec.contents, ctx)) != 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 = SSLFreeBuffer(b, ctx)) != 0) {
+                    if ((err = SSLFreeRecord(rec, ctx))) {
                        goto exit;
                     }
                 }
                        goto exit;
                     }
                 }
@@ -295,24 +320,25 @@ readRetry:
             if ((err = SSLProcessProtocolMessage(&rec, ctx)) != 0) {
                 goto exit;
                        }
             if ((err = SSLProcessProtocolMessage(&rec, ctx)) != 0) {
                 goto exit;
                        }
-            if ((err = SSLFreeBuffer(&rec.contents, ctx)) != 0) {
+            if ((err = SSLFreeRecord(rec, ctx))) {
                 goto exit;
                        }
         }
     }
 
                 goto exit;
                        }
         }
     }
 
-    err = noErr;
+    err = errSecSuccess;
 
 exit:
        /* test for renegotiate: loop until something useful happens */
 
 exit:
        /* test for renegotiate: loop until something useful happens */
-       if((err == noErr) && (*processed == 0) && !(dataLength == 0)) {
+       if(((err == errSecSuccess)  && (*processed == 0) && dataLength) || (err == errSSLUnexpectedRecord)) {
                sslLogNegotiateDebug("SSLRead recursion");
                goto readRetry;
        }
        /* shut down on serious errors */
        switch(err) {
                sslLogNegotiateDebug("SSLRead recursion");
                goto readRetry;
        }
        /* shut down on serious errors */
        switch(err) {
-               case noErr:
+               case errSecSuccess:
                case errSSLWouldBlock:
                case errSSLWouldBlock:
+        case errSSLUnexpectedRecord:
                case errSSLServerAuthCompleted: /* == errSSLClientAuthCompleted */
                case errSSLClientCertRequested:
                case errSSLClosedGraceful:
                case errSSLServerAuthCompleted: /* == errSSLClientAuthCompleted */
                case errSSLClientCertRequested:
                case errSSLClosedGraceful:
@@ -339,7 +365,7 @@ SSLHandshake(SSLContext *ctx)
        OSStatus  err;
 
        if(ctx == NULL) {
        OSStatus  err;
 
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
     if (ctx->state == SSL_HdskStateGracefulClose)
         return errSSLClosedGraceful;
        }
     if (ctx->state == SSL_HdskStateGracefulClose)
         return errSSLClosedGraceful;
@@ -359,7 +385,7 @@ SSLHandshake(SSLContext *ctx)
                return err;
        }
     }
                return err;
        }
     }
-    err = noErr;
+    err = errSecSuccess;
 
     if(ctx->isDTLS) {
         if (ctx->timeout_deadline<CFAbsoluteTimeGetCurrent()) {
 
     if(ctx->isDTLS) {
         if (ctx->timeout_deadline<CFAbsoluteTimeGetCurrent()) {
@@ -367,8 +393,10 @@ SSLHandshake(SSLContext *ctx)
         }
     }
 
         }
     }
 
-    while (ctx->readCipher.ready == 0 || ctx->writeCipher.ready == 0)
-    {   if ((err = SSLHandshakeProceed(ctx)) != 0)
+    while (ctx->readCipher_ready == 0 || ctx->writeCipher_ready == 0)
+    {
+        err = SSLHandshakeProceed(ctx);
+        if((err != 0) && (err != errSSLUnexpectedRecord))
             return err;
     }
 
             return err;
     }
 
@@ -376,7 +404,8 @@ SSLHandshake(SSLContext *ctx)
     if ((err = SSLServiceWriteQueue(ctx)) != 0) {
                return err;
        }
     if ((err = SSLServiceWriteQueue(ctx)) != 0) {
                return err;
        }
-    return noErr;
+
+    return errSecSuccess;
 }
 
 
 }
 
 
@@ -413,22 +442,24 @@ SSLHandshakeProceed(SSLContext *ctx)
 
     if ((err = SSLServiceWriteQueue(ctx)) != 0)
         return err;
 
     if ((err = SSLServiceWriteQueue(ctx)) != 0)
         return err;
-    assert(ctx->readCipher.ready == 0);
+
+    assert(ctx->readCipher_ready == 0);
     if ((err = SSLReadRecord(&rec, ctx)) != 0)
         return err;
     if ((err = SSLProcessProtocolMessage(&rec, ctx)) != 0)
     if ((err = SSLReadRecord(&rec, ctx)) != 0)
         return err;
     if ((err = SSLProcessProtocolMessage(&rec, ctx)) != 0)
-    {   SSLFreeBuffer(&rec.contents, ctx);
+    {
+        SSLFreeRecord(rec, ctx);
         return err;
     }
         return err;
     }
-    if ((err = SSLFreeBuffer(&rec.contents, ctx)) != 0)
+    if ((err = SSLFreeRecord(rec, ctx)))
         return err;
 
         return err;
 
-    return noErr;
+    return errSecSuccess;
 }
 
 static OSStatus
 SSLInitConnection(SSLContext *ctx)
 }
 
 static OSStatus
 SSLInitConnection(SSLContext *ctx)
-{   OSStatus      err = noErr;
+{   OSStatus      err = errSecSuccess;
 
     if (ctx->protocolSide == kSSLClientSide) {
         SSLChangeHdskState(ctx, SSL_HdskStateClientUninit);
 
     if (ctx->protocolSide == kSSLClientSide) {
         SSLChangeHdskState(ctx, SSL_HdskStateClientUninit);
@@ -464,7 +495,7 @@ SSLInitConnection(SSLContext *ctx)
                        sslLogResumSessDebug("===attempting to resume session");
                } else {
                        sslLogResumSessDebug("===Resumable session protocol mismatch");
                        sslLogResumSessDebug("===attempting to resume session");
                } else {
                        sslLogResumSessDebug("===Resumable session protocol mismatch");
-                       SSLFreeBuffer(&ctx->resumableSession, ctx);
+                       SSLFreeBuffer(&ctx->resumableSession);
                }
     }
 
                }
     }
 
@@ -472,8 +503,8 @@ SSLInitConnection(SSLContext *ctx)
         * If we're the client & handshake hasn't yet begun, start it by
         *  pretending we just received a hello request
         */
         * If we're the client & handshake hasn't yet begun, start it by
         *  pretending we just received a hello request
         */
-    if (ctx->state == SSL_HdskStateClientUninit && ctx->writeCipher.ready == 0)
-    {
+    if (ctx->state == SSL_HdskStateClientUninit && ctx->writeCipher_ready == 0)
+    {   
                assert(ctx->negProtocolVersion == SSL_Version_Undetermined);
 #if ENABLE_SSLV2
                if(!cachedV3OrTls1) {
                assert(ctx->negProtocolVersion == SSL_Version_Undetermined);
 #if ENABLE_SSLV2
                if(!cachedV3OrTls1) {
@@ -490,30 +521,6 @@ SSLInitConnection(SSLContext *ctx)
     return err;
 }
 
     return err;
 }
 
-static OSStatus
-SSLServiceWriteQueue(SSLContext *ctx)
-{   OSStatus        err = noErr, werr = noErr;
-    size_t          written = 0;
-    SSLBuffer       buf;
-    WaitingRecord   *rec;
-
-    while (!werr && ((rec = ctx->recordWriteQueue) != 0))
-    {   buf.data = rec->data + rec->sent;
-        buf.length = rec->length - rec->sent;
-        werr = sslIoWrite(buf, &written, ctx);
-        rec->sent += written;
-        if (rec->sent >= rec->length)
-        {   assert(rec->sent == rec->length);
-            assert(err == 0);
-            ctx->recordWriteQueue = rec->next;
-                       sslFree(rec);
-        }
-        if (err)
-            return err;
-    }
-
-    return werr;
-}
 
 static OSStatus
 SSLProcessProtocolMessage(SSLRecord *rec, SSLContext *ctx)
 
 static OSStatus
 SSLProcessProtocolMessage(SSLRecord *rec, SSLContext *ctx)
@@ -552,19 +559,21 @@ SSLProcessProtocolMessage(SSLRecord *rec, SSLContext *ctx)
 OSStatus
 SSLClose(SSLContext *ctx)
 {
 OSStatus
 SSLClose(SSLContext *ctx)
 {
-       OSStatus      err = noErr;
+       OSStatus      err = errSecSuccess;
 
        sslHdskStateDebug("SSLClose");
        if(ctx == NULL) {
 
        sslHdskStateDebug("SSLClose");
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
     if (ctx->negProtocolVersion >= SSL_Version_3_0)
         err = SSLSendAlert(SSL_AlertLevelWarning, SSL_AlertCloseNotify, ctx);
        }
     if (ctx->negProtocolVersion >= SSL_Version_3_0)
         err = SSLSendAlert(SSL_AlertLevelWarning, SSL_AlertCloseNotify, ctx);
+
     if (err == 0)
         err = SSLServiceWriteQueue(ctx);
     if (err == 0)
         err = SSLServiceWriteQueue(ctx);
+
     SSLChangeHdskState(ctx, SSL_HdskStateGracefulClose);
     SSLChangeHdskState(ctx, SSL_HdskStateGracefulClose);
-    if (err == ioErr)
-        err = noErr;     /* Ignore errors related to closed streams */
+    if (err == errSecIO)
+        err = errSecSuccess;     /* Ignore errors related to closed streams */
     return err;
 }
 
     return err;
 }
 
@@ -581,7 +590,7 @@ SSLGetBufferedReadSize(SSLContextRef ctx,
        size_t *bufSize)                        /* RETURNED */
 {
        if(ctx == NULL) {
        size_t *bufSize)                        /* RETURNED */
 {
        if(ctx == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        if(ctx->receivedDataBuffer.data == NULL) {
                *bufSize = 0;
        }
        if(ctx->receivedDataBuffer.data == NULL) {
                *bufSize = 0;
@@ -590,5 +599,5 @@ SSLGetBufferedReadSize(SSLContextRef ctx,
                assert(ctx->receivedDataBuffer.length >= ctx->receivedDataPos);
                *bufSize = ctx->receivedDataBuffer.length - ctx->receivedDataPos;
        }
                assert(ctx->receivedDataBuffer.length >= ctx->receivedDataPos);
                *bufSize = ctx->receivedDataBuffer.length - ctx->receivedDataPos;
        }
-       return noErr;
+       return errSecSuccess;
 }
 }
diff --git a/libsecurity_ssl/lib/sslTypes.h b/libsecurity_ssl/lib/sslTypes.h
new file mode 100644 (file)
index 0000000..33fb590
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2011 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * sslTypes.h - internal ssl types
+ */
+
+/* This header should be kernel compatible */
+
+#ifndef        _SSLTYPES_H_
+#define _SSLTYPES_H_ 1
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+enum {
+    errSSLRecordInternal            = -10000,
+    errSSLRecordWouldBlock          = -10001,
+    errSSLRecordProtocol            = -10002,
+    errSSLRecordNegotiation         = -10003,
+    errSSLRecordClosedAbort         = -10004,
+       errSSLRecordConnectionRefused   = -10005,       /* peer dropped connection before responding */
+       errSSLRecordDecryptionFail      = -10006,       /* decryption failure */
+       errSSLRecordBadRecordMac        = -10007,       /* bad MAC */
+       errSSLRecordRecordOverflow      = -10008,       /* record overflow */
+       errSSLRecordUnexpectedRecord    = -10009,       /* unexpected (skipped) record in DTLS */
+};
+
+typedef enum
+{
+    /* This value never appears in the actual protocol */
+    SSL_Version_Undetermined = 0,
+    /* actual protocol values */
+    SSL_Version_2_0 = 0x0002,
+    SSL_Version_3_0 = 0x0300,
+    TLS_Version_1_0 = 0x0301,          /* TLS 1.0 == SSL 3.1 */
+    TLS_Version_1_1 = 0x0302,
+    TLS_Version_1_2 = 0x0303,
+    DTLS_Version_1_0 = 0xfeff,
+} SSLProtocolVersion;
+
+/* FIXME: This enum and the SSLRecord are exposed because they
+ are used at the interface between the Record and Handshake layer.
+ This might not be the best idea */
+
+enum
+{   SSL_RecordTypeV2_0,
+    SSL_RecordTypeV3_Smallest = 20,
+    SSL_RecordTypeChangeCipher = 20,
+    SSL_RecordTypeAlert = 21,
+    SSL_RecordTypeHandshake = 22,
+    SSL_RecordTypeAppData = 23,
+    SSL_RecordTypeV3_Largest = 23
+};
+
+
+/*
+ * This is the buffer type used internally.
+ */
+typedef struct
+{   size_t  length;
+    uint8_t *data;
+} SSLBuffer;
+
+
+typedef struct
+{
+    uint8_t                 contentType;
+    SSLProtocolVersion      protocolVersion;
+    SSLBuffer               contents;
+} SSLRecord;
+
+
+/*
+ * We should remove this and use uint64_t all over.
+ */
+typedef uint64_t sslUint64;
+
+
+/* Opaque reference to a Record Context */
+typedef void * SSLRecordContextRef;
+
+
+typedef int
+(*SSLRecordReadFunc)                (SSLRecordContextRef    ref,
+                                     SSLRecord              *rec);
+
+typedef int
+(*SSLRecordWriteFunc)               (SSLRecordContextRef    ref,
+                                     SSLRecord              rec);
+
+typedef int
+(*SSLRecordInitPendingCiphersFunc)  (SSLRecordContextRef    ref,
+                                     uint16_t               selectedCipher,
+                                     bool                   server,
+                                     SSLBuffer              key);
+
+typedef int
+(*SSLRecordAdvanceWriteCipherFunc)  (SSLRecordContextRef    ref);
+
+typedef int
+(*SSLRecordRollbackWriteCipherFunc) (SSLRecordContextRef    ref);
+
+typedef int
+(*SSLRecordAdvanceReadCipherFunc)   (SSLRecordContextRef    ref);
+
+typedef int
+(*SSLRecordSetProtocolVersionFunc)  (SSLRecordContextRef    ref,
+                                     SSLProtocolVersion     protocolVersion);
+
+typedef int
+(*SSLRecordFreeFunc)                (SSLRecordContextRef    ref,
+                                     SSLRecord              rec);
+
+typedef int
+(*SSLRecordServiceWriteQueueFunc)   (SSLRecordContextRef    ref);
+
+
+struct SSLRecordFuncs
+{   SSLRecordReadFunc                   read;
+    SSLRecordWriteFunc                  write;
+    SSLRecordInitPendingCiphersFunc     initPendingCiphers;
+    SSLRecordAdvanceWriteCipherFunc     advanceWriteCipher;
+    SSLRecordRollbackWriteCipherFunc    rollbackWriteCipher;
+    SSLRecordAdvanceReadCipherFunc      advanceReadCipher;
+    SSLRecordSetProtocolVersionFunc     setProtocolVersion;
+    SSLRecordFreeFunc                   free;
+    SSLRecordServiceWriteQueueFunc      serviceWriteQueue;
+};
+
+#endif /* _SSLTYPES_H_ */
index 91a4f95bcb3867768c36af503a3957f2da7830c9..5a2625960460a9591ec5a2cba9aa5335d6929047 100644 (file)
  */
 
 /*
  */
 
 /*
- * sslUtils.c - Misc. SSL utility functions
+ * sslUtils.c - Misc. OS independant SSL utility functions
  */
 
  */
 
-#include "sslContext.h"
+/* THIS FILE CONTAINS KERNEL CODE */
+
 #include "sslUtils.h"
 #include "sslUtils.h"
-#include "sslMemory.h"
+#include "sslTypes.h"
 #include "sslDebug.h"
 
 #include "sslDebug.h"
 
-#include <sys/time.h>
-
-#include <fcntl.h> // for open
-#include <unistd.h> // for read
-#include <errno.h> // for errno
-#include <Security/SecFramework.h>
-#include <Security/SecRandom.h>
+#include <AssertMacros.h>
 
 #ifndef NDEBUG
 void SSLDump(const unsigned char *data, unsigned long len)
 
 #ifndef NDEBUG
 void SSLDump(const unsigned char *data, unsigned long len)
@@ -56,17 +51,17 @@ unsigned int
 SSLDecodeInt(const uint8_t *p, size_t length)
 {
     unsigned int val = 0;
 SSLDecodeInt(const uint8_t *p, size_t length)
 {
     unsigned int val = 0;
-    assert(length > 0 && length <= 4); //anything else would be an internal error.
+    check(length > 0 && length <= 4); //anything else would be an internal error.
     while (length--)
         val = (val << 8) | *p++;
     return val;
 }
 
 uint8_t *
     while (length--)
         val = (val << 8) | *p++;
     return val;
 }
 
 uint8_t *
-SSLEncodeInt(uint8_t *p, unsigned int value, size_t length)
+SSLEncodeInt(uint8_t *p, size_t value, size_t length)
 {
     unsigned char *retVal = p + length; /* Return pointer to char after int */
 {
     unsigned char *retVal = p + length; /* Return pointer to char after int */
-    assert(length > 0 && length <= 4);  //anything else would be an internal error.
+    check(length > 0 && length <= 4);  //anything else would be an internal error.
     while (length--)                    /* Assemble backwards */
     {   p[length] = (uint8_t)value;     /* Implicit masking to low byte */
         value >>= 8;
     while (length--)                    /* Assemble backwards */
     {   p[length] = (uint8_t)value;     /* Implicit masking to low byte */
         value >>= 8;
@@ -78,7 +73,7 @@ size_t
 SSLDecodeSize(const uint8_t *p, size_t length)
 {
     unsigned int val = 0;
 SSLDecodeSize(const uint8_t *p, size_t length)
 {
     unsigned int val = 0;
-    assert(length > 0 && length <= 4); //anything else would be an internal error.
+    check(length > 0 && length <= 4); //anything else would be an internal error.
     while (length--)
         val = (val << 8) | *p++;
     return val;
     while (length--)
         val = (val << 8) | *p++;
     return val;
@@ -88,7 +83,7 @@ uint8_t *
 SSLEncodeSize(uint8_t *p, size_t value, size_t length)
 {
     unsigned char *retVal = p + length; /* Return pointer to char after int */
 SSLEncodeSize(uint8_t *p, size_t value, size_t length)
 {
     unsigned char *retVal = p + length; /* Return pointer to char after int */
-    assert(length > 0 && length <= 4);  //anything else would be an internal error.
+    check(length > 0 && length <= 4);  //anything else would be an internal error.
     while (length--)                    /* Assemble backwards */
     {   p[length] = (uint8_t)value;     /* Implicit masking to low byte */
         value >>= 8;
     while (length--)                    /* Assemble backwards */
     {   p[length] = (uint8_t)value;     /* Implicit masking to low byte */
         value >>= 8;
@@ -98,221 +93,48 @@ SSLEncodeSize(uint8_t *p, size_t value, size_t length)
 
 
 uint8_t *
 
 
 uint8_t *
-SSLEncodeUInt64(uint8_t *p, sslUint64 value)
+SSLEncodeUInt64(uint8_t *p, uint64_t value)
 {
 {
-    p = SSLEncodeInt(p, value.high, 4);
-    return SSLEncodeInt(p, value.low, 4);
-}
-
-
-uint8_t *
-SSLEncodeHandshakeHeader(SSLContext *ctx, SSLRecord *rec, SSLHandshakeType type, size_t msglen)
-{
-    uint8_t *charPtr;
-
-    charPtr = rec->contents.data;
-    *charPtr++ = type;
-    charPtr = SSLEncodeSize(charPtr, msglen, 3);
-
-    if(rec->protocolVersion == DTLS_Version_1_0) {
-        charPtr = SSLEncodeInt(charPtr, ctx->hdskMessageSeq, 2);
-        /* fragmentation -- we encode header as if unfragmented,
-           actual fragmentation happens at lower layer. */
-        charPtr = SSLEncodeInt(charPtr, 0, 3);
-        charPtr = SSLEncodeSize(charPtr, msglen, 3);
-    }
-
-    return charPtr;
+    p = SSLEncodeInt(p, (value>>32)&0xffffffff, 4);
+    return SSLEncodeInt(p, value&0xffffffff, 4);
 }
 
 
 void
 IncrementUInt64(sslUint64 *v)
 }
 
 
 void
 IncrementUInt64(sslUint64 *v)
-{   if (++v->low == 0)          /* Must have just rolled over */
-        ++v->high;
+{
+    (*v)++;
 }
 
 }
 
-#if ENABLE_DTLS
 void
 void
-SSLDecodeUInt64(const uint8_t *p, size_t length, sslUint64 *v)
+SSLDecodeUInt64(const uint8_t *p, size_t length, uint64_t *v)
 {
 {
-    assert(length > 0 && length <= 8);
+    check(length > 0 && length <= 8);
     if(length<=4) {
     if(length<=4) {
-        v->low=SSLDecodeInt(p, length);
-        v->high=0;
+        *v=SSLDecodeInt(p, length);
     } else {
     } else {
-        v->high=SSLDecodeInt(p, length-4);
-        v->low=SSLDecodeInt(p+length-4, 4);
+        *v=((uint64_t)SSLDecodeInt(p, length-4))<<32 | SSLDecodeInt(p+length-4, 4);
     }
 }
     }
 }
-#endif
 
 
-#ifdef USE_SSLCERTIFICATE
-size_t
-SSLGetCertificateChainLength(const SSLCertificate *c)
-{
-       size_t rtn = 0;
-
-    while (c)
-    {
-       rtn++;
-        c = c->next;
-    }
-    return rtn;
-}
-
-OSStatus sslDeleteCertificateChain(
-    SSLCertificate             *certs,
-       SSLContext                      *ctx)
-{
-       SSLCertificate          *cert;
-       SSLCertificate          *nextCert;
-
-       assert(ctx != NULL);
-       cert=certs;
-       while(cert != NULL) {
-               nextCert = cert->next;
-               SSLFreeBuffer(&cert->derCert, ctx);
-               sslFree(cert);
-               cert = nextCert;
-       }
-       return noErr;
-}
-#endif /* USE_SSLCERTIFICATE */
-
-Boolean sslIsSessionActive(const SSLContext *ctx)
-{
-       assert(ctx != NULL);
-       switch(ctx->state) {
-               case SSL_HdskStateUninit:
-               case SSL_HdskStateServerUninit:
-               case SSL_HdskStateClientUninit:
-               case SSL_HdskStateGracefulClose:
-               case SSL_HdskStateErrorClose:
-                       return false;
-               default:
-                       return true;
-       }
-}
 
 #if    SSL_DEBUG
 
 const char *protocolVersStr(SSLProtocolVersion prot)
 {
        switch(prot) {
 
 #if    SSL_DEBUG
 
 const char *protocolVersStr(SSLProtocolVersion prot)
 {
        switch(prot) {
-       case SSL_Version_Undetermined: return "SSL_Version_Undetermined";
-       case SSL_Version_2_0: return "SSL_Version_2_0";
-       case SSL_Version_3_0: return "SSL_Version_3_0";
-       case TLS_Version_1_0: return "TLS_Version_1_0";
-    case TLS_Version_1_1: return "TLS_Version_1_1";
-    case TLS_Version_1_2: return "TLS_Version_1_2";
-       default: sslErrorLog("protocolVersStr: bad prot\n"); return "BAD PROTOCOL";
+        case SSL_Version_Undetermined: return "SSL_Version_Undetermined";
+        case SSL_Version_2_0: return "SSL_Version_2_0";
+        case SSL_Version_3_0: return "SSL_Version_3_0";
+        case TLS_Version_1_0: return "TLS_Version_1_0";
+        case TLS_Version_1_1: return "TLS_Version_1_1";
+        case TLS_Version_1_2: return "TLS_Version_1_2";
+        default: sslErrorLog("protocolVersStr: bad prot\n"); return "BAD PROTOCOL";
        }
        return NULL;    /* NOT REACHED */
 }
 
 #endif /* SSL_DEBUG */
 
        }
        return NULL;    /* NOT REACHED */
 }
 
 #endif /* SSL_DEBUG */
 
-/*
- * Redirect SSLBuffer-based I/O call to user-supplied I/O.
- */
-OSStatus sslIoRead(
-       SSLBuffer               buf,
-       size_t                  *actualLength,
-       SSLContext              *ctx)
-{
-       size_t          dataLength = buf.length;
-       OSStatus        ortn;
-
-       *actualLength = 0;
-       ortn = (ctx->ioCtx.read)(ctx->ioCtx.ioRef,
-               buf.data,
-               &dataLength);
-       *actualLength = dataLength;
-       return ortn;
-}
-
-OSStatus sslIoWrite(
-       SSLBuffer               buf,
-       size_t                  *actualLength,
-       SSLContext              *ctx)
-{
-       size_t                  dataLength = buf.length;
-       OSStatus                ortn;
-
-       *actualLength = 0;
-       ortn = (ctx->ioCtx.write)(ctx->ioCtx.ioRef,
-               buf.data,
-               &dataLength);
-       *actualLength = dataLength;
-       return ortn;
-}
 
 
-OSStatus sslTime(uint32_t *tim)
-{
-       time_t t;
-       time(&t);
-       *tim = (uint32_t)t;
-       return noErr;
-}
-
-/*
- * Common RNG function.
- */
-OSStatus sslRand(SSLContext *ctx, SSLBuffer *buf)
-{
-       assert(buf != NULL);
-       assert(buf->data != NULL);
-
-       if(buf->length == 0) {
-               sslErrorLog("sslRand: zero buf->length\n");
-               return noErr;
-       }
-
-       return SecRandomCopyBytes(kSecRandomDefault, buf->length, buf->data) ? errSSLCrypto : noErr;
-}
 
 
-/*
- * Given a protocol version sent by peer, determine if we accept that version
- * and downgrade if appropriate (which can not be done for the client side).
- */
-OSStatus sslVerifyProtVersion(
-       SSLContext                      *ctx,
-       SSLProtocolVersion      peerVersion,    // sent by peer
-       SSLProtocolVersion      *negVersion)    // final negotiated version if return success
-{
-    if ((ctx->isDTLS)
-        ? peerVersion > ctx->minProtocolVersion
-        : peerVersion < ctx->minProtocolVersion) {
-        return errSSLNegotiation;
-    }
-    if ((ctx->isDTLS)
-        ? peerVersion < ctx->maxProtocolVersion
-        : peerVersion > ctx->maxProtocolVersion) {
-        if (ctx->protocolSide == kSSLClientSide) {
-            return errSSLNegotiation;
-        }
-        *negVersion = ctx->maxProtocolVersion;
-    } else {
-        *negVersion = peerVersion;
-    }
-
-    return noErr;
-}
-
-/*
- * Determine max enabled protocol, i.e., the one we try to negotiate for.
- * Only returns an error (paramErr) if NO protocols are enabled, which can
- * in fact happen by malicious or ignorant use of SSLSetProtocolVersionEnabled().
- */
-OSStatus sslGetMaxProtVersion(
-       SSLContext                      *ctx,
-       SSLProtocolVersion      *version)       // RETURNED
-{
-    /* This check is here until SSLSetProtocolVersionEnabled() is gone .*/
-    if (ctx->maxProtocolVersion == SSL_Version_Undetermined)
-        return badReqErr;
-
-    *version = ctx->maxProtocolVersion;
-    return noErr;
-}
index e31763b08c7f5d270423e33417a70fbf79009b90..40501aa6659f08eff5bf317a4046f1a8b146cdf7 100644 (file)
  */
 
 /*
  */
 
 /*
- * sslUtils.h
+ * sslUtils.h - - Misc. OS independant SSL utility functions
  */
 
 #ifndef _SSLUTILS_H_
 #define _SSLUTILS_H_ 1
 
  */
 
 #ifndef _SSLUTILS_H_
 #define _SSLUTILS_H_ 1
 
-#include "SecureTransport.h"
-#include "sslPriv.h"
+#include "sslTypes.h"
 
 #ifdef __cplusplus
 extern "C" {
 
 #ifdef __cplusplus
 extern "C" {
@@ -40,7 +39,7 @@ uint32_t SSLDecodeInt(
        size_t              length);
 uint8_t *SSLEncodeInt(
        uint8_t             *p,
        size_t              length);
 uint8_t *SSLEncodeInt(
        uint8_t             *p,
-       uint32_t            value,
+       size_t              value,
        size_t length);
 
 /* Same, but the value to encode is a size_t */
        size_t length);
 
 /* Same, but the value to encode is a size_t */
@@ -58,12 +57,10 @@ uint8_t* SSLEncodeUInt64(
        sslUint64           value);
 void IncrementUInt64(
        sslUint64                       *v);
        sslUint64           value);
 void IncrementUInt64(
        sslUint64                       *v);
-#if ENABLE_DTLS
 void SSLDecodeUInt64(
     const uint8_t *p,
     size_t length,
     sslUint64 *v);
 void SSLDecodeUInt64(
     const uint8_t *p,
     size_t length,
     sslUint64 *v);
-#endif
 
 static inline
 int SSLHandshakeHeaderSize(SSLRecord *rec)
 
 static inline
 int SSLHandshakeHeaderSize(SSLRecord *rec)
@@ -74,68 +71,10 @@ int SSLHandshakeHeaderSize(SSLRecord *rec)
         return 4;
 }
 
         return 4;
 }
 
-uint8_t *SSLEncodeHandshakeHeader(
-    SSLContext *ctx,
-    SSLRecord *rec,
-    SSLHandshakeType type,
-    size_t msglen);
-
-#ifdef USE_SSLCERTIFICATE
-size_t SSLGetCertificateChainLength(
-       const SSLCertificate *c);
-OSStatus sslDeleteCertificateChain(
-       SSLCertificate          *certs,
-       SSLContext                      *ctx);
-#endif /* USE_SSLCERTIFICATE */
-
-Boolean sslIsSessionActive(
-       const SSLContext        *ctx);
-
-OSStatus sslTime(
-       uint32_t            *tim);
-
-#if    SSL_DEBUG
-extern const char *protocolVersStr(
-       SSLProtocolVersion      prot);
+#ifndef NDEBUG
+extern const char *protocolVersStr(SSLProtocolVersion prot);
 #endif
 #endif
-
-/*
- * Redirect SSLBuffer-based I/O call to user-supplied I/O.
- */
-OSStatus sslIoRead(
-       SSLBuffer               buf,
-       size_t                  *actualLength,
-       SSLContext              *ctx);
-
-OSStatus sslIoWrite(
-       SSLBuffer               buf,
-       size_t                  *actualLength,
-       SSLContext              *ctx);
-
-/*
- * Common RNG function.
- */
-OSStatus sslRand(
-       SSLContext              *ctx,
-       SSLBuffer               *buf);
-
-OSStatus sslVerifyProtVersion(
-       SSLContext                      *ctx,
-       SSLProtocolVersion      peerVersion,
-       SSLProtocolVersion      *negVersion);
-
-OSStatus sslGetMaxProtVersion(
-       SSLContext                      *ctx,
-       SSLProtocolVersion      *version);      // RETURNED
-
-static inline bool sslVersionIsLikeTls12(SSLContext *ctx)
-{
-    assert(ctx->negProtocolVersion!=SSL_Version_Undetermined);
-    return ctx->isDTLS ? ctx->negProtocolVersion > DTLS_Version_1_0 : ctx->negProtocolVersion >= TLS_Version_1_2;
-}
-
-#define SET_SSL_BUFFER(buf, d, l)   do { (buf).data = (d); (buf).length = (l); } while (0)
-
 #ifdef __cplusplus
 }
 #endif
 #ifdef __cplusplus
 }
 #endif
index 45d9ef8efb9fd5c47854351c11d2451375bd1222..aab1ec059394bdea6b0615b32be00e2dbd70ae1d 100644 (file)
  */
 
 /*
  */
 
 /*
- * symCipher.c - CDSA-based symmetric cipher module
+ * symCipher.c - CommonCrypto-based symmetric cipher module
  */
 
  */
 
-#include "sslContext.h"
-#include "cryptType.h"
+/* THIS FILE CONTAINS KERNEL CODE */
+
+#include "sslBuildFlags.h"
 #include "sslDebug.h"
 #include "sslMemory.h"
 #include "sslDebug.h"
 #include "sslMemory.h"
-#include <CommonCrypto/CommonCryptor.h>
 #include "symCipher.h"
 #include "symCipher.h"
+#include "cipherSpecs.h"
+#include "SSLRecordInternal.h"
+
+#ifdef KERNEL
+
+#include <corecrypto/ccaes.h>
+#include <corecrypto/ccdes.h>
+#include <corecrypto/ccmode.h>
+
+#include <AssertMacros.h>
+
+struct SymCipherContext {
+    const struct ccmode_cbc *cbc;
+    cccbc_ctx u[]; /* this will have the key and iv */
+};
+
+/* Macros for accessing the content of a SymCipherContext */
+/*
+ SymCipherContext looks like this in memory:
+ {
+    const struct ccmode_cbc *cbc;
+    cccbc_ctx key[n];
+    cccbc_iv  iv[m];
+ }
+ cccbc_ctx and cccbc_iv are typedef-ined as aligned opaque struct, the actual contexts are arrays
+ of those types normally declared with a cc_ctx_decl macro.
+ The cc_ctx_n macros gives the number of elements in those arrays that are needed to store the
+ contexts.
+ The size of the context depends on the actual cbc implementation used.
+*/
+
+
+/* CTX_SIZE: Total size of the SymCipherContext struct for a cbc implementation */
+static inline
+size_t CTX_SIZE(const struct ccmode_cbc *cbc)
+{
+#ifdef __CC_HAS_FIX_FOR_11468135__
+    return (sizeof(SymCipherContext) + (sizeof(cccbc_ctx) * (cc_ctx_n(cccbc_ctx, cbc->size) + cc_ctx_n(cccbc_iv, cbc->block_size))));
+#else
+    /* This is approximate, but will work in that case, this code will go away after we transition */
+    return (sizeof(SymCipherContext) + sizeof(cccbc_ctx) + cbc->size);
+#endif
+}
+
+/* CTX_KEY: Address of the key context in the SymCipherContext struct */
+static inline
+cccbc_ctx *CTX_KEY(struct SymCipherContext *ctx)
+{
+    return &ctx->u[0];
+}
+
+
+/* CTX_IV: Address of the iv context in the SymCipherContext struct */
+#ifdef __CC_HAS_FIX_FOR_11468135__
+static inline
+cccbc_iv *CTX_IV(struct SymCipherContext *ctx)
+{
+    return (cccbc_iv *)&ctx->u[cc_ctx_n(cccbc_ctx, ctx->cbc->size)];
+}
+#endif
+
+static
+const void *ccmode(SSL_CipherAlgorithm alg, int enc)
+{
+    switch(alg) {
+        case SSL_CipherAlgorithmAES_128_CBC:
+        case SSL_CipherAlgorithmAES_256_CBC:
+            return enc?ccaes_cbc_encrypt_mode():ccaes_cbc_decrypt_mode();
+        case SSL_CipherAlgorithm3DES_CBC:
+            return enc?ccdes3_cbc_encrypt_mode():ccdes3_cbc_decrypt_mode();
+        case SSL_CipherAlgorithmAES_128_GCM:
+        case SSL_CipherAlgorithmAES_256_GCM:
+        case SSL_CipherAlgorithmRC4_128:
+            /* TODO: we should do RC4 for TLS, but we dont need it for DTLS */
+        default:
+            check(0);
+            return NULL; /* This will cause CCCryptorCreate to return an error */
+    }
+}
+
+static
+int CCSymmInit(
+    const SSLSymmetricCipherParams *params,
+    int encrypting,
+    uint8_t *key,
+    uint8_t* iv,
+    SymCipherContext *cipherCtx)
+{
+    check(cipherCtx!=NULL);
+    check(params);
+    SymCipherContext ctx = *cipherCtx;
+
+       /*
+        * Cook up a cccbx_ctx object. Assumes:
+        *              cipherCtx->symCipher.keyAlg
+        *              cipherCtx->encrypting
+        *              key (raw key bytes)
+        *              iv (raw bytes)
+        * On successful exit:
+        *              Resulting ccmode --> cipherCtx
+        */
+
+    /* FIXME: this should not be needed as long as CCSymFinish is called */
+       if(ctx) {
+        sslFree(ctx);
+        ctx = NULL;
+       }
+
+    const struct ccmode_cbc *cbc = ccmode(params->keyAlg, encrypting);
+
+    ctx = sslMalloc(CTX_SIZE(cbc));
+
+    if(ctx==NULL) {
+        sslErrorLog("CCSymmInit: Can't allocate context\n");
+        return errSSLRecordInternal;
+    }
+
+    ctx->cbc = cbc;
+
+#ifdef __CC_HAS_FIX_FOR_11468135__
+    cccbc_init(cbc, CTX_KEY(ctx), params->keySize, key);
+    cccbc_set_iv(cbc, CTX_IV(ctx), iv);
+#else
+    cccbc_init(cbc, CTX_KEY(ctx), params->keySize, key, iv);
+#endif
+
+    *cipherCtx = ctx;
+       return 0;
+}
+
+/* same for en/decrypt */
+static
+int CCSymmEncryptDecrypt(
+                         const uint8_t *src,
+                         uint8_t *dest,
+                         size_t len,
+                         SymCipherContext cipherCtx)
+{
+
+       ASSERT(cipherCtx != NULL);
+    ASSERT(cipherCtx->cbc != NULL);
+
+       if(cipherCtx == NULL || cipherCtx->cbc == NULL) {
+               sslErrorLog("CCSymmEncryptDecrypt: NULL cipherCtx\n");
+               return errSSLRecordInternal;
+       }
+
+    ASSERT((len%cipherCtx->cbc->block_size)==0);
+
+    if(len%cipherCtx->cbc->block_size) {
+        sslErrorLog("CCSymmEncryptDecrypt: Invalid size\n");
+        return errSSLRecordInternal;
+    }
+
+    unsigned long nblocks = len/cipherCtx->cbc->block_size;
+
+#ifdef __CC_HAS_FIX_FOR_11468135__
+    cccbc_update(cipherCtx->cbc, CTX_KEY(cipherCtx), CTX_IV(cipherCtx), nblocks, src, dest);
+#else
+    cipherCtx->cbc->cbc(CTX_KEY(cipherCtx), nblocks, src, dest);
+#endif
+       return 0;
+}
+
+static
+int CCSymmFinish(
+                 SymCipherContext cipherCtx)
+{
+       if(cipherCtx) {
+        sslFree(cipherCtx);
+       }
+       return 0;
+}
+
+
+#else
+
+#define ENABLE_RC4      1
+#define ENABLE_3DES     1
+#define ENABLE_AES      1
+#define ENABLE_AES256   1
 
 /*
  * CommonCrypto-based symmetric cipher callouts
  */
 
 /*
  * CommonCrypto-based symmetric cipher callouts
  */
-OSStatus CCSymmInit(
-       uint8_t *key,
-       uint8_t* iv,
-       CipherContext *cipherCtx,
-       SSLContext *ctx)
+#include <CommonCrypto/CommonCryptor.h>
+#include <CommonCrypto/CommonCryptorSPI.h>
+#include <assert.h>
+
+static
+CCAlgorithm CCAlg(SSL_CipherAlgorithm alg)
+{
+    switch(alg) {
+        case SSL_CipherAlgorithmAES_128_CBC:
+        case SSL_CipherAlgorithmAES_256_CBC:
+        case SSL_CipherAlgorithmAES_128_GCM:
+        case SSL_CipherAlgorithmAES_256_GCM:
+            return kCCAlgorithmAES128;          /* AES128 here means 128bit block size, not key size */
+        case SSL_CipherAlgorithm3DES_CBC:
+            return kCCAlgorithm3DES;
+        case SSL_CipherAlgorithmDES_CBC:
+            return kCCAlgorithmDES;
+        case SSL_CipherAlgorithmRC4_128:
+            return kCCAlgorithmRC4;
+        case SSL_CipherAlgorithmRC2_128:
+            return kCCAlgorithmRC2;
+        default:
+            assert(0);
+            return (CCAlgorithm)(-1); /* This will cause CCCryptorCreate to return an error */
+    }
+}
+
+static CCOptions CCOpt(CipherType cipherType)
 {
 {
+#if 0
+    if(cipherType==aeadCipherType) return kCCModeGCM;
+#endif
+    return 0;
+}
+
+static
+int CCSymmInit(
+    const SSLSymmetricCipherParams *params,
+    int encrypting,
+       uint8_t *key, 
+       uint8_t* iv, 
+       SymCipherContext *cipherCtx)
+{
+    assert(cipherCtx!=NULL);
+
        /*
         * Cook up a CCCryptorRef. Assumes:
         *              cipherCtx->symCipher.keyAlg
        /*
         * Cook up a CCCryptorRef. Assumes:
         *              cipherCtx->symCipher.keyAlg
@@ -51,62 +274,301 @@ OSStatus CCSymmInit(
         *              Resulting CCCryptorRef --> cipherCtx->cryptorRef
         */
        CCCryptorStatus ccrtn;
         *              Resulting CCCryptorRef --> cipherCtx->cryptorRef
         */
        CCCryptorStatus ccrtn;
-       CCOperation op = cipherCtx->encrypting ? kCCEncrypt : kCCDecrypt;
+       CCOperation op = encrypting ? kCCEncrypt : kCCDecrypt;
+    CCCryptorRef cryptorRef = (CCCryptorRef)*cipherCtx;
 
 
-       if(cipherCtx->cryptorRef) {
-               CCCryptorRelease(cipherCtx->cryptorRef);
-               cipherCtx->cryptorRef = NULL;
+    /* FIXME: this should not be needed as long as CCSymFinish is called */
+       if(cryptorRef) {
+               CCCryptorRelease(cryptorRef);
+               cryptorRef = NULL;
        }
 
        }
 
-       ccrtn = CCCryptorCreate(op, cipherCtx->symCipher->keyAlg,
-               0,              /* options - no padding, default CBC */
-               key, cipherCtx->symCipher->keySize,
+       ccrtn = CCCryptorCreate(op, CCAlg(params->keyAlg),
+        /* options - gcm or no padding, default CBC */
+        CCOpt(params->cipherType),
+               key, params->keySize,
                iv,
                iv,
-               &cipherCtx->cryptorRef);
+               &cryptorRef);
        if(ccrtn) {
                sslErrorLog("CCCryptorCreate returned %d\n", (int)ccrtn);
        if(ccrtn) {
                sslErrorLog("CCCryptorCreate returned %d\n", (int)ccrtn);
-               return internalComponentErr;
+               return errSSLRecordInternal;
        }
        }
-       return noErr;
+    *cipherCtx = (SymCipherContext)cryptorRef;
+       return 0;
 }
 
 /* same for en/decrypt */
 }
 
 /* same for en/decrypt */
-OSStatus CCSymmEncryptDecrypt(
-       const uint8_t *src,
-       uint8_t *dest,
-       size_t len,
-       CipherContext *cipherCtx,
-       SSLContext *ctx)
+static
+int CCSymmEncryptDecrypt(
+                              const uint8_t *src,
+                              uint8_t *dest,
+                              size_t len,
+                              SymCipherContext cipherCtx)
 {
        CCCryptorStatus ccrtn;
 {
        CCCryptorStatus ccrtn;
-
-       ASSERT(cipherCtx != NULL);
-       ASSERT(cipherCtx->cryptorRef != NULL);
-       if(cipherCtx->cryptorRef == NULL) {
+       CCCryptorRef cryptorRef = (CCCryptorRef)cipherCtx;
+       ASSERT(cryptorRef != NULL);
+       if(cryptorRef == NULL) {
                sslErrorLog("CCSymmEncryptDecrypt: NULL cryptorRef\n");
                sslErrorLog("CCSymmEncryptDecrypt: NULL cryptorRef\n");
-               return internalComponentErr;
+               return errSSLRecordInternal;
        }
     size_t data_moved;
        }
     size_t data_moved;
-       ccrtn = CCCryptorUpdate(cipherCtx->cryptorRef, src, len,
-               dest, len, &data_moved);
+       ccrtn = CCCryptorUpdate(cryptorRef, src, len,
+                            dest, len, &data_moved);
     assert(data_moved == len);
     assert(data_moved == len);
-       #if SSL_DEBUG
+#if SSL_DEBUG
        if(ccrtn) {
                sslErrorLog("CCSymmEncryptDecrypt: returned %d\n", (int)ccrtn);
        if(ccrtn) {
                sslErrorLog("CCSymmEncryptDecrypt: returned %d\n", (int)ccrtn);
-               return internalComponentErr;
+               return errSSLRecordInternal;
+       }
+#endif
+       return 0;
+}
+
+#if ENABLE_AES_GCM
+
+/* same for en/decrypt */
+static
+int CCSymmAEADSetIV(
+    const uint8_t *iv,
+    size_t len,
+    SymCipherContext cipherCtx)
+{
+       CCCryptorStatus ccrtn;
+       CCCryptorRef cryptorRef = (CCCryptorRef)cipherCtx;
+
+       ASSERT(cryptorRef != NULL);
+       if(cryptorRef == NULL) {
+               sslErrorLog("CCSymmAEADAddIV: NULL cryptorRef\n");
+               return errSecInternalComponent;
+       }
+       ccrtn = CCCryptorGCMAddIV(cryptorRef, iv, len);
+#if SSL_DEBUG
+       if(ccrtn) {
+               sslErrorLog("CCSymmAEADAddIV: returned %d\n", (int)ccrtn);
+               return errSSLRecordInternal;
+       }
+#endif
+       return 0;
+}
+
+/* same for en/decrypt */
+static
+int CCSymmAddADD(
+    const uint8_t *src,
+    size_t len,
+    SymCipherContext cipherCtx)
+{
+       CCCryptorStatus ccrtn;
+       CCCryptorRef cryptorRef = (CCCryptorRef)cipherCtx;
+
+       ASSERT(cryptorRef != NULL);
+       if(cryptorRef == NULL) {
+               sslErrorLog("CCSymmAddADD: NULL cryptorRef\n");
+               return errSSLRecordInternal;
+       }
+       ccrtn = CCCryptorGCMAddADD(cryptorRef, src, len);
+#if SSL_DEBUG
+       if(ccrtn) {
+               sslErrorLog("CCSymmAddADD: returned %d\n", (int)ccrtn);
+               return errSSLRecordInternal;
+       }
+#endif
+       return 0;
+}
+
+static
+int CCSymmAEADEncrypt(
+    const uint8_t *src,
+    uint8_t *dest,
+    size_t len,
+    SymCipherContext cipherCtx)
+{
+       CCCryptorStatus ccrtn;
+       CCCryptorRef cryptorRef = (CCCryptorRef)cipherCtx;
+
+       ASSERT(cryptorRef != NULL);
+       if(cryptorRef == NULL) {
+               sslErrorLog("CCSymmAEADEncrypt: NULL cryptorRef\n");
+               return errSSLRecordInternal;
+       }
+       ccrtn = CCCryptorGCMEncrypt(cryptorRef, src, len, dest);
+#if SSL_DEBUG
+       if(ccrtn) {
+               sslErrorLog("CCSymmAEADEncrypt: returned %d\n", (int)ccrtn);
+               return errSSLRecordInternal;
        }
        }
-       #endif
-       return noErr;
+#endif
+       return 0;
 }
 
 }
 
-OSStatus CCSymmFinish(
-       CipherContext *cipherCtx,
-       SSLContext *ctx)
+
+static
+int CCSymmAEADDecrypt(
+    const uint8_t *src,
+    uint8_t *dest,
+    size_t len,
+    SymCipherContext cipherCtx)
 {
 {
-       if(cipherCtx->cryptorRef) {
-               CCCryptorRelease(cipherCtx->cryptorRef);
-               cipherCtx->cryptorRef = NULL;
+       CCCryptorStatus ccrtn;
+       CCCryptorRef cryptorRef = (CCCryptorRef)cipherCtx;
+
+       ASSERT(cipherCtx != NULL);
+       ASSERT(cipherCtx->cryptorRef != NULL);
+       if(cipherCtx->cryptorRef == NULL) {
+               sslErrorLog("CCSymmAEADDecrypt: NULL cryptorRef\n");
+               return errSSLRecordInternal;
+       }
+       ccrtn = CCCryptorGCMDecrypt(cryptorRef, src, len, dest);
+#if SSL_DEBUG
+       if(ccrtn) {
+               sslErrorLog("CCSymmAEADDecrypt: returned %d\n", (int)ccrtn);
+               return errSSLRecordInternal;
        }
        }
-       return noErr;
+#endif
+       return 0;
 }
 
 }
 
+
+static
+int CCSymmAEADDone(
+    uint8_t *mac,
+    size_t *macLen,
+    SymCipherContext cipherCtx)
+{
+       CCCryptorStatus ccrtn;
+       CCCryptorRef cryptorRef = (CCCryptorRef)cipherCtx;
+
+       ASSERT(cipherCtx != NULL);
+       ASSERT(cipherCtx->cryptorRef != NULL);
+       if(cipherCtx->cryptorRef == NULL) {
+               sslErrorLog("CCSymmAEADDone: NULL cryptorRef\n");
+               return errSSLRecordInternal;
+       }
+       ccrtn = CCCryptorGCMFinal(cipherCtx->cryptorRef, mac, macLen);
+    CCCryptorStatus ccrtn2 = CCCryptorGCMReset(cipherCtx->cryptorRef);
+    if (ccrtn == kCCSuccess)
+        ccrtn = ccrtn2;
+#if SSL_DEBUG
+       if(ccrtn) {
+               sslErrorLog("CCSymmAEADDone: returned %d\n", (int)ccrtn);
+               return errSSLRecordInternal;
+       }
+#endif
+       return 0;
+}
+#endif
+
+static
+int CCSymmFinish(
+       SymCipherContext cipherCtx)
+{
+       CCCryptorRef cryptorRef = (CCCryptorRef)cipherCtx;
+
+       if(cryptorRef) {
+               CCCryptorRelease(cryptorRef);
+       }
+       return 0;
+}
+
+#endif /* KERNEL */
+
+#if    ENABLE_DES
+const SSLSymmetricCipher SSLCipherDES_CBC = {
+    .params = &SSLCipherDES_CBCParams,
+    .c.cipher = {
+        .initialize = CCSymmInit,
+        .encrypt = CCSymmEncryptDecrypt,
+        .decrypt = CCSymmEncryptDecrypt
+    },
+    .finish = CCSymmFinish
+};
+#endif /* ENABLE_DES */
+
+#if    ENABLE_3DES
+const SSLSymmetricCipher SSLCipher3DES_CBC = {
+    .params = &SSLCipher3DES_CBCParams,
+    .c.cipher = {
+        .initialize = CCSymmInit,
+        .encrypt = CCSymmEncryptDecrypt,
+        .decrypt = CCSymmEncryptDecrypt
+    },
+    .finish = CCSymmFinish
+};
+#endif /* ENABLE_3DES */
+
+#if            ENABLE_RC4
+const SSLSymmetricCipher SSLCipherRC4_128 = {
+    .params = &SSLCipherRC4_128Params,
+    .c.cipher = {
+        .initialize = CCSymmInit,
+        .encrypt = CCSymmEncryptDecrypt,
+        .decrypt = CCSymmEncryptDecrypt
+    },
+    .finish = CCSymmFinish
+};
+#endif /* ENABLE_RC4 */
+
+#if            ENABLE_RC2
+const SSLSymmetricCipher SSLCipherRC2_128 = {
+    .params = &SSLCipherRC2_128Params,
+    .c.cipher = {
+        .initialize = CCSymmInit,
+        .encrypt = CCSymmEncryptDecrypt,
+        .decrypt = CCSymmEncryptDecrypt
+    },
+    .finish = CCSymmFinish
+};
+#endif /* ENABLE_RC2*/
+
+#if            ENABLE_AES
+const SSLSymmetricCipher SSLCipherAES_128_CBC = {
+    .params = &SSLCipherAES_128_CBCParams,
+    .c.cipher = {
+        .initialize = CCSymmInit,
+        .encrypt = CCSymmEncryptDecrypt,
+        .decrypt = CCSymmEncryptDecrypt
+    },
+    .finish = CCSymmFinish
+};
+#endif /* ENABLE_AES */
+
+#if ENABLE_AES256
+const SSLSymmetricCipher SSLCipherAES_256_CBC = {
+    .params = &SSLCipherAES_256_CBCParams,
+    .c.cipher = {
+        .initialize = CCSymmInit,
+        .encrypt = CCSymmEncryptDecrypt,
+        .decrypt = CCSymmEncryptDecrypt
+    },
+    .finish = CCSymmFinish
+};
+#endif /* ENABLE_AES256 */
+
+#if ENABLE_AES_GCM
+const SSLSymmetricCipher SSLCipherAES_128_GCM = {
+    .params = &SSLCipherAES_128_GCMParams,
+    .c.aead = {
+        .initialize = CCSymmInit,
+        .setIV = CCSymmAEADSetIV,
+        .update = CCSymmAddADD,
+        .encrypt = CCSymmAEADEncrypt,
+        .decrypt = CCSymmAEADDecrypt,
+        .done =  CCSymmAEADDone
+    },
+    .finish = CCSymmFinish
+};
+
+const SSLSymmetricCipher SSLCipherAES_256_GCM = {
+    .params = &SSLCipherAES_256_GCMParams,
+    .c.aead = {
+        .initialize = CCSymmInit,
+        .setIV = CCSymmAEADSetIV,
+        .update = CCSymmAddADD,
+        .encrypt = CCSymmAEADEncrypt,
+        .decrypt = CCSymmAEADDecrypt,
+        .done =  CCSymmAEADDone
+    },
+    .finish = CCSymmFinish
+};
+#endif /* ENABLE_AES_GCM */
index 0218616ceb4281432032eda2de462e2113ec4972..7fb0f61cf8627962be9f813a230bcae2ae29de51 100644 (file)
  */
 
 /*
  */
 
 /*
- * symCipher.h - CDSA-based symmetric cipher module
+ * symCipher.h - symmetric cipher module
  */
 
 #ifndef        _SYM_CIPHER_H_
 #define _SYM_CIPHER_H_
 
  */
 
 #ifndef        _SYM_CIPHER_H_
 #define _SYM_CIPHER_H_
 
-#include "sslContext.h"
-#include "cryptType.h"
-
+#include <sys/types.h>
+#include <stdint.h>
+#include "cipherSpecs.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-/*
- * CommonCrypto-based symmetric cipher callouts
- */
-OSStatus CCSymmInit(
-       uint8_t *key,
-       uint8_t* iv,
-       CipherContext *cipherCtx,
-       SSLContext *ctx);
-OSStatus CCSymmEncryptDecrypt(
-       const uint8_t *src,
-       uint8_t *dest,
-       size_t len,
-       CipherContext *cipherCtx,
-       SSLContext *ctx);
-OSStatus CCSymmFinish(
-       CipherContext *cipherCtx,
-       SSLContext *ctx);
+#define MASTER_SECRET_LEN      48      /* master secret = 3 x MD5 hashes concatenated */
+
+/* SSL V2 - mac secret is the size of symmetric key, not digest */
+#define MAX_SYMKEY_SIZE                24
+
+typedef enum
+{
+    streamCipherType,
+    blockCipherType,
+    aeadCipherType
+} CipherType;
+
+typedef struct  {
+    SSL_CipherAlgorithm keyAlg;
+    CipherType          cipherType;
+    uint8_t            keySize;            /* Sizes are in bytes */
+    uint8_t            ivSize;
+    uint8_t            blockSize;
+} SSLSymmetricCipherParams;
+
+
+/* All symmetric ciphers go thru these callouts. */
+struct SymCipherContext;
+typedef struct SymCipherContext *SymCipherContext;
+
+typedef int (*SSLKeyFunc)(
+                               const SSLSymmetricCipherParams *params,
+                               int encrypting,
+                               uint8_t *key,
+                               uint8_t *iv,
+                               SymCipherContext *cipherCtx);
+typedef int (*SSLSetIVFunc)(
+                                 const uint8_t *iv,
+                                 size_t len,
+                                 SymCipherContext cipherCtx);
+typedef int (*SSLAddADD)(
+                              const uint8_t *src,
+                              size_t len,
+                              SymCipherContext cipherCtx);
+typedef int (*SSLCryptFunc)(
+                                 const uint8_t *src,
+                                 uint8_t *dest,
+                                 size_t len,
+                                 SymCipherContext cipherCtx);
+typedef int (*SSLFinishFunc)(
+                                  SymCipherContext cipherCtx);
+typedef int (*SSLAEADDoneFunc)(
+                                    uint8_t *mac,
+                                    size_t *macLen,
+                                    SymCipherContext cipherCtx);
+
+/* Statically defined description of a symmetric cipher. */
+typedef struct {
+    SSLKeyFunc         initialize;
+    SSLCryptFunc       encrypt;
+    SSLCryptFunc       decrypt;
+} Cipher;
+
+typedef struct {
+    SSLKeyFunc         initialize;
+    SSLSetIVFunc        setIV;
+    SSLAddADD           update;
+    SSLCryptFunc       encrypt;
+    SSLCryptFunc       decrypt;
+    SSLAEADDoneFunc     done;
+    uint8_t            macSize;
+} AEADCipher;
+
+
+typedef struct SSLSymmetricCipher {
+    const SSLSymmetricCipherParams *params;
+    SSLFinishFunc      finish;
+    union {
+        const Cipher    cipher;  /* stream or block cipher type */
+        const AEADCipher aead;   /* aeadCipherType */
+    } c;
+} SSLSymmetricCipher;
+
+extern const SSLSymmetricCipher SSLCipherNull;
+extern const SSLSymmetricCipher SSLCipherRC2_40;
+extern const SSLSymmetricCipher SSLCipherRC2_128;
+extern const SSLSymmetricCipher SSLCipherRC4_40;
+extern const SSLSymmetricCipher SSLCipherRC4_128;
+extern const SSLSymmetricCipher SSLCipherDES40_CBC;
+extern const SSLSymmetricCipher SSLCipherDES_CBC;
+extern const SSLSymmetricCipher SSLCipher3DES_CBC;
+extern const SSLSymmetricCipher SSLCipherAES_128_CBC;
+extern const SSLSymmetricCipher SSLCipherAES_256_CBC;
+extern const SSLSymmetricCipher SSLCipherAES_128_GCM;
+extern const SSLSymmetricCipher SSLCipherAES_256_GCM;
+
+/* Those are defined in symCipherParams.c */
+extern const SSLSymmetricCipherParams SSLCipherNullParams;
+extern const SSLSymmetricCipherParams SSLCipherRC2_40Params;
+extern const SSLSymmetricCipherParams SSLCipherRC2_128Params;
+extern const SSLSymmetricCipherParams SSLCipherRC4_40Params;
+extern const SSLSymmetricCipherParams SSLCipherRC4_128Params;
+extern const SSLSymmetricCipherParams SSLCipherDES40_CBCParams;
+extern const SSLSymmetricCipherParams SSLCipherDES_CBCParams;
+extern const SSLSymmetricCipherParams SSLCipher3DES_CBCParams;
+extern const SSLSymmetricCipherParams SSLCipherAES_128_CBCParams;
+extern const SSLSymmetricCipherParams SSLCipherAES_256_CBCParams;
+extern const SSLSymmetricCipherParams SSLCipherAES_128_GCMParams;
+extern const SSLSymmetricCipherParams SSLCipherAES_256_GCMParams;
 
 #ifdef __cplusplus
 }
 
 #ifdef __cplusplus
 }
diff --git a/libsecurity_ssl/lib/symCipherParams.c b/libsecurity_ssl/lib/symCipherParams.c
new file mode 100644 (file)
index 0000000..1dfa43b
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 1999-2001,2005-2008,2010-2011 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * symCipherParams.c - symmetric cipher parameters
+ */
+
+/* THIS FILE CONTAINS KERNEL CODE */
+
+#include "sslBuildFlags.h"
+#include "symCipher.h"
+
+/*
+ * The parameters for the symmetric ciphers currently supported (in addition to the
+ * NULL cipher in nullciph.c).
+ */
+
+#if    ENABLE_DES
+const SSLSymmetricCipherParams SSLCipherDES_CBCParams = {
+    .keyAlg = SSL_CipherAlgorithmDES_CBC,
+    .keySize = 8,
+    .ivSize = 8,
+    .blockSize = 8,
+    .cipherType = blockCipherType,
+};
+#endif /* ENABLE_DES */
+
+#if    ENABLE_3DES
+const SSLSymmetricCipherParams SSLCipher3DES_CBCParams = {
+    .keyAlg = SSL_CipherAlgorithm3DES_CBC,
+    .keySize = 24,
+    .ivSize = 8,
+    .blockSize = 8,
+    .cipherType = blockCipherType,
+};
+#endif /* ENABLE_3DES */
+
+#if            ENABLE_RC4
+const SSLSymmetricCipherParams SSLCipherRC4_128Params = {
+    .keyAlg = SSL_CipherAlgorithmRC4_128,
+    .keySize = 16,
+    .cipherType = streamCipherType,
+};
+#endif /* ENABLE_RC4 */
+
+#if            ENABLE_RC2
+const SSLSymmetricCipherParams SSLCipherRC2_128Params = {
+    .keyAlg = SSL_CipherAlgorithmRC2_128,
+    .keySize = 16,
+    .ivSize = 8,
+    .blockSize = 8,
+    .cipherType = blockCipherType,
+};
+#endif /* ENABLE_RC2*/
+
+#if            ENABLE_AES
+const SSLSymmetricCipherParams SSLCipherAES_128_CBCParams = {
+    .keyAlg = SSL_CipherAlgorithmAES_128_CBC,
+    .keySize = 16,
+    .ivSize = 16,
+    .blockSize = 16,
+    .cipherType = blockCipherType,
+};
+#endif /* ENABLE_AES */
+
+#if ENABLE_AES256
+const SSLSymmetricCipherParams SSLCipherAES_256_CBCParams = {
+    .keyAlg = SSL_CipherAlgorithmAES_256_CBC,
+    .keySize = 32,
+    .ivSize = 16,
+    .blockSize = 16,
+    .cipherType = blockCipherType,
+};
+#endif /* ENABLE_AES256 */
+
+#if ENABLE_AES_GCM
+const SSLSymmetricCipherParams SSLCipherAES_128_GCMParams = {
+    .keyAlg = SSL_CipherAlgorithmAES_128_GCM,
+    .keySize = 16,
+    .ivSize = 16,
+    .blockSize = 16,
+    .cipherType = aeadCipherType,
+};
+
+const SSLSymmetricCipherParams SSLCipherAES_256_GCMParams = {
+    .keyAlg = SSL_CipherAlgorithmAES_256_GCM,
+    .keySize = 32,
+    .ivSize = 16,
+    .blockSize = 16,
+    .cipherType = aeadCipherType,
+};
+#endif /* ENABLE_AES_GCM */
index ca06db05a83c10094924b8261a06101b6c668070..9c873f7613738109b4aa2dccd81489cf07b56d59 100644 (file)
@@ -25,6 +25,8 @@
  * tls1Callouts.c - TLSv1-specific routines for SslTlsCallouts.
  */
 
  * tls1Callouts.c - TLSv1-specific routines for SslTlsCallouts.
  */
 
+#include "SecureTransport.h"
+
 #include "tls_ssl.h"
 #include "sslMemory.h"
 #include "sslUtils.h"
 #include "tls_ssl.h"
 #include "sslMemory.h"
 #include "sslUtils.h"
@@ -32,6 +34,7 @@
 #include "sslAlertMessage.h"
 #include "sslCrypto.h"
 #include "sslDebug.h"
 #include "sslAlertMessage.h"
 #include "sslCrypto.h"
 #include "sslDebug.h"
+#include "tls_hmac.h"
 #include <assert.h>
 #include <strings.h>
 
 #include <assert.h>
 #include <strings.h>
 
@@ -59,8 +62,8 @@ static void tlsDump(const char *name, void *b, unsigned len)
 #define tlsDump(name, b, len)
 #endif /* TLS_ENC_DEBUG */
 
 #define tlsDump(name, b, len)
 #endif /* TLS_ENC_DEBUG */
 
-#pragma mark -
-#pragma mark PRF label strings
+// MARK: -
+// MARK: PRF label strings
 /*
  * Note we could optimize away a bunch of mallocs and frees if we, like openSSL,
  * just mallocd buffers for inputs to SSLInternal_PRF() on the stack,
 /*
  * Note we could optimize away a bunch of mallocs and frees if we, like openSSL,
  * just mallocd buffers for inputs to SSLInternal_PRF() on the stack,
@@ -83,8 +86,8 @@ static void tlsDump(const char *name, void *b, unsigned len)
 #define PLS_EXPORT_IV_BLOCK                    "IV block"
 #define PLS_EXPORT_IV_BLOCK_LEN                8
 
 #define PLS_EXPORT_IV_BLOCK                    "IV block"
 #define PLS_EXPORT_IV_BLOCK_LEN                8
 
-#pragma mark -
-#pragma mark private functions
+// MARK: -
+// MARK: private functions
 
 /*
  * P_Hash function defined in RFC2246, section 5.
 
 /*
  * P_Hash function defined in RFC2246, section 5.
@@ -104,8 +107,8 @@ static OSStatus tlsPHash(
        HMACContextRef hmacCtx;
        OSStatus serr;
        size_t digestLen = hmac->macSize;
        HMACContextRef hmacCtx;
        OSStatus serr;
        size_t digestLen = hmac->macSize;
-
-       serr = hmac->alloc(hmac, ctx, secret, secretLen, &hmacCtx);
+       
+       serr = hmac->alloc(hmac, secret, secretLen, &hmacCtx);
        if(serr) {
                return serr;
        }
        if(serr) {
                return serr;
        }
@@ -206,7 +209,7 @@ OSStatus SSLInternal_PRF(
                labelSeedLen = labelLen + seedLen;
                labelSeed = (unsigned char *)sslMalloc(labelSeedLen);
                if(labelSeed == NULL) {
                labelSeedLen = labelLen + seedLen;
                labelSeed = (unsigned char *)sslMalloc(labelSeedLen);
                if(labelSeed == NULL) {
-                       return memFullErr;
+                       return errSecAllocate;
                }
                memmove(labelSeed, label, labelLen);
                memmove(labelSeed + labelLen, seed, seedLen);
                }
                memmove(labelSeed, label, labelLen);
                memmove(labelSeed + labelLen, seed, seedLen);
@@ -220,8 +223,8 @@ OSStatus SSLInternal_PRF(
     unsigned char *out = (unsigned char *)vout;
     if(sslVersionIsLikeTls12(ctx)) {
         const HMACReference *mac = &TlsHmacSHA256;
     unsigned char *out = (unsigned char *)vout;
     if(sslVersionIsLikeTls12(ctx)) {
         const HMACReference *mac = &TlsHmacSHA256;
-        if (ctx->selectedCipherSpec.macAlgorithm->hmac->alg == HA_SHA384) {
-            mac = ctx->selectedCipherSpec.macAlgorithm->hmac;
+        if (ctx->selectedCipherSpecParams.macAlg == HA_SHA384) {
+            mac = &TlsHmacSHA384;
         }
         serr = tlsPHash(ctx, mac, secret, secretLen, labelSeed, labelSeedLen,
                         out, outLen);
         }
         serr = tlsPHash(ctx, mac, secret, secretLen, labelSeed, labelSeedLen,
                         out, outLen);
@@ -238,7 +241,7 @@ OSStatus SSLInternal_PRF(
         /* temporary output for SHA1, to be XORd with MD5 */
         tmpOut = (unsigned char *)sslMalloc(outLen);
         if(tmpOut == NULL) {
         /* temporary output for SHA1, to be XORd with MD5 */
         tmpOut = (unsigned char *)sslMalloc(outLen);
         if(tmpOut == NULL) {
-            serr = memFullErr;
+            serr = errSecAllocate;
             goto fail;
         }
 
             goto fail;
         }
 
@@ -259,7 +262,7 @@ OSStatus SSLInternal_PRF(
         }
        }
 
         }
        }
 
-    serr = noErr;
+    serr = errSecSuccess;
 fail:
        if((labelSeed != NULL) && (label != NULL)) {
                sslFree(labelSeed);
 fail:
        if((labelSeed != NULL) && (label != NULL)) {
                sslFree(labelSeed);
@@ -270,201 +273,6 @@ fail:
        return serr;
 }
 
        return serr;
 }
 
-/* not needed; encrypt/encode is the same for both protocols as long as
- * we don't use the "variable length padding" feature. */
-#if 0
-static OSStatus tls1WriteRecord(
-       SSLRecord rec,
-       SSLContext *ctx)
-{
-       assert(0);
-       return unimpErr;
-}
-#endif
-
-static OSStatus tls1DecryptRecord(
-       UInt8 type,
-       SSLBuffer *payload,
-       SSLContext *ctx)
-{
-       OSStatus    err;
-    SSLBuffer   content;
-       bool decryption_failed_or_bad_record_mac = false;
-
-    if ((ctx->readCipher.symCipher->blockSize > 0) &&
-        ((payload->length % ctx->readCipher.symCipher->blockSize) != 0)) {
-               SSLFatalSessionAlert(SSL_AlertRecordOverflow, ctx);
-        return errSSLRecordOverflow;
-    }
-
-    /* Decrypt in place */
-    if ((err = ctx->readCipher.symCipher->decrypt(payload->data,
-               payload->data, payload->length,
-               &ctx->readCipher,
-               ctx)) != 0)
-    {
-               /* note: we no longer send a SSL_AlertDecryptError here;
-                * all subsequent failures result in SSL_AlertBadRecordMac
-                * being sent at the end of the function, to avoid leaking
-                * differences between padding and decryption failures. */
-        decryption_failed_or_bad_record_mac = true;
-    }
-
-    /* Locate content within decrypted payload */
-
-    /* TLS 1.1 and DTLS 1.0 block ciphers */
-    if((ctx->negProtocolVersion>=TLS_Version_1_1) && (ctx->readCipher.symCipher->blockSize>0))
-    {
-        content.data = payload->data + ctx->readCipher.symCipher->blockSize;
-        content.length = payload->length - (ctx->readCipher.macRef->hash->digestSize + ctx->readCipher.symCipher->blockSize);
-    } else {
-        content.data = payload->data;
-        content.length = payload->length - ctx->readCipher.macRef->hash->digestSize;
-    }
-
-    if (ctx->readCipher.symCipher->blockSize > 0) {
-               /* for TLSv1, padding can be anywhere from 0 to 255 bytes */
-               UInt8 padSize = payload->data[payload->length - 1];
-               UInt8 *padChars;
-
-               /* verify that all padding bytes are equal - WARNING - OpenSSL code
-                * has a special case here dealing with some kind of bug related to
-                * even size packets...beware... */
-               if(padSize > payload->length) {
-            /* This is TLS 1.1 compliant - Do it for all protocols versions */
-               sslErrorLog("tls1DecryptRecord: bad padding length (%d)\n",
-                       (unsigned)payload->data[payload->length - 1]);
-                       decryption_failed_or_bad_record_mac = true;
-               }
-               padChars = payload->data + payload->length - padSize;
-               while(padChars < (payload->data + payload->length)) {
-                       if(*padChars++ != padSize) {
-                /* This is TLS 1.1 compliant - Do it for all protocols versions */
-                               sslErrorLog("tls1DecryptRecord: bad padding value\n");
-                               decryption_failed_or_bad_record_mac = true;
-                       }
-               }
-               /* Remove block size padding and its one-byte length */
-        content.length -= (1 + padSize);
-    }
-
-       /* Verify MAC on payload */
-    if (ctx->readCipher.macRef->hash->digestSize > 0)
-               /* Optimize away MAC for null case */
-        if ((err = SSLVerifyMac(type, &content,
-                               content.data + content.length, ctx)) != 0)
-        {
-                       decryption_failed_or_bad_record_mac = true;
-        }
-
-       if (decryption_failed_or_bad_record_mac) {
-               SSLFatalSessionAlert(SSL_AlertBadRecordMac, ctx);
-               return errSSLDecryptionFail;
-       }
-
-    *payload = content;     /* Modify payload buffer to indicate content length */
-
-    return noErr;
-}
-
-/* initialize a per-CipherContext HashHmacContext for use in MACing each record */
-static OSStatus tls1InitMac (
-       CipherContext *cipherCtx,               // macRef, macSecret valid on entry
-                                                                       // macCtx valid on return
-       SSLContext *ctx)
-{
-       const HMACReference *hmac;
-       OSStatus serr;
-
-       assert(cipherCtx->macRef != NULL);
-       hmac = cipherCtx->macRef->hmac;
-       assert(hmac != NULL);
-
-       if(cipherCtx->macCtx.hmacCtx != NULL) {
-               hmac->free(cipherCtx->macCtx.hmacCtx);
-               cipherCtx->macCtx.hmacCtx = NULL;
-       }
-       serr = hmac->alloc(hmac, ctx, cipherCtx->macSecret,
-               cipherCtx->macRef->hmac->macSize, &cipherCtx->macCtx.hmacCtx);
-
-       /* mac secret now stored in macCtx.hmacCtx, delete it from cipherCtx */
-       memset(cipherCtx->macSecret, 0, sizeof(cipherCtx->macSecret));
-       return serr;
-}
-
-static OSStatus tls1FreeMac (
-       CipherContext *cipherCtx)
-{
-       /* this can be called on a completely zeroed out CipherContext... */
-       if(cipherCtx->macRef == NULL) {
-               return noErr;
-       }
-       assert(cipherCtx->macRef->hmac != NULL);
-
-       if(cipherCtx->macCtx.hmacCtx != NULL) {
-               cipherCtx->macRef->hmac->free(cipherCtx->macCtx.hmacCtx);
-               cipherCtx->macCtx.hmacCtx = NULL;
-       }
-       return noErr;
-}
-
-/*
- * mac = HMAC_hash(MAC_write_secret, seq_num + TLSCompressed.type +
- *                                     TLSCompressed.version + TLSCompressed.length +
- *                                     TLSCompressed.fragment));
- */
-
-/* sequence, type, version, length */
-#define HDR_LENGTH (8 + 1 + 2 + 2)
-static OSStatus tls1ComputeMac (
-       UInt8 type,
-       SSLBuffer data,
-       SSLBuffer mac,                                  // caller mallocs data
-       CipherContext *cipherCtx,               // assumes macCtx, macRef
-       sslUint64 seqNo,
-       SSLContext *ctx)
-{
-       uint8_t hdr[HDR_LENGTH];
-       uint8_t *p;
-       HMACContextRef hmacCtx;
-       OSStatus serr;
-       const HMACReference *hmac;
-       size_t macLength;
-
-       assert(cipherCtx != NULL);
-       assert(cipherCtx->macRef != NULL);
-       hmac = cipherCtx->macRef->hmac;
-       assert(hmac != NULL);
-       hmacCtx = cipherCtx->macCtx.hmacCtx;    // may be NULL, for null cipher
-
-       serr = hmac->init(hmacCtx);
-       if(serr) {
-               goto fail;
-       }
-       p = SSLEncodeUInt64(hdr, seqNo);
-       *p++ = type;
-       *p++ = ctx->negProtocolVersion >> 8;
-       *p++ = ctx->negProtocolVersion & 0xff;
-       *p++ = data.length >> 8;
-       *p   = data.length & 0xff;
-       serr = hmac->update(hmacCtx, hdr, HDR_LENGTH);
-       if(serr) {
-               goto fail;
-       }
-       serr = hmac->update(hmacCtx, data.data, data.length);
-       if(serr) {
-               goto fail;
-       }
-       macLength = mac.length;
-       serr = hmac->final(hmacCtx, mac.data, &macLength);
-       if(serr) {
-               goto fail;
-       }
-       mac.length = macLength;
-fail:
-       return serr;
-}
-
 /*
  * On input, the following are valid:
  *             MasterSecret[48]
 /*
  * On input, the following are valid:
  *             MasterSecret[48]
@@ -506,96 +314,6 @@ static OSStatus tls1GenerateKeyMaterial (
        return serr;
 }
 
        return serr;
 }
 
-/*
- *     final_client_write_key =
- *                     PRF(SecurityParameters.client_write_key,
- *                                 "client write key",
- *                                 SecurityParameters.client_random +
- *                                 SecurityParameters.server_random);
- *     final_server_write_key =
- *             PRF(SecurityParameters.server_write_key,
- *                                 "server write key",
- *                                 SecurityParameters.client_random +
- *                                 SecurityParameters.server_random);
- *
- *     iv_block = PRF("", "IV block", SecurityParameters.client_random +
- *                      SecurityParameters.server_random);
- *
- *        iv_block is broken up into:
- *
- *                     client_write_IV[SecurityParameters.IV_size]
- *             server_write_IV[SecurityParameters.IV_size]
- */
-static OSStatus tls1GenerateExportKeyAndIv (
-       SSLContext *ctx,                                // clientRandom, serverRandom valid
-       const SSLBuffer clientWriteKey,
-       const SSLBuffer serverWriteKey,
-       SSLBuffer finalClientWriteKey,  // RETURNED, mallocd by caller
-       SSLBuffer finalServerWriteKey,  // RETURNED, mallocd by caller
-       SSLBuffer finalClientIV,                // RETURNED, mallocd by caller
-       SSLBuffer finalServerIV)                // RETURNED, mallocd by caller
-{
-       unsigned char randBuf[2 * SSL_CLIENT_SRVR_RAND_SIZE];
-       OSStatus serr;
-       unsigned char *ivBlock;
-       char *nullKey = "";
-
-       /* all three PRF calls use the same seed */
-       memmove(randBuf, ctx->clientRandom, SSL_CLIENT_SRVR_RAND_SIZE);
-       memmove(randBuf + SSL_CLIENT_SRVR_RAND_SIZE,
-               ctx->serverRandom, SSL_CLIENT_SRVR_RAND_SIZE);
-
-       serr = SSLInternal_PRF(ctx,
-               clientWriteKey.data,
-               clientWriteKey.length,
-               (const unsigned char *)PLS_EXPORT_CLIENT_WRITE,
-               PLS_EXPORT_CLIENT_WRITE_LEN,
-               randBuf,
-               2 * SSL_CLIENT_SRVR_RAND_SIZE,
-               finalClientWriteKey.data,               // destination
-               finalClientWriteKey.length);
-       if(serr) {
-               return serr;
-       }
-       serr = SSLInternal_PRF(ctx,
-               serverWriteKey.data,
-               serverWriteKey.length,
-               (const unsigned char *)PLS_EXPORT_SERVER_WRITE,
-               PLS_EXPORT_SERVER_WRITE_LEN,
-               randBuf,
-               2 * SSL_CLIENT_SRVR_RAND_SIZE,
-               finalServerWriteKey.data,               // destination
-               finalServerWriteKey.length);
-       if(serr) {
-               return serr;
-       }
-       if((finalClientIV.length == 0) && (finalServerIV.length == 0)) {
-               /* skip remainder as optimization */
-               return noErr;
-       }
-       ivBlock = (unsigned char *)sslMalloc(finalClientIV.length + finalServerIV.length);
-       if(ivBlock == NULL) {
-               return memFullErr;
-       }
-       serr = SSLInternal_PRF(ctx,
-               (const unsigned char *)nullKey,
-               0,
-               (const unsigned char *)PLS_EXPORT_IV_BLOCK,
-               PLS_EXPORT_IV_BLOCK_LEN,
-               randBuf,
-               2 * SSL_CLIENT_SRVR_RAND_SIZE,
-               ivBlock,                                        // destination
-               finalClientIV.length + finalServerIV.length);
-       if(serr) {
-               goto done;
-       }
-       memmove(finalClientIV.data, ivBlock, finalClientIV.length);
-       memmove(finalServerIV.data, ivBlock + finalClientIV.length, finalServerIV.length);
-done:
-       sslFree(ivBlock);
-       return serr;
-}
-
 /*
  * On entry: clientRandom, serverRandom, preMasterSecret valid
  * On return: masterSecret valid
 /*
  * On entry: clientRandom, serverRandom, preMasterSecret valid
  * On return: masterSecret valid
@@ -649,9 +367,9 @@ static OSStatus tls1ComputeFinishedMac (
 
     shaMsgState.data = 0;
     md5MsgState.data = 0;
 
     shaMsgState.data = 0;
     md5MsgState.data = 0;
-    if ((serr = CloneHashState(&SSLHashSHA1, &ctx->shaState, &shaMsgState, ctx)) != 0)
+    if ((serr = CloneHashState(&SSLHashSHA1, &ctx->shaState, &shaMsgState)) != 0)
         goto fail;
         goto fail;
-    if ((serr = CloneHashState(&SSLHashMD5, &ctx->md5State, &md5MsgState, ctx)) != 0)
+    if ((serr = CloneHashState(&SSLHashMD5, &ctx->md5State, &md5MsgState)) != 0)
         goto fail;
 
        if(isServer) {
         goto fail;
 
        if(isServer) {
@@ -687,8 +405,8 @@ static OSStatus tls1ComputeFinishedMac (
                finished.length);
 
 fail:
                finished.length);
 
 fail:
-    SSLFreeBuffer(&shaMsgState, ctx);
-    SSLFreeBuffer(&md5MsgState, ctx);
+    SSLFreeBuffer(&shaMsgState);
+    SSLFreeBuffer(&md5MsgState);
 
     return serr;
 }
 
     return serr;
 }
@@ -715,7 +433,7 @@ static OSStatus tls12ComputeFinishedMac (
     const SSLBuffer *ctxHashState;
 
     /* The PRF used in the finished message is based on the cipherspec */
     const SSLBuffer *ctxHashState;
 
     /* The PRF used in the finished message is based on the cipherspec */
-    if (ctx->selectedCipherSpec.macAlgorithm->hmac->alg == HA_SHA384) {
+    if (ctx->selectedCipherSpecParams.macAlg == HA_SHA384) {
         hashRef = &SSLHashSHA384;
         ctxHashState = &ctx->sha512State;
     } else {
         hashRef = &SSLHashSHA384;
         ctxHashState = &ctx->sha512State;
     } else {
@@ -724,7 +442,7 @@ static OSStatus tls12ComputeFinishedMac (
     }
 
     hashState.data = 0;
     }
 
     hashState.data = 0;
-    if ((serr = CloneHashState(hashRef, ctxHashState, &hashState, ctx)) != 0)
+    if ((serr = CloneHashState(hashRef, ctxHashState, &hashState)) != 0)
         goto fail;
        if(isServer) {
                finLabel = PLS_SERVER_FINISH;
         goto fail;
        if(isServer) {
                finLabel = PLS_SERVER_FINISH;
@@ -750,7 +468,7 @@ static OSStatus tls12ComputeFinishedMac (
                            finished.data,                              // destination
                            finished.length);
 fail:
                            finished.data,                              // destination
                            finished.length);
 fail:
-    SSLFreeBuffer(&hashState, ctx);
+    SSLFreeBuffer(&hashState);
     return serr;
 }
 
     return serr;
 }
 
@@ -773,9 +491,9 @@ static OSStatus tls1ComputeCertVfyMac (
     shaMsgState.data = 0;
     md5MsgState.data = 0;
 
     shaMsgState.data = 0;
     md5MsgState.data = 0;
 
-    if ((serr = CloneHashState(&SSLHashSHA1, &ctx->shaState, &shaMsgState, ctx)) != 0)
+    if ((serr = CloneHashState(&SSLHashSHA1, &ctx->shaState, &shaMsgState)) != 0)
         goto fail;
         goto fail;
-    if ((serr = CloneHashState(&SSLHashMD5, &ctx->md5State, &md5MsgState, ctx)) != 0)
+    if ((serr = CloneHashState(&SSLHashMD5, &ctx->md5State, &md5MsgState)) != 0)
         goto fail;
 
     if ((ctx->protocolSide == kSSLServerSide && sslPubKeyGetAlgorithmID(ctx->peerPubKey) == kSecECDSAAlgorithmID) ||
         goto fail;
 
     if ((ctx->protocolSide == kSSLServerSide && sslPubKeyGetAlgorithmID(ctx->peerPubKey) == kSecECDSAAlgorithmID) ||
@@ -801,8 +519,8 @@ static OSStatus tls1ComputeCertVfyMac (
        serr = SSLHashSHA1.final(&shaMsgState, &digBuf);
 
 fail:
        serr = SSLHashSHA1.final(&shaMsgState, &digBuf);
 
 fail:
-    SSLFreeBuffer(&shaMsgState, ctx);
-    SSLFreeBuffer(&md5MsgState, ctx);
+    SSLFreeBuffer(&shaMsgState);
+    SSLFreeBuffer(&md5MsgState);
 
     return serr;
 }
 
     return serr;
 }
@@ -833,10 +551,11 @@ static OSStatus tls12ComputeCertVfyMac (
             ctxHashState = &ctx->sha512State;
             break;
         default:
             ctxHashState = &ctx->sha512State;
             break;
         default:
+            return errSSLInternal;
             break;
     }
 
             break;
     }
 
-    if ((serr = CloneHashState(hashRef, ctxHashState, &hashState, ctx)) != 0)
+    if ((serr = CloneHashState(hashRef, ctxHashState, &hashState)) != 0)
         goto fail;
 
        assert(finished->length >= (hashRef->digestSize));
         goto fail;
 
        assert(finished->length >= (hashRef->digestSize));
@@ -844,34 +563,21 @@ static OSStatus tls12ComputeCertVfyMac (
        serr = hashRef->final(&hashState, finished);
 
 fail:
        serr = hashRef->final(&hashState, finished);
 
 fail:
-    SSLFreeBuffer(&hashState, ctx);
+    SSLFreeBuffer(&hashState);
 
     return serr;
 }
 
 
 const SslTlsCallouts Tls1Callouts = {
 
     return serr;
 }
 
 
 const SslTlsCallouts Tls1Callouts = {
-       tls1DecryptRecord,
-       ssl3WriteRecord,
-       tls1InitMac,
-       tls1FreeMac,
-       tls1ComputeMac,
        tls1GenerateKeyMaterial,
        tls1GenerateKeyMaterial,
-       tls1GenerateExportKeyAndIv,
        tls1GenerateMasterSecret,
        tls1ComputeFinishedMac,
        tls1ComputeCertVfyMac
 };
 
        tls1GenerateMasterSecret,
        tls1ComputeFinishedMac,
        tls1ComputeCertVfyMac
 };
 
-
 const SslTlsCallouts Tls12Callouts = {
 const SslTlsCallouts Tls12Callouts = {
-       tls1DecryptRecord,
-       ssl3WriteRecord,
-       tls1InitMac,
-       tls1FreeMac,
-       tls1ComputeMac,
        tls1GenerateKeyMaterial,
        tls1GenerateKeyMaterial,
-       tls1GenerateExportKeyAndIv,
        tls1GenerateMasterSecret,
        tls12ComputeFinishedMac,
        tls12ComputeCertVfyMac
        tls1GenerateMasterSecret,
        tls12ComputeFinishedMac,
        tls12ComputeCertVfyMac
diff --git a/libsecurity_ssl/lib/tls1RecordCallouts.c b/libsecurity_ssl/lib/tls1RecordCallouts.c
new file mode 100644 (file)
index 0000000..a3e2da9
--- /dev/null
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2002,2005-2007,2010-2011 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * tls1RecordCallouts.c - TLSv1-specific routines for SslTlsCallouts.
+ */
+
+/* THIS FILE CONTAINS KERNEL CODE */
+
+#include "tls_record.h"
+#include "sslMemory.h"
+#include "sslDebug.h"
+#include "sslUtils.h"
+
+#include <AssertMacros.h>
+#include <string.h>
+
+/* not needed; encrypt/encode is the same for both protocols as long as
+ * we don't use the "variable length padding" feature. */
+#if 0
+static int tls1WriteRecord(
+       SSLRecord rec,
+       SSLContext *ctx)
+{
+       check(0);
+       return errSecUnimplemented;
+}
+#endif
+
+static int tls1DecryptRecord(
+       uint8_t type,
+       SSLBuffer *payload,
+       struct SSLRecordInternalContext *ctx)
+{
+       int    err;
+    SSLBuffer   content;
+
+    if ((ctx->readCipher.symCipher->params->blockSize > 0) &&
+        ((payload->length % ctx->readCipher.symCipher->params->blockSize) != 0)) {
+        return errSSLRecordRecordOverflow;
+    }
+
+    /* Decrypt in place */
+    if ((err = ctx->readCipher.symCipher->c.cipher.decrypt(payload->data,
+               payload->data, payload->length,
+               ctx->readCipher.cipherCtx)) != 0)
+    {
+        return errSSLRecordDecryptionFail;
+    }
+
+    /* Locate content within decrypted payload */
+
+    /* TLS 1.1 and DTLS 1.0 block ciphers */
+    if((ctx->negProtocolVersion>=TLS_Version_1_1) && (ctx->readCipher.symCipher->params->blockSize>0))
+    {
+        content.data = payload->data + ctx->readCipher.symCipher->params->blockSize;
+        content.length = payload->length - (ctx->readCipher.macRef->hash->digestSize + ctx->readCipher.symCipher->params->blockSize);
+    } else {
+        content.data = payload->data;
+        content.length = payload->length - ctx->readCipher.macRef->hash->digestSize;
+    }
+
+    /* Test for underflow - if the record size is smaller than required */
+    if(content.length > payload->length) {
+            return errSSLRecordClosedAbort;
+    }
+
+    err = 0;
+
+    if (ctx->readCipher.symCipher->params->blockSize > 0) {
+               /* for TLSv1, padding can be anywhere from 0 to 255 bytes */
+               uint8_t padSize = payload->data[payload->length - 1];
+
+        /* Padding check sequence:
+            1. Check that the padding size (last byte in padding) is within bound
+            2. Adjust content.length accordingly
+            3. Check every padding byte (except last, already checked)
+           Do not return, just set the error value on failure,
+           to avoid creating a padding oracle with timing.
+        */
+        if(padSize+1<=content.length) {
+            uint8_t *padChars;
+            content.length -= (1 + padSize);
+            padChars = payload->data + payload->length - (padSize+1);
+            while(padChars < (payload->data + payload->length - 1)) {
+                if(*padChars++ != padSize) {
+                    err = errSSLRecordBadRecordMac;
+                }
+            }
+        } else {
+            err = errSSLRecordBadRecordMac;
+        }
+    }
+
+       /* Verify MAC on payload */
+    if (ctx->readCipher.macRef->hash->digestSize > 0)
+    /* Optimize away MAC for null case */
+        if (SSLVerifyMac(type, &content,
+                          content.data + content.length, ctx) != 0)
+        {
+            err = errSSLRecordBadRecordMac;
+        }
+
+    *payload = content;     /* Modify payload buffer to indicate content length */
+
+    return err;
+}
+
+/* initialize a per-CipherContext HashHmacContext for use in MACing each record */
+static int tls1InitMac (
+       CipherContext *cipherCtx)               // macRef, macSecret valid on entry
+                                                                       // macCtx valid on return
+{
+       const HMACReference *hmac;
+       int serr;
+
+    check(cipherCtx);
+       check(cipherCtx->macRef != NULL);
+       hmac = cipherCtx->macRef->hmac;
+       check(hmac != NULL);
+
+       if(cipherCtx->macCtx.hmacCtx != NULL) {
+               hmac->free(cipherCtx->macCtx.hmacCtx);
+               cipherCtx->macCtx.hmacCtx = NULL;
+       }
+       serr = hmac->alloc(hmac, cipherCtx->macSecret,
+               cipherCtx->macRef->hmac->macSize, &cipherCtx->macCtx.hmacCtx);
+
+       /* mac secret now stored in macCtx.hmacCtx, delete it from cipherCtx */
+       memset(cipherCtx->macSecret, 0, sizeof(cipherCtx->macSecret));
+       return serr;
+}
+
+static int tls1FreeMac (
+       CipherContext *cipherCtx)
+{
+       /* this can be called on a completely zeroed out CipherContext... */
+       if(cipherCtx->macRef == NULL) {
+               return 0;
+       }
+       check(cipherCtx->macRef->hmac != NULL);
+
+       if(cipherCtx->macCtx.hmacCtx != NULL) {
+               cipherCtx->macRef->hmac->free(cipherCtx->macCtx.hmacCtx);
+               cipherCtx->macCtx.hmacCtx = NULL;
+       }
+       return 0;
+}
+
+/*
+ * mac = HMAC_hash(MAC_write_secret, seq_num + TLSCompressed.type +
+ *                                     TLSCompressed.version + TLSCompressed.length +
+ *                                     TLSCompressed.fragment));
+ */
+
+/* sequence, type, version, length */
+#define HDR_LENGTH (8 + 1 + 2 + 2)
+static int tls1ComputeMac (
+       uint8_t type,
+       SSLBuffer data,
+       SSLBuffer mac,                                  // caller mallocs data
+       CipherContext *cipherCtx,               // assumes macCtx, macRef
+       sslUint64 seqNo,
+       struct SSLRecordInternalContext *ctx)
+{
+       uint8_t hdr[HDR_LENGTH];
+       uint8_t *p;
+       HMACContextRef hmacCtx;
+       int serr;
+       const HMACReference *hmac;
+       size_t macLength;
+
+       check(cipherCtx != NULL);
+       check(cipherCtx->macRef != NULL);
+       hmac = cipherCtx->macRef->hmac;
+       check(hmac != NULL);
+       hmacCtx = cipherCtx->macCtx.hmacCtx;    // may be NULL, for null cipher
+
+       serr = hmac->init(hmacCtx);
+       if(serr) {
+               goto fail;
+       }
+       p = SSLEncodeUInt64(hdr, seqNo);
+       *p++ = type;
+       *p++ = ctx->negProtocolVersion >> 8;
+       *p++ = ctx->negProtocolVersion & 0xff;
+       *p++ = data.length >> 8;
+       *p   = data.length & 0xff;
+       serr = hmac->update(hmacCtx, hdr, HDR_LENGTH);
+       if(serr) {
+               goto fail;
+       }
+       serr = hmac->update(hmacCtx, data.data, data.length);
+       if(serr) {
+               goto fail;
+       }
+       macLength = mac.length;
+       serr = hmac->final(hmacCtx, mac.data, &macLength);
+       if(serr) {
+               goto fail;
+       }
+       mac.length = macLength;
+fail:
+       return serr;
+}
+
+const SslRecordCallouts Tls1RecordCallouts = {
+       tls1DecryptRecord,
+       ssl3WriteRecord,
+       tls1InitMac,
+       tls1FreeMac,
+       tls1ComputeMac,
+};
+
diff --git a/libsecurity_ssl/lib/tls_digest.c b/libsecurity_ssl/lib/tls_digest.c
new file mode 100644 (file)
index 0000000..5d97542
--- /dev/null
@@ -0,0 +1,545 @@
+/*
+ * Copyright (c) 2000-2001,2005-2007,2010-2011 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * tls_digest.c - Hash implementations
+ */
+
+/* THIS FILE CONTAINS KERNEL CODE */
+
+#include "tls_digest.h"
+#include "sslTypes.h"
+
+#include <string.h>
+
+#define DIGEST_PRINT           0
+#if            DIGEST_PRINT
+#define dgprintf(s)    printf s
+#else
+#define dgprintf(s)
+#endif
+
+const uint8_t SSLMACPad1[MAX_MAC_PADDING] =
+{
+       0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+       0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+       0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+       0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+       0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+       0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36
+};
+
+const uint8_t SSLMACPad2[MAX_MAC_PADDING] =
+{
+       0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,
+       0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,
+       0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,
+       0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,
+       0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,
+       0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C
+};
+
+/*** NULL ***/
+static int HashNullInit(SSLBuffer *digestCtx) {
+       return 0;
+}
+static int HashNullUpdate(SSLBuffer *digestCtx, const SSLBuffer *data) {
+       return 0;
+}
+static int HashNullFinal(SSLBuffer *digestCtx, SSLBuffer *digest) {
+       return 0;
+}
+static int HashNullClose(SSLBuffer *digestCtx) {
+       return 0;
+}
+static int HashNullClone(const SSLBuffer *src, SSLBuffer *dest) {
+       return 0;
+}
+
+#ifdef KERNEL
+
+// Kernel based implementation
+#include <corecrypto/ccdigest.h>
+#include <corecrypto/ccmd5.h>
+#include <corecrypto/ccsha1.h>
+#include <corecrypto/ccsha2.h>
+#include <AssertMacros.h>
+
+static int ccHashInit(const struct ccdigest_info *di, SSLBuffer *digestCtx)
+{
+    ccdigest_ctx_t ctx = (ccdigest_ctx_t)(struct ccdigest_ctx *)digestCtx->data;
+       check(digestCtx->length >= ccdigest_di_size(di));
+    ccdigest_init(di, ctx);
+    return 0;
+}
+
+static int ccHashUpdate(const struct ccdigest_info *di, SSLBuffer *digestCtx, const SSLBuffer *data)
+{
+    /* 64 bits cast: safe, SSL records are always smaller than 2^32 bytes */
+    ccdigest_ctx_t ctx = (ccdigest_ctx_t)(struct ccdigest_ctx *)digestCtx->data;
+       check(digestCtx->length >= ccdigest_di_size(di));
+    ccdigest_update(di, ctx, data->length, data->data);
+    return 0;
+}
+
+static int ccHashFinal(const struct ccdigest_info *di, SSLBuffer *digestCtx, SSLBuffer *digest)
+{
+    ccdigest_ctx_t ctx = (ccdigest_ctx_t)(struct ccdigest_ctx *)digestCtx->data;
+       check(digestCtx->length >= ccdigest_di_size(di));
+    check(digest->length >= di->output_size);
+    ccdigest_final(di, ctx, digest->data);
+    digest->length = di->output_size;
+    return 0;
+}
+
+static int ccHashClose(const struct ccdigest_info *di, SSLBuffer *digestCtx)
+{
+       check(digestCtx->length >= ccdigest_di_size(di));
+    return 0;
+}
+
+static int ccHashClone(const struct ccdigest_info *di, const SSLBuffer *src, SSLBuffer *dst)
+{
+       check(src->length >= ccdigest_di_size(di));
+       check(dst->length >= ccdigest_di_size(di));
+       memcpy(dst->data, src->data, ccdigest_di_size(di));
+       return 0;
+
+}
+
+#define SSL_MD5_DIGEST_LENGTH (CCMD5_OUTPUT_SIZE)
+#define SSL_SHA1_DIGEST_LENGTH (CCSHA1_OUTPUT_SIZE)
+#define SSL_SHA256_DIGEST_LENGTH (CCSHA256_OUTPUT_SIZE)
+#define SSL_SHA384_DIGEST_LENGTH (CCSHA384_OUTPUT_SIZE)
+
+#define SSL_MD5_CONTEXT_SIZE (ccdigest_ctx_size(CCMD5_STATE_SIZE, CCMD5_BLOCK_SIZE))
+#define SSL_SHA1_CONTEXT_SIZE (ccdigest_ctx_size(CCSHA1_STATE_SIZE, CCSHA1_BLOCK_SIZE))
+#define SSL_SHA256_CONTEXT_SIZE (ccdigest_ctx_size(CCSHA256_STATE_SIZE, CCSHA256_BLOCK_SIZE))
+#define SSL_SHA384_CONTEXT_SIZE (ccdigest_ctx_size(CCSHA512_STATE_SIZE, CCSHA512_BLOCK_SIZE))
+
+#define SSL_SHA256_BLOCK_BYTES CCSHA256_BLOCK_SIZE
+#define SSL_SHA384_BLOCK_BYTES CCSHA512_BLOCK_SIZE
+
+/*** MD5 ***/
+static int HashMD5Init(SSLBuffer *digestCtx)
+{
+    return ccHashInit(ccmd5_di(), digestCtx);
+}
+
+static int HashMD5Update(SSLBuffer *digestCtx, const SSLBuffer *data)
+{
+    return ccHashUpdate(ccmd5_di(), digestCtx, data);
+}
+
+static int HashMD5Final(SSLBuffer *digestCtx, SSLBuffer *digest)
+{
+    return ccHashFinal(ccmd5_di(), digestCtx, digest);
+}
+
+static int HashMD5Close(SSLBuffer *digestCtx)
+{
+    return ccHashClose(ccmd5_di(), digestCtx);
+}
+
+static int HashMD5Clone(const SSLBuffer *src, SSLBuffer *dst)
+{
+       return ccHashClone(ccmd5_di(), src, dst);
+}
+
+/*** SHA1 ***/
+static int HashSHA1Init(SSLBuffer *digestCtx)
+{
+    return ccHashInit(ccsha1_di(), digestCtx);
+}
+
+static int HashSHA1Update(SSLBuffer *digestCtx, const SSLBuffer *data)
+{
+    return ccHashUpdate(ccsha1_di(), digestCtx, data);
+}
+
+static int HashSHA1Final(SSLBuffer *digestCtx, SSLBuffer *digest)
+{
+    return ccHashFinal(ccsha1_di(), digestCtx, digest);
+}
+
+static int HashSHA1Close(SSLBuffer *digestCtx)
+{
+    return ccHashClose(ccsha1_di(), digestCtx);}
+
+static int HashSHA1Clone(const SSLBuffer *src, SSLBuffer *dst)
+{
+       return ccHashClone(ccsha1_di(), src, dst);
+}
+
+/*** SHA256 ***/
+static int HashSHA256Init(SSLBuffer *digestCtx)
+{
+    return ccHashInit(ccsha256_di(), digestCtx);
+}
+
+static int HashSHA256Update(SSLBuffer *digestCtx, const SSLBuffer *data)
+{
+    return ccHashUpdate(ccsha256_di(), digestCtx, data);
+}
+
+static int HashSHA256Final(SSLBuffer *digestCtx, SSLBuffer *digest)
+{
+    return ccHashFinal(ccsha256_di(), digestCtx, digest);
+}
+
+static int HashSHA256Close(SSLBuffer *digestCtx)
+{
+       return ccHashClose(ccsha256_di(), digestCtx);
+}
+
+static int HashSHA256Clone(const SSLBuffer *src, SSLBuffer *dst)
+{
+       return ccHashClone(ccsha256_di(), src, dst);
+}
+
+/*** SHA384 ***/
+static int HashSHA384Init(SSLBuffer *digestCtx)
+{
+    return ccHashInit(ccsha384_di(), digestCtx);
+}
+
+static int HashSHA384Update(SSLBuffer *digestCtx, const SSLBuffer *data)
+{
+    return ccHashUpdate(ccsha384_di(), digestCtx, data);
+}
+
+static int HashSHA384Final(SSLBuffer *digestCtx, SSLBuffer *digest)
+{
+    return ccHashFinal(ccsha384_di(), digestCtx, digest);
+}
+
+static int HashSHA384Close(SSLBuffer *digestCtx)
+{
+       return ccHashClose(ccsha384_di(), digestCtx);
+}
+
+static int HashSHA384Clone(const SSLBuffer *src, SSLBuffer *dst)
+{
+       return ccHashClone(ccsha384_di(), src, dst);
+}
+
+#else
+
+// CommonCrypto based implementation
+#include <CommonCrypto/CommonDigest.h>
+#include <assert.h>
+
+#define SSL_MD5_DIGEST_LENGTH    CC_MD5_DIGEST_LENGTH
+#define SSL_SHA1_DIGEST_LENGTH   CC_SHA1_DIGEST_LENGTH
+#define SSL_SHA256_DIGEST_LENGTH CC_SHA256_DIGEST_LENGTH
+#define SSL_SHA384_DIGEST_LENGTH CC_SHA384_DIGEST_LENGTH
+
+#define SSL_MD5_CONTEXT_SIZE    (sizeof(CC_MD5_CTX))
+#define SSL_SHA1_CONTEXT_SIZE   (sizeof(CC_SHA1_CTX))
+#define SSL_SHA256_CONTEXT_SIZE (sizeof(CC_SHA256_CTX))
+#define SSL_SHA384_CONTEXT_SIZE (sizeof(CC_SHA512_CTX))
+
+#define SSL_SHA256_BLOCK_BYTES CC_SHA256_BLOCK_BYTES
+#define SSL_SHA384_BLOCK_BYTES CC_SHA512_BLOCK_BYTES
+
+/*** MD5 ***/
+static int HashMD5Init(SSLBuffer *digestCtx)
+{
+       assert(digestCtx->length >= sizeof(CC_MD5_CTX));
+       CC_MD5_CTX *ctx = (CC_MD5_CTX *)digestCtx->data;
+       CC_MD5_Init(ctx);
+       dgprintf(("###HashMD5Init  ctx %p\n", ctx));
+    return 0;
+}
+
+static int HashMD5Update(SSLBuffer *digestCtx, const SSLBuffer *data)
+{
+    /* 64 bits cast: safe, SSL records are always smaller than 2^32 bytes */
+       assert(digestCtx->length >= sizeof(CC_MD5_CTX));
+       CC_MD5_CTX *ctx = (CC_MD5_CTX *)digestCtx->data;
+       CC_MD5_Update(ctx, data->data, (CC_LONG)data->length);
+    return 0;
+}
+
+static int HashMD5Final(SSLBuffer *digestCtx, SSLBuffer *digest)
+{
+       assert(digestCtx->length >= sizeof(CC_MD5_CTX));
+       CC_MD5_CTX *ctx = (CC_MD5_CTX *)digestCtx->data;
+       dgprintf(("###HashMD5Final  ctx %p\n", ctx));
+       assert(digest->length >= CC_MD5_DIGEST_LENGTH);
+       //if (digest->length < CC_MD5_DIGEST_LENGTH)
+       //      return errSSLCrypto;
+       CC_MD5_Final(digest->data, ctx);
+       digest->length = CC_MD5_DIGEST_LENGTH;
+    return 0;
+}
+
+static int HashMD5Close(SSLBuffer *digestCtx)
+{
+       assert(digestCtx->length >= sizeof(CC_MD5_CTX));
+    return 0;
+}
+
+static int HashMD5Clone(const SSLBuffer *src, SSLBuffer *dst)
+{
+       CC_MD5_CTX *srcCtx;
+       CC_MD5_CTX *dstCtx;
+
+       assert(src->length >= sizeof(CC_MD5_CTX));
+       assert(dst->length >= sizeof(CC_MD5_CTX));
+
+       srcCtx = (CC_MD5_CTX *)src->data;
+       dstCtx = (CC_MD5_CTX *)dst->data;
+       dgprintf(("###HashMD5Clone  srcCtx %p  dstCtx %p\n", srcCtx, dstCtx));
+
+       memcpy(dstCtx, srcCtx, sizeof(CC_MD5_CTX));
+       return 0;
+}
+
+/*** SHA1 ***/
+static int HashSHA1Init(SSLBuffer *digestCtx)
+{
+       assert(digestCtx->length >= sizeof(CC_SHA1_CTX));
+       CC_SHA1_CTX *ctx = (CC_SHA1_CTX *)digestCtx->data;
+       CC_SHA1_Init(ctx);
+       dgprintf(("###HashSHA1Init  ctx %p\n", ctx));
+    return 0;
+}
+
+static int HashSHA1Update(SSLBuffer *digestCtx, const SSLBuffer *data)
+{
+    /* 64 bits cast: safe, SSL records are always smaller than 2^32 bytes */
+       assert(digestCtx->length >= sizeof(CC_SHA1_CTX));
+       CC_SHA1_CTX *ctx = (CC_SHA1_CTX *)digestCtx->data;
+       CC_SHA1_Update(ctx, data->data, (CC_LONG)data->length);
+    return 0;
+}
+
+static int HashSHA1Final(SSLBuffer *digestCtx, SSLBuffer *digest)
+{
+       assert(digestCtx->length >= sizeof(CC_SHA1_CTX));
+       CC_SHA1_CTX *ctx = (CC_SHA1_CTX *)digestCtx->data;
+       dgprintf(("###HashSHA1Final  ctx %p\n", ctx));
+       assert(digest->length >= CC_SHA1_DIGEST_LENGTH);
+       //if (digest->length < CC_SHA1_DIGEST_LENGTH)
+       //      return errSSLCrypto;
+       CC_SHA1_Final(digest->data, ctx);
+       digest->length = CC_SHA1_DIGEST_LENGTH;
+    return 0;
+}
+
+static int HashSHA1Close(SSLBuffer *digestCtx)
+{
+       assert(digestCtx->length >= sizeof(CC_SHA1_CTX));
+    return 0;
+}
+
+static int HashSHA1Clone(const SSLBuffer *src, SSLBuffer *dst)
+{
+       CC_SHA1_CTX *srcCtx;
+       CC_SHA1_CTX *dstCtx;
+
+       assert(src->length >= sizeof(CC_SHA1_CTX));
+       assert(dst->length >= sizeof(CC_SHA1_CTX));
+
+       srcCtx = (CC_SHA1_CTX *)src->data;
+       dstCtx = (CC_SHA1_CTX *)dst->data;
+       dgprintf(("###HashSHA1Clone  srcCtx %p  dstCtx %p\n", srcCtx, dstCtx));
+
+       memcpy(dstCtx, srcCtx, sizeof(CC_SHA1_CTX));
+       return 0;
+}
+
+/*** SHA256 ***/
+static int HashSHA256Init(SSLBuffer *digestCtx)
+{
+       assert(digestCtx->length >= sizeof(CC_SHA256_CTX));
+       CC_SHA256_CTX *ctx = (CC_SHA256_CTX *)digestCtx->data;
+       CC_SHA256_Init(ctx);
+       dgprintf(("###HashSHA256Init  ctx %p\n", ctx));
+    return 0;
+}
+
+static int HashSHA256Update(SSLBuffer *digestCtx, const SSLBuffer *data)
+{
+    /* 64 bits cast: safe, SSL records are always smaller than 2^32 bytes */
+    assert(digestCtx->length >= sizeof(CC_SHA256_CTX));
+       CC_SHA256_CTX *ctx = (CC_SHA256_CTX *)digestCtx->data;
+       CC_SHA256_Update(ctx, data->data, (CC_LONG)data->length);
+    return 0;
+}
+
+static int HashSHA256Final(SSLBuffer *digestCtx, SSLBuffer *digest)
+{
+       assert(digestCtx->length >= sizeof(CC_SHA256_CTX));
+       CC_SHA256_CTX *ctx = (CC_SHA256_CTX *)digestCtx->data;
+       dgprintf(("###HashSHA256Final  ctx %p\n", ctx));
+       assert(digest->length >= CC_SHA256_DIGEST_LENGTH);
+       //if (digest->length < CC_SHA256_DIGEST_LENGTH)
+       //      return errSSLCrypto;
+       CC_SHA256_Final(digest->data, ctx);
+       digest->length = CC_SHA256_DIGEST_LENGTH;
+    return 0;
+}
+
+static int HashSHA256Close(SSLBuffer *digestCtx)
+{
+       assert(digestCtx->length >= sizeof(CC_SHA256_CTX));
+    return 0;
+}
+
+static int HashSHA256Clone(const SSLBuffer *src, SSLBuffer *dst)
+{
+       CC_SHA256_CTX *srcCtx;
+       CC_SHA256_CTX *dstCtx;
+
+       assert(src->length >= sizeof(CC_SHA256_CTX));
+       assert(dst->length >= sizeof(CC_SHA256_CTX));
+
+       srcCtx = (CC_SHA256_CTX *)src->data;
+       dstCtx = (CC_SHA256_CTX *)dst->data;
+       dgprintf(("###HashSHA256Clone  srcCtx %p  dstCtx %p\n", srcCtx, dstCtx));
+
+       memcpy(dstCtx, srcCtx, sizeof(CC_SHA256_CTX));
+       return 0;
+}
+
+/*** SHA384 ***/
+static int HashSHA384Init(SSLBuffer *digestCtx)
+{
+       assert(digestCtx->length >= sizeof(CC_SHA512_CTX));
+       CC_SHA512_CTX *ctx = (CC_SHA512_CTX *)digestCtx->data;
+       CC_SHA384_Init(ctx);
+       dgprintf(("###HashSHA384Init  ctx %p\n", ctx));
+    return 0;
+}
+
+static int HashSHA384Update(SSLBuffer *digestCtx, const SSLBuffer *data)
+{
+    /* 64 bits cast: safe, SSL records are always smaller than 2^32 bytes */
+    assert(digestCtx->length >= sizeof(CC_SHA512_CTX));
+       CC_SHA512_CTX *ctx = (CC_SHA512_CTX *)digestCtx->data;
+       CC_SHA384_Update(ctx, data->data, (CC_LONG)data->length);
+    return 0;
+}
+
+static int HashSHA384Final(SSLBuffer *digestCtx, SSLBuffer *digest)
+{
+       assert(digestCtx->length >= sizeof(CC_SHA512_CTX));
+       CC_SHA512_CTX *ctx = (CC_SHA512_CTX *)digestCtx->data;
+       dgprintf(("###HashSHA384Final  ctx %p\n", ctx));
+       assert(digest->length >= CC_SHA384_DIGEST_LENGTH);
+       //if (digest->length < CC_SHA384_DIGEST_LENGTH)
+       //      return errSSLCrypto;
+       CC_SHA384_Final(digest->data, ctx);
+       digest->length = CC_SHA384_DIGEST_LENGTH;
+    return 0;
+}
+
+static int HashSHA384Close(SSLBuffer *digestCtx)
+{
+       assert(digestCtx->length >= sizeof(CC_SHA512_CTX));
+    return 0;
+}
+
+static int HashSHA384Clone(const SSLBuffer *src, SSLBuffer *dst)
+{
+       CC_SHA512_CTX *srcCtx;
+       CC_SHA512_CTX *dstCtx;
+
+       assert(src->length >= sizeof(CC_SHA512_CTX));
+       assert(dst->length >= sizeof(CC_SHA512_CTX));
+
+       srcCtx = (CC_SHA512_CTX *)src->data;
+       dstCtx = (CC_SHA512_CTX *)dst->data;
+       dgprintf(("###HashSHA384Clone  srcCtx %p  dstCtx %p\n", srcCtx, dstCtx));
+
+       memcpy(dstCtx, srcCtx, sizeof(CC_SHA512_CTX));
+       return 0;
+}
+
+#endif
+
+/*
+ * These are the handles by which the bulk of digesting work
+ * is done.
+ */
+const HashReference SSLHashNull =
+{
+    0,
+    0,
+    0,
+    HashNullInit,
+    HashNullUpdate,
+    HashNullFinal,
+    HashNullClose,
+    HashNullClone
+};
+
+const HashReference SSLHashMD5 =
+{
+    SSL_MD5_DIGEST_LENGTH,
+    48,
+    SSL_MD5_CONTEXT_SIZE,
+    HashMD5Init,
+    HashMD5Update,
+    HashMD5Final,
+    HashMD5Close,
+    HashMD5Clone
+};
+
+const HashReference SSLHashSHA1 =
+{
+    SSL_SHA1_DIGEST_LENGTH,
+    40,
+    SSL_SHA1_CONTEXT_SIZE,
+    HashSHA1Init,
+    HashSHA1Update,
+    HashSHA1Final,
+    HashSHA1Close,
+    HashSHA1Clone
+};
+
+const HashReference SSLHashSHA256 =
+{
+    SSL_SHA256_DIGEST_LENGTH,
+    SSL_SHA256_BLOCK_BYTES,
+    SSL_SHA256_CONTEXT_SIZE,
+    HashSHA256Init,
+    HashSHA256Update,
+    HashSHA256Final,
+    HashSHA256Close,
+    HashSHA256Clone
+};
+
+const HashReference SSLHashSHA384 =
+{
+    SSL_SHA384_DIGEST_LENGTH,
+    SSL_SHA384_BLOCK_BYTES,
+    SSL_SHA384_CONTEXT_SIZE,
+    HashSHA384Init,
+    HashSHA384Update,
+    HashSHA384Final,
+    HashSHA384Close,
+    HashSHA384Clone
+};
diff --git a/libsecurity_ssl/lib/tls_digest.h b/libsecurity_ssl/lib/tls_digest.h
new file mode 100644 (file)
index 0000000..b89e847
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 1999-2001,2005-2007,2010-2011 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * tls_digest.h - HashReference declarations
+ */
+
+#ifndef        _TLS_DIGEST_H_
+#define _TLS_DIGEST_H_ 1
+
+#include "sslTypes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * These numbers show up all over the place...might as well hard code 'em once.
+ */
+#define SSL_MD5_DIGEST_LEN      16
+#define SSL_SHA1_DIGEST_LEN     20
+#define SSL_SHA256_DIGEST_LEN  32
+#define SSL_SHA384_DIGEST_LEN  48
+#define SSL_MAX_DIGEST_LEN      48 /* >= SSL_MD5_DIGEST_LEN + SSL_SHA1_DIGEST_LEN */
+
+#define MAX_MAC_PADDING         48     /* MD5 MAC padding size = 48 bytes */
+
+extern const uint8_t SSLMACPad1[], SSLMACPad2[];
+
+typedef int (*HashInit)(SSLBuffer *digestCtx);
+typedef int (*HashUpdate)(SSLBuffer *digestCtx, const SSLBuffer *data);
+/* HashFinal also does HashClose */
+typedef int (*HashFinal)(SSLBuffer *digestCtx, SSLBuffer *digest);
+typedef int (*HashClose)(SSLBuffer *digestCtx);
+typedef int (*HashClone)(const SSLBuffer *src, SSLBuffer *dest);
+
+typedef struct
+{
+    uint32_t    digestSize;
+    uint32_t    macPadSize;
+    uint32_t    contextSize;
+    HashInit    init;
+    HashUpdate  update;
+    HashFinal   final;
+    HashClose  close;
+    HashClone   clone;
+} HashReference;
+
+extern const HashReference SSLHashNull;
+extern const HashReference SSLHashMD5;
+extern const HashReference SSLHashSHA1;
+extern const HashReference SSLHashSHA256;
+extern const HashReference SSLHashSHA384;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TLS_DIGEST_H_ */
diff --git a/libsecurity_ssl/lib/tls_hashhmac.c b/libsecurity_ssl/lib/tls_hashhmac.c
new file mode 100644 (file)
index 0000000..3706298
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2002,2005-2008,2010-2011 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * tls_hashhmac.c - HMAC routines used by TLS
+ */
+
+/* THIS FILE CONTAINS KERNEL CODE */
+
+#include "tls_digest.h"
+#include "tls_hashhmac.h"
+
+const HashHmacReference HashHmacNull = {
+       &SSLHashNull,
+       &TlsHmacNull
+};
+
+const HashHmacReference HashHmacMD5 = {
+       &SSLHashMD5,
+       &TlsHmacMD5
+};
+
+const HashHmacReference HashHmacSHA1 = {
+       &SSLHashSHA1,
+       &TlsHmacSHA1
+};
+
+const HashHmacReference HashHmacSHA256 = {
+       &SSLHashSHA256,
+       &TlsHmacSHA256
+};
+
+const HashHmacReference HashHmacSHA384 = {
+       &SSLHashSHA384,
+       &TlsHmacSHA384
+};
diff --git a/libsecurity_ssl/lib/tls_hashhmac.h b/libsecurity_ssl/lib/tls_hashhmac.h
new file mode 100644 (file)
index 0000000..18ea9cc
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2002,2005-2007,2010-2011 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef        _TLS_HASHHMAC_H_
+#define _TLS_HASHHMAC_H_
+
+#include "tls_digest.h"
+#include "tls_hmac.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * TLS addenda:
+ *     -- new struct HashHmacReference
+ *     -- structs which used to use HashReference now use HashHmacReference
+ *     -- new union HashHmacContext, used in CipherContext.
+ */
+
+typedef struct {
+    const HashReference        *hash;
+    const HMACReference        *hmac;
+} HashHmacReference;
+
+typedef union {
+    SSLBuffer                  hashCtx;
+    HMACContextRef             hmacCtx;
+} HashHmacContext;
+
+/* these are declared in tls_hmac.c */
+extern const HashHmacReference HashHmacNull;
+extern const HashHmacReference HashHmacMD5;
+extern const HashHmacReference HashHmacSHA1;
+extern const HashHmacReference HashHmacSHA256;
+extern const HashHmacReference HashHmacSHA384;
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _TLS_HMAC_H_ */
index abb7af619ae21bbb2eb9f20248644d1875c2f8c7..cb20a9e5404d69fc56b53fbab2fc3efa865cff4b 100644 (file)
  * tls_hmac.c - HMAC routines used by TLS
  */
 
  * tls_hmac.c - HMAC routines used by TLS
  */
 
-#include "tls_hmac.h"
-
+/* THIS FILE CONTAINS KERNEL CODE */
 
 
+#include "tls_hmac.h"
+#include "tls_digest.h"
 #include "sslMemory.h"
 #include "sslMemory.h"
-#include "cryptType.h"
-#include "sslDigests.h"
 #include "sslDebug.h"
 #include "sslDebug.h"
-#include <strings.h>
-#include <assert.h>
+#include <string.h>
+#include <AssertMacros.h>
 
 
-#ifdef USE_CDSA_CRYPTO
-#include "sslCrypto.h"
-#include <CommonCrypto/CommonHMAC.h>
 
 /* Per-session state, opaque to callers; all fields set at alloc time */
 struct HMACContext {
 
 /* Per-session state, opaque to callers; all fields set at alloc time */
 struct HMACContext {
-       SSLContext                                      *ctx;
-
-       /* this one is set once with the key, and it then cloned
-        * for each init() */
-       CCHmacContext                           ccHmacTemplate;
-
-       /* the one we actually feed data to */
-       CCHmacContext                           ccHmac;
-       size_t                                          macSize;
-
-       /* FIXME not sure if we need this */
-       const struct HMACReference      *hmac;
-};
-
-#pragma mark -
-#pragma mark CommonCryptor HMAC routines
-
-/* Create an HMAC session */
-static OSStatus HMAC_Alloc(
-       const struct HMACReference      *hmac,
-       SSLContext                                      *ctx,
-       const void                                      *keyPtr,
-       unsigned                                        keyLen,
-       HMACContextRef                          *hmacCtxOut)            // RETURNED
-{
-       CCHmacAlgorithm ccAlg;
-
-       HMACContextRef hmacCtx = (HMACContextRef)sslMalloc(sizeof(struct HMACContext));
-
-       if(hmacCtx == NULL) {
-               return memFullErr;
-       }
-       hmacCtx->ctx = ctx;
-       hmacCtx->hmac = hmac;
-
-       switch(hmac->alg) {
-               case HA_SHA384:
-                       ccAlg = kCCHmacAlgSHA384;
-                       hmacCtx->macSize = CC_SHA384_DIGEST_LENGTH;
-                       break;
-               case HA_SHA256:
-                       ccAlg = kCCHmacAlgSHA256;
-                       hmacCtx->macSize = CC_SHA256_DIGEST_LENGTH;
-                       break;
-               case HA_SHA1:
-                       ccAlg = kCCHmacAlgSHA1;
-                       hmacCtx->macSize = CC_SHA1_DIGEST_LENGTH;
-                       break;
-               case HA_MD5:
-                       ccAlg = kCCHmacAlgMD5;
-                       hmacCtx->macSize = CC_MD5_DIGEST_LENGTH;
-                       break;
-               default:
-                       ASSERT(0);
-                       return errSSLInternal;
-       }
-
-       /* create the template from which individual record MAC-ers are cloned */
-       CCHmacInit(&hmacCtx->ccHmacTemplate, ccAlg, keyPtr, keyLen);
-       *hmacCtxOut = hmacCtx;
-       return noErr;
-}
-
-/* free a session */
-static OSStatus HMAC_Free(
-       HMACContextRef  hmacCtx)
-{
-       if(hmacCtx != NULL) {
-               memset(hmacCtx, 0, sizeof(*hmacCtx));
-               sslFree(hmacCtx);
-       }
-       return noErr;
-}
-
-/* Reusable init - clone from template */
-static OSStatus HMAC_Init(
-       HMACContextRef  hmacCtx)
-{
-       if(hmacCtx == NULL) {
-               return errSSLInternal;
-       }
-       hmacCtx->ccHmac = hmacCtx->ccHmacTemplate;
-       return noErr;
-}
-
-/* normal crypt ops */
-static OSStatus HMAC_Update(
-       HMACContextRef  hmacCtx,
-       const void              *data,
-       unsigned                dataLen)
-{
-       CCHmacUpdate(&hmacCtx->ccHmac, data, dataLen);
-       return noErr;
-}
-
-static OSStatus HMAC_Final(
-       HMACContextRef  hmacCtx,
-       void                    *hmac,                  // mallocd by caller
-       unsigned                *hmacLen)               // IN/OUT
-{
-       if(*hmacLen < hmacCtx->macSize) {
-               return errSSLInternal;
-       }
-       CCHmacFinal(&hmacCtx->ccHmac, hmac);
-       *hmacLen = hmacCtx->macSize;
-       return noErr;
-}
-
-/* one-shot */
-static OSStatus HMAC_Hmac (
-       HMACContextRef  hmacCtx,
-       const void              *data,
-       unsigned                dataLen,
-       void                    *hmac,                  // mallocd by caller
-       unsigned                *hmacLen)               // IN/OUT
-{
-       OSStatus serr;
-       const HMACReference     *hmacRef;
-
-       if(hmacCtx == NULL) {
-               return errSSLInternal;
-       }
-       hmacRef = hmacCtx->hmac;
-       assert(hmacRef != NULL);
-       serr = hmacRef->init(hmacCtx);
-       if(serr) {
-               return serr;
-       }
-       serr = hmacRef->update(hmacCtx, data, dataLen);
-       if(serr) {
-               return serr;
-       }
-       return hmacRef->final(hmacCtx, hmac, hmacLen);
-}
-
-#else
-
-/* Per-session state, opaque to callers; all fields set at alloc time */
-struct HMACContext {
-       SSLContext                  *ctx;
        const HashReference         *digest;
        SSLBuffer                                   outerHashCtx;
        SSLBuffer                                   innerHashCtx;
        SSLBuffer                                   currentHashCtx;
 };
 
        const HashReference         *digest;
        SSLBuffer                                   outerHashCtx;
        SSLBuffer                                   innerHashCtx;
        SSLBuffer                                   currentHashCtx;
 };
 
-#pragma mark -
-#pragma mark Common HMAC routines
+// MARK: -
+// MARK: Common HMAC routines
 
 /* Create an HMAC session */
 
 /* Create an HMAC session */
-static OSStatus HMAC_Alloc(
+static int HMAC_Alloc(
        const struct HMACReference      *hmac,
        const struct HMACReference      *hmac,
-       SSLContext                                      *ctx,
        const void                                      *keyPtr,
        size_t                      keyLen,
        HMACContextRef                          *hmacCtx)                       // RETURNED
        const void                                      *keyPtr,
        size_t                      keyLen,
        HMACContextRef                          *hmacCtx)                       // RETURNED
@@ -223,16 +78,17 @@ static OSStatus HMAC_Alloc(
             digest_block_size = 64;
                        break;
                default:
             digest_block_size = 64;
                        break;
                default:
-                       assert(0);
-                       return errSSLInternal;
+                       check(0);
+                       return -1;
        }
 
        context = (uint8_t *)sslMalloc(sizeof(struct HMACContext) +
                                    3 * digest->contextSize);
        }
 
        context = (uint8_t *)sslMalloc(sizeof(struct HMACContext) +
                                    3 * digest->contextSize);
-       if(context == NULL)
-               return memFullErr;
+       if(context == NULL) {
+        check(0);
+               return -1;
+    }
        href = (HMACContextRef)context;
        href = (HMACContextRef)context;
-       href->ctx = ctx;
     href->digest = digest;
        href->outerHashCtx.data = context + sizeof(*href);
        href->outerHashCtx.length = digest->contextSize;
     href->digest = digest;
        href->outerHashCtx.data = context + sizeof(*href);
        href->outerHashCtx.length = digest->contextSize;
@@ -241,8 +97,8 @@ static OSStatus HMAC_Alloc(
        href->currentHashCtx.data = href->innerHashCtx.data + digest->contextSize;
        href->currentHashCtx.length = digest->contextSize;
 
        href->currentHashCtx.data = href->innerHashCtx.data + digest->contextSize;
        href->currentHashCtx.length = digest->contextSize;
 
-       digest->init(&href->outerHashCtx, ctx);
-       digest->init(&href->innerHashCtx, ctx);
+       digest->init(&href->outerHashCtx);
+       digest->init(&href->innerHashCtx);
 
     uint8_t tmpkey[digest->digestSize];
        uint8_t pad[digest_block_size];
 
     uint8_t tmpkey[digest->digestSize];
        uint8_t pad[digest_block_size];
@@ -259,7 +115,7 @@ static OSStatus HMAC_Alloc(
         key = outBuffer.data;
         keyLen = outBuffer.length;
         /* Re-initialize the inner context. */
         key = outBuffer.data;
         keyLen = outBuffer.length;
         /* Re-initialize the inner context. */
-        digest->init(&href->innerHashCtx, ctx);
+        digest->init(&href->innerHashCtx);
        }
 
        /* Copy the key into k_opad while doing the XOR. */
        }
 
        /* Copy the key into k_opad while doing the XOR. */
@@ -283,17 +139,17 @@ static OSStatus HMAC_Alloc(
 
        /* success */
        *hmacCtx = href;
 
        /* success */
        *hmacCtx = href;
-       return noErr;
+       return 0;
 }
 
 /* free a session */
 }
 
 /* free a session */
-static OSStatus HMAC_Free(
+static int HMAC_Free(
        HMACContextRef  hmacCtx)
 {
        if(hmacCtx != NULL) {
        HMACContextRef  hmacCtx)
 {
        if(hmacCtx != NULL) {
-               hmacCtx->digest->close(&hmacCtx->outerHashCtx, hmacCtx->ctx);
-               hmacCtx->digest->close(&hmacCtx->innerHashCtx, hmacCtx->ctx);
-               hmacCtx->digest->close(&hmacCtx->currentHashCtx, hmacCtx->ctx);
+               hmacCtx->digest->close(&hmacCtx->outerHashCtx);
+               hmacCtx->digest->close(&hmacCtx->innerHashCtx);
+               hmacCtx->digest->close(&hmacCtx->currentHashCtx);
 
                /* Clear out any key material left in the digest contexts. */
                bzero(hmacCtx->outerHashCtx.data, hmacCtx->outerHashCtx.length);
 
                /* Clear out any key material left in the digest contexts. */
                bzero(hmacCtx->outerHashCtx.data, hmacCtx->outerHashCtx.length);
@@ -302,42 +158,46 @@ static OSStatus HMAC_Free(
 
                sslFree(hmacCtx);
        }
 
                sslFree(hmacCtx);
        }
-       return noErr;
+       return 0;
 }
 
 /* Reusable init */
 }
 
 /* Reusable init */
-static OSStatus HMAC_Init(
+static int HMAC_Init(
        HMACContextRef  hmacCtx)
 {
        HMACContextRef  hmacCtx)
 {
-       if(hmacCtx == NULL)
-               return errSSLInternal;
+       if(hmacCtx == NULL) {
+        check(0);
+               return -1;
+    }
 
 
-       assert(hmacCtx->digest != NULL);
+       check(hmacCtx->digest != NULL);
 
 
-       hmacCtx->digest->close(&hmacCtx->currentHashCtx, hmacCtx->ctx);
+       hmacCtx->digest->close(&hmacCtx->currentHashCtx);
        hmacCtx->digest->clone(&hmacCtx->innerHashCtx, &hmacCtx->currentHashCtx);
 
        hmacCtx->digest->clone(&hmacCtx->innerHashCtx, &hmacCtx->currentHashCtx);
 
-       return noErr;
+       return 0;
 }
 
 /* normal crypt ops */
 }
 
 /* normal crypt ops */
-static OSStatus HMAC_Update(
+static int HMAC_Update(
        HMACContextRef  hmacCtx,
        const void              *data,
        size_t          dataLen)
 {
        SSLBuffer       cdata = { dataLen, (uint8_t *)data };
        HMACContextRef  hmacCtx,
        const void              *data,
        size_t          dataLen)
 {
        SSLBuffer       cdata = { dataLen, (uint8_t *)data };
-       if(hmacCtx == NULL)
-               return errSSLInternal;
+       if(hmacCtx == NULL) {
+        check(0);
+               return -1;
+    }
 
 
-       assert(hmacCtx->digest != NULL);
+       check(hmacCtx->digest != NULL);
 
        hmacCtx->digest->update(&hmacCtx->currentHashCtx, &cdata);
 
 
        hmacCtx->digest->update(&hmacCtx->currentHashCtx, &cdata);
 
-       return noErr;
+       return 0;
 }
 }
-
-static OSStatus HMAC_Final(
+       
+static int HMAC_Final(
        HMACContextRef  hmacCtx,
        void                    *hmac,                  // mallocd by caller
        size_t          *hmacLen)               // IN/OUT
        HMACContextRef  hmacCtx,
        void                    *hmac,                  // mallocd by caller
        size_t          *hmacLen)               // IN/OUT
@@ -347,13 +207,15 @@ static OSStatus HMAC_Final(
        SSLBuffer       cdata;
 
        if(hmacCtx == NULL) {
        SSLBuffer       cdata;
 
        if(hmacCtx == NULL) {
-               return errSSLInternal;
+        check(0);
+               return -1;
        }
        if((hmac == NULL) || (hmacLen == NULL)) {
        }
        if((hmac == NULL) || (hmacLen == NULL)) {
-               return errSSLInternal;
+        check(0);
+               return -1;
        }
        }
-       assert(hmacCtx->digest != NULL);
-       assert(*hmacLen >= hmacCtx->digest->digestSize);
+       check(hmacCtx->digest != NULL);
+       check(*hmacLen >= hmacCtx->digest->digestSize);
 
        cdata.length = *hmacLen;
        cdata.data = (uint8_t *)hmac;
 
        cdata.length = *hmacLen;
        cdata.data = (uint8_t *)hmac;
@@ -365,21 +227,22 @@ static OSStatus HMAC_Final(
        hmacCtx->digest->final(&hmacCtx->currentHashCtx, &cdata);
        *hmacLen = hmacCtx->digest->digestSize;
 
        hmacCtx->digest->final(&hmacCtx->currentHashCtx, &cdata);
        *hmacLen = hmacCtx->digest->digestSize;
 
-       return noErr;
+       return 0;
 }
 
 /* one-shot */
 }
 
 /* one-shot */
-static OSStatus HMAC_Hmac (
+static int HMAC_Hmac (
        HMACContextRef  hmacCtx,
        const void              *data,
        size_t          dataLen,
        void                    *hmac,                  // mallocd by caller
        size_t          *hmacLen)               // IN/OUT
 {
        HMACContextRef  hmacCtx,
        const void              *data,
        size_t          dataLen,
        void                    *hmac,                  // mallocd by caller
        size_t          *hmacLen)               // IN/OUT
 {
-       OSStatus serr;
-
+       int serr;
+       
        if(hmacCtx == NULL) {
        if(hmacCtx == NULL) {
-               return errSSLInternal;
+        check(0);
+               return -1;
        }
        serr = HMAC_Init(hmacCtx);
        if(serr) {
        }
        serr = HMAC_Init(hmacCtx);
        if(serr) {
@@ -392,63 +255,61 @@ static OSStatus HMAC_Hmac (
        return HMAC_Final(hmacCtx, hmac, hmacLen);
 }
 
        return HMAC_Final(hmacCtx, hmac, hmacLen);
 }
 
-#endif /* !USE_CDSA_CRYPTO */
 
 
-#pragma mark -
-#pragma mark Null HMAC
+// MARK: -
+// MARK: Null HMAC
 
 
-static OSStatus HMAC_AllocNull(
+static int HMAC_AllocNull(
        const struct HMACReference      *hmac,
        const struct HMACReference      *hmac,
-       SSLContext                                      *ctx,
        const void                                      *keyPtr,
        size_t                      keyLen,
        HMACContextRef                          *hmacCtx)                       // RETURNED
 {
        *hmacCtx = NULL;
        const void                                      *keyPtr,
        size_t                      keyLen,
        HMACContextRef                          *hmacCtx)                       // RETURNED
 {
        *hmacCtx = NULL;
-       return noErr;
+       return 0;
 }
 
 }
 
-static OSStatus HMAC_FreeNull(
+static int HMAC_FreeNull(
        HMACContextRef  hmacCtx)
 {
        HMACContextRef  hmacCtx)
 {
-       return noErr;
+       return 0;
 }
 
 }
 
-static OSStatus HMAC_InitNull(
+static int HMAC_InitNull(
        HMACContextRef  hmacCtx)
        {
        HMACContextRef  hmacCtx)
        {
-       return noErr;
+       return 0;
 }
 
 }
 
-static OSStatus HMAC_UpdateNull(
+static int HMAC_UpdateNull(
        HMACContextRef  hmacCtx,
        const void              *data,
        size_t          dataLen)
 {
        HMACContextRef  hmacCtx,
        const void              *data,
        size_t          dataLen)
 {
-       return noErr;
+       return 0;
 }
 
 }
 
-static OSStatus HMAC_FinalNull(
+static int HMAC_FinalNull(
        HMACContextRef  hmacCtx,
        void                    *hmac,                  // mallocd by caller
        size_t          *hmacLen)               // IN/OUT
 {
        HMACContextRef  hmacCtx,
        void                    *hmac,                  // mallocd by caller
        size_t          *hmacLen)               // IN/OUT
 {
-       return noErr;
+       return 0;
 }
 
 }
 
-static OSStatus HMAC_HmacNull (
+static int HMAC_HmacNull (
        HMACContextRef  hmacCtx,
        const void              *data,
        size_t          dataLen,
        void                    *hmac,                  // mallocd by caller
        size_t          *hmacLen)
 {
        HMACContextRef  hmacCtx,
        const void              *data,
        size_t          dataLen,
        void                    *hmac,                  // mallocd by caller
        size_t          *hmacLen)
 {
-       return noErr;
+       return 0;
 }
 
 const HMACReference TlsHmacNull = {
 }
 
 const HMACReference TlsHmacNull = {
-       0,
-       HA_Null,
+    0,
+    HA_Null,
        HMAC_AllocNull,
        HMAC_FreeNull,
        HMAC_InitNull,
        HMAC_AllocNull,
        HMAC_FreeNull,
        HMAC_InitNull,
@@ -458,8 +319,8 @@ const HMACReference TlsHmacNull = {
 };
 
 const HMACReference TlsHmacMD5 = {
 };
 
 const HMACReference TlsHmacMD5 = {
-       16,
-       HA_MD5,
+    16,
+    HA_MD5,
        HMAC_Alloc,
        HMAC_Free,
        HMAC_Init,
        HMAC_Alloc,
        HMAC_Free,
        HMAC_Init,
@@ -469,8 +330,8 @@ const HMACReference TlsHmacMD5 = {
 };
 
 const HMACReference TlsHmacSHA1 = {
 };
 
 const HMACReference TlsHmacSHA1 = {
-       20,
-       HA_SHA1,
+    20,
+    HA_SHA1,
        HMAC_Alloc,
        HMAC_Free,
        HMAC_Init,
        HMAC_Alloc,
        HMAC_Free,
        HMAC_Init,
@@ -480,8 +341,8 @@ const HMACReference TlsHmacSHA1 = {
 };
 
 const HMACReference TlsHmacSHA256 = {
 };
 
 const HMACReference TlsHmacSHA256 = {
-       32,
-       HA_SHA256,
+    32,
+    HA_SHA256,
        HMAC_Alloc,
        HMAC_Free,
        HMAC_Init,
        HMAC_Alloc,
        HMAC_Free,
        HMAC_Init,
@@ -491,8 +352,8 @@ const HMACReference TlsHmacSHA256 = {
 };
 
 const HMACReference TlsHmacSHA384 = {
 };
 
 const HMACReference TlsHmacSHA384 = {
-       48,
-       HA_SHA384,
+    48,
+    HA_SHA384,
        HMAC_Alloc,
        HMAC_Free,
        HMAC_Init,
        HMAC_Alloc,
        HMAC_Free,
        HMAC_Init,
@@ -500,28 +361,3 @@ const HMACReference TlsHmacSHA384 = {
        HMAC_Final,
        HMAC_Hmac
 };
        HMAC_Final,
        HMAC_Hmac
 };
-
-const HashHmacReference HashHmacNull = {
-       &SSLHashNull,
-       &TlsHmacNull
-};
-
-const HashHmacReference HashHmacMD5 = {
-       &SSLHashMD5,
-       &TlsHmacMD5
-};
-
-const HashHmacReference HashHmacSHA1 = {
-       &SSLHashSHA1,
-       &TlsHmacSHA1
-};
-
-const HashHmacReference HashHmacSHA256 = {
-       &SSLHashSHA256,
-       &TlsHmacSHA256
-};
-
-const HashHmacReference HashHmacSHA384 = {
-       &SSLHashSHA384,
-       &TlsHmacSHA384
-};
index 0cc6aa4199f8c55e7209edfa1d9766fda48d03c5..c581b9139401b33bd986695272050b2c571e67d2 100644 (file)
@@ -32,8 +32,8 @@
 extern "C" {
 #endif
 
 extern "C" {
 #endif
 
-#include "ssl.h"
-#include "sslPriv.h"
+#include <sys/types.h>
+#include "cipherSpecs.h"
 
 /* forward declaration of HMAC object */
 struct                                                 HMACReference;
 
 /* forward declaration of HMAC object */
 struct                                                 HMACReference;
@@ -42,56 +42,51 @@ struct                                              HMACReference;
 struct                      HMACContext;
 typedef struct HMACContext  *HMACContextRef;
 
 struct                      HMACContext;
 typedef struct HMACContext  *HMACContextRef;
 
-/* The HMAC algorithms we support */
-typedef enum {
-       HA_Null = 0,            // i.e., uninitialized
-       HA_SHA1,
-       HA_MD5,
-    HA_SHA256,
-    HA_SHA384
-} HMAC_Algs;
 
 /* For convenience..the max size of HMAC, in bytes, this module will ever return */
 #define TLS_HMAC_MAX_SIZE              48
 
 /* Create an HMAC session */
 
 /* For convenience..the max size of HMAC, in bytes, this module will ever return */
 #define TLS_HMAC_MAX_SIZE              48
 
 /* Create an HMAC session */
-typedef OSStatus (*HMAC_AllocFcn) (
+typedef int (*HMAC_AllocFcn) (
        const struct HMACReference      *hmac,
        const struct HMACReference      *hmac,
-       SSLContext                                      *ctx,
        const void                                      *keyPtr,
        size_t                      keyLen,
        HMACContextRef                          *hmacCtx);                      // RETURNED
 
 /* Free a session */
        const void                                      *keyPtr,
        size_t                      keyLen,
        HMACContextRef                          *hmacCtx);                      // RETURNED
 
 /* Free a session */
-typedef OSStatus (*HMAC_FreeFcn) (
-       HMACContextRef  hmacCtx);
-
+typedef int (*HMAC_FreeFcn) (
+       HMACContextRef  hmacCtx);       
+       
 /* Reusable init, using same key */
 /* Reusable init, using same key */
-typedef OSStatus (*HMAC_InitFcn) (
+typedef int (*HMAC_InitFcn) (
        HMACContextRef  hmacCtx);
 
 /* normal crypt ops */
        HMACContextRef  hmacCtx);
 
 /* normal crypt ops */
-typedef OSStatus (*HMAC_UpdateFcn) (
+typedef int (*HMAC_UpdateFcn) (
        HMACContextRef  hmacCtx,
        const void              *data,
        size_t          dataLen);
        HMACContextRef  hmacCtx,
        const void              *data,
        size_t          dataLen);
-
-typedef OSStatus (*HMAC_FinalFcn) (
+       
+typedef int (*HMAC_FinalFcn) (
        HMACContextRef  hmacCtx,
        void                    *hmac,                  // mallocd by caller
        size_t          *hmacLen);              // IN/OUT
 
 /* one-shot */
        HMACContextRef  hmacCtx,
        void                    *hmac,                  // mallocd by caller
        size_t          *hmacLen);              // IN/OUT
 
 /* one-shot */
-typedef OSStatus (*HMAC_HmacFcn) (
+typedef int (*HMAC_HmacFcn) (
        HMACContextRef  hmacCtx,
        const void              *data,
        size_t          dataLen,
        void                    *hmac,                  // mallocd by caller
        size_t          *hmacLen);              // IN/OUT
        HMACContextRef  hmacCtx,
        const void              *data,
        size_t          dataLen,
        void                    *hmac,                  // mallocd by caller
        size_t          *hmacLen);              // IN/OUT
+       
+
+typedef struct HMACParams {
+} HMACParams;
 
 typedef struct HMACReference {
 
 typedef struct HMACReference {
-       size_t          macSize;
-       HMAC_Algs               alg;
+    size_t          macSize;
+    HMAC_Algs          alg;
        HMAC_AllocFcn   alloc;
        HMAC_FreeFcn    free;
        HMAC_InitFcn    init;
        HMAC_AllocFcn   alloc;
        HMAC_FreeFcn    free;
        HMAC_InitFcn    init;
@@ -106,6 +101,7 @@ extern const HMACReference TlsHmacMD5;
 extern const HMACReference TlsHmacSHA256;
 extern const HMACReference TlsHmacSHA384;
 
 extern const HMACReference TlsHmacSHA256;
 extern const HMACReference TlsHmacSHA384;
 
+
 #ifdef __cplusplus
 }
 #endif
 #ifdef __cplusplus
 }
 #endif
diff --git a/libsecurity_ssl/lib/tls_record.h b/libsecurity_ssl/lib/tls_record.h
new file mode 100644 (file)
index 0000000..eacd845
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2002,2005-2007,2010-2011 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * tls_record.h - Declarations of record layer callout struct to provide indirect calls to
+ *     SSLv3 and TLS routines.
+ */
+
+#ifndef        _TLS_RECORD_H_
+#define _TLS_RECORD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// #include "sslRecord.h"
+
+#include "sslTypes.h"
+#include "cryptType.h"
+#include "sslMemory.h"
+#include "SSLRecordInternal.h"
+
+struct SSLRecordInternalContext;
+
+/***
+ *** Each of {TLS, SSLv3} implements each of these functions.
+ ***/
+
+/* unpack, decrypt, validate one record */
+typedef int (*decryptRecordFcn) (
+       uint8_t type,
+       SSLBuffer *payload,
+       struct SSLRecordInternalContext *ctx);
+
+/* pack, encrypt, mac, queue one outgoing record */
+typedef int (*writeRecordFcn) (
+       SSLRecord rec,
+       struct SSLRecordInternalContext *ctx);
+
+/* initialize a per-CipherContext HashHmacContext for use in MACing each record */
+typedef int (*initMacFcn) (
+    CipherContext *cipherCtx           // macRef, macSecret valid on entry
+                                                                       // macCtx valid on return
+);
+
+/* free per-CipherContext HashHmacContext */
+typedef int (*freeMacFcn) (
+       CipherContext *cipherCtx);
+
+/* compute MAC on one record */
+typedef int (*computeMacFcn) (
+       uint8_t type,
+       SSLBuffer data,
+       SSLBuffer mac,                                  // caller mallocs data
+       CipherContext *cipherCtx,               // assumes macCtx, macRef
+       sslUint64 seqNo,
+       struct SSLRecordInternalContext *ctx);
+
+
+typedef struct _SslRecordCallouts {
+       decryptRecordFcn                        decryptRecord;
+       writeRecordFcn                          writeRecord;
+       initMacFcn                                      initMac;
+       freeMacFcn                                      freeMac;
+       computeMacFcn                           computeMac;
+} SslRecordCallouts;
+
+
+/* From ssl3RecordCallouts.c and tls1RecordCallouts.c */
+extern const SslRecordCallouts  Ssl3RecordCallouts;
+extern const SslRecordCallouts Tls1RecordCallouts;
+
+/* one callout routine used in common (for now) */
+int ssl3WriteRecord(
+       SSLRecord rec,
+       struct SSLRecordInternalContext *ctx);
+
+
+typedef struct WaitingRecord
+{   struct WaitingRecord    *next;
+    size_t                  sent;
+    /*
+     * These two fields replace a dynamically allocated SSLBuffer;
+     * the payload to write is contained in the variable-length
+     * array data[].
+     */
+    size_t                                     length;
+    uint8_t                                    data[1];
+} WaitingRecord;
+
+typedef struct {
+    const HashHmacReference     *macAlgorithm;
+    const SSLSymmetricCipher          *cipher;
+} SSLRecordCipherSpec;
+
+
+
+struct SSLRecordInternalContext
+{
+    /* I/O */
+    SSLIOReadFunc       read;
+    SSLIOWriteFunc      write;
+    SSLIOConnectionRef  ioRef;
+    
+    /* buffering */
+    SSLBuffer                  partialReadBuffer;
+    size_t              amountRead;
+    WaitingRecord       *recordWriteQueue;
+    
+    /* ciphers */
+    uint16_t            selectedCipher;                        /* currently selected */
+    SSLRecordCipherSpec selectedCipherSpec;     /* ditto */
+    CipherContext       readCipher;
+    CipherContext       writeCipher;
+    CipherContext       readPending;
+    CipherContext       writePending;
+    CipherContext       prevCipher;             /* previous write cipher context, used for retransmit */
+    
+    /* protocol */
+    bool                isDTLS;
+    SSLProtocolVersion  negProtocolVersion;    /* negotiated */
+    const SslRecordCallouts   *sslTslCalls;
+    
+};
+
+/* Function called from the ssl3/tls1 callouts */
+
+int SSLVerifyMac(
+                 uint8_t type,
+                 SSLBuffer *data,
+                 uint8_t *compareMAC,
+                 struct SSLRecordInternalContext *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif         /* _TLS_SSL_H_ */
index 5a682d523abb0c3c72035396976fc572fe222f33..aa6f8aaea26ab1c965bbd5ece74abb2eeab41830 100644 (file)
@@ -22,8 +22,8 @@
  */
 
 /*
  */
 
 /*
- * tls_ssl.h - Declarations of callout struct to provide indirect calls to
- *     SSLv3 and TLS routines.
+ * tls_ssl.h - Declarations of handshake layer callout struct to provide indirect calls to
+ *     SSLv3 and TLS routines. 
  */
 
 #ifndef        _TLS_SSL_H_
  */
 
 #ifndef        _TLS_SSL_H_
@@ -37,42 +37,11 @@ extern "C" {
 #include "sslPriv.h"
 #include "sslContext.h"
 #include "sslRecord.h"
 #include "sslPriv.h"
 #include "sslContext.h"
 #include "sslRecord.h"
-#include "cryptType.h"
 
 /***
  *** Each of {TLS, SSLv3} implements each of these functions.
  ***/
 
 
 /***
  *** Each of {TLS, SSLv3} implements each of these functions.
  ***/
 
-/* unpack, decrypt, validate one record */
-typedef OSStatus (*decryptRecordFcn) (
-       UInt8 type,
-       SSLBuffer *payload,
-       SSLContext *ctx);
-
-/* pack, encrypt, mac, queue one outgoing record */
-typedef OSStatus (*writeRecordFcn) (
-       SSLRecord rec,
-       SSLContext *ctx);
-
-/* initialize a per-CipherContext HashHmacContext for use in MACing each record */
-typedef OSStatus (*initMacFcn) (
-       CipherContext *cipherCtx,               // macRef, macSecret valid on entry
-                                                                       // macCtx valid on return
-       SSLContext *ctx);
-
-/* free per-CipherContext HashHmacContext */
-typedef OSStatus (*freeMacFcn) (
-       CipherContext *cipherCtx);
-
-/* compute MAC on one record */
-typedef OSStatus (*computeMacFcn) (
-       UInt8 type,
-       SSLBuffer data,
-       SSLBuffer mac,                                  // caller mallocs data
-       CipherContext *cipherCtx,               // assumes macCtx, macRef
-       sslUint64 seqNo,
-       SSLContext *ctx);
-
 typedef OSStatus (*generateKeyMaterialFcn) (
        SSLBuffer key,                                  // caller mallocs and specifies length of
                                                                        //   required key material here
 typedef OSStatus (*generateKeyMaterialFcn) (
        SSLBuffer key,                                  // caller mallocs and specifies length of
                                                                        //   required key material here
@@ -104,29 +73,20 @@ typedef OSStatus (*computeCertVfyMacFcn) (
     SSLBuffer *finished,               // output - mallocd by caller
     SSL_HashAlgorithm hash);    //only used in TLS 1.2
 
     SSLBuffer *finished,               // output - mallocd by caller
     SSL_HashAlgorithm hash);    //only used in TLS 1.2
 
+
 typedef struct _SslTlsCallouts {
 typedef struct _SslTlsCallouts {
-       decryptRecordFcn                        decryptRecord;
-       writeRecordFcn                          writeRecord;
-       initMacFcn                                      initMac;
-       freeMacFcn                                      freeMac;
-       computeMacFcn                           computeMac;
        generateKeyMaterialFcn          generateKeyMaterial;
        generateKeyMaterialFcn          generateKeyMaterial;
-       generateExportKeyAndIvFcn       generateExportKeyAndIv;
        generateMasterSecretFcn         generateMasterSecret;
        computeFinishedMacFcn           computeFinishedMac;
        computeCertVfyMacFcn            computeCertVfyMac;
 } SslTlsCallouts;
 
        generateMasterSecretFcn         generateMasterSecret;
        computeFinishedMacFcn           computeFinishedMac;
        computeCertVfyMacFcn            computeCertVfyMac;
 } SslTlsCallouts;
 
+
 /* From ssl3Callouts.c and tls1Callouts.c */
 extern const SslTlsCallouts    Ssl3Callouts;
 extern const SslTlsCallouts    Tls1Callouts;
 extern const SslTlsCallouts Tls12Callouts;
 
 /* From ssl3Callouts.c and tls1Callouts.c */
 extern const SslTlsCallouts    Ssl3Callouts;
 extern const SslTlsCallouts    Tls1Callouts;
 extern const SslTlsCallouts Tls12Callouts;
 
-/* one callout routine used in common (for now) */
-OSStatus ssl3WriteRecord(
-       SSLRecord rec,
-       SSLContext *ctx);
-
 #ifdef __cplusplus
 }
 #endif
 #ifdef __cplusplus
 }
 #endif
index 10dd34e58323117017a4e0eb2a4a5b7533e9b26d..86bde6005c9a7130382eea7bd92bebdef5ed77a9 100644 (file)
        objectVersion = 46;
        objects = {
 
        objectVersion = 46;
        objects = {
 
+/* Begin PBXAggregateTarget section */
+               0C6C633A15D1BD4800BC68CD /* dtlsEcho */ = {
+                       isa = PBXAggregateTarget;
+                       buildConfigurationList = 0C6C633B15D1BD4800BC68CD /* Build configuration list for PBXAggregateTarget "dtlsEcho" */;
+                       buildPhases = (
+                       );
+                       dependencies = (
+                               0C6C633F15D1BD4D00BC68CD /* PBXTargetDependency */,
+                               0C6C634115D1BD4E00BC68CD /* PBXTargetDependency */,
+                       );
+                       name = dtlsEcho;
+                       productName = dtlsEcho;
+               };
+/* End PBXAggregateTarget section */
+
 /* Begin PBXBuildFile section */
 /* Begin PBXBuildFile section */
+               0C0E0467162C9DF0009F7C71 /* ssl-46-SSLGetSupportedCiphers.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C0E0466162C9DF0009F7C71 /* ssl-46-SSLGetSupportedCiphers.c */; };
+               0C0E046A162CA288009F7C71 /* ssl_regressions.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C0E0469162CA288009F7C71 /* ssl_regressions.h */; };
+               0C1C92F315C8AC81007D377B /* cipherSpecs.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF4020534D89900303760 /* cipherSpecs.h */; };
+               0C1C92F415C8AC81007D377B /* sslTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CCA413C15C75863002AEC4C /* sslTypes.h */; settings = {ATTRIBUTES = (); }; };
+               0C1C92F515C8AC81007D377B /* cryptType.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF4040534D89900303760 /* cryptType.h */; };
+               0C1C930015C8AC81007D377B /* sslMemory.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF4270534D89900303760 /* sslMemory.h */; };
+               0C1C930515C8AC81007D377B /* symCipher.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF4320534D89900303760 /* symCipher.h */; };
+               0C1C930615C8AC81007D377B /* tls_hmac.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF4350534D89900303760 /* tls_hmac.h */; };
+               0C1C930815C8AC81007D377B /* CipherSuite.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF4030534D89900303760 /* CipherSuite.h */; settings = {ATTRIBUTES = (); }; };
+               0C1C931015C8AC81007D377B /* tls_digest.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CCA413F15C75863002AEC4C /* tls_digest.h */; };
+               0C1C931115C8AC81007D377B /* tls_hashhmac.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CCA414115C75863002AEC4C /* tls_hashhmac.h */; };
+               0C1C931215C8AC81007D377B /* tls_record.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CCA414215C75863002AEC4C /* tls_record.h */; };
+               0C1C931615C8AC81007D377B /* cipherSpecs.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4010534D89900303760 /* cipherSpecs.c */; };
+               0C1C932415C8AC81007D377B /* sslMemory.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4260534D89900303760 /* sslMemory.c */; };
+               0C1C932515C8AC81007D377B /* sslNullCipher.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4280534D89900303760 /* sslNullCipher.c */; };
+               0C1C932915C8AC81007D377B /* sslUtils.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF42F0534D89900303760 /* sslUtils.c */; };
+               0C1C932A15C8AC81007D377B /* symCipher.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4310534D89900303760 /* symCipher.c */; };
+               0C1C932C15C8AC81007D377B /* tls_hmac.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4340534D89900303760 /* tls_hmac.c */; };
+               0C1C932E15C8AC81007D377B /* ssl3RecordCallouts.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CCA413515C75863002AEC4C /* ssl3RecordCallouts.c */; };
+               0C1C933015C8AC81007D377B /* sslRand.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CCA413815C75863002AEC4C /* sslRand.c */; };
+               0C1C933115C8AC81007D377B /* SSLRecordInternal.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CCA413A15C75863002AEC4C /* SSLRecordInternal.c */; };
+               0C1C933215C8AC81007D377B /* symCipherParams.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CCA413D15C75863002AEC4C /* symCipherParams.c */; };
+               0C1C933315C8AC81007D377B /* tls_digest.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CCA413E15C75863002AEC4C /* tls_digest.c */; };
+               0C1C933415C8AC81007D377B /* tls_hashhmac.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CCA414015C75863002AEC4C /* tls_hashhmac.c */; };
+               0C1C933515C8AC81007D377B /* tls1RecordCallouts.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CCA414315C75863002AEC4C /* tls1RecordCallouts.c */; };
+               0C1C933B15C8AFB8007D377B /* SSLRecordInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CCA413B15C75863002AEC4C /* SSLRecordInternal.h */; };
+               0C6C633515D1BB4F00BC68CD /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C6C633315D1BB3300BC68CD /* Security.framework */; };
+               0C6C633615D1BB6000BC68CD /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C6C633315D1BB3300BC68CD /* Security.framework */; };
+               0C6C633815D1BB7100BC68CD /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C6C633715D1BB7100BC68CD /* CoreFoundation.framework */; };
+               0C6C633915D1BBAA00BC68CD /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C6C633715D1BB7100BC68CD /* CoreFoundation.framework */; };
+               0C6C634315D1BDCF00BC68CD /* ssl-utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C6C634215D1BDCF00BC68CD /* ssl-utils.c */; };
+               0C6C634515D1BE3900BC68CD /* ssl-utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C6C634415D1BE3900BC68CD /* ssl-utils.h */; };
+               0C6C641F15D5840700BC68CD /* cert-1.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C6C641C15D5840700BC68CD /* cert-1.h */; };
+               0C6C642015D5840700BC68CD /* identity-1.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C6C641D15D5840700BC68CD /* identity-1.h */; };
+               0C6C642115D5840700BC68CD /* privkey-1.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C6C641E15D5840700BC68CD /* privkey-1.h */; };
+               0C6C642315D5938E00BC68CD /* ssl-utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C6C634215D1BDCF00BC68CD /* ssl-utils.c */; };
+               0C6C642415D5939A00BC68CD /* ssl-utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C6C634215D1BDCF00BC68CD /* ssl-utils.c */; };
+               0CADC66716769B7C000A70D4 /* ssl_regressions.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CADC66616769B7C000A70D4 /* ssl_regressions.h */; };
+               0CC954F1161A62AE005D3D4A /* ssl-44-crashes.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CC954F0161A62AE005D3D4A /* ssl-44-crashes.c */; };
+               0CCA414515C75863002AEC4C /* ssl3RecordCallouts.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CCA413515C75863002AEC4C /* ssl3RecordCallouts.c */; };
+               0CCA414615C75863002AEC4C /* sslCipherSpecs.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CCA413615C75863002AEC4C /* sslCipherSpecs.c */; };
+               0CCA414815C75863002AEC4C /* sslRand.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CCA413815C75863002AEC4C /* sslRand.c */; };
+               0CCA414A15C75863002AEC4C /* SSLRecordInternal.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CCA413A15C75863002AEC4C /* SSLRecordInternal.c */; };
+               0CCA414D15C75863002AEC4C /* symCipherParams.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CCA413D15C75863002AEC4C /* symCipherParams.c */; };
+               0CCA414E15C75863002AEC4C /* tls_digest.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CCA413E15C75863002AEC4C /* tls_digest.c */; };
+               0CCA415015C75863002AEC4C /* tls_hashhmac.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CCA414015C75863002AEC4C /* tls_hashhmac.c */; };
+               0CCA415315C75863002AEC4C /* tls1RecordCallouts.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CCA414315C75863002AEC4C /* tls1RecordCallouts.c */; };
+               0CCA416F15C89EA3002AEC4C /* ClientCert_ecc_ecc.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CCA415E15C89EA3002AEC4C /* ClientCert_ecc_ecc.h */; };
+               0CCA417015C89EA3002AEC4C /* ClientCert_ecc_rsa.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CCA415F15C89EA3002AEC4C /* ClientCert_ecc_rsa.h */; };
+               0CCA417115C89EA3002AEC4C /* ClientCert_rsa_ecc.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CCA416015C89EA3002AEC4C /* ClientCert_rsa_ecc.h */; };
+               0CCA417215C89EA3002AEC4C /* ClientCert_rsa_rsa.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CCA416115C89EA3002AEC4C /* ClientCert_rsa_rsa.h */; };
+               0CCA417315C89EA3002AEC4C /* ClientKey_ecc.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CCA416215C89EA3002AEC4C /* ClientKey_ecc.h */; };
+               0CCA417415C89EA3002AEC4C /* ClientKey_rsa.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CCA416315C89EA3002AEC4C /* ClientKey_rsa.h */; };
+               0CCA417515C89EA3002AEC4C /* SECG_ecc-secp256r1-client_cert.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CCA416415C89EA3002AEC4C /* SECG_ecc-secp256r1-client_cert.h */; };
+               0CCA417615C89EA3002AEC4C /* SECG_ecc-secp256r1-client_key.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CCA416515C89EA3002AEC4C /* SECG_ecc-secp256r1-client_key.h */; };
+               0CCA417715C89EA3002AEC4C /* SECG_ecc_rsa-secp256r1-client_cert.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CCA416615C89EA3002AEC4C /* SECG_ecc_rsa-secp256r1-client_cert.h */; };
+               0CCA417815C89EA3002AEC4C /* SECG_ecc_rsa-secp256r1-client_key.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CCA416715C89EA3002AEC4C /* SECG_ecc_rsa-secp256r1-client_key.h */; };
+               0CCA417915C89EA3002AEC4C /* ssl-39-echo.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CCA416815C89EA3002AEC4C /* ssl-39-echo.c */; };
+               0CCA417A15C89EA3002AEC4C /* ssl-40-clientauth.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CCA416915C89EA3002AEC4C /* ssl-40-clientauth.c */; };
+               0CCA417B15C89EA3002AEC4C /* ssl-41-clientauth.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CCA416A15C89EA3002AEC4C /* ssl-41-clientauth.c */; };
+               0CCA417C15C89EA3002AEC4C /* ssl-42-ciphers.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CCA416B15C89EA3002AEC4C /* ssl-42-ciphers.c */; };
+               0CCA417D15C89EA3002AEC4C /* ssl-43-ciphers.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CCA416C15C89EA3002AEC4C /* ssl-43-ciphers.c */; };
+               0CCA417E15C89EA3002AEC4C /* ssl-45-tls12.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CCA416D15C89EA3002AEC4C /* ssl-45-tls12.c */; };
+               0CCA42E115C8A3D9002AEC4C /* dtlsEchoClient.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CCA42C115C8A34E002AEC4C /* dtlsEchoClient.c */; };
+               0CCA42E215C8A3DE002AEC4C /* dtlsEchoServer.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CCA42C215C8A34E002AEC4C /* dtlsEchoServer.c */; };
+               0CCA42EC15C8A71A002AEC4C /* sslAppUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0CCA42EA15C8A71A002AEC4C /* sslAppUtils.cpp */; };
+               0CCA42ED15C8A71A002AEC4C /* sslAppUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0CCA42EA15C8A71A002AEC4C /* sslAppUtils.cpp */; };
+               0CCF28B8166D5F5000AFA37C /* ssl-47-falsestart.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CCF28B7166D5F5000AFA37C /* ssl-47-falsestart.c */; };
                4CAFF4370534D89900303760 /* appleCdsa.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF3FD0534D89900303760 /* appleCdsa.c */; };
                4CAFF4370534D89900303760 /* appleCdsa.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF3FD0534D89900303760 /* appleCdsa.c */; };
-               4CAFF4380534D89900303760 /* appleCdsa.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF3FE0534D89900303760 /* appleCdsa.h */; };
                4CAFF4390534D89900303760 /* appleSession.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF3FF0534D89900303760 /* appleSession.c */; };
                4CAFF4390534D89900303760 /* appleSession.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF3FF0534D89900303760 /* appleSession.c */; };
-               4CAFF43A0534D89900303760 /* appleSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF4000534D89900303760 /* appleSession.h */; };
                4CAFF43B0534D89900303760 /* cipherSpecs.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4010534D89900303760 /* cipherSpecs.c */; };
                4CAFF43B0534D89900303760 /* cipherSpecs.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4010534D89900303760 /* cipherSpecs.c */; };
-               4CAFF43C0534D89900303760 /* cipherSpecs.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF4020534D89900303760 /* cipherSpecs.h */; };
-               4CAFF43E0534D89900303760 /* cryptType.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF4040534D89900303760 /* cryptType.h */; };
                4CAFF43F0534D89900303760 /* ModuleAttacher.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4050534D89900303760 /* ModuleAttacher.c */; };
                4CAFF43F0534D89900303760 /* ModuleAttacher.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4050534D89900303760 /* ModuleAttacher.c */; };
-               4CAFF4400534D89900303760 /* ModuleAttacher.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF4060534D89900303760 /* ModuleAttacher.h */; };
-               4CAFF4410534D89900303760 /* securetransport++.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4070534D89900303760 /* securetransport++.cpp */; };
-               4CAFF4420534D89900303760 /* securetransport++.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF4080534D89900303760 /* securetransport++.h */; };
-               4CAFF4450534D89900303760 /* ssl.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF40B0534D89900303760 /* ssl.h */; };
                4CAFF44B0534D89900303760 /* ssl3Callouts.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4110534D89900303760 /* ssl3Callouts.c */; };
                4CAFF44C0534D89900303760 /* sslAlertMessage.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4120534D89900303760 /* sslAlertMessage.c */; };
                4CAFF44B0534D89900303760 /* ssl3Callouts.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4110534D89900303760 /* ssl3Callouts.c */; };
                4CAFF44C0534D89900303760 /* sslAlertMessage.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4120534D89900303760 /* sslAlertMessage.c */; };
-               4CAFF44D0534D89900303760 /* sslAlertMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF4130534D89900303760 /* sslAlertMessage.h */; };
                4CAFF44E0534D89900303760 /* sslBER.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4140534D89900303760 /* sslBER.c */; };
                4CAFF44E0534D89900303760 /* sslBER.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4140534D89900303760 /* sslBER.c */; };
-               4CAFF44F0534D89900303760 /* sslBER.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF4150534D89900303760 /* sslBER.h */; };
-               4CAFF4510534D89900303760 /* sslBuildFlags.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF4170534D89900303760 /* sslBuildFlags.h */; };
                4CAFF4520534D89900303760 /* sslCert.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4180534D89900303760 /* sslCert.c */; };
                4CAFF4530534D89900303760 /* sslChangeCipher.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4190534D89900303760 /* sslChangeCipher.c */; };
                4CAFF4540534D89900303760 /* sslContext.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF41A0534D89900303760 /* sslContext.c */; };
                4CAFF4520534D89900303760 /* sslCert.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4180534D89900303760 /* sslCert.c */; };
                4CAFF4530534D89900303760 /* sslChangeCipher.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4190534D89900303760 /* sslChangeCipher.c */; };
                4CAFF4540534D89900303760 /* sslContext.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF41A0534D89900303760 /* sslContext.c */; };
-               4CAFF4550534D89900303760 /* sslContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF41B0534D89900303760 /* sslContext.h */; };
-               4CAFF4560534D89900303760 /* sslDebug.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF41C0534D89900303760 /* sslDebug.h */; };
                4CAFF4570534D89900303760 /* sslDigests.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF41D0534D89900303760 /* sslDigests.c */; };
                4CAFF4570534D89900303760 /* sslDigests.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF41D0534D89900303760 /* sslDigests.c */; };
-               4CAFF4580534D89900303760 /* sslDigests.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF41E0534D89900303760 /* sslDigests.h */; };
                4CAFF4590534D89900303760 /* sslHandshake.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF41F0534D89900303760 /* sslHandshake.c */; };
                4CAFF4590534D89900303760 /* sslHandshake.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF41F0534D89900303760 /* sslHandshake.c */; };
-               4CAFF45A0534D89900303760 /* sslHandshake.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF4200534D89900303760 /* sslHandshake.h */; };
                4CAFF45B0534D89900303760 /* sslHandshakeFinish.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4210534D89900303760 /* sslHandshakeFinish.c */; };
                4CAFF45C0534D89900303760 /* sslHandshakeHello.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4220534D89900303760 /* sslHandshakeHello.c */; };
                4CAFF45D0534D89900303760 /* sslKeychain.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4230534D89900303760 /* sslKeychain.c */; };
                4CAFF45B0534D89900303760 /* sslHandshakeFinish.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4210534D89900303760 /* sslHandshakeFinish.c */; };
                4CAFF45C0534D89900303760 /* sslHandshakeHello.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4220534D89900303760 /* sslHandshakeHello.c */; };
                4CAFF45D0534D89900303760 /* sslKeychain.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4230534D89900303760 /* sslKeychain.c */; };
-               4CAFF45E0534D89900303760 /* sslKeychain.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF4240534D89900303760 /* sslKeychain.h */; };
                4CAFF45F0534D89900303760 /* sslKeyExchange.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4250534D89900303760 /* sslKeyExchange.c */; };
                4CAFF4600534D89900303760 /* sslMemory.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4260534D89900303760 /* sslMemory.c */; };
                4CAFF45F0534D89900303760 /* sslKeyExchange.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4250534D89900303760 /* sslKeyExchange.c */; };
                4CAFF4600534D89900303760 /* sslMemory.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4260534D89900303760 /* sslMemory.c */; };
-               4CAFF4610534D89900303760 /* sslMemory.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF4270534D89900303760 /* sslMemory.h */; };
                4CAFF4620534D89900303760 /* sslNullCipher.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4280534D89900303760 /* sslNullCipher.c */; };
                4CAFF4620534D89900303760 /* sslNullCipher.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4280534D89900303760 /* sslNullCipher.c */; };
-               4CAFF4630534D89900303760 /* sslPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF4290534D89900303760 /* sslPriv.h */; };
                4CAFF4640534D89900303760 /* sslRecord.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF42A0534D89900303760 /* sslRecord.c */; };
                4CAFF4640534D89900303760 /* sslRecord.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF42A0534D89900303760 /* sslRecord.c */; };
-               4CAFF4650534D89900303760 /* sslRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF42B0534D89900303760 /* sslRecord.h */; };
                4CAFF4660534D89900303760 /* sslSession.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF42C0534D89900303760 /* sslSession.c */; };
                4CAFF4660534D89900303760 /* sslSession.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF42C0534D89900303760 /* sslSession.c */; };
-               4CAFF4670534D89900303760 /* sslSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF42D0534D89900303760 /* sslSession.h */; };
                4CAFF4680534D89900303760 /* sslTransport.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF42E0534D89900303760 /* sslTransport.c */; };
                4CAFF4690534D89900303760 /* sslUtils.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF42F0534D89900303760 /* sslUtils.c */; };
                4CAFF4680534D89900303760 /* sslTransport.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF42E0534D89900303760 /* sslTransport.c */; };
                4CAFF4690534D89900303760 /* sslUtils.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF42F0534D89900303760 /* sslUtils.c */; };
-               4CAFF46A0534D89900303760 /* sslUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF4300534D89900303760 /* sslUtils.h */; };
                4CAFF46B0534D89900303760 /* symCipher.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4310534D89900303760 /* symCipher.c */; };
                4CAFF46B0534D89900303760 /* symCipher.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4310534D89900303760 /* symCipher.c */; };
-               4CAFF46C0534D89900303760 /* symCipher.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF4320534D89900303760 /* symCipher.h */; };
                4CAFF46D0534D89900303760 /* tls1Callouts.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4330534D89900303760 /* tls1Callouts.c */; };
                4CAFF46E0534D89900303760 /* tls_hmac.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4340534D89900303760 /* tls_hmac.c */; };
                4CAFF46D0534D89900303760 /* tls1Callouts.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4330534D89900303760 /* tls1Callouts.c */; };
                4CAFF46E0534D89900303760 /* tls_hmac.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF4340534D89900303760 /* tls_hmac.c */; };
-               4CAFF46F0534D89900303760 /* tls_hmac.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF4350534D89900303760 /* tls_hmac.h */; };
-               4CAFF4700534D89900303760 /* tls_ssl.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF4360534D89900303760 /* tls_ssl.h */; };
-               4CF36F910581386100834D11 /* CipherSuite.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF4030534D89900303760 /* CipherSuite.h */; settings = {ATTRIBUTES = (Public, ); }; };
-               4CF36F930581386B00834D11 /* SecureTransport.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF4090534D89900303760 /* SecureTransport.h */; settings = {ATTRIBUTES = (Public, ); }; };
-               4CF36F940581388000834D11 /* SecureTransportPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAFF40A0534D89900303760 /* SecureTransportPriv.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               AAB589F216CACE540071FE64 /* ssl-44-crashes.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CC954F0161A62AE005D3D4A /* ssl-44-crashes.c */; };
                BEB382AC14EC84A0003C055B /* sslCrypto.c in Sources */ = {isa = PBXBuildFile; fileRef = BEB382AB14EC84A0003C055B /* sslCrypto.c */; };
                BEB382AC14EC84A0003C055B /* sslCrypto.c in Sources */ = {isa = PBXBuildFile; fileRef = BEB382AB14EC84A0003C055B /* sslCrypto.c */; };
-               BEB382AF14EC84AC003C055B /* sslCrypto.h in Headers */ = {isa = PBXBuildFile; fileRef = BEB382AE14EC84AC003C055B /* sslCrypto.h */; };
 /* End PBXBuildFile section */
 
 /* End PBXBuildFile section */
 
+/* Begin PBXContainerItemProxy section */
+               0C6C633E15D1BD4D00BC68CD /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 4CA1FEAB052A3C3800F22E42 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 0CCA42C815C8A387002AEC4C;
+                       remoteInfo = dtlsEchoClient;
+               };
+               0C6C634015D1BD4E00BC68CD /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 4CA1FEAB052A3C3800F22E42 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 0CCA42D615C8A395002AEC4C;
+                       remoteInfo = dtlsEchoServer;
+               };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+               0CCA42C715C8A387002AEC4C /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 2147483647;
+                       dstPath = /usr/share/man/man1/;
+                       dstSubfolderSpec = 0;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+               0CCA42D515C8A395002AEC4C /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 2147483647;
+                       dstPath = /usr/share/man/man1/;
+                       dstSubfolderSpec = 0;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+/* End PBXCopyFilesBuildPhase section */
+
 /* Begin PBXFileReference section */
 /* Begin PBXFileReference section */
+               0C0E0466162C9DF0009F7C71 /* ssl-46-SSLGetSupportedCiphers.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "ssl-46-SSLGetSupportedCiphers.c"; sourceTree = "<group>"; };
+               0C0E0469162CA288009F7C71 /* ssl_regressions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ssl_regressions.h; sourceTree = "<group>"; };
+               0C1C92ED15C8AC52007D377B /* kext.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = kext.xcconfig; sourceTree = "<group>"; };
+               0C1C933A15C8AC81007D377B /* libsecurity_ssl_kext.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurity_ssl_kext.a; sourceTree = BUILT_PRODUCTS_DIR; };
+               0C6C633315D1BB3300BC68CD /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Security.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+               0C6C633715D1BB7100BC68CD /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
+               0C6C634215D1BDCF00BC68CD /* ssl-utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "ssl-utils.c"; sourceTree = "<group>"; };
+               0C6C634415D1BE3900BC68CD /* ssl-utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ssl-utils.h"; sourceTree = "<group>"; };
+               0C6C641C15D5840700BC68CD /* cert-1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "cert-1.h"; sourceTree = "<group>"; };
+               0C6C641D15D5840700BC68CD /* identity-1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "identity-1.h"; sourceTree = "<group>"; };
+               0C6C641E15D5840700BC68CD /* privkey-1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "privkey-1.h"; sourceTree = "<group>"; };
+               0C85738D15DAB34C0038DFD7 /* tests.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = tests.xcconfig; sourceTree = "<group>"; };
+               0CC954F0161A62AE005D3D4A /* ssl-44-crashes.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "ssl-44-crashes.c"; sourceTree = "<group>"; };
+               0CCA413415C75863002AEC4C /* SecureTransportPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecureTransportPriv.h; path = ../lib/SecureTransportPriv.h; sourceTree = "<group>"; };
+               0CCA413515C75863002AEC4C /* ssl3RecordCallouts.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ssl3RecordCallouts.c; sourceTree = "<group>"; };
+               0CCA413615C75863002AEC4C /* sslCipherSpecs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sslCipherSpecs.c; sourceTree = "<group>"; };
+               0CCA413715C75863002AEC4C /* sslCipherSpecs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sslCipherSpecs.h; sourceTree = "<group>"; };
+               0CCA413815C75863002AEC4C /* sslRand.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sslRand.c; sourceTree = "<group>"; };
+               0CCA413915C75863002AEC4C /* sslRand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sslRand.h; sourceTree = "<group>"; };
+               0CCA413A15C75863002AEC4C /* SSLRecordInternal.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SSLRecordInternal.c; sourceTree = "<group>"; };
+               0CCA413B15C75863002AEC4C /* SSLRecordInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSLRecordInternal.h; sourceTree = "<group>"; };
+               0CCA413C15C75863002AEC4C /* sslTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sslTypes.h; path = ../lib/sslTypes.h; sourceTree = "<group>"; };
+               0CCA413D15C75863002AEC4C /* symCipherParams.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = symCipherParams.c; sourceTree = "<group>"; };
+               0CCA413E15C75863002AEC4C /* tls_digest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tls_digest.c; sourceTree = "<group>"; };
+               0CCA413F15C75863002AEC4C /* tls_digest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tls_digest.h; sourceTree = "<group>"; };
+               0CCA414015C75863002AEC4C /* tls_hashhmac.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tls_hashhmac.c; sourceTree = "<group>"; };
+               0CCA414115C75863002AEC4C /* tls_hashhmac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tls_hashhmac.h; sourceTree = "<group>"; };
+               0CCA414215C75863002AEC4C /* tls_record.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tls_record.h; sourceTree = "<group>"; };
+               0CCA414315C75863002AEC4C /* tls1RecordCallouts.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tls1RecordCallouts.c; sourceTree = "<group>"; };
+               0CCA415915C89E8B002AEC4C /* libsecurity_ssl_regressions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurity_ssl_regressions.a; sourceTree = BUILT_PRODUCTS_DIR; };
+               0CCA415E15C89EA3002AEC4C /* ClientCert_ecc_ecc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClientCert_ecc_ecc.h; sourceTree = "<group>"; };
+               0CCA415F15C89EA3002AEC4C /* ClientCert_ecc_rsa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClientCert_ecc_rsa.h; sourceTree = "<group>"; };
+               0CCA416015C89EA3002AEC4C /* ClientCert_rsa_ecc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClientCert_rsa_ecc.h; sourceTree = "<group>"; };
+               0CCA416115C89EA3002AEC4C /* ClientCert_rsa_rsa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClientCert_rsa_rsa.h; sourceTree = "<group>"; };
+               0CCA416215C89EA3002AEC4C /* ClientKey_ecc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClientKey_ecc.h; sourceTree = "<group>"; };
+               0CCA416315C89EA3002AEC4C /* ClientKey_rsa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClientKey_rsa.h; sourceTree = "<group>"; };
+               0CCA416415C89EA3002AEC4C /* SECG_ecc-secp256r1-client_cert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SECG_ecc-secp256r1-client_cert.h"; sourceTree = "<group>"; };
+               0CCA416515C89EA3002AEC4C /* SECG_ecc-secp256r1-client_key.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SECG_ecc-secp256r1-client_key.h"; sourceTree = "<group>"; };
+               0CCA416615C89EA3002AEC4C /* SECG_ecc_rsa-secp256r1-client_cert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SECG_ecc_rsa-secp256r1-client_cert.h"; sourceTree = "<group>"; };
+               0CCA416715C89EA3002AEC4C /* SECG_ecc_rsa-secp256r1-client_key.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SECG_ecc_rsa-secp256r1-client_key.h"; sourceTree = "<group>"; };
+               0CCA416815C89EA3002AEC4C /* ssl-39-echo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "ssl-39-echo.c"; sourceTree = "<group>"; };
+               0CCA416915C89EA3002AEC4C /* ssl-40-clientauth.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "ssl-40-clientauth.c"; sourceTree = "<group>"; };
+               0CCA416A15C89EA3002AEC4C /* ssl-41-clientauth.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "ssl-41-clientauth.c"; sourceTree = "<group>"; };
+               0CCA416B15C89EA3002AEC4C /* ssl-42-ciphers.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "ssl-42-ciphers.c"; sourceTree = "<group>"; };
+               0CCA416C15C89EA3002AEC4C /* ssl-43-ciphers.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "ssl-43-ciphers.c"; sourceTree = "<group>"; };
+               0CCA416D15C89EA3002AEC4C /* ssl-45-tls12.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "ssl-45-tls12.c"; sourceTree = "<group>"; };
+               0CCA42C115C8A34E002AEC4C /* dtlsEchoClient.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = dtlsEchoClient.c; sourceTree = "<group>"; };
+               0CCA42C215C8A34E002AEC4C /* dtlsEchoServer.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = dtlsEchoServer.c; sourceTree = "<group>"; };
+               0CCA42C315C8A34E002AEC4C /* README */ = {isa = PBXFileReference; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
+               0CCA42C915C8A387002AEC4C /* dtlsEchoClient */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = dtlsEchoClient; sourceTree = BUILT_PRODUCTS_DIR; };
+               0CCA42D715C8A395002AEC4C /* dtlsEchoServer */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = dtlsEchoServer; sourceTree = BUILT_PRODUCTS_DIR; };
+               0CCA42EA15C8A71A002AEC4C /* sslAppUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = sslAppUtils.cpp; path = sslViewer/sslAppUtils.cpp; sourceTree = SOURCE_ROOT; };
+               0CCA42EB15C8A71A002AEC4C /* sslAppUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sslAppUtils.h; path = sslViewer/sslAppUtils.h; sourceTree = SOURCE_ROOT; };
+               0CCF28B7166D5F5000AFA37C /* ssl-47-falsestart.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "ssl-47-falsestart.c"; sourceTree = "<group>"; };
                4CA1FEBE052A3C8100F22E42 /* libsecurity_ssl.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libsecurity_ssl.a; sourceTree = BUILT_PRODUCTS_DIR; };
                4CAFF3FD0534D89900303760 /* appleCdsa.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = appleCdsa.c; sourceTree = "<group>"; };
                4CAFF3FE0534D89900303760 /* appleCdsa.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = appleCdsa.h; sourceTree = "<group>"; };
                4CA1FEBE052A3C8100F22E42 /* libsecurity_ssl.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libsecurity_ssl.a; sourceTree = BUILT_PRODUCTS_DIR; };
                4CAFF3FD0534D89900303760 /* appleCdsa.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = appleCdsa.c; sourceTree = "<group>"; };
                4CAFF3FE0534D89900303760 /* appleCdsa.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = appleCdsa.h; sourceTree = "<group>"; };
                4CAFF4070534D89900303760 /* securetransport++.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = "securetransport++.cpp"; sourceTree = "<group>"; };
                4CAFF4080534D89900303760 /* securetransport++.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = "securetransport++.h"; sourceTree = "<group>"; };
                4CAFF4090534D89900303760 /* SecureTransport.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecureTransport.h; sourceTree = "<group>"; };
                4CAFF4070534D89900303760 /* securetransport++.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = "securetransport++.cpp"; sourceTree = "<group>"; };
                4CAFF4080534D89900303760 /* securetransport++.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = "securetransport++.h"; sourceTree = "<group>"; };
                4CAFF4090534D89900303760 /* SecureTransport.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecureTransport.h; sourceTree = "<group>"; };
-               4CAFF40A0534D89900303760 /* SecureTransportPriv.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecureTransportPriv.h; sourceTree = "<group>"; };
                4CAFF40B0534D89900303760 /* ssl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ssl.h; sourceTree = "<group>"; };
                4CAFF4110534D89900303760 /* ssl3Callouts.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = ssl3Callouts.c; sourceTree = "<group>"; };
                4CAFF4120534D89900303760 /* sslAlertMessage.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = sslAlertMessage.c; sourceTree = "<group>"; };
                4CAFF40B0534D89900303760 /* ssl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ssl.h; sourceTree = "<group>"; };
                4CAFF4110534D89900303760 /* ssl3Callouts.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = ssl3Callouts.c; sourceTree = "<group>"; };
                4CAFF4120534D89900303760 /* sslAlertMessage.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = sslAlertMessage.c; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
+               0C1C933615C8AC81007D377B /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               0CCA415615C89E8B002AEC4C /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               0CCA42C615C8A387002AEC4C /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               0C6C633815D1BB7100BC68CD /* CoreFoundation.framework in Frameworks */,
+                               0C6C633515D1BB4F00BC68CD /* Security.framework in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               0CCA42D415C8A395002AEC4C /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               0C6C633915D1BBAA00BC68CD /* CoreFoundation.framework in Frameworks */,
+                               0C6C633615D1BB6000BC68CD /* Security.framework in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                4CA1FEBB052A3C8100F22E42 /* Frameworks */ = {
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                4CA1FEBB052A3C8100F22E42 /* Frameworks */ = {
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                050651C8056A8404008AD683 /* SSL Core */ = {
                        isa = PBXGroup;
                        children = (
                050651C8056A8404008AD683 /* SSL Core */ = {
                        isa = PBXGroup;
                        children = (
+                               0CCA413A15C75863002AEC4C /* SSLRecordInternal.c */,
                                4CAFF4120534D89900303760 /* sslAlertMessage.c */,
                                4CAFF4120534D89900303760 /* sslAlertMessage.c */,
+                               0CCA413615C75863002AEC4C /* sslCipherSpecs.c */,
                                4CAFF41A0534D89900303760 /* sslContext.c */,
                                4CAFF42A0534D89900303760 /* sslRecord.c */,
                                4CAFF42C0534D89900303760 /* sslSession.c */,
                                4CAFF42E0534D89900303760 /* sslTransport.c */,
                                4CAFF4110534D89900303760 /* ssl3Callouts.c */,
                                4CAFF41A0534D89900303760 /* sslContext.c */,
                                4CAFF42A0534D89900303760 /* sslRecord.c */,
                                4CAFF42C0534D89900303760 /* sslSession.c */,
                                4CAFF42E0534D89900303760 /* sslTransport.c */,
                                4CAFF4110534D89900303760 /* ssl3Callouts.c */,
+                               0CCA413515C75863002AEC4C /* ssl3RecordCallouts.c */,
                                4CAFF4330534D89900303760 /* tls1Callouts.c */,
                                4CAFF4330534D89900303760 /* tls1Callouts.c */,
+                               0CCA414315C75863002AEC4C /* tls1RecordCallouts.c */,
                                050651E4056A86CF008AD683 /* Handshake */,
                        );
                        name = "SSL Core";
                                050651E4056A86CF008AD683 /* Handshake */,
                        );
                        name = "SSL Core";
                050651C9056A840E008AD683 /* Private Headers */ = {
                        isa = PBXGroup;
                        children = (
                050651C9056A840E008AD683 /* Private Headers */ = {
                        isa = PBXGroup;
                        children = (
-                               4CAFF40A0534D89900303760 /* SecureTransportPriv.h */,
+                               0CCA413C15C75863002AEC4C /* sslTypes.h */,
+                               0CCA413415C75863002AEC4C /* SecureTransportPriv.h */,
                        );
                        name = "Private Headers";
                        path = ../Security;
                        );
                        name = "Private Headers";
                        path = ../Security;
                        isa = PBXGroup;
                        children = (
                                4CAFF4010534D89900303760 /* cipherSpecs.c */,
                        isa = PBXGroup;
                        children = (
                                4CAFF4010534D89900303760 /* cipherSpecs.c */,
+                               0CCA413D15C75863002AEC4C /* symCipherParams.c */,
+                               0CCA413815C75863002AEC4C /* sslRand.c */,
                                BEB382AB14EC84A0003C055B /* sslCrypto.c */,
                                4CAFF41D0534D89900303760 /* sslDigests.c */,
                                4CAFF4280534D89900303760 /* sslNullCipher.c */,
                                4CAFF4310534D89900303760 /* symCipher.c */,
                                BEB382AB14EC84A0003C055B /* sslCrypto.c */,
                                4CAFF41D0534D89900303760 /* sslDigests.c */,
                                4CAFF4280534D89900303760 /* sslNullCipher.c */,
                                4CAFF4310534D89900303760 /* symCipher.c */,
+                               0CCA413E15C75863002AEC4C /* tls_digest.c */,
+                               0CCA414015C75863002AEC4C /* tls_hashhmac.c */,
                                4CAFF4340534D89900303760 /* tls_hmac.c */,
                        );
                        name = Crypto;
                                4CAFF4340534D89900303760 /* tls_hmac.c */,
                        );
                        name = Crypto;
                        name = Handshake;
                        sourceTree = "<group>";
                };
                        name = Handshake;
                        sourceTree = "<group>";
                };
+               0CCA415D15C89EA3002AEC4C /* regressions */ = {
+                       isa = PBXGroup;
+                       children = (
+                               0C6C641C15D5840700BC68CD /* cert-1.h */,
+                               0C6C641D15D5840700BC68CD /* identity-1.h */,
+                               0C6C641E15D5840700BC68CD /* privkey-1.h */,
+                               0CCA415E15C89EA3002AEC4C /* ClientCert_ecc_ecc.h */,
+                               0CCA415F15C89EA3002AEC4C /* ClientCert_ecc_rsa.h */,
+                               0CCA416015C89EA3002AEC4C /* ClientCert_rsa_ecc.h */,
+                               0CCA416115C89EA3002AEC4C /* ClientCert_rsa_rsa.h */,
+                               0CCA416215C89EA3002AEC4C /* ClientKey_ecc.h */,
+                               0CCA416315C89EA3002AEC4C /* ClientKey_rsa.h */,
+                               0CCA416415C89EA3002AEC4C /* SECG_ecc-secp256r1-client_cert.h */,
+                               0CCA416515C89EA3002AEC4C /* SECG_ecc-secp256r1-client_key.h */,
+                               0CCA416615C89EA3002AEC4C /* SECG_ecc_rsa-secp256r1-client_cert.h */,
+                               0CCA416715C89EA3002AEC4C /* SECG_ecc_rsa-secp256r1-client_key.h */,
+                               0CCA416815C89EA3002AEC4C /* ssl-39-echo.c */,
+                               0CCA416915C89EA3002AEC4C /* ssl-40-clientauth.c */,
+                               0CCA416A15C89EA3002AEC4C /* ssl-41-clientauth.c */,
+                               0CCA416B15C89EA3002AEC4C /* ssl-42-ciphers.c */,
+                               0CCA416C15C89EA3002AEC4C /* ssl-43-ciphers.c */,
+                               0CC954F0161A62AE005D3D4A /* ssl-44-crashes.c */,
+                               0CCA416D15C89EA3002AEC4C /* ssl-45-tls12.c */,
+                               0C0E0466162C9DF0009F7C71 /* ssl-46-SSLGetSupportedCiphers.c */,
+                               0CCF28B7166D5F5000AFA37C /* ssl-47-falsestart.c */,
+                               0C6C634215D1BDCF00BC68CD /* ssl-utils.c */,
+                               0C6C634415D1BE3900BC68CD /* ssl-utils.h */,
+                               0C0E0469162CA288009F7C71 /* ssl_regressions.h */,
+                       );
+                       path = regressions;
+                       sourceTree = "<group>";
+               };
+               0CCA42C015C8A34E002AEC4C /* dtlsEcho */ = {
+                       isa = PBXGroup;
+                       children = (
+                               0CCA42EA15C8A71A002AEC4C /* sslAppUtils.cpp */,
+                               0CCA42EB15C8A71A002AEC4C /* sslAppUtils.h */,
+                               0CCA42C115C8A34E002AEC4C /* dtlsEchoClient.c */,
+                               0CCA42C215C8A34E002AEC4C /* dtlsEchoServer.c */,
+                               0CCA42C315C8A34E002AEC4C /* README */,
+                       );
+                       path = dtlsEcho;
+                       sourceTree = "<group>";
+               };
                4CA1FEA7052A3C3800F22E42 = {
                        isa = PBXGroup;
                        children = (
                4CA1FEA7052A3C3800F22E42 = {
                        isa = PBXGroup;
                        children = (
+                               0C6C633715D1BB7100BC68CD /* CoreFoundation.framework */,
+                               0C6C633315D1BB3300BC68CD /* Security.framework */,
+                               0CCA42C015C8A34E002AEC4C /* dtlsEcho */,
+                               0CCA415D15C89EA3002AEC4C /* regressions */,
                                BE6A959B14E3700A00C158E0 /* config */,
                                4CAFF3FC0534D89900303760 /* lib */,
                                4CA1FEBF052A3C8100F22E42 /* Products */,
                                BE6A959B14E3700A00C158E0 /* config */,
                                4CAFF3FC0534D89900303760 /* lib */,
                                4CA1FEBF052A3C8100F22E42 /* Products */,
                        isa = PBXGroup;
                        children = (
                                4CA1FEBE052A3C8100F22E42 /* libsecurity_ssl.a */,
                        isa = PBXGroup;
                        children = (
                                4CA1FEBE052A3C8100F22E42 /* libsecurity_ssl.a */,
+                               0CCA415915C89E8B002AEC4C /* libsecurity_ssl_regressions.a */,
+                               0CCA42C915C8A387002AEC4C /* dtlsEchoClient */,
+                               0CCA42D715C8A395002AEC4C /* dtlsEchoServer */,
+                               0C1C933A15C8AC81007D377B /* libsecurity_ssl_kext.a */,
                        );
                        name = Products;
                        sourceTree = "<group>";
                        );
                        name = Products;
                        sourceTree = "<group>";
                        children = (
                                BE6A959C14E3700A00C158E0 /* base.xcconfig */,
                                BE6A959D14E3700A00C158E0 /* debug.xcconfig */,
                        children = (
                                BE6A959C14E3700A00C158E0 /* base.xcconfig */,
                                BE6A959D14E3700A00C158E0 /* debug.xcconfig */,
+                               0C1C92ED15C8AC52007D377B /* kext.xcconfig */,
                                BE6A959E14E3700A00C158E0 /* lib.xcconfig */,
                                BE6A959F14E3700A00C158E0 /* release.xcconfig */,
                                BE6A959E14E3700A00C158E0 /* lib.xcconfig */,
                                BE6A959F14E3700A00C158E0 /* release.xcconfig */,
+                               0C85738D15DAB34C0038DFD7 /* tests.xcconfig */,
                        );
                        path = config;
                        sourceTree = "<group>";
                        );
                        path = config;
                        sourceTree = "<group>";
                BE967B0314E9F622002A348A /* Project Headers */ = {
                        isa = PBXGroup;
                        children = (
                BE967B0314E9F622002A348A /* Project Headers */ = {
                        isa = PBXGroup;
                        children = (
+                               0CCA413715C75863002AEC4C /* sslCipherSpecs.h */,
+                               0CCA413B15C75863002AEC4C /* SSLRecordInternal.h */,
+                               0CCA413915C75863002AEC4C /* sslRand.h */,
+                               0CCA413F15C75863002AEC4C /* tls_digest.h */,
+                               0CCA414115C75863002AEC4C /* tls_hashhmac.h */,
+                               0CCA414215C75863002AEC4C /* tls_record.h */,
                                4CAFF3FE0534D89900303760 /* appleCdsa.h */,
                                4CAFF4000534D89900303760 /* appleSession.h */,
                                4CAFF4020534D89900303760 /* cipherSpecs.h */,
                                4CAFF3FE0534D89900303760 /* appleCdsa.h */,
                                4CAFF4000534D89900303760 /* appleSession.h */,
                                4CAFF4020534D89900303760 /* cipherSpecs.h */,
 /* End PBXGroup section */
 
 /* Begin PBXHeadersBuildPhase section */
 /* End PBXGroup section */
 
 /* Begin PBXHeadersBuildPhase section */
-               4CA1FEB9052A3C8100F22E42 /* Headers */ = {
+               0C1C92F015C8AC81007D377B /* Headers */ = {
                        isa = PBXHeadersBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        isa = PBXHeadersBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
-                               4CAFF4380534D89900303760 /* appleCdsa.h in Headers */,
-                               4CAFF43A0534D89900303760 /* appleSession.h in Headers */,
-                               4CAFF43C0534D89900303760 /* cipherSpecs.h in Headers */,
-                               4CAFF43E0534D89900303760 /* cryptType.h in Headers */,
-                               4CAFF4400534D89900303760 /* ModuleAttacher.h in Headers */,
-                               4CAFF4420534D89900303760 /* securetransport++.h in Headers */,
-                               4CAFF4450534D89900303760 /* ssl.h in Headers */,
-                               4CAFF44D0534D89900303760 /* sslAlertMessage.h in Headers */,
-                               4CAFF44F0534D89900303760 /* sslBER.h in Headers */,
-                               4CAFF4510534D89900303760 /* sslBuildFlags.h in Headers */,
-                               4CAFF4550534D89900303760 /* sslContext.h in Headers */,
-                               4CAFF4560534D89900303760 /* sslDebug.h in Headers */,
-                               4CAFF4580534D89900303760 /* sslDigests.h in Headers */,
-                               4CAFF45A0534D89900303760 /* sslHandshake.h in Headers */,
-                               4CAFF45E0534D89900303760 /* sslKeychain.h in Headers */,
-                               4CAFF4610534D89900303760 /* sslMemory.h in Headers */,
-                               4CAFF4630534D89900303760 /* sslPriv.h in Headers */,
-                               4CAFF4650534D89900303760 /* sslRecord.h in Headers */,
-                               4CAFF4670534D89900303760 /* sslSession.h in Headers */,
-                               4CAFF46A0534D89900303760 /* sslUtils.h in Headers */,
-                               4CAFF46C0534D89900303760 /* symCipher.h in Headers */,
-                               4CAFF46F0534D89900303760 /* tls_hmac.h in Headers */,
-                               4CAFF4700534D89900303760 /* tls_ssl.h in Headers */,
-                               4CF36F910581386100834D11 /* CipherSuite.h in Headers */,
-                               4CF36F930581386B00834D11 /* SecureTransport.h in Headers */,
-                               4CF36F940581388000834D11 /* SecureTransportPriv.h in Headers */,
-                               BEB382AF14EC84AC003C055B /* sslCrypto.h in Headers */,
+                               0C1C933B15C8AFB8007D377B /* SSLRecordInternal.h in Headers */,
+                               0C1C92F315C8AC81007D377B /* cipherSpecs.h in Headers */,
+                               0C1C92F515C8AC81007D377B /* cryptType.h in Headers */,
+                               0C1C930815C8AC81007D377B /* CipherSuite.h in Headers */,
+                               0C1C92F415C8AC81007D377B /* sslTypes.h in Headers */,
+                               0C1C930015C8AC81007D377B /* sslMemory.h in Headers */,
+                               0C1C930515C8AC81007D377B /* symCipher.h in Headers */,
+                               0C1C930615C8AC81007D377B /* tls_hmac.h in Headers */,
+                               0C1C931015C8AC81007D377B /* tls_digest.h in Headers */,
+                               0C1C931115C8AC81007D377B /* tls_hashhmac.h in Headers */,
+                               0C1C931215C8AC81007D377B /* tls_record.h in Headers */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               0CCA415715C89E8B002AEC4C /* Headers */ = {
+                       isa = PBXHeadersBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               0CCA416F15C89EA3002AEC4C /* ClientCert_ecc_ecc.h in Headers */,
+                               0CCA417015C89EA3002AEC4C /* ClientCert_ecc_rsa.h in Headers */,
+                               0CCA417115C89EA3002AEC4C /* ClientCert_rsa_ecc.h in Headers */,
+                               0CCA417215C89EA3002AEC4C /* ClientCert_rsa_rsa.h in Headers */,
+                               0CCA417315C89EA3002AEC4C /* ClientKey_ecc.h in Headers */,
+                               0CCA417415C89EA3002AEC4C /* ClientKey_rsa.h in Headers */,
+                               0CCA417515C89EA3002AEC4C /* SECG_ecc-secp256r1-client_cert.h in Headers */,
+                               0CCA417615C89EA3002AEC4C /* SECG_ecc-secp256r1-client_key.h in Headers */,
+                               0CCA417715C89EA3002AEC4C /* SECG_ecc_rsa-secp256r1-client_cert.h in Headers */,
+                               0CCA417815C89EA3002AEC4C /* SECG_ecc_rsa-secp256r1-client_key.h in Headers */,
+                               0C6C634515D1BE3900BC68CD /* ssl-utils.h in Headers */,
+                               0C6C641F15D5840700BC68CD /* cert-1.h in Headers */,
+                               0C6C642015D5840700BC68CD /* identity-1.h in Headers */,
+                               0C6C642115D5840700BC68CD /* privkey-1.h in Headers */,
+                               0C0E046A162CA288009F7C71 /* ssl_regressions.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
 /* End PBXHeadersBuildPhase section */
 
 /* Begin PBXNativeTarget section */
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
 /* End PBXHeadersBuildPhase section */
 
 /* Begin PBXNativeTarget section */
+               0C1C92EF15C8AC81007D377B /* libsecurity_ssl_kext */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 0C1C933715C8AC81007D377B /* Build configuration list for PBXNativeTarget "libsecurity_ssl_kext" */;
+                       buildPhases = (
+                               0C1C92F015C8AC81007D377B /* Headers */,
+                               0C1C931315C8AC81007D377B /* Sources */,
+                               0C1C933615C8AC81007D377B /* Frameworks */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = libsecurity_ssl_kext;
+                       productName = libsecurity_ssl;
+                       productReference = 0C1C933A15C8AC81007D377B /* libsecurity_ssl_kext.a */;
+                       productType = "com.apple.product-type.library.static";
+               };
+               0CCA415815C89E8B002AEC4C /* libsecurity_ssl_regressions */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 0CCA415A15C89E8B002AEC4C /* Build configuration list for PBXNativeTarget "libsecurity_ssl_regressions" */;
+                       buildPhases = (
+                               0CCA415515C89E8B002AEC4C /* Sources */,
+                               0CCA415615C89E8B002AEC4C /* Frameworks */,
+                               0CCA415715C89E8B002AEC4C /* Headers */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = libsecurity_ssl_regressions;
+                       productName = libsecurity_ssl_regressions;
+                       productReference = 0CCA415915C89E8B002AEC4C /* libsecurity_ssl_regressions.a */;
+                       productType = "com.apple.product-type.library.static";
+               };
+               0CCA42C815C8A387002AEC4C /* dtlsEchoClient */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 0CCA42D015C8A387002AEC4C /* Build configuration list for PBXNativeTarget "dtlsEchoClient" */;
+                       buildPhases = (
+                               0CCA42C515C8A387002AEC4C /* Sources */,
+                               0CCA42C615C8A387002AEC4C /* Frameworks */,
+                               0CCA42C715C8A387002AEC4C /* CopyFiles */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = dtlsEchoClient;
+                       productName = dtlsEchoClient;
+                       productReference = 0CCA42C915C8A387002AEC4C /* dtlsEchoClient */;
+                       productType = "com.apple.product-type.tool";
+               };
+               0CCA42D615C8A395002AEC4C /* dtlsEchoServer */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 0CCA42DE15C8A395002AEC4C /* Build configuration list for PBXNativeTarget "dtlsEchoServer" */;
+                       buildPhases = (
+                               0CCA42D315C8A395002AEC4C /* Sources */,
+                               0CCA42D415C8A395002AEC4C /* Frameworks */,
+                               0CCA42D515C8A395002AEC4C /* CopyFiles */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = dtlsEchoServer;
+                       productName = dtlsEchoServer;
+                       productReference = 0CCA42D715C8A395002AEC4C /* dtlsEchoServer */;
+                       productType = "com.apple.product-type.tool";
+               };
                4CA1FEBD052A3C8100F22E42 /* libsecurity_ssl */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = C27AD4000987FCDF001272E0 /* Build configuration list for PBXNativeTarget "libsecurity_ssl" */;
                        buildPhases = (
                4CA1FEBD052A3C8100F22E42 /* libsecurity_ssl */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = C27AD4000987FCDF001272E0 /* Build configuration list for PBXNativeTarget "libsecurity_ssl" */;
                        buildPhases = (
-                               4CA1FEB9052A3C8100F22E42 /* Headers */,
                                4CA1FEBA052A3C8100F22E42 /* Sources */,
                                4CA1FEBB052A3C8100F22E42 /* Frameworks */,
                        );
                                4CA1FEBA052A3C8100F22E42 /* Sources */,
                                4CA1FEBB052A3C8100F22E42 /* Frameworks */,
                        );
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0440;
+                               LastUpgradeCheck = 0500;
                        };
                        buildConfigurationList = C27AD4040987FCDF001272E0 /* Build configuration list for PBXProject "libsecurity_ssl" */;
                        compatibilityVersion = "Xcode 3.2";
                        };
                        buildConfigurationList = C27AD4040987FCDF001272E0 /* Build configuration list for PBXProject "libsecurity_ssl" */;
                        compatibilityVersion = "Xcode 3.2";
                        projectRoot = "";
                        targets = (
                                4CA1FEBD052A3C8100F22E42 /* libsecurity_ssl */,
                        projectRoot = "";
                        targets = (
                                4CA1FEBD052A3C8100F22E42 /* libsecurity_ssl */,
+                               0C1C92EF15C8AC81007D377B /* libsecurity_ssl_kext */,
+                               0CCA415815C89E8B002AEC4C /* libsecurity_ssl_regressions */,
+                               0CCA42C815C8A387002AEC4C /* dtlsEchoClient */,
+                               0CCA42D615C8A395002AEC4C /* dtlsEchoServer */,
+                               0C6C633A15D1BD4800BC68CD /* dtlsEcho */,
                        );
                };
 /* End PBXProject section */
 
 /* Begin PBXSourcesBuildPhase section */
                        );
                };
 /* End PBXProject section */
 
 /* Begin PBXSourcesBuildPhase section */
+               0C1C931315C8AC81007D377B /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               0C1C931615C8AC81007D377B /* cipherSpecs.c in Sources */,
+                               0C1C932415C8AC81007D377B /* sslMemory.c in Sources */,
+                               0C1C932515C8AC81007D377B /* sslNullCipher.c in Sources */,
+                               0C1C932915C8AC81007D377B /* sslUtils.c in Sources */,
+                               0C1C932A15C8AC81007D377B /* symCipher.c in Sources */,
+                               0C1C932E15C8AC81007D377B /* ssl3RecordCallouts.c in Sources */,
+                               0C1C933015C8AC81007D377B /* sslRand.c in Sources */,
+                               0C1C933115C8AC81007D377B /* SSLRecordInternal.c in Sources */,
+                               0C1C933215C8AC81007D377B /* symCipherParams.c in Sources */,
+                               0C1C933315C8AC81007D377B /* tls_digest.c in Sources */,
+                               0C1C932C15C8AC81007D377B /* tls_hmac.c in Sources */,
+                               0C1C933415C8AC81007D377B /* tls_hashhmac.c in Sources */,
+                               0C1C933515C8AC81007D377B /* tls1RecordCallouts.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               0CCA415515C89E8B002AEC4C /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               0CCA417915C89EA3002AEC4C /* ssl-39-echo.c in Sources */,
+                               0CCA417A15C89EA3002AEC4C /* ssl-40-clientauth.c in Sources */,
+                               0CCA417B15C89EA3002AEC4C /* ssl-41-clientauth.c in Sources */,
+                               0CCA417C15C89EA3002AEC4C /* ssl-42-ciphers.c in Sources */,
+                               0CCA417D15C89EA3002AEC4C /* ssl-43-ciphers.c in Sources */,
+                               AAB589F216CACE540071FE64 /* ssl-44-crashes.c in Sources */,
+                               0CCA417E15C89EA3002AEC4C /* ssl-45-tls12.c in Sources */,
+                               0CCF28B8166D5F5000AFA37C /* ssl-47-falsestart.c in Sources */,
+                               0C6C634315D1BDCF00BC68CD /* ssl-utils.c in Sources */,
+                               0C0E0467162C9DF0009F7C71 /* ssl-46-SSLGetSupportedCiphers.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               0CCA42C515C8A387002AEC4C /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               0C6C642315D5938E00BC68CD /* ssl-utils.c in Sources */,
+                               0CCA42E115C8A3D9002AEC4C /* dtlsEchoClient.c in Sources */,
+                               0CCA42EC15C8A71A002AEC4C /* sslAppUtils.cpp in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               0CCA42D315C8A395002AEC4C /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               0C6C642415D5939A00BC68CD /* ssl-utils.c in Sources */,
+                               0CCA42E215C8A3DE002AEC4C /* dtlsEchoServer.c in Sources */,
+                               0CCA42ED15C8A71A002AEC4C /* sslAppUtils.cpp in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                4CA1FEBA052A3C8100F22E42 /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                4CA1FEBA052A3C8100F22E42 /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                                4CAFF4390534D89900303760 /* appleSession.c in Sources */,
                                4CAFF43B0534D89900303760 /* cipherSpecs.c in Sources */,
                                4CAFF43F0534D89900303760 /* ModuleAttacher.c in Sources */,
                                4CAFF4390534D89900303760 /* appleSession.c in Sources */,
                                4CAFF43B0534D89900303760 /* cipherSpecs.c in Sources */,
                                4CAFF43F0534D89900303760 /* ModuleAttacher.c in Sources */,
-                               4CAFF4410534D89900303760 /* securetransport++.cpp in Sources */,
                                4CAFF44B0534D89900303760 /* ssl3Callouts.c in Sources */,
                                4CAFF44C0534D89900303760 /* sslAlertMessage.c in Sources */,
                                4CAFF44E0534D89900303760 /* sslBER.c in Sources */,
                                4CAFF44B0534D89900303760 /* ssl3Callouts.c in Sources */,
                                4CAFF44C0534D89900303760 /* sslAlertMessage.c in Sources */,
                                4CAFF44E0534D89900303760 /* sslBER.c in Sources */,
                                4CAFF46D0534D89900303760 /* tls1Callouts.c in Sources */,
                                4CAFF46E0534D89900303760 /* tls_hmac.c in Sources */,
                                BEB382AC14EC84A0003C055B /* sslCrypto.c in Sources */,
                                4CAFF46D0534D89900303760 /* tls1Callouts.c in Sources */,
                                4CAFF46E0534D89900303760 /* tls_hmac.c in Sources */,
                                BEB382AC14EC84A0003C055B /* sslCrypto.c in Sources */,
+                               0CCA414515C75863002AEC4C /* ssl3RecordCallouts.c in Sources */,
+                               0CCA414615C75863002AEC4C /* sslCipherSpecs.c in Sources */,
+                               0CCA414815C75863002AEC4C /* sslRand.c in Sources */,
+                               0CCA414A15C75863002AEC4C /* SSLRecordInternal.c in Sources */,
+                               0CCA414D15C75863002AEC4C /* symCipherParams.c in Sources */,
+                               0CCA414E15C75863002AEC4C /* tls_digest.c in Sources */,
+                               0CCA415015C75863002AEC4C /* tls_hashhmac.c in Sources */,
+                               0CCA415315C75863002AEC4C /* tls1RecordCallouts.c in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
 /* End PBXSourcesBuildPhase section */
 
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
 /* End PBXSourcesBuildPhase section */
 
+/* Begin PBXTargetDependency section */
+               0C6C633F15D1BD4D00BC68CD /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 0CCA42C815C8A387002AEC4C /* dtlsEchoClient */;
+                       targetProxy = 0C6C633E15D1BD4D00BC68CD /* PBXContainerItemProxy */;
+               };
+               0C6C634115D1BD4E00BC68CD /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 0CCA42D615C8A395002AEC4C /* dtlsEchoServer */;
+                       targetProxy = 0C6C634015D1BD4E00BC68CD /* PBXContainerItemProxy */;
+               };
+/* End PBXTargetDependency section */
+
 /* Begin XCBuildConfiguration section */
 /* Begin XCBuildConfiguration section */
+               0C1C933815C8AC81007D377B /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 0C1C92ED15C8AC52007D377B /* kext.xcconfig */;
+                       buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                       };
+                       name = Debug;
+               };
+               0C1C933915C8AC81007D377B /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 0C1C92ED15C8AC52007D377B /* kext.xcconfig */;
+                       buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                       };
+                       name = Release;
+               };
+               0C6C633C15D1BD4800BC68CD /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Debug;
+               };
+               0C6C633D15D1BD4800BC68CD /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Release;
+               };
+               0CCA415B15C89E8B002AEC4C /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = BE6A959E14E3700A00C158E0 /* lib.xcconfig */;
+                       buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                       };
+                       name = Debug;
+               };
+               0CCA415C15C89E8B002AEC4C /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = BE6A959E14E3700A00C158E0 /* lib.xcconfig */;
+                       buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                       };
+                       name = Release;
+               };
+               0CCA42D115C8A387002AEC4C /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 0C85738D15DAB34C0038DFD7 /* tests.xcconfig */;
+                       buildSettings = {
+                       };
+                       name = Debug;
+               };
+               0CCA42D215C8A387002AEC4C /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 0C85738D15DAB34C0038DFD7 /* tests.xcconfig */;
+                       buildSettings = {
+                       };
+                       name = Release;
+               };
+               0CCA42DF15C8A395002AEC4C /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 0C85738D15DAB34C0038DFD7 /* tests.xcconfig */;
+                       buildSettings = {
+                       };
+                       name = Debug;
+               };
+               0CCA42E015C8A395002AEC4C /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 0C85738D15DAB34C0038DFD7 /* tests.xcconfig */;
+                       buildSettings = {
+                       };
+                       name = Release;
+               };
                C27AD4010987FCDF001272E0 /* Debug */ = {
                        isa = XCBuildConfiguration;
                C27AD4010987FCDF001272E0 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = BE6A959D14E3700A00C158E0 /* debug.xcconfig */;
+                       baseConfigurationReference = BE6A959E14E3700A00C158E0 /* lib.xcconfig */;
                        buildSettings = {
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                        };
                        name = Debug;
                };
                C27AD4030987FCDF001272E0 /* Release */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Debug;
                };
                C27AD4030987FCDF001272E0 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = BE6A959F14E3700A00C158E0 /* release.xcconfig */;
+                       baseConfigurationReference = BE6A959E14E3700A00C158E0 /* lib.xcconfig */;
                        buildSettings = {
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                        };
                        name = Release;
                };
                C27AD4050987FCDF001272E0 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Release;
                };
                C27AD4050987FCDF001272E0 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = BE6A959E14E3700A00C158E0 /* lib.xcconfig */;
+                       baseConfigurationReference = BE6A959D14E3700A00C158E0 /* debug.xcconfig */;
                        buildSettings = {
                        };
                        name = Debug;
                };
                C27AD4070987FCDF001272E0 /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                        };
                        name = Debug;
                };
                C27AD4070987FCDF001272E0 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = BE6A959E14E3700A00C158E0 /* lib.xcconfig */;
+                       baseConfigurationReference = BE6A959F14E3700A00C158E0 /* release.xcconfig */;
                        buildSettings = {
                        };
                        name = Release;
                        buildSettings = {
                        };
                        name = Release;
 /* End XCBuildConfiguration section */
 
 /* Begin XCConfigurationList section */
 /* End XCBuildConfiguration section */
 
 /* Begin XCConfigurationList section */
+               0C1C933715C8AC81007D377B /* Build configuration list for PBXNativeTarget "libsecurity_ssl_kext" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               0C1C933815C8AC81007D377B /* Debug */,
+                               0C1C933915C8AC81007D377B /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               0C6C633B15D1BD4800BC68CD /* Build configuration list for PBXAggregateTarget "dtlsEcho" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               0C6C633C15D1BD4800BC68CD /* Debug */,
+                               0C6C633D15D1BD4800BC68CD /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               0CCA415A15C89E8B002AEC4C /* Build configuration list for PBXNativeTarget "libsecurity_ssl_regressions" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               0CCA415B15C89E8B002AEC4C /* Debug */,
+                               0CCA415C15C89E8B002AEC4C /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               0CCA42D015C8A387002AEC4C /* Build configuration list for PBXNativeTarget "dtlsEchoClient" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               0CCA42D115C8A387002AEC4C /* Debug */,
+                               0CCA42D215C8A387002AEC4C /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               0CCA42DE15C8A395002AEC4C /* Build configuration list for PBXNativeTarget "dtlsEchoServer" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               0CCA42DF15C8A395002AEC4C /* Debug */,
+                               0CCA42E015C8A395002AEC4C /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
                C27AD4000987FCDF001272E0 /* Build configuration list for PBXNativeTarget "libsecurity_ssl" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                C27AD4000987FCDF001272E0 /* Build configuration list for PBXNativeTarget "libsecurity_ssl" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
diff --git a/libsecurity_ssl/regressions/ClientCert_ecc_ecc.h b/libsecurity_ssl/regressions/ClientCert_ecc_ecc.h
new file mode 100644 (file)
index 0000000..c824e24
--- /dev/null
@@ -0,0 +1,29 @@
+unsigned char ClientCert_ecc_ecc_der[] = {
+  0x30, 0x82, 0x01, 0x34, 0x30, 0x81, 0xdd, 0x02, 0x02, 0x03, 0xec, 0x30,
+  0x09, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01, 0x30, 0x25,
+  0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1a, 0x53,
+  0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x20,
+  0x43, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x45, 0x43, 0x43,
+  0x29, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x31, 0x31, 0x31, 0x31, 0x34, 0x31,
+  0x39, 0x33, 0x31, 0x33, 0x39, 0x5a, 0x17, 0x0d, 0x31, 0x31, 0x31, 0x32,
+  0x31, 0x34, 0x31, 0x39, 0x33, 0x31, 0x33, 0x39, 0x5a, 0x30, 0x2a, 0x31,
+  0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1f, 0x53, 0x65,
+  0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x73, 0x20,
+  0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20,
+  0x28, 0x45, 0x43, 0x43, 0x29, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a,
+  0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
+  0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x11, 0x1d, 0x78, 0x90,
+  0x3b, 0x95, 0xf0, 0xdb, 0x47, 0x97, 0x5a, 0xf8, 0x76, 0x49, 0xc8, 0xd2,
+  0xc7, 0xb5, 0xd2, 0x32, 0xde, 0xe7, 0xe6, 0xd8, 0x4d, 0xe7, 0x2f, 0x9d,
+  0xb0, 0x6f, 0x9e, 0xcf, 0x21, 0x13, 0x40, 0xe6, 0x60, 0xe1, 0x3e, 0x4f,
+  0x04, 0x5e, 0x7f, 0xa9, 0xbf, 0x2b, 0x23, 0xc8, 0x85, 0xe2, 0x9b, 0xff,
+  0x28, 0x18, 0x40, 0xf6, 0x1e, 0x7c, 0xe5, 0xde, 0x8b, 0xa6, 0xdc, 0x74,
+  0x30, 0x09, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01, 0x03,
+  0x47, 0x00, 0x30, 0x44, 0x02, 0x20, 0x05, 0x32, 0xb1, 0xb7, 0x90, 0x3f,
+  0xe1, 0x45, 0x34, 0x5f, 0xa3, 0x5e, 0x3c, 0xfa, 0x93, 0xd0, 0x3a, 0x84,
+  0x92, 0x30, 0xbe, 0x34, 0x53, 0x29, 0x46, 0x90, 0x1d, 0xf9, 0x69, 0x6f,
+  0xe5, 0xa8, 0x02, 0x20, 0x52, 0x1e, 0xd3, 0x20, 0x0f, 0x80, 0x63, 0xce,
+  0x23, 0x58, 0x76, 0xf0, 0x27, 0xd9, 0x6a, 0x65, 0x9a, 0x86, 0x90, 0x86,
+  0x0c, 0xf6, 0x46, 0x8c, 0x6d, 0x5e, 0x44, 0xd3, 0x58, 0xec, 0x42, 0x4f
+};
+unsigned int ClientCert_ecc_ecc_der_len = 312;
diff --git a/libsecurity_ssl/regressions/ClientCert_ecc_rsa.h b/libsecurity_ssl/regressions/ClientCert_ecc_rsa.h
new file mode 100644 (file)
index 0000000..206ed81
--- /dev/null
@@ -0,0 +1,35 @@
+unsigned char ClientCert_ecc_rsa_der[] = {
+  0x30, 0x82, 0x01, 0x77, 0x30, 0x81, 0xe1, 0x02, 0x02, 0x03, 0xeb, 0x30,
+  0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
+  0x05, 0x00, 0x30, 0x25, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04,
+  0x03, 0x0c, 0x1a, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54,
+  0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20,
+  0x28, 0x52, 0x53, 0x41, 0x29, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x31, 0x31,
+  0x31, 0x31, 0x34, 0x31, 0x39, 0x33, 0x31, 0x33, 0x39, 0x5a, 0x17, 0x0d,
+  0x31, 0x31, 0x31, 0x32, 0x31, 0x34, 0x31, 0x39, 0x33, 0x31, 0x33, 0x39,
+  0x5a, 0x30, 0x2a, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x03,
+  0x0c, 0x1f, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65,
+  0x73, 0x74, 0x73, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x43,
+  0x65, 0x72, 0x74, 0x20, 0x28, 0x45, 0x43, 0x43, 0x29, 0x30, 0x59, 0x30,
+  0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08,
+  0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04,
+  0x11, 0x1d, 0x78, 0x90, 0x3b, 0x95, 0xf0, 0xdb, 0x47, 0x97, 0x5a, 0xf8,
+  0x76, 0x49, 0xc8, 0xd2, 0xc7, 0xb5, 0xd2, 0x32, 0xde, 0xe7, 0xe6, 0xd8,
+  0x4d, 0xe7, 0x2f, 0x9d, 0xb0, 0x6f, 0x9e, 0xcf, 0x21, 0x13, 0x40, 0xe6,
+  0x60, 0xe1, 0x3e, 0x4f, 0x04, 0x5e, 0x7f, 0xa9, 0xbf, 0x2b, 0x23, 0xc8,
+  0x85, 0xe2, 0x9b, 0xff, 0x28, 0x18, 0x40, 0xf6, 0x1e, 0x7c, 0xe5, 0xde,
+  0x8b, 0xa6, 0xdc, 0x74, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x2a,
+  0xd8, 0x04, 0x0f, 0xab, 0x76, 0x7e, 0x28, 0x2f, 0x53, 0xfe, 0x2a, 0xc1,
+  0x21, 0x63, 0x0c, 0xca, 0x6a, 0xc1, 0xed, 0x7d, 0x33, 0xa8, 0xe1, 0xf0,
+  0x42, 0x55, 0x5d, 0x07, 0x34, 0xf1, 0xd8, 0x7b, 0xfc, 0xcb, 0xe6, 0xf2,
+  0xf2, 0x4b, 0x85, 0x2a, 0xb1, 0x1f, 0xba, 0x54, 0xd5, 0xf0, 0x8c, 0x13,
+  0x41, 0xb1, 0xb1, 0xba, 0xab, 0x19, 0xa6, 0xad, 0xfd, 0x10, 0xa5, 0x24,
+  0x45, 0x46, 0x02, 0x58, 0x8f, 0x7b, 0xcc, 0xe0, 0xc7, 0xd2, 0xf4, 0x7e,
+  0x5c, 0x14, 0x9a, 0x4c, 0xa9, 0xf2, 0xcc, 0x73, 0x5a, 0x8a, 0x3a, 0xb0,
+  0x9c, 0x92, 0x65, 0xb5, 0xe7, 0xc6, 0x8e, 0x14, 0xfd, 0x73, 0x61, 0x81,
+  0xa2, 0x48, 0x40, 0x25, 0xf7, 0xad, 0xf7, 0x32, 0x31, 0x15, 0xe9, 0xc5,
+  0xbe, 0xd7, 0xe1, 0x51, 0xe6, 0xfd, 0xe2, 0x12, 0xa6, 0x3d, 0xbc, 0x6b,
+  0xb2, 0xbb, 0x9f, 0xfe, 0xbc, 0x8d, 0xbf
+};
+unsigned int ClientCert_ecc_rsa_der_len = 379;
diff --git a/libsecurity_ssl/regressions/ClientCert_rsa_ecc.h b/libsecurity_ssl/regressions/ClientCert_rsa_ecc.h
new file mode 100644 (file)
index 0000000..ba5afe0
--- /dev/null
@@ -0,0 +1,36 @@
+unsigned char ClientCert_rsa_ecc_der[] = {
+  0x30, 0x82, 0x01, 0x7e, 0x30, 0x82, 0x01, 0x24, 0x02, 0x02, 0x03, 0xea,
+  0x30, 0x09, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01, 0x30,
+  0x25, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1a,
+  0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74,
+  0x20, 0x43, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x45, 0x43,
+  0x43, 0x29, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x31, 0x31, 0x31, 0x31, 0x34,
+  0x31, 0x39, 0x33, 0x31, 0x33, 0x39, 0x5a, 0x17, 0x0d, 0x31, 0x31, 0x31,
+  0x32, 0x31, 0x34, 0x31, 0x39, 0x33, 0x31, 0x33, 0x39, 0x5a, 0x30, 0x2a,
+  0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1f, 0x53,
+  0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x73,
+  0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74,
+  0x20, 0x28, 0x52, 0x53, 0x41, 0x29, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06,
+  0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
+  0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xd4,
+  0x2a, 0xa0, 0xc8, 0xdf, 0xb3, 0xa2, 0x04, 0xe4, 0x9c, 0x69, 0x23, 0x59,
+  0x45, 0x9e, 0xbd, 0xb6, 0xd7, 0xb1, 0xe5, 0x4d, 0xe0, 0xff, 0xf1, 0xbb,
+  0x75, 0x14, 0x96, 0x24, 0xa5, 0x57, 0xae, 0xe9, 0xa5, 0x49, 0x6f, 0xd1,
+  0x21, 0x2b, 0xd2, 0x50, 0x76, 0x03, 0xa6, 0x9e, 0x9c, 0x32, 0xb3, 0x94,
+  0x38, 0x1d, 0xe0, 0xdd, 0xa1, 0x67, 0x94, 0x51, 0x26, 0x2d, 0xfa, 0xab,
+  0x8f, 0x89, 0x59, 0xa0, 0x80, 0xe0, 0xd1, 0xf7, 0xed, 0x67, 0x4c, 0xaf,
+  0xaf, 0xb4, 0x66, 0x13, 0xee, 0x7b, 0xb7, 0x7c, 0x87, 0xf6, 0x03, 0x57,
+  0xf2, 0x29, 0x56, 0x88, 0x62, 0x01, 0xed, 0x9a, 0x15, 0x12, 0x48, 0xae,
+  0x81, 0xf4, 0xf3, 0x05, 0x16, 0xc4, 0x88, 0x63, 0xde, 0xa2, 0x1c, 0x1a,
+  0xb7, 0x1e, 0xd8, 0xf2, 0x01, 0x76, 0x73, 0xe2, 0xdb, 0x1d, 0xd6, 0x39,
+  0x84, 0xee, 0xb2, 0x03, 0xe7, 0xf0, 0xc3, 0x02, 0x03, 0x01, 0x00, 0x01,
+  0x30, 0x09, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01, 0x03,
+  0x49, 0x00, 0x30, 0x46, 0x02, 0x21, 0x00, 0xea, 0x42, 0xa4, 0x68, 0xc9,
+  0xb3, 0x8f, 0xe2, 0xcc, 0xbd, 0x62, 0x4e, 0x1b, 0xd1, 0xea, 0x1e, 0xb5,
+  0x5b, 0x3a, 0x68, 0xa6, 0xe7, 0xca, 0x76, 0xfe, 0x8b, 0x23, 0x25, 0x64,
+  0xa0, 0x5b, 0x24, 0x02, 0x21, 0x00, 0xfb, 0xf7, 0xd3, 0x22, 0x63, 0xd3,
+  0x98, 0x08, 0xff, 0x3e, 0x21, 0xd9, 0xac, 0x62, 0xb6, 0x7f, 0x10, 0xa6,
+  0x7c, 0x6a, 0x1f, 0x75, 0xfe, 0x03, 0x9c, 0x5d, 0xea, 0x6e, 0x25, 0x05,
+  0x18, 0x68
+};
+unsigned int ClientCert_rsa_ecc_der_len = 386;
diff --git a/libsecurity_ssl/regressions/ClientCert_rsa_rsa.h b/libsecurity_ssl/regressions/ClientCert_rsa_rsa.h
new file mode 100644 (file)
index 0000000..4617c45
--- /dev/null
@@ -0,0 +1,41 @@
+unsigned char ClientCert_rsa_rsa_der[] = {
+  0x30, 0x82, 0x01, 0xbf, 0x30, 0x82, 0x01, 0x28, 0x02, 0x02, 0x03, 0xe9,
+  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+  0x05, 0x05, 0x00, 0x30, 0x25, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55,
+  0x04, 0x03, 0x0c, 0x1a, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79,
+  0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74,
+  0x20, 0x28, 0x52, 0x53, 0x41, 0x29, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x31,
+  0x31, 0x31, 0x31, 0x34, 0x31, 0x39, 0x33, 0x31, 0x33, 0x39, 0x5a, 0x17,
+  0x0d, 0x31, 0x31, 0x31, 0x32, 0x31, 0x34, 0x31, 0x39, 0x33, 0x31, 0x33,
+  0x39, 0x5a, 0x30, 0x2a, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04,
+  0x03, 0x0c, 0x1f, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54,
+  0x65, 0x73, 0x74, 0x73, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20,
+  0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x52, 0x53, 0x41, 0x29, 0x30, 0x81,
+  0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02,
+  0x81, 0x81, 0x00, 0xd4, 0x2a, 0xa0, 0xc8, 0xdf, 0xb3, 0xa2, 0x04, 0xe4,
+  0x9c, 0x69, 0x23, 0x59, 0x45, 0x9e, 0xbd, 0xb6, 0xd7, 0xb1, 0xe5, 0x4d,
+  0xe0, 0xff, 0xf1, 0xbb, 0x75, 0x14, 0x96, 0x24, 0xa5, 0x57, 0xae, 0xe9,
+  0xa5, 0x49, 0x6f, 0xd1, 0x21, 0x2b, 0xd2, 0x50, 0x76, 0x03, 0xa6, 0x9e,
+  0x9c, 0x32, 0xb3, 0x94, 0x38, 0x1d, 0xe0, 0xdd, 0xa1, 0x67, 0x94, 0x51,
+  0x26, 0x2d, 0xfa, 0xab, 0x8f, 0x89, 0x59, 0xa0, 0x80, 0xe0, 0xd1, 0xf7,
+  0xed, 0x67, 0x4c, 0xaf, 0xaf, 0xb4, 0x66, 0x13, 0xee, 0x7b, 0xb7, 0x7c,
+  0x87, 0xf6, 0x03, 0x57, 0xf2, 0x29, 0x56, 0x88, 0x62, 0x01, 0xed, 0x9a,
+  0x15, 0x12, 0x48, 0xae, 0x81, 0xf4, 0xf3, 0x05, 0x16, 0xc4, 0x88, 0x63,
+  0xde, 0xa2, 0x1c, 0x1a, 0xb7, 0x1e, 0xd8, 0xf2, 0x01, 0x76, 0x73, 0xe2,
+  0xdb, 0x1d, 0xd6, 0x39, 0x84, 0xee, 0xb2, 0x03, 0xe7, 0xf0, 0xc3, 0x02,
+  0x03, 0x01, 0x00, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x9e,
+  0x50, 0x77, 0xeb, 0x88, 0x89, 0xc7, 0xc1, 0x44, 0x6c, 0xc4, 0x1c, 0x9a,
+  0xbf, 0x0e, 0x8f, 0x63, 0x8d, 0x53, 0x5b, 0xea, 0x35, 0x7a, 0x06, 0xbd,
+  0x09, 0xe2, 0x3f, 0x19, 0x9a, 0x24, 0x3c, 0x2b, 0xf1, 0x7a, 0x14, 0x4d,
+  0x24, 0xc5, 0xf3, 0x6e, 0x04, 0xa3, 0x34, 0x83, 0x73, 0x6e, 0x3a, 0xc9,
+  0xd6, 0x51, 0x30, 0x5a, 0x14, 0x5b, 0xaa, 0x69, 0x23, 0x4f, 0xb5, 0x90,
+  0xdb, 0x1b, 0x37, 0xd0, 0xab, 0x99, 0xe2, 0x17, 0x08, 0x8d, 0x1e, 0xfb,
+  0x2d, 0x18, 0x3d, 0xc4, 0x08, 0xdc, 0x0f, 0xd4, 0x6e, 0x8e, 0xfb, 0xb6,
+  0x6f, 0x65, 0x71, 0x97, 0x93, 0x63, 0x3a, 0x59, 0xad, 0xd4, 0x25, 0xe4,
+  0x30, 0xa8, 0xe7, 0xcf, 0x82, 0x6a, 0x11, 0xc3, 0xce, 0x05, 0x04, 0x1a,
+  0x5b, 0xea, 0x33, 0xdf, 0xce, 0x9a, 0x48, 0x84, 0xe2, 0xf9, 0x42, 0x4f,
+  0xa1, 0x48, 0x75, 0xd3, 0x86, 0xac, 0xc4
+};
+unsigned int ClientCert_rsa_rsa_der_len = 451;
diff --git a/libsecurity_ssl/regressions/ClientKey_ecc.h b/libsecurity_ssl/regressions/ClientKey_ecc.h
new file mode 100644 (file)
index 0000000..f32bdf3
--- /dev/null
@@ -0,0 +1,14 @@
+unsigned char ClientKey_ecc_der[] = {
+  0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x77, 0xdd, 0xc7, 0x4d, 0x4c,
+  0x54, 0x9a, 0xcc, 0x9a, 0xf3, 0x38, 0x1b, 0x68, 0x77, 0xd8, 0x20, 0x96,
+  0xcf, 0x83, 0x6c, 0x37, 0x33, 0x13, 0xb9, 0xf8, 0x5a, 0xc5, 0xa9, 0x6b,
+  0xcd, 0x14, 0x07, 0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
+  0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0x11, 0x1d, 0x78,
+  0x90, 0x3b, 0x95, 0xf0, 0xdb, 0x47, 0x97, 0x5a, 0xf8, 0x76, 0x49, 0xc8,
+  0xd2, 0xc7, 0xb5, 0xd2, 0x32, 0xde, 0xe7, 0xe6, 0xd8, 0x4d, 0xe7, 0x2f,
+  0x9d, 0xb0, 0x6f, 0x9e, 0xcf, 0x21, 0x13, 0x40, 0xe6, 0x60, 0xe1, 0x3e,
+  0x4f, 0x04, 0x5e, 0x7f, 0xa9, 0xbf, 0x2b, 0x23, 0xc8, 0x85, 0xe2, 0x9b,
+  0xff, 0x28, 0x18, 0x40, 0xf6, 0x1e, 0x7c, 0xe5, 0xde, 0x8b, 0xa6, 0xdc,
+  0x74
+};
+unsigned int ClientKey_ecc_der_len = 121;
diff --git a/libsecurity_ssl/regressions/ClientKey_rsa.h b/libsecurity_ssl/regressions/ClientKey_rsa.h
new file mode 100644 (file)
index 0000000..9cc1252
--- /dev/null
@@ -0,0 +1,54 @@
+unsigned char ClientKey_rsa_der[] = {
+  0x30, 0x82, 0x02, 0x5d, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xd4,
+  0x2a, 0xa0, 0xc8, 0xdf, 0xb3, 0xa2, 0x04, 0xe4, 0x9c, 0x69, 0x23, 0x59,
+  0x45, 0x9e, 0xbd, 0xb6, 0xd7, 0xb1, 0xe5, 0x4d, 0xe0, 0xff, 0xf1, 0xbb,
+  0x75, 0x14, 0x96, 0x24, 0xa5, 0x57, 0xae, 0xe9, 0xa5, 0x49, 0x6f, 0xd1,
+  0x21, 0x2b, 0xd2, 0x50, 0x76, 0x03, 0xa6, 0x9e, 0x9c, 0x32, 0xb3, 0x94,
+  0x38, 0x1d, 0xe0, 0xdd, 0xa1, 0x67, 0x94, 0x51, 0x26, 0x2d, 0xfa, 0xab,
+  0x8f, 0x89, 0x59, 0xa0, 0x80, 0xe0, 0xd1, 0xf7, 0xed, 0x67, 0x4c, 0xaf,
+  0xaf, 0xb4, 0x66, 0x13, 0xee, 0x7b, 0xb7, 0x7c, 0x87, 0xf6, 0x03, 0x57,
+  0xf2, 0x29, 0x56, 0x88, 0x62, 0x01, 0xed, 0x9a, 0x15, 0x12, 0x48, 0xae,
+  0x81, 0xf4, 0xf3, 0x05, 0x16, 0xc4, 0x88, 0x63, 0xde, 0xa2, 0x1c, 0x1a,
+  0xb7, 0x1e, 0xd8, 0xf2, 0x01, 0x76, 0x73, 0xe2, 0xdb, 0x1d, 0xd6, 0x39,
+  0x84, 0xee, 0xb2, 0x03, 0xe7, 0xf0, 0xc3, 0x02, 0x03, 0x01, 0x00, 0x01,
+  0x02, 0x81, 0x80, 0x38, 0xe6, 0x55, 0xc8, 0x89, 0x75, 0xfb, 0x75, 0xa4,
+  0x79, 0xee, 0x18, 0x74, 0xd0, 0x9f, 0x09, 0xf2, 0x07, 0x56, 0xc6, 0x50,
+  0x64, 0x8f, 0x3f, 0x9d, 0x2e, 0x81, 0x1e, 0xe3, 0x25, 0x14, 0xa6, 0xec,
+  0x32, 0x4f, 0xc7, 0x95, 0x26, 0x78, 0x42, 0x27, 0x21, 0xff, 0x48, 0xa8,
+  0x30, 0xeb, 0xc8, 0x0d, 0x70, 0x1f, 0x53, 0x37, 0x1d, 0x1a, 0x52, 0x44,
+  0x91, 0x20, 0xb3, 0xa1, 0x5f, 0x15, 0x4e, 0x5f, 0x23, 0xcd, 0x4a, 0xd5,
+  0xf7, 0xa6, 0xd9, 0x0d, 0x05, 0xa1, 0xcc, 0x5b, 0x13, 0x1f, 0x8e, 0xeb,
+  0x87, 0x13, 0xbe, 0x74, 0x96, 0x1d, 0x0a, 0xd7, 0x68, 0xe5, 0x1e, 0xd6,
+  0x97, 0xbc, 0x9f, 0x52, 0x4f, 0xa2, 0x30, 0x50, 0x36, 0x27, 0x89, 0x09,
+  0x42, 0x5a, 0x07, 0x43, 0x27, 0x8a, 0x99, 0xe9, 0xb8, 0x7b, 0xe6, 0x81,
+  0xfa, 0xfb, 0xf5, 0x14, 0xe7, 0x92, 0x81, 0x00, 0xa1, 0x72, 0x01, 0x02,
+  0x41, 0x00, 0xe9, 0x5b, 0x6d, 0x62, 0x0b, 0x30, 0x61, 0x7b, 0x6c, 0xa7,
+  0x5a, 0x05, 0x96, 0x08, 0x91, 0x87, 0x05, 0x7e, 0xe7, 0x97, 0xe8, 0xaf,
+  0xb2, 0x77, 0xe1, 0xef, 0xa1, 0x34, 0x5d, 0x13, 0x5f, 0x72, 0x9f, 0x35,
+  0x3f, 0x44, 0xdd, 0x04, 0x43, 0x46, 0xbb, 0x9b, 0xf8, 0xf7, 0xd1, 0x8a,
+  0x9a, 0x97, 0x1c, 0x4f, 0xc2, 0x37, 0x28, 0xf3, 0x19, 0x9b, 0x59, 0x30,
+  0x11, 0x42, 0x0e, 0x0c, 0x3c, 0xa1, 0x02, 0x41, 0x00, 0xe8, 0xc0, 0xd3,
+  0xd2, 0x38, 0xe8, 0x6a, 0x5d, 0xbb, 0x4d, 0x95, 0xa8, 0x6e, 0x86, 0x53,
+  0xf6, 0x46, 0x79, 0x82, 0xdc, 0x92, 0xbb, 0x81, 0xec, 0xea, 0xe8, 0x59,
+  0x62, 0xf5, 0x22, 0x0b, 0x86, 0x06, 0x39, 0xe2, 0x4f, 0x27, 0xdc, 0x8f,
+  0x04, 0x96, 0x7f, 0xe7, 0x57, 0x5d, 0x1d, 0xde, 0x13, 0x29, 0xac, 0x07,
+  0x72, 0xf0, 0xa6, 0x71, 0xc2, 0x9c, 0xcc, 0x13, 0x7e, 0xd4, 0x61, 0x6e,
+  0xe3, 0x02, 0x41, 0x00, 0xbf, 0x8d, 0x11, 0x08, 0xbd, 0xee, 0x84, 0xd6,
+  0x6f, 0xa6, 0x1f, 0xbb, 0x1e, 0x21, 0x02, 0x74, 0x37, 0x0a, 0xa8, 0xc8,
+  0x85, 0x74, 0x53, 0xa7, 0x1c, 0x8b, 0x3b, 0x64, 0x64, 0x52, 0x96, 0xb2,
+  0xdc, 0x05, 0x35, 0x5e, 0x2d, 0x9e, 0x66, 0x2b, 0x15, 0xad, 0x3e, 0x7d,
+  0x0e, 0x40, 0x1c, 0x0d, 0x96, 0x6b, 0xd2, 0x1c, 0xbd, 0x3c, 0x6f, 0xf4,
+  0x99, 0x0d, 0x5f, 0xdd, 0x3c, 0xf2, 0xc6, 0x81, 0x02, 0x40, 0x1b, 0x7b,
+  0x39, 0x07, 0x67, 0x44, 0xb9, 0xda, 0x5b, 0x55, 0x2b, 0xc8, 0x79, 0x54,
+  0x4e, 0xf1, 0x93, 0x1c, 0xa1, 0xc0, 0xdd, 0x6a, 0x5a, 0x4a, 0xd8, 0xe9,
+  0x9a, 0x34, 0x3e, 0xf1, 0x48, 0x1f, 0x08, 0xf9, 0x28, 0xa9, 0x63, 0xf1,
+  0x7c, 0xc9, 0x73, 0xe3, 0xa2, 0x33, 0x04, 0x81, 0x94, 0x48, 0xfa, 0xf0,
+  0x9e, 0xe8, 0x89, 0x55, 0x7d, 0xb5, 0x16, 0xc2, 0x59, 0xc2, 0xed, 0xdc,
+  0x9b, 0x35, 0x02, 0x41, 0x00, 0xb2, 0xb9, 0x54, 0x20, 0xc0, 0x1d, 0xff,
+  0x6e, 0x9f, 0x09, 0x34, 0x4d, 0xa0, 0x75, 0x0b, 0xbd, 0xf2, 0xfb, 0xcc,
+  0x02, 0xcc, 0x07, 0x68, 0xf0, 0x5f, 0x93, 0xb9, 0x29, 0x49, 0x09, 0xba,
+  0xe5, 0x92, 0x4f, 0xdf, 0x5a, 0xa8, 0xeb, 0xd9, 0xe0, 0x64, 0x9f, 0x3d,
+  0xc5, 0xf2, 0x10, 0xe1, 0x01, 0xe4, 0x62, 0x8d, 0xd4, 0x86, 0x56, 0x2f,
+  0x36, 0x7d, 0xd0, 0xe9, 0x70, 0x80, 0xd7, 0x56, 0x6f
+};
+unsigned int ClientKey_rsa_der_len = 609;
diff --git a/libsecurity_ssl/regressions/SECG_ecc-secp256r1-client_cert.h b/libsecurity_ssl/regressions/SECG_ecc-secp256r1-client_cert.h
new file mode 100644 (file)
index 0000000..c3eead6
--- /dev/null
@@ -0,0 +1,52 @@
+unsigned char SECG_ecc_secp256r1_client_cert_der[] = {
+  0x30, 0x82, 0x02, 0x40, 0x30, 0x82, 0x01, 0xe7, 0xa0, 0x03, 0x02, 0x01,
+  0x02, 0x02, 0x02, 0x04, 0x19, 0x30, 0x09, 0x06, 0x07, 0x2a, 0x86, 0x48,
+  0xce, 0x3d, 0x04, 0x01, 0x30, 0x81, 0x9b, 0x31, 0x14, 0x30, 0x12, 0x06,
+  0x03, 0x55, 0x04, 0x0b, 0x13, 0x0b, 0x53, 0x41, 0x4d, 0x50, 0x4c, 0x45,
+  0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55,
+  0x04, 0x0a, 0x13, 0x0e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x63, 0x6f, 0x6d,
+  0x20, 0x43, 0x6f, 0x72, 0x70, 0x2e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03,
+  0x55, 0x04, 0x07, 0x13, 0x07, 0x54, 0x6f, 0x72, 0x6f, 0x6e, 0x74, 0x6f,
+  0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x04, 0x13, 0x07, 0x4f,
+  0x6e, 0x74, 0x61, 0x72, 0x69, 0x6f, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03,
+  0x55, 0x04, 0x03, 0x13, 0x30, 0x74, 0x6c, 0x73, 0x2e, 0x73, 0x65, 0x63,
+  0x67, 0x2e, 0x6f, 0x72, 0x67, 0x20, 0x45, 0x43, 0x43, 0x20, 0x73, 0x65,
+  0x63, 0x70, 0x32, 0x35, 0x36, 0x72, 0x31, 0x20, 0x43, 0x65, 0x72, 0x74,
+  0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68,
+  0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+  0x04, 0x06, 0x13, 0x02, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36,
+  0x30, 0x35, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17,
+  0x0d, 0x31, 0x35, 0x30, 0x35, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
+  0x30, 0x5a, 0x30, 0x81, 0x8b, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55,
+  0x04, 0x0b, 0x13, 0x0b, 0x53, 0x41, 0x4d, 0x50, 0x4c, 0x45, 0x20, 0x4f,
+  0x4e, 0x4c, 0x59, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a,
+  0x13, 0x0e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x63, 0x6f, 0x6d, 0x20, 0x43,
+  0x6f, 0x72, 0x70, 0x2e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04,
+  0x07, 0x13, 0x07, 0x54, 0x6f, 0x72, 0x6f, 0x6e, 0x74, 0x6f, 0x31, 0x10,
+  0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x04, 0x13, 0x07, 0x4f, 0x6e, 0x74,
+  0x61, 0x72, 0x69, 0x6f, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04,
+  0x03, 0x13, 0x2d, 0x74, 0x6c, 0x73, 0x2e, 0x73, 0x65, 0x63, 0x67, 0x2e,
+  0x6f, 0x72, 0x67, 0x20, 0x45, 0x43, 0x43, 0x20, 0x73, 0x65, 0x63, 0x70,
+  0x32, 0x35, 0x36, 0x72, 0x31, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74,
+  0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65,
+  0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
+  0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
+  0x42, 0x00, 0x04, 0x36, 0x48, 0x98, 0xf8, 0xb3, 0xd0, 0xc4, 0x2e, 0xca,
+  0x99, 0x3d, 0x14, 0xbb, 0x14, 0x24, 0xf5, 0x89, 0x82, 0x36, 0xe3, 0x34,
+  0xb2, 0xf5, 0x35, 0x07, 0xd0, 0xa8, 0xde, 0x14, 0x84, 0xd7, 0x78, 0xa4,
+  0x62, 0x01, 0x77, 0xea, 0xbd, 0xa9, 0xa3, 0x9f, 0x8b, 0x48, 0x5f, 0x3c,
+  0x7a, 0xa1, 0x96, 0x40, 0xd1, 0x2c, 0xb6, 0xdd, 0xea, 0x21, 0xf8, 0xed,
+  0x29, 0x70, 0x44, 0x80, 0x49, 0x2e, 0x77, 0xa3, 0x2a, 0x30, 0x28, 0x30,
+  0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03,
+  0x02, 0x03, 0x88, 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01,
+  0xff, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+  0x07, 0x03, 0x02, 0x30, 0x09, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d,
+  0x04, 0x01, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x20, 0x45, 0xa2, 0x99,
+  0x2c, 0xe0, 0x08, 0xb2, 0xee, 0x09, 0xcd, 0x1d, 0x51, 0x42, 0x60, 0x3f,
+  0x56, 0x4d, 0x2d, 0xa1, 0x7d, 0xab, 0xd0, 0xf5, 0x6d, 0xf7, 0xf0, 0xe2,
+  0x23, 0x33, 0xbc, 0xbd, 0xb3, 0x02, 0x21, 0x00, 0xcd, 0xfb, 0x57, 0x1c,
+  0x3a, 0x32, 0xd1, 0xbc, 0x67, 0xbb, 0x0f, 0x1d, 0x12, 0xeb, 0x63, 0x12,
+  0x1f, 0x50, 0x37, 0x67, 0x77, 0x66, 0x2b, 0xe1, 0x37, 0xd4, 0x8f, 0xdd,
+  0xe0, 0xaa, 0xe4, 0x22
+};
+unsigned int SECG_ecc_secp256r1_client_cert_der_len = 580;
diff --git a/libsecurity_ssl/regressions/SECG_ecc-secp256r1-client_key.h b/libsecurity_ssl/regressions/SECG_ecc-secp256r1-client_key.h
new file mode 100644 (file)
index 0000000..d4ab22d
--- /dev/null
@@ -0,0 +1,14 @@
+unsigned char SECG_ecc_secp256r1_client_key_der[] = {
+  0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x42, 0xc4, 0x28, 0xcb, 0x23,
+  0x58, 0x7e, 0xe0, 0xc8, 0xd6, 0x97, 0xbd, 0x40, 0x89, 0xf4, 0x27, 0x64,
+  0xe9, 0xfa, 0x42, 0x7d, 0x38, 0xe9, 0x91, 0x5d, 0xa4, 0x2f, 0x1b, 0xc5,
+  0x95, 0x63, 0x4a, 0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
+  0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0x36, 0x48, 0x98,
+  0xf8, 0xb3, 0xd0, 0xc4, 0x2e, 0xca, 0x99, 0x3d, 0x14, 0xbb, 0x14, 0x24,
+  0xf5, 0x89, 0x82, 0x36, 0xe3, 0x34, 0xb2, 0xf5, 0x35, 0x07, 0xd0, 0xa8,
+  0xde, 0x14, 0x84, 0xd7, 0x78, 0xa4, 0x62, 0x01, 0x77, 0xea, 0xbd, 0xa9,
+  0xa3, 0x9f, 0x8b, 0x48, 0x5f, 0x3c, 0x7a, 0xa1, 0x96, 0x40, 0xd1, 0x2c,
+  0xb6, 0xdd, 0xea, 0x21, 0xf8, 0xed, 0x29, 0x70, 0x44, 0x80, 0x49, 0x2e,
+  0x77
+};
+unsigned int SECG_ecc_secp256r1_client_key_der_len = 121;
diff --git a/libsecurity_ssl/regressions/SECG_ecc_rsa-secp256r1-client_cert.h b/libsecurity_ssl/regressions/SECG_ecc_rsa-secp256r1-client_cert.h
new file mode 100644 (file)
index 0000000..5189013
--- /dev/null
@@ -0,0 +1,57 @@
+unsigned char SECG_ecc_rsa_secp256r1_client_cert_der[] = {
+  0x30, 0x82, 0x02, 0x81, 0x30, 0x82, 0x01, 0xea, 0xa0, 0x03, 0x02, 0x01,
+  0x02, 0x02, 0x02, 0x04, 0x19, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x01, 0x04, 0x05, 0x00, 0x30, 0x81, 0x96, 0x31,
+  0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0b, 0x53, 0x41,
+  0x4d, 0x50, 0x4c, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x17, 0x30,
+  0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x43, 0x65, 0x72, 0x74,
+  0x69, 0x63, 0x6f, 0x6d, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x2e, 0x31, 0x10,
+  0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x54, 0x6f, 0x72,
+  0x6f, 0x6e, 0x74, 0x6f, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04,
+  0x04, 0x13, 0x07, 0x4f, 0x6e, 0x74, 0x61, 0x72, 0x69, 0x6f, 0x31, 0x34,
+  0x30, 0x32, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2b, 0x74, 0x6c, 0x73,
+  0x2e, 0x73, 0x65, 0x63, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x20, 0x52, 0x53,
+  0x41, 0x20, 0x31, 0x30, 0x32, 0x34, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
+  0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
+  0x72, 0x69, 0x74, 0x79, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
+  0x06, 0x13, 0x02, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30,
+  0x35, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d,
+  0x31, 0x35, 0x30, 0x35, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+  0x5a, 0x30, 0x81, 0x8f, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04,
+  0x0b, 0x13, 0x0b, 0x53, 0x41, 0x4d, 0x50, 0x4c, 0x45, 0x20, 0x4f, 0x4e,
+  0x4c, 0x59, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+  0x0e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x63, 0x6f, 0x6d, 0x20, 0x43, 0x6f,
+  0x72, 0x70, 0x2e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07,
+  0x13, 0x07, 0x54, 0x6f, 0x72, 0x6f, 0x6e, 0x74, 0x6f, 0x31, 0x10, 0x30,
+  0x0e, 0x06, 0x03, 0x55, 0x04, 0x04, 0x13, 0x07, 0x4f, 0x6e, 0x74, 0x61,
+  0x72, 0x69, 0x6f, 0x31, 0x3a, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, 0x03,
+  0x13, 0x31, 0x74, 0x6c, 0x73, 0x2e, 0x73, 0x65, 0x63, 0x67, 0x2e, 0x6f,
+  0x72, 0x67, 0x20, 0x45, 0x43, 0x43, 0x2d, 0x52, 0x53, 0x41, 0x20, 0x73,
+  0x65, 0x63, 0x70, 0x32, 0x35, 0x36, 0x72, 0x31, 0x20, 0x43, 0x6c, 0x69,
+  0x65, 0x6e, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+  0x61, 0x74, 0x65, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48,
+  0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03,
+  0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x36, 0x48, 0x98, 0xf8, 0xb3, 0xd0,
+  0xc4, 0x2e, 0xca, 0x99, 0x3d, 0x14, 0xbb, 0x14, 0x24, 0xf5, 0x89, 0x82,
+  0x36, 0xe3, 0x34, 0xb2, 0xf5, 0x35, 0x07, 0xd0, 0xa8, 0xde, 0x14, 0x84,
+  0xd7, 0x78, 0xa4, 0x62, 0x01, 0x77, 0xea, 0xbd, 0xa9, 0xa3, 0x9f, 0x8b,
+  0x48, 0x5f, 0x3c, 0x7a, 0xa1, 0x96, 0x40, 0xd1, 0x2c, 0xb6, 0xdd, 0xea,
+  0x21, 0xf8, 0xed, 0x29, 0x70, 0x44, 0x80, 0x49, 0x2e, 0x77, 0xa3, 0x2a,
+  0x30, 0x28, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
+  0x04, 0x04, 0x03, 0x02, 0x03, 0x88, 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d,
+  0x25, 0x01, 0x01, 0xff, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06,
+  0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x04, 0x05, 0x00, 0x03, 0x81, 0x81,
+  0x00, 0x62, 0x33, 0xbe, 0x0b, 0xd4, 0x2d, 0x9b, 0x5f, 0xa0, 0x13, 0x05,
+  0xc4, 0x9c, 0xa2, 0xc5, 0x24, 0x4d, 0x06, 0xca, 0xf7, 0x54, 0xdd, 0x48,
+  0x30, 0x27, 0xf6, 0xbf, 0x93, 0x4c, 0xe3, 0x97, 0x7c, 0xa7, 0xe3, 0x63,
+  0x0f, 0xe6, 0x17, 0xa1, 0xc5, 0xae, 0x7b, 0x10, 0x35, 0x10, 0x5e, 0x25,
+  0xa4, 0xe5, 0xa3, 0x4b, 0x2d, 0xa6, 0x86, 0x3c, 0x24, 0xb4, 0xe3, 0xed,
+  0x52, 0x39, 0xe4, 0x46, 0xc3, 0x99, 0xa1, 0x3a, 0xff, 0x41, 0xb3, 0xb0,
+  0x59, 0xbd, 0x7c, 0x53, 0xd0, 0x46, 0x99, 0x98, 0x24, 0xac, 0x8a, 0x23,
+  0x51, 0x5e, 0x06, 0x0d, 0xcb, 0x9f, 0xb0, 0x95, 0x75, 0x73, 0x49, 0x60,
+  0x24, 0x5c, 0xcd, 0x01, 0x1a, 0xfc, 0xad, 0xca, 0x14, 0x44, 0xc2, 0x0a,
+  0x01, 0x10, 0xbd, 0x19, 0xe1, 0xd7, 0x2c, 0xc0, 0x2f, 0xc7, 0x17, 0xbd,
+  0x9f, 0xdb, 0x08, 0x5b, 0xfe, 0x11, 0x51, 0x2b, 0xac
+};
+unsigned int SECG_ecc_rsa_secp256r1_client_cert_der_len = 645;
diff --git a/libsecurity_ssl/regressions/SECG_ecc_rsa-secp256r1-client_key.h b/libsecurity_ssl/regressions/SECG_ecc_rsa-secp256r1-client_key.h
new file mode 100644 (file)
index 0000000..8d2274f
--- /dev/null
@@ -0,0 +1,14 @@
+unsigned char SECG_ecc_rsa_secp256r1_client_key_der[] = {
+  0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x42, 0xc4, 0x28, 0xcb, 0x23,
+  0x58, 0x7e, 0xe0, 0xc8, 0xd6, 0x97, 0xbd, 0x40, 0x89, 0xf4, 0x27, 0x64,
+  0xe9, 0xfa, 0x42, 0x7d, 0x38, 0xe9, 0x91, 0x5d, 0xa4, 0x2f, 0x1b, 0xc5,
+  0x95, 0x63, 0x4a, 0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
+  0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0x36, 0x48, 0x98,
+  0xf8, 0xb3, 0xd0, 0xc4, 0x2e, 0xca, 0x99, 0x3d, 0x14, 0xbb, 0x14, 0x24,
+  0xf5, 0x89, 0x82, 0x36, 0xe3, 0x34, 0xb2, 0xf5, 0x35, 0x07, 0xd0, 0xa8,
+  0xde, 0x14, 0x84, 0xd7, 0x78, 0xa4, 0x62, 0x01, 0x77, 0xea, 0xbd, 0xa9,
+  0xa3, 0x9f, 0x8b, 0x48, 0x5f, 0x3c, 0x7a, 0xa1, 0x96, 0x40, 0xd1, 0x2c,
+  0xb6, 0xdd, 0xea, 0x21, 0xf8, 0xed, 0x29, 0x70, 0x44, 0x80, 0x49, 0x2e,
+  0x77
+};
+unsigned int SECG_ecc_rsa_secp256r1_client_key_der_len = 121;
diff --git a/libsecurity_ssl/regressions/cert-1.h b/libsecurity_ssl/regressions/cert-1.h
new file mode 100644 (file)
index 0000000..54bf58f
--- /dev/null
@@ -0,0 +1,66 @@
+unsigned char cert_1_der[] = {
+  0x30, 0x82, 0x02, 0xef, 0x30, 0x82, 0x02, 0x58, 0xa0, 0x03, 0x02, 0x01,
+  0x02, 0x02, 0x09, 0x00, 0x9f, 0xeb, 0x16, 0x7c, 0xc1, 0x64, 0xe6, 0x84,
+  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+  0x05, 0x05, 0x00, 0x30, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+  0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
+  0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49,
+  0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b,
+  0x13, 0x18, 0x43, 0x6f, 0x72, 0x65, 0x4f, 0x53, 0x20, 0x50, 0x6c, 0x61,
+  0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69,
+  0x74, 0x79, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+  0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30, 0x1e,
+  0x17, 0x0d, 0x31, 0x32, 0x30, 0x38, 0x31, 0x30, 0x31, 0x38, 0x30, 0x30,
+  0x31, 0x36, 0x5a, 0x17, 0x0d, 0x32, 0x32, 0x30, 0x38, 0x30, 0x38, 0x31,
+  0x38, 0x30, 0x30, 0x31, 0x36, 0x5a, 0x30, 0x59, 0x31, 0x0b, 0x30, 0x09,
+  0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30,
+  0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c,
+  0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03,
+  0x55, 0x04, 0x0b, 0x13, 0x18, 0x43, 0x6f, 0x72, 0x65, 0x4f, 0x53, 0x20,
+  0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x53, 0x65, 0x63,
+  0x75, 0x72, 0x69, 0x74, 0x79, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55,
+  0x04, 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
+  0x74, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30,
+  0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xbb, 0x2c, 0xef, 0x95, 0x09, 0x80,
+  0xff, 0xca, 0xb1, 0xd3, 0xd1, 0x15, 0xb6, 0x01, 0x15, 0xc1, 0x7c, 0x39,
+  0x81, 0xf6, 0x31, 0x13, 0xf2, 0x46, 0x75, 0xe6, 0xc6, 0xae, 0x2e, 0x68,
+  0x3a, 0xb8, 0x48, 0x70, 0x47, 0xf9, 0x44, 0x5d, 0x6a, 0x0e, 0x37, 0x2f,
+  0x71, 0x1e, 0x54, 0x6c, 0x33, 0x21, 0xe2, 0x2f, 0x0c, 0xd4, 0xfa, 0x88,
+  0x72, 0xad, 0x2b, 0x27, 0x02, 0x7c, 0x48, 0x10, 0x28, 0x18, 0x24, 0x4b,
+  0xf0, 0x87, 0x15, 0xf8, 0xac, 0xb6, 0x69, 0x1c, 0x1c, 0x25, 0xd6, 0xaf,
+  0xb3, 0xc8, 0x60, 0x1a, 0xa4, 0x8a, 0x20, 0xa9, 0x9b, 0x7d, 0x5a, 0xcd,
+  0xea, 0x97, 0x20, 0x45, 0x1a, 0x3b, 0xda, 0xbc, 0x15, 0x30, 0x84, 0x17,
+  0x08, 0xda, 0x50, 0xc0, 0x93, 0xa6, 0xd3, 0x28, 0x06, 0xc5, 0x6a, 0xc3,
+  0x9c, 0x48, 0x53, 0x38, 0x96, 0x8e, 0x33, 0x2f, 0xf9, 0x42, 0xac, 0xf0,
+  0xb1, 0x7f, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xbe, 0x30, 0x81,
+  0xbb, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
+  0x73, 0x7a, 0xcc, 0xf7, 0x1c, 0xf4, 0xc2, 0xa3, 0x95, 0xac, 0x64, 0x48,
+  0xbd, 0x5f, 0x1d, 0x09, 0xa6, 0x8c, 0x91, 0x08, 0x30, 0x81, 0x8b, 0x06,
+  0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0x83, 0x30, 0x81, 0x80, 0x80, 0x14,
+  0x73, 0x7a, 0xcc, 0xf7, 0x1c, 0xf4, 0xc2, 0xa3, 0x95, 0xac, 0x64, 0x48,
+  0xbd, 0x5f, 0x1d, 0x09, 0xa6, 0x8c, 0x91, 0x08, 0xa1, 0x5d, 0xa4, 0x5b,
+  0x30, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+  0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
+  0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+  0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x18, 0x43,
+  0x6f, 0x72, 0x65, 0x4f, 0x53, 0x20, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f,
+  0x72, 0x6d, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x31,
+  0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x09, 0x6c, 0x6f,
+  0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x82, 0x09, 0x00, 0x9f, 0xeb,
+  0x16, 0x7c, 0xc1, 0x64, 0xe6, 0x84, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d,
+  0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,
+  0x81, 0x81, 0x00, 0x4e, 0x9f, 0x0c, 0x99, 0x1b, 0x39, 0xf9, 0xf6, 0xd0,
+  0x3a, 0x16, 0x9b, 0xd9, 0xd1, 0x62, 0xb9, 0x71, 0xb2, 0xf7, 0x9a, 0x61,
+  0x60, 0x5a, 0x0f, 0x16, 0x07, 0xd9, 0x0e, 0x4d, 0xa3, 0x86, 0x7b, 0x18,
+  0xe2, 0xce, 0xa2, 0xbb, 0x44, 0x59, 0x57, 0xe0, 0x32, 0xeb, 0x75, 0x09,
+  0x15, 0xe1, 0xc5, 0x8c, 0x25, 0xfc, 0x04, 0x95, 0xa0, 0x2e, 0x75, 0xab,
+  0x54, 0x8b, 0x86, 0xf2, 0x43, 0x17, 0x79, 0x2f, 0xe8, 0x7f, 0x7c, 0x17,
+  0xaf, 0xf6, 0x91, 0xf7, 0xb0, 0x27, 0x53, 0x61, 0xf9, 0xd9, 0xb7, 0x22,
+  0x71, 0x78, 0x00, 0xfc, 0x8e, 0xc9, 0xd3, 0xb9, 0x5b, 0x09, 0x23, 0xa7,
+  0x92, 0xc5, 0xdc, 0x44, 0xcf, 0x4a, 0x6c, 0x0a, 0xf8, 0xda, 0x5c, 0x7d,
+  0x14, 0x36, 0x48, 0xc1, 0x76, 0xde, 0x6e, 0xde, 0xb6, 0xa0, 0xc6, 0x3a,
+  0x58, 0xd0, 0xc6, 0xfd, 0xe2, 0x32, 0xce, 0x49, 0x15, 0xcb, 0x71
+};
+unsigned int cert_1_der_len = 755;
diff --git a/libsecurity_ssl/regressions/gencerts.sh b/libsecurity_ssl/regressions/gencerts.sh
new file mode 100755 (executable)
index 0000000..934dc3b
--- /dev/null
@@ -0,0 +1,11 @@
+#!/bin/sh -x -e
+SUBJECT="/C=US/O=Apple Inc./OU=CoreOS Platform Security/CN=localhost"
+
+openssl req -x509 -newkey rsa:1024 -sha1 -days 3650  -subj "$SUBJECT" -nodes -keyout privkey-1.pem  -out cert-1.pem
+openssl x509 -in cert-1.pem -out cert-1.der -outform DER
+openssl rsa -in privkey-1.pem -out privkey-1.der -outform DER
+openssl pkcs12 -export -passout pass:password -out identity-1.p12 -inkey privkey-1.pem -in cert-1.pem
+
+xxd -i privkey-1.der privkey-1.h
+xxd -i cert-1.der cert-1.h
+xxd -i identity-1.p12 identity-1.h
diff --git a/libsecurity_ssl/regressions/identity-1.h b/libsecurity_ssl/regressions/identity-1.h
new file mode 100644 (file)
index 0000000..21d55d6
--- /dev/null
@@ -0,0 +1,151 @@
+unsigned char identity_1_p12[] = {
+  0x30, 0x82, 0x06, 0xe9, 0x02, 0x01, 0x03, 0x30, 0x82, 0x06, 0xaf, 0x06,
+  0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82,
+  0x06, 0xa0, 0x04, 0x82, 0x06, 0x9c, 0x30, 0x82, 0x06, 0x98, 0x30, 0x82,
+  0x03, 0x97, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07,
+  0x06, 0xa0, 0x82, 0x03, 0x88, 0x30, 0x82, 0x03, 0x84, 0x02, 0x01, 0x00,
+  0x30, 0x82, 0x03, 0x7d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x01, 0x0c, 0x01, 0x06, 0x30, 0x0e, 0x04, 0x08, 0xa1, 0x57, 0x35,
+  0x2d, 0xf3, 0x28, 0xdb, 0xf8, 0x02, 0x02, 0x08, 0x00, 0x80, 0x82, 0x03,
+  0x50, 0xf7, 0xae, 0x62, 0x01, 0x60, 0x8f, 0xa2, 0xda, 0x59, 0xf6, 0x8a,
+  0xc3, 0x46, 0xe7, 0x61, 0x69, 0x10, 0x7a, 0x4f, 0xab, 0x70, 0xf0, 0x73,
+  0xa9, 0x87, 0xba, 0x55, 0xdf, 0x47, 0x0c, 0xc4, 0xdd, 0x2e, 0x4c, 0x86,
+  0xb1, 0x06, 0x65, 0xad, 0xee, 0x2f, 0x7e, 0x8c, 0x5f, 0xbe, 0x7e, 0x46,
+  0x81, 0xa7, 0xe7, 0xa6, 0xca, 0x62, 0x65, 0xcb, 0x05, 0xe3, 0x67, 0x80,
+  0x3f, 0x3d, 0x7d, 0xf5, 0xbd, 0xb6, 0x6e, 0x3a, 0xb5, 0xc1, 0xa2, 0x99,
+  0x16, 0x0b, 0x21, 0x05, 0xf5, 0xc9, 0xde, 0x58, 0x77, 0xe4, 0x96, 0x75,
+  0x37, 0x85, 0x32, 0x2b, 0xed, 0x71, 0x99, 0xf3, 0xbe, 0xa4, 0x6c, 0x53,
+  0xe5, 0xe2, 0xea, 0x70, 0xaa, 0x63, 0x38, 0xa7, 0x5d, 0x4d, 0x8a, 0x39,
+  0xe7, 0xf4, 0xf5, 0xac, 0x43, 0xb1, 0x1f, 0x2b, 0xf6, 0x46, 0xee, 0xb1,
+  0x16, 0x27, 0x0d, 0x59, 0x6b, 0xc5, 0xff, 0xae, 0xb6, 0xfa, 0x76, 0x2b,
+  0x5c, 0x62, 0x9d, 0x19, 0x1c, 0xef, 0x6b, 0x1a, 0x69, 0x98, 0x43, 0x60,
+  0x03, 0x1f, 0x2a, 0x56, 0xe9, 0x26, 0x19, 0x4a, 0xe4, 0x3e, 0xd0, 0x85,
+  0xe4, 0x0d, 0x46, 0x2d, 0xaa, 0x2d, 0x61, 0x68, 0x8d, 0x00, 0xb8, 0xcd,
+  0x8b, 0x9d, 0xdc, 0xa9, 0xa8, 0xe9, 0xf7, 0x93, 0xdf, 0xb3, 0x84, 0x47,
+  0xe5, 0x12, 0xa4, 0xcd, 0x76, 0xd5, 0x28, 0xf4, 0xa9, 0xd5, 0x5e, 0x31,
+  0x94, 0x30, 0x44, 0x58, 0xbb, 0xcc, 0x5a, 0xe8, 0xf6, 0xc0, 0x67, 0x8b,
+  0xf5, 0x66, 0xe1, 0xdb, 0x28, 0x79, 0xf1, 0xa8, 0x78, 0x5a, 0x34, 0x1f,
+  0x3e, 0x2f, 0x57, 0x9d, 0xda, 0xa6, 0xbf, 0x38, 0xb6, 0x7e, 0xd4, 0x07,
+  0x30, 0x03, 0x65, 0xf9, 0xa2, 0xc9, 0xa5, 0x93, 0x2f, 0xc2, 0xf1, 0xbb,
+  0x1a, 0x2d, 0x39, 0xba, 0xa7, 0x47, 0xd3, 0x39, 0x70, 0xe1, 0x36, 0xf8,
+  0xba, 0x62, 0x57, 0x99, 0xf3, 0x38, 0xec, 0x82, 0xe2, 0x46, 0xe2, 0x39,
+  0x7e, 0x71, 0x08, 0x91, 0xbf, 0x8e, 0x5d, 0xf3, 0x31, 0x00, 0xf1, 0xff,
+  0xbf, 0x9e, 0xd6, 0x3b, 0xe6, 0xaa, 0xa0, 0x2c, 0xec, 0x1d, 0x50, 0x2b,
+  0xf3, 0xe0, 0xcd, 0xbd, 0x43, 0x94, 0xa9, 0x91, 0xff, 0x3c, 0x9f, 0xde,
+  0x70, 0x30, 0xc9, 0xee, 0x3f, 0xde, 0x8d, 0x4f, 0x75, 0x89, 0x5b, 0x58,
+  0x43, 0x33, 0x0c, 0x19, 0x85, 0x55, 0xc7, 0x22, 0x9f, 0xa7, 0xf3, 0x83,
+  0x6a, 0x34, 0xca, 0x8e, 0xfc, 0xcb, 0xa0, 0x71, 0x78, 0x59, 0xf4, 0x0b,
+  0x7f, 0xda, 0x2e, 0x21, 0x43, 0x0b, 0x11, 0xbb, 0xd5, 0x85, 0x09, 0xed,
+  0x08, 0x6e, 0x1b, 0x02, 0xb0, 0x1e, 0xf8, 0x45, 0xa0, 0xc4, 0xbb, 0xd4,
+  0xc4, 0x51, 0xb9, 0x16, 0x37, 0xd1, 0xfe, 0xf1, 0xa6, 0x41, 0x94, 0xbc,
+  0xb0, 0xaa, 0xf3, 0x7b, 0x90, 0xa7, 0xa2, 0xac, 0xc1, 0x82, 0xe5, 0x7c,
+  0x18, 0xcd, 0xd1, 0x83, 0x2b, 0xcd, 0x2d, 0x60, 0x5a, 0x48, 0x59, 0x2a,
+  0x27, 0x32, 0x1e, 0x14, 0xe6, 0x5b, 0x44, 0x98, 0xe7, 0xa0, 0x14, 0x22,
+  0x84, 0x52, 0xfa, 0x28, 0x1f, 0x54, 0xc5, 0xfc, 0x75, 0x12, 0x15, 0x9e,
+  0x22, 0xae, 0x12, 0xae, 0x7a, 0x98, 0xc4, 0x99, 0xa7, 0x26, 0x4f, 0xd3,
+  0x96, 0xd6, 0xbf, 0x98, 0x5f, 0x36, 0xf5, 0xd6, 0xee, 0xe8, 0x9a, 0x91,
+  0x8f, 0x23, 0x95, 0xe0, 0xa3, 0x30, 0x38, 0xc9, 0x7c, 0x03, 0xb7, 0x51,
+  0x96, 0x8d, 0x34, 0xbd, 0x4f, 0x10, 0x33, 0xdf, 0x48, 0xb3, 0x4e, 0x74,
+  0x43, 0x01, 0x55, 0x40, 0x85, 0x1a, 0xde, 0xa7, 0x34, 0xf0, 0x5e, 0x02,
+  0xa7, 0x1f, 0x24, 0x6c, 0x89, 0xf5, 0x3b, 0xe6, 0xdf, 0xae, 0xec, 0x06,
+  0x60, 0xe2, 0xfd, 0x1a, 0xa8, 0x03, 0x6c, 0xd8, 0x12, 0xbf, 0x11, 0x50,
+  0xd2, 0x6d, 0x64, 0xa0, 0xdc, 0x46, 0x4a, 0x26, 0x40, 0x80, 0x75, 0xec,
+  0x60, 0xa7, 0xbc, 0x6e, 0x0b, 0xdb, 0x76, 0x71, 0x20, 0xc5, 0x82, 0xfd,
+  0xe6, 0xd0, 0xc8, 0x14, 0x75, 0xf8, 0x3d, 0xd6, 0xd7, 0xe8, 0x46, 0x7f,
+  0x9d, 0x0a, 0xac, 0xa2, 0xfd, 0x32, 0xd9, 0xdc, 0x37, 0x00, 0x1d, 0xb0,
+  0x8e, 0x0b, 0x31, 0xba, 0x97, 0x1e, 0x0b, 0x42, 0x92, 0xe0, 0xaf, 0xe9,
+  0xe5, 0x06, 0xa4, 0xec, 0x3e, 0x97, 0x67, 0x7f, 0x0d, 0xef, 0xea, 0x53,
+  0xc1, 0xd3, 0x79, 0x33, 0xb8, 0xbd, 0x1d, 0x39, 0x33, 0xa2, 0x3d, 0xb0,
+  0x9d, 0xa2, 0x50, 0x85, 0xc9, 0x6e, 0x7e, 0x14, 0x88, 0x66, 0x5b, 0x10,
+  0x85, 0x95, 0xb9, 0xd0, 0x8b, 0xcb, 0xc5, 0x81, 0x0b, 0x16, 0xef, 0x05,
+  0x92, 0x99, 0x23, 0xc6, 0x78, 0xf0, 0x76, 0x30, 0x36, 0xda, 0x8e, 0x7d,
+  0x22, 0xbf, 0x73, 0x25, 0xd4, 0xfc, 0xa4, 0x20, 0xd9, 0x2f, 0x69, 0xa1,
+  0x1f, 0xca, 0xce, 0x28, 0xe8, 0xfd, 0xe0, 0x91, 0xfb, 0xe8, 0x76, 0x7f,
+  0xe2, 0xda, 0xfc, 0x7f, 0xa1, 0xd2, 0xc5, 0xd4, 0xac, 0x38, 0x7a, 0x28,
+  0x6b, 0xd7, 0x78, 0xed, 0xdf, 0xbf, 0xb5, 0xab, 0xa2, 0x2f, 0xa6, 0xdc,
+  0xfb, 0x12, 0x9c, 0xab, 0x89, 0x14, 0x88, 0x7c, 0x75, 0x15, 0x2a, 0x75,
+  0x83, 0x15, 0x89, 0x15, 0x28, 0x40, 0x48, 0xbf, 0x63, 0x81, 0xe2, 0x95,
+  0x65, 0x4d, 0x90, 0xf9, 0xd6, 0xc0, 0x67, 0x5f, 0x0d, 0xb4, 0x0f, 0x5c,
+  0xdb, 0xa9, 0x4f, 0x31, 0xe3, 0x71, 0x2d, 0x16, 0xfa, 0x81, 0x20, 0x45,
+  0xbf, 0xbb, 0xe7, 0x60, 0x0e, 0x59, 0xce, 0x33, 0x22, 0x98, 0x09, 0x3f,
+  0x7b, 0x7c, 0x80, 0x2f, 0xde, 0x5f, 0x6b, 0x51, 0x08, 0xae, 0xe4, 0x07,
+  0xef, 0x42, 0x90, 0x6d, 0xa9, 0x31, 0x7d, 0xe3, 0xaa, 0x55, 0x51, 0x79,
+  0x55, 0x83, 0xb0, 0x8d, 0x8e, 0xab, 0x5a, 0xe2, 0x18, 0xc5, 0x4e, 0x38,
+  0x2c, 0x2c, 0x68, 0x85, 0x7e, 0x55, 0xba, 0x50, 0x17, 0x6a, 0xa0, 0xb8,
+  0x7b, 0x84, 0xd1, 0xad, 0x37, 0xd0, 0x44, 0x92, 0x11, 0xfc, 0x69, 0x5c,
+  0x42, 0x8b, 0xe3, 0x43, 0xba, 0x35, 0x5b, 0x8f, 0xf0, 0xfa, 0xd1, 0xbd,
+  0x70, 0xf5, 0x4d, 0x75, 0x2f, 0x94, 0xc0, 0x77, 0xb3, 0xba, 0x95, 0x64,
+  0x27, 0x03, 0x10, 0x83, 0xc8, 0x2b, 0x01, 0xdf, 0xb7, 0xd3, 0xad, 0x41,
+  0x53, 0x14, 0x9f, 0xe8, 0x5d, 0x84, 0xb0, 0x27, 0x29, 0xb1, 0x99, 0xfe,
+  0x8b, 0xeb, 0x9f, 0xb7, 0x1e, 0x0c, 0xd5, 0x55, 0xa8, 0x30, 0x82, 0x02,
+  0xf9, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01,
+  0xa0, 0x82, 0x02, 0xea, 0x04, 0x82, 0x02, 0xe6, 0x30, 0x82, 0x02, 0xe2,
+  0x30, 0x82, 0x02, 0xde, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x0c, 0x0a, 0x01, 0x02, 0xa0, 0x82, 0x02, 0xa6, 0x30, 0x82, 0x02,
+  0xa2, 0x30, 0x1c, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x0c, 0x01, 0x03, 0x30, 0x0e, 0x04, 0x08, 0xd4, 0xf3, 0x35, 0x1a, 0xbd,
+  0x5e, 0xcd, 0x9f, 0x02, 0x02, 0x08, 0x00, 0x04, 0x82, 0x02, 0x80, 0xe4,
+  0x9c, 0x93, 0xc2, 0x8b, 0x15, 0xb0, 0xfd, 0x41, 0x40, 0x8f, 0xe2, 0x32,
+  0xd6, 0x46, 0x3b, 0x89, 0x3d, 0xed, 0xfa, 0x3f, 0x31, 0xa6, 0xf0, 0x5f,
+  0x42, 0x63, 0x57, 0xaf, 0x3c, 0xf0, 0x1f, 0x28, 0x2e, 0x8e, 0x0f, 0x6e,
+  0x98, 0x9a, 0xf2, 0x2c, 0x9f, 0x05, 0x87, 0xf9, 0xd1, 0x32, 0xf3, 0x1d,
+  0xc1, 0x6d, 0x24, 0xd2, 0x33, 0x67, 0x38, 0x1b, 0x5a, 0x9e, 0x92, 0x01,
+  0xcb, 0x2b, 0x4b, 0x0e, 0x94, 0x63, 0xf7, 0xd9, 0x42, 0xc7, 0x08, 0xcc,
+  0x2e, 0xe0, 0xee, 0x89, 0xe2, 0xaf, 0x56, 0xe3, 0x64, 0x22, 0xb0, 0xdf,
+  0x7d, 0x5a, 0x71, 0xd5, 0x8e, 0xc2, 0xac, 0xc5, 0x70, 0x7f, 0x24, 0x2c,
+  0x2f, 0x61, 0x1a, 0xa1, 0x55, 0xec, 0x53, 0x16, 0xd6, 0xb7, 0xfb, 0xfd,
+  0x61, 0x89, 0xdc, 0x4c, 0xe3, 0x62, 0xe9, 0xc4, 0x41, 0x80, 0xe6, 0xf1,
+  0x25, 0xd6, 0x16, 0xd9, 0xe9, 0x6a, 0x7c, 0x9c, 0xf4, 0xae, 0xa5, 0x26,
+  0xbd, 0x4f, 0x8d, 0x2b, 0x14, 0x7e, 0xe0, 0xc0, 0x21, 0xe4, 0x94, 0x45,
+  0x66, 0xd4, 0x4e, 0xcc, 0x7e, 0x92, 0xe3, 0xb6, 0xdd, 0x25, 0x0b, 0x61,
+  0x27, 0x1f, 0x06, 0x51, 0x8d, 0x23, 0xf1, 0x13, 0xe7, 0xb6, 0x42, 0x96,
+  0xc8, 0x6b, 0xb5, 0x5d, 0x8c, 0x7e, 0x5c, 0xbc, 0x6a, 0x6e, 0xc8, 0x7f,
+  0xa0, 0x0f, 0x1b, 0xed, 0x4f, 0x14, 0xd5, 0xa1, 0xf6, 0xe8, 0xb9, 0x51,
+  0xd4, 0x02, 0x3c, 0xdd, 0xff, 0xca, 0x72, 0x1c, 0x0b, 0xd3, 0x53, 0xa0,
+  0x42, 0x55, 0x00, 0xfa, 0x2d, 0x17, 0x16, 0xd9, 0xe8, 0x2d, 0x2c, 0xad,
+  0xf4, 0x54, 0x14, 0xda, 0x13, 0x1f, 0xb9, 0x16, 0x5e, 0x29, 0x8a, 0xa8,
+  0xee, 0xfd, 0x87, 0xee, 0xa2, 0xe5, 0x6a, 0x86, 0x53, 0x35, 0xb5, 0xa2,
+  0xa0, 0x2e, 0x27, 0x9a, 0x16, 0xb8, 0xa8, 0x8c, 0x92, 0x28, 0xe6, 0x54,
+  0xea, 0xf2, 0x82, 0x7b, 0x4b, 0x8a, 0xa7, 0x5c, 0x25, 0xb8, 0xa7, 0x6d,
+  0x61, 0x02, 0x51, 0xd7, 0xe0, 0xb8, 0x28, 0x88, 0x21, 0xeb, 0x3c, 0x54,
+  0x7a, 0x01, 0x13, 0x76, 0x26, 0x1b, 0x03, 0x2d, 0xec, 0x3d, 0xc3, 0xa9,
+  0x78, 0xf4, 0xd3, 0x27, 0x81, 0x08, 0x5c, 0x70, 0x14, 0x8a, 0x1e, 0xe8,
+  0x0d, 0x89, 0x78, 0x87, 0x97, 0xfe, 0xc1, 0x28, 0x8b, 0xa0, 0xcc, 0xed,
+  0x63, 0xd5, 0x10, 0x01, 0x36, 0xdc, 0xb6, 0xf7, 0x2e, 0x34, 0x9b, 0x45,
+  0x0a, 0x5c, 0x91, 0xb5, 0x3e, 0xb9, 0x47, 0xfe, 0x8f, 0xd6, 0xdb, 0x9c,
+  0xb1, 0x4b, 0xd8, 0xeb, 0xf4, 0x21, 0x96, 0xf1, 0x6b, 0xe3, 0xad, 0xfd,
+  0xa5, 0xce, 0x36, 0xef, 0xc5, 0xe2, 0x33, 0xa1, 0x58, 0x00, 0x4d, 0x9f,
+  0xf7, 0x9e, 0x51, 0x9d, 0x5a, 0xe4, 0x62, 0x15, 0x5e, 0xf9, 0x0e, 0x29,
+  0x9a, 0xf4, 0xdb, 0x10, 0x9a, 0x14, 0x91, 0x74, 0x3c, 0xa1, 0xa7, 0x0e,
+  0x71, 0x2c, 0x36, 0x5c, 0x2f, 0x08, 0x09, 0x66, 0xb5, 0xb3, 0xec, 0x6b,
+  0xe2, 0x58, 0xed, 0x39, 0x90, 0xc2, 0x54, 0xd2, 0xf3, 0x80, 0xe9, 0x4f,
+  0xf2, 0xa0, 0xac, 0x2c, 0xb5, 0x6f, 0x9c, 0x1e, 0x36, 0x80, 0xe8, 0xe2,
+  0x27, 0x29, 0x97, 0x9a, 0x4b, 0xa2, 0xac, 0xac, 0x55, 0x13, 0x6c, 0x86,
+  0x1c, 0x94, 0xb7, 0x20, 0x0d, 0x9c, 0x82, 0x95, 0xcc, 0xb3, 0xbd, 0x84,
+  0x5f, 0x92, 0xcd, 0xe2, 0x98, 0x5b, 0x8e, 0x3a, 0x63, 0x63, 0xe8, 0x40,
+  0xcc, 0xfc, 0x91, 0x71, 0xfd, 0xf1, 0xce, 0x3d, 0xba, 0x62, 0x21, 0x57,
+  0x46, 0x18, 0x8c, 0x7e, 0x60, 0xfb, 0xc4, 0xb8, 0x9e, 0xb0, 0xdd, 0x30,
+  0x90, 0x0f, 0xdd, 0x41, 0x75, 0x68, 0xa4, 0x82, 0xa7, 0xdd, 0xc1, 0x16,
+  0x2e, 0x17, 0x8f, 0x7a, 0xd9, 0xa9, 0xb3, 0xae, 0x1b, 0x0f, 0x99, 0xdc,
+  0xe1, 0x86, 0x76, 0x0c, 0x19, 0xbf, 0x00, 0xc8, 0xda, 0x8c, 0xa0, 0x16,
+  0x29, 0xaf, 0x62, 0x76, 0x7f, 0xe4, 0x8e, 0xd4, 0x10, 0xf2, 0x85, 0x37,
+  0x72, 0x9e, 0xba, 0xd6, 0x45, 0xd9, 0x61, 0x9b, 0xa5, 0xf1, 0x78, 0xab,
+  0x39, 0x67, 0x4d, 0xed, 0xfb, 0x25, 0x25, 0x2f, 0x57, 0xfe, 0xb0, 0xe8,
+  0xd6, 0x88, 0x26, 0xff, 0xe3, 0xbd, 0x55, 0xc8, 0x0f, 0xe8, 0x16, 0x0a,
+  0x7c, 0x25, 0xbd, 0x7f, 0xe0, 0x67, 0xe2, 0x22, 0x06, 0xd8, 0xb2, 0xbb,
+  0xd0, 0x83, 0x05, 0x4d, 0x00, 0x6e, 0xe8, 0x69, 0xd9, 0xc7, 0xec, 0x53,
+  0xfe, 0xc8, 0x73, 0xe1, 0x8e, 0x56, 0xae, 0xe5, 0x75, 0x38, 0xa7, 0x4a,
+  0x90, 0x5a, 0x2b, 0x93, 0xf3, 0x19, 0xf5, 0x90, 0x8a, 0x9a, 0xe3, 0x71,
+  0x93, 0x42, 0xb8, 0xbe, 0x05, 0xb6, 0xbe, 0x25, 0x39, 0xd1, 0x57, 0x37,
+  0x3f, 0x17, 0x9c, 0xa7, 0xf2, 0xf5, 0x9d, 0xed, 0x69, 0x4d, 0x87, 0x1e,
+  0x3e, 0x09, 0xad, 0x31, 0x25, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x09, 0x15, 0x31, 0x16, 0x04, 0x14, 0xe9, 0xac,
+  0x89, 0x1c, 0xee, 0x1d, 0xf8, 0xdd, 0xcb, 0xbc, 0x16, 0x15, 0xbf, 0xa5,
+  0x91, 0xdb, 0x2e, 0x6f, 0x42, 0x5b, 0x30, 0x31, 0x30, 0x21, 0x30, 0x09,
+  0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x24,
+  0xb2, 0x2c, 0x67, 0x3b, 0xe2, 0xee, 0xd9, 0x33, 0xeb, 0x6a, 0x79, 0xb3,
+  0x5c, 0x80, 0x10, 0x8f, 0xff, 0x53, 0x83, 0x04, 0x08, 0x12, 0x28, 0x41,
+  0x03, 0x3a, 0x0f, 0x13, 0xb9, 0x02, 0x02, 0x08, 0x00
+};
+unsigned int identity_1_p12_len = 1773;
diff --git a/libsecurity_ssl/regressions/privkey-1.h b/libsecurity_ssl/regressions/privkey-1.h
new file mode 100644 (file)
index 0000000..f39a5a5
--- /dev/null
@@ -0,0 +1,54 @@
+unsigned char privkey_1_der[] = {
+  0x30, 0x82, 0x02, 0x5e, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xbb,
+  0x2c, 0xef, 0x95, 0x09, 0x80, 0xff, 0xca, 0xb1, 0xd3, 0xd1, 0x15, 0xb6,
+  0x01, 0x15, 0xc1, 0x7c, 0x39, 0x81, 0xf6, 0x31, 0x13, 0xf2, 0x46, 0x75,
+  0xe6, 0xc6, 0xae, 0x2e, 0x68, 0x3a, 0xb8, 0x48, 0x70, 0x47, 0xf9, 0x44,
+  0x5d, 0x6a, 0x0e, 0x37, 0x2f, 0x71, 0x1e, 0x54, 0x6c, 0x33, 0x21, 0xe2,
+  0x2f, 0x0c, 0xd4, 0xfa, 0x88, 0x72, 0xad, 0x2b, 0x27, 0x02, 0x7c, 0x48,
+  0x10, 0x28, 0x18, 0x24, 0x4b, 0xf0, 0x87, 0x15, 0xf8, 0xac, 0xb6, 0x69,
+  0x1c, 0x1c, 0x25, 0xd6, 0xaf, 0xb3, 0xc8, 0x60, 0x1a, 0xa4, 0x8a, 0x20,
+  0xa9, 0x9b, 0x7d, 0x5a, 0xcd, 0xea, 0x97, 0x20, 0x45, 0x1a, 0x3b, 0xda,
+  0xbc, 0x15, 0x30, 0x84, 0x17, 0x08, 0xda, 0x50, 0xc0, 0x93, 0xa6, 0xd3,
+  0x28, 0x06, 0xc5, 0x6a, 0xc3, 0x9c, 0x48, 0x53, 0x38, 0x96, 0x8e, 0x33,
+  0x2f, 0xf9, 0x42, 0xac, 0xf0, 0xb1, 0x7f, 0x02, 0x03, 0x01, 0x00, 0x01,
+  0x02, 0x81, 0x81, 0x00, 0xb0, 0x57, 0xb5, 0xa0, 0x84, 0x43, 0xb4, 0xba,
+  0x12, 0xaf, 0xac, 0xdc, 0xf7, 0x8c, 0x2e, 0x23, 0x0c, 0x16, 0x62, 0x0a,
+  0xc0, 0x52, 0x3a, 0x7f, 0x87, 0xb4, 0xd4, 0x9a, 0x65, 0xbe, 0x6d, 0x14,
+  0x11, 0xab, 0x37, 0x23, 0xf0, 0xf4, 0xd1, 0x66, 0x73, 0x37, 0x8f, 0x2b,
+  0x33, 0xfe, 0x7c, 0x6d, 0xff, 0xda, 0xb4, 0x0c, 0x33, 0xbd, 0x39, 0xcd,
+  0x4c, 0x4a, 0x84, 0x5c, 0xf2, 0xc7, 0xc5, 0xfc, 0xdc, 0x03, 0x86, 0x8f,
+  0x2f, 0xac, 0x68, 0x11, 0x86, 0x55, 0x1c, 0x86, 0x51, 0x5d, 0xae, 0x18,
+  0x20, 0x33, 0x9d, 0x12, 0x59, 0x4c, 0x1a, 0xb9, 0x5a, 0x48, 0x89, 0xc4,
+  0x1a, 0x7c, 0x24, 0xf7, 0xff, 0xd6, 0x21, 0xa7, 0x7a, 0x14, 0xe8, 0x8c,
+  0x14, 0x3b, 0x80, 0xee, 0x4b, 0xc1, 0x33, 0x7d, 0x4e, 0x22, 0x23, 0xf7,
+  0xe8, 0x18, 0x0e, 0x24, 0x39, 0x62, 0x48, 0x66, 0x5e, 0x47, 0xa5, 0x81,
+  0x02, 0x41, 0x00, 0xe2, 0x4c, 0x05, 0x28, 0xdf, 0xa7, 0x4a, 0xb7, 0x41,
+  0x1c, 0xff, 0xc2, 0x65, 0x91, 0xa2, 0xd0, 0x0b, 0xe2, 0xf5, 0x32, 0x27,
+  0x3d, 0x14, 0xd5, 0xb2, 0xc2, 0x01, 0x18, 0x05, 0x54, 0x55, 0xb9, 0xd8,
+  0xed, 0xb2, 0x86, 0x69, 0xd6, 0x90, 0x0f, 0x40, 0xe7, 0x8a, 0x70, 0x5e,
+  0x60, 0x7a, 0xf5, 0x81, 0x5a, 0x22, 0x0e, 0x8b, 0x92, 0x5a, 0x43, 0xe7,
+  0xeb, 0xb2, 0x6b, 0x97, 0x6d, 0xee, 0xc5, 0x02, 0x41, 0x00, 0xd3, 0xbe,
+  0x5d, 0xca, 0x62, 0x62, 0x88, 0x48, 0x55, 0x8b, 0x23, 0xb4, 0x62, 0x2c,
+  0xba, 0xb4, 0xbc, 0xb7, 0xdc, 0xb1, 0xc5, 0x27, 0xd9, 0x5b, 0x36, 0xbb,
+  0x8f, 0x39, 0x4c, 0xb1, 0x7b, 0xa6, 0xac, 0x1a, 0xcd, 0x14, 0xca, 0xdc,
+  0x17, 0x45, 0x89, 0x37, 0x37, 0x14, 0x0a, 0x4e, 0xf2, 0x2d, 0xb5, 0x23,
+  0xbf, 0x3e, 0x0a, 0xb7, 0xb9, 0x16, 0x95, 0xcd, 0xda, 0xf0, 0x21, 0xdb,
+  0xa3, 0x73, 0x02, 0x40, 0x0b, 0xf9, 0x91, 0xdc, 0x53, 0xd9, 0x7a, 0x6e,
+  0xb0, 0x17, 0x64, 0xc1, 0x58, 0xb6, 0x98, 0x33, 0x02, 0x2e, 0x04, 0x63,
+  0x9f, 0x07, 0xf0, 0x6e, 0x4e, 0x83, 0x4d, 0xa3, 0x83, 0xc4, 0xae, 0xb4,
+  0xa2, 0xf2, 0x11, 0x1c, 0x63, 0xc5, 0x62, 0xe2, 0x2b, 0xc1, 0x14, 0xe6,
+  0x55, 0x58, 0x2d, 0xa9, 0x88, 0x2a, 0xc8, 0xda, 0x94, 0x30, 0x2e, 0x6e,
+  0xa1, 0x7b, 0x2b, 0x79, 0xde, 0x0d, 0x87, 0x31, 0x02, 0x41, 0x00, 0xbe,
+  0xed, 0x4a, 0x78, 0xf1, 0x19, 0xd3, 0xb5, 0x15, 0x9d, 0x6e, 0xc6, 0x7a,
+  0x37, 0xc6, 0xea, 0xad, 0xb8, 0x44, 0x41, 0xef, 0x7a, 0xad, 0x1c, 0xf8,
+  0x4f, 0x4b, 0x27, 0xe9, 0xa5, 0xa7, 0xcf, 0x74, 0x24, 0x7e, 0x83, 0x9f,
+  0x1f, 0xb1, 0xc4, 0x3b, 0xa4, 0x13, 0xff, 0xf8, 0x03, 0x93, 0x8f, 0xef,
+  0x63, 0x9a, 0x50, 0x01, 0x2e, 0x04, 0xb0, 0xfe, 0xc7, 0x2e, 0x01, 0x95,
+  0x26, 0x0d, 0x4d, 0x02, 0x41, 0x00, 0x84, 0x5d, 0xd1, 0xc6, 0xe9, 0xa2,
+  0x43, 0x94, 0xb4, 0xb9, 0x8b, 0x97, 0xe3, 0x52, 0xf4, 0xf0, 0x05, 0xd2,
+  0x24, 0x6c, 0x92, 0x90, 0xa1, 0x5e, 0xf8, 0xa7, 0xe8, 0x1b, 0xf3, 0x10,
+  0x09, 0xe7, 0xb0, 0xf0, 0xd4, 0xf5, 0x3b, 0x22, 0xd0, 0x2b, 0xa4, 0xdd,
+  0xd3, 0xd0, 0xdb, 0xc2, 0x11, 0xc1, 0x98, 0xff, 0xc6, 0x00, 0xae, 0x44,
+  0x1a, 0x29, 0x0e, 0xcd, 0x92, 0x65, 0x78, 0x6e, 0x6e, 0xb2
+};
+unsigned int privkey_1_der_len = 610;
diff --git a/libsecurity_ssl/regressions/ssl-39-echo.c b/libsecurity_ssl/regressions/ssl-39-echo.c
new file mode 100644 (file)
index 0000000..c11de67
--- /dev/null
@@ -0,0 +1,767 @@
+
+#if TARGET_OS_IPHONE
+// Currently only supported for iOS
+
+#include <stdbool.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <AssertMacros.h>
+#include <Security/SecureTransportPriv.h> /* SSLSetOption */
+#include <Security/SecureTransport.h>
+#include <Security/SecPolicy.h>
+#include <Security/SecTrust.h>
+#include <Security/SecIdentity.h>
+#include <Security/SecIdentityPriv.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecKeyPriv.h>
+#include <Security/SecItem.h>
+#include <Security/SecRandom.h>
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <mach/mach_time.h>
+
+#include <Security/SecRSAKey.h>
+
+#include "testlist.h"
+
+/*
+    SSL CipherSuite tests
+
+    Below are all the ciphers that are individually tested.  The first element
+    is the SecureTransport/RFC name; the second is what openssl calls it, which
+    can be looked up in ciphers(1).
+
+    All SSL_DH_* and TLS_DH_* are disabled because neither openssl nor
+    securetranport support them:
+    SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_DH_DSS_WITH_DES_CBC_SHA,
+    SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA, SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
+    SSL_DH_RSA_WITH_DES_CBC_SHA, SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA,
+    TLS_DH_DSS_WITH_AES_128_CBC_SHA, TLS_DH_RSA_WITH_AES_128_CBC_SHA,
+    TLS_DH_DSS_WITH_AES_256_CBC_SHA, TLS_DH_RSA_WITH_AES_256_CBC_SHA,
+
+    DSS is unimplemented by securetransport on the phone:
+    SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA,
+    SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
+    TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
+
+    SSLv2 ciphersuites disabled by securetransport on phone:
+    SSL_RSA_WITH_RC2_CBC_MD5, SSL_RSA_WITH_IDEA_CBC_MD5,
+    SSL_RSA_WITH_DES_CBC_MD5, SSL_RSA_WITH_3DES_EDE_CBC_MD5,
+
+    SSLv3 ciphersuites disabled by securetransport on phone:
+    SSL_RSA_WITH_IDEA_CBC_SHA, SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5
+
+*/
+
+typedef struct _CipherSuiteName {
+        SSLCipherSuite cipher;
+        const char *name;
+        bool dh_anonymous;
+} CipherSuiteName;
+
+#define CIPHER(cipher, dh_anonymous) { cipher, #cipher, dh_anonymous }
+
+static const CipherSuiteName ciphers[] = {
+#if 0
+    /* TODO: Generate an ecdsa private key and certificate for the tests. */
+    CIPHER(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, false),
+    CIPHER(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, false),
+    CIPHER(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, false),
+    CIPHER(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, false),
+    CIPHER(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, false),
+    CIPHER(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, false),
+    CIPHER(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, false),
+    CIPHER(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, false),
+    CIPHER(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, false),
+    CIPHER(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, false),
+    CIPHER(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, false),
+    CIPHER(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, false),
+    CIPHER(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, false),
+    CIPHER(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, false),
+    CIPHER(TLS_ECDHE_RSA_WITH_RC4_128_SHA, false),
+    CIPHER(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, false),
+    CIPHER(TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, false),
+    CIPHER(TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, false),
+    CIPHER(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, false),
+    CIPHER(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, false),
+    CIPHER(TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, false),
+    CIPHER(TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, false),
+    CIPHER(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, false),
+    CIPHER(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, false),
+    CIPHER(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, false),
+    CIPHER(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, false),
+    CIPHER(TLS_ECDH_ECDSA_WITH_RC4_128_SHA, false),
+    CIPHER(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, false),
+    CIPHER(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, false),
+    CIPHER(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, false),
+    CIPHER(TLS_ECDH_RSA_WITH_RC4_128_SHA, false),
+    CIPHER(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, false),
+#endif
+    CIPHER(TLS_RSA_WITH_AES_256_GCM_SHA384, false),
+    CIPHER(TLS_RSA_WITH_AES_128_GCM_SHA256, false),
+    CIPHER(TLS_RSA_WITH_AES_256_CBC_SHA256, false),
+    CIPHER(TLS_RSA_WITH_AES_128_CBC_SHA256, false),
+    CIPHER(TLS_RSA_WITH_AES_128_CBC_SHA, false),
+    CIPHER(SSL_RSA_WITH_RC4_128_SHA, false),
+    CIPHER(SSL_RSA_WITH_RC4_128_MD5, false),
+    CIPHER(TLS_RSA_WITH_AES_256_CBC_SHA, false),
+    CIPHER(SSL_RSA_WITH_3DES_EDE_CBC_SHA, false),
+    CIPHER(SSL_RSA_WITH_3DES_EDE_CBC_MD5, false),
+    CIPHER(SSL_RSA_WITH_DES_CBC_SHA, false),
+    CIPHER(SSL_RSA_WITH_DES_CBC_MD5, false),
+    CIPHER(SSL_RSA_EXPORT_WITH_RC4_40_MD5, false),
+    CIPHER(SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, false),
+    CIPHER(SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, false),
+    CIPHER(SSL_RSA_WITH_RC2_CBC_MD5, false),
+    CIPHER(TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, false),
+    CIPHER(TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, false),
+    CIPHER(TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, false),
+    CIPHER(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, false),
+    CIPHER(TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, false),
+    CIPHER(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, false),
+    CIPHER(TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, false),
+    CIPHER(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, false),
+    CIPHER(TLS_DHE_DSS_WITH_AES_128_CBC_SHA, false),
+    CIPHER(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, false),
+    CIPHER(TLS_DHE_DSS_WITH_AES_256_CBC_SHA, false),
+    CIPHER(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, false),
+    CIPHER(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, false),
+    CIPHER(SSL_DHE_RSA_WITH_DES_CBC_SHA, false),
+    CIPHER(SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, false),
+    CIPHER(SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, false),
+    CIPHER(SSL_DHE_DSS_WITH_DES_CBC_SHA, false),
+    CIPHER(SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, false),
+    CIPHER(TLS_DH_anon_WITH_AES_256_GCM_SHA384, true),
+    CIPHER(TLS_DH_anon_WITH_AES_128_GCM_SHA256, true),
+    CIPHER(TLS_DH_anon_WITH_AES_128_CBC_SHA256, true),
+    CIPHER(TLS_DH_anon_WITH_AES_256_CBC_SHA256, true),
+    CIPHER(TLS_DH_anon_WITH_AES_128_CBC_SHA, true),
+    CIPHER(TLS_DH_anon_WITH_AES_256_CBC_SHA, true),
+    CIPHER(SSL_DH_anon_WITH_RC4_128_MD5, true),
+    CIPHER(SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, true),
+    CIPHER(SSL_DH_anon_WITH_DES_CBC_SHA, true),
+    CIPHER(SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, true),
+    CIPHER(SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, true),
+#if 0
+       CIPHER(TLS_ECDHE_ECDSA_WITH_NULL_SHA, false),
+       CIPHER(TLS_ECDHE_RSA_WITH_NULL_SHA, false),
+    CIPHER(TLS_ECDH_ECDSA_WITH_NULL_SHA, false),
+       CIPHER(TLS_ECDH_RSA_WITH_NULL_SHA, false),
+#endif
+    CIPHER(TLS_RSA_WITH_NULL_SHA256, false),
+    CIPHER(SSL_RSA_WITH_NULL_SHA, false),
+    CIPHER(SSL_RSA_WITH_NULL_MD5, false),
+#if 0
+    /* We don't support these yet. */
+    CIPHER(TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, false),
+    CIPHER(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, false),
+    CIPHER(TLS_RSA_WITH_RC4_128_SHA, false),
+    CIPHER(TLS_RSA_WITH_3DES_EDE_CBC_SHA, false),
+    CIPHER(TLS_RSA_WITH_RC4_128_MD5, false),
+    CIPHER(TLS_DH_DSS_WITH_AES_256_GCM_SHA384, false),
+    CIPHER(TLS_DH_DSS_WITH_AES_128_GCM_SHA256, false),
+    CIPHER(TLS_DH_RSA_WITH_AES_256_GCM_SHA384, false),
+    CIPHER(TLS_DH_RSA_WITH_AES_128_GCM_SHA256, false),
+    CIPHER(TLS_DH_DSS_WITH_AES_256_CBC_SHA256, false),
+    CIPHER(TLS_DH_RSA_WITH_AES_256_CBC_SHA256, false),
+    CIPHER(TLS_DH_DSS_WITH_AES_128_CBC_SHA256, false),
+    CIPHER(TLS_DH_RSA_WITH_AES_128_CBC_SHA256, false),
+    CIPHER(TLS_DH_DSS_WITH_AES_256_CBC_SHA, false),
+    CIPHER(TLS_DH_RSA_WITH_AES_256_CBC_SHA, false),
+       CIPHER(TLS_DH_DSS_WITH_AES_128_CBC_SHA, false),
+    CIPHER(TLS_DH_RSA_WITH_AES_128_CBC_SHA, false),
+    CIPHER(TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA, false),
+    CIPHER(TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA, false),
+    CIPHER(TLS_ECDH_anon_WITH_AES_256_CBC_SHA, false),
+       CIPHER(TLS_ECDH_anon_WITH_AES_128_CBC_SHA, false),
+    CIPHER(TLS_ECDH_anon_WITH_RC4_128_SHA, false),
+    CIPHER(TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA, false),
+    CIPHER(TLS_ECDH_anon_WITH_NULL_SHA, false),
+#endif
+
+    { -1, NULL }
+};
+
+static int ciphers_len = array_size(ciphers);
+
+#if 0 // currently unused
+static SSLCipherSuite sslcipher_atoi(const char *name)
+{
+       const CipherSuiteName *a = ciphers;
+       while(a->name) {
+           if (0 == strcmp(a->name, name)) break;
+           a++;
+       }
+       return a->cipher;
+}
+
+static const char * sslcipher_itoa(SSLCipherSuite num)
+{
+       const CipherSuiteName *a = ciphers;
+       while(a->cipher >= 0) {
+           if (num == a->cipher) break;
+           a++;
+       }
+       return a->name;
+}
+#endif // currently unused
+
+static unsigned char dh_param_512_bytes[] = {
+  0x30, 0x46, 0x02, 0x41, 0x00, 0xdb, 0x3c, 0xfa, 0x13, 0xa6, 0xd2, 0x64,
+  0xdf, 0xcc, 0x40, 0xb1, 0x21, 0xd4, 0xf2, 0xad, 0x22, 0x7f, 0xce, 0xa0,
+  0xb9, 0x5b, 0x95, 0x1c, 0x2e, 0x99, 0xb0, 0x27, 0xd0, 0xed, 0xf4, 0xbd,
+  0xbb, 0x36, 0x93, 0xd0, 0x9d, 0x2b, 0x32, 0xa3, 0x56, 0x53, 0xe3, 0x7b,
+  0xed, 0xa1, 0x71, 0x82, 0x2e, 0x83, 0x14, 0xf9, 0xc0, 0x2f, 0x15, 0xcb,
+  0xcf, 0x97, 0xab, 0x88, 0x49, 0x20, 0x28, 0x2e, 0x63, 0x02, 0x01, 0x02
+};
+static unsigned char *dh_param_512_der = dh_param_512_bytes;
+static unsigned int dh_param_512_der_len = 72;
+
+/* openssl req -newkey rsa:512 -sha1 -days 365  -subj "/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=localhost" -x509 -nodes -outform DER -keyout privkey.der -outform der -out cert.der */
+static unsigned char pkey_der[] = {
+  0x30, 0x82, 0x01, 0x3b, 0x02, 0x01, 0x00, 0x02, 0x41, 0x00, 0xc0, 0x80,
+  0x43, 0xf1, 0x4d, 0xdc, 0x9a, 0x24, 0xe7, 0x25, 0x7c, 0x8b, 0x8b, 0x65,
+  0x87, 0x97, 0xed, 0x3f, 0xfa, 0xfe, 0xbe, 0xcb, 0x12, 0x43, 0x1f, 0x0c,
+  0xb5, 0xbf, 0x6b, 0x81, 0xee, 0x1b, 0x46, 0x6a, 0x02, 0x86, 0x92, 0xec,
+  0x8a, 0xb3, 0x65, 0x77, 0x15, 0xd0, 0x49, 0xb4, 0x22, 0x84, 0xf4, 0x85,
+  0x56, 0x53, 0xf5, 0x5a, 0x3b, 0xad, 0x23, 0xa8, 0x0c, 0x24, 0xb7, 0xf5,
+  0xf4, 0xa1, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x41, 0x00, 0xb8, 0x7f,
+  0xf7, 0x1e, 0xa7, 0x0e, 0xc1, 0x9a, 0x8f, 0x04, 0x49, 0xcb, 0x81, 0x4e,
+  0x4d, 0x58, 0x5a, 0xe7, 0x10, 0x8c, 0xea, 0x96, 0xbd, 0xa9, 0x21, 0x70,
+  0x50, 0x1d, 0xe8, 0x4f, 0x7e, 0xc2, 0x71, 0xff, 0x55, 0xc5, 0xa7, 0x28,
+  0xc8, 0xf2, 0xc7, 0x19, 0xd1, 0x2c, 0x10, 0x40, 0x39, 0xa8, 0xe1, 0x5b,
+  0xbd, 0x97, 0x04, 0xff, 0xd3, 0x27, 0x9b, 0xce, 0x5e, 0x8d, 0x2f, 0x0e,
+  0xd9, 0xf1, 0x02, 0x21, 0x00, 0xde, 0xfc, 0x18, 0x88, 0xa4, 0xef, 0x3b,
+  0x18, 0xca, 0x54, 0x3f, 0xa8, 0x14, 0x96, 0x9a, 0xd7, 0x67, 0x57, 0x55,
+  0xdc, 0x6b, 0xd4, 0x8e, 0x7d, 0xb4, 0x32, 0x00, 0x63, 0x67, 0x6a, 0x57,
+  0x65, 0x02, 0x21, 0x00, 0xdd, 0x00, 0xba, 0xdc, 0xa1, 0xe2, 0x5c, 0xda,
+  0xfe, 0xfc, 0x50, 0x1e, 0x9b, 0x95, 0x28, 0x34, 0xf2, 0x52, 0x31, 0x7a,
+  0x15, 0x00, 0x6f, 0xcc, 0x08, 0x2c, 0x6d, 0x55, 0xb0, 0x24, 0x6a, 0x8d,
+  0x02, 0x20, 0x14, 0xf5, 0x7d, 0x18, 0xda, 0xe7, 0xe1, 0x96, 0x22, 0xee,
+  0x68, 0x4d, 0x54, 0x22, 0x13, 0xcb, 0xcb, 0x5a, 0xda, 0x27, 0x2d, 0xbb,
+  0x7c, 0xe9, 0x33, 0xd6, 0xbf, 0x52, 0x98, 0x95, 0xd6, 0x41, 0x02, 0x21,
+  0x00, 0xaa, 0x58, 0x8c, 0xaf, 0xd1, 0x6b, 0xdc, 0x6c, 0xc4, 0xcc, 0x10,
+  0xa9, 0x76, 0xfc, 0xc2, 0x50, 0x05, 0x53, 0xcb, 0x65, 0x31, 0x58, 0xf3,
+  0xd3, 0x4d, 0x9d, 0x88, 0xec, 0xda, 0x67, 0x47, 0x65, 0x02, 0x20, 0x53,
+  0xf2, 0x49, 0x77, 0x7e, 0x10, 0xc1, 0xc4, 0xed, 0xc0, 0xaf, 0x99, 0x79,
+  0xab, 0x7b, 0x25, 0x0e, 0x70, 0x36, 0xd2, 0xd1, 0xa3, 0x81, 0x0d, 0x83,
+  0x4f, 0x6b, 0x1b, 0x48, 0xec, 0x87, 0x90
+};
+static unsigned int pkey_der_len = 319;
+
+static unsigned char cert_der[] = {
+  0x30, 0x82, 0x02, 0x79, 0x30, 0x82, 0x02, 0x23, 0xa0, 0x03, 0x02, 0x01,
+  0x02, 0x02, 0x09, 0x00, 0xc2, 0xa8, 0x3b, 0xaa, 0x40, 0xa4, 0x29, 0x2b,
+  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+  0x05, 0x05, 0x00, 0x30, 0x5e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+  0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
+  0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49,
+  0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b,
+  0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74,
+  0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
+  0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x12, 0x30, 0x10, 0x06,
+  0x03, 0x55, 0x04, 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68,
+  0x6f, 0x73, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x38, 0x30, 0x39, 0x31,
+  0x35, 0x32, 0x31, 0x35, 0x30, 0x35, 0x36, 0x5a, 0x17, 0x0d, 0x30, 0x39,
+  0x30, 0x39, 0x31, 0x35, 0x32, 0x31, 0x35, 0x30, 0x35, 0x36, 0x5a, 0x30,
+  0x5e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+  0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+  0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
+  0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70,
+  0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+  0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+  0x69, 0x74, 0x79, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03,
+  0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30,
+  0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00,
+  0xc0, 0x80, 0x43, 0xf1, 0x4d, 0xdc, 0x9a, 0x24, 0xe7, 0x25, 0x7c, 0x8b,
+  0x8b, 0x65, 0x87, 0x97, 0xed, 0x3f, 0xfa, 0xfe, 0xbe, 0xcb, 0x12, 0x43,
+  0x1f, 0x0c, 0xb5, 0xbf, 0x6b, 0x81, 0xee, 0x1b, 0x46, 0x6a, 0x02, 0x86,
+  0x92, 0xec, 0x8a, 0xb3, 0x65, 0x77, 0x15, 0xd0, 0x49, 0xb4, 0x22, 0x84,
+  0xf4, 0x85, 0x56, 0x53, 0xf5, 0x5a, 0x3b, 0xad, 0x23, 0xa8, 0x0c, 0x24,
+  0xb7, 0xf5, 0xf4, 0xa1, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xc3,
+  0x30, 0x81, 0xc0, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16,
+  0x04, 0x14, 0xe3, 0x58, 0xab, 0x35, 0xc0, 0x58, 0xb8, 0x65, 0x40, 0xca,
+  0x9b, 0x6c, 0xeb, 0x2f, 0xf5, 0xbf, 0xbd, 0x0b, 0xf3, 0xa6, 0x30, 0x81,
+  0x90, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0x88, 0x30, 0x81, 0x85,
+  0x80, 0x14, 0xe3, 0x58, 0xab, 0x35, 0xc0, 0x58, 0xb8, 0x65, 0x40, 0xca,
+  0x9b, 0x6c, 0xeb, 0x2f, 0xf5, 0xbf, 0xbd, 0x0b, 0xf3, 0xa6, 0xa1, 0x62,
+  0xa4, 0x60, 0x30, 0x5e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
+  0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
+  0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e,
+  0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
+  0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
+  0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
+  0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03,
+  0x55, 0x04, 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
+  0x73, 0x74, 0x82, 0x09, 0x00, 0xc2, 0xa8, 0x3b, 0xaa, 0x40, 0xa4, 0x29,
+  0x2b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03,
+  0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x41, 0x00, 0x41, 0x40, 0x07,
+  0xde, 0x1f, 0xd0, 0x00, 0x62, 0x75, 0x36, 0xb3, 0x94, 0xa8, 0xac, 0x3b,
+  0x98, 0xbb, 0x28, 0x56, 0xf6, 0x9f, 0xe3, 0x87, 0xd4, 0xa1, 0x7a, 0x85,
+  0xce, 0x40, 0x8a, 0xfd, 0x12, 0xb4, 0x99, 0x8c, 0x1d, 0x05, 0x61, 0xdb,
+  0x35, 0xb8, 0x04, 0x7c, 0xfb, 0xe4, 0x97, 0x88, 0x66, 0xa0, 0x54, 0x7b,
+  0x1c, 0xce, 0x99, 0xd8, 0xd3, 0x99, 0x80, 0x40, 0x9b, 0xa2, 0x73, 0x8b,
+  0xfd
+};
+static unsigned int cert_der_len = 637;
+
+typedef struct {
+    uint32_t session_id;
+    bool is_session_resume;
+    SSLContextRef handle;
+    bool is_st;
+    bool is_server;
+    bool client_side_auth;
+    bool dh_anonymous;
+    int comm;
+    CFArrayRef certs;
+} ssl_test_handle;
+
+#if 0 // currently unused
+static CFArrayRef SecIdentityCopySSLClientAuthenticationChain(SecIdentityRef identity)
+{
+   CFMutableArrayRef chain = NULL;
+   SecPolicyRef policy = NULL;
+   SecTrustRef trust = NULL;
+   SecTrustResultType trust_result;
+
+   do {
+       policy = SecPolicyCreateSSL(false, NULL);
+       if (!policy)
+           break;
+
+       SecCertificateRef cert = NULL;
+       if (SecIdentityCopyCertificate(identity, &cert))
+           break;
+
+       CFArrayRef certs = CFArrayCreate(NULL, (const void **)&cert,
+                 1, &kCFTypeArrayCallBacks);
+       CFRelease(cert);
+       if (!certs)
+           break;
+
+       if (SecTrustCreateWithCertificates(certs, policy, &trust))
+           break;
+       CFRelease(certs);
+       CFRelease(policy);
+       if (SecTrustEvaluate(trust, &trust_result))
+           break;
+
+       int i, count = SecTrustGetCertificateCount(trust);
+       chain = CFArrayCreateMutable(NULL, count, &kCFTypeArrayCallBacks);
+       CFArrayAppendValue(chain, identity);
+       for (i = 1; i < count; i++) {
+           if ((i+1 == count) && (trust_result == kSecTrustResultUnspecified))
+               continue; /* skip anchor if chain is complete */
+           SecCertificateRef s = SecTrustGetCertificateAtIndex(trust, i);
+           CFArrayAppendValue(chain, s);
+       }
+   } while (0);
+   if (trust)
+       CFRelease(trust);
+   if (policy)
+       CFRelease(policy);
+   return chain;
+}
+#endif // currently unused
+
+static CFArrayRef server_chain()
+{
+    SecKeyRef pkey = SecKeyCreateRSAPrivateKey(kCFAllocatorDefault,
+        pkey_der, pkey_der_len, kSecKeyEncodingPkcs1);
+    SecCertificateRef cert = SecCertificateCreateWithBytes(kCFAllocatorDefault,
+        cert_der, cert_der_len);
+    SecIdentityRef ident = SecIdentityCreate(kCFAllocatorDefault, cert, pkey);
+    CFRelease(pkey);
+    CFRelease(cert);
+    CFArrayRef items = CFArrayCreate(kCFAllocatorDefault,
+        (const void **)&ident, 1, &kCFTypeArrayCallBacks);
+    CFRelease(ident);
+    return items;
+}
+
+// MARK: -
+// MARK: SecureTransport support
+
+#if 0
+static void hexdump(const uint8_t *bytes, size_t len) {
+       size_t ix;
+    printf("socket write(%p, %lu)\n", bytes, len);
+       for (ix = 0; ix < len; ++ix) {
+        if (!(ix % 16))
+            printf("\n");
+               printf("%02X ", bytes[ix]);
+       }
+       printf("\n");
+}
+#else
+#define hexdump(bytes, len)
+#endif
+
+static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *length)
+{
+       size_t len = *length;
+       uint8_t *ptr = (uint8_t *)data;
+
+    do {
+        ssize_t ret;
+        do {
+            hexdump(ptr, len);
+            ret = write((int)conn, ptr, len);
+            if (ret < 0)
+                perror("send");
+        } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
+        if (ret > 0) {
+            len -= ret;
+            ptr += ret;
+        }
+        else
+            return -36;
+    } while (len > 0);
+
+    *length = *length - len;
+    return errSecSuccess;
+}
+
+static OSStatus SocketRead(SSLConnectionRef conn, void *data, size_t *length)
+{
+       size_t len = *length;
+       uint8_t *ptr = (uint8_t *)data;
+
+    do {
+        ssize_t ret;
+        do {
+            ret = read((int)conn, ptr, len);
+            if (ret < 0)
+                perror("send");
+        } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
+        if (ret > 0) {
+            len -= ret;
+            ptr += ret;
+        }
+        else
+            return -36;
+    } while (len > 0);
+
+    *length = *length - len;
+    return errSecSuccess;
+}
+
+static unsigned char dn[] = {
+  0x30, 0x5e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+  0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
+  0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+  0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41,
+  0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+  0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
+  0x72, 0x69, 0x74, 0x79, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
+  0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74
+};
+static unsigned int dn_len = 96;
+
+static SSLContextRef make_ssl_ref(bool server, bool client_side_auth, bool dh_anonymous,
+    bool dtls, int sock, CFArrayRef certs)
+{
+    SSLContextRef ctx = NULL;
+    if(dtls)
+        require_noerr(SSLNewDatagramContext(server, &ctx), out);
+    else
+        require_noerr(SSLNewContext(server, &ctx), out);
+    require_noerr(SSLSetIOFuncs(ctx,
+        (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
+    require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)sock), out);
+    static const char *peer_domain_name = "localhost";
+    require_noerr(SSLSetPeerDomainName(ctx, peer_domain_name,
+        strlen(peer_domain_name)), out);
+
+    if (!dh_anonymous) {
+        if (server)
+            require_noerr(SSLSetCertificate(ctx, certs), out);
+        if (client_side_auth && server) {
+            require_noerr(SSLSetClientSideAuthenticate(ctx, kAlwaysAuthenticate), out);
+            require_noerr(SSLAddDistinguishedName(ctx, dn, dn_len), out);
+        }
+#if 0 /* Setting client certificate in advance */
+        if (client_side_auth && !server)
+            require_noerr(SSLSetCertificate(ctx, certs), out);
+#endif
+        if (client_side_auth && !server) /* enable break from SSLHandshake */
+            require_noerr(SSLSetSessionOption(ctx,
+                kSSLSessionOptionBreakOnCertRequested, true), out);
+        require_noerr(SSLSetSessionOption(ctx,
+            kSSLSessionOptionBreakOnServerAuth, true), out);
+    }
+
+    /* Tell SecureTransport to not check certs itself: it will break out of the
+       handshake to let us take care of it instead. */
+    require_noerr(SSLSetEnableCertVerify(ctx, false), out);
+
+    if (server) {
+        require_noerr(SSLSetDiffieHellmanParams(ctx,
+            dh_param_512_der, dh_param_512_der_len), out);
+    }
+    else /* if client */ {
+    }
+
+    return ctx;
+out:
+    if (ctx)
+        SSLDisposeContext(ctx);
+    return NULL;
+}
+
+static void *securetransport_ssl_thread(void *arg)
+{
+    OSStatus ortn;
+    ssl_test_handle * ssl = (ssl_test_handle *)arg;
+    SSLContextRef ctx = ssl->handle;
+    SecTrustRef trust = NULL;
+    bool got_server_auth = false, got_client_cert_req = false;
+
+    //uint64_t start = mach_absolute_time();
+    do {
+        ortn = SSLHandshake(ctx);
+
+        if (ortn == errSSLServerAuthCompleted)
+        {
+            require_string(!got_server_auth, out, "second server auth");
+            require_string(!got_client_cert_req, out, "got client cert req before server auth");
+            got_server_auth = true;
+            require_string(!trust, out, "Got errSSLServerAuthCompleted twice?");
+            /* verify peer cert chain */
+            require_noerr(SSLCopyPeerTrust(ctx, &trust), out);
+            SecTrustResultType trust_result = 0;
+            /* this won't verify without setting up a trusted anchor */
+            require_noerr(SecTrustEvaluate(trust, &trust_result), out);
+
+            CFIndex n_certs = SecTrustGetCertificateCount(trust);
+            /*fprintf(stderr, "%ld certs; trust_eval: %d\n", n_certs, trust_result); */
+
+            CFMutableArrayRef peer_cert_array =
+                CFArrayCreateMutable(NULL, n_certs, &kCFTypeArrayCallBacks);
+            CFMutableArrayRef orig_peer_cert_array =
+                CFArrayCreateMutableCopy(NULL, n_certs, ssl->certs);
+            while (n_certs--)
+                CFArrayInsertValueAtIndex(peer_cert_array, 0,
+                    SecTrustGetCertificateAtIndex(trust, n_certs));
+
+            SecIdentityRef ident =
+                (SecIdentityRef)CFArrayGetValueAtIndex(orig_peer_cert_array, 0);
+            SecCertificateRef peer_cert = NULL;
+            require_noerr(SecIdentityCopyCertificate(ident, &peer_cert), out);
+            CFArraySetValueAtIndex(orig_peer_cert_array, 0, peer_cert);
+            CFRelease(peer_cert);
+
+            require(CFEqual(orig_peer_cert_array, peer_cert_array), out);
+            CFRelease(orig_peer_cert_array);
+            CFRelease(peer_cert_array);
+
+            /*
+            CFStringRef cert_name = SecCertificateCopySubjectSummary(cert);
+            char cert_name_buffer[1024];
+            require(CFStringGetFileSystemRepresentation(cert_name,
+                cert_name_buffer, sizeof(cert_name_buffer)), out);
+            fprintf(stderr, "cert name: %s\n", cert_name_buffer);
+            CFRelease(trust);
+            */
+        } else if (ortn == errSSLClientCertRequested) {
+            require_string(!got_client_cert_req, out, "second client cert req");
+            require_string(got_server_auth, out, "didn't get server auth first");
+            got_client_cert_req = true;
+
+            /* set client cert */
+            require_string(!ssl->is_server, out, "errSSLClientCertRequested while running server");
+            require_string(!ssl->dh_anonymous, out, "errSSLClientCertRequested while running anon DH");
+
+            CFArrayRef DNs = NULL;
+            require_noerr(SSLCopyDistinguishedNames    (ctx, &DNs), out);
+            require(DNs, out);
+            CFRelease(DNs);
+
+            require_string(ssl->client_side_auth, out, "errSSLClientCertRequested in run not testing that");
+            require_noerr(SSLSetCertificate(ctx, ssl->certs), out);
+        }
+    } while (ortn == errSSLWouldBlock
+        || ortn == errSSLServerAuthCompleted
+        || ortn == errSSLClientCertRequested);
+    require_noerr_action_quiet(ortn, out,
+        fprintf(stderr, "Fell out of SSLHandshake with error: %d\n", (int)ortn));
+
+    if (!ssl->is_server && !ssl->dh_anonymous && !ssl->is_session_resume) {
+        require_string(got_server_auth, out, "never got server auth");
+        if (ssl->client_side_auth)
+            require_string(got_client_cert_req, out, "never got client cert req");
+    }
+    //uint64_t elapsed = mach_absolute_time() - start;
+    //fprintf(stderr, "setr elapsed: %lld\n", elapsed);
+
+    /*
+    SSLProtocol proto = kSSLProtocolUnknown;
+    require_noerr_quiet(SSLGetNegotiatedProtocolVersion(ctx, &proto), out); */
+
+    SSLCipherSuite cipherSuite;
+    require_noerr_quiet(ortn = SSLGetNegotiatedCipher(ctx, &cipherSuite), out);
+    //fprintf(stderr, "st negotiated %s\n", sslcipher_itoa(cipherSuite));
+
+       Boolean sessionWasResumed = false;
+    uint8_t session_id_data[MAX_SESSION_ID_LENGTH];
+    size_t session_id_length = sizeof(session_id_data);
+    require_noerr_quiet(ortn = SSLGetResumableSessionInfo(ctx, &sessionWasResumed, session_id_data, &session_id_length), out);
+    require_action(ssl->dh_anonymous || (ssl->is_session_resume == sessionWasResumed), out, ortn = -1);
+    // if (sessionWasResumed) fprintf(stderr, "st resumed session\n");
+    //hexdump(session_id_data, session_id_length);
+
+    unsigned char ibuf[4096], obuf[4096];
+    size_t len;
+    if (ssl->is_server) {
+        SecRandomCopyBytes(kSecRandomDefault, sizeof(obuf), obuf);
+        require_noerr_quiet(ortn = SSLWrite(ctx, obuf, sizeof(obuf), &len), out);
+        require_action_quiet(len == sizeof(obuf), out, ortn = -1);
+    }
+    require_noerr_quiet(ortn = SSLRead(ctx, ibuf, sizeof(ibuf), &len), out);
+    require_action_quiet(len == sizeof(ibuf), out, ortn = -1);
+
+    if (ssl->is_server) {
+        require_noerr(memcmp(ibuf, obuf, sizeof(ibuf)), out);
+    } else {
+        require_noerr_quiet(ortn = SSLWrite(ctx, ibuf, sizeof(ibuf), &len), out);
+        require_action_quiet(len == sizeof(ibuf), out, ortn = -1);
+    }
+
+out:
+    SSLClose(ctx);
+    SSLDisposeContext(ctx);
+    if (trust) CFRelease(trust);
+
+    pthread_exit((void *)(intptr_t)ortn);
+    return NULL;
+}
+
+
+
+static ssl_test_handle *
+ssl_test_handle_create(uint32_t session_id, bool resume, bool server, bool client_side_auth, bool dh_anonymous, bool dtls,
+    int comm, CFArrayRef certs)
+{
+    ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle));
+    if (handle) {
+        handle->session_id = session_id;
+        handle->is_session_resume = resume;
+        handle->is_server = server;
+        handle->client_side_auth = client_side_auth;
+        handle->dh_anonymous = dh_anonymous;
+        handle->comm = comm;
+        handle->certs = certs;
+        handle->handle = make_ssl_ref(server, client_side_auth, dh_anonymous, dtls, comm, certs);
+    }
+    return handle;
+}
+
+static void
+tests(void)
+{
+    pthread_t client_thread, server_thread;
+    CFArrayRef server_certs = server_chain();
+    ok(server_certs, "got server certs");
+
+#if 0
+    int i=0, j=1, k=1; {
+#else
+    int d,i,k,l;
+    for (d=0;d<2; d++)  /* dtls or not dtls */
+    for (k=0; k<2; k++)
+    for (i=0; ciphers[i].cipher != (SSLCipherSuite)(-1); i++)
+    for (l = 0; l<2; l++) {
+#endif
+        SKIP: {
+            skip("ST doesn't support resumption", 1, l != 1);
+
+            int sp[2];
+            if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) exit(errno);
+
+            ssl_test_handle *server, *client;
+
+            bool client_side_auth = (k);
+
+            uint32_t session_id = (k+1) << 16 | 1 << 8 | (i+1);
+            //fprintf(stderr, "session_id: %d\n", session_id);
+            server = ssl_test_handle_create(session_id, (l == 1), true /*server*/,
+                client_side_auth, ciphers[i].dh_anonymous, d,
+                sp[0], server_certs);
+            client = ssl_test_handle_create(session_id, (l == 1), false/*client*/,
+                client_side_auth, ciphers[i].dh_anonymous, d,
+                sp[1], server_certs);
+
+            require_noerr(SSLSetPeerID(server->handle, &session_id, sizeof(session_id)), out);
+            require_noerr(SSLSetPeerID(client->handle, &session_id, sizeof(session_id)), out);
+
+            /* set fixed cipher on client and server */
+            require_noerr(SSLSetEnabledCiphers(client->handle, &ciphers[i].cipher, 1), out);
+            require_noerr(SSLSetEnabledCiphers(server->handle, &ciphers[i].cipher, 1), out);
+
+            char test_description[1024];
+            snprintf(test_description, sizeof(test_description),
+                     "%40s ADH:%d CSA:%d DTLS:%d",
+                     ciphers[i].name,
+                     server->dh_anonymous,
+                     server->client_side_auth,
+                     d);
+
+            printf("Echo test: %s\n", test_description);
+
+            pthread_create(&client_thread, NULL, securetransport_ssl_thread, client);
+            pthread_create(&server_thread, NULL, securetransport_ssl_thread, server);
+
+            int server_err, client_err;
+            pthread_join(client_thread, (void*)&client_err);
+            pthread_join(server_thread, (void*)&server_err);
+
+            ok(!server_err && !client_err, "%40s ADH:%d CSA:%d DTLS:%d",
+               ciphers[i].name,
+               server->dh_anonymous,
+               server->client_side_auth,
+               d);
+        out:
+            close(sp[0]);
+            close(sp[1]);
+        }
+    } /* all configs */
+
+    CFRelease(server_certs);
+
+}
+
+int ssl_39_echo(int argc, char *const *argv)
+{
+    plan_tests(2 * 2 * 2 * 3 * (ciphers_len-1)/* client auth on/off * #configs * #ciphers */
+                + 1 /*cert*/);
+
+
+    tests();
+
+    return 0;
+}
+
+#endif
+
+/*
+TODO: count errSSLWouldBlock
+TODO: skip tests that don't matter: client_auth and anonymous dh
+TODO: we seem to only be negotiating tls - force a round of sslv3
+TODO: allow secure transport to also defer client side auth to client
+TODO: make sure anonymous dh is never selected if not expicitly enabled
+TODO: make sure DHE is not available if not explicitly enabled and no parameters
+      are set
+TODO: resumable sessions
+*/
diff --git a/libsecurity_ssl/regressions/ssl-40-clientauth.c b/libsecurity_ssl/regressions/ssl-40-clientauth.c
new file mode 100644 (file)
index 0000000..5ad1f00
--- /dev/null
@@ -0,0 +1,517 @@
+/*
+ *  ssl-40-clientauth.c
+ *  Security
+ *
+ *  Copyright (c) 2008-2010 Apple Inc. All Rights Reserved.
+ *
+ */
+
+
+/* This test is only supported for iOS */
+
+#include <TargetConditionals.h>
+
+#if TARGET_OS_IPHONE
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecKey.h>
+#include <Security/SecItem.h>
+#include <Security/SecIdentity.h>
+#include <Security/SecPolicy.h>
+#include <Security/SecTrust.h>
+#include <Security/SecureTransport.h>
+#include <utilities/array_size.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#if TARGET_OS_IPHONE
+#include <Security/SecRSAKey.h>
+#endif
+
+#include "ssl_regressions.h"
+
+#define CFReleaseNull(CF) { CFTypeRef _cf = (CF); if (_cf) {  (CF) = NULL; CFRelease(_cf); } }
+
+/*
+   Bag Attributes
+friendlyName: uranusLeaf
+localKeyID: 46 E0 8A 05 63 4D 17 3F CA A4 AA B6 5A DA CF BA 84 22 7C 23
+subject=/CN=uranusLeaf/emailAddress=uranus@uranus.com
+issuer=/CN=plutoCA/emailAddress=pluto@pluto.com
+ */
+static const uint8_t _c1[] = {
+    0x30, 0x82, 0x02, 0xe0, 0x30, 0x82, 0x01, 0xc8,
+    0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x02,
+    0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+    0xf7, 0x0d, 0x01, 0x01, 0x05, 0x30, 0x32, 0x31,
+    0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03,
+    0x0c, 0x07, 0x70, 0x6c, 0x75, 0x74, 0x6f, 0x43,
+    0x41, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x09, 0x2a,
+    0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01,
+    0x0c, 0x0f, 0x70, 0x6c, 0x75, 0x74, 0x6f, 0x40,
+    0x70, 0x6c, 0x75, 0x74, 0x6f, 0x2e, 0x63, 0x6f,
+    0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x35, 0x31,
+    0x32, 0x31, 0x37, 0x30, 0x30, 0x30, 0x34, 0x32,
+    0x35, 0x5a, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x32,
+    0x31, 0x37, 0x30, 0x30, 0x30, 0x34, 0x32, 0x35,
+    0x5a, 0x30, 0x37, 0x31, 0x13, 0x30, 0x11, 0x06,
+    0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x75, 0x72,
+    0x61, 0x6e, 0x75, 0x73, 0x4c, 0x65, 0x61, 0x66,
+    0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86,
+    0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x0c,
+    0x11, 0x75, 0x72, 0x61, 0x6e, 0x75, 0x73, 0x40,
+    0x75, 0x72, 0x61, 0x6e, 0x75, 0x73, 0x2e, 0x63,
+    0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
+    0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+    0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
+    0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82,
+    0x01, 0x01, 0x00, 0xa6, 0x82, 0x8e, 0xc6, 0x7e,
+    0xc9, 0x8c, 0x99, 0x6f, 0xb0, 0x62, 0x32, 0x35,
+    0xe7, 0xdb, 0xff, 0x34, 0x84, 0xdc, 0x72, 0xa8,
+    0xef, 0x22, 0x6f, 0x93, 0x63, 0x64, 0x80, 0x80,
+    0x5d, 0x50, 0x7e, 0xb4, 0x2e, 0x1b, 0x93, 0x93,
+    0x49, 0xca, 0xae, 0xcd, 0x34, 0x44, 0x4b, 0xd7,
+    0xfa, 0x9f, 0x3c, 0xfc, 0x9e, 0x65, 0xa9, 0xfb,
+    0x5e, 0x5d, 0x18, 0xa3, 0xf8, 0xb0, 0x08, 0xac,
+    0x8f, 0xfd, 0x03, 0xcb, 0xbd, 0x7f, 0xa0, 0x2a,
+    0xa6, 0xea, 0xca, 0xa3, 0x24, 0xef, 0x7c, 0xc3,
+    0xeb, 0x95, 0xcb, 0x90, 0x3f, 0x5e, 0xde, 0x78,
+    0xf2, 0x3d, 0x32, 0x72, 0xdb, 0x33, 0x6e, 0x9b,
+    0x52, 0x9f, 0x0c, 0x60, 0x4a, 0x24, 0xa1, 0xf6,
+    0x3b, 0x80, 0xbd, 0xa1, 0xdc, 0x40, 0x03, 0xe7,
+    0xa0, 0x59, 0x1f, 0xdb, 0xb4, 0xed, 0x57, 0xdc,
+    0x74, 0x0d, 0x99, 0x5a, 0x12, 0x74, 0x64, 0xaa,
+    0xb6, 0xa5, 0x96, 0x75, 0xf9, 0x42, 0x43, 0xe2,
+    0x52, 0xc2, 0x57, 0x23, 0x75, 0xd7, 0xa9, 0x4f,
+    0x07, 0x32, 0x99, 0xbd, 0x3d, 0x44, 0xbd, 0x04,
+    0x62, 0xe5, 0xb7, 0x2c, 0x0c, 0x11, 0xc5, 0xb2,
+    0x2e, 0xc4, 0x12, 0x1d, 0x7f, 0x42, 0x1e, 0x71,
+    0xaf, 0x39, 0x2b, 0x78, 0x47, 0x92, 0x23, 0x44,
+    0xef, 0xe3, 0xc1, 0x47, 0x69, 0x5a, 0xf1, 0x48,
+    0xaa, 0x37, 0xa4, 0x94, 0x6b, 0x96, 0xe5, 0x4b,
+    0xfd, 0x05, 0xc7, 0x9c, 0xcc, 0x38, 0xd1, 0x47,
+    0x85, 0x60, 0x7f, 0xef, 0xe9, 0x2e, 0x25, 0x08,
+    0xf8, 0x7d, 0x98, 0xdd, 0x6c, 0xeb, 0x4a, 0x32,
+    0x33, 0x44, 0x0b, 0x61, 0xb3, 0xf9, 0xae, 0x26,
+    0x41, 0xb5, 0x38, 0xdb, 0xcf, 0x13, 0x72, 0x23,
+    0x5b, 0x66, 0x20, 0x86, 0x4d, 0x24, 0xc2, 0xd4,
+    0x94, 0xde, 0xe3, 0x24, 0xb7, 0xcd, 0x75, 0x9e,
+    0x1d, 0x9f, 0xbc, 0xd0, 0x60, 0x34, 0x7d, 0xf8,
+    0xcb, 0x41, 0x39, 0x02, 0x03, 0x01, 0x00, 0x01,
+    0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+    0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,
+    0x82, 0x01, 0x01, 0x00, 0x17, 0xa5, 0x22, 0xed,
+    0xb8, 0x3e, 0x1f, 0x11, 0x99, 0xc5, 0xba, 0x28,
+    0x3e, 0x7e, 0xa6, 0xeb, 0x02, 0x81, 0x06, 0xa1,
+    0xc6, 0x80, 0xb9, 0x7e, 0x5c, 0x5a, 0x63, 0xe0,
+    0x8d, 0xeb, 0xd0, 0xec, 0x9c, 0x3a, 0x94, 0x64,
+    0x7c, 0x13, 0x54, 0x0d, 0xd6, 0xe3, 0x27, 0x88,
+    0xa6, 0xd2, 0x4b, 0x36, 0xdd, 0x2e, 0xfa, 0x94,
+    0xe5, 0x03, 0x27, 0xc9, 0xa6, 0x31, 0x02, 0xea,
+    0x40, 0x77, 0x2e, 0x93, 0xc4, 0x4d, 0xe2, 0x70,
+    0xe2, 0x67, 0x1c, 0xa8, 0x0d, 0xcd, 0x1a, 0x72,
+    0x86, 0x2c, 0xea, 0xdc, 0x7f, 0x8c, 0x49, 0x2c,
+    0xe7, 0x99, 0x13, 0xda, 0x3f, 0x58, 0x9e, 0xf5,
+    0x4d, 0x3c, 0x8c, 0x1c, 0xed, 0x85, 0xa7, 0xe2,
+    0xae, 0xda, 0x5f, 0xbe, 0x36, 0x1c, 0x9f, 0x5a,
+    0xa0, 0xdc, 0x2a, 0xc0, 0xee, 0x71, 0x07, 0x26,
+    0x8b, 0xe8, 0x8a, 0xf8, 0x2d, 0x36, 0x78, 0xc9,
+    0x79, 0xfa, 0xbe, 0x98, 0x59, 0x95, 0x12, 0x24,
+    0xf1, 0xda, 0x20, 0xc7, 0x78, 0xf9, 0x7c, 0x6a,
+    0x24, 0x43, 0x82, 0xa8, 0x0f, 0xb1, 0x7d, 0x94,
+    0xaa, 0x30, 0x35, 0xe5, 0x69, 0xdc, 0x0a, 0x0e,
+    0xaf, 0x10, 0x5e, 0x1a, 0x81, 0x50, 0x5c, 0x7e,
+    0x24, 0xb3, 0x07, 0x65, 0x4b, 0xc1, 0x7e, 0xc6,
+    0x38, 0xdb, 0xd3, 0x6a, 0xf0, 0xd8, 0x85, 0x61,
+    0x9a, 0x9f, 0xfe, 0x02, 0x46, 0x29, 0xb2, 0x9a,
+    0xe2, 0x04, 0xe7, 0x72, 0xcc, 0x87, 0x46, 0xba,
+    0x7d, 0xa8, 0xf9, 0xd0, 0x0f, 0x29, 0xfc, 0xfd,
+    0xd1, 0xd0, 0x7f, 0x36, 0xc1, 0xd8, 0x7d, 0x88,
+    0x03, 0x62, 0xf5, 0x8c, 0x00, 0xb5, 0xc2, 0x81,
+    0x44, 0x67, 0x58, 0x11, 0xb4, 0x3a, 0xbb, 0xd1,
+    0x8c, 0x94, 0x20, 0x60, 0xea, 0xa0, 0xac, 0xc1,
+    0xf1, 0x08, 0x54, 0xb8, 0xf6, 0x5e, 0xac, 0xf1,
+    0xec, 0x78, 0x69, 0x9d, 0x7e, 0x4d, 0x06, 0x3b,
+    0x9b, 0x78, 0x78, 0x10
+};
+
+/*
+   Bag Attributes
+friendlyName: uranusLeaf
+localKeyID: 46 E0 8A 05 63 4D 17 3F CA A4 AA B6 5A DA CF BA 84 22 7C 23
+Key Attributes: <No Attributes>
+ */
+static const uint8_t _k1[] = {
+    0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02,
+    0x82, 0x01, 0x01, 0x00, 0xa6, 0x82, 0x8e, 0xc6,
+    0x7e, 0xc9, 0x8c, 0x99, 0x6f, 0xb0, 0x62, 0x32,
+    0x35, 0xe7, 0xdb, 0xff, 0x34, 0x84, 0xdc, 0x72,
+    0xa8, 0xef, 0x22, 0x6f, 0x93, 0x63, 0x64, 0x80,
+    0x80, 0x5d, 0x50, 0x7e, 0xb4, 0x2e, 0x1b, 0x93,
+    0x93, 0x49, 0xca, 0xae, 0xcd, 0x34, 0x44, 0x4b,
+    0xd7, 0xfa, 0x9f, 0x3c, 0xfc, 0x9e, 0x65, 0xa9,
+    0xfb, 0x5e, 0x5d, 0x18, 0xa3, 0xf8, 0xb0, 0x08,
+    0xac, 0x8f, 0xfd, 0x03, 0xcb, 0xbd, 0x7f, 0xa0,
+    0x2a, 0xa6, 0xea, 0xca, 0xa3, 0x24, 0xef, 0x7c,
+    0xc3, 0xeb, 0x95, 0xcb, 0x90, 0x3f, 0x5e, 0xde,
+    0x78, 0xf2, 0x3d, 0x32, 0x72, 0xdb, 0x33, 0x6e,
+    0x9b, 0x52, 0x9f, 0x0c, 0x60, 0x4a, 0x24, 0xa1,
+    0xf6, 0x3b, 0x80, 0xbd, 0xa1, 0xdc, 0x40, 0x03,
+    0xe7, 0xa0, 0x59, 0x1f, 0xdb, 0xb4, 0xed, 0x57,
+    0xdc, 0x74, 0x0d, 0x99, 0x5a, 0x12, 0x74, 0x64,
+    0xaa, 0xb6, 0xa5, 0x96, 0x75, 0xf9, 0x42, 0x43,
+    0xe2, 0x52, 0xc2, 0x57, 0x23, 0x75, 0xd7, 0xa9,
+    0x4f, 0x07, 0x32, 0x99, 0xbd, 0x3d, 0x44, 0xbd,
+    0x04, 0x62, 0xe5, 0xb7, 0x2c, 0x0c, 0x11, 0xc5,
+    0xb2, 0x2e, 0xc4, 0x12, 0x1d, 0x7f, 0x42, 0x1e,
+    0x71, 0xaf, 0x39, 0x2b, 0x78, 0x47, 0x92, 0x23,
+    0x44, 0xef, 0xe3, 0xc1, 0x47, 0x69, 0x5a, 0xf1,
+    0x48, 0xaa, 0x37, 0xa4, 0x94, 0x6b, 0x96, 0xe5,
+    0x4b, 0xfd, 0x05, 0xc7, 0x9c, 0xcc, 0x38, 0xd1,
+    0x47, 0x85, 0x60, 0x7f, 0xef, 0xe9, 0x2e, 0x25,
+    0x08, 0xf8, 0x7d, 0x98, 0xdd, 0x6c, 0xeb, 0x4a,
+    0x32, 0x33, 0x44, 0x0b, 0x61, 0xb3, 0xf9, 0xae,
+    0x26, 0x41, 0xb5, 0x38, 0xdb, 0xcf, 0x13, 0x72,
+    0x23, 0x5b, 0x66, 0x20, 0x86, 0x4d, 0x24, 0xc2,
+    0xd4, 0x94, 0xde, 0xe3, 0x24, 0xb7, 0xcd, 0x75,
+    0x9e, 0x1d, 0x9f, 0xbc, 0xd0, 0x60, 0x34, 0x7d,
+    0xf8, 0xcb, 0x41, 0x39, 0x02, 0x03, 0x01, 0x00,
+    0x01, 0x02, 0x82, 0x01, 0x00, 0x4d, 0x27, 0xf2,
+    0x40, 0xc8, 0x3f, 0x5c, 0x87, 0x3c, 0xd9, 0xde,
+    0xa6, 0xa5, 0x93, 0xea, 0xbd, 0x36, 0xf8, 0xd9,
+    0xad, 0xc7, 0xda, 0x07, 0x7a, 0xec, 0x31, 0x02,
+    0x41, 0x09, 0x3a, 0x34, 0x32, 0x82, 0x0b, 0x5b,
+    0x7b, 0xe6, 0xa4, 0x2a, 0xe7, 0x14, 0xef, 0x43,
+    0x36, 0x61, 0xbe, 0x20, 0x4b, 0x82, 0x43, 0x63,
+    0x98, 0x80, 0x82, 0x19, 0x61, 0x71, 0x99, 0xaa,
+    0xf8, 0x59, 0xfd, 0xde, 0xa0, 0x03, 0xa8, 0xab,
+    0x9a, 0xec, 0x28, 0xac, 0x63, 0x79, 0x75, 0x84,
+    0x03, 0xac, 0x45, 0x5e, 0x04, 0x15, 0xb3, 0x47,
+    0xa2, 0x8f, 0x28, 0xb0, 0x72, 0xd0, 0x06, 0x02,
+    0xaf, 0x1e, 0x0a, 0x0a, 0xe9, 0x11, 0x35, 0x4a,
+    0x04, 0x42, 0xb5, 0x0f, 0xd2, 0xcf, 0x4d, 0xdf,
+    0xdb, 0xef, 0x58, 0xbd, 0xf3, 0xa5, 0x3b, 0x11,
+    0x3f, 0xc5, 0x47, 0x81, 0x85, 0xad, 0xd7, 0x1f,
+    0x58, 0x06, 0x42, 0xdc, 0x37, 0x3c, 0xdb, 0x98,
+    0x33, 0xa1, 0xc6, 0x80, 0x07, 0xe0, 0x2b, 0xc5,
+    0xf5, 0x60, 0x35, 0x6a, 0xa2, 0x06, 0x40, 0x4a,
+    0xac, 0x64, 0x02, 0x58, 0x4d, 0x07, 0xe3, 0x69,
+    0xd7, 0xe0, 0x8f, 0xb5, 0xf4, 0xbc, 0xfa, 0xab,
+    0x1a, 0xb0, 0xfa, 0x29, 0xf8, 0xca, 0xde, 0x78,
+    0xf0, 0x89, 0xe2, 0xf9, 0xb7, 0x68, 0x5b, 0x0e,
+    0xdc, 0x4e, 0x8a, 0x56, 0x8d, 0x33, 0x20, 0x2e,
+    0xed, 0x2e, 0xab, 0x6f, 0xba, 0x77, 0xef, 0xe6,
+    0x12, 0x62, 0x49, 0x9e, 0x87, 0x76, 0x1c, 0x1e,
+    0xf4, 0x0e, 0x9e, 0x78, 0x98, 0x91, 0x1a, 0xe3,
+    0xb4, 0x51, 0x4b, 0x8c, 0x2f, 0x08, 0x97, 0x8f,
+    0xf9, 0x68, 0x61, 0x40, 0xcd, 0xb6, 0x10, 0xb4,
+    0xfb, 0x75, 0xb4, 0x20, 0xc1, 0x5a, 0xda, 0x64,
+    0xfd, 0x51, 0x06, 0x85, 0x9a, 0x9e, 0x5d, 0x82,
+    0x14, 0xd4, 0x41, 0x4e, 0x75, 0x10, 0xb5, 0x7b,
+    0xd0, 0x4c, 0xd1, 0x00, 0x01, 0x02, 0x81, 0x81,
+    0x00, 0xcf, 0x8e, 0x68, 0x04, 0x67, 0x09, 0xa9,
+    0x6e, 0xff, 0x11, 0x8c, 0xe5, 0xe4, 0x16, 0xdd,
+    0xb6, 0xa6, 0x55, 0xca, 0x4b, 0x0b, 0xbb, 0xb7,
+    0xf5, 0xe5, 0x73, 0xf3, 0x24, 0x84, 0x29, 0xb2,
+    0xc3, 0xbc, 0x7f, 0x2b, 0x4a, 0xc7, 0xdf, 0x46,
+    0x8e, 0xe1, 0x35, 0x69, 0x1b, 0x8e, 0x9f, 0x6b,
+    0x4d, 0xf3, 0x65, 0xae, 0x3d, 0x87, 0x2b, 0xc9,
+    0xf0, 0x8c, 0xf2, 0x88, 0x2f, 0x1b, 0x79, 0x80,
+    0xd2, 0xb2, 0x64, 0x0a, 0xcc, 0x66, 0x69, 0x4c,
+    0xa1, 0x85, 0xc4, 0x6a, 0x94, 0x46, 0x70, 0x69,
+    0xbc, 0x8c, 0x1c, 0x62, 0x65, 0x4d, 0x68, 0xcc,
+    0xe3, 0x3c, 0x6c, 0xe7, 0xd1, 0x09, 0xed, 0xdd,
+    0x42, 0x10, 0x11, 0x6b, 0xdd, 0x7c, 0xe3, 0xe1,
+    0x3b, 0x3b, 0x0d, 0x01, 0x6d, 0xca, 0x2f, 0x4b,
+    0x45, 0x5e, 0x76, 0x5d, 0x5c, 0x6f, 0x53, 0xa4,
+    0x38, 0x74, 0x75, 0x94, 0x2c, 0xda, 0xf8, 0xa6,
+    0x01, 0x02, 0x81, 0x81, 0x00, 0xcd, 0x5f, 0x9d,
+    0x6c, 0x94, 0xf6, 0x44, 0x37, 0x72, 0xfe, 0xcf,
+    0xbe, 0x82, 0x96, 0x24, 0x22, 0x12, 0x07, 0x6f,
+    0xd1, 0x57, 0x7b, 0xc7, 0x63, 0x20, 0xf5, 0x93,
+    0x79, 0x70, 0x0b, 0xe4, 0x38, 0x19, 0x62, 0x7b,
+    0x89, 0x3e, 0x45, 0xdf, 0xd6, 0xae, 0x9d, 0x0d,
+    0xa8, 0x76, 0xc1, 0xbd, 0x04, 0x2b, 0xaa, 0x30,
+    0x6a, 0xac, 0x65, 0x91, 0x61, 0xf0, 0xf8, 0x5d,
+    0xa3, 0x53, 0xa4, 0xfb, 0x99, 0xac, 0x46, 0x7a,
+    0x12, 0x4b, 0xf7, 0xa7, 0x48, 0x41, 0x61, 0x48,
+    0x26, 0x5c, 0x68, 0x2f, 0x73, 0x91, 0xe4, 0x74,
+    0xcd, 0xc9, 0x8b, 0xe7, 0x26, 0xe4, 0x35, 0xde,
+    0x32, 0x6b, 0x24, 0x49, 0xf2, 0x04, 0x67, 0x3d,
+    0x31, 0x8f, 0x22, 0xe5, 0x49, 0xae, 0x49, 0x94,
+    0xb3, 0x45, 0x2b, 0xed, 0x6f, 0x9c, 0xc7, 0x80,
+    0xf0, 0x42, 0xd5, 0x8f, 0x27, 0xd6, 0xd6, 0x49,
+    0xf2, 0x16, 0xcc, 0x4b, 0x39, 0x02, 0x81, 0x81,
+    0x00, 0xbb, 0xb7, 0xd7, 0x59, 0xcb, 0xfb, 0x10,
+    0x13, 0xc4, 0x7b, 0x92, 0x0c, 0x45, 0xcb, 0x6c,
+    0x81, 0x0a, 0x55, 0x63, 0x1d, 0x96, 0xa2, 0x13,
+    0xd2, 0x40, 0xd1, 0x2a, 0xa1, 0xe7, 0x2a, 0x73,
+    0x74, 0xd6, 0x61, 0xc9, 0xbc, 0xdb, 0xa2, 0x93,
+    0x85, 0x1c, 0x28, 0x9b, 0x44, 0x82, 0x2c, 0xaa,
+    0xf7, 0x18, 0x60, 0xe9, 0x42, 0xda, 0xa2, 0xff,
+    0x04, 0x21, 0xe6, 0x24, 0xc7, 0x3e, 0x39, 0x19,
+    0x0a, 0xf6, 0xae, 0xc6, 0x99, 0x71, 0x32, 0x61,
+    0x4d, 0x60, 0xd7, 0x71, 0x71, 0x63, 0x77, 0xbe,
+    0x19, 0xfa, 0x3a, 0x9d, 0xbf, 0x73, 0x50, 0x8a,
+    0xa6, 0x26, 0x7b, 0x74, 0xfa, 0x39, 0xd9, 0xb9,
+    0x18, 0x4b, 0xc2, 0x05, 0xe5, 0x8f, 0x53, 0xe6,
+    0xdc, 0x14, 0x1f, 0x42, 0x20, 0x93, 0x11, 0x4d,
+    0x29, 0x93, 0x32, 0xc8, 0x63, 0x96, 0x88, 0x76,
+    0x69, 0x5c, 0xe3, 0x0e, 0xbd, 0xb6, 0xd9, 0xd6,
+    0x01, 0x02, 0x81, 0x80, 0x62, 0xa2, 0xed, 0x84,
+    0xdc, 0xf6, 0x7a, 0x44, 0xf7, 0x62, 0x12, 0x7c,
+    0xb9, 0x53, 0x4a, 0xff, 0x62, 0x11, 0x58, 0x4e,
+    0xfe, 0xe9, 0x60, 0x15, 0xe8, 0x1a, 0x8a, 0x3d,
+    0xe4, 0xe6, 0x91, 0x31, 0xb0, 0x5f, 0x70, 0x5d,
+    0xb6, 0x1e, 0xf1, 0x26, 0xb6, 0xae, 0x8f, 0x84,
+    0xbd, 0xa4, 0xc7, 0x17, 0x5d, 0xb1, 0x5b, 0x97,
+    0xa0, 0x3d, 0x17, 0xda, 0x26, 0x55, 0xe3, 0x03,
+    0x32, 0x85, 0x26, 0xa1, 0xe3, 0xef, 0xe5, 0x69,
+    0x2c, 0x3b, 0x41, 0x88, 0x9e, 0x7e, 0x0e, 0x9c,
+    0xfd, 0xfc, 0xbb, 0xed, 0x91, 0xc0, 0x5b, 0xa9,
+    0x0a, 0x87, 0xba, 0xf9, 0x1e, 0xda, 0x10, 0x61,
+    0xbe, 0xbb, 0xab, 0x18, 0x25, 0xad, 0x3f, 0xe2,
+    0xb1, 0x90, 0x5c, 0xf7, 0x4a, 0x51, 0xe4, 0xad,
+    0x45, 0x27, 0x97, 0xdd, 0xe7, 0x3a, 0x9a, 0x5e,
+    0xca, 0x7a, 0xaf, 0x4a, 0xbf, 0x10, 0x24, 0x6b,
+    0xb5, 0x2f, 0x61, 0x61, 0x02, 0x81, 0x81, 0x00,
+    0x85, 0x7c, 0x78, 0xa5, 0x11, 0xdf, 0xc3, 0x6a,
+    0x38, 0x48, 0xfa, 0x7e, 0x48, 0xf0, 0x5a, 0x58,
+    0xe2, 0xc5, 0x83, 0x4e, 0x38, 0x3f, 0x4a, 0x2b,
+    0x07, 0x57, 0x31, 0xe7, 0xbe, 0x50, 0xb1, 0xbb,
+    0x24, 0xf3, 0x3d, 0x8b, 0x53, 0xb7, 0xd1, 0x47,
+    0x72, 0x5e, 0xd5, 0xd6, 0x4c, 0xce, 0x2c, 0x46,
+    0x61, 0x9a, 0xaa, 0xc3, 0x0e, 0xd4, 0x23, 0x2c,
+    0xdd, 0xf5, 0xb7, 0xad, 0x38, 0x52, 0x17, 0xc4,
+    0x16, 0xbb, 0xda, 0x1c, 0x61, 0xb1, 0xca, 0x8d,
+    0xb2, 0xa0, 0xbe, 0x4f, 0x3d, 0x19, 0x0e, 0xe0,
+    0x0e, 0x52, 0xad, 0xf3, 0xaf, 0xd9, 0xcc, 0x78,
+    0xc2, 0xb1, 0x5e, 0x05, 0x5e, 0xf2, 0x27, 0x84,
+    0x15, 0xe4, 0x8f, 0xca, 0xc5, 0x92, 0x43, 0xe0,
+    0x24, 0x8d, 0xf2, 0x5d, 0x55, 0xcc, 0x9d, 0x2f,
+    0xa9, 0xf6, 0x9b, 0x67, 0x6a, 0x87, 0x74, 0x36,
+    0x34, 0x7c, 0xd4, 0x9d, 0xff, 0xad, 0xee, 0x69
+};
+
+static const uint8_t _k1_digest[] = {
+    0x46, 0xE0, 0x8A, 0x05, 0x63, 0x4D, 0x17, 0x3F,
+    0xCA, 0xA4, 0xAA, 0xB6, 0x5A, 0xDA, 0xCF, 0xBA,
+    0x84, 0x22, 0x7C, 0x23
+};
+
+/* Create and identity and try to retrieve it. */
+static void AddIdentityToKeychain(void)
+{
+    SecCertificateRef cert = NULL;
+    SecKeyRef privKey = NULL;
+    //SecIdentityRef identity = NULL;
+
+    isnt(cert = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)),
+            NULL, "create certificate");
+
+#if TARGET_OS_IPHONE
+    privKey = SecKeyCreateRSAPrivateKey(NULL, _k1, sizeof(_k1),
+                                        kSecKeyEncodingPkcs1);
+#else
+#warning TODO
+    privKey = NULL;
+#endif
+
+    isnt(privKey, NULL, "create private key");
+
+    const void *certkeys[] = {
+        kSecValueRef
+    };
+    const void *certvalues[] = {
+        cert
+    };
+    CFDictionaryRef certDict = CFDictionaryCreate(NULL, certkeys, certvalues,
+            array_size(certkeys), NULL, NULL);
+    ok_status(SecItemAdd(certDict, NULL), "add certificate");
+    CFReleaseNull(certDict);
+    CFReleaseNull(cert);
+
+    const void *privkeys[] = {
+        kSecValueRef
+    };
+    const void *privvalues[] = {
+        privKey
+    };
+    CFDictionaryRef privDict = CFDictionaryCreate(NULL, privkeys, privvalues,
+            array_size(privkeys), NULL, NULL);
+    ok_status(SecItemAdd(privDict, NULL), "add private key");
+    CFReleaseNull(privDict);
+    CFReleaseNull(privKey);
+}
+
+static void DeleteIdentityFromKeychain(void)
+{
+    SecCertificateRef cert = NULL;
+    SecKeyRef privKey = NULL;
+    //SecIdentityRef identity = NULL;
+
+    isnt(cert = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)),
+         NULL, "create certificate");
+#if TARGET_OS_IPHONE
+    privKey = SecKeyCreateRSAPrivateKey(NULL, _k1, sizeof(_k1),
+                                        kSecKeyEncodingPkcs1);
+#else
+#warning TODO
+    privKey = NULL;
+#endif
+    isnt(privKey, NULL, "create private key");
+
+    const void *certkeys[] = {
+        kSecValueRef
+    };
+    const void *certvalues[] = {
+        cert
+    };
+    CFDictionaryRef certDict = CFDictionaryCreate(NULL, certkeys, certvalues,
+                                                  array_size(certkeys), NULL, NULL);
+    ok_status(SecItemDelete(certDict), "delete certificate");
+    CFReleaseNull(certDict);
+    CFReleaseNull(cert);
+
+    const void *privkeys[] = {
+        kSecValueRef
+    };
+    const void *privvalues[] = {
+        privKey
+    };
+    CFDictionaryRef privDict = CFDictionaryCreate(NULL, privkeys, privvalues,
+                                                  array_size(privkeys), NULL, NULL);
+    ok_status(SecItemDelete(privDict), "delete private key");
+    CFReleaseNull(privDict);
+    CFReleaseNull(privKey);
+}
+
+
+static OSStatus
+EAPSecIdentityListCreate(CFArrayRef * ret_array)
+{
+    const void *               keys[] = {
+       kSecClass,
+       kSecReturnRef,
+       kSecMatchLimit
+    };
+    CFDictionaryRef            query;
+    CFTypeRef                  results = NULL;
+    OSStatus                   status = errSecSuccess;
+    const void *               values[] = {
+       kSecClassIdentity,
+       kCFBooleanTrue,
+       kSecMatchLimitAll
+    };
+
+    query = CFDictionaryCreate(NULL, keys, values,
+                              array_size(keys),
+                              &kCFTypeDictionaryKeyCallBacks,
+                              &kCFTypeDictionaryValueCallBacks);
+    ok_status(status = SecItemCopyMatching(query, &results), "SecItemCopyMatching");
+    CFReleaseNull(query);
+    if (status == errSecSuccess) {
+       *ret_array = results;
+    }
+    return (status);
+}
+
+static OSStatus
+_EAPSecIdentityCreateCertificateTrustChain(SecIdentityRef identity,
+                                          CFArrayRef * ret_chain)
+{
+    SecCertificateRef          cert = NULL;
+    CFArrayRef                         certs;
+    SecPolicyRef               policy = NULL;
+    OSStatus                   status;
+    SecTrustRef                trust = NULL;
+    SecTrustResultType                 trust_result;
+
+    *ret_chain = NULL;
+    ok(policy = SecPolicyCreateBasicX509(), "SecPolicyCreateBasicX509");
+    ok_status(status = SecIdentityCopyCertificate(identity, &cert), "SecIdentityCopyCertificate");
+    certs = CFArrayCreate(NULL, (const void **)&cert,
+                         1, &kCFTypeArrayCallBacks);
+    CFReleaseNull(cert);
+    ok_status(status = SecTrustCreateWithCertificates(certs, policy, &trust),
+        "SecTrustCreateWithCertificates");
+    CFReleaseNull(certs);
+    ok_status(status = SecTrustEvaluate(trust, &trust_result), "SecTrustEvaluate");
+    {
+       CFMutableArrayRef       array;
+       CFIndex                 count = SecTrustGetCertificateCount(trust);
+       CFIndex                 i;
+
+       isnt(count, 0, "SecTrustGetCertificateCount is nonzero");
+       array = CFArrayCreateMutable(NULL, count, &kCFTypeArrayCallBacks);
+       for (i = 0; i < count; i++) {
+           SecCertificateRef   s;
+
+           s = SecTrustGetCertificateAtIndex(trust, i);
+           CFArrayAppendValue(array, s);
+       }
+       *ret_chain = array;
+    }
+
+    CFReleaseNull(trust);
+    CFReleaseNull(policy);
+    return (status);
+}
+
+static OSStatus
+EAPSecIdentityCreateIdentityTrustChain(SecIdentityRef identity,
+                                      CFArrayRef * ret_array)
+{
+    CFMutableArrayRef          array = NULL;
+    CFIndex                 count;
+    OSStatus                   status;
+    CFArrayRef                 trust_chain = NULL;
+
+    *ret_array = NULL;
+    ok_status(status = _EAPSecIdentityCreateCertificateTrustChain(identity,
+        &trust_chain), "_EAPSecIdentityCreateCertificateTrustChain");
+    count = CFArrayGetCount(trust_chain);
+    array = CFArrayCreateMutable(NULL, count + 1, &kCFTypeArrayCallBacks);
+    CFArrayAppendValue(array, identity); /* identity into [0] */
+    CFArrayAppendArray(array, trust_chain, CFRangeMake(0, count));
+    *ret_array = array;
+
+    CFReleaseNull(trust_chain);
+    return (status);
+}
+
+
+static void
+tests(void)
+{
+    SSLContextRef       ctx = NULL;
+    SecIdentityRef     identity;
+    CFArrayRef         list = NULL;
+    CFArrayRef         trust_chain;
+
+    AddIdentityToKeychain();
+    EAPSecIdentityListCreate(&list);
+    identity = (SecIdentityRef)CFArrayGetValueAtIndex(list, 0);
+    is(CFGetRetainCount(identity), 1, "identity rc = 1");
+    ok_status(EAPSecIdentityCreateIdentityTrustChain(identity, &trust_chain),
+        "EAPSecIdentityCreateIdentityTrustChain");
+    ok(ctx=SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType), "SSLNewContext");
+    ok_status(SSLSetCertificate(ctx, trust_chain), "SSLSetCertificate");
+    CFReleaseNull(ctx);
+    DeleteIdentityFromKeychain();
+    CFRelease(trust_chain);
+    CFReleaseNull(list);
+}
+
+int ssl_40_clientauth(int argc, char *const *argv)
+{
+    plan_tests(19);
+
+    tests();
+
+    return 0;
+}
+
+#endif /* TARGET_OS_IPHONE */
diff --git a/libsecurity_ssl/regressions/ssl-41-clientauth.c b/libsecurity_ssl/regressions/ssl-41-clientauth.c
new file mode 100644 (file)
index 0000000..8a86d07
--- /dev/null
@@ -0,0 +1,371 @@
+/*
+ *  ssl-40-clientauth.c
+ *  Security
+ *
+ *  Copyright (c) 2008-2010 Apple Inc. All Rights Reserved.
+ *
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecIdentityPriv.h>
+#include <Security/SecureTransport.h>
+#include <utilities/array_size.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#if TARGET_OS_IPHONE
+#include <Security/SecRSAKey.h>
+#endif
+
+#include "ssl_regressions.h"
+
+#define CFReleaseSafe(CF) { CFTypeRef _cf = (CF); if (_cf) {  CFRelease(_cf); } }
+#define CFReleaseNull(CF) { CFTypeRef _cf = (CF); if (_cf) {  (CF) = NULL; CFRelease(_cf); } }
+
+/*
+   Bag Attributes
+friendlyName: uranusLeaf
+localKeyID: 46 E0 8A 05 63 4D 17 3F CA A4 AA B6 5A DA CF BA 84 22 7C 23
+subject=/CN=uranusLeaf/emailAddress=uranus@uranus.com
+issuer=/CN=plutoCA/emailAddress=pluto@pluto.com
+ */
+static const uint8_t _c1[] = {
+    0x30, 0x82, 0x02, 0xe0, 0x30, 0x82, 0x01, 0xc8,
+    0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x02,
+    0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+    0xf7, 0x0d, 0x01, 0x01, 0x05, 0x30, 0x32, 0x31,
+    0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03,
+    0x0c, 0x07, 0x70, 0x6c, 0x75, 0x74, 0x6f, 0x43,
+    0x41, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x09, 0x2a,
+    0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01,
+    0x0c, 0x0f, 0x70, 0x6c, 0x75, 0x74, 0x6f, 0x40,
+    0x70, 0x6c, 0x75, 0x74, 0x6f, 0x2e, 0x63, 0x6f,
+    0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x35, 0x31,
+    0x32, 0x31, 0x37, 0x30, 0x30, 0x30, 0x34, 0x32,
+    0x35, 0x5a, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x32,
+    0x31, 0x37, 0x30, 0x30, 0x30, 0x34, 0x32, 0x35,
+    0x5a, 0x30, 0x37, 0x31, 0x13, 0x30, 0x11, 0x06,
+    0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x75, 0x72,
+    0x61, 0x6e, 0x75, 0x73, 0x4c, 0x65, 0x61, 0x66,
+    0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86,
+    0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x0c,
+    0x11, 0x75, 0x72, 0x61, 0x6e, 0x75, 0x73, 0x40,
+    0x75, 0x72, 0x61, 0x6e, 0x75, 0x73, 0x2e, 0x63,
+    0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
+    0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+    0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
+    0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82,
+    0x01, 0x01, 0x00, 0xa6, 0x82, 0x8e, 0xc6, 0x7e,
+    0xc9, 0x8c, 0x99, 0x6f, 0xb0, 0x62, 0x32, 0x35,
+    0xe7, 0xdb, 0xff, 0x34, 0x84, 0xdc, 0x72, 0xa8,
+    0xef, 0x22, 0x6f, 0x93, 0x63, 0x64, 0x80, 0x80,
+    0x5d, 0x50, 0x7e, 0xb4, 0x2e, 0x1b, 0x93, 0x93,
+    0x49, 0xca, 0xae, 0xcd, 0x34, 0x44, 0x4b, 0xd7,
+    0xfa, 0x9f, 0x3c, 0xfc, 0x9e, 0x65, 0xa9, 0xfb,
+    0x5e, 0x5d, 0x18, 0xa3, 0xf8, 0xb0, 0x08, 0xac,
+    0x8f, 0xfd, 0x03, 0xcb, 0xbd, 0x7f, 0xa0, 0x2a,
+    0xa6, 0xea, 0xca, 0xa3, 0x24, 0xef, 0x7c, 0xc3,
+    0xeb, 0x95, 0xcb, 0x90, 0x3f, 0x5e, 0xde, 0x78,
+    0xf2, 0x3d, 0x32, 0x72, 0xdb, 0x33, 0x6e, 0x9b,
+    0x52, 0x9f, 0x0c, 0x60, 0x4a, 0x24, 0xa1, 0xf6,
+    0x3b, 0x80, 0xbd, 0xa1, 0xdc, 0x40, 0x03, 0xe7,
+    0xa0, 0x59, 0x1f, 0xdb, 0xb4, 0xed, 0x57, 0xdc,
+    0x74, 0x0d, 0x99, 0x5a, 0x12, 0x74, 0x64, 0xaa,
+    0xb6, 0xa5, 0x96, 0x75, 0xf9, 0x42, 0x43, 0xe2,
+    0x52, 0xc2, 0x57, 0x23, 0x75, 0xd7, 0xa9, 0x4f,
+    0x07, 0x32, 0x99, 0xbd, 0x3d, 0x44, 0xbd, 0x04,
+    0x62, 0xe5, 0xb7, 0x2c, 0x0c, 0x11, 0xc5, 0xb2,
+    0x2e, 0xc4, 0x12, 0x1d, 0x7f, 0x42, 0x1e, 0x71,
+    0xaf, 0x39, 0x2b, 0x78, 0x47, 0x92, 0x23, 0x44,
+    0xef, 0xe3, 0xc1, 0x47, 0x69, 0x5a, 0xf1, 0x48,
+    0xaa, 0x37, 0xa4, 0x94, 0x6b, 0x96, 0xe5, 0x4b,
+    0xfd, 0x05, 0xc7, 0x9c, 0xcc, 0x38, 0xd1, 0x47,
+    0x85, 0x60, 0x7f, 0xef, 0xe9, 0x2e, 0x25, 0x08,
+    0xf8, 0x7d, 0x98, 0xdd, 0x6c, 0xeb, 0x4a, 0x32,
+    0x33, 0x44, 0x0b, 0x61, 0xb3, 0xf9, 0xae, 0x26,
+    0x41, 0xb5, 0x38, 0xdb, 0xcf, 0x13, 0x72, 0x23,
+    0x5b, 0x66, 0x20, 0x86, 0x4d, 0x24, 0xc2, 0xd4,
+    0x94, 0xde, 0xe3, 0x24, 0xb7, 0xcd, 0x75, 0x9e,
+    0x1d, 0x9f, 0xbc, 0xd0, 0x60, 0x34, 0x7d, 0xf8,
+    0xcb, 0x41, 0x39, 0x02, 0x03, 0x01, 0x00, 0x01,
+    0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+    0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,
+    0x82, 0x01, 0x01, 0x00, 0x17, 0xa5, 0x22, 0xed,
+    0xb8, 0x3e, 0x1f, 0x11, 0x99, 0xc5, 0xba, 0x28,
+    0x3e, 0x7e, 0xa6, 0xeb, 0x02, 0x81, 0x06, 0xa1,
+    0xc6, 0x80, 0xb9, 0x7e, 0x5c, 0x5a, 0x63, 0xe0,
+    0x8d, 0xeb, 0xd0, 0xec, 0x9c, 0x3a, 0x94, 0x64,
+    0x7c, 0x13, 0x54, 0x0d, 0xd6, 0xe3, 0x27, 0x88,
+    0xa6, 0xd2, 0x4b, 0x36, 0xdd, 0x2e, 0xfa, 0x94,
+    0xe5, 0x03, 0x27, 0xc9, 0xa6, 0x31, 0x02, 0xea,
+    0x40, 0x77, 0x2e, 0x93, 0xc4, 0x4d, 0xe2, 0x70,
+    0xe2, 0x67, 0x1c, 0xa8, 0x0d, 0xcd, 0x1a, 0x72,
+    0x86, 0x2c, 0xea, 0xdc, 0x7f, 0x8c, 0x49, 0x2c,
+    0xe7, 0x99, 0x13, 0xda, 0x3f, 0x58, 0x9e, 0xf5,
+    0x4d, 0x3c, 0x8c, 0x1c, 0xed, 0x85, 0xa7, 0xe2,
+    0xae, 0xda, 0x5f, 0xbe, 0x36, 0x1c, 0x9f, 0x5a,
+    0xa0, 0xdc, 0x2a, 0xc0, 0xee, 0x71, 0x07, 0x26,
+    0x8b, 0xe8, 0x8a, 0xf8, 0x2d, 0x36, 0x78, 0xc9,
+    0x79, 0xfa, 0xbe, 0x98, 0x59, 0x95, 0x12, 0x24,
+    0xf1, 0xda, 0x20, 0xc7, 0x78, 0xf9, 0x7c, 0x6a,
+    0x24, 0x43, 0x82, 0xa8, 0x0f, 0xb1, 0x7d, 0x94,
+    0xaa, 0x30, 0x35, 0xe5, 0x69, 0xdc, 0x0a, 0x0e,
+    0xaf, 0x10, 0x5e, 0x1a, 0x81, 0x50, 0x5c, 0x7e,
+    0x24, 0xb3, 0x07, 0x65, 0x4b, 0xc1, 0x7e, 0xc6,
+    0x38, 0xdb, 0xd3, 0x6a, 0xf0, 0xd8, 0x85, 0x61,
+    0x9a, 0x9f, 0xfe, 0x02, 0x46, 0x29, 0xb2, 0x9a,
+    0xe2, 0x04, 0xe7, 0x72, 0xcc, 0x87, 0x46, 0xba,
+    0x7d, 0xa8, 0xf9, 0xd0, 0x0f, 0x29, 0xfc, 0xfd,
+    0xd1, 0xd0, 0x7f, 0x36, 0xc1, 0xd8, 0x7d, 0x88,
+    0x03, 0x62, 0xf5, 0x8c, 0x00, 0xb5, 0xc2, 0x81,
+    0x44, 0x67, 0x58, 0x11, 0xb4, 0x3a, 0xbb, 0xd1,
+    0x8c, 0x94, 0x20, 0x60, 0xea, 0xa0, 0xac, 0xc1,
+    0xf1, 0x08, 0x54, 0xb8, 0xf6, 0x5e, 0xac, 0xf1,
+    0xec, 0x78, 0x69, 0x9d, 0x7e, 0x4d, 0x06, 0x3b,
+    0x9b, 0x78, 0x78, 0x10
+};
+
+/*
+   Bag Attributes
+friendlyName: uranusLeaf
+localKeyID: 46 E0 8A 05 63 4D 17 3F CA A4 AA B6 5A DA CF BA 84 22 7C 23
+Key Attributes: <No Attributes>
+ */
+static const uint8_t _k1[] = {
+    0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02,
+    0x82, 0x01, 0x01, 0x00, 0xa6, 0x82, 0x8e, 0xc6,
+    0x7e, 0xc9, 0x8c, 0x99, 0x6f, 0xb0, 0x62, 0x32,
+    0x35, 0xe7, 0xdb, 0xff, 0x34, 0x84, 0xdc, 0x72,
+    0xa8, 0xef, 0x22, 0x6f, 0x93, 0x63, 0x64, 0x80,
+    0x80, 0x5d, 0x50, 0x7e, 0xb4, 0x2e, 0x1b, 0x93,
+    0x93, 0x49, 0xca, 0xae, 0xcd, 0x34, 0x44, 0x4b,
+    0xd7, 0xfa, 0x9f, 0x3c, 0xfc, 0x9e, 0x65, 0xa9,
+    0xfb, 0x5e, 0x5d, 0x18, 0xa3, 0xf8, 0xb0, 0x08,
+    0xac, 0x8f, 0xfd, 0x03, 0xcb, 0xbd, 0x7f, 0xa0,
+    0x2a, 0xa6, 0xea, 0xca, 0xa3, 0x24, 0xef, 0x7c,
+    0xc3, 0xeb, 0x95, 0xcb, 0x90, 0x3f, 0x5e, 0xde,
+    0x78, 0xf2, 0x3d, 0x32, 0x72, 0xdb, 0x33, 0x6e,
+    0x9b, 0x52, 0x9f, 0x0c, 0x60, 0x4a, 0x24, 0xa1,
+    0xf6, 0x3b, 0x80, 0xbd, 0xa1, 0xdc, 0x40, 0x03,
+    0xe7, 0xa0, 0x59, 0x1f, 0xdb, 0xb4, 0xed, 0x57,
+    0xdc, 0x74, 0x0d, 0x99, 0x5a, 0x12, 0x74, 0x64,
+    0xaa, 0xb6, 0xa5, 0x96, 0x75, 0xf9, 0x42, 0x43,
+    0xe2, 0x52, 0xc2, 0x57, 0x23, 0x75, 0xd7, 0xa9,
+    0x4f, 0x07, 0x32, 0x99, 0xbd, 0x3d, 0x44, 0xbd,
+    0x04, 0x62, 0xe5, 0xb7, 0x2c, 0x0c, 0x11, 0xc5,
+    0xb2, 0x2e, 0xc4, 0x12, 0x1d, 0x7f, 0x42, 0x1e,
+    0x71, 0xaf, 0x39, 0x2b, 0x78, 0x47, 0x92, 0x23,
+    0x44, 0xef, 0xe3, 0xc1, 0x47, 0x69, 0x5a, 0xf1,
+    0x48, 0xaa, 0x37, 0xa4, 0x94, 0x6b, 0x96, 0xe5,
+    0x4b, 0xfd, 0x05, 0xc7, 0x9c, 0xcc, 0x38, 0xd1,
+    0x47, 0x85, 0x60, 0x7f, 0xef, 0xe9, 0x2e, 0x25,
+    0x08, 0xf8, 0x7d, 0x98, 0xdd, 0x6c, 0xeb, 0x4a,
+    0x32, 0x33, 0x44, 0x0b, 0x61, 0xb3, 0xf9, 0xae,
+    0x26, 0x41, 0xb5, 0x38, 0xdb, 0xcf, 0x13, 0x72,
+    0x23, 0x5b, 0x66, 0x20, 0x86, 0x4d, 0x24, 0xc2,
+    0xd4, 0x94, 0xde, 0xe3, 0x24, 0xb7, 0xcd, 0x75,
+    0x9e, 0x1d, 0x9f, 0xbc, 0xd0, 0x60, 0x34, 0x7d,
+    0xf8, 0xcb, 0x41, 0x39, 0x02, 0x03, 0x01, 0x00,
+    0x01, 0x02, 0x82, 0x01, 0x00, 0x4d, 0x27, 0xf2,
+    0x40, 0xc8, 0x3f, 0x5c, 0x87, 0x3c, 0xd9, 0xde,
+    0xa6, 0xa5, 0x93, 0xea, 0xbd, 0x36, 0xf8, 0xd9,
+    0xad, 0xc7, 0xda, 0x07, 0x7a, 0xec, 0x31, 0x02,
+    0x41, 0x09, 0x3a, 0x34, 0x32, 0x82, 0x0b, 0x5b,
+    0x7b, 0xe6, 0xa4, 0x2a, 0xe7, 0x14, 0xef, 0x43,
+    0x36, 0x61, 0xbe, 0x20, 0x4b, 0x82, 0x43, 0x63,
+    0x98, 0x80, 0x82, 0x19, 0x61, 0x71, 0x99, 0xaa,
+    0xf8, 0x59, 0xfd, 0xde, 0xa0, 0x03, 0xa8, 0xab,
+    0x9a, 0xec, 0x28, 0xac, 0x63, 0x79, 0x75, 0x84,
+    0x03, 0xac, 0x45, 0x5e, 0x04, 0x15, 0xb3, 0x47,
+    0xa2, 0x8f, 0x28, 0xb0, 0x72, 0xd0, 0x06, 0x02,
+    0xaf, 0x1e, 0x0a, 0x0a, 0xe9, 0x11, 0x35, 0x4a,
+    0x04, 0x42, 0xb5, 0x0f, 0xd2, 0xcf, 0x4d, 0xdf,
+    0xdb, 0xef, 0x58, 0xbd, 0xf3, 0xa5, 0x3b, 0x11,
+    0x3f, 0xc5, 0x47, 0x81, 0x85, 0xad, 0xd7, 0x1f,
+    0x58, 0x06, 0x42, 0xdc, 0x37, 0x3c, 0xdb, 0x98,
+    0x33, 0xa1, 0xc6, 0x80, 0x07, 0xe0, 0x2b, 0xc5,
+    0xf5, 0x60, 0x35, 0x6a, 0xa2, 0x06, 0x40, 0x4a,
+    0xac, 0x64, 0x02, 0x58, 0x4d, 0x07, 0xe3, 0x69,
+    0xd7, 0xe0, 0x8f, 0xb5, 0xf4, 0xbc, 0xfa, 0xab,
+    0x1a, 0xb0, 0xfa, 0x29, 0xf8, 0xca, 0xde, 0x78,
+    0xf0, 0x89, 0xe2, 0xf9, 0xb7, 0x68, 0x5b, 0x0e,
+    0xdc, 0x4e, 0x8a, 0x56, 0x8d, 0x33, 0x20, 0x2e,
+    0xed, 0x2e, 0xab, 0x6f, 0xba, 0x77, 0xef, 0xe6,
+    0x12, 0x62, 0x49, 0x9e, 0x87, 0x76, 0x1c, 0x1e,
+    0xf4, 0x0e, 0x9e, 0x78, 0x98, 0x91, 0x1a, 0xe3,
+    0xb4, 0x51, 0x4b, 0x8c, 0x2f, 0x08, 0x97, 0x8f,
+    0xf9, 0x68, 0x61, 0x40, 0xcd, 0xb6, 0x10, 0xb4,
+    0xfb, 0x75, 0xb4, 0x20, 0xc1, 0x5a, 0xda, 0x64,
+    0xfd, 0x51, 0x06, 0x85, 0x9a, 0x9e, 0x5d, 0x82,
+    0x14, 0xd4, 0x41, 0x4e, 0x75, 0x10, 0xb5, 0x7b,
+    0xd0, 0x4c, 0xd1, 0x00, 0x01, 0x02, 0x81, 0x81,
+    0x00, 0xcf, 0x8e, 0x68, 0x04, 0x67, 0x09, 0xa9,
+    0x6e, 0xff, 0x11, 0x8c, 0xe5, 0xe4, 0x16, 0xdd,
+    0xb6, 0xa6, 0x55, 0xca, 0x4b, 0x0b, 0xbb, 0xb7,
+    0xf5, 0xe5, 0x73, 0xf3, 0x24, 0x84, 0x29, 0xb2,
+    0xc3, 0xbc, 0x7f, 0x2b, 0x4a, 0xc7, 0xdf, 0x46,
+    0x8e, 0xe1, 0x35, 0x69, 0x1b, 0x8e, 0x9f, 0x6b,
+    0x4d, 0xf3, 0x65, 0xae, 0x3d, 0x87, 0x2b, 0xc9,
+    0xf0, 0x8c, 0xf2, 0x88, 0x2f, 0x1b, 0x79, 0x80,
+    0xd2, 0xb2, 0x64, 0x0a, 0xcc, 0x66, 0x69, 0x4c,
+    0xa1, 0x85, 0xc4, 0x6a, 0x94, 0x46, 0x70, 0x69,
+    0xbc, 0x8c, 0x1c, 0x62, 0x65, 0x4d, 0x68, 0xcc,
+    0xe3, 0x3c, 0x6c, 0xe7, 0xd1, 0x09, 0xed, 0xdd,
+    0x42, 0x10, 0x11, 0x6b, 0xdd, 0x7c, 0xe3, 0xe1,
+    0x3b, 0x3b, 0x0d, 0x01, 0x6d, 0xca, 0x2f, 0x4b,
+    0x45, 0x5e, 0x76, 0x5d, 0x5c, 0x6f, 0x53, 0xa4,
+    0x38, 0x74, 0x75, 0x94, 0x2c, 0xda, 0xf8, 0xa6,
+    0x01, 0x02, 0x81, 0x81, 0x00, 0xcd, 0x5f, 0x9d,
+    0x6c, 0x94, 0xf6, 0x44, 0x37, 0x72, 0xfe, 0xcf,
+    0xbe, 0x82, 0x96, 0x24, 0x22, 0x12, 0x07, 0x6f,
+    0xd1, 0x57, 0x7b, 0xc7, 0x63, 0x20, 0xf5, 0x93,
+    0x79, 0x70, 0x0b, 0xe4, 0x38, 0x19, 0x62, 0x7b,
+    0x89, 0x3e, 0x45, 0xdf, 0xd6, 0xae, 0x9d, 0x0d,
+    0xa8, 0x76, 0xc1, 0xbd, 0x04, 0x2b, 0xaa, 0x30,
+    0x6a, 0xac, 0x65, 0x91, 0x61, 0xf0, 0xf8, 0x5d,
+    0xa3, 0x53, 0xa4, 0xfb, 0x99, 0xac, 0x46, 0x7a,
+    0x12, 0x4b, 0xf7, 0xa7, 0x48, 0x41, 0x61, 0x48,
+    0x26, 0x5c, 0x68, 0x2f, 0x73, 0x91, 0xe4, 0x74,
+    0xcd, 0xc9, 0x8b, 0xe7, 0x26, 0xe4, 0x35, 0xde,
+    0x32, 0x6b, 0x24, 0x49, 0xf2, 0x04, 0x67, 0x3d,
+    0x31, 0x8f, 0x22, 0xe5, 0x49, 0xae, 0x49, 0x94,
+    0xb3, 0x45, 0x2b, 0xed, 0x6f, 0x9c, 0xc7, 0x80,
+    0xf0, 0x42, 0xd5, 0x8f, 0x27, 0xd6, 0xd6, 0x49,
+    0xf2, 0x16, 0xcc, 0x4b, 0x39, 0x02, 0x81, 0x81,
+    0x00, 0xbb, 0xb7, 0xd7, 0x59, 0xcb, 0xfb, 0x10,
+    0x13, 0xc4, 0x7b, 0x92, 0x0c, 0x45, 0xcb, 0x6c,
+    0x81, 0x0a, 0x55, 0x63, 0x1d, 0x96, 0xa2, 0x13,
+    0xd2, 0x40, 0xd1, 0x2a, 0xa1, 0xe7, 0x2a, 0x73,
+    0x74, 0xd6, 0x61, 0xc9, 0xbc, 0xdb, 0xa2, 0x93,
+    0x85, 0x1c, 0x28, 0x9b, 0x44, 0x82, 0x2c, 0xaa,
+    0xf7, 0x18, 0x60, 0xe9, 0x42, 0xda, 0xa2, 0xff,
+    0x04, 0x21, 0xe6, 0x24, 0xc7, 0x3e, 0x39, 0x19,
+    0x0a, 0xf6, 0xae, 0xc6, 0x99, 0x71, 0x32, 0x61,
+    0x4d, 0x60, 0xd7, 0x71, 0x71, 0x63, 0x77, 0xbe,
+    0x19, 0xfa, 0x3a, 0x9d, 0xbf, 0x73, 0x50, 0x8a,
+    0xa6, 0x26, 0x7b, 0x74, 0xfa, 0x39, 0xd9, 0xb9,
+    0x18, 0x4b, 0xc2, 0x05, 0xe5, 0x8f, 0x53, 0xe6,
+    0xdc, 0x14, 0x1f, 0x42, 0x20, 0x93, 0x11, 0x4d,
+    0x29, 0x93, 0x32, 0xc8, 0x63, 0x96, 0x88, 0x76,
+    0x69, 0x5c, 0xe3, 0x0e, 0xbd, 0xb6, 0xd9, 0xd6,
+    0x01, 0x02, 0x81, 0x80, 0x62, 0xa2, 0xed, 0x84,
+    0xdc, 0xf6, 0x7a, 0x44, 0xf7, 0x62, 0x12, 0x7c,
+    0xb9, 0x53, 0x4a, 0xff, 0x62, 0x11, 0x58, 0x4e,
+    0xfe, 0xe9, 0x60, 0x15, 0xe8, 0x1a, 0x8a, 0x3d,
+    0xe4, 0xe6, 0x91, 0x31, 0xb0, 0x5f, 0x70, 0x5d,
+    0xb6, 0x1e, 0xf1, 0x26, 0xb6, 0xae, 0x8f, 0x84,
+    0xbd, 0xa4, 0xc7, 0x17, 0x5d, 0xb1, 0x5b, 0x97,
+    0xa0, 0x3d, 0x17, 0xda, 0x26, 0x55, 0xe3, 0x03,
+    0x32, 0x85, 0x26, 0xa1, 0xe3, 0xef, 0xe5, 0x69,
+    0x2c, 0x3b, 0x41, 0x88, 0x9e, 0x7e, 0x0e, 0x9c,
+    0xfd, 0xfc, 0xbb, 0xed, 0x91, 0xc0, 0x5b, 0xa9,
+    0x0a, 0x87, 0xba, 0xf9, 0x1e, 0xda, 0x10, 0x61,
+    0xbe, 0xbb, 0xab, 0x18, 0x25, 0xad, 0x3f, 0xe2,
+    0xb1, 0x90, 0x5c, 0xf7, 0x4a, 0x51, 0xe4, 0xad,
+    0x45, 0x27, 0x97, 0xdd, 0xe7, 0x3a, 0x9a, 0x5e,
+    0xca, 0x7a, 0xaf, 0x4a, 0xbf, 0x10, 0x24, 0x6b,
+    0xb5, 0x2f, 0x61, 0x61, 0x02, 0x81, 0x81, 0x00,
+    0x85, 0x7c, 0x78, 0xa5, 0x11, 0xdf, 0xc3, 0x6a,
+    0x38, 0x48, 0xfa, 0x7e, 0x48, 0xf0, 0x5a, 0x58,
+    0xe2, 0xc5, 0x83, 0x4e, 0x38, 0x3f, 0x4a, 0x2b,
+    0x07, 0x57, 0x31, 0xe7, 0xbe, 0x50, 0xb1, 0xbb,
+    0x24, 0xf3, 0x3d, 0x8b, 0x53, 0xb7, 0xd1, 0x47,
+    0x72, 0x5e, 0xd5, 0xd6, 0x4c, 0xce, 0x2c, 0x46,
+    0x61, 0x9a, 0xaa, 0xc3, 0x0e, 0xd4, 0x23, 0x2c,
+    0xdd, 0xf5, 0xb7, 0xad, 0x38, 0x52, 0x17, 0xc4,
+    0x16, 0xbb, 0xda, 0x1c, 0x61, 0xb1, 0xca, 0x8d,
+    0xb2, 0xa0, 0xbe, 0x4f, 0x3d, 0x19, 0x0e, 0xe0,
+    0x0e, 0x52, 0xad, 0xf3, 0xaf, 0xd9, 0xcc, 0x78,
+    0xc2, 0xb1, 0x5e, 0x05, 0x5e, 0xf2, 0x27, 0x84,
+    0x15, 0xe4, 0x8f, 0xca, 0xc5, 0x92, 0x43, 0xe0,
+    0x24, 0x8d, 0xf2, 0x5d, 0x55, 0xcc, 0x9d, 0x2f,
+    0xa9, 0xf6, 0x9b, 0x67, 0x6a, 0x87, 0x74, 0x36,
+    0x34, 0x7c, 0xd4, 0x9d, 0xff, 0xad, 0xee, 0x69
+};
+
+static const uint8_t _k1_digest[] = {
+    0x46, 0xE0, 0x8A, 0x05, 0x63, 0x4D, 0x17, 0x3F,
+    0xCA, 0xA4, 0xAA, 0xB6, 0x5A, 0xDA, 0xCF, 0xBA,
+    0x84, 0x22, 0x7C, 0x23
+};
+
+/* Create and identity and try to retrieve it. */
+static void tests(void)
+{
+    SecCertificateRef cert = NULL, cert2 = NULL;
+    SecKeyRef privKey = NULL;
+    SecIdentityRef identity = NULL;
+    CFArrayRef trust_chain = NULL;
+    SSLContextRef ctx = NULL;
+
+    isnt(cert = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)),
+            NULL, "create certificate");
+    isnt(cert2 = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)),
+            NULL, "create certificate2");
+#if TARGET_OS_IPHONE
+    privKey = SecKeyCreateRSAPrivateKey(NULL, _k1, sizeof(_k1),
+                kSecKeyEncodingPkcs1);
+#else
+    privKey = NULL; /* TODO */
+#endif
+    isnt(privKey, NULL, "create private key");
+
+    ok(identity = SecIdentityCreate(kCFAllocatorDefault, cert, privKey), "SecIdentityCreate");
+    CFReleaseSafe(cert);
+    CFReleaseSafe(privKey);
+    const void *values[] = { identity, cert2 };
+    ok(trust_chain = CFArrayCreate(kCFAllocatorDefault, values,
+        array_size(values), &kCFTypeArrayCallBacks), "CFArrayCreate");
+    CFReleaseSafe(identity);
+    CFReleaseSafe(cert2);
+
+    is(CFGetRetainCount(trust_chain), 1, "trust_chain rc = 1");
+    is(CFGetRetainCount(identity), 1, "identity rc = 1");
+    is(CFGetRetainCount(cert), 1, "cert rc = 1");
+    is(CFGetRetainCount(cert2), 1, "cert2 rc = 1");
+    is(CFGetRetainCount(privKey), 1, "privKey rc = 1");
+
+    ok(ctx=SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType), "SSLNewContext");
+    ok_status(SSLSetCertificate(ctx, trust_chain), "SSLSetCertificate");
+    CFReleaseSafe(ctx);
+
+    is(CFGetRetainCount(trust_chain), 1, "trust_chain rc = 1");
+    is(CFGetRetainCount(identity), 1, "identity rc = 1");
+    is(CFGetRetainCount(cert), 1, "cert rc = 1");
+    is(CFGetRetainCount(cert2), 1, "cert2 rc = 1");
+    is(CFGetRetainCount(privKey), 1, "privKey rc = 1");
+
+    ok(ctx=SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType), "SSLCreateContext");
+    ok_status(SSLSetCertificate(ctx, trust_chain), "SSLSetCertificate");
+    CFReleaseSafe(ctx);
+
+    is(CFGetRetainCount(trust_chain), 1, "trust_chain rc = 1");
+    is(CFGetRetainCount(identity), 1, "identity rc = 1");
+    is(CFGetRetainCount(cert), 1, "cert rc = 1");
+    is(CFGetRetainCount(cert2), 1, "cert2 rc = 1");
+    is(CFGetRetainCount(privKey), 1, "privKey rc = 1");
+
+    ok(ctx=SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType), "SSLCreateContext");
+    ok_status(SSLSetCertificate(ctx, trust_chain), "SSLSetCertificate");
+    ok_status(SSLSetCertificate(ctx, trust_chain), "SSLSetCertificate");
+    CFReleaseSafe(ctx);
+
+    is(CFGetRetainCount(trust_chain), 1, "trust_chain rc = 1");
+    is(CFGetRetainCount(identity), 1, "identity rc = 1");
+    is(CFGetRetainCount(cert), 1, "cert rc = 1");
+    is(CFGetRetainCount(cert2), 1, "cert2 rc = 1");
+    is(CFGetRetainCount(privKey), 1, "privKey rc = 1");
+
+    CFReleaseNull(trust_chain);
+}
+
+int ssl_41_clientauth(int argc, char *const *argv)
+{
+    plan_tests(32);
+
+
+    tests();
+
+    return 0;
+}
diff --git a/libsecurity_ssl/regressions/ssl-42-ciphers.c b/libsecurity_ssl/regressions/ssl-42-ciphers.c
new file mode 100644 (file)
index 0000000..9804e78
--- /dev/null
@@ -0,0 +1,645 @@
+
+#include <stdbool.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <AssertMacros.h>
+#include <Security/SecureTransportPriv.h> /* SSLSetOption */
+#include <Security/SecureTransport.h>
+#include <Security/SecPolicy.h>
+#include <Security/SecTrust.h>
+#include <Security/SecIdentity.h>
+#include <Security/SecIdentityPriv.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecKeyPriv.h>
+#include <Security/SecItem.h>
+#include <Security/SecRandom.h>
+
+#include <utilities/array_size.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <mach/mach_time.h>
+
+#if TARGET_OS_IPHONE
+#include <Security/SecRSAKey.h>
+#endif
+
+#include "ssl_regressions.h"
+#include "ssl-utils.h"
+
+/*
+    SSL CipherSuite tests
+
+    Below are all the ciphers that are individually tested.  The first element
+    is the SecureTransport/RFC name; the second is what openssl calls it, which
+    can be looked up in ciphers(1).
+
+    All SSL_DH_* and TLS_DH_* are disabled because neither openssl nor
+    securetranport support them:
+    SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_DH_DSS_WITH_DES_CBC_SHA,
+    SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA, SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
+    SSL_DH_RSA_WITH_DES_CBC_SHA, SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA,
+    TLS_DH_DSS_WITH_AES_128_CBC_SHA, TLS_DH_RSA_WITH_AES_128_CBC_SHA,
+    TLS_DH_DSS_WITH_AES_256_CBC_SHA, TLS_DH_RSA_WITH_AES_256_CBC_SHA,
+
+    DSS is unimplemented by securetransport on the phone:
+    SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA,
+    SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
+    TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
+
+    SSLv2 ciphersuites disabled by securetransport on phone:
+    SSL_RSA_WITH_RC2_CBC_MD5, SSL_RSA_WITH_IDEA_CBC_MD5,
+    SSL_RSA_WITH_DES_CBC_MD5, SSL_RSA_WITH_3DES_EDE_CBC_MD5,
+
+    SSLv3 ciphersuites disabled by securetransport on phone:
+    SSL_RSA_WITH_IDEA_CBC_SHA, SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5
+
+    Export ciphersuites disabled on iOS 5.0:
+    SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA,
+    SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
+    SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DH_anon_EXPORT_WITH_RC4_40_MD5,
+    SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, SSL_DH_anon_WITH_DES_CBC_SHA
+
+*/
+
+typedef struct _CipherSuiteName {
+        SSLCipherSuite cipher;
+        const char *name;
+        bool dh_anonymous;
+} CipherSuiteName;
+
+#define CIPHER(cipher, dh_anonymous) { cipher, #cipher, dh_anonymous },
+
+static const CipherSuiteName ciphers[] = {
+    //SSL_NULL_WITH_NULL_NULL, unsupported
+    CIPHER(SSL_RSA_WITH_NULL_SHA, false)
+    CIPHER(SSL_RSA_WITH_NULL_MD5, false)
+    CIPHER(TLS_RSA_WITH_NULL_SHA256, false)
+
+    CIPHER(SSL_RSA_WITH_RC4_128_MD5, false)
+    CIPHER(SSL_RSA_WITH_RC4_128_SHA, false)
+    CIPHER(SSL_RSA_WITH_3DES_EDE_CBC_SHA, false)
+
+    CIPHER(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, false)
+    CIPHER(SSL_DH_anon_WITH_RC4_128_MD5, true)
+    CIPHER(SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, true)
+    CIPHER(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, false)
+    CIPHER(TLS_DH_anon_WITH_AES_128_CBC_SHA, true)
+    CIPHER(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, false)
+    CIPHER(TLS_DH_anon_WITH_AES_256_CBC_SHA, true)
+
+    CIPHER(TLS_RSA_WITH_AES_128_CBC_SHA, false)
+    CIPHER(TLS_RSA_WITH_AES_256_CBC_SHA, false)
+
+
+    CIPHER(TLS_PSK_WITH_AES_128_CBC_SHA, true)
+    CIPHER(TLS_PSK_WITH_AES_256_CBC_SHA384, true)
+    CIPHER(TLS_PSK_WITH_AES_128_CBC_SHA256, true)
+    CIPHER(TLS_PSK_WITH_AES_256_CBC_SHA, true)
+    CIPHER(TLS_PSK_WITH_AES_128_CBC_SHA, true)
+    CIPHER(TLS_PSK_WITH_RC4_128_SHA, true)
+    CIPHER(TLS_PSK_WITH_3DES_EDE_CBC_SHA, true)
+    CIPHER(TLS_PSK_WITH_NULL_SHA384, true)
+    CIPHER(TLS_PSK_WITH_NULL_SHA256, true)
+    CIPHER(TLS_PSK_WITH_NULL_SHA, true)
+
+
+#if 0
+    CIPHER(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, false)
+    CIPHER(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, false)
+
+    CIPHER(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, false)
+    CIPHER(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, false)
+
+    CIPHER(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, false)
+    CIPHER(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, false)
+
+    CIPHER(TLS_ECDH_anon_WITH_AES_128_CBC_SHA, true)
+    CIPHER(TLS_ECDH_anon_WITH_AES_256_CBC_SHA, true)
+
+    CIPHER(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, false)
+    CIPHER(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, false)
+    CIPHER(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, false)
+    CIPHER(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, false)
+#endif
+
+#if 0
+    CIPHER(TLS_RSA_WITH_AES_256_GCM_SHA384, false)
+    CIPHER(TLS_RSA_WITH_AES_128_GCM_SHA256, false)
+#endif
+
+/* Export ciphers are disabled */
+#if 0
+    CIPHER(SSL_RSA_EXPORT_WITH_RC4_40_MD5, false)
+    CIPHER(SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, false)
+    CIPHER(SSL_RSA_WITH_DES_CBC_SHA,  false)
+    CIPHER(SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,  false)
+    CIPHER(SSL_DHE_RSA_WITH_DES_CBC_SHA, false)
+    CIPHER(SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, true)
+    CIPHER(SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA,  true)
+    CIPHER(SSL_DH_anon_WITH_DES_CBC_SHA, true)
+#endif
+
+    { -1 }
+};
+
+static int ciphers_len = array_size(ciphers);
+
+
+static int protos[]={kTLSProtocol1, kTLSProtocol11, kTLSProtocol12 };
+static int nprotos = sizeof(protos)/sizeof(protos[0]);
+
+
+#if 0 // currently unused
+static SSLCipherSuite sslcipher_atoi(const char *name)
+{
+       const CipherSuiteName *a = ciphers;
+       while(a->name) {
+           if (0 == strcmp(a->name, name)) break;
+           a++;
+       }
+       return a->cipher;
+}
+
+static const char * sslcipher_itoa(SSLCipherSuite num)
+{
+       const CipherSuiteName *a = ciphers;
+       while(a->cipher >= 0) {
+           if (num == a->cipher) break;
+           a++;
+       }
+       return a->name;
+}
+#endif // currently unused
+
+static unsigned char dh_param_512_bytes[] = {
+  0x30, 0x46, 0x02, 0x41, 0x00, 0xdb, 0x3c, 0xfa, 0x13, 0xa6, 0xd2, 0x64,
+  0xdf, 0xcc, 0x40, 0xb1, 0x21, 0xd4, 0xf2, 0xad, 0x22, 0x7f, 0xce, 0xa0,
+  0xb9, 0x5b, 0x95, 0x1c, 0x2e, 0x99, 0xb0, 0x27, 0xd0, 0xed, 0xf4, 0xbd,
+  0xbb, 0x36, 0x93, 0xd0, 0x9d, 0x2b, 0x32, 0xa3, 0x56, 0x53, 0xe3, 0x7b,
+  0xed, 0xa1, 0x71, 0x82, 0x2e, 0x83, 0x14, 0xf9, 0xc0, 0x2f, 0x15, 0xcb,
+  0xcf, 0x97, 0xab, 0x88, 0x49, 0x20, 0x28, 0x2e, 0x63, 0x02, 0x01, 0x02
+};
+static unsigned char *dh_param_512_der = dh_param_512_bytes;
+static unsigned int dh_param_512_der_len = 72;
+
+
+typedef struct {
+    uint32_t session_id;
+    bool is_session_resume;
+    SSLContextRef st;
+    bool is_server;
+    bool is_dtls;
+    bool client_side_auth;
+    bool dh_anonymous;
+    int comm;
+    CFArrayRef certs;
+    SSLProtocol proto;
+} ssl_test_handle;
+
+#if 0 // currently unused
+static CFArrayRef SecIdentityCopySSLClientAuthenticationChain(SecIdentityRef identity)
+{
+   CFMutableArrayRef chain = NULL;
+   SecPolicyRef policy = NULL;
+   SecTrustRef trust = NULL;
+   SecTrustResultType trust_result;
+
+   do {
+       policy = SecPolicyCreateSSL(false, NULL);
+       if (!policy)
+           break;
+
+       SecCertificateRef cert = NULL;
+       if (SecIdentityCopyCertificate(identity, &cert))
+           break;
+
+       CFArrayRef certs = CFArrayCreate(NULL, (const void **)&cert,
+                 1, &kCFTypeArrayCallBacks);
+       CFRelease(cert);
+       if (!certs)
+           break;
+
+       if (SecTrustCreateWithCertificates(certs, policy, &trust))
+           break;
+       CFRelease(certs);
+       CFRelease(policy);
+       if (SecTrustEvaluate(trust, &trust_result))
+           break;
+
+       int i, count = SecTrustGetCertificateCount(trust);
+       chain = CFArrayCreateMutable(NULL, count, &kCFTypeArrayCallBacks);
+       CFArrayAppendValue(chain, identity);
+       for (i = 1; i < count; i++) {
+           if ((i+1 == count) && (trust_result == kSecTrustResultUnspecified))
+               continue; /* skip anchor if chain is complete */
+           SecCertificateRef s = SecTrustGetCertificateAtIndex(trust, i);
+           CFArrayAppendValue(chain, s);
+       }
+   } while (0);
+   if (trust)
+       CFRelease(trust);
+   if (policy)
+       CFRelease(policy);
+   return chain;
+}
+#endif // currently unused
+
+// MARK: -
+// MARK: SecureTransport support
+
+#if 0
+static void hexdump(const uint8_t *bytes, size_t len) {
+       size_t ix;
+    printf("socket write(%p, %lu)\n", bytes, len);
+       for (ix = 0; ix < len; ++ix) {
+        if (!(ix % 16))
+            printf("\n");
+               printf("%02X ", bytes[ix]);
+       }
+       printf("\n");
+}
+#else
+#define hexdump(bytes, len)
+#endif
+
+static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *length)
+{
+       size_t len = *length;
+       uint8_t *ptr = (uint8_t *)data;
+
+    do {
+        ssize_t ret;
+        do {
+            hexdump(ptr, len);
+            ret = write((int)conn, ptr, len);
+        } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
+        if (ret > 0) {
+            len -= ret;
+            ptr += ret;
+        }
+        else
+            return -36;
+    } while (len > 0);
+
+    *length = *length - len;
+    return errSecSuccess;
+}
+
+static OSStatus SocketRead(SSLConnectionRef conn, void *data, size_t *length)
+{
+       size_t len = *length;
+       uint8_t *ptr = (uint8_t *)data;
+
+    do {
+        ssize_t ret;
+        do {
+            ret = read((int)conn, ptr, len);
+        } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
+        if (ret > 0) {
+            len -= ret;
+            ptr += ret;
+        }
+        else
+            return -36;
+    } while (len > 0);
+
+    *length = *length - len;
+    return errSecSuccess;
+}
+
+static unsigned char dn[] = {
+  0x30, 0x5e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+  0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
+  0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+  0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41,
+  0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+  0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
+  0x72, 0x69, 0x74, 0x79, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
+  0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74
+};
+static unsigned int dn_len = 96;
+
+static SSLContextRef make_ssl_ref(bool server, bool client_side_auth, bool dh_anonymous,
+    bool dtls, int sock, CFArrayRef certs, SSLProtocol proto)
+{
+    SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, server?kSSLServerSide:kSSLClientSide, dtls?kSSLDatagramType:kSSLStreamType);
+    require(ctx, out);
+
+    if(dtls) {
+        size_t mtu;
+        require_noerr(SSLSetMaxDatagramRecordSize(ctx, 400), out);
+        require_noerr(SSLGetMaxDatagramRecordSize(ctx, &mtu), out);
+    } else {
+        require_noerr(SSLSetProtocolVersionMax(ctx, proto), out);
+    }
+    require_noerr(SSLSetIOFuncs(ctx,
+        (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
+    require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)sock), out);
+    static const char *peer_domain_name = "localhost";
+    require_noerr(SSLSetPeerDomainName(ctx, peer_domain_name,
+        strlen(peer_domain_name)), out);
+
+
+    if (!dh_anonymous) {
+        if (server)
+            require_noerr(SSLSetCertificate(ctx, certs), out);
+        if (client_side_auth && server) {
+            SSLAuthenticate auth;
+            require_noerr(SSLSetClientSideAuthenticate(ctx, kAlwaysAuthenticate), out);
+            require_noerr(SSLGetClientSideAuthenticate(ctx, &auth), out);
+            require(auth==kAlwaysAuthenticate, out);
+            require_noerr(SSLAddDistinguishedName(ctx, dn, dn_len), out);
+        }
+#if 0 /* Setting client certificate in advance */
+        if (client_side_auth && !server)
+            require_noerr(SSLSetCertificate(ctx, certs), out);
+#endif
+        if (client_side_auth && !server) /* enable break from SSLHandshake */
+            require_noerr(SSLSetSessionOption(ctx,
+                kSSLSessionOptionBreakOnCertRequested, true), out);
+        require_noerr(SSLSetSessionOption(ctx,
+            kSSLSessionOptionBreakOnServerAuth, true), out);
+    }
+
+    /* Tell SecureTransport to not check certs itself: it will break out of the
+       handshake to let us take care of it instead. */
+    require_noerr(SSLSetEnableCertVerify(ctx, false), out);
+
+    if (server) {
+        require_noerr(SSLSetDiffieHellmanParams(ctx,
+            dh_param_512_der, dh_param_512_der_len), out);
+    }
+    else /* if client */ {
+    }
+
+    return ctx;
+out:
+    if (ctx)
+        CFRelease(ctx);
+    return NULL;
+}
+
+static void *securetransport_ssl_thread(void *arg)
+{
+    OSStatus ortn;
+    ssl_test_handle * ssl = (ssl_test_handle *)arg;
+    SSLContextRef ctx = ssl->st;
+    SecTrustRef trust = NULL;
+    bool got_server_auth = false, got_client_cert_req = false;
+
+    pthread_setname_np(ssl->is_server?"server thread":"client thread");
+
+    //uint64_t start = mach_absolute_time();
+    do {
+        ortn = SSLHandshake(ctx);
+
+        if (ortn == errSSLPeerAuthCompleted)
+        {
+            require_string(!got_server_auth, out, "second server auth");
+            require_string(!got_client_cert_req, out, "got client cert req before server auth");
+            got_server_auth = true;
+            require_string(!trust, out, "Got errSSLServerAuthCompleted twice?");
+            /* verify peer cert chain */
+            require_noerr(SSLCopyPeerTrust(ctx, &trust), out);
+            SecTrustResultType trust_result = 0;
+            /* this won't verify without setting up a trusted anchor */
+            require_noerr(SecTrustEvaluate(trust, &trust_result), out);
+
+            CFIndex n_certs = SecTrustGetCertificateCount(trust);
+            /*fprintf(stderr, "%ld certs; trust_eval: %d\n", n_certs, trust_result); */
+
+            CFMutableArrayRef peer_cert_array =
+                CFArrayCreateMutable(NULL, n_certs, &kCFTypeArrayCallBacks);
+            CFMutableArrayRef orig_peer_cert_array =
+                CFArrayCreateMutableCopy(NULL, n_certs, ssl->certs);
+            while (n_certs--)
+                CFArrayInsertValueAtIndex(peer_cert_array, 0,
+                    SecTrustGetCertificateAtIndex(trust, n_certs));
+
+            SecIdentityRef ident =
+                (SecIdentityRef)CFArrayGetValueAtIndex(orig_peer_cert_array, 0);
+            SecCertificateRef peer_cert = NULL;
+            require_noerr(SecIdentityCopyCertificate(ident, &peer_cert), out);
+            CFArraySetValueAtIndex(orig_peer_cert_array, 0, peer_cert);
+            CFRelease(peer_cert);
+
+            require(CFEqual(orig_peer_cert_array, peer_cert_array), out);
+            CFRelease(orig_peer_cert_array);
+            CFRelease(peer_cert_array);
+
+            /*
+            CFStringRef cert_name = SecCertificateCopySubjectSummary(cert);
+            char cert_name_buffer[1024];
+            require(CFStringGetFileSystemRepresentation(cert_name,
+                cert_name_buffer, sizeof(cert_name_buffer)), out);
+            fprintf(stderr, "cert name: %s\n", cert_name_buffer);
+            CFRelease(trust);
+            */
+        } else if (ortn == errSSLClientCertRequested) {
+            require_string(!got_client_cert_req, out, "second client cert req");
+            require_string(got_server_auth, out, "didn't get server auth first");
+            got_client_cert_req = true;
+
+            /* set client cert */
+            require_string(!ssl->is_server, out, "errSSLClientCertRequested while running server");
+            require_string(!ssl->dh_anonymous, out, "errSSLClientCertRequested while running anon DH");
+
+            CFArrayRef DNs = NULL;
+            require_noerr(SSLCopyDistinguishedNames    (ctx, &DNs), out);
+            require(DNs, out);
+            CFRelease(DNs);
+
+            require_string(ssl->client_side_auth, out, "errSSLClientCertRequested in run not testing that");
+            require_noerr(SSLSetCertificate(ctx, ssl->certs), out);
+        }
+    } while (ortn == errSSLWouldBlock
+        || ortn == errSSLServerAuthCompleted
+        || ortn == errSSLClientCertRequested);
+    require_noerr_action_quiet(ortn, out,
+        fprintf(stderr, "Fell out of SSLHandshake with error: %d\n", (int)ortn));
+
+    if (!ssl->is_server && !ssl->dh_anonymous && !ssl->is_session_resume) {
+        require_string(got_server_auth, out, "never got server auth");
+        if (ssl->client_side_auth)
+            require_string(got_client_cert_req, out, "never got client cert req");
+    }
+    //uint64_t elapsed = mach_absolute_time() - start;
+    //fprintf(stderr, "setr elapsed: %lld\n", elapsed);
+
+    /*
+    SSLProtocol proto = kSSLProtocolUnknown;
+    require_noerr_quiet(SSLGetNegotiatedProtocolVersion(ctx, &proto), out); */
+
+    SSLCipherSuite cipherSuite;
+    require_noerr_quiet(ortn = SSLGetNegotiatedCipher(ctx, &cipherSuite), out);
+    //fprintf(stderr, "st negotiated %s\n", sslcipher_itoa(cipherSuite));
+
+    if(ssl->is_dtls) {
+        size_t sz;
+        SSLGetDatagramWriteSize(ctx, &sz);
+        //fprintf(stderr, "Max Write Size = %ld\n", sz);
+    }
+
+       Boolean sessionWasResumed = false;
+    uint8_t session_id_data[MAX_SESSION_ID_LENGTH];
+    size_t session_id_length = sizeof(session_id_data);
+    require_noerr_quiet(ortn = SSLGetResumableSessionInfo(ctx, &sessionWasResumed, session_id_data, &session_id_length), out);
+    require_action(ssl->dh_anonymous || (ssl->is_session_resume == sessionWasResumed), out, ortn = -1);
+    // if (sessionWasResumed) fprintf(stderr, "st resumed session\n");
+    //hexdump(session_id_data, session_id_length);
+
+    unsigned char ibuf[4096], obuf[4096];
+    size_t len;
+    if (ssl->is_server) {
+        SecRandomCopyBytes(kSecRandomDefault, sizeof(obuf), obuf);
+        require_noerr_quiet(ortn = SSLWrite(ctx, obuf, sizeof(obuf), &len), out);
+        require_action_quiet(len == sizeof(obuf), out, ortn = -1);
+    }
+    require_noerr_quiet(ortn = SSLRead(ctx, ibuf, sizeof(ibuf), &len), out);
+    require_action_quiet(len == sizeof(ibuf), out, ortn = -1);
+
+    if (ssl->is_server) {
+        require_noerr(memcmp(ibuf, obuf, sizeof(ibuf)), out);
+    } else {
+        require_noerr_quiet(ortn = SSLWrite(ctx, ibuf, sizeof(ibuf), &len), out);
+        require_action_quiet(len == sizeof(ibuf), out, ortn = -1);
+    }
+
+out:
+    SSLClose(ctx);
+    CFRelease(ctx);
+    if (trust) CFRelease(trust);
+    close(ssl->comm);
+    pthread_exit((void *)(intptr_t)ortn);
+    return NULL;
+}
+
+
+
+static ssl_test_handle *
+ssl_test_handle_create(uint32_t session_id, bool resume, bool server, bool client_side_auth, bool dh_anonymous, bool dtls,
+    int comm, CFArrayRef certs, SSLProtocol proto)
+{
+    ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle));
+    if (handle) {
+        handle->session_id = session_id;
+        handle->is_session_resume = resume;
+        handle->is_server = server;
+        handle->is_dtls = dtls;
+        handle->client_side_auth = client_side_auth;
+        handle->dh_anonymous = dh_anonymous;
+        handle->comm = comm;
+        handle->certs = certs;
+        handle->proto = proto;
+        handle->st = make_ssl_ref(server, client_side_auth, dh_anonymous, dtls, comm, certs, proto);
+    }
+    return handle;
+}
+
+static void
+tests(void)
+{
+    pthread_t client_thread, server_thread;
+    CFArrayRef server_certs = server_chain();
+    ok(server_certs, "got server certs");
+
+/* Enable this if you want to test a specific d/i/k/l combination */
+#if 0
+    int d=0, i=0, l=0, k=0; { {
+#else
+    int d,i,k,l,p;
+
+    for (p=0; p<nprotos; p++)
+    for (d=0;d<2; d++)  /* dtls or not dtls */
+    for (k=0; k<2; k++)
+    {
+        for (i=0; ciphers[i].cipher != (SSLCipherSuite)(-1); i++)
+        for (l = 0; l<2; l++) {
+#endif
+            SKIP:{
+                //skip("Session resumption tests do not work at this point", 1, l != 1);
+
+                int sp[2];
+                if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) exit(errno);
+                fcntl(sp[0], F_SETNOSIGPIPE, 1);
+                fcntl(sp[1], F_SETNOSIGPIPE, 1);
+
+                ssl_test_handle *server, *client;
+
+                bool client_side_auth = (k);
+
+                uint32_t session_id = (k+1) << 16 | (i+1);
+                //fprintf(stderr, "session_id: %d\n", session_id);
+                server = ssl_test_handle_create(session_id, (l == 1), true /*server*/,
+                    client_side_auth, ciphers[i].dh_anonymous, d,
+                    sp[0], server_certs, protos[p]);
+                client = ssl_test_handle_create(session_id, (l == 1), false/*client*/,
+                    client_side_auth, ciphers[i].dh_anonymous, d,
+                    sp[1], server_certs, protos[p]);
+
+                require_noerr(SSLSetPeerID(server->st, &session_id, sizeof(session_id)), out);
+                require_noerr(SSLSetPeerID(client->st, &session_id, sizeof(session_id)), out);
+
+                /* set fixed cipher on client and server */
+                require_noerr(SSLSetEnabledCiphers(client->st, &ciphers[i].cipher, 1), out);
+                require_noerr(SSLSetEnabledCiphers(server->st, &ciphers[i].cipher, 1), out);
+
+                require_noerr(SSLSetPSKSharedSecret(client->st, "123456789", 9), out);
+                require_noerr(SSLSetPSKSharedSecret(server->st, "123456789", 9), out);
+
+
+                pthread_create(&client_thread, NULL, securetransport_ssl_thread, client);
+                pthread_create(&server_thread, NULL, securetransport_ssl_thread, server);
+
+                int server_err, client_err;
+                pthread_join(client_thread, (void*)&client_err);
+                pthread_join(server_thread, (void*)&server_err);
+
+
+                ok(!server_err && !client_err,
+                   "%40s ADH:%d CSA:%d DTLS:%d RESUME:%d PROTO:%d",
+                   ciphers[i].name,
+                   server->dh_anonymous,
+                   server->client_side_auth,
+                   d, l, p);
+out:
+                free(client);
+                free(server);
+
+            }
+        } /* all ciphers */
+    } /* all configs */
+
+    CFRelease(server_certs);
+}
+
+int ssl_42_ciphers(int argc, char *const *argv)
+{
+
+    plan_tests(2 * 2 * 2 * nprotos * (ciphers_len-1)/* client auth on/off * #configs * #ciphers */
+                + 1 /*cert*/);
+
+
+    tests();
+
+    return 0;
+}
+
+/*
+TODO: count errSSLWouldBlock
+TODO: skip tests that don't matter: client_auth and anonymous dh
+TODO: we seem to only be negotiating tls - force a round of sslv3
+TODO: allow secure transport to also defer client side auth to client
+TODO: make sure anonymous dh is never selected if not expicitly enabled
+TODO: make sure DHE is not available if not explicitly enabled and no parameters
+      are set
+TODO: resumable sessions
+*/
diff --git a/libsecurity_ssl/regressions/ssl-43-ciphers.c b/libsecurity_ssl/regressions/ssl-43-ciphers.c
new file mode 100644 (file)
index 0000000..1030a28
--- /dev/null
@@ -0,0 +1,701 @@
+//
+//  ssl-43-ciphers.c
+//  regressions
+//
+//  Created by Fabrice Gautier on 6/7/11.
+//  Copyright 2011 Apple, Inc. All rights reserved.
+//
+
+#include <stdbool.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <AssertMacros.h>
+#include <Security/SecureTransportPriv.h> /* SSLSetOption */
+#include <Security/SecureTransport.h>
+#include <Security/SecPolicy.h>
+#include <Security/SecTrust.h>
+#include <Security/SecIdentity.h>
+#include <Security/SecIdentityPriv.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecKeyPriv.h>
+#include <Security/SecItem.h>
+#include <Security/SecRandom.h>
+
+#include <utilities/array_size.h>
+#include <utilities/SecIOFormat.h>
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <mach/mach_time.h>
+
+
+#include "ssl_regressions.h"
+#include "ssl-utils.h"
+
+/*
+ SSL CipherSuite tests
+
+ Below are all the ciphers that are individually tested.  The first element
+ is the SecureTransport/RFC name; the second is what openssl calls it, which
+ can be looked up in ciphers(1).
+
+ All SSL_DH_* and TLS_DH_* are disabled because neither openssl nor
+ securetranport support them:
+ SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_DH_DSS_WITH_DES_CBC_SHA,
+ SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA, SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
+ SSL_DH_RSA_WITH_DES_CBC_SHA, SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA,
+ TLS_DH_DSS_WITH_AES_128_CBC_SHA, TLS_DH_RSA_WITH_AES_128_CBC_SHA,
+ TLS_DH_DSS_WITH_AES_256_CBC_SHA, TLS_DH_RSA_WITH_AES_256_CBC_SHA,
+
+ DSS is unimplemented by securetransport on the phone:
+ SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA,
+ SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
+ TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
+
+ SSLv2 ciphersuites disabled by securetransport on phone:
+ SSL_RSA_WITH_RC2_CBC_MD5, SSL_RSA_WITH_IDEA_CBC_MD5,
+ SSL_RSA_WITH_DES_CBC_MD5, SSL_RSA_WITH_3DES_EDE_CBC_MD5,
+
+ SSLv3 ciphersuites disabled by securetransport on phone:
+ SSL_RSA_WITH_IDEA_CBC_SHA, SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5
+
+ */
+
+#define OPENSSL_SERVER "ariadne.apple.com"
+#define GNUTLS_SERVER "ariadne.apple.com"
+
+static struct {
+    const char *host;
+    int base_port;
+    int cs_index;
+    bool client_auth;
+} servers[] = {
+    { OPENSSL_SERVER, 4000, 0, false}, //openssl s_server w/o client side auth
+    { GNUTLS_SERVER, 5000, 1, false}, // gnutls-serv w/o client side auth
+    { "www.mikestoolbox.org", 442, 2, false}, // mike's  w/o client side auth
+//    { "tls.secg.org", 40022, 3, false}, // secg ecc server w/o client side auth - This server generate DH params we dont support.
+
+    { OPENSSL_SERVER, 4010, 0, true}, //openssl s_server w/ client side auth
+    { GNUTLS_SERVER, 5010, 1, true}, // gnutls-serv w/ client side auth
+    { "www.mikestoolbox.net", 442, 2, true}, // mike's  w/ client side auth
+//    { "tls.secg.org", 8442, 3}, //secg ecc server w/ client side auth
+};
+int nservers = sizeof(servers)/sizeof(servers[0]);
+
+int protos[]={ kSSLProtocol3, kTLSProtocol1, kTLSProtocol11, kTLSProtocol12 };
+int nprotos = sizeof(protos)/sizeof(protos[0]);
+
+typedef struct _CipherSuiteName {
+    int prot;
+    SSLCipherSuite cipher;
+    const char *name;
+    int portoffset[4]; // 0=not supported , else = port offset for this ciphersuite
+    bool dh_anonymous;
+} CipherSuiteName;
+
+/* prot: 0 = SSL3, 1=TLSv1.0, 2=TLSv1.1, 3=TLSv1.2 */
+#define CIPHER(prot, cipher, offsets...) { prot, cipher, #cipher, offsets},
+
+const CipherSuiteName ciphers[] = {
+    //SSL_NULL_WITH_NULL_NULL, unsupported
+#if 1
+    /* RSA cipher suites */
+    CIPHER(0, SSL_RSA_WITH_NULL_MD5,    {1, 1, 0, 1}, false)
+    CIPHER(0, SSL_RSA_WITH_NULL_SHA,    {1, 1, 0, 1}, false)
+    CIPHER(3, TLS_RSA_WITH_NULL_SHA256, {0, 1, 0, 0}, false)
+#endif
+
+#if 1
+    CIPHER(0, SSL_RSA_WITH_RC4_128_MD5,         {1, 1, 1, 1}, false)
+    CIPHER(0, SSL_RSA_WITH_RC4_128_SHA,         {1, 1, 1, 1}, false)
+    CIPHER(0, SSL_RSA_WITH_3DES_EDE_CBC_SHA,    {1, 1, 1, 1}, false)
+    CIPHER(0, TLS_RSA_WITH_AES_128_CBC_SHA,     {1, 1, 1, 1}, false)
+    CIPHER(3, TLS_RSA_WITH_AES_128_CBC_SHA256,  {0, 1, 1, 0}, false)
+    CIPHER(0, TLS_RSA_WITH_AES_256_CBC_SHA,     {1, 1, 1, 1}, false)
+    CIPHER(3, TLS_RSA_WITH_AES_256_CBC_SHA256,  {0, 1, 1, 0}, false)
+#endif
+
+#if 1
+    /* DHE_RSA ciphers suites */
+    CIPHER(0, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,    {1, 1, 1, 1}, false)
+    CIPHER(0, TLS_DHE_RSA_WITH_AES_128_CBC_SHA,     {1, 1, 1, 1}, false)
+    CIPHER(3, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,  {0, 1, 1, 0}, false)
+    CIPHER(0, TLS_DHE_RSA_WITH_AES_256_CBC_SHA,     {1, 1, 1, 1}, false)
+    CIPHER(3, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,  {0, 1, 1, 0}, false)
+#endif
+
+
+#if 1
+    /* DH_anon cipher suites */
+    CIPHER(0, SSL_DH_anon_WITH_RC4_128_MD5,         {1, 1, 0, 1}, true)
+    CIPHER(0, SSL_DH_anon_WITH_3DES_EDE_CBC_SHA,    {1, 1, 0, 1}, true)
+    CIPHER(0, TLS_DH_anon_WITH_AES_128_CBC_SHA,     {1, 1, 0, 1}, true)
+    CIPHER(3, TLS_DH_anon_WITH_AES_128_CBC_SHA256,  {0, 1, 0, 1}, true)
+    CIPHER(0, TLS_DH_anon_WITH_AES_256_CBC_SHA,     {1, 1, 0, 1}, true)
+    CIPHER(3, TLS_DH_anon_WITH_AES_256_CBC_SHA256,  {0, 1, 0, 1}, true)
+#endif
+
+#if 1
+    /* ECDHE_ECDSA cipher suites */
+    CIPHER(1, TLS_ECDHE_ECDSA_WITH_NULL_SHA,            {4, 4, 0, 1}, false)
+    CIPHER(1, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,         {4, 0, 0, 1}, false)
+    CIPHER(1, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,    {4, 4, 0, 1}, false)
+    CIPHER(1, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,     {4, 4, 0, 1}, false)
+    CIPHER(3, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,  {0, 4, 0, 1}, false)
+    CIPHER(1, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,     {4, 4, 0, 1}, false)
+    CIPHER(3, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,  {0, 4, 0, 1}, false)
+#endif
+
+#if 1
+    /* ECDHE_RSA cipher suites */
+    CIPHER(1, TLS_ECDHE_RSA_WITH_RC4_128_SHA,           {1, 0, 0, 1}, false)
+    CIPHER(1, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,      {1, 1, 0, 1}, false)
+    CIPHER(1, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,       {1, 1, 0, 1}, false)
+    CIPHER(3, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,    {0, 1, 0, 0}, false)
+    CIPHER(1, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,       {1, 1, 0, 1}, false)
+    CIPHER(3, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,    {0, 0, 0, 0}, false) // Not supported by either gnutls or openssl
+#endif
+
+#if 1
+    /* ECDH_ECDSA cipher suites */
+    CIPHER(1, TLS_ECDH_ECDSA_WITH_RC4_128_SHA,          {4, 0, 0, 1}, false)
+    CIPHER(1, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,     {4, 0, 0, 1}, false)
+    CIPHER(1, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,      {4, 0, 0, 1}, false)
+    CIPHER(3, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,   {0, 0, 0, 1}, false)
+    CIPHER(1, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,      {4, 0, 0, 1}, false)
+    CIPHER(3, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,   {0, 0, 0, 1}, false)
+#endif
+
+#if 1
+    /* ECDH_RSA cipher suites */
+    CIPHER(1, TLS_ECDH_RSA_WITH_RC4_128_SHA,            {3, 0, 0, 1}, false)
+    CIPHER(1, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,       {3, 0, 0, 1}, false)
+    CIPHER(1, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,        {3, 0, 0, 1}, false)
+    CIPHER(3, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,     {0, 0, 0, 1}, false)
+    CIPHER(1, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,        {3, 0, 0, 1}, false)
+    CIPHER(3, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,     {0, 0, 0, 1}, false)
+#endif
+
+#if 0
+    CIPHER(1, TLS_PSK_WITH_RC4_128_SHA,                 {1, 1, 0, 0}, true)
+    CIPHER(1, TLS_PSK_WITH_3DES_EDE_CBC_SHA,            {1, 1, 0, 0}, true)
+    CIPHER(1, TLS_PSK_WITH_AES_128_CBC_SHA,             {1, 1, 0, 0}, true)
+    CIPHER(1, TLS_PSK_WITH_AES_256_CBC_SHA,             {1, 1, 0, 0}, true)
+    CIPHER(3, TLS_PSK_WITH_AES_128_CBC_SHA256,          {0, 1, 0, 0}, true)
+    CIPHER(3, TLS_PSK_WITH_AES_256_CBC_SHA384,          {0, 0, 0, 0}, true)
+    CIPHER(1, TLS_PSK_WITH_NULL_SHA,                    {0, 0, 0, 0}, true)
+    CIPHER(3, TLS_PSK_WITH_NULL_SHA256,                 {0, 1, 0, 0}, true)
+    CIPHER(3, TLS_PSK_WITH_NULL_SHA384,                 {0, 0, 0, 0}, true)
+#endif
+
+#if 0
+    CIPHER(3, TLS_RSA_WITH_AES_128_GCM_SHA256,          {0, 1, 0, 0}, false)
+    CIPHER(3, TLS_RSA_WITH_AES_256_GCM_SHA384,          {0, 0, 0, 0}, false)
+
+    CIPHER(3, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,      {0, 1, 0, 0}, false)
+    CIPHER(3, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,      {0, 0, 0, 0}, false)
+
+    CIPHER(3, TLS_DH_anon_WITH_AES_128_GCM_SHA256,      {0, 1, 0, 0}, false)
+    CIPHER(3, TLS_DH_anon_WITH_AES_256_GCM_SHA384,      {0, 0, 0, 0}, false)
+
+    CIPHER(3, TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,     {0, 0, 0, 0}, false)
+    CIPHER(3, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,     {0, 0, 0, 0}, false)
+
+    CIPHER(3, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,   {0, 0, 0, 0}, false)
+    CIPHER(3, TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,   {0, 0, 0, 0}, false)
+
+    CIPHER(3, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,    {0, 1, 0, 0}, false)
+    CIPHER(3, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,    {0, 0, 0, 0}, false)
+
+    CIPHER(3, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,  {0, 1, 0, 0}, false)
+    CIPHER(3, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,  {0, 0, 0, 0}, false)
+#endif
+
+
+
+#if 0
+    CIPHER(SSL_RSA_EXPORT_WITH_RC4_40_MD5, true, false, true,false)
+    CIPHER(SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, true, false, true, false)
+    CIPHER(SSL_RSA_WITH_DES_CBC_SHA, true, false, true, false)
+    CIPHER(SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, true, false, true, false)
+    CIPHER(SSL_DHE_RSA_WITH_DES_CBC_SHA, true, false, true, false)
+    CIPHER(SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, true, false, true, true)
+    CIPHER(SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, true, false, true, true)
+    CIPHER(SSL_DH_anon_WITH_DES_CBC_SHA, true, false, true, true)
+#endif
+
+
+    /* "Any" cipher suite - test the default configuration */
+    {0, SSL_NO_SUCH_CIPHERSUITE, "Any cipher 1", {1, 1, 1, 1}, false},
+    {0, SSL_NO_SUCH_CIPHERSUITE, "Any cipher 2", {2, 2, 0, 0}, false},
+
+    // Those servers wont talk SSL3.0 because they have EC certs
+    {1, SSL_NO_SUCH_CIPHERSUITE, "Any cipher 3", {3, 3, 0, 0}, false},
+    {1, SSL_NO_SUCH_CIPHERSUITE, "Any cipher 4", {4, 4, 0, 0}, false},
+
+
+    { -1, -1, NULL, }
+};
+
+static int ciphers_len = array_size(ciphers);
+
+
+
+#if 0 // currently unused
+static SSLCipherSuite sslcipher_atoi(const char *name)
+{
+    const CipherSuiteName *a = ciphers;
+    while(a->name) {
+        if (0 == strcmp(a->name, name)) break;
+        a++;
+    }
+    return a->cipher;
+}
+
+static const char * sslcipher_itoa(SSLCipherSuite num)
+{
+    const CipherSuiteName *a = ciphers;
+    while(a->cipher >= 0) {
+        if (num == a->cipher) break;
+        a++;
+    }
+    return a->name;
+}
+#endif // currently unused
+
+unsigned char dh_param_512_bytes[] = {
+    0x30, 0x46, 0x02, 0x41, 0x00, 0xdb, 0x3c, 0xfa, 0x13, 0xa6, 0xd2, 0x64,
+    0xdf, 0xcc, 0x40, 0xb1, 0x21, 0xd4, 0xf2, 0xad, 0x22, 0x7f, 0xce, 0xa0,
+    0xb9, 0x5b, 0x95, 0x1c, 0x2e, 0x99, 0xb0, 0x27, 0xd0, 0xed, 0xf4, 0xbd,
+    0xbb, 0x36, 0x93, 0xd0, 0x9d, 0x2b, 0x32, 0xa3, 0x56, 0x53, 0xe3, 0x7b,
+    0xed, 0xa1, 0x71, 0x82, 0x2e, 0x83, 0x14, 0xf9, 0xc0, 0x2f, 0x15, 0xcb,
+    0xcf, 0x97, 0xab, 0x88, 0x49, 0x20, 0x28, 0x2e, 0x63, 0x02, 0x01, 0x02
+};
+unsigned char *dh_param_512_der = dh_param_512_bytes;
+unsigned int dh_param_512_der_len = 72;
+
+typedef struct {
+    uint32_t session_id;
+    bool is_session_resume;
+    SSLContextRef st;
+    bool is_server;
+    bool client_side_auth;
+    bool dh_anonymous;
+    int comm;
+    CFArrayRef certs;
+} ssl_test_handle;
+
+
+
+
+#if 0
+static void hexdump(const uint8_t *bytes, size_t len) {
+       size_t ix;
+    printf("socket write(%p, %lu)\n", bytes, len);
+       for (ix = 0; ix < len; ++ix) {
+        if (!(ix % 16))
+            printf("\n");
+               printf("%02X ", bytes[ix]);
+       }
+       printf("\n");
+}
+#else
+#define hexdump(bytes, len)
+#endif
+
+static int SocketConnect(const char *hostName, int port)
+{
+    struct sockaddr_in  addr;
+    struct in_addr      host;
+       int                                     sock;
+    int                 err;
+    struct hostent      *ent;
+
+    if (hostName[0] >= '0' && hostName[0] <= '9')
+    {
+        host.s_addr = inet_addr(hostName);
+    }
+    else {
+               unsigned dex;
+#define GETHOST_RETRIES 5
+               /* seeing a lot of soft failures here that I really don't want to track down */
+               for(dex=0; dex<GETHOST_RETRIES; dex++) {
+                       if(dex != 0) {
+                               printf("\n...retrying gethostbyname(%s)", hostName);
+                       }
+                       ent = gethostbyname(hostName);
+                       if(ent != NULL) {
+                               break;
+                       }
+               }
+        if(ent == NULL) {
+                       printf("\n***gethostbyname(%s) returned: %s\n", hostName, hstrerror(h_errno));
+            return -1;
+        }
+        memcpy(&host, ent->h_addr, sizeof(struct in_addr));
+    }
+
+    sock = socket(AF_INET, SOCK_STREAM, 0);
+    addr.sin_addr = host;
+    addr.sin_port = htons((u_short)port);
+
+    addr.sin_family = AF_INET;
+    err = connect(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_in));
+
+    if(err!=0)
+    {
+        perror("connect failed");
+        return err;
+    }
+
+    return sock;
+}
+
+
+static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *length)
+{
+       size_t len = *length;
+       uint8_t *ptr = (uint8_t *)data;
+
+    do {
+        ssize_t ret;
+        do {
+            hexdump(ptr, len);
+            ret = write((int)conn, ptr, len);
+            if (ret < 0)
+                perror("send");
+        } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
+        if (ret > 0) {
+            len -= ret;
+            ptr += ret;
+        }
+        else
+            return -36;
+    } while (len > 0);
+
+    *length = *length - len;
+    return errSecSuccess;
+}
+
+static OSStatus SocketRead(SSLConnectionRef conn, void *data, size_t *length)
+{
+       size_t len = *length;
+       uint8_t *ptr = (uint8_t *)data;
+
+    do {
+        ssize_t ret;
+        do {
+            ret = read((int)conn, ptr, len);
+            if (ret < 0)
+                perror("send");
+        } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
+        if (ret > 0) {
+            len -= ret;
+            ptr += ret;
+        }
+        else
+            return -36;
+    } while (len > 0);
+
+    *length = *length - len;
+    return errSecSuccess;
+}
+
+unsigned char dn[] = {
+    0x30, 0x5e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+    0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
+    0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+    0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41,
+    0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+    0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
+    0x72, 0x69, 0x74, 0x79, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
+    0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74
+};
+unsigned int dn_len = 96;
+
+static SSLContextRef make_ssl_ref(bool server, bool client_side_auth, bool dh_anonymous,
+                                  bool dtls, int sock, CFArrayRef certs, SSLProtocol prot)
+{
+    SSLContextRef ctx = NULL;
+    if(dtls)
+        require_noerr(SSLNewDatagramContext(server, &ctx), out);
+    else
+        require_noerr(SSLNewContext(server, &ctx), out);
+    require_noerr(SSLSetProtocolVersionMax(ctx, prot), out);
+    require_noerr(SSLSetIOFuncs(ctx,
+                                (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
+    require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)sock), out);
+    //    static const char *peer_domain_name = "localhost";
+    // require_noerr(SSLSetPeerDomainName(ctx, peer_domain_name,
+    //                                   strlen(peer_domain_name)), out);
+
+
+    if (!dh_anonymous) {
+        if (server)
+            require_noerr(SSLSetCertificate(ctx, certs), out);
+        if (client_side_auth && server) {
+            require_noerr(SSLSetClientSideAuthenticate(ctx, kAlwaysAuthenticate), out);
+            require_noerr(SSLAddDistinguishedName(ctx, dn, dn_len), out);
+        }
+#if 0 /* Setting client certificate in advance */
+        if (client_side_auth && !server)
+            require_noerr(SSLSetCertificate(ctx, certs), out);
+#endif
+        if (client_side_auth && !server) /* enable break from SSLHandshake */
+            require_noerr(SSLSetSessionOption(ctx,
+                                              kSSLSessionOptionBreakOnCertRequested, true), out);
+        require_noerr(SSLSetSessionOption(ctx,
+                                          kSSLSessionOptionBreakOnServerAuth, true), out);
+    }
+
+    /* Tell SecureTransport to not check certs itself: it will break out of the
+     handshake to let us take care of it instead. */
+    require_noerr(SSLSetEnableCertVerify(ctx, false), out);
+
+    require_noerr(SSLSetPSKIdentity(ctx, "Client_identity", 15), out);
+    require_noerr(SSLSetPSKSharedSecret(ctx, "123456789", 9), out);
+
+
+    if (server) {
+        require_noerr(SSLSetDiffieHellmanParams(ctx,
+                                                 dh_param_512_der, dh_param_512_der_len), out);
+    }
+    else /* if client */ {
+    }
+
+    return ctx;
+out:
+    if (ctx)
+        SSLDisposeContext(ctx);
+    return NULL;
+}
+
+static OSStatus securetransport(ssl_test_handle * ssl)
+{
+    OSStatus ortn;
+    SSLContextRef ctx = ssl->st;
+    SecTrustRef trust = NULL;
+    bool got_server_auth = false, got_client_cert_req = false;
+
+    //uint64_t start = mach_absolute_time();
+    do {
+        ortn = SSLHandshake(ctx);
+
+        if (ortn == errSSLServerAuthCompleted)
+        {
+            require_string(!got_server_auth, out, "second server auth");
+            require_string(!got_client_cert_req, out, "got client cert req before server auth");
+            got_server_auth = true;
+            require_string(!trust, out, "Got errSSLServerAuthCompleted twice?");
+            /* verify peer cert chain */
+            require_noerr(SSLCopyPeerTrust(ctx, &trust), out);
+            SecTrustResultType trust_result = 0;
+            /* this won't verify without setting up a trusted anchor */
+            require_noerr(SecTrustEvaluate(trust, &trust_result), out);
+
+            CFIndex n_certs = SecTrustGetCertificateCount(trust);
+            /*fprintf(stderr, "%ld certs; trust_eval: %d\n", n_certs, trust_result); */
+
+            CFMutableArrayRef peer_cert_array = CFArrayCreateMutable(NULL, n_certs, &kCFTypeArrayCallBacks);
+            CFMutableArrayRef orig_peer_cert_array = CFArrayCreateMutableCopy(NULL, n_certs, ssl->certs);
+            while (n_certs--)
+                CFArrayInsertValueAtIndex(peer_cert_array, 0,
+                                          SecTrustGetCertificateAtIndex(trust, n_certs));
+
+            SecIdentityRef ident = (SecIdentityRef)CFArrayGetValueAtIndex(orig_peer_cert_array, 0);
+            SecCertificateRef peer_cert = NULL;
+            require_noerr(SecIdentityCopyCertificate(ident, &peer_cert), out);
+            CFArraySetValueAtIndex(orig_peer_cert_array, 0, peer_cert);
+            CFRelease(peer_cert);
+
+#if 0
+            require(CFEqual(orig_peer_cert_array, peer_cert_array), out);
+#endif
+            CFRelease(orig_peer_cert_array);
+            CFRelease(peer_cert_array);
+
+            /*
+             CFStringRef cert_name = SecCertificateCopySubjectSummary(cert);
+             char cert_name_buffer[1024];
+             require(CFStringGetFileSystemRepresentation(cert_name,
+             cert_name_buffer, sizeof(cert_name_buffer)), out);
+             fprintf(stderr, "cert name: %s\n", cert_name_buffer);
+             CFRelease(trust);
+             */
+        } else if (ortn == errSSLClientCertRequested) {
+            require_string(!got_client_cert_req, out, "second client cert req");
+            require_string(got_server_auth, out, "didn't get server auth first");
+            got_client_cert_req = true;
+
+            /* set client cert */
+            require_string(!ssl->is_server, out, "errSSLClientCertRequested while running server");
+            require_string(!ssl->dh_anonymous, out, "errSSLClientCertRequested while running anon DH");
+/*
+            CFArrayRef DNs = NULL;
+            require_noerr(SSLCopyDistinguishedNames    (ctx, &DNs), out);
+            require(DNs, out);
+            CFRelease(DNs);
+*/
+            require_string(ssl->client_side_auth, out, "errSSLClientCertRequested in run not testing that");
+            require_noerr(SSLSetCertificate(ctx, ssl->certs), out);
+        }
+    } while (ortn == errSSLWouldBlock
+             || ortn == errSSLServerAuthCompleted
+             || ortn == errSSLClientCertRequested);
+    require_noerr_action_quiet(ortn, out,
+                               fprintf(stderr, "Fell out of SSLHandshake with error: %d\n", (int)ortn));
+
+    if (!ssl->is_server && !ssl->dh_anonymous && !ssl->is_session_resume) {
+        require_action_string(got_server_auth, out, ortn=-1, "never got server auth.");
+        if (ssl->client_side_auth)
+            require_string(got_client_cert_req, out, "never got client cert req");
+    }
+    //uint64_t elapsed = mach_absolute_time() - start;
+    //fprintf(stderr, "setr elapsed: %lld\n", elapsed);
+
+    /*
+     SSLProtocol proto = kSSLProtocolUnknown;
+     require_noerr_quiet(SSLGetNegotiatedProtocolVersion(ctx, &proto), out); */
+
+    SSLCipherSuite cipherSuite;
+    require_noerr_quiet(ortn = SSLGetNegotiatedCipher(ctx, &cipherSuite), out);
+    //fprintf(stderr, "st negotiated %s\n", sslcipher_itoa(cipherSuite));
+
+       Boolean sessionWasResumed = false;
+    uint8_t session_id_data[MAX_SESSION_ID_LENGTH];
+    size_t session_id_length = sizeof(session_id_data);
+    require_noerr_quiet(ortn = SSLGetResumableSessionInfo(ctx, &sessionWasResumed, session_id_data, &session_id_length), out);
+    require_action(ssl->dh_anonymous || (ssl->is_session_resume == sessionWasResumed), out, ortn = -1);
+    // if (sessionWasResumed) fprintf(stderr, "st resumed session\n");
+    //hexdump(session_id_data, session_id_length);
+
+#if 1
+    char *req="GET / HTTP/1.0\r\n\r\n";
+    char ibuf[4096];
+    size_t len;
+    if (!ssl->is_server) {
+        require_noerr_quiet(ortn = SSLWrite(ctx, req, strlen(req), &len), out);
+        require_action_quiet(len == strlen(req), out, ortn = -1);
+        require_noerr_quiet(ortn = SSLRead(ctx, ibuf, sizeof(ibuf), &len), out);
+        ibuf[len]=0;
+//        printf(">>>\n%s<<<\n", ibuf);
+    }
+#endif
+
+out:
+    SSLClose(ctx);
+    SSLDisposeContext(ctx);
+    if (trust) CFRelease(trust);
+
+    return ortn;
+}
+
+
+
+static ssl_test_handle *
+ssl_test_handle_create(uint32_t session_id, bool resume, bool server, bool client_side_auth, bool dh_anonymous, bool dtls,
+                       int comm, CFArrayRef certs, SSLProtocol prot)
+{
+    ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle));
+    if (handle) {
+        handle->session_id = session_id;
+        handle->is_session_resume = resume;
+        handle->is_server = server;
+        handle->client_side_auth = client_side_auth;
+        handle->dh_anonymous = dh_anonymous;
+        handle->comm = comm;
+        handle->certs = certs;
+        handle->st = make_ssl_ref(server, client_side_auth, dh_anonymous, dtls, comm, certs, prot);
+    }
+    return handle;
+}
+
+static void
+tests(void)
+{
+    CFArrayRef client_certs = client_chain();
+    ok(client_certs, "got client certs");
+
+    int i;
+    int p, pr;
+
+    for (p=0; p<nservers;p++) {
+    for (pr=0; pr<nprotos; pr++) {
+
+        for (i=0; ciphers[i].name != NULL; i++) {
+
+            ssl_test_handle *client;
+            SSLProtocol proto = protos[pr];
+            int port;
+
+            int s;
+
+            SKIP: {
+                skip("This ciphersuite is not supported for this protocol version", 2, ciphers[i].prot<=pr);
+                skip("This server doesn't support this ciphersuite", 2, ciphers[i].portoffset[servers[p].cs_index]);
+
+                port=servers[p].base_port + ciphers[i].portoffset[servers[p].cs_index];
+                uint32_t session_id = (pr<<16) | (port<<8) | (i+1);
+
+                s=SocketConnect(servers[p].host, port);
+
+                ok(s,
+                   "Connect failed: %40s to %s:%d proto=%d", ciphers[i].name, servers[p].host, port, pr);
+
+                skip("Could not connect to the server", 1, s);
+
+                //fprintf(stderr, "session_id: %d\n", session_id);
+                client = ssl_test_handle_create(session_id, false, false/*client*/,
+                                                servers[p].client_auth, ciphers[i].dh_anonymous, 0,
+                                                s, client_certs, proto);
+
+                /* set fixed cipher on client and server */
+                if(ciphers[i].cipher != SSL_NO_SUCH_CIPHERSUITE) {
+                    if(SSLSetEnabledCiphers(client->st, &ciphers[i].cipher, 1)!=0)
+                        printf("Invalid cipher %04x (i=%d, p=%d, pr=%d)\n", ciphers[i].cipher, i, p, pr);
+                }
+
+                ok(!securetransport(client),
+                   "Handshake failed: %40s to %s:%d proto=%d", ciphers[i].name, servers[p].host, port, pr);
+
+                close(s);
+
+            } /* SKIP block */
+        }
+    } /* all ciphers */
+    } /* all servers */
+
+    CFReleaseNull(client_certs);
+}
+
+int ssl_43_ciphers(int argc, char *const *argv)
+{
+        plan_tests(1 + 2*nservers*nprotos*(ciphers_len-1));
+
+        tests();
+
+        return 0;
+}
+
+/*
+ TODO: count errSSLWouldBlock
+ TODO: skip tests that don't matter: client_auth and anonymous dh
+ TODO: we seem to only be negotiating tls - force a round of sslv3
+ TODO: allow secure transport to also defer client side auth to client
+ TODO: make sure anonymous dh is never selected if not expicitly enabled
+ TODO: make sure DHE is not available if not explicitly enabled and no parameters
+ are set
+ TODO: resumable sessions
+ */
diff --git a/libsecurity_ssl/regressions/ssl-44-crashes.c b/libsecurity_ssl/regressions/ssl-44-crashes.c
new file mode 100644 (file)
index 0000000..1d724b8
--- /dev/null
@@ -0,0 +1,292 @@
+//
+//  ssl-44-crashes.c
+//  libsecurity_ssl
+//
+//  Created by Fabrice Gautier on 10/1/12.
+//
+//
+
+
+#include <stdbool.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <AssertMacros.h>
+#include <Security/SecureTransportPriv.h> /* SSLSetOption */
+#include <Security/SecureTransport.h>
+#include <Security/SecPolicy.h>
+#include <Security/SecTrust.h>
+#include <Security/SecIdentity.h>
+#include <Security/SecIdentityPriv.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecKeyPriv.h>
+#include <Security/SecItem.h>
+#include <Security/SecRandom.h>
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <mach/mach_time.h>
+
+#if TARGET_OS_IPHONE
+#include <Security/SecRSAKey.h>
+#endif
+
+#include "ssl_regressions.h"
+#include "ssl-utils.h"
+
+
+typedef struct {
+    SSLContextRef st;
+    bool is_server;
+    int comm;
+    CFArrayRef certs;
+    int test;
+} ssl_test_handle;
+
+
+#pragma mark -
+#pragma mark SecureTransport support
+
+#if 0
+static void hexdump(const uint8_t *bytes, size_t len) {
+       size_t ix;
+    printf("socket write(%p, %lu)\n", bytes, len);
+       for (ix = 0; ix < len; ++ix) {
+        if (!(ix % 16))
+            printf("\n");
+               printf("%02X ", bytes[ix]);
+       }
+       printf("\n");
+}
+#else
+#define hexdump(bytes, len)
+#endif
+
+static OSStatus SocketWrite(SSLConnectionRef h, const void *data, size_t *length)
+{
+    int conn = ((const ssl_test_handle *)h)->comm;
+       size_t len = *length;
+       uint8_t *ptr = (uint8_t *)data;
+
+    do {
+        ssize_t ret;
+        do {
+            hexdump(ptr, len);
+            ret = write((int)conn, ptr, len);
+        } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
+        if (ret > 0) {
+            len -= ret;
+            ptr += ret;
+        }
+        else
+            return -36;
+    } while (len > 0);
+
+    *length = *length - len;
+    return errSecSuccess;
+}
+
+static int changepad=0;
+
+static OSStatus SocketRead(SSLConnectionRef h, void *data, size_t *length)
+{
+    const ssl_test_handle *handle=h;
+    int conn = handle->comm;
+       size_t len = *length;
+       uint8_t *ptr = (uint8_t *)data;
+
+
+    do {
+        ssize_t ret;
+        do {
+            ret = read((int)conn, ptr, len);
+        } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
+        if (ret > 0) {
+            len -= ret;
+            ptr += ret;
+        }
+        else
+            return -36;
+    } while (len > 0);
+
+    if(len!=0)
+        printf("Something went wrong here... len=%d\n", (int)len);
+
+    *length = *length - len;
+
+    ptr=data;
+
+    /* change pad in the data */
+    if(changepad==1) {
+        changepad=0;
+        ptr[31]=ptr[31]^0x08^0xff; // expected padding was 8, changing it to 0xff to trigger integer underflow.
+    }
+
+    /* We are reading a data application header */
+    if(*length==5 && ptr[0]==0x17) {
+        switch(handle->test) {
+            case 0:
+                ptr[4]=32; // reduce the size to 2 blocks and trigger integer underflow.
+                break;
+            case 1:
+                ptr[4]=48; // reduce the size to 3 blocks and triggering integer underflow in the padding.
+                break;
+            case 2:
+                changepad=1;
+                break;
+            default:
+                break;
+        }
+    }
+
+
+    return errSecSuccess;
+}
+
+
+
+static void *securetransport_ssl_thread(void *arg)
+{
+    OSStatus ortn;
+    ssl_test_handle * ssl = (ssl_test_handle *)arg;
+    SSLContextRef ctx = ssl->st;
+    bool got_server_auth = false;
+
+    //uint64_t start = mach_absolute_time();
+    do {
+        ortn = SSLHandshake(ctx);
+
+        if (ortn == errSSLServerAuthCompleted)
+        {
+            require_string(!got_server_auth, out, "second server auth");
+            got_server_auth = true;
+        }
+    } while (ortn == errSSLWouldBlock
+             || ortn == errSSLServerAuthCompleted);
+
+    require_noerr_action_quiet(ortn, out,
+                               fprintf(stderr, "Fell out of SSLHandshake with error: %d\n", (int)ortn));
+
+    unsigned char ibuf[8], obuf[8];
+    size_t len;
+    if (ssl->is_server) {
+        SecRandomCopyBytes(kSecRandomDefault, sizeof(obuf), obuf);
+        require_noerr_quiet(ortn = SSLWrite(ctx, obuf, sizeof(obuf), &len), out);
+        require_action_quiet(len == sizeof(obuf), out, ortn = -1);
+    } else {
+        require_noerr_quiet(ortn = SSLRead(ctx, ibuf, sizeof(ibuf), &len), out);
+        require_action_quiet(len == sizeof(ibuf), out, ortn = -1);
+    }
+
+out:
+    SSLClose(ctx);
+    CFRelease(ctx);
+    close(ssl->comm);
+    pthread_exit((void *)(intptr_t)ortn);
+    return NULL;
+}
+
+
+static ssl_test_handle *
+ssl_test_handle_create(bool server, int comm, CFArrayRef certs)
+{
+    ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle));
+    SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, server?kSSLServerSide:kSSLClientSide, kSSLStreamType);
+
+    require(handle, out);
+    require(ctx, out);
+
+    require_noerr(SSLSetIOFuncs(ctx,
+                                (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
+    require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)handle), out);
+
+    if (server)
+        require_noerr(SSLSetCertificate(ctx, certs), out);
+
+    require_noerr(SSLSetSessionOption(ctx,
+                                      kSSLSessionOptionBreakOnServerAuth, true), out);
+
+    /* Tell SecureTransport to not check certs itself: it will break out of the
+     handshake to let us take care of it instead. */
+    require_noerr(SSLSetEnableCertVerify(ctx, false), out);
+
+    handle->is_server = server;
+    handle->comm = comm;
+    handle->certs = certs;
+    handle->st = ctx;
+
+    return handle;
+
+out:
+    if (handle) free(handle);
+    if (ctx) CFRelease(ctx);
+    return NULL;
+}
+
+static void
+tests(void)
+{
+    pthread_t client_thread, server_thread;
+    CFArrayRef server_certs = server_chain();
+    ok(server_certs, "got server certs");
+
+    int i;
+
+    for(i=0; i<3; i++)
+    {
+        int sp[2];
+        if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) exit(errno);
+        fcntl(sp[0], F_SETNOSIGPIPE, 1);
+        fcntl(sp[1], F_SETNOSIGPIPE, 1);
+
+        ssl_test_handle *server, *client;
+
+        server = ssl_test_handle_create(true /*server*/, sp[0], server_certs);
+        client = ssl_test_handle_create(false/*client*/, sp[1], NULL);
+
+        server->test=i;
+        client->test=i;
+
+        require(client, out);
+        require(server, out);
+
+        SSLCipherSuite cipher = TLS_RSA_WITH_AES_128_CBC_SHA256;
+        require_noerr(SSLSetEnabledCiphers(client->st, &cipher, 1), out);
+
+        pthread_create(&client_thread, NULL, securetransport_ssl_thread, client);
+        pthread_create(&server_thread, NULL, securetransport_ssl_thread, server);
+
+        int server_err, client_err;
+        pthread_join(client_thread, (void*)&client_err);
+        pthread_join(server_thread, (void*)&server_err);
+
+
+        ok(!server_err, "Server error = %d", server_err);
+        /* test i=0 should cause errSSLClosedAbort, 1 & 2 should cause errSSLBadRecordMac */
+        ok(client_err==(i?errSSLBadRecordMac:errSSLClosedAbort), "Client error = %d", client_err);
+
+out:
+        free(client);
+        free(server);
+
+    }
+    CFReleaseNull(server_certs);
+}
+
+int ssl_44_crashes(int argc, char *const *argv)
+{
+
+    plan_tests(3*2 + 1 /*cert*/);
+
+
+    tests();
+
+    return 0;
+}
diff --git a/libsecurity_ssl/regressions/ssl-45-tls12.c b/libsecurity_ssl/regressions/ssl-45-tls12.c
new file mode 100644 (file)
index 0000000..1e97e89
--- /dev/null
@@ -0,0 +1,311 @@
+//
+//  ssl-43-ciphers.c
+//  regressions
+//
+//  Created by Fabrice Gautier on 6/7/11.
+//  Copyright 2011 Apple, Inc. All rights reserved.
+//
+
+#include <stdbool.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <AssertMacros.h>
+#include <Security/SecureTransportPriv.h> /* SSLSetOption */
+#include <Security/SecureTransport.h>
+#include <Security/SecPolicy.h>
+#include <Security/SecTrust.h>
+#include <Security/SecIdentity.h>
+#include <Security/SecIdentityPriv.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecKeyPriv.h>
+#include <Security/SecItem.h>
+#include <Security/SecRandom.h>
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <mach/mach_time.h>
+
+#include "ssl_regressions.h"
+
+typedef struct {
+    uint32_t session_id;
+    bool is_session_resume;
+    SSLContextRef st;
+    bool is_server;
+    bool client_side_auth;
+    bool dh_anonymous;
+    int comm;
+    CFArrayRef certs;
+} ssl_test_handle;
+
+
+
+#if 0
+static void hexdump(const uint8_t *bytes, size_t len) {
+       size_t ix;
+    printf("socket write(%p, %lu)\n", bytes, len);
+       for (ix = 0; ix < len; ++ix) {
+        if (!(ix % 16))
+            printf("\n");
+               printf("%02X ", bytes[ix]);
+       }
+       printf("\n");
+}
+#else
+#define hexdump(bytes, len)
+#endif
+
+static int SocketConnect(const char *hostName, int port)
+{
+    struct sockaddr_in  addr;
+    struct in_addr      host;
+       int                                     sock;
+    int                 err;
+    struct hostent      *ent;
+
+    if (hostName[0] >= '0' && hostName[0] <= '9')
+    {
+        host.s_addr = inet_addr(hostName);
+    }
+    else {
+               unsigned dex;
+#define GETHOST_RETRIES 5
+               /* seeing a lot of soft failures here that I really don't want to track down */
+               for(dex=0; dex<GETHOST_RETRIES; dex++) {
+                       if(dex != 0) {
+                               printf("\n...retrying gethostbyname(%s)", hostName);
+                       }
+                       ent = gethostbyname(hostName);
+                       if(ent != NULL) {
+                               break;
+                       }
+               }
+        if(ent == NULL) {
+                       printf("\n***gethostbyname(%s) returned: %s\n", hostName, hstrerror(h_errno));
+            return -1;
+        }
+        memcpy(&host, ent->h_addr, sizeof(struct in_addr));
+    }
+
+
+    sock = socket(AF_INET, SOCK_STREAM, 0);
+    addr.sin_addr = host;
+    addr.sin_port = htons((u_short)port);
+
+    addr.sin_family = AF_INET;
+    err = connect(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_in));
+
+    if(err!=0)
+    {
+        perror("connect failed");
+        return err;
+    }
+
+    return sock;
+}
+
+
+static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *length)
+{
+       size_t len = *length;
+       uint8_t *ptr = (uint8_t *)data;
+
+    do {
+        ssize_t ret;
+        do {
+            hexdump(ptr, len);
+            ret = write((int)conn, ptr, len);
+            if (ret < 0)
+                perror("send");
+        } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
+        if (ret > 0) {
+            len -= ret;
+            ptr += ret;
+        }
+        else
+            return -36;
+    } while (len > 0);
+
+    *length = *length - len;
+    return errSecSuccess;
+}
+
+static OSStatus SocketRead(SSLConnectionRef conn, void *data, size_t *length)
+{
+       size_t len = *length;
+       uint8_t *ptr = (uint8_t *)data;
+
+    do {
+        ssize_t ret;
+        do {
+            ret = read((int)conn, ptr, len);
+            if (ret < 0)
+                perror("send");
+        } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
+        if (ret > 0) {
+            len -= ret;
+            ptr += ret;
+        }
+        else
+            return -36;
+    } while (len > 0);
+
+    *length = *length - len;
+    return errSecSuccess;
+}
+
+static SSLContextRef make_ssl_ref(int sock, SSLProtocol maxprot)
+{
+    SSLContextRef ctx = NULL;
+
+    require_noerr(SSLNewContext(false, &ctx), out);
+    require_noerr(SSLSetIOFuncs(ctx,
+                                (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
+    require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)sock), out);
+
+    require_noerr(SSLSetSessionOption(ctx,
+                                      kSSLSessionOptionBreakOnServerAuth, true), out);
+
+    require_noerr(SSLSetProtocolVersionMax(ctx, maxprot), out);
+    /* Tell SecureTransport to not check certs itself: it will break out of the
+     handshake to let us take care of it instead. */
+    require_noerr(SSLSetEnableCertVerify(ctx, false), out);
+
+    return ctx;
+out:
+    if (ctx)
+        SSLDisposeContext(ctx);
+    return NULL;
+}
+
+static OSStatus securetransport(ssl_test_handle * ssl)
+{
+    OSStatus ortn;
+    SSLContextRef ctx = ssl->st;
+    SecTrustRef trust = NULL;
+    bool got_server_auth = false, got_client_cert_req = false;
+
+    //uint64_t start = mach_absolute_time();
+    do {
+        ortn = SSLHandshake(ctx);
+
+        if (ortn == errSSLServerAuthCompleted)
+        {
+            require_string(!got_server_auth, out, "second server auth");
+            require_string(!got_client_cert_req, out, "got client cert req before server auth");
+            got_server_auth = true;
+            require_string(!trust, out, "Got errSSLServerAuthCompleted twice?");
+            /* verify peer cert chain */
+            require_noerr(SSLCopyPeerTrust(ctx, &trust), out);
+            SecTrustResultType trust_result = 0;
+            /* this won't verify without setting up a trusted anchor */
+            require_noerr(SecTrustEvaluate(trust, &trust_result), out);
+
+        }    } while (ortn == errSSLWouldBlock
+             || ortn == errSSLServerAuthCompleted);
+    require_noerr_action_quiet(ortn, out,
+                               fprintf(stderr, "Fell out of SSLHandshake with error: %d\n", (int)ortn));
+
+    require_string(got_server_auth, out, "never got server auth");
+
+    //uint64_t elapsed = mach_absolute_time() - start;
+    //fprintf(stderr, "setr elapsed: %lld\n", elapsed);
+
+    /*
+     SSLProtocol proto = kSSLProtocolUnknown;
+     require_noerr_quiet(SSLGetNegotiatedProtocolVersion(ctx, &proto), out); */
+
+    SSLCipherSuite cipherSuite;
+    require_noerr_quiet(ortn = SSLGetNegotiatedCipher(ctx, &cipherSuite), out);
+    //fprintf(stderr, "st negotiated %02x\n", cipherSuite);
+
+
+out:
+    SSLClose(ctx);
+    SSLDisposeContext(ctx);
+    if (trust) CFRelease(trust);
+
+    return ortn;
+}
+
+
+
+static ssl_test_handle *
+ssl_test_handle_create(int comm, SSLProtocol maxprot)
+{
+    ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle));
+    if (handle) {
+        handle->comm = comm;
+        handle->st = make_ssl_ref(comm, maxprot);
+    }
+    return handle;
+}
+
+
+struct s_server {
+    char *host;
+    int port;
+    SSLProtocol maxprot;
+} servers[] = {
+    /* Good tls 1.2 servers */
+    {"encrypted.google.com", 443, kTLSProtocol12 },
+    {"www.amazon.com",443, kTLSProtocol12 },
+    {"www.mikestoolbox.org",443, kTLSProtocol12 },
+    /* servers with issues */
+    {"vpp.visa.co.uk", 443, kTLSProtocol12 }, // Doesnt like SSL 3.0 in initial record layer version
+    {"imap.softbank.jp",993, kTLSProtocol1 },   // softbank imap server, there are multiple servers behind this, one of them is not able to handle downgrading to TLS 1.2 properly (126.240.66.17).
+    {"mobile.charter.net",993, kTLSProtocol1 }, // Support 1.2 but fail to negotiate properly
+    {"mybill.vodafone.com.au", 443, kTLSProtocol1 }, /* 2056 bit server key */
+};
+
+#define NSERVERS (int)(sizeof(servers)/sizeof(servers[0]))
+#define NLOOPS 1
+
+static void
+tests(void)
+{
+    int p;
+
+    for(p=0; p<NSERVERS;p++) {
+    for(int loops=0; loops<NLOOPS; loops++) {
+
+        ssl_test_handle *client;
+
+        int s;
+        OSStatus r;
+
+        s=SocketConnect(servers[p].host, servers[p].port);
+        if(s<0) {
+            fail("connect failed with err=%d - %s:%d (try %d)", s, servers[p].host, servers[p].port, loops);
+            break;
+        }
+
+        client = ssl_test_handle_create(s, servers[p].maxprot);
+
+        r=securetransport(client);
+        ok(!r, "handshake failed with err=%ld - %s:%d (try %d)", (long)r, servers[p].host, servers[p].port, loops);
+
+        close(s);
+    } }
+}
+
+int ssl_45_tls12(int argc, char *const *argv)
+{
+        plan_tests(NSERVERS*NLOOPS);
+
+        tests();
+
+        return 0;
+}
diff --git a/libsecurity_ssl/regressions/ssl-46-SSLGetSupportedCiphers.c b/libsecurity_ssl/regressions/ssl-46-SSLGetSupportedCiphers.c
new file mode 100644 (file)
index 0000000..94daab8
--- /dev/null
@@ -0,0 +1,313 @@
+//
+//  ssl-46-SSLGetSupportedCiphers.c
+//  libsecurity_ssl
+//
+//  Created by Fabrice Gautier on 10/15/12.
+//
+//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <Security/SecureTransport.h>
+#include <AssertMacros.h>
+
+#include "ssl_regressions.h"
+#include "ssl-utils.h"
+
+
+#include "cipherSpecs.h"
+
+static int test_GetSupportedCiphers(SSLContextRef ssl)
+{
+    size_t max_ciphers = 0;
+    int fail=1;
+    SSLCipherSuite *ciphers = NULL;
+
+    require_noerr(SSLGetNumberSupportedCiphers(ssl, &max_ciphers), out);
+
+    size_t size = max_ciphers * sizeof (SSLCipherSuite);
+    ciphers = (SSLCipherSuite *) malloc(size);
+
+    require_string(ciphers, out, "out of memory");
+    memset(ciphers, 0xff, size);
+
+    size_t num_ciphers = max_ciphers;
+    require_noerr(SSLGetSupportedCiphers(ssl, ciphers, &num_ciphers), out);
+
+
+    for (size_t i = 0; i < num_ciphers; i++) {
+        require(ciphers[i]!=(SSLCipherSuite)(-1), out);
+    }
+
+    /* Success! */
+    fail=0;
+
+out:
+    if(ciphers) free(ciphers);
+    return fail;
+}
+
+static
+int allowed_default_ciphers(SSLCipherSuite cs)
+{
+    switch (cs) {
+
+        /* BAD to enable by default */
+
+
+        /*
+         * Tags for SSL 2 cipher kinds which are not specified
+         * for SSL 3.
+         */
+        case SSL_RSA_WITH_RC2_CBC_MD5:
+        case SSL_RSA_WITH_IDEA_CBC_MD5:
+        case SSL_RSA_WITH_DES_CBC_MD5:
+        case SSL_RSA_WITH_3DES_EDE_CBC_MD5:
+
+        /* Export and Simple DES ciphers */
+        case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
+        case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
+        case SSL_RSA_WITH_IDEA_CBC_SHA:
+        case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
+        case SSL_RSA_WITH_DES_CBC_SHA:
+        case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
+        case SSL_DH_DSS_WITH_DES_CBC_SHA:
+        case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
+        case SSL_DH_RSA_WITH_DES_CBC_SHA:
+        case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
+        case SSL_DHE_DSS_WITH_DES_CBC_SHA:
+        case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
+        case SSL_DHE_RSA_WITH_DES_CBC_SHA:
+        case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
+        case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
+        case SSL_DH_anon_WITH_DES_CBC_SHA:
+        case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
+        case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
+
+        case SSL_NO_SUCH_CIPHERSUITE:
+
+        /* Null ciphers. */
+        case TLS_NULL_WITH_NULL_NULL:
+        case TLS_RSA_WITH_NULL_MD5:
+        case TLS_RSA_WITH_NULL_SHA:
+        case TLS_RSA_WITH_NULL_SHA256:
+        case TLS_ECDH_ECDSA_WITH_NULL_SHA:
+        case TLS_ECDHE_ECDSA_WITH_NULL_SHA:
+        case TLS_ECDHE_RSA_WITH_NULL_SHA:
+        case TLS_ECDH_RSA_WITH_NULL_SHA:
+        case TLS_ECDH_anon_WITH_NULL_SHA:
+
+        /* Completely anonymous Diffie-Hellman */
+        case TLS_DH_anon_WITH_RC4_128_MD5:
+        case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA:
+        case TLS_DH_anon_WITH_AES_128_CBC_SHA:
+        case TLS_DH_anon_WITH_AES_256_CBC_SHA:
+        case TLS_DH_anon_WITH_AES_128_CBC_SHA256:
+        case TLS_DH_anon_WITH_AES_256_CBC_SHA256:
+        case TLS_DH_anon_WITH_AES_128_GCM_SHA256:
+        case TLS_DH_anon_WITH_AES_256_GCM_SHA384:
+        case TLS_ECDH_anon_WITH_RC4_128_SHA:
+        case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
+        case TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
+        case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
+
+            return 0;
+
+
+        /* OK to enable by default */
+
+        /* Server provided RSA certificate for key exchange. */
+        case TLS_RSA_WITH_RC4_128_MD5:
+        case TLS_RSA_WITH_RC4_128_SHA:
+        case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
+        case TLS_RSA_WITH_AES_128_CBC_SHA:
+        case TLS_RSA_WITH_AES_256_CBC_SHA:
+        case TLS_RSA_WITH_AES_128_CBC_SHA256:
+        case TLS_RSA_WITH_AES_256_CBC_SHA256:
+            return 1;
+
+        /* Server-authenticated (and optionally client-authenticated) Diffie-Hellman. */
+        case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
+        case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
+        case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
+        case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
+        case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
+        case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
+        case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
+        case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
+        case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
+        case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
+        case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
+        case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
+        case TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
+        case TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
+        case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
+        case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
+        case TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
+        case TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
+        case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
+        case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
+
+        case TLS_RSA_WITH_AES_128_GCM_SHA256:
+        case TLS_RSA_WITH_AES_256_GCM_SHA384:
+        case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
+        case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
+        case TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
+        case TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
+        case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
+        case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
+        case TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
+        case TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
+
+        case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
+        case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
+        case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
+        case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
+        case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
+        case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
+        case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
+        case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
+        case TLS_ECDH_RSA_WITH_RC4_128_SHA:
+        case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
+        case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
+        case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
+        case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
+        case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
+        case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
+        case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
+
+        case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
+        case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
+        case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
+        case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
+        case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
+        case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
+        case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
+        case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
+
+        case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
+        case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
+        case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
+        case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
+        case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
+        case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
+        case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
+        case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
+
+        /* RFC 5746 - Secure Renegotiation */
+        case TLS_EMPTY_RENEGOTIATION_INFO_SCSV:
+            return 1;
+
+        /* unknown cipher ? */
+        default:
+            return 0;
+    }
+}
+
+static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *length)
+{
+    return errSSLWouldBlock;
+}
+
+static OSStatus SocketRead(SSLConnectionRef conn, void *data, size_t *length)
+{
+    return errSSLWouldBlock;
+}
+
+
+static int test_GetEnabledCiphers(SSLContextRef ssl)
+{
+    size_t max_ciphers = 0;
+    int fail=1;
+    SSLCipherSuite *ciphers = NULL;
+    OSStatus err;
+
+    err=SSLSetIOFuncs(ssl, &SocketRead, &SocketWrite);
+    err=SSLSetConnection(ssl, NULL);
+    err=SSLHandshake(ssl);
+
+    require_noerr(SSLGetNumberEnabledCiphers(ssl, &max_ciphers), out);
+
+    size_t size = max_ciphers * sizeof (SSLCipherSuite);
+    ciphers = (SSLCipherSuite *) malloc(size);
+
+    require_string(ciphers, out, "out of memory");
+    memset(ciphers, 0xff, size);
+
+    size_t num_ciphers = max_ciphers;
+    require_noerr(SSLGetEnabledCiphers(ssl, ciphers, &num_ciphers), out);
+
+    for (size_t i = 0; i < num_ciphers; i++) {
+        char csname[256];
+        snprintf(csname, 256, "(%04x) %s", ciphers[i], ciphersuite_name(ciphers[i]));
+        /* Uncomment the next line if you want to list the default enabled ciphers */
+        //printf("%s\n", csname);
+        require_string(allowed_default_ciphers(ciphers[i]), out, csname);
+    }
+
+    /* Success! */
+    fail=0;
+
+out:
+    if(ciphers) free(ciphers);
+    return fail;
+}
+
+static int test_SetEnabledCiphers(SSLContextRef ssl)
+{
+    int fail=1;
+    size_t num_enabled;
+    
+    /* This should not fail as long as we have one valid cipher in this table */
+    SSLCipherSuite ciphers[] = {
+        SSL_RSA_WITH_RC2_CBC_MD5, /* unsupported */
+        TLS_RSA_WITH_NULL_SHA, /* supported by not enabled by default */
+        TLS_RSA_WITH_AES_128_CBC_SHA, /* Supported and enabled by default */
+    };
+
+    require_noerr(SSLSetEnabledCiphers(ssl, ciphers, sizeof(ciphers)/sizeof(SSLCipherSuite)), out);
+    require_noerr(SSLGetNumberEnabledCiphers(ssl, &num_enabled), out);
+
+    require(num_enabled==2, out); /* 2 ciphers in the above table are supported */
+
+    /* Success! */
+    fail=0;
+
+out:
+    return fail;
+}
+
+
+static void
+test(void)
+{
+    SSLContextRef ssl = NULL;
+
+    require(ssl=SSLCreateContext(kCFAllocatorDefault, kSSLClientSide, kSSLStreamType), out);
+    ok(ssl, "SSLCreateContext failed");
+
+    /* The order of this tests does matter, be careful when adding tests */
+    ok(!test_GetSupportedCiphers(ssl), "GetSupportedCiphers test failed");
+    ok(!test_GetEnabledCiphers(ssl), "GetEnabledCiphers test failed");
+
+    CFRelease(ssl); ssl=NULL;
+
+    require(ssl=SSLCreateContext(kCFAllocatorDefault, kSSLClientSide, kSSLStreamType), out);
+    ok(ssl, "SSLCreateContext failed");
+    
+    ok(!test_SetEnabledCiphers(ssl), "SetEnabledCiphers test failed");
+
+out:
+    if(ssl) CFRelease(ssl);
+}
+
+
+int ssl_46_SSLGetSupportedCiphers(int argc, char *const *argv)
+{
+    plan_tests(5);
+
+    test();
+
+    return 0;
+}
+
diff --git a/libsecurity_ssl/regressions/ssl-47-falsestart.c b/libsecurity_ssl/regressions/ssl-47-falsestart.c
new file mode 100644 (file)
index 0000000..6b6c61c
--- /dev/null
@@ -0,0 +1,334 @@
+//
+//  ssl-46-falsestart.c
+//  regressions
+//
+//  Created by Fabrice Gautier on 6/7/11.
+//  Copyright 2011 Apple, Inc. All rights reserved.
+//
+
+#include <stdbool.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <AssertMacros.h>
+#include <Security/SecureTransportPriv.h> /* SSLSetOption */
+#include <Security/SecureTransport.h>
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <mach/mach_time.h>
+
+
+#include "ssl_regressions.h"
+
+
+typedef struct {
+    uint32_t session_id;
+    bool is_session_resume;
+    SSLContextRef st;
+    bool is_server;
+    bool client_side_auth;
+    bool dh_anonymous;
+    int comm;
+    CFArrayRef certs;
+} ssl_test_handle;
+
+
+
+#if 0
+static void hexdump(const uint8_t *bytes, size_t len) {
+       size_t ix;
+    printf("socket write(%p, %lu)\n", bytes, len);
+       for (ix = 0; ix < len; ++ix) {
+        if (!(ix % 16))
+            printf("\n");
+               printf("%02X ", bytes[ix]);
+       }
+       printf("\n");
+}
+#else
+#define hexdump(bytes, len)
+#endif
+
+static int SocketConnect(const char *hostName, int port)
+{
+    struct sockaddr_in  addr;
+    struct in_addr      host;
+       int                                     sock;
+    int                 err;
+    struct hostent      *ent;
+
+    if (hostName[0] >= '0' && hostName[0] <= '9')
+    {
+        host.s_addr = inet_addr(hostName);
+    }
+    else {
+               unsigned dex;
+#define GETHOST_RETRIES 5
+               /* seeing a lot of soft failures here that I really don't want to track down */
+               for(dex=0; dex<GETHOST_RETRIES; dex++) {
+                       if(dex != 0) {
+                               printf("\n...retrying gethostbyname(%s)", hostName);
+                       }
+                       ent = gethostbyname(hostName);
+                       if(ent != NULL) {
+                               break;
+                       }
+               }
+        if(ent == NULL) {
+                       printf("\n***gethostbyname(%s) returned: %s\n", hostName, hstrerror(h_errno));
+            return -1;
+        }
+        memcpy(&host, ent->h_addr, sizeof(struct in_addr));
+    }
+
+
+    sock = socket(AF_INET, SOCK_STREAM, 0);
+    addr.sin_addr = host;
+    addr.sin_port = htons((u_short)port);
+
+    addr.sin_family = AF_INET;
+    err = connect(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_in));
+
+    if(err!=0)
+    {
+        perror("connect failed");
+        return err;
+    }
+
+    /* make non blocking */
+    fcntl(sock, F_SETFL, O_NONBLOCK);
+
+
+    return sock;
+}
+
+
+static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *length)
+{
+       size_t len = *length;
+       uint8_t *ptr = (uint8_t *)data;
+
+    do {
+        ssize_t ret;
+        do {
+            hexdump(ptr, len);
+            ret = write((int)conn, ptr, len);
+            if (ret < 0)
+                perror("send");
+        } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
+        if (ret > 0) {
+            len -= ret;
+            ptr += ret;
+        }
+        else
+            return -36;
+    } while (len > 0);
+
+    *length = *length - len;
+    return errSecSuccess;
+}
+
+static
+OSStatus SocketRead(
+                    SSLConnectionRef   connection,
+                    void                               *data,
+                    size_t                             *dataLength)
+{
+    int fd = (int)connection;
+    ssize_t len;
+    
+    len = read(fd, data, *dataLength);
+   
+    if(len<0) {
+        int theErr = errno;
+        switch(theErr) {
+            case EAGAIN:
+                //printf("SocketRead: EAGAIN\n");
+                *dataLength=0;
+                /* nonblocking, no data */
+                return errSSLWouldBlock;
+            default:
+                perror("SocketRead");
+                return -36;
+        }
+    }
+    
+    if(len<(ssize_t)*dataLength) {
+        *dataLength=len;
+        return errSSLWouldBlock;
+    }
+    
+    return errSecSuccess;
+}
+
+static SSLContextRef make_ssl_ref(int sock, SSLProtocol maxprot, Boolean false_start)
+{
+    SSLContextRef ctx = NULL;
+
+    require_noerr(SSLNewContext(false, &ctx), out);
+    require_noerr(SSLSetIOFuncs(ctx,
+                                (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
+    require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)sock), out);
+
+    require_noerr(SSLSetSessionOption(ctx,
+                                      kSSLSessionOptionBreakOnServerAuth, true), out);
+    
+    require_noerr(SSLSetSessionOption(ctx,
+                                      kSSLSessionOptionFalseStart, false_start), out);
+
+    require_noerr(SSLSetProtocolVersionMax(ctx, maxprot), out);
+
+    return ctx;
+out:
+    if (ctx)
+        SSLDisposeContext(ctx);
+    return NULL;
+}
+
+const char request[]="GET / HTTP/1.1\n\n";
+char reply[2048];
+
+static OSStatus securetransport(ssl_test_handle * ssl)
+{
+    OSStatus ortn;
+    SSLContextRef ctx = ssl->st;
+    SecTrustRef trust = NULL;
+    bool got_server_auth = false, got_client_cert_req = false;
+
+    ortn = SSLHandshake(ctx);
+    //fprintf(stderr, "Fell out of SSLHandshake with error: %ld\n", (long)ortn);
+    
+    size_t sent, received;
+    const char *r=request;
+    size_t l=sizeof(request);
+
+    do {
+        
+        ortn = SSLWrite(ctx, r, l, &sent);
+        
+        if(ortn == errSSLWouldBlock) {
+                r+=sent;
+                l-=sent;
+        }
+        
+        if (ortn == errSSLServerAuthCompleted)
+        {
+            require_string(!got_server_auth, out, "second server auth");
+            require_string(!got_client_cert_req, out, "got client cert req before server auth");
+            got_server_auth = true;
+            require_string(!trust, out, "Got errSSLServerAuthCompleted twice?");
+            /* verify peer cert chain */
+            require_noerr(SSLCopyPeerTrust(ctx, &trust), out);
+            SecTrustResultType trust_result = 0;
+            /* this won't verify without setting up a trusted anchor */
+            require_noerr(SecTrustEvaluate(trust, &trust_result), out);
+        }
+        
+    } while(ortn == errSSLWouldBlock || ortn == errSSLServerAuthCompleted);
+
+    //fprintf(stderr, "\nHTTP Request Sent\n");
+
+    require_noerr_action_quiet(ortn, out, printf("SSLWrite failed with err %ld\n", (long)ortn));
+
+    require_string(got_server_auth, out, "never got server auth");
+
+    do {
+        ortn = SSLRead(ctx, reply, sizeof(reply)-1, &received);
+        //fprintf(stderr, "r"); usleep(1000);
+    } while(ortn == errSSLWouldBlock);
+    
+    //fprintf(stderr, "\n");
+    
+    require_noerr_action_quiet(ortn, out, printf("SSLRead failed with err %ld\n", (long)ortn));
+
+    reply[received]=0;
+
+    //fprintf(stderr, "HTTP reply:\n");
+    //fprintf(stderr, "%s\n",reply);
+    
+out:
+    SSLClose(ctx);
+    SSLDisposeContext(ctx);
+    if (trust) CFRelease(trust);
+
+    return ortn;
+}
+
+
+
+static ssl_test_handle *
+ssl_test_handle_create(int comm, SSLProtocol maxprot, Boolean false_start)
+{
+    ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle));
+    if (handle) {
+        handle->comm = comm;
+        handle->st = make_ssl_ref(comm, maxprot, false_start);
+    }
+    return handle;
+}
+
+static 
+struct s_server {
+    char *host;
+    int port;
+    SSLProtocol maxprot;
+} servers[] = {
+    /* Good tls 1.2 servers */
+    {"encrypted.google.com", 443, kTLSProtocol12 },
+    {"www.amazon.com",443, kTLSProtocol12 },
+    {"www.mikestoolbox.org",443, kTLSProtocol12 },
+};
+
+#define NSERVERS (int)(sizeof(servers)/sizeof(servers[0]))
+#define NLOOPS 1
+
+static void
+tests(void)
+{
+    int p;
+    int fs;
+    
+    for(p=0; p<NSERVERS;p++) {
+    for(int loops=0; loops<NLOOPS; loops++) {
+    for(fs=0;fs<2; fs++) {
+
+        ssl_test_handle *client;
+
+        int s;
+        OSStatus r;
+
+        s=SocketConnect(servers[p].host, servers[p].port);
+        if(s<0) {
+            fail("connect failed with err=%d - %s:%d (try %d)", s, servers[p].host, servers[p].port, loops);
+            break;
+        }
+
+        client = ssl_test_handle_create(s, servers[p].maxprot, fs);
+
+        r=securetransport(client);
+        ok(!r, "handshake failed with err=%ld - %s:%d (try %d), false start=%d", (long)r, servers[p].host, servers[p].port, loops, fs);
+
+        close(s);
+    } } }
+}
+
+int ssl_47_falsestart(int argc, char *const *argv)
+{
+        plan_tests(NSERVERS*NLOOPS*2);
+
+        tests();
+
+        return 0;
+}
diff --git a/libsecurity_ssl/regressions/ssl-utils.c b/libsecurity_ssl/regressions/ssl-utils.c
new file mode 100644 (file)
index 0000000..304f29c
--- /dev/null
@@ -0,0 +1,259 @@
+//
+//  ssl-utils.c
+//  libsecurity_ssl
+//
+//  Created by Fabrice Gautier on 8/7/12.
+//
+//
+
+#include <Security/Security.h>
+#include <AssertMacros.h>
+
+#include "ssl-utils.h"
+
+#if TARGET_OS_IPHONE
+
+#include <Security/SecRSAKey.h>
+#include <Security/SecECKey.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecIdentityPriv.h>
+
+#include "privkey-1.h"
+#include "cert-1.h"
+
+static
+CFArrayRef chain_from_der(const unsigned char *pkey_der, size_t pkey_der_len, const unsigned char *cert_der, size_t cert_der_len)
+{
+    SecKeyRef pkey = NULL;
+    SecCertificateRef cert = NULL;
+    SecIdentityRef ident = NULL;
+    CFArrayRef items = NULL;
+
+    require(pkey = SecKeyCreateRSAPrivateKey(kCFAllocatorDefault, pkey_der, pkey_der_len, kSecKeyEncodingPkcs1), errOut);
+    require(cert = SecCertificateCreateWithBytes(kCFAllocatorDefault, cert_der, cert_der_len), errOut);
+    require(ident = SecIdentityCreate(kCFAllocatorDefault, cert, pkey), errOut);
+    require(items = CFArrayCreate(kCFAllocatorDefault, (const void **)&ident, 1, &kCFTypeArrayCallBacks), errOut);
+
+errOut:
+    CFReleaseSafe(pkey);
+    CFReleaseSafe(cert);
+    CFReleaseSafe(ident);
+    return items;
+}
+
+#else
+
+#include "identity-1.h"
+#define P12_PASSWORD "password"
+
+static
+CFArrayRef chain_from_p12(const unsigned char *p12_data, size_t p12_len)
+{
+    char keychain_path[] = "/tmp/keychain.XXXXXX";
+
+    SecKeychainRef keychain = NULL;
+    CFArrayRef list;
+    CFDataRef data;
+
+    SecExternalFormat format=kSecFormatPKCS12;
+    SecExternalItemType type=kSecItemTypeAggregate;
+    SecItemImportExportFlags flags=0;
+    SecKeyImportExportParameters params = {0,};
+    CFArrayRef out = NULL;
+
+    require_noerr(SecKeychainCopyDomainSearchList(kSecPreferencesDomainUser, &list), errOut);
+    require(mktemp(keychain_path), errOut);
+    require_noerr(SecKeychainCreate (keychain_path, strlen(P12_PASSWORD), P12_PASSWORD,
+                                     FALSE, NULL, &keychain), errOut);
+    require_noerr(SecKeychainSetDomainSearchList(kSecPreferencesDomainUser, list), errOut);    // restores the previous search list
+    require(data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, p12_data, p12_len, kCFAllocatorNull), errOut);
+
+
+    params.passphrase=CFSTR("password");
+    params.keyAttributes = CSSM_KEYATTR_PERMANENT | CSSM_KEYATTR_SENSITIVE;
+
+    require_noerr(SecKeychainItemImport(data, CFSTR(".p12"), &format, &type, flags,
+                                        &params, keychain, &out), errOut);
+
+errOut:
+    CFReleaseSafe(keychain);
+    CFReleaseSafe(list);
+
+    return out;
+}
+
+#endif
+
+CFArrayRef server_chain(void)
+{
+#if TARGET_OS_IPHONE
+    return chain_from_der(privkey_1_der, privkey_1_der_len, cert_1_der, cert_1_der_len);
+#else
+    return chain_from_p12(identity_1_p12, identity_1_p12_len);
+#endif
+}
+
+CFArrayRef client_chain(void)
+{
+#if TARGET_OS_IPHONE
+    return chain_from_der(privkey_1_der, privkey_1_der_len, cert_1_der, cert_1_der_len);
+#else
+    return chain_from_p12(identity_1_p12, identity_1_p12_len);
+#endif
+}
+
+const char *ciphersuite_name(SSLCipherSuite cs)
+{
+
+#define C(x) case x: return #x;
+    switch (cs) {
+
+            /* TLS 1.2 addenda, RFC 5246 */
+
+            /* Initial state. */
+            C(TLS_NULL_WITH_NULL_NULL)
+
+            /* Server provided RSA certificate for key exchange. */
+            C(TLS_RSA_WITH_NULL_MD5)
+            C(TLS_RSA_WITH_NULL_SHA)
+            C(TLS_RSA_WITH_RC4_128_MD5)
+            C(TLS_RSA_WITH_RC4_128_SHA)
+            C(TLS_RSA_WITH_3DES_EDE_CBC_SHA)
+            C(TLS_RSA_WITH_AES_128_CBC_SHA)
+            C(TLS_RSA_WITH_AES_256_CBC_SHA)
+            C(TLS_RSA_WITH_NULL_SHA256)
+            C(TLS_RSA_WITH_AES_128_CBC_SHA256)
+            C(TLS_RSA_WITH_AES_256_CBC_SHA256)
+
+            /* Server-authenticated (and optionally client-authenticated) Diffie-Hellman. */
+            C(TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA)
+            C(TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA)
+            C(TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA)
+            C(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA)
+            C(TLS_DH_DSS_WITH_AES_128_CBC_SHA)
+            C(TLS_DH_RSA_WITH_AES_128_CBC_SHA)
+            C(TLS_DHE_DSS_WITH_AES_128_CBC_SHA)
+            C(TLS_DHE_RSA_WITH_AES_128_CBC_SHA)
+            C(TLS_DH_DSS_WITH_AES_256_CBC_SHA)
+            C(TLS_DH_RSA_WITH_AES_256_CBC_SHA)
+            C(TLS_DHE_DSS_WITH_AES_256_CBC_SHA)
+            C(TLS_DHE_RSA_WITH_AES_256_CBC_SHA)
+            C(TLS_DH_DSS_WITH_AES_128_CBC_SHA256)
+            C(TLS_DH_RSA_WITH_AES_128_CBC_SHA256)
+            C(TLS_DHE_DSS_WITH_AES_128_CBC_SHA256)
+            C(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256)
+            C(TLS_DH_DSS_WITH_AES_256_CBC_SHA256)
+            C(TLS_DH_RSA_WITH_AES_256_CBC_SHA256)
+            C(TLS_DHE_DSS_WITH_AES_256_CBC_SHA256)
+            C(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256)
+
+            /* Completely anonymous Diffie-Hellman */
+            C(TLS_DH_anon_WITH_RC4_128_MD5)
+            C(TLS_DH_anon_WITH_3DES_EDE_CBC_SHA)
+            C(TLS_DH_anon_WITH_AES_128_CBC_SHA)
+            C(TLS_DH_anon_WITH_AES_256_CBC_SHA)
+            C(TLS_DH_anon_WITH_AES_128_CBC_SHA256)
+            C(TLS_DH_anon_WITH_AES_256_CBC_SHA256)
+
+            /* Addenda from rfc 5288 AES Galois Counter Mode (GCM) Cipher Suites
+             for TLS. */
+            C(TLS_RSA_WITH_AES_128_GCM_SHA256)
+            C(TLS_RSA_WITH_AES_256_GCM_SHA384)
+            C(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256)
+            C(TLS_DHE_RSA_WITH_AES_256_GCM_SHA384)
+            C(TLS_DH_RSA_WITH_AES_128_GCM_SHA256)
+            C(TLS_DH_RSA_WITH_AES_256_GCM_SHA384)
+            C(TLS_DHE_DSS_WITH_AES_128_GCM_SHA256)
+            C(TLS_DHE_DSS_WITH_AES_256_GCM_SHA384)
+            C(TLS_DH_DSS_WITH_AES_128_GCM_SHA256)
+            C(TLS_DH_DSS_WITH_AES_256_GCM_SHA384)
+            C(TLS_DH_anon_WITH_AES_128_GCM_SHA256)
+            C(TLS_DH_anon_WITH_AES_256_GCM_SHA384)
+
+            /* ECDSA addenda, RFC 4492 */
+            C(TLS_ECDH_ECDSA_WITH_NULL_SHA)
+            C(TLS_ECDH_ECDSA_WITH_RC4_128_SHA)
+            C(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA)
+            C(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA)
+            C(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA)
+            C(TLS_ECDHE_ECDSA_WITH_NULL_SHA)
+            C(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA)
+            C(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA)
+            C(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA)
+            C(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA)
+            C(TLS_ECDH_RSA_WITH_NULL_SHA)
+            C(TLS_ECDH_RSA_WITH_RC4_128_SHA)
+            C(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA)
+            C(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA)
+            C(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA)
+            C(TLS_ECDHE_RSA_WITH_NULL_SHA)
+            C(TLS_ECDHE_RSA_WITH_RC4_128_SHA)
+            C(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA)
+            C(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA)
+            C(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA)
+            C(TLS_ECDH_anon_WITH_NULL_SHA)
+            C(TLS_ECDH_anon_WITH_RC4_128_SHA)
+            C(TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA)
+            C(TLS_ECDH_anon_WITH_AES_128_CBC_SHA)
+            C(TLS_ECDH_anon_WITH_AES_256_CBC_SHA)
+
+            /* Addenda from rfc 5289  Elliptic Curve Cipher Suites with
+             HMAC SHA-256/384. */
+            C(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256)
+            C(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384)
+            C(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256)
+            C(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384)
+            C(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256)
+            C(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384)
+            C(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256)
+            C(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384)
+
+            /* Addenda from rfc 5289  Elliptic Curve Cipher Suites with
+             SHA-256/384 and AES Galois Counter Mode (GCM) */
+            C(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)
+            C(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384)
+            C(TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256)
+            C(TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384)
+            C(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256)
+            C(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384)
+            C(TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256)
+            C(TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384)
+
+            /* RFC 5746 - Secure Renegotiation */
+            C(TLS_EMPTY_RENEGOTIATION_INFO_SCSV)
+
+            /*
+             * Tags for SSL 2 cipher kinds which are not specified
+             * for SSL 3.
+             */
+            C(SSL_RSA_WITH_RC2_CBC_MD5)
+            C(SSL_RSA_WITH_IDEA_CBC_MD5)
+            C(SSL_RSA_WITH_DES_CBC_MD5)
+            C(SSL_RSA_WITH_3DES_EDE_CBC_MD5)
+            C(SSL_NO_SUCH_CIPHERSUITE)
+
+            C(SSL_RSA_EXPORT_WITH_RC4_40_MD5)
+            C(SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5)
+            C(SSL_RSA_WITH_IDEA_CBC_SHA)
+            C(SSL_RSA_EXPORT_WITH_DES40_CBC_SHA)
+            C(SSL_RSA_WITH_DES_CBC_SHA)
+            C(SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA)
+            C(SSL_DH_DSS_WITH_DES_CBC_SHA)
+            C(SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA)
+            C(SSL_DH_RSA_WITH_DES_CBC_SHA)
+            C(SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA)
+            C(SSL_DHE_DSS_WITH_DES_CBC_SHA)
+            C(SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA)
+            C(SSL_DHE_RSA_WITH_DES_CBC_SHA)
+            C(SSL_DH_anon_EXPORT_WITH_RC4_40_MD5)
+            C(SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA)
+            C(SSL_DH_anon_WITH_DES_CBC_SHA)
+            C(SSL_FORTEZZA_DMS_WITH_NULL_SHA)
+            C(SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA)
+
+
+        default:
+            return "Unknown Ciphersuite";
+    }
+
+}
diff --git a/libsecurity_ssl/regressions/ssl-utils.h b/libsecurity_ssl/regressions/ssl-utils.h
new file mode 100644 (file)
index 0000000..cf9a9f3
--- /dev/null
@@ -0,0 +1,22 @@
+//
+//  ssl-utils.h
+//  libsecurity_ssl
+//
+//  Created by Fabrice Gautier on 8/7/12.
+//
+//
+
+#ifndef __SSL_UTILS_H__
+#define __SSL_UTILS_H__
+
+#include <Security/SecureTransport.h>
+
+#define CFReleaseSafe(CF) { CFTypeRef _cf = (CF); if (_cf) {  CFRelease(_cf); } }
+#define CFReleaseNull(CF) { CFTypeRef _cf = (CF); if (_cf) {  (CF) = NULL; CFRelease(_cf); } }
+
+CFArrayRef server_chain(void);
+CFArrayRef client_chain(void);
+
+const char *ciphersuite_name(SSLCipherSuite cs);
+
+#endif
diff --git a/libsecurity_ssl/regressions/ssl_regressions.h b/libsecurity_ssl/regressions/ssl_regressions.h
new file mode 100644 (file)
index 0000000..5595c09
--- /dev/null
@@ -0,0 +1,25 @@
+#include <test/testmore.h>
+
+DISABLED_ONE_TEST(ssl_39_echo)
+
+#if TARGET_OS_IPHONE
+
+ONE_TEST(ssl_40_clientauth)
+ONE_TEST(ssl_41_clientauth)
+
+#else
+
+DISABLED_ONE_TEST(ssl_40_clientauth)
+DISABLED_ONE_TEST(ssl_41_clientauth)
+
+#endif
+
+ONE_TEST(ssl_42_ciphers)
+
+OFF_ONE_TEST(ssl_43_ciphers)
+
+ONE_TEST(ssl_44_crashes)
+ONE_TEST(ssl_45_tls12)
+ONE_TEST(ssl_46_SSLGetSupportedCiphers)
+ONE_TEST(ssl_47_falsestart)
+
index ea79ac1d653adb2cfeccd79e47a820e30d64a2ce..dbc18da163aa9f24eec5e777b570a0d71563723e 100644 (file)
@@ -37,7 +37,7 @@
 #include <arpa/inet.h>
 #include <fcntl.h>
 
 #include <arpa/inet.h>
 #include <fcntl.h>
 
-#include <MacErrors.h>
+#include <Security/SecBase.h>
 #include <time.h>
 #include <strings.h>
 
 #include <time.h>
 #include <strings.h>
 
@@ -189,7 +189,7 @@ OSStatus MakeServerConnection(
                }
         if(ent == NULL) {
                        printf("\n***gethostbyname(%s) returned: %s\n", hostName, hstrerror(h_errno));
                }
         if(ent == NULL) {
                        printf("\n***gethostbyname(%s) returned: %s\n", hostName, hstrerror(h_errno));
-            return ioErr;
+            return errSecIO;
         }
         memcpy(&host, ent->h_addr, sizeof(struct in_addr));
     }
         }
         memcpy(&host, ent->h_addr, sizeof(struct in_addr));
     }
@@ -200,7 +200,7 @@ OSStatus MakeServerConnection(
     addr.sin_family = AF_INET;
     if (connect(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)) != 0)
     {   printf("connect returned error\n");
     addr.sin_family = AF_INET;
     if (connect(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)) != 0)
     {   printf("connect returned error\n");
-        return ioErr;
+        return errSecIO;
     }
 
        if(nonBlocking) {
     }
 
        if(nonBlocking) {
@@ -208,14 +208,14 @@ OSStatus MakeServerConnection(
                int rtn = fcntl(sock, F_SETFL, O_NONBLOCK);
                if(rtn == -1) {
                        perror("fctnl(O_NONBLOCK)");
                int rtn = fcntl(sock, F_SETFL, O_NONBLOCK);
                if(rtn == -1) {
                        perror("fctnl(O_NONBLOCK)");
-                       return ioErr;
+                       return errSecIO;
                }
        }
        
     peer->ipAddr = addr.sin_addr.s_addr;
     peer->port = htons((u_short)port);
        *socketNo = (otSocket)sock;
                }
        }
        
     peer->ipAddr = addr.sin_addr.s_addr;
     peer->port = htons((u_short)port);
        *socketNo = (otSocket)sock;
-    return noErr;
+    return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -235,7 +235,7 @@ OSStatus ListenForClients(
     sock = socket(AF_INET, SOCK_STREAM, 0);
        if(sock < 1) {
                perror("socket");
     sock = socket(AF_INET, SOCK_STREAM, 0);
        if(sock < 1) {
                perror("socket");
-               return ioErr;
+               return errSecIO;
        }
     
     int reuse = 1;
        }
     
     int reuse = 1;
@@ -248,7 +248,7 @@ OSStatus ListenForClients(
     ent = gethostbyname("localhost");
     if (!ent) {
                perror("gethostbyname");
     ent = gethostbyname("localhost");
     if (!ent) {
                perror("gethostbyname");
-               return ioErr;
+               return errSecIO;
     }
     memcpy(&addr.sin_addr, ent->h_addr, sizeof(struct in_addr));
        
     }
     memcpy(&addr.sin_addr, ent->h_addr, sizeof(struct in_addr));
        
@@ -260,17 +260,17 @@ OSStatus ListenForClients(
                int theErr = errno;
                perror("bind");
                if(theErr == EADDRINUSE) {
                int theErr = errno;
                perror("bind");
                if(theErr == EADDRINUSE) {
-                       return opWrErr;
+                       return errSecOpWr;
                }
                else {
                }
                else {
-                       return ioErr;
+                       return errSecIO;
                }
     }
        if(nonBlocking) {
                int rtn = fcntl(sock, F_SETFL, O_NONBLOCK);
                if(rtn == -1) {
                        perror("fctnl(O_NONBLOCK)");
                }
     }
        if(nonBlocking) {
                int rtn = fcntl(sock, F_SETFL, O_NONBLOCK);
                if(rtn == -1) {
                        perror("fctnl(O_NONBLOCK)");
-                       return ioErr;
+                       return errSecIO;
                }
        }
 
                }
        }
 
@@ -279,13 +279,13 @@ OSStatus ListenForClients(
                switch(rtn) {
                        case 0:
                                *socketNo = (otSocket)sock;
                switch(rtn) {
                        case 0:
                                *socketNo = (otSocket)sock;
-                               rtn = noErr;
+                               rtn = errSecSuccess;
                                break;
                        case EWOULDBLOCK:
                                continue;
                        default:
                                perror("listen");
                                break;
                        case EWOULDBLOCK:
                                continue;
                        default:
                                perror("listen");
-                               rtn = ioErr;
+                               rtn = errSecIO;
                                break;
                }
                return rtn;
                                break;
                }
                return rtn;
@@ -324,7 +324,7 @@ OSStatus AcceptClientConnection(
                        }
                        else {
                                perror("accept");
                        }
                        else {
                                perror("accept");
-                               return ioErr;
+                               return errSecIO;
                        }
                }
                else {
                        }
                }
                else {
@@ -338,7 +338,7 @@ OSStatus AcceptClientConnection(
        #else
     peer->port = ntohs(addr.sin_port);
        #endif
        #else
     peer->port = ntohs(addr.sin_port);
        #endif
-    return noErr;
+    return errSecSuccess;
 }
 
 /*
 }
 
 /*
@@ -364,7 +364,7 @@ OSStatus SocketRead(
        UInt32                  initLen = bytesToGo;
        UInt8                   *currData = (UInt8 *)data;
        int                             sock = (int)((long)connection);
        UInt32                  initLen = bytesToGo;
        UInt8                   *currData = (UInt8 *)data;
        int                             sock = (int)((long)connection);
-       OSStatus                rtn = noErr;
+       OSStatus                rtn = errSecSuccess;
        UInt32                  bytesRead;
        ssize_t                 rrtn;
        
        UInt32                  bytesRead;
        ssize_t                 rrtn;
        
@@ -394,7 +394,7 @@ OSStatus SocketRead(
                                        /* normal... */
                                        //rtn = errSSLWouldBlock;
                                        /* ...for temp testing.... */
                                        /* normal... */
                                        //rtn = errSSLWouldBlock;
                                        /* ...for temp testing.... */
-                                       rtn = ioErr
+                                       rtn = errSecIO
                                        break;
                                case ECONNRESET:
                                        /* explicit peer abort */
                                        break;
                                case ECONNRESET:
                                        /* explicit peer abort */
@@ -407,7 +407,7 @@ OSStatus SocketRead(
                                default:
                                        dprintf(("SocketRead: read(%u) error %d, rrtn %d\n", 
                                                (unsigned)bytesToGo, theErr, (int)rrtn));
                                default:
                                        dprintf(("SocketRead: read(%u) error %d, rrtn %d\n", 
                                                (unsigned)bytesToGo, theErr, (int)rrtn));
-                                       rtn = ioErr;
+                                       rtn = errSecIO;
                                        break;
                        }
                        /* in any case, we're done with this call if rrtn <= 0 */
                                        break;
                        }
                        /* in any case, we're done with this call if rrtn <= 0 */
@@ -468,7 +468,7 @@ OSStatus SocketWrite(
                                return ortn;
                        }
                }
                                return ortn;
                        }
                }
-               return noErr;
+               return errSecSuccess;
        }
        *dataLength = 0;
 
        }
        *dataLength = 0;
 
@@ -489,12 +489,12 @@ OSStatus SocketWrite(
                        default:
                                dprintf(("SocketWrite: write(%u) error %d\n", 
                                          (unsigned)(dataLen - bytesSent), theErr));
                        default:
                                dprintf(("SocketWrite: write(%u) error %d\n", 
                                          (unsigned)(dataLen - bytesSent), theErr));
-                               ortn = ioErr;
+                               ortn = errSecIO;
                                break;
                }
        }
        else {
                                break;
                }
        }
        else {
-               ortn = noErr;
+               ortn = errSecSuccess;
        }
        tprintf("SocketWrite", dataLen, bytesSent, dataPtr);
        *dataLength = bytesSent;
        }
        tprintf("SocketWrite", dataLen, bytesSent, dataPtr);
        *dataLength = bytesSent;
index 8467f2641144d1ea32f20ba2477c60f71eb978a8..7b12af626caf5e0b251d5e848cc7adb2a2dae32c 100644 (file)
@@ -7,7 +7,8 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/param.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/param.h>
-#include <MacErrors.h>
+#include <Security/SecBase.h>
+
 #include <CoreFoundation/CoreFoundation.h>
 #include <Security/Security.h>
 #include <Security/SecIdentityPriv.h>
 #include <CoreFoundation/CoreFoundation.h>
 #include <Security/Security.h>
 #include <Security/SecIdentityPriv.h>
@@ -184,15 +185,15 @@ const char *sslGetProtocolVersionString(SSLProtocol prot)
  */
 const char *sslGetSSLErrString(OSStatus err)
 {
  */
 const char *sslGetSSLErrString(OSStatus err)
 {
-       static char noErrStr[20];
+       static char errSecSuccessStr[20];
 
        switch(err) {
 
        switch(err) {
-               case noErr:                         return "noErr";
-               case memFullErr:                    return "memFullErr";
-               case paramErr:                      return "paramErr";
-               case unimpErr:                      return "unimpErr";
-               case ioErr:                         return "ioErr";
-               case badReqErr:                     return "badReqErr";
+               case errSecSuccess:                 return "errSecSuccess";
+               case errSecAllocate:                return "errSecAllocate";
+               case errSecParam:                   return "errSecParam";
+               case errSecUnimplemented:           return "errSecUnimplemented";
+               case errSecIO:                      return "errSecIO";
+               case errSecBadReq:                  return "errSecBadReq";
                /* SSL errors */
                case errSSLProtocol:                return "errSSLProtocol";
                case errSSLNegotiation:             return "errSSLNegotiation";
                /* SSL errors */
                case errSSLProtocol:                return "errSSLProtocol";
                case errSSLNegotiation:             return "errSSLNegotiation";
@@ -247,7 +248,7 @@ const char *sslGetSSLErrString(OSStatus err)
                case errSecNotAvailable:            return "errSecNotAvailable";
                case errSecDuplicateItem:           return "errSecDuplicateItem";
                case errSecItemNotFound:            return "errSecItemNotFound";
                case errSecNotAvailable:            return "errSecNotAvailable";
                case errSecDuplicateItem:           return "errSecDuplicateItem";
                case errSecItemNotFound:            return "errSecItemNotFound";
-#if TARGET_OS_MAC
+#if !TARGET_OS_IPHONE
                case errSecReadOnly:                return "errSecReadOnly";
                case errSecAuthFailed:              return "errSecAuthFailed";
                case errSecNoSuchKeychain:          return "errSecNoSuchKeychain";
                case errSecReadOnly:                return "errSecReadOnly";
                case errSecAuthFailed:              return "errSecAuthFailed";
                case errSecNoSuchKeychain:          return "errSecNoSuchKeychain";
@@ -272,8 +273,8 @@ const char *sslGetSSLErrString(OSStatus err)
                        else
 #endif
                        {
                        else
 #endif
                        {
-                               sprintf(noErrStr, "Unknown (%d)", (unsigned)err);
-                               return noErrStr;
+                               sprintf(errSecSuccessStr, "Unknown (%d)", (unsigned)err);
+                               return errSecSuccessStr;
                        }
        }
 }
                        }
        }
 }
@@ -551,7 +552,7 @@ OSStatus sslCompleteCertChain(
        if(isRoot) {
                *outArray = certArray;
                CFRelease(certRef);
        if(isRoot) {
                *outArray = certArray;
                CFRelease(certRef);
-               return noErr;
+               return errSecSuccess;
        }
 
        /*
        }
 
        /*
@@ -633,7 +634,7 @@ OSStatus sslCompleteCertChain(
                         * Just go with the single subject cert we were given.
                         */
                        printf("***Warning: could not construct completed cert chain\n");
                         * Just go with the single subject cert we were given.
                         */
                        printf("***Warning: could not construct completed cert chain\n");
-                       ortn = noErr;
+                       ortn = errSecSuccess;
                        goto errOut;
        }
 
                        goto errOut;
        }
 
@@ -658,7 +659,7 @@ OSStatus sslCompleteCertChain(
                 */
                printf("***sslCompleteCertChain screwup: numResCerts %d\n",
                        (int)numResCerts);
                 */
                printf("***sslCompleteCertChain screwup: numResCerts %d\n",
                        (int)numResCerts);
-               ortn = noErr;
+               ortn = errSecSuccess;
                goto errOut;
        }
        if(!includeRoot) {
                goto errOut;
        }
        if(!includeRoot) {
@@ -778,12 +779,12 @@ OSStatus addTrustedSecCert(
 
        if(secCert == NULL) {
                printf("***addTrustedSecCert screwup\n");
 
        if(secCert == NULL) {
                printf("***addTrustedSecCert screwup\n");
-               return paramErr;
+               return errSecParam;
        }
        array = CFArrayCreateMutable(kCFAllocatorDefault,
                (CFIndex)1, &kCFTypeArrayCallBacks);
        if(array == NULL) {
        }
        array = CFArrayCreateMutable(kCFAllocatorDefault,
                (CFIndex)1, &kCFTypeArrayCallBacks);
        if(array == NULL) {
-               return memFullErr;
+               return errSecAllocate;
        }
        CFArrayAppendValue(array, secCert);
        ortn = SSLSetTrustedRoots(ctx, array, replaceAnchors ? true : false);
        }
        CFArrayAppendValue(array, secCert);
        ortn = SSLSetTrustedRoots(ctx, array, replaceAnchors ? true : false);
@@ -813,12 +814,12 @@ OSStatus sslReadAnchor(
        free(certData);
        if(!secCert) {
                printf("***SecCertificateCreateWithData returned NULL\n");
        free(certData);
        if(!secCert) {
                printf("***SecCertificateCreateWithData returned NULL\n");
-               return paramErr;
+               return errSecParam;
        }
        if (certRef) {
                *certRef = secCert;
        }
        }
        if (certRef) {
                *certRef = secCert;
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 OSStatus sslAddTrustedRoot(
 }
 
 OSStatus sslAddTrustedRoot(
@@ -857,7 +858,7 @@ OSStatus addIdentityAsTrustedRoot(
        CFIndex numItems = CFArrayGetCount(identArray);
        if(numItems == 0) {
                printf("***addIdentityAsTrustedRoot: empty identArray\n");
        CFIndex numItems = CFArrayGetCount(identArray);
        if(numItems == 0) {
                printf("***addIdentityAsTrustedRoot: empty identArray\n");
-               return paramErr;
+               return errSecParam;
        }
 
        /* Root should be the last item - could be identity, could be cert */
        }
 
        /* Root should be the last item - could be identity, could be cert */
@@ -882,7 +883,7 @@ OSStatus addIdentityAsTrustedRoot(
        }
        else {
                printf("***Bogus item in identity array\n");
        }
        else {
                printf("***Bogus item in identity array\n");
-               return paramErr;
+               return errSecParam;
        }
 }
 #else
        }
 }
 #else
@@ -890,7 +891,7 @@ OSStatus addIdentityAsTrustedRoot(
        SSLContextRef   ctx,
        CFArrayRef              identArray)
 {
        SSLContextRef   ctx,
        CFArrayRef              identArray)
 {
-       return noErr;
+       return errSecSuccess;
 }
 #endif
 
 }
 #endif
 
@@ -1185,7 +1186,7 @@ OSStatus sslSetCipherRestrictions(
        OSStatus ortn;
 
        if(cipherRestrict == '\0') {
        OSStatus ortn;
 
        if(cipherRestrict == '\0') {
-               return noErr;           // actually should not have been called
+               return errSecSuccess;           // actually should not have been called
        }
        switch(cipherRestrict) {
                case 'e':
        }
        switch(cipherRestrict) {
                case 'e':
@@ -1356,7 +1357,7 @@ OSStatus sslSetProtocols(
                        return ortn;
                }
        }
                        return ortn;
                }
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 void sslShowResult(
 }
 
 void sslShowResult(
@@ -1497,11 +1498,11 @@ int sslRunSession(
                serverParams->certState);
        ourRtn += sslVerifyClientCertState("client", clientParams->expectCertState,
                clientParams->certState);
                serverParams->certState);
        ourRtn += sslVerifyClientCertState("client", clientParams->expectCertState,
                clientParams->certState);
-       if(serverParams->ortn == noErr) {
+       if(serverParams->ortn == errSecSuccess) {
                ourRtn += sslVerifyCipher("server", serverParams->expectCipher,
                        serverParams->negCipher);
        }
                ourRtn += sslVerifyCipher("server", serverParams->expectCipher,
                        serverParams->negCipher);
        }
-       if(clientParams->ortn == noErr) {
+       if(clientParams->ortn == errSecSuccess) {
                ourRtn += sslVerifyCipher("client", clientParams->expectCipher,
                        clientParams->negCipher);
        }
                ourRtn += sslVerifyCipher("client", clientParams->expectCipher,
                        clientParams->negCipher);
        }
@@ -1555,9 +1556,9 @@ OSStatus sslAddTrustedRoots(
                }
                CFRelease(secCert);
                *foundOne = true;
                }
                CFRelease(secCert);
                *foundOne = true;
-       } while(ortn == noErr);
+       } while(ortn == errSecSuccess);
        CFRelease(srch);
        CFRelease(srch);
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
index 2cb0ce75d47440099cbd5533b5f76df38089fb0a..0fc0d5419f0c384e9c2f92cefae8f5e60833f621 100644 (file)
@@ -33,7 +33,7 @@
 #include "ioSock.h"
 #include "fileIo.h"
 
 #include "ioSock.h"
 #include "fileIo.h"
 
-#include <MacErrors.h>
+#include <Security/SecBase.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -446,7 +446,7 @@ static OSStatus sslServe(
                }
                if(e) {
                        printf("***SSLGetAllowAnonymousCiphers() returned true; expected false\n");
                }
                if(e) {
                        printf("***SSLGetAllowAnonymousCiphers() returned true; expected false\n");
-                       ortn = ioErr;
+                       ortn = errSecIO;
                        goto cleanup;
                }
        }
                        goto cleanup;
                }
        }
@@ -495,7 +495,7 @@ static OSStatus sslServe(
        }
 
        /* wait for one complete line or user says they've had enough */
        }
 
        /* wait for one complete line or user says they've had enough */
-       while(ortn == noErr) {
+       while(ortn == errSecSuccess) {
                length = sizeof(rcvBuf);
                ortn = SSLRead(ctx, rcvBuf, length, &length);
                if(length == 0) {
                length = sizeof(rcvBuf);
                ortn = SSLRead(ctx, rcvBuf, length, &length);
                if(length == 0) {
@@ -527,7 +527,7 @@ static OSStatus sslServe(
                        }
                }
                if (ortn == errSSLWouldBlock) {
                        }
                }
                if (ortn == errSSLWouldBlock) {
-                       ortn = noErr;
+                       ortn = errSecSuccess;
                }
        }
 
                }
        }
 
@@ -550,7 +550,7 @@ cleanup:
         * always do close, even on error - to flush outgoing write queue
         */
        OSStatus cerr = SSLClose(ctx);
         * always do close, even on error - to flush outgoing write queue
         */
        OSStatus cerr = SSLClose(ctx);
-       if(ortn == noErr) {
+       if(ortn == errSecSuccess) {
                ortn = cerr;
        }
        if(acceptSock) {
                ortn = cerr;
        }
        if(acceptSock) {
index a661ef8da61a3b7136111a15d165a70157682ea8..2ec660ed1fceacc9ebaf06f11e18ae3745720d7e 100644 (file)
@@ -16,7 +16,7 @@
 #include "ioSock.h"
 #include "fileIo.h"
 
 #include "ioSock.h"
 #include "fileIo.h"
 
-#include <MacErrors.h>
+#include <Security/SecBase.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -216,7 +216,7 @@ static OSStatus sslEvaluateTrust(
        bool            silent,
        CFArrayRef      *peerCerts)             // fetched and retained
 {
        bool            silent,
        CFArrayRef      *peerCerts)             // fetched and retained
 {
-       OSStatus ortn = noErr;
+       OSStatus ortn = errSecSuccess;
 #if USE_CDSA_CRYPTO
        SecTrustRef secTrust = NULL;
        ortn = SSLGetPeerSecTrust(ctx, &secTrust);
 #if USE_CDSA_CRYPTO
        SecTrustRef secTrust = NULL;
        ortn = SSLGetPeerSecTrust(ctx, &secTrust);
@@ -231,7 +231,7 @@ static OSStatus sslEvaluateTrust(
                if(!silent) {
                        printf("...No SecTrust available - this is a resumed session, right?\n");
                }
                if(!silent) {
                        printf("...No SecTrust available - this is a resumed session, right?\n");
                }
-               return noErr;
+               return errSecSuccess;
        }
        SecTrustResultType      secTrustResult;
        ortn = SecTrustEvaluate(secTrust, &secTrustResult);
        }
        SecTrustResultType      secTrustResult;
        ortn = SecTrustEvaluate(secTrust, &secTrustResult);
@@ -412,7 +412,7 @@ static OSStatus sslPing(
        }
        if(getConn != (SSLConnectionRef)sock) {
                printf("***SSLGetConnection error\n");
        }
        if(getConn != (SSLConnectionRef)sock) {
                printf("***SSLGetConnection error\n");
-               ortn = paramErr;
+               ortn = errSecParam;
                goto cleanup;
        }
        if(!pargs->allowHostnameSpoof) {
                goto cleanup;
        }
        if(!pargs->allowHostnameSpoof) {
@@ -487,7 +487,7 @@ static OSStatus sslPing(
                        printf("***SSLGetProtocolVersion screwup: try %s  get %s\n",
                                sslGetProtocolVersionString(pargs->tryVersion),
                                sslGetProtocolVersionString(getVers));
                        printf("***SSLGetProtocolVersion screwup: try %s  get %s\n",
                                sslGetProtocolVersionString(pargs->tryVersion),
                                sslGetProtocolVersionString(getVers));
-                       ortn = paramErr;
+                       ortn = errSecParam;
                        goto cleanup;
                }
        }
                        goto cleanup;
                }
        }
@@ -597,7 +597,7 @@ static OSStatus sslPing(
                }
                if(dummy != pargs->clientCerts) {
                        printf("***SSLGetCertificate error\n");
                }
                if(dummy != pargs->clientCerts) {
                        printf("***SSLGetCertificate error\n");
-                       ortn = ioErr;
+                       ortn = errSecIO;
                        goto cleanup;
                }
        }
                        goto cleanup;
                }
        }
@@ -636,7 +636,7 @@ static OSStatus sslPing(
                }
                if(!e) {
                        printf("***SSLGetAllowAnonymousCiphers() returned false; expected true\n");
                }
                if(!e) {
                        printf("***SSLGetAllowAnonymousCiphers() returned false; expected true\n");
-                       ortn = ioErr;
+                       ortn = errSecIO;
                        goto cleanup;
                }
        }
                        goto cleanup;
                }
        }
@@ -693,7 +693,7 @@ static OSStatus sslPing(
                                }
                                if(dummy != pargs->clientCerts) {
                                        printf("***SSLGetCertificate error\n");
                                }
                                if(dummy != pargs->clientCerts) {
                                        printf("***SSLGetCertificate error\n");
-                                       ortn = ioErr;
+                                       ortn = errSecIO;
                                        goto cleanup;
                                }
                        }
                                        goto cleanup;
                                }
                        }
@@ -777,7 +777,7 @@ static OSStatus sslPing(
         * Try to snag RCV_BUF_SIZE bytes. Exit if (!keepConnected and we get any data
         * at all), or (keepConnected and err != (none, wouldBlock)).
         */
         * Try to snag RCV_BUF_SIZE bytes. Exit if (!keepConnected and we get any data
         * at all), or (keepConnected and err != (none, wouldBlock)).
         */
-    while (ortn == noErr) {
+    while (ortn == errSecSuccess) {
                actLen = 0;
                if(pargs->dumpRxData) {
                        size_t avail = 0;
                actLen = 0;
                if(pargs->dumpRxData) {
                        size_t avail = 0;
@@ -795,12 +795,12 @@ static OSStatus sslPing(
         if((actLen == 0) && !pargs->silent) {
                sslOutputDot();
         }
         if((actLen == 0) && !pargs->silent) {
                sslOutputDot();
         }
-        if((actLen == 0) && (ortn == noErr)) {
+        if((actLen == 0) && (ortn == errSecSuccess)) {
                        printf("***Radar 2984932 confirmed***\n");
                }
         if (ortn == errSSLWouldBlock) {
                        /* for this loop, these are identical */
                        printf("***Radar 2984932 confirmed***\n");
                }
         if (ortn == errSSLWouldBlock) {
                        /* for this loop, these are identical */
-            ortn = noErr;
+            ortn = errSecSuccess;
         }
                if(ortn == errSSLServerAuthCompleted ||
                   ortn == errSSLClientCertRequested) {
         }
                if(ortn == errSSLServerAuthCompleted ||
                   ortn == errSSLClientCertRequested) {
@@ -811,7 +811,7 @@ static OSStatus sslPing(
                if((actLen > 0) && pargs->dumpRxData) {
                        dumpAscii(rcvBuf, actLen);
                }
                if((actLen > 0) && pargs->dumpRxData) {
                        dumpAscii(rcvBuf, actLen);
                }
-               if(ortn != noErr) {
+               if(ortn != errSecSuccess) {
                        /* connection closed by server or by error */
                        break;
                }
                        /* connection closed by server or by error */
                        break;
                }
@@ -833,18 +833,18 @@ static OSStatus sslPing(
 
     /* convert normal "shutdown" into zero err rtn */
        if(ortn == errSSLClosedGraceful) {
 
     /* convert normal "shutdown" into zero err rtn */
        if(ortn == errSSLClosedGraceful) {
-               ortn = noErr;
+               ortn = errSecSuccess;
        }
        if((ortn == errSSLClosedNoNotify) && !pargs->requireNotify) {
                /* relaxed disconnect rules */
        }
        if((ortn == errSSLClosedNoNotify) && !pargs->requireNotify) {
                /* relaxed disconnect rules */
-               ortn = noErr;
+               ortn = errSecSuccess;
        }
 cleanup:
        /*
         * always do close, even on error - to flush outgoing write queue
         */
        OSStatus cerr = SSLClose(ctx);
        }
 cleanup:
        /*
         * always do close, even on error - to flush outgoing write queue
         */
        OSStatus cerr = SSLClose(ctx);
-       if(ortn == noErr) {
+       if(ortn == errSecSuccess) {
                ortn = cerr;
        }
        if(sock) {
                ortn = cerr;
        }
        if(sock) {
index 9aa8cefc04525ec1c58dbf18b8a83d189659dc59..d9db09c91a881e0f7d0b102148d2b9a1d3919d92 100644 (file)
@@ -3157,7 +3157,7 @@ static SecTransformInstanceBlock AttributeNotificationTest(CFStringRef name,
        NSAutoreleasePool *pool = [NSAutoreleasePool new];      
                
        // generate a symmetrical key for testing
        NSAutoreleasePool *pool = [NSAutoreleasePool new];      
                
        // generate a symmetrical key for testing
-       OSStatus err = noErr;
+       OSStatus err = errSecSuccess;
        
        NSString* algNames[] = 
        {
        
        NSString* algNames[] = 
        {
@@ -3223,8 +3223,8 @@ static SecTransformInstanceBlock AttributeNotificationTest(CFStringRef name,
                uint32 keySizeInBits = keySizes[iCnt];
                
                err = SecKeyGenerate(NULL, algoToUse, keySizeInBits, handle, keyUse, keyAttrFlags, accessRef, &testKey);
                uint32 keySizeInBits = keySizes[iCnt];
                
                err = SecKeyGenerate(NULL, algoToUse, keySizeInBits, handle, keyUse, keyAttrFlags, accessRef, &testKey);
-               STAssertTrue(err == noErr, [NSString stringWithFormat:@"Unable to create a symmetrical key %@", algNames[iCnt]]);
-               if (noErr != err)
+               STAssertTrue(err == errSecSuccess, [NSString stringWithFormat:@"Unable to create a symmetrical key %@", algNames[iCnt]]);
+               if (errSecSuccess != err)
                {
                        continue;
                }
                {
                        continue;
                }
@@ -3325,8 +3325,8 @@ static SecTransformInstanceBlock AttributeNotificationTest(CFStringRef name,
                                                   privKeyUse, privateKeyAttributes,
                                                   NULL, &publicKey, &privateKey);
        
                                                   privKeyUse, privateKeyAttributes,
                                                   NULL, &publicKey, &privateKey);
        
-       STAssertTrue(noErr == err, @"Unable to create a key pair");
-       if (noErr != err)
+       STAssertTrue(errSecSuccess == err, @"Unable to create a key pair");
+       if (errSecSuccess != err)
        {
                cssmPerror(NULL, err);
                return;
        {
                cssmPerror(NULL, err);
                return;
@@ -3429,7 +3429,7 @@ static SecTransformInstanceBlock AttributeNotificationTest(CFStringRef name,
        {
                OSStatus err;
                err = SecKeyGenerate(NULL, CSSM_ALGID_AES, 256, handle, keyUse, keyAttrFlags, accessRef, &testKey);
        {
                OSStatus err;
                err = SecKeyGenerate(NULL, CSSM_ALGID_AES, 256, handle, keyUse, keyAttrFlags, accessRef, &testKey);
-               STAssertTrue(err == noErr, @"Unable to create a symmetrical key err=%x", err);
+               STAssertTrue(err == errSecSuccess, @"Unable to create a symmetrical key err=%x", err);
        }
        
        // The number of iterations is somewhat arbitrary.   When we use to have failures they were
        }
        
        // The number of iterations is somewhat arbitrary.   When we use to have failures they were
index d9bb66bd5e4d096b45415f3d0cb220dbab6f9ef5..2c960f75294f0c2f51d794c0a8013556872f2632 100644 (file)
 // corecrypto headers don't like C++ (on a deaper level then extern "C" {} can fix
 // so we need a C "shim" for all our corecrypto use.
 
 // corecrypto headers don't like C++ (on a deaper level then extern "C" {} can fix
 // so we need a C "shim" for all our corecrypto use.
 
+#warning "This declaration should be in some headers"
+CFDataRef oaep_padding_via_c(int desired_message_length, CFDataRef dataValue);
 CFDataRef oaep_padding_via_c(int desired_message_length, CFDataRef dataValue)
 {
        cc_unit paddingBuffer[ccn_nof_size(desired_message_length)];
        bzero(paddingBuffer, sizeof(cc_unit) * ccn_nof_size(desired_message_length)); // XXX needed??
        static dispatch_once_t randomNumberGenneratorInitialzed;
 CFDataRef oaep_padding_via_c(int desired_message_length, CFDataRef dataValue)
 {
        cc_unit paddingBuffer[ccn_nof_size(desired_message_length)];
        bzero(paddingBuffer, sizeof(cc_unit) * ccn_nof_size(desired_message_length)); // XXX needed??
        static dispatch_once_t randomNumberGenneratorInitialzed;
-       static static struct ccrng_system_state rng;
+       static struct ccrng_system_state rng;
        dispatch_once(&randomNumberGenneratorInitialzed, ^{
         ccrng_system_init(&rng);
        });
        dispatch_once(&randomNumberGenneratorInitialzed, ^{
         ccrng_system_init(&rng);
        });
@@ -53,6 +55,8 @@ CFDataRef oaep_padding_via_c(int desired_message_length, CFDataRef dataValue)
        return paddedValue ? paddedValue : (void*)GetNoMemoryErrorAndRetain();
 }
 
        return paddedValue ? paddedValue : (void*)GetNoMemoryErrorAndRetain();
 }
 
+#warning "This declaration should be in some headers"
+CFDataRef oaep_unpadding_via_c(CFDataRef encodedMessage);
 CFDataRef oaep_unpadding_via_c(CFDataRef encodedMessage)
 {
        size_t mlen = CFDataGetLength(encodedMessage);
 CFDataRef oaep_unpadding_via_c(CFDataRef encodedMessage)
 {
        size_t mlen = CFDataGetLength(encodedMessage);
index 3ae163f1088afe4bde34ff295036401f2d4f65d3..20c9abd47bf9d2bc2f54d868648ad6796fcb9e8c 100644 (file)
@@ -55,7 +55,7 @@ MD2Digest::MD2Digest() : Digest(kSecDigestMD2, CC_MD2_DIGEST_LENGTH)
 
 void MD2Digest::Update(const void* buffer, size_t length)
 {
 
 void MD2Digest::Update(const void* buffer, size_t length)
 {
-       CC_MD2_Update(&mContext, buffer, length);
+       CC_MD2_Update(&mContext, buffer, (CC_LONG)length);
 }
 
 
 }
 
 
@@ -84,7 +84,7 @@ MD4Digest::MD4Digest() : Digest(kSecDigestMD4, CC_MD4_DIGEST_LENGTH)
 
 void MD4Digest::Update(const void* buffer, size_t length)
 {
 
 void MD4Digest::Update(const void* buffer, size_t length)
 {
-       CC_MD4_Update(&mContext, buffer, length);
+       CC_MD4_Update(&mContext, buffer, (CC_LONG)length);
 }
 
 
 }
 
 
@@ -116,7 +116,7 @@ MD5Digest::MD5Digest() : Digest(kSecDigestMD5, CC_MD5_DIGEST_LENGTH)
 
 void MD5Digest::Update(const void* buffer, size_t length)
 {
 
 void MD5Digest::Update(const void* buffer, size_t length)
 {
-       CC_MD5_Update(&mContext, buffer, length);
+       CC_MD5_Update(&mContext, buffer, (CC_LONG)length);
 }
 
 
 }
 
 
@@ -145,7 +145,7 @@ SHA1Digest::SHA1Digest() : Digest(kSecDigestSHA1, CC_SHA1_DIGEST_LENGTH)
 
 void SHA1Digest::Update(const void* buffer, size_t length)
 {
 
 void SHA1Digest::Update(const void* buffer, size_t length)
 {
-       CC_SHA1_Update(&mContext, buffer, length);
+       CC_SHA1_Update(&mContext, buffer, (CC_LONG)length);
 }
 
 
 }
 
 
@@ -174,7 +174,7 @@ SHA256Digest::SHA256Digest() : Digest(kSecDigestSHA2, CC_SHA256_DIGEST_LENGTH)
 
 void SHA256Digest::Update(const void* buffer, size_t length)
 {
 
 void SHA256Digest::Update(const void* buffer, size_t length)
 {
-       CC_SHA256_Update(&mContext, buffer, length);
+       CC_SHA256_Update(&mContext, buffer, (CC_LONG)length);
 }
 
 
 }
 
 
@@ -203,7 +203,7 @@ SHA224Digest::SHA224Digest() : Digest(kSecDigestSHA2, CC_SHA224_DIGEST_LENGTH)
 
 void SHA224Digest::Update(const void* buffer, size_t length)
 {
 
 void SHA224Digest::Update(const void* buffer, size_t length)
 {
-       CC_SHA224_Update(&mContext, buffer, length);
+       CC_SHA224_Update(&mContext, buffer, (CC_LONG)length);
 }
 
 
 }
 
 
@@ -232,7 +232,7 @@ SHA512Digest::SHA512Digest() : Digest(kSecDigestSHA2, CC_SHA512_DIGEST_LENGTH)
 
 void SHA512Digest::Update(const void* buffer, size_t length)
 {
 
 void SHA512Digest::Update(const void* buffer, size_t length)
 {
-       CC_SHA512_Update(&mContext, buffer, length);
+       CC_SHA512_Update(&mContext, buffer, (CC_LONG)length);
 }
 
 
 }
 
 
@@ -261,7 +261,7 @@ SHA384Digest::SHA384Digest() : Digest(kSecDigestSHA2, CC_SHA384_DIGEST_LENGTH)
 
 void SHA384Digest::Update(const void* buffer, size_t length)
 {
 
 void SHA384Digest::Update(const void* buffer, size_t length)
 {
-       CC_SHA384_Update(&mContext, buffer, length);
+       CC_SHA384_Update(&mContext, buffer, (CC_LONG)length);
 }
 
 
 }
 
 
@@ -396,8 +396,8 @@ CFErrorRef DigestTransform::Setup(CFTypeRef dt, CFIndex length)
                }
        }
     
                }
        }
     
-    int lengthInt = mDigest->DigestLength();
-    CFNumberRef lengthNumber = CFNumberCreate(NULL, kCFNumberIntType, &lengthInt);
+    long lengthInt = mDigest->DigestLength();
+    CFNumberRef lengthNumber = CFNumberCreate(NULL, kCFNumberLongType, &lengthInt);
     SendAttribute(kSecDigestLengthAttribute, lengthNumber);
     CFRelease(lengthNumber);
        return NULL;
     SendAttribute(kSecDigestLengthAttribute, lengthNumber);
     CFRelease(lengthNumber);
        return NULL;
index 25bb162283d82c609f21c427b9adc9b6d32e2bdc..1b5900a2f664cc1112b7e710ed5649bb55ef34b5 100644 (file)
@@ -12,7 +12,7 @@ class Digest
 {
 protected:
        CFStringRef mDigestType;
 {
 protected:
        CFStringRef mDigestType;
-       int mDigestLength;
+       size_t mDigestLength;
 
 public:
        Digest(CFStringRef digestType, size_t digestLength);
 
 public:
        Digest(CFStringRef digestType, size_t digestLength);
index ff7716c8862c2be23810229062fa3b2a9ab93c93..eaeb08cc7c7c7c36770243a7a40274f0d09c8e15 100644 (file)
@@ -183,7 +183,7 @@ static SecTransformInstanceBlock DecodeTransform(CFStringRef name,
                                                CFIndex enc_cnt = d ? CFDataGetLength(d) : 0;
                                                const unsigned char *enc = d ? CFDataGetBytePtr(d) : NULL;
                                                const unsigned char *enc_end = enc + enc_cnt;
                                                CFIndex enc_cnt = d ? CFDataGetLength(d) : 0;
                                                const unsigned char *enc = d ? CFDataGetBytePtr(d) : NULL;
                                                const unsigned char *enc_end = enc + enc_cnt;
-                                               int n_chunks = (leftover_cnt + enc_cnt) / out_chunk_size + 1;
+                                               long n_chunks = (leftover_cnt + enc_cnt) / out_chunk_size + 1;
 
                                                unsigned char *out_base = malloc(n_chunks * out_chunk_size);
                                                if (!out_base) {
 
                                                unsigned char *out_base = malloc(n_chunks * out_chunk_size);
                                                if (!out_base) {
@@ -276,7 +276,7 @@ static SecTransformInstanceBlock DecodeTransform(CFStringRef name,
                                                        CFIndex enc_cnt = d ? CFDataGetLength(d) : 0;
                                                        const unsigned char *enc = d ? CFDataGetBytePtr(d) : NULL;
                                                        const unsigned char *enc_end = enc + enc_cnt;
                                                        CFIndex enc_cnt = d ? CFDataGetLength(d) : 0;
                                                        const unsigned char *enc = d ? CFDataGetBytePtr(d) : NULL;
                                                        const unsigned char *enc_end = enc + enc_cnt;
-                                                       int n_chunks = (bits_accumulated/8 + enc_cnt) / out_chunk_size + 1;
+                                                       long n_chunks = (bits_accumulated/8 + enc_cnt) / out_chunk_size + 1;
 
                                                        unsigned char *out_base = malloc(n_chunks * out_chunk_size);
                                                        if (!out_base) {
 
                                                        unsigned char *out_base = malloc(n_chunks * out_chunk_size);
                                                        if (!out_base) {
@@ -362,7 +362,7 @@ static SecTransformInstanceBlock DecodeTransform(CFStringRef name,
 
                                                        if (d) {
                                                                zs.next_in = (UInt8 *)(CFDataGetBytePtr(d)); // we know that zlib will not 'futz' with the data
 
                                                        if (d) {
                                                                zs.next_in = (UInt8 *)(CFDataGetBytePtr(d)); // we know that zlib will not 'futz' with the data
-                                                               zs.avail_in = CFDataGetLength(d);
+                                                               zs.avail_in = (uInt)CFDataGetLength(d);
                                                        } else {
                                                                zs.next_in = NULL;
                                                                zs.avail_in = 0;
                                                        } else {
                                                                zs.next_in = NULL;
                                                                zs.avail_in = 0;
@@ -379,7 +379,7 @@ static SecTransformInstanceBlock DecodeTransform(CFStringRef name,
                                                                }
 
                                                                zs.next_out = buf;
                                                                }
 
                                                                zs.next_out = buf;
-                                                               zs.avail_out = buf_sz;
+                                                               zs.avail_out = (uInt)buf_sz;
 
                                                                rc = inflate(&zs, d ? Z_NO_FLUSH : Z_FINISH);
 
 
                                                                rc = inflate(&zs, d ? Z_NO_FLUSH : Z_FINISH);
 
@@ -511,7 +511,8 @@ SecTransformRef SecDecodeTransformCreate(CFTypeRef DecodeType, CFErrorRef* error
        return tr;
 }
 
        return tr;
 }
 
-unsigned char *encode_base64(const unsigned char *bin, unsigned char *base64, int bin_cnt) {   
+static
+unsigned char *encode_base64(const unsigned char *bin, unsigned char *base64, CFIndex bin_cnt) {
        for(; bin_cnt > 0; bin_cnt -= 3, base64 += 4, bin += 3) {
                switch (bin_cnt)
                {
        for(; bin_cnt > 0; bin_cnt -= 3, base64 += 4, bin += 3) {
                switch (bin_cnt)
                {
@@ -616,7 +617,7 @@ static SecTransformInstanceBlock EncodeTransform(CFStringRef name,
                                {
                                        __block struct { unsigned char a[3]; } leftover;
                                        static const short int in_chunk_size = 3, out_chunk_size = 4;
                                {
                                        __block struct { unsigned char a[3]; } leftover;
                                        static const short int in_chunk_size = 3, out_chunk_size = 4;
-                                       __block int leftover_cnt = 0;
+                                       __block CFIndex leftover_cnt = 0;
 
                                        SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, 
                                                kSecEncodeLineLengthAttribute, 
 
                                        SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, 
                                                kSecEncodeLineLengthAttribute, 
@@ -631,8 +632,8 @@ static SecTransformInstanceBlock EncodeTransform(CFStringRef name,
                                                        CFDataRef d = value;
                                                        CFIndex in_len = d ? CFDataGetLength(d) : 0;
                                                        const unsigned char *in = d ? CFDataGetBytePtr(d) : NULL;
                                                        CFDataRef d = value;
                                                        CFIndex in_len = d ? CFDataGetLength(d) : 0;
                                                        const unsigned char *in = d ? CFDataGetBytePtr(d) : NULL;
-                                                       int n_chunks = in_len / in_chunk_size + 3;
-                                                       int buf_len = n_chunks * out_chunk_size;
+                                                       CFIndex n_chunks = in_len / in_chunk_size + 3;
+                                                       CFIndex buf_len = n_chunks * out_chunk_size;
                                                        if (target_line_length) 
                                                        {
                                                                buf_len += (n_chunks * out_chunk_size) / target_line_length;
                                                        if (target_line_length) 
                                                        {
                                                                buf_len += (n_chunks * out_chunk_size) / target_line_length;
@@ -745,8 +746,8 @@ static SecTransformInstanceBlock EncodeTransform(CFStringRef name,
                                                        CFIndex in_len = d ? CFDataGetLength(d) : 0;
                                                        const unsigned char *in = d ? CFDataGetBytePtr(d) : NULL;
                                                        const unsigned char *in_end = in + in_len;
                                                        CFIndex in_len = d ? CFDataGetLength(d) : 0;
                                                        const unsigned char *in = d ? CFDataGetBytePtr(d) : NULL;
                                                        const unsigned char *in_end = in + in_len;
-                                                       int n_chunks = in_len / in_chunk_size + 3;
-                                                       int buf_len = n_chunks * out_chunk_size;
+                                                       CFIndex n_chunks = in_len / in_chunk_size + 3;
+                                                       CFIndex buf_len = n_chunks * out_chunk_size;
                                                        if (target_line_length) 
                                                        {
                                                                buf_len += (n_chunks * out_chunk_size) / target_line_length;
                                                        if (target_line_length) 
                                                        {
                                                                buf_len += (n_chunks * out_chunk_size) / target_line_length;
@@ -859,7 +860,7 @@ static SecTransformInstanceBlock EncodeTransform(CFStringRef name,
 
                                                        if (d) {
                                                                zs.next_in = (UInt8 *)CFDataGetBytePtr(d); // We know that xLib will not 'Futz' with the data
 
                                                        if (d) {
                                                                zs.next_in = (UInt8 *)CFDataGetBytePtr(d); // We know that xLib will not 'Futz' with the data
-                                                               zs.avail_in = CFDataGetLength(d);
+                                                               zs.avail_in = (uInt)CFDataGetLength(d);
                                                        } else {
                                                                zs.next_in = NULL;
                                                                zs.avail_in = 0;
                                                        } else {
                                                                zs.next_in = NULL;
                                                                zs.avail_in = 0;
@@ -876,7 +877,7 @@ static SecTransformInstanceBlock EncodeTransform(CFStringRef name,
                                                                }
 
                                                                zs.next_out = buf;
                                                                }
 
                                                                zs.next_out = buf;
-                                                               zs.avail_out = buf_sz;
+                                                               zs.avail_out = (uInt)buf_sz;
 
                                                                rc = deflate(&zs, d ? Z_NO_FLUSH : Z_FINISH);
 
 
                                                                rc = deflate(&zs, d ? Z_NO_FLUSH : Z_FINISH);
 
index 9398e514247e370ac1325149101514a32386970c..fc2f94cf1d37fb4ecfe001df4690a35525d3b156 100644 (file)
@@ -33,8 +33,8 @@
 
 static CFStringRef kEncryptTransformType = CFSTR("Encrypt Transform");
 static CFStringRef kDecryptTransformType = CFSTR("Decrypt Transform");
 
 static CFStringRef kEncryptTransformType = CFSTR("Encrypt Transform");
 static CFStringRef kDecryptTransformType = CFSTR("Decrypt Transform");
-static const char *kEncryptTransformType_cstr = "Encrypt Transform";
-static const char *kDecryptTransformType_cstr = "Decrypt Transform";
+//static const char *kEncryptTransformType_cstr = "Encrypt Transform";
+//static const char *kDecryptTransformType_cstr = "Decrypt Transform";
 static uint8 iv[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
 static const CSSM_DATA gKeySalt = {16, iv}; // default Salt for key
 
 static uint8 iv[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
 static const CSSM_DATA gKeySalt = {16, iv}; // default Salt for key
 
@@ -132,9 +132,9 @@ CFErrorRef EncryptDecryptBase::SerializedTransformStartingExecution()
                return CreateSecTransformErrorRef(kSecTransformErrorAttributeNotFound, "The attribute %@ was not found.", kSecEncryptKey);
        }
        
                return CreateSecTransformErrorRef(kSecTransformErrorAttributeNotFound, "The attribute %@ was not found.", kSecEncryptKey);
        }
        
-       OSStatus err = noErr;
+       OSStatus err = errSecSuccess;
        err = SecKeyGetCSSMKey(key, (const CSSM_KEY **)&m_cssm_key);
        err = SecKeyGetCSSMKey(key, (const CSSM_KEY **)&m_cssm_key);
-       if (noErr != err)
+       if (errSecSuccess != err)
        {
                CFStringRef result = SecCopyErrorMessageString(err, NULL);
                CFErrorRef retValue = CreateSecTransformErrorRef(err, "CDSA error (%@).", result);
        {
                CFStringRef result = SecCopyErrorMessageString(err, NULL);
                CFErrorRef retValue = CreateSecTransformErrorRef(err, "CDSA error (%@).", result);
@@ -144,7 +144,7 @@ CFErrorRef EncryptDecryptBase::SerializedTransformStartingExecution()
        
        CSSM_CSP_HANDLE csp;
        err = SecKeyGetCSPHandle(key, &csp);
        
        CSSM_CSP_HANDLE csp;
        err = SecKeyGetCSPHandle(key, &csp);
-       if (noErr != err)
+       if (errSecSuccess != err)
        {
                CFStringRef result = SecCopyErrorMessageString(err, NULL);
                CFErrorRef retValue = CreateSecTransformErrorRef(err, "CDSA error (%@).", result);
        {
                CFStringRef result = SecCopyErrorMessageString(err, NULL);
                CFErrorRef retValue = CreateSecTransformErrorRef(err, "CDSA error (%@).", result);
@@ -242,7 +242,7 @@ CFErrorRef EncryptDecryptBase::SerializedTransformStartingExecution()
                                                                   kSecCredentialTypeDefault,
                                                                   (const CSSM_ACCESS_CREDENTIALS **)&credPtr);
                
                                                                   kSecCredentialTypeDefault,
                                                                   (const CSSM_ACCESS_CREDENTIALS **)&credPtr);
                
-               if (noErr != err)
+               if (errSecSuccess != err)
                {
                        memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
                        credPtr = &creds;
                {
                        memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
                        credPtr = &creds;
@@ -321,6 +321,8 @@ void EncryptDecryptBase::SendCSSMError(CSSM_RETURN retCode)
        CFRelease(errorRef);
 }
 
        CFRelease(errorRef);
 }
 
+#warning "This declaration should be in some header"
+void xor_bytes(UInt8 *dst, const UInt8 *src1, const UInt8 *src2, CFIndex length);
 void xor_bytes(UInt8 *dst, const UInt8 *src1, const UInt8 *src2, CFIndex length)
 {
        // NOTE: this can be made faster, but see if we already have a faster version somewhere first.
 void xor_bytes(UInt8 *dst, const UInt8 *src1, const UInt8 *src2, CFIndex length)
 {
        // NOTE: this can be made faster, but see if we already have a faster version somewhere first.
@@ -509,10 +511,10 @@ CFDataRef EncryptDecryptBase::apply_oaep_padding(CFDataRef dataValue)
                CFNumberGetValue(desired_message_length_cf, kCFNumberIntType, &desired_message_length);
        } else {
                // take RSA (or whatever crypto) block size onto account too
                CFNumberGetValue(desired_message_length_cf, kCFNumberIntType, &desired_message_length);
        } else {
                // take RSA (or whatever crypto) block size onto account too
-               RSA_size.SizeInputBlock = CFDataGetLength(dataValue) + 2*hLen +1;
+               RSA_size.SizeInputBlock = (uint32)(CFDataGetLength(dataValue) + 2*hLen +1);
                RSA_size.SizeOutputBlock = 0;
                OSStatus status = CSSM_QuerySize(m_handle, CSSM_TRUE, 1, &RSA_size);
                RSA_size.SizeOutputBlock = 0;
                OSStatus status = CSSM_QuerySize(m_handle, CSSM_TRUE, 1, &RSA_size);
-               if (status != noErr) {
+               if (status != errSecSuccess) {
                        CFStringRef errorString = SecCopyErrorMessageString(status, NULL);
                        error = CreateSecTransformErrorRef(kSecTransformErrorInvalidOperation, "CDSA error (%@).", errorString);
                        CFRelease(errorString);
                        CFStringRef errorString = SecCopyErrorMessageString(status, NULL);
                        error = CreateSecTransformErrorRef(kSecTransformErrorInvalidOperation, "CDSA error (%@).", errorString);
                        CFRelease(errorString);
@@ -559,7 +561,7 @@ CFDataRef EncryptDecryptBase::apply_oaep_padding(CFDataRef dataValue)
                RSA_size.SizeInputBlock = CFDataGetLength(dataValue) + 2*hLen +1;
                RSA_size.SizeOutputBlock = 0;
                OSStatus status = CSSM_QuerySize(m_handle, CSSM_TRUE, 1, &RSA_size);
                RSA_size.SizeInputBlock = CFDataGetLength(dataValue) + 2*hLen +1;
                RSA_size.SizeOutputBlock = 0;
                OSStatus status = CSSM_QuerySize(m_handle, CSSM_TRUE, 1, &RSA_size);
-               if (status != noErr) {
+               if (status != errSecSuccess) {
                        CFStringRef errorString = SecCopyErrorMessageString(status, NULL);
                        error = CreateSecTransformErrorRef(kSecTransformErrorInvalidOperation, "CDSA error (%@).", errorString);
                        CFRelease(errorString);
                        CFStringRef errorString = SecCopyErrorMessageString(status, NULL);
                        error = CreateSecTransformErrorRef(kSecTransformErrorInvalidOperation, "CDSA error (%@).", errorString);
                        CFRelease(errorString);
index 263ef9fb73d8808e3f3ef16c47d825fd54eab1d7..7becb85cceaf77b9f359f261f2a3af6fb2a16df0 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "SecCustomTransform.h"
  */
 
 #include "SecCustomTransform.h"
+#include "SecTransformValidator.h"
 
 #include "TransformFactory.h"
 #include <CoreFoundation/CoreFoundation.h>
 
 #include "TransformFactory.h"
 #include <CoreFoundation/CoreFoundation.h>
@@ -17,7 +18,6 @@
 #include "misc.h"
 
 static const CFStringRef kSecCustom = CFSTR("CustomTransform");
 #include "misc.h"
 
 static const CFStringRef kSecCustom = CFSTR("CustomTransform");
-static const char *kSecCustom_cstr = "CustomTransform";
 const CFStringRef kSecTransformPreviousErrorKey = CFSTR("PreviousError");
 const CFStringRef kSecTransformAbortOriginatorKey = CFSTR("Originating Transform");
 const CFStringRef kSecTransformActionCanExecute = CFSTR("CanExecute");
 const CFStringRef kSecTransformPreviousErrorKey = CFSTR("PreviousError");
 const CFStringRef kSecTransformAbortOriginatorKey = CFSTR("Originating Transform");
 const CFStringRef kSecTransformActionCanExecute = CFSTR("CanExecute");
@@ -285,6 +285,7 @@ protected:
        SecTransformCreateFP  createFuncPtr;
 public:
        CustomTransformFactory(CFStringRef name, SecTransformCreateFP createFP, CFErrorRef *error);
        SecTransformCreateFP  createFuncPtr;
 public:
        CustomTransformFactory(CFStringRef name, SecTransformCreateFP createFP, CFErrorRef *error);
+    virtual ~CustomTransformFactory() {};
        virtual CFTypeRef Make();
 };
 
        virtual CFTypeRef Make();
 };
 
@@ -562,14 +563,6 @@ CFTypeRef CustomTransformFactory::Make()
 
 #pragma mark MISC
 
 
 #pragma mark MISC
 
-const void *Block_copy_a(CFAllocatorRef allocator, const void *block) {
-       return Block_copy(block);
-}
-
-void Block_release_a(CFAllocatorRef allocator, const void *block) {
-       Block_release(block);
-}
-
 extern "C" {
        SecTransformAttributeActionBlock SecTransformCreateValidatorForCFtype(CFTypeID expected_type, Boolean null_allowed) {
                SecTransformAttributeActionBlock validate = NULL;
 extern "C" {
        SecTransformAttributeActionBlock SecTransformCreateValidatorForCFtype(CFTypeID expected_type, Boolean null_allowed) {
                SecTransformAttributeActionBlock validate = NULL;
index 423f2c8f3387e919746a887e63b9333af140da22..e44e798a0bf6d36af9e56c60987c06006adb3bea 100644 (file)
@@ -19,8 +19,9 @@ CFStringRef kSecKeyAttributeName = CFSTR("KEY"), kSecSignatureAttributeName = CF
 // Internally we force kSecInputIsAttributeName to one of these 3 things, you can use == rather then CFStringCompare once that happens
 CFStringRef kSecInputIsPlainText = CFSTR("PlainText"), kSecInputIsDigest = CFSTR("Digest"), kSecInputIsRaw = CFSTR("Raw");
 
 // Internally we force kSecInputIsAttributeName to one of these 3 things, you can use == rather then CFStringCompare once that happens
 CFStringRef kSecInputIsPlainText = CFSTR("PlainText"), kSecInputIsDigest = CFSTR("Digest"), kSecInputIsRaw = CFSTR("Raw");
 
+static
 CFErrorRef do_sec_fail(OSStatus code, const char *func, const char *file, int line) {
 CFErrorRef do_sec_fail(OSStatus code, const char *func, const char *file, int line) {
-       CFStringRef msg = CFStringCreateWithFormat(NULL, NULL, CFSTR("Internal error #%x at %s %s:%d"), code, func, file, line);
+       CFStringRef msg = CFStringCreateWithFormat(NULL, NULL, CFSTR("Internal error #%x at %s %s:%d"), (unsigned)code, func, file, line);
        CFErrorRef err = fancy_error(CFSTR("Internal CSSM error"), code, msg);
        CFRelease(msg);
        
        CFErrorRef err = fancy_error(CFSTR("Internal CSSM error"), code, msg);
        CFRelease(msg);
        
@@ -32,6 +33,7 @@ CFErrorRef do_sec_fail(OSStatus code, const char *func, const char *file, int li
 }
 #define GET_SEC_FAIL(err) do_sec_fail(err, __func__, __FILE__, __LINE__)
 
 }
 #define GET_SEC_FAIL(err) do_sec_fail(err, __func__, __FILE__, __LINE__)
 
+static
 CFErrorRef accumulate_data(CFMutableArrayRef *a, CFDataRef d) {
        if (!*a) {
                *a = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
 CFErrorRef accumulate_data(CFMutableArrayRef *a, CFDataRef d) {
        if (!*a) {
                *a = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
@@ -53,6 +55,7 @@ CFErrorRef accumulate_data(CFMutableArrayRef *a, CFDataRef d) {
        return NULL;
 }
 
        return NULL;
 }
 
+static
 CFErrorRef fetch_and_clear_accumulated_data(CFMutableArrayRef *a, CFDataRef *data_out) {
        if (!*a) {
                *data_out = CFDataCreate(NULL, NULL, 0);
 CFErrorRef fetch_and_clear_accumulated_data(CFMutableArrayRef *a, CFDataRef *data_out) {
        if (!*a) {
                *data_out = CFDataCreate(NULL, NULL, 0);
@@ -109,6 +112,7 @@ struct digest_mapping {
        CSSM_ALGORITHMS plain_text_algo, digest_algo;
 };
 
        CSSM_ALGORITHMS plain_text_algo, digest_algo;
 };
 
+static
 Boolean digest_mapping_equal(struct digest_mapping *a, struct digest_mapping *b) {
        if (a == b) {
                return TRUE;
 Boolean digest_mapping_equal(struct digest_mapping *a, struct digest_mapping *b) {
        if (a == b) {
                return TRUE;
@@ -121,10 +125,12 @@ Boolean digest_mapping_equal(struct digest_mapping *a, struct digest_mapping *b)
        return FALSE;
 }
 
        return FALSE;
 }
 
+static
 CFHashCode digest_mapping_hash(struct digest_mapping *dm) {
        return CFHash(dm->digest_name) + dm->kclass + dm->digest_length;
 }
 
 CFHashCode digest_mapping_hash(struct digest_mapping *dm) {
        return CFHash(dm->digest_name) + dm->kclass + dm->digest_length;
 }
 
+static
 CSSM_ALGORITHMS alg_for_signature_context(CFStringRef input_is, const struct digest_mapping *dm) {
        if (!CFStringCompare(kSecInputIsPlainText, input_is, 0)) {
                return dm->plain_text_algo;
 CSSM_ALGORITHMS alg_for_signature_context(CFStringRef input_is, const struct digest_mapping *dm) {
        if (!CFStringCompare(kSecInputIsPlainText, input_is, 0)) {
                return dm->plain_text_algo;
@@ -135,6 +141,7 @@ CSSM_ALGORITHMS alg_for_signature_context(CFStringRef input_is, const struct dig
        }
 }
 
        }
 }
 
+static
 CFErrorRef pick_sign_alg(CFStringRef digest, int digest_length, const CSSM_KEY *ckey, struct digest_mapping **picked) {
        static dispatch_once_t once = 0;
        static CFMutableSetRef algos = NULL;
 CFErrorRef pick_sign_alg(CFStringRef digest, int digest_length, const CSSM_KEY *ckey, struct digest_mapping **picked) {
        static dispatch_once_t once = 0;
        static CFMutableSetRef algos = NULL;
@@ -554,8 +561,9 @@ static SecTransformInstanceBlock VerifyTransform(CFStringRef name,
                                        CSSM_DATA c_d;
                                        c_d.Data = (void*)CFDataGetBytePtr(alldata);
                                        c_d.Length = CFDataGetLength(alldata);
                                        CSSM_DATA c_d;
                                        c_d.Data = (void*)CFDataGetBytePtr(alldata);
                                        c_d.Length = CFDataGetLength(alldata);
-                                       
                                        rc = CSSM_VerifyData(cch, &c_d, 1, (input_is == kSecInputIsDigest) ? verify_alg->digest_algo : CSSM_ALGID_NONE, &sig);
                                        rc = CSSM_VerifyData(cch, &c_d, 1, (input_is == kSecInputIsDigest) ? verify_alg->digest_algo : CSSM_ALGID_NONE, &sig);
+                    CFRelease(alldata);
+
                                }
                                CSSM_DeleteContext(cch);
                                if (rc == 0 || rc == CSSMERR_CSP_VERIFY_FAILED) {
                                }
                                CSSM_DeleteContext(cch);
                                if (rc == 0 || rc == CSSMERR_CSP_VERIFY_FAILED) {
index 902bfb1dc4f1fb81456e80e30963cb5df3477034..5d998cf3d281dc159e549730bcabfd486d9d82a9 100644 (file)
@@ -41,15 +41,42 @@ static SecTransformInstanceBlock StreamTransformImplementation(CFStringRef name,
                        }
                        
                        CFArrayRef array = (CFArrayRef) value;
                        }
                        
                        CFArrayRef array = (CFArrayRef) value;
-                       CFReadStreamRef input = (CFReadStreamRef) CFArrayGetValueAtIndex(array, 0);
-                       
-                       // open the stream
-                       if (!CFReadStreamOpen(input))
+                       CFTypeRef item = (CFTypeRef) CFArrayGetValueAtIndex(array, 0);
+
+                       // Ensure that indeed we do have a CFReadStreamRef
+                       if (NULL == item || CFReadStreamGetTypeID() != CFGetTypeID(item))
                        {
                        {
-                               // We didn't open properly.  Error out
-                               return (CFTypeRef) CreateSecTransformErrorRef(kSecTransformErrorInvalidInput, "An error occurred while opening the stream.");
+                               return (CFTypeRef) CreateSecTransformErrorRef(kSecTransformErrorInvalidInput, "The input attribute item was nil or not a read stream");
                        }
                        
                        }
                        
+                       // This now is a safe cast
+                       CFReadStreamRef input = (CFReadStreamRef)item;
+
+                       // Get the state of the stream
+                       CFStreamStatus streamStatus = CFReadStreamGetStatus(input);
+                       switch (streamStatus)
+                       {
+                               case kCFStreamStatusNotOpen:
+                               {
+                                       if (!CFReadStreamOpen(input))
+                                       {
+                                               // We didn't open properly.  Error out
+                                               return (CFTypeRef) CreateSecTransformErrorRef(kSecTransformErrorInvalidInput, "An error occurred while opening the stream.");
+                                       }
+                               }
+                               break;
+
+                               case kCFStreamStatusError:
+                               {
+                                       return (CFTypeRef) CreateSecTransformErrorRef(kSecTransformErrorInvalidInput, "The read stream is in an error state");
+                               }
+                               break;
+
+                               default:
+                                       // The assumption is that the stream is ready to go as is.
+                               break;
+                       }               
+                       
                        // allocate the read buffer on the heap
                        u_int8_t* buffer = (u_int8_t*) malloc(blockSize);
                        
                        // allocate the read buffer on the heap
                        u_int8_t* buffer = (u_int8_t*) malloc(blockSize);
                        
index 4d7910f7ec8960afa2e5a11bc3f81a80abca7d8d..5ec84b8e6e66b3921780092384a1178175600d95 100644 (file)
@@ -12,6 +12,7 @@
 #include "SecTransformInternal.h"
 #include "GroupTransform.h"
 #include "GroupTransform.h"
 #include "SecTransformInternal.h"
 #include "GroupTransform.h"
 #include "GroupTransform.h"
+#include <pthread.h>
 
 static const int kMaxPendingTransactions = 20;
 
 
 static const int kMaxPendingTransactions = 20;
 
@@ -1423,7 +1424,7 @@ CFErrorRef Transform::ExecuteOperation(CFStringRef &outputAttached, SecMonitorRe
        for (i = 0; i < numAttributes; ++i)
        {
                transform_attribute *ta = attributes[i];
        for (i = 0; i < numAttributes; ++i)
        {
                transform_attribute *ta = attributes[i];
-               int arraySize = ta->connections ? CFArrayGetCount(ta->connections) : 0;
+               CFIndex arraySize = ta->connections ? CFArrayGetCount(ta->connections) : 0;
                if (arraySize == 0 && ta->requires_outbound_connection)
                {
                        if (CFStringCompare(ta->name, kSecTransformOutputAttributeName, 0) == kCFCompareEqualTo) {
                if (arraySize == 0 && ta->requires_outbound_connection)
                {
                        if (CFStringCompare(ta->name, kSecTransformOutputAttributeName, 0) == kCFCompareEqualTo) {
@@ -1547,15 +1548,6 @@ static Boolean CFTypeOrNULLEqual(const void *value1, const void *value2) {
        }
 }
 
        }
 }
 
-CFHashCode CFTypeOrNULLHash(const void *value) {
-       if (value != NULL) {
-               return CFHash(value);
-       } else {
-               return 42;
-       }
-}
-
-
 // Returns a dictionary of all the meta attributes that will need to be reset on a RestoreState
 CFDictionaryRef Transform::GetAHDictForSaveState(SecTransformStringOrAttributeRef key)
 {
 // Returns a dictionary of all the meta attributes that will need to be reset on a RestoreState
 CFDictionaryRef Transform::GetAHDictForSaveState(SecTransformStringOrAttributeRef key)
 {
@@ -1810,7 +1802,7 @@ CFErrorRef Transform::ProcessExternalize(CFMutableArrayRef transforms, CFMutable
        // walk the forward links
        for (i = 0; i < numAttributes; ++i)
        {
        // walk the forward links
        for (i = 0; i < numAttributes; ++i)
        {
-               int arraySize = attributes[i]->connections ? CFArrayGetCount(attributes[i]->connections) : 0;
+               CFIndex arraySize = attributes[i]->connections ? CFArrayGetCount(attributes[i]->connections) : 0;
                if (arraySize != 0)
                {
                        CFIndex j;
                if (arraySize != 0)
                {
                        CFIndex j;
index a82293a7656dac5b48c892fc066140f257cde27c..91a9f730d25a54324440d8323575f851b91b3cf6 100644 (file)
@@ -67,6 +67,7 @@ CFErrorRef fancy_error(CFStringRef domain, CFIndex code, CFStringRef description
        return err;
 }
 
        return err;
 }
 
+static
 void add_t2ca(CFMutableDictionaryRef t2ca, CFStringRef t, CFStringRef a) {
        CFMutableSetRef ca = (CFMutableSetRef)CFDictionaryGetValue(t2ca, t);
        if (!ca) {
 void add_t2ca(CFMutableDictionaryRef t2ca, CFStringRef t, CFStringRef a) {
        CFMutableSetRef ca = (CFMutableSetRef)CFDictionaryGetValue(t2ca, t);
        if (!ca) {
index 9b597cac0050185437eb9d1781efe9cbedfd226b..00e4f101ac892719793c38bc6ee12440f4c941df 100644 (file)
                18BBC73C1471F6DF00F2B224 /* release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = release.xcconfig; sourceTree = "<group>"; };
                18BBC73D1471F6DF00F2B224 /* security.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = security.xcconfig; sourceTree = "<group>"; };
                18C5A963148443F00010EF34 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; };
                18BBC73C1471F6DF00F2B224 /* release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = release.xcconfig; sourceTree = "<group>"; };
                18BBC73D1471F6DF00F2B224 /* security.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = security.xcconfig; sourceTree = "<group>"; };
                18C5A963148443F00010EF34 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; };
-               18C5A9651484440D0010EF34 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = ../../../../../../../System/Library/Frameworks/Foundation.framework; sourceTree = "<group>"; };
+               18C5A9651484440D0010EF34 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
                4C010B87121AE8DF0094CB72 /* input-speed-test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "input-speed-test"; sourceTree = BUILT_PRODUCTS_DIR; };
                4C010B99121AE9960094CB72 /* speed-test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "speed-test.h"; path = "misc/speed-test.h"; sourceTree = "<group>"; };
                4C010B9A121AE9960094CB72 /* speed-test.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "speed-test.mm"; path = "misc/speed-test.mm"; sourceTree = "<group>"; };
                4C010B87121AE8DF0094CB72 /* input-speed-test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "input-speed-test"; sourceTree = BUILT_PRODUCTS_DIR; };
                4C010B99121AE9960094CB72 /* speed-test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "speed-test.h"; path = "misc/speed-test.h"; sourceTree = "<group>"; };
                4C010B9A121AE9960094CB72 /* speed-test.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "speed-test.mm"; path = "misc/speed-test.mm"; sourceTree = "<group>"; };
-               4C010BBE121AED340094CB72 /* libc++.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libc++.dylib"; path = "/usr/lib/libc++.dylib"; sourceTree = "<absolute>"; };
+               4C010BBE121AED340094CB72 /* libc++.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libc++.dylib"; path = "usr/lib/libc++.dylib"; sourceTree = SDKROOT; };
                4C010C4B121AFCA70094CB72 /* SecExternalSourceTransform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecExternalSourceTransform.h; sourceTree = "<group>"; };
                4C010C4C121AFCA70094CB72 /* SecExternalSourceTransform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SecExternalSourceTransform.cpp; sourceTree = "<group>"; };
                4C01134F1468693100E4F866 /* SecMaskGenerationFunctionTransform.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecMaskGenerationFunctionTransform.c; sourceTree = "<group>"; };
                4C0113501468693100E4F866 /* SecMaskGenerationFunctionTransform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecMaskGenerationFunctionTransform.h; sourceTree = "<group>"; };
                4C01135A14686F2600E4F866 /* NSData+HexString.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+HexString.m"; sourceTree = "<group>"; };
                4C01135B14686F2600E4F866 /* NSData+HexString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+HexString.h"; sourceTree = "<group>"; };
                4C010C4B121AFCA70094CB72 /* SecExternalSourceTransform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecExternalSourceTransform.h; sourceTree = "<group>"; };
                4C010C4C121AFCA70094CB72 /* SecExternalSourceTransform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SecExternalSourceTransform.cpp; sourceTree = "<group>"; };
                4C01134F1468693100E4F866 /* SecMaskGenerationFunctionTransform.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecMaskGenerationFunctionTransform.c; sourceTree = "<group>"; };
                4C0113501468693100E4F866 /* SecMaskGenerationFunctionTransform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecMaskGenerationFunctionTransform.h; sourceTree = "<group>"; };
                4C01135A14686F2600E4F866 /* NSData+HexString.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+HexString.m"; sourceTree = "<group>"; };
                4C01135B14686F2600E4F866 /* NSData+HexString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+HexString.h"; sourceTree = "<group>"; };
-               4C27A37414F2D66C007FCA66 /* libcorecrypto.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libcorecrypto.dylib; path = ../../../../../../../../usr/lib/system/libcorecrypto.dylib; sourceTree = "<group>"; };
+               4C27A37414F2D66C007FCA66 /* libcorecrypto.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libcorecrypto.dylib; path = usr/lib/system/libcorecrypto.dylib; sourceTree = SDKROOT; };
                4C27A37714F2DCB4007FCA66 /* CEncryptDecrypt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CEncryptDecrypt.c; sourceTree = "<group>"; };
                4C6E5964116D4E3E00A70E8F /* misc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = misc.c; sourceTree = "<group>"; };
                4C6E5965116D4E3E00A70E8F /* misc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = misc.h; sourceTree = "<group>"; };
                4C27A37714F2DCB4007FCA66 /* CEncryptDecrypt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CEncryptDecrypt.c; sourceTree = "<group>"; };
                4C6E5964116D4E3E00A70E8F /* misc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = misc.c; sourceTree = "<group>"; };
                4C6E5965116D4E3E00A70E8F /* misc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = misc.h; sourceTree = "<group>"; };
                4CB89E61124D5667004DEC20 /* SecTransformValidator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecTransformValidator.h; sourceTree = "<group>"; };
                4CBCBEB61130A2D700CC18E9 /* 100-sha2 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "100-sha2"; sourceTree = BUILT_PRODUCTS_DIR; };
                4CBCBEB81130A2D800CC18E9 /* Info-security_transform.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-security_transform.plist"; sourceTree = "<group>"; };
                4CB89E61124D5667004DEC20 /* SecTransformValidator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecTransformValidator.h; sourceTree = "<group>"; };
                4CBCBEB61130A2D700CC18E9 /* 100-sha2 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "100-sha2"; sourceTree = BUILT_PRODUCTS_DIR; };
                4CBCBEB81130A2D800CC18E9 /* Info-security_transform.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-security_transform.plist"; sourceTree = "<group>"; };
-               4CD6A668113F41990094F287 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = /usr/lib/libz.dylib; sourceTree = "<absolute>"; };
+               4CD6A668113F41990094F287 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
                4CD87F3D1130A34700A98C5E /* 100-sha2.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "100-sha2.m"; sourceTree = "<group>"; };
                4CDF6DC9113C4E9E00C64234 /* EncodeDecodeTransforms.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = EncodeDecodeTransforms.c; sourceTree = "<group>"; };
                4CDF6DCA113C4E9E00C64234 /* SecDecodeTransform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecDecodeTransform.h; sourceTree = "<group>"; };
                4CDF6DCB113C4E9E00C64234 /* SecEncodeTransform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecEncodeTransform.h; sourceTree = "<group>"; };
                4CD87F3D1130A34700A98C5E /* 100-sha2.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "100-sha2.m"; sourceTree = "<group>"; };
                4CDF6DC9113C4E9E00C64234 /* EncodeDecodeTransforms.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = EncodeDecodeTransforms.c; sourceTree = "<group>"; };
                4CDF6DCA113C4E9E00C64234 /* SecDecodeTransform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecDecodeTransform.h; sourceTree = "<group>"; };
                4CDF6DCB113C4E9E00C64234 /* SecEncodeTransform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecEncodeTransform.h; sourceTree = "<group>"; };
-               5D16D6FB114EA1000096BD75 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = /System/Library/Frameworks/Security.framework; sourceTree = "<absolute>"; };
+               5D16D6FB114EA1000096BD75 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
                5DCAD5B511F0E099003F2E7A /* SecCollectTransform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SecCollectTransform.cpp; sourceTree = "<group>"; };
                5DCAD5B611F0E099003F2E7A /* SecCollectTransform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCollectTransform.h; sourceTree = "<group>"; };
                5DD2E91C114E9044007429E7 /* EncryptTransform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = EncryptTransform.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
                5DCAD5B511F0E099003F2E7A /* SecCollectTransform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SecCollectTransform.cpp; sourceTree = "<group>"; };
                5DCAD5B611F0E099003F2E7A /* SecCollectTransform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCollectTransform.h; sourceTree = "<group>"; };
                5DD2E91C114E9044007429E7 /* EncryptTransform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = EncryptTransform.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
                4CA1FEA7052A3C3800F22E42 = {
                        isa = PBXGroup;
                        children = (
                4CA1FEA7052A3C3800F22E42 = {
                        isa = PBXGroup;
                        children = (
-                               4C27A37414F2D66C007FCA66 /* libcorecrypto.dylib */,
                                18C5A9651484440D0010EF34 /* Foundation.framework */,
                                18C5A963148443F00010EF34 /* SenTestingKit.framework */,
                                18BBC7381471F6DF00F2B224 /* config */,
                                18C5A9651484440D0010EF34 /* Foundation.framework */,
                                18C5A963148443F00010EF34 /* SenTestingKit.framework */,
                                18BBC7381471F6DF00F2B224 /* config */,
+                               4C27A37414F2D66C007FCA66 /* libcorecrypto.dylib */,
                                4C010BBE121AED340094CB72 /* libc++.dylib */,
                                4CD6A668113F41990094F287 /* libz.dylib */,
                                4C73825F112DF66700EA003B /* unit-tests */,
                                4C010BBE121AED340094CB72 /* libc++.dylib */,
                                4CD6A668113F41990094F287 /* libz.dylib */,
                                4C73825F112DF66700EA003B /* unit-tests */,
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
                4CA1FEAB052A3C3800F22E42 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0440;
+                               LastUpgradeCheck = 0500;
                        };
                        buildConfigurationList = C27AD4040987FCDF001272E0 /* Build configuration list for PBXProject "libsecurity_transform" */;
                        compatibilityVersion = "Xcode 3.2";
                        };
                        buildConfigurationList = C27AD4040987FCDF001272E0 /* Build configuration list for PBXProject "libsecurity_transform" */;
                        compatibilityVersion = "Xcode 3.2";
                };
                4C738259112DF65400EA003B /* Debug */ = {
                        isa = XCBuildConfiguration;
                };
                4C738259112DF65400EA003B /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 18BBC73A1471F6DF00F2B224 /* debug.xcconfig */;
+                       baseConfigurationReference = 18BBC73B1471F6DF00F2B224 /* lib.xcconfig */;
                        buildSettings = {
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                FRAMEWORK_SEARCH_PATHS = (
                                        "$(inherited)",
                                FRAMEWORK_SEARCH_PATHS = (
                                        "$(inherited)",
-                                       "\"$(DEVELOPER_FRAMEWORKS_DIR)\"",
+                                       "$(DEVELOPER_FRAMEWORKS_DIR)",
                                );
                                INFOPLIST_FILE = "unit-tests-Info.plist";
                                LIBRARY_SEARCH_PATHS = (
                                );
                                INFOPLIST_FILE = "unit-tests-Info.plist";
                                LIBRARY_SEARCH_PATHS = (
                };
                4C73825B112DF65400EA003B /* Release */ = {
                        isa = XCBuildConfiguration;
                };
                4C73825B112DF65400EA003B /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 18BBC73C1471F6DF00F2B224 /* release.xcconfig */;
+                       baseConfigurationReference = 18BBC73B1471F6DF00F2B224 /* lib.xcconfig */;
                        buildSettings = {
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                FRAMEWORK_SEARCH_PATHS = (
                                        "$(inherited)",
                                FRAMEWORK_SEARCH_PATHS = (
                                        "$(inherited)",
-                                       "\"$(DEVELOPER_FRAMEWORKS_DIR)\"",
+                                       "$(DEVELOPER_FRAMEWORKS_DIR)",
                                );
                                INFOPLIST_FILE = "unit-tests-Info.plist";
                                LIBRARY_SEARCH_PATHS = (
                                );
                                INFOPLIST_FILE = "unit-tests-Info.plist";
                                LIBRARY_SEARCH_PATHS = (
                };
                C27AD4010987FCDF001272E0 /* Debug */ = {
                        isa = XCBuildConfiguration;
                };
                C27AD4010987FCDF001272E0 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 18BBC73A1471F6DF00F2B224 /* debug.xcconfig */;
+                       baseConfigurationReference = 18BBC73B1471F6DF00F2B224 /* lib.xcconfig */;
                        buildSettings = {
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                LIBRARY_SEARCH_PATHS = (
                                        "$(inherited)",
                                        /usr/lib/system,
                                LIBRARY_SEARCH_PATHS = (
                                        "$(inherited)",
                                        /usr/lib/system,
                                        "$(inherited)",
                                        "-DCOM_APPLE_SECURITY_SANE_INCLUDES",
                                );
                                        "$(inherited)",
                                        "-DCOM_APPLE_SECURITY_SANE_INCLUDES",
                                );
+                               WARNING_CFLAGS = (
+                                       "$(inherited)",
+                                       "-Wno-error=overloaded-virtual",
+                               );
                        };
                        name = Debug;
                };
                C27AD4030987FCDF001272E0 /* Release */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Debug;
                };
                C27AD4030987FCDF001272E0 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 18BBC73C1471F6DF00F2B224 /* release.xcconfig */;
+                       baseConfigurationReference = 18BBC73B1471F6DF00F2B224 /* lib.xcconfig */;
                        buildSettings = {
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                LIBRARY_SEARCH_PATHS = (
                                        "$(inherited)",
                                        /usr/lib/system,
                                LIBRARY_SEARCH_PATHS = (
                                        "$(inherited)",
                                        /usr/lib/system,
                                        "$(inherited)",
                                        "-DCOM_APPLE_SECURITY_SANE_INCLUDES",
                                );
                                        "$(inherited)",
                                        "-DCOM_APPLE_SECURITY_SANE_INCLUDES",
                                );
+                               WARNING_CFLAGS = (
+                                       "$(inherited)",
+                                       "-Wno-error=overloaded-virtual",
+                               );
                        };
                        name = Release;
                };
                C27AD4050987FCDF001272E0 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Release;
                };
                C27AD4050987FCDF001272E0 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 18BBC73B1471F6DF00F2B224 /* lib.xcconfig */;
+                       baseConfigurationReference = 18BBC73A1471F6DF00F2B224 /* debug.xcconfig */;
                        buildSettings = {
                        };
                        name = Debug;
                };
                C27AD4070987FCDF001272E0 /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                        };
                        name = Debug;
                };
                C27AD4070987FCDF001272E0 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 18BBC73B1471F6DF00F2B224 /* lib.xcconfig */;
+                       baseConfigurationReference = 18BBC73C1471F6DF00F2B224 /* release.xcconfig */;
                        buildSettings = {
                        };
                        name = Release;
                        buildSettings = {
                        };
                        name = Release;
index 22028c7e25eac7ea9a8cd821a198fbd3f184e9b9..e2c8d89ca17a44de58a64d8cf0959e26d6668680 100644 (file)
@@ -107,7 +107,7 @@ public:
        
        // inquiries for the Adornable itself
        bool empty() const                              { return !mAdornments || mAdornments->empty(); }
        
        // inquiries for the Adornable itself
        bool empty() const                              { return !mAdornments || mAdornments->empty(); }
-       unsigned int size() const               { return mAdornments ? mAdornments->size() : 0; }
+       unsigned int size() const               { return mAdornments ? (unsigned int)mAdornments->size() : 0; }
        void clearAdornments();
        
 public:
        void clearAdornments();
        
 public:
index 100354abc4c77395fd2d5377ef05843d60cd37c6..2f227768936952ecc3ddaa2b1357149816dc729e 100644 (file)
@@ -72,7 +72,7 @@ public:
        { return reinterpret_cast<T *>(realloc(addr, size)); }
 
        // All right, if you *really* have to have calloc...
        { return reinterpret_cast<T *>(realloc(addr, size)); }
 
        // All right, if you *really* have to have calloc...
-       void *calloc(size_t size, unsigned int count) throw(std::bad_alloc)
+       void *calloc(size_t size, size_t count) throw(std::bad_alloc)
        {
                void *addr = malloc(size * count);
                memset(addr, 0, size * count);
        {
                void *addr = malloc(size * count);
                memset(addr, 0, size * count);
index b0dab75f80963ade253612f35e3639ec0a686761..04be864e83793ecea3273a4b3d4eeda3202dab8a 100644 (file)
@@ -114,15 +114,19 @@ BlobCore *BlobCore::readBlob(std::FILE *file, uint32_t magic, size_t minSize, si
 BlobWrapper *BlobWrapper::alloc(size_t length, Magic magic /* = _magic */)
 {
        size_t wrapLength = length + sizeof(BlobCore);
 BlobWrapper *BlobWrapper::alloc(size_t length, Magic magic /* = _magic */)
 {
        size_t wrapLength = length + sizeof(BlobCore);
+       if (wrapLength < length)        // overflow
+               return NULL;
        BlobWrapper *w = (BlobWrapper *)malloc(wrapLength);
        BlobWrapper *w = (BlobWrapper *)malloc(wrapLength);
-       w->BlobCore::initialize(magic, wrapLength);
+       if (w)
+               w->BlobCore::initialize(magic, wrapLength);
        return w;
 }
 
 BlobWrapper *BlobWrapper::alloc(const void *data, size_t length, Magic magic /* = _magic */)
 {
        BlobWrapper *w = alloc(length, magic);
        return w;
 }
 
 BlobWrapper *BlobWrapper::alloc(const void *data, size_t length, Magic magic /* = _magic */)
 {
        BlobWrapper *w = alloc(length, magic);
-       memcpy(w->data(), data, w->length());
+       if (w)
+               memcpy(w->data(), data, w->length());
        return w;
 }
 
        return w;
 }
 
index ad3adf8de394c750fc0421ce519be871c76aec8f..a3bfb2036979030d5be9a9f283a8712b4b74f53f 100644 (file)
@@ -62,7 +62,7 @@ public:
        size_t length() const { return mLength; }
        
        void initialize(Magic magic, size_t length = 0)
        size_t length() const { return mLength; }
        
        void initialize(Magic magic, size_t length = 0)
-       { mMagic = magic; mLength = length; }
+       { mMagic = magic; mLength = (uint32_t)length; }
        
        bool validateBlob(Magic magic, size_t minSize = 0, size_t maxSize = 0) const;
 
        
        bool validateBlob(Magic magic, size_t minSize = 0, size_t maxSize = 0) const;
 
@@ -87,7 +87,7 @@ public:
 
        void *data()                                            { return this; }
        const void *data() const                        { return this; }
 
        void *data()                                            { return this; }
        const void *data() const                        { return this; }
-       void length(size_t size)                        { mLength = size; }
+       void length(size_t size)                        { mLength = (uint32_t)size; }
 
        BlobCore *clone() const
        {
 
        BlobCore *clone() const
        {
@@ -149,7 +149,7 @@ public:
        { return BlobCore::validateBlob(_magic, sizeof(BlobType)); }
        
        bool validateBlob(size_t extLength) const
        { return BlobCore::validateBlob(_magic, sizeof(BlobType)); }
        
        bool validateBlob(size_t extLength) const
-       { return validateBlob() && mLength == extLength; }
+       { return extLength >= sizeof(BlobType) && validateBlob() && mLength == extLength; }
        
        static BlobType *specific(BlobCore *blob, bool unalloc = false)
        {
        
        static BlobType *specific(BlobCore *blob, bool unalloc = false)
        {
index cfd80514ef57cf64e922439ae72d6d892a893937..d635ca44d7b203de1bef7fe6d93e2c7541099dea 100644 (file)
@@ -103,9 +103,17 @@ CFClass::cleanupObject(intptr_t op, CFTypeRef cf, bool &zap)
     }
     else if (currentCount == 0)
     {
     }
     else if (currentCount == 0)
     {
-        finalizeType(cf);
-        zap = true; // the the caller to release the mutex and zap the object
-        return 0;
+        // we may not be able to delete if the caller has active children
+        if (obj->mayDelete())
+        {
+            finalizeType(cf);
+            zap = true; // ask the caller to release the mutex and zap the object
+            return 0;
+        }
+        else
+        {
+            return currentCount;
+        }
     }
     else 
     {
     }
     else 
     {
index b4bd252dd238d34f6ab00bb30a5dd33b36a8def9..16993be1f40f6148022436ca466ca249efdbaf3d 100644 (file)
@@ -115,8 +115,9 @@ void CFAutoPort::cfCallback(CFMachPortRef cfPort, void *msg, CFIndex size, void
 {
        ++gNumTimesCalled;
        secdebug("adhoc", "Callback was called %d times.", gNumTimesCalled);
 {
        ++gNumTimesCalled;
        secdebug("adhoc", "Callback was called %d times.", gNumTimesCalled);
-       
-       Message message(msg, size);
+
+#warning Cast to mach_msg_size_t may loose precision
+       Message message(msg, (mach_msg_size_t)size);
        try {
                reinterpret_cast<CFAutoPort *>(context)->receive(message);
        } catch (...) {
        try {
                reinterpret_cast<CFAutoPort *>(context)->receive(message);
        } catch (...) {
index f6113f294e23790747355c175d56506b098e55ac..13d5b59987ea0117816187a2a50ebc9c625ca5c2 100644 (file)
@@ -50,7 +50,7 @@ namespace Security {
 // we do not throw errors.
 //
 CFMunge::CFMunge(const char *fmt, va_list arg)
 // we do not throw errors.
 //
 CFMunge::CFMunge(const char *fmt, va_list arg)
-       : format(fmt), allocator(NULL), error(noErr)
+       : format(fmt), allocator(NULL), error(errSecSuccess)
 {
        va_copy(args, arg);
 }
 {
        va_copy(args, arg);
 }
index d7ca3a7a2d103fe64c20c2575418f690621a53e5..942f5ec81df73898db1832224ec3cda19f9d9be0 100644 (file)
@@ -48,12 +48,22 @@ CFEmptyArray::CFEmptyArray()
 //
 CFURLRef makeCFURL(const char *s, bool isDirectory, CFURLRef base)
 {
 //
 CFURLRef makeCFURL(const char *s, bool isDirectory, CFURLRef base)
 {
+    CFStringRef ss = CFStringCreateWithCStringNoCopy(NULL, s, kCFStringEncodingUTF8, kCFAllocatorNull);
+    CFURLRef returnValue = NULL;
+
        if (base)
        if (base)
-               return CFURLCreateWithFileSystemPathRelativeToBase(NULL,
-                       CFTempString(s), kCFURLPOSIXPathStyle, isDirectory, base);
+    {
+               returnValue = CFURLCreateWithFileSystemPathRelativeToBase(NULL,
+                       ss, kCFURLPOSIXPathStyle, isDirectory, base);
+    }
        else
        else
-               return CFURLCreateWithFileSystemPath(NULL,
-                       CFTempString(s), kCFURLPOSIXPathStyle, isDirectory);
+    {
+               returnValue = CFURLCreateWithFileSystemPath(NULL,
+                       ss, kCFURLPOSIXPathStyle, isDirectory);
+    }
+    
+    CFRelease(ss);
+    return returnValue;
 }
 
 CFURLRef makeCFURL(CFStringRef s, bool isDirectory, CFURLRef base)
 }
 
 CFURLRef makeCFURL(CFStringRef s, bool isDirectory, CFURLRef base)
index 72900d9b73b3ad04e2686e256597519514a9f57e..dd1a7e8bcef94dcf06fba039dbe7b1a447e980fd 100644 (file)
@@ -32,7 +32,7 @@
 #include <security_utilities/globalizer.h>
 #include <CoreFoundation/CoreFoundation.h>
 #include <algorithm>
 #include <security_utilities/globalizer.h>
 #include <CoreFoundation/CoreFoundation.h>
 #include <algorithm>
-
+#include <Security/SecBase.h>
 #undef check
 
 
 #undef check
 
 
@@ -276,7 +276,7 @@ Number cfNumber(CFNumberRef number)
 {
        typename CFNumberTraits<Number>::ValueType value;
        if (CFNumberGetValue(number, CFNumberTraits<Number>::cfnType, &value))
 {
        typename CFNumberTraits<Number>::ValueType value;
        if (CFNumberGetValue(number, CFNumberTraits<Number>::cfnType, &value))
-               return value;
+               return (Number)value;
        else
                CFError::throwMe();
 }
        else
                CFError::throwMe();
 }
@@ -479,14 +479,14 @@ public:
        CFTypeRef get(const char *key)          { return CFDictionaryGetValue(*this, CFTempString(key)); }
        
        template <class CFType>
        CFTypeRef get(const char *key)          { return CFDictionaryGetValue(*this, CFTempString(key)); }
        
        template <class CFType>
-       CFType get(CFStringRef key, OSStatus err = noErr) const
+       CFType get(CFStringRef key, OSStatus err = errSecSuccess) const
        {
                CFTypeRef elem = CFDictionaryGetValue(*this, key);
                return CFRef<CFType>::check(elem, err ? err : mDefaultError);
        }
        
        template <class CFType>
        {
                CFTypeRef elem = CFDictionaryGetValue(*this, key);
                return CFRef<CFType>::check(elem, err ? err : mDefaultError);
        }
        
        template <class CFType>
-       CFType get(const char *key, OSStatus err = noErr) const
+       CFType get(const char *key, OSStatus err = errSecSuccess) const
        { return get<CFType>(CFTempString(key), err); }
        
        void apply(CFDictionaryApplierFunction func, void *context)
        { return get<CFType>(CFTempString(key), err); }
        
        void apply(CFDictionaryApplierFunction func, void *context)
@@ -568,7 +568,7 @@ CFToVector<VectorBase, CFRefType, convert>::CFToVector(CFArrayRef arrayRef)
         mCount = 0;
         mVector = NULL;
     } else {
         mCount = 0;
         mVector = NULL;
     } else {
-        mCount = CFArrayGetCount(arrayRef);
+        mCount = (UInt32)CFArrayGetCount(arrayRef);
         mVector = new VectorBase[mCount];
         for (UInt32 n = 0; n < mCount; n++)
             mVector[n] = convert(CFRefType(CFArrayGetValueAtIndex(arrayRef, n)));
         mVector = new VectorBase[mCount];
         for (UInt32 n = 0; n < mCount; n++)
             mVector[n] = convert(CFRefType(CFArrayGetValueAtIndex(arrayRef, n)));
index e562095b2edc3d1b20d766639453419faa20c711..bf43e180832565ab2de6c2b498fff9d5438f821c 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <cxxabi.h>                    // for name demangling
 #include <mach-o/dyld.h>       // for _NSGetExecutablePath
 
 #include <cxxabi.h>                    // for name demangling
 #include <mach-o/dyld.h>       // for _NSGetExecutablePath
+#include <limits.h>
 
 // enable kernel tracing
 #define ENABLE_SECTRACE 1
 
 // enable kernel tracing
 #define ENABLE_SECTRACE 1
@@ -147,7 +148,7 @@ Target::Target()
                        p++;
                else
                        p = execPath;
                        p++;
                else
                        p = execPath;
-               unsigned plen = strlen(p);
+               size_t plen = strlen(p);
                if (plen > maxProgNameLength)           // too long
                        p += plen - maxProgNameLength; // take rear
                strcpy(progName, p);
                if (plen > maxProgNameLength)           // too long
                        p += plen - maxProgNameLength; // take rear
                strcpy(progName, p);
@@ -230,7 +231,7 @@ void Target::message(const char *scope, const char *format, va_list args)
                bufp[1] = '\0';
 
                // submit to sink (do not count newline and null in count)
                bufp[1] = '\0';
 
                // submit to sink (do not count newline and null in count)
-               sink->put(buffer, bufp - buffer);
+               sink->put(buffer, (unsigned int)(bufp - buffer));
        }
 }
 
        }
 }
 
@@ -248,7 +249,7 @@ void Target::dump(const char *format, va_list args)
        char buffer[messageConstructionSize];   // building the message here
        vsnprintf(buffer, sizeof(buffer), format, args);
        for (char *p = buffer; *p; p++)
        char buffer[messageConstructionSize];   // building the message here
        vsnprintf(buffer, sizeof(buffer), format, args);
        for (char *p = buffer; *p; p++)
-               if (!isprint(*p) && !isspace(*p) || *p == '\r')
+               if ((!isprint(*p) && !isspace(*p)) || *p == '\r')
                        *p = '?';
        sink->dump(buffer);
 }
                        *p = '?';
        sink->dump(buffer);
 }
index 39e5aa1cbd1cc525885d879e1fd647b57a083519..b9f49c12504c1b4d417570c8df922c31bfb48751 100644 (file)
 #define _H_DEBUGGING
 
 
 #define _H_DEBUGGING
 
 
-//
-// Include DTrace static probe definitions
-//
-typedef const void *DTException;
-
-#include <security_utilities/utilities_dtrace.h>
-
+#include <security_utilities/debugging_internal.h>
 
 #ifdef __cplusplus
 
 
 #ifdef __cplusplus
 
@@ -43,7 +37,6 @@ typedef const void *DTException;
 #include <cstdarg>
 #include <typeinfo>
 
 #include <cstdarg>
 #include <typeinfo>
 
-
 namespace Security {
 namespace Debug {
 
 namespace Security {
 namespace Debug {
 
@@ -124,31 +117,13 @@ inline void vdebug(const char *scope, const char *format, va_list args) { }
 // leak debug() into the global namespace because URLAccess et al rely on that
 using Security::Debug::debug;
 
 // leak debug() into the global namespace because URLAccess et al rely on that
 using Security::Debug::debug;
 
-
 #else  //__cplusplus
 
 #include <stdio.h>
 
 #endif //__cplusplus
 
 #else  //__cplusplus
 
 #include <stdio.h>
 
 #endif //__cplusplus
 
-
-//
-// The debug-log macro is now unconditionally emitted as a DTrace static probe point.
-//
-#define secdebug(scope, format...) \
-       if (__builtin_expect(SECURITY_DEBUG_LOG_ENABLED(), 0)) { \
-               char __msg[500]; snprintf(__msg, sizeof(__msg), ## format); \
-               volatile char c __attribute__((unused)) = scope[0]; \
-               SECURITY_DEBUG_LOG((char *)(scope), (__msg)); \
-       } else /* nothing */
-#define secdebugf(scope, __msg)        SECURITY_DEBUG_LOG((char *)(scope), (__msg))
-
-
-//
-// The old secdelay() macro is also emitted as a DTrace probe (use destructive actions to handle this).
-// Secdelay() should be considered a legacy feature; just put a secdebug at the intended delay point.
-//
-#define secdelay(file) SECURITY_DEBUG_DELAY((char *)(file))
+#include <CoreFoundation/CFString.h>
 
 
 #endif //_H_DEBUGGING
 
 
 #endif //_H_DEBUGGING
diff --git a/libsecurity_utilities/lib/debugging_internal.cpp b/libsecurity_utilities/lib/debugging_internal.cpp
new file mode 100644 (file)
index 0000000..dc72060
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2000-2012 Apple Computer, Inc. All Rights Reserved.
+ * 
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+
+#include "debugging_internal.h"
+#include <stdarg.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+void secdebug_internal(const char* scope, const char* format, ...)
+{
+    if (__builtin_expect(SECURITY_DEBUG_LOG_ENABLED(), 0))
+    {
+        va_list list;
+        va_start(list, format);
+        
+        CFStringRef formatString = CFStringCreateWithCString(NULL, format, kCFStringEncodingUTF8);
+        CFStringRef message = CFStringCreateWithFormatAndArguments(kCFAllocatorDefault, NULL, formatString, list);
+        CFRelease(formatString);
+        CFIndex maxLength = CFStringGetMaximumSizeForEncoding(CFStringGetLength(message), kCFStringEncodingUTF8) + 1;
+        char buffer[maxLength];
+        CFStringGetCString(message, buffer, sizeof(buffer), kCFStringEncodingUTF8);
+        CFRelease(message);
+        SECURITY_DEBUG_LOG((char *)(scope), (buffer));
+        
+        va_end(list);
+    }
+}
diff --git a/libsecurity_utilities/lib/debugging_internal.h b/libsecurity_utilities/lib/debugging_internal.h
new file mode 100644 (file)
index 0000000..0199679
--- /dev/null
@@ -0,0 +1,45 @@
+//
+//  debugging_internal.h
+//  libsecurity_utilities
+//
+//  Created by ohjelmoija on 11/27/12.
+//
+//
+
+#ifndef libsecurity_utilities_debugging_internal_h
+#define libsecurity_utilities_debugging_internal_h
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif // __cplusplus
+
+//
+// Include DTrace static probe definitions
+//
+typedef const void *DTException;
+
+#include <security_utilities/utilities_dtrace.h>
+
+//
+// The debug-log macro is now unconditionally emitted as a DTrace static probe point.
+//
+
+void secdebug_internal(const char* scope, const char* format, ...);
+
+#define secdebug(scope, format...) secdebug_internal(scope, format)
+#define secdebugf(scope, __msg)        SECURITY_DEBUG_LOG((char *)(scope), (__msg))
+
+//
+// The old secdelay() macro is also emitted as a DTrace probe (use destructive actions to handle this).
+// Secdelay() should be considered a legacy feature; just put a secdebug at the intended delay point.
+//
+#define secdelay(file) SECURITY_DEBUG_DELAY((char *)(file))
+
+
+#ifdef __cplusplus
+};
+#endif // __cplusplus
+
+#endif
index 474bd9b5c46501d3cbee7c9af80a1894927fed07..bf2be9daec8395ae88c4451eb2f32a0427505764 100644 (file)
@@ -58,7 +58,7 @@ public:
        
        Name(const char *start, const char *end)
        {
        
        Name(const char *start, const char *end)
        {
-               int length = end - start; if (length >= maxLength) length = maxLength - 1;
+               intptr_t length = end - start; if (length >= maxLength) length = maxLength - 1;
                memcpy(mName, start, length); memset(mName + length, 0, maxLength - length);
        }
        
                memcpy(mName, start, length); memset(mName + length, 0, maxLength - length);
        }
        
index 8f8ddcfe21a88804d40aa259025887051320aacc..267e52d84cbfb09a78aa2ba278b55969c4223eb3 100644 (file)
@@ -83,8 +83,8 @@ DYLDCache::DYLDCache(const std::string &path)
                UnixError::throwMe(ENOEXEC);
        mFlip = *((const uint8_t *)&mArch->order) != 0x12;
        
                UnixError::throwMe(ENOEXEC);
        mFlip = *((const uint8_t *)&mArch->order) != 0x12;
        
-       mSigStart = flip(mHeader->codeSignatureOffset);
-       mSigLength = flip(mHeader->codeSignatureSize);
+       mSigStart = (size_t)flip(mHeader->codeSignatureOffset);
+       mSigLength = (size_t)flip(mHeader->codeSignatureSize);
 }
 
 
 }
 
 
index 6e32decd920d5fdacc2b96e1ae74ff0626a8ad9a..c004658b96428257b057f6bd4dc844ea075e6ac2 100644 (file)
@@ -125,8 +125,10 @@ public:
     Endian() : mValue(Type(0)) { }
     Endian(Value v) : mValue(h2n(v)) { }
     
     Endian() : mValue(Type(0)) { }
     Endian(Value v) : mValue(h2n(v)) { }
     
-    operator Value () const            { return n2h(mValue); }
+    Type get ()        const                   { return n2h(mValue); }
+    operator Value () const            { return this->get(); }
     Endian &operator = (Value v)       { mValue = h2n(v); return *this; }
     Endian &operator = (Value v)       { mValue = h2n(v); return *this; }
+
     
 private:
     Value mValue;
     
 private:
     Value mValue;
index 47c58616ff9faaeb433ebf558b78cc5129628251..585297754e0ad5ecadc818dbd1fa04d80600ffc5 100644 (file)
@@ -29,7 +29,7 @@
 #include <security_utilities/debugging.h>
 #include <typeinfo>
 #include <stdio.h>
 #include <security_utilities/debugging.h>
 #include <typeinfo>
 #include <stdio.h>
-
+#include <Security/SecBase.h>
 
 //@@@
 // From cssmapple.h - layering break
 
 //@@@
 // From cssmapple.h - layering break
@@ -140,13 +140,8 @@ CFError::CFError()
 const char *CFError::what() const throw ()
 { return "CoreFoundation error"; }
 
 const char *CFError::what() const throw ()
 { return "CoreFoundation error"; }
 
-// can't get this from CarbonCore/MacErrors, but it's too good to pass up
-enum {
-       coreFoundationUnknownErr      = -4960
-};
-
 OSStatus CFError::osStatus() const
 OSStatus CFError::osStatus() const
-{ return coreFoundationUnknownErr; }
+{ return errSecCoreFoundationUnknown; }
 
 int CFError::unixError() const
 {
 
 int CFError::unixError() const
 {
@@ -155,3 +150,26 @@ int CFError::unixError() const
 
 void CFError::throwMe()
 { throw CFError(); }
 
 void CFError::throwMe()
 { throw CFError(); }
+
+
+
+
+void ModuleNexusError::throwMe()
+{
+    throw ModuleNexusError();
+}
+
+
+
+OSStatus ModuleNexusError::osStatus() const
+{
+    return errSecParam;
+}
+
+
+
+int ModuleNexusError::unixError() const
+{
+    return EINVAL;      
+}
+
index cbb78668b5d8fe0f8574e666cc5d75b49a009a0d..dfc686d5c76ef9c33bd2077a5cbb682d729ee443 100644 (file)
@@ -30,9 +30,8 @@
 
 #include <AvailabilityMacros.h>
 #include <exception>
 
 #include <AvailabilityMacros.h>
 #include <exception>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
 #include <errno.h>
 #include <errno.h>
-
+#include <Security/SecBase.h>
 #undef check
 
 
 #undef check
 
 
@@ -92,7 +91,7 @@ public:
        virtual int unixError() const;
     virtual const char *what () const throw ();
     
        virtual int unixError() const;
     virtual const char *what () const throw ();
     
-    static void check(OSStatus status) { if (status != noErr) throwMe(status); }
+    static void check(OSStatus status) { if (status != errSecSuccess) throwMe(status); }
     static void throwMe(int err) __attribute__((noreturn));
 };
 
     static void throwMe(int err) __attribute__((noreturn));
 };
 
@@ -118,6 +117,17 @@ public:
 };
 
 
 };
 
 
+// Something that gets thrown when ModuleNexus creation fails
+class ModuleNexusError : public CommonError {
+protected:
+    ModuleNexusError() {}
+
+public:
+    virtual OSStatus osStatus() const;
+       virtual int unixError() const;
+    static void throwMe() __attribute__((noreturn));
+};
+
 } // end namespace Security
 
 
 } // end namespace Security
 
 
diff --git a/libsecurity_utilities/lib/exports b/libsecurity_utilities/lib/exports
new file mode 100644 (file)
index 0000000..b799d11
--- /dev/null
@@ -0,0 +1 @@
+_secdebug_internal
index 2f23a6ce9ec6d33d14612c81ae1d058ba43e4e12..4e1713f846d103c0e613d6c490adcb8b3b5b1f81 100644 (file)
@@ -37,7 +37,7 @@ namespace IPPlusPlus {
 void *FdMover::Element::operator new (size_t base, size_t more)
 {
        Element *element = (Element *)::malloc(CMSG_SPACE(more));
 void *FdMover::Element::operator new (size_t base, size_t more)
 {
        Element *element = (Element *)::malloc(CMSG_SPACE(more));
-       element->cmsg_len = CMSG_LEN(more);
+       element->cmsg_len = (socklen_t)CMSG_LEN(more);
        return element;
 }
 
        return element;
 }
 
@@ -92,7 +92,7 @@ size_t FdMover::receive(void *data, size_t length, FdVector &fds)
        msg.set(elem.get());
        ssize_t rc = ::recvmsg(fd(), &msg, 0);
        checkError(rc);
        msg.set(elem.get());
        ssize_t rc = ::recvmsg(fd(), &msg, 0);
        checkError(rc);
-       unsigned count = elem.get()->payloadSize() / sizeof(int);
+       size_t count = elem.get()->payloadSize() / sizeof(int);
        FdVector result;
        copy(&elem.get()->payload<int>(), &elem.get()->payload<int>() + count, back_inserter(result));
        swap(fds, result);
        FdVector result;
        copy(&elem.get()->payload<int>(), &elem.get()->payload<int>() + count, back_inserter(result));
        swap(fds, result);
index 1ef33e31ed77b70cc6f4cfd9d2398b6cdb406ee4..c9ea764906bf3cc45cd8550673e6ec0a988031dc 100644 (file)
@@ -46,88 +46,33 @@ GlobalNexus::Error::~Error() throw()
 {
 }
 
 {
 }
 
+void ModuleNexusCommon::do_create(void *(*make)())
+{
+    try
+    {
+        pointer = make();
+    }
+    catch (...)
+    {
+        pointer = NULL;
+    }
+}
+
+
 
 
-//
-// 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)
-//     (b) Pointers acquired from new have at least their LSB zero (are at
-//      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.
-//
 void *ModuleNexusCommon::create(void *(*make)())
 {
 void *ModuleNexusCommon::create(void *(*make)())
 {
-    sync++;            // keep mutex alive if needed
-  retry:
-    void *initialPointer = Atomic<void *>::load(pointer);      // latch pointer
-    if (!initialPointer || (uintptr_t(initialPointer) & 0x1)) {
-        Mutex *mutex;
-        if (initialPointer == 0) {
-            mutex = new Mutex;
-            mutex->lock();
-                       if (!Atomic<void *>::casb(0, (void *)(uintptr_t(mutex) | 0x1), pointer)) {
-                // somebody beat us to the lead - back off
-                mutex->unlock();
-                delete mutex;
-                goto retry;
-            }
-            // we have the ball
-            try {
-                void *singleton = make();
-                pointer = singleton;
-                // we need a write barrier here, but the mutex->unlock below provides it for free
-            } catch (...) {
-                               secdebug("nexus", "ModuleNexus %p construction failed", this);
-                mutex->unlock();
-                if (--sync == 0) {
-                    delete mutex;
-                    pointer = 0;
-                }
-                throw;
-            }
-        } else {
-            mutex = reinterpret_cast<Mutex *>(uintptr_t(initialPointer) & ~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;
+    dispatch_once(&once, ^{do_create(make);});
+    
+    if (pointer == NULL)
+    {
+        ModuleNexusError::throwMe();
     }
     }
+    
     return pointer;
 }
 
 
     return pointer;
 }
 
 
-// thread nexus static globals
-ModuleNexus<Mutex> ThreadNexusBase::mInstanceLock;
-
-// Thread nexus globals
-ModuleNexus<RetentionSet> ThreadNexusBase::mInstances;
-
 //
 // Process nexus operation
 //
 //
 // Process nexus operation
 //
index 4fe8e56a6b5a91a686f86a20e80dd0447c6f9b34..8a7e91a1635d299b8f85db19b0fe18d9373b0121 100644 (file)
@@ -31,6 +31,8 @@
 #include <security_utilities/threading.h>
 #include <memory>
 #include <set>
 #include <security_utilities/threading.h>
 #include <memory>
 #include <set>
+#include <dispatch/dispatch.h>
+#include <libkern/OSAtomic.h>
 
 namespace Security {
 
 
 namespace Security {
 
@@ -52,51 +54,68 @@ public:
 };
 
 
 };
 
 
-//
-// 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.
-//
 class ModuleNexusCommon : public GlobalNexus {
 class ModuleNexusCommon : public GlobalNexus {
+private:
+    void do_create(void *(*make)());
+
 protected:
     void *create(void *(*make)());
 protected:
     void *create(void *(*make)());
-    
+    void lock() {OSSpinLockLock(&access);}
+    void unlock() {OSSpinLockUnlock(&access);}
+
 protected:
 protected:
-    // both of these will be statically initialized to zero
+    // all of these will be statically initialized to zero
        void *pointer;
        void *pointer;
-    StaticAtomicCounter<uint32_t> sync;
+    dispatch_once_t once;
+    OSSpinLock access;
 };
 
 template <class Type>
 class ModuleNexus : public ModuleNexusCommon {
 public:
 };
 
 template <class Type>
 class ModuleNexus : public ModuleNexusCommon {
 public:
-    Type &operator () ()
+    Type &operator () () 
     {
     {
-        void *p = Atomic<void *>::load(pointer);       // latch pointer
-               if (!p || (uintptr_t(p) & 0x1)) {
-                       p = create(make);
-                       secdebug("nexus", "module %s 0x%p", Debug::typeName<Type>().c_str(), pointer);
-               }
-               return *reinterpret_cast<Type *>(p);
+        lock();
+        
+        try
+        {
+            if (pointer == NULL)
+            {
+                pointer = create(make);
+            }
+            
+            unlock();
+        }
+        catch (...)
+        {
+            unlock();
+            throw;
+        }
+        
+               return *reinterpret_cast<Type *>(pointer);
     }
        
        // does the object DEFINITELY exist already?
        bool exists() const
        {
     }
        
        // does the object DEFINITELY exist already?
        bool exists() const
        {
-               return Atomic<void *>::load(pointer) != NULL;
+        bool result;
+        lock();
+        result = pointer != NULL;
+        unlock();
+        return result;
        }
     
        // destroy the object (if any) and start over - not really thread-safe
     void reset()
     {
        }
     
        // destroy the object (if any) and start over - not really thread-safe
     void reset()
     {
-        if (pointer && !(uintptr_t(pointer) & 0x1)) {
+        lock();
+        if (pointer != NULL)
+        {
             delete reinterpret_cast<Type *>(pointer);
             delete reinterpret_cast<Type *>(pointer);
-            Atomic<void *>::store(0, pointer);
+            pointer = NULL;
+            once = 0;
         }
         }
+        unlock();
     }
     
 private:
     }
     
 private:
@@ -116,14 +135,6 @@ public:
 
 typedef std::set<void*> RetentionSet;
 
 
 typedef std::set<void*> RetentionSet;
 
-class ThreadNexusBase {
-protected:
-       static ModuleNexus<Mutex> mInstanceLock;
-       static ModuleNexus<RetentionSet> mInstances;
-};
-
-
-
 //
 // 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
 //
 // 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
@@ -133,7 +144,7 @@ protected:
 // zero-initialization ThreadNexi, put them inside a ModuleNexus.
 //
 template <class Type>
 // zero-initialization ThreadNexi, put them inside a ModuleNexus.
 //
 template <class Type>
-class ThreadNexus : public GlobalNexus, private ThreadNexusBase {
+class ThreadNexus : public GlobalNexus {
 public:
     ThreadNexus() : mSlot(true) { }
 
 public:
     ThreadNexus() : mSlot(true) { }
 
@@ -143,10 +154,6 @@ public:
         if (Type *p = mSlot)
             return *p;
         mSlot = new Type;
         if (Type *p = mSlot)
             return *p;
         mSlot = new Type;
-               {
-                       StLock<Mutex> _(mInstanceLock ());
-                       mInstances ().insert(mSlot);
-               }
         return *mSlot;
     }
 
         return *mSlot;
     }
 
index da3780a23d65da814234f1c57e1ee68b9e9b9aad..e931bd56a13dc637174c07ff48a9364f6bdd4367 100644 (file)
@@ -175,7 +175,7 @@ class SHA1 : public CC_SHA1_CTX, public Hash<CC_SHA1_DIGEST_LENGTH, SHA1>   {
 public:
        SHA1() { CC_SHA1_Init(this); }
        void update(const void *data, size_t length)
 public:
        SHA1() { CC_SHA1_Init(this); }
        void update(const void *data, size_t length)
-               { CC_SHA1_Update(this, data, length); }
+               { CC_SHA1_Update(this, data, (CC_LONG)length); }
        void finish(Byte *digest) { CC_SHA1_Final(digest, this); }
        using Hash<CC_SHA1_DIGEST_LENGTH, SHA1>::finish;
 };
        void finish(Byte *digest) { CC_SHA1_Final(digest, this); }
        using Hash<CC_SHA1_DIGEST_LENGTH, SHA1>::finish;
 };
index f229ce2f06015c74942a707132678cf34f68281d..94ddb30e38067452e417ef40a08ebdb4ec29ab59 100644 (file)
@@ -47,7 +47,7 @@ void InetReply::analyze()
 {
     // follow Internet rule #1: be lenient in what you accept
     /*const*/ char *p;                         // (un-const is ANSI bogosity in strtol)
 {
     // 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);
+    mCode = (int) strtol(mBuffer, &p, 10);
     if (p == mBuffer) {                        // conversion failed
         mCode = -1;                            // error indicator
         mSeparator = ' ';
     if (p == mBuffer) {                        // conversion failed
         mCode = -1;                            // error indicator
         mSeparator = ' ';
index 12677addd56f95690cf6119381da8f2762c25a79..f9f3065e82d90b9726429263631b615f3166d1d2 100644 (file)
@@ -83,7 +83,7 @@ public:
        Vnode() : KEvent(EVFILT_VNODE) { }
        Vnode(int fd, uint32_t flags) : KEvent(EVFILT_VNODE, fd, flags) { }
        
        Vnode() : KEvent(EVFILT_VNODE) { }
        Vnode(int fd, uint32_t flags) : KEvent(EVFILT_VNODE, fd, flags) { }
        
-       int fd() const { return this->ident; }
+       int fd() const { return (int)this->ident; }
 };
 
 } // namespace Event
 };
 
 } // namespace Event
index 930ccf2524ff2bf9b6c90d8523b77d0e70ae8c1f..c663d4c0f00392d091464016c750a95eea68d3e5 100644 (file)
@@ -311,13 +311,13 @@ StBootstrap::~StBootstrap()
 //
 // Mach message buffers
 //
 //
 // Mach message buffers
 //
-Message::Message(void *buffer, size_t size)
+Message::Message(void *buffer, mach_msg_size_t size)
        : mBuffer(NULL), mRelease(false)
 {
        setBuffer(buffer, size);
 }
 
        : mBuffer(NULL), mRelease(false)
 {
        setBuffer(buffer, size);
 }
 
-Message::Message(size_t size)
+Message::Message(mach_msg_size_t size)
        : mBuffer(NULL), mRelease(false)
 {
        setBuffer(size);
        : mBuffer(NULL), mRelease(false)
 {
        setBuffer(size);
@@ -334,7 +334,7 @@ Message::~Message()
 }
 
 
 }
 
 
-void Message::setBuffer(void *buffer, size_t size)
+void Message::setBuffer(void *buffer, mach_msg_size_t size)
 {
        release();
        mBuffer = reinterpret_cast<mig_reply_error_t *>(buffer);
 {
        release();
        mBuffer = reinterpret_cast<mig_reply_error_t *>(buffer);
@@ -342,7 +342,7 @@ void Message::setBuffer(void *buffer, size_t size)
        mRelease = false;
 }
 
        mRelease = false;
 }
 
-void Message::setBuffer(size_t size)
+void Message::setBuffer(mach_msg_size_t size)
 {
        assert(size >= sizeof(mach_msg_header_t));
        release();
 {
        assert(size >= sizeof(mach_msg_header_t));
        release();
index cb45ae28ba36772f00aa363233d535b9d51af461..5735682862108b08b94afedb9cd546c5af9b607c 100644 (file)
@@ -268,14 +268,14 @@ private:
 //
 class Message {
 public:
 //
 class Message {
 public:
-    Message(void *buffer, size_t size);                // use buffer with size
-    Message(size_t size);                                      // allocate buffer with size
-       Message();                                                              // set buffer later
+    Message(void *buffer, mach_msg_size_t size);               // use buffer with size
+    Message(mach_msg_size_t size);                                     // allocate buffer with size
+    Message();                                                         // set buffer later
     virtual ~Message();
        
     virtual ~Message();
        
-       void setBuffer(void *buffer, size_t size); // use buffer with size
-       void setBuffer(size_t size);                    // allocate buffer with size
-       void release();                                                 // discard buffer (if any)
+    void setBuffer(void *buffer, mach_msg_size_t size); // use buffer with size
+    void setBuffer(mach_msg_size_t size);                      // allocate buffer with size
+    void release();                                                    // discard buffer (if any)
 
     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; }
@@ -284,7 +284,7 @@ public:
     operator NDR_record_t & () const           { return mBuffer->NDR; }
     
     void *data() const                                         { return mBuffer; }
     operator NDR_record_t & () const           { return mBuffer->NDR; }
     
     void *data() const                                         { return mBuffer; }
-    size_t length() const                                      { return mBuffer->Head.msgh_size; }
+    mach_msg_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; }
     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; }
@@ -314,7 +314,7 @@ protected:
 
 private:
     mig_reply_error_t *mBuffer;
 
 private:
     mig_reply_error_t *mBuffer;
-    size_t mSize;
+    mach_msg_size_t mSize;
     bool mRelease;
 };
 
     bool mRelease;
 };
 
index 8c56b0e3b007ab2752927ceb268e7962587c26d5..71e226b61676b974b58172c587e26d2e18a4443d 100644 (file)
@@ -141,6 +141,8 @@ void MachOBase::initCommands(const load_command *commands)
 {
        mCommands = commands;
        mEndCommands = LowLevelMemoryUtilities::increment<load_command>(commands, flip(mHeader->sizeofcmds));
 {
        mCommands = commands;
        mEndCommands = LowLevelMemoryUtilities::increment<load_command>(commands, flip(mHeader->sizeofcmds));
+       if (mCommands + 1 > mEndCommands)       // ensure initial load command core available
+               UnixError::throwMe(ENOEXEC);
 }
 
 
 }
 
 
@@ -235,7 +237,12 @@ const load_command *MachOBase::nextCommand(const load_command *command) const
 {
        using LowLevelMemoryUtilities::increment;
        command = increment<const load_command>(command, flip(command->cmdsize));
 {
        using LowLevelMemoryUtilities::increment;
        command = increment<const load_command>(command, flip(command->cmdsize));
-       return (command < mEndCommands) ? command : NULL;
+       if (command >= mEndCommands)    // end of load commands
+               return NULL;
+       if (increment(command, sizeof(load_command)) > mEndCommands
+               || increment(command, flip(command->cmdsize)) > mEndCommands)
+               UnixError::throwMe(ENOEXEC);
+       return command;
 }
 
 
 }
 
 
@@ -384,7 +391,7 @@ CFDataRef MachO::dataAt(size_t offset, size_t size)
 // Fat (aka universal) file wrappers.
 // The offset is relative to the start of the containing file.
 //
 // Fat (aka universal) file wrappers.
 // The offset is relative to the start of the containing file.
 //
-Universal::Universal(FileDesc fd, off_t offset /* = 0 */)
+Universal::Universal(FileDesc fd, size_t offset /* = 0 */)
        : FileDesc(fd), mBase(offset)
 {
        union {
        : FileDesc(fd), mBase(offset)
 {
        union {
@@ -493,7 +500,7 @@ size_t Universal::archOffset(const Architecture &arch) const
 // Get the architecture at a specified offset from the fat file.
 // Throws an exception of the offset does not point at a Mach-O image.
 //
 // Get the architecture at a specified offset from the fat file.
 // Throws an exception of the offset does not point at a Mach-O image.
 //
-MachO *Universal::architecture(off_t offset) const
+MachO *Universal::architecture(size_t offset) const
 {
        if (isUniversal())
                return new MachO(*this, offset);
 {
        if (isUniversal())
                return new MachO(*this, offset);
@@ -606,6 +613,7 @@ uint32_t Universal::typeOf(FileDesc fd)
                        return 0;
                }
        }
                        return 0;
                }
        }
+    return 0;
 }
 
 
 }
 
 
index 29ff3bfb7d0e89611d0ccbe013b8966381f1fd17..c1280b67f73a87db39c8a71fb457bf980c6a435f 100644 (file)
@@ -182,17 +182,18 @@ public:
 //
 class Universal : public UnixPlusPlus::FileDesc {
 public:
 //
 class Universal : public UnixPlusPlus::FileDesc {
 public:
-       Universal(FileDesc fd, off_t offset = 0);
+       Universal(FileDesc fd, size_t offset = 0);
        ~Universal();
        
        // return a genuine MachO object for the given architecture
        MachO *architecture() const;            // native
        MachO *architecture(const Architecture &arch) const; // given
        ~Universal();
        
        // return a genuine MachO object for the given architecture
        MachO *architecture() const;            // native
        MachO *architecture(const Architecture &arch) const; // given
-       MachO *architecture(off_t offset) const; // given by file offset
+       MachO *architecture(size_t offset) const; // given by file offset
        
        // return (just) the starting offset of an architecture
        size_t archOffset() const;                      // native
        size_t archOffset(const Architecture &arch) const; // given
        
        // return (just) the starting offset of an architecture
        size_t archOffset() const;                      // native
        size_t archOffset(const Architecture &arch) const; // given
+       bool narrowed() const { return mBase != 0; }    // part of a fat file
        
        // return a set of architectures contained
        typedef std::set<Architecture> Architectures;
        
        // return a set of architectures contained
        typedef std::set<Architecture> Architectures;
@@ -212,7 +213,7 @@ private:
        fat_arch *mArchList;            // architectures (NULL if thin file)
        unsigned mArchCount;            // number of architectures (if fat)
        Architecture mThinArch;         // single architecture (if thin)
        fat_arch *mArchList;            // architectures (NULL if thin file)
        unsigned mArchCount;            // number of architectures (if fat)
        Architecture mThinArch;         // single architecture (if thin)
-       off_t mBase;                            // overriding offset in file (all types)
+       size_t mBase;                           // overriding offset in file (all types)
 };
 
 
 };
 
 
index cc0ed5c17f9fe66f0793dc0379c803915e15c892..a4cb1284b777779e5100adf12a2d6f0932229e46 100644 (file)
@@ -48,7 +48,7 @@ MachRunLoopServer::MachRunLoopServer(const char *name, const Bootstrap &boot)
 {
 }
 
 {
 }
 
-void MachRunLoopServer::run(size_t bufferSize, mach_msg_options_t options)
+void MachRunLoopServer::run(mach_msg_size_t bufferSize, mach_msg_options_t options)
 {
        // allocate reply buffer
        mReplyMessage.setBuffer(bufferSize);
 {
        // allocate reply buffer
        mReplyMessage.setBuffer(bufferSize);
@@ -73,7 +73,7 @@ MachRunLoopServer::~MachRunLoopServer()
 // 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.
 //
 // 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
+void MachRunLoopServer::notifyIfDead(Port port, bool doNotify) const
 {
        if (CFMachPortRef cfPort = CFMachPortCreateWithPort(NULL, port, NULL, NULL, NULL))
                CFMachPortSetInvalidationCallBack(cfPort, cfInvalidate);
 {
        if (CFMachPortRef cfPort = CFMachPortCreateWithPort(NULL, port, NULL, NULL, NULL))
                CFMachPortSetInvalidationCallBack(cfPort, cfInvalidate);
@@ -89,12 +89,12 @@ void MachRunLoopServer::cfInvalidate(CFMachPortRef cfPort, void *context)
 //
 // Reception callback
 //
 //
 // Reception callback
 //
-void MachRunLoopServer::receive(Message &request)
+void MachRunLoopServer::receive(const Message &request)
 {
        active().oneRequest(request);
 }
 
 {
        active().oneRequest(request);
 }
 
-void MachRunLoopServer::oneRequest(Message &request)
+void MachRunLoopServer::oneRequest(const Message &request)
 {
        if (!handle(request, mReplyMessage)) {  // MIG dispatch failed
                secdebug("machrls", "MachRunLoopServer dispatch failed");
 {
        if (!handle(request, mReplyMessage)) {  // MIG dispatch failed
                secdebug("machrls", "MachRunLoopServer dispatch failed");
index d810b6cf2f236b2755c58ead2b2f17910c2f23ce..da7f656d17c43e380dbed4e5676b1131bf89b16e 100644 (file)
@@ -54,16 +54,16 @@ public:
        MachRunLoopServer(const char *name, const Bootstrap &boot); // register in bootstrap
        virtual ~MachRunLoopServer();
 
        MachRunLoopServer(const char *name, const Bootstrap &boot); // register in bootstrap
        virtual ~MachRunLoopServer();
 
-       void run(size_t maxSize = 4096, mach_msg_options_t options = 0);
+       void run(mach_msg_size_t maxSize = 4096, mach_msg_options_t options = 0);
 
        static MachRunLoopServer &active()
        { return safer_cast<MachRunLoopServer &>(MachServer::active()); }
        
 
        static MachRunLoopServer &active()
        { return safer_cast<MachRunLoopServer &>(MachServer::active()); }
        
-       void notifyIfDead(Port port) const;
+       void notifyIfDead(Port port, bool doNotify = true) const;
 
 protected:
 
 protected:
-       void receive(Message &request);
-       void oneRequest(Message &request);
+       void receive(const Message &request);
+       void oneRequest(const Message &request);
 
 private:
        static void cfInvalidate(CFMachPortRef port, void *info);
 
 private:
        static void cfInvalidate(CFMachPortRef port, void *info);
index c71336b7e0b7f7a18965b7b260b850489fe16787..c036e61786c4db679cacaa208261119c1cc18e15 100644 (file)
@@ -129,7 +129,7 @@ void MachServer::notifyIfUnused(Port port, bool doNotify) const
 // as appropriate.
 // @@@ Msg-errors in additional threads are not acted upon.
 //
 // as appropriate.
 // @@@ Msg-errors in additional threads are not acted upon.
 //
-void MachServer::run(size_t maxSize, mach_msg_options_t options)
+void MachServer::run(mach_msg_size_t maxSize, mach_msg_options_t options)
 {
        // establish server-global (thread-shared) parameters
        mMaxSize = maxSize;
 {
        // establish server-global (thread-shared) parameters
        mMaxSize = maxSize;
@@ -177,7 +177,7 @@ void MachServer::runServerThread(bool doTimeout)
                        eventDone();
                        
                        // process all pending timers
                        eventDone();
                        
                        // process all pending timers
-                       while (processTimer()) ;
+                       while (processTimer()) {}
                
                        // check for worker idle timeout
                        {       StLock<Mutex> _(managerLock);
                
                        // check for worker idle timeout
                        {       StLock<Mutex> _(managerLock);
index e59067873768c37e09162e64f8cdd5961cb22a63..d1a9bc46d55bf97df02745ab10ee95a64532d037 100644 (file)
@@ -80,7 +80,7 @@ public:
        MachServer(const char *name, const Bootstrap &bootstrap);
        virtual ~MachServer();
        
        MachServer(const char *name, const Bootstrap &bootstrap);
        virtual ~MachServer();
        
-       void run(size_t maxSize = 4096, mach_msg_options_t options = 0);
+       void run(mach_msg_size_t maxSize = 4096, mach_msg_options_t options = 0);
        
        Time::Interval timeout() const { return workerTimeout; }
        void timeout(Time::Interval t)  { workerTimeout = t; }
        
        Time::Interval timeout() const { return workerTimeout; }
        void timeout(Time::Interval t)  { workerTimeout = t; }
@@ -190,7 +190,7 @@ protected:
        ReceivePort mServerPort;                // registered/primary server port
     PortSet mPortSet;                          // joint receiver port set
        
        ReceivePort mServerPort;                // registered/primary server port
     PortSet mPortSet;                          // joint receiver port set
        
-       size_t mMaxSize;                                // maximum message size
+       mach_msg_size_t mMaxSize;                               // maximum message size
        mach_msg_options_t mMsgOptions; // kernel call options
     
     typedef set<Handler *> HandlerSet;
        mach_msg_options_t mMsgOptions; // kernel call options
     
     typedef set<Handler *> HandlerSet;
index aca848aabd8db4c564f254fdb47f57adf806873b..bef8d462b4c4c90335e02dea937738b48a9d0115 100644 (file)
@@ -84,7 +84,7 @@ public:
        { 
         if (length > uint32_t(~0))
             UnixError::throwMe(ERANGE);
        { 
         if (length > uint32_t(~0))
             UnixError::throwMe(ERANGE);
-        Endian<uint32_t> temp = length; (*this)(temp); (*this)(data, length); 
+        Endian<uint32_t> temp = (uint32_t)length; (*this)(temp); (*this)(data, length); 
     }
        
        template <class Data>
     }
        
        template <class Data>
index b56dd7e1aa0b4babd254d2b5abfad6038185f373..a50a4cbdd75fc9127ee11cddd7aa640fe6608264 100644 (file)
@@ -92,7 +92,7 @@ void Connection::open(const PCSC::ReaderState &reader, unsigned share)
        // set ATR in info
        assert(reader.length() <= MAX_ATR_SIZE);
        memcpy(info.tokenId, reader.data(), reader.length());
        // set ATR in info
        assert(reader.length() <= MAX_ATR_SIZE);
        memcpy(info.tokenId, reader.data(), reader.length());
-       info.tokenIdLength = reader.length();
+       info.tokenIdLength = (MSCULong32)reader.length();
        
        // establish Muscle-level connection to card
        Error::check(::MSCEstablishConnection(&info, share, NULL, 0, this));
        
        // establish Muscle-level connection to card
        Error::check(::MSCEstablishConnection(&info, share, NULL, 0, this));
index e5b0a91806dde612660ad1dcea5a46d55d0b536e..f1b10f755bace5c86ab7e4dee0d181e22e8035e3 100644 (file)
@@ -200,9 +200,9 @@ void Bundle::resources(vector<string> &paths, const char *type, const char *subd
 {
        CFRef<CFArrayRef> cfList = CFBundleCopyResourceURLsOfType(cfBundle(),
                CFTempString(type), CFTempString(subdir));
 {
        CFRef<CFArrayRef> cfList = CFBundleCopyResourceURLsOfType(cfBundle(),
                CFTempString(type), CFTempString(subdir));
-       UInt32 size = CFArrayGetCount(cfList);
+       CFIndex size = CFArrayGetCount(cfList);
        paths.reserve(size);
        paths.reserve(size);
-       for (UInt32 n = 0; n < size; n++)
+       for (CFIndex n = 0; n < size; n++)
                paths.push_back(cfString(CFURLRef(CFArrayGetValueAtIndex(cfList, n))));
 }
 
                paths.push_back(cfString(CFURLRef(CFArrayGetValueAtIndex(cfList, n))));
 }
 
index 4b82f03d4f2f5f954f0549d668846a4e0eba5d4e..c0d6a16a562b2e75acc3769023ce065e09f77a4e 100644 (file)
@@ -59,13 +59,13 @@ inline void decode(vector<string> &names, const vector<char> &buffer, size_t siz
 //
 Error::Error(unsigned long err) : error(err)
 {
 //
 Error::Error(unsigned long err) : error(err)
 {
-       SECURITY_EXCEPTION_THROW_PCSC(this, err);
+       SECURITY_EXCEPTION_THROW_PCSC(this, (unsigned int)err);
 }
 
 
 const char *Error::what() const throw ()
 {
 }
 
 
 const char *Error::what() const throw ()
 {
-       return pcsc_stringify_error(error);
+       return pcsc_stringify_error((int32_t)error);
 }
 
 
 }
 
 
@@ -101,14 +101,14 @@ void ReaderState::set(const char *name, unsigned long known)
        clearPod();
        szReader = name;
        pvUserData = NULL;
        clearPod();
        szReader = name;
        pvUserData = NULL;
-       dwCurrentState = known;
+       dwCurrentState = (uint32_t)known;
 }
 
 
 void ReaderState::lastKnown(unsigned long s)
 {
        // clear out CHANGED and UNAVAILABLE
 }
 
 
 void ReaderState::lastKnown(unsigned long s)
 {
        // clear out CHANGED and UNAVAILABLE
-       dwCurrentState = s & ~(SCARD_STATE_CHANGED | SCARD_STATE_UNAVAILABLE);
+       dwCurrentState = (uint32_t)s & ~(SCARD_STATE_CHANGED | SCARD_STATE_UNAVAILABLE);
 }
 
 
 }
 
 
@@ -117,7 +117,7 @@ void ReaderState::setATR(const void *atr, size_t size)
        if (size > sizeof(rgbAtr))
                Error::throwMe(SCARD_E_INVALID_ATR);
        memcpy(rgbAtr, atr, size);
        if (size > sizeof(rgbAtr))
                Error::throwMe(SCARD_E_INVALID_ATR);
        memcpy(rgbAtr, atr, size);
-       cbAtr = size;
+       cbAtr = (uint32_t)size;
 }
 
 
 }
 
 
@@ -225,7 +225,7 @@ void Session::statusChange(ReaderState *readers, unsigned int nReaders, long tim
 {
        if (nReaders == 0)
                return; // no readers, no foul
 {
        if (nReaders == 0)
                return; // no readers, no foul
-       check(::SCardGetStatusChange(mContext, timeout, readers, nReaders));
+       check(::SCardGetStatusChange(mContext, (uint32_t)timeout, readers, nReaders));
 }
 
 
 }
 
 
@@ -262,7 +262,7 @@ void Card::connect(Session &session, const char *reader,
 {
        uint32_t activeProtocol;
        Error::check(::SCardConnect(session.mContext,
 {
        uint32_t activeProtocol;
        Error::check(::SCardConnect(session.mContext,
-               reader, share, protocols, &mHandle, &activeProtocol));
+               reader, (uint32_t)share, (uint32_t)protocols, &mHandle, &activeProtocol));
        setIOType(activeProtocol);
        mConnectedState = kConnected;
 }
        setIOType(activeProtocol);
        mConnectedState = kConnected;
 }
@@ -271,9 +271,9 @@ void Card::reconnect(unsigned long share, unsigned long protocols, unsigned long
 {
        assert(mConnectedState != kInitial);
 
 {
        assert(mConnectedState != kInitial);
 
-       DWORD activeProtocol;
-       Error::check(::SCardReconnect(mHandle, share, protocols,
-               initialization, &activeProtocol));
+       uint32_t activeProtocol;
+       Error::check(::SCardReconnect(mHandle, (uint32_t)share, (uint32_t)protocols,
+               (uint32_t)initialization, &activeProtocol));
        setIOType(activeProtocol);
        mConnectedState = kConnected;
 }
        setIOType(activeProtocol);
        mConnectedState = kConnected;
 }
@@ -288,7 +288,7 @@ void Card::disconnect(unsigned long disposition)
                        mTransactionNestLevel = 0;
                }
 
                        mTransactionNestLevel = 0;
                }
 
-               checkReset(::SCardDisconnect(mHandle, disposition));
+               checkReset(::SCardDisconnect(mHandle, (uint32_t)disposition));
                didDisconnect();
                mConnectedState = kInitial;
        }
                didDisconnect();
                mConnectedState = kInitial;
        }
@@ -329,8 +329,8 @@ Card::transmit(const unsigned char *pbSendBuffer, size_t cbSendLength,
 
        IFDUMPING("pcsc", dump("->", pbSendBuffer, cbSendLength));
 
 
        IFDUMPING("pcsc", dump("->", pbSendBuffer, cbSendLength));
 
-       uint32_t tmpRecvLength = pcbRecvLength;
-       checkReset(::SCardTransmit(mHandle, mIOType, pbSendBuffer, cbSendLength,
+       uint32_t tmpRecvLength = (uint32_t)pcbRecvLength;
+       checkReset(::SCardTransmit(mHandle, mIOType, pbSendBuffer, (uint32_t)cbSendLength,
                NULL, pbRecvBuffer, &tmpRecvLength));
        pcbRecvLength = tmpRecvLength;
        
                NULL, pbRecvBuffer, &tmpRecvLength));
        pcbRecvLength = tmpRecvLength;
        
@@ -366,7 +366,7 @@ void Card::end(unsigned long disposition)
                        reconnect();
                }
 
                        reconnect();
                }
 
-               checkReset(::SCardEndTransaction(mHandle, disposition));
+               checkReset(::SCardEndTransaction(mHandle, (uint32_t)disposition));
                didDisconnect();
        }
        else if (mTransactionNestLevel > 0)
                didDisconnect();
        }
        else if (mTransactionNestLevel > 0)
@@ -378,7 +378,7 @@ void Card::end(unsigned long disposition)
                                secdebug("pcsc", "%p: end transaction while disconnected ignored", this);
                        else
                        {
                                secdebug("pcsc", "%p: end transaction while disconnected ignored", this);
                        else
                        {
-                               checkReset(::SCardEndTransaction(mHandle, disposition));
+                               checkReset(::SCardEndTransaction(mHandle, (uint32_t)disposition));
                                didEnd();
                        }
                }
                                didEnd();
                        }
                }
index a224c63316e6ecb90fb8897e690020aa60fd5bac..40d13953619ae91a62ace1acb4453876fb57f6c2 100644 (file)
@@ -110,7 +110,7 @@ public:
        void statusChange(ReaderState &reader, long timeout = 0)
        { return statusChange(&reader, 1, timeout); }
        void statusChange(vector<ReaderState> &readers, long timeout = 0)
        void statusChange(ReaderState &reader, long timeout = 0)
        { return statusChange(&reader, 1, timeout); }
        void statusChange(vector<ReaderState> &readers, long timeout = 0)
-       { return statusChange(&readers[0], readers.size(), timeout); }
+       { return statusChange(&readers[0], (unsigned int)readers.size(), timeout); }
        
 
 private:
        
 
 private:
index f1ab95249917aa1eb0d8560352921d2b95fcb956..9c197af2b19487c6f3be3729ac3fe24a8af6f011 100644 (file)
@@ -103,37 +103,48 @@ IOPowerWatcher::setupDarkWake()
     
     mInDarkWake = false;
 
     
     mInDarkWake = false;
 
-    mIOPMqueue = dispatch_queue_create("com.apple.security.IOPowerWatcher", NULL);
-    if (mIOPMqueue == NULL)
-       return;
-
     ret = ::IOPMConnectionCreate(CFSTR("IOPowerWatcher"),
                                 kIOPMSystemPowerStateCapabilityDisk 
                                 | kIOPMSystemPowerStateCapabilityNetwork
                                 | kIOPMSystemPowerStateCapabilityAudio 
                                 | kIOPMSystemPowerStateCapabilityVideo,
                                 &mIOPMconn);
     ret = ::IOPMConnectionCreate(CFSTR("IOPowerWatcher"),
                                 kIOPMSystemPowerStateCapabilityDisk 
                                 | kIOPMSystemPowerStateCapabilityNetwork
                                 | kIOPMSystemPowerStateCapabilityAudio 
                                 | kIOPMSystemPowerStateCapabilityVideo,
                                 &mIOPMconn);
-    if (ret != kIOReturnSuccess)
-       return;
-       
-    ret = ::IOPMConnectionSetNotification(mIOPMconn, this,
-                                         (IOPMEventHandlerType)iopmcallback);
-    if (ret != kIOReturnSuccess)
-       return;
-
-    ::IOPMConnectionSetDispatchQueue(mIOPMconn, mIOPMqueue);
+    if (ret == kIOReturnSuccess) {
+        ret = ::IOPMConnectionSetNotification(mIOPMconn, this,
+                          (IOPMEventHandlerType)iopmcallback);
+        if (ret == kIOReturnSuccess) {
+            ::IOPMConnectionSetDispatchQueue(mIOPMconn, mIOPMqueue);
+        }
+    }
+
+    dispatch_group_leave(mDarkWakeGroup);
 }
 
 IOPowerWatcher::IOPowerWatcher()
 {
 }
 
 IOPowerWatcher::IOPowerWatcher()
 {
-    if (!(mKernelPort = ::IORegisterForSystemPower(this, &mPortRef, ioCallback, &mHandle)))
-        UnixError::throwMe(EINVAL);    // no clue
-
-       setupDarkWake();
+       if (!(mKernelPort = ::IORegisterForSystemPower(this, &mPortRef, ioCallback, &mHandle)))
+               UnixError::throwMe(EINVAL);     // no clue
+
+       mIOPMqueue = dispatch_queue_create("com.apple.security.IOPowerWatcher", NULL);
+       if (mIOPMqueue == NULL)
+               return;
+
+       // Running in background since this will wait for the power
+       // management in configd and we are not willing to block on
+       // that, power events will come in when they do.
+       mDarkWakeGroup = dispatch_group_create();
+       dispatch_group_enter(mDarkWakeGroup);
+       dispatch_async(mIOPMqueue, ^ { setupDarkWake(); });
 }
 
 IOPowerWatcher::~IOPowerWatcher()
 {
 }
 
 IOPowerWatcher::~IOPowerWatcher()
 {
+       // Make sure to wait until the asynchronous method
+       // finishes, to avoid <rdar://problem/14355434>
+       if (mDarkWakeGroup) {
+               ::dispatch_group_wait(mDarkWakeGroup, DISPATCH_TIME_FOREVER);
+               ::dispatch_release(mDarkWakeGroup);
+       }
        if (mKernelPort)
                ::IODeregisterForSystemPower(&mHandle);
 
        if (mKernelPort)
                ::IODeregisterForSystemPower(&mHandle);
 
index 4d044827bd33bb031f6b8a0d45d1b25f9c82db4c..cfde5fe33da695acabcf125c2c85230151f020c8 100644 (file)
@@ -74,6 +74,7 @@ protected:
     io_object_t mHandle;
     IOPMConnection mIOPMconn;
     dispatch_queue_t mIOPMqueue;
     io_object_t mHandle;
     IOPMConnection mIOPMconn;
     dispatch_queue_t mIOPMqueue;
+    dispatch_group_t mDarkWakeGroup;
     
     static void ioCallback(void *refCon, io_service_t service,
         natural_t messageType, void *argument);
     
     static void ioCallback(void *refCon, io_service_t service,
         natural_t messageType, void *argument);
index b5a726789f24a8de27b2d7f1185aa79ef413950c..e68cf71816f7cfc55c271d907958fcbee06e7d63 100644 (file)
@@ -29,6 +29,7 @@
 #define _SECURITY_REFCOUNT_H_
 
 #include <security_utilities/threading.h>
 #define _SECURITY_REFCOUNT_H_
 
 #include <security_utilities/threading.h>
+#include <libkern/OSAtomic.h>
 
 namespace Security {
 
 
 namespace Security {
 
@@ -70,14 +71,23 @@ public:
 protected:
        template <class T> friend class RefPointer;
 
 protected:
        template <class T> friend class RefPointer;
 
-       void ref() const                        { ++mRefCount; RCDEBUG(UP, mRefCount); }
-       unsigned int unref() const      { RCDEBUG(DOWN, mRefCount - 1); return --mRefCount; }
+       void ref() const
+    {
+        OSAtomicIncrement32(&mRefCount);
+        RCDEBUG(UP, mRefCount);
+    }
+       
+    unsigned int unref() const
+    {
+        RCDEBUG(DOWN, mRefCount - 1);
+        return OSAtomicDecrement32(&mRefCount);
+    }
        
        // if you call this for anything but debug output, you will go to hell (free handbasket included)
        unsigned int refCountForDebuggingOnly() const { return mRefCount; }
 
 private:
        
        // if you call this for anything but debug output, you will go to hell (free handbasket included)
        unsigned int refCountForDebuggingOnly() const { return mRefCount; }
 
 private:
-    mutable AtomicCounter<unsigned int> mRefCount;
+    volatile mutable int32_t mRefCount;
 };
 
 
 };
 
 
@@ -111,7 +121,7 @@ public:
        T & operator * () const         { _check(); return *ptr; }
 
 protected:
        T & operator * () const         { _check(); return *ptr; }
 
 protected:
-       void release()
+       void release_internal()
     {
         if (ptr && ptr->unref() == 0)
         {
     {
         if (ptr && ptr->unref() == 0)
         {
@@ -120,11 +130,28 @@ protected:
         }
     }
        
         }
     }
        
-    void setPointer(T *p) { if (p) p->ref(); release(); ptr = p; }
+    void release()
+    {
+        StLock<Mutex> mutexLock(mMutex);
+        release_internal();
+    }
+    
+    void setPointer(T *p)
+    {
+        StLock<Mutex> mutexLock(mMutex);
+        if (p)
+        {
+            p->ref();
+        }
+        
+        release_internal();
+        ptr = p;
+    }
        
        void _check() const { }
 
        T *ptr;
        
        void _check() const { }
 
        T *ptr;
+    Mutex mMutex;
 };
 
 template <class T>
 };
 
 template <class T>
index 537c086260e00ce323c096672139d5d06f719685..43b716b754f37492b76eedca440bc3d9c000f802 100644 (file)
@@ -45,7 +45,7 @@ SecPointerBase::SecPointerBase(const SecPointerBase& p)
 static void CheckForRelease(SecCFObject* ptr)
 {
        CFTypeRef tr = ptr->operator CFTypeRef();
 static void CheckForRelease(SecCFObject* ptr)
 {
        CFTypeRef tr = ptr->operator CFTypeRef();
-       int retainCount = CFGetRetainCount(tr);
+       CFIndex retainCount = CFGetRetainCount(tr);
        if (retainCount == 1 || retainCount == -1)
        {
                ptr->aboutToDestruct();
        if (retainCount == 1 || retainCount == -1)
        {
                ptr->aboutToDestruct();
@@ -159,7 +159,7 @@ SecCFObject::allocate(size_t size, const CFClass &cfclass) throw(std::bad_alloc)
 
        if (SECURITY_DEBUG_SEC_CREATE_ENABLED()) {
                const CFRuntimeClass *rtc = _CFRuntimeGetClassWithTypeID(cfclass.typeID);
 
        if (SECURITY_DEBUG_SEC_CREATE_ENABLED()) {
                const CFRuntimeClass *rtc = _CFRuntimeGetClassWithTypeID(cfclass.typeID);
-               SECURITY_DEBUG_SEC_CREATE(q, rtc ? (char *)rtc->className : NULL, cfclass.typeID);
+               SECURITY_DEBUG_SEC_CREATE(q, rtc ? (char *)rtc->className : NULL, (unsigned int)cfclass.typeID);
        }
        return q;
 }
        }
        return q;
 }
@@ -261,3 +261,10 @@ SecCFObject::getMutexForObject()
 {
        return NULL; // we only worry about descendants of KeychainImpl and ItemImpl
 }
 {
        return NULL; // we only worry about descendants of KeychainImpl and ItemImpl
 }
+
+
+
+bool SecCFObject::mayDelete()
+{
+    return true;
+}
index 022e9a5f4dcd9e4de4fb2a40cc76e760ee850815..311a202d4ee1054dc117d912891493eb5c9dd6d7 100644 (file)
@@ -108,6 +108,7 @@ public:
        virtual CFStringRef copyDebugDesc();
        virtual void aboutToDestruct();
        virtual Mutex* getMutexForObject();
        virtual CFStringRef copyDebugDesc();
        virtual void aboutToDestruct();
        virtual Mutex* getMutexForObject();
+    virtual bool mayDelete();
 };
 
 //
 };
 
 //
index 9b3cba1a992252227e5392b4fec45ee7eaa20a8e..e5744d93b3b023ff1859bc2221e4e8aec9120326 100644 (file)
@@ -98,11 +98,17 @@ int Error::unixError() const
 //
 // Database objects
 //
 //
 // Database objects
 //
-Database::Database(const char *path, int flags)
+Database::Database(const char *path, int flags, bool lenient /* = false */)
        : mMutex(Mutex::recursive)
 {
        try {
        : mMutex(Mutex::recursive)
 {
        try {
-               check(::sqlite3_open_v2(path, &mDb, flags, NULL));
+               int rc = ::sqlite3_open_v2(path, &mDb, flags, NULL);
+               if (rc != SQLITE_OK && lenient) {       // silent open failure
+                       sqlite3_close(mDb); // ditch useless Db object
+                       mDb = NULL;                     // indicate failure
+                       return;
+               }
+               check(rc);
                check(::sqlite3_extended_result_codes(mDb, true));
                mOpenFlags = flags;
        } catch (...) {
                check(::sqlite3_extended_result_codes(mDb, true));
                mOpenFlags = flags;
        } catch (...) {
@@ -378,11 +384,11 @@ void Statement::Binding::blob(const void *data, size_t length, bool shared /* =
        if (data == NULL)
                this->null();
        else if (shared) {
        if (data == NULL)
                this->null();
        else if (shared) {
-               statement.check(::sqlite3_bind_blob(statement.sql(), index, data, length, NULL));
+               statement.check(::sqlite3_bind_blob(statement.sql(), index, data, (int)length, NULL));
        } else if (void *copy = ::malloc(length)) {
                ::memcpy(copy, data, length);
                statement.check(::sqlite3_bind_blob(statement.sql(), index,
        } else if (void *copy = ::malloc(length)) {
                ::memcpy(copy, data, length);
                statement.check(::sqlite3_bind_blob(statement.sql(), index,
-               copy, length, ::free));
+               copy, (int)length, ::free));
        } else
                throw std::bad_alloc();
 }
        } else
                throw std::bad_alloc();
 }
index 1db59aaa7e434efa3c48e6fb74915a8b7f31dc0a..1b3894f7a8bec7b7c779394b2dbde6e6f435ed59 100644 (file)
@@ -69,9 +69,10 @@ public:
 class Database {
        friend class Statement;
 public:
 class Database {
        friend class Statement;
 public:
-       Database(const char *path, int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
+       Database(const char *path, int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, bool lenient = false);
        virtual ~Database();
        
        virtual ~Database();
        
+       bool isOpen() const { return mDb != NULL; }
        void close();
        
        // open flags
        void close();
        
        // open flags
index cef2ee3ecf8c4c8e90cbcb92a89ca83669c93fd3..785f51ce33e9283eea3fcc8cd285a8541d3c0fda 100644 (file)
@@ -184,7 +184,7 @@ template <class _BlobType, uint32_t _magic, class _Type>
 size_t SuperBlobCore<_BlobType, _magic, _Type>::Maker::size(size_t size1, ...) const
 {
        // count established blobs
 size_t SuperBlobCore<_BlobType, _magic, _Type>::Maker::size(size_t size1, ...) const
 {
        // count established blobs
-       unsigned count = mPieces.size();
+       size_t count = mPieces.size();
        size_t total = 0;
        for (typename BlobMap::const_iterator it = mPieces.begin(); it != mPieces.end(); ++it)
                total += it->second->length();
        size_t total = 0;
        for (typename BlobMap::const_iterator it = mPieces.begin(); it != mPieces.end(); ++it)
                total += it->second->length();
@@ -212,17 +212,17 @@ size_t SuperBlobCore<_BlobType, _magic, _Type>::Maker::size(size_t size1, ...) c
 template <class _BlobType, uint32_t _magic, class _Type>
 _BlobType *SuperBlobCore<_BlobType, _magic, _Type>::Maker::make() const
 {
 template <class _BlobType, uint32_t _magic, class _Type>
 _BlobType *SuperBlobCore<_BlobType, _magic, _Type>::Maker::make() const
 {
-       Offset pc = sizeof(SuperBlobCore) + mPieces.size() * sizeof(Index);
-       Offset total = size();
+       Offset pc = (Offset)(sizeof(SuperBlobCore) + mPieces.size() * sizeof(Index));
+       Offset total = (Offset)size();
        _BlobType *result = (_BlobType *)malloc(total);
        if (!result)
                UnixError::throwMe(ENOMEM);
        _BlobType *result = (_BlobType *)malloc(total);
        if (!result)
                UnixError::throwMe(ENOMEM);
-       result->setup(total, mPieces.size());
+       result->setup(total, (unsigned)mPieces.size());
        unsigned n = 0;
        for (typename BlobMap::const_iterator it = mPieces.begin(); it != mPieces.end(); ++it) {
                result->mIndex[n].type = it->first;
                result->mIndex[n].offset = pc;
        unsigned n = 0;
        for (typename BlobMap::const_iterator it = mPieces.begin(); it != mPieces.end(); ++it) {
                result->mIndex[n].type = it->first;
                result->mIndex[n].offset = pc;
-               memcpy(result->at<unsigned char>(pc), it->second, it->second->length());
+               memcpy(result->template at<unsigned char>(pc), it->second, it->second->length());
                pc += it->second->length();
                n++;
        }
                pc += it->second->length();
                n++;
        }
index 3bc71a1105172236b4b899303080ba25844f4f88..0d387181168353d0ebbc32f1a96d48f15756291b 100644 (file)
@@ -213,8 +213,8 @@ void Thread::run()
     {
         syslog(LOG_ERR, "error %d setting thread detach state", err);
     }
     {
         syslog(LOG_ERR, "error %d setting thread detach state", err);
     }
-    while (err = pthread_create(&self.mIdent, &ptattrs, runner, this) && 
-           --ntries)
+    while ((err = pthread_create(&self.mIdent, &ptattrs, runner, this) && 
+           --ntries))
     {
         syslog(LOG_ERR, "pthread_create() error %d", err);
         usleep(50000);          // 50 ms is arbitrary
     {
         syslog(LOG_ERR, "pthread_create() error %d", err);
         usleep(50000);          // 50 ms is arbitrary
@@ -241,6 +241,7 @@ void *Thread::runner(void *arg)
     }
     catch (...)
     {
     }
     catch (...)
     {
+        return NULL;
     }
 }
 
     }
 }
 
index d47a6085f26fdd05d06638070c52e3ab8d6a66a8..b3b6854f3b2062d111d33448c0a838cdc17c88fd 100644 (file)
@@ -116,7 +116,7 @@ public:
        
        static Type load(const Type &store) { readBarrier(); return store; }
        static Type store(Type value, Type &store)
        
        static Type load(const Type &store) { readBarrier(); return store; }
        static Type store(Type value, Type &store)
-       { while (!casb(store, value, store)) /* again */; return value; }
+       { while (!casb(store, value, store)) {}; return value; }
 };
 
 
 };
 
 
index 604a08b7566020874db3c4b3f0aca52d3ebda1de..9e9643ac7c1f6d1130caef54331edbfd06830677 100644 (file)
@@ -44,11 +44,13 @@ using LowLevelMemoryUtilities::increment;
 //
 void FileDesc::open(const char *path, int flags, mode_t mode)
 {
 //
 void FileDesc::open(const char *path, int flags, mode_t mode)
 {
-       if ((mFd = ::open(path, flags, mode & ~S_IFMT)) == -1)
-               if (errno == ENOENT && (mode & S_IFMT) == modeMissingOk)
+       if ((mFd = ::open(path, flags, mode & ~S_IFMT)) == -1) {
+               if (errno == ENOENT && (mode & S_IFMT) == modeMissingOk) {
                        return;
                        return;
-               else
+               } else {
                        UnixError::throwMe();
                        UnixError::throwMe();
+        }
+    }
        mAtEnd = false;
     secdebug("unixio", "open(%s,0x%x,0x%x) = %d", path, flags, mode, mFd);
 }
        mAtEnd = false;
     secdebug("unixio", "open(%s,0x%x,0x%x) = %d", path, flags, mode, mFd);
 }
@@ -103,12 +105,12 @@ size_t FileDesc::write(const void *addr, size_t length)
 // These don't affect file position and the atEnd() flag; and they
 // don't make allowances for asynchronous I/O.
 //
 // These don't affect file position and the atEnd() flag; and they
 // don't make allowances for asynchronous I/O.
 //
-size_t FileDesc::read(void *addr, size_t length, off_t position)
+size_t FileDesc::read(void *addr, size_t length, size_t position)
 {
        return checkError(::pread(mFd, addr, length, position));
 }
 
 {
        return checkError(::pread(mFd, addr, length, position));
 }
 
-size_t FileDesc::write(const void *addr, size_t length, off_t position)
+size_t FileDesc::write(const void *addr, size_t length, size_t position)
 {
        return checkError(::pwrite(mFd, addr, length, position));
 }
 {
        return checkError(::pwrite(mFd, addr, length, position));
 }
@@ -157,21 +159,23 @@ void FileDesc::writeAll(const void *addr, size_t length)
 //
 // Seeking
 //
 //
 // Seeking
 //
-size_t FileDesc::seek(off_t position, int whence)
+#warning Cast to size_t may loose precision, only a problem for large files.
+
+size_t FileDesc::seek(size_t position, int whence)
 {
 {
-    return checkError(::lseek(mFd, position, whence));
+    return (size_t)checkError(::lseek(mFd, position, whence));
 }
 
 size_t FileDesc::position() const
 {
 }
 
 size_t FileDesc::position() const
 {
-       return checkError(::lseek(mFd, 0, SEEK_CUR));
+       return (size_t)checkError(::lseek(mFd, 0, SEEK_CUR));
 }
 
 
 //
 // Mmap support
 //
 }
 
 
 //
 // Mmap support
 //
-void *FileDesc::mmap(int prot, size_t length, int flags, off_t offset, void *addr)
+void *FileDesc::mmap(int prot, size_t length, int flags, size_t offset, void *addr)
 {
        if (!(flags & (MAP_PRIVATE | MAP_SHARED)))      // one is required
                flags |= MAP_PRIVATE;
 {
        if (!(flags & (MAP_PRIVATE | MAP_SHARED)))      // one is required
                flags |= MAP_PRIVATE;
@@ -352,7 +356,7 @@ size_t FileDesc::fileSize() const
 {
     struct stat st;
     fstat(st);
 {
     struct stat st;
     fstat(st);
-    return st.st_size;
+    return (size_t)st.st_size;
 }
 
 bool FileDesc::isA(int mode) const
 }
 
 bool FileDesc::isA(int mode) const
index be1eedaa1005e00b1ec868ab1da1f10891df974b..03895d085cbd29cb9ea1224f080385d08427091b 100644 (file)
@@ -124,8 +124,8 @@ public:
     bool atEnd() const                 { return mAtEnd; }      // valid after zero-length read only
        
        // basic I/O with positioning
     bool atEnd() const                 { return mAtEnd; }      // valid after zero-length read only
        
        // basic I/O with positioning
-       size_t read(void *addr, size_t length, off_t position);
-       size_t write(const void *addr, size_t length, off_t position);
+       size_t read(void *addr, size_t length, size_t position);
+       size_t write(const void *addr, size_t length, size_t position);
 
        // read/write all of a buffer, in pieces of necessary
        size_t readAll(void *addr, size_t length);
 
        // read/write all of a buffer, in pieces of necessary
        size_t readAll(void *addr, size_t length);
@@ -141,12 +141,12 @@ public:
     template <class T> size_t write(const T &obj) { return write(&obj, sizeof(obj)); }
     
     // seeking
     template <class T> size_t write(const T &obj) { return write(&obj, sizeof(obj)); }
     
     // seeking
-    size_t seek(off_t position, int whence = SEEK_SET);
+    size_t seek(size_t position, int whence = SEEK_SET);
        size_t position() const;
     
     // mapping support
     void *mmap(int prot = PROT_READ, size_t length = 0,
        size_t position() const;
     
     // mapping support
     void *mmap(int prot = PROT_READ, size_t length = 0,
-               int flags = MAP_FILE | MAP_PRIVATE, off_t offset = 0, void *addr = NULL);
+               int flags = MAP_FILE | MAP_PRIVATE, size_t offset = 0, void *addr = NULL);
     
     // fcntl support
     int fcntl(int cmd, void *arg = NULL) const;
     
     // fcntl support
     int fcntl(int cmd, void *arg = NULL) const;
@@ -166,11 +166,11 @@ public:
        
        // lock support (fcntl style)
        struct Pos {
        
        // lock support (fcntl style)
        struct Pos {
-               Pos(off_t s = 0, int wh = SEEK_SET, off_t siz = 0)
+               Pos(size_t s = 0, int wh = SEEK_SET, size_t siz = 0)
                        : start(s), size(siz), whence(wh) { }
 
                        : start(s), size(siz), whence(wh) { }
 
-               off_t start;
-               off_t size;
+               size_t start;
+               size_t size;
                int whence;
        };
        static Pos lockAll()    { return Pos(0, SEEK_SET, 0); }
                int whence;
        };
        static Pos lockAll()    { return Pos(0, SEEK_SET, 0); }
index 9c3500ddc40c2acf40535c76c90989e2ecfe59ea..500575f83cc4937d3ace6d7981f7f904cec1a541 100644 (file)
@@ -27,7 +27,7 @@
 //
 #include "vproc++.h"
 #include <security_utilities/debugging.h>
 //
 #include "vproc++.h"
 #include <security_utilities/debugging.h>
-#include </usr/local/include/vproc_priv.h>
+#include <vproc_priv.h>
 
 
 namespace Security {
 
 
 namespace Security {
index 837261d9aa2ee7d95378ec9c76128e9558939ba5..03c008f1681e3a161305f8c3c9b4eafa74f48ab1 100644 (file)
                4CA684FB0525011E00233BF2 /* url.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CA684BB0525011E00233BF2 /* url.cpp */; };
                4CA684FD0525011E00233BF2 /* utilities.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CA684BD0525011E00233BF2 /* utilities.cpp */; };
                4E4813D707739B0C0090D7C2 /* ccaudit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4E4813D507739B0C0090D7C2 /* ccaudit.cpp */; };
                4CA684FB0525011E00233BF2 /* url.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CA684BB0525011E00233BF2 /* url.cpp */; };
                4CA684FD0525011E00233BF2 /* utilities.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CA684BD0525011E00233BF2 /* utilities.cpp */; };
                4E4813D707739B0C0090D7C2 /* ccaudit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4E4813D507739B0C0090D7C2 /* ccaudit.cpp */; };
+               AAA4B91E16653547005DEFDC /* debugging_internal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AAA4B91D16653547005DEFDC /* debugging_internal.cpp */; };
+               AAA4B920166535B4005DEFDC /* debugging_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = AAA4B91F16653597005DEFDC /* debugging_internal.h */; settings = {ATTRIBUTES = (Public, ); }; };
                AAAA499A0CC587B50099E9D4 /* crc.c in Sources */ = {isa = PBXBuildFile; fileRef = AAAA49980CC587B50099E9D4 /* crc.c */; };
                C200C0800731DEA300564CE0 /* trackingallocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C200C07F0731DE8C00564CE0 /* trackingallocator.cpp */; };
                C20A206B06B03FDC00979EF3 /* osxcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C20A206906B03FDC00979EF3 /* osxcode.cpp */; };
                AAAA499A0CC587B50099E9D4 /* crc.c in Sources */ = {isa = PBXBuildFile; fileRef = AAAA49980CC587B50099E9D4 /* crc.c */; };
                C200C0800731DEA300564CE0 /* trackingallocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C200C07F0731DE8C00564CE0 /* trackingallocator.cpp */; };
                C20A206B06B03FDC00979EF3 /* osxcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C20A206906B03FDC00979EF3 /* osxcode.cpp */; };
                4CA684BF0525011E00233BF2 /* utility_config.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = utility_config.h; sourceTree = "<group>"; };
                4E4813D507739B0C0090D7C2 /* ccaudit.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ccaudit.cpp; sourceTree = "<group>"; };
                4E4813D607739B0C0090D7C2 /* ccaudit.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ccaudit.h; sourceTree = "<group>"; };
                4CA684BF0525011E00233BF2 /* utility_config.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = utility_config.h; sourceTree = "<group>"; };
                4E4813D507739B0C0090D7C2 /* ccaudit.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ccaudit.cpp; sourceTree = "<group>"; };
                4E4813D607739B0C0090D7C2 /* ccaudit.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ccaudit.h; sourceTree = "<group>"; };
+               AA3BC08D166549EA00EF1D2E /* exports */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = exports; sourceTree = "<group>"; };
                AA5B97E70E140C3E0032C12F /* dtrace.mk */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = dtrace.mk; path = lib/dtrace.mk; sourceTree = "<group>"; usesTabs = 1; };
                AA5B97E70E140C3E0032C12F /* dtrace.mk */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = dtrace.mk; path = lib/dtrace.mk; sourceTree = "<group>"; usesTabs = 1; };
+               AAA4B91D16653547005DEFDC /* debugging_internal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debugging_internal.cpp; sourceTree = "<group>"; };
+               AAA4B91F16653597005DEFDC /* debugging_internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = debugging_internal.h; sourceTree = "<group>"; };
                AAAA49980CC587B50099E9D4 /* crc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crc.c; sourceTree = "<group>"; };
                AAAA49990CC587B50099E9D4 /* crc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = crc.h; sourceTree = "<group>"; };
                C200C07F0731DE8C00564CE0 /* trackingallocator.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = trackingallocator.cpp; path = lib/trackingallocator.cpp; sourceTree = SOURCE_ROOT; };
                AAAA49980CC587B50099E9D4 /* crc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crc.c; sourceTree = "<group>"; };
                AAAA49990CC587B50099E9D4 /* crc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = crc.h; sourceTree = "<group>"; };
                C200C07F0731DE8C00564CE0 /* trackingallocator.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = trackingallocator.cpp; path = lib/trackingallocator.cpp; sourceTree = SOURCE_ROOT; };
                                4CA684890525011D00233BF2 /* debugging.h */,
                                4CA6848A0525011D00233BF2 /* debugsupport.h */,
                                4CA684880525011D00233BF2 /* debugging.cpp */,
                                4CA684890525011D00233BF2 /* debugging.h */,
                                4CA6848A0525011D00233BF2 /* debugsupport.h */,
                                4CA684880525011D00233BF2 /* debugging.cpp */,
+                               AAA4B91D16653547005DEFDC /* debugging_internal.cpp */,
+                               AAA4B91F16653597005DEFDC /* debugging_internal.h */,
                                4CA6848C0525011D00233BF2 /* devrandom.h */,
                                4CA6848B0525011D00233BF2 /* devrandom.cpp */,
                                4CA6848E0525011D00233BF2 /* endian.h */,
                                4CA6848C0525011D00233BF2 /* devrandom.h */,
                                4CA6848B0525011D00233BF2 /* devrandom.cpp */,
                                4CA6848E0525011D00233BF2 /* endian.h */,
                                C2EF2B64066E52C100F205D4 /* Mach */,
                                C20A209606B040D400979EF3 /* CoreFoundation */,
                                C2EF2B61066E52AB00F205D4 /* Network */,
                                C2EF2B64066E52C100F205D4 /* Mach */,
                                C20A209606B040D400979EF3 /* CoreFoundation */,
                                C2EF2B61066E52AB00F205D4 /* Network */,
+                               AA3BC08D166549EA00EF1D2E /* exports */,
                        );
                        path = lib;
                        sourceTree = "<group>";
                        );
                        path = lib;
                        sourceTree = "<group>";
                                181EA3CB146D1D9700A6D320 /* socks++4.h in Headers */,
                                181EA3CC146D1D9700A6D320 /* socks++5.h in Headers */,
                                1865FC241472444600FD79DF /* utilities_dtrace.h in Headers */,
                                181EA3CB146D1D9700A6D320 /* socks++4.h in Headers */,
                                181EA3CC146D1D9700A6D320 /* socks++5.h in Headers */,
                                1865FC241472444600FD79DF /* utilities_dtrace.h in Headers */,
+                               AAA4B920166535B4005DEFDC /* debugging_internal.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        shellPath = /bin/sh;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        shellPath = /bin/sh;
-                       shellScript = "nmedit -p \"${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}\"\nranlib \"${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}\"";
+                       shellScript = "nmedit -s lib/exports -p \"${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}\"\nranlib \"${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}\"";
                };
                C2C9C69C0CECBE8400B3FE07 /* ShellScript */ = {
                        isa = PBXShellScriptBuildPhase;
                };
                C2C9C69C0CECBE8400B3FE07 /* ShellScript */ = {
                        isa = PBXShellScriptBuildPhase;
                                C2E7B1FA0E2415D700956987 /* vproc++.cpp in Sources */,
                                C28342CA0E366A8E00E54360 /* sqlite++.cpp in Sources */,
                                C2C1648E0F66F2D300FD6D34 /* kq++.cpp in Sources */,
                                C2E7B1FA0E2415D700956987 /* vproc++.cpp in Sources */,
                                C28342CA0E366A8E00E54360 /* sqlite++.cpp in Sources */,
                                C2C1648E0F66F2D300FD6D34 /* kq++.cpp in Sources */,
+                               AAA4B91E16653547005DEFDC /* debugging_internal.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 181EA3EB146D2A5F00A6D320 /* debug.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 181EA3EB146D2A5F00A6D320 /* debug.xcconfig */;
                        buildSettings = {
+                               EXPORTED_SYMBOLS_FILE = "";
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/security_utilities;
                                SKIP_INSTALL = NO;
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/security_utilities;
                                SKIP_INSTALL = NO;
+                               WARNING_CFLAGS = (
+                                       "-Wno-error=#warnings",
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                                       "$(inherited)",
+                               );
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 181EA3ED146D2A5F00A6D320 /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 181EA3ED146D2A5F00A6D320 /* release.xcconfig */;
                        buildSettings = {
+                               EXPORTED_SYMBOLS_FILE = "";
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/security_utilities;
                                SKIP_INSTALL = NO;
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/security_utilities;
                                SKIP_INSTALL = NO;
+                               WARNING_CFLAGS = (
+                                       "-Wno-error=#warnings",
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                                       "$(inherited)",
+                               );
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
index 2f1ada17467f0e1ba6a9355185ac2a227f173827..923767dc6c8a7253ffe6006828164e0f222cb204 100644 (file)
@@ -98,7 +98,7 @@ void SharedMemoryClient::ReadData (void* buffer, SegmentOffsetType length)
 
        u_int8_t* bptr = (u_int8_t*) buffer;
 
 
        u_int8_t* bptr = (u_int8_t*) buffer;
 
-       SegmentOffsetType bytesToEnd = mDataMax - mDataPtr;
+       SegmentOffsetType bytesToEnd = (SegmentOffsetType)(mDataMax - mDataPtr);
        
        // figure out how many bytes we can read
        SegmentOffsetType bytesToRead = (length <= bytesToEnd) ? length : bytesToEnd;
        
        // figure out how many bytes we can read
        SegmentOffsetType bytesToRead = (length <= bytesToEnd) ? length : bytesToEnd;
index bb15a65ea8ca09e7920c22e35289f662dea50732..f79ea20e5523e069b809f706159b2f3e298f44b9 100644 (file)
@@ -88,7 +88,7 @@ NameValuePair::~NameValuePair ()
 void NameValuePair::Export (CssmData &data) const
 {
        // export the data in the format name length data
 void NameValuePair::Export (CssmData &data) const
 {
        // export the data in the format name length data
-       uint32 outSize = 2 * sizeof (uint32) + mValue.length ();
+       size_t outSize = 2 * sizeof (uint32) + mValue.length ();
        unsigned char* d = (unsigned char*) malloc(outSize);
        unsigned char* finger = d;
        
        unsigned char* d = (unsigned char*) malloc(outSize);
        unsigned char* finger = d;
        
@@ -104,7 +104,7 @@ void NameValuePair::Export (CssmData &data) const
        
        // export the length
        finger += sizeof (uint32);
        
        // export the length
        finger += sizeof (uint32);
-       intBuffer = mValue.length ();
+       intBuffer = (uint32)mValue.length ();
        for (i = sizeof (uint32) - 1; i >= 0; --i)
        {
                finger[i] = intBuffer & 0xFF;
        for (i = sizeof (uint32) - 1; i >= 0; --i)
        {
                finger[i] = intBuffer & 0xFF;
@@ -129,7 +129,7 @@ NameValueDictionary::NameValueDictionary ()
 NameValueDictionary::~NameValueDictionary ()
 {
        // to prevent leaks, delete all members of the vector
 NameValueDictionary::~NameValueDictionary ()
 {
        // to prevent leaks, delete all members of the vector
-       int i = mVector.size ();
+       size_t i = mVector.size ();
        while (i > 0)
        {
                delete mVector[--i];
        while (i > 0)
        {
                delete mVector[--i];
@@ -258,7 +258,7 @@ const NameValuePair* NameValueDictionary::FindByName (uint32 name) const
 
 int NameValueDictionary::CountElements () const
 {
 
 int NameValueDictionary::CountElements () const
 {
-       return mVector.size ();
+       return (int)mVector.size ();
 }
 
 
 }
 
 
index 9f72962c28d78fee4dc54bfeca72e7b4a9b8a884..eecdd567dd4baa02b603c432972c9434f9fbb7c9 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2003-2004,2006 Apple Computer, Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2003-2004,2006,2011-2013 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -36,6 +36,7 @@ namespace Security {
 #define PID_KEY                                'pidk'
 #define ITEM_KEY                       'item'
 #define SSUID_KEY                      'ssui'
 #define PID_KEY                                'pidk'
 #define ITEM_KEY                       'item'
 #define SSUID_KEY                      'ssui'
+#define IDENTITY_KEY           'idnt'
 #define DB_NAME                                'dbnm'
 #define DB_LOCATION                    'dblc'
 
 #define DB_NAME                                'dbnm'
 #define DB_LOCATION                    'dblc'
 
@@ -48,7 +49,7 @@ protected:
        CssmData mValue;
 
        CssmData CloneData (const CssmData &value);
        CssmData mValue;
 
        CssmData CloneData (const CssmData &value);
-       
+
 public:
        NameValuePair (uint32 name, const CssmData &value);
        NameValuePair (const CssmData &data);
 public:
        NameValuePair (uint32 name, const CssmData &value);
        NameValuePair (const CssmData &data);
@@ -69,24 +70,24 @@ class NameValueDictionary
 {
 protected:
        NameValuePairVector mVector;
 {
 protected:
        NameValuePairVector mVector;
-       
+
        int FindPositionByName (uint32 name) const;
        int FindPositionByName (uint32 name) const;
-       
+
        void MakeFromData(const CssmData &data);
 
 public:
        NameValueDictionary ();
        ~NameValueDictionary ();
        NameValueDictionary (const CssmData &data);
        void MakeFromData(const CssmData &data);
 
 public:
        NameValueDictionary ();
        ~NameValueDictionary ();
        NameValueDictionary (const CssmData &data);
-       
+
        void Insert (NameValuePair* pair);
        void RemoveByName (uint32 name);
        const NameValuePair* FindByName (uint32 name) const;
        void Insert (NameValuePair* pair);
        void RemoveByName (uint32 name);
        const NameValuePair* FindByName (uint32 name) const;
-       
+
        int CountElements () const;
        int CountElements () const;
-       const NameValuePair* GetElement (int which);    
+       const NameValuePair* GetElement (int which);
        void Export (CssmData &data);
        void Export (CssmData &data);
-       
+
        // utility functions
        static void MakeNameValueDictionaryFromDLDbIdentifier (const DLDbIdentifier &identifier, NameValueDictionary &nvd);
        static DLDbIdentifier MakeDLDbIdentifierFromNameValueDictionary (const NameValueDictionary &nvd);
        // utility functions
        static void MakeNameValueDictionaryFromDLDbIdentifier (const DLDbIdentifier &identifier, NameValueDictionary &nvd);
        static DLDbIdentifier MakeDLDbIdentifierFromNameValueDictionary (const NameValueDictionary &nvd);
index fe5f03867599a3554dfd7d9388d47c39ee76d70b..e82f637450a5e3ce1e46a22e00860dc5ae865018 100644 (file)
@@ -94,7 +94,7 @@ bool_t sec_xdr_charp(XDR *xdrs, char **cpp, u_int maxsize)
         *cpp = NULL;
         return (TRUE);
     case XDR_ENCODE:
         *cpp = NULL;
         return (TRUE);
     case XDR_ENCODE:
-        if (sp) size = strlen(sp) + 1;
+        if (sp) size = (u_int)(strlen(sp) + 1);
         /* FALLTHROUGH */
     case XDR_DECODE:
         return sec_xdr_bytes(xdrs, (uint8_t**)cpp, &size, maxsize);
         /* FALLTHROUGH */
     case XDR_DECODE:
         return sec_xdr_bytes(xdrs, (uint8_t**)cpp, &size, maxsize);
@@ -223,7 +223,7 @@ bool_t copyin(void *data, xdrproc_t proc, void** copy, u_int *size)
     sec_xdrmem_create(&xdr, (char *)xdr_data, length, XDR_ENCODE);
 
     // cast to void* - function can go both ways (xdr->x_op) 
     sec_xdrmem_create(&xdr, (char *)xdr_data, length, XDR_ENCODE);
 
     // cast to void* - function can go both ways (xdr->x_op) 
-    if (proc(&xdr, data)) {
+    if (proc(&xdr, data, 0)) {
         *copy = xdr_data;
         if (size) *size = length;
         return (TRUE);
         *copy = xdr_data;
         if (size) *size = length;
         return (TRUE);
@@ -261,7 +261,7 @@ bool_t copyout(const void *copy, u_int size, xdrproc_t proc, void **data, u_int
     if (!sec_xdr_arena_init(&arena, &xdr, length_out ? length_out : length_required, length_out ? *data : NULL))
         return (FALSE);
 
     if (!sec_xdr_arena_init(&arena, &xdr, length_out ? length_out : length_required, length_out ? *data : NULL))
         return (FALSE);
 
-    if (proc(&xdr, data))
+    if (proc(&xdr, data, 0))
     {
         *length = length_required;
         return (TRUE);
     {
         *length = length_required;
         return (TRUE);
@@ -284,7 +284,7 @@ bool_t copyout_chunked(const void *copy, u_int size, xdrproc_t proc, void **data
 
     void *data_out = NULL;
 
 
     void *data_out = NULL;
 
-    if (proc(&xdr, &data_out))
+    if (proc(&xdr, &data_out, 0))
     {
         *data = data_out;
         return (TRUE);
     {
         *data = data_out;
         return (TRUE);
index 152a71b932d1603e59064a1ac70e156776ace63e..e5ec1adeb5a7e8ce9d8c748708613c989ad80a71 100644 (file)
@@ -147,7 +147,7 @@ sec_xdr_array(XDR *xdrs, uint8_t **addrp, u_int *sizep, u_int maxsize, u_int els
     for (i = 0; (i < c) && stat; i++) {
         if ((xdrs->x_op == XDR_DECODE) && sizeof_alloc)
             memset(obj, 0, elsize);
     for (i = 0; (i < c) && stat; i++) {
         if ((xdrs->x_op == XDR_DECODE) && sizeof_alloc)
             memset(obj, 0, elsize);
-        stat = (*elproc)(xdrs, target);
+        stat = (*elproc)(xdrs, target, 0);
         if ((xdrs->x_op == XDR_ENCODE) || !sizeof_alloc)
             target += elsize;
     }
         if ((xdrs->x_op == XDR_ENCODE) || !sizeof_alloc)
             target += elsize;
     }
index a66fb3726de44d0acd670bb8aad80175ed0695f8..ab5b4c40b59df3c2f32147721ea8ed6e4b55dda3 100644 (file)
@@ -121,7 +121,7 @@ sec_xdr_reference(XDR *xdrs, uint8_t **pp, u_int size, xdrproc_t proc)
                 break;
             }
 
                 break;
             }
 
-    stat = (*proc)(xdrs, loc);
+    stat = (*proc)(xdrs, loc, 0);
 
     if (xdrs->x_op == XDR_FREE) {
         sec_mem_free(xdrs, loc, size);
 
     if (xdrs->x_op == XDR_FREE) {
         sec_mem_free(xdrs, loc, size);
index a18bcd099d7259526e6e282c7970b39d1d4dd5b4..2788e5d2f2090411f8667af0293c472d65983b8f 100644 (file)
@@ -190,7 +190,7 @@ sec_xdr_sizeof_in(func, data)
 
     sec_xdr_arena_allocator_t size_alloc;
     sec_xdr_arena_init_size_alloc(&size_alloc, &x);
 
     sec_xdr_arena_allocator_t size_alloc;
     sec_xdr_arena_init_size_alloc(&size_alloc, &x);
-    stat = func(&x, data);
+    stat = func(&x, data, 0);
     if (x.x_private)
         free(x.x_private);
     return (stat == TRUE ? (unsigned) x.x_handy: 0);
     if (x.x_private)
         free(x.x_private);
     return (stat == TRUE ? (unsigned) x.x_handy: 0);
@@ -210,8 +210,8 @@ sec_xdr_sizeof_out(copy, size, func, data)
 
     sec_xdr_arena_allocator_t size_alloc;
     sec_xdr_arena_init_size_alloc(&size_alloc, &x);
 
     sec_xdr_arena_allocator_t size_alloc;
     sec_xdr_arena_init_size_alloc(&size_alloc, &x);
-    stat = func(&x, data);
+    stat = func(&x, data, 0);
     if (size_alloc.data)
         free(size_alloc.data);
     if (size_alloc.data)
         free(size_alloc.data);
-    return (stat == TRUE ? (unsigned long)size_alloc.offset : 0);
+    return (stat == TRUE ? (u_int)size_alloc.offset : 0);
 }
 }
index b2c610876175ae9a2f21ce3f32740a7986e6e0bf..ed408560b0e6aae05a70cceb9534690363ceb473 100644 (file)
@@ -55,11 +55,11 @@ public:
 protected:
     template <class T>
     T *at(off_t offset)                { return LowLevelMemoryUtilities::increment<T>(this, offset); }
 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); }
+    void *at(off_t offset)     { return LowLevelMemoryUtilities::increment(this, (ptrdiff_t)offset); }
        
     template <class T>
     const T *at(off_t offset) const { return LowLevelMemoryUtilities::increment<T>(this, offset); }
        
     template <class T>
     const T *at(off_t offset) const { return LowLevelMemoryUtilities::increment<T>(this, offset); }
-    const void *at(off_t offset) const { return LowLevelMemoryUtilities::increment(this, offset); }
+    const void *at(off_t offset) const { return LowLevelMemoryUtilities::increment(this, (ptrdiff_t)offset); }
 };
 
 
 };
 
 
index cf4aa25c8bba90088887faf4235381b4a3a88b96..c0dd89b253731092de7e41b04ae4e0de6dbed1d8 100644 (file)
@@ -180,7 +180,7 @@ Port ClientSession::findSecurityd()
        }
 
     secdebug("SSclnt", "Locating %s", mContactName);
        }
 
     secdebug("SSclnt", "Locating %s", mContactName);
-    Port serverPort = Bootstrap().lookup(mContactName);
+    Port serverPort = Bootstrap().lookup2(mContactName);
        secdebug("SSclnt", "contacting %s at port %d (version %d)",
                mContactName, serverPort.port(), SSPROTOVERSION);
        return serverPort;
        secdebug("SSclnt", "contacting %s at port %d (version %d)",
                mContactName, serverPort.port(), SSPROTOVERSION);
        return serverPort;
index 06293010e09eb1b1f0ffc763d587dcee40935774..c4f1e2191628c9809e8a481b279cc6010eea0c13 100644 (file)
@@ -196,7 +196,12 @@ public:
     void lockAll(bool forSleep);
     void unlock(DbHandle db);
     void unlock(DbHandle db, const CssmData &passPhrase);
     void lockAll(bool forSleep);
     void unlock(DbHandle db);
     void unlock(DbHandle db, const CssmData &passPhrase);
+    void stashDb(DbHandle db);
+    void stashDbCheck(DbHandle db);
     bool isLocked(DbHandle db);
     bool isLocked(DbHandle db);
+    void verifyKeyStorePassphrase(uint32_t retries);
+    void resetKeyStorePassphrase(const CssmData &passphrase);
+    void changeKeyStorePassphrase();
        
 public:
        //
        
 public:
        //
index 583111f4470e945443a336ba3dc050702c8d31cc..e0ec2919f2e89db91cf285acf58992c61c4ca292 100644 (file)
@@ -28,7 +28,6 @@
 #include "sstransit.h"
 #include <security_cdsa_client/cspclient.h>
 #include <security_utilities/mach++.h>
 #include "sstransit.h"
 #include <security_cdsa_client/cspclient.h>
 #include <security_utilities/mach++.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 
 namespace Security {
 namespace SecurityServer {
 
 namespace Security {
 namespace SecurityServer {
index 5c86c5193125b41dfda0acacda2ba26b02479b6f..34671e948e09a65c32661ed7a437f24d45c8d13c 100644 (file)
@@ -65,9 +65,12 @@ namespace SecurityServer {
 }
 
 // pass mandatory or optional CssmData arguments into an IPC call
 }
 
 // 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)
+#define DATA(arg)                      arg.data(), (mach_msg_type_number_t)(arg.length())
+#define OPTIONALDATA(arg)      (arg ? arg->data() : NULL), (mach_msg_type_number_t)(arg ? arg->length() : 0)
 
 
+// pass mandatory DataOutput argument into an IPC call
+#define DATA_OUT(arg)                   arg.data(), arg.length()
+    
 // 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
 // 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
index 063193039c20f748581af0131938f0b64293a8f5..f4527ff8f90edb991f5c9289cf4bdb11dcdf1fe9 100644 (file)
@@ -49,7 +49,6 @@
 //
 #include "sstransit.h"
 #include <security_cdsa_client/cspclient.h>
 //
 #include "sstransit.h"
 #include <security_cdsa_client/cspclient.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 
 #include <securityd_client/xdr_auth.h>
 #include <securityd_client/xdr_cssm.h>
 
 #include <securityd_client/xdr_auth.h>
 #include <securityd_client/xdr_cssm.h>
@@ -104,7 +103,7 @@ RecordHandle ClientSession::insertRecord(DbHandle db,
        RecordHandle record;
        CopyIn db_record_attr_data(attributes, reinterpret_cast<xdrproc_t>(xdr_CSSM_DB_RECORD_ATTRIBUTE_DATA));
     
        RecordHandle record;
        CopyIn db_record_attr_data(attributes, reinterpret_cast<xdrproc_t>(xdr_CSSM_DB_RECORD_ATTRIBUTE_DATA));
     
-       IPC(ucsp_client_insertRecord(UCSP_ARGS, db, recordType, db_record_attr_data.data(), db_record_attr_data.length(), OPTIONALDATA(data), &record));
+       IPC(ucsp_client_insertRecord(UCSP_ARGS, db, recordType, db_record_attr_data.data(), (mach_msg_type_number_t)db_record_attr_data.length(), OPTIONALDATA(data), &record));
     
        return record;
 }
     
        return record;
 }
@@ -124,10 +123,11 @@ void ClientSession::modifyRecord(DbHandle db, RecordHandle &record,
 {
        CopyIn db_record_attr_data(attributes, reinterpret_cast<xdrproc_t>(xdr_CSSM_DB_RECORD_ATTRIBUTE_DATA));
     
 {
        CopyIn db_record_attr_data(attributes, reinterpret_cast<xdrproc_t>(xdr_CSSM_DB_RECORD_ATTRIBUTE_DATA));
     
-       IPC(ucsp_client_modifyRecord(UCSP_ARGS, db, &record, recordType, db_record_attr_data.data(), db_record_attr_data.length(),
+       IPC(ucsp_client_modifyRecord(UCSP_ARGS, db, &record, recordType, db_record_attr_data.data(), (mach_msg_type_number_t)db_record_attr_data.length(),
         data != NULL, OPTIONALDATA(data), modifyMode));
 }
 
         data != NULL, OPTIONALDATA(data), modifyMode));
 }
 
+static
 void copy_back_attribute_return_data(CssmDbRecordAttributeData *dest_attrs, CssmDbRecordAttributeData *source_attrs, Allocator &returnAllocator)
 {
        assert(dest_attrs->size() == source_attrs->size());
 void copy_back_attribute_return_data(CssmDbRecordAttributeData *dest_attrs, CssmDbRecordAttributeData *source_attrs, Allocator &returnAllocator)
 {
        assert(dest_attrs->size() == source_attrs->size());
@@ -289,7 +289,7 @@ void ClientSession::commitDbForSync(DbHandle srcDb, DbHandle cloneDb,
                                     CssmData &blob, Allocator &alloc)
 {
     DataOutput outBlob(blob, alloc);
                                     CssmData &blob, Allocator &alloc)
 {
     DataOutput outBlob(blob, alloc);
-    IPC(ucsp_client_commitDbForSync(UCSP_ARGS, srcDb, cloneDb, DATA(outBlob)));
+    IPC(ucsp_client_commitDbForSync(UCSP_ARGS, srcDb, cloneDb, DATA_OUT(outBlob)));
 }
 
 DbHandle ClientSession::decodeDb(const DLDbIdentifier &dbId,
 }
 
 DbHandle ClientSession::decodeDb(const DLDbIdentifier &dbId,
@@ -311,7 +311,7 @@ DbHandle ClientSession::decodeDb(const DLDbIdentifier &dbId,
 void ClientSession::encodeDb(DbHandle db, CssmData &blob, Allocator &alloc)
 {
        DataOutput outBlob(blob, alloc);
 void ClientSession::encodeDb(DbHandle db, CssmData &blob, Allocator &alloc)
 {
        DataOutput outBlob(blob, alloc);
-       IPC(ucsp_client_encodeDb(UCSP_ARGS, db, DATA(outBlob)));
+       IPC(ucsp_client_encodeDb(UCSP_ARGS, db, DATA_OUT(outBlob)));
 }
 
 void ClientSession::setDbParameters(DbHandle db, const DBParameters &params)
 }
 
 void ClientSession::setDbParameters(DbHandle db, const DBParameters &params)
@@ -352,6 +352,16 @@ void ClientSession::unlock(DbHandle db, const CssmData &passphrase)
        IPC(ucsp_client_unlockDbWithPassphrase(UCSP_ARGS, db, DATA(passphrase)));
 }
 
        IPC(ucsp_client_unlockDbWithPassphrase(UCSP_ARGS, db, DATA(passphrase)));
 }
 
+void ClientSession::stashDb(DbHandle db)
+{
+    IPC(ucsp_client_stashDb(UCSP_ARGS, db));
+}
+
+void ClientSession::stashDbCheck(DbHandle db)
+{
+    IPC(ucsp_client_stashDbCheck(UCSP_ARGS, db));
+}
+    
 bool ClientSession::isLocked(DbHandle db)
 {
     boolean_t locked;
 bool ClientSession::isLocked(DbHandle db)
 {
     boolean_t locked;
@@ -359,6 +369,20 @@ bool ClientSession::isLocked(DbHandle db)
     return locked;
 }
 
     return locked;
 }
 
+void ClientSession::verifyKeyStorePassphrase(uint32_t retries)
+{
+    IPC(ucsp_client_verifyKeyStorePassphrase(UCSP_ARGS, retries));
+}
+
+void ClientSession::resetKeyStorePassphrase(const CssmData &passphrase)
+{
+    IPC(ucsp_client_resetKeyStorePassphrase(UCSP_ARGS, DATA(passphrase)));
+}
+
+void ClientSession::changeKeyStorePassphrase()
+{
+    IPC(ucsp_client_changeKeyStorePassphrase(UCSP_ARGS));
+}
 
 //
 // Key control
 
 //
 // Key control
@@ -387,7 +411,7 @@ KeyHandle ClientSession::decodeKey(DbHandle db, const CssmData &blob, CssmKey::H
        void *keyHeaderData;
        mach_msg_type_number_t keyHeaderDataLength;
 
        void *keyHeaderData;
        mach_msg_type_number_t keyHeaderDataLength;
 
-       IPC(ucsp_client_decodeKey(UCSP_ARGS, &key, &keyHeaderData, &keyHeaderDataLength, db, blob.data(), blob.length()));
+       IPC(ucsp_client_decodeKey(UCSP_ARGS, &key, &keyHeaderData, &keyHeaderDataLength, db, blob.data(), (mach_msg_type_number_t)blob.length()));
 
        CopyOut wrappedKeyHeaderXDR(keyHeaderData, keyHeaderDataLength + sizeof(CSSM_KEYHEADER), reinterpret_cast<xdrproc_t>(xdr_CSSM_KEYHEADER_PTR), true);
        header = *static_cast<CssmKey::Header *>(reinterpret_cast<CSSM_KEYHEADER*>(wrappedKeyHeaderXDR.data()));
 
        CopyOut wrappedKeyHeaderXDR(keyHeaderData, keyHeaderDataLength + sizeof(CSSM_KEYHEADER), reinterpret_cast<xdrproc_t>(xdr_CSSM_KEYHEADER_PTR), true);
        header = *static_cast<CssmKey::Header *>(reinterpret_cast<CSSM_KEYHEADER*>(wrappedKeyHeaderXDR.data()));
@@ -400,7 +424,7 @@ void ClientSession::recodeKey(DbHandle oldDb, KeyHandle key, DbHandle newDb,
        CssmData &blob)
 {
        DataOutput outBlob(blob, returnAllocator);
        CssmData &blob)
 {
        DataOutput outBlob(blob, returnAllocator);
-       IPC(ucsp_client_recodeKey(UCSP_ARGS, oldDb, key, newDb, DATA(outBlob)));
+       IPC(ucsp_client_recodeKey(UCSP_ARGS, oldDb, key, newDb, DATA_OUT(outBlob)));
 }
 
 void ClientSession::releaseKey(KeyHandle key)
 }
 
 void ClientSession::releaseKey(KeyHandle key)
@@ -439,7 +463,7 @@ void ClientSession::generateRandom(const Security::Context &context, CssmData &d
        CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
        DataOutput result(data, alloc);
     
        CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
        DataOutput result(data, alloc);
     
-       IPC(ucsp_client_generateRandom(UCSP_ARGS, 0, ctxcopy.data(), ctxcopy.length(), DATA(result)));
+       IPC(ucsp_client_generateRandom(UCSP_ARGS, 0, ctxcopy.data(), ctxcopy.length(), DATA_OUT(result)));
 }
 
 
 }
 
 
@@ -453,7 +477,7 @@ void ClientSession::generateSignature(const Context &context, KeyHandle key,
        DataOutput sig(signature, alloc);
     
        IPCKEY(ucsp_client_generateSignature(UCSP_ARGS, ctxcopy.data(), ctxcopy.length(), key, signOnlyAlgorithm,
        DataOutput sig(signature, alloc);
     
        IPCKEY(ucsp_client_generateSignature(UCSP_ARGS, ctxcopy.data(), ctxcopy.length(), key, signOnlyAlgorithm,
-               DATA(data), DATA(sig)),
+               DATA(data), DATA_OUT(sig)),
                   key, CSSM_ACL_AUTHORIZATION_SIGN);
 }
 
                   key, CSSM_ACL_AUTHORIZATION_SIGN);
 }
 
@@ -472,7 +496,7 @@ void ClientSession::generateMac(const Context &context, KeyHandle key,
        CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
        DataOutput sig(signature, alloc);
     
        CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
        DataOutput sig(signature, alloc);
     
-       IPCKEY(ucsp_client_generateMac(UCSP_ARGS, ctxcopy.data(), ctxcopy.length(), key, DATA(data), DATA(sig)),
+       IPCKEY(ucsp_client_generateMac(UCSP_ARGS, ctxcopy.data(), ctxcopy.length(), key, DATA(data), DATA_OUT(sig)),
                key, CSSM_ACL_AUTHORIZATION_MAC);
 }
 
                key, CSSM_ACL_AUTHORIZATION_MAC);
 }
 
@@ -496,7 +520,7 @@ void ClientSession::encrypt(const Context &context, KeyHandle key,
 {
        CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
        DataOutput cipherOut(cipher, alloc);
 {
        CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
        DataOutput cipherOut(cipher, alloc);
-       IPCKEY(ucsp_client_encrypt(UCSP_ARGS, ctxcopy.data(), ctxcopy.length(), key, DATA(clear), DATA(cipherOut)),
+       IPCKEY(ucsp_client_encrypt(UCSP_ARGS, ctxcopy.data(), ctxcopy.length(), key, DATA(clear), DATA_OUT(cipherOut)),
                key, CSSM_ACL_AUTHORIZATION_ENCRYPT);
 }
 
                key, CSSM_ACL_AUTHORIZATION_ENCRYPT);
 }
 
@@ -506,7 +530,7 @@ void ClientSession::decrypt(const Context &context, KeyHandle key,
        CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
        DataOutput clearOut(clear, alloc);
     
        CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
        DataOutput clearOut(clear, alloc);
     
-       IPCKEY(ucsp_client_decrypt(UCSP_ARGS, ctxcopy.data(), ctxcopy.length(), key, DATA(cipher), DATA(clearOut)),
+       IPCKEY(ucsp_client_decrypt(UCSP_ARGS, ctxcopy.data(), ctxcopy.length(), key, DATA(cipher), DATA_OUT(clearOut)),
                key, CSSM_ACL_AUTHORIZATION_DECRYPT);
 }
 
                key, CSSM_ACL_AUTHORIZATION_DECRYPT);
 }
 
@@ -589,7 +613,7 @@ void ClientSession::deriveKey(DbHandle db, const Context &context, KeyHandle bas
                        
                        IPCKEY(ucsp_client_deriveKey(UCSP_ARGS, db, ctxcopy.data(), ctxcopy.length(), baseKey,
                                creds.data(), creds.length(), proto.data(), proto.length(), 
                        
                        IPCKEY(ucsp_client_deriveKey(UCSP_ARGS, db, ctxcopy.data(), ctxcopy.length(), baseKey,
                                creds.data(), creds.length(), proto.data(), proto.length(), 
-                               inParam.data(), inParam.length(), DATA(paramOutput),
+                               inParam.data(), inParam.length(), DATA_OUT(paramOutput),
                                usage, attrs, &newKey, &keyHeaderData, &keyHeaderDataLength),
                                baseKey, CSSM_ACL_AUTHORIZATION_DERIVE);
                        
                                usage, attrs, &newKey, &keyHeaderData, &keyHeaderDataLength),
                                baseKey, CSSM_ACL_AUTHORIZATION_DERIVE);
                        
@@ -613,7 +637,7 @@ void ClientSession::deriveKey(DbHandle db, const Context &context, KeyHandle bas
 void ClientSession::getKeyDigest(KeyHandle key, CssmData &digest, Allocator &allocator)
 {
        DataOutput dig(digest, allocator);
 void ClientSession::getKeyDigest(KeyHandle key, CssmData &digest, Allocator &allocator)
 {
        DataOutput dig(digest, allocator);
-       IPC(ucsp_client_getKeyDigest(UCSP_ARGS, key, DATA(dig)));
+       IPC(ucsp_client_getKeyDigest(UCSP_ARGS, key, DATA_OUT(dig)));
 }
 
 
 }
 
 
@@ -661,7 +685,7 @@ void ClientSession::unwrapKey(DbHandle db, const Context &context, KeyHandle key
 
        IPCKEY(ucsp_client_unwrapKey(UCSP_ARGS, db, ctxcopy.data(), ctxcopy.length(), key,
                creds.data(), creds.length(), proto.data(), proto.length(),
 
        IPCKEY(ucsp_client_unwrapKey(UCSP_ARGS, db, ctxcopy.data(), ctxcopy.length(), key,
                creds.data(), creds.length(), proto.data(), proto.length(),
-               publicKey, wrappedKeyXDR.data(), wrappedKeyXDR.length(), usage, attr, DATA(descriptor),
+               publicKey, wrappedKeyXDR.data(), wrappedKeyXDR.length(), usage, attr, DATA_OUT(descriptor),
         &newKey, &keyHeaderData, &keyHeaderDataLength),
                key, CSSM_ACL_AUTHORIZATION_DECRYPT);
 
         &newKey, &keyHeaderData, &keyHeaderDataLength),
                key, CSSM_ACL_AUTHORIZATION_DECRYPT);
 
@@ -933,7 +957,7 @@ void ClientSession::authorizationdbGet(const AuthorizationString rightname, Cssm
 {
        DataOutput definition(rightDefinition, alloc);
        activate();
 {
        DataOutput definition(rightDefinition, alloc);
        activate();
-       IPCSTART(ucsp_client_authorizationdbGet(UCSP_ARGS, rightname, DATA(definition)));
+       IPCSTART(ucsp_client_authorizationdbGet(UCSP_ARGS, rightname, DATA_OUT(definition)));
        if (rcode == CSSMERR_CSSM_NO_USER_INTERACTION)
          CssmError::throwMe(errAuthorizationInteractionNotAllowed);
        IPCEND_CHECK;
        if (rcode == CSSMERR_CSSM_NO_USER_INTERACTION)
          CssmError::throwMe(errAuthorizationInteractionNotAllowed);
        IPCEND_CHECK;
index 39208bd33eefd700d02e08358754d9a0b52dae3d..b04a69c3797962a45e534d36dd043cafb82acf3e 100644 (file)
@@ -39,7 +39,7 @@ xdr_AuthorizationItem(XDR *xdrs, AuthorizationItem *objp)
     if (xdrs->x_op == XDR_ENCODE) {
                if (objp->valueLength > (u_int)~0)
                        return (FALSE);
     if (xdrs->x_op == XDR_ENCODE) {
                if (objp->valueLength > (u_int)~0)
                        return (FALSE);
-               valueLength = objp->valueLength;
+               valueLength = (u_int)objp->valueLength;
     }
        
     if (!sec_xdr_bytes(xdrs, (uint8_t **)&objp->value, &valueLength, ~0))
     }
        
     if (!sec_xdr_bytes(xdrs, (uint8_t **)&objp->value, &valueLength, ~0))
index 107cdd08924fa4311173d8cc4cdda849299f5a2e..a7a8cc8b03688d9754bea3a0f71f5e35c137baa0 100644 (file)
@@ -66,7 +66,7 @@ bool_t xdr_CSSM_DATA(XDR *xdrs, CSSM_DATA *objp)
     if (xdrs->x_op == XDR_ENCODE) {
         if (objp->Length > (u_int)~0)
             return (FALSE);
     if (xdrs->x_op == XDR_ENCODE) {
         if (objp->Length > (u_int)~0)
             return (FALSE);
-        valueLength = objp->Length;
+        valueLength = (u_int)objp->Length;
     }
     if (!sec_xdr_bytes(xdrs, &objp->Data, &valueLength, ~0))
         return (FALSE);
     }
     if (!sec_xdr_bytes(xdrs, &objp->Data, &valueLength, ~0))
         return (FALSE);
@@ -127,7 +127,7 @@ bool_t xdr_CSSM_CRYPTO_DATA(XDR *xdrs, CSSM_CRYPTO_DATA *objp)
         CSSM_CALLBACK func = objp->Callback; 
         CSSM_DATA data;
         CSSM_RETURN err;
         CSSM_CALLBACK func = objp->Callback; 
         CSSM_DATA data;
         CSSM_RETURN err;
-        if (err = func(&data, objp->CallerCtx))
+        if ((err = func(&data, objp->CallerCtx)))
             return (FALSE); // XXX/cs meaningfully return err
         if (!xdr_CSSM_DATA(xdrs, &data))
             return (FALSE);
             return (FALSE); // XXX/cs meaningfully return err
         if (!xdr_CSSM_DATA(xdrs, &data))
             return (FALSE);
@@ -516,6 +516,7 @@ bool_t xdr_CSSM_DB_ATTRIBUTE_INFO(XDR *xdrs, CSSM_DB_ATTRIBUTE_INFO *objp)
     return (TRUE);
 }
 
     return (TRUE);
 }
 
+static
 bool_t xdr_CSSM_DATA_FLIPPED(XDR *xdrs, CSSM_DATA *objp)
 {
        bool_t size_alloc = sec_xdr_arena_size_allocator(xdrs);
 bool_t xdr_CSSM_DATA_FLIPPED(XDR *xdrs, CSSM_DATA *objp)
 {
        bool_t size_alloc = sec_xdr_arena_size_allocator(xdrs);
index 809192a54522ae1a111195ef5caa71c0d385f46f..65e0f604f6202146005564a38b0072b80bdd48f1 100644 (file)
@@ -50,8 +50,8 @@ class CopyIn {
 class CopyOut {
     public:
                // CSSM_DATA can be output only if empty, but also specify preallocated memory to use
 class CopyOut {
     public:
                // CSSM_DATA can be output only if empty, but also specify preallocated memory to use
-        CopyOut(void *copy, size_t size, xdrproc_t proc, bool dealloc = false, CSSM_DATA *in_out_data = NULL) : mLength(in_out_data?in_out_data->Length:0), mData(NULL), mInOutData(in_out_data), mDealloc(dealloc), mSource(copy), mSourceLen(size) {
-            if (copy && size && !::copyout(copy, size, proc, mInOutData ? reinterpret_cast<void**>(&mInOutData) : &mData, &mLength)) {
+        CopyOut(void *copy, size_t size, xdrproc_t proc, bool dealloc = false, CSSM_DATA *in_out_data = NULL) : mLength(in_out_data?(u_int)in_out_data->Length:0), mData(NULL), mInOutData(in_out_data), mDealloc(dealloc), mSource(copy), mSourceLen(size) {
+            if (copy && size && !::copyout(copy, (u_int)size, proc, mInOutData ? reinterpret_cast<void**>(&mInOutData) : &mData, &mLength)) {
                 if (mInOutData && mInOutData->Length) // DataOut behaviour: error back to user if likely related to amount of space passed in
                     CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
                 else
                 if (mInOutData && mInOutData->Length) // DataOut behaviour: error back to user if likely related to amount of space passed in
                     CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
                 else
index 1de521d21ca898695532cedc2fbb0f4bd83e5972..78cc19612085b26458bd0524c1a86dddb55b5e2b 100644 (file)
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB173146EA1D6000BF1F3 /* debug.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB173146EA1D6000BF1F3 /* debug.xcconfig */;
                        buildSettings = {
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/securityd_client;
                                SKIP_INSTALL = NO;
                        };
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/securityd_client;
                                SKIP_INSTALL = NO;
                        };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB175146EA1D6000BF1F3 /* release.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 182BB175146EA1D6000BF1F3 /* release.xcconfig */;
                        buildSettings = {
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/securityd_client;
                                SKIP_INSTALL = NO;
                        };
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/securityd_client;
                                SKIP_INSTALL = NO;
                        };
index 61857ec645778cedae80cc9a56d9a66ccc4e16be..a0fdaf110c3a0b4ab5c0b5541ec392083f7e7520 100644 (file)
@@ -109,7 +109,6 @@ routine lockAll(UCSP_PORTS; in forSleep: boolean_t);
 routine unlockDb(UCSP_PORTS; in db: IPCDbHandle);
 routine unlockDbWithPassphrase(UCSP_PORTS; in db: IPCDbHandle; in passPhrase: Data);
 routine isLocked(UCSP_PORTS; in db: IPCDbHandle; out locked: boolean_t);
 routine unlockDb(UCSP_PORTS; in db: IPCDbHandle);
 routine unlockDbWithPassphrase(UCSP_PORTS; in db: IPCDbHandle; in passPhrase: Data);
 routine isLocked(UCSP_PORTS; in db: IPCDbHandle; out locked: boolean_t);
-
        
 //
 // Key management
        
 //
 // Key management
@@ -329,3 +328,11 @@ routine verifyPrivileged(UCSP_PORTS);
 // The original verifyPrivileged is subject to a Mach service in the middle attack (6986198).
 //
 routine verifyPrivileged2(UCSP_PORTS; out originPort: mach_port_make_send_t);
 // The original verifyPrivileged is subject to a Mach service in the middle attack (6986198).
 //
 routine verifyPrivileged2(UCSP_PORTS; out originPort: mach_port_make_send_t);
+
+// Internal Database call additions
+routine stashDb(UCSP_PORTS; in db: IPCDbHandle);
+routine stashDbCheck(UCSP_PORTS; in db: IPCDbHandle);
+
+routine verifyKeyStorePassphrase(UCSP_PORTS; in retries: uint32_t);
+routine resetKeyStorePassphrase(UCSP_PORTS; in passPhrase: Data);
+routine changeKeyStorePassphrase(UCSP_PORTS);
diff --git a/regressions/README b/regressions/README
new file mode 100644 (file)
index 0000000..d69fef4
--- /dev/null
@@ -0,0 +1,207 @@
+regression test suite for security components.
+by Michael Brouwer
+
+
+GOALS
+=====
+
+The goals of this test setup are  to have something that required
+0 configuration and setup and allows developers to quickly write
+new standalone test cases.
+
+
+USAGE
+=====
+
+The tests are runnable from the top level Makefile by typing:
+    make test
+or individually from the command line or with gdb.  Tests will be
+built into a directory called build by default or into LOCAL_BUILD_DIR
+if you set that in your environment.
+
+
+DIRECTORY LAYOUT
+================
+
+Currently there are subdirectories for a number of different parts
+of the security stack.  Each directory contains some of the unit
+tests I've managed to find from radar and other places.
+
+The test programs output their results in a format called TAP.  This
+is described here:
+    http://search.cpan.org/~petdance/Test-Harness-2.46/lib/Test/Harness/TAP.pod
+Because of this we can use Perl's Test::Harness to run the tests
+and produce some nice looking output without the need to write an
+entire test harness.
+
+Tests can be written in C, C++ or Objective-C or perl (using
+Test::More in perl).
+
+
+WRITING TESTS
+=============
+
+To add a new test simply copy one of the existing ones and hack away.
+Any file with a main() function in it will be built into a test
+automatically by the top level Makefile (no configuration required).
+
+To use the testmore C "library" all you need to do is #include
+"testmore.h" in your test program.
+
+Then in your main function you must call:
+
+plan_tests(NUMTESTS) where NUMTESTS is the number of test cases you
+test program will run.  After that you can start writing tests.
+There are a couple of macros to help you get started:
+
+The following are ways to run an actual test case (as in they count
+towards the NUMTESTS number above):
+
+ok(EXPR, NAME)
+    Evaluate EXPR if it's true the test passes if false it fails.
+    The second argument is a descriptive name of the test for debugging
+    purposes.
+
+is(EXPR, VALUE, NAME)
+    Evaluate EXPR if it's equal to VALUE the test passes otherwise
+    it fails.  This is equivalent to ok(EXPR == VALUE, NAME) except
+    this produces nicer output in a failure case.
+    CAVEAT: Currently EXPR and VALUE must both be type int.
+
+isnt(EXPR, VALUE, NAME)
+    Opposite of is() above.
+    CAVEAT: Currently EXPR and VALUE must both be type int.
+
+cmp_ok(EXPR, OP, VALUE, NAME)
+    Succeeds if EXPR OP VALUE is true.  Produces a diagnostic if not.
+    CAVEAT: Currently EXPR and VALUE must both be type int.
+
+ok_status(EXPR, NAME)
+    Evaluate EXPR, if it's 0 the test passes otherwise print a
+    diagnostic with the name and number of the error returned.
+
+is_status(EXPR, VALUE, NAME)
+    Evaluate EXPR, if the error returned equals VALUE the test
+    passes, otherwise print a diagnostic with the expected and
+    actual error returned.
+
+ok_unix(EXPR, NAME)
+    Evaluate EXPR, if it's >= 0 the test passes otherwise print a
+    diagnostic with the name and number of the errno.
+
+is_unix(EXPR, VALUE, NAME)
+    Evaluate EXPR, if the errno set by it equals VALUE the test
+    passes, otherwise print a diagnostic with the expected and
+    actual errno.
+
+Finally if you somehow can't express the success or failure of a
+test using the macros above you can use pass(NAME) or fail(NAME)
+explicitly.  These are equivalent to ok(1, NAME) and ok(0, NAME)
+respectively.
+
+
+LEAKS
+=====
+
+If you want to check for leaks in your test you can #include
+"testleaks.h" in your program and call:
+
+ok_leaks(NAME)
+    Passes if there are no leaks in your program.
+
+is_leaks(VALUE, NAME)
+    Passes if there are exactly VALUE leaks in your program.  Useful
+    if you are calling code that is known to leak and you can't fix
+    it.  But you still want to make sure there are no new leaks in
+    your code.
+
+
+C++
+===
+
+For C++ programs you can #include "testcpp.h" which defines these
+additional macros:
+no_throw(EXPR, NAME)
+    Success if EXPR doesn't throw.
+
+does_throw(EXPR, NAME)
+    Success if EXPR does throw.
+
+is_throw(EXPR, CLASS, FUNC, VALUE, NAME)
+    Success if EXPR throws an exception of type CLASS and CLASS.FUNC == VALUE.
+    Example usage:
+    is_throw(CssmError::throwMe(42), CssmError, osStatus(), 42, "throwMe(42)");
+
+
+TODO and SKIP
+=============
+
+Sometimes you write a test case that is known to fail (because you
+found a bug).  Rather than commenting out that test case you should
+put it inside a TODO block.  This will cause the test to run but
+the failure will not be reported as an error.  When the test starts
+passing (presumably because someone fixed the bug) you can comment
+out the TODO block and leave the test in place.
+
+The syntax for doing this looks like so:
+
+    TODO: {
+        todo("<rdar://problem/4000000> ER: AAPL target: $4,000,000/share");
+
+        cmp_ok(apple_stock_price(), >=, 4000000, "stock over 4M");
+    }
+
+Sometimes you don't want to run a particular test case or set of
+test cases because something in the environment is missing or you
+are running on a different version of the OS than the test was
+designed for.  To achieve this you can use a SKIP block.
+
+The syntax for a SKIP block looks like so:
+
+    SKIP: {
+        skip("only runs on Tiger and later", 4, os_version() >= os_tiger);
+
+        ok(tiger_test1(), "test1");
+        ok(tiger_test2(), "test2");
+        ok(tiger_test3(), "test3");
+        ok(tiger_test4(), "test4");
+    }
+
+How it works is like so:  If the third argument to skip evaluates
+to false it breaks out of the SKIP block and reports N tests as
+being skipped (where N is the second argument to skip)  The reason
+for the test being skipped is given as the first argument to skip.
+
+
+Utility Functions
+=================
+
+Anyone writing tests can add new utility functions.  Currently there
+is a pair called tests_begin and tests_end.  To get them
+#include "testenv.h". Calling them doesn't count as running a test
+case, unless you wrap them in an ok() macro.  tests_begin creates
+a unique dir in /tmp and sets HOME in the environment to that dir.
+tests_end cleans up the mess that tests_begin made.
+
+When writing your own utility functions you will probably want to use
+the setup("task") macro so that any uses of ok() and other macros
+don't count as actual test cases run, but do report errors when they
+fail.   Here is an example of how tests_end() does this:
+
+int
+tests_end(int result)
+{
+        setup("tests_end");
+        /* Restore previous cwd and remove scratch dir. */
+        return (ok_unix(fchdir(current_dir), "fchdir") &&
+                ok_unix(close(current_dir), "close") &&
+                ok_unix(rmdir_recursive(scratch_dir), "rmdir_recursive"));
+}
+
+Setup cases all tests unil the end of the current funtion to not count
+against your test cases test count and they output nothing if they
+succeed.
+
+There is also a simple utility header called "testcssm.h" which
+currently defines cssm_attach and cssm_detach functions for loading
+and initializing cssm and loading a module.
diff --git a/regressions/inc/IPC/Run3.pm b/regressions/inc/IPC/Run3.pm
new file mode 100644 (file)
index 0000000..c011d97
--- /dev/null
@@ -0,0 +1,666 @@
+package IPC::Run3;
+
+$VERSION = 0.010;
+
+=head1 NAME
+
+IPC::Run3 - Run a subprocess in batch mode (a la system) on Unix, Win32, etc.
+
+=head1 SYNOPSIS
+
+    use IPC::Run3;    ## Exports run3() by default
+    use IPC::Run3 (); ## Don't pollute
+
+    run3 \@cmd, \$in, \$out, \$err;
+    run3 \@cmd, \@in, \&out, \$err;
+
+=head1 DESCRIPTION
+
+This module allows you to run a subprocess and redirect stdin, stdout,
+and/or stderr to files and perl data structures.  It aims to satisfy 99%
+of the need for using system()/qx``/open3() with a simple, extremely
+Perlish API and none of the bloat and rarely used features of IPC::Run.
+
+Speed (of Perl code; which is often much slower than the kind of
+buffered I/O that this module uses to spool input to and output from the
+child command), simplicity, and portability are paramount.  Disk space
+is not.
+
+Note that passing in \undef explicitly redirects the associated file
+descriptor for STDIN, STDOUT, or STDERR from or to the local equivalent
+of /dev/null (this does I<not> pass a closed filehandle).  Passing in
+"undef" (or not passing a redirection) allows the child to inherit the
+corresponding STDIN, STDOUT, or STDERR from the parent.
+
+Because the redirects come last, this allows STDOUT and STDERR to
+default to the parent's by just not specifying them; a common use
+case.
+
+B<Note>: This means that:
+
+    run3 \@cmd, undef, \$out;   ## Pass on parent's STDIN
+
+B<does not close the child's STDIN>, it passes on the parent's.  Use
+
+    run3 \@cmd, \undef, \$out;  ## Close child's STDIN
+
+for that.  It's not ideal, but it does work.
+
+If the exact same value is passed for $stdout and $stderr, then
+the child will write both to the same filehandle.  In general, this
+means that
+
+    run3 \@cmd, \undef, "foo.txt", "foo.txt";
+    run3 \@cmd, \undef, \$both, \$both;
+
+will DWYM and pass a single file handle to the child for both
+STDOUT and STDERR, collecting all into $both.
+
+=head1 DEBUGGING
+
+To enable debugging use the IPCRUN3DEBUG environment variable to
+a non-zero integer value:
+
+    $ IPCRUN3DEBUG=1 myapp
+
+.
+
+=head1 PROFILING
+
+To enable profiling, set IPCRUN3PROFILE to a number to enable
+emitting profile information to STDERR (1 to get timestamps,
+2 to get a summary report at the END of the program,
+3 to get mini reports after each run) or to a filename to
+emit raw data to a file for later analysis.
+
+=head1 COMPARISON
+
+Here's how it stacks up to existing APIs:
+
+=over
+
+=item compared to system(), qx'', open "...|", open "|...":
+
+=over
+
+=item + redirects more than one file descriptor
+
+=item + returns TRUE on success, FALSE on failure
+
+=item + throws an error if problems occur in the parent process (or the
+pre-exec child)
+
+=item + allows a very perlish interface to perl data structures and
+subroutines
+
+=item + allows 1 word invocations to avoid the shell easily:
+
+    run3 ["foo"];  ## does not invoke shell
+
+=item - does not return the exit code, leaves it in $?
+
+=back
+
+=item compared to open2(), open3():
+
+=over
+
+=item + No lengthy, error prone polling / select loop needed
+
+=item + Hides OS dependancies
+
+=item + Allows SCALAR, ARRAY, and CODE references to source and sink I/O
+
+=item + I/O parameter order is like open3()  (not like open2()).
+
+=item - Does not allow interaction with the subprocess
+
+=back
+
+=item compared to IPC::Run::run():
+
+=over
+
+=item + Smaller, lower overhead, simpler, more portable
+
+=item + No select() loop portability issues
+
+=item + Does not fall prey to Perl closure leaks
+
+=item - Does not allow interaction with the subprocess (which
+IPC::Run::run() allows by redirecting subroutines).
+
+=item - Lacks many features of IPC::Run::run() (filters, pipes,
+redirects, pty support).
+
+=back
+
+=back
+
+=cut
+
+@EXPORT = qw( run3 );
+%EXPORT_TAGS = ( all => \@EXPORT );
+@ISA = qw( Exporter );
+use Exporter;
+
+use strict;
+use constant debugging => $ENV{IPCRUN3DEBUG} || $ENV{IPCRUNDEBUG} || 0;
+use constant profiling => $ENV{IPCRUN3PROFILE} || $ENV{IPCRUNPROFILE} || 0;
+use constant is_win32  => 0 <= index $^O, "Win32";
+
+BEGIN {
+   if ( is_win32 ) {
+      eval "use Win32 qw( GetOSName ); 1" or die $@;
+   }
+}
+
+#use constant is_win2k => is_win32 && GetOSName() =~ /Win2000/i;
+#use constant is_winXP => is_win32 && GetOSName() =~ /WinXP/i;
+
+use Carp qw( croak );
+use File::Temp qw( tempfile );
+use UNIVERSAL qw( isa );
+use POSIX qw( dup dup2 );
+
+## We cache the handles of our temp files in order to
+## keep from having to incur the (largish) overhead of File::Temp
+my %fh_cache;
+
+my $profiler;
+
+sub _profiler { $profiler } ## test suite access
+
+BEGIN {
+    if ( profiling ) {
+        eval "use Time::HiRes qw( gettimeofday ); 1" or die $@;
+        if ( $ENV{IPCRUN3PROFILE} =~ /\A\d+\z/ ) {
+            require IPC::Run3::ProfPP;
+            $profiler = IPC::Run3::ProfPP->new(
+                Level => $ENV{IPCRUN3PROFILE},
+            );
+        }
+        else {
+            my ( $dest, undef, $class ) =
+               reverse split /(=)/, $ENV{IPCRUN3PROFILE}, 2;
+            $class = "IPC::Run3::ProfLogger"
+                unless defined $class && length $class;
+            unless ( eval "require $class" ) {
+                my $x = $@;
+                $class = "IPC::Run3::$class";
+                eval "require IPC::Run3::$class" or die $x;
+            }
+            $profiler = $class->new(
+                Destination => $dest,
+            );
+        }
+        $profiler->app_call( [ $0, @ARGV ], scalar gettimeofday() );
+    }
+}
+
+
+END {
+    $profiler->app_exit( scalar gettimeofday() ) if profiling;
+}
+
+
+sub _spool_data_to_child {
+    my ( $type, $source, $binmode_it ) = @_;
+
+    ## If undef (not \undef) passed, they want the child to inherit
+    ## the parent's STDIN.
+    return undef unless defined $source;
+    warn "binmode()ing STDIN\n" if is_win32 && debugging && $binmode_it;
+
+    my $fh;
+    if ( ! $type ) {
+        local *FH;  ## Do this the backcompat way
+        open FH, "<$source" or croak "$!: $source";
+        $fh = *FH{IO};
+        if ( is_win32 ) {
+            binmode ":raw"; ## Remove all layers
+            binmode ":crlf" unless $binmode_it;
+        }
+        warn "run3(): feeding file '$source' to child STDIN\n"
+            if debugging >= 2;
+    }
+    elsif ( $type eq "FH" ) {
+        $fh = $source;
+        warn "run3(): feeding filehandle '$source' to child STDIN\n"
+            if debugging >= 2;
+    }
+    else {
+        $fh = $fh_cache{in} ||= tempfile;
+        truncate $fh, 0;
+        seek $fh, 0, 0;
+        if ( is_win32 ) {
+            binmode $fh, ":raw"; ## Remove any previous layers
+            binmode $fh, ":crlf" unless $binmode_it;
+        }
+        my $seekit;
+        if ( $type eq "SCALAR" ) {
+
+            ## When the run3()'s caller asks to feed an empty file
+            ## to the child's stdin, we want to pass a live file
+            ## descriptor to an empty file (like /dev/null) so that
+            ## they don't get surprised by invalid fd errors and get
+            ## normal EOF behaviors.
+            return $fh unless defined $$source;  ## \undef passed
+
+            warn "run3(): feeding SCALAR to child STDIN",
+                debugging >= 3
+                   ? ( ": '", $$source, "' (", length $$source, " chars)" )
+                   : (),
+                "\n"
+                if debugging >= 2;
+
+            $seekit = length $$source;
+            print $fh $$source or die "$! writing to temp file";
+
+        }
+        elsif ( $type eq "ARRAY" ) {
+            warn "run3(): feeding ARRAY to child STDIN",
+                debugging >= 3 ? ( ": '", @$source, "'" ) : (),
+                "\n"
+            if debugging >= 2;
+
+            print $fh @$source or die "$! writing to temp file";
+            $seekit = grep length, @$source;
+        }
+        elsif ( $type eq "CODE" ) {
+            warn "run3(): feeding output of CODE ref '$source' to child STDIN\n"
+                if debugging >= 2;
+            my $parms = [];  ## TODO: get these from $options
+            while (1) {
+                my $data = $source->( @$parms );
+                last unless defined $data;
+                print $fh $data or die "$! writing to temp file";
+                $seekit = length $data;
+            }
+        }
+
+        seek $fh, 0, 0 or croak "$! seeking on temp file for child's stdin"
+            if $seekit;
+    }
+
+    croak "run3() can't redirect $type to child stdin"
+        unless defined $fh;
+
+    return $fh;
+}
+
+
+sub _fh_for_child_output {
+    my ( $what, $type, $dest, $binmode_it ) = @_;
+
+    my $fh;
+    if ( $type eq "SCALAR" && $dest == \undef ) {
+        warn "run3(): redirecting child $what to oblivion\n"
+            if debugging >= 2;
+
+        $fh = $fh_cache{nul} ||= do {
+            local *FH;
+            open FH, ">" . File::Spec->devnull;
+            *FH{IO};
+        };
+    }
+    elsif ( !$type ) {
+        warn "run3(): feeding child $what to file '$dest'\n"
+            if debugging >= 2;
+
+        local *FH;
+        open FH, ">$dest" or croak "$!: $dest";
+        $fh = *FH{IO};
+    }
+    else {
+        warn "run3(): capturing child $what\n"
+            if debugging >= 2;
+
+        $fh = $fh_cache{$what} ||= tempfile;
+        seek $fh, 0, 0;
+        truncate $fh, 0;
+    }
+
+    if ( is_win32 ) {
+        warn "binmode()ing $what\n" if debugging && $binmode_it;
+        binmode $fh, ":raw";
+        binmode $fh, ":crlf" unless $binmode_it;
+    }
+    return $fh;
+}
+
+
+sub _read_child_output_fh {
+    my ( $what, $type, $dest, $fh, $options ) = @_;
+
+    return if $type eq "SCALAR" && $dest == \undef;
+
+    seek $fh, 0, 0 or croak "$! seeking on temp file for child $what";
+
+    if ( $type eq "SCALAR" ) {
+        warn "run3(): reading child $what to SCALAR\n"
+            if debugging >= 3;
+
+        ## two read()s are used instead of 1 so that the first will be
+        ## logged even it reads 0 bytes; the second won't.
+        my $count = read $fh, $$dest, 10_000;
+        while (1) {
+            croak "$! reading child $what from temp file"
+                unless defined $count;
+
+            last unless $count;
+
+            warn "run3(): read $count bytes from child $what",
+                debugging >= 3 ? ( ": '", substr( $$dest, -$count ), "'" ) : (),
+                "\n"
+                if debugging >= 2;
+
+            $count = read $fh, $$dest, 10_000, length $$dest;
+        }
+    }
+    elsif ( $type eq "ARRAY" ) {
+        @$dest = <$fh>;
+        if ( debugging >= 2 ) {
+            my $count = 0;
+            $count += length for @$dest;
+            warn
+                "run3(): read ",
+                scalar @$dest,
+                " records, $count bytes from child $what",
+                debugging >= 3 ? ( ": '", @$dest, "'" ) : (),
+                "\n";
+        }
+    }
+    elsif ( $type eq "CODE" ) {
+        warn "run3(): capturing child $what to CODE ref\n"
+            if debugging >= 3;
+
+        local $_;
+        while ( <$fh> ) {
+            warn
+                "run3(): read ",
+                length,
+                " bytes from child $what",
+                debugging >= 3 ? ( ": '", $_, "'" ) : (),
+                "\n"
+                if debugging >= 2;
+
+            $dest->( $_ );
+        }
+    }
+    else {
+        croak "run3() can't redirect child $what to a $type";
+    }
+
+#    close $fh;
+}
+
+
+sub _type {
+    my ( $redir ) = @_;
+    return "FH" if isa $redir, "IO::Handle";
+    my $type = ref $redir;
+    return $type eq "GLOB" ? "FH" : $type;
+}
+
+
+sub _max_fd {
+    my $fd = dup(0);
+    POSIX::close $fd;
+    return $fd;
+}
+
+my $run_call_time;
+my $sys_call_time;
+my $sys_exit_time;
+
+sub run3 {
+    $run_call_time = gettimeofday() if profiling;
+
+    my $options = @_ && ref $_[-1] eq "HASH" ? pop : {};
+
+    my ( $cmd, $stdin, $stdout, $stderr ) = @_;
+
+    print STDERR "run3(): running ", 
+       join( " ", map "'$_'", ref $cmd ? @$cmd : $cmd ), 
+       "\n"
+       if debugging;
+
+    if ( ref $cmd ) {
+        croak "run3(): empty command"     unless @$cmd;
+        croak "run3(): undefined command" unless defined $cmd->[0];
+        croak "run3(): command name ('')" unless length  $cmd->[0];
+    }
+    else {
+        croak "run3(): missing command" unless @_;
+        croak "run3(): undefined command" unless defined $cmd;
+        croak "run3(): command ('')" unless length  $cmd;
+    }
+
+    my $in_type  = _type $stdin;
+    my $out_type = _type $stdout;
+    my $err_type = _type $stderr;
+
+    ## This routine procedes in stages so that a failure in an early
+    ## stage prevents later stages from running, and thus from needing
+    ## cleanup.
+
+    my $in_fh  = _spool_data_to_child $in_type, $stdin,
+        $options->{binmode_stdin} if defined $stdin;
+
+    my $out_fh = _fh_for_child_output "stdout", $out_type, $stdout,
+        $options->{binmode_stdout} if defined $stdout;
+
+    my $tie_err_to_out =
+        defined $stderr && defined $stdout && $stderr eq $stdout;
+
+    my $err_fh = $tie_err_to_out
+        ? $out_fh
+        : _fh_for_child_output "stderr", $err_type, $stderr,
+            $options->{binmode_stderr} if defined $stderr;
+
+    ## this should make perl close these on exceptions
+    local *STDIN_SAVE;
+    local *STDOUT_SAVE;
+    local *STDERR_SAVE;
+
+    my $saved_fd0 = dup( 0 ) if defined $in_fh;
+
+#    open STDIN_SAVE,  "<&STDIN"#  or croak "run3(): $! saving STDIN"
+#        if defined $in_fh;
+    open STDOUT_SAVE, ">&STDOUT" or croak "run3(): $! saving STDOUT"
+        if defined $out_fh;
+    open STDERR_SAVE, ">&STDERR" or croak "run3(): $! saving STDERR"
+        if defined $err_fh;
+
+    my $ok = eval {
+        ## The open() call here seems to not force fd 0 in some cases;
+        ## I ran in to trouble when using this in VCP, not sure why.
+        ## the dup2() seems to work.
+        dup2( fileno $in_fh, 0 )
+#        open STDIN,  "<&=" . fileno $in_fh
+            or croak "run3(): $! redirecting STDIN"
+            if defined $in_fh;
+
+#        close $in_fh or croak "$! closing STDIN temp file"
+#            if ref $stdin;
+
+        open STDOUT, ">&" . fileno $out_fh
+            or croak "run3(): $! redirecting STDOUT"
+            if defined $out_fh;
+
+        open STDERR, ">&" . fileno $err_fh
+            or croak "run3(): $! redirecting STDERR"
+            if defined $err_fh;
+
+        $sys_call_time = gettimeofday() if profiling;
+
+        my $r = ref $cmd
+           ? system {$cmd->[0]}
+                   is_win32
+                       ? map {
+                           ## Probably need to offer a win32 escaping
+                           ## option, every command may be different.
+                           ( my $s = $_ ) =~ s/"/"""/g;
+                           $s = qq{"$s"};
+                           $s;
+                       } @$cmd
+                       : @$cmd
+           : system $cmd;
+
+        $sys_exit_time = gettimeofday() if profiling;
+
+        unless ( defined $r ) {
+            if ( debugging ) {
+                my $err_fh = defined $err_fh ? \*STDERR_SAVE : \*STDERR;
+                print $err_fh "run3(): system() error $!\n"
+            }
+            die $!;
+        }
+
+        if ( debugging ) {
+            my $err_fh = defined $err_fh ? \*STDERR_SAVE : \*STDERR;
+            print $err_fh "run3(): \$? is $?\n"
+        }
+        1;
+    };
+    my $x = $@;
+
+    my @errs;
+
+    if ( defined $saved_fd0 ) {
+        dup2( $saved_fd0, 0 );
+        POSIX::close( $saved_fd0 );
+    }
+
+#    open STDIN,  "<&STDIN_SAVE"#  or push @errs, "run3(): $! restoring STDIN"
+#        if defined $in_fh;
+    open STDOUT, ">&STDOUT_SAVE" or push @errs, "run3(): $! restoring STDOUT"
+        if defined $out_fh;
+    open STDERR, ">&STDERR_SAVE" or push @errs, "run3(): $! restoring STDERR"
+        if defined $err_fh;
+
+    croak join ", ", @errs if @errs;
+
+    die $x unless $ok;
+
+    _read_child_output_fh "stdout", $out_type, $stdout, $out_fh, $options
+        if defined $out_fh && $out_type && $out_type ne "FH";
+    _read_child_output_fh "stderr", $err_type, $stderr, $err_fh, $options
+        if defined $err_fh && $err_type && $err_type ne "FH" && !$tie_err_to_out;
+    $profiler->run_exit(
+       $cmd,
+       $run_call_time,
+       $sys_call_time,
+       $sys_exit_time,
+       scalar gettimeofday 
+    ) if profiling;
+
+    return 1;
+}
+
+my $in_fh;
+my $in_fd;
+my $out_fh;
+my $out_fd;
+my $err_fh;
+my $err_fd;
+        $in_fh = tempfile;
+        $in_fd = fileno $in_fh;
+        $out_fh = tempfile;
+        $out_fd = fileno $out_fh;
+        $err_fh = tempfile;
+        $err_fd = fileno $err_fh;
+    my $saved_fd0 = dup 0;
+    my $saved_fd1 = dup 1;
+    my $saved_fd2 = dup 2;
+    my $r;
+    my ( $cmd, $stdin, $stdout, $stderr );
+
+sub _run3 {
+    ( $cmd, $stdin, $stdout, $stderr ) = @_;
+
+    truncate $in_fh, 0;
+    seek $in_fh, 0, 0;
+
+    print $in_fh $$stdin or die "$! writing to temp file";
+    seek $in_fh, 0, 0;
+
+    seek $out_fh, 0, 0;
+    truncate $out_fh, 0;
+
+    seek $err_fh, 0, 0;
+    truncate $err_fh, 0;
+
+    dup2 $in_fd,  0 or croak "run3(): $! redirecting STDIN";
+    dup2 $out_fd, 1 or croak "run3(): $! redirecting STDOUT";
+    dup2 $err_fd, 2 or croak "run3(): $! redirecting STDERR";
+
+    $r = 
+       system {$cmd->[0]}
+               is_win32
+                   ? map {
+                       ## Probably need to offer a win32 escaping
+                       ## option, every command is different.
+                       ( my $s = $_ ) =~ s/"/"""/g;
+                       $s = q{"$s"} if /[^\w.:\/\\'-]/;
+                       $s;
+                   } @$cmd
+                   : @$cmd;
+
+    die $! unless defined $r;
+
+    dup2 $saved_fd0, 0;
+    dup2 $saved_fd1, 1;
+    dup2 $saved_fd2, 2;
+
+    seek $out_fh, 0, 0 or croak "$! seeking on temp file for child output";
+
+        my $count = read $out_fh, $$stdout, 10_000;
+        while ( $count == 10_000 ) {
+            $count = read $out_fh, $$stdout, 10_000, length $$stdout;
+        }
+        croak "$! reading child output from temp file"
+            unless defined $count;
+
+    seek $err_fh, 0, 0 or croak "$! seeking on temp file for child errput";
+
+        $count = read $err_fh, $$stderr, 10_000;
+        while ( $count == 10_000 ) {
+            $count = read $err_fh, $$stderr, 10_000, length $$stdout;
+        }
+        croak "$! reading child stderr from temp file"
+            unless defined $count;
+
+    return 1;
+}
+
+=cut
+
+
+=head1 TODO
+
+pty support
+
+=head1 LIMITATIONS
+
+Often uses intermediate files (determined by File::Temp, and thus by the
+File::Spec defaults and the TMPDIR env. variable) for speed, portability and
+simplicity.
+
+=head1 COPYRIGHT
+
+    Copyright 2003, R. Barrie Slaymaker, Jr., All Rights Reserved
+
+=head1 LICENSE
+
+You may use this module under the terms of the BSD, Artistic, or GPL licenses,
+any version.
+
+=head1 AUTHOR
+
+Barrie Slaymaker <barries@slaysys.com>
+
+=cut
+
+1;
diff --git a/regressions/inc/MyHarness.pm b/regressions/inc/MyHarness.pm
new file mode 100644 (file)
index 0000000..781b828
--- /dev/null
@@ -0,0 +1,29 @@
+use warnings;
+use strict;
+
+package MyStraps;
+use base qw( Test::Harness::Straps );
+sub _command_line {
+    my $self = shift;
+    my $file = shift;
+
+    $file = qq["$file"] if ($file =~ /\s/) && ($file !~ /^".*"$/);
+    my $line = "$file";
+
+    return $line;
+}
+
+sub _default_inc {
+    return @INC;
+}
+package MyHarness;
+use base qw( Test::Harness );
+
+#my $Strap = MyStraps->new();
+$Test::Harness::Strap = MyStraps->new();
+sub strap { return $Test::Harness::Strap }
+1;
diff --git a/regressions/regressions.xcodeproj/project.pbxproj b/regressions/regressions.xcodeproj/project.pbxproj
new file mode 100644 (file)
index 0000000..57814d2
--- /dev/null
@@ -0,0 +1,341 @@
+// !$*UTF8*$!
+{
+       archiveVersion = 1;
+       classes = {
+       };
+       objectVersion = 46;
+       objects = {
+
+/* Begin PBXBuildFile section */
+               4CC92AB915A3B19D00C6D578 /* testlist_end.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CC92AB815A3B19D00C6D578 /* testlist_end.h */; settings = {ATTRIBUTES = (); }; };
+               4CC92ABC15A3B51100C6D578 /* test_regressions.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CC92ABB15A3B51100C6D578 /* test_regressions.h */; settings = {ATTRIBUTES = (); }; };
+               4CC92ABD15A3B8FB00C6D578 /* testlist_begin.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CC92AB715A3B19100C6D578 /* testlist_begin.h */; settings = {ATTRIBUTES = (); }; };
+               4CC92B1715A3BD1E00C6D578 /* test-00-test.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92B1615A3BD1E00C6D578 /* test-00-test.c */; };
+               E710C7371331938000F85568 /* testenv.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C25A6C412271FAF0050C2BD /* testenv.c */; };
+               E710C7381331938000F85568 /* testmore.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C25A6C812271FAF0050C2BD /* testmore.c */; };
+               E710C7391331938000F85568 /* testcert.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C25A6CA12271FAF0050C2BD /* testcert.c */; };
+               E723A60F13DA18C50075AAC1 /* testcpp.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C25A6C312271FAF0050C2BD /* testcpp.h */; settings = {ATTRIBUTES = (); }; };
+               E723A61013DA18C50075AAC1 /* testenv.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C25A6C512271FAF0050C2BD /* testenv.h */; settings = {ATTRIBUTES = (); }; };
+               E723A61113DA18C50075AAC1 /* testmore.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C25A6C912271FAF0050C2BD /* testmore.h */; settings = {ATTRIBUTES = (); }; };
+               E723A61213DA18C50075AAC1 /* testcert.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C25A6CB12271FAF0050C2BD /* testcert.h */; settings = {ATTRIBUTES = (); }; };
+               E723A61313DA18C50075AAC1 /* testpolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = E76CA47B13D8D5CB001B6A11 /* testpolicy.h */; settings = {ATTRIBUTES = (); }; };
+               E76CA47913D8D5B4001B6A11 /* testpolicy.m in Sources */ = {isa = PBXBuildFile; fileRef = E76CA47813D8D5B4001B6A11 /* testpolicy.m */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+               0C25A68F12271FAF0050C2BD /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
+               0C25A69212271FAF0050C2BD /* Run3.pm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.perl; path = Run3.pm; sourceTree = "<group>"; };
+               0C25A69312271FAF0050C2BD /* MyHarness.pm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.perl; path = MyHarness.pm; sourceTree = "<group>"; };
+               0C25A6C012271FAF0050C2BD /* security.pl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.perl; path = security.pl; sourceTree = "<group>"; };
+               0C25A6C312271FAF0050C2BD /* testcpp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = testcpp.h; sourceTree = "<group>"; };
+               0C25A6C412271FAF0050C2BD /* testenv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testenv.c; sourceTree = "<group>"; };
+               0C25A6C512271FAF0050C2BD /* testenv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = testenv.h; sourceTree = "<group>"; };
+               0C25A6C812271FAF0050C2BD /* testmore.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testmore.c; sourceTree = "<group>"; };
+               0C25A6C912271FAF0050C2BD /* testmore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = testmore.h; sourceTree = "<group>"; };
+               0C25A6CA12271FAF0050C2BD /* testcert.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testcert.c; sourceTree = "<group>"; };
+               0C25A6CB12271FAF0050C2BD /* testcert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = testcert.h; sourceTree = "<group>"; };
+               0C25A6CE12271FAF0050C2BD /* run_tests.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = run_tests.sh; sourceTree = "<group>"; };
+               4CC92AB715A3B19100C6D578 /* testlist_begin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = testlist_begin.h; sourceTree = "<group>"; };
+               4CC92AB815A3B19D00C6D578 /* testlist_end.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = testlist_end.h; sourceTree = "<group>"; };
+               4CC92ABB15A3B51100C6D578 /* test_regressions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = test_regressions.h; sourceTree = "<group>"; };
+               4CC92B1615A3BD1E00C6D578 /* test-00-test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "test-00-test.c"; sourceTree = "<group>"; };
+               E710C6FE133192E900F85568 /* libregressions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libregressions.a; sourceTree = BUILT_PRODUCTS_DIR; };
+               E76CA47813D8D5B4001B6A11 /* testpolicy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = testpolicy.m; sourceTree = "<group>"; };
+               E76CA47B13D8D5CB001B6A11 /* testpolicy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = testpolicy.h; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+               E710C6FB133192E900F85568 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+               05441E5C08A971C700F0EC5A = {
+                       isa = PBXGroup;
+                       children = (
+                               0C25A68F12271FAF0050C2BD /* README */,
+                               0C25A69012271FAF0050C2BD /* inc */,
+                               0C25A6BF12271FAF0050C2BD /* t */,
+                               0C25A6C112271FAF0050C2BD /* test */,
+                               E710C6FE133192E900F85568 /* libregressions.a */,
+                       );
+                       sourceTree = "<group>";
+               };
+               0C25A69012271FAF0050C2BD /* inc */ = {
+                       isa = PBXGroup;
+                       children = (
+                               0C25A69112271FAF0050C2BD /* IPC */,
+                               0C25A69312271FAF0050C2BD /* MyHarness.pm */,
+                       );
+                       path = inc;
+                       sourceTree = "<group>";
+               };
+               0C25A69112271FAF0050C2BD /* IPC */ = {
+                       isa = PBXGroup;
+                       children = (
+                               0C25A69212271FAF0050C2BD /* Run3.pm */,
+                       );
+                       path = IPC;
+                       sourceTree = "<group>";
+               };
+               0C25A6BF12271FAF0050C2BD /* t */ = {
+                       isa = PBXGroup;
+                       children = (
+                               0C25A6C012271FAF0050C2BD /* security.pl */,
+                       );
+                       path = t;
+                       sourceTree = "<group>";
+               };
+               0C25A6C112271FAF0050C2BD /* test */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4CC92B1615A3BD1E00C6D578 /* test-00-test.c */,
+                               4CC92ABB15A3B51100C6D578 /* test_regressions.h */,
+                               4CC92AB715A3B19100C6D578 /* testlist_begin.h */,
+                               4CC92AB815A3B19D00C6D578 /* testlist_end.h */,
+                               0C25A6C312271FAF0050C2BD /* testcpp.h */,
+                               0C25A6C412271FAF0050C2BD /* testenv.c */,
+                               0C25A6C512271FAF0050C2BD /* testenv.h */,
+                               0C25A6C812271FAF0050C2BD /* testmore.c */,
+                               0C25A6C912271FAF0050C2BD /* testmore.h */,
+                               0C25A6CA12271FAF0050C2BD /* testcert.c */,
+                               0C25A6CB12271FAF0050C2BD /* testcert.h */,
+                               E76CA47B13D8D5CB001B6A11 /* testpolicy.h */,
+                               E76CA47813D8D5B4001B6A11 /* testpolicy.m */,
+                               0C25A6CE12271FAF0050C2BD /* run_tests.sh */,
+                       );
+                       path = test;
+                       sourceTree = "<group>";
+               };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+               E710C6FC133192E900F85568 /* Headers */ = {
+                       isa = PBXHeadersBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               E723A61113DA18C50075AAC1 /* testmore.h in Headers */,
+                               4CC92ABC15A3B51100C6D578 /* test_regressions.h in Headers */,
+                               4CC92ABD15A3B8FB00C6D578 /* testlist_begin.h in Headers */,
+                               4CC92AB915A3B19D00C6D578 /* testlist_end.h in Headers */,
+                               E723A61213DA18C50075AAC1 /* testcert.h in Headers */,
+                               E723A60F13DA18C50075AAC1 /* testcpp.h in Headers */,
+                               E723A61013DA18C50075AAC1 /* testenv.h in Headers */,
+                               E723A61313DA18C50075AAC1 /* testpolicy.h in Headers */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+               E710C6FD133192E900F85568 /* regressions */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = E710C703133192E900F85568 /* Build configuration list for PBXNativeTarget "regressions" */;
+                       buildPhases = (
+                               E710C6FA133192E900F85568 /* Sources */,
+                               E710C6FB133192E900F85568 /* Frameworks */,
+                               E710C6FC133192E900F85568 /* Headers */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = regressions;
+                       productName = regressions;
+                       productReference = E710C6FE133192E900F85568 /* libregressions.a */;
+                       productType = "com.apple.product-type.library.static";
+               };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+               05441E6008A971C700F0EC5A /* Project object */ = {
+                       isa = PBXProject;
+                       attributes = {
+                               LastUpgradeCheck = 0500;
+                       };
+                       buildConfigurationList = 4CD81AFC09BE1FD3000A9641 /* Build configuration list for PBXProject "regressions" */;
+                       compatibilityVersion = "Xcode 3.2";
+                       developmentRegion = English;
+                       hasScannedForEncodings = 0;
+                       knownRegions = (
+                               English,
+                               Japanese,
+                               French,
+                               German,
+                       );
+                       mainGroup = 05441E5C08A971C700F0EC5A;
+                       productRefGroup = 05441E5C08A971C700F0EC5A;
+                       projectDirPath = "";
+                       projectRoot = "";
+                       targets = (
+                               E710C6FD133192E900F85568 /* regressions */,
+                       );
+               };
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+               E710C6FA133192E900F85568 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               E710C7371331938000F85568 /* testenv.c in Sources */,
+                               E710C7381331938000F85568 /* testmore.c in Sources */,
+                               E710C7391331938000F85568 /* testcert.c in Sources */,
+                               E76CA47913D8D5B4001B6A11 /* testpolicy.m in Sources */,
+                               4CC92B1715A3BD1E00C6D578 /* test-00-test.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+               792E01860CBC0E6E007C00A0 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+                               COPY_PHASE_STRIP = NO;
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1";
+                               "GCC_PREPROCESSOR_DEFINITIONS[sdk=iphoneos*]" = (
+                                       "DEBUG=1",
+                                       "NO_SERVER=1",
+                               );
+                               "GCC_PREPROCESSOR_DEFINITIONS[sdk=iphonesimulator*]" = (
+                                       "DEBUG=1",
+                                       "NO_SERVER=1",
+                               );
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
+                               GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
+                               GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;
+                               GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
+                               GCC_WARN_MISSING_PARENTHESES = YES;
+                               GCC_WARN_SHADOW = YES;
+                               GCC_WARN_SIGN_COMPARE = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = NO;
+                               GCC_WARN_UNKNOWN_PRAGMAS = YES;
+                               GCC_WARN_UNUSED_FUNCTION = YES;
+                               GCC_WARN_UNUSED_LABEL = YES;
+                               GCC_WARN_UNUSED_VALUE = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               HEADER_SEARCH_PATHS = (
+                                       "$(PROJECT_DIR)/../utilities",
+                                       "$(PROJECT_DIR)/../sec",
+                                       "$(PROJECT_DIR)/../libDER",
+                                       "$(PROJECT_DIR)/..",
+                                       "$(PROJECT_DIR)",
+                                       "$(BUILT_PRODUCTS_DIR)$(INDIGO_INSTALL_PATH_PREFIX)/usr/local/include",
+                               );
+                               OTHER_CFLAGS = (
+                                       "-fconstant-cfstrings",
+                                       "-fno-inline",
+                               );
+                               "OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
+                                       "$(OTHER_LDFLAGS)",
+                                       "-framework",
+                                       MobileKeyBag,
+                               );
+                               SKIP_INSTALL = YES;
+                               SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator";
+                               WARNING_CFLAGS = (
+                                       "-Wall",
+                                       "-Wextra",
+                                       "-Wno-unused-parameter",
+                                       "-Wno-missing-field-initializers",
+                               );
+                       };
+                       name = Debug;
+               };
+               792E01870CBC0E6E007C00A0 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+                               COPY_PHASE_STRIP = YES;
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_OPTIMIZATION_LEVEL = s;
+                               GCC_PREPROCESSOR_DEFINITIONS = "NDEBUG=1";
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
+                               GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
+                               GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;
+                               GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
+                               GCC_WARN_MISSING_PARENTHESES = YES;
+                               GCC_WARN_SHADOW = YES;
+                               GCC_WARN_SIGN_COMPARE = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
+                               GCC_WARN_UNKNOWN_PRAGMAS = YES;
+                               GCC_WARN_UNUSED_FUNCTION = YES;
+                               GCC_WARN_UNUSED_LABEL = YES;
+                               GCC_WARN_UNUSED_VALUE = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               HEADER_SEARCH_PATHS = (
+                                       "$(PROJECT_DIR)/../utilities",
+                                       "$(PROJECT_DIR)/../sec",
+                                       "$(PROJECT_DIR)/../libDER",
+                                       "$(PROJECT_DIR)/..",
+                                       "$(PROJECT_DIR)",
+                                       "$(BUILT_PRODUCTS_DIR)$(INDIGO_INSTALL_PATH_PREFIX)/usr/local/include",
+                               );
+                               OTHER_CFLAGS = "-fconstant-cfstrings";
+                               SKIP_INSTALL = YES;
+                               SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator";
+                               WARNING_CFLAGS = (
+                                       "-Wall",
+                                       "-Wextra",
+                                       "-Wno-unused-parameter",
+                                       "-Wno-missing-field-initializers",
+                               );
+                       };
+                       name = Release;
+               };
+               E710C704133192E900F85568 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Debug;
+               };
+               E710C705133192E900F85568 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Release;
+               };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+               4CD81AFC09BE1FD3000A9641 /* Build configuration list for PBXProject "regressions" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               792E01860CBC0E6E007C00A0 /* Debug */,
+                               792E01870CBC0E6E007C00A0 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               E710C703133192E900F85568 /* Build configuration list for PBXNativeTarget "regressions" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               E710C704133192E900F85568 /* Debug */,
+                               E710C705133192E900F85568 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+/* End XCConfigurationList section */
+       };
+       rootObject = 05441E6008A971C700F0EC5A /* Project object */;
+}
diff --git a/regressions/t/security.pl b/regressions/t/security.pl
new file mode 100755 (executable)
index 0000000..d0892f0
--- /dev/null
@@ -0,0 +1,68 @@
+#!/usr/bin/perl -w
+#
+#  Copyright (c) 2006-2007 Apple Inc. All Rights Reserved.
+#
+
+my $pid = $$;
+
+END {
+    return unless $$ == $pid;
+    rm_test($_) for @TOCLEAN;
+}
+
+use strict;
+use Test::More;
+use IPC::Run3;
+
+sub plan_security {
+    
+    unless (1) {
+       plan skip_all => "security not installed";
+       exit;
+    };
+    plan @_;
+}
+
+use Carp;
+our @TOCLEAN;
+END {
+    return unless $$ == $pid;
+    $SIG{__WARN__} = sub { 1 };
+    cleanup_test($_) for @TOCLEAN;
+}
+
+our $output = '';
+
+sub build_test {
+    my $xd = "/tmp/test-$pid";
+    my $security = 'security';
+    $ENV{HOME} = $xd;
+    push @TOCLEAN, [$xd, $security];
+    return ($xd, $security);
+}
+
+sub rm_test {
+    my ($xd, $security) = @{+shift};
+    #rmtree [$xd];
+}
+
+sub cleanup_test {
+    return unless $ENV{TEST_VERBOSE};
+    my ($xd, $security) = @{+shift};
+}
+
+sub is_output {
+    my ($security, $cmd, $arg, $expected, $test) = @_;
+    $output = '';
+    run3([$security, $cmd, @$arg], \undef, \$output, \$output);
+#    open(STDOUT, ">&STDERR") || die "couldn't dup strerr: $!";
+#    open(my $out, '-|', $security, $cmd, @$arg);
+#    while (<$out>) { $output .= $_; }
+
+    my $cmp = (grep {ref ($_) eq 'Regexp'} @$expected)
+       ? \&is_deeply_like : \&is_deeply;
+    @_ = ([sort split (/\r?\n/, $output)], [sort @$expected], $test || join(' ', $cmd, @$arg));
+    goto &$cmp;
+}
+
+1;
diff --git a/regressions/test/run_tests.sh b/regressions/test/run_tests.sh
new file mode 100755 (executable)
index 0000000..a1ae8cd
--- /dev/null
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+# run_tests.sh
+# Security
+#
+# Created by Fabrice Gautier on 8/26/10.
+# Copyright 2010 Apple, Inc. All rights reserved.
+
+
+# Run a command line tool on the sim or the device
+
+CMD=SecurityTests.app/SecurityTests
+
+if [ "${PLATFORM_NAME}" == "iphoneos" ]; then
+    INSTALL_DIR=/tmp
+    RSYNC_URL=rsync://root@localhost:10873/root${INSTALL_DIR}
+#copy Security Framework and testrunner program to the device, to /tmp
+#This will not override the existing security Framework on your device (in /System/Library/Framework)
+    export RSYNC_PASSWORD=alpine
+    echo "run_tests.sh:${LINENO}: note: Copying stuff to device"
+    /usr/bin/rsync -cav ${CONFIGURATION_BUILD_DIR}/Security.framework ${RSYNC_URL}
+    /usr/bin/rsync -cav ${CONFIGURATION_BUILD_DIR}/SecurityTests.app ${RSYNC_URL}
+    echo "run_tests.sh:${LINENO}: note: Running the test"
+    xcrun -sdk "$SDKROOT" PurpleExec --env "DYLD_FRAMEWORK_PATH=${INSTALL_DIR}" --cmd ${INSTALL_DIR}/${CMD}
+else
+    echo "run_tests.sh:${LINENO}: note: Running test on simulator (${BUILT_PRODUCTS_DIR}/${CMD})"
+       export DYLD_ROOT_PATH="${SDKROOT}"
+    export DYLD_LIBRARY_PATH="${BUILT_PRODUCTS_DIR}"
+    export DYLD_FRAMEWORK_PATH="${BUILT_PRODUCTS_DIR}"
+    ${BUILT_PRODUCTS_DIR}/${CMD}
+fi
+
+
diff --git a/regressions/test/test-00-test.c b/regressions/test/test-00-test.c
new file mode 100644 (file)
index 0000000..bc0ffa8
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2006-2007 Apple Inc. All Rights Reserved.
+ */
+
+#include <stdlib.h>
+
+#include "test_regressions.h"
+
+int test_00_test(int argc, char *const *argv)
+{
+    int rv = 1;
+    plan_tests(6);
+
+    TODO: {
+       todo("ok 0 is supposed to fail");
+
+       rv = ok(0, "ok bad");
+       if (!rv)
+           diag("ok bad not good today");
+    }
+    rv &= ok(1, "ok ok");
+#if 0
+    SKIP: {
+       skip("is bad will fail", 1, 0);
+
+       if (!is(0, 4, "is bad"))
+           diag("is bad not good today");
+    }
+    SKIP: {
+       skip("is ok should not be skipped", 1, 1);
+
+        is(3, 3, "is ok");
+    }
+#endif
+    isnt(0, 4, "isnt ok");
+    TODO: {
+       todo("isnt bad is supposed to fail");
+
+       isnt(3, 3, "isnt bad");
+    }
+    TODO: {
+       todo("cmp_ok bad is supposed to fail");
+
+       cmp_ok(3, &&, 0, "cmp_ok bad");
+    }
+    cmp_ok(3, &&, 3, "cmp_ok ok");
+
+    return 0;
+}
diff --git a/regressions/test/test_regressions.h b/regressions/test/test_regressions.h
new file mode 100644 (file)
index 0000000..8a7c99c
--- /dev/null
@@ -0,0 +1,7 @@
+/* To add a test:
+ 1) add it here
+ 2) Add it as command line argument for SecurityTest.app in the Release and Debug schemes
+ */
+#include "testmore.h"
+
+ONE_TEST(test_00_test)
diff --git a/regressions/test/testcert.c b/regressions/test/testcert.c
new file mode 100644 (file)
index 0000000..3a70922
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2009 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ *
+ * testcert.c
+ */
+
+#include <TargetConditionals.h>
+
+#if TARGET_OS_IPHONE
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecIdentityPriv.h>
+#include <Security/SecItem.h>
+#include <Security/SecCertificateRequest.h>
+#include <Security/SecInternal.h>
+#include <utilities/array_size.h>
+
+#include <AssertMacros.h>
+
+#include "testcert.h"
+
+static inline CFMutableArrayRef maa(CFMutableArrayRef array, CFTypeRef a) {
+       CFMutableArrayRef ma = array;
+       if (!ma)
+               ma = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+       if (ma) {
+               CFArrayAppendValue(ma, a);
+               CFRelease(a);
+       }
+       return ma;
+}
+
+
+CFArrayRef test_cert_string_to_subject(CFStringRef subject)
+{
+       CFMutableArrayRef subject_array = NULL;
+       char buffer[1024];
+
+       if (!CFStringGetCString(subject, buffer, sizeof(buffer), kCFStringEncodingASCII))
+               goto out;
+
+       char *s = buffer, *e = NULL;
+       while ( (e = strchr(s, ',')) || (e = strchr(s, '\0')) ) {
+               if (s == e)
+                       break;
+               if (*e && (*(e-1) == '\\'))
+                       continue;
+               char *k;
+               while ((k = strchr(s, '=')) &&
+                               (*(k-1) == '\\'));
+               if ( ((k - s) > 0) && ((e - k) > 1) ) {
+                       CFStringRef key = CFStringCreateWithBytes(kCFAllocatorDefault, (uint8_t *)s, k - s, kCFStringEncodingASCII, false);
+                       CFStringRef value = CFStringCreateWithBytes(kCFAllocatorDefault, (uint8_t *)k + 1, e - k - 1, kCFStringEncodingASCII, false);
+                       subject_array = maa(subject_array, maa(NULL, maa(maa(NULL, key), value)));
+               }
+        if (*e == '\0')
+            break;
+               s = e + 1;
+       }
+
+out:
+       return subject_array;
+}
+
+
+static void test_cert_key_usage(CFMutableDictionaryRef extensions_dict, unsigned int key_usage)
+{
+       int key_usage_int = key_usage;
+       CFNumberRef key_usage_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &key_usage_int);
+       CFDictionarySetValue(extensions_dict, kSecCertificateKeyUsage, key_usage_num);
+       CFRelease(key_usage_num);
+}
+
+
+static void test_cert_path_length(CFMutableDictionaryRef extensions_dict, unsigned int path_length)
+{
+       int path_len_int = path_length;
+       CFNumberRef path_len_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &path_len_int);
+       CFDictionarySetValue(extensions_dict, kSecCSRBasicContraintsPathLen, path_len_num);
+       CFRelease(path_len_num);
+}
+
+
+SecIdentityRef test_cert_create_root_certificate(CFStringRef subject, SecKeyRef public_key, SecKeyRef private_key)
+{
+       SecCertificateRef ca_cert = NULL;
+       SecIdentityRef ca_identity = NULL;
+    CFMutableDictionaryRef extensions = NULL;
+
+       CFArrayRef ca_subject = NULL;
+       require(ca_subject = test_cert_string_to_subject(subject), out);
+       extensions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+       test_cert_key_usage(extensions, kSecKeyUsageKeyCertSign | kSecKeyUsageCRLSign);
+       test_cert_path_length(extensions, 0);
+       ca_cert = SecGenerateSelfSignedCertificate(ca_subject, extensions, public_key, private_key);
+       if (private_key && ca_cert)
+               ca_identity = SecIdentityCreate(kCFAllocatorDefault, ca_cert, private_key);
+
+out:
+       CFReleaseSafe(extensions);
+       CFReleaseSafe(ca_subject);
+       CFReleaseSafe(ca_cert);
+
+       return ca_identity;
+}
+
+SecCertificateRef test_cert_issue_certificate(SecIdentityRef ca_identity,
+       SecKeyRef public_key, CFStringRef subject,
+       unsigned int serial_no, unsigned int key_usage)
+{
+       SecCertificateRef cert = NULL;
+       CFArrayRef cert_subject = NULL;
+       CFDataRef serialno = NULL;
+       CFMutableDictionaryRef extensions = NULL;
+
+       unsigned int serial = htonl(serial_no);
+       unsigned int serial_length = sizeof(serial);
+       uint8_t *serial_non_zero = (uint8_t*)&serial;
+       while (!*serial_non_zero && serial_length)
+               { serial_non_zero++; serial_length--; }
+    serialno = CFDataCreate(kCFAllocatorDefault,
+               serial_non_zero, serial_length);
+       require(cert_subject = test_cert_string_to_subject(subject), out);
+       //extensions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+       //require(extensions, out);
+       //test_cert_key_usage(extensions, key_usage);
+
+       cert = SecIdentitySignCertificate(ca_identity, serialno,
+           public_key, cert_subject, NULL);
+
+out:
+       CFReleaseSafe(extensions);
+       CFReleaseSafe(cert_subject);
+       CFReleaseSafe(serialno);
+
+       return cert;
+}
+
+OSStatus
+test_cert_generate_key(uint32_t key_size_in_bits, CFTypeRef sec_attr_key_type,
+                       SecKeyRef *private_key, SecKeyRef *public_key)
+{
+       CFNumberRef key_size = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &key_size_in_bits);
+       const void *keygen_keys[] = { kSecAttrKeyType, kSecAttrKeySizeInBits };
+       const void *keygen_vals[] = { sec_attr_key_type, key_size };
+       CFDictionaryRef parameters = CFDictionaryCreate(kCFAllocatorDefault,
+                                                    keygen_keys, keygen_vals, array_size(keygen_vals),
+                                                    &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+       CFRelease(key_size);
+
+       return SecKeyGeneratePair(parameters, public_key, private_key);
+}
+
+#endif /* TARGET_OS_IPHONE */
diff --git a/regressions/test/testcert.h b/regressions/test/testcert.h
new file mode 100644 (file)
index 0000000..15d1740
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2009 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ *
+ * testcert.h
+ */
+
+#include <Security/SecIdentity.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecKey.h>
+
+OSStatus
+test_cert_generate_key(uint32_t key_size_in_bits, CFTypeRef sec_attr_key_type,
+                       SecKeyRef *private_key, SecKeyRef *public_key);
+
+SecIdentityRef
+test_cert_create_root_certificate(CFStringRef subject,
+       SecKeyRef public_key, SecKeyRef private_key);
+
+SecCertificateRef
+test_cert_issue_certificate(SecIdentityRef ca_identity,
+       SecKeyRef public_key, CFStringRef subject,
+       unsigned int serial_no, unsigned int key_usage);
+
+CFArrayRef test_cert_string_to_subject(CFStringRef subject);
diff --git a/regressions/test/testcpp.h b/regressions/test/testcpp.h
new file mode 100644 (file)
index 0000000..6149bfd
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2005-2007 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ *
+ * testcpp.h
+ */
+
+#ifndef _TESTCPP_H_
+#define _TESTCPP_H_  1
+
+#include "testmore.h"
+
+#ifdef __cplusplus
+
+#define no_throw(THIS, TESTNAME) \
+({ \
+    bool _this; \
+    try { THIS; _this = true; } catch (...) { _this = false; } \
+    test_ok(_this, TESTNAME, test_directive, test_reason, \
+               __FILE__, __LINE__, \
+               "#          got: <unknown exception>\n" \
+               "#     expected: <no throw>\n"); \
+})
+#define does_throw(THIS, TESTNAME) \
+({ \
+    bool _this; \
+    try { THIS; _this = false; } catch (...) { _this = true; } \
+    test_ok(_this, TESTNAME, test_directive, test_reason, \
+               __FILE__, __LINE__, \
+               "#          got: <no throw>\n" \
+               "#     expected: <any exception>\n"); \
+})
+#define is_throw(THIS, CLASS, METHOD, VALUE, TESTNAME) \
+({ \
+    bool _this; \
+    try \
+       { \
+               THIS; \
+               _this = test_ok(false, TESTNAME, test_directive, test_reason, \
+                       __FILE__, __LINE__, \
+                       "#          got: <no throw>\n" \
+                       "#     expected: %s.%s == %s\n", \
+                       #CLASS, #METHOD, #VALUE); \
+       } \
+    catch (const CLASS &_exception) \
+    { \
+               _this = test_ok(_exception.METHOD == (VALUE), TESTNAME, \
+                       test_directive, test_reason, __FILE__, __LINE__, \
+                       "#          got: %d\n" \
+                       "#     expected: %s.%s == %s\n", \
+                       _exception.METHOD, #CLASS, #METHOD, #VALUE); \
+       } \
+    catch (...) \
+    { \
+       _this = test_ok(false, TESTNAME, test_directive, test_reason, \
+                       __FILE__, __LINE__, \
+                       "#          got: <unknown exception>\n" \
+                       "#     expected: %s.%s == %s\n", \
+                       #CLASS, #METHOD, #VALUE); \
+       } \
+       _this; \
+})
+#endif /* __cplusplus */
+
+#endif /* !_TESTCPP_H_ */
diff --git a/regressions/test/testenv.c b/regressions/test/testenv.c
new file mode 100644 (file)
index 0000000..93482c5
--- /dev/null
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 2005-2007,2009-2011 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ *
+ * testenv.c
+ */
+
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include <time.h>
+
+#include "testmore.h"
+#include "testenv.h"
+
+#include <utilities/debugging.h>
+#include <utilities/SecCFRelease.h>
+#include <utilities/SecFileLocations.h>
+
+
+int test_verbose = 0;
+
+#ifdef NO_SERVER
+#include <securityd/spi.h>
+
+static int current_dir = -1;
+static char scratch_dir[50];
+static char *home_var;
+static bool keep_scratch_dir = false;
+
+static int
+rmdir_recursive(const char *path)
+{
+       char command_buf[256];
+       if (strlen(path) + 10 > sizeof(command_buf) || strchr(path, '\''))
+       {
+               fprintf(stderr, "# rmdir_recursive: invalid path: %s", path);
+               return -1;
+       }
+
+       sprintf(command_buf, "/bin/rm -rf '%s'", path);
+       return system(command_buf);
+}
+#endif
+
+static int tests_init(void) {
+    int ok = 0;
+#ifdef NO_SERVER
+       char preferences_dir[80];
+       char library_dir[70];
+
+       setup("tests_init");
+
+    /* Create scratch dir for tests to run in. */
+    sprintf(scratch_dir, "/tmp/tst-%d", getpid());
+    if (keep_scratch_dir) {
+        printf("running tests with HOME=%s\n", scratch_dir);
+    }
+
+    sprintf(library_dir, "%s/Library", scratch_dir);
+    sprintf(preferences_dir, "%s/Preferences", library_dir);
+    ok =  (ok_unix(mkdir(scratch_dir, 0755), "mkdir") &&
+           ok_unix(current_dir = open(".", O_RDONLY), "open") &&
+           ok_unix(chdir(scratch_dir), "chdir") &&
+           ok_unix(setenv("HOME", scratch_dir, 1), "setenv") &&
+           /* @@@ Work around a bug that the prefs code in
+            libsecurity_keychain never creates the Library/Preferences
+            dir. */
+           ok_unix(mkdir(library_dir, 0755), "mkdir") &&
+           ok_unix(mkdir(preferences_dir, 0755), "mkdir") &&
+           ok(home_var = getenv("HOME"), "getenv"));
+    
+    if (ok > 0)
+        securityd_init(scratch_dir);
+#endif
+
+    return ok;
+}
+
+static int
+tests_end(void)
+{
+#ifdef NO_SERVER
+       setup("tests_end");
+       /* Restore previous cwd and remove scratch dir. */
+       int ok = ok_unix(fchdir(current_dir), "fchdir");
+       if (ok)
+               ok = ok_unix(close(current_dir), "close");
+       if (ok) {
+               if (!keep_scratch_dir) {
+                       ok = ok_unix(rmdir_recursive(scratch_dir), "rmdir_recursive");
+               }
+       }
+    
+       return ok;
+#else
+    return 0;
+#endif
+}
+
+static void usage(const char *progname)
+{
+    fprintf(stderr, "usage: %s [-k][-w][testname [testargs] ...]\n", progname);
+    exit(1);
+}
+
+static int tests_run_index(int i, int argc, char * const *argv)
+{
+    int ch;
+
+    while ((ch = getopt(argc, argv, "v")) != -1)
+    {
+        switch  (ch)
+        {
+            case 'v':
+                test_verbose++;
+                break;
+            default:
+                usage(argv[0]);
+        }
+    }
+
+    fprintf(stderr, "TEST: Test Case '%s' started.\n", testlist[i].name);
+    
+    run_one_test(&testlist[i], argc, argv);
+    if(testlist[i].failed_tests) {
+        fprintf(stderr, "FAIL: Test Case '%s' failed.\n", testlist[i].name);
+    } else {
+        fprintf(stderr, "PASS: Test Case '%s' passed. (%lu ms)\n", testlist[i].name, testlist[i].duration);
+    }
+    return testlist[i].failed_tests;
+}
+
+static int strcmp_under_is_dash(const char *s, const char *t) {
+    for (;;) {
+        char a = *s++, b = *t++;
+        if (a != b) {
+            if (a != '_' || b != '-')
+                return a - b;
+        } else if (a == 0) {
+            return 0;
+        }
+    }
+}
+
+static int tests_named_index(const char *testcase)
+{
+    int i;
+
+    for (i = 0; testlist[i].name; ++i) {
+        if (strcmp_under_is_dash(testlist[i].name, testcase) == 0) {
+            return i;
+        }
+    }
+
+    return -1;
+}
+
+static int tests_run_all(int argc, char * const *argv)
+{
+    int curroptind = optind;
+    int i;
+    int failcount=0;
+
+    for (i = 0; testlist[i].name; ++i) {
+        if(!testlist[i].off) {
+            failcount+=tests_run_index(i, argc, argv);
+            optind = curroptind;
+        }
+    }
+    
+    return failcount;
+}
+
+int
+tests_begin(int argc, char * const *argv)
+{
+    const char *testcase = NULL;
+    bool initialized = false;
+    bool print_security_logs = false;
+    int testix = -1;
+    int failcount = 0;
+       int ch;
+    int loop = 0;
+
+    for (;;) {
+        while (!testcase && (ch = getopt(argc, argv, "klvws")) != -1)
+        {
+            switch  (ch)
+            {
+#ifdef NO_SERVER
+            case 'k':
+                keep_scratch_dir = true;
+                break;
+#endif
+            case 's':
+                print_security_logs = true;
+                break;
+
+            case 'v':
+                test_verbose++;
+                break;
+
+            case 'w':
+                sleep(100);
+                break;
+            case 'l':
+                loop=1;
+                break;
+            case '?':
+            default:
+                printf("invalid option %c\n",ch); 
+                usage(argv[0]);
+            }
+        }
+
+        if (optind < argc) {
+            testix = tests_named_index(argv[optind]);
+            if(testix<0) {
+                printf("invalid test %s\n",argv[optind]); 
+                usage(argv[0]);
+            }
+        }
+
+        if (print_security_logs) {
+            add_security_log_hanlder(^(const char *level, CFStringRef scope, const char *function, const char *file, int line, CFStringRef message) {
+                time_t now = time(NULL);
+                char *date = ctime(&now);
+                date[19] = '\0';
+                CFStringRef logStr = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
+                                                              CFSTR("%s %@ %s %@\n"), date + 4,
+                                                              scope ? scope : CFSTR(""), function, message);
+                CFShow(logStr);
+                CFReleaseSafe(logStr);
+            });
+        }
+        
+        if (testix < 0) {
+            if (!initialized) {
+                initialized = true;
+                tests_init();
+                failcount+=tests_run_all(argc, argv);
+            }
+            break;
+        } else {
+            if (!initialized) {
+                tests_init();
+                initialized = true;
+            }
+            optind++;
+            failcount+=tests_run_index(testix, argc, argv);
+            testix = -1;
+        }
+    }
+        
+    printf("Total failcount = %d\n", failcount);
+
+    /* Cleanups */
+    tests_end();
+    
+    if(loop) {
+        printf("Looping until key press 'q'. You can run leaks now.\n");
+        while(getchar()!='q');
+    }
+
+    return failcount;
+}
+
diff --git a/regressions/test/testenv.h b/regressions/test/testenv.h
new file mode 100644 (file)
index 0000000..727d42c
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2005-2007 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ *
+ * testenv.h
+ */
+
+#ifndef _TESTENV_H_
+#define _TESTENV_H_  1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int test_verbose;
+
+int tests_begin(int argc, char * const *argv);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* !_TESTENV_H_ */
diff --git a/regressions/test/testlist_begin.h b/regressions/test/testlist_begin.h
new file mode 100644 (file)
index 0000000..fc8a4c3
--- /dev/null
@@ -0,0 +1,10 @@
+/* This file contains an array of all test functions, last element is NULL */
+
+#undef ONE_TEST
+#undef DISABLED_ONE_TEST
+#undef OFF_ONE_TEST
+
+#define ONE_TEST(x) {#x, x, 0, 0 , 0, 0 },
+#define OFF_ONE_TEST(x) {#x, x, 1, 0 , 0, 0 },
+#define DISABLED_ONE_TEST(x)
+struct one_test_s testlist[] = {
diff --git a/regressions/test/testlist_end.h b/regressions/test/testlist_end.h
new file mode 100644 (file)
index 0000000..4ffe7b2
--- /dev/null
@@ -0,0 +1,5 @@
+    { NULL, NULL, 0, 0, 0},
+};
+#undef ONE_TEST
+#undef DISABLED_ONE_TEST
+#undef OFF_ONE_TEST
diff --git a/regressions/test/testmore.c b/regressions/test/testmore.c
new file mode 100644 (file)
index 0000000..0aaf0b3
--- /dev/null
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2005-2007 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ *
+ * testmore.c
+ */
+
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <AvailabilityMacros.h>
+
+#include "testmore.h"
+#include "testenv.h"
+
+static int test_num = 0;
+static int test_fails = 0;
+static int test_cases = 0;
+static const char *test_plan_file;
+static int test_plan_line=0;
+
+const char *test_directive = NULL;
+const char *test_reason = NULL;
+
+static void fprint_string(FILE *file, CFStringRef string) {
+    UInt8 buf[256];
+    CFRange range = { .location = 0 };
+    range.length = CFStringGetLength(string);
+    while (range.length > 0) {
+        CFIndex bytesUsed = 0;
+        CFIndex converted = CFStringGetBytes(string, range, kCFStringEncodingUTF8, 0, false, buf, sizeof(buf), &bytesUsed);
+        fwrite(buf, 1, bytesUsed, file);
+        range.length -= converted;
+        range.location += converted;
+    }
+}
+
+static void cffprint(FILE *file, CFStringRef fmt, ...) CF_FORMAT_FUNCTION(2,0);
+
+static void cffprint(FILE *file, CFStringRef fmt, ...) {
+    va_list args;
+    va_start(args, fmt);
+    CFStringRef line = CFStringCreateWithFormatAndArguments(NULL, NULL, fmt, args);
+    va_end(args);
+    fprint_string(file, line);
+    CFRelease(line);
+}
+
+void test_skip(const char *reason, int how_many, int unless)
+{
+    if (unless)
+        return;
+
+    int done;
+    for (done = 0; done < how_many; ++done)
+        test_ok(1, NULL, "skip", reason, __FILE__, __LINE__, NULL);
+}
+
+void test_bail_out(const char *reason, const char *file, unsigned line)
+{
+    printf("BAIL OUT! (%s at line %u) %s\n", file, line, reason);
+    fflush(stdout);
+    exit(255);
+}
+
+void test_plan_skip_all(const char *reason)
+{
+    if (test_num < test_cases)
+    {
+        test_skip(reason, test_cases - test_num, 0);
+    }
+}
+
+static int test_plan_exit(void)
+{
+    int status = 0;
+    fflush(stdout);
+
+    if (!test_num)
+    {
+        if (test_cases)
+        {
+            fprintf(stderr, "%s:%u: warning: No tests run!\n", test_plan_file, test_plan_line);
+            status = 255;
+        }
+        else
+        {
+            fprintf(stderr, "%s:%u: error: Looks like your test died before it could "
+                    "output anything.\n", test_plan_file, test_plan_line);
+            status = 255;
+        }
+    }
+    else if (test_num < test_cases)
+    {
+        fprintf(stderr, "%s:%u: warning: Looks like you planned %d tests but only ran %d.\n",
+               test_plan_file, test_plan_line, test_cases, test_num);
+        status = test_fails + test_cases - test_num;
+    }
+    else if (test_num > test_cases)
+    {
+        fprintf(stderr, "%s:%u: warning: Looks like you planned %d tests but ran %d extra.\n",
+               test_plan_file, test_plan_line, test_cases, test_num - test_cases);
+        status = test_fails;
+    }
+    else if (test_fails)
+    {
+        fprintf(stderr, "%s:%u: error: Looks like you failed %d tests of %d.\n",
+               test_plan_file, test_plan_line, test_fails, test_cases);
+        status = test_fails;
+    }
+
+    fflush(stderr);
+    
+    /* reset the test plan */
+    test_num = 0;
+    test_fails = 0;
+    test_cases = 0;
+
+    return status;
+}
+
+void test_plan_tests(int count, const char *file, unsigned line)
+{
+#if 0
+    if (atexit(test_plan_exit) < 0)
+    {
+        fprintf(stderr, "failed to setup atexit handler: %s\n",
+                strerror(errno));
+        fflush(stderr);
+        exit(255);
+    }
+#endif
+
+       if (test_cases)
+    {
+        fprintf(stderr,
+                "%s:%u: error: You tried to plan twice!\n",
+                file, line);
+        
+        fflush(stderr);
+        exit(255);
+    }
+    else
+       {
+        if (!count)
+        {
+            fprintf(stderr, "%s:%u: warning: You said to run 0 tests!  You've got to run "
+                    "something.\n", file, line);
+            fflush(stderr);
+            exit(255);
+        }
+
+        test_plan_file=file;
+        test_plan_line=line;
+        
+        test_cases = count;
+               fprintf(stderr, "%s:%u: note: 1..%d\n", file, line, test_cases);
+               fflush(stdout);
+       }
+}
+
+int
+test_diag(const char *directive, const char *reason,
+       const char *file, unsigned line, const char *fmt, ...)
+{
+       int is_todo = directive && !strcmp(directive, "TODO");
+       va_list args;
+
+       va_start(args, fmt);
+
+       if (is_todo)
+       {
+               fputs("# ", stdout);
+               if (fmt)
+                       vprintf(fmt, args);
+               fputs("\n", stdout);
+               fflush(stdout);
+       }
+       else
+       {
+               fflush(stdout);
+               fputs("# ", stderr);
+               if (fmt)
+                       vfprintf(stderr, fmt, args);
+               fputs("\n", stderr);
+               fflush(stderr);
+       }
+
+       va_end(args);
+
+       return 1;
+}
+
+int
+test_ok(int passed, __attribute((cf_consumed)) CFStringRef description, const char *directive,
+       const char *reason, const char *file, unsigned line,
+       const char *fmt, ...)
+{
+       int is_todo = !passed && directive && !strcmp(directive, "TODO");
+       int is_setup = directive && !is_todo && !strcmp(directive, "SETUP");
+
+       if (is_setup)
+       {
+               if (!passed)
+               {
+                       fflush(stdout);
+            cffprint(stderr, CFSTR("# SETUP not ok%s%@%s%s\n"),
+                                  description ? " - " : "",
+                                  description ? description : CFSTR(""),
+                                  reason ? " - " : "",
+                                  reason ? reason : "");
+               }
+       }
+       else
+       {
+               if (!test_cases)
+               {
+                       atexit((void(*)(void))test_plan_exit);
+                       fprintf(stderr, "You tried to run a test without a plan!  "
+                                       "Gotta have a plan. at %s line %u\n", file, line);
+                       fflush(stderr);
+                       exit(255);
+               }
+
+               ++test_num;
+               if (test_num > test_cases || (!passed && !is_todo))
+                       ++test_fails;
+
+        /* We only print this when a test fail, unless verbose is enabled */
+        if ((!passed) || (test_verbose > 0)) {
+            cffprint(stderr, CFSTR("%s:%u: note: %sok %d%s%@%s%s%s%s\n"),
+                      file, line, passed ? "" : "not ", test_num,
+                      description ? " - " : "",
+                      description ? description : CFSTR(""),
+                      directive ? " # " : "",
+                      directive ? directive : "",
+                      reason ? " " : "",
+                      reason ? reason : "");
+        }
+    }
+
+    if (passed)
+               fflush(stdout);
+       else
+    {
+               va_list args;
+
+               va_start(args, fmt);
+
+               if (is_todo)
+               {
+/* Enable this to output TODO as warning */
+#if 0             
+                       printf("%s:%d: warning: Failed (TODO) test\n", file, line);
+                       if (fmt)
+                               vprintf(fmt, args);
+#endif
+                       fflush(stdout);
+               }
+        else
+               {
+                       fflush(stdout);
+                       fprintf(stderr, "%s:%d: error: Failed test\n", file, line);
+                       if (fmt)
+                               vfprintf(stderr, fmt, args);
+                       fflush(stderr);
+               }
+
+               va_end(args);
+    }
+
+    if (description)
+        CFRelease(description);
+
+    return passed;
+}
+
+
+const char *
+sec_errstr(int err)
+{
+#if 1
+       static int bufnum = 0;
+    static char buf[2][20];
+       bufnum = bufnum ? 0 : 1;
+    sprintf(buf[bufnum], "0x%X", err);
+    return buf[bufnum];
+#else /* !1 */
+    if (err >= errSecErrnoBase && err <= errSecErrnoLimit)
+        return strerror(err - 100000);
+
+#ifdef MAC_OS_X_VERSION_10_4
+    /* AvailabilityMacros.h would only define this if we are on a
+       Tiger or later machine. */
+    extern const char *cssmErrorString(long);
+    return cssmErrorString(err);
+#else /* !defined(MAC_OS_X_VERSION_10_4) */
+    extern const char *_ZN8Security15cssmErrorStringEl(long);
+    return _ZN8Security15cssmErrorStringEl(err);
+#endif /* MAC_OS_X_VERSION_10_4 */
+#endif /* !1 */
+}
+
+/* run one test, described by test, return info in test struct */
+int run_one_test(struct one_test_s *test, int argc, char * const *argv)
+{
+    struct timeval start, stop;
+    
+    if(test->entry==NULL) {
+        printf("%s:%d: error: wtf?\n", __FILE__, __LINE__);
+        return -1;
+    }
+    
+    gettimeofday(&start, NULL);
+    test->entry(argc, argv);
+    gettimeofday(&stop, NULL);
+    
+    
+    /* this may overflow... */
+    test->duration=(stop.tv_sec-start.tv_sec)*1000+(stop.tv_usec/1000)-(start.tv_usec/1000);
+    test->failed_tests=test_fails;
+
+    return test_plan_exit();
+ };
diff --git a/regressions/test/testmore.h b/regressions/test/testmore.h
new file mode 100644 (file)
index 0000000..515a84e
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2005-2007 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ *
+ * testmore.h
+ */
+
+#ifndef _TESTMORE_H_
+#define _TESTMORE_H_  1
+
+#include <errno.h>
+#include <inttypes.h>
+#include <string.h>
+#include <stdio.h>
+#include <CoreFoundation/CFString.h>
+
+__BEGIN_DECLS
+
+/* Macros to be used in testlist.h style headers. */
+#define ONE_TEST(x) int x(int argc, char *const *argv);
+#define DISABLED_ONE_TEST(x) ONE_TEST(x)
+#define OFF_ONE_TEST(x) ONE_TEST(x)
+
+typedef int (*one_test_entry)(int argc, char *const *argv);
+    
+#define ONE_TEST_ENTRY(x) int x(int argc, char *const *argv)
+    
+struct one_test_s {
+    char *name;            /* test name */
+    one_test_entry entry;  /* entry point */
+    int off;               /* off by default */
+    int sub_tests;         /* number of subtests */
+    int failed_tests;      /* number of failed tests*/
+    unsigned long duration; /* test duration in msecs */
+    /* add more later: timing, etc... */
+};
+
+extern struct one_test_s testlist[];
+    
+int run_one_test(struct one_test_s *test, int argc, char * const *argv);
+
+/* this test harnes rely on shadowing for TODO, SKIP and SETUP blocks */
+#pragma GCC diagnostic ignored "-Wshadow"
+
+#define test_create_description(TESTNAME, ...) \
+    CFStringCreateWithFormat(NULL, NULL, CFSTR(TESTNAME), ## __VA_ARGS__)
+
+#define ok(THIS, ...) \
+({ \
+    bool is_ok = !!(THIS); \
+    test_ok(is_ok, test_create_description(__VA_ARGS__), test_directive, \
+        test_reason, __FILE__, __LINE__, NULL); \
+})
+#define is(THIS, THAT, ...) \
+({ \
+    __typeof__(THIS) _this = (THIS); \
+    __typeof__(THAT) _that = (THAT); \
+    test_ok((_this == _that), test_create_description(__VA_ARGS__), \
+        test_directive, test_reason, __FILE__, __LINE__, \
+               "#          got: '%d'\n" \
+               "#     expected: '%d'\n", \
+               _this, _that); \
+})
+#define isnt(THIS, THAT, ...) \
+       cmp_ok((THIS), !=, (THAT), __VA_ARGS__)
+#define diag(MSG, ARGS...) \
+       test_diag(test_directive, test_reason, __FILE__, __LINE__, MSG, ## ARGS)
+#define cmp_ok(THIS, OP, THAT, ...) \
+({ \
+       __typeof__(THIS) _this = (THIS); \
+       __typeof__(THAT) _that = (THAT); \
+       test_ok((_this OP _that), test_create_description(__VA_ARGS__), \
+        test_directive, test_reason, __FILE__, __LINE__, \
+          "#     '%d'\n" \
+          "#         " #OP "\n" \
+          "#     '%d'\n", \
+          _this, _that); \
+})
+#define eq_string(THIS, THAT, ...) \
+({ \
+       const char *_this = (THIS); \
+       const char *_that = (THAT); \
+       test_ok(!strcmp(_this, _that), test_create_description(__VA_ARGS__), \
+        test_directive, test_reason, __FILE__, __LINE__, \
+          "#     '%s'\n" \
+          "#         eq\n" \
+          "#     '%s'\n", \
+          _this, _that); \
+})
+#define eq_stringn(THIS, THISLEN, THAT, THATLEN, ...) \
+({ \
+       __typeof__(THISLEN) _thislen = (THISLEN); \
+       __typeof__(THATLEN) _thatlen = (THATLEN); \
+       const char *_this = (THIS); \
+       const char *_that = (THAT); \
+       test_ok(_thislen == _thatlen && !strncmp(_this, _that, _thislen), \
+               test_create_description(__VA_ARGS__), test_directive, test_reason, \
+               __FILE__, __LINE__, \
+          "#     '%.*s'\n" \
+          "#         eq\n" \
+          "#     '%.*s'\n", \
+          (int)_thislen, _this, (int)_thatlen, _that); \
+})
+#define like(THIS, REGEXP, ...) like_not_yet_implemented()
+#define unlike(THIS, REGEXP, ...) unlike_not_yet_implemented()
+#define is_deeply(STRUCT1, STRUCT2, ...) is_deeply_not_yet_implemented()
+#define TODO switch(0) default
+#define SKIP switch(0) default
+#define SETUP switch(0) default
+#define todo(REASON) const char *test_directive __attribute__((unused)) = "TODO", \
+       *test_reason __attribute__((unused)) = (REASON)
+#define skip(WHY, HOW_MANY, UNLESS) if (!(UNLESS)) \
+    { test_skip((WHY), (HOW_MANY), 0); break; }
+#define setup(REASON) const char *test_directive = "SETUP", \
+       *test_reason = (REASON)
+#define pass(...) ok(1, __VA_ARGS__)
+#define fail(...) ok(0, __VA_ARGS__)
+#define BAIL_OUT(WHY) test_bail_out(WHY, __FILE__, __LINE__)
+#define plan_skip_all(REASON) test_plan_skip_all(REASON)
+#define plan_tests(COUNT) test_plan_tests(COUNT, __FILE__, __LINE__)
+
+#define ok_status(THIS, ...) \
+({ \
+       OSStatus _this = (THIS); \
+       test_ok(!_this, test_create_description(__VA_ARGS__), \
+        test_directive, test_reason, __FILE__, __LINE__, \
+          "#     status: %s(%" PRId32 ")\n", \
+          sec_errstr(_this), _this); \
+})
+#define is_status(THIS, THAT, ...) \
+({ \
+    OSStatus _this = (THIS); \
+    OSStatus _that = (THAT); \
+    test_ok(_this == _that, test_create_description(__VA_ARGS__), \
+        test_directive, test_reason, __FILE__, __LINE__, \
+          "#          got: %s(%" PRId32 ")\n" \
+          "#     expected: %s(%" PRId32 ")\n", \
+          sec_errstr(_this), _this, sec_errstr(_that), _that); \
+})
+#define ok_unix(THIS, ...) \
+({ \
+    int _this = (THIS) < 0 ? errno : 0; \
+    test_ok(!_this, test_create_description(__VA_ARGS__), \
+        test_directive, test_reason, __FILE__, __LINE__, \
+          "#          got: %s(%d)\n", \
+          strerror(_this), _this); \
+})
+#define is_unix(THIS, THAT, ...) \
+({ \
+    int _result = (THIS); \
+    int _this = _result < 0 ? errno : 0; \
+    int _that = (THAT); \
+    _that && _result < 0 \
+       ? test_ok(_this == _that, test_create_description(__VA_ARGS__), \
+        test_directive, test_reason, __FILE__, __LINE__, \
+               "#          got: %s(%d)\n" \
+               "#     expected: %s(%d)\n", \
+               strerror(_this), _this, strerror(_that), _that) \
+       : test_ok(_this == _that, test_create_description(__VA_ARGS__), \
+        test_directive, test_reason, __FILE__, __LINE__, \
+               "#            got: %d\n" \
+               "# expected errno: %s(%d)\n", \
+               _result, strerror(_that), _that); \
+})
+
+
+extern const char *test_directive;
+extern const char *test_reason;
+
+void test_bail_out(const char *reason, const char *file, unsigned line);
+int test_diag(const char *directive, const char *reason,
+       const char *file, unsigned line, const char *fmt, ...);
+int test_ok(int passed, __attribute((cf_consumed)) CFStringRef description, const char *directive,
+       const char *reason, const char *file, unsigned line, const char *fmt, ...);
+void test_plan_skip_all(const char *reason);
+void test_plan_tests(int count, const char *file, unsigned line);
+void test_skip(const char *reason, int how_many, int unless);
+
+const char *sec_errstr(int err);
+
+__END_DECLS
+
+#endif /* !_TESTMORE_H_ */
diff --git a/regressions/test/testpolicy.h b/regressions/test/testpolicy.h
new file mode 100644 (file)
index 0000000..c7c5c24
--- /dev/null
@@ -0,0 +1,19 @@
+//
+//  testpolicy.h
+//  regressions
+//
+//  Created by Mitch Adler on 7/21/11.
+//  Copyright (c) 2011 Apple Inc. All rights reserved.
+//
+
+#ifndef regressions_testpolicy_h
+#define regressions_testpolicy_h
+
+#include <Security/SecPolicy.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+
+void runCertificateTestForDirectory(SecPolicyRef policy, CFStringRef resourceSubDirectory, CFGregorianDate *date);
+
+
+#endif
diff --git a/regressions/test/testpolicy.m b/regressions/test/testpolicy.m
new file mode 100644 (file)
index 0000000..5b5a7ff
--- /dev/null
@@ -0,0 +1,206 @@
+//
+//  testpolicy.cpp
+//  regressions
+//
+//  Created by Mitch Adler on 7/21/11.
+//  Copyright (c) 2011 Apple Inc. All rights reserved.
+//
+
+#include "testpolicy.h"
+
+#include <TargetConditionals.h>
+
+#if TARGET_OS_IPHONE
+
+#include <Foundation/Foundation.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecInternal.h>
+#include <Security/SecPolicyPriv.h>
+#include <Security/SecTrust.h>
+#include <Security/SecTrustPriv.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "testmore.h"
+
+/*
+ * Copyright (c) 2011 Apple Inc. All Rights Reserved.
+ */
+
+#include <Foundation/Foundation.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecInternal.h>
+#include <Security/SecPolicyPriv.h>
+#include <Security/SecTrust.h>
+#include <Security/SecTrustPriv.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "testmore.h"
+
+/* Those tests were originally written around that date. */
+CFGregorianDate frozenTime = {
+    .year = 2011,
+    .month  = 9,
+    .day    = 1,
+    .hour   = 0,
+    .minute = 0,
+    .second = 0,
+};
+
+static void runOneLeafTest(SecPolicyRef policy,
+                           NSArray* anchors,
+                           NSArray* intermediates,
+                           NSString* path,
+                           bool expectedResult,
+                           NSObject* expectations,
+                           CFGregorianDate *date)
+{
+    NSString* fileName = [path lastPathComponent];
+    const char *reason = NULL;
+    SecTrustRef trustRef = NULL;
+    CFStringRef failReason = NULL;
+    NSMutableArray* certArray = NULL;
+    SecCertificateRef certRef = NULL;
+
+    if (expectations) {
+        if ([expectations isKindOfClass: [NSString class]]) {
+            reason = [(NSString *)expectations UTF8String];
+        } else if ([expectations isKindOfClass: [NSDictionary class]]) {
+            NSDictionary *dict = (NSDictionary *)expectations;
+            NSObject *value = [dict valueForKey:@"valid"];
+            if (value) {
+                if ([value isKindOfClass: [NSNumber class]]) {
+                    expectedResult = [(NSNumber *)value boolValue];
+                } else {
+                    NSLog(@"Unexpected valid value %@ in dict for key %@", value, fileName);
+                }
+            }
+            value = [dict valueForKey:@"reason"];
+            if (value) {
+                if ([value isKindOfClass: [NSString class]]) {
+                    reason = [(NSString *)value UTF8String];
+                } else {
+                    NSLog(@"Unexpected reason value %@ in dict for key %@", value, fileName);
+                }
+            }
+        } else if ([expectations isKindOfClass: [NSNumber class]]) {
+            expectedResult = [(NSNumber *)expectations boolValue];
+        } else {
+            NSLog(@"Unexpected class %@ value %@ for key %@", [expectations class], expectations, fileName);
+        }
+    }
+
+    certRef = SecCertificateCreateWithData(NULL, (CFDataRef)[NSData dataWithContentsOfFile:path]);
+    if (!certRef) {
+        if (reason) {
+            todo(reason);
+            fail("%@ unable to create certificate", fileName);
+        } else {
+            fail("PARSE %@ unable to create certificate", fileName);
+        }
+        goto exit;
+    }
+
+    certArray = [NSMutableArray arrayWithArray:intermediates];
+    [certArray insertObject:(id)certRef atIndex:0]; //The certificate to be verified must be the first in the array.
+
+    OSStatus err;
+    err = SecTrustCreateWithCertificates(certArray, policy, &trustRef);
+    if (err) {
+        ok_status(err, "SecTrustCreateWithCertificates");
+        goto exit;
+    }
+    if ([anchors count])
+        SecTrustSetAnchorCertificates(trustRef, (CFArrayRef)anchors);
+
+    CFDateRef dateRef = CFDateCreate(kCFAllocatorDefault, CFGregorianDateGetAbsoluteTime(date?*date:frozenTime, NULL));
+    SecTrustSetVerifyDate(trustRef, dateRef);
+    CFRelease(dateRef);
+
+    SecTrustResultType evalRes = 0;
+    //NSLog(@"Evaluating: %@",certRef);
+    err = SecTrustEvaluate(trustRef, &evalRes);
+    if (err) {
+        ok_status(err, "SecTrustCreateWithCertificates");
+        goto exit;
+    }
+    BOOL isValid = (evalRes == kSecTrustResultProceed || evalRes == kSecTrustResultUnspecified);
+    if (!isValid && expectedResult) {
+        failReason = SecTrustCopyFailureDescription(trustRef);
+    }
+    if (reason) {
+        todo(reason);
+        ok(isValid == expectedResult, "%@%@",
+           fileName,
+           (expectedResult
+            ? (failReason ? failReason : CFSTR(""))
+            : CFSTR(" valid")));
+    } else {
+        ok(isValid == expectedResult, "%s %@%@",
+           expectedResult ? "REGRESSION" : "SECURITY", fileName,
+           failReason ? failReason : CFSTR(""));
+    }
+
+exit:
+    CFReleaseSafe(failReason);
+    CFReleaseSafe(trustRef);
+    CFReleaseSafe(certRef);
+}
+
+// TODO: Export this interface in a better way.
+static void runCertificateTestFor(SecPolicyRef policy,
+                           NSArray* anchors,
+                           NSArray* intermediates,
+                           NSMutableArray* leafPaths,
+                           NSDictionary* expect,
+                           CFGregorianDate *date)
+{
+    /* Sort the tests by name. */
+    [leafPaths sortUsingSelector:@selector(compare:)];
+
+       for (NSString* path in leafPaths) {
+        NSString* fileName = [path lastPathComponent];
+        runOneLeafTest(policy, anchors, intermediates, path, ![fileName hasPrefix:@"Invalid"], [expect objectForKey:fileName], date);
+       }
+}
+
+void runCertificateTestForDirectory(SecPolicyRef policy, CFStringRef resourceSubDirectory, CFGregorianDate *date)
+{
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+       NSMutableArray* allRoots = [NSMutableArray array];
+       NSMutableArray* allCAs = [NSMutableArray array];
+       NSMutableArray* certTests = [NSMutableArray array];
+    NSDictionary* expect = NULL;
+
+    /* Iterate though the nist-certs resources dir. */
+    NSURL* filesDirectory = [[[NSBundle mainBundle] resourceURL] URLByAppendingPathComponent:(NSString*)resourceSubDirectory];
+    for (NSURL* fileURL in [[NSFileManager defaultManager] contentsOfDirectoryAtURL:filesDirectory includingPropertiesForKeys:[NSArray array] options:NSDirectoryEnumerationSkipsSubdirectoryDescendants error:nil]) {
+        NSString* path = [fileURL path];
+               if ([path hasSuffix:@"Cert.crt"]) {
+            SecCertificateRef certRef = SecCertificateCreateWithData(NULL, (CFDataRef)[NSData dataWithContentsOfFile:path]);
+            [allCAs addObject:(id)certRef];
+        } else if ([path hasSuffix:@"RootCertificate.crt"]) {
+            SecCertificateRef certRef = SecCertificateCreateWithData(NULL, (CFDataRef)[NSData dataWithContentsOfFile:path]);
+            [allRoots addObject:(id)certRef];
+        } else if ([path hasSuffix:@".crt"]) {
+                [certTests addObject:path];
+        } else if ([path hasSuffix:@".plist"]) {
+            if (expect) {
+                fail("Multiple .plist files found in %@", filesDirectory);
+            } else {
+                expect = [NSDictionary dictionaryWithContentsOfFile:path];
+            }
+        }
+       }
+
+    runCertificateTestFor(policy, allRoots, allCAs, certTests, expect, date);
+
+    [pool release];
+}
+
+#endif /* TARGET_OS_IPHONE */
diff --git a/sec/CloudKeychainProxy/CloudKeychainProxy.1 b/sec/CloudKeychainProxy/CloudKeychainProxy.1
new file mode 100644 (file)
index 0000000..9cbfd79
--- /dev/null
@@ -0,0 +1,79 @@
+.\"Modified from man(1) of FreeBSD, the NetBSD mdoc.template, and mdoc.samples.\r
+.\"See Also:\r
+.\"man mdoc.samples for a complete listing of options\r
+.\"man mdoc for the short list of editing options\r
+.\"/usr/share/misc/mdoc.template\r
+.Dd 12/20/12               \" DATE \r
+.Dt CloudKeychainProxy 1      \" Program name and manual section number \r
+.Os Darwin\r
+.Sh NAME                 \" Section Header - required - don't modify \r
+.Nm CloudKeychainProxy,\r
+.\" The following lines are read in generating the apropos(man -k) database. Use only key\r
+.\" words here as the database is built based on the words here and in the .ND line. \r
+.Nm Other_name_for_same_program(),\r
+.Nm Yet another name for the same program.\r
+.\" Use .Nm macro to designate other names for the documented program.\r
+.Nd This line parsed for whatis database.\r
+.Sh SYNOPSIS             \" Section Header - required - don't modify\r
+.Nm\r
+.Op Fl abcd              \" [-abcd]\r
+.Op Fl a Ar path         \" [-a path] \r
+.Op Ar file              \" [file]\r
+.Op Ar                   \" [file ...]\r
+.Ar arg0                 \" Underlined argument - use .Ar anywhere to underline\r
+arg2 ...                 \" Arguments\r
+.Sh DESCRIPTION          \" Section Header - required - don't modify\r
+Use the .Nm macro to refer to your program throughout the man page like such:\r
+.Nm\r
+Underlining is accomplished with the .Ar macro like this:\r
+.Ar underlined text .\r
+.Pp                      \" Inserts a space\r
+A list of items with descriptions:\r
+.Bl -tag -width -indent  \" Begins a tagged list \r
+.It item a               \" Each item preceded by .It macro\r
+Description of item a\r
+.It item b\r
+Description of item b\r
+.El                      \" Ends the list\r
+.Pp\r
+A list of flags and their descriptions:\r
+.Bl -tag -width -indent  \" Differs from above in tag removed \r
+.It Fl a                 \"-a flag as a list item\r
+Description of -a flag\r
+.It Fl b\r
+Description of -b flag\r
+.El                      \" Ends the list\r
+.Pp\r
+.\" .Sh ENVIRONMENT      \" May not be needed\r
+.\" .Bl -tag -width "ENV_VAR_1" -indent \" ENV_VAR_1 is width of the string ENV_VAR_1\r
+.\" .It Ev ENV_VAR_1\r
+.\" Description of ENV_VAR_1\r
+.\" .It Ev ENV_VAR_2\r
+.\" Description of ENV_VAR_2\r
+.\" .El                      \r
+.Sh FILES                \" File used or created by the topic of the man page\r
+.Bl -tag -width "/Users/joeuser/Library/really_long_file_name" -compact\r
+.It Pa /usr/share/file_name\r
+FILE_1 description\r
+.It Pa /Users/joeuser/Library/really_long_file_name\r
+FILE_2 description\r
+.El                      \" Ends the list\r
+.\" .Sh DIAGNOSTICS       \" May not be needed\r
+.\" .Bl -diag\r
+.\" .It Diagnostic Tag\r
+.\" Diagnostic informtion here.\r
+.\" .It Diagnostic Tag\r
+.\" Diagnostic informtion here.\r
+.\" .El\r
+.Sh SEE ALSO \r
+.\" List links in ascending order by section, alphabetically within a section.\r
+.\" Please do not reference files that do not exist without filing a bug report\r
+.Xr a 1 , \r
+.Xr b 1 ,\r
+.Xr c 1 ,\r
+.Xr a 2 ,\r
+.Xr b 2 ,\r
+.Xr a 3 ,\r
+.Xr b 3 \r
+.\" .Sh BUGS              \" Document known, unremedied bugs \r
+.\" .Sh HISTORY           \" Document history if command behaves in a unique manner
\ No newline at end of file
diff --git a/sec/SOSCircle/CKBridge/CKClient.c b/sec/SOSCircle/CKBridge/CKClient.c
new file mode 100644 (file)
index 0000000..0c937dd
--- /dev/null
@@ -0,0 +1,493 @@
+/*
+ * Copyright (c) 2012 Apple Computer, Inc. All Rights Reserved.
+ * 
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+//
+//  ckdxpcclient.c
+//  ckd-xpc
+//
+
+/*
+    This XPC service is essentially just a proxy to iCloud KVS, which exists since
+    the main security code cannot link against Foundation.
+    
+    See sendTSARequestWithXPC in tsaSupport.c for how to call the service
+    
+    The client of an XPC service does not get connection events, nor does it
+    need to deal with transactions.
+*/
+
+//------------------------------------------------------------------------------------------------
+
+#include <AssertMacros.h>
+
+#include <xpc/xpc.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreFoundation/CFXPCBridge.h>
+#include <sysexits.h>
+#include <syslog.h>
+
+#include <utilities/debugging.h>
+#include <utilities/SecCFWrappers.h>
+
+#include "CKConstants.h"
+
+#define __CKDXPC_CLIENT_PRIVATE_INDIRECT__ 1
+#include "CKClient.h"
+
+
+#define pdebug(format...) secerror(format)
+
+#define verboseCKDDebugging 1
+
+#ifndef NDEBUG
+    #define xpdebug(format...) \
+        do {  \
+            if (verboseCKDDebugging) \
+                printf(format);  \
+        } while (0)
+#else
+    //empty
+    #define xpdebug(format...)
+#endif
+
+
+static xpc_connection_t serviceConnection = NULL;
+static dispatch_queue_t xpc_queue = NULL;
+static CloudKeychainReplyBlock itemsChangedBlock;
+
+static bool handle_xpc_event(const xpc_connection_t peer, xpc_object_t event);
+static bool xpc_event_filter(const xpc_connection_t peer, xpc_object_t event, CFErrorRef *error);
+
+// extern CFTypeRef _CFXPCCreateCFObjectFromXPCObject(xpc_object_t xo);
+// extern xpc_object_t _CFXPCCreateXPCObjectFromCFObject(CFTypeRef cf);
+
+// Debug
+static void describeXPCObject(char *prefix, xpc_object_t object);
+void describeXPCType(char *prefix, xpc_type_t xtype);
+
+static CFStringRef sErrorDomain = CFSTR("com.apple.security.cloudkeychain");
+
+enum {
+    kSOSObjectMallocFailed = 1,
+    kAddDuplicateEntry,
+    kSOSObjectNotFoundError = 1,
+    kSOSObjectCantBeConvertedToXPCObject,
+    kSOSOUnexpectedConnectionEvent,
+    kSOSOUnexpectedXPCEvent,
+    kSOSConnectionNotOpen
+};
+
+#define WANTXPCREPLY 0
+
+#pragma mark ----- utilities -----
+
+static CFErrorRef makeError(CFIndex which)
+{
+    CFDictionaryRef userInfo = NULL;
+    return CFErrorCreate(kCFAllocatorDefault, sErrorDomain, which, userInfo);
+}
+
+#pragma mark ----- SPI -----
+
+void initXPCConnection()
+{
+    pdebug("initXPCConnection\n");
+    
+    xpc_queue = dispatch_queue_create(xpcServiceName, DISPATCH_QUEUE_SERIAL);
+
+    serviceConnection = xpc_connection_create_mach_service(xpcServiceName, xpc_queue, 0);
+
+//    serviceConnection = xpc_connection_create(xpcServiceName, xpc_queue);
+    pdebug("serviceConnection: %p\n", serviceConnection);
+
+    xpc_connection_set_event_handler(serviceConnection, ^(xpc_object_t event)
+    {
+        pdebug("xpc_connection_set_event_handler\n");
+        handle_xpc_event(serviceConnection, event);
+    });
+
+    xpc_connection_resume(serviceConnection);
+    xpc_retain(serviceConnection);
+}
+
+void closeXPCConnection()
+{
+    pdebug("closeXPCConnection\n");
+    xpc_release(serviceConnection);
+}
+
+void setItemsChangedBlock(CloudKeychainReplyBlock icb)
+{
+    if (icb != itemsChangedBlock)
+    {
+        if (itemsChangedBlock)
+            Block_release(itemsChangedBlock);
+        itemsChangedBlock = icb;
+        Block_copy(itemsChangedBlock);
+    }
+}
+
+// typedef void (^CloudKeychainReplyBlock)(CFDictionaryRef returnedValues, CFErrorRef error);
+
+static bool handle_xpc_event(const xpc_connection_t peer, xpc_object_t event)
+{
+    CFErrorRef localError = NULL;
+    pdebug(">>>>> handle_connection_event via event_handler <<<<<\n");
+    bool result = false;
+    if ((result = xpc_event_filter(peer, event, &localError)))
+    {
+        const char *operation = xpc_dictionary_get_string(event, kMessageKeyOperation);
+        if (!operation || strcmp(operation, kMessageOperationItemChanged))  // some op we don't care about
+        {
+            pdebug("operation: %s", operation);
+            return result;
+        }
+        
+        xpc_object_t xrv = xpc_dictionary_get_value(event, kMessageKeyValue);
+        if (!xrv)
+        {
+            pdebug("xrv null for kMessageKeyValue");
+            return result;
+        }
+        describeXPCObject("xrv", xrv);
+        
+        CFDictionaryRef returnedValues = _CFXPCCreateCFObjectFromXPCObject(xrv);
+        pdebug("returnedValues: %@", returnedValues);
+
+        if (itemsChangedBlock)
+            itemsChangedBlock(returnedValues, localError);
+    }
+    CFReleaseSafe(localError);
+
+    return result;
+}
+
+static bool xpc_event_filter(const xpc_connection_t peer, xpc_object_t event, CFErrorRef *error)
+{
+    // return true if the type is XPC_TYPE_DICTIONARY (and therefore something more to process)
+    pdebug("handle_connection_event\n");
+    xpc_type_t xtype = xpc_get_type(event);
+    describeXPCType("handle_xpc_event", xtype);
+    if (XPC_TYPE_CONNECTION == xtype)
+    {
+        pdebug("handle_xpc_event: XPC_TYPE_CONNECTION (unexpected)");
+        // The client of an XPC service does not get connection events
+        // For nwo, we log this and keep going
+        describeXPCObject("handle_xpc_event: XPC_TYPE_CONNECTION, obj : ", event);
+#if 0
+        if (error)
+            *error = makeError(kSOSOUnexpectedConnectionEvent); // FIX
+        assert(true);
+#endif
+    }
+    else
+    if (XPC_TYPE_ERROR == xtype)
+    {
+        pdebug("default: xpc error: %s\n", xpc_dictionary_get_string(event, XPC_ERROR_KEY_DESCRIPTION));
+        if (error)
+            *error = makeError(kSOSOUnexpectedConnectionEvent); // FIX
+    }
+    else
+    if (XPC_TYPE_DICTIONARY == xtype)
+    {
+        pdebug("received dictionary event %p\n", event);
+        return true;
+    }
+    else
+    {
+        pdebug("default: unexpected connection event %p\n", event);
+        describeXPCObject("handle_xpc_event: obj : ", event);
+        if (error)
+            *error = makeError(kSOSOUnexpectedXPCEvent);
+    }
+    return false;
+}
+
+static void talkWithKVS(xpc_object_t message, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    secerror("start");
+    __block CFErrorRef error = NULL;
+    __block CFTypeRef object = NULL;
+    
+    dispatch_block_t callback = ^{
+            secerror("callback");
+            if (replyBlock)
+                replyBlock(object, error);
+    //        if (object)
+     //           CFRelease(object);
+            if (error)
+            {
+                secerror("callback error: %@", error);
+     //           CFRelease(error);
+            }
+            dispatch_release(processQueue);
+        };
+    
+    require_action(serviceConnection, xit, error = makeError(kSOSConnectionNotOpen));
+    require_action(message, xit, error = makeError(kSOSObjectNotFoundError));
+    dispatch_retain(processQueue);
+    secerror("xpc_connection_send_message_with_reply called");
+    
+    Block_copy(callback);
+    
+//#if !WANTXPCREPLY
+ //   xpc_connection_send_message(serviceConnection, message);            // Send message; don't want a reply
+//#else
+    xpc_connection_send_message_with_reply(serviceConnection, message, xpc_queue, ^(xpc_object_t reply)
+        {
+            secerror("xpc_connection_send_message_with_reply handler called back");
+            if (xpc_event_filter(serviceConnection, reply, &error) && reply)
+            {
+                describeXPCObject("getValuesFromKVS: reply : ", reply);
+                xpc_object_t xrv = xpc_dictionary_get_value(reply, kMessageKeyValue);
+                if (xrv)
+                {
+                    describeXPCObject("talkWithKVS: xrv: ", xrv);
+                    /*
+                        * The given XPC object must be one that was previously returned by
+                        * _CFXPCCreateXPCMessageWithCFObject().
+                    */
+                    object = _CFXPCCreateCFObjectFromXPCObject(xrv);   // CF object is retained; release in callback
+                    secerror("converted CF object: %@", object);
+                }
+                else
+                    secerror("missing value reply");
+            }
+            dispatch_async(processQueue, callback);
+        });
+//#endif
+
+//sleep(5);   // DEBUG DEBUG FIX
+ //   xpc_release(message);
+    return;
+    
+xit:
+    secerror("talkWithKVS error: %@", error);
+    if (replyBlock)
+        dispatch_async(processQueue, callback);
+}
+
+void putValuesWithXPC(CFDictionaryRef values, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    CFErrorRef error = NULL;
+
+    require_action(values, xit, error = makeError(kSOSObjectNotFoundError));
+
+    xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
+    xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationPUTDictionary);
+    
+    xpc_object_t xobject = _CFXPCCreateXPCObjectFromCFObject(values);
+    require_action(xobject, xit, error = makeError(kSOSObjectCantBeConvertedToXPCObject));
+    xpc_dictionary_set_value(message, kMessageKeyValue, xobject);
+    
+    talkWithKVS(message, processQueue, replyBlock);
+    return;
+
+xit:
+    if (replyBlock)
+        replyBlock(NULL, error);
+}
+
+void synchronizeKVS(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
+    xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationSynchronize);
+    talkWithKVS(message, processQueue, replyBlock);
+}
+
+void clearAll(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
+    xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationClearStore);
+    talkWithKVS(message, processQueue, replyBlock);
+}
+
+/*
+extern xpc_object_t xpc_create_reply_with_format(xpc_object_t original, const char * format, ...);
+            xpc_object_t reply = xpc_create_reply_with_format(event, 
+                "{keychain-paths: %value, all-paths: %value, extensions: %value, keychain-home: %value}",
+                keychain_paths, all_paths, sandbox_extensions, home);
+*/
+
+void getValuesFromKVS(CFArrayRef keysToGet, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    secerror("start");
+    CFErrorRef error = NULL;
+    xpc_object_t xkeysOfInterest = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_object_t xkeysToGet = keysToGet ? _CFXPCCreateXPCObjectFromCFObject(keysToGet) : xpc_null_create();
+
+    require_action(xkeysToGet, xit, error = makeError(kSOSObjectNotFoundError));
+
+    xpc_dictionary_set_value(xkeysOfInterest, kMessageKeyKeysToGet, xkeysToGet);
+
+    xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
+    xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationGETv2);
+    xpc_dictionary_set_value(message, kMessageKeyValue, xkeysOfInterest);
+    
+    talkWithKVS(message, processQueue, replyBlock);
+
+    xpc_release(message);
+    return;
+    
+xit:
+    if (replyBlock)
+        replyBlock(NULL, error);
+}
+
+void registerKeysForKVS(CFArrayRef keysToGet, CFStringRef clientIdentifier, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    secerror("start");
+
+    xpc_object_t xkeysOfInterest = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_object_t xkeysToRegister = keysToGet ? _CFXPCCreateXPCObjectFromCFObject(keysToGet) : xpc_null_create();
+    xpc_dictionary_set_value(xkeysOfInterest, kMessageKeyKeysToGet, xkeysToRegister);
+
+    xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
+    xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationRegisterKeysAndGet);
+    xpc_dictionary_set_value(message, kMessageKeyValue, xkeysOfInterest);
+    
+    if (clientIdentifier)
+    {
+        char *clientid = CFStringToCString(clientIdentifier);
+        if (clientid)
+        {
+            xpc_dictionary_set_string(message, kMessageKeyClientIdentifier, clientid);
+            free(clientid);
+        }
+    }
+
+    setItemsChangedBlock(replyBlock);
+    talkWithKVS(message, processQueue, replyBlock);
+
+    xpc_release(message);
+}
+
+void unregisterKeysForKVS(CFArrayRef keysToUnregister, CFStringRef clientIdentifier, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+#if NO_SERVERz
+    if (gCKD->unregisterKeys) {
+        return gCKD->unregisterKeys(...);
+    }
+#endif
+
+    secerror("start");
+
+    xpc_object_t xkeysOfInterest = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_object_t xkeysToUnregister = keysToUnregister ? _CFXPCCreateXPCObjectFromCFObject(keysToUnregister) : xpc_null_create();
+    xpc_dictionary_set_value(xkeysOfInterest, kMessageKeyKeysToGet, xkeysToUnregister);
+
+    xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
+    xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationUnregisterKeys);
+    xpc_dictionary_set_value(message, kMessageKeyValue, xkeysOfInterest);
+    
+    if (clientIdentifier)
+    {
+        char *clientid = CFStringToCString(clientIdentifier);
+        if (clientid)
+        {
+            xpc_dictionary_set_string(message, kMessageKeyClientIdentifier, clientid);
+            free(clientid);
+        }
+    }
+
+    talkWithKVS(message, processQueue, replyBlock);
+
+    xpc_release(message);
+}
+
+#pragma mark ----- CF-XPC Utilities -----
+
+
+#pragma mark ----- DEBUG Utilities -----
+
+//------------------------------------------------------------------------------------------------
+//          DEBUG only
+//------------------------------------------------------------------------------------------------
+
+void clearStore()
+{
+    xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
+    xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationClearStore);
+    xpc_connection_send_message(serviceConnection, message);  // Send message; don't wait for a reply
+    xpc_release(message);
+}
+
+void describeXPCObject(char *prefix, xpc_object_t object)
+{
+//#ifndef NDEBUG
+    // This is useful for debugging.
+    if (object)
+    {
+      char *desc = xpc_copy_description(object);
+    pdebug("%s%s\n", prefix, desc);
+    free(desc);
+    }
+    else
+        pdebug("%s<NULL>\n", prefix);
+//#endif
+}
+
+void describeXPCType(char *prefix, xpc_type_t xtype)
+{
+    /*
+        Add these as necessary:
+        XPC_TYPE_ENDPOINT
+        XPC_TYPE_NULL
+        XPC_TYPE_BOOL
+        XPC_TYPE_INT64
+        XPC_TYPE_UINT64
+        XPC_TYPE_DOUBLE
+        XPC_TYPE_DATE
+        XPC_TYPE_DATA
+        XPC_TYPE_STRING
+        XPC_TYPE_UUID
+        XPC_TYPE_FD
+        XPC_TYPE_SHMEM
+        XPC_TYPE_ARRAY
+    */
+    
+#ifndef NDEBUG
+    // This is useful for debugging.
+    char msg[256]={0,};
+    if (XPC_TYPE_CONNECTION == xtype)
+        strcpy(msg, "XPC_TYPE_CONNECTION");
+    else if (XPC_TYPE_ERROR == xtype)
+        strcpy(msg, "XPC_TYPE_ERROR");
+    else if  (XPC_TYPE_DICTIONARY == xtype)
+        strcpy(msg, "XPC_TYPE_DICTIONARY");
+    else
+        strcpy(msg, "<unknown>");
+
+    pdebug("%s type:%s\n", prefix, msg);
+#endif
+}
+
+
+
diff --git a/sec/SOSCircle/CKBridge/CKClient.h b/sec/SOSCircle/CKBridge/CKClient.h
new file mode 100644 (file)
index 0000000..761f367
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2012 Apple Computer, Inc. All Rights Reserved.
+ * 
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+//
+//  ckdxpcclient.h
+//  ckd-xpc
+//
+
+#include <xpc/xpc.h>
+#include <utilities/debugging.h>
+#include "SOSCloudKeychainClient.h"
+
+#ifndef        _CKDXPC_CLIENT_H_
+#define _CKDXPC_CLIENT_H_
+
+//#ifndef __CKDXPC_CLIENT_PRIVATE_INDIRECT__
+//#error "Please #include "SOSCloudKeychainClient.h" instead of this file directly."
+//#endif /* __CKDXPC_CLIENT_PRIVATE_INDIRECT__ */
+
+__BEGIN_DECLS
+
+void initXPCConnection(void);
+void closeXPCConnection(void);
+void setItemsChangedBlock(CloudKeychainReplyBlock icb);
+
+void putValuesWithXPC(CFDictionaryRef values, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+void getValuesFromKVS(CFArrayRef keysToGet, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+
+void registerKeysForKVS(CFArrayRef keysToGet, CFStringRef clientIdentifier, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+void unregisterKeysForKVS(CFArrayRef keysToGet, CFStringRef clientIdentifier, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+
+void synchronizeKVS(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+void clearAll(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+
+// Debug
+
+void clearStore(void);
+
+__END_DECLS
+
+#endif /* _CKDXPC_CLIENT_H_ */
+
diff --git a/sec/SOSCircle/CKBridge/SOSCloudKeychainClient.c b/sec/SOSCircle/CKBridge/SOSCloudKeychainClient.c
new file mode 100644 (file)
index 0000000..303acbf
--- /dev/null
@@ -0,0 +1,757 @@
+/*
+ * Copyright (c) 2012 Apple Computer, Inc. All Rights Reserved.
+ * 
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+    SOSCloudTransport.c -  Implementation of the transport layer from CKBridge to SOSAccount/SOSCircle
+    These are the exported functions from CloudKeychainProxy
+*/
+
+/*
+    This XPC service is essentially just a proxy to iCloud KVS, which exists since
+    the main security code cannot link against Foundation.
+    
+    See sendTSARequestWithXPC in tsaSupport.c for how to call the service
+    
+    The client of an XPC service does not get connection events, nor does it
+    need to deal with transactions.
+*/
+
+#include <AssertMacros.h>
+
+#include <xpc/xpc.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreFoundation/CFXPCBridge.h>
+#include <sysexits.h>
+#include <syslog.h>
+#include <CoreFoundation/CFUserNotification.h>
+
+#include <utilities/debugging.h>
+#include <utilities/SecCFWrappers.h>
+#include <utilities/SecXPCError.h>
+
+#include "SOSCloudKeychainConstants.h"
+#include "SOSCloudKeychainClient.h"
+
+static CFStringRef sErrorDomain = CFSTR("com.apple.security.sos.transport.error");
+
+#define SOSCKCSCOPE "sync"
+
+// MARK: ---------- SOSCloudTransport ----------
+
+/* SOSCloudTransport, a statically initialized transport singleton. */
+static SOSCloudTransportRef sTransport = NULL;
+
+static SOSCloudTransportRef SOSCloudTransportCreateXPCTransport(void);
+
+void SOSCloudKeychainSetTransport(SOSCloudTransportRef transport) {
+    sTransport = transport;
+}
+
+/* Return the singleton cloud transport instance. */
+static SOSCloudTransportRef SOSCloudTransportDefaultTransport(void)
+{
+    static dispatch_once_t sTransportOnce;
+    dispatch_once(&sTransportOnce, ^{
+        if (!sTransport)
+            SOSCloudKeychainSetTransport(SOSCloudTransportCreateXPCTransport());
+    });
+    return sTransport;
+}
+
+
+// MARK: ----- utilities -----
+
+static CFErrorRef makeError(CFIndex which)
+{
+    CFDictionaryRef userInfo = NULL;
+    return CFErrorCreate(kCFAllocatorDefault, sErrorDomain, which, userInfo);
+}
+
+// MARK: ----- DEBUG Utilities -----
+
+//------------------------------------------------------------------------------------------------
+//          DEBUG only
+//------------------------------------------------------------------------------------------------
+
+static void describeXPCObject(char *prefix, xpc_object_t object)
+{
+//#ifndef NDEBUG
+    // This is useful for debugging.
+    if (object)
+    {
+        char *desc = xpc_copy_description(object);
+        secdebug(SOSCKCSCOPE, "%s%s\n", prefix, desc);
+        free(desc);
+    }
+    else
+        secdebug(SOSCKCSCOPE, "%s<NULL>\n", prefix);
+//#endif
+}
+
+static void describeXPCType(char *prefix, xpc_type_t xtype)
+{
+    // Add others as necessary, e.g. XPC_TYPE_DOUBLE
+#ifndef NDEBUG
+    // This is useful for debugging.
+    char msg[256]={0,};
+    if (XPC_TYPE_CONNECTION == xtype)
+        strcpy(msg, "XPC_TYPE_CONNECTION");
+    else if (XPC_TYPE_ERROR == xtype)
+        strcpy(msg, "XPC_TYPE_ERROR");
+    else if  (XPC_TYPE_DICTIONARY == xtype)
+        strcpy(msg, "XPC_TYPE_DICTIONARY");
+    else
+        strcpy(msg, "<unknown>");
+
+    secdebug(SOSCKCSCOPE, "%s type:%s\n", prefix, msg);
+#endif
+}
+
+// MARK: ---------- SOSXPCCloudTransport ----------
+
+typedef struct SOSXPCCloudTransport *SOSXPCCloudTransportRef;
+struct SOSXPCCloudTransport
+{
+    struct SOSCloudTransport transport;
+    xpc_connection_t serviceConnection;
+    dispatch_queue_t xpc_queue;
+};
+
+static bool xpc_event_filter(const xpc_connection_t peer, xpc_object_t event, CFErrorRef *error)
+{
+    // return true if the type is XPC_TYPE_DICTIONARY (and therefore something more to process)
+    secdebug(SOSCKCSCOPE, "handle_connection_event\n");
+    xpc_type_t xtype = xpc_get_type(event);
+    describeXPCType("handle_xpc_event", xtype);
+    if (XPC_TYPE_CONNECTION == xtype)
+    {
+        secdebug(SOSCKCSCOPE, "handle_xpc_event: XPC_TYPE_CONNECTION (unexpected)");
+        // The client of an XPC service does not get connection events
+        // For now, we log this and keep going
+        describeXPCObject("handle_xpc_event: XPC_TYPE_CONNECTION, obj : ", event);
+#if 0
+        if (error)
+            *error = makeError(kSOSOUnexpectedConnectionEvent); // FIX
+        assert(true);
+#endif
+    }
+    else
+    if (XPC_TYPE_ERROR == xtype)
+    {
+#ifndef NDEBUG
+        const char *estr = xpc_dictionary_get_string(event, XPC_ERROR_KEY_DESCRIPTION);
+#endif
+        secdebug(SOSCKCSCOPE, "default: xpc error: %s\n", estr);
+#if 0   // just log for now
+        CFStringRef errStr = CFStringCreateWithCString(kCFAllocatorDefault, estr, kCFStringEncodingUTF8);
+        CFMutableDictionaryRef userInfo = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+        if (errStr)
+            CFDictionaryAddValue(userInfo, kCFErrorLocalizedDescriptionKey, errStr);
+        if (error)
+            *error = CFErrorCreate(kCFAllocatorDefault, sErrorDomain, kSOSOXPCErrorEvent, userInfo);
+        CFReleaseSafe(errStr);
+        CFReleaseSafe(userInfo);
+#endif
+    }
+    else
+    if (XPC_TYPE_DICTIONARY == xtype)
+    {
+        secdebug(SOSCKCSCOPE, "received dictionary event %p\n", event);
+        return true;
+    }
+    else
+    {
+        secdebug(SOSCKCSCOPE, "default: unexpected connection event %p\n", event);
+        describeXPCObject("handle_xpc_event: obj : ", event);
+        if (error)
+            *error = makeError(kSOSOUnexpectedXPCEvent);
+    }
+    return false;
+}
+
+static bool handle_xpc_event(SOSXPCCloudTransportRef transport, xpc_object_t event)
+{
+    CFErrorRef localError = NULL;
+    // See <rdar://problem/14566253>
+    secerror(">>>>> handle_connection_event via event_handler <<<<<, WTF?");
+    bool result = false;
+    if ((result = xpc_event_filter(transport->serviceConnection, event, &localError)))
+    {
+        const char *operation = xpc_dictionary_get_string(event, kMessageKeyOperation);
+        if (!operation || strcmp(operation, kMessageOperationItemChanged))  // some op we don't care about
+        {
+            secdebug(SOSCKCSCOPE, "operation: %s", operation);
+            return result;
+        }
+
+        xpc_object_t xrv = xpc_dictionary_get_value(event, kMessageKeyValue);
+        if (!xrv)
+        {
+            secdebug(SOSCKCSCOPE, "xrv null for kMessageKeyValue");
+            return result;
+        }
+        describeXPCObject("xrv", xrv);
+
+        CFDictionaryRef returnedValues = _CFXPCCreateCFObjectFromXPCObject(xrv);
+        secdebug(SOSCKCSCOPE, "returnedValues: %@", returnedValues);
+
+        SOSCloudKeychainHandleUpdate(returnedValues);
+
+        CFReleaseNull(returnedValues);
+    }
+    CFReleaseSafe(localError);
+
+    return result;
+}
+
+static void SOSXPCCloudTransportInit(SOSXPCCloudTransportRef transport)
+{
+    secdebug(SOSCKCSCOPE, "initXPCConnection\n");
+
+    transport->xpc_queue = dispatch_queue_create(xpcServiceName, DISPATCH_QUEUE_SERIAL);
+
+    transport->serviceConnection = xpc_connection_create_mach_service(xpcServiceName, transport->xpc_queue, 0);
+
+    secdebug(SOSCKCSCOPE, "serviceConnection: %p\n", transport->serviceConnection);
+
+    xpc_connection_set_event_handler(transport->serviceConnection, ^(xpc_object_t event)
+    {
+        secdebug(SOSCKCSCOPE, "xpc_connection_set_event_handler\n");
+        handle_xpc_event(transport, event);
+    });
+
+    xpc_connection_resume(transport->serviceConnection);
+    xpc_retain(transport->serviceConnection);
+}
+
+static void talkWithKVS(SOSXPCCloudTransportRef transport, xpc_object_t message, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    __block CFErrorRef error = NULL;
+    __block CFTypeRef object = NULL;
+    
+    dispatch_block_t callback = ^{
+            if (replyBlock)
+                replyBlock(object, error);
+            if(object)
+                CFReleaseNull(object);
+            if (error)
+            {
+                secerror("callback error: %@", error);
+                CFReleaseNull(error);
+            }
+            dispatch_release(processQueue);
+        };
+    
+    require_action(transport->serviceConnection, xit, error = makeError(kSOSConnectionNotOpen));
+    require_action(message, xit, error = makeError(kSOSObjectNotFoundError));
+    dispatch_retain(processQueue);
+        
+    xpc_connection_send_message_with_reply(transport->serviceConnection, message, transport->xpc_queue, ^(xpc_object_t reply)
+        {
+            if (xpc_event_filter(transport->serviceConnection, reply, &error) && reply)
+            {
+                describeXPCObject("getValuesFromKVS: reply : ", reply);
+                if (error)
+                    secerror("Error from xpc_event_filter: %@", error);
+                xpc_object_t xrv = xpc_dictionary_get_value(reply, kMessageKeyValue);
+                if (xrv)
+                {
+                    describeXPCObject("talkWithKVS: xrv: ", xrv);
+                    /*
+                        * The given XPC object must be one that was previously returned by
+                        * _CFXPCCreateXPCMessageWithCFObject().
+                    */
+                    object = _CFXPCCreateCFObjectFromXPCObject(xrv);   // CF object is retained; release in callback
+                    secnotice("talkwithkvs", "converted CF object: %@", object);
+                }
+                else
+                    secerror("missing value reply");
+
+                xpc_object_t xerror = xpc_dictionary_get_value(reply, kMessageKeyError);
+                if (xerror)
+                    error = SecCreateCFErrorWithXPCObject(xerror);  // use SecCFCreateErrorWithFormat?
+            }
+            dispatch_async(processQueue, callback);
+        });
+    return;
+    
+xit:
+    secerror("talkWithKVS error: %@", error);
+    if (replyBlock)
+        dispatch_async(processQueue, callback);
+    CFReleaseSafe(error);
+}
+
+// MARK: ---------- SOSXPCCloudTransport Client Calls ----------
+
+/* Concrete function backend implementations. */
+static void SOSCloudTransportSetItemsChangedBlock(SOSCloudTransportRef transport,
+                                                  CloudItemsChangedBlock itemsChangedBlock) {
+    if (transport->itemsChangedBlock != itemsChangedBlock)
+    {
+        if (transport->itemsChangedBlock)
+            Block_release(transport->itemsChangedBlock);
+        transport->itemsChangedBlock = Block_copy(itemsChangedBlock);
+    }
+}
+
+/* Virtual function backend implementations. */
+static void SOSCloudTransportPut(SOSCloudTransportRef transport, CFDictionaryRef values, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport;
+    secdebug(SOSCKCSCOPE, "%@", values);
+    CFErrorRef error = NULL;
+    xpc_object_t message = NULL;
+    xpc_object_t xobject = NULL;
+    require_action(values, xit, error = makeError(kSOSObjectNotFoundError));
+
+    message = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
+    xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationPUTDictionary);
+    
+    xobject = _CFXPCCreateXPCObjectFromCFObject(values);
+    require_action(xobject, xit, error = makeError(kSOSObjectCantBeConvertedToXPCObject));
+    xpc_dictionary_set_value(message, kMessageKeyValue, xobject);
+    xpc_release(xobject);
+    
+    talkWithKVS(xpcTransport, message, processQueue, replyBlock);
+    xpc_release(message);
+    return;
+
+xit:
+    if (replyBlock)
+        replyBlock(NULL, error);
+    CFReleaseSafe(error);
+}
+
+/* Get from KVS */
+static void SOSCloudTransportGet(SOSCloudTransportRef transport, CFArrayRef keysToGet, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport;
+    secdebug(SOSCKCSCOPE, "%@", keysToGet);
+    CFErrorRef error = NULL;
+    xpc_object_t xkeysOfInterest = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_object_t xkeysToGet = keysToGet ? _CFXPCCreateXPCObjectFromCFObject(keysToGet) : xpc_null_create();
+
+    require_action(xkeysToGet, xit, error = makeError(kSOSObjectNotFoundError));
+
+    if (keysToGet)  // don't add if nulll; will call getall
+        xpc_dictionary_set_value(xkeysOfInterest, kMessageKeyKeysToGet, xkeysToGet);
+
+    xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
+    xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationGETv2);
+    xpc_dictionary_set_value(message, kMessageKeyValue, xkeysOfInterest);
+    
+    talkWithKVS(xpcTransport, message, processQueue, replyBlock);
+    xpc_release(xkeysToGet);
+    xpc_release(xkeysOfInterest);
+    xpc_release(message);
+    return;
+    
+xit:
+    if(xkeysOfInterest)
+        xpc_release(xkeysOfInterest);
+    if(xkeysToGet)
+        xpc_release(xkeysToGet);
+    if (replyBlock)
+        replyBlock(NULL, error);
+    CFReleaseSafe(error);
+}
+
+static void SOSCloudTransportRegisterKeys(SOSCloudTransportRef transport, CFArrayRef keysToGet, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock, CloudItemsChangedBlock notificationBlock)
+{
+    SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport;
+    secdebug(SOSCKCSCOPE, "%@", keysToGet);
+    xpc_object_t xkeysOfInterest = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_object_t xkeysToRegister = keysToGet ? _CFXPCCreateXPCObjectFromCFObject(keysToGet) : xpc_null_create();
+    xpc_dictionary_set_value(xkeysOfInterest, kMessageKeyKeysToGet, xkeysToRegister);
+
+    xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
+    xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationRegisterKeysAndGet);
+    xpc_dictionary_set_value(message, kMessageKeyValue, xkeysOfInterest);
+
+    SOSCloudTransportSetItemsChangedBlock(transport, notificationBlock);
+    talkWithKVS(xpcTransport, message, processQueue, replyBlock);
+    xpc_release(xkeysOfInterest);
+    xpc_release(xkeysToRegister);
+    xpc_release(message);
+}
+
+//
+// Handles NULL by seting xpc_null.
+static void SecXPCDictionarySetCFObject(xpc_object_t xdict, const char *key, CFTypeRef object)
+{
+    xpc_object_t xpc_obj = object ? _CFXPCCreateXPCObjectFromCFObject(object) : xpc_null_create();
+    xpc_dictionary_set_value(xdict, key, xpc_obj);
+    xpc_release(xpc_obj);
+}
+
+static bool SOSCloudTransportUpdateKeys(SOSCloudTransportRef transport,
+                                        bool getNewKeysOnly,
+                                        CFArrayRef alwaysKeys,
+                                        CFArrayRef afterFirstUnlockKeys,
+                                        CFArrayRef unlockedKeys,
+                                        CFErrorRef *error)
+{
+    __block bool success = true;
+    dispatch_queue_t processQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
+
+    CloudKeychainReplyBlock replyBlock = ^(CFDictionaryRef returnedValues, CFErrorRef returnedError)
+    {
+        if (returnedError) {
+            success = false;
+            if (error) {
+                *error = returnedError;
+                CFRetain(*error);
+            }
+        }
+        CFReleaseSafe(returnedError);
+    };
+
+    SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport;
+
+    xpc_object_t xkeysOfInterest = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_bool(xkeysOfInterest, kMessageKeyGetNewKeysOnly, getNewKeysOnly);
+    SecXPCDictionarySetCFObject(xkeysOfInterest, kMessageKeyKeysToGet, alwaysKeys);
+    SecXPCDictionarySetCFObject(xkeysOfInterest, kMessageKeyKeysRequireFirstUnlock, afterFirstUnlockKeys);
+    SecXPCDictionarySetCFObject(xkeysOfInterest, kMessageKeyKeysRequiresUnlocked, unlockedKeys);
+
+    xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
+    xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationRegisterKeysAndGet);
+    xpc_dictionary_set_value(message, kMessageKeyValue, xkeysOfInterest);
+    
+    talkWithKVS(xpcTransport, message, processQueue, replyBlock);
+    xpc_release(message);
+    xpc_release(xkeysOfInterest);
+    
+    return success;
+}
+
+static void SOSCloudTransportUnregisterKeys(SOSCloudTransportRef transport, CFArrayRef keysToUnregister, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport;
+    secdebug(SOSCKCSCOPE, "%@", keysToUnregister);
+    xpc_object_t xkeysOfInterest = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_object_t xkeysToUnregister = keysToUnregister ? _CFXPCCreateXPCObjectFromCFObject(keysToUnregister) : xpc_null_create();
+    xpc_dictionary_set_value(xkeysOfInterest, kMessageKeyKeysToGet, xkeysToUnregister);
+
+    xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
+    xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationUnregisterKeys);
+    xpc_dictionary_set_value(message, kMessageKeyValue, xkeysOfInterest);
+
+    talkWithKVS(xpcTransport, message, processQueue, replyBlock);
+    xpc_release(xkeysOfInterest);
+    xpc_release(xkeysToUnregister);
+    xpc_release(message);
+}
+
+static void SOSCloudTransportGetAll(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    secdebug(SOSCKCSCOPE, "start");
+    SOSCloudTransportGet(transport, NULL, processQueue, replyBlock);
+}
+
+static void SOSCloudTransportSync(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport;
+    secdebug(SOSCKCSCOPE, "start");
+    xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
+    xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationSynchronize);
+    talkWithKVS(xpcTransport, message, processQueue, replyBlock);
+    xpc_release(message);
+}
+
+static void SOSCloudTransportSyncAndWait(SOSCloudTransportRef transport, CFArrayRef keysToGet, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport;
+    secdebug(SOSCKCSCOPE, "%@", keysToGet);
+    xpc_object_t xkeysOfInterest = xpc_dictionary_create(NULL, NULL, 0);
+
+    xpc_object_t xkeysToRegister = keysToGet ? _CFXPCCreateXPCObjectFromCFObject(keysToGet) : xpc_null_create();
+    xpc_dictionary_set_value(xkeysOfInterest, kMessageKeyKeysToGet, xkeysToRegister);
+    xpc_release(xkeysToRegister);
+    xkeysToRegister = NULL;
+
+    xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
+    xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationSynchronizeAndWait);
+    xpc_dictionary_set_value(message, kMessageKeyValue, xkeysOfInterest);
+    xpc_release(xkeysOfInterest);
+    xkeysOfInterest = NULL;
+
+    talkWithKVS(xpcTransport, message, processQueue, replyBlock);
+    xpc_release(message);
+}
+
+static void SOSCloudTransportClearAll(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport;
+    secdebug(SOSCKCSCOPE, "start");
+    xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
+    xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationClearStore);
+    talkWithKVS(xpcTransport, message, processQueue, replyBlock);
+    xpc_release(message);
+}
+
+static void SOSCloudTransportRemoveObjectForKey(SOSCloudTransportRef transport, CFStringRef keyToRemove, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport;
+    secdebug(SOSCKCSCOPE, "start");
+    CFErrorRef error = NULL;
+    xpc_object_t message = NULL;
+    xpc_object_t xkeytoremove = NULL;
+    
+    require_action(keyToRemove, xit, error = makeError(kSOSObjectNotFoundError));
+
+    message = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
+    xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationRemoveObjectForKey);
+
+    xkeytoremove = _CFXPCCreateXPCObjectFromCFObject(keyToRemove);
+    require_action(xkeytoremove, xit, error = makeError(kSOSObjectCantBeConvertedToXPCObject));
+    xpc_dictionary_set_value(message, kMessageKeyKey, xkeytoremove);
+    xpc_release(xkeytoremove);
+
+    talkWithKVS(xpcTransport, message, processQueue, replyBlock);
+    xpc_release(message);
+    return;
+
+xit:
+    if(xkeytoremove)
+        xpc_release(xkeytoremove);
+    if(message)
+        xpc_release(message);
+    if (replyBlock)
+        replyBlock(NULL, error);
+    CFReleaseSafe(error);
+}
+
+static void SOSCloudTransportLocalNotification(SOSCloudTransportRef transport, CFStringRef messageToUser, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport;
+    secdebug(SOSCKCSCOPE, "start");
+    xpc_object_t xLocalNotificationDict = xpc_dictionary_create(NULL, NULL, 0);
+    char *headerKey = CFStringToCString(kCFUserNotificationAlertHeaderKey);
+    char *message = CFStringToCString(messageToUser);
+    xpc_dictionary_set_string(xLocalNotificationDict, headerKey, message);
+
+    xpc_object_t xpcmessage = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_uint64(xpcmessage, kMessageKeyVersion, kCKDXPCVersion);
+    xpc_dictionary_set_string(xpcmessage, kMessageKeyOperation, kOperationUILocalNotification);
+    xpc_dictionary_set_value (xpcmessage, kMessageKeyValue, xLocalNotificationDict);
+    xpc_release(xLocalNotificationDict);
+
+    talkWithKVS(xpcTransport, xpcmessage, processQueue, replyBlock);
+
+    free(headerKey);
+    free(message);
+    xpc_release(xpcmessage);
+}
+
+static void SOSCloudTransportSetParams(SOSCloudTransportRef transport, CFDictionaryRef paramsDict, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    secdebug(SOSCKCSCOPE, "start");
+    SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport;
+    
+    xpc_object_t xParamsDict = paramsDict ? _CFXPCCreateXPCObjectFromCFObject(paramsDict) : xpc_null_create();
+    
+    xpc_object_t xpcmessage = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_uint64(xpcmessage, kMessageKeyVersion, kCKDXPCVersion);
+    xpc_dictionary_set_string(xpcmessage, kMessageKeyOperation, kOperationSetParams);
+    xpc_dictionary_set_value (xpcmessage, kMessageKeyValue, xParamsDict);
+    xpc_release(xParamsDict);
+    
+    talkWithKVS(xpcTransport, xpcmessage, processQueue, replyBlock);
+    
+    xpc_release(xpcmessage);
+}
+
+static void SOSCloudTransportRequestSyncWithAllPeers(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    secdebug(SOSCKCSCOPE, "start");
+    SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport;
+    
+    xpc_object_t xpcmessage = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_uint64(xpcmessage, kMessageKeyVersion, kCKDXPCVersion);
+    xpc_dictionary_set_string(xpcmessage, kMessageKeyOperation, kOperationRequestSyncWithAllPeers);
+    
+    talkWithKVS(xpcTransport, xpcmessage, processQueue, replyBlock);
+    
+    xpc_release(xpcmessage);
+}
+
+static SOSCloudTransportRef SOSCloudTransportCreateXPCTransport(void)
+{
+    SOSXPCCloudTransportRef st;
+    st = calloc(1, sizeof(*st));
+    st->transport.put = SOSCloudTransportPut;
+    st->transport.registerKeys = SOSCloudTransportRegisterKeys;
+    st->transport.updateKeys = SOSCloudTransportUpdateKeys;
+    st->transport.unregisterKeys = SOSCloudTransportUnregisterKeys;
+    st->transport.get = SOSCloudTransportGet;
+    st->transport.getAll = SOSCloudTransportGetAll;
+    st->transport.synchronize = SOSCloudTransportSync;
+    st->transport.synchronizeAndWait = SOSCloudTransportSyncAndWait;
+    st->transport.clearAll = SOSCloudTransportClearAll;
+    st->transport.removeObjectForKey = SOSCloudTransportRemoveObjectForKey;
+    st->transport.localNotification = SOSCloudTransportLocalNotification;
+    st->transport.setParams = SOSCloudTransportSetParams;
+    st->transport.requestSyncWithAllPeers = SOSCloudTransportRequestSyncWithAllPeers;
+    SOSXPCCloudTransportInit(st);
+    return &st->transport;
+}
+
+// MARK: ---------- SOSCloudKeychain concrete client APIs ----------
+void SOSCloudKeychainSetItemsChangedBlock(CloudItemsChangedBlock itemsChangedBlock)
+{
+    secdebug(SOSCKCSCOPE, "start");
+    SOSCloudTransportSetItemsChangedBlock(SOSCloudTransportDefaultTransport(),
+                                          itemsChangedBlock);
+}
+
+// MARK: ---------- SOSCloudKeychain virtual client APIs ----------
+
+void SOSCloudKeychainPutObjectsInCloud(CFDictionaryRef objects, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
+    if (cTransportRef)
+        cTransportRef->put(cTransportRef, objects, processQueue, replyBlock);
+}
+
+void SOSCloudKeychainRegisterKeysAndGet(CFArrayRef keysToRegister, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock, CloudItemsChangedBlock notificationBlock)
+{
+    SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
+    if (cTransportRef)
+        cTransportRef->registerKeys(cTransportRef, keysToRegister, processQueue, replyBlock, notificationBlock);
+}
+
+bool SOSCloudKeychainUpdateKeys(bool getNewKeysOnly,
+                                CFArrayRef alwaysKeys,
+                                CFArrayRef afterFirstUnlockKeys,
+                                CFArrayRef unlockedKeys,
+                                CFErrorRef *error)
+{
+    SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
+    if (cTransportRef)
+        return cTransportRef->updateKeys(cTransportRef, getNewKeysOnly, alwaysKeys, afterFirstUnlockKeys, unlockedKeys, error);
+    
+    return false;
+}
+
+void SOSCloudKeychainUnRegisterKeys(CFArrayRef keysToUnregister, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
+    if (cTransportRef)
+        cTransportRef->unregisterKeys(cTransportRef, keysToUnregister, processQueue, replyBlock);
+}
+
+void SOSCloudKeychainHandleUpdate(CFDictionaryRef updates)
+{
+    SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
+    if (cTransportRef->itemsChangedBlock)
+        ((CloudItemsChangedBlock)cTransportRef->itemsChangedBlock)(updates);
+}
+
+void SOSCloudKeychainGetObjectsFromCloud(CFArrayRef keysToGet, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
+    if (cTransportRef)
+        cTransportRef->get(cTransportRef, keysToGet, processQueue, replyBlock);
+}
+
+void SOSCloudKeychainGetAllObjectsFromCloud(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
+    if (cTransportRef)
+        cTransportRef->getAll(cTransportRef, processQueue, replyBlock);
+}
+
+void SOSCloudKeychainSynchronizeAndWait(CFArrayRef keysToGet, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
+    if (cTransportRef)
+        cTransportRef->synchronizeAndWait(cTransportRef, keysToGet, processQueue, replyBlock);
+}
+
+//DEBUG ONLY
+void SOSCloudKeychainSynchronize(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
+    if (cTransportRef)
+        cTransportRef->synchronize(cTransportRef, processQueue, replyBlock);
+}
+
+//DEBUG ONLY
+void SOSCloudKeychainClearAll(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
+    if (cTransportRef)
+        cTransportRef->clearAll(cTransportRef, processQueue, replyBlock);
+}
+
+void SOSCloudKeychainRemoveObjectForKey(CFStringRef keyToRemove, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
+    if (cTransportRef)
+        cTransportRef->removeObjectForKey(cTransportRef, keyToRemove, processQueue, replyBlock);
+}
+
+void SOSCloudKeychainUserNotification(CFStringRef messageToUser, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
+    if (cTransportRef)
+        cTransportRef->localNotification(cTransportRef, messageToUser, processQueue, replyBlock);
+}
+
+void SOSCloudKeychainSetParams(CFDictionaryRef paramsDict, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
+    if (cTransportRef)
+        cTransportRef->setParams(cTransportRef, paramsDict, processQueue, replyBlock);
+}
+
+void SOSCloudKeychainRequestSyncWithAllPeers(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
+    if (cTransportRef)
+        cTransportRef->requestSyncWithAllPeers(cTransportRef, processQueue, replyBlock);
+}
+
+void SOSCloudKeychainSetCallbackMethodXPC(void)
+{
+    // Call this before making any other calls to CloudKeychainProxy
+    CFDictionaryRef paramsDict = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
+        kParamCallbackMethod, kParamCallbackMethodXPC, NULL);
+    dispatch_queue_t processQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
+    SOSCloudKeychainSetParams(paramsDict, processQueue, ^(CFDictionaryRef returnedValues, CFErrorRef error)
+        {
+            secerror("set params called back");
+        });
+    CFReleaseSafe(paramsDict);
+}
diff --git a/sec/SOSCircle/CKBridge/SOSCloudKeychainClient.h b/sec/SOSCircle/CKBridge/SOSCloudKeychainClient.h
new file mode 100644 (file)
index 0000000..3d1ae27
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2012 Apple Computer, Inc. All Rights Reserved.
+ * 
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+
+/*
+ * SOSCloudKeychainClient.h -  Implementation of the transport layer from CKBridge to SOSAccount/SOSCircle
+ */
+
+/*!
+    @header SOSCloudKeychainClient
+    The functions provided in SOSCloudTransport.h provide an interface
+    from CKBridge to SOSAccount/SOSCircle
+ */
+
+#ifndef _SOSCLOUDKEYCHAINCLIENT_H_
+#define _SOSCLOUDKEYCHAINCLIENT_H_
+
+#include <CoreFoundation/CFArray.h>
+#include <CoreFoundation/CFDictionary.h>
+#include <CoreFoundation/CFError.h>
+#include <dispatch/dispatch.h>
+
+__BEGIN_DECLS
+
+
+// MARK: ---------- SOSCloudTransport ----------
+
+enum
+{
+    kSOSObjectMallocFailed = 1,
+    kAddDuplicateEntry,
+    kSOSObjectNotFoundError = 1,
+    kSOSObjectCantBeConvertedToXPCObject,
+    kSOSOUnexpectedConnectionEvent,
+    kSOSOXPCErrorEvent,
+    kSOSOUnexpectedXPCEvent,
+    kSOSConnectionNotOpen
+};
+
+typedef void (^CloudItemsChangedBlock)(CFDictionaryRef values);
+typedef void (^CloudKeychainReplyBlock)(CFDictionaryRef returnedValues, CFErrorRef error);
+
+/* SOSCloudTransport protocol.  */
+typedef struct SOSCloudTransport *SOSCloudTransportRef;
+struct SOSCloudTransport
+{
+    void (*put)(SOSCloudTransportRef transport, CFDictionaryRef valuesToPut, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+    void (*registerKeys)(SOSCloudTransportRef transport, CFArrayRef keysToGet, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock, CloudItemsChangedBlock notificationBlock);
+    bool (*updateKeys)(SOSCloudTransportRef transport, bool getNewKeysOnly, CFArrayRef alwaysKeys, CFArrayRef afterFirstUnlockKeys, CFArrayRef unlockedKeys, CFErrorRef *error);
+
+    void (*unregisterKeys)(SOSCloudTransportRef transport, CFArrayRef keysToUnregister, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+
+    // Debug calls
+    void (*get)(SOSCloudTransportRef transport, CFArrayRef keysToGet, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+    void (*getAll)(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+    void (*synchronize)(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+    void (*synchronizeAndWait)(SOSCloudTransportRef transport, CFArrayRef keysToGet, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+
+    void (*clearAll)(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+    void (*removeObjectForKey)(SOSCloudTransportRef transport, CFStringRef keyToRemove, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+    void (*localNotification)(SOSCloudTransportRef transport, CFStringRef messageToUser, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+    void (*setParams)(SOSCloudTransportRef transport, CFDictionaryRef paramsDict, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+    void (*requestSyncWithAllPeers)(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+
+    const void *itemsChangedBlock;
+};
+
+/* Call this function before calling any other function in this header to provide
+   an alternate transport, the default transport talks to CloudKeychainProxy via xpc. */
+void SOSCloudKeychainSetTransport(SOSCloudTransportRef transport);
+
+
+/*!
+    @function SOSCloudKeychainRegisterKeysAndGet
+    @abstract Register a set of keys-of-interest and optionally return their current values
+    @param keysToGet An array of CFStringRef keys to get/register
+    @param processQueue The replyBlock will be called via dispatch_async on this queue
+    @param replyBlock This will be called via dispatch_async
+    @discussion The replyBlock will be called asynchronously with the current values of
+    the registered keys. If an error occured, the error parameter to the replyBlock will
+    be filled in with an error. The caller should call CFRetain on the returned dictionary.
+ */
+void SOSCloudKeychainRegisterKeysAndGet(CFArrayRef keysToGet, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock, CloudItemsChangedBlock notificationBlock);
+bool SOSCloudKeychainUpdateKeys(bool getNewKeysOnly,
+                                CFArrayRef alwaysKeys,
+                                CFArrayRef afterFirstUnlockKeys,
+                                CFArrayRef unlockedKeys,
+                                CFErrorRef *error);
+void SOSCloudKeychainUnRegisterKeys(CFArrayRef keysToUnregister, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+
+void SOSCloudKeychainPutObjectsInCloud(CFDictionaryRef objects, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+
+void SOSCloudKeychainSetItemsChangedBlock(CloudItemsChangedBlock itemsChangedBlock);
+
+void SOSCloudKeychainUserNotification(CFStringRef messageToUser, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+
+void SOSCloudKeychainHandleUpdate(CFDictionaryRef update);
+void SOSCloudKeychainSynchronizeAndWait(CFArrayRef keysToGet, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+
+// Debug only?
+
+void SOSCloudKeychainGetObjectsFromCloud(CFArrayRef keysToGet, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+void SOSCloudKeychainSynchronize(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+void SOSCloudKeychainClearAll(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+void SOSCloudKeychainRemoveObjectForKey(CFStringRef keyToRemove, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+void SOSCloudKeychainGetAllObjectsFromCloud(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+
+void SOSCloudKeychainSetParams(CFDictionaryRef paramsDict, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+void SOSCloudKeychainRequestSyncWithAllPeers(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+
+void SOSCloudKeychainSetCallbackMethodXPC(void);
+
+__END_DECLS
+
+#endif /* !_SOSCLOUDKEYCHAINCLIENT_H_ */
+
diff --git a/sec/SOSCircle/CKBridge/SOSCloudKeychainConstants.c b/sec/SOSCircle/CKBridge/SOSCloudKeychainConstants.c
new file mode 100644 (file)
index 0000000..291fb50
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2012 Apple Computer, Inc. All Rights Reserved.
+ * 
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+    This XPC service is essentially just a proxy to iCloud KVS, which exists since
+    the main security code cannot link against Foundation.
+    
+    See sendTSARequestWithXPC in tsaSupport.c for how to call the service
+    
+    The client of an XPC service does not get connection events, nor does it
+    need to deal with transactions.
+*/
+
+//------------------------------------------------------------------------------------------------
+
+
+#include <CoreFoundation/CoreFoundation.h>
+#include "SOSCloudKeychainConstants.h"
+
+const uint64_t kCKDXPCVersion = 1;
+
+// seems like launchd looks for the BundleIdentifier, not the name
+const char *xpcServiceName = "com.apple.security.cloudkeychainproxy3";   //"CloudKeychainProxy";
+
+const char *kMessageKeyOperation = "operation";
+const char *kMessageKeyKey = "key";
+const char *kMessageKeyValue = "value";
+const char *kMessageKeyError = "error";
+const char *kMessageKeyVersion = "version";
+const char *kMessageKeyGetNewKeysOnly = "GetNewKeysOnly";
+const char *kMessageKeyKeysToGet = "KeysToGet";
+const char *kMessageKeyKeysRequireFirstUnlock = "KeysRequireFirstUnlock";
+const char *kMessageKeyKeysRequiresUnlocked = "KeysRequiresUnlocked";
+const char *kMessageKeyClientIdentifier = "ClientIdentifier";
+const char *kMessageKeyNotificationFlags = "NotificationFlags";
+
+const char *kMessageOperationItemChanged = "ItemChanged";
+
+const char *kOperationClearStore = "ClearStore";
+const char *kOperationSynchronize = "Synchronize";
+const char *kOperationSynchronizeAndWait = "SynchronizeAndWait";
+
+const char *kOperationPUTDictionary = "PUTDictionary";
+const char *kOperationGETv2 = "GETv2";
+const char *kOperationRemoveObjectForKey = "RemoveObjectForKey";
+
+const char *kOperationRegisterKeysAndGet = "RegisterKeysAndGet";
+const char *kOperationUnregisterKeys = "UnregisterKeys";
+
+const char *kOperationUILocalNotification = "UILocalNotification";
+
+const char *kOperationSetParams = "SetParams";
+const char *kOperationRequestSyncWithAllPeers = "requestSyncWithAllPeers";
+
+const CFStringRef kParamCallbackMethod = CFSTR("CallbackMethod");
+const CFStringRef kParamCallbackMethodSecurityd = CFSTR("CallbackMethodSecurityd");
+const CFStringRef kParamCallbackMethodXPC = CFSTR("CallbackMethodXPC");
+
+/*
+    The values for the KVS notification and KVS Store ID must be identical to the values
+    in syncdefaultsd (SYDApplication.m). The notification string is used in two places:
+    it is in our launchd plist (com.apple.security.cloudkeychainproxy.plist) as the
+    LaunchEvents/com.apple.notifyd.matching key and is examined in code in the stream event handler.
+
+    The KVS Store ID (_SYDRemotePreferencesStoreIdentifierKey in SYDApplication.m) must
+    be in the entitlements. The bundle identifier is (com.apple.security.cloudkeychainproxy3)
+    is used by installInfoForBundleIdentifiers in SYDApplication.m and is used to look up our
+    daemon to figure out what store to use, etc.
+*/
+
+const char * const kCloudKeychainStorechangeChangeNotification = "com.apple.security.cloudkeychainproxy.kvstorechange3"; // was "com.apple.security.cloudkeychain.kvstorechange" for seeds
+
+const char *kNotifyTokenForceUpdate = "com.apple.security.cloudkeychain.forceupdate";
diff --git a/sec/SOSCircle/CKBridge/SOSCloudKeychainConstants.h b/sec/SOSCircle/CKBridge/SOSCloudKeychainConstants.h
new file mode 100644 (file)
index 0000000..ad6ad60
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2012 Apple Computer, Inc. All Rights Reserved.
+ * 
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+    These constants are used by the XPC service and its clients.
+*/
+
+#ifndef        _CKDXPC_CONSTANTS_H_
+#define _CKDXPC_CONSTANTS_H_
+
+__BEGIN_DECLS
+
+extern const char *xpcServiceName;
+
+extern const char *kMessageKeyOperation;
+extern const char *kMessageKeyKey;
+extern const char *kMessageKeyValue;
+extern const char *kMessageKeyError;
+extern const char *kMessageKeyVersion;
+extern const char *kMessageKeyGetNewKeysOnly;
+extern const char *kMessageKeyKeysToGet;
+extern const char *kMessageKeyKeysRequireFirstUnlock;
+extern const char *kMessageKeyKeysRequiresUnlocked;
+extern const char *kMessageOperationItemChanged;
+extern const char *kOperationRemoveObjectForKey;
+extern const char *kMessageKeyNotificationFlags;
+
+extern const char *kOperationClearStore;
+extern const char *kOperationSynchronize;
+extern const char *kOperationSynchronizeAndWait;
+extern const char *kOperationPUTDictionary;
+extern const char *kOperationGETv2;
+extern const char *kOperationRegisterKeysAndGet;
+extern const char *kOperationUnregisterKeys;
+extern const char *kMessageKeyClientIdentifier;
+
+extern const uint64_t kCKDXPCVersion;
+
+extern const char *kOperationUILocalNotification;
+extern const char *kOperationSetParams;
+extern const char *kOperationRequestSyncWithAllPeers;
+
+extern const CFStringRef kParamCallbackMethod;
+extern const CFStringRef kParamCallbackMethodSecurityd;
+extern const CFStringRef kParamCallbackMethodXPC;
+
+extern const char * const kCloudKeychainStorechangeChangeNotification;
+
+extern const char *kNotifyTokenForceUpdate;
+
+__END_DECLS
+
+#endif /* _CKDXPC_CONSTANTS_H_ */
+
diff --git a/sec/SOSCircle/CKBridge/SOSCloudTransport.c b/sec/SOSCircle/CKBridge/SOSCloudTransport.c
new file mode 100644 (file)
index 0000000..973179a
--- /dev/null
@@ -0,0 +1,558 @@
+/*
+ * Copyright (c) 2012 Apple Computer, Inc. All Rights Reserved.
+ * 
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+
+/*
+ * SOSCloudTransport.c -  Implementation of the transport layer from CKBridge to SOSAccount/SOSCircle
+ */
+/*
+    This XPC service is essentially just a proxy to iCloud KVS, which exists since
+    the main security code cannot link against Foundation.
+    
+    See sendTSARequestWithXPC in tsaSupport.c for how to call the service
+    
+    The client of an XPC service does not get connection events, nor does it
+    need to deal with transactions.
+*/
+
+#include <SOSCloudTransport.h>
+#include <utilities/SecCFError.h>
+#include <dispatch/dispatch.h>
+#include <stdlib.h>
+
+static CFStringRef sErrorDomain = CFSTR("com.apple.security.sos.transport.error");
+
+enum
+{
+    kSOSObjectMallocFailed = 1,
+    kAddDuplicateEntry,
+    kSOSObjectNotFoundError = 1,
+    kSOSObjectCantBeConvertedToXPCObject,
+    kSOSOUnexpectedConnectionEvent,
+    kSOSOUnexpectedXPCEvent,
+    kSOSConnectionNotOpen
+};
+
+/* SOSCloudTransport, a statically initialized transport singleton. */
+struct SOSCloudTransport
+{
+    struct CloudTransport t;
+    unsigned version;
+    CFStringRef kvsID;
+    dispatch_once_t once;
+};
+
+#pragma mark ---------- Communication with XPC ----------
+
+
+//------------------------------------------------------------------------------------------------
+
+#include <AssertMacros.h>
+
+#include <xpc/xpc.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreFoundation/CFXPCBridge.h>
+#include <sysexits.h>
+#include <syslog.h>
+
+#include <utilities/debugging.h>
+#include <utilities/SecCFWrappers.h>
+
+#include "CKConstants.h"
+
+#define zsecdebug(format...)  secerror(format)
+
+static xpc_connection_t serviceConnection = NULL;
+static dispatch_queue_t xpc_queue = NULL;
+static CloudKeychainReplyBlock itemsChangedBlock;
+
+static bool handle_xpc_event(const xpc_connection_t peer, xpc_object_t event);
+static bool xpc_event_filter(const xpc_connection_t peer, xpc_object_t event, CFErrorRef *error);
+
+// extern CFTypeRef _CFXPCCreateCFObjectFromXPCObject(xpc_object_t xo);
+// extern xpc_object_t _CFXPCCreateXPCObjectFromCFObject(CFTypeRef cf);
+
+// Debug
+static void describeXPCObject(char *prefix, xpc_object_t object);
+static void describeXPCType(char *prefix, xpc_type_t xtype);
+
+
+
+#define WANTXPCREPLY 0
+
+#pragma mark ----- utilities -----
+
+static CFErrorRef makeError(CFIndex which)
+{
+    CFDictionaryRef userInfo = NULL;
+    return CFErrorCreate(kCFAllocatorDefault, sErrorDomain, which, userInfo);
+}
+
+#pragma mark ----- SPI -----
+
+static void initXPCConnection()
+{
+    zsecdebug("initXPCConnection\n");
+    
+    xpc_queue = dispatch_queue_create(xpcServiceName, DISPATCH_QUEUE_SERIAL);
+
+    serviceConnection = xpc_connection_create_mach_service(xpcServiceName, xpc_queue, 0);
+
+//    serviceConnection = xpc_connection_create(xpcServiceName, xpc_queue);
+    zsecdebug("serviceConnection: %p\n", serviceConnection);
+
+    xpc_connection_set_event_handler(serviceConnection, ^(xpc_object_t event)
+    {
+        zsecdebug("xpc_connection_set_event_handler\n");
+        handle_xpc_event(serviceConnection, event);
+    });
+
+    xpc_connection_resume(serviceConnection);
+    xpc_retain(serviceConnection);
+}
+
+#if 0   // unused
+static void closeXPCConnection()
+{
+    zsecdebug("closeXPCConnection\n");
+    xpc_release(serviceConnection);
+}
+#endif
+
+static void setItemsChangedBlock(CloudKeychainReplyBlock icb)
+{
+    if (icb != itemsChangedBlock)
+    {
+        if (itemsChangedBlock)
+            Block_release(itemsChangedBlock);
+        itemsChangedBlock = icb;
+        Block_copy(itemsChangedBlock);
+    }
+}
+
+// typedef void (^CloudKeychainReplyBlock)(CFDictionaryRef returnedValues, CFErrorRef error);
+
+static bool handle_xpc_event(const xpc_connection_t peer, xpc_object_t event)
+{
+    CFErrorRef localError = NULL;
+    zsecdebug(">>>>> handle_connection_event via event_handler <<<<<\n");
+    bool result = false;
+    if ((result = xpc_event_filter(peer, event, &localError)))
+    {
+        const char *operation = xpc_dictionary_get_string(event, kMessageKeyOperation);
+        if (!operation || strcmp(operation, kMessageOperationItemChanged))  // some op we don't care about
+        {
+            zsecdebug("operation: %s", operation);
+            return result;
+        }
+        
+        xpc_object_t xrv = xpc_dictionary_get_value(event, kMessageKeyValue);
+        if (!xrv)
+        {
+            zsecdebug("xrv null for kMessageKeyValue");
+            return result;
+        }
+        describeXPCObject("xrv", xrv);
+        
+        CFDictionaryRef returnedValues = _CFXPCCreateCFObjectFromXPCObject(xrv);
+        zsecdebug("returnedValues: %@", returnedValues);
+
+        if (itemsChangedBlock)
+            itemsChangedBlock(returnedValues, localError);
+    }
+    CFReleaseSafe(localError);
+
+    return result;
+}
+
+static bool xpc_event_filter(const xpc_connection_t peer, xpc_object_t event, CFErrorRef *error)
+{
+    // return true if the type is XPC_TYPE_DICTIONARY (and therefore something more to process)
+    zsecdebug("handle_connection_event\n");
+    xpc_type_t xtype = xpc_get_type(event);
+    describeXPCType("handle_xpc_event", xtype);
+    if (XPC_TYPE_CONNECTION == xtype)
+    {
+        zsecdebug("handle_xpc_event: XPC_TYPE_CONNECTION (unexpected)");
+        // The client of an XPC service does not get connection events
+        // For nwo, we log this and keep going
+        describeXPCObject("handle_xpc_event: XPC_TYPE_CONNECTION, obj : ", event);
+#if 0
+        if (error)
+            *error = makeError(kSOSOUnexpectedConnectionEvent); // FIX
+        assert(true);
+#endif
+    }
+    else
+    if (XPC_TYPE_ERROR == xtype)
+    {
+        zsecdebug("default: xpc error: %s\n", xpc_dictionary_get_string(event, XPC_ERROR_KEY_DESCRIPTION));
+        if (error)
+            *error = makeError(kSOSOUnexpectedConnectionEvent); // FIX
+    }
+    else
+    if (XPC_TYPE_DICTIONARY == xtype)
+    {
+        zsecdebug("received dictionary event %p\n", event);
+        return true;
+    }
+    else
+    {
+        zsecdebug("default: unexpected connection event %p\n", event);
+        describeXPCObject("handle_xpc_event: obj : ", event);
+        if (error)
+            *error = makeError(kSOSOUnexpectedXPCEvent);
+    }
+    return false;
+}
+
+static void talkWithKVS(xpc_object_t message, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    secerror("start");
+    __block CFErrorRef error = NULL;
+    __block CFTypeRef object = NULL;
+    
+    dispatch_block_t callback = ^{
+            secerror("callback");
+            if (replyBlock)
+                replyBlock(object, error);
+    //        if (object)
+     //           CFRelease(object);
+            if (error)
+            {
+                secerror("callback error: %@", error);
+     //           CFRelease(error);
+            }
+            dispatch_release(processQueue);
+        };
+    
+    require_action(serviceConnection, xit, error = makeError(kSOSConnectionNotOpen));
+    require_action(message, xit, error = makeError(kSOSObjectNotFoundError));
+    dispatch_retain(processQueue);
+    secerror("xpc_connection_send_message_with_reply called");
+    
+    Block_copy(callback);   // TODO -- this should not be needed, I think
+    
+//#if !WANTXPCREPLY
+ //   xpc_connection_send_message(serviceConnection, message);            // Send message; don't want a reply
+//#else
+    xpc_connection_send_message_with_reply(serviceConnection, message, xpc_queue, ^(xpc_object_t reply)
+        {
+            secerror("xpc_connection_send_message_with_reply handler called back");
+            if (xpc_event_filter(serviceConnection, reply, &error) && reply)
+            {
+                describeXPCObject("getValuesFromKVS: reply : ", reply);
+                xpc_object_t xrv = xpc_dictionary_get_value(reply, kMessageKeyValue);
+                if (xrv)
+                {
+                    describeXPCObject("talkWithKVS: xrv: ", xrv);
+                    /*
+                        * The given XPC object must be one that was previously returned by
+                        * _CFXPCCreateXPCMessageWithCFObject().
+                    */
+                    object = _CFXPCCreateCFObjectFromXPCObject(xrv);   // CF object is retained; release in callback
+                    secerror("converted CF object: %@", object);
+                }
+                else
+                    secerror("missing value reply");
+            }
+            dispatch_async(processQueue, callback);
+        });
+//#endif
+
+//sleep(5);   // DEBUG DEBUG FIX
+ //   xpc_release(message);
+    return;
+    
+xit:
+    secerror("talkWithKVS error: %@", error);
+    if (replyBlock)
+        dispatch_async(processQueue, callback);
+}
+
+static void putValuesWithXPC(CFDictionaryRef values, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    CFErrorRef error = NULL;
+
+    require_action(values, xit, error = makeError(kSOSObjectNotFoundError));
+
+    xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
+    xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationPUTDictionary);
+    
+    xpc_object_t xobject = _CFXPCCreateXPCObjectFromCFObject(values);
+    require_action(xobject, xit, error = makeError(kSOSObjectCantBeConvertedToXPCObject));
+    xpc_dictionary_set_value(message, kMessageKeyValue, xobject);
+    
+    talkWithKVS(message, processQueue, replyBlock);
+    return;
+
+xit:
+    if (replyBlock)
+        replyBlock(NULL, error);
+}
+
+static void synchronizeKVS(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
+    xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationSynchronize);
+    talkWithKVS(message, processQueue, replyBlock);
+}
+
+static void clearAll(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
+    xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationClearStore);
+    talkWithKVS(message, processQueue, replyBlock);
+}
+
+static void getValuesFromKVS(CFArrayRef keysToGet, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    secerror("start");
+    CFErrorRef error = NULL;
+    xpc_object_t xkeysOfInterest = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_object_t xkeysToGet = keysToGet ? _CFXPCCreateXPCObjectFromCFObject(keysToGet) : xpc_null_create();
+
+    require_action(xkeysToGet, xit, error = makeError(kSOSObjectNotFoundError));
+
+    xpc_dictionary_set_value(xkeysOfInterest, kMessageKeyKeysToGet, xkeysToGet);
+
+    xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
+    xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationGETv2);
+    xpc_dictionary_set_value(message, kMessageKeyValue, xkeysOfInterest);
+    
+    talkWithKVS(message, processQueue, replyBlock);
+
+    xpc_release(message);
+    return;
+    
+xit:
+    if (replyBlock)
+        replyBlock(NULL, error);
+}
+
+static void registerKeysForKVS(CFArrayRef keysToGet, CFStringRef clientIdentifier, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    secerror("start");
+
+    xpc_object_t xkeysOfInterest = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_object_t xkeysToRegister = keysToGet ? _CFXPCCreateXPCObjectFromCFObject(keysToGet) : xpc_null_create();
+    xpc_dictionary_set_value(xkeysOfInterest, kMessageKeyKeysToGet, xkeysToRegister);
+
+    xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
+    xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationRegisterKeysAndGet);
+    xpc_dictionary_set_value(message, kMessageKeyValue, xkeysOfInterest);
+    
+    if (clientIdentifier)
+    {
+        char *clientid = CFStringToCString(clientIdentifier);
+        if (clientid)
+        {
+            xpc_dictionary_set_string(message, kMessageKeyClientIdentifier, clientid);
+            free(clientid);
+        }
+    }
+
+    setItemsChangedBlock(replyBlock);
+    talkWithKVS(message, processQueue, replyBlock);
+
+    xpc_release(message);
+}
+
+static void unregisterKeysForKVS(CFArrayRef keysToUnregister, CFStringRef clientIdentifier, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+#if NO_SERVERz
+    if (gCKD->unregisterKeys) {
+        return gCKD->unregisterKeys(...);
+    }
+#endif
+
+    secerror("start");
+
+    xpc_object_t xkeysOfInterest = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_object_t xkeysToUnregister = keysToUnregister ? _CFXPCCreateXPCObjectFromCFObject(keysToUnregister) : xpc_null_create();
+    xpc_dictionary_set_value(xkeysOfInterest, kMessageKeyKeysToGet, xkeysToUnregister);
+
+    xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
+    xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationUnregisterKeys);
+    xpc_dictionary_set_value(message, kMessageKeyValue, xkeysOfInterest);
+    
+    if (clientIdentifier)
+    {
+        char *clientid = CFStringToCString(clientIdentifier);
+        if (clientid)
+        {
+            xpc_dictionary_set_string(message, kMessageKeyClientIdentifier, clientid);
+            free(clientid);
+        }
+    }
+
+    talkWithKVS(message, processQueue, replyBlock);
+
+    xpc_release(message);
+}
+
+#pragma mark ----- DEBUG Utilities -----
+
+//------------------------------------------------------------------------------------------------
+//          DEBUG only
+//------------------------------------------------------------------------------------------------
+
+static void describeXPCObject(char *prefix, xpc_object_t object)
+{
+//#ifndef NDEBUG
+    // This is useful for debugging.
+    if (object)
+    {
+      char *desc = xpc_copy_description(object);
+    zsecdebug("%s%s\n", prefix, desc);
+    free(desc);
+    }
+    else
+        zsecdebug("%s<NULL>\n", prefix);
+//#endif
+}
+
+static void describeXPCType(char *prefix, xpc_type_t xtype)
+{
+    /*
+        Add these as necessary:
+        XPC_TYPE_ENDPOINT
+        XPC_TYPE_NULL
+        XPC_TYPE_BOOL
+        XPC_TYPE_INT64
+        XPC_TYPE_UINT64
+        XPC_TYPE_DOUBLE
+        XPC_TYPE_DATE
+        XPC_TYPE_DATA
+        XPC_TYPE_STRING
+        XPC_TYPE_UUID
+        XPC_TYPE_FD
+        XPC_TYPE_SHMEM
+        XPC_TYPE_ARRAY
+    */
+    
+#ifndef NDEBUG
+    // This is useful for debugging.
+    char msg[256]={0,};
+    if (XPC_TYPE_CONNECTION == xtype)
+        strcpy(msg, "XPC_TYPE_CONNECTION");
+    else if (XPC_TYPE_ERROR == xtype)
+        strcpy(msg, "XPC_TYPE_ERROR");
+    else if  (XPC_TYPE_DICTIONARY == xtype)
+        strcpy(msg, "XPC_TYPE_DICTIONARY");
+    else
+        strcpy(msg, "<unknown>");
+
+    zsecdebug("%s type:%s\n", prefix, msg);
+#endif
+}
+
+#pragma mark ---------- SOSCloudTransport ----------
+
+static void SOSCloudTransportPut(SOSCloudTransportRef transport, CFDictionaryRef valuesToPut, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    secerror("%@", valuesToPut);
+    putValuesWithXPC(valuesToPut, processQueue, replyBlock);
+}
+
+static void SOSCloudTransportGet(SOSCloudTransportRef transport, CFArrayRef keysToGet, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+//    struct SOSCloudTransport *t = (struct SOSCloudTransport *)transport;
+    /* Get from KVS */
+    secerror("%@", keysToGet);
+    getValuesFromKVS(keysToGet, processQueue, replyBlock);
+}
+
+static void SOSCloudTransportRegisterKeys(SOSCloudTransportRef transport, CFArrayRef keysToGet, CFStringRef clientIdentifier, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    /* RegisterKeys with KVS */
+    registerKeysForKVS(keysToGet, clientIdentifier, processQueue, replyBlock);
+}
+
+static void SOSCloudTransportUnregisterKeys(SOSCloudTransportRef transport, CFArrayRef keysToUnregister, CFStringRef clientIdentifier, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    /* unregister from KVS */
+    unregisterKeysForKVS(keysToUnregister, clientIdentifier, processQueue, replyBlock);
+}
+
+static void SOSCloudTransportGetAll(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    /* Get from KVS */
+    getValuesFromKVS(NULL, processQueue, replyBlock);
+}
+
+static void SOSCloudTransportSync(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+//    struct SOSCloudTransport *t = (struct SOSCloudTransport *)transport;
+    /* Sync KVS */
+    synchronizeKVS(processQueue, replyBlock);
+}
+
+static void SOSCloudTransportClearAll(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+//    struct SOSCloudTransport *t = (struct SOSCloudTransport *)transport;
+    /* clear KVS */
+    clearAll(processQueue, replyBlock);
+}
+
+static void SOSCloudTransportSetItemsChangedBlock(SOSCloudTransportRef transport, CloudKeychainReplyBlock itemsChangedBlock)
+{
+//    struct SOSCloudTransport *t = (struct SOSCloudTransport *)transport;
+    /* clear KVS */
+    setItemsChangedBlock(itemsChangedBlock);
+}
+
+static void SOSCloudTransportInit(void *ctx)
+{
+    struct SOSCloudTransport *st = (struct SOSCloudTransport *)ctx;
+    st->t.put = SOSCloudTransportPut;
+    st->t.registerKeys = SOSCloudTransportRegisterKeys;
+    st->t.unregisterKeys = SOSCloudTransportUnregisterKeys;
+    st->t.get = SOSCloudTransportGet;
+    st->t.getAll = SOSCloudTransportGetAll;
+    st->t.synchronize = SOSCloudTransportSync;
+    st->t.clearAll = SOSCloudTransportClearAll;
+    st->t.setItemsChangedBlock = SOSCloudTransportSetItemsChangedBlock;
+    
+    if (st->kvsID)
+        CFRetain(st->kvsID);
+    
+    st->version = 0;
+    initXPCConnection();
+}
+
+SOSCloudTransportRef SOSCloudTransportDefaultTransport(CFStringRef kvsID, uint32_t options)
+{
+    static struct SOSCloudTransport cloudTransport = {};
+    cloudTransport.kvsID = kvsID;
+    dispatch_once_f(&cloudTransport.once, &cloudTransport, SOSCloudTransportInit);
+    return &cloudTransport.t;
+}
+
+
diff --git a/sec/SOSCircle/CKBridge/SOSCloudTransport.h b/sec/SOSCircle/CKBridge/SOSCloudTransport.h
new file mode 100644 (file)
index 0000000..477d12b
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2012 Apple Computer, Inc. All Rights Reserved.
+ * 
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+
+/*
+ * SOSCloudTransport.h -  Implementation of the transport layer from CKBridge to SOSAccount/SOSCircle
+ */
+
+/*!
+    @header SOSCloudTransport
+    The functions provided in SOSCloudTransport.h provide an interface
+    from CKBridge to SOSAccount/SOSCircle
+ */
+
+#ifndef _SOSCLOUDTRANSPORT_H_
+#define _SOSCLOUDTRANSPORT_H_
+
+#include <dispatch/dispatch.h>
+
+#include "SOSCloudKeychainClient.h"
+
+__BEGIN_DECLS
+
+/* CKPTransport. */
+
+/* CKPTransport protocol (not opaque). */
+typedef struct CloudTransport *SOSCloudTransportRef;
+struct CloudTransport
+{
+    void (*put)(SOSCloudTransportRef transport, CFDictionaryRef valuesToPut, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+    
+    void (*registerKeys)(SOSCloudTransportRef transport, CFArrayRef keysToGet, CFStringRef clientIdentifier, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+    void (*unregisterKeys)(SOSCloudTransportRef transport, CFArrayRef keysToUnregister, CFStringRef clientIdentifier, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+    void (*setItemsChangedBlock)(SOSCloudTransportRef transport, CloudKeychainReplyBlock icb);
+
+    // Debug calls
+    void (*get)(SOSCloudTransportRef transport, CFArrayRef keysToGet, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+    void (*getAll)(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); 
+    void (*synchronize)(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+    void (*clearAll)(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+};
+
+/* Return the singleton cloud transport instance. */
+/* pass NULL for kvsID to use real KVS */
+SOSCloudTransportRef SOSCloudTransportDefaultTransport(CFStringRef kvsID, uint32_t options);
+
+__END_DECLS
+
+#endif /* !_SOSCLOUDTRANSPORT_H_ */
diff --git a/sec/SOSCircle/CloudKeychainProxy/CKDKVSProxy.h b/sec/SOSCircle/CloudKeychainProxy/CKDKVSProxy.h
new file mode 100644 (file)
index 0000000..aad1a9d
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2012 Apple Computer, Inc. All Rights Reserved.
+ * 
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+//
+//  CKDKVSProxy.h
+//  ckd-xpc
+
+#import <Foundation/Foundation.h>
+#import <dispatch/queue.h>
+#import <xpc/xpc.h>
+
+#import <utilities/debugging.h>
+
+#import "SOSCloudKeychainConstants.h"
+#import "SOSCloudKeychainClient.h"
+
+#define XPROXYSCOPE "proxy"
+
+@interface UbiqitousKVSProxy  : NSObject
+{
+    id currentiCloudToken;
+    CloudItemsChangedBlock itemsChangedCallback;
+    int callbackMethod;
+}
+@property (retain, nonatomic) NSString *myID;
+@property (retain, nonatomic) NSArray *keysToRead;
+@property (retain, nonatomic) NSArray *keysToWrite;
+@property (retain, nonatomic) NSArray *keysReadWrite;
+
+@property (retain, nonatomic) NSSet *alwaysKeys;
+@property (retain, nonatomic) NSSet *firstUnlockKeys;
+@property (retain, nonatomic) NSSet *unlockedKeys;
+@property (retain, nonatomic) NSMutableSet *pendingKeys;
+@property (retain, nonatomic) NSMutableSet *shadowPendingKeys;
+@property (atomic) bool syncWithPeersPending;
+@property (atomic) bool shadowSyncWithPeersPending;
+@property (atomic) bool inCallout;
+@property (atomic) bool unlockedSinceBoot;
+@property (atomic) bool isLocked;
+@property (atomic) bool seenKVSStoreChange;
+
+@property (atomic) dispatch_source_t syncTimer;
+@property (atomic) bool syncTimerScheduled;
+@property (atomic) dispatch_time_t deadline;
+@property (atomic) dispatch_time_t lastSyncTime;
+
++ (UbiqitousKVSProxy *) sharedKVSProxy;
+- (NSString *)description;
+- (id)init;
+- (void)streamEvent:(xpc_object_t)notification;
+- (void)setItemsChangedBlock:(CloudItemsChangedBlock)itemsChangedBlock;
+
+- (void)setObject:(id)obj forKey:(id)key;
+- (id)get:(id)key;
+- (NSDictionary *)getAll;
+- (void)requestSynchronization:(bool)force;
+- (void)waitForSynchronization:(NSArray *)keys handler:(void (^)(NSDictionary *values, NSError *err))handler;
+- (void)clearStore;
+- (void)setObjectsFromDictionary:(NSDictionary *)values;
+- (void)removeObjectForKey:(NSString *)keyToRemove;
+- (void)processAllItems;
+- (void)requestSyncWithAllPeers;
+
+- (NSUbiquitousKeyValueStore *)cloudStore;
+
+- (NSSet*) keysForCurrentLockState;
+- (NSSet*) filterKeySetWithLockState: (NSSet*) startingSet;
+- (NSDictionary *)registerKeysAndGet:(BOOL)getNewKeysOnly always:(NSArray *)keysToRegister reqFirstUnlock:(NSArray *)reqFirstUnlock reqUnlocked:(NSArray *)reqUnlocked;
+
+- (NSDictionary *)localNotification:(NSDictionary *)localNotificationDict outFlags:(int64_t *)outFlags;
+- (void)processKeyChangedEvent:(NSDictionary *)keysChangedInCloud;
+- (NSMutableDictionary *)copyChangedValues:(NSSet *)keysOfInterest;
+- (void)setParams:(NSDictionary *)paramsDict;
+
+@end
diff --git a/sec/SOSCircle/CloudKeychainProxy/CKDKVSProxy.m b/sec/SOSCircle/CloudKeychainProxy/CKDKVSProxy.m
new file mode 100644 (file)
index 0000000..b5947a1
--- /dev/null
@@ -0,0 +1,869 @@
+/*
+ * Copyright (c) 2012-2013 Apple Computer, Inc. All Rights Reserved.
+ * 
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+//
+//  CKDKVSProxy.m
+//  ckd-xpc
+//
+
+#import <Foundation/NSUbiquitousKeyValueStore.h>
+#import <Foundation/NSUbiquitousKeyValueStore_Private.h>
+#import <Foundation/NSArray.h>
+#import <Foundation/Foundation.h>
+
+#import <Security/SecBasePriv.h>
+#import <Security/SecItemPriv.h>
+#import <utilities/debugging.h>
+#import <notify.h>
+
+#import "CKDKVSProxy.h"
+#import "CKDPersistentState.h"
+#import "CKDUserInteraction.h"
+
+#import "SOSARCDefines.h"
+
+#include <SecureObjectSync/SOSAccount.h>
+#include <SecureObjectSync/SOSCloudCircleInternal.h>
+#include "SOSCloudKeychainConstants.h"
+
+#include <utilities/SecAKSWrappers.h>
+#include <utilities/SecCFRelease.h>
+
+#define SOSCKCSCOPE "sync"
+
+/*
+    The total space available in your app’s iCloud key-value storage is 1 MB.
+    The maximum number of keys you can specify is 1024, and the size limit for
+    each value associated with a key is 1 MB. So, for example, if you store a
+    single large value of 1 MB for a single key, that consumes your total
+    available storage. If you store 1 KB of data for each key, you can use
+    1,000 key-value pairs.
+*/
+
+static const char *kStreamName = "com.apple.notifyd.matching";
+
+
+static NSString *kKeyAlwaysKeys = @"AlwaysKeys";
+static NSString *kKeyFirstUnlockKeys = @"FirstUnlockKeys";
+static NSString *kKeyUnlockedKeys = @"UnlockedKeys";
+static NSString *kKeyPendingKeys = @"PendingKeys";
+static NSString *kKeyUnsentChangedKeys = @"unsentChangedKeys";
+static NSString *kKeyUnlockNotificationRequested = @"unlockNotificationRequested";
+static NSString *kKeySyncWithPeersPending = @"SyncWithPeersPending";
+
+enum
+{
+    kCallbackMethodSecurityd = 0,
+    kCallbackMethodXPC = 1,
+};
+
+static const int64_t kMinSyncDelay = (NSEC_PER_MSEC * 500);
+static const int64_t kMaxSyncDelay = (NSEC_PER_SEC * 5);
+static const int64_t kMinSyncInterval = (NSEC_PER_SEC * 15);
+static const int64_t kSyncTimerLeeway = (NSEC_PER_MSEC * 250);
+
+@interface NSUbiquitousKeyValueStore (NSUbiquitousKeyValueStore_PrivateZ)
+- (void) _synchronizeWithCompletionHandler:(void (^)(NSError *error))completionHandler;
+
+/*
+// SPI For Security
+- (void) synchronizeWithCompletionHandler:(void (^)(NSError *error))completionHandler;
+ */
+
+@end
+
+@implementation UbiqitousKVSProxy
+
+
+- (void)persistState
+{
+    [SOSPersistentState setRegisteredKeys:[self exportKeyInterests]];
+}
+
++ (UbiqitousKVSProxy *) sharedKVSProxy
+{
+    static UbiqitousKVSProxy *sharedKVSProxy;
+    if (!sharedKVSProxy) {
+        static dispatch_once_t onceToken;
+        dispatch_once(&onceToken, ^{
+            sharedKVSProxy = [[self alloc] init];
+        });
+    }
+    return sharedKVSProxy;
+}
+
+- (id)init
+{
+    if (self = [super init])
+    {
+        secnotice("event", "%@ start", self);
+
+        _syncTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
+        dispatch_source_set_timer(_syncTimer, DISPATCH_TIME_FOREVER, DISPATCH_TIME_FOREVER, kSyncTimerLeeway);
+        dispatch_source_set_event_handler(_syncTimer, ^{
+            [self timerFired];
+        });
+        dispatch_resume(_syncTimer);
+
+        [[NSNotificationCenter defaultCenter]
+            addObserver: self
+               selector: @selector (iCloudAccountAvailabilityChanged:)
+                   name: NSUbiquityIdentityDidChangeNotification
+                 object: nil];
+        
+        [[NSNotificationCenter defaultCenter] addObserver:self 
+                selector:@selector(cloudChanged:)
+                name:NSUbiquitousKeyValueStoreDidChangeExternallyNotification 
+                object:nil];
+
+        [self importKeyInterests: [SOSPersistentState registeredKeys]];
+
+        // Register for lock state changes
+        xpc_set_event_stream_handler(kStreamName, dispatch_get_main_queue(),
+                                     ^(xpc_object_t notification){
+                                         [self streamEvent:notification];
+                                     });
+
+        [self updateUnlockedSinceBoot];
+        [self updateIsLocked];
+        if (!_isLocked)
+            [self keybagDidUnlock];
+
+        secdebug(XPROXYSCOPE, "%@ done", self);
+    }
+    return self;
+}
+
+- (NSString *)description
+{
+    return [NSString stringWithFormat:@"<%s%s%s%s%s%s%s%s%s>",
+            _isLocked ? "L" : "U",
+            _unlockedSinceBoot ? "B" : "-",
+            _seenKVSStoreChange ? "K" : "-",
+            _syncTimerScheduled ? "T" : "-",
+            _syncWithPeersPending ? "s" : "-",
+            [_pendingKeys count] ? "p" : "-",
+            _inCallout ? "C" : "-",
+            _shadowSyncWithPeersPending ? "S" : "-",
+            [_shadowPendingKeys count] ? "P" : "-"];
+}
+
+- (void)processAllItems
+{
+    NSDictionary *allItems = [self getAll];
+    if (allItems)
+    {
+        secnotice("event", "%@ sending: %@", self, [[allItems allKeys] componentsJoinedByString: @" "]);
+        [self processKeyChangedEvent:allItems];
+    }
+    else
+        secdebug(XPROXYSCOPE, "%@ No items in KVS", self);
+}
+
+- (void)setItemsChangedBlock:(CloudItemsChangedBlock)itemsChangedBlock
+{
+    self->itemsChangedCallback = itemsChangedBlock;
+}
+
+- (void)dealloc
+{
+    secdebug(XPROXYSCOPE, "%@", self);
+    [[NSNotificationCenter defaultCenter] removeObserver:self
+        name:NSUbiquitousKeyValueStoreDidChangeExternallyNotification object:nil];
+
+    [[NSNotificationCenter defaultCenter] removeObserver:self 
+        name:NSUbiquityIdentityDidChangeNotification object:nil];
+}
+
+// MARK: ----- Client Interface -----
+
+- (void)setObject:(id)obj forKey:(id)key
+{
+    secdebug("keytrace", "%@ key: %@, obj: %@", self, key, obj);
+    NSUbiquitousKeyValueStore *store = [self cloudStore];
+    if (store)
+    {
+        id value = [store objectForKey:key];
+        if (value)
+            secdebug("keytrace", "%@ Current value (before set) for key %@ is: %@", self, key, value);
+        else
+            secdebug("keytrace", "%@ No current value for key %@", self, key);
+    }
+    else
+        secdebug("keytrace", "Can't get store");
+    
+    [[self cloudStore] setObject:obj forKey:key];
+    [self requestSynchronization:NO];
+}
+
+- (void)setObjectsFromDictionary:(NSDictionary *)values
+{
+    secdebug(XPROXYSCOPE, "%@ start: %lu values to put", self, (unsigned long)[values count]);
+
+    NSUbiquitousKeyValueStore *store = [self cloudStore];
+    if (store && values)
+    {
+        [values enumerateKeysAndObjectsUsingBlock: ^(id key, id obj, BOOL *stop)
+        {
+            if (obj == NULL || obj == [NSNull null])
+                [store removeObjectForKey:key];
+            else
+                [store setObject:obj forKey:key];
+        }];
+
+        [self requestSynchronization:NO];
+    }
+    else
+        secdebug(XPROXYSCOPE, "%@ NULL? store: %@, values: %@", self, store, values);
+}
+
+- (void)requestSynchronization:(bool)force
+{
+    if (force)
+    {
+        secdebug(XPROXYSCOPE, "%@ synchronize (forced)", self);
+        [[self cloudStore] synchronize];
+    }
+    else
+    {
+        secdebug(XPROXYSCOPE, "%@ synchronize (soon)", self);
+        [[self cloudStore] synchronize];
+    }
+}
+
+- (NSUbiquitousKeyValueStore *)cloudStore
+{
+    NSUbiquitousKeyValueStore *iCloudStore = [NSUbiquitousKeyValueStore defaultStore];
+//    secdebug(XPROXYSCOPE, "cloudStore: %@", iCloudStore);
+    return iCloudStore;
+}
+
+// try to synchronize asap, and invoke the handler on completion to take incoming changes.
+- (void)waitForSynchronization:(NSArray *)keys handler:(void (^)(NSDictionary *values, NSError *err))handler
+{
+    secdebug(XPROXYSCOPE, "%@ synchronize and wait", self);
+
+    if (!keys)
+    {
+        NSError *err = [NSError errorWithDomain:(NSString *)NSPOSIXErrorDomain code:(NSInteger)ENOPROTOOPT userInfo:nil];
+        handler(@{}, err);
+        return;
+    }
+
+    secdebug(XPROXYSCOPE, "%@ Requesting synchronizeWithCompletionHandler", self);
+
+    [[self cloudStore] synchronizeWithCompletionHandler:^(NSError *error) {
+        [[self cloudStore] synchronize]; // Per olivier in <rdar://problem/13412631>, sync before getting values
+
+        NSDictionary * changedKeys = error ? @{} : [self copyChangedValues:[NSSet setWithArray:keys]];
+
+        secdebug(XPROXYSCOPE, "%@ Got synchronize completion %@ (error %@)", self, changedKeys, error);
+        handler(changedKeys, error);
+    }];
+}
+
+- (void)dumpStore
+{
+    NSDictionary *dict = [[self cloudStore] dictionaryRepresentation];
+    [dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
+        secdebug(XPROXYSCOPE, "%@ Dump: value for key %@ is: %@", self, key, obj);
+    }];
+}
+
+- (void)removeObjectForKey:(NSString *)keyToRemove
+{
+    [[self cloudStore] removeObjectForKey:keyToRemove];
+}
+
+- (void)clearStore
+{
+    secdebug(XPROXYSCOPE, "%@ clearStore", self);
+    NSDictionary *dict = [[self cloudStore] dictionaryRepresentation];
+    NSArray *allKeys = [dict allKeys];
+    [allKeys enumerateObjectsUsingBlock:^(id key, NSUInteger idx, BOOL *stop)
+    {
+        secdebug(XPROXYSCOPE, "%@ Clearing value for key %@", self, key);
+        [[self cloudStore] removeObjectForKey:(NSString *)key];
+    }];
+
+    [self requestSynchronization:YES];
+}
+
+
+//
+// MARK: ----- KVS key lists -----
+//
+
+- (id)get:(id)key
+{
+    return [[self cloudStore] objectForKey:key];
+}
+
+- (NSDictionary *)getAll
+{
+    return [[self cloudStore] dictionaryRepresentation];
+}
+
+- (NSDictionary*) exportKeyInterests
+{
+    return @{ kKeyAlwaysKeys:[_alwaysKeys allObjects],
+              kKeyFirstUnlockKeys:[_firstUnlockKeys allObjects],
+              kKeyUnlockedKeys:[_unlockedKeys allObjects],
+              kKeyPendingKeys:[_pendingKeys allObjects],
+              kKeySyncWithPeersPending:[NSNumber numberWithBool:_syncWithPeersPending]
+              };
+}
+
+- (void) importKeyInterests: (NSDictionary*) interests
+{
+    _alwaysKeys = [NSSet setWithArray: interests[kKeyAlwaysKeys]];
+    _firstUnlockKeys = [NSSet setWithArray: interests[kKeyFirstUnlockKeys]];
+    _unlockedKeys = [NSSet setWithArray: interests[kKeyUnlockedKeys]];
+    _pendingKeys = [NSMutableSet setWithArray: interests[kKeyPendingKeys]];
+    _syncWithPeersPending = [interests[kKeySyncWithPeersPending] boolValue];
+}
+
+- (NSMutableSet *)copyAllKeys
+{
+    NSMutableSet *allKeys = [NSMutableSet setWithSet: _alwaysKeys];
+    [allKeys unionSet: _firstUnlockKeys];
+    [allKeys unionSet: _unlockedKeys];
+    return allKeys;
+}
+
+- (NSDictionary *)registerKeysAndGet:(BOOL)getNewKeysOnly always:(NSArray *)keysToRegister reqFirstUnlock:(NSArray *)reqFirstUnlock reqUnlocked:(NSArray *)reqUnlocked
+{
+    NSMutableSet *allOldKeys = [self copyAllKeys];
+    _alwaysKeys = [NSSet setWithArray: keysToRegister];
+    _firstUnlockKeys = [NSSet setWithArray: reqFirstUnlock];
+    _unlockedKeys = [NSSet setWithArray: reqUnlocked];
+    NSMutableSet *allNewKeys = [self copyAllKeys];
+
+    [_pendingKeys intersectSet:allNewKeys];
+
+    NSSet* keysToGet = nil;
+    if (getNewKeysOnly) {
+        [allNewKeys minusSet:allOldKeys];
+        keysToGet = allNewKeys;
+    } else {
+        keysToGet = [self keysForCurrentLockState];
+    }
+
+    // Mark keysToGet for the current lockState as pending
+    NSSet *filteredKeys = [self filterKeySetWithLockState:keysToGet];
+    [self persistState];
+    NSMutableDictionary *returnedValues = [self copyChangedValues: filteredKeys];
+
+    secnotice("keytrace", "%@ [%s] always: %@ firstUnlock: %@ unlocked: %@ got: %@", self, getNewKeysOnly ? "new only " : "", [keysToRegister componentsJoinedByString: @" "], [reqFirstUnlock componentsJoinedByString: @" "], [reqUnlocked componentsJoinedByString: @" "], [[returnedValues allKeys] componentsJoinedByString: @" "]);
+
+    [self processKeyChangedEvent:returnedValues];
+    [returnedValues removeAllObjects];
+
+    return returnedValues;
+}
+
+- (NSDictionary *)localNotification:(NSDictionary *)localNotificationDict outFlags:(int64_t *)outFlags
+{
+    __block bool done = false;
+    __block int64_t returnedFlags = 0;
+    __block NSDictionary *responses = NULL;
+    typedef bool (^CKDUserInteractionBlock) (CFDictionaryRef responses);
+
+    CKDUserInteraction *cui = [CKDUserInteraction sharedInstance];
+    [cui requestShowNotification:localNotificationDict completion:^ bool (CFDictionaryRef userResponses, int64_t flags)
+        {
+            responses = [NSDictionary dictionaryWithDictionary:(__bridge NSDictionary *)userResponses];
+            returnedFlags = flags;
+            secdebug(XPROXYSCOPE, "%@ requestShowNotification: dict: %@, flags: %#llx", self, responses, returnedFlags);
+            done = true;
+            return true;
+        }];
+
+    // TODO: replace with e.g. dispatch calls to wait, or semaphore
+    while (!done)
+        sleep(1);
+    if (outFlags)
+    {
+        secdebug(XPROXYSCOPE, "%@ outFlags: %#llx", self, returnedFlags);
+        *outFlags = returnedFlags;
+    }
+    return responses;
+}
+
+- (void)setParams:(NSDictionary *)paramsDict
+{
+    secdebug(XPROXYSCOPE, "%@ setParams: %@ ", self, paramsDict);
+    NSString *cbmethod = [paramsDict objectForKey:(__bridge id)kParamCallbackMethod];
+    if (!cbmethod)
+        return;
+
+    if ([cbmethod isEqualToString:(__bridge NSString *)kParamCallbackMethodSecurityd])
+        callbackMethod = kCallbackMethodSecurityd;
+    else if ([cbmethod isEqualToString:(__bridge NSString *)kParamCallbackMethodXPC])
+        callbackMethod = kCallbackMethodXPC;
+}
+
+- (void)saveToUbiquitousStore
+{
+    [self requestSynchronization:NO];
+}
+
+// MARK: ----- Event Handling -----
+
+- (void)streamEvent:(xpc_object_t)notification
+{
+#if (!TARGET_IPHONE_SIMULATOR)
+    const char *notificationName = xpc_dictionary_get_string(notification, "Notification");
+    if (!notificationName) {
+    } else if (strcmp(notificationName, kUserKeybagStateChangeNotification)==0) {
+        return [self keybagStateChange];
+    } else if (strcmp(notificationName, kCloudKeychainStorechangeChangeNotification)==0) {
+        return [self kvsStoreChange];
+    } else if (strcmp(notificationName, kNotifyTokenForceUpdate)==0) {
+        // DEBUG -- Possibly remove in future
+        return [self processAllItems];
+    }
+    const char *eventName = xpc_dictionary_get_string(notification, "XPCEventName");
+    char *desc = xpc_copy_description(notification);
+    secerror("%@ event: %s name: %s desc: %s", self, eventName, notificationName, desc);
+    if (desc)
+        free((void *)desc);
+#endif
+}
+
+- (void)iCloudAccountAvailabilityChanged:(NSNotification*)notification
+{
+    /*
+        Continuing this example, you’d then implement an iCloudAccountAvailabilityChanged: method that would:
+
+        Call the ubiquityIdentityToken method and store its return value.
+        Compare the new value to the previous value, to find out if the user logged out of their account or 
+        logged in to a different account. If the previously-used account is now unavailable, save the current 
+        state locally as needed, empty your iCloud-related data caches, and refresh all iCloud-related user interface elements.
+    */
+    id previCloudToken = currentiCloudToken;
+    currentiCloudToken = [[NSFileManager defaultManager] ubiquityIdentityToken];
+    if (previCloudToken != currentiCloudToken)
+        secnotice("event", "%@ iCloud account changed!", self);
+    else
+        secnotice("event", "%@ %@", self, notification);
+}
+
+- (void)cloudChanged:(NSNotification*)notification
+{
+    /*
+        Posted when the value of one or more keys in the local key-value store
+        changed due to incoming data pushed from iCloud. This notification is
+        sent only upon a change received from iCloud; it is not sent when your
+        app sets a value.
+
+        The user info dictionary can contain the reason for the notification as
+        well as a list of which values changed, as follows:
+
+        The value of the NSUbiquitousKeyValueStoreChangeReasonKey key, when
+        present, indicates why the key-value store changed. Its value is one of
+        the constants in "Change Reason Values."
+        
+        The value of the NSUbiquitousKeyValueStoreChangedKeysKey, when present, 
+        is an array of strings, each the name of a key whose value changed. The
+        notification object is the NSUbiquitousKeyValueStore object whose contents
+        changed.
+     
+        NSUbiquitousKeyValueStoreInitialSyncChange is only posted if there is any 
+        local value that has been overwritten by a distant value. If there is no 
+        conflict between the local and the distant values when doing the initial
+        sync (e.g. if the cloud has no data stored or the client has not stored 
+        any data yet), you'll never see that notification.
+     
+        NSUbiquitousKeyValueStoreInitialSyncChange implies an initial round trip
+        with server but initial round trip with server does not imply 
+        NSUbiquitousKeyValueStoreInitialSyncChange.
+    */
+
+    secdebug(XPROXYSCOPE, "%@ cloudChanged notification: %@", self, notification);
+
+    NSDictionary *userInfo = [notification userInfo];
+    NSNumber *reason = [userInfo objectForKey:NSUbiquitousKeyValueStoreChangeReasonKey];
+    if (reason) switch ([reason integerValue]) {
+        case NSUbiquitousKeyValueStoreInitialSyncChange:
+        case NSUbiquitousKeyValueStoreServerChange:
+        {
+            _seenKVSStoreChange = YES;
+            NSSet *keysChangedInCloud = [NSSet setWithArray:[userInfo objectForKey:NSUbiquitousKeyValueStoreChangedKeysKey]];
+            NSSet *keysOfInterestThatChanged = [self filterKeySetWithLockState:keysChangedInCloud];
+            NSMutableDictionary *changedValues = [self copyChangedValues:keysOfInterestThatChanged];
+            if ([reason integerValue] == NSUbiquitousKeyValueStoreInitialSyncChange)
+                changedValues[(__bridge NSString*)kSOSKVSInitialSyncKey] =  @"true";
+
+            secnotice("event", "%@ keysChangedInCloud: %@ keysOfInterest: %@", self, [[keysChangedInCloud allObjects] componentsJoinedByString: @" "], [[changedValues allKeys] componentsJoinedByString: @" "]);
+            if ([changedValues count])
+                [self processKeyChangedEvent:changedValues];
+            break;
+        }
+        case NSUbiquitousKeyValueStoreQuotaViolationChange:
+            seccritical("%@ event received NSUbiquitousKeyValueStoreQuotaViolationChange", self);
+            break;
+        case NSUbiquitousKeyValueStoreAccountChange:
+            // The primary account changed. We do not get this for password changes on the same account
+            secnotice("event", "%@ NSUbiquitousKeyValueStoreAccountChange", self);
+            if ([reason integerValue] == NSUbiquitousKeyValueStoreInitialSyncChange)
+            {
+                NSDictionary *changedValues = @{ (__bridge NSString*)kSOSKVSAccountChangedKey:  @"true" };
+                [self processKeyChangedEvent:changedValues];
+            }
+            break;
+    }
+}
+
+- (void) calloutWith: (void(^)(NSSet *pending, bool syncWithPeersPending, dispatch_queue_t queue, void(^done)(NSSet *handledKeys, bool handledSyncWithPeers))) callout
+{
+    // In CKDKVSProxy's serial queue
+    NSSet *myPending = [_pendingKeys copy];
+    bool mySyncWithPeersPending = _syncWithPeersPending;
+    bool wasLocked = _isLocked;
+    _inCallout = YES;
+    _shadowPendingKeys = [NSMutableSet set];
+    _shadowSyncWithPeersPending = NO;
+    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+        callout(myPending, mySyncWithPeersPending, dispatch_get_main_queue(), ^(NSSet *handledKeys, bool handledSyncWithPeers) {
+            // In CKDKVSProxy's serial queue
+            _inCallout = NO;
+
+            // Update SyncWithPeers stuff.
+            _syncWithPeersPending = (mySyncWithPeersPending && (!handledSyncWithPeers)) || _shadowSyncWithPeersPending;
+            _shadowSyncWithPeersPending = NO;
+            if (handledSyncWithPeers)
+                _lastSyncTime = dispatch_time(DISPATCH_TIME_NOW, 0);
+
+            // Update pendingKeys and handle them
+            [_pendingKeys minusSet: handledKeys];
+            bool hadShadowPendingKeys = [_shadowPendingKeys count];
+            NSSet *filteredKeys = [self filterKeySetWithLockState:_shadowPendingKeys];
+            _shadowPendingKeys = nil;
+
+            // Write state to disk
+            [self persistState];
+
+            // Handle shadow pended stuff
+            if (_syncWithPeersPending && !_isLocked)
+                [self scheduleSyncRequestTimer];
+            /* We don't want to call processKeyChangedEvent if we failed to
+               handle pending keys and the device didn't unlock nor receive
+               any kvs changes while we were in our callout.
+               Doing so will lead to securityd and CloudKeychainProxy
+               talking to each other forever in a tight loop if securityd
+               repeatedly returns an error processing the same message.
+               Instead we leave any old pending keys until the next event. */
+            if (hadShadowPendingKeys || (!_isLocked && wasLocked))
+                [self processKeyChangedEvent:[self copyChangedValues:filteredKeys]];
+        });
+    });
+}
+
+- (void) doSyncWithAllPeers
+{
+    [self calloutWith:^(NSSet *pending, bool syncWithPeersPending, dispatch_queue_t queue, void(^done)(NSSet *, bool)) {
+        CFErrorRef error = NULL;
+        SyncWithAllPeersReason reason = SOSCCProcessSyncWithAllPeers(&error);
+        dispatch_async(queue, ^{
+            bool handledSyncWithPeers = NO;
+            if (reason == kSyncWithAllPeersSuccess) {
+                handledSyncWithPeers = YES;
+                secnotice("event", "%@ syncWithAllPeers succeeded", self);
+            } else if (reason == kSyncWithAllPeersLocked) {
+                secnotice("event", "%@ syncWithAllPeers attempted while locked - waiting for unlock", self);
+                handledSyncWithPeers = YES;
+            } else if (reason == kSyncWithAllPeersOtherFail) {
+                // Pretend we handled syncWithPeers, by pushing out the _lastSyncTime
+                // This will cause us to wait for kMinSyncInterval seconds before
+                // retrying, so we don't spam securityd if sync is failing
+                secerror("%@ syncWithAllPeers %@, rescheduling timer", self, error);
+                _lastSyncTime = dispatch_time(DISPATCH_TIME_NOW, 0);
+            } else {
+                secerror("%@ syncWithAllPeers %@, unknown reason: %d", self, error, reason);
+            }
+
+            done(nil, handledSyncWithPeers);
+            CFReleaseSafe(error);
+        });
+    }];
+}
+
+- (void)timerFired
+{
+    secnotice("event", "%@ syncWithPeersPending: %d inCallout: %d isLocked: %d", self, _syncWithPeersPending, _inCallout, _isLocked);
+    _syncTimerScheduled = NO;
+    if (_syncWithPeersPending && !_inCallout && !_isLocked)
+        [self doSyncWithAllPeers];
+}
+
+- (dispatch_time_t) nextSyncTime
+{
+    dispatch_time_t nextSync = dispatch_time(DISPATCH_TIME_NOW, kMinSyncDelay);
+
+    // Don't sync again unless we waited at least kMinSyncInterval
+    if (_lastSyncTime) {
+        dispatch_time_t soonest = dispatch_time(_lastSyncTime, kMinSyncInterval);
+        if (nextSync < soonest || _deadline < soonest) {
+            secdebug("timer", "%@ backing off", self);
+            return soonest;
+        }
+    }
+
+    // Don't delay more than kMaxSyncDelay after the first request.
+    if (nextSync > _deadline) {
+        secdebug("timer", "%@ hit deadline", self);
+        return _deadline;
+    }
+
+    // Bump the timer by kMinSyncDelay
+    if (_syncTimerScheduled)
+        secdebug("timer", "%@ bumped timer", self);
+    else
+        secdebug("timer", "%@ scheduled timer", self);
+
+    return nextSync;
+}
+
+- (void)scheduleSyncRequestTimer
+{
+    dispatch_source_set_timer(_syncTimer, [self nextSyncTime], DISPATCH_TIME_FOREVER, kSyncTimerLeeway);
+    _syncTimerScheduled = YES;
+}
+
+- (void)requestSyncWithAllPeers // secd calling SOSCCSyncWithAllPeers invokes this
+{
+    secdebug("event", "%@ _syncWithPeersPending: %d _inCallout: %d _shadowSyncWithPeersPending: %d _isLocked: %d", self, _syncWithPeersPending, _inCallout, _shadowSyncWithPeersPending, _isLocked);
+
+    if (!_syncWithPeersPending || (_inCallout && !_shadowSyncWithPeersPending))
+        _deadline = dispatch_time(DISPATCH_TIME_NOW, kMaxSyncDelay);
+
+    if (!_syncWithPeersPending) {
+        _syncWithPeersPending = YES;
+        [self persistState];
+    }
+
+    if (_inCallout)
+        _shadowSyncWithPeersPending = YES;
+
+    if (!_isLocked)
+        [self scheduleSyncRequestTimer];
+}
+
+- (BOOL) updateUnlockedSinceBoot
+{
+    CFErrorRef aksError = NULL;
+    if (!SecAKSGetHasBeenUnlocked(&_unlockedSinceBoot, &aksError)) {
+        secerror("%@ Got error from SecAKSGetHasBeenUnlocked: %@", self, aksError);
+        CFReleaseSafe(aksError);
+        return NO;
+    }
+    return YES;
+}
+
+- (BOOL) updateIsLocked
+{
+    CFErrorRef aksError = NULL;
+    if (!SecAKSGetIsLocked(&_isLocked, &aksError)) {
+        secerror("%@ Got error querying lock state: %@", self, aksError);
+        CFReleaseSafe(aksError);
+        return NO;
+    }
+    if (!_isLocked)
+        _unlockedSinceBoot = YES;
+    return YES;
+}
+
+- (void) keybagStateChange
+{
+    BOOL wasLocked = _isLocked;
+    if ([self updateIsLocked]) {
+        if (wasLocked == _isLocked)
+            secdebug("event", "%@ still %s ignoring", self, _isLocked ? "locked" : "unlocked");
+        else if (_isLocked)
+            [self keybagDidLock];
+        else
+            [self keybagDidUnlock];
+    }
+}
+
+- (void) keybagDidLock
+{
+    secnotice("event", "%@", self);
+}
+
+- (void) keybagDidUnlock
+{
+    secnotice("event", "%@", self);
+    // First send changed keys to securityd so it can proccess updates
+    NSSet *filteredKeys = [self filterKeySetWithLockState:nil];
+    [self processKeyChangedEvent:[self copyChangedValues:filteredKeys]];
+
+    // Then, tickle securityd to perform a sync if needed.
+    if (_syncWithPeersPending && !_syncTimerScheduled) {
+        [self doSyncWithAllPeers];
+    }
+}
+
+- (void) kvsStoreChange {
+    if (!_seenKVSStoreChange) {
+        _seenKVSStoreChange = YES; // Only do this once
+        secnotice("event", "%@ received darwin notification before first NSNotification", self);
+        // TODO This might not be needed if we always get the NSNotification
+        // deleived even if we were launched due to a kvsStoreChange
+        // Send all keys for current lock state to securityd so it can proccess them
+        NSSet *filteredKeys = [self filterKeySetWithLockState:[self copyAllKeys]];
+        [self processKeyChangedEvent:[self copyChangedValues:filteredKeys]];
+    } else {
+        secdebug("event", "%@ ignored, waiting for NSNotification", self);
+    }
+}
+
+//
+// MARK: ----- Key Filtering -----
+//
+
+- (NSSet*) keysForCurrentLockState
+{
+    secdebug("keytrace", "%@ Filtering: unlockedSinceBoot: %d\n unlocked: %d\n, _keysOfInterest: %@", self, (int) _unlockedSinceBoot, (int) !_isLocked, [self exportKeyInterests]);
+
+    NSMutableSet *currentStateKeys = [NSMutableSet setWithSet: _alwaysKeys];
+    if (_unlockedSinceBoot)
+        [currentStateKeys unionSet: _firstUnlockKeys];
+
+    if (!_isLocked)
+        [currentStateKeys unionSet: _unlockedKeys];
+
+    return currentStateKeys;
+}
+
+- (NSSet*) filterKeySetWithLockState: (NSSet*) startingSet
+{
+    NSSet* availableKeys = [self keysForCurrentLockState];
+    NSSet *allKeys = [self copyAllKeys];
+    if (_inCallout) {
+        [_shadowPendingKeys unionSet:startingSet];
+        [_shadowPendingKeys intersectSet:allKeys];
+    }
+    [_pendingKeys unionSet:startingSet];
+    [_pendingKeys intersectSet:allKeys];
+
+    NSMutableSet *filtered =[_pendingKeys mutableCopy];
+    [filtered intersectSet:availableKeys];
+
+    return filtered;
+}
+
+- (NSMutableDictionary *)copyChangedValues:(NSSet*)keysOfInterest
+{
+    // Grab values from KVS.
+    NSUbiquitousKeyValueStore *store = [self cloudStore];
+    NSMutableDictionary *changedValues = [NSMutableDictionary dictionaryWithCapacity:0];
+    [keysOfInterest enumerateObjectsUsingBlock:^(id obj, BOOL *stop)
+    {
+        NSString* key = (NSString*) obj;
+        id objval = [store objectForKey:key];
+        if (!objval) objval = [NSNull null];
+
+        [changedValues setObject:objval forKey:key];
+        secdebug(XPROXYSCOPE, "%@ storeChanged updated value for %@", self, key);
+    }];
+    return changedValues;
+}
+
+/*
+    During RegisterKeys, separate keys-of-interest into three disjoint sets:
+    - keys that we always want to be notified about; this means we can get the
+        value at any time
+    - keys that require the device to have been unlocked at least once
+    - keys that require the device to be unlocked now
+    
+    Typically, the sets of keys will be:
+    
+    - Dk: alwaysKeys
+    - Ck: firstUnlock
+    - Ak: unlocked
+    
+    The caller is responsible for making sure that the keys in e.g. alwaysKeys are
+    values that can be handled at any time (that is, not when unlocked)
+
+    Each time we get a notification from ubiquity that keys have changed, we need to
+    see if anything of interest changed. If we don't care, then done.
+    
+    For each key-of-interest that changed, we either notify the client that things
+    changed, or add it to a pendingNotifications list. If the notification to the
+    client fails, also add it to the pendingNotifications list. This pending list
+    should be written to persistent storage and consulted any time we either get an
+    item changed notification, or get a stream event signalling a change in lock state.
+    
+    We can notify the client either through XPC if a connection is set up, or call a
+    routine in securityd to launch it.
+    
+*/
+
+- (void)processKeyChangedEvent:(NSDictionary *)changedValues
+{
+    NSMutableDictionary* filtered = [NSMutableDictionary dictionary];
+    NSMutableArray* nullKeys = [NSMutableArray array];
+    // Remove nulls because we don't want them in securityd.
+    [changedValues enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
+        if (obj == [NSNull null])
+            [nullKeys addObject:key];
+        else
+            filtered[key] = obj;
+    }];
+    if ([filtered count]) {
+        [self calloutWith:^(NSSet *pending, bool syncWithPeersPending, dispatch_queue_t queue, void(^done)(NSSet *, bool)) {
+            CFErrorRef error = NULL;
+            bool bx = [filtered count] && _SecKeychainSyncUpdate((__bridge CFDictionaryRef)filtered, &error);
+            // TODO: Make SecKeychainSyncUpdate return handled keys, for now we
+            // record that we handled everything when _SecKeychainSyncUpdate succeeds.
+            NSSet* handledKeys = [NSSet setWithArray: bx ? [changedValues allKeys] : nullKeys];
+            dispatch_async(queue, ^{
+                done(handledKeys, NO);
+                if (bx)
+                    secnotice("keytrace", "%@ handled: %@ null: %@ pending: %@", self,
+                              [[filtered allKeys] componentsJoinedByString: @" "],
+                              [nullKeys componentsJoinedByString: @" "],
+                              [[_pendingKeys allObjects] componentsJoinedByString: @" "]);
+                else
+                    secerror("%@ failed: %@ not handled: %@ null: %@ pending: %@", self, error,
+                             [[filtered allKeys] componentsJoinedByString: @" "],
+                             [nullKeys componentsJoinedByString: @" "],
+                             [[_pendingKeys allObjects] componentsJoinedByString: @" "]);
+                CFReleaseSafe(error);
+            });
+        }];
+    } else {
+        if ([nullKeys count])
+            [_pendingKeys minusSet: [NSSet setWithArray: nullKeys]];
+
+        secnotice("keytrace", "%@ handled: %@ null: %@ pending: %@", self,
+                  [[filtered allKeys] componentsJoinedByString: @" "],
+                  [nullKeys componentsJoinedByString: @" "],
+                  [[_pendingKeys allObjects] componentsJoinedByString: @" "]);
+    }
+}
+
+@end
+
diff --git a/sec/SOSCircle/CloudKeychainProxy/CKDPersistentState.h b/sec/SOSCircle/CloudKeychainProxy/CKDPersistentState.h
new file mode 100644 (file)
index 0000000..4609f01
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012 Apple Computer, Inc. All Rights Reserved.
+ * 
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+//
+//  SOSPersistentState.h
+//  ckdxpc
+//
+
+#import <Foundation/NSString.h>
+
+@interface SOSPersistentState : NSObject
+{
+}
+
++ (id)read:(NSURL *)path error:(NSError **)error;
++ (BOOL)write:(NSURL *)path data:(id)plist error:(NSError **)error;
++ (NSMutableDictionary *)registeredKeys;
++ (void)setRegisteredKeys: (NSDictionary *)keysToRegister;
++ (NSURL *)registrationFileURL;
+
+@end
+
diff --git a/sec/SOSCircle/CloudKeychainProxy/CKDPersistentState.m b/sec/SOSCircle/CloudKeychainProxy/CKDPersistentState.m
new file mode 100644 (file)
index 0000000..ad0f616
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2012-2013 Apple Computer, Inc. All Rights Reserved.
+ * 
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+//
+//  SOSPersistentState.m
+//  ckdxpc
+//
+
+#import <Security/Security.h>
+#import <Foundation/NSPropertyList.h>
+#import <Foundation/NSData.h>
+#import <Foundation/NSDictionary.h>
+#import <utilities/debugging.h>
+#import <utilities/SecFileLocations.h>
+
+#import "CKDPersistentState.h"
+
+#if ! __has_feature(objc_arc)
+#error This file must be compiled with ARC. Either turn on ARC for the project or use -fobjc-arc flag
+#endif
+
+// may want to have this hold incoming events in file as well
+
+// TODO: Sandbox stuff
+
+static CFStringRef kRegistrationFileName = CFSTR("com.apple.security.cloudkeychainproxy3.keysToRegister.plist");
+
+#define DEBUGSCOPEPW    "keytrace"
+
+@implementation SOSPersistentState
+
++ (BOOL)write:(NSURL *)path data:(id)plist error:(NSError **)error
+{
+    if (![NSPropertyListSerialization propertyList: plist isValidForFormat: NSPropertyListXMLFormat_v1_0])
+    {
+        secerror("can't save PersistentState as XML");
+        return false;
+    }
+
+    NSData *data = [NSPropertyListSerialization dataWithPropertyList: plist
+        format: NSPropertyListXMLFormat_v1_0 options: 0 error: error];
+    if (data == nil)
+    {
+        secerror("error serializing PersistentState to xml: %@", *error);
+        return false;
+    }
+
+    BOOL writeStatus = [data writeToURL: path options: NSDataWritingAtomic error: error];
+    if (!writeStatus)
+        secerror("error writing PersistentState to file: %@", *error);
+    
+    return writeStatus;
+}
+
++ (id)read: (NSURL *)path error:(NSError **)error
+{
+    NSData *data = [NSData dataWithContentsOfURL: path options: 0 error: error];
+    if (data == nil)
+    {
+        secdebug(DEBUGSCOPEPW, "error reading PersistentState from %@: %@", path, *error);
+        return nil;
+    }
+
+    // Now the deserializing:
+
+    NSPropertyListFormat format;
+    id plist = [NSPropertyListSerialization propertyListWithData: data
+        options: NSPropertyListMutableContainersAndLeaves format: &format error: error];
+                                            
+    if (plist == nil)
+        secerror("could not deserialize PersistentState from %@: %@", path, *error);
+    
+    return plist;
+}
+
++ (NSURL *)registrationFileURL
+{
+    return (NSURL *)CFBridgingRelease(SecCopyURLForFileInPreferencesDirectory(kRegistrationFileName));
+}
+
++ (NSMutableDictionary *)registeredKeys
+{
+    NSError *error = NULL;
+    id stateDictionary = [SOSPersistentState read:[[self class] registrationFileURL] error:&error];
+    secdebug(DEBUGSCOPEPW, "Read persistent stateDictionary: %@", stateDictionary);
+    // Ignore older states with an NSArray
+    if (![stateDictionary isKindOfClass:[NSDictionary class]])
+        return NULL;
+    return [NSMutableDictionary dictionaryWithDictionary:stateDictionary];
+}
+
++ (void)setRegisteredKeys: (NSDictionary *)keysToRegister
+{
+    NSError *error = NULL;
+    secdebug(DEBUGSCOPEPW, "Write persistent keysToRegister: %@", keysToRegister);
+    [SOSPersistentState write:[[self class] registrationFileURL] data:keysToRegister error:&error];
+}
+
+@end
diff --git a/sec/SOSCircle/CloudKeychainProxy/CKDUserInteraction.h b/sec/SOSCircle/CloudKeychainProxy/CKDUserInteraction.h
new file mode 100644 (file)
index 0000000..350d567
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012-2013 Apple Computer, Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+//
+//  CKDUserInteraction.h
+//  CloudKeychainProxy
+//
+
+#import <Foundation/Foundation.h>
+#import <CoreFoundation/CFUserNotification.h>
+
+typedef bool (^CKDUserInteractionBlock) (CFDictionaryRef responses, int64_t flags);
+
+@interface CKDUserInteraction : NSObject
+{
+    
+}
+@property (atomic) CFUserNotificationRef userNotificationRef;
+@property CFRunLoopSourceRef runLoopSourceRef;
+
++ (CKDUserInteraction *) sharedInstance;
+- (void)requestShowNotification:(NSDictionary *)infoForUserInfo completion:(CKDUserInteractionBlock)completionf;
+
+@end
diff --git a/sec/SOSCircle/CloudKeychainProxy/CKDUserInteraction.m b/sec/SOSCircle/CloudKeychainProxy/CKDUserInteraction.m
new file mode 100644 (file)
index 0000000..34b0c5e
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2012-2013 Apple Computer, Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+//
+//  CKDUserInteraction.m
+//  CloudKeychainProxy
+//
+
+#import <CoreFoundation/CFUserNotification.h>
+#import <utilities/debugging.h>
+
+#import "CKDUserInteraction.h"
+#import "SOSARCDefines.h"
+
+static CKDUserInteraction *sharedInstance = nil;
+static CKDUserInteractionBlock completion;
+
+#define XPROXYUISCOPE "proxy-ui"
+
+static void userNotificationCallback(CFUserNotificationRef userNotification, CFOptionFlags responseFlags)
+{
+       
+/*  
+    kCFUserNotificationDefaultResponse         = 0,
+    kCFUserNotificationAlternateResponse       = 1,
+    kCFUserNotificationOtherResponse           = 2,
+    kCFUserNotificationCancelResponse          = 3
+*/
+
+    CKDUserInteraction *sharedInstance = [CKDUserInteraction sharedInstance];
+    CFDictionaryRef userResponses = CFUserNotificationGetResponseDictionary(userNotification);
+               // CFOptionFlags are poorly named, since it's a single response value, not a mask
+
+       secdebug(XPROXYUISCOPE, "sharedInstance: %@, rlsr: %@", sharedInstance, sharedInstance.runLoopSourceRef);
+       secdebug(XPROXYUISCOPE, "userNotification responses: %@, flags: %#lx",userResponses, responseFlags);
+    
+    if (sharedInstance.runLoopSourceRef)
+        CFRunLoopRemoveSource(CFRunLoopGetMain(), sharedInstance.runLoopSourceRef, kCFRunLoopDefaultMode);
+    
+    if (completion)  // sharedInstance.completion
+       {
+        secdebug(XPROXYUISCOPE, "Calling user completion routine");
+        completion(userResponses, responseFlags);   // sharedInstance.completion
+    }
+    
+    secdebug(XPROXYUISCOPE, "Releasing user completion routine");
+//    Block_release(completion);   // sharedInstance.completion
+    
+/*
+       if (responseFlags & kCFUserNotificationCancelResponse) {
+                returnCode = kABNotifierUserCancelled;
+        } else {
+                fUsername = (CFStringRef)CFUserNotificationGetResponseValue(notification, kCFUserNotificationTextFieldValuesKey, 0);
+                if(fUsername) CFRetain(fUsername);
+                
+                fPassword = (CFStringRef)CFUserNotificationGetResponseValue(notification, kCFUserNotificationTextFieldValuesKey, 1);
+                if(fPassword) CFRetain(fPassword);
+                
+                if((response & CFUserNotificationCheckBoxChecked(0)))
+*/
+
+//    if (responseFlags == kCFUserNotificationCancelResponse || responseFlags == kCFUserNotificationDefaultResponse)
+    CFRunLoopStop(CFRunLoopGetCurrent());
+       secdebug(XPROXYUISCOPE, "exit");
+}
+
+@implementation CKDUserInteraction
+
++ (CKDUserInteraction *) sharedInstance
+{
+    if (!sharedInstance)
+               sharedInstance = [[self alloc] init];
+
+    return sharedInstance;
+}
+
+- (void)requestShowNotification:(NSDictionary *)infoForUserInfo completion:(CKDUserInteractionBlock)completionf
+{
+    __block CFOptionFlags flags = kCFUserNotificationCautionAlertLevel | kCFUserNotificationNoDefaultButtonFlag;
+    CFTimeInterval timeout = 30.0;
+    
+//  completion = Block_copy(completionf);
+    completion = completionf;
+    
+    CFStringRef headerStr = (__bridge CFStringRef)([infoForUserInfo objectForKey:(__bridge id)kCFUserNotificationAlertHeaderKey]);
+
+    CFStringRef cancelStr = CFSTR("No way"); //CFStringCreateWithCString(kCFAllocatorDefault, cancel.c_str(), kCFStringEncodingUTF8);
+    CFStringRef defaultStr = CFSTR("Sure"); //CFStringCreateWithCString(kCFAllocatorDefault, settings.c_str(), kCFStringEncodingUTF8);
+
+    CFMutableDictionaryRef notifyDictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+
+    // Header and buttons
+    CFDictionarySetValue(notifyDictionary, kCFUserNotificationAlertHeaderKey, headerStr);
+    CFDictionarySetValue(notifyDictionary, kCFUserNotificationDefaultButtonTitleKey, defaultStr);
+    CFDictionarySetValue(notifyDictionary, kCFUserNotificationAlternateButtonTitleKey, cancelStr);
+
+    SInt32 error = 0;
+    _userNotificationRef = CFUserNotificationCreate(kCFAllocatorDefault, timeout, flags, &error, notifyDictionary);
+
+    if (_userNotificationRef)
+    {
+        _runLoopSourceRef = CFUserNotificationCreateRunLoopSource(kCFAllocatorDefault, _userNotificationRef, userNotificationCallback, 0);
+        CFRunLoopAddSource(CFRunLoopGetMain(), _runLoopSourceRef, kCFRunLoopDefaultMode);
+       }
+
+}
+
+@end
+
diff --git a/sec/SOSCircle/CloudKeychainProxy/ckdmain.m b/sec/SOSCircle/CloudKeychainProxy/ckdmain.m
new file mode 100644 (file)
index 0000000..7cb90de
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2012 Apple Computer, Inc. All Rights Reserved.
+ * 
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+//
+//  main.m
+//  ckd-xpc
+//
+//  Created by John Hurley on 7/19/12.
+//  Copyright (c) 2012 John Hurley. All rights reserved.
+//
+
+/*
+    This XPC service is essentially just a proxy to iCloud KVS, which exists since
+    the main security code cannot link against Foundation.
+    
+    See sendTSARequestWithXPC in tsaSupport.c for how to call the service
+    
+    send message to app with xpc_connection_send_message
+    
+    For now, build this with:
+    
+        ~rc/bin/buildit .  --rootsDirectory=/var/tmp -noverify -offline -target CloudKeychainProxy
+
+    and install or upgrade with:
+        
+        darwinup install /var/tmp/sec.roots/sec~dst
+        darwinup upgrade /var/tmp/sec.roots/sec~dst
+    You must use darwinup during development to update system caches
+*/
+
+//------------------------------------------------------------------------------------------------
+
+#include <stdlib.h>
+#include <asl.h>
+#include <Foundation/Foundation.h>
+
+extern int ckdproxymain(int argc, const char *argv[]);
+
+int main(int argc, const char *argv[])
+{
+    // TODO: Remove log before ship
+    asl_log(NULL, NULL, ASL_LEVEL_NOTICE, "start");
+    return ckdproxymain(argc, argv);
+}
diff --git a/sec/SOSCircle/CloudKeychainProxy/cloudkeychain.entitlements.plist b/sec/SOSCircle/CloudKeychainProxy/cloudkeychain.entitlements.plist
new file mode 100644 (file)
index 0000000..46c70ef
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>keychain-sync-updates</key>
+       <true/>
+       <key>application-identifier</key>
+       <string>com.apple.security.cloudkeychainproxy3</string>
+       <key>sync-keychain</key>
+       <true/>
+       <key>keychain-access-groups</key>
+       <array>
+               <string>sync</string>
+               <string>*</string>
+       </array>
+       <key>com.apple.developer.ubiquity-kvstore-identifier</key>
+       <string>com.apple.security.cloudkeychainproxy3</string>
+</dict>
+</plist>
diff --git a/sec/SOSCircle/CloudKeychainProxy/cloudkeychainproxy.m b/sec/SOSCircle/CloudKeychainProxy/cloudkeychainproxy.m
new file mode 100644 (file)
index 0000000..a4a8678
--- /dev/null
@@ -0,0 +1,461 @@
+/*
+ * Copyright (c) 2012 Apple Computer, Inc. All Rights Reserved.
+ * 
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+//
+//  main.m
+//  ckd-xpc
+//
+//  Created by John Hurley on 7/19/12.
+//  Copyright (c) 2012 John Hurley. All rights reserved.
+//
+
+/*
+    This XPC service is essentially just a proxy to iCloud KVS, which exists since
+    the main security code cannot link against Foundation.
+    
+    See sendTSARequestWithXPC in tsaSupport.c for how to call the service
+    
+    send message to app with xpc_connection_send_message
+    
+    For now, build this with:
+    
+        ~rc/bin/buildit .  --rootsDirectory=/var/tmp -noverify -offline -target CloudKeychainProxy
+
+    and install or upgrade with:
+        
+        darwinup install /var/tmp/sec.roots/sec~dst
+        darwinup upgrade /var/tmp/sec.roots/sec~dst
+    You must use darwinup during development to update system caches
+*/
+
+//------------------------------------------------------------------------------------------------
+
+#include <AssertMacros.h>
+
+#import <Foundation/Foundation.h>
+#import <Security/Security.h>
+#import <utilities/SecCFRelease.h>
+#import <xpc/xpc.h>
+#import <xpc/private.h>
+#import <CoreFoundation/CFXPCBridge.h>
+#import <sysexits.h>
+#import <syslog.h>
+#import <CommonCrypto/CommonDigest.h>
+#include <utilities/SecXPCError.h>
+
+#import "SOSCloudKeychainConstants.h"
+#import "CKDKVSProxy.h"
+
+void finalize_connection(void *not_used);
+void handle_connection_event(const xpc_connection_t peer);
+static void cloudkeychainproxy_peer_dictionary_handler(const xpc_connection_t peer, xpc_object_t event);
+
+static bool operation_put_dictionary(xpc_object_t event);
+static bool operation_get_v2(xpc_object_t event);
+
+int ckdproxymain(int argc, const char *argv[]);
+
+static void describeXPCObject(char *prefix, xpc_object_t object)
+{
+//#ifndef NDEBUG
+    // This is useful for debugging.
+    if (object)
+    {
+        char *desc = xpc_copy_description(object);
+        secdebug(XPROXYSCOPE, "%s%s\n", prefix, desc);
+        free(desc);
+    }
+    else
+        secdebug(XPROXYSCOPE, "%s<NULL>\n", prefix);
+
+//#endif
+}
+
+static void cloudkeychainproxy_peer_dictionary_handler(const xpc_connection_t peer, xpc_object_t event)
+{
+    bool result = false;
+    int err = 0;
+    
+    require_action_string(xpc_get_type(event) == XPC_TYPE_DICTIONARY, xit, err = -51, "expected XPC_TYPE_DICTIONARY");
+
+    const char *operation = xpc_dictionary_get_string(event, kMessageKeyOperation);
+    require_action(operation, xit, result = false);
+    
+    // Check protocol version
+    uint64_t version = xpc_dictionary_get_uint64(event, kMessageKeyVersion);
+    secdebug(XPROXYSCOPE, "Reply version: %lld\n", version);
+    require_action(version == kCKDXPCVersion, xit, result = false);
+
+    // Operations
+    secdebug(XPROXYSCOPE, "Handling %s operation", operation);
+
+    if (operation && !strcmp(operation, kOperationPUTDictionary))
+         operation_put_dictionary(event);
+    else
+    if (operation && !strcmp(operation, kOperationGETv2))
+         operation_get_v2(event);
+    else
+    if (operation && !strcmp(operation, kOperationClearStore))
+    {
+        [[UbiqitousKVSProxy sharedKVSProxy] clearStore];
+        xpc_object_t replyMessage = xpc_dictionary_create_reply(event);
+        if (replyMessage)   // Caller wanted an ACK, so give one
+        {
+            xpc_dictionary_set_string(replyMessage, kMessageKeyValue, "ACK");
+            xpc_connection_send_message(peer, replyMessage);
+        }
+    }
+    else if (operation && !strcmp(operation, kOperationRemoveObjectForKey))
+    {
+        const char *keyToRemove = xpc_dictionary_get_string(event, kMessageKeyKey);
+        [[UbiqitousKVSProxy sharedKVSProxy] removeObjectForKey:[NSString stringWithCString:keyToRemove encoding:NSUTF8StringEncoding]];
+        xpc_object_t replyMessage = xpc_dictionary_create_reply(event);
+        if (replyMessage)   // Caller wanted an ACK, so give one
+        {
+            xpc_dictionary_set_string(replyMessage, kMessageKeyValue, "ACK");
+            xpc_connection_send_message(peer, replyMessage);
+        }
+    }
+    else if (operation && !strcmp(operation, kOperationSynchronize))
+    {
+        [[UbiqitousKVSProxy sharedKVSProxy] requestSynchronization:YES];
+        xpc_object_t replyMessage = xpc_dictionary_create_reply(event);
+        if (replyMessage)   // Caller wanted an ACK, so give one
+        {
+            xpc_dictionary_set_string(replyMessage, kMessageKeyValue, "ACK");
+            xpc_connection_send_message(peer, replyMessage);
+        }
+    }
+    else if (operation && !strcmp(operation, kOperationSynchronizeAndWait))
+    {
+        xpc_object_t xkeysToGetDict = xpc_dictionary_get_value(event, kMessageKeyValue);
+        xpc_object_t replyMessage = xpc_dictionary_create_reply(event);
+        xpc_object_t xkeys = xpc_dictionary_get_value(xkeysToGetDict, kMessageKeyKeysToGet);
+        NSArray *keysToGet = (__bridge NSArray *)(_CFXPCCreateCFObjectFromXPCObject(xkeys));
+        [[UbiqitousKVSProxy sharedKVSProxy] waitForSynchronization:keysToGet
+            handler:^(NSDictionary *values, NSError *err) {
+                if (replyMessage)   // Caller wanted an ACK, so give one
+                {
+                    secdebug("keytrace", "Result from [[UbiqitousKVSProxy sharedKVSProxy] waitForSynchronization:]: %@", err);
+                    xpc_object_t xobject = values ? _CFXPCCreateXPCObjectFromCFObject((__bridge CFTypeRef)(values)) : xpc_null_create();
+                    xpc_dictionary_set_value(replyMessage, kMessageKeyValue, xobject);
+                    if (err)
+                    {
+                        xpc_object_t xerrobj = SecCreateXPCObjectWithCFError((CFErrorRef)CFBridgingRetain(err));
+                        xpc_dictionary_set_value(replyMessage, kMessageKeyError, xerrobj);
+                        CFReleaseSafe((__bridge CFTypeRef)(err));
+                    }
+                    xpc_connection_send_message(peer, replyMessage);
+                }
+        }];
+        CFReleaseSafe((__bridge CFTypeRef)(keysToGet));
+    }
+    else if (operation && !strcmp(operation, kOperationRegisterKeysAndGet))
+    {
+        xpc_object_t xkeysToRegisterDict = xpc_dictionary_get_value(event, kMessageKeyValue);
+//        describeXPCObject("xkeysToRegister: ", xkeysToRegisterDict);
+        // KTR = keysToRegister
+        bool getNewKeysOnly = xpc_dictionary_get_bool(xkeysToRegisterDict, kMessageKeyGetNewKeysOnly);
+        xpc_object_t xKTRallkeys = xpc_dictionary_get_value(xkeysToRegisterDict, kMessageKeyKeysToGet);
+        xpc_object_t xKTRrequiresFirstUnlock = xpc_dictionary_get_value(xkeysToRegisterDict, kMessageKeyKeysRequireFirstUnlock);
+        xpc_object_t xKTRrequiresUnlock = xpc_dictionary_get_value(xkeysToRegisterDict, kMessageKeyKeysRequiresUnlocked);
+
+        NSArray *KTRallkeys = (__bridge NSArray *)(_CFXPCCreateCFObjectFromXPCObject(xKTRallkeys));
+        NSArray *KTRrequiresFirstUnlock = (__bridge NSArray *)(_CFXPCCreateCFObjectFromXPCObject(xKTRrequiresFirstUnlock));
+        NSArray *KTRrequiresUnlock = (__bridge NSArray *)(_CFXPCCreateCFObjectFromXPCObject(xKTRrequiresUnlock));
+
+        id object = [[UbiqitousKVSProxy sharedKVSProxy] registerKeysAndGet:getNewKeysOnly always:KTRallkeys reqFirstUnlock:KTRrequiresFirstUnlock reqUnlocked:KTRrequiresUnlock];
+        
+        CFReleaseSafe((__bridge CFTypeRef)(KTRallkeys));
+        CFReleaseSafe((__bridge CFTypeRef)(KTRrequiresFirstUnlock));
+        CFReleaseSafe((__bridge CFTypeRef)(KTRrequiresUnlock));
+
+        secdebug("keytrace", "Result from [[UbiqitousKVSProxy sharedKVSProxy] registerKeysAndGet:]: %@", object);
+        
+        xpc_object_t xobject = object ? _CFXPCCreateXPCObjectFromCFObject((__bridge CFTypeRef)(object)) : xpc_null_create();
+               
+        xpc_object_t replyMessage = xpc_dictionary_create_reply(event);
+        xpc_dictionary_set_value(replyMessage, kMessageKeyValue, xobject);
+        xpc_connection_send_message(peer, replyMessage);
+        secdebug(XPROXYSCOPE, "RegisterKeysAndGet message sent");
+    }
+    else if (operation && !strcmp(operation, kOperationUILocalNotification))
+    {
+        xpc_object_t xLocalNotificationDict = xpc_dictionary_get_value(event, kMessageKeyValue);
+//        describeXPCObject("xLocalNotificationDict: ", xLocalNotificationDict);
+        NSDictionary *localNotificationDict = (__bridge NSDictionary *)(_CFXPCCreateCFObjectFromXPCObject(xLocalNotificationDict));
+        int64_t outFlags = 0;
+        id object = [[UbiqitousKVSProxy sharedKVSProxy] localNotification:localNotificationDict outFlags:&outFlags];
+        secdebug(XPROXYSCOPE, "Result from [[UbiqitousKVSProxy sharedKVSProxy] localNotification:]: %@", object);
+        xpc_object_t xobject = object ? _CFXPCCreateXPCObjectFromCFObject((__bridge CFTypeRef)(object)) : xpc_null_create();
+        xpc_object_t replyMessage = xpc_dictionary_create_reply(event);
+        xpc_dictionary_set_int64(xobject, kMessageKeyNotificationFlags, outFlags);
+        xpc_dictionary_set_value(replyMessage, kMessageKeyValue, xobject);
+        xpc_connection_send_message(peer, replyMessage);
+        secdebug(XPROXYSCOPE, "localNotification reply sent");
+        CFReleaseSafe((__bridge CFTypeRef)(localNotificationDict));
+    }
+    else if (operation && !strcmp(operation, kOperationSetParams))
+    {
+        xpc_object_t xParamsDict = xpc_dictionary_get_value(event, kMessageKeyValue);
+        NSDictionary *paramsDict = (__bridge NSDictionary *)(_CFXPCCreateCFObjectFromXPCObject(xParamsDict));
+        [[UbiqitousKVSProxy sharedKVSProxy] setParams:paramsDict];
+        xpc_object_t replyMessage = xpc_dictionary_create_reply(event);
+        if (replyMessage)   // Caller wanted an ACK, so give one
+        {
+            xpc_dictionary_set_string(replyMessage, kMessageKeyValue, "ACK");
+            xpc_connection_send_message(peer, replyMessage);
+        }
+        secdebug(XPROXYSCOPE, "setParams reply sent");
+        CFReleaseSafe((__bridge CFTypeRef)(paramsDict));
+    }
+    else if (operation && !strcmp(operation, kOperationRequestSyncWithAllPeers))
+    {
+        [[UbiqitousKVSProxy sharedKVSProxy] requestSyncWithAllPeers];
+        xpc_object_t replyMessage = xpc_dictionary_create_reply(event);
+        if (replyMessage)   // Caller wanted an ACK, so give one
+        {
+            xpc_dictionary_set_string(replyMessage, kMessageKeyValue, "ACK");
+            xpc_connection_send_message(peer, replyMessage);
+        }
+        secdebug(XPROXYSCOPE, "RequestSyncWithAllPeers reply sent");
+    }
+    else
+    {
+        char *description = xpc_copy_description(event);
+        secdebug(XPROXYSCOPE, "Unknown op=%s request from pid %d: %s", operation, xpc_connection_get_pid(peer), description);
+        free(description);
+    }
+    result = true;
+xit:
+    if (!result)
+        describeXPCObject("handle_operation fail: ", event);
+}
+
+void finalize_connection(void *not_used)
+{
+    secdebug(XPROXYSCOPE, "finalize_connection");
+    [[UbiqitousKVSProxy sharedKVSProxy] requestSynchronization:YES];
+       xpc_transaction_end();
+}
+
+static bool operation_put_dictionary(xpc_object_t event)
+{
+    // PUT a set of objects into the KVS store. Return false if error
+
+    describeXPCObject("operation_put_dictionary event: ", event);
+    xpc_object_t xvalue = xpc_dictionary_get_value(event, kMessageKeyValue);
+    if (!xvalue)
+        return false;
+
+    CFTypeRef cfvalue = _CFXPCCreateCFObjectFromXPCObject(xvalue);
+    if (cfvalue && (CFGetTypeID(cfvalue)==CFDictionaryGetTypeID()))
+    {
+        [[UbiqitousKVSProxy sharedKVSProxy] setObjectsFromDictionary:(__bridge NSDictionary *)cfvalue];
+        CFReleaseSafe(cfvalue);
+        return true;
+    }
+    else{
+        describeXPCObject("operation_put_dictionary unable to convert to CF: ", xvalue);
+        CFReleaseSafe(cfvalue);
+    }
+    return false;
+}
+
+static bool operation_get_v2(xpc_object_t event)
+{
+    // GET a set of objects from the KVS store. Return false if error    
+    describeXPCObject("operation_get_v2 event: ", event);
+    xpc_connection_t peer = xpc_dictionary_get_remote_connection(event);
+    describeXPCObject("operation_get_v2: peer: ", peer);
+
+    xpc_object_t replyMessage = xpc_dictionary_create_reply(event);
+    if (!replyMessage)
+    {
+        secdebug(XPROXYSCOPE, "can't create replyMessage");
+        assert(true);   //must have a reply handler
+        return false;
+    }
+    xpc_object_t returnedValues = xpc_dictionary_create(NULL, NULL, 0);
+    if (!returnedValues)
+    {
+        secdebug(XPROXYSCOPE, "can't create returnedValues");
+        assert(true);   // must have a spot for the returned values
+        return false;
+    }
+
+    xpc_object_t xvalue = xpc_dictionary_get_value(event, kMessageKeyValue);
+    if (!xvalue)
+    {
+        secdebug(XPROXYSCOPE, "missing \"value\" key");
+        return false;
+    }
+    
+    xpc_object_t xkeystoget = xpc_dictionary_get_value(xvalue, kMessageKeyKeysToGet);
+    if (xkeystoget)
+    {
+        secdebug(XPROXYSCOPE, "got xkeystoget");
+        CFTypeRef keystoget = _CFXPCCreateCFObjectFromXPCObject(xkeystoget);
+        if (!keystoget || (CFGetTypeID(keystoget)!=CFArrayGetTypeID()))     // not "getAll", this is an error of some kind
+        {
+            secdebug(XPROXYSCOPE, "can't convert keystoget or is not an array");
+            CFReleaseSafe(keystoget);
+            return false;
+        }
+        
+        [(__bridge NSArray *)keystoget enumerateObjectsUsingBlock: ^ (id obj, NSUInteger idx, BOOL *stop)
+        {
+            NSString *key = (NSString *)obj;
+            id object = [[UbiqitousKVSProxy sharedKVSProxy] get:key];
+            secdebug(XPROXYSCOPE, "[UbiqitousKVSProxy sharedKVSProxy] get: key: %@, object: %@", key, object);
+            xpc_object_t xobject = object ? _CFXPCCreateXPCObjectFromCFObject((__bridge CFTypeRef)object) : xpc_null_create();
+            xpc_dictionary_set_value(returnedValues, [key UTF8String], xobject);
+            describeXPCObject("operation_get_v2: value from kvs: ", xobject);
+        }];
+    }
+    else    // get all values from kvs
+    {
+        secdebug(XPROXYSCOPE, "get all values from kvs");
+        NSDictionary *all = [[UbiqitousKVSProxy sharedKVSProxy] getAll];
+        [all enumerateKeysAndObjectsUsingBlock: ^ (id key, id obj, BOOL *stop)
+        {
+            xpc_object_t xobject = obj ? _CFXPCCreateXPCObjectFromCFObject((__bridge CFTypeRef)obj) : xpc_null_create();
+            xpc_dictionary_set_value(returnedValues, [(NSString *)key UTF8String], xobject);
+        }];
+    }
+
+    xpc_dictionary_set_uint64(replyMessage, kMessageKeyVersion, kCKDXPCVersion);
+    xpc_dictionary_set_value(replyMessage, kMessageKeyValue, returnedValues);
+    xpc_connection_send_message(peer, replyMessage);
+
+    return true;
+}
+
+static void initializeProxyObjectWithConnection(const xpc_connection_t connection)
+{
+    [[UbiqitousKVSProxy sharedKVSProxy] setItemsChangedBlock:^(CFDictionaryRef values)
+        {
+            secdebug(XPROXYSCOPE, "UbiqitousKVSProxy called back");
+            xpc_object_t xobj = _CFXPCCreateXPCObjectFromCFObject(values);
+            xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
+            xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
+            xpc_dictionary_set_string(message, kMessageKeyOperation, kMessageOperationItemChanged);
+            xpc_dictionary_set_value(message, kMessageKeyValue, xobj?xobj:xpc_null_create());
+            xpc_connection_send_message(connection, message);  // Send message; don't wait for a reply
+        }];
+}
+
+static void cloudkeychainproxy_peer_event_handler(xpc_connection_t peer, xpc_object_t event) 
+{
+    describeXPCObject("peer: ", peer);
+       xpc_type_t type = xpc_get_type(event);
+       if (type == XPC_TYPE_ERROR) {
+               if (event == XPC_ERROR_CONNECTION_INVALID) {
+                       // The client process on the other end of the connection has either
+                       // crashed or cancelled the connection. After receiving this error,
+                       // the connection is in an invalid state, and you do not need to
+                       // call xpc_connection_cancel(). Just tear down any associated state
+                       // here.
+               } else if (event == XPC_ERROR_TERMINATION_IMMINENT) {
+                       // Handle per-connection termination cleanup.
+               }
+       } else {
+               assert(type == XPC_TYPE_DICTIONARY);
+               // Handle the message.
+    //    describeXPCObject("dictionary:", event);
+        cloudkeychainproxy_peer_dictionary_handler(peer, event);
+       }
+}
+
+static void cloudkeychainproxy_event_handler(xpc_connection_t peer)
+{
+       // By defaults, new connections will target the default dispatch
+       // concurrent queue.
+
+    if (xpc_get_type(peer) != XPC_TYPE_CONNECTION)
+    {
+        secdebug(XPROXYSCOPE, "expected XPC_TYPE_CONNECTION");
+        return;
+    }
+    initializeProxyObjectWithConnection(peer);
+       xpc_connection_set_event_handler(peer, ^(xpc_object_t event)
+    {
+        cloudkeychainproxy_peer_event_handler(peer, event);
+       });
+       
+       // This will tell the connection to begin listening for events. If you
+       // have some other initialization that must be done asynchronously, then
+       // you can defer this call until after that initialization is done.
+       xpc_connection_resume(peer);
+}
+
+static void diagnostics(int argc, const char *argv[])
+{
+    @autoreleasepool
+    {
+        NSDictionary *all = [[UbiqitousKVSProxy sharedKVSProxy] getAll];
+        NSLog(@"All: %@",all);
+    }
+}
+
+int ckdproxymain(int argc, const char *argv[])
+{
+    secdebug(XPROXYSCOPE, "Starting CloudKeychainProxy");
+    char *wait4debugger = getenv("WAIT4DEBUGGER");
+    if (wait4debugger && !strcasecmp("YES", wait4debugger))
+    {
+        syslog(LOG_ERR, "Waiting for debugger");
+        kill(getpid(), SIGSTOP);
+    }
+
+    if (argc > 1) {
+        diagnostics(argc, argv);
+        return 0;
+    }
+    
+#if !TARGET_IPHONE_SIMULATOR    
+    xpc_track_activity();   // sets us up for idle timeout handling
+#endif
+
+    // DISPATCH_TARGET_QUEUE_DEFAULT
+       xpc_connection_t listener = xpc_connection_create_mach_service(xpcServiceName, NULL, XPC_CONNECTION_MACH_SERVICE_LISTENER);
+       xpc_connection_set_event_handler(listener, ^(xpc_object_t object){ cloudkeychainproxy_event_handler(object); });
+
+    [UbiqitousKVSProxy sharedKVSProxy];
+
+    // It looks to me like there is insufficient locking to allow a request to come in on the XPC connection while doing the initial all items.
+    // Therefore I'm leaving the XPC connection suspended until that has time to process.
+       xpc_connection_resume(listener);
+
+    @autoreleasepool
+    {
+        secdebug(XPROXYSCOPE, "Starting mainRunLoop");
+        NSRunLoop *runLoop = [NSRunLoop mainRunLoop];
+        [runLoop run];
+    }
+
+    secdebug(XPROXYSCOPE, "Exiting CloudKeychainProxy");
+
+    return EXIT_FAILURE;
+}
diff --git a/sec/SOSCircle/CloudKeychainProxy/en.lproj/InfoPlist.strings b/sec/SOSCircle/CloudKeychainProxy/en.lproj/InfoPlist.strings
new file mode 100644 (file)
index 0000000..477b28f
--- /dev/null
@@ -0,0 +1,2 @@
+/* Localized versions of Info.plist keys */
+
diff --git a/sec/SOSCircle/CloudKeychainProxy/scripts/PhoneTerms2.scpt b/sec/SOSCircle/CloudKeychainProxy/scripts/PhoneTerms2.scpt
new file mode 100644 (file)
index 0000000..7450706
Binary files /dev/null and b/sec/SOSCircle/CloudKeychainProxy/scripts/PhoneTerms2.scpt differ
diff --git a/sec/SOSCircle/CloudKeychainProxy/scripts/install_on_devices b/sec/SOSCircle/CloudKeychainProxy/scripts/install_on_devices
new file mode 100755 (executable)
index 0000000..53c710a
--- /dev/null
@@ -0,0 +1,39 @@
+#!/bin/zsh
+
+roots="/tmp/security.roots.tgz"
+syms="/tmp/security.syms.tgz"
+srcs="/tmp/security.src.tgz"
+sshopts=(-o CheckHostIP=no -o StrictHostKeyChecking=no -o NoHostAuthenticationForLocalhost=yes -o UserKnownHostsFile=/dev/null)
+
+locations=(`mobdev list | awk '/UDID/ { gsub(/^(.*location ID = )+|(,.*)+$/, ""); print}'`)
+
+port_offset=20000
+
+symdir="/var/mobile/secsyms"
+
+for location in $locations
+do
+       echo 'Installing to location '"$location"
+
+       tcprelay --portoffset $port_offset --locationid $location ssh >/dev/null 2>&1 &
+
+       (( sshport = $port_offset + 22 ))
+
+       echo "Copying roots to device (via port $sshport)"
+       scp -P $sshport $sshopts $roots $syms $srcs root@localhost:/var/mobile/
+
+       echo "SSH to device and do commands"
+       ssh  $sshopts -p $sshport root@localhost << END
+/bin/hostname
+/sbin/mount -uw /
+/usr/local/bin/darwinup install "/var/mobile/`basename $roots`" | grep -v '^  /'
+/usr/local/bin/darwinup uninstall superseded > /dev/null 2>&1 || true
+touch /System/Library/Caches/com.apple.xpcd/xpcd_cache.dylib
+/usr/local/bin/mobile_install rebuild internal
+/bin/launchctl stop com.apple.securityd
+/bin/launchctl stop com.apple.security.cloudkeychainproxy3
+/bin/launchctl stop com.apple.security.CircleJoinRequest
+END
+
+       kill -HUP %%
+done
diff --git a/sec/SOSCircle/CloudKeychainProxy/scripts/sosbuildroot b/sec/SOSCircle/CloudKeychainProxy/scripts/sosbuildroot
new file mode 100755 (executable)
index 0000000..efa3137
--- /dev/null
@@ -0,0 +1,31 @@
+#!/bin/zsh -e
+
+if [ ! -d "Security.xcodeproj" ]; then
+   echo "Not in correct directory to build; currently in " `pwd`
+   exit 2
+fi
+
+localbase=`basename $PWD`
+target=${1-world}
+config=${2-Release}
+roots=/var/tmp
+project=Security
+
+~rc/bin/buildit .  --rootsDirectory=/var/tmp -noverify -project $project -archive -dsymsInDstroot \
+       -target $target \
+       -configuration $config || { echo 'build failed' ; exit 1; }
+
+rootsDir=/var/tmp/${project}_${localbase}.roots
+buildRoots=$rootsDir/BuildRecords/${project}_install
+
+roottar=/tmp/security.roots.tgz
+symtar=/tmp/security.syms.tgz
+srctar=/tmp/security.src.tgz
+
+cp $rootsDir/Archives/Security_${localbase}_DSTROOT.tar.gz $roottar
+
+tar -czvf $symtar -C ${buildRoots}/Symbols . &> /dev/null
+tar -czvf $srctar -C ${rootsDir}/Sources/${project} . &> /dev/null
+
+echo "now run"
+echo " ~/bin/install_on_devices"
diff --git a/sec/SOSCircle/CloudKeychainProxy/scripts/soscopy b/sec/SOSCircle/CloudKeychainProxy/scripts/soscopy
new file mode 100755 (executable)
index 0000000..7e9b0d6
--- /dev/null
@@ -0,0 +1,13 @@
+#!/bin/zsh
+
+echo "10873 12873 15873"
+
+for port in "$@"
+do
+       echo "Copying roots to port: $item"
+       RSYNC_PASSWORD=alpine rsync -av /tmp/security.roots.tgz rsync://root@localhost:$port/root/var/mobile/
+       RSYNC_PASSWORD=alpine rsync -av /tmp/security.syms.tgz rsync://root@localhost:$port/root/var/mobile/
+       RSYNC_PASSWORD=alpine rsync -av ~/bin/sosinstallroot rsync://root@localhost:$port/root/usr/local/bin/sosinstallroot
+       RSYNC_PASSWORD=alpine rsync -av /tmp/SyncedDefaults.roots.tgz rsync://root@localhost:$port/root/var/mobile/
+done
+
diff --git a/sec/SOSCircle/CloudKeychainProxy/scripts/soscopysshkeys b/sec/SOSCircle/CloudKeychainProxy/scripts/soscopysshkeys
new file mode 100755 (executable)
index 0000000..9f555e9
--- /dev/null
@@ -0,0 +1,26 @@
+#!/bin/zsh
+
+echo 'Copying ssh keys to devices'
+
+sshopts=(-o CheckHostIP=no -o StrictHostKeyChecking=no -o NoHostAuthenticationForLocalhost=yes -o UserKnownHostsFile=/dev/null)
+
+locations=(`mobdev list | awk '/UDID/ { gsub(/^(.*location ID = )+|(,.*)+$/, ""); print}'`)
+
+port_offset=20000
+
+mkdir -p /var/tmp/roothome/.ssh/
+cat ~/.ssh/id_*.pub > /var/tmp/roothome/.ssh/authorized_keys
+
+for location in $locations
+do
+       echo 'Copying to location '"$location"
+
+       tcprelay --portoffset $port_offset --locationid $location ssh --quiet  &
+
+       (( sshport = $port_offset + 22 ))
+
+       echo "Copying file to device (via port $sshport)"
+       scp -r -P $sshport $sshopts /var/tmp/roothome/.ssh root@localhost:/var/root/
+
+       kill -HUP %%
+done
diff --git a/sec/SOSCircle/CloudKeychainProxy/scripts/sosinstallroot b/sec/SOSCircle/CloudKeychainProxy/scripts/sosinstallroot
new file mode 100644 (file)
index 0000000..b231594
--- /dev/null
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+# This script should be run as root on the target device
+
+if [ $(id -u) != "0" ]; then
+    echo "You must be root to run this script" >&2
+    exit 1
+fi
+
+echo "-----------------------------------------------"
+echo "Tell launchctl to unload the old one"
+launchctl unload -w  /System/Library/LaunchDaemons/com.apple.security.cloudkeychainproxy.plist
+
+echo "call darwinup install"
+darwinup install  /var/mobile/security.roots.tgz
+
+/usr/local/bin/darwinup uninstall superseded > /dev/null 2>&1 || true
+
+echo "Untar sym files"
+symdir="/var/mobile/secsyms"
+if [ ! -d "$symdir" ]; then
+    mkdir $symdir
+fi
+echo "Untar sym files to " $symdir
+tar -xzvf /var/mobile/security.syms.tgz -C $symdir
+echo "To use, enter e.g. in gdb: add-dsym /var/mobile/secsyms/SecurityTests.app.dSYM"
+
+echo "touch cache"
+touch /System/Library/Caches/com.apple.xpcd/xpcd_cache.dylib 
+
+echo "Killing off old CloudKeychainProxy..."
+killall -9 CloudKeychainProxy || true
+
+echo "Tell launchctl to load the new one"
+launchctl  load -w /System/Library/LaunchDaemons/com.apple.security.cloudkeychainproxy.plist
+echo "done"
+
+echo "Kill the old SyncTest"
+killall -9 SyncTest2  || true
+
+echo "Rebuild mobile app cache"
+/usr/local/bin/mobile_install rebuild internal || true
diff --git a/sec/SOSCircle/CloudKeychainProxy/scripts/sosreset b/sec/SOSCircle/CloudKeychainProxy/scripts/sosreset
new file mode 100644 (file)
index 0000000..8737324
--- /dev/null
@@ -0,0 +1,10 @@
+#/bin/sh
+
+killall SyncTest2; killall -9 securityd; killall CloudKeychainProxy; rm /Library/Keychains/PersistedAccount.plist 
+rm /tmp/com.apple.security.cloudkeychain.keysToRegister.plist
+
+/AppleInternal/Applications/SecurityTests.app/SecurityTests sc_kvstool -v --  --clear
+
+killall SyncTest2; killall -9 securityd; killall CloudKeychainProxy; rm /Library/Keychains/PersistedAccount.plist 
+rm /tmp/com.apple.security.cloudkeychain.keysToRegister.plist
+
diff --git a/sec/SOSCircle/CloudKeychainProxy/scripts/sshauser b/sec/SOSCircle/CloudKeychainProxy/scripts/sshauser
new file mode 100755 (executable)
index 0000000..81fc6fb
--- /dev/null
@@ -0,0 +1,69 @@
+#!/usr/bin/expect --
+
+proc usage {} {
+  puts stderr "Usage: sshauser \[ --retry \] port user \[ command ... \]"
+  exit 22
+}
+
+if { $argc < 2 } {
+    usage
+}
+
+set arg 0
+set retry 0
+if { [lindex $argv $arg] == "--retry" } {
+  set retry 1
+  set arg [expr $arg + 1]
+}
+set offset [lindex $argv $arg]
+set arg [expr $arg + 1]
+set username [lindex $argv $arg]
+set arg [expr $arg + 1]
+set command [lrange $argv $arg $argc]
+
+set password "alpine"
+set timeout 60
+
+# trap SIGWINCH and pass to spawned process
+trap {
+ set rows [stty rows]
+ set cols [stty columns]
+ stty rows $rows columns $cols < $spawn_out(slave,name)
+} WINCH
+
+set continue 1
+while { $continue } {
+       set continue $retry
+       spawn ssh -o NoHostAuthenticationForLocalhost=yes -p $offset $username@localhost
+       while { 1 } {
+               expect "Are you sure you want to continue connecting (yes/no)" {
+                       send "yes\r" 
+               } "password:" { 
+                       send "$password\r" 
+               } "#" {
+                        if { $argc > 2 } { send "$command\r" }
+                        interact
+                        break
+               } "mobile" {
+                        if { $argc > 2 } { send "$command\r" }
+                        interact
+                        break
+               } "ssh: connect to host localhost port $offset: Connection refused" {
+                       if { $retry } {
+                         wait
+                         set continue $retry
+                         send_user "conection lost... retrying in 5 seconds.\n"
+                         sleep 5
+                       }
+                       break
+               } "ssh_exchange_identification: read: Connection reset by peer" {
+                       if { $retry } {
+                         wait
+                         set continue $retry
+                         send_user "Device rebooting waiting for 15 seconds.\n"
+                         sleep 15
+                       }
+                       break
+               }
+       }
+}
diff --git a/sec/SOSCircle/Empty.c b/sec/SOSCircle/Empty.c
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/sec/SOSCircle/Regressions/CKDKeyValueStore.h b/sec/SOSCircle/Regressions/CKDKeyValueStore.h
new file mode 100644 (file)
index 0000000..4875922
--- /dev/null
@@ -0,0 +1,78 @@
+//
+//  CKDKeyValueStore.h
+//  sec
+//
+//  Created by John Hurley on 9/9/12.
+//
+//
+
+#import <Foundation/Foundation.h>
+//#import "CKDKVSProxy.h"
+#import "SOSCloudKeychainConstants.h"
+#import "SOSCloudKeychainClient.h"
+
+extern CFStringRef kCKDKVSRemoteStoreID;
+extern CFStringRef kCKDAWSRemoteStoreID;
+
+//--- protocol ---
+
+@protocol CKDKVSDelegate <NSObject>
+
+@required
+
+- (id)objectForKey:(NSString *)aKey;
+- (void)setObject:(id)anObject forKey:(NSString *)aKey;
+- (void)removeObjectForKey:(NSString *)aKey;
+
+- (NSDictionary *)dictionaryRepresentation;
+
+- (BOOL)synchronize;
+
+@optional
+- (BOOL)isLocalKVS;
+// DEBUG
+- (void)setDictionaryRepresentation:(NSMutableDictionary *)initialValue;
+- (void)clearPersistentStores;
+
+@end
+
+//--- interface ---
+
+@interface CKDKeyValueStore : NSObject <CKDKVSDelegate>
+{
+    BOOL localKVS;
+    BOOL persistStore;
+    CloudItemsChangedBlock itemsChangedCallback;
+}
+@property (retain) id <CKDKVSDelegate> delegate;
+@property (retain) NSString *identifier;
+@property (retain) NSString *path;
+- (BOOL)synchronize;
++ (CKDKeyValueStore *)defaultStore:(NSString *)identifier itemsChangedBlock:(CloudItemsChangedBlock)itemsChangedBlock;
+- (id)initWithIdentifier:(NSString *)xidentifier itemsChangedBlock:(CloudItemsChangedBlock)itemsChangedBlock;
+
++ (CFStringRef)remoteStoreID;
+
+- (id)initWithItemsChangedBlock:(CloudItemsChangedBlock)itemsChangedBlock;
+- (void)cloudChanged:(NSNotification*)notification;
+
+@end
+
+@interface CKDKeyValueStoreCollection : NSObject
+{
+    dispatch_queue_t syncrequestqueue;
+    NSMutableDictionary *store;
+}
+@property (retain) NSMutableDictionary *collection;
+
++ (id)sharedInstance;
++ (id <CKDKVSDelegate>)defaultStore:(NSString *)identifier itemsChangedBlock:(CloudItemsChangedBlock)itemsChangedBlock;
++ (void)enqueueWrite:(id)anObject forKey:(NSString *)aKey from:(NSString *)identifier;
++ (id)enqueueWithReply:(NSString *)aKey;
++ (BOOL)enqueueSyncWithReply;
++ (void)postItemChangedNotification:(NSString *)keyThatChanged from:(NSString *)identifier;
++ (void)postItemsChangedNotification:(NSArray *)keysThatChanged from:(NSString *)identifier;
+
+@end
diff --git a/sec/SOSCircle/Regressions/CKDKeyValueStore.m b/sec/SOSCircle/Regressions/CKDKeyValueStore.m
new file mode 100644 (file)
index 0000000..6839443
--- /dev/null
@@ -0,0 +1,365 @@
+/*
+ * Copyright (c) 2012-2013 Apple, Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+//
+//  CKDKeyValueStore.m
+//  sec
+//
+
+#import "CKDKeyValueStore.h"
+#import "CKDPersistentState.h"
+
+/*
+    pseudo-code
+    
+    g = [CKDKeyValueStore defaultStore:mystoreID];
+    [g setObject:obj forKey:@"foo"];
+    [g synchronize];
+*/
+
+#define DONTUSENOTIFICATIONS true
+
+static const int verboseCKDKVSDebugging = false;
+
+#ifndef NDEBUG
+    #define pdebug(format...) \
+        do {  \
+            if (verboseCKDKVSDebugging) \
+                NSLog(format);  \
+        } while (0)
+#else
+    //empty
+    #define pdebug(format...)
+#endif
+
+
+extern CFStringRef kCKDKVSRemoteStoreID;
+CFStringRef kCKDKVSRemoteStoreID = CFSTR("REMOTE");
+CFStringRef kCKDAWSRemoteStoreID = CFSTR("AWS");
+
+NSString * const kCKDKVSWhoChangedItemKey = @"WhoChangedItemKey";
+
+static NSString * const ourNSUbiquitousKeyValueStoreDidChangeExternallyNotification = @"ourNSUbiquitousKeyValueStoreDidChangeExternallyNotification";
+
+// MARK: ----- CKDKeyValueStore -----
+
+@implementation CKDKeyValueStore
+
+- (id)initWithIdentifier:(NSString *)identifier itemsChangedBlock:(CloudItemsChangedBlock)itemsChangedBlock
+{
+    if (self = [super init])
+    {
+        self.delegate = self;
+        self.identifier = identifier;
+        self->localKVS = true;
+        
+        // copy blocks onto heap
+        itemsChangedCallback = Block_copy(itemsChangedBlock);
+        
+         [[NSNotificationCenter defaultCenter] addObserver: self
+            selector: @selector (iCloudAccountAvailabilityChanged:)
+            name: NSUbiquityIdentityDidChangeNotification
+            object: nil];
+        
+        [[NSNotificationCenter defaultCenter] addObserver:self 
+            selector:@selector(cloudChanged:)
+            name:ourNSUbiquitousKeyValueStoreDidChangeExternallyNotification
+            object:nil];
+    }
+    return self;
+}
+
++ (CKDKeyValueStore *)defaultStore:(NSString *)identifier itemsChangedBlock:(CloudItemsChangedBlock)itemsChangedBlock
+{
+    return [CKDKeyValueStoreCollection defaultStore:identifier itemsChangedBlock:itemsChangedBlock];
+}
+
+- (BOOL)synchronize
+{
+    BOOL value = NO;
+    value = [CKDKeyValueStoreCollection enqueueSyncWithReply];
+
+    return value;
+}
+
+- (BOOL)isLocalKVS
+{
+    return YES;
+}
+
+- (id)objectForKey:(NSString *)aKey
+{
+    pdebug(@"retrieving value for key \"%@\"", aKey);
+    id value = [CKDKeyValueStoreCollection enqueueWithReply:aKey];
+    pdebug(@"retrieved value for key \"%@\": %@", aKey, value);
+    return value;
+}
+
+- (void)setObject:(id)anObject forKey:(NSString *)aKey
+{
+    pdebug(@"setting value for key \"%@\"", aKey);
+    [CKDKeyValueStoreCollection enqueueWrite:anObject forKey:aKey from:self.identifier];
+}
+
+- (void)removeObjectForKey:(NSString *)aKey
+{
+    pdebug(@"removing value for key \"%@\"", aKey);
+    [CKDKeyValueStoreCollection enqueueWrite:NULL forKey:aKey from:self.identifier];
+}
+
+- (NSDictionary *)dictionaryRepresentation
+{
+    pdebug(@"retrieving dictionaryRepresentation");
+    id value = [CKDKeyValueStoreCollection enqueueWithReply:NULL];
+    pdebug(@"retrieved dictionaryRepresentation: %@", value);
+    return value;
+}
+
+- (void)setDictionaryRepresentation:(NSMutableDictionary *)initialValue
+{
+    // DEBUG
+    [CKDKeyValueStoreCollection enqueueWrite:initialValue forKey:NULL from:self.identifier];
+}
+
+- (void)clearPersistentStores
+{
+}
+
++ (CFStringRef)remoteStoreID
+{
+    return kCKDKVSRemoteStoreID;
+}
+
+// MARK: ----- copied from real kvs -----
+
+- (id)initWithItemsChangedBlock:(CloudItemsChangedBlock)itemsChangedBlock
+{
+    if (self = [super init])
+    {
+        // copy blocks onto heap
+        itemsChangedCallback = Block_copy(itemsChangedBlock);
+        
+         [[NSNotificationCenter defaultCenter] addObserver: self
+            selector: @selector (iCloudAccountAvailabilityChanged:)
+            name: NSUbiquityIdentityDidChangeNotification
+            object: nil];
+        
+        [[NSNotificationCenter defaultCenter] addObserver:self 
+            selector:@selector(cloudChanged:)
+            name:ourNSUbiquitousKeyValueStoreDidChangeExternallyNotification
+            object:nil];
+    }
+    return self;
+}
+
+- (void)dealloc
+{
+
+    [[NSNotificationCenter defaultCenter] removeObserver:self
+        name:ourNSUbiquitousKeyValueStoreDidChangeExternallyNotification object:nil];
+
+    [[NSNotificationCenter defaultCenter] removeObserver:self 
+        name:NSUbiquityIdentityDidChangeNotification object:nil];
+
+    Block_release(itemsChangedCallback);
+    [super dealloc];
+}
+
+- (void)cloudChanged:(NSNotification*)notification
+{
+    /*
+        Posted when the value of one or more keys in the local key-value store changed due to incoming data pushed from iCloud.
+        This notification is sent only upon a change received from iCloud; it is not sent when your app sets a value.
+
+        The user info dictionary can contain the reason for the notification as well as a list of which values changed, as follows:
+
+        The value of the NSUbiquitousKeyValueStoreChangeReasonKey key, when present, indicates why the key-value store changed. 
+        Its value is one of the constants in “Change Reason Values .” The value of the NSUbiquitousKeyValueStoreChangedKeysKey, 
+        when present, is an array of strings, each the name of a key whose value changed. The notification object is the 
+        NSUbiquitousKeyValueStore object whose contents changed.
+        
+        enum {
+            NSUbiquitousKeyValueStoreServerChange NS_ENUM_AVAILABLE(10_7, 5_0),
+            NSUbiquitousKeyValueStoreInitialSyncChange NS_ENUM_AVAILABLE(10_7, 5_0),
+            NSUbiquitousKeyValueStoreQuotaViolationChange NS_ENUM_AVAILABLE(10_7, 5_0),
+            NSUbiquitousKeyValueStoreAccountChange NS_ENUM_AVAILABLE(10_8, 6_0)
+        };
+
+    */
+    
+    NSDictionary *userInfo = [notification userInfo];
+    NSNumber *reason = [userInfo objectForKey:NSUbiquitousKeyValueStoreChangeReasonKey];
+    NSInteger reasonValue = -1;
+    
+    pdebug(@"cloudChanged notification: %@", notification);
+
+    NSString *whoChangedIt = [userInfo objectForKey:kCKDKVSWhoChangedItemKey];
+    
+    if (self.identifier && whoChangedIt && [self.identifier isEqualToString:whoChangedIt])
+    {
+        pdebug(@"cloudChanged by us (%@), ignoring event", self.identifier);
+        return;
+    }
+    
+    if (reason)
+    {
+        reasonValue = [reason integerValue];
+        NSArray *reasonStrings = [NSArray arrayWithObjects:@"Server", @"InitialSync", @"QuotaViolation", @"Account", @"unknown", nil];
+        long ridx = (NSUbiquitousKeyValueStoreServerChange <= reasonValue && reasonValue <= NSUbiquitousKeyValueStoreAccountChange)?reasonValue : 5;
+        pdebug(@"cloudChanged with reason %ld (%@ Change)", (long)reasonValue, [reasonStrings objectAtIndex:ridx]);
+    }
+    
+    if ((reasonValue == NSUbiquitousKeyValueStoreServerChange) ||
+        (reasonValue == NSUbiquitousKeyValueStoreInitialSyncChange))
+    {
+        NSArray *keysChangedInCloud = [userInfo objectForKey:NSUbiquitousKeyValueStoreChangedKeysKey];
+        pdebug(@"keysChangedInCloud: %@", keysChangedInCloud);
+        NSMutableDictionary *changedValues = [NSMutableDictionary dictionaryWithCapacity:0];
+        [keysChangedInCloud enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop)
+        {
+            NSString *key = (NSString *)obj;
+        //    itemChangedCallback(key, [self.store objectForKey:key]);
+            id anObject = @"FIXME"; //[self.store objectForKey:key];
+            [changedValues setObject:anObject forKey:key];
+
+            pdebug(@"storeChanged updated value for %@", key);
+        }];
+        itemsChangedCallback((CFDictionaryRef)changedValues); // fix me *************************
+    }
+}
+
+
+
+@end
+
+// MARK: ----- CKDKeyValueStoreCollection -----
+
+@implementation CKDKeyValueStoreCollection
+
+- (id)init
+{
+    if (self = [super init])
+    {
+        self.collection = [NSMutableDictionary dictionaryWithCapacity:0];
+        self->syncrequestqueue = dispatch_queue_create("syncrequestqueue", DISPATCH_QUEUE_SERIAL);
+        self->store = [NSMutableDictionary dictionaryWithCapacity:0];
+    }
+    return self;
+}
+
+// maybe should return (CKDKeyValueStore *), main thing is that it matches the protocol
++ (id <CKDKVSDelegate>)defaultStore:(NSString *)identifier itemsChangedBlock:(CloudItemsChangedBlock)itemsChangedBlock
+{
+    // look it up in the collection and return singleton
+    if (identifier == NULL)
+        return (id <CKDKVSDelegate>)[NSUbiquitousKeyValueStore defaultStore];
+
+    CKDKeyValueStoreCollection *mall = [CKDKeyValueStoreCollection sharedInstance];
+    id <CKDKVSDelegate> store =  mall.collection[identifier];
+    if (!store)
+    {
+        store = [[CKDKeyValueStore alloc] initWithIdentifier:identifier itemsChangedBlock:itemsChangedBlock];
+        mall->_collection[identifier] = store;
+    }
+    return store;
+
+}
+
++ (id)sharedInstance
+{
+    static dispatch_once_t once;
+    static CKDKeyValueStoreCollection *sharedStoreCollection;
+    dispatch_once(&once, ^ { sharedStoreCollection = [[self alloc] init]; });
+    return sharedStoreCollection;
+}
+
++ (void)enqueueWrite:(id)anObject forKey:(NSString *)aKey from:(NSString *)identifier
+{
+    CKDKeyValueStoreCollection *mall = [CKDKeyValueStoreCollection sharedInstance];
+    dispatch_async(mall->syncrequestqueue, ^void ()
+    {
+        if (aKey==NULL && (CFGetTypeID(anObject)==CFDictionaryGetTypeID()))
+        {
+            [mall->store setDictionary:anObject];
+            [self postItemsChangedNotification:[anObject allKeys] from:identifier];
+        }
+        else
+        {
+            if (anObject)
+                [mall->store setObject:anObject forKey:aKey];
+            else
+                [mall->store removeObjectForKey:aKey];
+            [CKDKeyValueStoreCollection postItemChangedNotification:aKey from:identifier];
+        }
+
+    });
+}
+
++ (id)enqueueWithReply:(NSString *)aKey
+{
+    __block id value = NULL;
+    CKDKeyValueStoreCollection *mall = [CKDKeyValueStoreCollection sharedInstance];
+    dispatch_sync(mall->syncrequestqueue,  ^void ()
+    {
+        value = (aKey==NULL)?mall->store:[mall->store objectForKey:aKey];
+    });
+    return value;
+}
+
++ (BOOL)enqueueSyncWithReply
+{
+    // basically a barrier
+    __block BOOL value = false;
+    CKDKeyValueStoreCollection *mall = [CKDKeyValueStoreCollection sharedInstance];
+    dispatch_sync(mall->syncrequestqueue,  ^void ()
+    {
+        value = true;
+    });
+    return value;
+}
+
++ (void)postItemChangedNotification:(NSString *)keyThatChanged from:(NSString *)identifier
+{
+    // convenience routine when a single key changes
+    NSArray *keysThatChanged = [NSArray arrayWithObject:keyThatChanged];
+    [self postItemsChangedNotification:keysThatChanged from:identifier];
+//  [keysThatChanged release];
+}
+
++ (void)postItemsChangedNotification:(NSArray *)keysThatChanged from:(NSString *)identifier
+{
+    // add in array of keys plus the id of who changed it
+    NSDictionary *aUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
+        keysThatChanged, NSUbiquitousKeyValueStoreChangedKeysKey,
+        @(NSUbiquitousKeyValueStoreServerChange), NSUbiquitousKeyValueStoreChangeReasonKey,
+        identifier, kCKDKVSWhoChangedItemKey,
+        nil];
+
+    [[NSNotificationCenter defaultCenter] postNotificationName:ourNSUbiquitousKeyValueStoreDidChangeExternallyNotification
+        object:nil userInfo:aUserInfo];
+ //       NSArray *keysChangedInCloud = [userInfo objectForKey:NSUbiquitousKeyValueStoreChangedKeysKey];
+}
+
+
+@end
+
diff --git a/sec/SOSCircle/Regressions/SOSCircle_regressions.h b/sec/SOSCircle/Regressions/SOSCircle_regressions.h
new file mode 100644 (file)
index 0000000..e96e7ae
--- /dev/null
@@ -0,0 +1,32 @@
+/* To add a test:
+ 1) add it here
+ 2) Add it as command line argument for SecurityTest.app in the Release and Debug schemes
+ */
+#include <test/testmore.h>
+
+ONE_TEST(sc_20_keynames)
+ONE_TEST(sc_30_peerinfo)
+ONE_TEST(sc_40_circle)
+OFF_ONE_TEST(sc_41_cloudcircle) // This is destructive to the cloud state
+OFF_ONE_TEST(sc_51_persistentEC)
+
+#ifdef NO_SERVER
+ONE_TEST(sc_60_peer)
+ONE_TEST(sc_70_engine)
+ONE_TEST(sc_75_circle_engine)
+#else
+OFF_ONE_TEST(sc_60_peer)
+OFF_ONE_TEST(sc_70_engine)
+OFF_ONE_TEST(sc_75_circle_engine)
+#endif
+
+OFF_ONE_TEST(sc_90_ckdclient)
+OFF_ONE_TEST(sc_95_ckd2client)
+OFF_ONE_TEST(sc_100_devicecircle)
+OFF_ONE_TEST(sc_101_accountsync)
+OFF_ONE_TEST(sc_102_cfusernotification)
+OFF_ONE_TEST(sc_103_syncupdate)
+OFF_ONE_TEST(sc_120_cloudcircle)
+ONE_TEST(sc_130_resignationticket)
+
+
diff --git a/sec/SOSCircle/Regressions/SOSRegressionUtilities.c b/sec/SOSCircle/Regressions/SOSRegressionUtilities.c
new file mode 100644 (file)
index 0000000..6c7729d
--- /dev/null
@@ -0,0 +1,485 @@
+/*
+ * Copyright (c) 2012 Apple Computer, Inc. All Rights Reserved.
+ * 
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+//
+//  SOSRegressionUtilities.c
+//
+
+#include <AssertMacros.h>
+#include <stdio.h>
+#include <Security/SecItem.h>
+
+#include <utilities/SecCFWrappers.h>
+#include <utilities/debugging.h>
+
+#include <SecureObjectSync/SOSAccount.h>
+#include <SecureObjectSync/SOSCircle.h>
+#include <SecureObjectSync/SOSInternal.h>
+#include <SecureObjectSync/SOSPeerInfoInternal.h>
+
+#include <SOSCloudKeychainClient.h>
+#include "SOSRegressionUtilities.h"
+#include "SOSInternal.h"
+
+#if TARGET_OS_IPHONE
+#include <MobileGestalt.h>
+#endif
+
+static const uint64_t maxTimeToWaitInSeconds = 30ull * NSEC_PER_SEC;
+
+// MARK: ----- SOS General -----
+
+const char *cloudKeychainProxyPath = "/System/Library/Frameworks/Security.framework/Resources/CloudKeychainProxy.bundle/CloudKeychainProxy";
+
+static const char *basecfabsoluteTimeToString(CFAbsoluteTime abstime, CFTimeZoneRef tz)
+{
+    CFGregorianDate greg = CFAbsoluteTimeGetGregorianDate(abstime, NULL);
+    char str[20];
+    if (19 != snprintf(str, 20, "%4.4d-%2.2d-%2.2d_%2.2d:%2.2d:%2.2d",
+        (int)greg.year, greg.month, greg.day, greg.hour, greg.minute, (int)greg.second))
+        str[0]=0;
+    char *data = (char *)malloc(20);
+    strncpy(data, str, 20);
+    return data;
+}
+
+const char *cfabsoluteTimeToString(CFAbsoluteTime abstime)
+{
+    return basecfabsoluteTimeToString(abstime, NULL);
+}
+
+const char *cfabsoluteTimeToStringLocal(CFAbsoluteTime abstime)
+{
+    // Caller must release using free
+    CFDateFormatterRef formatter = NULL;
+    CFTimeZoneRef tz = NULL;
+       CFLocaleRef locale = NULL;
+    CFDateRef date = NULL;
+    CFStringRef cftime_string = NULL;
+    char *time_string = NULL;
+    char buffer[1024] = {0,};
+    size_t sz;
+    
+    require(tz = CFTimeZoneCopySystem(), xit);
+    require(locale = CFLocaleCreate(NULL, CFSTR("en_US")), xit);
+    
+    require(formatter = CFDateFormatterCreate(kCFAllocatorDefault, locale, kCFDateFormatterShortStyle, kCFDateFormatterShortStyle), xit);
+    CFDateFormatterSetFormat(formatter, CFSTR("MM/dd/yy HH:mm:ss.SSS zzz"));
+    require(date = CFDateCreate(kCFAllocatorDefault, abstime), xit);
+    require(cftime_string = CFDateFormatterCreateStringWithDate(kCFAllocatorDefault, formatter, date), xit);
+
+    CFStringGetCString(cftime_string, buffer, 1024, kCFStringEncodingUTF8);
+    sz = strnlen(buffer, 1024);
+    time_string = (char *)malloc(sz);
+    strncpy(time_string, buffer, sz+1);
+xit:
+    CFReleaseSafe(tz);
+    CFReleaseSafe(formatter);
+    CFReleaseSafe(locale);
+    CFReleaseSafe(date);
+    CFReleaseSafe(cftime_string);
+    return time_string;
+}
+
+#include <sys/stat.h>
+
+static int file_exist (const char *filename)
+{
+    struct stat buffer;   
+    return (stat (filename, &buffer) == 0);
+}
+
+bool XPCServiceInstalled(void)
+{
+    return file_exist(cloudKeychainProxyPath);
+}
+
+void registerForKVSNotifications(const void *observer, CFStringRef name, CFNotificationCallback callBack)
+{
+    // observer is basically a context; name may not be null
+    CFNotificationCenterRef center = CFNotificationCenterGetDarwinNotifyCenter();
+    CFNotificationSuspensionBehavior suspensionBehavior = CFNotificationSuspensionBehaviorDeliverImmediately;    //ignored?
+    CFNotificationCenterAddObserver(center, observer, callBack, name, NULL, suspensionBehavior);
+}
+
+void testPutObjectInCloudAndSync(CFStringRef key, CFTypeRef object, CFErrorRef *error, dispatch_group_t dgroup, dispatch_queue_t processQueue)
+{
+    testPutObjectInCloud(key, object, error, dgroup, processQueue);
+    testSynchronize(processQueue, dgroup);
+}
+
+void testPutObjectInCloud(CFStringRef key, CFTypeRef object, CFErrorRef *error, dispatch_group_t dgroup, dispatch_queue_t processQueue)
+{
+    secerror("testPutObjectInCloud: key: %@, %@", key, object);
+    CFDictionaryRef objects = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, key, object, NULL);
+    if (objects)
+    {
+        dispatch_group_enter(dgroup);
+        SOSCloudKeychainPutObjectsInCloud(objects, processQueue, ^ (CFDictionaryRef returnedValues, CFErrorRef error)
+        {
+            secerror("testPutObjectInCloud returned: %@", returnedValues);
+            if (error)
+            {
+                secerror("testPutObjectInCloud returned: %@", error);
+                CFRelease(error);
+            }
+            dispatch_group_leave(dgroup);
+        });
+        CFRelease(objects);
+    }    
+}
+
+CFTypeRef testGetObjectFromCloud(CFStringRef key, dispatch_queue_t processQueue, dispatch_group_t dgroup)
+{
+    // TODO: make sure we return NULL, not CFNull
+    secerror("start");
+    CFMutableArrayRef keysToGet = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
+    CFArrayAppendValue(keysToGet, key);
+
+    __block CFTypeRef object = NULL;
+
+    dispatch_semaphore_t waitSemaphore = dispatch_semaphore_create(0);
+    dispatch_time_t finishTime = dispatch_time(DISPATCH_TIME_NOW, maxTimeToWaitInSeconds);
+
+    dispatch_group_enter(dgroup);
+    SOSCloudKeychainGetObjectsFromCloud(keysToGet, processQueue, ^ (CFDictionaryRef returnedValues, CFErrorRef error)
+    {
+        secerror("SOSCloudKeychainGetObjectsFromCloud returned: %@", returnedValues);
+        if (returnedValues)
+        {
+            object = (CFTypeRef)CFDictionaryGetValue(returnedValues, key);
+            if (object)
+                CFRetain(object);
+        }
+        if (error)
+        {
+            secerror("SOSCloudKeychainGetObjectsFromCloud returned error: %@", error);
+     //       CFRelease(*error);
+        }
+        dispatch_group_leave(dgroup);
+        secerror("SOSCloudKeychainGetObjectsFromCloud block exit: %@", object);
+        dispatch_semaphore_signal(waitSemaphore);
+    });
+    
+       dispatch_semaphore_wait(waitSemaphore, finishTime);
+       dispatch_release(waitSemaphore);
+    if (object && (CFGetTypeID(object) == CFNullGetTypeID()))   // return a NULL instead of a CFNull
+    {
+        CFRelease(object);
+        object = NULL;
+    }
+    secerror("returned: %@", object);
+    return object;
+}
+
+CFTypeRef testGetObjectsFromCloud(CFArrayRef keysToGet, dispatch_queue_t processQueue, dispatch_group_t dgroup)
+{
+    __block CFTypeRef object = NULL;
+
+    dispatch_semaphore_t waitSemaphore = dispatch_semaphore_create(0);
+    dispatch_time_t finishTime = dispatch_time(DISPATCH_TIME_NOW, maxTimeToWaitInSeconds);
+
+    dispatch_group_enter(dgroup);
+    
+    CloudKeychainReplyBlock replyBlock =
+        ^ (CFDictionaryRef returnedValues, CFErrorRef error)
+    {
+        secerror("SOSCloudKeychainGetObjectsFromCloud returned: %@", returnedValues);
+        object = returnedValues;
+        if (object)
+            CFRetain(object);
+        if (error)
+        {
+            secerror("SOSCloudKeychainGetObjectsFromCloud returned error: %@", error);
+     //       CFRelease(*error);
+        }
+        dispatch_group_leave(dgroup);
+        secerror("SOSCloudKeychainGetObjectsFromCloud block exit: %@", object);
+        dispatch_semaphore_signal(waitSemaphore);
+    };
+    
+    if (!keysToGet)
+        SOSCloudKeychainGetAllObjectsFromCloud(processQueue, replyBlock);
+    else
+        SOSCloudKeychainGetObjectsFromCloud(keysToGet, processQueue, replyBlock);
+    
+       dispatch_semaphore_wait(waitSemaphore, finishTime);
+       dispatch_release(waitSemaphore);
+    if (object && (CFGetTypeID(object) == CFNullGetTypeID()))   // return a NULL instead of a CFNull
+    {
+        CFRelease(object);
+        object = NULL;
+    }
+    secerror("returned: %@", object);
+    return object;
+}
+
+bool testRegisterKeys(CFArrayRef keysToRegister, dispatch_queue_t processQueue, dispatch_group_t dgroup)
+{
+    __block bool result = false;
+
+    dispatch_semaphore_t waitSemaphore = dispatch_semaphore_create(0);
+    dispatch_time_t finishTime = dispatch_time(DISPATCH_TIME_NOW, maxTimeToWaitInSeconds);
+
+        dispatch_group_enter(dgroup);
+    SOSCloudKeychainRegisterKeysAndGet(keysToRegister, processQueue,
+            ^ (CFDictionaryRef returnedValues, CFErrorRef error)
+            {
+                secerror("testRegisterKeys returned: %@", returnedValues);
+                if (error)
+                {
+                secerror("testRegisterKeys returned: %@", error);
+                CFRelease(error);
+                }
+                dispatch_group_leave(dgroup);
+                result = true;
+            dispatch_semaphore_signal(waitSemaphore);
+            },
+           ^ (CFDictionaryRef returnedValues)
+           {
+               secerror("testRegisterKeys returned: %@", returnedValues);
+               dispatch_group_leave(dgroup);
+               result = true;
+               dispatch_semaphore_signal(waitSemaphore);
+           });
+
+       dispatch_semaphore_wait(waitSemaphore, finishTime);
+       dispatch_release(waitSemaphore);
+//    printTimeNow("finished registerKeysForKVS");
+    return result;
+}
+
+bool testSynchronize(dispatch_queue_t processQueue, dispatch_group_t dgroup)
+{
+    __block bool result = false;
+    dispatch_semaphore_t waitSemaphore = dispatch_semaphore_create(0);
+    dispatch_time_t finishTime = dispatch_time(DISPATCH_TIME_NOW, maxTimeToWaitInSeconds);
+
+    dispatch_group_enter(dgroup);
+
+    SOSCloudKeychainSynchronize(processQueue, ^(CFDictionaryRef returnedValues, CFErrorRef error)
+        {
+            result = true;
+            dispatch_group_leave(dgroup);
+            dispatch_semaphore_signal(waitSemaphore);
+        });
+    
+       dispatch_semaphore_wait(waitSemaphore, finishTime);
+       dispatch_release(waitSemaphore);
+    return result;
+}
+
+bool testClearAll(dispatch_queue_t processQueue, dispatch_group_t dgroup)
+{
+    __block bool result = false;
+    dispatch_semaphore_t waitSemaphore = dispatch_semaphore_create(0);
+    dispatch_time_t finishTime = dispatch_time(DISPATCH_TIME_NOW, maxTimeToWaitInSeconds);
+
+    dispatch_group_enter(dgroup);
+
+    SOSCloudKeychainClearAll(processQueue, ^(CFDictionaryRef returnedValues, CFErrorRef error)
+        {
+            result = true;
+            secerror("SOSCloudKeychainClearAll returned: %@", error);
+            dispatch_group_leave(dgroup);
+            dispatch_semaphore_signal(waitSemaphore);
+        });
+    
+       dispatch_semaphore_wait(waitSemaphore, finishTime);
+       dispatch_release(waitSemaphore);
+    secerror("SOSCloudKeychainClearAll exit");
+    return result;
+}
+
+void unregisterFromKVSNotifications(const void *observer)
+{
+    CFNotificationCenterRemoveEveryObserver(CFNotificationCenterGetDarwinNotifyCenter(), observer);
+}
+
+//
+// MARK: SOSPeerInfo creation helpers
+//
+
+CFDictionaryRef SOSCreatePeerGestaltFromName(CFStringRef name)
+{
+    return CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
+                                        kPIUserDefinedDeviceName, name,
+                                        NULL);
+}
+
+
+SOSPeerInfoRef SOSCreatePeerInfoFromName(CFStringRef name, SecKeyRef* outSigningKey, CFErrorRef *error)
+{
+    SOSPeerInfoRef result = NULL;
+    SecKeyRef publicKey = NULL;
+    CFDictionaryRef gestalt = NULL;
+
+    require(outSigningKey, exit);
+
+    GeneratePermanentECPair(256, &publicKey, outSigningKey);
+
+    gestalt = SOSCreatePeerGestaltFromName(name);
+    require(gestalt, exit);
+
+    result = SOSPeerInfoCreate(NULL, gestalt, *outSigningKey, error);
+
+exit:
+    CFReleaseNull(gestalt);
+    CFReleaseNull(publicKey);
+
+    return result;
+}
+
+SOSFullPeerInfoRef SOSCreateFullPeerInfoFromName(CFStringRef name, SecKeyRef* outSigningKey, CFErrorRef *error)
+{
+    SOSFullPeerInfoRef result = NULL;
+    SecKeyRef publicKey = NULL;
+    CFDictionaryRef gestalt = NULL;
+
+    require(outSigningKey, exit);
+
+    GeneratePermanentECPair(256, &publicKey, outSigningKey);
+
+    gestalt = SOSCreatePeerGestaltFromName(name);
+    require(gestalt, exit);
+
+    result = SOSFullPeerInfoCreate(NULL, gestalt, *outSigningKey, error);
+
+exit:
+    CFReleaseNull(gestalt);
+    CFReleaseNull(publicKey);
+
+    return result;
+}
+
+// MARK: ----- MAC Address -----
+
+/*
+ *     Name:                   GetHardwareAdress
+ *
+ *     Parameters:             None.
+ *
+ *     Returns:                Nothing
+ *
+ *     Description:    Retrieve the hardare address for a specified network interface
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/sysctl.h>
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/route.h>
+
+#include <unistd.h>
+#include <netdb.h>
+#include <sys/stat.h>
+
+static int getHardwareAddress(const char *interfaceName, size_t maxLenAllowed, size_t *outActualLength, char *outHardwareAddress)
+{
+       char                            *end;
+       struct if_msghdr        *ifm;
+       struct sockaddr_dl      *sdl;
+       char                            *buf;
+       int                             result;
+       size_t                          buffSize;
+       int                                     mib[6] = {CTL_NET, AF_ROUTE, 0, AF_INET, NET_RT_IFLIST, 0 };
+       
+       buf = 0;
+       *outActualLength = 0;
+       result = -1;
+       //      see how much space is needed
+       require_noerr(result = sysctl(mib, 6, NULL, &buffSize, NULL, 0), xit);
+
+       //      allocate the buffer
+       require(buf = malloc(buffSize), xit);
+               
+       //      get the interface info  
+       require_noerr(result = sysctl(mib, 6, buf, &buffSize, NULL, 0), xit);
+    
+       ifm = (struct if_msghdr *) buf;
+       end = buf + buffSize;
+       do
+       {
+               if (ifm->ifm_type == RTM_IFINFO)                //      should always be true
+               {
+                       sdl = (struct sockaddr_dl *) (ifm + 1);
+                       if ( sdl->sdl_nlen == strlen( interfaceName ) && ( bcmp( sdl->sdl_data, interfaceName, sdl->sdl_nlen ) == 0 ) )
+                       {
+                               if (  sdl->sdl_alen > 0 )
+                               {
+                                       size_t hardwareLen;
+                                       
+                                       result = 0;                                             //      indicate found the interface
+                                       hardwareLen = sdl->sdl_alen;
+                                       if ( hardwareLen > maxLenAllowed )
+                                       {
+                                               hardwareLen = maxLenAllowed;
+                                               result = -2;                            //      indicate truncation of the address
+                                       } 
+                                       memcpy( outHardwareAddress, sdl->sdl_data + sdl->sdl_nlen, hardwareLen );
+                                       *outActualLength = hardwareLen;
+                                       break;
+                                       
+                               }       
+                       }       
+               }
+               ifm = (struct if_msghdr *)  ((char*)ifm + ifm->ifm_msglen);
+       } while ( (char*)ifm < end );
+       
+xit:
+       if (buf)
+               free(buf);
+
+       return result;  
+}
+
+// MARK: ----- cloudTransportTests -----
+
+CFStringRef myMacAddress(void)
+{
+    // 6 bytes, no ":"s
+    CFStringRef result = NULL;
+    const char *interfaceName = "en0";
+    size_t maxLenAllowed = 1024;
+    size_t outActualLength = 0;
+    char outHardwareAddress[1024];
+    
+    require_noerr(getHardwareAddress(interfaceName, maxLenAllowed, &outActualLength, outHardwareAddress), xit);
+    require(outActualLength==6, xit);
+    unsigned char buf[32]={0,};
+    
+    unsigned char *ps = (unsigned char *)buf;
+    unsigned char *pa = (unsigned char *)outHardwareAddress;
+    for (int ix = 0; ix < 6; ix++, pa++)
+        ps += sprintf((char *)ps, "%02x", *pa);
+
+    result = CFStringCreateWithCString(kCFAllocatorDefault, (const char *)buf, kCFStringEncodingUTF8);
+    
+xit:
+    return result;    
+}
diff --git a/sec/SOSCircle/Regressions/SOSRegressionUtilities.h b/sec/SOSCircle/Regressions/SOSRegressionUtilities.h
new file mode 100644 (file)
index 0000000..1087594
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2012 Apple Computer, Inc. All Rights Reserved.
+ * 
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+//
+//  SOSRegressionUtilities.h
+//
+
+#ifndef sec_SOSRegressionUtilities_h
+#define sec_SOSRegressionUtilities_h
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreFoundation/CFArray.h>
+#include <CoreFoundation/CFError.h>
+#include <Security/SecKey.h>
+#include <SecureObjectSync/SOSPeerInfo.h>
+#include <SecureObjectSync/SOSFullPeerInfo.h>
+
+__BEGIN_DECLS
+
+CFStringRef myMacAddress(void);
+const char *cfabsoluteTimeToString(CFAbsoluteTime abstime);
+const char *cfabsoluteTimeToStringLocal(CFAbsoluteTime abstime);
+bool XPCServiceInstalled(void);
+
+void registerForKVSNotifications(const void *observer, CFStringRef name, CFNotificationCallback callBack);
+void unregisterFromKVSNotifications(const void *observer);
+
+void testPutObjectInCloudAndSync(CFStringRef key, CFTypeRef object, CFErrorRef *error, dispatch_group_t dgroup, dispatch_queue_t processQueue);
+void testPutObjectInCloud(CFStringRef key, CFTypeRef object, CFErrorRef *error, dispatch_group_t dgroup, dispatch_queue_t processQueue);
+
+CFTypeRef testGetObjectFromCloud(CFStringRef key, dispatch_queue_t processQueue, dispatch_group_t dgroup);
+CFTypeRef testGetObjectsFromCloud(CFArrayRef keys, dispatch_queue_t processQueue, dispatch_group_t dgroup);
+
+bool testSynchronize(dispatch_queue_t processQueue, dispatch_group_t dgroup);
+bool testRegisterKeys(CFArrayRef keysToRegister, dispatch_queue_t processQueue, dispatch_group_t dgroup);
+bool testClearAll(dispatch_queue_t processQueue, dispatch_group_t dgroup);
+
+//
+// MARK: Peer Info helpers
+//   These generate keys for your and create info objects with that name.
+//
+
+CFDictionaryRef SOSCreatePeerGestaltFromName(CFStringRef name);
+
+SOSPeerInfoRef SOSCreatePeerInfoFromName(CFStringRef name, SecKeyRef* outSigningKey, CFErrorRef *error);
+SOSFullPeerInfoRef SOSCreateFullPeerInfoFromName(CFStringRef name, SecKeyRef* outSigningKey, CFErrorRef *error);
+
+__END_DECLS
+
+#endif /* sec_SOSRegressionUtilities_h */
+
diff --git a/sec/SOSCircle/Regressions/SOSTestDataSource.c b/sec/SOSCircle/Regressions/SOSTestDataSource.c
new file mode 100644 (file)
index 0000000..1045f80
--- /dev/null
@@ -0,0 +1,382 @@
+//
+//  SOSTestDataSource.c
+//  sec
+//
+//  Created by Michael Brouwer on 9/28/12.
+//
+//
+
+#include "SOSTestDataSource.h"
+
+#include <corecrypto/ccder.h>
+#include <SecureObjectSync/SOSEngine.h>
+#include <utilities/array_size.h>
+#include <utilities/der_plist.h>
+#include <utilities/SecCFError.h>
+#include <utilities/SecCFWrappers.h>
+#include <Security/SecItemPriv.h>
+
+static CFStringRef sErrorDomain = CFSTR("com.apple.testdatasource");
+
+enum {
+    kSOSObjectMallocFailed = 1,
+    kAddDuplicateEntry,
+    kSOSObjectNotFouncError = 1,
+};
+
+typedef struct SOSTestDataSource *SOSTestDataSourceRef;
+
+struct SOSTestDataSource {
+    struct SOSDataSource ds;
+    unsigned gm_count;
+    unsigned cm_count;
+    unsigned co_count;
+    CFMutableDictionaryRef database;
+    uint8_t manifest_digest[SOSDigestSize];
+    bool clean;
+};
+
+typedef struct SOSTestDataSourceFactory *SOSTestDataSourceFactoryRef;
+
+struct SOSTestDataSourceFactory {
+    struct SOSDataSourceFactory dsf;
+    CFMutableDictionaryRef data_sources;
+};
+
+
+/* DataSource protocol. */
+static bool get_manifest_digest(SOSDataSourceRef data_source, uint8_t *out_digest, CFErrorRef *error) {
+    struct SOSTestDataSource *ds = (struct SOSTestDataSource *)data_source;
+    if (!ds->clean) {
+        SOSManifestRef mf = data_source->copy_manifest(data_source, error);
+        if (mf) {
+            CFRelease(mf);
+        } else {
+            return false;
+        }
+    }
+    memcpy(out_digest, ds->manifest_digest, SOSDigestSize);
+    ds->gm_count++;
+    return true;
+}
+
+static SOSManifestRef copy_manifest(SOSDataSourceRef data_source, CFErrorRef *error) {
+    struct SOSTestDataSource *ds = (struct SOSTestDataSource *)data_source;
+    ds->cm_count++;
+    __block struct SOSDigestVector dv = SOSDigestVectorInit;
+    CFDictionaryForEach(ds->database, ^(const void *key, const void *value) {
+        SOSDigestVectorAppend(&dv, CFDataGetBytePtr((CFDataRef)key));
+    });
+    SOSDigestVectorSort(&dv);
+    SOSManifestRef manifest = SOSManifestCreateWithBytes((const uint8_t *)dv.digest, dv.count * SOSDigestSize, error);
+    SOSDigestVectorFree(&dv);
+    ccdigest(ccsha1_di(), SOSManifestGetSize(manifest), SOSManifestGetBytePtr(manifest), ds->manifest_digest);
+    ds->clean = true;
+
+    return manifest;
+}
+
+static bool foreach_object(SOSDataSourceRef data_source, SOSManifestRef manifest, CFErrorRef *error, bool (^handle_object)(SOSObjectRef object, CFErrorRef *error)) {
+    struct SOSTestDataSource *ds = (struct SOSTestDataSource *)data_source;
+    ds->co_count++;
+    __block bool result = true;
+    SOSManifestForEach(manifest, ^(CFDataRef key) {
+        CFDictionaryRef dict = (CFDictionaryRef)CFDictionaryGetValue(ds->database, key);
+        if (dict) {
+            result = result && handle_object((SOSObjectRef)dict, error);
+        } else {
+            result = false;
+            if (error) {
+                // TODO: Collect all missing keys in an array and return an single error at the end with all collected keys
+                // Collect all errors as chained errors.
+                CFErrorRef old_error = *error;
+                *error = NULL;
+                SecCFCreateErrorWithFormat(kSOSObjectNotFouncError, sErrorDomain, old_error, error, 0, CFSTR("key %@ not in database"), key);
+            }
+        }
+    });
+    return result;
+}
+
+static void dispose(SOSDataSourceRef data_source) {
+    struct SOSTestDataSource *ds = (struct SOSTestDataSource *)data_source;
+    free(ds);
+}
+
+static SOSObjectRef createWithPropertyList(SOSDataSourceRef ds, CFDictionaryRef plist, CFErrorRef *error) {
+    return (SOSObjectRef)CFDictionaryCreateCopy(kCFAllocatorDefault, plist);
+}
+
+static CFDataRef SOSObjectCopyDER(SOSObjectRef object, CFErrorRef *error) {
+    CFDictionaryRef dict = (CFDictionaryRef)object;
+    size_t size = der_sizeof_plist(dict, error);
+    CFMutableDataRef data = CFDataCreateMutable(0, size);
+    if (data) {
+        CFDataSetLength(data, size);
+        uint8_t *der = (uint8_t *)CFDataGetMutableBytePtr(data);
+        uint8_t *der_end = der + size;
+        der_end = der_encode_plist(dict, error, der, der_end);
+        assert(der_end == der);
+    } else if (error && *error == NULL) {
+        *error = CFErrorCreate(0, sErrorDomain, kSOSObjectMallocFailed, NULL);
+    }
+    return data;
+}
+
+static CFDataRef ccdigest_copy_data(const struct ccdigest_info *di, size_t len,
+                                    const void *data, CFErrorRef *error) {
+    CFMutableDataRef digest = CFDataCreateMutable(0, di->output_size);
+    if (digest) {
+        CFDataSetLength(digest, di->output_size);
+        ccdigest(di, len, data, CFDataGetMutableBytePtr(digest));
+    } else if (error && *error == NULL) {
+        *error = CFErrorCreate(0, sErrorDomain, kSOSObjectMallocFailed, NULL);
+    }
+    return digest;
+}
+
+static CFDataRef copyDigest(SOSObjectRef object, CFErrorRef *error) {
+    CFMutableDictionaryRef ocopy = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, (CFDictionaryRef)object);
+    CFDictionaryRemoveValue(ocopy, kSecClass);
+    CFDataRef der = SOSObjectCopyDER((SOSObjectRef)ocopy, error);
+    CFRelease(ocopy);
+    CFDataRef digest = NULL;
+    if (der) {
+        digest = ccdigest_copy_data(ccsha1_di(), CFDataGetLength(der), CFDataGetBytePtr(der), error);
+        CFRelease(der);
+    }
+    return digest;
+}
+
+static CFDataRef copyPrimaryKey(SOSObjectRef object, CFErrorRef *error) {
+    CFMutableDictionaryRef ocopy = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
+    CFTypeRef pkNames[] = {
+        CFSTR("acct"),
+        CFSTR("agrp"),
+        CFSTR("svce"),
+        CFSTR("sync"),
+        CFSTR("sdmn"),
+        CFSTR("srvr"),
+        CFSTR("ptcl"),
+        CFSTR("atyp"),
+        CFSTR("port"),
+        CFSTR("path"),
+        CFSTR("ctyp"),
+        CFSTR("issr"),
+        CFSTR("slnr"),
+        CFSTR("kcls"),
+        CFSTR("klbl"),
+        CFSTR("atag"),
+        CFSTR("crtr"),
+        CFSTR("type"),
+        CFSTR("bsiz"),
+        CFSTR("esiz"),
+        CFSTR("sdat"),
+        CFSTR("edat"),
+    };
+    CFSetRef pkAttrs = CFSetCreate(kCFAllocatorDefault, pkNames, array_size(pkNames), &kCFTypeSetCallBacks);
+    CFDictionaryForEach((CFDictionaryRef)object, ^(const void *key, const void *value) {
+        if (CFSetContainsValue(pkAttrs, key))
+            CFDictionaryAddValue(ocopy, key, value);
+    });
+    CFRelease(pkAttrs);
+    CFDataRef der = SOSObjectCopyDER((SOSObjectRef)ocopy, error);
+    CFRelease(ocopy);
+    CFDataRef digest = NULL;
+    if (der) {
+        digest = ccdigest_copy_data(ccsha1_di(), CFDataGetLength(der), CFDataGetBytePtr(der), error);
+        CFRelease(der);
+    }
+    return digest;
+}
+
+static CFDictionaryRef copyPropertyList(SOSObjectRef object, CFErrorRef *error) {
+    return (CFDictionaryRef) CFRetain(object);
+}
+
+// Return the newest object
+static SOSObjectRef copyMergedObject(SOSObjectRef object1, SOSObjectRef object2, CFErrorRef *error) {
+    CFDictionaryRef dict1 = (CFDictionaryRef)object1;
+    CFDictionaryRef dict2 = (CFDictionaryRef)object2;
+    SOSObjectRef result = NULL;
+    CFDateRef m1, m2;
+    m1 = CFDictionaryGetValue(dict1, kSecAttrModificationDate);
+    m2 = CFDictionaryGetValue(dict2, kSecAttrModificationDate);
+    switch (CFDateCompare(m1, m2, NULL)) {
+        case kCFCompareGreaterThan:
+            result = (SOSObjectRef)dict1;
+            break;
+        case kCFCompareLessThan:
+            result = (SOSObjectRef)dict2;
+            break;
+        case kCFCompareEqualTo:
+        {
+            // Return the item with the smallest digest.
+            CFDataRef digest1 = copyDigest(object1, error);
+            CFDataRef digest2 = copyDigest(object2, error);
+            if (digest1 && digest2) switch (CFDataCompare(digest1, digest2)) {
+                case kCFCompareGreaterThan:
+                case kCFCompareEqualTo:
+                    result = (SOSObjectRef)dict2;
+                    break;
+                case kCFCompareLessThan:
+                    result = (SOSObjectRef)dict1;
+                    break;
+            }
+            CFReleaseSafe(digest2);
+            CFReleaseSafe(digest1);
+            break;
+        }
+    }
+    CFRetainSafe(result);
+    return result;
+}
+
+SOSDataSourceRef SOSTestDataSourceCreate(void) {
+    SOSTestDataSourceRef ds = calloc(1, sizeof(struct SOSTestDataSource));
+
+    ds->ds.get_manifest_digest = get_manifest_digest;
+    ds->ds.copy_manifest = copy_manifest;
+    ds->ds.foreach_object = foreach_object;
+    ds->ds.release = dispose;
+    ds->ds.add = SOSTestDataSourceAddObject;
+
+    ds->ds.createWithPropertyList = createWithPropertyList;
+    ds->ds.copyDigest = copyDigest;
+    ds->ds.copyPrimaryKey = copyPrimaryKey;
+    ds->ds.copyPropertyList = copyPropertyList;
+    ds->ds.copyMergedObject = copyMergedObject;
+
+    ds->database = CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    ds->clean = false;
+
+    return (SOSDataSourceRef)ds;
+}
+
+static CFArrayRef SOSTestDataSourceFactoryCopyNames(SOSDataSourceFactoryRef factory)
+{
+    SOSTestDataSourceFactoryRef dsf = (SOSTestDataSourceFactoryRef) factory;
+    CFMutableArrayRef result = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
+
+    CFDictionaryForEach(dsf->data_sources, ^(const void*key, const void*value) { CFArrayAppendValue(result, key); });
+    
+    return result;
+}
+
+static SOSDataSourceRef SOSTestDataSourceFactoryCreateDataSource(SOSDataSourceFactoryRef factory, CFStringRef dataSourceName, bool readOnly __unused, CFErrorRef *error)
+{
+    SOSTestDataSourceFactoryRef dsf = (SOSTestDataSourceFactoryRef) factory;
+
+    return (SOSDataSourceRef) CFDictionaryGetValue(dsf->data_sources, dataSourceName);
+}
+
+static void SOSTestDataSourceFactoryDispose(SOSDataSourceFactoryRef factory)
+{
+    SOSTestDataSourceFactoryRef dsf = (SOSTestDataSourceFactoryRef) factory;
+    
+    CFReleaseNull(dsf->data_sources);
+    free(dsf);
+}
+
+SOSDataSourceFactoryRef SOSTestDataSourceFactoryCreate() {
+    SOSTestDataSourceFactoryRef dsf = calloc(1, sizeof(struct SOSTestDataSourceFactory));
+    
+    dsf->dsf.copy_names = SOSTestDataSourceFactoryCopyNames;
+    dsf->dsf.create_datasource = SOSTestDataSourceFactoryCreateDataSource;
+    dsf->dsf.release = SOSTestDataSourceFactoryDispose;
+    dsf->data_sources = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, NULL);
+    
+    return &(dsf->dsf);
+}
+
+static void do_nothing(SOSDataSourceRef ds)
+{
+}
+
+void SOSTestDataSourceFactoryAddDataSource(SOSDataSourceFactoryRef factory, CFStringRef name, SOSDataSourceRef ds)
+{
+    SOSTestDataSourceFactoryRef dsf = (SOSTestDataSourceFactoryRef) factory;
+
+    // TODO This hack sucks. It leaks now.
+    ds->release = do_nothing;
+
+    CFDictionarySetValue(dsf->data_sources, name, ds);
+
+}
+
+SOSMergeResult SOSTestDataSourceAddObject(SOSDataSourceRef data_source, SOSObjectRef object, CFErrorRef *error) {
+    struct SOSTestDataSource *ds = (struct SOSTestDataSource *)data_source;
+    bool result = false;
+    CFDataRef key = copyDigest(object, error);
+    if (key) {
+        SOSObjectRef myObject = (SOSObjectRef)CFDictionaryGetValue(ds->database, key);
+        SOSObjectRef merged = NULL;
+        if (myObject) {
+            merged = copyMergedObject(object, myObject, error);
+        } else {
+            merged = object;
+            CFRetain(merged);
+        }
+        if (merged) {
+            result = true;
+            if (!CFEqualSafe(merged, myObject)) {
+                CFDictionarySetValue(ds->database, key, merged);
+                ds->clean = false;
+            }
+            CFRelease(merged);
+        }
+        CFRelease(key);
+    }
+    return result;
+}
+
+bool SOSTestDataSourceDeleteObject(SOSDataSourceRef data_source, CFDataRef key, CFErrorRef *error) {
+    //struct SOSTestDataSource *ds = (struct SOSTestDataSource *)data_source;
+    return false;
+}
+
+CFMutableDictionaryRef SOSTestDataSourceGetDatabase(SOSDataSourceRef data_source) {
+    struct SOSTestDataSource *ds = (struct SOSTestDataSource *)data_source;
+    return ds->database;
+}
+
+// This works for any datasource, not just the test one, but it's only used in testcases, so it's here for now.
+SOSObjectRef SOSDataSourceCreateGenericItemWithData(SOSDataSourceRef ds, CFStringRef account, CFStringRef service, bool is_tomb, CFDataRef data) {
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+    abort();
+#else
+    int32_t value = 0;
+    CFNumberRef zero = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
+    value = 1;
+    CFNumberRef one = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
+    CFAbsoluteTime timestamp = 3700000;
+    CFDateRef now = CFDateCreate(kCFAllocatorDefault, timestamp);
+    CFDictionaryRef dict = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
+                                                        kSecClass,                  kSecClassGenericPassword,
+                                                        kSecAttrSynchronizable,     one,
+                                                        kSecAttrTombstone,          is_tomb ? one : zero,
+                                                        kSecAttrAccount,            account,
+                                                        kSecAttrService,            service,
+                                                        kSecAttrCreationDate,       now,
+                                                        kSecAttrModificationDate,   now,
+                                                        kSecAttrAccessGroup,        CFSTR("test"),
+                                                        kSecAttrAccessible,         kSecAttrAccessibleWhenUnlocked,
+                                                        !is_tomb && data ?  kSecValueData : NULL,data,
+                                                        NULL);
+    CFRelease(one);
+    CFRelease(zero);
+    CFReleaseSafe(now);
+    CFErrorRef localError = NULL;
+    SOSObjectRef object = ds->createWithPropertyList(ds, dict, &localError);
+    if (!object) {
+        secerror("createWithPropertyList: %@ failed: %@", dict, localError);
+        CFRelease(localError);
+    }
+    CFRelease(dict);
+    return object;
+#endif
+}
+
+SOSObjectRef SOSDataSourceCreateGenericItem(SOSDataSourceRef ds, CFStringRef account, CFStringRef service) {
+    return SOSDataSourceCreateGenericItemWithData(ds, account, service, false, NULL);
+}
diff --git a/sec/SOSCircle/Regressions/SOSTestDataSource.h b/sec/SOSCircle/Regressions/SOSTestDataSource.h
new file mode 100644 (file)
index 0000000..7c0d046
--- /dev/null
@@ -0,0 +1,34 @@
+//
+//  SOSTestDataSource.h
+//  sec
+//
+//  Created by Michael Brouwer on 9/28/12.
+//
+//
+
+#ifndef _SEC_SOSTestDataSource_H_
+#define _SEC_SOSTestDataSource_H_
+
+#include <SecureObjectSync/SOSAccount.h>
+
+//
+// MARK: Data Source Functions
+//
+SOSDataSourceRef SOSTestDataSourceCreate(void);
+
+CFMutableDictionaryRef SOSTestDataSourceGetDatabase(SOSDataSourceRef data_source);
+
+SOSMergeResult SOSTestDataSourceAddObject(SOSDataSourceRef data_source, SOSObjectRef object, CFErrorRef *error);
+bool SOSTestDataSourceDeleteObject(SOSDataSourceRef data_source, CFDataRef key, CFErrorRef *error);
+
+//
+// MARK: Data Source Factory Functions
+//
+
+SOSDataSourceFactoryRef SOSTestDataSourceFactoryCreate(void);
+void SOSTestDataSourceFactoryAddDataSource(SOSDataSourceFactoryRef factory, CFStringRef name, SOSDataSourceRef ds);
+
+SOSObjectRef SOSDataSourceCreateGenericItemWithData(SOSDataSourceRef ds, CFStringRef account, CFStringRef service, bool is_tomb, CFDataRef data);
+SOSObjectRef SOSDataSourceCreateGenericItem(SOSDataSourceRef ds, CFStringRef account, CFStringRef service);
+
+#endif /* _SEC_SOSTestDataSource_H_ */
diff --git a/sec/SOSCircle/Regressions/SOSTestTransport.c b/sec/SOSCircle/Regressions/SOSTestTransport.c
new file mode 100644 (file)
index 0000000..a00acfa
--- /dev/null
@@ -0,0 +1,48 @@
+//
+//  SOSTestTransport.c
+//  sec
+//
+//  Created by Michael Brouwer on 10/16/12.
+//
+
+#include "SOSTestTransport.h"
+
+#include <utilities/SecCFWrappers.h>
+#include <test/testmore.h>
+
+struct SOSTestTransport {
+    struct SOSTransport t;
+    CFDataRef lastMessage;
+};
+
+
+/* Transport protocol. */
+static bool SOSTestTransportQueue(SOSTransportRef transport, CFDataRef message) {
+    struct SOSTestTransport *t = (struct SOSTestTransport *)transport;
+    if (t->lastMessage) {
+        fail("We already had an unproccessed message");
+        CFReleaseNull(t->lastMessage);
+    }
+    CFRetain(message);
+    t->lastMessage = message;
+    return true;
+}
+
+CFDataRef SOSTestTransportDequeue(SOSTransportRef transport) {
+    struct SOSTestTransport *t = (struct SOSTestTransport *)transport;
+    CFDataRef message = t->lastMessage;
+    t->lastMessage = NULL;
+    return message;
+}
+
+void SOSTestTransportDispose(SOSTransportRef transport) {
+    struct SOSTestTransport *t = (struct SOSTestTransport *)transport;
+    free(t);
+}
+
+SOSTransportRef SOSTestTransportCreate(void) {
+    struct SOSTestTransport *transport = calloc(1, sizeof(struct SOSTestTransport));
+    transport->t.send = SOSTestTransportQueue;
+
+    return (SOSTransportRef)transport;
+}
diff --git a/sec/SOSCircle/Regressions/SOSTestTransport.h b/sec/SOSCircle/Regressions/SOSTestTransport.h
new file mode 100644 (file)
index 0000000..8f828a6
--- /dev/null
@@ -0,0 +1,24 @@
+//
+//  SOSTestTransport.h
+//  sec
+//
+//  Created by Michael Brouwer on 10/16/12.
+//
+//
+
+#ifndef _SEC_SOSTESTTRANSPORT_H_
+#define _SEC_SOSTESTTRANSPORT_H_
+
+#include <SecureObjectSync/SOSTransport.h>
+
+__BEGIN_DECLS
+
+SOSTransportRef SOSTestTransportCreate(void);
+
+CFDataRef SOSTestTransportDequeue(SOSTransportRef transport);
+
+void SOSTestTransportDispose(SOSTransportRef transport);
+
+__END_DECLS
+
+#endif /* _SEC_SOSTESTTRANSPORT_H_ */
diff --git a/sec/SOSCircle/Regressions/sc-100-devicecircle.c b/sec/SOSCircle/Regressions/sc-100-devicecircle.c
new file mode 100644 (file)
index 0000000..9d92b12
--- /dev/null
@@ -0,0 +1,565 @@
+//
+//  sc-100-devicecircle.c
+//  sec
+//
+//  Created by John Hurley 10/16/12.
+//  Copyright 2012 Apple Inc. All rights reserved.
+//
+
+/*
+    This test is a combination of sc-75, sc_93 and sc_94 that can
+    be run on two devices.
+    
+    The test will look for a circle in kvs
+    - if none exists, it will create one
+    - if one exists, it will try to join
+    
+    Whenever you confirm a new peer, must start sync
+    
+    Test sc-98 can be run before this to clear out kvs
+*/
+
+// Run on 2 devices:
+//      /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_100_devicecircle -v -- -i alice
+//      /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_100_devicecircle -v -- -i bob
+
+#include <SecureObjectSync/SOSEngine.h>
+#include <SecureObjectSync/SOSPeer.h>
+
+#include "SOSCircle_regressions.h"
+
+#include <corecrypto/ccsha2.h>
+
+#include <utilities/SecCFWrappers.h>
+#include <utilities/debugging.h>
+
+#include <stdint.h>
+
+#include <AssertMacros.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <CoreFoundation/CFDate.h>
+#include <getopt.h>
+
+
+#include <Security/SecKey.h>
+
+#include <SecureObjectSync/SOSFullPeerInfo.h>
+#include <SecureObjectSync/SOSPeerInfo.h>
+#include <SecureObjectSync/SOSCircle.h>
+#include <SecureObjectSync/SOSCloudCircle.h>
+#include <SecureObjectSync/SOSInternal.h>
+#include <SecureObjectSync/SOSUserKeygen.h>
+
+#include "SOSCircle_regressions.h"
+#include "SOSRegressionUtilities.h"
+#include "SOSTestDataSource.h"
+#include "SOSTestTransport.h"
+#include "SOSCloudKeychainClient.h"
+
+#include <securityd/SOSCloudCircleServer.h>
+
+#ifndef SEC_CONST_DECL
+#define SEC_CONST_DECL(k,v) CFTypeRef k = (CFTypeRef)(CFSTR(v));
+#endif
+
+//static     dispatch_queue_t wait_queue = NULL;
+
+#define VALUECFNULLCHECK(msg) if (msg == NULL || CFGetTypeID(msg) == CFNullGetTypeID()) { pass("CFNull message"); return 0; }
+
+// TODO _SecServerKeychainSyncUpdate
+
+// MARK: ----- Constants -----
+
+static CFStringRef circleKey = CFSTR("Circle");
+//static CFStringRef messageKey = CFSTR("Message");
+static CFStringRef messageFromAliceToBobKey = CFSTR("AliceToBob");
+static CFStringRef messageFromBobToAliceKey = CFSTR("BobToAlice");
+
+#if USE_BOB_GO
+static CFStringRef messageGoBobGoKey = CFSTR("GoBobGo");
+#endif
+
+struct SOSKVSTransport {
+    struct SOSTransport t;
+    CFStringRef messageKey;
+};
+
+#include <notify.h>
+#include <dispatch/dispatch.h>
+
+static bool kvsTransportSend(CFStringRef key, CFDataRef message) {
+    __block bool success = true;
+    __block dispatch_semaphore_t waitSemaphore = dispatch_semaphore_create(0);
+    
+    CFDictionaryRef objects = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, key, message, NULL);
+
+    CFStringRef desc = SOSMessageCopyDescription(message);
+    pass("kvsTransportSend: %@ %@", key, desc);
+    CFReleaseSafe(desc);
+    
+    SOSCloudKeychainPutObjectsInCloud(objects, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
+        ^ (CFDictionaryRef returnedValues, CFErrorRef error)
+        {
+            ok(error == NULL, "Error from SOSCloudKeychainPutObjectsInCloud %@:", error);
+            if (error)
+                success = false;
+            dispatch_semaphore_signal(waitSemaphore);
+        });
+
+    dispatch_release(waitSemaphore);
+
+    return success;
+}
+
+static void putCircleInCloud(SOSCircleRef circle, dispatch_queue_t work_queue, dispatch_group_t work_group)
+{
+    CFErrorRef error = NULL;
+    CFDataRef newCloudCircleEncoded = SOSCircleCopyEncodedData(circle, kCFAllocatorDefault, &error);
+    ok(newCloudCircleEncoded, "Encoded as: %@ [%@]", newCloudCircleEncoded, error);
+
+    // Send the circle with our application request back to cloud
+    testPutObjectInCloud(circleKey, newCloudCircleEncoded, &error, work_group, work_queue);
+    CFReleaseSafe(newCloudCircleEncoded);
+}
+
+static void mutate_inflated_circle(SOSCircleRef newCircle,
+                                   dispatch_queue_t work_queue, dispatch_group_t work_group,
+                          void (^action)(SOSCircleRef circle))
+{
+//JCH    action(newCircle);
+        
+    putCircleInCloud(newCircle, work_queue, work_group);
+    pass("Put circle in cloud: (%@)", newCircle);
+}
+
+static void mutate_account_circle(SOSAccountRef account,
+                                  CFDataRef encodedCircle,
+                                  dispatch_queue_t work_queue, dispatch_group_t work_group,
+                                  void (^action)(SOSCircleRef circle))
+{
+    bool mutated = false;
+
+    CFErrorRef error = NULL;
+    SKIP:
+    {
+        skip("Must be CFData!", 3, encodedCircle && (CFDataGetTypeID() == CFGetTypeID(encodedCircle)));
+        SOSCircleRef newCircle = SOSCircleCreateFromData(kCFAllocatorDefault, encodedCircle, &error);
+        ok(newCircle, "Decoded data version of circle: %@", newCircle);
+        
+        SOSCircleRef accountCircle = SOSAccountFindCircle(account, SOSCircleGetName(newCircle), NULL);
+        ok(accountCircle, "Found our circle in account");
+        
+        if (!CFEqual(newCircle, accountCircle)) {
+            pass("New circle and accountCircle not equal");
+            
+            // JCH JCH
+                action(newCircle);
+
+            bool updated = SOSAccountUpdateCircle(account, newCircle, &error);
+            if (updated) {
+                pass("Updated account with new circle");
+                mutated = true;
+                mutate_inflated_circle(newCircle, work_queue, work_group, action);
+            }
+        }
+    }
+    pass("mutate_account_circle exit");
+}
+
+static void SOSCloudKeychainRegisterKeysAndGetWithNotification(CFArrayRef keysToRegister, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+    SOSCloudKeychainRegisterKeysAndGet(keysToRegister, processQueue, replyBlock,
+                                       ^(CFDictionaryRef dict) { replyBlock(dict, NULL);});
+}
+
+#define kAlicePeerID CFSTR("alice-peer-id")
+#define kBobPeerID CFSTR("bob-peer-id")
+
+static void runTests(bool Alice, dispatch_queue_t work_queue, dispatch_group_t work_group)
+{
+    SecKeyRef user_key = NULL;
+    SecKeyRef public_key = NULL;
+    CFErrorRef error = NULL;
+    CFStringRef cflabel = CFSTR("TEST_USERKEY");
+    CFDataRef cfpassword = CFDataCreate(NULL, (uint8_t *) "FooFooFoo", 10);
+
+    GenerateECPair(256, &public_key, &user_key);
+    SOSCCRegisterUserCredentials(cflabel, cfpassword, &error);
+    CFReleaseNull(public_key);
+    CFReleaseNull(cfpassword);
+
+    SOSDataSourceFactoryRef our_data_source_factory = SOSTestDataSourceFactoryCreate();
+    SOSDataSourceRef our_data_source = SOSTestDataSourceCreate();
+    SOSTestDataSourceFactoryAddDataSource(our_data_source_factory, circleKey, our_data_source);
+
+    CFDictionaryRef gestalt = SOSCreatePeerGestaltFromName(Alice? kAlicePeerID: kBobPeerID);
+
+    SOSAccountRef our_account = SOSAccountCreate(kCFAllocatorDefault, gestalt, our_data_source_factory, NULL, NULL);
+    SOSAccountEnsureCircle(our_account, circleKey, NULL);
+
+    SOSFullPeerInfoRef our_full_peer_info = SOSAccountGetMyFullPeerInCircleNamed(our_account, circleKey, &error);
+    __block SOSPeerInfoRef our_peer_info = SOSFullPeerInfoGetPeerInfo(our_full_peer_info);
+    CFRetain(our_peer_info);
+    pass("We are %s (%@)", Alice?"Alice":"Bob", our_peer_info);
+
+    ok(our_peer_info, "Peer Info: %@ [error: %@]", our_peer_info, error);
+
+    /// Setup ck notifications.
+    
+    CFArrayRef keysToRegister = NULL;
+    
+    CFStringRef message_key;
+    
+    if (Alice)
+    {
+        keysToRegister = CFArrayCreateForCFTypes(kCFAllocatorDefault, circleKey, messageFromBobToAliceKey, NULL);
+        message_key = messageFromAliceToBobKey;
+    }
+    else
+    {
+#if USE_BOB_GO
+        keysToRegister = CFArrayCreateForCFTypes(kCFAllocatorDefault, circleKey, messageFromAliceToBobKey, messageGoBobGoKey, NULL);
+#else
+        keysToRegister = CFArrayCreateForCFTypes(kCFAllocatorDefault, circleKey, messageFromAliceToBobKey, NULL);
+#endif
+        message_key = messageFromBobToAliceKey;
+    }
+
+    SOSPeerSendBlock transport = ^bool (CFDataRef message, CFErrorRef *error) {
+        kvsTransportSend(message_key, message);
+        return true;
+    };
+
+
+    __block CFIndex current = 0;
+    typedef CFIndex (^TestStateBlock) (CFDictionaryRef returnedValues, CFErrorRef error);
+
+    //------------------------------------------------------------------------
+    //              ALICE
+    //------------------------------------------------------------------------
+    CFArrayRef aliceWorkToDo =
+    CFArrayCreateForCFTypes(kCFAllocatorDefault,
+        ^ CFIndex (CFDictionaryRef returnedValues, CFErrorRef error)
+        {
+            /*
+                We get here as the return from registerkeys.
+                Here we create a fresh circle, add and accept ourselves
+                Then we post to the cloud and wait for a Circle changed notification
+            */
+            
+            (void) returnedValues; (void) error;
+            
+            testClearAll(work_queue, work_group);
+
+            CFErrorRef localError = NULL;
+            
+#if USE_BOB_GO
+            testPutObjectInCloud(messageGoBobGoKey, CFSTR("Go Bob, Go!"), &localError, work_group, work_queue);
+#endif
+
+            SOSCircleRef circle = SOSAccountFindCircle(our_account, circleKey, NULL);
+            CFRetain(circle);
+            
+            ok(SOSCircleRequestAdmission(circle, SOSAccountGetPrivateCredential(our_account, &error), our_full_peer_info, &localError), "Requested admission (%@)", our_peer_info);
+            ok(SOSCircleAcceptRequests(circle, SOSAccountGetPrivateCredential(our_account, &error), our_full_peer_info, &localError), "Accepted self");
+            
+            our_peer_info = SOSFullPeerInfoGetPeerInfo(our_full_peer_info);
+
+            putCircleInCloud(circle, work_queue, work_group);
+            pass("Put circle in cloud: (%@)", circle);
+            
+            CFRelease(circle);
+            
+            return +1;
+        },
+        ^ CFIndex (CFDictionaryRef returnedValues, CFErrorRef error)
+        {
+            __block CFIndex incrementAmount = 0; // Don't increment unless we find stuff
+
+            /*
+                When we get here, it should only be because Bob has retrieved
+                our circle and requested admission to our circle.
+                If we don't find a circleKey entry, our test setup is wrong.
+            */
+            SKIP:
+            {
+                __block CFErrorRef localError = NULL;
+                CFDataRef value = CFDictionaryGetValue(returnedValues, circleKey);
+                VALUECFNULLCHECK(value);
+                skip("cloudCircle NULL!", 5, value);
+                ok(value, "Found circle");
+                
+                mutate_account_circle(our_account, value, work_queue, work_group,
+                    ^ (SOSCircleRef circle)
+                    {
+                        ok(SOSCircleHasPeer(circle, our_peer_info, &localError), "We're a peer [error: %@]", localError);
+                        CFReleaseNull(localError);
+                        
+                        is(SOSCircleCountPeers(circle), 1, "One peer, woot");
+                        is(SOSCircleCountApplicants(circle), 1, "One applicant, hope it's BOB");
+                        
+                        CFErrorRef pkerr;
+                        ok(SOSCircleAcceptRequests(circle, SOSAccountGetPrivateCredential(our_account, &pkerr), our_full_peer_info, &localError), "Accepted peers [error: %@]", localError);
+                        CFReleaseNull(localError);
+
+                        ok(SOSCircleSyncWithPeer(our_full_peer_info, circle, our_data_source_factory, transport, kBobPeerID, &localError), "Started sync: [error: %@]", localError);
+                        CFReleaseNull(localError);
+                        
+                        incrementAmount = 1;
+                    });
+
+                CFReleaseSafe(localError);
+            }
+            
+            return incrementAmount;
+        },
+        ^ (CFDictionaryRef returnedValues, CFErrorRef error)
+        {
+            CFErrorRef localError = NULL;
+            SOSCircleRef circle = SOSAccountFindCircle(our_account, circleKey, NULL);
+            CFDataRef message = CFDictionaryGetValue(returnedValues, messageFromBobToAliceKey);
+            VALUECFNULLCHECK(message);
+
+            ok(message, "Saw response to manifest message from Bob");
+            ok(SOSCircleHandlePeerMessage(circle, our_full_peer_info, our_data_source_factory, transport, kBobPeerID, message, &localError), "handle message from bob: [error: %@]", localError);
+            
+#if TEST_EMPTY_ADD
+            // Sync again after adding an empty object
+            CFDictionaryRef object = CFDictionaryCreate(0, NULL, NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+            ok(SOSTestDataSourceAddObject(our_data_source, object, &error), "add empty object to datasource [error: %@]", error);
+
+            ok(ourEngine = SOSCircleCopyEngine(circle, our_data_source_factory, &localError), "get ourEngine [error: %@]", localError);
+
+            // Start syncing
+            SOSPeerRef bobPeer = SOSCircleCopyPeer(circle, transport, kBobPeerID, &localError);
+            ok(bobPeer, "Got bob: [error: %@]", error);
+            ok(SOSEngineSyncWithPeer(ourEngine, bobPeer, false, &localError), "tell Alice sync with peer Bob");
+            SOSPeerDispose(bobPeer);
+
+            CFReleaseNull(localError);
+#endif
+            return 1;
+        },
+#if TEST_EMPTY_ADD
+        ^ (CFDictionaryRef returnedValues, CFErrorRef error)
+        {
+            CFErrorRef localError = NULL;
+            SOSCircleRef circle = SOSAccountFindCircle(our_account, circleKey);
+            CFDataRef message = CFDictionaryGetValue(returnedValues, messageFromBobToAliceKey);
+            VALUECFNULLCHECK(message);
+            ok(message, "Saw response to manifest message from Bob - 2");
+            ok(SOSCircleHandlePeerMessage(circle, our_data_source_factory, transport, kBobPeerID, message, &localError), "handle message from bob: [error: %@]", localError);
+            return 1;
+        },
+#endif
+        NULL);
+    
+    //------------------------------------------------------------------------
+    //              BOB
+    //------------------------------------------------------------------------
+
+    CFArrayRef bobWorkToDo =
+    CFArrayCreateForCFTypes(kCFAllocatorDefault,
+
+        ^ CFIndex (CFDictionaryRef returnedValues, CFErrorRef error)
+        {
+            __block CFIndex incrementAmount = 0; // Don't increment unless we find stuff
+            __block CFErrorRef localError = NULL;
+            
+#if USE_BOB_GO
+            CFTypeRef goMessage = CFDictionaryGetValue(returnedValues, messageGoBobGoKey);
+            if (!goMessage) // We can discard any changes we see here; they are stale
+                return 0;
+            
+            SOSCloudKeychainRemoveObjectForKey(messageGoBobGoKey, work_queue,
+                ^ (CFDictionaryRef returnedValues, CFErrorRef error)
+                {
+                    pass("ACK from messageGoBobGoKey");
+                });
+#endif
+
+            CFTypeRef value = CFDictionaryGetValue(returnedValues, circleKey);
+            VALUECFNULLCHECK(value);
+
+            ok(value, "Found circle %@", value);
+
+            mutate_account_circle(our_account, value, work_queue, work_group,
+                ^ (SOSCircleRef circle)
+                {
+                    int peerCount = SOSCircleCountPeers(circle);
+                    ok(peerCount == 1, "One peer, hope it's Alice");
+                    if (peerCount != 1)
+                        printf("NOT One peer, hope it's Alice: saw %d peers\n", peerCount);
+                    ok(SOSCircleCountApplicants(circle) == 0, "No applicants");
+                    CFErrorRef pkerr;
+
+                    ok(SOSCircleRequestAdmission(circle, SOSAccountGetPrivateCredential(our_account, &pkerr), our_full_peer_info, &localError), "Requested admission");
+                    our_peer_info = SOSFullPeerInfoGetPeerInfo(our_full_peer_info);
+
+                    incrementAmount = 1;
+                });
+
+            CFReleaseSafe(localError);
+            
+            return incrementAmount;
+        },
+        ^ CFIndex (CFDictionaryRef returnedValues, CFErrorRef error)
+        {
+            __block CFIndex incrementAmount = 0; // Don't increment unless we find stuff
+            __block CFErrorRef localError = NULL;
+
+            CFDataRef value = CFDictionaryGetValue(returnedValues, circleKey);
+            VALUECFNULLCHECK(value);
+            ok(value, "Found circle");
+
+            mutate_account_circle(our_account, value, work_queue, work_group,
+                ^ (SOSCircleRef circle)
+                {
+                    ok(SOSCircleHasPeer(circle, our_peer_info, &localError), "We're a peer");
+                    ok(SOSCircleCountPeers(circle) == 2, "Both peers!");
+                    ok(SOSCircleCountApplicants(circle) == 0, "No applicants!");
+
+                    CFDataRef message;
+                    ok(message = CFDictionaryGetValue(returnedValues, messageFromAliceToBobKey), "got message from alice");
+               //     VALUECFNULLCHECK(message);
+               if (message == NULL || CFGetTypeID(message) == CFNullGetTypeID()) { pass("CFNull message"); return; }
+                    ok(SOSCircleHandlePeerMessage(circle, our_full_peer_info, our_data_source_factory, transport, kAlicePeerID, message, &localError), "handle message from alice: %@", localError);
+                    
+                    incrementAmount = 1;
+                });
+
+            CFReleaseSafe(localError);
+            return incrementAmount;
+
+        },
+#if TEST_EMPTY_ADD
+/**/
+        // this next block would normally be looking at the reply to the initial sync message.
+        // Since that one was the same we sent out, we won't get a notification for that.
+        // This block looks at the sync message of the empty object datasource
+        ^ (CFDictionaryRef returnedValues, CFErrorRef error)
+        {
+            CFErrorRef localError = NULL;
+            SOSCircleRef circle = SOSAccountFindCircle(our_account, circleKey);
+            CFDataRef message = CFDictionaryGetValue(returnedValues, messageFromBobToAliceKey);
+            VALUECFNULLCHECK(message);
+            ok(message, "Saw response to manifest message from Alice 2");
+            ok(SOSCircleHandlePeerMessage(circle, our_data_source_factory, transport, kAlicePeerID, message, &localError), "handle message from Alice 2: %@", localError);
+            return 1;
+        },
+#endif            
+
+         NULL);
+    
+    //------------------------------------------------------------------------
+    //              START
+    //------------------------------------------------------------------------
+    
+    CFArrayRef ourWork = Alice ? aliceWorkToDo : bobWorkToDo;
+
+    SOSCloudKeychainRegisterKeysAndGetWithNotification(keysToRegister, work_queue,
+        ^ (CFDictionaryRef returnedValues, CFErrorRef error)
+        {
+            pass("Got key changes: %@ [error: %@]", returnedValues, error);
+
+            CFReleaseSafe(error);
+
+            TestStateBlock thingToDo = CFArrayGetValueAtIndex(ourWork, current);
+            
+            if (thingToDo)
+            {
+                pass("%s stage %d rv: %@ [error: %@]", Alice?"Alice":"Bob", (int)current, returnedValues, error);
+                current += thingToDo(returnedValues, error);
+            }
+
+            if (current < 0 || current >= CFArrayGetCount(ourWork))
+                dispatch_group_leave(work_group);
+        });
+
+    dispatch_group_wait(work_group, DISPATCH_TIME_FOREVER);
+
+    // We probably never get here since the program exits..
+
+    CFReleaseNull(aliceWorkToDo);
+    CFReleaseNull(bobWorkToDo);
+    CFReleaseNull(gestalt);
+    CFReleaseNull(our_account);
+    CFReleaseNull(our_peer_info);
+    CFReleaseNull(user_key);
+    CFReleaseNull(public_key); // Should be NULL but just in case..
+
+#if 0
+
+    if (Alice)
+    {
+        CFDictionaryRef object = CFDictionaryCreate(0, NULL, NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+        ok(SOSTestDataSourceAddObject(our_data_source, object, &error), "add empty object to datasource (error: %@)", error);
+        CFReleaseNull(error);
+        CFReleaseNull(object);
+
+        sendManifestDigest(transportX, pqrEngine, our_circle, our_peer_info);
+        ok(waitForSemaphore(), "Got ACK for manifest with object");
+        ok(handleCloudMessage(our_circle, our_data_source, t), "Got ACK for manifest with object");
+    }
+#endif
+}
+
+// MARK: ----- start of all tests -----
+static void tests(bool Alice)
+{
+    dispatch_queue_t work_queue = dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
+    dispatch_group_t work_group = dispatch_group_create();
+
+    // Queue the work we want to do.
+    runTests(Alice, work_queue, work_group);
+
+}
+
+// define the options table for the command line
+static const struct option options[] =
+{
+       { "verbose",            optional_argument,      NULL, 'v' },
+       { "identity",           optional_argument,      NULL, 'i' },
+       { "clear",          optional_argument,  NULL, 'C' },
+       { }
+};
+
+static int kAliceTestCount = 22;
+static int kBobTestCount = 20;
+
+int sc_100_devicecircle(int argc, char *const *argv)
+{
+    char *identity = NULL;
+//    extern int optind;
+    extern char *optarg;
+    int arg, argSlot;
+    bool Alice = false;
+
+    while (argSlot = -1, (arg = getopt_long(argc, (char * const *)argv, "i:vC", options, &argSlot)) != -1)
+        switch (arg)
+        {
+        case 'i':
+            identity = (char *)(optarg);
+            break;
+        case 'C':   // should set up to call testClearAll
+            break;
+        default:
+            secerror("arg: %s", optarg);
+            break;
+        }
+    
+    if (identity)
+    {
+        secerror("We are %s",identity);
+        if (!strcmp(identity, "alice"))
+            Alice = true;
+    }
+
+    plan_tests(Alice?kAliceTestCount:kBobTestCount);
+    tests(Alice);
+
+       return 0;
+}
diff --git a/sec/SOSCircle/Regressions/sc-101-accountsync.c b/sec/SOSCircle/Regressions/sc-101-accountsync.c
new file mode 100644 (file)
index 0000000..d433c62
--- /dev/null
@@ -0,0 +1,574 @@
+//
+//  sc-100-devicecircle.c
+//  sec
+//
+//  Created by John Hurley 10/16/12.
+//  Copyright 2012 Apple Inc. All rights reserved.
+//
+
+/*
+    This test is a combination of sc-75, sc_93 and sc_94 that can
+    be run on two devices.
+    
+    The test will look for a circle in kvs
+    - if none exists, it will create one
+    - if one exists, it will try to join
+    
+    Whenever you confirm a new peer, must start sync
+    
+    Test sc-98 can be run before this to clear out kvs
+*/
+
+// Run on 2 devices:
+//      /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_101_accountsync -v -- -i alice
+//      /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_101_accountsync -v -- -i bob
+
+#include <SecureObjectSync/SOSEngine.h>
+#include <SecureObjectSync/SOSPeer.h>
+
+#include "SOSCircle_regressions.h"
+
+#include <corecrypto/ccsha2.h>
+#include <Security/SecRandom.h>
+
+#include <utilities/SecCFWrappers.h>
+#include <utilities/debugging.h>
+#include <utilities/iOSforOSX.h>
+#include <stdint.h>
+
+#include <AssertMacros.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <CoreFoundation/CFDate.h>
+#include <getopt.h>
+
+#include <Security/SecKey.h>
+
+#include <SecureObjectSync/SOSFullPeerInfo.h>
+#include <SecureObjectSync/SOSPeerInfo.h>
+#include <SecureObjectSync/SOSCircle.h>
+#include <SecureObjectSync/SOSCloudCircle.h>
+#include <SecureObjectSync/SOSInternal.h>
+#include <SecureObjectSync/SOSUserKeygen.h>
+
+#include "SOSCircle_regressions.h"
+#include "SOSRegressionUtilities.h"
+#include "SOSTestDataSource.h"
+#include "SOSTestTransport.h"
+#include "SOSCloudKeychainClient.h"
+
+#include <securityd/SOSCloudCircleServer.h>
+
+#ifndef SEC_CONST_DECL
+#define SEC_CONST_DECL(k,v) CFTypeRef k = (CFTypeRef)(CFSTR(v));
+#endif
+
+//static     dispatch_queue_t wait_queue = NULL;
+
+#define VALUECFNULLCHECK(msg) if (msg == NULL || CFGetTypeID(msg) == CFNullGetTypeID()) { pass("CFNull message"); return 0; }
+
+// TODO _SecServerKeychainSyncUpdate
+
+// MARK: ----- Constants -----
+
+static CFStringRef circleKey = CFSTR("Circle");
+
+struct SOSKVSTransport {
+    struct SOSTransport t;
+    CFStringRef messageKey;
+};
+
+#include <notify.h>
+#include <dispatch/dispatch.h>
+
+static void putCircleInCloud(SOSCircleRef circle, dispatch_queue_t work_queue, dispatch_group_t work_group)
+{
+    CFErrorRef error = NULL;
+    CFDataRef newCloudCircleEncoded = SOSCircleCopyEncodedData(circle, kCFAllocatorDefault, &error);
+    ok(newCloudCircleEncoded, "Encoded as: %@ [%@]", newCloudCircleEncoded, error);
+
+    // Send the circle with our application request back to cloud
+    testPutObjectInCloud(circleKey, newCloudCircleEncoded, &error, work_group, work_queue);
+    CFReleaseSafe(newCloudCircleEncoded);
+}
+
+
+// artifacts of test harness : , dispatch_queue_t work_queue, dispatch_group_t work_group)
+bool SOSAccountEstablishCircle(SOSAccountRef account, CFStringRef circleName, CFErrorRef *error, dispatch_queue_t work_queue, dispatch_group_t work_group);
+
+bool SOSAccountEstablishCircle(SOSAccountRef account, CFStringRef circleName, CFErrorRef *error, dispatch_queue_t work_queue, dispatch_group_t work_group)
+{
+    CFErrorRef localError = NULL;
+    SOSCircleRef circle = SOSAccountEnsureCircle(account, circleName, NULL);
+    CFRetain(circle);
+    SecKeyRef user_privkey = SOSAccountGetPrivateCredential(account, &localError);
+
+    SOSFullPeerInfoRef our_full_peer_info = SOSAccountGetMyFullPeerInCircleNamed(account, circleName, &localError);
+    SOSPeerInfoRef our_peer_info = SOSFullPeerInfoGetPeerInfo(our_full_peer_info);
+    CFRetain(our_peer_info);
+
+    SecKeyRef   device_key =   SOSFullPeerInfoCopyDeviceKey(our_full_peer_info, &localError);
+    ok(device_key, "Retrieved device_key from full peer info (Error: %@)", localError);
+    CFReleaseNull(device_key);
+    CFReleaseNull(localError);
+    ok(SOSCircleRequestAdmission(circle, user_privkey, our_full_peer_info, &localError), "Requested admission (%@)", our_peer_info);
+    ok(SOSCircleAcceptRequests(circle, user_privkey, our_full_peer_info, &localError), "Accepted self");
+    
+    putCircleInCloud(circle, work_queue, work_group);
+    pass("Put (new) circle in cloud: (%@)", circle);
+
+#if 0
+    
+
+    SOSCircleRef oldCircle = SOSAccountFindCircle(account, SOSCircleGetName(circle));
+
+    if (!oldCircle)
+        return false; // Can't update one we don't have.
+    // TODO: Ensure we don't let circles get replayed.
+
+    CFDictionarySetValue(account->circles, SOSCircleGetName(circle), circle);
+
+//----
+            SOSCircleRef circle = SOSAccountFindCircle(our_account, circleKey);
+            CFRetain(circle);
+            
+            ok(SOSCircleRequestAdmission(circle, our_full_peer_info, user_key, &localError), "Requested admission (%@)", our_peer_info);
+            ok(SOSCircleAcceptRequests(circle, our_full_peer_info, user_key, &localError), "Accepted self");
+            
+            putCircleInCloud(circle, work_queue, work_group);
+
+//-----
+#endif
+    return true;
+}
+
+
+static void runTests(bool Alice, dispatch_queue_t work_queue, dispatch_group_t work_group)
+{
+    CFStringRef our_name =      Alice ? CFSTR("Alice") : CFSTR("Bob");
+    CFDictionaryRef our_gestalt = SOSCreatePeerGestaltFromName(our_name);
+    
+    dispatch_queue_t global_queue = dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
+    
+    CFErrorRef error = NULL;
+
+    CFDataRef cfpassword = CFDataCreate(NULL, (uint8_t *) "FooFooFoo", 10);
+
+    CFDataRef parameters = SOSUserKeyCreateGenerateParameters(&error);
+    ok(parameters, "No parameters!");
+    ok(error == NULL, "Error: (%@)", error);
+    CFReleaseNull(error);
+
+    SecKeyRef user_privkey = SOSUserKeygen(cfpassword, parameters, &error);
+    CFReleaseNull(parameters);
+    CFReleaseNull(cfpassword);
+
+    dispatch_semaphore_t start_semaphore = dispatch_semaphore_create(0);
+
+    CFStringRef sBobReady = CFSTR("Bob-Ready");
+    CFStringRef sAliceReady = CFSTR("Alice-Ready");
+    __block CFDataRef foundNonce = NULL;
+    if (Alice) {
+        const CFIndex nonceByteCount = 10;
+        CFMutableDataRef nonce = CFDataCreateMutable(kCFAllocatorDefault, nonceByteCount);
+        CFDataSetLength(nonce, nonceByteCount);
+        SecRandomCopyBytes(kSecRandomDefault, CFDataGetLength(nonce), CFDataGetMutableBytePtr(nonce));
+
+        CloudItemsChangedBlock notification_block = ^ (CFDictionaryRef returnedValues)
+        {
+            CFTypeRef bobReadyValue = CFDictionaryGetValue(returnedValues, sBobReady);
+            if (isData(bobReadyValue) && CFEqual(bobReadyValue, nonce)) {
+                CFDictionaryRef changes = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, sAliceReady, kCFNull, sBobReady, kCFNull, NULL);
+
+                SOSCloudKeychainPutObjectsInCloud(changes, global_queue, NULL);
+
+                pass("signalling");
+                dispatch_semaphore_signal(start_semaphore);
+                CFReleaseSafe(changes);
+            }
+            CFReleaseSafe(error);
+        };
+
+        CloudKeychainReplyBlock reply_block = ^ (CFDictionaryRef returnedValues, CFErrorRef error)
+        {
+            notification_block(returnedValues);
+        };
+
+        pass("Clearing");
+
+        testClearAll(global_queue, work_group);
+
+        CFArrayRef bobKey = CFArrayCreateForCFTypes(kCFAllocatorDefault, sBobReady, NULL);
+        SOSCloudKeychainRegisterKeysAndGet(bobKey, work_queue, reply_block, notification_block);
+        
+        CFStringRef description = SOSInterestListCopyDescription(bobKey);
+        pass("%@", description);
+        
+        CFReleaseNull(description);
+        CFReleaseNull(bobKey);
+
+        CFDictionaryRef changes = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, sAliceReady, nonce, NULL);
+        SOSCloudKeychainPutObjectsInCloud(changes, global_queue, NULL);
+        
+        description = SOSChangesCopyDescription(changes, true);
+        pass("%@", description);
+        CFReleaseNull(description);
+        
+        CFReleaseNull(changes);
+    } else {
+        CloudItemsChangedBlock notification_block = ^ (CFDictionaryRef returnedValues)
+        {
+            CFTypeRef aliceReadyValue = CFDictionaryGetValue(returnedValues, sAliceReady);
+            if (isData(aliceReadyValue)) {
+                foundNonce = (CFDataRef) aliceReadyValue;
+                CFRetain(foundNonce);
+
+                pass("signalling found: %@", foundNonce);
+                dispatch_semaphore_signal(start_semaphore);
+            }
+            CFReleaseSafe(error);
+        };
+
+        CloudKeychainReplyBlock reply_block = ^ (CFDictionaryRef returnedValues, CFErrorRef error)
+        {
+            notification_block(returnedValues);
+        };
+
+        CFArrayRef aliceKey = CFArrayCreateForCFTypes(kCFAllocatorDefault, sAliceReady, NULL);
+        SOSCloudKeychainRegisterKeysAndGet(aliceKey, work_queue, reply_block, notification_block);
+        
+        CFStringRef description = SOSInterestListCopyDescription(aliceKey);
+        pass("%@", description);
+        CFReleaseNull(description);
+
+        CFReleaseSafe(aliceKey);
+    }
+
+    pass("Waiting");
+    dispatch_semaphore_wait(start_semaphore, DISPATCH_TIME_FOREVER);
+    pass("Moving on");
+
+
+    __block CFArrayRef ourWork = NULL;
+    __block CFIndex current = 0;
+    __block SOSAccountRef our_account = NULL;
+    typedef CFIndex (^TestStateBlock) (SOSAccountRef account, CFErrorRef error);
+
+    SOSDataSourceFactoryRef our_data_source_factory = SOSTestDataSourceFactoryCreate();
+    SOSDataSourceRef our_data_source = SOSTestDataSourceCreate();
+    SOSTestDataSourceFactoryAddDataSource(our_data_source_factory, circleKey, our_data_source);
+    
+    CloudItemsChangedBlock notification_block = ^ (CFDictionaryRef returnedValues)
+    {
+        CFStringRef changesString = SOSChangesCopyDescription(returnedValues, false);
+        pass("Got: %@", changesString);
+        CFReleaseNull(changesString);
+
+        CFErrorRef error = NULL;
+
+        SOSAccountHandleUpdates(our_account, returnedValues, &error);
+
+        TestStateBlock thingToDo = CFArrayGetValueAtIndex(ourWork, current);
+
+        if (thingToDo)
+        {
+            pass("%@ stage %d rv: %@ [error: %@]", our_name, (int)current, returnedValues, error);
+            current += thingToDo(our_account, error);
+        }
+
+        if (current < 0 || current >= CFArrayGetCount(ourWork))
+            dispatch_group_leave(work_group);
+
+        CFReleaseSafe(error);
+    };
+
+    CloudKeychainReplyBlock reply_block = ^ (CFDictionaryRef returnedValues, CFErrorRef error)
+    {
+        pass("Reply block");
+        notification_block(returnedValues);
+    };
+
+    __block bool initialConnection = !Alice;
+    SOSAccountKeyInterestBlock updateKVSKeys = ^(bool getNewKeysOnly, CFArrayRef alwaysKeys, CFArrayRef afterFirstUnlockKeys, CFArrayRef unlockedKeys) {
+        CFMutableArrayRef keys = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, alwaysKeys);
+        CFArrayAppendArray(keys, afterFirstUnlockKeys, CFRangeMake(0, CFArrayGetCount(afterFirstUnlockKeys)));
+        CFArrayAppendArray(keys, unlockedKeys, CFRangeMake(0, CFArrayGetCount(unlockedKeys)));
+
+        CFStringRef description = SOSInterestListCopyDescription(keys);
+
+        pass("%@", description);
+
+        CFReleaseNull(description);
+
+        SOSCloudKeychainRegisterKeysAndGet(keys, work_queue,
+                                           initialConnection ? reply_block : NULL, notification_block);
+
+        CFReleaseSafe(keys);
+        initialConnection = false;
+    };
+    
+    SOSAccountDataUpdateBlock updateKVS = ^ bool (CFDictionaryRef changes, CFErrorRef *error) {
+        CFStringRef changesString = SOSChangesCopyDescription(changes, true);
+        pass("Pushing: %@", changesString);
+        CFReleaseNull(changesString);
+
+        SOSCloudKeychainPutObjectsInCloud(changes, global_queue,
+                                          ^ (CFDictionaryRef returnedValues, CFErrorRef error)
+                                          {
+                                              if (error) {
+                                                  fail("testPutObjectInCloud returned: %@", error);
+                                                  CFRelease(error);
+                                              }
+                                          });
+        return true;
+    };
+    
+
+    our_account = SOSAccountCreate(kCFAllocatorDefault, our_gestalt, our_data_source_factory, updateKVSKeys, updateKVS);
+    
+    SOSFullPeerInfoRef our_full_peer_info = SOSAccountGetMyFullPeerInCircleNamed(our_account, circleKey, &error);
+    SOSPeerInfoRef our_peer_info = SOSFullPeerInfoGetPeerInfo(our_full_peer_info);
+    CFRetain(our_peer_info);
+
+    SOSAccountAddChangeBlock(our_account, ^(SOSCircleRef circle,
+                                            CFArrayRef peer_additions, CFArrayRef peer_removals,
+                                            CFArrayRef applicant_additions, CFArrayRef applicant_removals) {
+        // Should initiate syncing here!
+        bool joined = CFArrayContainsValue(peer_additions, CFRangeMake(0, CFArrayGetCount(peer_additions)), our_peer_info);
+
+        pass("Peers Changed [%s] (Add: %@, Remove: %@)", joined ? "*** I'm in ***" : "Not including me.", peer_additions, peer_removals);
+
+        if (joined) {
+            SOSCircleForEachPeer(circle, ^(SOSPeerInfoRef peer_info)
+                       {
+                           CFErrorRef error = NULL;
+
+                           if (!CFEqual(peer_info, our_peer_info)) {
+                               ok(SOSAccountSyncWithPeer(our_account, circle, peer_info, NULL, &error),
+                                  "Initiated sync with %@: [Error %@]", peer_info, error);
+                           }
+                       });
+        }
+    });
+    
+    ok(our_peer_info, "Peer Info: %@ [error: %@]", our_peer_info, error);
+        
+    //__block SOSEngineRef ourEngine;
+
+    SOSObjectRef firstObject = SOSDataSourceCreateGenericItem(our_data_source, CFSTR("1234"), CFSTR("service"));
+
+    //------------------------------------------------------------------------
+    //              ALICE
+    //------------------------------------------------------------------------
+    CFArrayRef aliceWorkToDo =
+    CFArrayCreateForCFTypes(kCFAllocatorDefault,
+                           ^ CFIndex (SOSAccountRef account, CFErrorRef error)
+                           {
+                               /*
+                                When we get here, it should only be because Bob has retrieved
+                                our circle and requested admission to our circle.
+                                If we don't find a circleKey entry, our test setup is wrong.
+                                */
+                               CFErrorRef modifyError = NULL;
+                               SOSAccountModifyCircle(account, circleKey, &modifyError, ^(SOSCircleRef circle) {
+                                   CFErrorRef localError = NULL;
+                                   
+                                   ok(SOSCircleHasPeer(circle, our_peer_info, &localError), "We're a peer [Error: %@]", localError);
+                                   is(SOSCircleCountPeers(circle), 1, "One peer, woot");
+                                   is(SOSCircleCountApplicants(circle), 1, "One applicant, hope it's BOB");
+                                   
+                                   ok(SOSCircleAcceptRequests(circle, user_privkey, our_full_peer_info, &localError), "Accepted peers (%@) [Error: %@]", circle, localError);
+                                   
+                                   CFReleaseSafe(localError);
+                               });
+                               CFReleaseSafe(modifyError);
+
+                               return +1;
+                           },
+                           ^ CFIndex (SOSAccountRef account, CFErrorRef error)
+                           {
+                               // He should be telling us about him and we should be responding.
+                               
+                               CFMutableDictionaryRef ourDatabase = SOSTestDataSourceGetDatabase(our_data_source);
+                               
+                               is(CFDictionaryGetCount(ourDatabase), 0, "Database empty, we're synced");
+
+                               pass("1");
+                               return +1;
+                           },
+                           ^ CFIndex (SOSAccountRef account, CFErrorRef error)
+                           {
+                               CFMutableDictionaryRef ourDatabase = SOSTestDataSourceGetDatabase(our_data_source);
+                               
+                               is(CFDictionaryGetCount(ourDatabase), 1, "One element!");
+                               
+                               return +1;
+                           },
+                           NULL);
+    
+    //------------------------------------------------------------------------
+    //              BOB
+    //------------------------------------------------------------------------
+    
+    CFArrayRef bobWorkToDo =
+    CFArrayCreateForCFTypes(kCFAllocatorDefault,
+                           ^ CFIndex (SOSAccountRef account, CFErrorRef error)
+                           {
+                               __block CFIndex increment = 0;
+                               CFErrorRef modifyError = NULL;
+                               SOSAccountModifyCircle(account, circleKey, &modifyError, ^(SOSCircleRef circle) {
+                                   CFErrorRef localError = NULL;
+
+                                   if (SOSCircleCountPeers(circle) == 1) {
+                                       is(SOSCircleCountApplicants(circle), 0, "No applicants");
+                                       ok(SOSCircleRequestAdmission(circle, user_privkey, our_full_peer_info, &localError), "Requested admission (%@) [Error: %@]", circle, localError);
+                                       increment = +1;
+                                   }
+                                   
+                                   CFReleaseSafe(localError);
+                               });
+                               CFReleaseSafe(modifyError);
+                               return increment;
+                           },
+                           ^ CFIndex (SOSAccountRef account, CFErrorRef error)
+                           {
+                               CFErrorRef modifyError = NULL;
+                               SOSAccountModifyCircle(account, circleKey, &modifyError, ^(SOSCircleRef circle) {
+                                   CFErrorRef localError = NULL;
+
+                                   ok(SOSCircleHasPeer(circle, our_peer_info, &localError), "We're a peer (%@) [Error: %@]", circle, localError);
+                                   is(SOSCircleCountPeers(circle), 2, "One peer, hope it's Alice");
+                                   is(SOSCircleCountApplicants(circle), 0, "No applicants");
+                                   
+                                   CFReleaseSafe(localError);
+                               });
+                               CFReleaseSafe(modifyError);
+
+                               return +1;
+                           },
+                           ^ CFIndex (SOSAccountRef account, CFErrorRef error)
+                           {
+                               CFErrorRef localError = NULL;
+                               CFMutableDictionaryRef ourDatabase = SOSTestDataSourceGetDatabase(our_data_source);
+                               is(CFDictionaryGetCount(ourDatabase), 0, "Database empty, we're synced");
+                               
+                               SOSTestDataSourceAddObject(our_data_source, firstObject, &localError);
+                               CFReleaseNull(localError);
+                               
+                               SOSAccountSyncWithAllPeers(account, &localError);
+                               CFReleaseNull(localError);
+                               
+                               pass("1");
+                               return +1;
+                           },
+                           ^ CFIndex (SOSAccountRef account, CFErrorRef error)
+                           {
+                               pass("2");
+                               
+                               CFMutableDictionaryRef ourDatabase = SOSTestDataSourceGetDatabase(our_data_source);
+                               is(CFDictionaryGetCount(ourDatabase), 1, "Still one element!");
+
+                               return +1;
+                           },
+                           NULL);
+    
+    //------------------------------------------------------------------------
+    //              START
+    //------------------------------------------------------------------------
+    
+    ourWork = Alice ? aliceWorkToDo : bobWorkToDo;
+
+    if (Alice) {
+        /*
+         Here we create a fresh circle, add and accept ourselves
+         Then we post to the cloud and wait for a Circle changed notification
+         */
+
+        CFErrorRef modifyError = NULL;
+        SOSAccountModifyCircle(our_account, circleKey, &modifyError, ^(SOSCircleRef circle) {
+            CFErrorRef localError = NULL;
+
+            ok(SOSCircleRequestAdmission(circle, user_privkey, our_full_peer_info, &localError), "Requested admission (%@) [error: %@]", our_peer_info, localError);
+            ok(SOSCircleAcceptRequests(circle, user_privkey, our_full_peer_info, &localError), "Accepted self [Error: %@]", localError);
+
+            CFReleaseSafe(localError);
+        });
+        CFReleaseSafe(modifyError);
+
+    } else {
+        // Tell alice we're set to go:
+        if (foundNonce) {
+            CFDictionaryRef changes = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, sBobReady, foundNonce, NULL);
+            SOSCloudKeychainPutObjectsInCloud(changes, global_queue, NULL);
+            CFReleaseSafe(changes);
+        } else {
+            fail("No none found to start the handshake");
+        }
+    }
+    dispatch_group_wait(work_group, DISPATCH_TIME_FOREVER);
+    
+    // We probably never get here since the program exits..
+    
+    CFReleaseNull(aliceWorkToDo);
+    CFReleaseNull(bobWorkToDo);
+    CFReleaseNull(our_peer_info);
+    CFReleaseNull(foundNonce);
+    
+}
+
+// MARK: ----- start of all tests -----
+static void tests(bool Alice)
+{
+    dispatch_queue_t work_queue = dispatch_queue_create("NotificationQueue", DISPATCH_QUEUE_SERIAL); //;
+    dispatch_group_t work_group = dispatch_group_create();
+
+    // Prep the group for exitting the whole shebang.
+    runTests(Alice, work_queue, work_group);
+}
+
+// define the options table for the command line
+static const struct option options[] =
+{
+       { "verbose",            optional_argument,      NULL, 'v' },
+       { "identity",           optional_argument,      NULL, 'i' },
+       { "clear",          optional_argument,  NULL, 'C' },
+       { }
+};
+
+static int kAliceTestCount = 32;
+static int kBobTestCount = 30;
+
+int sc_101_accountsync(int argc, char *const *argv)
+{
+    char *identity = NULL;
+    extern char *optarg;
+    int arg, argSlot;
+    bool Alice = false;
+
+    while (argSlot = -1, (arg = getopt_long(argc, (char * const *)argv, "i:vC", options, &argSlot)) != -1)
+        switch (arg)
+        {
+        case 'i':
+            identity = (char *)(optarg);
+            break;
+        case 'C':   // should set up to call testClearAll
+            break;
+        default:
+            secerror("arg: %s", optarg);
+            break;
+        }
+    
+    if (identity)
+    {
+        secerror("We are %s",identity);
+        if (!strcmp(identity, "alice"))
+            Alice = true;
+    }
+
+    plan_tests(Alice?kAliceTestCount:kBobTestCount);
+    tests(Alice);
+
+       return 0;
+}
diff --git a/sec/SOSCircle/Regressions/sc-102-cfusernotification.c b/sec/SOSCircle/Regressions/sc-102-cfusernotification.c
new file mode 100644 (file)
index 0000000..85ae8c9
--- /dev/null
@@ -0,0 +1,100 @@
+//
+//  sc-102-xx
+//  sec
+//
+//  Created by John Hurley 10/16/12.
+//  Copyright 2012 Apple Inc. All rights reserved.
+//
+
+/*
+    This test is a simple test of SOSCloudKeychainUserNotification to show
+    an OK/Cancel dialog to the user and get the response. Run with:
+    
+        /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_102_cfusernotification -v
+         
+*/
+
+#include <AssertMacros.h>
+#include <CoreFoundation/CFUserNotification.h>
+#include <dispatch/dispatch.h>
+
+#include <utilities/SecCFWrappers.h>
+#include <utilities/debugging.h>
+
+#include "SOSCircle_regressions.h"
+#include "SOSCloudKeychainClient.h"
+#include "SOSCloudKeychainConstants.h"
+
+#if TARGET_OS_EMBEDDED && !TARGET_IPHONE_SIMULATOR
+#include <MobileGestalt.h>
+#endif
+
+static void tests(void)
+{
+//    CFStringRef messageToUser = CFSTR("OK to sync with world?");
+//    CFStringRef messageToUser = CFSTR("Allow “Emily‘s iPad to use your iCloud Keychain?");
+#if !TARGET_IPHONE_SIMULATOR
+#if TARGET_OS_EMBEDDED
+    CFStringRef our_peer_id = (CFStringRef)MGCopyAnswer(kMGQUserAssignedDeviceName, NULL);
+#else
+    CFStringRef our_peer_id = CFSTR("🔥💩");
+#endif
+#else
+    CFStringRef our_peer_id = CFSTR("Emily‘s iPad");
+#endif
+
+    CFStringRef messageToUser = CFStringCreateWithFormat(kCFAllocatorDefault, 0, CFSTR("Allow “%@” to use your iCloud Keychain?"), our_peer_id);
+    dispatch_queue_t processQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
+    dispatch_group_t work_group = dispatch_group_create();
+
+    // Prep the group for exitting the whole shebang.
+    dispatch_group_enter(work_group);
+    dispatch_group_notify(work_group, processQueue, ^
+        {
+            printf("Exiting via dispatch_group_notify; all work done\n");
+            CFRunLoopStop(CFRunLoopGetMain());
+        //  exit(0);
+        });
+
+    SOSCloudKeychainUserNotification(messageToUser, processQueue, ^ (CFDictionaryRef returnedValues, CFErrorRef error)
+        {
+            uint64_t flags = 0;
+            pass("Reply from SOSCloudKeychainUserNotification: %@", returnedValues);
+            CFStringRef nfkey = CFStringCreateWithCString(kCFAllocatorDefault, kMessageKeyNotificationFlags, kCFStringEncodingUTF8);
+            CFTypeRef cfflags = returnedValues ? CFDictionaryGetValue(returnedValues, nfkey) : NULL;
+            if (cfflags && (CFGetTypeID(cfflags) == CFNumberGetTypeID()))
+                CFNumberGetValue(cfflags, kCFNumberSInt64Type, &flags);
+            CFReleaseSafe(nfkey);
+            
+            // flags is not actually a mask
+            if (flags == kCFUserNotificationDefaultResponse)
+                pass("OK button pressed");
+            else
+            if (flags == kCFUserNotificationCancelResponse)
+                pass("Cancel button pressed");
+            else
+            if (flags == kCFUserNotificationAlternateResponse)
+                pass("Alternate button pressed");
+            else
+                pass("Flags: %#llx", flags);
+
+            ok(error == NULL, "SOSCloudKeychainPutObjectsInCloud [error: %@:]", error);
+            dispatch_group_leave(work_group);
+        });
+
+    pass("Dialog is up for device \"%@\"", our_peer_id);
+    printf("Dialog is up\n");
+    dispatch_group_wait(work_group, DISPATCH_TIME_FOREVER);
+    CFRunLoopRun();                 // Wait for it...
+    pass("Exit from run loop");
+}
+
+static int kUNTestCount = 5;
+
+int sc_102_cfusernotification(int argc, char *const *argv)
+{
+    plan_tests(kUNTestCount);
+    tests();
+
+       return 0;
+}
diff --git a/sec/SOSCircle/Regressions/sc-103-syncupdate.c b/sec/SOSCircle/Regressions/sc-103-syncupdate.c
new file mode 100644 (file)
index 0000000..48e26de
--- /dev/null
@@ -0,0 +1,228 @@
+//
+//  sc-103-syncupdate.c
+//  sec
+//
+//  Created by John Hurley on 9/6/12.
+//
+//
+
+// Run on 2 devices:
+//      /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_103_syncupdate -v -- -i alice
+//      /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_103_syncupdate -v -- -i bob
+// Run on 2 devices:
+//      /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_101_accountsync -v -- -i 
+//      /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_101_accountsync -v -- -i 
+
+#include <AssertMacros.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <xpc/xpc.h>
+
+#include <Security/SecBase.h>
+#include <Security/SecItem.h>
+#include <Security/SecItemPriv.h>
+
+#include <CKBridge/SOSCloudKeychainClient.h>
+#include <SecureObjectSync/SOSCloudCircle.h>
+
+#include <notify.h>
+#include <dispatch/dispatch.h>
+#include <getopt.h>
+
+#include <utilities/SecCFWrappers.h>
+#include <utilities/debugging.h>
+#include <utilities/SecCFRelease.h>
+
+#include "SOSCircle_regressions.h"
+#include "SOSRegressionUtilities.h"
+#include "SOSCloudKeychainConstants.h"
+
+#define xsecdebug(format...) secerror(format)
+
+static dispatch_group_t sDispatchGroup = NULL;
+
+static const uint64_t putTestInterval = 10ull * NSEC_PER_SEC;
+static const uint64_t leeway = 1ull * NSEC_PER_SEC;
+static const uint64_t syncInterval = 60ull * NSEC_PER_SEC;             // seconds
+static const uint64_t putDelay = 10ull * NSEC_PER_SEC;   // seconds; should probably be longer than syncedefaultsd latency (6 sec)
+static const uint64_t exitDelay = 180ull * NSEC_PER_SEC;   // seconds
+
+static dispatch_queue_t requestqueue;
+
+static dispatch_source_t exitTimerSource;
+
+static uint64_t failCounter = 0;
+static uint64_t putAttemptCounter = 0;
+static uint64_t itemsChangedCount = 0;
+
+
+// MARK: ----- Debug Routines -----
+
+static void tearDown(void)
+{
+    xsecdebug("exit");
+    CFRunLoopStop(CFRunLoopGetMain());
+}
+
+// MARK: ----- Get Cycle Tester -----
+
+static void initCyclerTests(dispatch_group_t dgroup)
+{
+    /*
+        We set up two timer sources:
+        - getRequestsource waits 5 seconds, then gets every 5 seconds
+        - exitTimerSource fires once after 300 seconds (5 minutes)
+        All are created suspended, so they don't start yet
+    */
+    
+    uint64_t delay = exitDelay;
+    dispatch_time_t exitFireTime = dispatch_time(DISPATCH_TIME_NOW, delay);
+    exitTimerSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, (uintptr_t)NULL, 0, requestqueue);
+    dispatch_source_set_timer(exitTimerSource, exitFireTime, 0ull, leeway);
+        
+    dispatch_source_set_event_handler(exitTimerSource,
+    ^{
+        xsecdebug("Test Exit: %lld", failCounter);
+        printf("Test Exit: fail: %lld, total: %lld, changed: %lld\n", failCounter, putAttemptCounter, itemsChangedCount);
+        tearDown();
+        exit(0);
+    });
+}
+
+static void updateSyncingEnabledSwitch()
+{
+    // Set the visual state of switch based on membership in circle
+    CFErrorRef error = NULL;
+    SOSCCStatus ccstatus = SOSCCThisDeviceIsInCircle(&error);
+ //   [_syncingEnabled setOn:(BOOL)(ccstatus == kSOSCCInCircle) animated:NO];
+    pass("ccstatus: %d, error: %@", ccstatus, error);
+}
+
+static void requestToJoinCircle()
+{
+    // Set the visual state of switch based on membership in circle
+    bool bx;
+    CFErrorRef error = NULL;
+    SOSCCStatus ccstatus = SOSCCThisDeviceIsInCircle(&error);
+    pass("ccstatus: %d, error: %@", ccstatus, error);
+    if (ccstatus == kSOSCCInCircle)
+        return;
+
+    if (ccstatus == kSOSCCNotInCircle)
+    {
+        pass("Not in circle, requesting admission");
+        bx = SOSCCRequestToJoinCircle(&error);
+        if (!bx)
+            pass("SOSCCRequestToJoinCircle error: %@", error);
+    }
+    else
+    if (ccstatus == kSOSCCRequestPending)
+        pass("Not in circle, admission pending");
+}
+
+static void handleEnableSyncing(bool turningOn)
+{
+    dispatch_queue_t workq = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
+    if (turningOn)  // i.e. we are trying to turn on syncing
+    {
+        pass("Keychain syncing is being turned ON");
+        dispatch_async(workq, ^
+        {
+            CFErrorRef error = NULL;
+            bool bx = SOSCCResetToOffering(&error);
+            if (bx)
+                pass("ResetToOffering OK");
+            else
+                pass("ResetToOffering fail: %@", error);
+
+            requestToJoinCircle();
+            updateSyncingEnabledSwitch();
+            dispatch_group_leave(sDispatchGroup);
+        });
+    }
+    else
+    {
+        pass("Keychain syncing is being turned OFF");
+        CFErrorRef error = NULL;
+        bool bx = SOSCCRemoveThisDeviceFromCircle(&error);
+        updateSyncingEnabledSwitch();
+        if (!bx)
+            pass("SOSCCRemoveThisDeviceFromCircle fail: %@", error);
+    }
+}
+
+// MARK: ----- start of all tests -----
+
+static void initialEstablish(void)
+{
+    dispatch_group_enter(sDispatchGroup);
+    dispatch_group_notify(sDispatchGroup, requestqueue, ^
+        {
+            printf("Exiting via dispatch_group_notify; all work done\n");
+            CFRunLoopStop(CFRunLoopGetMain());
+        //  exit(0);
+        });
+handleEnableSyncing(true);
+
+#if 0
+    CFErrorRef error = NULL;
+    bool bx = false;
+    SOSCCStatus sccStatus = SOSCCThisDeviceIsInCircle(&error);
+    if (sccStatus == kSOSCCNotInCircle)
+        bx = SOSCCResetToOffering(&error);
+    else
+        bx = SOSCCRequestToJoinCircle(&error);
+    if (!bx)
+        xsecdebug("circle establish error: %@", error);
+    ok(bx, "Circle established");
+#endif
+}
+
+// MARK: ---------- Main ----------
+
+// define the options table for the command line
+static const struct option options[] =
+{
+       { "verbose",            optional_argument,      NULL, 'v' },
+       { }
+};
+
+static int kTestCount = 22;
+
+int sc_103_syncupdate(int argc, char *const *argv)
+{
+    extern char *optarg;
+    int arg, argSlot;
+    
+    while (argSlot = -1, (arg = getopt_long(argc, (char * const *)argv, "i:v", options, &argSlot)) != -1)
+        switch (arg)
+        {
+        default:
+            secerror("arg: %s", optarg);
+            break;
+        }
+    
+    plan_tests(kTestCount);
+
+    SKIP:
+    {
+        skip("Skipping ckdclient tests because CloudKeychainProxy.xpc is not installed", kTestCount, XPCServiceInstalled());
+        sDispatchGroup = dispatch_group_create();
+        requestqueue = dispatch_queue_create("sc_103_syncupdate", DISPATCH_QUEUE_CONCURRENT);
+        initCyclerTests(sDispatchGroup);
+        initialEstablish();
+    }
+    
+    dispatch_group_wait(sDispatchGroup, DISPATCH_TIME_FOREVER);
+    pass("Tests are running...");
+    printf("Tests are running...\n");
+    CFRunLoopRun();                 // Wait for it...
+    pass("Exit from run loop");
+
+       return 0;
+}
+
+
+
diff --git a/sec/SOSCircle/Regressions/sc-120-cloudcircle.c b/sec/SOSCircle/Regressions/sc-120-cloudcircle.c
new file mode 100644 (file)
index 0000000..30d2c84
--- /dev/null
@@ -0,0 +1,391 @@
+/*
+ *  sc-01-create.c
+ *
+ *  Created by Mitch Adler on 1/25/121.
+ *  Copyright 2012 Apple Inc. All rights reserved.
+ *
+ */
+
+//      /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_120_cloudcircle -v -- -i alice
+//      /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_120_cloudcircle -v -- -i bob
+
+#include <Security/SecBase.h>
+#include <Security/SecItem.h>
+#include <Security/SecKey.h>
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+#include <Security/SecRandom.h>
+#endif
+
+#include <SecureObjectSync/SOSAccount.h>
+#include <SecureObjectSync/SOSCloudCircle.h>
+#include <SecureObjectSync/SOSCloudCircleInternal.h>
+#include <SecureObjectSync/SOSPeerInfo.h>
+#include <SecureObjectSync/SOSInternal.h>
+#include "SOSTestDataSource.h"
+#include <CKBridge/SOSCloudKeychainClient.h>
+
+#include <utilities/debugging.h>
+
+#include <utilities/SecCFWrappers.h>
+#include <utilities/iOSforOSX.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <getopt.h>
+
+#include <notify.h>
+
+#include "SOSRegressionUtilities.h"
+
+#include "SOSCircle_regressions.h"
+#include "SecureObjectSync/Imported/SOSCloudCircleServer.h"
+
+#ifdef NO_SERVER
+#if TARGET_OS_EMBEDDED || TARGET_IPHONE_SIMULATOR
+#include <securityd/SOSCloudCircleServer.h>
+#else
+#warning "NO_SERVER doesn't really work on OSX"
+#endif
+#endif
+
+static CFStringRef kCircleName = CFSTR("Global Circle");
+
+static CFStringRef sAliceReady = CFSTR("Alice-Ready");
+static CFStringRef sBobReady = CFSTR("Bob-Ready");
+
+static void SOSCloudKeychainClearAllSync()
+{
+    dispatch_semaphore_t waitSemaphore = dispatch_semaphore_create(0);
+    SOSCloudKeychainClearAll(dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
+                             ^(CFDictionaryRef returnedValues __unused, CFErrorRef error)
+                             {
+                                 CFReleaseSafe(error);
+                                 dispatch_semaphore_signal(waitSemaphore);
+                             });
+    dispatch_semaphore_wait(waitSemaphore, DISPATCH_TIME_FOREVER);
+    dispatch_release(waitSemaphore);
+}
+
+static void ClearAndSynchronize()
+{
+    dispatch_queue_t global_queue = dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
+    dispatch_semaphore_t bob_ready_semaphore = dispatch_semaphore_create(0);
+    
+    const CFIndex nonceByteCount = 10;
+    CFMutableDataRef nonce = CFDataCreateMutable(kCFAllocatorDefault, nonceByteCount);
+    CFDataSetLength(nonce, nonceByteCount);
+    SecRandomCopyBytes(kSecRandomDefault, CFDataGetLength(nonce), CFDataGetMutableBytePtr(nonce));
+    
+    dispatch_queue_t notification_queue = dispatch_queue_create("sync notification queue", DISPATCH_QUEUE_SERIAL);
+    
+    CloudItemsChangedBlock notification_block = ^ (CFDictionaryRef returnedValues)
+    {
+        CFRetain(returnedValues);
+        dispatch_async(notification_queue, ^{
+            CFTypeRef bobReadyValue = CFDictionaryGetValue(returnedValues, sBobReady);
+            if (isData(bobReadyValue) && CFEqual(bobReadyValue, nonce)) {
+                SOSCloudKeychainClearAllSync();
+
+                pass("signalling");
+                dispatch_semaphore_signal(bob_ready_semaphore);
+            } else {
+                pass("Ignoring change: %@", returnedValues);
+            }
+            CFReleaseSafe(returnedValues);
+        });
+    };
+    
+    CloudKeychainReplyBlock reply_block = ^ (CFDictionaryRef returnedValues, CFErrorRef error)
+    {
+        if (CFDictionaryGetCount(returnedValues) != 0)
+            notification_block(returnedValues);
+    };
+    
+    pass("Clearing");
+    SOSCloudKeychainClearAllSync();
+    
+    CFArrayRef bobKey = CFArrayCreateForCFTypes(kCFAllocatorDefault, sBobReady, NULL);
+    SOSCloudKeychainRegisterKeysAndGet(bobKey, global_queue, reply_block, notification_block);
+    
+    CFStringRef description = SOSInterestListCopyDescription(bobKey);
+    pass("%@", description);
+    
+    CFReleaseNull(description);
+    CFReleaseNull(bobKey);
+    
+    CFDictionaryRef changes = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, sAliceReady, nonce, NULL);
+    SOSCloudKeychainPutObjectsInCloud(changes, global_queue, NULL);
+    
+    description = SOSChangesCopyDescription(changes, true);
+    pass("%@", description);
+    CFReleaseNull(description);
+    
+    pass("Waiting");
+    dispatch_semaphore_wait(bob_ready_semaphore, DISPATCH_TIME_FOREVER);
+    dispatch_release(bob_ready_semaphore);
+
+    pass("Continuing");
+
+    CFErrorRef error = NULL;
+    CFArrayRef no_keys = CFArrayCreateForCFTypes(kCFAllocatorDefault, NULL);
+    SOSCloudKeychainUpdateKeys(false, no_keys, no_keys, no_keys, &error);
+
+    SOSCloudKeychainSetItemsChangedBlock(NULL);
+    CFReleaseSafe(no_keys);
+    CFReleaseSafe(error);
+
+    
+    CFReleaseNull(changes);
+}
+
+static void WaitForSynchronization()
+{
+    dispatch_queue_t global_queue = dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
+    dispatch_semaphore_t alice_ready_semaphore = dispatch_semaphore_create(0);
+    dispatch_queue_t notification_queue = dispatch_queue_create("sync notification queue", DISPATCH_QUEUE_SERIAL);
+    
+    __block CFDataRef foundNonce = NULL;
+    CloudItemsChangedBlock notification_block = ^ (CFDictionaryRef returnedValues)
+    {
+        CFRetain(returnedValues);
+        dispatch_async(notification_queue, ^{
+            CFTypeRef aliceReadyValue = CFDictionaryGetValue(returnedValues, sAliceReady);
+            if (isData(aliceReadyValue)) {
+                foundNonce = (CFDataRef) aliceReadyValue;
+                CFRetain(foundNonce);
+                pass("signalling for: %@", foundNonce);
+                
+                dispatch_semaphore_signal(alice_ready_semaphore);
+            }
+            CFReleaseSafe(returnedValues);
+        });
+    };
+    
+    CloudKeychainReplyBlock reply_block = ^ (CFDictionaryRef returnedValues, CFErrorRef error)
+    {
+        if (CFDictionaryGetCount(returnedValues) != 0)
+            notification_block(returnedValues);
+    };
+    
+    CFArrayRef aliceKey = CFArrayCreateForCFTypes(kCFAllocatorDefault, sAliceReady, NULL);
+    SOSCloudKeychainRegisterKeysAndGet(aliceKey, global_queue, reply_block, notification_block);
+    
+    CFStringRef description = SOSInterestListCopyDescription(aliceKey);
+    pass("%@", description);
+    CFReleaseNull(description);
+    
+    pass("Waiting");
+    dispatch_semaphore_wait(alice_ready_semaphore, DISPATCH_TIME_FOREVER);
+    dispatch_release(alice_ready_semaphore);
+    pass("Continuing");
+
+    CFDictionaryRef changes = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, sBobReady, foundNonce, NULL);
+    SOSCloudKeychainPutObjectsInCloud(changes, global_queue, NULL);
+    CFReleaseSafe(changes);
+    
+    CFReleaseSafe(foundNonce);
+    CFReleaseSafe(aliceKey);
+}
+
+static CFStringRef circleKey = CFSTR("Circle");
+
+#ifdef NO_SERVER
+static SOSDataSourceRef SetupTestFactory()
+{
+    static SOSDataSourceRef our_data_source;
+
+    our_data_source = SOSTestDataSourceCreate();
+
+    SOSKeychainAccountSetFactoryForAccount(^ {
+        SOSDataSourceFactoryRef our_data_source_factory = SOSTestDataSourceFactoryCreate();
+        SOSTestDataSourceFactoryAddDataSource(our_data_source_factory, circleKey, our_data_source);
+        return our_data_source_factory;
+    });
+    
+    return our_data_source;
+}
+#endif
+
+static void PurgeAndReload()
+{
+#if 0
+    CFErrorRef error = NULL;
+    ok(SOSKeychainSaveAccountDataAndPurge(&error), "Purged");
+    CFReleaseNull(error);
+    
+    ok(SOSKeychainAccountGetSharedAccount(), "Got Shared: %@", SOSKeychainAccountGetSharedAccount());
+#endif
+}
+
+#ifndef NO_SERVER
+#define SOSKeychainAccountGetSharedAccount() NULL
+#endif
+
+#define kAliceTestCount 100
+static void AliceTests()
+{
+    plan_tests(kAliceTestCount);
+    
+    dispatch_semaphore_t notification_signal = dispatch_semaphore_create(0);
+    int token;
+    notify_register_dispatch(kSOSCCCircleChangedNotification, &token,
+                             dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
+                             ^(int token) {
+                                 dispatch_semaphore_signal(notification_signal);
+                             });
+
+    SOSCloudKeychainSetCallbackMethodXPC(); // call this first
+    ClearAndSynchronize();
+
+#ifdef NO_SERVER
+    SOSDataSourceRef our_test_data_source = SetupTestFactory();
+#endif
+    CFErrorRef error = NULL;
+    
+    ok(SOSCCResetToOffering(&error), "Reset: %@ [%@]", SOSKeychainAccountGetSharedAccount(), error);
+    CFReleaseNull(error);
+    
+    PurgeAndReload();
+    
+    CFArrayRef applicants = NULL;
+    do {
+        dispatch_semaphore_wait(notification_signal, DISPATCH_TIME_FOREVER);
+        applicants = SOSCCCopyApplicantPeerInfo(&error);
+        CFReleaseNull(error);
+    } while (CFArrayGetCount(applicants) == 0);
+    pass("Waited long enough");
+    
+    is(CFArrayGetCount(applicants), 1, "Bob should be applying");
+    CFReleaseNull(error);
+
+    ok(SOSCCAcceptApplicants(applicants, &error), "Accepted all applicants: %@", error);
+    CFReleaseNull(error);
+    CFReleaseSafe(applicants);
+    
+    PurgeAndReload();
+
+    sleep(180);
+    pass("Waited long enough again");
+
+#ifdef NO_SERVER
+    CFDictionaryRef data = SOSTestDataSourceGetDatabase(our_test_data_source);
+    is(CFDictionaryGetCount(data), 1, "Should have gotten bob's one");
+#endif
+}
+
+#define kBobTestCount 100
+static void BobTests()
+{
+    plan_tests(kBobTestCount);
+    
+    dispatch_semaphore_t notification_signal = dispatch_semaphore_create(0);
+    int token;
+    notify_register_dispatch(kSOSCCCircleChangedNotification, &token,
+                             dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
+                             ^(int token) {
+                                 dispatch_semaphore_signal(notification_signal);
+                             });
+
+    SOSCloudKeychainSetCallbackMethodXPC(); // call this first
+    WaitForSynchronization();
+    
+#ifdef NO_SERVER
+    SOSDataSourceRef our_test_data_source = SetupTestFactory();
+#endif
+
+    CFErrorRef error = NULL;
+
+#ifdef NO_SERVER
+    SOSObjectRef firstObject = SOSDataSourceCreateGenericItem(our_test_data_source, CFSTR("1234"), CFSTR("service"));
+    SOSTestDataSourceAddObject(our_test_data_source, firstObject, &error);
+#endif
+
+    CFReleaseNull(error);
+
+    is(SOSCCThisDeviceIsInCircle(&error), kSOSCCCircleAbsent, "Shouldn't be a circle: %@", error);
+    CFReleaseNull(error);
+    
+    PurgeAndReload();
+
+    CFArrayRef peers = NULL;
+    do {
+        dispatch_semaphore_wait(notification_signal, DISPATCH_TIME_FOREVER);
+        peers = SOSCCCopyPeerPeerInfo(&error);
+        CFReleaseNull(error);
+    } while (CFArrayGetCount(peers) == 0);
+
+    pass("Peer arrived: %@", SOSKeychainAccountGetSharedAccount());
+
+    is(CFArrayGetCount(peers), 1, "Only Alice should be there");
+    CFReleaseSafe(peers);
+    
+    ok(SOSCCRequestToJoinCircle(&error), "Join circles: %@ [%@]", SOSKeychainAccountGetSharedAccount(), error);
+    CFReleaseNull(error);
+   
+    PurgeAndReload();
+    
+    do {
+        dispatch_semaphore_wait(notification_signal, DISPATCH_TIME_FOREVER);
+
+    } while (SOSCCThisDeviceIsInCircle(&error) != kSOSCCInCircle);
+    pass("Was admitted: %@ [%@]", SOSKeychainAccountGetSharedAccount(), error);
+    CFReleaseNull(error);
+    
+    is(SOSCCThisDeviceIsInCircle(&error), kSOSCCInCircle, "Should be in circle: %@", error);
+    CFReleaseNull(error);
+    
+    PurgeAndReload();
+    
+    // Sync
+    sleep(120);
+    pass("Waited long enough again: %@", SOSKeychainAccountGetSharedAccount());
+    
+#ifdef NO_SERVER
+    CFDictionaryRef data = SOSTestDataSourceGetDatabase(our_test_data_source);
+    is(CFDictionaryGetCount(data), 1, "Only have one");
+#endif
+}
+
+
+static const struct option options[] =
+{
+       { "identity",           optional_argument,      NULL, 'i' },
+       { }
+};
+
+
+int sc_120_cloudcircle(int argc, char *const *argv)
+{
+    char *identity = NULL;
+    extern char *optarg;
+    int arg, argSlot;
+    
+    bool isAlice = false;
+    
+    while (argSlot = -1, (arg = getopt_long(argc, (char * const *)argv, "i:vC", options, &argSlot)) != -1)
+        switch (arg)
+    {
+        case 'i':
+            identity = (char *)(optarg);
+            break;
+        default:
+            fail("arg: %s", optarg);
+            break;
+    }
+    
+    if (identity)
+    {
+        if (!strcmp(identity, "alice"))
+            isAlice = true;
+    }
+
+    if (isAlice)
+        AliceTests();
+    else
+        BobTests();
+
+       return 0;
+    
+}
diff --git a/sec/SOSCircle/Regressions/sc-130-resignationticket.c b/sec/SOSCircle/Regressions/sc-130-resignationticket.c
new file mode 100644 (file)
index 0000000..ec7bf3b
--- /dev/null
@@ -0,0 +1,117 @@
+//
+//  sc-130-resignationticket.c
+//  sec
+//
+//  Created by Richard Murphy on 5/1/13.
+//
+//
+
+#include <Security/SecBase.h>
+#include <Security/SecItem.h>
+#include <Security/SecKey.h>
+
+#include <SecureObjectSync/SOSCircle.h>
+#include <SecureObjectSync/SOSPeerInfo.h>
+#include <SecureObjectSync/SOSInternal.h>
+
+#include <utilities/SecCFWrappers.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "SOSCircle_regressions.h"
+
+#include "SOSRegressionUtilities.h"
+
+typedef struct piStuff_t {
+    SecKeyRef signingKey;
+    SOSFullPeerInfoRef fpi;
+    SOSPeerInfoRef pi;
+    SOSPeerInfoRef resignation_ticket;
+} piStuff;
+
+static piStuff *makeSimplePeer(char *name) {
+    piStuff *pi = malloc(sizeof(piStuff));
+    
+    if(!pi) return NULL;
+    pi->signingKey = NULL;
+    CFStringRef cfName = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingMacRoman);
+    pi->fpi = SOSCreateFullPeerInfoFromName(cfName, &pi->signingKey, NULL);
+    CFReleaseSafe(cfName);
+    pi->pi = SOSFullPeerInfoGetPeerInfo(pi->fpi);
+    pi->resignation_ticket = SOSPeerInfoCreateRetirementTicket(kCFAllocatorDefault, pi->signingKey, pi->pi, NULL);
+    return pi;
+}
+
+static inline bool retire_me(piStuff *pi, size_t seconds) {
+    return SOSPeerInfoRetireRetirementTicket(seconds, pi->resignation_ticket);
+}
+
+// Copied from SOSPeerInfo.c
+static CFStringRef sFlatticket = CFSTR("flatticket");
+static CFStringRef sSignature = CFSTR("RetirementPsig");
+static CFStringRef sPeerid = CFSTR("peerid");
+
+
+static inline bool chkBasicTicket(piStuff *pi) {
+    return CFEqual(SOSPeerInfoInspectRetirementTicket(pi->resignation_ticket, NULL), SOSPeerInfoGetPeerID(pi->pi));
+}
+
+static bool in_between_time(CFDateRef before, piStuff *pi, CFDateRef after) {
+    CFDateRef during = SOSPeerInfoGetRetirementDate(pi->resignation_ticket);
+    CFTimeInterval time1 = CFDateGetTimeIntervalSinceDate(before, during);
+    CFTimeInterval time2 = CFDateGetTimeIntervalSinceDate(during, after);
+    CFReleaseNull(during);
+    if(time1 >= 0.0) return false;
+    if(time2 >= 0.0) return false;
+    return true;
+}
+
+static void tests(void)
+{
+    CFDateRef before_time = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent());
+    sleep(1);
+    piStuff *iPhone = makeSimplePeer("iPhone");
+    piStuff *iPad = makeSimplePeer("iPad");
+    piStuff *iMac = makeSimplePeer("iMac");
+    piStuff *iDrone = makeSimplePeer("iDrone");
+    sleep(1);
+    CFDateRef after_time = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent());
+    
+    ok(in_between_time(before_time, iPhone, after_time), "retirement date recorded correctly");
+    CFReleaseSafe(before_time);
+    CFReleaseSafe(after_time);
+    ok(chkBasicTicket(iPhone), "peer ID's Match");
+    ok(chkBasicTicket(iPad), "peer ID's Match");
+    ok(chkBasicTicket(iMac), "peer ID's Match");
+    ok(chkBasicTicket(iDrone), "peer ID's Match");
+    
+    // ok(miss_signature(iDrone, iPad), "signature failure detected");
+    
+    ok(!retire_me(iPhone, 10000), "ticket still valid");
+    sleep(2);
+    ok(retire_me(iPhone, 1), "ticket not valid");
+    
+    CFDateRef retdate = NULL;
+    ok((retdate = SOSPeerInfoGetRetirementDate(iPhone->resignation_ticket)) != NULL, "got retirement date %@", retdate);
+    CFReleaseSafe(retdate);
+    
+#if 0
+    CFDateRef appdate = NULL;
+    ok((appdate = SOSPeerInfoGetApplicationDate(iPhone->resignation_ticket)) != NULL, "got application date %@", appdate);
+    CFReleaseSafe(appdate);
+#endif
+}
+
+static int kTestTestCount = 20;
+
+int sc_130_resignationticket(int argc, char *const *argv)
+{
+    plan_tests(kTestTestCount);
+    
+    tests();
+    
+       return 0;
+}
diff --git a/sec/SOSCircle/Regressions/sc-20-keynames.c b/sec/SOSCircle/Regressions/sc-20-keynames.c
new file mode 100644 (file)
index 0000000..1c3f781
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ *  sc-20-keynames.c
+ *
+ *  Created by Mitch Adler on 1/25/121.
+ *  Copyright 2012 Apple Inc. All rights reserved.
+ *
+ */
+
+
+#include <Security/SecBase.h>
+#include <Security/SecItem.h>
+#include <Security/SecKey.h>
+
+#include <SecureObjectSync/SOSAccount.h>
+#include <SecureObjectSync/SOSCircle.h>
+#include <SecureObjectSync/SOSPeerInfo.h>
+#include <SecureObjectSync/SOSInternal.h>
+
+#include <utilities/SecCFWrappers.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "SOSCircle_regressions.h"
+
+#include "SOSRegressionUtilities.h"
+
+
+static int kTestTestCount = 15;
+static void tests(void)
+{
+    SecKeyRef publicKey = NULL;
+    SecKeyRef signingKey = NULL;
+    GenerateECPair(256, &publicKey, &signingKey);
+   
+    CFErrorRef error = NULL;
+    SOSCircleRef circle = SOSCircleCreate(NULL, CFSTR("Test Circle"), &error);
+    
+    CFStringRef circle_key = SOSCircleKeyCreateWithCircle(circle, NULL);
+
+    CFStringRef circle_name = NULL;
+    ok(circle_key, "Circle key created");
+    is(SOSKVSKeyGetKeyType(circle_key), kCircleKey, "Is circle key");
+    is(SOSKVSKeyGetKeyTypeAndParse(circle_key, &circle_name, NULL, NULL), kCircleKey, "Is circle key, extract name");
+    ok(circle_name, "Circle name extracted");
+    ok(CFEqualSafe(circle_name, SOSCircleGetName(circle)), "Circle name matches '%@' '%@'", circle_name, SOSCircleGetName(circle));
+    
+    CFReleaseSafe(circle_key);
+    
+    SOSPeerInfoRef pi = SOSCreatePeerInfoFromName(CFSTR("Test Peer"), &publicKey, &error);
+    
+    CFStringRef other_peer_id = CFSTR("OTHER PEER");
+    
+    CFStringRef messageKey = SOSMessageKeyCreateWithCircleAndPeerNames(circle, SOSPeerInfoGetPeerID(pi), other_peer_id);
+    
+    ok(messageKey, "Getting message key '%@'", messageKey);
+    
+    CFStringRef message_circle_name = NULL;
+    CFStringRef message_from_peer_id = NULL;
+    CFStringRef message_to_peer_id = NULL;
+
+    is(SOSKVSKeyGetKeyType(messageKey), kMessageKey, "Is message key");
+    is(SOSKVSKeyGetKeyTypeAndParse(messageKey,
+                                   &message_circle_name,
+                                   &message_from_peer_id,
+                                   &message_to_peer_id), kMessageKey, "Is message key, extract parts");
+    
+    
+    ok(CFEqualSafe(SOSCircleGetName(circle), message_circle_name), "circle key matches in message (%@ v %@)",SOSCircleGetName(circle), message_circle_name);
+
+    
+    ok(CFEqualSafe(SOSPeerInfoGetPeerID(pi), message_from_peer_id), "from peer set correctly (%@ v %@)", SOSPeerInfoGetPeerID(pi), message_from_peer_id);
+    
+    ok(CFEqualSafe(other_peer_id, message_to_peer_id), "to peer set correctly (%@ v %@)", other_peer_id, message_to_peer_id);
+    
+    CFStringRef retirementKey = SOSRetirementKeyCreateWithCircleAndPeer(circle, SOSPeerInfoGetPeerID(pi));
+    CFStringRef retirement_circle_name = NULL;
+    CFStringRef retirement_peer_id = NULL;
+    
+    is(SOSKVSKeyGetKeyType(retirementKey), kRetirementKey, "Is retirement key");
+    is(SOSKVSKeyGetKeyTypeAndParse(retirementKey,
+                                   &retirement_circle_name,
+                                   &retirement_peer_id,
+                                   NULL), kRetirementKey, "Is retirement key, extract parts");
+    CFReleaseSafe(retirementKey);
+    ok(CFEqualSafe(SOSCircleGetName(circle), retirement_circle_name), "circle key matches in retirement (%@ v %@)",
+       SOSCircleGetName(circle), retirement_circle_name);
+    ok(CFEqualSafe(SOSPeerInfoGetPeerID(pi), retirement_peer_id), "retirement peer set correctly (%@ v %@)",
+       SOSPeerInfoGetPeerID(pi), retirement_peer_id);
+    
+    CFReleaseNull(publicKey);
+    CFReleaseNull(signingKey);
+    CFReleaseNull(circle);
+    CFReleaseNull(error);
+    CFReleaseNull(pi);
+    CFReleaseNull(messageKey);
+    CFReleaseNull(message_circle_name);
+    CFReleaseNull(message_from_peer_id);
+    CFReleaseNull(message_to_peer_id);
+}
+
+int sc_20_keynames(int argc, char *const *argv)
+{
+    plan_tests(kTestTestCount);
+       
+    tests();
+
+       return 0;
+}
diff --git a/sec/SOSCircle/Regressions/sc-30-peerinfo.c b/sec/SOSCircle/Regressions/sc-30-peerinfo.c
new file mode 100644 (file)
index 0000000..380d62c
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ *  sc-30-peerinfo.c
+ *
+ *  Created by Mitch Adler on 1/25/121.
+ *  Copyright 2012 Apple Inc. All rights reserved.
+ *
+ */
+
+
+#include <Security/SecBase.h>
+#include <Security/SecItem.h>
+#include <Security/SecKey.h>
+#include <Security/SecKeyPriv.h>
+
+#include <SecureObjectSync/SOSCircle.h>
+#include <SecureObjectSync/SOSPeerInfo.h>
+#include <SecureObjectSync/SOSInternal.h>
+#include <SecureObjectSync/SOSUserKeygen.h>
+
+#include <utilities/SecCFWrappers.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "SOSCircle_regressions.h"
+
+#include "SOSRegressionUtilities.h"
+
+#if TARGET_OS_IPHONE
+#include <MobileGestalt.h>
+#endif
+
+static int kTestTestCount = 11;
+static void tests(void)
+{
+    SecKeyRef signingKey = NULL;
+    SOSFullPeerInfoRef fpi = SOSCreateFullPeerInfoFromName(CFSTR("Test Peer"), &signingKey, NULL);
+    SOSPeerInfoRef pi = SOSFullPeerInfoGetPeerInfo(fpi);
+    CFRetainSafe(pi);
+    
+    ok(NULL != pi, "info creation");
+    
+    uint8_t buffer[4096];
+    
+    const uint8_t *buffer_p = SOSPeerInfoEncodeToDER(pi, NULL, buffer, buffer + sizeof(buffer));
+    
+    ok(buffer_p != NULL, "encode");
+    
+    SOSPeerInfoRef pi2 = SOSPeerInfoCreateFromDER(NULL, NULL, &buffer_p, buffer + sizeof(buffer));
+    
+    SKIP:
+    {
+        skip("Decode failed", 1, ok(NULL != pi2, "Decode"));
+        ok(CFEqual(pi, pi2), "Decode matches");
+    }
+    
+    buffer_p = SOSFullPeerInfoEncodeToDER(fpi, NULL, buffer, buffer + sizeof(buffer));
+
+    ok(buffer_p != NULL, "Full peer encode");
+
+    SOSFullPeerInfoRef  fpi2 = SOSFullPeerInfoCreateFromDER(kCFAllocatorDefault, NULL, &buffer_p, buffer + sizeof(buffer));
+
+    SKIP:
+    {
+        skip("Full Peer Decode failed", 1, ok(fpi2, "Full peer inflated"));
+
+        ok(CFEqual(fpi, fpi2), "Full peer inflate matches");
+    }
+
+
+// Application ticket time.
+    CFDataRef cfpassword = CFDataCreate(NULL, (uint8_t *) "FooFooFoo", 10);
+    CFErrorRef error = NULL;
+
+    CFDataRef parameters = SOSUserKeyCreateGenerateParameters(&error);
+    ok(parameters, "No parameters!");
+    ok(error == NULL, "Error: (%@)", error);
+    CFReleaseNull(error);
+
+    SecKeyRef user_privkey = SOSUserKeygen(cfpassword, parameters, &error);
+    CFReleaseSafe(cfpassword);
+    CFReleaseNull(parameters);
+    SecKeyRef user_pubkey = SecKeyCreatePublicFromPrivate(user_privkey);
+
+    ok(SOSFullPeerInfoPromoteToApplication(fpi, user_privkey, &error), "Promote to Application");
+    ok(SOSPeerInfoApplicationVerify(SOSFullPeerInfoGetPeerInfo(fpi), user_pubkey, &error), "Promote to Application");
+
+
+    CFReleaseNull(user_privkey);
+    CFReleaseNull(user_pubkey);
+
+    CFReleaseNull(signingKey);
+    CFReleaseNull(pi);
+    CFReleaseNull(pi2);
+    CFReleaseNull(fpi);
+    CFReleaseNull(fpi2);
+}
+
+int sc_30_peerinfo(int argc, char *const *argv)
+{
+    plan_tests(kTestTestCount);
+       
+    tests();
+
+       return 0;
+}
diff --git a/sec/SOSCircle/Regressions/sc-40-circle.c b/sec/SOSCircle/Regressions/sc-40-circle.c
new file mode 100644 (file)
index 0000000..6a33b23
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ *  sc-01-create.c
+ *
+ *  Created by Mitch Adler on 1/25/121.
+ *  Copyright 2012 Apple Inc. All rights reserved.
+ *
+ */
+
+
+#include <Security/SecBase.h>
+#include <Security/SecItem.h>
+#include <Security/SecKey.h>
+
+#include <SecureObjectSync/SOSCircle.h>
+#include <SecureObjectSync/SOSCloudCircle.h>
+#include <SecureObjectSync/SOSPeerInfo.h>
+#include <SecureObjectSync/SOSInternal.h>
+#include <SecureObjectSync/SOSUserKeygen.h>
+
+#include <utilities/SecCFWrappers.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <securityd/SOSCloudCircleServer.h>
+
+#include "SOSCircle_regressions.h"
+
+#include "SOSRegressionUtilities.h"
+
+static int kTestTestCount = 17;
+static void tests(void)
+{
+    SOSCircleRef circle = SOSCircleCreate(NULL, CFSTR("TEST DOMAIN"), NULL);
+    
+    ok(NULL != circle, "Circle creation");
+
+    ok(0 == SOSCircleCountPeers(circle), "Zero peers");
+
+    //SecKeyRef publicKey = NULL;
+    SecKeyRef dev_a_key = NULL;
+    SecKeyRef dev_b_key = NULL;
+    CFErrorRef error = NULL;
+    CFDataRef cfpassword = CFDataCreate(NULL, (uint8_t *) "FooFooFoo", 10);
+    
+    if(cfpassword == NULL) printf("WTF\n");
+    
+    CFDataRef parameters = SOSUserKeyCreateGenerateParameters(&error);
+    ok(parameters, "No parameters!");
+    ok(error == NULL, "Error: (%@)", error);
+    CFReleaseNull(error);
+
+    SecKeyRef user_privkey = SOSUserKeygen(cfpassword, parameters, &error);
+    CFReleaseNull(parameters);
+
+    SOSFullPeerInfoRef peer_a_full_info = SOSCreateFullPeerInfoFromName(CFSTR("Peer A"), &dev_a_key, NULL);
+    
+    SOSFullPeerInfoRef peer_b_full_info = SOSCreateFullPeerInfoFromName(CFSTR("Peer B"), &dev_b_key, NULL);
+    
+    ok(SOSCircleRequestAdmission(circle, user_privkey, peer_a_full_info, NULL));
+    ok(SOSCircleRequestAdmission(circle, user_privkey, peer_a_full_info, NULL));
+    ok(SOSCircleRequestAdmission(circle, user_privkey, peer_a_full_info, NULL));
+
+    ok(SOSCircleAcceptRequest(circle, user_privkey, peer_a_full_info, SOSFullPeerInfoGetPeerInfo(peer_a_full_info), NULL));
+    
+    ok(!SOSCircleRequestAdmission(circle, user_privkey, peer_a_full_info, NULL));
+    ok(SOSCircleRequestAdmission(circle, user_privkey, peer_b_full_info, NULL));
+    
+    ok(SOSCircleCountPeers(circle) == 1, "Peer count");
+
+    size_t size = SOSCircleGetDEREncodedSize(circle, &error);
+    uint8_t buffer[size];
+    uint8_t* start = SOSCircleEncodeToDER(circle, &error, buffer, buffer + sizeof(buffer));
+    
+    ok(start, "successful encoding");
+    ok(start == buffer, "Used whole buffer");
+    
+    const uint8_t *der = buffer;
+    SOSCircleRef inflated = SOSCircleCreateFromDER(NULL, &error, &der, buffer + sizeof(buffer));
+    
+    ok(inflated, "inflated");
+    ok(CFEqualSafe(inflated, circle), "Compares");
+    
+    
+    ok(SOSCircleRemovePeer(circle, user_privkey, peer_a_full_info, SOSFullPeerInfoGetPeerInfo(peer_a_full_info), NULL));
+    ok(SOSCircleCountPeers(circle) == 0, "Peer count");
+    
+    CFReleaseNull(dev_a_key);
+    CFReleaseNull(cfpassword);
+}
+
+int sc_40_circle(int argc, char *const *argv)
+{
+    plan_tests(kTestTestCount);
+       
+    tests();
+
+       return 0;
+}
diff --git a/sec/SOSCircle/Regressions/sc-41-cloudcircle.c b/sec/SOSCircle/Regressions/sc-41-cloudcircle.c
new file mode 100644 (file)
index 0000000..1a5d5df
--- /dev/null
@@ -0,0 +1,48 @@
+//
+//  sc-41-cloudcircle.c
+//  sec
+//
+//  Created by Mitch Adler on 12/13/12.
+//
+//
+
+#include "SOSCircle_regressions.h"
+
+#include "SOSRegressionUtilities.h"
+
+#include <SecureObjectSync/SOSCloudCircle.h>
+#include <utilities/SecCFWrappers.h>
+
+static const int kSOSCCTestCount = 6;   // # of "ok"s in "tests" below
+static int kTestTestCount = kSOSCCTestCount;
+static void tests(void)
+{
+    CFErrorRef error = NULL;
+    CFDataRef cfpassword = CFDataCreate(NULL, (uint8_t *) "FooFooFoo", 10);
+
+    ok(SOSCCSetUserCredentials(CFSTR("foo1"), cfpassword, &error), "Added Creds (%@)", error);
+    CFReleaseNull(error);
+    CFReleaseNull(cfpassword);
+    
+    ok(SOSCCThisDeviceIsInCircle(&error) == kSOSCCCircleAbsent, "Circle Absent (%@)", error);
+    CFReleaseNull(error);
+    ok(SOSCCResetToOffering(&error), "SOSCCOfferPotentialCircle (%@)", error);
+    CFReleaseNull(error);
+    
+    ok(SOSCCThisDeviceIsInCircle(&error) == kSOSCCInCircle, "Circle Absent (%@)", error);
+    CFReleaseNull(error);
+    ok(SOSCCRemoveThisDeviceFromCircle(&error), "Leaving (%@)", error);
+    CFReleaseNull(error);
+    
+    ok(SOSCCThisDeviceIsInCircle(&error) == kSOSCCCircleAbsent, "Circle Absent (%@)", error);
+    CFReleaseNull(error);
+}
+
+int sc_41_cloudcircle(int argc, char *const *argv)
+{
+    plan_tests(kTestTestCount);
+       
+    tests();
+    
+       return 0;
+}
diff --git a/sec/SOSCircle/Regressions/sc-51-persistentEC.c b/sec/SOSCircle/Regressions/sc-51-persistentEC.c
new file mode 100644 (file)
index 0000000..bfb2e4f
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ *  sc-51-persistentEC.c
+ *  Security
+ *
+ *  Copyright (c) 2008-2010 Apple Inc. All Rights Reserved.
+ *
+ */
+
+/*
+    Test code for SOSCircle keys
+*/
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecBase.h>
+#include <Security/SecItem.h>
+#include <Security/SecKey.h>
+#if TARGET_OS_EMBEDDED
+#include <Security/SecInternal.h>
+#endif
+#include <Security/SecItemPriv.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <utilities/SecCFWrappers.h>
+#include <utilities/iOSforOSX.h>
+
+#include "SOSCircle_regressions.h"
+
+static SecKeyRef GeneratePermanentFullECKey(int keySize, CFStringRef name)
+{    
+    SecKeyRef public_key = NULL;
+    SecKeyRef full_key = NULL;
+    
+    CFNumberRef key_size_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &keySize);
+    
+    CFDictionaryRef keygen_parameters = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
+        kSecAttrKeyType,        kSecAttrKeyTypeEC,
+        kSecAttrKeySizeInBits,  key_size_num,
+        kSecAttrIsPermanent,    kCFBooleanTrue,
+        kSecAttrAccessible,     kSecAttrAccessibleAlwaysThisDeviceOnly,
+        kSecAttrLabel,          name,
+        NULL);
+    
+    CFReleaseNull(key_size_num);
+    ok_status(SecKeyGeneratePair(keygen_parameters, &public_key, &full_key), "generate EC Key Pair");
+    CFReleaseNull(keygen_parameters);
+    CFReleaseNull(public_key);
+    
+    return full_key;
+}
+
+static void tests(void)
+{
+    CFStringRef ourAccountName = CFSTR("LjzZ2JteIrnHoHWf5hYb1WGqjI");
+    CFStringRef circleName = CFSTR("ak");
+    CFStringRef keyName = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("ID for %@-%@"), ourAccountName, circleName);
+    const int keySize = 256;
+    
+    // Create it
+    SecKeyRef full_key = GeneratePermanentFullECKey(keySize, keyName);
+    ok(full_key, "EC Key generated");
+    
+    // Now search for it
+    CFNumberRef key_size_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &keySize);
+
+    CFDictionaryRef keysearch_parameters = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
+        kSecClass,              kSecClassKey,
+        kSecReturnRef,          kCFBooleanTrue,
+        kSecAttrKeySizeInBits,  key_size_num,
+        kSecAttrLabel,          keyName,
+        NULL);
+
+    CFReleaseNull(key_size_num);
+    CFReleaseNull(keyName);
+
+    CFTypeRef results = NULL;
+    ok_status(SecItemCopyMatching(keysearch_parameters, &results), "find EC key by attr");
+    ok(results && (CFGetTypeID(results) == SecKeyGetTypeID()), "Got a SecKeyRef");
+    CFReleaseNull(results);
+
+    ok_status(SecItemDelete(keysearch_parameters), "delete EC Key Pair");
+
+    CFRelease(keysearch_parameters);
+}
+
+int sc_51_persistentEC(int argc, char *const *argv)
+{
+    plan_tests(5);
+    tests();
+
+    return 0;
+}
diff --git a/sec/SOSCircle/Regressions/sc-60-peer.c b/sec/SOSCircle/Regressions/sc-60-peer.c
new file mode 100644 (file)
index 0000000..5adcb78
--- /dev/null
@@ -0,0 +1,147 @@
+//
+//  sc-60-peer.c
+//  sec
+//
+//  Created by Michael Brouwer on 8/2/12.
+//  Copyright 2012 Apple Inc. All rights reserved.
+//
+
+#include <SecureObjectSync/SOSPeer.h>
+
+#include "SOSCircle_regressions.h"
+
+#include <corecrypto/ccsha2.h>
+
+#include <Security/SecBase64.h>
+
+#include <utilities/SecCFWrappers.h>
+
+#include <stdint.h>
+
+static int kTestTestCount = 13;
+
+struct SOSTestTransport {
+    struct SOSTransport t;
+    unsigned t_msg_count;
+    uint8_t digest[CCSHA256_OUTPUT_SIZE];
+};
+
+
+static void tests(void)
+{
+    const unsigned kSOSPeerVersion = 0;
+
+    CFErrorRef error = NULL;
+    SOSPeerRef peer;
+
+    /* Create peer test. */
+    CFStringRef peer_id = CFSTR("peer 60");
+    
+    __block unsigned msg_count = 0;
+    uint8_t msg_digest_buffer[CCSHA256_OUTPUT_SIZE];
+    uint8_t *msg_digest = msg_digest_buffer;
+    
+    SOSPeerSendBlock sendBlock = ^bool (CFDataRef message, CFErrorRef *error) {
+        size_t msglen = CFDataGetLength(message);
+        const uint8_t *msg = CFDataGetBytePtr(message);
+        const struct ccdigest_info *sha256 = ccsha256_di();
+        if (msg_count++ == 0) {
+            /* message n=0 */
+            ccdigest(sha256, msglen, msg, msg_digest);
+        } else {
+            /* message n=n+1 */
+            ccdigest_di_decl(sha256, sha256_ctx);
+            ccdigest_init(sha256, sha256_ctx);
+            ccdigest_update(sha256, sha256_ctx, sizeof(msg_digest_buffer), msg_digest);
+            ccdigest_update(sha256, sha256_ctx, msglen, msg);
+            ccdigest_final(sha256, sha256_ctx, msg_digest);
+        }
+        size_t encmaxlen = SecBase64Encode(msg, msglen, NULL, 0);
+        CFMutableDataRef encoded = CFDataCreateMutable(NULL, encmaxlen);
+        CFDataSetLength(encoded, encmaxlen);
+        SecBase64Result rc;
+        char *enc = (char *)CFDataGetMutableBytePtr(encoded);
+#ifndef NDEBUG
+        size_t enclen =
+#endif
+            SecBase64Encode2(msg, msglen,
+                             enc,
+                             encmaxlen, kSecB64_F_LINE_LEN_USE_PARAM,
+                             64, &rc);
+        assert(enclen < INT32_MAX);
+        
+//      printf("=== BEGIN SOSMESSAGE ===\n%.*s\n=== END SOSMESSAGE ===\n", (int)enclen, enc);
+        
+        CFRelease(encoded);
+        return true;
+    };
+    
+    
+    ok(peer = SOSPeerCreateSimple(peer_id, kSOSPeerVersion, &error, sendBlock),
+       "create peer: %@", error);
+    CFReleaseNull(error);
+
+    /* Send a test message. */
+    is((int)msg_count, 0, "no message sent yet");
+    size_t msglen = 10;
+    uint8_t msg[msglen];
+    memcpy(msg, "0123456789", msglen);
+    CFDataRef message = CFDataCreate(NULL, msg, msglen);
+    ok(SOSPeerSendMessage(peer, message, &error),
+       "send message to peer: %@", error);
+    CFReleaseNull(error);
+    is((int)msg_count, 1, "We sent %d/1 messages", msg_count);
+    CFRelease(message);
+
+    /* Check the peer's version. */
+    is(SOSPeerGetVersion(peer), kSOSPeerVersion, "version is correct");
+
+    /* Get the peer's manifest. */
+    SOSManifestRef manifest = SOSPeerCopyManifest(peer, &error);
+    ok(manifest == NULL, "No manifest yet for this peer: %@", error);
+    CFReleaseNull(error);
+    CFReleaseNull(manifest);
+
+    /* Get the peer's manifest digest. */
+    CFDataRef digest = SOSPeerCopyManifestDigest(peer, &error);
+    ok(digest == NULL, "No digest yet for this peer's manifest: %@", error);
+    CFReleaseNull(error);
+    CFReleaseNull(digest);
+
+    ok(manifest = SOSManifestCreateWithBytes(NULL, 0, &error), "Create empty manifest: %@", error);
+    CFReleaseNull(error);
+    ok(SOSPeerSetManifest(peer, manifest, &error), "Set empty manifest on peer: %@", error);
+    CFReleaseNull(error);
+
+    /* Get the peer's empty manifest digest. */
+    digest = SOSPeerCopyManifestDigest(peer, &error);
+    ok(digest, "Got a digest: %@ this peer's manifest: %@", digest, error);
+    CFReleaseNull(error);
+
+    /* Clean up. */
+    SOSPeerDispose(peer);
+
+    SOSPeerRef reinflated_peer = NULL;
+    ok(reinflated_peer = SOSPeerCreateSimple(peer_id, kSOSPeerVersion, &error, sendBlock),
+       "create peer: %@", error);
+    CFReleaseNull(error);
+
+    CFDataRef digestAfterReinflate = SOSPeerCopyManifestDigest(reinflated_peer, &error);
+    ok(digest != NULL, "Got NULL after reinflate (%@)", error);
+    ok(CFEqual(digest, digestAfterReinflate), "Compare digest after reinflate, before: %@ after: %@", digest, digestAfterReinflate);
+    CFReleaseNull(error);
+
+    SOSPeerDispose(reinflated_peer);
+
+    CFReleaseNull(digestAfterReinflate);
+    CFReleaseNull(digest);
+}
+
+int sc_60_peer(int argc, char *const *argv)
+{
+    plan_tests(kTestTestCount);
+
+    tests();
+
+       return 0;
+}
diff --git a/sec/SOSCircle/Regressions/sc-70-engine.c b/sec/SOSCircle/Regressions/sc-70-engine.c
new file mode 100644 (file)
index 0000000..b845e75
--- /dev/null
@@ -0,0 +1,368 @@
+//
+//  sc-70-engine.c
+//  sec
+//
+//  Created by Michael Brouwer on 8/2/12.
+//  Copyright 2012 Apple Inc. All rights reserved.
+//
+//
+
+#include <SecureObjectSync/SOSEngine.h>
+#include <SecureObjectSync/SOSPeer.h>
+
+#include "SOSCircle_regressions.h"
+
+#include <corecrypto/ccsha2.h>
+#include <Security/SecBase64.h>
+
+#include <utilities/SecCFWrappers.h>
+
+#include <stdint.h>
+#include "SOSTestDataSource.h"
+#include "SOSTestTransport.h"
+
+static int kTestTestCount = 61;
+
+static void tests(void)
+{
+    CFErrorRef error = NULL;
+
+    /* Transport. */
+    __block unsigned msg_count = 0;
+    uint8_t msg_digest_buffer[CCSHA256_OUTPUT_SIZE];
+    uint8_t *msg_digest = msg_digest_buffer;
+    
+    SOSPeerSendBlock sendBlock = ^bool (CFDataRef message, CFErrorRef *error) {
+        size_t msglen = CFDataGetLength(message);
+        const uint8_t *msg = CFDataGetBytePtr(message);
+        const struct ccdigest_info *sha256 = ccsha256_di();
+        if (msg_count++ == 0) {
+            /* message n=0 */
+            ccdigest(sha256, msglen, msg, msg_digest);
+        } else {
+            /* message n=n+1 */
+            ccdigest_di_decl(sha256, sha256_ctx);
+            ccdigest_init(sha256, sha256_ctx);
+            ccdigest_update(sha256, sha256_ctx, sizeof(msg_digest_buffer), msg_digest);
+            ccdigest_update(sha256, sha256_ctx, msglen, msg);
+            ccdigest_final(sha256, sha256_ctx, msg_digest);
+        }
+        size_t encmaxlen = SecBase64Encode(msg, msglen, NULL, 0);
+        CFMutableDataRef encoded = CFDataCreateMutable(NULL, encmaxlen);
+        CFDataSetLength(encoded, encmaxlen);
+        SecBase64Result rc;
+        char *enc = (char *)CFDataGetMutableBytePtr(encoded);
+#ifndef NDEBUG
+        size_t enclen =
+#endif
+            SecBase64Encode2(msg, msglen,
+                             enc,
+                             encmaxlen, kSecB64_F_LINE_LEN_USE_PARAM,
+                             64, &rc);
+        assert(enclen < INT32_MAX);
+//      printf("=== BEGIN SOSMESSAGE ===\n%.*s\n=== END SOSMESSAGE ===\n", (int)enclen, enc);
+        CFRelease(encoded);
+        return true;
+    };
+
+    /* Create peer test. */
+    CFStringRef peer_id = CFSTR("peer 70");
+    SOSPeerRef peer;
+    ok(peer = SOSPeerCreateSimple(peer_id, kSOSPeerVersion, &error, sendBlock),
+       "create peer: %@", error);
+    CFReleaseNull(error);
+
+    /* DataSource */
+    SOSDataSourceRef ds = SOSTestDataSourceCreate();
+
+    /* Create engine test. */
+    SOSEngineRef engine;
+    ok(engine = SOSEngineCreate(ds, &error), "create engine: %@", error);
+    CFReleaseNull(error);
+
+    /* Make sure the engine did not yet send a any messages to the peer. */
+    unsigned expected_msg_count = 0;
+    is(msg_count, expected_msg_count, "Engine sent %d/%d messages",
+       msg_count, expected_msg_count);
+
+    /* Test passing peer messages to the engine. */
+    CFDataRef message;
+
+    /* Hand an empty message to the engine for handeling. */
+    message = CFDataCreate(NULL, NULL, 0);
+    ok(false == SOSEngineHandleMessage(engine, peer, message, &error),
+       "handle empty message: %@", error);
+    CFReleaseNull(error);
+    CFReleaseNull(message);
+    /* Make sure the engine did not yet send a response to the peer. */
+    is(msg_count, expected_msg_count, "Engine sent %d/%d messages",
+       msg_count, expected_msg_count);
+
+
+    /* Create manifest digest message. */
+    SKIP: {
+        skip("Create manifest digest message failed", 2,
+             ok(message = SOSEngineCreateManifestDigestMessage(engine, peer,
+                                                               &error),
+                "create manifest digest message: %@", error));
+        CFReleaseNull(error);
+        /* Pass manifest digest message to the engine for handeling. */
+        skip("", 1,
+             ok(SOSEngineHandleMessage(engine, peer, message, &error),
+                "handle manifest digest message: %@", error));
+        /* Make sure the engine sent a response to the peer. */
+        expected_msg_count++;
+        is(msg_count, expected_msg_count, "Engine sent %d/%d messages",
+           msg_count, expected_msg_count);
+    }
+    CFReleaseNull(message);
+    CFReleaseNull(error);
+
+    /* Create manifest message. */
+    SKIP: {
+        skip("Create manifest message failed", 2,
+             ok(message = SOSEngineCreateManifestMessage(engine, peer, &error),
+             "create manifest message: %@", error));
+        CFReleaseNull(error);
+        /* Pass manifest message to the engine for handeling. */
+        skip("", 1,
+             ok(SOSEngineHandleMessage(engine, peer, message, &error),
+                "handle manifest message: %@", error));
+        /* Make sure the engine sent a response to the peer. */
+        expected_msg_count++;
+        is(msg_count, expected_msg_count, "Engine sent %d/%d messages",
+           msg_count, expected_msg_count);
+    }
+    CFReleaseNull(message);
+    CFReleaseNull(error);
+
+    /* Create manifest and objects message. */
+    SKIP: {
+        skip("Create manifest and objects message failed", 2,
+             ok(message = SOSEngineCreateManifestAndObjectsMessage(engine, peer,
+                                                                   &error),
+                "create manifest and objects message: %@", error));
+        CFReleaseNull(error);
+        /* Pass manifest and objects message to the engine for handeling. */
+        skip("", 1,
+             ok(SOSEngineHandleMessage(engine, peer, message, &error),
+                "handle manifest and objects message: %@", error));
+        /* Make sure the engine sent a response to the peer. */
+        expected_msg_count++;
+        is(msg_count, expected_msg_count, "Engine sent %d/%d messages",
+           msg_count, expected_msg_count);
+    }
+    CFReleaseNull(message);
+    CFReleaseNull(error);
+
+    /* Clean up. */
+    SOSPeerDispose(peer);
+    SOSEngineDispose(engine);
+}
+
+static CFStringRef SOSMessageCopyDigestHex(CFDataRef message) {
+    uint8_t digest[CCSHA1_OUTPUT_SIZE];
+    ccdigest(ccsha1_di(), CFDataGetLength(message), CFDataGetBytePtr(message), digest);
+    CFMutableStringRef hex = CFStringCreateMutable(0, 2 * sizeof(digest));
+    for (unsigned int ix = 0; ix < sizeof(digest); ++ix) {
+        CFStringAppendFormat(hex, 0, CFSTR("%02X"), digest[ix]);
+    }
+    return hex;
+}
+
+static void testsync(const char *name, void (^aliceInit)(SOSDataSourceRef ds), void (^bobInit)(SOSDataSourceRef ds), CFStringRef msg, ...) {
+    CFErrorRef error = NULL;
+
+    /* Setup Alice engine, dataSource and peer for Alice to talk to Bob */
+    SOSDataSourceRef aliceDataSource = SOSTestDataSourceCreate();
+    SOSEngineRef aliceEngine;
+    ok(aliceEngine = SOSEngineCreate(aliceDataSource, &error), "create alice engine: %@", error);
+    CFReleaseNull(error);
+    CFStringRef bobID = CFStringCreateWithFormat(kCFAllocatorDefault, 0, CFSTR("Bob-%s"), name);
+    
+    __block CFDataRef queued_message = NULL;
+    
+    SOSPeerSendBlock enqueueMessage =  ^bool (CFDataRef message, CFErrorRef *error) {
+        if (queued_message)
+            fail("We already had an unproccessed message");
+        
+        queued_message = (CFDataRef) CFRetain(message);
+        return true;
+    };
+
+    CFDataRef (^dequeueMessage)() = ^CFDataRef () {        
+        CFDataRef result = queued_message;
+        queued_message = NULL;
+        
+        return result;
+    };
+    
+    SOSPeerRef bobPeer;
+    ok(bobPeer = SOSPeerCreateSimple(bobID, kSOSPeerVersion, &error, enqueueMessage),
+       "create peer: %@", error);
+
+    /* Setup Bob engine, dataSource and peer for Bob to talk to Alice */
+    SOSDataSourceRef bobDataSource = SOSTestDataSourceCreate();
+    SOSEngineRef bobEngine;
+    ok(bobEngine = SOSEngineCreate(bobDataSource, &error), "create bob engine: %@", error);
+    CFReleaseNull(error);
+    CFStringRef aliceID = CFStringCreateWithFormat(kCFAllocatorDefault, 0, CFSTR("Alice-%s"), name);
+
+    SOSPeerRef alicePeer;
+    ok(alicePeer = SOSPeerCreateSimple(aliceID, kSOSPeerVersion, &error, enqueueMessage),
+       "create peer: %@", error);
+    CFReleaseNull(error);
+
+    /* Now call provided setup blocks to populate the dataSources with
+       interesting stuff. */
+    aliceInit(aliceDataSource);
+    bobInit(bobDataSource);
+
+    /* Start syncing by making alice send the first message. */
+    ok(SOSEngineSyncWithPeer(aliceEngine, bobPeer, false, &error), "tell Alice sync with peer Bob");
+    CFDataRef message;
+
+       va_list msgs;
+       va_start(msgs, msg);
+
+    int msg_index = 0;
+    bool alice = false;
+    for (;;) {
+        message = dequeueMessage();
+        msg_index++;
+        /* We are expecting a message and msg is it's digest. */
+        if (message) {
+            CFStringRef messageDesc = SOSMessageCopyDescription(message);
+            CFStringRef messageDigestStr = SOSMessageCopyDigestHex(message);
+            if (msg) {
+                bool handeled = SOSEngineHandleMessage(alice ? aliceEngine : bobEngine, alice ? bobPeer : alicePeer, message, &error);
+                if (!CFEqual(messageDigestStr, msg)) {
+                    if (handeled) {
+                        fail("%s %s received message [%d] digest %@ != %@ %@", name, alice ? "Alice" : "Bob", msg_index, messageDigestStr, msg, messageDesc);
+                    } else {
+                        fail("%s %s failed to handle message [%d] digest %@ != %@ %@: %@", name, alice ? "Alice" : "Bob", msg_index, messageDigestStr, msg, messageDesc, error);
+                        CFReleaseNull(error);
+                    }
+                } else if (handeled) {
+                    pass("%s %s handled message [%d] %@", name, alice ? "Alice" : "Bob", msg_index, messageDesc);
+                } else {
+                    fail("%s %s failed to handle message [%d] %@: %@", name, alice ? "Alice" : "Bob", msg_index, messageDesc, error);
+                    CFReleaseNull(error);
+                }
+            } else {
+                fail("%s %s sent extra message [%d] with digest %@: %@", name, alice ? "Bob" : "Alice", msg_index, messageDigestStr, messageDesc);
+            }
+            CFRelease(messageDigestStr);
+            CFRelease(messageDesc);
+            CFRelease(message);
+        } else {
+            if (msg) {
+                fail("%s %s expected message [%d] with digest %@, none received", name, alice ? "Alice" : "Bob", msg_index, msg);
+            } else {
+                /* Compare alice and bobs dataSources databases. */
+                ok(CFEqual(SOSTestDataSourceGetDatabase(aliceDataSource), SOSTestDataSourceGetDatabase(bobDataSource)), "%s Alice and Bob are in sync", name);
+            }
+        }
+
+        if (msg) {
+            alice = !alice;
+            msg = va_arg(msgs, CFStringRef);
+        } else
+            break;
+    }
+
+       va_end(msgs);
+
+    SOSEngineDispose(aliceEngine); // Also disposes aliceDataSource
+    SOSPeerDispose(alicePeer);
+    CFReleaseSafe(aliceID);
+
+    SOSEngineDispose(bobEngine); // Also disposes bobDataSource
+    SOSPeerDispose(bobPeer);
+    CFReleaseSafe(bobID);
+}
+
+static void synctests(void) {
+    // Sync between 2 empty dataSources
+    testsync("empty",
+             ^ (SOSDataSourceRef dataSource) {},
+             ^ (SOSDataSourceRef dataSource) {},
+             CFSTR("2AF312E092D67308A0083DFFBF2B6B754B967864"),
+             CFSTR("2AF312E092D67308A0083DFFBF2B6B754B967864"),
+             CFSTR("2AF312E092D67308A0083DFFBF2B6B754B967864"),
+             NULL);
+
+    // Sync a dataSource with one object to an empty dataSource
+    testsync("alice1",
+             ^ (SOSDataSourceRef dataSource) {
+                 CFErrorRef error = NULL;
+                 SOSObjectRef object = SOSDataSourceCreateGenericItem(dataSource, CFSTR("test_account"), CFSTR("test service"));
+                 ok(dataSource->add(dataSource, object, &error), "dataSource added object %@", error);
+                 CFReleaseSafe(object);
+                 CFReleaseNull(error);
+             },
+             ^ (SOSDataSourceRef dataSource) {},
+             CFSTR("ADAA3ACE75ED516CB91893413EE9CC9ED04CA47B"),
+             CFSTR("147B6C509908CC4A9FC4263973A842104A64CE01"),
+             CFSTR("019B494F3C06B48BB02C280AF1E19AD861A7003C"),
+             CFSTR("ADAA3ACE75ED516CB91893413EE9CC9ED04CA47B"),
+             NULL);
+
+    // Sync a dataSource with one object to another dataSource with the same object
+    testsync("alice1bob1",
+             ^ (SOSDataSourceRef dataSource) {
+                 CFErrorRef error = NULL;
+                 SOSObjectRef object = SOSDataSourceCreateGenericItem(dataSource, CFSTR("test_account"), CFSTR("test service"));
+                 ok(dataSource->add(dataSource, object, &error), "dataSource added object %@", error);
+                 CFReleaseSafe(object);
+                 CFReleaseNull(error);
+             },
+             ^ (SOSDataSourceRef dataSource) {
+                 CFErrorRef error = NULL;
+                 SOSObjectRef object = SOSDataSourceCreateGenericItem(dataSource, CFSTR("test_account"), CFSTR("test service"));
+                 ok(dataSource->add(dataSource, object, &error), "dataSource added object %@", error);
+                 CFReleaseSafe(object);
+                 CFReleaseNull(error);
+             },
+             CFSTR("ADAA3ACE75ED516CB91893413EE9CC9ED04CA47B"),
+             CFSTR("ADAA3ACE75ED516CB91893413EE9CC9ED04CA47B"),
+             CFSTR("ADAA3ACE75ED516CB91893413EE9CC9ED04CA47B"),
+             NULL);
+
+    // Sync a dataSource with one object to another dataSource with the same object
+    testsync("alice1bob2",
+             ^ (SOSDataSourceRef dataSource) {
+                 CFErrorRef error = NULL;
+                 SOSObjectRef object = SOSDataSourceCreateGenericItem(dataSource, CFSTR("test_account"), CFSTR("test service"));
+                 ok(dataSource->add(dataSource, object, &error), "dataSource added object %@", error);
+                 CFReleaseSafe(object);
+                 CFReleaseNull(error);
+             },
+             ^ (SOSDataSourceRef dataSource) {
+                 CFErrorRef error = NULL;
+                 SOSObjectRef object = SOSDataSourceCreateGenericItem(dataSource, CFSTR("test_account"), CFSTR("test service"));
+                 ok(dataSource->add(dataSource, object, &error), "dataSource added object %@", error);
+                 CFReleaseSafe(object);
+                 object = SOSDataSourceCreateGenericItem(dataSource, CFSTR("account1"), CFSTR("service1"));
+                 ok(dataSource->add(dataSource, object, &error), "dataSource added object %@", error);
+                 CFReleaseSafe(object);
+                 CFReleaseNull(error);
+             },
+             CFSTR("ADAA3ACE75ED516CB91893413EE9CC9ED04CA47B"),
+             CFSTR("D4049A1063CFBF7CAF8424E13DE3CE926FF5856C"),
+             CFSTR("9624EA855BBED6B668868BB723443E804D04F6A1"),
+             CFSTR("063E097CCD4FEB7F3610ED12B3DA828467314846"),
+             CFSTR("D1B3944E3084425F41B2C2EA0BE82170E10AA37D"),
+             NULL);
+
+}
+
+int sc_70_engine(int argc, char *const *argv)
+{
+    plan_tests(kTestTestCount);
+
+    tests();
+    synctests();
+
+       return 0;
+}
diff --git a/sec/SOSCircle/Regressions/sc-75-circle-engine.c b/sec/SOSCircle/Regressions/sc-75-circle-engine.c
new file mode 100644 (file)
index 0000000..e0c3f5c
--- /dev/null
@@ -0,0 +1,223 @@
+//
+//  sc-75-circle-engine.c
+//  sec
+//
+//  Created by Michael Brouwer on 9/24/12.
+//  Copyright 2012 Apple Inc. All rights reserved.
+//
+
+#include <SecureObjectSync/SOSEngine.h>
+#include <SecureObjectSync/SOSPeer.h>
+
+#include "SOSCircle_regressions.h"
+
+#include <corecrypto/ccsha2.h>
+
+#include <utilities/SecCFWrappers.h>
+
+#include <stdint.h>
+
+#include <AssertMacros.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <CoreFoundation/CFDate.h>
+
+#include <utilities/SecCFWrappers.h>
+
+#include <Security/SecKey.h>
+
+#include <SecureObjectSync/SOSPeerInfo.h>
+#include <SecureObjectSync/SOSCircle.h>
+#include <SecureObjectSync/SOSCloudCircle.h>
+#include <SecureObjectSync/SOSInternal.h>
+#include <SecureObjectSync/SOSUserKeygen.h>
+
+#include "SOSCircle_regressions.h"
+#include "SOSRegressionUtilities.h"
+#include "SOSTestDataSource.h"
+
+#ifndef SEC_CONST_DECL
+#define SEC_CONST_DECL(k,v) CFTypeRef k = (CFTypeRef)(CFSTR(v));
+#endif
+
+#include <securityd/SOSCloudCircleServer.h>
+
+
+// MARK: ----- Constants -----
+
+static CFStringRef circleKey = CFSTR("Circle");
+
+static int kTestTestCount = 22;
+
+static void tests()
+{
+    CFErrorRef error = NULL;
+
+    CFStringRef aliceID = CFSTR("Alice");
+    CFStringRef bobID = CFSTR("Bob");    // not really remote, just another client on same machine
+
+    SecKeyRef alice_key = NULL;
+    SecKeyRef bob_key = NULL;
+
+    CFDataRef cfpassword = CFDataCreate(NULL, (uint8_t *) "FooFooFoo", 10);
+
+    CFDataRef parameters = SOSUserKeyCreateGenerateParameters(&error);
+    ok(parameters, "No parameters!");
+    ok(error == NULL, "Error: (%@)", error);
+    CFReleaseNull(error);
+
+    SecKeyRef user_privkey = SOSUserKeygen(cfpassword, parameters, &error);
+    CFReleaseNull(parameters);
+    CFReleaseSafe(cfpassword);
+
+    CFStringRef circleName = CFSTR("Woot Circle");
+
+    SOSFullPeerInfoRef alice_full_peer_info = SOSCreateFullPeerInfoFromName(aliceID, &alice_key, &error);
+    SOSPeerInfoRef alice_peer_info = SOSFullPeerInfoGetPeerInfo(alice_full_peer_info);
+
+    SOSFullPeerInfoRef bob_full_peer_info = SOSCreateFullPeerInfoFromName(bobID, &bob_key, &error);
+    SOSPeerInfoRef bob_peer_info = SOSFullPeerInfoGetPeerInfo(bob_full_peer_info);
+
+    SOSCircleRef aliceCircle = SOSCircleCreate(kCFAllocatorDefault, circleName, &error);
+
+    ok(SOSCircleRequestAdmission(aliceCircle, user_privkey, alice_full_peer_info, &error));
+    ok(SOSCircleAcceptRequests(aliceCircle, user_privkey, alice_full_peer_info, NULL));
+    ok(SOSCircleRequestAdmission(aliceCircle, user_privkey, bob_full_peer_info, &error), "requested admission");
+    ok(SOSCircleAcceptRequests(aliceCircle, user_privkey, bob_full_peer_info, &error), "accepted them all!");
+
+    alice_peer_info = SOSFullPeerInfoGetPeerInfo(alice_full_peer_info);
+    bob_peer_info = SOSFullPeerInfoGetPeerInfo(bob_full_peer_info);
+
+    CFDataRef aliceCircleEncoded;
+    ok(aliceCircleEncoded = SOSCircleCopyEncodedData(aliceCircle, kCFAllocatorDefault, &error), "encode alice circle: %@", error);
+    CFReleaseNull(error);
+    SOSCircleRef bobCircle;
+    ok(bobCircle = SOSCircleCreateFromData(0, aliceCircleEncoded, &error), "decode bobCircle: %@", error);
+    CFReleaseNull(aliceCircleEncoded);
+    CFReleaseNull(error);
+
+    /* Transport. */
+    __block CFDataRef queued_message = NULL;
+    
+    SOSPeerSendBlock enqueueMessage =  ^bool (CFDataRef message, CFErrorRef *error) {
+        if (queued_message)
+            fail("We already had an unproccessed message");
+        
+        queued_message = (CFDataRef) CFRetain(message);
+        return true;
+    };
+    
+    CFDataRef (^dequeueMessage)() = ^CFDataRef () {
+        CFDataRef result = queued_message;
+        queued_message = NULL;
+        
+        return result;
+    };
+
+    /* DataSource */
+    SOSDataSourceRef aliceDs = SOSTestDataSourceCreate();
+    SOSDataSourceRef bobDs = SOSTestDataSourceCreate();
+    
+    SOSDataSourceFactoryRef aliceDsf = SOSTestDataSourceFactoryCreate();
+    SOSTestDataSourceFactoryAddDataSource(aliceDsf, circleName, aliceDs);
+
+    SOSDataSourceFactoryRef bobDsf = SOSTestDataSourceFactoryCreate();
+    SOSTestDataSourceFactoryAddDataSource(bobDsf, circleName, bobDs);
+    
+    /* Test passing peer messages to the engine. */
+    CFDataRef message;
+
+    CFStringRef bob_peer_id = SOSPeerInfoGetPeerID(bob_peer_info);
+
+    /* Hand an empty message to the engine for handeling. */
+    message = CFDataCreate(NULL, NULL, 0);
+    is(SOSCircleHandlePeerMessage(aliceCircle, alice_full_peer_info, aliceDsf, enqueueMessage, bob_peer_id, message, &error), false,
+       "empty message rejected, %@", error);
+
+    CFReleaseNull(error);
+    CFReleaseNull(message);
+
+    ok(SOSCircleSyncWithPeer(alice_full_peer_info, aliceCircle, aliceDsf, enqueueMessage, bob_peer_id, &error), "Start sync [error %@]", error);
+    CFReleaseNull(error);
+
+    ok(message = dequeueMessage(), "Alice sent message");
+    CFStringRef alice_peer_id = SOSPeerInfoGetPeerID(alice_peer_info);
+    is(SOSCircleHandlePeerMessage(bobCircle, bob_full_peer_info, bobDsf, enqueueMessage, alice_peer_id, message, &error), true,
+       "Bob accepted message: %@", error);
+    CFReleaseNull(message);
+
+#if 1
+    CFStringRef desc = NULL;
+    ok(message = dequeueMessage(), "we got a message from Bob %@", desc = SOSMessageCopyDescription(message));
+    ok(SOSCircleHandlePeerMessage(aliceCircle, alice_full_peer_info, aliceDsf, enqueueMessage, bob_peer_id, message, &error),
+       "Alice accepted message: %@", error);
+    CFReleaseNull(message);
+    CFReleaseNull(desc);
+
+    ok(message = dequeueMessage(), "we got a reply from Alice %@", desc = SOSMessageCopyDescription(message));
+    ok(SOSCircleHandlePeerMessage(bobCircle, bob_full_peer_info, bobDsf, enqueueMessage, alice_peer_id, message, &error),
+       "Bob accepted message: %@", error);
+    CFReleaseNull(message);
+    CFReleaseNull(desc);
+#endif
+
+#if 0
+    message = dequeueMessage();
+    ok(NULL == message, "we got no message from Bob %@", desc = SOSMessageCopyDescription(message));
+
+    SOSObjectRef object = SOSDataSourceCreateGenericItem(aliceDs, CFSTR("75_circle_engine_account"), CFSTR("test service"));
+    ok(SOSTestDataSourceAddObject(aliceDs, object, &error), "add empty object to datasource: %@", error);
+    CFReleaseNull(error);
+    CFReleaseNull(object);
+
+    ok(SOSCircleSyncWithPeer(alice_full_peer_info, aliceCircle, aliceDsf, enqueueMessage, bob_peer_id, &error), "Restart sync [error %@]", error);
+    CFReleaseNull(error);
+    
+    ok(message = dequeueMessage(), "Alice started again %@", desc = SOSMessageCopyDescription(message));
+    is(SOSCircleHandlePeerMessage(bobCircle, bob_full_peer_info, bobDsf, enqueueMessage, alice_peer_id, message, &error), true,
+       "bob accepted %@: %@", SOSMessageCopyDescription(message), error);
+    CFReleaseNull(error);
+    CFReleaseNull(message);
+#endif
+
+#if 1
+    bool alice = true;
+    int max_loops = 50;
+    while (max_loops-- && NULL != (message = dequeueMessage())) {
+        if (alice) {
+            ok(SOSCircleHandlePeerMessage(aliceCircle, alice_full_peer_info, aliceDsf, enqueueMessage, bob_peer_id, message, &error),
+               "alice accepted %@: %@", desc = SOSMessageCopyDescription(message), error);
+        } else {
+            ok(SOSCircleHandlePeerMessage(bobCircle, bob_full_peer_info, bobDsf, enqueueMessage, alice_peer_id, message, &error),
+               "bob accepted %@: %@", desc = SOSMessageCopyDescription(message), error);
+        }
+        alice = !alice;
+        CFRelease(message);
+        CFReleaseNull(desc);
+    }
+#endif
+
+    CFReleaseNull(aliceCircle);
+    CFReleaseNull(bobCircle);
+
+    CFReleaseNull(alice_peer_info);
+    CFReleaseNull(bob_peer_info);
+
+    CFReleaseNull(alice_key);
+    CFReleaseNull(bob_key);
+    aliceDsf->release(aliceDsf);
+    bobDsf->release(bobDsf);
+}
+
+// MARK: ----- start of all tests -----
+
+int sc_75_circle_engine(int argc, char *const *argv)
+{
+    plan_tests(kTestTestCount);
+
+    tests();
+
+       return 0;
+}
diff --git a/sec/SOSCircle/Regressions/sc-90-ckdclient.c b/sec/SOSCircle/Regressions/sc-90-ckdclient.c
new file mode 100644 (file)
index 0000000..ed56ca4
--- /dev/null
@@ -0,0 +1,186 @@
+//
+//  sc-90-ckdclient.c
+//  sec
+//
+//  Created by John Hurley on 9/6/12.
+//
+//
+
+#include <AssertMacros.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <xpc/xpc.h>
+
+#include <Security/SecBase.h>
+#include <Security/SecItem.h>
+
+#include <SecureObjectSync/SOSAccount.h>
+#include <CKBridge/SOSCloudKeychainClient.h>
+
+#include <utilities/SecCFWrappers.h>
+#include <utilities/debugging.h>
+
+#include "SOSCircle_regressions.h"
+#include "SOSRegressionUtilities.h"
+
+
+static bool verboseCKDClientDebugging = false;
+
+static CFStringRef kTestKeyIDTimestamp = CFSTR("IDTimestamp");
+static dispatch_group_t sDispatchGroup = NULL;
+static dispatch_queue_t xpc_queue = NULL;
+
+// MARK: ----- Test Data -----
+
+static CFStringRef kTestKeyString = CFSTR("teststring");
+static CFStringRef kTestKeyData = CFSTR("testdata");
+static const UInt8 tdata[] = {0x01, 0x02, 0x03, 0x04, 'a', 'b', 'c'};
+static CFStringRef kTestKeyArray = CFSTR("testarray");
+static const CFStringRef adata[] = {CFSTR("A"), CFSTR("b"), CFSTR("C"), CFSTR("D")};
+static const CFStringRef circleKeyStrings[] = {CFSTR("circleA"), CFSTR("circleB"), CFSTR("circleC"), CFSTR("circleD")};
+static const CFStringRef keysWhenUnlockedKeyStrings[] = {CFSTR("foo"), CFSTR("bar"), CFSTR("baz")};
+
+static CFDataRef testData = NULL;
+static CFArrayRef testArray = NULL;
+static CFArrayRef circleKeys = NULL;
+static CFArrayRef keysWhenUnlocked = NULL;
+
+static void initializeTestData(void)
+{
+    testData = CFDataCreate(kCFAllocatorDefault, tdata, sizeof(tdata)/sizeof(UInt8));
+    testArray = CFArrayCreate(kCFAllocatorDefault, (const void **)&adata, sizeof(adata)/sizeof(CFStringRef), &kCFTypeArrayCallBacks);
+    // Register keys
+    circleKeys = CFArrayCreate(kCFAllocatorDefault, (const void **)&circleKeyStrings, sizeof(circleKeyStrings)/sizeof(CFStringRef), &kCFTypeArrayCallBacks);
+    keysWhenUnlocked = CFArrayCreate(kCFAllocatorDefault, (const void **)&keysWhenUnlockedKeyStrings, sizeof(keysWhenUnlockedKeyStrings)/sizeof(CFStringRef),
+        &kCFTypeArrayCallBacks);
+}
+
+// MARK: ----- utilities -----
+
+static void printTimeNow(const char *msg)
+{
+    if (verboseCKDClientDebugging)
+    {
+        CFAbsoluteTime now = CFAbsoluteTimeGetCurrent();
+        const char *nowstr = cfabsoluteTimeToString(now);
+        if (nowstr)
+        {
+                printf("%s %s\n", nowstr, msg);
+            free((void *)nowstr);
+        }
+    }
+}
+
+// MARK: ----- basicKVSTests -----
+
+static bool testPostGet(CFStringRef key, CFTypeRef cfobj, dispatch_queue_t processQueue, dispatch_group_t dgroup)
+{
+    CFErrorRef error = NULL;
+    bool result = false;
+    CFTypeRef cfv = NULL;
+    
+    testPutObjectInCloud(key, cfobj, &error, dgroup, processQueue);
+    CFTypeRef cfvalue = testGetObjectFromCloud(key, processQueue, dgroup);
+    printTimeNow("finished getObjectFromCloud");
+    if (!cfvalue)
+        return false;
+    if (CFGetTypeID(cfvalue)==CFDictionaryGetTypeID())
+        cfv = CFDictionaryGetValue(cfvalue, key);
+    else
+        cfv = cfvalue;
+    result = CFEqual(cfobj, cfv);
+    return result;
+}
+
+static bool postIDTimestamp(dispatch_queue_t theq, dispatch_group_t dgroup)
+{
+    bool result = false;
+    CFStringRef macaddr = myMacAddress();
+    CFAbsoluteTime now = CFAbsoluteTimeGetCurrent();
+    const char *nowstr = cfabsoluteTimeToStringLocal(now);
+    CFStringRef cfidstr = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@: %@  %s"), kTestKeyIDTimestamp, macaddr ,nowstr);
+    secerror("Setting %@ key: %@", kTestKeyIDTimestamp, cfidstr);
+    result = testPostGet(kTestKeyIDTimestamp, cfidstr, theq, dgroup);
+
+    if (nowstr)
+        free((void *)nowstr);
+    CFReleaseSafe(cfidstr);
+    return result;
+}
+
+
+static const int kbasicKVSTestsCount = 10;
+static void basicKVSTests(dispatch_group_t dgroup)
+{
+    dispatch_queue_t generalq = dispatch_queue_create("general", DISPATCH_QUEUE_SERIAL);
+
+    printTimeNow("Start tests [basicKVSTests]");
+ //   dispatch_group_enter(dgroup);
+    
+    // synchronize first to make sure we see cloud values
+    ok(testSynchronize(generalq, dgroup), "test synchronize");
+
+    // Next, get the TimeNow value, since this is the only one that differs from test to test (i.e. sc-90-ckdclient)
+    CFAbsoluteTime now = CFAbsoluteTimeGetCurrent();
+    const char *nowstr = cfabsoluteTimeToStringLocal(now);
+    CFStringRef cfstrtime = CFStringCreateWithCString(kCFAllocatorDefault, nowstr, kCFStringEncodingUTF8);
+    ok(testGetObjectFromCloud(kTestKeyIDTimestamp, generalq, dgroup) != nil, "testGet for %@", kTestKeyIDTimestamp);
+    
+    ok(postIDTimestamp(generalq, dgroup), "testPostGet for %@", kTestKeyIDTimestamp);
+
+    ok(testPostGet(kTestKeyString, CFSTR("test string"), generalq, dgroup), "testPostGet for CFStringRef");
+
+    // Now the fixed values
+    ok(testPostGet(kTestKeyString, CFSTR("test string"), generalq, dgroup), "testPostGet for CFStringRef");
+    ok(testPostGet(kTestKeyData, testData, generalq, dgroup), "testPostGet for CFDataRef");
+    ok(testPostGet(kTestKeyArray, testArray, generalq, dgroup), "testPostGet for CFDataRef");
+    ok(testRegisterKeys(circleKeys, generalq, dgroup), "test register keys");
+    
+    ok(postIDTimestamp(generalq, dgroup), "testPostGet for %@", kTestKeyIDTimestamp);
+
+    // Synchronize one more time before exit
+    ok(testSynchronize(generalq, dgroup), "test synchronize");
+/**/
+    printTimeNow("End tests [basicKVSTests]");
+
+//    dispatch_group_leave(dgroup);
+    
+    // Release test data
+    CFRelease(testData);
+    CFRelease(testArray);
+    CFRelease(circleKeys);
+    CFRelease(keysWhenUnlocked);
+    CFRelease(cfstrtime);
+    if (nowstr)
+        free((void *)nowstr);
+}
+
+// MARK: ----- start of all tests -----
+
+static int kTestTestCount = kbasicKVSTestsCount;
+static void tests(void)
+{
+    SKIP: {
+        skip("Skipping ckdclient tests because CloudKeychainProxy.xpc is not installed", kTestTestCount, XPCServiceInstalled());
+ //       dispatch_queue_t dqueue = dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
+            xpc_queue = dispatch_queue_create("sc_90_ckdclient", DISPATCH_QUEUE_SERIAL);
+
+        sDispatchGroup = dispatch_group_create();
+        
+        initializeTestData();
+        basicKVSTests(sDispatchGroup);
+    }
+}
+
+int sc_90_ckdclient(int argc, char *const *argv)
+{
+    plan_tests(kTestTestCount);
+    
+    tests();
+
+       return 0;
+}
+
+
diff --git a/sec/SOSCircle/Regressions/sc-95-ckd2client.c b/sec/SOSCircle/Regressions/sc-95-ckd2client.c
new file mode 100644 (file)
index 0000000..aea9fd4
--- /dev/null
@@ -0,0 +1,134 @@
+//
+//  sc-90-ckdclient.c
+//  sec
+//
+//  Created by John Hurley on 9/6/12.
+//
+//
+
+#include <AssertMacros.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <xpc/xpc.h>
+
+#include <Security/SecBase.h>
+#include <Security/SecItem.h>
+
+#include <SecureObjectSync/SOSAccount.h>
+#include <CKBridge/SOSCloudKeychainClient.h>
+#include <utilities/SecCFWrappers.h>
+#include <utilities/debugging.h>
+
+#include "SOSCircle_regressions.h"
+#include "SOSRegressionUtilities.h"
+
+static bool verboseCKDClientDebugging = false;
+
+static CFStringRef kTestKeyIDTimestamp = CFSTR("IDTimestamp");
+
+static void printTimeNow(const char *msg)
+{
+    if (verboseCKDClientDebugging)
+    {
+        CFAbsoluteTime now = CFAbsoluteTimeGetCurrent();
+        const char *nowstr = cfabsoluteTimeToString(now);
+        if (nowstr)
+        {
+                printf("%s %s\n", nowstr, msg);
+            free((void *)nowstr);
+        }
+    }
+}
+
+// MARK: ----- basicKVSTests -----
+
+static bool postIDTimestamp(dispatch_queue_t theq)
+{
+    __block bool result = false;
+    CFStringRef macaddr = myMacAddress();
+    CFAbsoluteTime now = CFAbsoluteTimeGetCurrent();
+    const char *nowstr = cfabsoluteTimeToStringLocal(now);
+    CFStringRef cfidstr = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@: %@  %s"), kTestKeyIDTimestamp, macaddr ,nowstr);
+    secerror("Setting %@ key: %@", kTestKeyIDTimestamp, cfidstr);
+
+    // create a dictionary with one key/value pair
+    CFDictionaryRef objects = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, kTestKeyIDTimestamp, cfidstr, NULL);
+    SOSCloudKeychainPutObjectsInCloud(objects, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
+                                      ^(CFDictionaryRef returnedValues, CFErrorRef error) {
+                                          if (error) {
+                                              fail("Error putting: %@", error);
+                                              CFReleaseSafe(error);
+                                          }
+                                      });
+
+    CFMutableArrayRef keysToGet = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
+    CFArrayAppendValue(keysToGet, kTestKeyIDTimestamp);
+    SOSCloudKeychainGetObjectsFromCloud(keysToGet, theq, ^ (CFDictionaryRef returnedValues, CFErrorRef error)
+        {
+            CFStringRef returnedTimestamp = (CFStringRef)CFDictionaryGetValue(returnedValues, kTestKeyIDTimestamp);
+            if (returnedTimestamp)
+                result = CFEqual(returnedTimestamp, cfidstr);
+        });
+
+    if (nowstr)
+        free((void *)nowstr);
+    return result;
+}
+
+static const int kbasicKVSTestsCount = 1;
+static void basicKVSTests2()
+{
+    dispatch_queue_t generalq = dispatch_queue_create("general", DISPATCH_QUEUE_SERIAL);
+
+    const UInt8 tdata[] = {0x01, 0x02, 0x03, 0x04, 'a', 'b', 'c'};
+    CFDataRef testData = CFDataCreate(kCFAllocatorDefault, tdata, sizeof(tdata)/sizeof(UInt8));
+   
+    const CFStringRef adata[] = {CFSTR("A"), CFSTR("b"), CFSTR("C"), CFSTR("D")};
+    CFArrayRef testArray = CFArrayCreate(kCFAllocatorDefault, (const void **)&adata, sizeof(adata)/sizeof(CFStringRef), &kCFTypeArrayCallBacks);
+
+    // Register keys
+    const CFStringRef circleKeyStrings[] = {CFSTR("circleA"), CFSTR("circleB"), CFSTR("circleC"), CFSTR("circleD")};
+    CFArrayRef circleKeys = CFArrayCreate(kCFAllocatorDefault, (const void **)&circleKeyStrings, sizeof(circleKeyStrings)/sizeof(CFStringRef), &kCFTypeArrayCallBacks);
+
+    const CFStringRef keysWhenUnlockedKeyStrings[] = {CFSTR("foo"), CFSTR("bar"), CFSTR("baz")};
+    CFArrayRef keysWhenUnlocked = CFArrayCreate(kCFAllocatorDefault, (const void **)&keysWhenUnlockedKeyStrings, sizeof(keysWhenUnlockedKeyStrings)/sizeof(CFStringRef), &kCFTypeArrayCallBacks);
+
+    printTimeNow("Start tests [basicKVSTests]");
+    
+    ok(postIDTimestamp(generalq), "testPostGet for %@", kTestKeyIDTimestamp);
+
+    printTimeNow("Start tests [basicKVSTests2]");
+
+    // Release test data
+    CFRelease(testData);
+    CFRelease(testArray);
+    CFRelease(circleKeys);
+    CFRelease(keysWhenUnlocked);
+}
+
+// MARK: ----- start of all tests -----
+
+static const int kCloudTransportTestsCount = 0;
+static int kTestTestCount = kbasicKVSTestsCount + kCloudTransportTestsCount;
+static void tests(void)
+{
+    SKIP: {
+        skip("Skipping ckdclient tests because CloudKeychainProxy.xpc is not installed", kTestTestCount, XPCServiceInstalled());
+        basicKVSTests2();
+  //      cloudTransportTests();
+  sleep(15);    // on iOS, we need to hang around long enough for syncdefaultsd to see us
+    }
+}
+
+int sc_95_ckd2client(int argc, char *const *argv)
+{
+    plan_tests(kTestTestCount);
+    
+    tests();
+
+       return 0;
+}
+
+
diff --git a/sec/SOSCircle/Regressions/sc-kvstool.m b/sec/SOSCircle/Regressions/sc-kvstool.m
new file mode 100644 (file)
index 0000000..f578970
--- /dev/null
@@ -0,0 +1,340 @@
+//
+//  sc-kvstool.c
+//  sec
+//
+//  Created by John Hurley 11/01/12.
+//  Copyright 2012 Apple Inc. All rights reserved.
+//
+
+
+// Run on a device:
+//      /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_kvstool -v --  --dump
+//      /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_kvstool -v --  --clear
+//      /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_kvstool -v --  --putcircle
+//      /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_kvstool -v -- --direct  --dump
+//      /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_kvstool -v -- --direct --putcircle
+
+#include <Foundation/Foundation.h>
+#include <SecureObjectSync/SOSEngine.h>
+#include <SecureObjectSync/SOSPeer.h>
+#include <SecureObjectSync/SOSInternal.h>
+#include <SecureObjectSync/SOSCloudCircle.h>
+
+#include "SOSCircle_regressions.h"
+
+#include <corecrypto/ccsha2.h>
+
+#include <utilities/SecCFWrappers.h>
+#include <utilities/debugging.h>
+
+#include <stdint.h>
+
+#include <AssertMacros.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <CoreFoundation/CFDate.h>
+#include <getopt.h>
+
+#include <notify.h>
+#include <dispatch/dispatch.h>
+
+#include "SOSCircle_regressions.h"
+#include "CKDLocalKeyValueStore.h"
+#include "SOSRegressionUtilities.h"
+#include "SOSTestDataSource.h"
+#include "SOSTestTransport.h"
+#include "SOSCloudKeychainClient.h"
+
+#import "SOSDirectCloudTransport.h"
+
+// MARK: ----- Constants -----
+
+static CFStringRef circleKey = CFSTR("Circle");
+
+// MARK: ----- start of all tests -----
+
+static void putCircleInCloud(SOSCircleRef circle, dispatch_queue_t work_queue, dispatch_group_t work_group)
+{
+    CFErrorRef error = NULL;
+    CFDataRef newCloudCircleEncoded = SOSCircleCopyEncodedData(circle, kCFAllocatorDefault, &error);
+    ok(newCloudCircleEncoded, "Encoded as: %@ [%@]", newCloudCircleEncoded, error);
+
+    // Send the circle with our application request back to cloud
+    testPutObjectInCloud(circleKey, newCloudCircleEncoded, &error, work_group, work_queue);
+}
+
+static void createAndPutInitialCircle(void)
+{
+    dispatch_queue_t work_queue = dispatch_queue_create("capic", DISPATCH_QUEUE_CONCURRENT);
+    dispatch_group_t work_group = dispatch_group_create();
+
+    CFErrorRef error = NULL;
+    CFStringRef cflabel = CFSTR("TEST_USERKEY");
+    CFDataRef cfpassword = CFDataCreate(NULL, (uint8_t *) "FooFooFoo", 10);
+    SOSCCRegisterUserCredentials(cflabel, cfpassword, &error);
+
+    CFErrorRef localError = NULL;
+    
+    SOSDataSourceFactoryRef our_data_source_factory = SOSTestDataSourceFactoryCreate();
+    SOSDataSourceRef our_data_source = SOSTestDataSourceCreate();
+    SOSTestDataSourceFactoryAddDataSource(our_data_source_factory, circleKey, our_data_source);
+
+    CFDictionaryRef gestalt = SOSCreatePeerGestaltFromName(CFSTR("Alice"));
+
+    SOSAccountRef our_account = SOSAccountCreate(kCFAllocatorDefault, gestalt, our_data_source_factory,
+        ^(CFArrayRef keys)
+        {
+            pass("SOSAccountKeyInterestBlock");
+        },
+        ^ bool (CFDictionaryRef keys, CFErrorRef *error)
+        {
+            pass("SOSAccountDataUpdateBlock");
+            return false;
+        },
+        NULL);
+    SOSAccountEnsureCircle(our_account, circleKey);
+
+    SOSFullPeerInfoRef our_full_peer_info = SOSAccountGetMyFullPeerInCircleNamed(our_account, circleKey, &error);
+    SOSPeerInfoRef our_peer_info = SOSFullPeerInfoGetPeerInfo(our_full_peer_info);
+    CFRetain(our_peer_info);
+
+    SOSCircleRef circle = SOSAccountFindCircle(our_account, circleKey);
+    CFRetain(circle);
+    
+//    SecKeyRef user_privkey = SOSUserGetPrivKey(&localError);
+    SecKeyRef user_privkey = NULL;  // TODO: this will not work
+    ok(SOSCircleRequestAdmission(circle, user_privkey, our_full_peer_info, &localError), "Requested admission (%@)", our_peer_info);
+    ok(SOSCircleAcceptRequests(circle, user_privkey, our_full_peer_info, &localError), "Accepted self");
+    
+    putCircleInCloud(circle, work_queue, work_group);
+    pass("Put circle in cloud: (%@)", circle);
+    
+    CFRelease(circle);
+}
+
+static void postCircleChangeNotification()
+{
+    NSArray *keys = [NSArray arrayWithObjects:(id)circleKey, nil];
+    NSDictionary* userInfo = [[NSDictionary alloc] initWithObjectsAndKeys:
+        keys, NSUbiquitousKeyValueStoreChangedKeysKey,
+        [NSNumber numberWithInt:NSUbiquitousKeyValueStoreServerChange], NSUbiquitousKeyValueStoreChangeReasonKey,
+        nil];
+    [[NSNotificationCenter defaultCenter] postNotificationName:NSUbiquitousKeyValueStoreDidChangeExternallyNotification object:NULL userInfo:userInfo];
+    [userInfo release];
+}
+
+static void requestSynchronization(dispatch_queue_t processQueue, dispatch_group_t dgroup)
+{
+    testSynchronize(processQueue, dgroup);
+}
+
+static void displayCircles(CFTypeRef objects)
+{
+    // SOSCCCopyApplicantPeerInfo doesn't display all info, e.g. in the case where we are not in circle
+    CFDictionaryForEach(objects, ^(const void *key, const void *value)
+    {
+        if (SOSKVSKeyGetKeyType(key) == kCircleKey)
+        {
+            CFErrorRef localError = NULL;
+            if (isData(value))
+            {
+                SOSCircleRef circle = SOSCircleCreateFromData(NULL, (CFDataRef) value, &localError);
+                pass("circle: %@ %@", key, circle);
+                CFReleaseSafe(circle);
+            }
+            else
+                pass("non-circle: %@ %@", key, value);
+        }
+    });
+}
+
+
+static void dumpCircleInfo()
+{
+    CFErrorRef error = NULL;
+    CFArrayRef applicantPeerInfos = NULL;
+    CFArrayRef peerInfos = NULL;
+    int idx;
+    
+    NSArray *ccmsgs = @[@"ParamErr", @"Error", @"InCircle", @"NotInCircle", @"RequestPending", @"CircleAbsent"  ];
+
+    SOSCCStatus ccstatus = SOSCCThisDeviceIsInCircle(&error);
+    pass("ccstatus: %d, error: %@", ccstatus, error);
+    idx = ccstatus-kSOSCCParamErr;
+    if (0<=idx && idx<(int)[ccmsgs count])
+        pass("ccstatus: %d (%@)", ccstatus, ccmsgs[idx]);
+
+    // Now look at current applicants
+    applicantPeerInfos = SOSCCCopyApplicantPeerInfo(&error);
+    if (applicantPeerInfos)
+    {
+        pass("Applicants: %ld, error: %@", (long)CFArrayGetCount(applicantPeerInfos), error);
+        CFArrayForEach(applicantPeerInfos, ^(const void *value) {
+            SOSPeerInfoRef peer = (SOSPeerInfoRef)value;
+            CFStringRef peerName = SOSPeerInfoGetPeerName(peer);
+            pass("Applicant: %@", peerName);
+        });
+    }
+    else
+        pass("No applicants, error: %@", error);
+    
+    
+    peerInfos = SOSCCCopyPeerPeerInfo(&error);
+    if (peerInfos)
+    {
+        pass("Peers: %ld, error: %@", (long)CFArrayGetCount(applicantPeerInfos), error);
+        CFArrayForEach(peerInfos, ^(const void *value) {
+            SOSPeerInfoRef peer = (SOSPeerInfoRef)value;
+            CFStringRef peerName = SOSPeerInfoGetPeerName(peer);
+            pass("Peer: %@", peerName);
+        });
+    }
+    else
+        pass("No peers, error: %@", error);
+}
+
+// define the options table for the command line
+static const struct option options[] =
+{
+       { "verbose",            optional_argument,      NULL, 'v' },
+       { "dump",           optional_argument,  NULL, 'd' },
+       { "clear",          optional_argument,  NULL, 'C' },
+       { "putcircle",      optional_argument,  NULL, 'p' },
+       { "direct",         optional_argument,  NULL, 'D' },
+       { "notify",         optional_argument,  NULL, 'n' },
+       { "sync",           optional_argument,  NULL, 's' },
+       { "info",           optional_argument,  NULL, 'i' },
+       { }
+};
+
+static int kTestCount = 10;
+
+static void usage(void)
+{
+    printf("Usage:\n");
+    printf("    --dump [itemName]   Dump the contents of the kvs store (through proxy)\n");
+    printf("    --clear             Clear the contents of the kvs store (through proxy)\n");
+    printf("    --putcircle         Put a new circle into the kvs store (through proxy)\n");
+    printf("    --direct            Go directly to KVS (bypass proxy)\n");
+    printf("    --notify            Post a notification that the circle key has changed\n");
+    printf("    --sync              Post a notification that the circle key has changed\n");
+    printf("    --info              Dump info about circle and peer status\n");
+}
+
+enum kvscommands
+{
+    kCommandClear = 1,
+    kCommandDump = 2,
+    kCommandPutCircle = 3,
+    kCommandNotify = 4,
+    kCommandSynchronize = 5,
+    kCommandInfo = 6,
+    kCommandHelp
+};
+
+static int command = kCommandHelp;
+static bool useDirect = false;
+
+static void tests(const char *itemName)
+{
+    dispatch_queue_t generalq = dispatch_queue_create("general", DISPATCH_QUEUE_SERIAL);
+    dispatch_group_t work_group = dispatch_group_create();
+
+#if 0
+    if (useDirect)
+    {
+        SOSCloudKeychainServerInit();
+    }
+#endif
+    SOSCloudKeychainSetCallbackMethodXPC(); // call this first
+
+    pass("Command: %d", command);
+    switch (command)
+    {
+        case kCommandClear:
+            ok(testClearAll(generalq, work_group), "test Clear All");
+            break;
+        case kCommandDump:
+            {
+                CFArrayRef keysToGet = NULL;
+                if (itemName)
+                {
+                    CFStringRef itemStr = CFStringCreateWithCString(kCFAllocatorDefault, itemName, kCFStringEncodingUTF8);
+                    pass("Retrieving   : %@", itemStr);
+                    keysToGet = CFArrayCreateForCFTypes(kCFAllocatorDefault, itemStr);
+                    CFReleaseSafe(itemStr);
+                }
+                CFTypeRef objects = testGetObjectsFromCloud(keysToGet, generalq, work_group);
+                CFReleaseSafe(keysToGet);
+                pass("   : %@", objects);
+                displayCircles(objects);
+            }
+            break;
+        case kCommandPutCircle:
+            createAndPutInitialCircle();
+            break;
+        case kCommandNotify:
+            postCircleChangeNotification();
+            break;
+        case kCommandSynchronize:
+            requestSynchronization(generalq, work_group);
+            break;
+        case kCommandInfo:
+            dumpCircleInfo();
+            break;
+        default:
+        case kCommandHelp:
+            usage();
+            break;
+    }
+}
+
+int sc_kvstool(int argc, char *const *argv)
+{
+    char *itemName = NULL;
+//  extern int optind;
+    extern char *optarg;
+    int arg, argSlot;
+
+    while (argSlot = -1, (arg = getopt_long(argc, (char * const *)argv, "ivChpdns", options, &argSlot)) != -1)
+        switch (arg)
+        {
+        case 'd':
+            itemName = (char *)(optarg);
+            command = kCommandDump;
+            break;
+        case 'C':   // should set up to call testClearAll
+            command = kCommandClear;
+            break;
+        case 'p':
+            command = kCommandPutCircle;
+            break;
+        case 'n':
+            command = kCommandNotify;
+            break;
+        case 's':
+            command = kCommandSynchronize;
+            break;
+        case 'i':
+            command = kCommandInfo;
+            break;
+        case 'D':
+            useDirect = true;
+            printf("Using direct calls to KVS\n");
+            break;
+        default:
+            secerror("arg: %s", optarg);
+            break;
+        }
+
+    plan_tests(kTestCount);
+
+    secerror("Command: %d", command);
+    printf("Command: %d\n", command);
+
+       tests(itemName);
+
+       return 0;
+}
diff --git a/sec/SOSCircle/SOSARCDefines.h b/sec/SOSCircle/SOSARCDefines.h
new file mode 100644 (file)
index 0000000..50c0475
--- /dev/null
@@ -0,0 +1,49 @@
+//
+//  SOSARCDefines.h
+//  sec
+//
+//  Created by John Hurley on 11/2/12.
+//
+//
+
+#ifndef sec_SOSARCDefines_h
+#define sec_SOSARCDefines_h
+
+#ifndef __has_feature
+#define __has_feature(x) 0
+#endif
+#ifndef __has_extension
+#define __has_extension __has_feature // Compatibility with pre-3.0 compilers.
+#endif
+
+#if __has_feature(objc_arc) && __clang_major__ >= 3
+#define ARC_ENABLED 1
+#endif // __has_feature(objc_arc)
+
+#if !ARC_ENABLED || !defined(__clang__) || __clang_major__ < 3
+
+#ifndef __bridge
+#define __bridge
+#endif
+#ifndef __bridge_retained
+#define __bridge_retained
+#endif
+#ifndef __bridge_transfer
+#define __bridge_transfer
+#endif
+#ifndef __autoreleasing
+#define __autoreleasing
+#endif
+#ifndef __strong
+#define __strong
+#endif
+#ifndef __weak
+#define __weak
+#endif
+#ifndef __unsafe_unretained
+#define __unsafe_unretained
+#endif
+
+#endif // __clang_major__ < 3
+
+#endif
diff --git a/sec/SOSCircle/SecureObjectSync/Imported/SOSCloudCircleServer.h b/sec/SOSCircle/SecureObjectSync/Imported/SOSCloudCircleServer.h
new file mode 120000 (symlink)
index 0000000..55a3e26
--- /dev/null
@@ -0,0 +1 @@
+./../../securityd/SOSCloudCircleServer.h
\ No newline at end of file
diff --git a/sec/SOSCircle/SecureObjectSync/Imported/SecItemServer.h b/sec/SOSCircle/SecureObjectSync/Imported/SecItemServer.h
new file mode 120000 (symlink)
index 0000000..a3cf6ee
--- /dev/null
@@ -0,0 +1 @@
+./../../securityd/SecItemServer.h
\ No newline at end of file
diff --git a/sec/SOSCircle/SecureObjectSync/Imported/SecuritydXPC.h b/sec/SOSCircle/SecureObjectSync/Imported/SecuritydXPC.h
new file mode 120000 (symlink)
index 0000000..bc4863a
--- /dev/null
@@ -0,0 +1 @@
+./../../Security/SecuritydXPC.h
\ No newline at end of file
diff --git a/sec/SOSCircle/SecureObjectSync/Imported/securityd_client.h b/sec/SOSCircle/SecureObjectSync/Imported/securityd_client.h
new file mode 120000 (symlink)
index 0000000..f966009
--- /dev/null
@@ -0,0 +1 @@
+./../../ipc/securityd_client.h
\ No newline at end of file
diff --git a/sec/SOSCircle/SecureObjectSync/Imported/spi.h b/sec/SOSCircle/SecureObjectSync/Imported/spi.h
new file mode 120000 (symlink)
index 0000000..b59d797
--- /dev/null
@@ -0,0 +1 @@
+./../../securityd/spi.h
\ No newline at end of file
diff --git a/sec/SOSCircle/SecureObjectSync/SOSAccount.c b/sec/SOSCircle/SecureObjectSync/SOSAccount.c
new file mode 100644 (file)
index 0000000..8ac8431
--- /dev/null
@@ -0,0 +1,3193 @@
+/*
+ * Created by Michael Brouwer on 6/22/12.
+ * Copyright 2012 Apple Inc. All Rights Reserved.
+ */
+
+/*
+ * SOSAccount.c -  Implementation of the secure object syncing account.
+ * An account contains a SOSCircle for each protection domain synced.
+ */
+
+#include <SecureObjectSync/SOSInternal.h>
+#include <SecureObjectSync/SOSAccount.h>
+#include <SecureObjectSync/SOSCircle.h>
+#include <SecureObjectSync/SOSCloudCircle.h>
+#include <SecureObjectSync/SOSEngine.h>
+#include <SecureObjectSync/SOSPeer.h>
+#include <SecureObjectSync/SOSFullPeerInfo.h>
+#include <SecureObjectSync/SOSPeerInfo.h>
+#include <SecureObjectSync/SOSPeerInfoInternal.h>
+#include <SecureObjectSync/SOSUserKeygen.h>
+#include <Security/SecKeyPriv.h>
+#include <Security/SecItemPriv.h>
+#include <CoreFoundation/CFArray.h>
+#include <dispatch/dispatch.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <AssertMacros.h>
+#include <utilities/SecCFWrappers.h>
+
+#include <utilities/der_plist.h>
+#include <utilities/der_plist_internal.h>
+#include <utilities/iOSforOSX.h>
+
+#include <utilities/SecAKSWrappers.h>
+
+#include <corecrypto/ccder.h>
+
+#include <securityd/SOSCloudCircleServer.h>
+#include <securityd/SecDbItem.h> // For SecError
+
+#include <utilities/debugging.h>
+#include <utilities/iCloudKeychainTrace.h>
+
+#include <notify.h>
+
+static CFStringRef kicloud_identity_name = CFSTR("Cloud Identity");
+
+//
+// Forward statics.
+//
+
+static bool SOSAccountHandleUpdateCircle(SOSAccountRef account, SOSCircleRef newCircle, bool writeUpdate, bool initialSync, CFErrorRef *error);
+
+//
+// DER Encoding utilities
+//
+
+//
+// Encodes data or a zero length data
+//
+static size_t der_sizeof_data_or_null(CFDataRef data, CFErrorRef* error)
+{
+       if (data) {
+               return der_sizeof_data(data, error);
+       } else {
+               return der_sizeof_null(kCFNull, error);
+       }
+}
+
+static uint8_t* der_encode_data_or_null(CFDataRef data, CFErrorRef* error, const uint8_t* der, uint8_t* der_end)
+{
+    if (data) {
+               return der_encode_data(data, error, der, der_end);
+       } else {
+               return der_encode_null(kCFNull, error, der, der_end);
+       }
+}
+
+
+static const uint8_t* der_decode_data_or_null(CFAllocatorRef allocator, CFDataRef* data,
+                                              CFErrorRef* error,
+                                              const uint8_t* der, const uint8_t* der_end)
+{
+    CFTypeRef value = NULL;
+       der = der_decode_plist(allocator, 0, &value, error, der, der_end);
+       if (value && CFGetTypeID(value) != CFDataGetTypeID()) {
+               CFReleaseNull(value);
+       }
+       if (data) {
+               *data = value;
+       }
+       return der;
+}
+
+
+//
+// Mark: public_bytes encode/decode
+//
+
+static size_t der_sizeof_public_bytes(SecKeyRef publicKey, CFErrorRef* error)
+{
+    CFDataRef publicData = NULL;
+
+    if (publicKey)
+        SecKeyCopyPublicBytes(publicKey, &publicData);
+
+    size_t size = der_sizeof_data_or_null(publicData, error);
+
+    CFReleaseNull(publicData);
+
+    return size;
+}
+
+static uint8_t* der_encode_public_bytes(SecKeyRef publicKey, CFErrorRef* error, const uint8_t* der, uint8_t* der_end)
+{
+    CFDataRef publicData = NULL;
+
+    if (publicKey)
+        SecKeyCopyPublicBytes(publicKey, &publicData);
+
+    uint8_t *result = der_encode_data_or_null(publicData, error, der, der_end);
+
+    CFReleaseNull(publicData);
+
+    return result;
+}
+
+static const uint8_t* der_decode_public_bytes(CFAllocatorRef allocator, CFIndex algorithmID, SecKeyRef* publicKey, CFErrorRef* error, const uint8_t* der, const uint8_t* der_end)
+{
+    CFDataRef dataFound = NULL;
+    der = der_decode_data_or_null(allocator, &dataFound, error, der, der_end);
+
+    if (der && dataFound && publicKey) {
+        *publicKey = SecKeyCreateFromPublicData(allocator, algorithmID, dataFound);
+    }
+    CFReleaseNull(dataFound);
+
+    return der;
+}
+
+
+//
+// Cloud Paramters encode/decode
+//
+
+static size_t der_sizeof_cloud_parameters(SecKeyRef publicKey, CFDataRef paramters, CFErrorRef* error)
+{
+    size_t public_key_size = der_sizeof_public_bytes(publicKey, error);
+    size_t parameters_size = der_sizeof_data_or_null(paramters, error);
+
+    return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, public_key_size + parameters_size);
+}
+
+static uint8_t* der_encode_cloud_parameters(SecKeyRef publicKey, CFDataRef paramters, CFErrorRef* error,
+                                            const uint8_t* der, uint8_t* der_end)
+{
+    uint8_t* original_der_end = der_end;
+
+    return ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, original_der_end, der,
+                                       der_encode_public_bytes(publicKey, error, der,
+                                                               der_encode_data_or_null(paramters, error, der, der_end)));
+}
+
+static const uint8_t* der_decode_cloud_parameters(CFAllocatorRef allocator,
+                                                  CFIndex algorithmID, SecKeyRef* publicKey,
+                                                  CFDataRef *parameters,
+                                                  CFErrorRef* error,
+                                                  const uint8_t* der, const uint8_t* der_end)
+{
+    const uint8_t *sequence_end;
+    der = ccder_decode_sequence_tl(&sequence_end, der, der_end);
+    der = der_decode_public_bytes(allocator, algorithmID, publicKey, error, der, sequence_end);
+    der = der_decode_data_or_null(allocator, parameters, error, der, sequence_end);
+
+    return der;
+}
+
+
+//
+// bool encoding/decoding
+//
+
+
+static const uint8_t* ccder_decode_bool(bool* boolean, const uint8_t* der, const uint8_t *der_end)
+{
+    if (NULL == der)
+        return NULL;
+
+    size_t payload_size = 0;
+    const uint8_t *payload = ccder_decode_tl(CCDER_BOOLEAN, &payload_size, der, der_end);
+
+    if (NULL == payload || (der_end - payload) < 1 || payload_size != 1) {
+        return NULL;
+    }
+
+    if (boolean)
+        *boolean = (*payload != 0);
+
+    return payload + payload_size;
+}
+
+
+static size_t ccder_sizeof_bool(bool value __unused, CFErrorRef *error)
+{
+    return ccder_sizeof(CCDER_BOOLEAN, 1);
+}
+
+
+static uint8_t* ccder_encode_bool(bool value, const uint8_t *der, uint8_t *der_end)
+{
+    uint8_t value_byte = value;
+
+    return ccder_encode_tl(CCDER_BOOLEAN, 1, der,
+           ccder_encode_body(1, &value_byte, der, der_end));
+}
+
+struct __OpaqueSOSAccount {
+    CFRuntimeBase           _base;
+
+    dispatch_queue_t        queue;
+
+    CFDictionaryRef         gestalt;
+
+    CFMutableDictionaryRef  circle_identities;
+    CFMutableDictionaryRef  circles;
+    CFMutableDictionaryRef  retired_peers;
+
+    bool      user_public_trusted;
+    CFDataRef user_key_parameters;
+    SecKeyRef user_public;
+    SecKeyRef previous_public;
+    enum DepartureReason    departure_code;
+
+    // Non-persistent data
+
+    SOSDataSourceFactoryRef factory;
+    SecKeyRef _user_private;
+    dispatch_source_t user_private_timer;
+    int               lock_notification_token;
+
+    // Live Notification
+    CFMutableArrayRef       change_blocks;
+
+    SOSAccountKeyInterestBlock        update_interest_block;
+    SOSAccountDataUpdateBlock         update_block;
+    SOSAccountMessageProcessedBlock   processed_message_block;
+
+    CFMutableDictionaryRef  deferred_updates;
+
+    CFMutableDictionaryRef  pending_changes;
+};
+
+CFGiblisWithCompareFor(SOSAccount);
+
+static inline bool SOSAccountHasLeft(SOSAccountRef account) {
+    switch(account->departure_code) {
+        case kSOSWithdrewMembership: /* Fallthrough */
+        case kSOSMembershipRevoked: /* Fallthrough */
+        case kSOSLeftUntrustedCircle:
+            return true;
+        case kSOSNeverAppliedToCircle: /* Fallthrough */
+        case kSOSNeverLeftCircle: /* Fallthrough */
+        default:
+            return false;
+    }
+}
+
+// Private static functions.
+
+static bool SOSUpdateKeyInterest(SOSAccountRef account, bool getNewKeysOnly, CFErrorRef *error);
+
+static bool SOSAccountEnsureFactoryCircles(SOSAccountRef a)
+{
+    bool result = false;
+    if (a)
+    {
+        require(a->factory, xit);
+        CFArrayRef circle_names = a->factory->copy_names(a->factory);
+        require(circle_names, xit);
+        CFArrayForEach(circle_names, ^(const void*name) {
+            if (isString(name))
+                SOSAccountEnsureCircle(a, (CFStringRef)name, NULL);
+        });
+
+        CFReleaseNull(circle_names);
+        result = true;
+    }
+xit:
+    return result;
+}
+
+static SOSAccountRef SOSAccountCreateBasic(CFAllocatorRef allocator,
+                                           CFDictionaryRef gestalt,
+                                           SOSDataSourceFactoryRef factory,
+                                           SOSAccountKeyInterestBlock interest_block,
+                                           SOSAccountDataUpdateBlock update_block) {
+    SOSAccountRef a = CFTypeAllocate(SOSAccount, struct __OpaqueSOSAccount, allocator);
+
+    a->queue = dispatch_queue_create("Account Queue", DISPATCH_QUEUE_SERIAL);
+
+    a->gestalt = gestalt;
+    CFRetain(a->gestalt);
+
+    a->circles = CFDictionaryCreateMutableForCFTypes(allocator);
+    a->circle_identities = CFDictionaryCreateMutableForCFTypes(allocator);
+    a->retired_peers = CFDictionaryCreateMutableForCFTypes(allocator);
+    
+    a->factory = factory; // We adopt the factory. kthanksbai.
+    
+    a->change_blocks = CFArrayCreateMutableForCFTypes(allocator);
+    
+    a->update_interest_block = Block_copy(interest_block);
+    a->update_block = Block_copy(update_block);
+
+    a->pending_changes = CFDictionaryCreateMutableForCFTypes(allocator);
+    a->departure_code = kSOSNeverAppliedToCircle;
+
+    return a;
+}
+
+
+static SOSFullPeerInfoRef SOSAccountGetMyFullPeerInCircleNamedIfPresent(SOSAccountRef account, CFStringRef name, CFErrorRef *error) {
+    if (CFDictionaryGetValue(account->circles, name) == NULL) {
+        SOSCreateErrorWithFormat(kSOSErrorNoCircle, NULL, error, NULL, CFSTR("No circle named '%@'"), name);
+        return NULL;
+    }
+    
+    return (SOSFullPeerInfoRef) CFDictionaryGetValue(account->circle_identities, name);
+}
+
+
+static void SOSAccountForEachKnownCircle(SOSAccountRef account,
+                                         void (^handle_incompatible)(CFStringRef name),
+                                         void (^handle_no_peer)(SOSCircleRef circle),
+                                         void (^handle_peer)(SOSCircleRef circle, SOSFullPeerInfoRef full_peer)) {
+    CFDictionaryForEach(account->circles, ^(const void *key, const void *value) {
+        if (isNull(value)) {
+            if (handle_incompatible)
+                handle_incompatible((CFStringRef)key);
+        } else {
+            SOSCircleRef circle = (SOSCircleRef) value;
+            CFRetainSafe(circle);
+            SOSFullPeerInfoRef fpi = SOSAccountGetMyFullPeerInCircleNamedIfPresent(account, SOSCircleGetName(circle), NULL);
+            if (!fpi) {
+                if (handle_no_peer)
+                    handle_no_peer(circle);
+            } else {
+                CFRetainSafe(fpi);
+                if (handle_peer)
+                    handle_peer(circle, fpi);
+                CFReleaseSafe(fpi);
+            }
+            CFReleaseSafe(circle);
+        }
+    });
+}
+
+
+bool SOSAccountUpdateGestalt(SOSAccountRef account, CFDictionaryRef new_gestalt)
+{
+    if (CFEqual(new_gestalt, account->gestalt))
+        return false;
+    
+    SOSAccountForEachKnownCircle(account, NULL, NULL, ^(SOSCircleRef circle, SOSFullPeerInfoRef full_peer) {
+        if (SOSFullPeerInfoUpdateGestalt(full_peer, new_gestalt, NULL)) {
+            SOSAccountModifyCircle(account, SOSCircleGetName(circle),
+                                   NULL, ^(SOSCircleRef circle_to_change) {
+                                       (void) SOSCircleUpdatePeerInfo(circle_to_change, SOSFullPeerInfoGetPeerInfo(full_peer));
+                                   });
+        };
+    });
+
+    CFReleaseNull(account->gestalt);
+    account->gestalt = new_gestalt;
+    CFRetain(account->gestalt);
+    
+    return true;
+}
+
+SOSAccountRef SOSAccountCreate(CFAllocatorRef allocator,
+                               CFDictionaryRef gestalt,
+                               SOSDataSourceFactoryRef factory,
+                               SOSAccountKeyInterestBlock interest_block,
+                               SOSAccountDataUpdateBlock update_block) {
+    SOSAccountRef a = SOSAccountCreateBasic(allocator, gestalt, factory, interest_block, update_block);
+
+    SOSAccountEnsureFactoryCircles(a);
+
+    return a;
+}
+
+static void SOSAccountDestroy(CFTypeRef aObj) {
+    SOSAccountRef a = (SOSAccountRef) aObj;
+
+    if (a->factory)
+        a->factory->release(a->factory);
+
+    CFReleaseNull(a->gestalt);
+    CFReleaseNull(a->circle_identities);
+    CFReleaseNull(a->circles);
+    CFReleaseNull(a->retired_peers);
+
+    a->user_public_trusted = false;
+    CFReleaseNull(a->user_public);
+    CFReleaseNull(a->user_key_parameters);
+
+    SOSAccountPurgePrivateCredential(a);
+    CFReleaseNull(a->previous_public);
+
+    CFReleaseNull(a->change_blocks);
+    Block_release(a->update_interest_block);
+    Block_release(a->update_block);
+    CFReleaseNull(a->processed_message_block);
+    CFReleaseNull(a->pending_changes);
+    CFReleaseNull(a->deferred_updates);
+    a->departure_code = kSOSNeverAppliedToCircle;
+
+    dispatch_release(a->queue);
+}
+
+static void SOSAccountSetToNew(SOSAccountRef a) {
+    CFAllocatorRef allocator = CFGetAllocator(a);
+    CFReleaseNull(a->circle_identities);
+    CFReleaseNull(a->circles);
+    CFReleaseNull(a->retired_peers);
+
+    CFReleaseNull(a->user_key_parameters);
+    CFReleaseNull(a->user_public);
+    CFReleaseNull(a->previous_public);
+    CFReleaseNull(a->_user_private);
+    
+    CFReleaseNull(a->pending_changes);
+    CFReleaseNull(a->deferred_updates);
+    
+    a->user_public_trusted = false;
+    a->departure_code = kSOSNeverAppliedToCircle;
+    a->user_private_timer = 0;
+    a->lock_notification_token = 0;
+    
+    // keeping gestalt;
+    // keeping factory;
+    // Live Notification
+    // change_blocks;
+    // update_interest_block;
+    // update_block;
+    
+    a->circles = CFDictionaryCreateMutableForCFTypes(allocator);
+    a->circle_identities = CFDictionaryCreateMutableForCFTypes(allocator);
+    a->retired_peers = CFDictionaryCreateMutableForCFTypes(allocator);
+    a->pending_changes = CFDictionaryCreateMutableForCFTypes(allocator);
+
+    SOSAccountEnsureFactoryCircles(a);
+}
+
+
+static CFStringRef SOSAccountCopyDescription(CFTypeRef aObj) {
+    SOSAccountRef a = (SOSAccountRef) aObj;
+    
+    return CFStringCreateWithFormat(NULL, NULL, CFSTR("<SOSAccount@%p: Gestalt: %@\n Circles: %@ CircleIDs: %@>"), a, a->gestalt, a->circles, a->circle_identities);
+}
+
+static Boolean SOSAccountCompare(CFTypeRef lhs, CFTypeRef rhs)
+{
+    SOSAccountRef laccount = (SOSAccountRef) lhs;
+    SOSAccountRef raccount = (SOSAccountRef) rhs;
+
+    return CFEqual(laccount->gestalt, raccount->gestalt)
+        && CFEqual(laccount->circles, raccount->circles)
+        && CFEqual(laccount->circle_identities, raccount->circle_identities);
+    //  ??? retired_peers
+}
+
+#if OLD_CODERS_SUPPORTED
+
+//
+// MARK: Persistent Encode decode
+//
+SOSAccountRef SOSAccountCreateFromDER_V1(CFAllocatorRef allocator,
+                                      SOSDataSourceFactoryRef factory,
+                                      SOSAccountKeyInterestBlock interest_block,
+                                      SOSAccountDataUpdateBlock update_block,
+                                      CFErrorRef* error,
+                                      const uint8_t** der_p, const uint8_t *der_end)
+{
+    SOSAccountRef account = NULL;
+
+    const uint8_t *sequence_end;
+    *der_p = ccder_decode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, &sequence_end, *der_p, der_end);
+
+    {
+        CFDictionaryRef decoded_gestalt = NULL;
+        *der_p = der_decode_dictionary(kCFAllocatorDefault, kCFPropertyListImmutable, &decoded_gestalt, error,
+                                       *der_p, der_end);
+
+        if (*der_p == 0)
+            return NULL;
+
+        account = SOSAccountCreateBasic(allocator, decoded_gestalt, factory, interest_block, update_block);
+        CFReleaseNull(decoded_gestalt);
+    }
+
+    CFArrayRef array = NULL;
+    *der_p = der_decode_array(kCFAllocatorDefault, 0, &array, error, *der_p, sequence_end);
+
+    *der_p = ccder_decode_bool(&account->user_public_trusted, *der_p, sequence_end);
+    *der_p = der_decode_public_bytes(kCFAllocatorDefault, kSecECDSAAlgorithmID, &account->user_public, error, *der_p, sequence_end);
+    *der_p = der_decode_data_or_null(kCFAllocatorDefault, &account->user_key_parameters, error, *der_p, sequence_end);
+    *der_p = der_decode_dictionary(kCFAllocatorDefault, kCFPropertyListMutableContainers, (CFDictionaryRef *) &account->retired_peers, error, *der_p, sequence_end);
+    if (*der_p != sequence_end)
+        *der_p = NULL;
+
+    __block bool success = true;
+
+    require_quiet(array && *der_p, fail);
+    
+    CFArrayForEach(array, ^(const void *value) {
+        if (success) {
+            if (isString(value)) {
+                CFDictionaryAddValue(account->circles, value, kCFNull);
+            } else {
+                CFDataRef circleData = NULL;
+                CFDataRef fullPeerInfoData = NULL;
+
+                if (isData(value)) {
+                    circleData = (CFDataRef) value;
+                } else if (isArray(value)) {
+                    CFArrayRef pair = (CFArrayRef) value;
+                    
+                    CFTypeRef circleObject = CFArrayGetValueAtIndex(pair, 0);
+                    CFTypeRef fullPeerInfoObject = CFArrayGetValueAtIndex(pair, 1);
+                    
+                    if (CFArrayGetCount(pair) == 2 && isData(circleObject) && isData(fullPeerInfoObject)) {
+                        circleData = (CFDataRef) circleObject;
+                        fullPeerInfoData = (CFDataRef) fullPeerInfoObject;
+                    }
+                }
+                
+                if (circleData) {
+                    SOSCircleRef circle = SOSCircleCreateFromData(kCFAllocatorDefault, circleData, error);
+                    require_action_quiet(circle, fail, success = false);
+                    
+                    CFStringRef circleName = SOSCircleGetName(circle);
+                    CFDictionaryAddValue(account->circles, circleName, circle);
+
+                    if (fullPeerInfoData) {
+                        SOSFullPeerInfoRef full_peer = SOSFullPeerInfoCreateFromData(kCFAllocatorDefault, fullPeerInfoData, error);
+                        require_action_quiet(full_peer, fail, success = false);
+                        
+                        CFDictionaryAddValue(account->circle_identities, circleName, full_peer);
+                        CFReleaseNull(full_peer);
+                    }
+                fail:
+                    CFReleaseNull(circle);
+                }
+            }
+        }
+    });
+    CFReleaseNull(array);
+    
+    require_quiet(success, fail);
+    require_action_quiet(SOSAccountEnsureFactoryCircles(account), fail,
+                         SOSCreateError(kSOSErrorBadFormat, CFSTR("Cannot EnsureFactoryCircles"), (error != NULL) ? *error : NULL, error));
+
+    return account;
+    
+fail:
+    // Create a default error if we don't have one:
+    SOSCreateError(kSOSErrorBadFormat, CFSTR("Bad Account DER"), NULL, error);
+    CFReleaseNull(account);
+    return NULL;
+}
+
+SOSAccountRef SOSAccountCreateFromDER_V2(CFAllocatorRef allocator,
+                                         SOSDataSourceFactoryRef factory,
+                                         SOSAccountKeyInterestBlock interest_block,
+                                         SOSAccountDataUpdateBlock update_block,
+                                         CFErrorRef* error,
+                                         const uint8_t** der_p, const uint8_t *der_end)
+{
+    SOSAccountRef account = NULL;
+    const uint8_t *dersave = *der_p;
+    const uint8_t *derend = der_end;
+
+    const uint8_t *sequence_end;
+    *der_p = ccder_decode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, &sequence_end, *der_p, der_end);
+
+    {
+        CFDictionaryRef decoded_gestalt = NULL;
+        *der_p = der_decode_dictionary(kCFAllocatorDefault, kCFPropertyListImmutable, &decoded_gestalt, error,
+                                       *der_p, der_end);
+
+        if (*der_p == 0)
+            return NULL;
+
+        account = SOSAccountCreateBasic(allocator, decoded_gestalt, factory, interest_block, update_block);
+        CFReleaseNull(decoded_gestalt);
+    }
+
+    CFArrayRef array = NULL;
+    *der_p = der_decode_array(kCFAllocatorDefault, 0, &array, error, *der_p, sequence_end);
+
+    uint64_t tmp_departure_code = kSOSNeverAppliedToCircle;
+    *der_p = ccder_decode_uint64(&tmp_departure_code, *der_p, sequence_end);
+    *der_p = ccder_decode_bool(&account->user_public_trusted, *der_p, sequence_end);
+    *der_p = der_decode_public_bytes(kCFAllocatorDefault, kSecECDSAAlgorithmID, &account->user_public, error, *der_p, sequence_end);
+    *der_p = der_decode_data_or_null(kCFAllocatorDefault, &account->user_key_parameters, error, *der_p, sequence_end);
+    *der_p = der_decode_dictionary(kCFAllocatorDefault, kCFPropertyListMutableContainers, (CFDictionaryRef *) &account->retired_peers, error, *der_p, sequence_end);
+    if (*der_p != sequence_end)
+        *der_p = NULL;
+    account->departure_code = (enum DepartureReason) tmp_departure_code;
+
+    __block bool success = true;
+
+    require_quiet(array && *der_p, fail);
+
+    CFArrayForEach(array, ^(const void *value) {
+        if (success) {
+            if (isString(value)) {
+                CFDictionaryAddValue(account->circles, value, kCFNull);
+            } else {
+                CFDataRef circleData = NULL;
+                CFDataRef fullPeerInfoData = NULL;
+
+                if (isData(value)) {
+                    circleData = (CFDataRef) value;
+                } else if (isArray(value)) {
+                    CFArrayRef pair = (CFArrayRef) value;
+
+                    CFTypeRef circleObject = CFArrayGetValueAtIndex(pair, 0);
+                    CFTypeRef fullPeerInfoObject = CFArrayGetValueAtIndex(pair, 1);
+
+                    if (CFArrayGetCount(pair) == 2 && isData(circleObject) && isData(fullPeerInfoObject)) {
+                        circleData = (CFDataRef) circleObject;
+                        fullPeerInfoData = (CFDataRef) fullPeerInfoObject;
+                    }
+                }
+
+                if (circleData) {
+                    SOSCircleRef circle = SOSCircleCreateFromData(kCFAllocatorDefault, circleData, error);
+                    require_action_quiet(circle, fail, success = false);
+
+                    CFStringRef circleName = SOSCircleGetName(circle);
+                    CFDictionaryAddValue(account->circles, circleName, circle);
+
+                    if (fullPeerInfoData) {
+                        SOSFullPeerInfoRef full_peer = SOSFullPeerInfoCreateFromData(kCFAllocatorDefault, fullPeerInfoData, error);
+                        require_action_quiet(full_peer, fail, success = false);
+
+                        CFDictionaryAddValue(account->circle_identities, circleName, full_peer);
+                    }
+                fail:
+                    CFReleaseNull(circle);
+                }
+            }
+        }
+    });
+    CFReleaseNull(array);
+
+    require_quiet(success, fail);
+    require_action_quiet(SOSAccountEnsureFactoryCircles(account), fail,
+                         SOSCreateError(kSOSErrorBadFormat, CFSTR("Cannot EnsureFactoryCircles"), (error != NULL) ? *error : NULL, error));
+
+    return account;
+
+fail:
+    // Create a default error if we don't have one:
+    account->factory = NULL; // give the factory back.
+    CFReleaseNull(account);
+    // Try the der inflater from the previous release.
+    account = SOSAccountCreateFromDER_V1(allocator, factory, interest_block, update_block, error, &dersave, derend);
+    if(account) account->departure_code = kSOSNeverAppliedToCircle;
+    return account;
+}
+
+#endif /* OLD_CODERS_SUPPORTED */
+
+#define CURRENT_ACCOUNT_PERSISTENT_VERSION 6
+
+SOSAccountRef SOSAccountCreateFromDER(CFAllocatorRef allocator,
+                                         SOSDataSourceFactoryRef factory,
+                                         SOSAccountKeyInterestBlock interest_block,
+                                         SOSAccountDataUpdateBlock update_block,
+                                         CFErrorRef* error,
+                                         const uint8_t** der_p, const uint8_t *der_end)
+{
+    SOSAccountRef account = NULL;
+#if UPGRADE_FROM_PREVIOUS_VERSION
+    const uint8_t *dersave = *der_p;
+    const uint8_t *derend = der_end;
+#endif
+    uint64_t version = 0;
+    
+    const uint8_t *sequence_end;
+    *der_p = ccder_decode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, &sequence_end, *der_p, der_end);
+    *der_p = ccder_decode_uint64(&version, *der_p, sequence_end);
+    if(!(*der_p) || version < CURRENT_ACCOUNT_PERSISTENT_VERSION) {
+#if UPGRADE_FROM_PREVIOUS_VERSION
+        return SOSAccountCreateFromDER_V3(allocator, factory, interest_block, update_block, error, &dersave, derend);
+#else
+        return NULL;
+#endif
+    }
+    
+    {
+        CFDictionaryRef decoded_gestalt = NULL;
+        *der_p = der_decode_dictionary(kCFAllocatorDefault, kCFPropertyListImmutable, &decoded_gestalt, error,
+                                       *der_p, der_end);
+        
+        if (*der_p == 0)
+            return NULL;
+        
+        account = SOSAccountCreateBasic(allocator, decoded_gestalt, factory, interest_block, update_block);
+        CFReleaseNull(decoded_gestalt);
+    }
+    
+    CFArrayRef array = NULL;
+    *der_p = der_decode_array(kCFAllocatorDefault, 0, &array, error, *der_p, sequence_end);
+    
+    uint64_t tmp_departure_code = kSOSNeverAppliedToCircle;
+    *der_p = ccder_decode_uint64(&tmp_departure_code, *der_p, sequence_end);
+    *der_p = ccder_decode_bool(&account->user_public_trusted, *der_p, sequence_end);
+    *der_p = der_decode_public_bytes(kCFAllocatorDefault, kSecECDSAAlgorithmID, &account->user_public, error, *der_p, sequence_end);
+    *der_p = der_decode_public_bytes(kCFAllocatorDefault, kSecECDSAAlgorithmID, &account->previous_public, error, *der_p, sequence_end);
+    *der_p = der_decode_data_or_null(kCFAllocatorDefault, &account->user_key_parameters, error, *der_p, sequence_end);
+    *der_p = der_decode_dictionary(kCFAllocatorDefault, kCFPropertyListMutableContainers, (CFDictionaryRef *) &account->retired_peers, error, *der_p, sequence_end);
+    if (*der_p != sequence_end)
+        *der_p = NULL;
+    account->departure_code = (enum DepartureReason) tmp_departure_code;
+    
+    __block bool success = true;
+    
+    require_quiet(array && *der_p, fail);
+    
+    CFArrayForEach(array, ^(const void *value) {
+        if (success) {
+            if (isString(value)) {
+                CFDictionaryAddValue(account->circles, value, kCFNull);
+            } else {
+                CFDataRef circleData = NULL;
+                CFDataRef fullPeerInfoData = NULL;
+                
+                if (isData(value)) {
+                    circleData = (CFDataRef) value;
+                } else if (isArray(value)) {
+                    CFArrayRef pair = (CFArrayRef) value;
+                    
+                    CFTypeRef circleObject = CFArrayGetValueAtIndex(pair, 0);
+                    CFTypeRef fullPeerInfoObject = CFArrayGetValueAtIndex(pair, 1);
+                    
+                    if (CFArrayGetCount(pair) == 2 && isData(circleObject) && isData(fullPeerInfoObject)) {
+                        circleData = (CFDataRef) circleObject;
+                        fullPeerInfoData = (CFDataRef) fullPeerInfoObject;
+                    }
+                }
+                
+                if (circleData) {
+                    SOSCircleRef circle = SOSCircleCreateFromData(kCFAllocatorDefault, circleData, error);
+                    require_action_quiet(circle, fail, success = false);
+                    
+                    CFStringRef circleName = SOSCircleGetName(circle);
+                    CFDictionaryAddValue(account->circles, circleName, circle);
+                    
+                    if (fullPeerInfoData) {
+                        SOSFullPeerInfoRef full_peer = SOSFullPeerInfoCreateFromData(kCFAllocatorDefault, fullPeerInfoData, error);
+                        require_action_quiet(full_peer, fail, success = false);
+                        
+                        CFDictionaryAddValue(account->circle_identities, circleName, full_peer);
+                    }
+                fail:
+                    CFReleaseNull(circle);
+                }
+            }
+        }
+    });
+    CFReleaseNull(array);
+    
+    require_quiet(success, fail);
+    require_action_quiet(SOSAccountEnsureFactoryCircles(account), fail,
+                         SOSCreateError(kSOSErrorBadFormat, CFSTR("Cannot EnsureFactoryCircles"), (error != NULL) ? *error : NULL, error));
+    
+    return account;
+    
+fail:
+    account->factory = NULL; // give the factory back.
+    CFReleaseNull(account);
+    return NULL;
+}
+
+
+SOSAccountRef SOSAccountCreateFromDER_V3(CFAllocatorRef allocator,
+                                         SOSDataSourceFactoryRef factory,
+                                         SOSAccountKeyInterestBlock interest_block,
+                                         SOSAccountDataUpdateBlock update_block,
+                                         CFErrorRef* error,
+                                         const uint8_t** der_p, const uint8_t *der_end)
+{
+    SOSAccountRef account = NULL;
+    uint64_t version = 0;
+    
+    const uint8_t *sequence_end;
+    *der_p = ccder_decode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, &sequence_end, *der_p, der_end);
+    *der_p = ccder_decode_uint64(&version, *der_p, sequence_end);
+    if(!(*der_p) || version != 3) {
+        // In this case we want to silently fail so that an account gets newly created.
+        return NULL;
+    }
+
+    {
+        CFDictionaryRef decoded_gestalt = NULL;
+        *der_p = der_decode_dictionary(kCFAllocatorDefault, kCFPropertyListImmutable, &decoded_gestalt, error,
+                                       *der_p, der_end);
+        
+        if (*der_p == 0)
+            return NULL;
+        
+        account = SOSAccountCreateBasic(allocator, decoded_gestalt, factory, interest_block, update_block);
+        CFReleaseNull(decoded_gestalt);
+    }
+    
+    CFArrayRef array = NULL;
+    *der_p = der_decode_array(kCFAllocatorDefault, 0, &array, error, *der_p, sequence_end);
+    
+    uint64_t tmp_departure_code = kSOSNeverAppliedToCircle;
+    *der_p = ccder_decode_uint64(&tmp_departure_code, *der_p, sequence_end);
+    *der_p = ccder_decode_bool(&account->user_public_trusted, *der_p, sequence_end);
+    *der_p = der_decode_public_bytes(kCFAllocatorDefault, kSecECDSAAlgorithmID, &account->user_public, error, *der_p, sequence_end);
+    *der_p = der_decode_data_or_null(kCFAllocatorDefault, &account->user_key_parameters, error, *der_p, sequence_end);
+    *der_p = der_decode_dictionary(kCFAllocatorDefault, kCFPropertyListMutableContainers, (CFDictionaryRef *) &account->retired_peers, error, *der_p, sequence_end);
+    if (*der_p != sequence_end)
+        *der_p = NULL;
+    account->departure_code = (enum DepartureReason) tmp_departure_code;
+    
+    __block bool success = true;
+    
+    require_quiet(array && *der_p, fail);
+    
+    CFArrayForEach(array, ^(const void *value) {
+        if (success) {
+            if (isString(value)) {
+                CFDictionaryAddValue(account->circles, value, kCFNull);
+            } else {
+                CFDataRef circleData = NULL;
+                CFDataRef fullPeerInfoData = NULL;
+                
+                if (isData(value)) {
+                    circleData = (CFDataRef) value;
+                } else if (isArray(value)) {
+                    CFArrayRef pair = (CFArrayRef) value;
+                    
+                    CFTypeRef circleObject = CFArrayGetValueAtIndex(pair, 0);
+                    CFTypeRef fullPeerInfoObject = CFArrayGetValueAtIndex(pair, 1);
+                    
+                    if (CFArrayGetCount(pair) == 2 && isData(circleObject) && isData(fullPeerInfoObject)) {
+                        circleData = (CFDataRef) circleObject;
+                        fullPeerInfoData = (CFDataRef) fullPeerInfoObject;
+                    }
+                }
+                
+                if (circleData) {
+                    SOSCircleRef circle = SOSCircleCreateFromData(kCFAllocatorDefault, circleData, error);
+                    require_action_quiet(circle, fail, success = false);
+                    
+                    CFStringRef circleName = SOSCircleGetName(circle);
+                    CFDictionaryAddValue(account->circles, circleName, circle);
+                    
+                    if (fullPeerInfoData) {
+                        SOSFullPeerInfoRef full_peer = SOSFullPeerInfoCreateFromData(kCFAllocatorDefault, fullPeerInfoData, error);
+                        require_action_quiet(full_peer, fail, success = false);
+                        
+                        CFDictionaryAddValue(account->circle_identities, circleName, full_peer);
+                    }
+                fail:
+                    CFReleaseNull(circle);
+                }
+            }
+        }
+    });
+    CFReleaseNull(array);
+    
+    require_quiet(success, fail);
+    require_action_quiet(SOSAccountEnsureFactoryCircles(account), fail,
+                         SOSCreateError(kSOSErrorBadFormat, CFSTR("Cannot EnsureFactoryCircles"), (error != NULL) ? *error : NULL, error));
+    
+    return account;
+    
+fail:
+    // Create a default error if we don't have one:
+    account->factory = NULL; // give the factory back.
+    CFReleaseNull(account);
+    // Don't try the der inflater from the previous release.
+    // account = SOSAccountCreateFromDER_V2(allocator, factory, interest_block, update_block, error, &dersave, derend);
+    if(account) account->departure_code = kSOSNeverAppliedToCircle;
+    return account;
+}
+
+SOSAccountRef SOSAccountCreateFromData(CFAllocatorRef allocator, CFDataRef circleData,
+                                       SOSDataSourceFactoryRef factory,
+                                       SOSAccountKeyInterestBlock interest_block,
+                                       SOSAccountDataUpdateBlock update_block,
+                                       CFErrorRef* error)
+{
+    size_t size = CFDataGetLength(circleData);
+    const uint8_t *der = CFDataGetBytePtr(circleData);
+    SOSAccountRef account = SOSAccountCreateFromDER(allocator, factory, interest_block, update_block,
+                                                    error,
+                                                    &der, der + size);
+    return account;
+}
+
+static CFMutableArrayRef SOSAccountCopyCircleArrayToEncode(SOSAccountRef account)
+{
+    CFMutableArrayRef arrayToEncode = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
+
+    CFDictionaryForEach(account->circles, ^(const void *key, const void *value) {
+        if (isNull(value)) {
+            CFArrayAppendValue(arrayToEncode, key); // Encode the name of the circle that's out of date.
+        } else {
+            SOSCircleRef circle = (SOSCircleRef) value;
+            CFDataRef encodedCircle = SOSCircleCopyEncodedData(circle, kCFAllocatorDefault, NULL);
+            CFTypeRef arrayEntry = encodedCircle;
+            CFRetainSafe(arrayEntry);
+            
+            SOSFullPeerInfoRef full_peer = (SOSFullPeerInfoRef) CFDictionaryGetValue(account->circle_identities, key);
+        
+            if (full_peer) {
+                CFDataRef encodedPeer = SOSFullPeerInfoCopyEncodedData(full_peer, kCFAllocatorDefault, NULL);
+                CFTypeRef originalArrayEntry = arrayEntry;
+                arrayEntry = CFArrayCreateForCFTypes(kCFAllocatorDefault, encodedCircle, encodedPeer, NULL);
+                
+                CFReleaseSafe(originalArrayEntry);
+                CFReleaseNull(encodedPeer);
+            }
+            
+            CFArrayAppendValue(arrayToEncode, arrayEntry);
+
+            CFReleaseSafe(arrayEntry);
+            CFReleaseNull(encodedCircle);
+        }
+               
+    });
+
+    return arrayToEncode;
+}
+
+size_t SOSAccountGetDEREncodedSize(SOSAccountRef account, CFErrorRef *error)
+{
+    size_t sequence_size = 0;
+    CFMutableArrayRef arrayToEncode = SOSAccountCopyCircleArrayToEncode(account);
+    uint64_t version = CURRENT_ACCOUNT_PERSISTENT_VERSION;
+    
+    require_quiet(accumulate_size(&sequence_size, ccder_sizeof_uint64(version)),                                    fail);
+    require_quiet(accumulate_size(&sequence_size, der_sizeof_dictionary(account->gestalt, error)),                  fail);
+    require_quiet(accumulate_size(&sequence_size, der_sizeof_array(arrayToEncode, error)),                          fail);
+    require_quiet(accumulate_size(&sequence_size, ccder_sizeof_uint64(account->departure_code)),                    fail);
+    require_quiet(accumulate_size(&sequence_size, ccder_sizeof_bool(account->user_public_trusted, error)),          fail);
+    require_quiet(accumulate_size(&sequence_size, der_sizeof_public_bytes(account->user_public, error)),            fail);
+    require_quiet(accumulate_size(&sequence_size, der_sizeof_public_bytes(account->previous_public, error)),        fail);
+    require_quiet(accumulate_size(&sequence_size, der_sizeof_data_or_null(account->user_key_parameters, error)),    fail);
+    require_quiet(accumulate_size(&sequence_size, der_sizeof_dictionary(account->retired_peers, error)),            fail);
+    
+    CFReleaseNull(arrayToEncode);
+    return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, sequence_size);
+    
+fail:
+    CFReleaseNull(arrayToEncode);
+    SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("don't know how to encode"), NULL, error);
+    return 0;
+}
+
+uint8_t* SOSAccountEncodeToDER(SOSAccountRef account, CFErrorRef* error, const uint8_t* der, uint8_t* der_end)
+{
+    CFMutableArrayRef arrayToEncode = SOSAccountCopyCircleArrayToEncode(account);
+    uint64_t version = CURRENT_ACCOUNT_PERSISTENT_VERSION;
+    der_end =  ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der,
+        ccder_encode_uint64(version, der,
+        der_encode_dictionary(account->gestalt, error, der,
+        der_encode_array(arrayToEncode, error, der,
+        ccder_encode_uint64(account->departure_code, der,
+        ccder_encode_bool(account->user_public_trusted, der,
+        der_encode_public_bytes(account->user_public, error, der,
+        der_encode_public_bytes(account->previous_public, error, der,
+        der_encode_data_or_null(account->user_key_parameters, error, der,
+        der_encode_dictionary(account->retired_peers, error, der, der_end))))))))));
+
+    CFReleaseNull(arrayToEncode);
+    
+    return der_end;
+}
+
+
+
+size_t SOSAccountGetDEREncodedSize_V3(SOSAccountRef account, CFErrorRef *error)
+{
+    size_t sequence_size = 0;
+    CFMutableArrayRef arrayToEncode = SOSAccountCopyCircleArrayToEncode(account);
+    uint64_t version = CURRENT_ACCOUNT_PERSISTENT_VERSION;
+
+    require_quiet(accumulate_size(&sequence_size, ccder_sizeof_uint64(version)),                                    fail);
+    require_quiet(accumulate_size(&sequence_size, der_sizeof_dictionary(account->gestalt, error)),                  fail);
+    require_quiet(accumulate_size(&sequence_size, der_sizeof_array(arrayToEncode, error)),                          fail);
+    require_quiet(accumulate_size(&sequence_size, ccder_sizeof_uint64(account->departure_code)),                    fail);
+    require_quiet(accumulate_size(&sequence_size, ccder_sizeof_bool(account->user_public_trusted, error)),          fail);
+    require_quiet(accumulate_size(&sequence_size, der_sizeof_public_bytes(account->user_public, error)),            fail);
+    require_quiet(accumulate_size(&sequence_size, der_sizeof_data_or_null(account->user_key_parameters, error)),    fail);
+    require_quiet(accumulate_size(&sequence_size, der_sizeof_dictionary(account->retired_peers, error)),            fail);
+    
+    CFReleaseNull(arrayToEncode);
+    return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, sequence_size);
+    
+fail:
+    CFReleaseNull(arrayToEncode);
+    SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("don't know how to encode"), NULL, error);
+    return 0;
+}
+
+uint8_t* SOSAccountEncodeToDER_V3(SOSAccountRef account, CFErrorRef* error, const uint8_t* der, uint8_t* der_end)
+{
+    CFMutableArrayRef arrayToEncode = SOSAccountCopyCircleArrayToEncode(account);
+    uint64_t version = 3;
+    der_end =  ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der,
+        ccder_encode_uint64(version, der,
+        der_encode_dictionary(account->gestalt, error, der,
+        der_encode_array(arrayToEncode, error, der,
+        ccder_encode_uint64(account->departure_code, der,
+        ccder_encode_bool(account->user_public_trusted, der,
+        der_encode_public_bytes(account->user_public, error, der,
+        der_encode_data_or_null(account->user_key_parameters, error, der,
+        der_encode_dictionary(account->retired_peers, error, der, der_end)))))))));
+    
+    CFReleaseNull(arrayToEncode);
+    
+    return der_end;
+}
+
+#if OLD_CODERS_SUPPORTED
+
+/* Original V2 encoders */
+
+size_t SOSAccountGetDEREncodedSize_V2(SOSAccountRef account, CFErrorRef *error)
+{
+    size_t sequence_size = 0;
+    CFMutableArrayRef arrayToEncode = SOSAccountCopyCircleArrayToEncode(account);
+
+    require_quiet(accumulate_size(&sequence_size, der_sizeof_dictionary(account->gestalt, error)),                  fail);
+    require_quiet(accumulate_size(&sequence_size, der_sizeof_array(arrayToEncode, error)),                          fail);
+    require_quiet(accumulate_size(&sequence_size, ccder_sizeof_uint64(account->departure_code)), fail);
+    require_quiet(accumulate_size(&sequence_size, ccder_sizeof_bool(account->user_public_trusted, error)),          fail);
+    require_quiet(accumulate_size(&sequence_size, der_sizeof_public_bytes(account->user_public, error)),            fail);
+    require_quiet(accumulate_size(&sequence_size, der_sizeof_data_or_null(account->user_key_parameters, error)),    fail);
+    require_quiet(accumulate_size(&sequence_size, der_sizeof_dictionary(account->retired_peers, error)),            fail);
+
+    CFReleaseNull(arrayToEncode);
+    return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, sequence_size);
+
+fail:
+    CFReleaseNull(arrayToEncode);
+    SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("don't know how to encode"), NULL, error);
+    return 0;
+}
+
+uint8_t* SOSAccountEncodeToDER_V2(SOSAccountRef account, CFErrorRef* error, const uint8_t* der, uint8_t* der_end)
+{
+    CFMutableArrayRef arrayToEncode = SOSAccountCopyCircleArrayToEncode(account);
+
+    der_end =  ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der,
+               der_encode_dictionary(account->gestalt, error, der,
+               der_encode_array(arrayToEncode, error, der,
+               ccder_encode_uint64(account->departure_code, der,
+               ccder_encode_bool(account->user_public_trusted, der,
+               der_encode_public_bytes(account->user_public, error, der,
+               der_encode_data_or_null(account->user_key_parameters, error, der,
+               der_encode_dictionary(account->retired_peers, error, der, der_end))))))));
+
+    CFReleaseNull(arrayToEncode);
+
+    return der_end;
+}
+
+
+/* Original V1 encoders */
+
+
+size_t SOSAccountGetDEREncodedSize_V1(SOSAccountRef account, CFErrorRef *error)
+{
+    size_t sequence_size = 0;
+    CFMutableArrayRef arrayToEncode = SOSAccountCopyCircleArrayToEncode(account);
+
+    require_quiet(accumulate_size(&sequence_size, der_sizeof_dictionary(account->gestalt, error)),                  fail);
+    require_quiet(accumulate_size(&sequence_size, der_sizeof_array(arrayToEncode, error)),                          fail);
+    require_quiet(accumulate_size(&sequence_size, ccder_sizeof_bool(account->user_public_trusted, error)),          fail);
+    require_quiet(accumulate_size(&sequence_size, der_sizeof_public_bytes(account->user_public, error)),            fail);
+    require_quiet(accumulate_size(&sequence_size, der_sizeof_data_or_null(account->user_key_parameters, error)),    fail);
+    require_quiet(accumulate_size(&sequence_size, der_sizeof_dictionary(account->retired_peers, error)),            fail);
+
+    CFReleaseNull(arrayToEncode);
+    return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, sequence_size);
+
+fail:
+    CFReleaseNull(arrayToEncode);
+    SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("don't know how to encode"), NULL, error);
+    return 0;
+}
+
+uint8_t* SOSAccountEncodeToDER_V1(SOSAccountRef account, CFErrorRef* error, const uint8_t* der, uint8_t* der_end)
+{
+    CFMutableArrayRef arrayToEncode = SOSAccountCopyCircleArrayToEncode(account);
+
+    der_end =  ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der,
+        der_encode_dictionary(account->gestalt, error, der,
+        der_encode_array(arrayToEncode, error, der,
+        ccder_encode_bool(account->user_public_trusted, der,
+        der_encode_public_bytes(account->user_public, error, der,
+        der_encode_data_or_null(account->user_key_parameters, error, der,
+               der_encode_dictionary(account->retired_peers, error, der, der_end)))))));
+
+    CFReleaseNull(arrayToEncode);
+
+    return der_end;
+}
+#endif /* OLD_CODERS_SUPPORTED */
+
+/************************/
+
+CFDataRef SOSAccountCopyEncodedData(SOSAccountRef account, CFAllocatorRef allocator, CFErrorRef *error)
+{
+    size_t size = SOSAccountGetDEREncodedSize(account, error);
+    if (size == 0)
+        return NULL;
+    uint8_t buffer[size];
+    uint8_t* start = SOSAccountEncodeToDER(account, error, buffer, buffer + sizeof(buffer));
+    CFDataRef result = CFDataCreate(kCFAllocatorDefault, start, size);
+    return result;
+}
+
+dispatch_queue_t SOSAccountGetQueue(SOSAccountRef account) {
+    return account->queue;
+}
+
+//
+// MARK: User Credential management
+//
+
+void SOSAccountPurgePrivateCredential(SOSAccountRef account)
+{
+    CFReleaseNull(account->_user_private);
+    if (account->user_private_timer) {
+        dispatch_source_cancel(account->user_private_timer);
+        dispatch_release(account->user_private_timer);
+        account->user_private_timer = NULL;
+        xpc_transaction_end();
+    }
+    if (account->lock_notification_token) {
+        notify_cancel(account->lock_notification_token);
+        account->lock_notification_token = 0;
+    }
+}
+
+static void SOSAccountSetPrivateCredential(SOSAccountRef account, SecKeyRef private) {
+    if (!private)
+        return SOSAccountPurgePrivateCredential(account);
+
+    CFRetain(private);
+    CFReleaseSafe(account->_user_private);
+    account->_user_private = private;
+
+    bool resume_timer = false;
+    if (!account->user_private_timer) {
+        xpc_transaction_begin();
+        resume_timer = true;
+        account->user_private_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, account->queue);
+        dispatch_source_set_event_handler(account->user_private_timer, ^{
+            SOSAccountPurgePrivateCredential(account);
+        });
+
+        notify_register_dispatch(kUserKeybagStateChangeNotification, &account->lock_notification_token, account->queue, ^(int token) {
+            bool locked = false;
+            CFErrorRef lockCheckError = NULL;
+
+            if (!SecAKSGetIsLocked(&locked, &lockCheckError)) {
+                secerror("Checking for locked after change failed: %@", lockCheckError);
+            }
+
+            if (locked) {
+                SOSAccountPurgePrivateCredential(account);
+            }
+        });
+    }
+
+    // (Re)set the timer's fire time to now + 120 seconds with a 5 second fuzz factor.
+    dispatch_time_t purgeTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * 60 * NSEC_PER_SEC));
+    dispatch_source_set_timer(account->user_private_timer, purgeTime, DISPATCH_TIME_FOREVER, (int64_t)(5 * NSEC_PER_SEC));
+    if (resume_timer)
+        dispatch_resume(account->user_private_timer);
+}
+
+SecKeyRef SOSAccountGetPrivateCredential(SOSAccountRef account, CFErrorRef* error)
+{
+    if (account->_user_private == NULL) {
+        SOSCreateError(kSOSErrorPrivateKeyAbsent, CFSTR("Private Key not available - failed to prompt user recently"), NULL, error);
+    }
+    return account->_user_private;
+}
+
+static bool SOSAccountHasPublicKey(SOSAccountRef account, CFErrorRef* error)
+{
+    if (account->user_public == NULL || account->user_public_trusted == false) {
+        SOSCreateError(kSOSErrorPublicKeyAbsent, CFSTR("Public Key not available - failed to register before call"), NULL, error);
+        return false;
+    }
+
+    return true;
+}
+
+static bool SOSAccountIsMyPeerActiveInCircle(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error);
+
+static void SOSAccountGenerationSignatureUpdate(SOSAccountRef account, SecKeyRef privKey) {
+    SOSAccountForEachCircle(account, ^(SOSCircleRef circle) {
+        SOSFullPeerInfoRef fpi = SOSAccountGetMyFullPeerInCircle(account, circle, NULL);
+        if(SOSCircleHasPeer(circle, SOSFullPeerInfoGetPeerInfo(fpi), NULL) &&
+           !SOSCircleVerify(circle, account->user_public, NULL)) {
+            SOSAccountModifyCircle(account, SOSCircleGetName(circle), NULL, ^(SOSCircleRef circle) {
+                SOSFullPeerInfoRef cloud_fpi = SOSCircleGetiCloudFullPeerInfoRef(circle);
+                require_quiet(cloud_fpi != NULL, gen_sign);
+                require_quiet(SOSFullPeerInfoUpgradeSignatures(cloud_fpi, privKey, NULL), gen_sign);
+                if(!SOSCircleUpdatePeerInfo(circle, SOSFullPeerInfoGetPeerInfo(cloud_fpi))) {
+                }
+            gen_sign: // finally generation sign this.
+                SOSCircleGenerationSign(circle, privKey, fpi, NULL);
+                account->departure_code = kSOSNeverLeftCircle;
+            });
+        }
+    });
+}
+
+/* this one is meant to be local - not published over KVS. */
+static void SOSAccountPeerSignatureUpdate(SOSAccountRef account, SecKeyRef privKey) {
+    SOSAccountForEachCircle(account, ^(SOSCircleRef circle) {
+        SOSFullPeerInfoRef fpi = SOSAccountGetMyFullPeerInCircle(account, circle, NULL);
+        SOSFullPeerInfoUpgradeSignatures(fpi, privKey, NULL);
+    });
+}
+
+static void SOSAccountSetPreviousPublic(SOSAccountRef account) {
+    CFReleaseNull(account->previous_public);
+    account->previous_public = account->user_public;
+    CFRetain(account->previous_public);
+}
+
+static void SOSAccountSetTrustedUserPublicKey(SOSAccountRef account, bool public_was_trusted, SecKeyRef privKey)
+{
+    if (!privKey) return;
+    SecKeyRef publicKey = SecKeyCreatePublicFromPrivate(privKey);
+
+    if (account->user_public && account->user_public_trusted && CFEqual(publicKey, account->user_public)) return;
+
+    if(public_was_trusted && account->user_public) {
+        CFReleaseNull(account->previous_public);
+        account->previous_public = account->user_public;
+        CFRetain(account->previous_public);
+    }
+    
+    CFReleaseNull(account->user_public);
+    account->user_public = publicKey;
+    account->user_public_trusted = true;
+    
+    if(!account->previous_public) {
+        account->previous_public = account->user_public;
+        CFRetain(account->previous_public);
+    }
+
+       secnotice("trust", "trusting new public key: %@", account->user_public);
+}
+
+static void SOSAccountProcessDeferredUpdates(SOSAccountRef account) {
+    CFErrorRef error = NULL;
+    if (account->deferred_updates && !SOSAccountHandleUpdates(account, account->deferred_updates, &error))
+        secerror("Failed to handle updates when setting public key (%@)", error);
+
+    CFReleaseNull(account->deferred_updates);
+}
+
+
+bool SOSAccountTryUserCredentials(SOSAccountRef account, CFStringRef user_account __unused, CFDataRef user_password, CFErrorRef *error)
+{
+    bool success = false;
+
+    if (!SOSAccountHasPublicKey(account, error))
+        return false;
+    
+    if (account->user_key_parameters) {
+        SecKeyRef new_key = SOSUserKeygen(user_password, account->user_key_parameters, error);
+        if (new_key) {
+            SecKeyRef new_public_key = SecKeyCreatePublicFromPrivate(new_key);
+
+            if (CFEqualSafe(new_public_key, account->user_public)) {
+                SOSAccountSetPrivateCredential(account, new_key);
+                success = true;
+            } else {
+                SOSCreateError(kSOSErrorWrongPassword, CFSTR("Password passed in incorrect: ▇█████▇▇██"), NULL, error);
+            }
+            CFReleaseSafe(new_public_key);
+            CFReleaseSafe(new_key);
+        }
+    } else {
+        SOSCreateError(kSOSErrorProcessingFailure, CFSTR("Have public key but no parameters??"), NULL, error);
+    }
+
+    return success;
+}
+
+static bool SOSAccountPublishCloudParameters(SOSAccountRef account, CFErrorRef* error)
+{
+    bool success = false;
+    CFMutableDataRef cloudParameters = CFDataCreateMutableWithScratch(kCFAllocatorDefault,
+                                                                      der_sizeof_cloud_parameters(account->user_public,
+                                                                                                  account->user_key_parameters,
+                                                                                                  error));
+    if (der_encode_cloud_parameters(account->user_public, account->user_key_parameters, error,
+                                    CFDataGetMutableBytePtr(cloudParameters),
+                                    CFDataGetMutablePastEndPtr(cloudParameters)) != NULL) {
+
+        CFDictionaryRef changes = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
+                                                               kSOSKVSKeyParametersKey, cloudParameters,
+                                                               NULL);
+
+        CFErrorRef changeError = NULL;
+        if (account->update_block(changes, &changeError)) {
+            success = true;
+        } else {
+            SOSCreateErrorWithFormat(kSOSErrorSendFailure, changeError, error, NULL,
+                                     CFSTR("update parameters key failed [%@]"), changes);
+        }
+        CFReleaseSafe(changes);
+        CFReleaseSafe(changeError);
+    } else {
+        SOSCreateError(kSOSErrorEncodeFailure, CFSTR("Encoding parameters failed"), NULL, error);
+    }
+
+    CFReleaseNull(cloudParameters);
+
+    return success;
+}
+
+bool SOSAccountAssertUserCredentials(SOSAccountRef account, CFStringRef user_account __unused, CFDataRef user_password, CFErrorRef *error)
+{
+    bool public_was_trusted = account->user_public_trusted;
+    account->user_public_trusted = false;
+    SecKeyRef user_private = NULL;
+
+    if (account->user_public && account->user_key_parameters) {
+        // We have an untrusted public key – see if our generation makes the same key:
+        // if so we trust it and we have the private key.
+        // if not we still don't trust it.
+        require_quiet(user_private = SOSUserKeygen(user_password, account->user_key_parameters, error), exit);
+        SecKeyRef public_candidate = SecKeyCreatePublicFromPrivate(user_private);
+        if (!CFEqualSafe(account->user_public, public_candidate)) {
+            secnotice("trust", "Public keys don't match:  calculated: %@, expected: %@",
+                      account->user_public, public_candidate);
+            debugDumpUserParameters(CFSTR("params"), account->user_key_parameters);
+            CFReleaseNull(user_private);
+        } else {
+            SOSAccountPeerSignatureUpdate(account, user_private);
+            SOSAccountSetTrustedUserPublicKey(account, public_was_trusted, user_private);
+        }
+        CFReleaseSafe(public_candidate);
+    }
+
+    if (!account->user_public_trusted) {
+        // We may or may not have parameters here.
+        // In any case we tried using them and they didn't match
+        // So forget all that and start again, assume we're the first to push anything useful.
+        
+        CFReleaseNull(account->user_key_parameters);
+        account->user_key_parameters = SOSUserKeyCreateGenerateParameters(error);
+        require_quiet(user_private = SOSUserKeygen(user_password, account->user_key_parameters, error), exit);
+
+        SOSAccountPeerSignatureUpdate(account, user_private);
+        SOSAccountSetTrustedUserPublicKey(account, public_was_trusted, user_private);
+
+        CFErrorRef publishError = NULL;
+        if (!SOSAccountPublishCloudParameters(account, &publishError))
+            secerror("Failed to publish new cloud parameters: %@", publishError);
+        CFReleaseSafe(publishError);
+    }
+
+    SOSAccountProcessDeferredUpdates(account);
+    SOSAccountGenerationSignatureUpdate(account, user_private);
+    SOSAccountSetPrivateCredential(account, user_private);
+exit:
+    CFReleaseSafe(user_private);
+
+    return account->user_public_trusted;
+}
+
+//
+// MARK: Circle management
+//
+
+int SOSAccountCountCircles(SOSAccountRef a) {
+    assert(a);
+    assert(a->circle_identities);
+    assert(a->circles);
+    return (int)CFDictionaryGetCount(a->circles);
+}
+
+static SecKeyRef GeneratePermanentFullECKey_internal(int keySize, CFStringRef name, CFTypeRef accessibility, CFBooleanRef sync,  CFErrorRef* error)
+{    
+    SecKeyRef full_key = NULL;
+    
+    CFNumberRef key_size_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &keySize);
+
+    CFDictionaryRef priv_key_attrs = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
+                                                                  kSecAttrIsPermanent,    kCFBooleanTrue,
+                                                                  NULL);
+    
+    CFDictionaryRef keygen_parameters = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
+        kSecAttrKeyType,        kSecAttrKeyTypeEC,
+        kSecAttrKeySizeInBits,  key_size_num,
+        kSecPrivateKeyAttrs,    priv_key_attrs,
+        kSecAttrAccessible,     accessibility,
+        kSecAttrAccessGroup,    kSOSInternalAccessGroup,
+        kSecAttrLabel,          name,
+        kSecAttrSynchronizable, sync,
+        kSecUseTombstones,      kCFBooleanTrue,
+        NULL);
+
+    CFReleaseNull(priv_key_attrs);
+
+    CFReleaseNull(key_size_num);
+    OSStatus status = SecKeyGeneratePair(keygen_parameters, NULL, &full_key);
+    CFReleaseNull(keygen_parameters);
+    
+    if (status)
+        secerror("status: %ld", (long)status);
+    if (status != errSecSuccess && error != NULL && *error == NULL) {
+        *error = CFErrorCreate(kCFAllocatorDefault, kCFErrorDomainOSStatus, status, NULL);
+    }
+    
+    return full_key;
+}
+
+static SecKeyRef GeneratePermanentFullECKey(int keySize, CFStringRef name, CFErrorRef* error) {
+    return GeneratePermanentFullECKey_internal(keySize, name, kSecAttrAccessibleWhenUnlockedThisDeviceOnly, kCFBooleanFalse, error);
+}
+
+static SecKeyRef GeneratePermanentFullECKeyForCloudIdentity(int keySize, CFStringRef name, CFErrorRef* error) {
+    return GeneratePermanentFullECKey_internal(keySize, name, kSecAttrAccessibleWhenUnlocked, kCFBooleanTrue, error);
+}
+
+
+SOSFullPeerInfoRef SOSAccountGetMyFullPeerInCircleNamed(SOSAccountRef account, CFStringRef name, CFErrorRef *error) {
+    if (CFDictionaryGetValue(account->circles, name) == NULL) {
+        SOSCreateErrorWithFormat(kSOSErrorNoCircle, NULL, error, NULL, CFSTR("No circle named '%@'"), name);
+        return NULL;
+    }
+    SOSFullPeerInfoRef circle_full_peer_info = (SOSFullPeerInfoRef) CFDictionaryGetValue(account->circle_identities, name);
+    
+
+    if (circle_full_peer_info == NULL) {
+        CFStringRef keyName = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("ID for %@-%@"), SOSPeerGestaltGetName(account->gestalt), name);
+        SecKeyRef full_key = GeneratePermanentFullECKey(256, keyName, error);
+        CFReleaseNull(keyName);
+
+        if (full_key) {
+            circle_full_peer_info = SOSFullPeerInfoCreate(kCFAllocatorDefault, account->gestalt, full_key, error);
+    
+            CFReleaseNull(full_key);
+
+            if (!circle_full_peer_info) {
+                secerror("Can't make FullPeerInfo for %@-%@ (%@) - is AKS ok?", SOSPeerGestaltGetName(account->gestalt), name, error ? (void*)*error : (void*)CFSTR("-"));
+                return circle_full_peer_info;
+            }
+            
+            CFDictionarySetValue(account->circle_identities, name, circle_full_peer_info);
+            CFReleaseNull(circle_full_peer_info);
+            circle_full_peer_info = (SOSFullPeerInfoRef) CFDictionaryGetValue(account->circle_identities, name);
+        }
+        else
+            secerror("No full_key: %@:", error ? *error : NULL);
+    }
+    
+    return circle_full_peer_info;
+}
+
+static bool SOSAccountDestroyCirclePeerInfoNamed(SOSAccountRef account, CFStringRef name, CFErrorRef* error) {
+    if (CFDictionaryGetValue(account->circles, name) == NULL) {
+        SOSCreateErrorWithFormat(kSOSErrorNoCircle, NULL, error, NULL, CFSTR("No circle named '%@'"), name);
+        return false;
+    }
+    
+    SOSFullPeerInfoRef circle_full_peer_info = (SOSFullPeerInfoRef) CFDictionaryGetValue(account->circle_identities, name);
+    
+    if (circle_full_peer_info) {
+        SOSPeerPurgeAllFor(SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(circle_full_peer_info)));
+        
+        SOSFullPeerInfoPurgePersistentKey(circle_full_peer_info, NULL);
+    }
+    
+    CFDictionaryRemoveValue(account->circle_identities, name);
+    
+    return true;
+}
+
+static bool SOSAccountDestroyCirclePeerInfo(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error) {    
+    return SOSAccountDestroyCirclePeerInfoNamed(account, SOSCircleGetName(circle), error);
+}
+
+SOSFullPeerInfoRef SOSAccountGetMyFullPeerInCircle(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error) {
+    return SOSAccountGetMyFullPeerInCircleNamed(account, SOSCircleGetName(circle), error);
+}
+
+SOSPeerInfoRef SOSAccountGetMyPeerInCircle(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error) {
+    SOSFullPeerInfoRef fpi =  SOSAccountGetMyFullPeerInCircleNamed(account, SOSCircleGetName(circle), error);
+    
+    return fpi ? SOSFullPeerInfoGetPeerInfo(fpi) : NULL;
+}
+
+SOSPeerInfoRef SOSAccountGetMyPeerInCircleNamed(SOSAccountRef account, CFStringRef name, CFErrorRef *error)
+{
+    SOSFullPeerInfoRef fpi =  SOSAccountGetMyFullPeerInCircleNamed(account, name, error);
+    
+    return fpi ? SOSFullPeerInfoGetPeerInfo(fpi) : NULL;
+}
+
+CFArrayRef SOSAccountCopyAccountIdentityPeerInfos(SOSAccountRef account, CFAllocatorRef allocator, CFErrorRef* error)
+{
+    CFMutableArrayRef result = CFArrayCreateMutableForCFTypes(allocator);
+
+    CFDictionaryForEach(account->circle_identities, ^(const void *key, const void *value) {
+        SOSFullPeerInfoRef fpi = (SOSFullPeerInfoRef) value;
+        
+        CFArrayAppendValue(result, SOSFullPeerInfoGetPeerInfo(fpi));
+    });
+    
+    return result;
+}
+
+bool SOSAccountIsAccountIdentity(SOSAccountRef account, SOSPeerInfoRef peer_info, CFErrorRef *error)
+{
+    __block bool matches = false;
+    CFDictionaryForEach(account->circle_identities, ^(const void *key, const void *value) {
+        if (!matches) {
+            matches = CFEqual(peer_info, SOSFullPeerInfoGetPeerInfo((SOSFullPeerInfoRef) value));
+        }
+    });
+    
+    return matches;
+}
+
+bool SOSAccountSyncWithAllPeers(SOSAccountRef account, CFErrorRef *error)
+{
+    __block bool result = true;
+    SOSAccountForEachCircle(account, ^(SOSCircleRef circle) {
+        if (!SOSAccountSyncWithAllPeersInCircle(account, circle, error))
+            result = false;
+    });
+    
+    return result;
+}
+
+bool SOSAccountSyncWithAllPeersInCircle(SOSAccountRef account, SOSCircleRef circle,
+                                CFErrorRef *error)
+{
+    SOSPeerInfoRef my_peer = SOSAccountGetMyPeerInCircle(account, circle, error);
+    if (!my_peer)
+        return false;
+    
+    __block bool didSync = false;
+    __block bool result = true;
+    
+    if (SOSCircleHasPeer(circle, my_peer, NULL)) {
+        SOSCircleForEachPeer(circle, ^(SOSPeerInfoRef peer) {
+            if (!CFEqual(SOSPeerInfoGetPeerID(my_peer), SOSPeerInfoGetPeerID(peer)))
+            {
+                bool local_didSync = false;
+                if (!SOSAccountSyncWithPeer(account, circle, peer, &local_didSync, error))
+                    result = false;
+                if (!didSync && local_didSync)
+                {
+                    didSync = true;
+                }
+            }
+        });
+        
+        if (didSync)
+        {
+            SetCloudKeychainTraceValueForKey(kCloudKeychainNumberOfTimesSyncedWithPeers, 1);
+        }
+    }
+    
+    return result;
+}
+
+bool SOSAccountSyncWithPeer(SOSAccountRef account, SOSCircleRef circle,
+                            SOSPeerInfoRef thisPeer, bool* didSendData, CFErrorRef* error)
+{
+    CFStringRef peer_id = SOSPeerInfoGetPeerID(thisPeer);
+    CFStringRef peer_write_key = SOSMessageKeyCreateWithAccountAndPeer(account, circle, peer_id);
+    SOSFullPeerInfoRef myRef = SOSAccountGetMyFullPeerInCircle(account, circle, error);
+    
+    __block bool sentData = false;
+
+
+    SOSPeerSendBlock writeToKVSKey = ^bool (CFDataRef data, CFErrorRef* error) {
+        secnotice("account", "writing data of size %ld:", data?CFDataGetLength(data):0);
+        sentData = (NULL != data);
+        CFDictionaryRef writeToDo = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, peer_write_key, data, NULL);
+        bool written = account->update_block(writeToDo, error);
+        if (account->processed_message_block)
+            account->processed_message_block(circle, NULL, data);
+        CFRelease(writeToDo);
+        return written;
+    };
+    
+    if (NULL != didSendData)
+    {
+        *didSendData = sentData;
+    }
+    
+    bool result = SOSCircleSyncWithPeer(myRef, circle, account->factory, writeToKVSKey, peer_id, error);
+    CFReleaseNull(peer_write_key);
+    return result;
+}
+
+static bool SOSAccountIsActivePeerInCircleNamed(SOSAccountRef account, CFStringRef circle_name, CFStringRef peerid, CFErrorRef* error) {
+    SOSCircleRef circle = SOSAccountFindCircle(account, circle_name, error);
+    if(!circle) return false;
+    return SOSCircleHasActivePeerWithID(circle, peerid, error);
+}
+
+static bool SOSAccountIsMyPeerActiveInCircle(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error) {
+    SOSFullPeerInfoRef fpi = SOSAccountGetMyFullPeerInCircleNamedIfPresent(account, SOSCircleGetName(circle), NULL);
+    if(!fpi) return false;
+    return SOSCircleHasActivePeer(circle, SOSFullPeerInfoGetPeerInfo(fpi), error);
+}
+
+bool SOSAccountCleanupAfterPeer(SOSAccountRef account, size_t seconds, SOSCircleRef circle,
+                                SOSPeerInfoRef cleanupPeer, CFErrorRef* error)
+{
+    if(!SOSAccountIsMyPeerActiveInCircle(account, circle, NULL)) return true;
+    
+    CFMutableDictionaryRef keysToWrite = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
+
+    SOSCircleForEachPeer(circle, ^(SOSPeerInfoRef circlePeer) {
+        CFStringRef from_key = SOSMessageKeyCreateWithCircleAndPeerInfos(circle, cleanupPeer, circlePeer);
+        CFStringRef to_key = SOSMessageKeyCreateWithCircleAndPeerInfos(circle, circlePeer, cleanupPeer);
+
+        CFDictionaryAddValue(keysToWrite, from_key, kCFNull);
+        CFDictionaryAddValue(keysToWrite, to_key, kCFNull);
+
+        CFReleaseNull(from_key);
+        CFReleaseNull(to_key);
+    });
+    
+    if(SOSPeerInfoRetireRetirementTicket(seconds, cleanupPeer)) {
+        CFStringRef resignationKey = SOSRetirementKeyCreateWithCircleAndPeer(circle, SOSPeerInfoGetPeerID(cleanupPeer));
+        CFDictionarySetValue(keysToWrite, resignationKey, kCFNull);
+        CFDictionaryRemoveValue(account->retired_peers, resignationKey);
+        CFReleaseNull(resignationKey);
+    }
+
+    bool success = account->update_block(keysToWrite, error);
+
+    CFReleaseNull(keysToWrite);
+
+    return success;
+}
+
+bool SOSAccountCleanupRetirementTickets(SOSAccountRef account, size_t seconds, CFErrorRef* error) {
+    CFMutableDictionaryRef keysToWrite = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
+    
+    CFDictionaryRef copyToIterate = CFDictionaryCreateCopy(kCFAllocatorDefault, account->retired_peers);
+
+    CFDictionaryForEach(copyToIterate, ^(const void* resignationKey, const void* value) {
+        CFStringRef circle_name = NULL;
+        CFStringRef retiree_peerid = NULL;
+        SOSPeerInfoRef pi = NULL;
+        SOSKVSKeyType keytype = SOSKVSKeyGetKeyTypeAndParse(resignationKey, &circle_name, &retiree_peerid, NULL);
+        require_quiet(keytype == kRetirementKey && circle_name && retiree_peerid && isData(value), forget);
+        pi = SOSPeerInfoCreateFromData(NULL, error, (CFDataRef) value);
+        require_quiet(pi && CFEqualSafe(retiree_peerid, SOSPeerInfoGetPeerID(pi)), forget);
+
+        require_quiet(!SOSAccountIsActivePeerInCircleNamed(account, circle_name, retiree_peerid, NULL), keep);
+        require_quiet(SOSPeerInfoRetireRetirementTicket(seconds, pi), keep);
+        
+        // Happy day, it's time and it's a ticket we should eradicate from KVS.
+        CFDictionarySetValue(keysToWrite, resignationKey, kCFNull);
+
+    forget:
+        CFDictionaryRemoveValue(account->retired_peers, resignationKey);
+    keep:
+        CFReleaseSafe(pi);
+        CFReleaseSafe(circle_name);
+        CFReleaseSafe(retiree_peerid);
+    });
+    CFReleaseNull(copyToIterate);
+
+    bool success = true;
+    if(CFDictionaryGetCount(keysToWrite)) {
+        success = account->update_block(keysToWrite, error);
+    }
+    CFReleaseNull(keysToWrite);
+        
+    return success;
+}
+
+bool SOSAccountScanForRetired(SOSAccountRef account, SOSCircleRef circle, CFErrorRef *error) {
+    SOSCircleForEachRetiredPeer(circle, ^(SOSPeerInfoRef peer) {
+        CFStringRef key = SOSRetirementKeyCreateWithCircleAndPeer(circle, SOSPeerInfoGetPeerID(peer));
+        if(key && !CFDictionaryGetValueIfPresent(account->retired_peers, key, NULL)) {
+            CFDataRef value = SOSPeerInfoCopyEncodedData(peer, NULL, NULL);
+            if(value) {
+                CFDictionarySetValue(account->retired_peers, key, value);
+                SOSAccountCleanupAfterPeer(account, RETIREMENT_FINALIZATION_SECONDS, circle, peer, error);
+            }
+            CFReleaseSafe(value);
+        }
+        CFReleaseSafe(key);
+    });
+    return true;
+}
+
+SOSCircleRef SOSAccountCloneCircleWithRetirement(SOSAccountRef account, SOSCircleRef starting_circle, CFErrorRef *error) {
+    CFStringRef circle_to_mod = SOSCircleGetName(starting_circle);
+    SOSCircleRef new_circle = SOSCircleCopyCircle(NULL, starting_circle, error);
+    if(!new_circle) return NULL;
+    
+    CFDictionaryForEach(account->retired_peers, ^(const void* resignationKey, const void* value) {
+        CFStringRef circle_name = NULL;
+        CFStringRef retiree_peerid = NULL;
+        
+        SOSKVSKeyType keytype = SOSKVSKeyGetKeyTypeAndParse(resignationKey, &circle_name, &retiree_peerid, NULL);
+        if(keytype == kRetirementKey && CFEqualSafe(circle_name, circle_to_mod) && SOSCircleHasPeerWithID(new_circle, retiree_peerid, NULL)) {
+            if(isData(value)) {
+                SOSPeerInfoRef pi = SOSPeerInfoCreateFromData(NULL, error, (CFDataRef) value);
+                SOSCircleUpdatePeerInfo(new_circle, pi);
+                CFReleaseSafe(pi);
+            }
+        }
+        CFReleaseSafe(circle_name);
+        CFReleaseSafe(retiree_peerid);
+    });
+    
+    if(SOSCircleCountPeers(new_circle) == 0) {
+        SOSCircleResetToEmpty(new_circle, NULL);
+    }
+    
+    return new_circle;
+}
+
+
+//
+// Circle Finding
+//
+SOSCircleRef SOSAccountFindCompatibleCircle(SOSAccountRef a, CFStringRef name)
+{
+    CFTypeRef entry = CFDictionaryGetValue(a->circles, name);
+    
+    if (CFGetTypeID(entry) == SOSCircleGetTypeID())
+        return (SOSCircleRef) entry;
+    
+    return NULL;
+}
+
+SOSCircleRef SOSAccountFindCircle(SOSAccountRef a, CFStringRef name, CFErrorRef *error)
+{
+    CFTypeRef entry = CFDictionaryGetValue(a->circles, name);
+    
+    require_action_quiet(!isNull(entry), fail,
+                         SOSCreateError(kSOSErrorIncompatibleCircle, CFSTR("Incompatible circle in KVS"), NULL, error));
+
+    require_action_quiet(entry, fail,
+                         SOSCreateError(kSOSErrorNoCircle, CFSTR("No circle found"), NULL, error));
+
+    
+    return (SOSCircleRef) entry;
+
+fail:
+    return NULL;
+}
+
+SOSCircleRef SOSAccountEnsureCircle(SOSAccountRef a, CFStringRef name, CFErrorRef *error)
+{
+    CFErrorRef localError = NULL;
+
+    SOSCircleRef circle = SOSAccountFindCircle(a, name, &localError);
+    
+    require_action_quiet(circle || !isSOSErrorCoded(localError, kSOSErrorIncompatibleCircle), fail,
+                         if (error) { *error = localError; localError = NULL; });
+    
+
+    if (NULL == circle) {
+        circle = SOSCircleCreate(NULL, name, NULL);
+        if (circle){
+            CFDictionaryAddValue(a->circles, name, circle);
+            CFRelease(circle);
+            circle = SOSAccountFindCircle(a, name, &localError);
+        }
+        SOSUpdateKeyInterest(a, false, NULL);
+    }
+
+fail:
+    CFReleaseNull(localError);
+    return circle;
+}
+
+
+void SOSAccountAddChangeBlock(SOSAccountRef a, SOSAccountCircleMembershipChangeBlock changeBlock)
+{
+    CFArrayAppendValue(a->change_blocks, changeBlock);
+}
+
+void SOSAccountRemoveChangeBlock(SOSAccountRef a, SOSAccountCircleMembershipChangeBlock changeBlock)
+{
+    CFArrayRemoveAllValue(a->change_blocks, changeBlock);
+}
+
+static void DifferenceAndCall(CFArrayRef old_members, CFArrayRef new_members, void (^updatedCircle)(CFArrayRef additions, CFArrayRef removals))
+{
+    CFMutableArrayRef additions = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, new_members);
+    CFMutableArrayRef removals = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, old_members);
+    
+
+    CFArrayForEach(old_members, ^(const void * value) {
+        CFArrayRemoveAllValue(additions, value);
+    });
+    
+    CFArrayForEach(new_members, ^(const void * value) {
+        CFArrayRemoveAllValue(removals, value);
+    });
+
+    updatedCircle(additions, removals);
+    
+    CFReleaseSafe(additions);
+    CFReleaseSafe(removals);
+}
+
+static void SOSAccountNotifyOfChange(SOSAccountRef account, SOSCircleRef oldCircle, SOSCircleRef newCircle)
+{
+    CFMutableArrayRef old_members = SOSCircleCopyPeers(oldCircle, kCFAllocatorDefault);
+    CFMutableArrayRef new_members = SOSCircleCopyPeers(newCircle, kCFAllocatorDefault);
+    
+    CFMutableArrayRef old_applicants = SOSCircleCopyApplicants(oldCircle, kCFAllocatorDefault);
+    CFMutableArrayRef new_applicants = SOSCircleCopyApplicants(newCircle, kCFAllocatorDefault);
+    
+    DifferenceAndCall(old_members, new_members, ^(CFArrayRef added_members, CFArrayRef removed_members) {
+        DifferenceAndCall(old_applicants, new_applicants, ^(CFArrayRef added_applicants, CFArrayRef removed_applicants) {
+            CFArrayForEach(account->change_blocks, ^(const void * notificationBlock) {
+                ((SOSAccountCircleMembershipChangeBlock) notificationBlock)(newCircle, added_members, removed_members, added_applicants, removed_applicants);
+            });
+        });
+    });
+    
+    CFReleaseNull(old_applicants);
+    CFReleaseNull(new_applicants);
+
+    CFReleaseNull(old_members);
+    CFReleaseNull(new_members);
+}
+
+void SOSAccountForEachCircle(SOSAccountRef account, void (^process)(SOSCircleRef circle))
+{
+    CFDictionaryForEach(account->circles, ^(const void* key, const void* value) {
+        assert(value);
+        process((SOSCircleRef)value);
+    });
+}
+
+static void AppendCircleKeyName(CFMutableArrayRef array, CFStringRef name) {
+    CFStringRef circle_key = SOSCircleKeyCreateWithName(name, NULL);
+    CFArrayAppendValue(array, circle_key);
+    CFReleaseNull(circle_key);
+}
+
+static inline void AppendCircleInterests(CFMutableArrayRef circle_keys, CFMutableArrayRef retiree_keys, CFMutableArrayRef message_keys, SOSCircleRef circle, SOSFullPeerInfoRef me) {
+    CFStringRef my_peer_id = NULL;
+    
+    if (me) {
+        SOSPeerInfoRef my_peer = me ? SOSFullPeerInfoGetPeerInfo(me) : NULL;
+        my_peer_id = SOSPeerInfoGetPeerID(my_peer);
+    }
+    
+    if (circle_keys) {
+        CFStringRef circleName = SOSCircleGetName(circle);
+        AppendCircleKeyName(circle_keys, circleName);
+    }
+
+    SOSCircleForEachPeer(circle, ^(SOSPeerInfoRef peer) {
+        if (!CFEqualSafe(my_peer_id, SOSPeerInfoGetPeerID(peer))) {
+            CFStringRef peer_name = SOSPeerInfoGetPeerID(peer);
+            if (retiree_keys) {
+                CFStringRef retirementKey = SOSRetirementKeyCreateWithCircleAndPeer(circle, peer_name);
+                CFArrayAppendValue(retiree_keys, retirementKey);
+                CFReleaseNull(retirementKey);
+            }
+            
+            if (my_peer_id && message_keys) {
+                CFStringRef messageKey = SOSMessageKeyCreateWithCircleAndPeerNames(circle, peer_name, my_peer_id);
+                CFArrayAppendValue(message_keys, messageKey);
+                CFRelease(messageKey);
+            }
+        }
+    });
+}
+
+static void SOSAccountCopyKeyInterests(SOSAccountRef account,
+                                       CFMutableArrayRef alwaysKeys,
+                                       CFMutableArrayRef afterFirstUnlockKeys,
+                                       CFMutableArrayRef whenUnlockedKeys)
+{
+    CFArrayAppendValue(afterFirstUnlockKeys, kSOSKVSKeyParametersKey);
+    
+    SOSAccountForEachKnownCircle(account, ^(CFStringRef name) {
+        AppendCircleKeyName(afterFirstUnlockKeys, name);
+    }, ^(SOSCircleRef circle) {
+        AppendCircleInterests(afterFirstUnlockKeys, afterFirstUnlockKeys, whenUnlockedKeys, circle, NULL);
+    }, ^(SOSCircleRef circle, SOSFullPeerInfoRef full_peer) {
+        bool inCircle = SOSCircleHasPeer(circle, SOSFullPeerInfoGetPeerInfo(full_peer), NULL);
+
+        AppendCircleInterests(afterFirstUnlockKeys, afterFirstUnlockKeys, inCircle ? whenUnlockedKeys : NULL, circle, full_peer);
+    });
+}
+
+static bool SOSUpdateKeyInterest(SOSAccountRef account, bool getNewKeysOnly, CFErrorRef *error)
+{
+    if (account->update_interest_block) {
+
+        CFMutableArrayRef alwaysKeys = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
+        CFMutableArrayRef afterFirstUnlockKeys = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
+        CFMutableArrayRef whenUnlockedKeys = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
+
+        SOSAccountCopyKeyInterests(account, alwaysKeys, afterFirstUnlockKeys, whenUnlockedKeys);
+
+        account->update_interest_block(getNewKeysOnly, alwaysKeys, afterFirstUnlockKeys, whenUnlockedKeys);
+    
+        CFReleaseNull(alwaysKeys);
+        CFReleaseNull(afterFirstUnlockKeys);
+        CFReleaseNull(whenUnlockedKeys);
+    }
+    
+    return true;
+}
+
+static bool SOSAccountSendPendingChanges(SOSAccountRef account, CFErrorRef *error) {
+    CFErrorRef changeError = NULL;
+    
+    if (CFDictionaryGetCount(account->pending_changes) == 0)
+        return true;
+    
+    bool success = account->update_block(account->pending_changes, &changeError);
+    if (success) {
+        CFDictionaryRemoveAllValues(account->pending_changes);
+    } else {
+        SOSCreateErrorWithFormat(kSOSErrorSendFailure, changeError, error, NULL,
+                                 CFSTR("Send changes block failed [%@]"), account->pending_changes);
+    }
+    
+    return success;
+}
+
+static bool SOSAccountAddCircleToPending(SOSAccountRef account, SOSCircleRef circle, CFErrorRef *error)
+{
+    bool success = false;
+    CFDataRef circle_data = SOSCircleCopyEncodedData(circle, kCFAllocatorDefault, error);
+    
+    if (circle_data) {
+        CFStringRef circle_key = SOSCircleKeyCreateWithCircle(circle, NULL);
+
+        CFDictionarySetValue(account->pending_changes, circle_key, circle_data);
+        success = true;
+        
+        CFReleaseNull(circle_data);
+        CFReleaseNull(circle_key);
+    }
+    
+    return success;
+}
+
+
+static void SOSAccountRecordRetiredPeerInCircleNamed(SOSAccountRef account, CFStringRef circleName, SOSPeerInfoRef retiree)
+{
+    // Replace Peer with RetiredPeer, if were a peer.
+    SOSAccountModifyCircle(account, circleName, NULL, ^(SOSCircleRef circle) {
+        if (SOSCircleUpdatePeerInfo(circle, retiree)) {
+            CFErrorRef cleanupError = NULL;
+            SOSAccountCleanupAfterPeer(account, RETIREMENT_FINALIZATION_SECONDS, circle, retiree, &cleanupError);
+            secerror("Error cleanup up after peer (%@): %@", retiree, cleanupError);
+            CFReleaseSafe(cleanupError);
+        }
+    });
+}
+
+static bool sosAccountLeaveCircle(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error) {
+    SOSFullPeerInfoRef fpi = SOSAccountGetMyFullPeerInCircle(account, circle, NULL);
+    if(!fpi) return false;
+       CFErrorRef localError = NULL;
+    SOSPeerInfoRef pi = SOSFullPeerInfoGetPeerInfo(fpi);
+       CFStringRef retire_key = SOSRetirementKeyCreateWithCircleAndPeer(circle, SOSPeerInfoGetPeerID(pi));
+       SOSPeerInfoRef retire_peer = NULL;
+       CFDataRef retire_value = NULL;
+    bool retval = false;
+    bool writeCircle = false;
+    
+    // Create a Retirement Ticket and store it in the retired_peers of the account.
+       retire_peer = SOSFullPeerInfoPromoteToRetiredAndCopy(fpi, &localError);
+    require_action_quiet(retire_peer, errout, secerror("Create ticket failed for peer %@: %@", fpi, localError));
+       retire_value = SOSPeerInfoCopyEncodedData(retire_peer, NULL, &localError);
+    require_action_quiet(retire_value, errout, secerror("Failed to encode retirement peer %@: %@", retire_peer, localError));
+
+    // See if we need to repost the circle we could either be an applicant or a peer already in the circle
+    if(SOSCircleHasApplicant(circle, pi, NULL)) {
+           // Remove our application if we have one.
+           SOSCircleWithdrawRequest(circle, pi, NULL);
+        writeCircle = true;
+    } else if (SOSCircleHasPeer(circle, pi, NULL)) {
+        if (SOSCircleUpdatePeerInfo(circle, retire_peer)) {
+            CFErrorRef cleanupError = NULL;
+            SOSAccountCleanupAfterPeer(account, RETIREMENT_FINALIZATION_SECONDS, circle, retire_peer, &cleanupError);
+            secerror("Error cleanup up after peer (%@): %@", retire_peer, cleanupError);
+            CFReleaseSafe(cleanupError);
+        }
+        writeCircle = true;
+    }
+    
+    // Store the retirement record locally.
+    CFDictionarySetValue(account->retired_peers, retire_key, retire_value);
+
+    // Write pending change to KVS
+    CFDictionarySetValue(account->pending_changes, retire_key, retire_value);
+    
+    // Kill peer key but don't return error if we can't.
+    if(!SOSAccountDestroyCirclePeerInfo(account, circle, &localError))
+        secerror("Couldn't purge key for peer %@ on retirement: %@", fpi, localError);
+
+    if (writeCircle) {
+        SOSAccountAddCircleToPending(account, circle, NULL);
+    }
+    retval = true;
+
+errout:
+    CFReleaseNull(localError);
+    CFReleaseNull(retire_peer);
+    CFReleaseNull(retire_key);
+    CFReleaseNull(retire_value);
+    return retval;
+}
+
+/*
+    NSUbiquitousKeyValueStoreInitialSyncChange is only posted if there is any
+    local value that has been overwritten by a distant value. If there is no
+    conflict between the local and the distant values when doing the initial
+    sync (e.g. if the cloud has no data stored or the client has not stored
+    any data yet), you'll never see that notification.
+
+    NSUbiquitousKeyValueStoreInitialSyncChange implies an initial round trip
+    with server but initial round trip with server does not imply
+    NSUbiquitousKeyValueStoreInitialSyncChange.
+ */
+
+//
+// MARK: Handle Circle Updates
+//
+
+
+static bool SOSAccountHandleUpdateCircle(SOSAccountRef account, SOSCircleRef prospective_circle, bool writeUpdate, bool initialSync, CFErrorRef *error)
+{
+    bool success = true;
+
+    secnotice("signing", "start: %@", prospective_circle);
+    if (!account->user_public || !account->user_public_trusted) {
+        SOSCreateError(kSOSErrorPublicKeyAbsent, CFSTR("Can't handle updates with no trusted public key here"), NULL, error);
+        return false;
+    }
+    
+    if (!prospective_circle) {
+        secerror("##### Can't update to a NULL circle ######");
+        return false; // Can't update one we don't have.
+    }
+    
+    CFStringRef newCircleName = SOSCircleGetName(prospective_circle);
+    SOSCircleRef oldCircle = SOSAccountFindCompatibleCircle(account, newCircleName);
+    SOSFullPeerInfoRef me_full = SOSAccountGetMyFullPeerInCircle(account, oldCircle, NULL);
+    SOSPeerInfoRef me = SOSFullPeerInfoGetPeerInfo(me_full);
+    
+    if (initialSync)
+        secerror("##### Processing initial sync. Old (local) circle: %@, New (cloud) circle: %@", oldCircle, prospective_circle);
+
+    if (!oldCircle)
+        return false; // Can't update one we don't have.
+    
+    SOSAccountScanForRetired(account, prospective_circle, error);
+    SOSCircleRef newCircle = SOSAccountCloneCircleWithRetirement(account, prospective_circle, error);
+    if(!newCircle) return false;
+    
+    SOSCircleUpdatePeerInfo(newCircle, me);
+    
+    typedef enum {
+        accept,
+        countersign,
+        leave,
+        revert,
+        ignore
+    } circle_action_t;
+    
+    circle_action_t circle_action = ignore;
+    enum DepartureReason leave_reason = kSOSNeverLeftCircle;
+    
+    SecKeyRef old_circle_key = NULL;
+    if(SOSCircleVerify(oldCircle, account->user_public, NULL)) old_circle_key = account->user_public;
+    else if(account->previous_public && SOSCircleVerify(oldCircle, account->previous_public, NULL)) old_circle_key = account->previous_public;
+    bool userTrustedOldCircle = (old_circle_key != NULL);
+    
+    SOSConcordanceStatus concstat =
+        SOSCircleConcordanceTrust(oldCircle, newCircle,
+                                  old_circle_key, account->user_public,
+                                  me, error);
+    
+    CFStringRef concStr = NULL;
+    switch(concstat) {
+        case kSOSConcordanceTrusted:
+            circle_action = countersign;
+            concStr = CFSTR("Trusted");
+            break;
+        case kSOSConcordanceGenOld:
+            circle_action = userTrustedOldCircle ? revert : ignore;
+            concStr = CFSTR("Generation Old");
+            break;
+        case kSOSConcordanceBadUserSig:
+        case kSOSConcordanceBadPeerSig:
+            circle_action = userTrustedOldCircle ? revert : accept;
+            concStr = CFSTR("Bad Signature");
+            break;
+        case kSOSConcordanceNoUserSig:
+            circle_action = userTrustedOldCircle ? revert : accept;
+            concStr = CFSTR("No User Signature");
+            break;
+        case kSOSConcordanceNoPeerSig:
+            circle_action = accept; // We might like this one eventually but don't countersign.
+            concStr = CFSTR("No trusted peer signature");
+            secerror("##### No trusted peer signature found, accepting hoping for concordance later %@", newCircle);
+            break;
+        case kSOSConcordanceNoPeer:
+            circle_action = leave;
+            leave_reason = kSOSLeftUntrustedCircle;
+            concStr = CFSTR("No trusted peer left");
+            break;
+        case kSOSConcordanceNoUserKey:
+            secerror("##### No User Public Key Available, this shouldn't ever happen!!!");
+            abort();
+            break;
+        default:
+            secerror("##### Bad Error Return from ConcordanceTrust");
+            abort();
+            break;
+    }
+
+    secnotice("signing", "Decided on action %d based on concordance state %d and %s circle.", circle_action, concstat, userTrustedOldCircle ? "trusted" : "untrusted");
+
+    SOSCircleRef circleToPush = NULL;
+
+    if (circle_action == leave) {
+        circle_action = ignore;
+
+        if (me && SOSCircleHasPeer(oldCircle, me, NULL)) {
+            if (sosAccountLeaveCircle(account, newCircle, error)) {
+                account->departure_code = leave_reason;
+                circleToPush = newCircle;
+                circle_action = accept;
+                me = NULL;
+                me_full = NULL;
+            }
+        }
+        else {
+            // We are not in this circle, but we need to update account with it, since we got it from cloud
+            secnotice("updatecircle", "We are not in this circle, but we need to update account with it");
+            circle_action = accept;
+        }
+    }
+
+    if (circle_action == countersign) {
+        if (me && SOSCircleHasPeer(newCircle, me, NULL) && !SOSCircleVerifyPeerSigned(newCircle, me, NULL)) {
+            CFErrorRef signing_error = NULL;
+
+            if (me_full && SOSCircleConcordanceSign(newCircle, me_full, &signing_error)) {
+                circleToPush = newCircle;
+                secnotice("signing", "Concurred with: %@", newCircle);
+            } else {
+                secerror("Failed to concurrence sign, error: %@  Old: %@ New: %@", signing_error, oldCircle, newCircle);
+            }
+            CFReleaseSafe(signing_error);
+        }
+        circle_action = accept;
+    }
+
+    if (circle_action == accept) {
+        if (me && SOSCircleHasActivePeer(oldCircle, me, NULL) && !SOSCircleHasPeer(newCircle, me, NULL)) {
+            //  Don't destroy evidence of other code determining reason for leaving.
+            if(!SOSAccountHasLeft(account)) account->departure_code = kSOSMembershipRevoked;
+        }
+
+        if (me
+            && SOSCircleHasActivePeer(oldCircle, me, NULL)
+            && !(SOSCircleCountPeers(oldCircle) == 1 && SOSCircleHasPeer(oldCircle, me, NULL)) // If it was our offering, don't change ID to avoid ghosts
+            && !SOSCircleHasPeer(newCircle, me, NULL) && !SOSCircleHasApplicant(newCircle, me, NULL)) {
+            secnotice("circle", "Purging my peer (ID: %@) for circle '%@'!!!", SOSPeerInfoGetPeerID(me), SOSCircleGetName(oldCircle));
+            SOSAccountDestroyCirclePeerInfo(account, oldCircle, NULL);
+            me = NULL;
+            me_full = NULL;
+        }
+        
+        if (me && SOSCircleHasRejectedApplicant(newCircle, me, NULL)) {
+            SOSPeerInfoRef  reject = SOSCircleCopyRejectedApplicant(newCircle, me, NULL);
+            if(CFEqualSafe(reject, me) && SOSPeerInfoApplicationVerify(me, account->user_public, NULL)) {
+                secnotice("circle", "Rejected, Purging my applicant peer (ID: %@) for circle '%@'", SOSPeerInfoGetPeerID(me), SOSCircleGetName(oldCircle));
+                SOSAccountDestroyCirclePeerInfo(account, oldCircle, NULL);
+                me = NULL;
+                me_full = NULL;
+            } else {
+                SOSCircleRequestReadmission(newCircle, account->user_public, me_full, NULL);
+                writeUpdate = true;
+            }
+        }
+        
+        CFRetain(oldCircle); // About to replace the oldCircle
+        CFDictionarySetValue(account->circles, newCircleName, newCircle);
+        SOSAccountSetPreviousPublic(account);
+        
+        secnotice("signing", "%@, Accepting circle: %@", concStr, newCircle);
+        
+        if (me_full && account->user_public_trusted
+            && SOSCircleHasApplicant(oldCircle, me, NULL)
+            && SOSCircleCountPeers(newCircle) > 0
+            && !SOSCircleHasPeer(newCircle, me, NULL) && !SOSCircleHasApplicant(newCircle, me, NULL)) {
+            // We weren't rejected (above would have set me to NULL.
+            // We were applying and we weren't accepted.
+            // Our application is declared lost, let us reapply.
+            
+            if (SOSCircleRequestReadmission(newCircle, account->user_public, me_full, NULL))
+                writeUpdate = true;
+        }
+        
+        if (me && SOSCircleHasActivePeer(oldCircle, me, NULL)) {
+            SOSAccountCleanupRetirementTickets(account, RETIREMENT_FINALIZATION_SECONDS, NULL);
+        }
+
+        SOSAccountNotifyOfChange(account, oldCircle, newCircle);
+
+        CFReleaseNull(oldCircle);
+
+        if (writeUpdate)
+            circleToPush = newCircle;
+
+        success = SOSUpdateKeyInterest(account, true, error);
+    }
+
+    if (circle_action == revert) {
+        secnotice("signing", "%@, Rejecting: %@ re-publishing %@", concStr, newCircle, oldCircle);
+        
+        circleToPush = oldCircle;
+    }
+
+
+    if (circleToPush != NULL) {
+        success = (success
+                   && SOSAccountAddCircleToPending(account, circleToPush, error)
+                   && SOSAccountSendPendingChanges(account, error));
+    }
+
+    CFReleaseSafe(newCircle);
+
+    return success;
+}
+
+static bool SOSAccountUpdateCircleFromRemote(SOSAccountRef account, SOSCircleRef newCircle, bool initialSync, CFErrorRef *error)
+{
+    return SOSAccountHandleUpdateCircle(account, newCircle, false, initialSync, error);
+}
+
+bool SOSAccountUpdateCircle(SOSAccountRef account, SOSCircleRef newCircle, CFErrorRef *error)
+{
+    return SOSAccountHandleUpdateCircle(account, newCircle, true, false, error);
+}
+
+bool SOSAccountModifyCircle(SOSAccountRef account,
+                            CFStringRef circleName,
+                            CFErrorRef* error,
+                            void (^action)(SOSCircleRef circle))
+{
+    bool success = false;
+    
+    SOSCircleRef circle = NULL;
+    SOSCircleRef accountCircle = SOSAccountFindCircle(account, circleName, error);
+    require_quiet(accountCircle, fail);
+
+    circle = SOSCircleCopyCircle(kCFAllocatorDefault, accountCircle, error);
+    require_quiet(circle, fail);
+
+    action(circle);
+    success = SOSAccountUpdateCircle(account, circle, error);
+    
+fail:
+    CFReleaseSafe(circle);
+    return success;
+}
+
+static SOSCircleRef SOSAccountCreateCircleFrom(CFStringRef circleName, CFTypeRef value, CFErrorRef *error) {
+    if (value && !isData(value) && !isNull(value)) {
+        CFStringRef description = CFCopyTypeIDDescription(CFGetTypeID(value));
+        SOSCreateErrorWithFormat(kSOSErrorUnexpectedType, NULL, error, NULL,
+                                 CFSTR("Expected data or NULL got %@"), description);
+        CFReleaseSafe(description);
+        return NULL;
+    }
+
+    SOSCircleRef circle = NULL;
+    if (!value || isNull(value)) {
+        circle = SOSCircleCreate(kCFAllocatorDefault, circleName, error);
+    } else {
+        circle = SOSCircleCreateFromData(NULL, (CFDataRef) value, error);
+        if (circle) {
+            CFStringRef name = SOSCircleGetName(circle);
+            if (!CFEqualSafe(name, circleName)) {
+                SOSCreateErrorWithFormat(kSOSErrorNameMismatch, NULL, error, NULL,
+                                     CFSTR("Expected circle named %@, got %@"), circleName, name);
+                CFReleaseNull(circle);
+            }
+        }
+    }
+    return circle;
+}
+
+static SOSCCStatus SOSCCCircleStatus(SOSCircleRef circle)
+{
+    if (SOSCircleCountPeers(circle) == 0)
+        return kSOSCCCircleAbsent;
+
+    return kSOSCCNotInCircle;
+}
+
+static SOSCCStatus SOSCCThisDeviceStatusInCircle(SOSCircleRef circle, SOSPeerInfoRef this_peer)
+{
+    if (SOSCircleCountPeers(circle) == 0)
+        return kSOSCCCircleAbsent;
+
+    if (SOSCircleHasPeer(circle, this_peer, NULL))
+        return kSOSCCInCircle;
+
+    if (SOSCircleHasApplicant(circle, this_peer, NULL))
+        return kSOSCCRequestPending;
+
+    return kSOSCCNotInCircle;
+}
+
+static SOSCCStatus UnionStatus(SOSCCStatus accumulated_status, SOSCCStatus additional_circle_status)
+{
+    switch (additional_circle_status) {
+        case kSOSCCInCircle:
+            return accumulated_status;
+        case kSOSCCRequestPending:
+            return (accumulated_status == kSOSCCInCircle) ?
+            kSOSCCRequestPending :
+            accumulated_status;
+        case kSOSCCNotInCircle:
+            return (accumulated_status == kSOSCCInCircle ||
+                    accumulated_status == kSOSCCRequestPending) ?
+            kSOSCCNotInCircle :
+            accumulated_status;
+        case kSOSCCCircleAbsent:
+            return (accumulated_status == kSOSCCInCircle ||
+                    accumulated_status == kSOSCCRequestPending ||
+                    accumulated_status == kSOSCCNotInCircle) ?
+            kSOSCCCircleAbsent :
+            accumulated_status;
+        default:
+            return additional_circle_status;
+    };
+
+}
+
+SOSCCStatus SOSAccountIsInCircles(SOSAccountRef account, CFErrorRef* error)
+{
+    if (!SOSAccountHasPublicKey(account, error)) {
+        return kSOSCCError;
+    }
+
+    __block bool set_once = false;
+    __block SOSCCStatus status = kSOSCCInCircle;
+
+    SOSAccountForEachKnownCircle(account, ^(CFStringRef name) {
+        set_once = true;
+        status = kSOSCCError;
+        SOSCreateError(kSOSErrorIncompatibleCircle, CFSTR("Incompatible circle"), NULL, error);
+    }, ^(SOSCircleRef circle) {
+        set_once = true;
+        status = UnionStatus(status, SOSCCCircleStatus(circle));
+    }, ^(SOSCircleRef circle, SOSFullPeerInfoRef full_peer) {
+        set_once = true;
+        SOSCCStatus circle_status = SOSCCThisDeviceStatusInCircle(circle, SOSFullPeerInfoGetPeerInfo(full_peer));
+        status = UnionStatus(status, circle_status);
+    });
+
+    if (!set_once)
+        status = kSOSCCCircleAbsent;
+
+    return status;
+}
+
+static SOSPeerInfoRef GenerateNewCloudIdentityPeerInfo(CFErrorRef *error) {
+    SecKeyRef cloud_key = GeneratePermanentFullECKeyForCloudIdentity(256, kicloud_identity_name, error);
+    SOSPeerInfoRef cloud_peer = NULL;
+    CFDictionaryRef query = NULL;
+    CFDictionaryRef change = NULL;
+    CFStringRef new_name = NULL;
+
+    CFDictionaryRef gestalt = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
+                                                           kPIUserDefinedDeviceName, CFSTR("iCloud"),
+                                                           NULL);
+    require_action_quiet(gestalt, fail, SecError(errSecAllocate, error, CFSTR("Can't allocate gestalt")));
+
+    cloud_peer = SOSPeerInfoCreateCloudIdentity(kCFAllocatorDefault, gestalt, cloud_key, error);
+
+    require(cloud_peer, fail);
+
+    query = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
+                                         kSecClass,             kSecClassKey,
+                                         kSecAttrSynchronizable,kCFBooleanTrue,
+                                         kSecUseTombstones,     kCFBooleanTrue,
+                                         kSecValueRef,          cloud_key,
+                                         NULL);
+
+    new_name = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
+                                        CFSTR("Cloud Identity - '%@'"), SOSPeerInfoGetPeerID(cloud_peer));
+    
+    change = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
+                                          kSecAttrLabel,        new_name,
+                                          NULL);
+    
+    SecError(SecItemUpdate(query, change), error, CFSTR("Couldn't update name"));
+
+fail:
+    CFReleaseNull(new_name);
+    CFReleaseNull(query);
+    CFReleaseNull(change);
+    CFReleaseNull(gestalt);
+    CFReleaseNull(cloud_key);
+
+    return cloud_peer;
+}
+
+static SOSFullPeerInfoRef CopyCloudKeychainIdentity(SOSPeerInfoRef cloudPeer, CFErrorRef *error) {    
+    return SOSFullPeerInfoCreateCloudIdentity(NULL, cloudPeer, error);
+}
+
+static bool SOSAccountResetThisCircleToOffering(SOSAccountRef account, SOSCircleRef circle, SecKeyRef user_key, CFErrorRef *error) {
+    SOSFullPeerInfoRef myCirclePeer = SOSAccountGetMyFullPeerInCircle(account, circle, error);
+    if (!myCirclePeer)
+        return false;
+
+    SOSAccountModifyCircle(account, SOSCircleGetName(circle), error, ^(SOSCircleRef circle) {
+        bool result = false;
+        SOSFullPeerInfoRef cloud_identity = NULL;
+        CFErrorRef localError = NULL;
+
+        require_quiet(SOSCircleResetToOffering(circle, user_key, myCirclePeer, &localError), err_out);
+
+        {
+            SOSPeerInfoRef cloud_peer = GenerateNewCloudIdentityPeerInfo(error);
+            require_quiet(cloud_peer, err_out);
+            cloud_identity = CopyCloudKeychainIdentity(cloud_peer, error);
+            require_quiet(cloud_identity, err_out);
+        }
+
+        account->departure_code = kSOSNeverLeftCircle;
+        require_quiet(SOSCircleRequestAdmission(circle, user_key, cloud_identity, &localError), err_out);
+        require_quiet(SOSCircleAcceptRequest(circle, user_key, myCirclePeer, SOSFullPeerInfoGetPeerInfo(cloud_identity), &localError), err_out);
+        result = true;
+        SOSAccountPublishCloudParameters(account, NULL);
+
+    err_out:
+        if (result == false)
+            secerror("error resetting circle (%@) to offering: %@", circle, localError);
+        if (localError && error && *error == NULL) {
+            *error = localError;
+            localError = NULL;
+        }
+        CFReleaseNull(localError);
+        CFReleaseNull(cloud_identity);
+    });
+
+    return true;
+}
+
+static bool SOSAccountJoinThisCircle(SOSAccountRef account, SecKeyRef user_key,
+                                     SOSCircleRef circle, bool use_cloud_peer, CFErrorRef* error) {
+    __block bool result = false;
+    __block SOSFullPeerInfoRef cloud_full_peer = NULL;
+
+    SOSFullPeerInfoRef myCirclePeer = SOSAccountGetMyFullPeerInCircle(account, circle, error);
+    require_action_quiet(myCirclePeer, fail,
+                         SOSCreateErrorWithFormat(kSOSErrorPeerNotFound, NULL, error, NULL, CFSTR("Can't find/create peer for circle: %@"), circle));
+    if (use_cloud_peer) {
+        cloud_full_peer = SOSCircleGetiCloudFullPeerInfoRef(circle);
+    }
+
+    if (SOSCircleCountPeers(circle) == 0) {
+        result = SOSAccountResetThisCircleToOffering(account, circle, user_key, error);
+    } else {
+        SOSAccountModifyCircle(account, SOSCircleGetName(circle), error, ^(SOSCircleRef circle) {
+            result = SOSCircleRequestAdmission(circle, user_key, myCirclePeer, error);
+            account->departure_code = kSOSNeverLeftCircle;
+            if(result && cloud_full_peer) {
+                CFErrorRef localError = NULL;
+                CFStringRef cloudid = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(cloud_full_peer));
+                require_quiet(cloudid, finish);
+                require_quiet(SOSCircleHasActivePeerWithID(circle, cloudid, &localError), finish);
+                require_quiet(SOSCircleAcceptRequest(circle, user_key, cloud_full_peer, SOSFullPeerInfoGetPeerInfo(myCirclePeer), &localError), finish);
+            finish:
+                if (localError){
+                    secerror("Failed to join with cloud identity: %@", localError);
+                    CFReleaseNull(localError);
+                }
+            }
+        });
+    }
+    
+fail:
+    CFReleaseNull(cloud_full_peer);
+    return result;
+}
+                           
+static bool SOSAccountJoinCircles_internal(SOSAccountRef account, bool use_cloud_identity, CFErrorRef* error) {
+    SecKeyRef user_key = SOSAccountGetPrivateCredential(account, error);
+    if (!user_key)
+        return false;
+
+    __block bool success = true;
+
+    SOSAccountForEachKnownCircle(account, ^(CFStringRef name) { // Incompatible
+        success = false;
+        SOSCreateError(kSOSErrorIncompatibleCircle, CFSTR("Incompatible circle"), NULL, error);
+    }, ^(SOSCircleRef circle) {                                 // No Peer
+        success = SOSAccountJoinThisCircle(account, user_key, circle, use_cloud_identity, error) && success;
+    }, ^(SOSCircleRef circle, SOSFullPeerInfoRef full_peer) {   // Have Peer
+        SOSPeerInfoRef myPeer = SOSFullPeerInfoGetPeerInfo(full_peer);
+        if(SOSCircleHasPeer(circle, myPeer, NULL)) goto already_present;
+        if(SOSCircleHasApplicant(circle, myPeer, NULL))  goto already_applied;
+        if(SOSCircleHasRejectedApplicant(circle, myPeer, NULL)) {
+            SOSCircleRemoveRejectedPeer(circle, myPeer, NULL);
+        }
+        
+        secerror("Resetting my peer (ID: %@) for circle '%@' during application", SOSPeerInfoGetPeerID(myPeer), SOSCircleGetName(circle));
+        CFErrorRef localError = NULL;
+        if (!SOSAccountDestroyCirclePeerInfo(account, circle, &localError)) {
+            secerror("Failed to destroy peer (%@) during application, error=%@", myPeer, localError);
+            CFReleaseNull(localError);
+        }
+    already_applied:
+        success = SOSAccountJoinThisCircle(account, user_key, circle, use_cloud_identity, error) && success;
+        return;
+    already_present:
+        success = true;
+        return;
+    });
+
+    if(success) account->departure_code = kSOSNeverLeftCircle;
+
+    return success;
+}
+
+bool SOSAccountJoinCircles(SOSAccountRef account, CFErrorRef* error) {
+    return SOSAccountJoinCircles_internal(account, false, error);
+}
+
+
+bool SOSAccountJoinCirclesAfterRestore(SOSAccountRef account, CFErrorRef* error) {
+    return SOSAccountJoinCircles_internal(account, true, error);
+}
+
+
+bool SOSAccountLeaveCircles(SOSAccountRef account, CFErrorRef* error)
+{
+    __block bool result = true;
+    
+    SOSAccountForEachKnownCircle(account, NULL, NULL, ^(SOSCircleRef circle, SOSFullPeerInfoRef myCirclePeer) {
+        SOSAccountModifyCircle(account, SOSCircleGetName(circle), error, ^(SOSCircleRef circle) {
+               result = sosAccountLeaveCircle(account, circle, error); // TODO: What about multiple errors!
+               });
+    });
+
+    account->departure_code = kSOSWithdrewMembership;
+
+    return SOSAccountSendPendingChanges(account, error) && result;
+}
+
+bool SOSAccountBail(SOSAccountRef account, uint64_t limit_in_seconds, CFErrorRef* error)
+{
+    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
+    dispatch_group_t group = dispatch_group_create();
+    __block bool result = false;
+    
+    secnotice("circle", "Attempting to leave circle - best effort - in %llu seconds\n", limit_in_seconds);
+    // Add a task to the group
+    dispatch_group_async(group, queue, ^{
+        SOSAccountForEachKnownCircle(account, NULL, NULL, ^(SOSCircleRef circle, SOSFullPeerInfoRef myCirclePeer) {
+            SOSAccountModifyCircle(account, SOSCircleGetName(circle), error, ^(SOSCircleRef circle) {
+                result = sosAccountLeaveCircle(account, circle, error); // TODO: What about multiple errors!
+            });
+        });
+        
+        account->departure_code = kSOSWithdrewMembership;
+        if(result) result = SOSAccountSendPendingChanges(account, error);
+    });
+    dispatch_time_t milestone = dispatch_time(DISPATCH_TIME_NOW, limit_in_seconds * NSEC_PER_SEC);
+
+    dispatch_group_wait(group, milestone);
+    dispatch_release(group);
+    return result;
+}
+
+
+static void for_each_applicant_in_each_circle(SOSAccountRef account, CFArrayRef peer_infos,
+                                              void (^action)(SOSCircleRef circle, SOSFullPeerInfoRef myCirclePeer, SOSPeerInfoRef peer)) {
+    SOSAccountForEachKnownCircle(account, NULL, NULL, ^(SOSCircleRef circle, SOSFullPeerInfoRef full_peer) {
+        SOSPeerInfoRef me = SOSFullPeerInfoGetPeerInfo(full_peer);
+        CFErrorRef peer_error = NULL;
+        if (SOSCircleHasPeer(circle, me, &peer_error)) {
+            CFArrayForEach(peer_infos, ^(const void *value) {
+                SOSPeerInfoRef peer = (SOSPeerInfoRef) value;
+                if (SOSCircleHasApplicant(circle, peer, NULL)) {
+                    SOSAccountModifyCircle(account, SOSCircleGetName(circle), NULL, ^(SOSCircleRef circle) {
+                        action(circle, full_peer, peer);
+                    });
+                }
+            });
+        }
+        if (peer_error)
+            secerror("Got error in SOSCircleHasPeer: %@", peer_error);
+        CFReleaseSafe(peer_error); // TODO: We should be accumulating errors here.
+    });
+}
+
+bool SOSAccountAcceptApplicants(SOSAccountRef account, CFArrayRef applicants, CFErrorRef* error) {
+    SecKeyRef user_key = SOSAccountGetPrivateCredential(account, error);
+    if (!user_key)
+        return false;
+
+    __block bool success = true;
+       __block int64_t num_peers = 0;
+
+    for_each_applicant_in_each_circle(account, applicants, ^(SOSCircleRef circle, SOSFullPeerInfoRef myCirclePeer, SOSPeerInfoRef peer) {
+        if (!SOSCircleAcceptRequest(circle, user_key, myCirclePeer, peer, error))
+            success = false;
+               else
+                       num_peers = MAX(num_peers, SOSCircleCountPeers(circle));
+    });
+       
+    return success;
+}
+
+bool SOSAccountRejectApplicants(SOSAccountRef account, CFArrayRef applicants, CFErrorRef* error) {
+    __block bool success = true;
+       __block int64_t num_peers = 0;
+
+    for_each_applicant_in_each_circle(account, applicants, ^(SOSCircleRef circle, SOSFullPeerInfoRef myCirclePeer, SOSPeerInfoRef peer) {
+        if (!SOSCircleRejectRequest(circle, myCirclePeer, peer, error))
+            success = false;
+               else
+                       num_peers = MAX(num_peers, SOSCircleCountPeers(circle));
+    });
+
+    return success;
+}
+
+bool SOSAccountResetToOffering(SOSAccountRef account, CFErrorRef* error) {
+    SecKeyRef user_key = SOSAccountGetPrivateCredential(account, error);
+    if (!user_key)
+        return false;
+
+    __block bool result = true;
+
+    SOSAccountForEachKnownCircle(account, ^(CFStringRef name) {
+        SOSCircleRef circle = SOSCircleCreate(NULL, name, NULL);
+        if (circle)
+            CFDictionaryAddValue(account->circles, name, circle);
+        
+        SOSAccountResetThisCircleToOffering(account, circle, user_key, error);
+    }, ^(SOSCircleRef circle) {
+        SOSAccountResetThisCircleToOffering(account, circle, user_key, error);
+    }, ^(SOSCircleRef circle, SOSFullPeerInfoRef full_peer) {
+        SOSAccountResetThisCircleToOffering(account, circle, user_key, error);
+    });
+
+    return result;
+}
+
+bool SOSAccountResetToEmpty(SOSAccountRef account, CFErrorRef* error) {
+    if (!SOSAccountHasPublicKey(account, error))
+        return false;
+
+    __block bool result = true;
+    SOSAccountForEachCircle(account, ^(SOSCircleRef circle) {
+        SOSAccountModifyCircle(account, SOSCircleGetName(circle), error, ^(SOSCircleRef circle) {
+            if (!SOSCircleResetToEmpty(circle, error))
+            {
+                secerror("error: %@", *error);
+                result = false;
+            }
+            account->departure_code = kSOSWithdrewMembership;
+        });
+    });
+
+    return result;
+}
+
+CFArrayRef SOSAccountCopyApplicants(SOSAccountRef account, CFErrorRef *error) {
+    if (!SOSAccountHasPublicKey(account, error))
+        return NULL;
+    CFMutableArrayRef applicants = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
+    SOSAccountForEachCircle(account, ^(SOSCircleRef circle) {
+        SOSCircleForEachApplicant(circle, ^(SOSPeerInfoRef peer) {
+            CFArrayAppendValue(applicants, peer);
+        });
+    });
+
+    return applicants;
+}
+
+CFArrayRef SOSAccountCopyPeers(SOSAccountRef account, CFErrorRef *error) {
+    if (!SOSAccountHasPublicKey(account, error))
+        return NULL;
+
+    CFMutableArrayRef peers = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
+
+    SOSAccountForEachCircle(account, ^(SOSCircleRef circle) {
+        SOSCircleForEachPeer(circle, ^(SOSPeerInfoRef peer) {
+            CFArrayAppendValue(peers, peer);
+        });
+    });
+
+    return peers;
+}
+
+CFArrayRef SOSAccountCopyActivePeers(SOSAccountRef account, CFErrorRef *error) {
+    if (!SOSAccountHasPublicKey(account, error))
+        return NULL;
+    
+    CFMutableArrayRef peers = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
+    
+    SOSAccountForEachCircle(account, ^(SOSCircleRef circle) {
+        SOSCircleForEachActivePeer(circle, ^(SOSPeerInfoRef peer) {
+            CFArrayAppendValue(peers, peer);
+        });
+    });
+    
+    return peers;
+}
+
+CFArrayRef SOSAccountCopyActiveValidPeers(SOSAccountRef account, CFErrorRef *error) {
+    if (!SOSAccountHasPublicKey(account, error))
+        return NULL;
+    
+    CFMutableArrayRef peers = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
+    
+    SOSAccountForEachCircle(account, ^(SOSCircleRef circle) {
+        SOSCircleForEachActiveValidPeer(circle, account->user_public, ^(SOSPeerInfoRef peer) {
+            CFArrayAppendValue(peers, peer);
+        });
+    });
+    
+    return peers;
+}
+
+
+CFArrayRef SOSAccountCopyConcurringPeers(SOSAccountRef account, CFErrorRef *error)
+{
+    if (!SOSAccountHasPublicKey(account, error))
+        return NULL;
+
+    CFMutableArrayRef concurringPeers = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
+
+    SOSAccountForEachCircle(account, ^(SOSCircleRef circle) {
+        CFMutableArrayRef circleConcurring = SOSCircleCopyConcurringPeers(circle, NULL);
+        CFArrayAppendArray(concurringPeers, circleConcurring, CFRangeMake(0, CFArrayGetCount(circleConcurring)));
+        CFReleaseSafe(circleConcurring);
+    });
+
+    return concurringPeers;
+}
+
+CFStringRef SOSAccountCopyIncompatibilityInfo(SOSAccountRef account, CFErrorRef* error)
+{
+    return CFSTR("We're compatible, go away");
+}
+
+enum DepartureReason SOSAccountGetLastDepartureReason(SOSAccountRef account, CFErrorRef* error)
+{
+    return account->departure_code;
+}
+
+//
+// TODO: Handle '|' and "¬" in other strings.
+//
+const CFStringRef kSOSKVSKeyParametersKey = CFSTR(">KeyParameters");
+const CFStringRef kSOSKVSInitialSyncKey = CFSTR("^InitialSync");
+const CFStringRef kSOSKVSAccountChangedKey = CFSTR("^AccountChanged");
+
+const CFStringRef sWarningPrefix = CFSTR("!");
+const CFStringRef sAncientCirclePrefix = CFSTR("@");
+const CFStringRef sCirclePrefix = CFSTR("o");
+const CFStringRef sRetirementPrefix = CFSTR("-");
+const CFStringRef sCircleSeparator = CFSTR("|");
+const CFStringRef sFromToSeparator = CFSTR(":");
+
+static CFStringRef stringEndingIn(CFMutableStringRef in, CFStringRef token) {
+    if(token == NULL) return CFStringCreateCopy(NULL, in);
+    CFRange tokenAt = CFStringFind(in, token, 0);
+    if(tokenAt.location == kCFNotFound) return NULL;
+    CFStringRef retval = CFStringCreateWithSubstring(NULL, in, CFRangeMake(0, tokenAt.location));
+    CFStringDelete(in, CFRangeMake(0, tokenAt.location+1));
+    return retval;
+}
+
+SOSKVSKeyType SOSKVSKeyGetKeyTypeAndParse(CFStringRef key, CFStringRef *circle, CFStringRef *from, CFStringRef *to)
+{
+    SOSKVSKeyType retval = kUnknownKey;
+    
+    if(CFStringHasPrefix(key, sCirclePrefix)) retval = kCircleKey;
+    else if(CFStringHasPrefix(key, sRetirementPrefix)) retval = kRetirementKey;
+    else if(CFStringHasPrefix(key, kSOSKVSKeyParametersKey)) retval = kParametersKey;
+    else if(CFStringHasPrefix(key, kSOSKVSInitialSyncKey)) retval = kInitialSyncKey;
+    else if(CFStringHasPrefix(key, kSOSKVSAccountChangedKey)) retval = kAccountChangedKey;
+    else retval = kMessageKey;
+    
+    switch(retval) {
+        case kCircleKey:
+            if (circle) {
+                CFRange fromRange = CFRangeMake(1, CFStringGetLength(key)-1);
+                *circle = CFStringCreateWithSubstring(NULL, key, fromRange);
+            }
+            break;
+        case kMessageKey: {
+                CFStringRef mCircle = NULL;
+                CFStringRef mFrom = NULL;
+                CFStringRef mTo = NULL;
+                CFMutableStringRef keycopy = CFStringCreateMutableCopy(NULL, 128, key);
+
+                if( ((mCircle = stringEndingIn(keycopy, sCircleSeparator)) != NULL) &&
+                    ((mFrom = stringEndingIn(keycopy, sFromToSeparator)) != NULL) &&
+                    (CFStringGetLength(mFrom) > 0)  ) {
+                        mTo = stringEndingIn(keycopy, NULL);                
+                        if (circle) *circle = CFStringCreateCopy(NULL, mCircle);
+                        if (from) *from = CFStringCreateCopy(NULL, mFrom);
+                        if (to && mTo) *to = CFStringCreateCopy(NULL, mTo);
+                } else {
+                    retval = kUnknownKey;
+                }
+                CFReleaseNull(mCircle);
+                CFReleaseNull(mFrom);
+                CFReleaseNull(mTo);
+                CFReleaseNull(keycopy);
+            }
+            break;
+        case kRetirementKey: {
+                CFStringRef mCircle = NULL;
+                CFStringRef mPeer = NULL;
+                CFMutableStringRef keycopy = CFStringCreateMutableCopy(NULL, 128, key);
+                CFStringDelete(keycopy, CFRangeMake(0, 1));
+                if( ((mCircle = stringEndingIn(keycopy, sCircleSeparator)) != NULL) &&
+                    ((mPeer = stringEndingIn(keycopy, NULL)) != NULL)) {
+                    if (circle) *circle = CFStringCreateCopy(NULL, mCircle);
+                    if (from) *from = CFStringCreateCopy(NULL, mPeer);
+                } else {
+                    retval = kUnknownKey;
+                }
+                // TODO - Update our circle
+                CFReleaseNull(mCircle);
+                CFReleaseNull(mPeer);
+                CFReleaseNull(keycopy);
+            }
+            break;
+        case kAccountChangedKey:
+        case kParametersKey:
+        case kInitialSyncKey:
+        case kUnknownKey:
+            break;
+    }
+    
+    return retval;
+}
+
+
+SOSKVSKeyType SOSKVSKeyGetKeyType(CFStringRef key)
+{
+    return SOSKVSKeyGetKeyTypeAndParse(key, NULL, NULL, NULL);
+}
+
+CFStringRef SOSCircleKeyCreateWithCircle(SOSCircleRef circle, CFErrorRef *error)
+{
+    return SOSCircleKeyCreateWithName(SOSCircleGetName(circle), error);
+}
+
+
+CFStringRef SOSCircleKeyCreateWithName(CFStringRef circleName, CFErrorRef *error)
+{
+    return CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), sCirclePrefix, circleName);
+}
+
+CFStringRef SOSCircleKeyCopyCircleName(CFStringRef key, CFErrorRef *error)
+{
+    CFStringRef circleName = NULL;
+    
+    if (kCircleKey != SOSKVSKeyGetKeyTypeAndParse(key, &circleName, NULL, NULL)) {
+        SOSCreateErrorWithFormat(kSOSErrorNoCircleName, NULL, error, NULL, CFSTR("Couldn't find circle name in key '%@'"), key);
+        
+        CFReleaseNull(circleName);
+    }
+    
+    return circleName;
+}
+
+CFStringRef SOSMessageKeyCopyCircleName(CFStringRef key, CFErrorRef *error)
+{
+    CFStringRef circleName = NULL;
+    
+    if (SOSKVSKeyGetKeyTypeAndParse(key, &circleName, NULL, NULL) != kMessageKey) {
+        SOSCreateErrorWithFormat(kSOSErrorNoCircleName, NULL, error, NULL, CFSTR("Couldn't find circle name in key '%@'"), key);
+        
+        CFReleaseNull(circleName);
+    }        
+    return circleName;
+}
+
+CFStringRef SOSMessageKeyCopyFromPeerName(CFStringRef messageKey, CFErrorRef *error)
+{
+    CFStringRef fromPeer = NULL;
+    
+    if (SOSKVSKeyGetKeyTypeAndParse(messageKey, NULL, &fromPeer, NULL) != kMessageKey) {
+        SOSCreateErrorWithFormat(kSOSErrorNoCircleName, NULL, error, NULL, CFSTR("Couldn't find from peer in key '%@'"), messageKey);
+        
+        CFReleaseNull(fromPeer);
+    }
+    return fromPeer;
+}
+
+CFStringRef SOSMessageKeyCreateWithCircleAndPeerNames(SOSCircleRef circle, CFStringRef from_peer_name, CFStringRef to_peer_name)
+{
+    return CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@%@%@%@"),
+                                    SOSCircleGetName(circle), sCircleSeparator, from_peer_name, sFromToSeparator, to_peer_name);
+}
+
+CFStringRef SOSMessageKeyCreateWithCircleAndPeerInfos(SOSCircleRef circle, SOSPeerInfoRef from_peer, SOSPeerInfoRef to_peer)
+{
+    return SOSMessageKeyCreateWithCircleAndPeerNames(circle, SOSPeerInfoGetPeerID(from_peer), SOSPeerInfoGetPeerID(to_peer));
+}
+
+CFStringRef SOSMessageKeyCreateWithAccountAndPeer(SOSAccountRef account, SOSCircleRef circle, CFStringRef peer_name) {
+    // TODO: Handle errors!
+    CFErrorRef error = NULL;
+
+    SOSFullPeerInfoRef me = SOSAccountGetMyFullPeerInCircle(account, circle, &error);
+    SOSPeerInfoRef my_pi = SOSFullPeerInfoGetPeerInfo(me);
+    CFStringRef result = SOSMessageKeyCreateWithCircleAndPeerNames(circle, SOSPeerInfoGetPeerID(my_pi), peer_name);
+    CFReleaseSafe(error);
+    return result;
+}
+
+CFStringRef SOSRetirementKeyCreateWithCircleAndPeer(SOSCircleRef circle, CFStringRef retirement_peer_name)
+{
+     return CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@%@%@"),
+                                    sRetirementPrefix, SOSCircleGetName(circle), sCircleSeparator, retirement_peer_name);
+}
+
+
+static SOSPeerCoderStatus SOSAccountHandlePeerMessage(SOSAccountRef account,
+                                        CFStringRef circle_id,
+                                        CFStringRef peer_name,
+                                        CFDataRef message,
+                                        SOSAccountSendBlock send_block,
+                                        CFErrorRef *error)
+{
+    bool success = false;
+    CFStringRef peer_key = NULL;
+
+    SOSCircleRef circle = SOSAccountFindCircle(account, circle_id, error);
+    require_quiet(circle, fail);
+    SOSFullPeerInfoRef myFullPeer = SOSAccountGetMyFullPeerInCircle(account, circle, error);
+    SOSPeerInfoRef myPeer = SOSFullPeerInfoGetPeerInfo(myFullPeer);
+    require_action_quiet(SOSCircleHasPeer(circle, myPeer, NULL), fail, SOSCreateErrorWithFormat(kSOSErrorNotReady, NULL, error, NULL, CFSTR("Not in circle, can't handle message")));
+    
+    peer_key = SOSMessageKeyCreateWithAccountAndPeer(account, circle, peer_name);
+
+    SOSPeerSendBlock peer_send_block = ^bool (CFDataRef message, CFErrorRef *error) {
+        return send_block(circle, peer_key, message, error);
+    };
+
+    success = SOSCircleHandlePeerMessage(circle, myFullPeer, account->factory, peer_send_block, peer_name, message, error);
+
+fail:
+    CFReleaseNull(peer_key);
+    return success;
+}
+
+bool SOSAccountHandleUpdates(SOSAccountRef account,
+                             CFDictionaryRef updates,
+                             CFErrorRef *error) {
+    
+    if(CFDictionaryGetValue(updates, kSOSKVSAccountChangedKey) != NULL) {
+        SOSAccountSetToNew(account);
+    }
+
+    CFTypeRef parameters = CFDictionaryGetValue(updates, kSOSKVSKeyParametersKey);
+    if (isData(parameters)) {
+        SecKeyRef newKey = NULL;
+        CFDataRef newParameters = NULL;
+        const uint8_t *parse_end = der_decode_cloud_parameters(kCFAllocatorDefault, kSecECDSAAlgorithmID,
+                                                               &newKey, &newParameters, error,
+                                                               CFDataGetBytePtr(parameters), CFDataGetPastEndPtr(parameters));
+
+        if (parse_end == CFDataGetPastEndPtr(parameters)) {
+            if (CFEqualSafe(account->user_public, newKey)) {
+                secnotice("updates", "Got same public key sent our way. Ignoring.");
+            } else if (CFEqualSafe(account->previous_public, newKey)) {
+                secnotice("updates", "Got previous public key repeated. Ignoring.");
+            } else {
+                CFReleaseNull(account->user_public);
+                SOSAccountPurgePrivateCredential(account);
+                CFReleaseNull(account->user_key_parameters);
+
+                account->user_public_trusted = false;
+
+                account->user_public = newKey;
+                newKey = NULL;
+
+                account->user_key_parameters = newParameters;
+                newParameters = NULL;
+
+                secnotice("updates", "Got new parameters for public key: %@", account->user_public);
+                debugDumpUserParameters(CFSTR("params"), account->user_key_parameters);
+            }
+        }
+
+        CFReleaseNull(newKey);
+        CFReleaseNull(newParameters);
+    }
+
+    if (!account->user_public_trusted) {
+        if (!account->deferred_updates) {
+            account->deferred_updates = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
+        }
+        
+        CFDictionaryForEach(updates, ^(const void *key, const void *value) {
+            if (!CFEqualSafe(key, kSOSKVSKeyParametersKey) && !CFEqualSafe(key, kSOSKVSAccountChangedKey))
+                CFDictionarySetValue(account->deferred_updates, key, value);
+        });
+        secnotice("updates", "No public peer key, deferring updates: %@", updates);
+        return true;
+    }
+
+    // Iterate though keys in updates.  Perform circle change update.
+    // Then instantiate circles and engines and peers for all peers that
+    // are receiving a message in updates.
+    __block bool is_initial_sync = CFDictionaryContainsKey(updates, kSOSKVSInitialSyncKey);
+
+    CFDictionaryForEach(updates, ^(const void *key, const void *value) {
+        CFStringRef circle_name = NULL;
+        CFErrorRef localError = NULL;
+        SOSCircleRef circle = NULL;
+        
+        if (SOSKVSKeyGetKeyTypeAndParse(key, &circle_name, NULL, NULL) == kCircleKey) {
+            circle = SOSAccountCreateCircleFrom(circle_name, value, &localError);
+            if (!circle) {
+                if (isSOSErrorCoded(localError, kSOSErrorIncompatibleCircle)) {
+                    SOSAccountDestroyCirclePeerInfoNamed(account, circle_name, NULL);
+                    CFDictionarySetValue(account->circles, circle_name, kCFNull);
+                } else {
+                    SOSCreateErrorWithFormat(kSOSErrorNameMismatch, localError, error, NULL,
+                                         CFSTR("Bad key for message, no circle '%@'"), key);
+                    goto circle_done;
+                }
+            }
+
+            if (!SOSAccountUpdateCircleFromRemote(account, circle, is_initial_sync, &localError)) {
+                SOSCreateErrorWithFormat(kSOSErrorProcessingFailure, localError, error, NULL,
+                                         CFSTR("Error handling circle change '%@'"), key);
+                secnotice("update", "Error updating circle '%@': %@", key, circle);
+                goto circle_done;
+            }
+        }
+        circle_done:
+        CFReleaseSafe(circle_name);
+        CFReleaseNull(circle);
+        CFReleaseNull(localError);
+    });
+    
+    CFDictionaryForEach(updates, ^(const void *key, const void *value) {
+        CFErrorRef localError = NULL;
+        CFStringRef circle_name = NULL;
+        CFStringRef from_name = NULL;
+        CFStringRef to_name = NULL;
+        switch (SOSKVSKeyGetKeyTypeAndParse(key, &circle_name, &from_name, &to_name)) {
+            case kParametersKey:
+            case kInitialSyncKey:
+            case kCircleKey:
+                break;
+            case kMessageKey:
+            {
+                SOSFullPeerInfoRef my_peer = NULL;
+
+                require_action_quiet(isData(value), message_error, SOSCreateErrorWithFormat(kSOSErrorUnexpectedType, localError, error, NULL, CFSTR("Non-Data for message(%@) from '%@'"), value, key));
+                require_quiet(my_peer = SOSAccountGetMyFullPeerInCircleNamedIfPresent(account, circle_name, &localError), message_error);
+                
+                CFStringRef my_id = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(my_peer));
+                require_quiet(SOSAccountIsActivePeerInCircleNamed(account, circle_name, my_id, &localError), skip);
+                require_quiet(CFEqual(my_id, to_name), skip);
+                require_quiet(!CFEqual(my_id, from_name), skip);
+
+                SOSAccountSendBlock cacheInDictionary = ^ bool (SOSCircleRef circle, CFStringRef key, CFDataRef new_message, CFErrorRef* error) {
+                    CFDictionarySetValue(account->pending_changes, key, new_message);
+                    
+                    if (account->processed_message_block) {
+                        account->processed_message_block(circle, value, new_message);
+                    }
+                    
+                    return true;
+                };
+                
+                if (SOSAccountHandlePeerMessage(account, circle_name, from_name, value, cacheInDictionary, &localError) == kSOSPeerCoderFailure) {
+                    SOSCreateErrorWithFormat(kSOSErrorNameMismatch, localError, error, NULL,
+                                             CFSTR("Error handling peer message from '%@'"), key);
+                    localError = NULL; // Released by SOSCreateErrorWithFormat
+                    goto message_error;
+                }
+
+            message_error:
+            skip:
+                break;
+            }
+            case kRetirementKey:
+                if(isData(value)) {                
+                    SOSPeerInfoRef pi = SOSPeerInfoCreateFromData(NULL, error, (CFDataRef) value);
+                    if(pi && CFEqual(from_name, SOSPeerInfoGetPeerID(pi)) && SOSPeerInfoInspectRetirementTicket(pi, error)) {
+                        CFDictionarySetValue(account->retired_peers, key, value);
+                        SOSAccountRecordRetiredPeerInCircleNamed(account, circle_name, pi);
+                    }
+                    CFReleaseSafe(pi);
+                }
+                break;
+            
+            case kAccountChangedKey: // Handled at entry to function to make sure these are processed first.
+                break;
+                
+            case kUnknownKey:
+                secnotice("updates", "Unknown key '%@', ignoring", key);
+                break;
+            
+        }
+        
+        CFReleaseNull(circle_name);
+        CFReleaseNull(from_name);
+        CFReleaseNull(to_name);
+
+        if (error && *error)
+            secerror("Peer message processing error for: %@ -> %@ (%@)", key, value, *error);
+        if (localError)
+            secerror("Peer message local processing error for: %@ -> %@ (%@)", key, value, localError);
+
+        CFReleaseNull(localError);
+    });
+    
+    return SOSAccountSendPendingChanges(account, error);
+}
+
+void SOSAccountSetMessageProcessedBlock(SOSAccountRef account, SOSAccountMessageProcessedBlock processedBlock)
+{
+    CFRetainSafe(processedBlock);
+    CFReleaseNull(account->processed_message_block);
+    account->processed_message_block = processedBlock;
+}
+
+CFStringRef SOSInterestListCopyDescription(CFArrayRef interests)
+{
+    CFMutableStringRef description = CFStringCreateMutable(kCFAllocatorDefault, 0);
+    CFStringAppendFormat(description, NULL, CFSTR("<Interest: "));
+    
+    CFArrayForEach(interests, ^(const void* string) {
+        if (isString(string))
+            CFStringAppendFormat(description, NULL, CFSTR(" '%@'"), string);
+    });
+    CFStringAppend(description, CFSTR(">"));
+
+    return description;
+}
diff --git a/sec/SOSCircle/SecureObjectSync/SOSAccount.h b/sec/SOSCircle/SecureObjectSync/SOSAccount.h
new file mode 100644 (file)
index 0000000..005975b
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * Created by Michael Brouwer on 6/22/12.
+ * Copyright 2012 Apple Inc. All Rights Reserved.
+ */
+
+/*!
+ @header SOSAccount.h
+ The functions provided in SOSCircle.h provide an interface to a
+ secure object syncing circle for a single class
+ */
+
+#ifndef _SOSACCOUNT_H_
+#define _SOSACCOUNT_H_
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <SecureObjectSync/SOSCircle.h>
+#include <SecureObjectSync/SOSFullPeerInfo.h>
+#include <SecureObjectSync/SOSCloudCircle.h>
+#include <dispatch/dispatch.h>
+
+__BEGIN_DECLS
+
+#define RETIREMENT_FINALIZATION_SECONDS (24*60*60)
+
+
+/* Forward declarations of SOS types. */
+typedef struct __OpaqueSOSAccount *SOSAccountRef;
+
+typedef void (^SOSAccountKeyInterestBlock)(bool getNewKeysOnly, CFArrayRef alwaysKeys, CFArrayRef afterFirstUnlockKeys, CFArrayRef unlockedKeys);
+typedef bool (^SOSAccountDataUpdateBlock)(CFDictionaryRef keys, CFErrorRef *error);
+typedef void (^SOSAccountCircleMembershipChangeBlock)(SOSCircleRef new_circle,
+                                                      CFArrayRef added_peers, CFArrayRef removed_peers,
+                                                      CFArrayRef added_applicants, CFArrayRef removed_applicants);
+
+SOSAccountRef SOSAccountGetShared(void);
+SOSAccountRef SOSAccountCreate(CFAllocatorRef allocator,
+                               CFDictionaryRef gestalt,
+                               SOSDataSourceFactoryRef factory,
+                               SOSAccountKeyInterestBlock interest_block,
+                               SOSAccountDataUpdateBlock update_block);
+
+//
+// MARK: Persistent Encode decode
+//
+
+SOSAccountRef SOSAccountCreateFromDER(CFAllocatorRef allocator, SOSDataSourceFactoryRef factory,
+                                      SOSAccountKeyInterestBlock interest_block, SOSAccountDataUpdateBlock update_block,
+                                      CFErrorRef* error,
+                                      const uint8_t** der_p, const uint8_t *der_end);
+
+SOSAccountRef SOSAccountCreateFromDER_V3(CFAllocatorRef allocator,
+                                         SOSDataSourceFactoryRef factory,
+                                         SOSAccountKeyInterestBlock interest_block,
+                                         SOSAccountDataUpdateBlock update_block,
+                                         CFErrorRef* error,
+                                         const uint8_t** der_p, const uint8_t *der_end);
+
+SOSAccountRef SOSAccountCreateFromData(CFAllocatorRef allocator, CFDataRef circleData,
+                                       SOSDataSourceFactoryRef factory,
+                                       SOSAccountKeyInterestBlock interest_block, SOSAccountDataUpdateBlock update_block,
+                                       CFErrorRef* error);
+
+size_t SOSAccountGetDEREncodedSize(SOSAccountRef cir, CFErrorRef *error);
+uint8_t* SOSAccountEncodeToDER(SOSAccountRef cir, CFErrorRef* error, const uint8_t* der, uint8_t* der_end);
+size_t SOSAccountGetDEREncodedSize_V3(SOSAccountRef cir, CFErrorRef *error);
+uint8_t* SOSAccountEncodeToDER_V3(SOSAccountRef cir, CFErrorRef* error, const uint8_t* der, uint8_t* der_end);
+CFDataRef SOSAccountCopyEncodedData(SOSAccountRef circle, CFAllocatorRef allocator, CFErrorRef *error);
+
+
+//
+// MARK: Local Peer finding
+//
+SOSPeerInfoRef SOSAccountGetMyPeerInCircle(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error);
+SOSPeerInfoRef SOSAccountGetMyPeerInCircleNamed(SOSAccountRef account, CFStringRef circle, CFErrorRef* error);
+
+SOSFullPeerInfoRef SOSAccountGetMyFullPeerInCircle(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error);
+SOSFullPeerInfoRef SOSAccountGetMyFullPeerInCircleNamed(SOSAccountRef account, CFStringRef name, CFErrorRef *error);
+
+//
+// MARK: Credential management
+//
+
+SecKeyRef SOSAccountGetPrivateCredential(SOSAccountRef account, CFErrorRef* error);
+void SOSAccountPurgePrivateCredential(SOSAccountRef account);
+
+bool SOSAccountTryUserCredentials(SOSAccountRef account,
+                                  CFStringRef user_account, CFDataRef user_password,
+                                  CFErrorRef *error);
+
+bool SOSAccountAssertUserCredentials(SOSAccountRef account,
+                                     CFStringRef user_account, CFDataRef user_password,
+                                     CFErrorRef *error);
+
+
+//
+// MARK: Circle management
+//
+int SOSAccountCountCircles(SOSAccountRef a);
+
+void SOSAccountForEachCircle(SOSAccountRef account, void (^process)(SOSCircleRef circle));
+
+SOSCircleRef SOSAccountFindCompatibleCircle(SOSAccountRef a, CFStringRef name);
+SOSCircleRef SOSAccountFindCircle(SOSAccountRef a, CFStringRef name, CFErrorRef *error);
+SOSCircleRef SOSAccountEnsureCircle(SOSAccountRef a, CFStringRef name, CFErrorRef *error);
+bool SOSAccountUpdateCircle(SOSAccountRef account, SOSCircleRef circle, CFErrorRef *error);
+
+bool SOSAccountModifyCircle(SOSAccountRef account,
+                            CFStringRef circleName,
+                            CFErrorRef *error,
+                            void (^action)(SOSCircleRef circle));
+
+
+SOSCCStatus SOSAccountIsInCircles(SOSAccountRef account, CFErrorRef* error);
+bool SOSAccountJoinCircles(SOSAccountRef account, CFErrorRef* error);
+bool SOSAccountJoinCirclesAfterRestore(SOSAccountRef account, CFErrorRef* error);
+bool SOSAccountLeaveCircles(SOSAccountRef account, CFErrorRef* error);
+bool SOSAccountBail(SOSAccountRef account, uint64_t limit_in_seconds, CFErrorRef* error);
+bool SOSAccountAcceptApplicants(SOSAccountRef account, CFArrayRef applicants, CFErrorRef* error);
+bool SOSAccountRejectApplicants(SOSAccountRef account, CFArrayRef applicants, CFErrorRef* error);
+
+bool SOSAccountResetToOffering(SOSAccountRef account, CFErrorRef* error);
+bool SOSAccountResetToEmpty(SOSAccountRef account, CFErrorRef* error);
+
+CFArrayRef SOSAccountCopyApplicants(SOSAccountRef account, CFErrorRef *error);
+CFArrayRef SOSAccountCopyPeers(SOSAccountRef account, CFErrorRef *error);
+CFArrayRef SOSAccountCopyActivePeers(SOSAccountRef account, CFErrorRef *error);
+CFArrayRef SOSAccountCopyActiveValidPeers(SOSAccountRef account, CFErrorRef *error);
+CFArrayRef SOSAccountCopyConcurringPeers(SOSAccountRef account, CFErrorRef *error);
+
+CFArrayRef SOSAccountCopyAccountIdentityPeerInfos(SOSAccountRef account, CFAllocatorRef allocator, CFErrorRef* error);
+bool SOSAccountIsAccountIdentity(SOSAccountRef account, SOSPeerInfoRef peer_info, CFErrorRef *error);
+
+enum DepartureReason SOSAccountGetLastDepartureReason(SOSAccountRef account, CFErrorRef* error);
+
+//
+// MARK: Change blocks
+//
+void SOSAccountAddChangeBlock(SOSAccountRef a, SOSAccountCircleMembershipChangeBlock changeBlock);
+void SOSAccountRemoveChangeBlock(SOSAccountRef a, SOSAccountCircleMembershipChangeBlock changeBlock);
+
+//
+// MARK: Local device gestalt change.
+//
+bool SOSAccountUpdateGestalt(SOSAccountRef account, CFDictionaryRef new_gestalt);
+
+// TODO: ds should be a SOSDataSourceFactoryRef
+bool SOSAccountHandleUpdates(SOSAccountRef account,
+                             CFDictionaryRef updates,
+                             CFErrorRef *error);
+
+bool SOSAccountSyncWithPeer(SOSAccountRef account, SOSCircleRef circle, SOSPeerInfoRef thisPeer, bool* didSendData, CFErrorRef* error);
+bool SOSAccountSyncWithAllPeers(SOSAccountRef account, CFErrorRef *error);
+bool SOSAccountSyncWithAllPeersInCircle(SOSAccountRef account, SOSCircleRef circle, CFErrorRef *error);
+
+bool SOSAccountCleanupAfterPeer(SOSAccountRef account, size_t seconds, SOSCircleRef circle,
+                                SOSPeerInfoRef cleanupPeer, CFErrorRef* error);
+
+bool SOSAccountCleanupRetirementTickets(SOSAccountRef account, size_t seconds, CFErrorRef* error);
+
+bool SOSAccountScanForRetired(SOSAccountRef account, SOSCircleRef circle, CFErrorRef *error);
+
+SOSCircleRef SOSAccountCloneCircleWithRetirement(SOSAccountRef account, SOSCircleRef starting_circle, CFErrorRef *error);
+
+//
+// MARK: Version incompatibility Functions
+//
+CFStringRef SOSAccountCopyIncompatibilityInfo(SOSAccountRef account, CFErrorRef* error);
+
+//
+// MARK: Private functions
+//
+
+dispatch_queue_t SOSAccountGetQueue(SOSAccountRef account);
+
+
+//
+// MARK: Private functions for testing
+//
+
+
+typedef enum {
+    kCircleKey,
+    kMessageKey,
+    kParametersKey,
+    kInitialSyncKey,
+    kRetirementKey,
+    kAccountChangedKey,
+    kUnknownKey,
+} SOSKVSKeyType;
+
+extern const CFStringRef kSOSKVSKeyParametersKey;
+extern const CFStringRef kSOSKVSInitialSyncKey;
+extern const CFStringRef kSOSKVSAccountChangedKey;
+
+SOSKVSKeyType SOSKVSKeyGetKeyType(CFStringRef key);
+SOSKVSKeyType SOSKVSKeyGetKeyTypeAndParse(CFStringRef key, CFStringRef *circle, CFStringRef *from, CFStringRef *to);
+
+CFStringRef SOSCircleKeyCreateWithCircle(SOSCircleRef circle, CFErrorRef *error);
+CFStringRef SOSCircleKeyCreateWithName(CFStringRef name, CFErrorRef *error);
+CFStringRef SOSCircleKeyCopyCircleName(CFStringRef key, CFErrorRef *error);
+
+CFStringRef SOSMessageKeyCopyCircleName(CFStringRef key, CFErrorRef *error);
+CFStringRef SOSMessageKeyCopyFromPeerName(CFStringRef messageKey, CFErrorRef *error);
+CFStringRef SOSMessageKeyCreateWithCircleAndPeerNames(SOSCircleRef circle, CFStringRef from_peer_name, CFStringRef to_peer_name);
+CFStringRef SOSMessageKeyCreateWithCircleAndPeerInfos(SOSCircleRef circle, SOSPeerInfoRef from_peer, SOSPeerInfoRef to_peer);
+CFStringRef SOSMessageKeyCreateWithAccountAndPeer(SOSAccountRef account, SOSCircleRef circle, CFStringRef peer_name);
+
+CFStringRef SOSRetirementKeyCreateWithCircleAndPeer(SOSCircleRef circle, CFStringRef retirement_peer_name);
+
+typedef void (^SOSAccountMessageProcessedBlock)(SOSCircleRef circle, CFDataRef messageIn, CFDataRef messageOut);
+typedef bool (^SOSAccountSendBlock)(SOSCircleRef circle, CFStringRef key, CFDataRef message, CFErrorRef *error);
+
+void SOSAccountSetMessageProcessedBlock(SOSAccountRef account, SOSAccountMessageProcessedBlock processedBlock);
+
+//
+// MARK: Utility functions
+//
+
+CFStringRef SOSInterestListCopyDescription(CFArrayRef interests);
+
+__END_DECLS
+
+#endif /* !_SOSACCOUNT_H_ */
diff --git a/sec/SOSCircle/SecureObjectSync/SOSCircle.c b/sec/SOSCircle/SecureObjectSync/SOSCircle.c
new file mode 100644 (file)
index 0000000..9475fc6
--- /dev/null
@@ -0,0 +1,1171 @@
+/*
+ * Created by Michael Brouwer on 6/22/12.
+ * Copyright 2012 Apple Inc. All Rights Reserved.
+ */
+
+/*
+ * SOSCircle.c -  Implementation of the secure object syncing transport
+ */
+
+#include <AssertMacros.h>
+
+#include <CoreFoundation/CFArray.h>
+#include <SecureObjectSync/SOSCircle.h>
+#include <SecureObjectSync/SOSCloudCircleInternal.h>
+#include <SecureObjectSync/SOSInternal.h>
+#include <SecureObjectSync/SOSEngine.h>
+#include <SecureObjectSync/SOSPeer.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecFramework.h>
+
+#include <Security/SecKey.h>
+#include <Security/SecKeyPriv.h>
+
+#include <utilities/SecCFWrappers.h>
+//#include "ckdUtilities.h"
+
+#include <utilities/der_plist.h>
+#include <utilities/der_plist_internal.h>
+
+#include <corecrypto/ccder.h>
+#include <corecrypto/ccdigest.h>
+#include <corecrypto/ccsha2.h>
+
+#include <stdlib.h>
+#include <assert.h>
+
+enum {
+    kOnlyCompatibleVersion = 1, // Sometime in the future this name will be improved to reflect history.
+    
+    kAlwaysIncompatibleVersion = UINT64_MAX,
+};
+
+struct __OpaqueSOSCircle {
+    CFRuntimeBase _base;
+    
+    CFStringRef name;
+    CFNumberRef generation;
+    CFMutableArrayRef peers;
+    CFMutableArrayRef applicants;
+    CFMutableArrayRef rejected_applicants;
+
+    CFMutableDictionaryRef signatures;
+};
+
+CFGiblisWithCompareFor(SOSCircle);
+
+// Move the next 2 lines to SOSPeer if we need it.
+static void SOSPeerRelease(CFAllocatorRef allocator, const void *value) {
+    SOSPeerDispose((SOSPeerRef)value);
+}
+
+static const CFDictionaryValueCallBacks dispose_peer_callbacks = { .release = SOSPeerRelease };
+
+SOSCircleRef SOSCircleCreate(CFAllocatorRef allocator, CFStringRef name, CFErrorRef *error) {
+    SOSCircleRef c = CFTypeAllocate(SOSCircle, struct __OpaqueSOSCircle, allocator);
+    int64_t gen = 1;
+
+    assert(name);
+    
+    c->name = CFStringCreateCopy(allocator, name);
+    c->generation = CFNumberCreate(allocator, kCFNumberSInt64Type, &gen);
+    c->peers = CFArrayCreateMutableForCFTypes(allocator);
+    c->applicants = CFArrayCreateMutableForCFTypes(allocator);
+    c->rejected_applicants = CFArrayCreateMutableForCFTypes(allocator);
+    c->signatures = CFDictionaryCreateMutableForCFTypes(allocator);
+
+    return c;
+}
+
+static CFNumberRef SOSCircleGenerationCopy(CFNumberRef generation) {
+    int64_t value;
+    CFAllocatorRef allocator = CFGetAllocator(generation);
+    CFNumberGetValue(generation, kCFNumberSInt64Type, &value);
+    return CFNumberCreate(allocator, kCFNumberSInt64Type, &value);
+}
+
+SOSCircleRef SOSCircleCopyCircle(CFAllocatorRef allocator, SOSCircleRef otherCircle, CFErrorRef *error)
+{
+    SOSCircleRef c = CFTypeAllocate(SOSCircle, struct __OpaqueSOSCircle, allocator);
+
+    assert(otherCircle);
+    c->name = CFStringCreateCopy(allocator, otherCircle->name);
+    c->generation = SOSCircleGenerationCopy(otherCircle->generation);
+    c->peers = CFArrayCreateMutableCopy(allocator, 0, otherCircle->peers);
+    c->applicants = CFArrayCreateMutableCopy(allocator, 0, otherCircle->applicants);
+    c->rejected_applicants = CFArrayCreateMutableCopy(allocator, 0, otherCircle->rejected_applicants);
+    c->signatures = CFDictionaryCreateMutableCopy(allocator, 0, otherCircle->signatures);
+    
+    return c;
+}
+
+static inline
+void SOSCircleAssertStable(SOSCircleRef circle)
+{
+    assert(circle);
+    assert(circle->name);
+    assert(circle->generation);
+    assert(circle->peers);
+    assert(circle->applicants);
+    assert(circle->rejected_applicants);
+    assert(circle->signatures);
+}
+
+static inline
+SOSCircleRef SOSCircleConvertAndAssertStable(CFTypeRef circleAsType)
+{
+    if (CFGetTypeID(circleAsType) != SOSCircleGetTypeID())
+        return NULL;
+
+    SOSCircleRef circle = (SOSCircleRef) circleAsType;
+
+    SOSCircleAssertStable(circle);
+
+    return circle;
+}
+
+
+static Boolean SOSCircleCompare(CFTypeRef lhs, CFTypeRef rhs) {
+    if (CFGetTypeID(lhs) != SOSCircleGetTypeID()
+     || CFGetTypeID(rhs) != SOSCircleGetTypeID())
+        return false;
+
+    SOSCircleRef left = SOSCircleConvertAndAssertStable(lhs);
+    SOSCircleRef right = SOSCircleConvertAndAssertStable(rhs);
+
+    // TODO: we should be doing set equality for peers and applicants.
+    return NULL != left && NULL != right
+        && CFEqual(left->generation, right->generation)
+        && CFEqual(left->peers, right->peers)
+        && CFEqual(left->applicants, right->applicants)
+        && CFEqual(left->rejected_applicants, right->rejected_applicants)
+        && CFEqual(left->signatures, right->signatures);
+}
+
+
+static bool SOSCircleDigestArray(const struct ccdigest_info *di, CFMutableArrayRef array, void *hash_result, CFErrorRef *error)
+{
+    __block bool success = true;
+    ccdigest_di_decl(di, array_digest);
+    const void * a_digest = array_digest;
+
+    ccdigest_init(di, array_digest);
+    CFArraySortValues(array, CFRangeMake(0, CFArrayGetCount(array)), SOSPeerInfoCompareByID, SOSPeerCmpPubKeyHash);
+    CFArrayForEach(array, ^(const void *peer) {
+        if (!SOSPeerInfoUpdateDigestWithPublicKeyBytes((SOSPeerInfoRef)peer, di, a_digest, error))
+            success = false;
+    });
+    ccdigest_final(di, array_digest, hash_result);
+
+    return success;
+}
+
+static bool SOSCircleHash(const struct ccdigest_info *di, SOSCircleRef circle, void *hash_result, CFErrorRef *error) {
+    ccdigest_di_decl(di, circle_digest);
+    ccdigest_init(di, circle_digest);
+    int64_t gen = SOSCircleGetGenerationSint(circle);
+    ccdigest_update(di, circle_digest, sizeof(gen), &gen);
+    
+    SOSCircleDigestArray(di, circle->peers, hash_result, error);
+    ccdigest_update(di, circle_digest, di->output_size, hash_result);
+    ccdigest_final(di, circle_digest, hash_result);
+    return true;
+}
+
+static bool SOSCircleSetSignature(SOSCircleRef circle, SecKeyRef pubkey, CFDataRef signature, CFErrorRef *error) {
+    bool result = false;
+    
+    CFStringRef pubKeyID = SOSCopyIDOfKey(pubkey, error);
+    require_quiet(pubKeyID, fail);
+    CFDictionarySetValue(circle->signatures, pubKeyID, signature);
+    result = true;
+
+fail:
+    CFReleaseSafe(pubKeyID);
+    return result;
+}
+
+static bool SOSCircleRemoveSignatures(SOSCircleRef circle, CFErrorRef *error) {
+    CFDictionaryRemoveAllValues(circle->signatures);
+    return true;
+}
+
+static CFDataRef SOSCircleGetSignature(SOSCircleRef circle, SecKeyRef pubkey, CFErrorRef *error) {    
+    CFStringRef pubKeyID = SOSCopyIDOfKey(pubkey, error);
+    CFDataRef result = NULL;
+    require_quiet(pubKeyID, fail);
+
+    CFTypeRef value = (CFDataRef)CFDictionaryGetValue(circle->signatures, pubKeyID);
+    
+    if (isData(value)) result = (CFDataRef) value;
+
+fail:
+    CFReleaseSafe(pubKeyID);
+    return result;
+}
+
+bool SOSCircleSign(SOSCircleRef circle, SecKeyRef privKey, CFErrorRef *error) {
+    if (!privKey) return false; // Really assertion but not always true for now.
+    CFAllocatorRef allocator = CFGetAllocator(circle);
+    uint8_t tmp[4096];
+    size_t tmplen = 4096;
+    const struct ccdigest_info *di = ccsha256_di();
+    uint8_t hash_result[di->output_size];
+    
+    SOSCircleHash(di, circle, hash_result, error);
+    OSStatus stat =  SecKeyRawSign(privKey, kSecPaddingNone, hash_result, di->output_size, tmp, &tmplen);
+    if(stat) {
+        // TODO - Create a CFErrorRef;
+        secerror("Bad Circle SecKeyRawSign, stat: %ld", (long)stat);
+        SOSCreateError(kSOSErrorBadFormat, CFSTR("Bad Circle SecKeyRawSign"), (error != NULL) ? *error : NULL, error);
+        return false;
+    };
+    CFDataRef signature = CFDataCreate(allocator, tmp, tmplen);
+    SecKeyRef publicKey = SecKeyCreatePublicFromPrivate(privKey);
+    SOSCircleSetSignature(circle, publicKey, signature, error);
+    CFReleaseNull(publicKey);
+    CFRelease(signature);
+    return true;
+}
+
+bool SOSCircleVerifySignatureExists(SOSCircleRef circle, SecKeyRef pubKey, CFErrorRef *error) {
+    if(!pubKey) {
+        // TODO ErrorRef
+        secerror("SOSCircleVerifySignatureExists no pubKey");
+        SOSCreateError(kSOSErrorBadFormat, CFSTR("SOSCircleVerifySignatureExists no pubKey"), (error != NULL) ? *error : NULL, error);
+        return false;
+    }
+    CFDataRef signature = SOSCircleGetSignature(circle, pubKey, error);
+    return NULL != signature;
+}
+
+bool SOSCircleVerify(SOSCircleRef circle, SecKeyRef pubKey, CFErrorRef *error) {
+    const struct ccdigest_info *di = ccsha256_di();
+    uint8_t hash_result[di->output_size];
+    
+    SOSCircleHash(di, circle, hash_result, error);
+
+    CFDataRef signature = SOSCircleGetSignature(circle, pubKey, error);
+    if(!signature) return false;
+
+    return SecKeyRawVerify(pubKey, kSecPaddingNone, hash_result, di->output_size,
+                           CFDataGetBytePtr(signature), CFDataGetLength(signature)) == errSecSuccess;
+}
+
+bool SOSCircleVerifyPeerSigned(SOSCircleRef circle, SOSPeerInfoRef peer, CFErrorRef *error) {
+    SecKeyRef pub_key = SOSPeerInfoCopyPubKey(peer);
+    bool result = SOSCircleVerify(circle, pub_key, error);
+    CFReleaseSafe(pub_key);
+    return result;
+}
+
+
+static CFIndex CFArrayRemoveAllPassing(CFMutableArrayRef array, bool (^test)(const void *) ){
+    CFIndex numberRemoved = 0;
+    
+    CFIndex position =  0;
+    while (position < CFArrayGetCount(array) && !test(CFArrayGetValueAtIndex(array, position)))
+        ++position;
+    
+    while (position < CFArrayGetCount(array)) {
+        CFArrayRemoveValueAtIndex(array, position);
+        ++numberRemoved;
+        while (position < CFArrayGetCount(array) && !test(CFArrayGetValueAtIndex(array, position)))
+            ++position;
+    }
+    
+    return numberRemoved;
+}
+
+static CFIndex CFArrayRemoveAllWithMatchingID(CFMutableArrayRef array, SOSPeerInfoRef peerInfo) {
+    CFStringRef peer_id = SOSPeerInfoGetPeerID(peerInfo);
+    
+    return CFArrayRemoveAllPassing(array,  ^ bool (const void *element) {
+        SOSPeerInfoRef peer = (SOSPeerInfoRef) element;
+        
+        return CFEqual(peer_id, SOSPeerInfoGetPeerID(peer));
+    });
+}
+
+static void SOSCircleRejectNonValidApplicants(SOSCircleRef circle, SecKeyRef pubkey) {
+    CFArrayRef applicants = SOSCircleCopyApplicants(circle, NULL);
+    CFArrayForEach(applicants, ^(const void *value) {
+        SOSPeerInfoRef pi = (SOSPeerInfoRef) value;
+        if(!SOSPeerInfoApplicationVerify(pi, pubkey, NULL)) {
+            CFArrayRemoveAllWithMatchingID(circle->applicants, pi);
+            CFArrayAppendValue(circle->rejected_applicants, pi);
+        }
+    });
+}
+
+bool SOSCircleGenerationSign(SOSCircleRef circle, SecKeyRef user_approver, SOSFullPeerInfoRef peerinfo, CFErrorRef *error) {
+    
+    SecKeyRef ourKey = SOSFullPeerInfoCopyDeviceKey(peerinfo, error);
+    require_quiet(ourKey, fail);
+    
+    SOSCircleRemoveRetired(circle, error); // Prune off retirees since we're signing this one
+    CFArrayRemoveAllValues(circle->rejected_applicants); // Dump rejects so we clean them up sometime.
+    SOSCircleRejectNonValidApplicants(circle, SecKeyCreatePublicFromPrivate(user_approver));
+    SOSCircleGenerationIncrement(circle);
+    require_quiet(SOSCircleRemoveSignatures(circle, error), fail);
+    require_quiet(SOSCircleSign(circle, user_approver, error), fail);
+    require_quiet(SOSCircleSign(circle, ourKey, error), fail);
+    
+    CFReleaseNull(ourKey);
+    return true;
+    
+fail:
+    CFReleaseNull(ourKey);
+    return false;
+}
+
+
+bool SOSCircleConcordanceSign(SOSCircleRef circle, SOSFullPeerInfoRef peerinfo, CFErrorRef *error) {
+    bool success = false;
+    SecKeyRef ourKey = SOSFullPeerInfoCopyDeviceKey(peerinfo, error);
+    require_quiet(ourKey, exit);
+    
+    success = SOSCircleSign(circle, ourKey, error);
+
+exit:
+    CFReleaseNull(ourKey);
+    return success;
+}
+
+static inline SOSConcordanceStatus CheckPeerStatus(SOSCircleRef circle, SOSPeerInfoRef peer, CFErrorRef *error) {
+    SOSConcordanceStatus result = kSOSConcordanceNoPeer;
+    SecKeyRef pubKey = SOSPeerInfoCopyPubKey(peer);
+
+    require_action_quiet(SOSCircleHasActivePeer(circle, peer, error), exit, result = kSOSConcordanceNoPeer);
+    require_action_quiet(SOSCircleVerifySignatureExists(circle, pubKey, error), exit, result = kSOSConcordanceNoPeerSig);
+    require_action_quiet(SOSCircleVerify(circle, pubKey, error), exit, result = kSOSConcordanceBadPeerSig);
+    
+    result = kSOSConcordanceTrusted;
+    
+exit:
+    CFReleaseNull(pubKey);
+    return result;
+}
+
+static inline SOSConcordanceStatus CombineStatus(SOSConcordanceStatus status1, SOSConcordanceStatus status2)
+{
+    if (status1 == kSOSConcordanceTrusted || status2 == kSOSConcordanceTrusted)
+        return kSOSConcordanceTrusted;
+    
+    if (status1 == kSOSConcordanceBadPeerSig || status2 == kSOSConcordanceBadPeerSig)
+        return kSOSConcordanceBadPeerSig;
+    
+    if (status1 == kSOSConcordanceNoPeerSig || status2 == kSOSConcordanceNoPeerSig)
+        return kSOSConcordanceNoPeerSig;
+
+    return status1;
+}
+
+static inline bool SOSCircleIsEmpty(SOSCircleRef circle) {
+    return SOSCircleCountPeers(circle) == 0;
+}
+
+static inline bool SOSCircleIsOffering(SOSCircleRef circle) {
+    return SOSCircleCountPeers(circle) == 1;
+}
+
+static inline bool SOSCircleIsResignOffering(SOSCircleRef circle, SecKeyRef pubkey) {
+    return SOSCircleCountActiveValidPeers(circle, pubkey) == 1;
+}
+
+static inline SOSConcordanceStatus GetSignersStatus(SOSCircleRef signers_circle, SOSCircleRef status_circle,
+                                                    SecKeyRef user_pubKey, SOSPeerInfoRef exclude, CFErrorRef *error) {
+    CFStringRef excluded_id = exclude ? SOSPeerInfoGetPeerID(exclude) : NULL;
+
+    __block SOSConcordanceStatus status = kSOSConcordanceNoPeer;
+    SOSCircleForEachActiveValidPeer(signers_circle, user_pubKey, ^(SOSPeerInfoRef peer) {
+        SOSConcordanceStatus peerStatus = CheckPeerStatus(status_circle, peer, error);
+
+        if (peerStatus == kSOSConcordanceNoPeerSig &&
+            (CFEqualSafe(SOSPeerInfoGetPeerID(peer), excluded_id) || SOSPeerInfoIsCloudIdentity(peer)))
+            peerStatus = kSOSConcordanceNoPeer;
+
+        status = CombineStatus(status, peerStatus); // TODO: Use multiple error gathering.
+    });
+
+    return status;
+}
+
+static inline bool isOlderGeneration(SOSCircleRef current, SOSCircleRef proposed) {
+    return CFNumberCompare(current->generation, proposed->generation, NULL) == kCFCompareGreaterThan;
+}
+
+bool SOSCircleSharedTrustedPeers(SOSCircleRef current, SOSCircleRef proposed, SOSPeerInfoRef me) {
+    __block bool retval = false;
+    SOSCircleForEachPeer(current, ^(SOSPeerInfoRef peer) {
+        if(!CFEqual(me, peer) && SOSCircleHasPeer(proposed, peer, NULL)) retval = true;
+    });
+    return retval;
+}
+
+static void SOSCircleUpgradePeersByCircle(SOSCircleRef known_circle, SOSCircleRef proposed_circle) {
+    SOSCircleForEachPeer(known_circle, ^(SOSPeerInfoRef known_peer) {
+        SOSPeerInfoRef proposed_peer = SOSCircleCopyPeerInfo(proposed_circle, SOSPeerInfoGetPeerID(known_peer), NULL);
+        if(proposed_peer && CFEqualSafe(proposed_peer, known_peer) != 0) {
+            SOSCircleUpdatePeerInfo(known_circle, proposed_peer);
+        }
+    });
+}
+
+SOSConcordanceStatus SOSCircleConcordanceTrust(SOSCircleRef known_circle, SOSCircleRef proposed_circle,
+                                               SecKeyRef known_pubkey, SecKeyRef user_pubkey,
+                                               SOSPeerInfoRef exclude, CFErrorRef *error) {
+    
+    if(user_pubkey == NULL) {
+        SOSCreateError(kSOSErrorPublicKeyAbsent, CFSTR("Concordance with no public key"), NULL, error);
+        return kSOSConcordanceNoUserKey; //TODO: - needs to return an error
+    }
+
+    if (SOSCircleIsEmpty(proposed_circle)) {
+        return kSOSConcordanceTrusted;
+    }
+    
+    if(!SOSCircleVerifySignatureExists(proposed_circle, user_pubkey, error)) {
+        SOSCreateError(kSOSErrorBadSignature, CFSTR("No public signature"), (error != NULL) ? *error : NULL, error);
+        return kSOSConcordanceNoUserSig;
+    }
+    
+    if(!SOSCircleVerify(proposed_circle, user_pubkey, error)) {
+        SOSCreateError(kSOSErrorBadSignature, CFSTR("Bad public signature"), (error != NULL) ? *error : NULL, error);
+        return kSOSConcordanceBadUserSig;
+    }
+
+    if (SOSCircleIsEmpty(known_circle) || SOSCircleIsOffering(proposed_circle)) {
+        return GetSignersStatus(proposed_circle, proposed_circle, user_pubkey, NULL, error);
+    }
+
+    if(isOlderGeneration(known_circle, proposed_circle)) {
+        SOSCreateError(kSOSErrorReplay, CFSTR("Bad generation"), NULL, error);
+        return kSOSConcordanceGenOld;
+    }
+    
+    
+    if(!SOSCircleVerify(known_circle, user_pubkey, error)) {
+        SOSCircleUpgradePeersByCircle(known_circle, proposed_circle);
+    }
+    
+    if(known_pubkey == NULL) known_pubkey = user_pubkey;
+    if(!SOSCircleVerify(known_circle, known_pubkey, error)) known_pubkey = user_pubkey;
+    return GetSignersStatus(known_circle, proposed_circle, known_pubkey, exclude, error);
+}
+
+
+static const uint8_t* der_decode_mutable_dictionary(CFAllocatorRef allocator, CFOptionFlags mutability,
+                                                    CFMutableDictionaryRef* dictionary, CFErrorRef *error,
+                                                    const uint8_t* der, const uint8_t *der_end)
+{
+    CFDictionaryRef theDict;
+    const uint8_t* result = der_decode_dictionary(allocator, mutability, &theDict, error, der, der_end);
+
+    if (result != NULL)
+        *dictionary = (CFMutableDictionaryRef)theDict;
+
+    return result;
+}
+
+SOSCircleRef SOSCircleCreateFromDER(CFAllocatorRef allocator, CFErrorRef* error,
+                                      const uint8_t** der_p, const uint8_t *der_end) {
+    SOSCircleRef cir = CFTypeAllocate(SOSCircle, struct __OpaqueSOSCircle, allocator);
+
+    const uint8_t *sequence_end;
+
+    cir->name = NULL;
+    cir->generation = NULL;
+    cir->peers = NULL;
+    cir->applicants = NULL;
+    cir->rejected_applicants = NULL;
+    cir->signatures = NULL;
+
+    *der_p = ccder_decode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, &sequence_end, *der_p, der_end);
+    require_action_quiet(sequence_end != NULL, fail,
+                         SOSCreateError(kSOSErrorBadFormat, CFSTR("Bad Circle DER"), (error != NULL) ? *error : NULL, error));
+    
+    // Version first.
+    uint64_t version = 0;
+    *der_p = ccder_decode_uint64(&version, *der_p, der_end);
+    
+    require_action_quiet(version == kOnlyCompatibleVersion, fail,
+                         SOSCreateError(kSOSErrorIncompatibleCircle, CFSTR("Bad Circle Version"), NULL, error));
+
+    *der_p = der_decode_string(allocator, 0, &cir->name, error, *der_p, sequence_end);
+    *der_p = der_decode_number(allocator, 0, &cir->generation, error, *der_p, sequence_end);
+
+    cir->peers = SOSPeerInfoArrayCreateFromDER(allocator, error, der_p, sequence_end);
+    cir->applicants = SOSPeerInfoArrayCreateFromDER(allocator, error, der_p, sequence_end);
+    cir->rejected_applicants = SOSPeerInfoArrayCreateFromDER(allocator, error, der_p, sequence_end);
+
+    *der_p = der_decode_mutable_dictionary(allocator, kCFPropertyListMutableContainersAndLeaves,
+                                           &cir->signatures, error, *der_p, sequence_end);
+
+    require_action_quiet(*der_p == sequence_end, fail,
+                         SOSCreateError(kSOSErrorBadFormat, CFSTR("Bad Circle DER"), (error != NULL) ? *error : NULL, error));
+
+    return cir;
+    
+fail:
+    CFReleaseNull(cir);
+    return NULL;
+}
+
+SOSCircleRef SOSCircleCreateFromData(CFAllocatorRef allocator, CFDataRef circleData, CFErrorRef *error)
+{    
+    size_t size = CFDataGetLength(circleData);
+    const uint8_t *der = CFDataGetBytePtr(circleData);
+    SOSCircleRef inflated = SOSCircleCreateFromDER(allocator, error, &der, der + size);
+    return inflated;
+}
+
+size_t SOSCircleGetDEREncodedSize(SOSCircleRef cir, CFErrorRef *error) {
+    SOSCircleAssertStable(cir);
+    size_t total_payload = 0;
+
+    require_quiet(accumulate_size(&total_payload, ccder_sizeof_uint64(kOnlyCompatibleVersion)),                        fail);
+    require_quiet(accumulate_size(&total_payload, der_sizeof_string(cir->name, error)),                                fail);
+    require_quiet(accumulate_size(&total_payload, der_sizeof_number(cir->generation, error)),                          fail);
+    require_quiet(accumulate_size(&total_payload, SOSPeerInfoArrayGetDEREncodedSize(cir->peers, error)),               fail);
+    require_quiet(accumulate_size(&total_payload, SOSPeerInfoArrayGetDEREncodedSize(cir->applicants, error)),          fail);
+    require_quiet(accumulate_size(&total_payload, SOSPeerInfoArrayGetDEREncodedSize(cir->rejected_applicants, error)), fail);
+    require_quiet(accumulate_size(&total_payload, der_sizeof_dictionary((CFDictionaryRef) cir->signatures, error)),    fail);
+
+    return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, total_payload);
+    
+fail:
+    SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("don't know how to encode"), NULL, error);
+    return 0;
+}
+
+uint8_t* SOSCircleEncodeToDER(SOSCircleRef cir, CFErrorRef* error, const uint8_t* der, uint8_t* der_end) {
+    SOSCircleAssertStable(cir);
+
+    return ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der,
+           ccder_encode_uint64(kOnlyCompatibleVersion, der,
+           der_encode_string(cir->name, error, der,
+           der_encode_number(cir->generation, error, der,
+           SOSPeerInfoArrayEncodeToDER(cir->peers, error, der,
+           SOSPeerInfoArrayEncodeToDER(cir->applicants, error, der,
+           SOSPeerInfoArrayEncodeToDER(cir->rejected_applicants, error, der,
+           der_encode_dictionary((CFDictionaryRef) cir->signatures, error, der, der_end))))))));
+}
+
+CFDataRef SOSCircleCreateIncompatibleCircleDER(CFErrorRef* error)
+{
+    size_t total_payload = 0;
+    size_t encoded_size = 0;
+    uint8_t* der = 0;
+    uint8_t* der_end = 0;
+    CFMutableDataRef result = NULL;
+    
+    require_quiet(accumulate_size(&total_payload, ccder_sizeof_uint64(kAlwaysIncompatibleVersion)), fail);
+    
+    encoded_size = ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, total_payload);
+
+    result = CFDataCreateMutableWithScratch(kCFAllocatorDefault, encoded_size);
+    
+    der = CFDataGetMutableBytePtr(result);
+    der_end = der + CFDataGetLength(result);
+    
+    der_end = ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der,
+              ccder_encode_uint64(kAlwaysIncompatibleVersion, der, der_end));
+fail:
+    if (der == NULL || der != der_end)
+        CFReleaseNull(result);
+
+    return result;
+}
+
+
+CFDataRef SOSCircleCopyEncodedData(SOSCircleRef circle, CFAllocatorRef allocator, CFErrorRef *error)
+{
+    size_t size = SOSCircleGetDEREncodedSize(circle, error);
+    if (size == 0)
+        return NULL;
+    uint8_t buffer[size];
+    uint8_t* start = SOSCircleEncodeToDER(circle, error, buffer, buffer + sizeof(buffer));
+    CFDataRef result = CFDataCreate(kCFAllocatorDefault, start, size);
+    return result;
+}
+
+static void SOSCircleDestroy(CFTypeRef aObj) {
+    SOSCircleRef c = (SOSCircleRef) aObj;
+
+    CFReleaseNull(c->name);
+    CFReleaseNull(c->generation);
+    CFReleaseNull(c->peers);
+    CFReleaseNull(c->applicants);
+    CFReleaseNull(c->rejected_applicants);
+    CFReleaseNull(c->signatures);
+}
+
+static CFStringRef SOSCircleCopyDescription(CFTypeRef aObj) {
+    SOSCircleRef c = (SOSCircleRef) aObj;
+    
+    SOSCircleAssertStable(c);
+
+    return CFStringCreateWithFormat(NULL, NULL,
+                                    CFSTR("<SOSCircle@%p: [ \nName: %@, \nPeers: %@,\nApplicants: %@,\nRejects: %@,\nSignatures: %@\n ] >"),
+                                    c, c->name, c->peers, c->applicants, c->rejected_applicants, c->signatures);
+}
+
+CFStringRef SOSCircleGetName(SOSCircleRef circle) {
+    assert(circle);
+    assert(circle->name);
+    return circle->name;
+}
+
+const char *SOSCircleGetNameC(SOSCircleRef circle) {
+    CFStringRef name = SOSCircleGetName(circle);
+    if (!name)
+        return strdup("");
+    return CFStringToCString(name);
+}
+
+CFNumberRef SOSCircleGetGeneration(SOSCircleRef circle) {
+    assert(circle);
+    assert(circle->generation);
+    return circle->generation;
+}
+
+int64_t SOSCircleGetGenerationSint(SOSCircleRef circle) {
+    CFNumberRef gen = SOSCircleGetGeneration(circle);
+    int64_t value;
+    if(!gen) return 0;
+    CFNumberGetValue(gen, kCFNumberSInt64Type, &value);
+    return value;
+}
+
+void SOSCircleGenerationIncrement(SOSCircleRef circle) {
+    CFAllocatorRef allocator = CFGetAllocator(circle->generation);
+    int64_t value = SOSCircleGetGenerationSint(circle);
+    value++;
+    circle->generation = CFNumberCreate(allocator, kCFNumberSInt64Type, &value);
+}
+
+int SOSCircleCountPeers(SOSCircleRef circle) {
+    SOSCircleAssertStable(circle);
+    __block int count = 0;
+    SOSCircleForEachPeer(circle, ^(SOSPeerInfoRef peer) {
+        ++count;
+    });
+    return count;
+}
+
+int SOSCircleCountActivePeers(SOSCircleRef circle) {
+    SOSCircleAssertStable(circle);
+    __block int count = 0;
+    SOSCircleForEachActivePeer(circle, ^(SOSPeerInfoRef peer) {
+        ++count;
+    });
+    return count;
+}
+
+int SOSCircleCountActiveValidPeers(SOSCircleRef circle, SecKeyRef pubkey) {
+    SOSCircleAssertStable(circle);
+    __block int count = 0;
+    SOSCircleForEachActiveValidPeer(circle, pubkey, ^(SOSPeerInfoRef peer) {
+        ++count;
+    });
+    return count;
+}
+
+int SOSCircleCountRetiredPeers(SOSCircleRef circle) {
+    SOSCircleAssertStable(circle);
+    __block int count = 0;
+    SOSCircleForEachRetiredPeer(circle, ^(SOSPeerInfoRef peer) {
+        ++count;
+    });
+    return count;
+}
+
+int SOSCircleCountApplicants(SOSCircleRef circle) {
+    SOSCircleAssertStable(circle);
+    
+    return (int)CFArrayGetCount(circle->applicants);
+}
+
+bool SOSCircleHasApplicant(SOSCircleRef circle, SOSPeerInfoRef peerInfo, CFErrorRef *error) {
+    SOSCircleAssertStable(circle);
+    
+    return CFArrayHasValueMatching(circle->applicants, ^bool(const void *value) {
+        return SOSPeerInfoCompareByID(value, peerInfo, NULL) == 0;
+    });
+}
+
+CFMutableArrayRef SOSCircleCopyApplicants(SOSCircleRef circle, CFAllocatorRef allocator) {
+    SOSCircleAssertStable(circle);
+    
+    return CFArrayCreateMutableCopy(allocator, 0, circle->applicants);
+}
+
+int SOSCircleCountRejectedApplicants(SOSCircleRef circle) {
+    SOSCircleAssertStable(circle);
+    
+    return (int)CFArrayGetCount(circle->rejected_applicants);
+}
+
+bool SOSCircleHasRejectedApplicant(SOSCircleRef circle, SOSPeerInfoRef peerInfo, CFErrorRef *error) {
+    SOSCircleAssertStable(circle);
+
+    return CFArrayHasValueMatching(circle->rejected_applicants, ^bool(const void *value) {
+        return SOSPeerInfoCompareByID(value, peerInfo, NULL) == 0;
+    });
+}
+
+SOSPeerInfoRef SOSCircleCopyRejectedApplicant(SOSCircleRef circle, SOSPeerInfoRef peerInfo, CFErrorRef *error) {
+    SOSCircleAssertStable(circle);
+    return (SOSPeerInfoRef) CFArrayGetValueMatching(circle->rejected_applicants, ^bool(const void *value) {
+        return SOSPeerInfoCompareByID(value, peerInfo, NULL) == 0;
+    });
+}
+
+CFMutableArrayRef SOSCircleCopyRejectedApplicants(SOSCircleRef circle, CFAllocatorRef allocator) {
+    SOSCircleAssertStable(circle);
+    
+    return CFArrayCreateMutableCopy(allocator, 0, circle->rejected_applicants);
+}
+
+
+bool SOSCircleHasPeerWithID(SOSCircleRef circle, CFStringRef peerid, CFErrorRef *error) {
+    SOSCircleAssertStable(circle);
+    __block bool found = false;
+    SOSCircleForEachPeer(circle, ^(SOSPeerInfoRef peer) {
+        if(peerid && peer && CFEqualSafe(peerid, SOSPeerInfoGetPeerID(peer))) found = true;
+    });
+    return found;
+}
+
+bool SOSCircleHasPeer(SOSCircleRef circle, SOSPeerInfoRef peerInfo, CFErrorRef *error) {
+    return SOSCircleHasPeerWithID(circle, SOSPeerInfoGetPeerID(peerInfo), error);
+}
+
+bool SOSCircleHasActivePeerWithID(SOSCircleRef circle, CFStringRef peerid, CFErrorRef *error) {
+    SOSCircleAssertStable(circle);
+    __block bool found = false;
+    SOSCircleForEachActivePeer(circle, ^(SOSPeerInfoRef peer) {
+        if(peerid && peer && CFEqualSafe(peerid, SOSPeerInfoGetPeerID(peer))) found = true;
+    });
+    return found;
+}
+
+bool SOSCircleHasActivePeer(SOSCircleRef circle, SOSPeerInfoRef peerInfo, CFErrorRef *error) {
+    if(!peerInfo) return false;
+    return SOSCircleHasActivePeerWithID(circle, SOSPeerInfoGetPeerID(peerInfo), error);
+}
+
+
+
+bool SOSCircleResetToEmpty(SOSCircleRef circle, CFErrorRef *error) {
+    CFArrayRemoveAllValues(circle->applicants);
+    CFArrayRemoveAllValues(circle->peers);
+    CFDictionaryRemoveAllValues(circle->signatures);
+
+    return true;
+}
+
+bool SOSCircleResetToOffering(SOSCircleRef circle, SecKeyRef user_privkey, SOSFullPeerInfoRef requestor, CFErrorRef *error){
+
+    return SOSCircleResetToEmpty(circle, error)
+        && SOSCircleRequestAdmission(circle, user_privkey, requestor, error)
+        && SOSCircleAcceptRequest(circle, user_privkey, requestor, SOSFullPeerInfoGetPeerInfo(requestor), error);
+}
+
+CFIndex SOSCircleRemoveRetired(SOSCircleRef circle, CFErrorRef *error) {
+    CFIndex n = CFArrayRemoveAllPassing(circle->peers,  ^ bool (const void *element) {
+        SOSPeerInfoRef peer = (SOSPeerInfoRef) element;
+        
+        return SOSPeerInfoIsRetirementTicket(peer);
+    });
+    
+    return n;
+}
+
+static bool SOSCircleRecordAdmission(SOSCircleRef circle, SecKeyRef user_pubkey, SOSFullPeerInfoRef requestor, CFErrorRef *error) {
+    SOSCircleAssertStable(circle);
+    
+    bool isPeer = SOSCircleHasPeer(circle, SOSFullPeerInfoGetPeerInfo(requestor), error);
+    
+    require_action_quiet(!isPeer, fail, SOSCreateError(kSOSErrorAlreadyPeer, CFSTR("Cannot request admission when already a peer"), NULL, error));
+    
+    CFIndex total = CFArrayRemoveAllWithMatchingID(circle->applicants, SOSFullPeerInfoGetPeerInfo(requestor));
+    
+    (void) total; // Suppress unused warning in release code.
+    assert(total <= 1); // We should at most be in the list once.
+
+    total = CFArrayRemoveAllWithMatchingID(circle->rejected_applicants, SOSFullPeerInfoGetPeerInfo(requestor));
+    
+    (void) total; // Suppress unused warning in release code.
+    assert(total <= 1); // We should at most be in the list once.
+   
+    
+    // Refetch the current PeerInfo as the promtion above can change it.
+    CFArrayAppendValue(circle->applicants, SOSFullPeerInfoGetPeerInfo(requestor));
+    
+    return true;
+    
+fail:
+    return false;
+    
+}
+
+bool SOSCircleRequestReadmission(SOSCircleRef circle, SecKeyRef user_pubkey, SOSFullPeerInfoRef requestor, CFErrorRef *error) {
+    bool success = false;
+    
+    SOSPeerInfoRef peer = SOSFullPeerInfoGetPeerInfo(requestor);
+    require_quiet(SOSPeerInfoApplicationVerify(peer, user_pubkey, error), fail);
+    success = SOSCircleRecordAdmission(circle, user_pubkey, requestor, error);
+fail:
+    return success;
+}
+
+bool SOSCircleRequestAdmission(SOSCircleRef circle, SecKeyRef user_privkey, SOSFullPeerInfoRef requestor, CFErrorRef *error) {
+    bool success = false;
+    
+    SecKeyRef user_pubkey = SecKeyCreatePublicFromPrivate(user_privkey);
+    require_action_quiet(user_pubkey, fail, SOSCreateError(kSOSErrorBadKey, CFSTR("No public key for key"), NULL, error));
+
+    require(SOSFullPeerInfoPromoteToApplication(requestor, user_privkey, error), fail);
+    
+    success = SOSCircleRecordAdmission(circle, user_pubkey, requestor, error);
+fail:
+    CFReleaseNull(user_pubkey);
+    return success;
+}
+
+
+bool SOSCircleUpdatePeerInfo(SOSCircleRef circle, SOSPeerInfoRef replacement_peer_info) {
+    __block bool replaced = false;
+    CFStringRef replacement_peer_id = SOSPeerInfoGetPeerID(replacement_peer_info);
+    
+    CFMutableArrayModifyValues(circle->peers, ^const void *(const void *value) {
+        if (CFEqual(replacement_peer_id, SOSPeerInfoGetPeerID((SOSPeerInfoRef) value))
+         && !CFEqual(replacement_peer_info, value)) {
+            replaced = true;
+            return replacement_peer_info;
+        }
+      
+        return value;
+    });
+    return replaced;
+}
+
+bool SOSCircleRemovePeer(SOSCircleRef circle, SecKeyRef user_privkey, SOSFullPeerInfoRef requestor, SOSPeerInfoRef peer_to_remove, CFErrorRef *error) {
+    SOSPeerInfoRef requestor_peer_info = SOSFullPeerInfoGetPeerInfo(requestor);
+        
+    if (SOSCircleHasApplicant(circle, peer_to_remove, error)) {
+        return SOSCircleRejectRequest(circle, requestor, peer_to_remove, error);
+    }
+
+    if (!SOSCircleHasPeer(circle, requestor_peer_info, error)) {
+        SOSCreateError(kSOSErrorAlreadyPeer, CFSTR("Must be peer to remove peer"), NULL, error);
+        return false;
+    }
+
+    CFArrayRemoveAllWithMatchingID(circle->peers, peer_to_remove);
+
+    SOSCircleGenerationSign(circle, user_privkey, requestor, error);
+
+    return true;
+}
+
+bool SOSCircleAcceptRequest(SOSCircleRef circle, SecKeyRef user_privkey, SOSFullPeerInfoRef device_approver, SOSPeerInfoRef peerInfo, CFErrorRef *error) {
+    SOSCircleAssertStable(circle);
+
+    CFIndex total = CFArrayRemoveAllWithMatchingID(circle->applicants, peerInfo);
+    SecKeyRef publicKey = NULL;
+    bool result = false;
+
+    require_action_quiet(total != 0, fail, 
+                         SOSCreateError(kSOSErrorNotApplicant, CFSTR("Cannot accept non-applicant"), NULL, error));
+    
+    publicKey = SecKeyCreatePublicFromPrivate(user_privkey);
+    require_quiet(SOSPeerInfoApplicationVerify(peerInfo, publicKey, error), fail);
+
+    assert(total == 1);
+    
+    CFArrayAppendValue(circle->peers, peerInfo);
+    result = SOSCircleGenerationSign(circle, user_privkey, device_approver, error);
+    secnotice("circle", "Accepted %@", peerInfo);
+
+fail:
+    CFReleaseNull(publicKey);
+    return result;
+}
+
+bool SOSCircleWithdrawRequest(SOSCircleRef circle, SOSPeerInfoRef peerInfo, CFErrorRef *error) {
+    SOSCircleAssertStable(circle);
+
+#ifndef NDEBUG
+    CFIndex total =
+#endif
+        CFArrayRemoveAllWithMatchingID(circle->applicants, peerInfo);
+
+    assert(total <= 1);
+    
+    return true;
+}
+
+bool SOSCircleRemoveRejectedPeer(SOSCircleRef circle, SOSPeerInfoRef peerInfo, CFErrorRef *error) {
+    SOSCircleAssertStable(circle);
+    
+#ifndef NDEBUG
+    CFIndex total =
+#endif
+    CFArrayRemoveAllWithMatchingID(circle->rejected_applicants, peerInfo);
+    
+    assert(total <= 1);
+    
+    return true;
+}
+
+
+bool SOSCircleRejectRequest(SOSCircleRef circle, SOSFullPeerInfoRef device_rejector,
+                            SOSPeerInfoRef peerInfo, CFErrorRef *error) {
+    SOSCircleAssertStable(circle);
+
+    if (CFEqual(SOSPeerInfoGetPeerID(peerInfo), SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(device_rejector))))
+        return SOSCircleWithdrawRequest(circle, peerInfo, error);
+
+       CFIndex total = CFArrayRemoveAllWithMatchingID(circle->applicants, peerInfo);
+    
+    if (total == 0) {
+        SOSCreateError(kSOSErrorNotApplicant, CFSTR("Cannot reject non-applicant"), NULL, error);
+        return false;
+    }
+    assert(total == 1);
+    
+    CFArrayAppendValue(circle->rejected_applicants, peerInfo);
+    
+    // TODO: Maybe we sign the rejection with device_rejector.
+    
+    return true;
+}
+
+bool SOSCircleAcceptRequests(SOSCircleRef circle, SecKeyRef user_privkey, SOSFullPeerInfoRef device_approver,
+                             CFErrorRef *error) {
+    // Returns true if we accepted someone and therefore have to post the circle back to KVS
+    __block bool result = false;
+    
+    SOSCircleForEachApplicant(circle, ^(SOSPeerInfoRef peer) {
+        if (!SOSCircleAcceptRequest(circle, user_privkey, device_approver, peer, error))
+            printf("error in SOSCircleAcceptRequest\n");
+        else {
+            secnotice("circle", "Accepted peer: %@", peer);
+            result = true;
+        }
+    });
+    
+    if (result) {
+        SOSCircleGenerationSign(circle, user_privkey, device_approver, error);
+        secnotice("circle", "Countersigned accepted requests");
+    }
+
+    return result;
+}
+
+bool SOSCirclePeerSigUpdate(SOSCircleRef circle, SecKeyRef userPrivKey, SOSFullPeerInfoRef fpi,
+                             CFErrorRef *error) {
+    // Returns true if we accepted someone and therefore have to post the circle back to KVS
+    __block bool result = false;
+    SecKeyRef userPubKey = SecKeyCreatePublicFromPrivate(userPrivKey);
+
+    // We're going to remove any applicants using a mismatched user key.
+    SOSCircleForEachApplicant(circle, ^(SOSPeerInfoRef peer) {
+        if(!SOSPeerInfoApplicationVerify(peer, userPubKey, NULL)) {
+            if(!SOSCircleRejectRequest(circle, fpi, peer, NULL)) {
+                // do we care?
+            }
+        }
+    });
+    
+    result = SOSCircleUpdatePeerInfo(circle, SOSFullPeerInfoGetPeerInfo(fpi));
+    
+    if (result) {
+        SOSCircleGenerationSign(circle, userPrivKey, fpi, error);
+        secnotice("circle", "Generation signed updated signatures on peerinfo");
+    }
+    
+    return result;
+}
+
+SOSPeerInfoRef SOSCircleCopyPeerInfo(SOSCircleRef circle, CFStringRef peer_id, CFErrorRef *error) {
+    __block SOSPeerInfoRef result = NULL;
+
+    CFArrayForEach(circle->peers, ^(const void *value) {
+        if (result == NULL) {
+            SOSPeerInfoRef tpi = (SOSPeerInfoRef)value;
+            if (CFEqual(SOSPeerInfoGetPeerID(tpi), peer_id))
+                result = tpi;
+        }
+    });
+
+    CFRetainSafe(result);
+    return result;
+}
+
+
+static inline void SOSCircleForEachPeerMatching(SOSCircleRef circle,
+                                                void (^action)(SOSPeerInfoRef peer),
+                                                bool (^condition)(SOSPeerInfoRef peer)) {
+    CFArrayForEach(circle->peers, ^(const void *value) {
+        SOSPeerInfoRef peer = (SOSPeerInfoRef) value;
+        if (condition(peer))
+            action(peer);
+    });
+}
+
+void SOSCircleForEachPeer(SOSCircleRef circle, void (^action)(SOSPeerInfoRef peer)) {
+    SOSCircleForEachPeerMatching(circle, action, ^bool(SOSPeerInfoRef peer) {
+        return !SOSPeerInfoIsRetirementTicket(peer) && !SOSPeerInfoIsCloudIdentity(peer);
+    });
+}
+
+void SOSCircleForEachRetiredPeer(SOSCircleRef circle, void (^action)(SOSPeerInfoRef peer)) {
+    SOSCircleForEachPeerMatching(circle, action, ^bool(SOSPeerInfoRef peer) {
+        return SOSPeerInfoIsRetirementTicket(peer);
+    });
+}
+
+void SOSCircleForEachActivePeer(SOSCircleRef circle, void (^action)(SOSPeerInfoRef peer)) {
+    SOSCircleForEachPeerMatching(circle, action, ^bool(SOSPeerInfoRef peer) {
+        return true;
+    });
+}
+
+void SOSCircleForEachActiveValidPeer(SOSCircleRef circle, SecKeyRef user_public_key, void (^action)(SOSPeerInfoRef peer)) {
+    SOSCircleForEachPeerMatching(circle, action, ^bool(SOSPeerInfoRef peer) {
+        return SOSPeerInfoApplicationVerify(peer, user_public_key, NULL);
+    });
+}
+
+void SOSCircleForEachApplicant(SOSCircleRef circle, void (^action)(SOSPeerInfoRef peer)) {
+    CFArrayForEach(circle->applicants, ^(const void*value) { action((SOSPeerInfoRef) value); } );
+}
+
+
+CFMutableArrayRef SOSCircleCopyPeers(SOSCircleRef circle, CFAllocatorRef allocator) {
+    SOSCircleAssertStable(circle);
+    
+    CFMutableArrayRef result = CFArrayCreateMutableForCFTypes(allocator);
+    
+    SOSCircleForEachPeer(circle, ^(SOSPeerInfoRef peer) {
+        CFArrayAppendValue(result, peer);
+    });
+    
+    return result;
+}
+
+CFMutableArrayRef SOSCircleCopyConcurringPeers(SOSCircleRef circle, CFErrorRef* error) {
+    SOSCircleAssertStable(circle);
+
+    CFMutableArrayRef concurringPeers = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
+    
+    SOSCircleForEachActivePeer(circle, ^(SOSPeerInfoRef peer) {
+        CFErrorRef error = NULL;
+        if (SOSCircleVerifyPeerSigned(circle, peer, &error)) {
+            CFArrayAppendValue(concurringPeers, peer);
+        } else if (error != NULL) {
+            secerror("Error checking concurrence: %@", error);
+        }
+        CFReleaseNull(error);
+    });
+
+    return concurringPeers;
+}
+
+
+//
+// Stuff above this line is really SOSCircleInfo below the line is the active SOSCircle functionality
+//
+
+static SOSPeerRef SOSCircleCopyPeer(SOSCircleRef circle, SOSFullPeerInfoRef myRef, SOSPeerSendBlock sendBlock,
+                                    CFStringRef peer_id, CFErrorRef *error) {
+    SOSPeerRef peer = NULL;
+    SOSPeerInfoRef peer_info = SOSCircleCopyPeerInfo(circle, peer_id, error);
+    //TODO: if (peer is legit member of us then good otherwise bail) {
+    //}
+    if (peer_info) {
+        peer = SOSPeerCreate(myRef, peer_info, error, sendBlock);
+        CFReleaseNull(peer_info);
+    }
+    return peer;
+}
+
+
+static bool SOSCircleDoWithPeer(SOSFullPeerInfoRef myRef, SOSCircleRef circle, SOSDataSourceFactoryRef factory,
+                                SOSPeerSendBlock sendBlock, CFStringRef peer_id, bool readOnly,
+                                CFErrorRef* error, bool (^do_action)(SOSEngineRef engine, SOSPeerRef peer, CFErrorRef *error))
+{
+    bool success = false;
+    SOSEngineRef engine = NULL;
+    SOSPeerRef peer = NULL;
+    SOSDataSourceRef ds = NULL;
+
+    peer = SOSCircleCopyPeer(circle, myRef, sendBlock, peer_id, error);
+    require(peer, exit);
+
+    ds = factory->create_datasource(factory, SOSCircleGetName(circle), readOnly, error);
+    require(ds, exit);
+
+    engine = SOSEngineCreate(ds, error); // Hand off DS to engine.
+    ds = NULL;
+    require(engine, exit);
+
+    success = do_action(engine, peer, error);
+
+exit:
+    if (ds)
+        ds->release(ds);
+    if (engine)
+        SOSEngineDispose(engine);
+    if (peer)
+        SOSPeerDispose(peer);
+
+    return success;
+}
+
+bool SOSCircleSyncWithPeer(SOSFullPeerInfoRef myRef, SOSCircleRef circle, SOSDataSourceFactoryRef factory,
+                           SOSPeerSendBlock sendBlock, CFStringRef peer_id,
+                           CFErrorRef *error)
+{
+    return SOSCircleDoWithPeer(myRef, circle, factory, sendBlock, peer_id, true, error, ^bool(SOSEngineRef engine, SOSPeerRef peer, CFErrorRef *error) {
+        return SOSPeerStartSync(peer, engine, error) != kSOSPeerCoderFailure;
+    });
+}
+
+bool SOSCircleHandlePeerMessage(SOSCircleRef circle, SOSFullPeerInfoRef myRef, SOSDataSourceFactoryRef factory,
+                                SOSPeerSendBlock sendBlock, CFStringRef peer_id,
+                                CFDataRef message, CFErrorRef *error) {
+    return SOSCircleDoWithPeer(myRef, circle, factory, sendBlock, peer_id, false, error, ^bool(SOSEngineRef engine, SOSPeerRef peer, CFErrorRef *error) {
+        return SOSPeerHandleMessage(peer, engine, message, error) != kSOSPeerCoderFailure;
+    });
+}
+
+
+SOSFullPeerInfoRef SOSCircleGetiCloudFullPeerInfoRef(SOSCircleRef circle) {
+    __block SOSFullPeerInfoRef cloud_full_peer = NULL;
+    SOSCircleForEachActivePeer(circle, ^(SOSPeerInfoRef peer) {
+        if (SOSPeerInfoIsCloudIdentity(peer)) {
+            if (cloud_full_peer == NULL) {
+                CFErrorRef localError = NULL;
+                cloud_full_peer = SOSFullPeerInfoCreateCloudIdentity(kCFAllocatorDefault, peer, &localError);
+                
+                if (localError) {
+                    secerror("Found cloud peer in circle but can't make full peer: %@", localError);
+                    CFReleaseNull(localError);
+                }
+                
+            } else {
+                secerror("More than one cloud identity found in circle: %@", circle);
+            }
+        }
+    });
+    return cloud_full_peer;
+}
+
+
+
diff --git a/sec/SOSCircle/SecureObjectSync/SOSCircle.h b/sec/SOSCircle/SecureObjectSync/SOSCircle.h
new file mode 100644 (file)
index 0000000..a87e882
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * Created by Michael Brouwer on 6/22/12.
+ * Copyright 2012 Apple Inc. All Rights Reserved.
+ */
+
+/*!
+ @header SOSCircle.h
+ The functions provided in SOSCircle.h provide an interface to a
+ secure object syncing circle for a single class
+ */
+
+#ifndef _SOSCIRCLE_H_
+#define _SOSCIRCLE_H_
+
+#include <Security/Security.h>
+#include <SecureObjectSync/SOSFullPeerInfo.h>
+#include <SecureObjectSync/SOSPeerInfo.h>
+#include <SecureObjectSync/SOSEngine.h>
+#include <SecureObjectSync/SOSPeer.h>
+
+__BEGIN_DECLS
+
+typedef struct __OpaqueSOSCircle *SOSCircleRef;
+
+/* SOSDataSourceFactory protocol (non opaque). */
+typedef struct SOSDataSourceFactory *SOSDataSourceFactoryRef;
+
+struct SOSDataSourceFactory {
+    CFArrayRef       (*copy_names)(SOSDataSourceFactoryRef factory);
+    SOSDataSourceRef (*create_datasource)(SOSDataSourceFactoryRef factory, CFStringRef dataSourceName, bool readOnly, CFErrorRef *error);
+    void             (*release)(SOSDataSourceFactoryRef factory);
+};
+
+
+CFTypeID SOSCircleGetTypeID();
+
+SOSCircleRef SOSCircleCreate(CFAllocatorRef allocator, CFStringRef circleName, CFErrorRef *error);
+SOSCircleRef SOSCircleCreateFromDER(CFAllocatorRef allocator, CFErrorRef* error,
+                                    const uint8_t** der_p, const uint8_t *der_end);
+SOSCircleRef SOSCircleCreateFromData(CFAllocatorRef allocator, CFDataRef circleData, CFErrorRef *error);
+SOSCircleRef SOSCircleCopyCircle(CFAllocatorRef allocator, SOSCircleRef otherCircle, CFErrorRef *error);
+
+bool SOSCircleSign(SOSCircleRef circle, SecKeyRef privkey, CFErrorRef *error);
+bool SOSCircleVerifySignatureExists(SOSCircleRef circle, SecKeyRef pubKey, CFErrorRef *error);
+bool SOSCircleVerify(SOSCircleRef circle, SecKeyRef pubkey, CFErrorRef *error);
+
+bool SOSCircleVerifyPeerSigned(SOSCircleRef circle, SOSPeerInfoRef peer, CFErrorRef *error);
+
+bool SOSCircleGenerationSign(SOSCircleRef circle, SecKeyRef user_approver, SOSFullPeerInfoRef peerinfo, CFErrorRef *error);
+
+size_t SOSCircleGetDEREncodedSize(SOSCircleRef cir, CFErrorRef *error);
+uint8_t* SOSCircleEncodeToDER(SOSCircleRef cir, CFErrorRef* error, const uint8_t* der, uint8_t* der_end);
+CFDataRef SOSCircleCopyEncodedData(SOSCircleRef circle, CFAllocatorRef allocator, CFErrorRef *error);
+
+int SOSCircleCountApplicants(SOSCircleRef circle);
+bool SOSCircleHasApplicant(SOSCircleRef circle, SOSPeerInfoRef peerInfo, CFErrorRef *error);
+CFMutableArrayRef SOSCircleCopyApplicants(SOSCircleRef c, CFAllocatorRef allocator);
+void SOSCircleForEachApplicant(SOSCircleRef circle, void (^action)(SOSPeerInfoRef peer));
+
+int SOSCircleCountRejectedApplicants(SOSCircleRef circle);
+bool SOSCircleHasRejectedApplicant(SOSCircleRef circle, SOSPeerInfoRef peerInfo, CFErrorRef *error);
+SOSPeerInfoRef SOSCircleCopyRejectedApplicant(SOSCircleRef circle, SOSPeerInfoRef peerInfo, CFErrorRef *error);
+CFMutableArrayRef SOSCircleCopyRejectedApplicants(SOSCircleRef c, CFAllocatorRef allocator);
+
+CFStringRef SOSCircleGetName(SOSCircleRef circle);
+const char *SOSCircleGetNameC(SOSCircleRef circle);
+
+CFNumberRef SOSCircleGetGeneration(SOSCircleRef circle);
+int64_t SOSCircleGetGenerationSint(SOSCircleRef circle);
+void SOSCircleGenerationIncrement(SOSCircleRef circle);
+
+CFMutableArrayRef SOSCircleCopyPeers(SOSCircleRef circle, CFAllocatorRef allocator);
+CFMutableArrayRef SOSCircleCopyConcurringPeers(SOSCircleRef circle, CFErrorRef* error);
+
+int SOSCircleCountPeers(SOSCircleRef circle);
+int SOSCircleCountActivePeers(SOSCircleRef circle);
+int SOSCircleCountActiveValidPeers(SOSCircleRef circle, SecKeyRef pubkey);
+int SOSCircleCountRetiredPeers(SOSCircleRef circle);
+
+void SOSCircleForEachPeer(SOSCircleRef circle, void (^action)(SOSPeerInfoRef peer));
+void SOSCircleForEachRetiredPeer(SOSCircleRef circle, void (^action)(SOSPeerInfoRef peer));
+void SOSCircleForEachActivePeer(SOSCircleRef circle, void (^action)(SOSPeerInfoRef peer));
+void SOSCircleForEachActiveValidPeer(SOSCircleRef circle, SecKeyRef user_public_key, void (^action)(SOSPeerInfoRef peer));
+
+bool SOSCircleHasPeerWithID(SOSCircleRef circle, CFStringRef peerid, CFErrorRef *error);
+bool SOSCircleHasPeer(SOSCircleRef circle, SOSPeerInfoRef peerInfo, CFErrorRef *error);
+bool SOSCircleHasActivePeerWithID(SOSCircleRef circle, CFStringRef peerid, CFErrorRef *error);
+bool SOSCircleHasActivePeer(SOSCircleRef circle, SOSPeerInfoRef peerInfo, CFErrorRef *error);
+
+bool SOSCircleResetToOffering(SOSCircleRef circle, SecKeyRef user_privkey, SOSFullPeerInfoRef requestor, CFErrorRef *error);
+bool SOSCircleResetToEmpty(SOSCircleRef circle, CFErrorRef *error);
+bool SOSCircleRequestAdmission(SOSCircleRef circle, SecKeyRef user_privkey, SOSFullPeerInfoRef requestor, CFErrorRef *error);
+bool SOSCircleRequestReadmission(SOSCircleRef circle, SecKeyRef user_pubkey, SOSFullPeerInfoRef requestor, CFErrorRef *error);
+
+bool SOSCircleAcceptRequest(SOSCircleRef circle, SecKeyRef user_privkey, SOSFullPeerInfoRef device_approver, SOSPeerInfoRef peerInfo, CFErrorRef *error);
+bool SOSCircleRejectRequest(SOSCircleRef circle, SOSFullPeerInfoRef device_approver, SOSPeerInfoRef peerInfo, CFErrorRef *error);
+bool SOSCircleWithdrawRequest(SOSCircleRef circle, SOSPeerInfoRef peerInfo, CFErrorRef *error);
+bool SOSCircleRemoveRejectedPeer(SOSCircleRef circle, SOSPeerInfoRef peerInfo, CFErrorRef *error);
+bool SOSCirclePeerSigUpdate(SOSCircleRef circle, SecKeyRef userPrivKey, SOSFullPeerInfoRef fpi,
+                            CFErrorRef *error);
+//
+// Update a peer's meta information.
+// No resigning of the circle is done, only updates to their own self signed description.
+//
+bool SOSCircleUpdatePeerInfo(SOSCircleRef circle, SOSPeerInfoRef replacement_peer_info);
+
+bool SOSCircleRemovePeer(SOSCircleRef circle, SecKeyRef user_privkey, SOSFullPeerInfoRef device_approver, SOSPeerInfoRef peerInfo, CFErrorRef *error);
+
+CFIndex SOSCircleRemoveRetired(SOSCircleRef circle, CFErrorRef *error);
+
+bool SOSCircleAcceptRequests(SOSCircleRef circle, SecKeyRef user_privkey, SOSFullPeerInfoRef device_approver, CFErrorRef *error);
+
+SOSPeerInfoRef SOSCircleCopyPeerInfo(SOSCircleRef circle, CFStringRef peer_id, CFErrorRef *error);
+
+// Stuff above this line is really SOSCircleInfo below the line is the active SOSCircle functionality
+
+bool SOSCircleSyncWithPeer(SOSFullPeerInfoRef myRef, SOSCircleRef circle,
+                           SOSDataSourceFactoryRef factory,
+                           SOSPeerSendBlock sendBlock, CFStringRef peer_id,
+                           CFErrorRef *error);
+
+bool SOSCircleHandlePeerMessage(SOSCircleRef circle, SOSFullPeerInfoRef myRef, SOSDataSourceFactoryRef factory,
+                                SOSPeerSendBlock sendBlock, CFStringRef peer_id,
+                                CFDataRef message, CFErrorRef *error);
+
+SOSFullPeerInfoRef SOSCircleGetiCloudFullPeerInfoRef(SOSCircleRef circle);
+
+bool SOSCircleConcordanceSign(SOSCircleRef circle, SOSFullPeerInfoRef peerinfo, CFErrorRef *error);
+
+enum {
+    kSOSConcordanceTrusted = 0,
+    kSOSConcordanceGenOld = 1,     // kSOSErrorReplay
+    kSOSConcordanceNoUserSig = 2,  // kSOSErrorBadSignature
+    kSOSConcordanceNoUserKey = 3,  // kSOSErrorNoKey
+    kSOSConcordanceNoPeer = 4,     // kSOSErrorPeerNotFound
+    kSOSConcordanceBadUserSig = 5, // kSOSErrorBadSignature
+    kSOSConcordanceBadPeerSig = 6, // kSOSErrorBadSignature
+    kSOSConcordanceNoPeerSig = 7,
+    kSOSConcordanceWeSigned = 8,
+};
+typedef uint32_t SOSConcordanceStatus;
+
+bool SOSCircleSharedTrustedPeers(SOSCircleRef current, SOSCircleRef proposed, SOSPeerInfoRef me);
+
+SOSConcordanceStatus SOSCircleConcordanceTrust(SOSCircleRef known_circle, SOSCircleRef proposed_circle,
+                                               SecKeyRef known_pubkey, SecKeyRef user_pubkey,
+                                               SOSPeerInfoRef exclude, CFErrorRef *error);
+//
+// Testing routines:
+//
+
+CFDataRef SOSCircleCreateIncompatibleCircleDER(CFErrorRef* error);
+
+__END_DECLS
+
+#endif /* !_SOSCIRCLE_H_ */
diff --git a/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.c b/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.c
new file mode 100644 (file)
index 0000000..2e5c442
--- /dev/null
@@ -0,0 +1,425 @@
+/*
+ * Copyright (c) 2012 Apple Computer, Inc. All Rights Reserved.
+ * 
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+//
+//  SOSCloudCircle.m
+//
+
+#include <stdio.h>
+#include <AssertMacros.h>
+#include <SecureObjectSync/SOSCloudCircle.h>
+#include <SecureObjectSync/SOSCloudCircleInternal.h>
+#include <SecureObjectSync/SOSCircle.h>
+#include <SecureObjectSync/SOSAccount.h>
+#include <SecureObjectSync/SOSFullPeerInfo.h>
+#include <SecureObjectSync/SOSInternal.h>
+#include <Security/SecKeyPriv.h>
+#include <Security/SecFramework.h>
+#include <CoreFoundation/CFXPCBridge.h>
+
+#include "Imported/SecItemServer.h"
+
+#include <utilities/SecDispatchRelease.h>
+#include <utilities/SecCFRelease.h>
+#include <utilities/SecCFWrappers.h>
+#include <utilities/SecXPCError.h>
+
+#include <utilities/debugging.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <xpc/xpc.h>
+#define MINIMIZE_INCLUDES MINIMIZE_INCLUDES
+#include "Imported/securityd_client.h"
+#include "Imported/spi.h"
+
+#include "SOSRegressionUtilities.h"
+
+
+const char * kSOSCCCircleChangedNotification = "com.apple.security.secureobjectsync.circlechanged";
+
+#define do_if_registered(sdp, ...) if (gSecurityd && gSecurityd->sdp) { return gSecurityd->sdp(__VA_ARGS__); }
+
+static bool xpc_dictionary_entry_is_type(xpc_object_t dictionary, const char *key, xpc_type_t type)
+{
+    xpc_object_t value = xpc_dictionary_get_value(dictionary, key);
+    
+    return value && (xpc_get_type(value) == type);
+}
+
+SOSCCStatus SOSCCThisDeviceIsInCircle(CFErrorRef *error)
+{
+    sec_trace_enter_api(NULL);
+    sec_trace_return_api(SOSCCStatus, ^{
+        SOSCCStatus result = kSOSCCError;
+        
+        do_if_registered(soscc_ThisDeviceIsInCircle, error);
+        
+        xpc_object_t message = securityd_create_message(kSecXPCOpDeviceInCircle, error);
+        if (message) {
+            xpc_object_t response = securityd_message_with_reply_sync(message, error);
+            
+            if (response && xpc_dictionary_entry_is_type(response, kSecXPCKeyResult, XPC_TYPE_INT64)) {
+                result = (SOSCCStatus) xpc_dictionary_get_int64(response, kSecXPCKeyResult);
+            } else {
+                result = kSOSCCError;
+            }
+            
+            if (result < 0) {
+                if (response && securityd_message_no_error(response, error))
+                {
+                    char *desc = xpc_copy_description(response);
+                    SecCFCreateErrorWithFormat(0, sSecXPCErrorDomain, NULL, error, NULL, CFSTR("Remote error occurred/no info: %s"), desc);
+                    free((void *)desc);
+                }
+            }
+            if(response)
+                xpc_release(response);
+            if(message)
+                xpc_release(message);
+        }
+        
+        
+        return result;
+    }, CFSTR("SOSCCStatus=%d"))
+}
+
+static CFStringRef simple_cfstring_error_request(enum SecXPCOperation op, CFErrorRef* error)
+{
+    __block CFStringRef result = NULL;
+    
+    secdebug("sosops","enter - operation: %d", op);
+    securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
+        const char *c_string = xpc_dictionary_get_string(response, kSecXPCKeyResult);
+
+        if (c_string) {
+            result = CFStringCreateWithBytes(kCFAllocatorDefault, (const UInt8*)c_string, strlen(c_string), kCFStringEncodingUTF8, false);
+        }
+        
+        return c_string != NULL;
+    });
+    return result;
+}
+
+static bool simple_bool_error_request(enum SecXPCOperation op, CFErrorRef* error)
+{
+    __block bool result = false;
+    
+    secdebug("sosops","enter - operation: %d", op);
+    securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
+        result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
+        return result;
+    });
+    return result;
+}
+
+static int simple_int_error_request(enum SecXPCOperation op, CFErrorRef* error)
+{
+    __block int result = 0;
+    
+    secdebug("sosops","enter - operation: %d", op);
+    securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
+        int64_t temp_result =  xpc_dictionary_get_int64(response, kSecXPCKeyResult);
+        if ((temp_result >= INT32_MIN) && (temp_result <= INT32_MAX)) {
+            result = (int)temp_result;
+        }
+        return result;
+    });
+    return result;
+}
+
+static CFArrayRef array_of_info_error_request(enum SecXPCOperation op, CFErrorRef* error)
+{
+    __block CFArrayRef result = NULL;
+    
+    secdebug("sosops","enter - operation: %d", op);
+    securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
+        xpc_object_t encoded_array = xpc_dictionary_get_value(response, kSecXPCKeyResult);
+        if (response && (NULL != encoded_array)) {
+            result = CreateArrayOfPeerInfoWithXPCObject(encoded_array,  error);
+        }
+        return result != NULL;
+    });
+
+    return result;
+}
+
+static bool info_array_to_bool_error_request(enum SecXPCOperation op, CFArrayRef peer_infos, CFErrorRef* error)
+{
+    __block bool result = false;
+    
+    secdebug("sosops", "enter - operation: %d", op);
+    securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
+        xpc_object_t encoded_peers = CreateXPCObjectWithArrayOfPeerInfo(peer_infos, error);
+        if (encoded_peers)
+            xpc_dictionary_set_value(message, kSecXPCKeyPeerInfos, encoded_peers);
+        return encoded_peers != NULL;
+    }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
+        result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
+        return result;
+    });
+    return result;
+}
+
+static bool uint64_t_to_bool_error_request(enum SecXPCOperation op,
+                                           uint64_t number,
+                                           CFErrorRef* error)
+{
+    __block bool result = false;
+    
+    securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
+        xpc_dictionary_set_uint64(message, kSecXPCLimitInMinutes, number);
+        return true;
+    }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
+        result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
+        return result;
+    });
+    
+    return result;
+}
+
+bool SOSCCRequestToJoinCircle(CFErrorRef* error)
+{
+    sec_trace_enter_api(NULL);
+    sec_trace_return_bool_api(^{
+        do_if_registered(soscc_RequestToJoinCircle, error);
+        
+        return simple_bool_error_request(kSecXPCOpRequestToJoin, error);
+    }, NULL)
+}
+
+bool SOSCCRequestToJoinCircleAfterRestore(CFErrorRef* error)
+{
+    sec_trace_enter_api(NULL);
+    sec_trace_return_bool_api(^{
+        do_if_registered(soscc_RequestToJoinCircleAfterRestore, error);
+        
+        return simple_bool_error_request(kSecXPCOpRequestToJoinAfterRestore, error);
+    }, NULL)
+}
+
+bool SOSCCResetToOffering(CFErrorRef* error)
+{
+    sec_trace_enter_api(NULL);
+    sec_trace_return_bool_api(^{
+        do_if_registered(soscc_ResetToOffering, error);
+        
+        return simple_bool_error_request(kSecXPCOpResetToOffering, error);
+    }, NULL)
+}
+
+bool SOSCCResetToEmpty(CFErrorRef* error)
+{
+    sec_trace_enter_api(NULL);
+    sec_trace_return_bool_api(^{
+        do_if_registered(soscc_ResetToEmpty, error);
+        
+        return simple_bool_error_request(kSecXPCOpResetToEmpty, error);
+    }, NULL)
+}
+
+bool SOSCCRemoveThisDeviceFromCircle(CFErrorRef* error)
+{
+    sec_trace_enter_api(NULL);
+    sec_trace_return_bool_api(^{
+        do_if_registered(soscc_RemoveThisDeviceFromCircle, error);
+        
+        return simple_bool_error_request(kSecXPCOpRemoveThisDeviceFromCircle, error);
+    }, NULL)
+}
+
+bool SOSCCBailFromCircle_BestEffort(uint64_t limit_in_seconds, CFErrorRef* error)
+{
+    sec_trace_enter_api(NULL);
+    sec_trace_return_bool_api(^{
+        do_if_registered(soscc_BailFromCircle, limit_in_seconds, error);
+        
+        return uint64_t_to_bool_error_request(kSecXPCOpBailFromCircle, limit_in_seconds, error);
+    }, NULL)
+}
+
+
+CFArrayRef SOSCCCopyPeerPeerInfo(CFErrorRef* error)
+{
+    sec_trace_enter_api(NULL);
+    sec_trace_return_api(CFArrayRef, ^{
+        do_if_registered(soscc_CopyPeerInfo, error);
+        
+        return array_of_info_error_request(kSecXPCOpCopyPeerPeerInfo, error);
+    }, CFSTR("return=%@"));
+}
+
+CFArrayRef SOSCCCopyConcurringPeerPeerInfo(CFErrorRef* error)
+{
+    sec_trace_enter_api(NULL);
+    sec_trace_return_api(CFArrayRef, ^{
+        do_if_registered(soscc_CopyConcurringPeerInfo, error);
+        
+        return array_of_info_error_request(kSecXPCOpCopyConcurringPeerPeerInfo, error);
+    }, CFSTR("return=%@"));
+}
+
+CFArrayRef SOSCCCopyApplicantPeerInfo(CFErrorRef* error)
+{
+    sec_trace_enter_api(NULL);
+    sec_trace_return_api(CFArrayRef, ^{
+        do_if_registered(soscc_CopyApplicantPeerInfo, error);
+        
+        return array_of_info_error_request(kSecXPCOpCopyApplicantPeerInfo, error);
+    }, CFSTR("return=%@"))
+}
+
+bool SOSCCAcceptApplicants(CFArrayRef applicants, CFErrorRef* error)
+{
+    sec_trace_enter_api(NULL);
+    sec_trace_return_bool_api(^{
+        do_if_registered(soscc_AcceptApplicants, applicants, error);
+
+        return info_array_to_bool_error_request(kSecXPCOpAcceptApplicants, applicants, error);
+    }, NULL)
+}
+
+bool SOSCCRejectApplicants(CFArrayRef applicants, CFErrorRef *error)
+{
+    sec_trace_enter_api(CFSTR("applicants=%@"), applicants);
+    sec_trace_return_bool_api(^{
+        do_if_registered(soscc_RejectApplicants, applicants, error);
+        
+        return info_array_to_bool_error_request(kSecXPCOpRejectApplicants, applicants, error);
+    }, NULL)
+}
+
+static bool label_and_password_to_bool_error_request(enum SecXPCOperation op,
+                                                     CFStringRef user_label, CFDataRef user_password,
+                                                     CFErrorRef* error)
+{
+    __block bool result = false;
+
+    securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
+        CFStringPerformWithCString(user_label, ^(const char *utf8Str) {
+            xpc_dictionary_set_string(message, kSecXPCKeyUserLabel, utf8Str);
+        });
+        xpc_dictionary_set_data(message, kSecXPCKeyUserPassword, CFDataGetBytePtr(user_password), CFDataGetLength(user_password));
+        return true;
+    }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
+        result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
+        return result;
+    });
+
+    return result;
+}
+
+bool SOSCCRegisterUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef* error)
+{
+    return SOSCCSetUserCredentials(user_label, user_password, error);
+}
+
+bool SOSCCSetUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef* error)
+{
+       sec_trace_enter_api(CFSTR("user_label=%@"), user_label);
+    sec_trace_return_bool_api(^{
+               do_if_registered(soscc_SetUserCredentials, user_label, user_password, error);
+
+       return label_and_password_to_bool_error_request(kSecXPCOpSetUserCredentials, user_label, user_password, error);
+    }, NULL)
+}
+
+bool SOSCCTryUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef* error)
+{
+       sec_trace_enter_api(CFSTR("user_label=%@"), user_label);
+    sec_trace_return_bool_api(^{
+           do_if_registered(soscc_TryUserCredentials, user_label, user_password, error);
+
+       return label_and_password_to_bool_error_request(kSecXPCOpTryUserCredentials, user_label, user_password, error);
+    }, NULL)
+}
+
+
+bool SOSCCCanAuthenticate(CFErrorRef* error) {
+    sec_trace_enter_api(NULL);
+    sec_trace_return_bool_api(^{
+           do_if_registered(soscc_CanAuthenticate, error);
+
+           return simple_bool_error_request(kSecXPCOpCanAuthenticate, error);
+    }, NULL)
+}
+
+bool SOSCCPurgeUserCredentials(CFErrorRef* error) {
+    sec_trace_enter_api(NULL);
+    sec_trace_return_bool_api(^{
+           do_if_registered(soscc_PurgeUserCredentials, error);
+
+           return simple_bool_error_request(kSecXPCOpPurgeUserCredentials, error);
+    }, NULL)
+}
+
+enum DepartureReason SOSCCGetLastDepartureReason(CFErrorRef *error) {
+    sec_trace_enter_api(NULL);
+    sec_trace_return_api(enum DepartureReason, ^{
+           do_if_registered(soscc_GetLastDepartureReason, error);
+        
+           return (enum DepartureReason) simple_int_error_request(kSecXPCOpGetLastDepartureReason, error);
+    }, NULL)
+}
+
+CFStringRef SOSCCCopyIncompatibilityInfo(CFErrorRef* error) {
+    sec_trace_enter_api(NULL);
+    sec_trace_return_api(CFStringRef, ^{
+           do_if_registered(soscc_CopyIncompatibilityInfo, error);
+        
+           return simple_cfstring_error_request(kSecXPCOpCopyIncompatibilityInfo, error);
+    }, NULL)
+}
+
+SyncWithAllPeersReason SOSCCProcessSyncWithAllPeers(CFErrorRef* error)
+{
+    sec_trace_enter_api(NULL);
+    sec_trace_return_api(SyncWithAllPeersReason, ^{
+           do_if_registered(soscc_ProcessSyncWithAllPeers, error);
+        
+           return (SyncWithAllPeersReason) simple_int_error_request(kSecXPCOpProcessSyncWithAllPeers, error);
+    }, NULL)
+}
+
+CFStringRef SOSCCGetStatusDescription(SOSCCStatus status)
+{
+    switch (status) {
+        case kSOSCCInCircle:
+            return CFSTR("InCircle");
+        case kSOSCCNotInCircle:
+            return CFSTR("NotInCircle");
+        case kSOSCCRequestPending:
+            return CFSTR("RequestPending");
+        case kSOSCCCircleAbsent:
+            return CFSTR("CircleAbsent");
+        case kSOSCCError:
+            return CFSTR("InternalError");
+        case kSOSCCParamErr:
+            return CFSTR("ParamError");
+        case kSOSCCMemoryErr:
+            return CFSTR("MemoryError");
+
+        default:
+            return CFSTR("WTF? Unknown Status");
+    };
+}
diff --git a/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.h b/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.h
new file mode 100644 (file)
index 0000000..32457bf
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2012 Apple Computer, Inc. All Rights Reserved.
+ * 
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+//
+//  SOSCloudCircle.h
+//
+
+#ifndef _SECURITY_SOSCLOUDCIRCLE_H_
+#define _SECURITY_SOSCLOUDCIRCLE_H_
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreFoundation/CFArray.h>
+#include <CoreFoundation/CFError.h>
+
+// #include <SecureObjectSync/SOSPeer.h>
+
+__BEGIN_DECLS
+
+
+//
+// CFError info for propogated errors
+//
+
+extern CFStringRef kSOSErrorDomain;
+
+enum {
+    kSOSErrorPrivateKeyAbsent = 1,
+    kSOSErrorPublicKeyAbsent = 2,
+
+    kSOSErrorWrongPassword = 3,
+
+    kSOSErrorNotReady = 4, // System not yet ready (before first unlock)
+
+    kSOSErrorIncompatibleCircle = 5, // We saw an incompatible circle out there.
+};
+
+//
+// Types
+//
+
+enum {
+    kSOSCCInCircle          = 0,
+    kSOSCCNotInCircle       = 1,
+    kSOSCCRequestPending    = 2,
+    kSOSCCCircleAbsent      = 3,
+    kSOSCCError             = -1,
+
+// Never being used, were a bad idea, have clients leaving here deprecated.
+    kSOSCCParamErr  __attribute__((deprecated)) = -2,
+    kSOSCCMemoryErr __attribute__((deprecated)) = -3
+};
+
+typedef int SOSCCStatus;
+
+extern const char * kSOSCCCircleChangedNotification;
+
+/*!
+ @function SOSCCSetUserCredentials
+ @abstract Uses the user authentication credential (password) to create an internal EC Key Pair for authenticating Circle changes.
+ @param user_label This string can be used for a label to tag the resulting credential data for persistent storage.
+ @param user_password The user's password that's used as input to generate EC keys for Circle authenticating operations.
+ @param error What went wrong if we returned false.
+ @discussion This call needs to be made whenever a call that updates a Cloud Circle returns an error of kSOSErrorPrivateKeyAbsent (credential timeout) or kSOSErrorPublicKeyAbsent (programmer error).
+
+     Any caller to SetUserCredential is asserting that they know the credential is correct.
+
+     If you are uncertain (unable to verify) use TryUserCredentials, but if you can know it's better
+     to call Set so we can recover from password change.
+ */
+
+bool SOSCCSetUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef* error);
+
+
+/*!
+ @function SOSCCTryUserCredentials
+ @abstract Uses the user authentication credential (password) to create an internal EC Key Pair for authenticating Circle changes.
+ @param user_label This string can be used for a label to tag the resulting credential data for persistent storage.
+ @param user_password The user's password that's used as input to generate EC keys for Circle authenticating operations.
+ @param error What went wrong if we returned false.
+ @discussion When one of the user credential requiring calls below (almost all) need a credential it will fail with kSOSErrorPrivateKeyAbsent. If you don't have an outside way to confirm correctness of the password we will attempt to use the passed in value and if it doesn't match the public information we currently have we'll fail.
+ */
+
+bool SOSCCTryUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef* error);
+
+
+/*!
+ @function SOSCCRegisterUserCredentials
+ @abstract Deprecated name for SOSCCSetUserCredentials.
+ */
+bool SOSCCRegisterUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef *error);
+
+/*!
+ @function SOSCCCanAuthenticate
+ @abstract Determines whether we currently have valid credentials to authenticate a circle operation.
+ @param error What went wrong if we returned false.
+ */
+
+bool SOSCCCanAuthenticate(CFErrorRef *error);
+
+/*!
+ @function SOSCCThisDeviceIsInCircle
+ @abstract Finds and returns if this devices status in the user's circle. 
+ @param error What went wrong if we returned kSOSCCError.
+ @result kSOSCCInCircle if we're in the circle.
+ @discussion If we have an error figuring out if we're in the circle we return false and the error.
+ */
+SOSCCStatus SOSCCThisDeviceIsInCircle(CFErrorRef* error);
+
+/*!
+ @function SOSCCRequestToJoinCircle
+ @abstract Requests that this device join the circle.
+ @param error What went wrong if we tried to join.
+ @result true if we pushed the request out successfully. False if there was an error.
+ @discussion Requests to join the user's circle or all the pending circles (other than his) if there are multiple pending circles.
+ */
+bool SOSCCRequestToJoinCircle(CFErrorRef* error);
+
+/*!
+ @function SOSCCRequestToJoinCircleAfterRestore
+ @abstract Requests that this device join the circle and do the magic just after restore approval.
+ @param error What went wrong if we tried to join.
+ @result true if we joined or pushed a request out. False if we failed to try.
+ @discussion Uses the cloud identity to get in the circle if it can. If it cannot it falls back on simple application.
+ */
+bool SOSCCRequestToJoinCircleAfterRestore(CFErrorRef* error);
+
+/*!
+ @function SOSCCResetToOffering
+ @abstract Resets the cloud to offer this device's circle. 
+ @param error What went wrong if we tried to post our circle.
+ @result true if we posted the circle successfully. False if there was an error.
+ */
+bool SOSCCResetToOffering(CFErrorRef* error);
+
+/*!
+ @function SOSCCResetToEmpty
+ @abstract Resets the cloud to a completely empty circle.
+ @param error What went wrong if we tried to post our circle.
+ @result true if we posted the circle successfully. False if there was an error.
+ */
+bool SOSCCResetToEmpty(CFErrorRef* error);
+
+/*!
+ @function SOSCCRemoveThisDeviceFromCircle
+ @abstract Removes the current device from the circle. 
+ @param error What went wrong trying to remove ourselves.
+ @result true if we posted the removal. False if there was an error.
+ @discussion This removes us from the circle.
+ */
+bool SOSCCRemoveThisDeviceFromCircle(CFErrorRef* error);
+
+/*!
+ @function SOSCCBailFromCircle_BestEffort
+ @abstract Attempts to publish a retirement ticket for the current device.
+ @param error What went wrong trying to remove ourselves.
+ @result true if we posted the ticket. False if there was an error.
+ @discussion This attempts to post a retirement ticket that should
+ result in other devices removing this device from the circle.  It does so
+ with a 5 second timeout.  The only use for this call is when doing a device
+ erase.
+ */
+bool SOSCCBailFromCircle_BestEffort(uint64_t limit_in_seconds, CFErrorRef* error);
+
+/*!
+ @function SOSCCCopyApplicantPeerInfo
+ @abstract Get the list of peers wishing admittance.
+ @param error What went wrong.
+ @result Array of PeerInfos for applying peers.
+ */
+CFArrayRef SOSCCCopyApplicantPeerInfo(CFErrorRef* error);
+
+/*!
+ @function SOSCCAcceptApplicants
+ @abstract Accepts the applicants into the circle (requires that we recently had the user enter the credentials).
+ @param applicants List of applicants to accept.
+ @param error What went wrong if we tried to post our circle.
+ @result true if we accepted the applicants. False if there was an error.
+ */
+bool SOSCCAcceptApplicants(CFArrayRef applicants, CFErrorRef* error);
+
+/*!
+ @function SOSCCRejectApplicants
+ @abstract Rejects the applications for admission (requires that we recently had the user enter the credentials).
+ @param applicants List of applicants to reject.
+ @param error What went wrong if we tried to post our circle.
+ @result true if we rejected the applicants. False if there was an error.
+ */
+bool SOSCCRejectApplicants(CFArrayRef applicants, CFErrorRef *error);
+
+/*!
+ @function SOSCCCopyPeerPeerInfo
+ @abstract Returns peers in the circle (we may not be in it). 
+ @param error What went wrong trying look at the circle.
+ @result Returns a list of peers in the circle currently syncing.
+ @discussion We get the list of all peers syncing in the circle.
+ */
+CFArrayRef SOSCCCopyPeerPeerInfo(CFErrorRef* error);
+
+/*!
+ @function SOSCCGetLastDepartureReason
+ @abstract Returns the information (string, hopefully URL) that will lead to an explanation of why you have an incompatible circle.
+ @param error What went wrong if we returned NULL.
+ */
+enum DepartureReason {
+    kSOSDepartureReasonError = 0,
+    kSOSNeverLeftCircle,       // We haven't ever left a circle
+    kSOSWithdrewMembership,    // SOSCCRemoveThisDeviceFromCircle
+    kSOSMembershipRevoked,     // Via reset or remote removal.
+    kSOSLeftUntrustedCircle,   // We saw a circle we could no longer trust
+    kSOSNeverAppliedToCircle,  // We've never applied to a circle
+};
+
+enum DepartureReason SOSCCGetLastDepartureReason(CFErrorRef *error);
+
+/*!
+ @function SOSCCGetIncompatibilityInfo
+ @abstract Returns the information (string, hopefully URL) that will lead to an explinatoin of why you have an incompatible circle.
+ @param error What went wrong if we returned NULL.
+ */
+CFStringRef SOSCCCopyIncompatibilityInfo(CFErrorRef *error);
+
+typedef enum SyncWithAllPeersReason {
+    kSyncWithAllPeersOtherFail = 0,
+    kSyncWithAllPeersSuccess,
+    kSyncWithAllPeersLocked,
+} SyncWithAllPeersReason;
+
+__END_DECLS
+
+#endif
diff --git a/sec/SOSCircle/SecureObjectSync/SOSCloudCircleInternal.h b/sec/SOSCircle/SecureObjectSync/SOSCloudCircleInternal.h
new file mode 100644 (file)
index 0000000..0c32d3f
--- /dev/null
@@ -0,0 +1,31 @@
+//
+//  SOSCloudCircleInternal.h
+//
+//  Created by Mitch Adler on 11/13/12.
+//
+//
+
+#ifndef _SECURITY_SOSCLOUDCIRCLEINTERNAL_H_
+#define _SECURITY_SOSCLOUDCIRCLEINTERNAL_H_
+
+#include <SecureObjectSync/SOSCloudCircle.h>
+#include <xpc/xpc.h>
+#include <Security/SecKey.h>
+
+CFArrayRef SOSCCCopyConcurringPeerPeerInfo(CFErrorRef* error);
+
+bool SOSCCPurgeUserCredentials(CFErrorRef* error);
+
+CFStringRef SOSCCGetStatusDescription(SOSCCStatus status);
+SecKeyRef SOSCCGetUserPrivKey(CFErrorRef *error);
+SecKeyRef SOSCCGetUserPubKey(CFErrorRef *error);
+
+/*!
+ @function SOSCCProcessSyncWithAllPeers
+ @abstract Returns the information (string, hopefully URL) that will lead to an explanation of why you have an incompatible circle.
+ @param error What went wrong if we returned NULL.
+ */
+
+SyncWithAllPeersReason SOSCCProcessSyncWithAllPeers(CFErrorRef* error);
+
+#endif
diff --git a/sec/SOSCircle/SecureObjectSync/SOSCoder.c b/sec/SOSCircle/SecureObjectSync/SOSCoder.c
new file mode 100644 (file)
index 0000000..7a9eb8f
--- /dev/null
@@ -0,0 +1,495 @@
+//
+//  SOSCoder.c
+//  sec
+//
+//  Created by Richard Murphy on 2/6/13.
+//
+//
+#include <stdlib.h>
+
+#include <CoreFoundation/CFBase.h>
+#include <CoreFoundation/CFError.h>
+
+#include <Security/SecBasePriv.h>
+#include <Security/SecOTR.h>
+#include <Security/SecOTRSession.h>
+#include <SecureObjectSync/SOSInternal.h>
+#include <SecureObjectSync/SOSFullPeerInfo.h>
+#include <SecureObjectSync/SOSPeerInfo.h>
+#include <SecureObjectSync/SOSPeer.h>
+#include <SecureObjectSync/SOSCoder.h>
+
+#include <utilities/SecCFRelease.h>
+#include <utilities/SecCFWrappers.h>
+#include <utilities/SecIOFormat.h>
+#include <utilities/SecCFError.h>
+#include <utilities/debugging.h>
+
+#include <utilities/der_plist.h>
+#include <utilities/der_plist_internal.h>
+
+#include <corecrypto/ccder.h>
+#include <utilities/iCloudKeychainTrace.h>
+
+#include "AssertMacros.h"
+
+struct __OpaqueSOSCoder {
+    CFStringRef peer_id;
+    SecOTRSessionRef sessRef;
+    bool waitingForDataPacket;
+};
+
+static const char *SOSPeerCoderString(SOSPeerCoderStatus coderStatus) {
+    switch (coderStatus) {
+        case kSOSPeerCoderDataReturned: return "DataReturned";
+        case kSOSPeerCoderNegotiating: return "Negotiating";
+        case kSOSPeerCoderNegotiationCompleted: return "NegotiationCompleted";
+        case kSOSPeerCoderFailure: return "Failure";
+        case kSOSPeerCoderStaleEvent: return "StaleEvent";
+        default: return "StatusUnknown";
+    }
+}
+
+static size_t der_sizeof_bool(bool value) {
+    return ccder_sizeof(CCDER_BOOLEAN, 1);
+}
+
+static uint8_t* der_encode_bool(bool value, const uint8_t *der, uint8_t *der_end) {
+    uint8_t valueByte = value;
+    return ccder_encode_tl(CCDER_BOOLEAN, 1, der,
+              ccder_encode_body(1, &valueByte, der, der_end));
+}
+
+static const uint8_t* der_decode_bool(bool *value, const uint8_t *der, const uint8_t *der_end) {
+    size_t payload_size = 0;
+    
+    der = ccder_decode_tl(CCDER_BOOLEAN, &payload_size, der, der_end);
+    
+    if (payload_size != 1) {
+        der = NULL;
+    }
+    
+    if (der != NULL) {
+        *value = (*der != 0);
+        der++;
+    }
+
+    return der;
+}
+
+static CFMutableDataRef sessSerialized(SOSCoderRef coder, CFErrorRef *error) {
+    CFMutableDataRef otr_state = NULL;
+        
+    if(!coder || !coder->sessRef) {
+        SOSCreateErrorWithFormat(kSOSErrorUnexpectedType, NULL, error, 0, CFSTR("No session reference."));
+        return NULL;
+    }
+    
+    if ((otr_state = CFDataCreateMutable(NULL, 0)) == NULL) {
+        SOSCreateErrorWithFormat(kSOSErrorAllocationFailure, NULL, error, 0, CFSTR("Mutable Data allocation failed."));
+        return NULL;
+    }
+    
+    if (errSecSuccess != SecOTRSAppendSerialization(coder->sessRef, otr_state)) {
+        SOSCreateErrorWithFormat(kSOSErrorEncodeFailure, NULL, error, 0, CFSTR("Append Serialization failed."));
+        CFReleaseSafe(otr_state);
+        return NULL;
+    }
+    
+    return otr_state;
+
+}
+
+static size_t SOSCoderGetDEREncodedSize(SOSCoderRef coder, CFErrorRef *error) {
+    size_t encoded_size = 0;
+    CFMutableDataRef otr_state = sessSerialized(coder, error);
+
+    if (otr_state) {
+        size_t data_size = der_sizeof_data(otr_state, error);
+        size_t waiting_size = der_sizeof_bool(coder->waitingForDataPacket);
+        
+        if ((data_size != 0) && (waiting_size != 0))
+        {
+            encoded_size = ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, data_size + waiting_size);
+        }
+        CFReleaseSafe(otr_state);
+    }
+    return encoded_size;
+}
+
+static uint8_t* SOSCoderEncodeToDER(SOSCoderRef coder, CFErrorRef* error, const uint8_t* der, uint8_t* der_end) {
+    if(!der_end) return NULL;
+    uint8_t* result = NULL;
+    CFMutableDataRef otr_state = sessSerialized(coder, error);
+    
+    if(otr_state) {
+        result = ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der,
+                 der_encode_data(otr_state, error, der,
+                 der_encode_bool(coder->waitingForDataPacket, der, der_end)));
+        CFReleaseSafe(otr_state);
+    }
+    return result;
+}
+
+
+CFDataRef SOSCoderCopyDER(SOSCoderRef coder, CFErrorRef* error) {
+    CFMutableDataRef encoded = NULL;
+    size_t encoded_size = SOSCoderGetDEREncodedSize(coder, error);
+    
+    if (encoded_size > 0) {
+        encoded = CFDataCreateMutable(NULL, encoded_size);
+        if (encoded) {
+            CFDataSetLength(encoded, encoded_size);
+            uint8_t * der = CFDataGetMutableBytePtr(encoded);
+            uint8_t * der_end = der + encoded_size;
+            if (!SOSCoderEncodeToDER(coder, error, der, der_end)) {
+                CFReleaseNull(encoded);
+                encoded = NULL;
+            }
+        }
+    }
+    return encoded;
+}
+
+SOSCoderRef SOSCoderCreateFromData(CFDataRef exportedData, CFErrorRef *error) {
+    
+    SOSCoderRef p = calloc(1, sizeof(struct __OpaqueSOSCoder));
+    
+    const uint8_t *der = CFDataGetBytePtr(exportedData);
+    const uint8_t *der_end = der + CFDataGetLength(exportedData);
+    
+    CFDataRef otr_data = NULL;
+
+    ccder_tag tag;
+    require(ccder_decode_tag(&tag, der, der_end),fail);
+
+    switch (tag) {
+        case CCDER_OCTET_STRING:
+        {
+            der = der_decode_data(kCFAllocatorDefault, 0, &otr_data, error, der, der_end);
+            p->waitingForDataPacket = false;
+        }
+        break;
+        
+        case CCDER_CONSTRUCTED_SEQUENCE:
+        {
+            const uint8_t *sequence_end = NULL;
+            der = ccder_decode_sequence_tl(&sequence_end, der, der_end);
+            
+            require_action_quiet(sequence_end == der_end, fail, SecCFDERCreateError(kSOSErrorDecodeFailure, CFSTR("Extra data in SOS coder"), NULL, error));
+            
+            der = der_decode_data(kCFAllocatorDefault, 0, &otr_data, error, der, der_end);
+            der = der_decode_bool(&p->waitingForDataPacket, der, sequence_end);
+        }
+        break;
+        
+        default:
+            SecCFDERCreateError(kSOSErrorDecodeFailure, CFSTR("Unsupported SOS Coder DER"), NULL, error);
+            goto fail;
+    }
+
+    require(der, fail);
+    
+    p->sessRef = SecOTRSessionCreateFromData(NULL, otr_data);
+    require(p->sessRef, fail);
+
+    CFReleaseSafe(otr_data);
+    return p;
+        
+fail:
+    SOSCoderDispose(p);
+    CFReleaseSafe(otr_data);
+    return NULL;
+}
+
+
+SOSCoderRef SOSCoderCreate(SOSPeerInfoRef peerInfo, SOSFullPeerInfoRef myPeerInfo, CFErrorRef *error) {        
+    CFAllocatorRef allocator = CFGetAllocator(peerInfo);
+    
+    SOSCoderRef p = calloc(1, sizeof(struct __OpaqueSOSCoder));
+
+    SecOTRFullIdentityRef myRef = NULL;
+    SecOTRPublicIdentityRef peerRef = NULL;
+    SecKeyRef privateKey = NULL;
+    SecKeyRef publicKey = NULL;
+
+    if (myPeerInfo && peerInfo) {
+        privateKey = SOSFullPeerInfoCopyDeviceKey(myPeerInfo, error);
+        require_quiet(privateKey, errOut);
+
+        myRef = SecOTRFullIdentityCreateFromSecKeyRef(allocator, privateKey, error);
+        require_quiet(myRef, errOut);
+        
+        CFReleaseNull(privateKey);
+    
+        publicKey = SOSPeerInfoCopyPubKey(peerInfo);
+        
+        peerRef = SecOTRPublicIdentityCreateFromSecKeyRef(allocator, publicKey, error);
+        require_quiet(peerRef, errOut);
+        
+        p->sessRef = SecOTRSessionCreateFromID(allocator, myRef, peerRef);
+
+        require(p->sessRef, errOut);
+        
+        p->waitingForDataPacket = false;
+        
+        CFReleaseNull(publicKey);
+        CFReleaseNull(privateKey);
+        CFReleaseNull(myRef);
+        CFReleaseNull(peerRef);
+    } else {
+        secnotice("coder", "NULL Coder requested, no transport security");
+    }
+
+    return p;
+
+errOut:
+    secerror("Coder create failed: %@\n", *error);
+    CFReleaseNull(myRef);
+    CFReleaseNull(peerRef);
+    CFReleaseNull(publicKey);
+    CFReleaseNull(privateKey);
+
+    free(p);
+    return NULL;
+}
+
+void SOSCoderDispose(SOSCoderRef coder)
+{
+    CFReleaseNull(coder->sessRef);
+    
+    free(coder);
+}
+
+void SOSCoderReset(SOSCoderRef coder)
+{
+    SecOTRSessionReset(coder->sessRef);
+    coder->waitingForDataPacket = false;
+}
+
+static bool SOSOTRSAppendStartPacket(SecOTRSessionRef session, CFMutableDataRef appendPacket, CFErrorRef *error) {
+    OSStatus otrStatus = SecOTRSAppendStartPacket(session, appendPacket);
+    if (otrStatus != errSecSuccess) {
+        SOSCreateErrorWithFormat(kSOSErrorEncodeFailure, (error != NULL) ? *error : NULL, error, NULL, CFSTR("append start packet returned: %" PRIdOSStatus), otrStatus);
+    }
+    return otrStatus == errSecSuccess;
+}
+
+// Start OTR negotiation if we haven't already done so.
+SOSPeerCoderStatus
+SOSCoderStart(SOSCoderRef coder, SOSPeerSendBlock sendBlock, CFStringRef clientId, CFErrorRef *error) {
+    CFMutableStringRef action = CFStringCreateMutable(kCFAllocatorDefault, 0);
+    CFStringRef beginState = NULL;
+    SOSPeerCoderStatus result = kSOSPeerCoderFailure;
+    CFMutableDataRef startPacket = NULL;
+
+    require_action_quiet(coder->sessRef, coderFailure, CFStringAppend(action, CFSTR("*** no otr session ***")));
+    beginState = CFCopyDescription(coder->sessRef);
+    require_action_quiet(!coder->waitingForDataPacket, negotiatingOut, CFStringAppend(action, CFSTR("waiting for peer to send first data packet")));
+    require_action_quiet(!SecOTRSGetIsReadyForMessages(coder->sessRef), coderFailure, CFStringAppend(action, CFSTR("otr session ready"));
+                         result = kSOSPeerCoderDataReturned);
+    require_action_quiet(SecOTRSGetIsIdle(coder->sessRef), negotiatingOut, CFStringAppend(action, CFSTR("otr negotiating already")));
+    require_action_quiet(startPacket = CFDataCreateMutable(kCFAllocatorDefault, 0), coderFailure, SOSCreateError(kSOSErrorAllocationFailure, CFSTR("alloc failed"), NULL, error));
+    require_quiet(SOSOTRSAppendStartPacket(coder->sessRef, startPacket, error), coderFailure);
+    require_quiet(sendBlock(startPacket, error), coderFailure);
+
+negotiatingOut:
+    result = kSOSPeerCoderNegotiating;
+coderFailure:
+    // Uber state log
+    if (result == kSOSPeerCoderFailure && error && *error)
+        CFStringAppendFormat(action, NULL, CFSTR(" %@"), *error);
+    secnotice("coder", "%@ %@ %s %@ %@ returned %s", clientId, beginState,
+              SecOTRPacketTypeString(startPacket), action, coder->sessRef, SOSPeerCoderString(result));
+    CFReleaseNull(startPacket);
+    CFReleaseSafe(beginState);
+    CFRelease(action);
+
+    return result;
+
+}
+
+SOSPeerCoderStatus
+SOSCoderResendDH(SOSCoderRef coder, SOSPeerSendBlock sendBlock, CFErrorRef *error) {
+    if(coder->sessRef == NULL) return kSOSPeerCoderDataReturned;
+    
+    CFMutableDataRef startPacket = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    if (SecOTRSAppendRestartPacket(coder->sessRef, startPacket)) {
+        return kSOSPeerCoderFailure;
+    }
+    
+    secnotice("coder", "Resending OTR Start %@", startPacket);
+    SOSPeerCoderStatus result = sendBlock(startPacket, error) ? kSOSPeerCoderNegotiating : kSOSPeerCoderFailure;
+    CFReleaseNull(startPacket);
+    return result;
+}
+
+
+static SOSPeerCoderStatus nullCoder(CFDataRef from, CFMutableDataRef *to) {
+    *to = CFDataCreateMutableCopy(NULL, CFDataGetLength(from), from);
+    return kSOSPeerCoderDataReturned;
+}
+
+SOSPeerCoderStatus SOSCoderUnwrap(SOSCoderRef coder, SOSPeerSendBlock send_block,
+                                  CFDataRef codedMessage, CFMutableDataRef *message,
+                                  CFStringRef clientId,
+                                  CFErrorRef *error) {
+    if(codedMessage == NULL) return kSOSPeerCoderDataReturned;
+    if(coder->sessRef == NULL) return nullCoder(codedMessage, message);
+    CFMutableStringRef action = CFStringCreateMutable(kCFAllocatorDefault, 0);
+    /* This should be the "normal" case.  We just use OTR to unwrap the received message. */
+    SOSPeerCoderStatus result = kSOSPeerCoderFailure;
+
+    CFStringRef beginState = CFCopyDescription(coder->sessRef);
+    enum SecOTRSMessageKind kind = SecOTRSGetMessageKind(coder->sessRef, codedMessage);
+
+    switch (kind) {
+        case kOTRNegotiationPacket: {
+            if(send_block) {
+                /* If we're in here we haven't completed negotiating a session.  Use SecOTRSProcessPacket() to go through
+                 the negotiation steps and immediately send a reply back if necessary using the sendBlock.  This
+                 assumes the sendBlock is still available.
+                 */
+                CFMutableDataRef response = CFDataCreateMutable(kCFAllocatorDefault, 0);
+                OSStatus ppstatus = errSecSuccess;
+                if (response) {
+                    switch (ppstatus = SecOTRSProcessPacket(coder->sessRef, codedMessage, response)) {
+                        case errSecSuccess:
+                            if (CFDataGetLength(response) > 1) {
+                                CFStringAppendFormat(action, NULL, CFSTR("Sending OTR Response %s"), SecOTRPacketTypeString(response));
+                                if (send_block(response, error)) {
+                                    result = kSOSPeerCoderNegotiating;
+                                    if (SecOTRSGetIsReadyForMessages(coder->sessRef)) {
+                                        CFStringAppend(action, CFSTR(" begin waiting for data packet"));
+                                        coder->waitingForDataPacket = true;
+                                    }
+                                } else {
+                                    secerror("%@ Coder send Error %@", clientId, (CFTypeRef)error);
+                                    result =  kSOSPeerCoderFailure;
+                                }
+                            } else if(!SecOTRSGetIsReadyForMessages(coder->sessRef)) {
+                                CFStringAppend(action, CFSTR("stuck?"));
+                                result = kSOSPeerCoderNegotiating;
+                            } else {
+                                CFStringAppend(action, CFSTR("completed negotiation"));
+                                result = kSOSPeerCoderNegotiationCompleted;
+                                coder->waitingForDataPacket = false;
+                            }
+                            break;
+                        case errSecDecode:
+                            CFStringAppend(action, CFSTR("resending dh"));
+                            result = SOSCoderResendDH(coder, send_block, error);
+                            break;
+                        default:
+                            SOSCreateErrorWithFormat(kSOSErrorEncodeFailure, (error != NULL) ? *error : NULL, error, NULL, CFSTR("%@ Cannot negotiate session (%ld)"), clientId, (long)ppstatus);
+                            result = kSOSPeerCoderFailure;
+                            break;
+                    };
+                } else {
+                    SOSCreateErrorWithFormat(kSOSErrorAllocationFailure, (error != NULL) ? *error : NULL, error, NULL, CFSTR("%@ Cannot allocate CFData"), clientId);
+                    result = kSOSPeerCoderFailure;
+                }
+
+                CFReleaseNull(response);
+            } else {
+                secerror("%@ Can't send, no send_block!!", clientId);
+                SOSCreateErrorWithFormat(kSOSErrorEncodeFailure, (error != NULL) ? *error : NULL, error, NULL, CFSTR("%@ Cannot negotiate session"), clientId);
+                result = kSOSPeerCoderFailure;
+            }
+
+            break;
+        }
+
+        case kOTRDataPacket:
+            if(!SecOTRSGetIsReadyForMessages(coder->sessRef)) {
+                CFStringAppend(action, CFSTR("not ready, resending DH packet"));
+                               SetCloudKeychainTraceValueForKey(kCloudKeychainNumberOfTimesSyncFailed, 1);
+                CFStringAppend(action, CFSTR("not ready for data; resending dh"));
+                result = SOSCoderResendDH(coder, send_block, error);
+            } else {
+                if (coder->waitingForDataPacket) {
+                    CFStringAppend(action, CFSTR("got data packet we were waiting for "));
+                    coder->waitingForDataPacket = false;
+                }
+                CFMutableDataRef exposed = CFDataCreateMutable(0, 0);
+                OSStatus otrResult = SecOTRSVerifyAndExposeMessage(coder->sessRef, codedMessage, exposed);
+                CFStringAppend(action, CFSTR("verify and expose message"));
+                if (otrResult) {
+                    if (otrResult == errSecOTRTooOld) {
+                        CFStringAppend(action, CFSTR(" too old"));
+                        result = kSOSPeerCoderStaleEvent;
+                    } else {
+                        SecError(otrResult, error, CFSTR("%@ Cannot expose message: %" PRIdOSStatus), clientId, otrResult);
+                        secerror("%@ Decode OTR Protected Packet: %@", clientId, error ? *error : NULL);
+                        result = kSOSPeerCoderFailure;
+                    }
+                } else {
+                    CFStringAppend(action, CFSTR("decoded OTR protected packet"));
+                    *message = exposed;
+                    exposed = NULL;
+                    result = kSOSPeerCoderDataReturned;
+                }
+                CFReleaseNull(exposed);
+            }
+            break;
+
+        default:
+            secerror("%@ Unknown packet type: %@", clientId, codedMessage);
+            SOSCreateError(kSOSErrorDecodeFailure, CFSTR("Unknown packet type"), (error != NULL) ? *error : NULL, error);
+            result = kSOSPeerCoderFailure;
+            break;
+    };
+
+    // Uber state log
+    if (result == kSOSPeerCoderFailure && error && *error)
+        CFStringAppendFormat(action, NULL, CFSTR(" %@"), *error);
+    secnotice("coder", "%@ %@ %s %@ %@ returned %s", clientId, beginState,
+              SecOTRPacketTypeString(codedMessage), action, coder->sessRef, SOSPeerCoderString(result));
+    CFReleaseSafe(beginState);
+    CFRelease(action);
+
+    return result;
+}
+
+
+SOSPeerCoderStatus SOSCoderWrap(SOSCoderRef coder, CFDataRef message, CFMutableDataRef *codedMessage, CFStringRef clientId, CFErrorRef *error) {
+    CFMutableStringRef action = CFStringCreateMutable(kCFAllocatorDefault, 0);
+    SOSPeerCoderStatus result = kSOSPeerCoderDataReturned;
+    CFStringRef beginState = NULL;
+    CFMutableDataRef encoded = NULL;
+    OSStatus otrStatus = 0;
+
+    require_action_quiet(coder->sessRef, errOut,
+                         CFStringAppend(action, CFSTR("*** using null coder ***"));
+                         result = nullCoder(message, codedMessage));
+    beginState = CFCopyDescription(coder->sessRef);
+    require_action_quiet(SecOTRSGetIsReadyForMessages(coder->sessRef), errOut,
+                         CFStringAppend(action, CFSTR("not ready"));
+                         result = kSOSPeerCoderNegotiating);
+    require_action_quiet(!coder->waitingForDataPacket, errOut,
+                         CFStringAppend(action, CFSTR("waiting for peer to send data packet first"));
+                         result = kSOSPeerCoderNegotiating);
+    require_action_quiet(encoded = CFDataCreateMutable(kCFAllocatorDefault, 0), errOut,
+                         SOSCreateErrorWithFormat(kSOSErrorAllocationFailure, NULL, error, NULL, CFSTR("%@ alloc failed"), clientId);
+                         result = kSOSPeerCoderFailure);
+    require_noerr_action_quiet(otrStatus = SecOTRSSignAndProtectMessage(coder->sessRef, message, encoded), errOut,
+                               SOSCreateErrorWithFormat(kSOSErrorEncodeFailure, (error != NULL) ? *error : NULL, error, NULL, CFSTR("%@ cannot protect message: %" PRIdOSStatus), clientId, otrStatus);
+                               CFReleaseNull(encoded);
+                               result = kSOSPeerCoderFailure);
+    *codedMessage = encoded;
+
+errOut:
+    // Uber state log
+    if (result == kSOSPeerCoderFailure && error && *error)
+        CFStringAppendFormat(action, NULL, CFSTR(" %@"), *error);
+    secnotice("coder", "%@ %@ %s %@ %@ returned %s", clientId, beginState,
+              SecOTRPacketTypeString(encoded), action, coder->sessRef, SOSPeerCoderString(result));
+    CFReleaseSafe(beginState);
+    CFRelease(action);
+
+    return result;
+}
+
+bool SOSCoderCanWrap(SOSCoderRef coder) {
+    return coder->sessRef && SecOTRSGetIsReadyForMessages(coder->sessRef) && !coder->waitingForDataPacket;
+}
diff --git a/sec/SOSCircle/SecureObjectSync/SOSCoder.h b/sec/SOSCircle/SecureObjectSync/SOSCoder.h
new file mode 100644 (file)
index 0000000..28e178b
--- /dev/null
@@ -0,0 +1,41 @@
+//
+//  SOSCoder.h
+//  sec
+//
+//  Created by Richard Murphy on 2/6/13.
+//
+//
+
+#ifndef sec_SOSCoder_h
+#define sec_SOSCoder_h
+
+#include <SecureObjectSync/SOSFullPeerInfo.h>
+#include <SecureObjectSync/SOSPeerInfo.h>
+#include <SecureObjectSync/SOSPeer.h>
+
+typedef struct __OpaqueSOSCoder *SOSCoderRef;
+
+SOSCoderRef SOSCoderCreate(SOSPeerInfoRef peerInfo, SOSFullPeerInfoRef myPeerInfo, CFErrorRef *error);
+SOSCoderRef SOSCoderCreateFromData(CFDataRef exportedData, CFErrorRef *error);
+
+void SOSCoderDispose(SOSCoderRef coder);
+
+CFDataRef SOSCoderCopyDER(SOSCoderRef coder, CFErrorRef* error);
+
+SOSPeerCoderStatus
+SOSCoderStart(SOSCoderRef coder, SOSPeerSendBlock sendBlock, CFStringRef clientId, CFErrorRef *error);
+
+SOSPeerCoderStatus
+SOSCoderResendDH(SOSCoderRef coder, SOSPeerSendBlock sendBlock, CFErrorRef *error);
+
+void SOSCoderPersistState(CFStringRef peer_id, SOSCoderRef coder);
+
+SOSPeerCoderStatus SOSCoderUnwrap(SOSCoderRef coder, SOSPeerSendBlock send_block, CFDataRef codedMessage, CFMutableDataRef *message, CFStringRef clientId, CFErrorRef *error);
+
+SOSPeerCoderStatus SOSCoderWrap(SOSCoderRef coder, CFDataRef message, CFMutableDataRef *codedMessage, CFStringRef clientId, CFErrorRef *error);
+
+bool SOSCoderCanWrap(SOSCoderRef coder);
+
+void SOSCoderReset(SOSCoderRef coder);
+
+#endif
diff --git a/sec/SOSCircle/SecureObjectSync/SOSEngine.c b/sec/SOSCircle/SecureObjectSync/SOSEngine.c
new file mode 100644 (file)
index 0000000..aab5bff
--- /dev/null
@@ -0,0 +1,932 @@
+/*
+ * Created by Michael Brouwer on 7/17/12.
+ * Copyright 2012 Apple Inc. All Rights Reserved.
+ */
+
+/*
+ * SOSEngine.c -  Implementation of a secure object syncing engine
+ */
+
+#include <SecureObjectSync/SOSEngine.h>
+#include <SecureObjectSync/SOSPeer.h>
+#include <SecureObjectSync/SOSPeerInfo.h>
+#include <corecrypto/ccder.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <utilities/SecCFError.h>
+#include <utilities/SecCFRelease.h>
+#include <utilities/SecCFWrappers.h>
+#include <utilities/der_plist.h>
+#include <utilities/der_plist_internal.h>
+#include <utilities/debugging.h>
+#include <utilities/iCloudKeychainTrace.h>
+#include <AssertMacros.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <SecItemServer.h>
+#include <SecItemPriv.h>
+
+/* DataSource helper macros and functions. */
+
+// TODO: Change to create with DER.
+#define SOSObjectCreateWithPropertyList(dataSource, plist, error) (dataSource->createWithPropertyList(dataSource, plist, error))
+
+#define SOSObjectCopyPropertyList(dataSource, object, error) (dataSource->copyPropertyList(object, error))
+#define SOSObjectCopyDigest(dataSource, object, error) (dataSource->copyDigest(object, error))
+#define SOSObjectCopyPrimaryKey(dataSource, object, error) (dataSource->copyPrimaryKey(object, error))
+#define SOSObjectCopyMergedObject(dataSource, object1, object2, error) (dataSource->copyMergedObject(object1, object2, error))
+
+#define kSOSMaxObjectPerMessage (500)
+
+static CFArrayRef SOSDataSourceCopyObjectArray(SOSDataSourceRef data_source, SOSManifestRef manifest, CFErrorRef *error) {
+    CFMutableArrayRef objects = CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks);
+
+    // Delta sync by only sending a max of kSOSMaxObjectPerMessage objects at a time.
+    SOSManifestRef toSend = NULL;
+    if (SOSManifestGetCount(manifest) > kSOSMaxObjectPerMessage) {
+        toSend = SOSManifestCreateWithBytes(SOSManifestGetBytePtr(manifest), kSOSMaxObjectPerMessage * SOSDigestSize, error);
+    } else {
+        toSend = manifest;
+        CFRetain(toSend);
+    }
+
+    if (!data_source->foreach_object(data_source, toSend, error, ^bool (SOSObjectRef object, CFErrorRef *localError) {
+        CFDictionaryRef plist = SOSObjectCopyPropertyList(data_source, object, localError);
+        if (plist) {
+            CFArrayAppendValue(objects, plist);
+            CFRelease(plist);
+        }
+        return plist;
+    })) {
+        CFReleaseNull(objects);
+    }
+    CFRetainSafe(toSend);
+    return objects;
+}
+
+static CFDataRef SOSDataSourceCopyManifestDigest(SOSDataSourceRef ds, CFErrorRef *error) {
+    CFMutableDataRef manifestDigest = CFDataCreateMutable(0, SOSDigestSize);
+    CFDataSetLength(manifestDigest, SOSDigestSize);
+    if (!ds->get_manifest_digest(ds, CFDataGetMutableBytePtr(manifestDigest), error))
+        CFReleaseNull(manifestDigest);
+
+    return manifestDigest;
+}
+
+static SOSManifestRef SOSDataSourceCopyManifest(SOSDataSourceRef ds, CFErrorRef *error) {
+    return ds->copy_manifest(ds, error);
+}
+
+static void SOSDataSourceRelease(SOSDataSourceRef ds) {
+    ds->release(ds);
+}
+
+
+/* SOSEngine implementation. */
+
+static CFStringRef sErrorDomain = CFSTR("com.apple.security.sos.engine.error");
+
+static bool SOSEngineCreateError(CFIndex errorCode, CFStringRef descriptionString, CFErrorRef previousError, CFErrorRef *newError) {
+    SecCFCreateError(errorCode, descriptionString, sErrorDomain, previousError, newError);
+    return true;
+}
+
+struct __OpaqueSOSEngine {
+    SOSDataSourceRef dataSource;
+};
+
+SOSEngineRef SOSEngineCreate(SOSDataSourceRef dataSource, CFErrorRef *error) {
+    SOSEngineRef engine = calloc(1, sizeof(struct __OpaqueSOSEngine));
+    engine->dataSource = dataSource;
+
+    return engine;
+}
+
+void SOSEngineDispose(SOSEngineRef engine) {
+    SOSDataSourceRelease(engine->dataSource);
+    free(engine);
+}
+
+/* SOSEngine. */
+enum SOSMessageType {
+    SOSManifestInvalidMessageType = 0,
+    SOSManifestDigestMessageType = 1,
+    SOSManifestMessageType = 2,
+    SOSManifestDeltaAndObjectsMessageType = 3,
+};
+
+/* H(): SHA1 hash function.
+ M: Manifest of peer p
+ MSG: H(M).
+ SOSPeerMessage := SEQUENCE {
+ messageType INTEGER (manifestDigest, manifest, manifestDeltaAndObjects)
+ version INTEGER OPTIONAL default v0
+ content ANY defined by messageType
+ }
+ ManifestDigest := OCTECT STRING (length 20)
+ Manifest := OCTECT STRING (length 20 * number of entries)
+ Value := CHOICE {
+ bool Boolean
+ number INTEGER
+ string UTF8String
+ data OCTECT STRING
+ date GENERAL TIME
+ dictionary Object
+ array Array
+ }
+ KVPair := SEQUENCE {
+ key UTF8String
+ value Value
+ }
+ Array := SEQUENCE of Value
+ Dictionary := SET of KVPair
+ Object := SEQUENCE {
+ [0] conflict OCTECT STRING OPTIONAL
+ [1] change OCTECT STRING OPTIONAL
+ object Dictionary
+ ManifestDeltaAndObjects := SEQUENCE {
+ manfestDigest ManifestDigest
+ removals Manifest
+ additions Manifest
+ addedObjects SEQUENCE of Object
+ }
+ manifestDigest content = OCTECT STRING
+ manifest content := OCTECT STRING
+ manifestDeltaAndObjects := SEQUENCE {
+ manfestDigest ManifestDigest
+ }
+ */
+
+
+/* ManifestDigest message */
+static size_t der_sizeof_manifest_digest_message(void) {
+    return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE,
+                        (ccder_sizeof_uint64(SOSManifestDigestMessageType) +
+                         ccder_sizeof_raw_octet_string(SOSDigestSize)));
+}
+
+static uint8_t *der_encode_manifest_digest_message(const uint8_t digest[SOSDigestSize], const uint8_t *der, uint8_t *der_end) {
+    return ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der,
+           ccder_encode_uint64(SOSManifestDigestMessageType, der,
+           ccder_encode_raw_octet_string(SOSDigestSize, digest, der, der_end)));
+}
+
+/* This message is sent to each peer that joins a circle and can also be sent
+ as a form of ACK to confirm that the local peer is in sync with the peer
+ this is beig sent to. */
+CFDataRef SOSEngineCreateManifestDigestMessage(SOSEngineRef engine, SOSPeerRef peer, CFErrorRef *error) {
+    /* TODO: avoid copying the digest here by inlining der_encode_manifest_digest_message(). */
+
+    uint8_t digest[SOSDigestSize];
+    if (!engine->dataSource->get_manifest_digest(engine->dataSource, &digest[0], error)) {
+        return NULL;
+    }
+    
+    size_t der_size = der_sizeof_manifest_digest_message();
+    CFMutableDataRef message = CFDataCreateMutable(NULL, der_size);
+    if (message == NULL) {
+       return NULL;
+    }
+    CFDataSetLength(message, der_size);
+    uint8_t *der_end = CFDataGetMutableBytePtr(message);
+    const uint8_t *der = der_end;
+    der_end += der_size;
+
+    der_end = der_encode_manifest_digest_message(digest, der, der_end);
+    assert(der == der_end);
+
+    return message;
+}
+
+
+/* Manifest message */
+static size_t der_sizeof_manifest_message(SOSManifestRef manifest) {
+    return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE,
+                        (ccder_sizeof_uint64(SOSManifestMessageType) +
+                         ccder_sizeof_raw_octet_string(SOSManifestGetSize(manifest))));
+}
+
+static uint8_t *der_encode_manifest_message(SOSManifestRef manifest, const uint8_t *der, uint8_t *der_end) {
+    return ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der,
+           ccder_encode_uint64(SOSManifestMessageType, der,
+           ccder_encode_raw_octet_string(SOSManifestGetSize(manifest),
+                                         SOSManifestGetBytePtr(manifest), der, der_end)));
+}
+
+/* This message is sent in response to a manifestDigest if our manifestDigest
+ differs from that of the received manifestDigest, or in response to a
+ manifestAndObjects message if the manifestDigest in the received message
+ doesn't match our own manifestDigest. */
+CFDataRef SOSEngineCreateManifestMessage(SOSEngineRef engine, SOSPeerRef peer, CFErrorRef *error) {
+    SOSManifestRef manifest = SOSDataSourceCopyManifest(engine->dataSource, error);
+    if (!manifest)
+        return NULL;
+
+    size_t der_size = der_sizeof_manifest_message(manifest);
+    CFMutableDataRef message = CFDataCreateMutable(NULL, der_size);
+    CFDataSetLength(message, der_size);
+    uint8_t *der_end = CFDataGetMutableBytePtr(message);
+    const uint8_t *der = der_end;
+    der_end += der_size;
+
+    der_end = der_encode_manifest_message(manifest, der, der_end);
+    assert(der == der_end);
+
+    return message;
+}
+
+
+/* ManifestDeltaAndObjects message */
+static size_t der_sizeof_manifest_and_objects_message(SOSManifestRef removals, SOSManifestRef additions, CFArrayRef objects, CFErrorRef *error) {
+    size_t objects_size = der_sizeof_plist(objects, error);
+    if (objects_size == 0)
+        return objects_size;
+
+    return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE,
+                        (ccder_sizeof_uint64(SOSManifestDeltaAndObjectsMessageType) +
+                         ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE,
+                         (ccder_sizeof_raw_octet_string(SOSDigestSize) +
+                          ccder_sizeof_raw_octet_string(SOSManifestGetSize(removals)) +
+                          ccder_sizeof_raw_octet_string(SOSManifestGetSize(additions)) +
+                          objects_size))));
+}
+
+static uint8_t *der_encode_manifest_and_objects_message(CFDataRef digest, SOSManifestRef removals, SOSManifestRef additions, CFArrayRef objects, CFErrorRef *error, const uint8_t *der, uint8_t *der_end) {
+    assert(CFDataGetLength(digest) == SOSDigestSize);
+    return ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der,
+           ccder_encode_uint64(SOSManifestDeltaAndObjectsMessageType, der,
+           ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der,
+           ccder_encode_raw_octet_string(SOSDigestSize, CFDataGetBytePtr(digest), der,
+           ccder_encode_raw_octet_string(SOSManifestGetSize(removals), SOSManifestGetBytePtr(removals), der,
+           ccder_encode_raw_octet_string(SOSManifestGetSize(additions), SOSManifestGetBytePtr(additions), der,
+           der_encode_plist(objects, error, der, der_end)))))));
+}
+
+/* This message is sent in response to a local change that needs to be
+ propagated to our peers or in response to a manifest or manifestDigest
+ message from a peer that is not in sync with us yet. */
+CFDataRef SOSEngineCreateManifestAndObjectsMessage(SOSEngineRef engine, SOSPeerRef peer, CFErrorRef *error) {
+    /* Assumptions:
+       peer has a manifest that corresponds to peers real manifest.
+       we send everything in our datasource that's not in peers manifest already to peer.
+     */
+    CFMutableDataRef message = NULL;
+    SOSManifestRef manifest, peerManifest, additions, removals;
+
+retry:
+    manifest = SOSDataSourceCopyManifest(engine->dataSource, error);
+    if (!manifest)
+        goto errOut4;
+    
+    peerManifest = SOSPeerCopyManifest(peer, error);
+    if (!peerManifest)
+        goto errOut3;
+
+    if (!SOSManifestDiff(manifest, peerManifest, &additions, &removals, error))
+        goto errOut2;
+
+    CFErrorRef localError = NULL;
+    CFArrayRef objects = SOSDataSourceCopyObjectArray(engine->dataSource, additions, &localError);
+    if (!objects) {
+        if(SecErrorGetOSStatus(localError)==errSecDecode) {
+            secnotice("engine", "Corrupted item found: %@", localError);
+            CFReleaseNull(manifest);
+            CFReleaseNull(additions);
+            CFReleaseNull(removals);
+            CFReleaseNull(peerManifest);
+            CFReleaseNull(localError);
+            goto retry;
+        }
+        if(error && *error==NULL)
+            *error=localError;
+        else
+            CFReleaseNull(localError);
+        goto errOut1;
+    }
+
+    size_t der_size = der_sizeof_manifest_and_objects_message(removals, additions, objects, error);
+    if (der_size == 0)
+        goto errOut0;
+
+    /* TODO: avoid copying the digest here by inlining der_encode_manifest_and_objects_message(). */
+    CFDataRef peerDigest = SOSPeerCopyManifestDigest(peer, error);
+    if (!peerDigest)
+        goto errOut0;
+
+    message = CFDataCreateMutable(NULL, der_size);
+    CFDataSetLength(message, der_size);
+    uint8_t *der_end = CFDataGetMutableBytePtr(message);
+    const uint8_t *der = der_end;
+    der_end += der_size;
+
+    der_end = der_encode_manifest_and_objects_message(peerDigest, removals, additions, objects, error, der, der_end);
+    assert(der == der_end);
+    if (der_end == NULL) {
+        CFReleaseNull(message);
+        goto errOut_;
+    }
+
+    /* Record the peers new manifest assuming that peer will accept all the
+       changes we are about to send them. */
+    SOSPeerSetManifest(peer, manifest, error);
+
+errOut_:
+    CFRelease(peerDigest);
+errOut0:
+    CFRelease(objects);
+errOut1:
+    SOSManifestDispose(removals);
+    SOSManifestDispose(additions);
+errOut2:
+    SOSManifestDispose(peerManifest);
+errOut3:
+    SOSManifestDispose(manifest);
+errOut4:
+
+    return message;
+}
+
+static const uint8_t *der_decode_msg_type(enum SOSMessageType *msg_type,
+                                          const uint8_t *der,
+                                          const uint8_t *der_end,
+                                          CFErrorRef *error) {
+    const uint8_t *body_end;
+    der = ccder_decode_sequence_tl(&body_end, der, der_end);
+    if (!der)
+        return NULL;
+
+    if (body_end != der_end) {
+        SOSEngineCreateError(kSOSEngineInvalidMessageError, CFSTR("Trailing garbage at end of message"), NULL, error);
+        return NULL;
+    }
+
+    uint64_t msgType;
+    der = ccder_decode_uint64(&msgType, der, der_end);
+    if (msgType < 1 || msgType > SOSManifestDeltaAndObjectsMessageType) {
+        SecCFCreateErrorWithFormat(kSOSEngineInvalidMessageError, sErrorDomain,
+                                   NULL, error, NULL,
+                                   CFSTR("Bad message type: %llu"), msgType);
+        return NULL;
+    }
+    *msg_type = (enum SOSMessageType)msgType;
+    return der;
+}
+
+static const uint8_t *
+der_decode_manifest_digest(CFDataRef *digest, CFErrorRef *error,
+                           const uint8_t *der, const uint8_t *der_end) {
+    require_quiet(der, errOut);
+    size_t len;
+    der = ccder_decode_tl(CCDER_OCTET_STRING, &len, der, der_end);
+    require_action_quiet(der, errOut, SOSEngineCreateError(kSOSEngineInvalidMessageError, CFSTR("Failed to find string"), NULL, error));
+    require_action_quiet(len == SOSDigestSize, errOut, SOSEngineCreateError(kSOSEngineInvalidMessageError, CFSTR("Invalid digest size"), NULL, error));
+
+    *digest = CFDataCreate(0, der, len);
+    require_action_quiet(*digest, errOut, SOSEngineCreateError(kSOSEngineInvalidMessageError, CFSTR("Failed to create digest"), NULL, error));
+
+    der += len;
+    require_action_quiet(der, errOut, CFReleaseNull(*digest); SOSEngineCreateError(kSOSEngineInvalidMessageError, CFSTR("Failed to find string"), NULL, error));
+
+    return der;
+
+errOut:
+    return NULL;
+}
+
+static const uint8_t *
+der_decode_manifest(SOSManifestRef *manifest, CFErrorRef *error,
+                    const uint8_t *der, const uint8_t *der_end) {
+    if (!der)
+        goto errOut;
+    size_t len;
+    der = ccder_decode_tl(CCDER_OCTET_STRING, &len, der, der_end);
+    if (!der) {
+        SOSEngineCreateError(kSOSEngineInvalidMessageError, CFSTR("Failed to decode manifest"), NULL, error);
+        goto errOut;
+    }
+    if (len % SOSDigestSize != 0) {
+        SOSEngineCreateError(kSOSEngineInvalidMessageError, CFSTR("manifest not a multiple of digest size"), NULL, error);
+        goto errOut;
+    }
+    *manifest = SOSManifestCreateWithBytes(der, len, error);
+    if (!*manifest)
+        goto errOut;
+
+    return der += len;
+
+errOut:
+    return NULL;
+}
+
+static const uint8_t *
+der_decode_manifest_digest_message(CFDataRef *digest, CFErrorRef *error,
+                                   const uint8_t *der, const uint8_t *der_end) {
+    der = der_decode_manifest_digest(digest, error, der, der_end);
+    if (der && der != der_end) {
+        SOSEngineCreateError(kSOSEngineInvalidMessageError, CFSTR("Trailing garbage after digest"), NULL, error);
+        CFReleaseNull(*digest);
+        der = NULL;
+    }
+    return der;
+}
+
+static const uint8_t *
+der_decode_manifest_message(SOSManifestRef *manifest, CFErrorRef *error,
+                            const uint8_t *der, const uint8_t *der_end) {
+    der = der_decode_manifest(manifest, error, der, der_end);
+    if (der && der != der_end) {
+        SOSEngineCreateError(kSOSEngineInvalidMessageError, CFSTR("Trailing garbage after manifest"), NULL, error);
+        SOSManifestDispose(*manifest);
+        *manifest = NULL;
+        der = NULL;
+    }
+    return der;
+}
+
+static const uint8_t *
+der_decode_manifest_and_objects_message(CFDataRef *peerManifestDigest,
+                                        SOSManifestRef *removals,
+                                        SOSManifestRef *additions,
+                                        CFArrayRef *objects,
+                                        CFErrorRef *error, const uint8_t *der,
+                                        const uint8_t *der_end) {
+    const uint8_t *body_end;
+    der = ccder_decode_sequence_tl(&body_end, der, der_end);
+    if (!der) {
+        SOSEngineCreateError(kSOSEngineInvalidMessageError, CFSTR("Failed to decode top level sequence"), NULL, error);
+        goto errOut;
+    }
+
+    if (body_end != der_end) {
+        SOSEngineCreateError(kSOSEngineInvalidMessageError, CFSTR("Trailing garbage at end of message"), NULL, error);
+        goto errOut;
+    }
+
+    der = der_decode_manifest_digest(peerManifestDigest, error, der, der_end);
+    if (!der)
+        goto errOut;
+    der = der_decode_manifest(removals, error, der, der_end);
+    if (!der)
+        goto errOut1;
+    der = der_decode_manifest(additions, error, der, der_end);
+    if (!der)
+        goto errOut2;
+
+    CFPropertyListRef pl;
+    der = der_decode_plist(0, 0, &pl, error, der, der_end);
+    if (!der)
+        goto errOut3;
+
+    if (der != der_end) {
+        SOSEngineCreateError(kSOSEngineInvalidMessageError, CFSTR("Trailing garbage at end of message body"), NULL, error);
+        goto errOut4;
+    }
+
+    // TODO Check that objects is in fact an array. */
+    if (CFArrayGetTypeID() != CFGetTypeID(pl)) {
+        SOSEngineCreateError(kSOSEngineInvalidMessageError, CFSTR("objects is not an array"), NULL, error);
+        goto errOut4;
+    }
+    *objects = pl;
+
+    return der;
+
+errOut4:
+    CFRelease(pl);
+errOut3:
+    CFRelease(additions);
+errOut2:
+    CFRelease(removals);
+errOut1:
+    CFRelease(peerManifestDigest);
+errOut:
+    return NULL;
+}
+
+
+#if 0
+enum SOSMessageType SOSMessageGetType(CFDataRef message) {
+    const uint8_t *der = CFDataGetBytePtr(message);
+    const uint8_t *der_end = der + CFDataGetLength(message);
+    enum SOSMessageType msg_type;
+    der_decode_msg_type(&msg_type, der, der_end, NULL);
+    if (!der) {
+        return SOSManifestInvalidMessageType;
+    }
+
+    return msg_type;
+}
+#endif
+
+/* H(): SHA1 hash function.
+ M: Manifest of peer p
+ MSG: H(M) */
+static CFDataRef SOSEngineCopyManifestDigestReply(SOSEngineRef engine,
+                                                  SOSPeerRef peer,
+                                                  CFDataRef digest,
+                                                  CFErrorRef *error) {
+    CFDataRef reply = NULL;
+    CFDataRef peerDigest = SOSPeerCopyManifestDigest(peer, NULL);
+    CFDataRef manifestDigest = SOSDataSourceCopyManifestDigest(engine->dataSource, error);
+    if (manifestDigest) {
+        if (CFEqual(manifestDigest, digest)) {
+            /* Our dataSources manifest and that of the peer are equal, we are in sync. */
+            if (peerDigest && CFEqual(peerDigest, digest)) {
+                /* The last known digest we had for peer already matched the digest peer
+                   sent us, so this message is redundant, consider it an ack of our last
+                   message to peer. */
+                reply = CFDataCreate(kCFAllocatorDefault, NULL, 0);
+            } else {
+                /* Our peer just sent us a manifest digest that matches our own, but the digest
+                   we have for the peer (if any) doesn't match that.   Peer must have the same
+                   manifest we do, so record that. */
+                SOSManifestRef manifest = SOSDataSourceCopyManifest(engine->dataSource, error);
+                if (manifest) {
+                    bool ok = SOSPeerSetManifest(peer, manifest, error);
+                    SOSManifestDispose(manifest);
+                    if (ok) {
+                        /* Since we got lucky and happen to have the same digest as our peer, we
+                         send back an ack to ensure our peer ends up knowning our manifest as well. */
+                        reply = SOSEngineCreateManifestDigestMessage(engine, peer, error);
+                    }
+                }
+            }
+        } else if (peerDigest && CFEqual(peerDigest, digest)) {
+            /* We know peer's current manifest is correct (the computed digest
+               matches the passed in one) but peer and our dataSource
+               are not in sync.  Send the deltas to peer. */
+            reply = SOSEngineCreateManifestAndObjectsMessage(engine, peer, error);
+        } else {
+            /* Our peer has no digest yet, or the manifestDigest peer just sent
+               us doesn't match the digest of the manifest we think peer has.
+               We need to get peer to tell us their manifest, to do so we sent
+               it ours and hope it responds with deltas. */
+            reply = SOSEngineCreateManifestMessage(engine, peer, error);
+        }
+        CFRelease(manifestDigest);
+    }
+    CFReleaseSafe(peerDigest);
+    return reply;
+}
+
+/* M: Manifest of peer p
+ MSG: M */
+static CFDataRef SOSEngineCopyManifestReply(SOSEngineRef engine, SOSPeerRef peer,
+                                            SOSManifestRef manifest,
+                                            CFErrorRef *error) {
+    CFDataRef reply = NULL;
+    // Peer just told us what his manifest was.  Let's roll with it.
+    SOSPeerSetManifest(peer, manifest, error);
+    CFDataRef peerManifestDigest = SOSPeerCopyManifestDigest(peer, error);
+    if (peerManifestDigest) {
+        CFDataRef manifestDigest = SOSDataSourceCopyManifestDigest(engine->dataSource, error);
+        if (manifestDigest) {
+            if (CFEqual(peerManifestDigest, manifestDigest)) {
+                /* We're in sync, optionally send peer an ack. */
+                reply = SOSEngineCreateManifestDigestMessage(engine, peer, error);
+            } else {
+                /* Send peer the objects it is missing from our manifest. */
+                reply = SOSEngineCreateManifestAndObjectsMessage(engine, peer, error);
+            }
+            CFRelease(manifestDigest);
+        }
+        CFRelease(peerManifestDigest);
+    }
+    return reply;
+}
+
+static bool SOSEngineProccesObjects(SOSEngineRef engine,
+                                    SOSPeerRef peer,
+                                    CFDataRef digest,
+                                    SOSManifestRef removals,
+                                    SOSManifestRef additions,
+                                    CFArrayRef objects,
+                                    CFErrorRef *error) {
+    __block bool result = true;
+    CFArrayForEach(objects, ^(const void *value) {
+        SOSObjectRef ob = SOSObjectCreateWithPropertyList(engine->dataSource, value, error);
+        if (ob) {
+            SOSMergeResult mr = engine->dataSource->add(engine->dataSource, ob, error);
+            if (!mr) {
+                result = false;
+                // assertion failure, duplicate object added during transaction, that wasn't explicitly listed in removal list.
+                // treat as conflict?
+                // oa =  ds->lookup(pkb);
+                // ds->choose_between(oa, ob)
+                // TODO: This is needed is we want to allow conflicts with other circles.
+                SetCloudKeychainTraceValueForKey(kCloudKeychainNumberOfTimesSyncFailed, 1);
+                secerror("assertion failure, add failed: %@",
+                         error ? *error : (CFErrorRef)CFSTR("error is null"));
+            }
+            CFRelease(ob);
+        }
+    });
+    return result;
+}
+
+/* H(): SHA1 hash function.
+ L: Manifest of local peer.
+ M: Manifest of peer p.
+ M-L: Manifest of entries in M but not in L
+ L-M: Manifest of entries in L but not in M
+ O(M): Objects in manifest M
+ MSG: H(L) || L-M || M-L || O(M-L)  */
+static CFDataRef SOSEngineCopyManifestAndObjectsReply(SOSEngineRef engine,
+                                                      SOSPeerRef peer,
+                                                      CFDataRef digest,
+                                                      SOSManifestRef removals,
+                                                      SOSManifestRef additions,
+                                                      CFArrayRef objects,
+                                                      CFErrorRef *error) {
+    CFDataRef reply = NULL;
+    CFMutableDataRef manifestDigest = (CFMutableDataRef)SOSDataSourceCopyManifestDigest(engine->dataSource, error);
+    if (manifestDigest) {
+        SOSManifestRef manifest = SOSDataSourceCopyManifest(engine->dataSource, error);
+
+        /* Always proccess the objects after we snapshot our manifest. */
+        if (!SOSEngineProccesObjects(engine, peer, digest, removals, additions, objects, error)) {
+            secerror("peer: %@ SOSEngineProccesObjects(): %@", SOSPeerGetID(peer), *error);
+        }
+
+        if (CFEqual(manifestDigest, digest)) {
+            SOSManifestRef peerManifest = NULL;
+            if (manifest) {
+                peerManifest = SOSManifestCreateWithPatch(manifest, removals, additions, error);
+            }
+            if (peerManifest) {
+                if (SOSPeerSetManifest(peer, peerManifest, error)) {
+                    /* Now proccess the objects. */
+                    if (!SOSEngineProccesObjects(engine, peer, digest, removals, additions, objects, error)) {
+                        secerror("peer: %@ SOSEngineProccesObjects(): %@", SOSPeerGetID(peer), *error);
+                    }
+
+                    CFDataRef peerDigest = SOSPeerCopyManifestDigest(peer, error);
+                    if (peerDigest) {
+                        /* Depending on whether after proccess objects we still have objects that need to be sent back to peer we respond with our digestManifest or with a manifestAndObjectsMessage. */
+                        if (engine->dataSource->get_manifest_digest(engine->dataSource, CFDataGetMutableBytePtr(manifestDigest), error)) {
+                            if (CFEqual(manifestDigest, peerDigest)) {
+                                reply = SOSEngineCreateManifestDigestMessage(engine, peer, error);
+                            } else {
+                                reply = SOSEngineCreateManifestAndObjectsMessage(engine, peer, error);
+                            }
+                        }
+                        CFRelease(peerDigest);
+                    }
+                }
+                CFRelease(peerManifest);
+            } else {
+                secerror("Received peer: %@ sent bad message: %@", SOSPeerGetID(peer), *error);
+                /* We failed to compute peer's digest, let's tell him ours again and hope for a retransmission. */
+                /* TODO: Perhaps this should be sent by the top level whenever an error occurs during parsing. */
+                reply = SOSEngineCreateManifestDigestMessage(engine, peer, error);
+            }
+        } else {
+            /* ds->manifestDigest != msg->manigestDigest => We received deltas
+               against a manifest we don't have respond with our current
+               manifest to get back in sync. */
+            reply = SOSEngineCreateManifestMessage(engine, peer, error);
+        }
+        CFReleaseSafe(manifest);
+        CFRelease(manifestDigest);
+    }
+    return reply;
+}
+
+/* Handle incoming message from peer p.  Return false if there was an error, true otherwise. */
+bool SOSEngineHandleMessage(SOSEngineRef engine, SOSPeerRef peer,
+                            CFDataRef message, CFErrorRef *error) {
+    CFDataRef reply = NULL;
+    SOSManifestRef oldPeerManifest = SOSPeerCopyManifest(peer, NULL);
+    const uint8_t *der = CFDataGetBytePtr(message);
+    const uint8_t *der_end = der + CFDataGetLength(message);
+    enum SOSMessageType msgType;
+
+    der = der_decode_msg_type(&msgType, der, der_end, error);
+    if (der) switch (msgType) {
+        case SOSManifestDigestMessageType:
+        {
+            CFDataRef digest = NULL; // Make the static analyzer happy by NULL and Release safe
+            der = der_decode_manifest_digest_message(&digest, error, der, der_end);
+            if (der) {
+                reply = SOSEngineCopyManifestDigestReply(engine, peer, digest, error);
+            }
+            CFReleaseSafe(digest);
+            break;
+        }
+        case SOSManifestMessageType:
+        {
+            SOSManifestRef manifest;
+            der = der_decode_manifest_message(&manifest, error, der, der_end);
+            if (der) {
+                reply = SOSEngineCopyManifestReply(engine, peer, manifest, error);
+                SOSManifestDispose(manifest);
+            }
+            break;
+        }
+        case SOSManifestDeltaAndObjectsMessageType:
+        {
+            CFDataRef peerManifestDigest;
+            SOSManifestRef removals;
+            SOSManifestRef additions;
+            CFArrayRef objects;
+            der = der_decode_manifest_and_objects_message(&peerManifestDigest, &removals, &additions, &objects, error, der, der_end);
+            if (der) {
+                reply = SOSEngineCopyManifestAndObjectsReply(engine, peer, peerManifestDigest, removals, additions, objects, error);
+                CFRelease(peerManifestDigest);
+                SOSManifestDispose(removals);
+                SOSManifestDispose(additions);
+                CFRelease(objects);
+            }
+            break;
+        }
+        default:
+            SecCFCreateErrorWithFormat(kSOSEngineInvalidMessageError, sErrorDomain,
+                                       NULL, error, NULL, CFSTR("Invalid message type %d"), msgType);
+            break;
+    }
+
+    bool ok = reply;
+    if (reply && CFDataGetLength(reply)) {
+        ok = SOSPeerSendMessage(peer, reply, error);
+        if (!ok)
+            SOSPeerSetManifest(peer, oldPeerManifest, NULL);
+    }
+    secnotice("engine", "%@", SOSPeerGetID(peer));
+    CFReleaseSafe(oldPeerManifest);
+    CFReleaseSafe(reply);
+    return ok;
+}
+
+bool SOSEngineSyncWithPeer(SOSEngineRef engine, SOSPeerRef peer, bool force,
+                           CFErrorRef *error) {
+    CFDataRef reply = NULL;
+    SOSManifestRef oldPeerManifest = SOSPeerCopyManifest(peer, NULL);
+    bool ok = true;
+    require_quiet(SOSPeerCanSendMessage(peer), exit);
+    CFDataRef peerDigest = SOSPeerCopyManifestDigest(peer, NULL);
+    CFMutableDataRef manifestDigest = CFDataCreateMutable(0, SOSDigestSize);
+    CFDataSetLength(manifestDigest, SOSDigestSize);
+    if (engine->dataSource->get_manifest_digest(engine->dataSource, CFDataGetMutableBytePtr(manifestDigest), error)) {
+        if (peerDigest) {
+            if (CFEqual(peerDigest, manifestDigest)) {
+                /* We are in sync with peer already. */
+                if (force) {
+                    /* If we are at the end of the OTR handshake, we have to send
+                       something to our peer no matter what to break the symmmetry.  */
+                    reply = SOSEngineCreateManifestDigestMessage(engine, peer, error);
+                } else {
+                    reply = CFDataCreate(kCFAllocatorDefault, NULL, 0);
+                }
+            } else {
+                /* We have have a digest for peer's manifest and it doesn't
+                   match our current digest, so send deltas to peer. */
+                reply = SOSEngineCreateManifestAndObjectsMessage(engine, peer, error);
+            }
+        } else {
+            /* We have no digest for peer yet, send our manifest digest to peer,
+               it should respond with it's manifest so we can sync. */
+            reply = SOSEngineCreateManifestDigestMessage(engine, peer, error);
+        }
+    }
+    CFRelease(manifestDigest);
+    CFReleaseSafe(peerDigest);
+
+    ok = ok && reply;
+    if (ok && CFDataGetLength(reply)) {
+        ok = SOSPeerSendMessage(peer, reply, error);
+        if (!ok)
+            SOSPeerSetManifest(peer, oldPeerManifest, NULL);
+    }
+
+exit:
+    secnotice("engine", "%@", SOSPeerGetID(peer));
+    CFReleaseSafe(oldPeerManifest);
+    CFReleaseSafe(reply);
+    return ok;
+}
+
+#if 0
+static void appendObject(CFMutableStringRef desc, CFDictionaryRef object) {
+    __block bool needComma = false;
+    CFDictionaryForEach(object, ^(const void *key, const void *value) {
+        if (needComma)
+            CFStringAppend(desc, CFSTR(","));
+        else
+            needComma = true;
+
+        CFStringAppend(desc, key);
+        CFStringAppend(desc, CFSTR("="));
+        if (CFEqual(CFSTR("data"), key)) {
+            CFStringAppend(desc, CFSTR("<?>"));
+        } else if (isData(value)) {
+            CFStringAppendHexData(desc, value);
+        } else {
+            CFStringAppendFormat(desc, 0, CFSTR("%@"), value);
+        }
+    });
+}
+#endif
+
+static void appendObjects(CFMutableStringRef desc, CFArrayRef objects) {
+    __block bool needComma = false;
+    CFArrayForEach(objects, ^(const void *value) {
+        if (needComma)
+            CFStringAppend(desc, CFSTR(","));
+        else
+            needComma = true;
+
+        SecItemServerAppendItemDescription(desc, value);
+    });
+}
+
+CFStringRef SOSMessageCopyDescription(CFDataRef message) {
+    if (!message)
+        return CFSTR("<NULL>");
+
+    CFMutableStringRef desc = CFStringCreateMutable(0, 0);
+    const uint8_t *der = CFDataGetBytePtr(message);
+    const uint8_t *der_end = der + CFDataGetLength(message);
+    enum SOSMessageType msgType;
+
+    CFStringAppend(desc, CFSTR("<Msg"));
+    der = der_decode_msg_type(&msgType, der, der_end, 0);
+    if (der) switch (msgType) {
+        case SOSManifestDigestMessageType:
+        {
+            CFStringAppend(desc, CFSTR("ManifestDigest digest: "));
+            CFDataRef digest = NULL;
+            der = der_decode_manifest_digest_message(&digest, 0, der, der_end);
+            if (der) {
+                CFStringAppendHexData(desc, digest);
+            }
+            CFReleaseNull(digest);
+
+            break;
+        }
+        case SOSManifestMessageType:
+        {
+            CFStringAppend(desc, CFSTR("Manifest"));
+
+            SOSManifestRef manifest;
+            der = der_decode_manifest_message(&manifest, 0, der, der_end);
+            if (der) {
+                CFStringRef mfdesc = SOSManifestCopyDescription(manifest);
+                if (mfdesc) {
+                    CFStringAppendFormat(desc, 0, CFSTR(" manifest: %@"), mfdesc);
+                    CFRelease(mfdesc);
+                }
+                SOSManifestDispose(manifest);
+            }
+            break;
+        }
+        case SOSManifestDeltaAndObjectsMessageType:
+        {
+            CFStringAppend(desc, CFSTR("ManifestDeltaAndObjects digest:"));
+
+            CFDataRef peerManifestDigest;
+            SOSManifestRef removals;
+            SOSManifestRef additions;
+            CFArrayRef objects;
+            der = der_decode_manifest_and_objects_message(&peerManifestDigest, &removals, &additions, &objects, 0, der, der_end);
+            if (der) {
+                CFStringAppendHexData(desc, peerManifestDigest);
+                CFStringRef remdesc = SOSManifestCopyDescription(removals);
+                if (remdesc) {
+                    CFStringAppendFormat(desc, 0, CFSTR(" removals: %@"), remdesc);
+                    CFRelease(remdesc);
+                }
+                CFStringRef adddesc = SOSManifestCopyDescription(additions);
+                if (adddesc) {
+                    CFStringAppendFormat(desc, 0, CFSTR(" additions: %@"), adddesc);
+                    CFRelease(adddesc);
+                }
+                CFStringAppendFormat(desc, 0, CFSTR(" objects: "));
+                appendObjects(desc, objects);
+
+                CFRelease(peerManifestDigest);
+                SOSManifestDispose(removals);
+                SOSManifestDispose(additions);
+                CFRelease(objects);
+            }
+            break;
+        }
+        default:
+            CFStringAppendFormat(desc, 0, CFSTR("InvalidType: %d"), msgType);
+            break;
+    }
+
+    CFStringAppend(desc, CFSTR(">"));
+
+    return desc;
+}
diff --git a/sec/SOSCircle/SecureObjectSync/SOSEngine.h b/sec/SOSCircle/SecureObjectSync/SOSEngine.h
new file mode 100644 (file)
index 0000000..cc63bbf
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Created by Michael Brouwer on 7/17/12.
+ * Copyright 2012 Apple Inc. All Rights Reserved.
+ */
+
+/*!
+ @header SOSEngine.h
+ The functions provided in SOSEngine.h provide an interface to a
+ secure object syncing engine
+ */
+
+#ifndef _SEC_SOSENGINE_H_
+#define _SEC_SOSENGINE_H_
+
+#include <SecureObjectSync/SOSTransport.h>
+#include <CoreFoundation/CFRuntime.h>
+
+__BEGIN_DECLS
+
+enum {
+    kSOSEngineInvalidMessageError = 1,
+    kSOSEngineInternalError = 2,
+};
+
+typedef struct __OpaqueSOSEngine *SOSEngineRef;
+typedef struct __OpaqueSOSPeer *SOSPeerRef;
+
+/* SOSDataSource protocol (non opaque). */
+typedef struct SOSDataSource *SOSDataSourceRef;
+
+typedef struct __OpaqueSOSObject *SOSObjectRef;
+
+/* Implement this if you want to create a new type of sync client.
+ Currently we support keychains, but the engine should scale to
+ entire filesystems. */
+enum SOSMergeResult {
+    kSOSMergeFailure = 0,   // CFErrorRef returned, no error returned in any other case
+    kSOSMergeLocalObject,   // We choose the current object in the dataSource the manifest is still valid.
+    kSOSMergePeersObject,   // We chose the peers object over our own, manifest is now dirty.
+    kSOSMergeCreatedObject, // *createdObject is returned and should be released
+};
+typedef CFIndex SOSMergeResult;
+
+struct SOSDataSource {
+    bool (*get_manifest_digest)(SOSDataSourceRef ds, uint8_t *out_digest, CFErrorRef *error);
+    SOSManifestRef (*copy_manifest)(SOSDataSourceRef ds, CFErrorRef *error);
+    bool (*foreach_object)(SOSDataSourceRef ds, SOSManifestRef manifest, CFErrorRef *error, bool (^handle_object)(SOSObjectRef object, CFErrorRef *error));
+    SOSMergeResult (*add)(SOSDataSourceRef ds, SOSObjectRef object, CFErrorRef *error);
+    void (*release)(SOSDataSourceRef ds);
+
+    SOSObjectRef (*createWithPropertyList)(SOSDataSourceRef ds, CFDictionaryRef plist, CFErrorRef *error);
+    CFDataRef (*copyDigest)(SOSObjectRef object, CFErrorRef *error);
+    CFDataRef (*copyPrimaryKey)(SOSObjectRef object, CFErrorRef *error);
+    CFDictionaryRef (*copyPropertyList)(SOSObjectRef object, CFErrorRef *error);
+    SOSObjectRef (*copyMergedObject)(SOSObjectRef object1, SOSObjectRef object2, CFErrorRef *error);
+    CFDictionaryRef (*backupObject)(SOSObjectRef object, uint64_t handle, CFErrorRef *error);
+    bool (*restoreObject)(SOSDataSourceRef ds, uint64_t handle, CFDictionaryRef item, CFErrorRef *error);
+};
+
+// Create a new engine instance for a given datasource.
+SOSEngineRef SOSEngineCreate(SOSDataSourceRef dataSource, CFErrorRef *error);
+
+// Dispose of an engine when it's no longer needed.
+void SOSEngineDispose(SOSEngineRef engine);
+
+// Handle incoming message from a remote peer.
+bool SOSEngineHandleMessage(SOSEngineRef engine, SOSPeerRef peer,
+                            CFDataRef message, CFErrorRef *error);
+
+// Initiate a sync with the providied peer by sending it a message.
+bool SOSEngineSyncWithPeer(SOSEngineRef engine, SOSPeerRef peer, bool force,
+                           CFErrorRef *error);
+
+/* Internal functions exposed for testability. */
+CFDataRef SOSEngineCreateManifestDigestMessage(SOSEngineRef engine, SOSPeerRef peer, CFErrorRef *error);
+CFDataRef SOSEngineCreateManifestMessage(SOSEngineRef engine, SOSPeerRef peer, CFErrorRef *error);
+CFDataRef SOSEngineCreateManifestAndObjectsMessage(SOSEngineRef engine, SOSPeerRef peer, CFErrorRef *error);
+
+CFStringRef SOSMessageCopyDescription(CFDataRef message);
+
+__END_DECLS
+
+#endif /* !_SEC_SOSENGINE_H_ */
diff --git a/sec/SOSCircle/SecureObjectSync/SOSExports.exp-in b/sec/SOSCircle/SecureObjectSync/SOSExports.exp-in
new file mode 100644 (file)
index 0000000..b3c970f
--- /dev/null
@@ -0,0 +1,53 @@
+//
+// SOS
+//
+
+_kSOSCCCircleChangedNotification
+_kSOSErrorDomain
+_kSOSKVSInitialSyncKey
+_kSOSKVSAccountChangedKey
+
+_SOSCCAcceptApplicants
+_SOSCCCanAuthenticate
+_SOSCCRejectApplicants
+_SOSCCGetLastDepartureReason
+_SOSCCGetStatusDescription
+_SOSCCPurgeUserCredentials
+_SOSCCCopyApplicantPeerInfo
+_SOSCCCopyConcurringPeerPeerInfo
+_SOSCCCopyIncompatibilityInfo
+_SOSCCCopyPeerPeerInfo
+_SOSCCRegisterUserCredentials
+_SOSCCSetUserCredentials
+_SOSCCTryUserCredentials
+_SOSCCRemoveThisDeviceFromCircle
+_SOSCCBailFromCircle_BestEffort
+_SOSCCRequestToJoinCircle
+_SOSCCRequestToJoinCircleAfterRestore
+_SOSCCResetToEmpty
+_SOSCCResetToOffering
+_SOSCCThisDeviceIsInCircle
+_SOSCloudKeychainClearAll
+_SOSCloudKeychainPutObjectsInCloud
+_SOSCloudKeychainRegisterKeysAndGet
+_SOSCloudKeychainSetItemsChangedBlock
+_SOSPeerInfoGetPeerDeviceType
+_SOSPeerInfoGetPeerID
+_SOSPeerInfoGetPeerName
+_SecCreateCFErrorWithXPCObject
+_SecCreateXPCObjectWithCFError
+
+_SOSCircleCreateFromData
+_SOSCloudKeychainGetAllObjectsFromCloud
+_SOSCloudKeychainGetObjectsFromCloud
+_SOSCloudKeychainSynchronizeAndWait
+_SOSKVSKeyGetKeyType
+
+_SOSCCProcessSyncWithAllPeers
+
+#if !(TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+
+// Symbols only for embedded, typically for tests
+_SOSCCGetOperationDescription
+
+#endif
diff --git a/sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.c b/sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.c
new file mode 100644 (file)
index 0000000..b7b6782
--- /dev/null
@@ -0,0 +1,355 @@
+//
+//  SOSFullPeerInfo.c
+//  sec
+//
+//  Created by Mitch Adler on 10/26/12.
+//
+//
+
+#include <AssertMacros.h>
+
+#include <SecureObjectSync/SOSFullPeerInfo.h>
+#include <SecureObjectSync/SOSCircle.h>
+
+#include <SecureObjectSync/SOSInternal.h>
+
+#include <Security/SecKeyPriv.h>
+#include <Security/SecItemPriv.h>
+#include <Security/SecOTR.h>
+#include <CoreFoundation/CFArray.h>
+#include <dispatch/dispatch.h>
+
+#include <stdlib.h>
+#include <assert.h>
+
+#include <utilities/SecCFWrappers.h>
+#include <utilities/SecCFRelease.h>
+
+#include <utilities/der_plist.h>
+#include <utilities/der_plist_internal.h>
+#include <corecrypto/ccder.h>
+
+#include <CommonCrypto/CommonDigest.h>
+#include <CommonCrypto/CommonDigestSPI.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include "utilities/iOSforOSX.h"
+
+#include <AssertMacros.h>
+
+#include <utilities/SecCFError.h>
+
+// for OS X
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//---- missing
+
+extern OSStatus SecKeyCopyPublicBytes(SecKeyRef key, CFDataRef* publicBytes);
+extern SecKeyRef SecKeyCreatePublicFromPrivate(SecKeyRef privateKey);
+#ifdef __cplusplus
+}
+#endif
+
+struct __OpaqueSOSFullPeerInfo {
+    CFRuntimeBase          _base;
+    
+    SOSPeerInfoRef         peer_info;
+    CFDataRef              key_ref;
+};
+
+CFGiblisWithHashFor(SOSFullPeerInfo);
+
+
+static CFStringRef sPublicKeyKey = CFSTR("PublicSigningKey");
+static CFStringRef sNameKey      = CFSTR("DeviceName");
+static CFStringRef sVersionKey   = CFSTR("ConflictVersion");
+
+CFStringRef kSOSFullPeerInfoDescriptionKey = CFSTR("SOSFullPeerInfoDescription");
+CFStringRef kSOSFullPeerInfoSignatureKey = CFSTR("SOSFullPeerInfoSignature");
+CFStringRef kSOSFullPeerInfoNameKey = CFSTR("SOSFullPeerInfoName");
+
+SOSFullPeerInfoRef SOSFullPeerInfoCreate(CFAllocatorRef allocator, CFDictionaryRef gestalt, SecKeyRef signingKey, CFErrorRef* error) {
+    SOSFullPeerInfoRef fpi = CFTypeAllocate(SOSFullPeerInfo, struct __OpaqueSOSFullPeerInfo, allocator);
+
+    fpi->peer_info = SOSPeerInfoCreate(allocator, gestalt, signingKey, error);
+    if (fpi->peer_info == NULL) {
+        CFReleaseNull(fpi);
+        goto exit;
+    }
+    
+    OSStatus result = SecKeyCopyPersistentRef(signingKey, &fpi->key_ref);
+
+    if (result != errSecSuccess) {
+        CFReleaseNull(fpi);
+        goto exit;
+    }
+
+exit:
+    return fpi;
+}
+
+
+
+SOSFullPeerInfoRef SOSFullPeerInfoCreateCloudIdentity(CFAllocatorRef allocator, SOSPeerInfoRef peer, CFErrorRef* error) {
+    SOSFullPeerInfoRef fpi = CFTypeAllocate(SOSFullPeerInfo, struct __OpaqueSOSFullPeerInfo, allocator);
+    
+    SecKeyRef pubKey = NULL;
+    
+    fpi->peer_info = peer;
+    CFRetainSafe(fpi->peer_info);
+    if (fpi->peer_info == NULL) {
+        CFReleaseNull(fpi);
+        goto exit;
+    }
+
+    pubKey = SOSPeerInfoCopyPubKey(peer);
+    
+    fpi->key_ref = SecKeyCreatePersistentRefToMatchingPrivateKey(pubKey, error);
+    
+    if (fpi->key_ref == NULL) {
+        CFReleaseNull(fpi);
+        goto exit;
+    }
+    
+exit:
+    CFReleaseNull(pubKey);
+    return fpi;
+}
+
+
+SOSFullPeerInfoRef SOSFullPeerInfoCreateFromDER(CFAllocatorRef allocator, CFErrorRef* error,
+                                        const uint8_t** der_p, const uint8_t *der_end) {
+    SOSFullPeerInfoRef fpi = CFTypeAllocate(SOSFullPeerInfo, struct __OpaqueSOSFullPeerInfo, allocator);
+    
+    const uint8_t *sequence_end;
+    
+    *der_p = ccder_decode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, &sequence_end, *der_p, der_end);
+    
+    fpi->peer_info = SOSPeerInfoCreateFromDER(allocator, error, der_p, der_end);
+    require_quiet(fpi->peer_info != NULL, fail);
+
+    *der_p = der_decode_data(allocator, kCFPropertyListImmutable, &fpi->key_ref, error, *der_p, sequence_end);
+    require_quiet(*der_p != NULL, fail);
+
+    return fpi;
+
+fail:
+    CFReleaseNull(fpi);
+    return NULL;
+}
+
+SOSFullPeerInfoRef SOSFullPeerInfoCreateFromData(CFAllocatorRef allocator, CFDataRef fullPeerData, CFErrorRef *error)
+{
+    size_t size = CFDataGetLength(fullPeerData);
+    const uint8_t *der = CFDataGetBytePtr(fullPeerData);
+    SOSFullPeerInfoRef inflated = SOSFullPeerInfoCreateFromDER(allocator, error, &der, der + size);
+    return inflated;
+}
+
+static void SOSFullPeerInfoDestroy(CFTypeRef aObj) {
+    SOSFullPeerInfoRef fpi = (SOSFullPeerInfoRef) aObj;
+    
+    CFReleaseNull(fpi->peer_info);
+    CFReleaseNull(fpi->key_ref);
+}
+
+static Boolean SOSFullPeerInfoCompare(CFTypeRef lhs, CFTypeRef rhs) {
+    SOSFullPeerInfoRef lpeer = (SOSFullPeerInfoRef) lhs;
+    SOSFullPeerInfoRef rpeer = (SOSFullPeerInfoRef) rhs;
+    
+    if (!CFEqual(lpeer->peer_info, rpeer->peer_info))
+        return false;
+    
+    if (CFEqual(lpeer->key_ref, rpeer->key_ref))
+        return true;
+    
+    SecKeyRef lpk = SOSFullPeerInfoCopyDeviceKey(lpeer, NULL);
+    SecKeyRef rpk = SOSFullPeerInfoCopyDeviceKey(rpeer, NULL);
+    
+    bool match = lpk && rpk && CFEqual(lpk, rpk);
+    
+    CFReleaseNull(lpk);
+    CFReleaseNull(rpk);
+    
+    return match;
+}
+
+static CFHashCode   SOSFullPeerInfoHash(CFTypeRef cf) {
+    SOSFullPeerInfoRef peer = (SOSFullPeerInfoRef) cf;
+
+    return CFHash(peer->peer_info);
+}
+
+static CFStringRef SOSFullPeerInfoCopyDescription(CFTypeRef aObj) {
+    SOSFullPeerInfoRef fpi = (SOSFullPeerInfoRef) aObj;
+
+    return CFStringCreateWithFormat(NULL, NULL, CFSTR("<SOSFullPeerInfo@%p: \"%@\">"), fpi, fpi->peer_info);
+}
+
+bool SOSFullPeerInfoUpdateGestalt(SOSFullPeerInfoRef peer, CFDictionaryRef gestalt, CFErrorRef* error)
+{
+    SecKeyRef device_key = SOSFullPeerInfoCopyDeviceKey(peer, error);
+    require_quiet(device_key, fail);
+    
+    SOSPeerInfoRef newPeer = SOSPeerInfoCopyWithGestaltUpdate(kCFAllocatorDefault, peer->peer_info,
+                                                              gestalt, device_key, error);
+    
+    require_quiet(newPeer, fail);
+    
+    CFReleaseNull(peer->peer_info);
+    peer->peer_info = newPeer;
+    newPeer = NULL;
+
+    CFReleaseNull(device_key);
+    return true;
+
+fail:
+    CFReleaseNull(device_key);
+    return false;
+}
+
+
+bool SOSFullPeerInfoValidate(SOSFullPeerInfoRef peer, CFErrorRef* error) {
+    return true;
+}
+
+bool SOSFullPeerInfoPurgePersistentKey(SOSFullPeerInfoRef fullPeer, CFErrorRef* error) {
+    CFDictionaryRef query = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
+                                                         kSecValuePersistentRef, fullPeer->key_ref,
+                                                         kSecUseTombstones, kCFBooleanFalse,
+                                                         NULL);
+    SecItemDelete(query);
+    CFReleaseNull(query);
+    
+    return true;
+}
+
+SOSPeerInfoRef SOSFullPeerInfoGetPeerInfo(SOSFullPeerInfoRef fullPeer)
+{
+    return fullPeer?fullPeer->peer_info:NULL;
+}
+
+SecKeyRef  SOSFullPeerInfoCopyDeviceKey(SOSFullPeerInfoRef fullPeer, CFErrorRef* error)
+{
+    SecKeyRef device_key = NULL;
+
+    require(fullPeer->key_ref, fail);
+
+    OSStatus result = SecKeyFindWithPersistentRef(fullPeer->key_ref, &device_key);
+
+    require_action_quiet(result == errSecSuccess, fail, SecError(result, error, CFSTR("Finding Persistent Ref")));
+
+    return device_key;
+        
+fail:
+    CFReleaseNull(device_key);
+    return NULL;
+}
+
+//
+// MARK: Encode and decode
+//
+size_t      SOSFullPeerInfoGetDEREncodedSize(SOSFullPeerInfoRef peer, CFErrorRef *error)
+{
+    size_t peer_size = SOSPeerInfoGetDEREncodedSize(peer->peer_info, error);
+    if (peer_size == 0)
+        return 0;
+
+    size_t ref_size = der_sizeof_data(peer->key_ref, error);
+    if (ref_size == 0)
+        return 0;
+
+    return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE,
+                        peer_size + ref_size);
+}
+
+uint8_t* SOSFullPeerInfoEncodeToDER(SOSFullPeerInfoRef peer, CFErrorRef* error, const uint8_t* der, uint8_t* der_end)
+{
+    return ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der,
+           SOSPeerInfoEncodeToDER(peer->peer_info, error, der,
+           der_encode_data(peer->key_ref, error, der, der_end)));
+}
+
+CFDataRef SOSFullPeerInfoCopyEncodedData(SOSFullPeerInfoRef peer, CFAllocatorRef allocator, CFErrorRef *error)
+{
+    size_t size = SOSFullPeerInfoGetDEREncodedSize(peer, error);
+    if (size == 0)
+        return NULL;
+    uint8_t buffer[size];
+    uint8_t* start = SOSFullPeerInfoEncodeToDER(peer, error, buffer, buffer + sizeof(buffer));
+    CFDataRef result = CFDataCreate(kCFAllocatorDefault, start, size);
+    return result;
+}
+
+bool SOSFullPeerInfoPromoteToApplication(SOSFullPeerInfoRef fpi, SecKeyRef user_key, CFErrorRef *error)
+{
+    bool success = false;
+    SOSPeerInfoRef old_pi = NULL;
+
+    SecKeyRef device_key = SOSFullPeerInfoCopyDeviceKey(fpi, error);
+    require_quiet(device_key, exit);
+
+    old_pi = fpi->peer_info;
+    fpi->peer_info = SOSPeerInfoCopyAsApplication(old_pi, user_key, device_key, error);
+
+    require_action_quiet(fpi->peer_info, exit, fpi->peer_info = old_pi; old_pi = NULL);
+
+    success = true;
+
+exit:
+    CFReleaseSafe(old_pi);
+    CFReleaseSafe(device_key);
+    return success;
+}
+
+bool SOSFullPeerInfoUpgradeSignatures(SOSFullPeerInfoRef fpi, SecKeyRef user_key, CFErrorRef *error)
+{
+    bool success = false;
+    SOSPeerInfoRef old_pi = NULL;
+    
+    SecKeyRef device_key = SOSFullPeerInfoCopyDeviceKey(fpi, error);
+    require_quiet(device_key, exit);
+    
+    old_pi = fpi->peer_info;
+    fpi->peer_info = SOSPeerInfoUpgradeSignatures(NULL, user_key, device_key, old_pi, error);
+    
+    require_action_quiet(fpi->peer_info, exit, fpi->peer_info = old_pi; old_pi = NULL);
+    
+    success = true;
+    
+exit:
+    CFReleaseSafe(old_pi);
+    CFReleaseSafe(device_key);
+    return success;
+}
+
+//
+//
+//
+
+SOSPeerInfoRef SOSFullPeerInfoPromoteToRetiredAndCopy(SOSFullPeerInfoRef fpi, CFErrorRef *error)
+{
+    SOSPeerInfoRef peer_to_free = NULL;
+    SOSPeerInfoRef retired_peer = NULL;
+    SecKeyRef key = SOSFullPeerInfoCopyDeviceKey(fpi, error);
+    require_quiet(key, error_out);
+
+    retired_peer = SOSPeerInfoCreateRetirementTicket(NULL, key, fpi->peer_info, error);
+
+    require_quiet(retired_peer, error_out);
+
+    peer_to_free = fpi->peer_info;
+    fpi->peer_info = retired_peer;
+    CFRetainSafe(fpi->peer_info);
+
+error_out:
+    CFReleaseNull(key);
+    CFReleaseNull(peer_to_free);
+    return retired_peer;
+}
+
+
+
diff --git a/sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.h b/sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.h
new file mode 100644 (file)
index 0000000..87f34ef
--- /dev/null
@@ -0,0 +1,60 @@
+//
+//  SOSFullPeerInfo.h
+//  sec
+//
+//  Created by Mitch Adler on 10/26/12.
+//
+//
+
+#ifndef _SOSFULLPEERINFO_H_
+#define _SOSFULLPEERINFO_H_
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecKey.h>
+#include <CommonCrypto/CommonDigestSPI.h>
+#include <SecureObjectSync/SOSPeerInfo.h>
+
+__BEGIN_DECLS
+
+typedef struct __OpaqueSOSFullPeerInfo   *SOSFullPeerInfoRef;
+
+enum {
+    kSOSFullPeerVersion = 1,
+};
+
+SOSFullPeerInfoRef SOSFullPeerInfoCreate(CFAllocatorRef allocator, CFDictionaryRef gestalt, SecKeyRef signingKey, CFErrorRef *error);
+
+SOSFullPeerInfoRef SOSFullPeerInfoCreateCloudIdentity(CFAllocatorRef allocator, SOSPeerInfoRef peer, CFErrorRef* error);
+
+SOSPeerInfoRef SOSFullPeerInfoGetPeerInfo(SOSFullPeerInfoRef fullPeer);
+SecKeyRef      SOSFullPeerInfoCopyDeviceKey(SOSFullPeerInfoRef fullPeer, CFErrorRef* error);
+
+bool SOSFullPeerInfoPurgePersistentKey(SOSFullPeerInfoRef peer, CFErrorRef* error);
+
+SOSPeerInfoRef SOSFullPeerInfoPromoteToRetiredAndCopy(SOSFullPeerInfoRef peer, CFErrorRef *error);
+
+bool SOSFullPeerInfoValidate(SOSFullPeerInfoRef peer, CFErrorRef* error);
+
+bool SOSFullPeerInfoUpdateGestalt(SOSFullPeerInfoRef peer, CFDictionaryRef gestalt, CFErrorRef* error);
+
+bool SOSFullPeerInfoPromoteToApplication(SOSFullPeerInfoRef fpi, SecKeyRef user_key, CFErrorRef *error);
+
+bool SOSFullPeerInfoUpgradeSignatures(SOSFullPeerInfoRef fpi, SecKeyRef user_key, CFErrorRef *error);
+
+//
+// DER Import Export
+//
+SOSFullPeerInfoRef SOSFullPeerInfoCreateFromDER(CFAllocatorRef allocator, CFErrorRef* error,
+                                        const uint8_t** der_p, const uint8_t *der_end);
+
+SOSFullPeerInfoRef SOSFullPeerInfoCreateFromData(CFAllocatorRef allocator, CFDataRef fullPeerData, CFErrorRef *error);
+
+size_t      SOSFullPeerInfoGetDEREncodedSize(SOSFullPeerInfoRef peer, CFErrorRef *error);
+uint8_t*    SOSFullPeerInfoEncodeToDER(SOSFullPeerInfoRef peer, CFErrorRef* error,
+                                   const uint8_t* der, uint8_t* der_end);
+
+CFDataRef SOSFullPeerInfoCopyEncodedData(SOSFullPeerInfoRef peer, CFAllocatorRef allocator, CFErrorRef *error);
+
+__END_DECLS
+
+#endif
diff --git a/sec/SOSCircle/SecureObjectSync/SOSInternal.c b/sec/SOSCircle/SecureObjectSync/SOSInternal.c
new file mode 100644 (file)
index 0000000..7311df8
--- /dev/null
@@ -0,0 +1,160 @@
+//
+//  SOSInternal.c
+//  sec
+//
+//  Created by Mitch Adler on 7/18/12.
+//
+//
+
+#include <SecureObjectSync/SOSInternal.h>
+#include <SecureObjectSync/SOSCircle.h>
+#include <SecureObjectSync/SOSCloudCircle.h>
+#include <SecureObjectSync/SOSAccount.h>
+
+#include "utilities/SecCFError.h"
+#include "utilities/SecCFRelease.h"
+#include "utilities/SecCFWrappers.h"
+#include "utilities/iOSforOSX.h"
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <Security/SecKey.h>
+#include <Security/SecKeyPriv.h>
+#include <Security/SecItem.h>
+#include <securityd/SecDbItem.h> // For SecError
+#include "utilities/iOSforOSX.h"
+
+#include <Security/SecBase64.h>
+
+#include <AssertMacros.h>
+
+CFStringRef kSOSErrorDomain = CFSTR("com.apple.security.sos.error");
+
+bool SOSCreateError(CFIndex errorCode, CFStringRef descriptionString, CFErrorRef previousError, CFErrorRef *newError) {
+    SOSCreateErrorWithFormat(errorCode, previousError, newError, NULL, CFSTR("%@"), descriptionString);
+    return true;
+}
+
+bool SOSCreateErrorWithFormat(CFIndex errorCode, CFErrorRef previousError, CFErrorRef *newError,
+                              CFDictionaryRef formatOptions, CFStringRef format, ...) {
+    va_list va;
+    va_start(va, format);
+    bool res = SOSCreateErrorWithFormatAndArguments(errorCode, previousError, newError, formatOptions, format, va);
+    va_end(va);
+    return res;
+}
+
+bool SOSCreateErrorWithFormatAndArguments(CFIndex errorCode, CFErrorRef previousError, CFErrorRef *newError,
+                                          CFDictionaryRef formatOptions, CFStringRef format, va_list args)
+{
+    SecCFCreateErrorWithFormatAndArguments(errorCode, kSOSErrorDomain, previousError, newError, formatOptions, format, args);
+    return true;
+}
+
+
+//
+// Utility Functions
+//
+
+static OSStatus GenerateECPairImp(int keySize, CFBooleanRef permanent, SecKeyRef* public, SecKeyRef *full)
+{
+    static const CFStringRef sTempNameToUse = CFSTR("GenerateECPair Temporary Key - Shouldn't be live");
+
+    CFNumberRef signing_bitsize = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &keySize);
+
+    CFDictionaryRef keygen_parameters = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
+                                                                     kSecAttrKeyType,       kSecAttrKeyTypeEC,
+                                                                     kSecAttrKeySizeInBits, signing_bitsize,
+                                                                     kSecAttrIsPermanent,   permanent,
+                                                                     kSecAttrLabel,         sTempNameToUse,
+                                                                     NULL);
+    CFReleaseNull(signing_bitsize);
+    OSStatus result = SecKeyGeneratePair(keygen_parameters, public, full);
+    CFReleaseNull(keygen_parameters);
+
+    return result;
+}
+
+OSStatus GenerateECPair(int keySize, SecKeyRef* public, SecKeyRef *full)
+{
+    return GenerateECPairImp(keySize, kCFBooleanFalse, public, full);
+}
+
+OSStatus GeneratePermanentECPair(int keySize, SecKeyRef* public, SecKeyRef *full)
+{
+    return GenerateECPairImp(keySize, kCFBooleanTrue, public, full);
+}
+
+static CFStringRef SOSCircleCopyDescriptionFromData(CFDataRef data)
+{
+    CFErrorRef error;
+    CFStringRef result = NULL;
+
+    SOSCircleRef circle = SOSCircleCreateFromData(kCFAllocatorDefault, data, &error);
+
+    if (circle)
+        result = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@"), circle);
+
+    CFReleaseSafe(circle);
+
+    return result;
+}
+
+CFStringRef SOSChangesCopyDescription(CFDictionaryRef changes, bool is_sender)
+{
+    CFMutableStringRef string = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, CFSTR("<Changes: {\n"));
+
+    CFDictionaryForEach(changes, ^(const void *key, const void *value) {
+        CFStringRef value_description = NULL;
+        if (isString(key) && isData(value)) {
+            CFDataRef value_data = (CFDataRef) value;
+            switch (SOSKVSKeyGetKeyType(key)) {
+                case kCircleKey:
+                    value_description = SOSCircleCopyDescriptionFromData(value_data);
+                    break;
+                case kMessageKey:
+                    value_description = SOSMessageCopyDescription(value_data);
+                    break;
+                default:
+                    break;
+            }
+
+        }
+        CFStringAppendFormat(string, NULL, CFSTR("    '%@' %s %@\n"),
+                             key,
+                             is_sender ? "<=" : "=>",
+                             value_description ? value_description : value);
+        
+        CFReleaseNull(value_description);
+    });
+
+    CFStringAppendFormat(string, NULL, CFSTR("}"));
+
+    return string;
+}
+
+CFStringRef SOSCopyIDOfKey(SecKeyRef key, CFErrorRef *error)
+{
+    const struct ccdigest_info * di = ccsha1_di();
+    CFDataRef publicBytes = NULL;
+    CFStringRef result = NULL;
+
+    uint8_t digest[di->output_size];
+    char encoded[2 * di->output_size]; // Big enough for base64 encoding.
+
+    require_quiet(SecError(SecKeyCopyPublicBytes(key, &publicBytes), error, CFSTR("Failed to export public bytes %@"), key), fail);
+    
+    ccdigest(di, CFDataGetLength(publicBytes), CFDataGetBytePtr(publicBytes), digest);
+
+    size_t length = SecBase64Encode(digest, sizeof(digest), encoded, sizeof(encoded));
+    assert(length && length < sizeof(encoded));
+    if (length > 26)
+      length = 26;
+    encoded[length] = 0;
+    CFReleaseNull(publicBytes);
+    return CFStringCreateWithCString(kCFAllocatorDefault, encoded, kCFStringEncodingASCII);
+
+fail:
+    CFReleaseNull(publicBytes);
+    return result;
+}
diff --git a/sec/SOSCircle/SecureObjectSync/SOSInternal.h b/sec/SOSCircle/SecureObjectSync/SOSInternal.h
new file mode 100644 (file)
index 0000000..007280d
--- /dev/null
@@ -0,0 +1,87 @@
+//
+//  SOSInternal.h
+//  sec
+//
+//  Created by Mitch Adler on 7/18/12.
+//
+//
+
+#ifndef _SOSINTERNAL_H_
+#define _SOSINTERNAL_H_
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <Security/SecKey.h>
+
+#include <SecureObjectSync/SOSCloudCircle.h>
+
+#include <utilities/SecCFWrappers.h>
+
+__BEGIN_DECLS
+
+enum {
+    // Public errors are first (See SOSCloudCircle)
+
+    kSOSErrorFirstPrivateError = 1024,
+    
+    kSOSErrorAllocationFailure  = 1024,
+    kSOSErrorEncodeFailure      = 1025,
+    kSOSErrorNameMismatch       = 1026,
+    kSOSErrorSendFailure        = 1027,
+    kSOSErrorProcessingFailure  = 1028,
+    kSOSErrorDecodeFailure      = 1029,
+
+    kSOSErrorAlreadyPeer        = 1030,
+    kSOSErrorNotApplicant       = 1031,
+    kSOSErrorPeerNotFound       = 1032,
+
+    kSOSErrorNoKey              = 1033,
+    kSOSErrorBadKey             = 1034,
+    kSOSErrorBadFormat          = 1035,
+    kSOSErrorNoCircleName       = 1036,
+    kSOSErrorNoCircle           = 1037,
+    kSOSErrorBadSignature       = 1038,
+    kSOSErrorReplay             = 1039,
+
+    kSOSErrorUnexpectedType     = 1040,
+
+    kSOSErrorUnsupported        = 1041
+};
+
+bool SOSCreateError(CFIndex errorCode, CFStringRef descriptionString, CFErrorRef previousError, CFErrorRef *newError);
+
+bool SOSCreateErrorWithFormat(CFIndex errorCode, CFErrorRef previousError, CFErrorRef *newError,
+                              CFDictionaryRef formatOptions, CFStringRef formatString, ...)
+                        CF_FORMAT_FUNCTION(5,6);
+
+bool SOSCreateErrorWithFormatAndArguments(CFIndex errorCode, CFErrorRef previousError, CFErrorRef *newError,
+                                          CFDictionaryRef formatOptions, CFStringRef formatString, va_list args)
+                                CF_FORMAT_FUNCTION(5,0);
+
+
+static inline bool isSOSErrorCoded(CFErrorRef error, CFIndex sosErrorCode) {
+    return CFErrorGetCode(error) == sosErrorCode && CFEqualSafe(CFErrorGetDomain(error), kSOSErrorDomain);
+}
+
+
+//
+// Utility Functions
+//
+OSStatus GenerateECPair(int keySize, SecKeyRef* public, SecKeyRef *full);
+OSStatus GeneratePermanentECPair(int keySize, SecKeyRef* public, SecKeyRef *full);
+
+CFStringRef SOSChangesCopyDescription(CFDictionaryRef changes, bool is_sender);
+
+CFStringRef SOSCopyIDOfKey(SecKeyRef key, CFErrorRef *error);
+
+//
+// Der encoding accumulation
+//
+static inline bool accumulate_size(size_t *accumulator, size_t size) {
+    *accumulator += size;
+    return size != 0;
+}
+
+__END_DECLS
+
+#endif
diff --git a/sec/SOSCircle/SecureObjectSync/SOSPeer.c b/sec/SOSCircle/SecureObjectSync/SOSPeer.c
new file mode 100644 (file)
index 0000000..206b0a7
--- /dev/null
@@ -0,0 +1,517 @@
+/*
+ * Created by Michael Brouwer on 6/22/12.
+ * Copyright 2012 Apple Inc. All Rights Reserved.
+ */
+
+/*
+ * SOSPeer.c -  Implementation of a secure object syncing peer
+ */
+#include <SecureObjectSync/SOSPeer.h>
+#include <SecureObjectSync/SOSEngine.h>
+#include <SecureObjectSync/SOSFullPeerInfo.h>
+#include <SecureObjectSync/SOSPeerInfo.h>
+#include <SecureObjectSync/SOSCoder.h>
+#include <SecureObjectSync/SOSInternal.h>
+#include <utilities/SecCFRelease.h>
+#include <CommonCrypto/CommonDigest.h>
+#include <CommonCrypto/CommonDigestSPI.h>
+#include <utilities/SecCFError.h>
+#include <utilities/SecCFWrappers.h>
+#include <utilities/debugging.h>
+#include <utilities/SecFileLocations.h>
+#include <utilities/der_plist.h>
+#include <utilities/der_plist_internal.h>
+
+#include <utilities/SecDb.h>
+
+#include <securityd/SOSCloudCircleServer.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <stdlib.h>
+
+#include <AssertMacros.h>
+
+//
+//
+//
+static CFStringRef sErrorDomain = CFSTR("com.apple.security.sos.peer.error");
+
+static CFMutableDictionaryRef sPersistenceCache = NULL;
+static CFStringRef peerFile = CFSTR("PeerManifestCache.plist");
+
+static CFMutableDictionaryRef SOSPeerGetPersistenceCache(CFStringRef my_id)
+{
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        CFErrorRef localError = NULL;
+        CFMutableDictionaryRef peerDict = NULL;
+        CFDataRef dictAsData = SOSItemGet(kSOSPeerDataLabel, &localError);
+
+        if (dictAsData) {
+            der_decode_dictionary(kCFAllocatorDefault, kCFPropertyListMutableContainers, (CFDictionaryRef*)&peerDict, &localError,
+                                  CFDataGetBytePtr(dictAsData),
+                                  CFDataGetBytePtr(dictAsData) + CFDataGetLength(dictAsData));
+        }
+        
+        if (!isDictionary(peerDict)) {
+            CFReleaseNull(peerDict);
+            secnotice("peer", "Error finding persisted peer data %@, using empty", localError);
+            peerDict = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
+            CFReleaseNull(localError);
+        }
+        
+        if (CFDictionaryGetValue(peerDict, my_id) != NULL) {
+            CFMutableDictionaryRef mySubDictionary = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
+
+            CFDictionaryForEach(peerDict, ^(const void *key, const void *value) {
+                if (!isDictionary(value)) {
+                    CFDictionaryAddValue(mySubDictionary, key, value);
+                };
+            });
+            
+            CFDictionaryForEach(mySubDictionary, ^(const void *key, const void *value) {
+                CFDictionaryRemoveValue(peerDict, key);
+            });
+            
+            CFDictionaryAddValue(peerDict, my_id, mySubDictionary);
+        }
+        sPersistenceCache = peerDict;
+    });
+
+    return sPersistenceCache;
+}
+
+static void SOSPeerFlushPersistenceCache()
+{
+    if (!sPersistenceCache)
+        return;
+
+    CFErrorRef localError = NULL;
+    CFIndex size = der_sizeof_dictionary(sPersistenceCache, &localError);
+    CFMutableDataRef dataToStore = CFDataCreateMutableWithScratch(kCFAllocatorDefault, size);
+
+    if (size == 0) {
+        secerror("Error calculating size of persistence cache: %@", localError);
+        goto fail;
+    }
+
+    uint8_t *der = NULL;
+    if (CFDataGetBytePtr(dataToStore) != (der = der_encode_dictionary(sPersistenceCache, &localError,
+                                                                                         CFDataGetBytePtr(dataToStore),
+                                                                      CFDataGetMutableBytePtr(dataToStore) + CFDataGetLength(dataToStore)))) {
+        secerror("Error flattening peer cache: %@", localError);
+        secerror("ERROR flattening peer cache (%@): size=%zd %@ (%p %p)", sPersistenceCache, size, dataToStore, CFDataGetBytePtr(dataToStore), der);
+        goto fail;
+}
+
+    if (!SOSItemUpdateOrAdd(kSOSPeerDataLabel, kSecAttrAccessibleWhenUnlockedThisDeviceOnly, dataToStore, &localError)) {
+        secerror("Peer cache item save failed: %@", localError);
+        goto fail;
+    }
+
+fail:
+    CFReleaseNull(localError);
+    CFReleaseNull(dataToStore);
+}
+
+void SOSPeerPurge(SOSPeerRef peer) {
+    // TODO: Do we use this or some other end-around for PurgeAll?
+}
+
+void SOSPeerPurgeAllFor(CFStringRef my_id)
+{
+    if (!my_id)
+        return;
+    
+    CFMutableDictionaryRef persistenceCache = SOSPeerGetPersistenceCache(my_id);
+    
+    CFMutableDictionaryRef myPeerIDs = (CFMutableDictionaryRef) CFDictionaryGetValue(persistenceCache, my_id);
+    if (myPeerIDs)
+    {
+        CFRetainSafe(myPeerIDs);
+
+        CFDictionaryRemoveValue(myPeerIDs, my_id);
+
+        if (isDictionary(myPeerIDs)) {
+            CFDictionaryForEach(myPeerIDs, ^(const void *key, const void *value) {
+                // TODO: Inflate each and purge its keys.
+            });
+        }
+
+        CFReleaseNull(myPeerIDs);
+    }
+}
+
+static bool SOSPeerFindDataFor(CFTypeRef *peerData, CFStringRef my_id, CFStringRef peer_id, CFErrorRef *error)
+{
+    CFDictionaryRef table = (CFDictionaryRef) CFDictionaryGetValue(SOSPeerGetPersistenceCache(my_id), my_id);
+
+    *peerData = isDictionary(table) ? CFDictionaryGetValue(table, peer_id) : NULL;
+
+    return true;
+}
+
+static bool SOSPeerCopyPersistedManifest(SOSManifestRef* manifest, CFStringRef my_id, CFStringRef peer_id, CFErrorRef *error)
+{
+    CFTypeRef persistedObject = NULL;
+    
+    require(SOSPeerFindDataFor(&persistedObject, my_id, peer_id, error), fail);
+    
+    CFDataRef persistedData = NULL;
+    
+    if (isData(persistedObject))
+        persistedData = (CFDataRef)persistedObject;
+    else if (isArray(persistedObject) && (CFArrayGetCount((CFArrayRef) persistedObject) == 2))
+        persistedData = CFArrayGetValueAtIndex((CFArrayRef) persistedObject, 1);
+    
+    if (isData(persistedData)) {
+        SOSManifestRef createdManifest = SOSManifestCreateWithData(persistedData, error);
+
+        require(createdManifest, fail);
+
+        *manifest = createdManifest;
+}
+
+    return true;
+
+fail:
+    return false;
+}
+
+
+static bool SOSPeerCopyCoderData(CFDataRef *data, CFStringRef my_id, CFStringRef peer_id, CFErrorRef *error)
+{    
+    CFTypeRef persistedObject = NULL;
+    
+    require(SOSPeerFindDataFor(&persistedObject, my_id, peer_id, error), fail);
+    
+    CFDataRef persistedData = NULL;
+    
+    if (isArray(persistedObject))
+        persistedData = CFArrayGetValueAtIndex((CFArrayRef) persistedObject, 0);
+    
+    if (isData(persistedData)) {
+        CFRetainSafe(persistedData);
+        *data = persistedData;
+    }
+
+    return true;
+    
+fail:
+    return false;
+}
+
+
+static void SOSPeerPersistData(CFStringRef my_id, CFStringRef peer_id, SOSManifestRef manifest, CFDataRef coderData)
+{
+    CFMutableArrayRef data_array = CFArrayCreateMutableForCFTypes(0);
+       if (coderData) {
+    CFArrayAppendValue(data_array, coderData);
+    } else {
+        CFDataRef nullData = CFDataCreate(kCFAllocatorDefault, NULL, 0);
+        CFArrayAppendValue(data_array, nullData);
+        CFReleaseNull(nullData);
+       }
+
+    if (manifest) {
+        CFArrayAppendValue(data_array, SOSManifestGetData(manifest));
+    }
+
+    CFMutableDictionaryRef mySubDict = (CFMutableDictionaryRef) CFDictionaryGetValue(SOSPeerGetPersistenceCache(my_id), my_id);
+
+    if (mySubDict == NULL) {
+        mySubDict = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
+        CFDictionaryAddValue(SOSPeerGetPersistenceCache(my_id), my_id, mySubDict);
+    }
+
+    CFDictionarySetValue(mySubDict, peer_id, data_array);
+    
+    CFReleaseNull(data_array);
+
+    SOSPeerFlushPersistenceCache();
+}
+
+struct __OpaqueSOSPeer {
+    SOSPeerSendBlock send_block;
+    CFStringRef my_id;
+    CFStringRef peer_id;
+    CFIndex version;
+    SOSManifestRef manifest;
+    CFDataRef manifest_digest;
+    SOSCoderRef coder; // Currently will be used for OTR stuff.
+};
+
+static SOSPeerRef SOSPeerCreate_Internal(CFStringRef myPeerID, CFStringRef theirPeerID, CFIndex version, CFErrorRef *error,
+                                         SOSPeerSendBlock sendBlock) {
+    SOSPeerRef p = calloc(1, sizeof(struct __OpaqueSOSPeer));
+    p->send_block = sendBlock;
+    p->peer_id = theirPeerID;
+    CFRetainSafe(p->peer_id);
+
+    p->version = version;
+    
+    p->my_id = myPeerID;
+    CFRetainSafe(myPeerID);
+    
+    require(SOSPeerCopyPersistedManifest(&p->manifest, p->my_id, p->peer_id, error), fail);
+
+    return p;
+
+fail:
+    CFReleaseSafe(p->peer_id);
+    CFReleaseSafe(p->my_id);
+    free(p);
+    return NULL;
+}
+
+
+SOSPeerRef SOSPeerCreate(SOSFullPeerInfoRef myPeerInfo, SOSPeerInfoRef peerInfo,
+                         CFErrorRef *error, SOSPeerSendBlock sendBlock) {
+    
+    if (myPeerInfo == NULL) {
+        SOSCreateError(kSOSErrorUnsupported, CFSTR("Can't create peer without my peer info!"), NULL, error);
+        return NULL;
+    }
+    if (peerInfo == NULL) {
+        SOSCreateError(kSOSErrorUnsupported, CFSTR("Can't create peer without their peer info!"), NULL, error);
+        return NULL;
+    }
+
+    SOSPeerRef result = NULL;
+    SOSPeerRef p = SOSPeerCreate_Internal(SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(myPeerInfo)),
+                                          SOSPeerInfoGetPeerID(peerInfo),
+                                          SOSPeerInfoGetVersion(peerInfo),
+                                          error, sendBlock);
+    
+    require(p, fail);
+
+    CFDataRef coderData = NULL;
+    CFErrorRef coderError = NULL;
+
+    if (SOSPeerCopyCoderData(&coderData, p->my_id, p->peer_id, &coderError)
+        && coderData && CFDataGetLength(coderData) != 0) {
+        p->coder = SOSCoderCreateFromData(coderData, &coderError);
+    }
+
+    if (p->coder) {
+        secnotice("peer", "Old coder for me: %@ to peer: %@", p->my_id, p->peer_id);
+    } else {
+        secnotice("peer", "New coder for me: %@ to peer: %@ [Got error: %@]", p->my_id, p->peer_id, coderError);
+
+        p->coder = SOSCoderCreate(peerInfo, myPeerInfo, error);
+        
+        if (!p->coder) {
+            SOSPeerDispose(p);
+            p = NULL;
+        }
+    }
+
+    CFReleaseNull(coderData);
+    CFReleaseNull(coderError);
+
+    result = p;
+    p = NULL;
+    
+fail:
+    CFReleaseNull(p);
+    return result;
+}
+
+SOSPeerRef SOSPeerCreateSimple(CFStringRef peer_id, CFIndex version, CFErrorRef *error,
+                               SOSPeerSendBlock sendBlock) {
+    return SOSPeerCreate_Internal(CFSTR("FakeTestID"), peer_id, version, error, sendBlock);
+}
+
+void SOSPeerDispose(SOSPeerRef peer) {
+        CFErrorRef error = NULL;
+    CFDataRef coderData = NULL;
+    if (peer->coder) {
+        coderData = SOSCoderCopyDER(peer->coder, &error);
+        if (coderData == NULL) {
+                       secerror("Coder data failed to export (%@), zapping data for me: %@ to peer: %@", error, peer->my_id, peer->peer_id);
+               }
+               CFReleaseNull(error);
+    }
+        
+        if (!coderData) {
+            coderData = CFDataCreate(NULL, NULL, 0);
+        }
+        
+        SOSPeerPersistData(peer->my_id, peer->peer_id, peer->manifest, coderData);
+        
+        CFReleaseNull(coderData);
+    CFReleaseSafe(peer->peer_id);
+    CFReleaseSafe(peer->my_id);
+    if (peer->manifest)
+        SOSManifestDispose(peer->manifest);
+    CFReleaseSafe(peer->manifest_digest);
+    if (peer->coder)
+        SOSCoderDispose(peer->coder);
+
+    free(peer);
+}
+
+SOSPeerCoderStatus SOSPeerHandleMessage(SOSPeerRef peer, SOSEngineRef engine, CFDataRef codedMessage, CFErrorRef *error) {
+    CFMutableDataRef message = NULL;
+    SOSPeerCoderStatus coderStatus = kSOSPeerCoderDataReturned;
+
+    if (peer->coder) {
+        coderStatus = SOSCoderUnwrap(peer->coder, peer->send_block, codedMessage, &message, peer->peer_id, error);
+    } else {
+        message = CFDataCreateMutableCopy(kCFAllocatorDefault, 0, codedMessage);
+    }
+
+    switch(coderStatus) {
+        case kSOSPeerCoderDataReturned: {
+            CFStringRef description = SOSMessageCopyDescription(message);
+            secnotice("peer", "Got message from %@: %@", peer->peer_id, description);
+            CFReleaseSafe(description);
+            coderStatus = (SOSEngineHandleMessage(engine, peer, message, error)) ? coderStatus: kSOSPeerCoderFailure;
+            break;
+        }
+        case kSOSPeerCoderNegotiating:  // Sent message already in Unwrap.
+            secnotice("peer", "Negotiating with %@: Got: %@", peer->peer_id, codedMessage);
+            break;
+        case kSOSPeerCoderNegotiationCompleted:
+            if (SOSEngineSyncWithPeer(engine, peer, true, error)) {
+                secnotice("peer", "Negotiating with %@ completed: %@" , peer->peer_id, codedMessage);
+            } else {
+                secerror("Negotiating with %@ completed syncWithPeer: %@ calling syncWithAllPeers" , peer->peer_id, error ? *error : NULL);
+                // Clearing the manifest forces SOSEngineSyncWithPeer(engine, peer, false, error) to send a message no matter what.
+                // This is needed because that's what gets called by SOSPeerStartSync, which is what SOSCCSyncWithAllPeers triggers.
+                SOSPeerSetManifest(peer, NULL, NULL);
+                SOSCCSyncWithAllPeers();
+                coderStatus = kSOSPeerCoderFailure;
+            }
+            break;
+        case kSOSPeerCoderFailure:      // Probably restart coder
+            secnotice("peer", "Failed handling message from %@: Got: %@", peer->peer_id, codedMessage);
+            SOSCoderReset(peer->coder);
+            coderStatus = SOSCoderStart(peer->coder, peer->send_block, peer->peer_id, error);
+            break;
+        case kSOSPeerCoderStaleEvent:   // We received an event we have already processed in the past.
+            secnotice("peer", "StaleEvent from %@: Got: %@", peer->peer_id, codedMessage);
+            break;
+        default:
+            assert(false);
+            break;
+    }
+
+    CFReleaseNull(message);
+
+    return coderStatus;
+}
+
+SOSPeerCoderStatus SOSPeerStartSync(SOSPeerRef peer, SOSEngineRef engine, CFErrorRef *error) {
+    SOSPeerCoderStatus coderStatus = kSOSPeerCoderDataReturned;
+
+    if (peer->coder) {
+        coderStatus = SOSCoderStart(peer->coder, peer->send_block, peer->peer_id, error);
+    }
+
+    switch(coderStatus) {
+        case kSOSPeerCoderDataReturned:         // fallthrough
+        case kSOSPeerCoderNegotiationCompleted: // fallthrough
+            coderStatus = (SOSEngineSyncWithPeer(engine, peer, false, error)) ? coderStatus: kSOSPeerCoderFailure;
+            break;
+        case kSOSPeerCoderNegotiating: // Sent message already in Unwrap.
+            secnotice("peer", "Started sync with %@", peer->peer_id);
+            break;
+        case kSOSPeerCoderFailure: // Probably restart coder
+            break;
+        default:
+            assert(false);
+            break;
+    }
+    return coderStatus;
+}
+
+bool SOSPeerSendMessage(SOSPeerRef peer, CFDataRef message, CFErrorRef *error) {
+    CFMutableDataRef codedMessage = NULL;
+    CFStringRef description = SOSMessageCopyDescription(message);
+
+    SOSPeerCoderStatus coderStatus = kSOSPeerCoderDataReturned;
+
+    if (peer->coder) {
+        coderStatus = SOSCoderWrap(peer->coder, message, &codedMessage, peer->peer_id, error);
+    } else {
+        codedMessage = CFDataCreateMutableCopy(kCFAllocatorDefault, 0, message);
+    }
+    bool ok = true;
+    switch(coderStatus) {
+        case kSOSPeerCoderDataReturned:
+            secnotice("peer", "%@ message: %@", peer->peer_id, description);
+            peer->send_block(codedMessage, error);
+            break;
+        case kSOSPeerCoderNegotiating:
+            secnotice("peer", "%@ coder Negotiating - message not sent", peer->peer_id);
+            ok = SOSCreateErrorWithFormat(kSOSCCError, NULL, error, NULL, CFSTR("%@ failed to send message peer still negotiating"), peer->peer_id);
+            break;
+        default: // includes kSOSPeerCoderFailure
+            secerror("%@ coder failure - message not sent %@", peer->peer_id, error ? *error : NULL);
+            ok = false;
+            break;
+    }
+    CFReleaseSafe(description);
+    return ok;
+}
+
+bool SOSPeerCanSendMessage(SOSPeerRef peer) {
+    return (!peer->coder || SOSCoderCanWrap(peer->coder));
+}
+
+CFIndex SOSPeerGetVersion(SOSPeerRef peer) {
+    return peer->version;
+}
+
+CFStringRef SOSPeerGetID(SOSPeerRef peer) {
+    return peer->peer_id;
+}
+
+bool SOSPeersEqual(SOSPeerRef peerA, SOSPeerRef peerB)
+{
+    // Use mainly to see if peerB is actually this device (peerA)
+    return CFStringCompare(SOSPeerGetID(peerA), SOSPeerGetID(peerB), 0) == kCFCompareEqualTo;
+}
+
+bool SOSPeerSetManifest(SOSPeerRef peer, SOSManifestRef manifest, CFErrorRef *error __unused) {
+    CFRetainSafe(manifest);
+    CFReleaseSafe(peer->manifest);
+    peer->manifest = manifest;
+
+    CFReleaseNull(peer->manifest_digest);
+    return true;
+}
+
+SOSManifestRef SOSPeerCopyManifest(SOSPeerRef peer, CFErrorRef *error __unused) {
+    if (!peer->manifest) {
+        SecCFCreateError(kSOSPeerHasNoManifest, sErrorDomain, CFSTR("failed to find peer manifest - not yet implemented"), NULL, error);
+        return NULL;
+    }
+
+    CFRetain(peer->manifest);
+    return peer->manifest;
+}
+
+CFDataRef SOSPeerCopyManifestDigest(SOSPeerRef peer, CFErrorRef *error) {
+    if (peer->manifest_digest) {
+        CFRetain(peer->manifest_digest);
+    } else {
+        if (peer->manifest) {
+            CFMutableDataRef data = CFDataCreateMutable(NULL, CC_SHA1_DIGEST_LENGTH);
+            if (data) {
+                CFDataSetLength(data, CC_SHA1_DIGEST_LENGTH);
+                CCDigest(kCCDigestSHA1, SOSManifestGetBytePtr(peer->manifest), (CC_LONG)SOSManifestGetSize(peer->manifest), CFDataGetMutableBytePtr(data));
+                peer->manifest_digest = data;
+                CFRetain(peer->manifest_digest);
+            } else {
+                SecCFCreateError(kSOSPeerDigestFailure, sErrorDomain, CFSTR("failed to create digest"), NULL, error);
+            }
+        } else {
+            SecCFCreateError(kSOSPeerHasNoManifest, sErrorDomain, CFSTR("peer has no manifest, can't create digest"), NULL, error);
+        }
+    }
+
+    return peer->manifest_digest;
+}
diff --git a/sec/SOSCircle/SecureObjectSync/SOSPeer.h b/sec/SOSCircle/SecureObjectSync/SOSPeer.h
new file mode 100644 (file)
index 0000000..97c711e
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Created by Michael Brouwer on 6/22/12.
+ * Copyright 2012 Apple Inc. All Rights Reserved.
+ */
+
+/*!
+ @header SOSPeer
+ The functions provided in SOSPeer provide an interface to a
+ secure object syncing peer in a circle
+ */
+
+#ifndef _SOSPEER_H_
+#define _SOSPEER_H_
+
+#include <SecureObjectSync/SOSEngine.h>
+// #include <SecureObjectSync/SOSCoder.h>
+#include <SecureObjectSync/SOSFullPeerInfo.h>
+#include <SecureObjectSync/SOSPeerInfo.h>
+
+__BEGIN_DECLS
+
+enum {
+    kSOSPeerHasNoManifest = 1,
+    kSOSPeerDigestFailure = 2,
+};
+
+enum {
+    kSOSPeerCoderDataReturned = 0,
+    kSOSPeerCoderNegotiating = 1,
+    kSOSPeerCoderNegotiationCompleted = 2,
+    kSOSPeerCoderFailure = 3,
+    kSOSPeerCoderStaleEvent = 4,
+};
+typedef uint32_t SOSPeerCoderStatus;
+
+typedef bool (^SOSPeerSendBlock)(CFDataRef message, CFErrorRef *error);
+
+
+/* Constructor */
+SOSPeerRef SOSPeerCreate(SOSFullPeerInfoRef myPeerInfo, SOSPeerInfoRef peerInfo, CFErrorRef *error,
+                         SOSPeerSendBlock sendBlock);
+
+// Permanently forgetting stored information (e.g. keys on keychain)
+void SOSPeerPurge(SOSPeerRef);
+void SOSPeerPurgeAllFor(CFStringRef my_id);
+
+// Dispose of a peer when it's no longer needed.
+void SOSPeerDispose(SOSPeerRef peer);
+
+SOSPeerCoderStatus SOSPeerStartSync(SOSPeerRef peer, SOSEngineRef engine, CFErrorRef *error);
+
+// Handle an incoming message and pass it to the engine.
+SOSPeerCoderStatus SOSPeerHandleMessage(SOSPeerRef peer, SOSEngineRef engine, CFDataRef message, CFErrorRef *error);
+
+// Called by engine to send message to our tranport.
+bool SOSPeerSendMessage(SOSPeerRef peer, CFDataRef message, CFErrorRef *error);
+
+// Return true if the peer is ready to transmit data.
+bool SOSPeerCanSendMessage(SOSPeerRef peer);
+
+CFIndex SOSPeerGetVersion(SOSPeerRef peer);
+
+CFStringRef SOSPeerGetID(SOSPeerRef peer);
+bool SOSPeersEqual(SOSPeerRef peerA, SOSPeerRef peerB);
+
+bool SOSPeerSetManifest(SOSPeerRef peer, SOSManifestRef manifest, CFErrorRef *error);
+
+SOSManifestRef SOSPeerCopyManifest(SOSPeerRef peer, CFErrorRef *error);
+CFDataRef SOSPeerCopyManifestDigest(SOSPeerRef peer, CFErrorRef *error);
+
+/* For testing, doesn't OTR encode and uses static ID for self */
+SOSPeerRef SOSPeerCreateSimple(CFStringRef peer_id, CFIndex version, CFErrorRef *error,
+                               SOSPeerSendBlock sendBlock);
+
+__END_DECLS
+
+#endif /* !_SOSPEER_H_ */
diff --git a/sec/SOSCircle/SecureObjectSync/SOSPeerInfo.c b/sec/SOSCircle/SecureObjectSync/SOSPeerInfo.c
new file mode 100644 (file)
index 0000000..84c3e48
--- /dev/null
@@ -0,0 +1,785 @@
+//
+//  SOSPeerInfo.c
+//  sec
+//
+//  Created by Mitch Adler on 7/19/12.
+//
+//
+
+#include <AssertMacros.h>
+#include <TargetConditionals.h>
+
+#include <SecureObjectSync/SOSPeerInfo.h>
+#include <SecureObjectSync/SOSPeerInfoInternal.h>
+#include <SecureObjectSync/SOSCircle.h>
+
+#include <SecureObjectSync/SOSInternal.h>
+#include <ipc/securityd_client.h>
+
+#include "Imported/SecuritydXPC.h"
+
+#include <CoreFoundation/CFArray.h>
+#include <dispatch/dispatch.h>
+
+#include <stdlib.h>
+#include <assert.h>
+
+#include <utilities/SecCFWrappers.h>
+#include <utilities/SecCFRelease.h>
+#include <utilities/SecCFError.h>
+#include <utilities/SecXPCError.h>
+
+#include <utilities/der_plist.h>
+#include <utilities/der_plist_internal.h>
+#include <corecrypto/ccder.h>
+#include <utilities/der_date.h>
+
+#include <corecrypto/ccdigest.h>
+#include <corecrypto/ccsha2.h>
+
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreFoundation/CFDate.h>
+
+#include <xpc/xpc.h>
+
+#if TARGET_OS_IPHONE || TARGET_OS_EMBEDDED
+#include <MobileGestalt.h>
+#endif
+
+#include <Security/SecBase64.h>
+#include <Security/SecKeyPriv.h>
+#include <Security/SecOTR.h>
+
+#if 0//TARGET_OS_MAC // TODO: this function is the only one that causes secd to need to link against Security.framework on OSX
+
+__BEGIN_DECLS
+SecKeyRef _SecKeyCreateFromPublicData(CFAllocatorRef allocator, CFIndex algorithmID, CFDataRef publicBytes);
+__END_DECLS
+
+#endif  /* TARGET_OS_MAC */
+
+struct __OpaqueSOSPeerInfo {
+    CFRuntimeBase          _base;
+    
+    //
+    CFMutableDictionaryRef description;
+    CFDataRef              signature;
+    
+    // Cached data
+    CFDictionaryRef        gestalt;
+    CFStringRef            id;
+    CFIndex                version;
+};
+
+CFGiblisWithHashFor(SOSPeerInfo);
+
+CFStringRef kPIUserDefinedDeviceName = CFSTR("ComputerName");
+CFStringRef kPIDeviceModelName = CFSTR("ModelName");
+
+// Description Dictionary Entries
+static CFStringRef sPublicKeyKey = CFSTR("PublicSigningKey");
+static CFStringRef sGestaltKey   = CFSTR("DeviceGestalt");
+static CFStringRef sVersionKey   = CFSTR("ConflictVersion");
+static CFStringRef sCloudIdentityKey   = CFSTR("CloudIdentity");
+static CFStringRef sApplicationDate   = CFSTR("ApplicationDate");
+static CFStringRef sApplicationUsig   = CFSTR("ApplicationUsig");
+static CFStringRef sRetirementDate   = CFSTR("RetirementDate");
+
+// Peerinfo Entries
+CFStringRef kSOSPeerInfoDescriptionKey = CFSTR("SOSPeerInfoDescription");
+CFStringRef kSOSPeerInfoSignatureKey = CFSTR("SOSPeerInfoSignature");
+CFStringRef kSOSPeerInfoNameKey = CFSTR("SOSPeerInfoName");
+
+
+SecKeyRef SOSPeerInfoCopyPubKey(SOSPeerInfoRef peer) {
+    CFDataRef pubKeyBytes = CFDictionaryGetValue(peer->description, sPublicKeyKey);
+    CFAllocatorRef allocator = CFGetAllocator(peer);
+    SecKeyRef pubKey = SecKeyCreateFromPublicData(allocator, kSecECDSAAlgorithmID, pubKeyBytes);
+    return pubKey;
+}
+
+
+static bool SOSDescriptionHash(SOSPeerInfoRef peer, const struct ccdigest_info *di, void *hashresult, CFErrorRef *error) {
+    ccdigest_di_decl(di, ctx);
+    ccdigest_init(di, ctx);
+    void *ctx_p = ctx;
+    if(!SOSPeerInfoUpdateDigestWithDescription(peer, di, ctx_p, error)) return false;
+    ccdigest_final(di, ctx, hashresult);
+    return true;
+}
+
+
+#define SIGLEN 128
+static CFDataRef sosSignHash(SecKeyRef privkey, const struct ccdigest_info *di, uint8_t *hbuf) {
+    OSStatus stat;
+    size_t siglen = SIGLEN;
+    uint8_t sig[siglen];
+    if((stat = SecKeyRawSign(privkey, kSecPaddingNone, hbuf, di->output_size, sig, &siglen)) != 0) {
+        return NULL;
+    }
+    return CFDataCreate(NULL, sig, (CFIndex)siglen);
+}
+
+static bool sosVerifyHash(SecKeyRef pubkey, const struct ccdigest_info *di, uint8_t *hbuf, CFDataRef signature) {
+    return SecKeyRawVerify(pubkey, kSecPaddingNone, hbuf, di->output_size,
+                           CFDataGetBytePtr(signature), CFDataGetLength(signature)) == errSecSuccess;
+}
+
+static bool SOSPeerInfoSign(SecKeyRef privKey, SOSPeerInfoRef peer, CFErrorRef *error) {
+    bool status = false;
+    const struct ccdigest_info *di = ccsha256_di();
+    uint8_t hbuf[di->output_size];
+    CFDataRef newSignature = NULL;
+    
+    require_action_quiet(SOSDescriptionHash(peer, di, hbuf, error), fail,
+                         SOSCreateError(kSOSErrorUnexpectedType, CFSTR("Failed to hash description for peer"), NULL, error));
+    
+    newSignature = sosSignHash(privKey, di, hbuf);
+    require_action_quiet(newSignature, fail, SOSCreateError(kSOSErrorUnexpectedType, CFSTR("Failed to sign peerinfo for peer"), NULL, error));
+
+    CFReleaseNull(peer->signature);
+    peer->signature = newSignature;
+    newSignature = NULL;
+    status = true;
+
+fail:
+    CFReleaseNull(newSignature);
+    return status;
+}
+
+// Return true (1) if the signature verifies.
+static bool SOSPeerInfoVerify(SOSPeerInfoRef peer, CFErrorRef *error) {
+    bool result = false;
+    const struct ccdigest_info *di = ccsha256_di();
+    uint8_t hbuf[di->output_size];
+
+    SecKeyRef pubKey = SOSPeerInfoCopyPubKey(peer);
+    require_quiet(pubKey, error_out);
+
+    require_quiet(SOSDescriptionHash(peer, di, hbuf, error), error_out);
+    
+    result = sosVerifyHash(pubKey, di, hbuf, peer->signature);
+
+error_out:
+    CFReleaseNull(pubKey);
+    return result;
+}
+
+static SOSPeerInfoRef SOSPeerInfoCreate_Internal(CFAllocatorRef allocator, CFDictionaryRef gestalt, SecKeyRef signingKey, CFErrorRef* error, void (^ description_modifier)(CFMutableDictionaryRef description)) {
+    SOSPeerInfoRef pi = CFTypeAllocate(SOSPeerInfo, struct __OpaqueSOSPeerInfo, allocator);
+    pi->gestalt = gestalt;
+    CFRetain(pi->gestalt);
+    
+    pi->version = kSOSPeerVersion;
+
+    CFDataRef publicBytes = NULL;
+    CFNumberRef versionNumber = NULL;
+
+    SecKeyRef publicKey = SecKeyCreatePublicFromPrivate(signingKey);
+    if (publicKey == NULL) {
+        SOSCreateError(kSOSErrorBadKey, CFSTR("Unable to get public"), NULL, error);
+        CFReleaseNull(pi);
+        goto exit;
+    }
+
+    OSStatus result = SecKeyCopyPublicBytes(publicKey, &publicBytes);
+    
+    if (result != errSecSuccess) {
+        SOSCreateError(kSOSErrorBadKey, CFSTR("Failed to export public bytes"), NULL, error);
+        CFReleaseNull(pi);
+        goto exit;
+    }
+    
+    pi->signature = CFDataCreateMutable(allocator, 0);
+    
+    versionNumber = CFNumberCreateWithCFIndex(NULL, pi->version);
+    pi->description = CFDictionaryCreateMutableForCFTypesWith(allocator,
+                                                              sVersionKey,   versionNumber,
+                                                              sPublicKeyKey, publicBytes,
+                                                              sGestaltKey,   pi->gestalt,
+                                                              NULL);
+    description_modifier(pi->description);
+    
+    pi->id = SOSCopyIDOfKey(publicKey, error);
+    CFReleaseNull(publicKey);
+
+    require_quiet(pi->id, exit);
+
+    if (!SOSPeerInfoSign(signingKey, pi, error)) {
+        CFReleaseNull(pi);
+        goto exit;
+    }
+
+exit:
+    CFReleaseNull(versionNumber);
+    CFReleaseNull(publicBytes);
+    return pi;
+}
+
+SOSPeerInfoRef SOSPeerInfoCreate(CFAllocatorRef allocator, CFDictionaryRef gestalt, SecKeyRef signingKey, CFErrorRef* error) {
+    return SOSPeerInfoCreate_Internal(allocator, gestalt, signingKey, error, ^(CFMutableDictionaryRef description) {});
+}
+
+SOSPeerInfoRef SOSPeerInfoCreateCloudIdentity(CFAllocatorRef allocator, CFDictionaryRef gestalt, SecKeyRef signingKey, CFErrorRef* error) {
+    return SOSPeerInfoCreate_Internal(allocator, gestalt, signingKey, error, ^(CFMutableDictionaryRef description) {
+        CFDictionarySetValue(description, sCloudIdentityKey, kCFBooleanTrue);
+    });
+
+}
+
+
+SOSPeerInfoRef SOSPeerInfoCreateCopy(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, CFErrorRef* error) {
+    SOSPeerInfoRef pi = CFTypeAllocate(SOSPeerInfo, struct __OpaqueSOSPeerInfo, allocator);
+    
+    pi->description = CFDictionaryCreateMutableCopy(allocator, 0, toCopy->description);
+    pi->signature = CFDataCreateCopy(allocator, toCopy->signature);
+    
+    pi->gestalt = CFDictionaryCreateCopy(allocator, toCopy->gestalt);
+    pi->id = CFStringCreateCopy(allocator, toCopy->id);
+
+    pi->version = toCopy->version;
+
+    return pi;
+}
+
+SOSPeerInfoRef SOSPeerInfoCopyWithGestaltUpdate(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, CFDictionaryRef gestalt, SecKeyRef signingKey, CFErrorRef* error) {
+    SOSPeerInfoRef pi = SOSPeerInfoCreateCopy(allocator, toCopy, error);
+
+    CFRetainSafe(gestalt);
+    CFReleaseNull(pi->gestalt);
+    pi->gestalt = gestalt;
+
+    CFDictionarySetValue(pi->description, sGestaltKey, pi->gestalt);
+
+    SecKeyRef pub_key = SOSPeerInfoCopyPubKey(pi);
+   
+    pi->id = SOSCopyIDOfKey(pub_key, error);
+    require_quiet(pi->id, exit);
+
+    require_action_quiet(SOSPeerInfoSign(signingKey, pi, error), exit, CFReleaseNull(pi));
+
+exit:
+    CFReleaseNull(pub_key);
+    return pi;
+}
+
+SOSPeerInfoRef SOSPeerInfoCreateFromDER(CFAllocatorRef allocator, CFErrorRef* error,
+                                        const uint8_t** der_p, const uint8_t *der_end) {
+    SOSPeerInfoRef pi = CFTypeAllocate(SOSPeerInfo, struct __OpaqueSOSPeerInfo, allocator);
+    SecKeyRef pubKey = NULL;
+
+    const uint8_t *sequence_end;
+
+    CFPropertyListRef pl = NULL;
+    
+    pi->gestalt = NULL;
+    pi->version = 0; // TODO: Encode this in the DER
+    
+    *der_p = ccder_decode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, &sequence_end, *der_p, der_end);
+    *der_p = der_decode_plist(allocator, kCFPropertyListImmutable, &pl, error, *der_p, sequence_end);
+    *der_p = der_decode_data(allocator, kCFPropertyListImmutable, &pi->signature, error, *der_p, sequence_end);
+        
+    if (*der_p == NULL || *der_p != sequence_end) {
+        SOSCreateError(kSOSErrorBadFormat, CFSTR("Bad Format of Peer Info DER"), NULL, error);
+        goto fail;
+    }
+
+    if (CFGetTypeID(pl) != CFDictionaryGetTypeID()) {
+        CFStringRef description = CFCopyTypeIDDescription(CFGetTypeID(pl));
+        SOSCreateErrorWithFormat(kSOSErrorUnexpectedType, NULL, error, NULL,
+                                 CFSTR("Expected dictionary got %@"), description);
+        CFReleaseSafe(description);
+        goto fail;
+    }
+    
+    pi->description = (CFMutableDictionaryRef) pl;
+    CFRetain(pi->description);
+    CFReleaseNull(pl);
+    
+    CFNumberRef versionNumber = CFDictionaryGetValue(pi->description, sVersionKey);
+
+    if (versionNumber) {
+        CFNumberGetValue(versionNumber, kCFNumberCFIndexType, &pi->version);
+    }
+
+    CFDictionaryRef gestalt = CFDictionaryGetValue(pi->description, sGestaltKey);
+
+    if (!isDictionary(gestalt)) {
+        CFStringRef description = CFCopyTypeIDDescription(CFGetTypeID(pl));
+        SOSCreateErrorWithFormat(kSOSErrorUnexpectedType, NULL, error, NULL,
+                                 CFSTR("Expected dictionary got %@"), description);
+        CFReleaseSafe(description);
+        goto fail;
+    }
+
+    pi->gestalt = gestalt;
+    CFRetain(pi->gestalt);
+
+    pubKey = SOSPeerInfoCopyPubKey(pi);
+    require_quiet(pubKey, fail);
+
+    pi->id = SOSCopyIDOfKey(pubKey, error);
+    require_quiet(pi->id, fail);
+
+    if(!SOSPeerInfoVerify(pi, error)) {
+        SOSCreateErrorWithFormat(kSOSErrorBadSignature, NULL, error, NULL, CFSTR("Signature doesn't validate"));
+        if (error)
+            secerror("Can't validate PeerInfo: %@", *error);
+        goto fail;
+    }
+    CFReleaseNull(pubKey);
+    return pi;
+
+fail:
+    CFReleaseNull(pi);
+    CFReleaseNull(pl);
+    CFReleaseNull(pubKey);
+
+    return NULL;
+}
+
+SOSPeerInfoRef SOSPeerInfoCreateFromData(CFAllocatorRef allocator, CFErrorRef* error,
+                                        CFDataRef peerinfo_data) {
+    const uint8_t *der = CFDataGetBytePtr(peerinfo_data);
+    CFIndex len = CFDataGetLength(peerinfo_data);
+    return SOSPeerInfoCreateFromDER(NULL, error, &der, der+len);
+}
+
+static void SOSPeerInfoDestroy(CFTypeRef aObj) {
+    SOSPeerInfoRef pi = (SOSPeerInfoRef) aObj;
+    
+    if(!pi) return;
+    CFReleaseNull(pi->description);
+    CFReleaseNull(pi->signature);
+    CFReleaseNull(pi->gestalt);
+    CFReleaseNull(pi->id);
+}
+
+static Boolean SOSPeerInfoCompare(CFTypeRef lhs, CFTypeRef rhs) {
+    SOSPeerInfoRef lpeer = (SOSPeerInfoRef) lhs;
+    SOSPeerInfoRef rpeer = (SOSPeerInfoRef) rhs;
+    if(!lpeer || !rpeer) return false;
+    return CFEqualSafe(lpeer->description, rpeer->description) && CFEqualSafe(lpeer->signature, rpeer->signature);
+}
+
+
+CFComparisonResult SOSPeerInfoCompareByID(const void *val1, const void *val2, void *context) {
+       CFStringRef v1 = SOSPeerInfoGetPeerID((SOSPeerInfoRef) val1);
+       CFStringRef v2 = SOSPeerInfoGetPeerID((SOSPeerInfoRef) val2);
+    return CFStringCompare(v1, v2, 0);
+}
+
+static CFHashCode SOSPeerInfoHash(CFTypeRef cf) {
+    SOSPeerInfoRef peer = (SOSPeerInfoRef) cf;
+
+    return CFHash(peer->description) ^ CFHash(peer->signature);
+}
+
+static CFStringRef SOSPeerInfoCopyDescription(CFTypeRef aObj) {
+    SOSPeerInfoRef pi = (SOSPeerInfoRef) aObj;
+
+    return CFStringCreateWithFormat(NULL, NULL, CFSTR("<SOSPeerInfo@%p: Name:'%@'%s Type: '%@' ID:'%@'>"),
+                                    pi,
+                                    CFDictionaryGetValue(pi->gestalt, kPIUserDefinedDeviceName),
+                                    SOSPeerInfoIsRetirementTicket(pi) ? " [retired]" : "",
+                                    CFDictionaryGetValue(pi->gestalt, kPIDeviceModelName),
+                                    pi->id);
+}
+
+CFDictionaryRef SOSPeerInfoCopyPeerGestalt(SOSPeerInfoRef pi) {
+    CFRetain(pi->gestalt);
+    return pi->gestalt;
+}
+
+CFStringRef SOSPeerInfoGetPeerName(SOSPeerInfoRef peer) {
+    return SOSPeerInfoLookupGestaltValue(peer, kPIUserDefinedDeviceName);
+}
+
+CFStringRef SOSPeerInfoGetPeerDeviceType(SOSPeerInfoRef peer) {
+    return SOSPeerInfoLookupGestaltValue(peer, kPIDeviceModelName);
+}
+
+CFTypeRef SOSPeerInfoLookupGestaltValue(SOSPeerInfoRef pi, CFStringRef key) {
+    return CFDictionaryGetValue(pi->gestalt, key);
+}
+
+CFStringRef SOSPeerInfoGetPeerID(SOSPeerInfoRef pi) {
+    return pi->id;
+}
+
+CFIndex SOSPeerInfoGetVersion(SOSPeerInfoRef pi) {
+    // TODO: Encode this in the DER.
+    return pi->version;
+}
+
+bool SOSPeerInfoUpdateDigestWithPublicKeyBytes(SOSPeerInfoRef peer, const struct ccdigest_info *di,
+                                               ccdigest_ctx_t ctx, CFErrorRef *error) {
+    CFDataRef pubKeyBytes = CFDictionaryGetValue(peer->description, sPublicKeyKey);
+    
+    if(!pubKeyBytes) {
+        SOSCreateErrorWithFormat(kSOSErrorEncodeFailure, NULL, error, NULL, CFSTR("Digest failed – no public key"));
+        return false;
+    }
+    
+    ccdigest_update(di, ctx, CFDataGetLength(pubKeyBytes), CFDataGetBytePtr(pubKeyBytes));
+    
+    return true;
+}
+
+bool SOSPeerInfoUpdateDigestWithDescription(SOSPeerInfoRef peer, const struct ccdigest_info *di,
+                                            ccdigest_ctx_t ctx, CFErrorRef *error) {
+    size_t description_size = der_sizeof_plist(peer->description, error);
+    uint8_t data_begin[description_size];
+    uint8_t *data_end = data_begin + description_size;
+    uint8_t *encoded = der_encode_plist(peer->description, error, data_begin, data_end);
+    
+    if(!encoded) {
+        SOSCreateErrorWithFormat(kSOSErrorEncodeFailure, NULL, error, NULL, CFSTR("Description encode failed"));
+        return false;
+    }
+    
+    ccdigest_update(di, ctx, description_size, data_begin);
+    
+    return true;
+}
+
+
+static CFDataRef sosCreateDate() {
+    CFDateRef now = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent());
+    size_t bufsiz = der_sizeof_date(now, NULL);
+    uint8_t buf[bufsiz];
+    der_encode_date(now, NULL, buf, buf+bufsiz);
+    CFReleaseNull(now);
+    return CFDataCreate(NULL, buf, bufsiz);
+}
+
+static CFDateRef sosCreateCFDate(CFDataRef sosdate) {
+    CFDateRef date;
+    der_decode_date(NULL, 0, &date, NULL, CFDataGetBytePtr(sosdate),
+                    CFDataGetBytePtr(sosdate) + CFDataGetLength(sosdate));
+    return date;
+}
+
+static bool sospeer_application_hash(SOSPeerInfoRef pi, const struct ccdigest_info *di, uint8_t *hbuf) {
+    CFDataRef appdate = CFDictionaryGetValue(pi->description, sApplicationDate);
+    if(!appdate) return false;
+    ccdigest_di_decl(di, ctx);
+    ccdigest_init(di, ctx);
+    ccdigest_update(di, ctx, CFDataGetLength(appdate), CFDataGetBytePtr(appdate));
+    if (!SOSPeerInfoUpdateDigestWithPublicKeyBytes(pi, di, ctx, NULL)) return false;
+    ccdigest_final(di, ctx, hbuf);
+    return true;
+}
+
+SOSPeerInfoRef SOSPeerInfoCopyAsApplication(SOSPeerInfoRef original, SecKeyRef userkey, SecKeyRef peerkey, CFErrorRef *error) {
+    SOSPeerInfoRef result = NULL;
+    SOSPeerInfoRef pi = SOSPeerInfoCreateCopy(kCFAllocatorDefault, original, error);
+
+    const struct ccdigest_info *di = ccsha256_di();
+    uint8_t hbuf[di->output_size];
+    CFDataRef usersig = NULL;
+    
+    CFDataRef creationDate = sosCreateDate();
+    CFDictionarySetValue(pi->description, sApplicationDate, creationDate);
+    CFReleaseNull(creationDate);
+
+    // Create User Application Signature
+    require_action_quiet(sospeer_application_hash(pi, di, hbuf), fail,
+                         SOSCreateError(kSOSErrorUnexpectedType, CFSTR("Failed to create hash for peer applicant"), NULL, error));
+    
+    usersig = sosSignHash(userkey, di, hbuf);
+    require_action_quiet(usersig, fail,
+                        SOSCreateError(kSOSErrorUnexpectedType, CFSTR("Failed to sign public key hash for peer"), NULL, error));
+
+    CFDictionarySetValue(pi->description, sApplicationUsig, usersig);
+    
+    require_quiet(SOSPeerInfoSign(peerkey, pi, error), fail);
+
+    result = pi;
+    pi = NULL;
+
+fail:
+    CFReleaseNull(usersig);
+    CFReleaseNull(pi);
+    return result;
+}
+
+bool SOSPeerInfoApplicationVerify(SOSPeerInfoRef pi, SecKeyRef userkey, CFErrorRef *error) {
+    const struct ccdigest_info *di = ccsha256_di();
+    uint8_t hbuf[di->output_size];
+    bool result = false;
+
+    CFDataRef usig = CFDictionaryGetValue(pi->description, sApplicationUsig);
+    require_action_quiet(usig, exit,
+                         SOSCreateError(kSOSErrorUnexpectedType, CFSTR("Peer is not an applicant"), NULL, error));
+    // Verify User Application Signature
+    require_action_quiet(sospeer_application_hash(pi, di, hbuf), exit,
+                         SOSCreateError(kSOSErrorUnexpectedType, CFSTR("Failed to create hash for peer applicant"), NULL, error));
+    require_action_quiet(sosVerifyHash(userkey, di, hbuf, usig), exit,
+                         SOSCreateError(kSOSErrorUnexpectedType, CFSTR("user signature of public key hash fails to verify"), NULL, error));
+
+    result = SOSPeerInfoVerify(pi, error);
+
+exit:
+    return result;
+}
+
+
+static CF_RETURNS_RETAINED CFDateRef sosPeerInfoGetDate(SOSPeerInfoRef pi, CFStringRef entry) {
+    if(!pi) return NULL;
+    CFDataRef sosdate = CFDictionaryGetValue(pi->description, entry);
+    if(!sosdate) return NULL;
+    CFDateRef date = sosCreateCFDate(sosdate);
+    
+    return date;
+}
+
+CF_RETURNS_RETAINED CFDateRef SOSPeerInfoGetApplicationDate(SOSPeerInfoRef pi) {
+    return sosPeerInfoGetDate(pi, sApplicationDate);
+}
+
+CF_RETURNS_RETAINED CFDateRef SOSPeerInfoGetRetirementDate(SOSPeerInfoRef pi) {
+    return sosPeerInfoGetDate(pi, sRetirementDate);
+}
+
+
+size_t SOSPeerInfoGetDEREncodedSize(SOSPeerInfoRef peer, CFErrorRef *error) {
+    size_t plist_size = der_sizeof_plist(peer->description, error);
+    if (plist_size == 0)
+        return 0;
+    
+    size_t signature_size = der_sizeof_data(peer->signature, error);
+    if (signature_size == 0)
+        return 0;
+    
+    return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE,
+                        plist_size + signature_size);
+}
+
+uint8_t* SOSPeerInfoEncodeToDER(SOSPeerInfoRef peer, CFErrorRef* error, const uint8_t* der, uint8_t* der_end) {
+    return ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der,
+                                       der_encode_plist(peer->description, error, der,
+                                       der_encode_data(peer->signature, error, der, der_end)));
+}
+
+CFDataRef SOSPeerInfoCopyEncodedData(SOSPeerInfoRef peer, CFAllocatorRef allocator, CFErrorRef *error) {
+    size_t size = SOSPeerInfoGetDEREncodedSize(peer, error);
+    if (size == 0) return NULL;
+
+    uint8_t buffer[size];
+    uint8_t* start = SOSPeerInfoEncodeToDER(peer, error, buffer, buffer + sizeof(buffer));
+    CFDataRef result = CFDataCreate(kCFAllocatorDefault, start, size);
+    return result;
+}
+
+
+//
+// PeerInfoArray encoding decoding
+//
+
+CFMutableArrayRef SOSPeerInfoArrayCreateFromDER(CFAllocatorRef allocator, CFErrorRef* error,
+                                                const uint8_t** der_p, const uint8_t *der_end) {
+    CFMutableArrayRef pia = CFArrayCreateMutableForCFTypes(allocator);
+
+    const uint8_t *sequence_end;
+
+    *der_p = ccder_decode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, &sequence_end, *der_p, der_end);
+
+    require_action(*der_p, fail, SOSCreateError(kSOSErrorBadFormat, CFSTR("Bad Peer Info Array Sequence Header"), NULL, error));
+
+    while (sequence_end != *der_p) {
+        SOSPeerInfoRef pi = SOSPeerInfoCreateFromDER(allocator, error, der_p, sequence_end);
+
+        if (pi == NULL || *der_p == NULL) {
+            SOSCreateError(kSOSErrorBadFormat, CFSTR("Bad Peer Info Array DER"), (error != NULL ? *error : NULL), error);
+            CFReleaseNull(pi);
+            goto fail;
+        }
+
+        CFArrayAppendValue(pia, pi);
+        CFReleaseSafe(pi);
+    }
+
+    if (!pia)
+        *der_p = NULL;
+    return pia;
+
+fail:
+    CFReleaseNull(pia);
+    *der_p = NULL;
+    return NULL;
+}
+
+size_t SOSPeerInfoArrayGetDEREncodedSize(CFArrayRef pia, CFErrorRef *error) {
+    size_t array_size = 0;
+
+    for(CFIndex count = CFArrayGetCount(pia);
+        count > 0;
+        --count) {
+        SOSPeerInfoRef pi = (SOSPeerInfoRef) CFArrayGetValueAtIndex(pia, count - 1);
+
+        if (CFGetTypeID(pi) != SOSPeerInfoGetTypeID()) {
+            SOSCreateError(kSOSErrorUnexpectedType, CFSTR("Non SOSPeerInfo in array"), (error != NULL ? *error : NULL), error);
+            return 0;
+        }
+
+        size_t pi_size = SOSPeerInfoGetDEREncodedSize(pi, error);
+
+        if (pi_size == 0) {
+            SOSCreateError(kSOSErrorEncodeFailure, CFSTR("Bad DER size"), (error != NULL ? *error : NULL), error);
+            return 0;
+        }
+
+        array_size += pi_size;
+    }
+
+
+    return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE,
+                        array_size);
+}
+
+uint8_t* SOSPeerInfoArrayEncodeToDER(CFArrayRef pia, CFErrorRef* error, const uint8_t* der, uint8_t* der_end_param) {
+
+    uint8_t* const sequence_end = der_end_param;
+    __block uint8_t* der_end = der_end_param;
+
+    CFArrayForEachReverse(pia, ^(const void *value) {
+        SOSPeerInfoRef pi = (SOSPeerInfoRef) value;
+        if (CFGetTypeID(pi) != SOSPeerInfoGetTypeID()) {
+            SOSCreateError(kSOSErrorUnexpectedType, CFSTR("Non SOSPeerInfo in array"), NULL, error);
+            der_end = NULL; // Indicate error and continue.
+        }
+        if (der_end)
+            der_end = SOSPeerInfoEncodeToDER(pi, error, der, der_end);
+    });
+    
+    if (der_end == NULL)
+        return NULL;
+
+    return ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, sequence_end, der, der_end);
+}
+
+
+CFArrayRef CreateArrayOfPeerInfoWithXPCObject(xpc_object_t peerArray, CFErrorRef* error) {
+    if (!peerArray) {
+        SecCFCreateErrorWithFormat(kSecXPCErrorUnexpectedNull, sSecXPCErrorDomain, NULL, error, NULL, CFSTR("Unexpected Null Array to encode"));
+        return NULL;
+    }
+    
+    if (xpc_get_type(peerArray) != XPC_TYPE_DATA) {
+        SecCFCreateErrorWithFormat(kSecXPCErrorUnexpectedType, sSecXPCErrorDomain, NULL, error, NULL, CFSTR("Array of peer info not array, got %@"), peerArray);
+        return NULL;
+    }
+    
+    const uint8_t* der = xpc_data_get_bytes_ptr(peerArray);
+    const uint8_t* der_end = der + xpc_data_get_length(peerArray);
+    
+    return SOSPeerInfoArrayCreateFromDER(kCFAllocatorDefault, error, &der, der_end);
+}
+
+xpc_object_t CreateXPCObjectWithArrayOfPeerInfo(CFArrayRef array, CFErrorRef *error) {
+    size_t data_size = SOSPeerInfoArrayGetDEREncodedSize(array, error);
+    if (data_size == 0)
+        return NULL;
+    uint8_t *data = (uint8_t *)malloc(data_size);
+    if (!data) return NULL;
+    
+    xpc_object_t result = NULL;
+    if (SOSPeerInfoArrayEncodeToDER(array, error, data, data + data_size))
+        result = xpc_data_create(data, data_size);
+
+    free(data);
+    return result;
+}
+
+//
+// Gestalt helpers
+//
+
+CFStringRef SOSPeerGestaltGetName(CFDictionaryRef gestalt) {
+    CFStringRef name = SOSPeerGestaltGetAnswer(gestalt, kPIUserDefinedDeviceName);
+    return isString(name) ? name : NULL;
+}
+
+CFTypeRef SOSPeerGestaltGetAnswer(CFDictionaryRef gestalt, CFStringRef question) {
+    return gestalt ? CFDictionaryGetValue(gestalt, question) : NULL;
+}
+
+//
+// Peer Retirement
+//
+
+
+SOSPeerInfoRef SOSPeerInfoCreateRetirementTicket(CFAllocatorRef allocator, SecKeyRef privKey, SOSPeerInfoRef peer, CFErrorRef *error) {
+    // Copy PeerInfo
+    SOSPeerInfoRef pi = SOSPeerInfoCreateCopy(allocator, peer, error);
+
+    require(pi, fail);
+
+    // Fill out Resignation Date
+    CFDataRef resignationDate = sosCreateDate();
+    CFDictionaryAddValue(pi->description, sRetirementDate, resignationDate);
+    CFReleaseNull(resignationDate);
+
+    require(SOSPeerInfoSign(privKey, pi, error), fail);
+
+    return pi;
+
+fail:
+    CFReleaseNull(pi);
+    return NULL;
+}
+
+CFStringRef SOSPeerInfoInspectRetirementTicket(SOSPeerInfoRef pi, CFErrorRef *error) {
+    CFStringRef retval = NULL;
+    CFDateRef now = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent());
+    CFDateRef retirement = NULL;
+    
+    require_quiet(SOSPeerInfoVerify(pi, error), err);
+
+    retirement = sosCreateCFDate(CFDictionaryGetValue(pi->description, sRetirementDate));
+
+    require_action_quiet(retirement, err,
+                         SOSCreateError(kSOSErrorUnexpectedType, CFSTR("Peer is not retired"), NULL, error));
+
+    require_action_quiet(CFDateCompare(now, retirement, NULL) == kCFCompareGreaterThan, err,
+                         SOSCreateError(kSOSErrorUnexpectedType, CFSTR("Retirement date is after current date"), NULL, error));
+
+    retval = SOSPeerInfoGetPeerID(pi);
+
+err:
+    CFReleaseNull(now);
+    CFReleaseNull(retirement);
+    return retval;
+}
+
+bool SOSPeerInfoRetireRetirementTicket(size_t max_seconds, SOSPeerInfoRef pi) {
+    CFDateRef now = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent());
+    CFDateRef retirement = sosCreateCFDate(CFDictionaryGetValue(pi->description, sRetirementDate));
+    CFTimeInterval timediff = CFDateGetTimeIntervalSinceDate(now, retirement); // diff in seconds
+    CFReleaseNull(now);
+    CFReleaseNull(retirement);
+    if(timediff > (max_seconds)) return true;
+    return false;
+}
+
+bool SOSPeerInfoIsRetirementTicket(SOSPeerInfoRef pi) {
+    CFDataRef flag = CFDictionaryGetValue(pi->description, sRetirementDate);
+    return flag != NULL;
+}
+
+bool SOSPeerInfoIsCloudIdentity(SOSPeerInfoRef pi) {
+    CFTypeRef value = CFDictionaryGetValue(pi->description, sCloudIdentityKey);
+    return CFEqualSafe(value, kCFBooleanTrue);
+}
+
+SOSPeerInfoRef SOSPeerInfoUpgradeSignatures(CFAllocatorRef allocator, SecKeyRef privKey, SecKeyRef peerKey, SOSPeerInfoRef peer, CFErrorRef *error) {
+    SecKeyRef pubKey = SecKeyCreatePublicFromPrivate(privKey);
+    SOSPeerInfoRef retval = NULL;
+    
+    retval = SOSPeerInfoCopyAsApplication(peer, privKey, peerKey, error);
+    CFReleaseNull(pubKey);
+    return retval;
+}
+
diff --git a/sec/SOSCircle/SecureObjectSync/SOSPeerInfo.h b/sec/SOSCircle/SecureObjectSync/SOSPeerInfo.h
new file mode 100644 (file)
index 0000000..50ca02f
--- /dev/null
@@ -0,0 +1,127 @@
+//
+//  SOSPeerInfo.h
+//  sec
+//
+//  Created by Mitch Adler on 7/19/12.
+//
+//
+
+#ifndef _SOSPEERINFO_H_
+#define _SOSPEERINFO_H_
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecKey.h>
+#include <CommonCrypto/CommonDigestSPI.h>
+#include <corecrypto/ccdigest.h>
+#include <xpc/xpc.h>
+
+__BEGIN_DECLS
+
+typedef struct __OpaqueSOSPeerInfo   *SOSPeerInfoRef;
+
+enum {
+    kSOSPeerVersion = 1,
+};
+
+
+enum {
+    SOSPeerCmpPubKeyHash = 0,
+    SOSPeerCmpName = 1,
+};
+typedef uint32_t SOSPeerInfoCmpSelect;
+
+SOSPeerInfoRef SOSPeerInfoCreate(CFAllocatorRef allocator, CFDictionaryRef gestalt, SecKeyRef signingKey, CFErrorRef* error);
+
+SOSPeerInfoRef SOSPeerInfoCreateCloudIdentity(CFAllocatorRef allocator, CFDictionaryRef gestalt, SecKeyRef signingKey, CFErrorRef* error);
+
+SOSPeerInfoRef SOSPeerInfoCreateCopy(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, CFErrorRef* error);
+SOSPeerInfoRef SOSPeerInfoCopyWithGestaltUpdate(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, CFDictionaryRef gestalt, SecKeyRef signingKey, CFErrorRef* error);
+SOSPeerInfoRef SOSPeerInfoCopyAsApplication(SOSPeerInfoRef pi, SecKeyRef userkey, SecKeyRef peerkey, CFErrorRef *error);
+
+bool SOSPeerInfoUpdateDigestWithPublicKeyBytes(SOSPeerInfoRef peer, const struct ccdigest_info *di,
+                                               ccdigest_ctx_t ctx, CFErrorRef *error);
+bool SOSPeerInfoUpdateDigestWithDescription(SOSPeerInfoRef peer, const struct ccdigest_info *di,
+                                            ccdigest_ctx_t ctx, CFErrorRef *error);
+
+
+bool SOSPeerInfoApplicationVerify(SOSPeerInfoRef pi, SecKeyRef userkey, CFErrorRef *error);
+
+CF_RETURNS_RETAINED CFDateRef SOSPeerInfoGetApplicationDate(SOSPeerInfoRef pi);
+
+//
+// DER Import Export
+//
+SOSPeerInfoRef SOSPeerInfoCreateFromDER(CFAllocatorRef allocator, CFErrorRef* error,
+                                        const uint8_t** der_p, const uint8_t *der_end);
+
+SOSPeerInfoRef SOSPeerInfoCreateFromData(CFAllocatorRef allocator, CFErrorRef* error,
+                                         CFDataRef peerinfo_data);
+
+size_t      SOSPeerInfoGetDEREncodedSize(SOSPeerInfoRef peer, CFErrorRef *error);
+uint8_t*    SOSPeerInfoEncodeToDER(SOSPeerInfoRef peer, CFErrorRef* error,
+                                   const uint8_t* der, uint8_t* der_end);
+
+CFDataRef SOSPeerInfoCopyEncodedData(SOSPeerInfoRef peer, CFAllocatorRef allocator, CFErrorRef *error);
+
+//
+// Gestalt info about the peer. It was fetched by the implementation on the other side.
+// probably has what you're looking for..
+//
+CFTypeRef SOSPeerInfoLookupGestaltValue(SOSPeerInfoRef pi, CFStringRef key);
+CFDictionaryRef SOSPeerInfoCopyPeerGestalt(SOSPeerInfoRef pi);
+
+//
+// Syntactic Sugar for some commone ones, might get deprectated at this level.
+//
+CFStringRef SOSPeerInfoGetPeerName(SOSPeerInfoRef peer);
+CFStringRef SOSPeerInfoGetPeerDeviceType(SOSPeerInfoRef peer);
+
+
+// Stringified ID for this peer, not human readable.
+CFStringRef SOSPeerInfoGetPeerID(SOSPeerInfoRef peer);
+
+CFIndex SOSPeerInfoGetVersion(SOSPeerInfoRef peer);
+
+
+
+//
+// Peer Info Arrays
+//
+
+CFMutableArrayRef SOSPeerInfoArrayCreateFromDER(CFAllocatorRef allocator, CFErrorRef* error,
+                                                const uint8_t** der_p, const uint8_t *der_end);
+size_t SOSPeerInfoArrayGetDEREncodedSize(CFArrayRef pia, CFErrorRef *error);
+uint8_t* SOSPeerInfoArrayEncodeToDER(CFArrayRef pia, CFErrorRef* error, const uint8_t* der, uint8_t* der_end);
+
+CFArrayRef CreateArrayOfPeerInfoWithXPCObject(xpc_object_t peerArray, CFErrorRef* error);
+xpc_object_t CreateXPCObjectWithArrayOfPeerInfo(CFArrayRef array, CFErrorRef *error);
+
+//
+// Peer Info Gestalt Helpers
+//
+CFStringRef SOSPeerGestaltGetName(CFDictionaryRef gestalt);
+
+// These are Mobile Gestalt questions. Not all Gestalt questions are carried.
+CFTypeRef SOSPeerGestaltGetAnswer(CFDictionaryRef gestalt, CFStringRef question);
+
+SecKeyRef SOSPeerInfoCopyPubKey(SOSPeerInfoRef peer);
+
+CFComparisonResult SOSPeerInfoCompareByID(const void *val1, const void *val2, void *context);
+
+SOSPeerInfoRef SOSPeerInfoCreateRetirementTicket(CFAllocatorRef allocator, SecKeyRef privKey, SOSPeerInfoRef peer, CFErrorRef *error);
+
+CFStringRef SOSPeerInfoInspectRetirementTicket(SOSPeerInfoRef pi, CFErrorRef *error);
+
+bool SOSPeerInfoRetireRetirementTicket(size_t max_days, SOSPeerInfoRef pi);
+
+CF_RETURNS_RETAINED CFDateRef SOSPeerInfoGetRetirementDate(SOSPeerInfoRef pi);
+
+bool SOSPeerInfoIsRetirementTicket(SOSPeerInfoRef pi);
+
+bool SOSPeerInfoIsCloudIdentity(SOSPeerInfoRef pi);
+
+SOSPeerInfoRef SOSPeerInfoUpgradeSignatures(CFAllocatorRef allocator, SecKeyRef privKey, SecKeyRef perKey, SOSPeerInfoRef peer, CFErrorRef *error);
+
+__END_DECLS
+
+#endif
diff --git a/sec/SOSCircle/SecureObjectSync/SOSPeerInfoInternal.h b/sec/SOSCircle/SecureObjectSync/SOSPeerInfoInternal.h
new file mode 100644 (file)
index 0000000..8ee1650
--- /dev/null
@@ -0,0 +1,16 @@
+//
+//  SOSPeerInfoInternal.h
+//  sec
+//
+//  Created by Richard Murphy on 6/24/13.
+//
+//
+
+#ifndef sec_SOSPeerInfoInternal_h
+#define sec_SOSPeerInfoInternal_h
+
+CFStringRef kPIUserDefinedDeviceName;
+CFStringRef kPIDeviceModelName;
+
+
+#endif
diff --git a/sec/SOSCircle/SecureObjectSync/SOSTransport.c b/sec/SOSCircle/SecureObjectSync/SOSTransport.c
new file mode 100644 (file)
index 0000000..9126a19
--- /dev/null
@@ -0,0 +1,329 @@
+/*
+ * Created by Michael Brouwer on 2/14/12.
+ * Copyright 2012 Apple Inc. All Rights Reserved.
+ */
+
+/*
+ * SOSTransport.c -  Implementation of the secure object syncing transport
+ */
+
+#include <SecureObjectSync/SOSTransport.h>
+#include <utilities/SecCFError.h>
+#include <utilities/SecCFWrappers.h>
+#include <dispatch/dispatch.h>
+#include <stdlib.h>
+
+static CFStringRef sErrorDomain = CFSTR("com.apple.security.sos.transport.error");
+
+/* SOSDigestVector code. */
+
+#define VECTOR_GROW(vector, count, capacity) \
+    do { \
+    if ((count) > capacity) { \
+        capacity = ((capacity) + 16) * 3 / 2; \
+        if (capacity < (count)) \
+            capacity = (count); \
+        vector = realloc((vector), sizeof(*(vector)) * capacity); \
+    } \
+} while (0)
+
+static void SOSDigestVectorEnsureCapacity(struct SOSDigestVector *dv, size_t count) {
+       VECTOR_GROW(dv->digest, count, dv->capacity);
+}
+
+void SOSDigestVectorReplaceAtIndex(struct SOSDigestVector *dv, size_t ix, const uint8_t *digest)
+{
+       SOSDigestVectorEnsureCapacity(dv, ix + 1);
+       memcpy(dv->digest[ix], digest, SOSDigestSize);
+       dv->is_sorted = false;
+}
+
+static void SOSDigestVectorAppendOrdered(struct SOSDigestVector *dv, const uint8_t *digest)
+{
+       SOSDigestVectorEnsureCapacity(dv, dv->count + 1);
+       memcpy(dv->digest[dv->count++], digest, SOSDigestSize);
+}
+
+void SOSDigestVectorAppend(struct SOSDigestVector *dv, const uint8_t *digest)
+{
+    SOSDigestVectorAppendOrdered(dv, digest);
+       dv->is_sorted = false;
+}
+
+static int SOSDigestCompare(const void *a, const void *b)
+{
+       return memcmp(a, b, SOSDigestSize);
+}
+
+void SOSDigestVectorSort(struct SOSDigestVector *dv)
+{
+       qsort(dv->digest, dv->count, sizeof(*dv->digest), SOSDigestCompare);
+       dv->is_sorted = true;
+}
+
+bool SOSDigestVectorContains(struct SOSDigestVector *dv, const uint8_t *digest)
+{
+    return SOSDigestVectorIndexOf(dv, digest) != (size_t)-1;
+}
+
+size_t SOSDigestVectorIndexOf(struct SOSDigestVector *dv, const uint8_t *digest)
+{
+       if (!dv->is_sorted)
+               SOSDigestVectorSort(dv);
+    const void *pos = bsearch(digest, dv->digest, dv->count, sizeof(*dv->digest), SOSDigestCompare);
+    return pos ? ((size_t)(pos - (void *)dv->digest)) / SOSDigestSize : ((size_t)-1);
+}
+
+void SOSDigestVectorFree(struct SOSDigestVector *dv)
+{
+       free(dv->digest);
+       dv->digest = NULL;
+       dv->count = 0;
+       dv->capacity = 0;
+       dv->is_sorted = false;
+}
+
+void SOSDigestVectorApply(struct SOSDigestVector *dv,
+                          void *context, SOSDigestVectorApplyFunc func)
+{
+       if (!dv->is_sorted)
+               SOSDigestVectorSort(dv);
+
+       for (size_t ix = 0; ix < dv->count; ++ix) {
+               func(context, dv->digest[ix]);
+       }
+}
+
+static void SOSDigestVectorAppendMultiple(struct SOSDigestVector *dv,
+                                          size_t count, const uint8_t *digests) {
+    if (count) {
+        SOSDigestVectorEnsureCapacity(dv, dv->count + count);
+        memcpy(dv->digest[dv->count], digests, count * SOSDigestSize);
+        dv->count += count;
+    }
+}
+
+void SOSDigestVectorDiff(struct SOSDigestVector *dv1, struct SOSDigestVector *dv2,
+                         struct SOSDigestVector *dv1_2, struct SOSDigestVector *dv2_1)
+{
+    /* dv1_2 and dv2_1 should be empty to start. */
+    assert(dv1_2->count == 0);
+    assert(dv2_1->count == 0);
+
+       if (!dv1->is_sorted)
+               SOSDigestVectorSort(dv1);
+       if (!dv2->is_sorted)
+               SOSDigestVectorSort(dv2);
+
+    size_t i1 = 0, i2 = 0;
+    while (i1 < dv1->count && i2 < dv2->count) {
+        int delta = SOSDigestCompare(dv1->digest[i1], dv2->digest[i2]);
+        if (delta == 0) {
+            ++i1, ++i2;
+        } else if (delta < 0) {
+            SOSDigestVectorAppendOrdered(dv1_2, dv1->digest[i1++]);
+        } else {
+            SOSDigestVectorAppendOrdered(dv2_1, dv2->digest[i2++]);
+        }
+    }
+    SOSDigestVectorAppendMultiple(dv1_2, dv1->count - i1, dv1->digest[i1]);
+    SOSDigestVectorAppendMultiple(dv2_1, dv2->count - i2, dv2->digest[i2]);
+
+    dv1_2->is_sorted = true;
+    dv2_1->is_sorted = true;
+}
+
+bool SOSDigestVectorPatch(struct SOSDigestVector *base, struct SOSDigestVector *removals,
+                          struct SOSDigestVector *additions, struct SOSDigestVector *dv,
+                          CFErrorRef *error)
+{
+    size_t base_ix = 0, removals_ix = 0, additions_ix = 0;
+       if (!base->is_sorted)
+               SOSDigestVectorSort(base);
+       if (!removals->is_sorted)
+               SOSDigestVectorSort(removals);
+       if (!additions->is_sorted)
+               SOSDigestVectorSort(additions);
+
+    assert(dv->count == 0);
+    SOSDigestVectorEnsureCapacity(dv, base->count - removals->count + additions->count);
+    dv->is_sorted = true;
+
+    while (base_ix < base->count) {
+        const uint8_t *d = base->digest[base_ix];
+        if (additions_ix < additions->count && SOSDigestCompare(d, additions->digest[additions_ix]) > 0) {
+            SOSDigestVectorAppendOrdered(dv, additions->digest[additions_ix++]);
+        } else if (removals_ix < removals->count && SOSDigestCompare(d, removals->digest[removals_ix]) == 0) {
+            base_ix++;
+            removals_ix++;
+        } else {
+            SOSDigestVectorAppendOrdered(dv, base->digest[base_ix++]);
+        }
+    }
+
+    if (removals_ix != removals->count) {
+        SecCFCreateErrorWithFormat(1, sErrorDomain, NULL, error, NULL, CFSTR("%lu extra removals left"), removals->count - removals_ix);
+        goto errOut;
+    }
+
+    while (additions_ix < additions->count) {
+        if (dv->count > 0 && SOSDigestCompare(dv->digest[dv->count - 1], additions->digest[additions_ix]) >= 0) {
+            SecCFCreateErrorWithFormat(1, sErrorDomain, NULL, error, NULL, CFSTR("unordered addition (%lu left)"), additions->count - additions_ix);
+            goto errOut;
+        }
+        SOSDigestVectorAppendOrdered(dv, additions->digest[additions_ix++]);
+    }
+
+    return true;
+errOut:
+    return false;
+}
+
+
+
+/* SOSManifest implementation. */
+struct __OpaqueSOSManifest {
+};
+
+SOSManifestRef SOSManifestCreateWithBytes(const uint8_t *bytes, size_t len,
+                                          CFErrorRef *error) {
+    SOSManifestRef manifest = (SOSManifestRef)CFDataCreate(NULL, bytes, (CFIndex)len);
+    if (!manifest)
+        SecCFCreateErrorWithFormat(kSOSManifestCreateError, sErrorDomain, NULL, error, NULL, CFSTR("Failed to create manifest"));
+
+    return manifest;
+}
+
+SOSManifestRef SOSManifestCreateWithData(CFDataRef data, CFErrorRef *error)
+{
+    SOSManifestRef manifest = NULL;
+
+    if (data)
+        manifest = (SOSManifestRef)CFDataCreateCopy(kCFAllocatorDefault, data);
+    else
+        manifest = (SOSManifestRef)CFDataCreate(kCFAllocatorDefault, NULL, 0);
+
+    if (!manifest)
+        SecCFCreateErrorWithFormat(kSOSManifestCreateError, sErrorDomain, NULL, error, NULL, CFSTR("Failed to create manifest"));
+
+    return manifest;
+}
+
+void SOSManifestDispose(SOSManifestRef m) {
+    CFRelease(m);
+}
+
+size_t SOSManifestGetSize(SOSManifestRef m) {
+    return (size_t)CFDataGetLength((CFDataRef)m);
+}
+
+size_t SOSManifestGetCount(SOSManifestRef m) {
+    return SOSManifestGetSize(m) / SOSDigestSize;
+}
+
+const uint8_t *SOSManifestGetBytePtr(SOSManifestRef m) {
+    return CFDataGetBytePtr((CFDataRef)m);
+}
+
+CFDataRef SOSManifestGetData(SOSManifestRef m) {
+    return (CFDataRef)m;
+}
+
+
+bool SOSManifestDiff(SOSManifestRef a, SOSManifestRef b,
+                     SOSManifestRef *a_minus_b, SOSManifestRef *b_minus_a,
+                     CFErrorRef *error) {
+    bool result = true;
+    struct SOSDigestVector dva = SOSDigestVectorInit,
+                           dvb = SOSDigestVectorInit,
+                           dvab = SOSDigestVectorInit,
+                           dvba = SOSDigestVectorInit;
+    SOSDigestVectorAppendMultiple(&dva, SOSManifestGetCount(a), SOSManifestGetBytePtr(a));
+    SOSDigestVectorAppendMultiple(&dvb, SOSManifestGetCount(b), SOSManifestGetBytePtr(b));
+    SOSDigestVectorDiff(&dva, &dvb, &dvab, &dvba);
+    SOSDigestVectorFree(&dva);
+    SOSDigestVectorFree(&dvb);
+
+    if (a_minus_b) {
+        *a_minus_b = SOSManifestCreateWithBytes((const uint8_t *)dvab.digest, dvab.count * SOSDigestSize, error);
+        if (!*a_minus_b)
+            result = false;
+    }
+
+    if (b_minus_a) {
+        *b_minus_a = SOSManifestCreateWithBytes((const uint8_t *)dvba.digest, dvba.count * SOSDigestSize, error);
+        if (!*b_minus_a)
+            result = false;
+    }
+
+    SOSDigestVectorFree(&dvab);
+    SOSDigestVectorFree(&dvba);
+
+    return result;
+}
+
+SOSManifestRef SOSManifestCreateWithPatch(SOSManifestRef base,
+                                          SOSManifestRef removals,
+                                          SOSManifestRef additions,
+                                          CFErrorRef *error) {
+    struct SOSDigestVector dvbase = SOSDigestVectorInit,
+                           dvresult = SOSDigestVectorInit,
+                           dvremovals = SOSDigestVectorInit,
+                           dvadditions = SOSDigestVectorInit;
+    dvbase.is_sorted = dvresult.is_sorted = dvremovals.is_sorted = dvadditions.is_sorted = true;
+    SOSDigestVectorAppendMultiple(&dvbase, SOSManifestGetCount(base), SOSManifestGetBytePtr(base));
+    SOSDigestVectorAppendMultiple(&dvremovals, SOSManifestGetCount(removals), SOSManifestGetBytePtr(removals));
+    SOSDigestVectorAppendMultiple(&dvadditions, SOSManifestGetCount(additions), SOSManifestGetBytePtr(additions));
+    SOSManifestRef result;
+    if (SOSDigestVectorPatch(&dvbase, &dvremovals, &dvadditions, &dvresult, error)) {
+        result = SOSManifestCreateWithBytes((const uint8_t *)dvresult.digest, dvresult.count * SOSDigestSize, error);
+    } else {
+        result = NULL;
+    }
+    SOSDigestVectorFree(&dvbase);
+    SOSDigestVectorFree(&dvresult);
+    SOSDigestVectorFree(&dvremovals);
+    SOSDigestVectorFree(&dvadditions);
+    return result;
+}
+
+void SOSManifestForEach(SOSManifestRef m, void(^block)(CFDataRef e)) {
+    CFDataRef e;
+    const uint8_t *p, *q;
+    for (p = SOSManifestGetBytePtr(m), q = p + SOSManifestGetSize(m);
+         p + SOSDigestSize <= q; p += SOSDigestSize) {
+        e = CFDataCreateWithBytesNoCopy(0, p, SOSDigestSize, kCFAllocatorNull);
+        if (e) {
+            block(e);
+            CFRelease(e);
+        }
+    }
+}
+
+CFStringRef SOSManifestCopyDescription(SOSManifestRef m) {
+    CFMutableStringRef desc = CFStringCreateMutable(0, 0);
+    CFStringAppend(desc, CFSTR("<Manifest"));
+    SOSManifestForEach(m, ^(CFDataRef e) {
+        CFStringAppend(desc, CFSTR(" "));
+        const uint8_t *d = CFDataGetBytePtr(e);
+        CFStringAppendFormat(desc, 0, CFSTR("%02X%02X%02X%02X"), d[0], d[1], d[2], d[3]);
+    });
+    CFStringAppend(desc, CFSTR(">"));
+
+    return desc;
+}
+
+#if 0
+SOSObjectRef SOSManifestGetObject(SOSManifestRef m, SOSObjectID k) {
+    return NULL;
+}
+
+void SOSManifestPutObject(SOSManifestRef m, SOSObjectID k, SOSObjectRef v) {
+
+}
+
+
+SOSManifestRef SOSManifestCreateSparse(void *get_ctx, SOSManifestGetF get_f) {
+    return NULL;
+}
+#endif
diff --git a/sec/SOSCircle/SecureObjectSync/SOSTransport.h b/sec/SOSCircle/SecureObjectSync/SOSTransport.h
new file mode 100644 (file)
index 0000000..7cbe8ac
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Created by Michael Brouwer on 2/14/12.
+ * Copyright 2012 Apple Inc. All Rights Reserved.
+ */
+
+/*!
+ @header SOSTransport
+ The functions provided in SOSTransport.h provide an interface to the
+ secure object syncing transport
+ */
+
+#ifndef _SOSTRANSPORT_H_
+#define _SOSTRANSPORT_H_
+
+#include <corecrypto/ccsha1.h>
+#include <CoreFoundation/CFData.h>
+#include <CoreFoundation/CFError.h>
+
+__BEGIN_DECLS
+
+enum {
+    kSOSManifestUnsortedError = 1,
+    kSOSManifestCreateError = 2,
+};
+
+
+/* SOSTransport. */
+
+/* SOSTransport protocol (not opaque). */
+typedef struct SOSTransport *SOSTransportRef;
+
+struct SOSTransport {
+    bool (*send)(SOSTransportRef transport, CFDataRef message);
+};
+
+/* Return the singleton cloud transport instance. */
+SOSTransportRef SOSTransportCopyCloudTransport(void);
+
+#define SOSDigestSize ((size_t)CCSHA1_OUTPUT_SIZE)
+
+#define SOSDigestVectorInit { .digest = NULL, .count = 0, .capacity = 0, .is_sorted = false }
+
+struct SOSDigestVector {
+    uint8_t (*digest)[SOSDigestSize];
+    size_t count;
+    size_t capacity;
+    bool is_sorted;
+};
+
+/* SOSDigestVector. */
+void SOSDigestVectorAppend(struct SOSDigestVector *dv, const uint8_t *digest);
+void SOSDigestVectorSort(struct SOSDigestVector *dv);
+size_t SOSDigestVectorIndexOf(struct SOSDigestVector *dv, const uint8_t *digest);
+bool SOSDigestVectorContains(struct SOSDigestVector *dv, const uint8_t *digest);
+void SOSDigestVectorReplaceAtIndex(struct SOSDigestVector *dv, size_t ix, const uint8_t *digest);
+void SOSDigestVectorFree(struct SOSDigestVector *dv);
+
+typedef void (*SOSDigestVectorApplyFunc)(void *context, const uint8_t digest[SOSDigestSize]);
+void SOSDigestVectorApply(struct SOSDigestVector *dv,
+                          void *context, SOSDigestVectorApplyFunc func);
+void SOSDigestVectorDiff(struct SOSDigestVector *dv1, struct SOSDigestVector *dv2,
+                         struct SOSDigestVector *dv1_2, struct SOSDigestVector *dv2_1);
+bool SOSDigestVectorPatch(struct SOSDigestVector *base, struct SOSDigestVector *removals,
+                          struct SOSDigestVector *additions, struct SOSDigestVector *dv,
+                          CFErrorRef *error);
+
+/* SOSObject. */
+
+/* Forward declarations of SOS types. */
+typedef struct __OpaqueSOSObjectID *SOSObjectID;
+typedef struct __OpaqueSOSManifest *SOSManifestRef;
+
+/* SOSManifest. */
+SOSManifestRef SOSManifestCreateWithBytes(const uint8_t *bytes, size_t len,
+                                          CFErrorRef *error);
+SOSManifestRef SOSManifestCreateWithData(CFDataRef data, CFErrorRef *error);
+void SOSManifestDispose(SOSManifestRef m);
+size_t SOSManifestGetSize(SOSManifestRef m);
+size_t SOSManifestGetCount(SOSManifestRef m);
+const uint8_t *SOSManifestGetBytePtr(SOSManifestRef m);
+CFDataRef SOSManifestGetData(SOSManifestRef m);
+bool SOSManifestDiff(SOSManifestRef a, SOSManifestRef b,
+                     SOSManifestRef *a_minus_b, SOSManifestRef *b_minus_a,
+                     CFErrorRef *error);
+SOSManifestRef SOSManifestCreateWithPatch(SOSManifestRef base,
+                                          SOSManifestRef removals,
+                                          SOSManifestRef additions,
+                                          CFErrorRef *error);
+void SOSManifestForEach(SOSManifestRef m, void(^block)(CFDataRef e));
+
+CFStringRef SOSManifestCopyDescription(SOSManifestRef m);
+
+#if 0
+SOSObjectRef SOSManifestGetObject(SOSManifestRef m, SOSObjectID k);
+void SOSManifestPutObject(SOSManifestRef m, SOSObjectID k, SOSObjectRef v);
+
+typedef SOSObjectRef(*SOSManifestGetF)(void *get_ctx, SOSObjectID k);
+SOSManifestRef SOSManifestCreateSparse(void *get_ctx, SOSManifestGetF get_f);
+#endif
+
+__END_DECLS
+
+#endif /* !_SOSTRANSPORT_H_ */
diff --git a/sec/SOSCircle/SecureObjectSync/SOSUserKey.c b/sec/SOSCircle/SecureObjectSync/SOSUserKey.c
new file mode 100644 (file)
index 0000000..d3109c6
--- /dev/null
@@ -0,0 +1,80 @@
+//
+//  SOSUserKey.c
+//  sec
+//
+//  Created by Richard Murphy on 2/13/13.
+//
+//
+
+#include <stdio.h>
+#include <SecureObjectSync/SOSUserKey.h>
+#include <corecrypto/ccrng.h>
+#include <corecrypto/ccec.h>
+#include <CommonCrypto/CommonRandomSPI.h>
+#include <CoreFoundation/CFString.h>
+
+#if 0
+#include <corecrypto/ccrng_pbkdf2_prng.h>
+
+#define UK_CONST_DECL(k,v) CFTypeRef k = (CFTypeRef)(CFSTR(v));
+
+UK_CONST_DECL (ukSalt, "salt");
+UK_CONST_DECL (ukIteration, "iteration");
+
+static const size_t saltlen = 16;
+static const unsigned long iterations = 10240;
+
+static dispatch_once_t keyParmStoreInit;
+static CFMutableDictionaryRef keyParmStorage = NULL;
+static void SOSKeyParmStore(CFStringRef user_label, CFDictionaryRef parmData) {
+    dispatch_once(&keyParmStoreInit, ^{
+        keyParmStorage = CFDictionaryCreateMutable(kCFAllocatorDefault, 50,  &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    });
+    CFDictionaryAddValue(keyParmStorage, user_label, parmData);
+}
+
+static CFDictionaryRef SOSKeyParmRetrieve(CFStringRef user_label) {
+    if(keyParmStorage && CFDictionaryContainsKey(keyParmStorage, user_label)) {
+        CFDictionaryRef parmData = CFDictionaryGetValue(keyParmStorage, user_label);
+        CFRetain(parmData);
+        return parmData;
+    }
+/*
+    const void *keys[] = { ukSalt, ukIteration };
+    const void *values[] = { cfsalt,  cfiteration };
+    CFDictionaryRef query = CFDictionaryCreate(kCFAllocatorDefault, keys, values, sizeof(keys)/sizeof(*keys), NULL, NULL);
+    CFDictionaryRef retval = CFDictionaryCreate(
+*/
+    return NULL;
+}
+
+
+static void
+SOSUserKeyGenParmPersist(CFStringRef user_label)
+{
+}
+
+static void
+SOSUserKeyGenParmRetrieve(CFStringRef user_label)
+{
+}
+#endif
+
+bool
+SOSUserKeyGenerate(int keysize, CFStringRef user_label, CFDataRef user_password, SecKeyRef *user_pubkey, SecKeyRef *user_privkey)
+{
+#if 0
+    ccec_const_cp_t cp = ccec_get_cp(keysize);
+    ccec_full_ctx_decl_cp(cp, full_key);
+    struct ccrng_pbkdf2_prng_state pbkdf2_prng;
+    uint8_t salt[saltlen];
+    if(CCRandomCopyBytes(kCCRandomDefault, salt, sizeof(salt)) != kCCSuccess) return false;
+    uint8_t password_bytes = CFDataGetBytePtr(user_password);
+    size_t password_length = CFDataGetLength(user_password);
+    ccrng_pbkdf2_prng_init(&pbkdf2_prng, 72, password_length, password_bytes, sizeof(salt), salt, iterations);
+    struct ccrng_state *rng = (struct ccrng_state *)&pbkdf2_prng;
+    ccec_generate_key(cp, rng, full_key);
+#endif
+
+    return true;
+}
diff --git a/sec/SOSCircle/SecureObjectSync/SOSUserKey.h b/sec/SOSCircle/SecureObjectSync/SOSUserKey.h
new file mode 100644 (file)
index 0000000..3064876
--- /dev/null
@@ -0,0 +1,18 @@
+//
+//  SOSUserKey.h
+//  sec
+//
+//  Created by Richard Murphy on 2/13/13.
+//
+//
+
+#ifndef sec_SOSUserKey_h
+#define sec_SOSUserKey_h
+
+#include <Security/Security.h>
+
+bool
+SOSUserKeyGenerate(int keysize, CFStringRef user_label, CFDataRef user_password, SecKeyRef *user_pubkey, SecKeyRef *user_privkey);
+
+
+#endif
diff --git a/sec/SOSCircle/SecureObjectSync/SOSUserKeygen.c b/sec/SOSCircle/SecureObjectSync/SOSUserKeygen.c
new file mode 100644 (file)
index 0000000..c8f0a28
--- /dev/null
@@ -0,0 +1,292 @@
+//
+//  SOSUserKeygen.c
+//  sec
+//
+//  Created by Richard Murphy on 2/21/13.
+//
+//
+
+#include <SecureObjectSync/SOSUserKeygen.h>
+#include <stdio.h>
+#include <corecrypto/ccrng.h>
+#include <corecrypto/ccrng_pbkdf2_prng.h>
+#include <corecrypto/ccec.h>
+#include <corecrypto/ccdigest.h>
+#include <corecrypto/ccsha2.h>
+#include <CommonCrypto/CommonRandomSPI.h>
+#include <Security/SecKey.h>
+#include <Security/SecKeyPriv.h>
+#include <Security/SecFramework.h>
+#include <utilities/SecCFWrappers.h>
+#include <utilities/SecCFRelease.h>
+#include <utilities/debugging.h>
+#include <SecureObjectSync/SOSCloudCircle.h>
+#include <SecureObjectSync/SOSInternal.h>
+#include <Security/SecFramework.h>
+#include <Security/SecItem.h>
+#include <utilities/der_plist.h>
+#include <utilities/der_plist_internal.h>
+
+#include <corecrypto/ccder.h>
+#include <Security/oidsalg.h>
+
+// A.2   PBKDF2
+//
+// The object identifier id-PBKDF2 identifies the PBKDF2 key derivation
+// function (Section 5.2).
+//
+// id-PBKDF2 OBJECT IDENTIFIER ::= {pkcs-5 12}
+//
+// The parameters field associated with this OID in an
+// AlgorithmIdentifier shall have type PBKDF2-params:
+//
+// 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 }
+//
+// The fields of type PKDF2-params have the following meanings:
+
+
+static size_t der_sizeof_SecAsn1Oid(const SecAsn1Oid* secasn_oid)
+{
+    return ccder_sizeof(CCDER_OBJECT_IDENTIFIER, secasn_oid->Length);
+}
+
+static uint8_t *der_encode_SecAsn1Oid(const SecAsn1Oid* secasn_oid, const uint8_t *der, uint8_t *der_end)
+{
+    return ccder_encode_tl(CCDER_OBJECT_IDENTIFIER, secasn_oid->Length, der,
+           ccder_encode_body(secasn_oid->Length, secasn_oid->Data, der, der_end));
+}
+
+static const uint8_t *der_expect_SecAsn1Oid(const SecAsn1Oid* secasn_oid, const uint8_t *der, const uint8_t *der_end)
+{
+    size_t len = 0;
+    der = ccder_decode_tl(CCDER_OBJECT_IDENTIFIER, &len,
+                                          der, der_end);
+
+    if (secasn_oid->Length != len || memcmp(secasn_oid->Data, der, len) != 0)
+        der = NULL;
+    else
+        der += len;
+
+    return der;
+}
+
+static size_t der_sizeof_pbkdf2_params(size_t saltLen, const uint8_t *salt,
+                                       unsigned long iterationCount,
+                                       unsigned long keyLength)
+{
+    size_t body_size = ccder_sizeof_raw_octet_string(saltLen)
+                     + ccder_sizeof_uint64(iterationCount)
+                     + ccder_sizeof_uint64(keyLength)
+                     + der_sizeof_SecAsn1Oid(&CSSMOID_PKCS5_HMAC_SHA1);
+
+    return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, body_size);
+}
+
+static uint8_t *der_encode_pbkdf2_params(size_t saltLen, const uint8_t *salt,
+                                         unsigned long iterationCount,
+                                         unsigned long keyLength,
+                                         const uint8_t *der, uint8_t *der_end)
+{
+    uint8_t* original_der_end = der_end;
+
+    return ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, original_der_end, der,
+           ccder_encode_raw_octet_string(saltLen, salt, der,
+           ccder_encode_uint64(iterationCount, der,
+           ccder_encode_uint64(keyLength, der,
+           der_encode_SecAsn1Oid(&CSSMOID_PKCS5_HMAC_SHA1, der, der_end)))));
+}
+
+static const uint8_t *der_decode_pbkdf2_params(size_t *saltLen, const uint8_t **salt,
+                                               unsigned long *iterationCount,
+                                               unsigned long *keyLength,
+                                               const uint8_t *der, const uint8_t *der_end)
+{
+    const uint8_t * body_end = NULL;
+    der = ccder_decode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, &body_end, der, der_end);
+
+    if (body_end != der_end)
+        der = NULL;
+
+    size_t salt_size = 0;
+    const uint8_t *salt_bytes = NULL;
+
+    der = ccder_decode_tl(CCDER_OCTET_STRING, &salt_size, der, body_end);
+    salt_bytes = der;
+    der += salt_size;
+
+    uint64_t iteration_count = 0;
+    uint64_t key_len = 0;
+    der = ccder_decode_uint64(&iteration_count, der, body_end);
+    if (iteration_count > UINT32_MAX)
+        der = NULL;
+
+    der = ccder_decode_uint64(&key_len, der, body_end);
+    if (key_len > UINT32_MAX)
+        der = NULL;
+
+    der = der_expect_SecAsn1Oid(&CSSMOID_PKCS5_HMAC_SHA1, der, body_end);
+
+    if (der) {
+        if (salt)
+            *salt = salt_bytes;
+        if (saltLen)
+            *saltLen = salt_size;
+        if (iterationCount)
+            *iterationCount = (unsigned long)iteration_count;
+        if (keyLength)
+            *keyLength = (unsigned long) key_len;
+    }
+
+    return der;
+}
+
+
+static SecKeyRef ccec2SecKey(ccec_full_ctx_t fk)
+{
+    size_t export_size = ccec_x963_export_size(1, fk);
+    uint8_t export_keybytes[export_size];
+    ccec_x963_export(1, export_keybytes, fk);
+    CFDataRef exportedkey = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, export_keybytes, export_size, kCFAllocatorNull);
+
+    CFDictionaryRef keyattributes = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
+                                                                 kSecValueData, exportedkey,
+                                                                 kSecAttrKeyType, kSecAttrKeyTypeEC,
+                                                                 kSecAttrKeyClass, kSecAttrKeyClassPrivate,
+                                                                 NULL);
+
+    SecKeyRef retval = SecKeyCreateFromAttributeDictionary(keyattributes);
+
+    CFRelease(keyattributes);
+    CFRelease(exportedkey);
+    bzero(export_keybytes, 0);
+    return retval;
+}
+
+#define SALTMAX 16
+#define ITERATIONMIN 50000
+
+CFDataRef SOSUserKeyCreateGenerateParameters(CFErrorRef *error) {
+    size_t saltlen = SALTMAX;
+    uint8_t salt[saltlen];
+
+    size_t iterations = ITERATIONMIN;
+    size_t keysize = 256;
+
+    if(CCRandomCopyBytes(kCCRandomDefault, salt, sizeof(salt)) != kCCSuccess) {
+        SOSCreateError(kSOSErrorProcessingFailure, CFSTR("CCRandomCopyBytes failed"), NULL, error);
+        return NULL;
+    }
+
+    CFMutableDataRef result = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    CFDataSetLength(result, der_sizeof_pbkdf2_params(saltlen, salt, iterations, keysize));
+
+    uint8_t * encode = der_encode_pbkdf2_params(saltlen, salt, iterations, keysize,
+                                                CFDataGetBytePtr(result),
+                                                CFDataGetMutableBytePtr(result) + CFDataGetLength(result));
+
+    if (!encode)
+        CFReleaseNull(result);
+
+    if (result) {
+        secnotice("keygen", "Created new parameters: iterations %zd, keysize %zd: %@", iterations, keysize, result);
+    }
+
+    return result;
+}
+
+SecKeyRef SOSUserKeygen(CFDataRef password, CFDataRef parameters, CFErrorRef *error)
+{
+    size_t saltlen;
+    const uint8_t *salt = NULL;
+
+    size_t iterations = 0;
+    size_t keysize = 0;
+
+    const uint8_t *der = CFDataGetBytePtr(parameters);
+    const uint8_t *der_end = der + CFDataGetLength(parameters);
+
+    der = der_decode_pbkdf2_params(&saltlen, &salt, &iterations, &keysize, der, der_end);
+
+    if (der == NULL) {
+        SOSCreateErrorWithFormat(kSOSErrorDecodeFailure, NULL, error, NULL,
+                                 CFSTR("Bad paramter encoding, got: %@"), parameters);
+        return NULL;
+    }
+    if (keysize != 256) {
+        SOSCreateErrorWithFormat(kSOSErrorUnsupported, NULL, error, NULL,
+                                 CFSTR("Key size not supported, requested %zd."), keysize);
+        return NULL;
+    }
+    if (saltlen < 4) {
+        SOSCreateErrorWithFormat(kSOSErrorUnsupported, NULL, error, NULL,
+                                 CFSTR("Salt length not supported, requested %zd."), saltlen);
+        return NULL;
+    }
+    if (iterations < ITERATIONMIN) {
+        SOSCreateErrorWithFormat(kSOSErrorUnsupported, NULL, error, NULL,
+                                 CFSTR("Too few iterations, params suggested %zd."), iterations);
+        return NULL;
+    }
+
+    const uint8_t *password_bytes = CFDataGetBytePtr(password);
+    size_t password_length = CFDataGetLength(password);
+
+    const size_t maxbytes = 128;
+
+    ccec_const_cp_t cp = ccec_get_cp(keysize);
+    struct ccrng_pbkdf2_prng_state pbkdf2_prng;
+
+    ccec_full_ctx_decl_cp(cp, tmpkey);
+
+    secnotice("keygen", "Generating key for: iterations %zd, keysize %zd: %@", iterations, keysize, parameters);
+
+    if (ccrng_pbkdf2_prng_init(&pbkdf2_prng, maxbytes,
+                                password_length, password_bytes,
+                                saltlen, salt,
+                                iterations)) {
+        SOSCreateError(kSOSErrorProcessingFailure, CFSTR("prng init failed"), NULL, error);
+        return NULL;
+    }
+
+    if (ccec_generate_key(cp, (struct ccrng_state *)&pbkdf2_prng, tmpkey)) {
+        SOSCreateError(kSOSErrorProcessingFailure, CFSTR("Keygen failed"), NULL, error);
+        return NULL;
+    }
+
+
+    return ccec2SecKey(tmpkey);
+}
+
+void debugDumpUserParameters(CFStringRef message, CFDataRef parameters)
+{
+    size_t saltlen = 0;
+    const uint8_t *salt = NULL;
+    
+    size_t iterations = 0;
+    size_t keysize = 0;
+    
+    const uint8_t *der = CFDataGetBytePtr(parameters);
+    const uint8_t *der_end = der + CFDataGetLength(parameters);
+    
+    der = der_decode_pbkdf2_params(&saltlen, &salt, &iterations, &keysize, der, der_end);
+    if (der == NULL) {
+        secnotice("keygen", "failed to decode pbkdf2 params");
+        return;
+    }
+    
+    BufferPerformWithHexString(salt, saltlen, ^(CFStringRef saltHex) {
+        CFDataPerformWithHexString(parameters, ^(CFStringRef parametersHex) {
+            secnotice("keygen", "%@ <Params: count: %zd, keysize: %zd, salt: %@, raw: %@>]", message, iterations, keysize, saltHex, parametersHex);
+        });
+    });
+}
+
+
diff --git a/sec/SOSCircle/SecureObjectSync/SOSUserKeygen.h b/sec/SOSCircle/SecureObjectSync/SOSUserKeygen.h
new file mode 100644 (file)
index 0000000..0a166ee
--- /dev/null
@@ -0,0 +1,19 @@
+//
+//  SOSUserKeygen.h
+//  sec
+//
+//  Created by Richard Murphy on 2/21/13.
+//
+//
+
+#ifndef sec_SOSUserKeygen_h
+#define sec_SOSUserKeygen_h
+#include <SecureObjectSync/SOSCloudCircle.h>
+#include <Security/SecKey.h>
+
+CFDataRef SOSUserKeyCreateGenerateParameters(CFErrorRef *error);
+SecKeyRef SOSUserKeygen(CFDataRef password, CFDataRef parameters, CFErrorRef *error);
+
+void debugDumpUserParameters(CFStringRef message, CFDataRef parameters);
+
+#endif
diff --git a/sec/SOSCircle/Tool/SOSCommands.h b/sec/SOSCircle/Tool/SOSCommands.h
new file mode 100644 (file)
index 0000000..cdc8bf0
--- /dev/null
@@ -0,0 +1,32 @@
+//
+//  SOSCommands.h
+//  sec
+//
+//  Created by Mitch Adler on 1/9/13.
+//
+//
+
+#include <SecurityTool/security_tool_commands.h>
+
+SECURITY_COMMAND("sync", keychain_sync,
+                 "[options]\n"
+                 "    -e     Enable Keychain Syncing (join/create circle)\n"
+                 "    -d     Disable Keychain Syncing\n"
+                 "    -a     Accept all applicants\n"
+                 "    -r     Reject all applicants\n"
+                 "    -i     Info\n"
+                 "    -k     Pend all registered kvs keys\n"
+                 "    -s     Schedule sync with all peers\n"
+                 "    -R     Reset\n"
+                 "    -O     ResetToOffering\n"
+                 "    -C     Clear all values from KVS\n"
+                 "    -P    [label:]password  Set password (optionally for a given label) for sync\n"
+                 "    -D    [itemName]  Dump contents of KVS\n"
+                 "    -P    [label:]password  Set password (optionally for a given label) for sync\n"
+                 "    -T    [label:]password  Try password (optionally for a given label) for sync\n"
+                 "    -U     Purge private key material cache\n"
+                 "    -D    [itemName]  Dump contents of KVS\n"
+                 "    -W    itemNames  sync and dump\n",
+                 "    -X    [limit]  Best effort bail from circle in limit seconds\n"
+                 "Keychain Syncing controls." )
+
diff --git a/sec/SOSCircle/Tool/keychain_sync.c b/sec/SOSCircle/Tool/keychain_sync.c
new file mode 100644 (file)
index 0000000..6e3c7c8
--- /dev/null
@@ -0,0 +1,459 @@
+/*
+ * Copyright (c) 2003-2007,2009-2010 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ *
+ * keychain_add.c
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <Security/SecItem.h>
+
+#include <CoreFoundation/CFNumber.h>
+#include <CoreFoundation/CFString.h>
+
+#include <SecureObjectSync/SOSCloudCircle.h>
+#include <SecureObjectSync/SOSCloudCircleInternal.h>
+#include <SecureObjectSync/SOSPeerInfo.h>
+
+#include <securityd/SOSCloudCircleServer.h>
+
+#include <CKBridge/SOSCloudKeychainClient.h>
+
+#include <utilities/SecCFWrappers.h>
+#include <utilities/debugging.h>
+
+#include <SecurityTool/readline.h>
+#include <notify.h>
+
+#include "SOSCommands.h"
+
+#define printmsg(format, ...) _printcfmsg(stdout, format, __VA_ARGS__)
+#define printerr(format, ...) _printcfmsg(stderr, format, __VA_ARGS__)
+
+static void _printcfmsg(FILE *ff, CFStringRef format, ...)
+{
+    va_list args;
+    va_start(args, format);
+    CFStringRef message = CFStringCreateWithFormatAndArguments(kCFAllocatorDefault, NULL, format, args);
+    va_end(args);
+    CFStringPerformWithCString(message, ^(const char *utf8String) { fprintf(ff, utf8String, ""); });
+    CFRelease(message);
+}
+
+static bool clearAllKVS(CFErrorRef *error)
+{
+    __block bool result = false;
+    const uint64_t maxTimeToWaitInSeconds = 30ull * NSEC_PER_SEC;
+    dispatch_queue_t processQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
+    dispatch_semaphore_t waitSemaphore = dispatch_semaphore_create(0);
+    dispatch_time_t finishTime = dispatch_time(DISPATCH_TIME_NOW, maxTimeToWaitInSeconds);
+    
+    SOSCloudKeychainClearAll(processQueue, ^(CFDictionaryRef returnedValues, CFErrorRef cerror)
+    {
+        result = (cerror != NULL);
+        dispatch_semaphore_signal(waitSemaphore);
+    });
+    
+       dispatch_semaphore_wait(waitSemaphore, finishTime);
+    dispatch_release(waitSemaphore);
+
+    return result;
+}
+
+static const char *getSOSCCStatusDescription(SOSCCStatus ccstatus)
+{
+    switch (ccstatus)
+    {
+        case kSOSCCInCircle:        return "In Circle";
+        case kSOSCCNotInCircle:     return "Not in Circle";
+        case kSOSCCRequestPending:  return "Request pending";
+        case kSOSCCCircleAbsent:    return "Circle absent";
+        case kSOSCCError:           return "Circle error";
+
+        default:
+            return "<unknown ccstatus>";
+            break;
+    }
+}
+
+static void dumpCircleInfo()
+{
+    CFErrorRef error = NULL;
+    CFArrayRef applicantPeerInfos = NULL;
+    CFArrayRef peerInfos = NULL;
+
+    SOSCCStatus ccstatus = SOSCCThisDeviceIsInCircle(&error);
+    printerr(CFSTR("ccstatus: %s (%d), error: %@\n"), getSOSCCStatusDescription(ccstatus), ccstatus, error);
+    
+    if(ccstatus == kSOSCCError) {
+        printerr(CFSTR("End of Dump - unable to proceed due to ccstatus -\n\t%s\n"), getSOSCCStatusDescription(ccstatus));
+        return;
+    }
+
+    // Now look at current applicants
+    applicantPeerInfos = SOSCCCopyApplicantPeerInfo(&error);
+    if (applicantPeerInfos)
+    {
+        printerr(CFSTR("Applicants: %ld, error: %@\n"), (long)CFArrayGetCount(applicantPeerInfos), error);
+        CFArrayForEach(applicantPeerInfos, ^(const void *value) {
+            SOSPeerInfoRef peer = (SOSPeerInfoRef)value;
+            CFStringRef peerName = SOSPeerInfoGetPeerName(peer);
+            printerr(CFSTR("Applicant: %@ (%@)\n"), peerName, peer);
+        });
+    }
+    else
+        printerr(CFSTR("No applicants, error: %@\n"), error);
+    
+    
+    peerInfos = SOSCCCopyPeerPeerInfo(&error);
+    if (peerInfos)
+    {
+        printerr(CFSTR("Peers: %ld, error: %@\n"), (long)CFArrayGetCount(peerInfos), error);
+        CFArrayForEach(peerInfos, ^(const void *value) {
+            SOSPeerInfoRef peer = (SOSPeerInfoRef)value;
+            CFStringRef peerName = SOSPeerInfoGetPeerName(peer);
+            printerr(CFSTR("Peer: %@ (%@)\n"), peerName, peer);
+        });
+    }
+    else
+        printerr(CFSTR("No peers, error: %@\n"), error);
+    
+    peerInfos = SOSCCCopyConcurringPeerPeerInfo(&error);
+    if (peerInfos)
+    {
+        printerr(CFSTR("Concurring Peers: %ld, error: %@\n"), (long)CFArrayGetCount(peerInfos), error);
+        CFArrayForEach(peerInfos, ^(const void *value) {
+            SOSPeerInfoRef peer = (SOSPeerInfoRef)value;
+            CFStringRef peerName = SOSPeerInfoGetPeerName(peer);
+            printerr(CFSTR("Concurr: %@ (%@)\n"), peerName, peer);
+        });
+    }
+    else
+        printerr(CFSTR("No concurring peers, error: %@\n"), error);
+}
+
+static bool requestToJoinCircle(CFErrorRef *error)
+{
+    // Set the visual state of switch based on membership in circle
+    bool hadError = false;
+    SOSCCStatus ccstatus = SOSCCThisDeviceIsInCircle(error);
+    
+    switch (ccstatus)
+    {
+    case kSOSCCCircleAbsent:
+        hadError = !SOSCCResetToOffering(error);
+        break;
+    case kSOSCCNotInCircle:
+        hadError = !SOSCCRequestToJoinCircle(error);
+        break;
+    default:
+        printerr(CFSTR("Request to join circle with bad status:  %@ (%d)\n"), SOSCCGetStatusDescription(ccstatus), ccstatus);
+        break;
+    }
+    return hadError;
+}
+
+static bool setPassword(char *labelAndPassword, CFErrorRef *err)
+{
+    char *last = NULL;
+    char *token0 = strtok_r(labelAndPassword, ":", &last);
+    char *token1 = strtok_r(NULL, "", &last);
+    CFStringRef label = token1 ? CFStringCreateWithCString(NULL, token0, kCFStringEncodingUTF8) : CFSTR("security command line tool");
+    char *password_token = token1 ? token1 : token0;
+    password_token = password_token ? password_token : "";
+    CFDataRef password = CFDataCreate(NULL, (const UInt8*) password_token, strlen(password_token));
+    bool returned = !SOSCCSetUserCredentials(label, password, err);
+    CFRelease(label);
+    CFRelease(password);
+    return returned;
+}
+
+static bool tryPassword(char *labelAndPassword, CFErrorRef *err)
+{
+    char *last = NULL;
+    char *token0 = strtok_r(labelAndPassword, ":", &last);
+    char *token1 = strtok_r(NULL, "", &last);
+    CFStringRef label = token1 ? CFStringCreateWithCString(NULL, token0, kCFStringEncodingUTF8) : CFSTR("security command line tool");
+    char *password_token = token1 ? token1 : token0;
+    password_token = password_token ? password_token : "";
+    CFDataRef password = CFDataCreate(NULL, (const UInt8*) password_token, strlen(password_token));
+    bool returned = !SOSCCTryUserCredentials(label, password, err);
+    CFRelease(label);
+    CFRelease(password);
+    return returned;
+}
+
+static CFTypeRef getObjectsFromCloud(CFArrayRef keysToGet, dispatch_queue_t processQueue, dispatch_group_t dgroup)
+{
+    __block CFTypeRef object = NULL;
+
+    const uint64_t maxTimeToWaitInSeconds = 30ull * NSEC_PER_SEC;
+    dispatch_semaphore_t waitSemaphore = dispatch_semaphore_create(0);
+    dispatch_time_t finishTime = dispatch_time(DISPATCH_TIME_NOW, maxTimeToWaitInSeconds);
+
+    dispatch_group_enter(dgroup);
+
+    CloudKeychainReplyBlock replyBlock =
+    ^ (CFDictionaryRef returnedValues, CFErrorRef error)
+    {
+        secerror("SOSCloudKeychainGetObjectsFromCloud returned: %@", returnedValues);
+        object = returnedValues;
+        if (object)
+            CFRetain(object);
+        if (error)
+        {
+            secerror("SOSCloudKeychainGetObjectsFromCloud returned error: %@", error);
+            //       CFRelease(*error);
+        }
+        dispatch_group_leave(dgroup);
+        secerror("SOSCloudKeychainGetObjectsFromCloud block exit: %@", object);
+        dispatch_semaphore_signal(waitSemaphore);
+    };
+
+    if (!keysToGet)
+        SOSCloudKeychainGetAllObjectsFromCloud(processQueue, replyBlock);
+    else
+        SOSCloudKeychainGetObjectsFromCloud(keysToGet, processQueue, replyBlock);
+
+       dispatch_semaphore_wait(waitSemaphore, finishTime);
+       dispatch_release(waitSemaphore);
+    if (object && (CFGetTypeID(object) == CFNullGetTypeID()))   // return a NULL instead of a CFNull
+    {
+        CFRelease(object);
+        object = NULL;
+    }
+    secerror("returned: %@", object);
+    return object;
+}
+
+static void displayCircles(CFTypeRef objects)
+{
+    // SOSCCCopyApplicantPeerInfo doesn't display all info, e.g. in the case where we are not in circle
+    CFDictionaryForEach(objects, ^(const void *key, const void *value) {
+        if (SOSKVSKeyGetKeyType(key) == kCircleKey)
+        {
+            CFErrorRef localError = NULL;
+            if (isData(value))
+            {
+                SOSCircleRef circle = SOSCircleCreateFromData(NULL, (CFDataRef) value, &localError);
+                printmsg(CFSTR("circle: %@ %@"), key, circle);
+                CFReleaseSafe(circle);
+            }
+            else
+                printmsg(CFSTR("non-circle: %@ %@"), key, value);
+        }
+    });
+}
+
+static bool dumpKVS(char *itemName, CFErrorRef *err)
+{
+    CFArrayRef keysToGet = NULL;
+    if (itemName)
+    {
+        CFStringRef itemStr = CFStringCreateWithCString(kCFAllocatorDefault, itemName, kCFStringEncodingUTF8);
+        printf("Retrieving %s from KVS\n", itemName);
+        keysToGet = CFArrayCreateForCFTypes(kCFAllocatorDefault, itemStr, NULL);
+        CFReleaseSafe(itemStr);
+    }
+    dispatch_queue_t generalq = dispatch_queue_create("general", DISPATCH_QUEUE_SERIAL);
+    dispatch_group_t work_group = dispatch_group_create();
+    CFTypeRef objects = getObjectsFromCloud(keysToGet, generalq, work_group);
+    CFReleaseSafe(keysToGet);
+    printmsg(CFSTR("   : %@\n"), objects);
+    if (objects)
+        displayCircles(objects);
+    printf("\n");
+    return false;
+}
+
+static bool syncAndWait(char *itemName, CFErrorRef *err)
+{
+    CFArrayRef keysToGet = NULL;
+    __block CFTypeRef objects = NULL;
+    if (!itemName)
+    {
+        fprintf(stderr, "No item keys supplied\n");
+        return false;
+    }
+
+    CFStringRef itemStr = CFStringCreateWithCString(kCFAllocatorDefault, itemName, kCFStringEncodingUTF8);
+    printf("Retrieving %s from KVS\n", itemName);
+    keysToGet = CFArrayCreateForCFTypes(kCFAllocatorDefault, itemStr, NULL);
+    CFReleaseSafe(itemStr);
+
+    dispatch_queue_t generalq = dispatch_queue_create("general", DISPATCH_QUEUE_SERIAL);
+
+    const uint64_t maxTimeToWaitInSeconds = 30ull * NSEC_PER_SEC;
+    dispatch_semaphore_t waitSemaphore = dispatch_semaphore_create(0);
+    dispatch_time_t finishTime = dispatch_time(DISPATCH_TIME_NOW, maxTimeToWaitInSeconds);
+
+    CloudKeychainReplyBlock replyBlock = ^ (CFDictionaryRef returnedValues, CFErrorRef error)
+    {
+        secerror("SOSCloudKeychainSynchronizeAndWait returned: %@", returnedValues);
+        if (error)
+            secerror("SOSCloudKeychainSynchronizeAndWait returned error: %@", error);
+        objects = returnedValues;
+        if (objects)
+            CFRetain(objects);
+        secerror("SOSCloudKeychainGetObjectsFromCloud block exit: %@", objects);
+        dispatch_semaphore_signal(waitSemaphore);
+    };
+
+    SOSCloudKeychainSynchronizeAndWait(keysToGet, generalq, replyBlock);
+
+       dispatch_semaphore_wait(waitSemaphore, finishTime);
+       dispatch_release(waitSemaphore);
+
+    CFReleaseSafe(keysToGet);
+    printmsg(CFSTR("   : %@\n"), objects);
+    if (objects)
+        displayCircles(objects);
+    printf("\n");
+    return false;
+}
+
+// enable, disable, accept, reject, status, Reset, Clear
+int
+keychain_sync(int argc, char * const *argv)
+{
+    /*
+     "    -e     Enable Keychain Syncing (join/create circle)\n"
+     "    -d     Disable Keychain Syncing\n"
+     "    -a     Accept all applicants\n"
+     "    -r     Reject all applicants\n"
+     "    -i     Info\n"
+     "    -k     Pend all registered kvs keys\n"
+     "    -s     Schedule sync with all peers\n"
+     "    -R     Reset\n"
+     "    -O     ResetToOffering\n"
+     "    -C     Clear all values from KVS\n"
+     "    -P    [label:]password  Set password (optionally for a given label) for sync\n"
+     "    -D    [itemName]  Dump contents of KVS\n"
+     "    -P    [label:]password  Set password (optionally for a given label) for sync\n"
+     "    -T    [label:]password  Try password (optionally for a given label) for sync\n"
+     "    -U     Purge private key material cache\n"
+     "    -D    [itemName]  Dump contents of KVS\n"
+     "    -W    itemNames  sync and dump\n"
+     "    -X    [limit]  Best effort bail from circle in limit seconds\n"
+     */
+       int ch, result = 0;
+    CFErrorRef error = NULL;
+    bool hadError = false;
+    
+       while ((ch = getopt(argc, argv, "edakrisROChP:T:DW:UX:")) != -1)
+       {
+               switch  (ch)
+               {
+        case 'e':
+            printf("Keychain syncing is being turned ON\n");
+            hadError = requestToJoinCircle(&error);
+            break;
+        case 'd':
+            printf("Keychain syncing is being turned OFF\n");
+            hadError = !SOSCCRemoveThisDeviceFromCircle(&error);
+            break;
+        case 'a':
+            {
+                CFArrayRef applicants = SOSCCCopyApplicantPeerInfo(NULL);
+                if (applicants)
+                {
+                    hadError = !SOSCCAcceptApplicants(applicants, &error);
+                    CFRelease(applicants);
+                }
+                else
+                    fprintf(stderr, "No applicants to accept\n");
+            }
+            break;
+        case 'r':
+            {
+                CFArrayRef applicants = SOSCCCopyApplicantPeerInfo(NULL);
+                if (applicants)
+                {
+                    hadError = !SOSCCRejectApplicants(applicants, &error);
+                    CFRelease(applicants);
+                }
+                else
+                    fprintf(stderr, "No applicants to reject\n");
+            }
+            break;
+        case 'i':
+            dumpCircleInfo();
+            break;
+        case 'k':
+            notify_post("com.apple.security.cloudkeychain.forceupdate");
+            break;
+        case 's':
+            //SOSCloudKeychainRequestSyncWithAllPeers(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), NULL);
+            break;
+        case 'R':
+            hadError = !SOSCCResetToEmpty(&error);
+            break;
+        case 'O':
+            hadError = !SOSCCResetToOffering(&error);
+            break;
+        case 'C':
+            hadError = clearAllKVS(&error);
+            break;
+        case 'P':
+            hadError = setPassword(optarg, &error);
+            break;
+        case 'T':
+            hadError = tryPassword(optarg, &error);
+            break;
+        case 'X':
+            {
+            uint64_t limit = strtoul(optarg, NULL, 10);
+            hadError = !SOSCCBailFromCircle_BestEffort(limit, &error);
+            }
+            break;
+        case 'U':
+            hadError = !SOSCCPurgeUserCredentials(&error);
+            break;
+        case 'D':
+            hadError = dumpKVS(optarg, &error);
+            break;
+        case 'W':
+            hadError = syncAndWait(optarg, &error);
+            break;
+               case '?':
+               default:
+                       return 2; /* Return 2 triggers usage message. */
+               }
+       }
+
+       argc -= optind;
+       argv += optind;
+
+//     if (argc == 0)
+//             return 2;
+
+       if (hadError)
+        printerr(CFSTR("Error: %@\n"), error);
+
+    //                 sec_perror("SecItemAdd", result);
+
+       return result;
+}
diff --git a/sec/SOSCircle/osxshim.c b/sec/SOSCircle/osxshim.c
new file mode 100644 (file)
index 0000000..2468f08
--- /dev/null
@@ -0,0 +1,30 @@
+//
+//  osxshim.c
+//  sec
+//
+//  Created by J Osborne on 12/4/12.
+//
+//
+
+#include <stdbool.h>
+
+typedef void *SOSDataSourceFactoryRef;
+typedef void *SOSAccountRef;
+
+// XXX Need to plumb these from security to secd.   If we can.
+
+typedef SOSDataSourceFactoryRef (^AccountDataSourceFactoryBlock)();
+
+bool SOSKeychainAccountSetFactoryForAccount(AccountDataSourceFactoryBlock factory);
+
+bool SOSKeychainAccountSetFactoryForAccount(AccountDataSourceFactoryBlock factory)
+{
+    return false;
+}
+
+SOSAccountRef SOSKeychainAccountGetSharedAccount(void);
+
+SOSAccountRef SOSKeychainAccountGetSharedAccount(void)
+{
+    return (void*)0;
+}
diff --git a/sec/Security/AppleBaselineEscrowCertificates.h b/sec/Security/AppleBaselineEscrowCertificates.h
new file mode 100644 (file)
index 0000000..4a999b1
--- /dev/null
@@ -0,0 +1,94 @@
+//
+//  AppleBaselineEscrowCertificates.h
+//  sec
+//
+//  Created by Jim Murphy on 6/25/13.
+//
+//
+
+#ifndef sec_AppleBaselineEscrowCertificates_h
+#define sec_AppleBaselineEscrowCertificates_h
+
+struct RootRecord
+{
+       size_t  _length;
+       UInt8*  _bytes;
+};
+
+/* ==========================================================================
+    Production Escrow Certificates
+   ========================================================================== */
+
+
+static const UInt8 kBaseLineEscrowRootGM[] = {
+       0x30, 0x82, 0x03, 0xd0, 0x30, 0x82, 0x02, 0xb8, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x64,
+       0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30,
+       0x79, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x05, 0x13, 0x03, 0x31, 0x30, 0x30, 0x31,
+       0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11,
+       0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63,
+       0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c,
+       0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
+       0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55,
+       0x04, 0x03, 0x13, 0x16, 0x45, 0x73, 0x63, 0x72, 0x6f, 0x77, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69,
+       0x63, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33,
+       0x30, 0x38, 0x30, 0x32, 0x32, 0x33, 0x32, 0x34, 0x34, 0x34, 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x30,
+       0x38, 0x30, 0x32, 0x32, 0x33, 0x32, 0x34, 0x34, 0x34, 0x5a, 0x30, 0x79, 0x31, 0x0c, 0x30, 0x0a,
+       0x06, 0x03, 0x55, 0x04, 0x05, 0x13, 0x03, 0x31, 0x30, 0x30, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+       0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
+       0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24,
+       0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72,
+       0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
+       0x72, 0x69, 0x74, 0x79, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x45,
+       0x73, 0x63, 0x72, 0x6f, 0x77, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, 0x52, 0x6f,
+       0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+       0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01,
+       0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd0, 0xa3, 0xf4, 0x56, 0x7d, 0x3f, 0x46, 0x31, 0xd2, 0x56,
+       0xa0, 0xdf, 0x42, 0xa0, 0x29, 0x83, 0x1e, 0xb9, 0x82, 0xb5, 0xa5, 0xff, 0x3e, 0xde, 0xb5, 0x0f,
+       0x4a, 0x8a, 0x28, 0x60, 0xcf, 0x75, 0xb4, 0xa0, 0x70, 0x7c, 0xf5, 0xe2, 0x94, 0xf3, 0x22, 0x02,
+       0xc8, 0x81, 0xce, 0x34, 0xc7, 0x66, 0x6a, 0x18, 0xaa, 0xb4, 0xfd, 0x6d, 0xb0, 0x0b, 0xdd, 0x4a,
+       0xdd, 0xcf, 0xe0, 0x08, 0x1b, 0x1c, 0xa6, 0xdb, 0xba, 0xb2, 0xc1, 0xa4, 0x10, 0x5f, 0x35, 0x4f,
+       0x8b, 0x8b, 0x7a, 0xa3, 0xdb, 0x3c, 0xf6, 0x54, 0x95, 0x42, 0xad, 0x2a, 0x3b, 0xfe, 0x06, 0x8c,
+       0xe1, 0x92, 0xf1, 0x60, 0x97, 0x58, 0x1b, 0xd9, 0x8f, 0xbe, 0xfb, 0x46, 0x4c, 0x29, 0x5c, 0x1c,
+       0xf0, 0x20, 0xb6, 0x2b, 0xa5, 0x12, 0x09, 0x9b, 0x28, 0x41, 0x34, 0x97, 0x9f, 0xf3, 0x88, 0x4b,
+       0x69, 0x72, 0xea, 0x3a, 0x27, 0xb0, 0x50, 0x1d, 0x88, 0x29, 0x0d, 0xbb, 0xed, 0x04, 0xa2, 0x11,
+       0xcf, 0x0c, 0x5b, 0x65, 0x61, 0x35, 0xbd, 0xf2, 0x0d, 0xfc, 0xe2, 0xb9, 0x20, 0xd3, 0xb7, 0x03,
+       0x70, 0x39, 0xd5, 0xe0, 0x86, 0x7c, 0x04, 0xcc, 0xc9, 0xa1, 0x85, 0xb4, 0x9b, 0xbc, 0x88, 0x4e,
+       0xd7, 0xad, 0x5c, 0xff, 0x2c, 0x0d, 0x80, 0x8e, 0x51, 0x39, 0x20, 0x8b, 0xaf, 0x1e, 0x46, 0x95,
+       0xfa, 0x0d, 0x1b, 0xd2, 0xbf, 0x80, 0xe0, 0x9f, 0x6d, 0x4a, 0xf5, 0x31, 0x67, 0x18, 0x11, 0xa5,
+       0x63, 0x27, 0x08, 0xee, 0xd9, 0x07, 0x29, 0xd0, 0xd4, 0x36, 0x91, 0x5b, 0xfb, 0x4a, 0x0b, 0x07,
+       0xd1, 0x0d, 0x79, 0x16, 0x6e, 0x16, 0x02, 0x23, 0x80, 0xc6, 0x15, 0x07, 0x6d, 0xa0, 0x06, 0xb6,
+       0x45, 0x90, 0xb0, 0xae, 0xa4, 0xad, 0x0e, 0x75, 0x04, 0x2b, 0x2b, 0x78, 0xf1, 0x57, 0x84, 0x23,
+       0x87, 0x24, 0xec, 0x58, 0xc4, 0xf1, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x63, 0x30, 0x61, 0x30,
+       0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff,
+       0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06,
+       0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xfd, 0x78, 0x96, 0x53, 0x80,
+       0xd6, 0xf6, 0xdc, 0xa6, 0xc3, 0x59, 0x06, 0x38, 0xed, 0x79, 0x3e, 0x8f, 0x50, 0x1b, 0x50, 0x30,
+       0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xfd, 0x78, 0x96, 0x53,
+       0x80, 0xd6, 0xf6, 0xdc, 0xa6, 0xc3, 0x59, 0x06, 0x38, 0xed, 0x79, 0x3e, 0x8f, 0x50, 0x1b, 0x50,
+       0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
+       0x82, 0x01, 0x01, 0x00, 0x71, 0x15, 0xca, 0x87, 0xd0, 0x2d, 0xb5, 0x18, 0xd5, 0x35, 0x7a, 0xcd,
+       0xdf, 0x62, 0x28, 0xf0, 0x0b, 0x63, 0x4d, 0x4e, 0x02, 0xba, 0x3d, 0xb8, 0xb4, 0x37, 0xea, 0xb0,
+       0x93, 0x93, 0xab, 0x1c, 0xfd, 0x9f, 0xe8, 0x72, 0xbf, 0xf3, 0xdb, 0xe6, 0xad, 0x16, 0xfe, 0x71,
+       0x61, 0xa8, 0x5a, 0xd0, 0x58, 0x0f, 0x65, 0x7a, 0x57, 0x7a, 0xe0, 0x34, 0x80, 0x8e, 0xbb, 0x41,
+       0x01, 0xe7, 0xb0, 0x3b, 0xf7, 0x2b, 0x3a, 0x6d, 0x44, 0x2a, 0x3a, 0x04, 0x52, 0xfa, 0x2b, 0x7b,
+       0x3b, 0x21, 0xdd, 0x0c, 0x70, 0x3d, 0xfb, 0x45, 0xc6, 0x79, 0x68, 0x62, 0xe2, 0x89, 0xb8, 0x25,
+       0xee, 0x63, 0x76, 0x02, 0xb2, 0x22, 0xe9, 0x53, 0x85, 0x68, 0x3e, 0x75, 0xb6, 0x0b, 0x65, 0xe9,
+       0x1c, 0xba, 0x84, 0x93, 0xb0, 0x8a, 0xef, 0xb5, 0x1a, 0x12, 0xe4, 0x8f, 0xae, 0xd5, 0x5c, 0xa1,
+       0x05, 0x4a, 0x01, 0xbc, 0x6f, 0xf9, 0x58, 0x5e, 0xf7, 0x04, 0x61, 0xee, 0xf5, 0xc6, 0xa0, 0x1b,
+       0x44, 0x2e, 0x5a, 0x3a, 0x59, 0xa1, 0xb3, 0xb0, 0xf4, 0xb6, 0xcb, 0xe0, 0x6c, 0x2b, 0x59, 0x8a,
+       0xfb, 0x6a, 0xe0, 0xa2, 0x57, 0x09, 0x79, 0xc1, 0xdd, 0xfb, 0x84, 0x86, 0xeb, 0x66, 0x29, 0x73,
+       0xae, 0xbf, 0x58, 0xae, 0x47, 0x4d, 0x48, 0x37, 0xd6, 0xb1, 0x8c, 0x5f, 0x26, 0x5f, 0xb5, 0x26,
+       0x07, 0x0b, 0x85, 0xb7, 0x36, 0x37, 0x14, 0xcf, 0x5e, 0x55, 0xa5, 0x3c, 0xf3, 0x1e, 0x79, 0x50,
+       0xbb, 0x85, 0x3b, 0xb2, 0x94, 0x68, 0xb0, 0x25, 0x4f, 0x75, 0xec, 0xf0, 0xf9, 0xc0, 0x5a, 0x2d,
+       0xe5, 0xed, 0x67, 0xcd, 0x88, 0x55, 0xa0, 0x42, 0xde, 0x78, 0xbc, 0xfe, 0x30, 0xb1, 0x62, 0x2d,
+       0xe1, 0xfd, 0xec, 0x75, 0x03, 0xa6, 0x1f, 0x7c, 0xc4, 0x3a, 0x4a, 0x59, 0xfe, 0x77, 0xc3, 0x99,
+       0x96, 0x87, 0x44, 0xc3,
+};
+
+
+static struct RootRecord kBaseLineEscrowRootRecord = {sizeof(kBaseLineEscrowRootGM), (UInt8*)kBaseLineEscrowRootGM};
+static struct RootRecord* kBaseLineEscrowRoots[] = {&kBaseLineEscrowRootRecord};
+static const int kNumberOfBaseLineEscrowRoots = (int)(sizeof(kBaseLineEscrowRoots)/sizeof(kBaseLineEscrowRoots[0]));
+
+
+#endif
diff --git a/sec/Security/AuthorizationStatus.h b/sec/Security/AuthorizationStatus.h
new file mode 100644 (file)
index 0000000..6075f2b
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012 Apple Inc. All Rights Reserved.
+ * 
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*!
+       @header AuthorizationStatus
+       The data types in AuthorizationStatus define the various states of Authorization for accessing services.
+*/
+
+/*!
+       @typedef ABAuthorizationStatus
+       @abstract Specifies the AuthorizationStatus result when accessing a service.
+    @constant kABAuthorizationStatusNotDetermined indicates the user has not yet made a choice if this app can access the service.
+       @constant kABAuthorizationStatusRestricted indicates the app is not authorized to use the service. Due to active restrictions on the service the user cannot change this status and may not have personally denied authorization.
+       @constant kABAuthorizationStatusDenied indicates the user has explicitly denied authorization for this app or the service is disabled in Settings.
+       @constant kABAuthorizationStatusAuthorized indicates the user has authorized this app to access the service. 
+ */
+
+typedef enum {
+    kABAuthorizationStatusNotDetermined = 0,
+    kABAuthorizationStatusRestricted,
+    kABAuthorizationStatusDenied,
+    kABAuthorizationStatusAuthorized
+} ABAuthorizationStatus;
+
diff --git a/sec/Security/Regressions/Security_regressions.h b/sec/Security/Regressions/Security_regressions.h
new file mode 100644 (file)
index 0000000..d6c3dc5
--- /dev/null
@@ -0,0 +1,75 @@
+/* To add a test:
+ 1) add it here
+ 2) Add it as command line argument for SecurityTest.app in the Release and Debug schemes
+ */
+#include <test/testmore.h>
+
+ONE_TEST(pbkdf2_00_hmac_sha1)
+ONE_TEST(spbkdf_00_hmac_sha1)
+
+ONE_TEST(si_00_find_nothing)
+ONE_TEST(si_05_add)
+ONE_TEST(si_10_find_internet)
+ONE_TEST(si_11_update_data)
+ONE_TEST(si_12_item_stress)
+ONE_TEST(si_14_dateparse)
+ONE_TEST(si_15_certificate)
+ONE_TEST(si_16_ec_certificate)
+ONE_TEST(si_20_sectrust_activation)
+ONE_TEST(si_20_sectrust)
+ONE_TEST(si_21_sectrust_asr)
+ONE_TEST(si_22_sectrust_iap)
+ONE_TEST(si_23_sectrust_ocsp)
+ONE_TEST(si_24_sectrust_itms)
+ONE_TEST(si_24_sectrust_nist)
+ONE_TEST(si_24_sectrust_otatasking)
+ONE_TEST(si_24_sectrust_mobileasset)
+ONE_TEST(si_24_sectrust_diginotar)
+ONE_TEST(si_24_sectrust_appleid)
+ONE_TEST(si_24_sectrust_digicert_malaysia)
+ONE_TEST(si_24_sectrust_shoebox)
+ONE_TEST(si_25_sectrust_ipsec_eap)
+ONE_TEST(si_26_applicationsigning)
+ONE_TEST(si_27_sectrust_exceptions)
+ONE_TEST(si_28_sectrustsettings)
+ONE_TEST(si_29_sectrust_codesigning)
+DISABLED_ONE_TEST(si_30_keychain_upgrade) //obsolete, needs updating
+ONE_TEST(si_31_keychain_bad)
+ONE_TEST(si_31_keychain_unreadable)
+ONE_TEST(si_33_keychain_backup)
+ONE_TEST(si_40_seckey)
+ONE_TEST(si_40_seckey_custom)
+ONE_TEST(si_41_sececkey)
+ONE_TEST(si_42_identity)
+ONE_TEST(si_43_persistent)
+ONE_TEST(si_50_secrandom)
+ONE_TEST(si_60_cms)
+DISABLED_ONE_TEST(si_61_pkcs12)
+ONE_TEST(si_62_csr)
+ONE_TEST(si_63_scep)
+ONE_TEST(si_64_ossl_cms)
+ONE_TEST(si_65_cms_cert_policy)
+ONE_TEST(si_66_smime)
+ONE_TEST(si_67_sectrust_blacklist)
+ONE_TEST(si_68_secmatchissuer)
+ONE_TEST(si_69_keydesc)
+ONE_TEST(si_70_sectrust_unified)
+ONE_TEST(si_71_mobile_store_policy)
+ONE_TEST(si_72_syncableitems)
+ONE_TEST(si_73_secpasswordgenerate)
+#if TARGET_OS_IPHONE
+ONE_TEST(si_74_OTA_PKI_Signer)
+ONE_TEST(si_75_AppleIDRecordSigning)
+#else
+DISABLED_ONE_TEST(si_74_OTA_PKI_Signer)
+DISABLED_ONE_TEST(si_75_AppleIDRecordSigning)
+#endif
+
+ONE_TEST(vmdh_40)
+ONE_TEST(vmdh_41_example)
+ONE_TEST(vmdh_42_example2)
+
+ONE_TEST(otr_00_identity)
+ONE_TEST(otr_30_negotiation)
+ONE_TEST(otr_otrdh)
+ONE_TEST(otr_packetdata)
diff --git a/sec/Security/Regressions/crypto/pbkdf2-00-hmac-sha1.c b/sec/Security/Regressions/crypto/pbkdf2-00-hmac-sha1.c
new file mode 100644 (file)
index 0000000..6b7901f
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2010 Apple Inc. All Rights Reserved.
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecItem.h>
+#include <Security/SecBase.h>
+#include <CommonCrypto/CommonHMAC.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <Security/pbkdf2.h>
+
+#include "Security_regressions.h"
+
+static
+void
+hmac_sha1(const uint8_t *key, size_t key_len, const uint8_t *text, size_t text_len,
+    uint8_t digest[CC_SHA1_DIGEST_LENGTH])
+{
+    CCHmacContext hmac_sha1_context;
+
+    CCHmacInit(&hmac_sha1_context, kCCHmacAlgSHA1, key, key_len);
+    CCHmacUpdate(&hmac_sha1_context, text, text_len);
+    CCHmacFinal(&hmac_sha1_context, digest);
+}
+
+static
+void
+pbkdf2_hmac_sha1_deriviation(const uint8_t *passphrase, size_t passphrase_length,
+                             const uint8_t *salt, size_t salt_length,
+                             size_t iterations,
+                             uint8_t *key_out, size_t key_length)
+{
+        // MAX(salt_length + 4, 20 /* SHA1 Digest size */) + 2 * 20;
+    uint8_t temp_data[3*20+salt_length];
+
+    pbkdf2(hmac_sha1, 20, passphrase, passphrase_length,
+                   salt, salt_length, iterations, key_out, key_length, temp_data);
+}
+
+
+
+#if 0
+static void
+printComparison(const uint8_t*left, const uint8_t* right, int length)
+{
+    int i;
+    for(i = 0; i < length; ++i)
+    {
+        fprintf(stderr, "#  Values :: 0x%02x :: 0x%02x\n", left[i], right[i]);
+    }
+}
+#endif
+
+static int kTestTestCount = 4;
+static void tests(void)
+{
+    {
+        const char *password =          "password";
+        const char *salt =              "salt";
+        const int iterations =          1;
+        const uint8_t expected[20] =  { 0x0c, 0x60, 0xc8, 0x0f,
+                                        0x96, 0x1f, 0x0e, 0x71,
+                                        0xf3, 0xa9, 0xb5, 0x24,
+                                        0xaf, 0x60, 0x12, 0x06,
+                                        0x2f, 0xe0, 0x37, 0xa6 };
+
+        const char resultSize = sizeof(expected);
+
+        uint8_t actual[resultSize];
+
+        pbkdf2_hmac_sha1_deriviation((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize);
+
+        ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-1: P-'password' S-'Salt' I-1");
+    }
+
+    {
+        const char *password =          "password";
+        const char *salt =              "salt";
+        const int iterations =          2;
+        const uint8_t expected[20] =  { 0xea, 0x6c, 0x01, 0x4d,
+                                        0xc7, 0x2d, 0x6f, 0x8c,
+                                        0xcd, 0x1e, 0xd9, 0x2a,
+                                        0xce, 0x1d, 0x41, 0xf0,
+                                        0xd8, 0xde, 0x89, 0x57 };
+
+        const char resultSize = sizeof(expected);
+
+        uint8_t actual[resultSize];
+
+        pbkdf2_hmac_sha1_deriviation((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize);
+
+        ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-1: P-'password' S-'Salt' I-2");
+    }
+
+    {
+        const char *password =          "password";
+        const char *salt =              "salt";
+        const int iterations =          4096;
+        const uint8_t expected[20] =  { 0x4b, 0x00, 0x79, 0x01,
+                                        0xb7, 0x65, 0x48, 0x9a,
+                                        0xbe, 0xad, 0x49, 0xd9,
+                                        0x26, 0xf7, 0x21, 0xd0,
+                                        0x65, 0xa4, 0x29, 0xc1 };
+
+        const char resultSize = sizeof(expected);
+
+        uint8_t actual[resultSize];
+
+        pbkdf2_hmac_sha1_deriviation((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize);
+
+        ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-1: P-'password' S-'Salt' I-4096");
+    }
+
+    SKIP: {
+        skip("16777216 iterations is too slow", 1, 0);
+
+        const char *password =          "password";
+        const char *salt =              "salt";
+        const int iterations =          16777216;
+        const uint8_t expected[20] =  { 0xee, 0xfe, 0x3d, 0x61,
+                                        0xcd, 0x4d, 0xa4, 0xe4,
+                                        0xe9, 0x94, 0x5b, 0x3d,
+                                        0x6b, 0xa2, 0x15, 0x8c,
+                                        0x26, 0x34, 0xe9, 0x84 };
+
+        const char resultSize = sizeof(expected);
+
+        uint8_t actual[resultSize];
+
+        pbkdf2_hmac_sha1_deriviation((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize);
+
+        ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-1: P-'password' S-'Salt' I-16777216");
+    }
+}
+
+int pbkdf2_00_hmac_sha1(int argc, char *const *argv)
+{
+       plan_tests(kTestTestCount);
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/crypto/spbkdf-00-hmac-sha1.c b/sec/Security/Regressions/crypto/spbkdf-00-hmac-sha1.c
new file mode 100644 (file)
index 0000000..25641ae
--- /dev/null
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2010 Apple Inc. All Rights Reserved.
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecInternal.h>
+#include <Security/SecItem.h>
+#include <Security/SecBase.h>
+#include <CommonCrypto/CommonHMAC.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <Security/SecPBKDF.h>
+
+#include "Security_regressions.h"
+
+#if 0
+static void
+printComparison(const uint8_t*left, const uint8_t* right, int length)
+{
+    int i;
+    for(i = 0; i < length; ++i)
+    {
+        fprintf(stderr, "#  Values :: 0x%02x :: 0x%02x\n", left[i], right[i]);
+    }
+}
+#endif
+
+static int kTestTestCount = 8;
+
+static void tests(void)
+{
+    {
+        const char *password =          "password";
+        const char *salt =              "salt";
+        const int iterations =          1;
+        const uint8_t expected[20] =  { 0x0c, 0x60, 0xc8, 0x0f,
+                                        0x96, 0x1f, 0x0e, 0x71,
+                                        0xf3, 0xa9, 0xb5, 0x24,
+                                        0xaf, 0x60, 0x12, 0x06,
+                                        0x2f, 0xe0, 0x37, 0xa6 };
+
+        const char resultSize = sizeof(expected);
+
+        uint8_t actual[resultSize];
+
+        pbkdf2_hmac_sha1((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize);
+
+        ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-1: P-'password' S-'Salt' I-1");
+    }
+
+    {
+        const char *password =          "password";
+        const char *salt =              "salt";
+        const int iterations =          2;
+        const uint8_t expected[20] =  { 0xea, 0x6c, 0x01, 0x4d,
+                                        0xc7, 0x2d, 0x6f, 0x8c,
+                                        0xcd, 0x1e, 0xd9, 0x2a,
+                                        0xce, 0x1d, 0x41, 0xf0,
+                                        0xd8, 0xde, 0x89, 0x57 };
+
+        const char resultSize = sizeof(expected);
+
+        uint8_t actual[resultSize];
+
+        pbkdf2_hmac_sha1((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize);
+
+        ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-1: P-'password' S-'Salt' I-2");
+    }
+
+    {
+        const char *password =          "password";
+        const char *salt =              "salt";
+        const int iterations =          4096;
+        const uint8_t expected[20] =  { 0x4b, 0x00, 0x79, 0x01,
+                                        0xb7, 0x65, 0x48, 0x9a,
+                                        0xbe, 0xad, 0x49, 0xd9,
+                                        0x26, 0xf7, 0x21, 0xd0,
+                                        0x65, 0xa4, 0x29, 0xc1 };
+
+        const char resultSize = sizeof(expected);
+
+        uint8_t actual[resultSize];
+
+        pbkdf2_hmac_sha1((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize);
+
+        ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-1: P-'password' S-'Salt' I-4096");
+    }
+
+    SKIP: {
+        skip("16777216 iterations is too slow", 1, 0);
+
+        const char *password =          "password";
+        const char *salt =              "salt";
+        const int iterations =          16777216;
+        const uint8_t expected[20] =  { 0xee, 0xfe, 0x3d, 0x61,
+                                        0xcd, 0x4d, 0xa4, 0xe4,
+                                        0xe9, 0x94, 0x5b, 0x3d,
+                                        0x6b, 0xa2, 0x15, 0x8c,
+                                        0x26, 0x34, 0xe9, 0x84 };
+
+        const char resultSize = sizeof(expected);
+
+        uint8_t actual[resultSize];
+
+        pbkdf2_hmac_sha1((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize);
+
+        ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-1: P-'password' S-'Salt' I-16777216");
+    }
+
+
+    {
+        CFStringRef password    = CFStringCreateWithCString(NULL, "password", kCFStringEncodingUTF8);
+        CFStringRef salt        = CFStringCreateWithCString(NULL, "salt", kCFStringEncodingUTF8);
+
+        CFDataRef   passwordData    = CFStringCreateExternalRepresentation(NULL, password, kCFStringEncodingUTF8, 0);
+        CFDataRef   saltData        = CFStringCreateExternalRepresentation(NULL, salt, kCFStringEncodingUTF8, 0);
+
+        const int iterations =          1;
+        const uint8_t expected[20] =  { 0x0c, 0x60, 0xc8, 0x0f,
+                                        0x96, 0x1f, 0x0e, 0x71,
+                                        0xf3, 0xa9, 0xb5, 0x24,
+                                        0xaf, 0x60, 0x12, 0x06,
+                                        0x2f, 0xe0, 0x37, 0xa6 };
+
+        const char resultSize = sizeof(expected);
+
+        CFMutableDataRef resultData = CFDataCreateMutable(NULL, resultSize);
+        CFDataIncreaseLength(resultData, resultSize);
+
+        SecKeyFromPassphraseDataHMACSHA1(passwordData, saltData, iterations, resultData);
+
+        ok(memcmp(expected, CFDataGetBytePtr(resultData), resultSize) == 0, "pbkdf-sha-1: P-'password' S-'Salt' I-1");
+
+        CFReleaseSafe(password);
+        CFReleaseSafe(salt);
+        CFReleaseSafe(passwordData);
+        CFReleaseSafe(saltData);
+        CFReleaseSafe(resultData);
+    }
+
+    {
+        CFStringRef password    = CFStringCreateWithCString(NULL, "password", kCFStringEncodingUTF8);
+        CFStringRef salt        = CFStringCreateWithCString(NULL, "salt", kCFStringEncodingUTF8);
+
+        CFDataRef   passwordData    = CFStringCreateExternalRepresentation(NULL, password, kCFStringEncodingUTF8, 0);
+        CFDataRef   saltData        = CFStringCreateExternalRepresentation(NULL, salt, kCFStringEncodingUTF8, 0);
+
+        const int iterations =          2;
+        const uint8_t expected[20] =  { 0xea, 0x6c, 0x01, 0x4d,
+                                        0xc7, 0x2d, 0x6f, 0x8c,
+                                        0xcd, 0x1e, 0xd9, 0x2a,
+                                        0xce, 0x1d, 0x41, 0xf0,
+                                        0xd8, 0xde, 0x89, 0x57 };
+
+        const char resultSize = sizeof(expected);
+
+        CFMutableDataRef resultData = CFDataCreateMutable(NULL, resultSize);
+        CFDataIncreaseLength(resultData, resultSize);
+
+        SecKeyFromPassphraseDataHMACSHA1(passwordData, saltData, iterations, resultData);
+
+        ok(memcmp(expected, CFDataGetBytePtr(resultData), resultSize) == 0, "pbkdf-sha-1: P-'password' S-'Salt' I-1");
+
+        CFReleaseSafe(password);
+        CFReleaseSafe(salt);
+        CFReleaseSafe(passwordData);
+        CFReleaseSafe(saltData);
+        CFReleaseSafe(resultData);
+    }
+
+    {
+        CFStringRef password    = CFStringCreateWithCString(NULL, "password", kCFStringEncodingUTF8);
+        CFStringRef salt        = CFStringCreateWithCString(NULL, "salt", kCFStringEncodingUTF8);
+
+        CFDataRef   passwordData    = CFStringCreateExternalRepresentation(NULL, password, kCFStringEncodingUTF8, 0);
+        CFDataRef   saltData        = CFStringCreateExternalRepresentation(NULL, salt, kCFStringEncodingUTF8, 0);
+
+        const int iterations =          4096;
+        const uint8_t expected[20] =  { 0x4b, 0x00, 0x79, 0x01,
+                                        0xb7, 0x65, 0x48, 0x9a,
+                                        0xbe, 0xad, 0x49, 0xd9,
+                                        0x26, 0xf7, 0x21, 0xd0,
+                                        0x65, 0xa4, 0x29, 0xc1 };
+
+
+        const char resultSize = sizeof(expected);
+
+        CFMutableDataRef resultData = CFDataCreateMutable(NULL, resultSize);
+        CFDataIncreaseLength(resultData, resultSize);
+
+        SecKeyFromPassphraseDataHMACSHA1(passwordData, saltData, iterations, resultData);
+
+        ok(memcmp(expected, CFDataGetBytePtr(resultData), resultSize) == 0, "pbkdf-sha-1: P-'password' S-'Salt' I-1");
+
+        CFReleaseSafe(password);
+        CFReleaseSafe(salt);
+        CFReleaseSafe(passwordData);
+        CFReleaseSafe(saltData);
+        CFReleaseSafe(resultData);
+    }
+
+    SKIP: {
+        skip("16777216 iterations is too slow", 1, 0);
+
+        CFStringRef password    = CFStringCreateWithCString(NULL, "password", kCFStringEncodingUTF8);
+        CFStringRef salt        = CFStringCreateWithCString(NULL, "salt", kCFStringEncodingUTF8);
+
+        CFDataRef   passwordData    = CFStringCreateExternalRepresentation(NULL, password, kCFStringEncodingUTF8, 0);
+        CFDataRef   saltData        = CFStringCreateExternalRepresentation(NULL, salt, kCFStringEncodingUTF8, 0);
+
+        const int iterations =          16777216;
+        const uint8_t expected[20] =  { 0xee, 0xfe, 0x3d, 0x61,
+                                        0xcd, 0x4d, 0xa4, 0xe4,
+                                        0xe9, 0x94, 0x5b, 0x3d,
+                                        0x6b, 0xa2, 0x15, 0x8c,
+                                        0x26, 0x34, 0xe9, 0x84 };
+
+
+        const char resultSize = sizeof(expected);
+
+        CFMutableDataRef resultData = CFDataCreateMutable(NULL, resultSize);
+        CFDataIncreaseLength(resultData, resultSize);
+
+        SecKeyFromPassphraseDataHMACSHA1(passwordData, saltData, iterations, resultData);
+
+        ok(memcmp(expected, CFDataGetBytePtr(resultData), resultSize) == 0, "pbkdf-sha-1: P-'password' S-'Salt' I-1");
+
+        CFReleaseSafe(password);
+        CFReleaseSafe(salt);
+        CFReleaseSafe(passwordData);
+        CFReleaseSafe(saltData);
+        CFReleaseSafe(resultData);
+    }
+
+}
+
+int spbkdf_00_hmac_sha1(int argc, char *const *argv)
+{
+       plan_tests(kTestTestCount);
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/otr/otr-00-identity.c b/sec/Security/Regressions/otr/otr-00-identity.c
new file mode 100644 (file)
index 0000000..8787271
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ *  mp-00-identity.c
+ *  regressions
+ *
+ *  Created by Mitch Adler on 2/3/11.
+ *  Copyright 2011 Apple Inc. All rights reserved.
+ *
+ */
+
+#include <stdio.h>
+
+#include "Security_regressions.h"
+
+#include <CoreFoundation/CFData.h>
+#include <Security/SecOTRSession.h>
+#include <Security/SecInternal.h>
+#include <Security/SecBasePriv.h>
+
+static void RegressionsLogError(CFErrorRef error) {
+    if (error == NULL) {
+        return;
+    }
+    CFDictionaryRef tempDictionary = CFErrorCopyUserInfo(error);
+    CFIndex errorCode = CFErrorGetCode(error);
+    CFStringRef errorDomain = CFErrorGetDomain(error);
+    CFStringRef errorString = CFDictionaryGetValue(tempDictionary, kCFErrorDescriptionKey);
+    CFErrorRef previousError = (CFErrorRef)CFDictionaryGetValue(tempDictionary, kCFErrorUnderlyingErrorKey);
+    if (previousError != NULL) {
+        RegressionsLogError(previousError);
+    }
+    char errorDomainStr[1024];
+    char errorStringStr[1024];
+    
+    CFStringGetCString(errorDomain, errorDomainStr, 1024, kCFStringEncodingUTF8);
+    CFStringGetCString(errorString, errorStringStr, 1024, kCFStringEncodingUTF8);
+    printf("OTR: %s (%ld) -- %s\n", errorDomainStr, errorCode, errorStringStr);
+    CFReleaseSafe(tempDictionary);
+}
+
+static int kTestTestCount = 18;
+static void tests(void)
+{
+    CFErrorRef testError = NULL;
+    
+    SecOTRFullIdentityRef idToPurge = SecOTRFullIdentityCreate(kCFAllocatorDefault, &testError);
+    RegressionsLogError(testError);
+    CFReleaseNull(testError);
+    
+    ok(idToPurge != NULL, "Make Identity");
+    
+    CFMutableDataRef purgeExport = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    
+    ok(SecOTRFIAppendSerialization(idToPurge, purgeExport, &testError), "First export");
+    RegressionsLogError(testError);
+    CFReleaseNull(testError);
+    
+    SecOTRFullIdentityRef purgeIdInflate = SecOTRFullIdentityCreateFromData(kCFAllocatorDefault, purgeExport, &testError);
+    RegressionsLogError(testError);
+    CFReleaseNull(testError);
+    
+    ok(purgeIdInflate != NULL, "Inflate Identity");
+
+    SecOTRFIPurgeFromKeychain(idToPurge, &testError);
+    RegressionsLogError(testError);
+    CFReleaseNull(testError);
+
+    SecOTRFullIdentityRef failIDInflate = SecOTRFullIdentityCreateFromData(kCFAllocatorDefault, purgeExport, &testError);
+    RegressionsLogError(testError);
+    CFReleaseNull(testError);
+  
+    ok(failIDInflate == NULL, "Should fail");
+
+    CFReleaseSafe(idToPurge);
+
+
+    idToPurge = SecOTRFullIdentityCreate(kCFAllocatorDefault, &testError);
+    RegressionsLogError(testError);
+    CFReleaseNull(testError);
+    
+    ok(idToPurge != NULL, "Make Identity again");
+
+    SecOTRFIPurgeAllFromKeychain(&testError);
+    RegressionsLogError(testError);
+    CFReleaseNull(testError);
+
+    SecOTRFullIdentityRef failIDInflate2 = SecOTRFullIdentityCreateFromData(kCFAllocatorDefault, purgeExport, &testError);
+    RegressionsLogError(testError);
+    CFReleaseNull(testError);
+    
+    ok(failIDInflate2 == NULL, "Should fail 2");
+
+    SecOTRFullIdentityRef id = SecOTRFullIdentityCreate(kCFAllocatorDefault, &testError);
+    RegressionsLogError(testError);
+    CFReleaseNull(testError);
+    
+    ok(id != NULL, "Make Identity");
+
+    CFMutableDataRef firstExport = CFDataCreateMutable(kCFAllocatorDefault, 0);
+
+    ok(SecOTRFIAppendSerialization(id, firstExport, &testError), "First export");
+    RegressionsLogError(testError);
+    CFReleaseNull(testError);
+
+    SecOTRFullIdentityRef idInflate = SecOTRFullIdentityCreateFromData(kCFAllocatorDefault, firstExport, &testError);
+    RegressionsLogError(testError);
+    CFReleaseNull(testError);
+    
+    ok(idInflate != NULL, "Inflate Identity");
+
+
+    CFMutableDataRef secondExport = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    
+    ok(SecOTRFIAppendSerialization(idInflate, secondExport, &testError), "second export");
+    RegressionsLogError(testError);
+    CFReleaseNull(testError);
+
+    ok(CFDataGetLength(firstExport) == CFDataGetLength(secondExport)
+       && 0 == memcmp(CFDataGetBytePtr(firstExport), CFDataGetBytePtr(secondExport), (size_t)CFDataGetLength(firstExport)), "Different exports");
+    
+    SecOTRPublicIdentityRef pubID = SecOTRPublicIdentityCopyFromPrivate(kCFAllocatorDefault, id, &testError);
+    RegressionsLogError(testError);
+    CFReleaseNull(testError);
+    
+    ok(id != NULL, "Failed to copy public identity");
+    
+    CFMutableDataRef firstPublicExport = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    
+    ok(SecOTRPIAppendSerialization(pubID, firstPublicExport, &testError), "failed first public export");
+    RegressionsLogError(testError);
+    CFReleaseNull(testError);
+
+    SecOTRPublicIdentityRef pubIDInflate = SecOTRPublicIdentityCreateFromData(kCFAllocatorDefault, firstPublicExport, &testError);
+    RegressionsLogError(testError);
+    CFReleaseNull(testError);
+    
+    ok(pubIDInflate != NULL, "Pub inflate failed");
+    
+    CFMutableDataRef secondPublicExport = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    
+    ok(SecOTRPIAppendSerialization(pubID, secondPublicExport, &testError), "failed second public export");
+    RegressionsLogError(testError);
+    CFReleaseNull(testError);
+
+    ok(CFDataGetLength(firstPublicExport) == CFDataGetLength(secondPublicExport) 
+       && 0 == memcmp(CFDataGetBytePtr(firstPublicExport), CFDataGetBytePtr(secondPublicExport), (size_t)CFDataGetLength(firstPublicExport)), "Different public exports");
+
+    uint8_t sampleByteString[] = {
+        0x30, 0x81, 0xf6, 0x81, 0x43, 0x00, 0x41, 0x04, 0xc6, 0x8a, 0x2a, 0x5c, 0x29, 0xa4, 0xb7, 0x58,
+        0xe1, 0x3c, 0x07, 0x19, 0x20, 0xf3, 0x0b, 0xb8, 0xb3, 0x40, 0x41, 0x29, 0x4a, 0xa6, 0x7a, 0x56,
+        0x28, 0x6d, 0x10, 0x85, 0x2b, 0x14, 0x83, 0xaa, 0x1f, 0x6a, 0x47, 0xbc, 0x19, 0x26, 0x39, 0x1c,
+        0xd4, 0xbb, 0x8c, 0xd6, 0x94, 0x24, 0x79, 0x60, 0xfb, 0x8e, 0x4b, 0xf4, 0x0f, 0xbf, 0x38, 0x81,
+        0x78, 0xce, 0x1d, 0xd9, 0x03, 0xec, 0x65, 0xcd, 0x82, 0x81, 0xae, 0x00, 0xac, 0x30, 0x81, 0xa9,
+        0x02, 0x81, 0xa1, 0x00, 0xd2, 0xf4, 0x40, 0x8b, 0x2f, 0x09, 0x75, 0x2c, 0x68, 0x12, 0x76, 0xb9,
+        0xfb, 0x1b, 0x02, 0x91, 0x6d, 0xd7, 0x86, 0x49, 0xdc, 0xef, 0x38, 0xf3, 0x50, 0x58, 0xb5, 0xff,
+        0x5c, 0x02, 0x8a, 0xb0, 0xcd, 0xb3, 0x3d, 0x94, 0x71, 0x7d, 0x32, 0x53, 0xed, 0x43, 0xfb, 0xde,
+        0xbc, 0x20, 0x21, 0x33, 0xe3, 0xeb, 0x93, 0x48, 0xe8, 0xd1, 0x32, 0x2f, 0x40, 0x40, 0x47, 0x1f,
+        0xeb, 0x7e, 0xf6, 0x43, 0x81, 0x51, 0xd6, 0x4f, 0xe0, 0x57, 0xbf, 0x12, 0xeb, 0x18, 0x2e, 0x81,
+        0x0b, 0x3a, 0x04, 0xf1, 0xeb, 0x3c, 0xe1, 0xb9, 0xf4, 0x87, 0x37, 0x83, 0x5a, 0x2e, 0x09, 0xf8,
+        0xd5, 0xa0, 0x12, 0xfb, 0x35, 0xe4, 0xd4, 0x3f, 0xef, 0x24, 0x3e, 0x6c, 0xff, 0xb1, 0x35, 0x7e,
+        0x9f, 0xe7, 0x6d, 0x2f, 0xf8, 0x0d, 0xc6, 0xbc, 0x19, 0xe2, 0x78, 0xb3, 0x71, 0xe1, 0x35, 0xe7,
+        0xc7, 0x22, 0x6b, 0x4d, 0x92, 0xc4, 0x10, 0x75, 0x1a, 0x9b, 0x9f, 0x7f, 0xac, 0x2d, 0xfb, 0xc9,
+        0x64, 0x1e, 0x80, 0x11, 0x7f, 0x75, 0x8a, 0x86, 0x7e, 0x09, 0x44, 0xc4, 0x71, 0xbf, 0xd4, 0xfa,
+        0x8b, 0x6a, 0xb8, 0x9f, 0x02, 0x03, 0x01, 0x00,
+        0x01}; 
+    
+    CFDataRef testInteropImport = CFDataCreate(kCFAllocatorDefault, sampleByteString, sizeof(sampleByteString));
+    SecOTRPublicIdentityRef interopIDInflate = SecOTRPublicIdentityCreateFromData(kCFAllocatorDefault, testInteropImport, &testError);
+    RegressionsLogError(testError);
+    CFReleaseNull(testError);
+    ok(interopIDInflate != NULL, "Interop inflate failed");
+    
+    /* cleanup keychain */
+    ok(SecOTRFIPurgeAllFromKeychain(&testError),"cleanup keychain");
+    RegressionsLogError(testError);
+    CFReleaseNull(testError);
+
+    CFReleaseSafe(pubID);
+    CFReleaseSafe(pubIDInflate);
+    CFReleaseSafe(firstPublicExport);
+    CFReleaseSafe(secondPublicExport);
+    CFReleaseSafe(id);
+    CFReleaseSafe(idToPurge);
+    CFReleaseSafe(idInflate);
+    CFReleaseSafe(firstExport);
+    CFReleaseSafe(secondExport);
+    CFReleaseSafe(purgeExport);
+    CFReleaseSafe(purgeIdInflate);
+    CFReleaseSafe(failIDInflate);
+    CFReleaseSafe(failIDInflate2);
+    CFReleaseSafe(testInteropImport);
+    CFReleaseSafe(interopIDInflate);
+    
+}
+
+int otr_00_identity(int argc, char *const *argv)
+{
+    plan_tests(kTestTestCount);
+    
+       tests();
+    
+       return 0;    
+}
diff --git a/sec/Security/Regressions/otr/otr-30-negotiation.c b/sec/Security/Regressions/otr/otr-30-negotiation.c
new file mode 100644 (file)
index 0000000..0f84439
--- /dev/null
@@ -0,0 +1,295 @@
+//
+//  otr-30-negotiation.c
+//  regressions
+//
+//  Created by Mitch Adler on 6/7/11.
+//  Copyright 2011 Apple Inc. All rights reserved.
+//
+
+#include "Security_regressions.h"
+
+#include <CoreFoundation/CFData.h>
+#include <Security/SecOTRSession.h>
+#include <Security/SecInternal.h>
+#include <Security/SecBasePriv.h>
+
+static void SecMPLogError(CFErrorRef error) {
+    if (error == NULL) {
+        return;
+    }
+    CFDictionaryRef tempDictionary = CFErrorCopyUserInfo(error);
+    CFIndex errorCode = CFErrorGetCode(error);
+    CFStringRef errorDomain = CFErrorGetDomain(error);
+    CFStringRef errorString = CFDictionaryGetValue(tempDictionary, kCFErrorDescriptionKey);
+    CFErrorRef previousError = (CFErrorRef)CFDictionaryGetValue(tempDictionary, kCFErrorUnderlyingErrorKey);
+    if (previousError != NULL) {
+        SecMPLogError(previousError);
+    }
+    char errorDomainStr[1024];
+    char errorStringStr[1024];
+    
+    CFStringGetCString(errorDomain, errorDomainStr, 1024, kCFStringEncodingUTF8);
+    CFStringGetCString(errorString, errorStringStr, 1024, kCFStringEncodingUTF8);
+    printf("MessageProtection: %s (%ld) -- %s\n", errorDomainStr, errorCode, errorStringStr);
+    CFReleaseSafe(tempDictionary);
+}
+
+static void serializeAndDeserialize(SecOTRSessionRef* thisOne)
+{
+    CFMutableDataRef serialized = CFDataCreateMutable(kCFAllocatorDefault, 0);
+
+    SecOTRSAppendSerialization(*thisOne, serialized);
+    CFReleaseNull(*thisOne);
+    *thisOne = SecOTRSessionCreateFromData(kCFAllocatorDefault, serialized);
+
+    CFReleaseSafe(serialized);
+}
+
+
+
+#define sendMessagesCount(n) ((n) * 8)
+static void sendMessages(int howMany, SecOTRSessionRef *bobSession, SecOTRSessionRef *aliceSession, bool serialize)
+{
+    for(int count = howMany; count > 0; --count) {
+        const char* aliceToBob = "aliceToBob";
+        CFDataRef rawAliceToBob = CFDataCreate(kCFAllocatorDefault, (const uint8_t*)aliceToBob, (CFIndex) strlen(aliceToBob));
+        CFMutableDataRef protectedAliceToBob = CFDataCreateMutable(kCFAllocatorDefault, 0);
+        CFMutableDataRef bobDecode = CFDataCreateMutable(kCFAllocatorDefault, 0);
+
+        ok_status(SecOTRSSignAndProtectMessage(*aliceSession, rawAliceToBob, protectedAliceToBob), "encode message");
+        ok_status(SecOTRSVerifyAndExposeMessage(*bobSession, protectedAliceToBob, bobDecode), "Decode message");
+
+        if (serialize) {
+            serializeAndDeserialize(bobSession);
+            serializeAndDeserialize(aliceSession);
+        }
+
+        ok(CFDataGetLength(rawAliceToBob) == CFDataGetLength(bobDecode)
+           && 0 == memcmp(CFDataGetBytePtr(rawAliceToBob), CFDataGetBytePtr(bobDecode), (size_t)CFDataGetLength(rawAliceToBob)), "Didn't match!");
+
+        CFReleaseNull(rawAliceToBob);
+        CFReleaseNull(protectedAliceToBob);
+        CFReleaseNull(bobDecode);
+
+        const char* bobToAlice = "i liked your silly message from me to you";
+        CFDataRef rawBobToAlice = CFDataCreate(kCFAllocatorDefault, (const uint8_t*)bobToAlice, (CFIndex) strlen(bobToAlice));
+        CFMutableDataRef protectedBobToAlice = CFDataCreateMutable(kCFAllocatorDefault, 0);
+        CFMutableDataRef aliceDecode = CFDataCreateMutable(kCFAllocatorDefault, 0);
+
+        ok_status(SecOTRSSignAndProtectMessage(*bobSession, rawBobToAlice, protectedBobToAlice), "encode reply");
+        ok_status(SecOTRSVerifyAndExposeMessage(*aliceSession, protectedBobToAlice, aliceDecode), "decode reply");
+
+        if (serialize) {
+            serializeAndDeserialize(bobSession);
+            serializeAndDeserialize(aliceSession);
+        }
+
+        ok(CFDataGetLength(rawBobToAlice) == CFDataGetLength(aliceDecode)
+           && 0 == memcmp(CFDataGetBytePtr(rawBobToAlice), CFDataGetBytePtr(aliceDecode), (size_t)CFDataGetLength(rawBobToAlice)), "reply matched");
+
+        CFReleaseNull(rawAliceToBob);
+        CFReleaseNull(protectedAliceToBob);
+        CFReleaseNull(aliceDecode);
+
+        CFStringRef stateString = CFCopyDescription(*bobSession);
+        ok(stateString, "getting state from bob");
+        CFReleaseNull(stateString);
+
+        stateString = CFCopyDescription(*aliceSession);
+        ok(stateString, "getting state from alice");
+        CFReleaseNull(stateString);
+    }
+}
+
+#define kNegotiateTestCount (14 + sendMessagesCount(5) \
+                               + 2 + sendMessagesCount(1) \
+                               + 1 + sendMessagesCount(1))
+static void negotiate(SecOTRSessionRef* aliceSession, SecOTRSessionRef* bobSession, bool serialize)
+{
+    // Step 1: Create a start packet for each side of the transaction
+    CFMutableDataRef bobStartPacket = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    
+    ok_status(SecOTRSAppendStartPacket(*bobSession, bobStartPacket), "Bob start packet");
+    
+    if (serialize)
+        serializeAndDeserialize(bobSession);
+    
+    CFMutableDataRef aliceStartPacket = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    
+    ok_status(SecOTRSAppendStartPacket(*aliceSession, aliceStartPacket), "Alice start packet");
+    
+    if (serialize)
+        serializeAndDeserialize(aliceSession);
+    
+    // Step 2: Exchange the start packets, forcing the DH commit messages to collide
+    CFMutableDataRef aliceDHKeyResponse = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    
+    ok_status(SecOTRSProcessPacket(*aliceSession, bobStartPacket, aliceDHKeyResponse),
+              "Bob DH packet failed");
+    
+    if (serialize)
+        serializeAndDeserialize(aliceSession);
+    
+    CFReleaseNull(bobStartPacket);
+    
+    CFMutableDataRef bobDHKeyResponse = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    
+    ok_status(SecOTRSProcessPacket(*bobSession, aliceStartPacket, bobDHKeyResponse),
+              "Alice DH packet failed");
+    
+    if (serialize)
+        serializeAndDeserialize(bobSession);
+    
+    CFReleaseNull(aliceStartPacket);
+    
+    // Step 3: With one "real" DH key message, and one replayed DH commit message, try to get a "reveal sig" out of one side
+    
+    CFMutableDataRef bobRevealSigResponse = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    
+    ok_status(SecOTRSProcessPacket(*bobSession, aliceDHKeyResponse, bobRevealSigResponse),
+              "Alice DH Key packet failed");
+    
+    if (serialize)
+        serializeAndDeserialize(bobSession);
+    
+    CFReleaseNull(aliceDHKeyResponse);
+    
+    CFMutableDataRef aliceRevealSigResponse = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    
+    ok_status(SecOTRSProcessPacket(*aliceSession, bobDHKeyResponse, aliceRevealSigResponse),
+              "Bob DH Key packet failed");
+    
+    if (serialize)
+        serializeAndDeserialize(aliceSession);
+    
+    CFReleaseNull(bobDHKeyResponse);
+    
+    // Step 4: Having gotten the reveal signature, now work for the signature
+    
+    CFMutableDataRef aliceSigResponse = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    
+    ok_status(SecOTRSProcessPacket(*aliceSession, bobRevealSigResponse, aliceSigResponse),
+              "Bob Reveal sig failed");
+    
+    if (serialize)
+        serializeAndDeserialize(aliceSession);
+    
+    CFReleaseNull(bobRevealSigResponse);
+    
+    CFMutableDataRef bobSigResponse = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    
+    ok_status(SecOTRSProcessPacket(*bobSession, aliceRevealSigResponse, bobSigResponse),
+              "Alice Reveal sig failed");
+    
+    if (serialize)
+        serializeAndDeserialize(bobSession);
+    
+    CFReleaseNull(aliceRevealSigResponse);
+    
+    // Step 5: All the messages have been sent, now deal with any replays from the collision handling
+    CFMutableDataRef bobFinalResponse = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    
+    ok_status(SecOTRSProcessPacket(*bobSession, aliceSigResponse, bobFinalResponse),
+              "Alice Final Sig failed");
+    
+    if (serialize)
+        serializeAndDeserialize(bobSession);
+    
+    CFMutableDataRef aliceFinalResponse = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    
+    ok_status(SecOTRSProcessPacket(*aliceSession, bobSigResponse, aliceFinalResponse),
+              "Bob Final Sig failed");
+
+    if (serialize)
+        serializeAndDeserialize(aliceSession);
+    
+    is(6, CFDataGetLength(bobFinalResponse), "Alice had nothing left to say");
+    is(6, CFDataGetLength(bobFinalResponse), "Bob had nothing left to say");
+    ok(SecOTRSGetIsReadyForMessages(*bobSession), "Bob is ready");
+    ok(SecOTRSGetIsReadyForMessages(*aliceSession), "Alice is ready");
+
+    CFReleaseNull(aliceSigResponse);
+    CFReleaseNull(bobFinalResponse);
+
+    sendMessages(5, bobSession, aliceSession, serialize);
+
+    const char* aliceToBob = "deferredMessage";
+    CFDataRef rawAliceToBob = CFDataCreate(kCFAllocatorDefault, (const uint8_t*)aliceToBob, (CFIndex) strlen(aliceToBob));
+    CFMutableDataRef protectedAliceToBob = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    CFMutableDataRef bobDecode = CFDataCreateMutable(kCFAllocatorDefault, 0);
+
+    ok_status(SecOTRSSignAndProtectMessage(*aliceSession, rawAliceToBob, protectedAliceToBob), "encode message");
+
+    sendMessages(1, bobSession, aliceSession, serialize);
+
+    ok(errSecOTRTooOld ==SecOTRSVerifyAndExposeMessage(*bobSession, protectedAliceToBob, bobDecode), "Decode old message");
+
+    sendMessages(1, bobSession, aliceSession, serialize);
+
+    ok(errSecOTRTooOld == SecOTRSVerifyAndExposeMessage(*bobSession, protectedAliceToBob, bobDecode), "Fail to decode excessively old message");
+
+    CFReleaseNull(rawAliceToBob);
+    CFReleaseNull(protectedAliceToBob);
+    CFReleaseNull(bobDecode);
+}
+
+
+#define kTestTestCount (7 + kNegotiateTestCount)
+
+static void tests()
+{
+    CFErrorRef testError = NULL;
+    SecOTRFullIdentityRef aliceID = SecOTRFullIdentityCreate(kCFAllocatorDefault, &testError);
+    SecMPLogError(testError);
+    CFReleaseNull(testError);
+    testError = NULL;
+    SecOTRFullIdentityRef bobID = SecOTRFullIdentityCreate(kCFAllocatorDefault, &testError);
+    SecMPLogError(testError);
+    CFReleaseNull(testError);
+    testError = NULL;
+
+    ok(aliceID, "create alice ID");
+    ok(bobID, "create bob ID");
+
+    SecOTRPublicIdentityRef alicePublicID = SecOTRPublicIdentityCopyFromPrivate(kCFAllocatorDefault, aliceID, &testError);
+    SecMPLogError(testError);
+    CFReleaseNull(testError);
+    SecOTRPublicIdentityRef bobPublicID = SecOTRPublicIdentityCopyFromPrivate(kCFAllocatorDefault, bobID, &testError);
+    SecMPLogError(testError);
+    CFReleaseNull(testError);
+
+    ok(alicePublicID, "extract alice public");
+    ok(bobPublicID, "extract bob public");
+
+    SecOTRSessionRef aliceSession = SecOTRSessionCreateFromIDAndFlags(kCFAllocatorDefault, aliceID, bobPublicID, kSecOTRSendTextMessages);
+    SecOTRSessionRef bobSession = SecOTRSessionCreateFromIDAndFlags(kCFAllocatorDefault, bobID, alicePublicID, kSecOTRSendTextMessages);
+
+    ok(aliceSession, "create alice session");
+    ok(bobSession, "create bob session");
+
+    // Release the IDs, sessions shouldn't need us to retain them for them.
+    CFReleaseNull(aliceID);
+    CFReleaseNull(bobID);
+
+    CFReleaseNull(alicePublicID);
+    CFReleaseNull(bobPublicID);
+
+    negotiate(&aliceSession, &bobSession, true);
+
+    /* cleanup keychain */
+    ok(SecOTRFIPurgeAllFromKeychain(&testError),"cleanup keychain");
+    SecMPLogError(testError);
+    CFReleaseNull(testError);
+
+    CFReleaseNull(aliceSession);
+    CFReleaseNull(bobSession);
+}
+
+int otr_30_negotiation(int argc, char *const *argv)
+{
+    plan_tests(kTestTestCount);
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/otr/otr-otrdh.c b/sec/Security/Regressions/otr/otr-otrdh.c
new file mode 100644 (file)
index 0000000..0c8cacc
--- /dev/null
@@ -0,0 +1,45 @@
+//
+//  otr-otrdh.c
+//  OTR
+//
+//  Created by Mitch Adler on 7/22/11.
+//  Copyright (c) 2011 Apple Inc. All rights reserved.
+//
+
+#include "Security_regressions.h"
+
+#include <Security/SecOTRMath.h>
+#include <Security/SecOTRDHKey.h>
+
+int otr_otrdh(int argc, char *const * argv)
+{
+    plan_tests(4);
+    
+    SecOTRFullDHKeyRef aliceFull = SecOTRFullDHKCreate(kCFAllocatorDefault);
+    SecOTRPublicDHKeyRef alicePublic = SecOTRPublicDHKCreateFromFullKey(kCFAllocatorDefault, aliceFull);
+    
+    SecOTRFullDHKeyRef bobFull = SecOTRFullDHKCreate(kCFAllocatorDefault);
+    SecOTRPublicDHKeyRef bobPublic = SecOTRPublicDHKCreateFromFullKey(kCFAllocatorDefault, bobFull);
+    
+    uint8_t aliceMessageKeys[2][kOTRMessageKeyBytes];
+    uint8_t aliceMacKeys[2][kOTRMessageMacKeyBytes];
+    
+    SecOTRDHKGenerateOTRKeys(aliceFull, bobPublic,
+                          aliceMessageKeys[0], aliceMacKeys[0],
+                          aliceMessageKeys[1], aliceMacKeys[1]);
+    
+    uint8_t bobMessageKeys[2][kOTRMessageKeyBytes];
+    uint8_t bobMacKeys[2][kOTRMessageMacKeyBytes];
+    
+    SecOTRDHKGenerateOTRKeys(bobFull, alicePublic,
+                          bobMessageKeys[0], bobMacKeys[0],
+                          bobMessageKeys[1], bobMacKeys[1]);
+    
+    
+    ok(0 == memcmp(aliceMessageKeys[0], bobMessageKeys[1], sizeof(aliceMessageKeys[0])), "Mac Keys don't match!!");
+    ok(0 == memcmp(aliceMessageKeys[1], bobMessageKeys[0], sizeof(aliceMessageKeys[1])), "Mac Keys don't match!!");
+    ok(0 == memcmp(aliceMacKeys[0], bobMacKeys[1], sizeof(aliceMacKeys[0])), "Mac Keys don't match!!");
+    ok(0 == memcmp(aliceMacKeys[1], bobMacKeys[0], sizeof(aliceMacKeys[1])), "Mac Keys don't match!!");
+    
+    return 0;
+}
diff --git a/sec/Security/Regressions/otr/otr-packetdata.c b/sec/Security/Regressions/otr/otr-packetdata.c
new file mode 100644 (file)
index 0000000..4e6d22f
--- /dev/null
@@ -0,0 +1,185 @@
+//
+//  otr-packetdata.c
+//  OTR
+//
+//  Created by Mitch Adler on 7/22/11.
+//  Copyright (c) 2011 Apple Inc. All rights reserved.
+//
+
+#include <CoreFoundation/CFData.h>
+#include "SecOTRPacketData.h"
+
+#include <corecrypto/ccn.h>
+
+#include "security_regressions.h"
+
+static bool CFDataMatches(CFDataRef data, size_t amount, const uint8_t* bytes)
+{
+    if ((size_t) CFDataGetLength(data) != amount)
+        return false;
+    
+    return 0 == memcmp(CFDataGetBytePtr(data), bytes, amount);
+    
+}
+
+
+static void testAppendShort()
+{
+    CFMutableDataRef result = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    
+    const uint8_t firstResult[] = { 1, 2 };
+    AppendShort(result, 0x0102);
+    ok(CFDataMatches(result, sizeof(firstResult), firstResult), "Didn't insert correctly");
+    
+    const uint8_t secondResult[] = { 1, 2, 3, 4};
+    AppendShort(result, 0x0304);
+    ok(CFDataMatches(result, sizeof(secondResult), secondResult), "Didn't append!");
+    
+    CFRelease(result);
+    
+    result = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    
+    const uint8_t thirdResult[] = { 0, 0 };
+    AppendShort(result, 0x0);
+    ok(CFDataMatches(result, sizeof(thirdResult), thirdResult), "Didn't insert zero");
+    
+    CFRelease(result);
+    
+    result = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    
+    const uint8_t fourthResult[] = { 0xFF, 0xFF};
+    AppendShort(result, 0xFFFF);
+    ok(CFDataMatches(result, sizeof(thirdResult), fourthResult), "Didn't insert 0xFFFFFFFF");
+    
+    CFRelease(result);
+}
+
+static void testAppendLong()
+{
+    CFMutableDataRef result = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    
+    const uint8_t firstResult[] = { 1, 2, 3, 4 };
+    AppendLong(result, 0x01020304);
+    ok(CFDataMatches(result, sizeof(firstResult), firstResult), "Didn't insert correctly");
+    
+    const uint8_t secondResult[] = { 1, 2, 3, 4, 5, 6, 7, 8};
+    AppendLong(result, 0x05060708);
+    ok(CFDataMatches(result, sizeof(secondResult), secondResult), "Didn't append!");
+    
+    CFRelease(result);
+    
+    result = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    
+    const uint8_t thirdResult[] = { 0, 0, 0, 0 };
+    AppendLong(result, 0x0);
+    ok(CFDataMatches(result, sizeof(thirdResult), thirdResult), "Didn't insert zero");
+    
+    CFRelease(result);
+    
+    result = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    
+    const uint8_t fourthResult[] = { 0xFF, 0xFF, 0xFF, 0xFF };
+    AppendLong(result, 0xFFFFFFFF);
+    ok(CFDataMatches(result, sizeof(thirdResult), fourthResult), "Didn't insert 0xFFFFFFFF");
+    
+    CFRelease(result);
+}
+
+static void testAppendData()
+{
+    CFMutableDataRef result = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    
+    const uint8_t firstResult[] = { 0, 0, 0, 4, 1, 2, 3, 4 };
+    AppendDATA(result, sizeof(firstResult) - 4, firstResult + 4);
+    ok(CFDataMatches(result, sizeof(firstResult), firstResult), "Didn't insert correctly");
+    
+    const uint8_t secondResult[] = { 0, 0, 0, 4, 1, 2, 3, 4, 0, 0, 0, 1, 0 };
+    AppendDATA(result, sizeof(secondResult) - 12, secondResult + 12);
+    ok(CFDataMatches(result, sizeof(secondResult), secondResult), "Didn't append!");
+    
+    CFRelease(result);
+    
+    result = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    
+    const uint8_t thirdResult[] = { 0, 0, 0, 2, 0, 0 };
+    AppendDATA(result, sizeof(thirdResult) - 4, thirdResult + 4);
+    ok(CFDataMatches(result, sizeof(thirdResult), thirdResult), "Didn't insert correctly");
+    
+    CFRelease(result);
+    
+    result = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    
+    const uint8_t fourthResult[] = { 0, 0, 0, 5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+    AppendDATA(result, sizeof(fourthResult) - 4, fourthResult + 4);
+    ok(CFDataMatches(result, sizeof(fourthResult), fourthResult), "Didn't insert correctly");
+    
+    CFRelease(result);
+}
+
+
+static void testAppendMPI()
+{
+    const size_t kUnitBufferN = 1024;
+    cc_unit unitBuffer[1024];
+    
+    CFMutableDataRef result = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    
+    const uint8_t firstResult[] = { 0, 0, 0, 2, 1, 2 };
+    ccn_read_uint(kUnitBufferN, unitBuffer, sizeof(firstResult) - 4, firstResult + 4);
+    AppendMPI(result, kUnitBufferN, unitBuffer);
+    
+    ok(CFDataMatches(result, sizeof(firstResult), firstResult), "Didn't insert zero");
+    
+    const uint8_t secondResult[] = { 0, 0, 0, 2, 1, 2, 0, 0, 0, 3, 5, 6, 7 };
+    ccn_read_uint(kUnitBufferN, unitBuffer, sizeof(secondResult) - 10, secondResult + 10);
+    AppendMPI(result, kUnitBufferN, unitBuffer);
+    
+    ok(CFDataMatches(result, sizeof(secondResult), secondResult), "Didn't append zero");
+    
+    CFRelease(result);
+    
+    result = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    
+    const uint8_t thirdResult[] = { 0, 0, 0, 1, 1 };
+    ccn_read_uint(kUnitBufferN, unitBuffer, sizeof(thirdResult) - 4, thirdResult + 4);
+    AppendMPI(result, kUnitBufferN, unitBuffer);
+    
+    ok(CFDataMatches(result, sizeof(thirdResult), thirdResult), "Didn't insert zero");
+    
+    CFRelease(result);
+    
+    result = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    
+    const uint8_t fourthResult[] = { 0, 0, 0, 7, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };
+    ccn_read_uint(kUnitBufferN, unitBuffer, sizeof(fourthResult) - 4, fourthResult + 4);
+    AppendMPI(result, kUnitBufferN, unitBuffer);
+    
+    ok(CFDataMatches(result, sizeof(fourthResult), fourthResult), "Didn't insert zero");
+    
+    CFRelease(result);
+    
+    result = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    
+    const uint8_t paddedData[] = { 0, 0xCC, 0xDD, 0xEE, 0xFF, 0xAA };
+    const uint8_t shortenedResult[] = { 0, 0, 0, 5, 0xCC, 0xDD, 0xEE, 0xFF, 0xAA };
+    ccn_read_uint(kUnitBufferN, unitBuffer, sizeof(paddedData), paddedData);
+    AppendMPI(result, kUnitBufferN, unitBuffer);
+    
+    ok(CFDataMatches(result, sizeof(shortenedResult), shortenedResult), "Didn't insert zero");
+    
+    CFRelease(result);
+    
+}
+
+int otr_packetdata(int argc, char *const * argv)
+{
+    plan_tests(17);
+
+    testAppendShort();
+    testAppendLong();
+    testAppendData();
+    testAppendMPI();
+    
+    return 0;
+}
+
diff --git a/sec/Security/Regressions/secitem/si-00-find-nothing.c b/sec/Security/Regressions/secitem/si-00-find-nothing.c
new file mode 100644 (file)
index 0000000..6488412
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2006-2007,2009-2010 Apple Inc. All Rights Reserved.
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecItem.h>
+#include <Security/SecBase.h>
+#include <utilities/array_size.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "Security_regressions.h"
+
+/* Test basic add delete update copy matching stuff. */
+static void tests(void)
+{
+#ifndef NO_SERVER
+    plan_skip_all("No testing against server.");
+#else
+    const void *keys[] = {
+        kSecClass,
+    };
+    const void *values[] = {
+        kSecClassInternetPassword,
+    };
+    CFDictionaryRef query = CFDictionaryCreate(NULL, keys, values,
+    array_size(keys), NULL, NULL);
+    CFTypeRef results = NULL;
+    is_status(SecItemCopyMatching(query, &results), errSecItemNotFound,
+    "find nothing");
+    is(results, NULL, "results still NULL?");
+    if (results) {
+        CFRelease(results);
+        results = NULL;
+    }
+
+    if (query) {
+        CFRelease(query);
+        query = NULL;
+    }
+#endif
+}
+
+int si_00_find_nothing(int argc, char *const *argv)
+{
+    plan_tests(2);
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-05-add.c b/sec/Security/Regressions/secitem/si-05-add.c
new file mode 100644 (file)
index 0000000..3e38f80
--- /dev/null
@@ -0,0 +1,308 @@
+/*
+ *  si-05-add.c
+ *  Security
+ *
+ *  Created by Michael Brouwer on 12/6/08.
+ *  Copyright (c) 2008-2010 Apple Inc. All Rights Reserved.
+ *
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecItem.h>
+#include <Security/SecItemPriv.h>
+#include <Security/SecBase.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "Security_regressions.h"
+
+#define CFReleaseNull(CF) { CFTypeRef _cf = (CF); if (_cf) {  (CF) = NULL; CFRelease(_cf); } }
+
+/*
+       subject= /O=VeriSign Trust Network/OU=VeriSign, Inc./OU=VeriSign International Server CA - Class 3/OU=www.verisign.com/CPS Incorp.by Ref. LIABILITY LTD.(c)97 VeriSign
+       issuer= /C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
+       serial=254B8A853842CCE358F8C5DDAE226EA4
+*/
+const uint8_t _myCert[] = {
+    0x30, 0x82, 0x03, 0x83, 0x30, 0x82, 0x02, 0xec,
+    0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x25,
+    0x4b, 0x8a, 0x85, 0x38, 0x42, 0xcc, 0xe3, 0x58,
+    0xf8, 0xc5, 0xdd, 0xae, 0x22, 0x6e, 0xa4, 0x30,
+    0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+    0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 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, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e,
+    0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x37,
+    0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
+    0x2e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33,
+    0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20,
+    0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20,
+    0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+    0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
+    0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30,
+    0x1e, 0x17, 0x0d, 0x39, 0x37, 0x30, 0x34, 0x31,
+    0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
+    0x17, 0x0d, 0x31, 0x31, 0x31, 0x30, 0x32, 0x34,
+    0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30,
+    0x81, 0xba, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03,
+    0x55, 0x04, 0x0a, 0x13, 0x16, 0x56, 0x65, 0x72,
+    0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72,
+    0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77,
+    0x6f, 0x72, 0x6b, 0x31, 0x17, 0x30, 0x15, 0x06,
+    0x03, 0x55, 0x04, 0x0b, 0x13, 0x0e, 0x56, 0x65,
+    0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20,
+    0x49, 0x6e, 0x63, 0x2e, 0x31, 0x33, 0x30, 0x31,
+    0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56,
+    0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20,
+    0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74,
+    0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65,
+    0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x20,
+    0x2d, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20,
+    0x33, 0x31, 0x49, 0x30, 0x47, 0x06, 0x03, 0x55,
+    0x04, 0x0b, 0x13, 0x40, 0x77, 0x77, 0x77, 0x2e,
+    0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e,
+    0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x50, 0x53,
+    0x20, 0x49, 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x2e,
+    0x62, 0x79, 0x20, 0x52, 0x65, 0x66, 0x2e, 0x20,
+    0x4c, 0x49, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54,
+    0x59, 0x20, 0x4c, 0x54, 0x44, 0x2e, 0x28, 0x63,
+    0x29, 0x39, 0x37, 0x20, 0x56, 0x65, 0x72, 0x69,
+    0x53, 0x69, 0x67, 0x6e, 0x30, 0x81, 0x9f, 0x30,
+    0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+    0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81,
+    0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81,
+    0x00, 0xd8, 0x82, 0x80, 0xe8, 0xd6, 0x19, 0x02,
+    0x7d, 0x1f, 0x85, 0x18, 0x39, 0x25, 0xa2, 0x65,
+    0x2b, 0xe1, 0xbf, 0xd4, 0x05, 0xd3, 0xbc, 0xe6,
+    0x36, 0x3b, 0xaa, 0xf0, 0x4c, 0x6c, 0x5b, 0xb6,
+    0xe7, 0xaa, 0x3c, 0x73, 0x45, 0x55, 0xb2, 0xf1,
+    0xbd, 0xea, 0x97, 0x42, 0xed, 0x9a, 0x34, 0x0a,
+    0x15, 0xd4, 0xa9, 0x5c, 0xf5, 0x40, 0x25, 0xdd,
+    0xd9, 0x07, 0xc1, 0x32, 0xb2, 0x75, 0x6c, 0xc4,
+    0xca, 0xbb, 0xa3, 0xfe, 0x56, 0x27, 0x71, 0x43,
+    0xaa, 0x63, 0xf5, 0x30, 0x3e, 0x93, 0x28, 0xe5,
+    0xfa, 0xf1, 0x09, 0x3b, 0xf3, 0xb7, 0x4d, 0x4e,
+    0x39, 0xf7, 0x5c, 0x49, 0x5a, 0xb8, 0xc1, 0x1d,
+    0xd3, 0xb2, 0x8a, 0xfe, 0x70, 0x30, 0x95, 0x42,
+    0xcb, 0xfe, 0x2b, 0x51, 0x8b, 0x5a, 0x3c, 0x3a,
+    0xf9, 0x22, 0x4f, 0x90, 0xb2, 0x02, 0xa7, 0x53,
+    0x9c, 0x4f, 0x34, 0xe7, 0xab, 0x04, 0xb2, 0x7b,
+    0x6f, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81,
+    0xe3, 0x30, 0x81, 0xe0, 0x30, 0x0f, 0x06, 0x03,
+    0x55, 0x1d, 0x13, 0x04, 0x08, 0x30, 0x06, 0x01,
+    0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x44, 0x06,
+    0x03, 0x55, 0x1d, 0x20, 0x04, 0x3d, 0x30, 0x3b,
+    0x30, 0x39, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01,
+    0x86, 0xf8, 0x45, 0x01, 0x07, 0x01, 0x01, 0x30,
+    0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01,
+    0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68,
+    0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77,
+    0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73,
+    0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+    0x43, 0x50, 0x53, 0x30, 0x34, 0x06, 0x03, 0x55,
+    0x1d, 0x25, 0x04, 0x2d, 0x30, 0x2b, 0x06, 0x08,
+    0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01,
+    0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+    0x03, 0x02, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
+    0x86, 0xf8, 0x42, 0x04, 0x01, 0x06, 0x0a, 0x60,
+    0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x08,
+    0x01, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f,
+    0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x11,
+    0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8,
+    0x42, 0x01, 0x01, 0x04, 0x04, 0x03, 0x02, 0x01,
+    0x06, 0x30, 0x31, 0x06, 0x03, 0x55, 0x1d, 0x1f,
+    0x04, 0x2a, 0x30, 0x28, 0x30, 0x26, 0xa0, 0x24,
+    0xa0, 0x22, 0x86, 0x20, 0x68, 0x74, 0x74, 0x70,
+    0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x76,
+    0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e,
+    0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63, 0x61, 0x33,
+    0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0d, 0x06, 0x09,
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+    0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x08,
+    0x01, 0xec, 0xe4, 0x68, 0x94, 0x03, 0x42, 0xf1,
+    0x73, 0xf1, 0x23, 0xa2, 0x3a, 0xde, 0xe9, 0xf1,
+    0xda, 0xc6, 0x54, 0xc4, 0x23, 0x3e, 0x86, 0xea,
+    0xcf, 0x6a, 0x3a, 0x33, 0xab, 0xea, 0x9c, 0x04,
+    0x14, 0x07, 0x36, 0x06, 0x0b, 0xf9, 0x88, 0x6f,
+    0xd5, 0x13, 0xee, 0x29, 0x2b, 0xc3, 0xe4, 0x72,
+    0x8d, 0x44, 0xed, 0xd1, 0xac, 0x20, 0x09, 0x2d,
+    0xe1, 0xf6, 0xe1, 0x19, 0x05, 0x38, 0xb0, 0x3d,
+    0x0f, 0x9f, 0x7f, 0xf8, 0x9e, 0x02, 0xdc, 0x86,
+    0x02, 0x86, 0x61, 0x4e, 0x26, 0x5f, 0x5e, 0x9f,
+    0x92, 0x1e, 0x0c, 0x24, 0xa4, 0xf5, 0xd0, 0x70,
+    0x13, 0xcf, 0x26, 0xc3, 0x43, 0x3d, 0x49, 0x1d,
+    0x9e, 0x82, 0x2e, 0x52, 0x5f, 0xbc, 0x3e, 0xc6,
+    0x66, 0x29, 0x01, 0x8e, 0x4e, 0x92, 0x2c, 0xbc,
+    0x46, 0x75, 0x03, 0x82, 0xac, 0x73, 0xe9, 0xd9,
+    0x7e, 0x0b, 0x67, 0xef, 0x54, 0x52, 0x1a
+};
+
+static void persistentRefIs(CFDataRef pref, CFDataRef data) {
+    CFMutableDictionaryRef dict = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFTypeRef result = NULL;
+    CFDictionaryAddValue(dict, kSecValuePersistentRef, pref);
+    CFDictionaryAddValue(dict, kSecReturnData, kCFBooleanTrue);
+    ok_status(SecItemCopyMatching(dict, &result), "lookup item data by persistent ref");
+    ok(CFEqual(data, result), "result %@ equals expected data %@", result, data);
+    CFReleaseNull(result);
+    CFReleaseNull(dict);
+}
+
+/* Test add api in all it's variants. */
+static void tests(void)
+{
+    CFDataRef myCertData = NULL;
+       SecCertificateRef myCert = NULL;
+       CFTypeRef  certHandle = NULL;
+
+    /* Create myCert and setup dict. */
+    myCertData = CFDataCreateWithBytesNoCopy(NULL, _myCert, sizeof(_myCert),
+        kCFAllocatorNull);
+       isnt(myCert = SecCertificateCreateWithData(NULL, myCertData),
+               NULL, "create myCert");
+    CFMutableDictionaryRef dict = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(dict, kSecClass, kSecClassCertificate);
+    CFDictionaryAddValue(dict, kSecValueRef, myCert);
+
+    /* Case 1: add certificate with no return pointer. */
+    ok_status(SecItemAdd(dict, NULL),
+        "Case 1: add certificate NULL return pointer");
+    ok_status(SecItemDelete(dict), "delete certificate");
+    /* Case 1b: add certificate ref should be returned implicitly. */
+    ok_status(SecItemAdd(dict, &certHandle),
+              "Case 1: add certificate dont ask for return type");
+    // See also: "<rdar://problem/7091317493> SecItemAdd unimplemented feature";
+    is(certHandle, NULL, "nothing returned");
+    CFReleaseNull(certHandle);
+    ok_status(SecItemDelete(dict), "delete certificate");
+
+    /* Case 2: add certificate ask for persistent ref. */
+    CFDictionaryAddValue(dict, kSecReturnPersistentRef, kCFBooleanTrue);
+    ok_status(SecItemAdd(dict, &certHandle),
+        "Case 2: add certificate ask for persistent ref");
+    is(CFGetTypeID(certHandle), CFDataGetTypeID(), "persistent ref returned");
+    /* Check if persistent ref yields cert data again when searched. */
+    persistentRefIs(certHandle, myCertData);
+    CFReleaseNull(certHandle);
+    CFDictionaryRemoveValue(dict, kSecReturnPersistentRef);
+    ok_status(SecItemDelete(dict), "delete certificate");
+
+    /* Case 3: add certificate ask for ref to be returned explicitly. */
+    CFDictionaryAddValue(dict, kSecReturnRef, kCFBooleanTrue);
+    ok_status(SecItemAdd(dict, &certHandle),
+        "Case 3: add certificate ask for ref to be returned explicitly");
+    ok(CFEqual(myCert, certHandle), "certificate ref matches");
+    CFReleaseNull(certHandle);
+    CFDictionaryRemoveValue(dict, kSecReturnRef);
+    ok_status(SecItemDelete(dict), "delete certificate");
+
+    /* Case 4: add certificate ask for data to be returned explicitly. */
+    CFDictionaryAddValue(dict, kSecReturnData, kCFBooleanTrue);
+    ok_status(SecItemAdd(dict, &certHandle),
+        "Case 4: add certificate ask for data to be returned explicitly");
+    ok(CFEqual(myCertData, certHandle), "certificate data matches");
+    CFReleaseNull(certHandle);
+    CFDictionaryRemoveValue(dict, kSecReturnData);
+    ok_status(SecItemDelete(dict), "delete certificate");
+
+    /* Case 5: add certificate ask for attributes to be returned explicitly. */
+    CFDictionaryAddValue(dict, kSecReturnAttributes, kCFBooleanTrue);
+    ok_status(SecItemAdd(dict, &certHandle),
+        "Case 5: add certificate ask for attributes to be returned explicitly");
+    is(CFGetTypeID(certHandle), CFDictionaryGetTypeID(), "result is a dict");
+    ok(!CFDictionaryContainsKey(certHandle, kSecValueData),
+        "result has no data");
+    ok(!CFDictionaryContainsKey(certHandle, kSecValueRef),
+        "result has no ref");
+    ok(!CFDictionaryContainsKey(certHandle, kSecValuePersistentRef),
+        "result has no persistent ref");
+    /* @@@ Check attribute values. Against this list:
+        kSecClassCertificate item attributes:
+        kSecAttrAccessGroup
+        kSecAttrCertificateType
+        kSecAttrCertificateEncoding
+        kSecAttrLabel
+        kSecAttrSubject
+        kSecAttrIssuer
+        kSecAttrSerialNumber
+        kSecAttrSubjectKeyID
+        kSecAttrPublicKeyHash
+    */
+    is(CFGetTypeID(CFDictionaryGetValue(certHandle, kSecAttrCertificateType)),
+        CFNumberGetTypeID(), "certificate type is a number");
+    is(CFGetTypeID(CFDictionaryGetValue(certHandle, kSecAttrCertificateEncoding)),
+        CFNumberGetTypeID(), "certificate encoding is a number");
+    CFReleaseNull(certHandle);
+    CFDictionaryRemoveValue(dict, kSecReturnAttributes);
+    ok_status(SecItemDelete(dict), "delete certificate");
+
+    /* Case 6: add certificate ask for attributes, data, ref and persistent ref
+       to be returned explicitly. */
+    CFDictionaryAddValue(dict, kSecReturnData, kCFBooleanTrue);
+    CFDictionaryAddValue(dict, kSecReturnAttributes, kCFBooleanTrue);
+    CFDictionaryAddValue(dict, kSecReturnRef, kCFBooleanTrue);
+    CFDictionaryAddValue(dict, kSecReturnPersistentRef, kCFBooleanTrue);
+    ok_status(SecItemAdd(dict, &certHandle),
+        "Case 6: add certificate ask for attributes, data, ref and persistent ref to be returned explicitly");
+    isnt(certHandle, NULL, "certificate handle returned");
+    is(CFGetTypeID(certHandle), CFDictionaryGetTypeID(), "result is a dict");
+    ok(CFEqual(myCertData, CFDictionaryGetValue(certHandle, kSecValueData)),
+        "certificate data in dict matches");
+    ok(CFEqual(myCert, CFDictionaryGetValue(certHandle, kSecValueRef)),
+        "certificate ref in dict matches");
+    /* Check if persistent ref yields cert data again when searched. */
+    persistentRefIs(CFDictionaryGetValue(certHandle, kSecValuePersistentRef),
+        myCertData);
+    ok(CFEqual(kSecClassCertificate,
+        CFDictionaryGetValue(certHandle, kSecClass)),
+        "certificate class in dict matches");
+    is(CFGetTypeID(CFDictionaryGetValue(certHandle, kSecAttrCertificateType)),
+        CFNumberGetTypeID(), "certificate type is a number");
+    is(CFGetTypeID(CFDictionaryGetValue(certHandle, kSecAttrCertificateEncoding)),
+        CFNumberGetTypeID(), "certificate encoding is a number");
+    CFReleaseNull(certHandle);
+    CFDictionaryRemoveValue(dict, kSecReturnData);
+    CFDictionaryRemoveValue(dict, kSecReturnAttributes);
+    CFDictionaryRemoveValue(dict, kSecReturnRef);
+    CFDictionaryRemoveValue(dict, kSecReturnPersistentRef);
+    ok_status(SecItemDelete(dict), "delete certificate");
+
+    /* Case 7: add certificate with bogus attribute. */
+    CFDataRef tagData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
+        (const UInt8 *)"funnytag", 8, kCFAllocatorNull);
+    CFDictionaryAddValue(dict, kSecAttrApplicationTag, tagData);
+    is_status(SecItemAdd(dict, &certHandle), errSecParam,
+        "Case 7: add certificate with bogus attribute returns errSecParam");
+    CFReleaseNull(certHandle);
+    is_status(SecItemDelete(dict), errSecParam,
+        "delete certificate with bogus attribute returns errSecParam");
+    CFDictionaryRemoveValue(dict, kSecAttrApplicationTag);
+    CFReleaseNull(tagData);
+
+    /* Case 8: add certificate with synchronizable attribute. */
+    CFDictionaryAddValue(dict, kSecAttrSynchronizable, kCFBooleanTrue);
+    ok_status(SecItemAdd(dict, &certHandle),
+              "Case 7: add certificate with synchronizable attribute works");
+    CFReleaseNull(certHandle);
+    ok_status(SecItemDelete(dict),
+              "delete certificate with synchronizable attribute works");
+    CFDictionaryRemoveValue(dict, kSecAttrSynchronizable);
+
+    /* Cleanup. */
+    CFReleaseNull(dict);
+    CFReleaseNull(myCert);
+    CFReleaseNull(myCertData);
+
+}
+
+int si_05_add(int argc, char *const *argv)
+{
+       plan_tests(40);
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-10-find-internet.c b/sec/Security/Regressions/secitem/si-10-find-internet.c
new file mode 100644 (file)
index 0000000..e58c810
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2006-2010 Apple Inc. All Rights Reserved.
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecItem.h>
+#include <Security/SecBase.h>
+#include <utilities/array_size.h>
+#include <utilities/SecCFWrappers.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "Security_regressions.h"
+
+// TODO: Test whether limit's works.
+
+/* Test basic add delete update copy matching stuff. */
+static void tests(void)
+{
+    int v_eighty = 80;
+    CFNumberRef eighty = CFNumberCreate(NULL, kCFNumberSInt32Type, &v_eighty);
+    const char *v_data = "test";
+    CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data));
+    const void *keys[] = {
+               kSecClass,
+               kSecAttrServer,
+               kSecAttrAccount,
+               kSecAttrPort,
+               kSecAttrProtocol,
+               kSecAttrAuthenticationType,
+               kSecValueData
+    };
+    const void *values[] = {
+               kSecClassInternetPassword,
+               CFSTR("members.spamcop.net"),
+               CFSTR("smith"),
+               eighty,
+               CFSTR("http"),
+               CFSTR("dflt"),
+               pwdata
+    };
+    CFDictionaryRef item = CFDictionaryCreate(NULL, keys, values,
+       array_size(keys), NULL, NULL);
+    ok_status(SecItemAdd(item, NULL), "add internet password");
+    is_status(SecItemAdd(item, NULL), errSecDuplicateItem,
+       "add internet password again");
+
+    CFTypeRef results = NULL;
+    /* Create a dict with all attrs except the data. */
+    CFDictionaryRef query = CFDictionaryCreate(NULL, keys, values,
+       (array_size(keys)) - 1, NULL, NULL);
+    ok_status(SecItemCopyMatching(query, &results), "find internet password");
+    CFReleaseNull(results);
+
+    CFMutableDictionaryRef query2 = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, query);
+    CFDictionarySetValue(query2, kSecReturnAttributes, kCFBooleanTrue);
+    CFDictionarySetValue(query2, kSecMatchLimit , kSecMatchLimitOne);
+    ok_status(SecItemCopyMatching(query2, &results), "find internet password, return attributes");
+    CFReleaseNull(query2);
+    query2 = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, results);
+    CFDictionarySetValue(query2, kSecClass, kSecClassInternetPassword);
+    CFDictionarySetValue(query2, kSecReturnData, kCFBooleanTrue);
+    ok_status(SecItemCopyMatching(query2, &results), "find internet password using returned attributes");
+    CFReleaseSafe(query2);
+    ok(isData(results) && CFEqual(results, pwdata), "retrieved data correctly");
+    CFReleaseNull(results);
+
+    /* Modify the server attr of the item. */
+    const void *ch_keys[] = {
+        kSecAttrServer,
+               kSecClass,
+    };
+    const void *ch_values[] = {
+               CFSTR("www.spamcop.net"),
+               kSecClassInternetPassword,
+    };
+    CFDictionaryRef changes = CFDictionaryCreate(NULL, ch_keys, ch_values,
+               1, NULL, NULL);
+    ok_status(SecItemUpdate(query, changes), "update internet password");
+
+    is_status(SecItemUpdate(query, changes), errSecItemNotFound,
+               "update non-exisiting internet password again");
+
+    /* Delete the original item (which should fail since we modified it). */
+    is_status(SecItemDelete(query), errSecItemNotFound,
+               "delete non existing internet password");
+    ok_status(SecItemAdd(item, NULL), "add unmodified password");
+    ok_status(SecItemDelete(query), "delete internet password");
+
+    ok_status(SecItemAdd(item, NULL), "add unmodified password");
+    is_status(SecItemUpdate(query, changes), errSecDuplicateItem,
+               "update internet password causing dupe");
+    ok_status(SecItemDelete(query), "delete internet password");
+
+    CFDictionaryRef changed_item = CFDictionaryCreate(NULL, ch_keys, ch_values,
+               array_size(ch_keys), NULL, NULL);
+    ok_status(SecItemDelete(changed_item), "delete changed internet password");
+
+       if (changed_item) {
+               CFRelease(changed_item);
+               changed_item = NULL;
+       }
+
+    if (changes) {
+        CFRelease(changes);
+        changes = NULL;
+    }
+
+    if (item) {
+        CFRelease(item);
+        item = NULL;
+    }
+
+    if (query) {
+        CFRelease(query);
+        query = NULL;
+    }
+
+    if (eighty) {
+        CFRelease(eighty);
+        eighty = NULL;
+    }
+    if (pwdata) {
+        CFRelease(pwdata);
+        pwdata = NULL;
+    }
+}
+
+int si_10_find_internet(int argc, char *const *argv)
+{
+       plan_tests(15);
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-11-update-data.c b/sec/Security/Regressions/secitem/si-11-update-data.c
new file mode 100644 (file)
index 0000000..840a3f6
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2006-2010 Apple Inc. All Rights Reserved.
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecItem.h>
+#include <Security/SecItemPriv.h>
+#include <Security/SecBase.h>
+#include <utilities/array_size.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "Security_regressions.h"
+
+/* Test basic add delete update copy matching stuff. */
+static void tests(void)
+{
+    const char *v_data = "test";
+    CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data));
+    const void *keys[] = {
+               kSecClass,
+               kSecAttrAccount,
+               kSecAttrService,
+               kSecValueData
+    };
+    const void *values[] = {
+               kSecClassGenericPassword,
+               CFSTR("dankeen"),
+               CFSTR("iTools"),
+               pwdata
+    };
+    CFDictionaryRef item = CFDictionaryCreate(NULL, keys, values,
+       array_size(keys), NULL, NULL);
+    ok_status(SecItemAdd(item, NULL), "add generic password");
+
+    CFTypeRef results = NULL;
+    /* Create a dict with all attrs except the data. */
+    CFDictionaryRef query = CFDictionaryCreate(NULL, keys, values,
+       (array_size(keys)) - 1, NULL, NULL);
+    ok_status(SecItemCopyMatching(query, &results), "find generic password");
+    if (results) {
+        CFRelease(results);
+        results = NULL;
+    }
+
+    /* Modify the data of the item. */
+    const char *v_data2 = "different password data this time";
+    CFDataRef pwdata2 = CFDataCreate(NULL, (UInt8 *)v_data2, strlen(v_data2));
+    CFMutableDictionaryRef changes = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionarySetValue(changes, kSecValueData, pwdata2);
+    ok_status(SecItemUpdate(query, changes), "update generic password");
+
+    CFDictionarySetValue(changes, kSecValueData, NULL);
+    is_status(SecItemUpdate(query, changes), errSecParam, "update NULL data");
+
+    /* This seems to be what we were seeing in
+       <rdar://problem/6940041> 466 Crashes in securityd: kc_encrypt_data (SecItemServer.c:971).
+       which is now fixed. */
+    CFDictionarySetValue(changes, kSecValueData, CFSTR("bogus"));
+    is_status(SecItemUpdate(query, changes), errSecParam, "update string data");
+
+    ok_status(SecItemDelete(query), "delete generic password");
+
+    if (changes) {
+        CFRelease(changes);
+        changes = NULL;
+    }
+
+    if (item) {
+        CFRelease(item);
+        item = NULL;
+    }
+
+    if (query) {
+        CFRelease(query);
+        query = NULL;
+    }
+
+    if (pwdata) {
+        CFRelease(pwdata);
+        pwdata = NULL;
+    }
+
+    if (pwdata2) {
+        CFRelease(pwdata2);
+        pwdata = NULL;
+    }
+}
+
+int si_11_update_data(int argc, char *const *argv)
+{
+       plan_tests(6);
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-12-item-stress.c b/sec/Security/Regressions/secitem/si-12-item-stress.c
new file mode 100644 (file)
index 0000000..5e75be7
--- /dev/null
@@ -0,0 +1,381 @@
+//
+//  si-12-item-stress.c
+//  sec
+//
+//  Created by Michael Brouwer on 8/1/13.
+//  Copyright (c) 2013 Apple Inc. All Rights Reserved.
+//
+//
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecItem.h>
+#include <Security/SecItemPriv.h>
+#include <Security/SecBase.h>
+#include <utilities/array_size.h>
+#include <utilities/SecCFWrappers.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "Security_regressions.h"
+
+#if 0
+static void persistentRefIs(CFDataRef pref, CFDataRef data) {
+    CFMutableDictionaryRef dict = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFTypeRef result = NULL;
+    CFDictionaryAddValue(dict, kSecValuePersistentRef, pref);
+    CFDictionaryAddValue(dict, kSecReturnData, kCFBooleanTrue);
+    ok_status(SecItemCopyMatching(dict, &result), "lookup item data by persistent ref");
+    ok(CFEqual(data, result), "result %@ equals expected data %@", result, data);
+    CFReleaseNull(result);
+    CFReleaseNull(dict);
+}
+#endif
+
+enum ItemAttrType {
+    kBoolItemAttr,
+    kNumberItemAttr,
+    kStringItemAttr,
+    kDataItemAttr,
+    kBlobItemAttr,
+    kDateItemAttr,
+    kAccessabilityItemAttr,
+    kAccessGroupItemAttr,
+};
+
+static void WithEachString(void(^each)(CFStringRef attr, enum ItemAttrType atype), ...) {
+    va_list ap;
+    va_start(ap, each);
+    CFStringRef attr;
+    while((attr = va_arg(ap, CFStringRef)) != NULL) {
+        enum ItemAttrType atype = va_arg(ap, enum ItemAttrType);
+        each(attr, atype);
+    }
+    va_end(ap);
+}
+
+#if 0
+static void ItemForEachAttr(CFMutableDictionaryRef item, void(^each)(CFStringRef attr, enum ItemAttrType atype)) {
+    CFStringRef iclass = CFDictionaryGetValue(item, kSecClass);
+    if (!iclass) {
+        return;
+    } else if (CFEqual(iclass, kSecClassGenericPassword)) {
+        WithEachString(each,
+                       kSecAttrAccessible,          kAccessabilityItemAttr,
+                       kSecAttrAccessGroup,         kAccessGroupItemAttr,
+                       kSecAttrCreationDate,        kDateItemAttr,
+                       kSecAttrModificationDate,    kDateItemAttr,
+                       kSecAttrDescription,         kStringItemAttr,
+                       kSecAttrComment,             kStringItemAttr,
+                       kSecAttrCreator,             kNumberItemAttr,
+                       kSecAttrType,                kNumberItemAttr,
+                       kSecAttrLabel,               kStringItemAttr,
+                       kSecAttrIsInvisible,         kBoolItemAttr,
+                       kSecAttrIsNegative,          kBoolItemAttr,
+                       kSecAttrAccount,             kStringItemAttr,
+                       kSecAttrService,             kStringItemAttr,
+                       kSecAttrGeneric,             kDataItemAttr,
+                       kSecAttrSynchronizable,      kBoolItemAttr,
+                       NULL);
+    } else if (CFEqual(iclass, kSecClassInternetPassword)) {
+        WithEachString(each,
+                       kSecAttrAccessible,          kAccessabilityItemAttr,
+                       kSecAttrAccessGroup,         kAccessGroupItemAttr,
+                       kSecAttrCreationDate,        kDateItemAttr,
+                       kSecAttrModificationDate,    kDateItemAttr,
+                       kSecAttrDescription,         kStringItemAttr,
+                       kSecAttrComment,             kStringItemAttr,
+                       kSecAttrCreator,             kNumberItemAttr,
+                       kSecAttrType,                kNumberItemAttr,
+                       kSecAttrLabel,               kStringItemAttr,
+                       kSecAttrIsInvisible,         kBoolItemAttr,
+                       kSecAttrIsNegative,          kBoolItemAttr,
+                       kSecAttrAccount,             kStringItemAttr,
+                       kSecAttrSecurityDomain,      kStringItemAttr,
+                       kSecAttrServer,              kStringItemAttr,
+                       kSecAttrProtocol,            kNumberItemAttr,
+                       kSecAttrAuthenticationType,  kNumberItemAttr,
+                       kSecAttrPort,                kNumberItemAttr,
+                       kSecAttrPath,                kStringItemAttr,
+                       kSecAttrSynchronizable,      kBoolItemAttr,
+                       NULL);
+    } else if (CFEqual(iclass, kSecClassCertificate)) {
+        WithEachString(each,
+                       kSecAttrAccessible,          kAccessabilityItemAttr,
+                       kSecAttrAccessGroup,         kAccessGroupItemAttr,
+                       kSecAttrCertificateType,     kNumberItemAttr,
+                       kSecAttrCertificateEncoding, kNumberItemAttr,
+                       kSecAttrLabel,               kStringItemAttr,
+                       kSecAttrSubject,             kDataItemAttr,
+                       kSecAttrIssuer,              kDataItemAttr,
+                       kSecAttrSerialNumber,        kDataItemAttr,
+                       kSecAttrSubjectKeyID,        kDataItemAttr,
+                       kSecAttrPublicKeyHash,       kDataItemAttr,
+                       kSecAttrSynchronizable,      kBoolItemAttr,
+                       NULL);
+    } else if (CFEqual(iclass, kSecClassKey)) {
+        WithEachString(each,
+                       kSecAttrAccessible,          kAccessabilityItemAttr,
+                       kSecAttrAccessGroup,         kAccessGroupItemAttr,
+                       kSecAttrKeyClass,            kStringItemAttr, // Might be Number on replies
+                       kSecAttrLabel,               kStringItemAttr,
+                       kSecAttrApplicationLabel,    kDataItemAttr,
+                       kSecAttrIsPermanent,         kBoolItemAttr,
+                       kSecAttrApplicationTag,      kDataItemAttr,
+                       kSecAttrKeyType,             kNumberItemAttr,
+                       kSecAttrKeySizeInBits,       kNumberItemAttr,
+                       kSecAttrEffectiveKeySize,    kNumberItemAttr,
+                       kSecAttrCanEncrypt,          kBoolItemAttr,
+                       kSecAttrCanDecrypt,          kBoolItemAttr,
+                       kSecAttrCanDerive,           kBoolItemAttr,
+                       kSecAttrCanSign,             kBoolItemAttr,
+                       kSecAttrCanVerify,           kBoolItemAttr,
+                       kSecAttrCanWrap,             kBoolItemAttr,
+                       kSecAttrCanUnwrap,           kBoolItemAttr,
+                       kSecAttrStartDate,           kDateItemAttr,
+                       kSecAttrEndDate,             kDateItemAttr,
+                       kSecAttrSynchronizable,      kBoolItemAttr,
+                       NULL);
+    } else if (CFEqual(iclass, kSecClassIdentity)) {
+        WithEachString(each,
+                       kSecAttrAccessible,          kAccessabilityItemAttr,
+                       kSecAttrAccessGroup,         kAccessGroupItemAttr,
+                       kSecAttrCertificateType,     kNumberItemAttr,
+                       kSecAttrCertificateEncoding, kNumberItemAttr,
+                       kSecAttrLabel,               kStringItemAttr,
+                       kSecAttrSubject,             kDataItemAttr,
+                       kSecAttrIssuer,              kDataItemAttr,
+                       kSecAttrSerialNumber,        kDataItemAttr,
+                       kSecAttrSubjectKeyID,        kDataItemAttr,
+                       kSecAttrPublicKeyHash,       kDataItemAttr,
+                       kSecAttrKeyClass,            kStringItemAttr, // Might be Number on replies
+                       kSecAttrApplicationLabel,    kDataItemAttr,
+                       kSecAttrIsPermanent,         kBoolItemAttr,
+                       kSecAttrApplicationTag,      kDataItemAttr,
+                       kSecAttrKeyType,             kNumberItemAttr,
+                       kSecAttrKeySizeInBits,       kNumberItemAttr,
+                       kSecAttrEffectiveKeySize,    kNumberItemAttr,
+                       kSecAttrCanEncrypt,          kBoolItemAttr,
+                       kSecAttrCanDecrypt,          kBoolItemAttr,
+                       kSecAttrCanDerive,           kBoolItemAttr,
+                       kSecAttrCanSign,             kBoolItemAttr,
+                       kSecAttrCanVerify,           kBoolItemAttr,
+                       kSecAttrCanWrap,             kBoolItemAttr,
+                       kSecAttrCanUnwrap,           kBoolItemAttr,
+                       kSecAttrStartDate,           kDateItemAttr,
+                       kSecAttrEndDate,             kDateItemAttr,
+                       kSecAttrSynchronizable,      kBoolItemAttr,
+                       NULL);
+    }
+}
+#endif
+
+static void ItemForEachPKAttr(CFMutableDictionaryRef item, void(^each)(CFStringRef attr, enum ItemAttrType atype)) {
+    CFStringRef iclass = CFDictionaryGetValue(item, kSecClass);
+    if (!iclass) {
+        return;
+    } else if (CFEqual(iclass, kSecClassGenericPassword)) {
+        WithEachString(each,
+                       kSecAttrAccessGroup,         kAccessGroupItemAttr,
+                       kSecAttrAccount,             kStringItemAttr,
+                       kSecAttrService,             kStringItemAttr,
+                       kSecAttrSynchronizable,      kBoolItemAttr,
+                       NULL);
+    } else if (CFEqual(iclass, kSecClassInternetPassword)) {
+        WithEachString(each,
+                       kSecAttrAccessGroup,         kAccessGroupItemAttr,
+                       kSecAttrAccount,             kStringItemAttr,
+                       kSecAttrSecurityDomain,      kStringItemAttr,
+                       kSecAttrServer,              kStringItemAttr,
+                       kSecAttrProtocol,            kNumberItemAttr,
+                       kSecAttrAuthenticationType,  kNumberItemAttr,
+                       kSecAttrPort,                kNumberItemAttr,
+                       kSecAttrPath,                kStringItemAttr,
+                       kSecAttrSynchronizable,      kBoolItemAttr,
+                       NULL);
+    } else if (CFEqual(iclass, kSecClassCertificate)) {
+        WithEachString(each,
+                       kSecAttrAccessGroup,         kAccessGroupItemAttr,
+                       kSecAttrCertificateType,     kNumberItemAttr,
+                       kSecAttrIssuer,              kDataItemAttr,
+                       kSecAttrSerialNumber,        kDataItemAttr,
+                       kSecAttrSynchronizable,      kBoolItemAttr,
+                       NULL);
+    } else if (CFEqual(iclass, kSecClassKey)) {
+        WithEachString(each,
+                       kSecAttrAccessGroup,         kAccessGroupItemAttr,
+                       kSecAttrKeyClass,            kStringItemAttr, // kNumberItemAttr on replies
+                       kSecAttrApplicationLabel,    kDataItemAttr,
+                       kSecAttrApplicationTag,      kDataItemAttr,
+                       kSecAttrKeyType,             kNumberItemAttr,
+                       kSecAttrKeySizeInBits,       kNumberItemAttr,
+                       kSecAttrEffectiveKeySize,    kNumberItemAttr,
+                       kSecAttrStartDate,           kDateItemAttr,
+                       kSecAttrEndDate,             kDateItemAttr,
+                       kSecAttrSynchronizable,      kBoolItemAttr,
+                       NULL);
+    } else if (CFEqual(iclass, kSecClassIdentity)) {
+        WithEachString(each,
+                       kSecAttrAccessGroup,         kAccessGroupItemAttr,
+                       kSecAttrCertificateType,     kNumberItemAttr,
+                       kSecAttrIssuer,              kDataItemAttr,
+                       kSecAttrSerialNumber,        kDataItemAttr,
+                       kSecAttrSynchronizable,      kBoolItemAttr,
+                       kSecAttrKeyClass,            kStringItemAttr, // kNumberItemAttr on replies
+                       kSecAttrApplicationLabel,    kDataItemAttr,
+                       kSecAttrApplicationTag,      kDataItemAttr,
+                       kSecAttrKeyType,             kNumberItemAttr,
+                       kSecAttrKeySizeInBits,       kNumberItemAttr,
+                       kSecAttrEffectiveKeySize,    kNumberItemAttr,
+                       kSecAttrStartDate,           kDateItemAttr,
+                       kSecAttrEndDate,             kDateItemAttr,
+                       kSecAttrSynchronizable,      kBoolItemAttr,
+                       NULL);
+    }
+}
+
+static CFMutableDictionaryRef ItemCreate(int num) {
+    CFStringRef iclass = NULL;
+    switch (num % 4) {
+        case 0:
+            iclass = kSecClassInternetPassword;
+            break;
+        case 1:
+            iclass = kSecClassGenericPassword;
+            break;
+        case 2:
+            iclass = kSecClassKey;
+            break;
+        case 3:
+            iclass = kSecClassCertificate;
+            break;
+    }
+    return CFDictionaryCreateMutableForCFTypesWith(kCFAllocatorDefault, kSecClass, iclass, NULL);
+}
+
+/* Test add api in all it's variants. */
+static void tests(void)
+{
+    for (int num = 0 ; num < 8; ++num) {
+        CFMutableDictionaryRef item = ItemCreate(num);
+        ItemForEachPKAttr(item, ^(CFStringRef attr, enum ItemAttrType atype) {
+            CFTypeRef value = NULL;
+            switch (atype) {
+                case kBoolItemAttr:
+                    value = (num % 2 == 0 ? kCFBooleanTrue : kCFBooleanFalse);
+                    CFRetain(value);
+                    break;
+                case kNumberItemAttr:
+                    value = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &num);
+                    break;
+                case kStringItemAttr:
+                case kBlobItemAttr:
+                    value = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("string-%d"), num);
+                    break;
+                case kDataItemAttr:
+                {
+                    char buf[10];
+                    int len = snprintf(buf, sizeof(buf), "data-%d", num);
+                    value = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)buf, len);
+                    break;
+                }
+                case kDateItemAttr:
+                    value = NULL; // Don't mess with dates on create.
+                    break;
+                case kAccessabilityItemAttr:
+                {
+                    CFStringRef accessabilites[] = {
+                        kSecAttrAccessibleWhenUnlocked,
+                        kSecAttrAccessibleAfterFirstUnlock,
+                        kSecAttrAccessibleAlways,
+                        kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
+                        kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly,
+                        kSecAttrAccessibleAlwaysThisDeviceOnly,
+                    };
+                    value = accessabilites[num % array_size(accessabilites)];
+                    break;
+                }
+                case kAccessGroupItemAttr:
+                {
+                    CFStringRef accessGroups[] = {
+                        NULL,
+#if 0
+#if NO_SERVER
+                        CFSTR("test"),
+                        CFSTR("apple"),
+                        CFSTR("lockdown-identities"),
+#else
+                        CFSTR("sync"),
+#endif
+                        CFSTR("com.apple.security.sos"),          // Secd internally uses this
+
+                        CFSTR("com.apple.security.regressions"),  // SecurityTestApp is in this group.
+#endif
+                    };
+                    value = accessGroups[num % array_size(accessGroups)];
+                    break;
+                }
+            }
+            if (value)
+                CFDictionarySetValue(item, attr, value);
+            CFReleaseSafe(value);
+        });
+
+        CFDictionarySetValue(item, kSecAttrSynchronizable, kCFBooleanTrue);
+        ok_status(SecItemAdd(item, NULL), "add sync");
+
+        CFDictionarySetValue(item, kSecUseTombstones, kCFBooleanTrue);
+        ok_status(SecItemDelete(item), "delete sync");
+
+        CFDictionarySetValue(item, kSecAttrTombstone, kCFBooleanTrue);
+        ok_status(SecItemCopyMatching(item, NULL), "find tombstone after delete sync");
+        ok_status(SecItemDelete(item), "delete sync tombstone");
+        CFDictionaryRemoveValue(item, kSecAttrTombstone);
+
+        ok_status(SecItemAdd(item, NULL), "add sync again");
+
+        CFDictionarySetValue(item, kSecUseTombstones, kCFBooleanFalse);
+        ok_status(SecItemDelete(item), "delete sync without leaving a tombstone behind");
+        CFDictionaryRemoveValue(item, kSecUseTombstones);
+
+        CFDictionarySetValue(item, kSecAttrTombstone, kCFBooleanTrue);
+        is_status(SecItemCopyMatching(item, NULL), errSecItemNotFound, "do not find tombstone after delete sync with kSecUseTombstones=false");
+
+        CFDictionaryRemoveValue(item, kSecAttrSynchronizable);
+        ok_status(SecItemAdd(item, NULL), "add local");
+        ok_status(SecItemDelete(item), "delete local");
+
+        CFDictionarySetValue(item, kSecAttrTombstone, kCFBooleanTrue);
+        is_status(SecItemCopyMatching(item, NULL), errSecItemNotFound, "do not find tombstone after delete local");
+        is_status(SecItemDelete(item), errSecItemNotFound, "do not delete tombstone after delete local");
+        CFDictionaryRemoveValue(item, kSecAttrTombstone);
+
+        ok_status(SecItemAdd(item, NULL), "add local again");
+
+        CFDictionarySetValue(item, kSecUseTombstones, kCFBooleanTrue);
+        ok_status(SecItemDelete(item), "delete local and leave a tombstone behind");
+        CFDictionaryRemoveValue(item, kSecUseTombstones);
+
+        CFDictionarySetValue(item, kSecAttrTombstone, kCFBooleanTrue);
+        ok_status(SecItemCopyMatching(item, NULL), "find tombstone after delete sync with kSecUseTombstones=true");
+
+        CFDictionarySetValue(item, kSecUseTombstones, kCFBooleanTrue);
+        ok_status(SecItemDelete(item), "delete local tombstone kSecUseTombstones=true");
+        CFDictionaryRemoveValue(item, kSecUseTombstones);
+
+        ok_status(SecItemCopyMatching(item, NULL), "find tombstone after delete local tombstone with kSecUseTombstones=true");
+        ok_status(SecItemDelete(item), "delete local tombstone");
+        is_status(SecItemCopyMatching(item, NULL), errSecItemNotFound, "do not find tombstone after delete local");
+
+        CFRelease(item);
+    }
+}
+
+int si_12_item_stress(int argc, char *const *argv)
+{
+       plan_tests(144);
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-14-dateparse.c b/sec/Security/Regressions/secitem/si-14-dateparse.c
new file mode 100644 (file)
index 0000000..ef2eca0
--- /dev/null
@@ -0,0 +1,138 @@
+//
+//  si-14-dateparse.c
+//  regressions
+//
+//  Created by Michael Brouwer on 5/5/11.
+//  Copyright 2011 Apple Inc. All rights reserved.
+//
+
+#include <stdio.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCertificateInternal.h>
+#include <Security/SecInternal.h>
+#include <libDER/asn1Types.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "Security_regressions.h"
+
+#define CFReleaseSafe(CF) { CFTypeRef _cf = (CF); if (_cf) CFRelease(_cf); }
+
+#define dateparse(TTYPE, DATE)  SecAbsoluteTimeFromDateContent(ASN1_ ## TTYPE ## _TIME, (const uint8_t *)DATE, sizeof(DATE) - 1); \
+
+#define dateequals(TTYPE, DATE, EXPECTED)  do { \
+    UInt8 string[64]; \
+    CFIndex string_len = 63; \
+    CFAbsoluteTime at = dateparse(TTYPE, DATE); \
+    if (at == NULL_TIME) { \
+        eq_string("NULL_TIME", EXPECTED, "input: " DATE); \
+        break; \
+    } \
+    ds = CFDateFormatterCreateStringWithAbsoluteTime(NULL, df, at); \
+    CFStringGetBytes(ds, CFRangeMake(0, CFStringGetLength(ds)), kCFStringEncodingASCII, ' ', false, string, 63, &string_len); \
+    string[string_len] = 0; \
+    eq_string((const char *)string, EXPECTED, "input: " DATE); \
+    CFReleaseSafe(ds); \
+} while(0)
+
+/* Test SecAbsoluteTimeFromDateContent. */
+static void tests(void)
+{
+    CFLocaleRef ls = CFLocaleGetSystem();
+    CFDateFormatterRef df = CFDateFormatterCreate(NULL, ls, kCFDateFormatterMediumStyle, kCFDateFormatterLongStyle);
+    CFStringRef ds = NULL;
+    CFTimeZoneRef tz = CFTimeZoneCreateWithTimeIntervalFromGMT(NULL, 0.0);
+    if (tz) {
+        CFDateFormatterSetProperty(df, kCFDateFormatterTimeZone, tz);
+        CFRelease(tz);
+    }
+    CFDateFormatterSetFormat(df, CFSTR("yyyyMMddHHmmss"));
+
+    dateequals(UTC, "1101010000Z", "20110101000000");
+    dateequals(UTC, "010101000001Z", "20010101000001");
+    dateequals(GENERALIZED, "201101010000Z", "NULL_TIME"); // Invalid date
+    dateequals(GENERALIZED, "20010101000001Z", "20010101000001");
+
+    dateequals(GENERALIZED, "20000101000000Z", "20000101000000");
+    dateequals(UTC, "990101000000Z", "19990101000000");
+    dateequals(UTC, "710101000000Z", "19710101000000");
+
+    dateequals(UTC, "020101000000+0000", "20020101000000");
+    dateequals(UTC, "020101000000-0800", "20020101080000");
+    dateequals(UTC, "020101000000+0800", "20011231160000");
+    dateequals(UTC, "020101000000-0420", "20020101042000");
+    dateequals(UTC, "020101000013+0430", "20011231193013");
+
+    dateequals(UTC, "0201010000+0000", "NULL_TIME");
+
+    dateequals(GENERALIZED, "20020101000000+0000", "20020101000000");
+    dateequals(GENERALIZED, "20020101000000-0800", "20020101080000");
+    dateequals(GENERALIZED, "20020101000000+0800", "20011231160000");
+    dateequals(GENERALIZED, "20020101000000-0420", "20020101042000");
+    dateequals(GENERALIZED, "20020101000013+0430", "20011231193013");
+
+    dateequals(GENERALIZED, "20060101000013+0900", "20051231150013");
+    dateequals(GENERALIZED, "20090101000013+0900", "20081231150013");
+    dateequals(GENERALIZED, "20110101000013+0900", "20101231150013");
+
+    /* I'd expect these to be off by one second but since they aren't it
+       seems we don't support leap seconds. */
+    dateequals(GENERALIZED, "20051231200013-0900", "20060101050013");
+    dateequals(GENERALIZED, "20081231200013-0900", "20090101050013");
+    dateequals(GENERALIZED, "20101231200013-0900", "20110101050013");
+
+    dateequals(GENERALIZED, "20051231200013+0900", "20051231110013");
+    dateequals(GENERALIZED, "20081231200013+0900", "20081231110013");
+    dateequals(GENERALIZED, "20101231200013+0900", "20101231110013");
+
+    dateequals(GENERALIZED, "19001231200013Z", "19001231200013");
+    dateequals(GENERALIZED, "19811231200013Z", "19811231200013");
+    dateequals(GENERALIZED, "19840229000001Z", "19840229000001");
+    dateequals(GENERALIZED, "19810229000002Z", "NULL_TIME"); // Feb 29 in a non leap-year
+    dateequals(GENERALIZED, "20000001000000Z", "NULL_TIME"); // Month 0
+    dateequals(GENERALIZED, "20000100000000Z", "NULL_TIME"); // Day 0
+    dateequals(GENERALIZED, "20000131000000Z", "20000131000000"); // Day 1/31
+    dateequals(GENERALIZED, "20000132000000Z", "NULL_TIME"); // Day 1/31
+    dateequals(GENERALIZED, "20000229000000Z", "20000229000000"); // Day 2/29
+    dateequals(GENERALIZED, "20000230000000Z", "NULL_TIME"); // Day 2/30
+    dateequals(GENERALIZED, "20010331000000Z", "20010331000000");
+    dateequals(GENERALIZED, "20010332000000Z", "NULL_TIME");
+    dateequals(GENERALIZED, "20010430000000Z", "20010430000000");
+    dateequals(GENERALIZED, "20010431000000Z", "NULL_TIME");
+    dateequals(GENERALIZED, "20010531000000Z", "20010531000000");
+    dateequals(GENERALIZED, "20010532000000Z", "NULL_TIME");
+    dateequals(GENERALIZED, "20010630000000Z", "20010630000000");
+    dateequals(GENERALIZED, "20010631000000Z", "NULL_TIME");
+    dateequals(GENERALIZED, "20010731000000Z", "20010731000000");
+    dateequals(GENERALIZED, "20010732000000Z", "NULL_TIME");
+    dateequals(GENERALIZED, "20010831000000Z", "20010831000000");
+    dateequals(GENERALIZED, "20010832000000Z", "NULL_TIME");
+    dateequals(GENERALIZED, "20010930000000Z", "20010930000000");
+    dateequals(GENERALIZED, "20010931000000Z", "NULL_TIME");
+    dateequals(GENERALIZED, "20011031000000Z", "20011031000000");
+    dateequals(GENERALIZED, "20011032000000Z", "NULL_TIME");
+    dateequals(GENERALIZED, "20011130000000Z", "20011130000000");
+    dateequals(GENERALIZED, "20011131000000Z", "NULL_TIME");
+    dateequals(GENERALIZED, "20011231000000Z", "20011231000000");
+    dateequals(GENERALIZED, "20011232000000Z", "NULL_TIME");
+    dateequals(GENERALIZED, "20011301000000Z", "NULL_TIME");
+
+    dateequals(GENERALIZED, "21000301120000Z", "21000301120000");
+    dateequals(GENERALIZED, "23000301120000Z", "23000301120000");
+    dateequals(GENERALIZED, "24000301120000Z", "24000301120000");
+    dateequals(GENERALIZED, "30000301120000Z", "30000301120000");
+    dateequals(GENERALIZED, "60000228120000Z", "60000228120000");
+    dateequals(GENERALIZED, "60800301120000Z", "60800301120000");
+
+    CFReleaseSafe(df);
+}
+
+int si_14_dateparse(int argc, char *const *argv)
+{
+       plan_tests(64);
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-15-certificate.c b/sec/Security/Regressions/secitem/si-15-certificate.c
new file mode 100644 (file)
index 0000000..5bffe1d
--- /dev/null
@@ -0,0 +1,783 @@
+/*
+ * Copyright (c) 2008-2010 Apple Inc. All Rights Reserved.
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecPolicy.h>
+#include <Security/SecTrust.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "Security_regressions.h"
+
+/*
+    Apple Inc. CA
+*/
+static const uint8_t _c0[] = {
+    0x30, 0x82, 0x04, 0xbb, 0x30, 0x82, 0x03, 0xa3,
+    0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x02,
+    0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+    0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
+    0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+    0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
+    0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+    0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49,
+    0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06,
+    0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70,
+    0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74,
+    0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+    0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+    0x69, 0x74, 0x79, 0x31, 0x16, 0x30, 0x14, 0x06,
+    0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x41, 0x70,
+    0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74,
+    0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x30,
+    0x36, 0x30, 0x34, 0x32, 0x35, 0x32, 0x31, 0x34,
+    0x30, 0x33, 0x36, 0x5a, 0x17, 0x0d, 0x33, 0x35,
+    0x30, 0x32, 0x30, 0x39, 0x32, 0x31, 0x34, 0x30,
+    0x33, 0x36, 0x5a, 0x30, 0x62, 0x31, 0x0b, 0x30,
+    0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+    0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
+    0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70,
+    0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
+    0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b,
+    0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20,
+    0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+    0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
+    0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31,
+    0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03,
+    0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20,
+    0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30,
+    0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+    0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
+    0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30,
+    0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00,
+    0xe4, 0x91, 0xa9, 0x09, 0x1f, 0x91, 0xdb, 0x1e,
+    0x47, 0x50, 0xeb, 0x05, 0xed, 0x5e, 0x79, 0x84,
+    0x2d, 0xeb, 0x36, 0xa2, 0x57, 0x4c, 0x55, 0xec,
+    0x8b, 0x19, 0x89, 0xde, 0xf9, 0x4b, 0x6c, 0xf5,
+    0x07, 0xab, 0x22, 0x30, 0x02, 0xe8, 0x18, 0x3e,
+    0xf8, 0x50, 0x09, 0xd3, 0x7f, 0x41, 0xa8, 0x98,
+    0xf9, 0xd1, 0xca, 0x66, 0x9c, 0x24, 0x6b, 0x11,
+    0xd0, 0xa3, 0xbb, 0xe4, 0x1b, 0x2a, 0xc3, 0x1f,
+    0x95, 0x9e, 0x7a, 0x0c, 0xa4, 0x47, 0x8b, 0x5b,
+    0xd4, 0x16, 0x37, 0x33, 0xcb, 0xc4, 0x0f, 0x4d,
+    0xce, 0x14, 0x69, 0xd1, 0xc9, 0x19, 0x72, 0xf5,
+    0x5d, 0x0e, 0xd5, 0x7f, 0x5f, 0x9b, 0xf2, 0x25,
+    0x03, 0xba, 0x55, 0x8f, 0x4d, 0x5d, 0x0d, 0xf1,
+    0x64, 0x35, 0x23, 0x15, 0x4b, 0x15, 0x59, 0x1d,
+    0xb3, 0x94, 0xf7, 0xf6, 0x9c, 0x9e, 0xcf, 0x50,
+    0xba, 0xc1, 0x58, 0x50, 0x67, 0x8f, 0x08, 0xb4,
+    0x20, 0xf7, 0xcb, 0xac, 0x2c, 0x20, 0x6f, 0x70,
+    0xb6, 0x3f, 0x01, 0x30, 0x8c, 0xb7, 0x43, 0xcf,
+    0x0f, 0x9d, 0x3d, 0xf3, 0x2b, 0x49, 0x28, 0x1a,
+    0xc8, 0xfe, 0xce, 0xb5, 0xb9, 0x0e, 0xd9, 0x5e,
+    0x1c, 0xd6, 0xcb, 0x3d, 0xb5, 0x3a, 0xad, 0xf4,
+    0x0f, 0x0e, 0x00, 0x92, 0x0b, 0xb1, 0x21, 0x16,
+    0x2e, 0x74, 0xd5, 0x3c, 0x0d, 0xdb, 0x62, 0x16,
+    0xab, 0xa3, 0x71, 0x92, 0x47, 0x53, 0x55, 0xc1,
+    0xaf, 0x2f, 0x41, 0xb3, 0xf8, 0xfb, 0xe3, 0x70,
+    0xcd, 0xe6, 0xa3, 0x4c, 0x45, 0x7e, 0x1f, 0x4c,
+    0x6b, 0x50, 0x96, 0x41, 0x89, 0xc4, 0x74, 0x62,
+    0x0b, 0x10, 0x83, 0x41, 0x87, 0x33, 0x8a, 0x81,
+    0xb1, 0x30, 0x58, 0xec, 0x5a, 0x04, 0x32, 0x8c,
+    0x68, 0xb3, 0x8f, 0x1d, 0xde, 0x65, 0x73, 0xff,
+    0x67, 0x5e, 0x65, 0xbc, 0x49, 0xd8, 0x76, 0x9f,
+    0x33, 0x14, 0x65, 0xa1, 0x77, 0x94, 0xc9, 0x2d,
+    0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01,
+    0x7a, 0x30, 0x82, 0x01, 0x76, 0x30, 0x0e, 0x06,
+    0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04,
+    0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0f, 0x06,
+    0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04,
+    0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d,
+    0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
+    0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76, 0x09,
+    0xfe, 0xf4, 0x6b, 0x8d, 0x2e, 0x40, 0xa6, 0xf7,
+    0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x1f, 0x06,
+    0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
+    0x80, 0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76,
+    0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e, 0x40, 0xa6,
+    0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x82,
+    0x01, 0x11, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04,
+    0x82, 0x01, 0x08, 0x30, 0x82, 0x01, 0x04, 0x30,
+    0x82, 0x01, 0x00, 0x06, 0x09, 0x2a, 0x86, 0x48,
+    0x86, 0xf7, 0x63, 0x64, 0x05, 0x01, 0x30, 0x81,
+    0xf2, 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01,
+    0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1e, 0x68,
+    0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77,
+    0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65,
+    0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x70,
+    0x6c, 0x65, 0x63, 0x61, 0x2f, 0x30, 0x81, 0xc3,
+    0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+    0x02, 0x02, 0x30, 0x81, 0xb6, 0x1a, 0x81, 0xb3,
+    0x52, 0x65, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65,
+    0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73,
+    0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+    0x63, 0x61, 0x74, 0x65, 0x20, 0x62, 0x79, 0x20,
+    0x61, 0x6e, 0x79, 0x20, 0x70, 0x61, 0x72, 0x74,
+    0x79, 0x20, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65,
+    0x73, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74,
+    0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20,
+    0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e,
+    0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61,
+    0x62, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e,
+    0x64, 0x61, 0x72, 0x64, 0x20, 0x74, 0x65, 0x72,
+    0x6d, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63,
+    0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e,
+    0x73, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65,
+    0x2c, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66,
+    0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x70, 0x6f,
+    0x6c, 0x69, 0x63, 0x79, 0x20, 0x61, 0x6e, 0x64,
+    0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+    0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70,
+    0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x20,
+    0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
+    0x74, 0x73, 0x2e, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+    0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
+    0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x5c,
+    0x36, 0x99, 0x4c, 0x2d, 0x78, 0xb7, 0xed, 0x8c,
+    0x9b, 0xdc, 0xf3, 0x77, 0x9b, 0xf2, 0x76, 0xd2,
+    0x77, 0x30, 0x4f, 0xc1, 0x1f, 0x85, 0x83, 0x85,
+    0x1b, 0x99, 0x3d, 0x47, 0x37, 0xf2, 0xa9, 0x9b,
+    0x40, 0x8e, 0x2c, 0xd4, 0xb1, 0x90, 0x12, 0xd8,
+    0xbe, 0xf4, 0x73, 0x9b, 0xee, 0xd2, 0x64, 0x0f,
+    0xcb, 0x79, 0x4f, 0x34, 0xd8, 0xa2, 0x3e, 0xf9,
+    0x78, 0xff, 0x6b, 0xc8, 0x07, 0xec, 0x7d, 0x39,
+    0x83, 0x8b, 0x53, 0x20, 0xd3, 0x38, 0xc4, 0xb1,
+    0xbf, 0x9a, 0x4f, 0x0a, 0x6b, 0xff, 0x2b, 0xfc,
+    0x59, 0xa7, 0x05, 0x09, 0x7c, 0x17, 0x40, 0x56,
+    0x11, 0x1e, 0x74, 0xd3, 0xb7, 0x8b, 0x23, 0x3b,
+    0x47, 0xa3, 0xd5, 0x6f, 0x24, 0xe2, 0xeb, 0xd1,
+    0xb7, 0x70, 0xdf, 0x0f, 0x45, 0xe1, 0x27, 0xca,
+    0xf1, 0x6d, 0x78, 0xed, 0xe7, 0xb5, 0x17, 0x17,
+    0xa8, 0xdc, 0x7e, 0x22, 0x35, 0xca, 0x25, 0xd5,
+    0xd9, 0x0f, 0xd6, 0x6b, 0xd4, 0xa2, 0x24, 0x23,
+    0x11, 0xf7, 0xa1, 0xac, 0x8f, 0x73, 0x81, 0x60,
+    0xc6, 0x1b, 0x5b, 0x09, 0x2f, 0x92, 0xb2, 0xf8,
+    0x44, 0x48, 0xf0, 0x60, 0x38, 0x9e, 0x15, 0xf5,
+    0x3d, 0x26, 0x67, 0x20, 0x8a, 0x33, 0x6a, 0xf7,
+    0x0d, 0x82, 0xcf, 0xde, 0xeb, 0xa3, 0x2f, 0xf9,
+    0x53, 0x6a, 0x5b, 0x64, 0xc0, 0x63, 0x33, 0x77,
+    0xf7, 0x3a, 0x07, 0x2c, 0x56, 0xeb, 0xda, 0x0f,
+    0x21, 0x0e, 0xda, 0xba, 0x73, 0x19, 0x4f, 0xb5,
+    0xd9, 0x36, 0x7f, 0xc1, 0x87, 0x55, 0xd9, 0xa7,
+    0x99, 0xb9, 0x32, 0x42, 0xfb, 0xd8, 0xd5, 0x71,
+    0x9e, 0x7e, 0xa1, 0x52, 0xb7, 0x1b, 0xbd, 0x93,
+    0x42, 0x24, 0x12, 0x2a, 0xc7, 0x0f, 0x1d, 0xb6,
+    0x4d, 0x9c, 0x5e, 0x63, 0xc8, 0x4b, 0x80, 0x17,
+    0x50, 0xaa, 0x8a, 0xd5, 0xda, 0xe4, 0xfc, 0xd0,
+    0x09, 0x07, 0x37, 0xb0, 0x75, 0x75, 0x21,
+};
+
+/*
+       subject= /O=VeriSign Trust Network/OU=VeriSign, Inc./OU=VeriSign International Server CA - Class 3/OU=www.verisign.com/CPS Incorp.by Ref. LIABILITY LTD.(c)97 VeriSign
+       issuer= /C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
+       serial=254B8A853842CCE358F8C5DDAE226EA4
+*/
+static const uint8_t _c1[] = {
+    0x30, 0x82, 0x03, 0x83, 0x30, 0x82, 0x02, 0xec,
+    0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x25,
+    0x4b, 0x8a, 0x85, 0x38, 0x42, 0xcc, 0xe3, 0x58,
+    0xf8, 0xc5, 0xdd, 0xae, 0x22, 0x6e, 0xa4, 0x30,
+    0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+    0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 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, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e,
+    0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x37,
+    0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
+    0x2e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33,
+    0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20,
+    0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20,
+    0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+    0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
+    0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30,
+    0x1e, 0x17, 0x0d, 0x39, 0x37, 0x30, 0x34, 0x31,
+    0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
+    0x17, 0x0d, 0x31, 0x31, 0x31, 0x30, 0x32, 0x34,
+    0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30,
+    0x81, 0xba, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03,
+    0x55, 0x04, 0x0a, 0x13, 0x16, 0x56, 0x65, 0x72,
+    0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72,
+    0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77,
+    0x6f, 0x72, 0x6b, 0x31, 0x17, 0x30, 0x15, 0x06,
+    0x03, 0x55, 0x04, 0x0b, 0x13, 0x0e, 0x56, 0x65,
+    0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20,
+    0x49, 0x6e, 0x63, 0x2e, 0x31, 0x33, 0x30, 0x31,
+    0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56,
+    0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20,
+    0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74,
+    0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65,
+    0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x20,
+    0x2d, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20,
+    0x33, 0x31, 0x49, 0x30, 0x47, 0x06, 0x03, 0x55,
+    0x04, 0x0b, 0x13, 0x40, 0x77, 0x77, 0x77, 0x2e,
+    0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e,
+    0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x50, 0x53,
+    0x20, 0x49, 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x2e,
+    0x62, 0x79, 0x20, 0x52, 0x65, 0x66, 0x2e, 0x20,
+    0x4c, 0x49, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54,
+    0x59, 0x20, 0x4c, 0x54, 0x44, 0x2e, 0x28, 0x63,
+    0x29, 0x39, 0x37, 0x20, 0x56, 0x65, 0x72, 0x69,
+    0x53, 0x69, 0x67, 0x6e, 0x30, 0x81, 0x9f, 0x30,
+    0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+    0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81,
+    0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81,
+    0x00, 0xd8, 0x82, 0x80, 0xe8, 0xd6, 0x19, 0x02,
+    0x7d, 0x1f, 0x85, 0x18, 0x39, 0x25, 0xa2, 0x65,
+    0x2b, 0xe1, 0xbf, 0xd4, 0x05, 0xd3, 0xbc, 0xe6,
+    0x36, 0x3b, 0xaa, 0xf0, 0x4c, 0x6c, 0x5b, 0xb6,
+    0xe7, 0xaa, 0x3c, 0x73, 0x45, 0x55, 0xb2, 0xf1,
+    0xbd, 0xea, 0x97, 0x42, 0xed, 0x9a, 0x34, 0x0a,
+    0x15, 0xd4, 0xa9, 0x5c, 0xf5, 0x40, 0x25, 0xdd,
+    0xd9, 0x07, 0xc1, 0x32, 0xb2, 0x75, 0x6c, 0xc4,
+    0xca, 0xbb, 0xa3, 0xfe, 0x56, 0x27, 0x71, 0x43,
+    0xaa, 0x63, 0xf5, 0x30, 0x3e, 0x93, 0x28, 0xe5,
+    0xfa, 0xf1, 0x09, 0x3b, 0xf3, 0xb7, 0x4d, 0x4e,
+    0x39, 0xf7, 0x5c, 0x49, 0x5a, 0xb8, 0xc1, 0x1d,
+    0xd3, 0xb2, 0x8a, 0xfe, 0x70, 0x30, 0x95, 0x42,
+    0xcb, 0xfe, 0x2b, 0x51, 0x8b, 0x5a, 0x3c, 0x3a,
+    0xf9, 0x22, 0x4f, 0x90, 0xb2, 0x02, 0xa7, 0x53,
+    0x9c, 0x4f, 0x34, 0xe7, 0xab, 0x04, 0xb2, 0x7b,
+    0x6f, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81,
+    0xe3, 0x30, 0x81, 0xe0, 0x30, 0x0f, 0x06, 0x03,
+    0x55, 0x1d, 0x13, 0x04, 0x08, 0x30, 0x06, 0x01,
+    0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x44, 0x06,
+    0x03, 0x55, 0x1d, 0x20, 0x04, 0x3d, 0x30, 0x3b,
+    0x30, 0x39, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01,
+    0x86, 0xf8, 0x45, 0x01, 0x07, 0x01, 0x01, 0x30,
+    0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01,
+    0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68,
+    0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77,
+    0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73,
+    0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+    0x43, 0x50, 0x53, 0x30, 0x34, 0x06, 0x03, 0x55,
+    0x1d, 0x25, 0x04, 0x2d, 0x30, 0x2b, 0x06, 0x08,
+    0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01,
+    0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+    0x03, 0x02, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
+    0x86, 0xf8, 0x42, 0x04, 0x01, 0x06, 0x0a, 0x60,
+    0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x08,
+    0x01, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f,
+    0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x11,
+    0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8,
+    0x42, 0x01, 0x01, 0x04, 0x04, 0x03, 0x02, 0x01,
+    0x06, 0x30, 0x31, 0x06, 0x03, 0x55, 0x1d, 0x1f,
+    0x04, 0x2a, 0x30, 0x28, 0x30, 0x26, 0xa0, 0x24,
+    0xa0, 0x22, 0x86, 0x20, 0x68, 0x74, 0x74, 0x70,
+    0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x76,
+    0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e,
+    0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63, 0x61, 0x33,
+    0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0d, 0x06, 0x09,
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+    0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x08,
+    0x01, 0xec, 0xe4, 0x68, 0x94, 0x03, 0x42, 0xf1,
+    0x73, 0xf1, 0x23, 0xa2, 0x3a, 0xde, 0xe9, 0xf1,
+    0xda, 0xc6, 0x54, 0xc4, 0x23, 0x3e, 0x86, 0xea,
+    0xcf, 0x6a, 0x3a, 0x33, 0xab, 0xea, 0x9c, 0x04,
+    0x14, 0x07, 0x36, 0x06, 0x0b, 0xf9, 0x88, 0x6f,
+    0xd5, 0x13, 0xee, 0x29, 0x2b, 0xc3, 0xe4, 0x72,
+    0x8d, 0x44, 0xed, 0xd1, 0xac, 0x20, 0x09, 0x2d,
+    0xe1, 0xf6, 0xe1, 0x19, 0x05, 0x38, 0xb0, 0x3d,
+    0x0f, 0x9f, 0x7f, 0xf8, 0x9e, 0x02, 0xdc, 0x86,
+    0x02, 0x86, 0x61, 0x4e, 0x26, 0x5f, 0x5e, 0x9f,
+    0x92, 0x1e, 0x0c, 0x24, 0xa4, 0xf5, 0xd0, 0x70,
+    0x13, 0xcf, 0x26, 0xc3, 0x43, 0x3d, 0x49, 0x1d,
+    0x9e, 0x82, 0x2e, 0x52, 0x5f, 0xbc, 0x3e, 0xc6,
+    0x66, 0x29, 0x01, 0x8e, 0x4e, 0x92, 0x2c, 0xbc,
+    0x46, 0x75, 0x03, 0x82, 0xac, 0x73, 0xe9, 0xd9,
+    0x7e, 0x0b, 0x67, 0xef, 0x54, 0x52, 0x1a
+};
+
+
+/*
+   subject= /C=US/O=University of Virginia/OU=UVA Standard PKI User/emailAddress=kmm6b@Virginia.EDU/CN=Keith M. Moores 10
+   issuer= /C=US/ST=Virginia/L=Charlottesville/O=University of Virginia/emailAddress=pkimaster@virginia.edu/CN=UVA Standard Assurance SKP 1
+   serial=0C6D
+*/
+static const uint8_t _c2[] = {
+    0x30, 0x82, 0x05, 0x56, 0x30, 0x82, 0x04, 0xbf,
+    0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x0c,
+    0x6d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+    0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,
+    0x30, 0x81, 0xa9, 0x31, 0x0b, 0x30, 0x09, 0x06,
+    0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
+    0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04,
+    0x08, 0x13, 0x08, 0x56, 0x69, 0x72, 0x67, 0x69,
+    0x6e, 0x69, 0x61, 0x31, 0x18, 0x30, 0x16, 0x06,
+    0x03, 0x55, 0x04, 0x07, 0x13, 0x0f, 0x43, 0x68,
+    0x61, 0x72, 0x6c, 0x6f, 0x74, 0x74, 0x65, 0x73,
+    0x76, 0x69, 0x6c, 0x6c, 0x65, 0x31, 0x1f, 0x30,
+    0x1d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x16,
+    0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x69,
+    0x74, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x56, 0x69,
+    0x72, 0x67, 0x69, 0x6e, 0x69, 0x61, 0x31, 0x25,
+    0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+    0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x16, 0x70,
+    0x6b, 0x69, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72,
+    0x40, 0x76, 0x69, 0x72, 0x67, 0x69, 0x6e, 0x69,
+    0x61, 0x2e, 0x65, 0x64, 0x75, 0x31, 0x25, 0x30,
+    0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1c,
+    0x55, 0x56, 0x41, 0x20, 0x53, 0x74, 0x61, 0x6e,
+    0x64, 0x61, 0x72, 0x64, 0x20, 0x41, 0x73, 0x73,
+    0x75, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x53,
+    0x4b, 0x50, 0x20, 0x31, 0x30, 0x1e, 0x17, 0x0d,
+    0x30, 0x34, 0x30, 0x31, 0x30, 0x38, 0x31, 0x37,
+    0x32, 0x35, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30,
+    0x35, 0x30, 0x31, 0x30, 0x38, 0x31, 0x37, 0x32,
+    0x35, 0x30, 0x30, 0x5a, 0x30, 0x81, 0x8e, 0x31,
+    0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+    0x13, 0x02, 0x55, 0x53, 0x31, 0x1f, 0x30, 0x1d,
+    0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x16, 0x55,
+    0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x69, 0x74,
+    0x79, 0x20, 0x6f, 0x66, 0x20, 0x56, 0x69, 0x72,
+    0x67, 0x69, 0x6e, 0x69, 0x61, 0x31, 0x1e, 0x30,
+    0x1c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x15,
+    0x55, 0x56, 0x41, 0x20, 0x53, 0x74, 0x61, 0x6e,
+    0x64, 0x61, 0x72, 0x64, 0x20, 0x50, 0x4b, 0x49,
+    0x20, 0x55, 0x73, 0x65, 0x72, 0x31, 0x21, 0x30,
+    0x1f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+    0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x6b, 0x6d,
+    0x6d, 0x36, 0x62, 0x40, 0x56, 0x69, 0x72, 0x67,
+    0x69, 0x6e, 0x69, 0x61, 0x2e, 0x45, 0x44, 0x55,
+    0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04,
+    0x03, 0x13, 0x12, 0x4b, 0x65, 0x69, 0x74, 0x68,
+    0x20, 0x4d, 0x2e, 0x20, 0x4d, 0x6f, 0x6f, 0x72,
+    0x65, 0x73, 0x20, 0x31, 0x30, 0x30, 0x81, 0x9f,
+    0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+    0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
+    0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81,
+    0x81, 0x00, 0xb4, 0xf9, 0x1b, 0xda, 0x10, 0x01,
+    0x47, 0x96, 0xb4, 0xea, 0xb2, 0x35, 0xbb, 0x7e,
+    0x69, 0x69, 0xd9, 0x49, 0x2c, 0x36, 0x3a, 0x27,
+    0x55, 0x6e, 0x11, 0xb1, 0xdf, 0x13, 0x54, 0xf2,
+    0x66, 0xa5, 0x98, 0x3a, 0xfd, 0x7e, 0xda, 0x6d,
+    0x12, 0xb7, 0x06, 0xaa, 0xde, 0x55, 0x50, 0x04,
+    0xf5, 0x91, 0x27, 0xc7, 0x4d, 0x85, 0x91, 0xd9,
+    0xc5, 0xd6, 0x88, 0xc6, 0x33, 0x40, 0x83, 0xc0,
+    0xe4, 0x83, 0xe2, 0x9f, 0x49, 0xfb, 0xc1, 0x1f,
+    0xdb, 0xd9, 0xf4, 0xd4, 0x32, 0x2e, 0x3a, 0xe9,
+    0xb4, 0x12, 0x5d, 0x58, 0x2a, 0x65, 0x4e, 0xc7,
+    0x09, 0x59, 0xfc, 0x2b, 0x0d, 0xda, 0x6a, 0xc3,
+    0x9f, 0x32, 0x7d, 0xf2, 0xfc, 0xf4, 0x3e, 0xb8,
+    0x63, 0xbc, 0x13, 0x74, 0xc6, 0x0e, 0x76, 0x3a,
+    0x7a, 0xe9, 0x93, 0x97, 0x7f, 0xc8, 0x2b, 0x33,
+    0x9f, 0xd8, 0x59, 0xef, 0xc0, 0x0a, 0x2e, 0xd3,
+    0xd9, 0x69, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
+    0x82, 0x02, 0xa4, 0x30, 0x82, 0x02, 0xa0, 0x30,
+    0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04,
+    0x03, 0x02, 0x05, 0xa0, 0x30, 0x1d, 0x06, 0x03,
+    0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06,
+    0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03,
+    0x02, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+    0x07, 0x03, 0x04, 0x30, 0x1d, 0x06, 0x03, 0x55,
+    0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x4d, 0xe0,
+    0xe1, 0x57, 0xb6, 0x91, 0x7a, 0x34, 0x99, 0x7a,
+    0xe5, 0x2a, 0xd6, 0xae, 0x0a, 0x75, 0x05, 0x73,
+    0x5d, 0x30, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d,
+    0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1f, 0x06,
+    0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
+    0x80, 0x14, 0x2c, 0xb7, 0xe3, 0xa6, 0x09, 0x68,
+    0x85, 0x90, 0x58, 0x8e, 0x2d, 0xd5, 0x3a, 0xef,
+    0x93, 0x02, 0x2a, 0x4c, 0x85, 0x62, 0x30, 0x41,
+    0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x3a, 0x30,
+    0x38, 0xa0, 0x22, 0x06, 0x0a, 0x2b, 0x06, 0x01,
+    0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x03, 0xa0,
+    0x14, 0x0c, 0x12, 0x6b, 0x6d, 0x6d, 0x36, 0x62,
+    0x40, 0x56, 0x69, 0x72, 0x67, 0x69, 0x6e, 0x69,
+    0x61, 0x2e, 0x45, 0x44, 0x55, 0x81, 0x12, 0x6b,
+    0x6d, 0x6d, 0x36, 0x62, 0x40, 0x56, 0x69, 0x72,
+    0x67, 0x69, 0x6e, 0x69, 0x61, 0x2e, 0x45, 0x44,
+    0x55, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x1d, 0x12,
+    0x04, 0x28, 0x30, 0x26, 0x81, 0x16, 0x70, 0x6b,
+    0x69, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x40,
+    0x56, 0x69, 0x72, 0x67, 0x69, 0x6e, 0x69, 0x61,
+    0x2e, 0x45, 0x44, 0x55, 0x82, 0x0c, 0x56, 0x69,
+    0x72, 0x67, 0x69, 0x6e, 0x69, 0x61, 0x2e, 0x45,
+    0x44, 0x55, 0x30, 0x82, 0x01, 0x5c, 0x06, 0x03,
+    0x55, 0x1d, 0x1f, 0x04, 0x82, 0x01, 0x53, 0x30,
+    0x82, 0x01, 0x4f, 0x30, 0x74, 0xa0, 0x72, 0xa0,
+    0x70, 0x86, 0x6e, 0x6c, 0x64, 0x61, 0x70, 0x3a,
+    0x2f, 0x2f, 0x6c, 0x64, 0x61, 0x70, 0x2e, 0x70,
+    0x6b, 0x69, 0x2e, 0x76, 0x69, 0x72, 0x67, 0x69,
+    0x6e, 0x69, 0x61, 0x2e, 0x65, 0x64, 0x75, 0x2f,
+    0x63, 0x3d, 0x55, 0x53, 0x2c, 0x6f, 0x3d, 0x55,
+    0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x69, 0x74,
+    0x79, 0x25, 0x32, 0x30, 0x6f, 0x66, 0x25, 0x32,
+    0x30, 0x56, 0x69, 0x72, 0x67, 0x69, 0x6e, 0x69,
+    0x61, 0x2c, 0x6f, 0x75, 0x3d, 0x55, 0x56, 0x41,
+    0x25, 0x32, 0x30, 0x53, 0x74, 0x61, 0x6e, 0x64,
+    0x61, 0x72, 0x64, 0x25, 0x32, 0x30, 0x41, 0x73,
+    0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x25,
+    0x32, 0x30, 0x53, 0x4b, 0x50, 0x25, 0x32, 0x30,
+    0x31, 0x2c, 0x63, 0x6e, 0x3d, 0x30, 0x43, 0x36,
+    0x44, 0x30, 0x74, 0xa0, 0x72, 0xa0, 0x70, 0x86,
+    0x6e, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f,
+    0x6c, 0x64, 0x61, 0x70, 0x2e, 0x70, 0x6b, 0x69,
+    0x2e, 0x76, 0x69, 0x72, 0x67, 0x69, 0x6e, 0x69,
+    0x61, 0x2e, 0x65, 0x64, 0x75, 0x2f, 0x63, 0x6e,
+    0x3d, 0x30, 0x43, 0x36, 0x44, 0x2c, 0x6f, 0x75,
+    0x3d, 0x55, 0x56, 0x41, 0x25, 0x32, 0x30, 0x53,
+    0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x25,
+    0x32, 0x30, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61,
+    0x6e, 0x63, 0x65, 0x25, 0x32, 0x30, 0x53, 0x4b,
+    0x50, 0x25, 0x32, 0x30, 0x31, 0x2c, 0x6f, 0x3d,
+    0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x69,
+    0x74, 0x79, 0x25, 0x32, 0x30, 0x6f, 0x66, 0x25,
+    0x32, 0x30, 0x56, 0x69, 0x72, 0x67, 0x69, 0x6e,
+    0x69, 0x61, 0x2c, 0x63, 0x3d, 0x55, 0x53, 0x30,
+    0x61, 0xa0, 0x5f, 0xa0, 0x5d, 0x86, 0x5b, 0x68,
+    0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77,
+    0x77, 0x2e, 0x70, 0x6b, 0x69, 0x2e, 0x76, 0x69,
+    0x72, 0x67, 0x69, 0x6e, 0x69, 0x61, 0x2e, 0x65,
+    0x64, 0x75, 0x2f, 0x63, 0x67, 0x69, 0x2d, 0x62,
+    0x69, 0x6e, 0x2f, 0x67, 0x65, 0x74, 0x2d, 0x63,
+    0x72, 0x6c, 0x3f, 0x6f, 0x75, 0x3d, 0x55, 0x56,
+    0x41, 0x25, 0x32, 0x30, 0x53, 0x74, 0x61, 0x6e,
+    0x64, 0x61, 0x72, 0x64, 0x25, 0x32, 0x30, 0x41,
+    0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, 0x65,
+    0x25, 0x32, 0x30, 0x53, 0x4b, 0x50, 0x25, 0x32,
+    0x30, 0x31, 0x26, 0x63, 0x6e, 0x3d, 0x30, 0x43,
+    0x36, 0x44, 0x30, 0x53, 0x06, 0x03, 0x55, 0x1d,
+    0x20, 0x04, 0x4c, 0x30, 0x4a, 0x30, 0x48, 0x06,
+    0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xb4, 0x76,
+    0x01, 0x01, 0x30, 0x3b, 0x30, 0x39, 0x06, 0x08,
+    0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01,
+    0x16, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+    0x2f, 0x77, 0x77, 0x77, 0x2e, 0x70, 0x6b, 0x69,
+    0x2e, 0x76, 0x69, 0x72, 0x67, 0x69, 0x6e, 0x69,
+    0x61, 0x2e, 0x65, 0x64, 0x75, 0x2f, 0x73, 0x74,
+    0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x2f, 0x63,
+    0x70, 0x73, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x30,
+    0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+    0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81,
+    0x81, 0x00, 0x9f, 0xf2, 0x7f, 0x51, 0x97, 0x2c,
+    0xe6, 0x8f, 0x50, 0xba, 0x75, 0xd8, 0x9c, 0x77,
+    0x5e, 0x2a, 0xe9, 0xbe, 0x18, 0x37, 0x7f, 0x18,
+    0x86, 0xbb, 0x9d, 0x22, 0xf2, 0xf9, 0x3e, 0x22,
+    0x00, 0x0b, 0xf2, 0x41, 0x6b, 0x08, 0x17, 0xbc,
+    0x7a, 0xc4, 0xc9, 0x99, 0xa0, 0xbd, 0x53, 0x8d,
+    0x52, 0xdb, 0xcc, 0xd0, 0x88, 0x14, 0x2a, 0x05,
+    0x93, 0xcd, 0xf3, 0xa0, 0xf3, 0xb9, 0xdb, 0x35,
+    0x5c, 0xec, 0x24, 0xe8, 0x08, 0xbe, 0x4e, 0xa1,
+    0xa2, 0x54, 0x41, 0xbc, 0xbe, 0x7b, 0x22, 0xf4,
+    0x03, 0x7d, 0xd0, 0xfb, 0x25, 0x8d, 0xf5, 0xa9,
+    0x04, 0x14, 0xe9, 0xe3, 0x3e, 0x3f, 0x13, 0x6f,
+    0x89, 0x72, 0x76, 0x41, 0x67, 0x8a, 0x48, 0x2a,
+    0x36, 0xf0, 0xe6, 0xb9, 0x33, 0x35, 0x88, 0xda,
+    0x27, 0x9d, 0xf9, 0x5d, 0x42, 0x04, 0x6f, 0x7d,
+    0x60, 0x53, 0x86, 0xf2, 0xf4, 0x3b, 0x3d, 0xbe,
+    0x1d, 0x99,
+};
+
+/* subject:/C=US/O=Apple Computer, Inc./OU=mac.com/CN=phased/description=.Mac Sharing Certificate */
+/* issuer :/C=US/O=Apple Computer, Inc./OU=Apple Computer Certificate Authority/CN=Apple .Mac Certificate Authority */
+static unsigned char _phased_c3[1376]={
+0x30,0x82,0x05,0x5C,0x30,0x82,0x04,0x44,0xA0,0x03,0x02,0x01,0x02,0x02,0x03,0x20,
+0x7D,0xC7,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,
+0x00,0x30,0x81,0x86,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
+0x53,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x0A,0x13,0x14,0x41,0x70,0x70,0x6C,
+0x65,0x20,0x43,0x6F,0x6D,0x70,0x75,0x74,0x65,0x72,0x2C,0x20,0x49,0x6E,0x63,0x2E,
+0x31,0x2D,0x30,0x2B,0x06,0x03,0x55,0x04,0x0B,0x13,0x24,0x41,0x70,0x70,0x6C,0x65,
+0x20,0x43,0x6F,0x6D,0x70,0x75,0x74,0x65,0x72,0x20,0x43,0x65,0x72,0x74,0x69,0x66,
+0x69,0x63,0x61,0x74,0x65,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x31,
+0x29,0x30,0x27,0x06,0x03,0x55,0x04,0x03,0x13,0x20,0x41,0x70,0x70,0x6C,0x65,0x20,
+0x2E,0x4D,0x61,0x63,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,
+0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x30,0x37,
+0x31,0x30,0x32,0x38,0x31,0x38,0x35,0x34,0x35,0x33,0x5A,0x17,0x0D,0x30,0x38,0x31,
+0x30,0x32,0x38,0x31,0x38,0x35,0x34,0x35,0x33,0x5A,0x30,0x72,0x31,0x0B,0x30,0x09,
+0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55,
+0x04,0x0A,0x13,0x14,0x41,0x70,0x70,0x6C,0x65,0x20,0x43,0x6F,0x6D,0x70,0x75,0x74,
+0x65,0x72,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,
+0x0B,0x13,0x07,0x6D,0x61,0x63,0x2E,0x63,0x6F,0x6D,0x31,0x0F,0x30,0x0D,0x06,0x03,
+0x55,0x04,0x03,0x13,0x06,0x70,0x68,0x61,0x73,0x65,0x64,0x31,0x21,0x30,0x1F,0x06,
+0x03,0x55,0x04,0x0D,0x13,0x18,0x2E,0x4D,0x61,0x63,0x20,0x53,0x68,0x61,0x72,0x69,
+0x6E,0x67,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x30,0x81,
+0x9F,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,
+0x03,0x81,0x8D,0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xC0,0xFB,0x0E,0x62,0xD3,
+0xE2,0xCC,0xC7,0x54,0x6A,0x4F,0x9C,0x4E,0x40,0x9D,0x30,0x3D,0x60,0x86,0x00,0x7C,
+0x33,0x0C,0x2E,0x2E,0x45,0xDF,0xBE,0xEB,0x94,0xE7,0xD6,0xBE,0x6B,0x0F,0x7B,0x88,
+0x3C,0x02,0xA7,0x25,0x5E,0x18,0xC6,0x97,0xF0,0x0C,0xDD,0x89,0x22,0x27,0x9C,0x85,
+0x25,0x36,0x95,0x61,0x26,0xE7,0x6C,0x7E,0x41,0xDE,0xFF,0x5D,0x77,0xCB,0xE6,0x05,
+0xB0,0xAD,0x77,0xC9,0xFC,0xA5,0xF1,0x82,0x1A,0xB4,0xE4,0x26,0x8D,0x1B,0xC3,0xE2,
+0xEF,0x6A,0xE0,0xEE,0xF3,0x38,0x27,0xE1,0x73,0x9E,0xD0,0x93,0x6A,0xA6,0xD5,0xD1,
+0xEC,0xE5,0x0D,0x4B,0x3A,0x42,0x8C,0xF1,0xE1,0x24,0x0A,0x02,0x0D,0x22,0xAE,0xEC,
+0x47,0xDA,0xFA,0x6B,0x12,0x50,0x47,0x2E,0x4A,0xD8,0x9F,0x02,0x03,0x01,0x00,0x01,
+0xA3,0x82,0x02,0x68,0x30,0x82,0x02,0x64,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,
+0x01,0xFF,0x04,0x02,0x30,0x00,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,
+0x04,0x04,0x03,0x02,0x03,0x88,0x30,0x28,0x06,0x03,0x55,0x1D,0x25,0x04,0x21,0x30,
+0x1F,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x0A,0x2A,0x86,0x48,
+0x86,0xF7,0x63,0x64,0x03,0x02,0x01,0x06,0x07,0x2B,0x06,0x01,0x05,0x02,0x03,0x04,
+0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x3D,0xD9,0xDD,0x8F,0x5B,
+0x5E,0xA3,0x3A,0x8C,0x89,0x7F,0x8A,0x85,0x26,0xA7,0x84,0x0E,0xF3,0x0D,0x82,0x30,
+0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x7A,0x7D,0x90,0xB1,
+0x30,0x59,0x08,0x92,0x91,0xF9,0x53,0xB9,0x71,0x1D,0x35,0x33,0x67,0x34,0x8B,0xD5,
+0x30,0x81,0xAD,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x81,0xA0,
+0x30,0x81,0x9D,0x30,0x28,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,
+0x1C,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x65,0x72,0x74,0x69,0x6E,0x66,0x6F,
+0x2E,0x6D,0x61,0x63,0x2E,0x63,0x6F,0x6D,0x2F,0x6F,0x63,0x73,0x70,0x30,0x44,0x06,
+0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x38,0x68,0x74,0x74,0x70,0x3A,
+0x2F,0x2F,0x77,0x77,0x77,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x2F,
+0x63,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x61,0x75,0x74,0x68,0x6F,
+0x72,0x69,0x74,0x79,0x2F,0x63,0x61,0x73,0x69,0x67,0x6E,0x65,0x72,0x73,0x2E,0x68,
+0x74,0x6D,0x6C,0x30,0x2B,0x06,0x03,0x55,0x1D,0x12,0x86,0x24,0x68,0x74,0x74,0x70,
+0x3A,0x2F,0x2F,0x63,0x65,0x72,0x74,0x69,0x6E,0x66,0x6F,0x2E,0x6D,0x61,0x63,0x2E,
+0x63,0x6F,0x6D,0x2F,0x64,0x6F,0x74,0x4D,0x61,0x63,0x43,0x41,0x2E,0x63,0x65,0x72,
+0x30,0x82,0x01,0x28,0x06,0x03,0x55,0x1D,0x20,0x04,0x82,0x01,0x1F,0x30,0x82,0x01,
+0x1B,0x30,0x82,0x01,0x17,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,0x05,0x02,
+0x30,0x82,0x01,0x08,0x30,0x40,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,
+0x16,0x34,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x61,0x70,0x70,
+0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x2F,0x63,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,
+0x74,0x65,0x61,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x2F,0x74,0x65,0x72,0x6D,
+0x73,0x2E,0x68,0x74,0x6D,0x6C,0x30,0x81,0xC3,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,
+0x07,0x02,0x02,0x30,0x81,0xB6,0x1A,0x81,0xB3,0x52,0x65,0x6C,0x69,0x61,0x6E,0x63,
+0x65,0x20,0x6F,0x6E,0x20,0x74,0x68,0x69,0x73,0x20,0x63,0x65,0x72,0x74,0x69,0x66,
+0x69,0x63,0x61,0x74,0x65,0x20,0x62,0x79,0x20,0x61,0x6E,0x79,0x20,0x70,0x61,0x72,
+0x74,0x79,0x20,0x61,0x73,0x73,0x75,0x6D,0x65,0x73,0x20,0x61,0x63,0x63,0x65,0x70,
+0x74,0x61,0x6E,0x63,0x65,0x20,0x6F,0x66,0x20,0x74,0x68,0x65,0x20,0x74,0x68,0x65,
+0x6E,0x20,0x61,0x70,0x70,0x6C,0x69,0x63,0x61,0x62,0x6C,0x65,0x20,0x73,0x74,0x61,
+0x6E,0x64,0x61,0x72,0x64,0x20,0x74,0x65,0x72,0x6D,0x73,0x20,0x61,0x6E,0x64,0x20,
+0x63,0x6F,0x6E,0x64,0x69,0x74,0x69,0x6F,0x6E,0x73,0x20,0x6F,0x66,0x20,0x75,0x73,
+0x65,0x2C,0x20,0x63,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x70,
+0x6F,0x6C,0x69,0x63,0x79,0x20,0x61,0x6E,0x64,0x20,0x63,0x65,0x72,0x74,0x69,0x66,
+0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x70,0x72,0x61,0x63,0x74,0x69,0x63,0x65,
+0x20,0x73,0x74,0x61,0x74,0x65,0x6D,0x65,0x6E,0x74,0x73,0x2E,0x30,0x0D,0x06,0x09,
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,
+0x30,0x48,0x04,0xA8,0x63,0x5A,0x7A,0xF9,0xEA,0x8B,0xF7,0x7F,0xF6,0x27,0x21,0x02,
+0xE2,0x83,0xC8,0x64,0x99,0xB3,0x40,0x71,0x97,0x30,0xE2,0x92,0xD4,0x58,0xB8,0xD8,
+0xF1,0xAA,0x30,0x59,0x75,0x4C,0x67,0x16,0xF8,0x38,0xBD,0xD7,0xF4,0xEA,0x03,0xB5,
+0xE6,0x42,0xF8,0x95,0xBA,0x5B,0xE4,0x3C,0xA8,0x75,0x6C,0x05,0xFB,0x3C,0x3C,0xE3,
+0x08,0x90,0x5F,0x6D,0x7E,0x3A,0xEA,0xBD,0x19,0x52,0x82,0x3B,0x9C,0x7F,0x64,0x15,
+0x3A,0xCA,0x54,0x52,0x57,0xEB,0x53,0x09,0xE8,0x05,0x53,0x79,0xB9,0x7D,0x51,0xA3,
+0x8E,0x31,0xF1,0xE5,0x5E,0xC6,0xA6,0x81,0x11,0x68,0x0A,0x17,0xD5,0xA0,0xBB,0x49,
+0xF3,0x4E,0x59,0x1D,0xCB,0xCA,0x3E,0x09,0x64,0x2F,0x27,0x6C,0xCA,0x39,0x50,0x73,
+0x42,0x5C,0x9D,0xE2,0x92,0x45,0x37,0x7F,0x02,0xF0,0x2B,0xA0,0xDD,0x1C,0x02,0xDC,
+0x77,0xA9,0x0C,0xEA,0x14,0xAE,0xDE,0x81,0xDF,0x3E,0x31,0x59,0xF6,0xF7,0xE5,0x7F,
+0xBC,0x7C,0xFD,0xE8,0x22,0xBE,0x9A,0x78,0xDD,0xFD,0x32,0x7F,0xE0,0xEC,0x0F,0x8D,
+0x4D,0xB5,0xDE,0xF6,0x91,0x4B,0xAD,0xDB,0x7D,0xF9,0x07,0xB8,0x2B,0x0E,0xB5,0x58,
+0x05,0xA2,0x85,0xF6,0x72,0x0E,0xCB,0x63,0x4E,0x8F,0xBF,0xD6,0x33,0x6F,0xF3,0xC2,
+0x53,0xFA,0x67,0x5D,0x19,0xA8,0x49,0x1C,0x05,0x5D,0xAF,0x6C,0xDC,0x14,0x37,0xD5,
+0x65,0x42,0x24,0x3B,0x69,0xC9,0x78,0x3F,0x4B,0x0E,0xAF,0x13,0x37,0x00,0x1E,0x6B,
+0xCE,0xB9,0xCC,0xAA,0x99,0x1A,0xB7,0x5A,0x27,0xB9,0xE9,0xD6,0x87,0x0A,0xEB,0x77,
+};
+
+static unsigned char pem[] = "\n"
+"-----BEGIN CERTIFICATE-----\n"
+"MIIDSzCCAjOgAwIBAgIJAPsB+wAAAAABMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNV\n"
+"BAYTAlVTMRMwEQYDVQQKEwpBcHBsZSBJbmMuMSYwJAYDVQQLEx1BcHBsZSBDZXJ0\n"
+"aWZpY2F0aW9uIEF1dGhvcml0eTEyMDAGA1UEAxMpQXBwbGUgU2VjdXJlIEJvb3Qg\n"
+"Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDcwMTA2MDUyMDUyWhcNMTcwMTA2\n"
+"MDUyMDUyWjB0MQswCQYDVQQGEwJVUzETMBEGA1UEChMKQXBwbGUgSW5jLjEyMDAG\n"
+"A1UECxMpQXBwbGUgU2VjdXJlIEJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkx\n"
+"HDAaBgNVBAMTE1M1TDg5MDAgU2VjdXJlIEJvb3QwgZ8wDQYJKoZIhvcNAQEBBQAD\n"
+"gY0AMIGJAoGBAMSrg/5uSm6EaOPbN2sedX5F31i+4x5BLd8cVbopszz/9OJZz/RD\n"
+"tWbVkSh2O7PZbvfYwwHB6D3pebAA1S9rakwaKO7hKyKzHqpHeiqu+ECdmPGBRhFf\n"
+"16zQL/pXzEnHn4IBfHcG5O49VqI8TK9pMZiqOQ4nh5H5mYIBImcaQ7frAgMBAAGj\n"
+"WjBYMAsGA1UdDwQEAwIHgDAJBgNVHRMEAjAAMB0GA1UdDgQWBBQZ39dDpsNXFu2G\n"
+"Qt2ylAihau3f3jAfBgNVHSMEGDAWgBRJPTZTydcV4YZhTqyrqxhWY13DxjANBgkq\n"
+"hkiG9w0BAQUFAAOCAQEAlAHI8JncOxR8kSzIuN6jCY22DgiZYahvO7H3f68w3QO3\n"
+"NE8Cp/UCECv+pQmlMuJPMAYzfLwGtoLhpq6BlCQXEc4KYhjGh5aicdXBkZDf+rA0\n"
+"p1KphAd8c2UEIAWBbqU87q1FbDSJBw3YKN7C/I4qGnzUrWSpBbq6musM0QzO/uUZ\n"
+"3R1QsfpicZ+nT/1WmlJSAwtoQsBjNAgMauhRLAJc/fCPi8TqONju/xxbGDYJ/cQs\n"
+"bCGfszrUSeGYu4ryxeyNuu2L8gluHUKbhfZ7J1XYgIsvoCnk5E5hWJDhpIyywylb\n"
+"9F/uRNib8zb0L80S64vAWC4m4QUJ3iLmTfIsk+NYPQ==\n"
+"-----END CERTIFICATE-----\n";
+
+static unsigned char _elektron_v1_cert_der[] = {
+  0x30, 0x82, 0x02, 0x71, 0x30, 0x82, 0x01, 0xda, 0x02, 0x01, 0x01, 0x30,
+  0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
+  0x05, 0x00, 0x30, 0x81, 0x80, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+  0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+  0x55, 0x04, 0x08, 0x13, 0x02, 0x63, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
+  0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x73, 0x61, 0x6e, 0x20, 0x6a, 0x6f,
+  0x73, 0x65, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+  0x04, 0x62, 0x72, 0x61, 0x64, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55,
+  0x04, 0x0b, 0x13, 0x1e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x64,
+  0x20, 0x62, 0x79, 0x20, 0x45, 0x6c, 0x65, 0x6b, 0x74, 0x72, 0x6f, 0x6e,
+  0x20, 0x76, 0x32, 0x2e, 0x30, 0x2e, 0x31, 0x38, 0x35, 0x32, 0x31, 0x19,
+  0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x62, 0x72, 0x61,
+  0x64, 0x20, 0x45, 0x6c, 0x65, 0x6b, 0x74, 0x72, 0x6f, 0x6e, 0x20, 0x43,
+  0x41, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x33, 0x31, 0x32, 0x32, 0x33, 0x31,
+  0x31, 0x34, 0x36, 0x30, 0x37, 0x5a, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x32,
+  0x32, 0x32, 0x31, 0x31, 0x34, 0x36, 0x30, 0x37, 0x5a, 0x30, 0x81, 0x80,
+  0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+  0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02,
+  0x63, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13,
+  0x08, 0x73, 0x61, 0x6e, 0x20, 0x6a, 0x6f, 0x73, 0x65, 0x31, 0x0d, 0x30,
+  0x0b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x04, 0x62, 0x72, 0x61, 0x64,
+  0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1e, 0x50,
+  0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x45,
+  0x6c, 0x65, 0x6b, 0x74, 0x72, 0x6f, 0x6e, 0x20, 0x76, 0x32, 0x2e, 0x30,
+  0x2e, 0x31, 0x38, 0x35, 0x32, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55,
+  0x04, 0x03, 0x13, 0x10, 0x62, 0x72, 0x61, 0x64, 0x20, 0x45, 0x6c, 0x65,
+  0x6b, 0x74, 0x72, 0x6f, 0x6e, 0x20, 0x43, 0x41, 0x30, 0x81, 0x9f, 0x30,
+  0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
+  0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81,
+  0x00, 0xe0, 0xab, 0x3a, 0x05, 0x8d, 0xed, 0x81, 0x73, 0xa8, 0x76, 0x9c,
+  0x14, 0x07, 0x50, 0x4b, 0x56, 0x8f, 0xfe, 0x88, 0xba, 0xec, 0xde, 0xab,
+  0x9a, 0x5d, 0x49, 0x23, 0x3b, 0x87, 0x4f, 0x50, 0x59, 0x8d, 0x0f, 0x78,
+  0xd0, 0x61, 0x98, 0x28, 0x9d, 0x1d, 0x39, 0xbf, 0x92, 0x62, 0xda, 0x21,
+  0xf7, 0xb1, 0x32, 0x6a, 0x5d, 0x73, 0x1c, 0x1d, 0x36, 0xba, 0xf7, 0x3c,
+  0xff, 0xda, 0xd9, 0xff, 0xf0, 0xbd, 0x62, 0x1d, 0xde, 0x6d, 0xc7, 0x76,
+  0x93, 0xdd, 0x3a, 0x90, 0x2b, 0x97, 0xab, 0x86, 0xea, 0x48, 0xb5, 0x70,
+  0xe7, 0xe1, 0xa2, 0x5c, 0x61, 0x1a, 0x7d, 0x48, 0x4d, 0x83, 0x42, 0x73,
+  0x70, 0xaf, 0x5d, 0xcf, 0x8c, 0x26, 0xb4, 0x83, 0xff, 0x77, 0xd5, 0x64,
+  0xe0, 0x14, 0x52, 0x20, 0xa2, 0xe9, 0xc5, 0x8c, 0x70, 0xb5, 0x6f, 0xf5,
+  0x6d, 0x31, 0x2b, 0xcb, 0x1d, 0xad, 0xf4, 0xb2, 0x27, 0x02, 0x03, 0x01,
+  0x00, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x74, 0x49, 0x79,
+  0x14, 0xc0, 0x68, 0xd7, 0x9d, 0xfd, 0x35, 0x6a, 0xda, 0xa0, 0x1d, 0x46,
+  0x0a, 0xc6, 0x1b, 0x51, 0x4b, 0xdf, 0x27, 0xd6, 0x14, 0x1a, 0xcf, 0xf1,
+  0xd0, 0xe2, 0x1b, 0x92, 0x39, 0x33, 0x98, 0x13, 0xc2, 0x6e, 0x97, 0xed,
+  0x2b, 0x1b, 0xfc, 0x28, 0x8a, 0x93, 0xf9, 0xe5, 0xe1, 0xf0, 0xbf, 0xf8,
+  0xa3, 0x5e, 0x08, 0x9c, 0x9f, 0x61, 0x7d, 0xb9, 0xe7, 0x14, 0x0e, 0x6d,
+  0x07, 0x3e, 0x35, 0x12, 0xd4, 0x98, 0x2e, 0x0a, 0x9c, 0x5c, 0xb9, 0xbf,
+  0x20, 0x29, 0x01, 0x55, 0x82, 0x86, 0xa7, 0xcb, 0x97, 0x8f, 0xbb, 0xd8,
+  0x2b, 0xbd, 0x40, 0xd3, 0x1a, 0xa7, 0xb1, 0x66, 0x5c, 0xe5, 0x9a, 0x7b,
+  0x39, 0xb7, 0x73, 0x49, 0x2c, 0x44, 0x8c, 0x79, 0x5b, 0xb5, 0x18, 0x41,
+  0xd0, 0xf1, 0x4b, 0x6d, 0xc5, 0x1a, 0xf8, 0x51, 0xea, 0x99, 0x0d, 0x85,
+  0x1b, 0xbe, 0x16, 0x56, 0x18
+};
+
+#if 0 // currently unused.
+static unsigned int _elektron_v1_cert_der_len = 629;
+#endif
+
+static unsigned char _wapi_as_der[] = {
+  0x30, 0x82, 0x01, 0xb7, 0x30, 0x82, 0x01, 0x6c, 0xa0, 0x03, 0x02, 0x01,
+  0x02, 0x02, 0x01, 0x12, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x81, 0x1c, 0xd7,
+  0x63, 0x01, 0x01, 0x01, 0x05, 0x00, 0x30, 0x1d, 0x31, 0x0c, 0x30, 0x0a,
+  0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x03, 0x54, 0x4d, 0x43, 0x31, 0x0d,
+  0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x04, 0x57, 0x41, 0x50,
+  0x49, 0x30, 0x1e, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30, 0x31, 0x30,
+  0x30, 0x30, 0x30, 0x31, 0x38, 0x5a, 0x17, 0x0d, 0x39, 0x30, 0x30, 0x31,
+  0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x31, 0x38, 0x5a, 0x30, 0x1d, 0x31,
+  0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x03, 0x54, 0x4d,
+  0x43, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x04,
+  0x57, 0x41, 0x50, 0x49, 0x30, 0x4a, 0x30, 0x14, 0x06, 0x07, 0x2a, 0x86,
+  0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x09, 0x2a, 0x81, 0x1c, 0xd7, 0x63,
+  0x01, 0x01, 0x02, 0x01, 0x03, 0x32, 0x00, 0x04, 0x74, 0xd9, 0x78, 0x91,
+  0xc4, 0xd3, 0xb5, 0x9e, 0xb0, 0xa9, 0x9e, 0xf1, 0x01, 0x5b, 0xd7, 0x7f,
+  0x79, 0x9a, 0x02, 0xe5, 0x87, 0x65, 0xa1, 0x0d, 0x04, 0xc9, 0x06, 0xdb,
+  0xf6, 0x12, 0x24, 0x05, 0x9d, 0x1c, 0x51, 0x00, 0x75, 0x58, 0x46, 0x11,
+  0xe3, 0xdc, 0x71, 0x02, 0x69, 0x43, 0x37, 0x61, 0xa3, 0x81, 0xa9, 0x30,
+  0x81, 0xa6, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
+  0x14, 0x08, 0xa9, 0x47, 0x65, 0xf2, 0x39, 0xa9, 0xe8, 0x8b, 0xd1, 0x75,
+  0x43, 0xce, 0x8c, 0x1c, 0xc0, 0xec, 0x99, 0xae, 0xad, 0x30, 0x45, 0x06,
+  0x03, 0x55, 0x1d, 0x23, 0x04, 0x3e, 0x30, 0x3c, 0x80, 0x14, 0x08, 0xa9,
+  0x47, 0x65, 0xf2, 0x39, 0xa9, 0xe8, 0x8b, 0xd1, 0x75, 0x43, 0xce, 0x8c,
+  0x1c, 0xc0, 0xec, 0x99, 0xae, 0xad, 0xa1, 0x21, 0xa4, 0x1f, 0x30, 0x1d,
+  0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x03, 0x54,
+  0x4d, 0x43, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+  0x04, 0x57, 0x41, 0x50, 0x49, 0x82, 0x01, 0x12, 0x30, 0x31, 0x06, 0x03,
+  0x55, 0x1d, 0x1f, 0x04, 0x2a, 0x30, 0x28, 0x30, 0x26, 0xa0, 0x24, 0xa0,
+  0x22, 0x86, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x39,
+  0x32, 0x2e, 0x31, 0x36, 0x38, 0x2e, 0x31, 0x2e, 0x32, 0x30, 0x30, 0x3a,
+  0x38, 0x30, 0x38, 0x30, 0x2f, 0x61, 0x73, 0x2e, 0x63, 0x72, 0x6c, 0x30,
+  0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80,
+  0x30, 0x0c, 0x06, 0x08, 0x2a, 0x81, 0x1c, 0xd7, 0x63, 0x01, 0x01, 0x01,
+  0x05, 0x00, 0x03, 0x37, 0x00, 0x30, 0x34, 0x02, 0x18, 0x23, 0xc5, 0x39,
+  0xc9, 0x91, 0x89, 0x3d, 0xe5, 0xae, 0x95, 0x75, 0x88, 0x68, 0xf6, 0x11,
+  0x64, 0xb1, 0x71, 0xe7, 0x67, 0x1f, 0xa1, 0x58, 0x77, 0x02, 0x18, 0x15,
+  0xef, 0x5a, 0x62, 0x7f, 0x7d, 0x9d, 0x6e, 0x6d, 0x91, 0x2b, 0x61, 0x15,
+  0x4d, 0x5a, 0xbe, 0xc8, 0x8d, 0xdc, 0x85, 0x00, 0xa9, 0x7d, 0x99
+};
+
+#if 0 // currently unused.
+static unsigned int _wapi_as_der_len = 443;
+#endif
+
+#define CFReleaseSafe(CF) { CFTypeRef _cf = (CF); if (_cf) CFRelease(_cf); }
+#define CFReleaseNull(CF) { CFTypeRef _cf = (CF); if (_cf) CFRelease(_cf); (CF) = NULL; }
+
+/* Test basic add delete update copy matching stuff. */
+static void tests(void)
+{
+       SecCertificateRef cert0, cert1, cert2, cert3, cert4, cert5, cert6;
+       isnt(cert0 = SecCertificateCreateWithBytes(NULL, _c0, sizeof(_c0)),
+               NULL, "create cert0");
+       isnt(cert1 = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)),
+               NULL, "create cert1");
+
+    CFDataRef cert2Data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
+        _c2, sizeof(_c2), kCFAllocatorNull);
+       isnt(cert2 = SecCertificateCreateWithData(kCFAllocatorDefault, cert2Data),
+               NULL, "create cert2");
+    CFReleaseNull(cert2Data);
+
+       isnt(cert3 = SecCertificateCreateWithBytes(NULL, _phased_c3, sizeof(_phased_c3)),
+               NULL, "create cert3");
+
+    CFDataRef cert4data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
+        pem, sizeof(pem), kCFAllocatorNull);
+    ok(cert4 = SecCertificateCreateWithPEM(NULL, cert4data), "create cert from pem");
+    CFReleaseNull(cert4data);
+
+       isnt(cert5 = SecCertificateCreateWithBytes(NULL, _elektron_v1_cert_der,
+        sizeof(_elektron_v1_cert_der)), NULL, "create cert5");
+
+       isnt(cert6 = SecCertificateCreateWithBytes(NULL, _wapi_as_der,
+        sizeof(_wapi_as_der)), NULL, "create cert6");
+
+    ok(SecCertificateIsSelfSignedCA(cert0), "cert0 is CA");
+    ok(!SecCertificateIsSelfSignedCA(cert1), "cert1 is not CA");
+    ok(SecCertificateIsSelfSignedCA(cert5), "cert5 is v1 CA");
+
+    CFStringRef subjectSummary, issuerSummary;
+    isnt(subjectSummary = SecCertificateCopySubjectSummary(cert1), NULL,
+        "cert1 has a subject summary");
+    isnt(issuerSummary = SecCertificateCopyIssuerSummary(cert1), NULL,
+        "cert1 has an issuer summary");
+
+    ok(subjectSummary && CFEqual(subjectSummary, CFSTR("www.verisign.com/CPS Incorp.by Ref. LIABILITY LTD.(c)97 VeriSign, VeriSign International Server CA - Class 3, VeriSign, Inc.")),
+        "subject summary is \"www.verisign.com/CPS Incorp.by Ref. LIABILITY LTD.(c)97 VeriSign, VeriSign International Server CA - Class 3, VeriSign, Inc.\"");
+    ok(issuerSummary && CFEqual(issuerSummary,
+        CFSTR("Class 3 Public Primary Certification Authority")),
+        "issuer summary is \"Class 3 Public Primary Certification Authority\"");
+
+    CFArrayRef ntPrincipalNames;
+    ok(ntPrincipalNames = SecCertificateCopyNTPrincipalNames(cert2),
+        "SecCertificateCopyNTPrincipalNames");
+    is(CFArrayGetCount(ntPrincipalNames), 1, "we got 1 princialname back");
+    CFStringRef principal = (CFStringRef)CFArrayGetValueAtIndex(ntPrincipalNames, 0);
+    ok(CFEqual(principal, CFSTR("kmm6b@Virginia.EDU")),
+        "first principal is kmm6b@Virginia.EDU");
+    CFReleaseSafe(ntPrincipalNames);
+
+       CFReleaseSafe(subjectSummary);
+       CFReleaseSafe(issuerSummary);
+
+    isnt(subjectSummary = SecCertificateCopySubjectSummary(cert3), NULL,
+        "cert3 has a subject summary");
+       /* @@@ this causes a double free without an extra retain in obtainSummaryFromX501Name():
+              summary->description = string = copyDERThingDescription(kCFAllocatorDefault, value, true); */
+       CFReleaseSafe(subjectSummary);
+
+    isnt(subjectSummary = SecCertificateCopySubjectSummary(cert4), NULL,
+        "cert4 has a subject summary");
+    ok(subjectSummary && CFEqual(subjectSummary, CFSTR("S5L8900 Secure Boot")),
+        "cert4 is S5L8900 Secure Boot");
+       CFReleaseSafe(subjectSummary);
+
+    CFStringRef desc = NULL;
+    ok(desc = CFCopyDescription(cert4), "cert4 CFCopyDescription works");
+
+       CFReleaseSafe(cert0);
+       CFReleaseSafe(cert1);
+       CFReleaseSafe(cert2);
+       CFReleaseSafe(cert3);
+       CFReleaseSafe(cert4);
+       CFReleaseSafe(cert5);
+       CFReleaseSafe(cert6);
+       CFReleaseNull(desc);
+}
+
+int si_15_certificate(int argc, char *const *argv)
+{
+       plan_tests(21);
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-16-ec-certificate.c b/sec/Security/Regressions/secitem/si-16-ec-certificate.c
new file mode 100644 (file)
index 0000000..8db44a3
--- /dev/null
@@ -0,0 +1,1181 @@
+/*
+ *  si-16-ec-certificate.c
+ *  Security
+ *
+ *  Created by Michael Brouwer on 4/16/10.
+ *  Copyright 2010 Apple Inc. All rights reserved.
+ *
+ */
+
+
+/*
+ * Copyright (c) 2010 Apple Inc. All Rights Reserved.
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecPolicy.h>
+#include <Security/SecTrust.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "Security_regressions.h"
+
+/* Set this to 1 to test support for the legacy ecdsa-with-specified
+   signature oid. */
+#define TEST_ECDSA_WITH_SPECIFIED  0
+
+/* subject:/C=US/O=Red Hat/CN=ECC CA */
+/* issuer :/C=US/O=Red Hat/CN=ECC CA */
+unsigned char ECCCA_cer[386]={
+0x30,0x82,0x01,0x7E,0x30,0x82,0x01,0x26,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x01,
+0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30,0x30,0x31,0x0B,0x30,
+0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x10,0x30,0x0E,0x06,0x03,
+0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48,0x61,0x74,0x31,0x0F,0x30,0x0D,
+0x06,0x03,0x55,0x04,0x03,0x13,0x06,0x45,0x43,0x43,0x20,0x43,0x41,0x30,0x20,0x17,
+0x0D,0x30,0x36,0x30,0x32,0x30,0x33,0x32,0x32,0x31,0x31,0x35,0x37,0x5A,0x18,0x0F,
+0x32,0x30,0x35,0x36,0x30,0x35,0x30,0x33,0x32,0x32,0x31,0x31,0x35,0x37,0x5A,0x30,
+0x30,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x10,
+0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48,0x61,0x74,
+0x31,0x0F,0x30,0x0D,0x06,0x03,0x55,0x04,0x03,0x13,0x06,0x45,0x43,0x43,0x20,0x43,
+0x41,0x30,0x59,0x30,0x13,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,0x06,0x08,
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07,0x03,0x42,0x00,0x04,0x25,0xDF,0xFC,0x2F,
+0x17,0xA8,0xED,0xAD,0x1B,0x49,0xBA,0xA9,0xA5,0x9E,0x8B,0x17,0x24,0x39,0x25,0xFF,
+0xDD,0x42,0x1F,0xBE,0xAB,0x79,0x99,0x4F,0xC8,0x6D,0x28,0x6B,0x10,0x06,0x1E,0x55,
+0xF5,0x12,0x2D,0x96,0x1D,0x7B,0x05,0x99,0x76,0xDA,0xC7,0xD4,0xB7,0x7F,0x18,0x89,
+0x27,0x6F,0xA5,0x20,0x09,0x6C,0x72,0xF8,0xC6,0x05,0xCD,0x11,0xA3,0x30,0x30,0x2E,
+0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,0x04,0x04,0x03,
+0x02,0x00,0x07,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x04,0x05,0x30,0x03,0x01,0x01,
+0xFF,0x30,0x0B,0x06,0x03,0x55,0x1D,0x0F,0x04,0x04,0x03,0x02,0x02,0x84,0x30,0x09,
+0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x03,0x47,0x00,0x30,0x44,0x02,0x20,
+0x30,0x09,0x1B,0x6F,0xE1,0xB2,0x99,0x8D,0xD1,0x84,0xB1,0xE2,0x9B,0xA4,0x05,0xB0,
+0xC9,0x33,0x1D,0xF2,0x82,0x8A,0x57,0x0C,0xE1,0xE4,0xA6,0xC8,0xB3,0x0A,0x49,0x2D,
+0x02,0x20,0x46,0x85,0xA2,0x1D,0xC1,0x0F,0xA2,0x94,0x85,0xF5,0x09,0xF7,0x53,0x5A,
+0xD8,0x81,0x2A,0xFB,0x02,0x0D,0xD9,0x42,0xE2,0xB4,0xF7,0xB7,0x28,0xDF,0x3A,0xF7,
+0x99,0x5C,
+};
+/* subject:/C=US/O=Red Hat/OU=ECC p192/CN=jordan.sfbay.redhat.com */
+/* issuer :/C=US/O=Red Hat/CN=ECC CA */
+unsigned char ECCp192_cer[382]={
+0x30,0x82,0x01,0x7A,0x30,0x82,0x01,0x21,0xA0,0x03,0x02,0x01,0x02,0x02,0x05,0x00,
+0x81,0x7D,0x68,0xFA,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30,
+0x30,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x10,
+0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48,0x61,0x74,
+0x31,0x0F,0x30,0x0D,0x06,0x03,0x55,0x04,0x03,0x13,0x06,0x45,0x43,0x43,0x20,0x43,
+0x41,0x30,0x1E,0x17,0x0D,0x30,0x36,0x30,0x32,0x30,0x33,0x32,0x32,0x31,0x37,0x34,
+0x36,0x5A,0x17,0x0D,0x30,0x36,0x30,0x35,0x30,0x33,0x32,0x32,0x31,0x37,0x34,0x36,
+0x5A,0x30,0x54,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,
+0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48,
+0x61,0x74,0x31,0x11,0x30,0x0F,0x06,0x03,0x55,0x04,0x0B,0x13,0x08,0x45,0x43,0x43,
+0x20,0x70,0x31,0x39,0x32,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17,
+0x6A,0x6F,0x72,0x64,0x61,0x6E,0x2E,0x73,0x66,0x62,0x61,0x79,0x2E,0x72,0x65,0x64,
+0x68,0x61,0x74,0x2E,0x63,0x6F,0x6D,0x30,0x49,0x30,0x13,0x06,0x07,0x2A,0x86,0x48,
+0xCE,0x3D,0x02,0x01,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01,0x03,0x32,
+0x00,0x04,0x5E,0x73,0x9E,0x99,0xB2,0xCB,0xC8,0x29,0x9B,0x6A,0x60,0xE2,0x5C,0x04,
+0x38,0x61,0x42,0x76,0x4E,0xFA,0xC0,0x74,0x82,0x43,0x7F,0x73,0x98,0x03,0x8A,0x98,
+0x6D,0x49,0x76,0x35,0x4F,0xD6,0x5B,0x39,0x4F,0x93,0x57,0x2D,0xE8,0xFE,0xD4,0x1B,
+0xD5,0x26,0xA3,0x15,0x30,0x13,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,
+0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x06,0x40,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,
+0xCE,0x3D,0x04,0x01,0x03,0x48,0x00,0x30,0x45,0x02,0x21,0x00,0xD0,0xDA,0x8B,0xD0,
+0xCD,0x6A,0x49,0x59,0xD7,0xBF,0xFB,0xAA,0xFF,0x9D,0x86,0xBF,0xF1,0x08,0xA6,0x8D,
+0xE8,0x0E,0x34,0x18,0x06,0xCE,0x1D,0x26,0x3D,0x2E,0xFF,0xB4,0x02,0x20,0x5D,0x34,
+0x70,0xDC,0x65,0xBE,0xC3,0x86,0x3B,0xEF,0x4A,0xBA,0x25,0x6C,0x76,0xC1,0x78,0x3D,
+0xFB,0xD9,0xCF,0xD8,0x63,0x0A,0x76,0x24,0x04,0x82,0x82,0xDB,0x47,0xBE,
+};
+/* subject:/C=US/O=Red Hat/OU=ECC p224/CN=jordan.sfbay.redhat.com */
+/* issuer :/C=US/O=Red Hat/CN=ECC CA */
+unsigned char ECCp224_cer[388]={
+0x30,0x82,0x01,0x80,0x30,0x82,0x01,0x26,0xA0,0x03,0x02,0x01,0x02,0x02,0x05,0x00,
+0x81,0x7D,0x69,0xB5,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30,
+0x30,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x10,
+0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48,0x61,0x74,
+0x31,0x0F,0x30,0x0D,0x06,0x03,0x55,0x04,0x03,0x13,0x06,0x45,0x43,0x43,0x20,0x43,
+0x41,0x30,0x1E,0x17,0x0D,0x30,0x36,0x30,0x32,0x30,0x33,0x32,0x32,0x31,0x39,0x32,
+0x35,0x5A,0x17,0x0D,0x30,0x36,0x30,0x35,0x30,0x33,0x32,0x32,0x31,0x39,0x32,0x35,
+0x5A,0x30,0x54,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,
+0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48,
+0x61,0x74,0x31,0x11,0x30,0x0F,0x06,0x03,0x55,0x04,0x0B,0x13,0x08,0x45,0x43,0x43,
+0x20,0x70,0x32,0x32,0x34,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17,
+0x6A,0x6F,0x72,0x64,0x61,0x6E,0x2E,0x73,0x66,0x62,0x61,0x79,0x2E,0x72,0x65,0x64,
+0x68,0x61,0x74,0x2E,0x63,0x6F,0x6D,0x30,0x4E,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,
+0xCE,0x3D,0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x21,0x03,0x3A,0x00,0x04,0xB1,
+0x41,0x9F,0x63,0x9A,0xFB,0xBE,0xC5,0xD6,0x2D,0xDD,0xC2,0x94,0x5E,0x3D,0xAC,0x5A,
+0x2C,0x85,0xD5,0xE7,0x4C,0xC4,0x67,0xF5,0xA7,0x27,0x99,0xC8,0x2D,0x8D,0x90,0x9A,
+0x50,0xFD,0x9A,0x5C,0x87,0xA5,0x24,0xDE,0x1F,0x01,0x9D,0xCE,0xDF,0x75,0x93,0x14,
+0x54,0x04,0x1C,0x9F,0x03,0x44,0x20,0xA3,0x15,0x30,0x13,0x30,0x11,0x06,0x09,0x60,
+0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x06,0x40,0x30,0x09,
+0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x03,0x49,0x00,0x30,0x46,0x02,0x21,
+0x00,0xEA,0xCC,0x97,0xB3,0xF3,0xF2,0x23,0xF1,0xAB,0x90,0x4D,0x74,0x03,0x46,0xF9,
+0xE0,0x04,0x84,0x20,0xC1,0xD6,0x4B,0xC0,0xC1,0xE4,0x73,0xD8,0x91,0x28,0x13,0x0D,
+0xD5,0x02,0x21,0x00,0xAF,0xF7,0x8F,0x5F,0x58,0xD1,0x9F,0x15,0xD1,0x14,0x3B,0x4C,
+0xA8,0xA2,0x01,0xBA,0x31,0x85,0xEC,0x6A,0x36,0x5B,0x6B,0x64,0xF4,0x2E,0x0E,0x2D,
+0xA9,0x05,0x10,0x6C,
+};
+/* subject:/C=US/O=Red Hat/OU=ECC p256/CN=jordan.sfbay.redhat.com */
+/* issuer :/C=US/O=Red Hat/CN=ECC CA */
+unsigned char ECCp256_cer[398]={
+0x30,0x82,0x01,0x8A,0x30,0x82,0x01,0x31,0xA0,0x03,0x02,0x01,0x02,0x02,0x05,0x00,
+0x81,0x7D,0x6A,0x1D,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30,
+0x30,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x10,
+0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48,0x61,0x74,
+0x31,0x0F,0x30,0x0D,0x06,0x03,0x55,0x04,0x03,0x13,0x06,0x45,0x43,0x43,0x20,0x43,
+0x41,0x30,0x1E,0x17,0x0D,0x30,0x36,0x30,0x32,0x30,0x33,0x32,0x32,0x32,0x30,0x31,
+0x39,0x5A,0x17,0x0D,0x30,0x36,0x30,0x35,0x30,0x33,0x32,0x32,0x32,0x30,0x31,0x39,
+0x5A,0x30,0x54,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,
+0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48,
+0x61,0x74,0x31,0x11,0x30,0x0F,0x06,0x03,0x55,0x04,0x0B,0x13,0x08,0x45,0x43,0x43,
+0x20,0x70,0x32,0x35,0x36,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17,
+0x6A,0x6F,0x72,0x64,0x61,0x6E,0x2E,0x73,0x66,0x62,0x61,0x79,0x2E,0x72,0x65,0x64,
+0x68,0x61,0x74,0x2E,0x63,0x6F,0x6D,0x30,0x59,0x30,0x13,0x06,0x07,0x2A,0x86,0x48,
+0xCE,0x3D,0x02,0x01,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07,0x03,0x42,
+0x00,0x04,0x02,0x5E,0xC5,0x3F,0x2D,0xB3,0x57,0x12,0xFE,0xDA,0x3D,0x2A,0xE1,0x27,
+0xD5,0xBA,0x99,0x56,0xB0,0x1D,0x47,0x3D,0x56,0xEB,0x7D,0xAE,0x72,0xBC,0x7D,0xEA,
+0x3F,0xCB,0x5B,0xD8,0x8F,0xA3,0x62,0xB0,0x0C,0xD5,0x14,0x0B,0x11,0x21,0x1A,0x34,
+0xDB,0x64,0x96,0x76,0x21,0x15,0xB6,0x17,0x9E,0xB8,0xF6,0x48,0x33,0xBD,0xD3,0x4F,
+0xEA,0xA5,0xA3,0x15,0x30,0x13,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,
+0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x06,0x40,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,
+0xCE,0x3D,0x04,0x01,0x03,0x48,0x00,0x30,0x45,0x02,0x20,0x4A,0x1D,0x02,0x95,0xC3,
+0xD8,0x71,0x6C,0x9E,0x8E,0x9E,0xC1,0x13,0x16,0xC5,0x7D,0x76,0x5C,0xB0,0x77,0x7C,
+0x37,0x0A,0xB6,0x7E,0x85,0xB1,0xDA,0x7C,0x32,0x52,0xBA,0x02,0x21,0x00,0xAC,0x8F,
+0x49,0x7D,0x42,0x6D,0x6D,0x03,0x6C,0x8B,0x0B,0x64,0x9C,0xFA,0x9B,0x08,0x05,0xD0,
+0x1D,0x4D,0xA9,0xF0,0x07,0x83,0x95,0xBE,0xB7,0x0E,0x9E,0xBE,0xC6,0x75,
+};
+/* subject:/C=US/O=Red Hat/OU=ECC p384/CN=jordan.sfbay.redhat.com */
+/* issuer :/C=US/O=Red Hat/CN=ECC CA */
+unsigned char ECCp384_cer[427]={
+0x30,0x82,0x01,0xA7,0x30,0x82,0x01,0x4E,0xA0,0x03,0x02,0x01,0x02,0x02,0x05,0x00,
+0x81,0x7D,0x6A,0x67,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30,
+0x30,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x10,
+0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48,0x61,0x74,
+0x31,0x0F,0x30,0x0D,0x06,0x03,0x55,0x04,0x03,0x13,0x06,0x45,0x43,0x43,0x20,0x43,
+0x41,0x30,0x1E,0x17,0x0D,0x30,0x36,0x30,0x32,0x30,0x33,0x32,0x32,0x32,0x30,0x35,
+0x39,0x5A,0x17,0x0D,0x30,0x36,0x30,0x35,0x30,0x33,0x32,0x32,0x32,0x30,0x35,0x39,
+0x5A,0x30,0x54,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,
+0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48,
+0x61,0x74,0x31,0x11,0x30,0x0F,0x06,0x03,0x55,0x04,0x0B,0x13,0x08,0x45,0x43,0x43,
+0x20,0x70,0x33,0x38,0x34,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17,
+0x6A,0x6F,0x72,0x64,0x61,0x6E,0x2E,0x73,0x66,0x62,0x61,0x79,0x2E,0x72,0x65,0x64,
+0x68,0x61,0x74,0x2E,0x63,0x6F,0x6D,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,
+0xCE,0x3D,0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0x43,
+0x52,0x0B,0x54,0x28,0x27,0xB5,0x05,0xEC,0x01,0x7B,0x33,0xF5,0x8F,0x3E,0x69,0xF7,
+0xFA,0x93,0x8B,0x46,0xC2,0x1C,0xC8,0x28,0x4D,0xF5,0x8A,0x88,0xEC,0x91,0x9C,0x2E,
+0xD0,0x3F,0x2E,0x64,0x84,0x1B,0x3E,0xBD,0xF1,0xDD,0xA9,0xE4,0xC2,0xA8,0x2E,0xD4,
+0x98,0x91,0x5F,0xD8,0x21,0x2B,0x1D,0x38,0xB4,0x6D,0xF8,0xE9,0x05,0x5C,0x46,0x1A,
+0x2B,0x48,0xA9,0x8F,0xBD,0xC7,0xD9,0xE5,0x75,0xD4,0x1A,0x7B,0x91,0x8D,0x36,0xEE,
+0xF0,0xA6,0xB8,0x7C,0xDE,0xEE,0xBB,0x9E,0xF4,0x82,0x63,0xAD,0xA7,0xC3,0x1B,0xA3,
+0x15,0x30,0x13,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,
+0x04,0x04,0x03,0x02,0x06,0x40,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,
+0x01,0x03,0x48,0x00,0x30,0x45,0x02,0x21,0x00,0x9C,0xC0,0x76,0x15,0x17,0xB8,0x44,
+0xB9,0x48,0x02,0x74,0xB0,0x02,0x34,0xBE,0x4D,0x06,0xE7,0x05,0x03,0x2C,0xD0,0xF6,
+0xEB,0x45,0x5D,0x47,0xA4,0x79,0x9D,0xEE,0x66,0x02,0x20,0x02,0x05,0x84,0xD5,0xDC,
+0x9F,0x8A,0xA5,0xEB,0x09,0x58,0x0E,0xB5,0x02,0x71,0x5D,0xF7,0xDF,0x46,0xAE,0x6A,
+0x15,0xB0,0xCC,0x7C,0xF0,0x4B,0x56,0xFB,0x20,0x95,0x41,
+};
+/* subject:/C=US/O=Red Hat/OU=ECC p5214/CN=jordan.sfbay.redhat.com */
+/* issuer :/C=US/O=Red Hat/CN=ECC CA */
+unsigned char ECCp521_cer[465]={
+0x30,0x82,0x01,0xCD,0x30,0x82,0x01,0x75,0xA0,0x03,0x02,0x01,0x02,0x02,0x05,0x00,
+0x81,0x7D,0x6A,0xB7,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30,
+0x30,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x10,
+0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48,0x61,0x74,
+0x31,0x0F,0x30,0x0D,0x06,0x03,0x55,0x04,0x03,0x13,0x06,0x45,0x43,0x43,0x20,0x43,
+0x41,0x30,0x1E,0x17,0x0D,0x30,0x36,0x30,0x32,0x30,0x33,0x32,0x32,0x32,0x31,0x34,
+0x31,0x5A,0x17,0x0D,0x30,0x36,0x30,0x35,0x30,0x33,0x32,0x32,0x32,0x31,0x34,0x31,
+0x5A,0x30,0x55,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,
+0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48,
+0x61,0x74,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x0B,0x13,0x09,0x45,0x43,0x43,
+0x20,0x70,0x35,0x32,0x31,0x34,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,
+0x17,0x6A,0x6F,0x72,0x64,0x61,0x6E,0x2E,0x73,0x66,0x62,0x61,0x79,0x2E,0x72,0x65,
+0x64,0x68,0x61,0x74,0x2E,0x63,0x6F,0x6D,0x30,0x81,0x9B,0x30,0x10,0x06,0x07,0x2A,
+0x86,0x48,0xCE,0x3D,0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x23,0x03,0x81,0x86,
+0x00,0x04,0x01,0x71,0xB4,0x18,0xE9,0x83,0x60,0x7E,0x23,0x8F,0xDF,0x40,0xA2,0x95,
+0x76,0x3F,0x90,0xBB,0x39,0xAA,0x69,0x44,0x1B,0x5F,0xA4,0x98,0x4A,0xEC,0xED,0x11,
+0xC1,0xAE,0x14,0x84,0x5F,0x71,0xB6,0xAF,0x74,0x02,0x6F,0x65,0x31,0x09,0x2F,0x96,
+0x96,0x06,0xEC,0xA7,0x88,0x71,0x4A,0xBC,0x60,0x76,0x49,0xF7,0xA6,0x55,0x5A,0xF4,
+0xE6,0x6F,0xFC,0xA0,0x01,0x70,0x86,0x93,0xE2,0xC7,0xF6,0xB4,0x98,0x77,0xAA,0x91,
+0xAB,0xEA,0xB0,0x70,0x3E,0x81,0xC4,0xB9,0x47,0x67,0xB8,0xCC,0x8D,0x48,0x62,0x9E,
+0x3B,0xE3,0xC0,0x40,0x7D,0xF5,0xB4,0x69,0x1F,0xA3,0xEB,0x04,0x68,0x95,0x0A,0x42,
+0xC0,0xAC,0xE9,0xCF,0x2E,0xEC,0xA6,0x40,0x41,0x6A,0x30,0x20,0x89,0x57,0x4C,0xEC,
+0xC5,0x71,0x50,0x9F,0x1E,0x87,0xA3,0x15,0x30,0x13,0x30,0x11,0x06,0x09,0x60,0x86,
+0x48,0x01,0x86,0xF8,0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x06,0x40,0x30,0x09,0x06,
+0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x03,0x47,0x00,0x30,0x44,0x02,0x20,0x6D,
+0x48,0x0F,0x69,0xDA,0xB8,0x48,0x51,0x43,0xF5,0x02,0xD8,0x94,0xFA,0xFF,0xC9,0x23,
+0xEF,0xFF,0xD6,0xAA,0xC4,0x90,0xDB,0xE0,0xA4,0xEA,0xB4,0xCF,0x54,0xED,0xFD,0x02,
+0x20,0x55,0xB4,0xC1,0x2C,0x62,0x52,0x7E,0x70,0x46,0xFA,0x67,0xEF,0xB4,0xD4,0x94,
+0xEF,0x29,0xDC,0x71,0x46,0x5D,0x48,0x61,0x94,0x2B,0x6E,0xA8,0x62,0x1D,0xF9,0x13,
+0x1F,
+};
+
+#if TEST_ECDSA_WITH_SPECIFIED
+/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x002\x005\x006\x00_\x00S\x00p\x00e\x00c\x00i\x00f\x00i\x00e\x00d\x00_\x00S\x00H\x00A\x001 */
+/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */
+unsigned char End_P256_Specified_SHA1_cer[574]={
+0x30,0x82,0x02,0x3A,0x30,0x82,0x01,0xD6,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0xE4,
+0xDD,0xA2,0x79,0x22,0x46,0xAF,0x9D,0x4A,0x71,0xDA,0xBC,0x68,0x30,0x70,0x63,0x30,
+0x14,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x30,0x09,0x06,0x05,0x2B,0x0E,
+0x03,0x02,0x1A,0x05,0x00,0x30,0x1D,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x03,
+0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54,0x00,0x5F,0x00,0x50,0x00,0x32,
+0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31,0x30,0x34,0x30,0x31,0x30,0x30,
+0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31,0x32,0x33,0x31,0x30,0x30,0x30,
+0x30,0x30,0x30,0x5A,0x30,0x39,0x31,0x37,0x30,0x35,0x06,0x03,0x55,0x04,0x03,0x1E,
+0x2E,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00,
+0x36,0x00,0x5F,0x00,0x53,0x00,0x70,0x00,0x65,0x00,0x63,0x00,0x69,0x00,0x66,0x00,
+0x69,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00,0x41,0x00,0x31,0x30,
+0x59,0x30,0x13,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,0x06,0x08,0x2A,0x86,
+0x48,0xCE,0x3D,0x03,0x01,0x07,0x03,0x42,0x00,0x04,0x6C,0xCD,0x5C,0xC7,0xCD,0xE2,
+0x79,0x33,0xD5,0x37,0x30,0xD7,0x65,0x9A,0xEB,0x45,0x10,0x57,0xCF,0x06,0x51,0xA4,
+0xFB,0xCA,0x02,0x62,0xB9,0x83,0x58,0xFA,0xB3,0xB4,0x01,0x85,0x4D,0xBE,0x8F,0x85,
+0x43,0xA0,0x1F,0x91,0x40,0x8F,0x9E,0xF0,0xCD,0xA6,0xFD,0x62,0x3E,0x99,0xEF,0x4F,
+0x18,0x9E,0x3F,0x0A,0x0E,0x12,0x0E,0x5E,0x5A,0x1B,0xA3,0x81,0xD1,0x30,0x81,0xCE,
+0x30,0x81,0xCB,0x06,0x0F,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x13,0x82,0xDF,0x67,
+0x86,0xA3,0x53,0x01,0x04,0x81,0xB7,0x30,0x81,0xB4,0x04,0x12,0x43,0x65,0x72,0x74,
+0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53,0x61,0x6D,0x70,0x6C,0x65,0x00,0x04,0x18,
+0x45,0x6E,0x64,0x5F,0x50,0x32,0x35,0x36,0x5F,0x53,0x70,0x65,0x63,0x69,0x66,0x69,
+0x65,0x64,0x5F,0x53,0x48,0x41,0x31,0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14,
+0x45,0x00,0x43,0x00,0x44,0x00,0x53,0x00,0x41,0x00,0x5F,0x00,0x50,0x00,0x32,0x00,
+0x35,0x00,0x36,0x00,0x04,0x68,0x45,0x43,0x53,0x32,0x20,0x00,0x00,0x00,0x6C,0xCD,
+0x5C,0xC7,0xCD,0xE2,0x79,0x33,0xD5,0x37,0x30,0xD7,0x65,0x9A,0xEB,0x45,0x10,0x57,
+0xCF,0x06,0x51,0xA4,0xFB,0xCA,0x02,0x62,0xB9,0x83,0x58,0xFA,0xB3,0xB4,0x01,0x85,
+0x4D,0xBE,0x8F,0x85,0x43,0xA0,0x1F,0x91,0x40,0x8F,0x9E,0xF0,0xCD,0xA6,0xFD,0x62,
+0x3E,0x99,0xEF,0x4F,0x18,0x9E,0x3F,0x0A,0x0E,0x12,0x0E,0x5E,0x5A,0x1B,0x2F,0xA9,
+0x13,0x48,0xAA,0x53,0x7C,0x1F,0x20,0x87,0xC9,0xAF,0x94,0x50,0x75,0xDC,0xAA,0x2B,
+0xEC,0x08,0xB5,0x78,0x19,0x16,0x88,0x24,0xCC,0x8B,0x7D,0xCF,0x6F,0xDA,0x30,0x14,
+0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x30,0x09,0x06,0x05,0x2B,0x0E,0x03,
+0x02,0x1A,0x05,0x00,0x03,0x48,0x00,0x30,0x45,0x02,0x21,0x00,0xCD,0x27,0x04,0x6A,
+0x7A,0xFC,0x0F,0xCA,0xAA,0x17,0xDD,0x62,0xAD,0x56,0x40,0x26,0xBF,0xBB,0x8F,0xFD,
+0x47,0x80,0x24,0x09,0x5F,0x05,0x6B,0x61,0x86,0x8B,0xEA,0xC9,0x02,0x20,0x1B,0x57,
+0x9B,0x7D,0x07,0x71,0x74,0xEC,0x2E,0xA6,0x7F,0xF3,0x31,0x9F,0x76,0x21,0xA5,0x4E,
+0x37,0xAE,0xCB,0xA2,0x7B,0x09,0x3F,0x01,0x66,0x25,0x18,0xE3,0x8F,0x4D,
+};
+/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x002\x005\x006\x00_\x00S\x00p\x00e\x00c\x00i\x00f\x00i\x00e\x00d\x00_\x00S\x00H\x00A\x002\x005\x006 */
+/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */
+unsigned char End_P256_Specified_SHA256_cer[589]={
+0x30,0x82,0x02,0x49,0x30,0x82,0x01,0xE0,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x92,
+0x1A,0x37,0x71,0x59,0xAB,0x6E,0xB3,0x48,0x9C,0xC1,0x3E,0xCB,0x20,0x2B,0xA0,0x30,
+0x18,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x30,0x0D,0x06,0x09,0x60,0x86,
+0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x30,0x1D,0x31,0x1B,0x30,0x19,0x06,
+0x03,0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54,0x00,0x5F,
+0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31,0x30,0x34,
+0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31,0x32,0x33,
+0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x3D,0x31,0x3B,0x30,0x39,0x06,0x03,
+0x55,0x04,0x03,0x1E,0x32,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00,0x50,0x00,
+0x32,0x00,0x35,0x00,0x36,0x00,0x5F,0x00,0x53,0x00,0x70,0x00,0x65,0x00,0x63,0x00,
+0x69,0x00,0x66,0x00,0x69,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00,
+0x41,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x59,0x30,0x13,0x06,0x07,0x2A,0x86,0x48,
+0xCE,0x3D,0x02,0x01,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07,0x03,0x42,
+0x00,0x04,0x6C,0xCD,0x5C,0xC7,0xCD,0xE2,0x79,0x33,0xD5,0x37,0x30,0xD7,0x65,0x9A,
+0xEB,0x45,0x10,0x57,0xCF,0x06,0x51,0xA4,0xFB,0xCA,0x02,0x62,0xB9,0x83,0x58,0xFA,
+0xB3,0xB4,0x01,0x85,0x4D,0xBE,0x8F,0x85,0x43,0xA0,0x1F,0x91,0x40,0x8F,0x9E,0xF0,
+0xCD,0xA6,0xFD,0x62,0x3E,0x99,0xEF,0x4F,0x18,0x9E,0x3F,0x0A,0x0E,0x12,0x0E,0x5E,
+0x5A,0x1B,0xA3,0x81,0xD3,0x30,0x81,0xD0,0x30,0x81,0xCD,0x06,0x0F,0x2B,0x06,0x01,
+0x04,0x01,0x82,0x37,0x13,0x82,0xDF,0x67,0x86,0xA3,0x53,0x01,0x04,0x81,0xB9,0x30,
+0x81,0xB6,0x04,0x12,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53,
+0x61,0x6D,0x70,0x6C,0x65,0x00,0x04,0x1A,0x45,0x6E,0x64,0x5F,0x50,0x32,0x35,0x36,
+0x5F,0x53,0x70,0x65,0x63,0x69,0x66,0x69,0x65,0x64,0x5F,0x53,0x48,0x41,0x32,0x35,
+0x36,0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14,0x45,0x00,0x43,0x00,0x44,0x00,
+0x53,0x00,0x41,0x00,0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x00,0x04,0x68,
+0x45,0x43,0x53,0x32,0x20,0x00,0x00,0x00,0x6C,0xCD,0x5C,0xC7,0xCD,0xE2,0x79,0x33,
+0xD5,0x37,0x30,0xD7,0x65,0x9A,0xEB,0x45,0x10,0x57,0xCF,0x06,0x51,0xA4,0xFB,0xCA,
+0x02,0x62,0xB9,0x83,0x58,0xFA,0xB3,0xB4,0x01,0x85,0x4D,0xBE,0x8F,0x85,0x43,0xA0,
+0x1F,0x91,0x40,0x8F,0x9E,0xF0,0xCD,0xA6,0xFD,0x62,0x3E,0x99,0xEF,0x4F,0x18,0x9E,
+0x3F,0x0A,0x0E,0x12,0x0E,0x5E,0x5A,0x1B,0x2F,0xA9,0x13,0x48,0xAA,0x53,0x7C,0x1F,
+0x20,0x87,0xC9,0xAF,0x94,0x50,0x75,0xDC,0xAA,0x2B,0xEC,0x08,0xB5,0x78,0x19,0x16,
+0x88,0x24,0xCC,0x8B,0x7D,0xCF,0x6F,0xDA,0x30,0x18,0x06,0x07,0x2A,0x86,0x48,0xCE,
+0x3D,0x04,0x03,0x30,0x0D,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,
+0x05,0x00,0x03,0x49,0x00,0x30,0x46,0x02,0x21,0x00,0xB9,0xE7,0x43,0x4B,0x49,0xA9,
+0x28,0xE0,0x25,0x6A,0xF6,0x40,0xF8,0xD7,0x08,0x1A,0x90,0x48,0x96,0x2B,0x13,0x23,
+0x50,0xE9,0x93,0x18,0xEA,0x0D,0x24,0x79,0xF6,0x40,0x02,0x21,0x00,0xBC,0xB3,0x8D,
+0xDF,0x5C,0x96,0xE4,0xB0,0x20,0xBA,0xAE,0x59,0x83,0x1E,0xE6,0x0D,0x06,0x5A,0x0B,
+0x3A,0xCB,0xA7,0x52,0xC9,0x20,0x90,0x78,0xA9,0x36,0x11,0xC3,0x9E,
+};
+/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x003\x008\x004\x00_\x00S\x00p\x00e\x00c\x00i\x00f\x00i\x00e\x00d\x00_\x00S\x00H\x00A\x002\x005\x006 */
+/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */
+unsigned char End_P384_Specified_SHA256_cer[668]={
+0x30,0x82,0x02,0x98,0x30,0x82,0x02,0x30,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0xD7,
+0x49,0x65,0x6B,0xBB,0x38,0x01,0xB1,0x43,0xDD,0xC2,0xB9,0x37,0xD8,0x2B,0x56,0x30,
+0x18,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x30,0x0D,0x06,0x09,0x60,0x86,
+0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x30,0x1D,0x31,0x1B,0x30,0x19,0x06,
+0x03,0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54,0x00,0x5F,
+0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31,0x30,0x34,
+0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31,0x32,0x33,
+0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x3D,0x31,0x3B,0x30,0x39,0x06,0x03,
+0x55,0x04,0x03,0x1E,0x32,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00,0x50,0x00,
+0x33,0x00,0x38,0x00,0x34,0x00,0x5F,0x00,0x53,0x00,0x70,0x00,0x65,0x00,0x63,0x00,
+0x69,0x00,0x66,0x00,0x69,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00,
+0x41,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,
+0xCE,0x3D,0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0x50,
+0x39,0x6D,0xDC,0x02,0x89,0xA4,0x44,0x90,0x3A,0x6E,0x4C,0xE0,0x97,0x35,0xD1,0x82,
+0xC2,0xBE,0xB3,0x48,0x7B,0x98,0xEB,0xA4,0x9D,0x04,0x38,0x9E,0xD9,0xB2,0x4C,0x5D,
+0xE3,0x6F,0x62,0x08,0x22,0x08,0xD9,0xA3,0xAE,0x43,0xB8,0xB5,0x65,0x2D,0x5F,0xB6,
+0x87,0xE9,0x41,0x0B,0x7D,0xA4,0x11,0x9F,0x08,0xCA,0x9B,0x39,0x84,0xDD,0x96,0xAC,
+0x28,0xC0,0xA0,0x1F,0x51,0x84,0xB1,0x1A,0x46,0xEF,0xE7,0x63,0x72,0xAA,0xD2,0x05,
+0x79,0xC1,0x3C,0x06,0x66,0xAE,0x84,0x10,0x74,0x9F,0xB1,0xFF,0x9F,0x34,0xBF,0xA3,
+0x82,0x01,0x05,0x30,0x82,0x01,0x01,0x30,0x81,0xFE,0x06,0x0F,0x2B,0x06,0x01,0x04,
+0x01,0x82,0x37,0x13,0x82,0xDF,0x67,0x86,0xA3,0x53,0x01,0x04,0x81,0xEA,0x30,0x81,
+0xE7,0x04,0x12,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53,0x61,
+0x6D,0x70,0x6C,0x65,0x00,0x04,0x1A,0x45,0x6E,0x64,0x5F,0x50,0x33,0x38,0x34,0x5F,
+0x53,0x70,0x65,0x63,0x69,0x66,0x69,0x65,0x64,0x5F,0x53,0x48,0x41,0x32,0x35,0x36,
+0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14,0x45,0x00,0x43,0x00,0x44,0x00,0x53,
+0x00,0x41,0x00,0x5F,0x00,0x50,0x00,0x33,0x00,0x38,0x00,0x34,0x00,0x04,0x81,0x98,
+0x45,0x43,0x53,0x34,0x30,0x00,0x00,0x00,0x50,0x39,0x6D,0xDC,0x02,0x89,0xA4,0x44,
+0x90,0x3A,0x6E,0x4C,0xE0,0x97,0x35,0xD1,0x82,0xC2,0xBE,0xB3,0x48,0x7B,0x98,0xEB,
+0xA4,0x9D,0x04,0x38,0x9E,0xD9,0xB2,0x4C,0x5D,0xE3,0x6F,0x62,0x08,0x22,0x08,0xD9,
+0xA3,0xAE,0x43,0xB8,0xB5,0x65,0x2D,0x5F,0xB6,0x87,0xE9,0x41,0x0B,0x7D,0xA4,0x11,
+0x9F,0x08,0xCA,0x9B,0x39,0x84,0xDD,0x96,0xAC,0x28,0xC0,0xA0,0x1F,0x51,0x84,0xB1,
+0x1A,0x46,0xEF,0xE7,0x63,0x72,0xAA,0xD2,0x05,0x79,0xC1,0x3C,0x06,0x66,0xAE,0x84,
+0x10,0x74,0x9F,0xB1,0xFF,0x9F,0x34,0xBF,0x58,0x01,0x0E,0x04,0x30,0xAF,0x13,0xE2,
+0x71,0x54,0xA4,0xE6,0x9C,0x43,0x67,0x02,0x55,0xE4,0x11,0xF5,0x7C,0x5A,0x86,0x92,
+0x08,0xEA,0xD2,0x75,0xE3,0xE7,0x73,0x99,0xAB,0xF7,0x5D,0x18,0x5B,0xDF,0x17,0x55,
+0x81,0xC9,0xC8,0x63,0x3E,0x6E,0x3F,0x81,0x30,0x18,0x06,0x07,0x2A,0x86,0x48,0xCE,
+0x3D,0x04,0x03,0x30,0x0D,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,
+0x05,0x00,0x03,0x48,0x00,0x30,0x45,0x02,0x20,0x59,0x2A,0xCA,0xB2,0x04,0x41,0x23,
+0xDD,0x0E,0x23,0x58,0xD2,0x02,0xCB,0xB5,0xDA,0x7E,0x2A,0x9D,0xFF,0xC8,0x5F,0x39,
+0x11,0xE2,0x45,0x1A,0x75,0x5C,0x76,0xCE,0x7D,0x02,0x21,0x00,0xC9,0x57,0xBB,0x43,
+0x27,0xAE,0x84,0x53,0x17,0x11,0xE5,0x9E,0x6C,0x3D,0x14,0xB4,0x71,0x05,0x9F,0x45,
+0x9E,0xEF,0x7F,0xF2,0xAF,0xBD,0x57,0xE5,0xE7,0xE4,0x25,0x0F,
+};
+/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x003\x008\x004\x00_\x00S\x00p\x00e\x00c\x00i\x00f\x00i\x00e\x00d\x00_\x00S\x00H\x00A\x003\x008\x004 */
+/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */
+unsigned char End_P384_Specified_SHA384_cer[669]={
+0x30,0x82,0x02,0x99,0x30,0x82,0x02,0x30,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0xF2,
+0x2A,0x87,0x2B,0x7D,0x53,0x13,0xA3,0x4A,0xF1,0x35,0x7C,0xDB,0x23,0x6F,0xA3,0x30,
+0x18,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x30,0x0D,0x06,0x09,0x60,0x86,
+0x48,0x01,0x65,0x03,0x04,0x02,0x02,0x05,0x00,0x30,0x1D,0x31,0x1B,0x30,0x19,0x06,
+0x03,0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54,0x00,0x5F,
+0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31,0x30,0x34,
+0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31,0x32,0x33,
+0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x3D,0x31,0x3B,0x30,0x39,0x06,0x03,
+0x55,0x04,0x03,0x1E,0x32,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00,0x50,0x00,
+0x33,0x00,0x38,0x00,0x34,0x00,0x5F,0x00,0x53,0x00,0x70,0x00,0x65,0x00,0x63,0x00,
+0x69,0x00,0x66,0x00,0x69,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00,
+0x41,0x00,0x33,0x00,0x38,0x00,0x34,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,
+0xCE,0x3D,0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0x50,
+0x39,0x6D,0xDC,0x02,0x89,0xA4,0x44,0x90,0x3A,0x6E,0x4C,0xE0,0x97,0x35,0xD1,0x82,
+0xC2,0xBE,0xB3,0x48,0x7B,0x98,0xEB,0xA4,0x9D,0x04,0x38,0x9E,0xD9,0xB2,0x4C,0x5D,
+0xE3,0x6F,0x62,0x08,0x22,0x08,0xD9,0xA3,0xAE,0x43,0xB8,0xB5,0x65,0x2D,0x5F,0xB6,
+0x87,0xE9,0x41,0x0B,0x7D,0xA4,0x11,0x9F,0x08,0xCA,0x9B,0x39,0x84,0xDD,0x96,0xAC,
+0x28,0xC0,0xA0,0x1F,0x51,0x84,0xB1,0x1A,0x46,0xEF,0xE7,0x63,0x72,0xAA,0xD2,0x05,
+0x79,0xC1,0x3C,0x06,0x66,0xAE,0x84,0x10,0x74,0x9F,0xB1,0xFF,0x9F,0x34,0xBF,0xA3,
+0x82,0x01,0x05,0x30,0x82,0x01,0x01,0x30,0x81,0xFE,0x06,0x0F,0x2B,0x06,0x01,0x04,
+0x01,0x82,0x37,0x13,0x82,0xDF,0x67,0x86,0xA3,0x53,0x01,0x04,0x81,0xEA,0x30,0x81,
+0xE7,0x04,0x12,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53,0x61,
+0x6D,0x70,0x6C,0x65,0x00,0x04,0x1A,0x45,0x6E,0x64,0x5F,0x50,0x33,0x38,0x34,0x5F,
+0x53,0x70,0x65,0x63,0x69,0x66,0x69,0x65,0x64,0x5F,0x53,0x48,0x41,0x33,0x38,0x34,
+0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14,0x45,0x00,0x43,0x00,0x44,0x00,0x53,
+0x00,0x41,0x00,0x5F,0x00,0x50,0x00,0x33,0x00,0x38,0x00,0x34,0x00,0x04,0x81,0x98,
+0x45,0x43,0x53,0x34,0x30,0x00,0x00,0x00,0x50,0x39,0x6D,0xDC,0x02,0x89,0xA4,0x44,
+0x90,0x3A,0x6E,0x4C,0xE0,0x97,0x35,0xD1,0x82,0xC2,0xBE,0xB3,0x48,0x7B,0x98,0xEB,
+0xA4,0x9D,0x04,0x38,0x9E,0xD9,0xB2,0x4C,0x5D,0xE3,0x6F,0x62,0x08,0x22,0x08,0xD9,
+0xA3,0xAE,0x43,0xB8,0xB5,0x65,0x2D,0x5F,0xB6,0x87,0xE9,0x41,0x0B,0x7D,0xA4,0x11,
+0x9F,0x08,0xCA,0x9B,0x39,0x84,0xDD,0x96,0xAC,0x28,0xC0,0xA0,0x1F,0x51,0x84,0xB1,
+0x1A,0x46,0xEF,0xE7,0x63,0x72,0xAA,0xD2,0x05,0x79,0xC1,0x3C,0x06,0x66,0xAE,0x84,
+0x10,0x74,0x9F,0xB1,0xFF,0x9F,0x34,0xBF,0x58,0x01,0x0E,0x04,0x30,0xAF,0x13,0xE2,
+0x71,0x54,0xA4,0xE6,0x9C,0x43,0x67,0x02,0x55,0xE4,0x11,0xF5,0x7C,0x5A,0x86,0x92,
+0x08,0xEA,0xD2,0x75,0xE3,0xE7,0x73,0x99,0xAB,0xF7,0x5D,0x18,0x5B,0xDF,0x17,0x55,
+0x81,0xC9,0xC8,0x63,0x3E,0x6E,0x3F,0x81,0x30,0x18,0x06,0x07,0x2A,0x86,0x48,0xCE,
+0x3D,0x04,0x03,0x30,0x0D,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,
+0x05,0x00,0x03,0x49,0x00,0x30,0x46,0x02,0x21,0x00,0xB8,0x9E,0x1B,0xB7,0x4C,0x37,
+0x88,0xD0,0x41,0x96,0xBD,0x8C,0xC4,0xD4,0x51,0xC8,0xF8,0xEB,0xE2,0x40,0x1B,0x15,
+0x68,0x36,0xB0,0x72,0x90,0x03,0x7B,0x7C,0xF3,0xD3,0x02,0x21,0x00,0xC2,0x00,0x4F,
+0x0D,0xD7,0x3A,0x21,0x3F,0x02,0x3F,0x76,0x4E,0xA8,0xF2,0x70,0x19,0xFF,0x88,0x0A,
+0xE8,0xA8,0x50,0xD4,0xD5,0x88,0xFD,0x2E,0x32,0xA4,0xED,0x63,0x4B,
+};
+/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x005\x002\x001\x00_\x00S\x00p\x00e\x00c\x00i\x00f\x00i\x00e\x00d\x00_\x00S\x00H\x00A\x001 */
+/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */
+unsigned char End_P521_Specified_SHA1_cer[749]={
+0x30,0x82,0x02,0xE9,0x30,0x82,0x02,0x85,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0xBB,
+0x17,0x7C,0x5C,0xD2,0x80,0xF2,0x8F,0x4B,0x16,0x8F,0x07,0x9B,0x85,0x90,0x34,0x30,
+0x14,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x30,0x09,0x06,0x05,0x2B,0x0E,
+0x03,0x02,0x1A,0x05,0x00,0x30,0x1D,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x03,
+0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54,0x00,0x5F,0x00,0x50,0x00,0x32,
+0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31,0x30,0x34,0x30,0x31,0x30,0x30,
+0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31,0x32,0x33,0x31,0x30,0x30,0x30,
+0x30,0x30,0x30,0x5A,0x30,0x39,0x31,0x37,0x30,0x35,0x06,0x03,0x55,0x04,0x03,0x1E,
+0x2E,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00,0x50,0x00,0x35,0x00,0x32,0x00,
+0x31,0x00,0x5F,0x00,0x53,0x00,0x70,0x00,0x65,0x00,0x63,0x00,0x69,0x00,0x66,0x00,
+0x69,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00,0x41,0x00,0x31,0x30,
+0x81,0x9B,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,0x06,0x05,0x2B,
+0x81,0x04,0x00,0x23,0x03,0x81,0x86,0x00,0x04,0x01,0x8C,0x45,0xFF,0x45,0x37,0x84,
+0x67,0x93,0x5F,0x82,0xE0,0xD2,0x4D,0xF4,0xB7,0xC4,0x1F,0x19,0xF2,0xCC,0xB6,0x78,
+0xA5,0xE9,0x2B,0xFF,0x31,0xBB,0xE7,0x4C,0x23,0xB9,0xA4,0x9F,0x5B,0x7A,0x55,0x54,
+0xF8,0x31,0x4D,0x64,0x9D,0x76,0xE9,0x98,0x24,0xCA,0xBA,0x6E,0x32,0x87,0x76,0xA8,
+0x08,0xCD,0x75,0x8A,0x03,0x7D,0x63,0x2C,0xD1,0xCB,0xD1,0x01,0x05,0x14,0xF8,0x2E,
+0xE5,0x28,0x23,0xB6,0x77,0xCF,0x5B,0xC0,0x74,0xED,0xF1,0x44,0xD0,0x60,0x0F,0xAA,
+0x70,0x86,0x01,0xD0,0x86,0x46,0x66,0xC6,0xF2,0x19,0xD5,0x87,0xBC,0x56,0xC7,0x90,
+0xA7,0x78,0x5F,0x57,0x6F,0x2D,0x3D,0x0B,0xB2,0x7C,0xF3,0xBF,0x1C,0x8B,0x00,0xED,
+0xDC,0x01,0x3F,0xFA,0xFE,0xE8,0x42,0x82,0x02,0xE4,0xCB,0xF8,0x57,0xA3,0x82,0x01,
+0x3C,0x30,0x82,0x01,0x38,0x30,0x82,0x01,0x34,0x06,0x0F,0x2B,0x06,0x01,0x04,0x01,
+0x82,0x37,0x13,0x82,0xDF,0x67,0x86,0xA3,0x53,0x01,0x04,0x82,0x01,0x1F,0x30,0x82,
+0x01,0x1B,0x04,0x12,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53,
+0x61,0x6D,0x70,0x6C,0x65,0x00,0x04,0x18,0x45,0x6E,0x64,0x5F,0x50,0x35,0x32,0x31,
+0x5F,0x53,0x70,0x65,0x63,0x69,0x66,0x69,0x65,0x64,0x5F,0x53,0x48,0x41,0x31,0x00,
+0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14,0x45,0x00,0x43,0x00,0x44,0x00,0x53,0x00,
+0x41,0x00,0x5F,0x00,0x50,0x00,0x35,0x00,0x32,0x00,0x31,0x00,0x04,0x81,0xCE,0x45,
+0x43,0x53,0x36,0x42,0x00,0x00,0x00,0x01,0x8C,0x45,0xFF,0x45,0x37,0x84,0x67,0x93,
+0x5F,0x82,0xE0,0xD2,0x4D,0xF4,0xB7,0xC4,0x1F,0x19,0xF2,0xCC,0xB6,0x78,0xA5,0xE9,
+0x2B,0xFF,0x31,0xBB,0xE7,0x4C,0x23,0xB9,0xA4,0x9F,0x5B,0x7A,0x55,0x54,0xF8,0x31,
+0x4D,0x64,0x9D,0x76,0xE9,0x98,0x24,0xCA,0xBA,0x6E,0x32,0x87,0x76,0xA8,0x08,0xCD,
+0x75,0x8A,0x03,0x7D,0x63,0x2C,0xD1,0xCB,0xD1,0x01,0x05,0x14,0xF8,0x2E,0xE5,0x28,
+0x23,0xB6,0x77,0xCF,0x5B,0xC0,0x74,0xED,0xF1,0x44,0xD0,0x60,0x0F,0xAA,0x70,0x86,
+0x01,0xD0,0x86,0x46,0x66,0xC6,0xF2,0x19,0xD5,0x87,0xBC,0x56,0xC7,0x90,0xA7,0x78,
+0x5F,0x57,0x6F,0x2D,0x3D,0x0B,0xB2,0x7C,0xF3,0xBF,0x1C,0x8B,0x00,0xED,0xDC,0x01,
+0x3F,0xFA,0xFE,0xE8,0x42,0x82,0x02,0xE4,0xCB,0xF8,0x57,0x00,0x6A,0x16,0xCB,0x4A,
+0x50,0x7E,0xA6,0x23,0xDA,0xB0,0xD4,0x76,0x76,0x2E,0x66,0x17,0x79,0x73,0x85,0x22,
+0x91,0xAE,0x66,0xEB,0xA0,0xE6,0x00,0x9F,0x5B,0x9E,0x63,0x39,0x5D,0xE7,0x57,0x0B,
+0xAB,0x1D,0xDE,0x69,0x35,0xD3,0xFB,0x7E,0x7C,0x57,0x08,0x67,0x6E,0x42,0x83,0xA8,
+0x6B,0xAA,0xA8,0x19,0x7C,0xC5,0xCF,0x05,0x88,0x57,0x9C,0xAC,0xB0,0x30,0x14,0x06,
+0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x30,0x09,0x06,0x05,0x2B,0x0E,0x03,0x02,
+0x1A,0x05,0x00,0x03,0x48,0x00,0x30,0x45,0x02,0x20,0x0B,0x00,0xD0,0x87,0x48,0x6E,
+0x91,0x69,0x6C,0xBD,0xE1,0x54,0x4E,0xD2,0x4A,0xB6,0x88,0x5E,0xAA,0xC1,0xFE,0xEF,
+0xDC,0x6A,0x7C,0x72,0x70,0xFD,0x54,0x47,0x61,0x6C,0x02,0x21,0x00,0xFD,0xD8,0xFE,
+0xBB,0xF3,0x60,0x49,0x42,0x77,0x6A,0x2B,0xB6,0x38,0x67,0xA3,0x52,0xE8,0xC1,0xA9,
+0x8E,0x81,0xD3,0xC5,0xA0,0x24,0x14,0x3F,0xC8,0xFD,0xBF,0x51,0xC5,
+};
+#endif /* TEST_ECDSA_WITH_SPECIFIED */
+
+/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x002\x005\x006\x00_\x00C\x00o\x00m\x00b\x00i\x00n\x00e\x00d\x00_\x00S\x00H\x00A\x002\x005\x006 */
+/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */
+unsigned char End_P256_combined_SHA256_cer[557]={
+0x30,0x82,0x02,0x29,0x30,0x82,0x01,0xCF,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x56,
+0xFE,0xDD,0xC2,0x3F,0xD9,0x7C,0xA3,0x48,0x0E,0x9E,0x46,0x75,0xAE,0x31,0x39,0x30,
+0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02,0x30,0x1D,0x31,0x1B,0x30,
+0x19,0x06,0x03,0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54,
+0x00,0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31,
+0x30,0x34,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31,
+0x32,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x3B,0x31,0x39,0x30,0x37,
+0x06,0x03,0x55,0x04,0x03,0x1E,0x30,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00,
+0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x00,0x5F,0x00,0x43,0x00,0x6F,0x00,0x6D,0x00,
+0x62,0x00,0x69,0x00,0x6E,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00,
+0x41,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x59,0x30,0x13,0x06,0x07,0x2A,0x86,0x48,
+0xCE,0x3D,0x02,0x01,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07,0x03,0x42,
+0x00,0x04,0x6C,0xCD,0x5C,0xC7,0xCD,0xE2,0x79,0x33,0xD5,0x37,0x30,0xD7,0x65,0x9A,
+0xEB,0x45,0x10,0x57,0xCF,0x06,0x51,0xA4,0xFB,0xCA,0x02,0x62,0xB9,0x83,0x58,0xFA,
+0xB3,0xB4,0x01,0x85,0x4D,0xBE,0x8F,0x85,0x43,0xA0,0x1F,0x91,0x40,0x8F,0x9E,0xF0,
+0xCD,0xA6,0xFD,0x62,0x3E,0x99,0xEF,0x4F,0x18,0x9E,0x3F,0x0A,0x0E,0x12,0x0E,0x5E,
+0x5A,0x1B,0xA3,0x81,0xD2,0x30,0x81,0xCF,0x30,0x81,0xCC,0x06,0x0F,0x2B,0x06,0x01,
+0x04,0x01,0x82,0x37,0x13,0x82,0xDF,0x67,0x86,0xA3,0x53,0x01,0x04,0x81,0xB8,0x30,
+0x81,0xB5,0x04,0x12,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53,
+0x61,0x6D,0x70,0x6C,0x65,0x00,0x04,0x19,0x45,0x6E,0x64,0x5F,0x50,0x32,0x35,0x36,
+0x5F,0x63,0x6F,0x6D,0x62,0x69,0x6E,0x65,0x64,0x5F,0x53,0x48,0x41,0x32,0x35,0x36,
+0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14,0x45,0x00,0x43,0x00,0x44,0x00,0x53,
+0x00,0x41,0x00,0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x00,0x04,0x68,0x45,
+0x43,0x53,0x32,0x20,0x00,0x00,0x00,0x6C,0xCD,0x5C,0xC7,0xCD,0xE2,0x79,0x33,0xD5,
+0x37,0x30,0xD7,0x65,0x9A,0xEB,0x45,0x10,0x57,0xCF,0x06,0x51,0xA4,0xFB,0xCA,0x02,
+0x62,0xB9,0x83,0x58,0xFA,0xB3,0xB4,0x01,0x85,0x4D,0xBE,0x8F,0x85,0x43,0xA0,0x1F,
+0x91,0x40,0x8F,0x9E,0xF0,0xCD,0xA6,0xFD,0x62,0x3E,0x99,0xEF,0x4F,0x18,0x9E,0x3F,
+0x0A,0x0E,0x12,0x0E,0x5E,0x5A,0x1B,0x2F,0xA9,0x13,0x48,0xAA,0x53,0x7C,0x1F,0x20,
+0x87,0xC9,0xAF,0x94,0x50,0x75,0xDC,0xAA,0x2B,0xEC,0x08,0xB5,0x78,0x19,0x16,0x88,
+0x24,0xCC,0x8B,0x7D,0xCF,0x6F,0xDA,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,
+0x04,0x03,0x02,0x03,0x48,0x00,0x30,0x45,0x02,0x20,0x7B,0x9C,0x11,0xF8,0x74,0x62,
+0x81,0x33,0x42,0x81,0x09,0x93,0x90,0x7D,0x3F,0xA6,0xEA,0xD6,0x47,0x7F,0x02,0xCE,
+0x6E,0x2A,0x70,0x69,0x4F,0xE3,0xA0,0x42,0x48,0xB3,0x02,0x21,0x00,0xD2,0x0F,0xFF,
+0xF5,0xDB,0x13,0xE7,0xD5,0xB2,0x4D,0x60,0x74,0x41,0xFD,0x7A,0xF7,0x87,0xFA,0x38,
+0xFF,0x41,0x62,0xC0,0x60,0xBE,0x85,0x77,0x50,0xE2,0x34,0x64,0x3E,
+};
+/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x002\x005\x006\x00_\x00C\x00o\x00m\x00b\x00i\x00n\x00e\x00d\x00_\x00S\x00H\x00A\x005\x001\x002 */
+/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */
+unsigned char End_P256_combined_SHA512_cer[557]={
+0x30,0x82,0x02,0x29,0x30,0x82,0x01,0xCF,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x6A,
+0x4A,0x02,0x0A,0xE7,0xBD,0x6F,0x90,0x40,0x1F,0xF8,0xF1,0xF6,0x29,0x0B,0x73,0x30,
+0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x04,0x30,0x1D,0x31,0x1B,0x30,
+0x19,0x06,0x03,0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54,
+0x00,0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31,
+0x30,0x34,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31,
+0x32,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x3B,0x31,0x39,0x30,0x37,
+0x06,0x03,0x55,0x04,0x03,0x1E,0x30,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00,
+0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x00,0x5F,0x00,0x43,0x00,0x6F,0x00,0x6D,0x00,
+0x62,0x00,0x69,0x00,0x6E,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00,
+0x41,0x00,0x35,0x00,0x31,0x00,0x32,0x30,0x59,0x30,0x13,0x06,0x07,0x2A,0x86,0x48,
+0xCE,0x3D,0x02,0x01,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07,0x03,0x42,
+0x00,0x04,0x6C,0xCD,0x5C,0xC7,0xCD,0xE2,0x79,0x33,0xD5,0x37,0x30,0xD7,0x65,0x9A,
+0xEB,0x45,0x10,0x57,0xCF,0x06,0x51,0xA4,0xFB,0xCA,0x02,0x62,0xB9,0x83,0x58,0xFA,
+0xB3,0xB4,0x01,0x85,0x4D,0xBE,0x8F,0x85,0x43,0xA0,0x1F,0x91,0x40,0x8F,0x9E,0xF0,
+0xCD,0xA6,0xFD,0x62,0x3E,0x99,0xEF,0x4F,0x18,0x9E,0x3F,0x0A,0x0E,0x12,0x0E,0x5E,
+0x5A,0x1B,0xA3,0x81,0xD2,0x30,0x81,0xCF,0x30,0x81,0xCC,0x06,0x0F,0x2B,0x06,0x01,
+0x04,0x01,0x82,0x37,0x13,0x82,0xDF,0x67,0x86,0xA3,0x53,0x01,0x04,0x81,0xB8,0x30,
+0x81,0xB5,0x04,0x12,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53,
+0x61,0x6D,0x70,0x6C,0x65,0x00,0x04,0x19,0x45,0x6E,0x64,0x5F,0x50,0x32,0x35,0x36,
+0x5F,0x63,0x6F,0x6D,0x62,0x69,0x6E,0x65,0x64,0x5F,0x53,0x48,0x41,0x35,0x31,0x32,
+0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14,0x45,0x00,0x43,0x00,0x44,0x00,0x53,
+0x00,0x41,0x00,0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x00,0x04,0x68,0x45,
+0x43,0x53,0x32,0x20,0x00,0x00,0x00,0x6C,0xCD,0x5C,0xC7,0xCD,0xE2,0x79,0x33,0xD5,
+0x37,0x30,0xD7,0x65,0x9A,0xEB,0x45,0x10,0x57,0xCF,0x06,0x51,0xA4,0xFB,0xCA,0x02,
+0x62,0xB9,0x83,0x58,0xFA,0xB3,0xB4,0x01,0x85,0x4D,0xBE,0x8F,0x85,0x43,0xA0,0x1F,
+0x91,0x40,0x8F,0x9E,0xF0,0xCD,0xA6,0xFD,0x62,0x3E,0x99,0xEF,0x4F,0x18,0x9E,0x3F,
+0x0A,0x0E,0x12,0x0E,0x5E,0x5A,0x1B,0x2F,0xA9,0x13,0x48,0xAA,0x53,0x7C,0x1F,0x20,
+0x87,0xC9,0xAF,0x94,0x50,0x75,0xDC,0xAA,0x2B,0xEC,0x08,0xB5,0x78,0x19,0x16,0x88,
+0x24,0xCC,0x8B,0x7D,0xCF,0x6F,0xDA,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,
+0x04,0x03,0x04,0x03,0x48,0x00,0x30,0x45,0x02,0x21,0x00,0x87,0xA9,0x50,0xE4,0x9D,
+0x51,0x56,0x8F,0x29,0xC1,0x0F,0xBD,0x10,0x6D,0x43,0x43,0x10,0x10,0xF3,0x08,0x9C,
+0x80,0x16,0x1A,0x5A,0x9F,0x1E,0x96,0x73,0x1C,0x96,0x54,0x02,0x20,0x1D,0x22,0xE1,
+0x9B,0x25,0x6E,0x21,0xB4,0x0A,0x64,0xF3,0xC4,0xDB,0x77,0xA4,0x5F,0x15,0x5A,0xAD,
+0xA4,0x81,0x68,0xB1,0x55,0xFE,0xD8,0xE6,0x4B,0xC8,0xB9,0x4C,0x95,
+};
+/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x003\x008\x004\x00_\x00C\x00o\x00m\x00b\x00i\x00n\x00e\x00d\x00_\x00S\x00H\x00A\x001 */
+/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */
+unsigned char End_P384_combined_SHA1_cer[628]={
+0x30,0x82,0x02,0x70,0x30,0x82,0x02,0x17,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x10,
+0x75,0xF7,0x9E,0x1A,0x44,0xE2,0xA6,0x48,0x38,0x44,0x2E,0xAD,0x3D,0x06,0xFD,0x30,
+0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30,0x1D,0x31,0x1B,0x30,0x19,
+0x06,0x03,0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54,0x00,
+0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31,0x30,
+0x34,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31,0x32,
+0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x37,0x31,0x35,0x30,0x33,0x06,
+0x03,0x55,0x04,0x03,0x1E,0x2C,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00,0x50,
+0x00,0x33,0x00,0x38,0x00,0x34,0x00,0x5F,0x00,0x43,0x00,0x6F,0x00,0x6D,0x00,0x62,
+0x00,0x69,0x00,0x6E,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00,0x41,
+0x00,0x31,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,0x06,
+0x05,0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0x50,0x39,0x6D,0xDC,0x02,0x89,
+0xA4,0x44,0x90,0x3A,0x6E,0x4C,0xE0,0x97,0x35,0xD1,0x82,0xC2,0xBE,0xB3,0x48,0x7B,
+0x98,0xEB,0xA4,0x9D,0x04,0x38,0x9E,0xD9,0xB2,0x4C,0x5D,0xE3,0x6F,0x62,0x08,0x22,
+0x08,0xD9,0xA3,0xAE,0x43,0xB8,0xB5,0x65,0x2D,0x5F,0xB6,0x87,0xE9,0x41,0x0B,0x7D,
+0xA4,0x11,0x9F,0x08,0xCA,0x9B,0x39,0x84,0xDD,0x96,0xAC,0x28,0xC0,0xA0,0x1F,0x51,
+0x84,0xB1,0x1A,0x46,0xEF,0xE7,0x63,0x72,0xAA,0xD2,0x05,0x79,0xC1,0x3C,0x06,0x66,
+0xAE,0x84,0x10,0x74,0x9F,0xB1,0xFF,0x9F,0x34,0xBF,0xA3,0x82,0x01,0x01,0x30,0x81,
+0xFE,0x30,0x81,0xFB,0x06,0x0F,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x13,0x82,0xDF,
+0x67,0x86,0xA3,0x53,0x01,0x04,0x81,0xE7,0x30,0x81,0xE4,0x04,0x12,0x43,0x65,0x72,
+0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53,0x61,0x6D,0x70,0x6C,0x65,0x00,0x04,
+0x17,0x45,0x6E,0x64,0x5F,0x50,0x33,0x38,0x34,0x5F,0x63,0x6F,0x6D,0x62,0x69,0x6E,
+0x65,0x64,0x5F,0x53,0x48,0x41,0x31,0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14,
+0x45,0x00,0x43,0x00,0x44,0x00,0x53,0x00,0x41,0x00,0x5F,0x00,0x50,0x00,0x33,0x00,
+0x38,0x00,0x34,0x00,0x04,0x81,0x98,0x45,0x43,0x53,0x34,0x30,0x00,0x00,0x00,0x50,
+0x39,0x6D,0xDC,0x02,0x89,0xA4,0x44,0x90,0x3A,0x6E,0x4C,0xE0,0x97,0x35,0xD1,0x82,
+0xC2,0xBE,0xB3,0x48,0x7B,0x98,0xEB,0xA4,0x9D,0x04,0x38,0x9E,0xD9,0xB2,0x4C,0x5D,
+0xE3,0x6F,0x62,0x08,0x22,0x08,0xD9,0xA3,0xAE,0x43,0xB8,0xB5,0x65,0x2D,0x5F,0xB6,
+0x87,0xE9,0x41,0x0B,0x7D,0xA4,0x11,0x9F,0x08,0xCA,0x9B,0x39,0x84,0xDD,0x96,0xAC,
+0x28,0xC0,0xA0,0x1F,0x51,0x84,0xB1,0x1A,0x46,0xEF,0xE7,0x63,0x72,0xAA,0xD2,0x05,
+0x79,0xC1,0x3C,0x06,0x66,0xAE,0x84,0x10,0x74,0x9F,0xB1,0xFF,0x9F,0x34,0xBF,0x58,
+0x01,0x0E,0x04,0x30,0xAF,0x13,0xE2,0x71,0x54,0xA4,0xE6,0x9C,0x43,0x67,0x02,0x55,
+0xE4,0x11,0xF5,0x7C,0x5A,0x86,0x92,0x08,0xEA,0xD2,0x75,0xE3,0xE7,0x73,0x99,0xAB,
+0xF7,0x5D,0x18,0x5B,0xDF,0x17,0x55,0x81,0xC9,0xC8,0x63,0x3E,0x6E,0x3F,0x81,0x30,
+0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x03,0x48,0x00,0x30,0x45,0x02,
+0x20,0x5B,0x9F,0x7C,0x3A,0x41,0x10,0x43,0xC5,0x4E,0xF4,0xFA,0xCD,0xB4,0x55,0xE2,
+0x93,0x26,0xF9,0x3D,0xB5,0x4D,0x2B,0xE7,0x76,0x73,0x38,0xA0,0x4F,0xB6,0x89,0x63,
+0xF7,0x02,0x21,0x00,0xFC,0xD6,0xF7,0x3E,0x9E,0x8E,0x59,0x93,0x5C,0xAA,0x41,0xA2,
+0x24,0x9A,0x9F,0xBC,0x37,0xAE,0x45,0x7C,0x3C,0x7C,0xFF,0xC7,0xFE,0x4B,0x61,0x48,
+0x9B,0xE8,0xE6,0x38,
+};
+/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x003\x008\x004\x00_\x00C\x00o\x00m\x00b\x00i\x00n\x00e\x00d\x00_\x00S\x00H\x00A\x002\x005\x006 */
+/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */
+unsigned char End_P384_combined_SHA256_cer[636]={
+0x30,0x82,0x02,0x78,0x30,0x82,0x02,0x1F,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0xA8,
+0xC0,0xEA,0x79,0x10,0x6D,0x61,0xAD,0x43,0x66,0xD0,0xDC,0xAC,0x2E,0x51,0x06,0x30,
+0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02,0x30,0x1D,0x31,0x1B,0x30,
+0x19,0x06,0x03,0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54,
+0x00,0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31,
+0x30,0x34,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31,
+0x32,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x3B,0x31,0x39,0x30,0x37,
+0x06,0x03,0x55,0x04,0x03,0x1E,0x30,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00,
+0x50,0x00,0x33,0x00,0x38,0x00,0x34,0x00,0x5F,0x00,0x43,0x00,0x6F,0x00,0x6D,0x00,
+0x62,0x00,0x69,0x00,0x6E,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00,
+0x41,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,
+0xCE,0x3D,0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0x50,
+0x39,0x6D,0xDC,0x02,0x89,0xA4,0x44,0x90,0x3A,0x6E,0x4C,0xE0,0x97,0x35,0xD1,0x82,
+0xC2,0xBE,0xB3,0x48,0x7B,0x98,0xEB,0xA4,0x9D,0x04,0x38,0x9E,0xD9,0xB2,0x4C,0x5D,
+0xE3,0x6F,0x62,0x08,0x22,0x08,0xD9,0xA3,0xAE,0x43,0xB8,0xB5,0x65,0x2D,0x5F,0xB6,
+0x87,0xE9,0x41,0x0B,0x7D,0xA4,0x11,0x9F,0x08,0xCA,0x9B,0x39,0x84,0xDD,0x96,0xAC,
+0x28,0xC0,0xA0,0x1F,0x51,0x84,0xB1,0x1A,0x46,0xEF,0xE7,0x63,0x72,0xAA,0xD2,0x05,
+0x79,0xC1,0x3C,0x06,0x66,0xAE,0x84,0x10,0x74,0x9F,0xB1,0xFF,0x9F,0x34,0xBF,0xA3,
+0x82,0x01,0x04,0x30,0x82,0x01,0x00,0x30,0x81,0xFD,0x06,0x0F,0x2B,0x06,0x01,0x04,
+0x01,0x82,0x37,0x13,0x82,0xDF,0x67,0x86,0xA3,0x53,0x01,0x04,0x81,0xE9,0x30,0x81,
+0xE6,0x04,0x12,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53,0x61,
+0x6D,0x70,0x6C,0x65,0x00,0x04,0x19,0x45,0x6E,0x64,0x5F,0x50,0x33,0x38,0x34,0x5F,
+0x63,0x6F,0x6D,0x62,0x69,0x6E,0x65,0x64,0x5F,0x53,0x48,0x41,0x32,0x35,0x36,0x00,
+0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14,0x45,0x00,0x43,0x00,0x44,0x00,0x53,0x00,
+0x41,0x00,0x5F,0x00,0x50,0x00,0x33,0x00,0x38,0x00,0x34,0x00,0x04,0x81,0x98,0x45,
+0x43,0x53,0x34,0x30,0x00,0x00,0x00,0x50,0x39,0x6D,0xDC,0x02,0x89,0xA4,0x44,0x90,
+0x3A,0x6E,0x4C,0xE0,0x97,0x35,0xD1,0x82,0xC2,0xBE,0xB3,0x48,0x7B,0x98,0xEB,0xA4,
+0x9D,0x04,0x38,0x9E,0xD9,0xB2,0x4C,0x5D,0xE3,0x6F,0x62,0x08,0x22,0x08,0xD9,0xA3,
+0xAE,0x43,0xB8,0xB5,0x65,0x2D,0x5F,0xB6,0x87,0xE9,0x41,0x0B,0x7D,0xA4,0x11,0x9F,
+0x08,0xCA,0x9B,0x39,0x84,0xDD,0x96,0xAC,0x28,0xC0,0xA0,0x1F,0x51,0x84,0xB1,0x1A,
+0x46,0xEF,0xE7,0x63,0x72,0xAA,0xD2,0x05,0x79,0xC1,0x3C,0x06,0x66,0xAE,0x84,0x10,
+0x74,0x9F,0xB1,0xFF,0x9F,0x34,0xBF,0x58,0x01,0x0E,0x04,0x30,0xAF,0x13,0xE2,0x71,
+0x54,0xA4,0xE6,0x9C,0x43,0x67,0x02,0x55,0xE4,0x11,0xF5,0x7C,0x5A,0x86,0x92,0x08,
+0xEA,0xD2,0x75,0xE3,0xE7,0x73,0x99,0xAB,0xF7,0x5D,0x18,0x5B,0xDF,0x17,0x55,0x81,
+0xC9,0xC8,0x63,0x3E,0x6E,0x3F,0x81,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,
+0x04,0x03,0x02,0x03,0x47,0x00,0x30,0x44,0x02,0x20,0x29,0x22,0x02,0x06,0x24,0xB8,
+0xED,0xEC,0x12,0xC9,0xE5,0xE0,0xC7,0xB2,0x75,0x12,0x62,0x05,0xED,0x62,0xAF,0x9A,
+0x31,0x0D,0x42,0xA7,0x3C,0x03,0x2A,0x76,0xD8,0x1E,0x02,0x20,0x27,0x74,0x0F,0x3B,
+0x0A,0x8A,0x7D,0x4F,0x2B,0x76,0x0C,0x34,0x87,0xC8,0xD2,0xC9,0xBC,0xF7,0x0A,0x0D,
+0xF9,0x64,0x52,0xD2,0x8D,0xCF,0x9E,0x06,0x90,0xF6,0xE8,0x13,
+};
+/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x005\x002\x001\x00_\x00C\x00o\x00m\x00b\x00i\x00n\x00e\x00d\x00_\x00S\x00H\x00A\x001 */
+/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */
+unsigned char End_P521_combined_SHA1_cer[725]={
+0x30,0x82,0x02,0xD1,0x30,0x82,0x02,0x77,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0xD2,
+0x71,0xD1,0x3D,0x82,0x40,0xE3,0xA9,0x44,0x27,0x3F,0xC6,0x18,0x9A,0x4E,0x44,0x30,
+0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30,0x1D,0x31,0x1B,0x30,0x19,
+0x06,0x03,0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54,0x00,
+0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31,0x30,
+0x34,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31,0x32,
+0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x37,0x31,0x35,0x30,0x33,0x06,
+0x03,0x55,0x04,0x03,0x1E,0x2C,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00,0x50,
+0x00,0x35,0x00,0x32,0x00,0x31,0x00,0x5F,0x00,0x43,0x00,0x6F,0x00,0x6D,0x00,0x62,
+0x00,0x69,0x00,0x6E,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00,0x41,
+0x00,0x31,0x30,0x81,0x9B,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,
+0x06,0x05,0x2B,0x81,0x04,0x00,0x23,0x03,0x81,0x86,0x00,0x04,0x01,0x8C,0x45,0xFF,
+0x45,0x37,0x84,0x67,0x93,0x5F,0x82,0xE0,0xD2,0x4D,0xF4,0xB7,0xC4,0x1F,0x19,0xF2,
+0xCC,0xB6,0x78,0xA5,0xE9,0x2B,0xFF,0x31,0xBB,0xE7,0x4C,0x23,0xB9,0xA4,0x9F,0x5B,
+0x7A,0x55,0x54,0xF8,0x31,0x4D,0x64,0x9D,0x76,0xE9,0x98,0x24,0xCA,0xBA,0x6E,0x32,
+0x87,0x76,0xA8,0x08,0xCD,0x75,0x8A,0x03,0x7D,0x63,0x2C,0xD1,0xCB,0xD1,0x01,0x05,
+0x14,0xF8,0x2E,0xE5,0x28,0x23,0xB6,0x77,0xCF,0x5B,0xC0,0x74,0xED,0xF1,0x44,0xD0,
+0x60,0x0F,0xAA,0x70,0x86,0x01,0xD0,0x86,0x46,0x66,0xC6,0xF2,0x19,0xD5,0x87,0xBC,
+0x56,0xC7,0x90,0xA7,0x78,0x5F,0x57,0x6F,0x2D,0x3D,0x0B,0xB2,0x7C,0xF3,0xBF,0x1C,
+0x8B,0x00,0xED,0xDC,0x01,0x3F,0xFA,0xFE,0xE8,0x42,0x82,0x02,0xE4,0xCB,0xF8,0x57,
+0xA3,0x82,0x01,0x3B,0x30,0x82,0x01,0x37,0x30,0x82,0x01,0x33,0x06,0x0F,0x2B,0x06,
+0x01,0x04,0x01,0x82,0x37,0x13,0x82,0xDF,0x67,0x86,0xA3,0x53,0x01,0x04,0x82,0x01,
+0x1E,0x30,0x82,0x01,0x1A,0x04,0x12,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,
+0x74,0x65,0x53,0x61,0x6D,0x70,0x6C,0x65,0x00,0x04,0x17,0x45,0x6E,0x64,0x5F,0x50,
+0x35,0x32,0x31,0x5F,0x63,0x6F,0x6D,0x62,0x69,0x6E,0x65,0x64,0x5F,0x53,0x48,0x41,
+0x31,0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14,0x45,0x00,0x43,0x00,0x44,0x00,
+0x53,0x00,0x41,0x00,0x5F,0x00,0x50,0x00,0x35,0x00,0x32,0x00,0x31,0x00,0x04,0x81,
+0xCE,0x45,0x43,0x53,0x36,0x42,0x00,0x00,0x00,0x01,0x8C,0x45,0xFF,0x45,0x37,0x84,
+0x67,0x93,0x5F,0x82,0xE0,0xD2,0x4D,0xF4,0xB7,0xC4,0x1F,0x19,0xF2,0xCC,0xB6,0x78,
+0xA5,0xE9,0x2B,0xFF,0x31,0xBB,0xE7,0x4C,0x23,0xB9,0xA4,0x9F,0x5B,0x7A,0x55,0x54,
+0xF8,0x31,0x4D,0x64,0x9D,0x76,0xE9,0x98,0x24,0xCA,0xBA,0x6E,0x32,0x87,0x76,0xA8,
+0x08,0xCD,0x75,0x8A,0x03,0x7D,0x63,0x2C,0xD1,0xCB,0xD1,0x01,0x05,0x14,0xF8,0x2E,
+0xE5,0x28,0x23,0xB6,0x77,0xCF,0x5B,0xC0,0x74,0xED,0xF1,0x44,0xD0,0x60,0x0F,0xAA,
+0x70,0x86,0x01,0xD0,0x86,0x46,0x66,0xC6,0xF2,0x19,0xD5,0x87,0xBC,0x56,0xC7,0x90,
+0xA7,0x78,0x5F,0x57,0x6F,0x2D,0x3D,0x0B,0xB2,0x7C,0xF3,0xBF,0x1C,0x8B,0x00,0xED,
+0xDC,0x01,0x3F,0xFA,0xFE,0xE8,0x42,0x82,0x02,0xE4,0xCB,0xF8,0x57,0x00,0x6A,0x16,
+0xCB,0x4A,0x50,0x7E,0xA6,0x23,0xDA,0xB0,0xD4,0x76,0x76,0x2E,0x66,0x17,0x79,0x73,
+0x85,0x22,0x91,0xAE,0x66,0xEB,0xA0,0xE6,0x00,0x9F,0x5B,0x9E,0x63,0x39,0x5D,0xE7,
+0x57,0x0B,0xAB,0x1D,0xDE,0x69,0x35,0xD3,0xFB,0x7E,0x7C,0x57,0x08,0x67,0x6E,0x42,
+0x83,0xA8,0x6B,0xAA,0xA8,0x19,0x7C,0xC5,0xCF,0x05,0x88,0x57,0x9C,0xAC,0xB0,0x30,
+0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x03,0x49,0x00,0x30,0x46,0x02,
+0x21,0x00,0xC2,0xC4,0x47,0x63,0x90,0x43,0xDD,0x8C,0x62,0x6D,0x6F,0xC9,0xBE,0xDF,
+0x5E,0x85,0xDD,0x66,0xBC,0x50,0x3C,0x05,0xBA,0x1A,0x08,0x5B,0xE9,0x4F,0x53,0xA1,
+0x0E,0x93,0x02,0x21,0x00,0xDC,0xD6,0xA2,0x50,0x24,0x7C,0x62,0xFA,0x29,0x8B,0x97,
+0x8B,0x17,0x6F,0x1F,0x19,0x40,0x7B,0x50,0x7C,0xED,0xCE,0xB0,0xF5,0x6E,0xCA,0xE6,
+0xD2,0xFF,0xB2,0x10,0xBB,
+};
+/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x002\x005\x006\x00_\x00C\x00o\x00m\x00b\x00i\x00n\x00e\x00d\x00_\x00S\x00H\x00A\x005\x001\x002 */
+/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */
+unsigned char End_P521_combined_SHA512_cer[733]={
+0x30,0x82,0x02,0xD9,0x30,0x82,0x02,0x7E,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x4C,
+0xC5,0xA8,0x41,0x8A,0xCD,0x27,0xBB,0x44,0x7A,0x81,0xFE,0x64,0xBC,0xC2,0x86,0x30,
+0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x04,0x30,0x1D,0x31,0x1B,0x30,
+0x19,0x06,0x03,0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54,
+0x00,0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31,
+0x30,0x34,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31,
+0x32,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x3B,0x31,0x39,0x30,0x37,
+0x06,0x03,0x55,0x04,0x03,0x1E,0x30,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00,
+0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x00,0x5F,0x00,0x43,0x00,0x6F,0x00,0x6D,0x00,
+0x62,0x00,0x69,0x00,0x6E,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00,
+0x41,0x00,0x35,0x00,0x31,0x00,0x32,0x30,0x81,0x9B,0x30,0x10,0x06,0x07,0x2A,0x86,
+0x48,0xCE,0x3D,0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x23,0x03,0x81,0x86,0x00,
+0x04,0x01,0x8C,0x45,0xFF,0x45,0x37,0x84,0x67,0x93,0x5F,0x82,0xE0,0xD2,0x4D,0xF4,
+0xB7,0xC4,0x1F,0x19,0xF2,0xCC,0xB6,0x78,0xA5,0xE9,0x2B,0xFF,0x31,0xBB,0xE7,0x4C,
+0x23,0xB9,0xA4,0x9F,0x5B,0x7A,0x55,0x54,0xF8,0x31,0x4D,0x64,0x9D,0x76,0xE9,0x98,
+0x24,0xCA,0xBA,0x6E,0x32,0x87,0x76,0xA8,0x08,0xCD,0x75,0x8A,0x03,0x7D,0x63,0x2C,
+0xD1,0xCB,0xD1,0x01,0x05,0x14,0xF8,0x2E,0xE5,0x28,0x23,0xB6,0x77,0xCF,0x5B,0xC0,
+0x74,0xED,0xF1,0x44,0xD0,0x60,0x0F,0xAA,0x70,0x86,0x01,0xD0,0x86,0x46,0x66,0xC6,
+0xF2,0x19,0xD5,0x87,0xBC,0x56,0xC7,0x90,0xA7,0x78,0x5F,0x57,0x6F,0x2D,0x3D,0x0B,
+0xB2,0x7C,0xF3,0xBF,0x1C,0x8B,0x00,0xED,0xDC,0x01,0x3F,0xFA,0xFE,0xE8,0x42,0x82,
+0x02,0xE4,0xCB,0xF8,0x57,0xA3,0x82,0x01,0x3D,0x30,0x82,0x01,0x39,0x30,0x82,0x01,
+0x35,0x06,0x0F,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x13,0x82,0xDF,0x67,0x86,0xA3,
+0x53,0x01,0x04,0x82,0x01,0x20,0x30,0x82,0x01,0x1C,0x04,0x12,0x43,0x65,0x72,0x74,
+0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53,0x61,0x6D,0x70,0x6C,0x65,0x00,0x04,0x19,
+0x45,0x6E,0x64,0x5F,0x50,0x35,0x32,0x31,0x5F,0x63,0x6F,0x6D,0x62,0x69,0x6E,0x65,
+0x64,0x5F,0x53,0x48,0x41,0x35,0x31,0x32,0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x04,
+0x14,0x45,0x00,0x43,0x00,0x44,0x00,0x53,0x00,0x41,0x00,0x5F,0x00,0x50,0x00,0x35,
+0x00,0x32,0x00,0x31,0x00,0x04,0x81,0xCE,0x45,0x43,0x53,0x36,0x42,0x00,0x00,0x00,
+0x01,0x8C,0x45,0xFF,0x45,0x37,0x84,0x67,0x93,0x5F,0x82,0xE0,0xD2,0x4D,0xF4,0xB7,
+0xC4,0x1F,0x19,0xF2,0xCC,0xB6,0x78,0xA5,0xE9,0x2B,0xFF,0x31,0xBB,0xE7,0x4C,0x23,
+0xB9,0xA4,0x9F,0x5B,0x7A,0x55,0x54,0xF8,0x31,0x4D,0x64,0x9D,0x76,0xE9,0x98,0x24,
+0xCA,0xBA,0x6E,0x32,0x87,0x76,0xA8,0x08,0xCD,0x75,0x8A,0x03,0x7D,0x63,0x2C,0xD1,
+0xCB,0xD1,0x01,0x05,0x14,0xF8,0x2E,0xE5,0x28,0x23,0xB6,0x77,0xCF,0x5B,0xC0,0x74,
+0xED,0xF1,0x44,0xD0,0x60,0x0F,0xAA,0x70,0x86,0x01,0xD0,0x86,0x46,0x66,0xC6,0xF2,
+0x19,0xD5,0x87,0xBC,0x56,0xC7,0x90,0xA7,0x78,0x5F,0x57,0x6F,0x2D,0x3D,0x0B,0xB2,
+0x7C,0xF3,0xBF,0x1C,0x8B,0x00,0xED,0xDC,0x01,0x3F,0xFA,0xFE,0xE8,0x42,0x82,0x02,
+0xE4,0xCB,0xF8,0x57,0x00,0x6A,0x16,0xCB,0x4A,0x50,0x7E,0xA6,0x23,0xDA,0xB0,0xD4,
+0x76,0x76,0x2E,0x66,0x17,0x79,0x73,0x85,0x22,0x91,0xAE,0x66,0xEB,0xA0,0xE6,0x00,
+0x9F,0x5B,0x9E,0x63,0x39,0x5D,0xE7,0x57,0x0B,0xAB,0x1D,0xDE,0x69,0x35,0xD3,0xFB,
+0x7E,0x7C,0x57,0x08,0x67,0x6E,0x42,0x83,0xA8,0x6B,0xAA,0xA8,0x19,0x7C,0xC5,0xCF,
+0x05,0x88,0x57,0x9C,0xAC,0xB0,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,
+0x03,0x04,0x03,0x49,0x00,0x30,0x46,0x02,0x21,0x00,0xD3,0xE5,0x57,0xD9,0xA3,0x26,
+0x56,0x5F,0x1D,0x5C,0x88,0x1B,0x63,0x80,0x33,0x22,0x5D,0x35,0x52,0x3F,0x29,0xFC,
+0xFF,0x5E,0x5D,0xBE,0x80,0x4D,0xCD,0xC4,0xA1,0x27,0x02,0x21,0x00,0xAC,0xA0,0x01,
+0x4F,0x29,0xC3,0xA9,0x04,0xE3,0xB9,0xCB,0xA3,0xF7,0xF0,0x80,0x5C,0x61,0xCF,0x1F,
+0x8B,0xEE,0x79,0xBD,0x16,0x2D,0x5B,0xF3,0xBD,0xF2,0x84,0x49,0xF8,
+};
+/* subject:/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */
+/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */
+unsigned char RootP256_cer[539]={
+0x30,0x82,0x02,0x17,0x30,0x82,0x01,0xB0,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x8F,
+0x92,0x09,0xDB,0xA4,0xFC,0xDA,0xA1,0x45,0xC2,0xFA,0x59,0x87,0xC6,0xEA,0xE6,0x30,
+0x18,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x30,0x0D,0x06,0x09,0x60,0x86,
+0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x30,0x1D,0x31,0x1B,0x30,0x19,0x06,
+0x03,0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54,0x00,0x5F,
+0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31,0x30,0x34,
+0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31,0x32,0x33,
+0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x1D,0x31,0x1B,0x30,0x19,0x06,0x03,
+0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54,0x00,0x5F,0x00,
+0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x59,0x30,0x13,0x06,0x07,0x2A,0x86,0x48,
+0xCE,0x3D,0x02,0x01,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07,0x03,0x42,
+0x00,0x04,0x85,0x59,0x2A,0x87,0x8E,0x6A,0x9B,0xB9,0x19,0xD4,0x73,0x82,0x24,0xC1,
+0x03,0x15,0xB3,0xF1,0x70,0x88,0x1B,0xAA,0xBA,0x57,0xE8,0x76,0x9F,0xC0,0xCE,0xF6,
+0xA9,0xBB,0x19,0xF5,0x6B,0x09,0x63,0xFB,0x69,0xA1,0x3D,0x88,0x67,0x3E,0x7E,0x1F,
+0x7B,0x18,0xC8,0xF2,0x31,0xE6,0xD7,0x54,0xD5,0xA7,0xAA,0x09,0x9C,0x15,0xD1,0x8D,
+0x37,0x7F,0xA3,0x81,0xC3,0x30,0x81,0xC0,0x30,0x81,0xBD,0x06,0x0F,0x2B,0x06,0x01,
+0x04,0x01,0x82,0x37,0x13,0x82,0xDF,0x67,0x86,0xA3,0x53,0x01,0x04,0x81,0xA9,0x30,
+0x81,0xA6,0x04,0x12,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53,
+0x61,0x6D,0x70,0x6C,0x65,0x00,0x04,0x0A,0x52,0x4F,0x4F,0x54,0x5F,0x50,0x32,0x35,
+0x36,0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14,0x45,0x00,0x43,0x00,0x44,0x00,
+0x53,0x00,0x41,0x00,0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x00,0x04,0x68,
+0x45,0x43,0x53,0x32,0x20,0x00,0x00,0x00,0x85,0x59,0x2A,0x87,0x8E,0x6A,0x9B,0xB9,
+0x19,0xD4,0x73,0x82,0x24,0xC1,0x03,0x15,0xB3,0xF1,0x70,0x88,0x1B,0xAA,0xBA,0x57,
+0xE8,0x76,0x9F,0xC0,0xCE,0xF6,0xA9,0xBB,0x19,0xF5,0x6B,0x09,0x63,0xFB,0x69,0xA1,
+0x3D,0x88,0x67,0x3E,0x7E,0x1F,0x7B,0x18,0xC8,0xF2,0x31,0xE6,0xD7,0x54,0xD5,0xA7,
+0xAA,0x09,0x9C,0x15,0xD1,0x8D,0x37,0x7F,0x61,0x97,0x7D,0x85,0xBF,0x7E,0x4E,0xD5,
+0x70,0x08,0xF2,0xE8,0xB5,0xBC,0x39,0x59,0xB3,0x23,0x97,0x5F,0xD4,0xCB,0x63,0x74,
+0xB9,0x88,0x6D,0xD6,0xF4,0xB8,0x20,0xA8,0x30,0x18,0x06,0x07,0x2A,0x86,0x48,0xCE,
+0x3D,0x04,0x03,0x30,0x0D,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,
+0x05,0x00,0x03,0x47,0x00,0x30,0x44,0x02,0x20,0x44,0xC4,0xBD,0x7A,0xDE,0x6F,0x41,
+0xA6,0x78,0x82,0xFD,0x32,0xB7,0x55,0xCA,0xE3,0x21,0x01,0x1C,0xD5,0x6A,0x0B,0x19,
+0xA4,0xA9,0x4D,0x06,0x6F,0xB2,0xE8,0xBF,0x9E,0x02,0x20,0x20,0x1C,0x24,0xEA,0x39,
+0x24,0xEB,0x91,0xBE,0x73,0x76,0xAF,0xFC,0x99,0x60,0xEC,0x22,0xFD,0x43,0xBF,0xDA,
+0xF3,0x7F,0xE4,0x8E,0x6C,0xA5,0x46,0xBF,0x64,0x01,0x3D,
+};
+
+/* subject:/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test CA (secp256r1)/CN=dev.experimentalstuff.com */
+/* issuer :/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test CA (secp256r1)/CN=dev.experimentalstuff.com */
+unsigned char secp256r1ca_cer[825]={
+0x30,0x82,0x03,0x35,0x30,0x82,0x02,0xDD,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00,
+0xC5,0x80,0x5F,0x51,0x16,0xE3,0xA8,0x04,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,
+0x3D,0x04,0x01,0x30,0x81,0x9C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,
+0x02,0x55,0x53,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,
+0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x07,0x0C,0x0D,0x4D,0x6F,0x75,0x6E,0x74,
+0x61,0x69,0x6E,0x20,0x56,0x69,0x65,0x77,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,
+0x0A,0x0C,0x1D,0x53,0x75,0x6E,0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,
+0x65,0x6D,0x73,0x20,0x4C,0x61,0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,
+0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20,
+0x43,0x41,0x20,0x28,0x73,0x65,0x63,0x70,0x32,0x35,0x36,0x72,0x31,0x29,0x31,0x22,
+0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70,
+0x65,0x72,0x69,0x6D,0x65,0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63,
+0x6F,0x6D,0x30,0x1E,0x17,0x0D,0x30,0x35,0x31,0x32,0x30,0x36,0x32,0x31,0x32,0x39,
+0x35,0x33,0x5A,0x17,0x0D,0x31,0x30,0x30,0x31,0x31,0x34,0x32,0x31,0x32,0x39,0x35,
+0x33,0x5A,0x30,0x81,0x9C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
+0x55,0x53,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,0x31,
+0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x07,0x0C,0x0D,0x4D,0x6F,0x75,0x6E,0x74,0x61,
+0x69,0x6E,0x20,0x56,0x69,0x65,0x77,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A,
+0x0C,0x1D,0x53,0x75,0x6E,0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65,
+0x6D,0x73,0x20,0x4C,0x61,0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31,
+0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20,0x43,
+0x41,0x20,0x28,0x73,0x65,0x63,0x70,0x32,0x35,0x36,0x72,0x31,0x29,0x31,0x22,0x30,
+0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70,0x65,
+0x72,0x69,0x6D,0x65,0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63,0x6F,
+0x6D,0x30,0x59,0x30,0x13,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,0x06,0x08,
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07,0x03,0x42,0x00,0x04,0xDC,0xC0,0x0F,0x8D,
+0xF5,0xED,0x3E,0x9B,0x6F,0x5A,0x22,0xA3,0x52,0x76,0x6B,0x0B,0xB2,0x6F,0x6C,0x12,
+0x17,0xBA,0x24,0xB8,0x7C,0x1B,0x16,0x17,0xD3,0xB9,0x78,0x2F,0x2E,0xC4,0x1C,0x01,
+0x68,0x77,0xE0,0xC7,0x79,0x48,0x9E,0xF5,0xD6,0xB3,0x7B,0x6A,0x7F,0xAC,0x12,0xBD,
+0x11,0x57,0x21,0x3A,0x87,0xAC,0xE0,0x42,0x40,0xFC,0x0D,0x4C,0xA3,0x82,0x01,0x05,
+0x30,0x82,0x01,0x01,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x48,
+0xF7,0xD9,0x0A,0x7A,0x90,0xA1,0xD1,0x60,0xE9,0x89,0x41,0xC9,0x20,0x42,0xB2,0xB8,
+0xD0,0xEE,0x16,0x30,0x81,0xD1,0x06,0x03,0x55,0x1D,0x23,0x04,0x81,0xC9,0x30,0x81,
+0xC6,0x80,0x14,0x48,0xF7,0xD9,0x0A,0x7A,0x90,0xA1,0xD1,0x60,0xE9,0x89,0x41,0xC9,
+0x20,0x42,0xB2,0xB8,0xD0,0xEE,0x16,0xA1,0x81,0xA2,0xA4,0x81,0x9F,0x30,0x81,0x9C,
+0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0B,0x30,
+0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,0x31,0x16,0x30,0x14,0x06,0x03,
+0x55,0x04,0x07,0x0C,0x0D,0x4D,0x6F,0x75,0x6E,0x74,0x61,0x69,0x6E,0x20,0x56,0x69,
+0x65,0x77,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A,0x0C,0x1D,0x53,0x75,0x6E,
+0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65,0x6D,0x73,0x20,0x4C,0x61,
+0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31,0x1C,0x30,0x1A,0x06,0x03,
+0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20,0x43,0x41,0x20,0x28,0x73,0x65,
+0x63,0x70,0x32,0x35,0x36,0x72,0x31,0x29,0x31,0x22,0x30,0x20,0x06,0x03,0x55,0x04,
+0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70,0x65,0x72,0x69,0x6D,0x65,0x6E,
+0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63,0x6F,0x6D,0x82,0x09,0x00,0xC5,
+0x80,0x5F,0x51,0x16,0xE3,0xA8,0x04,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x04,0x05,
+0x30,0x03,0x01,0x01,0xFF,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,
+0x03,0x47,0x00,0x30,0x44,0x02,0x20,0x79,0x72,0xE8,0x77,0xD2,0xBB,0x03,0x75,0x46,
+0x47,0x0F,0xF7,0xC0,0xC5,0xEB,0x9F,0x13,0x54,0x03,0xE2,0xB8,0xCB,0x37,0xC0,0x7F,
+0x53,0xA5,0x0B,0x2F,0x3D,0xDB,0x79,0x02,0x20,0x6A,0xAE,0xDF,0xEF,0x41,0xE6,0x56,
+0x60,0x1D,0x6B,0xC7,0x89,0x60,0x64,0x8E,0x99,0x01,0xA9,0xE8,0x01,0xA7,0x9B,0x75,
+0xED,0x8C,0x95,0xE0,0xAD,0x40,0x2F,0x17,0x07,
+};
+/* subject:/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test Server (secp256r1server-secp256r1ca)/CN=dev.experimentalstuff.com */
+/* issuer :/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test CA (secp256r1)/CN=dev.experimentalstuff.com */
+unsigned char secp256r1server_secp256r1ca_cer[578]={
+0x30,0x82,0x02,0x3E,0x30,0x82,0x01,0xE5,0x02,0x09,0x00,0xA0,0xDD,0x4F,0x0C,0x73,
+0xB5,0xC2,0x3A,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30,0x81,
+0x9C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0B,
+0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,0x31,0x16,0x30,0x14,0x06,
+0x03,0x55,0x04,0x07,0x0C,0x0D,0x4D,0x6F,0x75,0x6E,0x74,0x61,0x69,0x6E,0x20,0x56,
+0x69,0x65,0x77,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A,0x0C,0x1D,0x53,0x75,
+0x6E,0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65,0x6D,0x73,0x20,0x4C,
+0x61,0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31,0x1C,0x30,0x1A,0x06,
+0x03,0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20,0x43,0x41,0x20,0x28,0x73,
+0x65,0x63,0x70,0x32,0x35,0x36,0x72,0x31,0x29,0x31,0x22,0x30,0x20,0x06,0x03,0x55,
+0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70,0x65,0x72,0x69,0x6D,0x65,
+0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63,0x6F,0x6D,0x30,0x1E,0x17,
+0x0D,0x30,0x35,0x31,0x32,0x30,0x36,0x32,0x31,0x33,0x30,0x31,0x35,0x5A,0x17,0x0D,
+0x31,0x30,0x30,0x31,0x31,0x34,0x32,0x31,0x33,0x30,0x31,0x35,0x5A,0x30,0x81,0xB2,
+0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0B,0x30,
+0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,0x31,0x16,0x30,0x14,0x06,0x03,
+0x55,0x04,0x07,0x0C,0x0D,0x4D,0x6F,0x75,0x6E,0x74,0x61,0x69,0x6E,0x20,0x56,0x69,
+0x65,0x77,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A,0x0C,0x1D,0x53,0x75,0x6E,
+0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65,0x6D,0x73,0x20,0x4C,0x61,
+0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31,0x32,0x30,0x30,0x06,0x03,
+0x55,0x04,0x0B,0x0C,0x29,0x54,0x65,0x73,0x74,0x20,0x53,0x65,0x72,0x76,0x65,0x72,
+0x20,0x28,0x73,0x65,0x63,0x70,0x32,0x35,0x36,0x72,0x31,0x73,0x65,0x72,0x76,0x65,
+0x72,0x2D,0x73,0x65,0x63,0x70,0x32,0x35,0x36,0x72,0x31,0x63,0x61,0x29,0x31,0x22,
+0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70,
+0x65,0x72,0x69,0x6D,0x65,0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63,
+0x6F,0x6D,0x30,0x59,0x30,0x13,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,0x06,
+0x08,0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07,0x03,0x42,0x00,0x04,0x47,0x09,0x8C,
+0x61,0x41,0xD7,0xA6,0x9F,0x4B,0x7D,0xB0,0xE6,0x93,0x7D,0xF2,0x58,0xE8,0xC0,0x7F,
+0xD7,0xE5,0xCF,0x8D,0xC8,0x1E,0xA1,0x6A,0xDB,0x16,0xBA,0x6D,0xCC,0xEF,0x72,0x1B,
+0x7B,0x64,0x39,0x1A,0xED,0x49,0x92,0x39,0x54,0x3C,0x03,0xC7,0x76,0x15,0xD8,0xC6,
+0x06,0x5A,0x80,0x9C,0x42,0xAF,0x08,0x79,0x71,0xAB,0x0E,0x35,0x4A,0x30,0x09,0x06,
+0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x03,0x48,0x00,0x30,0x45,0x02,0x20,0x7F,
+0xBE,0x32,0x64,0x5A,0x63,0xB2,0x21,0xC9,0x27,0x22,0xE8,0x71,0x9F,0xB0,0x00,0x83,
+0xA2,0xD9,0x43,0x0E,0xDE,0xA4,0xBE,0x92,0x4E,0x09,0x35,0xD0,0x4B,0x41,0xBC,0x02,
+0x21,0x00,0xC0,0xD0,0x3E,0xE3,0xFC,0x15,0x78,0x4B,0xED,0x8D,0xE9,0xDD,0x80,0xB5,
+0xFB,0x89,0xC3,0x4A,0xDF,0x72,0xF9,0xDD,0xF2,0xBD,0x0A,0xA8,0x99,0xA2,0xF7,0xE2,
+0xC3,0xBA,
+};
+/* subject:/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test CA (secp384r1)/CN=dev.experimentalstuff.com */
+/* issuer :/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test CA (secp384r1)/CN=dev.experimentalstuff.com */
+unsigned char secp384r1ca_cer[887]={
+0x30,0x82,0x03,0x73,0x30,0x82,0x02,0xFA,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00,
+0xC2,0xA9,0x40,0xC7,0xF5,0x21,0x4A,0x02,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,
+0x3D,0x04,0x01,0x30,0x81,0x9C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,
+0x02,0x55,0x53,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,
+0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x07,0x0C,0x0D,0x4D,0x6F,0x75,0x6E,0x74,
+0x61,0x69,0x6E,0x20,0x56,0x69,0x65,0x77,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,
+0x0A,0x0C,0x1D,0x53,0x75,0x6E,0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,
+0x65,0x6D,0x73,0x20,0x4C,0x61,0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,
+0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20,
+0x43,0x41,0x20,0x28,0x73,0x65,0x63,0x70,0x33,0x38,0x34,0x72,0x31,0x29,0x31,0x22,
+0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70,
+0x65,0x72,0x69,0x6D,0x65,0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63,
+0x6F,0x6D,0x30,0x1E,0x17,0x0D,0x30,0x35,0x31,0x32,0x30,0x36,0x32,0x31,0x32,0x39,
+0x35,0x34,0x5A,0x17,0x0D,0x31,0x30,0x30,0x31,0x31,0x34,0x32,0x31,0x32,0x39,0x35,
+0x34,0x5A,0x30,0x81,0x9C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
+0x55,0x53,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,0x31,
+0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x07,0x0C,0x0D,0x4D,0x6F,0x75,0x6E,0x74,0x61,
+0x69,0x6E,0x20,0x56,0x69,0x65,0x77,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A,
+0x0C,0x1D,0x53,0x75,0x6E,0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65,
+0x6D,0x73,0x20,0x4C,0x61,0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31,
+0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20,0x43,
+0x41,0x20,0x28,0x73,0x65,0x63,0x70,0x33,0x38,0x34,0x72,0x31,0x29,0x31,0x22,0x30,
+0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70,0x65,
+0x72,0x69,0x6D,0x65,0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63,0x6F,
+0x6D,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,0x06,0x05,
+0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0xC6,0x97,0x31,0x8C,0x95,0x62,0x93,
+0x7A,0x41,0x67,0xBE,0xE5,0x3A,0x53,0x37,0xCA,0xFD,0x8D,0xB0,0x0F,0x50,0x43,0xBF,
+0x62,0xE4,0x76,0xDC,0x73,0x97,0xE4,0xAA,0xB5,0x6C,0xFD,0x06,0xA0,0x5F,0x7A,0xB9,
+0x7C,0x79,0xDD,0x7D,0x15,0xD0,0x43,0xA7,0x71,0xFF,0xE7,0x6A,0xF4,0xDD,0xF5,0xEE,
+0xE8,0x17,0x80,0x4E,0x82,0x40,0xAC,0x1D,0xED,0x1B,0x0F,0x6A,0x7C,0x6F,0xCD,0x88,
+0x21,0xB4,0x3D,0xE7,0x72,0xB7,0x0C,0x34,0xFA,0x78,0x85,0xB8,0x4D,0x71,0x7B,0x62,
+0xF4,0xBF,0xC4,0x5F,0x41,0xC8,0x8C,0x7F,0x89,0xA3,0x82,0x01,0x05,0x30,0x82,0x01,
+0x01,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xEA,0xCB,0x02,0x59,
+0x57,0xA6,0xC2,0x49,0xE3,0xA7,0x49,0x0D,0xEB,0x88,0x33,0x34,0x4C,0x37,0xC8,0x31,
+0x30,0x81,0xD1,0x06,0x03,0x55,0x1D,0x23,0x04,0x81,0xC9,0x30,0x81,0xC6,0x80,0x14,
+0xEA,0xCB,0x02,0x59,0x57,0xA6,0xC2,0x49,0xE3,0xA7,0x49,0x0D,0xEB,0x88,0x33,0x34,
+0x4C,0x37,0xC8,0x31,0xA1,0x81,0xA2,0xA4,0x81,0x9F,0x30,0x81,0x9C,0x31,0x0B,0x30,
+0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0B,0x30,0x09,0x06,0x03,
+0x55,0x04,0x08,0x0C,0x02,0x43,0x41,0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x07,
+0x0C,0x0D,0x4D,0x6F,0x75,0x6E,0x74,0x61,0x69,0x6E,0x20,0x56,0x69,0x65,0x77,0x31,
+0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A,0x0C,0x1D,0x53,0x75,0x6E,0x20,0x4D,0x69,
+0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65,0x6D,0x73,0x20,0x4C,0x61,0x62,0x6F,0x72,
+0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0B,
+0x0C,0x13,0x54,0x65,0x73,0x74,0x20,0x43,0x41,0x20,0x28,0x73,0x65,0x63,0x70,0x33,
+0x38,0x34,0x72,0x31,0x29,0x31,0x22,0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,
+0x64,0x65,0x76,0x2E,0x65,0x78,0x70,0x65,0x72,0x69,0x6D,0x65,0x6E,0x74,0x61,0x6C,
+0x73,0x74,0x75,0x66,0x66,0x2E,0x63,0x6F,0x6D,0x82,0x09,0x00,0xC2,0xA9,0x40,0xC7,
+0xF5,0x21,0x4A,0x02,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x04,0x05,0x30,0x03,0x01,
+0x01,0xFF,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x03,0x68,0x00,
+0x30,0x65,0x02,0x30,0x5B,0xF0,0x3E,0xD4,0xF0,0xE8,0xAA,0x3B,0xC6,0x54,0xF6,0x05,
+0x2B,0x90,0xCA,0x34,0x63,0x6D,0xC0,0x37,0x9F,0x28,0xDD,0x34,0x9A,0xA5,0x18,0x1E,
+0xEE,0xA8,0x80,0xB9,0x43,0x95,0xAD,0xA5,0xA2,0xA0,0xDA,0xEB,0x35,0x5A,0x42,0xDB,
+0x3D,0x98,0x23,0x66,0x02,0x31,0x00,0xB9,0xDD,0xB2,0x90,0xBE,0x5A,0x88,0x43,0xE1,
+0x9B,0x18,0xC6,0x3A,0x0B,0x9B,0xFE,0x17,0xFC,0xC4,0x4A,0x65,0x62,0x7B,0x4E,0xAF,
+0x6D,0xAE,0xEA,0x7B,0x6B,0xC8,0x97,0xA3,0x88,0x06,0x23,0xCE,0x3F,0x97,0x39,0x80,
+0x28,0xF8,0x36,0x3D,0x60,0xDE,0xE2,
+};
+/* subject:/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test Server (secp384r1server-secp384r1ca)/CN=dev.experimentalstuff.com */
+/* issuer :/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test CA (secp384r1)/CN=dev.experimentalstuff.com */
+unsigned char secp384r1server_secp384r1ca_cer[640]={
+0x30,0x82,0x02,0x7C,0x30,0x82,0x02,0x02,0x02,0x09,0x00,0xA0,0xDD,0x4F,0x0C,0x73,
+0xB5,0xC2,0x43,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30,0x81,
+0x9C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0B,
+0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,0x31,0x16,0x30,0x14,0x06,
+0x03,0x55,0x04,0x07,0x0C,0x0D,0x4D,0x6F,0x75,0x6E,0x74,0x61,0x69,0x6E,0x20,0x56,
+0x69,0x65,0x77,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A,0x0C,0x1D,0x53,0x75,
+0x6E,0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65,0x6D,0x73,0x20,0x4C,
+0x61,0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31,0x1C,0x30,0x1A,0x06,
+0x03,0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20,0x43,0x41,0x20,0x28,0x73,
+0x65,0x63,0x70,0x33,0x38,0x34,0x72,0x31,0x29,0x31,0x22,0x30,0x20,0x06,0x03,0x55,
+0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70,0x65,0x72,0x69,0x6D,0x65,
+0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63,0x6F,0x6D,0x30,0x1E,0x17,
+0x0D,0x30,0x35,0x31,0x32,0x30,0x36,0x32,0x31,0x33,0x30,0x32,0x32,0x5A,0x17,0x0D,
+0x31,0x30,0x30,0x31,0x31,0x34,0x32,0x31,0x33,0x30,0x32,0x32,0x5A,0x30,0x81,0xB2,
+0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0B,0x30,
+0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,0x31,0x16,0x30,0x14,0x06,0x03,
+0x55,0x04,0x07,0x0C,0x0D,0x4D,0x6F,0x75,0x6E,0x74,0x61,0x69,0x6E,0x20,0x56,0x69,
+0x65,0x77,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A,0x0C,0x1D,0x53,0x75,0x6E,
+0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65,0x6D,0x73,0x20,0x4C,0x61,
+0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31,0x32,0x30,0x30,0x06,0x03,
+0x55,0x04,0x0B,0x0C,0x29,0x54,0x65,0x73,0x74,0x20,0x53,0x65,0x72,0x76,0x65,0x72,
+0x20,0x28,0x73,0x65,0x63,0x70,0x33,0x38,0x34,0x72,0x31,0x73,0x65,0x72,0x76,0x65,
+0x72,0x2D,0x73,0x65,0x63,0x70,0x33,0x38,0x34,0x72,0x31,0x63,0x61,0x29,0x31,0x22,
+0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70,
+0x65,0x72,0x69,0x6D,0x65,0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63,
+0x6F,0x6D,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,0x06,
+0x05,0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0x2E,0xB6,0x93,0xC0,0x46,0xD0,
+0xAD,0x39,0x38,0xD2,0x75,0x3B,0xE8,0x8F,0xCC,0x51,0x6B,0xC3,0xAD,0x7E,0x07,0x12,
+0x19,0xCD,0xB7,0x65,0xA8,0xAF,0x9D,0x33,0xCC,0x7A,0x4D,0xB5,0xC5,0xA5,0x0E,0x1E,
+0xB8,0xC7,0x20,0xC8,0x50,0xEE,0x88,0x83,0x03,0xEE,0x99,0x8F,0x77,0x3C,0xC5,0x11,
+0x13,0x63,0x9B,0x13,0x0D,0x73,0x9B,0x68,0xCB,0xC7,0xE9,0x5D,0xDF,0x60,0x87,0x66,
+0x15,0x43,0xDC,0xD1,0x60,0xD5,0xEC,0x94,0xCF,0x15,0x16,0x5E,0x59,0xD5,0xE5,0x8C,
+0x8C,0x42,0x0E,0x24,0x33,0xE4,0x38,0x45,0xF4,0xA8,0x30,0x09,0x06,0x07,0x2A,0x86,
+0x48,0xCE,0x3D,0x04,0x01,0x03,0x69,0x00,0x30,0x66,0x02,0x31,0x00,0x9A,0x76,0xDA,
+0xF6,0x4A,0x3C,0xEF,0xC5,0x7A,0xD9,0x6A,0xC0,0xB2,0x1C,0x82,0x1A,0xA8,0xCB,0x4A,
+0xEE,0x78,0x2B,0x24,0x15,0x00,0xB9,0xDD,0xF8,0x54,0xD3,0x30,0x32,0x6D,0x38,0x88,
+0xCC,0x32,0xF3,0x33,0x70,0x30,0xC3,0x02,0x23,0x1C,0x72,0x2F,0x39,0x02,0x31,0x00,
+0xBC,0xA5,0x79,0xA7,0xDA,0xAB,0x3F,0x94,0x87,0x5D,0x16,0x5A,0x78,0x5E,0x9D,0x9E,
+0x30,0x11,0xC1,0xAD,0x9E,0xF3,0x2A,0xEC,0xD3,0x8B,0x03,0x6E,0x83,0xB6,0xD0,0x6A,
+0x1D,0xD6,0xB8,0x50,0x99,0xC1,0x91,0x11,0x41,0xA3,0x9F,0x8D,0xD2,0x6F,0xA5,0xE9,
+};
+/* subject:/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test CA (secp521r1)/CN=dev.experimentalstuff.com */
+/* issuer :/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test CA (secp521r1)/CN=dev.experimentalstuff.com */
+unsigned char secp521r1ca_cer[962]={
+0x30,0x82,0x03,0xBE,0x30,0x82,0x03,0x20,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00,
+0xD1,0x2B,0x56,0x0F,0xA8,0x93,0xA8,0x80,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,
+0x3D,0x04,0x01,0x30,0x81,0x9C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,
+0x02,0x55,0x53,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,
+0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x07,0x0C,0x0D,0x4D,0x6F,0x75,0x6E,0x74,
+0x61,0x69,0x6E,0x20,0x56,0x69,0x65,0x77,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,
+0x0A,0x0C,0x1D,0x53,0x75,0x6E,0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,
+0x65,0x6D,0x73,0x20,0x4C,0x61,0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,
+0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20,
+0x43,0x41,0x20,0x28,0x73,0x65,0x63,0x70,0x35,0x32,0x31,0x72,0x31,0x29,0x31,0x22,
+0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70,
+0x65,0x72,0x69,0x6D,0x65,0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63,
+0x6F,0x6D,0x30,0x1E,0x17,0x0D,0x30,0x35,0x31,0x32,0x30,0x36,0x32,0x31,0x32,0x39,
+0x35,0x35,0x5A,0x17,0x0D,0x31,0x30,0x30,0x31,0x31,0x34,0x32,0x31,0x32,0x39,0x35,
+0x35,0x5A,0x30,0x81,0x9C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
+0x55,0x53,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,0x31,
+0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x07,0x0C,0x0D,0x4D,0x6F,0x75,0x6E,0x74,0x61,
+0x69,0x6E,0x20,0x56,0x69,0x65,0x77,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A,
+0x0C,0x1D,0x53,0x75,0x6E,0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65,
+0x6D,0x73,0x20,0x4C,0x61,0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31,
+0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20,0x43,
+0x41,0x20,0x28,0x73,0x65,0x63,0x70,0x35,0x32,0x31,0x72,0x31,0x29,0x31,0x22,0x30,
+0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70,0x65,
+0x72,0x69,0x6D,0x65,0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63,0x6F,
+0x6D,0x30,0x81,0x9B,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,0x06,
+0x05,0x2B,0x81,0x04,0x00,0x23,0x03,0x81,0x86,0x00,0x04,0x00,0x33,0x52,0x71,0xF2,
+0x20,0x84,0x86,0x46,0x37,0x54,0xC8,0xF4,0x0E,0xA2,0x33,0xC1,0x7E,0x2E,0xB0,0x20,
+0xC6,0xB2,0x27,0x73,0xB9,0xE6,0x28,0x80,0x6D,0x75,0x86,0x1F,0xB0,0x55,0xB0,0x4F,
+0x83,0xFA,0x6D,0x0A,0x8D,0xAC,0xE6,0x62,0xC6,0xB4,0xA6,0x4E,0x26,0x57,0x48,0x65,
+0xA1,0xCD,0xA8,0xFE,0x80,0x60,0x1D,0x17,0xCB,0xDF,0xAF,0xCD,0x58,0x01,0x53,0x5E,
+0xD6,0x19,0x2E,0x3F,0x78,0x82,0xFF,0x88,0x9A,0x46,0x4F,0x6F,0xC8,0xC0,0xC7,0x36,
+0xF2,0x83,0x1D,0x07,0x94,0xC4,0x53,0x48,0x2F,0x65,0x13,0x01,0xF4,0x93,0x97,0x4B,
+0xD8,0x98,0xBD,0x42,0xE4,0xA9,0x29,0x61,0x4D,0xFE,0xA8,0x15,0x45,0x4C,0xBA,0x5A,
+0xEE,0xE2,0x26,0x93,0x5B,0x37,0xC1,0x02,0x24,0x4D,0x31,0xF2,0x14,0xB2,0xCC,0xA3,
+0x82,0x01,0x05,0x30,0x82,0x01,0x01,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,
+0x04,0x14,0x0C,0x0F,0xD9,0xE6,0x4E,0x8C,0x8A,0xBA,0x17,0xCE,0xCF,0xB1,0x28,0xE9,
+0xAA,0x78,0x91,0xCF,0x16,0x69,0x30,0x81,0xD1,0x06,0x03,0x55,0x1D,0x23,0x04,0x81,
+0xC9,0x30,0x81,0xC6,0x80,0x14,0x0C,0x0F,0xD9,0xE6,0x4E,0x8C,0x8A,0xBA,0x17,0xCE,
+0xCF,0xB1,0x28,0xE9,0xAA,0x78,0x91,0xCF,0x16,0x69,0xA1,0x81,0xA2,0xA4,0x81,0x9F,
+0x30,0x81,0x9C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,
+0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,0x31,0x16,0x30,
+0x14,0x06,0x03,0x55,0x04,0x07,0x0C,0x0D,0x4D,0x6F,0x75,0x6E,0x74,0x61,0x69,0x6E,
+0x20,0x56,0x69,0x65,0x77,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A,0x0C,0x1D,
+0x53,0x75,0x6E,0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65,0x6D,0x73,
+0x20,0x4C,0x61,0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31,0x1C,0x30,
+0x1A,0x06,0x03,0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20,0x43,0x41,0x20,
+0x28,0x73,0x65,0x63,0x70,0x35,0x32,0x31,0x72,0x31,0x29,0x31,0x22,0x30,0x20,0x06,
+0x03,0x55,0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70,0x65,0x72,0x69,
+0x6D,0x65,0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63,0x6F,0x6D,0x82,
+0x09,0x00,0xD1,0x2B,0x56,0x0F,0xA8,0x93,0xA8,0x80,0x30,0x0C,0x06,0x03,0x55,0x1D,
+0x13,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,
+0x3D,0x04,0x01,0x03,0x81,0x8C,0x00,0x30,0x81,0x88,0x02,0x42,0x01,0x80,0xFF,0x46,
+0x4F,0x45,0x30,0xF9,0x34,0x67,0x33,0x6B,0x5C,0x21,0xCA,0x45,0xD5,0xE4,0x8C,0x1A,
+0x9F,0xB2,0x80,0x79,0x55,0x84,0x63,0x14,0x84,0x27,0x23,0x3F,0x3E,0xC4,0x40,0x02,
+0x2A,0xA1,0xE3,0x76,0x66,0x1D,0xE1,0xD8,0xD1,0xEA,0x5E,0x8D,0x03,0x8A,0x25,0x29,
+0x09,0xFE,0x2D,0x4C,0x04,0xDA,0x19,0xAD,0xA2,0x6E,0xAB,0x7A,0xCD,0x86,0x02,0x42,
+0x01,0x3C,0x39,0x41,0x73,0x01,0xB3,0xA0,0x3C,0x54,0xE0,0x24,0x10,0x6F,0xFA,0xCF,
+0x70,0x51,0x0C,0x68,0x0E,0x48,0xE1,0xFA,0x46,0x75,0x23,0x58,0xB4,0x82,0x43,0x91,
+0x73,0x65,0xB9,0x51,0xC0,0x3E,0x4B,0xFE,0xB8,0xAF,0x65,0xAE,0x1B,0x23,0xBA,0xFA,
+0x55,0x6E,0x1E,0xFA,0xFA,0x63,0x37,0x07,0xD6,0xE0,0xE1,0x3A,0xBA,0xF8,0xFC,0x5B,
+0x28,0xDD,
+};
+/* subject:/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test Server (secp521r1server-secp521r1ca)/CN=dev.experimentalstuff.com */
+/* issuer :/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test CA (secp521r1)/CN=dev.experimentalstuff.com */
+unsigned char secp521r1server_secp521r1ca_cer[714]={
+0x30,0x82,0x02,0xC6,0x30,0x82,0x02,0x28,0x02,0x09,0x00,0xA0,0xDD,0x4F,0x0C,0x73,
+0xB5,0xC2,0x4C,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30,0x81,
+0x9C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0B,
+0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,0x31,0x16,0x30,0x14,0x06,
+0x03,0x55,0x04,0x07,0x0C,0x0D,0x4D,0x6F,0x75,0x6E,0x74,0x61,0x69,0x6E,0x20,0x56,
+0x69,0x65,0x77,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A,0x0C,0x1D,0x53,0x75,
+0x6E,0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65,0x6D,0x73,0x20,0x4C,
+0x61,0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31,0x1C,0x30,0x1A,0x06,
+0x03,0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20,0x43,0x41,0x20,0x28,0x73,
+0x65,0x63,0x70,0x35,0x32,0x31,0x72,0x31,0x29,0x31,0x22,0x30,0x20,0x06,0x03,0x55,
+0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70,0x65,0x72,0x69,0x6D,0x65,
+0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63,0x6F,0x6D,0x30,0x1E,0x17,
+0x0D,0x30,0x35,0x31,0x32,0x30,0x36,0x32,0x31,0x33,0x30,0x33,0x30,0x5A,0x17,0x0D,
+0x31,0x30,0x30,0x31,0x31,0x34,0x32,0x31,0x33,0x30,0x33,0x30,0x5A,0x30,0x81,0xB2,
+0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0B,0x30,
+0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,0x31,0x16,0x30,0x14,0x06,0x03,
+0x55,0x04,0x07,0x0C,0x0D,0x4D,0x6F,0x75,0x6E,0x74,0x61,0x69,0x6E,0x20,0x56,0x69,
+0x65,0x77,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A,0x0C,0x1D,0x53,0x75,0x6E,
+0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65,0x6D,0x73,0x20,0x4C,0x61,
+0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31,0x32,0x30,0x30,0x06,0x03,
+0x55,0x04,0x0B,0x0C,0x29,0x54,0x65,0x73,0x74,0x20,0x53,0x65,0x72,0x76,0x65,0x72,
+0x20,0x28,0x73,0x65,0x63,0x70,0x35,0x32,0x31,0x72,0x31,0x73,0x65,0x72,0x76,0x65,
+0x72,0x2D,0x73,0x65,0x63,0x70,0x35,0x32,0x31,0x72,0x31,0x63,0x61,0x29,0x31,0x22,
+0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70,
+0x65,0x72,0x69,0x6D,0x65,0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63,
+0x6F,0x6D,0x30,0x81,0x9B,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,
+0x06,0x05,0x2B,0x81,0x04,0x00,0x23,0x03,0x81,0x86,0x00,0x04,0x00,0xC9,0x8F,0xA5,
+0x49,0x40,0x30,0x24,0x4E,0x61,0x3C,0x45,0x02,0xC2,0xE7,0x1C,0x7A,0xB7,0x5F,0xCE,
+0x86,0x4C,0xA7,0x77,0x3D,0x1E,0x4C,0x3F,0x7E,0x7B,0xD5,0x8D,0x0A,0x40,0xD1,0x5B,
+0xDB,0xD2,0x98,0x81,0x27,0x7F,0x4C,0x44,0x21,0x98,0x8B,0xAD,0xD1,0x6D,0xA4,0x6C,
+0x41,0xEC,0x66,0x52,0xAD,0xD7,0x19,0xD6,0xCB,0xF2,0x6C,0x28,0x57,0x46,0x01,0xE6,
+0x78,0x8E,0x67,0xD7,0x20,0xE9,0x87,0xAA,0x5D,0x10,0x27,0x91,0xC4,0xBF,0x19,0xBA,
+0x07,0x36,0x3B,0x58,0x41,0x6C,0xAC,0xB5,0xAF,0x83,0xF9,0xD7,0xD7,0xF1,0x2D,0x60,
+0x60,0x1B,0x97,0x74,0xD6,0x6B,0x6C,0x67,0x40,0x8F,0xD5,0x0F,0xEF,0xE8,0x33,0xFF,
+0xD5,0xAB,0x3C,0xE7,0x2D,0xCF,0xA8,0x30,0xC9,0xE8,0x8A,0x2C,0xAB,0x2F,0xA2,0xC3,
+0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x03,0x81,0x8C,0x00,0x30,
+0x81,0x88,0x02,0x42,0x01,0x2B,0xC4,0xEB,0xEA,0xCE,0xB4,0xED,0xE5,0xE1,0xEB,0x74,
+0x7E,0x19,0xC5,0x49,0xF8,0x00,0xCF,0x5D,0x04,0x0A,0x97,0xDF,0x78,0xCA,0x5C,0x12,
+0x8D,0xB9,0x18,0x26,0xC9,0x82,0x31,0xA0,0x83,0xB6,0x73,0x6B,0x6A,0x91,0xDC,0x42,
+0xAD,0x79,0x9E,0xB9,0xD1,0x59,0x98,0x51,0x84,0x10,0x1A,0x2B,0xE5,0xB8,0x36,0x44,
+0xC2,0x3A,0xA6,0x47,0x28,0x5B,0x02,0x42,0x01,0xEE,0x93,0x23,0x1D,0x0A,0x71,0xA1,
+0x7A,0x0F,0x5C,0x16,0xF6,0xD9,0x66,0x45,0x76,0x7E,0xF3,0xCF,0x12,0x4B,0xA1,0x6A,
+0x05,0xD5,0x70,0x9F,0x86,0xBC,0xFF,0xA4,0xEB,0x4F,0x14,0x06,0x98,0x30,0xFA,0xA9,
+0x54,0xF0,0x19,0xCA,0x3B,0xEA,0xE9,0xA3,0x1E,0x76,0xA6,0xE7,0x42,0x9C,0xBE,0x0E,
+0xA2,0x04,0x08,0xDF,0x49,0x49,0xB0,0x8F,0xFE,0x7A,
+};
+
+
+#define CFReleaseSafe(CF) { CFTypeRef _cf = (CF); if (_cf) CFRelease(_cf); }
+#define CFReleaseNull(CF) { CFTypeRef _cf = (CF); if (_cf) CFRelease(_cf); (CF) = NULL; }
+
+#define trust_ok(CERT, ROOT, DATE, ...) \
+({ \
+    test_trust_ok(CERT, sizeof(CERT), ROOT, sizeof(ROOT), DATE, \
+        test_create_description(__VA_ARGS__), test_directive, test_reason, \
+               __FILE__, __LINE__); \
+})
+
+static void test_trust_ok(const uint8_t *cert_data, size_t cert_len,
+    const uint8_t *root_data, size_t root_len, const char *date_str,
+    CFStringRef testname, const char *directive,
+    const char *reason, const char *file, int line) {
+    SecTrustResultType trustResult;
+    SETUP: {
+        SecTrustRef trust = NULL;
+        SecCertificateRef cert, root;
+        setup("sectrust" /* testname */);
+        isnt(cert = SecCertificateCreateWithBytes(NULL, cert_data, cert_len),
+            NULL, "create cert");
+        isnt(root = SecCertificateCreateWithBytes(NULL, root_data, root_len),
+            NULL, "create root");
+
+        SecPolicyRef policy = SecPolicyCreateSSL(false, NULL);
+        ok_status(SecTrustCreateWithCertificates(cert, policy, &trust),
+            "create trust with single cert");
+        CFArrayRef anchors = CFArrayCreate(NULL, (const void **)&root, 1,
+            &kCFTypeArrayCallBacks);
+        ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set anchors");
+
+        /* 2006/03/03 00:12:00 */
+        CFDateRef date = CFDateCreate(NULL, 163037520.0);
+        ok_status(SecTrustSetVerifyDate(trust, date), "set date");
+        ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+
+        CFReleaseSafe(date);
+        CFReleaseSafe(anchors);
+        CFReleaseSafe(policy);
+        CFReleaseSafe(root);
+        CFReleaseSafe(cert);
+        CFReleaseSafe(trust);
+    }
+
+    test_ok(trustResult == kSecTrustResultUnspecified, testname,
+        directive, reason, file, line,
+        "#     unexpected trustResult: %ld\n", trustResult);
+}
+
+/* Test basic add delete update copy matching stuff. */
+static void tests(void)
+{
+    /* Verification of ECC certs created by Microsoft */
+    trust_ok(RootP256_cer, RootP256_cer,
+        "20060303001200", "RootP256_cer root");
+#if TEST_ECDSA_WITH_SPECIFIED
+    trust_ok(End_P256_Specified_SHA1_cer, RootP256_cer,
+        "20060303001200", "End_P256_Specified_SHA1_cer");
+    trust_ok(End_P256_Specified_SHA256_cer, RootP256_cer,
+        "20060303001200", "End_P256_Specified_SHA256_cer");
+    trust_ok(End_P384_Specified_SHA256_cer, RootP256_cer,
+        "20060303001200", "End_P384_Specified_SHA256_cer");
+    trust_ok(End_P384_Specified_SHA384_cer, RootP256_cer,
+        "20060303001200", "End_P384_Specified_SHA384_cer");
+    trust_ok(End_P521_Specified_SHA1_cer, RootP256_cer,
+        "20060303001200", "End_P521_Specified_SHA1_cer");
+#endif /* TEST_ECDSA_WITH_SPECIFIED */
+    trust_ok(End_P256_combined_SHA256_cer, RootP256_cer,
+        "20060303001200", "End_P256_combined_SHA256_cer");
+    trust_ok(End_P384_combined_SHA256_cer, RootP256_cer,
+        "20060303001200", "End_P384_combined_SHA256_cer");
+    trust_ok(End_P384_combined_SHA1_cer, RootP256_cer,
+        "20060303001200", "End_P384_combined_SHA1_cer");
+    trust_ok(End_P521_combined_SHA1_cer, RootP256_cer,
+        "20060303001200", "End_P521_combined_SHA1_cer");
+    TODO: {
+        todo("ecdsa-with-SHA512 seems to be failing");
+        trust_ok(End_P256_combined_SHA512_cer, RootP256_cer,
+            "20060303001200", "End_P256_combined_SHA512_cer");
+        trust_ok(End_P521_combined_SHA512_cer, RootP256_cer,
+            "20060303001200", "End_P521_combined_SHA512_cer");
+    }
+
+    /* Verification of ECC certs created by NSS */
+    trust_ok(ECCCA_cer, ECCCA_cer,
+        "20060303001200", "ECCCA_cer root");
+    trust_ok(ECCp192_cer, ECCCA_cer,
+        "20060303001200", "ECCp192_cer");
+    trust_ok(ECCp256_cer, ECCCA_cer,
+        "20060303001200", "ECCp256_cer");
+    trust_ok(ECCp384_cer, ECCCA_cer,
+        "20060303001200", "ECCp384_cer");
+    trust_ok(ECCp521_cer, ECCCA_cer,
+        "20060303001200", "ECCp521_cer");
+
+    /* Verification of ECC certs created by OpenSSL */
+    trust_ok(secp256r1ca_cer, secp256r1ca_cer,
+        "20060303001200", "secp256r1ca_cer root");
+    trust_ok(secp256r1server_secp256r1ca_cer, secp256r1ca_cer,
+        "20060303001200", "secp256r1server_secp256r1ca_cer");
+    trust_ok(secp384r1ca_cer, secp384r1ca_cer,
+        "20060303001200", "secp384r1ca_cer root");
+    trust_ok(secp384r1server_secp384r1ca_cer, secp384r1ca_cer,
+        "20060303001200", "secp384r1server_secp384r1ca_cer");
+    trust_ok(secp521r1ca_cer, secp521r1ca_cer,
+        "20060303001200", "secp521r1ca_cer root");
+    trust_ok(secp521r1server_secp521r1ca_cer, secp521r1ca_cer,
+        "20060303001200", "secp521r1server_secp521r1ca_cer");
+}
+
+int si_16_ec_certificate(int argc, char *const *argv)
+{
+#if TEST_ECDSA_WITH_SPECIFIED
+       plan_tests(23);
+#else /* !TEST_ECDSA_WITH_SPECIFIED */
+       plan_tests(18);
+#endif /* !TEST_ECDSA_WITH_SPECIFIED */
+
+
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-20-sectrust-activation.c b/sec/Security/Regressions/secitem/si-20-sectrust-activation.c
new file mode 100644 (file)
index 0000000..c6642e8
--- /dev/null
@@ -0,0 +1,942 @@
+/*
+ * Copyright (c) 2006-2010 Apple Inc. All Rights Reserved.
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecPolicyPriv.h>
+#include <Security/SecTrust.h>
+#include <Security/SecTrustPriv.h>
+#include <Security/SecInternal.h>
+#include <utilities/array_size.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "Security_regressions.h"
+
+unsigned char certa[] = {
+  0x30, 0x82, 0x02, 0xba, 0x30, 0x82, 0x01, 0xa2, 0xa0, 0x03, 0x02, 0x01,
+  0x02, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x00, 0x30, 0x1e, 0x17,
+  0x0d, 0x31, 0x30, 0x30, 0x38, 0x32, 0x34, 0x32, 0x32, 0x35, 0x35, 0x31,
+  0x37, 0x5a, 0x17, 0x0d, 0x32, 0x30, 0x30, 0x38, 0x32, 0x31, 0x32, 0x32,
+  0x35, 0x35, 0x31, 0x37, 0x5a, 0x30, 0x00, 0x30, 0x82, 0x01, 0x22, 0x30,
+  0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
+  0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02,
+  0x82, 0x01, 0x01, 0x00, 0xbe, 0xa4, 0x39, 0x73, 0x58, 0xca, 0xcc, 0x43,
+  0x1c, 0xb1, 0xce, 0x1e, 0xf3, 0x4b, 0xcd, 0x80, 0xb5, 0x90, 0x66, 0x06,
+  0xf7, 0x82, 0x08, 0xf8, 0xd6, 0x93, 0x6e, 0x06, 0x89, 0xed, 0x70, 0x66,
+  0xfb, 0xed, 0x96, 0xcd, 0xcb, 0x6a, 0x7b, 0x93, 0x74, 0x15, 0x8e, 0x37,
+  0x8b, 0x40, 0x6d, 0x29, 0xf7, 0x37, 0x4c, 0x44, 0x66, 0x73, 0xe4, 0xb2,
+  0x7f, 0x9b, 0x13, 0x73, 0x3a, 0x5d, 0x12, 0x1c, 0xa0, 0x39, 0x98, 0xdb,
+  0x26, 0xa1, 0x56, 0x2b, 0xf4, 0xc5, 0x39, 0xa3, 0xd8, 0x83, 0x2d, 0xa9,
+  0x6b, 0x73, 0xac, 0x42, 0xc0, 0xb8, 0xbf, 0xfb, 0xb7, 0x2e, 0xf2, 0x90,
+  0xa6, 0x96, 0xa4, 0x8c, 0xf5, 0xdf, 0xd4, 0x26, 0xff, 0x08, 0x30, 0x39,
+  0x1f, 0x59, 0xd4, 0xbf, 0x2f, 0x8f, 0x24, 0xab, 0x80, 0xff, 0x6c, 0x5a,
+  0x6b, 0xfd, 0x9b, 0xac, 0x10, 0x96, 0x86, 0x07, 0x04, 0x20, 0x1f, 0xb3,
+  0xf8, 0x0a, 0xdd, 0x09, 0x48, 0x04, 0x1e, 0x43, 0x66, 0x81, 0x96, 0xa4,
+  0x98, 0x3d, 0x50, 0x4e, 0xef, 0x29, 0x36, 0x3a, 0xad, 0x60, 0x70, 0xd3,
+  0x76, 0xee, 0xed, 0x6a, 0xd5, 0xf9, 0x6c, 0xac, 0x3f, 0x92, 0xff, 0x36,
+  0xe8, 0x96, 0x19, 0xfb, 0x6f, 0x8a, 0x68, 0xd0, 0x32, 0x2e, 0xc9, 0xe2,
+  0x47, 0xf7, 0x5d, 0xd3, 0xba, 0x84, 0x7f, 0x06, 0xaf, 0xa1, 0xa9, 0x7a,
+  0xb9, 0x02, 0xf3, 0x0a, 0x95, 0xe3, 0xef, 0x45, 0x99, 0x4d, 0x7d, 0xfb,
+  0xb0, 0x94, 0x5c, 0x14, 0xeb, 0x53, 0x15, 0x9b, 0xc9, 0x7b, 0x13, 0x13,
+  0xd3, 0x53, 0xb8, 0x42, 0xdd, 0x63, 0xbf, 0xaa, 0xe9, 0xff, 0x21, 0x86,
+  0x21, 0xef, 0xb4, 0x3c, 0x41, 0x38, 0xd8, 0x68, 0x6b, 0xd8, 0x75, 0x48,
+  0x15, 0x57, 0x39, 0x28, 0xf0, 0xe3, 0x1a, 0x5c, 0x02, 0x0f, 0x1d, 0xd6,
+  0x90, 0xd3, 0xd9, 0x78, 0x6d, 0xd4, 0xba, 0x2d, 0x02, 0x03, 0x01, 0x00,
+  0x01, 0xa3, 0x3f, 0x30, 0x3d, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13,
+  0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55,
+  0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xa4, 0x9b, 0x02, 0x27, 0xdf, 0xb1,
+  0xc3, 0x84, 0x43, 0x44, 0x36, 0x3e, 0x5b, 0x7c, 0x43, 0x3b, 0x69, 0x9e,
+  0x35, 0x0b, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
+  0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01,
+  0x01, 0x00, 0x44, 0xb0, 0x0f, 0x9b, 0xc1, 0x93, 0x72, 0x0a, 0xdd, 0x68,
+  0x0a, 0x08, 0x78, 0xf0, 0xee, 0x95, 0x38, 0x31, 0x8c, 0x71, 0x96, 0x5d,
+  0xb3, 0xc2, 0xd6, 0xa3, 0xdb, 0xc3, 0xaa, 0x06, 0xa4, 0xf8, 0xb4, 0xb0,
+  0xd3, 0xb8, 0xcd, 0x3f, 0x22, 0xf0, 0xf1, 0x5c, 0xf5, 0xf8, 0x46, 0xa2,
+  0xf2, 0xd2, 0xd3, 0xa2, 0x2f, 0x30, 0xd8, 0x90, 0x9f, 0x1a, 0xb7, 0x9b,
+  0xc9, 0xf1, 0x72, 0xde, 0xb5, 0xfe, 0x62, 0xb6, 0x73, 0xe8, 0xb9, 0xe4,
+  0x3a, 0x77, 0xb6, 0xd5, 0x9f, 0x22, 0x06, 0x71, 0x31, 0x83, 0x5c, 0xd3,
+  0x06, 0x76, 0x7d, 0x67, 0x0e, 0x8e, 0xa5, 0x69, 0xb1, 0x4e, 0xe4, 0x5f,
+  0x67, 0x74, 0xe4, 0x56, 0xd8, 0x73, 0x35, 0x2e, 0x0d, 0x4f, 0xdd, 0x1a,
+  0xc1, 0x47, 0xb5, 0x16, 0xa1, 0x8c, 0x63, 0x7b, 0x0d, 0x95, 0xe8, 0x84,
+  0xce, 0x7e, 0xd4, 0xc6, 0xae, 0x8c, 0x7d, 0xfe, 0xc4, 0xe8, 0xb7, 0x09,
+  0xd9, 0x2b, 0xaa, 0xbe, 0x90, 0x9c, 0x86, 0xcb, 0xc8, 0xcc, 0x73, 0x3a,
+  0xaa, 0xd7, 0x19, 0x7d, 0x7f, 0xfc, 0x84, 0x5f, 0x31, 0x4e, 0xb7, 0xd0,
+  0xeb, 0x5c, 0xb7, 0x0b, 0x3a, 0x06, 0x0e, 0xeb, 0x80, 0x4d, 0x96, 0x85,
+  0x64, 0xbf, 0xf0, 0xc8, 0x6a, 0x5d, 0x0e, 0xd3, 0x26, 0x76, 0xbe, 0xb5,
+  0x36, 0x25, 0x68, 0x41, 0x10, 0x0a, 0x79, 0x58, 0x0f, 0x7f, 0x44, 0xf4,
+  0xf1, 0x9b, 0xeb, 0x00, 0xac, 0xbf, 0xa6, 0xaa, 0x3d, 0x88, 0x40, 0x70,
+  0x03, 0x7c, 0x5a, 0x45, 0x17, 0x8c, 0xf1, 0xe3, 0xf4, 0x61, 0x77, 0x56,
+  0x5f, 0xfc, 0x7a, 0xc8, 0x35, 0x5a, 0x95, 0xe3, 0x0c, 0xfb, 0x6d, 0x6d,
+  0x6c, 0xcc, 0x86, 0x47, 0x9d, 0xb3, 0xe1, 0xe2, 0x26, 0xcb, 0xb8, 0xa4,
+  0x91, 0xb6, 0x51, 0x4c, 0xf5, 0x37, 0x68, 0x29, 0xc1, 0xef, 0xba, 0xf0,
+  0x8b, 0x82, 0x17, 0x65, 0x81, 0xe9
+};
+unsigned int certa_len = 702;
+
+unsigned char certb[] = {
+  0x30, 0x82, 0x02, 0xad, 0x30, 0x82, 0x01, 0x95, 0xa0, 0x03, 0x02, 0x01,
+  0x02, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x00, 0x30, 0x1e, 0x17,
+  0x0d, 0x31, 0x30, 0x30, 0x38, 0x32, 0x34, 0x32, 0x32, 0x35, 0x35, 0x31,
+  0x37, 0x5a, 0x17, 0x0d, 0x32, 0x30, 0x30, 0x38, 0x32, 0x31, 0x32, 0x32,
+  0x35, 0x35, 0x31, 0x37, 0x5a, 0x30, 0x00, 0x30, 0x82, 0x01, 0x22, 0x30,
+  0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
+  0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02,
+  0x82, 0x01, 0x01, 0x00, 0xd7, 0x67, 0x3f, 0xf1, 0x88, 0xf8, 0x81, 0x9d,
+  0x6b, 0x8a, 0x5e, 0xc7, 0xc7, 0x1f, 0xfc, 0x04, 0x89, 0x81, 0x0a, 0x1a,
+  0x7f, 0x70, 0x63, 0x6f, 0x66, 0x8e, 0x1a, 0x7a, 0xb0, 0xf9, 0xb9, 0x71,
+  0x3d, 0xda, 0xcb, 0xd5, 0x84, 0xa8, 0x67, 0x4e, 0xde, 0x7e, 0x3e, 0xc8,
+  0x15, 0x01, 0xe2, 0x41, 0xb7, 0x82, 0x4a, 0x6e, 0x62, 0x12, 0xa1, 0xe7,
+  0x8b, 0x78, 0x5c, 0x50, 0x13, 0xd1, 0x0a, 0xbc, 0x6c, 0x6b, 0xad, 0xb6,
+  0x3b, 0x65, 0xd6, 0x89, 0x03, 0x76, 0x51, 0x2b, 0xee, 0xa1, 0x8b, 0x54,
+  0x41, 0xbb, 0x03, 0x6a, 0x55, 0xda, 0x06, 0xac, 0xf0, 0xd0, 0xa0, 0x39,
+  0xe5, 0x0e, 0x22, 0xe9, 0x44, 0x28, 0xfb, 0x03, 0xbd, 0x21, 0xc5, 0xb6,
+  0xd3, 0x11, 0x3b, 0x90, 0x78, 0xc3, 0xe7, 0x41, 0x8d, 0x9b, 0xf1, 0xab,
+  0x0f, 0xa3, 0x31, 0x4f, 0x52, 0x59, 0x0f, 0x66, 0x66, 0x86, 0x43, 0x26,
+  0x3f, 0x4e, 0x29, 0x83, 0x7f, 0x60, 0x3d, 0x59, 0x55, 0xad, 0x47, 0x09,
+  0x75, 0x96, 0x50, 0xec, 0xfb, 0x15, 0xbd, 0x15, 0x2a, 0x32, 0x73, 0x23,
+  0xe8, 0x3e, 0xe0, 0x16, 0xc6, 0x46, 0x54, 0x6d, 0xff, 0x84, 0x5a, 0x55,
+  0xe1, 0xea, 0xb3, 0xcc, 0x33, 0xf2, 0xa1, 0x2d, 0x5a, 0x1e, 0x48, 0xc5,
+  0x75, 0xa1, 0x84, 0xc4, 0x81, 0x7d, 0xcf, 0xf9, 0x8d, 0x09, 0xdc, 0xba,
+  0xad, 0xad, 0x52, 0x34, 0xc0, 0xda, 0xec, 0x37, 0x14, 0x24, 0xda, 0xdf,
+  0xd6, 0x3e, 0x98, 0xfc, 0x8e, 0x00, 0xf7, 0x8a, 0x44, 0xe5, 0xe6, 0xe7,
+  0x07, 0x0e, 0x8a, 0x52, 0xff, 0xff, 0xac, 0x9c, 0x3e, 0x31, 0xc7, 0x93,
+  0xe6, 0x71, 0xf3, 0x13, 0x42, 0xe3, 0x99, 0x73, 0x17, 0x5b, 0x79, 0xfa,
+  0xd4, 0xc2, 0xcd, 0x68, 0x59, 0x43, 0x91, 0xb0, 0x87, 0xd0, 0x5f, 0x5c,
+  0x22, 0x1c, 0xbf, 0xc2, 0x12, 0x4c, 0xc2, 0x4b, 0x02, 0x03, 0x01, 0x00,
+  0x01, 0xa3, 0x32, 0x30, 0x30, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13,
+  0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d,
+  0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xae, 0xc3, 0x1e,
+  0x3f, 0x30, 0xe6, 0xe4, 0xf5, 0x68, 0x0d, 0x57, 0xed, 0x55, 0x53, 0xea,
+  0x91, 0xdb, 0x71, 0x24, 0xcf, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01,
+  0x00, 0x28, 0x3d, 0xe2, 0xa1, 0x7e, 0x13, 0x8b, 0xd7, 0xf3, 0xf5, 0xaa,
+  0x5a, 0x2c, 0x06, 0x95, 0x5f, 0x3d, 0x12, 0x2a, 0xf4, 0xbd, 0x80, 0xb2,
+  0x3a, 0x2d, 0x72, 0x85, 0xb6, 0xf6, 0x1f, 0xdc, 0x5e, 0x27, 0xfb, 0xc4,
+  0xb8, 0x48, 0xeb, 0xab, 0x44, 0xec, 0x8b, 0xa9, 0x0b, 0x77, 0xb5, 0x21,
+  0xa0, 0x3c, 0x11, 0xec, 0x9c, 0x68, 0x8b, 0xe8, 0x35, 0x5f, 0xaf, 0xee,
+  0x0a, 0x8d, 0x39, 0x44, 0xa4, 0x75, 0x97, 0x73, 0x49, 0x41, 0xef, 0xe3,
+  0xf7, 0xc7, 0x0d, 0x7f, 0x23, 0x0d, 0xfe, 0x83, 0xf3, 0x7b, 0x21, 0x00,
+  0x5b, 0x2d, 0xbb, 0x76, 0xea, 0x79, 0xce, 0x2c, 0x86, 0x15, 0x08, 0xf7,
+  0x12, 0x48, 0x0e, 0x5e, 0x0c, 0x97, 0xce, 0xbd, 0xc9, 0x0d, 0xa2, 0x73,
+  0xec, 0x81, 0x54, 0x2b, 0x50, 0xab, 0xb6, 0xea, 0xa7, 0xa1, 0x8a, 0xbf,
+  0xee, 0x16, 0xf1, 0x2b, 0x03, 0x97, 0xfb, 0x38, 0x9d, 0xa8, 0xde, 0x73,
+  0xb1, 0x8f, 0xd2, 0x3b, 0x40, 0x86, 0x32, 0xdb, 0xeb, 0x8f, 0x0a, 0xf7,
+  0x1f, 0xac, 0xbc, 0x32, 0x05, 0x8b, 0xa1, 0xc6, 0xdd, 0x39, 0x9c, 0xfa,
+  0x70, 0x91, 0xda, 0x80, 0x60, 0xfa, 0xaa, 0xef, 0x51, 0x65, 0x2c, 0x09,
+  0x21, 0x9b, 0x35, 0xed, 0x99, 0x07, 0xbd, 0x63, 0x84, 0x72, 0xa0, 0xc4,
+  0x11, 0x7e, 0x6e, 0x27, 0xe1, 0xda, 0xd4, 0xac, 0xf1, 0xca, 0xc0, 0xfd,
+  0x77, 0x64, 0x29, 0x3b, 0x49, 0x64, 0x5f, 0xe3, 0x4c, 0x8b, 0x93, 0x98,
+  0x9a, 0x9a, 0xb7, 0xb7, 0x04, 0xfc, 0x7d, 0x82, 0x9b, 0xcc, 0x1d, 0xd2,
+  0x8c, 0x98, 0x3b, 0x9a, 0xca, 0x53, 0x9b, 0x04, 0x6d, 0x3d, 0x41, 0x38,
+  0x8c, 0x2b, 0xea, 0xaa, 0x28, 0xef, 0x27, 0xd3, 0xc7, 0x0e, 0x59, 0xa1,
+  0x30, 0xd9, 0xee, 0x92, 0x5a, 0x34, 0x21, 0x11, 0x54, 0xa4, 0xdd, 0xc0,
+  0x86, 0x07, 0xd9, 0x33, 0xb1
+};
+unsigned int certb_len = 689;
+
+unsigned char certc[] = {
+  0x30, 0x82, 0x02, 0xad, 0x30, 0x82, 0x01, 0x95, 0xa0, 0x03, 0x02, 0x01,
+  0x02, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x00, 0x30, 0x1e, 0x17,
+  0x0d, 0x31, 0x30, 0x30, 0x38, 0x32, 0x37, 0x32, 0x33, 0x30, 0x37, 0x34,
+  0x35, 0x5a, 0x17, 0x0d, 0x32, 0x30, 0x30, 0x38, 0x32, 0x34, 0x32, 0x33,
+  0x30, 0x37, 0x34, 0x35, 0x5a, 0x30, 0x00, 0x30, 0x82, 0x01, 0x22, 0x30,
+  0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
+  0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02,
+  0x82, 0x01, 0x01, 0x00, 0xae, 0x74, 0xef, 0x9f, 0x1f, 0x5d, 0x85, 0x83,
+  0x57, 0xce, 0x65, 0xd5, 0x54, 0x2d, 0x71, 0x4d, 0xea, 0x6c, 0x57, 0x8c,
+  0x4f, 0x3f, 0xfd, 0xcb, 0x22, 0x01, 0xa0, 0x2a, 0xbd, 0x41, 0xd1, 0xf5,
+  0xb2, 0xf5, 0xe7, 0x7b, 0xe3, 0xd1, 0xe1, 0x48, 0xcf, 0xc6, 0xdb, 0x71,
+  0x52, 0xde, 0xd9, 0x1e, 0xb4, 0x29, 0xd4, 0xc8, 0xf2, 0xf9, 0x6e, 0xbb,
+  0xff, 0x69, 0x36, 0x72, 0xa8, 0x8b, 0x54, 0x0d, 0xf7, 0x5c, 0x3d, 0x62,
+  0x10, 0xdc, 0x8d, 0x4a, 0xc3, 0x11, 0x91, 0x9f, 0x24, 0xe1, 0x5e, 0xcf,
+  0x21, 0x82, 0xa9, 0xf9, 0xff, 0xa6, 0xe2, 0x79, 0xc2, 0x0b, 0x93, 0xa2,
+  0x31, 0x62, 0xef, 0x01, 0x4e, 0x77, 0xd2, 0xa6, 0x49, 0xb4, 0x6e, 0x8e,
+  0xbd, 0x63, 0x57, 0x01, 0x51, 0xd6, 0xb3, 0xf0, 0x11, 0xd5, 0xf1, 0xf8,
+  0xcc, 0xd8, 0x4e, 0x9d, 0x04, 0xf7, 0xa3, 0xa1, 0x14, 0x61, 0x6a, 0x21,
+  0x16, 0xe3, 0xa3, 0x6d, 0x92, 0xaf, 0xc6, 0xfd, 0x12, 0x63, 0x54, 0xbf,
+  0x24, 0xc8, 0x11, 0xcc, 0xdb, 0xaf, 0x14, 0xdd, 0x84, 0xd9, 0xdd, 0x5d,
+  0xc4, 0xe6, 0x92, 0xbe, 0x76, 0x3b, 0x91, 0x52, 0xcb, 0x4c, 0x31, 0x8c,
+  0xeb, 0x12, 0xce, 0xde, 0xe0, 0xb4, 0x12, 0x7f, 0xa1, 0x60, 0xd4, 0x9e,
+  0xc5, 0x0b, 0x49, 0xd6, 0xbf, 0x9a, 0x13, 0x99, 0x0e, 0x65, 0x83, 0xff,
+  0xf5, 0xab, 0xe2, 0x76, 0xa3, 0x58, 0x7a, 0xea, 0x0d, 0x0f, 0x76, 0x4c,
+  0xff, 0xf3, 0xc7, 0x6e, 0x48, 0x0a, 0xba, 0x37, 0x87, 0x32, 0x94, 0x44,
+  0xfa, 0x06, 0x70, 0xfd, 0x9a, 0x17, 0x7e, 0x73, 0x92, 0x6e, 0xe6, 0xc9,
+  0x75, 0xbb, 0xd3, 0x16, 0x92, 0xb0, 0xed, 0xfc, 0x80, 0x3d, 0xba, 0x56,
+  0x82, 0xdf, 0xe7, 0xf5, 0xe1, 0xc8, 0xd7, 0x68, 0xf9, 0xc5, 0x8b, 0xf5,
+  0x15, 0x3d, 0xda, 0x77, 0xc1, 0xc8, 0xb8, 0xfb, 0x02, 0x03, 0x01, 0x00,
+  0x01, 0xa3, 0x32, 0x30, 0x30, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13,
+  0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d,
+  0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x6e, 0x04, 0x5d,
+  0xde, 0x1e, 0x58, 0xca, 0x9d, 0xa4, 0x25, 0x50, 0xeb, 0xf9, 0xff, 0x3c,
+  0x31, 0xb7, 0x29, 0x63, 0xa8, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01,
+  0x00, 0x01, 0x6d, 0xbb, 0xa9, 0xf5, 0x59, 0x07, 0xe2, 0xf5, 0x8c, 0x82,
+  0x84, 0x3f, 0x13, 0xe0, 0x2f, 0x03, 0x9b, 0xce, 0x8d, 0x48, 0x80, 0x60,
+  0xda, 0xfc, 0x8e, 0x08, 0xda, 0xff, 0x83, 0x49, 0xd4, 0x10, 0x80, 0xe2,
+  0x57, 0x95, 0x27, 0x92, 0xb5, 0x61, 0x23, 0x4c, 0x23, 0x3a, 0x9a, 0x61,
+  0xd5, 0xdb, 0x60, 0x00, 0x7d, 0x18, 0x96, 0xc2, 0x97, 0xa7, 0x6f, 0x41,
+  0x38, 0xf3, 0xb7, 0x04, 0xeb, 0x86, 0xce, 0xe3, 0x27, 0x2b, 0xf2, 0x6d,
+  0x25, 0xf9, 0xc2, 0x04, 0x8a, 0x58, 0x6e, 0x32, 0x8c, 0x04, 0xe5, 0x2a,
+  0x60, 0x03, 0x5c, 0x78, 0xf8, 0x34, 0xfe, 0x24, 0x67, 0x77, 0xd7, 0x7a,
+  0x96, 0xec, 0x0d, 0x37, 0x74, 0x22, 0xc4, 0xa6, 0x42, 0x83, 0x3a, 0x5b,
+  0xed, 0x11, 0x46, 0xfd, 0x1d, 0xd5, 0x8c, 0x39, 0x3b, 0x24, 0x70, 0x2a,
+  0x4a, 0xdf, 0x54, 0xbd, 0xa5, 0x29, 0x86, 0xa5, 0xe6, 0xcb, 0xde, 0x99,
+  0x8c, 0x7d, 0x80, 0xcc, 0xb1, 0x2f, 0x5e, 0xad, 0x51, 0xfa, 0x74, 0x15,
+  0x17, 0xc3, 0x00, 0xfc, 0xa8, 0x7f, 0x67, 0x44, 0x5f, 0x0e, 0x29, 0x8e,
+  0x74, 0x12, 0xab, 0x2c, 0xc5, 0xee, 0xd2, 0xa3, 0xb6, 0xa8, 0x78, 0xb0,
+  0x04, 0x8e, 0x77, 0x33, 0x91, 0x1d, 0x8e, 0x50, 0x97, 0x61, 0x5c, 0x1f,
+  0x0e, 0xe0, 0x2a, 0xfa, 0x56, 0x1d, 0x5b, 0x36, 0x63, 0xeb, 0x13, 0x70,
+  0xb2, 0x40, 0x1e, 0x78, 0x41, 0x71, 0x7d, 0x81, 0x63, 0xe9, 0xec, 0xe4,
+  0xe6, 0x7b, 0x63, 0x4f, 0x29, 0x75, 0x7a, 0xf7, 0x96, 0x47, 0x7d, 0x5b,
+  0x11, 0xd2, 0x52, 0x17, 0x69, 0x19, 0x53, 0x3f, 0x8f, 0xc2, 0xaa, 0xaf,
+  0x42, 0x35, 0x3b, 0xb2, 0x94, 0x6f, 0xcf, 0xf8, 0xb1, 0xca, 0xe7, 0x47,
+  0xcc, 0xed, 0x6c, 0x97, 0xfd, 0xdd, 0x41, 0x3a, 0x22, 0x69, 0xfc, 0x3c,
+  0xdf, 0x13, 0x32, 0x3c, 0xa4
+};
+unsigned int certc_len = 689;
+
+
+unsigned char _AppleiPhoneDeviceCert_DER[] = {
+  0x30, 0x82, 0x03, 0x3f, 0x30, 0x82, 0x02, 0xa8, 0xa0, 0x03, 0x02, 0x01,
+  0x02, 0x02, 0x0a, 0x01, 0x4c, 0x21, 0x41, 0x26, 0x71, 0x63, 0x81, 0xd8,
+  0xd9, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x01, 0x0b, 0x05, 0x00, 0x30, 0x5a, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+  0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06,
+  0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20,
+  0x49, 0x6e, 0x63, 0x2e, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04,
+  0x0b, 0x13, 0x0c, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x69, 0x50, 0x68,
+  0x6f, 0x6e, 0x65, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03,
+  0x13, 0x16, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x69, 0x50, 0x68, 0x6f,
+  0x6e, 0x65, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x20, 0x43, 0x41,
+  0x30, 0x1e, 0x17, 0x0d, 0x30, 0x38, 0x30, 0x37, 0x32, 0x32, 0x31, 0x38,
+  0x33, 0x32, 0x34, 0x35, 0x5a, 0x17, 0x0d, 0x31, 0x31, 0x30, 0x37, 0x32,
+  0x32, 0x31, 0x38, 0x33, 0x32, 0x34, 0x35, 0x5a, 0x30, 0x81, 0x87, 0x31,
+  0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x28, 0x32, 0x31,
+  0x33, 0x63, 0x65, 0x65, 0x35, 0x63, 0x64, 0x31, 0x31, 0x37, 0x37, 0x38,
+  0x62, 0x65, 0x65, 0x32, 0x63, 0x64, 0x31, 0x63, 0x65, 0x61, 0x36, 0x32,
+  0x34, 0x62, 0x63, 0x63, 0x30, 0x61, 0x62, 0x38, 0x31, 0x33, 0x64, 0x32,
+  0x33, 0x35, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+  0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08,
+  0x13, 0x02, 0x43, 0x41, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
+  0x07, 0x13, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f,
+  0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41,
+  0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x0f, 0x30,
+  0x0d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x06, 0x69, 0x50, 0x68, 0x6f,
+  0x6e, 0x65, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00,
+  0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0x82, 0x8e, 0xda, 0x67, 0x93,
+  0x6d, 0x54, 0x03, 0x98, 0xcc, 0xdb, 0xec, 0x06, 0xed, 0xd7, 0x4e, 0xc7,
+  0x74, 0xc8, 0xb5, 0x91, 0x64, 0xf9, 0x52, 0x23, 0x50, 0xae, 0x4d, 0x15,
+  0x22, 0x8b, 0x05, 0x03, 0x79, 0x76, 0x45, 0xfc, 0x33, 0xcb, 0x2a, 0xf1,
+  0x5c, 0x96, 0x49, 0x96, 0x06, 0x11, 0x06, 0x6e, 0x76, 0xbe, 0x99, 0xdc,
+  0xae, 0xf9, 0x67, 0x3d, 0x03, 0x0c, 0x07, 0x5f, 0x38, 0xe5, 0x98, 0x64,
+  0x65, 0x68, 0xd2, 0x65, 0x59, 0x9a, 0xd6, 0x70, 0x59, 0x80, 0xf2, 0x54,
+  0x91, 0xb9, 0xd9, 0x45, 0x80, 0x6a, 0x29, 0x4f, 0xa7, 0xfb, 0x72, 0x75,
+  0x70, 0x2a, 0xb2, 0xe9, 0x35, 0x7d, 0x63, 0x8f, 0xf7, 0x83, 0xba, 0x4a,
+  0x8e, 0xb8, 0x29, 0x37, 0xde, 0x70, 0x3e, 0xc2, 0x0f, 0xc7, 0x55, 0x36,
+  0xce, 0xc1, 0xd4, 0x2d, 0x11, 0xb7, 0x02, 0x46, 0x7a, 0x30, 0x69, 0xba,
+  0x81, 0x60, 0x5d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xdd, 0x30,
+  0x81, 0xda, 0x30, 0x81, 0x82, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x7b,
+  0x30, 0x79, 0x80, 0x14, 0xb2, 0xfe, 0x21, 0x23, 0x44, 0x86, 0x95, 0x6a,
+  0x79, 0xd5, 0x81, 0x26, 0x8e, 0x73, 0x10, 0xd8, 0xa7, 0x4c, 0x8e, 0x74,
+  0xa1, 0x5e, 0xa4, 0x5c, 0x30, 0x5a, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+  0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06,
+  0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20,
+  0x49, 0x6e, 0x63, 0x2e, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04,
+  0x0b, 0x13, 0x0c, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x69, 0x50, 0x68,
+  0x6f, 0x6e, 0x65, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03,
+  0x13, 0x16, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x69, 0x50, 0x68, 0x6f,
+  0x6e, 0x65, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x20, 0x43, 0x41,
+  0x82, 0x01, 0x01, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16,
+  0x04, 0x14, 0x54, 0x8c, 0xa9, 0x72, 0xce, 0x75, 0x20, 0xf9, 0x99, 0xa0,
+  0xa7, 0x9e, 0xb9, 0x1f, 0x7d, 0x70, 0x67, 0x74, 0xf5, 0x01, 0x30, 0x0c,
+  0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00,
+  0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04,
+  0x03, 0x02, 0x05, 0xa0, 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01,
+  0x01, 0xff, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+  0x05, 0x07, 0x03, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x32,
+  0xc8, 0xf6, 0xa0, 0x75, 0x47, 0x75, 0xaf, 0x5c, 0xac, 0x0d, 0x12, 0xc4,
+  0x73, 0x63, 0x0e, 0x59, 0xee, 0x99, 0x1a, 0xea, 0xe8, 0x8c, 0x12, 0xd9,
+  0x64, 0xf5, 0xe3, 0x45, 0x1e, 0x62, 0x45, 0xb5, 0xc4, 0xfc, 0xf4, 0x37,
+  0x92, 0xfe, 0xb9, 0x8e, 0x06, 0x87, 0xcb, 0xf6, 0x16, 0xb7, 0xca, 0x1a,
+  0x31, 0x24, 0x7e, 0xdf, 0x46, 0xd9, 0xe1, 0x26, 0x82, 0xff, 0xcd, 0xd1,
+  0x10, 0xba, 0xfd, 0x1e, 0x47, 0xc4, 0x3c, 0x76, 0x0d, 0x39, 0x0b, 0x57,
+  0xd9, 0xf1, 0xd5, 0x1d, 0x18, 0xd3, 0x35, 0xae, 0x1d, 0xdf, 0xec, 0xf1,
+  0x2a, 0x9d, 0x61, 0x91, 0x60, 0x43, 0x15, 0x2f, 0x4b, 0x19, 0x24, 0xc9,
+  0xbd, 0xf6, 0xa4, 0x66, 0x48, 0x48, 0x55, 0x67, 0xbf, 0xaa, 0x71, 0xa2,
+  0x92, 0x3d, 0x3c, 0xc7, 0xdc, 0x73, 0x6e, 0x38, 0xe6, 0xae, 0x6b, 0x8e,
+  0xbc, 0xbb, 0xa2, 0x75, 0xf9, 0x7a, 0x77
+};
+
+/*
+    subject= /C=US/O=Apple Inc./OU=Apple iPhone/CN=Apple iPhone Activation
+    issuer= /C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple iPhone Certification Authority
+    serial=02
+*/
+const uint8_t _AppleiPhoneActivation_DER[] = {
+    0x30, 0x82, 0x03, 0x67, 0x30, 0x82, 0x02, 0x4f,
+    0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x02,
+    0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+    0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
+    0x79, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+    0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
+    0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+    0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49,
+    0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06,
+    0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70,
+    0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74,
+    0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+    0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+    0x69, 0x74, 0x79, 0x31, 0x2d, 0x30, 0x2b, 0x06,
+    0x03, 0x55, 0x04, 0x03, 0x13, 0x24, 0x41, 0x70,
+    0x70, 0x6c, 0x65, 0x20, 0x69, 0x50, 0x68, 0x6f,
+    0x6e, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
+    0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+    0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
+    0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x37,
+    0x30, 0x34, 0x31, 0x36, 0x32, 0x32, 0x35, 0x35,
+    0x30, 0x32, 0x5a, 0x17, 0x0d, 0x31, 0x34, 0x30,
+    0x34, 0x31, 0x36, 0x32, 0x32, 0x35, 0x35, 0x30,
+    0x32, 0x5a, 0x30, 0x5b, 0x31, 0x0b, 0x30, 0x09,
+    0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+    0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
+    0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c,
+    0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x15,
+    0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
+    0x0c, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x69,
+    0x50, 0x68, 0x6f, 0x6e, 0x65, 0x31, 0x20, 0x30,
+    0x1e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x17,
+    0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x69, 0x50,
+    0x68, 0x6f, 0x6e, 0x65, 0x20, 0x41, 0x63, 0x74,
+    0x69, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x30,
+    0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+    0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
+    0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89,
+    0x02, 0x81, 0x81, 0x00, 0xc5, 0x01, 0x7c, 0xd1,
+    0x22, 0x60, 0x2b, 0x9a, 0x88, 0x87, 0x7d, 0xb4,
+    0xb6, 0xa0, 0xf7, 0x2a, 0x01, 0xf6, 0xc4, 0xbf,
+    0x47, 0x75, 0x8e, 0x4e, 0xc6, 0x6e, 0x75, 0xfb,
+    0xfb, 0x86, 0x14, 0x97, 0x22, 0x1f, 0xa6, 0xbc,
+    0xc1, 0x55, 0xd9, 0x66, 0xcf, 0x62, 0x47, 0x62,
+    0xfd, 0x7e, 0xd3, 0x82, 0x33, 0x26, 0xd2, 0xfb,
+    0x70, 0xbf, 0x7b, 0x50, 0x8e, 0xdf, 0x93, 0x48,
+    0xb4, 0x38, 0xc6, 0x34, 0x6a, 0x5f, 0x1a, 0xf8,
+    0x93, 0xd0, 0x6b, 0x85, 0x20, 0xeb, 0x5d, 0x53,
+    0x6e, 0xa1, 0x2d, 0xfa, 0x78, 0xc0, 0x98, 0x09,
+    0x20, 0x7b, 0x71, 0xd7, 0x58, 0x30, 0x5d, 0x01,
+    0x70, 0xfd, 0x32, 0x19, 0x02, 0xed, 0x3f, 0xfd,
+    0xa3, 0xbe, 0xf3, 0x39, 0x0d, 0x68, 0x96, 0x2e,
+    0x1c, 0x51, 0xdc, 0xe5, 0x9d, 0x85, 0x9f, 0xce,
+    0x65, 0xb4, 0x3d, 0xdb, 0x8e, 0xc6, 0xeb, 0xde,
+    0x01, 0xe6, 0x18, 0xe3, 0x02, 0x03, 0x01, 0x00,
+    0x01, 0xa3, 0x81, 0x9b, 0x30, 0x81, 0x98, 0x30,
+    0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
+    0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30,
+    0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
+    0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06,
+    0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
+    0xa1, 0xa0, 0xd2, 0xfe, 0xb7, 0xb4, 0x73, 0xfe,
+    0x9b, 0x14, 0x6a, 0xaf, 0xcd, 0x3d, 0x73, 0x4f,
+    0x1f, 0xef, 0xd6, 0x94, 0x30, 0x1f, 0x06, 0x03,
+    0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80,
+    0x14, 0xe7, 0x34, 0x2a, 0x2e, 0x22, 0xde, 0x39,
+    0x60, 0x6b, 0xb4, 0x94, 0xce, 0x77, 0x83, 0x61,
+    0x2f, 0x31, 0xa0, 0x7c, 0x35, 0x30, 0x38, 0x06,
+    0x03, 0x55, 0x1d, 0x1f, 0x04, 0x31, 0x30, 0x2f,
+    0x30, 0x2d, 0xa0, 0x2b, 0xa0, 0x29, 0x86, 0x27,
+    0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
+    0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65,
+    0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x70,
+    0x6c, 0x65, 0x63, 0x61, 0x2f, 0x69, 0x70, 0x68,
+    0x6f, 0x6e, 0x65, 0x2e, 0x63, 0x72, 0x6c, 0x30,
+    0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+    0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82,
+    0x01, 0x01, 0x00, 0x5f, 0x6a, 0x9a, 0xb5, 0x0d,
+    0x74, 0x0f, 0x85, 0x44, 0xe6, 0x06, 0x3f, 0xba,
+    0x56, 0x71, 0x84, 0xc0, 0x2b, 0xea, 0x4b, 0xc8,
+    0xe7, 0xfd, 0xcc, 0xe6, 0x84, 0xed, 0xa7, 0x95,
+    0x23, 0xcf, 0x39, 0x57, 0xc6, 0x3f, 0x04, 0xa1,
+    0xe1, 0x97, 0x00, 0x28, 0xfb, 0x31, 0x24, 0x88,
+    0xe5, 0x37, 0x15, 0xb1, 0x0f, 0x09, 0x2f, 0x55,
+    0xb5, 0x2d, 0x7c, 0x64, 0x17, 0x30, 0x0f, 0xff,
+    0x9d, 0xe5, 0x94, 0x13, 0x30, 0x59, 0x27, 0x85,
+    0xc5, 0x09, 0xc1, 0xd3, 0xea, 0xaa, 0x39, 0xe6,
+    0xf4, 0xba, 0x93, 0x7c, 0x7f, 0xf1, 0xe2, 0x9c,
+    0x3c, 0x38, 0xd1, 0xd1, 0x0f, 0x3c, 0x47, 0x76,
+    0x9f, 0x7a, 0x80, 0xe5, 0x77, 0x03, 0x8f, 0xbc,
+    0x69, 0xb9, 0x28, 0x01, 0x27, 0xdc, 0x62, 0xab,
+    0xc8, 0x47, 0x2a, 0x57, 0x9d, 0xbb, 0xab, 0xdd,
+    0xb4, 0x51, 0x85, 0x3c, 0xc0, 0xb3, 0x85, 0x48,
+    0x2d, 0x2e, 0xa3, 0x4f, 0x21, 0x58, 0xca, 0x66,
+    0x5e, 0x49, 0xec, 0x2d, 0x06, 0xe6, 0xe6, 0x9a,
+    0x28, 0x28, 0xd6, 0x40, 0x90, 0x89, 0x91, 0x9c,
+    0xef, 0xa7, 0x39, 0x7d, 0xe0, 0xc0, 0xc8, 0x76,
+    0xf6, 0x6f, 0x31, 0x2a, 0xb6, 0xfc, 0x77, 0x5a,
+    0x9a, 0xe5, 0x8e, 0xd4, 0xb8, 0xe9, 0x04, 0xf9,
+    0x09, 0x1e, 0x98, 0x7a, 0x58, 0xa7, 0x66, 0x78,
+    0xa8, 0xdf, 0x68, 0xc0, 0xcd, 0x16, 0x13, 0xc6,
+    0xd4, 0xba, 0xaf, 0x72, 0x6c, 0xbd, 0x90, 0xe2,
+    0x27, 0x4e, 0xfe, 0x10, 0x77, 0x26, 0x7c, 0x67,
+    0x69, 0xc7, 0x08, 0x0e, 0xfb, 0xb6, 0xed, 0x5b,
+    0x5a, 0x45, 0x6a, 0xbd, 0x19, 0x8c, 0x5f, 0x7f,
+    0x8d, 0x82, 0x8a, 0x9c, 0xe6, 0x0d, 0xca, 0xf0,
+    0xab, 0xc2, 0xcc, 0xe1, 0x69, 0xf6, 0xd2, 0x63,
+    0x0c, 0xc0, 0x1b, 0x91, 0x09, 0xa1, 0x71, 0x41,
+    0xe1, 0xdf, 0xa9, 0x89, 0x61, 0xd4, 0x0d, 0xc3,
+    0xf1, 0xb5, 0xc7
+};
+
+unsigned char _AppleiPhoneDeviceCA_DER[] = {
+  0x30, 0x82, 0x03, 0x69, 0x30, 0x82, 0x02, 0x51, 0xa0, 0x03, 0x02, 0x01,
+  0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x79, 0x31, 0x0b, 0x30,
+  0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
+  0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70,
+  0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06,
+  0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20,
+  0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+  0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31,
+  0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x24, 0x41, 0x70,
+  0x70, 0x6c, 0x65, 0x20, 0x69, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x20, 0x43,
+  0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+  0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e,
+  0x17, 0x0d, 0x30, 0x37, 0x30, 0x34, 0x31, 0x36, 0x32, 0x32, 0x35, 0x34,
+  0x34, 0x36, 0x5a, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x34, 0x31, 0x36, 0x32,
+  0x32, 0x35, 0x34, 0x34, 0x36, 0x5a, 0x30, 0x5a, 0x31, 0x0b, 0x30, 0x09,
+  0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30,
+  0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c,
+  0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03,
+  0x55, 0x04, 0x0b, 0x13, 0x0c, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x69,
+  0x50, 0x68, 0x6f, 0x6e, 0x65, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55,
+  0x04, 0x03, 0x13, 0x16, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x69, 0x50,
+  0x68, 0x6f, 0x6e, 0x65, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x20,
+  0x43, 0x41, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00,
+  0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xf1, 0x94, 0x4a, 0xc9, 0xea,
+  0xba, 0x5a, 0x18, 0x60, 0xad, 0xcb, 0xa2, 0x4d, 0x4d, 0x4e, 0x54, 0x19,
+  0x69, 0x17, 0x59, 0x07, 0x66, 0xcb, 0x97, 0xe8, 0x66, 0x9a, 0x47, 0x5f,
+  0x46, 0xae, 0x67, 0x7a, 0xb5, 0x4a, 0x73, 0x54, 0xb1, 0xcb, 0x04, 0xf6,
+  0xbd, 0x36, 0xb8, 0x0c, 0x55, 0x38, 0x8a, 0x84, 0x83, 0x31, 0x52, 0x65,
+  0xf9, 0x33, 0xe1, 0x97, 0x77, 0x9c, 0x2b, 0x4c, 0x26, 0xb0, 0x25, 0x3f,
+  0xe9, 0x32, 0xaa, 0x7b, 0x08, 0x74, 0x94, 0xec, 0xc1, 0x4b, 0x38, 0x1d,
+  0x67, 0x4e, 0x08, 0x52, 0x94, 0x5a, 0x8b, 0x59, 0xa3, 0x5c, 0xd7, 0x93,
+  0xf4, 0xa0, 0xfe, 0x55, 0x85, 0xbb, 0x4c, 0x46, 0x97, 0x5e, 0x6e, 0xb2,
+  0x77, 0x45, 0x2f, 0x67, 0x5c, 0xbc, 0x0b, 0x18, 0xbf, 0x59, 0xb9, 0x6c,
+  0x86, 0xf7, 0x2a, 0x75, 0x76, 0xd2, 0x19, 0x71, 0xf4, 0x29, 0x63, 0xb9,
+  0x25, 0x0b, 0xaf, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0x9e, 0x30,
+  0x81, 0x9b, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
+  0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d,
+  0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30,
+  0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xb2, 0xfe,
+  0x21, 0x23, 0x44, 0x86, 0x95, 0x6a, 0x79, 0xd5, 0x81, 0x26, 0x8e, 0x73,
+  0x10, 0xd8, 0xa7, 0x4c, 0x8e, 0x74, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
+  0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xe7, 0x34, 0x2a, 0x2e, 0x22,
+  0xde, 0x39, 0x60, 0x6b, 0xb4, 0x94, 0xce, 0x77, 0x83, 0x61, 0x2f, 0x31,
+  0xa0, 0x7c, 0x35, 0x30, 0x38, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x31,
+  0x30, 0x2f, 0x30, 0x2d, 0xa0, 0x2b, 0xa0, 0x29, 0x86, 0x27, 0x68, 0x74,
+  0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70,
+  0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x70, 0x6c, 0x65,
+  0x63, 0x61, 0x2f, 0x69, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x2e, 0x63, 0x72,
+  0x6c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x77, 0x5d, 0xcf,
+  0x67, 0x7a, 0x4c, 0x56, 0x2b, 0xa4, 0x54, 0x77, 0xbd, 0x59, 0x48, 0x3c,
+  0x1e, 0xe9, 0xbe, 0xd0, 0x8f, 0xf4, 0x90, 0x72, 0xaf, 0x8e, 0x1c, 0x15,
+  0x77, 0xf2, 0x0c, 0xc0, 0x69, 0x57, 0xc9, 0x4e, 0xc3, 0x85, 0x46, 0x16,
+  0x76, 0x36, 0xb6, 0x5f, 0xfc, 0xea, 0x8f, 0xb5, 0xb6, 0xe0, 0x0a, 0xb9,
+  0xed, 0xd1, 0x0a, 0x9b, 0x77, 0xea, 0xab, 0x12, 0xb9, 0x5c, 0x21, 0x55,
+  0x19, 0x8e, 0x47, 0x23, 0x47, 0x11, 0xb1, 0xd1, 0x0d, 0xc9, 0x33, 0xfb,
+  0x97, 0x14, 0xa2, 0x89, 0x34, 0x58, 0x8f, 0x69, 0xa5, 0x3d, 0xe7, 0x61,
+  0x78, 0x29, 0xfe, 0x93, 0xa4, 0xf9, 0xcb, 0x45, 0x38, 0x5e, 0xbe, 0x34,
+  0x15, 0x7c, 0x16, 0x6f, 0x69, 0xd6, 0xa8, 0x21, 0x75, 0x02, 0x02, 0x2e,
+  0x76, 0x18, 0x2f, 0x55, 0xbc, 0x65, 0xbe, 0xa7, 0x31, 0x52, 0x6f, 0x19,
+  0xcf, 0xbc, 0x83, 0x78, 0x9d, 0x09, 0x16, 0x8b, 0xd7, 0x42, 0x1c, 0x8e,
+  0xe5, 0xf2, 0xd4, 0x1d, 0x12, 0xc2, 0x40, 0x5b, 0x2c, 0x01, 0xb7, 0xfc,
+  0x07, 0x88, 0xbc, 0xad, 0x86, 0x2c, 0x05, 0x48, 0x58, 0x4e, 0xca, 0x55,
+  0x25, 0xcc, 0x55, 0xa4, 0x82, 0x25, 0xb6, 0x46, 0x29, 0x74, 0x84, 0x52,
+  0x20, 0x04, 0x40, 0xe3, 0xd1, 0xcd, 0xbc, 0xa2, 0xb8, 0x87, 0x38, 0xf3,
+  0x31, 0x2f, 0xce, 0x84, 0xa4, 0x29, 0x54, 0xac, 0x3e, 0x38, 0x21, 0x19,
+  0xc6, 0x9b, 0x42, 0x55, 0xe3, 0x76, 0xa6, 0x36, 0xdd, 0xb7, 0xdb, 0xb3,
+  0x8b, 0x5e, 0xf9, 0xa1, 0x5a, 0x3f, 0xbb, 0xa0, 0x76, 0x02, 0xb2, 0x80,
+  0x5b, 0x5e, 0xee, 0xe9, 0x71, 0x07, 0x21, 0xd0, 0xcc, 0x39, 0xee, 0xdc,
+  0x6f, 0x7d, 0xe9, 0x79, 0x52, 0x3a, 0x4c, 0x3d, 0x79, 0x5b, 0x83, 0x08,
+  0xa7, 0x24, 0x0f, 0x6e, 0x9f, 0x28, 0xae, 0x55, 0xde, 0xfa, 0xd0, 0x3c,
+  0x24
+};
+
+/*
+    subject= /C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple iPhone Certification Authority
+    issuer= /C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Root CA
+    serial=17
+*/
+const uint8_t _AppleiPhoneCertificationAuthority_DER[] = {
+    0x30, 0x82, 0x03, 0xf3, 0x30, 0x82, 0x02, 0xdb,
+    0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x17,
+    0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+    0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
+    0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+    0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
+    0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+    0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49,
+    0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06,
+    0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70,
+    0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74,
+    0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+    0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+    0x69, 0x74, 0x79, 0x31, 0x16, 0x30, 0x14, 0x06,
+    0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x41, 0x70,
+    0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74,
+    0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x30,
+    0x37, 0x30, 0x34, 0x31, 0x32, 0x31, 0x37, 0x34,
+    0x33, 0x32, 0x38, 0x5a, 0x17, 0x0d, 0x32, 0x32,
+    0x30, 0x34, 0x31, 0x32, 0x31, 0x37, 0x34, 0x33,
+    0x32, 0x38, 0x5a, 0x30, 0x79, 0x31, 0x0b, 0x30,
+    0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+    0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
+    0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70,
+    0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
+    0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b,
+    0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20,
+    0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+    0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
+    0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31,
+    0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04, 0x03,
+    0x13, 0x24, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20,
+    0x69, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x20, 0x43,
+    0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
+    0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
+    0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x82,
+    0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+    0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
+    0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82,
+    0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa3,
+    0x1e, 0xbe, 0xf0, 0x47, 0xc0, 0xb4, 0x9e, 0x10,
+    0x5b, 0x46, 0xa4, 0xb8, 0x21, 0xb8, 0x4f, 0x86,
+    0x21, 0x70, 0x28, 0x45, 0x60, 0x5c, 0x1c, 0xc3,
+    0xc8, 0x0a, 0x64, 0x63, 0x88, 0xfb, 0xfc, 0x69,
+    0xee, 0xf8, 0x54, 0xfc, 0xe9, 0x5b, 0xb7, 0x06,
+    0x4e, 0x04, 0x2f, 0xc3, 0x6b, 0x33, 0xaf, 0x44,
+    0x4c, 0xea, 0x4b, 0x80, 0x09, 0xb4, 0x87, 0xf6,
+    0x5b, 0xb4, 0xfd, 0x64, 0xdd, 0xb3, 0x72, 0xe0,
+    0x13, 0xb3, 0xfd, 0x17, 0xd9, 0xbc, 0xe7, 0xa8,
+    0xed, 0xc2, 0x8c, 0x61, 0xc2, 0x2a, 0xf9, 0xec,
+    0xce, 0xa5, 0x5e, 0xd6, 0x69, 0xeb, 0x64, 0x0b,
+    0x8d, 0x08, 0x8f, 0xb8, 0xa0, 0x50, 0x46, 0x09,
+    0xdc, 0x19, 0xe4, 0xe5, 0xb0, 0x94, 0x6d, 0xbb,
+    0xf7, 0x99, 0x98, 0xc4, 0xe8, 0x9b, 0x41, 0x4e,
+    0xd4, 0xf1, 0x65, 0xe3, 0x1b, 0x52, 0x7a, 0xdc,
+    0xe8, 0x03, 0xd9, 0x6e, 0x1d, 0xda, 0x10, 0x55,
+    0x86, 0xa4, 0x29, 0x58, 0x49, 0x0c, 0xea, 0x47,
+    0xd7, 0x15, 0x34, 0x33, 0xf6, 0xc0, 0xa0, 0x44,
+    0x4a, 0x70, 0xbe, 0x2c, 0xb5, 0x2a, 0x30, 0x37,
+    0x8c, 0x2e, 0x15, 0xeb, 0xd1, 0xe4, 0x6c, 0x97,
+    0x38, 0x55, 0x56, 0xb1, 0x35, 0x2b, 0x58, 0xea,
+    0x44, 0xa3, 0x26, 0x85, 0xee, 0xc8, 0x66, 0x4a,
+    0xe4, 0xcf, 0x89, 0xf0, 0x3d, 0x63, 0xad, 0x29,
+    0xde, 0xad, 0xba, 0x5a, 0xb3, 0xdc, 0xa5, 0xa3,
+    0x9a, 0xa7, 0x09, 0x4e, 0x80, 0x16, 0x35, 0x65,
+    0xa4, 0x85, 0x0d, 0x63, 0x7b, 0x3e, 0x63, 0x8a,
+    0xda, 0x7d, 0x4a, 0x46, 0xec, 0xa3, 0x39, 0x18,
+    0x34, 0xb9, 0xc6, 0x28, 0x65, 0x18, 0xbc, 0x13,
+    0x60, 0x9c, 0x7f, 0x57, 0xac, 0x14, 0xc9, 0x89,
+    0xed, 0xa1, 0xb6, 0x87, 0x68, 0x52, 0xb6, 0x84,
+    0x4e, 0xb8, 0xc8, 0x83, 0xec, 0xf9, 0x9e, 0x19,
+    0xab, 0xb3, 0xc1, 0x0b, 0x86, 0xc7, 0x9f, 0x02,
+    0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0x9c, 0x30,
+    0x81, 0x99, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
+    0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02,
+    0x01, 0x86, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d,
+    0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03,
+    0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55,
+    0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xe7, 0x34,
+    0x2a, 0x2e, 0x22, 0xde, 0x39, 0x60, 0x6b, 0xb4,
+    0x94, 0xce, 0x77, 0x83, 0x61, 0x2f, 0x31, 0xa0,
+    0x7c, 0x35, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
+    0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x2b,
+    0xd0, 0x69, 0x47, 0x94, 0x76, 0x09, 0xfe, 0xf4,
+    0x6b, 0x8d, 0x2e, 0x40, 0xa6, 0xf7, 0x47, 0x4d,
+    0x7f, 0x08, 0x5e, 0x30, 0x36, 0x06, 0x03, 0x55,
+    0x1d, 0x1f, 0x04, 0x2f, 0x30, 0x2d, 0x30, 0x2b,
+    0xa0, 0x29, 0xa0, 0x27, 0x86, 0x25, 0x68, 0x74,
+    0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77,
+    0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63,
+    0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x70, 0x6c, 0x65,
+    0x63, 0x61, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x2e,
+    0x63, 0x72, 0x6c, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+    0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
+    0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x1d,
+    0xd1, 0xd5, 0x7b, 0xdd, 0x74, 0x4e, 0xd7, 0x17,
+    0xfc, 0x82, 0x2d, 0x0c, 0x99, 0x9b, 0x5e, 0x42,
+    0x72, 0xf2, 0x69, 0xdc, 0xd5, 0x6b, 0x5e, 0x0d,
+    0x0c, 0x6b, 0x4b, 0x3e, 0x7b, 0x14, 0x25, 0xde,
+    0xb3, 0x94, 0xe8, 0xa0, 0xfa, 0x0f, 0x80, 0x89,
+    0xf2, 0x17, 0x3d, 0x00, 0x02, 0xa2, 0x91, 0x91,
+    0xbe, 0x74, 0x57, 0xdc, 0xaf, 0x9a, 0x9f, 0xa1,
+    0x0a, 0x7d, 0x30, 0xbe, 0x00, 0x2a, 0xcc, 0x21,
+    0x59, 0xeb, 0xfd, 0x49, 0xac, 0x6e, 0x75, 0x19,
+    0xe8, 0x9a, 0x7a, 0x03, 0xd1, 0x86, 0xf6, 0xe7,
+    0xf6, 0xb0, 0x0e, 0x4b, 0x49, 0xfa, 0xa3, 0xb7,
+    0x41, 0xba, 0xd7, 0xd1, 0xe3, 0x56, 0xa1, 0x7d,
+    0x83, 0xab, 0x97, 0xae, 0xf8, 0x51, 0x4a, 0x26,
+    0xc1, 0x85, 0x42, 0x13, 0x26, 0x8d, 0x03, 0x54,
+    0x66, 0x10, 0x5e, 0x60, 0x84, 0x05, 0x12, 0x31,
+    0x2b, 0x6b, 0x54, 0xc0, 0xa0, 0xc8, 0x41, 0xbc,
+    0x54, 0x1e, 0xe7, 0x54, 0xad, 0x13, 0x00, 0xd2,
+    0x4a, 0xc7, 0xbb, 0xc1, 0x8a, 0xaf, 0x81, 0x08,
+    0x8e, 0xf0, 0x46, 0x0a, 0xbf, 0x27, 0xa6, 0xbe,
+    0xdc, 0xcf, 0x39, 0x3a, 0x80, 0x70, 0x19, 0x23,
+    0x32, 0xa3, 0x6b, 0x66, 0x5d, 0x9e, 0x4d, 0xa8,
+    0x47, 0x49, 0xb2, 0x7b, 0x45, 0xb5, 0x51, 0x33,
+    0xa7, 0x74, 0x67, 0x09, 0x4e, 0xb6, 0x6c, 0x6f,
+    0x48, 0xf7, 0x2c, 0xb9, 0x33, 0x05, 0x44, 0x6b,
+    0x45, 0xbe, 0x74, 0x4b, 0x6f, 0xb2, 0x86, 0x91,
+    0xb4, 0x3e, 0x25, 0x28, 0x25, 0x9e, 0xb3, 0xc2,
+    0x51, 0x86, 0xfc, 0x4f, 0xe5, 0xaf, 0x3b, 0xaa,
+    0xbb, 0x44, 0x2c, 0x01, 0x49, 0xe2, 0x74, 0xb3,
+    0x34, 0xfa, 0x44, 0xef, 0x14, 0xc2, 0x11, 0xf2,
+    0x2d, 0x19, 0x1a, 0x51, 0x89, 0xd3, 0x08, 0x4a,
+    0x41, 0x6c, 0x58, 0x56, 0xde, 0x9b, 0x3a, 0xe1,
+    0x05, 0x57, 0xe5, 0x62, 0xcf, 0xd2, 0x0f
+};
+
+static const unsigned char _AppleFactoryDeviceCA_DER[] = {
+  0x30, 0x82, 0x03, 0x78, 0x30, 0x82, 0x02, 0x60, 0xa0, 0x03, 0x02, 0x01,
+  0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, 0x80, 0x31, 0x0b,
+  0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
+  0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70,
+  0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24,
+  0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65,
+  0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
+  0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
+  0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55, 0x04, 0x03, 0x14, 0x2b, 0x5b,
+  0x54, 0x45, 0x53, 0x54, 0x5d, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20,
+  0x69, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
+  0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
+  0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x37,
+  0x30, 0x33, 0x32, 0x31, 0x30, 0x36, 0x32, 0x30, 0x35, 0x30, 0x5a, 0x17,
+  0x0d, 0x32, 0x32, 0x30, 0x33, 0x31, 0x32, 0x30, 0x36, 0x32, 0x30, 0x35,
+  0x30, 0x5a, 0x30, 0x61, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
+  0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
+  0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e,
+  0x63, 0x2e, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
+  0x0c, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x69, 0x50, 0x68, 0x6f, 0x6e,
+  0x65, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x03, 0x14, 0x1d,
+  0x5b, 0x54, 0x45, 0x53, 0x54, 0x5d, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x65,
+  0x20, 0x69, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x20, 0x44, 0x65, 0x76, 0x69,
+  0x63, 0x65, 0x20, 0x43, 0x41, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
+  0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xd7, 0x60,
+  0x52, 0x2a, 0xfa, 0x93, 0x52, 0xdc, 0xdb, 0xae, 0x92, 0x6b, 0xd6, 0xac,
+  0x59, 0x17, 0x1f, 0x9a, 0x20, 0xed, 0x34, 0xae, 0xc2, 0x15, 0xe8, 0xe3,
+  0xf0, 0x3b, 0x63, 0x84, 0xd8, 0x6d, 0x8d, 0x02, 0x65, 0x74, 0xe6, 0x62,
+  0x18, 0x27, 0xd1, 0xfc, 0x78, 0xc3, 0x2f, 0x36, 0x83, 0x39, 0x91, 0x9f,
+  0x3d, 0x32, 0xe0, 0x95, 0x7f, 0x90, 0x3b, 0xab, 0x47, 0xbe, 0xf1, 0x47,
+  0x85, 0x8c, 0x5d, 0xab, 0x1c, 0x5c, 0xbb, 0x10, 0x69, 0x47, 0x56, 0xb8,
+  0x15, 0xbf, 0x34, 0x4a, 0xf0, 0x49, 0x6e, 0x8a, 0x35, 0x4a, 0x4f, 0x47,
+  0xbb, 0x3e, 0xea, 0xcc, 0xdf, 0x2e, 0xf4, 0xb8, 0x96, 0x16, 0x94, 0xdd,
+  0x38, 0xf6, 0xf0, 0x82, 0xcf, 0x26, 0xfd, 0x67, 0xa1, 0x73, 0x01, 0x43,
+  0xd8, 0x25, 0xbd, 0x02, 0x2c, 0x82, 0x89, 0x7c, 0x70, 0x01, 0x68, 0xc2,
+  0x8a, 0x85, 0x60, 0x84, 0x77, 0x83, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
+  0x81, 0x9e, 0x30, 0x81, 0x9b, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f,
+  0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x0f, 0x06,
+  0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01,
+  0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
+  0x14, 0x38, 0x05, 0x20, 0xa9, 0x3f, 0xc6, 0x79, 0xf4, 0xec, 0x9a, 0x6f,
+  0x7f, 0x47, 0x02, 0x5e, 0x6e, 0xa4, 0x79, 0x11, 0xf5, 0x30, 0x1f, 0x06,
+  0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x45, 0xa2,
+  0x4c, 0xa9, 0x8a, 0x5b, 0x4a, 0x27, 0x5e, 0x85, 0xa6, 0x4d, 0x05, 0x1c,
+  0x27, 0x44, 0xa5, 0x87, 0x76, 0x17, 0x30, 0x38, 0x06, 0x03, 0x55, 0x1d,
+  0x1f, 0x04, 0x31, 0x30, 0x2f, 0x30, 0x2d, 0xa0, 0x2b, 0xa0, 0x29, 0x86,
+  0x27, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e,
+  0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70,
+  0x70, 0x6c, 0x65, 0x63, 0x61, 0x2f, 0x69, 0x70, 0x68, 0x6f, 0x6e, 0x65,
+  0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00,
+  0x8d, 0xbe, 0x6b, 0xc8, 0x4e, 0x80, 0x9e, 0x78, 0x86, 0x0c, 0x09, 0xd0,
+  0x6e, 0xed, 0xc1, 0xdc, 0x30, 0xf7, 0x29, 0x4b, 0x20, 0x4e, 0x2c, 0x6c,
+  0xb3, 0x24, 0x72, 0xfd, 0xce, 0x24, 0x34, 0x60, 0x95, 0x30, 0xd7, 0x32,
+  0x61, 0x31, 0xe5, 0xd4, 0xd5, 0x63, 0xaa, 0x3f, 0x89, 0x81, 0xf6, 0x44,
+  0xab, 0x71, 0xd0, 0xbc, 0x17, 0xdb, 0xab, 0xbc, 0xec, 0xbb, 0xa4, 0x40,
+  0x6a, 0xe7, 0xe4, 0x57, 0xc6, 0x28, 0x6f, 0x11, 0x72, 0xfc, 0x0c, 0x51,
+  0x07, 0x31, 0xdb, 0x40, 0x54, 0xee, 0xb5, 0xe6, 0x1e, 0xe3, 0xdc, 0x9b,
+  0xf9, 0x3c, 0x6a, 0xba, 0xd8, 0xc3, 0x20, 0xf1, 0xdd, 0x49, 0xcb, 0x3a,
+  0xa6, 0x29, 0xcd, 0x52, 0xf9, 0xf3, 0xf3, 0x18, 0x5e, 0xdd, 0x82, 0x83,
+  0xb8, 0xe8, 0x4e, 0x94, 0x10, 0x7a, 0x1e, 0x11, 0xa0, 0x63, 0x4d, 0x8e,
+  0x60, 0x4a, 0x1d, 0x45, 0x72, 0x4d, 0xa0, 0xac, 0x1f, 0xb0, 0x98, 0x8b,
+  0xb4, 0x33, 0x5a, 0x85, 0x60, 0xcf, 0x7f, 0x89, 0x35, 0x62, 0x65, 0xd1,
+  0x1b, 0x48, 0xa4, 0xec, 0xca, 0x60, 0x1a, 0x9d, 0xa6, 0xd1, 0xb9, 0x3d,
+  0xf3, 0x64, 0xa4, 0x67, 0xd1, 0xa5, 0x1b, 0xb6, 0xd9, 0xe7, 0x65, 0x75,
+  0xcb, 0xaf, 0x2f, 0x7a, 0xdb, 0xd8, 0xa1, 0xf4, 0xf3, 0x09, 0xbf, 0x9a,
+  0x99, 0x1a, 0x34, 0xa6, 0xed, 0x1f, 0x82, 0x84, 0x0b, 0xb6, 0xa8, 0x68,
+  0x5d, 0xec, 0x49, 0xd4, 0xb3, 0x34, 0x84, 0xaf, 0xcb, 0xa4, 0xd9, 0x00,
+  0xf0, 0xbc, 0x07, 0x6c, 0x17, 0xe7, 0x95, 0xbb, 0xc3, 0x3d, 0xd9, 0xbb,
+  0x6a, 0x13, 0x1d, 0x34, 0xbd, 0x2f, 0xc1, 0x9a, 0xf1, 0x4d, 0x67, 0x5f,
+  0x56, 0x33, 0x90, 0xb2, 0xef, 0xff, 0x27, 0xda, 0x19, 0x60, 0x55, 0xb0,
+  0x78, 0xc2, 0x8c, 0x34, 0x5b, 0x61, 0x3a, 0xe1, 0xec, 0x61, 0x92, 0x8b,
+  0x2f, 0x04, 0x9a, 0xc6
+};
+
+unsigned char _AppleFactoryDeviceCert_DER[] = {
+  0x30, 0x82, 0x03, 0x7c, 0x30, 0x82, 0x02, 0xe5, 0xa0, 0x03, 0x02, 0x01,
+  0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x61, 0x31, 0x0b, 0x30,
+  0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
+  0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70,
+  0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x15, 0x30, 0x13, 0x06,
+  0x03, 0x55, 0x04, 0x0b, 0x13, 0x0c, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20,
+  0x69, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03,
+  0x55, 0x04, 0x03, 0x14, 0x1d, 0x5b, 0x54, 0x45, 0x53, 0x54, 0x5d, 0x20,
+  0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x69, 0x50, 0x68, 0x6f, 0x6e, 0x65,
+  0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x20, 0x43, 0x41, 0x30, 0x1e,
+  0x17, 0x0d, 0x30, 0x39, 0x30, 0x31, 0x32, 0x30, 0x30, 0x36, 0x32, 0x36,
+  0x34, 0x33, 0x5a, 0x17, 0x0d, 0x31, 0x39, 0x30, 0x31, 0x31, 0x38, 0x30,
+  0x36, 0x32, 0x36, 0x34, 0x33, 0x5a, 0x30, 0x81, 0x87, 0x31, 0x31, 0x30,
+  0x2f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x28, 0x63, 0x61, 0x62, 0x32,
+  0x38, 0x64, 0x35, 0x36, 0x37, 0x31, 0x38, 0x64, 0x39, 0x35, 0x32, 0x34,
+  0x66, 0x38, 0x31, 0x64, 0x63, 0x63, 0x31, 0x30, 0x35, 0x35, 0x38, 0x65,
+  0x35, 0x34, 0x65, 0x33, 0x32, 0x35, 0x31, 0x36, 0x39, 0x63, 0x66, 0x65,
+  0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+  0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02,
+  0x43, 0x41, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13,
+  0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x13,
+  0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70,
+  0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x0f, 0x30, 0x0d, 0x06,
+  0x03, 0x55, 0x04, 0x0b, 0x13, 0x06, 0x69, 0x50, 0x68, 0x6f, 0x6e, 0x65,
+  0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81,
+  0x89, 0x02, 0x81, 0x81, 0x00, 0xaf, 0xe4, 0x3c, 0xd3, 0x42, 0xb5, 0x82,
+  0x6f, 0x13, 0x13, 0x51, 0x67, 0xd1, 0x37, 0xec, 0xc6, 0xb9, 0xab, 0xff,
+  0xde, 0x9a, 0xcc, 0x6b, 0x16, 0xc3, 0x41, 0x78, 0x77, 0x20, 0x07, 0x46,
+  0xc9, 0x50, 0xab, 0x4d, 0xf4, 0xd9, 0x0e, 0x52, 0x0a, 0x86, 0x20, 0x28,
+  0x19, 0xaf, 0xe0, 0x96, 0xaa, 0x4e, 0x24, 0xac, 0xad, 0xf9, 0x6b, 0x61,
+  0x99, 0xda, 0x09, 0x3e, 0x7a, 0x4a, 0xe1, 0x5d, 0xa5, 0xb7, 0x12, 0xc7,
+  0xf7, 0x9b, 0xf8, 0xdb, 0x3a, 0x28, 0x33, 0x07, 0x2c, 0xf0, 0xf7, 0x41,
+  0xd1, 0x0f, 0xb0, 0x97, 0x01, 0xf1, 0xb3, 0x75, 0xc1, 0x4f, 0x48, 0x42,
+  0x52, 0x41, 0x42, 0x99, 0x89, 0x39, 0x59, 0x96, 0xec, 0x2d, 0x72, 0xf0,
+  0x32, 0x75, 0xc9, 0x00, 0xcd, 0xad, 0xf0, 0x2f, 0xbe, 0x6a, 0x07, 0xac,
+  0xbc, 0x04, 0x54, 0x15, 0xe0, 0x6e, 0xcb, 0x11, 0x86, 0x77, 0xaf, 0xf2,
+  0x07, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x1b, 0x30, 0x82,
+  0x01, 0x17, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30,
+  0x00, 0x30, 0x2e, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42,
+  0x01, 0x0d, 0x04, 0x21, 0x16, 0x1f, 0x22, 0x4f, 0x70, 0x65, 0x6e, 0x53,
+  0x53, 0x4c, 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64,
+  0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65,
+  0x22, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
+  0x34, 0xe0, 0x45, 0x63, 0xa4, 0x4a, 0x7d, 0x07, 0xf2, 0x1e, 0xc1, 0x55,
+  0xf3, 0x33, 0x21, 0xa5, 0xa9, 0x71, 0x92, 0x06, 0x30, 0x81, 0xad, 0x06,
+  0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0xa5, 0x30, 0x81, 0xa2, 0x80, 0x14,
+  0x38, 0x05, 0x20, 0xa9, 0x3f, 0xc6, 0x79, 0xf4, 0xec, 0x9a, 0x6f, 0x7f,
+  0x47, 0x02, 0x5e, 0x6e, 0xa4, 0x79, 0x11, 0xf5, 0xa1, 0x81, 0x86, 0xa4,
+  0x81, 0x83, 0x30, 0x81, 0x80, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+  0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
+  0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49,
+  0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b,
+  0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74,
+  0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
+  0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x34, 0x30, 0x32, 0x06,
+  0x03, 0x55, 0x04, 0x03, 0x14, 0x2b, 0x5b, 0x54, 0x45, 0x53, 0x54, 0x5d,
+  0x20, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x69, 0x50, 0x68, 0x6f, 0x6e,
+  0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+  0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
+  0x79, 0x82, 0x01, 0x01, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04,
+  0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00,
+  0x02, 0xc0, 0x6e, 0x4c, 0x4c, 0xeb, 0x7b, 0x02, 0xc3, 0x09, 0x05, 0x51,
+  0x29, 0xc1, 0x72, 0x3f, 0x7e, 0x39, 0x3f, 0xfd, 0x1f, 0xe0, 0x09, 0x9d,
+  0xff, 0xb6, 0xff, 0xda, 0xfd, 0xbc, 0xc9, 0xbd, 0xb2, 0x8d, 0x59, 0xf9,
+  0x89, 0x6a, 0x09, 0x96, 0x50, 0xdd, 0xf6, 0x16, 0xf6, 0x23, 0x84, 0x0b,
+  0xef, 0x0d, 0xf5, 0x16, 0x59, 0x8f, 0x7b, 0xd9, 0xbe, 0x1d, 0x94, 0xab,
+  0x07, 0x3c, 0x8c, 0x1e, 0x1b, 0x55, 0xa3, 0xab, 0xe7, 0x20, 0x97, 0x67,
+  0x1b, 0xb6, 0xad, 0x11, 0xe9, 0x8c, 0xd5, 0x80, 0xba, 0x3b, 0xad, 0xf8,
+  0x4e, 0x15, 0xce, 0x47, 0x4d, 0x2a, 0x67, 0x74, 0x4f, 0xe3, 0x3c, 0x95,
+  0x46, 0xed, 0x90, 0x33, 0x25, 0x01, 0x53, 0x74, 0x41, 0x29, 0xa5, 0x51,
+  0xee, 0x7a, 0x8c, 0x2e, 0x09, 0x0f, 0x2f, 0x25, 0x35, 0x81, 0x8a, 0x2e,
+  0xc3, 0x4b, 0xce, 0x79, 0xe1, 0xf8, 0x31, 0xeb
+};
+
+
+/* Test basic add delete update copy matching stuff. */
+static void tests(void)
+{
+    SecTrustRef trust;
+       SecCertificateRef _device_cert, _device_ca, _device_activation,
+        _iphone_cert_authority, _factory_device_ca, _factory_device_cert;
+       isnt(_device_activation = SecCertificateCreateWithBytes(NULL,
+        _AppleiPhoneActivation_DER, sizeof(_AppleiPhoneActivation_DER)),
+               NULL, "create iphone activation cert");
+       isnt(_iphone_cert_authority = SecCertificateCreateWithBytes(NULL,
+        _AppleiPhoneCertificationAuthority_DER,
+        sizeof(_AppleiPhoneCertificationAuthority_DER)),
+               NULL, "create iphone cert authority");
+       isnt(_device_ca = SecCertificateCreateWithBytes(NULL,
+        _AppleiPhoneDeviceCA_DER,
+        sizeof(_AppleiPhoneDeviceCA_DER)),
+               NULL, "create iphone device CA");
+       isnt(_device_cert = SecCertificateCreateWithBytes(NULL,
+        _AppleiPhoneDeviceCert_DER,
+        sizeof(_AppleiPhoneDeviceCert_DER)),
+               NULL, "create iphone device certificate");
+    isnt(_factory_device_ca = SecCertificateCreateWithBytes(NULL,
+        _AppleFactoryDeviceCA_DER,
+        sizeof(_AppleFactoryDeviceCA_DER)),
+               NULL, "create factory device authority");
+    isnt(_factory_device_cert = SecCertificateCreateWithBytes(NULL,
+        _AppleFactoryDeviceCert_DER,
+        sizeof(_AppleFactoryDeviceCert_DER)),
+               NULL, "create factory device certificate");
+
+       const void *v_certs[] = {
+               _device_activation,
+               _iphone_cert_authority
+       };
+    SecPolicyRef policy = SecPolicyCreateiPhoneActivation();
+    CFArrayRef certs = CFArrayCreate(NULL, v_certs,
+               array_size(v_certs), NULL);
+    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust");
+
+       SecTrustResultType trustResult;
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultUnspecified,
+               "trust is kSecTrustResultUnspecified");
+
+       is(SecTrustGetCertificateCount(trust), 3, "cert count is 3");
+
+    CFArrayRef anchors = CFArrayCreate(NULL, (const void **)&_iphone_cert_authority,
+        1, &kCFTypeArrayCallBacks);
+    ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set anchors");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultRecoverableTrustFailure,
+        "trust is kSecTrustResultRecoverableTrustFailure");
+       is(SecTrustGetCertificateCount(trust), 2, "cert count is 2");
+
+       CFReleaseSafe(anchors);
+       CFReleaseSafe(trust);
+       CFReleaseSafe(policy);
+       CFReleaseSafe(certs);
+       CFReleaseSafe(_device_activation);
+
+    /* SHA256 signature test */
+    policy = SecPolicyCreateiPhoneDeviceCertificate();
+       const void *v_dev_certs[] = {
+               _device_cert,
+               _device_ca,
+               _iphone_cert_authority
+       };
+    certs = CFArrayCreate(NULL, v_dev_certs,
+               array_size(v_dev_certs), NULL);
+
+    /* leaf is valid from 238444365-333052365 */
+    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust");
+    CFDateRef date = CFDateCreate(NULL, 220752000.0); /* 1 Jan 2008 */
+    ok_status(SecTrustSetVerifyDate(trust, date), "set date");
+    CFRelease(date);
+
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultUnspecified, "trusted");
+
+    CFReleaseSafe(trust);
+    CFReleaseSafe(policy);
+    CFReleaseSafe(certs);
+
+    certs = CFArrayCreate(NULL, (const void **)&_factory_device_cert, 1, NULL);
+    anchors = CFArrayCreate(NULL, (const void **)&_factory_device_ca, 1, NULL);
+    policy = SecPolicyCreateFactoryDeviceCertificate();
+    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust");
+    /* pick date outside of validity range: 254125603-569485603 */
+    date = CFDateCreate(NULL, 220752000.0); /* 1 Jan 2008 */
+    ok_status(SecTrustSetVerifyDate(trust, date), "set date");
+    CFRelease(date);
+    ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set anchor");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultUnspecified, "trusted");
+    is(2, SecTrustGetCertificateCount(trust), "cert count is 2");
+
+    CFReleaseSafe(trust);
+    CFReleaseSafe(policy);
+    CFReleaseSafe(certs);
+    CFReleaseSafe(anchors);
+
+       CFReleaseSafe(_iphone_cert_authority);
+    CFReleaseSafe(_device_ca);
+    CFReleaseSafe(_device_cert);
+    CFReleaseSafe(_factory_device_ca);
+    CFReleaseSafe(_factory_device_cert);
+
+    SecCertificateRef _pairing_host_cert, _pairing_root_cert, _wrong_pairing_root_cert;
+    isnt(_pairing_host_cert = SecCertificateCreateWithBytes(NULL,
+        certa, certa_len),
+        NULL, "create iphone activation cert");
+    isnt(_pairing_root_cert = SecCertificateCreateWithBytes(NULL,
+        certb, certb_len),
+        NULL, "create iphone cert authority");
+    isnt(_wrong_pairing_root_cert = SecCertificateCreateWithBytes(NULL,
+        certc, certc_len),
+        NULL, "create iphone cert authority");
+
+    const void *pairing_certs_chain[] = {
+        _pairing_host_cert,
+        _pairing_root_cert
+    };
+    policy = SecPolicyCreateLockdownPairing();
+    certs = CFArrayCreate(NULL, pairing_certs_chain,
+        array_size(pairing_certs_chain), NULL);
+    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust");
+
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultRecoverableTrustFailure,
+        "trust is kSecTrustResultRecoverableTrustFailure");
+
+    is(SecTrustGetCertificateCount(trust), 2, "cert count is 2");
+
+    anchors = CFArrayCreate(NULL, (const void **)&_pairing_root_cert,
+        1, &kCFTypeArrayCallBacks);
+    ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set anchors");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultUnspecified,
+        "trust is kSecTrustResultUnspecified");
+    is(SecTrustGetCertificateCount(trust), 2, "cert count is 2");
+    CFReleaseSafe(trust);
+    CFReleaseSafe(certs);
+
+    ok_status(SecTrustCreateWithCertificates(anchors, policy, &trust), "create trust");
+    ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set anchors");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultUnspecified,
+        "trust is kSecTrustResultUnspecified");
+    CFReleaseSafe(trust);
+
+    certs = CFArrayCreate(NULL, (const void **)&_wrong_pairing_root_cert,
+        1, NULL);
+    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust");
+    ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set anchors");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultRecoverableTrustFailure,
+        "trust is kSecTrustResultRecoverableTrustFailure");
+
+    CFReleaseSafe(policy);
+    CFReleaseSafe(certs);
+    CFReleaseSafe(trust);
+    CFReleaseSafe(anchors);
+
+    CFReleaseSafe(_pairing_root_cert);
+    CFReleaseSafe(_pairing_host_cert);
+    CFReleaseSafe(_wrong_pairing_root_cert);
+
+}
+
+int si_20_sectrust_activation(int argc, char *const *argv)
+{
+       plan_tests(43);
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-20-sectrust.c b/sec/Security/Regressions/secitem/si-20-sectrust.c
new file mode 100644 (file)
index 0000000..8e42f54
--- /dev/null
@@ -0,0 +1,861 @@
+/*
+ * Copyright (c) 2006-2010,2012 Apple Inc. All Rights Reserved.
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecInternal.h>
+#include <Security/SecPolicyPriv.h>
+#include <Security/SecTrustPriv.h>
+#include <Security/SecItem.h>
+#include <ipc/securityd_client.h>
+#include <utilities/array_size.h>
+#include <utilities/SecCFWrappers.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "Security_regressions.h"
+
+/*
+       subject= /C=US/ST=California/L=Cupertino/O=Apple Computer, Inc./OU=Apple Internet Services/OU=Terms of use at www.verisign.com/rpa (c)00/CN=store.apple.com
+       issuer= /O=VeriSign Trust Network/OU=VeriSign, Inc./OU=VeriSign International Server CA - Class 3/OU=www.verisign.com/CPS Incorp.by Ref. LIABILITY LTD.(c)97 VeriSign
+       serial=4450E623F57E734FF85C1DEEFB976C86
+*/
+static const uint8_t _c0[] = {
+    0x30, 0x82, 0x04, 0x82, 0x30, 0x82, 0x03, 0xeb,
+    0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x44,
+    0x50, 0xe6, 0x23, 0xf5, 0x7e, 0x73, 0x4f, 0xf8,
+    0x5c, 0x1d, 0xee, 0xfb, 0x97, 0x6c, 0x86, 0x30,
+    0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+    0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81,
+    0xba, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55,
+    0x04, 0x0a, 0x13, 0x16, 0x56, 0x65, 0x72, 0x69,
+    0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75,
+    0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f,
+    0x72, 0x6b, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03,
+    0x55, 0x04, 0x0b, 0x13, 0x0e, 0x56, 0x65, 0x72,
+    0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49,
+    0x6e, 0x63, 0x2e, 0x31, 0x33, 0x30, 0x31, 0x06,
+    0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
+    0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x49,
+    0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69,
+    0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65, 0x72,
+    0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x20, 0x2d,
+    0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33,
+    0x31, 0x49, 0x30, 0x47, 0x06, 0x03, 0x55, 0x04,
+    0x0b, 0x13, 0x40, 0x77, 0x77, 0x77, 0x2e, 0x76,
+    0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e,
+    0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x50, 0x53, 0x20,
+    0x49, 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x62,
+    0x79, 0x20, 0x52, 0x65, 0x66, 0x2e, 0x20, 0x4c,
+    0x49, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59,
+    0x20, 0x4c, 0x54, 0x44, 0x2e, 0x28, 0x63, 0x29,
+    0x39, 0x37, 0x20, 0x56, 0x65, 0x72, 0x69, 0x53,
+    0x69, 0x67, 0x6e, 0x30, 0x1e, 0x17, 0x0d, 0x30,
+    0x35, 0x30, 0x33, 0x30, 0x32, 0x30, 0x30, 0x30,
+    0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x37,
+    0x30, 0x34, 0x30, 0x31, 0x32, 0x33, 0x35, 0x39,
+    0x35, 0x39, 0x5a, 0x30, 0x81, 0xc6, 0x31, 0x0b,
+    0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+    0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06,
+    0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x43, 0x61,
+    0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61,
+    0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
+    0x07, 0x14, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72,
+    0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1d, 0x30, 0x1b,
+    0x06, 0x03, 0x55, 0x04, 0x0a, 0x14, 0x14, 0x41,
+    0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x6f, 0x6d,
+    0x70, 0x75, 0x74, 0x65, 0x72, 0x2c, 0x20, 0x49,
+    0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, 0x06,
+    0x03, 0x55, 0x04, 0x0b, 0x14, 0x17, 0x41, 0x70,
+    0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x74, 0x65,
+    0x72, 0x6e, 0x65, 0x74, 0x20, 0x53, 0x65, 0x72,
+    0x76, 0x69, 0x63, 0x65, 0x73, 0x31, 0x33, 0x30,
+    0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x14, 0x2a,
+    0x54, 0x65, 0x72, 0x6d, 0x73, 0x20, 0x6f, 0x66,
+    0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x74, 0x20,
+    0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, 0x69,
+    0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
+    0x2f, 0x72, 0x70, 0x61, 0x20, 0x28, 0x63, 0x29,
+    0x30, 0x30, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03,
+    0x55, 0x04, 0x03, 0x14, 0x0f, 0x73, 0x74, 0x6f,
+    0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65,
+    0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x81, 0x9f, 0x30,
+    0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+    0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81,
+    0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81,
+    0x00, 0xbf, 0x8f, 0x59, 0x14, 0xbb, 0x91, 0xa4,
+    0xe6, 0x3e, 0x75, 0xf8, 0x38, 0x36, 0xfe, 0xcd,
+    0x9e, 0x5d, 0x3f, 0x14, 0x62, 0xfc, 0xe7, 0x48,
+    0x5f, 0x7e, 0x6b, 0x6e, 0x87, 0xd2, 0x31, 0x6e,
+    0x9d, 0x19, 0x92, 0x6f, 0xe3, 0xbc, 0x7e, 0x48,
+    0xb1, 0x2f, 0x9d, 0x70, 0x2c, 0x11, 0xdf, 0x35,
+    0xd1, 0xee, 0xd2, 0xd5, 0x37, 0x92, 0x4e, 0x06,
+    0x66, 0xb3, 0xc9, 0x9c, 0x99, 0xec, 0x09, 0xc6,
+    0xc4, 0xd6, 0xe6, 0x62, 0xb7, 0x97, 0x24, 0xd8,
+    0x38, 0x40, 0xf1, 0xa0, 0x1c, 0x0f, 0xf2, 0x3d,
+    0xaf, 0x4a, 0x93, 0xba, 0x11, 0xad, 0x67, 0xc4,
+    0x4b, 0x1d, 0x74, 0x33, 0x7c, 0xb9, 0x6b, 0x2d,
+    0xc5, 0x9b, 0x6a, 0xd2, 0xf2, 0x28, 0x08, 0x05,
+    0x18, 0x7d, 0xf0, 0xde, 0x28, 0x61, 0xf1, 0x81,
+    0xd5, 0x56, 0x4f, 0x20, 0x6e, 0xf3, 0x34, 0x89,
+    0x67, 0xd3, 0xa7, 0x09, 0xda, 0xc7, 0x89, 0x4d,
+    0xe1, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82,
+    0x01, 0x79, 0x30, 0x82, 0x01, 0x75, 0x30, 0x09,
+    0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30,
+    0x00, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f,
+    0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x46,
+    0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x3f, 0x30,
+    0x3d, 0x30, 0x3b, 0xa0, 0x39, 0xa0, 0x37, 0x86,
+    0x35, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+    0x63, 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72, 0x69,
+    0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
+    0x2f, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x33, 0x49,
+    0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69,
+    0x6f, 0x6e, 0x61, 0x6c, 0x53, 0x65, 0x72, 0x76,
+    0x65, 0x72, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x44,
+    0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3d, 0x30,
+    0x3b, 0x30, 0x39, 0x06, 0x0b, 0x60, 0x86, 0x48,
+    0x01, 0x86, 0xf8, 0x45, 0x01, 0x07, 0x17, 0x03,
+    0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06,
+    0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c,
+    0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f,
+    0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, 0x69,
+    0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
+    0x2f, 0x72, 0x70, 0x61, 0x30, 0x28, 0x06, 0x03,
+    0x55, 0x1d, 0x25, 0x04, 0x21, 0x30, 0x1f, 0x06,
+    0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42,
+    0x04, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+    0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06,
+    0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x34,
+    0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+    0x01, 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24,
+    0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+    0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70,
+    0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e,
+    0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e,
+    0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x6d, 0x06, 0x08,
+    0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x0c,
+    0x04, 0x61, 0x30, 0x5f, 0xa1, 0x5d, 0xa0, 0x5b,
+    0x30, 0x59, 0x30, 0x57, 0x30, 0x55, 0x16, 0x09,
+    0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69,
+    0x66, 0x30, 0x21, 0x30, 0x1f, 0x30, 0x07, 0x06,
+    0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14,
+    0x8f, 0xe5, 0xd3, 0x1a, 0x86, 0xac, 0x8d, 0x8e,
+    0x6b, 0xc3, 0xcf, 0x80, 0x6a, 0xd4, 0x48, 0x18,
+    0x2c, 0x7b, 0x19, 0x2e, 0x30, 0x25, 0x16, 0x23,
+    0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c,
+    0x6f, 0x67, 0x6f, 0x2e, 0x76, 0x65, 0x72, 0x69,
+    0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
+    0x2f, 0x76, 0x73, 0x6c, 0x6f, 0x67, 0x6f, 0x2e,
+    0x67, 0x69, 0x66, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+    0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
+    0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x01, 0x5e,
+    0x47, 0x3c, 0x5f, 0x38, 0x4f, 0x4d, 0x64, 0xf1,
+    0x33, 0x13, 0xd3, 0xcf, 0x80, 0xf9, 0x88, 0x93,
+    0xba, 0x44, 0x7b, 0xf0, 0xbd, 0x60, 0x96, 0x39,
+    0xa8, 0xc5, 0x76, 0x18, 0x01, 0xa7, 0x03, 0x53,
+    0x8b, 0x92, 0xda, 0x97, 0xaa, 0x85, 0xc7, 0xb7,
+    0x7d, 0x58, 0x83, 0x68, 0x4a, 0xd9, 0x54, 0x78,
+    0x7f, 0xa0, 0xe9, 0x8f, 0xc5, 0xb4, 0x3a, 0xb7,
+    0x3c, 0xa1, 0x70, 0x40, 0xac, 0xc2, 0xc6, 0x5b,
+    0xbd, 0x70, 0x90, 0xb9, 0xc6, 0x7d, 0x7e, 0x49,
+    0xe4, 0xbd, 0xc1, 0x5d, 0x1a, 0x0f, 0x9e, 0x0a,
+    0x93, 0xfd, 0xc7, 0x7a, 0x8b, 0x9c, 0x61, 0x61,
+    0x34, 0x02, 0xcc, 0x68, 0xdd, 0x2b, 0x29, 0xbc,
+    0x83, 0x8d, 0x7a, 0x8b, 0x22, 0xb9, 0x1e, 0x79,
+    0x3a, 0x5a, 0xc6, 0xda, 0xb3, 0xaf, 0xaf, 0x0b,
+    0x41, 0x16, 0xda, 0xd2, 0x8e, 0xcd, 0xc1, 0xc0,
+    0x43, 0xfc, 0xb3, 0x10, 0xb7, 0x27
+};
+
+static const uint8_t _c0_serial[] = {
+       0x44, 0x50, 0xE6, 0x23, 0xF5, 0x7E, 0x73, 0x4F,
+       0xF8, 0x5C, 0x1D, 0xEE, 0xFB, 0x97, 0x6C, 0x86
+};
+
+/*
+       subject= /O=VeriSign Trust Network/OU=VeriSign, Inc./OU=VeriSign International Server CA - Class 3/OU=www.verisign.com/CPS Incorp.by Ref. LIABILITY LTD.(c)97 VeriSign
+       issuer= /C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
+       serial=254B8A853842CCE358F8C5DDAE226EA4
+*/
+static const uint8_t _c1[] = {
+    0x30, 0x82, 0x03, 0x83, 0x30, 0x82, 0x02, 0xec,
+    0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x25,
+    0x4b, 0x8a, 0x85, 0x38, 0x42, 0xcc, 0xe3, 0x58,
+    0xf8, 0xc5, 0xdd, 0xae, 0x22, 0x6e, 0xa4, 0x30,
+    0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+    0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 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, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e,
+    0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x37,
+    0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
+    0x2e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33,
+    0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20,
+    0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20,
+    0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+    0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
+    0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30,
+    0x1e, 0x17, 0x0d, 0x39, 0x37, 0x30, 0x34, 0x31,
+    0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
+    0x17, 0x0d, 0x31, 0x31, 0x31, 0x30, 0x32, 0x34,
+    0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30,
+    0x81, 0xba, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03,
+    0x55, 0x04, 0x0a, 0x13, 0x16, 0x56, 0x65, 0x72,
+    0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72,
+    0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77,
+    0x6f, 0x72, 0x6b, 0x31, 0x17, 0x30, 0x15, 0x06,
+    0x03, 0x55, 0x04, 0x0b, 0x13, 0x0e, 0x56, 0x65,
+    0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20,
+    0x49, 0x6e, 0x63, 0x2e, 0x31, 0x33, 0x30, 0x31,
+    0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56,
+    0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20,
+    0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74,
+    0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65,
+    0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x20,
+    0x2d, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20,
+    0x33, 0x31, 0x49, 0x30, 0x47, 0x06, 0x03, 0x55,
+    0x04, 0x0b, 0x13, 0x40, 0x77, 0x77, 0x77, 0x2e,
+    0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e,
+    0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x50, 0x53,
+    0x20, 0x49, 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x2e,
+    0x62, 0x79, 0x20, 0x52, 0x65, 0x66, 0x2e, 0x20,
+    0x4c, 0x49, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54,
+    0x59, 0x20, 0x4c, 0x54, 0x44, 0x2e, 0x28, 0x63,
+    0x29, 0x39, 0x37, 0x20, 0x56, 0x65, 0x72, 0x69,
+    0x53, 0x69, 0x67, 0x6e, 0x30, 0x81, 0x9f, 0x30,
+    0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+    0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81,
+    0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81,
+    0x00, 0xd8, 0x82, 0x80, 0xe8, 0xd6, 0x19, 0x02,
+    0x7d, 0x1f, 0x85, 0x18, 0x39, 0x25, 0xa2, 0x65,
+    0x2b, 0xe1, 0xbf, 0xd4, 0x05, 0xd3, 0xbc, 0xe6,
+    0x36, 0x3b, 0xaa, 0xf0, 0x4c, 0x6c, 0x5b, 0xb6,
+    0xe7, 0xaa, 0x3c, 0x73, 0x45, 0x55, 0xb2, 0xf1,
+    0xbd, 0xea, 0x97, 0x42, 0xed, 0x9a, 0x34, 0x0a,
+    0x15, 0xd4, 0xa9, 0x5c, 0xf5, 0x40, 0x25, 0xdd,
+    0xd9, 0x07, 0xc1, 0x32, 0xb2, 0x75, 0x6c, 0xc4,
+    0xca, 0xbb, 0xa3, 0xfe, 0x56, 0x27, 0x71, 0x43,
+    0xaa, 0x63, 0xf5, 0x30, 0x3e, 0x93, 0x28, 0xe5,
+    0xfa, 0xf1, 0x09, 0x3b, 0xf3, 0xb7, 0x4d, 0x4e,
+    0x39, 0xf7, 0x5c, 0x49, 0x5a, 0xb8, 0xc1, 0x1d,
+    0xd3, 0xb2, 0x8a, 0xfe, 0x70, 0x30, 0x95, 0x42,
+    0xcb, 0xfe, 0x2b, 0x51, 0x8b, 0x5a, 0x3c, 0x3a,
+    0xf9, 0x22, 0x4f, 0x90, 0xb2, 0x02, 0xa7, 0x53,
+    0x9c, 0x4f, 0x34, 0xe7, 0xab, 0x04, 0xb2, 0x7b,
+    0x6f, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81,
+    0xe3, 0x30, 0x81, 0xe0, 0x30, 0x0f, 0x06, 0x03,
+    0x55, 0x1d, 0x13, 0x04, 0x08, 0x30, 0x06, 0x01,
+    0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x44, 0x06,
+    0x03, 0x55, 0x1d, 0x20, 0x04, 0x3d, 0x30, 0x3b,
+    0x30, 0x39, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01,
+    0x86, 0xf8, 0x45, 0x01, 0x07, 0x01, 0x01, 0x30,
+    0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01,
+    0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68,
+    0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77,
+    0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73,
+    0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+    0x43, 0x50, 0x53, 0x30, 0x34, 0x06, 0x03, 0x55,
+    0x1d, 0x25, 0x04, 0x2d, 0x30, 0x2b, 0x06, 0x08,
+    0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01,
+    0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+    0x03, 0x02, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
+    0x86, 0xf8, 0x42, 0x04, 0x01, 0x06, 0x0a, 0x60,
+    0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x08,
+    0x01, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f,
+    0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x11,
+    0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8,
+    0x42, 0x01, 0x01, 0x04, 0x04, 0x03, 0x02, 0x01,
+    0x06, 0x30, 0x31, 0x06, 0x03, 0x55, 0x1d, 0x1f,
+    0x04, 0x2a, 0x30, 0x28, 0x30, 0x26, 0xa0, 0x24,
+    0xa0, 0x22, 0x86, 0x20, 0x68, 0x74, 0x74, 0x70,
+    0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x76,
+    0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e,
+    0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63, 0x61, 0x33,
+    0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0d, 0x06, 0x09,
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+    0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x08,
+    0x01, 0xec, 0xe4, 0x68, 0x94, 0x03, 0x42, 0xf1,
+    0x73, 0xf1, 0x23, 0xa2, 0x3a, 0xde, 0xe9, 0xf1,
+    0xda, 0xc6, 0x54, 0xc4, 0x23, 0x3e, 0x86, 0xea,
+    0xcf, 0x6a, 0x3a, 0x33, 0xab, 0xea, 0x9c, 0x04,
+    0x14, 0x07, 0x36, 0x06, 0x0b, 0xf9, 0x88, 0x6f,
+    0xd5, 0x13, 0xee, 0x29, 0x2b, 0xc3, 0xe4, 0x72,
+    0x8d, 0x44, 0xed, 0xd1, 0xac, 0x20, 0x09, 0x2d,
+    0xe1, 0xf6, 0xe1, 0x19, 0x05, 0x38, 0xb0, 0x3d,
+    0x0f, 0x9f, 0x7f, 0xf8, 0x9e, 0x02, 0xdc, 0x86,
+    0x02, 0x86, 0x61, 0x4e, 0x26, 0x5f, 0x5e, 0x9f,
+    0x92, 0x1e, 0x0c, 0x24, 0xa4, 0xf5, 0xd0, 0x70,
+    0x13, 0xcf, 0x26, 0xc3, 0x43, 0x3d, 0x49, 0x1d,
+    0x9e, 0x82, 0x2e, 0x52, 0x5f, 0xbc, 0x3e, 0xc6,
+    0x66, 0x29, 0x01, 0x8e, 0x4e, 0x92, 0x2c, 0xbc,
+    0x46, 0x75, 0x03, 0x82, 0xac, 0x73, 0xe9, 0xd9,
+    0x7e, 0x0b, 0x67, 0xef, 0x54, 0x52, 0x1a
+};
+
+
+/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc/OU=Internet Operations/CN=xedge2.apple.com
+   issuer :/C=US/O=Entrust.net/OU=www.entrust.net/CPS incorp. by ref. (limits liab.)/OU=(c) 1999 Entrust.net Limited/CN=Entrust.net Secure Server Certification Authority */
+const uint8_t xedge2_certificate[1385]={
+0x30,0x82,0x05,0x65,0x30,0x82,0x04,0xCE,0xA0,0x03,0x02,0x01,0x02,0x02,0x04,0x46,
+0x9C,0xDF,0x96,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,
+0x05,0x00,0x30,0x81,0xC3,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
+0x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x13,0x0B,0x45,0x6E,0x74,
+0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x31,0x3B,0x30,0x39,0x06,0x03,0x55,0x04,
+0x0B,0x13,0x32,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,
+0x65,0x74,0x2F,0x43,0x50,0x53,0x20,0x69,0x6E,0x63,0x6F,0x72,0x70,0x2E,0x20,0x62,
+0x79,0x20,0x72,0x65,0x66,0x2E,0x20,0x28,0x6C,0x69,0x6D,0x69,0x74,0x73,0x20,0x6C,
+0x69,0x61,0x62,0x2E,0x29,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x0B,0x13,0x1C,
+0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x39,0x20,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,
+0x2E,0x6E,0x65,0x74,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x3A,0x30,0x38,
+0x06,0x03,0x55,0x04,0x03,0x13,0x31,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,
+0x65,0x74,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x53,0x65,0x72,0x76,0x65,0x72,
+0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,
+0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x30,0x38,0x30,0x31,
+0x32,0x39,0x31,0x38,0x33,0x33,0x31,0x33,0x5A,0x17,0x0D,0x31,0x30,0x30,0x31,0x32,
+0x38,0x31,0x39,0x30,0x33,0x31,0x32,0x5A,0x30,0x81,0x83,0x31,0x0B,0x30,0x09,0x06,
+0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,
+0x08,0x13,0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61,0x31,0x12,0x30,
+0x10,0x06,0x03,0x55,0x04,0x07,0x13,0x09,0x43,0x75,0x70,0x65,0x72,0x74,0x69,0x6E,
+0x6F,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x0A,0x13,0x09,0x41,0x70,0x70,0x6C,
+0x65,0x20,0x49,0x6E,0x63,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0B,0x13,0x13,
+0x49,0x6E,0x74,0x65,0x72,0x6E,0x65,0x74,0x20,0x4F,0x70,0x65,0x72,0x61,0x74,0x69,
+0x6F,0x6E,0x73,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x03,0x13,0x10,0x78,0x65,
+0x64,0x67,0x65,0x32,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x81,
+0x9F,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,
+0x03,0x81,0x8D,0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xC7,0xF3,0xA1,0x0E,0x0E,
+0xA4,0xDF,0xC5,0x3F,0x24,0x87,0xC3,0x6E,0xE7,0xD0,0x7C,0x2B,0x5A,0x1C,0xF3,0x67,
+0x6C,0x6B,0x56,0x0A,0x95,0xC9,0xE5,0x13,0x28,0x6E,0x16,0x9D,0x4F,0xB1,0x76,0xFB,
+0x7D,0x42,0x5B,0x2A,0x7C,0xCC,0x97,0x75,0xAA,0xA6,0xA9,0xDE,0xB2,0xEC,0xEF,0xE2,
+0xAB,0x40,0xAE,0x9A,0x23,0xF0,0x6A,0x10,0xB3,0x75,0x27,0xF0,0xF4,0x7D,0x08,0x67,
+0x8F,0xCE,0x41,0x24,0x74,0xAA,0x37,0xB6,0xC1,0x32,0x61,0xCF,0x7D,0x1C,0x21,0xCD,
+0xCF,0x7C,0x9E,0xE2,0x48,0x03,0x7E,0x78,0xB3,0x86,0x3D,0x06,0x6B,0x39,0xEC,0xC8,
+0x73,0x68,0xDB,0xE7,0x5B,0x97,0xF4,0xF9,0xA3,0xE7,0xFB,0x81,0x2E,0x4D,0x0B,0x3F,
+0xA9,0xCA,0xDE,0x32,0x26,0xF3,0xF0,0x97,0x72,0x65,0xAB,0x02,0x03,0x01,0x00,0x01,
+0xA3,0x82,0x02,0xA2,0x30,0x82,0x02,0x9E,0x30,0x0B,0x06,0x03,0x55,0x1D,0x0F,0x04,
+0x04,0x03,0x02,0x05,0xA0,0x30,0x2B,0x06,0x03,0x55,0x1D,0x10,0x04,0x24,0x30,0x22,
+0x80,0x0F,0x32,0x30,0x30,0x38,0x30,0x31,0x32,0x39,0x31,0x38,0x33,0x33,0x31,0x33,
+0x5A,0x81,0x0F,0x32,0x30,0x31,0x30,0x30,0x31,0x32,0x38,0x31,0x39,0x30,0x33,0x31,
+0x32,0x5A,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,0x04,
+0x04,0x03,0x02,0x06,0x40,0x30,0x13,0x06,0x03,0x55,0x1D,0x25,0x04,0x0C,0x30,0x0A,
+0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01,0x30,0x82,0x01,0x68,0x06,0x03,
+0x55,0x1D,0x20,0x04,0x82,0x01,0x5F,0x30,0x82,0x01,0x5B,0x30,0x82,0x01,0x57,0x06,
+0x09,0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x4B,0x02,0x30,0x82,0x01,0x48,0x30,0x26,
+0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1A,0x68,0x74,0x74,0x70,
+0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,
+0x65,0x74,0x2F,0x63,0x70,0x73,0x30,0x82,0x01,0x1C,0x06,0x08,0x2B,0x06,0x01,0x05,
+0x05,0x07,0x02,0x02,0x30,0x82,0x01,0x0E,0x1A,0x82,0x01,0x0A,0x54,0x68,0x65,0x20,
+0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x20,0x53,0x53,0x4C,0x20,0x57,0x65,0x62,0x20,
+0x53,0x65,0x72,0x76,0x65,0x72,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,
+0x74,0x69,0x6F,0x6E,0x20,0x50,0x72,0x61,0x63,0x74,0x69,0x63,0x65,0x20,0x53,0x74,
+0x61,0x74,0x65,0x6D,0x65,0x6E,0x74,0x20,0x28,0x43,0x50,0x53,0x29,0x20,0x61,0x76,
+0x61,0x69,0x6C,0x61,0x62,0x6C,0x65,0x20,0x61,0x74,0x20,0x77,0x77,0x77,0x2E,0x65,
+0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x2F,0x63,0x70,0x73,0x20,0x20,
+0x69,0x73,0x20,0x68,0x65,0x72,0x65,0x62,0x79,0x20,0x69,0x6E,0x63,0x6F,0x72,0x70,
+0x6F,0x72,0x61,0x74,0x65,0x64,0x20,0x69,0x6E,0x74,0x6F,0x20,0x79,0x6F,0x75,0x72,
+0x20,0x75,0x73,0x65,0x20,0x6F,0x72,0x20,0x72,0x65,0x6C,0x69,0x61,0x6E,0x63,0x65,
+0x20,0x6F,0x6E,0x20,0x74,0x68,0x69,0x73,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,
+0x63,0x61,0x74,0x65,0x2E,0x20,0x20,0x54,0x68,0x69,0x73,0x20,0x43,0x50,0x53,0x20,
+0x63,0x6F,0x6E,0x74,0x61,0x69,0x6E,0x73,0x20,0x6C,0x69,0x6D,0x69,0x74,0x61,0x74,
+0x69,0x6F,0x6E,0x73,0x20,0x6F,0x6E,0x20,0x77,0x61,0x72,0x72,0x61,0x6E,0x74,0x69,
+0x65,0x73,0x20,0x61,0x6E,0x64,0x20,0x6C,0x69,0x61,0x62,0x69,0x6C,0x69,0x74,0x69,
+0x65,0x73,0x2E,0x20,0x43,0x6F,0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x20,0x28,0x63,
+0x29,0x20,0x32,0x30,0x30,0x32,0x20,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x20,0x4C,
+0x69,0x6D,0x69,0x74,0x65,0x64,0x30,0x33,0x06,0x03,0x55,0x1D,0x1F,0x04,0x2C,0x30,
+0x2A,0x30,0x28,0xA0,0x26,0xA0,0x24,0x86,0x22,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,
+0x63,0x72,0x6C,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x2F,
+0x73,0x65,0x72,0x76,0x65,0x72,0x31,0x2E,0x63,0x72,0x6C,0x30,0x33,0x06,0x08,0x2B,
+0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x27,0x30,0x25,0x30,0x23,0x06,0x08,0x2B,
+0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x17,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,
+0x6F,0x63,0x73,0x70,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,
+0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xF0,0x17,0x62,
+0x13,0x55,0x3D,0xB3,0xFF,0x0A,0x00,0x6B,0xFB,0x50,0x84,0x97,0xF3,0xED,0x62,0xD0,
+0x1A,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x2D,0xEF,0xD9,0xAF,
+0x1A,0x89,0x40,0x53,0x75,0x48,0x26,0x59,0x2F,0xEC,0x11,0x18,0xC0,0xD1,0x7A,0x34,
+0x30,0x09,0x06,0x03,0x55,0x1D,0x13,0x04,0x02,0x30,0x00,0x30,0x19,0x06,0x09,0x2A,
+0x86,0x48,0x86,0xF6,0x7D,0x07,0x41,0x00,0x04,0x0C,0x30,0x0A,0x1B,0x04,0x56,0x37,
+0x2E,0x31,0x03,0x02,0x03,0x28,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,
+0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x77,0x33,0x2A,0x69,0x45,0x5A,0xB2,
+0xF5,0x74,0xF7,0xDF,0xC7,0x08,0x85,0x86,0x88,0x98,0x41,0x7F,0x57,0x49,0x01,0xBA,
+0x13,0x21,0x40,0xD0,0x0A,0x5C,0xA7,0x37,0xDF,0xB3,0x7E,0xF8,0xED,0x04,0x63,0xC3,
+0xE8,0x0F,0xA0,0xE5,0xC4,0x4F,0x3A,0x90,0xE4,0x87,0x5F,0xEC,0xDB,0x65,0x8B,0x6E,
+0x88,0x6E,0x6E,0xE4,0xBC,0x6A,0x7E,0x37,0x47,0x04,0xFF,0x09,0xC6,0x70,0xE1,0x65,
+0x8F,0xE3,0xE9,0x60,0xEB,0xE8,0x8E,0x29,0xAE,0xF9,0x81,0xCA,0x9A,0x97,0x3C,0x6F,
+0x7C,0xFA,0xA8,0x49,0xB4,0x33,0x76,0x9C,0x65,0x92,0x12,0xF6,0x7F,0x6A,0x62,0x84,
+0x29,0x5F,0x14,0x26,0x6E,0x07,0x6F,0x5C,0xB5,0x7C,0x21,0x64,0x7C,0xD9,0x93,0xF4,
+0x9C,0xC8,0xE7,0xEC,0xC6,0xAC,0x13,0xC4,0xF0
+};
+
+
+/* subject:/CN=garthc2.apple.com/O=Apple Inc./OU=DTS/ST=California/C=US/L=Cupertino/emailAddress=gcummings@apple.com
+   issuer :/CN=garthc2.apple.com/O=Apple Inc./OU=DTS/ST=California/C=US/L=Cupertino/emailAddress=gcummings@apple.com */
+const uint8_t garthc2_certificate[730]={
+0x30,0x82,0x02,0xD6,0x30,0x82,0x02,0x3F,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x01,
+0x30,0x0B,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x30,0x81,0x99,
+0x31,0x1A,0x30,0x18,0x06,0x03,0x55,0x04,0x03,0x0C,0x11,0x67,0x61,0x72,0x74,0x68,
+0x63,0x32,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x31,0x13,0x30,0x11,
+0x06,0x03,0x55,0x04,0x0A,0x0C,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x6E,0x63,
+0x2E,0x31,0x0C,0x30,0x0A,0x06,0x03,0x55,0x04,0x0B,0x0C,0x03,0x44,0x54,0x53,0x31,
+0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x08,0x0C,0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,
+0x72,0x6E,0x69,0x61,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
+0x53,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x07,0x0C,0x09,0x43,0x75,0x70,0x65,
+0x72,0x74,0x69,0x6E,0x6F,0x31,0x22,0x30,0x20,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,
+0x0D,0x01,0x09,0x01,0x16,0x13,0x67,0x63,0x75,0x6D,0x6D,0x69,0x6E,0x67,0x73,0x40,
+0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x1E,0x17,0x0D,0x30,0x39,0x30,
+0x37,0x31,0x36,0x32,0x32,0x34,0x39,0x31,0x30,0x5A,0x17,0x0D,0x31,0x30,0x30,0x37,
+0x31,0x36,0x32,0x32,0x34,0x39,0x31,0x30,0x5A,0x30,0x81,0x99,0x31,0x1A,0x30,0x18,
+0x06,0x03,0x55,0x04,0x03,0x0C,0x11,0x67,0x61,0x72,0x74,0x68,0x63,0x32,0x2E,0x61,
+0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,
+0x0A,0x0C,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x0C,0x30,
+0x0A,0x06,0x03,0x55,0x04,0x0B,0x0C,0x03,0x44,0x54,0x53,0x31,0x13,0x30,0x11,0x06,
+0x03,0x55,0x04,0x08,0x0C,0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61,
+0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x12,0x30,
+0x10,0x06,0x03,0x55,0x04,0x07,0x0C,0x09,0x43,0x75,0x70,0x65,0x72,0x74,0x69,0x6E,
+0x6F,0x31,0x22,0x30,0x20,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x01,
+0x16,0x13,0x67,0x63,0x75,0x6D,0x6D,0x69,0x6E,0x67,0x73,0x40,0x61,0x70,0x70,0x6C,
+0x65,0x2E,0x63,0x6F,0x6D,0x30,0x81,0x9F,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,
+0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8D,0x00,0x30,0x81,0x89,0x02,0x81,
+0x81,0x00,0xCF,0x30,0xD9,0x9D,0x9C,0xD5,0x6F,0xCB,0xB1,0xD1,0xC2,0x73,0xE2,0xB4,
+0x06,0xC3,0x16,0x6D,0x0E,0x68,0x40,0x5E,0x92,0xFC,0xD9,0x14,0xD2,0x5E,0x21,0x50,
+0x66,0x41,0x96,0x3A,0x76,0x26,0xF6,0x6C,0x3C,0xA2,0xD4,0x84,0x91,0x09,0x2E,0x23,
+0x2D,0x07,0x38,0x48,0x58,0x31,0xE5,0x00,0x08,0xB1,0x6C,0x5D,0x39,0x50,0x30,0xF7,
+0x68,0x12,0x99,0xB5,0x4C,0x86,0x1E,0xA5,0xF4,0x0C,0xCB,0xCB,0x25,0xB0,0x7C,0x6A,
+0xFE,0x28,0xD4,0x34,0xA5,0xD2,0x94,0x5E,0xBE,0x5F,0xC1,0x61,0xAE,0xB5,0xD2,0xD2,
+0x18,0x34,0x07,0x02,0xA8,0x56,0xAC,0x55,0x4D,0x87,0x56,0x8A,0xBA,0x1B,0x17,0x26,
+0x11,0x9B,0xF8,0x88,0xD1,0x4F,0x94,0x03,0x01,0xCC,0x01,0xE7,0x0B,0x9B,0x14,0x43,
+0x25,0xFB,0x02,0x03,0x01,0x00,0x01,0xA3,0x2E,0x30,0x2C,0x30,0x0B,0x06,0x03,0x55,
+0x1D,0x0F,0x04,0x04,0x03,0x02,0x05,0xA0,0x30,0x1D,0x06,0x03,0x55,0x1D,0x25,0x04,
+0x16,0x30,0x14,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x08,0x2B,
+0x06,0x01,0x05,0x05,0x07,0x03,0x01,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,
+0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x9D,0x8A,0x8A,0x9F,0xA5,0x36,
+0xA2,0xE6,0x1D,0xA9,0xF1,0x10,0xDF,0xC8,0xFC,0x1A,0x2B,0xA0,0x01,0x07,0x58,0xA4,
+0xD0,0x41,0xE1,0x32,0xD8,0xA9,0x84,0x9E,0xF3,0xE2,0xDE,0x48,0xD3,0x03,0xD7,0xC9,
+0x40,0x58,0x5A,0x91,0x85,0x70,0xF6,0xC7,0x34,0x90,0x3C,0x1B,0x06,0x8F,0x0C,0xEE,
+0xDD,0x79,0x14,0x42,0x72,0x4F,0x41,0xF9,0xB0,0xEC,0x04,0x9F,0xD6,0x75,0x68,0x06,
+0xA0,0xEA,0x11,0x0C,0xE9,0x16,0x2F,0x9E,0x23,0xFA,0x5D,0xC2,0x02,0x92,0x2A,0xDD,
+0xE8,0xBD,0xA1,0x8F,0x33,0x96,0x84,0xFA,0xFD,0x3C,0x70,0xD4,0x9D,0x43,0xA4,0xA0,
+0xE9,0xF4,0x49,0xB2,0xF4,0xCB,0x9F,0x43,0x87,0x04,0x8D,0xD0,0xEA,0xAC,0x21,0x24,
+0x2C,0x4C,0x36,0x5C,0x34,0x8C,0x61,0xA4,0xF4,0xB8,
+};
+
+const uint8_t prt_forest_fi_certificate[1797] = {
+    0x30, 0x82, 0x07, 0x01, 0x30, 0x82, 0x05, 0xe9, 0xa0, 0x03, 0x02, 0x01,
+    0x02, 0x02, 0x11, 0x00, 0xfa, 0x69, 0x1a, 0xa7, 0xbf, 0x1b, 0x93, 0xbe,
+    0x97, 0x11, 0xb0, 0xfe, 0xfc, 0xa8, 0x8d, 0x8c, 0x30, 0x0d, 0x06, 0x09,
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
+    0x39, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+    0x46, 0x49, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+    0x06, 0x53, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x31, 0x19, 0x30, 0x17, 0x06,
+    0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x53, 0x6f, 0x6e, 0x65, 0x72, 0x61,
+    0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x32, 0x20, 0x43, 0x41, 0x30, 0x1e,
+    0x17, 0x0d, 0x31, 0x30, 0x31, 0x32, 0x30, 0x31, 0x30, 0x39, 0x33, 0x39,
+    0x33, 0x33, 0x5a, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x31, 0x33, 0x30, 0x30,
+    0x39, 0x33, 0x39, 0x33, 0x33, 0x5a, 0x30, 0x57, 0x31, 0x0b, 0x30, 0x09,
+    0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x46, 0x49, 0x31, 0x16, 0x30,
+    0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0d, 0x50, 0x52, 0x54, 0x2d,
+    0x46, 0x6f, 0x72, 0x65, 0x73, 0x74, 0x20, 0x4f, 0x79, 0x31, 0x16, 0x30,
+    0x14, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x0d, 0x54, 0x69, 0x65, 0x74,
+    0x6f, 0x68, 0x61, 0x6c, 0x6c, 0x69, 0x6e, 0x74, 0x6f, 0x31, 0x18, 0x30,
+    0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x2a, 0x2e, 0x70, 0x72,
+    0x74, 0x2d, 0x66, 0x6f, 0x72, 0x65, 0x73, 0x74, 0x2e, 0x66, 0x69, 0x30,
+    0x82, 0x04, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+    0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x04, 0x0f, 0x00, 0x30,
+    0x82, 0x04, 0x0a, 0x02, 0x82, 0x04, 0x01, 0x00, 0xbc, 0x62, 0x25, 0x57,
+    0xbc, 0x71, 0xb8, 0xa9, 0x5b, 0x0e, 0x04, 0xbc, 0xc4, 0x0e, 0xf1, 0x0e,
+    0x1f, 0x20, 0xd2, 0xf4, 0x4f, 0x23, 0xfe, 0x14, 0x54, 0x34, 0x81, 0xd3,
+    0x5b, 0xdd, 0x74, 0xed, 0xa1, 0xbe, 0x91, 0x99, 0x9d, 0x02, 0xb9, 0x36,
+    0x70, 0x43, 0x5d, 0x73, 0xa6, 0xe5, 0x70, 0x7b, 0x0e, 0x0c, 0x3f, 0x33,
+    0xbb, 0x71, 0xd6, 0xd4, 0x22, 0xb0, 0xeb, 0xf5, 0x6e, 0x07, 0x7c, 0xe7,
+    0xc7, 0xd1, 0x20, 0x64, 0x72, 0x4e, 0xae, 0x5e, 0xae, 0xaf, 0x08, 0xfb,
+    0x7d, 0x6d, 0xdb, 0x69, 0x5a, 0x31, 0x73, 0x7d, 0xbd, 0x53, 0xcb, 0x04,
+    0x69, 0x6d, 0x74, 0x56, 0x6c, 0xbc, 0x84, 0xa6, 0x01, 0x39, 0x37, 0x0c,
+    0xb9, 0x5c, 0x2e, 0x78, 0x50, 0x3a, 0x8d, 0x1f, 0xa2, 0x33, 0xf1, 0xd2,
+    0xc2, 0x87, 0x51, 0xf4, 0x92, 0xc3, 0xa7, 0xaa, 0xc8, 0x36, 0x51, 0x1c,
+    0xfb, 0x77, 0xbf, 0xcf, 0x24, 0x11, 0xfe, 0xf4, 0x11, 0x2f, 0x5c, 0xdf,
+    0x26, 0xf6, 0xb9, 0x15, 0xc1, 0x46, 0x75, 0x83, 0x40, 0x77, 0xa4, 0x83,
+    0x74, 0xce, 0xc0, 0x29, 0x31, 0xd3, 0xd8, 0x68, 0xfa, 0x2e, 0xcc, 0x15,
+    0x2c, 0x59, 0x5c, 0xa7, 0x96, 0x65, 0x8f, 0x34, 0x87, 0x29, 0x22, 0x1d,
+    0xde, 0x65, 0xc7, 0x1c, 0x5c, 0xd8, 0x33, 0x22, 0xf7, 0x93, 0xd9, 0xcd,
+    0x96, 0x76, 0x22, 0xab, 0x75, 0x18, 0x04, 0xe7, 0x65, 0x2a, 0xeb, 0x42,
+    0x75, 0x17, 0x13, 0x12, 0x00, 0xe3, 0xf4, 0xd9, 0xde, 0xd1, 0x9f, 0x1c,
+    0x61, 0xee, 0xf6, 0xb9, 0xf9, 0x50, 0xb3, 0x1b, 0x79, 0x77, 0x38, 0x3c,
+    0x6a, 0xcc, 0xa0, 0x1d, 0xe4, 0xd7, 0x43, 0xca, 0x8b, 0x22, 0xbf, 0x77,
+    0x33, 0xea, 0xaa, 0x01, 0xcf, 0x1e, 0xd0, 0x0d, 0x04, 0x2b, 0xec, 0x42,
+    0x7b, 0xec, 0x53, 0xed, 0xc7, 0x4f, 0x0c, 0xac, 0x29, 0xb7, 0x8b, 0x92,
+    0x14, 0x3f, 0x9b, 0xc6, 0xd8, 0xa1, 0x30, 0x4d, 0x5a, 0x07, 0x0e, 0x1e,
+    0x80, 0x5f, 0x38, 0x66, 0x4d, 0xc1, 0xad, 0x2f, 0xee, 0xae, 0x94, 0x50,
+    0x8e, 0x38, 0x2a, 0x00, 0x80, 0xe2, 0xc4, 0x43, 0x2e, 0xd5, 0xcd, 0xca,
+    0x3f, 0x3d, 0xcb, 0x35, 0x13, 0x96, 0xd2, 0xdc, 0x0e, 0xe7, 0x45, 0x57,
+    0x4b, 0x8f, 0xee, 0xa1, 0xce, 0xe6, 0x57, 0x52, 0xcd, 0xd0, 0x82, 0xca,
+    0x3b, 0x87, 0xf4, 0x22, 0xff, 0x81, 0x4b, 0xf5, 0xa3, 0xda, 0xc5, 0xb6,
+    0x67, 0xb8, 0xf4, 0xaf, 0xff, 0x8d, 0x4e, 0x80, 0xb5, 0x22, 0x80, 0x3c,
+    0x70, 0xe4, 0xa0, 0xae, 0xdc, 0xcf, 0x44, 0xff, 0x00, 0x98, 0x3f, 0x19,
+    0x7b, 0x4c, 0x3d, 0xd8, 0xa5, 0xd8, 0xe0, 0x05, 0x73, 0x54, 0x06, 0x0c,
+    0x4d, 0x50, 0xf8, 0xd8, 0x85, 0x0b, 0xa8, 0x49, 0xaa, 0x97, 0x87, 0x3b,
+    0x32, 0xe8, 0x58, 0x22, 0xee, 0x34, 0x1c, 0x9f, 0xe3, 0x18, 0xba, 0x93,
+    0x43, 0xea, 0xb7, 0x78, 0x35, 0xa2, 0xb5, 0x1e, 0x19, 0x16, 0x3b, 0xb3,
+    0xf5, 0x12, 0xe8, 0x26, 0x62, 0x2d, 0xd7, 0x45, 0xc3, 0xa4, 0x4b, 0xda,
+    0x38, 0x48, 0x00, 0x3f, 0x68, 0x62, 0xa2, 0x83, 0x9d, 0x32, 0x76, 0x27,
+    0x40, 0x5d, 0x0e, 0x75, 0xb1, 0x08, 0xdb, 0x58, 0xfa, 0x20, 0x62, 0xf1,
+    0x3f, 0xbd, 0x86, 0x2f, 0x7c, 0x07, 0x01, 0x14, 0x1d, 0x19, 0x61, 0xee,
+    0x0a, 0x85, 0xbf, 0xc7, 0x4f, 0x4a, 0x06, 0xc0, 0xaf, 0x44, 0x5d, 0x6f,
+    0xc3, 0x53, 0x23, 0xcb, 0xdf, 0x40, 0x7a, 0x18, 0xa1, 0x34, 0x80, 0x18,
+    0x86, 0xfe, 0xe3, 0x87, 0xce, 0x30, 0x53, 0x33, 0x1c, 0x45, 0x4a, 0xb4,
+    0xe1, 0x8c, 0x9b, 0x4b, 0xf5, 0x2c, 0x7c, 0x13, 0x56, 0x37, 0x8a, 0x94,
+    0x24, 0xdb, 0x3a, 0x4b, 0x80, 0xb1, 0x26, 0x57, 0x5a, 0x75, 0x1c, 0x44,
+    0xc5, 0xf7, 0x67, 0xb4, 0x61, 0x87, 0xe8, 0x2e, 0xd9, 0xe1, 0xb9, 0x45,
+    0xcc, 0xdc, 0xdf, 0x3b, 0x8c, 0xce, 0xd0, 0x46, 0x6b, 0x87, 0xb5, 0xa9,
+    0xfe, 0x35, 0x87, 0xe0, 0xca, 0xc6, 0x7d, 0xc8, 0x86, 0xc2, 0xfe, 0x89,
+    0xec, 0xa9, 0x86, 0x33, 0x81, 0xdc, 0x41, 0xb3, 0xe7, 0xc4, 0x82, 0x3a,
+    0x81, 0x05, 0xbd, 0x8b, 0x92, 0xb2, 0x6a, 0x2c, 0x3c, 0xca, 0xd0, 0x22,
+    0xff, 0xc8, 0x8f, 0xf0, 0x5f, 0x0e, 0xfb, 0x0b, 0x36, 0x64, 0x6a, 0x12,
+    0x77, 0x2d, 0x8a, 0x38, 0xde, 0x7d, 0xed, 0xc9, 0xa7, 0xc1, 0x85, 0x41,
+    0xa2, 0x7b, 0xa5, 0xdc, 0x30, 0x96, 0xda, 0xf8, 0xb3, 0xc8, 0x21, 0x56,
+    0x3c, 0xdb, 0xe4, 0x8c, 0xb0, 0xfb, 0xec, 0x0e, 0x58, 0x49, 0x3c, 0x75,
+    0x3c, 0xc2, 0x41, 0xbd, 0xc0, 0x81, 0x37, 0xc7, 0x69, 0x5a, 0x41, 0x86,
+    0x18, 0xe9, 0x41, 0x7f, 0xba, 0xff, 0xc3, 0x52, 0x56, 0xf9, 0x7c, 0x60,
+    0x14, 0xf9, 0x66, 0x4c, 0x60, 0xb6, 0x3e, 0x23, 0xcd, 0xd1, 0x2d, 0x4f,
+    0x43, 0x97, 0xea, 0xa3, 0x37, 0xa4, 0x2a, 0xa7, 0x81, 0x49, 0x90, 0xe3,
+    0xb6, 0x12, 0x1b, 0xac, 0x78, 0x57, 0x20, 0x51, 0xb4, 0x16, 0x5e, 0x58,
+    0x61, 0x0f, 0x1e, 0x35, 0xbc, 0x3f, 0x44, 0xc2, 0x85, 0xa5, 0x61, 0x8a,
+    0x0a, 0x7c, 0x2e, 0xb0, 0x11, 0x12, 0xc6, 0xc0, 0xc8, 0xcb, 0xd8, 0x13,
+    0xc3, 0x58, 0xf1, 0xcd, 0x06, 0x5f, 0x90, 0xa5, 0xd7, 0x74, 0xbc, 0x1a,
+    0x9c, 0xdc, 0xab, 0xde, 0xea, 0x36, 0x67, 0x41, 0x4f, 0x62, 0x86, 0xc6,
+    0xfe, 0x63, 0x14, 0x83, 0x11, 0xab, 0xfb, 0x61, 0x38, 0x11, 0xce, 0x01,
+    0xe8, 0xee, 0x3a, 0x21, 0xbc, 0xaa, 0x4b, 0xb0, 0x8f, 0x2f, 0xcf, 0x58,
+    0xe6, 0x55, 0x61, 0x38, 0xa7, 0xc3, 0xaa, 0x3b, 0xb0, 0x8c, 0xf4, 0x82,
+    0xa0, 0x96, 0xc4, 0x13, 0x4a, 0xc0, 0xc8, 0x93, 0xb7, 0x3d, 0x28, 0x05,
+    0xb9, 0xc8, 0x4c, 0xe8, 0x57, 0xda, 0x56, 0x8b, 0xda, 0x27, 0xab, 0xbf,
+    0x7e, 0x66, 0x43, 0xdc, 0x57, 0x09, 0xdc, 0x88, 0x8e, 0xfb, 0xa7, 0x63,
+    0x41, 0xfb, 0xf1, 0x67, 0xb5, 0xe1, 0x84, 0x5d, 0x1d, 0xe3, 0xb4, 0xc6,
+    0x40, 0x97, 0xf8, 0x4d, 0xfc, 0x00, 0xcd, 0x56, 0xc2, 0xab, 0xff, 0x49,
+    0x93, 0xff, 0x46, 0x56, 0x9b, 0xee, 0x6d, 0xa0, 0x5d, 0xf4, 0x78, 0x36,
+    0x0e, 0xf6, 0xc9, 0x9c, 0x79, 0x89, 0xf9, 0x9c, 0xa7, 0x3e, 0xa0, 0x8d,
+    0x62, 0x7c, 0xdc, 0x83, 0x0a, 0xfc, 0x46, 0x96, 0x31, 0xd3, 0x56, 0xc6,
+    0xea, 0x7f, 0x1d, 0xaa, 0x49, 0xd1, 0x8b, 0x54, 0xa2, 0x6e, 0x59, 0x8c,
+    0x2a, 0xec, 0x3a, 0xd7, 0xda, 0xd2, 0xc1, 0xfc, 0x1d, 0x78, 0x55, 0xce,
+    0xd8, 0x0c, 0x1d, 0x7e, 0x99, 0xf8, 0x5e, 0x3c, 0x2d, 0xec, 0x63, 0xe2,
+    0xda, 0xa1, 0x68, 0x6f, 0x28, 0x2e, 0xb4, 0xef, 0x07, 0xc4, 0xa8, 0x65,
+    0xc7, 0xfd, 0x6b, 0x0f, 0x83, 0x23, 0xf8, 0xc2, 0xc9, 0x55, 0xfa, 0xa4,
+    0xa8, 0x6a, 0xab, 0x12, 0xf4, 0x89, 0x42, 0x26, 0x72, 0xd1, 0x82, 0x2f,
+    0x62, 0x14, 0xb6, 0x04, 0x23, 0x20, 0xb6, 0xd4, 0xef, 0x59, 0x8a, 0x40,
+    0x43, 0xd7, 0x72, 0xe0, 0x5b, 0x0c, 0xb0, 0x73, 0x6f, 0x6a, 0x87, 0xc1,
+    0x82, 0x50, 0x20, 0xdb, 0xaa, 0xf8, 0x8d, 0x70, 0xb6, 0x39, 0x46, 0xe0,
+    0x68, 0xc4, 0xab, 0xea, 0xd1, 0x31, 0xad, 0xf7, 0x05, 0xfb, 0x3a, 0x3c,
+    0x2e, 0x66, 0x4f, 0xc6, 0x0d, 0xf9, 0xb8, 0x29, 0xec, 0xdc, 0xfc, 0x81,
+    0x56, 0x2b, 0xb0, 0xad, 0xd2, 0x12, 0x8f, 0x69, 0x70, 0x18, 0x27, 0x16,
+    0xf9, 0xf0, 0x40, 0x93, 0xef, 0x6b, 0x95, 0x96, 0xcd, 0x5f, 0xe9, 0x5a,
+    0x7b, 0xad, 0x7f, 0x98, 0xa7, 0x6a, 0xe5, 0x17, 0xeb, 0xc3, 0xdd, 0xc9,
+    0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xe5, 0x30, 0x81, 0xe2, 0x30,
+    0x13, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x0c, 0x30, 0x0a, 0x80, 0x08,
+    0x4a, 0xa0, 0xaa, 0x58, 0x84, 0xd3, 0x5e, 0x3c, 0x30, 0x19, 0x06, 0x03,
+    0x55, 0x1d, 0x20, 0x04, 0x12, 0x30, 0x10, 0x30, 0x0e, 0x06, 0x0c, 0x2b,
+    0x06, 0x01, 0x04, 0x01, 0x82, 0x0f, 0x02, 0x03, 0x01, 0x01, 0x02, 0x30,
+    0x72, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x6b, 0x30, 0x69, 0x30, 0x67,
+    0xa0, 0x65, 0xa0, 0x63, 0x86, 0x61, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f,
+    0x2f, 0x31, 0x39, 0x34, 0x2e, 0x32, 0x35, 0x32, 0x2e, 0x31, 0x32, 0x34,
+    0x2e, 0x32, 0x34, 0x31, 0x3a, 0x33, 0x38, 0x39, 0x2f, 0x63, 0x6e, 0x3d,
+    0x53, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x25, 0x32, 0x30, 0x43, 0x6c, 0x61,
+    0x73, 0x73, 0x32, 0x25, 0x32, 0x30, 0x43, 0x41, 0x2c, 0x6f, 0x3d, 0x53,
+    0x6f, 0x6e, 0x65, 0x72, 0x61, 0x2c, 0x63, 0x3d, 0x46, 0x49, 0x3f, 0x63,
+    0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x72, 0x65,
+    0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x6c, 0x69, 0x73, 0x74,
+    0x3b, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x30, 0x1d, 0x06, 0x03, 0x55,
+    0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+    0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+    0x03, 0x02, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
+    0x14, 0x85, 0xc2, 0x31, 0x35, 0x4f, 0x93, 0x92, 0x9d, 0x8a, 0xbc, 0x32,
+    0x7d, 0x1b, 0xf0, 0xaa, 0x96, 0xb1, 0x03, 0x86, 0x71, 0x30, 0x0d, 0x06,
+    0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,
+    0x03, 0x82, 0x01, 0x01, 0x00, 0x00, 0x9e, 0x75, 0x2b, 0x95, 0x6a, 0x96,
+    0x12, 0x24, 0xd5, 0x04, 0x6c, 0x34, 0x0a, 0x58, 0x5a, 0x7d, 0x59, 0xb9,
+    0x03, 0x23, 0x13, 0xc3, 0xf5, 0x24, 0x57, 0x33, 0x8d, 0xca, 0x5f, 0xd8,
+    0x26, 0xff, 0x64, 0x46, 0x13, 0x40, 0xe5, 0x04, 0xb2, 0xba, 0x92, 0xa5,
+    0xa6, 0xa3, 0xd9, 0x2b, 0xff, 0x05, 0xef, 0xce, 0x3c, 0x28, 0xe8, 0x1b,
+    0xa3, 0x10, 0x8a, 0xdd, 0x3d, 0x3a, 0x0a, 0xe1, 0x07, 0x3c, 0xb4, 0xf6,
+    0xbb, 0xeb, 0xb5, 0xf2, 0x05, 0xe8, 0xd7, 0x16, 0x3e, 0xe5, 0x15, 0x49,
+    0xdf, 0x8d, 0x34, 0xb8, 0x1b, 0xd4, 0xf2, 0x65, 0xa0, 0x70, 0x80, 0xd0,
+    0xbf, 0xa5, 0x74, 0x5d, 0xfb, 0xd4, 0x52, 0x3b, 0x54, 0xca, 0x32, 0xba,
+    0xf7, 0xe3, 0x90, 0xa5, 0xa8, 0xad, 0xd0, 0xe5, 0x5d, 0x18, 0x18, 0x87,
+    0x60, 0xb0, 0xf3, 0xf9, 0x62, 0x20, 0x77, 0xaa, 0x0f, 0xdd, 0x16, 0x4c,
+    0x01, 0x3a, 0xb1, 0x1f, 0x85, 0x7e, 0x01, 0x04, 0x5f, 0xf1, 0x37, 0x36,
+    0xe3, 0x3a, 0xc1, 0xa3, 0x7c, 0x33, 0xca, 0xce, 0x0b, 0xb9, 0x34, 0xe2,
+    0xe1, 0xe6, 0xed, 0x24, 0xc1, 0xc3, 0xc7, 0x74, 0x8f, 0x22, 0x2c, 0x6e,
+    0xcb, 0x5c, 0x7a, 0x61, 0x99, 0xde, 0xea, 0x13, 0xe1, 0xa8, 0xa1, 0x94,
+    0xd0, 0x85, 0x65, 0x65, 0xed, 0x97, 0x14, 0x6e, 0x97, 0xc9, 0xcf, 0x34,
+    0x7c, 0xf2, 0x68, 0xeb, 0xc2, 0x7d, 0x03, 0x53, 0xf5, 0xdb, 0xa1, 0x11,
+    0x8d, 0xda, 0xcc, 0x26, 0x13, 0xaa, 0x43, 0x76, 0x04, 0x9b, 0x85, 0x89,
+    0xc3, 0x29, 0xd8, 0xb5, 0x54, 0x81, 0x09, 0xf5, 0x18, 0x52, 0xa5, 0x38,
+    0x4a, 0x00, 0xc6, 0x1d, 0x4d, 0x5a, 0x15, 0xa0, 0xfd, 0xf7, 0x58, 0x27,
+    0xcd, 0x6b, 0x56, 0x6b, 0xee, 0x7d, 0x73, 0xd3, 0xfd, 0x6c, 0xb6, 0xb1,
+    0x3b, 0xbd, 0xbf, 0x5b, 0x4a, 0x6c, 0xd3, 0x1c, 0x47
+};
+
+
+/* Test basic add delete update copy matching stuff. */
+static void tests(void)
+{
+    SecTrustRef trust;
+       SecCertificateRef cert0, cert1;
+       isnt(cert0 = SecCertificateCreateWithBytes(NULL, _c0, sizeof(_c0)),
+               NULL, "create cert0");
+       isnt(cert1 = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)),
+               NULL, "create cert1");
+       const void *v_certs[] = {
+               cert0,
+               cert1
+       };
+    SecPolicyRef policy = SecPolicyCreateSSL(false, NULL);
+    CFArrayRef certs = CFArrayCreate(NULL, v_certs,
+               array_size(v_certs), NULL);
+
+    /* SecTrustCreateWithCertificates using single cert. */
+    ok_status(SecTrustCreateWithCertificates(cert0, policy, &trust),
+        "create trust with single cert0");
+    is(SecTrustGetCertificateCount(trust), 1, "cert count is 1");
+    is(SecTrustGetCertificateAtIndex(trust, 0), cert0, "cert 0 is leaf");
+    CFReleaseNull(trust);
+
+    /* SecTrustCreateWithCertificates failures. */
+    is_status(SecTrustCreateWithCertificates(kCFBooleanTrue, policy, &trust),
+        errSecParam, "create trust with boolean instead of cert");
+    is_status(SecTrustCreateWithCertificates(cert0, kCFBooleanTrue, &trust),
+        errSecParam, "create trust with boolean instead of policy");
+
+    /* SecTrustCreateWithCertificates using array of certs. */
+    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust");
+    /* NOTE: prior to <rdar://11810677 SecTrustGetCertificateCount would return 1 at this point.
+     * Now, however, we do an implicit SecTrustEvaluate to build the chain if it has not yet been
+     * evaluated, so we now expect the full chain length.
+     */
+    is(SecTrustGetCertificateCount(trust), 3, "cert count is 3");
+    is(SecTrustGetCertificateAtIndex(trust, 0), cert0, "cert 0 is leaf");
+
+       /* Jan 1st 2006. */
+       CFDateRef date = CFDateCreate(NULL, 157680000.0);
+    ok_status(SecTrustSetVerifyDate(trust, date), "set date");
+
+    is(SecTrustGetVerifyTime(trust), 157680000.0, "get date");
+
+       SecTrustResultType trustResult;
+
+SKIP: {
+#ifdef NO_SERVER
+    skip("Can't fail to connect to securityd in NO_SERVER mode", 4, false);
+#endif
+    // Test Restore OS environment
+    SecServerSetMachServiceName("com.apple.security.doesn't-exist");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust without securityd running");
+    is_status(trustResult, kSecTrustResultInvalid, "trustResult is kSecTrustResultInvalid");
+       is(SecTrustGetCertificateCount(trust), 1, "cert count is 1 without securityd running");
+    SecKeyRef pubKey = NULL;
+    ok(pubKey = SecTrustCopyPublicKey(trust), "copy public key without securityd running");
+    CFReleaseNull(pubKey);
+    SecServerSetMachServiceName(NULL);
+    // End of Restore OS environment tests
+}
+
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultUnspecified,
+               "trustResult is kSecTrustResultUnspecified");
+
+       is(SecTrustGetCertificateCount(trust), 3, "cert count is 3");
+
+       CFDataRef c0_serial = CFDataCreate(NULL, _c0_serial, sizeof(_c0_serial));
+       CFDataRef serial;
+       ok(serial = SecCertificateCopySerialNumber(cert0), "copy cert0 serial");
+       ok(CFEqual(c0_serial, serial), "serial matches");
+
+    CFArrayRef anchors = CFArrayCreate(NULL, (const void **)&cert1, 1, &kCFTypeArrayCallBacks);
+    ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set anchors");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultUnspecified,
+               "trust is kSecTrustResultUnspecified");
+       is(SecTrustGetCertificateCount(trust), 2, "cert count is 2");
+
+       CFReleaseSafe(anchors);
+    anchors = CFArrayCreate(NULL, NULL, 0, NULL);
+    ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set empty anchors list");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultRecoverableTrustFailure,
+               "trust is kSecTrustResultRecoverableTrustFailure");
+
+       ok_status(SecTrustSetAnchorCertificatesOnly(trust, false), "trust passed in anchors and system anchors");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultUnspecified,
+               "trust is kSecTrustResultUnspecified");
+
+       ok_status(SecTrustSetAnchorCertificatesOnly(trust, true), "only trust passed in anchors (default)");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultRecoverableTrustFailure,
+               "trust is kSecTrustResultRecoverableTrustFailure");
+
+    /* Test cert_1 intermididate from the keychain. */
+    CFReleaseSafe(trust);
+    ok_status(SecTrustCreateWithCertificates(cert0, policy, &trust),
+              "create trust with single cert0");
+    ok_status(SecTrustSetVerifyDate(trust, date), "set date");
+
+    // Add cert1
+    CFDictionaryRef query = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
+        kSecClass, kSecClassCertificate, kSecValueRef, cert1, NULL);
+    ok_status(SecItemAdd(query, NULL), "add cert1 to keychain");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    // Cleanup added cert1.
+    ok_status(SecItemDelete(query), "remove cert1 from keychain");
+    CFReleaseSafe(query);
+    is_status(trustResult, kSecTrustResultUnspecified,
+              "trust is kSecTrustResultUnspecified");
+       is(SecTrustGetCertificateCount(trust), 3, "cert count is 3");
+
+    /* Set certs to be the xedge2 leaf. */
+       CFReleaseSafe(certs);
+       const void *cert_xedge2;
+       isnt(cert_xedge2 = SecCertificateCreateWithBytes(NULL, xedge2_certificate,
+        sizeof(xedge2_certificate)), NULL, "create cert_xedge2");
+    certs = CFArrayCreate(NULL, &cert_xedge2, 1, NULL);
+
+       CFReleaseSafe(trust);
+       CFReleaseSafe(policy);
+       CFReleaseSafe(date);
+    bool server = true;
+    policy = SecPolicyCreateSSL(server, CFSTR("xedge2.apple.com"));
+    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
+        "create trust for ssl server xedge2.apple.com");
+    /* Jan 1st 2009. */
+    date = CFDateCreate(NULL, 252288000.0);
+    ok_status(SecTrustSetVerifyDate(trust, date), "set xedge2 trust date to Jan 1st 2009");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust");
+    is_status(trustResult, kSecTrustResultUnspecified,
+               "trust is kSecTrustResultUnspecified");
+
+       CFReleaseSafe(trust);
+       CFReleaseSafe(policy);
+    server = false;
+    policy = SecPolicyCreateSSL(server, CFSTR("xedge2.apple.com"));
+    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
+        "create trust for ssl client xedge2.apple.com");
+    ok_status(SecTrustSetVerifyDate(trust, date), "set xedge2 trust date to Jan 1st 2009");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust");
+    is_status(trustResult, kSecTrustResultRecoverableTrustFailure,
+               "trust is kSecTrustResultRecoverableTrustFailure");
+
+       CFReleaseSafe(trust);
+       CFReleaseSafe(policy);
+    server = true;
+    policy = SecPolicyCreateIPSec(server, CFSTR("xedge2.apple.com"));
+    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
+        "create trust for ip server xedge2.apple.com");
+    ok_status(SecTrustSetVerifyDate(trust, date), "set xedge2 trust date to Jan 1st 2009");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust");
+#if 0
+    /* Although this shouldn't be a valid ipsec cert, since we no longer
+       check for ekus in the ipsec policy it is. */
+    is_status(trustResult, kSecTrustResultRecoverableTrustFailure,
+               "trust is kSecTrustResultRecoverableTrustFailure");
+#else
+    is_status(trustResult, kSecTrustResultUnspecified,
+               "trust is kSecTrustResultUnspecified");
+#endif
+
+       CFReleaseSafe(trust);
+       CFReleaseSafe(policy);
+    server = true;
+    policy = SecPolicyCreateSSL(server, CFSTR("nowhere.com"));
+    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
+        "create trust for ssl server nowhere.com");
+    SecPolicyRef replacementPolicy = SecPolicyCreateSSL(server, CFSTR("xedge2.apple.com"));
+    SecTrustSetPolicies(trust, replacementPolicy);
+    CFReleaseSafe(replacementPolicy);
+    ok_status(SecTrustSetVerifyDate(trust, date), "set xedge2 trust date to Jan 1st 2009");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust");
+    is_status(trustResult, kSecTrustResultUnspecified,
+               "trust is kSecTrustResultUnspecified");
+
+       CFReleaseSafe(trust);
+       CFReleaseSafe(policy);
+    server = true;
+    policy = SecPolicyCreateSSL(server, CFSTR("nowhere.com"));
+    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
+        "create trust for ssl server nowhere.com");
+    SecPolicyRef replacementPolicy2 = SecPolicyCreateSSL(server, CFSTR("xedge2.apple.com"));
+    CFArrayRef replacementPolicies = CFArrayCreate(kCFAllocatorDefault, (CFTypeRef*)&replacementPolicy2, 1, &kCFTypeArrayCallBacks);
+    SecTrustSetPolicies(trust, replacementPolicies);
+    CFReleaseSafe(replacementPolicy2);
+    CFReleaseSafe(replacementPolicies);
+    ok_status(SecTrustSetVerifyDate(trust, date), "set xedge2 trust date to Jan 1st 2009");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust");
+    is_status(trustResult, kSecTrustResultUnspecified,
+               "trust is kSecTrustResultUnspecified");
+
+    /* Test self signed ssl cert with cert itself set as anchor. */
+       CFReleaseSafe(trust);
+       CFReleaseSafe(policy);
+       CFReleaseSafe(certs);
+       CFReleaseSafe(date);
+       const void *garthc2;
+    server = true;
+       isnt(garthc2 = SecCertificateCreateWithBytes(NULL, garthc2_certificate,
+        sizeof(garthc2_certificate)), NULL, "create garthc2");
+    certs = CFArrayCreate(NULL, &garthc2, 1, NULL);
+    policy = SecPolicyCreateSSL(server, CFSTR("garthc2.apple.com"));
+    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
+        "create trust for ip server garthc2.apple.com");
+    date = CFDateCreate(NULL, 269568000.0);
+    ok_status(SecTrustSetVerifyDate(trust, date),
+        "set garthc2 trust date to Aug 2009");
+    ok_status(SecTrustSetAnchorCertificates(trust, certs),
+        "set garthc2 as anchor");
+    ok_status(SecTrustEvaluate(trust, &trustResult),
+        "evaluate self signed cert with cert as anchor");
+    is_status(trustResult, kSecTrustResultUnspecified,
+               "trust is kSecTrustResultUnspecified");
+
+       CFReleaseSafe(garthc2);
+       CFReleaseSafe(cert_xedge2);
+       CFReleaseSafe(anchors);
+       CFReleaseSafe(trust);
+       CFReleaseSafe(serial);
+       CFReleaseSafe(c0_serial);
+       CFReleaseSafe(policy);
+       CFReleaseSafe(certs);
+       CFReleaseSafe(cert0);
+       CFReleaseSafe(cert1);
+       CFReleaseSafe(date);
+    
+    /* Test prt_forest_fi */
+    const void *prt_forest_fi;
+    isnt(prt_forest_fi = SecCertificateCreateWithBytes(NULL, prt_forest_fi_certificate,
+                                                sizeof(prt_forest_fi_certificate)), NULL, "create prt_forest_fi");
+    isnt(certs = CFArrayCreate(NULL, &prt_forest_fi, 1, NULL), NULL, "failed to create cert array");
+    policy = SecPolicyCreateSSL(false, CFSTR("owa.prt-forest.fi"));
+    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
+             "create trust for ip client owa.prt-forest.fi");
+    date = CFDateCreate(NULL, 391578321.0);
+    ok_status(SecTrustSetVerifyDate(trust, date),
+             "set owa.prt-forest.fi trust date to May 2013");
+    
+    SecKeyRef pubkey = SecTrustCopyPublicKey(trust);
+    is(pubkey, NULL, "pubkey returned");
+    
+       CFReleaseSafe(certs);
+    CFReleaseNull(prt_forest_fi);
+    CFReleaseNull(policy);
+    CFReleaseNull(trust);
+    CFReleaseNull(pubkey);
+    CFReleaseNull(date);
+
+}
+
+int si_20_sectrust(int argc, char *const *argv)
+{
+       plan_tests(73);
+
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-21-sectrust-asr.c b/sec/Security/Regressions/secitem/si-21-sectrust-asr.c
new file mode 100644 (file)
index 0000000..2ea8d13
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ *  si-21-sectrust-asr.c
+ *  Security
+ *
+ *  Copyright (c) 2009-2010 Apple Inc.. All Rights Reserved.
+ *
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecPolicyPriv.h>
+#include <Security/SecTrust.h>
+#include <Security/SecKey.h>
+#include <Security/SecInternal.h>
+#include <CommonCrypto/CommonDigest.h>
+#include <CommonCrypto/CommonDigestSPI.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "Security_regressions.h"
+
+static const UInt8 sITunesStoreRootCertificate[] =
+{
+       0x30, 0x82, 0x04, 0x65, 0x30, 0x82, 0x03, 0x4d, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00,
+       0xcb, 0x06, 0xa3, 0x3b, 0x30, 0xc3, 0x24, 0x03, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+       0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x7e, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
+       0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x15,
+       0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0c, 0x69, 0x54, 0x75, 0x6e, 0x65, 0x73, 0x20,
+       0x53, 0x74, 0x6f, 0x72, 0x65, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11,
+       0x69, 0x54, 0x75, 0x6e, 0x65, 0x73, 0x20, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x20, 0x52, 0x6f, 0x6f,
+       0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
+       0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72,
+       0x6e, 0x69, 0x61, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, 0x75,
+       0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x37, 0x31, 0x30, 0x30,
+       0x39, 0x31, 0x37, 0x35, 0x31, 0x33, 0x30, 0x5a, 0x17, 0x0d, 0x33, 0x32, 0x31, 0x30, 0x30, 0x32,
+       0x31, 0x37, 0x35, 0x31, 0x33, 0x30, 0x5a, 0x30, 0x7e, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
+       0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x15,
+       0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0c, 0x69, 0x54, 0x75, 0x6e, 0x65, 0x73, 0x20,
+       0x53, 0x74, 0x6f, 0x72, 0x65, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11,
+       0x69, 0x54, 0x75, 0x6e, 0x65, 0x73, 0x20, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x20, 0x52, 0x6f, 0x6f,
+       0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
+       0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72,
+       0x6e, 0x69, 0x61, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, 0x75,
+       0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+       0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30,
+       0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa9, 0x78, 0xc0, 0xaf, 0x1a, 0x96, 0x59, 0xad,
+       0xf8, 0x3c, 0x16, 0xe1, 0xfc, 0xc4, 0x7a, 0xaf, 0xf0, 0x80, 0xed, 0x7f, 0x3a, 0xff, 0xf2, 0x2a,
+       0xb6, 0xf3, 0x1a, 0xdd, 0xbd, 0x14, 0xb1, 0x5d, 0x9d, 0x66, 0xaf, 0xc7, 0xaf, 0x2b, 0x26, 0x78,
+       0x9c, 0xb8, 0x0b, 0x41, 0x9c, 0xdc, 0x17, 0xf1, 0x40, 0x18, 0x09, 0xa1, 0x0a, 0xbc, 0x01, 0x9a,
+       0x0c, 0xbe, 0x89, 0xdb, 0x9d, 0x34, 0xc7, 0x52, 0x8a, 0xf2, 0xbf, 0x35, 0x2b, 0x24, 0x04, 0xb0,
+       0x0c, 0x9d, 0x41, 0x7d, 0x63, 0xe3, 0xad, 0xcf, 0x8b, 0x34, 0xbf, 0x5c, 0x42, 0x82, 0x9b, 0x78,
+       0x7f, 0x00, 0x10, 0x88, 0xd9, 0xfd, 0xf8, 0xbf, 0x63, 0x2c, 0x91, 0x87, 0x03, 0xda, 0xbc, 0xc6,
+       0x71, 0x2b, 0x9a, 0x21, 0x30, 0x95, 0xd6, 0x88, 0xe8, 0xbd, 0x0a, 0x74, 0xa4, 0xa6, 0x39, 0xd0,
+       0x61, 0xd3, 0xb6, 0xe0, 0x2b, 0x1e, 0xe4, 0x78, 0x5c, 0x70, 0x32, 0x66, 0x97, 0x34, 0xa9, 0x79,
+       0xfc, 0x96, 0xaf, 0x4b, 0x8a, 0xd5, 0x12, 0x07, 0x8c, 0x1c, 0xf6, 0x3e, 0x5f, 0xdc, 0x8f, 0x92,
+       0x10, 0xe8, 0x7e, 0xa0, 0x14, 0x1e, 0x61, 0x28, 0xfa, 0xcc, 0xcf, 0x3c, 0xdb, 0x2b, 0xe3, 0xe9,
+       0x44, 0x4a, 0x9d, 0x5f, 0x92, 0x3d, 0xa3, 0xfd, 0x1a, 0x63, 0xb4, 0xbb, 0xab, 0x67, 0x45, 0xc6,
+       0x4d, 0x84, 0x4a, 0xaa, 0x33, 0xe4, 0xde, 0xd3, 0x04, 0x92, 0xbf, 0xf7, 0x00, 0x48, 0x76, 0xc6,
+       0x4e, 0x17, 0xea, 0x70, 0xdb, 0x09, 0xbc, 0x22, 0x07, 0x7b, 0x97, 0x49, 0xe5, 0x29, 0xa7, 0x1a,
+       0x04, 0xd2, 0x0d, 0x0e, 0x73, 0xf1, 0x49, 0x43, 0x34, 0x35, 0x61, 0xe5, 0x67, 0xdf, 0x3c, 0x58,
+       0x42, 0x51, 0xfb, 0xc3, 0xa4, 0x15, 0x6d, 0x39, 0x6b, 0x2a, 0x22, 0xde, 0xdd, 0xe2, 0x36, 0x5b,
+       0xd7, 0x37, 0x53, 0x96, 0x9d, 0x3a, 0x9f, 0x4b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xe5,
+       0x30, 0x81, 0xe2, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xb0, 0xda,
+       0xe1, 0x7f, 0xa8, 0x8b, 0x4a, 0x6a, 0x81, 0x5d, 0x0c, 0xa1, 0x84, 0x56, 0x46, 0x1e, 0x6a, 0xef,
+       0xe5, 0xcf, 0x30, 0x81, 0xb2, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0xaa, 0x30, 0x81, 0xa7,
+       0x80, 0x14, 0xb0, 0xda, 0xe1, 0x7f, 0xa8, 0x8b, 0x4a, 0x6a, 0x81, 0x5d, 0x0c, 0xa1, 0x84, 0x56,
+       0x46, 0x1e, 0x6a, 0xef, 0xe5, 0xcf, 0xa1, 0x81, 0x83, 0xa4, 0x81, 0x80, 0x30, 0x7e, 0x31, 0x13,
+       0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49,
+       0x6e, 0x63, 0x2e, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0c, 0x69, 0x54,
+       0x75, 0x6e, 0x65, 0x73, 0x20, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03,
+       0x55, 0x04, 0x03, 0x13, 0x11, 0x69, 0x54, 0x75, 0x6e, 0x65, 0x73, 0x20, 0x53, 0x74, 0x6f, 0x72,
+       0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+       0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x43, 0x61,
+       0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
+       0x07, 0x13, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x82, 0x09, 0x00, 0xcb,
+       0x06, 0xa3, 0x3b, 0x30, 0xc3, 0x24, 0x03, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05,
+       0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+       0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x7b, 0xcc, 0xfb, 0x34, 0x4e, 0xec, 0x27,
+       0x05, 0xf9, 0x10, 0xc9, 0xdf, 0x8e, 0x22, 0x21, 0x94, 0x70, 0xe9, 0x74, 0x64, 0x11, 0xce, 0x07,
+       0x91, 0xc2, 0x58, 0x0d, 0xff, 0x51, 0x6d, 0x97, 0x64, 0x32, 0x1a, 0x1c, 0xdf, 0x4a, 0x93, 0xdb,
+       0x94, 0x62, 0x14, 0xcb, 0x00, 0x13, 0x37, 0x98, 0x0e, 0x3d, 0x96, 0x19, 0x5f, 0x44, 0xc9, 0x11,
+       0xd2, 0xc9, 0x8c, 0xa3, 0x19, 0x2f, 0x88, 0x4f, 0x5f, 0x3c, 0x46, 0x56, 0xe2, 0xbd, 0x78, 0x4f,
+       0xfe, 0x8e, 0x39, 0xb5, 0xed, 0x37, 0x3e, 0xfb, 0xf6, 0xae, 0x56, 0x2c, 0x49, 0x37, 0x4a, 0x94,
+       0x05, 0x4b, 0x8f, 0x67, 0xdb, 0xe6, 0x24, 0xa6, 0x75, 0xae, 0xc8, 0xa2, 0x26, 0x87, 0x70, 0xb8,
+       0x1d, 0xc2, 0xfc, 0x8d, 0xff, 0x41, 0x23, 0x8a, 0x01, 0x8a, 0xc3, 0x78, 0x5a, 0x61, 0x4a, 0xed,
+       0x48, 0x96, 0xb5, 0x82, 0xa7, 0xaa, 0x2e, 0xb5, 0xed, 0xdd, 0xf4, 0xe6, 0xb5, 0xa1, 0x27, 0x3b,
+       0xda, 0xf9, 0x18, 0x26, 0x7e, 0x8e, 0xec, 0xef, 0xe1, 0x00, 0x7d, 0x3d, 0xf7, 0x3d, 0x01, 0x68,
+       0x14, 0x92, 0xfc, 0x9c, 0xbb, 0x0a, 0xa1, 0xc3, 0x60, 0x31, 0x16, 0x08, 0x9b, 0xef, 0x4d, 0xaf,
+       0x46, 0xc7, 0xcc, 0x4e, 0x05, 0x34, 0xa8, 0x44, 0xb2, 0x85, 0x03, 0x67, 0x6c, 0x31, 0xae, 0xa3,
+       0x18, 0xb5, 0x5f, 0x75, 0xae, 0xe0, 0x5a, 0xbf, 0x64, 0x32, 0x2b, 0x28, 0x99, 0x24, 0xcd, 0x01,
+       0x34, 0xc2, 0xfc, 0xf1, 0x88, 0xba, 0x8c, 0x9b, 0x90, 0x85, 0x56, 0x6d, 0xaf, 0xd5, 0x2e, 0x88,
+       0x12, 0x61, 0x7c, 0x76, 0x33, 0x6b, 0xc4, 0xf7, 0x31, 0x77, 0xe4, 0x02, 0xb7, 0x9e, 0x9c, 0x8c,
+       0xbe, 0x04, 0x2e, 0x51, 0xa3, 0x04, 0x4c, 0xcd, 0xe2, 0x71, 0x5e, 0x36, 0xfb, 0xf1, 0x68, 0xf0,
+       0xad, 0x37, 0x80, 0x98, 0x26, 0xc0, 0xef, 0x9b, 0x3c
+};
+
+static const unsigned char url_bag[] =
+"<plist version=\"1.0\">"
+"        <dict>"
+"        <key>signature</key>"
+"        <data>IIHLRC69w8K+iJQYKEh5U1wo/H2+U27lFzQlLrUWZIqBkd2rvUOcxBJlAG/5rCnq/mNwfhvrRZjpBzC9FzzH4a1mImPPGBYQtkD2pw/deJ67jPymyDlseH85grcDBgbRYaTR4+pbr4XTsMyQ1wEEF8OExKw9pNfHu1XyLg4iS3A=</data>"
+"        <key>certs</key>"
+"        <array>"
+"            <data>MIIDOTCCAiGgAwIBAgIBATANBgkqhkiG9w0BAQQFADB+MRMwEQYDVQQKEwpBcHBsZSBJbmMuMRUwEwYDVQQLEwxpVHVuZXMgU3RvcmUxGjAYBgNVBAMTEWlUdW5lcyBTdG9yZSBSb290MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTESMBAGA1UEBxMJQ3VwZXJ0aW5vMB4XDTA3MTAwOTIxNTkxNFoXDTA4MTEwNzIxNTkxNFowgYExEzARBgNVBAoTCkFwcGxlIEluYy4xFTATBgNVBAsTDGlUdW5lcyBTdG9yZTEdMBsGA1UEAxMUaVR1bmVzIFN0b3JlIFVSTCBCYWcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQHEwlDdXBlcnRpbm8wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOLMu/eV+eSLVEGtn536FkXAsi/vtpXdHpTNS9muEVlvlkubKXdPDd5jV5WnQpAKY4GZrBn8azP9UKBd85nhIb5nqHQHCmH5DpBK9GZPFpoIdXguJSre8pZwQaYEXQGtTt3nXvk9k8OHs5W/9xFLuD7fpkKSIl+0KLPFULdyEtlvAgMBAAGjQjBAMB0GA1UdDgQWBBTd4gDjfN3LFr3b5G8dvUTpC56JZTAfBgNVHSMEGDAWgBSw2uF/qItKaoFdDKGEVkYeau/lzzANBgkqhkiG9w0BAQQFAAOCAQEAIDpkK1CqTNyl7SEZWvUTRYPdZzn9Y4QjnbSQ6hFkF/PClJkXn3TzMW3ojnxNLphKZxOY53s6D/Hf1B5UX2bJDAnfQ/W8d10SPubGJ1FnUZK8KaKeOzAgks5ob9dnOUe4CZKhZ5FyggIJfgd38Q0s8WF474j5OA/5XRPczgjt+OiIfzEVX5Xqpm1TU7T4013eHze5umqAsd9fFxUXdTC+bl9xdj5VOmqUUfOivoiqiBK2/6XAaDIFF/PEnxVou+BpqkdsyTZz/HiQApve+7NONqS58ciq3Ov+wivpVJKxMyFgcXFWb/d2ZTc04i+fGf0OA4QmkSRcAZOxQkv0oggtTw==</data>"
+"        </array>"
+"        <key>bag</key>"
+"        <data>PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBwbGlzdCBQVUJMSUMgIi0vL0FwcGxlIENvbXB1dGVyLy9EVEQgUExJU1QgMS4wLy9FTiIgImh0dHA6Ly93d3cuYXBwbGUuY29tL0RURHMvUHJvcGVydHlMaXN0LTEuMC5kdGQiPiAKCiAgPHBsaXN0IHZlcnNpb249IjEuMCI+CiAgICA8ZGljdD4KICAgICAgCiAgICAgIAogICAgICAKICAgICAgCiAgICAgICAgPGtleT5zdG9yZUZyb250PC9rZXk+PHN0cmluZz5odHRwOi8vYXgucGhvYm9zLmFwcGxlLmNvbS5lZGdlc3VpdGUubmV0L1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2Evc3RvcmVGcm9udDwvc3RyaW5nPgogICAgPGtleT5uZXdVc2VyU3RvcmVGcm9udDwva2V5PjxzdHJpbmc+aHR0cDovL3Bob2Jvcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS9maXJzdExhdW5jaDwvc3RyaW5nPgogICAgPGtleT5uZXdJUG9kVXNlclN0b3JlRnJvbnQ8L2tleT48c3RyaW5nPmh0dHA6Ly9heC5waG9ib3MuYXBwbGUuY29tLmVkZ2VzdWl0ZS5uZXQvV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS9uZXdJUG9kVXNlcj9uZXdJUG9kVXNlcj10cnVlPC9zdHJpbmc+CiAgICA8a2V5Pm5ld1Bob25lVXNlcjwva2V5PjxzdHJpbmc+aHR0cDovL2F4LnBob2Jvcy5hcHBsZS5jb20uZWRnZXN1aXRlLm5ldC9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL3Bob25lTGFuZGluZ1BhZ2U8L3N0cmluZz4gICAgICAgICAgICAgICAgICAKICAgIDxrZXk+c2VhcmNoPC9rZXk+PHN0cmluZz5odHRwOi8vYXgucGhvYm9zLmFwcGxlLmNvbS5lZGdlc3VpdGUubmV0L1dlYk9iamVjdHMvTVpTZWFyY2gud29hL3dhL3NlYXJjaDwvc3RyaW5nPgogICAgPGtleT5hZHZhbmNlZFNlYXJjaDwva2V5PjxzdHJpbmc+aHR0cDovL2F4LnBob2Jvcy5hcHBsZS5jb20uZWRnZXN1aXRlLm5ldC9XZWJPYmplY3RzL01aU2VhcmNoLndvYS93YS9hZHZhbmNlZFNlYXJjaDwvc3RyaW5nPgogICAgPGtleT5zZWFyY2hIaW50czwva2V5PjxzdHJpbmc+aHR0cDovL2F4LnBob2Jvcy5hcHBsZS5jb20uZWRnZXN1aXRlLm5ldC9XZWJPYmplY3RzL01aU2VhcmNoSGludHMud29hL3dhL2hpbnRzPC9zdHJpbmc+CiAgICA8a2V5PnBhcmVudGFsQWR2aXNvcnk8L2tleT48c3RyaW5nPmh0dHA6Ly9heC5waG9ib3MuYXBwbGUuY29tLmVkZ2VzdWl0ZS5uZXQvV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS9wYXJlbnRhbEFkdmlzb3J5PC9zdHJpbmc+CiAgICA8a2V5PnNvbmdNZXRhRGF0YTwva2V5PjxzdHJpbmc+aHR0cDovL2F4LnBob2Jvcy5hcHBsZS5jb20uZWRnZXN1aXRlLm5ldC9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL3NvbmdNZXRhRGF0YTwvc3RyaW5nPgogICAgPGtleT5icm93c2U8L2tleT48c3RyaW5nPmh0dHA6Ly9heC5waG9ib3MuYXBwbGUuY29tLmVkZ2VzdWl0ZS5uZXQvV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS9icm93c2U8L3N0cmluZz4KICAgIDxrZXk+YnJvd3NlU3RvcmU8L2tleT48c3RyaW5nPmh0dHA6Ly9heC5waG9ib3MuYXBwbGUuY29tLmVkZ2VzdWl0ZS5uZXQvV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS9icm93c2VTdG9yZTwvc3RyaW5nPgogICAgPGtleT5icm93c2VHZW5yZTwva2V5PjxzdHJpbmc+aHR0cDovL2F4LnBob2Jvcy5hcHBsZS5jb20uZWRnZXN1aXRlLm5ldC9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL2Jyb3dzZUdlbnJlPC9zdHJpbmc+CiAgICA8a2V5PmJyb3dzZUFydGlzdDwva2V5PjxzdHJpbmc+aHR0cDovL2F4LnBob2Jvcy5hcHBsZS5jb20uZWRnZXN1aXRlLm5ldC9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL2Jyb3dzZUFydGlzdDwvc3RyaW5nPgogICAgPGtleT5icm93c2VBbGJ1bTwva2V5PjxzdHJpbmc+aHR0cDovL2F4LnBob2Jvcy5hcHBsZS5jb20uZWRnZXN1aXRlLm5ldC9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL2Jyb3dzZUFsYnVtPC9zdHJpbmc+CiAgICA8a2V5PnZpZXdBbGJ1bTwva2V5PjxzdHJpbmc+aHR0cDovL2F4LnBob2Jvcy5hcHBsZS5jb20uZWRnZXN1aXRlLm5ldC9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL3ZpZXdBbGJ1bTwvc3RyaW5nPgogICAgPGtleT52aWV3QXJ0aXN0PC9rZXk+PHN0cmluZz5odHRwOi8vYXgucGhvYm9zLmFwcGxlLmNvbS5lZGdlc3VpdGUubmV0L1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2Evdmlld0FydGlzdDwvc3RyaW5nPgogICAgPGtleT52aWV3Q29tcG9zZXI8L2tleT48c3RyaW5nPmh0dHA6Ly9heC5waG9ib3MuYXBwbGUuY29tLmVkZ2VzdWl0ZS5uZXQvV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS92aWV3Q29tcG9zZXI8L3N0cmluZz4KICAgIDxrZXk+dmlld0dlbnJlPC9rZXk+PHN0cmluZz5odHRwOi8vYXgucGhvYm9zLmFwcGxlLmNvbS5lZGdlc3VpdGUubmV0L1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2Evdmlld0dlbnJlPC9zdHJpbmc+CiAgICA8a2V5PnZpZXdQb2RjYXN0PC9rZXk+PHN0cmluZz5odHRwOi8vYXgucGhvYm9zLmFwcGxlLmNvbS5lZGdlc3VpdGUubmV0L1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2Evdmlld1BvZGNhc3Q8L3N0cmluZz4KICAgIDxrZXk+dmlld1B1Ymxpc2hlZFBsYXlsaXN0PC9rZXk+PHN0cmluZz5odHRwOi8vYXgucGhvYm9zLmFwcGxlLmNvbS5lZGdlc3VpdGUubmV0L1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2Evdmlld1B1Ymxpc2hlZFBsYXlsaXN0PC9zdHJpbmc+CiAgICA8a2V5PnZpZXdWaWRlbzwva2V5PjxzdHJpbmc+aHR0cDovL2F4LnBob2Jvcy5hcHBsZS5jb20uZWRnZXN1aXRlLm5ldC9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL3ZpZXdWaWRlbzwvc3RyaW5nPgogICAgPGtleT5wb2RjYXN0czwva2V5PjxzdHJpbmc+aHR0cDovL2F4LnBob2Jvcy5hcHBsZS5jb20uZWRnZXN1aXRlLm5ldC9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL3ZpZXdQb2RjYXN0RGlyZWN0b3J5PC9zdHJpbmc+CiAgICA8a2V5PmV4dGVybmFsVVJMU2VhcmNoS2V5PC9rZXk+PHN0cmluZz5heC5waG9ib3MuYXBwbGUuY29tLmVkZ2VzdWl0ZS5uZXQ8L3N0cmluZz4KICAgIDxrZXk+ZXh0ZXJuYWxVUkxSZXBsYWNlS2V5PC9rZXk+PHN0cmluZz5waG9ib3MuYXBwbGUuY29tPC9zdHJpbmc+CiAgICA8a2V5PnNlbGVjdGVkSXRlbXNQYWdlPC9rZXk+PHN0cmluZz5odHRwOi8vYXgucGhvYm9zLmFwcGxlLmNvbS5lZGdlc3VpdGUubmV0L1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2Evc2VsZWN0ZWRJdGVtc1BhZ2U8L3N0cmluZz4KCiAgICAKCiAgICAKCiAgICA8a2V5Pm1pbmktc3RvcmU8L2tleT48c3RyaW5nPmh0dHA6Ly9heC5waG9ib3MuYXBwbGUuY29tLmVkZ2VzdWl0ZS5uZXQvV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS9taW5pc3RvcmVWMjwvc3RyaW5nPgogICAgPGtleT5taW5pLXN0b3JlLWZpZWxkczwva2V5PjxzdHJpbmc+YSxraW5kLHA8L3N0cmluZz4KICAgIDxrZXk+bWluaS1zdG9yZS1tYXRjaDwva2V5PjxzdHJpbmc+aHR0cDovL2F4LnBob2Jvcy5hcHBsZS5jb20uZWRnZXN1aXRlLm5ldC9XZWJPYmplY3RzL01aU3RvcmVTZXJ2aWNlcy53b2Evd2EvbWluaXN0b3JlTWF0Y2hWMjwvc3RyaW5nPgogICAgPGtleT5taW5pLXN0b3JlLW1hdGNoLWZpZWxkczwva2V5PjxzdHJpbmc+YW4sZ24sa2luZCxwbjwvc3RyaW5nPgogICAgPGtleT5taW5pLXN0b3JlLXdlbGNvbWU8L2tleT48c3RyaW5nPmh0dHA6Ly9heC5waG9ib3MuYXBwbGUuY29tLmVkZ2VzdWl0ZS5uZXQvV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS9taW5pc3RvcmVXZWxjb21lP3dpdGhDbGllbnRPcHRJbj0xPC9zdHJpbmc+CgogICAgPGtleT5jb3Zlci1hcnQ8L2tleT48c3RyaW5nPmh0dHA6Ly9heC5waG9ib3MuYXBwbGUuY29tLmVkZ2VzdWl0ZS5uZXQvV2ViT2JqZWN0cy9NWlN0b3JlU2VydmljZXMud29hL3dhL2NvdmVyQXJ0TWF0Y2g8L3N0cmluZz4KICAgIDxrZXk+Y292ZXItYXJ0LWZpZWxkczwva2V5PjxzdHJpbmc+YSxwPC9zdHJpbmc+CiAgICA8a2V5PmNvdmVyLWFydC1jZC1maWVsZHM8L2tleT48c3RyaW5nPmNkZGI8L3N0cmluZz4KICAgIDxrZXk+Y292ZXItYXJ0LW1hdGNoPC9rZXk+PHN0cmluZz5odHRwOi8vYXgucGhvYm9zLmFwcGxlLmNvbS5lZGdlc3VpdGUubmV0L1dlYk9iamVjdHMvTVpTdG9yZVNlcnZpY2VzLndvYS93YS9jb3ZlckFydE1hdGNoPC9zdHJpbmc+CiAgICA8a2V5PmNvdmVyLWFydC1tYXRjaC1maWVsZHM8L2tleT48c3RyaW5nPmNkZGIsYW4scG48L3N0cmluZz4KICAgIDxrZXk+Y292ZXItYXJ0LXVzZXI8L2tleT48c3RyaW5nPmh0dHA6Ly9waG9ib3MuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpQZXJzb25hbGl6ZXIud29hL3dhL2NvdmVyQXJ0VXNlcjwvc3RyaW5nPgoKICAgIDxrZXk+bWF0Y2hVUkxzPC9rZXk+PGFycmF5PjxzdHJpbmc+aHR0cDovL3Bob2Jvcy5hcHBsZS5jb20vV2ViT2JqZWN0cy88L3N0cmluZz48L2FycmF5PgoKICAgIAogICAgPGtleT5saWJyYXJ5LWxpbms8L2tleT48c3RyaW5nPmh0dHA6Ly9heC5waG9ib3MuYXBwbGUuY29tLmVkZ2VzdWl0ZS5uZXQvV2ViT2JqZWN0cy9NWlN0b3JlU2VydmljZXMud29hL3dhL2xpYnJhcnlMaW5rPC9zdHJpbmc+CiAgICAKICAgIDxrZXk+bGlicmFyeS1saW5rLWZpZWxkcy1saXN0PC9rZXk+CiAgICA8YXJyYXk+CiAgICAgIDxzdHJpbmc+YW4sY24sZ24sa2luZCxuLHBuPC9zdHJpbmc+CiAgICA8L2FycmF5PgogICAgCiAgICA8a2V5PmxpYnJhcnlMaW5rPC9rZXk+PHN0cmluZz5odHRwOi8vYXgucGhvYm9zLmFwcGxlLmNvbS5lZGdlc3VpdGUubmV0L1dlYk9iamVjdHMvTVpTdG9yZVNlcnZpY2VzLndvYS93YS9saWJyYXJ5TGluazwvc3RyaW5nPgoKICAgIAogICAgPGtleT5hdmFpbGFibGUtcmluZ3RvbmVzPC9rZXk+PHN0cmluZz5odHRwOi8vcGhvYm9zLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aUGVyc29uYWxpemVyLndvYS93YS9hdmFpbGFibGVSaW5ndG9uZXM8L3N0cmluZz4KCiAgICAKICAgIDxrZXk+Y3JlYXRlLXJpbmd0b25lPC9rZXk+PHN0cmluZz5odHRwczovL3Bob2Jvcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL2NyZWF0ZVJpbmd0b25lPC9zdHJpbmc+CiAgICA8a2V5PnJpbmd0b25lLWluZm88L2tleT48c3RyaW5nPmh0dHBzOi8vcGhvYm9zLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2EvaXNSaW5ndG9uZWFibGU8L3N0cmluZz4KICAgIDxrZXk+cmluZ3RvbmUtaW5mby1maWVsZHMtbGlzdDwva2V5PgogICAgPGFycmF5PgogICAgICAgIDxzdHJpbmc+aWQscyxkc2lkPC9zdHJpbmc+CiAgICA8L2FycmF5PgogICAgCgoKICAgIDxrZXk+bWF4Q29tcHV0ZXJzPC9rZXk+PHN0cmluZz41PC9zdHJpbmc+CiAgICA8a2V5Pm1heFB1Ymxpc2hlZFBsYXlsaXN0SXRlbXM8L2tleT48aW50ZWdlcj4xMDA8L2ludGVnZXI+CiAgICAKICAgIDxrZXk+dHJ1c3RlZERvbWFpbnM8L2tleT4KICAgIDxhcnJheT4KICAgICAgPHN0cmluZz4uYXBwbGUuY29tPC9zdHJpbmc+CiAgICAgIDxzdHJpbmc+LmFwcGxlLmNvbS5lZGdlc3VpdGUubmV0PC9zdHJpbmc+CiAgICAgIDxzdHJpbmc+c3VwcG9ydC5tYWMuY29tPC9zdHJpbmc+CiAgICAgIDxzdHJpbmc+Lml0dW5lcy5jb208L3N0cmluZz4KICAgICAgPHN0cmluZz5pdHVuZXMuY29tPC9zdHJpbmc+CiAgICA8L2FycmF5PgoKICAgIDxrZXk+cGx1cy1pbmZvPC9rZXk+PHN0cmluZz5odHRwOi8vYXgucGhvYm9zLmFwcGxlLmNvbS5lZGdlc3VpdGUubmV0L1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2EvaVR1bmVzUGx1c0xlYXJuTW9yZVBhZ2U8L3N0cmluZz4KCiAgICA8a2V5PmFwcGxldHYteW91dHViZS1hdXRoLXVybDwva2V5PjxzdHJpbmc+aHR0cHM6Ly93d3cuZ29vZ2xlLmNvbS88L3N0cmluZz4KICAgIDxrZXk+YXBwbGV0di15b3V0dWJlLXVybDwva2V5PjxzdHJpbmc+aHR0cDovL2dkYXRhLnlvdXR1YmUuY29tLzwvc3RyaW5nPgogICAgPGtleT5pdHVuZXMtcHJlc2VudHMtZGlyZWN0b3J5LXVybDwva2V5PjxzdHJpbmc+aHR0cDovL2F4LnBob2Jvcy5hcHBsZS5jb20uZWRnZXN1aXRlLm5ldC9XZWJPYmplY3RzL01aU3RvcmVTZXJ2aWNlcy53b2Evd3MvUlNTL2RpcmVjdG9yeTwvc3RyaW5nPgogICAgPGtleT5HaG9zdHJpZGVyPC9rZXk+PHN0cmluZz5ZRVM8L3N0cmluZz4KCiAgICA8a2V5PnAyLXRvcC10ZW48L2tleT48c3RyaW5nPmh0dHA6Ly9heC5waG9ib3MuYXBwbGUuY29tLmVkZ2VzdWl0ZS5uZXQvV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS92aWV3VG9wVGVuc0xpc3Q8L3N0cmluZz4KICAgIDxrZXk+cDItc2VydmljZS10ZXJtcy11cmw8L2tleT48c3RyaW5nPmh0dHA6Ly93d3cuYXBwbGUuY29tL3N1cHBvcnQvaXR1bmVzL2xlZ2FsL3Rlcm1zLmh0bWw8L3N0cmluZz4KCiAgICA8a2V5Pm5vdy1wbGF5aW5nLXVybDwva2V5PjxzdHJpbmc+aHR0cDovL2F4LnBob2Jvcy5hcHBsZS5jb20uZWRnZXN1aXRlLm5ldC9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL25vd1BsYXlpbmc8L3N0cmluZz4KICAgIDxrZXk+bm93LXBsYXlpbmctbmV0d29yay1kZXRlY3QtdXJsPC9rZXk+PHN0cmluZz5odHRwOi8vYXgucGhvYm9zLmFwcGxlLmNvbS5lZGdlc3VpdGUubmV0L1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2Evbm93UGxheWluZzwvc3RyaW5nPgogICAgPGtleT5hZGFtaWQtbG9va3VwLXVybDwva2V5PjxzdHJpbmc+aHR0cDovL2F4LnBob2Jvcy5hcHBsZS5jb20uZWRnZXN1aXRlLm5ldC9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL2FkYW1JZExvb2t1cDwvc3RyaW5nPgoKICAgIAoKICAgIAoKICAgICAgICA8a2V5PmF1dGhlbnRpY2F0ZUFjY291bnQ8L2tleT48c3RyaW5nPmh0dHBzOi8vcGhvYm9zLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2EvYXV0aGVudGljYXRlPC9zdHJpbmc+CiAgICA8a2V5PmlQaG9uZUFjdGl2YXRpb248L2tleT48c3RyaW5nPmh0dHBzOi8vYWxiZXJ0LmFwcGxlLmNvbS9XZWJPYmplY3RzL0FMQWN0aXZhdGlvbi53b2Evd2EvaVBob25lUmVnaXN0cmF0aW9uPC9zdHJpbmc+CiAgICA8a2V5PmRldmljZS1hY3RpdmF0aW9uPC9rZXk+PHN0cmluZz5odHRwczovL2FsYmVydC5hcHBsZS5jb20vV2ViT2JqZWN0cy9BTEFjdGl2YXRpb24ud29hL3dhL2RldmljZUFjdGl2YXRpb248L3N0cmluZz4KICAgIDxrZXk+YXV0aG9yaXplTWFjaGluZTwva2V5PjxzdHJpbmc+aHR0cHM6Ly9waG9ib3MuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS9hdXRob3JpemVNYWNoaW5lPC9zdHJpbmc+CiAgICA8a2V5PmJ1eVByb2R1Y3Q8L2tleT48c3RyaW5nPmh0dHBzOi8vcGhvYm9zLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2EvYnV5UHJvZHVjdDwvc3RyaW5nPgogICAgPGtleT5idXlDYXJ0PC9rZXk+PHN0cmluZz5odHRwczovL3Bob2Jvcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL2J1eUNhcnQ8L3N0cmluZz4KICAgIDxrZXk+ZGVhdXRob3JpemVNYWNoaW5lPC9rZXk+PHN0cmluZz5odHRwczovL3Bob2Jvcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL2RlYXV0aG9yaXplTWFjaGluZTwvc3RyaW5nPgogICAgPGtleT5tYWNoaW5lQXV0aG9yaXphdGlvbkluZm88L2tleT48c3RyaW5nPmh0dHBzOi8vcGhvYm9zLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmFzdEZpbmFuY2Uud29hL3dhL21hY2hpbmVBdXRob3JpemF0aW9uSW5mbzwvc3RyaW5nPgogICAgPGtleT5tb2RpZnlBY2NvdW50PC9rZXk+PHN0cmluZz5odHRwczovL3Bob2Jvcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL2FjY291bnRTdW1tYXJ5PC9zdHJpbmc+CiAgICA8a2V5PnBlbmRpbmdTb25nczwva2V5PjxzdHJpbmc+aHR0cHM6Ly9waG9ib3MuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS9wZW5kaW5nU29uZ3M8L3N0cmluZz4KICAgIDxrZXk+c2lnbnVwPC9rZXk+PHN0cmluZz5odHRwczovL3Bob2Jvcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL3NpZ251cFdpemFyZDwvc3RyaW5nPgogICAgPGtleT5zb25nRG93bmxvYWREb25lPC9rZXk+PHN0cmluZz5odHRwczovL3Bob2Jvcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZhc3RGaW5hbmNlLndvYS93YS9zb25nRG93bmxvYWREb25lPC9zdHJpbmc+CiAgICA8a2V5PmZvcmdvdHRlblBhc3N3b3JkPC9rZXk+PHN0cmluZz5odHRwczovL3Bob2Jvcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL2lGb3Jnb3Q8L3N0cmluZz4KICAgIDxrZXk+bXlJbmZvPC9rZXk+PHN0cmluZz5odHRwczovL215aW5mby5hcHBsZS5jb20vPC9zdHJpbmc+CiAgICA8a2V5Pm5vQU9MQWNjb3VudHM8L2tleT48ZmFsc2UvPgogICAgPGtleT51cGxvYWRQdWJsaXNoZWRQbGF5bGlzdDwva2V5PjxzdHJpbmc+aHR0cHM6Ly9waG9ib3MuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS91cGxvYWRQdWJsaXNoZWRQbGF5TGlzdDwvc3RyaW5nPgogICAgPGtleT5sb2dvdXQ8L2tleT48c3RyaW5nPmh0dHBzOi8vcGhvYm9zLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2EvbG9nb3V0PC9zdHJpbmc+CiAgICA8a2V5PmFkZFRvQ2FydDwva2V5PjxzdHJpbmc+aHR0cHM6Ly9waG9ib3MuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS9hZGRUb0NhcnQ8L3N0cmluZz4KICAgIDxrZXk+cmVtb3ZlRnJvbUNhcnQ8L2tleT48c3RyaW5nPmh0dHBzOi8vcGhvYm9zLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2EvcmVtb3ZlRnJvbUNhcnQ8L3N0cmluZz4KICAgIDxrZXk+c2hvcHBpbmdDYXJ0PC9rZXk+PHN0cmluZz5odHRwczovL3Bob2Jvcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL3Nob3BwaW5nQ2FydDwvc3RyaW5nPgogICAgPGtleT5iY1VSTHM8L2tleT48YXJyYXk+PHN0cmluZz5odHRwOi8vLnBob2Jvcy5hcHBsZS5jb208L3N0cmluZz48c3RyaW5nPmh0dHA6Ly93d3cuYXRkbXQuY29tPC9zdHJpbmc+PC9hcnJheT4KICAgIDxrZXk+dXBncmFkZVBob25lPC9rZXk+PHN0cmluZz5odHRwczovL3Bob2Jvcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL3VwZ3JhZGVQaG9uZTwvc3RyaW5nPgogICAgPGtleT51cGdyYWRlRHJtPC9rZXk+PHN0cmluZz5odHRwczovL3Bob2Jvcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL3VwZ3JhZGVEcm08L3N0cmluZz4KICAgIDxrZXk+cmVwb3J0UG9kY2FzdDwva2V5PjxzdHJpbmc+aHR0cHM6Ly9waG9ib3MuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS9yZXBvcnRQb2RjYXN0PC9zdHJpbmc+CiAgICA8a2V5PmdpZnRQbGF5bGlzdDwva2V5PjxzdHJpbmc+aHR0cHM6Ly9waG9ib3MuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS9naWZ0U29uZ3NXaXphcmQ8L3N0cmluZz4KICAgIDxrZXk+Z2l2ZS1wbGF5bGlzdDwva2V5PjxzdHJpbmc+aHR0cHM6Ly9waG9ib3MuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS9naWZ0U29uZ3NXaXphcmQ8L3N0cmluZz4KICAgIDxrZXk+Y2hlY2stZG93bmxvYWQtcXVldWU8L2tleT48c3RyaW5nPmh0dHBzOi8vcGhvYm9zLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2EvY2hlY2tEb3dubG9hZFF1ZXVlPC9zdHJpbmc+CiAgICA8a2V5PnNldC1hdXRvLWRvd25sb2FkPC9rZXk+PHN0cmluZz5odHRwczovL3Bob2Jvcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL3NldEF1dG9Eb3dubG9hZDwvc3RyaW5nPgogICAgPGtleT5uZXctaXBvZC11c2VyPC9rZXk+PHN0cmluZz5odHRwczovL3Bob2Jvcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL2lQb2RSZWdpc3RyYXRpb248L3N0cmluZz4KICAgIDxrZXk+bmV3LXR2LXVzZXI8L2tleT48c3RyaW5nPmh0dHBzOi8vcGhvYm9zLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2EvaVRWUmVnaXN0cmF0aW9uPC9zdHJpbmc+CiAgICA8a2V5Pm1kNS1taXNtYXRjaDwva2V5PjxzdHJpbmc+aHR0cHM6Ly9waG9ib3MuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS9tZDVNaXNtYXRjaDwvc3RyaW5nPgogICAgPGtleT5yZXBvcnQtZXJyb3I8L2tleT48c3RyaW5nPmh0dHBzOi8vcGhvYm9zLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2EvcmVwb3J0RXJyb3JGcm9tQ2xpZW50PC9zdHJpbmc+CiAgICA8a2V5PnVwZGF0ZUFzc2V0PC9rZXk+PHN0cmluZz5odHRwczovL3Bob2Jvcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL3VwZGF0ZUFzc2V0PC9zdHJpbmc+CiAgICA8a2V5PmNyZWF0ZS10b2tlbjwva2V5PjxzdHJpbmc+aHR0cHM6Ly9waG9ib3MuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS9jcmVhdGVUb2tlbjwvc3RyaW5nPgogICAgPGtleT5jcmVhdGUtc2Vzc2lvbjwva2V5PjxzdHJpbmc+aHR0cHM6Ly9waG9ib3MuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS9jcmVhdGVTZXNzaW9uPC9zdHJpbmc+CiAgICAKCiAgICAgIAogICAgICAKICAgIDwvZGljdD4KICA8L3BsaXN0PgoKCg==</data>"
+"        </dict>"
+"</plist>";
+
+/* Test basic add delete update copy matching stuff. */
+static void tests(void)
+{
+    SecTrustRef trust;
+    SecCertificateRef leaf, root;
+    SecPolicyRef policy;
+    CFDataRef urlBagData;
+       CFDictionaryRef urlBagDict;
+
+    isnt(urlBagData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, url_bag, sizeof(url_bag), kCFAllocatorNull), NULL,
+               "load url bag");
+    isnt(urlBagDict = CFPropertyListCreateWithData(kCFAllocatorDefault, urlBagData, kCFPropertyListImmutable, NULL, NULL), NULL,
+               "parse url bag");
+       CFReleaseSafe(urlBagData);
+    CFArrayRef certs_data = CFDictionaryGetValue(urlBagDict, CFSTR("certs"));
+    CFDataRef cert_data = CFArrayGetValueAtIndex(certs_data, 0);
+    isnt(leaf = SecCertificateCreateWithData(kCFAllocatorDefault, cert_data), NULL, "create leaf");
+    isnt(root = SecCertificateCreateWithBytes(kCFAllocatorDefault, sITunesStoreRootCertificate, sizeof(sITunesStoreRootCertificate)), NULL, "create root");
+
+    CFArrayRef certs = CFArrayCreate(kCFAllocatorDefault, (const void **)&leaf, 1, NULL);
+    CFDataRef signature = CFDictionaryGetValue(urlBagDict, CFSTR("signature"));
+       CFDataRef bag = CFDictionaryGetValue(urlBagDict, CFSTR("bag"));
+    unsigned char sha1_hash[CC_SHA1_DIGEST_LENGTH];
+    CCDigest(kCCDigestSHA1, CFDataGetBytePtr(bag), CFDataGetLength(bag), sha1_hash);
+
+    isnt(policy = SecPolicyCreateBasicX509(), NULL, "create policy instance");
+
+    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust for leaf");
+
+    SecTrustResultType trustResult;
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    TODO: {
+        todo("Only works in !NO_SERVER setup");
+        is_status(trustResult, kSecTrustResultOtherError,
+            "trust is kSecTrustResultOtherError");
+    }
+       SecKeyRef pub_key_leaf;
+       isnt(pub_key_leaf = SecTrustCopyPublicKey(trust), NULL, "get leaf pub key");
+       ok_status(SecKeyRawVerify(pub_key_leaf, kSecPaddingPKCS1SHA1, sha1_hash, sizeof(sha1_hash), CFDataGetBytePtr(signature), CFDataGetLength(signature)),
+               "verify signature on bag");
+
+    CFReleaseSafe(pub_key_leaf);
+       CFReleaseSafe(urlBagDict);
+    CFReleaseSafe(certs);
+    CFReleaseSafe(trust);
+    CFReleaseSafe(policy);
+    CFReleaseSafe(leaf);
+    CFReleaseSafe(root);
+}
+
+int si_21_sectrust_asr(int argc, char *const *argv)
+{
+    plan_tests(10);
+
+
+    tests();
+
+    return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-22-sectrust-iap.c b/sec/Security/Regressions/secitem/si-22-sectrust-iap.c
new file mode 100644 (file)
index 0000000..f333f6b
--- /dev/null
@@ -0,0 +1,595 @@
+/*
+ * Copyright (c) 2006-2010 Apple Inc. All Rights Reserved.
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecPolicyPriv.h>
+#include <Security/SecTrust.h>
+#include <utilities/array_size.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "Security_regressions.h"
+
+/*
+       subject= /C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple iPod Accessories Certification Authority
+       issuer= /C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Root CA
+       serial=16
+*/
+const uint8_t _iAP1CA[] = {
+    0x30, 0x82, 0x03, 0xfe, 0x30, 0x82, 0x02, 0xe6,
+    0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x16,
+    0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+    0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
+    0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+    0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
+    0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+    0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49,
+    0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06,
+    0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70,
+    0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74,
+    0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+    0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+    0x69, 0x74, 0x79, 0x31, 0x16, 0x30, 0x14, 0x06,
+    0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x41, 0x70,
+    0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74,
+    0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x30,
+    0x37, 0x30, 0x32, 0x31, 0x34, 0x32, 0x32, 0x31,
+    0x38, 0x30, 0x38, 0x5a, 0x17, 0x0d, 0x32, 0x32,
+    0x30, 0x32, 0x31, 0x34, 0x32, 0x32, 0x31, 0x38,
+    0x30, 0x38, 0x5a, 0x30, 0x81, 0x83, 0x31, 0x0b,
+    0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+    0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06,
+    0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70,
+    0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+    0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04,
+    0x0b, 0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65,
+    0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+    0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41,
+    0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
+    0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04,
+    0x03, 0x13, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x65,
+    0x20, 0x69, 0x50, 0x6f, 0x64, 0x20, 0x41, 0x63,
+    0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x69, 0x65,
+    0x73, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+    0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
+    0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
+    0x79, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06,
+    0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+    0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f,
+    0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01,
+    0x01, 0x00, 0xa1, 0xf6, 0xca, 0xdb, 0x3d, 0x4a,
+    0x5a, 0x3e, 0xef, 0x74, 0x78, 0xf1, 0xb7, 0xb0,
+    0x32, 0x82, 0x1f, 0x90, 0xc6, 0x08, 0xdf, 0xaa,
+    0x3b, 0xd2, 0xcb, 0x0f, 0xe6, 0x37, 0x13, 0xf8,
+    0xff, 0x71, 0xfc, 0x28, 0x86, 0x24, 0x36, 0x85,
+    0x3f, 0xd0, 0x1d, 0x9c, 0xd0, 0x9c, 0xb2, 0x5d,
+    0x20, 0x41, 0xdc, 0xb0, 0xd8, 0xa8, 0x86, 0x3c,
+    0x42, 0x3c, 0xbe, 0x5a, 0x48, 0xdf, 0x34, 0x74,
+    0x9a, 0x61, 0x05, 0x0d, 0xce, 0xc8, 0x25, 0x14,
+    0xc8, 0x0a, 0xcd, 0xbd, 0xba, 0x12, 0x1b, 0x3b,
+    0x41, 0x13, 0x8e, 0x38, 0x65, 0x1d, 0xac, 0x1d,
+    0xd5, 0x38, 0x95, 0x9d, 0x3a, 0xd0, 0x79, 0x5c,
+    0x66, 0x9c, 0x47, 0x4b, 0x2c, 0xb8, 0x44, 0x3b,
+    0x7e, 0x8b, 0x68, 0x39, 0x3e, 0x46, 0xc1, 0xb8,
+    0xc0, 0x85, 0xd6, 0x84, 0xfb, 0x0e, 0xa6, 0xdd,
+    0x34, 0x06, 0xda, 0x1c, 0x78, 0xd9, 0xc4, 0x63,
+    0x11, 0x1b, 0xcf, 0x20, 0x15, 0xd2, 0x7a, 0xef,
+    0x60, 0x40, 0xdf, 0xba, 0xe0, 0x05, 0x45, 0x41,
+    0x82, 0x0e, 0x9b, 0x78, 0x2d, 0x2a, 0xb4, 0x94,
+    0xb5, 0xca, 0x79, 0xcd, 0xdb, 0xb5, 0x95, 0x02,
+    0xbe, 0x55, 0x2c, 0x36, 0x21, 0xaf, 0x6e, 0x39,
+    0xb6, 0x76, 0x5a, 0xec, 0x5d, 0x6a, 0xf3, 0xcc,
+    0xfa, 0x90, 0x8a, 0x15, 0x77, 0xbb, 0xba, 0x5c,
+    0x2b, 0xa1, 0x87, 0xf8, 0x0e, 0x70, 0x5d, 0x23,
+    0x01, 0x08, 0x79, 0xef, 0xab, 0xd7, 0x91, 0x38,
+    0x81, 0x35, 0xb3, 0x07, 0xd4, 0x79, 0xa2, 0x25,
+    0xa7, 0xf7, 0x90, 0x75, 0xeb, 0xeb, 0x71, 0xa2,
+    0xd0, 0xc1, 0xab, 0x02, 0x06, 0xf9, 0x07, 0x08,
+    0x97, 0x35, 0xda, 0x7e, 0x4d, 0x61, 0x51, 0x75,
+    0x92, 0xf6, 0x19, 0xf5, 0xdf, 0xfb, 0xc9, 0xa5,
+    0x4e, 0x9b, 0x8a, 0x14, 0x11, 0x4c, 0x10, 0x74,
+    0x83, 0xaf, 0x2f, 0xfc, 0xb6, 0xd6, 0x6b, 0x57,
+    0x46, 0x1d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
+    0x81, 0x9c, 0x30, 0x81, 0x99, 0x30, 0x0e, 0x06,
+    0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04,
+    0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x0f, 0x06,
+    0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04,
+    0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d,
+    0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
+    0x14, 0xff, 0x4b, 0x1a, 0x43, 0x9a, 0xf5, 0x19,
+    0x96, 0xab, 0x18, 0x00, 0x2b, 0x61, 0xc9, 0xee,
+    0x40, 0x9d, 0x8e, 0xc7, 0x04, 0x30, 0x1f, 0x06,
+    0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
+    0x80, 0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76,
+    0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e, 0x40, 0xa6,
+    0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x36,
+    0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2f, 0x30,
+    0x2d, 0x30, 0x2b, 0xa0, 0x29, 0xa0, 0x27, 0x86,
+    0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+    0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c,
+    0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70,
+    0x70, 0x6c, 0x65, 0x63, 0x61, 0x2f, 0x72, 0x6f,
+    0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0d,
+    0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+    0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01,
+    0x01, 0x00, 0x9e, 0xb4, 0xaf, 0x3d, 0xb7, 0x61,
+    0xe0, 0x64, 0xc3, 0x86, 0x27, 0xd2, 0x3f, 0xe9,
+    0xe4, 0x08, 0x50, 0x77, 0xa2, 0x81, 0x09, 0x8c,
+    0x7d, 0xb7, 0xd0, 0x54, 0x52, 0xde, 0xfe, 0x8d,
+    0x48, 0xf2, 0x86, 0xc1, 0x17, 0xe5, 0x1a, 0x5d,
+    0x29, 0x20, 0xd3, 0x81, 0xca, 0xee, 0xc8, 0xa3,
+    0x61, 0xb3, 0x90, 0x9f, 0x73, 0xe8, 0xe3, 0xc8,
+    0xbc, 0xa7, 0x12, 0xb4, 0x8c, 0x2d, 0xaa, 0xf5,
+    0x39, 0x27, 0x19, 0xf5, 0xfb, 0xf9, 0x14, 0x7b,
+    0x3a, 0xb4, 0x78, 0x1a, 0x9a, 0x4c, 0x96, 0xeb,
+    0x36, 0xc7, 0xfe, 0xb5, 0xe7, 0x14, 0x7e, 0x6c,
+    0x4f, 0xa8, 0x22, 0xba, 0x23, 0x82, 0xf0, 0xce,
+    0xfa, 0x09, 0x7b, 0x8a, 0x0d, 0x5a, 0x61, 0x21,
+    0x74, 0x7a, 0xca, 0xc2, 0xca, 0x6b, 0xc2, 0x63,
+    0x40, 0x77, 0x23, 0x2b, 0x8f, 0xa0, 0x29, 0x5c,
+    0xeb, 0xad, 0xfc, 0xcc, 0xdc, 0x5a, 0x42, 0x42,
+    0x2e, 0xc8, 0x4f, 0xb4, 0x90, 0xd2, 0x6e, 0xfc,
+    0x4f, 0x8a, 0x0e, 0xa8, 0xb7, 0x83, 0x5c, 0x5c,
+    0x12, 0x02, 0x15, 0x17, 0xa8, 0x65, 0x7d, 0x5a,
+    0x28, 0x2b, 0x69, 0x5f, 0x76, 0x9e, 0x2f, 0xe0,
+    0x9e, 0xec, 0x41, 0x57, 0x97, 0xc5, 0x0f, 0x9a,
+    0xa0, 0x70, 0xb8, 0x2c, 0x8f, 0x6d, 0x80, 0xb5,
+    0x46, 0xec, 0xe8, 0x58, 0xb0, 0x04, 0x40, 0x3c,
+    0xc3, 0x62, 0x8a, 0x0a, 0xb7, 0xa9, 0x5b, 0x58,
+    0x7d, 0xea, 0x7b, 0x8c, 0xff, 0xf7, 0xf8, 0xbf,
+    0xd2, 0xc1, 0x95, 0x76, 0x05, 0xd7, 0x5d, 0x16,
+    0x4d, 0xf1, 0x1e, 0x7d, 0xb2, 0x81, 0x10, 0xe8,
+    0x47, 0x74, 0x12, 0xf1, 0xe6, 0x60, 0x3f, 0xe3,
+    0x6f, 0xb6, 0xa4, 0xc6, 0xe1, 0x08, 0xb3, 0xe4,
+    0x7d, 0x98, 0xf1, 0xfb, 0xd0, 0x42, 0xb2, 0x59,
+    0x26, 0x17, 0xfb, 0x72, 0x6b, 0x05, 0xa9, 0xac,
+    0x94, 0xbf, 0x88, 0x0a, 0x09, 0xef, 0xd2, 0xa5,
+    0x25, 0xae
+};
+
+/*
+       subject= /C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple iPod Accessories Certification Authority
+       issuer= /C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Root CA
+       serial=16
+*/
+const uint8_t _iAP2CA[] = {
+    0x30, 0x82, 0x03, 0xfe, 0x30, 0x82, 0x02, 0xe6,
+    0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x16,
+    0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+    0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
+    0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+    0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
+    0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+    0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49,
+    0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06,
+    0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70,
+    0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74,
+    0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+    0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+    0x69, 0x74, 0x79, 0x31, 0x16, 0x30, 0x14, 0x06,
+    0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x41, 0x70,
+    0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74,
+    0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x30,
+    0x37, 0x30, 0x32, 0x31, 0x34, 0x32, 0x32, 0x31,
+    0x38, 0x30, 0x38, 0x5a, 0x17, 0x0d, 0x32, 0x32,
+    0x30, 0x32, 0x31, 0x34, 0x32, 0x32, 0x31, 0x38,
+    0x30, 0x38, 0x5a, 0x30, 0x81, 0x83, 0x31, 0x0b,
+    0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+    0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06,
+    0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70,
+    0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+    0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04,
+    0x0b, 0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65,
+    0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+    0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41,
+    0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
+    0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04,
+    0x03, 0x13, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x65,
+    0x20, 0x69, 0x50, 0x6f, 0x64, 0x20, 0x41, 0x63,
+    0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x69, 0x65,
+    0x73, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+    0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
+    0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
+    0x79, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06,
+    0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+    0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f,
+    0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01,
+    0x01, 0x00, 0xa1, 0xf6, 0xca, 0xdb, 0x3d, 0x4a,
+    0x5a, 0x3e, 0xef, 0x74, 0x78, 0xf1, 0xb7, 0xb0,
+    0x32, 0x82, 0x1f, 0x90, 0xc6, 0x08, 0xdf, 0xaa,
+    0x3b, 0xd2, 0xcb, 0x0f, 0xe6, 0x37, 0x13, 0xf8,
+    0xff, 0x71, 0xfc, 0x28, 0x86, 0x24, 0x36, 0x85,
+    0x3f, 0xd0, 0x1d, 0x9c, 0xd0, 0x9c, 0xb2, 0x5d,
+    0x20, 0x41, 0xdc, 0xb0, 0xd8, 0xa8, 0x86, 0x3c,
+    0x42, 0x3c, 0xbe, 0x5a, 0x48, 0xdf, 0x34, 0x74,
+    0x9a, 0x61, 0x05, 0x0d, 0xce, 0xc8, 0x25, 0x14,
+    0xc8, 0x0a, 0xcd, 0xbd, 0xba, 0x12, 0x1b, 0x3b,
+    0x41, 0x13, 0x8e, 0x38, 0x65, 0x1d, 0xac, 0x1d,
+    0xd5, 0x38, 0x95, 0x9d, 0x3a, 0xd0, 0x79, 0x5c,
+    0x66, 0x9c, 0x47, 0x4b, 0x2c, 0xb8, 0x44, 0x3b,
+    0x7e, 0x8b, 0x68, 0x39, 0x3e, 0x46, 0xc1, 0xb8,
+    0xc0, 0x85, 0xd6, 0x84, 0xfb, 0x0e, 0xa6, 0xdd,
+    0x34, 0x06, 0xda, 0x1c, 0x78, 0xd9, 0xc4, 0x63,
+    0x11, 0x1b, 0xcf, 0x20, 0x15, 0xd2, 0x7a, 0xef,
+    0x60, 0x40, 0xdf, 0xba, 0xe0, 0x05, 0x45, 0x41,
+    0x82, 0x0e, 0x9b, 0x78, 0x2d, 0x2a, 0xb4, 0x94,
+    0xb5, 0xca, 0x79, 0xcd, 0xdb, 0xb5, 0x95, 0x02,
+    0xbe, 0x55, 0x2c, 0x36, 0x21, 0xaf, 0x6e, 0x39,
+    0xb6, 0x76, 0x5a, 0xec, 0x5d, 0x6a, 0xf3, 0xcc,
+    0xfa, 0x90, 0x8a, 0x15, 0x77, 0xbb, 0xba, 0x5c,
+    0x2b, 0xa1, 0x87, 0xf8, 0x0e, 0x70, 0x5d, 0x23,
+    0x01, 0x08, 0x79, 0xef, 0xab, 0xd7, 0x91, 0x38,
+    0x81, 0x35, 0xb3, 0x07, 0xd4, 0x79, 0xa2, 0x25,
+    0xa7, 0xf7, 0x90, 0x75, 0xeb, 0xeb, 0x71, 0xa2,
+    0xd0, 0xc1, 0xab, 0x02, 0x06, 0xf9, 0x07, 0x08,
+    0x97, 0x35, 0xda, 0x7e, 0x4d, 0x61, 0x51, 0x75,
+    0x92, 0xf6, 0x19, 0xf5, 0xdf, 0xfb, 0xc9, 0xa5,
+    0x4e, 0x9b, 0x8a, 0x14, 0x11, 0x4c, 0x10, 0x74,
+    0x83, 0xaf, 0x2f, 0xfc, 0xb6, 0xd6, 0x6b, 0x57,
+    0x46, 0x1d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
+    0x81, 0x9c, 0x30, 0x81, 0x99, 0x30, 0x0e, 0x06,
+    0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04,
+    0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x0f, 0x06,
+    0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04,
+    0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d,
+    0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
+    0x14, 0xff, 0x4b, 0x1a, 0x43, 0x9a, 0xf5, 0x19,
+    0x96, 0xab, 0x18, 0x00, 0x2b, 0x61, 0xc9, 0xee,
+    0x40, 0x9d, 0x8e, 0xc7, 0x04, 0x30, 0x1f, 0x06,
+    0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
+    0x80, 0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76,
+    0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e, 0x40, 0xa6,
+    0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x36,
+    0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2f, 0x30,
+    0x2d, 0x30, 0x2b, 0xa0, 0x29, 0xa0, 0x27, 0x86,
+    0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+    0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c,
+    0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70,
+    0x70, 0x6c, 0x65, 0x63, 0x61, 0x2f, 0x72, 0x6f,
+    0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0d,
+    0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+    0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01,
+    0x01, 0x00, 0x9e, 0xb4, 0xaf, 0x3d, 0xb7, 0x61,
+    0xe0, 0x64, 0xc3, 0x86, 0x27, 0xd2, 0x3f, 0xe9,
+    0xe4, 0x08, 0x50, 0x77, 0xa2, 0x81, 0x09, 0x8c,
+    0x7d, 0xb7, 0xd0, 0x54, 0x52, 0xde, 0xfe, 0x8d,
+    0x48, 0xf2, 0x86, 0xc1, 0x17, 0xe5, 0x1a, 0x5d,
+    0x29, 0x20, 0xd3, 0x81, 0xca, 0xee, 0xc8, 0xa3,
+    0x61, 0xb3, 0x90, 0x9f, 0x73, 0xe8, 0xe3, 0xc8,
+    0xbc, 0xa7, 0x12, 0xb4, 0x8c, 0x2d, 0xaa, 0xf5,
+    0x39, 0x27, 0x19, 0xf5, 0xfb, 0xf9, 0x14, 0x7b,
+    0x3a, 0xb4, 0x78, 0x1a, 0x9a, 0x4c, 0x96, 0xeb,
+    0x36, 0xc7, 0xfe, 0xb5, 0xe7, 0x14, 0x7e, 0x6c,
+    0x4f, 0xa8, 0x22, 0xba, 0x23, 0x82, 0xf0, 0xce,
+    0xfa, 0x09, 0x7b, 0x8a, 0x0d, 0x5a, 0x61, 0x21,
+    0x74, 0x7a, 0xca, 0xc2, 0xca, 0x6b, 0xc2, 0x63,
+    0x40, 0x77, 0x23, 0x2b, 0x8f, 0xa0, 0x29, 0x5c,
+    0xeb, 0xad, 0xfc, 0xcc, 0xdc, 0x5a, 0x42, 0x42,
+    0x2e, 0xc8, 0x4f, 0xb4, 0x90, 0xd2, 0x6e, 0xfc,
+    0x4f, 0x8a, 0x0e, 0xa8, 0xb7, 0x83, 0x5c, 0x5c,
+    0x12, 0x02, 0x15, 0x17, 0xa8, 0x65, 0x7d, 0x5a,
+    0x28, 0x2b, 0x69, 0x5f, 0x76, 0x9e, 0x2f, 0xe0,
+    0x9e, 0xec, 0x41, 0x57, 0x97, 0xc5, 0x0f, 0x9a,
+    0xa0, 0x70, 0xb8, 0x2c, 0x8f, 0x6d, 0x80, 0xb5,
+    0x46, 0xec, 0xe8, 0x58, 0xb0, 0x04, 0x40, 0x3c,
+    0xc3, 0x62, 0x8a, 0x0a, 0xb7, 0xa9, 0x5b, 0x58,
+    0x7d, 0xea, 0x7b, 0x8c, 0xff, 0xf7, 0xf8, 0xbf,
+    0xd2, 0xc1, 0x95, 0x76, 0x05, 0xd7, 0x5d, 0x16,
+    0x4d, 0xf1, 0x1e, 0x7d, 0xb2, 0x81, 0x10, 0xe8,
+    0x47, 0x74, 0x12, 0xf1, 0xe6, 0x60, 0x3f, 0xe3,
+    0x6f, 0xb6, 0xa4, 0xc6, 0xe1, 0x08, 0xb3, 0xe4,
+    0x7d, 0x98, 0xf1, 0xfb, 0xd0, 0x42, 0xb2, 0x59,
+    0x26, 0x17, 0xfb, 0x72, 0x6b, 0x05, 0xa9, 0xac,
+    0x94, 0xbf, 0x88, 0x0a, 0x09, 0xef, 0xd2, 0xa5,
+    0x25, 0xae
+};
+
+/*
+       subject= /C=US/O=Apple Inc./OU=Apple iPod Accessories/CN=IPA_3333AA070313AA06AA0007AA000001
+       issuer= /C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple iPod Accessories Certification Authority
+       serial=3333AA070313AA06AA0007AA000001
+*/
+const uint8_t _leaf0[] = {
+    0x30, 0x82, 0x03, 0x59, 0x30, 0x82, 0x02, 0x41,
+    0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0f, 0x33,
+    0x33, 0xaa, 0x07, 0x03, 0x13, 0xaa, 0x06, 0xaa,
+    0x00, 0x07, 0xaa, 0x00, 0x00, 0x01, 0x30, 0x0d,
+    0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+    0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, 0x83,
+    0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
+    0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30,
+    0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a,
+    0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e,
+    0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03,
+    0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70, 0x70,
+    0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
+    0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+    0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
+    0x74, 0x79, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03,
+    0x55, 0x04, 0x03, 0x13, 0x2e, 0x41, 0x70, 0x70,
+    0x6c, 0x65, 0x20, 0x69, 0x50, 0x6f, 0x64, 0x20,
+    0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72,
+    0x69, 0x65, 0x73, 0x20, 0x43, 0x65, 0x72, 0x74,
+    0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+    0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+    0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x30,
+    0x37, 0x30, 0x33, 0x31, 0x33, 0x32, 0x31, 0x31,
+    0x37, 0x32, 0x36, 0x5a, 0x17, 0x0d, 0x31, 0x35,
+    0x30, 0x33, 0x31, 0x33, 0x32, 0x31, 0x31, 0x37,
+    0x32, 0x36, 0x5a, 0x30, 0x70, 0x31, 0x0b, 0x30,
+    0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+    0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
+    0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70,
+    0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
+    0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b,
+    0x13, 0x16, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20,
+    0x69, 0x50, 0x6f, 0x64, 0x20, 0x41, 0x63, 0x63,
+    0x65, 0x73, 0x73, 0x6f, 0x72, 0x69, 0x65, 0x73,
+    0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04,
+    0x03, 0x14, 0x22, 0x49, 0x50, 0x41, 0x5f, 0x33,
+    0x33, 0x33, 0x33, 0x41, 0x41, 0x30, 0x37, 0x30,
+    0x33, 0x31, 0x33, 0x41, 0x41, 0x30, 0x36, 0x41,
+    0x41, 0x30, 0x30, 0x30, 0x37, 0x41, 0x41, 0x30,
+    0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x81, 0x9f,
+    0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+    0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
+    0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81,
+    0x81, 0x00, 0xcb, 0x76, 0xe3, 0xa7, 0x3b, 0xf0,
+    0x42, 0xd5, 0x48, 0x93, 0x62, 0x0a, 0x10, 0x17,
+    0x37, 0xb9, 0xc8, 0x52, 0xdd, 0xde, 0x8a, 0x40,
+    0xa0, 0xf8, 0xda, 0xe8, 0x64, 0x0a, 0x67, 0xf5,
+    0x8f, 0x91, 0xa6, 0xb5, 0x93, 0xe8, 0xc2, 0x28,
+    0xb3, 0xac, 0xf4, 0xaf, 0x40, 0xc6, 0xbb, 0x49,
+    0x85, 0x5a, 0x7c, 0x1b, 0x42, 0xc3, 0x3c, 0xc8,
+    0x95, 0x36, 0x0b, 0x85, 0xbe, 0x36, 0x85, 0xb7,
+    0x0d, 0x04, 0x0e, 0x4e, 0x4c, 0x3c, 0x28, 0xfb,
+    0x03, 0x78, 0x42, 0xac, 0xf1, 0x9e, 0xad, 0x22,
+    0x7c, 0x86, 0xd3, 0xa6, 0x0e, 0xc8, 0x42, 0xbd,
+    0x9c, 0x7c, 0xd9, 0x2c, 0xe4, 0x1f, 0xd5, 0x91,
+    0x4e, 0x9d, 0xb7, 0xff, 0x83, 0x2e, 0x06, 0x3e,
+    0xd4, 0x95, 0xe4, 0x0e, 0x8e, 0x2d, 0x46, 0x8f,
+    0xcf, 0xe6, 0x32, 0xce, 0x47, 0x56, 0x57, 0x97,
+    0x1a, 0x87, 0xc8, 0xd4, 0xf3, 0x32, 0xf9, 0xd6,
+    0x80, 0x83, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
+    0x60, 0x30, 0x5e, 0x30, 0x0e, 0x06, 0x03, 0x55,
+    0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03,
+    0x02, 0x03, 0xb8, 0x30, 0x0c, 0x06, 0x03, 0x55,
+    0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30,
+    0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
+    0x04, 0x16, 0x04, 0x14, 0x71, 0x53, 0x3f, 0x7f,
+    0x72, 0x47, 0xbb, 0xe3, 0x60, 0xd9, 0xd9, 0xd8,
+    0x39, 0x6d, 0x8d, 0x33, 0xa3, 0x74, 0xc3, 0x59,
+    0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
+    0x18, 0x30, 0x16, 0x80, 0x14, 0xff, 0x4b, 0x1a,
+    0x43, 0x9a, 0xf5, 0x19, 0x96, 0xab, 0x18, 0x00,
+    0x2b, 0x61, 0xc9, 0xee, 0x40, 0x9d, 0x8e, 0xc7,
+    0x04, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+    0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,
+    0x03, 0x82, 0x01, 0x01, 0x00, 0x0f, 0xd9, 0x40,
+    0x27, 0x1c, 0x00, 0x01, 0x2d, 0x4c, 0x67, 0xa6,
+    0x0d, 0x74, 0xa8, 0xbd, 0xf6, 0x97, 0x16, 0x46,
+    0xb1, 0x02, 0xd7, 0x51, 0xf6, 0x02, 0xc1, 0x0f,
+    0xb1, 0x34, 0x8a, 0xcb, 0xb7, 0x81, 0x29, 0xbd,
+    0x7b, 0x67, 0xa3, 0xe6, 0x49, 0x3d, 0xbb, 0x3e,
+    0x0d, 0x26, 0x75, 0x1d, 0xdc, 0x37, 0xa7, 0x38,
+    0x86, 0xd8, 0x81, 0x5a, 0xc5, 0xaf, 0xcd, 0xd6,
+    0xcb, 0x0e, 0xba, 0x53, 0x28, 0x57, 0x83, 0x16,
+    0x23, 0xcc, 0x11, 0x01, 0x0e, 0x18, 0x4d, 0xfe,
+    0x29, 0x1b, 0x7c, 0x3f, 0x33, 0xd5, 0x4b, 0x7c,
+    0x74, 0xb5, 0xfd, 0x62, 0xc5, 0x45, 0xec, 0x08,
+    0xe4, 0xc0, 0xd3, 0xce, 0xba, 0xb0, 0x04, 0x0d,
+    0x7c, 0xef, 0x5c, 0x3f, 0x92, 0xdc, 0x45, 0x24,
+    0xa3, 0x02, 0xfe, 0xa4, 0x60, 0x15, 0x28, 0x43,
+    0x1b, 0x46, 0x51, 0x1f, 0x9f, 0x0d, 0x89, 0x62,
+    0x6c, 0x30, 0xe2, 0x2b, 0xf7, 0x8c, 0x7b, 0xd6,
+    0xe3, 0x71, 0x11, 0xd1, 0xe5, 0xf5, 0x83, 0xae,
+    0xd8, 0xeb, 0x5a, 0x40, 0xb6, 0x09, 0x00, 0x53,
+    0x8f, 0xaf, 0x4d, 0xa7, 0x3d, 0x50, 0xb0, 0x1b,
+    0x88, 0x6b, 0x9d, 0x18, 0x79, 0x1e, 0xcb, 0xbf,
+    0x86, 0xba, 0xde, 0x48, 0x28, 0x3a, 0x53, 0x17,
+    0x59, 0x2d, 0xc2, 0x98, 0xe0, 0xe7, 0x54, 0x03,
+    0xd0, 0x1d, 0xfb, 0xc1, 0xca, 0x68, 0x43, 0x2d,
+    0x23, 0xc3, 0xa3, 0x12, 0x04, 0x89, 0x77, 0x41,
+    0xb8, 0x96, 0x3f, 0xdc, 0x00, 0x73, 0x07, 0xd0,
+    0xa6, 0x8c, 0x35, 0x45, 0xb4, 0x07, 0x69, 0xf8,
+    0x79, 0x6e, 0x7b, 0x04, 0x6d, 0x0f, 0x95, 0x20,
+    0x5b, 0x76, 0x17, 0x78, 0x91, 0x91, 0xa4, 0xbe,
+    0x6d, 0x5c, 0xe9, 0x71, 0x12, 0x68, 0x6c, 0xb7,
+    0xa4, 0x36, 0xc3, 0x82, 0xcf, 0x65, 0x7d, 0xe3,
+    0x50, 0x92, 0x02, 0x54, 0x3d, 0xfe, 0x16, 0x8d,
+    0x4f, 0xe0, 0x11, 0xe0, 0xb5
+};
+
+/*
+       subject= /C=US/O=Apple Computer, Inc./OU=Apple Computer iPod Accessories/CN=IPA_3333AA070313AA06AA0011AA000001
+       issuer= /C=US/O=Apple Computer, Inc./OU=Apple Computer Certificate Authority/CN=Apple iPod Accessories Certificate Authority
+       serial=3333AA070313AA06AA0011AA000001
+*/
+const uint8_t _leaf1[] = {
+    0x30, 0x82, 0x03, 0x7c, 0x30, 0x82, 0x02, 0x64,
+    0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0f, 0x33,
+    0x33, 0xaa, 0x07, 0x03, 0x13, 0xaa, 0x06, 0xaa,
+    0x00, 0x11, 0xaa, 0x00, 0x00, 0x01, 0x30, 0x0d,
+    0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+    0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, 0x92,
+    0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
+    0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x1d, 0x30,
+    0x1b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x14,
+    0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x6f,
+    0x6d, 0x70, 0x75, 0x74, 0x65, 0x72, 0x2c, 0x20,
+    0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2d, 0x30, 0x2b,
+    0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x24, 0x41,
+    0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x6f, 0x6d,
+    0x70, 0x75, 0x74, 0x65, 0x72, 0x20, 0x43, 0x65,
+    0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+    0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+    0x69, 0x74, 0x79, 0x31, 0x35, 0x30, 0x33, 0x06,
+    0x03, 0x55, 0x04, 0x03, 0x13, 0x2c, 0x41, 0x70,
+    0x70, 0x6c, 0x65, 0x20, 0x69, 0x50, 0x6f, 0x64,
+    0x20, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f,
+    0x72, 0x69, 0x65, 0x73, 0x20, 0x43, 0x65, 0x72,
+    0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65,
+    0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
+    0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x37,
+    0x30, 0x33, 0x31, 0x33, 0x32, 0x31, 0x32, 0x37,
+    0x33, 0x35, 0x5a, 0x17, 0x0d, 0x31, 0x35, 0x30,
+    0x33, 0x31, 0x33, 0x32, 0x31, 0x32, 0x37, 0x33,
+    0x35, 0x5a, 0x30, 0x81, 0x83, 0x31, 0x0b, 0x30,
+    0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+    0x55, 0x53, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03,
+    0x55, 0x04, 0x0a, 0x13, 0x14, 0x41, 0x70, 0x70,
+    0x6c, 0x65, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x75,
+    0x74, 0x65, 0x72, 0x2c, 0x20, 0x49, 0x6e, 0x63,
+    0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55,
+    0x04, 0x0b, 0x13, 0x1f, 0x41, 0x70, 0x70, 0x6c,
+    0x65, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74,
+    0x65, 0x72, 0x20, 0x69, 0x50, 0x6f, 0x64, 0x20,
+    0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72,
+    0x69, 0x65, 0x73, 0x31, 0x2b, 0x30, 0x29, 0x06,
+    0x03, 0x55, 0x04, 0x03, 0x14, 0x22, 0x49, 0x50,
+    0x41, 0x5f, 0x33, 0x33, 0x33, 0x33, 0x41, 0x41,
+    0x30, 0x37, 0x30, 0x33, 0x31, 0x33, 0x41, 0x41,
+    0x30, 0x36, 0x41, 0x41, 0x30, 0x30, 0x31, 0x31,
+    0x41, 0x41, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31,
+    0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+    0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
+    0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81,
+    0x89, 0x02, 0x81, 0x81, 0x00, 0x91, 0x66, 0xdb,
+    0x40, 0x0e, 0xc4, 0xe5, 0x8d, 0xb3, 0x86, 0xfd,
+    0x36, 0x06, 0x38, 0xcc, 0x83, 0xa4, 0xd7, 0xff,
+    0x14, 0xa6, 0x77, 0x3b, 0x63, 0x7a, 0xae, 0xe8,
+    0x76, 0xdb, 0xd8, 0x2f, 0x7c, 0x70, 0x84, 0xe8,
+    0x0a, 0x63, 0x33, 0xa7, 0xcb, 0x0e, 0x17, 0x94,
+    0x80, 0x39, 0xb7, 0xe6, 0x16, 0x0c, 0xa7, 0x1f,
+    0x7d, 0x11, 0x02, 0x76, 0xda, 0x1d, 0x0b, 0xed,
+    0x8d, 0x2a, 0xeb, 0x60, 0xcf, 0x55, 0x85, 0xbd,
+    0x92, 0x32, 0xc9, 0xc9, 0xb2, 0x16, 0xea, 0xba,
+    0xa8, 0xc8, 0x8c, 0xe4, 0x93, 0x7a, 0x0a, 0xaa,
+    0x40, 0x24, 0x0f, 0x96, 0xc7, 0xc5, 0x95, 0x21,
+    0xd9, 0xb0, 0x98, 0x51, 0x8d, 0xe4, 0xc6, 0x63,
+    0x6e, 0x73, 0x92, 0xab, 0x77, 0xe9, 0x71, 0xaf,
+    0x0e, 0x50, 0xa3, 0xb4, 0x68, 0xa8, 0x82, 0x67,
+    0x88, 0xf9, 0xa5, 0xc8, 0x68, 0x7b, 0x49, 0x36,
+    0x72, 0xee, 0x06, 0x1a, 0x95, 0x02, 0x03, 0x01,
+    0x00, 0x01, 0xa3, 0x60, 0x30, 0x5e, 0x30, 0x0e,
+    0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
+    0x04, 0x04, 0x03, 0x02, 0x03, 0xb8, 0x30, 0x0c,
+    0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
+    0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03,
+    0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xde,
+    0x6a, 0x9d, 0x5e, 0x83, 0x77, 0xa6, 0xfe, 0xa9,
+    0x65, 0x30, 0x5f, 0x98, 0xe8, 0xa4, 0x7c, 0xde,
+    0x0a, 0xb3, 0x48, 0x30, 0x1f, 0x06, 0x03, 0x55,
+    0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
+    0xc9, 0xaa, 0x84, 0x6b, 0x06, 0xb8, 0x76, 0xe2,
+    0x96, 0x4f, 0xe7, 0x27, 0x02, 0xd7, 0x2e, 0x3b,
+    0xda, 0xf7, 0xb0, 0x18, 0x30, 0x0d, 0x06, 0x09,
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+    0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00,
+    0x96, 0x07, 0x3b, 0x68, 0xe8, 0x2f, 0x97, 0xa5,
+    0x42, 0xff, 0x9d, 0x34, 0xfd, 0x3a, 0xd2, 0x01,
+    0x69, 0xd7, 0x67, 0x46, 0x9a, 0x7d, 0x56, 0xe0,
+    0x7f, 0x91, 0xee, 0xc3, 0x5c, 0xd2, 0x51, 0x54,
+    0xe3, 0xd2, 0x17, 0x08, 0xb2, 0xbc, 0xcd, 0x85,
+    0xf8, 0x8e, 0xad, 0x49, 0x53, 0xe1, 0x07, 0x5a,
+    0x9b, 0x03, 0xa2, 0x35, 0xca, 0xcf, 0xc6, 0xb6,
+    0xc9, 0x71, 0x53, 0xbc, 0x2e, 0xa3, 0x1b, 0x03,
+    0x5c, 0x55, 0x57, 0xa3, 0x10, 0xbc, 0x15, 0x81,
+    0xd5, 0xe6, 0xa3, 0xb8, 0x21, 0x50, 0x2e, 0x44,
+    0xd4, 0xea, 0x71, 0x17, 0xe5, 0xfc, 0x71, 0xc3,
+    0xf9, 0xe8, 0x99, 0x98, 0xf3, 0x5f, 0xff, 0xb2,
+    0x8e, 0xc7, 0x56, 0x74, 0x46, 0xec, 0x63, 0x3f,
+    0x4a, 0xa6, 0x9c, 0x85, 0x7c, 0x08, 0x61, 0x32,
+    0xb7, 0x35, 0x36, 0x01, 0x0c, 0xce, 0xd8, 0xe3,
+    0xc4, 0x6a, 0x0d, 0xf2, 0x25, 0x56, 0x59, 0xba,
+    0x88, 0x1b, 0xb4, 0x21, 0x80, 0xb9, 0x69, 0x9e,
+    0x93, 0xf7, 0xb1, 0x22, 0x19, 0x8b, 0x8b, 0xd8,
+    0xbd, 0xdc, 0x0c, 0xa7, 0x69, 0x4b, 0x5b, 0xe9,
+    0xd7, 0x7a, 0x1d, 0xef, 0x37, 0x0d, 0x24, 0xdc,
+    0xa7, 0x67, 0xbc, 0x0d, 0xe1, 0x0d, 0x28, 0xa0,
+    0xb8, 0x83, 0x28, 0x6a, 0x8a, 0xd6, 0x59, 0x40,
+    0x4a, 0xf1, 0x06, 0x0d, 0x75, 0xb9, 0x81, 0x4b,
+    0x4c, 0x2d, 0xcb, 0x57, 0xe0, 0x7a, 0x32, 0x5b,
+    0xe0, 0xea, 0xdd, 0x0c, 0xdc, 0xfd, 0x5e, 0x7e,
+    0xb0, 0x77, 0x07, 0x0d, 0xa7, 0x14, 0x0b, 0x41,
+    0x94, 0x4f, 0x10, 0x3e, 0xa5, 0x0c, 0x68, 0x3f,
+    0x8c, 0x70, 0x5c, 0x29, 0xb7, 0xe9, 0xfc, 0x09,
+    0x35, 0x5c, 0x2d, 0xb3, 0xa9, 0x4f, 0x51, 0xb0,
+    0xa7, 0xd5, 0xad, 0x3f, 0xe2, 0xa2, 0x4c, 0x73,
+    0xfc, 0x2f, 0x6e, 0x21, 0x38, 0xe5, 0xbb, 0x8b,
+    0x57, 0x51, 0xe5, 0x9b, 0x8b, 0xa6, 0xaa, 0x0b
+};
+
+#define CFReleaseSafe(CF) { CFTypeRef _cf = (CF); if (_cf) CFRelease(_cf); }
+
+/* Test basic add delete update copy matching stuff. */
+static void tests(void)
+{
+    SecTrustRef trust;
+       SecCertificateRef iAP1CA, iAP2CA, leaf0, leaf1;
+       isnt(iAP1CA = SecCertificateCreateWithBytes(NULL, _iAP1CA, sizeof(_iAP1CA)),
+               NULL, "create iAP1CA");
+       isnt(iAP2CA = SecCertificateCreateWithBytes(NULL, _iAP2CA, sizeof(_iAP2CA)),
+               NULL, "create iAP2CA");
+       isnt(leaf0 = SecCertificateCreateWithBytes(NULL, _leaf0, sizeof(_leaf0)),
+               NULL, "create leaf0");
+       isnt(leaf1 = SecCertificateCreateWithBytes(NULL, _leaf1, sizeof(_leaf1)),
+               NULL, "create leaf1");
+    SecPolicyRef policy = SecPolicyCreateiAP();
+       const void *v_anchors[] = {
+               iAP1CA,
+               iAP2CA
+       };
+    CFArrayRef anchors = CFArrayCreate(NULL, v_anchors,
+               array_size(v_anchors), NULL);
+    CFArrayRef certs0 = CFArrayCreate(NULL, (const void **)&leaf0, 1, NULL);
+    CFArrayRef certs1 = CFArrayCreate(NULL, (const void **)&leaf1, 1, NULL);
+    ok_status(SecTrustCreateWithCertificates(certs0, policy, &trust), "create trust for leaf0");
+       ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set anchors");
+
+       /* Jan 1st 2008. */
+       CFDateRef date = CFDateCreate(NULL, 220752000.0);
+    ok_status(SecTrustSetVerifyDate(trust, date), "set date");
+
+       SecTrustResultType trustResult;
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultUnspecified,
+               "trust is kSecTrustResultUnspecified");
+
+       is(SecTrustGetCertificateCount(trust), 2, "cert count is 2");
+
+       CFReleaseSafe(trust);
+    ok_status(SecTrustCreateWithCertificates(certs1, policy, &trust), "create trust for leaf1");
+       ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set anchors");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+       TODO:
+       {
+               todo("We need the actual iAP1 intermediate");
+               is_status(trustResult, kSecTrustResultUnspecified,
+                       "trust is kSecTrustResultUnspecified");
+       }
+
+       CFReleaseSafe(anchors);
+       CFReleaseSafe(certs1);
+       CFReleaseSafe(certs0);
+       CFReleaseSafe(trust);
+       CFReleaseSafe(policy);
+       CFReleaseSafe(leaf0);
+       CFReleaseSafe(leaf1);
+       CFReleaseSafe(iAP1CA);
+       CFReleaseSafe(iAP2CA);
+       CFReleaseSafe(date);
+}
+
+int si_22_sectrust_iap(int argc, char *const *argv)
+{
+       plan_tests(14);
+
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-23-sectrust-ocsp-wwdr.c b/sec/Security/Regressions/secitem/si-23-sectrust-ocsp-wwdr.c
new file mode 100644 (file)
index 0000000..e8ac887
--- /dev/null
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 2012 Apple Inc. All Rights Reserved.
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecCertificateInternal.h>
+#include <Security/SecPolicyPriv.h>
+#include <Security/SecTrustPriv.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "testmore.h"
+
+/* subject:/UID=6H766P4BDJ/CN=iPhone Distribution: SCK Solutions LLC/OU=6H766P4BDJ/O=6H766P4BDJ/C=US */
+/* issuer :/C=US/O=Apple Inc./OU=Apple Worldwide Developer Relations/CN=Apple Worldwide Developer Relations Certification Authority */
+static const unsigned char WWDR_NoRevInfo[]={
+0x30,0x82,0x05,0x2D,0x30,0x82,0x04,0x15,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x34,
+0x92,0xF6,0x39,0x2B,0x4B,0x16,0x64,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,
+0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81,0x96,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,
+0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x0C,
+0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x2C,0x30,0x2A,0x06,
+0x03,0x55,0x04,0x0B,0x0C,0x23,0x41,0x70,0x70,0x6C,0x65,0x20,0x57,0x6F,0x72,0x6C,
+0x64,0x77,0x69,0x64,0x65,0x20,0x44,0x65,0x76,0x65,0x6C,0x6F,0x70,0x65,0x72,0x20,
+0x52,0x65,0x6C,0x61,0x74,0x69,0x6F,0x6E,0x73,0x31,0x44,0x30,0x42,0x06,0x03,0x55,
+0x04,0x03,0x0C,0x3B,0x41,0x70,0x70,0x6C,0x65,0x20,0x57,0x6F,0x72,0x6C,0x64,0x77,
+0x69,0x64,0x65,0x20,0x44,0x65,0x76,0x65,0x6C,0x6F,0x70,0x65,0x72,0x20,0x52,0x65,
+0x6C,0x61,0x74,0x69,0x6F,0x6E,0x73,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,
+0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,
+0x1E,0x17,0x0D,0x31,0x32,0x30,0x31,0x31,0x34,0x32,0x30,0x33,0x30,0x34,0x30,0x5A,
+0x17,0x0D,0x31,0x33,0x30,0x31,0x31,0x33,0x32,0x30,0x33,0x30,0x34,0x30,0x5A,0x30,
+0x81,0x84,0x31,0x1A,0x30,0x18,0x06,0x0A,0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,
+0x01,0x01,0x0C,0x0A,0x36,0x48,0x37,0x36,0x36,0x50,0x34,0x42,0x44,0x4A,0x31,0x2F,
+0x30,0x2D,0x06,0x03,0x55,0x04,0x03,0x0C,0x26,0x69,0x50,0x68,0x6F,0x6E,0x65,0x20,
+0x44,0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x69,0x6F,0x6E,0x3A,0x20,0x53,0x43,
+0x4B,0x20,0x53,0x6F,0x6C,0x75,0x74,0x69,0x6F,0x6E,0x73,0x20,0x4C,0x4C,0x43,0x31,
+0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0B,0x0C,0x0A,0x36,0x48,0x37,0x36,0x36,0x50,
+0x34,0x42,0x44,0x4A,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0A,0x36,
+0x48,0x37,0x36,0x36,0x50,0x34,0x42,0x44,0x4A,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,
+0x04,0x06,0x13,0x02,0x55,0x53,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,
+0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,
+0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xED,0x4A,0x4F,0x35,0x46,0x46,0x40,0xDE,0x95,
+0x88,0x51,0x73,0x00,0x96,0x6F,0x7F,0xA4,0x25,0x1E,0x61,0xA9,0x37,0x30,0x01,0x5C,
+0xAF,0x92,0xCB,0x29,0x8D,0xC2,0x93,0xBE,0xDF,0x7D,0xF0,0xC7,0x0C,0xD3,0x25,0x84,
+0xF8,0x12,0x0D,0x35,0xBC,0x75,0x58,0x80,0x25,0x24,0x3A,0xCD,0x90,0xD9,0xE6,0x2E,
+0xD6,0x00,0x1E,0x36,0x33,0x13,0xBA,0x35,0x5F,0x87,0xB5,0x33,0x5E,0x7E,0x91,0x96,
+0x92,0x91,0x5E,0xE9,0xAE,0xB1,0x50,0xBB,0x7C,0x71,0xF2,0x86,0xF3,0xA9,0x4F,0x48,
+0xE5,0x02,0xFE,0x0A,0x0B,0x3E,0x01,0xC5,0x38,0x02,0x96,0x2F,0xC5,0x44,0x11,0x89,
+0x8D,0x15,0xC1,0xCE,0x77,0x11,0xE7,0xD4,0x83,0x5F,0x4B,0xA9,0x1D,0xE9,0xE2,0xFD,
+0x8E,0xFA,0x7B,0x9A,0xC2,0x2E,0x10,0x8A,0x27,0x86,0xDE,0x65,0x47,0x57,0x49,0x5B,
+0x6F,0xA4,0x41,0x22,0x4C,0x4A,0x9D,0xB5,0x7A,0xD7,0x87,0x06,0xF9,0x52,0x53,0xB8,
+0x39,0xB5,0xA1,0xAC,0x74,0xFC,0x28,0xAE,0x4E,0x14,0xC8,0x0C,0x77,0xEC,0x10,0xBD,
+0xBA,0x22,0xDB,0x5C,0x2E,0x15,0xDD,0x17,0x7A,0x7D,0xFA,0x15,0x81,0x1E,0x31,0xB1,
+0x2D,0x06,0x7E,0x21,0x71,0x69,0xA4,0x7E,0x47,0x43,0x59,0x1D,0xE7,0x3E,0x11,0xCE,
+0xBA,0x58,0x91,0xB5,0xBC,0x52,0x89,0xDE,0x02,0x3E,0x84,0x29,0xF9,0xA0,0xF4,0x24,
+0x04,0x24,0x5C,0xB2,0xA0,0x09,0x54,0xE2,0x8E,0xCF,0xA9,0x43,0x12,0x4B,0xC0,0x22,
+0x18,0x3B,0x51,0x8C,0x89,0xC3,0xB2,0x86,0x05,0x98,0x4F,0x25,0x95,0x82,0x7B,0x7F,
+0xED,0x4A,0xC4,0x74,0xF1,0xA5,0x7D,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x01,0x8D,
+0x30,0x82,0x01,0x89,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xA1,
+0x00,0xAE,0xE5,0x3E,0x53,0xF1,0x39,0x38,0x73,0x02,0xC0,0x6E,0x50,0xCE,0xC8,0xD9,
+0x05,0x50,0x2A,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x02,0x30,
+0x00,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x88,0x27,
+0x17,0x09,0xA9,0xB6,0x18,0x60,0x8B,0xEC,0xEB,0xBA,0xF6,0x47,0x59,0xC5,0x52,0x54,
+0xA3,0xB7,0x30,0x82,0x01,0x0F,0x06,0x03,0x55,0x1D,0x20,0x04,0x82,0x01,0x06,0x30,
+0x82,0x01,0x02,0x30,0x81,0xFF,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,0x05,
+0x01,0x30,0x81,0xF1,0x30,0x81,0xC3,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,
+0x02,0x30,0x81,0xB6,0x0C,0x81,0xB3,0x52,0x65,0x6C,0x69,0x61,0x6E,0x63,0x65,0x20,
+0x6F,0x6E,0x20,0x74,0x68,0x69,0x73,0x20,0x63,0x65,0x72,0x74,0x69,0x66,0x69,0x63,
+0x61,0x74,0x65,0x20,0x62,0x79,0x20,0x61,0x6E,0x79,0x20,0x70,0x61,0x72,0x74,0x79,
+0x20,0x61,0x73,0x73,0x75,0x6D,0x65,0x73,0x20,0x61,0x63,0x63,0x65,0x70,0x74,0x61,
+0x6E,0x63,0x65,0x20,0x6F,0x66,0x20,0x74,0x68,0x65,0x20,0x74,0x68,0x65,0x6E,0x20,
+0x61,0x70,0x70,0x6C,0x69,0x63,0x61,0x62,0x6C,0x65,0x20,0x73,0x74,0x61,0x6E,0x64,
+0x61,0x72,0x64,0x20,0x74,0x65,0x72,0x6D,0x73,0x20,0x61,0x6E,0x64,0x20,0x63,0x6F,
+0x6E,0x64,0x69,0x74,0x69,0x6F,0x6E,0x73,0x20,0x6F,0x66,0x20,0x75,0x73,0x65,0x2C,
+0x20,0x63,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x70,0x6F,0x6C,
+0x69,0x63,0x79,0x20,0x61,0x6E,0x64,0x20,0x63,0x65,0x72,0x74,0x69,0x66,0x69,0x63,
+0x61,0x74,0x69,0x6F,0x6E,0x20,0x70,0x72,0x61,0x63,0x74,0x69,0x63,0x65,0x20,0x73,
+0x74,0x61,0x74,0x65,0x6D,0x65,0x6E,0x74,0x73,0x2E,0x30,0x29,0x06,0x08,0x2B,0x06,
+0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1D,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,
+0x77,0x77,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x2F,0x61,0x70,0x70,
+0x6C,0x65,0x63,0x61,0x2F,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,
+0x04,0x03,0x02,0x07,0x80,0x30,0x16,0x06,0x03,0x55,0x1D,0x25,0x01,0x01,0xFF,0x04,
+0x0C,0x30,0x0A,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x03,0x30,0x0D,0x06,
+0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,
+0x00,0x27,0x78,0xD3,0xFB,0xCE,0xD6,0x10,0x99,0xBF,0x7F,0xAE,0x0A,0x00,0xA3,0x9F,
+0x9C,0x4E,0x23,0x15,0xDB,0x54,0x3E,0x4F,0x9B,0x93,0x67,0x17,0xF2,0x14,0x5A,0x36,
+0x1C,0x30,0x28,0x71,0xCB,0x0A,0xFF,0x1A,0x36,0xA2,0x49,0x7B,0xA4,0xE2,0xD5,0xC7,
+0x58,0x96,0x2A,0x09,0x74,0x16,0x51,0x69,0xEC,0x54,0xDC,0x97,0xA5,0x43,0x65,0x6A,
+0xC9,0x8D,0x93,0x74,0x59,0x62,0x4D,0xF9,0x88,0x42,0x99,0xB6,0xDB,0xA1,0x19,0x19,
+0x2D,0x1D,0xB6,0x4B,0x40,0x74,0x5B,0x57,0x3E,0x3E,0xD6,0x02,0xE0,0xEB,0xAB,0x01,
+0x48,0x7D,0x4B,0x78,0x2B,0x0C,0x9F,0xD3,0x24,0x5C,0x9B,0xB7,0x37,0xA0,0x99,0xC7,
+0xB5,0xDC,0x9A,0x3D,0x85,0x4D,0xAA,0x23,0xEF,0xBA,0xAB,0xA2,0x64,0x56,0x15,0xAF,
+0x0D,0x1B,0xEB,0x64,0xBD,0xD4,0x98,0x61,0xA8,0xB9,0xF8,0x1B,0xD6,0x4A,0x11,0xBB,
+0x13,0x77,0x7A,0x29,0x31,0xC8,0x24,0xBF,0xD5,0xB3,0x4D,0x5F,0xEB,0x2A,0xA8,0xDF,
+0x24,0x40,0xF4,0x2E,0x28,0x43,0xB4,0x88,0x61,0x20,0x51,0xA3,0xEF,0x5A,0xF2,0x24,
+0xE2,0x87,0x29,0x2C,0xDC,0xE9,0xB7,0x43,0xAC,0x38,0x04,0xFB,0x8C,0x18,0x09,0x76,
+0x9C,0xEE,0xFA,0x17,0xE4,0xE4,0x53,0x78,0x91,0x40,0xFC,0x76,0xE2,0x2B,0x39,0x54,
+0xF6,0xF8,0xC6,0xB1,0xF8,0x55,0xD2,0xAF,0xF0,0x65,0x32,0x4E,0x89,0x05,0x4F,0x19,
+0xAD,0xB3,0x65,0xB2,0x19,0xF8,0x00,0xDA,0xDD,0x8F,0x76,0x51,0x52,0x62,0x28,0x4B,
+0x41,0x1C,0xDA,0xFD,0x12,0x11,0x65,0x8D,0xB4,0x69,0xD4,0xC4,0x23,0x67,0x3E,0xD6,
+0x89,
+};
+
+/* subject:/C=US/O=Apple Inc./OU=Apple Worldwide Developer Relations/CN=Apple Worldwide Developer Relations Certification Authority */
+/* issuer :/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Root CA */
+static const unsigned char WWDR_CA[]={
+0x30,0x82,0x04,0x23,0x30,0x82,0x03,0x0B,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x19,
+0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,
+0x62,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,
+0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x13,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,
+0x6E,0x63,0x2E,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0B,0x13,0x1D,0x41,0x70,
+0x70,0x6C,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,
+0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x31,0x16,0x30,0x14,0x06,
+0x03,0x55,0x04,0x03,0x13,0x0D,0x41,0x70,0x70,0x6C,0x65,0x20,0x52,0x6F,0x6F,0x74,
+0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x30,0x38,0x30,0x32,0x31,0x34,0x31,0x38,0x35,
+0x36,0x33,0x35,0x5A,0x17,0x0D,0x31,0x36,0x30,0x32,0x31,0x34,0x31,0x38,0x35,0x36,
+0x33,0x35,0x5A,0x30,0x81,0x96,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,
+0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0A,0x41,0x70,
+0x70,0x6C,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x2C,0x30,0x2A,0x06,0x03,0x55,0x04,
+0x0B,0x0C,0x23,0x41,0x70,0x70,0x6C,0x65,0x20,0x57,0x6F,0x72,0x6C,0x64,0x77,0x69,
+0x64,0x65,0x20,0x44,0x65,0x76,0x65,0x6C,0x6F,0x70,0x65,0x72,0x20,0x52,0x65,0x6C,
+0x61,0x74,0x69,0x6F,0x6E,0x73,0x31,0x44,0x30,0x42,0x06,0x03,0x55,0x04,0x03,0x0C,
+0x3B,0x41,0x70,0x70,0x6C,0x65,0x20,0x57,0x6F,0x72,0x6C,0x64,0x77,0x69,0x64,0x65,
+0x20,0x44,0x65,0x76,0x65,0x6C,0x6F,0x70,0x65,0x72,0x20,0x52,0x65,0x6C,0x61,0x74,
+0x69,0x6F,0x6E,0x73,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,
+0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x82,0x01,0x22,
+0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,
+0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xCA,0x38,0x54,
+0xA6,0xCB,0x56,0xAA,0xC8,0x24,0x39,0x48,0xE9,0x8C,0xEE,0xEC,0x5F,0xB8,0x7F,0x26,
+0x91,0xBC,0x34,0x53,0x7A,0xCE,0x7C,0x63,0x80,0x61,0x77,0x64,0x5E,0xA5,0x07,0x23,
+0xB6,0x39,0xFE,0x50,0x2D,0x15,0x56,0x58,0x70,0x2D,0x7E,0xC4,0x6E,0xC1,0x4A,0x85,
+0x3E,0x2F,0xF0,0xDE,0x84,0x1A,0xA1,0x57,0xC9,0xAF,0x7B,0x18,0xFF,0x6A,0xFA,0x15,
+0x12,0x49,0x15,0x08,0x19,0xAC,0xAA,0xDB,0x2A,0x32,0xED,0x96,0x63,0x68,0x52,0x15,
+0x3D,0x8C,0x8A,0xEC,0xBF,0x6B,0x18,0x95,0xE0,0x03,0xAC,0x01,0x7D,0x97,0x05,0x67,
+0xCE,0x0E,0x85,0x95,0x37,0x6A,0xED,0x09,0xB6,0xAE,0x67,0xCD,0x51,0x64,0x9F,0xC6,
+0x5C,0xD1,0xBC,0x57,0x6E,0x67,0x35,0x80,0x76,0x36,0xA4,0x87,0x81,0x6E,0x38,0x8F,
+0xD8,0x2B,0x15,0x4E,0x7B,0x25,0xD8,0x5A,0xBF,0x4E,0x83,0xC1,0x8D,0xD2,0x93,0xD5,
+0x1A,0x71,0xB5,0x60,0x9C,0x9D,0x33,0x4E,0x55,0xF9,0x12,0x58,0x0C,0x86,0xB8,0x16,
+0x0D,0xC1,0xE5,0x77,0x45,0x8D,0x50,0x48,0xBA,0x2B,0x2D,0xE4,0x94,0x85,0xE1,0xE8,
+0xC4,0x9D,0xC6,0x68,0xA5,0xB0,0xA3,0xFC,0x67,0x7E,0x70,0xBA,0x02,0x59,0x4B,0x77,
+0x42,0x91,0x39,0xB9,0xF5,0xCD,0xE1,0x4C,0xEF,0xC0,0x3B,0x48,0x8C,0xA6,0xE5,0x21,
+0x5D,0xFD,0x6A,0x6A,0xBB,0xA7,0x16,0x35,0x60,0xD2,0xE6,0xAD,0xF3,0x46,0x29,0xC9,
+0xE8,0xC3,0x8B,0xE9,0x79,0xC0,0x6A,0x61,0x67,0x15,0xB2,0xF0,0xFD,0xE5,0x68,0xBC,
+0x62,0x5F,0x6E,0xCF,0x99,0xDD,0xEF,0x1B,0x63,0xFE,0x92,0x65,0xAB,0x02,0x03,0x01,
+0x00,0x01,0xA3,0x81,0xAE,0x30,0x81,0xAB,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,
+0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x86,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,
+0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,
+0x04,0x16,0x04,0x14,0x88,0x27,0x17,0x09,0xA9,0xB6,0x18,0x60,0x8B,0xEC,0xEB,0xBA,
+0xF6,0x47,0x59,0xC5,0x52,0x54,0xA3,0xB7,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,
+0x18,0x30,0x16,0x80,0x14,0x2B,0xD0,0x69,0x47,0x94,0x76,0x09,0xFE,0xF4,0x6B,0x8D,
+0x2E,0x40,0xA6,0xF7,0x47,0x4D,0x7F,0x08,0x5E,0x30,0x36,0x06,0x03,0x55,0x1D,0x1F,
+0x04,0x2F,0x30,0x2D,0x30,0x2B,0xA0,0x29,0xA0,0x27,0x86,0x25,0x68,0x74,0x74,0x70,
+0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,
+0x2F,0x61,0x70,0x70,0x6C,0x65,0x63,0x61,0x2F,0x72,0x6F,0x6F,0x74,0x2E,0x63,0x72,
+0x6C,0x30,0x10,0x06,0x0A,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,0x06,0x02,0x01,0x04,
+0x02,0x05,0x00,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,
+0x05,0x00,0x03,0x82,0x01,0x01,0x00,0xDA,0x32,0x00,0x96,0xC5,0x54,0x94,0xD3,0x3B,
+0x82,0x37,0x66,0x7D,0x2E,0x68,0xD5,0xC3,0xC6,0xB8,0xCB,0x26,0x8C,0x48,0x90,0xCF,
+0x13,0x24,0x6A,0x46,0x8E,0x63,0xD4,0xF0,0xD0,0x13,0x06,0xDD,0xD8,0xC4,0xC1,0x37,
+0x15,0xF2,0x33,0x13,0x39,0x26,0x2D,0xCE,0x2E,0x55,0x40,0xE3,0x0B,0x03,0xAF,0xFA,
+0x12,0xC2,0xE7,0x0D,0x21,0xB8,0xD5,0x80,0xCF,0xAC,0x28,0x2F,0xCE,0x2D,0xB3,0x4E,
+0xAF,0x86,0x19,0x04,0xC6,0xE9,0x50,0xDD,0x4C,0x29,0x47,0x10,0x23,0xFC,0x6C,0xBB,
+0x1B,0x98,0x6B,0x48,0x89,0xE1,0x5B,0x9D,0xDE,0x46,0xDB,0x35,0x85,0x35,0xEF,0x3E,
+0xD0,0xE2,0x58,0x4B,0x38,0xF4,0xED,0x75,0x5A,0x1F,0x5C,0x70,0x1D,0x56,0x39,0x12,
+0xE5,0xE1,0x0D,0x11,0xE4,0x89,0x25,0x06,0xBD,0xD5,0xB4,0x15,0x8E,0x5E,0xD0,0x59,
+0x97,0x90,0xE9,0x4B,0x81,0xE2,0xDF,0x18,0xAF,0x44,0x74,0x1E,0x19,0xA0,0x3A,0x47,
+0xCC,0x91,0x1D,0x3A,0xEB,0x23,0x5A,0xFE,0xA5,0x2D,0x97,0xF7,0x7B,0xBB,0xD6,0x87,
+0x46,0x42,0x85,0xEB,0x52,0x3D,0x26,0xB2,0x63,0xA8,0xB4,0xB1,0xCA,0x8F,0xF4,0xCC,
+0xE2,0xB3,0xC8,0x47,0xE0,0xBF,0x9A,0x59,0x83,0xFA,0xDA,0x98,0x53,0x2A,0x82,0xF5,
+0x7C,0x65,0x2E,0x95,0xD9,0x33,0x5D,0xF5,0xED,0x65,0xCC,0x31,0x37,0xC5,0x5A,0x04,
+0xE8,0x6B,0xE1,0xE7,0x88,0x03,0x4A,0x75,0x9E,0x9B,0x28,0xCB,0x4A,0x40,0x88,0x65,
+0x43,0x75,0xDD,0xCB,0x3A,0x25,0x23,0xC5,0x9E,0x57,0xF8,0x2E,0xCE,0xD2,0xA9,0x92,
+0x5E,0x73,0x2E,0x2F,0x25,0x75,0x15,
+};
+
+
+#define CFReleaseSafe(CF) { CFTypeRef _cf = (CF); if (_cf) CFRelease(_cf); }
+#define CFReleaseNull(CF) { CFTypeRef _cf = (CF); \
+       if (_cf) { (CF) = NULL; CFRelease(_cf); } }
+
+static void tests(void)
+{
+       SecTrustRef trust;
+       SecCertificateRef cert0, cert1;
+       isnt(cert0 = SecCertificateCreateWithBytes(NULL, WWDR_NoRevInfo, sizeof(WWDR_NoRevInfo)),
+                       NULL, "create leaf");
+       isnt(cert1 = SecCertificateCreateWithBytes(NULL, WWDR_CA, sizeof(WWDR_CA)),
+                       NULL, "create intermediate");
+       CFMutableArrayRef certs = CFArrayCreateMutable(kCFAllocatorDefault, 0,
+                       &kCFTypeArrayCallBacks);
+       CFArrayAppendValue(certs, cert0);
+       CFArrayAppendValue(certs, cert1);
+
+       /* at this point, we should have an OCSP responder for the WWDR-issued leaf cert,
+        * even though the leaf itself doesn't contain any revocation info.
+        */
+       CFArrayRef ocspResponders = SecCertificateGetOCSPResponders(cert0);
+       ok(ocspResponders != NULL, "synthesized OCSP responder successfully");
+
+       SecPolicyRef signingPolicy = SecPolicyCreateCodeSigning();
+       SecPolicyRef ocspPolicy = SecPolicyCreateRevocation();
+       const void *v_policies[] = { signingPolicy, ocspPolicy };
+       CFArrayRef policies = CFArrayCreate(NULL, v_policies,
+                       sizeof(v_policies) / sizeof(*v_policies), &kCFTypeArrayCallBacks);
+       CFRelease(signingPolicy);
+       CFRelease(ocspPolicy);
+       ok_status(SecTrustCreateWithCertificates(certs, policies, &trust),
+                       "create trust");
+       /* Aug 1st 2012. */
+       CFGregorianDate g_date = { 2012, 8, 1, 12, 0, 0 }; // Aug 1 2012 12:00 PM
+       CFDateRef date = CFDateCreate(kCFAllocatorDefault,
+                       CFGregorianDateGetAbsoluteTime(g_date, NULL));
+#if 0
+       /* will we trust the OCSP response for a verify date in the past?? */
+       ok_status(SecTrustSetVerifyDate(trust, date), "set date");
+#else
+       ok_status(errSecSuccess, "using current date");
+#endif
+
+       SecTrustResultType trustResult;
+       ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+
+       /* The cert should either be reported as revoked (until Jan 13 2013),
+        * or as expired (after Jan 13 2013). That means its trust result value
+     * should be 5 (kSecTrustResultRecoverableTrustFailure) or greater.
+        */
+       ok(trustResult >= kSecTrustResultRecoverableTrustFailure,
+       "trustResult must report a failure, cert is either expired or revoked");
+#if 0
+    fprintf(stderr, "=== trustResult %lu\n", trustResult);
+    CFStringRef errStr = SecTrustCopyFailureDescription(trust);
+    CFShow(errStr);
+#endif
+
+       CFReleaseSafe(trust);
+       CFReleaseSafe(policies);
+       CFReleaseSafe(certs);
+       CFReleaseSafe(cert0);
+       CFReleaseSafe(cert1);
+       CFReleaseSafe(date);
+}
+
+int si_23_sectrust_ocsp_wwdr(int argc, char *const *argv)
+{
+       plan_tests(7);
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-23-sectrust-ocsp.c b/sec/Security/Regressions/secitem/si-23-sectrust-ocsp.c
new file mode 100644 (file)
index 0000000..3fa8e42
--- /dev/null
@@ -0,0 +1,777 @@
+/*
+ * Copyright (c) 2006-2009 Apple Inc. All Rights Reserved.
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecPolicyPriv.h>
+#include <Security/SecTrustPriv.h>
+#include <utilities/array_size.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "Security_regressions.h"
+
+/* subject:/1.3.6.1.4.1.311.60.2.1.3=US/1.3.6.1.4.1.311.60.2.1.2=Delaware/2.5.4.15=V1.0, Clause 5.(b)/serialNumber=3014267/C=US/postalCode=95131-2021/ST=California/L=San Jose/streetAddress=2211 N 1st St/O=PayPal, Inc./OU=Information Systems/CN=www.paypal.com */
+/* issuer :/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)06/CN=VeriSign Class 3 Extended Validation SSL SGC CA */
+static const uint8_t _c0[]={
+0x30,0x82,0x05,0xCC,0x30,0x82,0x04,0xB4,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x63,
+0x4D,0xCE,0x1C,0x61,0x9F,0xFB,0x6B,0x26,0x1E,0x05,0xAD,0x5B,0xA9,0x85,0x86,0x30,
+0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81,
+0xBE,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,0x65,0x72,0x69,0x53,0x69,0x67,
+0x6E,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x0B,
+0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x54,0x72,0x75,0x73,0x74,
+0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x31,0x3B,0x30,0x39,0x06,0x03,0x55,0x04,
+0x0B,0x13,0x32,0x54,0x65,0x72,0x6D,0x73,0x20,0x6F,0x66,0x20,0x75,0x73,0x65,0x20,
+0x61,0x74,0x20,0x68,0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x76,
+0x65,0x72,0x69,0x73,0x69,0x67,0x6E,0x2E,0x63,0x6F,0x6D,0x2F,0x72,0x70,0x61,0x20,
+0x28,0x63,0x29,0x30,0x36,0x31,0x38,0x30,0x36,0x06,0x03,0x55,0x04,0x03,0x13,0x2F,
+0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x33,
+0x20,0x45,0x78,0x74,0x65,0x6E,0x64,0x65,0x64,0x20,0x56,0x61,0x6C,0x69,0x64,0x61,
+0x74,0x69,0x6F,0x6E,0x20,0x53,0x53,0x4C,0x20,0x53,0x47,0x43,0x20,0x43,0x41,0x30,
+0x1E,0x17,0x0D,0x30,0x38,0x30,0x35,0x30,0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,
+0x17,0x0D,0x30,0x39,0x30,0x35,0x30,0x32,0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,
+0x82,0x01,0x0F,0x31,0x13,0x30,0x11,0x06,0x0B,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,
+0x3C,0x02,0x01,0x03,0x13,0x02,0x55,0x53,0x31,0x19,0x30,0x17,0x06,0x0B,0x2B,0x06,
+0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x02,0x13,0x08,0x44,0x65,0x6C,0x61,0x77,
+0x61,0x72,0x65,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x0F,0x13,0x12,0x56,0x31,
+0x2E,0x30,0x2C,0x20,0x43,0x6C,0x61,0x75,0x73,0x65,0x20,0x35,0x2E,0x28,0x62,0x29,
+0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x05,0x13,0x07,0x33,0x30,0x31,0x34,0x32,
+0x36,0x37,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,
+0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x11,0x14,0x0A,0x39,0x35,0x31,0x33,0x31,0x2D,
+0x32,0x30,0x32,0x31,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x08,0x13,0x0A,0x43,
+0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61,0x31,0x11,0x30,0x0F,0x06,0x03,0x55,
+0x04,0x07,0x14,0x08,0x53,0x61,0x6E,0x20,0x4A,0x6F,0x73,0x65,0x31,0x16,0x30,0x14,
+0x06,0x03,0x55,0x04,0x09,0x14,0x0D,0x32,0x32,0x31,0x31,0x20,0x4E,0x20,0x31,0x73,
+0x74,0x20,0x53,0x74,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x0A,0x14,0x0C,0x50,
+0x61,0x79,0x50,0x61,0x6C,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1C,0x30,0x1A,0x06,
+0x03,0x55,0x04,0x0B,0x14,0x13,0x49,0x6E,0x66,0x6F,0x72,0x6D,0x61,0x74,0x69,0x6F,
+0x6E,0x20,0x53,0x79,0x73,0x74,0x65,0x6D,0x73,0x31,0x17,0x30,0x15,0x06,0x03,0x55,
+0x04,0x03,0x14,0x0E,0x77,0x77,0x77,0x2E,0x70,0x61,0x79,0x70,0x61,0x6C,0x2E,0x63,
+0x6F,0x6D,0x30,0x81,0x9F,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,
+0x01,0x01,0x05,0x00,0x03,0x81,0x8D,0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xD9,
+0x11,0xDB,0xC4,0x0A,0xC2,0x68,0x25,0x78,0xF8,0x21,0x5A,0xA4,0x75,0x85,0xDB,0x55,
+0xDF,0xA0,0x65,0x55,0x40,0x15,0xB6,0x0B,0x72,0xB1,0xE2,0x86,0x0A,0x42,0x40,0x84,
+0x23,0x44,0x24,0xBA,0xA6,0x7D,0x25,0x4C,0x89,0x79,0xB0,0xAD,0x0A,0xC9,0x59,0x78,
+0xD2,0xFB,0xF2,0x25,0x0A,0x0F,0x3B,0x67,0x92,0x11,0xDA,0x71,0x3B,0x2B,0x3F,0xD6,
+0x49,0x86,0x33,0x10,0x31,0x48,0x15,0x93,0x84,0xA5,0x32,0x80,0xB4,0x12,0x77,0x14,
+0x70,0xF8,0x9A,0x79,0x95,0x8E,0x39,0x48,0x14,0x2C,0x69,0x83,0x72,0x24,0x64,0x87,
+0x18,0x6E,0x8D,0x37,0x45,0xC5,0xC7,0xF1,0x02,0x5E,0x5D,0x5A,0x1F,0x8E,0x5F,0x8C,
+0x68,0xED,0x18,0x0B,0xE0,0x78,0x42,0x9C,0x45,0x5D,0xE3,0xF6,0xDF,0x49,0xE9,0x02,
+0x03,0x01,0x00,0x01,0xA3,0x82,0x01,0xF4,0x30,0x82,0x01,0xF0,0x30,0x09,0x06,0x03,
+0x55,0x1D,0x13,0x04,0x02,0x30,0x00,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,
+0x04,0x14,0x84,0xC4,0x7D,0xEB,0x50,0x81,0x49,0xC0,0x42,0xB5,0xC8,0x46,0x2B,0xBA,
+0x24,0xE7,0x41,0x15,0x8F,0x2B,0x30,0x0B,0x06,0x03,0x55,0x1D,0x0F,0x04,0x04,0x03,
+0x02,0x05,0xA0,0x30,0x44,0x06,0x03,0x55,0x1D,0x20,0x04,0x3D,0x30,0x3B,0x30,0x39,
+0x06,0x0B,0x60,0x86,0x48,0x01,0x86,0xF8,0x45,0x01,0x07,0x17,0x06,0x30,0x2A,0x30,
+0x28,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1C,0x68,0x74,0x74,
+0x70,0x73,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x76,0x65,0x72,0x69,0x73,0x69,0x67,
+0x6E,0x2E,0x63,0x6F,0x6D,0x2F,0x72,0x70,0x61,0x30,0x3E,0x06,0x03,0x55,0x1D,0x1F,
+0x04,0x37,0x30,0x35,0x30,0x33,0xA0,0x31,0xA0,0x2F,0x86,0x2D,0x68,0x74,0x74,0x70,
+0x3A,0x2F,0x2F,0x45,0x56,0x49,0x6E,0x74,0x6C,0x2D,0x63,0x72,0x6C,0x2E,0x76,0x65,
+0x72,0x69,0x73,0x69,0x67,0x6E,0x2E,0x63,0x6F,0x6D,0x2F,0x45,0x56,0x49,0x6E,0x74,
+0x6C,0x32,0x30,0x30,0x36,0x2E,0x63,0x72,0x6C,0x30,0x28,0x06,0x03,0x55,0x1D,0x25,
+0x04,0x21,0x30,0x1F,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01,0x06,0x08,
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,
+0x42,0x04,0x01,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,
+0x4E,0x43,0xC8,0x1D,0x76,0xEF,0x37,0x53,0x7A,0x4F,0xF2,0x58,0x6F,0x94,0xF3,0x38,
+0xE2,0xD5,0xBD,0xDF,0x30,0x76,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,
+0x04,0x6A,0x30,0x68,0x30,0x2B,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,
+0x86,0x1F,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x45,0x56,0x49,0x6E,0x74,0x6C,0x2D,
+0x6F,0x63,0x73,0x70,0x2E,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6E,0x2E,0x63,0x6F,
+0x6D,0x30,0x39,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x2D,0x68,
+0x74,0x74,0x70,0x3A,0x2F,0x2F,0x45,0x56,0x49,0x6E,0x74,0x6C,0x2D,0x61,0x69,0x61,
+0x2E,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6E,0x2E,0x63,0x6F,0x6D,0x2F,0x45,0x56,
+0x49,0x6E,0x74,0x6C,0x32,0x30,0x30,0x36,0x2E,0x63,0x65,0x72,0x30,0x6E,0x06,0x08,
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0C,0x04,0x62,0x30,0x60,0xA1,0x5E,0xA0,0x5C,
+0x30,0x5A,0x30,0x58,0x30,0x56,0x16,0x09,0x69,0x6D,0x61,0x67,0x65,0x2F,0x67,0x69,
+0x66,0x30,0x21,0x30,0x1F,0x30,0x07,0x06,0x05,0x2B,0x0E,0x03,0x02,0x1A,0x04,0x14,
+0x4B,0x6B,0xB9,0x28,0x96,0x06,0x0C,0xBB,0xD0,0x52,0x38,0x9B,0x29,0xAC,0x4B,0x07,
+0x8B,0x21,0x05,0x18,0x30,0x26,0x16,0x24,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6C,
+0x6F,0x67,0x6F,0x2E,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6E,0x2E,0x63,0x6F,0x6D,
+0x2F,0x76,0x73,0x6C,0x6F,0x67,0x6F,0x31,0x2E,0x67,0x69,0x66,0x30,0x0D,0x06,0x09,
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,
+0x61,0x3B,0x51,0x57,0xA5,0x3C,0x25,0xD3,0x22,0x05,0x58,0x99,0x80,0x86,0x1F,0xED,
+0x5C,0x8C,0xD8,0xE0,0xD3,0xF9,0x05,0x84,0x46,0x9C,0xC9,0x3A,0xD8,0x15,0x91,0xF6,
+0x34,0x37,0xC9,0x9A,0x6D,0xB3,0x48,0x3E,0x3E,0xD8,0x8B,0xE9,0x1A,0x96,0x7D,0xA8,
+0x34,0xA7,0x58,0x86,0x2E,0xE8,0xB2,0x99,0xCB,0xD3,0x61,0x07,0x96,0x4A,0xC8,0x26,
+0x7B,0x80,0x31,0xC2,0x70,0x7E,0xE9,0x4F,0x26,0x10,0x6A,0x2E,0x8F,0x03,0x8C,0x99,
+0x3A,0x06,0x46,0x14,0xEF,0x97,0x5C,0xED,0xEB,0x8D,0x6F,0xB8,0xC0,0xFB,0xD9,0x4D,
+0xC1,0x46,0x77,0x82,0x3D,0x66,0xDA,0x37,0xEF,0x1F,0xD3,0x4A,0xC5,0xF1,0x06,0xFC,
+0x76,0x95,0xFF,0x85,0xDC,0x33,0x74,0xAE,0x0C,0xDB,0x04,0x7D,0x88,0xC6,0x36,0x0D,
+0xBD,0x18,0xFE,0x0A,0x9C,0x23,0xED,0x67,0x28,0xB0,0xF7,0x0A,0xDD,0xE8,0x2C,0x90,
+0x3C,0xE3,0x5A,0x62,0xDA,0x99,0xEA,0x14,0x68,0xF9,0x4A,0x1B,0x9F,0xDC,0x20,0xB0,
+0x06,0xE4,0xFF,0x74,0x17,0x4C,0x89,0xE8,0x74,0x5B,0x1E,0x9C,0xF2,0x61,0x48,0xA9,
+0xFA,0xE7,0x8F,0xCE,0x98,0xC3,0x95,0x29,0x4C,0xBF,0x32,0xB8,0x72,0x8C,0x5A,0x60,
+0x99,0xDD,0xAA,0x71,0xA2,0x48,0x05,0x69,0xA0,0xDE,0x26,0x98,0xBE,0xAE,0xD8,0xDD,
+0xB3,0x59,0xEA,0xAA,0x55,0x0C,0xF5,0xCA,0x2B,0x57,0xFF,0x33,0x4C,0xEA,0xE9,0x93,
+0x25,0x8F,0x48,0x4F,0xF8,0xE4,0xC0,0xF8,0x5C,0x15,0xBB,0xD7,0x05,0x9C,0x74,0x13,
+0xF3,0x67,0x01,0x3C,0x15,0xF1,0xBA,0x47,0x15,0xAF,0xF6,0xA8,0x5D,0xE3,0x56,0x41
+};
+
+
+/* subject:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)06/CN=VeriSign Class 3 Extended Validation SSL SGC CA */
+/* issuer :/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G5 */
+static const uint8_t _c1[]= {
+0x30,0x82,0x06,0x0A,0x30,0x82,0x04,0xF2,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x11,
+0x2A,0x00,0x6D,0x37,0xE5,0x10,0x6F,0xD6,0xCA,0x7C,0xC3,0xEF,0xBA,0xCC,0x18,0x30,
+0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81,
+0xCA,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,0x65,0x72,0x69,0x53,0x69,0x67,
+0x6E,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x0B,
+0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x54,0x72,0x75,0x73,0x74,
+0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04,
+0x0B,0x13,0x31,0x28,0x63,0x29,0x20,0x32,0x30,0x30,0x36,0x20,0x56,0x65,0x72,0x69,
+0x53,0x69,0x67,0x6E,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72,
+0x20,0x61,0x75,0x74,0x68,0x6F,0x72,0x69,0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20,
+0x6F,0x6E,0x6C,0x79,0x31,0x45,0x30,0x43,0x06,0x03,0x55,0x04,0x03,0x13,0x3C,0x56,
+0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x33,0x20,
+0x50,0x75,0x62,0x6C,0x69,0x63,0x20,0x50,0x72,0x69,0x6D,0x61,0x72,0x79,0x20,0x43,
+0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,
+0x68,0x6F,0x72,0x69,0x74,0x79,0x20,0x2D,0x20,0x47,0x35,0x30,0x1E,0x17,0x0D,0x30,
+0x36,0x31,0x31,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x36,
+0x31,0x31,0x30,0x37,0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x81,0xBE,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,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x2C,0x20,
+0x49,0x6E,0x63,0x2E,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x0B,0x13,0x16,0x56,
+0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4E,0x65,
+0x74,0x77,0x6F,0x72,0x6B,0x31,0x3B,0x30,0x39,0x06,0x03,0x55,0x04,0x0B,0x13,0x32,
+0x54,0x65,0x72,0x6D,0x73,0x20,0x6F,0x66,0x20,0x75,0x73,0x65,0x20,0x61,0x74,0x20,
+0x68,0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x76,0x65,0x72,0x69,
+0x73,0x69,0x67,0x6E,0x2E,0x63,0x6F,0x6D,0x2F,0x72,0x70,0x61,0x20,0x28,0x63,0x29,
+0x30,0x36,0x31,0x38,0x30,0x36,0x06,0x03,0x55,0x04,0x03,0x13,0x2F,0x56,0x65,0x72,
+0x69,0x53,0x69,0x67,0x6E,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x33,0x20,0x45,0x78,
+0x74,0x65,0x6E,0x64,0x65,0x64,0x20,0x56,0x61,0x6C,0x69,0x64,0x61,0x74,0x69,0x6F,
+0x6E,0x20,0x53,0x53,0x4C,0x20,0x53,0x47,0x43,0x20,0x43,0x41,0x30,0x82,0x01,0x22,
+0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,
+0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xBD,0x56,0x88,
+0xBA,0x88,0x34,0x64,0x64,0xCF,0xCD,0xCA,0xB0,0xEE,0xE7,0x19,0x73,0xC5,0x72,0xD9,
+0xBB,0x45,0xBC,0xB5,0xA8,0xFF,0x83,0xBE,0x1C,0x03,0xDB,0xED,0x89,0xB7,0x2E,0x10,
+0x1A,0x25,0xBC,0x55,0xCA,0x41,0xA1,0x9F,0x0B,0xCF,0x19,0x5E,0x70,0xB9,0x5E,0x39,
+0x4B,0x9E,0x31,0x1C,0x5F,0x87,0xAE,0x2A,0xAA,0xA8,0x2B,0xA2,0x1B,0x3B,0x10,0x23,
+0x5F,0x13,0xB1,0xDD,0x08,0x8C,0x4E,0x14,0xDA,0x83,0x81,0xE3,0xB5,0x8C,0xE3,0x68,
+0xED,0x24,0x67,0xCE,0x56,0xB6,0xAC,0x9B,0x73,0x96,0x44,0xDB,0x8A,0x8C,0xB3,0xD6,
+0xF0,0x71,0x93,0x8E,0xDB,0x71,0x54,0x4A,0xEB,0x73,0x59,0x6A,0x8F,0x70,0x51,0x2C,
+0x03,0x9F,0x97,0xD1,0xCC,0x11,0x7A,0xBC,0x62,0x0D,0x95,0x2A,0xC9,0x1C,0x75,0x57,
+0xE9,0xF5,0xC7,0xEA,0xBA,0x84,0x35,0xCB,0xC7,0x85,0x5A,0x7E,0xE4,0x4D,0xE1,0x11,
+0x97,0x7D,0x0E,0x20,0x34,0x45,0xDB,0xF1,0xA2,0x09,0xEB,0xEB,0x3D,0x9E,0xB8,0x96,
+0x43,0x5E,0x34,0x4B,0x08,0x25,0x1E,0x43,0x1A,0xA2,0xD9,0xB7,0x8A,0x01,0x34,0x3D,
+0xC3,0xF8,0xE5,0xAF,0x4F,0x8C,0xFF,0xCD,0x65,0xF0,0x23,0x4E,0xC5,0x97,0xB3,0x5C,
+0xDA,0x90,0x1C,0x82,0x85,0x0D,0x06,0x0D,0xC1,0x22,0xB6,0x7B,0x28,0xA4,0x03,0xC3,
+0x4C,0x53,0xD1,0x58,0xBC,0x72,0xBC,0x08,0x39,0xFC,0xA0,0x76,0xA8,0xA8,0xE9,0x4B,
+0x6E,0x88,0x3D,0xE3,0xB3,0x31,0x25,0x8C,0x73,0x29,0x48,0x0E,0x32,0x79,0x06,0xED,
+0x3D,0x43,0xF4,0xF6,0xE4,0xE9,0xFC,0x7D,0xBE,0x8E,0x08,0xD5,0x1F,0x02,0x03,0x01,
+0x00,0x01,0xA3,0x82,0x01,0xF4,0x30,0x82,0x01,0xF0,0x30,0x1D,0x06,0x03,0x55,0x1D,
+0x0E,0x04,0x16,0x04,0x14,0x4E,0x43,0xC8,0x1D,0x76,0xEF,0x37,0x53,0x7A,0x4F,0xF2,
+0x58,0x6F,0x94,0xF3,0x38,0xE2,0xD5,0xBD,0xDF,0x30,0x12,0x06,0x03,0x55,0x1D,0x13,
+0x01,0x01,0xFF,0x04,0x08,0x30,0x06,0x01,0x01,0xFF,0x02,0x01,0x00,0x30,0x3D,0x06,
+0x03,0x55,0x1D,0x20,0x04,0x36,0x30,0x34,0x30,0x32,0x06,0x04,0x55,0x1D,0x20,0x00,
+0x30,0x2A,0x30,0x28,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1C,
+0x68,0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x76,0x65,0x72,0x69,
+0x73,0x69,0x67,0x6E,0x2E,0x63,0x6F,0x6D,0x2F,0x63,0x70,0x73,0x30,0x3D,0x06,0x03,
+0x55,0x1D,0x1F,0x04,0x36,0x30,0x34,0x30,0x32,0xA0,0x30,0xA0,0x2E,0x86,0x2C,0x68,
+0x74,0x74,0x70,0x3A,0x2F,0x2F,0x45,0x56,0x53,0x65,0x63,0x75,0x72,0x65,0x2D,0x63,
+0x72,0x6C,0x2E,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6E,0x2E,0x63,0x6F,0x6D,0x2F,
+0x70,0x63,0x61,0x33,0x2D,0x67,0x35,0x2E,0x63,0x72,0x6C,0x30,0x20,0x06,0x03,0x55,
+0x1D,0x25,0x04,0x19,0x30,0x17,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x04,
+0x01,0x06,0x0A,0x60,0x86,0x48,0x01,0x86,0xF8,0x45,0x01,0x08,0x01,0x30,0x0E,0x06,
+0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x11,0x06,
+0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x01,0x06,
+0x30,0x6D,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0C,0x04,0x61,0x30,0x5F,
+0xA1,0x5D,0xA0,0x5B,0x30,0x59,0x30,0x57,0x30,0x55,0x16,0x09,0x69,0x6D,0x61,0x67,
+0x65,0x2F,0x67,0x69,0x66,0x30,0x21,0x30,0x1F,0x30,0x07,0x06,0x05,0x2B,0x0E,0x03,
+0x02,0x1A,0x04,0x14,0x8F,0xE5,0xD3,0x1A,0x86,0xAC,0x8D,0x8E,0x6B,0xC3,0xCF,0x80,
+0x6A,0xD4,0x48,0x18,0x2C,0x7B,0x19,0x2E,0x30,0x25,0x16,0x23,0x68,0x74,0x74,0x70,
+0x3A,0x2F,0x2F,0x6C,0x6F,0x67,0x6F,0x2E,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6E,
+0x2E,0x63,0x6F,0x6D,0x2F,0x76,0x73,0x6C,0x6F,0x67,0x6F,0x2E,0x67,0x69,0x66,0x30,
+0x29,0x06,0x03,0x55,0x1D,0x11,0x04,0x22,0x30,0x20,0xA4,0x1E,0x30,0x1C,0x31,0x1A,
+0x30,0x18,0x06,0x03,0x55,0x04,0x03,0x13,0x11,0x43,0x6C,0x61,0x73,0x73,0x33,0x43,
+0x41,0x32,0x30,0x34,0x38,0x2D,0x31,0x2D,0x34,0x38,0x30,0x3D,0x06,0x08,0x2B,0x06,
+0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x31,0x30,0x2F,0x30,0x2D,0x06,0x08,0x2B,0x06,
+0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x21,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x45,
+0x56,0x53,0x65,0x63,0x75,0x72,0x65,0x2D,0x6F,0x63,0x73,0x70,0x2E,0x76,0x65,0x72,
+0x69,0x73,0x69,0x67,0x6E,0x2E,0x63,0x6F,0x6D,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,
+0x04,0x18,0x30,0x16,0x80,0x14,0x7F,0xD3,0x65,0xA7,0xC2,0xDD,0xEC,0xBB,0xF0,0x30,
+0x09,0xF3,0x43,0x39,0xFA,0x02,0xAF,0x33,0x31,0x33,0x30,0x0D,0x06,0x09,0x2A,0x86,
+0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x5A,0xA2,
+0xB1,0xBF,0xEB,0x8D,0xD4,0x38,0xA8,0x80,0x72,0xC2,0xDC,0x38,0x2E,0xAC,0xA7,0x71,
+0xF9,0x2B,0xA3,0xBB,0x47,0xBB,0x6D,0x69,0x6F,0x10,0x36,0x98,0x8C,0xC7,0x56,0x2E,
+0xBB,0xBC,0xAB,0x4A,0x9B,0x7A,0xD6,0xF2,0x82,0x93,0xE0,0x14,0xFE,0x8A,0xCE,0x83,
+0xB7,0x83,0xDB,0x93,0x87,0xAB,0xAC,0x65,0x79,0x49,0xFD,0x57,0xA9,0xB1,0xCE,0x09,
+0x1F,0xBA,0x10,0x15,0xC4,0x09,0x0E,0x62,0xE3,0xF9,0x0A,0x25,0xD5,0x64,0x98,0xF0,
+0xF2,0xA8,0x0F,0x76,0x32,0x7E,0x91,0xE6,0x18,0xEE,0xBC,0xE7,0xDA,0xD0,0x4E,0x8D,
+0x78,0xBB,0xE2,0x9D,0xC0,0x59,0x2B,0xC0,0xCE,0x95,0x0D,0x24,0x0C,0x72,0xCA,0x34,
+0x5E,0x70,0x22,0x89,0x2B,0x4A,0xB0,0xF1,0x68,0x87,0xF3,0xEE,0x44,0x8D,0x28,0x40,
+0x77,0x39,0x6E,0x48,0x72,0x45,0x31,0x5D,0x6B,0x39,0x0E,0x86,0x02,0xEA,0x66,0x99,
+0x93,0x31,0x0F,0xDF,0x67,0xDE,0xA6,0x9F,0x8C,0x9D,0x4C,0xCE,0x71,0x6F,0x3A,0x21,
+0xF6,0xB9,0x34,0x3F,0xF9,0x6E,0xD8,0x9A,0xF7,0x3E,0xDA,0xF3,0x81,0x5F,0x7A,0x5C,
+0x6D,0x8F,0x7C,0xF6,0x99,0x74,0xB7,0xFF,0xE4,0x17,0x5D,0xED,0x61,0x5E,0xAB,0x48,
+0xBB,0x96,0x8D,0x66,0x45,0x39,0xB4,0x12,0x0A,0xF6,0x70,0xE9,0x9C,0x76,0x22,0x4B,
+0x60,0xE9,0x2A,0x1B,0x34,0x49,0xF7,0xA2,0xD4,0x67,0xC0,0xB1,0x26,0xAD,0x13,0xBA,
+0xD9,0x84,0x01,0xC1,0xAB,0xE1,0x8E,0x6D,0x70,0x16,0x3B,0x77,0xAC,0x91,0x9A,0xBB,
+0x1A,0x1F,0xDA,0x58,0xA7,0xE4,0x4F,0xC1,0x61,0xAE,0xBC,0xA2,0xFE,0x4B
+};
+
+static const uint8_t _responderCert[]= {
+0x30,0x82,0x04,0xAC,0x30,0x82,0x03,0x94,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x5F,
+0xF9,0xFB,0x30,0x1A,0x50,0xF5,0xA2,0x0D,0x3B,0x05,0xC1,0x47,0xAB,0x0B,0x7E,0x30,
+0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81,
+0xBE,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,0x65,0x72,0x69,0x53,0x69,0x67,
+0x6E,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x0B,
+0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x54,0x72,0x75,0x73,0x74,
+0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x31,0x3B,0x30,0x39,0x06,0x03,0x55,0x04,
+0x0B,0x13,0x32,0x54,0x65,0x72,0x6D,0x73,0x20,0x6F,0x66,0x20,0x75,0x73,0x65,0x20,
+0x61,0x74,0x20,0x68,0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x76,
+0x65,0x72,0x69,0x73,0x69,0x67,0x6E,0x2E,0x63,0x6F,0x6D,0x2F,0x72,0x70,0x61,0x20,
+0x28,0x63,0x29,0x30,0x36,0x31,0x38,0x30,0x36,0x06,0x03,0x55,0x04,0x03,0x13,0x2F,
+0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x33,
+0x20,0x45,0x78,0x74,0x65,0x6E,0x64,0x65,0x64,0x20,0x56,0x61,0x6C,0x69,0x64,0x61,
+0x74,0x69,0x6F,0x6E,0x20,0x53,0x53,0x4C,0x20,0x53,0x47,0x43,0x20,0x43,0x41,0x30,
+0x1E,0x17,0x0D,0x30,0x39,0x30,0x33,0x31,0x37,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,
+0x17,0x0D,0x30,0x39,0x30,0x36,0x31,0x35,0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,
+0x81,0xCA,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,0x65,0x72,0x69,0x53,0x69,
+0x67,0x6E,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,
+0x0B,0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x54,0x72,0x75,0x73,
+0x74,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x31,0x3B,0x30,0x39,0x06,0x03,0x55,
+0x04,0x0B,0x13,0x32,0x54,0x65,0x72,0x6D,0x73,0x20,0x6F,0x66,0x20,0x75,0x73,0x65,
+0x20,0x61,0x74,0x20,0x68,0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,
+0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6E,0x2E,0x63,0x6F,0x6D,0x2F,0x72,0x70,0x61,
+0x20,0x28,0x63,0x29,0x30,0x36,0x31,0x44,0x30,0x42,0x06,0x03,0x55,0x04,0x03,0x13,
+0x3B,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,
+0x33,0x20,0x45,0x78,0x74,0x65,0x6E,0x64,0x65,0x64,0x20,0x56,0x61,0x6C,0x69,0x64,
+0x61,0x74,0x69,0x6F,0x6E,0x20,0x53,0x53,0x4C,0x20,0x53,0x47,0x43,0x20,0x4F,0x43,
+0x53,0x50,0x20,0x52,0x65,0x73,0x70,0x6F,0x6E,0x64,0x65,0x72,0x30,0x81,0x9F,0x30,
+0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x81,
+0x8D,0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xC8,0x31,0x14,0x85,0x67,0xCD,0xB2,
+0x3B,0xAA,0x94,0xD9,0x8C,0xB2,0x50,0x17,0xAA,0x62,0xE7,0xBE,0x7A,0x29,0xD5,0xBD,
+0x6F,0x27,0x72,0x9E,0xC4,0x8C,0xB8,0x58,0xF2,0x20,0x9C,0x51,0x53,0x61,0x83,0x2D,
+0x08,0xC8,0xE0,0x3F,0xF6,0x79,0x53,0xBD,0xFB,0x7A,0x5E,0x10,0xB8,0xCA,0x13,0x78,
+0x85,0x61,0xF9,0x63,0xD9,0x31,0x3B,0xCE,0x6A,0xEB,0x8C,0x02,0xD8,0xDA,0xB0,0x72,
+0x17,0x46,0x1A,0x0E,0x26,0xC3,0x2A,0x7A,0x2E,0x89,0x42,0xB6,0xB0,0xC6,0x20,0x24,
+0x44,0xED,0x1C,0xE0,0x91,0x7A,0x68,0x3B,0xD6,0x25,0xF4,0x9B,0x6E,0xE8,0xBE,0x0C,
+0x67,0x69,0x55,0x84,0xD1,0xB4,0x36,0x04,0xE6,0xFD,0x94,0xE4,0x30,0x11,0x2D,0x13,
+0xFC,0xAF,0xB1,0x72,0xC4,0xBB,0xA7,0xA6,0x1F,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,
+0x01,0x1A,0x30,0x82,0x01,0x16,0x30,0x09,0x06,0x03,0x55,0x1D,0x13,0x04,0x02,0x30,
+0x00,0x30,0x81,0xAC,0x06,0x03,0x55,0x1D,0x20,0x04,0x81,0xA4,0x30,0x81,0xA1,0x30,
+0x81,0x9E,0x06,0x0B,0x60,0x86,0x48,0x01,0x86,0xF8,0x45,0x01,0x07,0x17,0x03,0x30,
+0x81,0x8E,0x30,0x28,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1C,
+0x68,0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x76,0x65,0x72,0x69,
+0x73,0x69,0x67,0x6E,0x2E,0x63,0x6F,0x6D,0x2F,0x43,0x50,0x53,0x30,0x62,0x06,0x08,
+0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x02,0x30,0x56,0x30,0x15,0x16,0x0E,0x56,0x65,
+0x72,0x69,0x53,0x69,0x67,0x6E,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x30,0x03,0x02,0x01,
+0x01,0x1A,0x3D,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x27,0x73,0x20,0x43,0x50,
+0x53,0x20,0x69,0x6E,0x63,0x6F,0x72,0x70,0x2E,0x20,0x62,0x79,0x20,0x72,0x65,0x66,
+0x65,0x72,0x65,0x6E,0x63,0x65,0x20,0x6C,0x69,0x61,0x62,0x2E,0x20,0x6C,0x74,0x64,
+0x2E,0x20,0x28,0x63,0x29,0x39,0x37,0x20,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,
+0x30,0x13,0x06,0x03,0x55,0x1D,0x25,0x04,0x0C,0x30,0x0A,0x06,0x08,0x2B,0x06,0x01,
+0x05,0x05,0x07,0x03,0x09,0x30,0x0B,0x06,0x03,0x55,0x1D,0x0F,0x04,0x04,0x03,0x02,
+0x07,0x80,0x30,0x0F,0x06,0x09,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x05,0x04,
+0x02,0x05,0x00,0x30,0x27,0x06,0x03,0x55,0x1D,0x11,0x04,0x20,0x30,0x1E,0xA4,0x1C,
+0x30,0x1A,0x31,0x18,0x30,0x16,0x06,0x03,0x55,0x04,0x03,0x13,0x0F,0x4F,0x43,0x53,
+0x50,0x34,0x2D,0x54,0x47,0x56,0x2D,0x33,0x2D,0x32,0x30,0x36,0x30,0x0D,0x06,0x09,
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,
+0x48,0x8E,0xBE,0x20,0xE3,0xA3,0x80,0x60,0xB8,0x6B,0x5A,0xC1,0x94,0x29,0xA4,0x4D,
+0x9C,0xED,0xD4,0xE0,0x0B,0xD9,0x5C,0xEF,0x01,0x36,0xD1,0x9F,0x76,0xB6,0x6C,0xA1,
+0xB7,0x10,0x50,0x1D,0x7C,0xE9,0x9C,0xEB,0xD4,0xF7,0x3E,0x79,0x75,0x4D,0xE8,0x32,
+0x8A,0xF1,0x4E,0xD4,0xE5,0x58,0x9C,0x5D,0x68,0x55,0xA6,0x45,0x42,0x8C,0xB2,0x9F,
+0xE4,0x0F,0x11,0xDB,0x6E,0x4B,0xEB,0xF4,0xA4,0x86,0x0C,0x24,0x59,0x3C,0x16,0x1D,
+0xA7,0xD7,0x37,0x6E,0xC6,0x05,0x6A,0x22,0x2E,0x78,0xDA,0x07,0xEF,0x4F,0xEF,0xDD,
+0xC6,0xF9,0xD8,0xAD,0xF1,0xBF,0x0A,0x73,0x88,0xF4,0x17,0xF2,0x36,0x8D,0x40,0x85,
+0x71,0x4D,0x16,0x7E,0x05,0x78,0xDE,0xBA,0x7B,0x2C,0x9F,0x35,0x5A,0xAB,0x07,0xA2,
+0x9F,0x76,0x30,0xDF,0x91,0x32,0x25,0x20,0x18,0x18,0xCA,0x22,0xEF,0x7C,0xA2,0xF7,
+0x8F,0x63,0xB8,0xB3,0x8E,0x9D,0xF8,0x12,0x87,0x3F,0x9F,0x40,0x28,0x60,0x6F,0x50,
+0xAF,0x3C,0x9E,0x78,0x46,0xC7,0x1E,0x07,0xFA,0x32,0x57,0x7E,0x0E,0x30,0xFE,0x96,
+0x41,0x5D,0xB6,0x78,0x73,0x55,0xB0,0x77,0xC0,0x1F,0x17,0xBE,0xBD,0x56,0x68,0x2E,
+0x2F,0x18,0x54,0x60,0xEB,0x88,0x81,0x8C,0x76,0xEE,0x37,0xE6,0x75,0x55,0x01,0x14,
+0xD9,0x7A,0x23,0x16,0xA4,0x01,0xF5,0x2C,0x4C,0x14,0x4C,0x52,0x90,0x92,0x76,0xE7,
+0x46,0x5D,0x82,0x4A,0x86,0xDC,0x17,0xF7,0x2C,0xC1,0xAA,0x3C,0x43,0xA0,0xBC,0x24,
+0x6C,0xFA,0xCE,0xA1,0x5D,0xCF,0x87,0x4F,0xD1,0x27,0xA6,0x23,0x7E,0x7F,0xAE,0x7A
+};
+
+/* subject:/serialNumber=424761419/1.3.6.1.4.1.311.60.2.1.3=FR/1.3.6.1.4.1.311.60.2.1.2=Nord/1.3.6.1.4.1.311.60.2.1.1=ROUBAIX/2.5.4.15=V1.0, Clause 5.(b)/C=FR/postalCode=59100/ST=Nord/L=ROUBAIX/streetAddress=140 quai du Sartel/O=OVH/OU=0002 424761419 */
+/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO EV SGC CA */
+static unsigned char ovh_certificate[1546]={
+0x30,0x82,0x06,0x06,0x30,0x82,0x04,0xEE,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x31,
+0xF0,0x42,0x6A,0x0B,0xBB,0xE7,0x45,0xD4,0x0E,0x51,0x9B,0xE0,0xE5,0xC1,0xB4,0x30,
+0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x73,
+0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x47,0x42,0x31,0x1B,0x30,
+0x19,0x06,0x03,0x55,0x04,0x08,0x13,0x12,0x47,0x72,0x65,0x61,0x74,0x65,0x72,0x20,
+0x4D,0x61,0x6E,0x63,0x68,0x65,0x73,0x74,0x65,0x72,0x31,0x10,0x30,0x0E,0x06,0x03,
+0x55,0x04,0x07,0x13,0x07,0x53,0x61,0x6C,0x66,0x6F,0x72,0x64,0x31,0x1A,0x30,0x18,
+0x06,0x03,0x55,0x04,0x0A,0x13,0x11,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x43,0x41,
+0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,
+0x03,0x13,0x10,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x45,0x56,0x20,0x53,0x47,0x43,
+0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x30,0x38,0x31,0x32,0x30,0x32,0x30,0x30,0x30,
+0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31,0x32,0x30,0x33,0x32,0x33,0x35,0x39,
+0x35,0x39,0x5A,0x30,0x82,0x01,0x48,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x05,
+0x13,0x09,0x34,0x32,0x34,0x37,0x36,0x31,0x34,0x31,0x39,0x31,0x13,0x30,0x11,0x06,
+0x0B,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x03,0x13,0x02,0x46,0x52,
+0x31,0x15,0x30,0x13,0x06,0x0B,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,
+0x02,0x13,0x04,0x4E,0x6F,0x72,0x64,0x31,0x18,0x30,0x16,0x06,0x0B,0x2B,0x06,0x01,
+0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x01,0x13,0x07,0x52,0x4F,0x55,0x42,0x41,0x49,
+0x58,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x0F,0x13,0x12,0x56,0x31,0x2E,0x30,
+0x2C,0x20,0x43,0x6C,0x61,0x75,0x73,0x65,0x20,0x35,0x2E,0x28,0x62,0x29,0x31,0x0B,
+0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x46,0x52,0x31,0x0E,0x30,0x0C,0x06,
+0x03,0x55,0x04,0x11,0x13,0x05,0x35,0x39,0x31,0x30,0x30,0x31,0x0D,0x30,0x0B,0x06,
+0x03,0x55,0x04,0x08,0x13,0x04,0x4E,0x6F,0x72,0x64,0x31,0x10,0x30,0x0E,0x06,0x03,
+0x55,0x04,0x07,0x13,0x07,0x52,0x4F,0x55,0x42,0x41,0x49,0x58,0x31,0x1B,0x30,0x19,
+0x06,0x03,0x55,0x04,0x09,0x13,0x12,0x31,0x34,0x30,0x20,0x71,0x75,0x61,0x69,0x20,
+0x64,0x75,0x20,0x53,0x61,0x72,0x74,0x65,0x6C,0x31,0x0C,0x30,0x0A,0x06,0x03,0x55,
+0x04,0x0A,0x13,0x03,0x4F,0x56,0x48,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0B,
+0x13,0x0E,0x30,0x30,0x30,0x32,0x20,0x34,0x32,0x34,0x37,0x36,0x31,0x34,0x31,0x39,
+0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x0B,0x13,0x16,0x48,0x6F,0x73,0x74,0x65,
+0x64,0x20,0x62,0x79,0x20,0x54,0x42,0x53,0x20,0x49,0x4E,0x54,0x45,0x52,0x4E,0x45,
+0x54,0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x0B,0x13,0x0D,0x43,0x6F,0x6D,0x6F,
+0x64,0x6F,0x20,0x45,0x56,0x20,0x53,0x53,0x4C,0x31,0x14,0x30,0x12,0x06,0x03,0x55,
+0x04,0x03,0x13,0x0B,0x77,0x77,0x77,0x2E,0x6F,0x76,0x68,0x2E,0x63,0x6F,0x6D,0x30,
+0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,
+0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,
+0xAF,0x7C,0x18,0x7E,0x00,0x52,0x8E,0x89,0x51,0x56,0x30,0xC8,0x83,0xED,0x53,0xAE,
+0x19,0xB3,0xA2,0x09,0x1A,0x17,0x41,0x6A,0x72,0x26,0xBC,0x77,0x47,0x0A,0xEA,0xA7,
+0x74,0x01,0x68,0x5D,0xC1,0x40,0x54,0x77,0xF2,0x03,0xAC,0xDA,0x1D,0x9F,0xAE,0xD0,
+0x0F,0x13,0x28,0xDD,0xF6,0x98,0xF5,0xAF,0x3D,0x69,0xDE,0xF0,0xE6,0x34,0xFD,0xB9,
+0x94,0x91,0x26,0x9D,0x56,0x9C,0xA5,0xD4,0xBA,0x04,0xFD,0xDA,0x5C,0x8D,0xCB,0x85,
+0x81,0x9D,0xD0,0x85,0x62,0x83,0x41,0xB6,0xAC,0x14,0xC3,0xAA,0xAE,0xA7,0x54,0x84,
+0xFD,0xED,0x9C,0xFC,0xB2,0x51,0xD1,0x43,0x5B,0xF3,0x6E,0xB9,0x6D,0xB1,0xE2,0x19,
+0xB1,0xB4,0xC6,0x15,0x10,0x78,0xBB,0x68,0x8D,0x4D,0x8D,0xE5,0xB2,0x97,0xFD,0x50,
+0xE1,0x07,0x14,0x0A,0xD3,0x28,0x0E,0x0A,0xFB,0xF3,0x18,0x65,0x2E,0xB1,0xD6,0xEE,
+0x00,0x4D,0xB8,0xB7,0xB9,0x86,0x90,0x97,0xC2,0x66,0xCC,0x09,0x11,0xFC,0xD7,0x4B,
+0xEF,0x4A,0x8B,0x9E,0x13,0xD0,0x5E,0x71,0x57,0xA9,0x39,0x91,0x6A,0xB2,0x60,0xC9,
+0x45,0xED,0xD9,0xFA,0x35,0xFF,0xF8,0x28,0xBB,0x87,0x90,0x99,0xBB,0x45,0x30,0x4A,
+0x15,0xC3,0x1D,0x6E,0xCD,0x02,0x1A,0x28,0x8E,0x89,0x1A,0x1A,0xC6,0x58,0xD8,0x78,
+0x1F,0xF0,0x24,0xFE,0x79,0x26,0xA8,0xCF,0x10,0x1E,0x31,0x58,0xF6,0x21,0xBA,0x05,
+0x31,0xF4,0x44,0x89,0x1B,0xC1,0x24,0x62,0x38,0xA8,0xCA,0x1A,0xCE,0x2F,0x2C,0xFA,
+0xB6,0x4F,0x12,0xD4,0x30,0xC6,0xDC,0xC5,0x5B,0x1B,0x8D,0xA2,0xAB,0xCE,0xC3,0x03,
+0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x01,0xBD,0x30,0x82,0x01,0xB9,0x30,0x1F,0x06,
+0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x7F,0xF6,0x4C,0x36,0x28,0x14,
+0xAE,0xCD,0x1E,0x37,0xAF,0xDE,0x5A,0xF2,0x5B,0xC3,0xA0,0xAC,0x2B,0xFE,0x30,0x1D,
+0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xA4,0x72,0x61,0x0C,0x67,0xA4,0x90,
+0xCC,0x81,0x5A,0xDB,0xDF,0x7E,0xE8,0x08,0xF3,0xDA,0x3A,0x1E,0x55,0x30,0x0E,0x06,
+0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x05,0xA0,0x30,0x0C,0x06,
+0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x02,0x30,0x00,0x30,0x34,0x06,0x03,0x55,
+0x1D,0x25,0x04,0x2D,0x30,0x2B,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01,
+0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x0A,0x2B,0x06,0x01,0x04,
+0x01,0x82,0x37,0x0A,0x03,0x03,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x04,
+0x01,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,0x04,0x04,
+0x03,0x02,0x06,0xC0,0x30,0x46,0x06,0x03,0x55,0x1D,0x20,0x04,0x3F,0x30,0x3D,0x30,
+0x3B,0x06,0x0C,0x2B,0x06,0x01,0x04,0x01,0xB2,0x31,0x01,0x02,0x01,0x05,0x01,0x30,
+0x2B,0x30,0x29,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1D,0x68,
+0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F,0x73,0x65,0x63,0x75,0x72,0x65,0x2E,0x63,0x6F,
+0x6D,0x6F,0x64,0x6F,0x2E,0x6E,0x65,0x74,0x2F,0x43,0x50,0x53,0x30,0x3A,0x06,0x03,
+0x55,0x1D,0x1F,0x04,0x33,0x30,0x31,0x30,0x2F,0xA0,0x2D,0xA0,0x2B,0x86,0x29,0x68,
+0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F,
+0x63,0x61,0x2E,0x63,0x6F,0x6D,0x2F,0x43,0x6F,0x6D,0x6F,0x64,0x6F,0x45,0x56,0x53,
+0x47,0x43,0x43,0x41,0x2E,0x63,0x72,0x6C,0x30,0x6B,0x06,0x08,0x2B,0x06,0x01,0x05,
+0x05,0x07,0x01,0x01,0x04,0x5F,0x30,0x5D,0x30,0x35,0x06,0x08,0x2B,0x06,0x01,0x05,
+0x05,0x07,0x30,0x02,0x86,0x29,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x74,
+0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F,0x63,0x61,0x2E,0x63,0x6F,0x6D,0x2F,0x43,0x6F,
+0x6D,0x6F,0x64,0x6F,0x45,0x56,0x53,0x47,0x43,0x43,0x41,0x2E,0x63,0x72,0x74,0x30,
+0x24,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x18,0x68,0x74,0x74,
+0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,0x70,0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F,0x63,
+0x61,0x2E,0x63,0x6F,0x6D,0x30,0x1F,0x06,0x03,0x55,0x1D,0x11,0x04,0x18,0x30,0x16,
+0x82,0x0B,0x77,0x77,0x77,0x2E,0x6F,0x76,0x68,0x2E,0x63,0x6F,0x6D,0x82,0x07,0x6F,
+0x76,0x68,0x2E,0x63,0x6F,0x6D,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,
+0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x85,0x1C,0xDD,0x46,0x8F,0x8A,
+0x37,0x7F,0xB7,0x13,0x67,0xE2,0x83,0x0A,0xEC,0x6F,0x29,0x02,0xD2,0x03,0xE0,0x84,
+0x66,0x28,0x37,0x0E,0xFF,0x61,0x14,0x0A,0xF5,0x62,0xBF,0x25,0x2B,0x01,0x3F,0xD2,
+0x27,0xCC,0x6B,0xB3,0x79,0xC2,0x93,0x9D,0xA4,0x56,0x6E,0x0C,0x8B,0x25,0x49,0xAA,
+0x8B,0xC9,0xDD,0x6A,0x68,0xFC,0x32,0xDC,0x83,0x17,0x10,0x87,0x90,0x06,0xC3,0xA7,
+0x16,0x77,0x05,0x7D,0x42,0xD7,0xBE,0xA5,0x5F,0x89,0x90,0xA8,0xF8,0x3A,0xFE,0x2E,
+0x95,0x7F,0x51,0x88,0x7D,0xFC,0xA3,0x8A,0x83,0xFF,0xD1,0x86,0xB2,0x30,0x3F,0x22,
+0x77,0xD4,0xE2,0xD8,0x61,0x78,0x50,0x16,0xE1,0x38,0xAD,0x75,0x7F,0x64,0x3D,0x4B,
+0x65,0x06,0x58,0x07,0xBF,0x1B,0x62,0xB2,0xE0,0xC9,0x55,0x08,0x6D,0x0D,0xF1,0x53,
+0x25,0x25,0x12,0x50,0x07,0x84,0xEA,0x43,0x95,0x7D,0xF1,0x1B,0x80,0xFE,0xE4,0x2D,
+0xA5,0x42,0x77,0x2F,0x9E,0x79,0x24,0x0A,0xB0,0xE5,0xCB,0xE7,0x9B,0xA6,0x09,0x7B,
+0xD0,0x5B,0x72,0x43,0x6C,0x91,0x31,0x48,0x35,0x6C,0xA2,0xB6,0xF4,0x64,0xAD,0x7B,
+0x7A,0x25,0x34,0xBA,0x2E,0xB4,0x52,0x2C,0x65,0x41,0xE5,0xCE,0xB2,0x53,0xEF,0xE7,
+0xFF,0x0C,0x39,0x72,0x61,0x91,0x21,0xBB,0x75,0x9A,0x11,0xD0,0xAB,0xB3,0x94,0x08,
+0x44,0xDA,0x78,0xF7,0x92,0x98,0x48,0xAD,0xE4,0xB6,0xBB,0x9F,0xFD,0x59,0x37,0xB6,
+0x42,0x8E,0xEE,0x99,0x90,0xB2,0xA0,0xB5,0xF3,0x68,0xA7,0x54,0x46,0xB6,0x6C,0x05,
+0x27,0x75,0x60,0x87,0x25,0x2E,0x2A,0x16,0xDA,0xA1,
+};
+
+/* This is the cert the ssl server returns to us. */
+/* subject:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO EV SGC CA */
+/* issuer :/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN - DATACorp SGC */
+static unsigned char comodo_ev_certificate[1232]={
+0x30,0x82,0x04,0xCC,0x30,0x82,0x03,0xB4,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x3B,
+0x9F,0xB1,0xF2,0xC0,0x97,0x44,0x9D,0x61,0xA4,0x8F,0x5F,0xF9,0xA6,0xF5,0xE0,0x30,
+0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81,
+0x93,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0B,
+0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x13,0x02,0x55,0x54,0x31,0x17,0x30,0x15,0x06,
+0x03,0x55,0x04,0x07,0x13,0x0E,0x53,0x61,0x6C,0x74,0x20,0x4C,0x61,0x6B,0x65,0x20,
+0x43,0x69,0x74,0x79,0x31,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x0A,0x13,0x15,0x54,
+0x68,0x65,0x20,0x55,0x53,0x45,0x52,0x54,0x52,0x55,0x53,0x54,0x20,0x4E,0x65,0x74,
+0x77,0x6F,0x72,0x6B,0x31,0x21,0x30,0x1F,0x06,0x03,0x55,0x04,0x0B,0x13,0x18,0x68,
+0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x75,0x73,0x65,0x72,0x74,0x72,
+0x75,0x73,0x74,0x2E,0x63,0x6F,0x6D,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x03,
+0x13,0x12,0x55,0x54,0x4E,0x20,0x2D,0x20,0x44,0x41,0x54,0x41,0x43,0x6F,0x72,0x70,
+0x20,0x53,0x47,0x43,0x30,0x1E,0x17,0x0D,0x30,0x36,0x31,0x32,0x30,0x31,0x30,0x30,
+0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x39,0x30,0x36,0x32,0x34,0x31,0x39,0x30,
+0x36,0x33,0x30,0x5A,0x30,0x73,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,
+0x02,0x47,0x42,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x08,0x13,0x12,0x47,0x72,
+0x65,0x61,0x74,0x65,0x72,0x20,0x4D,0x61,0x6E,0x63,0x68,0x65,0x73,0x74,0x65,0x72,
+0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x07,0x13,0x07,0x53,0x61,0x6C,0x66,0x6F,
+0x72,0x64,0x31,0x1A,0x30,0x18,0x06,0x03,0x55,0x04,0x0A,0x13,0x11,0x43,0x4F,0x4D,
+0x4F,0x44,0x4F,0x20,0x43,0x41,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x19,
+0x30,0x17,0x06,0x03,0x55,0x04,0x03,0x13,0x10,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,
+0x45,0x56,0x20,0x53,0x47,0x43,0x20,0x43,0x41,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,
+0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,
+0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xE8,0xCE,0xAA,0xA9,0x25,0xAF,
+0x2E,0x8E,0xD1,0x79,0x95,0x5E,0xA4,0x88,0x24,0x4F,0xFD,0xB3,0x5C,0xAE,0x2A,0x9E,
+0x4A,0x7B,0x40,0xE0,0xCC,0x50,0xE9,0x81,0x58,0x15,0xD2,0x87,0xF7,0xAD,0x85,0x7A,
+0x69,0x52,0xA0,0x95,0x6E,0x8F,0x67,0x09,0x8E,0xF1,0xF3,0x5C,0x17,0xE3,0x49,0x42,
+0xC8,0x12,0x67,0xA6,0x05,0xF8,0x37,0xA0,0x0F,0x16,0x61,0x0F,0x8F,0x31,0x52,0xC6,
+0xE1,0x87,0xE1,0x4F,0xB9,0xDB,0xC9,0xFE,0x69,0x1B,0xD4,0xC9,0xF7,0x2D,0xAC,0x48,
+0xD7,0x73,0x4A,0x04,0x95,0xE3,0xA1,0x37,0x87,0x52,0x5A,0x88,0xB3,0xD6,0x01,0x2C,
+0xF1,0x03,0x70,0x2C,0x26,0x70,0x2B,0x47,0x3B,0x0A,0xAE,0x31,0x7A,0xD7,0xE5,0x14,
+0x4E,0xAC,0x2F,0x30,0xE1,0x7C,0x6D,0x36,0xDA,0xA0,0xF5,0x83,0x62,0x5D,0x88,0x26,
+0x0D,0x05,0x45,0x5E,0xCE,0xF7,0x8B,0xEB,0x95,0xB4,0xE0,0xEB,0x10,0x7A,0xD4,0xB9,
+0x59,0x75,0x46,0x52,0xDD,0x86,0x74,0x84,0xCB,0x5F,0xD3,0x1C,0x41,0xEA,0xF0,0x9A,
+0xDA,0x91,0x64,0x84,0xDF,0xDE,0x9F,0xF2,0xDD,0xD0,0xFA,0xA6,0x68,0x96,0xB7,0x3E,
+0x97,0x2D,0x7F,0xB1,0xFB,0x8C,0x6C,0xA7,0xFE,0x72,0x82,0xD0,0xE3,0x8A,0xD3,0xBB,
+0xE3,0xCE,0x01,0xB7,0x9D,0x67,0xE9,0xA9,0x13,0x9A,0x3B,0x21,0xED,0xF7,0x73,0x13,
+0xE3,0x33,0x5D,0x7A,0x01,0xA9,0xCA,0x49,0xD0,0x4E,0x63,0x87,0x57,0x81,0x3A,0x17,
+0x54,0x30,0xF6,0x02,0x5E,0x94,0xB6,0x60,0xD2,0x29,0xF9,0x4E,0xE7,0x29,0xA0,0xA0,
+0x9D,0x2A,0x5B,0xEB,0x3F,0x89,0x2E,0x45,0xA2,0xFD,0x02,0x03,0x01,0x00,0x01,0xA3,
+0x82,0x01,0x39,0x30,0x82,0x01,0x35,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,
+0x30,0x16,0x80,0x14,0x53,0x32,0xD1,0xB3,0xCF,0x7F,0xFA,0xE0,0xF1,0xA0,0x5D,0x85,
+0x4E,0x92,0xD2,0x9E,0x45,0x1D,0xB4,0x4F,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,
+0x16,0x04,0x14,0x7F,0xF6,0x4C,0x36,0x28,0x14,0xAE,0xCD,0x1E,0x37,0xAF,0xDE,0x5A,
+0xF2,0x5B,0xC3,0xA0,0xAC,0x2B,0xFE,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,
+0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x12,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,
+0xFF,0x04,0x08,0x30,0x06,0x01,0x01,0xFF,0x02,0x01,0x00,0x30,0x20,0x06,0x03,0x55,
+0x1D,0x25,0x04,0x19,0x30,0x17,0x06,0x0A,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,
+0x03,0x03,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x04,0x01,0x30,0x3E,0x06,
+0x03,0x55,0x1D,0x20,0x04,0x37,0x30,0x35,0x30,0x33,0x06,0x04,0x55,0x1D,0x20,0x00,
+0x30,0x2B,0x30,0x29,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1D,
+0x68,0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F,0x73,0x65,0x63,0x75,0x72,0x65,0x2E,0x63,
+0x6F,0x6D,0x6F,0x64,0x6F,0x2E,0x6E,0x65,0x74,0x2F,0x43,0x50,0x53,0x30,0x6D,0x06,
+0x03,0x55,0x1D,0x1F,0x04,0x66,0x30,0x64,0x30,0x31,0xA0,0x2F,0xA0,0x2D,0x86,0x2B,
+0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x63,0x6F,0x6D,0x6F,0x64,
+0x6F,0x63,0x61,0x2E,0x63,0x6F,0x6D,0x2F,0x55,0x54,0x4E,0x2D,0x44,0x41,0x54,0x41,
+0x43,0x6F,0x72,0x70,0x53,0x47,0x43,0x2E,0x63,0x72,0x6C,0x30,0x2F,0xA0,0x2D,0xA0,
+0x2B,0x86,0x29,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x63,0x6F,
+0x6D,0x6F,0x64,0x6F,0x2E,0x6E,0x65,0x74,0x2F,0x55,0x54,0x4E,0x2D,0x44,0x41,0x54,
+0x41,0x43,0x6F,0x72,0x70,0x53,0x47,0x43,0x2E,0x63,0x72,0x6C,0x30,0x0D,0x06,0x09,
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,
+0x63,0xCD,0x05,0x7E,0x6F,0x81,0x18,0xF9,0x50,0x25,0x8E,0x91,0x75,0x1B,0x1F,0xF7,
+0x3E,0x02,0x54,0x5B,0xAF,0xD2,0xA3,0x15,0xFD,0xD6,0x1D,0x61,0x73,0x7A,0x9C,0x57,
+0xFA,0xCB,0xB7,0xF9,0xE8,0x32,0xA2,0x02,0x5D,0x36,0xFE,0x34,0x1F,0x6C,0x8A,0xB3,
+0x72,0x43,0x26,0x36,0x8F,0x4D,0x14,0x5E,0x34,0x8A,0xBB,0xFC,0x6B,0x69,0xC4,0x46,
+0x76,0x07,0x04,0x75,0xA4,0xF2,0xA5,0xF8,0x91,0x46,0x2D,0xD5,0x28,0x71,0xE3,0xCC,
+0xA6,0x2C,0x99,0x2F,0xD5,0xFD,0xA3,0x45,0xD8,0x1A,0x9A,0x04,0xFB,0x1D,0x90,0xEE,
+0x57,0x5E,0x08,0x73,0xC0,0x7A,0x02,0x36,0x11,0xEA,0x06,0x44,0x1E,0x39,0xA1,0x2A,
+0x3F,0x22,0x5C,0x91,0xF4,0x22,0x55,0xAF,0x9A,0x0B,0x07,0x56,0x2A,0x59,0x0B,0x71,
+0x5D,0x43,0x16,0xF4,0xE6,0x4F,0xD5,0x50,0xB0,0xCF,0xAD,0xA0,0xF8,0xE2,0x0B,0x00,
+0x3C,0x83,0xA9,0x4E,0x50,0x37,0xD9,0x9C,0x65,0x3E,0x8C,0xC5,0x3A,0xA9,0x51,0xF5,
+0xEB,0x7B,0x56,0xCD,0xF9,0xD5,0xBC,0xE4,0x6B,0x29,0xAC,0x3E,0x09,0x8E,0xB8,0x8D,
+0x76,0x24,0x11,0xA1,0x80,0x4A,0xF2,0xD9,0xEC,0x83,0xD0,0x91,0x03,0x2C,0x6B,0x2B,
+0x11,0xD5,0xD0,0x90,0x81,0xBB,0xE6,0x17,0xBD,0xD0,0xCD,0x85,0x73,0x2D,0x8D,0xDE,
+0x69,0x27,0xE7,0x7E,0xAF,0x39,0x5C,0x0F,0xF2,0xC5,0x7C,0x3D,0xFB,0xE4,0xB0,0xF7,
+0x81,0x1F,0x30,0x54,0x68,0x20,0x9C,0x8C,0xC5,0x2A,0x5A,0x39,0x17,0xCD,0x30,0x68,
+0x5D,0x45,0xD8,0xA7,0xB8,0x4B,0xFD,0xDC,0x2D,0x2D,0x04,0x01,0x8D,0x5D,0x78,0x28,
+};
+
+/* This is the cert we get when we get the url in the AIA extension of the ovh leaf. */
+/* subject:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO EV SGC CA */
+/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO Certification Authority */
+static unsigned char comodo_aia_certificate[1178]={
+0x30,0x82,0x04,0x96,0x30,0x82,0x03,0x7E,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x13,
+0x62,0xE8,0xEB,0x54,0x1A,0x10,0x8C,0xB8,0xA8,0x0E,0xE5,0x9F,0xB1,0xD4,0x51,0x30,
+0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81,
+0x81,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x47,0x42,0x31,0x1B,
+0x30,0x19,0x06,0x03,0x55,0x04,0x08,0x13,0x12,0x47,0x72,0x65,0x61,0x74,0x65,0x72,
+0x20,0x4D,0x61,0x6E,0x63,0x68,0x65,0x73,0x74,0x65,0x72,0x31,0x10,0x30,0x0E,0x06,
+0x03,0x55,0x04,0x07,0x13,0x07,0x53,0x61,0x6C,0x66,0x6F,0x72,0x64,0x31,0x1A,0x30,
+0x18,0x06,0x03,0x55,0x04,0x0A,0x13,0x11,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x43,
+0x41,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x27,0x30,0x25,0x06,0x03,0x55,
+0x04,0x03,0x13,0x1E,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x43,0x65,0x72,0x74,0x69,
+0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,
+0x74,0x79,0x30,0x1E,0x17,0x0D,0x30,0x36,0x31,0x32,0x30,0x31,0x30,0x30,0x30,0x30,
+0x30,0x30,0x5A,0x17,0x0D,0x31,0x39,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
+0x39,0x5A,0x30,0x73,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x47,
+0x42,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x08,0x13,0x12,0x47,0x72,0x65,0x61,
+0x74,0x65,0x72,0x20,0x4D,0x61,0x6E,0x63,0x68,0x65,0x73,0x74,0x65,0x72,0x31,0x10,
+0x30,0x0E,0x06,0x03,0x55,0x04,0x07,0x13,0x07,0x53,0x61,0x6C,0x66,0x6F,0x72,0x64,
+0x31,0x1A,0x30,0x18,0x06,0x03,0x55,0x04,0x0A,0x13,0x11,0x43,0x4F,0x4D,0x4F,0x44,
+0x4F,0x20,0x43,0x41,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x19,0x30,0x17,
+0x06,0x03,0x55,0x04,0x03,0x13,0x10,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x45,0x56,
+0x20,0x53,0x47,0x43,0x20,0x43,0x41,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,
+0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,
+0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xE8,0xCE,0xAA,0xA9,0x25,0xAF,0x2E,0x8E,
+0xD1,0x79,0x95,0x5E,0xA4,0x88,0x24,0x4F,0xFD,0xB3,0x5C,0xAE,0x2A,0x9E,0x4A,0x7B,
+0x40,0xE0,0xCC,0x50,0xE9,0x81,0x58,0x15,0xD2,0x87,0xF7,0xAD,0x85,0x7A,0x69,0x52,
+0xA0,0x95,0x6E,0x8F,0x67,0x09,0x8E,0xF1,0xF3,0x5C,0x17,0xE3,0x49,0x42,0xC8,0x12,
+0x67,0xA6,0x05,0xF8,0x37,0xA0,0x0F,0x16,0x61,0x0F,0x8F,0x31,0x52,0xC6,0xE1,0x87,
+0xE1,0x4F,0xB9,0xDB,0xC9,0xFE,0x69,0x1B,0xD4,0xC9,0xF7,0x2D,0xAC,0x48,0xD7,0x73,
+0x4A,0x04,0x95,0xE3,0xA1,0x37,0x87,0x52,0x5A,0x88,0xB3,0xD6,0x01,0x2C,0xF1,0x03,
+0x70,0x2C,0x26,0x70,0x2B,0x47,0x3B,0x0A,0xAE,0x31,0x7A,0xD7,0xE5,0x14,0x4E,0xAC,
+0x2F,0x30,0xE1,0x7C,0x6D,0x36,0xDA,0xA0,0xF5,0x83,0x62,0x5D,0x88,0x26,0x0D,0x05,
+0x45,0x5E,0xCE,0xF7,0x8B,0xEB,0x95,0xB4,0xE0,0xEB,0x10,0x7A,0xD4,0xB9,0x59,0x75,
+0x46,0x52,0xDD,0x86,0x74,0x84,0xCB,0x5F,0xD3,0x1C,0x41,0xEA,0xF0,0x9A,0xDA,0x91,
+0x64,0x84,0xDF,0xDE,0x9F,0xF2,0xDD,0xD0,0xFA,0xA6,0x68,0x96,0xB7,0x3E,0x97,0x2D,
+0x7F,0xB1,0xFB,0x8C,0x6C,0xA7,0xFE,0x72,0x82,0xD0,0xE3,0x8A,0xD3,0xBB,0xE3,0xCE,
+0x01,0xB7,0x9D,0x67,0xE9,0xA9,0x13,0x9A,0x3B,0x21,0xED,0xF7,0x73,0x13,0xE3,0x33,
+0x5D,0x7A,0x01,0xA9,0xCA,0x49,0xD0,0x4E,0x63,0x87,0x57,0x81,0x3A,0x17,0x54,0x30,
+0xF6,0x02,0x5E,0x94,0xB6,0x60,0xD2,0x29,0xF9,0x4E,0xE7,0x29,0xA0,0xA0,0x9D,0x2A,
+0x5B,0xEB,0x3F,0x89,0x2E,0x45,0xA2,0xFD,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x01,
+0x15,0x30,0x82,0x01,0x11,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,
+0x80,0x14,0x0B,0x58,0xE5,0x8B,0xC6,0x4C,0x15,0x37,0xA4,0x40,0xA9,0x30,0xA9,0x21,
+0xBE,0x47,0x36,0x5A,0x56,0xFF,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,
+0x14,0x7F,0xF6,0x4C,0x36,0x28,0x14,0xAE,0xCD,0x1E,0x37,0xAF,0xDE,0x5A,0xF2,0x5B,
+0xC3,0xA0,0xAC,0x2B,0xFE,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,
+0x04,0x03,0x02,0x01,0x06,0x30,0x12,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,
+0x08,0x30,0x06,0x01,0x01,0xFF,0x02,0x01,0x00,0x30,0x20,0x06,0x03,0x55,0x1D,0x25,
+0x04,0x19,0x30,0x17,0x06,0x0A,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x03,
+0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x04,0x01,0x30,0x3E,0x06,0x03,0x55,
+0x1D,0x20,0x04,0x37,0x30,0x35,0x30,0x33,0x06,0x04,0x55,0x1D,0x20,0x00,0x30,0x2B,
+0x30,0x29,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1D,0x68,0x74,
+0x74,0x70,0x73,0x3A,0x2F,0x2F,0x73,0x65,0x63,0x75,0x72,0x65,0x2E,0x63,0x6F,0x6D,
+0x6F,0x64,0x6F,0x2E,0x6E,0x65,0x74,0x2F,0x43,0x50,0x53,0x30,0x49,0x06,0x03,0x55,
+0x1D,0x1F,0x04,0x42,0x30,0x40,0x30,0x3E,0xA0,0x3C,0xA0,0x3A,0x86,0x38,0x68,0x74,
+0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F,0x63,
+0x61,0x2E,0x63,0x6F,0x6D,0x2F,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x43,0x65,0x72,0x74,
+0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,
+0x74,0x79,0x2E,0x63,0x72,0x6C,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,
+0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x8C,0xD9,0xD9,0x52,0x33,0xEE,
+0x07,0xF6,0xE1,0xEC,0xAB,0x15,0xE0,0x9F,0x15,0xD8,0x99,0x25,0xDB,0x19,0x95,0x25,
+0x9B,0x43,0xBE,0x59,0x2B,0x81,0x29,0xC8,0xF8,0xF1,0x5F,0x8E,0x49,0x02,0x36,0x46,
+0x1C,0xEB,0xF2,0xA1,0xFE,0xD1,0x0A,0x45,0xBA,0xD0,0xDB,0x50,0x44,0x0C,0x50,0xA3,
+0x3C,0x6E,0x5F,0x84,0xD4,0x4F,0x1A,0xA8,0x69,0x8F,0x24,0x66,0x01,0xD2,0x0B,0xB4,
+0x08,0x19,0xBA,0xBD,0x34,0x09,0x90,0x09,0x62,0x71,0xAD,0x39,0x8E,0xB8,0x78,0x79,
+0xB1,0x24,0x78,0xB4,0xCD,0xA7,0x49,0xF9,0x6D,0x78,0x7F,0x70,0x87,0x82,0x91,0x35,
+0xAC,0xB1,0x00,0x86,0x21,0x51,0xD2,0xCD,0x46,0xCB,0x3A,0x82,0xC0,0x48,0x1A,0xD3,
+0x15,0x26,0xDB,0xF1,0x0F,0x82,0x71,0x66,0xE2,0x8B,0x77,0x54,0xA3,0x76,0x2F,0xD7,
+0x6D,0xF8,0x0D,0x0E,0xCE,0x3A,0x4E,0x65,0x57,0x3F,0x1C,0x77,0x50,0xCA,0xBB,0x7A,
+0x53,0xF7,0xFB,0x5F,0x3D,0x75,0x56,0xAA,0xD3,0xE3,0x1F,0x12,0xB5,0x1D,0xBF,0xC3,
+0xDC,0xE1,0xF9,0x39,0x67,0x81,0xF1,0x33,0x9C,0xC8,0x1E,0xC5,0xE6,0xEE,0x2B,0xB9,
+0xD9,0x58,0xC8,0xC7,0x2E,0xDF,0x48,0xD1,0xC9,0xE4,0xB3,0x1A,0x08,0x5F,0x9A,0x18,
+0x6D,0x61,0xD3,0xB0,0xAD,0x27,0x5E,0x08,0x35,0x34,0x25,0xA1,0x9F,0x42,0xC8,0x75,
+0x98,0xD3,0x02,0x64,0x55,0x94,0xE3,0xAF,0xD1,0xE7,0x4A,0xB9,0xE4,0xD9,0x06,0x6E,
+0x71,0x28,0xF8,0xDD,0xAC,0xE5,0x45,0xDF,0xD8,0xE7,0x28,0x05,0xA1,0x68,0xCE,0xC1,
+0x25,0x5B,0x85,0xFA,0x46,0x9D,0xFE,0xDB,0x64,0xF0,
+};
+
+#define CFReleaseSafe(CF) { CFTypeRef _cf = (CF); if (_cf) CFRelease(_cf); }
+#define CFReleaseNull(CF) { CFTypeRef _cf = (CF); \
+       if (_cf) { (CF) = NULL; CFRelease(_cf); } }
+
+static void tests(void)
+{
+    SecTrustRef trust;
+    SecCertificateRef cert0, cert1, responderCert;
+    isnt(cert0 = SecCertificateCreateWithBytes(NULL, _c0, sizeof(_c0)),
+           NULL, "create cert0");
+    isnt(cert1 = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)),
+           NULL, "create cert1");
+    CFMutableArrayRef certs = CFArrayCreateMutable(kCFAllocatorDefault, 0,
+        &kCFTypeArrayCallBacks);
+    CFArrayAppendValue(certs, cert0);
+    CFArrayAppendValue(certs, cert1);
+
+    SecPolicyRef sslPolicy = SecPolicyCreateSSL(false, CFSTR("www.paypal.com"));
+    SecPolicyRef ocspPolicy = SecPolicyCreateRevocation(kSecRevocationOCSPMethod);
+    const void *v_policies[] = { sslPolicy, ocspPolicy };
+    CFArrayRef policies = CFArrayCreate(NULL, v_policies,
+       array_size(v_policies), &kCFTypeArrayCallBacks);
+    CFRelease(sslPolicy);
+    CFRelease(ocspPolicy);
+    ok_status(SecTrustCreateWithCertificates(certs, policies, &trust),
+        "create trust");
+    /* Jan 1st 2009. */
+    CFDateRef date = CFDateCreate(NULL, 252288000.0);
+    ok_status(SecTrustSetVerifyDate(trust, date), "set date");
+
+    is(SecTrustGetVerifyTime(trust), 252288000.0, "get date");
+
+    SecTrustResultType trustResult;
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultUnspecified,
+               "trust is kSecTrustResultUnspecified");
+
+    
+    CFDictionaryRef info = SecTrustCopyInfo(trust);
+    CFBooleanRef ev = (CFBooleanRef)CFDictionaryGetValue(info,
+        kSecTrustInfoExtendedValidationKey);
+    ok(ev && CFEqual(kCFBooleanTrue, ev), "extended validation succeeded");
+
+    CFStringRef companyName = (CFStringRef)CFDictionaryGetValue(info,
+        kSecTrustInfoCompanyNameKey);
+    CFReleaseSafe(info);
+    ok(companyName && CFEqual(CFSTR("PayPal, Inc."), companyName),
+        "kSecTrustInfoCompanyNameKey is correct");
+
+    SecPolicyRef ocspSignerPolicy;
+    ok(ocspSignerPolicy = SecPolicyCreateOCSPSigner(),
+        "create ocspSigner policy");
+
+    CFReleaseNull(trust);
+    ok_status(SecTrustCreateWithCertificates(certs, ocspSignerPolicy, &trust),
+        "create trust for c0 -> c1");
+    ok_status(SecTrustSetVerifyDate(trust, date), "set date");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultRecoverableTrustFailure,
+               "trust is kSecTrustResultRecoverableTrustFailure");
+
+    isnt(responderCert = SecCertificateCreateWithBytes(NULL, _responderCert,
+        sizeof(_responderCert)), NULL, "create responderCert");
+    CFArraySetValueAtIndex(certs, 0, responderCert);
+    CFReleaseNull(trust);
+    ok_status(SecTrustCreateWithCertificates(certs, ocspSignerPolicy, &trust),
+        "create trust for ocspResponder -> c1");
+    CFReleaseNull(date);
+    /* Apr 3rd 2009. */
+    date = CFDateCreate(NULL, 260509092.0);
+    ok_status(SecTrustSetVerifyDate(trust, date), "set date");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultUnspecified,
+               "trust is kSecTrustResultUnspecified");
+
+    CFReleaseSafe(ocspSignerPolicy);
+    //CFReleaseSafe(info);
+    CFReleaseSafe(trust);
+    CFReleaseSafe(policies);
+    CFReleaseSafe(certs);
+    CFReleaseSafe(cert0);
+    CFReleaseSafe(cert1);
+    CFReleaseSafe(responderCert);
+    CFReleaseSafe(date);
+}
+
+#if 0
+static void hexdump(const uint8_t *bytes, size_t len) {
+       size_t ix;
+       printf("#anchor-sha1: ");
+       for (ix = 0; ix < len; ++ix) {
+               printf("%02X", bytes[ix]);
+       }
+       printf("\n");
+}
+
+static void datadump(const uint8_t *bytes, size_t len) {
+       size_t ix;
+       printf("#anchor-sha1: ");
+       for (ix = 0; ix < len; ++ix) {
+               printf("%c", bytes[ix]);
+       }
+       printf("\n");
+}
+
+static void display_anchor_digest(SecTrustRef trust) {
+    CFIndex count = SecTrustGetCertificateCount(trust);
+    SecCertificateRef anchor = SecTrustGetCertificateAtIndex(trust, count - 1);
+    CFDataRef digest = SecCertificateGetSHA1Digest(anchor);
+    CFDataRef xml = CFPropertyListCreateXMLData(NULL, digest);
+    datadump(CFDataGetBytePtr(xml), CFDataGetLength(xml));
+}
+#endif
+
+static void test_aia(void) {
+    SecCertificateRef ovh, comodo_ev, comodo_aia;
+    CFMutableArrayRef certs;
+    SecPolicyRef sslPolicy;
+    CFDateRef jan1st2009;
+    CFDictionaryRef info;
+    SecTrustRef trust;
+    SecTrustResultType trustResult;
+    CFStringRef companyName;
+    CFBooleanRef ev;
+
+    /* Initialize common variables */
+    isnt(ovh = SecCertificateCreateWithBytes(NULL, ovh_certificate,
+        sizeof(ovh_certificate)), NULL, "create ovh cert");
+    isnt(comodo_ev = SecCertificateCreateWithBytes(NULL, comodo_ev_certificate,
+        sizeof(comodo_ev_certificate)), NULL, "create comodo_ev cert");
+    isnt(comodo_aia = SecCertificateCreateWithBytes(NULL,
+        comodo_aia_certificate, sizeof(comodo_aia_certificate)), NULL,
+        "create comodo_aia cert");
+    certs = CFArrayCreateMutable(kCFAllocatorDefault, 0,
+        &kCFTypeArrayCallBacks);
+    sslPolicy = SecPolicyCreateSSL(false, CFSTR("www.ovh.com"));
+    /* Jan 1st 2009. */
+    jan1st2009 = CFDateCreate(NULL, 252288000.0);
+
+    /* First run with the intermediate returned by the ssl server. */
+    CFArrayAppendValue(certs, ovh);
+    CFArrayAppendValue(certs, comodo_ev);
+    ok_status(SecTrustCreateWithCertificates(certs, sslPolicy, &trust),
+        "create trust");
+    ok_status(SecTrustSetVerifyDate(trust, jan1st2009), "set date");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultUnspecified,
+               "trust is kSecTrustResultUnspecified");
+    info = SecTrustCopyInfo(trust);
+    ev = (CFBooleanRef)CFDictionaryGetValue(info,
+        kSecTrustInfoExtendedValidationKey);
+    ok(ev, "extended validation succeeded due to caissuers fetch");
+    //display_anchor_digest(trust);
+    CFReleaseSafe(info);
+    CFReleaseSafe(trust);
+
+    /* Now run with the intermediate returned by following the url in the
+       Certificate Access Information Authority (AIA) extension of the ovh
+       leaf certificate. */
+    CFArrayAppendValue(certs, comodo_aia);
+    ok_status(SecTrustCreateWithCertificates(certs, sslPolicy, &trust),
+        "re-create trust with aia intermediate");
+    ok_status(SecTrustSetVerifyDate(trust, jan1st2009), "set date");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultUnspecified,
+               "trust is kSecTrustResultUnspecified");
+    info = SecTrustCopyInfo(trust);
+    ev = (CFBooleanRef)CFDictionaryGetValue(info,
+        kSecTrustInfoExtendedValidationKey);
+    ok(ev && CFEqual(kCFBooleanTrue, ev), "extended validation succeeded");
+    companyName = (CFStringRef)CFDictionaryGetValue(info,
+        kSecTrustInfoCompanyNameKey);
+    ok(companyName && CFEqual(CFSTR("OVH"), companyName),
+        "kSecTrustInfoCompanyNameKey is correct");
+    //display_anchor_digest(trust);
+    CFReleaseSafe(info);
+    CFReleaseSafe(trust);
+
+    /* Now run with the intermediate returned by following the url in the
+       Certificate Access Information Authority (AIA) extension of the ovh
+       leaf certificate. */
+    CFArrayRemoveValueAtIndex(certs, 1);
+    ok_status(SecTrustCreateWithCertificates(certs, sslPolicy, &trust),
+        "re-create trust with aia intermediate");
+    ok_status(SecTrustSetVerifyDate(trust, jan1st2009), "set date");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultUnspecified,
+               "trust is kSecTrustResultUnspecified");
+    info = SecTrustCopyInfo(trust);
+    ev = (CFBooleanRef)CFDictionaryGetValue(info,
+        kSecTrustInfoExtendedValidationKey);
+    ok(ev && CFEqual(kCFBooleanTrue, ev), "extended validation succeeded");
+    companyName = (CFStringRef)CFDictionaryGetValue(info,
+        kSecTrustInfoCompanyNameKey);
+    ok(companyName && CFEqual(CFSTR("OVH"), companyName),
+        "kSecTrustInfoCompanyNameKey is correct");
+    //display_anchor_digest(trust);
+    CFReleaseSafe(info);
+    CFReleaseSafe(trust);
+
+    /* Common variable cleanup. */
+    CFReleaseSafe(sslPolicy);
+    CFReleaseSafe(certs);
+    CFReleaseSafe(comodo_aia);
+    CFReleaseSafe(comodo_ev);
+    CFReleaseSafe(ovh);
+    CFReleaseSafe(jan1st2009);
+}
+
+int si_23_sectrust_ocsp(int argc, char *const *argv)
+{
+       plan_tests(39);
+
+    tests();
+    test_aia();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-24-sectrust-appleid.c b/sec/Security/Regressions/secitem/si-24-sectrust-appleid.c
new file mode 100644 (file)
index 0000000..0463280
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2011 Apple Inc. All Rights Reserved.
+ */
+
+#include <Security/SecPolicyPriv.h>
+#include <Security/SecInternal.h>
+
+#include <test/testpolicy.h>
+
+#include "Security_regressions.h"
+
+static void tests(void)
+{
+    SecPolicyRef policy = SecPolicyCreateAppleIDAuthorityPolicy();
+
+    /* Run the tests. */
+    runCertificateTestForDirectory(policy, CFSTR("AppleID-certs"), NULL);
+
+    CFReleaseSafe(policy);
+}
+
+int si_24_sectrust_appleid(int argc, char *const *argv)
+{
+       plan_tests(2);
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-24-sectrust-digicert-malaysia.c b/sec/Security/Regressions/secitem/si-24-sectrust-digicert-malaysia.c
new file mode 100644 (file)
index 0000000..59dcd34
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2011 Apple Inc. All Rights Reserved.
+ */
+
+#include <Security/SecPolicyPriv.h>
+#include <Security/SecInternal.h>
+
+#include <test/testpolicy.h>
+
+#include "Security_regressions.h"
+
+static void tests(void)
+{
+    SecPolicyRef sslPolicy = SecPolicyCreateSSL(false, 0);
+
+    /* Run the tests. */
+    runCertificateTestForDirectory(sslPolicy, CFSTR("DigicertMalaysia"), NULL);
+
+    CFReleaseSafe(sslPolicy);
+}
+
+int si_24_sectrust_digicert_malaysia(int argc, char *const *argv)
+{
+       plan_tests(2);
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-24-sectrust-diginotar.c b/sec/Security/Regressions/secitem/si-24-sectrust-diginotar.c
new file mode 100644 (file)
index 0000000..7b1ae2c
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2011 Apple Inc. All Rights Reserved.
+ */
+
+#include <Security/SecPolicyPriv.h>
+#include <Security/SecInternal.h>
+
+#include <test/testpolicy.h>
+
+#include "Security_regressions.h"
+
+static void tests(void)
+{
+    SecPolicyRef sslPolicy = SecPolicyCreateSSL(false, 0);
+
+    /* Run the tests. */
+    runCertificateTestForDirectory(sslPolicy, CFSTR("DigiNotar"), NULL);
+    runCertificateTestForDirectory(sslPolicy, CFSTR("DigiNotar-Entrust"), NULL);
+    runCertificateTestForDirectory(sslPolicy, CFSTR("DigiNotar-ok"), NULL);
+
+    CFReleaseSafe(sslPolicy);
+}
+
+int si_24_sectrust_diginotar(int argc, char *const *argv)
+{
+       plan_tests(27);
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-24-sectrust-itms.c b/sec/Security/Regressions/secitem/si-24-sectrust-itms.c
new file mode 100644 (file)
index 0000000..4533ca7
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2007-2010 Apple Inc. All Rights Reserved.
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecPolicyPriv.h>
+#include <Security/SecTrust.h>
+#include <Security/SecKey.h>
+#include <Security/SecInternal.h>
+#include <CommonCrypto/CommonDigest.h>
+#include <CommonCrypto/CommonDigestSPI.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "Security_regressions.h"
+
+static const UInt8 sITunesStoreRootCertificate[] =
+{
+       0x30, 0x82, 0x04, 0x65, 0x30, 0x82, 0x03, 0x4d, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00,
+       0xcb, 0x06, 0xa3, 0x3b, 0x30, 0xc3, 0x24, 0x03, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+       0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x7e, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
+       0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x15,
+       0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0c, 0x69, 0x54, 0x75, 0x6e, 0x65, 0x73, 0x20,
+       0x53, 0x74, 0x6f, 0x72, 0x65, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11,
+       0x69, 0x54, 0x75, 0x6e, 0x65, 0x73, 0x20, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x20, 0x52, 0x6f, 0x6f,
+       0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
+       0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72,
+       0x6e, 0x69, 0x61, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, 0x75,
+       0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x37, 0x31, 0x30, 0x30,
+       0x39, 0x31, 0x37, 0x35, 0x31, 0x33, 0x30, 0x5a, 0x17, 0x0d, 0x33, 0x32, 0x31, 0x30, 0x30, 0x32,
+       0x31, 0x37, 0x35, 0x31, 0x33, 0x30, 0x5a, 0x30, 0x7e, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
+       0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x15,
+       0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0c, 0x69, 0x54, 0x75, 0x6e, 0x65, 0x73, 0x20,
+       0x53, 0x74, 0x6f, 0x72, 0x65, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11,
+       0x69, 0x54, 0x75, 0x6e, 0x65, 0x73, 0x20, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x20, 0x52, 0x6f, 0x6f,
+       0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
+       0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72,
+       0x6e, 0x69, 0x61, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, 0x75,
+       0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+       0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30,
+       0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa9, 0x78, 0xc0, 0xaf, 0x1a, 0x96, 0x59, 0xad,
+       0xf8, 0x3c, 0x16, 0xe1, 0xfc, 0xc4, 0x7a, 0xaf, 0xf0, 0x80, 0xed, 0x7f, 0x3a, 0xff, 0xf2, 0x2a,
+       0xb6, 0xf3, 0x1a, 0xdd, 0xbd, 0x14, 0xb1, 0x5d, 0x9d, 0x66, 0xaf, 0xc7, 0xaf, 0x2b, 0x26, 0x78,
+       0x9c, 0xb8, 0x0b, 0x41, 0x9c, 0xdc, 0x17, 0xf1, 0x40, 0x18, 0x09, 0xa1, 0x0a, 0xbc, 0x01, 0x9a,
+       0x0c, 0xbe, 0x89, 0xdb, 0x9d, 0x34, 0xc7, 0x52, 0x8a, 0xf2, 0xbf, 0x35, 0x2b, 0x24, 0x04, 0xb0,
+       0x0c, 0x9d, 0x41, 0x7d, 0x63, 0xe3, 0xad, 0xcf, 0x8b, 0x34, 0xbf, 0x5c, 0x42, 0x82, 0x9b, 0x78,
+       0x7f, 0x00, 0x10, 0x88, 0xd9, 0xfd, 0xf8, 0xbf, 0x63, 0x2c, 0x91, 0x87, 0x03, 0xda, 0xbc, 0xc6,
+       0x71, 0x2b, 0x9a, 0x21, 0x30, 0x95, 0xd6, 0x88, 0xe8, 0xbd, 0x0a, 0x74, 0xa4, 0xa6, 0x39, 0xd0,
+       0x61, 0xd3, 0xb6, 0xe0, 0x2b, 0x1e, 0xe4, 0x78, 0x5c, 0x70, 0x32, 0x66, 0x97, 0x34, 0xa9, 0x79,
+       0xfc, 0x96, 0xaf, 0x4b, 0x8a, 0xd5, 0x12, 0x07, 0x8c, 0x1c, 0xf6, 0x3e, 0x5f, 0xdc, 0x8f, 0x92,
+       0x10, 0xe8, 0x7e, 0xa0, 0x14, 0x1e, 0x61, 0x28, 0xfa, 0xcc, 0xcf, 0x3c, 0xdb, 0x2b, 0xe3, 0xe9,
+       0x44, 0x4a, 0x9d, 0x5f, 0x92, 0x3d, 0xa3, 0xfd, 0x1a, 0x63, 0xb4, 0xbb, 0xab, 0x67, 0x45, 0xc6,
+       0x4d, 0x84, 0x4a, 0xaa, 0x33, 0xe4, 0xde, 0xd3, 0x04, 0x92, 0xbf, 0xf7, 0x00, 0x48, 0x76, 0xc6,
+       0x4e, 0x17, 0xea, 0x70, 0xdb, 0x09, 0xbc, 0x22, 0x07, 0x7b, 0x97, 0x49, 0xe5, 0x29, 0xa7, 0x1a,
+       0x04, 0xd2, 0x0d, 0x0e, 0x73, 0xf1, 0x49, 0x43, 0x34, 0x35, 0x61, 0xe5, 0x67, 0xdf, 0x3c, 0x58,
+       0x42, 0x51, 0xfb, 0xc3, 0xa4, 0x15, 0x6d, 0x39, 0x6b, 0x2a, 0x22, 0xde, 0xdd, 0xe2, 0x36, 0x5b,
+       0xd7, 0x37, 0x53, 0x96, 0x9d, 0x3a, 0x9f, 0x4b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xe5,
+       0x30, 0x81, 0xe2, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xb0, 0xda,
+       0xe1, 0x7f, 0xa8, 0x8b, 0x4a, 0x6a, 0x81, 0x5d, 0x0c, 0xa1, 0x84, 0x56, 0x46, 0x1e, 0x6a, 0xef,
+       0xe5, 0xcf, 0x30, 0x81, 0xb2, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0xaa, 0x30, 0x81, 0xa7,
+       0x80, 0x14, 0xb0, 0xda, 0xe1, 0x7f, 0xa8, 0x8b, 0x4a, 0x6a, 0x81, 0x5d, 0x0c, 0xa1, 0x84, 0x56,
+       0x46, 0x1e, 0x6a, 0xef, 0xe5, 0xcf, 0xa1, 0x81, 0x83, 0xa4, 0x81, 0x80, 0x30, 0x7e, 0x31, 0x13,
+       0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49,
+       0x6e, 0x63, 0x2e, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0c, 0x69, 0x54,
+       0x75, 0x6e, 0x65, 0x73, 0x20, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03,
+       0x55, 0x04, 0x03, 0x13, 0x11, 0x69, 0x54, 0x75, 0x6e, 0x65, 0x73, 0x20, 0x53, 0x74, 0x6f, 0x72,
+       0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+       0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x43, 0x61,
+       0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
+       0x07, 0x13, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x82, 0x09, 0x00, 0xcb,
+       0x06, 0xa3, 0x3b, 0x30, 0xc3, 0x24, 0x03, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05,
+       0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+       0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x7b, 0xcc, 0xfb, 0x34, 0x4e, 0xec, 0x27,
+       0x05, 0xf9, 0x10, 0xc9, 0xdf, 0x8e, 0x22, 0x21, 0x94, 0x70, 0xe9, 0x74, 0x64, 0x11, 0xce, 0x07,
+       0x91, 0xc2, 0x58, 0x0d, 0xff, 0x51, 0x6d, 0x97, 0x64, 0x32, 0x1a, 0x1c, 0xdf, 0x4a, 0x93, 0xdb,
+       0x94, 0x62, 0x14, 0xcb, 0x00, 0x13, 0x37, 0x98, 0x0e, 0x3d, 0x96, 0x19, 0x5f, 0x44, 0xc9, 0x11,
+       0xd2, 0xc9, 0x8c, 0xa3, 0x19, 0x2f, 0x88, 0x4f, 0x5f, 0x3c, 0x46, 0x56, 0xe2, 0xbd, 0x78, 0x4f,
+       0xfe, 0x8e, 0x39, 0xb5, 0xed, 0x37, 0x3e, 0xfb, 0xf6, 0xae, 0x56, 0x2c, 0x49, 0x37, 0x4a, 0x94,
+       0x05, 0x4b, 0x8f, 0x67, 0xdb, 0xe6, 0x24, 0xa6, 0x75, 0xae, 0xc8, 0xa2, 0x26, 0x87, 0x70, 0xb8,
+       0x1d, 0xc2, 0xfc, 0x8d, 0xff, 0x41, 0x23, 0x8a, 0x01, 0x8a, 0xc3, 0x78, 0x5a, 0x61, 0x4a, 0xed,
+       0x48, 0x96, 0xb5, 0x82, 0xa7, 0xaa, 0x2e, 0xb5, 0xed, 0xdd, 0xf4, 0xe6, 0xb5, 0xa1, 0x27, 0x3b,
+       0xda, 0xf9, 0x18, 0x26, 0x7e, 0x8e, 0xec, 0xef, 0xe1, 0x00, 0x7d, 0x3d, 0xf7, 0x3d, 0x01, 0x68,
+       0x14, 0x92, 0xfc, 0x9c, 0xbb, 0x0a, 0xa1, 0xc3, 0x60, 0x31, 0x16, 0x08, 0x9b, 0xef, 0x4d, 0xaf,
+       0x46, 0xc7, 0xcc, 0x4e, 0x05, 0x34, 0xa8, 0x44, 0xb2, 0x85, 0x03, 0x67, 0x6c, 0x31, 0xae, 0xa3,
+       0x18, 0xb5, 0x5f, 0x75, 0xae, 0xe0, 0x5a, 0xbf, 0x64, 0x32, 0x2b, 0x28, 0x99, 0x24, 0xcd, 0x01,
+       0x34, 0xc2, 0xfc, 0xf1, 0x88, 0xba, 0x8c, 0x9b, 0x90, 0x85, 0x56, 0x6d, 0xaf, 0xd5, 0x2e, 0x88,
+       0x12, 0x61, 0x7c, 0x76, 0x33, 0x6b, 0xc4, 0xf7, 0x31, 0x77, 0xe4, 0x02, 0xb7, 0x9e, 0x9c, 0x8c,
+       0xbe, 0x04, 0x2e, 0x51, 0xa3, 0x04, 0x4c, 0xcd, 0xe2, 0x71, 0x5e, 0x36, 0xfb, 0xf1, 0x68, 0xf0,
+       0xad, 0x37, 0x80, 0x98, 0x26, 0xc0, 0xef, 0x9b, 0x3c
+};
+
+static const unsigned char url_bag[] =
+"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>"
+"<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"
+"<plist version=\"1.0\">"
+"<dict>"
+"  <key>signature</key><data>PXlOzELnbcmmd6zbfl/CfXhx4lUKpH7exmCIMQXbwLzGCEjy2g1ekpMopSZZ+OeizHJDPrgfMf3mzhPsagguGNVan8Y335wF0iT5zh4dR/POso9mj1HOvoU5JmqjVXpNVWoflfkIyHZUiQafXitKda7DWXOrNpP92LplPtBzLIg=</data>"
+"  <key>certs</key>"
+"  <array>"
+"    <data>MIIDRjCCAi6gAwIBAgIBAjANBgkqhkiG9w0BAQUFADB+MRMwEQYDVQQKEwpBcHBsZSBJbmMuMRUwEwYDVQQLEwxpVHVuZXMgU3RvcmUxGjAYBgNVBAMTEWlUdW5lcyBTdG9yZSBSb290MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTESMBAGA1UEBxMJQ3VwZXJ0aW5vMB4XDTExMDYwNjIyMTkxOFoXDTEzMDYwNTIyMTkxOFowgYExEzARBgNVBAoTCkFwcGxlIEluYy4xFTATBgNVBAsTDGlUdW5lcyBTdG9yZTEdMBsGA1UEAxMUaVR1bmVzIFN0b3JlIFVSTCBCYWcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQHEwlDdXBlcnRpbm8wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALucax5drB+v1stVZDaqk/kyW1zcZ9Va8lKAXzsDXpkt4gvzhSJX1bQ3Z6qNMhbVT1nvkDHONGsnCyqOkRfI6Py19gRAoQO3XtfAqrZ5Sh7Spxsznm8GCUBBNRtSUzYa+StvwOWiXdPX3D9X5dZTetatpsLL5t5FeedaAW7Baan7AgMBAAGjTzBNMB0GA1UdDgQWBBTI704/Bfpw+vAHyPMVdbk/gT3xpjAfBgNVHSMEGDAWgBSw2uF/qItKaoFdDKGEVkYeau/lzzALBgNVHQ8EBAMCB4AwDQYJKoZIhvcNAQEFBQADggEBAIF7O5xNidy+EE3/skB0Erwy0358vboeowqkSPYzYaNWhK2UCyUiERN61hkaZFFIDqjchND3h7y67kJDCyGviRzRlFiMAEb56rKFzAwlT5w1btOoQjbKgl5MnqYIC9GtUWKC5gH4Qx6lgmIR90qQ/7gEykivZ/IkIvYpXHCYvOStEPqN//u1oiAAVmJpmMN1MHCrhJeZebtMu8zgS9i1rv/e+YaxQJcdJ5COg0GD8i5RI3VCCWqRGl3aGvLx5TzzetnQlRvglnfzsSuXR7gB6oENnOjPGnarccN1qdwPCd8lw+hxfzG8/2LWLUooH2tWXC1Qi9dU9yxCgjgTwzmol3I=</data>"
+"  </array>"
+"  <key>bag</key><data>PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBwbGlzdCBQVUJMSUMgIi0vL0FwcGxlIENvbXB1dGVyLy9EVEQgUExJU1QgMS4wLy9FTiIgImh0dHA6Ly93d3cuYXBwbGUuY29tL0RURHMvUHJvcGVydHlMaXN0LTEuMC5kdGQiPgo8cGxpc3QgdmVyc2lvbj0iMS4wIj4KPGRpY3Q+CiAgPGtleT50aW1lc3RhbXA8L2tleT48ZGF0ZT4yMDExLTA3LTIyVDE0OjIyOjE4WjwvZGF0ZT4KICA8a2V5PnN0b3JlRnJvbnQ8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2Evc3RvcmVGcm9udDwvc3RyaW5nPgogIDxrZXk+bmV3VXNlclN0b3JlRnJvbnQ8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2EvZmlyc3RMYXVuY2g8L3N0cmluZz4KICA8a2V5Pm5ld0lQb2RVc2VyU3RvcmVGcm9udDwva2V5PjxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS9uZXdJUG9kVXNlcj9uZXdJUG9kVXNlcj10cnVlPC9zdHJpbmc+CiAgPGtleT5uZXdQaG9uZVVzZXI8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2EvcGhvbmVMYW5kaW5nUGFnZTwvc3RyaW5nPgogIDxrZXk+c2VhcmNoPC9rZXk+PHN0cmluZz5odHRwOi8vYXguc2VhcmNoLml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlNlYXJjaC53b2Evd2Evc2VhcmNoPC9zdHJpbmc+CiAgPGtleT5hZHZhbmNlZFNlYXJjaDwva2V5PjxzdHJpbmc+aHR0cDovL2F4LnNlYXJjaC5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTZWFyY2gud29hL3dhL2FkdmFuY2VkU2VhcmNoPC9zdHJpbmc+CiAgPGtleT5zZWFyY2hIaW50czwva2V5PjxzdHJpbmc+aHR0cDovL2F4LnNlYXJjaC5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTZWFyY2hIaW50cy53b2Evd2EvaGludHM8L3N0cmluZz4KICA8a2V5PnBhcmVudGFsQWR2aXNvcnk8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2EvcGFyZW50YWxBZHZpc29yeTwvc3RyaW5nPgogIDxrZXk+YnJvd3NlPC9rZXk+PHN0cmluZz5odHRwOi8vaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL2Jyb3dzZTwvc3RyaW5nPgogIDxrZXk+dmlld0FsYnVtPC9rZXk+PHN0cmluZz5odHRwOi8vaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL3ZpZXdBbGJ1bTwvc3RyaW5nPgogIDxrZXk+dmlld0Jvb2s8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2Evdmlld0Jvb2s8L3N0cmluZz4KICA8a2V5PnZpZXdBcnRpc3Q8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2Evdmlld0FydGlzdDwvc3RyaW5nPgogIDxrZXk+dmlld0NvbXBvc2VyPC9rZXk+PHN0cmluZz5odHRwOi8vaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL3ZpZXdDb21wb3Nlcjwvc3RyaW5nPgogIDxrZXk+dmlld0dlbnJlPC9rZXk+PHN0cmluZz5odHRwOi8vaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL3ZpZXdHZW5yZTwvc3RyaW5nPgogIDxrZXk+dmlld1BvZGNhc3Q8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2Evdmlld1BvZGNhc3Q8L3N0cmluZz4KICA8a2V5PnZpZXdQdWJsaXNoZWRQbGF5bGlzdDwva2V5PjxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS92aWV3UHVibGlzaGVkUGxheWxpc3Q8L3N0cmluZz4KICA8a2V5PnZpZXdWaWRlbzwva2V5PjxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS92aWV3VmlkZW88L3N0cmluZz4KICA8a2V5PmFwcHM8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2Evdmlld0FwcHNNYWluPC9zdHJpbmc+CiAgPGtleT5hdWRpb2Jvb2tzPC9rZXk+PHN0cmluZz5odHRwOi8vaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL3ZpZXdBdWRpb2Jvb2tzTWFpbjwvc3RyaW5nPgogIDxrZXk+aXR1bmVzLXU8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2Evdmlld0dlbnJlP2lkPTQwMDAwMDAwPC9zdHJpbmc+CiAgPGtleT5tb3ZpZXM8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2Evdmlld01vdmllc01haW48L3N0cmluZz4KICA8a2V5Pm11c2ljPC9rZXk+PHN0cmluZz5odHRwOi8vaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL3ZpZXdNdXNpY01haW48L3N0cmluZz4KICA8a2V5PnBvZGNhc3RzPC9rZXk+PHN0cmluZz5odHRwOi8vaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL3ZpZXdQb2RjYXN0RGlyZWN0b3J5PC9zdHJpbmc+CiAgPGtleT5yaW5ndG9uZXM8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2Evdmlld1Jpbmd0b25lczwvc3RyaW5nPgogIDxrZXk+dHYtc2hvd3M8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2Evdmlld1RWU2hvd3NNYWluPC9zdHJpbmc+CiAgPGtleT5leHRlcm5hbFVSTFNlYXJjaEtleTwva2V5PjxzdHJpbmc+aXR1bmVzLmFwcGxlLmNvbTwvc3RyaW5nPgogIDxrZXk+ZXh0ZXJuYWxVUkxSZXBsYWNlS2V5PC9rZXk+PHN0cmluZz5pdHVuZXMuYXBwbGUuY29tPC9zdHJpbmc+CiAgPGtleT5zb25nTWV0YURhdGE8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2Evc29uZ01ldGFEYXRhPC9zdHJpbmc+CiAgPGtleT5zZWxlY3RlZEl0ZW1zUGFnZTwva2V5PjxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS9zZWxlY3RlZEl0ZW1zUGFnZTwvc3RyaW5nPgogIDxrZXk+c3dpc2gtdXJsPC9rZXk+PHN0cmluZz5odHRwOi8vaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL3ZpZXdSb29tP2ZjSWQ9Mjk3NDgwODcyJmFtcDtpZD0zNzwvc3RyaW5nPgogIDxrZXk+dXBsb2FkUHVibGlzaGVkUGxheWxpc3Q8L2tleT48c3RyaW5nPmh0dHA6Ly9jLml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkNvbm5lY3Rpb25zLndvYS93YS9jcmVhdGVJTWl4P3M9MTQzNDQxPC9zdHJpbmc+CiAgPGtleT5taW5pLXN0b3JlPC9rZXk+PHN0cmluZz5odHRwOi8vaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL21pbmlzdG9yZVJldGlyZWQ8L3N0cmluZz4KICA8a2V5Pm1pbmktc3RvcmUtZmllbGRzPC9rZXk+PHN0cmluZz48L3N0cmluZz4KICA8a2V5Pm1pbmktc3RvcmUtbWF0Y2g8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2EvbWluaXN0b3JlUmV0aXJlZDwvc3RyaW5nPgogIDxrZXk+bWluaS1zdG9yZS1tYXRjaC1maWVsZHM8L2tleT48c3RyaW5nPjwvc3RyaW5nPgogIDxrZXk+bWluaS1zdG9yZS13ZWxjb21lPC9rZXk+PHN0cmluZz5odHRwOi8vaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL21pbmlzdG9yZVJldGlyZWQ8L3N0cmluZz4KICA8a2V5Pm1heFB1Ymxpc2hlZFBsYXlsaXN0SXRlbXM8L2tleT48aW50ZWdlcj4xMDA8L2ludGVnZXI+CiAgPGtleT5hdmFpbGFibGUtcmluZ3RvbmVzPC9rZXk+PHN0cmluZz5odHRwOi8vbXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aUGVyc29uYWxpemVyLndvYS93YS9hdmFpbGFibGVSaW5ndG9uZXM8L3N0cmluZz4KICA8a2V5PmFib3V0LXJpbmd0b25lczwva2V5PjxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS9SaW5ndG9uZUxlYXJuTW9yZVBhZ2U8L3N0cmluZz4KICA8a2V5PnJpbmd0b25lLWluZm8tZmllbGRzLWxpc3Q8L2tleT4KICA8YXJyYXk+CiAgICA8c3RyaW5nPmlkLHMsZHNpZDwvc3RyaW5nPgogIDwvYXJyYXk+CiAgPGtleT5jb3Zlci1hcnQ8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZVNlcnZpY2VzLndvYS93YS9jb3ZlckFydE1hdGNoPC9zdHJpbmc+CiAgPGtleT5jb3Zlci1hcnQtbWF0Y2g8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZVNlcnZpY2VzLndvYS93YS9jb3ZlckFydE1hdGNoPC9zdHJpbmc+CiAgPGtleT5jb3Zlci1hcnQtZmllbGRzPC9rZXk+PHN0cmluZz5hLHA8L3N0cmluZz4KICA8a2V5PmNvdmVyLWFydC1jZC1maWVsZHM8L2tleT48c3RyaW5nPmNkZGI8L3N0cmluZz4KICA8a2V5PmNvdmVyLWFydC1tYXRjaC1maWVsZHM8L2tleT48c3RyaW5nPmNkZGItdHVpZCxjZGRiLGFuLGFhbixwbjwvc3RyaW5nPgogIDxrZXk+Y292ZXItYXJ0LWZpZWxkcy1saXN0PC9rZXk+CiAgPGFycmF5PgogICAgPHN0cmluZz5hLHA8L3N0cmluZz4KICAgIDxzdHJpbmc+aWQsY2RkYi10dWlkLGNkZGIsYW4sYWFuLHBuPC9zdHJpbmc+CiAgPC9hcnJheT4KICA8a2V5PmNvdmVyLWFydC11c2VyPC9rZXk+PHN0cmluZz5odHRwOi8vbXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aUGVyc29uYWxpemVyLndvYS93YS9jb3ZlckFydFVzZXI8L3N0cmluZz4KICA8a2V5Pm1hdGNoVVJMczwva2V5PgogIDxhcnJheT4KICAgIDxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vPC9zdHJpbmc+CiAgICA8c3RyaW5nPmh0dHA6Ly9zZWFyY2guaXR1bmVzLmFwcGxlLmNvbS88L3N0cmluZz4KICAgIDxzdHJpbmc+aHR0cDovL2J1eS5pdHVuZXMuYXBwbGUuY29tLzwvc3RyaW5nPgogIDwvYXJyYXk+CiAgPGtleT5saWJyYXJ5LWxpbms8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZVNlcnZpY2VzLndvYS93YS9saWJyYXJ5TGluazwvc3RyaW5nPgogIDxrZXk+bGlicmFyeS1saW5rLWZpZWxkcy1saXN0PC9rZXk+CiAgPGFycmF5PgogICAgPHN0cmluZz5pZCxhLHAsZyxjZGRiLXR1aWQsYW4sY24sZ24sa2luZCxuLHBuLHBvZGNhc3QtdXJsPC9zdHJpbmc+CiAgPC9hcnJheT4KICA8a2V5PmxpYnJhcnlMaW5rPC9rZXk+PHN0cmluZz5odHRwOi8vaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU3RvcmVTZXJ2aWNlcy53b2Evd2EvbGlicmFyeUxpbms8L3N0cmluZz4KICA8a2V5Pm1heENvbXB1dGVyczwva2V5PjxzdHJpbmc+NTwvc3RyaW5nPgogIDxrZXk+dHJ1c3RlZERvbWFpbnM8L2tleT4KICA8YXJyYXk+CiAgICA8c3RyaW5nPmFsYmVydC1zby5hcHBsZS5jb208L3N0cmluZz4KICAgIDxzdHJpbmc+YWIyLXNvLmFwcGxlLmNvbTwvc3RyaW5nPgogICAgPHN0cmluZz5hbGJlcnQuYXBwbGUuY29tPC9zdHJpbmc+CiAgICA8c3RyaW5nPmJ1eWlwaG9uZS5hcHBsZS5jb208L3N0cmluZz4KICAgIDxzdHJpbmc+MmdhY3RpdmF0aW9uLmFwcGxlLmNvbTwvc3RyaW5nPgogICAgPHN0cmluZz4qLmlwcy5hcHBsZS5jb208L3N0cmluZz4KICAgIDxzdHJpbmc+d3d3LmFwcGxlLmNvbTwvc3RyaW5nPgogICAgPHN0cmluZz50cmFpbGVycy5hcHBsZS5jb208L3N0cmluZz4KICAgIDxzdHJpbmc+cGhvYm9zLmFwcGxlLmNvbTwvc3RyaW5nPgogICAgPHN0cmluZz4uaXR1bmVzLmFwcGxlLmNvbTwvc3RyaW5nPgogICAgPHN0cmluZz4ubXpzdGF0aWMuY29tPC9zdHJpbmc+CiAgICA8c3RyaW5nPml0dW5lcy5hcHBsZS5jb208L3N0cmluZz4KICAgIDxzdHJpbmc+bWV0cmljcy5hcHBsZS5jb208L3N0cmluZz4KICAgIDxzdHJpbmc+c2VjdXJlLm1lLmNvbTwvc3RyaW5nPgogICAgPHN0cmluZz4uYXBwbGUuY29tLmVkZ2VzdWl0ZS5uZXQ8L3N0cmluZz4KICAgIDxzdHJpbmc+c3VwcG9ydC5tYWMuY29tPC9zdHJpbmc+CiAgICA8c3RyaW5nPi5pdHVuZXMuY29tPC9zdHJpbmc+CiAgICA8c3RyaW5nPml0dW5lcy5jb208L3N0cmluZz4KICAgIDxzdHJpbmc+ZGVpbW9zLmFwcGxlLmNvbTwvc3RyaW5nPgogICAgPHN0cmluZz5kZWltb3MyLmFwcGxlLmNvbTwvc3RyaW5nPgogICAgPHN0cmluZz5kZWltb3MzLmFwcGxlLmNvbTwvc3RyaW5nPgogICAgPHN0cmluZz5pbmRpZ28wMS5hcHBsZS5jb208L3N0cmluZz4KICAgIDxzdHJpbmc+aW5kaWdvLWVkZ2UuYXBwbGUuY29tPC9zdHJpbmc+CiAgICA8c3RyaW5nPm53ay11bmJyaWNrMy5hcHBsZS5jb208L3N0cmluZz4KICAgIDxzdHJpbmc+bXpzdXBwb3J0LmFwcGxlLmNvbTwvc3RyaW5nPgogICAgPHN0cmluZz5zdG9yZXByZXZpZXcuYXBwbGUuY29tPC9zdHJpbmc+CiAgICA8c3RyaW5nPi5jb3JwLmFwcGxlLmNvbTwvc3RyaW5nPgogICAgPHN0cmluZz4uYXNpYS5hcHBsZS5jb208L3N0cmluZz4KICAgIDxzdHJpbmc+LmV1cm8uYXBwbGUuY29tPC9zdHJpbmc+CiAgICA8c3RyaW5nPmFpdXN3LmFwcGxlLmNvbTwvc3RyaW5nPgogICAgPHN0cmluZz5zb2Z0ZGVwb3QuZmlsZW1ha2VyLmNvbTwvc3RyaW5nPgogICAgPHN0cmluZz5pc3RkZXYxLmFwcGxlLmNvbTwvc3RyaW5nPgogICAgPHN0cmluZz5pc3R3ZWJkZXYxLmFwcGxlLmNvbTwvc3RyaW5nPgogICAgPHN0cmluZz4ucnRsY2RuLmFwcGxlLmNvbTwvc3RyaW5nPgogICAgPHN0cmluZz5pc3R3ZWIuYXBwbGUuY29tPC9zdHJpbmc+CiAgICA8c3RyaW5nPml0dW5lcy5hcHBsZS5jb208L3N0cmluZz4KICA8L2FycmF5PgogIDxrZXk+ZHNpZC1kb21haW5zPC9rZXk+CiAgPGFycmF5PgogICAgPHN0cmluZz5idXkuaXR1bmVzLmFwcGxlLmNvbTwvc3RyaW5nPgogICAgPHN0cmluZz4qLWJ1eS5pdHVuZXMuYXBwbGUuY29tPC9zdHJpbmc+CiAgICA8c3RyaW5nPnN1Lml0dW5lcy5hcHBsZS5jb208L3N0cmluZz4KICAgIDxzdHJpbmc+YXguc3UuaXR1bmVzLmFwcGxlLmNvbTwvc3RyaW5nPgogICAgPHN0cmluZz5teS5pdHVuZXMuYXBwbGUuY29tPC9zdHJpbmc+CiAgICA8c3RyaW5nPnNlLml0dW5lcy5hcHBsZS5jb208L3N0cmluZz4KICAgIDxzdHJpbmc+bXlhcHAuaXR1bmVzLmFwcGxlLmNvbTwvc3RyaW5nPgogICAgPHN0cmluZz51c2VycHViLml0dW5lcy5hcHBsZS5jb208L3N0cmluZz4KICAgIDxzdHJpbmc+Yy5pdHVuZXMuYXBwbGUuY29tPC9zdHJpbmc+CiAgICA8c3RyaW5nPnNjLml0dW5lcy5hcHBsZS5jb208L3N0cmluZz4KICAgIDxzdHJpbmc+ZHUuaXR1bmVzLmFwcGxlLmNvbTwvc3RyaW5nPgogICAgPHN0cmluZz5zaWRlYmFyLml0dW5lcy5hcHBsZS5jb208L3N0cmluZz4KICAgIDxzdHJpbmc+YXguc2lkZWJhci5pdHVuZXMuYXBwbGUuY29tPC9zdHJpbmc+CiAgICA8c3RyaW5nPiotaXR1bmVzLmFwcGxlLmNvbTwvc3RyaW5nPgogICAgPHN0cmluZz4qLWl0dW5lcy5hcHBsZS5jb208L3N0cmluZz4KICA8L2FycmF5PgogIDxrZXk+cGx1cy1pbmZvPC9rZXk+PHN0cmluZz5odHRwOi8vaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL2lUdW5lc1BsdXNMZWFybk1vcmVQYWdlPC9zdHJpbmc+CiAgPGtleT5oZC1pbmZvPC9rZXk+PHN0cmluZz5odHRwOi8vaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL0hEVFZMZWFybk1vcmVQYWdlPC9zdHJpbmc+CiAgPGtleT5hcHBsZXR2LXJlbGF0ZWQtY29udGVudC11cmw8L2tleT48c3RyaW5nPmh0dHA6Ly9teS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpQZXJzb25hbGl6ZXIud29hL3dhL3JlbGF0ZWRJdGVtc1NoZWxmPC9zdHJpbmc+CiAgPGtleT5hcHBsZXR2LXlvdXR1YmUtYXV0aC11cmw8L2tleT48c3RyaW5nPmh0dHBzOi8vd3d3Lmdvb2dsZS5jb20vPC9zdHJpbmc+CiAgPGtleT5hcHBsZXR2LXlvdXR1YmUtdXJsPC9rZXk+PHN0cmluZz5odHRwOi8vZ2RhdGEueW91dHViZS5jb20vPC9zdHJpbmc+CiAgPGtleT5hdmFpbGFibGUtc3RvcmVmcm9udHM8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2EvYXZhaWxhYmxlU3RvcmVGcm9udHM8L3N0cmluZz4KICA8a2V5PmFwcGxldHYtdmlldy10b3AtdXJsPC9rZXk+PHN0cmluZz5odHRwOi8vaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL3ZpZXdUb3A8L3N0cmluZz4KICA8a2V5PmFwcGxldHYtdXNlLXBlcnNvbmFsaXplZC1tZW51LWNvbnRlbnQ8L2tleT48c3RyaW5nPk5PPC9zdHJpbmc+CiAgPGtleT5HaG9zdHJpZGVyPC9rZXk+PHN0cmluZz5ZRVM8L3N0cmluZz4KICA8a2V5Pml0dW5lcy1wcmVzZW50cy1kaXJlY3RvcnktdXJsPC9rZXk+PHN0cmluZz5odHRwOi8vaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU3RvcmVTZXJ2aWNlcy53b2Evd3MvUlNTL2RpcmVjdG9yeTwvc3RyaW5nPgogIDxrZXk+cDItdG9wLXRlbjwva2V5PjxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS92aWV3VG9wVGVuc0xpc3Q8L3N0cmluZz4KICA8a2V5PnAyLXNlcnZpY2UtdGVybXMtdXJsPC9rZXk+PHN0cmluZz5odHRwOi8vd3d3LmFwcGxlLmNvbS9sZWdhbC9pdHVuZXMvd3cvPC9zdHJpbmc+CiAgPGtleT5tb2JpbGUtY29ubmVjdGlvbi10eXBlLWFsbG93czwva2V5PgogIDxkaWN0PgogICAgPGtleT4zRzwva2V5PgogICAgPGRpY3Q+CiAgICAgIDxrZXk+ZUJvb2stc3RvcmUtYXZhaWxhYmxlPC9rZXk+PHN0cmluZz5ZRVM8L3N0cmluZz4KICAgICAgPGtleT5lQm9vay1kb3dubG9hZC1zaXplLWxpbWl0LWluLWJ5dGVzPC9rZXk+PGludGVnZXI+MjA5NzE1MjA8L2ludGVnZXI+CiAgICAgIDxrZXk+ZUJvb2stc2VhcmNoLXBhcmFtZXRlcnM8L2tleT48c3RyaW5nPm1lZGlhPWVib29rPC9zdHJpbmc+CiAgICAgIDxrZXk+cDItbXVzaWMtc3RvcmUtYXZhaWxhYmxlPC9rZXk+PHN0cmluZz5ZRVM8L3N0cmluZz4KICAgICAgPGtleT5tdXNpYy1kb3dubG9hZC1zaXplLWxpbWl0LWluLWJ5dGVzPC9rZXk+PGludGVnZXI+MjA5NzE1MjA8L2ludGVnZXI+CiAgICAgIDxrZXk+cDItc3RvcmUtc2VhcmNoLXBhcmFtZXRlcnM8L2tleT48c3RyaW5nPm1lZGlhPWFsbDwvc3RyaW5nPgogICAgICA8a2V5PnAyLXN0b3JlLW5zLXNlYXJjaC1wYXJhbWV0ZXJzPC9rZXk+PHN0cmluZz5tZWRpYT1hbGxXaXRoUmluZ3RvbmU8L3N0cmluZz4KICAgICAgPGtleT5wMi1wb2RjYXN0cy1lbmFibGVkPC9rZXk+PHN0cmluZz5ZRVM8L3N0cmluZz4KICAgICAgPGtleT5wb2RjYXN0LWRvd25sb2FkLXNpemUtbGltaXQtaW4tYnl0ZXM8L2tleT48aW50ZWdlcj4yMDk3MTUyMDwvaW50ZWdlcj4KICAgICAgPGtleT5wMi1tdXNpYy1zZWFyY2gtcGFyYW1ldGVyczwva2V5PjxzdHJpbmc+bWVkaWE9bXVzaWNBbmRQb2RjYXN0PC9zdHJpbmc+CiAgICAgIDxrZXk+cDItc29mdHdhcmUtc3RvcmUtYXZhaWxhYmxlPC9rZXk+PHN0cmluZz5ZRVM8L3N0cmluZz4KICAgICAgPGtleT5zb2Z0d2FyZS1kb3dubG9hZC1zaXplLWxpbWl0LWluLWJ5dGVzPC9rZXk+PGludGVnZXI+MjA5NzE1MjA8L2ludGVnZXI+CiAgICAgIDxrZXk+dmlkZW8tZG93bmxvYWQtc2l6ZS1saW1pdC1pbi1ieXRlczwva2V5PjxpbnRlZ2VyPjIwOTcxNTIwPC9pbnRlZ2VyPgogICAgPC9kaWN0PgogICAgPGtleT4yRzwva2V5PgogICAgPGRpY3Q+CiAgICAgIDxrZXk+ZUJvb2stc3RvcmUtYXZhaWxhYmxlPC9rZXk+PHN0cmluZz5ZRVM8L3N0cmluZz4KICAgICAgPGtleT5lQm9vay1kb3dubG9hZC1zaXplLWxpbWl0LWluLWJ5dGVzPC9rZXk+PGludGVnZXI+MjA5NzE1MjA8L2ludGVnZXI+CiAgICAgIDxrZXk+ZUJvb2stc2VhcmNoLXBhcmFtZXRlcnM8L2tleT48c3RyaW5nPm1lZGlhPWVib29rPC9zdHJpbmc+CiAgICAgIDxrZXk+cDItbXVzaWMtc3RvcmUtYXZhaWxhYmxlPC9rZXk+PHN0cmluZz5ZRVM8L3N0cmluZz4KICAgICAgPGtleT5tdXNpYy1kb3dubG9hZC1zaXplLWxpbWl0LWluLWJ5dGVzPC9rZXk+PGludGVnZXI+MjA5NzE1MjA8L2ludGVnZXI+CiAgICAgIDxrZXk+cDItc3RvcmUtc2VhcmNoLXBhcmFtZXRlcnM8L2tleT48c3RyaW5nPm1lZGlhPWFsbDwvc3RyaW5nPgogICAgICA8a2V5PnAyLXN0b3JlLW5zLXNlYXJjaC1wYXJhbWV0ZXJzPC9rZXk+PHN0cmluZz5tZWRpYT1hbGxXaXRoUmluZ3RvbmU8L3N0cmluZz4KICAgICAgPGtleT5wMi1wb2RjYXN0cy1lbmFibGVkPC9rZXk+PHN0cmluZz5ZRVM8L3N0cmluZz4KICAgICAgPGtleT5wb2RjYXN0LWRvd25sb2FkLXNpemUtbGltaXQtaW4tYnl0ZXM8L2tleT48aW50ZWdlcj4yMDk3MTUyMDwvaW50ZWdlcj4KICAgICAgPGtleT5wMi1tdXNpYy1zZWFyY2gtcGFyYW1ldGVyczwva2V5PjxzdHJpbmc+bWVkaWE9bXVzaWNBbmRQb2RjYXN0PC9zdHJpbmc+CiAgICAgIDxrZXk+cDItc29mdHdhcmUtc3RvcmUtYXZhaWxhYmxlPC9rZXk+PHN0cmluZz5ZRVM8L3N0cmluZz4KICAgICAgPGtleT5zb2Z0d2FyZS1kb3dubG9hZC1zaXplLWxpbWl0LWluLWJ5dGVzPC9rZXk+PGludGVnZXI+MjA5NzE1MjA8L2ludGVnZXI+CiAgICAgIDxrZXk+dmlkZW8tZG93bmxvYWQtc2l6ZS1saW1pdC1pbi1ieXRlczwva2V5PjxpbnRlZ2VyPjIwOTcxNTIwPC9pbnRlZ2VyPgogICAgPC9kaWN0PgogICAgPGtleT5XaUZpPC9rZXk+CiAgICA8ZGljdD4KICAgICAgPGtleT5lQm9vay1zdG9yZS1hdmFpbGFibGU8L2tleT48c3RyaW5nPllFUzwvc3RyaW5nPgogICAgICA8a2V5PmVCb29rLWRvd25sb2FkLXNpemUtbGltaXQtaW4tYnl0ZXM8L2tleT48aW50ZWdlcj4wPC9pbnRlZ2VyPgogICAgICA8a2V5PmVCb29rLXNlYXJjaC1wYXJhbWV0ZXJzPC9rZXk+PHN0cmluZz5tZWRpYT1lYm9vazwvc3RyaW5nPgogICAgICA8a2V5PnAyLW11c2ljLXN0b3JlLWF2YWlsYWJsZTwva2V5PjxzdHJpbmc+WUVTPC9zdHJpbmc+CiAgICAgIDxrZXk+bXVzaWMtZG93bmxvYWQtc2l6ZS1saW1pdC1pbi1ieXRlczwva2V5PjxpbnRlZ2VyPjA8L2ludGVnZXI+CiAgICAgIDxrZXk+cDItc3RvcmUtc2VhcmNoLXBhcmFtZXRlcnM8L2tleT48c3RyaW5nPm1lZGlhPWFsbDwvc3RyaW5nPgogICAgICA8a2V5PnAyLXN0b3JlLW5zLXNlYXJjaC1wYXJhbWV0ZXJzPC9rZXk+PHN0cmluZz5tZWRpYT1hbGxXaXRoUmluZ3RvbmU8L3N0cmluZz4KICAgICAgPGtleT5wMi1wb2RjYXN0cy1lbmFibGVkPC9rZXk+PHN0cmluZz5ZRVM8L3N0cmluZz4KICAgICAgPGtleT5wb2RjYXN0LWRvd25sb2FkLXNpemUtbGltaXQtaW4tYnl0ZXM8L2tleT48aW50ZWdlcj4wPC9pbnRlZ2VyPgogICAgICA8a2V5PnAyLW11c2ljLXNlYXJjaC1wYXJhbWV0ZXJzPC9rZXk+PHN0cmluZz5tZWRpYT1tdXNpY0FuZFBvZGNhc3Q8L3N0cmluZz4KICAgICAgPGtleT5wMi1zb2Z0d2FyZS1zdG9yZS1hdmFpbGFibGU8L2tleT48c3RyaW5nPllFUzwvc3RyaW5nPgogICAgICA8a2V5PnNvZnR3YXJlLWRvd25sb2FkLXNpemUtbGltaXQtaW4tYnl0ZXM8L2tleT48aW50ZWdlcj4wPC9pbnRlZ2VyPgogICAgICA8a2V5PnZpZGVvLWRvd25sb2FkLXNpemUtbGltaXQtaW4tYnl0ZXM8L2tleT48aW50ZWdlcj4wPC9pbnRlZ2VyPgogICAgPC9kaWN0PgogIDwvZGljdD4KICA8a2V5PnAyLW11c2ljLXNlYXJjaDwva2V5PjxzdHJpbmc+aHR0cDovL2F4LnNlYXJjaC5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTZWFyY2gud29hL3dhL3NlYXJjaDwvc3RyaW5nPgogIDxrZXk+cDItbXVzaWMtc2VhcmNoSGludHM8L2tleT48c3RyaW5nPmh0dHA6Ly9heC5zZWFyY2guaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU2VhcmNoSGludHMud29hL3dhL2hpbnRzPC9zdHJpbmc+CiAgPGtleT5wMi1ib29rLXNlYXJjaDwva2V5PjxzdHJpbmc+aHR0cDovL2F4LnNlYXJjaC5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTZWFyY2gud29hL3dhL3NlYXJjaD9tZWRpYT1lYm9vazwvc3RyaW5nPgogIDxrZXk+cDItYm9vay1zZWFyY2hIaW50czwva2V5PjxzdHJpbmc+aHR0cDovL2F4LnNlYXJjaC5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTZWFyY2hIaW50cy53b2Evd2EvaGludHM/bWVkaWE9ZWJvb2s8L3N0cmluZz4KICA8a2V5Pm1vYmlsZS10YWItYmFyczwva2V5PgogIDxkaWN0PgogICAgPGtleT5XaUZpLU11c2ljPC9rZXk+CiAgICA8ZGljdD4KICAgICAgPGtleT52ZXJzaW9uPC9rZXk+PHN0cmluZz4zMy0xNDM0NDE8L3N0cmluZz4KICAgICAgPGtleT51cmw8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2EvZm9vdGVyU2VjdGlvbnM/YXBwPXdpZmk8L3N0cmluZz4KICAgIDwvZGljdD4KICAgIDxrZXk+U29mdHdhcmU8L2tleT4KICAgIDxkaWN0PgogICAgICA8a2V5PnZlcnNpb248L2tleT48c3RyaW5nPjEyLTE0MzQ0MTwvc3RyaW5nPgogICAgICA8a2V5PnVybDwva2V5PjxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS9mb290ZXJTZWN0aW9ucz9hcHA9YXBwPC9zdHJpbmc+CiAgICA8L2RpY3Q+CiAgICA8a2V5PmVCb29rczwva2V5PgogICAgPGRpY3Q+CiAgICAgIDxrZXk+dmVyc2lvbjwva2V5PjxzdHJpbmc+Ny0xNDM0NDE8L3N0cmluZz4KICAgICAgPGtleT51cmw8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2EvZm9vdGVyU2VjdGlvbnM/YXBwPWVCb29rczwvc3RyaW5nPgogICAgPC9kaWN0PgogIDwvZGljdD4KICA8a2V5PnAyLWxhdW5jaC1ob3N0LXN1ZmZpeC13aGl0ZWxpc3Q8L2tleT4KICA8YXJyYXk+CiAgICA8c3RyaW5nPi5hcHBsZS5jb208L3N0cmluZz4KICA8L2FycmF5PgogIDxrZXk+cDItbGF1bmNoLW1vYmlsZXN0b3JlLWhvc3QtcGF0dGVybnM8L2tleT4KICA8YXJyYXk+CiAgICA8c3RyaW5nPigoYnV5fG15fHNlYXJjaHxjKVwuKT9pdHVuZXNcLmFwcGxlXC5jb20kPC9zdHJpbmc+CiAgICA8c3RyaW5nPnBob2Jvc1wuYXBwbGVcLmNvbSQ8L3N0cmluZz4KICA8L2FycmF5PgogIDxrZXk+cDItbGF1bmNoLW1vYmlsZXN0b3JlLXBhdGgtcGF0dGVybnM8L2tleT4KICA8YXJyYXk+CiAgICA8c3RyaW5nPl4vd2Vib2JqZWN0cy9tenN0b3JlLndvYS93YS8oc3RvcmVmcm9udHx2aWV3dG9wdGVuc2xpc3R8dmlld3RvcGZpZnR5fHZpZXd0b3B8dmlld2F1ZGlvYm9va3x2aWV3Z3JvdXBpbmd8dmlld2dlbnJlfHZpZXdwbGF5bGlzdHNwYWdlfHZpZXdyb29tfHZpZXdhbGJ1bXx2aWV3cG9kY2FzdHx2aWV3bWl4fHN0b3JlZnJvbnRzfHZpZXdjb250ZW50c3VzZXJyZXZpZXdzfHZpZXdldWxhfHZpZXd0dnNob3d8dmlld3R2c2Vhc29ufHZpZXdtb3ZpZXx2aWV3dmlkZW98Zm9vdGVyc2VjdGlvbnN8bGlicmFyeWxpbmt8dmlld2ZlYXR1cmV8dmlld2FydGlzdCk8L3N0cmluZz4KICAgIDxzdHJpbmc+Xi93ZWJvYmplY3RzL216c2VhcmNoLndvYS93YS8oc2VhcmNofGFkdmFuY2Vkc2VhcmNoKTwvc3RyaW5nPgogICAgPHN0cmluZz5eL3dlYm9iamVjdHMvbXooZmFzdCk/ZmluYW5jZS53b2Evd2EvKGNvbS5hcHBsZS5qaW5nbGUuYXBwLmZpbmFuY2UuZGlyZWN0YWN0aW9uLyk/KHJlZGVlbWxhbmRpbmdwYWdlfGZyZWVwcm9kdWN0Y29kZXdpemFyZHxjaGVja2ZvcnByZW9yZGVyc3xzaG93ZGlhbG9nZm9ycmVkZWVtfGJ1eW9uZWdldG9uZXxjaGVja2ZvcnB1cmNoYXNlc2F1dGh8YXJ0aXN0Y29ubmVjdHxyZWpvaW5hcnRpc3Rjb25uZWN0fG9wdGludG9jb25uZWN0aW9uc3xyZWpvaW5vcHRpbnRvY29ubmVjdGlvbnN8b3B0aW50b3BpbmcpPC9zdHJpbmc+CiAgICA8c3RyaW5nPl4vKFthLXpdW2Etel0vKT8oYWxidW18YXJ0aXN0fGF1ZGlvYm9va3xhdWRpb2Jvb2tzfGF1dGhvcnxib29rfGJyb3dzZXxjYXRlZ29yeXxjZWxlYnJpdHktcGxheWxpc3RzfGNoYXJ0c3xjb2xsYWJvcmF0aW9ufGNvbGxlY3Rpb258Y29sbGVjdGlvbnN8Y29tcG9zZXJ8Y3VzdG9tZXItcmV2aWV3c3xkaXJlY3Rvcnxlc3NlbnRpYWx8ZXNzZW50aWFsc3xmYXF8Z2VucmV8aW1peHxpbWl4ZXN8bW92aWV8bW92aWUtcmVudGFsc3xtb3ZpZXN8bXVzaWN8bXVzaWMtdmlkZW98cGxheWxpc3R8cG9kY2FzdHxwb2RjYXN0c3xwcmVvcmRlcnxwcm9tb3Rpb258cmV2aWV3fHJldmlld3N8c3RvcmV8c3R1ZGlvfHR2LXNlYXNvbnx0di1zaG93fHR2LXNob3dzfHZpZGVvfGl0dW5lcy11fGluc3RpdHV0aW9ufG9wdGludG9jb25uZWN0aW9uc3xvcHRpbnRvcGluZykoL3xcP3wkKTwvc3RyaW5nPgogICAgPHN0cmluZz5eL3dlYm9iamVjdHMvbXpjb250ZW50bGluay53b2Evd2EvbGluayhcP3wkKTwvc3RyaW5nPgogICAgPHN0cmluZz5eL3dlYm9iamVjdHMvbXpjb25uZWN0aW9ucy53b2Evd2EvPC9zdHJpbmc+CiAgICA8c3RyaW5nPl4vd2Vib2JqZWN0cy9tenVzZXJwdWJsaXNoaW5nLndvYS93YS8obWFuYWdlYXJ0aXN0YWxlcnRzKTwvc3RyaW5nPgogICAgPHN0cmluZz5eL3dlYm9iamVjdHMvbXpwZXJzb25hbGl6ZXIud29hL3dhLyhteWFsZXJ0cyk8L3N0cmluZz4KICA8L2FycmF5PgogIDxrZXk+cDItbGF1bmNoLWFwcHN0b3JlLWhvc3QtcGF0dGVybnM8L2tleT4KICA8YXJyYXk+CiAgICA8c3RyaW5nPigoYnV5fG15fHNlYXJjaHxjKVwuKT9pdHVuZXNcLmFwcGxlXC5jb20kPC9zdHJpbmc+CiAgICA8c3RyaW5nPnBob2Jvc1wuYXBwbGVcLmNvbSQ8L3N0cmluZz4KICA8L2FycmF5PgogIDxrZXk+cDItbGF1bmNoLWFwcHN0b3JlLXBhdGgtcGF0dGVybnM8L2tleT4KICA8YXJyYXk+CiAgICA8c3RyaW5nPlsmYW1wOz9dKG10PTh8bWVkaWE9c29mdHdhcmUpKCZhbXA7fCQpPC9zdHJpbmc+CiAgICA8c3RyaW5nPl4vd2Vib2JqZWN0cy9tenNvZnR3YXJldXBkYXRlLndvYS93YS8oYXZhaWxhYmxlc29mdHdhcmV1cGRhdGVzKTwvc3RyaW5nPgogICAgPHN0cmluZz5eL3dlYm9iamVjdHMvbXpzdG9yZS53b2Evd2EvKHZpZXdzb2Z0d2FyZXxwYW5kYXN0b3JlZnJvbnR8dmlld2ZlYXR1cmVkc29mdHdhcmVjYXRlZ29yaWVzKTwvc3RyaW5nPgogICAgPHN0cmluZz5eL3dlYm9iamVjdHMvbXpmaW5hbmNlLndvYS93YS8oY29tLmFwcGxlLmppbmdsZS5hcHAuZmluYW5jZS5kaXJlY3RhY3Rpb24vKT8odmVyaWZ5YWNjb3VudGVtYWlsKTwvc3RyaW5nPgogICAgPHN0cmluZz5eLyhbYS16XVthLXpdLyk/KGFwcHxhcHBzLXN0b3JlfGRldmVsb3BlcikoL3xcP3wkKTwvc3RyaW5nPgogIDwvYXJyYXk+CiAgPGtleT5wMi1sYXVuY2gtZWJvb2tzdG9yZS1ob3N0LXBhdHRlcm5zPC9rZXk+CiAgPGFycmF5PgogICAgPHN0cmluZz4oKGJ1eXxteXxzZWFyY2h8YylcLik/aXR1bmVzXC5hcHBsZVwuY29tJDwvc3RyaW5nPgogICAgPHN0cmluZz5waG9ib3NcLmFwcGxlXC5jb20kPC9zdHJpbmc+CiAgPC9hcnJheT4KICA8a2V5PnAyLWxhdW5jaC1lYm9va3N0b3JlLXBhdGgtcGF0dGVybnM8L2tleT4KICA8YXJyYXk+CiAgICA8c3RyaW5nPlsmYW1wOz9dKG10PTExfG1lZGlhPWVib29rKSgmYW1wO3wkKTwvc3RyaW5nPgogICAgPHN0cmluZz5eL3dlYm9iamVjdHMvbXpzdG9yZS53b2Evd2EvKHZpZXdib29rKTwvc3RyaW5nPgogICAgPHN0cmluZz5eLyhbYS16XVthLXpdLyk/KGJvb2spKC98XD98JCk8L3N0cmluZz4KICA8L2FycmF5PgogIDxrZXk+cDItbGF1bmNoLWFwcGxlLXN0b3JlLWhvc3QtcGF0dGVybnM8L2tleT4KICA8YXJyYXk+CiAgICA8c3RyaW5nPl4oc3RvcmV8cmVzZXJ2ZSlbLl1hcHBsZVsuXWNvbSQ8L3N0cmluZz4KICA8L2FycmF5PgogIDxrZXk+cDItbGF1bmNoLWFwcGxlLXN0b3JlLXBhdGgtcGF0dGVybnM8L2tleT4KICA8YXJyYXk+CiAgICA8c3RyaW5nPl4vKFteL10rLyk/eGMvPC9zdHJpbmc+CiAgICA8c3RyaW5nPl5bXj9dKi9yZXNlcnZlcHJvZHVjdChcP3wkKTwvc3RyaW5nPgogIDwvYXJyYXk+CiAgPGtleT5wMi11cmwtcmVzb2x1dGlvbjwva2V5PgogIDxhcnJheT4KICAgIDxkaWN0PgogICAgICA8a2V5PnAyLXVybC1zZWN0aW9uLW5hbWU8L2tleT48c3RyaW5nPkVCb29rczwvc3RyaW5nPgogICAgICA8a2V5Pmhvc3Qtc3VmZml4LXdoaXRlbGlzdDwva2V5PgogICAgICA8YXJyYXk+CiAgICAgICAgPHN0cmluZz4uYXBwbGUuY29tPC9zdHJpbmc+CiAgICAgIDwvYXJyYXk+CiAgICAgIDxrZXk+aG9zdC1wYXR0ZXJuczwva2V5PgogICAgICA8YXJyYXk+CiAgICAgICAgPHN0cmluZz4oKGJ1eXxteXxzZWFyY2h8YylcLik/aXR1bmVzXC5hcHBsZVwuY29tJDwvc3RyaW5nPgogICAgICAgIDxzdHJpbmc+cGhvYm9zXC5hcHBsZVwuY29tJDwvc3RyaW5nPgogICAgICA8L2FycmF5PgogICAgICA8a2V5PnBhdGgtcGF0dGVybnM8L2tleT4KICAgICAgPGFycmF5PgogICAgICAgIDxzdHJpbmc+WyZhbXA7P10obXQ9MTF8bWVkaWE9ZWJvb2spKCZhbXA7fCQpPC9zdHJpbmc+CiAgICAgICAgPHN0cmluZz5eL3dlYm9iamVjdHMvbXpzdG9yZS53b2Evd2EvKHZpZXdib29rKTwvc3RyaW5nPgogICAgICAgIDxzdHJpbmc+Xi8oW2Etel1bYS16XS8pPyhib29rKSgvfFw/fCQpPC9zdHJpbmc+CiAgICAgIDwvYXJyYXk+CiAgICAgIDxrZXk+c2NoZW1lLW1hcHBpbmc8L2tleT4KICAgICAgPGRpY3Q+CiAgICAgICAgPGtleT5odHRwPC9rZXk+PHN0cmluZz5pdG1zLWJvb2s8L3N0cmluZz4KICAgICAgICA8a2V5Pmh0dHBzPC9rZXk+PHN0cmluZz5pdG1zLWJvb2tzPC9zdHJpbmc+CiAgICAgIDwvZGljdD4KICAgIDwvZGljdD4KICAgIDxkaWN0PgogICAgICA8a2V5PnAyLXVybC1zZWN0aW9uLW5hbWU8L2tleT48c3RyaW5nPk1vYmlsZVNvZnR3YXJlQXBwbGljYXRpb25zPC9zdHJpbmc+CiAgICAgIDxrZXk+aG9zdC1zdWZmaXgtd2hpdGVsaXN0PC9rZXk+CiAgICAgIDxhcnJheT4KICAgICAgICA8c3RyaW5nPi5hcHBsZS5jb208L3N0cmluZz4KICAgICAgPC9hcnJheT4KICAgICAgPGtleT5ob3N0LXBhdHRlcm5zPC9rZXk+CiAgICAgIDxhcnJheT4KICAgICAgICA8c3RyaW5nPigoYnV5fG15fHNlYXJjaHxjKVwuKT9pdHVuZXNcLmFwcGxlXC5jb20kPC9zdHJpbmc+CiAgICAgICAgPHN0cmluZz5waG9ib3NcLmFwcGxlXC5jb20kPC9zdHJpbmc+CiAgICAgIDwvYXJyYXk+CiAgICAgIDxrZXk+cGF0aC1wYXR0ZXJuczwva2V5PgogICAgICA8YXJyYXk+CiAgICAgICAgPHN0cmluZz5bJmFtcDs/XShtdD04fG1lZGlhPXNvZnR3YXJlKSgmYW1wO3wkKTwvc3RyaW5nPgogICAgICAgIDxzdHJpbmc+Xi93ZWJvYmplY3RzL216c29mdHdhcmV1cGRhdGUud29hL3dhLyhhdmFpbGFibGVzb2Z0d2FyZXVwZGF0ZXMpPC9zdHJpbmc+CiAgICAgICAgPHN0cmluZz5eL3dlYm9iamVjdHMvbXpzdG9yZS53b2Evd2EvKHZpZXdzb2Z0d2FyZXxwYW5kYXN0b3JlZnJvbnR8dmlld2ZlYXR1cmVkc29mdHdhcmVjYXRlZ29yaWVzKTwvc3RyaW5nPgogICAgICAgIDxzdHJpbmc+Xi93ZWJvYmplY3RzL216ZmluYW5jZS53b2Evd2EvKGNvbS5hcHBsZS5qaW5nbGUuYXBwLmZpbmFuY2UuZGlyZWN0YWN0aW9uLyk/KHZlcmlmeWFjY291bnRlbWFpbCk8L3N0cmluZz4KICAgICAgICA8c3RyaW5nPl4vKFthLXpdW2Etel0vKT8oYXBwfGFwcHMtc3RvcmV8ZGV2ZWxvcGVyKSgvfFw/fCQpPC9zdHJpbmc+CiAgICAgIDwvYXJyYXk+CiAgICAgIDxrZXk+c2NoZW1lLW1hcHBpbmc8L2tleT4KICAgICAgPGRpY3Q+CiAgICAgICAgPGtleT5odHRwPC9rZXk+PHN0cmluZz5pdG1zLWFwcHM8L3N0cmluZz4KICAgICAgICA8a2V5Pmh0dHBzPC9rZXk+PHN0cmluZz5pdG1zLWFwcHNzPC9zdHJpbmc+CiAgICAgIDwvZGljdD4KICAgIDwvZGljdD4KICAgIDxkaWN0PgogICAgICA8a2V5PnAyLXVybC1zZWN0aW9uLW5hbWU8L2tleT48c3RyaW5nPk11c2ljPC9zdHJpbmc+CiAgICAgIDxrZXk+aG9zdC1zdWZmaXgtd2hpdGVsaXN0PC9rZXk+CiAgICAgIDxhcnJheT4KICAgICAgICA8c3RyaW5nPi5hcHBsZS5jb208L3N0cmluZz4KICAgICAgPC9hcnJheT4KICAgICAgPGtleT5ob3N0LXBhdHRlcm5zPC9rZXk+CiAgICAgIDxhcnJheT4KICAgICAgICA8c3RyaW5nPigoYnV5fG15fHNlYXJjaHxjKVwuKT9pdHVuZXNcLmFwcGxlXC5jb20kPC9zdHJpbmc+CiAgICAgICAgPHN0cmluZz5waG9ib3NcLmFwcGxlXC5jb20kPC9zdHJpbmc+CiAgICAgIDwvYXJyYXk+CiAgICAgIDxrZXk+cGF0aC1wYXR0ZXJuczwva2V5PgogICAgICA8YXJyYXk+CiAgICAgICAgPHN0cmluZz5eL3dlYm9iamVjdHMvbXpzdG9yZS53b2Evd2EvKHN0b3JlZnJvbnR8dmlld3RvcHRlbnNsaXN0fHZpZXd0b3BmaWZ0eXx2aWV3dG9wfHZpZXdhdWRpb2Jvb2t8dmlld2dyb3VwaW5nfHZpZXdnZW5yZXx2aWV3cGxheWxpc3RzcGFnZXx2aWV3cm9vbXx2aWV3YWxidW18dmlld3BvZGNhc3R8dmlld21peHxzdG9yZWZyb250c3x2aWV3Y29udGVudHN1c2VycmV2aWV3c3x2aWV3ZXVsYXx2aWV3dHZzaG93fHZpZXd0dnNlYXNvbnx2aWV3bW92aWV8dmlld3ZpZGVvfGZvb3RlcnNlY3Rpb25zfGxpYnJhcnlsaW5rfHZpZXdmZWF0dXJlfHZpZXdhcnRpc3QpPC9zdHJpbmc+CiAgICAgICAgPHN0cmluZz5eL3dlYm9iamVjdHMvbXpzZWFyY2gud29hL3dhLyhzZWFyY2h8YWR2YW5jZWRzZWFyY2gpPC9zdHJpbmc+CiAgICAgICAgPHN0cmluZz5eL3dlYm9iamVjdHMvbXooZmFzdCk/ZmluYW5jZS53b2Evd2EvKGNvbS5hcHBsZS5qaW5nbGUuYXBwLmZpbmFuY2UuZGlyZWN0YWN0aW9uLyk/KHJlZGVlbWxhbmRpbmdwYWdlfGZyZWVwcm9kdWN0Y29kZXdpemFyZHxjaGVja2ZvcnByZW9yZGVyc3xzaG93ZGlhbG9nZm9ycmVkZWVtfGJ1eW9uZWdldG9uZXxjaGVja2ZvcnB1cmNoYXNlc2F1dGh8YXJ0aXN0Y29ubmVjdHxyZWpvaW5hcnRpc3Rjb25uZWN0fG9wdGludG9jb25uZWN0aW9uc3xyZWpvaW5vcHRpbnRvY29ubmVjdGlvbnN8b3B0aW50b3BpbmcpPC9zdHJpbmc+CiAgICAgICAgPHN0cmluZz5eLyhbYS16XVthLXpdLyk/KGFsYnVtfGFydGlzdHxhdWRpb2Jvb2t8YXVkaW9ib29rc3xhdXRob3J8Ym9va3xicm93c2V8Y2F0ZWdvcnl8Y2VsZWJyaXR5LXBsYXlsaXN0c3xjaGFydHN8Y29sbGFib3JhdGlvbnxjb2xsZWN0aW9ufGNvbGxlY3Rpb25zfGNvbXBvc2VyfGN1c3RvbWVyLXJldmlld3N8ZGlyZWN0b3J8ZXNzZW50aWFsfGVzc2VudGlhbHN8ZmFxfGdlbnJlfGltaXh8aW1peGVzfG1vdmllfG1vdmllLXJlbnRhbHN8bW92aWVzfG11c2ljfG11c2ljLXZpZGVvfHBsYXlsaXN0fHBvZGNhc3R8cG9kY2FzdHN8cHJlb3JkZXJ8cHJvbW90aW9ufHJldmlld3xyZXZpZXdzfHN0b3JlfHN0dWRpb3x0di1zZWFzb258dHYtc2hvd3x0di1zaG93c3x2aWRlb3xpdHVuZXMtdXxpbnN0aXR1dGlvbnxvcHRpbnRvY29ubmVjdGlvbnN8b3B0aW50b3BpbmcpKC98XD98JCk8L3N0cmluZz4KICAgICAgICA8c3RyaW5nPl4vd2Vib2JqZWN0cy9temNvbnRlbnRsaW5rLndvYS93YS9saW5rKFw/fCQpPC9zdHJpbmc+CiAgICAgICAgPHN0cmluZz5eL3dlYm9iamVjdHMvbXpjb25uZWN0aW9ucy53b2Evd2EvPC9zdHJpbmc+CiAgICAgICAgPHN0cmluZz5eL3dlYm9iamVjdHMvbXp1c2VycHVibGlzaGluZy53b2Evd2EvKG1hbmFnZWFydGlzdGFsZXJ0cyk8L3N0cmluZz4KICAgICAgICA8c3RyaW5nPl4vd2Vib2JqZWN0cy9tenBlcnNvbmFsaXplci53b2Evd2EvKG15YWxlcnRzKTwvc3RyaW5nPgogICAgICA8L2FycmF5PgogICAgICA8a2V5PnNjaGVtZS1tYXBwaW5nPC9rZXk+CiAgICAgIDxkaWN0PgogICAgICAgIDxrZXk+aHR0cDwva2V5PjxzdHJpbmc+aXRtczwvc3RyaW5nPgogICAgICAgIDxrZXk+aHR0cHM8L2tleT48c3RyaW5nPml0bXNzPC9zdHJpbmc+CiAgICAgIDwvZGljdD4KICAgIDwvZGljdD4KICA8L2FycmF5PgogIDxrZXk+cDItbXVzaWMtc3RvcmUtYXZhaWxhYmxlPC9rZXk+PHN0cmluZz5ZRVM8L3N0cmluZz4KICA8a2V5PnAyLXNvZnR3YXJlLXN0b3JlLWF2YWlsYWJsZTwva2V5PjxzdHJpbmc+WUVTPC9zdHJpbmc+CiAgPGtleT5wMi1wYW5kYS1zdG9yZWZyb250PC9rZXk+PHN0cmluZz5odHRwOi8vaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL3BhbmRhU3RvcmVGcm9udDwvc3RyaW5nPgogIDxrZXk+cDItcGFuZGEtZ2VucmVzPC9rZXk+PHN0cmluZz5odHRwOi8vaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL3ZpZXdGZWF0dXJlZFNvZnR3YXJlQ2F0ZWdvcmllczwvc3RyaW5nPgogIDxrZXk+cDItcGFuZGEtdG9wLWNoYXJ0czwva2V5PjxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS92aWV3VG9wP2dlbnJlSWQ9MzY8L3N0cmluZz4KICA8a2V5PnAyLXBhbmRhLXRvcC1maWZ0eTwva2V5PjxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS92aWV3VG9wRmlmdHk/Z2VucmVJZD0zNjwvc3RyaW5nPgogIDxrZXk+cDItcGFuZGEtdXBkYXRlczwva2V5PjxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS92aWV3UGFuZGFVcGRhdGVzPC9zdHJpbmc+CiAgPGtleT5wMi1wYW5kYS1zZWFyY2g8L2tleT48c3RyaW5nPmh0dHA6Ly9heC5zZWFyY2guaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU2VhcmNoLndvYS93YS9zZWFyY2g/bWVkaWE9c29mdHdhcmU8L3N0cmluZz4KICA8a2V5PnAyLXBhbmRhLXNlYXJjaEhpbnRzPC9rZXk+PHN0cmluZz5odHRwOi8vYXguc2VhcmNoLml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlNlYXJjaEhpbnRzLndvYS93YS9oaW50cz9tZWRpYT1zb2Z0d2FyZTwvc3RyaW5nPgogIDxrZXk+YXZhaWxhYmxlLXNvZnR3YXJlLXVwZGF0ZXM8L2tleT48c3RyaW5nPmh0dHA6Ly9heC5zdS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTb2Z0d2FyZVVwZGF0ZS53b2Evd2EvYXZhaWxhYmxlU29mdHdhcmVVcGRhdGVzPC9zdHJpbmc+CiAgPGtleT5hdmFpbGFibGUtc29mdHdhcmUtdXBkYXRlcy1odG1sPC9rZXk+PHN0cmluZz5odHRwOi8vYXguc3UuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU29mdHdhcmVVcGRhdGUud29hL3dhL3ZpZXdTb2Z0d2FyZVVwZGF0ZXM8L3N0cmluZz4KICA8a2V5PmF2YWlsYWJsZS1zb2Z0d2FyZS1jaGVjay1vbi1sYXVuY2g8L2tleT48c3RyaW5nPllFUzwvc3RyaW5nPgogIDxrZXk+YXZhaWxhYmxlLXNvZnR3YXJlLXVwZGF0ZXMtcmVsb2FkLWZyZXF1ZW5jeTwva2V5PjxpbnRlZ2VyPjg0PC9pbnRlZ2VyPgogIDxrZXk+YXZhaWxhYmxlLXNvZnR3YXJlLXVwZGF0ZXMtY29tcHJlc3MtcmVxdWVzdDwva2V5PjxzdHJpbmc+WUVTPC9zdHJpbmc+CiAgPGtleT5wMi1hcHBsaWNhdGlvbi11c2VyLXJldmlldy1pbmZvPC9rZXk+PHN0cmluZz5odHRwczovL3VzZXJwdWIuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aVXNlclB1Ymxpc2hpbmcud29hL3dhL3VzZXJSZXZpZXdJbmZvP3R5cGU9UHVycGxlK1NvZnR3YXJlJmFtcDthbXA7ZGlzcGxheWFibGUta2luZD0xMTwvc3RyaW5nPgogIDxrZXk+cDItY2FwYWJpbGl0aWVzLWRpYWxvZzwva2V5PjxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS9jYXBhYmlsaXRpZXNEaWFsb2c8L3N0cmluZz4KICA8a2V5PnAyLWFjY2Vzc29yeS1yb29tPC9rZXk+PHN0cmluZz5odHRwOi8vaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL3ZpZXdBY2Nlc3NvcnlSb29tPC9zdHJpbmc+CiAgPGtleT5wMi1wcm9kdWN0LW9mZmVyczwva2V5PjxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS9mZXRjaFNvZnR3YXJlQWRkT25zPC9zdHJpbmc+CiAgPGtleT5wMi1wcm9kdWN0LW9mZmVycy1iYXRjaC1saW1pdDwva2V5PjxpbnRlZ2VyPjEwMDwvaW50ZWdlcj4KICA8a2V5PnAyLWFwcC1nZW5pdXMtc3RhdGlzdGljczwva2V5PgogIDxkaWN0PgogICAgPGtleT5hbGxvd2VkLWNvbm5lY3Rpb24tdHlwZXM8L2tleT4KICAgIDxkaWN0PgogICAgICA8a2V5PjNHPC9rZXk+PHN0cmluZz5ZRVM8L3N0cmluZz4KICAgICAgPGtleT4yRzwva2V5PjxzdHJpbmc+WUVTPC9zdHJpbmc+CiAgICAgIDxrZXk+V2lGaTwva2V5PjxzdHJpbmc+WUVTPC9zdHJpbmc+CiAgICA8L2RpY3Q+CiAgICA8a2V5PnVybDwva2V5PjxzdHJpbmc+aHR0cHM6Ly9nZW5pdXMuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL1VDQXBwQ2hhbm5lbC53b2Evd2EvYXBwU3RhdHM8L3N0cmluZz4KICAgIDxrZXk+cG9zdC1pbnRlcnZhbDwva2V5PjxpbnRlZ2VyPjE0NDAwPC9pbnRlZ2VyPgogICAgPGtleT5zZW5kLWRhdGEtdXNhZ2U8L2tleT48c3RyaW5nPk5PPC9zdHJpbmc+CiAgPC9kaWN0PgogIDxrZXk+Y2xpZW50LWNhY2hlLWRlZmluaXRpb25zPC9rZXk+CiAgPGRpY3Q+CiAgICA8a2V5PmNhY2hlczwva2V5PgogICAgPGFycmF5PgogICAgICA8ZGljdD4KICAgICAgICA8a2V5PnR5cGU8L2tleT48c3RyaW5nPmNsaWVudC1jYWNoZS1kZWZpbml0aW9uPC9zdHJpbmc+CiAgICAgICAgPGtleT5tZW1vcnktc2l6ZTwva2V5PjxpbnRlZ2VyPjE1NzI4NjQ8L2ludGVnZXI+CiAgICAgICAgPGtleT5kaXNrLXNpemU8L2tleT48aW50ZWdlcj4xNTcyODY0PC9pbnRlZ2VyPgogICAgICAgIDxrZXk+cGVyc2lzdGVudC1pZDwva2V5PjxzdHJpbmc+QjNDQnNjcmlwdENhY2hlPC9zdHJpbmc+CiAgICAgICAgPGtleT5jbGllbnRzPC9rZXk+CiAgICAgICAgPGFycmF5PgogICAgICAgICAgPHN0cmluZz5Tb2Z0d2FyZTwvc3RyaW5nPgogICAgICAgICAgPHN0cmluZz5lQm9va3M8L3N0cmluZz4KICAgICAgICAgIDxzdHJpbmc+V2lGaS1NdXNpYzwvc3RyaW5nPgogICAgICAgIDwvYXJyYXk+CiAgICAgICAgPGtleT5maWxlLWV4dGVuc2lvbnM8L2tleT4KICAgICAgICA8YXJyYXk+CiAgICAgICAgICA8c3RyaW5nPmNzczwvc3RyaW5nPgogICAgICAgICAgPHN0cmluZz5jc3N6PC9zdHJpbmc+CiAgICAgICAgICA8c3RyaW5nPmpzPC9zdHJpbmc+CiAgICAgICAgICA8c3RyaW5nPmpzejwvc3RyaW5nPgogICAgICAgIDwvYXJyYXk+CiAgICAgIDwvZGljdD4KICAgICAgPGRpY3Q+CiAgICAgICAgPGtleT50eXBlPC9rZXk+PHN0cmluZz5jbGllbnQtY2FjaGUtZGVmaW5pdGlvbjwvc3RyaW5nPgogICAgICAgIDxrZXk+bWVtb3J5LXNpemU8L2tleT48aW50ZWdlcj4yMDk3MTUyPC9pbnRlZ2VyPgogICAgICAgIDxrZXk+ZGlzay1zaXplPC9rZXk+PGludGVnZXI+MjA5NzE1MjwvaW50ZWdlcj4KICAgICAgICA8a2V5PnBlcnNpc3RlbnQtaWQ8L2tleT48c3RyaW5nPkIzQ0JpbWFnZUNhY2hlPC9zdHJpbmc+CiAgICAgICAgPGtleT5jbGllbnRzPC9rZXk+CiAgICAgICAgPGFycmF5PgogICAgICAgICAgPHN0cmluZz5Tb2Z0d2FyZTwvc3RyaW5nPgogICAgICAgICAgPHN0cmluZz5lQm9va3M8L3N0cmluZz4KICAgICAgICAgIDxzdHJpbmc+V2lGaS1NdXNpYzwvc3RyaW5nPgogICAgICAgIDwvYXJyYXk+CiAgICAgICAgPGtleT51cmwtcGF0dGVybnM8L2tleT4KICAgICAgICA8YXJyYXk+CiAgICAgICAgICA8c3RyaW5nPnNwcml0ZXMtazItc3RvcmVmcm9udC5wbmc8L3N0cmluZz4KICAgICAgICAgIDxzdHJpbmc+bWlkZGxlX2JsdWVfcHJlc3NlZC5wbmc8L3N0cmluZz4KICAgICAgICAgIDxzdHJpbmc+bWlkZGxlX2JsdWUucG5nPC9zdHJpbmc+CiAgICAgICAgICA8c3RyaW5nPm1pZGRsZV9ncmF5X3ByZXNzZWQucG5nPC9zdHJpbmc+CiAgICAgICAgICA8c3RyaW5nPm1pZGRsZV9ncmF5LnBuZzwvc3RyaW5nPgogICAgICAgICAgPHN0cmluZz5taWRkbGVfZ3JlZW5fcHJlc3NlZC5wbmc8L3N0cmluZz4KICAgICAgICAgIDxzdHJpbmc+bWlkZGxlX2dyZWVuLnBuZzwvc3RyaW5nPgogICAgICAgICAgPHN0cmluZz5taWRkbGVfZGFya2dyYXlfcHJlc3NlZC5wbmc8L3N0cmluZz4KICAgICAgICAgIDxzdHJpbmc+bWlkZGxlX3NpbHZlcl9wcmVzc2VkLnBuZzwvc3RyaW5nPgogICAgICAgICAgPHN0cmluZz5hY3Rpb24tYnV0dG9uLWJnLnBuZzwvc3RyaW5nPgogICAgICAgICAgPHN0cmluZz5hY3Rpb24tYnV0dG9uLWJnLXByZXNzZWQucG5nPC9zdHJpbmc+CiAgICAgICAgICA8c3RyaW5nPm1pZGRsZV9kYXJrZ3JheS5wbmc8L3N0cmluZz4KICAgICAgICAgIDxzdHJpbmc+bWlkZGxlX3NpbHZlci5wbmc8L3N0cmluZz4KICAgICAgICA8L2FycmF5PgogICAgICA8L2RpY3Q+CiAgICAgIDxkaWN0PgogICAgICAgIDxrZXk+dHlwZTwva2V5PjxzdHJpbmc+Y2xpZW50LWNhY2hlLWRlZmluaXRpb248L3N0cmluZz4KICAgICAgICA8a2V5Pm1lbW9yeS1zaXplPC9rZXk+PGludGVnZXI+MjA5NzE1MjwvaW50ZWdlcj4KICAgICAgICA8a2V5PnBlcnNpc3RlbnQtaWQ8L2tleT48c3RyaW5nPkIzQ0JtaXNjQ2FjaGU8L3N0cmluZz4KICAgICAgICA8a2V5PmNsaWVudHM8L2tleT4KICAgICAgICA8YXJyYXk+CiAgICAgICAgICA8c3RyaW5nPlNvZnR3YXJlPC9zdHJpbmc+CiAgICAgICAgICA8c3RyaW5nPmVCb29rczwvc3RyaW5nPgogICAgICAgICAgPHN0cmluZz5XaUZpLU11c2ljPC9zdHJpbmc+CiAgICAgICAgPC9hcnJheT4KICAgICAgPC9kaWN0PgogICAgPC9hcnJheT4KICA8L2RpY3Q+CiAgPGtleT5wbGF0Zm9ybS1ncmFkaWVudHM8L2tleT4KICA8ZGljdD4KICAgIDxrZXk+ZUJvb2tzPC9rZXk+CiAgICA8ZGljdD4KICAgICAgPGtleT5wYWdlPC9rZXk+CiAgICAgIDxkaWN0PgogICAgICAgIDxrZXk+dG9wLWNvbG9yPC9rZXk+PHN0cmluZz5yZ2IoMjExLDIxNSwyMTgpPC9zdHJpbmc+CiAgICAgICAgPGtleT5ib3R0b20tY29sb3I8L2tleT48c3RyaW5nPnJnYigyMTEsMjE1LDIxOCk8L3N0cmluZz4KICAgICAgPC9kaWN0PgogICAgPC9kaWN0PgogIDwvZGljdD4KICA8a2V5PnZpZXctbW9iaWxlLXNvZnR3YXJlLXVwZGF0ZXM8L2tleT48c3RyaW5nPmh0dHA6Ly9heC5zdS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTb2Z0d2FyZVVwZGF0ZS53b2Evd2Evdmlld0FsbEF2YWlsYWJsZVNvZnR3YXJlVXBkYXRlczwvc3RyaW5nPgogIDxrZXk+bm93LXBsYXlpbmctdXJsPC9rZXk+PHN0cmluZz5odHRwOi8vaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL25vd1BsYXlpbmc8L3N0cmluZz4KICA8a2V5Pm5vdy1wbGF5aW5nLW5ldHdvcmstZGV0ZWN0LXVybDwva2V5PjxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS9ub3dQbGF5aW5nPC9zdHJpbmc+CiAgPGtleT5hZGFtaWQtbG9va3VwLXVybDwva2V5PjxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS9hZGFtSWRMb29rdXA8L3N0cmluZz4KICA8a2V5PnJlbnRhbC1yZWNvbW1lbmRhdGlvbnM8L2tleT48c3RyaW5nPmh0dHA6Ly9teS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpQZXJzb25hbGl6ZXIud29hL3dhL3JlbnRhbFJlY29tbWVuZGF0aW9uczwvc3RyaW5nPgogIDxrZXk+cmVudGFsLW1haW48L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2Evdmlld1JlbnRhbE1haW48L3N0cmluZz4KICA8a2V5PnR2LXJlbnRhbC1tYWluPC9rZXk+PHN0cmluZz5odHRwOi8vaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL3ZpZXdUdlJlbnRhbE1haW4/cz0xNDM0NDE8L3N0cmluZz4KICA8a2V5PnZpZXdUVlNlYXNvbjwva2V5PjxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS92aWV3VFZTZWFzb248L3N0cmluZz4KICA8a2V5PnZpZXdUVlNob3c8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2Evdmlld1RWU2hvdzwvc3RyaW5nPgogIDxrZXk+dmlld01vdmllPC9rZXk+PHN0cmluZz5odHRwOi8vaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL3ZpZXdNb3ZpZTwvc3RyaW5nPgogIDxrZXk+dmlld0dhbWU8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2Evdmlld0dhbWU8L3N0cmluZz4KICA8a2V5PnZpZXdQcmVvcmRlcjwva2V5PjxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS92aWV3UHJlb3JkZXI8L3N0cmluZz4KICA8a2V5Pm5pa2UtcGx1cy1sYW5kaW5nLXBhZ2U8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2Evdmlld0N1c3RvbVBhZ2U/bmFtZT1wYWdlTmlrZTwvc3RyaW5nPgogIDxrZXk+bGlicmFyeS11cGRhdGUtYWNjZXB0aW5nLXJlcXVlc3RzPC9rZXk+PHN0cmluZz5odHRwczovL2dlbml1cy5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvVUNHb3Zlcm5vci53b2Evd2EvbGlicmFyeVVwZGF0ZUFjY2VwdGluZ1JlcXVlc3RzPC9zdHJpbmc+CiAgPGtleT5saWJyYXJ5LXVwZGF0ZS1yZXF1ZXN0PC9rZXk+PHN0cmluZz5odHRwczovL2dlbml1cy5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvVUNHb3Zlcm5vci53b2Evd2EvcmVxdWVzdExpYnJhcnlVcGRhdGU8L3N0cmluZz4KICA8a2V5PmxpYnJhcnktdXBkYXRlLWNoZWNrPC9rZXk+PHN0cmluZz5odHRwczovL2dlbml1cy5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvVUNHb3Zlcm5vci53b2Evd2EvY2hlY2tVcGRhdGVQcm9jZXNzaW5nU3RhdHVzPC9zdHJpbmc+CiAgPGtleT5saWJyYXJ5LXVwZGF0ZS1tZWRpYS10eXBlczwva2V5PjxzdHJpbmc+Ym9vayxmZWF0dXJlLW1vdmllLG11c2ljLXZpZGVvLHBvZGNhc3QtZmVlZCxwb2RjYXN0LWVwaXNvZGUsc29uZyx0di1lcGlzb2RlPC9zdHJpbmc+CiAgPGtleT5saWJyYXJ5LXVwZGF0ZS1maWVsZHM8L2tleT48c3RyaW5nPmFkZGVkLWRhdGUsYWxidW0tcmF0aW5nLGFsYnVtLXJhdGluZy1jb21wdXRlZCxhcnRpc3QtaWQsYXJ0aXN0LW5hbWUsY2RkYi1maW5nZXJwcmludCxjZGRiLWZpbmdlcnByaW50LW5vdC1hdmFpbCxjZGRiLW1lZGlhLWlkLGNkZGItbXVpZCxjZGRiLXRvYyxjZGRiLXR1aWQsY2RkYi10dWlkLXRhZyxjb21wb3Nlci1uYW1lLGR1cmF0aW9uLGVpZCxlcGlzb2RlLWlkLGVwaXNvZGUtbnVtYmVyLGV4Y2x1ZGUtZnJvbS1zaHVmZmxlLGZlZWQtdXJsLGZpbGVuYW1lLGdlbml1cy1wbGF5LWNvdW50LGdlbnJlLW5hbWUsZ3JhbmRwYXJlbnQtZGlyLGl0ZW0tY2hlY2tlZCxpdGVtLWlkLGl0ZW0tbmFtZSxraW5kLGxhY2tzLWNvdmVyLWFydCxsYXN0LXBsYXllZC1kYXRlLGxhc3Qtc2tpcHBlZC1kYXRlLGxvbmctZGVzY3JpcHRpb24sbWF0Y2gtaWQscGFyZW50LWRpcixwZXJzaXN0ZW50LWlkLHBsYXktY291bnQscGxheWxpc3QtaWQscGxheWxpc3QtbmFtZSxwb2RjYXN0LWNhdGVnb3J5LHBvZGNhc3QtZ3VpZCxwb2RjYXN0LWlkLHByb3RlY3RlZCxyZW50YWwsc2Vhc29uLW51bWJlcixzaG93LHNraXAtY291bnQsdHJhY2stbnVtYmVyLHRyYWNrLWNvdW50LHVzZXItcmF0aW5nLHVzZXItcmF0aW5nLWNvbXB1dGVkLHZhbGlkLWZpZWxkcyx5ZWFyPC9zdHJpbmc+CiAgPGtleT5saWJyYXJ5LXVwZGF0ZS1jb3JyZWxhdGlvbi1maWVsZHM8L2tleT48c3RyaW5nPmFkZGVkLWRhdGUsYWxidW0tcmF0aW5nLGFsYnVtLXJhdGluZy1jb21wdXRlZCxsYXN0LXBsYXllZC1kYXRlLGxhc3Qtc2tpcHBlZC1kYXRlLHBsYXktY291bnQsc2tpcC1jb3VudCx1c2VyLXJhdGluZyx1c2VyLXJhdGluZy1jb21wdXRlZDwvc3RyaW5nPgogIDxrZXk+bGlicmFyeS11cGRhdGUtbWF0Y2hpbmctZmllbGRzPC9rZXk+PHN0cmluZz5hcnRpc3QtbmFtZSxjZGRiLWZpbmdlcnByaW50LGNkZGItZmluZ2VycHJpbnQtbm90LWF2YWlsLCBjZGRiLW1lZGlhLWlkLGNkZGItbXVpZCxjZGRiLXRvYyxjZGRiLXR1aWQsY2RkYi10dWlkLXRhZyxjb21wb3Nlci1uYW1lLGR1cmF0aW9uLGVpZCxmaWxlbmFtZSxnZW5yZS1uYW1lLGdyYW5kcGFyZW50LWRpcixpdGVtLWNoZWNrZWQsaXRlbS1pZCxpdGVtLW5hbWUsa2luZCxtYXRjaC1pZCxwYXJlbnQtZGlyLHBlcnNpc3RlbnQtaWQscGxheWxpc3QtbmFtZSxwcm90ZWN0ZWQsdHJhY2stbnVtYmVyLHRyYWNrLWNvdW50LHllYXI8L3N0cmluZz4KICA8a2V5PmxpYnJhcnktdXBkYXRlLW1pbmltdW0tZmllbGRzPC9rZXk+PHN0cmluZz5hcnRpc3QtbmFtZSxjZGRiLWZpbmdlcnByaW50LGNkZGItZmluZ2VycHJpbnQtbm90LWF2YWlsLCBjZGRiLW1lZGlhLWlkLGNkZGItbXVpZCxjZGRiLXRvYyxjZGRiLXR1aWQsY2RkYi10dWlkLXRhZyxjb21wb3Nlci1uYW1lLGR1cmF0aW9uLGVpZCxmaWxlbmFtZSxnZW5yZS1uYW1lLGdyYW5kcGFyZW50LWRpcixpdGVtLWNoZWNrZWQsaXRlbS1pZCxpdGVtLW5hbWUsa2luZCxtYXRjaC1pZCxwYXJlbnQtZGlyLHBlcnNpc3RlbnQtaWQscGxheWxpc3QtbmFtZSxwcm90ZWN0ZWQsdHJhY2stbnVtYmVyLHRyYWNrLWNvdW50LHllYXI8L3N0cmluZz4KICA8a2V5PnVjLXNlcnZlci1kaXNhYmxlZDwva2V5PjxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS91c2VyQ29sbGVjdGlvbnNFcnJvcj9lcnJvcj1zZXJ2ZXJEaXNhYmxlZDwvc3RyaW5nPgogIDxrZXk+dWMtc2VydmVyLW5vdC1hY2NlcHRpbmctc2lnbnVwczwva2V5PjxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS91c2VyQ29sbGVjdGlvbnNFcnJvcj9lcnJvcj1zZXJ2ZXJOb3RBY2NlcHRpbmdTaWdudXBzPC9zdHJpbmc+CiAgPGtleT51Yy1nb3Zlcm5vci1lcnJvcjwva2V5PjxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS91c2VyQ29sbGVjdGlvbnNQcm9ncmVzcz9zdGF0ZT1lcnJvciZhbXA7c3RlcD0yPC9zdHJpbmc+CiAgPGtleT51Yy1wcm9ncmVzcy1zdG9wcGVkPC9rZXk+PHN0cmluZz5odHRwOi8vaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL3VzZXJDb2xsZWN0aW9uc1Byb2dyZXNzP3N0YXRlPXN0b3BwZWQ8L3N0cmluZz4KICA8a2V5PnVjLXN0ZXAtb25lPC9rZXk+PHN0cmluZz5odHRwOi8vaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL3VzZXJDb2xsZWN0aW9uc1Byb2dyZXNzP3N0ZXA9MTwvc3RyaW5nPgogIDxrZXk+dWMtc3RlcC10d28tc2VydmVyLXByb2Nlc3Npbmc8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2EvdXNlckNvbGxlY3Rpb25zUHJvZ3Jlc3M/c3RhdGU9c2VydmVycHJvY2Vzc2luZyZhbXA7c3RlcD0yPC9zdHJpbmc+CiAgPGtleT51Yy1zdGVwLXR3by11cGxvYWQ8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2EvdXNlckNvbGxlY3Rpb25zUHJvZ3Jlc3M/c3RhdGU9dXBsb2FkJmFtcDtzdGVwPTI8L3N0cmluZz4KICA8a2V5PnVjLXN0ZXAtdGhyZWU8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2EvdXNlckNvbGxlY3Rpb25zUHJvZ3Jlc3M/c3RlcD0zPC9zdHJpbmc+CiAgPGtleT51Yy1zdWNjZXNzLXBhZ2U8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2EvdXNlckNvbGxlY3Rpb25zSG93VG8/c3RhdGU9c3VjY2Vzczwvc3RyaW5nPgogIDxrZXk+dWMtaG93LXRvLXBhZ2U8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2EvdXNlckNvbGxlY3Rpb25zSG93VG88L3N0cmluZz4KICA8a2V5Pmdlbml1cy1vcHQtb3V0PC9rZXk+PHN0cmluZz5odHRwczovL2dlbml1cy5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvVUNHb3Zlcm5vci53b2Evd2Evb3B0T3V0TGlicmFyeTwvc3RyaW5nPgogIDxrZXk+bGlicmFyeS11cGRhdGUtc2VydmVyLWRpc2FibGVkPC9rZXk+PHN0cmluZz5odHRwOi8vaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL3VzZXJDb2xsZWN0aW9uc0Vycm9yP2Vycm9yPXNlcnZlckRpc2FibGVkPC9zdHJpbmc+CiAgPGtleT5saWJyYXJ5LXVwZGF0ZS1zZXJ2ZXItbm90LWFjY2VwdGluZy1zaWdudXBzPC9rZXk+PHN0cmluZz5odHRwOi8vaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL3VzZXJDb2xsZWN0aW9uc0Vycm9yP2Vycm9yPXNlcnZlck5vdEFjY2VwdGluZ1NpZ251cHM8L3N0cmluZz4KICA8a2V5PmxpYnJhcnktdXBkYXRlLWdvdmVybm9yLWVycm9yPC9rZXk+PHN0cmluZz5odHRwOi8vaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL3VzZXJDb2xsZWN0aW9uc1Byb2dyZXNzP3N0YXRlPWVycm9yJmFtcDtzdGVwPTI8L3N0cmluZz4KICA8a2V5PmxpYnJhcnktdXBkYXRlLXN0b3BwZWQ8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2EvdXNlckNvbGxlY3Rpb25zUHJvZ3Jlc3M/c3RhdGU9c3RvcHBlZDwvc3RyaW5nPgogIDxrZXk+bGlicmFyeS11cGRhdGUtc3RlcC1vbmU8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2EvdXNlckNvbGxlY3Rpb25zUHJvZ3Jlc3M/c3RlcD0xPC9zdHJpbmc+CiAgPGtleT5saWJyYXJ5LXVwZGF0ZS1zdGVwLXR3by1zZXJ2ZXItcHJvY2Vzc2luZzwva2V5PjxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS91c2VyQ29sbGVjdGlvbnNQcm9ncmVzcz9zdGF0ZT1zZXJ2ZXJwcm9jZXNzaW5nJmFtcDtzdGVwPTI8L3N0cmluZz4KICA8a2V5PmxpYnJhcnktdXBkYXRlLXN0ZXAtdHdvLXVwbG9hZDwva2V5PjxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS91c2VyQ29sbGVjdGlvbnNQcm9ncmVzcz9zdGF0ZT11cGxvYWQmYW1wO3N0ZXA9Mjwvc3RyaW5nPgogIDxrZXk+bGlicmFyeS11cGRhdGUtc3RlcC10aHJlZTwva2V5PjxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS91c2VyQ29sbGVjdGlvbnNQcm9ncmVzcz9zdGVwPTM8L3N0cmluZz4KICA8a2V5PmxpYnJhcnktdXBkYXRlLXN1Y2Nlc3MtcGFnZTwva2V5PjxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS91c2VyQ29sbGVjdGlvbnNIb3dUbz9zdGF0ZT1zdWNjZXNzPC9zdHJpbmc+CiAgPGtleT5saWJyYXJ5LXVwZGF0ZS1ob3ctdG8tcGFnZTwva2V5PjxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS91c2VyQ29sbGVjdGlvbnNIb3dUbzwvc3RyaW5nPgogIDxrZXk+c2lkZWJhci1mYWxsYmFjazwva2V5PjxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS9zaWRlYmFyRGVmYXVsdDwvc3RyaW5nPgogIDxrZXk+c2lkZWJhci10aW1lb3V0PC9rZXk+PGludGVnZXI+NTwvaW50ZWdlcj4KICA8a2V5PnNpZGViYXItd2VsY29tZTwva2V5PjxzdHJpbmc+aHR0cDovL2F4LnNpZGViYXIuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU2lkZWJhci53b2Evd2Evc2lkZWJhcldlbGNvbWU8L3N0cmluZz4KICA8a2V5PnNpZGViYXItbWF0Y2gtcnVsZXM8L2tleT4KICA8YXJyYXk+CiAgICA8ZGljdD4KICAgICAgPGtleT51cmw8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZVNlcnZpY2VzLndvYS93YS9zaWRlYmFyTWF0Y2g8L3N0cmluZz4KICAgICAgPGtleT5vcHRpb25hbC1maWVsZHM8L2tleT4KICAgICAgPGFycmF5PgogICAgICAgIDxzdHJpbmc+cDwvc3RyaW5nPgogICAgICAgIDxzdHJpbmc+YTwvc3RyaW5nPgogICAgICAgIDxzdHJpbmc+a2luZDwvc3RyaW5nPgogICAgICA8L2FycmF5PgogICAgICA8a2V5PnJlcXVpcmVkLWZpZWxkczwva2V5PgogICAgICA8YXJyYXk+CiAgICAgICAgPHN0cmluZz5pZDwvc3RyaW5nPgogICAgICA8L2FycmF5PgogICAgPC9kaWN0PgogICAgPGRpY3Q+CiAgICAgIDxrZXk+dXJsPC9rZXk+PHN0cmluZz5odHRwOi8vaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU3RvcmVTZXJ2aWNlcy53b2Evd2Evc2lkZWJhck1hdGNoPC9zdHJpbmc+CiAgICAgIDxrZXk+b3B0aW9uYWwtZmllbGRzPC9rZXk+CiAgICAgIDxhcnJheT4KICAgICAgICA8c3RyaW5nPmtpbmQ8L3N0cmluZz4KICAgICAgPC9hcnJheT4KICAgICAgPGtleT5yZXF1aXJlZC1maWVsZHM8L2tleT4KICAgICAgPGFycmF5PgogICAgICAgIDxzdHJpbmc+Y2RkYi10dWlkPC9zdHJpbmc+CiAgICAgIDwvYXJyYXk+CiAgICA8L2RpY3Q+CiAgICA8ZGljdD4KICAgICAgPGtleT51cmw8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZVNlcnZpY2VzLndvYS93YS9zaWRlYmFyTWF0Y2g8L3N0cmluZz4KICAgICAgPGtleT5vcHRpb25hbC1maWVsZHM8L2tleT4KICAgICAgPGFycmF5PgogICAgICAgIDxzdHJpbmc+dG51bTwvc3RyaW5nPgogICAgICAgIDxzdHJpbmc+a2luZDwvc3RyaW5nPgogICAgICA8L2FycmF5PgogICAgICA8a2V5PnJlcXVpcmVkLWZpZWxkczwva2V5PgogICAgICA8YXJyYXk+CiAgICAgICAgPHN0cmluZz5jZGRiPC9zdHJpbmc+CiAgICAgIDwvYXJyYXk+CiAgICA8L2RpY3Q+CiAgICA8ZGljdD4KICAgICAgPGtleT51cmw8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZVNlcnZpY2VzLndvYS93YS9zaWRlYmFyTWF0Y2g8L3N0cmluZz4KICAgICAgPGtleT5vcHRpb25hbC1maWVsZHM8L2tleT4KICAgICAgPGFycmF5PgogICAgICAgIDxzdHJpbmc+YW48L3N0cmluZz4KICAgICAgICA8c3RyaW5nPmduPC9zdHJpbmc+CiAgICAgICAgPHN0cmluZz5wbjwvc3RyaW5nPgogICAgICAgIDxzdHJpbmc+a2luZDwvc3RyaW5nPgogICAgICA8L2FycmF5PgogICAgICA8a2V5PnJlcXVpcmVkLWZpZWxkczwva2V5PgogICAgICA8YXJyYXk+CiAgICAgICAgPHN0cmluZz5uPC9zdHJpbmc+CiAgICAgIDwvYXJyYXk+CiAgICA8L2RpY3Q+CiAgICA8ZGljdD4KICAgICAgPGtleT5vcHRpb25hbC1maWVsZHM8L2tleT4KICAgICAgPGFycmF5PgogICAgICAgIDxzdHJpbmc+ZHA8L3N0cmluZz4KICAgICAgICA8c3RyaW5nPmtpbmQ8L3N0cmluZz4KICAgICAgPC9hcnJheT4KICAgICAgPGtleT51cmw8L2tleT48c3RyaW5nPmh0dHA6Ly9heC5zaWRlYmFyLml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlNpZGViYXIud29hL3dhL3NpZGViYXI8L3N0cmluZz4KICAgIDwvZGljdD4KICA8L2FycmF5PgogIDxrZXk+c2lkZWJhci1kaXN0aW5ndWlzaGVkLXBsYXlsaXN0czwva2V5PgogIDxkaWN0PgogICAgPGtleT4yPC9rZXk+CiAgICA8ZGljdD4KICAgIDwvZGljdD4KICAgIDxrZXk+Mzwva2V5PgogICAgPGRpY3Q+CiAgICA8L2RpY3Q+CiAgICA8a2V5PjQ8L2tleT4KICAgIDxkaWN0PgogICAgPC9kaWN0PgogICAgPGtleT4yNjwva2V5PgogICAgPGRpY3Q+CiAgICA8L2RpY3Q+CiAgICA8a2V5Pjc8L2tleT4KICAgIDxkaWN0PgogICAgPC9kaWN0PgogICAgPGtleT4xOTwva2V5PgogICAgPGRpY3Q+CiAgICA8L2RpY3Q+CiAgICA8a2V5PjIwPC9rZXk+CiAgICA8ZGljdD4KICAgIDwvZGljdD4KICA8L2RpY3Q+CiAgPGtleT5zaWRlYmFyLWZhbGxiYWNrMjwva2V5PjxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS9zaWRlYmFyRGVmYXVsdDwvc3RyaW5nPgogIDxrZXk+c2lkZWJhci10aW1lb3V0Mjwva2V5PjxpbnRlZ2VyPjA8L2ludGVnZXI+CiAgPGtleT5zaWRlYmFyLWRpc3Rpbmd1aXNoZWQtcGxheWxpc3RzMjwva2V5PgogIDxkaWN0PgogICAgPGtleT4xOTwva2V5PgogICAgPGRpY3Q+CiAgICA8L2RpY3Q+CiAgICA8a2V5PjQ8L2tleT4KICAgIDxkaWN0PgogICAgPC9kaWN0PgogICAgPGtleT4yNjwva2V5PgogICAgPGRpY3Q+CiAgICA8L2RpY3Q+CiAgICA8a2V5PjIwPC9rZXk+CiAgICA8ZGljdD4KICAgIDwvZGljdD4KICA8L2RpY3Q+CiAgPGtleT5wb2RjYXN0LWdldC1lcGlzb2RlPC9rZXk+PHN0cmluZz5odHRwOi8vaXR1bmVzLmFwcGxlLmNvbS9tZXRyaWNzL3BvZGNhc3QvZ2V0RXBpc29kZTwvc3RyaW5nPgogIDxrZXk+cG9kY2FzdC1wbGF5LWVwaXNvZGU8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL21ldHJpY3MvcG9kY2FzdC9wbGF5RXBpc29kZTwvc3RyaW5nPgogIDxrZXk+ZG93bmxvYWQtc3BlZWR0ZXN0LXBvc3QtcmVzdWx0cy11cmw8L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL3VwbG9hZC9kaWFnL2F0di88L3N0cmluZz4KICA8a2V5PmRvd25sb2FkLXNwZWVkdGVzdC11cmxzPC9rZXk+CiAgPGFycmF5PgogICAgPHN0cmluZz5odHRwOi8vYTU2OC5waG9ib3MuYXBwbGUuY29tL3VzL3IxMDAwLzAwMC9EaWFnL3Rlc3RfOE1CLm00dj9uby1zdG9yZT10cnVlPC9zdHJpbmc+CiAgICA8c3RyaW5nPmh0dHA6Ly9hNTY4LnBob2Jvcy5hcHBsZS5jb20vdXMvcjEwMDAvMDAwL0RpYWcvdGVzdF84TUIubTR2PC9zdHJpbmc+CiAgICA8c3RyaW5nPmh0dHA6Ly9hNTY4LnBob2Jvcy5hcHBsZS5jb20vdXMvcjEwMDAvMDAwL0RpYWcvdGVzdF84TUIubTR2PC9zdHJpbmc+CiAgPC9hcnJheT4KICA8a2V5PmRvd25sb2FkLW1vdmllLXNwZWVkdGVzdC11cmxzPC9rZXk+CiAgPGFycmF5PgogICAgPHN0cmluZz5odHRwOi8vYTEudi5waG9ib3MuYXBwbGUuY29tL3VzL3IxMDAwLzAwMC9EaWFnL1NURU1faGQubTR2P25vLXN0b3JlPXRydWU8L3N0cmluZz4KICAgIDxzdHJpbmc+aHR0cDovL2ExLnYucGhvYm9zLmFwcGxlLmNvbS91cy9yMTAwMC8wMDAvRGlhZy9TVEVNX2hkLm00djwvc3RyaW5nPgogICAgPHN0cmluZz5odHRwOi8vYTEudi5waG9ib3MuYXBwbGUuY29tL3VzL3IxMDAwLzAwMC9EaWFnL1NURU1faGQubTR2PC9zdHJpbmc+CiAgPC9hcnJheT4KICA8a2V5PnRndDwva2V5PjxzdHJpbmc+MTwvc3RyaW5nPgogIDxrZXk+ZW5kLW9mLWJvb2stdXBzZWxsLWVuYWJsZWQ8L2tleT48c3RyaW5nPllFUzwvc3RyaW5nPgogIDxrZXk+ZW5kLW9mLXBpY3R1cmUtYm9vay11cHNlbGwtZW5hYmxlZDwva2V5PjxzdHJpbmc+WUVTPC9zdHJpbmc+CiAgPGtleT5ib29rLXVwc2VsbDwva2V5PjxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS9ib29rVXBzZWxsPC9zdHJpbmc+CiAgPGtleT5ib29rLWxpYnJhcnktdGl0bGU8L2tleT48c3RyaW5nPkxpYnJhcnk8L3N0cmluZz4KICA8a2V5Pmlib29rczwva2V5PjxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS92aWV3U29mdHdhcmU/aWQ9MzY0NzA5MTkzPC9zdHJpbmc+CiAgPGtleT5maW4tcG9zdHM8L2tleT48c3RyaW5nPjE8L3N0cmluZz4KICA8a2V5PnRpbWVCZXR3ZWVuSG9tZVNoYXJpbmdDb3B5QXBwcm92YWxzPC9rZXk+PGludGVnZXI+ODY0MDA8L2ludGVnZXI+CiAgPGtleT5wMi1wYW5kYS1hcHBSZWNvbW1lbmRhdGlvbnM8L2tleT48c3RyaW5nPmh0dHA6Ly9teWFwcC5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpBcHBQZXJzb25hbGl6ZXIud29hL3dhL2FwcFJlY29tbWVuZGF0aW9ucz9tdD04PC9zdHJpbmc+CiAgPGtleT5hZGtpdC1wcm9kdWN0LXVybDwva2V5PjxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlN0b3JlLndvYS93YS9hZGtpdFByb2R1Y3Q8L3N0cmluZz4KICA8a2V5PmNyb3NzLW1lcmNoYW5kaXNpbmctdXJsPC9rZXk+PHN0cmluZz5odHRwOi8vaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU3RvcmUud29hL3dhL3ZpZXdDcm9zc01lcmNoYW5kaXNpbmc8L3N0cmluZz4KICA8a2V5Pmdob3N0LXJpZGluZy10aGUtd2hpcDwva2V5PjxzdHJpbmc+WUVTPC9zdHJpbmc+CiAgPGtleT5uZXRmbGl4LXRvcC1zaGVsZjwva2V5PjxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vbmV0ZmxpeC1nZW5lcmljLXNoZWxmLnhtbDwvc3RyaW5nPgogIDxrZXk+Z2hvc3QtcmlkaW5nLXRoZS13aGlwMjwva2V5PjxzdHJpbmc+WUVTPC9zdHJpbmc+CiAgPGtleT5jb25uZWN0aW9ucy11cmwtcHJlZml4ZXM8L2tleT4KICA8YXJyYXk+CiAgICA8c3RyaW5nPmh0dHA6Ly9jLml0dW5lcy5hcHBsZS5jb208L3N0cmluZz4KICAgIDxzdHJpbmc+aHR0cHM6Ly9jLml0dW5lcy5hcHBsZS5jb208L3N0cmluZz4KICAgIDxzdHJpbmc+aHR0cDovL2J1eS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpVc2VyUHJvZmlsZS53b2E8L3N0cmluZz4KICAgIDxzdHJpbmc+aHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aVXNlclByb2ZpbGUud29hPC9zdHJpbmc+CiAgICA8c3RyaW5nPmh0dHA6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2Evb3B0SW50b0Nvbm5lY3Rpb25zPC9zdHJpbmc+CiAgICA8c3RyaW5nPmh0dHBzOi8vYnV5Lml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL29wdEludG9Db25uZWN0aW9uczwvc3RyaW5nPgogICAgPHN0cmluZz5odHRwOi8vYnV5Lml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL3Jlam9pbk9wdEludG9Db25uZWN0aW9uczwvc3RyaW5nPgogICAgPHN0cmluZz5odHRwczovL2J1eS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS9yZWpvaW5PcHRJbnRvQ29ubmVjdGlvbnM8L3N0cmluZz4KICAgIDxzdHJpbmc+aHR0cDovL2J1eS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS9zb2NpYWxPcHRPdXQ8L3N0cmluZz4KICAgIDxzdHJpbmc+aHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2Evc29jaWFsT3B0T3V0PC9zdHJpbmc+CiAgPC9hcnJheT4KICA8a2V5PmNvbm5lY3Rpb25zLW1haW48L2tleT48c3RyaW5nPmh0dHA6Ly9pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZS53b2Evd2EvY29ubmVjdGlvbnNIb21lP3M9MTQzNDQxPC9zdHJpbmc+CiAgPGtleT5wMi1zb2NpYWwtbGluazwva2V5PgogIDxkaWN0PgogICAgPGtleT5saWtlLXVybDwva2V5PjxzdHJpbmc+aHR0cHM6Ly91c2VycHViLml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlVzZXJQdWJsaXNoaW5nLndvYS93YS9yYXRlP2NkPXQmYW1wO3I9LTImYW1wO3BsaXN0PXQ8L3N0cmluZz4KICAgIDxrZXk+cG9zdC11cmw8L2tleT48c3RyaW5nPmh0dHA6Ly9jLml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkNvbm5lY3Rpb25zLndvYS93YS92aWV3RHZQb3N0U2hlZXQ/cz0xNDM0NDE8L3N0cmluZz4KICAgIDxrZXk+aGlzdG9yeS11cmw8L2tleT48c3RyaW5nPmh0dHA6Ly9teS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpQZXJzb25hbGl6ZXIud29hL3dhL3NvY2lhbEhpc3Rvcnk/cz0xNDM0NDE8L3N0cmluZz4KICA8L2RpY3Q+CiAgPGtleT5waW5nLW1hdGNoPC9rZXk+PHN0cmluZz5odHRwOi8vYy5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpDb25uZWN0aW9ucy53b2Evd2EvcGluZ01hdGNoP3M9MTQzNDQxPC9zdHJpbmc+CiAgPGtleT5waW5nLW1hdGNoLWZpZWxkcy1saXN0PC9rZXk+CiAgPGFycmF5PgogICAgPHN0cmluZz5pZCxhLHAsZyxjZGRiLXR1aWQsYW4sY24sZ24sa2luZCxuLHBuPC9zdHJpbmc+CiAgPC9hcnJheT4KICA8a2V5PnBpbmctYWN0aW9uPC9rZXk+PHN0cmluZz5odHRwOi8vYy5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpDb25uZWN0aW9ucy53b2Evd2EvcGluZ0FjdGlvbj9zPTE0MzQ0MTwvc3RyaW5nPgogIDxrZXk+ZGEtc29vbjwva2V5PjxzdHJpbmc+aHR0cDovL2l0dW5lcy5hcHBsZS5jb20vc3RhdGljL3BhZ2VzL2FwcF9zdG9yZV9jb21pbmdfc29vbi5odG1sPC9zdHJpbmc+CiAgPGtleT51c2VyeHAtdXJsPC9rZXk+PHN0cmluZz5odHRwczovL21ldHJpY3MubXpzdGF0aWMuY29tLzwvc3RyaW5nPgogIDxrZXk+dXNlcnhwLXB1bnQtcmF0aW88L2tleT48aW50ZWdlcj4xMDAwPC9pbnRlZ2VyPgogIDxrZXk+bW9iaWxlLXVybC1oYW5kbGVyczwva2V5PgogIDxhcnJheT4KICAgIDxzdHJpbmc+aHR0cDwvc3RyaW5nPgogICAgPHN0cmluZz5odHRwczwvc3RyaW5nPgogICAgPHN0cmluZz5pdG1zPC9zdHJpbmc+CiAgICA8c3RyaW5nPml0bXNzPC9zdHJpbmc+CiAgICA8c3RyaW5nPml0bXMtYXBwczwvc3RyaW5nPgogICAgPHN0cmluZz5pdG1zLWFwcHNzPC9zdHJpbmc+CiAgICA8c3RyaW5nPml0bXMtYm9va3M8L3N0cmluZz4KICAgIDxzdHJpbmc+aXRtcy1ib29rc3M8L3N0cmluZz4KICAgIDxzdHJpbmc+bWFpbHRvPC9zdHJpbmc+CiAgICA8c3RyaW5nPmxpdmVuYXRpb248L3N0cmluZz4KICAgIDxzdHJpbmc+cHJlZnM8L3N0cmluZz4KICA8L2FycmF5PgogIDxrZXk+ZHQtcHVyY2hhc2VzLXBhZ2U8L2tleT48c3RyaW5nPmh0dHBzOi8vc2UuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aU3RvcmVFbGVtZW50cy53b2Evd2EvcHVyY2hhc2VzP3M9MTQzNDQxPC9zdHJpbmc+CiAgPGtleT5taW50LW9mZmVyczwva2V5PjxzdHJpbmc+aHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2EvcHJlc2VudE9mZmVyczwvc3RyaW5nPgogIDxrZXk+cGVyc29uYWxpemVkLWJ1eS1idXR0b25zPC9rZXk+CiAgPGRpY3Q+CiAgICA8a2V5PmVCb29rPC9rZXk+PHN0cmluZz5odHRwczovL3NlLml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWlN0b3JlRWxlbWVudHMud29hL3dhL2J1eUJ1dHRvbk1ldGFEYXRhP3BsaXN0UGFnZT10cnVlJmFtcDtzPTE0MzQ0MTwvc3RyaW5nPgogICAgPGtleT5zb2Z0d2FyZTwva2V5PjxzdHJpbmc+aHR0cHM6Ly9zZS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpTdG9yZUVsZW1lbnRzLndvYS93YS9idXlCdXR0b25NZXRhRGF0YT9wbGlzdFBhZ2U9dHJ1ZSZhbXA7cz0xNDM0NDE8L3N0cmluZz4KICA8L2RpY3Q+CiAgPGtleT5hdXRoZW50aWNhdGVBY2NvdW50PC9rZXk+PHN0cmluZz5odHRwczovL2J1eS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS9hdXRoZW50aWNhdGU8L3N0cmluZz4KICA8a2V5PmlQaG9uZUFjdGl2YXRpb248L2tleT48c3RyaW5nPmh0dHBzOi8vYWxiZXJ0LmFwcGxlLmNvbS9XZWJPYmplY3RzL0FMVW5icmljay53b2Evd2EvZGV2aWNlQWN0aXZhdGlvbjwvc3RyaW5nPgogIDxrZXk+ZGV2aWNlLWFjdGl2YXRpb248L2tleT48c3RyaW5nPmh0dHBzOi8vYWxiZXJ0LmFwcGxlLmNvbS9XZWJPYmplY3RzL0FMVW5icmljay53b2Evd2EvZGV2aWNlQWN0aXZhdGlvbjwvc3RyaW5nPgogIDxrZXk+Y2hlY2tVbmJyaWNrSGVhbHRoPC9rZXk+PHN0cmluZz5odHRwczovL2FsYmVydC5hcHBsZS5jb20vV2ViT2JqZWN0cy9BTFVuYnJpY2sud29hL3dhL0FMQWN0aXZhdGlvbk1vbml0b3IvY2hlY2tVbmJyaWNrSGVhbHRoPC9zdHJpbmc+CiAgPGtleT5hdXRob3JpemVNYWNoaW5lPC9rZXk+PHN0cmluZz5odHRwczovL2J1eS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS9hdXRob3JpemVNYWNoaW5lPC9zdHJpbmc+CiAgPGtleT5idXlQcm9kdWN0PC9rZXk+PHN0cmluZz5odHRwczovL2J1eS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpCdXkud29hL3dhL2J1eVByb2R1Y3Q8L3N0cmluZz4KICA8a2V5PmJ1eUNhcnQ8L2tleT48c3RyaW5nPmh0dHBzOi8vYnV5Lml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL2J1eUNhcnQ8L3N0cmluZz4KICA8a2V5PmRlYXV0aG9yaXplTWFjaGluZTwva2V5PjxzdHJpbmc+aHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2EvZGVhdXRob3JpemVNYWNoaW5lPC9zdHJpbmc+CiAgPGtleT5tYWNoaW5lQXV0aG9yaXphdGlvbkluZm88L2tleT48c3RyaW5nPmh0dHBzOi8vYnV5Lml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL21hY2hpbmVBdXRob3JpemF0aW9uSW5mbzwvc3RyaW5nPgogIDxrZXk+bW9kaWZ5QWNjb3VudDwva2V5PjxzdHJpbmc+aHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2EvYWNjb3VudFN1bW1hcnk8L3N0cmluZz4KICA8a2V5PnBlbmRpbmdTb25nczwva2V5PjxzdHJpbmc+aHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2EvcGVuZGluZ1NvbmdzPC9zdHJpbmc+CiAgPGtleT5zaWdudXA8L2tleT48c3RyaW5nPmh0dHBzOi8vYnV5Lml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL3NpZ251cFdpemFyZDwvc3RyaW5nPgogIDxrZXk+c29uZ0Rvd25sb2FkRG9uZTwva2V5PjxzdHJpbmc+aHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmFzdEZpbmFuY2Uud29hL3dhL3NvbmdEb3dubG9hZERvbmU8L3N0cmluZz4KICA8a2V5PmZvcmdvdHRlblBhc3N3b3JkPC9rZXk+PHN0cmluZz5odHRwczovL2J1eS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS9pRm9yZ290PC9zdHJpbmc+CiAgPGtleT5teUluZm88L2tleT48c3RyaW5nPmh0dHA6Ly9teWluZm8uY29ycC5hcHBsZS5jb20vPC9zdHJpbmc+CiAgPGtleT5ub0FPTEFjY291bnRzPC9rZXk+PGZhbHNlLz4KICA8a2V5Pm1pbnQtYWNjb3VudDwva2V5PjxzdHJpbmc+aHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2EvYWNjb3VudFN1bW1hcnk8L3N0cmluZz4KICA8a2V5Pm1pbnQtYWNjb3VudC1mcmFnbWVudDwva2V5PjxzdHJpbmc+aHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2EvYWNjb3VudFN1bW1hcnlGcmFnbWVudDwvc3RyaW5nPgogIDxrZXk+bG9nb3V0PC9rZXk+PHN0cmluZz5odHRwczovL2J1eS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS9sb2dvdXQ8L3N0cmluZz4KICA8a2V5PmFkZFRvQ2FydDwva2V5PjxzdHJpbmc+aHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2EvYWRkVG9DYXJ0PC9zdHJpbmc+CiAgPGtleT5yZW1vdmVGcm9tQ2FydDwva2V5PjxzdHJpbmc+aHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2EvcmVtb3ZlRnJvbUNhcnQ8L3N0cmluZz4KICA8a2V5PnNob3BwaW5nQ2FydDwva2V5PjxzdHJpbmc+aHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2Evc2hvcHBpbmdDYXJ0PC9zdHJpbmc+CiAgPGtleT5iY1VSTHM8L2tleT4KICA8YXJyYXk+CiAgICA8c3RyaW5nPmh0dHA6Ly8uaXR1bmVzLmFwcGxlLmNvbTwvc3RyaW5nPgogICAgPHN0cmluZz5odHRwOi8vd3d3LmF0ZG10LmNvbTwvc3RyaW5nPgogIDwvYXJyYXk+CiAgPGtleT5yZXBvcnRQb2RjYXN0PC9rZXk+PHN0cmluZz5odHRwczovL2J1eS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS9yZXBvcnRQb2RjYXN0PC9zdHJpbmc+CiAgPGtleT5jaGVjay1kb3dubG9hZC1xdWV1ZTwva2V5PjxzdHJpbmc+aHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2EvY2hlY2tEb3dubG9hZFF1ZXVlPC9zdHJpbmc+CiAgPGtleT5zZXQtYXV0by1kb3dubG9hZDwva2V5PjxzdHJpbmc+aHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2Evc2V0QXV0b0Rvd25sb2FkPC9zdHJpbmc+CiAgPGtleT5uZXctaXBvZC11c2VyPC9rZXk+PHN0cmluZz5odHRwczovL2J1eS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS9pUG9kUmVnaXN0cmF0aW9uPC9zdHJpbmc+CiAgPGtleT5uZXctaXBvZC11c2VyLTI8L2tleT48c3RyaW5nPmh0dHBzOi8vc2VjdXJlLm1lLmNvbS9zaWdudXAvaXR1bmVzPC9zdHJpbmc+CiAgPGtleT5uZXctdHYtdXNlcjwva2V5PjxzdHJpbmc+aHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2EvaVRWUmVnaXN0cmF0aW9uPC9zdHJpbmc+CiAgPGtleT5tZDUtbWlzbWF0Y2g8L2tleT48c3RyaW5nPmh0dHBzOi8vYnV5Lml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL21kNU1pc21hdGNoPC9zdHJpbmc+CiAgPGtleT5yZXBvcnQtZXJyb3I8L2tleT48c3RyaW5nPmh0dHBzOi8vYnV5Lml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL3JlcG9ydEVycm9yRnJvbUNsaWVudDwvc3RyaW5nPgogIDxrZXk+dXBkYXRlQXNzZXQ8L2tleT48c3RyaW5nPmh0dHBzOi8vYnV5Lml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL3VwZGF0ZUFzc2V0PC9zdHJpbmc+CiAgPGtleT5jcmVhdGUtdG9rZW48L2tleT48c3RyaW5nPmh0dHBzOi8vYnV5Lml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL2NyZWF0ZVRva2VuPC9zdHJpbmc+CiAgPGtleT5jcmVhdGUtc2Vzc2lvbjwva2V5PjxzdHJpbmc+aHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2EvY3JlYXRlU2Vzc2lvbjwvc3RyaW5nPgogIDxrZXk+ZGlnaXRhbC1jb3B5PC9rZXk+PHN0cmluZz5odHRwczovL2J1eS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS9kaWdpdGFsQ29weVdpemFyZDwvc3RyaW5nPgogIDxrZXk+cDItcmVkZW1wdGlvbjwva2V5PjxzdHJpbmc+aHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2EvcDJSZWRlZW1Db2RlPC9zdHJpbmc+CiAgPGtleT5wMi1oZWFkbGVzcy1yZWRlbXB0aW9uPC9rZXk+PHN0cmluZz5odHRwczovL2J1eS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS9wMkhlYWRsZXNzUmVkZWVtQ29kZTwvc3RyaW5nPgogIDxrZXk+cDItcmVkZWVtLXNlcnZpY2UtdGVybXMtdXJsPC9rZXk+PHN0cmluZz5odHRwOi8vd3d3LmFwcGxlLmNvbS9sZWdhbC9pdHVuZXMvd3cvPC9zdHJpbmc+CiAgPGtleT5wZW5kaW5nQXBwczwva2V5PjxzdHJpbmc+aHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2EvcGVuZGluZ0FwcHM8L3N0cmluZz4KICA8a2V5PmNoZWNrQXBwUXVldWU8L2tleT48c3RyaW5nPmh0dHBzOi8vYnV5Lml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL2NoZWNrQXBwRG93bmxvYWRRdWV1ZTwvc3RyaW5nPgogIDxrZXk+bWFya2V0aW5nLWFjdGlvbjwva2V5PjxzdHJpbmc+aHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2Evdmlld01hcmtldGluZ1BhZ2U8L3N0cmluZz4KICA8a2V5Pm1hcmtldGluZy1hY3Rpb24tMjwva2V5PjxzdHJpbmc+aHR0cHM6Ly9zZWN1cmUubWUuY29tL2l0dW5lc3NpZ251cDwvc3RyaW5nPgogIDxrZXk+Z2lmdFBsYXlsaXN0PC9rZXk+PHN0cmluZz5odHRwczovL2J1eS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS9naWZ0U29uZ3NXaXphcmQ8L3N0cmluZz4KICA8a2V5PmdpdmUtcGxheWxpc3Q8L2tleT48c3RyaW5nPmh0dHBzOi8vYnV5Lml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL2dpZnRTb25nc1dpemFyZDwvc3RyaW5nPgogIDxrZXk+bmV3VG91Y2hVc2VyPC9rZXk+PHN0cmluZz5odHRwczovL2J1eS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS90b3VjaExhbmRpbmdQYWdlP2lzRGV2aWNlU2VsZWN0ZWQ9dHJ1ZTwvc3RyaW5nPgogIDxrZXk+cmVudGFsLWNoZWNraW48L2tleT48c3RyaW5nPmh0dHBzOi8vYnV5Lml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL2NoZWNraW5SZW50YWw8L3N0cmluZz4KICA8a2V5PnJlbnRhbC1hY2stY2hlY2tpbjwva2V5PjxzdHJpbmc+aHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2EvY2hlY2tpbkFja1JlbnRhbDwvc3RyaW5nPgogIDxrZXk+cmVudGFsLWNoZWNrb3V0PC9rZXk+PHN0cmluZz5odHRwczovL2J1eS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS9jaGVja291dFJlbnRhbDwvc3RyaW5nPgogIDxrZXk+Z2V0LW5pa2l0YS1kcGluZm88L2tleT48c3RyaW5nPmh0dHBzOi8vYnV5Lml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL2lQb2RUcmFuc2Zlcjwvc3RyaW5nPgogIDxrZXk+YXBwLXJlY2VpcHQtY3JlYXRlPC9rZXk+PHN0cmluZz5odHRwczovL2J1eS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS9jcmVhdGVBcHBSZWNlaXB0PC9zdHJpbmc+CiAgPGtleT5jcmVhdGUtcmluZ3RvbmU8L2tleT48c3RyaW5nPmh0dHBzOi8vYnV5Lml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL2NyZWF0ZVJpbmd0b25lPC9zdHJpbmc+CiAgPGtleT5yaW5ndG9uZS1pbmZvPC9rZXk+PHN0cmluZz5odHRwczovL2J1eS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS9pc1Jpbmd0b25lYWJsZTwvc3RyaW5nPgogIDxrZXk+cDItY29uY2Vybi1saXN0PC9rZXk+PHN0cmluZz5odHRwczovL2J1eS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS9wMkdldFJlcG9ydEFDb25jZXJuTGlzdDwvc3RyaW5nPgogIDxrZXk+cDItcmVwb3J0LWNvbmNlcm48L2tleT48c3RyaW5nPmh0dHBzOi8vYnV5Lml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL3AyUmVwb3J0QVByb2JsZW08L3N0cmluZz4KICA8a2V5Pmdlbml1cy13ZWxjb21lPC9rZXk+PHN0cmluZz5odHRwczovL2J1eS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS91c2VyQ29sbGVjdGlvbnNXZWxjb21lPC9zdHJpbmc+CiAgPGtleT5wMi1jaGVjay1wcmUtb3JkZXItcXVldWU8L2tleT48c3RyaW5nPmh0dHBzOi8vYnV5Lml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL2dldFByZW9yZGVyUXVldWVDb3VudDwvc3RyaW5nPgogIDxrZXk+cDItcHJlLW9yZGVyLXF1ZXVlPC9rZXk+PHN0cmluZz5odHRwczovL2J1eS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS9nZXRQcmVvcmRlclF1ZXVlPC9zdHJpbmc+CiAgPGtleT5wMi1vcmRlci1wcmUtb3JkZXI8L2tleT48c3RyaW5nPmh0dHBzOi8vYnV5Lml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL29yZGVyUHJlb3JkZXI8L3N0cmluZz4KICA8a2V5PnAyLWNhbmNlbC1wcmUtb3JkZXI8L2tleT48c3RyaW5nPmh0dHBzOi8vYnV5Lml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL2NhbmNlbFByZW9yZGVyPC9zdHJpbmc+CiAgPGtleT5wMi1wcm9kdWN0LW9mZmVyPC9rZXk+PHN0cmluZz5odHRwczovL2J1eS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS9vZmZlckF2YWlsYWJpbGl0eUFuZEluZm9EaWFsb2c8L3N0cmluZz4KICA8a2V5PnAyLWluLWFwcC1idXk8L2tleT48c3RyaW5nPmh0dHBzOi8vYnV5Lml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkJ1eS53b2Evd2EvaW5BcHBCdXk8L3N0cmluZz4KICA8a2V5PnAyLWluLWFwcC1jaGVjay1kb3dubG9hZC1xdWV1ZTwva2V5PjxzdHJpbmc+aHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2EvaW5BcHBDaGVja0Rvd25sb2FkUXVldWU8L3N0cmluZz4KICA8a2V5PnAyLWluLWFwcC1wZW5kaW5nLXRyYW5zYWN0aW9uczwva2V5PjxzdHJpbmc+aHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2EvaW5BcHBQZW5kaW5nVHJhbnNhY3Rpb25zPC9zdHJpbmc+CiAgPGtleT5wMi1pbi1hcHAtY2hlY2stcmVjdXJyaW5nLWRvd25sb2FkLXF1ZXVlPC9rZXk+PHN0cmluZz5odHRwczovL2J1eS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS9pbkFwcENoZWNrUmVjdXJyaW5nRG93bmxvYWRRdWV1ZTwvc3RyaW5nPgogIDxrZXk+cDItaW4tYXBwLXJlY3VycmluZy10cmFuc2FjdGlvbnM8L2tleT48c3RyaW5nPmh0dHBzOi8vYnV5Lml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL2luQXBwUmVjdXJyaW5nVHJhbnNhY3Rpb25zPC9zdHJpbmc+CiAgPGtleT5wMi1pbi1hcHAtdHJhbnNhY3Rpb24tZG9uZTwva2V5PjxzdHJpbmc+aHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2EvaW5BcHBUcmFuc2FjdGlvbkRvbmU8L3N0cmluZz4KICA8a2V5PnAyLWluLWFwcC1yZWdyYW50LXB1cmNoYXNlLWhpc3Rvcnk8L2tleT48c3RyaW5nPmh0dHBzOi8vYnV5Lml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL2luQXBwUmVncmFudFB1cmNoYXNlSGlzdG9yeTwvc3RyaW5nPgogIDxrZXk+Z2V0U2hhcmVJZGVudGlmaWVyczwva2V5PjxzdHJpbmc+aHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aSG9tZVNoYXJpbmcud29hL3dhL2dldFNoYXJlSWRlbnRpZmllcnM8L3N0cmluZz4KICA8a2V5PmFwcHJvdmVDb250ZW50VHJhbnNmZXI8L2tleT48c3RyaW5nPmh0dHBzOi8vYnV5Lml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkhvbWVTaGFyaW5nLndvYS93YS9hcHByb3ZlQ29udGVudFRyYW5zZmVyPC9zdHJpbmc+CiAgPGtleT5wZW5kaW5nQm9va3M8L2tleT48c3RyaW5nPmh0dHBzOi8vYnV5Lml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL3BlbmRpbmdCb29rczwvc3RyaW5nPgogIDxrZXk+Y2hlY2tCb29rUXVldWU8L2tleT48c3RyaW5nPmh0dHBzOi8vYnV5Lml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL2NoZWNrRUJvb2tEb3dubG9hZFF1ZXVlPC9zdHJpbmc+CiAgPGtleT5rdnMtZ2V0PC9rZXk+PHN0cmluZz5odHRwczovL2J1eS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpCb29ra2VlcGVyLndvYS93YS9nZXQ8L3N0cmluZz4KICA8a2V5Pmt2cy1nZXRhbGw8L2tleT48c3RyaW5nPmh0dHBzOi8vYnV5Lml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkJvb2trZWVwZXIud29hL3dhL2dldEFsbDwvc3RyaW5nPgogIDxrZXk+a3ZzLXB1dDwva2V5PjxzdHJpbmc+aHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aQm9va2tlZXBlci53b2Evd2EvcHV0PC9zdHJpbmc+CiAgPGtleT5rdnMtcHV0YWxsPC9rZXk+PHN0cmluZz5odHRwczovL2J1eS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpCb29ra2VlcGVyLndvYS93YS9wdXRBbGw8L3N0cmluZz4KICA8a2V5PmdldC1wbGF5LWluZm88L2tleT48c3RyaW5nPmh0dHBzOi8vYnV5Lml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL2dldFBsYXlJbmZvPC9zdHJpbmc+CiAgPGtleT5wdXNoLW5vdGlmaWNhdGlvbnM8L2tleT4KICA8ZGljdD4KICAgIDxrZXk+cmVnaXN0ZXItc3VjY2Vzczwva2V5PjxzdHJpbmc+aHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2EvcmVnaXN0ZXJTdWNjZXNzPC9zdHJpbmc+CiAgICA8a2V5PmVudmlyb25tZW50PC9rZXk+PHN0cmluZz5wcm9kdWN0aW9uPC9zdHJpbmc+CiAgPC9kaWN0PgogIDxrZXk+YXV0b21hdGljLWRvd25sb2FkczI8L2tleT4KICA8ZGljdD4KICAgIDxrZXk+ZG93bmxvYWRzLXVybDwva2V5PjxzdHJpbmc+aHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2EvZ2V0QXV0b0Rvd25sb2FkUXVldWU8L3N0cmluZz4KICAgIDxrZXk+cmVnaXN0ZXItbWVkaWEtdHlwZXM8L2tleT48c3RyaW5nPmh0dHBzOi8vYnV5Lml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL3JlZ2lzdGVyTWVkaWFUeXBlczwvc3RyaW5nPgogICAgPGtleT5jb25maWd1cmF0aW9uczwva2V5PgogICAgPGFycmF5PgogICAgICA8ZGljdD4KICAgICAgICA8a2V5Pm1lZGlhLXR5cGVzPC9rZXk+CiAgICAgICAgPGFycmF5PgogICAgICAgICAgPHN0cmluZz5zb25nPC9zdHJpbmc+CiAgICAgICAgICA8c3RyaW5nPm11c2ljLXZpZGVvPC9zdHJpbmc+CiAgICAgICAgPC9hcnJheT4KICAgICAgICA8a2V5PmNhbm9uaWNhbC1uYW1lPC9rZXk+PHN0cmluZz5BVVRPX0RPV05MT0FEX01VU0lDPC9zdHJpbmc+CiAgICAgIDwvZGljdD4KICAgICAgPGRpY3Q+CiAgICAgICAgPGtleT5tZWRpYS10eXBlczwva2V5PgogICAgICAgIDxhcnJheT4KICAgICAgICAgIDxzdHJpbmc+c29mdHdhcmU8L3N0cmluZz4KICAgICAgICA8L2FycmF5PgogICAgICAgIDxrZXk+Y2Fub25pY2FsLW5hbWU8L2tleT48c3RyaW5nPkFVVE9fRE9XTkxPQURfQVBQUzwvc3RyaW5nPgogICAgICA8L2RpY3Q+CiAgICAgIDxkaWN0PgogICAgICAgIDxrZXk+bWVkaWEtdHlwZXM8L2tleT4KICAgICAgICA8YXJyYXk+CiAgICAgICAgICA8c3RyaW5nPmVib29rPC9zdHJpbmc+CiAgICAgICAgPC9hcnJheT4KICAgICAgICA8a2V5PmNhbm9uaWNhbC1uYW1lPC9rZXk+PHN0cmluZz5BVVRPX0RPV05MT0FEX0JPT0tTPC9zdHJpbmc+CiAgICAgIDwvZGljdD4KICAgIDwvYXJyYXk+CiAgPC9kaWN0PgogIDxrZXk+ZW5hYmxlZC1tZWRpYS10eXBlczwva2V5PjxzdHJpbmc+aHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2EvZW5hYmxlZE1lZGlhVHlwZXM8L3N0cmluZz4KICA8a2V5PnAyLWNvbnRlbnQtcmVzdG9yZTwva2V5PgogIDxkaWN0PgogICAgPGtleT5nemlwPC9rZXk+PGZhbHNlLz4KICAgIDxrZXk+bWF4LWl0ZW0tY291bnQ8L2tleT48aW50ZWdlcj41MDwvaW50ZWdlcj4KICAgIDxrZXk+dXJsPC9rZXk+PHN0cmluZz5odHRwczovL2J1eS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS9jb250ZW50UmVzdG9yZTwvc3RyaW5nPgogICAgPGtleT5hbGxvd2VkLWtpbmRzPC9rZXk+CiAgICA8YXJyYXk+CiAgICAgIDxzdHJpbmc+c29uZzwvc3RyaW5nPgogICAgICA8c3RyaW5nPm11c2ljLXZpZGVvPC9zdHJpbmc+CiAgICAgIDxzdHJpbmc+c29mdHdhcmU8L3N0cmluZz4KICAgICAgPHN0cmluZz5lYm9vazwvc3RyaW5nPgogICAgPC9hcnJheT4KICA8L2RpY3Q+CiAgPGtleT5wcmVmbGlnaHQtbG9va3VwPC9rZXk+PHN0cmluZz5odHRwczovL2J1eS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS9nZXRQcmVmbGlnaHQ8L3N0cmluZz4KICA8a2V5PmJ1bmRsZS1vd25zLWNoZWNrPC9rZXk+PHN0cmluZz5odHRwczovL2J1eS5pdHVuZXMuYXBwbGUuY29tL1dlYk9iamVjdHMvTVpGaW5hbmNlLndvYS93YS9vd25zQ2hlY2s8L3N0cmluZz4KICA8a2V5PnJlY292ZXJ5LWJ1eTwva2V5PjxzdHJpbmc+aHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS9XZWJPYmplY3RzL01aRmluYW5jZS53b2Evd2EvcmVjb3ZlcnlCdXk8L3N0cmluZz4KICA8a2V5PmFkb3B0LXByb2R1Y3Q8L2tleT48c3RyaW5nPmh0dHBzOi8vYnV5Lml0dW5lcy5hcHBsZS5jb20vV2ViT2JqZWN0cy9NWkZpbmFuY2Uud29hL3dhL2Fkb3B0UHJvZHVjdDwvc3RyaW5nPgo8L2RpY3Q+CjwvcGxpc3Q+Cg==</data>"
+"</dict>"
+"</plist>"
+;
+
+/* Test basic add delete update copy matching stuff. */
+static void tests(void)
+{
+    SecTrustRef trust;
+    SecCertificateRef leaf, root;
+    SecPolicyRef policy;
+    CFDataRef urlBagData;
+       CFDictionaryRef urlBagDict;
+
+    isnt(urlBagData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, url_bag, sizeof(url_bag), kCFAllocatorNull), NULL,
+               "load url bag");
+    isnt(urlBagDict = CFPropertyListCreateWithData(kCFAllocatorDefault, urlBagData, kCFPropertyListImmutable, NULL, NULL), NULL,
+               "parse url bag");
+       CFReleaseSafe(urlBagData);
+    CFArrayRef certs_data = CFDictionaryGetValue(urlBagDict, CFSTR("certs"));
+    CFDataRef cert_data = CFArrayGetValueAtIndex(certs_data, 0);
+    isnt(leaf = SecCertificateCreateWithData(kCFAllocatorDefault, cert_data), NULL, "create leaf");
+    isnt(root = SecCertificateCreateWithBytes(kCFAllocatorDefault, sITunesStoreRootCertificate, sizeof(sITunesStoreRootCertificate)), NULL, "create root");
+
+    CFArrayRef certs = CFArrayCreate(kCFAllocatorDefault, (const void **)&leaf, 1, NULL);
+    CFArrayRef anchors = CFArrayCreate(kCFAllocatorDefault, (const void **)&root, 1, NULL);
+    CFDataRef signature = CFDictionaryGetValue(urlBagDict, CFSTR("signature"));
+       CFDataRef bag = CFDictionaryGetValue(urlBagDict, CFSTR("bag"));
+    unsigned char sha1_hash[CC_SHA1_DIGEST_LENGTH];
+    CCDigest(kCCDigestSHA1, CFDataGetBytePtr(bag), CFDataGetLength(bag), sha1_hash);
+
+    isnt(policy = SecPolicyCreateiTunesStoreURLBag(), NULL, "create policy instance");
+
+    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust for leaf");
+    ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set iTMS anchor for evaluation");
+
+    /* it'll have just expired */
+    CFTimeZoneRef tz = CFTimeZoneCreateWithName(NULL, CFSTR("GMT"), true);
+    CFGregorianDate date_check = { 2008, 11, 7, 22, 0, 0 };
+    CFAbsoluteTime atime = CFGregorianDateGetAbsoluteTime(date_check, tz);
+    CFRelease(tz);
+    CFDateRef date = CFDateCreate(NULL, atime);
+    ok_status(SecTrustSetVerifyDate(trust, date), "set date");
+    CFReleaseSafe(date);
+
+    SecTrustResultType trustResult;
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultUnspecified,
+               "trust is kSecTrustResultUnspecified");
+    is(SecTrustGetCertificateCount(trust), 2, "cert count is 2");
+       SecKeyRef pub_key_leaf;
+       isnt(pub_key_leaf = SecTrustCopyPublicKey(trust), NULL, "get leaf pub key");
+       ok_status(SecKeyRawVerify(pub_key_leaf, kSecPaddingPKCS1SHA1, sha1_hash, sizeof(sha1_hash), CFDataGetBytePtr(signature), CFDataGetLength(signature)),
+               "verify signature on bag");
+
+    CFReleaseSafe(pub_key_leaf);
+       CFReleaseSafe(urlBagDict);
+    CFReleaseSafe(certs);
+    CFReleaseSafe(anchors);
+    CFReleaseSafe(trust);
+    CFReleaseSafe(policy);
+    CFReleaseSafe(leaf);
+    CFReleaseSafe(root);
+}
+
+int si_24_sectrust_itms(int argc, char *const *argv)
+{
+    plan_tests(13);
+
+
+    tests();
+#ifdef NO_SERVER
+# if NDEBUG
+# else
+# endif
+#else
+#endif
+
+    return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-24-sectrust-mobileasset.c b/sec/Security/Regressions/secitem/si-24-sectrust-mobileasset.c
new file mode 100644 (file)
index 0000000..d0dab9b
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2011 Apple Inc. All Rights Reserved.
+ */
+
+#include <Security/SecPolicyPriv.h>
+#include <Security/SecInternal.h>
+
+#include <test/testpolicy.h>
+
+#include "Security_regressions.h"
+
+static void tests(void)
+{
+    SecPolicyRef otaPolicy = SecPolicyCreateMobileAsset();
+
+    /* Run the tests. */
+    runCertificateTestForDirectory(otaPolicy, CFSTR("mobileasset-certs"), NULL);
+
+    CFReleaseSafe(otaPolicy);
+}
+
+int si_24_sectrust_mobileasset(int argc, char *const *argv)
+{
+       plan_tests(2);
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-24-sectrust-nist.c b/sec/Security/Regressions/secitem/si-24-sectrust-nist.c
new file mode 100644 (file)
index 0000000..55f38c4
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2011 Apple Inc. All Rights Reserved.
+ */
+
+#include <Security/SecPolicyPriv.h>
+#include <Security/SecInternal.h>
+
+#include <test/testpolicy.h>
+
+#include "Security_regressions.h"
+
+static void tests(void)
+{
+    SecPolicyRef basicPolicy = SecPolicyCreateBasicX509();
+
+    /* Run the tests. */
+    runCertificateTestForDirectory(basicPolicy, CFSTR("nist-certs"), NULL);
+
+    CFReleaseSafe(basicPolicy);
+}
+
+int si_24_sectrust_nist(int argc, char *const *argv)
+{
+       plan_tests(179);
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-24-sectrust-otatasking.c b/sec/Security/Regressions/secitem/si-24-sectrust-otatasking.c
new file mode 100644 (file)
index 0000000..26247af
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2011 Apple Inc. All Rights Reserved.
+ */
+
+#include <Security/SecPolicyPriv.h>
+#include <Security/SecInternal.h>
+
+#include <test/testpolicy.h>
+
+#include "Security_regressions.h"
+
+static void tests(void)
+{
+    SecPolicyRef otaPolicy = SecPolicyCreateOTATasking();
+
+    /* Run the tests. */
+    runCertificateTestForDirectory(otaPolicy, CFSTR("OTATasking-certs"), NULL);
+
+    CFReleaseSafe(otaPolicy);
+}
+
+int si_24_sectrust_otatasking(int argc, char *const *argv)
+{
+       plan_tests(2);
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-24-sectrust-shoebox.c b/sec/Security/Regressions/secitem/si-24-sectrust-shoebox.c
new file mode 100644 (file)
index 0000000..5e887ee
--- /dev/null
@@ -0,0 +1,965 @@
+/*
+ * Copyright (c) 2011-2012 Apple Inc. All Rights Reserved.
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecPolicyPriv.h>
+#include <Security/SecTrustPriv.h>
+#include <Security/SecCMS.h>
+#include <Security/SecInternal.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <test/testpolicy.h>
+#include "Security_regressions.h"
+
+/* subject:/C=US/O=Apple Inc./OU=Apple Worldwide Developer Relations/CN=Apple Worldwide Developer Relations Certification Authority */
+/* issuer :/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Root CA */
+static const unsigned char _wwdrca[]={
+0x30,0x82,0x04,0x23,0x30,0x82,0x03,0x0B,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x19,
+0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,
+0x62,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,
+0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x13,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,
+0x6E,0x63,0x2E,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0B,0x13,0x1D,0x41,0x70,
+0x70,0x6C,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,
+0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x31,0x16,0x30,0x14,0x06,
+0x03,0x55,0x04,0x03,0x13,0x0D,0x41,0x70,0x70,0x6C,0x65,0x20,0x52,0x6F,0x6F,0x74,
+0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x30,0x38,0x30,0x32,0x31,0x34,0x31,0x38,0x35,
+0x36,0x33,0x35,0x5A,0x17,0x0D,0x31,0x36,0x30,0x32,0x31,0x34,0x31,0x38,0x35,0x36,
+0x33,0x35,0x5A,0x30,0x81,0x96,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,
+0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0A,0x41,0x70,
+0x70,0x6C,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x2C,0x30,0x2A,0x06,0x03,0x55,0x04,
+0x0B,0x0C,0x23,0x41,0x70,0x70,0x6C,0x65,0x20,0x57,0x6F,0x72,0x6C,0x64,0x77,0x69,
+0x64,0x65,0x20,0x44,0x65,0x76,0x65,0x6C,0x6F,0x70,0x65,0x72,0x20,0x52,0x65,0x6C,
+0x61,0x74,0x69,0x6F,0x6E,0x73,0x31,0x44,0x30,0x42,0x06,0x03,0x55,0x04,0x03,0x0C,
+0x3B,0x41,0x70,0x70,0x6C,0x65,0x20,0x57,0x6F,0x72,0x6C,0x64,0x77,0x69,0x64,0x65,
+0x20,0x44,0x65,0x76,0x65,0x6C,0x6F,0x70,0x65,0x72,0x20,0x52,0x65,0x6C,0x61,0x74,
+0x69,0x6F,0x6E,0x73,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,
+0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x82,0x01,0x22,
+0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,
+0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xCA,0x38,0x54,
+0xA6,0xCB,0x56,0xAA,0xC8,0x24,0x39,0x48,0xE9,0x8C,0xEE,0xEC,0x5F,0xB8,0x7F,0x26,
+0x91,0xBC,0x34,0x53,0x7A,0xCE,0x7C,0x63,0x80,0x61,0x77,0x64,0x5E,0xA5,0x07,0x23,
+0xB6,0x39,0xFE,0x50,0x2D,0x15,0x56,0x58,0x70,0x2D,0x7E,0xC4,0x6E,0xC1,0x4A,0x85,
+0x3E,0x2F,0xF0,0xDE,0x84,0x1A,0xA1,0x57,0xC9,0xAF,0x7B,0x18,0xFF,0x6A,0xFA,0x15,
+0x12,0x49,0x15,0x08,0x19,0xAC,0xAA,0xDB,0x2A,0x32,0xED,0x96,0x63,0x68,0x52,0x15,
+0x3D,0x8C,0x8A,0xEC,0xBF,0x6B,0x18,0x95,0xE0,0x03,0xAC,0x01,0x7D,0x97,0x05,0x67,
+0xCE,0x0E,0x85,0x95,0x37,0x6A,0xED,0x09,0xB6,0xAE,0x67,0xCD,0x51,0x64,0x9F,0xC6,
+0x5C,0xD1,0xBC,0x57,0x6E,0x67,0x35,0x80,0x76,0x36,0xA4,0x87,0x81,0x6E,0x38,0x8F,
+0xD8,0x2B,0x15,0x4E,0x7B,0x25,0xD8,0x5A,0xBF,0x4E,0x83,0xC1,0x8D,0xD2,0x93,0xD5,
+0x1A,0x71,0xB5,0x60,0x9C,0x9D,0x33,0x4E,0x55,0xF9,0x12,0x58,0x0C,0x86,0xB8,0x16,
+0x0D,0xC1,0xE5,0x77,0x45,0x8D,0x50,0x48,0xBA,0x2B,0x2D,0xE4,0x94,0x85,0xE1,0xE8,
+0xC4,0x9D,0xC6,0x68,0xA5,0xB0,0xA3,0xFC,0x67,0x7E,0x70,0xBA,0x02,0x59,0x4B,0x77,
+0x42,0x91,0x39,0xB9,0xF5,0xCD,0xE1,0x4C,0xEF,0xC0,0x3B,0x48,0x8C,0xA6,0xE5,0x21,
+0x5D,0xFD,0x6A,0x6A,0xBB,0xA7,0x16,0x35,0x60,0xD2,0xE6,0xAD,0xF3,0x46,0x29,0xC9,
+0xE8,0xC3,0x8B,0xE9,0x79,0xC0,0x6A,0x61,0x67,0x15,0xB2,0xF0,0xFD,0xE5,0x68,0xBC,
+0x62,0x5F,0x6E,0xCF,0x99,0xDD,0xEF,0x1B,0x63,0xFE,0x92,0x65,0xAB,0x02,0x03,0x01,
+0x00,0x01,0xA3,0x81,0xAE,0x30,0x81,0xAB,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,
+0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x86,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,
+0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,
+0x04,0x16,0x04,0x14,0x88,0x27,0x17,0x09,0xA9,0xB6,0x18,0x60,0x8B,0xEC,0xEB,0xBA,
+0xF6,0x47,0x59,0xC5,0x52,0x54,0xA3,0xB7,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,
+0x18,0x30,0x16,0x80,0x14,0x2B,0xD0,0x69,0x47,0x94,0x76,0x09,0xFE,0xF4,0x6B,0x8D,
+0x2E,0x40,0xA6,0xF7,0x47,0x4D,0x7F,0x08,0x5E,0x30,0x36,0x06,0x03,0x55,0x1D,0x1F,
+0x04,0x2F,0x30,0x2D,0x30,0x2B,0xA0,0x29,0xA0,0x27,0x86,0x25,0x68,0x74,0x74,0x70,
+0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,
+0x2F,0x61,0x70,0x70,0x6C,0x65,0x63,0x61,0x2F,0x72,0x6F,0x6F,0x74,0x2E,0x63,0x72,
+0x6C,0x30,0x10,0x06,0x0A,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,0x06,0x02,0x01,0x04,
+0x02,0x05,0x00,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,
+0x05,0x00,0x03,0x82,0x01,0x01,0x00,0xDA,0x32,0x00,0x96,0xC5,0x54,0x94,0xD3,0x3B,
+0x82,0x37,0x66,0x7D,0x2E,0x68,0xD5,0xC3,0xC6,0xB8,0xCB,0x26,0x8C,0x48,0x90,0xCF,
+0x13,0x24,0x6A,0x46,0x8E,0x63,0xD4,0xF0,0xD0,0x13,0x06,0xDD,0xD8,0xC4,0xC1,0x37,
+0x15,0xF2,0x33,0x13,0x39,0x26,0x2D,0xCE,0x2E,0x55,0x40,0xE3,0x0B,0x03,0xAF,0xFA,
+0x12,0xC2,0xE7,0x0D,0x21,0xB8,0xD5,0x80,0xCF,0xAC,0x28,0x2F,0xCE,0x2D,0xB3,0x4E,
+0xAF,0x86,0x19,0x04,0xC6,0xE9,0x50,0xDD,0x4C,0x29,0x47,0x10,0x23,0xFC,0x6C,0xBB,
+0x1B,0x98,0x6B,0x48,0x89,0xE1,0x5B,0x9D,0xDE,0x46,0xDB,0x35,0x85,0x35,0xEF,0x3E,
+0xD0,0xE2,0x58,0x4B,0x38,0xF4,0xED,0x75,0x5A,0x1F,0x5C,0x70,0x1D,0x56,0x39,0x12,
+0xE5,0xE1,0x0D,0x11,0xE4,0x89,0x25,0x06,0xBD,0xD5,0xB4,0x15,0x8E,0x5E,0xD0,0x59,
+0x97,0x90,0xE9,0x4B,0x81,0xE2,0xDF,0x18,0xAF,0x44,0x74,0x1E,0x19,0xA0,0x3A,0x47,
+0xCC,0x91,0x1D,0x3A,0xEB,0x23,0x5A,0xFE,0xA5,0x2D,0x97,0xF7,0x7B,0xBB,0xD6,0x87,
+0x46,0x42,0x85,0xEB,0x52,0x3D,0x26,0xB2,0x63,0xA8,0xB4,0xB1,0xCA,0x8F,0xF4,0xCC,
+0xE2,0xB3,0xC8,0x47,0xE0,0xBF,0x9A,0x59,0x83,0xFA,0xDA,0x98,0x53,0x2A,0x82,0xF5,
+0x7C,0x65,0x2E,0x95,0xD9,0x33,0x5D,0xF5,0xED,0x65,0xCC,0x31,0x37,0xC5,0x5A,0x04,
+0xE8,0x6B,0xE1,0xE7,0x88,0x03,0x4A,0x75,0x9E,0x9B,0x28,0xCB,0x4A,0x40,0x88,0x65,
+0x43,0x75,0xDD,0xCB,0x3A,0x25,0x23,0xC5,0x9E,0x57,0xF8,0x2E,0xCE,0xD2,0xA9,0x92,
+0x5E,0x73,0x2E,0x2F,0x25,0x75,0x15,
+};
+
+/* subject:/UID=pass.com.apple.cardman/CN=Pass Type ID: pass.com.apple.cardman/OU=A1B2C3D4E5/O=Apple Internal Use Only/C=US */
+/* issuer :/C=US/O=Apple Inc./OU=Apple Worldwide Developer Relations/CN=Apple Worldwide Developer Relations Certification Authority */
+static const unsigned char _leaf[]={
+0x30,0x82,0x05,0xF1,0x30,0x82,0x04,0xD9,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x29,
+0xD6,0x12,0x53,0x17,0x20,0x2D,0x6A,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,
+0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81,0x96,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,
+0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x0C,
+0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x2C,0x30,0x2A,0x06,
+0x03,0x55,0x04,0x0B,0x0C,0x23,0x41,0x70,0x70,0x6C,0x65,0x20,0x57,0x6F,0x72,0x6C,
+0x64,0x77,0x69,0x64,0x65,0x20,0x44,0x65,0x76,0x65,0x6C,0x6F,0x70,0x65,0x72,0x20,
+0x52,0x65,0x6C,0x61,0x74,0x69,0x6F,0x6E,0x73,0x31,0x44,0x30,0x42,0x06,0x03,0x55,
+0x04,0x03,0x0C,0x3B,0x41,0x70,0x70,0x6C,0x65,0x20,0x57,0x6F,0x72,0x6C,0x64,0x77,
+0x69,0x64,0x65,0x20,0x44,0x65,0x76,0x65,0x6C,0x6F,0x70,0x65,0x72,0x20,0x52,0x65,
+0x6C,0x61,0x74,0x69,0x6F,0x6E,0x73,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,
+0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,
+0x1E,0x17,0x0D,0x31,0x32,0x30,0x35,0x33,0x30,0x32,0x33,0x32,0x30,0x31,0x30,0x5A,
+0x17,0x0D,0x31,0x33,0x30,0x35,0x33,0x30,0x32,0x33,0x32,0x30,0x31,0x30,0x5A,0x30,
+0x81,0x9B,0x31,0x26,0x30,0x24,0x06,0x0A,0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,
+0x01,0x01,0x0C,0x16,0x70,0x61,0x73,0x73,0x2E,0x63,0x6F,0x6D,0x2E,0x61,0x70,0x70,
+0x6C,0x65,0x2E,0x63,0x61,0x72,0x64,0x6D,0x61,0x6E,0x31,0x2D,0x30,0x2B,0x06,0x03,
+0x55,0x04,0x03,0x0C,0x24,0x50,0x61,0x73,0x73,0x20,0x54,0x79,0x70,0x65,0x20,0x49,
+0x44,0x3A,0x20,0x70,0x61,0x73,0x73,0x2E,0x63,0x6F,0x6D,0x2E,0x61,0x70,0x70,0x6C,
+0x65,0x2E,0x63,0x61,0x72,0x64,0x6D,0x61,0x6E,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
+0x04,0x0B,0x0C,0x0A,0x41,0x31,0x42,0x32,0x43,0x33,0x44,0x34,0x45,0x35,0x31,0x20,
+0x30,0x1E,0x06,0x03,0x55,0x04,0x0A,0x0C,0x17,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,
+0x6E,0x74,0x65,0x72,0x6E,0x61,0x6C,0x20,0x55,0x73,0x65,0x20,0x4F,0x6E,0x6C,0x79,
+0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x30,0x82,0x01,
+0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,
+0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xBB,0x6C,
+0x6C,0xD4,0xCD,0x0B,0xD9,0x47,0x49,0xE1,0xA3,0xFE,0x73,0xE0,0x15,0xA6,0x2E,0x35,
+0xC8,0xB7,0xCD,0xAB,0x5E,0xD3,0x87,0x8A,0x94,0x8F,0x4D,0x94,0x52,0x72,0x27,0x57,
+0xB8,0xF5,0xA8,0xE2,0xF2,0xB0,0x46,0xAD,0xB9,0x30,0x9B,0x6A,0xD7,0x0A,0xFF,0x0E,
+0x5E,0x78,0x4C,0x97,0x17,0x16,0xA7,0x03,0xE1,0x13,0xE7,0x97,0x72,0x24,0xC8,0x7F,
+0x80,0x91,0xD2,0x45,0xA3,0xF8,0x21,0xCE,0x2D,0xFA,0xE4,0x3A,0x5E,0x04,0x30,0xE9,
+0x48,0xCA,0x32,0xCE,0x52,0x4C,0xCF,0x14,0xF9,0x04,0x58,0x30,0x4A,0xF8,0x49,0xBB,
+0x39,0x18,0x5C,0x4B,0x28,0x9E,0x14,0x16,0x23,0x73,0x6E,0x0D,0xCD,0xCD,0xEF,0x98,
+0xE7,0x90,0x04,0x0E,0x4A,0xC8,0x16,0x22,0x76,0x68,0xC6,0xDF,0x5D,0x20,0xA7,0x49,
+0x2E,0x55,0x9E,0x50,0x31,0x56,0x50,0x29,0xF9,0x56,0x09,0x38,0x32,0x25,0x1B,0x3A,
+0x1C,0x97,0x3E,0x04,0xEE,0x69,0x3C,0x68,0x44,0x54,0x51,0x27,0x75,0x70,0xA2,0x33,
+0x86,0x7A,0x9D,0x71,0xC0,0x18,0x2E,0x37,0xB5,0x47,0x8D,0xBE,0x57,0xB6,0xAA,0xDA,
+0x1D,0xE8,0x78,0x23,0x66,0xC8,0x6C,0xE3,0x7E,0xFD,0xDE,0x6B,0x70,0x2F,0x76,0x1D,
+0xA6,0x2B,0x97,0xEE,0xAD,0x5B,0x8B,0x8E,0x00,0x87,0x27,0xDF,0x16,0x54,0x08,0x97,
+0x18,0x23,0x31,0x2C,0xF5,0x9D,0x41,0xD5,0xBB,0x60,0x23,0x92,0x3D,0xCC,0x9E,0x2D,
+0xFF,0xA5,0x8B,0xE0,0xF9,0x65,0xDC,0x94,0x58,0xB0,0x9D,0x73,0x05,0x05,0x21,0xA1,
+0xB3,0x37,0xA4,0x8F,0x5D,0xDA,0xCE,0x9C,0xF6,0x63,0x9B,0x6B,0x9F,0x77,0x02,0x03,
+0x01,0x00,0x01,0xA3,0x82,0x02,0x3A,0x30,0x82,0x02,0x36,0x30,0x3D,0x06,0x08,0x2B,
+0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x31,0x30,0x2F,0x30,0x2D,0x06,0x08,0x2B,
+0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x21,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,
+0x6F,0x63,0x73,0x70,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x2F,0x6F,
+0x63,0x73,0x70,0x2D,0x77,0x77,0x64,0x72,0x30,0x33,0x30,0x1D,0x06,0x03,0x55,0x1D,
+0x0E,0x04,0x16,0x04,0x14,0x9B,0xC2,0x61,0x59,0x72,0x23,0xB6,0x5F,0x91,0x0F,0x04,
+0x87,0x92,0xF9,0xA4,0xF3,0x6B,0xE9,0xBE,0xAB,0x30,0x09,0x06,0x03,0x55,0x1D,0x13,
+0x04,0x02,0x30,0x00,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,
+0x14,0x88,0x27,0x17,0x09,0xA9,0xB6,0x18,0x60,0x8B,0xEC,0xEB,0xBA,0xF6,0x47,0x59,
+0xC5,0x52,0x54,0xA3,0xB7,0x30,0x82,0x01,0x0F,0x06,0x03,0x55,0x1D,0x20,0x04,0x82,
+0x01,0x06,0x30,0x82,0x01,0x02,0x30,0x81,0xFF,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,
+0x63,0x64,0x05,0x01,0x30,0x81,0xF1,0x30,0x29,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,
+0x07,0x02,0x01,0x16,0x1D,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,
+0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x2F,0x61,0x70,0x70,0x6C,0x65,0x63,
+0x61,0x2F,0x30,0x81,0xC3,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x02,0x30,
+0x81,0xB6,0x0C,0x81,0xB3,0x52,0x65,0x6C,0x69,0x61,0x6E,0x63,0x65,0x20,0x6F,0x6E,
+0x20,0x74,0x68,0x69,0x73,0x20,0x63,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,
+0x65,0x20,0x62,0x79,0x20,0x61,0x6E,0x79,0x20,0x70,0x61,0x72,0x74,0x79,0x20,0x61,
+0x73,0x73,0x75,0x6D,0x65,0x73,0x20,0x61,0x63,0x63,0x65,0x70,0x74,0x61,0x6E,0x63,
+0x65,0x20,0x6F,0x66,0x20,0x74,0x68,0x65,0x20,0x74,0x68,0x65,0x6E,0x20,0x61,0x70,
+0x70,0x6C,0x69,0x63,0x61,0x62,0x6C,0x65,0x20,0x73,0x74,0x61,0x6E,0x64,0x61,0x72,
+0x64,0x20,0x74,0x65,0x72,0x6D,0x73,0x20,0x61,0x6E,0x64,0x20,0x63,0x6F,0x6E,0x64,
+0x69,0x74,0x69,0x6F,0x6E,0x73,0x20,0x6F,0x66,0x20,0x75,0x73,0x65,0x2C,0x20,0x63,
+0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x70,0x6F,0x6C,0x69,0x63,
+0x79,0x20,0x61,0x6E,0x64,0x20,0x63,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,
+0x69,0x6F,0x6E,0x20,0x70,0x72,0x61,0x63,0x74,0x69,0x63,0x65,0x20,0x73,0x74,0x61,
+0x74,0x65,0x6D,0x65,0x6E,0x74,0x73,0x2E,0x30,0x30,0x06,0x03,0x55,0x1D,0x1F,0x04,
+0x29,0x30,0x27,0x30,0x25,0xA0,0x23,0xA0,0x21,0x86,0x1F,0x68,0x74,0x74,0x70,0x3A,
+0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x2F,
+0x77,0x77,0x64,0x72,0x63,0x61,0x2E,0x63,0x72,0x6C,0x30,0x0B,0x06,0x03,0x55,0x1D,
+0x0F,0x04,0x04,0x03,0x02,0x07,0x80,0x30,0x1E,0x06,0x03,0x55,0x1D,0x25,0x04,0x17,
+0x30,0x15,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x09,0x2A,0x86,
+0x48,0x86,0xF7,0x63,0x64,0x04,0x0E,0x30,0x10,0x06,0x0A,0x2A,0x86,0x48,0x86,0xF7,
+0x63,0x64,0x06,0x03,0x02,0x04,0x02,0x05,0x00,0x30,0x26,0x06,0x0A,0x2A,0x86,0x48,
+0x86,0xF7,0x63,0x64,0x06,0x01,0x10,0x04,0x18,0x0C,0x16,0x70,0x61,0x73,0x73,0x2E,
+0x63,0x6F,0x6D,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x61,0x72,0x64,0x6D,0x61,
+0x6E,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,
+0x03,0x82,0x01,0x01,0x00,0x9B,0xEF,0x1E,0xFF,0xEE,0xD5,0xFD,0x71,0x1A,0xF5,0x17,
+0xFE,0x05,0xBA,0x30,0xFC,0xBD,0x6D,0x01,0xB0,0x0B,0x78,0x41,0x4B,0x76,0x71,0xD1,
+0x8C,0xF0,0xCD,0xED,0xD9,0xAA,0xEC,0xAD,0x1D,0x4A,0x2D,0xCC,0x00,0x11,0x5B,0x1D,
+0xD9,0xEF,0x08,0xA2,0x3D,0xEA,0xE9,0xBD,0x35,0x0B,0x1C,0x9F,0xE7,0xEB,0xC9,0xC9,
+0xEA,0x99,0xCC,0x77,0x27,0xB9,0x01,0x09,0x72,0x40,0xBA,0xD4,0x26,0x54,0x8F,0x30,
+0x84,0x7E,0x03,0x65,0xDA,0x08,0xB2,0x92,0xEE,0x61,0x4E,0x5F,0x00,0x39,0x48,0x2D,
+0x99,0x83,0xB5,0xC4,0x33,0xB2,0xF7,0x62,0xCF,0x6A,0xBF,0xBB,0xB8,0x40,0x70,0xBF,
+0x11,0xFF,0x7F,0xC1,0xC1,0x8D,0x1D,0x67,0x6C,0x87,0x02,0xE2,0x93,0x17,0x16,0xC3,
+0xEC,0x5E,0x97,0xE4,0xDD,0x12,0xCC,0xB2,0xDD,0x91,0x51,0xA8,0x32,0x25,0x6D,0xF7,
+0x55,0xB7,0x4A,0x8E,0x6B,0x90,0xCB,0x0F,0x4C,0x93,0x87,0x2A,0xD9,0x31,0xB8,0x1A,
+0x16,0x12,0xBB,0x6E,0xFC,0xB0,0xAE,0xFB,0x93,0x76,0x63,0x37,0xB7,0x36,0x13,0x11,
+0xC5,0x53,0x45,0xE0,0x0D,0xFF,0xAF,0x05,0x5F,0x67,0x51,0xE1,0x54,0x29,0xA2,0x1A,
+0x7C,0x61,0xE0,0xC2,0xCD,0xAC,0xBE,0xEE,0xA6,0x4A,0xDC,0x92,0x95,0x48,0x41,0x2F,
+0x37,0xC0,0x64,0x05,0xAA,0x4F,0x05,0xEE,0xE0,0x3F,0xA0,0x9F,0x43,0x6C,0xCC,0xD5,
+0x97,0x64,0x6D,0x15,0x5B,0xB6,0xCD,0x2A,0xBC,0x18,0xDE,0xC7,0x94,0x80,0x2D,0x2B,
+0x81,0x14,0xFC,0x48,0xF7,0xDF,0xCE,0x94,0xB3,0xFD,0xF5,0x7E,0x42,0x4D,0x33,0x58,
+0x4D,0x7A,0x62,0x2E,0x61,
+};
+
+static const unsigned char _USAirwaysCorrect_signature[] = {
+    0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07,
+    0x02, 0xa0, 0x80, 0x30, 0x80, 0x02, 0x01, 0x01, 0x31, 0x0b, 0x30, 0x09,
+    0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x30, 0x80, 0x06,
+    0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x00, 0x00,
+    0xa0, 0x82, 0x0a, 0x1c, 0x30, 0x82, 0x04, 0x23, 0x30, 0x82, 0x03, 0x0b,
+    0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x19, 0x30, 0x0d, 0x06, 0x09,
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
+    0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+    0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+    0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
+    0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70,
+    0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+    0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+    0x69, 0x74, 0x79, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03,
+    0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74,
+    0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x38, 0x30, 0x32, 0x31,
+    0x34, 0x31, 0x38, 0x35, 0x36, 0x33, 0x35, 0x5a, 0x17, 0x0d, 0x31, 0x36,
+    0x30, 0x32, 0x31, 0x34, 0x31, 0x38, 0x35, 0x36, 0x33, 0x35, 0x5a, 0x30,
+    0x81, 0x96, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+    0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
+    0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+    0x31, 0x2c, 0x30, 0x2a, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x23, 0x41,
+    0x70, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x77, 0x69,
+    0x64, 0x65, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72,
+    0x20, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x31, 0x44,
+    0x30, 0x42, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x3b, 0x41, 0x70, 0x70,
+    0x6c, 0x65, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x77, 0x69, 0x64, 0x65,
+    0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x20, 0x52,
+    0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x43, 0x65, 0x72,
+    0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41,
+    0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x82, 0x01, 0x22,
+    0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+    0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
+    0x02, 0x82, 0x01, 0x01, 0x00, 0xca, 0x38, 0x54, 0xa6, 0xcb, 0x56, 0xaa,
+    0xc8, 0x24, 0x39, 0x48, 0xe9, 0x8c, 0xee, 0xec, 0x5f, 0xb8, 0x7f, 0x26,
+    0x91, 0xbc, 0x34, 0x53, 0x7a, 0xce, 0x7c, 0x63, 0x80, 0x61, 0x77, 0x64,
+    0x5e, 0xa5, 0x07, 0x23, 0xb6, 0x39, 0xfe, 0x50, 0x2d, 0x15, 0x56, 0x58,
+    0x70, 0x2d, 0x7e, 0xc4, 0x6e, 0xc1, 0x4a, 0x85, 0x3e, 0x2f, 0xf0, 0xde,
+    0x84, 0x1a, 0xa1, 0x57, 0xc9, 0xaf, 0x7b, 0x18, 0xff, 0x6a, 0xfa, 0x15,
+    0x12, 0x49, 0x15, 0x08, 0x19, 0xac, 0xaa, 0xdb, 0x2a, 0x32, 0xed, 0x96,
+    0x63, 0x68, 0x52, 0x15, 0x3d, 0x8c, 0x8a, 0xec, 0xbf, 0x6b, 0x18, 0x95,
+    0xe0, 0x03, 0xac, 0x01, 0x7d, 0x97, 0x05, 0x67, 0xce, 0x0e, 0x85, 0x95,
+    0x37, 0x6a, 0xed, 0x09, 0xb6, 0xae, 0x67, 0xcd, 0x51, 0x64, 0x9f, 0xc6,
+    0x5c, 0xd1, 0xbc, 0x57, 0x6e, 0x67, 0x35, 0x80, 0x76, 0x36, 0xa4, 0x87,
+    0x81, 0x6e, 0x38, 0x8f, 0xd8, 0x2b, 0x15, 0x4e, 0x7b, 0x25, 0xd8, 0x5a,
+    0xbf, 0x4e, 0x83, 0xc1, 0x8d, 0xd2, 0x93, 0xd5, 0x1a, 0x71, 0xb5, 0x60,
+    0x9c, 0x9d, 0x33, 0x4e, 0x55, 0xf9, 0x12, 0x58, 0x0c, 0x86, 0xb8, 0x16,
+    0x0d, 0xc1, 0xe5, 0x77, 0x45, 0x8d, 0x50, 0x48, 0xba, 0x2b, 0x2d, 0xe4,
+    0x94, 0x85, 0xe1, 0xe8, 0xc4, 0x9d, 0xc6, 0x68, 0xa5, 0xb0, 0xa3, 0xfc,
+    0x67, 0x7e, 0x70, 0xba, 0x02, 0x59, 0x4b, 0x77, 0x42, 0x91, 0x39, 0xb9,
+    0xf5, 0xcd, 0xe1, 0x4c, 0xef, 0xc0, 0x3b, 0x48, 0x8c, 0xa6, 0xe5, 0x21,
+    0x5d, 0xfd, 0x6a, 0x6a, 0xbb, 0xa7, 0x16, 0x35, 0x60, 0xd2, 0xe6, 0xad,
+    0xf3, 0x46, 0x29, 0xc9, 0xe8, 0xc3, 0x8b, 0xe9, 0x79, 0xc0, 0x6a, 0x61,
+    0x67, 0x15, 0xb2, 0xf0, 0xfd, 0xe5, 0x68, 0xbc, 0x62, 0x5f, 0x6e, 0xcf,
+    0x99, 0xdd, 0xef, 0x1b, 0x63, 0xfe, 0x92, 0x65, 0xab, 0x02, 0x03, 0x01,
+    0x00, 0x01, 0xa3, 0x81, 0xae, 0x30, 0x81, 0xab, 0x30, 0x0e, 0x06, 0x03,
+    0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86,
+    0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05,
+    0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
+    0x04, 0x16, 0x04, 0x14, 0x88, 0x27, 0x17, 0x09, 0xa9, 0xb6, 0x18, 0x60,
+    0x8b, 0xec, 0xeb, 0xba, 0xf6, 0x47, 0x59, 0xc5, 0x52, 0x54, 0xa3, 0xb7,
+    0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80,
+    0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76, 0x09, 0xfe, 0xf4, 0x6b, 0x8d,
+    0x2e, 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x36, 0x06,
+    0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2f, 0x30, 0x2d, 0x30, 0x2b, 0xa0, 0x29,
+    0xa0, 0x27, 0x86, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
+    0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
+    0x2f, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x63, 0x61, 0x2f, 0x72, 0x6f, 0x6f,
+    0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x10, 0x06, 0x0a, 0x2a, 0x86, 0x48,
+    0x86, 0xf7, 0x63, 0x64, 0x06, 0x02, 0x01, 0x04, 0x02, 0x05, 0x00, 0x30,
+    0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
+    0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xda, 0x32, 0x00, 0x96, 0xc5,
+    0x54, 0x94, 0xd3, 0x3b, 0x82, 0x37, 0x66, 0x7d, 0x2e, 0x68, 0xd5, 0xc3,
+    0xc6, 0xb8, 0xcb, 0x26, 0x8c, 0x48, 0x90, 0xcf, 0x13, 0x24, 0x6a, 0x46,
+    0x8e, 0x63, 0xd4, 0xf0, 0xd0, 0x13, 0x06, 0xdd, 0xd8, 0xc4, 0xc1, 0x37,
+    0x15, 0xf2, 0x33, 0x13, 0x39, 0x26, 0x2d, 0xce, 0x2e, 0x55, 0x40, 0xe3,
+    0x0b, 0x03, 0xaf, 0xfa, 0x12, 0xc2, 0xe7, 0x0d, 0x21, 0xb8, 0xd5, 0x80,
+    0xcf, 0xac, 0x28, 0x2f, 0xce, 0x2d, 0xb3, 0x4e, 0xaf, 0x86, 0x19, 0x04,
+    0xc6, 0xe9, 0x50, 0xdd, 0x4c, 0x29, 0x47, 0x10, 0x23, 0xfc, 0x6c, 0xbb,
+    0x1b, 0x98, 0x6b, 0x48, 0x89, 0xe1, 0x5b, 0x9d, 0xde, 0x46, 0xdb, 0x35,
+    0x85, 0x35, 0xef, 0x3e, 0xd0, 0xe2, 0x58, 0x4b, 0x38, 0xf4, 0xed, 0x75,
+    0x5a, 0x1f, 0x5c, 0x70, 0x1d, 0x56, 0x39, 0x12, 0xe5, 0xe1, 0x0d, 0x11,
+    0xe4, 0x89, 0x25, 0x06, 0xbd, 0xd5, 0xb4, 0x15, 0x8e, 0x5e, 0xd0, 0x59,
+    0x97, 0x90, 0xe9, 0x4b, 0x81, 0xe2, 0xdf, 0x18, 0xaf, 0x44, 0x74, 0x1e,
+    0x19, 0xa0, 0x3a, 0x47, 0xcc, 0x91, 0x1d, 0x3a, 0xeb, 0x23, 0x5a, 0xfe,
+    0xa5, 0x2d, 0x97, 0xf7, 0x7b, 0xbb, 0xd6, 0x87, 0x46, 0x42, 0x85, 0xeb,
+    0x52, 0x3d, 0x26, 0xb2, 0x63, 0xa8, 0xb4, 0xb1, 0xca, 0x8f, 0xf4, 0xcc,
+    0xe2, 0xb3, 0xc8, 0x47, 0xe0, 0xbf, 0x9a, 0x59, 0x83, 0xfa, 0xda, 0x98,
+    0x53, 0x2a, 0x82, 0xf5, 0x7c, 0x65, 0x2e, 0x95, 0xd9, 0x33, 0x5d, 0xf5,
+    0xed, 0x65, 0xcc, 0x31, 0x37, 0xc5, 0x5a, 0x04, 0xe8, 0x6b, 0xe1, 0xe7,
+    0x88, 0x03, 0x4a, 0x75, 0x9e, 0x9b, 0x28, 0xcb, 0x4a, 0x40, 0x88, 0x65,
+    0x43, 0x75, 0xdd, 0xcb, 0x3a, 0x25, 0x23, 0xc5, 0x9e, 0x57, 0xf8, 0x2e,
+    0xce, 0xd2, 0xa9, 0x92, 0x5e, 0x73, 0x2e, 0x2f, 0x25, 0x75, 0x15, 0x30,
+    0x82, 0x05, 0xf1, 0x30, 0x82, 0x04, 0xd9, 0xa0, 0x03, 0x02, 0x01, 0x02,
+    0x02, 0x08, 0x29, 0xd6, 0x12, 0x53, 0x17, 0x20, 0x2d, 0x6a, 0x30, 0x0d,
+    0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
+    0x00, 0x30, 0x81, 0x96, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
+    0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
+    0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e,
+    0x63, 0x2e, 0x31, 0x2c, 0x30, 0x2a, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c,
+    0x23, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64,
+    0x77, 0x69, 0x64, 0x65, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70,
+    0x65, 0x72, 0x20, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+    0x31, 0x44, 0x30, 0x42, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x3b, 0x41,
+    0x70, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x77, 0x69,
+    0x64, 0x65, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72,
+    0x20, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x43,
+    0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+    0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e,
+    0x17, 0x0d, 0x31, 0x32, 0x30, 0x35, 0x33, 0x30, 0x32, 0x33, 0x32, 0x30,
+    0x31, 0x30, 0x5a, 0x17, 0x0d, 0x31, 0x33, 0x30, 0x35, 0x33, 0x30, 0x32,
+    0x33, 0x32, 0x30, 0x31, 0x30, 0x5a, 0x30, 0x81, 0x9b, 0x31, 0x26, 0x30,
+    0x24, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01,
+    0x01, 0x0c, 0x16, 0x70, 0x61, 0x73, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2e,
+    0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x61, 0x72, 0x64, 0x6d, 0x61,
+    0x6e, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x24,
+    0x50, 0x61, 0x73, 0x73, 0x20, 0x54, 0x79, 0x70, 0x65, 0x20, 0x49, 0x44,
+    0x3a, 0x20, 0x70, 0x61, 0x73, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61,
+    0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x61, 0x72, 0x64, 0x6d, 0x61, 0x6e,
+    0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x0a, 0x41,
+    0x31, 0x42, 0x32, 0x43, 0x33, 0x44, 0x34, 0x45, 0x35, 0x31, 0x20, 0x30,
+    0x1e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x17, 0x41, 0x70, 0x70, 0x6c,
+    0x65, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x55,
+    0x73, 0x65, 0x20, 0x4f, 0x6e, 0x6c, 0x79, 0x31, 0x0b, 0x30, 0x09, 0x06,
+    0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x30, 0x82, 0x01, 0x22,
+    0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+    0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
+    0x02, 0x82, 0x01, 0x01, 0x00, 0xbb, 0x6c, 0x6c, 0xd4, 0xcd, 0x0b, 0xd9,
+    0x47, 0x49, 0xe1, 0xa3, 0xfe, 0x73, 0xe0, 0x15, 0xa6, 0x2e, 0x35, 0xc8,
+    0xb7, 0xcd, 0xab, 0x5e, 0xd3, 0x87, 0x8a, 0x94, 0x8f, 0x4d, 0x94, 0x52,
+    0x72, 0x27, 0x57, 0xb8, 0xf5, 0xa8, 0xe2, 0xf2, 0xb0, 0x46, 0xad, 0xb9,
+    0x30, 0x9b, 0x6a, 0xd7, 0x0a, 0xff, 0x0e, 0x5e, 0x78, 0x4c, 0x97, 0x17,
+    0x16, 0xa7, 0x03, 0xe1, 0x13, 0xe7, 0x97, 0x72, 0x24, 0xc8, 0x7f, 0x80,
+    0x91, 0xd2, 0x45, 0xa3, 0xf8, 0x21, 0xce, 0x2d, 0xfa, 0xe4, 0x3a, 0x5e,
+    0x04, 0x30, 0xe9, 0x48, 0xca, 0x32, 0xce, 0x52, 0x4c, 0xcf, 0x14, 0xf9,
+    0x04, 0x58, 0x30, 0x4a, 0xf8, 0x49, 0xbb, 0x39, 0x18, 0x5c, 0x4b, 0x28,
+    0x9e, 0x14, 0x16, 0x23, 0x73, 0x6e, 0x0d, 0xcd, 0xcd, 0xef, 0x98, 0xe7,
+    0x90, 0x04, 0x0e, 0x4a, 0xc8, 0x16, 0x22, 0x76, 0x68, 0xc6, 0xdf, 0x5d,
+    0x20, 0xa7, 0x49, 0x2e, 0x55, 0x9e, 0x50, 0x31, 0x56, 0x50, 0x29, 0xf9,
+    0x56, 0x09, 0x38, 0x32, 0x25, 0x1b, 0x3a, 0x1c, 0x97, 0x3e, 0x04, 0xee,
+    0x69, 0x3c, 0x68, 0x44, 0x54, 0x51, 0x27, 0x75, 0x70, 0xa2, 0x33, 0x86,
+    0x7a, 0x9d, 0x71, 0xc0, 0x18, 0x2e, 0x37, 0xb5, 0x47, 0x8d, 0xbe, 0x57,
+    0xb6, 0xaa, 0xda, 0x1d, 0xe8, 0x78, 0x23, 0x66, 0xc8, 0x6c, 0xe3, 0x7e,
+    0xfd, 0xde, 0x6b, 0x70, 0x2f, 0x76, 0x1d, 0xa6, 0x2b, 0x97, 0xee, 0xad,
+    0x5b, 0x8b, 0x8e, 0x00, 0x87, 0x27, 0xdf, 0x16, 0x54, 0x08, 0x97, 0x18,
+    0x23, 0x31, 0x2c, 0xf5, 0x9d, 0x41, 0xd5, 0xbb, 0x60, 0x23, 0x92, 0x3d,
+    0xcc, 0x9e, 0x2d, 0xff, 0xa5, 0x8b, 0xe0, 0xf9, 0x65, 0xdc, 0x94, 0x58,
+    0xb0, 0x9d, 0x73, 0x05, 0x05, 0x21, 0xa1, 0xb3, 0x37, 0xa4, 0x8f, 0x5d,
+    0xda, 0xce, 0x9c, 0xf6, 0x63, 0x9b, 0x6b, 0x9f, 0x77, 0x02, 0x03, 0x01,
+    0x00, 0x01, 0xa3, 0x82, 0x02, 0x3a, 0x30, 0x82, 0x02, 0x36, 0x30, 0x3d,
+    0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x31,
+    0x30, 0x2f, 0x30, 0x2d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+    0x30, 0x01, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f,
+    0x63, 0x73, 0x70, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
+    0x6d, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2d, 0x77, 0x77, 0x64, 0x72, 0x30,
+    0x33, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
+    0x9b, 0xc2, 0x61, 0x59, 0x72, 0x23, 0xb6, 0x5f, 0x91, 0x0f, 0x04, 0x87,
+    0x92, 0xf9, 0xa4, 0xf3, 0x6b, 0xe9, 0xbe, 0xab, 0x30, 0x09, 0x06, 0x03,
+    0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1f, 0x06, 0x03, 0x55,
+    0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x88, 0x27, 0x17, 0x09,
+    0xa9, 0xb6, 0x18, 0x60, 0x8b, 0xec, 0xeb, 0xba, 0xf6, 0x47, 0x59, 0xc5,
+    0x52, 0x54, 0xa3, 0xb7, 0x30, 0x82, 0x01, 0x0f, 0x06, 0x03, 0x55, 0x1d,
+    0x20, 0x04, 0x82, 0x01, 0x06, 0x30, 0x82, 0x01, 0x02, 0x30, 0x81, 0xff,
+    0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x05, 0x01, 0x30,
+    0x81, 0xf1, 0x30, 0x29, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+    0x02, 0x01, 0x16, 0x1d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
+    0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
+    0x2f, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x63, 0x61, 0x2f, 0x30, 0x81, 0xc3,
+    0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x81,
+    0xb6, 0x0c, 0x81, 0xb3, 0x52, 0x65, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65,
+    0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x63, 0x65, 0x72,
+    0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x62, 0x79, 0x20,
+    0x61, 0x6e, 0x79, 0x20, 0x70, 0x61, 0x72, 0x74, 0x79, 0x20, 0x61, 0x73,
+    0x73, 0x75, 0x6d, 0x65, 0x73, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74,
+    0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20,
+    0x74, 0x68, 0x65, 0x6e, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61,
+    0x62, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64,
+    0x20, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63,
+    0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66,
+    0x20, 0x75, 0x73, 0x65, 0x2c, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66,
+    0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79,
+    0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+    0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x61, 0x63, 0x74,
+    0x69, 0x63, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
+    0x74, 0x73, 0x2e, 0x30, 0x30, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x29,
+    0x30, 0x27, 0x30, 0x25, 0xa0, 0x23, 0xa0, 0x21, 0x86, 0x1f, 0x68, 0x74,
+    0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x61, 0x70, 0x70,
+    0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x77, 0x77, 0x64, 0x72, 0x63,
+    0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f,
+    0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x1d,
+    0x25, 0x04, 0x17, 0x30, 0x15, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+    0x07, 0x03, 0x02, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64,
+    0x04, 0x0e, 0x30, 0x10, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63,
+    0x64, 0x06, 0x03, 0x02, 0x04, 0x02, 0x05, 0x00, 0x30, 0x26, 0x06, 0x0a,
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x06, 0x01, 0x10, 0x04, 0x18,
+    0x0c, 0x16, 0x70, 0x61, 0x73, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61,
+    0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x61, 0x72, 0x64, 0x6d, 0x61, 0x6e,
+    0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+    0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x9b, 0xef, 0x1e, 0xff,
+    0xee, 0xd5, 0xfd, 0x71, 0x1a, 0xf5, 0x17, 0xfe, 0x05, 0xba, 0x30, 0xfc,
+    0xbd, 0x6d, 0x01, 0xb0, 0x0b, 0x78, 0x41, 0x4b, 0x76, 0x71, 0xd1, 0x8c,
+    0xf0, 0xcd, 0xed, 0xd9, 0xaa, 0xec, 0xad, 0x1d, 0x4a, 0x2d, 0xcc, 0x00,
+    0x11, 0x5b, 0x1d, 0xd9, 0xef, 0x08, 0xa2, 0x3d, 0xea, 0xe9, 0xbd, 0x35,
+    0x0b, 0x1c, 0x9f, 0xe7, 0xeb, 0xc9, 0xc9, 0xea, 0x99, 0xcc, 0x77, 0x27,
+    0xb9, 0x01, 0x09, 0x72, 0x40, 0xba, 0xd4, 0x26, 0x54, 0x8f, 0x30, 0x84,
+    0x7e, 0x03, 0x65, 0xda, 0x08, 0xb2, 0x92, 0xee, 0x61, 0x4e, 0x5f, 0x00,
+    0x39, 0x48, 0x2d, 0x99, 0x83, 0xb5, 0xc4, 0x33, 0xb2, 0xf7, 0x62, 0xcf,
+    0x6a, 0xbf, 0xbb, 0xb8, 0x40, 0x70, 0xbf, 0x11, 0xff, 0x7f, 0xc1, 0xc1,
+    0x8d, 0x1d, 0x67, 0x6c, 0x87, 0x02, 0xe2, 0x93, 0x17, 0x16, 0xc3, 0xec,
+    0x5e, 0x97, 0xe4, 0xdd, 0x12, 0xcc, 0xb2, 0xdd, 0x91, 0x51, 0xa8, 0x32,
+    0x25, 0x6d, 0xf7, 0x55, 0xb7, 0x4a, 0x8e, 0x6b, 0x90, 0xcb, 0x0f, 0x4c,
+    0x93, 0x87, 0x2a, 0xd9, 0x31, 0xb8, 0x1a, 0x16, 0x12, 0xbb, 0x6e, 0xfc,
+    0xb0, 0xae, 0xfb, 0x93, 0x76, 0x63, 0x37, 0xb7, 0x36, 0x13, 0x11, 0xc5,
+    0x53, 0x45, 0xe0, 0x0d, 0xff, 0xaf, 0x05, 0x5f, 0x67, 0x51, 0xe1, 0x54,
+    0x29, 0xa2, 0x1a, 0x7c, 0x61, 0xe0, 0xc2, 0xcd, 0xac, 0xbe, 0xee, 0xa6,
+    0x4a, 0xdc, 0x92, 0x95, 0x48, 0x41, 0x2f, 0x37, 0xc0, 0x64, 0x05, 0xaa,
+    0x4f, 0x05, 0xee, 0xe0, 0x3f, 0xa0, 0x9f, 0x43, 0x6c, 0xcc, 0xd5, 0x97,
+    0x64, 0x6d, 0x15, 0x5b, 0xb6, 0xcd, 0x2a, 0xbc, 0x18, 0xde, 0xc7, 0x94,
+    0x80, 0x2d, 0x2b, 0x81, 0x14, 0xfc, 0x48, 0xf7, 0xdf, 0xce, 0x94, 0xb3,
+    0xfd, 0xf5, 0x7e, 0x42, 0x4d, 0x33, 0x58, 0x4d, 0x7a, 0x62, 0x2e, 0x61,
+    0x31, 0x82, 0x02, 0x2a, 0x30, 0x82, 0x02, 0x26, 0x02, 0x01, 0x01, 0x30,
+    0x81, 0xa3, 0x30, 0x81, 0x96, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+    0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
+    0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49,
+    0x6e, 0x63, 0x2e, 0x31, 0x2c, 0x30, 0x2a, 0x06, 0x03, 0x55, 0x04, 0x0b,
+    0x0c, 0x23, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x6f, 0x72, 0x6c,
+    0x64, 0x77, 0x69, 0x64, 0x65, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f,
+    0x70, 0x65, 0x72, 0x20, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+    0x73, 0x31, 0x44, 0x30, 0x42, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x3b,
+    0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x77,
+    0x69, 0x64, 0x65, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65,
+    0x72, 0x20, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20,
+    0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+    0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x02,
+    0x08, 0x29, 0xd6, 0x12, 0x53, 0x17, 0x20, 0x2d, 0x6a, 0x30, 0x09, 0x06,
+    0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0xa0, 0x5d, 0x30, 0x18,
+    0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x03, 0x31,
+    0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01,
+    0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09,
+    0x05, 0x31, 0x0f, 0x17, 0x0d, 0x31, 0x32, 0x30, 0x38, 0x30, 0x37, 0x32,
+    0x31, 0x32, 0x31, 0x35, 0x30, 0x5a, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86,
+    0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04, 0x31, 0x16, 0x04, 0x14, 0x97,
+    0xab, 0x93, 0x47, 0x94, 0xc1, 0xdf, 0x9b, 0xf4, 0x8e, 0xf9, 0xec, 0x96,
+    0x77, 0xf9, 0x35, 0x15, 0xe1, 0x75, 0x58, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+    0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
+    0x01, 0x00, 0x33, 0xdd, 0xcb, 0xf1, 0xa1, 0x74, 0xc2, 0xad, 0x44, 0xcd,
+    0x49, 0x95, 0xad, 0xd4, 0xd5, 0xaf, 0x37, 0x98, 0x5e, 0x1b, 0x0e, 0xf7,
+    0x49, 0xc5, 0x3a, 0x01, 0x99, 0x7e, 0xc2, 0x3b, 0x4f, 0x37, 0xd0, 0x8e,
+    0x31, 0x7f, 0xcd, 0x7d, 0x9f, 0xfd, 0xb9, 0x6a, 0x8e, 0x43, 0xcf, 0xc0,
+    0x94, 0xda, 0x2b, 0x1b, 0x98, 0x28, 0x0a, 0x34, 0x39, 0x1c, 0x3d, 0xf1,
+    0x86, 0xad, 0x02, 0x7e, 0xdb, 0x02, 0x9b, 0xfc, 0x4a, 0x2e, 0x10, 0x82,
+    0x50, 0xfe, 0x61, 0x18, 0xc4, 0x6f, 0x45, 0x30, 0x66, 0x7a, 0x44, 0x70,
+    0x0d, 0x4c, 0x47, 0x04, 0xb4, 0x09, 0x02, 0x12, 0xa8, 0x61, 0x3c, 0xf7,
+    0x24, 0x7c, 0xb3, 0xa8, 0x5b, 0xde, 0xe4, 0xa4, 0x5d, 0x98, 0x9e, 0x72,
+    0x0a, 0xea, 0x36, 0x5c, 0xfa, 0xe1, 0x80, 0xd6, 0x93, 0xa2, 0xbc, 0x09,
+    0x9c, 0xd6, 0xf9, 0x05, 0x53, 0x88, 0xe5, 0x24, 0x9f, 0x8f, 0x5e, 0x2f,
+    0xfd, 0x2c, 0x9c, 0xd6, 0x69, 0xad, 0x22, 0x54, 0xa7, 0xc5, 0x27, 0x2f,
+    0x35, 0x77, 0xda, 0x0e, 0x49, 0xd0, 0x0a, 0x75, 0xaa, 0x5e, 0x6e, 0xad,
+    0xe9, 0x20, 0xff, 0xf8, 0x5a, 0x40, 0x03, 0xe4, 0x36, 0xf1, 0x88, 0x1a,
+    0xf3, 0x81, 0xc6, 0xd7, 0x70, 0xc8, 0xa9, 0xd2, 0x93, 0x51, 0x81, 0x49,
+    0xf0, 0xe2, 0xef, 0xdb, 0xbd, 0x1a, 0x33, 0xf8, 0x2e, 0xa4, 0xb7, 0x21,
+    0x14, 0x57, 0x98, 0x0e, 0xab, 0xbd, 0xa4, 0xd7, 0xec, 0xfc, 0x7a, 0x8d,
+    0xdd, 0xcc, 0xec, 0x22, 0x13, 0x8d, 0xa9, 0x43, 0x68, 0xda, 0x5f, 0x78,
+    0xe1, 0x21, 0xeb, 0xb1, 0x25, 0xb5, 0x4f, 0x99, 0x29, 0x7d, 0xf1, 0x9c,
+    0x11, 0x2a, 0xa6, 0xdf, 0x9c, 0xd3, 0x33, 0xdb, 0xff, 0xb4, 0xcb, 0x40,
+    0x77, 0x4d, 0xa5, 0x5c, 0x9b, 0x6f, 0x11, 0xad, 0x98, 0x17, 0x3b, 0xdd,
+    0x16, 0xad, 0x5e, 0x4f, 0xcb, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char _USAirwaysWrongTeamID_signature[] = {
+    0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07,
+    0x02, 0xa0, 0x80, 0x30, 0x80, 0x02, 0x01, 0x01, 0x31, 0x0b, 0x30, 0x09,
+    0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x30, 0x80, 0x06,
+    0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x00, 0x00,
+    0xa0, 0x82, 0x0a, 0x1c, 0x30, 0x82, 0x04, 0x23, 0x30, 0x82, 0x03, 0x0b,
+    0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x19, 0x30, 0x0d, 0x06, 0x09,
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
+    0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+    0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+    0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
+    0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70,
+    0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+    0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+    0x69, 0x74, 0x79, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03,
+    0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74,
+    0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x38, 0x30, 0x32, 0x31,
+    0x34, 0x31, 0x38, 0x35, 0x36, 0x33, 0x35, 0x5a, 0x17, 0x0d, 0x31, 0x36,
+    0x30, 0x32, 0x31, 0x34, 0x31, 0x38, 0x35, 0x36, 0x33, 0x35, 0x5a, 0x30,
+    0x81, 0x96, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+    0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
+    0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+    0x31, 0x2c, 0x30, 0x2a, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x23, 0x41,
+    0x70, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x77, 0x69,
+    0x64, 0x65, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72,
+    0x20, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x31, 0x44,
+    0x30, 0x42, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x3b, 0x41, 0x70, 0x70,
+    0x6c, 0x65, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x77, 0x69, 0x64, 0x65,
+    0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x20, 0x52,
+    0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x43, 0x65, 0x72,
+    0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41,
+    0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x82, 0x01, 0x22,
+    0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+    0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
+    0x02, 0x82, 0x01, 0x01, 0x00, 0xca, 0x38, 0x54, 0xa6, 0xcb, 0x56, 0xaa,
+    0xc8, 0x24, 0x39, 0x48, 0xe9, 0x8c, 0xee, 0xec, 0x5f, 0xb8, 0x7f, 0x26,
+    0x91, 0xbc, 0x34, 0x53, 0x7a, 0xce, 0x7c, 0x63, 0x80, 0x61, 0x77, 0x64,
+    0x5e, 0xa5, 0x07, 0x23, 0xb6, 0x39, 0xfe, 0x50, 0x2d, 0x15, 0x56, 0x58,
+    0x70, 0x2d, 0x7e, 0xc4, 0x6e, 0xc1, 0x4a, 0x85, 0x3e, 0x2f, 0xf0, 0xde,
+    0x84, 0x1a, 0xa1, 0x57, 0xc9, 0xaf, 0x7b, 0x18, 0xff, 0x6a, 0xfa, 0x15,
+    0x12, 0x49, 0x15, 0x08, 0x19, 0xac, 0xaa, 0xdb, 0x2a, 0x32, 0xed, 0x96,
+    0x63, 0x68, 0x52, 0x15, 0x3d, 0x8c, 0x8a, 0xec, 0xbf, 0x6b, 0x18, 0x95,
+    0xe0, 0x03, 0xac, 0x01, 0x7d, 0x97, 0x05, 0x67, 0xce, 0x0e, 0x85, 0x95,
+    0x37, 0x6a, 0xed, 0x09, 0xb6, 0xae, 0x67, 0xcd, 0x51, 0x64, 0x9f, 0xc6,
+    0x5c, 0xd1, 0xbc, 0x57, 0x6e, 0x67, 0x35, 0x80, 0x76, 0x36, 0xa4, 0x87,
+    0x81, 0x6e, 0x38, 0x8f, 0xd8, 0x2b, 0x15, 0x4e, 0x7b, 0x25, 0xd8, 0x5a,
+    0xbf, 0x4e, 0x83, 0xc1, 0x8d, 0xd2, 0x93, 0xd5, 0x1a, 0x71, 0xb5, 0x60,
+    0x9c, 0x9d, 0x33, 0x4e, 0x55, 0xf9, 0x12, 0x58, 0x0c, 0x86, 0xb8, 0x16,
+    0x0d, 0xc1, 0xe5, 0x77, 0x45, 0x8d, 0x50, 0x48, 0xba, 0x2b, 0x2d, 0xe4,
+    0x94, 0x85, 0xe1, 0xe8, 0xc4, 0x9d, 0xc6, 0x68, 0xa5, 0xb0, 0xa3, 0xfc,
+    0x67, 0x7e, 0x70, 0xba, 0x02, 0x59, 0x4b, 0x77, 0x42, 0x91, 0x39, 0xb9,
+    0xf5, 0xcd, 0xe1, 0x4c, 0xef, 0xc0, 0x3b, 0x48, 0x8c, 0xa6, 0xe5, 0x21,
+    0x5d, 0xfd, 0x6a, 0x6a, 0xbb, 0xa7, 0x16, 0x35, 0x60, 0xd2, 0xe6, 0xad,
+    0xf3, 0x46, 0x29, 0xc9, 0xe8, 0xc3, 0x8b, 0xe9, 0x79, 0xc0, 0x6a, 0x61,
+    0x67, 0x15, 0xb2, 0xf0, 0xfd, 0xe5, 0x68, 0xbc, 0x62, 0x5f, 0x6e, 0xcf,
+    0x99, 0xdd, 0xef, 0x1b, 0x63, 0xfe, 0x92, 0x65, 0xab, 0x02, 0x03, 0x01,
+    0x00, 0x01, 0xa3, 0x81, 0xae, 0x30, 0x81, 0xab, 0x30, 0x0e, 0x06, 0x03,
+    0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86,
+    0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05,
+    0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
+    0x04, 0x16, 0x04, 0x14, 0x88, 0x27, 0x17, 0x09, 0xa9, 0xb6, 0x18, 0x60,
+    0x8b, 0xec, 0xeb, 0xba, 0xf6, 0x47, 0x59, 0xc5, 0x52, 0x54, 0xa3, 0xb7,
+    0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80,
+    0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76, 0x09, 0xfe, 0xf4, 0x6b, 0x8d,
+    0x2e, 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x36, 0x06,
+    0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2f, 0x30, 0x2d, 0x30, 0x2b, 0xa0, 0x29,
+    0xa0, 0x27, 0x86, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
+    0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
+    0x2f, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x63, 0x61, 0x2f, 0x72, 0x6f, 0x6f,
+    0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x10, 0x06, 0x0a, 0x2a, 0x86, 0x48,
+    0x86, 0xf7, 0x63, 0x64, 0x06, 0x02, 0x01, 0x04, 0x02, 0x05, 0x00, 0x30,
+    0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
+    0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xda, 0x32, 0x00, 0x96, 0xc5,
+    0x54, 0x94, 0xd3, 0x3b, 0x82, 0x37, 0x66, 0x7d, 0x2e, 0x68, 0xd5, 0xc3,
+    0xc6, 0xb8, 0xcb, 0x26, 0x8c, 0x48, 0x90, 0xcf, 0x13, 0x24, 0x6a, 0x46,
+    0x8e, 0x63, 0xd4, 0xf0, 0xd0, 0x13, 0x06, 0xdd, 0xd8, 0xc4, 0xc1, 0x37,
+    0x15, 0xf2, 0x33, 0x13, 0x39, 0x26, 0x2d, 0xce, 0x2e, 0x55, 0x40, 0xe3,
+    0x0b, 0x03, 0xaf, 0xfa, 0x12, 0xc2, 0xe7, 0x0d, 0x21, 0xb8, 0xd5, 0x80,
+    0xcf, 0xac, 0x28, 0x2f, 0xce, 0x2d, 0xb3, 0x4e, 0xaf, 0x86, 0x19, 0x04,
+    0xc6, 0xe9, 0x50, 0xdd, 0x4c, 0x29, 0x47, 0x10, 0x23, 0xfc, 0x6c, 0xbb,
+    0x1b, 0x98, 0x6b, 0x48, 0x89, 0xe1, 0x5b, 0x9d, 0xde, 0x46, 0xdb, 0x35,
+    0x85, 0x35, 0xef, 0x3e, 0xd0, 0xe2, 0x58, 0x4b, 0x38, 0xf4, 0xed, 0x75,
+    0x5a, 0x1f, 0x5c, 0x70, 0x1d, 0x56, 0x39, 0x12, 0xe5, 0xe1, 0x0d, 0x11,
+    0xe4, 0x89, 0x25, 0x06, 0xbd, 0xd5, 0xb4, 0x15, 0x8e, 0x5e, 0xd0, 0x59,
+    0x97, 0x90, 0xe9, 0x4b, 0x81, 0xe2, 0xdf, 0x18, 0xaf, 0x44, 0x74, 0x1e,
+    0x19, 0xa0, 0x3a, 0x47, 0xcc, 0x91, 0x1d, 0x3a, 0xeb, 0x23, 0x5a, 0xfe,
+    0xa5, 0x2d, 0x97, 0xf7, 0x7b, 0xbb, 0xd6, 0x87, 0x46, 0x42, 0x85, 0xeb,
+    0x52, 0x3d, 0x26, 0xb2, 0x63, 0xa8, 0xb4, 0xb1, 0xca, 0x8f, 0xf4, 0xcc,
+    0xe2, 0xb3, 0xc8, 0x47, 0xe0, 0xbf, 0x9a, 0x59, 0x83, 0xfa, 0xda, 0x98,
+    0x53, 0x2a, 0x82, 0xf5, 0x7c, 0x65, 0x2e, 0x95, 0xd9, 0x33, 0x5d, 0xf5,
+    0xed, 0x65, 0xcc, 0x31, 0x37, 0xc5, 0x5a, 0x04, 0xe8, 0x6b, 0xe1, 0xe7,
+    0x88, 0x03, 0x4a, 0x75, 0x9e, 0x9b, 0x28, 0xcb, 0x4a, 0x40, 0x88, 0x65,
+    0x43, 0x75, 0xdd, 0xcb, 0x3a, 0x25, 0x23, 0xc5, 0x9e, 0x57, 0xf8, 0x2e,
+    0xce, 0xd2, 0xa9, 0x92, 0x5e, 0x73, 0x2e, 0x2f, 0x25, 0x75, 0x15, 0x30,
+    0x82, 0x05, 0xf1, 0x30, 0x82, 0x04, 0xd9, 0xa0, 0x03, 0x02, 0x01, 0x02,
+    0x02, 0x08, 0x29, 0xd6, 0x12, 0x53, 0x17, 0x20, 0x2d, 0x6a, 0x30, 0x0d,
+    0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
+    0x00, 0x30, 0x81, 0x96, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
+    0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
+    0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e,
+    0x63, 0x2e, 0x31, 0x2c, 0x30, 0x2a, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c,
+    0x23, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64,
+    0x77, 0x69, 0x64, 0x65, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70,
+    0x65, 0x72, 0x20, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+    0x31, 0x44, 0x30, 0x42, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x3b, 0x41,
+    0x70, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x77, 0x69,
+    0x64, 0x65, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72,
+    0x20, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x43,
+    0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+    0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e,
+    0x17, 0x0d, 0x31, 0x32, 0x30, 0x35, 0x33, 0x30, 0x32, 0x33, 0x32, 0x30,
+    0x31, 0x30, 0x5a, 0x17, 0x0d, 0x31, 0x33, 0x30, 0x35, 0x33, 0x30, 0x32,
+    0x33, 0x32, 0x30, 0x31, 0x30, 0x5a, 0x30, 0x81, 0x9b, 0x31, 0x26, 0x30,
+    0x24, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01,
+    0x01, 0x0c, 0x16, 0x70, 0x61, 0x73, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2e,
+    0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x61, 0x72, 0x64, 0x6d, 0x61,
+    0x6e, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x24,
+    0x50, 0x61, 0x73, 0x73, 0x20, 0x54, 0x79, 0x70, 0x65, 0x20, 0x49, 0x44,
+    0x3a, 0x20, 0x70, 0x61, 0x73, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61,
+    0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x61, 0x72, 0x64, 0x6d, 0x61, 0x6e,
+    0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x0a, 0x41,
+    0x31, 0x42, 0x32, 0x43, 0x33, 0x44, 0x34, 0x45, 0x35, 0x31, 0x20, 0x30,
+    0x1e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x17, 0x41, 0x70, 0x70, 0x6c,
+    0x65, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x55,
+    0x73, 0x65, 0x20, 0x4f, 0x6e, 0x6c, 0x79, 0x31, 0x0b, 0x30, 0x09, 0x06,
+    0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x30, 0x82, 0x01, 0x22,
+    0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+    0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
+    0x02, 0x82, 0x01, 0x01, 0x00, 0xbb, 0x6c, 0x6c, 0xd4, 0xcd, 0x0b, 0xd9,
+    0x47, 0x49, 0xe1, 0xa3, 0xfe, 0x73, 0xe0, 0x15, 0xa6, 0x2e, 0x35, 0xc8,
+    0xb7, 0xcd, 0xab, 0x5e, 0xd3, 0x87, 0x8a, 0x94, 0x8f, 0x4d, 0x94, 0x52,
+    0x72, 0x27, 0x57, 0xb8, 0xf5, 0xa8, 0xe2, 0xf2, 0xb0, 0x46, 0xad, 0xb9,
+    0x30, 0x9b, 0x6a, 0xd7, 0x0a, 0xff, 0x0e, 0x5e, 0x78, 0x4c, 0x97, 0x17,
+    0x16, 0xa7, 0x03, 0xe1, 0x13, 0xe7, 0x97, 0x72, 0x24, 0xc8, 0x7f, 0x80,
+    0x91, 0xd2, 0x45, 0xa3, 0xf8, 0x21, 0xce, 0x2d, 0xfa, 0xe4, 0x3a, 0x5e,
+    0x04, 0x30, 0xe9, 0x48, 0xca, 0x32, 0xce, 0x52, 0x4c, 0xcf, 0x14, 0xf9,
+    0x04, 0x58, 0x30, 0x4a, 0xf8, 0x49, 0xbb, 0x39, 0x18, 0x5c, 0x4b, 0x28,
+    0x9e, 0x14, 0x16, 0x23, 0x73, 0x6e, 0x0d, 0xcd, 0xcd, 0xef, 0x98, 0xe7,
+    0x90, 0x04, 0x0e, 0x4a, 0xc8, 0x16, 0x22, 0x76, 0x68, 0xc6, 0xdf, 0x5d,
+    0x20, 0xa7, 0x49, 0x2e, 0x55, 0x9e, 0x50, 0x31, 0x56, 0x50, 0x29, 0xf9,
+    0x56, 0x09, 0x38, 0x32, 0x25, 0x1b, 0x3a, 0x1c, 0x97, 0x3e, 0x04, 0xee,
+    0x69, 0x3c, 0x68, 0x44, 0x54, 0x51, 0x27, 0x75, 0x70, 0xa2, 0x33, 0x86,
+    0x7a, 0x9d, 0x71, 0xc0, 0x18, 0x2e, 0x37, 0xb5, 0x47, 0x8d, 0xbe, 0x57,
+    0xb6, 0xaa, 0xda, 0x1d, 0xe8, 0x78, 0x23, 0x66, 0xc8, 0x6c, 0xe3, 0x7e,
+    0xfd, 0xde, 0x6b, 0x70, 0x2f, 0x76, 0x1d, 0xa6, 0x2b, 0x97, 0xee, 0xad,
+    0x5b, 0x8b, 0x8e, 0x00, 0x87, 0x27, 0xdf, 0x16, 0x54, 0x08, 0x97, 0x18,
+    0x23, 0x31, 0x2c, 0xf5, 0x9d, 0x41, 0xd5, 0xbb, 0x60, 0x23, 0x92, 0x3d,
+    0xcc, 0x9e, 0x2d, 0xff, 0xa5, 0x8b, 0xe0, 0xf9, 0x65, 0xdc, 0x94, 0x58,
+    0xb0, 0x9d, 0x73, 0x05, 0x05, 0x21, 0xa1, 0xb3, 0x37, 0xa4, 0x8f, 0x5d,
+    0xda, 0xce, 0x9c, 0xf6, 0x63, 0x9b, 0x6b, 0x9f, 0x77, 0x02, 0x03, 0x01,
+    0x00, 0x01, 0xa3, 0x82, 0x02, 0x3a, 0x30, 0x82, 0x02, 0x36, 0x30, 0x3d,
+    0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x31,
+    0x30, 0x2f, 0x30, 0x2d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+    0x30, 0x01, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f,
+    0x63, 0x73, 0x70, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
+    0x6d, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2d, 0x77, 0x77, 0x64, 0x72, 0x30,
+    0x33, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
+    0x9b, 0xc2, 0x61, 0x59, 0x72, 0x23, 0xb6, 0x5f, 0x91, 0x0f, 0x04, 0x87,
+    0x92, 0xf9, 0xa4, 0xf3, 0x6b, 0xe9, 0xbe, 0xab, 0x30, 0x09, 0x06, 0x03,
+    0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1f, 0x06, 0x03, 0x55,
+    0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x88, 0x27, 0x17, 0x09,
+    0xa9, 0xb6, 0x18, 0x60, 0x8b, 0xec, 0xeb, 0xba, 0xf6, 0x47, 0x59, 0xc5,
+    0x52, 0x54, 0xa3, 0xb7, 0x30, 0x82, 0x01, 0x0f, 0x06, 0x03, 0x55, 0x1d,
+    0x20, 0x04, 0x82, 0x01, 0x06, 0x30, 0x82, 0x01, 0x02, 0x30, 0x81, 0xff,
+    0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x05, 0x01, 0x30,
+    0x81, 0xf1, 0x30, 0x29, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+    0x02, 0x01, 0x16, 0x1d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
+    0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
+    0x2f, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x63, 0x61, 0x2f, 0x30, 0x81, 0xc3,
+    0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x81,
+    0xb6, 0x0c, 0x81, 0xb3, 0x52, 0x65, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65,
+    0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x63, 0x65, 0x72,
+    0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x62, 0x79, 0x20,
+    0x61, 0x6e, 0x79, 0x20, 0x70, 0x61, 0x72, 0x74, 0x79, 0x20, 0x61, 0x73,
+    0x73, 0x75, 0x6d, 0x65, 0x73, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74,
+    0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20,
+    0x74, 0x68, 0x65, 0x6e, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61,
+    0x62, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64,
+    0x20, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63,
+    0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66,
+    0x20, 0x75, 0x73, 0x65, 0x2c, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66,
+    0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79,
+    0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+    0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x61, 0x63, 0x74,
+    0x69, 0x63, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
+    0x74, 0x73, 0x2e, 0x30, 0x30, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x29,
+    0x30, 0x27, 0x30, 0x25, 0xa0, 0x23, 0xa0, 0x21, 0x86, 0x1f, 0x68, 0x74,
+    0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x61, 0x70, 0x70,
+    0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x77, 0x77, 0x64, 0x72, 0x63,
+    0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f,
+    0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x1d,
+    0x25, 0x04, 0x17, 0x30, 0x15, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+    0x07, 0x03, 0x02, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64,
+    0x04, 0x0e, 0x30, 0x10, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63,
+    0x64, 0x06, 0x03, 0x02, 0x04, 0x02, 0x05, 0x00, 0x30, 0x26, 0x06, 0x0a,
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x06, 0x01, 0x10, 0x04, 0x18,
+    0x0c, 0x16, 0x70, 0x61, 0x73, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61,
+    0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x61, 0x72, 0x64, 0x6d, 0x61, 0x6e,
+    0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+    0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x9b, 0xef, 0x1e, 0xff,
+    0xee, 0xd5, 0xfd, 0x71, 0x1a, 0xf5, 0x17, 0xfe, 0x05, 0xba, 0x30, 0xfc,
+    0xbd, 0x6d, 0x01, 0xb0, 0x0b, 0x78, 0x41, 0x4b, 0x76, 0x71, 0xd1, 0x8c,
+    0xf0, 0xcd, 0xed, 0xd9, 0xaa, 0xec, 0xad, 0x1d, 0x4a, 0x2d, 0xcc, 0x00,
+    0x11, 0x5b, 0x1d, 0xd9, 0xef, 0x08, 0xa2, 0x3d, 0xea, 0xe9, 0xbd, 0x35,
+    0x0b, 0x1c, 0x9f, 0xe7, 0xeb, 0xc9, 0xc9, 0xea, 0x99, 0xcc, 0x77, 0x27,
+    0xb9, 0x01, 0x09, 0x72, 0x40, 0xba, 0xd4, 0x26, 0x54, 0x8f, 0x30, 0x84,
+    0x7e, 0x03, 0x65, 0xda, 0x08, 0xb2, 0x92, 0xee, 0x61, 0x4e, 0x5f, 0x00,
+    0x39, 0x48, 0x2d, 0x99, 0x83, 0xb5, 0xc4, 0x33, 0xb2, 0xf7, 0x62, 0xcf,
+    0x6a, 0xbf, 0xbb, 0xb8, 0x40, 0x70, 0xbf, 0x11, 0xff, 0x7f, 0xc1, 0xc1,
+    0x8d, 0x1d, 0x67, 0x6c, 0x87, 0x02, 0xe2, 0x93, 0x17, 0x16, 0xc3, 0xec,
+    0x5e, 0x97, 0xe4, 0xdd, 0x12, 0xcc, 0xb2, 0xdd, 0x91, 0x51, 0xa8, 0x32,
+    0x25, 0x6d, 0xf7, 0x55, 0xb7, 0x4a, 0x8e, 0x6b, 0x90, 0xcb, 0x0f, 0x4c,
+    0x93, 0x87, 0x2a, 0xd9, 0x31, 0xb8, 0x1a, 0x16, 0x12, 0xbb, 0x6e, 0xfc,
+    0xb0, 0xae, 0xfb, 0x93, 0x76, 0x63, 0x37, 0xb7, 0x36, 0x13, 0x11, 0xc5,
+    0x53, 0x45, 0xe0, 0x0d, 0xff, 0xaf, 0x05, 0x5f, 0x67, 0x51, 0xe1, 0x54,
+    0x29, 0xa2, 0x1a, 0x7c, 0x61, 0xe0, 0xc2, 0xcd, 0xac, 0xbe, 0xee, 0xa6,
+    0x4a, 0xdc, 0x92, 0x95, 0x48, 0x41, 0x2f, 0x37, 0xc0, 0x64, 0x05, 0xaa,
+    0x4f, 0x05, 0xee, 0xe0, 0x3f, 0xa0, 0x9f, 0x43, 0x6c, 0xcc, 0xd5, 0x97,
+    0x64, 0x6d, 0x15, 0x5b, 0xb6, 0xcd, 0x2a, 0xbc, 0x18, 0xde, 0xc7, 0x94,
+    0x80, 0x2d, 0x2b, 0x81, 0x14, 0xfc, 0x48, 0xf7, 0xdf, 0xce, 0x94, 0xb3,
+    0xfd, 0xf5, 0x7e, 0x42, 0x4d, 0x33, 0x58, 0x4d, 0x7a, 0x62, 0x2e, 0x61,
+    0x31, 0x82, 0x02, 0x2a, 0x30, 0x82, 0x02, 0x26, 0x02, 0x01, 0x01, 0x30,
+    0x81, 0xa3, 0x30, 0x81, 0x96, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+    0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
+    0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49,
+    0x6e, 0x63, 0x2e, 0x31, 0x2c, 0x30, 0x2a, 0x06, 0x03, 0x55, 0x04, 0x0b,
+    0x0c, 0x23, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x6f, 0x72, 0x6c,
+    0x64, 0x77, 0x69, 0x64, 0x65, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f,
+    0x70, 0x65, 0x72, 0x20, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+    0x73, 0x31, 0x44, 0x30, 0x42, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x3b,
+    0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x77,
+    0x69, 0x64, 0x65, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65,
+    0x72, 0x20, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20,
+    0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+    0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x02,
+    0x08, 0x29, 0xd6, 0x12, 0x53, 0x17, 0x20, 0x2d, 0x6a, 0x30, 0x09, 0x06,
+    0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0xa0, 0x5d, 0x30, 0x18,
+    0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x03, 0x31,
+    0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01,
+    0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09,
+    0x05, 0x31, 0x0f, 0x17, 0x0d, 0x31, 0x32, 0x30, 0x38, 0x30, 0x37, 0x32,
+    0x31, 0x32, 0x33, 0x30, 0x35, 0x5a, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86,
+    0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04, 0x31, 0x16, 0x04, 0x14, 0x3e,
+    0xa0, 0x0a, 0xb8, 0x8c, 0x99, 0x95, 0xbc, 0x08, 0x28, 0xfc, 0x76, 0x6c,
+    0xcc, 0xb7, 0x75, 0x57, 0x82, 0x6f, 0x81, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+    0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
+    0x01, 0x00, 0x1a, 0x4c, 0x93, 0x84, 0xe5, 0x8a, 0x68, 0x26, 0x7f, 0xb2,
+    0xf7, 0xa4, 0x69, 0x66, 0x3a, 0xfa, 0xad, 0x77, 0x30, 0xa7, 0x21, 0xa7,
+    0xbb, 0x01, 0x17, 0xb4, 0x88, 0x4a, 0x58, 0x37, 0x2b, 0xf5, 0x92, 0x79,
+    0xce, 0xb2, 0x89, 0xbb, 0xb3, 0x52, 0x80, 0xa3, 0x10, 0x6f, 0x58, 0xcb,
+    0x03, 0x80, 0xb9, 0x32, 0x12, 0x76, 0xe6, 0x79, 0xc1, 0xcc, 0x3c, 0x7b,
+    0xf6, 0x69, 0x31, 0x9a, 0xe1, 0x59, 0xd4, 0x15, 0x8a, 0x1d, 0xbd, 0xb0,
+    0xc9, 0xc3, 0xe7, 0x55, 0x24, 0xcc, 0x42, 0x5c, 0x01, 0x1d, 0xd7, 0x1b,
+    0x3a, 0x6e, 0x26, 0xda, 0x56, 0xd1, 0xaf, 0x44, 0x2c, 0x41, 0x6f, 0x26,
+    0x36, 0xb0, 0x2d, 0x43, 0x04, 0xb8, 0x05, 0xd1, 0xe3, 0xe4, 0xa0, 0x9d,
+    0x98, 0x5b, 0x52, 0x7d, 0xd2, 0x8b, 0x78, 0x27, 0x1f, 0x8e, 0xd0, 0xb0,
+    0x09, 0x8a, 0x7d, 0x09, 0xd9, 0xc2, 0x7b, 0x09, 0x1e, 0xd8, 0x92, 0x1f,
+    0x3f, 0x0f, 0x52, 0x10, 0x13, 0x9c, 0x0a, 0x4c, 0x9d, 0x4e, 0x55, 0x32,
+    0x67, 0xc0, 0x46, 0x64, 0x8c, 0x89, 0x77, 0x6a, 0x6a, 0x60, 0xe2, 0x4d,
+    0xb2, 0x9e, 0x4d, 0x18, 0xc9, 0x77, 0x74, 0xf1, 0x41, 0xf5, 0xb7, 0xfa,
+    0x4b, 0x0f, 0xb7, 0x51, 0xf4, 0x59, 0x4d, 0xfa, 0x7a, 0x07, 0xba, 0xab,
+    0xd5, 0x90, 0xa6, 0xbd, 0x61, 0x05, 0xde, 0x8b, 0x46, 0xbf, 0x8b, 0x5a,
+    0xf8, 0xbf, 0xd8, 0x6c, 0x87, 0x0e, 0xc0, 0xfd, 0xc4, 0x63, 0xdd, 0xd9,
+    0xb1, 0x52, 0xca, 0x64, 0x68, 0x87, 0xab, 0x27, 0x41, 0x41, 0xb8, 0x02,
+    0xa2, 0xb7, 0xde, 0xda, 0x84, 0x15, 0x0e, 0xc6, 0x49, 0x5d, 0xd2, 0xc9,
+    0xf1, 0x4a, 0x44, 0xa4, 0x1a, 0xf8, 0x5f, 0x70, 0x52, 0x67, 0xb3, 0x6f,
+    0x59, 0x9a, 0x9a, 0xea, 0x1d, 0xfa, 0x6e, 0x06, 0xf3, 0xdc, 0x60, 0x28,
+    0x97, 0xc3, 0x78, 0x04, 0x17, 0xbb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char _USAirwaysCorrect_manifest_json[] = {
+    0x7b, 0x0a, 0x20, 0x20, 0x22, 0x69, 0x63, 0x6f, 0x6e, 0x40, 0x32, 0x78,
+    0x2e, 0x70, 0x6e, 0x67, 0x22, 0x20, 0x3a, 0x20, 0x22, 0x38, 0x31, 0x38,
+    0x64, 0x32, 0x37, 0x64, 0x33, 0x65, 0x66, 0x61, 0x39, 0x35, 0x37, 0x31,
+    0x62, 0x61, 0x30, 0x66, 0x66, 0x31, 0x65, 0x36, 0x32, 0x34, 0x33, 0x62,
+    0x30, 0x39, 0x34, 0x35, 0x62, 0x63, 0x63, 0x36, 0x39, 0x33, 0x65, 0x62,
+    0x37, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x22, 0x69, 0x63, 0x6f, 0x6e, 0x2e,
+    0x70, 0x6e, 0x67, 0x22, 0x20, 0x3a, 0x20, 0x22, 0x62, 0x65, 0x64, 0x66,
+    0x30, 0x30, 0x61, 0x61, 0x62, 0x32, 0x32, 0x31, 0x61, 0x63, 0x37, 0x31,
+    0x64, 0x33, 0x66, 0x66, 0x65, 0x64, 0x64, 0x33, 0x32, 0x63, 0x33, 0x63,
+    0x64, 0x36, 0x63, 0x32, 0x35, 0x30, 0x33, 0x32, 0x62, 0x61, 0x34, 0x30,
+    0x22, 0x2c, 0x0a, 0x20, 0x20, 0x22, 0x70, 0x61, 0x73, 0x73, 0x2e, 0x6a,
+    0x73, 0x6f, 0x6e, 0x22, 0x20, 0x3a, 0x20, 0x22, 0x61, 0x65, 0x33, 0x38,
+    0x39, 0x35, 0x39, 0x36, 0x30, 0x62, 0x34, 0x64, 0x61, 0x31, 0x65, 0x64,
+    0x35, 0x38, 0x33, 0x66, 0x64, 0x37, 0x31, 0x66, 0x66, 0x32, 0x36, 0x31,
+    0x36, 0x65, 0x34, 0x39, 0x65, 0x36, 0x34, 0x64, 0x36, 0x36, 0x65, 0x66,
+    0x22, 0x2c, 0x0a, 0x20, 0x20, 0x22, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x70,
+    0x6e, 0x67, 0x22, 0x20, 0x3a, 0x20, 0x22, 0x39, 0x30, 0x62, 0x63, 0x62,
+    0x39, 0x34, 0x62, 0x62, 0x30, 0x66, 0x31, 0x30, 0x33, 0x66, 0x36, 0x63,
+    0x32, 0x63, 0x32, 0x36, 0x35, 0x35, 0x33, 0x36, 0x66, 0x65, 0x61, 0x63,
+    0x37, 0x61, 0x38, 0x38, 0x33, 0x36, 0x37, 0x30, 0x34, 0x34, 0x33, 0x22,
+    0x2c, 0x0a, 0x20, 0x20, 0x22, 0x2e, 0x44, 0x53, 0x5f, 0x53, 0x74, 0x6f,
+    0x72, 0x65, 0x22, 0x20, 0x3a, 0x20, 0x22, 0x64, 0x66, 0x32, 0x66, 0x62,
+    0x65, 0x62, 0x31, 0x34, 0x30, 0x30, 0x61, 0x63, 0x64, 0x61, 0x30, 0x39,
+    0x30, 0x39, 0x61, 0x33, 0x32, 0x63, 0x31, 0x63, 0x66, 0x36, 0x62, 0x66,
+    0x34, 0x39, 0x32, 0x66, 0x31, 0x31, 0x32, 0x31, 0x65, 0x30, 0x37, 0x22,
+    0x2c, 0x0a, 0x20, 0x20, 0x22, 0x6c, 0x6f, 0x67, 0x6f, 0x40, 0x32, 0x78,
+    0x2e, 0x70, 0x6e, 0x67, 0x22, 0x20, 0x3a, 0x20, 0x22, 0x39, 0x30, 0x62,
+    0x63, 0x62, 0x39, 0x34, 0x62, 0x62, 0x30, 0x66, 0x31, 0x30, 0x33, 0x66,
+    0x36, 0x63, 0x32, 0x63, 0x32, 0x36, 0x35, 0x35, 0x33, 0x36, 0x66, 0x65,
+    0x61, 0x63, 0x37, 0x61, 0x38, 0x38, 0x33, 0x36, 0x37, 0x30, 0x34, 0x34,
+    0x33, 0x22, 0x0a, 0x7d
+};
+
+unsigned char _USAirwaysWrongTeamID_manifest_json[] = {
+    0x7b, 0x0a, 0x20, 0x20, 0x22, 0x69, 0x63, 0x6f, 0x6e, 0x40, 0x32, 0x78,
+    0x2e, 0x70, 0x6e, 0x67, 0x22, 0x20, 0x3a, 0x20, 0x22, 0x38, 0x31, 0x38,
+    0x64, 0x32, 0x37, 0x64, 0x33, 0x65, 0x66, 0x61, 0x39, 0x35, 0x37, 0x31,
+    0x62, 0x61, 0x30, 0x66, 0x66, 0x31, 0x65, 0x36, 0x32, 0x34, 0x33, 0x62,
+    0x30, 0x39, 0x34, 0x35, 0x62, 0x63, 0x63, 0x36, 0x39, 0x33, 0x65, 0x62,
+    0x37, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x22, 0x69, 0x63, 0x6f, 0x6e, 0x2e,
+    0x70, 0x6e, 0x67, 0x22, 0x20, 0x3a, 0x20, 0x22, 0x62, 0x65, 0x64, 0x66,
+    0x30, 0x30, 0x61, 0x61, 0x62, 0x32, 0x32, 0x31, 0x61, 0x63, 0x37, 0x31,
+    0x64, 0x33, 0x66, 0x66, 0x65, 0x64, 0x64, 0x33, 0x32, 0x63, 0x33, 0x63,
+    0x64, 0x36, 0x63, 0x32, 0x35, 0x30, 0x33, 0x32, 0x62, 0x61, 0x34, 0x30,
+    0x22, 0x2c, 0x0a, 0x20, 0x20, 0x22, 0x70, 0x61, 0x73, 0x73, 0x2e, 0x6a,
+    0x73, 0x6f, 0x6e, 0x22, 0x20, 0x3a, 0x20, 0x22, 0x32, 0x61, 0x35, 0x66,
+    0x38, 0x66, 0x34, 0x37, 0x66, 0x34, 0x61, 0x33, 0x38, 0x37, 0x35, 0x35,
+    0x36, 0x62, 0x31, 0x65, 0x61, 0x30, 0x65, 0x64, 0x64, 0x36, 0x39, 0x65,
+    0x64, 0x31, 0x64, 0x62, 0x61, 0x39, 0x37, 0x39, 0x64, 0x32, 0x66, 0x33,
+    0x22, 0x2c, 0x0a, 0x20, 0x20, 0x22, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x70,
+    0x6e, 0x67, 0x22, 0x20, 0x3a, 0x20, 0x22, 0x39, 0x30, 0x62, 0x63, 0x62,
+    0x39, 0x34, 0x62, 0x62, 0x30, 0x66, 0x31, 0x30, 0x33, 0x66, 0x36, 0x63,
+    0x32, 0x63, 0x32, 0x36, 0x35, 0x35, 0x33, 0x36, 0x66, 0x65, 0x61, 0x63,
+    0x37, 0x61, 0x38, 0x38, 0x33, 0x36, 0x37, 0x30, 0x34, 0x34, 0x33, 0x22,
+    0x2c, 0x0a, 0x20, 0x20, 0x22, 0x2e, 0x44, 0x53, 0x5f, 0x53, 0x74, 0x6f,
+    0x72, 0x65, 0x22, 0x20, 0x3a, 0x20, 0x22, 0x64, 0x66, 0x32, 0x66, 0x62,
+    0x65, 0x62, 0x31, 0x34, 0x30, 0x30, 0x61, 0x63, 0x64, 0x61, 0x30, 0x39,
+    0x30, 0x39, 0x61, 0x33, 0x32, 0x63, 0x31, 0x63, 0x66, 0x36, 0x62, 0x66,
+    0x34, 0x39, 0x32, 0x66, 0x31, 0x31, 0x32, 0x31, 0x65, 0x30, 0x37, 0x22,
+    0x2c, 0x0a, 0x20, 0x20, 0x22, 0x6c, 0x6f, 0x67, 0x6f, 0x40, 0x32, 0x78,
+    0x2e, 0x70, 0x6e, 0x67, 0x22, 0x20, 0x3a, 0x20, 0x22, 0x39, 0x30, 0x62,
+    0x63, 0x62, 0x39, 0x34, 0x62, 0x62, 0x30, 0x66, 0x31, 0x30, 0x33, 0x66,
+    0x36, 0x63, 0x32, 0x63, 0x32, 0x36, 0x35, 0x35, 0x33, 0x36, 0x66, 0x65,
+    0x61, 0x63, 0x37, 0x61, 0x38, 0x38, 0x33, 0x36, 0x37, 0x30, 0x34, 0x34,
+    0x33, 0x22, 0x0a, 0x7d
+};
+
+
+static void test_sig_verification(void)
+{
+    SecPolicyRef policy;
+
+    CFDataRef goodSig = CFDataCreate(NULL, (const UInt8*) _USAirwaysCorrect_signature,
+                                     sizeof(_USAirwaysCorrect_signature));
+    CFDataRef goodManifest = CFDataCreate(NULL, (const UInt8*) _USAirwaysCorrect_manifest_json,
+                                     sizeof(_USAirwaysCorrect_manifest_json));
+    CFDataRef badSig = CFDataCreate(NULL, (const UInt8*) _USAirwaysWrongTeamID_signature,
+                                    sizeof(_USAirwaysWrongTeamID_signature));
+    CFDataRef badManifest = CFDataCreate(NULL, (const UInt8*) _USAirwaysWrongTeamID_manifest_json,
+                                    sizeof(_USAirwaysWrongTeamID_manifest_json));
+
+    /*
+     OSStatus SecCMSVerifySignedData(CFDataRef message, CFDataRef detached_contents,
+     SecPolicyRef policy, SecTrustRef *trustref, CFArrayRef additional_certificates,
+     CFDataRef *attached_contents, CFDictionaryRef *message_attributes)
+     */
+
+    /* Case 1: verify signature with good values */
+    isnt(policy = SecPolicyCreatePassbookCardSigner(CFSTR("pass.com.apple.cardman"), CFSTR("A1B2C3D4E5")),
+         NULL, "create policy");
+    ok_status(SecCMSVerifySignedData(goodSig, goodManifest, policy, NULL, NULL, NULL, NULL), "verify signed data 1");
+    CFReleaseNull(policy);
+    CFRelease(goodManifest);
+    CFRelease(goodSig);
+    policy = NULL;
+
+    /* Case 2: verify signature with bad values */
+    isnt(policy = SecPolicyCreatePassbookCardSigner(CFSTR("pass.com.apple.cardman"), CFSTR("IAMBOGUS")),
+         NULL, "create policy");
+    isnt(SecCMSVerifySignedData(badSig, badManifest, policy, NULL, NULL, NULL, NULL), errSecSuccess, "verify signed data 2");
+    CFReleaseNull(policy);
+    policy = NULL;
+
+
+    /* Case 3: get trust reference back from SecCMSVerifySignedData and verify it ourselves */
+    SecTrustRef trust = NULL;
+    SecTrustResultType trustResult;
+    isnt(policy = SecPolicyCreatePassbookCardSigner(CFSTR("pass.com.apple.cardman"), CFSTR("IAMBOGUS")),
+         NULL, "create policy");
+    ok_status(SecCMSVerifySignedData(badSig, badManifest, policy, &trust, NULL, NULL, NULL), "verify signed data 3");
+    isnt(trust, NULL, "get trust");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+       ok(trustResult == kSecTrustResultRecoverableTrustFailure, "recoverable trustResult expected (ok)");
+       CFReleaseNull(trust);
+       CFRelease(badManifest);
+       CFRelease(badSig);
+       trust = NULL;
+}
+
+static void tests(void)
+{
+       /* Aug 1st 2012. */
+       CFGregorianDate g_date = { 2012, 8, 1, 12, 0, 0 }; // Aug 1 2012 12:00 PM
+       CFDateRef date;
+       CFArrayRef policies;
+       SecPolicyRef policy;
+       SecTrustRef trust;
+    SecCertificateRef cert0, cert1;
+       CFMutableArrayRef certs;
+       SecTrustResultType trustResult;
+
+    isnt(cert0 = SecCertificateCreateWithBytes(NULL, _leaf, sizeof(_leaf)),
+           NULL, "create cert0");
+    isnt(cert1 = SecCertificateCreateWithBytes(NULL, _wwdrca, sizeof(_wwdrca)),
+           NULL, "create cert1");
+    isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0,
+        &kCFTypeArrayCallBacks), NULL, "create cert array");
+    CFArrayAppendValue(certs, cert0);
+    CFArrayAppendValue(certs, cert1);
+
+       /* Case 1: make sure known-good values cause policy to succeed */
+    isnt(policy = SecPolicyCreatePassbookCardSigner(CFSTR("pass.com.apple.cardman"), CFSTR("A1B2C3D4E5")),
+               NULL, "create policy");
+    policies = CFArrayCreate(NULL, (const void **)&policy, 1, &kCFTypeArrayCallBacks);
+    CFRelease(policy);
+       policy = NULL;
+    ok_status(SecTrustCreateWithCertificates(certs, policies, &trust),
+        "create trust");
+       CFRelease(policies);
+       policies = NULL;
+       isnt(date = CFDateCreate(kCFAllocatorDefault,
+                       CFGregorianDateGetAbsoluteTime(g_date, NULL)),
+                       NULL, "create verify date");
+       ok_status(SecTrustSetVerifyDate(trust, date), "set date");
+       CFReleaseSafe(date);
+       date = NULL;
+
+       ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+       ok(trustResult == kSecTrustResultUnspecified, "unspecified trustResult expected (ok)");
+       CFRelease(trust);
+       trust = NULL;
+
+       /* Case 2: make sure known-bad card identifier value causes policy to fail */
+    isnt(policy = SecPolicyCreatePassbookCardSigner(CFSTR("pass.com.scuzzo.cardman"), CFSTR("A1B2C3D4E5")),
+               NULL, "create policy");
+    policies = CFArrayCreate(NULL, (const void **)&policy, 1, &kCFTypeArrayCallBacks);
+    CFRelease(policy);
+       policy = NULL;
+    ok_status(SecTrustCreateWithCertificates(certs, policies, &trust),
+        "create trust");
+       CFRelease(policies);
+       policies = NULL;
+       isnt(date = CFDateCreate(kCFAllocatorDefault,
+                       CFGregorianDateGetAbsoluteTime(g_date, NULL)),
+                       NULL, "create verify date");
+       ok_status(SecTrustSetVerifyDate(trust, date), "set date");
+       CFReleaseNull(date);
+       date = NULL;
+
+       ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+       ok(trustResult == kSecTrustResultRecoverableTrustFailure, "recoverable trustResult expected (ok)");
+       CFRelease(trust);
+       trust = NULL;
+
+       /* Case 3: make sure known-bad teamID value causes policy to fail */
+    isnt(policy = SecPolicyCreatePassbookCardSigner(CFSTR("pass.com.apple.cardman"), CFSTR("01B2C3D4E5")),
+               NULL, "create policy");
+    policies = CFArrayCreate(NULL, (const void **)&policy, 1, &kCFTypeArrayCallBacks);
+    CFRelease(policy);
+       policy = NULL;
+    ok_status(SecTrustCreateWithCertificates(certs, policies, &trust),
+        "create trust");
+       CFRelease(policies);
+       policies = NULL;
+       isnt(date = CFDateCreate(kCFAllocatorDefault,
+                       CFGregorianDateGetAbsoluteTime(g_date, NULL)),
+                       NULL, "create verify date");
+       ok_status(SecTrustSetVerifyDate(trust, date), "set date");
+       CFReleaseNull(date);
+       date = NULL;
+
+       ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+       ok(trustResult == kSecTrustResultRecoverableTrustFailure, "recoverable trustResult expected (ok)");
+       CFRelease(trust);
+       trust = NULL;
+
+    test_sig_verification();
+
+    CFGregorianDate whenWritten = {
+        .year = 2012,
+        .month  = 5,
+        .day    = 10,
+        .hour   = 0,
+        .minute = 0,
+        .second = 0,
+    };
+
+    SecPolicyRef shoeboxPolicy = SecPolicyCreatePassbookCardSigner(CFSTR("com.apple.testcard"),
+                                          CFSTR("A1B2C3D4E5"));
+
+    /* Run the tests. */
+    runCertificateTestForDirectory(shoeboxPolicy, CFSTR("Shoebox"), &whenWritten);
+
+    CFReleaseSafe(shoeboxPolicy);
+}
+
+int si_24_sectrust_shoebox(int argc, char *const *argv)
+{
+       plan_tests(31);
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-25-sectrust-ipsec-eap.c b/sec/Security/Regressions/secitem/si-25-sectrust-ipsec-eap.c
new file mode 100644 (file)
index 0000000..d563064
--- /dev/null
@@ -0,0 +1,783 @@
+/*
+ *  Copyright (c) 2008-2010 Apple Inc. All Rights Reserved.
+ *
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecPolicyPriv.h>
+#include <Security/SecTrust.h>
+#include <Security/SecInternal.h>
+#include <utilities/array_size.h>
+
+#include "Security_regressions.h"
+
+
+/*
+openssl req -newkey rsa:2048 -sha1 -days 365 -sha1 \
+    -subj "/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Root CA" \
+    -nodes -keyout CA-key.pem -out CA-csr.pem
+openssl x509 -req -sha1 -in CA-csr.pem -signkey CA-key.pem -set_serial 0 -out CA-cert.pem
+
+openssl req -newkey rsa:1024 -sha1 \
+    -subj "/O=Apple Inc./OU=IS&T/CN=IPSec Gateway/C=US/ST=California/L=Cupertino" \
+    -nodes -out ipsec-csr.pem -keyout ipsec-key.pem
+openssl x509 -req -in ipsec-csr.pem -CA CA-cert.pem -CAkey CA-key.pem -set_serial 1 \
+    -out ipsec-cert.pem -extfile ext.txt -extensions v3_req
+
+[ v3_req ]
+keyUsage = digitalSignature, keyEncipherment
+subjectAltName=email:user@fqdn.com,DNS:ipsec.apple.com,IP:17.255.42.2,DNS:ipsec2.apple.com,IP:17.255.42.1
+
+*/
+
+/* subject:/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Root CA */
+/* issuer :/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Root CA */
+unsigned char _ca_certificate[828]={
+0x30,0x82,0x03,0x38,0x30,0x82,0x02,0x20,0x02,0x01,0x00,0x30,0x0D,0x06,0x09,0x2A,
+0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x62,0x31,0x0B,0x30,0x09,
+0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
+0x04,0x0A,0x13,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x26,
+0x30,0x24,0x06,0x03,0x55,0x04,0x0B,0x13,0x1D,0x41,0x70,0x70,0x6C,0x65,0x20,0x43,
+0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,
+0x68,0x6F,0x72,0x69,0x74,0x79,0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x03,0x13,
+0x0D,0x41,0x70,0x70,0x6C,0x65,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x30,0x1E,
+0x17,0x0D,0x30,0x39,0x31,0x31,0x31,0x33,0x32,0x32,0x30,0x37,0x32,0x35,0x5A,0x17,
+0x0D,0x30,0x39,0x31,0x32,0x31,0x33,0x32,0x32,0x30,0x37,0x32,0x35,0x5A,0x30,0x62,
+0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,
+0x11,0x06,0x03,0x55,0x04,0x0A,0x13,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x6E,
+0x63,0x2E,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0B,0x13,0x1D,0x41,0x70,0x70,
+0x6C,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,
+0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x31,0x16,0x30,0x14,0x06,0x03,
+0x55,0x04,0x03,0x13,0x0D,0x41,0x70,0x70,0x6C,0x65,0x20,0x52,0x6F,0x6F,0x74,0x20,
+0x43,0x41,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,
+0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,
+0x01,0x01,0x00,0xD3,0x61,0x56,0x8A,0xF3,0x52,0x4C,0xAF,0xB3,0xF8,0x27,0x74,0x53,
+0x32,0x2F,0xB8,0x38,0xB1,0x58,0x43,0x3A,0x82,0x22,0xA2,0x54,0x78,0xB4,0xBD,0x96,
+0x94,0xD9,0x43,0x00,0xA3,0x5F,0x83,0xF5,0xFB,0x4C,0x8F,0x40,0xE6,0xC4,0x36,0xD7,
+0xF4,0x4A,0x9C,0xA1,0x03,0xCE,0x9F,0x28,0x01,0x07,0x29,0x40,0x69,0xA9,0xC7,0xF0,
+0x0A,0x2F,0x76,0xC7,0x44,0xE3,0xA5,0x1C,0xC9,0x49,0x0A,0xFA,0x89,0xC8,0x00,0x48,
+0x05,0x68,0xC9,0x20,0x15,0xC1,0x2D,0xDB,0x3C,0x2C,0xD5,0xE8,0xC2,0xC0,0x31,0x14,
+0x72,0x58,0xE1,0xBE,0x47,0xB4,0xEE,0xA8,0x77,0x33,0xB6,0xC0,0x55,0x77,0x66,0x52,
+0x1C,0xDF,0x71,0x23,0x99,0x28,0xCA,0x3F,0x08,0xC6,0x20,0x02,0xAB,0xC4,0x57,0x50,
+0x6B,0xB1,0xCF,0x85,0xEF,0x76,0xF6,0x97,0xF5,0x3E,0x0B,0xEC,0xC1,0x26,0xC2,0xF9,
+0xD4,0x9E,0xE5,0x8E,0x30,0xD6,0x94,0xC7,0x0E,0x64,0x6B,0x73,0x36,0xF4,0xF7,0xB6,
+0xD5,0xC7,0x69,0xF4,0xBC,0xCF,0x63,0x72,0xB0,0xDD,0xB9,0x46,0x5C,0xE0,0xD7,0x4D,
+0x20,0xC7,0xE8,0xFD,0x2D,0x7A,0x81,0x34,0xF8,0x26,0x4C,0x83,0x02,0x80,0x33,0xB1,
+0x24,0x95,0xE5,0x10,0x98,0xC1,0x95,0xF0,0x43,0xC2,0x8D,0x8A,0x0E,0x33,0x68,0xAC,
+0x17,0xA6,0x68,0x7D,0xC9,0xEC,0xEC,0x17,0x1F,0xD2,0x01,0x11,0x02,0x09,0x12,0x75,
+0x40,0xCC,0x28,0xE2,0x1B,0xCC,0xC2,0x2B,0xF2,0xDC,0x4D,0x71,0x5B,0x28,0x6F,0x30,
+0x16,0x22,0xDA,0x87,0x92,0x7B,0x43,0x09,0x1F,0x89,0x8C,0xDD,0x8F,0xD9,0xD2,0xB9,
+0x88,0xDE,0xA3,0x02,0x03,0x01,0x00,0x01,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,
+0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x66,0x29,0x32,0x2C,
+0x4B,0x10,0x82,0xFA,0x90,0x18,0xC5,0x0C,0x1F,0xC5,0x42,0x47,0x48,0xEF,0x0A,0x16,
+0xFE,0x46,0xF8,0x81,0x4C,0x1B,0x43,0x3B,0x66,0x66,0xDD,0xBB,0xFF,0x9A,0xE9,0xAD,
+0x92,0xC1,0x56,0xB3,0x3F,0x04,0xEE,0x0C,0x7C,0x4F,0xCE,0x39,0xC4,0x24,0x39,0x3C,
+0x6F,0x08,0x02,0x44,0xEE,0x25,0x22,0x01,0x14,0x55,0x05,0xB6,0x5C,0x92,0x34,0x8C,
+0x37,0x33,0xAB,0xD3,0xBD,0x28,0xF2,0x88,0x96,0xDF,0x4F,0xE1,0x45,0x73,0x9D,0x1A,
+0x56,0x6D,0x06,0x0C,0x38,0xAC,0xCA,0x83,0xAF,0xCB,0x3F,0xF2,0xF4,0x78,0x5D,0x2E,
+0x1D,0x52,0x26,0x60,0x4D,0xE4,0x7D,0xDE,0x41,0xE5,0x98,0x10,0x59,0x7E,0x36,0x94,
+0x74,0x45,0xE8,0x3E,0x0E,0x1A,0xE7,0x8C,0xE5,0xD8,0x35,0x97,0x1E,0xA8,0x25,0x22,
+0x07,0xA6,0x6E,0x39,0x22,0x35,0x85,0xBD,0xDC,0x8B,0x49,0x9B,0x9C,0xA5,0xE4,0xBF,
+0xD8,0x9D,0x18,0x27,0x24,0x7F,0x7D,0x07,0x7A,0x2A,0xBA,0x94,0x63,0x9C,0x03,0xA0,
+0x41,0x1E,0x12,0x0F,0xA9,0xA9,0x6A,0x16,0xA9,0x3C,0x4A,0x12,0xBB,0x15,0xBA,0xD2,
+0x1C,0xA2,0x74,0x29,0xD5,0xBE,0x5C,0x1B,0x87,0x82,0x5B,0x25,0x01,0xF6,0x91,0x8F,
+0x7B,0xCC,0x2C,0x92,0x65,0xE9,0x6F,0xFA,0x09,0x2D,0xE2,0x40,0xA0,0x81,0x30,0xDE,
+0xD3,0x96,0x3A,0x2C,0x5E,0x0C,0xEE,0x10,0xA7,0x7D,0x9B,0xDC,0x75,0x06,0x41,0x4A,
+0x8D,0x31,0x04,0x2C,0x9E,0xAD,0xED,0xD5,0xF8,0x08,0xBA,0xBD,0x4C,0xBE,0x1F,0xC6,
+0x6C,0x03,0xC5,0x79,0x26,0xDA,0x79,0x21,0xCA,0x5C,0x3A,0xEC,
+};
+
+/* subject:/O=Apple Inc./OU=IS&T/CN=IPSec Gateway/C=US/ST=California/L=Cupertino */
+/* issuer :/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Root CA */
+unsigned char _ipsec_certificate[807]={
+0x30,0x82,0x03,0x23,0x30,0x82,0x02,0x0B,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x01,
+0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,
+0x62,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,
+0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x13,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,
+0x6E,0x63,0x2E,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0B,0x13,0x1D,0x41,0x70,
+0x70,0x6C,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,
+0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x31,0x16,0x30,0x14,0x06,
+0x03,0x55,0x04,0x03,0x13,0x0D,0x41,0x70,0x70,0x6C,0x65,0x20,0x52,0x6F,0x6F,0x74,
+0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x30,0x39,0x31,0x31,0x31,0x33,0x32,0x32,0x30,
+0x37,0x33,0x37,0x5A,0x17,0x0D,0x30,0x39,0x31,0x32,0x31,0x33,0x32,0x32,0x30,0x37,
+0x33,0x37,0x5A,0x30,0x72,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x13,0x0A,
+0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x0D,0x30,0x0B,0x06,0x03,
+0x55,0x04,0x0B,0x14,0x04,0x49,0x53,0x26,0x54,0x31,0x16,0x30,0x14,0x06,0x03,0x55,
+0x04,0x03,0x13,0x0D,0x49,0x50,0x53,0x65,0x63,0x20,0x47,0x61,0x74,0x65,0x77,0x61,
+0x79,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,
+0x30,0x11,0x06,0x03,0x55,0x04,0x08,0x13,0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,
+0x6E,0x69,0x61,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x07,0x13,0x09,0x43,0x75,
+0x70,0x65,0x72,0x74,0x69,0x6E,0x6F,0x30,0x81,0x9F,0x30,0x0D,0x06,0x09,0x2A,0x86,
+0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8D,0x00,0x30,0x81,0x89,
+0x02,0x81,0x81,0x00,0xBB,0xA8,0x14,0x61,0x78,0x57,0x5A,0x23,0xC0,0xDA,0xC9,0xF0,
+0x16,0x46,0x61,0xDA,0x48,0x5F,0xA7,0x0E,0xED,0x66,0xA8,0xBD,0x5A,0x4E,0x70,0xA4,
+0xEB,0x65,0xB0,0x4C,0xF7,0x72,0xF6,0x51,0xCD,0xB1,0xAF,0x39,0xEF,0x9B,0x9E,0xDF,
+0xA9,0x08,0xC1,0xF0,0xCF,0x54,0x9D,0x54,0xD1,0x4F,0xDE,0x95,0xE9,0xF5,0xD1,0xB2,
+0x17,0x9E,0x00,0x29,0x42,0x3F,0xD2,0x6A,0x0C,0xFB,0x71,0xC4,0x8A,0x4E,0x21,0x7B,
+0xAB,0x98,0xBA,0x5C,0x8E,0x7D,0x2E,0xF4,0x1C,0x33,0x6E,0x3C,0x92,0x18,0xA0,0xBD,
+0x23,0x05,0xBF,0xAB,0xE4,0xF5,0x2C,0xA6,0x55,0x69,0x43,0xA7,0xFA,0x52,0xB0,0x57,
+0x51,0xC5,0xF8,0xC4,0xE0,0x81,0x30,0x56,0x49,0xB8,0x6D,0xF0,0xAE,0xF8,0xAC,0xF0,
+0x43,0xAC,0x0D,0xB3,0x02,0x03,0x01,0x00,0x01,0xA3,0x58,0x30,0x56,0x30,0x0B,0x06,
+0x03,0x55,0x1D,0x0F,0x04,0x04,0x03,0x02,0x05,0xA0,0x30,0x47,0x06,0x03,0x55,0x1D,
+0x11,0x04,0x40,0x30,0x3E,0x81,0x0D,0x75,0x73,0x65,0x72,0x40,0x66,0x71,0x64,0x6E,
+0x2E,0x63,0x6F,0x6D,0x82,0x0F,0x69,0x70,0x73,0x65,0x63,0x2E,0x61,0x70,0x70,0x6C,
+0x65,0x2E,0x63,0x6F,0x6D,0x87,0x04,0x11,0xFF,0x2A,0x02,0x82,0x10,0x69,0x70,0x73,
+0x65,0x63,0x32,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x87,0x04,0x11,
+0xFF,0x2A,0x01,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,
+0x05,0x00,0x03,0x82,0x01,0x01,0x00,0xB3,0x75,0x2A,0xD1,0xB5,0x54,0x87,0x57,0x59,
+0xD2,0x38,0x99,0x4E,0xFE,0x0E,0x02,0x0D,0x50,0x95,0xE8,0x14,0x12,0x76,0x18,0x98,
+0x14,0xD4,0xDE,0xCA,0x1D,0x25,0x86,0xDA,0x3E,0x47,0x64,0x67,0xDB,0x0B,0x17,0x5E,
+0xF1,0xF2,0x8A,0xB9,0xC2,0xB5,0xCA,0x53,0x4B,0x6E,0x20,0xA3,0xE2,0xEE,0x51,0xE0,
+0xD7,0xD1,0x46,0x21,0x40,0x82,0x32,0x25,0x6F,0x70,0x17,0xA7,0xE1,0xF6,0xD0,0x71,
+0xA4,0x58,0xDF,0x54,0x2F,0x49,0xFE,0x93,0x2C,0x47,0x46,0x54,0xF8,0x0E,0xC5,0xFF,
+0x57,0xE5,0x59,0xAF,0xCF,0xF6,0xEB,0x1F,0x43,0xAB,0x1D,0x0E,0xF2,0x22,0x5C,0x96,
+0x52,0x40,0xDE,0xA5,0xE6,0xB2,0xE6,0xFC,0x4D,0x89,0xC3,0x5E,0x27,0x32,0xBD,0xFD,
+0x70,0x50,0xA6,0x57,0x94,0x8A,0xDA,0x9B,0x74,0xCB,0x43,0xD8,0x8E,0x78,0x8B,0x52,
+0x0C,0x0E,0x11,0x8E,0x34,0xA2,0x8B,0x52,0x18,0x15,0xB2,0x06,0xA9,0x27,0x44,0x5D,
+0x6D,0x3C,0xE1,0x66,0x89,0x4D,0xE3,0x2B,0x19,0x96,0x0D,0x44,0xC5,0x79,0xF0,0x10,
+0x76,0x38,0xBC,0xA1,0x99,0x84,0x5D,0x30,0x5A,0x04,0x61,0x75,0x1B,0xC1,0x88,0xD7,
+0x5E,0xAB,0xA6,0xA8,0x9C,0x2C,0xDA,0xE7,0xDB,0x73,0x19,0x40,0xF0,0x46,0xC5,0x15,
+0xEA,0x6B,0x22,0x69,0x49,0xE1,0xD4,0x8C,0xA7,0xB1,0xAA,0x98,0x3D,0x7B,0x7F,0x1C,
+0x8F,0xAF,0x29,0x00,0xE4,0xEE,0x28,0xF6,0xF6,0x94,0x40,0x89,0x60,0x99,0xF4,0xDE,
+0xEE,0xDE,0x43,0x04,0x5D,0x19,0x9D,0x56,0xE3,0xBC,0x8A,0xD6,0xA7,0x0C,0xCF,0xED,
+0x1E,0x8B,0x86,0xE7,0x34,0xA6,0x56,
+};
+
+unsigned char ivpntest_com_root_der[] = {
+  0x30, 0x82, 0x04, 0x98, 0x30, 0x82, 0x03, 0x80, 0xa0, 0x03, 0x02, 0x01,
+  0x02, 0x02, 0x10, 0x7a, 0xdb, 0x4e, 0x56, 0x1a, 0xb8, 0x90, 0xae, 0x46,
+  0x6f, 0x06, 0x74, 0x44, 0x09, 0x68, 0x87, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x4e,
+  0x31, 0x13, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2,
+  0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x63, 0x6f, 0x6d, 0x31, 0x18, 0x30,
+  0x16, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01,
+  0x19, 0x16, 0x08, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x31,
+  0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x71, 0x61,
+  0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65,
+  0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39,
+  0x30, 0x31, 0x32, 0x38, 0x30, 0x32, 0x34, 0x33, 0x33, 0x30, 0x5a, 0x17,
+  0x0d, 0x31, 0x34, 0x30, 0x31, 0x32, 0x38, 0x30, 0x32, 0x35, 0x32, 0x34,
+  0x33, 0x5a, 0x30, 0x4e, 0x31, 0x13, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92,
+  0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x63, 0x6f,
+  0x6d, 0x31, 0x18, 0x30, 0x16, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
+  0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x08, 0x69, 0x76, 0x70, 0x6e, 0x74,
+  0x65, 0x73, 0x74, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03,
+  0x13, 0x14, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76,
+  0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82,
+  0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82,
+  0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xbe, 0xf8, 0xff, 0x61, 0xca,
+  0x9d, 0xcf, 0x07, 0x4d, 0x06, 0xf4, 0x52, 0x4b, 0x3f, 0x84, 0xc5, 0x0b,
+  0x71, 0xef, 0x7f, 0x7d, 0x35, 0xac, 0x68, 0xce, 0x84, 0xe6, 0x7c, 0x0a,
+  0xba, 0x02, 0x71, 0xcf, 0x81, 0x40, 0xcb, 0x25, 0xdb, 0x41, 0x23, 0x84,
+  0x88, 0x4d, 0x16, 0xa2, 0x41, 0xa5, 0x2a, 0x98, 0xa3, 0xb7, 0x02, 0xff,
+  0x54, 0xb6, 0xd5, 0x55, 0x75, 0x17, 0xbc, 0xd5, 0x04, 0x24, 0x35, 0x63,
+  0xfa, 0xcb, 0x98, 0x38, 0x98, 0x18, 0xd3, 0x13, 0xc1, 0xef, 0x1a, 0xfe,
+  0xb7, 0xcd, 0x2e, 0xc2, 0xb8, 0x0d, 0x3e, 0x62, 0x38, 0xc0, 0x05, 0xf9,
+  0x5b, 0xc5, 0xd5, 0xf6, 0xc4, 0x9d, 0x8e, 0xc3, 0x90, 0x32, 0xa2, 0xb1,
+  0x88, 0xa8, 0xf9, 0xd3, 0x0d, 0x02, 0x8d, 0xbe, 0x8f, 0x41, 0xe7, 0x92,
+  0x85, 0xe7, 0x4c, 0x11, 0x9a, 0x4b, 0xfb, 0x00, 0xa9, 0x9f, 0xf5, 0xfb,
+  0x23, 0xda, 0xf1, 0xfd, 0x95, 0x89, 0xd5, 0x2b, 0xc5, 0xbf, 0x9c, 0xc3,
+  0x93, 0xd0, 0xc2, 0xf8, 0x12, 0xbe, 0x26, 0x24, 0x41, 0x80, 0x64, 0x2f,
+  0xc0, 0x7b, 0x31, 0x85, 0x06, 0x3c, 0xe4, 0xc6, 0x7e, 0xbc, 0x61, 0xa7,
+  0xa2, 0xf4, 0xa7, 0xd7, 0xd7, 0xcb, 0xeb, 0xea, 0xb0, 0xc6, 0xd7, 0x13,
+  0xd6, 0x09, 0xfa, 0x45, 0xc6, 0x25, 0x6f, 0x34, 0xdc, 0x78, 0x70, 0xa0,
+  0xa5, 0xea, 0xd7, 0xe7, 0xda, 0xe2, 0x5a, 0x7a, 0xc3, 0xe3, 0x7a, 0x8d,
+  0xf3, 0x5a, 0x78, 0xfa, 0x57, 0xe1, 0xf1, 0xae, 0x6b, 0xea, 0x83, 0xd0,
+  0xd7, 0xa9, 0x43, 0x2d, 0x5d, 0x8b, 0xac, 0xbb, 0x92, 0x5b, 0x2a, 0xd7,
+  0x27, 0xbe, 0xe7, 0xa0, 0xd2, 0xc5, 0x9b, 0xd7, 0xa4, 0xc1, 0x6a, 0xf8,
+  0xec, 0xfc, 0xa6, 0x96, 0xfc, 0x09, 0x11, 0x95, 0xca, 0x75, 0xab, 0x8a,
+  0x5b, 0xd2, 0xb2, 0xb4, 0x11, 0xf1, 0x88, 0x34, 0xe3, 0xb7, 0x21, 0x02,
+  0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x70, 0x30, 0x82, 0x01, 0x6c,
+  0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01,
+  0x86, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04,
+  0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
+  0x0e, 0x04, 0x16, 0x04, 0x14, 0x40, 0xb5, 0x54, 0x10, 0x88, 0x09, 0xeb,
+  0x3e, 0x2e, 0x69, 0x82, 0xa6, 0xa0, 0xd8, 0xe4, 0xb0, 0x98, 0xc1, 0x69,
+  0x3d, 0x30, 0x82, 0x01, 0x19, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x82,
+  0x01, 0x10, 0x30, 0x82, 0x01, 0x0c, 0x30, 0x82, 0x01, 0x08, 0xa0, 0x82,
+  0x01, 0x04, 0xa0, 0x82, 0x01, 0x00, 0x86, 0x81, 0xbc, 0x6c, 0x64, 0x61,
+  0x70, 0x3a, 0x2f, 0x2f, 0x2f, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72,
+  0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74,
+  0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72,
+  0x76, 0x31, 0x30, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x44, 0x50, 0x2c, 0x43,
+  0x4e, 0x3d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30, 0x4b,
+  0x65, 0x79, 0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+  0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+  0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75,
+  0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x69, 0x76,
+  0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f,
+  0x6d, 0x3f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+  0x65, 0x52, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c,
+  0x69, 0x73, 0x74, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a,
+  0x65, 0x63, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x52, 0x4c,
+  0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e,
+  0x50, 0x6f, 0x69, 0x6e, 0x74, 0x86, 0x3f, 0x68, 0x74, 0x74, 0x70, 0x3a,
+  0x2f, 0x2f, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76,
+  0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43,
+  0x65, 0x72, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x71, 0x61,
+  0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65,
+  0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x10,
+  0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x01, 0x04,
+  0x03, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00,
+  0x07, 0x74, 0x27, 0x8c, 0xdd, 0x75, 0xa1, 0x0d, 0x97, 0xd1, 0x9d, 0x0d,
+  0xae, 0x3b, 0xf3, 0x14, 0x0f, 0xa1, 0x1c, 0x51, 0xd8, 0x68, 0xe7, 0xfd,
+  0xd0, 0xaf, 0xe7, 0x66, 0x62, 0xf8, 0x73, 0x75, 0x88, 0x6c, 0xb9, 0xb3,
+  0x1e, 0xf5, 0x82, 0x3a, 0x1d, 0x82, 0x7b, 0xa3, 0x18, 0xd9, 0x1a, 0x40,
+  0xf2, 0xcd, 0xb3, 0x83, 0xae, 0x12, 0x5b, 0xb4, 0x45, 0xd9, 0xbe, 0x51,
+  0x3e, 0x11, 0x64, 0xaf, 0x95, 0x06, 0xb6, 0xbd, 0xd1, 0xa1, 0xfd, 0xbb,
+  0xdb, 0xa4, 0xbb, 0xba, 0x3e, 0xd5, 0xd6, 0x1d, 0x37, 0x80, 0x17, 0xe8,
+  0x08, 0x75, 0x5f, 0x5d, 0x49, 0x5f, 0x70, 0xdd, 0x67, 0xde, 0x9a, 0x34,
+  0x95, 0x2e, 0x54, 0x58, 0x42, 0xaf, 0x8a, 0x57, 0xf2, 0xb4, 0x1f, 0xfb,
+  0x40, 0x9c, 0x05, 0xa0, 0x6a, 0x9a, 0x91, 0x0e, 0x27, 0xaa, 0x9e, 0xdb,
+  0xbf, 0x50, 0xc9, 0xa4, 0x2f, 0xc8, 0x71, 0x00, 0x11, 0xf8, 0x2f, 0xda,
+  0x98, 0xf4, 0x1d, 0x98, 0x2a, 0xe9, 0x29, 0xc7, 0xea, 0x74, 0x65, 0xf1,
+  0x6d, 0x06, 0x9f, 0x59, 0xa3, 0x50, 0x7e, 0x1b, 0x52, 0x5a, 0xb9, 0x5e,
+  0xce, 0xa0, 0x03, 0x53, 0xe8, 0xba, 0x36, 0x4a, 0xc2, 0x95, 0xdb, 0x34,
+  0x61, 0xc8, 0xf4, 0xa5, 0x7c, 0xd6, 0x9d, 0x64, 0x91, 0xfb, 0x23, 0xfd,
+  0x8b, 0x3a, 0xd2, 0x67, 0xb0, 0x64, 0xa7, 0x80, 0x82, 0x74, 0x85, 0x45,
+  0xa7, 0x78, 0x57, 0xb6, 0xf0, 0x0a, 0xf9, 0xa2, 0xb5, 0x7f, 0x7e, 0x88,
+  0x21, 0xd7, 0x67, 0xd2, 0xc4, 0x9c, 0x98, 0x51, 0x9b, 0x71, 0xfb, 0x39,
+  0xf2, 0xb3, 0xfd, 0x3f, 0x0b, 0x61, 0x59, 0xa0, 0x15, 0x40, 0x53, 0x71,
+  0xac, 0xf5, 0xf7, 0xee, 0x03, 0x6b, 0x1f, 0x5d, 0x29, 0x0a, 0xf7, 0x4f,
+  0x1a, 0xea, 0xa4, 0xb8, 0x02, 0x63, 0x7c, 0x37, 0x37, 0xdd, 0x46, 0x42,
+  0xe3, 0xe1, 0x82, 0x94
+};
+unsigned int ivpntest_com_root_der_len = 1180;
+
+unsigned char vpn3000_id_cer[] = {
+  0x30, 0x82, 0x06, 0x84, 0x30, 0x82, 0x05, 0x6c, 0xa0, 0x03, 0x02, 0x01,
+  0x02, 0x02, 0x0a, 0x14, 0xb8, 0xa0, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x2a, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x01, 0x05, 0x05, 0x00, 0x30, 0x4e, 0x31, 0x13, 0x30, 0x11, 0x06, 0x0a,
+  0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03,
+  0x63, 0x6f, 0x6d, 0x31, 0x18, 0x30, 0x16, 0x06, 0x0a, 0x09, 0x92, 0x26,
+  0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x08, 0x69, 0x76, 0x70,
+  0x6e, 0x74, 0x65, 0x73, 0x74, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55,
+  0x04, 0x03, 0x13, 0x14, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e,
+  0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
+  0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, 0x30, 0x33, 0x31, 0x30, 0x30, 0x32,
+  0x34, 0x39, 0x35, 0x32, 0x5a, 0x17, 0x0d, 0x31, 0x31, 0x30, 0x33, 0x31,
+  0x30, 0x30, 0x32, 0x34, 0x39, 0x35, 0x32, 0x5a, 0x30, 0x6d, 0x31, 0x0b,
+  0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x75, 0x73, 0x31,
+  0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x63, 0x61,
+  0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x63,
+  0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x11, 0x30, 0x0f,
+  0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x08, 0x69, 0x76, 0x70, 0x6e, 0x74,
+  0x65, 0x73, 0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x0b,
+  0x13, 0x02, 0x71, 0x61, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04,
+  0x03, 0x13, 0x14, 0x76, 0x70, 0x6e, 0x33, 0x30, 0x30, 0x30, 0x2e, 0x69,
+  0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30,
+  0x81, 0x9d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8b, 0x00, 0x30, 0x81, 0x87,
+  0x02, 0x81, 0x81, 0x00, 0x8a, 0xaa, 0x14, 0x59, 0x49, 0x6e, 0x70, 0x37,
+  0x3d, 0x53, 0x22, 0x27, 0x95, 0xc0, 0x11, 0x3e, 0xb4, 0x7d, 0x5c, 0x37,
+  0x29, 0xd8, 0x4c, 0x5d, 0x81, 0x6c, 0xdc, 0x50, 0xd3, 0xa9, 0x88, 0xaa,
+  0x99, 0x68, 0x94, 0x1d, 0x63, 0x9a, 0xf1, 0xd4, 0x57, 0x63, 0xa3, 0x78,
+  0x29, 0x5e, 0xae, 0x4a, 0xe6, 0x8b, 0x70, 0xf9, 0x04, 0x82, 0x1e, 0xa8,
+  0x1d, 0x61, 0x98, 0xda, 0xe3, 0xac, 0x86, 0xb7, 0x62, 0x58, 0xae, 0x37,
+  0xee, 0x1b, 0x37, 0xf8, 0xfd, 0x12, 0xc6, 0x69, 0x87, 0x58, 0xf5, 0x66,
+  0xb2, 0x07, 0xed, 0x2d, 0x3c, 0xbb, 0x64, 0xac, 0x92, 0x07, 0x98, 0x17,
+  0x72, 0xdc, 0x41, 0xf0, 0x7b, 0x1a, 0x3e, 0x83, 0x29, 0x05, 0x36, 0x21,
+  0x08, 0x23, 0xf6, 0x8a, 0x84, 0x31, 0x83, 0x50, 0xea, 0x53, 0xe0, 0x88,
+  0x24, 0x84, 0xdd, 0xb2, 0x4a, 0x3a, 0x90, 0x4b, 0xeb, 0x08, 0x07, 0x6b,
+  0x02, 0x01, 0x03, 0xa3, 0x82, 0x03, 0xc9, 0x30, 0x82, 0x03, 0xc5, 0x30,
+  0x1f, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x18, 0x30, 0x16, 0x82, 0x14,
+  0x76, 0x70, 0x6e, 0x33, 0x30, 0x30, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e,
+  0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1d, 0x06, 0x03,
+  0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x3d, 0xb1, 0xf6, 0x70, 0x4c,
+  0x4d, 0x42, 0xf4, 0x41, 0x91, 0xd4, 0xef, 0xa8, 0xcf, 0x45, 0x31, 0x16,
+  0x29, 0x92, 0x1a, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
+  0x30, 0x16, 0x80, 0x14, 0x40, 0xb5, 0x54, 0x10, 0x88, 0x09, 0xeb, 0x3e,
+  0x2e, 0x69, 0x82, 0xa6, 0xa0, 0xd8, 0xe4, 0xb0, 0x98, 0xc1, 0x69, 0x3d,
+  0x30, 0x82, 0x01, 0x5c, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x82, 0x01,
+  0x53, 0x30, 0x82, 0x01, 0x4f, 0x30, 0x82, 0x01, 0x4b, 0xa0, 0x82, 0x01,
+  0x47, 0xa0, 0x82, 0x01, 0x43, 0x86, 0x81, 0xbc, 0x6c, 0x64, 0x61, 0x70,
+  0x3a, 0x2f, 0x2f, 0x2f, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72, 0x76,
+  0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e,
+  0x63, 0x6f, 0x6d, 0x2c, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72, 0x76,
+  0x31, 0x30, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x44, 0x50, 0x2c, 0x43, 0x4e,
+  0x3d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30, 0x4b, 0x65,
+  0x79, 0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73,
+  0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73,
+  0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72,
+  0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x69, 0x76, 0x70,
+  0x6e, 0x74, 0x65, 0x73, 0x74, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, 0x6d,
+  0x3f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65,
+  0x52, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69,
+  0x73, 0x74, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65,
+  0x63, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x52, 0x4c, 0x44,
+  0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50,
+  0x6f, 0x69, 0x6e, 0x74, 0x86, 0x3f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+  0x2f, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70,
+  0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x65,
+  0x72, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x71, 0x61, 0x73,
+  0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73,
+  0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x72, 0x6c, 0x86, 0x41, 0x66,
+  0x69, 0x6c, 0x65, 0x3a, 0x2f, 0x2f, 0x5c, 0x5c, 0x71, 0x61, 0x73, 0x72,
+  0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74,
+  0x2e, 0x63, 0x6f, 0x6d, 0x5c, 0x43, 0x65, 0x72, 0x74, 0x45, 0x6e, 0x72,
+  0x6f, 0x6c, 0x6c, 0x5c, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e,
+  0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
+  0x2e, 0x63, 0x72, 0x6c, 0x30, 0x82, 0x01, 0x8f, 0x06, 0x08, 0x2b, 0x06,
+  0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x82, 0x01, 0x81, 0x30, 0x82,
+  0x01, 0x7d, 0x30, 0x81, 0xb4, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+  0x07, 0x30, 0x01, 0x86, 0x81, 0xa7, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f,
+  0x2f, 0x2f, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30,
+  0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f,
+  0x6d, 0x2c, 0x43, 0x4e, 0x3d, 0x41, 0x49, 0x41, 0x2c, 0x43, 0x4e, 0x3d,
+  0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30, 0x4b, 0x65, 0x79,
+  0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c,
+  0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c,
+  0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61,
+  0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x69, 0x76, 0x70, 0x6e,
+  0x74, 0x65, 0x73, 0x74, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, 0x6d, 0x3f,
+  0x63, 0x41, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+  0x65, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65, 0x63,
+  0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x65, 0x72, 0x74, 0x69,
+  0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x75, 0x74, 0x68,
+  0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x60, 0x06, 0x08, 0x2b, 0x06, 0x01,
+  0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x54, 0x68, 0x74, 0x74, 0x70, 0x3a,
+  0x2f, 0x2f, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76,
+  0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43,
+  0x65, 0x72, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x71, 0x61,
+  0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65,
+  0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x5f, 0x71, 0x61, 0x73, 0x72, 0x76,
+  0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e,
+  0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x62, 0x06, 0x08, 0x2b,
+  0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x56, 0x66, 0x69, 0x6c,
+  0x65, 0x3a, 0x2f, 0x2f, 0x5c, 0x5c, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31,
+  0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63,
+  0x6f, 0x6d, 0x5c, 0x43, 0x65, 0x72, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c,
+  0x6c, 0x5c, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76,
+  0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x5f, 0x71,
+  0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74,
+  0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x72, 0x74, 0x30,
+  0x3f, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02,
+  0x04, 0x32, 0x1e, 0x30, 0x00, 0x49, 0x00, 0x50, 0x00, 0x53, 0x00, 0x45,
+  0x00, 0x43, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72,
+  0x00, 0x6d, 0x00, 0x65, 0x00, 0x64, 0x00, 0x69, 0x00, 0x61, 0x00, 0x74,
+  0x00, 0x65, 0x00, 0x4f, 0x00, 0x66, 0x00, 0x66, 0x00, 0x6c, 0x00, 0x69,
+  0x00, 0x6e, 0x00, 0x65, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
+  0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d,
+  0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x13, 0x06, 0x03, 0x55,
+  0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+  0x05, 0x08, 0x02, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00,
+  0x50, 0x59, 0x35, 0x26, 0x1b, 0x1b, 0x60, 0x29, 0x39, 0xe1, 0x3d, 0xc5,
+  0xdc, 0xe7, 0xcd, 0x8c, 0xbb, 0x7b, 0x86, 0xad, 0x82, 0xc2, 0xb3, 0xea,
+  0xdb, 0xd9, 0xe0, 0x8b, 0x40, 0x7b, 0x7e, 0xe1, 0xe9, 0xbe, 0x4d, 0x9a,
+  0x42, 0xda, 0xb3, 0x4c, 0x13, 0x08, 0x84, 0x10, 0x0f, 0x01, 0xb0, 0x13,
+  0x89, 0xd6, 0xf0, 0xc6, 0xb8, 0x6e, 0x77, 0xbc, 0x48, 0x49, 0xf2, 0x25,
+  0xc1, 0x89, 0x62, 0xe8, 0xd9, 0x4e, 0xd7, 0xa9, 0x4b, 0x53, 0xd6, 0x6a,
+  0x45, 0x7a, 0x74, 0xc1, 0x92, 0x95, 0x74, 0x32, 0xea, 0xee, 0xfb, 0x0e,
+  0x87, 0x10, 0xce, 0x79, 0x96, 0x84, 0x41, 0x7e, 0x8f, 0x3f, 0x60, 0xff,
+  0xe4, 0x23, 0xb5, 0xc4, 0x91, 0x99, 0x5b, 0x90, 0x12, 0x88, 0xc3, 0x6a,
+  0x0e, 0x99, 0x35, 0xd6, 0x28, 0x62, 0x9f, 0x9c, 0xf0, 0xb3, 0x35, 0x0a,
+  0x8c, 0xb1, 0x01, 0x76, 0x64, 0xa8, 0x30, 0x3d, 0x09, 0x22, 0x06, 0xab,
+  0x8e, 0xba, 0x55, 0x64, 0xd6, 0x91, 0x7c, 0x01, 0xb9, 0xaa, 0xc5, 0x56,
+  0x85, 0xa3, 0xd7, 0x7c, 0xd6, 0x1a, 0x5d, 0x45, 0xee, 0x40, 0x82, 0x06,
+  0x03, 0xa2, 0x25, 0x02, 0x67, 0x24, 0xd0, 0x4c, 0xe3, 0xc5, 0x49, 0xb5,
+  0xa7, 0xe8, 0xb4, 0x4d, 0x0e, 0xe8, 0x4c, 0x76, 0xb9, 0xe5, 0xc4, 0x7c,
+  0xfc, 0x35, 0x5c, 0xe3, 0x62, 0xe2, 0x42, 0x36, 0xe9, 0xb5, 0x5f, 0xec,
+  0x50, 0xde, 0x61, 0x6e, 0x76, 0x9d, 0xe7, 0x5a, 0x4f, 0xa5, 0x45, 0x51,
+  0x41, 0xd3, 0xbb, 0x8d, 0x72, 0x51, 0xc7, 0xfb, 0x99, 0x2c, 0x52, 0x15,
+  0xa0, 0xde, 0xa9, 0xd0, 0xbc, 0x66, 0x7a, 0x81, 0x99, 0x5c, 0xd4, 0x52,
+  0x75, 0x0a, 0x80, 0x3c, 0xa9, 0x0c, 0x91, 0x51, 0x73, 0xf1, 0x97, 0xdd,
+  0xe4, 0xbb, 0xaa, 0x5b, 0x0d, 0xfe, 0xfb, 0xff, 0xed, 0xb8, 0x71, 0x3d,
+  0xbc, 0x7b, 0x70, 0xaf
+};
+unsigned int vpn3000_id_cer_len = 1672;
+
+
+unsigned char wifiuser_certificate[1305]={
+0x30,0x82,0x05,0x15,0x30,0x82,0x03,0xFD,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x05,
+0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,
+0x23,0x31,0x21,0x30,0x1F,0x06,0x03,0x55,0x04,0x03,0x13,0x18,0x57,0x69,0x46,0x69,
+0x2D,0x49,0x6E,0x74,0x65,0x72,0x6D,0x65,0x64,0x69,0x61,0x74,0x65,0x2D,0x43,0x41,
+0x2D,0x73,0x74,0x61,0x30,0x1E,0x17,0x0D,0x30,0x35,0x30,0x31,0x30,0x31,0x30,0x30,
+0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x35,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
+0x30,0x30,0x30,0x5A,0x30,0x55,0x31,0x15,0x30,0x13,0x06,0x0A,0x09,0x92,0x26,0x89,
+0x93,0xF2,0x2C,0x64,0x01,0x19,0x16,0x05,0x6C,0x6F,0x63,0x61,0x6C,0x31,0x18,0x30,
+0x16,0x06,0x0A,0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x19,0x16,0x08,0x77,
+0x69,0x66,0x69,0x6C,0x61,0x62,0x73,0x31,0x0E,0x30,0x0C,0x06,0x03,0x55,0x04,0x03,
+0x13,0x05,0x55,0x73,0x65,0x72,0x73,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x03,
+0x13,0x09,0x77,0x69,0x66,0x69,0x2D,0x75,0x73,0x65,0x72,0x30,0x82,0x01,0x22,0x30,
+0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,
+0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xCC,0xF6,0xF1,0xD9,
+0x2E,0xFE,0xC6,0x50,0xB4,0x8F,0x1E,0x44,0xBF,0x93,0x87,0xDF,0x92,0xB2,0x5E,0xDF,
+0x31,0xEF,0x4B,0x40,0x9D,0x20,0xC4,0x88,0x7B,0x4D,0x96,0x60,0x38,0x26,0xCA,0x45,
+0xA4,0x2E,0xCF,0x99,0x02,0x89,0x37,0x2E,0xAB,0x5D,0x73,0x6C,0x17,0xC8,0x8A,0x2A,
+0xE2,0xC1,0x9D,0xB3,0x9E,0xBE,0x8A,0xDB,0xFD,0x04,0x34,0x3E,0x08,0x44,0x1B,0x0F,
+0xFE,0xB6,0xA0,0x0F,0xE1,0x51,0xD8,0x68,0x27,0x6A,0xFC,0xBE,0x8B,0x95,0xF5,0xD9,
+0x05,0x3E,0x47,0xDD,0x01,0xD3,0x84,0x17,0x07,0xEB,0x0D,0xA6,0x3D,0xC6,0xF2,0xD7,
+0xE4,0x7D,0xCB,0x9F,0xE8,0xF1,0x3B,0x03,0x72,0xFC,0x70,0x38,0x9B,0x7F,0x00,0xB3,
+0xAF,0xD8,0x4F,0x26,0x70,0xAC,0x4D,0xC6,0x72,0x91,0x9A,0xDF,0x1D,0x43,0xD5,0x22,
+0xE1,0x7E,0x70,0x47,0x74,0xF2,0x51,0x1E,0x20,0x95,0xB5,0x5E,0xAC,0xDD,0x10,0x75,
+0x72,0xDB,0x16,0x1B,0x10,0xE4,0x40,0xF0,0xE3,0x86,0xCC,0xF0,0x35,0xB9,0x36,0x86,
+0x5A,0x2F,0xD0,0xB3,0x12,0xDA,0x8F,0x50,0x61,0xB4,0xC7,0x40,0xBF,0xEC,0x81,0x83,
+0xAA,0x7A,0x69,0xD3,0x8C,0x9D,0xAF,0x0D,0xD5,0x0A,0x70,0xB5,0x35,0xB4,0xBE,0xD6,
+0xEF,0xEA,0x25,0x2F,0xDB,0x99,0x34,0xA4,0x04,0x09,0x50,0xF5,0x4B,0xEA,0xFD,0x18,
+0x55,0x16,0x2D,0x9E,0x23,0xE2,0xF7,0xBA,0xD7,0x12,0x92,0x30,0xC1,0xDB,0xE5,0x0E,
+0x53,0x58,0xC7,0x0C,0x0C,0x55,0xF4,0x64,0x42,0xAE,0x9A,0x7A,0x4F,0x0F,0x22,0xC3,
+0x44,0xF7,0xAF,0xF7,0x69,0x76,0xCF,0xFC,0xE0,0xBB,0xE9,0x33,0x02,0x03,0x01,0x00,
+0x01,0xA3,0x82,0x02,0x20,0x30,0x82,0x02,0x1C,0x30,0x3F,0x06,0x03,0x55,0x1D,0x23,
+0x04,0x38,0x30,0x36,0x80,0x14,0xB0,0x8C,0xE2,0xB2,0xC1,0x86,0xFC,0x56,0x61,0x78,
+0xBF,0x1F,0x06,0xD5,0xF3,0x11,0x92,0xB1,0x38,0x00,0xA1,0x1B,0xA4,0x19,0x30,0x17,
+0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x03,0x13,0x0C,0x57,0x69,0x46,0x69,0x2D,
+0x52,0x6F,0x6F,0x74,0x2D,0x43,0x41,0x82,0x01,0x03,0x30,0x42,0x06,0x09,0x60,0x86,
+0x48,0x01,0x86,0xF8,0x42,0x01,0x04,0x04,0x35,0x16,0x33,0x68,0x74,0x74,0x70,0x3A,
+0x2F,0x2F,0x73,0x65,0x72,0x76,0x65,0x72,0x2E,0x77,0x69,0x66,0x69,0x6C,0x61,0x62,
+0x73,0x2E,0x6C,0x6F,0x63,0x61,0x6C,0x2F,0x63,0x61,0x2F,0x63,0x72,0x6C,0x2F,0x77,
+0x69,0x66,0x69,0x69,0x6D,0x63,0x61,0x73,0x74,0x61,0x2E,0x63,0x72,0x6C,0x30,0x44,
+0x06,0x03,0x55,0x1D,0x1F,0x04,0x3D,0x30,0x3B,0x30,0x39,0xA0,0x37,0xA0,0x35,0x86,
+0x33,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x73,0x65,0x72,0x76,0x65,0x72,0x2E,0x77,
+0x69,0x66,0x69,0x6C,0x61,0x62,0x73,0x2E,0x6C,0x6F,0x63,0x61,0x6C,0x2F,0x63,0x61,
+0x2F,0x63,0x72,0x6C,0x2F,0x77,0x69,0x66,0x69,0x69,0x6D,0x63,0x61,0x73,0x74,0x61,
+0x2E,0x63,0x72,0x6C,0x30,0x4E,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,
+0x04,0x42,0x30,0x40,0x30,0x3E,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,
+0x86,0x32,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x73,0x65,0x72,0x76,0x65,0x72,0x2E,
+0x77,0x69,0x66,0x69,0x6C,0x61,0x62,0x73,0x2E,0x6C,0x6F,0x63,0x61,0x6C,0x2F,0x63,
+0x61,0x2F,0x63,0x61,0x2F,0x77,0x69,0x66,0x69,0x69,0x6D,0x63,0x61,0x73,0x74,0x61,
+0x2E,0x63,0x72,0x74,0x30,0x20,0x06,0x03,0x55,0x1D,0x12,0x04,0x19,0x30,0x17,0x82,
+0x15,0x73,0x65,0x72,0x76,0x65,0x72,0x2E,0x77,0x69,0x66,0x69,0x6C,0x61,0x62,0x73,
+0x2E,0x6C,0x6F,0x63,0x61,0x6C,0x30,0x33,0x06,0x03,0x55,0x1D,0x11,0x04,0x2C,0x30,
+0x2A,0xA0,0x28,0x06,0x0A,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x03,0xA0,
+0x1A,0x0C,0x18,0x77,0x69,0x66,0x69,0x2D,0x75,0x73,0x65,0x72,0x40,0x77,0x69,0x66,
+0x69,0x6C,0x61,0x62,0x73,0x2E,0x6C,0x6F,0x63,0x61,0x6C,0x30,0x0B,0x06,0x03,0x55,
+0x1D,0x0F,0x04,0x04,0x03,0x02,0x05,0xA0,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,
+0x16,0x04,0x14,0x0B,0xC1,0x85,0x9B,0x11,0xBC,0xE9,0x6A,0xC0,0x4E,0x08,0xB3,0x87,
+0xBC,0x29,0xAF,0x35,0x6E,0x58,0x23,0x30,0x1D,0x06,0x03,0x55,0x1D,0x25,0x04,0x16,
+0x30,0x14,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x08,0x2B,0x06,
+0x01,0x05,0x05,0x07,0x03,0x04,0x30,0x44,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,
+0x01,0x09,0x0F,0x04,0x37,0x30,0x35,0x30,0x0E,0x06,0x08,0x2A,0x86,0x48,0x86,0xF7,
+0x0D,0x03,0x02,0x02,0x02,0x00,0x80,0x30,0x0E,0x06,0x08,0x2A,0x86,0x48,0x86,0xF7,
+0x0D,0x03,0x04,0x02,0x02,0x00,0x80,0x30,0x07,0x06,0x05,0x2B,0x0E,0x03,0x02,0x07,
+0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x07,0x30,0x17,0x06,0x09,
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x04,0x0A,0x1E,0x08,0x00,0x55,0x00,
+0x73,0x00,0x65,0x00,0x72,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,
+0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x0F,0x18,0x23,0xE5,0x68,0x76,0x00,
+0x79,0xF0,0xE6,0xC1,0xA1,0x47,0x26,0xE0,0x7B,0xF9,0x5A,0x6A,0x8A,0xFA,0xD2,0x90,
+0x52,0x3D,0x98,0x86,0x5A,0x43,0x4B,0xE7,0x6C,0x07,0x73,0x43,0x9E,0x8C,0x6C,0xA7,
+0xA5,0x92,0x28,0xE8,0x4B,0xB9,0xE9,0x86,0x9A,0xB9,0xDA,0x9C,0xF4,0x54,0x38,0x13,
+0xC8,0xA1,0xAF,0x5A,0xCD,0xCB,0x92,0x62,0xEF,0x45,0xC5,0x57,0x58,0xE6,0xC2,0x8E,
+0xFC,0xC2,0x84,0xC7,0xF8,0xB9,0xF0,0x90,0x45,0xA4,0x04,0x29,0x61,0xC4,0x79,0xD8,
+0xCB,0xD3,0xE8,0xF0,0x19,0x9A,0x72,0x38,0xCA,0xAF,0x71,0xF8,0xF7,0x96,0x5E,0xCD,
+0x4D,0x64,0x35,0x97,0x67,0xE2,0x96,0x01,0xF0,0x36,0x5E,0xD6,0x5D,0xCC,0x7B,0x03,
+0x3C,0xDE,0x67,0xAD,0x44,0x75,0x86,0xEE,0x1C,0x21,0x11,0xFE,0xF0,0x44,0xBC,0x89,
+0xC4,0x0C,0x20,0x27,0x36,0x54,0x03,0x93,0xC1,0x57,0xA9,0x1C,0xAA,0x6B,0x80,0xDF,
+0x43,0xCA,0xC7,0x3F,0x7D,0xAB,0xD6,0x52,0x8F,0xC2,0x04,0xDC,0x08,0x45,0xD5,0x9F,
+0xEC,0xBD,0x70,0x18,0xA6,0xFA,0xA6,0xED,0x5B,0x66,0x70,0xFC,0xB0,0x31,0xE9,0x3D,
+0xDB,0x62,0xCC,0xDE,0xF6,0x91,0xD6,0x10,0xCC,0x3D,0x7D,0x2C,0x46,0x08,0xF8,0x1F,
+0x56,0x35,0x26,0xAA,0x92,0x54,0x5E,0xDC,0xA0,0x0F,0x06,0xB8,0xFC,0xE6,0x38,0xF0,
+0xAA,0x60,0x96,0xF7,0xAD,0xC0,0xA1,0x86,0x83,0x8C,0xCD,0x6C,0x30,0xB9,0xB9,0xC1,
+0xBB,0x29,0x8F,0xE4,0x0F,0x75,0xC6,0xFD,0x81,0xDF,0x7E,0xEE,0x25,0x7A,0x76,0x9B,
+0x80,0x42,0xD4,0xF4,0x3B,0xC9,0x21,0x3D,0x7E,
+};
+
+unsigned char wifiimcasta_certificate[1115]={
+0x30,0x82,0x04,0x57,0x30,0x82,0x03,0x3F,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x03,
+0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,
+0x17,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x03,0x13,0x0C,0x57,0x69,0x46,0x69,
+0x2D,0x52,0x6F,0x6F,0x74,0x2D,0x43,0x41,0x30,0x1E,0x17,0x0D,0x30,0x35,0x30,0x31,
+0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x35,0x30,0x31,0x30,
+0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x23,0x31,0x21,0x30,0x1F,0x06,0x03,
+0x55,0x04,0x03,0x13,0x18,0x57,0x69,0x46,0x69,0x2D,0x49,0x6E,0x74,0x65,0x72,0x6D,
+0x65,0x64,0x69,0x61,0x74,0x65,0x2D,0x43,0x41,0x2D,0x73,0x74,0x61,0x30,0x82,0x01,
+0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,
+0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xA2,0xFE,
+0x9E,0x00,0xB0,0x65,0x7D,0x76,0x44,0xE6,0x0A,0x33,0xD0,0xF2,0xF2,0xC0,0xEE,0xF7,
+0x40,0x21,0x45,0x00,0xBC,0xCA,0x4F,0x51,0x0D,0xA4,0xAA,0x1E,0xF1,0x37,0xCD,0x9C,
+0xE3,0xFE,0x31,0xBE,0xD5,0x64,0x48,0x31,0xEC,0x4D,0x38,0x19,0x31,0x63,0x5C,0xFB,
+0x0C,0x46,0xB7,0x42,0xFE,0xE5,0x78,0x08,0xE5,0xEB,0xC9,0xC7,0xA6,0x52,0x0D,0x62,
+0xA2,0x06,0xD1,0x11,0x4E,0xE7,0x49,0x5B,0xC2,0xA7,0xB9,0x2F,0x43,0xF6,0xE0,0xFB,
+0xBE,0x4D,0xE9,0x31,0x18,0x55,0xA8,0x73,0x0C,0x25,0xD5,0xED,0x66,0x4D,0xC3,0xED,
+0x6B,0x71,0x74,0xEF,0xB4,0x51,0x90,0x32,0x5A,0x83,0xB9,0x6E,0x48,0x9F,0x0E,0xD4,
+0x21,0xC8,0x89,0x60,0x50,0xB9,0xAC,0x28,0x06,0xE3,0xAA,0x36,0xA9,0x16,0x92,0x4E,
+0xD3,0x2A,0x06,0xAE,0x3D,0x8B,0x1A,0x92,0x00,0x99,0x49,0x3E,0x95,0x29,0x56,0x9F,
+0x5B,0x45,0x93,0x90,0xAD,0xDA,0x3E,0x41,0x0F,0x03,0xE5,0x81,0x22,0x53,0x52,0x4B,
+0x7F,0x42,0x98,0xBB,0x62,0x1E,0xE9,0xF6,0x5D,0xE4,0xCF,0x69,0x5D,0x5C,0x10,0x9F,
+0x27,0x73,0xB8,0xEE,0xDA,0xF6,0xCC,0x43,0x56,0xD3,0x22,0x29,0x1A,0x7E,0xE5,0x8A,
+0xB7,0x41,0xCF,0xC8,0x94,0x00,0x31,0x34,0x89,0x2A,0x6B,0x27,0x35,0x9B,0x16,0xBE,
+0xFF,0x54,0x12,0xEA,0x18,0xC2,0x97,0x3A,0xE8,0xE1,0x67,0xBD,0x02,0x09,0x34,0x4C,
+0x58,0xB8,0x79,0xDE,0x1A,0xDB,0x13,0x5C,0x50,0x61,0x91,0x93,0x65,0x26,0x4D,0x1F,
+0x11,0x63,0x1B,0x28,0x6B,0x45,0x9A,0xBB,0x06,0xE1,0x4C,0x21,0x49,0x37,0x02,0x03,
+0x01,0x00,0x01,0xA3,0x82,0x01,0xA0,0x30,0x82,0x01,0x9C,0x30,0x3F,0x06,0x03,0x55,
+0x1D,0x23,0x04,0x38,0x30,0x36,0x80,0x14,0xD7,0x1D,0x74,0xC8,0xD6,0x6A,0x94,0x8C,
+0x10,0xCF,0x05,0x4F,0xE3,0x96,0xA6,0xD6,0xCF,0xB2,0x62,0xF3,0xA1,0x1B,0xA4,0x19,
+0x30,0x17,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x03,0x13,0x0C,0x57,0x69,0x46,
+0x69,0x2D,0x52,0x6F,0x6F,0x74,0x2D,0x43,0x41,0x82,0x01,0x01,0x30,0x41,0x06,0x09,
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x04,0x04,0x34,0x16,0x32,0x68,0x74,0x74,
+0x70,0x3A,0x2F,0x2F,0x73,0x65,0x72,0x76,0x65,0x72,0x2E,0x77,0x69,0x66,0x69,0x6C,
+0x61,0x62,0x73,0x2E,0x6C,0x6F,0x63,0x61,0x6C,0x2F,0x63,0x61,0x2F,0x63,0x72,0x6C,
+0x2F,0x77,0x69,0x66,0x69,0x72,0x6F,0x6F,0x74,0x63,0x61,0x2E,0x63,0x72,0x6C,0x30,
+0x43,0x06,0x03,0x55,0x1D,0x1F,0x04,0x3C,0x30,0x3A,0x30,0x38,0xA0,0x36,0xA0,0x34,
+0x86,0x32,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x73,0x65,0x72,0x76,0x65,0x72,0x2E,
+0x77,0x69,0x66,0x69,0x6C,0x61,0x62,0x73,0x2E,0x6C,0x6F,0x63,0x61,0x6C,0x2F,0x63,
+0x61,0x2F,0x63,0x72,0x6C,0x2F,0x77,0x69,0x66,0x69,0x72,0x6F,0x6F,0x74,0x63,0x61,
+0x2E,0x63,0x72,0x6C,0x30,0x4D,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,
+0x04,0x41,0x30,0x3F,0x30,0x3D,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,
+0x86,0x31,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x73,0x65,0x72,0x76,0x65,0x72,0x2E,
+0x77,0x69,0x66,0x69,0x6C,0x61,0x62,0x73,0x2E,0x6C,0x6F,0x63,0x61,0x6C,0x2F,0x63,
+0x61,0x2F,0x63,0x61,0x2F,0x77,0x69,0x66,0x69,0x72,0x6F,0x6F,0x74,0x63,0x61,0x2E,
+0x63,0x72,0x74,0x30,0x20,0x06,0x03,0x55,0x1D,0x12,0x04,0x19,0x30,0x17,0x82,0x15,
+0x73,0x65,0x72,0x76,0x65,0x72,0x2E,0x77,0x69,0x66,0x69,0x6C,0x61,0x62,0x73,0x2E,
+0x6C,0x6F,0x63,0x61,0x6C,0x30,0x20,0x06,0x03,0x55,0x1D,0x11,0x04,0x19,0x30,0x17,
+0x82,0x15,0x73,0x65,0x72,0x76,0x65,0x72,0x2E,0x77,0x69,0x66,0x69,0x6C,0x61,0x62,
+0x73,0x2E,0x6C,0x6F,0x63,0x61,0x6C,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,
+0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,
+0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x86,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,
+0x16,0x04,0x14,0xB0,0x8C,0xE2,0xB2,0xC1,0x86,0xFC,0x56,0x61,0x78,0xBF,0x1F,0x06,
+0xD5,0xF3,0x11,0x92,0xB1,0x38,0x00,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,
+0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x94,0xF0,0xD6,0x8C,0x0A,
+0xDE,0x10,0xD0,0x7D,0xA5,0xB0,0xDE,0xFD,0x8D,0x1E,0xCB,0x8A,0xEC,0x60,0x66,0x74,
+0x22,0x31,0xB1,0x78,0xAD,0x0E,0x02,0x53,0x99,0xC6,0x75,0x10,0x65,0x60,0x59,0x57,
+0x60,0x76,0xE5,0x87,0x58,0x82,0xB4,0x6F,0xB6,0x11,0xB9,0x6D,0x9D,0x09,0x7F,0x55,
+0x20,0x28,0xA4,0x69,0x45,0x11,0x4A,0x9E,0x6D,0x38,0xD4,0x6B,0x26,0xBA,0x05,0xDA,
+0x4C,0x12,0xE3,0x40,0x86,0xDD,0x7F,0x4B,0xC7,0xF1,0xB7,0xF4,0xAE,0xE1,0xC5,0xB9,
+0x3B,0x4B,0x8A,0x64,0x91,0x57,0x1A,0xF1,0x9E,0x55,0x56,0x16,0xCE,0x3F,0xD1,0xD8,
+0x29,0x4A,0xC2,0x81,0x9A,0xEE,0x92,0xC8,0x3C,0x43,0x85,0xAA,0x2D,0x5B,0x2F,0x9C,
+0x68,0x00,0xD7,0x56,0xF4,0xFE,0x85,0x5F,0xF2,0x45,0x9A,0xB9,0x27,0x19,0x78,0x58,
+0x79,0x3C,0xDB,0x53,0x6B,0x45,0x94,0xF2,0x22,0x09,0xE0,0xF5,0xC3,0xFF,0xBC,0x3D,
+0xED,0x41,0x33,0x63,0xE5,0x3B,0x4C,0xE2,0x51,0xD2,0x1D,0xFA,0xFC,0xD1,0xA2,0x96,
+0xEE,0x57,0x4F,0x08,0xDC,0x31,0xEB,0x1F,0x9D,0xBD,0x9F,0x4C,0x75,0xC0,0xCD,0x4F,
+0x79,0x1F,0x7C,0x5B,0x6A,0x61,0x5C,0xE7,0x54,0xF3,0xBF,0xB4,0xE7,0xE9,0xE4,0x01,
+0xEE,0x4E,0x1A,0x0F,0x9A,0xC0,0x22,0x72,0xB0,0x37,0x9C,0x51,0xE6,0x2F,0x51,0x64,
+0xEC,0xDF,0x80,0x6F,0xD9,0x08,0x5B,0x58,0xAC,0xDD,0x32,0xF4,0xA6,0x2F,0x4D,0x18,
+0x1D,0x92,0x5E,0x2E,0x16,0xAF,0x76,0xF6,0x4D,0x2F,0xE7,0x13,0xFA,0x76,0xA7,0x22,
+0x57,0x4C,0xE5,0x01,0x53,0x69,0x0B,0xF9,0x34,0xBA,0xB5,
+};
+
+unsigned char wifirootca_certificate[1038]={
+0x30,0x82,0x04,0x0A,0x30,0x82,0x02,0xF2,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x01,
+0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,
+0x17,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x03,0x13,0x0C,0x57,0x69,0x46,0x69,
+0x2D,0x52,0x6F,0x6F,0x74,0x2D,0x43,0x41,0x30,0x1E,0x17,0x0D,0x30,0x35,0x30,0x31,
+0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x35,0x30,0x31,0x30,
+0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x17,0x31,0x15,0x30,0x13,0x06,0x03,
+0x55,0x04,0x03,0x13,0x0C,0x57,0x69,0x46,0x69,0x2D,0x52,0x6F,0x6F,0x74,0x2D,0x43,
+0x41,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,
+0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,
+0x01,0x00,0xB9,0xE7,0x9B,0x04,0x54,0x53,0x99,0x0B,0xB6,0x6D,0x50,0x97,0xC8,0x42,
+0x36,0x82,0xE0,0x93,0xA4,0x51,0xB7,0x7E,0x9E,0x6A,0xDC,0x22,0x3D,0x39,0xDA,0x5C,
+0xD0,0xA2,0x29,0x51,0x8F,0xE1,0x36,0xA3,0x45,0x07,0xCC,0x9C,0x24,0xC9,0xD3,0x5B,
+0xBC,0x34,0x83,0xEB,0xFD,0xE2,0x79,0xD6,0x70,0x11,0x16,0x9E,0xDA,0x83,0xC0,0xFE,
+0x70,0x98,0x2F,0xDB,0x0E,0x9D,0x00,0xA9,0x7C,0x99,0xBA,0xBB,0xC4,0xDB,0x4A,0xE2,
+0xEE,0x46,0xAC,0xA5,0x35,0x1B,0xC2,0xBD,0xF0,0xE0,0x6A,0x77,0x29,0x34,0x6E,0x6D,
+0x5F,0x51,0xDE,0x67,0xFD,0x27,0xF1,0x50,0x02,0xBF,0xE9,0x1B,0x95,0x2E,0x99,0x0B,
+0xB3,0x4D,0x7C,0xBC,0x5E,0x4B,0x29,0x5D,0x52,0xE3,0x14,0xDE,0xD3,0x6D,0xFA,0xB4,
+0x07,0x6C,0xB7,0x83,0xE7,0x5A,0xB3,0x51,0xC6,0x73,0xA6,0x96,0xEB,0x97,0x2F,0xBA,
+0x04,0xF0,0xF2,0xEB,0xEE,0xC0,0xB8,0x95,0x29,0x98,0xCA,0xAF,0x8B,0xC9,0x27,0xAD,
+0x22,0x93,0x17,0x9C,0x88,0x51,0x79,0x90,0x31,0xCB,0x9F,0x98,0x47,0xB6,0x5C,0x03,
+0xD1,0x0F,0x98,0xBF,0xEA,0x32,0x97,0x65,0xD3,0x54,0xD5,0x71,0x0B,0x52,0x7F,0x55,
+0xA7,0x88,0xB1,0x0B,0x04,0xD5,0x84,0x71,0xA7,0x62,0x28,0x53,0xBB,0x33,0xBE,0x11,
+0xFD,0x98,0x7D,0x3A,0x03,0x98,0x17,0x73,0xB7,0xD6,0xDE,0x02,0x57,0x47,0x39,0x9D,
+0x0C,0x26,0x17,0xAA,0x33,0x42,0x44,0x5A,0xB0,0x0D,0x8F,0x1A,0xF7,0xBF,0x18,0xBF,
+0x2D,0x32,0x2A,0x32,0x0C,0x4C,0xBA,0xC9,0xEA,0xA9,0x2E,0x07,0xBE,0x4C,0xD2,0xC4,
+0x59,0xF7,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x01,0x5F,0x30,0x82,0x01,0x5B,0x30,
+0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,
+0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x86,
+0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xD7,0x1D,0x74,0xC8,0xD6,
+0x6A,0x94,0x8C,0x10,0xCF,0x05,0x4F,0xE3,0x96,0xA6,0xD6,0xCF,0xB2,0x62,0xF3,0x30,
+0x41,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x04,0x04,0x34,0x16,0x32,
+0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x73,0x65,0x72,0x76,0x65,0x72,0x2E,0x77,0x69,
+0x66,0x69,0x6C,0x61,0x62,0x73,0x2E,0x6C,0x6F,0x63,0x61,0x6C,0x2F,0x63,0x61,0x2F,
+0x63,0x72,0x6C,0x2F,0x77,0x69,0x66,0x69,0x72,0x6F,0x6F,0x74,0x63,0x61,0x2E,0x63,
+0x72,0x6C,0x30,0x43,0x06,0x03,0x55,0x1D,0x1F,0x04,0x3C,0x30,0x3A,0x30,0x38,0xA0,
+0x36,0xA0,0x34,0x86,0x32,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x73,0x65,0x72,0x76,
+0x65,0x72,0x2E,0x77,0x69,0x66,0x69,0x6C,0x61,0x62,0x73,0x2E,0x6C,0x6F,0x63,0x61,
+0x6C,0x2F,0x63,0x61,0x2F,0x63,0x72,0x6C,0x2F,0x77,0x69,0x66,0x69,0x72,0x6F,0x6F,
+0x74,0x63,0x61,0x2E,0x63,0x72,0x6C,0x30,0x4D,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,
+0x07,0x01,0x01,0x04,0x41,0x30,0x3F,0x30,0x3D,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,
+0x07,0x30,0x02,0x86,0x31,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x73,0x65,0x72,0x76,
+0x65,0x72,0x2E,0x77,0x69,0x66,0x69,0x6C,0x61,0x62,0x73,0x2E,0x6C,0x6F,0x63,0x61,
+0x6C,0x2F,0x63,0x61,0x2F,0x63,0x61,0x2F,0x77,0x69,0x66,0x69,0x72,0x6F,0x6F,0x74,
+0x63,0x61,0x2E,0x63,0x72,0x74,0x30,0x20,0x06,0x03,0x55,0x1D,0x12,0x04,0x19,0x30,
+0x17,0x82,0x15,0x73,0x65,0x72,0x76,0x65,0x72,0x2E,0x77,0x69,0x66,0x69,0x6C,0x61,
+0x62,0x73,0x2E,0x6C,0x6F,0x63,0x61,0x6C,0x30,0x20,0x06,0x03,0x55,0x1D,0x11,0x04,
+0x19,0x30,0x17,0x82,0x15,0x73,0x65,0x72,0x76,0x65,0x72,0x2E,0x77,0x69,0x66,0x69,
+0x6C,0x61,0x62,0x73,0x2E,0x6C,0x6F,0x63,0x61,0x6C,0x30,0x0D,0x06,0x09,0x2A,0x86,
+0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x91,0x75,
+0x35,0x21,0xF9,0x64,0xDD,0xF8,0xB1,0x73,0xDF,0x64,0x19,0x50,0xF6,0xC9,0xDD,0x06,
+0xFE,0xF9,0x24,0xEE,0xED,0x9B,0x1D,0x4F,0xDA,0x76,0x07,0xFC,0xDB,0x87,0x20,0x13,
+0xB6,0xC7,0x08,0x25,0x9A,0x08,0x73,0x32,0xD6,0xB6,0xD6,0xE4,0xC7,0x00,0x88,0xD2,
+0x60,0x7D,0x85,0x4E,0x83,0xE6,0x9E,0xD1,0x75,0x6C,0xA8,0x76,0x96,0x1B,0x92,0x17,
+0x99,0x15,0x85,0x6F,0x27,0x6C,0xAE,0x48,0xA1,0x31,0xD2,0x34,0xDA,0x90,0xEA,0xB8,
+0xB0,0x30,0x85,0xCB,0xA2,0xC2,0xC0,0x8E,0xBB,0x45,0x31,0x35,0xDA,0x78,0x14,0xD1,
+0x4A,0x36,0x4D,0x97,0xBF,0x33,0x1A,0xC5,0xE6,0xDA,0x8A,0x9E,0x15,0xC2,0x87,0xD1,
+0x84,0x31,0xEB,0xBD,0xB8,0x04,0xF6,0x97,0xFA,0x38,0xA6,0x52,0x34,0xB3,0x1E,0xCD,
+0x1B,0xFB,0xC2,0x3E,0x4C,0x2F,0xCA,0x0A,0x60,0x97,0x74,0xD0,0x91,0x0C,0xA0,0x98,
+0xE8,0x17,0x63,0x27,0x3B,0x72,0xA0,0x07,0xB0,0x2F,0x6F,0x3A,0x00,0xAF,0xD7,0x4C,
+0xDB,0x37,0x9C,0xB5,0x1E,0x67,0xB5,0x81,0x5E,0xC9,0xB9,0xC1,0x7B,0xE0,0xC6,0xB5,
+0x02,0x8C,0xD6,0x6D,0xD4,0x00,0x0B,0x57,0x7E,0xF7,0x99,0x50,0xD4,0x83,0xBC,0x8F,
+0xF4,0xEB,0xAD,0x20,0xF4,0x22,0x78,0xAF,0x55,0x2C,0xD2,0xDC,0x55,0xDA,0xEE,0xF2,
+0xE7,0x7B,0x24,0x76,0x19,0xB8,0x2E,0x1D,0xDA,0x37,0x18,0xBB,0x85,0x77,0xEF,0xEB,
+0x2E,0xB4,0x3E,0xC1,0xE0,0x49,0x67,0xB4,0xA4,0xF9,0xFF,0x9F,0xDC,0x76,0xAC,0x92,
+0xB4,0x96,0xEC,0xBA,0x36,0x46,0x80,0xCC,0xA4,0xF9,0x89,0x3E,0xF9,0x7D,
+};
+
+/* Test basic add delete update copy matching stuff. */
+static void tests(void)
+{
+    SecTrustRef trust;
+    SecCertificateRef anchor, leaf;
+    SecPolicyRef policy;
+    isnt(anchor = SecCertificateCreateWithBytes(NULL, _ca_certificate, sizeof(_ca_certificate)),
+                                                NULL, "create anchor");
+    isnt(leaf = SecCertificateCreateWithBytes(NULL, _ipsec_certificate, sizeof(_ipsec_certificate)),
+                                                NULL, "create leaf");
+
+    CFArrayRef anchor_certs = CFArrayCreate(NULL, (const void **)&anchor, 1, NULL);
+    CFArrayRef leaf_certs = CFArrayCreate(NULL, (const void **)&leaf, 1, NULL);
+
+    const void *host[] = { CFSTR("ipsec.apple.com"), CFSTR("17.255.42.1"),
+        CFSTR("ipsec2.apple.com"), CFSTR("17.255.42.2"),
+        /* CFSTR("user@fqdn.com"), */ NULL };
+    CFStringRef *host_value = (CFStringRef*)host;
+    while (*host_value) {
+        isnt(policy = SecPolicyCreateIPSec(true, *host_value++), NULL, "create ipsec policy instance");
+
+        ok_status(SecTrustCreateWithCertificates(leaf_certs, policy, &trust), "create trust for leaf");
+
+        CFTimeZoneRef tz = CFTimeZoneCreateWithName(NULL, CFSTR("CET"), true);
+        CFGregorianDate date_check = { 2009, 12, 1, 19, 10, 0 };
+        CFAbsoluteTime atime = CFGregorianDateGetAbsoluteTime(date_check, tz);
+        CFReleaseNull(tz);
+        CFDateRef date = CFDateCreate(NULL, atime);
+        ok_status(SecTrustSetVerifyDate(trust, date), "set date");
+
+        ok_status(SecTrustSetAnchorCertificates(trust, anchor_certs), "set anchor");
+
+        SecTrustResultType trustResult;
+        ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+        is_status(trustResult, kSecTrustResultUnspecified,
+            "trust is kSecTrustResultUnspecified");
+
+        is(SecTrustGetCertificateCount(trust), 2, "cert count is 2");
+
+        CFReleaseNull(trust);
+        CFReleaseNull(policy);
+        CFReleaseNull(date);
+    }
+
+    const void *hosts[] = { CFSTR("test.apple.com"), CFSTR("fake.apple.com"), CFSTR("ipsec.apple.com") };
+    CFArrayRef valid_hosts = CFArrayCreate(NULL, hosts, array_size(hosts), NULL);
+    isnt(policy = SecPolicyCreateEAP(true, valid_hosts), NULL, "create eap policy instance");
+
+    ok_status(SecTrustCreateWithCertificates(leaf_certs, policy, &trust), "create trust for leaf");
+
+    CFTimeZoneRef tz = CFTimeZoneCreateWithName(NULL, CFSTR("CET"), true);
+    CFGregorianDate date_check = { 2009, 12, 1, 19, 10, 0 };
+    CFAbsoluteTime atime = CFGregorianDateGetAbsoluteTime(date_check, tz);
+    CFReleaseNull(tz);
+    CFDateRef date = CFDateCreate(NULL, atime);
+    ok_status(SecTrustSetVerifyDate(trust, date), "set date");
+
+    ok_status(SecTrustSetAnchorCertificates(trust, anchor_certs), "set anchor");
+
+    SecTrustResultType trustResult;
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultUnspecified,
+        "trust is kSecTrustResultUnspecified");
+
+    CFReleaseNull(trust);
+    CFReleaseNull(policy);
+    CFReleaseNull(date);
+
+    CFReleaseSafe(valid_hosts);
+    CFReleaseSafe(leaf_certs);
+    CFReleaseSafe(anchor_certs);
+    CFReleaseSafe(leaf);
+    CFReleaseSafe(anchor);
+
+
+    isnt(anchor = SecCertificateCreateWithBytes(NULL, ivpntest_com_root_der, ivpntest_com_root_der_len),
+                                                NULL, "create anchor");
+    isnt(leaf = SecCertificateCreateWithBytes(NULL, vpn3000_id_cer, vpn3000_id_cer_len),
+                                                NULL, "create leaf");
+
+    anchor_certs = CFArrayCreate(NULL, (const void **)&anchor, 1, NULL);
+    leaf_certs = CFArrayCreate(NULL, (const void **)&leaf, 1, NULL);
+
+    isnt(policy = SecPolicyCreateIPSec(true, CFSTR("vpn3000.ivpntest.com")), NULL, "create ipsec policy instance");
+    ok_status(SecTrustCreateWithCertificates(leaf_certs, policy, &trust), "create trust for leaf");
+
+    tz = CFTimeZoneCreateWithName(NULL, CFSTR("CET"), true);
+    CFGregorianDate date_check_too = { 2009, 3, 11, 19, 10, 0 };
+    atime = CFGregorianDateGetAbsoluteTime(date_check_too, tz);
+    CFReleaseNull(tz);
+    date = CFDateCreate(NULL, atime);
+    ok_status(SecTrustSetVerifyDate(trust, date), "set date");
+
+    ok_status(SecTrustSetAnchorCertificates(trust, anchor_certs), "set anchor");
+
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultUnspecified,
+        "trust is kSecTrustResultUnspecified");
+
+    is(SecTrustGetCertificateCount(trust), 2, "cert count is 2");
+
+    CFReleaseNull(trust);
+    CFReleaseNull(policy);
+    CFReleaseNull(date);
+
+    CFReleaseSafe(leaf_certs);
+    CFReleaseSafe(anchor_certs);
+    CFReleaseSafe(leaf);
+    CFReleaseSafe(anchor);
+
+}
+
+static void testnontrustedcachainbuilder(void) {
+    SecCertificateRef user, imcasta, rootca;
+    CFMutableArrayRef certs;
+    SecPolicyRef policy;
+    SecTrustRef trust;
+
+    isnt(user = SecCertificateCreateWithBytes(NULL,
+        wifiuser_certificate, sizeof(wifiuser_certificate)), NULL,
+        "create wifiuser");
+    isnt(imcasta = SecCertificateCreateWithBytes(NULL,
+        wifiimcasta_certificate, sizeof(wifiimcasta_certificate)), NULL,
+        "create wifiimcasta");
+    isnt(rootca = SecCertificateCreateWithBytes(NULL,
+        wifirootca_certificate, sizeof(wifirootca_certificate)), NULL,
+        "create wifirootca");
+
+    certs = CFArrayCreateMutable(NULL, 0, NULL);
+    CFArrayAppendValue(certs, user);
+    CFArrayAppendValue(certs, imcasta);
+    CFArrayAppendValue(certs, rootca);
+    isnt(policy = SecPolicyCreateEAP(false, NULL), NULL,
+        "create eap client cert policy instance");
+    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
+        "create trust with 3 certs");
+
+    SecTrustResultType trustResult;
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultRecoverableTrustFailure,
+        "trust is kSecTrustResultRecoverableTrustFailure");
+
+    is(SecTrustGetCertificateCount(trust), 3, "cert count is 3");
+
+    CFReleaseNull(user);
+    CFReleaseNull(imcasta);
+    CFReleaseNull(rootca);
+    CFReleaseNull(certs);
+    CFReleaseNull(policy);
+    CFReleaseNull(trust);
+}
+
+int si_25_sectrust_ipsec_eap(int argc, char *const *argv)
+{
+    plan_tests(53);
+
+
+    tests();
+    testnontrustedcachainbuilder();
+
+    return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-26-applicationsigning.c b/sec/Security/Regressions/secitem/si-26-applicationsigning.c
new file mode 100644 (file)
index 0000000..fbbaeb1
--- /dev/null
@@ -0,0 +1,408 @@
+/*
+ * Copyright (c) 2007,2009-2010 Apple Inc. All Rights Reserved.
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecPolicyPriv.h>
+#include <Security/SecTrust.h>
+#include <Security/SecTrustPriv.h>
+#include <Security/SecKey.h>
+#include <Security/SecInternal.h>
+#include <CommonCrypto/CommonDigest.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <utilities/SecIOFormat.h>
+
+#include "Security_regressions.h"
+
+/* subject:/CN=iPhone Developer: Katherine Kojima/OU=Core OS Plus Others/O=Core OS Plus Others/C=usa */
+/* issuer :/C=US/O=Apple Inc./OU=Apple Worldwide Developer Relations/CN=Apple Worldwide Developer Relations Certification Authority */
+unsigned char codesigning_certificate[1415]={
+0x30,0x82,0x05,0x83,0x30,0x82,0x04,0x6B,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x70,
+0xA9,0x16,0x20,0x02,0xA2,0xD4,0x50,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,
+0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81,0x96,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,
+0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x0C,
+0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x2C,0x30,0x2A,0x06,
+0x03,0x55,0x04,0x0B,0x0C,0x23,0x41,0x70,0x70,0x6C,0x65,0x20,0x57,0x6F,0x72,0x6C,
+0x64,0x77,0x69,0x64,0x65,0x20,0x44,0x65,0x76,0x65,0x6C,0x6F,0x70,0x65,0x72,0x20,
+0x52,0x65,0x6C,0x61,0x74,0x69,0x6F,0x6E,0x73,0x31,0x44,0x30,0x42,0x06,0x03,0x55,
+0x04,0x03,0x0C,0x3B,0x41,0x70,0x70,0x6C,0x65,0x20,0x57,0x6F,0x72,0x6C,0x64,0x77,
+0x69,0x64,0x65,0x20,0x44,0x65,0x76,0x65,0x6C,0x6F,0x70,0x65,0x72,0x20,0x52,0x65,
+0x6C,0x61,0x74,0x69,0x6F,0x6E,0x73,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,
+0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,
+0x1E,0x17,0x0D,0x30,0x38,0x30,0x33,0x32,0x36,0x31,0x37,0x30,0x37,0x34,0x36,0x5A,
+0x17,0x0D,0x30,0x38,0x30,0x39,0x32,0x34,0x31,0x37,0x30,0x37,0x34,0x36,0x5A,0x30,
+0x77,0x31,0x2B,0x30,0x29,0x06,0x03,0x55,0x04,0x03,0x0C,0x22,0x69,0x50,0x68,0x6F,
+0x6E,0x65,0x20,0x44,0x65,0x76,0x65,0x6C,0x6F,0x70,0x65,0x72,0x3A,0x20,0x4B,0x61,
+0x74,0x68,0x65,0x72,0x69,0x6E,0x65,0x20,0x4B,0x6F,0x6A,0x69,0x6D,0x61,0x31,0x1C,
+0x30,0x1A,0x06,0x03,0x55,0x04,0x0B,0x0C,0x13,0x43,0x6F,0x72,0x65,0x20,0x4F,0x53,
+0x20,0x50,0x6C,0x75,0x73,0x20,0x4F,0x74,0x68,0x65,0x72,0x73,0x31,0x1C,0x30,0x1A,
+0x06,0x03,0x55,0x04,0x0A,0x0C,0x13,0x43,0x6F,0x72,0x65,0x20,0x4F,0x53,0x20,0x50,
+0x6C,0x75,0x73,0x20,0x4F,0x74,0x68,0x65,0x72,0x73,0x31,0x0C,0x30,0x0A,0x06,0x03,
+0x55,0x04,0x06,0x13,0x03,0x75,0x73,0x61,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,
+0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xD4,0x2B,0xF2,0x10,0x71,0x0B,0xBB,
+0x3D,0xA0,0x1A,0x32,0x41,0xBC,0xA9,0x55,0xF4,0xFB,0x6C,0x9C,0xB5,0x32,0x52,0x10,
+0x7E,0x41,0xF4,0x2C,0x18,0x3A,0x4F,0x32,0x9D,0xA3,0x64,0x28,0xDD,0x94,0xD0,0xB8,
+0x3F,0xF9,0x7C,0x62,0xE6,0xF5,0xF1,0x16,0x0D,0x7F,0xBA,0xEC,0xBF,0xD9,0x95,0xD4,
+0x7A,0xD7,0x4D,0x32,0x0F,0xCD,0x6D,0xBC,0xF3,0x10,0xDE,0xE8,0x5D,0xA1,0xDA,0x98,
+0x8F,0x6C,0x75,0xF7,0x7B,0xBE,0x33,0x43,0xBD,0x95,0xFA,0x35,0xD6,0x77,0x81,0x68,
+0x02,0x9C,0x41,0x99,0x0B,0x53,0x5F,0x58,0xF3,0x85,0x4C,0xAB,0x06,0xC2,0xC0,0xC4,
+0xD8,0x68,0x64,0xE3,0x14,0x5F,0x62,0x75,0xD5,0x66,0x9B,0xEE,0x4A,0x49,0xBA,0xC7,
+0x7B,0xD1,0xE6,0x96,0x9D,0xE5,0xEF,0x99,0x0E,0x87,0xEC,0xE3,0xA4,0x54,0x3E,0x19,
+0xBB,0x87,0x53,0x9C,0x3C,0x6A,0x94,0x6B,0x22,0x1A,0x01,0xAF,0x21,0xD5,0xDA,0xB0,
+0x92,0xE0,0x70,0x61,0xDD,0xC1,0x37,0x60,0x1F,0xC3,0xB0,0xFC,0xB3,0x00,0x4A,0x56,
+0x9D,0x70,0xC3,0xDE,0x66,0xD0,0xEF,0x39,0x88,0x48,0xBD,0x6D,0xA6,0xB2,0x2C,0x0A,
+0x78,0xCE,0x05,0x62,0x9B,0xE9,0x18,0x4E,0x59,0xC8,0xDC,0xD3,0xDF,0xB6,0x77,0xB5,
+0xA3,0xDA,0x62,0x15,0x9A,0x50,0x1E,0x28,0x55,0x70,0xC2,0xB7,0x97,0x63,0x00,0x1E,
+0x0E,0x3A,0x8B,0xA6,0x13,0xE5,0xE0,0xD6,0xE6,0xFA,0x61,0xDE,0x5F,0x30,0x72,0xAA,
+0xE4,0xBA,0x21,0x74,0x63,0x4A,0xF2,0x18,0x4C,0x99,0x8D,0x75,0x27,0x91,0xF9,0xD4,
+0x08,0xAE,0xB6,0xDA,0x69,0x33,0x06,0x7F,0x17,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,
+0x01,0xF1,0x30,0x82,0x01,0xED,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,
+0x04,0x02,0x30,0x00,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,
+0x03,0x02,0x07,0x80,0x30,0x16,0x06,0x03,0x55,0x1D,0x25,0x01,0x01,0xFF,0x04,0x0C,
+0x30,0x0A,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x03,0x30,0x1D,0x06,0x03,
+0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x6A,0x6D,0x56,0xC6,0xA5,0x0E,0xC2,0x97,0xF7,
+0x17,0x48,0xBE,0xA0,0x07,0xFF,0x77,0xE9,0xEF,0xB2,0xED,0x30,0x1F,0x06,0x03,0x55,
+0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x88,0x27,0x17,0x09,0xA9,0xB6,0x18,0x60,
+0x8B,0xEC,0xEB,0xBA,0xF6,0x47,0x59,0xC5,0x52,0x54,0xA3,0xB7,0x30,0x82,0x01,0x0F,
+0x06,0x03,0x55,0x1D,0x20,0x04,0x82,0x01,0x06,0x30,0x82,0x01,0x02,0x30,0x81,0xFF,
+0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,0x05,0x01,0x30,0x81,0xF1,0x30,0x81,
+0xC3,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x02,0x30,0x81,0xB6,0x0C,0x81,
+0xB3,0x52,0x65,0x6C,0x69,0x61,0x6E,0x63,0x65,0x20,0x6F,0x6E,0x20,0x74,0x68,0x69,
+0x73,0x20,0x63,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x62,0x79,
+0x20,0x61,0x6E,0x79,0x20,0x70,0x61,0x72,0x74,0x79,0x20,0x61,0x73,0x73,0x75,0x6D,
+0x65,0x73,0x20,0x61,0x63,0x63,0x65,0x70,0x74,0x61,0x6E,0x63,0x65,0x20,0x6F,0x66,
+0x20,0x74,0x68,0x65,0x20,0x74,0x68,0x65,0x6E,0x20,0x61,0x70,0x70,0x6C,0x69,0x63,
+0x61,0x62,0x6C,0x65,0x20,0x73,0x74,0x61,0x6E,0x64,0x61,0x72,0x64,0x20,0x74,0x65,
+0x72,0x6D,0x73,0x20,0x61,0x6E,0x64,0x20,0x63,0x6F,0x6E,0x64,0x69,0x74,0x69,0x6F,
+0x6E,0x73,0x20,0x6F,0x66,0x20,0x75,0x73,0x65,0x2C,0x20,0x63,0x65,0x72,0x74,0x69,
+0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x70,0x6F,0x6C,0x69,0x63,0x79,0x20,0x61,0x6E,
+0x64,0x20,0x63,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,
+0x70,0x72,0x61,0x63,0x74,0x69,0x63,0x65,0x20,0x73,0x74,0x61,0x74,0x65,0x6D,0x65,
+0x6E,0x74,0x73,0x2E,0x30,0x29,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,
+0x16,0x1D,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x61,0x70,0x70,
+0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x2F,0x61,0x70,0x70,0x6C,0x65,0x63,0x61,0x2F,0x30,
+0x4D,0x06,0x03,0x55,0x1D,0x1F,0x04,0x46,0x30,0x44,0x30,0x42,0xA0,0x40,0xA0,0x3E,
+0x86,0x3C,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x64,0x65,0x76,0x65,0x6C,0x6F,0x70,
+0x65,0x72,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x2F,0x63,0x65,0x72,
+0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x61,0x75,0x74,0x68,0x6F,0x72,
+0x69,0x74,0x79,0x2F,0x77,0x77,0x64,0x72,0x63,0x61,0x2E,0x63,0x72,0x6C,0x30,0x13,
+0x06,0x0A,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,0x06,0x01,0x02,0x01,0x01,0xFF,0x04,
+0x02,0x05,0x00,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,
+0x05,0x00,0x03,0x82,0x01,0x01,0x00,0xA1,0x1D,0x8C,0xB9,0x21,0x59,0xC8,0xC0,0x08,
+0x25,0x97,0x78,0x0D,0x04,0x14,0x85,0xA8,0xFC,0xC3,0xB1,0x7E,0x72,0x45,0x4C,0x96,
+0x82,0x90,0x73,0x68,0x24,0x65,0x11,0x0F,0xB8,0x0D,0xB8,0xE4,0x46,0xD5,0x61,0x01,
+0x64,0xB8,0x51,0xF8,0xAE,0xE7,0xCF,0xF2,0x7A,0x93,0x78,0xC7,0x9A,0xD3,0xF4,0xF8,
+0x04,0xDB,0xF1,0x4A,0xDB,0x05,0x98,0x2F,0xF3,0x39,0x37,0xB0,0x2B,0x49,0x9A,0x82,
+0x36,0x63,0xF4,0xB3,0x70,0x75,0x43,0xE3,0xF1,0xBD,0xB5,0x68,0x0C,0xB3,0x7E,0xA3,
+0xB3,0x29,0x55,0xD2,0x34,0xD8,0x13,0xB5,0x87,0xD3,0xCE,0xEB,0x26,0xE5,0xCB,0x1F,
+0xF1,0xE1,0x89,0x7A,0xB0,0x39,0xB2,0x2E,0x88,0x76,0xE9,0x68,0x69,0x4E,0x90,0xB4,
+0x7C,0x42,0x7A,0x2C,0xDF,0x33,0xCF,0x2F,0xBD,0x38,0x3A,0xCC,0xB3,0xC7,0x47,0x9C,
+0xC4,0x87,0xCE,0x1A,0x1E,0xF4,0xBB,0xC9,0x97,0x35,0x1C,0x65,0xC2,0xF0,0x2F,0x98,
+0x50,0x96,0xA6,0x6C,0xF5,0x1B,0x45,0xE6,0x48,0xBE,0x17,0xFB,0xF6,0x61,0x3E,0x94,
+0xF3,0x49,0x57,0xB5,0x54,0x5F,0xE1,0x92,0x30,0xF9,0xC6,0xB7,0x21,0xE0,0x30,0x64,
+0x83,0xE7,0x49,0x97,0x8D,0xDC,0xE5,0x9D,0x89,0xA9,0x14,0x2E,0xEF,0x21,0x00,0xBA,
+0x13,0x63,0xF4,0xCD,0x2F,0x61,0x17,0x58,0xAB,0xD3,0xA8,0x06,0x54,0x5F,0x60,0xB3,
+0xBE,0xED,0xE8,0xF8,0xA4,0x29,0x2F,0xE1,0x4A,0x0E,0xB1,0xFE,0xCE,0x73,0x14,0x9A,
+0x3A,0x95,0xFC,0xC8,0xB6,0x53,0xBC,0xBF,0x3A,0xB0,0xAE,0x80,0x76,0xF5,0x57,0x47,
+0xD2,0x1C,0x08,0x19,0x22,0xF2,0x6D,
+};
+
+/* subject:/C=US/O=Apple Inc./OU=Apple Worldwide Developer Relations/CN=Apple Worldwide Developer Relations Certification Authority */
+/* issuer :/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Root CA */
+unsigned char wwdr_intermediate_cert[1063]={
+0x30,0x82,0x04,0x23,0x30,0x82,0x03,0x0B,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x19,
+0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,
+0x62,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,
+0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x13,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,
+0x6E,0x63,0x2E,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0B,0x13,0x1D,0x41,0x70,
+0x70,0x6C,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,
+0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x31,0x16,0x30,0x14,0x06,
+0x03,0x55,0x04,0x03,0x13,0x0D,0x41,0x70,0x70,0x6C,0x65,0x20,0x52,0x6F,0x6F,0x74,
+0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x30,0x38,0x30,0x32,0x31,0x34,0x31,0x38,0x35,
+0x36,0x33,0x35,0x5A,0x17,0x0D,0x31,0x36,0x30,0x32,0x31,0x34,0x31,0x38,0x35,0x36,
+0x33,0x35,0x5A,0x30,0x81,0x96,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,
+0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0A,0x41,0x70,
+0x70,0x6C,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x2C,0x30,0x2A,0x06,0x03,0x55,0x04,
+0x0B,0x0C,0x23,0x41,0x70,0x70,0x6C,0x65,0x20,0x57,0x6F,0x72,0x6C,0x64,0x77,0x69,
+0x64,0x65,0x20,0x44,0x65,0x76,0x65,0x6C,0x6F,0x70,0x65,0x72,0x20,0x52,0x65,0x6C,
+0x61,0x74,0x69,0x6F,0x6E,0x73,0x31,0x44,0x30,0x42,0x06,0x03,0x55,0x04,0x03,0x0C,
+0x3B,0x41,0x70,0x70,0x6C,0x65,0x20,0x57,0x6F,0x72,0x6C,0x64,0x77,0x69,0x64,0x65,
+0x20,0x44,0x65,0x76,0x65,0x6C,0x6F,0x70,0x65,0x72,0x20,0x52,0x65,0x6C,0x61,0x74,
+0x69,0x6F,0x6E,0x73,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,
+0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x82,0x01,0x22,
+0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,
+0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xCA,0x38,0x54,
+0xA6,0xCB,0x56,0xAA,0xC8,0x24,0x39,0x48,0xE9,0x8C,0xEE,0xEC,0x5F,0xB8,0x7F,0x26,
+0x91,0xBC,0x34,0x53,0x7A,0xCE,0x7C,0x63,0x80,0x61,0x77,0x64,0x5E,0xA5,0x07,0x23,
+0xB6,0x39,0xFE,0x50,0x2D,0x15,0x56,0x58,0x70,0x2D,0x7E,0xC4,0x6E,0xC1,0x4A,0x85,
+0x3E,0x2F,0xF0,0xDE,0x84,0x1A,0xA1,0x57,0xC9,0xAF,0x7B,0x18,0xFF,0x6A,0xFA,0x15,
+0x12,0x49,0x15,0x08,0x19,0xAC,0xAA,0xDB,0x2A,0x32,0xED,0x96,0x63,0x68,0x52,0x15,
+0x3D,0x8C,0x8A,0xEC,0xBF,0x6B,0x18,0x95,0xE0,0x03,0xAC,0x01,0x7D,0x97,0x05,0x67,
+0xCE,0x0E,0x85,0x95,0x37,0x6A,0xED,0x09,0xB6,0xAE,0x67,0xCD,0x51,0x64,0x9F,0xC6,
+0x5C,0xD1,0xBC,0x57,0x6E,0x67,0x35,0x80,0x76,0x36,0xA4,0x87,0x81,0x6E,0x38,0x8F,
+0xD8,0x2B,0x15,0x4E,0x7B,0x25,0xD8,0x5A,0xBF,0x4E,0x83,0xC1,0x8D,0xD2,0x93,0xD5,
+0x1A,0x71,0xB5,0x60,0x9C,0x9D,0x33,0x4E,0x55,0xF9,0x12,0x58,0x0C,0x86,0xB8,0x16,
+0x0D,0xC1,0xE5,0x77,0x45,0x8D,0x50,0x48,0xBA,0x2B,0x2D,0xE4,0x94,0x85,0xE1,0xE8,
+0xC4,0x9D,0xC6,0x68,0xA5,0xB0,0xA3,0xFC,0x67,0x7E,0x70,0xBA,0x02,0x59,0x4B,0x77,
+0x42,0x91,0x39,0xB9,0xF5,0xCD,0xE1,0x4C,0xEF,0xC0,0x3B,0x48,0x8C,0xA6,0xE5,0x21,
+0x5D,0xFD,0x6A,0x6A,0xBB,0xA7,0x16,0x35,0x60,0xD2,0xE6,0xAD,0xF3,0x46,0x29,0xC9,
+0xE8,0xC3,0x8B,0xE9,0x79,0xC0,0x6A,0x61,0x67,0x15,0xB2,0xF0,0xFD,0xE5,0x68,0xBC,
+0x62,0x5F,0x6E,0xCF,0x99,0xDD,0xEF,0x1B,0x63,0xFE,0x92,0x65,0xAB,0x02,0x03,0x01,
+0x00,0x01,0xA3,0x81,0xAE,0x30,0x81,0xAB,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,
+0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x86,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,
+0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,
+0x04,0x16,0x04,0x14,0x88,0x27,0x17,0x09,0xA9,0xB6,0x18,0x60,0x8B,0xEC,0xEB,0xBA,
+0xF6,0x47,0x59,0xC5,0x52,0x54,0xA3,0xB7,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,
+0x18,0x30,0x16,0x80,0x14,0x2B,0xD0,0x69,0x47,0x94,0x76,0x09,0xFE,0xF4,0x6B,0x8D,
+0x2E,0x40,0xA6,0xF7,0x47,0x4D,0x7F,0x08,0x5E,0x30,0x36,0x06,0x03,0x55,0x1D,0x1F,
+0x04,0x2F,0x30,0x2D,0x30,0x2B,0xA0,0x29,0xA0,0x27,0x86,0x25,0x68,0x74,0x74,0x70,
+0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,
+0x2F,0x61,0x70,0x70,0x6C,0x65,0x63,0x61,0x2F,0x72,0x6F,0x6F,0x74,0x2E,0x63,0x72,
+0x6C,0x30,0x10,0x06,0x0A,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,0x06,0x02,0x01,0x04,
+0x02,0x05,0x00,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,
+0x05,0x00,0x03,0x82,0x01,0x01,0x00,0xDA,0x32,0x00,0x96,0xC5,0x54,0x94,0xD3,0x3B,
+0x82,0x37,0x66,0x7D,0x2E,0x68,0xD5,0xC3,0xC6,0xB8,0xCB,0x26,0x8C,0x48,0x90,0xCF,
+0x13,0x24,0x6A,0x46,0x8E,0x63,0xD4,0xF0,0xD0,0x13,0x06,0xDD,0xD8,0xC4,0xC1,0x37,
+0x15,0xF2,0x33,0x13,0x39,0x26,0x2D,0xCE,0x2E,0x55,0x40,0xE3,0x0B,0x03,0xAF,0xFA,
+0x12,0xC2,0xE7,0x0D,0x21,0xB8,0xD5,0x80,0xCF,0xAC,0x28,0x2F,0xCE,0x2D,0xB3,0x4E,
+0xAF,0x86,0x19,0x04,0xC6,0xE9,0x50,0xDD,0x4C,0x29,0x47,0x10,0x23,0xFC,0x6C,0xBB,
+0x1B,0x98,0x6B,0x48,0x89,0xE1,0x5B,0x9D,0xDE,0x46,0xDB,0x35,0x85,0x35,0xEF,0x3E,
+0xD0,0xE2,0x58,0x4B,0x38,0xF4,0xED,0x75,0x5A,0x1F,0x5C,0x70,0x1D,0x56,0x39,0x12,
+0xE5,0xE1,0x0D,0x11,0xE4,0x89,0x25,0x06,0xBD,0xD5,0xB4,0x15,0x8E,0x5E,0xD0,0x59,
+0x97,0x90,0xE9,0x4B,0x81,0xE2,0xDF,0x18,0xAF,0x44,0x74,0x1E,0x19,0xA0,0x3A,0x47,
+0xCC,0x91,0x1D,0x3A,0xEB,0x23,0x5A,0xFE,0xA5,0x2D,0x97,0xF7,0x7B,0xBB,0xD6,0x87,
+0x46,0x42,0x85,0xEB,0x52,0x3D,0x26,0xB2,0x63,0xA8,0xB4,0xB1,0xCA,0x8F,0xF4,0xCC,
+0xE2,0xB3,0xC8,0x47,0xE0,0xBF,0x9A,0x59,0x83,0xFA,0xDA,0x98,0x53,0x2A,0x82,0xF5,
+0x7C,0x65,0x2E,0x95,0xD9,0x33,0x5D,0xF5,0xED,0x65,0xCC,0x31,0x37,0xC5,0x5A,0x04,
+0xE8,0x6B,0xE1,0xE7,0x88,0x03,0x4A,0x75,0x9E,0x9B,0x28,0xCB,0x4A,0x40,0x88,0x65,
+0x43,0x75,0xDD,0xCB,0x3A,0x25,0x23,0xC5,0x9E,0x57,0xF8,0x2E,0xCE,0xD2,0xA9,0x92,
+0x5E,0x73,0x2E,0x2F,0x25,0x75,0x15,
+};
+
+/* TODO: Use the shared version of this function in print_cert.c. */
+static void print_line(CFStringRef line) {
+    UInt8 buf[256];
+    CFRange range = { .location = 0 };
+    range.length = CFStringGetLength(line);
+    while (range.length > 0) {
+        CFIndex bytesUsed = 0;
+        CFIndex converted = CFStringGetBytes(line, range, kCFStringEncodingUTF8, 0, false, buf, sizeof(buf), &bytesUsed);
+        fwrite(buf, 1, bytesUsed, stdout);
+        range.length -= converted;
+        range.location += converted;
+    }
+    fputc('\n', stdout);
+}
+
+static void printPlist(CFArrayRef plist, CFIndex indent, CFIndex maxWidth) {
+    CFIndex count = CFArrayGetCount(plist);
+    CFIndex ix;
+    for (ix = 0; ix < count ; ++ix) {
+        CFDictionaryRef prop = (CFDictionaryRef)CFArrayGetValueAtIndex(plist,
+            ix);
+        CFStringRef pType = (CFStringRef)CFDictionaryGetValue(prop,
+            kSecPropertyKeyType);
+        CFStringRef label = (CFStringRef)CFDictionaryGetValue(prop,
+            kSecPropertyKeyLabel);
+        CFStringRef llabel = (CFStringRef)CFDictionaryGetValue(prop,
+            kSecPropertyKeyLocalizedLabel);
+        CFTypeRef value = (CFTypeRef)CFDictionaryGetValue(prop,
+            kSecPropertyKeyValue);
+
+        bool isSection = CFEqual(pType, kSecPropertyTypeSection);
+        CFMutableStringRef line = CFStringCreateMutable(NULL, 0);
+        CFIndex jx = 0;
+        for (jx = 0; jx < indent; ++jx) {
+            CFStringAppend(line, CFSTR("    "));
+        }
+        if (llabel) {
+            CFStringAppend(line, llabel);
+            if (!isSection) {
+                for (jx = CFStringGetLength(llabel) + indent * 4;
+                    jx < maxWidth; ++jx) {
+                    CFStringAppend(line, CFSTR(" "));
+                }
+                CFStringAppend(line, CFSTR(" : "));
+            }
+        }
+        if (CFEqual(pType, kSecPropertyTypeWarning)) {
+            CFStringAppend(line, CFSTR("*WARNING* "));
+            CFStringAppend(line, (CFStringRef)value);
+        } else if (CFEqual(pType, kSecPropertyTypeError)) {
+            CFStringAppend(line, CFSTR("*ERROR* "));
+            CFStringAppend(line, (CFStringRef)value);
+        } else if (CFEqual(pType, kSecPropertyTypeSuccess)) {
+            CFStringAppend(line, CFSTR("*OK* "));
+            CFStringAppend(line, (CFStringRef)value);
+        } else if (CFEqual(pType, kSecPropertyTypeTitle)) {
+            CFStringAppend(line, CFSTR("*"));
+            CFStringAppend(line, (CFStringRef)value);
+            CFStringAppend(line, CFSTR("*"));
+        } else if (CFEqual(pType, kSecPropertyTypeSection)) {
+        } else if (CFEqual(pType, kSecPropertyTypeData)) {
+            CFDataRef data = (CFDataRef)value;
+            CFIndex length = CFDataGetLength(data);
+            if (length > 20)
+                CFStringAppendFormat(line, NULL, CFSTR("[%" PRIdCFIndex " bytes] "), length);
+            const UInt8 *bytes = CFDataGetBytePtr(data);
+            for (jx = 0; jx < length; ++jx) {
+                if (jx == 0)
+                    CFStringAppendFormat(line, NULL, CFSTR("%02X"), bytes[jx]);
+                else if (jx < 15 || length <= 20)
+                    CFStringAppendFormat(line, NULL, CFSTR(" %02X"),
+                        bytes[jx]);
+                else {
+                    CFStringAppend(line, CFSTR(" ..."));
+                    break;
+                }
+            }
+        } else if (CFEqual(pType, kSecPropertyTypeString)) {
+            CFStringAppend(line, (CFStringRef)value);
+        } else if (CFEqual(pType, kSecPropertyTypeDate)) {
+            CFLocaleRef lc = CFLocaleCopyCurrent();
+            CFDateFormatterRef df = CFDateFormatterCreate(NULL, lc,
+                kCFDateFormatterFullStyle, kCFDateFormatterFullStyle);
+            //CFTimeZoneRef tz = CFTimeZoneCreateWithName(NULL, CFSTR("GMT"), false);
+            //CFDateFormatterSetProperty(df, kCFDateFormatterTimeZone, tz);
+            //CFRelease(tz);
+            CFDateRef date = (CFDateRef)value;
+            CFStringRef ds = CFDateFormatterCreateStringWithDate(NULL, df,
+                date);
+            CFStringAppend(line, ds);
+            CFRelease(ds);
+            CFRelease(df);
+            CFRelease(lc);
+        } else if (CFEqual(pType, kSecPropertyTypeURL)) {
+            CFURLRef url = (CFURLRef)value;
+            CFStringAppend(line, CFSTR("<"));
+            CFStringAppend(line, CFURLGetString(url));
+            CFStringAppend(line, CFSTR(">"));
+        } else {
+            CFStringAppendFormat(line, NULL, CFSTR("*unknown type %@* = %@"),
+            pType, value);
+        }
+
+               if (!isSection || label)
+                       print_line(line);
+               CFRelease(line);
+        if (isSection) {
+            printPlist((CFArrayRef)value, indent + 1, maxWidth);
+        }
+    }
+}
+
+static CFIndex maxLabelWidth(CFArrayRef plist, CFIndex indent) {
+    CFIndex count = CFArrayGetCount(plist);
+    CFIndex ix;
+    CFIndex maxWidth = 0;
+    for (ix = 0; ix < count ; ++ix) {
+        CFDictionaryRef prop = (CFDictionaryRef)CFArrayGetValueAtIndex(plist,
+            ix);
+        CFStringRef pType = (CFStringRef)CFDictionaryGetValue(prop,
+            kSecPropertyKeyType);
+        CFStringRef llabel = (CFStringRef)CFDictionaryGetValue(prop,
+            kSecPropertyKeyLocalizedLabel);
+        CFTypeRef value = (CFTypeRef)CFDictionaryGetValue(prop,
+            kSecPropertyKeyValue);
+
+        if (CFEqual(pType, kSecPropertyTypeSection)) {
+            CFIndex width = maxLabelWidth((CFArrayRef)value, indent + 1);
+            if (width > maxWidth)
+                maxWidth = width;
+        } else if (llabel) {
+            CFIndex width = indent * 4 + CFStringGetLength(llabel);
+            if (width > maxWidth)
+                maxWidth = width;
+        }
+    }
+
+    return maxWidth;
+}
+
+static void print_plist(CFArrayRef plist) {
+    if (plist)
+        printPlist(plist, 0, maxLabelWidth(plist, 0));
+    else
+        printf("NULL plist\n");
+}
+
+static void print_cert(SecCertificateRef cert, bool verbose) {
+    CFArrayRef plist;
+    if (verbose)
+        plist = SecCertificateCopyProperties(cert);
+    else {
+        CFAbsoluteTime now = CFAbsoluteTimeGetCurrent();
+        plist = SecCertificateCopySummaryProperties(cert, now);
+    }
+
+    CFStringRef subject = SecCertificateCopySubjectString(cert);
+    if (subject) {
+        print_line(subject);
+        CFRelease(subject);
+    } else {
+        print_line(CFSTR("no subject"));
+    }
+
+    print_plist(plist);
+    CFRelease(plist);
+}
+
+static void tests(void)
+{
+    SecTrustRef trust;
+    SecCertificateRef leaf, wwdr_intermediate;
+    SecPolicyRef policy;
+
+    isnt(wwdr_intermediate = SecCertificateCreateWithBytes(kCFAllocatorDefault,
+        wwdr_intermediate_cert, sizeof(wwdr_intermediate_cert)), NULL, "create WWDR intermediate");
+    isnt(leaf = SecCertificateCreateWithBytes(kCFAllocatorDefault,
+        codesigning_certificate, sizeof(codesigning_certificate)), NULL, "create leaf");
+
+    const void *vcerts[] = { leaf, wwdr_intermediate };
+    CFArrayRef certs = CFArrayCreate(kCFAllocatorDefault, vcerts, 2, NULL);
+
+    isnt(policy = SecPolicyCreateiPhoneProfileApplicationSigning(), NULL,
+        "create iPhoneProfileApplicationSigning policy instance");
+    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust for leaf");
+    CFDateRef verifyDate = CFDateCreate(kCFAllocatorDefault, 228244066);
+    ok_status(SecTrustSetVerifyDate(trust, verifyDate), "set verify date");
+    CFReleaseNull(verifyDate);
+    SecTrustResultType trustResult;
+    CFArrayRef properties = NULL;
+    properties = SecTrustCopyProperties(trust);
+    is(properties, NULL, "no properties returned before eval");
+    CFReleaseNull(properties);
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultUnspecified, "trust is kSecTrustResultUnspecified");
+    properties = SecTrustCopyProperties(trust);
+
+    if (properties) {
+        print_plist(properties);
+        print_cert(leaf, true);
+        print_cert(wwdr_intermediate, false);
+    }
+
+    CFReleaseNull(properties);
+    CFReleaseNull(trust);
+    CFReleaseNull(wwdr_intermediate);
+    CFReleaseNull(leaf);
+    CFReleaseNull(certs);
+    CFReleaseNull(policy);
+       CFReleaseNull(trust);
+}
+
+int si_26_applicationsigning(int argc, char *const *argv)
+{
+    plan_tests(8);
+
+
+    tests();
+
+    return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-27-sectrust-exceptions.c b/sec/Security/Regressions/secitem/si-27-sectrust-exceptions.c
new file mode 100644 (file)
index 0000000..75fdafa
--- /dev/null
@@ -0,0 +1,390 @@
+/*
+ * Copyright (c) 2006-2010 Apple Inc. All Rights Reserved.
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecPolicy.h>
+#include <Security/SecTrustPriv.h>
+#include <utilities/array_size.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "Security_regressions.h"
+
+/*
+       subject= /C=US/ST=California/L=Cupertino/O=Apple Computer, Inc./OU=Apple Internet Services/OU=Terms of use at www.verisign.com/rpa (c)00/CN=store.apple.com
+       issuer= /O=VeriSign Trust Network/OU=VeriSign, Inc./OU=VeriSign International Server CA - Class 3/OU=www.verisign.com/CPS Incorp.by Ref. LIABILITY LTD.(c)97 VeriSign
+       serial=4450E623F57E734FF85C1DEEFB976C86
+*/
+static const uint8_t _c0[] = {
+    0x30, 0x82, 0x04, 0x82, 0x30, 0x82, 0x03, 0xeb,
+    0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x44,
+    0x50, 0xe6, 0x23, 0xf5, 0x7e, 0x73, 0x4f, 0xf8,
+    0x5c, 0x1d, 0xee, 0xfb, 0x97, 0x6c, 0x86, 0x30,
+    0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+    0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81,
+    0xba, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55,
+    0x04, 0x0a, 0x13, 0x16, 0x56, 0x65, 0x72, 0x69,
+    0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75,
+    0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f,
+    0x72, 0x6b, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03,
+    0x55, 0x04, 0x0b, 0x13, 0x0e, 0x56, 0x65, 0x72,
+    0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49,
+    0x6e, 0x63, 0x2e, 0x31, 0x33, 0x30, 0x31, 0x06,
+    0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
+    0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x49,
+    0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69,
+    0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65, 0x72,
+    0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x20, 0x2d,
+    0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33,
+    0x31, 0x49, 0x30, 0x47, 0x06, 0x03, 0x55, 0x04,
+    0x0b, 0x13, 0x40, 0x77, 0x77, 0x77, 0x2e, 0x76,
+    0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e,
+    0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x50, 0x53, 0x20,
+    0x49, 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x62,
+    0x79, 0x20, 0x52, 0x65, 0x66, 0x2e, 0x20, 0x4c,
+    0x49, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59,
+    0x20, 0x4c, 0x54, 0x44, 0x2e, 0x28, 0x63, 0x29,
+    0x39, 0x37, 0x20, 0x56, 0x65, 0x72, 0x69, 0x53,
+    0x69, 0x67, 0x6e, 0x30, 0x1e, 0x17, 0x0d, 0x30,
+    0x35, 0x30, 0x33, 0x30, 0x32, 0x30, 0x30, 0x30,
+    0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x37,
+    0x30, 0x34, 0x30, 0x31, 0x32, 0x33, 0x35, 0x39,
+    0x35, 0x39, 0x5a, 0x30, 0x81, 0xc6, 0x31, 0x0b,
+    0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+    0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06,
+    0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x43, 0x61,
+    0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61,
+    0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
+    0x07, 0x14, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72,
+    0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1d, 0x30, 0x1b,
+    0x06, 0x03, 0x55, 0x04, 0x0a, 0x14, 0x14, 0x41,
+    0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x6f, 0x6d,
+    0x70, 0x75, 0x74, 0x65, 0x72, 0x2c, 0x20, 0x49,
+    0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, 0x06,
+    0x03, 0x55, 0x04, 0x0b, 0x14, 0x17, 0x41, 0x70,
+    0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x74, 0x65,
+    0x72, 0x6e, 0x65, 0x74, 0x20, 0x53, 0x65, 0x72,
+    0x76, 0x69, 0x63, 0x65, 0x73, 0x31, 0x33, 0x30,
+    0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x14, 0x2a,
+    0x54, 0x65, 0x72, 0x6d, 0x73, 0x20, 0x6f, 0x66,
+    0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x74, 0x20,
+    0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, 0x69,
+    0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
+    0x2f, 0x72, 0x70, 0x61, 0x20, 0x28, 0x63, 0x29,
+    0x30, 0x30, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03,
+    0x55, 0x04, 0x03, 0x14, 0x0f, 0x73, 0x74, 0x6f,
+    0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65,
+    0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x81, 0x9f, 0x30,
+    0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+    0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81,
+    0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81,
+    0x00, 0xbf, 0x8f, 0x59, 0x14, 0xbb, 0x91, 0xa4,
+    0xe6, 0x3e, 0x75, 0xf8, 0x38, 0x36, 0xfe, 0xcd,
+    0x9e, 0x5d, 0x3f, 0x14, 0x62, 0xfc, 0xe7, 0x48,
+    0x5f, 0x7e, 0x6b, 0x6e, 0x87, 0xd2, 0x31, 0x6e,
+    0x9d, 0x19, 0x92, 0x6f, 0xe3, 0xbc, 0x7e, 0x48,
+    0xb1, 0x2f, 0x9d, 0x70, 0x2c, 0x11, 0xdf, 0x35,
+    0xd1, 0xee, 0xd2, 0xd5, 0x37, 0x92, 0x4e, 0x06,
+    0x66, 0xb3, 0xc9, 0x9c, 0x99, 0xec, 0x09, 0xc6,
+    0xc4, 0xd6, 0xe6, 0x62, 0xb7, 0x97, 0x24, 0xd8,
+    0x38, 0x40, 0xf1, 0xa0, 0x1c, 0x0f, 0xf2, 0x3d,
+    0xaf, 0x4a, 0x93, 0xba, 0x11, 0xad, 0x67, 0xc4,
+    0x4b, 0x1d, 0x74, 0x33, 0x7c, 0xb9, 0x6b, 0x2d,
+    0xc5, 0x9b, 0x6a, 0xd2, 0xf2, 0x28, 0x08, 0x05,
+    0x18, 0x7d, 0xf0, 0xde, 0x28, 0x61, 0xf1, 0x81,
+    0xd5, 0x56, 0x4f, 0x20, 0x6e, 0xf3, 0x34, 0x89,
+    0x67, 0xd3, 0xa7, 0x09, 0xda, 0xc7, 0x89, 0x4d,
+    0xe1, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82,
+    0x01, 0x79, 0x30, 0x82, 0x01, 0x75, 0x30, 0x09,
+    0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30,
+    0x00, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f,
+    0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x46,
+    0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x3f, 0x30,
+    0x3d, 0x30, 0x3b, 0xa0, 0x39, 0xa0, 0x37, 0x86,
+    0x35, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+    0x63, 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72, 0x69,
+    0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
+    0x2f, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x33, 0x49,
+    0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69,
+    0x6f, 0x6e, 0x61, 0x6c, 0x53, 0x65, 0x72, 0x76,
+    0x65, 0x72, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x44,
+    0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3d, 0x30,
+    0x3b, 0x30, 0x39, 0x06, 0x0b, 0x60, 0x86, 0x48,
+    0x01, 0x86, 0xf8, 0x45, 0x01, 0x07, 0x17, 0x03,
+    0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06,
+    0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c,
+    0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f,
+    0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, 0x69,
+    0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
+    0x2f, 0x72, 0x70, 0x61, 0x30, 0x28, 0x06, 0x03,
+    0x55, 0x1d, 0x25, 0x04, 0x21, 0x30, 0x1f, 0x06,
+    0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42,
+    0x04, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+    0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06,
+    0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x34,
+    0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+    0x01, 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24,
+    0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+    0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70,
+    0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e,
+    0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e,
+    0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x6d, 0x06, 0x08,
+    0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x0c,
+    0x04, 0x61, 0x30, 0x5f, 0xa1, 0x5d, 0xa0, 0x5b,
+    0x30, 0x59, 0x30, 0x57, 0x30, 0x55, 0x16, 0x09,
+    0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69,
+    0x66, 0x30, 0x21, 0x30, 0x1f, 0x30, 0x07, 0x06,
+    0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14,
+    0x8f, 0xe5, 0xd3, 0x1a, 0x86, 0xac, 0x8d, 0x8e,
+    0x6b, 0xc3, 0xcf, 0x80, 0x6a, 0xd4, 0x48, 0x18,
+    0x2c, 0x7b, 0x19, 0x2e, 0x30, 0x25, 0x16, 0x23,
+    0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c,
+    0x6f, 0x67, 0x6f, 0x2e, 0x76, 0x65, 0x72, 0x69,
+    0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
+    0x2f, 0x76, 0x73, 0x6c, 0x6f, 0x67, 0x6f, 0x2e,
+    0x67, 0x69, 0x66, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+    0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
+    0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x01, 0x5e,
+    0x47, 0x3c, 0x5f, 0x38, 0x4f, 0x4d, 0x64, 0xf1,
+    0x33, 0x13, 0xd3, 0xcf, 0x80, 0xf9, 0x88, 0x93,
+    0xba, 0x44, 0x7b, 0xf0, 0xbd, 0x60, 0x96, 0x39,
+    0xa8, 0xc5, 0x76, 0x18, 0x01, 0xa7, 0x03, 0x53,
+    0x8b, 0x92, 0xda, 0x97, 0xaa, 0x85, 0xc7, 0xb7,
+    0x7d, 0x58, 0x83, 0x68, 0x4a, 0xd9, 0x54, 0x78,
+    0x7f, 0xa0, 0xe9, 0x8f, 0xc5, 0xb4, 0x3a, 0xb7,
+    0x3c, 0xa1, 0x70, 0x40, 0xac, 0xc2, 0xc6, 0x5b,
+    0xbd, 0x70, 0x90, 0xb9, 0xc6, 0x7d, 0x7e, 0x49,
+    0xe4, 0xbd, 0xc1, 0x5d, 0x1a, 0x0f, 0x9e, 0x0a,
+    0x93, 0xfd, 0xc7, 0x7a, 0x8b, 0x9c, 0x61, 0x61,
+    0x34, 0x02, 0xcc, 0x68, 0xdd, 0x2b, 0x29, 0xbc,
+    0x83, 0x8d, 0x7a, 0x8b, 0x22, 0xb9, 0x1e, 0x79,
+    0x3a, 0x5a, 0xc6, 0xda, 0xb3, 0xaf, 0xaf, 0x0b,
+    0x41, 0x16, 0xda, 0xd2, 0x8e, 0xcd, 0xc1, 0xc0,
+    0x43, 0xfc, 0xb3, 0x10, 0xb7, 0x27
+};
+
+static const uint8_t _c0_serial[] = {
+       0x44, 0x50, 0xE6, 0x23, 0xF5, 0x7E, 0x73, 0x4F,
+       0xF8, 0x5C, 0x1D, 0xEE, 0xFB, 0x97, 0x6C, 0x86
+};
+
+/*
+       subject= /O=VeriSign Trust Network/OU=VeriSign, Inc./OU=VeriSign International Server CA - Class 3/OU=www.verisign.com/CPS Incorp.by Ref. LIABILITY LTD.(c)97 VeriSign
+       issuer= /C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
+       serial=254B8A853842CCE358F8C5DDAE226EA4
+*/
+static const uint8_t _c1[] = {
+    0x30, 0x82, 0x03, 0x83, 0x30, 0x82, 0x02, 0xec,
+    0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x25,
+    0x4b, 0x8a, 0x85, 0x38, 0x42, 0xcc, 0xe3, 0x58,
+    0xf8, 0xc5, 0xdd, 0xae, 0x22, 0x6e, 0xa4, 0x30,
+    0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+    0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 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, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e,
+    0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x37,
+    0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
+    0x2e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33,
+    0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20,
+    0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20,
+    0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+    0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
+    0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30,
+    0x1e, 0x17, 0x0d, 0x39, 0x37, 0x30, 0x34, 0x31,
+    0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
+    0x17, 0x0d, 0x31, 0x31, 0x31, 0x30, 0x32, 0x34,
+    0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30,
+    0x81, 0xba, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03,
+    0x55, 0x04, 0x0a, 0x13, 0x16, 0x56, 0x65, 0x72,
+    0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72,
+    0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77,
+    0x6f, 0x72, 0x6b, 0x31, 0x17, 0x30, 0x15, 0x06,
+    0x03, 0x55, 0x04, 0x0b, 0x13, 0x0e, 0x56, 0x65,
+    0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20,
+    0x49, 0x6e, 0x63, 0x2e, 0x31, 0x33, 0x30, 0x31,
+    0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56,
+    0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20,
+    0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74,
+    0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65,
+    0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x20,
+    0x2d, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20,
+    0x33, 0x31, 0x49, 0x30, 0x47, 0x06, 0x03, 0x55,
+    0x04, 0x0b, 0x13, 0x40, 0x77, 0x77, 0x77, 0x2e,
+    0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e,
+    0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x50, 0x53,
+    0x20, 0x49, 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x2e,
+    0x62, 0x79, 0x20, 0x52, 0x65, 0x66, 0x2e, 0x20,
+    0x4c, 0x49, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54,
+    0x59, 0x20, 0x4c, 0x54, 0x44, 0x2e, 0x28, 0x63,
+    0x29, 0x39, 0x37, 0x20, 0x56, 0x65, 0x72, 0x69,
+    0x53, 0x69, 0x67, 0x6e, 0x30, 0x81, 0x9f, 0x30,
+    0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+    0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81,
+    0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81,
+    0x00, 0xd8, 0x82, 0x80, 0xe8, 0xd6, 0x19, 0x02,
+    0x7d, 0x1f, 0x85, 0x18, 0x39, 0x25, 0xa2, 0x65,
+    0x2b, 0xe1, 0xbf, 0xd4, 0x05, 0xd3, 0xbc, 0xe6,
+    0x36, 0x3b, 0xaa, 0xf0, 0x4c, 0x6c, 0x5b, 0xb6,
+    0xe7, 0xaa, 0x3c, 0x73, 0x45, 0x55, 0xb2, 0xf1,
+    0xbd, 0xea, 0x97, 0x42, 0xed, 0x9a, 0x34, 0x0a,
+    0x15, 0xd4, 0xa9, 0x5c, 0xf5, 0x40, 0x25, 0xdd,
+    0xd9, 0x07, 0xc1, 0x32, 0xb2, 0x75, 0x6c, 0xc4,
+    0xca, 0xbb, 0xa3, 0xfe, 0x56, 0x27, 0x71, 0x43,
+    0xaa, 0x63, 0xf5, 0x30, 0x3e, 0x93, 0x28, 0xe5,
+    0xfa, 0xf1, 0x09, 0x3b, 0xf3, 0xb7, 0x4d, 0x4e,
+    0x39, 0xf7, 0x5c, 0x49, 0x5a, 0xb8, 0xc1, 0x1d,
+    0xd3, 0xb2, 0x8a, 0xfe, 0x70, 0x30, 0x95, 0x42,
+    0xcb, 0xfe, 0x2b, 0x51, 0x8b, 0x5a, 0x3c, 0x3a,
+    0xf9, 0x22, 0x4f, 0x90, 0xb2, 0x02, 0xa7, 0x53,
+    0x9c, 0x4f, 0x34, 0xe7, 0xab, 0x04, 0xb2, 0x7b,
+    0x6f, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81,
+    0xe3, 0x30, 0x81, 0xe0, 0x30, 0x0f, 0x06, 0x03,
+    0x55, 0x1d, 0x13, 0x04, 0x08, 0x30, 0x06, 0x01,
+    0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x44, 0x06,
+    0x03, 0x55, 0x1d, 0x20, 0x04, 0x3d, 0x30, 0x3b,
+    0x30, 0x39, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01,
+    0x86, 0xf8, 0x45, 0x01, 0x07, 0x01, 0x01, 0x30,
+    0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01,
+    0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68,
+    0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77,
+    0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73,
+    0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+    0x43, 0x50, 0x53, 0x30, 0x34, 0x06, 0x03, 0x55,
+    0x1d, 0x25, 0x04, 0x2d, 0x30, 0x2b, 0x06, 0x08,
+    0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01,
+    0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+    0x03, 0x02, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
+    0x86, 0xf8, 0x42, 0x04, 0x01, 0x06, 0x0a, 0x60,
+    0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x08,
+    0x01, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f,
+    0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x11,
+    0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8,
+    0x42, 0x01, 0x01, 0x04, 0x04, 0x03, 0x02, 0x01,
+    0x06, 0x30, 0x31, 0x06, 0x03, 0x55, 0x1d, 0x1f,
+    0x04, 0x2a, 0x30, 0x28, 0x30, 0x26, 0xa0, 0x24,
+    0xa0, 0x22, 0x86, 0x20, 0x68, 0x74, 0x74, 0x70,
+    0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x76,
+    0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e,
+    0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63, 0x61, 0x33,
+    0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0d, 0x06, 0x09,
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+    0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x08,
+    0x01, 0xec, 0xe4, 0x68, 0x94, 0x03, 0x42, 0xf1,
+    0x73, 0xf1, 0x23, 0xa2, 0x3a, 0xde, 0xe9, 0xf1,
+    0xda, 0xc6, 0x54, 0xc4, 0x23, 0x3e, 0x86, 0xea,
+    0xcf, 0x6a, 0x3a, 0x33, 0xab, 0xea, 0x9c, 0x04,
+    0x14, 0x07, 0x36, 0x06, 0x0b, 0xf9, 0x88, 0x6f,
+    0xd5, 0x13, 0xee, 0x29, 0x2b, 0xc3, 0xe4, 0x72,
+    0x8d, 0x44, 0xed, 0xd1, 0xac, 0x20, 0x09, 0x2d,
+    0xe1, 0xf6, 0xe1, 0x19, 0x05, 0x38, 0xb0, 0x3d,
+    0x0f, 0x9f, 0x7f, 0xf8, 0x9e, 0x02, 0xdc, 0x86,
+    0x02, 0x86, 0x61, 0x4e, 0x26, 0x5f, 0x5e, 0x9f,
+    0x92, 0x1e, 0x0c, 0x24, 0xa4, 0xf5, 0xd0, 0x70,
+    0x13, 0xcf, 0x26, 0xc3, 0x43, 0x3d, 0x49, 0x1d,
+    0x9e, 0x82, 0x2e, 0x52, 0x5f, 0xbc, 0x3e, 0xc6,
+    0x66, 0x29, 0x01, 0x8e, 0x4e, 0x92, 0x2c, 0xbc,
+    0x46, 0x75, 0x03, 0x82, 0xac, 0x73, 0xe9, 0xd9,
+    0x7e, 0x0b, 0x67, 0xef, 0x54, 0x52, 0x1a
+};
+
+#define CFReleaseSafe(CF) { CFTypeRef _cf = (CF); if (_cf) CFRelease(_cf); }
+
+/* Test basic add delete update copy matching stuff. */
+static void tests(void)
+{
+    SecTrustRef trust;
+       SecCertificateRef cert0, cert1;
+       isnt(cert0 = SecCertificateCreateWithBytes(NULL, _c0, sizeof(_c0)),
+               NULL, "create cert0");
+       isnt(cert1 = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)),
+               NULL, "create cert1");
+       const void *v_certs[] = {
+               cert0,
+               cert1
+       };
+    SecPolicyRef policy = SecPolicyCreateSSL(false, CFSTR("store.apple.com"));
+    CFArrayRef certs = CFArrayCreate(NULL, v_certs,
+               array_size(v_certs), NULL);
+    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust");
+       /* Jan 1st 2006. */
+       CFDateRef date = CFDateCreate(NULL, 157680000.0);
+    ok_status(SecTrustSetVerifyDate(trust, date), "set date");
+
+       SecTrustResultType trustResult;
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultUnspecified,
+               "trust is kSecTrustResultUnspecified");
+    CFDataRef exceptions;
+    ok(exceptions = SecTrustCopyExceptions(trust), "create an exceptions");
+    ok(SecTrustSetExceptions(trust, exceptions), "set exceptions");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultProceed, "trust is kSecTrustResultProceed");
+
+       CFReleaseSafe(trust);
+       CFReleaseSafe(policy);
+    policy = SecPolicyCreateSSL(false, CFSTR("badstore.apple.com"));
+    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust with hostname mismatch");
+    ok_status(SecTrustSetVerifyDate(trust, date), "set date");
+    ok(SecTrustSetExceptions(trust, exceptions), "set old exceptions");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure");
+       CFReleaseSafe(exceptions);
+    ok(exceptions = SecTrustCopyExceptions(trust), "create a new exceptions");
+    ok(SecTrustSetExceptions(trust, exceptions), "set exceptions");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultProceed, "trust is kSecTrustResultProceed");
+
+       CFReleaseSafe(trust);
+    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust");
+    ok_status(SecTrustSetVerifyDate(trust, date), "set date");
+    ok(SecTrustSetExceptions(trust, exceptions), "set exceptions");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultProceed, "trust is kSecTrustResultProceed");
+    CFArrayRef anchors = CFArrayCreate(kCFAllocatorDefault, NULL, 0, &kCFTypeArrayCallBacks);
+    ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set empty anchor list");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure");
+
+       ok_status(SecTrustSetAnchorCertificatesOnly(trust, false), "trust passed in anchors and system anchors");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultProceed, "trust is now kSecTrustResultProceed");
+
+       ok_status(SecTrustSetAnchorCertificatesOnly(trust, true), "only trust passed in anchors (default)");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure again");
+
+       CFReleaseSafe(exceptions);
+    ok(exceptions = SecTrustCopyExceptions(trust), "create a new exceptions");
+    ok(SecTrustSetExceptions(trust, exceptions), "set exceptions");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultProceed, "trust is kSecTrustResultProceed");
+       CFReleaseSafe(date);
+       date = CFDateCreate(NULL, 667680000.0);
+    ok_status(SecTrustSetVerifyDate(trust, date), "set date to far future so certs are expired");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure");
+
+       CFReleaseSafe(anchors);
+       CFReleaseSafe(exceptions);
+       CFReleaseSafe(trust);
+       CFReleaseSafe(policy);
+       CFReleaseSafe(certs);
+       CFReleaseSafe(cert0);
+       CFReleaseSafe(cert1);
+       CFReleaseSafe(date);
+}
+
+int si_27_sectrust_exceptions(int argc, char *const *argv)
+{
+       plan_tests(40);
+
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-28-sectrustsettings.c b/sec/Security/Regressions/secitem/si-28-sectrustsettings.c
new file mode 100644 (file)
index 0000000..02957bb
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2008-2010 Apple Inc. All Rights Reserved.
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecTrustStore.h>
+#include <Security/SecItemPriv.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "Security_regressions.h"
+
+/*
+       subject= /C=US/ST=California/L=Cupertino/O=Apple Computer, Inc./OU=Apple Internet Services/OU=Terms of use at www.verisign.com/rpa (c)00/CN=store.apple.com
+       issuer= /O=VeriSign Trust Network/OU=VeriSign, Inc./OU=VeriSign International Server CA - Class 3/OU=www.verisign.com/CPS Incorp.by Ref. LIABILITY LTD.(c)97 VeriSign
+       serial=4450E623F57E734FF85C1DEEFB976C86
+*/
+static const uint8_t _c0[] = {
+    0x30, 0x82, 0x04, 0x82, 0x30, 0x82, 0x03, 0xeb,
+    0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x44,
+    0x50, 0xe6, 0x23, 0xf5, 0x7e, 0x73, 0x4f, 0xf8,
+    0x5c, 0x1d, 0xee, 0xfb, 0x97, 0x6c, 0x86, 0x30,
+    0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+    0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81,
+    0xba, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55,
+    0x04, 0x0a, 0x13, 0x16, 0x56, 0x65, 0x72, 0x69,
+    0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75,
+    0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f,
+    0x72, 0x6b, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03,
+    0x55, 0x04, 0x0b, 0x13, 0x0e, 0x56, 0x65, 0x72,
+    0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49,
+    0x6e, 0x63, 0x2e, 0x31, 0x33, 0x30, 0x31, 0x06,
+    0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
+    0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x49,
+    0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69,
+    0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65, 0x72,
+    0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x20, 0x2d,
+    0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33,
+    0x31, 0x49, 0x30, 0x47, 0x06, 0x03, 0x55, 0x04,
+    0x0b, 0x13, 0x40, 0x77, 0x77, 0x77, 0x2e, 0x76,
+    0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e,
+    0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x50, 0x53, 0x20,
+    0x49, 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x62,
+    0x79, 0x20, 0x52, 0x65, 0x66, 0x2e, 0x20, 0x4c,
+    0x49, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59,
+    0x20, 0x4c, 0x54, 0x44, 0x2e, 0x28, 0x63, 0x29,
+    0x39, 0x37, 0x20, 0x56, 0x65, 0x72, 0x69, 0x53,
+    0x69, 0x67, 0x6e, 0x30, 0x1e, 0x17, 0x0d, 0x30,
+    0x35, 0x30, 0x33, 0x30, 0x32, 0x30, 0x30, 0x30,
+    0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x37,
+    0x30, 0x34, 0x30, 0x31, 0x32, 0x33, 0x35, 0x39,
+    0x35, 0x39, 0x5a, 0x30, 0x81, 0xc6, 0x31, 0x0b,
+    0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+    0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06,
+    0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x43, 0x61,
+    0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61,
+    0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
+    0x07, 0x14, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72,
+    0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1d, 0x30, 0x1b,
+    0x06, 0x03, 0x55, 0x04, 0x0a, 0x14, 0x14, 0x41,
+    0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x6f, 0x6d,
+    0x70, 0x75, 0x74, 0x65, 0x72, 0x2c, 0x20, 0x49,
+    0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, 0x06,
+    0x03, 0x55, 0x04, 0x0b, 0x14, 0x17, 0x41, 0x70,
+    0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x74, 0x65,
+    0x72, 0x6e, 0x65, 0x74, 0x20, 0x53, 0x65, 0x72,
+    0x76, 0x69, 0x63, 0x65, 0x73, 0x31, 0x33, 0x30,
+    0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x14, 0x2a,
+    0x54, 0x65, 0x72, 0x6d, 0x73, 0x20, 0x6f, 0x66,
+    0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x74, 0x20,
+    0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, 0x69,
+    0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
+    0x2f, 0x72, 0x70, 0x61, 0x20, 0x28, 0x63, 0x29,
+    0x30, 0x30, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03,
+    0x55, 0x04, 0x03, 0x14, 0x0f, 0x73, 0x74, 0x6f,
+    0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65,
+    0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x81, 0x9f, 0x30,
+    0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+    0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81,
+    0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81,
+    0x00, 0xbf, 0x8f, 0x59, 0x14, 0xbb, 0x91, 0xa4,
+    0xe6, 0x3e, 0x75, 0xf8, 0x38, 0x36, 0xfe, 0xcd,
+    0x9e, 0x5d, 0x3f, 0x14, 0x62, 0xfc, 0xe7, 0x48,
+    0x5f, 0x7e, 0x6b, 0x6e, 0x87, 0xd2, 0x31, 0x6e,
+    0x9d, 0x19, 0x92, 0x6f, 0xe3, 0xbc, 0x7e, 0x48,
+    0xb1, 0x2f, 0x9d, 0x70, 0x2c, 0x11, 0xdf, 0x35,
+    0xd1, 0xee, 0xd2, 0xd5, 0x37, 0x92, 0x4e, 0x06,
+    0x66, 0xb3, 0xc9, 0x9c, 0x99, 0xec, 0x09, 0xc6,
+    0xc4, 0xd6, 0xe6, 0x62, 0xb7, 0x97, 0x24, 0xd8,
+    0x38, 0x40, 0xf1, 0xa0, 0x1c, 0x0f, 0xf2, 0x3d,
+    0xaf, 0x4a, 0x93, 0xba, 0x11, 0xad, 0x67, 0xc4,
+    0x4b, 0x1d, 0x74, 0x33, 0x7c, 0xb9, 0x6b, 0x2d,
+    0xc5, 0x9b, 0x6a, 0xd2, 0xf2, 0x28, 0x08, 0x05,
+    0x18, 0x7d, 0xf0, 0xde, 0x28, 0x61, 0xf1, 0x81,
+    0xd5, 0x56, 0x4f, 0x20, 0x6e, 0xf3, 0x34, 0x89,
+    0x67, 0xd3, 0xa7, 0x09, 0xda, 0xc7, 0x89, 0x4d,
+    0xe1, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82,
+    0x01, 0x79, 0x30, 0x82, 0x01, 0x75, 0x30, 0x09,
+    0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30,
+    0x00, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f,
+    0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x46,
+    0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x3f, 0x30,
+    0x3d, 0x30, 0x3b, 0xa0, 0x39, 0xa0, 0x37, 0x86,
+    0x35, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+    0x63, 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72, 0x69,
+    0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
+    0x2f, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x33, 0x49,
+    0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69,
+    0x6f, 0x6e, 0x61, 0x6c, 0x53, 0x65, 0x72, 0x76,
+    0x65, 0x72, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x44,
+    0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3d, 0x30,
+    0x3b, 0x30, 0x39, 0x06, 0x0b, 0x60, 0x86, 0x48,
+    0x01, 0x86, 0xf8, 0x45, 0x01, 0x07, 0x17, 0x03,
+    0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06,
+    0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c,
+    0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f,
+    0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, 0x69,
+    0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
+    0x2f, 0x72, 0x70, 0x61, 0x30, 0x28, 0x06, 0x03,
+    0x55, 0x1d, 0x25, 0x04, 0x21, 0x30, 0x1f, 0x06,
+    0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42,
+    0x04, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+    0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06,
+    0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x34,
+    0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+    0x01, 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24,
+    0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+    0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70,
+    0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e,
+    0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e,
+    0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x6d, 0x06, 0x08,
+    0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x0c,
+    0x04, 0x61, 0x30, 0x5f, 0xa1, 0x5d, 0xa0, 0x5b,
+    0x30, 0x59, 0x30, 0x57, 0x30, 0x55, 0x16, 0x09,
+    0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69,
+    0x66, 0x30, 0x21, 0x30, 0x1f, 0x30, 0x07, 0x06,
+    0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14,
+    0x8f, 0xe5, 0xd3, 0x1a, 0x86, 0xac, 0x8d, 0x8e,
+    0x6b, 0xc3, 0xcf, 0x80, 0x6a, 0xd4, 0x48, 0x18,
+    0x2c, 0x7b, 0x19, 0x2e, 0x30, 0x25, 0x16, 0x23,
+    0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c,
+    0x6f, 0x67, 0x6f, 0x2e, 0x76, 0x65, 0x72, 0x69,
+    0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
+    0x2f, 0x76, 0x73, 0x6c, 0x6f, 0x67, 0x6f, 0x2e,
+    0x67, 0x69, 0x66, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+    0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
+    0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x01, 0x5e,
+    0x47, 0x3c, 0x5f, 0x38, 0x4f, 0x4d, 0x64, 0xf1,
+    0x33, 0x13, 0xd3, 0xcf, 0x80, 0xf9, 0x88, 0x93,
+    0xba, 0x44, 0x7b, 0xf0, 0xbd, 0x60, 0x96, 0x39,
+    0xa8, 0xc5, 0x76, 0x18, 0x01, 0xa7, 0x03, 0x53,
+    0x8b, 0x92, 0xda, 0x97, 0xaa, 0x85, 0xc7, 0xb7,
+    0x7d, 0x58, 0x83, 0x68, 0x4a, 0xd9, 0x54, 0x78,
+    0x7f, 0xa0, 0xe9, 0x8f, 0xc5, 0xb4, 0x3a, 0xb7,
+    0x3c, 0xa1, 0x70, 0x40, 0xac, 0xc2, 0xc6, 0x5b,
+    0xbd, 0x70, 0x90, 0xb9, 0xc6, 0x7d, 0x7e, 0x49,
+    0xe4, 0xbd, 0xc1, 0x5d, 0x1a, 0x0f, 0x9e, 0x0a,
+    0x93, 0xfd, 0xc7, 0x7a, 0x8b, 0x9c, 0x61, 0x61,
+    0x34, 0x02, 0xcc, 0x68, 0xdd, 0x2b, 0x29, 0xbc,
+    0x83, 0x8d, 0x7a, 0x8b, 0x22, 0xb9, 0x1e, 0x79,
+    0x3a, 0x5a, 0xc6, 0xda, 0xb3, 0xaf, 0xaf, 0x0b,
+    0x41, 0x16, 0xda, 0xd2, 0x8e, 0xcd, 0xc1, 0xc0,
+    0x43, 0xfc, 0xb3, 0x10, 0xb7, 0x27
+};
+
+#define CFReleaseSafe(CF) { CFTypeRef _cf = (CF); if (_cf) CFRelease(_cf); }
+
+static void tests(void)
+{
+       SecCertificateRef cert0;
+       isnt(cert0 = SecCertificateCreateWithBytes(NULL, _c0, sizeof(_c0)),
+               NULL, "create cert0");
+    SecTrustStoreRef user_store;
+    isnt(user_store = SecTrustStoreForDomain(kSecTrustStoreDomainUser),
+        NULL, "get user trust settings store handle");
+    ok(!SecTrustStoreContains(user_store, cert0),
+        "cert0 is not yet present");
+    ok_status(SecTrustStoreSetTrustSettings(user_store, cert0, NULL),
+        "make cert0 trusted for anything");
+    ok(SecTrustStoreContains(user_store, cert0),
+        "cert0 is present");
+    ok_status(SecTrustStoreSetTrustSettings(user_store, cert0, NULL),
+        "make cert0 trusted for anything - again, should update now");
+    ok(SecTrustStoreContains(user_store, cert0),
+        "cert0 is still present");
+    ok_status(SecTrustStoreRemoveCertificate(user_store, cert0),
+        "removing cert0");
+    ok(!SecTrustStoreContains(user_store, cert0),
+        "cert0 is no longer present");
+
+    /* Adding again...*/
+    ok_status(SecTrustStoreSetTrustSettings(user_store, cert0, NULL),
+        "make cert0 trusted for anything");
+    ok(SecTrustStoreContains(user_store, cert0),
+       "cert0 is present");
+
+    /* Remove it */
+    ok_status(SecTrustStoreRemoveCertificate(user_store, cert0),
+              "removing cert0");
+    ok(!SecTrustStoreContains(user_store, cert0),
+       "cert0 is no longer present");
+
+       CFReleaseSafe(cert0);
+}
+
+int si_28_sectrustsettings(int argc, char *const *argv)
+{
+       plan_tests(13);
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-29-sectrust-codesigning.c b/sec/Security/Regressions/secitem/si-29-sectrust-codesigning.c
new file mode 100644 (file)
index 0000000..18e634f
--- /dev/null
@@ -0,0 +1,680 @@
+/*
+ * Copyright (c) 2007-2010 Apple Inc. All Rights Reserved.
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecPolicyPriv.h>
+#include <Security/SecTrust.h>
+#include <Security/SecTrustPriv.h>
+#include <Security/SecKey.h>
+#include <Security/SecInternal.h>
+#include <utilities/array_size.h>
+#include <CommonCrypto/CommonDigest.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "Security_regressions.h"
+
+/* subject:/CN=iPhone Developer: Katherine Kojima/OU=Core OS Plus Others/O=Core OS Plus Others/C=usa */
+/* issuer :/C=US/O=Apple Inc./OU=Apple Worldwide Developer Relations/CN=Apple Worldwide Developer Relations Certification Authority */
+static unsigned char codesigning_certificate[1415]={
+0x30,0x82,0x05,0x83,0x30,0x82,0x04,0x6B,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x70,
+0xA9,0x16,0x20,0x02,0xA2,0xD4,0x50,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,
+0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81,0x96,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,
+0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x0C,
+0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x2C,0x30,0x2A,0x06,
+0x03,0x55,0x04,0x0B,0x0C,0x23,0x41,0x70,0x70,0x6C,0x65,0x20,0x57,0x6F,0x72,0x6C,
+0x64,0x77,0x69,0x64,0x65,0x20,0x44,0x65,0x76,0x65,0x6C,0x6F,0x70,0x65,0x72,0x20,
+0x52,0x65,0x6C,0x61,0x74,0x69,0x6F,0x6E,0x73,0x31,0x44,0x30,0x42,0x06,0x03,0x55,
+0x04,0x03,0x0C,0x3B,0x41,0x70,0x70,0x6C,0x65,0x20,0x57,0x6F,0x72,0x6C,0x64,0x77,
+0x69,0x64,0x65,0x20,0x44,0x65,0x76,0x65,0x6C,0x6F,0x70,0x65,0x72,0x20,0x52,0x65,
+0x6C,0x61,0x74,0x69,0x6F,0x6E,0x73,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,
+0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,
+0x1E,0x17,0x0D,0x30,0x38,0x30,0x33,0x32,0x36,0x31,0x37,0x30,0x37,0x34,0x36,0x5A,
+0x17,0x0D,0x30,0x38,0x30,0x39,0x32,0x34,0x31,0x37,0x30,0x37,0x34,0x36,0x5A,0x30,
+0x77,0x31,0x2B,0x30,0x29,0x06,0x03,0x55,0x04,0x03,0x0C,0x22,0x69,0x50,0x68,0x6F,
+0x6E,0x65,0x20,0x44,0x65,0x76,0x65,0x6C,0x6F,0x70,0x65,0x72,0x3A,0x20,0x4B,0x61,
+0x74,0x68,0x65,0x72,0x69,0x6E,0x65,0x20,0x4B,0x6F,0x6A,0x69,0x6D,0x61,0x31,0x1C,
+0x30,0x1A,0x06,0x03,0x55,0x04,0x0B,0x0C,0x13,0x43,0x6F,0x72,0x65,0x20,0x4F,0x53,
+0x20,0x50,0x6C,0x75,0x73,0x20,0x4F,0x74,0x68,0x65,0x72,0x73,0x31,0x1C,0x30,0x1A,
+0x06,0x03,0x55,0x04,0x0A,0x0C,0x13,0x43,0x6F,0x72,0x65,0x20,0x4F,0x53,0x20,0x50,
+0x6C,0x75,0x73,0x20,0x4F,0x74,0x68,0x65,0x72,0x73,0x31,0x0C,0x30,0x0A,0x06,0x03,
+0x55,0x04,0x06,0x13,0x03,0x75,0x73,0x61,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,
+0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xD4,0x2B,0xF2,0x10,0x71,0x0B,0xBB,
+0x3D,0xA0,0x1A,0x32,0x41,0xBC,0xA9,0x55,0xF4,0xFB,0x6C,0x9C,0xB5,0x32,0x52,0x10,
+0x7E,0x41,0xF4,0x2C,0x18,0x3A,0x4F,0x32,0x9D,0xA3,0x64,0x28,0xDD,0x94,0xD0,0xB8,
+0x3F,0xF9,0x7C,0x62,0xE6,0xF5,0xF1,0x16,0x0D,0x7F,0xBA,0xEC,0xBF,0xD9,0x95,0xD4,
+0x7A,0xD7,0x4D,0x32,0x0F,0xCD,0x6D,0xBC,0xF3,0x10,0xDE,0xE8,0x5D,0xA1,0xDA,0x98,
+0x8F,0x6C,0x75,0xF7,0x7B,0xBE,0x33,0x43,0xBD,0x95,0xFA,0x35,0xD6,0x77,0x81,0x68,
+0x02,0x9C,0x41,0x99,0x0B,0x53,0x5F,0x58,0xF3,0x85,0x4C,0xAB,0x06,0xC2,0xC0,0xC4,
+0xD8,0x68,0x64,0xE3,0x14,0x5F,0x62,0x75,0xD5,0x66,0x9B,0xEE,0x4A,0x49,0xBA,0xC7,
+0x7B,0xD1,0xE6,0x96,0x9D,0xE5,0xEF,0x99,0x0E,0x87,0xEC,0xE3,0xA4,0x54,0x3E,0x19,
+0xBB,0x87,0x53,0x9C,0x3C,0x6A,0x94,0x6B,0x22,0x1A,0x01,0xAF,0x21,0xD5,0xDA,0xB0,
+0x92,0xE0,0x70,0x61,0xDD,0xC1,0x37,0x60,0x1F,0xC3,0xB0,0xFC,0xB3,0x00,0x4A,0x56,
+0x9D,0x70,0xC3,0xDE,0x66,0xD0,0xEF,0x39,0x88,0x48,0xBD,0x6D,0xA6,0xB2,0x2C,0x0A,
+0x78,0xCE,0x05,0x62,0x9B,0xE9,0x18,0x4E,0x59,0xC8,0xDC,0xD3,0xDF,0xB6,0x77,0xB5,
+0xA3,0xDA,0x62,0x15,0x9A,0x50,0x1E,0x28,0x55,0x70,0xC2,0xB7,0x97,0x63,0x00,0x1E,
+0x0E,0x3A,0x8B,0xA6,0x13,0xE5,0xE0,0xD6,0xE6,0xFA,0x61,0xDE,0x5F,0x30,0x72,0xAA,
+0xE4,0xBA,0x21,0x74,0x63,0x4A,0xF2,0x18,0x4C,0x99,0x8D,0x75,0x27,0x91,0xF9,0xD4,
+0x08,0xAE,0xB6,0xDA,0x69,0x33,0x06,0x7F,0x17,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,
+0x01,0xF1,0x30,0x82,0x01,0xED,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,
+0x04,0x02,0x30,0x00,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,
+0x03,0x02,0x07,0x80,0x30,0x16,0x06,0x03,0x55,0x1D,0x25,0x01,0x01,0xFF,0x04,0x0C,
+0x30,0x0A,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x03,0x30,0x1D,0x06,0x03,
+0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x6A,0x6D,0x56,0xC6,0xA5,0x0E,0xC2,0x97,0xF7,
+0x17,0x48,0xBE,0xA0,0x07,0xFF,0x77,0xE9,0xEF,0xB2,0xED,0x30,0x1F,0x06,0x03,0x55,
+0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x88,0x27,0x17,0x09,0xA9,0xB6,0x18,0x60,
+0x8B,0xEC,0xEB,0xBA,0xF6,0x47,0x59,0xC5,0x52,0x54,0xA3,0xB7,0x30,0x82,0x01,0x0F,
+0x06,0x03,0x55,0x1D,0x20,0x04,0x82,0x01,0x06,0x30,0x82,0x01,0x02,0x30,0x81,0xFF,
+0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,0x05,0x01,0x30,0x81,0xF1,0x30,0x81,
+0xC3,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x02,0x30,0x81,0xB6,0x0C,0x81,
+0xB3,0x52,0x65,0x6C,0x69,0x61,0x6E,0x63,0x65,0x20,0x6F,0x6E,0x20,0x74,0x68,0x69,
+0x73,0x20,0x63,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x62,0x79,
+0x20,0x61,0x6E,0x79,0x20,0x70,0x61,0x72,0x74,0x79,0x20,0x61,0x73,0x73,0x75,0x6D,
+0x65,0x73,0x20,0x61,0x63,0x63,0x65,0x70,0x74,0x61,0x6E,0x63,0x65,0x20,0x6F,0x66,
+0x20,0x74,0x68,0x65,0x20,0x74,0x68,0x65,0x6E,0x20,0x61,0x70,0x70,0x6C,0x69,0x63,
+0x61,0x62,0x6C,0x65,0x20,0x73,0x74,0x61,0x6E,0x64,0x61,0x72,0x64,0x20,0x74,0x65,
+0x72,0x6D,0x73,0x20,0x61,0x6E,0x64,0x20,0x63,0x6F,0x6E,0x64,0x69,0x74,0x69,0x6F,
+0x6E,0x73,0x20,0x6F,0x66,0x20,0x75,0x73,0x65,0x2C,0x20,0x63,0x65,0x72,0x74,0x69,
+0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x70,0x6F,0x6C,0x69,0x63,0x79,0x20,0x61,0x6E,
+0x64,0x20,0x63,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,
+0x70,0x72,0x61,0x63,0x74,0x69,0x63,0x65,0x20,0x73,0x74,0x61,0x74,0x65,0x6D,0x65,
+0x6E,0x74,0x73,0x2E,0x30,0x29,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,
+0x16,0x1D,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x61,0x70,0x70,
+0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x2F,0x61,0x70,0x70,0x6C,0x65,0x63,0x61,0x2F,0x30,
+0x4D,0x06,0x03,0x55,0x1D,0x1F,0x04,0x46,0x30,0x44,0x30,0x42,0xA0,0x40,0xA0,0x3E,
+0x86,0x3C,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x64,0x65,0x76,0x65,0x6C,0x6F,0x70,
+0x65,0x72,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x2F,0x63,0x65,0x72,
+0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x61,0x75,0x74,0x68,0x6F,0x72,
+0x69,0x74,0x79,0x2F,0x77,0x77,0x64,0x72,0x63,0x61,0x2E,0x63,0x72,0x6C,0x30,0x13,
+0x06,0x0A,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,0x06,0x01,0x02,0x01,0x01,0xFF,0x04,
+0x02,0x05,0x00,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,
+0x05,0x00,0x03,0x82,0x01,0x01,0x00,0xA1,0x1D,0x8C,0xB9,0x21,0x59,0xC8,0xC0,0x08,
+0x25,0x97,0x78,0x0D,0x04,0x14,0x85,0xA8,0xFC,0xC3,0xB1,0x7E,0x72,0x45,0x4C,0x96,
+0x82,0x90,0x73,0x68,0x24,0x65,0x11,0x0F,0xB8,0x0D,0xB8,0xE4,0x46,0xD5,0x61,0x01,
+0x64,0xB8,0x51,0xF8,0xAE,0xE7,0xCF,0xF2,0x7A,0x93,0x78,0xC7,0x9A,0xD3,0xF4,0xF8,
+0x04,0xDB,0xF1,0x4A,0xDB,0x05,0x98,0x2F,0xF3,0x39,0x37,0xB0,0x2B,0x49,0x9A,0x82,
+0x36,0x63,0xF4,0xB3,0x70,0x75,0x43,0xE3,0xF1,0xBD,0xB5,0x68,0x0C,0xB3,0x7E,0xA3,
+0xB3,0x29,0x55,0xD2,0x34,0xD8,0x13,0xB5,0x87,0xD3,0xCE,0xEB,0x26,0xE5,0xCB,0x1F,
+0xF1,0xE1,0x89,0x7A,0xB0,0x39,0xB2,0x2E,0x88,0x76,0xE9,0x68,0x69,0x4E,0x90,0xB4,
+0x7C,0x42,0x7A,0x2C,0xDF,0x33,0xCF,0x2F,0xBD,0x38,0x3A,0xCC,0xB3,0xC7,0x47,0x9C,
+0xC4,0x87,0xCE,0x1A,0x1E,0xF4,0xBB,0xC9,0x97,0x35,0x1C,0x65,0xC2,0xF0,0x2F,0x98,
+0x50,0x96,0xA6,0x6C,0xF5,0x1B,0x45,0xE6,0x48,0xBE,0x17,0xFB,0xF6,0x61,0x3E,0x94,
+0xF3,0x49,0x57,0xB5,0x54,0x5F,0xE1,0x92,0x30,0xF9,0xC6,0xB7,0x21,0xE0,0x30,0x64,
+0x83,0xE7,0x49,0x97,0x8D,0xDC,0xE5,0x9D,0x89,0xA9,0x14,0x2E,0xEF,0x21,0x00,0xBA,
+0x13,0x63,0xF4,0xCD,0x2F,0x61,0x17,0x58,0xAB,0xD3,0xA8,0x06,0x54,0x5F,0x60,0xB3,
+0xBE,0xED,0xE8,0xF8,0xA4,0x29,0x2F,0xE1,0x4A,0x0E,0xB1,0xFE,0xCE,0x73,0x14,0x9A,
+0x3A,0x95,0xFC,0xC8,0xB6,0x53,0xBC,0xBF,0x3A,0xB0,0xAE,0x80,0x76,0xF5,0x57,0x47,
+0xD2,0x1C,0x08,0x19,0x22,0xF2,0x6D,
+};
+
+/* subject:/C=US/O=Apple Inc./OU=Apple Worldwide Developer Relations/CN=Apple Worldwide Developer Relations Certification Authority */
+/* issuer :/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Root CA */
+static unsigned char wwdr_anchor_certificate[1063]={
+0x30,0x82,0x04,0x23,0x30,0x82,0x03,0x0B,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x19,
+0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,
+0x62,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,
+0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x13,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,
+0x6E,0x63,0x2E,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0B,0x13,0x1D,0x41,0x70,
+0x70,0x6C,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,
+0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x31,0x16,0x30,0x14,0x06,
+0x03,0x55,0x04,0x03,0x13,0x0D,0x41,0x70,0x70,0x6C,0x65,0x20,0x52,0x6F,0x6F,0x74,
+0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x30,0x38,0x30,0x32,0x31,0x34,0x31,0x38,0x35,
+0x36,0x33,0x35,0x5A,0x17,0x0D,0x31,0x36,0x30,0x32,0x31,0x34,0x31,0x38,0x35,0x36,
+0x33,0x35,0x5A,0x30,0x81,0x96,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,
+0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0A,0x41,0x70,
+0x70,0x6C,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x2C,0x30,0x2A,0x06,0x03,0x55,0x04,
+0x0B,0x0C,0x23,0x41,0x70,0x70,0x6C,0x65,0x20,0x57,0x6F,0x72,0x6C,0x64,0x77,0x69,
+0x64,0x65,0x20,0x44,0x65,0x76,0x65,0x6C,0x6F,0x70,0x65,0x72,0x20,0x52,0x65,0x6C,
+0x61,0x74,0x69,0x6F,0x6E,0x73,0x31,0x44,0x30,0x42,0x06,0x03,0x55,0x04,0x03,0x0C,
+0x3B,0x41,0x70,0x70,0x6C,0x65,0x20,0x57,0x6F,0x72,0x6C,0x64,0x77,0x69,0x64,0x65,
+0x20,0x44,0x65,0x76,0x65,0x6C,0x6F,0x70,0x65,0x72,0x20,0x52,0x65,0x6C,0x61,0x74,
+0x69,0x6F,0x6E,0x73,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,
+0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x82,0x01,0x22,
+0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,
+0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xCA,0x38,0x54,
+0xA6,0xCB,0x56,0xAA,0xC8,0x24,0x39,0x48,0xE9,0x8C,0xEE,0xEC,0x5F,0xB8,0x7F,0x26,
+0x91,0xBC,0x34,0x53,0x7A,0xCE,0x7C,0x63,0x80,0x61,0x77,0x64,0x5E,0xA5,0x07,0x23,
+0xB6,0x39,0xFE,0x50,0x2D,0x15,0x56,0x58,0x70,0x2D,0x7E,0xC4,0x6E,0xC1,0x4A,0x85,
+0x3E,0x2F,0xF0,0xDE,0x84,0x1A,0xA1,0x57,0xC9,0xAF,0x7B,0x18,0xFF,0x6A,0xFA,0x15,
+0x12,0x49,0x15,0x08,0x19,0xAC,0xAA,0xDB,0x2A,0x32,0xED,0x96,0x63,0x68,0x52,0x15,
+0x3D,0x8C,0x8A,0xEC,0xBF,0x6B,0x18,0x95,0xE0,0x03,0xAC,0x01,0x7D,0x97,0x05,0x67,
+0xCE,0x0E,0x85,0x95,0x37,0x6A,0xED,0x09,0xB6,0xAE,0x67,0xCD,0x51,0x64,0x9F,0xC6,
+0x5C,0xD1,0xBC,0x57,0x6E,0x67,0x35,0x80,0x76,0x36,0xA4,0x87,0x81,0x6E,0x38,0x8F,
+0xD8,0x2B,0x15,0x4E,0x7B,0x25,0xD8,0x5A,0xBF,0x4E,0x83,0xC1,0x8D,0xD2,0x93,0xD5,
+0x1A,0x71,0xB5,0x60,0x9C,0x9D,0x33,0x4E,0x55,0xF9,0x12,0x58,0x0C,0x86,0xB8,0x16,
+0x0D,0xC1,0xE5,0x77,0x45,0x8D,0x50,0x48,0xBA,0x2B,0x2D,0xE4,0x94,0x85,0xE1,0xE8,
+0xC4,0x9D,0xC6,0x68,0xA5,0xB0,0xA3,0xFC,0x67,0x7E,0x70,0xBA,0x02,0x59,0x4B,0x77,
+0x42,0x91,0x39,0xB9,0xF5,0xCD,0xE1,0x4C,0xEF,0xC0,0x3B,0x48,0x8C,0xA6,0xE5,0x21,
+0x5D,0xFD,0x6A,0x6A,0xBB,0xA7,0x16,0x35,0x60,0xD2,0xE6,0xAD,0xF3,0x46,0x29,0xC9,
+0xE8,0xC3,0x8B,0xE9,0x79,0xC0,0x6A,0x61,0x67,0x15,0xB2,0xF0,0xFD,0xE5,0x68,0xBC,
+0x62,0x5F,0x6E,0xCF,0x99,0xDD,0xEF,0x1B,0x63,0xFE,0x92,0x65,0xAB,0x02,0x03,0x01,
+0x00,0x01,0xA3,0x81,0xAE,0x30,0x81,0xAB,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,
+0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x86,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,
+0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,
+0x04,0x16,0x04,0x14,0x88,0x27,0x17,0x09,0xA9,0xB6,0x18,0x60,0x8B,0xEC,0xEB,0xBA,
+0xF6,0x47,0x59,0xC5,0x52,0x54,0xA3,0xB7,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,
+0x18,0x30,0x16,0x80,0x14,0x2B,0xD0,0x69,0x47,0x94,0x76,0x09,0xFE,0xF4,0x6B,0x8D,
+0x2E,0x40,0xA6,0xF7,0x47,0x4D,0x7F,0x08,0x5E,0x30,0x36,0x06,0x03,0x55,0x1D,0x1F,
+0x04,0x2F,0x30,0x2D,0x30,0x2B,0xA0,0x29,0xA0,0x27,0x86,0x25,0x68,0x74,0x74,0x70,
+0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,
+0x2F,0x61,0x70,0x70,0x6C,0x65,0x63,0x61,0x2F,0x72,0x6F,0x6F,0x74,0x2E,0x63,0x72,
+0x6C,0x30,0x10,0x06,0x0A,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,0x06,0x02,0x01,0x04,
+0x02,0x05,0x00,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,
+0x05,0x00,0x03,0x82,0x01,0x01,0x00,0xDA,0x32,0x00,0x96,0xC5,0x54,0x94,0xD3,0x3B,
+0x82,0x37,0x66,0x7D,0x2E,0x68,0xD5,0xC3,0xC6,0xB8,0xCB,0x26,0x8C,0x48,0x90,0xCF,
+0x13,0x24,0x6A,0x46,0x8E,0x63,0xD4,0xF0,0xD0,0x13,0x06,0xDD,0xD8,0xC4,0xC1,0x37,
+0x15,0xF2,0x33,0x13,0x39,0x26,0x2D,0xCE,0x2E,0x55,0x40,0xE3,0x0B,0x03,0xAF,0xFA,
+0x12,0xC2,0xE7,0x0D,0x21,0xB8,0xD5,0x80,0xCF,0xAC,0x28,0x2F,0xCE,0x2D,0xB3,0x4E,
+0xAF,0x86,0x19,0x04,0xC6,0xE9,0x50,0xDD,0x4C,0x29,0x47,0x10,0x23,0xFC,0x6C,0xBB,
+0x1B,0x98,0x6B,0x48,0x89,0xE1,0x5B,0x9D,0xDE,0x46,0xDB,0x35,0x85,0x35,0xEF,0x3E,
+0xD0,0xE2,0x58,0x4B,0x38,0xF4,0xED,0x75,0x5A,0x1F,0x5C,0x70,0x1D,0x56,0x39,0x12,
+0xE5,0xE1,0x0D,0x11,0xE4,0x89,0x25,0x06,0xBD,0xD5,0xB4,0x15,0x8E,0x5E,0xD0,0x59,
+0x97,0x90,0xE9,0x4B,0x81,0xE2,0xDF,0x18,0xAF,0x44,0x74,0x1E,0x19,0xA0,0x3A,0x47,
+0xCC,0x91,0x1D,0x3A,0xEB,0x23,0x5A,0xFE,0xA5,0x2D,0x97,0xF7,0x7B,0xBB,0xD6,0x87,
+0x46,0x42,0x85,0xEB,0x52,0x3D,0x26,0xB2,0x63,0xA8,0xB4,0xB1,0xCA,0x8F,0xF4,0xCC,
+0xE2,0xB3,0xC8,0x47,0xE0,0xBF,0x9A,0x59,0x83,0xFA,0xDA,0x98,0x53,0x2A,0x82,0xF5,
+0x7C,0x65,0x2E,0x95,0xD9,0x33,0x5D,0xF5,0xED,0x65,0xCC,0x31,0x37,0xC5,0x5A,0x04,
+0xE8,0x6B,0xE1,0xE7,0x88,0x03,0x4A,0x75,0x9E,0x9B,0x28,0xCB,0x4A,0x40,0x88,0x65,
+0x43,0x75,0xDD,0xCB,0x3A,0x25,0x23,0xC5,0x9E,0x57,0xF8,0x2E,0xCE,0xD2,0xA9,0x92,
+0x5E,0x73,0x2E,0x2F,0x25,0x75,0x15,
+};
+
+static unsigned char applicable_exceptions[] = {
+  0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xa1, 0x01, 0xd6, 0x02,
+  0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0d, 0x5f,
+  0x10, 0x12, 0x43, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x45, 0x78,
+  0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x10, 0x10, 0x49,
+  0x73, 0x73, 0x75, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x4e,
+  0x61, 0x6d, 0x65, 0x5f, 0x10, 0x11, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63,
+  0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x5b,
+  0x43, 0x68, 0x61, 0x69, 0x6e, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x5a,
+  0x41, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x53, 0x48, 0x41, 0x31, 0x5a, 0x53,
+  0x48, 0x41, 0x31, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x08, 0x08, 0x08,
+  0x08, 0x08, 0x4f, 0x10, 0x14, 0xd7, 0x16, 0x8a, 0x2a, 0x8e, 0xa0, 0x18,
+  0xba, 0x31, 0x36, 0x99, 0x01, 0x90, 0x58, 0xde, 0x18, 0x85, 0xa2, 0xab,
+  0xc2, 0x08, 0x0a, 0x17, 0x2c, 0x3f, 0x53, 0x5f, 0x6a, 0x75, 0x76, 0x77,
+  0x78, 0x79, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91
+};
+
+/* subject:/C=US/O=Apple Inc./CN=TEST Apple iPhone OS Provisioning Profile Signing TEST */
+/* issuer :/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple iPhone Certification Authority */
+static unsigned char _c0[1031]={
+0x30,0x82,0x04,0x03,0x30,0x82,0x02,0xEB,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x0E,
+0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,
+0x79,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,
+0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x13,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,
+0x6E,0x63,0x2E,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0B,0x13,0x1D,0x41,0x70,
+0x70,0x6C,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,
+0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x31,0x2D,0x30,0x2B,0x06,
+0x03,0x55,0x04,0x03,0x13,0x24,0x41,0x70,0x70,0x6C,0x65,0x20,0x69,0x50,0x68,0x6F,
+0x6E,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,
+0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x30,0x38,
+0x30,0x35,0x30,0x32,0x31,0x37,0x35,0x36,0x35,0x31,0x5A,0x17,0x0D,0x30,0x39,0x30,
+0x35,0x30,0x32,0x31,0x37,0x35,0x36,0x35,0x31,0x5A,0x30,0x63,0x31,0x0B,0x30,0x09,
+0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
+0x04,0x0A,0x13,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x3F,
+0x30,0x3D,0x06,0x03,0x55,0x04,0x03,0x13,0x36,0x54,0x45,0x53,0x54,0x20,0x41,0x70,
+0x70,0x6C,0x65,0x20,0x69,0x50,0x68,0x6F,0x6E,0x65,0x20,0x4F,0x53,0x20,0x50,0x72,
+0x6F,0x76,0x69,0x73,0x69,0x6F,0x6E,0x69,0x6E,0x67,0x20,0x50,0x72,0x6F,0x66,0x69,
+0x6C,0x65,0x20,0x53,0x69,0x67,0x6E,0x69,0x6E,0x67,0x20,0x54,0x45,0x53,0x54,0x30,
+0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,
+0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,
+0xAD,0x52,0x0E,0xF9,0x9B,0x54,0x95,0x16,0x61,0x2D,0xBF,0xD3,0x84,0x3B,0xC5,0x6B,
+0x3C,0x0C,0x4C,0xD7,0x27,0x39,0x59,0xAF,0x37,0x47,0x75,0x3B,0xDA,0xF1,0xEB,0xE2,
+0xB8,0xA6,0xCA,0x07,0xF5,0xC2,0x9B,0x69,0x32,0xDF,0x45,0x2E,0xC7,0xAD,0xC6,0xC3,
+0x64,0x6C,0x26,0x5C,0xBA,0x48,0xC8,0x6E,0x09,0x84,0xDC,0xAC,0xC4,0x49,0x02,0x29,
+0x6D,0x40,0x77,0x7D,0x7F,0x16,0x08,0x16,0xF3,0x07,0xC2,0x3A,0xDB,0x80,0x28,0x00,
+0x74,0x0E,0xAD,0xD1,0x48,0x82,0x55,0x69,0x95,0x8B,0x19,0x39,0xA1,0xE5,0xA1,0x38,
+0xE2,0x42,0xC1,0x2D,0x9A,0x71,0xB5,0xE6,0xAB,0xF6,0x21,0xC6,0xBD,0x3D,0x7B,0xBF,
+0x8D,0x0E,0x87,0x85,0x37,0x3C,0x50,0x93,0x12,0xC7,0xA1,0x9B,0xEF,0x1F,0x18,0xD7,
+0xC6,0x1C,0x12,0x7B,0x74,0xED,0xB2,0x6C,0x19,0xFC,0xA9,0x1B,0xDD,0xB0,0x3B,0x5F,
+0xBD,0x10,0x02,0xE5,0x58,0xDB,0x19,0xA8,0x05,0xE4,0xB2,0x2F,0xF4,0x36,0x0C,0xD9,
+0x2F,0xF5,0x2B,0x9A,0x17,0x68,0x0F,0x86,0xCF,0xBC,0x63,0xFF,0x4B,0x35,0x46,0x25,
+0x3A,0x98,0x7C,0x22,0x90,0xA3,0x2D,0xF7,0x78,0x5D,0x0B,0x35,0x98,0x96,0x39,0xA9,
+0xE1,0x2C,0x74,0x96,0x63,0x08,0xB4,0x3A,0x3C,0x76,0x41,0x19,0xF2,0x17,0x3D,0xC9,
+0x1D,0xBA,0xFA,0xDD,0x53,0x8B,0x30,0x73,0xBB,0x3D,0x96,0xCB,0x71,0xB7,0xB9,0x2A,
+0xF9,0x39,0x6D,0xD1,0x33,0xF4,0x1F,0xE9,0xAD,0xB0,0xAA,0x1C,0xCB,0xA7,0x1F,0xBA,
+0x6F,0x13,0x17,0xC9,0xE1,0x8F,0x8A,0xCD,0xDF,0x4D,0xBB,0xFD,0x6C,0xC6,0x06,0xEB,
+0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0xAB,0x30,0x81,0xA8,0x30,0x0B,0x06,0x03,0x55,
+0x1D,0x0F,0x04,0x04,0x03,0x02,0x07,0x80,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,
+0x01,0xFF,0x04,0x02,0x30,0x00,0x30,0x11,0x06,0x0B,0x2A,0x86,0x48,0x86,0xF7,0x63,
+0x64,0x06,0x02,0x02,0x01,0x04,0x02,0x05,0x00,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,
+0x04,0x16,0x04,0x14,0xF7,0x0D,0xCA,0x30,0x6D,0xD5,0xB1,0x7B,0x33,0xEB,0x45,0xC0,
+0xEA,0x08,0x16,0xBB,0x16,0x2F,0x2C,0x30,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,
+0x18,0x30,0x16,0x80,0x14,0xE7,0x34,0x2A,0x2E,0x22,0xDE,0x39,0x60,0x6B,0xB4,0x94,
+0xCE,0x77,0x83,0x61,0x2F,0x31,0xA0,0x7C,0x35,0x30,0x38,0x06,0x03,0x55,0x1D,0x1F,
+0x04,0x31,0x30,0x2F,0x30,0x2D,0xA0,0x2B,0xA0,0x29,0x86,0x27,0x68,0x74,0x74,0x70,
+0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,
+0x2F,0x61,0x70,0x70,0x6C,0x65,0x63,0x61,0x2F,0x69,0x70,0x68,0x6F,0x6E,0x65,0x2E,
+0x63,0x72,0x6C,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,
+0x05,0x00,0x03,0x82,0x01,0x01,0x00,0xA1,0x94,0x7D,0xB9,0xCC,0x61,0xBD,0x93,0xB7,
+0x65,0x0D,0xED,0x4B,0xFB,0x23,0x98,0x6C,0xFD,0xD8,0xEC,0x4F,0x61,0xF7,0x08,0xB4,
+0x52,0xC5,0x4D,0x48,0x1C,0x15,0xE3,0x0D,0xE6,0x50,0x1A,0xE1,0x3D,0x28,0x63,0x5A,
+0xB7,0x28,0x2F,0x51,0xAE,0x25,0x64,0x2B,0x18,0x37,0x55,0x34,0xC3,0xC5,0x31,0x6D,
+0x81,0xED,0x82,0x9A,0xEB,0x22,0x91,0x0A,0x1B,0x19,0xAB,0xDE,0xF6,0xFC,0x2F,0x0D,
+0xE4,0xDE,0x84,0x2D,0x38,0x96,0xA1,0x68,0xED,0x55,0xCB,0x9D,0xCF,0x55,0x07,0xF2,
+0x93,0xE0,0x40,0x53,0x26,0x56,0x7E,0x70,0x4E,0x15,0x3F,0x53,0x3B,0x4D,0x4C,0x63,
+0x8E,0x43,0xC1,0x41,0xB0,0xC3,0x10,0xD2,0xDE,0x52,0xF0,0xB1,0x41,0xB1,0x32,0x3F,
+0x14,0x82,0x30,0x0D,0x9E,0xFA,0x2D,0x61,0x96,0xA5,0x09,0xA5,0xFC,0x6D,0x01,0xCC,
+0xDD,0x2F,0xC4,0x92,0x7E,0x63,0x82,0xAD,0x51,0x4F,0xC7,0x2C,0xF7,0x1F,0x01,0x85,
+0xEE,0x0F,0xF7,0x6E,0x18,0x4E,0xEB,0xA0,0x8F,0x91,0x17,0xE6,0x3C,0x7D,0x24,0xC6,
+0xB3,0x1F,0xAC,0xDC,0xDE,0xC9,0x92,0x28,0x26,0x53,0x1A,0x84,0x7D,0xAB,0x74,0xC1,
+0x8C,0x78,0x61,0x62,0x54,0x03,0xB0,0xB1,0x2A,0xAD,0x44,0x13,0x93,0xEB,0x6A,0x5C,
+0xD5,0xF9,0xEC,0x02,0x56,0x8F,0x88,0x7F,0x67,0x5D,0x24,0xDF,0x70,0x43,0xFC,0x29,
+0x58,0x89,0xED,0x17,0x91,0x2F,0x8C,0xD9,0xA3,0xB5,0x6B,0xAE,0x6D,0x24,0x41,0x82,
+0x7E,0xFE,0x03,0xA5,0xE4,0xD3,0x34,0x1D,0xE7,0x21,0xE7,0xD7,0x70,0x5A,0xAB,0xFE,
+0x1D,0x51,0xC4,0x59,0x48,0x80,0xFC,
+};
+
+/* subject:/C=US/O=Apple Inc./CN=TEST Apple iPhone OS Application Signing TEST */
+/* issuer :/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple iPhone Certification Authority */
+static unsigned char _c1[1046]={
+0x30,0x82,0x04,0x12,0x30,0x82,0x02,0xFA,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x19,
+0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,
+0x79,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,
+0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x13,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,
+0x6E,0x63,0x2E,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0B,0x13,0x1D,0x41,0x70,
+0x70,0x6C,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,
+0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x31,0x2D,0x30,0x2B,0x06,
+0x03,0x55,0x04,0x03,0x13,0x24,0x41,0x70,0x70,0x6C,0x65,0x20,0x69,0x50,0x68,0x6F,
+0x6E,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,
+0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x30,0x38,
+0x30,0x35,0x30,0x32,0x32,0x30,0x31,0x30,0x30,0x38,0x5A,0x17,0x0D,0x30,0x39,0x30,
+0x35,0x30,0x32,0x32,0x30,0x31,0x30,0x30,0x38,0x5A,0x30,0x5A,0x31,0x0B,0x30,0x09,
+0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
+0x04,0x0A,0x13,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x36,
+0x30,0x34,0x06,0x03,0x55,0x04,0x03,0x13,0x2D,0x54,0x45,0x53,0x54,0x20,0x41,0x70,
+0x70,0x6C,0x65,0x20,0x69,0x50,0x68,0x6F,0x6E,0x65,0x20,0x4F,0x53,0x20,0x41,0x70,
+0x70,0x6C,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x53,0x69,0x67,0x6E,0x69,0x6E,
+0x67,0x20,0x54,0x45,0x53,0x54,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,
+0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,
+0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xDA,0xC9,0x59,0x0A,0xD0,0xC3,0x90,0xFE,0x18,
+0xCA,0x8A,0xEE,0x45,0x67,0x51,0x1E,0xF6,0x77,0x98,0xD0,0x29,0xC4,0xF3,0x4D,0xFD,
+0x3E,0xC8,0x17,0x2E,0x42,0xCD,0xAF,0x85,0x13,0xC5,0x74,0x6F,0x8D,0x81,0x64,0x09,
+0x91,0x4E,0xC3,0x64,0xF8,0x21,0x81,0xB7,0x33,0x17,0xBC,0x2D,0xEC,0x19,0xBB,0xF8,
+0x0D,0x4A,0x78,0xCA,0xB2,0xE4,0x7A,0x79,0xF5,0x18,0xFA,0xB4,0x63,0x7F,0xDD,0xE5,
+0x87,0x7B,0x11,0xFD,0xC6,0xFA,0x70,0x5E,0x97,0xDC,0x58,0xD4,0x5D,0x81,0xCA,0x60,
+0x0D,0x8F,0x27,0x51,0x99,0x8D,0x81,0x02,0x5D,0x2E,0xA1,0x42,0xB2,0xD0,0xC9,0xFC,
+0x46,0xD5,0xCB,0xA9,0x68,0xC2,0x93,0xAD,0x1E,0x99,0x7D,0x79,0x22,0x36,0x32,0xC3,
+0x9A,0x92,0xBA,0x04,0x00,0xDB,0xFA,0x8A,0xAC,0xB7,0x74,0x33,0x58,0xAC,0xED,0x9D,
+0xAB,0xC5,0x23,0xAA,0x7E,0xAE,0xEE,0x97,0x67,0x96,0x2F,0x52,0xA2,0x34,0x23,0x83,
+0x97,0x18,0x57,0xA9,0xA6,0x1A,0xF1,0x09,0x3C,0xD6,0x5C,0x39,0xA1,0xB2,0x59,0x7E,
+0xA8,0x65,0x3B,0x45,0x60,0xED,0x6A,0x94,0xD2,0x05,0x79,0xFA,0xAA,0x51,0x4D,0x59,
+0x93,0x72,0xEB,0x9D,0x24,0x23,0xEA,0x32,0xD3,0x5A,0x83,0xB5,0x2D,0xB7,0x14,0xDA,
+0x24,0x60,0x07,0xC0,0x20,0x7E,0x6F,0xD4,0x56,0x85,0x47,0x29,0xE5,0xC0,0x1C,0x91,
+0xC8,0xE4,0x04,0xB4,0x3E,0x4F,0xAB,0x53,0xCC,0x6D,0x71,0x39,0x8F,0x17,0x19,0x16,
+0x81,0x24,0xFA,0xD4,0x4D,0xD0,0x3B,0x4B,0x87,0x0A,0xFF,0x92,0x86,0x89,0x1D,0xFC,
+0x4E,0xA0,0x58,0x0F,0xA5,0x9C,0x19,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0xC3,0x30,
+0x81,0xC0,0x30,0x0B,0x06,0x03,0x55,0x1D,0x0F,0x04,0x04,0x03,0x02,0x07,0x80,0x30,
+0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x02,0x30,0x00,0x30,0x16,0x06,
+0x03,0x55,0x1D,0x25,0x01,0x01,0xFF,0x04,0x0C,0x30,0x0A,0x06,0x08,0x2B,0x06,0x01,
+0x05,0x05,0x07,0x03,0x03,0x30,0x11,0x06,0x0B,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,
+0x06,0x01,0x03,0x01,0x04,0x02,0x05,0x00,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,
+0x16,0x04,0x14,0xB8,0x12,0xA4,0x44,0x18,0x52,0x79,0x30,0x43,0xE0,0x8E,0xFC,0xA6,
+0x7A,0xE7,0x5D,0x0B,0x04,0xB3,0x8C,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,
+0x30,0x16,0x80,0x14,0xE7,0x34,0x2A,0x2E,0x22,0xDE,0x39,0x60,0x6B,0xB4,0x94,0xCE,
+0x77,0x83,0x61,0x2F,0x31,0xA0,0x7C,0x35,0x30,0x38,0x06,0x03,0x55,0x1D,0x1F,0x04,
+0x31,0x30,0x2F,0x30,0x2D,0xA0,0x2B,0xA0,0x29,0x86,0x27,0x68,0x74,0x74,0x70,0x3A,
+0x2F,0x2F,0x77,0x77,0x77,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x2F,
+0x61,0x70,0x70,0x6C,0x65,0x63,0x61,0x2F,0x69,0x70,0x68,0x6F,0x6E,0x65,0x2E,0x63,
+0x72,0x6C,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,
+0x00,0x03,0x82,0x01,0x01,0x00,0x93,0x79,0x8C,0xD9,0x4C,0x24,0x0A,0x60,0x14,0x6B,
+0xAF,0xA1,0xE9,0xEF,0x52,0xDC,0x89,0x91,0x4D,0x13,0xF3,0xDB,0x90,0x5E,0x55,0x36,
+0x1C,0x50,0xBE,0xA6,0x57,0x86,0x32,0x73,0x6E,0x51,0x6C,0x40,0xBA,0xCB,0x1D,0xF8,
+0x44,0xCB,0x14,0x6C,0xBC,0x09,0x2E,0xA5,0xEA,0x26,0x29,0xAB,0xF1,0x8B,0x66,0x53,
+0x99,0x40,0x5D,0xB5,0xBE,0x07,0xD3,0x3C,0x18,0x51,0xEC,0x16,0xC6,0xE4,0x28,0x06,
+0xD3,0x33,0x46,0xB4,0x2A,0x96,0xBE,0x1F,0x60,0xF7,0x7A,0x63,0xC7,0xB7,0x21,0x53,
+0x50,0x9B,0x83,0x54,0xDA,0x7B,0xF8,0x52,0x69,0xFD,0xCF,0x79,0xF5,0x4F,0xA4,0xE4,
+0x34,0x0B,0xC8,0xB9,0x21,0xE7,0x57,0x69,0x9A,0xE3,0xCB,0x47,0xE4,0x74,0x49,0x9A,
+0xD8,0x22,0x7B,0x58,0x0D,0xF7,0x64,0x10,0x30,0x69,0x73,0xC6,0x8E,0x4B,0x36,0x1B,
+0xBB,0xA4,0x48,0x9A,0x5E,0x81,0x97,0x0D,0x5C,0x4A,0x1F,0xE6,0xC8,0x75,0xC2,0xD9,
+0x5D,0x8C,0xE4,0xB3,0xBA,0x5C,0xB9,0xDC,0xCC,0x93,0x7C,0x1F,0x16,0xC7,0x13,0x38,
+0xEA,0x80,0x15,0xF8,0x60,0x80,0xF8,0x44,0xA5,0x8E,0x23,0x10,0x4A,0xD6,0x9A,0x17,
+0x2C,0xEE,0x53,0xF8,0x01,0x45,0xED,0x9A,0x90,0x59,0x07,0xE6,0x14,0xB4,0xA6,0x22,
+0xE4,0xAF,0x50,0xD8,0x6E,0xC0,0x19,0xCF,0x3B,0xC0,0x6C,0x54,0x8C,0x4F,0xFA,0x8F,
+0xB4,0x54,0x75,0xA5,0xED,0xF6,0x22,0x54,0xE5,0x1A,0x4D,0x87,0x60,0x2F,0x3E,0x3A,
+0xB8,0x02,0x07,0xB2,0x0E,0xC4,0x1E,0x70,0x5D,0xB7,0xC5,0x28,0xEC,0x26,0xF7,0x0E,
+0x11,0xBC,0xE8,0x63,0x8C,0x5A,
+};
+
+
+/* subject:/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple iPhone Certification Authority */
+/* issuer :/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Root CA */
+static unsigned char _i1[1015]={
+0x30,0x82,0x03,0xF3,0x30,0x82,0x02,0xDB,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x17,
+0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,
+0x62,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,
+0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x13,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,
+0x6E,0x63,0x2E,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0B,0x13,0x1D,0x41,0x70,
+0x70,0x6C,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,
+0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x31,0x16,0x30,0x14,0x06,
+0x03,0x55,0x04,0x03,0x13,0x0D,0x41,0x70,0x70,0x6C,0x65,0x20,0x52,0x6F,0x6F,0x74,
+0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x30,0x37,0x30,0x34,0x31,0x32,0x31,0x37,0x34,
+0x33,0x32,0x38,0x5A,0x17,0x0D,0x32,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x33,
+0x32,0x38,0x5A,0x30,0x79,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
+0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x13,0x0A,0x41,0x70,0x70,
+0x6C,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0B,
+0x13,0x1D,0x41,0x70,0x70,0x6C,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,
+0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x31,
+0x2D,0x30,0x2B,0x06,0x03,0x55,0x04,0x03,0x13,0x24,0x41,0x70,0x70,0x6C,0x65,0x20,
+0x69,0x50,0x68,0x6F,0x6E,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,
+0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x82,
+0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,
+0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xA3,
+0x1E,0xBE,0xF0,0x47,0xC0,0xB4,0x9E,0x10,0x5B,0x46,0xA4,0xB8,0x21,0xB8,0x4F,0x86,
+0x21,0x70,0x28,0x45,0x60,0x5C,0x1C,0xC3,0xC8,0x0A,0x64,0x63,0x88,0xFB,0xFC,0x69,
+0xEE,0xF8,0x54,0xFC,0xE9,0x5B,0xB7,0x06,0x4E,0x04,0x2F,0xC3,0x6B,0x33,0xAF,0x44,
+0x4C,0xEA,0x4B,0x80,0x09,0xB4,0x87,0xF6,0x5B,0xB4,0xFD,0x64,0xDD,0xB3,0x72,0xE0,
+0x13,0xB3,0xFD,0x17,0xD9,0xBC,0xE7,0xA8,0xED,0xC2,0x8C,0x61,0xC2,0x2A,0xF9,0xEC,
+0xCE,0xA5,0x5E,0xD6,0x69,0xEB,0x64,0x0B,0x8D,0x08,0x8F,0xB8,0xA0,0x50,0x46,0x09,
+0xDC,0x19,0xE4,0xE5,0xB0,0x94,0x6D,0xBB,0xF7,0x99,0x98,0xC4,0xE8,0x9B,0x41,0x4E,
+0xD4,0xF1,0x65,0xE3,0x1B,0x52,0x7A,0xDC,0xE8,0x03,0xD9,0x6E,0x1D,0xDA,0x10,0x55,
+0x86,0xA4,0x29,0x58,0x49,0x0C,0xEA,0x47,0xD7,0x15,0x34,0x33,0xF6,0xC0,0xA0,0x44,
+0x4A,0x70,0xBE,0x2C,0xB5,0x2A,0x30,0x37,0x8C,0x2E,0x15,0xEB,0xD1,0xE4,0x6C,0x97,
+0x38,0x55,0x56,0xB1,0x35,0x2B,0x58,0xEA,0x44,0xA3,0x26,0x85,0xEE,0xC8,0x66,0x4A,
+0xE4,0xCF,0x89,0xF0,0x3D,0x63,0xAD,0x29,0xDE,0xAD,0xBA,0x5A,0xB3,0xDC,0xA5,0xA3,
+0x9A,0xA7,0x09,0x4E,0x80,0x16,0x35,0x65,0xA4,0x85,0x0D,0x63,0x7B,0x3E,0x63,0x8A,
+0xDA,0x7D,0x4A,0x46,0xEC,0xA3,0x39,0x18,0x34,0xB9,0xC6,0x28,0x65,0x18,0xBC,0x13,
+0x60,0x9C,0x7F,0x57,0xAC,0x14,0xC9,0x89,0xED,0xA1,0xB6,0x87,0x68,0x52,0xB6,0x84,
+0x4E,0xB8,0xC8,0x83,0xEC,0xF9,0x9E,0x19,0xAB,0xB3,0xC1,0x0B,0x86,0xC7,0x9F,0x02,
+0x03,0x01,0x00,0x01,0xA3,0x81,0x9C,0x30,0x81,0x99,0x30,0x0E,0x06,0x03,0x55,0x1D,
+0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x86,0x30,0x0F,0x06,0x03,0x55,0x1D,
+0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x1D,0x06,0x03,0x55,
+0x1D,0x0E,0x04,0x16,0x04,0x14,0xE7,0x34,0x2A,0x2E,0x22,0xDE,0x39,0x60,0x6B,0xB4,
+0x94,0xCE,0x77,0x83,0x61,0x2F,0x31,0xA0,0x7C,0x35,0x30,0x1F,0x06,0x03,0x55,0x1D,
+0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x2B,0xD0,0x69,0x47,0x94,0x76,0x09,0xFE,0xF4,
+0x6B,0x8D,0x2E,0x40,0xA6,0xF7,0x47,0x4D,0x7F,0x08,0x5E,0x30,0x36,0x06,0x03,0x55,
+0x1D,0x1F,0x04,0x2F,0x30,0x2D,0x30,0x2B,0xA0,0x29,0xA0,0x27,0x86,0x25,0x68,0x74,
+0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,
+0x6F,0x6D,0x2F,0x61,0x70,0x70,0x6C,0x65,0x63,0x61,0x2F,0x72,0x6F,0x6F,0x74,0x2E,
+0x63,0x72,0x6C,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,
+0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x1D,0xD1,0xD5,0x7B,0xDD,0x74,0x4E,0xD7,0x17,
+0xFC,0x82,0x2D,0x0C,0x99,0x9B,0x5E,0x42,0x72,0xF2,0x69,0xDC,0xD5,0x6B,0x5E,0x0D,
+0x0C,0x6B,0x4B,0x3E,0x7B,0x14,0x25,0xDE,0xB3,0x94,0xE8,0xA0,0xFA,0x0F,0x80,0x89,
+0xF2,0x17,0x3D,0x00,0x02,0xA2,0x91,0x91,0xBE,0x74,0x57,0xDC,0xAF,0x9A,0x9F,0xA1,
+0x0A,0x7D,0x30,0xBE,0x00,0x2A,0xCC,0x21,0x59,0xEB,0xFD,0x49,0xAC,0x6E,0x75,0x19,
+0xE8,0x9A,0x7A,0x03,0xD1,0x86,0xF6,0xE7,0xF6,0xB0,0x0E,0x4B,0x49,0xFA,0xA3,0xB7,
+0x41,0xBA,0xD7,0xD1,0xE3,0x56,0xA1,0x7D,0x83,0xAB,0x97,0xAE,0xF8,0x51,0x4A,0x26,
+0xC1,0x85,0x42,0x13,0x26,0x8D,0x03,0x54,0x66,0x10,0x5E,0x60,0x84,0x05,0x12,0x31,
+0x2B,0x6B,0x54,0xC0,0xA0,0xC8,0x41,0xBC,0x54,0x1E,0xE7,0x54,0xAD,0x13,0x00,0xD2,
+0x4A,0xC7,0xBB,0xC1,0x8A,0xAF,0x81,0x08,0x8E,0xF0,0x46,0x0A,0xBF,0x27,0xA6,0xBE,
+0xDC,0xCF,0x39,0x3A,0x80,0x70,0x19,0x23,0x32,0xA3,0x6B,0x66,0x5D,0x9E,0x4D,0xA8,
+0x47,0x49,0xB2,0x7B,0x45,0xB5,0x51,0x33,0xA7,0x74,0x67,0x09,0x4E,0xB6,0x6C,0x6F,
+0x48,0xF7,0x2C,0xB9,0x33,0x05,0x44,0x6B,0x45,0xBE,0x74,0x4B,0x6F,0xB2,0x86,0x91,
+0xB4,0x3E,0x25,0x28,0x25,0x9E,0xB3,0xC2,0x51,0x86,0xFC,0x4F,0xE5,0xAF,0x3B,0xAA,
+0xBB,0x44,0x2C,0x01,0x49,0xE2,0x74,0xB3,0x34,0xFA,0x44,0xEF,0x14,0xC2,0x11,0xF2,
+0x2D,0x19,0x1A,0x51,0x89,0xD3,0x08,0x4A,0x41,0x6C,0x58,0x56,0xDE,0x9B,0x3A,0xE1,
+0x05,0x57,0xE5,0x62,0xCF,0xD2,0x0F,
+};
+
+
+/* subject:/C=US/O=Apple Inc./CN=Apple iPhone OS Application Signing */
+/* issuer :/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple iPhone Certification Authority */
+static unsigned char app_signing_production[903]={
+0x30,0x82,0x03,0x83,0x30,0x82,0x02,0x6B,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x1E,
+0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,
+0x79,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,
+0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x13,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,
+0x6E,0x63,0x2E,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0B,0x13,0x1D,0x41,0x70,
+0x70,0x6C,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,
+0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x31,0x2D,0x30,0x2B,0x06,
+0x03,0x55,0x04,0x03,0x13,0x24,0x41,0x70,0x70,0x6C,0x65,0x20,0x69,0x50,0x68,0x6F,
+0x6E,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,
+0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x30,0x38,
+0x30,0x35,0x32,0x31,0x30,0x32,0x30,0x34,0x31,0x35,0x5A,0x17,0x0D,0x32,0x30,0x30,
+0x35,0x32,0x31,0x30,0x32,0x30,0x34,0x31,0x35,0x5A,0x30,0x50,0x31,0x0B,0x30,0x09,
+0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
+0x04,0x0A,0x13,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x2C,
+0x30,0x2A,0x06,0x03,0x55,0x04,0x03,0x13,0x23,0x41,0x70,0x70,0x6C,0x65,0x20,0x69,
+0x50,0x68,0x6F,0x6E,0x65,0x20,0x4F,0x53,0x20,0x41,0x70,0x70,0x6C,0x69,0x63,0x61,
+0x74,0x69,0x6F,0x6E,0x20,0x53,0x69,0x67,0x6E,0x69,0x6E,0x67,0x30,0x81,0x9F,0x30,
+0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x81,
+0x8D,0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xB1,0x1D,0x55,0x38,0xAE,0xEF,0xF6,
+0x30,0xA5,0x9B,0x65,0xAE,0x79,0x36,0x01,0x4D,0x48,0x02,0x6E,0x71,0xB8,0x67,0xD2,
+0xF8,0x53,0xF5,0xD8,0xB9,0x27,0xBD,0xAD,0x4B,0xF7,0x44,0xF3,0x5D,0xD6,0x83,0x62,
+0x31,0x71,0x20,0x1D,0xBE,0x02,0x91,0x11,0x42,0xED,0xD9,0xCC,0x29,0xD8,0x31,0xE8,
+0x60,0x07,0x1B,0x07,0x97,0x74,0x7F,0xFA,0x1D,0x89,0xDE,0x85,0x4B,0xD5,0x1F,0xA4,
+0xFE,0x28,0x2D,0xD3,0x29,0x6E,0xD4,0x3F,0xEB,0x10,0x99,0x33,0x11,0x8C,0xD4,0xD4,
+0x32,0x15,0xEE,0xDF,0xB3,0x58,0x2C,0x29,0x6C,0x79,0x48,0x41,0xAE,0x0C,0xDF,0xE6,
+0x8A,0x2C,0x2B,0xA5,0xE9,0x1E,0xD8,0xB6,0x71,0xA2,0xAB,0x11,0x28,0x48,0x72,0xC5,
+0xE3,0x35,0xA5,0x0C,0xDF,0xE7,0xAC,0x44,0x87,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,
+0xC2,0x30,0x81,0xBF,0x30,0x0B,0x06,0x03,0x55,0x1D,0x0F,0x04,0x04,0x03,0x02,0x07,
+0x80,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x02,0x30,0x00,0x30,
+0x16,0x06,0x03,0x55,0x1D,0x25,0x01,0x01,0xFF,0x04,0x0C,0x30,0x0A,0x06,0x08,0x2B,
+0x06,0x01,0x05,0x05,0x07,0x03,0x03,0x30,0x10,0x06,0x0A,0x2A,0x86,0x48,0x86,0xF7,
+0x63,0x64,0x06,0x01,0x03,0x04,0x02,0x05,0x00,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,
+0x04,0x16,0x04,0x14,0x29,0x74,0x91,0xAC,0x21,0xD9,0xCD,0xA4,0xBD,0x78,0xF0,0x8A,
+0x46,0xF9,0x0A,0xB4,0x6E,0x06,0xAC,0x09,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,
+0x18,0x30,0x16,0x80,0x14,0xE7,0x34,0x2A,0x2E,0x22,0xDE,0x39,0x60,0x6B,0xB4,0x94,
+0xCE,0x77,0x83,0x61,0x2F,0x31,0xA0,0x7C,0x35,0x30,0x38,0x06,0x03,0x55,0x1D,0x1F,
+0x04,0x31,0x30,0x2F,0x30,0x2D,0xA0,0x2B,0xA0,0x29,0x86,0x27,0x68,0x74,0x74,0x70,
+0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,
+0x2F,0x61,0x70,0x70,0x6C,0x65,0x63,0x61,0x2F,0x69,0x70,0x68,0x6F,0x6E,0x65,0x2E,
+0x63,0x72,0x6C,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,
+0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x8C,0xEC,0xB5,0x3E,0x50,0x80,0xCC,0x0D,0xF5,
+0x1D,0x2A,0x24,0x38,0x1D,0x60,0xED,0x32,0x8E,0xB2,0x78,0xBB,0x73,0x97,0xF5,0x90,
+0x61,0x4C,0x35,0xF2,0x95,0xDA,0xB7,0x97,0xD3,0x75,0x4C,0x05,0xBE,0xEE,0xE3,0xD1,
+0x66,0xF2,0x36,0xE8,0xF1,0xAD,0x60,0xDF,0x92,0x48,0x6C,0xD1,0xC3,0x95,0x57,0x22,
+0x1F,0xDC,0x74,0x3B,0x36,0xD6,0xC9,0x49,0x43,0xD0,0x74,0x9B,0x74,0xF3,0xFD,0xC8,
+0x8E,0x07,0x79,0x7B,0x5C,0xE0,0x4B,0x74,0xB2,0xBE,0x05,0xFE,0x43,0x68,0xA2,0x30,
+0x04,0xCC,0x5B,0x4B,0x78,0xB3,0x08,0x26,0x3B,0x28,0x47,0xCE,0xF6,0x59,0xAB,0xCC,
+0x10,0xE1,0xBB,0x55,0x3C,0x67,0x55,0x73,0x98,0xF2,0x6E,0xFE,0x51,0x80,0xE7,0x71,
+0x54,0xAF,0x88,0xE8,0xDB,0xE9,0x73,0xA9,0x66,0x17,0x79,0x70,0x1B,0x1C,0xAB,0x24,
+0x74,0x08,0x20,0x46,0xC5,0x99,0x30,0x3E,0x13,0x9A,0x60,0x9F,0x08,0x5B,0xCC,0x01,
+0x26,0xFA,0x93,0x6B,0x72,0xC7,0xB6,0xEC,0x7E,0x3B,0x77,0xE3,0xEB,0x85,0x53,0x82,
+0x4B,0xF7,0x11,0xF7,0x5F,0x7F,0x1D,0xDA,0xA7,0xFE,0x24,0xF5,0x41,0x7D,0x10,0xF1,
+0xBF,0xA6,0x90,0x86,0xC8,0x59,0x98,0xAF,0x41,0xFA,0x91,0x24,0x7C,0x2C,0x38,0x40,
+0x97,0xA2,0xE8,0x4F,0x7A,0xCD,0x1A,0xAD,0x6F,0xC0,0x12,0x1D,0xA7,0x59,0xE5,0xF5,
+0x27,0xF2,0x00,0x5C,0xF0,0xB6,0x8F,0x0E,0xFB,0xCE,0x69,0xAA,0x1F,0x21,0x6A,0xD8,
+0xC7,0x79,0x1B,0x4F,0x1A,0xB2,0xC6,0xC5,0x9C,0xEF,0x11,0x3E,0x7B,0xB1,0xB7,0x7E,
+0xE8,0x8C,0xE0,0xD1,0xFE,0x6D,0x32,
+};
+
+/* subject:/C=US/O=Apple Inc./CN=Apple iPhone OS Provisioning Profile Signing */
+/* issuer :/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple iPhone Certification Authority */
+static unsigned char prof_signing_production[1021]={
+0x30,0x82,0x03,0xF9,0x30,0x82,0x02,0xE1,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x1F,
+0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,
+0x79,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,
+0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x13,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,
+0x6E,0x63,0x2E,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0B,0x13,0x1D,0x41,0x70,
+0x70,0x6C,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,
+0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x31,0x2D,0x30,0x2B,0x06,
+0x03,0x55,0x04,0x03,0x13,0x24,0x41,0x70,0x70,0x6C,0x65,0x20,0x69,0x50,0x68,0x6F,
+0x6E,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,
+0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x30,0x38,
+0x30,0x35,0x32,0x31,0x30,0x32,0x30,0x34,0x31,0x35,0x5A,0x17,0x0D,0x32,0x30,0x30,
+0x35,0x32,0x31,0x30,0x32,0x30,0x34,0x31,0x35,0x5A,0x30,0x59,0x31,0x0B,0x30,0x09,
+0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
+0x04,0x0A,0x13,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x35,
+0x30,0x33,0x06,0x03,0x55,0x04,0x03,0x13,0x2C,0x41,0x70,0x70,0x6C,0x65,0x20,0x69,
+0x50,0x68,0x6F,0x6E,0x65,0x20,0x4F,0x53,0x20,0x50,0x72,0x6F,0x76,0x69,0x73,0x69,
+0x6F,0x6E,0x69,0x6E,0x67,0x20,0x50,0x72,0x6F,0x66,0x69,0x6C,0x65,0x20,0x53,0x69,
+0x67,0x6E,0x69,0x6E,0x67,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,
+0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,
+0x0A,0x02,0x82,0x01,0x01,0x00,0xC5,0x22,0x96,0xB6,0xD1,0xFC,0xBD,0x7C,0x84,0xC2,
+0xFD,0x6B,0x39,0xD4,0x60,0xCC,0xCE,0x4E,0x3A,0xDA,0x41,0x42,0x9E,0x8D,0x94,0xA9,
+0x18,0x67,0x86,0x8A,0x16,0xF1,0x46,0xB1,0x1C,0x69,0x25,0xC7,0xBF,0xF3,0xB3,0x88,
+0xDD,0xC8,0xA5,0xA9,0xC9,0xA5,0x8B,0x42,0x39,0x58,0x39,0xB4,0x8A,0xDB,0x40,0xFA,
+0x74,0xA4,0xAC,0x75,0x57,0x21,0x8D,0xDB,0xD9,0xAA,0xA2,0x0A,0xBE,0xE4,0x9A,0x2A,
+0x83,0x00,0xDA,0x1F,0x37,0x11,0xC0,0xCA,0xCA,0x10,0x76,0xFB,0xE6,0x50,0xC1,0x15,
+0x1B,0x0B,0x67,0x9C,0x8F,0xA1,0xF3,0x5C,0xC8,0x9D,0x78,0xA6,0xAD,0x05,0x80,0xAE,
+0xD7,0x0A,0xB4,0x84,0x9A,0xD8,0x8E,0xD4,0xB4,0x6E,0xF4,0x49,0x99,0x2F,0x1D,0x8E,
+0x7C,0x10,0xE3,0x11,0xC2,0x92,0x74,0x28,0xB2,0x7C,0x2B,0x98,0x15,0xC7,0x0D,0x55,
+0x00,0xAA,0x67,0xA1,0xEE,0x4C,0x54,0xA6,0x9E,0x13,0xE4,0x80,0x2F,0xE1,0xC3,0x36,
+0x47,0x12,0xA1,0xFF,0x56,0xA4,0x9D,0x94,0xEF,0xA5,0x50,0xE2,0x64,0x1B,0x00,0x08,
+0xA4,0xE2,0xB2,0xBD,0x9C,0x76,0xF3,0xAE,0xEA,0x84,0x73,0xD0,0x8F,0xBA,0xFF,0x33,
+0xD7,0x90,0xE6,0x1A,0xB5,0x1F,0xBE,0x83,0x00,0xEA,0x7F,0xF6,0x24,0xA7,0x40,0xE1,
+0x86,0xE2,0x13,0x97,0x27,0x0B,0x5D,0x7D,0xC5,0x0B,0x8F,0x6F,0xA6,0xC4,0x5D,0x63,
+0x30,0x21,0x8D,0x95,0x92,0xEC,0x1A,0xD1,0x55,0x94,0x7F,0x63,0x8F,0x66,0x3F,0x84,
+0x67,0x0C,0x1D,0x70,0x17,0xBC,0x99,0xA8,0x12,0x1D,0x9B,0x07,0x1E,0x0F,0x76,0x3A,
+0x0C,0x40,0x6F,0xAF,0x28,0x3B,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0xAB,0x30,0x81,
+0xA8,0x30,0x0B,0x06,0x03,0x55,0x1D,0x0F,0x04,0x04,0x03,0x02,0x07,0x80,0x30,0x0C,
+0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x02,0x30,0x00,0x30,0x11,0x06,0x0B,
+0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,0x06,0x02,0x02,0x01,0x04,0x02,0x05,0x00,0x30,
+0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xD6,0xE3,0x26,0x4A,0x0D,0x68,
+0xB3,0x0E,0x10,0xBD,0xF8,0xDF,0x25,0x21,0xE3,0x7F,0xC2,0x55,0x7F,0x6C,0x30,0x1F,
+0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xE7,0x34,0x2A,0x2E,0x22,
+0xDE,0x39,0x60,0x6B,0xB4,0x94,0xCE,0x77,0x83,0x61,0x2F,0x31,0xA0,0x7C,0x35,0x30,
+0x38,0x06,0x03,0x55,0x1D,0x1F,0x04,0x31,0x30,0x2F,0x30,0x2D,0xA0,0x2B,0xA0,0x29,
+0x86,0x27,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x61,0x70,0x70,
+0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x2F,0x61,0x70,0x70,0x6C,0x65,0x63,0x61,0x2F,0x69,
+0x70,0x68,0x6F,0x6E,0x65,0x2E,0x63,0x72,0x6C,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,
+0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x23,0xDF,0xB9,
+0xC3,0x8D,0xFB,0x3E,0x64,0xC7,0x1C,0x5D,0x42,0xD0,0x18,0x97,0x80,0xD1,0x34,0xCD,
+0x13,0xC8,0xC0,0x6D,0xF5,0x86,0xC3,0x1C,0x5E,0xE7,0xC4,0x55,0x54,0x0C,0x58,0xB7,
+0x0F,0x5D,0x53,0x41,0xF9,0xDC,0xB5,0x77,0x97,0xB4,0x77,0x93,0x84,0x39,0x5F,0xDF,
+0x7B,0x62,0x29,0x75,0xBD,0xEC,0xF8,0xB2,0x7B,0x90,0xF7,0xEA,0x1A,0x48,0xBF,0x6C,
+0x05,0x2A,0x31,0xE0,0xC7,0x5B,0x24,0x40,0xA3,0x98,0xFD,0x16,0x9A,0x93,0x70,0x6A,
+0xDC,0xED,0x47,0xB6,0x65,0x3B,0xFC,0x89,0x8B,0x66,0x45,0x46,0x8C,0xDE,0x4B,0xB6,
+0x70,0x6D,0xBA,0xA7,0xB1,0x14,0x4F,0xA3,0x6C,0xDB,0x4F,0x4F,0x42,0x98,0x7C,0xF5,
+0x05,0x80,0xCD,0xB6,0x11,0xB0,0xF0,0xEC,0xD4,0x59,0x6A,0xBF,0x1B,0x4D,0xFA,0xA5,
+0xE4,0xBD,0xDE,0x2F,0xB2,0xB9,0x8F,0x0B,0x31,0x44,0xF3,0x92,0x1C,0x02,0x48,0x74,
+0x9F,0xFF,0xAB,0x25,0x8D,0x4F,0xFB,0x74,0xEC,0x2B,0x3B,0x2C,0x0A,0xDE,0x65,0x29,
+0x92,0x1D,0x17,0xEA,0x94,0x4A,0x6F,0x78,0x41,0x41,0x97,0x31,0xA9,0x25,0x9A,0xF1,
+0x69,0x1B,0xD4,0xE1,0x2D,0xF4,0x1A,0xB6,0x89,0xC0,0xBF,0xD6,0x95,0x0E,0xB7,0x85,
+0xB7,0xC6,0x42,0xF0,0x29,0xE9,0xFA,0xF4,0xE4,0x71,0xB7,0x59,0xDB,0x61,0x31,0x33,
+0x52,0x74,0x51,0x37,0x86,0x91,0x1F,0x49,0x70,0xBE,0xF3,0x02,0x26,0x0B,0xBC,0xD5,
+0x12,0x58,0xB0,0xEF,0x5A,0x85,0xEC,0x56,0xCB,0xB4,0xA1,0xAE,0xF5,0x88,0x6C,0x89,
+0x16,0x27,0x13,0x25,0xDF,0xE7,0xE2,0x15,0xE4,0x7A,0x21,0x66,0x9A,
+};
+
+
+static void tests(void)
+{
+    SecTrustRef trust;
+    SecCertificateRef leaf, root;
+    SecPolicyRef policy;
+
+    isnt(leaf = SecCertificateCreateWithBytes(kCFAllocatorDefault,
+        codesigning_certificate, sizeof(codesigning_certificate)), NULL, "create leaf");
+    isnt(root = SecCertificateCreateWithBytes(kCFAllocatorDefault,
+        wwdr_anchor_certificate, sizeof(wwdr_anchor_certificate)), NULL, "create root");
+
+    CFArrayRef certs = CFArrayCreate(kCFAllocatorDefault, (const void **)&leaf, 1, NULL);
+    CFArrayRef anchors = CFArrayCreate(kCFAllocatorDefault, (const void **)&root, 1, NULL);
+    isnt(policy = SecPolicyCreateiPhoneApplicationSigning(), NULL, "create policy instance");
+
+    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust for leaf");
+    ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set WWDR anchor for evaluation");
+    CFDataRef exceptions = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
+            applicable_exceptions, sizeof(applicable_exceptions), kCFAllocatorNull);
+    ok(SecTrustSetExceptions(trust, exceptions), "set applicable exceptions");
+    CFReleaseNull(exceptions);
+
+    SecTrustResultType trustResult;
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultProceed, "trust is kSecTrustResultProceed");
+
+    CFReleaseNull(policy);
+    CFReleaseNull(trust);
+    isnt(policy = SecPolicyCreateiPhoneProfileApplicationSigning(), NULL,
+        "create iPhoneProfileApplicationSigning policy instance");
+    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust for leaf");
+    CFDateRef verifyDate = CFDateCreate(kCFAllocatorDefault, 228244066);
+    ok_status(SecTrustSetVerifyDate(trust, verifyDate), "set verify date");
+    CFReleaseNull(verifyDate);
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    TODO: {
+        todo("We now require a complete certificate chain up to an anchor for every policy");
+        is_status(trustResult, kSecTrustResultUnspecified, "trust is kSecTrustResultUnspecified");
+    }
+    CFReleaseNull(trust);
+    CFReleaseNull(leaf);
+    CFReleaseNull(certs);
+    CFReleaseNull(policy);
+    CFReleaseNull(root);
+    CFReleaseNull(anchors);
+
+/*
+    CFDataRef trust_exceptions = SecTrustCopyExceptions(trust);
+    int fd = open("/var/tmp/si-29-except", O_CREAT|O_RDWR, 0644);
+    write(fd, CFDataGetBytePtr(trust_exceptions), CFDataGetLength(trust_exceptions));
+    close(fd);
+    CFPropertyListRef exception_plist = CFPropertyListCreateWithData(kCFAllocatorDefault, trust_exceptions, kCFPropertyListImmutable, NULL, NULL);
+    CFShow(exception_plist);
+*/
+
+       SecCertificateRef cert0, cert1, ntmd0,
+        app_signing_production_cert, prof_production_cert;
+       isnt(cert0 = SecCertificateCreateWithBytes(NULL, _c0, sizeof(_c0)),
+               NULL, "create cert0");
+       isnt(cert1 = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)),
+               NULL, "create cert1");
+       isnt(ntmd0 = SecCertificateCreateWithBytes(NULL, _i1, sizeof(_i1)),
+               NULL, "create cert1");
+       isnt(app_signing_production_cert = SecCertificateCreateWithBytes(NULL, app_signing_production, sizeof(app_signing_production)),
+               NULL, "create app_signing_production");
+       isnt(prof_production_cert = SecCertificateCreateWithBytes(NULL, prof_signing_production, sizeof(prof_signing_production)),
+               NULL, "create prof_signing_production");
+       const void *v_certs[] = {
+               cert0,
+               ntmd0
+       };
+    policy = SecPolicyCreateiPhoneProvisioningProfileSigning();
+    certs = CFArrayCreate(NULL, v_certs, array_size(v_certs), NULL);
+    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultUnspecified,
+               "trust is kSecTrustResultUnspecified");
+
+       CFReleaseNull(certs);
+       CFReleaseNull(trust);
+
+     v_certs[0] = prof_production_cert;
+    certs = CFArrayCreate(NULL, v_certs, array_size(v_certs), NULL);
+    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultUnspecified,
+               "trust is kSecTrustResultUnspecified");
+
+       CFReleaseNull(certs);
+       CFReleaseNull(trust);
+       CFReleaseNull(policy);
+
+    policy = SecPolicyCreateiPhoneApplicationSigning();
+    v_certs[0] = cert1;
+    certs = CFArrayCreate(NULL, v_certs, array_size(v_certs), NULL);
+    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultUnspecified,
+               "trust is kSecTrustResultUnspecified");
+
+       CFReleaseNull(certs);
+       CFReleaseNull(trust);
+
+    v_certs[0] = app_signing_production_cert;
+    certs = CFArrayCreate(NULL, v_certs, array_size(v_certs), NULL);
+    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+    is_status(trustResult, kSecTrustResultUnspecified,
+               "trust is kSecTrustResultUnspecified");
+
+       CFReleaseNull(certs);
+       CFReleaseNull(trust);
+       CFReleaseNull(policy);
+
+       CFReleaseNull(cert0);
+       CFReleaseNull(cert1);
+       CFReleaseNull(ntmd0);
+    CFReleaseNull(app_signing_production_cert);
+    CFReleaseNull(prof_production_cert);
+
+}
+
+int si_29_sectrust_codesigning(int argc, char *const *argv)
+{
+    plan_tests(30);
+
+
+    tests();
+
+    return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-30-keychain-upgrade.c b/sec/Security/Regressions/secitem/si-30-keychain-upgrade.c
new file mode 100644 (file)
index 0000000..d7e0890
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ *  si-30-keychain-upgrade.c
+ *  Security
+ *
+ *  Created by Michael Brouwer on 4/29/08.
+ *  Copyright (c) 2008,2010 Apple Inc.. All Rights Reserved.
+ *
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecBase.h>
+#include <Security/SecItem.h>
+#include <Security/SecItemPriv.h>
+#include <Security/SecInternal.h>
+#include <utilities/SecCFWrappers.h>
+
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sqlite3.h>
+
+#include "Security_regressions.h"
+#include "SecItemServer.h"
+
+/* TODO: This test needs to be updated. It was originally created to test upgrades from DB prior to the introduction of versionning, circa 2008.
+   We don't support upgrading from that old of keychain, but this test should be upgraded to test upgrades from v5 to v6 keychain, or more current
+*/
+
+const char *create_db_sql =
+"BEGIN TRANSACTION;"
+"CREATE TABLE genp(cdat REAL,mdat REAL,desc BLOB,icmt BLOB,crtr INTEGER,type INTEGER,scrp INTEGER,labl BLOB,alis BLOB,invi INTEGER,nega INTEGER,cusi INTEGER,prot BLOB,acct BLOB NOT NULL DEFAULT '',svce BLOB NOT NULL DEFAULT '',gena BLOB,data BLOB,PRIMARY KEY(acct,svce));"
+"INSERT INTO \"genp\" VALUES(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'4087574952','EnhancedVoicemail',NULL,X'34F32095A0ED6F32637629114439CE38E6FF39ADB591E761D20ED23F9FACF639258DA4F12454FD4D0189C0D39AAA9227');"
+"INSERT INTO \"genp\" VALUES(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'TlalocNet','AirPort',NULL,X'52E24441994D93D18F344DDF6A7F1F6EC43A63BCEB5F89B02FEBEEAAE108BB4933EAE73A0FB615F693C70BCFBCF034BE74BDF0280ECBEB357EEFA3B7EF03060B');"
+"INSERT INTO \"genp\" VALUES(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'weasels','AirPort',NULL,X'3FAD49851913382FBC92C9EB90D90D82A74B1DABB5F726648898B2FA2FBA405AA0B9D95D9837BBFF0F9B7C29954973249AA066F9F8AA68D79552970C687A7DA6');"
+"CREATE TABLE inet(cdat REAL,mdat REAL,desc BLOB,icmt BLOB,crtr INTEGER,type INTEGER,scrp INTEGER,labl BLOB,alis BLOB,invi INTEGER,nega INTEGER,cusi INTEGER,prot BLOB,acct BLOB NOT NULL DEFAULT '',sdmn BLOB NOT NULL DEFAULT '',srvr BLOB NOT NULL DEFAULT '',ptcl INTEGER NOT NULL DEFAULT 0,atyp BLOB NOT NULL DEFAULT '',port INTEGER NOT NULL DEFAULT 0,path BLOB NOT NULL DEFAULT '',data BLOB,PRIMARY KEY(acct,sdmn,srvr,ptcl,atyp,port,path));"
+"INSERT INTO \"inet\" VALUES(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'mb.7766@gmail.com','','imap.gmail.com','imap','',143,'',X'0029D7AFBF0000E0E386C8654070569B2DF1D7DC2D641AA29223297EC9E8AD86ED91CA6DEE3D2DA0FABD8F05DE5A7AD4CC46B134A211472B6DE50595EACAC149');"
+"INSERT INTO \"inet\" VALUES(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'brouwer','','phonehome.apple.com','imap','',143,'',X'BB373BAE840427C5E1247540ADA559AB14DF3788906B786498A8E1CFF4B4C596634E4A4C7F9C55EA1B646163AFCDADA8');"
+"INSERT INTO \"inet\" VALUES(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'mb.7766@gmail.com','','smtp.gmail.com','smtp','',25,'',X'042C08A4AECD3957822F531A602734F07B89DABA3BA6629ECEFE10E264C12635F83EFBB1707C6B39FB20CCE0200D8997B690FBB0B92911BFE9B2D1E05B1CD5F5');"
+"INSERT INTO \"inet\" VALUES(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'brouwer','','phonehome.apple.com','smtp','',25,'',X'25B0775265ADC808B8AFB2F2602C44B13F5ECC1F04B1D5E6EAE1B803446F3A817CCF8401416FE673CE366E25FACF5C55');"
+"CREATE TABLE cert(ctyp INTEGER NOT NULL DEFAULT 0,cenc INTEGER,labl BLOB,alis BLOB,subj BLOB,issr BLOB NOT NULL DEFAULT '',slnr BLOB NOT NULL DEFAULT '',skid BLOB,pkhh BLOB,data BLOB,PRIMARY KEY(ctyp,issr,slnr));"
+"CREATE TABLE keys(kcls INTEGER NOT NULL DEFAULT 0,labl BLOB,alis BLOB,perm INTEGER,priv INTEGER,modi INTEGER,klbl BLOB NOT NULL DEFAULT '',atag BLOB NOT NULL DEFAULT '',crtr INTEGER NOT NULL DEFAULT 0,type INTEGER NOT NULL DEFAULT 0,bsiz INTEGER NOT NULL DEFAULT 0,esiz INTEGER NOT NULL DEFAULT 0,sdat REAL NOT NULL DEFAULT 0,edat REAL NOT NULL DEFAULT 0,sens INTEGER,asen INTEGER,extr INTEGER,next INTEGER,encr INTEGER,decr INTEGER,drve INTEGER,sign INTEGER,vrfy INTEGER,snrc INTEGER,vyrc INTEGER,wrap INTEGER,unwp INTEGER,data BLOB,PRIMARY KEY(kcls,klbl,atag,crtr,type,bsiz,esiz,sdat,edat));"
+"CREATE INDEX ialis ON cert(alis);"
+"CREATE INDEX isubj ON cert(subj);"
+"CREATE INDEX iskid ON cert(skid);"
+"CREATE INDEX ipkhh ON cert(pkhh);"
+"CREATE INDEX ikcls ON keys(kcls);"
+"CREATE INDEX iklbl ON keys(klbl);"
+"CREATE INDEX iencr ON keys(encr);"
+"CREATE INDEX idecr ON keys(decr);"
+"CREATE INDEX idrve ON keys(drve);"
+"CREATE INDEX isign ON keys(sign);"
+"CREATE INDEX ivrfy ON keys(vrfy);"
+"CREATE INDEX iwrap ON keys(wrap);"
+"CREATE INDEX iunwp ON keys(unwp);"
+"COMMIT;";
+
+void kc_dbhandle_reset(void);
+
+#ifdef NO_SERVER
+static void ensureKeychainExists(void) {
+    CFDictionaryRef query = CFDictionaryCreateForCFTypes(0, kSecClass,kSecClassInternetPassword, NULL);
+    CFTypeRef results = NULL;
+    is_status(SecItemCopyMatching(query, &results), errSecItemNotFound, "expected nothing got %@", results);
+    CFReleaseNull(query);
+    CFReleaseNull(results);
+}
+#endif
+
+/* Test basic add delete update copy matching stuff. */
+static void tests(void)
+{
+#ifndef NO_SERVER
+    plan_skip_all("No testing against server.");
+#else
+    char *keychain_name;
+
+    ensureKeychainExists();
+
+    CFStringRef dbPath = __SecKeychainCopyPath();
+    keychain_name = CFStringToCString(dbPath);
+    CFRelease(dbPath);
+
+    /* delete the keychain file, and let sqllite recreate it */
+    ok_unix(unlink(keychain_name), "delete keychain file");
+
+    sqlite3 *db;
+    is(sqlite3_open(keychain_name, &db), SQLITE_OK, "create keychain");
+    is(sqlite3_exec(db, create_db_sql, NULL, NULL, NULL), SQLITE_OK,
+        "populate keychain");
+    free(keychain_name);
+
+    kc_dbhandle_reset();
+
+    int v_eighty = 80;
+    CFNumberRef eighty = CFNumberCreate(NULL, kCFNumberSInt32Type, &v_eighty);
+    const char *v_data = "test";
+    CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data));
+    CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(query, kSecClass, kSecClassInternetPassword);
+    CFDictionaryAddValue(query, kSecAttrServer, CFSTR("members.spamcop.net"));
+    CFDictionaryAddValue(query, kSecAttrAccount, CFSTR("smith"));
+    CFDictionaryAddValue(query, kSecAttrPort, eighty);
+    CFDictionaryAddValue(query, kSecAttrProtocol, kSecAttrProtocolHTTP);
+    CFDictionaryAddValue(query, kSecAttrAuthenticationType, kSecAttrAuthenticationTypeDefault);
+    CFDictionaryAddValue(query, kSecValueData, pwdata);
+    ok_status(SecItemAdd(query, NULL), "add internet password");
+    is_status(SecItemAdd(query, NULL), errSecDuplicateItem,
+       "add internet password again");
+
+    ok_status(SecItemCopyMatching(query, NULL), "Found the item we added");
+
+    ok_status(SecItemDelete(query), "Deleted the item we added");
+
+    CFReleaseSafe(eighty);
+    CFReleaseSafe(pwdata);
+    CFReleaseSafe(query);
+#endif
+}
+
+int si_30_keychain_upgrade(int argc, char *const *argv)
+{
+       plan_tests(8);
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-31-keychain-bad.c b/sec/Security/Regressions/secitem/si-31-keychain-bad.c
new file mode 100644 (file)
index 0000000..e3d17c5
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ *  si-31-keychain-bad.c
+ *  Security
+ *
+ *  Created by Michael Brouwer on 5/23/08.
+ *  Copyright (c) 2008,2010 Apple Inc.. All Rights Reserved.
+ *
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecBase.h>
+#include <Security/SecItem.h>
+
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sqlite3.h>
+
+#include "Security_regressions.h"
+
+const uint8_t keychain_data[] = {
+    0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xd2, 0x01, 0x02, 0x03,
+    0x04, 0x5f, 0x10, 0x1b, 0x4e, 0x53, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77,
+    0x20, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x20, 0x50, 0x72, 0x6f, 0x63, 0x65,
+    0x73, 0x73, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x5f, 0x10, 0x1d, 0x4e, 0x53,
+    0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x46, 0x72, 0x61, 0x6d, 0x65,
+    0x20, 0x41, 0x62, 0x6f, 0x75, 0x74, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20,
+    0x4d, 0x61, 0x63, 0x5f, 0x10, 0x1c, 0x32, 0x38, 0x20, 0x33, 0x37, 0x33,
+    0x20, 0x33, 0x34, 0x36, 0x20, 0x32, 0x39, 0x30, 0x20, 0x30, 0x20, 0x30,
+    0x20, 0x31, 0x34, 0x34, 0x30, 0x20, 0x38, 0x37, 0x38, 0x20, 0x5f, 0x10,
+    0x1d, 0x35, 0x36, 0x38, 0x20, 0x33, 0x39, 0x35, 0x20, 0x33, 0x30, 0x37,
+    0x20, 0x33, 0x37, 0x39, 0x20, 0x30, 0x20, 0x30, 0x20, 0x31, 0x34, 0x34,
+    0x30, 0x20, 0x38, 0x37, 0x38, 0x20, 0x08, 0x0d, 0x2b, 0x4b, 0x6a, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a
+};
+
+void kc_dbhandle_reset(void);
+
+/* Test basic add delete update copy matching stuff. */
+static void tests(void)
+{
+#ifndef NO_SERVER
+    plan_skip_all("No testing against server.");
+#else
+    const char *home_dir = getenv("HOME");
+    char keychain_dir[1000];
+    char keychain_name[1000];
+    sprintf(keychain_dir, "%s/Library/Keychains", home_dir);
+    sprintf(keychain_name, "%s/keychain-2-debug.db", keychain_dir);
+    int fd;
+    ok_unix(fd = open(keychain_name, O_RDWR | O_CREAT | O_TRUNC, 0644),
+        "create keychain file");
+    is(write(fd, keychain_data, sizeof(keychain_data)),
+        (ssize_t)sizeof(keychain_data), "write garbage to keychain file");
+    ok_unix(close(fd), "close keychain file");
+
+    kc_dbhandle_reset();
+
+    int v_eighty = 80;
+    CFNumberRef eighty = CFNumberCreate(NULL, kCFNumberSInt32Type, &v_eighty);
+    const char *v_data = "test";
+    CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data));
+    CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(query, kSecClass, kSecClassInternetPassword);
+    CFDictionaryAddValue(query, kSecAttrServer, CFSTR("members.spamcop.net"));
+    CFDictionaryAddValue(query, kSecAttrAccount, CFSTR("smith"));
+    CFDictionaryAddValue(query, kSecAttrPort, eighty);
+    CFDictionaryAddValue(query, kSecAttrProtocol, kSecAttrProtocolHTTP);
+    CFDictionaryAddValue(query, kSecAttrAuthenticationType, kSecAttrAuthenticationTypeDefault);
+    CFDictionaryAddValue(query, kSecValueData, pwdata);
+    ok_status(SecItemAdd(query, NULL), "add internet password");
+    is_status(SecItemAdd(query, NULL), errSecDuplicateItem,
+       "add internet password again");
+
+    ok_status(SecItemCopyMatching(query, NULL), "Found the item we added");
+
+    ok_status(SecItemDelete(query),"Deleted the item we added");
+
+    CFRelease(query);
+    CFRelease(eighty);
+    CFRelease(pwdata);
+#endif
+}
+
+int si_31_keychain_bad(int argc, char *const *argv)
+{
+       plan_tests(7);
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-31-keychain-unreadable.c b/sec/Security/Regressions/secitem/si-31-keychain-unreadable.c
new file mode 100644 (file)
index 0000000..ad73b6f
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ *  si-31-keychain-unreadable.c
+ *  Security
+ *
+ *  Created by Michael Brouwer on 5/23/08.
+ *  Copyright (c) 2008-2010 Apple Inc.  All Rights Reserved.
+ *
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecBase.h>
+#include <Security/SecItem.h>
+#include <Security/SecInternal.h>
+
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sqlite3.h>
+
+#include "Security_regressions.h"
+
+#ifdef NO_SERVER
+static void ensureKeychainExists(void) {
+    CFDictionaryRef query = CFDictionaryCreate(0, &kSecClass, &kSecClassInternetPassword, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    CFTypeRef results = NULL;
+    is_status(SecItemCopyMatching(query, &results), errSecItemNotFound, "expected nothing got %@", results);
+    CFReleaseNull(query);
+    CFReleaseNull(results);
+}
+#endif
+
+void kc_dbhandle_reset(void);
+
+/* Create an empty keychain file that can't be read or written and make sure
+   securityd can deal with it. */
+static void tests(void)
+{
+#ifndef NO_SERVER
+    plan_skip_all("No testing against server.");
+#else
+    const char *home_dir = getenv("HOME");
+    char keychain_dir[1000];
+    char keychain_name[1000];
+    sprintf(keychain_dir, "%s/Library/Keychains", home_dir);
+    sprintf(keychain_name, "%s/keychain-2-debug.db", keychain_dir);
+
+    ensureKeychainExists();
+    int fd;
+    ok_unix(fd = open(keychain_name, O_RDWR | O_CREAT | O_TRUNC, 0644),
+        "create keychain file '%s'", keychain_name);
+    ok_unix(fchmod(fd, 0), " keychain file '%s'", keychain_name);
+    ok_unix(close(fd), "close keychain file '%s'", keychain_name);
+
+    kc_dbhandle_reset();
+
+    int v_eighty = 80;
+    CFNumberRef eighty = CFNumberCreate(NULL, kCFNumberSInt32Type, &v_eighty);
+    const char *v_data = "test";
+    CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data));
+    CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(query, kSecClass, kSecClassInternetPassword);
+    CFDictionaryAddValue(query, kSecAttrServer, CFSTR("members.spamcop.net"));
+    CFDictionaryAddValue(query, kSecAttrAccount, CFSTR("smith"));
+    CFDictionaryAddValue(query, kSecAttrPort, eighty);
+    CFDictionaryAddValue(query, kSecAttrProtocol, kSecAttrProtocolHTTP);
+    CFDictionaryAddValue(query, kSecAttrAuthenticationType, kSecAttrAuthenticationTypeDefault);
+    CFDictionaryAddValue(query, kSecValueData, pwdata);
+    ok_status(SecItemAdd(query, NULL), "add internet password");
+    is_status(SecItemAdd(query, NULL), errSecDuplicateItem,
+       "add internet password again");
+
+    ok_status(SecItemCopyMatching(query, NULL), "Found the item we added");
+
+    ok_status(SecItemDelete(query),"Deleted the item we added");
+
+    CFReleaseSafe(eighty);
+    CFReleaseSafe(pwdata);
+    CFReleaseSafe(query);
+#endif
+}
+
+int si_31_keychain_unreadable(int argc, char *const *argv)
+{
+       plan_tests(8);
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-33-keychain-backup.c b/sec/Security/Regressions/secitem/si-33-keychain-backup.c
new file mode 100644 (file)
index 0000000..dddb3d1
--- /dev/null
@@ -0,0 +1,481 @@
+/*
+ *  si-33-keychain-backup.c
+ *  Security
+ *
+ *  Created by Michael Brouwer on 1/30/10.
+ *  Copyright 2010 Apple Inc. All rights reserved.
+ *
+ */
+
+#include <TargetConditionals.h>
+
+#if TARGET_OS_EMBEDDED && !TARGET_IPHONE_SIMULATOR
+#define USE_KEYSTORE  1
+#else /* No AppleKeyStore.kext on this OS. */
+#define USE_KEYSTORE  0
+#endif
+
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecBase.h>
+#include <Security/SecItem.h>
+#include <Security/SecInternal.h>
+#include <Security/SecItemPriv.h>
+#include <utilities/array_size.h>
+
+#if USE_KEYSTORE
+#include <IOKit/IOKitLib.h>
+#include <Kernel/IOKit/crypto/AppleKeyStoreDefs.h>
+#endif
+
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sqlite3.h>
+
+#include "Security_regressions.h"
+
+struct test_persistent_s {
+    CFTypeRef persist[2];
+    CFDictionaryRef query;
+    CFDictionaryRef query1;
+    CFDictionaryRef query2;
+    CFMutableDictionaryRef query3;
+    CFMutableDictionaryRef query4;
+};
+
+static void test_persistent(struct test_persistent_s *p)
+{
+    int v_eighty = 80;
+    CFNumberRef eighty = CFNumberCreate(NULL, kCFNumberSInt32Type, &v_eighty);
+    const char *v_data = "test";
+    CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data));
+    const void *keys[] = {
+               kSecClass,
+               kSecAttrServer,
+               kSecAttrAccount,
+               kSecAttrPort,
+               kSecAttrProtocol,
+               kSecAttrAuthenticationType,
+               kSecReturnPersistentRef,
+               kSecValueData
+    };
+    const void *values[] = {
+               kSecClassInternetPassword,
+               CFSTR("zuigt.nl"),
+               CFSTR("frtnbf"),
+               eighty,
+               CFSTR("http"),
+               CFSTR("dflt"),
+               kCFBooleanTrue,
+               pwdata
+    };
+    CFDictionaryRef item = CFDictionaryCreate(NULL, keys, values,
+        array_size(keys), &kCFTypeDictionaryKeyCallBacks,
+        &kCFTypeDictionaryValueCallBacks);
+
+    p->persist[0] = NULL;
+    ok_status(SecItemAdd(item, &p->persist[0]), "add internet password");
+    CFTypeRef results = NULL;
+    CFTypeRef results2 = NULL;
+    SKIP: {
+        skip("no persistent ref", 3, ok(p->persist[0], "got back persistent ref"));
+
+        /* Create a dict with all attrs except the data. */
+        keys[(array_size(keys)) - 2] = kSecReturnAttributes;
+        p->query = CFDictionaryCreate(NULL, keys, values,
+                                      (array_size(keys)) - 1, &kCFTypeDictionaryKeyCallBacks,
+                                      &kCFTypeDictionaryValueCallBacks);
+        ok_status(SecItemCopyMatching(p->query, &results), "find internet password by attr");
+
+        const void *keys_persist[] = {
+            kSecReturnAttributes,
+            kSecValuePersistentRef
+        };
+        const void *values_persist[] = {
+            kCFBooleanTrue,
+            p->persist[0]
+        };
+        p->query2 = CFDictionaryCreate(NULL, keys_persist, values_persist,
+                                       (array_size(keys_persist)), &kCFTypeDictionaryKeyCallBacks,
+                                       &kCFTypeDictionaryValueCallBacks);
+        ok_status(SecItemCopyMatching(p->query2, &results2), "find internet password by persistent ref");
+        ok(CFEqual(results, results2 ? results2 : CFSTR("")), "same item (attributes)");
+
+        CFReleaseNull(results);
+        CFReleaseNull(results2);
+    }
+    ok_status(SecItemDelete(p->query), "delete internet password");
+
+    ok_status(!SecItemCopyMatching(p->query, &results),
+        "don't find internet password by attributes");
+    ok(!results, "no results");
+
+    /* clean up left over from aborted run */
+    if (results) {
+        CFDictionaryRef cleanup = CFDictionaryCreate(NULL, &kSecValuePersistentRef,
+            &results, 1, &kCFTypeDictionaryKeyCallBacks,
+        &kCFTypeDictionaryValueCallBacks);
+        SecItemDelete(cleanup);
+        CFRelease(results);
+        CFRelease(cleanup);
+    }
+
+    ok_status(!SecItemCopyMatching(p->query2, &results2),
+        "don't find internet password by persistent ref anymore");
+    ok(!results2, "no results");
+
+    CFReleaseNull(p->persist[0]);
+
+    /* Add a new item and get it's persitant ref. */
+    ok_status(SecItemAdd(item, &p->persist[0]), "add internet password");
+    p->persist[1] = NULL;
+    CFMutableDictionaryRef item2 = CFDictionaryCreateMutableCopy(NULL, 0, item);
+    CFDictionarySetValue(item2, kSecAttrAccount, CFSTR("johndoe-bu"));
+    ok_status(SecItemAdd(item2, &p->persist[1]), "add second internet password");
+    is(CFGetTypeID(p->persist[0]), CFDataGetTypeID(), "result is a CFData");
+    p->query3 = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks,
+        &kCFTypeDictionaryValueCallBacks);
+    CFDictionaryAddValue(p->query3, kSecValuePersistentRef, p->persist[0]);
+    CFMutableDictionaryRef update = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(update, kSecAttrServer, CFSTR("zuigt.com"));
+    ok_status(SecItemUpdate(p->query3, update), "update via persitant ref");
+
+    /* Verify that the update really worked. */
+    CFDictionaryAddValue(p->query3, kSecReturnAttributes, kCFBooleanTrue);
+    ok_status(SecItemCopyMatching(p->query3, &results2), "find updated internet password by persistent ref");
+    CFStringRef server = CFDictionaryGetValue(results2, kSecAttrServer);
+    ok(CFEqual(server, CFSTR("zuigt.com")), "verify attribute was modified by update");
+    CFReleaseNull(results2);
+    CFDictionaryRemoveValue(p->query3, kSecReturnAttributes);
+
+    /* Verify that item2 wasn't affected by the update. */
+    p->query4 = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks,
+        &kCFTypeDictionaryValueCallBacks);
+    CFDictionaryAddValue(p->query4, kSecValuePersistentRef, p->persist[1]);
+    CFDictionaryAddValue(p->query4, kSecReturnAttributes, kCFBooleanTrue);
+    ok_status(SecItemCopyMatching(p->query4, &results2), "find non updated internet password by persistent ref");
+    server = CFDictionaryGetValue(results2, kSecAttrServer);
+    ok(CFEqual(server, CFSTR("zuigt.nl")), "verify second items attribute was not modified by update");
+    CFReleaseNull(results2);
+
+    /* Delete the item via persitant ref. */
+    ok_status(SecItemDelete(p->query3), "delete via persitant ref");
+    is_status(SecItemCopyMatching(p->query3, &results2), errSecItemNotFound,
+        "don't find deleted internet password by persistent ref");
+    CFReleaseNull(results2);
+    ok_status(SecItemCopyMatching(p->query4, &results2),
+        "find non deleted internet password by persistent ref");
+    CFReleaseNull(results2);
+
+    CFRelease(update);
+    CFReleaseNull(item);
+    CFReleaseNull(item2);
+    CFReleaseNull(eighty);
+    CFReleaseNull(pwdata);
+}
+
+static void test_persistent2(struct test_persistent_s *p)
+{
+    CFTypeRef results = NULL;
+    CFTypeRef results2 = NULL;
+
+    ok_status(!SecItemCopyMatching(p->query, &results),
+        "don't find internet password by attributes");
+    ok(!results, "no results");
+
+    ok_status(!SecItemCopyMatching(p->query2, &results2),
+        "don't find internet password by persistent ref anymore");
+    ok(!results2, "no results");
+
+    SKIP:{
+        ok_status(SecItemCopyMatching(p->query4, &results2), "find non updated internet password by persistent ref");
+        skip("non updated internet password by persistent ref NOT FOUND!", 2, results2);
+        ok(results2, "non updated internet password not found");
+        CFStringRef server = CFDictionaryGetValue(results2, kSecAttrServer);
+        ok(CFEqual(server, CFSTR("zuigt.nl")), "verify second items attribute was not modified by update");
+        CFReleaseNull(results2);
+    }
+
+    is_status(SecItemCopyMatching(p->query3, &results2), errSecItemNotFound,
+        "don't find deleted internet password by persistent ref");
+    CFReleaseNull(results2);
+    ok_status(SecItemCopyMatching(p->query4, &results2),
+        "find non deleted internet password by persistent ref");
+    CFReleaseNull(results2);
+
+    ok_status(SecItemDelete(p->query4),"Deleted internet password by persistent ref");
+
+    CFRelease(p->query);
+    CFRelease(p->query2);
+    CFRelease(p->query3);
+    CFRelease(p->query4);
+    CFReleaseNull(p->persist[0]);
+    CFReleaseNull(p->persist[1]);
+}
+
+static CFMutableDictionaryRef test_create_lockdown_identity_query(void) {
+    CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(query, kSecClass, kSecClassGenericPassword);
+    CFDictionaryAddValue(query, kSecAttrAccessGroup, CFSTR("lockdown-identities"));
+    return query;
+}
+
+static CFMutableDictionaryRef test_create_managedconfiguration_query(void) {
+    CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(query, kSecClass, kSecClassGenericPassword);
+    CFDictionaryAddValue(query, kSecAttrService, CFSTR("com.apple.managedconfiguration"));
+    CFDictionaryAddValue(query, kSecAttrAccount, CFSTR("Public"));
+    CFDictionaryAddValue(query, kSecAttrAccessGroup, CFSTR("apple"));
+    return query;
+}
+
+static void test_add_lockdown_identity_items(void) {
+    CFMutableDictionaryRef query = test_create_lockdown_identity_query();
+    const char *v_data = "lockdown identity data (which should be a cert + key)";
+    CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data));
+    CFDictionaryAddValue(query, kSecValueData, pwdata);
+    ok_status(SecItemAdd(query, NULL), "test_add_lockdown_identity_items");
+    CFReleaseSafe(pwdata);
+    CFReleaseSafe(query);
+}
+
+static void test_remove_lockdown_identity_items(void) {
+    CFMutableDictionaryRef query = test_create_lockdown_identity_query();
+    ok_status(SecItemDelete(query), "test_remove_lockdown_identity_items");
+    CFReleaseSafe(query);
+}
+
+static void test_no_find_lockdown_identity_item(void) {
+    CFMutableDictionaryRef query = test_create_lockdown_identity_query();
+    is_status(SecItemCopyMatching(query, NULL), errSecItemNotFound,
+        "test_no_find_lockdown_identity_item");
+    CFReleaseSafe(query);
+}
+
+static void test_add_managedconfiguration_item(void) {
+    CFMutableDictionaryRef query = test_create_managedconfiguration_query();
+    const char *v_data = "public managedconfiguration password history data";
+    CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data));
+    CFDictionaryAddValue(query, kSecValueData, pwdata);
+    ok_status(SecItemAdd(query, NULL), "test_add_managedconfiguration_item");
+    CFReleaseSafe(pwdata);
+    CFReleaseSafe(query);
+}
+
+static void test_find_managedconfiguration_item(void) {
+    CFMutableDictionaryRef query = test_create_managedconfiguration_query();
+    ok_status(SecItemCopyMatching(query, NULL), "test_find_managedconfiguration_item");
+    ok_status(SecItemDelete(query), "test_find_managedconfiguration_item (deleted)");
+    CFReleaseSafe(query);
+}
+
+#if USE_KEYSTORE
+static io_connect_t connect_to_keystore(void)
+{
+    io_registry_entry_t apple_key_bag_service;
+    kern_return_t result;
+    io_connect_t keystore = MACH_PORT_NULL;
+
+    apple_key_bag_service = IOServiceGetMatchingService(kIOMasterPortDefault,
+                                                        IOServiceMatching(kAppleKeyStoreServiceName));
+
+    if (apple_key_bag_service == IO_OBJECT_NULL) {
+        fprintf(stderr, "Failed to get service.\n");
+        return keystore;
+    }
+
+    result = IOServiceOpen(apple_key_bag_service, mach_task_self(), 0, &keystore);
+    if (KERN_SUCCESS != result)
+        fprintf(stderr, "Failed to open keystore\n");
+
+    if (keystore != MACH_PORT_NULL) {
+        IOReturn kernResult = IOConnectCallMethod(keystore,
+                                                  kAppleKeyStoreUserClientOpen, NULL, 0, NULL, 0, NULL, NULL,
+                                                  NULL, NULL);
+        if (kernResult) {
+            fprintf(stderr, "Failed to open AppleKeyStore: %x\n", kernResult);
+        }
+    }
+       return keystore;
+}
+
+static CFDataRef create_keybag(keybag_handle_t bag_type, CFDataRef password)
+{
+    uint64_t inputs[] = { bag_type };
+    uint64_t outputs[] = {0};
+    uint32_t num_inputs = array_size(inputs);
+    uint32_t num_outputs = array_size(outputs);
+    IOReturn kernResult;
+
+    io_connect_t keystore;
+
+    unsigned char keybagdata[4096]; //Is that big enough?
+       size_t keybagsize=sizeof(keybagdata);
+
+    keystore=connect_to_keystore();
+
+    kernResult = IOConnectCallMethod(keystore,
+                                     kAppleKeyStoreKeyBagCreate,
+                                     inputs, num_inputs, NULL, 0,
+                                     outputs, &num_outputs, NULL, 0);
+
+    if (kernResult) {
+        fprintf(stderr, "kAppleKeyStoreKeyBagCreate: 0x%x\n", kernResult);
+        return NULL;
+    }
+
+    /* Copy out keybag */
+       inputs[0]=outputs[0];
+    num_inputs=1;
+
+    kernResult = IOConnectCallMethod(keystore,
+                                     kAppleKeyStoreKeyBagCopy,
+                                     inputs, num_inputs, NULL, 0,
+                                     NULL, 0, keybagdata, &keybagsize);
+
+    if (kernResult) {
+        fprintf(stderr, "kAppleKeyStoreKeyBagCopy: 0x%x\n", kernResult);
+        return NULL;
+    }
+
+    return CFDataCreate(kCFAllocatorDefault, keybagdata, keybagsize);
+}
+#endif
+
+/* Test low level keychain migration from device to device interface. */
+static void tests(void)
+{
+    int v_eighty = 80;
+    CFNumberRef eighty = CFNumberCreate(NULL, kCFNumberSInt32Type, &v_eighty);
+    const char *v_data = "test";
+    CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data));
+    CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(query, kSecClass, kSecClassInternetPassword);
+    CFDictionaryAddValue(query, kSecAttrServer, CFSTR("members.spamcop.net"));
+    CFDictionaryAddValue(query, kSecAttrAccount, CFSTR("smith"));
+    CFDictionaryAddValue(query, kSecAttrPort, eighty);
+    CFDictionaryAddValue(query, kSecAttrProtocol, kSecAttrProtocolHTTP);
+    CFDictionaryAddValue(query, kSecAttrAuthenticationType, kSecAttrAuthenticationTypeDefault);
+    CFDictionaryAddValue(query, kSecValueData, pwdata);
+    ok_status(SecItemAdd(query, NULL), "add internet password");
+    is_status(SecItemAdd(query, NULL), errSecDuplicateItem,
+       "add internet password again");
+
+    ok_status(SecItemCopyMatching(query, NULL), "Found the item we added");
+
+    struct test_persistent_s p = {};
+    test_persistent(&p);
+
+    CFDataRef backup = NULL, keybag = NULL, password = NULL;
+
+    test_add_lockdown_identity_items();
+
+#if USE_KEYSTORE
+    keybag = create_keybag(kAppleKeyStoreBackupBag, password);
+#else
+    keybag = CFDataCreate(kCFAllocatorDefault, NULL, 0);
+#endif
+
+    ok(backup = _SecKeychainCopyBackup(keybag, password),
+        "_SecKeychainCopyBackup");
+
+    test_add_managedconfiguration_item();
+    test_remove_lockdown_identity_items();
+
+    ok_status(_SecKeychainRestoreBackup(backup, keybag, password),
+        "_SecKeychainRestoreBackup");
+    CFReleaseSafe(backup);
+
+    test_no_find_lockdown_identity_item();
+    test_find_managedconfiguration_item();
+
+    ok_status(SecItemCopyMatching(query, NULL),
+        "Found the item we added after restore");
+
+    test_persistent2(&p);
+
+#if USE_KEYSTORE
+    CFReleaseNull(keybag);
+    keybag = create_keybag(kAppleKeyStoreOTABackupBag, password);
+#endif
+
+    ok(backup = _SecKeychainCopyBackup(keybag, password),
+       "_SecKeychainCopyBackup");
+    ok_status(_SecKeychainRestoreBackup(backup, keybag, password),
+              "_SecKeychainRestoreBackup");
+    ok_status(SecItemCopyMatching(query, NULL),
+              "Found the item we added after restore");
+    CFReleaseNull(backup);
+
+    CFDictionaryAddValue(query, kSecUseTombstones, kCFBooleanTrue);
+
+    ok_status(SecItemDelete(query), "Deleted item we added");
+
+#if USE_KEYSTORE
+    CFReleaseNull(keybag);
+    keybag = create_keybag(kAppleKeyStoreOTABackupBag /* use truthiness bag once it's there */, password);
+#endif
+
+    // add syncable item
+    CFDictionaryAddValue(query, kSecAttrSynchronizable, kCFBooleanTrue);
+    ok_status(SecItemAdd(query, NULL), "add internet password");
+
+    // and non-syncable item
+    test_add_managedconfiguration_item();
+
+    CFDictionaryRef syncableBackup = NULL;
+
+    ok_status(_SecKeychainBackupSyncable(keybag, password, NULL, &syncableBackup), "export items");
+
+    // TODO: add item, call SecServerCopyTruthInTheCloud again
+
+    // CFShow(syncableBackup);
+
+    // find and delete
+    ok_status(SecItemCopyMatching(query, NULL), "find item we are about to destroy");
+
+    ok_status(SecItemDelete(query), "delete item we backed up");
+
+    // ensure we added a tombstone
+    CFDictionaryAddValue(query, kSecAttrTombstone, kCFBooleanTrue);
+    ok_status(SecItemCopyMatching(query, NULL), "find tombstone for item we deleted");
+    CFDictionaryRemoveValue(query, kSecAttrTombstone);
+
+    test_find_managedconfiguration_item();
+
+    // TODO: add a different new item - delete what's not in the syncableBackup?
+
+    // Do another backup after some changes
+    CFDictionaryRef scratch = NULL;
+    ok_status(_SecKeychainBackupSyncable(keybag, password, syncableBackup, &scratch), "export items after changes");
+    CFReleaseNull(scratch);
+
+    ok_status(_SecKeychainRestoreSyncable(keybag, password, syncableBackup), "import items");
+
+    // non-syncable item should (still) be gone -> add should work
+    test_add_managedconfiguration_item();
+    test_find_managedconfiguration_item();
+
+    // syncable item should have not been restored, because the tombstone was newer than the item in the backup -> copy matching should fail
+    is_status(errSecItemNotFound, SecItemCopyMatching(query, NULL),
+              "find restored item");
+    is_status(errSecItemNotFound, SecItemDelete(query), "delete restored item");
+
+    CFReleaseSafe(syncableBackup);
+    CFReleaseSafe(keybag);
+    CFReleaseSafe(eighty);
+    CFReleaseSafe(pwdata);
+    CFReleaseSafe(query);
+}
+
+int si_33_keychain_backup(int argc, char *const *argv)
+{
+       plan_tests(62);
+
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-40-seckey-custom.c b/sec/Security/Regressions/secitem/si-40-seckey-custom.c
new file mode 100644 (file)
index 0000000..9a22851
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ *  si-40-seckey.c
+ *  Security
+ *
+ *  Created by Michael Brouwer on 1/29/07.
+ *  Copyright (c) 2007-2008,2010 Apple Inc. All Rights Reserved.
+ *
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecKeyPriv.h>
+
+#include "Security_regressions.h"
+
+#define CFReleaseNull(CF) { CFTypeRef _cf = (CF); if (_cf) {  (CF) = NULL; CFRelease(_cf); } }
+
+static SecKeyRef customKey;
+static SecKeyRef initedCustomKey;
+
+static OSStatus CustomKeyInit(SecKeyRef key, const uint8_t *key_data,
+    CFIndex key_len, SecKeyEncoding encoding)
+{
+    ok(key, "CustomKeyInit");
+    is(key->key, NULL, "key->key is NULL");
+    initedCustomKey = key;
+    return errSecSuccess;
+}
+
+static void CustomKeyDestroy(SecKeyRef key)
+{
+    is(customKey, key, "CustomKeyDestroy");
+}
+
+static OSStatus CustomKeyRawSign(SecKeyRef key, SecPadding padding,
+       const uint8_t *dataToSign, size_t dataToSignLen,
+       uint8_t *sig, size_t *sigLen)
+{
+    is(customKey, key, "CustomKeyRawSign");
+    return errSecSuccess;
+}
+
+static OSStatus CustomKeyRawVerify(
+    SecKeyRef key, SecPadding padding, const uint8_t *signedData,
+    size_t signedDataLen, const uint8_t *sig, size_t sigLen)
+{
+    is(customKey, key, "CustomKeyRawVerify");
+    return errSecSuccess;
+}
+
+static OSStatus CustomKeyEncrypt(SecKeyRef key, SecPadding padding,
+    const uint8_t *plainText, size_t plainTextLen,
+       uint8_t *cipherText, size_t *cipherTextLen)
+{
+    is(customKey, key, "CustomKeyEncrypt");
+    return errSecSuccess;
+}
+
+static OSStatus CustomKeyDecrypt(SecKeyRef key, SecPadding padding,
+    const uint8_t *cipherText, size_t cipherTextLen,
+    uint8_t *plainText, size_t *plainTextLen)
+{
+    is(customKey, key, "CustomKeyDecrypt");
+    return errSecSuccess;
+}
+
+static OSStatus CustomKeyCompute(SecKeyRef key,
+    const uint8_t *pub_key, size_t pub_key_len,
+    uint8_t *computed_key, size_t *computed_key_len)
+{
+    is(customKey, key, "CustomKeyCompute");
+    return errSecSuccess;
+}
+
+static size_t CustomKeyBlockSize(SecKeyRef key)
+{
+    is(customKey, key, "CustomKeyBlockSize");
+    return 42;
+}
+
+static CFDictionaryRef CustomKeyCopyAttributeDictionary(SecKeyRef key)
+{
+    is(customKey, key, "CustomKeyCopyAttributeDictionary");
+    CFDictionaryRef dict = CFDictionaryCreate(kCFAllocatorDefault, NULL, NULL,
+        0, NULL, NULL);
+    return dict;
+}
+
+SecKeyDescriptor kCustomKeyDescriptor = {
+    kSecKeyDescriptorVersion,
+    "CustomKey",
+    0, /* extraBytes */
+    CustomKeyInit,
+    CustomKeyDestroy,
+    CustomKeyRawSign,
+    CustomKeyRawVerify,
+    CustomKeyEncrypt,
+    CustomKeyDecrypt,
+    CustomKeyCompute,
+    CustomKeyBlockSize,
+       CustomKeyCopyAttributeDictionary,
+};
+
+/* Test basic add delete update copy matching stuff. */
+static void tests(void)
+{
+    const uint8_t *keyData = (const uint8_t *)"abc";
+    CFIndex keyDataLength = 3;
+    SecKeyEncoding encoding = kSecKeyEncodingRaw;
+    ok(customKey = SecKeyCreate(kCFAllocatorDefault,
+        &kCustomKeyDescriptor, keyData, keyDataLength, encoding),
+        "create custom key");
+    is(customKey, initedCustomKey, "CustomKeyInit got the right key");
+
+    SecPadding padding = kSecPaddingPKCS1;
+    const uint8_t *src = NULL;
+    size_t srcLen = 3;
+    uint8_t *dst = NULL;
+    size_t dstLen = 3;
+
+    ok_status(SecKeyDecrypt(customKey, padding, src, srcLen, dst, &dstLen),
+        "SecKeyDecrypt");
+    ok_status(SecKeyEncrypt(customKey, padding, src, srcLen, dst, &dstLen),
+        "SecKeyEncrypt");
+    ok_status(SecKeyRawSign(customKey, padding, src, srcLen, dst, &dstLen),
+        "SecKeyRawSign");
+    ok_status(SecKeyRawVerify(customKey, padding, src, srcLen, dst, dstLen),
+        "SecKeyRawVerify");
+    is(SecKeyGetSize(customKey, kSecKeyKeySizeInBits), (size_t)42*8, "SecKeyGetSize");
+
+    CFDictionaryRef attrDict = NULL;
+    ok(attrDict = SecKeyCopyAttributeDictionary(customKey),
+        "SecKeyCopyAttributeDictionary");
+    CFReleaseNull(attrDict);
+
+    //ok(SecKeyGeneratePair(customKey, ), "SecKeyGeneratePair");
+    ok(SecKeyGetTypeID() != 0, "SecKeyGetTypeID works");
+
+    if (customKey) {
+        CFRelease(customKey);
+        customKey = NULL;
+    }
+}
+
+int si_40_seckey_custom(int argc, char *const *argv)
+{
+       plan_tests(18);
+
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-40-seckey.c b/sec/Security/Regressions/secitem/si-40-seckey.c
new file mode 100644 (file)
index 0000000..aef3a8f
--- /dev/null
@@ -0,0 +1,440 @@
+/*
+ *  si-40-seckey.c
+ *  Security
+ *
+ *  Created by Michael Brouwer on 1/29/07.
+ *  Copyright (c) 2007-2009 Apple Inc. All Rights Reserved.
+ *
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecCertificateInternal.h>
+#include <Security/SecKey.h>
+#include <Security/SecKeyPriv.h>
+#include <Security/SecItem.h>
+#include <Security/SecAsn1Types.h>
+#include <Security/oidsalg.h>
+#include <Security/SecureTransport.h>
+#include <Security/SecRandom.h>
+#include <utilities/array_size.h>
+#include <CommonCrypto/CommonDigest.h>
+#include <libDER/libDER.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "Security_regressions.h"
+
+#include "utilities/SecCFRelease.h"
+
+static void testdigestandsignalg(SecKeyRef privKey, SecKeyRef pubKey, const SecAsn1AlgId *algId) {
+    uint8_t dataToDigest[256] = {0,};
+    size_t dataToDigestLen = sizeof(dataToDigest);
+    size_t sigLen = SecKeyGetSize(privKey, kSecKeySignatureSize);
+    uint8_t sig[sigLen];
+
+    DERItem oid;
+    oid.length = algId->algorithm.Length;
+    oid.data = algId->algorithm.Data;
+
+    /* Get the oid in decimal for display purposes. */
+    CFStringRef oidStr = SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault, &oid);
+       char oidBuf[40];
+    CFStringGetCString(oidStr, oidBuf, sizeof(oidBuf), kCFStringEncodingUTF8);
+    CFRelease(oidStr);
+
+       SKIP: {
+        OSStatus status;
+
+        /* Time to sign. */
+        ok_status(status = SecKeyDigestAndSign(privKey, algId, dataToDigest, dataToDigestLen,
+            sig, &sigLen), "digest and sign %s with %ld bit RSA key", oidBuf, sigLen * 8);
+
+        skip("SecKeyDigestAndSign failed", 3, status == errSecSuccess);
+
+        /* Verify the signature we just made. */
+        ok_status(SecKeyDigestAndVerify(pubKey, algId, dataToDigest, dataToDigestLen,
+            sig, sigLen), "digest and verify");
+        /* Invalidate the signature. */
+        sig[0] ^= 0xff;
+        is_status(SecKeyDigestAndVerify(pubKey, algId, dataToDigest, dataToDigestLen,
+            sig, sigLen), errSSLCrypto, "digest and verify bad sig");
+        sig[0] ^= 0xff;
+        dataToDigest[0] ^= 0xff;
+        is_status(SecKeyDigestAndVerify(pubKey, algId, dataToDigest, dataToDigestLen,
+            sig, sigLen), errSSLCrypto, "digest and verify bad digest");
+    }
+}
+
+static void testdigestandsign(SecKeyRef privKey, SecKeyRef pubKey) {
+    static const SecAsn1Oid *oids[] = {
+        &CSSMOID_SHA1WithRSA,
+        &CSSMOID_SHA224WithRSA,
+        &CSSMOID_SHA256WithRSA,
+        &CSSMOID_SHA384WithRSA,
+        &CSSMOID_SHA512WithRSA,
+#if 0
+        &CSSMOID_SHA1WithRSA_OIW,
+        &CSSMOID_SHA1WithDSA,          // BSAFE
+        &CSSMOID_SHA1WithDSA_CMS,      // X509/CMS
+        &CSSMOID_SHA1WithDSA_JDK,      // JDK 1.1
+#endif
+    };
+
+
+    uint32_t ix;
+    SecAsn1AlgId algId = {};
+    for (ix = 0; ix < array_size(oids); ++ix) {
+        if (oids[ix]) {
+            algId.algorithm = *oids[ix];
+        } else {
+            algId.algorithm.Length = 0;
+            algId.algorithm.Data = NULL;
+        }
+
+        testdigestandsignalg(privKey, pubKey, &algId);
+    }
+}
+
+#if 0
+static void dump_bytes(uint8_t* bytes, size_t amount)
+{
+    while (amount > 0) {
+        printf("0x%02x ", *bytes);
+        ++bytes;
+        --amount;
+    }
+}
+#endif
+
+#define kEncryptDecryptTestCount 5
+static void test_encrypt_decrypt(SecKeyRef pubKey, SecKeyRef privKey, uint32_t padding, size_t keySizeInBytes)
+{
+    SKIP: {
+        size_t max_len = keySizeInBytes;
+        switch (padding) {
+            case kSecPaddingNone: max_len = keySizeInBytes; break;
+            case kSecPaddingOAEP: max_len = keySizeInBytes - 2 - 2 * CC_SHA1_DIGEST_LENGTH; break;
+            case kSecPaddingPKCS1: max_len = keySizeInBytes - 11; break;
+            default: skip("what is the max_len for this padding?", 5, false);
+        }
+
+        uint8_t secret[max_len + 1], encrypted_secret[keySizeInBytes], decrypted_secret[keySizeInBytes];
+        uint8_t *secret_ptr = secret;
+        size_t secret_len = max_len;
+        size_t encrypted_secret_len = sizeof(encrypted_secret);
+        size_t decrypted_secret_len = sizeof(decrypted_secret);
+        memset(decrypted_secret, 0xff, decrypted_secret_len);
+        SecRandomCopyBytes(kSecRandomDefault, sizeof(secret), secret);
+
+        // zero pad, no accidental second zero byte
+        if (padding == kSecPaddingNone) {
+            secret[0] = 0;
+            secret[1] = 128;
+        }
+
+        is_status(SecKeyEncrypt(pubKey, padding,
+                                secret, sizeof(secret),
+                                encrypted_secret, &encrypted_secret_len), errSecParam, "encrypt secret (overflow)");
+        ok_status(SecKeyEncrypt(pubKey, padding,
+                                secret, secret_len,
+                                encrypted_secret, &encrypted_secret_len), "encrypt secret");
+
+        ok_status(SecKeyDecrypt(privKey, padding,
+                                encrypted_secret, encrypted_secret_len,
+                                decrypted_secret, &decrypted_secret_len), "decrypt secret");
+
+        // zero padding is removed on decode
+        if (padding == kSecPaddingNone) {
+            secret_len--;
+            secret_ptr++;
+        }
+
+        ok(decrypted_secret_len == secret_len, "correct length");
+        ok_status(memcmp(secret_ptr, decrypted_secret, secret_len), "verify secret");
+    }
+}
+
+#define kKeyGenTestCount (49 + (3*kEncryptDecryptTestCount))
+static void testkeygen(size_t keySizeInBits) {
+       SecKeyRef pubKey = NULL, privKey = NULL;
+       size_t keySizeInBytes = (keySizeInBits + 7) / 8;
+       CFNumberRef kzib;
+
+       kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keySizeInBits);
+       CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+       CFDictionaryAddValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
+       CFDictionaryAddValue(kgp, kSecAttrKeySizeInBits, kzib);
+
+       OSStatus status;
+       ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
+              "Generate %ld bit (%ld byte) RSA keypair", keySizeInBits,
+              keySizeInBytes);
+       CFRelease(kzib);
+       CFRelease(kgp);
+
+       SKIP: {
+        skip("keygen failed", 8, status == errSecSuccess);
+               ok(pubKey, "pubkey returned");
+               ok(privKey, "privKey returned");
+               is(SecKeyGetSize(pubKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "public key size is ok");
+               is(SecKeyGetSize(privKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "private key size is ok");
+
+               /* Sign something. */
+               uint8_t something[keySizeInBytes];
+        size_t something_len = keySizeInBytes - 11;
+        SecRandomCopyBytes(kSecRandomDefault, sizeof(something), something);
+               uint8_t sig[keySizeInBytes];
+               size_t sigLen = sizeof(sig);
+               is_status(SecKeyRawSign(privKey, kSecPaddingPKCS1,
+                                something, something_len + 1, sig, &sigLen),
+                                errSecParam, "sign overflow");
+               ok_status(SecKeyRawSign(privKey, kSecPaddingPKCS1,
+                       something, something_len, sig, &sigLen), "sign something");
+               ok_status(SecKeyRawVerify(pubKey, kSecPaddingPKCS1,
+                       something, something_len, sig, sigLen), "verify sig on something");
+
+        // Torture test ASN.1 encoder by setting high bit to 1.
+        uint8_t digest[CC_SHA512_DIGEST_LENGTH] = {
+            0x80, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+            0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+            0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+            0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+            0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+            0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+            0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+        };
+        //CC_MD2(something, sizeof(something), digest);
+               ok_status(!SecKeyRawSign(privKey, kSecPaddingPKCS1MD2,
+                       digest, CC_MD2_DIGEST_LENGTH, sig, &sigLen),
+            "don't sign md2 digest");
+               ok_status(!SecKeyRawVerify(pubKey, kSecPaddingPKCS1MD2,
+                       digest, CC_MD2_DIGEST_LENGTH, sig, sigLen),
+            "verify sig on md2 digest fails");
+
+        //CC_MD5(something, sizeof(something), digest);
+               sigLen = sizeof(sig);
+               ok_status(!SecKeyRawSign(privKey, kSecPaddingPKCS1MD5,
+                       digest, CC_MD5_DIGEST_LENGTH, sig, &sigLen),
+            "don't sign md5 digest");
+               ok_status(!SecKeyRawVerify(pubKey, kSecPaddingPKCS1MD5,
+                       digest, CC_MD5_DIGEST_LENGTH, sig, sigLen),
+            "verify sig on md5 digest fails");
+
+        //CCDigest(kCCDigestSHA1, something, sizeof(something), digest);
+               sigLen = sizeof(sig);
+               ok_status(SecKeyRawSign(privKey, kSecPaddingPKCS1SHA1,
+                       digest, CC_SHA1_DIGEST_LENGTH, sig, &sigLen),
+            "sign sha1 digest");
+               ok_status(SecKeyRawVerify(pubKey, kSecPaddingPKCS1SHA1,
+                       digest, CC_SHA1_DIGEST_LENGTH, sig, sigLen),
+            "verify sig on sha1 digest");
+
+               uint8_t signature[keySizeInBytes], *ptr = signature;
+               size_t signature_len = sizeof(signature);
+               ok_status(SecKeyDecrypt(pubKey, kSecPaddingNone, sig, sigLen, signature, &signature_len), "inspect signature");
+               is(signature_len, keySizeInBytes - 1, "got signature");
+               while(*ptr && ((size_t)(ptr - signature) < signature_len)) ptr++;
+               is(signature + signature_len - ptr, 16 /* length(\0 || OID_SHA1) */ + CC_SHA1_DIGEST_LENGTH, "successful decode");
+
+        /* PKCS1 padding is 00 01 PAD * 8 or more 00 data.
+           data is SEQ { SEQ { OID NULL } BIT STRING 00 DIGEST }
+           So min data + pad overhead is 11 + 9 + oidlen
+           oidlen = 11 for the sha2 family of oids, so we have 29 bytes; or
+           232 bits of minimum overhead.  */
+        const size_t pkcs1Overhead = 232;
+        if (keySizeInBits > 224 + pkcs1Overhead) {
+            //CC_SHA224(something, sizeof(something), digest);
+            sigLen = sizeof(sig);
+            ok_status(SecKeyRawSign(privKey, kSecPaddingPKCS1SHA224,
+                                    digest, CC_SHA224_DIGEST_LENGTH, sig, &sigLen),
+                      "sign sha224 digest");
+            ok_status(SecKeyRawVerify(pubKey, kSecPaddingPKCS1SHA224,
+                                      digest, CC_SHA224_DIGEST_LENGTH, sig, sigLen),
+                      "verify sig on sha224 digest");
+        }
+
+        if (keySizeInBits > 256 + pkcs1Overhead) {
+            //CC_SHA256(something, sizeof(something), digest);
+            sigLen = sizeof(sig);
+            ok_status(SecKeyRawSign(privKey, kSecPaddingPKCS1SHA256,
+                                    digest, CC_SHA256_DIGEST_LENGTH, sig, &sigLen),
+                      "sign sha256 digest");
+            ok_status(SecKeyRawVerify(pubKey, kSecPaddingPKCS1SHA256,
+                                      digest, CC_SHA256_DIGEST_LENGTH, sig, sigLen),
+                      "verify sig on sha256 digest");
+        }
+
+        if (keySizeInBits > 384 + pkcs1Overhead) {
+            //CC_SHA384(something, sizeof(something), digest);
+            sigLen = sizeof(sig);
+            ok_status(SecKeyRawSign(privKey, kSecPaddingPKCS1SHA384,
+                                    digest, CC_SHA384_DIGEST_LENGTH, sig, &sigLen),
+                      "sign sha384 digest");
+            ok_status(SecKeyRawVerify(pubKey, kSecPaddingPKCS1SHA384,
+                                      digest, CC_SHA384_DIGEST_LENGTH, sig, sigLen),
+                      "verify sig on sha384 digest");
+        }
+
+        if (keySizeInBits > 512 + pkcs1Overhead) {
+            //CC_SHA512(something, sizeof(something), digest);
+            sigLen = sizeof(sig);
+            ok_status(SecKeyRawSign(privKey, kSecPaddingPKCS1SHA512,
+                                    digest, CC_SHA512_DIGEST_LENGTH, sig, &sigLen),
+                      "sign sha512 digest");
+            ok_status(SecKeyRawVerify(pubKey, kSecPaddingPKCS1SHA512,
+                                      digest, CC_SHA512_DIGEST_LENGTH, sig, sigLen),
+                      "verify sig on sha512 digest");
+        }
+
+        test_encrypt_decrypt(pubKey, privKey, kSecPaddingNone, keySizeInBytes);
+        test_encrypt_decrypt(pubKey, privKey, kSecPaddingPKCS1, keySizeInBytes);
+        test_encrypt_decrypt(pubKey, privKey, kSecPaddingOAEP, keySizeInBytes);
+
+        testdigestandsign(privKey, pubKey);
+
+               const void *privkeys[] = {
+                       kSecValueRef
+               };
+               const void *privvalues[] = {
+                       privKey
+               };
+               CFDictionaryRef privitem = CFDictionaryCreate(NULL, privkeys, privvalues,
+               array_size(privkeys), NULL, NULL);
+               ok_status(SecItemAdd(privitem, NULL), "add private key");
+        ok_status(SecItemDelete(privitem), "delete private key");
+               CFReleaseNull(privitem);
+
+               const void *pubkeys[] = {
+                       kSecValueRef
+               };
+               const void *pubvalues[] = {
+                       pubKey
+               };
+               CFDictionaryRef pubitem = CFDictionaryCreate(NULL, pubkeys, pubvalues,
+               array_size(pubkeys), NULL, NULL);
+               ok_status(SecItemAdd(pubitem, NULL), "add public key");
+        ok_status(SecItemDelete(pubitem), "delete public key");
+               CFReleaseNull(pubitem);
+
+               /* Cleanup. */
+               CFReleaseNull(pubKey);
+               CFReleaseNull(privKey);
+       }
+}
+
+#define kKeyGen2TestCount 12
+static void testkeygen2(size_t keySizeInBits) {
+       SecKeyRef pubKey = NULL, privKey = NULL;
+       size_t keySizeInBytes = (keySizeInBits + 7) / 8;
+       CFNumberRef kzib;
+
+    CFUUIDRef ourUUID = CFUUIDCreate(kCFAllocatorDefault);
+    CFStringRef uuidString = CFUUIDCreateString(kCFAllocatorDefault, ourUUID);
+    CFMutableStringRef publicName = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, uuidString);
+    CFMutableStringRef privateName = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, uuidString);
+
+    CFReleaseNull(ourUUID);
+    CFReleaseNull(uuidString);
+
+    CFStringAppend(publicName, CFSTR("-Public-40"));
+    CFStringAppend(privateName, CFSTR("-Private-40"));
+       CFMutableDictionaryRef pubd = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+       CFMutableDictionaryRef privd = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+
+       CFDictionaryAddValue(pubd, kSecAttrLabel, publicName);
+       CFDictionaryAddValue(privd, kSecAttrLabel, privateName);
+
+       kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keySizeInBits);
+       CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+       CFDictionaryAddValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
+       CFDictionaryAddValue(kgp, kSecAttrKeySizeInBits, kzib);
+       CFDictionaryAddValue(kgp, kSecAttrIsPermanent, kCFBooleanTrue);
+       CFDictionaryAddValue(kgp, kSecPublicKeyAttrs, pubd);
+       CFDictionaryAddValue(kgp, kSecPrivateKeyAttrs, privd);
+
+       OSStatus status;
+       ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
+              "Generate %ld bit (%ld byte) persistent RSA keypair",
+              keySizeInBits, keySizeInBytes);
+       CFRelease(kzib);
+       CFRelease(kgp);
+
+       SKIP: {
+        skip("keygen failed", 8, status == errSecSuccess);
+               ok(pubKey, "pubkey returned");
+               ok(privKey, "privKey returned");
+               is(SecKeyGetSize(pubKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "public key size is ok");
+               is(SecKeyGetSize(privKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "private key size is ok");
+
+               SecKeyRef pubKey2, privKey2;
+               CFDictionaryAddValue(pubd, kSecClass, kSecClassKey);
+               CFDictionaryAddValue(pubd, kSecReturnRef, kCFBooleanTrue);
+               CFDictionaryAddValue(privd, kSecClass, kSecClassKey);
+               CFDictionaryAddValue(privd, kSecReturnRef, kCFBooleanTrue);
+        CFDictionaryAddValue(privd, kSecAttrCanSign, kCFBooleanTrue);
+               ok_status(SecItemCopyMatching(pubd, (CFTypeRef *)&pubKey2),
+                       "retrieve pub key by label");
+               ok_status(SecItemCopyMatching(privd, (CFTypeRef *)&privKey2),
+                       "retrieve priv key by label and kSecAttrCanSign");
+
+               /* Sign something. */
+               uint8_t something[50] = {0x80, 0xbe, 0xef, 0xba, 0xd0, };
+               uint8_t sig[keySizeInBytes];
+               size_t sigLen = keySizeInBytes;
+               ok_status(SecKeyRawSign(privKey2, kSecPaddingPKCS1,
+                       something, sizeof(something), sig, &sigLen), "sign something");
+               ok_status(SecKeyRawVerify(pubKey2, kSecPaddingPKCS1,
+                       something, sizeof(something), sig, sigLen), "verify sig on something");
+
+        sigLen = keySizeInBytes;
+               is_status(SecKeyEncrypt(pubKey2, kSecPaddingPKCS1SHA1,
+                       something, sizeof(something), sig, &sigLen), errSecParam,
+            "encrypt something with invalid padding");
+
+               /* Cleanup. */
+               CFReleaseNull(pubKey2);
+               CFReleaseNull(privKey2);
+
+        /* delete from keychain - note: do it before releasing publicName and privateName
+         because pubd and privd have no retain/release callbacks */
+        ok_status(SecItemDelete(pubd), "delete generated pub key");
+        ok_status(SecItemDelete(privd), "delete generated priv key");
+       }
+
+       /* Cleanup. */
+       CFReleaseNull(pubKey);
+       CFReleaseNull(privKey);
+
+    CFReleaseNull(publicName);
+    CFReleaseNull(privateName);
+
+       CFRelease(pubd);
+       CFRelease(privd);
+}
+
+/* Test basic add delete update copy matching stuff. */
+#define kTestCount ((3 * kKeyGenTestCount) + kKeyGen2TestCount)
+static void tests(void)
+{
+       /* Comment out lines below for testing generating all common key sizes,
+          disabled now for speed reasons. */
+       //testkeygen(512);
+       testkeygen(768);
+       testkeygen(1024);
+       testkeygen(2056); // Stranged sized for edge cases in padding.
+       //testkeygen(2048);
+       //testkeygen(4096);
+
+    testkeygen2(768);
+}
+
+int si_40_seckey(int argc, char *const *argv)
+{
+       plan_tests(kTestCount);
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-41-sececkey.c b/sec/Security/Regressions/secitem/si-41-sececkey.c
new file mode 100644 (file)
index 0000000..cf407cb
--- /dev/null
@@ -0,0 +1,283 @@
+//
+//  si-41-sececkey.c
+//  regressions
+//
+//  Created by Mitch Adler on 5/20/11.
+//  Copyright 2011 Apple Inc. All rights reserved.
+//
+
+/*
+ *  si-40-seckey.c
+ *  Security
+ *
+ *  Created by Michael Brouwer on 1/29/07.
+ *  Copyright (c) 2007-2009 Apple Inc. All Rights Reserved.
+ *
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecCertificateInternal.h>
+#include <Security/SecKey.h>
+#include <Security/SecKeyPriv.h>
+#include <Security/SecItem.h>
+#include <Security/SecAsn1Types.h>
+#include <Security/oidsalg.h>
+#include <Security/SecureTransport.h>
+#include <Security/SecRandom.h>
+#include <utilities/array_size.h>
+#include <CommonCrypto/CommonDigest.h>
+#include <libDER/libDER.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "Security_regressions.h"
+
+#define CFReleaseNull(CF) { CFTypeRef _cf = (CF); if (_cf) {  (CF) = NULL; CFRelease(_cf); } }
+
+
+static void testdigestandsignalg(SecKeyRef privKey, SecKeyRef pubKey, const SecAsn1AlgId *algId) {
+    uint8_t dataToDigest[256] = {0,};
+    size_t dataToDigestLen = sizeof(dataToDigest);
+    size_t sigLen = SecKeyGetSize(privKey, kSecKeySignatureSize);
+    uint8_t sig[sigLen];
+
+    DERItem oid;
+    oid.length = algId->algorithm.Length;
+    oid.data = algId->algorithm.Data;
+
+    /* Get the oid in decimal for display purposes. */
+    CFStringRef oidStr = SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault, &oid);
+       char oidBuf[40];
+    CFStringGetCString(oidStr, oidBuf, sizeof(oidBuf), kCFStringEncodingUTF8);
+    CFRelease(oidStr);
+
+SKIP: {
+    OSStatus status;
+
+    /* Time to sign. */
+    ok_status(status = SecKeyDigestAndSign(privKey, algId, dataToDigest, dataToDigestLen,
+                                           sig, &sigLen),
+              "digest and sign %s with %ld bit RSA key", oidBuf, sigLen * 8);
+
+    skip("SecKeyDigestAndSign failed", 3, status == errSecSuccess);
+
+    /* Verify the signature we just made. */
+    ok_status(SecKeyDigestAndVerify(pubKey, algId, dataToDigest, dataToDigestLen,
+                                    sig, sigLen), "digest and verify");
+    /* Invalidate the signature. */
+    sig[0] ^= 0xff;
+    is_status(SecKeyDigestAndVerify(pubKey, algId, dataToDigest, dataToDigestLen,
+                                    sig, sigLen), errSSLCrypto, "digest and verify bad sig");
+    sig[0] ^= 0xff;
+    dataToDigest[0] ^= 0xff;
+    is_status(SecKeyDigestAndVerify(pubKey, algId, dataToDigest, dataToDigestLen,
+                                    sig, sigLen), errSSLCrypto, "digest and verify bad digest");
+}
+}
+
+static void testdigestandsign(SecKeyRef privKey, SecKeyRef pubKey) {
+    static const SecAsn1Oid *oids[] = {
+        &CSSMOID_ECDSA_WithSHA1,
+#if 0
+        &CSSMOID_ECDSA_WithSHA224,
+        &CSSMOID_ECDSA_WithSHA256,
+        &CSSMOID_ECDSA_WithSHA384,
+        &CSSMOID_ECDSA_WithSHA512,
+#endif
+    };
+
+    uint32_t ix;
+    SecAsn1AlgId algId = {};
+    for (ix = 0; ix < array_size(oids); ++ix) {
+        if (oids[ix]) {
+            algId.algorithm = *oids[ix];
+        } else {
+            algId.algorithm.Length = 0;
+            algId.algorithm.Data = NULL;
+        }
+
+        testdigestandsignalg(privKey, pubKey, &algId);
+    }
+}
+
+static void testkeygen(size_t keySizeInBits) {
+       SecKeyRef pubKey = NULL, privKey = NULL;
+       size_t keySizeInBytes = (keySizeInBits + 7) / 8;
+       CFNumberRef kzib;
+    int32_t keysz32 = (int32_t)keySizeInBits;
+
+       kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
+       CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+       CFDictionaryAddValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeEC);
+       CFDictionaryAddValue(kgp, kSecAttrKeySizeInBits, kzib);
+
+       OSStatus status;
+       ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
+              "Generate %ld bit (%ld byte) EC keypair", keySizeInBits,
+              keySizeInBytes);
+       CFRelease(kzib);
+       CFRelease(kgp);
+
+SKIP: {
+    skip("keygen failed", 8, status == errSecSuccess);
+    ok(pubKey, "pubkey returned");
+    ok(privKey, "privKey returned");
+    is(SecKeyGetSize(pubKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "public key size is ok");
+    is(SecKeyGetSize(privKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "private key size is ok");
+
+    /* Sign something. */
+    uint8_t something[20] = {0x80, 0xbe, 0xef, 0xba, 0xd0, };
+    uint8_t sig[8+2*keySizeInBytes];
+    size_t sigLen = sizeof(sig);
+    ok_status(SecKeyRawSign(privKey, kSecPaddingNone,
+                            something, sizeof(something), sig, &sigLen), "sign something");
+    ok_status(SecKeyRawVerify(pubKey, kSecPaddingNone,
+                              something, sizeof(something), sig, sigLen), "verify sig on something");
+
+    testdigestandsign(privKey, pubKey);
+
+    const void *privkeys[] = {
+        kSecValueRef
+    };
+    const void *privvalues[] = {
+        privKey
+    };
+    CFDictionaryRef privitem = CFDictionaryCreate(NULL, privkeys, privvalues,
+                                                  array_size(privkeys), NULL, NULL);
+    ok_status(SecItemAdd(privitem, NULL), "add private key");
+    ok_status(SecItemDelete(privitem), "delete public key");
+    CFReleaseNull(privitem);
+
+    const void *pubkeys[] = {
+        kSecValueRef
+    };
+    const void *pubvalues[] = {
+        pubKey
+    };
+    CFDictionaryRef pubitem = CFDictionaryCreate(NULL, pubkeys, pubvalues,
+                                                 array_size(pubkeys), NULL, NULL);
+    ok_status(SecItemAdd(pubitem, NULL), "add public key");
+    ok_status(SecItemDelete(pubitem), "delete public key");
+    CFReleaseNull(pubitem);
+
+    /* Cleanup. */
+    CFReleaseNull(pubKey);
+    CFReleaseNull(privKey);
+}
+}
+
+
+static void testkeygen2(size_t keySizeInBits) {
+       SecKeyRef pubKey = NULL, privKey = NULL;
+       size_t keySizeInBytes = (keySizeInBits + 7) / 8;
+       CFNumberRef kzib;
+    int32_t keysz32 = (int32_t)keySizeInBits;
+
+    CFUUIDRef ourUUID = CFUUIDCreate(kCFAllocatorDefault);
+    CFStringRef uuidString = CFUUIDCreateString(kCFAllocatorDefault, ourUUID);
+    CFMutableStringRef publicName = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, uuidString);
+    CFMutableStringRef privateName = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, uuidString);
+
+    CFReleaseNull(ourUUID);
+    CFReleaseNull(uuidString);
+
+    CFStringAppend(publicName, CFSTR("-Public-41"));
+    CFStringAppend(privateName, CFSTR("-Private-41"));
+
+       CFMutableDictionaryRef pubd = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+       CFMutableDictionaryRef privd = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+       CFDictionaryAddValue(pubd, kSecAttrLabel, publicName);
+       CFDictionaryAddValue(privd, kSecAttrLabel, privateName);
+
+       kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
+       CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+       CFDictionaryAddValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeEC);
+       CFDictionaryAddValue(kgp, kSecAttrKeySizeInBits, kzib);
+       CFDictionaryAddValue(kgp, kSecAttrIsPermanent, kCFBooleanTrue);
+       CFDictionaryAddValue(kgp, kSecPublicKeyAttrs, pubd);
+       CFDictionaryAddValue(kgp, kSecPrivateKeyAttrs, privd);
+
+       OSStatus status;
+       ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
+              "Generate %ld bit (%ld byte) persistent RSA keypair",
+              keySizeInBits, keySizeInBytes);
+       CFRelease(kzib);
+       CFRelease(kgp);
+
+SKIP: {
+    skip("keygen failed", 8, status == errSecSuccess);
+    ok(pubKey, "pubkey returned");
+    ok(privKey, "privKey returned");
+    is(SecKeyGetSize(pubKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "public key size is ok");
+    is(SecKeyGetSize(privKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "private key size is ok");
+
+    SecKeyRef pubKey2, privKey2;
+    CFDictionaryAddValue(pubd, kSecClass, kSecClassKey);
+    CFDictionaryAddValue(pubd, kSecReturnRef, kCFBooleanTrue);
+    CFDictionaryAddValue(privd, kSecClass, kSecClassKey);
+    CFDictionaryAddValue(privd, kSecReturnRef, kCFBooleanTrue);
+    CFDictionaryAddValue(privd, kSecAttrCanSign, kCFBooleanTrue);
+    ok_status(SecItemCopyMatching(pubd, (CFTypeRef *)&pubKey2),
+              "retrieve pub key by label");
+    ok(pubKey2, "got valid object");
+    ok_status(SecItemCopyMatching(privd, (CFTypeRef *)&privKey2),
+              "retrieve priv key by label and kSecAttrCanSign");
+    ok(privKey2, "got valid object");
+
+    /* Sign something. */
+    uint8_t something[20] = {0x80, 0xbe, 0xef, 0xba, 0xd0, };
+    size_t sigLen = SecKeyGetSize(privKey2, kSecKeySignatureSize);
+    uint8_t sig[sigLen];
+    ok_status(SecKeyRawSign(privKey2, kSecPaddingPKCS1,
+                            something, sizeof(something), sig, &sigLen), "sign something");
+    ok_status(SecKeyRawVerify(pubKey2, kSecPaddingPKCS1,
+                              something, sizeof(something), sig, sigLen), "verify sig on something");
+
+    /* Cleanup. */
+    CFReleaseNull(pubKey2);
+    CFReleaseNull(privKey2);
+}
+
+    /* delete from keychain - note: do it before releasing publicName and privateName
+       because pubd and privd have no retain/release callbacks */
+    ok_status(SecItemDelete(pubd), "delete generated pub key");
+    ok_status(SecItemDelete(privd), "delete generated priv key");
+
+       /* Cleanup. */
+       CFReleaseNull(pubKey);
+       CFReleaseNull(privKey);
+
+    CFReleaseNull(publicName);
+    CFReleaseNull(privateName);
+
+       CFRelease(pubd);
+       CFRelease(privd);
+}
+
+
+/* Test basic add delete update copy matching stuff. */
+static void tests(void)
+{
+       testkeygen(192);
+       testkeygen(224);
+       testkeygen(256);
+       testkeygen(384);
+       testkeygen(521);
+
+    testkeygen2(192);
+    testkeygen2(224);
+       testkeygen2(256);
+       testkeygen2(384);
+       testkeygen2(521);
+
+}
+
+int si_41_sececkey(int argc, char *const *argv)
+{
+       plan_tests(140);
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-42-identity.c b/sec/Security/Regressions/secitem/si-42-identity.c
new file mode 100644 (file)
index 0000000..1841e8d
--- /dev/null
@@ -0,0 +1,748 @@
+/*
+ *  si-42-secidentity.c
+ *  Security
+ *
+ *  Created by Michael Brouwer on 1/29/07.
+ *  Copyright (c) 2007-2010 Apple Inc. All Rights Reserved.
+ *
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecCertificateInternal.h>
+#include <Security/SecKey.h>
+#include <Security/SecRSAKey.h>
+#include <Security/SecItem.h>
+#include <Security/SecItemPriv.h>
+#include <Security/SecIdentityPriv.h>
+#include <Security/SecIdentity.h>
+#include <utilities/array_size.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "Security_regressions.h"
+
+#define CFReleaseNull(CF) { CFTypeRef _cf = (CF); if (_cf) {  (CF) = NULL; CFRelease(_cf); } }
+
+static const uint8_t _c0[] = {
+    0x30, 0x82, 0x04, 0xbb, 0x30, 0x82, 0x03, 0xa3,
+    0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x02,
+    0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+    0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
+    0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+    0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
+    0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+    0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49,
+    0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06,
+    0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70,
+    0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74,
+    0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+    0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+    0x69, 0x74, 0x79, 0x31, 0x16, 0x30, 0x14, 0x06,
+    0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x41, 0x70,
+    0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74,
+    0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x30,
+    0x36, 0x30, 0x34, 0x32, 0x35, 0x32, 0x31, 0x34,
+    0x30, 0x33, 0x36, 0x5a, 0x17, 0x0d, 0x33, 0x35,
+    0x30, 0x32, 0x30, 0x39, 0x32, 0x31, 0x34, 0x30,
+    0x33, 0x36, 0x5a, 0x30, 0x62, 0x31, 0x0b, 0x30,
+    0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+    0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
+    0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70,
+    0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
+    0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b,
+    0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20,
+    0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+    0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
+    0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31,
+    0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03,
+    0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20,
+    0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30,
+    0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+    0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
+    0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30,
+    0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00,
+    0xe4, 0x91, 0xa9, 0x09, 0x1f, 0x91, 0xdb, 0x1e,
+    0x47, 0x50, 0xeb, 0x05, 0xed, 0x5e, 0x79, 0x84,
+    0x2d, 0xeb, 0x36, 0xa2, 0x57, 0x4c, 0x55, 0xec,
+    0x8b, 0x19, 0x89, 0xde, 0xf9, 0x4b, 0x6c, 0xf5,
+    0x07, 0xab, 0x22, 0x30, 0x02, 0xe8, 0x18, 0x3e,
+    0xf8, 0x50, 0x09, 0xd3, 0x7f, 0x41, 0xa8, 0x98,
+    0xf9, 0xd1, 0xca, 0x66, 0x9c, 0x24, 0x6b, 0x11,
+    0xd0, 0xa3, 0xbb, 0xe4, 0x1b, 0x2a, 0xc3, 0x1f,
+    0x95, 0x9e, 0x7a, 0x0c, 0xa4, 0x47, 0x8b, 0x5b,
+    0xd4, 0x16, 0x37, 0x33, 0xcb, 0xc4, 0x0f, 0x4d,
+    0xce, 0x14, 0x69, 0xd1, 0xc9, 0x19, 0x72, 0xf5,
+    0x5d, 0x0e, 0xd5, 0x7f, 0x5f, 0x9b, 0xf2, 0x25,
+    0x03, 0xba, 0x55, 0x8f, 0x4d, 0x5d, 0x0d, 0xf1,
+    0x64, 0x35, 0x23, 0x15, 0x4b, 0x15, 0x59, 0x1d,
+    0xb3, 0x94, 0xf7, 0xf6, 0x9c, 0x9e, 0xcf, 0x50,
+    0xba, 0xc1, 0x58, 0x50, 0x67, 0x8f, 0x08, 0xb4,
+    0x20, 0xf7, 0xcb, 0xac, 0x2c, 0x20, 0x6f, 0x70,
+    0xb6, 0x3f, 0x01, 0x30, 0x8c, 0xb7, 0x43, 0xcf,
+    0x0f, 0x9d, 0x3d, 0xf3, 0x2b, 0x49, 0x28, 0x1a,
+    0xc8, 0xfe, 0xce, 0xb5, 0xb9, 0x0e, 0xd9, 0x5e,
+    0x1c, 0xd6, 0xcb, 0x3d, 0xb5, 0x3a, 0xad, 0xf4,
+    0x0f, 0x0e, 0x00, 0x92, 0x0b, 0xb1, 0x21, 0x16,
+    0x2e, 0x74, 0xd5, 0x3c, 0x0d, 0xdb, 0x62, 0x16,
+    0xab, 0xa3, 0x71, 0x92, 0x47, 0x53, 0x55, 0xc1,
+    0xaf, 0x2f, 0x41, 0xb3, 0xf8, 0xfb, 0xe3, 0x70,
+    0xcd, 0xe6, 0xa3, 0x4c, 0x45, 0x7e, 0x1f, 0x4c,
+    0x6b, 0x50, 0x96, 0x41, 0x89, 0xc4, 0x74, 0x62,
+    0x0b, 0x10, 0x83, 0x41, 0x87, 0x33, 0x8a, 0x81,
+    0xb1, 0x30, 0x58, 0xec, 0x5a, 0x04, 0x32, 0x8c,
+    0x68, 0xb3, 0x8f, 0x1d, 0xde, 0x65, 0x73, 0xff,
+    0x67, 0x5e, 0x65, 0xbc, 0x49, 0xd8, 0x76, 0x9f,
+    0x33, 0x14, 0x65, 0xa1, 0x77, 0x94, 0xc9, 0x2d,
+    0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01,
+    0x7a, 0x30, 0x82, 0x01, 0x76, 0x30, 0x0e, 0x06,
+    0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04,
+    0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0f, 0x06,
+    0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04,
+    0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d,
+    0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
+    0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76, 0x09,
+    0xfe, 0xf4, 0x6b, 0x8d, 0x2e, 0x40, 0xa6, 0xf7,
+    0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x1f, 0x06,
+    0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
+    0x80, 0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76,
+    0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e, 0x40, 0xa6,
+    0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x82,
+    0x01, 0x11, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04,
+    0x82, 0x01, 0x08, 0x30, 0x82, 0x01, 0x04, 0x30,
+    0x82, 0x01, 0x00, 0x06, 0x09, 0x2a, 0x86, 0x48,
+    0x86, 0xf7, 0x63, 0x64, 0x05, 0x01, 0x30, 0x81,
+    0xf2, 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01,
+    0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1e, 0x68,
+    0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77,
+    0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65,
+    0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x70,
+    0x6c, 0x65, 0x63, 0x61, 0x2f, 0x30, 0x81, 0xc3,
+    0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+    0x02, 0x02, 0x30, 0x81, 0xb6, 0x1a, 0x81, 0xb3,
+    0x52, 0x65, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65,
+    0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73,
+    0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+    0x63, 0x61, 0x74, 0x65, 0x20, 0x62, 0x79, 0x20,
+    0x61, 0x6e, 0x79, 0x20, 0x70, 0x61, 0x72, 0x74,
+    0x79, 0x20, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65,
+    0x73, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74,
+    0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20,
+    0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e,
+    0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61,
+    0x62, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e,
+    0x64, 0x61, 0x72, 0x64, 0x20, 0x74, 0x65, 0x72,
+    0x6d, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63,
+    0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e,
+    0x73, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65,
+    0x2c, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66,
+    0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x70, 0x6f,
+    0x6c, 0x69, 0x63, 0x79, 0x20, 0x61, 0x6e, 0x64,
+    0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+    0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70,
+    0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x20,
+    0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
+    0x74, 0x73, 0x2e, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+    0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
+    0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x5c,
+    0x36, 0x99, 0x4c, 0x2d, 0x78, 0xb7, 0xed, 0x8c,
+    0x9b, 0xdc, 0xf3, 0x77, 0x9b, 0xf2, 0x76, 0xd2,
+    0x77, 0x30, 0x4f, 0xc1, 0x1f, 0x85, 0x83, 0x85,
+    0x1b, 0x99, 0x3d, 0x47, 0x37, 0xf2, 0xa9, 0x9b,
+    0x40, 0x8e, 0x2c, 0xd4, 0xb1, 0x90, 0x12, 0xd8,
+    0xbe, 0xf4, 0x73, 0x9b, 0xee, 0xd2, 0x64, 0x0f,
+    0xcb, 0x79, 0x4f, 0x34, 0xd8, 0xa2, 0x3e, 0xf9,
+    0x78, 0xff, 0x6b, 0xc8, 0x07, 0xec, 0x7d, 0x39,
+    0x83, 0x8b, 0x53, 0x20, 0xd3, 0x38, 0xc4, 0xb1,
+    0xbf, 0x9a, 0x4f, 0x0a, 0x6b, 0xff, 0x2b, 0xfc,
+    0x59, 0xa7, 0x05, 0x09, 0x7c, 0x17, 0x40, 0x56,
+    0x11, 0x1e, 0x74, 0xd3, 0xb7, 0x8b, 0x23, 0x3b,
+    0x47, 0xa3, 0xd5, 0x6f, 0x24, 0xe2, 0xeb, 0xd1,
+    0xb7, 0x70, 0xdf, 0x0f, 0x45, 0xe1, 0x27, 0xca,
+    0xf1, 0x6d, 0x78, 0xed, 0xe7, 0xb5, 0x17, 0x17,
+    0xa8, 0xdc, 0x7e, 0x22, 0x35, 0xca, 0x25, 0xd5,
+    0xd9, 0x0f, 0xd6, 0x6b, 0xd4, 0xa2, 0x24, 0x23,
+    0x11, 0xf7, 0xa1, 0xac, 0x8f, 0x73, 0x81, 0x60,
+    0xc6, 0x1b, 0x5b, 0x09, 0x2f, 0x92, 0xb2, 0xf8,
+    0x44, 0x48, 0xf0, 0x60, 0x38, 0x9e, 0x15, 0xf5,
+    0x3d, 0x26, 0x67, 0x20, 0x8a, 0x33, 0x6a, 0xf7,
+    0x0d, 0x82, 0xcf, 0xde, 0xeb, 0xa3, 0x2f, 0xf9,
+    0x53, 0x6a, 0x5b, 0x64, 0xc0, 0x63, 0x33, 0x77,
+    0xf7, 0x3a, 0x07, 0x2c, 0x56, 0xeb, 0xda, 0x0f,
+    0x21, 0x0e, 0xda, 0xba, 0x73, 0x19, 0x4f, 0xb5,
+    0xd9, 0x36, 0x7f, 0xc1, 0x87, 0x55, 0xd9, 0xa7,
+    0x99, 0xb9, 0x32, 0x42, 0xfb, 0xd8, 0xd5, 0x71,
+    0x9e, 0x7e, 0xa1, 0x52, 0xb7, 0x1b, 0xbd, 0x93,
+    0x42, 0x24, 0x12, 0x2a, 0xc7, 0x0f, 0x1d, 0xb6,
+    0x4d, 0x9c, 0x5e, 0x63, 0xc8, 0x4b, 0x80, 0x17,
+    0x50, 0xaa, 0x8a, 0xd5, 0xda, 0xe4, 0xfc, 0xd0,
+    0x09, 0x07, 0x37, 0xb0, 0x75, 0x75, 0x21,
+};
+
+
+/*
+   Bag Attributes
+friendlyName: uranusLeaf
+localKeyID: 46 E0 8A 05 63 4D 17 3F CA A4 AA B6 5A DA CF BA 84 22 7C 23
+subject=/CN=uranusLeaf/emailAddress=uranus@uranus.com
+issuer=/CN=plutoCA/emailAddress=pluto@pluto.com
+ */
+static const uint8_t _c1[] = {
+    0x30, 0x82, 0x02, 0xe0, 0x30, 0x82, 0x01, 0xc8,
+    0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x02,
+    0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+    0xf7, 0x0d, 0x01, 0x01, 0x05, 0x30, 0x32, 0x31,
+    0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03,
+    0x0c, 0x07, 0x70, 0x6c, 0x75, 0x74, 0x6f, 0x43,
+    0x41, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x09, 0x2a,
+    0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01,
+    0x0c, 0x0f, 0x70, 0x6c, 0x75, 0x74, 0x6f, 0x40,
+    0x70, 0x6c, 0x75, 0x74, 0x6f, 0x2e, 0x63, 0x6f,
+    0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x35, 0x31,
+    0x32, 0x31, 0x37, 0x30, 0x30, 0x30, 0x34, 0x32,
+    0x35, 0x5a, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x32,
+    0x31, 0x37, 0x30, 0x30, 0x30, 0x34, 0x32, 0x35,
+    0x5a, 0x30, 0x37, 0x31, 0x13, 0x30, 0x11, 0x06,
+    0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x75, 0x72,
+    0x61, 0x6e, 0x75, 0x73, 0x4c, 0x65, 0x61, 0x66,
+    0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86,
+    0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x0c,
+    0x11, 0x75, 0x72, 0x61, 0x6e, 0x75, 0x73, 0x40,
+    0x75, 0x72, 0x61, 0x6e, 0x75, 0x73, 0x2e, 0x63,
+    0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
+    0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+    0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
+    0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82,
+    0x01, 0x01, 0x00, 0xa6, 0x82, 0x8e, 0xc6, 0x7e,
+    0xc9, 0x8c, 0x99, 0x6f, 0xb0, 0x62, 0x32, 0x35,
+    0xe7, 0xdb, 0xff, 0x34, 0x84, 0xdc, 0x72, 0xa8,
+    0xef, 0x22, 0x6f, 0x93, 0x63, 0x64, 0x80, 0x80,
+    0x5d, 0x50, 0x7e, 0xb4, 0x2e, 0x1b, 0x93, 0x93,
+    0x49, 0xca, 0xae, 0xcd, 0x34, 0x44, 0x4b, 0xd7,
+    0xfa, 0x9f, 0x3c, 0xfc, 0x9e, 0x65, 0xa9, 0xfb,
+    0x5e, 0x5d, 0x18, 0xa3, 0xf8, 0xb0, 0x08, 0xac,
+    0x8f, 0xfd, 0x03, 0xcb, 0xbd, 0x7f, 0xa0, 0x2a,
+    0xa6, 0xea, 0xca, 0xa3, 0x24, 0xef, 0x7c, 0xc3,
+    0xeb, 0x95, 0xcb, 0x90, 0x3f, 0x5e, 0xde, 0x78,
+    0xf2, 0x3d, 0x32, 0x72, 0xdb, 0x33, 0x6e, 0x9b,
+    0x52, 0x9f, 0x0c, 0x60, 0x4a, 0x24, 0xa1, 0xf6,
+    0x3b, 0x80, 0xbd, 0xa1, 0xdc, 0x40, 0x03, 0xe7,
+    0xa0, 0x59, 0x1f, 0xdb, 0xb4, 0xed, 0x57, 0xdc,
+    0x74, 0x0d, 0x99, 0x5a, 0x12, 0x74, 0x64, 0xaa,
+    0xb6, 0xa5, 0x96, 0x75, 0xf9, 0x42, 0x43, 0xe2,
+    0x52, 0xc2, 0x57, 0x23, 0x75, 0xd7, 0xa9, 0x4f,
+    0x07, 0x32, 0x99, 0xbd, 0x3d, 0x44, 0xbd, 0x04,
+    0x62, 0xe5, 0xb7, 0x2c, 0x0c, 0x11, 0xc5, 0xb2,
+    0x2e, 0xc4, 0x12, 0x1d, 0x7f, 0x42, 0x1e, 0x71,
+    0xaf, 0x39, 0x2b, 0x78, 0x47, 0x92, 0x23, 0x44,
+    0xef, 0xe3, 0xc1, 0x47, 0x69, 0x5a, 0xf1, 0x48,
+    0xaa, 0x37, 0xa4, 0x94, 0x6b, 0x96, 0xe5, 0x4b,
+    0xfd, 0x05, 0xc7, 0x9c, 0xcc, 0x38, 0xd1, 0x47,
+    0x85, 0x60, 0x7f, 0xef, 0xe9, 0x2e, 0x25, 0x08,
+    0xf8, 0x7d, 0x98, 0xdd, 0x6c, 0xeb, 0x4a, 0x32,
+    0x33, 0x44, 0x0b, 0x61, 0xb3, 0xf9, 0xae, 0x26,
+    0x41, 0xb5, 0x38, 0xdb, 0xcf, 0x13, 0x72, 0x23,
+    0x5b, 0x66, 0x20, 0x86, 0x4d, 0x24, 0xc2, 0xd4,
+    0x94, 0xde, 0xe3, 0x24, 0xb7, 0xcd, 0x75, 0x9e,
+    0x1d, 0x9f, 0xbc, 0xd0, 0x60, 0x34, 0x7d, 0xf8,
+    0xcb, 0x41, 0x39, 0x02, 0x03, 0x01, 0x00, 0x01,
+    0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+    0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,
+    0x82, 0x01, 0x01, 0x00, 0x17, 0xa5, 0x22, 0xed,
+    0xb8, 0x3e, 0x1f, 0x11, 0x99, 0xc5, 0xba, 0x28,
+    0x3e, 0x7e, 0xa6, 0xeb, 0x02, 0x81, 0x06, 0xa1,
+    0xc6, 0x80, 0xb9, 0x7e, 0x5c, 0x5a, 0x63, 0xe0,
+    0x8d, 0xeb, 0xd0, 0xec, 0x9c, 0x3a, 0x94, 0x64,
+    0x7c, 0x13, 0x54, 0x0d, 0xd6, 0xe3, 0x27, 0x88,
+    0xa6, 0xd2, 0x4b, 0x36, 0xdd, 0x2e, 0xfa, 0x94,
+    0xe5, 0x03, 0x27, 0xc9, 0xa6, 0x31, 0x02, 0xea,
+    0x40, 0x77, 0x2e, 0x93, 0xc4, 0x4d, 0xe2, 0x70,
+    0xe2, 0x67, 0x1c, 0xa8, 0x0d, 0xcd, 0x1a, 0x72,
+    0x86, 0x2c, 0xea, 0xdc, 0x7f, 0x8c, 0x49, 0x2c,
+    0xe7, 0x99, 0x13, 0xda, 0x3f, 0x58, 0x9e, 0xf5,
+    0x4d, 0x3c, 0x8c, 0x1c, 0xed, 0x85, 0xa7, 0xe2,
+    0xae, 0xda, 0x5f, 0xbe, 0x36, 0x1c, 0x9f, 0x5a,
+    0xa0, 0xdc, 0x2a, 0xc0, 0xee, 0x71, 0x07, 0x26,
+    0x8b, 0xe8, 0x8a, 0xf8, 0x2d, 0x36, 0x78, 0xc9,
+    0x79, 0xfa, 0xbe, 0x98, 0x59, 0x95, 0x12, 0x24,
+    0xf1, 0xda, 0x20, 0xc7, 0x78, 0xf9, 0x7c, 0x6a,
+    0x24, 0x43, 0x82, 0xa8, 0x0f, 0xb1, 0x7d, 0x94,
+    0xaa, 0x30, 0x35, 0xe5, 0x69, 0xdc, 0x0a, 0x0e,
+    0xaf, 0x10, 0x5e, 0x1a, 0x81, 0x50, 0x5c, 0x7e,
+    0x24, 0xb3, 0x07, 0x65, 0x4b, 0xc1, 0x7e, 0xc6,
+    0x38, 0xdb, 0xd3, 0x6a, 0xf0, 0xd8, 0x85, 0x61,
+    0x9a, 0x9f, 0xfe, 0x02, 0x46, 0x29, 0xb2, 0x9a,
+    0xe2, 0x04, 0xe7, 0x72, 0xcc, 0x87, 0x46, 0xba,
+    0x7d, 0xa8, 0xf9, 0xd0, 0x0f, 0x29, 0xfc, 0xfd,
+    0xd1, 0xd0, 0x7f, 0x36, 0xc1, 0xd8, 0x7d, 0x88,
+    0x03, 0x62, 0xf5, 0x8c, 0x00, 0xb5, 0xc2, 0x81,
+    0x44, 0x67, 0x58, 0x11, 0xb4, 0x3a, 0xbb, 0xd1,
+    0x8c, 0x94, 0x20, 0x60, 0xea, 0xa0, 0xac, 0xc1,
+    0xf1, 0x08, 0x54, 0xb8, 0xf6, 0x5e, 0xac, 0xf1,
+    0xec, 0x78, 0x69, 0x9d, 0x7e, 0x4d, 0x06, 0x3b,
+    0x9b, 0x78, 0x78, 0x10
+};
+
+/*
+   Bag Attributes
+friendlyName: uranusLeaf
+localKeyID: 46 E0 8A 05 63 4D 17 3F CA A4 AA B6 5A DA CF BA 84 22 7C 23
+Key Attributes: <No Attributes>
+ */
+static const uint8_t _k1[] = {
+    0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02,
+    0x82, 0x01, 0x01, 0x00, 0xa6, 0x82, 0x8e, 0xc6,
+    0x7e, 0xc9, 0x8c, 0x99, 0x6f, 0xb0, 0x62, 0x32,
+    0x35, 0xe7, 0xdb, 0xff, 0x34, 0x84, 0xdc, 0x72,
+    0xa8, 0xef, 0x22, 0x6f, 0x93, 0x63, 0x64, 0x80,
+    0x80, 0x5d, 0x50, 0x7e, 0xb4, 0x2e, 0x1b, 0x93,
+    0x93, 0x49, 0xca, 0xae, 0xcd, 0x34, 0x44, 0x4b,
+    0xd7, 0xfa, 0x9f, 0x3c, 0xfc, 0x9e, 0x65, 0xa9,
+    0xfb, 0x5e, 0x5d, 0x18, 0xa3, 0xf8, 0xb0, 0x08,
+    0xac, 0x8f, 0xfd, 0x03, 0xcb, 0xbd, 0x7f, 0xa0,
+    0x2a, 0xa6, 0xea, 0xca, 0xa3, 0x24, 0xef, 0x7c,
+    0xc3, 0xeb, 0x95, 0xcb, 0x90, 0x3f, 0x5e, 0xde,
+    0x78, 0xf2, 0x3d, 0x32, 0x72, 0xdb, 0x33, 0x6e,
+    0x9b, 0x52, 0x9f, 0x0c, 0x60, 0x4a, 0x24, 0xa1,
+    0xf6, 0x3b, 0x80, 0xbd, 0xa1, 0xdc, 0x40, 0x03,
+    0xe7, 0xa0, 0x59, 0x1f, 0xdb, 0xb4, 0xed, 0x57,
+    0xdc, 0x74, 0x0d, 0x99, 0x5a, 0x12, 0x74, 0x64,
+    0xaa, 0xb6, 0xa5, 0x96, 0x75, 0xf9, 0x42, 0x43,
+    0xe2, 0x52, 0xc2, 0x57, 0x23, 0x75, 0xd7, 0xa9,
+    0x4f, 0x07, 0x32, 0x99, 0xbd, 0x3d, 0x44, 0xbd,
+    0x04, 0x62, 0xe5, 0xb7, 0x2c, 0x0c, 0x11, 0xc5,
+    0xb2, 0x2e, 0xc4, 0x12, 0x1d, 0x7f, 0x42, 0x1e,
+    0x71, 0xaf, 0x39, 0x2b, 0x78, 0x47, 0x92, 0x23,
+    0x44, 0xef, 0xe3, 0xc1, 0x47, 0x69, 0x5a, 0xf1,
+    0x48, 0xaa, 0x37, 0xa4, 0x94, 0x6b, 0x96, 0xe5,
+    0x4b, 0xfd, 0x05, 0xc7, 0x9c, 0xcc, 0x38, 0xd1,
+    0x47, 0x85, 0x60, 0x7f, 0xef, 0xe9, 0x2e, 0x25,
+    0x08, 0xf8, 0x7d, 0x98, 0xdd, 0x6c, 0xeb, 0x4a,
+    0x32, 0x33, 0x44, 0x0b, 0x61, 0xb3, 0xf9, 0xae,
+    0x26, 0x41, 0xb5, 0x38, 0xdb, 0xcf, 0x13, 0x72,
+    0x23, 0x5b, 0x66, 0x20, 0x86, 0x4d, 0x24, 0xc2,
+    0xd4, 0x94, 0xde, 0xe3, 0x24, 0xb7, 0xcd, 0x75,
+    0x9e, 0x1d, 0x9f, 0xbc, 0xd0, 0x60, 0x34, 0x7d,
+    0xf8, 0xcb, 0x41, 0x39, 0x02, 0x03, 0x01, 0x00,
+    0x01, 0x02, 0x82, 0x01, 0x00, 0x4d, 0x27, 0xf2,
+    0x40, 0xc8, 0x3f, 0x5c, 0x87, 0x3c, 0xd9, 0xde,
+    0xa6, 0xa5, 0x93, 0xea, 0xbd, 0x36, 0xf8, 0xd9,
+    0xad, 0xc7, 0xda, 0x07, 0x7a, 0xec, 0x31, 0x02,
+    0x41, 0x09, 0x3a, 0x34, 0x32, 0x82, 0x0b, 0x5b,
+    0x7b, 0xe6, 0xa4, 0x2a, 0xe7, 0x14, 0xef, 0x43,
+    0x36, 0x61, 0xbe, 0x20, 0x4b, 0x82, 0x43, 0x63,
+    0x98, 0x80, 0x82, 0x19, 0x61, 0x71, 0x99, 0xaa,
+    0xf8, 0x59, 0xfd, 0xde, 0xa0, 0x03, 0xa8, 0xab,
+    0x9a, 0xec, 0x28, 0xac, 0x63, 0x79, 0x75, 0x84,
+    0x03, 0xac, 0x45, 0x5e, 0x04, 0x15, 0xb3, 0x47,
+    0xa2, 0x8f, 0x28, 0xb0, 0x72, 0xd0, 0x06, 0x02,
+    0xaf, 0x1e, 0x0a, 0x0a, 0xe9, 0x11, 0x35, 0x4a,
+    0x04, 0x42, 0xb5, 0x0f, 0xd2, 0xcf, 0x4d, 0xdf,
+    0xdb, 0xef, 0x58, 0xbd, 0xf3, 0xa5, 0x3b, 0x11,
+    0x3f, 0xc5, 0x47, 0x81, 0x85, 0xad, 0xd7, 0x1f,
+    0x58, 0x06, 0x42, 0xdc, 0x37, 0x3c, 0xdb, 0x98,
+    0x33, 0xa1, 0xc6, 0x80, 0x07, 0xe0, 0x2b, 0xc5,
+    0xf5, 0x60, 0x35, 0x6a, 0xa2, 0x06, 0x40, 0x4a,
+    0xac, 0x64, 0x02, 0x58, 0x4d, 0x07, 0xe3, 0x69,
+    0xd7, 0xe0, 0x8f, 0xb5, 0xf4, 0xbc, 0xfa, 0xab,
+    0x1a, 0xb0, 0xfa, 0x29, 0xf8, 0xca, 0xde, 0x78,
+    0xf0, 0x89, 0xe2, 0xf9, 0xb7, 0x68, 0x5b, 0x0e,
+    0xdc, 0x4e, 0x8a, 0x56, 0x8d, 0x33, 0x20, 0x2e,
+    0xed, 0x2e, 0xab, 0x6f, 0xba, 0x77, 0xef, 0xe6,
+    0x12, 0x62, 0x49, 0x9e, 0x87, 0x76, 0x1c, 0x1e,
+    0xf4, 0x0e, 0x9e, 0x78, 0x98, 0x91, 0x1a, 0xe3,
+    0xb4, 0x51, 0x4b, 0x8c, 0x2f, 0x08, 0x97, 0x8f,
+    0xf9, 0x68, 0x61, 0x40, 0xcd, 0xb6, 0x10, 0xb4,
+    0xfb, 0x75, 0xb4, 0x20, 0xc1, 0x5a, 0xda, 0x64,
+    0xfd, 0x51, 0x06, 0x85, 0x9a, 0x9e, 0x5d, 0x82,
+    0x14, 0xd4, 0x41, 0x4e, 0x75, 0x10, 0xb5, 0x7b,
+    0xd0, 0x4c, 0xd1, 0x00, 0x01, 0x02, 0x81, 0x81,
+    0x00, 0xcf, 0x8e, 0x68, 0x04, 0x67, 0x09, 0xa9,
+    0x6e, 0xff, 0x11, 0x8c, 0xe5, 0xe4, 0x16, 0xdd,
+    0xb6, 0xa6, 0x55, 0xca, 0x4b, 0x0b, 0xbb, 0xb7,
+    0xf5, 0xe5, 0x73, 0xf3, 0x24, 0x84, 0x29, 0xb2,
+    0xc3, 0xbc, 0x7f, 0x2b, 0x4a, 0xc7, 0xdf, 0x46,
+    0x8e, 0xe1, 0x35, 0x69, 0x1b, 0x8e, 0x9f, 0x6b,
+    0x4d, 0xf3, 0x65, 0xae, 0x3d, 0x87, 0x2b, 0xc9,
+    0xf0, 0x8c, 0xf2, 0x88, 0x2f, 0x1b, 0x79, 0x80,
+    0xd2, 0xb2, 0x64, 0x0a, 0xcc, 0x66, 0x69, 0x4c,
+    0xa1, 0x85, 0xc4, 0x6a, 0x94, 0x46, 0x70, 0x69,
+    0xbc, 0x8c, 0x1c, 0x62, 0x65, 0x4d, 0x68, 0xcc,
+    0xe3, 0x3c, 0x6c, 0xe7, 0xd1, 0x09, 0xed, 0xdd,
+    0x42, 0x10, 0x11, 0x6b, 0xdd, 0x7c, 0xe3, 0xe1,
+    0x3b, 0x3b, 0x0d, 0x01, 0x6d, 0xca, 0x2f, 0x4b,
+    0x45, 0x5e, 0x76, 0x5d, 0x5c, 0x6f, 0x53, 0xa4,
+    0x38, 0x74, 0x75, 0x94, 0x2c, 0xda, 0xf8, 0xa6,
+    0x01, 0x02, 0x81, 0x81, 0x00, 0xcd, 0x5f, 0x9d,
+    0x6c, 0x94, 0xf6, 0x44, 0x37, 0x72, 0xfe, 0xcf,
+    0xbe, 0x82, 0x96, 0x24, 0x22, 0x12, 0x07, 0x6f,
+    0xd1, 0x57, 0x7b, 0xc7, 0x63, 0x20, 0xf5, 0x93,
+    0x79, 0x70, 0x0b, 0xe4, 0x38, 0x19, 0x62, 0x7b,
+    0x89, 0x3e, 0x45, 0xdf, 0xd6, 0xae, 0x9d, 0x0d,
+    0xa8, 0x76, 0xc1, 0xbd, 0x04, 0x2b, 0xaa, 0x30,
+    0x6a, 0xac, 0x65, 0x91, 0x61, 0xf0, 0xf8, 0x5d,
+    0xa3, 0x53, 0xa4, 0xfb, 0x99, 0xac, 0x46, 0x7a,
+    0x12, 0x4b, 0xf7, 0xa7, 0x48, 0x41, 0x61, 0x48,
+    0x26, 0x5c, 0x68, 0x2f, 0x73, 0x91, 0xe4, 0x74,
+    0xcd, 0xc9, 0x8b, 0xe7, 0x26, 0xe4, 0x35, 0xde,
+    0x32, 0x6b, 0x24, 0x49, 0xf2, 0x04, 0x67, 0x3d,
+    0x31, 0x8f, 0x22, 0xe5, 0x49, 0xae, 0x49, 0x94,
+    0xb3, 0x45, 0x2b, 0xed, 0x6f, 0x9c, 0xc7, 0x80,
+    0xf0, 0x42, 0xd5, 0x8f, 0x27, 0xd6, 0xd6, 0x49,
+    0xf2, 0x16, 0xcc, 0x4b, 0x39, 0x02, 0x81, 0x81,
+    0x00, 0xbb, 0xb7, 0xd7, 0x59, 0xcb, 0xfb, 0x10,
+    0x13, 0xc4, 0x7b, 0x92, 0x0c, 0x45, 0xcb, 0x6c,
+    0x81, 0x0a, 0x55, 0x63, 0x1d, 0x96, 0xa2, 0x13,
+    0xd2, 0x40, 0xd1, 0x2a, 0xa1, 0xe7, 0x2a, 0x73,
+    0x74, 0xd6, 0x61, 0xc9, 0xbc, 0xdb, 0xa2, 0x93,
+    0x85, 0x1c, 0x28, 0x9b, 0x44, 0x82, 0x2c, 0xaa,
+    0xf7, 0x18, 0x60, 0xe9, 0x42, 0xda, 0xa2, 0xff,
+    0x04, 0x21, 0xe6, 0x24, 0xc7, 0x3e, 0x39, 0x19,
+    0x0a, 0xf6, 0xae, 0xc6, 0x99, 0x71, 0x32, 0x61,
+    0x4d, 0x60, 0xd7, 0x71, 0x71, 0x63, 0x77, 0xbe,
+    0x19, 0xfa, 0x3a, 0x9d, 0xbf, 0x73, 0x50, 0x8a,
+    0xa6, 0x26, 0x7b, 0x74, 0xfa, 0x39, 0xd9, 0xb9,
+    0x18, 0x4b, 0xc2, 0x05, 0xe5, 0x8f, 0x53, 0xe6,
+    0xdc, 0x14, 0x1f, 0x42, 0x20, 0x93, 0x11, 0x4d,
+    0x29, 0x93, 0x32, 0xc8, 0x63, 0x96, 0x88, 0x76,
+    0x69, 0x5c, 0xe3, 0x0e, 0xbd, 0xb6, 0xd9, 0xd6,
+    0x01, 0x02, 0x81, 0x80, 0x62, 0xa2, 0xed, 0x84,
+    0xdc, 0xf6, 0x7a, 0x44, 0xf7, 0x62, 0x12, 0x7c,
+    0xb9, 0x53, 0x4a, 0xff, 0x62, 0x11, 0x58, 0x4e,
+    0xfe, 0xe9, 0x60, 0x15, 0xe8, 0x1a, 0x8a, 0x3d,
+    0xe4, 0xe6, 0x91, 0x31, 0xb0, 0x5f, 0x70, 0x5d,
+    0xb6, 0x1e, 0xf1, 0x26, 0xb6, 0xae, 0x8f, 0x84,
+    0xbd, 0xa4, 0xc7, 0x17, 0x5d, 0xb1, 0x5b, 0x97,
+    0xa0, 0x3d, 0x17, 0xda, 0x26, 0x55, 0xe3, 0x03,
+    0x32, 0x85, 0x26, 0xa1, 0xe3, 0xef, 0xe5, 0x69,
+    0x2c, 0x3b, 0x41, 0x88, 0x9e, 0x7e, 0x0e, 0x9c,
+    0xfd, 0xfc, 0xbb, 0xed, 0x91, 0xc0, 0x5b, 0xa9,
+    0x0a, 0x87, 0xba, 0xf9, 0x1e, 0xda, 0x10, 0x61,
+    0xbe, 0xbb, 0xab, 0x18, 0x25, 0xad, 0x3f, 0xe2,
+    0xb1, 0x90, 0x5c, 0xf7, 0x4a, 0x51, 0xe4, 0xad,
+    0x45, 0x27, 0x97, 0xdd, 0xe7, 0x3a, 0x9a, 0x5e,
+    0xca, 0x7a, 0xaf, 0x4a, 0xbf, 0x10, 0x24, 0x6b,
+    0xb5, 0x2f, 0x61, 0x61, 0x02, 0x81, 0x81, 0x00,
+    0x85, 0x7c, 0x78, 0xa5, 0x11, 0xdf, 0xc3, 0x6a,
+    0x38, 0x48, 0xfa, 0x7e, 0x48, 0xf0, 0x5a, 0x58,
+    0xe2, 0xc5, 0x83, 0x4e, 0x38, 0x3f, 0x4a, 0x2b,
+    0x07, 0x57, 0x31, 0xe7, 0xbe, 0x50, 0xb1, 0xbb,
+    0x24, 0xf3, 0x3d, 0x8b, 0x53, 0xb7, 0xd1, 0x47,
+    0x72, 0x5e, 0xd5, 0xd6, 0x4c, 0xce, 0x2c, 0x46,
+    0x61, 0x9a, 0xaa, 0xc3, 0x0e, 0xd4, 0x23, 0x2c,
+    0xdd, 0xf5, 0xb7, 0xad, 0x38, 0x52, 0x17, 0xc4,
+    0x16, 0xbb, 0xda, 0x1c, 0x61, 0xb1, 0xca, 0x8d,
+    0xb2, 0xa0, 0xbe, 0x4f, 0x3d, 0x19, 0x0e, 0xe0,
+    0x0e, 0x52, 0xad, 0xf3, 0xaf, 0xd9, 0xcc, 0x78,
+    0xc2, 0xb1, 0x5e, 0x05, 0x5e, 0xf2, 0x27, 0x84,
+    0x15, 0xe4, 0x8f, 0xca, 0xc5, 0x92, 0x43, 0xe0,
+    0x24, 0x8d, 0xf2, 0x5d, 0x55, 0xcc, 0x9d, 0x2f,
+    0xa9, 0xf6, 0x9b, 0x67, 0x6a, 0x87, 0x74, 0x36,
+    0x34, 0x7c, 0xd4, 0x9d, 0xff, 0xad, 0xee, 0x69
+};
+
+static const uint8_t _k1_digest[] = {
+    0x46, 0xE0, 0x8A, 0x05, 0x63, 0x4D, 0x17, 0x3F,
+    0xCA, 0xA4, 0xAA, 0xB6, 0x5A, 0xDA, 0xCF, 0xBA,
+    0x84, 0x22, 0x7C, 0x23
+};
+
+/* Create and identity and try to retrieve it. */
+static void tests(void)
+{
+    SecCertificateRef cert = NULL;
+    SecKeyRef privKey = NULL;
+    SecIdentityRef identity = NULL;
+
+    isnt(cert = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)),
+            NULL, "create certificate");
+    isnt(privKey = SecKeyCreateRSAPrivateKey(NULL, _k1, sizeof(_k1),
+                kSecKeyEncodingPkcs1), NULL, "create private key");
+
+    const void *certkeys[] = {
+        kSecValueRef
+    };
+    const void *certvalues[] = {
+        cert
+    };
+    CFDictionaryRef certDict = CFDictionaryCreate(NULL, certkeys, certvalues,
+            array_size(certkeys), NULL, NULL);
+    ok_status(SecItemAdd(certDict, NULL), "add certificate");
+    CFReleaseNull(certDict);
+
+    const void *privkeys[] = {
+        kSecValueRef
+    };
+    const void *privvalues[] = {
+        privKey
+    };
+    CFDictionaryRef privDict = CFDictionaryCreate(NULL, privkeys, privvalues,
+            array_size(privkeys), NULL, NULL);
+    ok_status(SecItemAdd(privDict, NULL), "add private key");
+    CFReleaseNull(privDict);
+
+    isnt(identity = SecIdentityCreate(NULL, cert, privKey), NULL, "create identity");
+
+    /* Lookup the key and certificate using SecItemCopyMatching(). */
+    CFDataRef pk_digest = CFDataCreate(NULL, _k1_digest, sizeof(_k1_digest));
+    const void *q_keys[] = {
+        kSecClass,
+        kSecAttrApplicationLabel,
+        kSecReturnRef
+    };
+    const void *q_values[] = {
+        kSecClassKey,
+        pk_digest,
+        kCFBooleanTrue
+    };
+    CFDictionaryRef query = CFDictionaryCreate(NULL, q_keys, q_values,
+            array_size(q_keys), NULL, NULL);
+    CFTypeRef result_key;
+    ok_status(SecItemCopyMatching(query, &result_key), "lookup key");
+
+    isnt(CFEqual(privKey, result_key), 0, "keys match");
+    CFReleaseNull(query);
+
+    q_keys[1] = kSecAttrPublicKeyHash;
+    q_values[0] = kSecClassCertificate;
+    query = CFDictionaryCreate(NULL, q_keys, q_values,
+            array_size(q_keys), NULL, NULL);
+    CFTypeRef result_cert;
+    ok_status(SecItemCopyMatching(query, &result_cert), "lookup certificate");
+    isnt(CFEqual(cert, result_cert), 0, "certificates match");
+    CFReleaseNull(query);
+
+    /* Cleanup. */
+    CFReleaseNull(result_key);
+    CFReleaseNull(result_cert);
+
+    /* identity lookup */
+    const void *idnt_keys[] = {
+        kSecClass,
+        kSecAttrApplicationLabel,
+        kSecReturnRef
+    };
+    const void *idnt_values[] = {
+        kSecClassIdentity,
+        pk_digest,
+        kCFBooleanTrue
+    };
+    CFTypeRef result_idnt;
+    SecCertificateRef result_cert2;
+    query = CFDictionaryCreate(NULL, idnt_keys, idnt_values,
+            array_size(idnt_keys), NULL, NULL);
+    ok_status(SecItemCopyMatching(query, &result_idnt), "lookup identity");
+    isnt(result_idnt, NULL, "found identity?");
+    is(CFGetRetainCount(result_idnt), 1, "result_idnt rc = 1");
+    isnt(CFEqual(identity, result_idnt), 0, "identities match");
+    CFReleaseNull(identity);
+
+    ok_status(SecIdentityCopyCertificate((SecIdentityRef)result_idnt, &result_cert2), "get cert from identity");
+    isnt(CFEqual(cert, result_cert2), 0, "certificates match");
+    CFRelease(query);
+    CFRelease(pk_digest);
+    CFReleaseNull(result_cert2);
+
+    certDict = CFDictionaryCreate(NULL, certkeys, certvalues,
+            array_size(certkeys), NULL, NULL);
+    ok_status(SecItemDelete(certDict), "delete certificate via ref");
+    is_status(errSecItemNotFound, SecItemCopyMatching(certDict, NULL), "verify certificate is gone");
+
+    CFReleaseNull(certDict);
+
+    privDict = CFDictionaryCreate(NULL, privkeys, privvalues,
+            array_size(privkeys), NULL, NULL);
+    ok_status(SecItemDelete(privDict), "delete key via ref");
+    is_status(errSecItemNotFound, SecItemCopyMatching(privDict, NULL), "verify key is gone");
+    CFReleaseNull(privDict);
+
+    /* add certificate to offset cert row id from key row id */
+    SecCertificateRef apple_ca_cert = NULL;
+    isnt(apple_ca_cert = SecCertificateCreateWithBytes(NULL, _c0, sizeof(_c0)),
+            NULL, "create apple ca certificate");
+    CFDictionaryRef appleCertDict = CFDictionaryCreate(NULL, (const void **)&kSecValueRef, (const void **)&apple_ca_cert, 1, NULL, NULL);
+    ok_status(SecItemAdd(appleCertDict, NULL), "add apple ca certificate to offset key and cert rowid");
+
+    /* add identity, get persistent ref */
+    const void *keys_identity[] = {     kSecValueRef,   kSecReturnPersistentRef };
+    const void *values_identity[] = {   result_idnt,    kCFBooleanTrue };
+    CFDictionaryRef identity_add = CFDictionaryCreate(NULL, keys_identity, values_identity,
+        array_size(keys_identity), NULL, NULL);
+    CFTypeRef persist = NULL;
+    ok_status(SecItemAdd(identity_add, &persist), "add identity ref");
+    ok(persist, "got back persistent ref");
+    /* <rdar://problem/6537195> SecItemAdd returns success when it shouldn't */
+    CFTypeRef persist_again = NULL;
+    is_status(errSecDuplicateItem, SecItemAdd(identity_add, &persist_again),
+        "fail to add identity ref again");
+    ok(!persist_again, "no persistent ref this time");
+
+    /* find by persistent ref */
+    const void *keys_persist[] = { kSecReturnRef, kSecValuePersistentRef };
+    const void *values_persist[] = { kCFBooleanTrue, persist };
+    CFDictionaryRef persist_find = CFDictionaryCreate(NULL, keys_persist, values_persist,
+       (array_size(keys_persist)), NULL, NULL);
+    CFTypeRef results2 = NULL;
+    ok_status(SecItemCopyMatching(persist_find, &results2), "find identity by persistent ref");
+    is(CFGetRetainCount(results2), 1, "results2 rc = 1");
+    // not implemented ok(CFEqual(result_idnt, results2), "same item (attributes)");
+    CFReleaseNull(results2);
+
+    /* find identity, key and cert by ref and return persistent ref */
+    const void *keys_ref_to_persist[] = { kSecReturnPersistentRef, kSecValueRef };
+    const void *values_ref_to_persist[] = { kCFBooleanTrue, NULL };
+    CFTypeRef items[] = { result_idnt, privKey, cert, NULL };
+    CFTypeRef *item = items;
+    while (*item) {
+        values_ref_to_persist[1] = *item;
+        CFDictionaryRef ref_to_persist_find = CFDictionaryCreate(NULL, keys_ref_to_persist, values_ref_to_persist,
+            (array_size(keys_ref_to_persist)), NULL, NULL);
+        results2 = NULL;
+        ok_status(SecItemCopyMatching(ref_to_persist_find, &results2), "find persistent ref for identity ref");
+        ok(NULL != results2, "good persistent ref");
+        is(CFGetRetainCount(results2), 1, "results2 rc = 1");
+        CFReleaseNull(results2);
+        CFReleaseNull(ref_to_persist_find);
+        item++;
+    }
+
+    /* delete identity by identity ref */
+    ok_status(SecItemDelete(identity_add), "delete identity by identity ref");
+    is(SecItemCopyMatching(persist_find, &results2), errSecItemNotFound,
+        "make sure identity by persistent ref is no longer there");
+    CFRelease(persist_find);
+    CFReleaseNull(persist);
+    ok_status(SecItemAdd(identity_add, &persist), "add identity ref back");
+    CFRelease(identity_add);
+
+    /* delete identity by persistent ref */
+    CFDictionaryRef persist_delete = CFDictionaryCreate(NULL,
+        &kSecValuePersistentRef, &persist, 1, NULL, NULL);
+    ok_status(SecItemDelete(persist_delete),
+        "delete identity by persistent ref");
+    is(SecItemCopyMatching(persist_delete, &results2), errSecItemNotFound,
+        "make sure identity by persistent ref is no longer there");
+    CFRelease(persist_delete);
+    CFReleaseNull(persist);
+
+       /* add identity with a label set */
+       CFStringRef zomg_label = CFSTR("zomg");
+       CFMutableDictionaryRef lbl_idnt_query =
+               CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+               &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+       CFDictionarySetValue(lbl_idnt_query, kSecValueRef, result_idnt);
+       CFDictionarySetValue(lbl_idnt_query, kSecAttrLabel, zomg_label);
+    ok_status(SecItemAdd(lbl_idnt_query, NULL), "add identity ref");
+
+       /* find identity with label*/
+       CFDictionaryRemoveAllValues(lbl_idnt_query);
+       CFDictionarySetValue(lbl_idnt_query, kSecClass, kSecClassIdentity);
+       CFDictionarySetValue(lbl_idnt_query, kSecAttrLabel, zomg_label);
+       ok_status(SecItemCopyMatching(lbl_idnt_query, NULL), "find identity by label");
+
+       /* find certs with label */
+       CFTypeRef zomg_cert;
+       CFDictionaryRemoveAllValues(lbl_idnt_query);
+       CFDictionarySetValue(lbl_idnt_query, kSecClass, kSecClassCertificate);
+       CFDictionarySetValue(lbl_idnt_query, kSecAttrLabel, zomg_label);
+       CFDictionarySetValue(lbl_idnt_query, kSecReturnRef, kCFBooleanTrue);
+       ok_status(SecItemCopyMatching(lbl_idnt_query, &zomg_cert), "find cert by label");
+
+       /* find keys with label */
+       CFTypeRef zomg_key;
+       CFDictionaryRemoveAllValues(lbl_idnt_query);
+       CFDictionarySetValue(lbl_idnt_query, kSecClass, kSecClassKey);
+       CFDictionarySetValue(lbl_idnt_query, kSecAttrLabel, zomg_label);
+       CFDictionarySetValue(lbl_idnt_query, kSecReturnRef, kCFBooleanTrue);
+       ok_status(SecItemCopyMatching(lbl_idnt_query, &zomg_key), "find key by label");
+
+       /* update label on key */
+       CFStringRef new_label_value = CFSTR("zzzomg");
+       CFDictionaryRef new_label = CFDictionaryCreate(kCFAllocatorDefault, (const void **)&kSecAttrLabel, (const void **)&new_label_value, 1, NULL, NULL);
+       CFDictionaryRemoveAllValues(lbl_idnt_query);
+       CFDictionarySetValue(lbl_idnt_query, kSecValueRef, zomg_key);
+       ok_status(SecItemUpdate(lbl_idnt_query, new_label), "update label to zzzomg for key");
+
+       CFTypeRef zomg_idnt = NULL;
+       CFDictionaryRemoveAllValues(lbl_idnt_query);
+       CFDictionarySetValue(lbl_idnt_query, kSecReturnRef, kCFBooleanTrue);
+       CFDictionarySetValue(lbl_idnt_query, kSecAttrLabel, zomg_label);
+       CFDictionarySetValue(lbl_idnt_query, kSecClass, kSecClassIdentity);
+       ok_status(SecItemCopyMatching(lbl_idnt_query, &zomg_idnt), "still finding zomg ident");
+       CFReleaseNull(zomg_idnt);
+
+
+       CFDictionaryRemoveAllValues(lbl_idnt_query);
+       CFDictionarySetValue(lbl_idnt_query, kSecValueRef, zomg_cert);
+       ok_status(SecItemUpdate(lbl_idnt_query, new_label), "update label to zzzomg for cert");
+       CFReleaseNull(new_label);
+
+       CFDictionaryRemoveAllValues(lbl_idnt_query);
+       CFDictionarySetValue(lbl_idnt_query, kSecReturnRef, kCFBooleanTrue);
+       CFDictionarySetValue(lbl_idnt_query, kSecAttrLabel, zomg_label);
+       CFDictionarySetValue(lbl_idnt_query, kSecClass, kSecClassIdentity);
+       is_status(errSecItemNotFound, SecItemCopyMatching(lbl_idnt_query, &zomg_idnt), "no longer find identity by label");
+
+       CFDictionaryRemoveAllValues(lbl_idnt_query);
+       CFDictionarySetValue(lbl_idnt_query, kSecReturnRef, kCFBooleanTrue);
+       CFDictionarySetValue(lbl_idnt_query, kSecAttrLabel, new_label_value);
+       CFDictionarySetValue(lbl_idnt_query, kSecClass, kSecClassIdentity);
+       ok_status(SecItemCopyMatching(lbl_idnt_query, &zomg_idnt), "finding ident with zzzomg label");
+
+    /* Find zomg identity with canonical issuer */
+    {
+        unsigned char DN[] = {
+            0x30, 0x32, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
+            0x07, 0x70, 0x6c, 0x75, 0x74, 0x6f, 0x43, 0x41, 0x31, 0x1e, 0x30, 0x1c,
+            0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x0c,
+            0x0f, 0x70, 0x6c, 0x75, 0x74, 0x6f, 0x40, 0x70, 0x6c, 0x75, 0x74, 0x6f,
+            0x2e, 0x63, 0x6f, 0x6d
+        };
+        unsigned int DN_len = 52;
+        CFMutableDictionaryRef find_by_issuer = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+        CFDataRef issuer = SecCertificateGetNormalizedIssuerContent(cert);
+        CFTypeRef found_by_issuer = NULL;
+        CFDictionarySetValue(find_by_issuer, kSecAttrIssuer, issuer);
+        CFDictionarySetValue(find_by_issuer, kSecClass, kSecClassIdentity);
+        CFDictionarySetValue(find_by_issuer, kSecReturnRef, kCFBooleanTrue);
+        ok_status(SecItemCopyMatching(find_by_issuer, &found_by_issuer), "find identity by cert issuer");
+        ok(CFEqual(found_by_issuer, zomg_idnt), "should be same as zomg_idnt");
+        CFReleaseNull(found_by_issuer);
+        issuer = CFDataCreate(kCFAllocatorDefault, DN, DN_len);
+        CFDictionarySetValue(find_by_issuer, kSecAttrIssuer, issuer);
+        ok_status(SecItemCopyMatching(find_by_issuer, &found_by_issuer), "find identity by cert issuer");
+        CFReleaseNull(issuer);
+        ok(CFEqual(found_by_issuer, zomg_idnt), "should be same as zomg_idnt");
+        CFReleaseNull(found_by_issuer);
+        CFReleaseNull(find_by_issuer);
+    }
+
+    ok_status(SecItemDelete(lbl_idnt_query), "delete ident with zzzomg label");
+
+    /* Delete the apple cert last */
+    ok_status(SecItemDelete(appleCertDict), "delete apple ca certificate");
+    CFReleaseNull(appleCertDict);
+    CFReleaseNull(apple_ca_cert);
+
+       CFRelease(zomg_key);
+       CFRelease(zomg_cert);
+       CFRelease(zomg_idnt);
+       CFRelease(zomg_label);
+       CFRelease(new_label_value);
+       CFRelease(lbl_idnt_query);
+
+    CFReleaseNull(result_idnt);
+    CFReleaseNull(privKey);
+    CFReleaseNull(cert);
+}
+
+int si_42_identity(int argc, char *const *argv)
+{
+    plan_tests(56);
+
+
+    tests();
+
+    return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-43-persistent.c b/sec/Security/Regressions/secitem/si-43-persistent.c
new file mode 100644 (file)
index 0000000..e96dbfe
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ *  si-43-persistent.c
+ *  Security
+ *
+ *  Copyright (c) 2008-2010 Apple Inc. All Rights Reserved.
+ *
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecBase.h>
+#include <Security/SecItem.h>
+#include <Security/SecInternal.h>
+#include <Security/SecItemPriv.h>
+#include <utilities/array_size.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "Security_regressions.h"
+
+static void tests(void)
+{
+    int v_eighty = 80;
+    CFNumberRef eighty = CFNumberCreate(NULL, kCFNumberSInt32Type, &v_eighty);
+    const char *v_data = "test";
+    CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data));
+    const void *keys[] = {
+               kSecClass,
+               kSecAttrServer,
+               kSecAttrAccount,
+               kSecAttrPort,
+               kSecAttrProtocol,
+               kSecAttrAuthenticationType,
+               kSecReturnPersistentRef,
+               kSecValueData
+    };
+    const void *values[] = {
+               kSecClassInternetPassword,
+               CFSTR("zuigt.nl"),
+               CFSTR("frtnbf"),
+               eighty,
+               CFSTR("http"),
+               CFSTR("dflt"),
+               kCFBooleanTrue,
+               pwdata
+    };
+    CFDictionaryRef item = CFDictionaryCreate(NULL, keys, values,
+        array_size(keys), NULL, NULL);
+
+    CFTypeRef persist = NULL;
+    ok_status(SecItemAdd(item, &persist), "add internet password");
+    ok(persist, "got back persistent ref");
+
+    /* Create a dict with all attrs except the data. */
+    keys[(array_size(keys)) - 2] = kSecReturnAttributes;
+    CFDictionaryRef query = CFDictionaryCreate(NULL, keys, values,
+        (array_size(keys)) - 1, NULL, NULL);
+    CFTypeRef results = NULL;
+    ok_status(SecItemCopyMatching(query, &results), "find internet password by attr");
+
+    const void *keys_persist[] = {
+               kSecReturnAttributes,
+               kSecValuePersistentRef
+    };
+    const void *values_persist[] = {
+        kCFBooleanTrue,
+        persist
+    };
+    CFDictionaryRef query2 = CFDictionaryCreate(NULL, keys_persist, values_persist,
+       (array_size(keys_persist)), NULL, NULL);
+    CFTypeRef results2 = NULL;
+    ok_status(SecItemCopyMatching(query2, &results2), "find internet password by persistent ref");
+    ok(CFEqual(results, results2 ? results2 : CFSTR("")), "same item (attributes)");
+
+    CFReleaseNull(results);
+    CFReleaseNull(results2);
+
+    ok_status(SecItemDelete(query), "delete internet password");
+
+    ok_status(!SecItemCopyMatching(query, &results),
+        "don't find internet password by attributes");
+    ok(!results, "no results");
+
+    /* clean up left over from aborted run */
+    if (results) {
+        CFDictionaryRef cleanup = CFDictionaryCreate(NULL, &kSecValuePersistentRef,
+            &results, 1, NULL, NULL);
+        SecItemDelete(cleanup);
+        CFRelease(results);
+        CFRelease(cleanup);
+    }
+
+    ok_status(!SecItemCopyMatching(query2, &results2),
+        "don't find internet password by persistent ref anymore");
+    ok(!results2, "no results");
+
+    CFReleaseNull(persist);
+
+    /* Add a new item and get its persistent ref. */
+    ok_status(SecItemAdd(item, &persist), "add internet password");
+    CFTypeRef persist2 = NULL;
+    CFMutableDictionaryRef item2 = CFDictionaryCreateMutableCopy(NULL, 0, item);
+    CFDictionarySetValue(item2, kSecAttrAccount, CFSTR("johndoe"));
+    ok_status(SecItemAdd(item2, &persist2), "add second internet password");
+    is(CFGetTypeID(persist), CFDataGetTypeID(), "result is a CFData");
+    CFMutableDictionaryRef query3 = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(query3, kSecValuePersistentRef, persist);
+    CFMutableDictionaryRef update = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(update, kSecAttrServer, CFSTR("zuigt.com"));
+    ok_status(SecItemUpdate(query3, update), "update via persitant ref");
+
+    /* Verify that the update really worked. */
+    CFDictionaryAddValue(query3, kSecReturnAttributes, kCFBooleanTrue);
+    ok_status(SecItemCopyMatching(query3, &results2), "find updated internet password by persistent ref");
+    CFStringRef server = CFDictionaryGetValue(results2, kSecAttrServer);
+    ok(CFEqual(server, CFSTR("zuigt.com")), "verify attribute was modified by update");
+    CFReleaseNull(results2);
+    CFDictionaryRemoveValue(query3, kSecReturnAttributes);
+
+    /* Verify that item2 wasn't affected by the update. */
+    CFMutableDictionaryRef query4 = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(query4, kSecValuePersistentRef, persist2);
+    CFDictionaryAddValue(query4, kSecReturnAttributes, kCFBooleanTrue);
+    ok_status(SecItemCopyMatching(query4, &results2), "find non updated internet password by persistent ref");
+    server = CFDictionaryGetValue(results2, kSecAttrServer);
+    ok(CFEqual(server, CFSTR("zuigt.nl")), "verify second items attribute was not modified by update");
+    CFReleaseNull(results2);
+
+    /* Delete the item via persitant ref. */
+    ok_status(SecItemDelete(query3), "delete via persitant ref");
+    is_status(SecItemCopyMatching(query3, &results2), errSecItemNotFound,
+        "don't find deleted internet password by persistent ref");
+    CFReleaseNull(results2);
+    ok_status(SecItemCopyMatching(query4, &results2),
+        "find non deleted internet password by persistent ref");
+    CFReleaseNull(results2);
+    ok_status(SecItemDelete(query4),
+              "delete internet password by persistent ref");
+
+    CFRelease(query);
+    CFRelease(query2);
+    CFRelease(query3);
+    CFRelease(query4);
+    CFRelease(update);
+    CFReleaseNull(item);
+    CFReleaseNull(item2);
+    CFReleaseNull(eighty);
+    CFReleaseNull(pwdata);
+    CFReleaseNull(persist);
+    CFReleaseNull(persist2);
+}
+
+int si_43_persistent(int argc, char *const *argv)
+{
+    plan_tests(22);
+
+
+    tests();
+
+    return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-50-secrandom.c b/sec/Security/Regressions/secitem/si-50-secrandom.c
new file mode 100644 (file)
index 0000000..5b5616a
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ *  si-50-secrandom.c
+ *  Security
+ *
+ *  Created by Michael Brouwer on 5/8/07
+ *  Copyright (c) 2007-2008,2010 Apple Inc. All Rights Reserved.
+ *
+ */
+
+#include <Security/SecRandom.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "Security_regressions.h"
+
+/* Test basic add delete update copy matching stuff. */
+static void tests(void)
+{
+       UInt8 bytes[4096] = {};
+       CFIndex size = 42;
+       UInt8 *p = bytes + 23;
+       ok_status(SecRandomCopyBytes(kSecRandomDefault, size, p), "generate some random bytes");
+}
+
+int si_50_secrandom(int argc, char *const *argv)
+{
+       plan_tests(1);
+
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-60-cms.c b/sec/Security/Regressions/secitem/si-60-cms.c
new file mode 100644 (file)
index 0000000..44bab4e
--- /dev/null
@@ -0,0 +1,1816 @@
+/*
+ *  si-60-cms.c
+ *  Security
+ *
+ *  Created by Michael Brouwer on 2/21/08
+ *  Copyright (c) 2008-2010 Apple Inc. All Rights Reserved.
+ *
+ */
+
+#include <Security/SecCMS.h>
+#include <Security/SecItem.h>
+#include <Security/SecItemPriv.h>
+#include <Security/SecInternal.h>
+#include <Security/SecPolicyPriv.h>
+#include <Security/SecBasePriv.h>
+#include <Security/SecRSAKey.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecIdentityPriv.h>
+#include <Security/SecCertificateRequest.h>
+#include <utilities/array_size.h>
+
+#include <CommonCrypto/CommonDigest.h>
+#include <CommonCrypto/CommonDigestSPI.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "Security_regressions.h"
+
+/*
+   Bag Attributes
+friendlyName: uranusLeaf
+localKeyID: 46 E0 8A 05 63 4D 17 3F CA A4 AA B6 5A DA CF BA 84 22 7C 23
+subject=/CN=uranusLeaf/emailAddress=uranus@uranus.com
+issuer=/CN=plutoCA/emailAddress=pluto@pluto.com
+ */
+static const uint8_t _c1[] = {
+    0x30, 0x82, 0x02, 0xe0, 0x30, 0x82, 0x01, 0xc8,
+    0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x02,
+    0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+    0xf7, 0x0d, 0x01, 0x01, 0x05, 0x30, 0x32, 0x31,
+    0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03,
+    0x0c, 0x07, 0x70, 0x6c, 0x75, 0x74, 0x6f, 0x43,
+    0x41, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x09, 0x2a,
+    0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01,
+    0x0c, 0x0f, 0x70, 0x6c, 0x75, 0x74, 0x6f, 0x40,
+    0x70, 0x6c, 0x75, 0x74, 0x6f, 0x2e, 0x63, 0x6f,
+    0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x35, 0x31,
+    0x32, 0x31, 0x37, 0x30, 0x30, 0x30, 0x34, 0x32,
+    0x35, 0x5a, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x32,
+    0x31, 0x37, 0x30, 0x30, 0x30, 0x34, 0x32, 0x35,
+    0x5a, 0x30, 0x37, 0x31, 0x13, 0x30, 0x11, 0x06,
+    0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x75, 0x72,
+    0x61, 0x6e, 0x75, 0x73, 0x4c, 0x65, 0x61, 0x66,
+    0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86,
+    0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x0c,
+    0x11, 0x75, 0x72, 0x61, 0x6e, 0x75, 0x73, 0x40,
+    0x75, 0x72, 0x61, 0x6e, 0x75, 0x73, 0x2e, 0x63,
+    0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
+    0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+    0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
+    0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82,
+    0x01, 0x01, 0x00, 0xa6, 0x82, 0x8e, 0xc6, 0x7e,
+    0xc9, 0x8c, 0x99, 0x6f, 0xb0, 0x62, 0x32, 0x35,
+    0xe7, 0xdb, 0xff, 0x34, 0x84, 0xdc, 0x72, 0xa8,
+    0xef, 0x22, 0x6f, 0x93, 0x63, 0x64, 0x80, 0x80,
+    0x5d, 0x50, 0x7e, 0xb4, 0x2e, 0x1b, 0x93, 0x93,
+    0x49, 0xca, 0xae, 0xcd, 0x34, 0x44, 0x4b, 0xd7,
+    0xfa, 0x9f, 0x3c, 0xfc, 0x9e, 0x65, 0xa9, 0xfb,
+    0x5e, 0x5d, 0x18, 0xa3, 0xf8, 0xb0, 0x08, 0xac,
+    0x8f, 0xfd, 0x03, 0xcb, 0xbd, 0x7f, 0xa0, 0x2a,
+    0xa6, 0xea, 0xca, 0xa3, 0x24, 0xef, 0x7c, 0xc3,
+    0xeb, 0x95, 0xcb, 0x90, 0x3f, 0x5e, 0xde, 0x78,
+    0xf2, 0x3d, 0x32, 0x72, 0xdb, 0x33, 0x6e, 0x9b,
+    0x52, 0x9f, 0x0c, 0x60, 0x4a, 0x24, 0xa1, 0xf6,
+    0x3b, 0x80, 0xbd, 0xa1, 0xdc, 0x40, 0x03, 0xe7,
+    0xa0, 0x59, 0x1f, 0xdb, 0xb4, 0xed, 0x57, 0xdc,
+    0x74, 0x0d, 0x99, 0x5a, 0x12, 0x74, 0x64, 0xaa,
+    0xb6, 0xa5, 0x96, 0x75, 0xf9, 0x42, 0x43, 0xe2,
+    0x52, 0xc2, 0x57, 0x23, 0x75, 0xd7, 0xa9, 0x4f,
+    0x07, 0x32, 0x99, 0xbd, 0x3d, 0x44, 0xbd, 0x04,
+    0x62, 0xe5, 0xb7, 0x2c, 0x0c, 0x11, 0xc5, 0xb2,
+    0x2e, 0xc4, 0x12, 0x1d, 0x7f, 0x42, 0x1e, 0x71,
+    0xaf, 0x39, 0x2b, 0x78, 0x47, 0x92, 0x23, 0x44,
+    0xef, 0xe3, 0xc1, 0x47, 0x69, 0x5a, 0xf1, 0x48,
+    0xaa, 0x37, 0xa4, 0x94, 0x6b, 0x96, 0xe5, 0x4b,
+    0xfd, 0x05, 0xc7, 0x9c, 0xcc, 0x38, 0xd1, 0x47,
+    0x85, 0x60, 0x7f, 0xef, 0xe9, 0x2e, 0x25, 0x08,
+    0xf8, 0x7d, 0x98, 0xdd, 0x6c, 0xeb, 0x4a, 0x32,
+    0x33, 0x44, 0x0b, 0x61, 0xb3, 0xf9, 0xae, 0x26,
+    0x41, 0xb5, 0x38, 0xdb, 0xcf, 0x13, 0x72, 0x23,
+    0x5b, 0x66, 0x20, 0x86, 0x4d, 0x24, 0xc2, 0xd4,
+    0x94, 0xde, 0xe3, 0x24, 0xb7, 0xcd, 0x75, 0x9e,
+    0x1d, 0x9f, 0xbc, 0xd0, 0x60, 0x34, 0x7d, 0xf8,
+    0xcb, 0x41, 0x39, 0x02, 0x03, 0x01, 0x00, 0x01,
+    0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+    0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,
+    0x82, 0x01, 0x01, 0x00, 0x17, 0xa5, 0x22, 0xed,
+    0xb8, 0x3e, 0x1f, 0x11, 0x99, 0xc5, 0xba, 0x28,
+    0x3e, 0x7e, 0xa6, 0xeb, 0x02, 0x81, 0x06, 0xa1,
+    0xc6, 0x80, 0xb9, 0x7e, 0x5c, 0x5a, 0x63, 0xe0,
+    0x8d, 0xeb, 0xd0, 0xec, 0x9c, 0x3a, 0x94, 0x64,
+    0x7c, 0x13, 0x54, 0x0d, 0xd6, 0xe3, 0x27, 0x88,
+    0xa6, 0xd2, 0x4b, 0x36, 0xdd, 0x2e, 0xfa, 0x94,
+    0xe5, 0x03, 0x27, 0xc9, 0xa6, 0x31, 0x02, 0xea,
+    0x40, 0x77, 0x2e, 0x93, 0xc4, 0x4d, 0xe2, 0x70,
+    0xe2, 0x67, 0x1c, 0xa8, 0x0d, 0xcd, 0x1a, 0x72,
+    0x86, 0x2c, 0xea, 0xdc, 0x7f, 0x8c, 0x49, 0x2c,
+    0xe7, 0x99, 0x13, 0xda, 0x3f, 0x58, 0x9e, 0xf5,
+    0x4d, 0x3c, 0x8c, 0x1c, 0xed, 0x85, 0xa7, 0xe2,
+    0xae, 0xda, 0x5f, 0xbe, 0x36, 0x1c, 0x9f, 0x5a,
+    0xa0, 0xdc, 0x2a, 0xc0, 0xee, 0x71, 0x07, 0x26,
+    0x8b, 0xe8, 0x8a, 0xf8, 0x2d, 0x36, 0x78, 0xc9,
+    0x79, 0xfa, 0xbe, 0x98, 0x59, 0x95, 0x12, 0x24,
+    0xf1, 0xda, 0x20, 0xc7, 0x78, 0xf9, 0x7c, 0x6a,
+    0x24, 0x43, 0x82, 0xa8, 0x0f, 0xb1, 0x7d, 0x94,
+    0xaa, 0x30, 0x35, 0xe5, 0x69, 0xdc, 0x0a, 0x0e,
+    0xaf, 0x10, 0x5e, 0x1a, 0x81, 0x50, 0x5c, 0x7e,
+    0x24, 0xb3, 0x07, 0x65, 0x4b, 0xc1, 0x7e, 0xc6,
+    0x38, 0xdb, 0xd3, 0x6a, 0xf0, 0xd8, 0x85, 0x61,
+    0x9a, 0x9f, 0xfe, 0x02, 0x46, 0x29, 0xb2, 0x9a,
+    0xe2, 0x04, 0xe7, 0x72, 0xcc, 0x87, 0x46, 0xba,
+    0x7d, 0xa8, 0xf9, 0xd0, 0x0f, 0x29, 0xfc, 0xfd,
+    0xd1, 0xd0, 0x7f, 0x36, 0xc1, 0xd8, 0x7d, 0x88,
+    0x03, 0x62, 0xf5, 0x8c, 0x00, 0xb5, 0xc2, 0x81,
+    0x44, 0x67, 0x58, 0x11, 0xb4, 0x3a, 0xbb, 0xd1,
+    0x8c, 0x94, 0x20, 0x60, 0xea, 0xa0, 0xac, 0xc1,
+    0xf1, 0x08, 0x54, 0xb8, 0xf6, 0x5e, 0xac, 0xf1,
+    0xec, 0x78, 0x69, 0x9d, 0x7e, 0x4d, 0x06, 0x3b,
+    0x9b, 0x78, 0x78, 0x10
+};
+
+/*
+   Bag Attributes
+friendlyName: uranusLeaf
+localKeyID: 46 E0 8A 05 63 4D 17 3F CA A4 AA B6 5A DA CF BA 84 22 7C 23
+Key Attributes: <No Attributes>
+ */
+static const uint8_t _k1[] = {
+    0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02,
+    0x82, 0x01, 0x01, 0x00, 0xa6, 0x82, 0x8e, 0xc6,
+    0x7e, 0xc9, 0x8c, 0x99, 0x6f, 0xb0, 0x62, 0x32,
+    0x35, 0xe7, 0xdb, 0xff, 0x34, 0x84, 0xdc, 0x72,
+    0xa8, 0xef, 0x22, 0x6f, 0x93, 0x63, 0x64, 0x80,
+    0x80, 0x5d, 0x50, 0x7e, 0xb4, 0x2e, 0x1b, 0x93,
+    0x93, 0x49, 0xca, 0xae, 0xcd, 0x34, 0x44, 0x4b,
+    0xd7, 0xfa, 0x9f, 0x3c, 0xfc, 0x9e, 0x65, 0xa9,
+    0xfb, 0x5e, 0x5d, 0x18, 0xa3, 0xf8, 0xb0, 0x08,
+    0xac, 0x8f, 0xfd, 0x03, 0xcb, 0xbd, 0x7f, 0xa0,
+    0x2a, 0xa6, 0xea, 0xca, 0xa3, 0x24, 0xef, 0x7c,
+    0xc3, 0xeb, 0x95, 0xcb, 0x90, 0x3f, 0x5e, 0xde,
+    0x78, 0xf2, 0x3d, 0x32, 0x72, 0xdb, 0x33, 0x6e,
+    0x9b, 0x52, 0x9f, 0x0c, 0x60, 0x4a, 0x24, 0xa1,
+    0xf6, 0x3b, 0x80, 0xbd, 0xa1, 0xdc, 0x40, 0x03,
+    0xe7, 0xa0, 0x59, 0x1f, 0xdb, 0xb4, 0xed, 0x57,
+    0xdc, 0x74, 0x0d, 0x99, 0x5a, 0x12, 0x74, 0x64,
+    0xaa, 0xb6, 0xa5, 0x96, 0x75, 0xf9, 0x42, 0x43,
+    0xe2, 0x52, 0xc2, 0x57, 0x23, 0x75, 0xd7, 0xa9,
+    0x4f, 0x07, 0x32, 0x99, 0xbd, 0x3d, 0x44, 0xbd,
+    0x04, 0x62, 0xe5, 0xb7, 0x2c, 0x0c, 0x11, 0xc5,
+    0xb2, 0x2e, 0xc4, 0x12, 0x1d, 0x7f, 0x42, 0x1e,
+    0x71, 0xaf, 0x39, 0x2b, 0x78, 0x47, 0x92, 0x23,
+    0x44, 0xef, 0xe3, 0xc1, 0x47, 0x69, 0x5a, 0xf1,
+    0x48, 0xaa, 0x37, 0xa4, 0x94, 0x6b, 0x96, 0xe5,
+    0x4b, 0xfd, 0x05, 0xc7, 0x9c, 0xcc, 0x38, 0xd1,
+    0x47, 0x85, 0x60, 0x7f, 0xef, 0xe9, 0x2e, 0x25,
+    0x08, 0xf8, 0x7d, 0x98, 0xdd, 0x6c, 0xeb, 0x4a,
+    0x32, 0x33, 0x44, 0x0b, 0x61, 0xb3, 0xf9, 0xae,
+    0x26, 0x41, 0xb5, 0x38, 0xdb, 0xcf, 0x13, 0x72,
+    0x23, 0x5b, 0x66, 0x20, 0x86, 0x4d, 0x24, 0xc2,
+    0xd4, 0x94, 0xde, 0xe3, 0x24, 0xb7, 0xcd, 0x75,
+    0x9e, 0x1d, 0x9f, 0xbc, 0xd0, 0x60, 0x34, 0x7d,
+    0xf8, 0xcb, 0x41, 0x39, 0x02, 0x03, 0x01, 0x00,
+    0x01, 0x02, 0x82, 0x01, 0x00, 0x4d, 0x27, 0xf2,
+    0x40, 0xc8, 0x3f, 0x5c, 0x87, 0x3c, 0xd9, 0xde,
+    0xa6, 0xa5, 0x93, 0xea, 0xbd, 0x36, 0xf8, 0xd9,
+    0xad, 0xc7, 0xda, 0x07, 0x7a, 0xec, 0x31, 0x02,
+    0x41, 0x09, 0x3a, 0x34, 0x32, 0x82, 0x0b, 0x5b,
+    0x7b, 0xe6, 0xa4, 0x2a, 0xe7, 0x14, 0xef, 0x43,
+    0x36, 0x61, 0xbe, 0x20, 0x4b, 0x82, 0x43, 0x63,
+    0x98, 0x80, 0x82, 0x19, 0x61, 0x71, 0x99, 0xaa,
+    0xf8, 0x59, 0xfd, 0xde, 0xa0, 0x03, 0xa8, 0xab,
+    0x9a, 0xec, 0x28, 0xac, 0x63, 0x79, 0x75, 0x84,
+    0x03, 0xac, 0x45, 0x5e, 0x04, 0x15, 0xb3, 0x47,
+    0xa2, 0x8f, 0x28, 0xb0, 0x72, 0xd0, 0x06, 0x02,
+    0xaf, 0x1e, 0x0a, 0x0a, 0xe9, 0x11, 0x35, 0x4a,
+    0x04, 0x42, 0xb5, 0x0f, 0xd2, 0xcf, 0x4d, 0xdf,
+    0xdb, 0xef, 0x58, 0xbd, 0xf3, 0xa5, 0x3b, 0x11,
+    0x3f, 0xc5, 0x47, 0x81, 0x85, 0xad, 0xd7, 0x1f,
+    0x58, 0x06, 0x42, 0xdc, 0x37, 0x3c, 0xdb, 0x98,
+    0x33, 0xa1, 0xc6, 0x80, 0x07, 0xe0, 0x2b, 0xc5,
+    0xf5, 0x60, 0x35, 0x6a, 0xa2, 0x06, 0x40, 0x4a,
+    0xac, 0x64, 0x02, 0x58, 0x4d, 0x07, 0xe3, 0x69,
+    0xd7, 0xe0, 0x8f, 0xb5, 0xf4, 0xbc, 0xfa, 0xab,
+    0x1a, 0xb0, 0xfa, 0x29, 0xf8, 0xca, 0xde, 0x78,
+    0xf0, 0x89, 0xe2, 0xf9, 0xb7, 0x68, 0x5b, 0x0e,
+    0xdc, 0x4e, 0x8a, 0x56, 0x8d, 0x33, 0x20, 0x2e,
+    0xed, 0x2e, 0xab, 0x6f, 0xba, 0x77, 0xef, 0xe6,
+    0x12, 0x62, 0x49, 0x9e, 0x87, 0x76, 0x1c, 0x1e,
+    0xf4, 0x0e, 0x9e, 0x78, 0x98, 0x91, 0x1a, 0xe3,
+    0xb4, 0x51, 0x4b, 0x8c, 0x2f, 0x08, 0x97, 0x8f,
+    0xf9, 0x68, 0x61, 0x40, 0xcd, 0xb6, 0x10, 0xb4,
+    0xfb, 0x75, 0xb4, 0x20, 0xc1, 0x5a, 0xda, 0x64,
+    0xfd, 0x51, 0x06, 0x85, 0x9a, 0x9e, 0x5d, 0x82,
+    0x14, 0xd4, 0x41, 0x4e, 0x75, 0x10, 0xb5, 0x7b,
+    0xd0, 0x4c, 0xd1, 0x00, 0x01, 0x02, 0x81, 0x81,
+    0x00, 0xcf, 0x8e, 0x68, 0x04, 0x67, 0x09, 0xa9,
+    0x6e, 0xff, 0x11, 0x8c, 0xe5, 0xe4, 0x16, 0xdd,
+    0xb6, 0xa6, 0x55, 0xca, 0x4b, 0x0b, 0xbb, 0xb7,
+    0xf5, 0xe5, 0x73, 0xf3, 0x24, 0x84, 0x29, 0xb2,
+    0xc3, 0xbc, 0x7f, 0x2b, 0x4a, 0xc7, 0xdf, 0x46,
+    0x8e, 0xe1, 0x35, 0x69, 0x1b, 0x8e, 0x9f, 0x6b,
+    0x4d, 0xf3, 0x65, 0xae, 0x3d, 0x87, 0x2b, 0xc9,
+    0xf0, 0x8c, 0xf2, 0x88, 0x2f, 0x1b, 0x79, 0x80,
+    0xd2, 0xb2, 0x64, 0x0a, 0xcc, 0x66, 0x69, 0x4c,
+    0xa1, 0x85, 0xc4, 0x6a, 0x94, 0x46, 0x70, 0x69,
+    0xbc, 0x8c, 0x1c, 0x62, 0x65, 0x4d, 0x68, 0xcc,
+    0xe3, 0x3c, 0x6c, 0xe7, 0xd1, 0x09, 0xed, 0xdd,
+    0x42, 0x10, 0x11, 0x6b, 0xdd, 0x7c, 0xe3, 0xe1,
+    0x3b, 0x3b, 0x0d, 0x01, 0x6d, 0xca, 0x2f, 0x4b,
+    0x45, 0x5e, 0x76, 0x5d, 0x5c, 0x6f, 0x53, 0xa4,
+    0x38, 0x74, 0x75, 0x94, 0x2c, 0xda, 0xf8, 0xa6,
+    0x01, 0x02, 0x81, 0x81, 0x00, 0xcd, 0x5f, 0x9d,
+    0x6c, 0x94, 0xf6, 0x44, 0x37, 0x72, 0xfe, 0xcf,
+    0xbe, 0x82, 0x96, 0x24, 0x22, 0x12, 0x07, 0x6f,
+    0xd1, 0x57, 0x7b, 0xc7, 0x63, 0x20, 0xf5, 0x93,
+    0x79, 0x70, 0x0b, 0xe4, 0x38, 0x19, 0x62, 0x7b,
+    0x89, 0x3e, 0x45, 0xdf, 0xd6, 0xae, 0x9d, 0x0d,
+    0xa8, 0x76, 0xc1, 0xbd, 0x04, 0x2b, 0xaa, 0x30,
+    0x6a, 0xac, 0x65, 0x91, 0x61, 0xf0, 0xf8, 0x5d,
+    0xa3, 0x53, 0xa4, 0xfb, 0x99, 0xac, 0x46, 0x7a,
+    0x12, 0x4b, 0xf7, 0xa7, 0x48, 0x41, 0x61, 0x48,
+    0x26, 0x5c, 0x68, 0x2f, 0x73, 0x91, 0xe4, 0x74,
+    0xcd, 0xc9, 0x8b, 0xe7, 0x26, 0xe4, 0x35, 0xde,
+    0x32, 0x6b, 0x24, 0x49, 0xf2, 0x04, 0x67, 0x3d,
+    0x31, 0x8f, 0x22, 0xe5, 0x49, 0xae, 0x49, 0x94,
+    0xb3, 0x45, 0x2b, 0xed, 0x6f, 0x9c, 0xc7, 0x80,
+    0xf0, 0x42, 0xd5, 0x8f, 0x27, 0xd6, 0xd6, 0x49,
+    0xf2, 0x16, 0xcc, 0x4b, 0x39, 0x02, 0x81, 0x81,
+    0x00, 0xbb, 0xb7, 0xd7, 0x59, 0xcb, 0xfb, 0x10,
+    0x13, 0xc4, 0x7b, 0x92, 0x0c, 0x45, 0xcb, 0x6c,
+    0x81, 0x0a, 0x55, 0x63, 0x1d, 0x96, 0xa2, 0x13,
+    0xd2, 0x40, 0xd1, 0x2a, 0xa1, 0xe7, 0x2a, 0x73,
+    0x74, 0xd6, 0x61, 0xc9, 0xbc, 0xdb, 0xa2, 0x93,
+    0x85, 0x1c, 0x28, 0x9b, 0x44, 0x82, 0x2c, 0xaa,
+    0xf7, 0x18, 0x60, 0xe9, 0x42, 0xda, 0xa2, 0xff,
+    0x04, 0x21, 0xe6, 0x24, 0xc7, 0x3e, 0x39, 0x19,
+    0x0a, 0xf6, 0xae, 0xc6, 0x99, 0x71, 0x32, 0x61,
+    0x4d, 0x60, 0xd7, 0x71, 0x71, 0x63, 0x77, 0xbe,
+    0x19, 0xfa, 0x3a, 0x9d, 0xbf, 0x73, 0x50, 0x8a,
+    0xa6, 0x26, 0x7b, 0x74, 0xfa, 0x39, 0xd9, 0xb9,
+    0x18, 0x4b, 0xc2, 0x05, 0xe5, 0x8f, 0x53, 0xe6,
+    0xdc, 0x14, 0x1f, 0x42, 0x20, 0x93, 0x11, 0x4d,
+    0x29, 0x93, 0x32, 0xc8, 0x63, 0x96, 0x88, 0x76,
+    0x69, 0x5c, 0xe3, 0x0e, 0xbd, 0xb6, 0xd9, 0xd6,
+    0x01, 0x02, 0x81, 0x80, 0x62, 0xa2, 0xed, 0x84,
+    0xdc, 0xf6, 0x7a, 0x44, 0xf7, 0x62, 0x12, 0x7c,
+    0xb9, 0x53, 0x4a, 0xff, 0x62, 0x11, 0x58, 0x4e,
+    0xfe, 0xe9, 0x60, 0x15, 0xe8, 0x1a, 0x8a, 0x3d,
+    0xe4, 0xe6, 0x91, 0x31, 0xb0, 0x5f, 0x70, 0x5d,
+    0xb6, 0x1e, 0xf1, 0x26, 0xb6, 0xae, 0x8f, 0x84,
+    0xbd, 0xa4, 0xc7, 0x17, 0x5d, 0xb1, 0x5b, 0x97,
+    0xa0, 0x3d, 0x17, 0xda, 0x26, 0x55, 0xe3, 0x03,
+    0x32, 0x85, 0x26, 0xa1, 0xe3, 0xef, 0xe5, 0x69,
+    0x2c, 0x3b, 0x41, 0x88, 0x9e, 0x7e, 0x0e, 0x9c,
+    0xfd, 0xfc, 0xbb, 0xed, 0x91, 0xc0, 0x5b, 0xa9,
+    0x0a, 0x87, 0xba, 0xf9, 0x1e, 0xda, 0x10, 0x61,
+    0xbe, 0xbb, 0xab, 0x18, 0x25, 0xad, 0x3f, 0xe2,
+    0xb1, 0x90, 0x5c, 0xf7, 0x4a, 0x51, 0xe4, 0xad,
+    0x45, 0x27, 0x97, 0xdd, 0xe7, 0x3a, 0x9a, 0x5e,
+    0xca, 0x7a, 0xaf, 0x4a, 0xbf, 0x10, 0x24, 0x6b,
+    0xb5, 0x2f, 0x61, 0x61, 0x02, 0x81, 0x81, 0x00,
+    0x85, 0x7c, 0x78, 0xa5, 0x11, 0xdf, 0xc3, 0x6a,
+    0x38, 0x48, 0xfa, 0x7e, 0x48, 0xf0, 0x5a, 0x58,
+    0xe2, 0xc5, 0x83, 0x4e, 0x38, 0x3f, 0x4a, 0x2b,
+    0x07, 0x57, 0x31, 0xe7, 0xbe, 0x50, 0xb1, 0xbb,
+    0x24, 0xf3, 0x3d, 0x8b, 0x53, 0xb7, 0xd1, 0x47,
+    0x72, 0x5e, 0xd5, 0xd6, 0x4c, 0xce, 0x2c, 0x46,
+    0x61, 0x9a, 0xaa, 0xc3, 0x0e, 0xd4, 0x23, 0x2c,
+    0xdd, 0xf5, 0xb7, 0xad, 0x38, 0x52, 0x17, 0xc4,
+    0x16, 0xbb, 0xda, 0x1c, 0x61, 0xb1, 0xca, 0x8d,
+    0xb2, 0xa0, 0xbe, 0x4f, 0x3d, 0x19, 0x0e, 0xe0,
+    0x0e, 0x52, 0xad, 0xf3, 0xaf, 0xd9, 0xcc, 0x78,
+    0xc2, 0xb1, 0x5e, 0x05, 0x5e, 0xf2, 0x27, 0x84,
+    0x15, 0xe4, 0x8f, 0xca, 0xc5, 0x92, 0x43, 0xe0,
+    0x24, 0x8d, 0xf2, 0x5d, 0x55, 0xcc, 0x9d, 0x2f,
+    0xa9, 0xf6, 0x9b, 0x67, 0x6a, 0x87, 0x74, 0x36,
+    0x34, 0x7c, 0xd4, 0x9d, 0xff, 0xad, 0xee, 0x69
+};
+
+
+/* A certs only cms message. */
+static UInt8 certsOnlyMsg[] = {
+    0x30, 0x82, 0x04, 0xdc, 0x06, 0x09, 0x2a, 0x86,
+    0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0,
+    0x82, 0x04, 0xcd, 0x30, 0x82, 0x04, 0xc9, 0x02,
+    0x01, 0x01, 0x31, 0x00, 0x30, 0x0b, 0x06, 0x09,
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07,
+    0x01, 0xa0, 0x82, 0x04, 0xb1, 0x30, 0x82, 0x04,
+    0xad, 0x30, 0x82, 0x03, 0x95, 0xa0, 0x03, 0x02,
+    0x01, 0x02, 0x02, 0x10, 0x4e, 0x2d, 0x47, 0x54,
+    0xcd, 0xbb, 0x8e, 0x98, 0x42, 0xdb, 0x18, 0x9e,
+    0x3a, 0xca, 0x80, 0xcc, 0x30, 0x0d, 0x06, 0x09,
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+    0x05, 0x05, 0x00, 0x30, 0x57, 0x31, 0x13, 0x30,
+    0x11, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
+    0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x63,
+    0x6f, 0x6d, 0x31, 0x15, 0x30, 0x13, 0x06, 0x0a,
+    0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64,
+    0x01, 0x19, 0x16, 0x05, 0x61, 0x70, 0x70, 0x6c,
+    0x65, 0x31, 0x17, 0x30, 0x15, 0x06, 0x0a, 0x09,
+    0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01,
+    0x19, 0x16, 0x07, 0x63, 0x61, 0x6c, 0x6c, 0x69,
+    0x65, 0x39, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03,
+    0x55, 0x04, 0x03, 0x13, 0x07, 0x63, 0x61, 0x6c,
+    0x6c, 0x69, 0x65, 0x39, 0x30, 0x1e, 0x17, 0x0d,
+    0x30, 0x34, 0x30, 0x32, 0x32, 0x34, 0x31, 0x39,
+    0x31, 0x35, 0x35, 0x37, 0x5a, 0x17, 0x0d, 0x30,
+    0x39, 0x30, 0x32, 0x32, 0x34, 0x31, 0x39, 0x32,
+    0x35, 0x30, 0x31, 0x5a, 0x30, 0x57, 0x31, 0x13,
+    0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89,
+    0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03,
+    0x63, 0x6f, 0x6d, 0x31, 0x15, 0x30, 0x13, 0x06,
+    0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c,
+    0x64, 0x01, 0x19, 0x16, 0x05, 0x61, 0x70, 0x70,
+    0x6c, 0x65, 0x31, 0x17, 0x30, 0x15, 0x06, 0x0a,
+    0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64,
+    0x01, 0x19, 0x16, 0x07, 0x63, 0x61, 0x6c, 0x6c,
+    0x69, 0x65, 0x39, 0x31, 0x10, 0x30, 0x0e, 0x06,
+    0x03, 0x55, 0x04, 0x03, 0x13, 0x07, 0x63, 0x61,
+    0x6c, 0x6c, 0x69, 0x65, 0x39, 0x30, 0x82, 0x01,
+    0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+    0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
+    0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01,
+    0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0x9d, 0xbf,
+    0x50, 0x9c, 0x42, 0xea, 0xad, 0xfa, 0xb7, 0x3e,
+    0x22, 0xcf, 0xc5, 0xba, 0xd3, 0x3a, 0xe8, 0x62,
+    0xb5, 0x62, 0x3d, 0x1e, 0xcf, 0xec, 0x52, 0x48,
+    0x51, 0xa0, 0xef, 0x20, 0xf2, 0x7b, 0xb2, 0x57,
+    0x25, 0x86, 0xd7, 0x15, 0xd8, 0xc6, 0x1a, 0x5f,
+    0x95, 0xe0, 0x35, 0x97, 0x23, 0x7c, 0xc6, 0x88,
+    0x11, 0x1c, 0x8d, 0x8d, 0x7d, 0xf0, 0xc0, 0xbd,
+    0x71, 0x49, 0xbd, 0x9e, 0x51, 0x02, 0x3c, 0x70,
+    0xd7, 0xaa, 0xd2, 0x80, 0xb4, 0xda, 0xb0, 0x3b,
+    0x42, 0x16, 0x50, 0xc6, 0x1b, 0x17, 0x29, 0xd6,
+    0xbe, 0x40, 0xce, 0x3c, 0x54, 0xaf, 0xf5, 0x29,
+    0xc6, 0x12, 0x47, 0xc4, 0x96, 0x85, 0x46, 0xaa,
+    0xf1, 0x76, 0xd1, 0x76, 0x22, 0xd3, 0x45, 0xf7,
+    0x71, 0xea, 0x4b, 0x42, 0x7b, 0x97, 0x39, 0x02,
+    0x2c, 0x6d, 0x36, 0x2a, 0x80, 0xaa, 0x01, 0x58,
+    0xbc, 0x52, 0xa2, 0xa4, 0xc4, 0x3c, 0xe8, 0xcd,
+    0xb2, 0xb8, 0x4a, 0xd3, 0x4e, 0x06, 0xcc, 0x52,
+    0x0f, 0x5e, 0xd2, 0xe9, 0xe9, 0xb8, 0xe6, 0x79,
+    0xe3, 0x91, 0x24, 0x72, 0x44, 0x65, 0x3c, 0xfe,
+    0x01, 0x69, 0x70, 0x0a, 0xce, 0xd1, 0x9a, 0xd1,
+    0x3f, 0x77, 0xa6, 0x78, 0x04, 0x9b, 0x7b, 0x14,
+    0x37, 0x71, 0x3d, 0x4b, 0x56, 0xe9, 0xc3, 0xf6,
+    0x58, 0x16, 0x0c, 0x10, 0x86, 0x5b, 0xbd, 0x93,
+    0xc0, 0xf5, 0xb8, 0xbb, 0x78, 0xcf, 0xf3, 0xb2,
+    0xaa, 0xaf, 0xc4, 0x0c, 0x66, 0x13, 0x1d, 0xce,
+    0x98, 0x4e, 0x99, 0x93, 0xb6, 0xf7, 0xe0, 0x73,
+    0xb6, 0x74, 0x55, 0xcf, 0x83, 0x1d, 0x8d, 0x68,
+    0xcf, 0x59, 0x5e, 0x1b, 0x3e, 0xb5, 0x5a, 0x71,
+    0x36, 0x07, 0xb6, 0xfa, 0xc4, 0x6f, 0xe5, 0x7b,
+    0x69, 0x09, 0xe7, 0xe5, 0xce, 0x8a, 0x1c, 0xfa,
+    0x5c, 0xdc, 0x5d, 0x18, 0xf4, 0x5a, 0x5b, 0x0d,
+    0x37, 0x44, 0x56, 0x9e, 0xe9, 0x95, 0x02, 0x03,
+    0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x73, 0x30,
+    0x82, 0x01, 0x6f, 0x30, 0x0b, 0x06, 0x03, 0x55,
+    0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86,
+    0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
+    0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01,
+    0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
+    0x04, 0x16, 0x04, 0x14, 0x6c, 0xde, 0x50, 0x56,
+    0x01, 0x34, 0xdc, 0x26, 0xec, 0x85, 0xdf, 0xf7,
+    0x32, 0x67, 0x68, 0x08, 0x04, 0xa0, 0xa8, 0xcd,
+    0x30, 0x82, 0x01, 0x1c, 0x06, 0x03, 0x55, 0x1d,
+    0x1f, 0x04, 0x82, 0x01, 0x13, 0x30, 0x82, 0x01,
+    0x0f, 0x30, 0x82, 0x01, 0x0b, 0xa0, 0x82, 0x01,
+    0x07, 0xa0, 0x82, 0x01, 0x03, 0x86, 0x81, 0xbf,
+    0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x2f,
+    0x43, 0x4e, 0x3d, 0x63, 0x61, 0x6c, 0x6c, 0x69,
+    0x65, 0x39, 0x2c, 0x43, 0x4e, 0x3d, 0x63, 0x68,
+    0x72, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x2d, 0x6d,
+    0x74, 0x33, 0x71, 0x66, 0x6f, 0x2c, 0x43, 0x4e,
+    0x3d, 0x43, 0x44, 0x50, 0x2c, 0x43, 0x4e, 0x3d,
+    0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32,
+    0x30, 0x4b, 0x65, 0x79, 0x25, 0x32, 0x30, 0x53,
+    0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c,
+    0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69,
+    0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x43,
+    0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61,
+    0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d,
+    0x63, 0x61, 0x6c, 0x6c, 0x69, 0x65, 0x39, 0x2c,
+    0x44, 0x43, 0x3d, 0x61, 0x70, 0x70, 0x6c, 0x65,
+    0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, 0x6d, 0x3f,
+    0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+    0x61, 0x74, 0x65, 0x52, 0x65, 0x76, 0x6f, 0x63,
+    0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73,
+    0x74, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f,
+    0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x61,
+    0x73, 0x73, 0x3d, 0x63, 0x52, 0x4c, 0x44, 0x69,
+    0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69,
+    0x6f, 0x6e, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x86,
+    0x3f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+    0x63, 0x68, 0x72, 0x69, 0x73, 0x74, 0x6f, 0x70,
+    0x2d, 0x6d, 0x74, 0x33, 0x71, 0x66, 0x6f, 0x2e,
+    0x63, 0x61, 0x6c, 0x6c, 0x69, 0x65, 0x39, 0x2e,
+    0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
+    0x6d, 0x2f, 0x43, 0x65, 0x72, 0x74, 0x45, 0x6e,
+    0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x63, 0x61, 0x6c,
+    0x6c, 0x69, 0x65, 0x39, 0x2e, 0x63, 0x72, 0x6c,
+    0x30, 0x10, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04,
+    0x01, 0x82, 0x37, 0x15, 0x01, 0x04, 0x03, 0x02,
+    0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+    0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
+    0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x9d, 0xba,
+    0x9a, 0xeb, 0x1d, 0x78, 0x99, 0x93, 0xc6, 0x2c,
+    0x36, 0x16, 0xa0, 0x15, 0x18, 0xe8, 0x20, 0x2e,
+    0xb2, 0x0a, 0x8c, 0x02, 0x2e, 0x69, 0xe3, 0x9c,
+    0x03, 0x26, 0x56, 0x41, 0xdd, 0x5a, 0xe1, 0x49,
+    0x38, 0x5d, 0xf8, 0x1d, 0x09, 0x57, 0x22, 0xad,
+    0xd9, 0xf4, 0x47, 0xa4, 0x0a, 0x46, 0xd7, 0x13,
+    0xda, 0x08, 0xa1, 0x2c, 0xff, 0xb3, 0xbd, 0x07,
+    0xfa, 0x95, 0x98, 0x0f, 0x53, 0x40, 0x79, 0xb2,
+    0xf7, 0x85, 0x67, 0xf6, 0x37, 0x7f, 0xec, 0x21,
+    0xf6, 0xb4, 0x6c, 0xda, 0x93, 0x03, 0x32, 0x74,
+    0x5a, 0xa8, 0x81, 0x86, 0x10, 0xb7, 0x55, 0x11,
+    0xe7, 0x53, 0xc3, 0x0a, 0x7e, 0x47, 0xba, 0xf5,
+    0x8a, 0xaa, 0xab, 0x02, 0xc2, 0x01, 0xd6, 0x5b,
+    0xb2, 0x96, 0xa9, 0x04, 0xda, 0xc2, 0x83, 0xb5,
+    0x09, 0x54, 0x69, 0x67, 0xd2, 0x3a, 0x13, 0x6a,
+    0x6c, 0xce, 0xc0, 0x64, 0x92, 0xb5, 0xda, 0x48,
+    0x1c, 0x07, 0x15, 0xfb, 0xdd, 0x5f, 0xb6, 0x66,
+    0x4c, 0x89, 0x44, 0xa0, 0x5c, 0x22, 0x41, 0x3d,
+    0x5f, 0x21, 0x97, 0xa9, 0x0f, 0x58, 0xe9, 0xf8,
+    0x16, 0x5e, 0xd9, 0x1e, 0x9d, 0x99, 0x0a, 0x9c,
+    0xf3, 0x8b, 0x35, 0x3d, 0x0e, 0xc1, 0x10, 0x13,
+    0x77, 0xcf, 0x4d, 0x4c, 0x85, 0xb4, 0x66, 0x27,
+    0xa8, 0x79, 0x8f, 0xa4, 0x9f, 0x5f, 0x1f, 0xe9,
+    0xe6, 0x39, 0xc0, 0xcf, 0x3d, 0x4a, 0x17, 0x3f,
+    0x0b, 0xbf, 0x35, 0xe7, 0xe4, 0x47, 0x66, 0x4d,
+    0x1e, 0xbc, 0x58, 0xf5, 0x62, 0xf8, 0x31, 0x02,
+    0x84, 0xfb, 0x52, 0x39, 0x26, 0x92, 0xc3, 0xff,
+    0x2a, 0x0a, 0x8e, 0x76, 0x66, 0xbc, 0x94, 0x38,
+    0xe2, 0x28, 0x19, 0xcd, 0x40, 0xde, 0x88, 0xdd,
+    0xfe, 0xf1, 0xdd, 0x62, 0xf4, 0xb5, 0x58, 0xf6,
+    0x30, 0x22, 0xc3, 0x94, 0xed, 0xd2, 0x0a, 0x9a,
+    0x71, 0x14, 0xd4, 0xed, 0x70, 0x94, 0x31, 0x00
+};
+
+static unsigned char mobileconfig_with_long_issuer[] = {
+  0x30, 0x82, 0x0e, 0x6a, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x07, 0x02, 0xa0, 0x82, 0x0e, 0x5b, 0x30, 0x82, 0x0e, 0x57, 0x02,
+  0x01, 0x01, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
+  0x1a, 0x05, 0x00, 0x30, 0x82, 0x05, 0x68, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x05, 0x59, 0x04, 0x82,
+  0x05, 0x55, 0x3c, 0x3f, 0x78, 0x6d, 0x6c, 0x20, 0x76, 0x65, 0x72, 0x73,
+  0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x31, 0x2e, 0x30, 0x22, 0x20, 0x65, 0x6e,
+  0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3d, 0x22, 0x55, 0x54, 0x46, 0x2d,
+  0x38, 0x22, 0x3f, 0x3e, 0x0a, 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59,
+  0x50, 0x45, 0x20, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x50, 0x55, 0x42,
+  0x4c, 0x49, 0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x41, 0x70, 0x70, 0x6c,
+  0x65, 0x2f, 0x2f, 0x44, 0x54, 0x44, 0x20, 0x50, 0x4c, 0x49, 0x53, 0x54,
+  0x20, 0x31, 0x2e, 0x30, 0x2f, 0x2f, 0x45, 0x4e, 0x22, 0x20, 0x22, 0x68,
+  0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70,
+  0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x54, 0x44, 0x73,
+  0x2f, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x4c, 0x69, 0x73,
+  0x74, 0x2d, 0x31, 0x2e, 0x30, 0x2e, 0x64, 0x74, 0x64, 0x22, 0x3e, 0x0a,
+  0x3c, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69,
+  0x6f, 0x6e, 0x3d, 0x22, 0x31, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x3c, 0x64,
+  0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x50,
+  0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e,
+  0x74, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x3c, 0x61, 0x72,
+  0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x64, 0x69, 0x63, 0x74,
+  0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x50, 0x61,
+  0x79, 0x6c, 0x6f, 0x61, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,
+  0x74, 0x69, 0x6f, 0x6e, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09,
+  0x09, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x43, 0x6f,
+  0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x73, 0x20, 0x73, 0x65, 0x63,
+  0x75, 0x72, 0x69, 0x74, 0x79, 0x2d, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65,
+  0x64, 0x20, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x3c, 0x2f, 0x73, 0x74,
+  0x72, 0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65,
+  0x79, 0x3e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x44, 0x69, 0x73,
+  0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x3c, 0x2f, 0x6b, 0x65,
+  0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e,
+  0x67, 0x3e, 0x50, 0x61, 0x73, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x50,
+  0x6f, 0x6c, 0x69, 0x63, 0x79, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e,
+  0x67, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x50,
+  0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69,
+  0x66, 0x69, 0x65, 0x72, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09,
+  0x09, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x63, 0x6f,
+  0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x69, 0x6d, 0x70,
+  0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x73, 0x69, 0x6d,
+  0x70, 0x6c, 0x65, 0x2e, 0x34, 0x64, 0x69, 0x67, 0x69, 0x74, 0x73, 0x2e,
+  0x70, 0x61, 0x73, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x70, 0x6f, 0x6c, 0x69,
+  0x63, 0x79, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x0a,
+  0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x50, 0x61, 0x79, 0x6c,
+  0x6f, 0x61, 0x64, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74,
+  0x69, 0x6f, 0x6e, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09,
+  0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x73, 0x61, 0x66,
+  0x73, 0x64, 0x66, 0x61, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67,
+  0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x50, 0x61,
+  0x79, 0x6c, 0x6f, 0x61, 0x64, 0x54, 0x79, 0x70, 0x65, 0x3c, 0x2f, 0x6b,
+  0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69,
+  0x6e, 0x67, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65,
+  0x2e, 0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x64, 0x65, 0x76, 0x69, 0x63,
+  0x65, 0x2e, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x70, 0x6f,
+  0x6c, 0x69, 0x63, 0x79, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67,
+  0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x50, 0x61,
+  0x79, 0x6c, 0x6f, 0x61, 0x64, 0x55, 0x55, 0x49, 0x44, 0x3c, 0x2f, 0x6b,
+  0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69,
+  0x6e, 0x67, 0x3e, 0x45, 0x37, 0x45, 0x34, 0x33, 0x46, 0x38, 0x34, 0x2d,
+  0x30, 0x31, 0x39, 0x35, 0x2d, 0x34, 0x41, 0x37, 0x46, 0x2d, 0x42, 0x30,
+  0x39, 0x46, 0x2d, 0x32, 0x34, 0x46, 0x42, 0x39, 0x39, 0x42, 0x30, 0x33,
+  0x46, 0x41, 0x35, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e,
+  0x0a, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x50, 0x61, 0x79,
+  0x6c, 0x6f, 0x61, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3c,
+  0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x69, 0x6e,
+  0x74, 0x65, 0x67, 0x65, 0x72, 0x3e, 0x31, 0x3c, 0x2f, 0x69, 0x6e, 0x74,
+  0x65, 0x67, 0x65, 0x72, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65,
+  0x79, 0x3e, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x53, 0x69, 0x6d, 0x70, 0x6c,
+  0x65, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c,
+  0x74, 0x72, 0x75, 0x65, 0x2f, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x6b,
+  0x65, 0x79, 0x3e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x50, 0x49, 0x4e, 0x3c,
+  0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x74, 0x72,
+  0x75, 0x65, 0x2f, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79,
+  0x3e, 0x6d, 0x69, 0x6e, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3c, 0x2f,
+  0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x72, 0x65, 0x61,
+  0x6c, 0x3e, 0x34, 0x3c, 0x2f, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x0a, 0x09,
+  0x09, 0x3c, 0x2f, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x3c, 0x2f,
+  0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x3c, 0x6b, 0x65, 0x79,
+  0x3e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x44, 0x65, 0x73, 0x63,
+  0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3c, 0x2f, 0x6b, 0x65, 0x79,
+  0x3e, 0x0a, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x50,
+  0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72,
+  0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x3c, 0x2f, 0x73, 0x74, 0x72,
+  0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x50,
+  0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61,
+  0x79, 0x4e, 0x61, 0x6d, 0x65, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a,
+  0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x34, 0x64, 0x69,
+  0x67, 0x69, 0x74, 0x73, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67,
+  0x3e, 0x0a, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x50, 0x61, 0x79, 0x6c,
+  0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65,
+  0x72, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x3c, 0x73, 0x74,
+  0x72, 0x69, 0x6e, 0x67, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70,
+  0x6c, 0x65, 0x2e, 0x70, 0x69, 0x6d, 0x70, 0x2e, 0x74, 0x65, 0x73, 0x74,
+  0x69, 0x6e, 0x67, 0x2e, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x34,
+  0x64, 0x69, 0x67, 0x69, 0x74, 0x73, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69,
+  0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x50, 0x61,
+  0x79, 0x6c, 0x6f, 0x61, 0x64, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a,
+  0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a,
+  0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x73, 0x61, 0x66,
+  0x73, 0x64, 0x66, 0x61, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67,
+  0x3e, 0x0a, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x50, 0x61, 0x79, 0x6c,
+  0x6f, 0x61, 0x64, 0x54, 0x79, 0x70, 0x65, 0x3c, 0x2f, 0x6b, 0x65, 0x79,
+  0x3e, 0x0a, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x43,
+  0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+  0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x3c,
+  0x6b, 0x65, 0x79, 0x3e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x55,
+  0x55, 0x49, 0x44, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x3c,
+  0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x43, 0x32, 0x46, 0x30, 0x37,
+  0x46, 0x38, 0x33, 0x2d, 0x43, 0x30, 0x35, 0x43, 0x2d, 0x34, 0x45, 0x32,
+  0x43, 0x2d, 0x38, 0x37, 0x31, 0x36, 0x2d, 0x36, 0x34, 0x46, 0x41, 0x33,
+  0x33, 0x42, 0x38, 0x46, 0x42, 0x34, 0x46, 0x3c, 0x2f, 0x73, 0x74, 0x72,
+  0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x50,
+  0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
+  0x6e, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x3c, 0x69, 0x6e,
+  0x74, 0x65, 0x67, 0x65, 0x72, 0x3e, 0x31, 0x3c, 0x2f, 0x69, 0x6e, 0x74,
+  0x65, 0x67, 0x65, 0x72, 0x3e, 0x0a, 0x3c, 0x2f, 0x64, 0x69, 0x63, 0x74,
+  0x3e, 0x0a, 0x3c, 0x2f, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x3e, 0x0a, 0xa0,
+  0x82, 0x06, 0x5c, 0x30, 0x82, 0x06, 0x58, 0x30, 0x82, 0x05, 0xc1, 0xa0,
+  0x03, 0x02, 0x01, 0x02, 0x02, 0x03, 0x00, 0xda, 0x16, 0x30, 0x0d, 0x06,
+  0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,
+  0x30, 0x82, 0x01, 0x12, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
+  0x06, 0x13, 0x02, 0x45, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55,
+  0x04, 0x08, 0x13, 0x09, 0x42, 0x61, 0x72, 0x63, 0x65, 0x6c, 0x6f, 0x6e,
+  0x61, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09,
+  0x42, 0x61, 0x72, 0x63, 0x65, 0x6c, 0x6f, 0x6e, 0x61, 0x31, 0x29, 0x30,
+  0x27, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x20, 0x49, 0x50, 0x53, 0x20,
+  0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+  0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20,
+  0x73, 0x2e, 0x6c, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04,
+  0x0a, 0x14, 0x25, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x40, 0x69,
+  0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x20, 0x43, 0x2e, 0x49,
+  0x2e, 0x46, 0x2e, 0x20, 0x20, 0x42, 0x2d, 0x42, 0x36, 0x32, 0x32, 0x31,
+  0x30, 0x36, 0x39, 0x35, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04,
+  0x0b, 0x13, 0x25, 0x69, 0x70, 0x73, 0x43, 0x41, 0x20, 0x43, 0x4c, 0x41,
+  0x53, 0x45, 0x41, 0x31, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+  0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
+  0x72, 0x69, 0x74, 0x79, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04,
+  0x03, 0x13, 0x25, 0x69, 0x70, 0x73, 0x43, 0x41, 0x20, 0x43, 0x4c, 0x41,
+  0x53, 0x45, 0x41, 0x31, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+  0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
+  0x72, 0x69, 0x74, 0x79, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86,
+  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x11, 0x67, 0x65, 0x6e,
+  0x65, 0x72, 0x61, 0x6c, 0x40, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63,
+  0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x38, 0x30, 0x38, 0x31, 0x32,
+  0x30, 0x36, 0x32, 0x35, 0x32, 0x32, 0x5a, 0x17, 0x0d, 0x31, 0x30, 0x30,
+  0x38, 0x31, 0x32, 0x30, 0x36, 0x32, 0x35, 0x32, 0x32, 0x5a, 0x30, 0x81,
+  0x97, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+  0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
+  0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31,
+  0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a, 0x53, 0x61,
+  0x6e, 0x74, 0x61, 0x20, 0x43, 0x72, 0x75, 0x7a, 0x31, 0x0d, 0x30, 0x0b,
+  0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x04, 0x55, 0x43, 0x53, 0x43, 0x31,
+  0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x03, 0x49, 0x54,
+  0x53, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x18,
+  0x61, 0x70, 0x70, 0x6c, 0x65, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74,
+  0x65, 0x73, 0x74, 0x2e, 0x75, 0x63, 0x73, 0x63, 0x2e, 0x65, 0x64, 0x75,
+  0x31, 0x1e, 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x09, 0x01, 0x16, 0x0f, 0x6e, 0x65, 0x74, 0x6f, 0x70, 0x73, 0x40,
+  0x75, 0x63, 0x73, 0x63, 0x2e, 0x65, 0x64, 0x75, 0x30, 0x81, 0x9f, 0x30,
+  0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
+  0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81,
+  0x00, 0xcd, 0x2d, 0x36, 0x7c, 0xc6, 0x45, 0x6a, 0x4b, 0x86, 0x39, 0xfb,
+  0xa4, 0xae, 0xc0, 0x48, 0x4c, 0x0f, 0x50, 0xb3, 0xa5, 0x60, 0x5b, 0xbd,
+  0xe1, 0xcf, 0xac, 0x1f, 0xab, 0x06, 0xb3, 0x46, 0x52, 0x75, 0x96, 0x54,
+  0xc5, 0xbb, 0x69, 0x1f, 0x23, 0x6f, 0x69, 0xb1, 0x49, 0x37, 0x3f, 0x32,
+  0xf6, 0xea, 0x27, 0xe2, 0xbc, 0x38, 0x21, 0x37, 0x2b, 0x9b, 0x02, 0x4c,
+  0xd2, 0x6e, 0x9c, 0x20, 0x37, 0x21, 0xfc, 0x0f, 0x78, 0x59, 0xac, 0x0f,
+  0x21, 0x35, 0xa0, 0x93, 0x5d, 0xf8, 0x07, 0x6c, 0x8d, 0x38, 0x07, 0xb6,
+  0x4f, 0x2d, 0xbf, 0x42, 0x6e, 0xe9, 0xb5, 0xc7, 0xe9, 0x55, 0xbf, 0xb8,
+  0x81, 0xf5, 0x43, 0x65, 0x02, 0x33, 0xca, 0x86, 0x48, 0xf2, 0xd8, 0xbb,
+  0x29, 0x6e, 0x0e, 0x9d, 0x88, 0x41, 0x82, 0x95, 0x2c, 0x3b, 0x18, 0xc6,
+  0xf4, 0x04, 0xe2, 0x84, 0x60, 0x9e, 0x32, 0xae, 0x43, 0x02, 0x03, 0x01,
+  0x00, 0x01, 0xa3, 0x82, 0x03, 0x32, 0x30, 0x82, 0x03, 0x2e, 0x30, 0x09,
+  0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x11, 0x06,
+  0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x01, 0x04, 0x04,
+  0x03, 0x02, 0x06, 0x40, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04,
+  0x04, 0x03, 0x02, 0x03, 0xf8, 0x30, 0x13, 0x06, 0x03, 0x55, 0x1d, 0x25,
+  0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+  0x03, 0x01, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
+  0x14, 0xdc, 0x34, 0x6b, 0x6a, 0xcb, 0x0c, 0xeb, 0x53, 0xb2, 0xeb, 0x49,
+  0xca, 0xe3, 0xf4, 0x8b, 0x44, 0x7e, 0x33, 0xae, 0x51, 0x30, 0x1f, 0x06,
+  0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x0e, 0x07,
+  0x60, 0xd4, 0x39, 0xc9, 0x1b, 0x5b, 0x5d, 0x90, 0x7b, 0x23, 0xc8, 0xd2,
+  0x34, 0x9d, 0x4a, 0x9a, 0x46, 0x39, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x1d,
+  0x11, 0x04, 0x13, 0x30, 0x11, 0x81, 0x0f, 0x6e, 0x65, 0x74, 0x6f, 0x70,
+  0x73, 0x40, 0x75, 0x63, 0x73, 0x63, 0x2e, 0x65, 0x64, 0x75, 0x30, 0x1c,
+  0x06, 0x03, 0x55, 0x1d, 0x12, 0x04, 0x15, 0x30, 0x13, 0x81, 0x11, 0x67,
+  0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x40, 0x69, 0x70, 0x73, 0x63, 0x61,
+  0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x72, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
+  0x86, 0xf8, 0x42, 0x01, 0x0d, 0x04, 0x65, 0x16, 0x63, 0x4f, 0x72, 0x67,
+  0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x6e,
+  0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4e, 0x4f,
+  0x54, 0x20, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x45, 0x44, 0x2e,
+  0x20, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x20, 0x53, 0x65, 0x72,
+  0x76, 0x65, 0x72, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+  0x61, 0x74, 0x65, 0x20, 0x69, 0x73, 0x73, 0x75, 0x65, 0x64, 0x20, 0x62,
+  0x79, 0x20, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77,
+  0x77, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+  0x30, 0x2f, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01,
+  0x02, 0x04, 0x22, 0x16, 0x20, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f,
+  0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63,
+  0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32,
+  0x2f, 0x30, 0x43, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42,
+  0x01, 0x04, 0x04, 0x36, 0x16, 0x34, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a,
+  0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e,
+  0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30,
+  0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x43,
+  0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x46,
+  0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x03, 0x04,
+  0x39, 0x16, 0x37, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77,
+  0x77, 0x77, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d,
+  0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x72,
+  0x65, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x4c, 0x41,
+  0x53, 0x45, 0x41, 0x31, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x3f, 0x30, 0x43,
+  0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x07, 0x04,
+  0x36, 0x16, 0x34, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77,
+  0x77, 0x77, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d,
+  0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x72,
+  0x65, 0x6e, 0x65, 0x77, 0x61, 0x6c, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41,
+  0x31, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x3f, 0x30, 0x41, 0x06, 0x09, 0x60,
+  0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x08, 0x04, 0x34, 0x16, 0x32,
+  0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e,
+  0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70,
+  0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x70, 0x6f, 0x6c, 0x69,
+  0x63, 0x79, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x68, 0x74,
+  0x6d, 0x6c, 0x30, 0x81, 0x83, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x7c,
+  0x30, 0x7a, 0x30, 0x39, 0xa0, 0x37, 0xa0, 0x35, 0x86, 0x33, 0x68, 0x74,
+  0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73,
+  0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61,
+  0x32, 0x30, 0x30, 0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30,
+  0x30, 0x32, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63, 0x72,
+  0x6c, 0x30, 0x3d, 0xa0, 0x3b, 0xa0, 0x39, 0x86, 0x37, 0x68, 0x74, 0x74,
+  0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x62, 0x61, 0x63, 0x6b, 0x2e,
+  0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70,
+  0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x69, 0x70, 0x73, 0x63,
+  0x61, 0x32, 0x30, 0x30, 0x32, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31,
+  0x2e, 0x63, 0x72, 0x6c, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+  0x05, 0x07, 0x01, 0x01, 0x04, 0x26, 0x30, 0x24, 0x30, 0x22, 0x06, 0x08,
+  0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x16, 0x68, 0x74,
+  0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x69, 0x70,
+  0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,
+  0x81, 0x81, 0x00, 0x80, 0x25, 0xd5, 0x3d, 0x12, 0x08, 0x27, 0x54, 0xc0,
+  0x57, 0x72, 0xcc, 0xa7, 0x08, 0xf8, 0xc5, 0x3f, 0x0c, 0xdd, 0x27, 0xdd,
+  0xb3, 0xf7, 0xcd, 0x78, 0xc4, 0xc8, 0x7c, 0xad, 0x9c, 0x15, 0xe5, 0x36,
+  0xa1, 0x69, 0xf8, 0x46, 0xe6, 0x71, 0x4c, 0x02, 0xe9, 0xad, 0xc2, 0x0b,
+  0xe1, 0x45, 0xf3, 0x86, 0x9f, 0x9a, 0x57, 0x99, 0x06, 0x4f, 0x4f, 0xeb,
+  0x2c, 0x33, 0xa0, 0x82, 0xa5, 0x66, 0x8e, 0xd6, 0x46, 0x61, 0x64, 0xac,
+  0x25, 0x8c, 0x9b, 0x70, 0x28, 0x8f, 0x81, 0xfa, 0x4f, 0x37, 0xc4, 0x8a,
+  0xa1, 0xd8, 0x79, 0x8e, 0x4c, 0x1a, 0x2f, 0x2e, 0x84, 0x1b, 0x6e, 0x85,
+  0xc1, 0xc6, 0x56, 0xda, 0xd4, 0xa3, 0x40, 0x85, 0xf2, 0x31, 0x10, 0x1a,
+  0x6d, 0x70, 0x5c, 0xf0, 0xd5, 0xdf, 0x71, 0x9d, 0x0e, 0xff, 0xf4, 0xb5,
+  0xa3, 0x80, 0x38, 0x43, 0x5b, 0x88, 0x81, 0x08, 0xf5, 0xcc, 0xb3, 0x31,
+  0x82, 0x02, 0x77, 0x30, 0x82, 0x02, 0x73, 0x02, 0x01, 0x01, 0x30, 0x82,
+  0x01, 0x1b, 0x30, 0x82, 0x01, 0x12, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+  0x55, 0x04, 0x06, 0x13, 0x02, 0x45, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06,
+  0x03, 0x55, 0x04, 0x08, 0x13, 0x09, 0x42, 0x61, 0x72, 0x63, 0x65, 0x6c,
+  0x6f, 0x6e, 0x61, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07,
+  0x13, 0x09, 0x42, 0x61, 0x72, 0x63, 0x65, 0x6c, 0x6f, 0x6e, 0x61, 0x31,
+  0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x20, 0x49, 0x50,
+  0x53, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+  0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
+  0x79, 0x20, 0x73, 0x2e, 0x6c, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03,
+  0x55, 0x04, 0x0a, 0x14, 0x25, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c,
+  0x40, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x20, 0x43,
+  0x2e, 0x49, 0x2e, 0x46, 0x2e, 0x20, 0x20, 0x42, 0x2d, 0x42, 0x36, 0x32,
+  0x32, 0x31, 0x30, 0x36, 0x39, 0x35, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03,
+  0x55, 0x04, 0x0b, 0x13, 0x25, 0x69, 0x70, 0x73, 0x43, 0x41, 0x20, 0x43,
+  0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
+  0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
+  0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03,
+  0x55, 0x04, 0x03, 0x13, 0x25, 0x69, 0x70, 0x73, 0x43, 0x41, 0x20, 0x43,
+  0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
+  0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
+  0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x11, 0x67,
+  0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x40, 0x69, 0x70, 0x73, 0x63, 0x61,
+  0x2e, 0x63, 0x6f, 0x6d, 0x02, 0x03, 0x00, 0xda, 0x16, 0x30, 0x09, 0x06,
+  0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0xa0, 0x81, 0xb1, 0x30,
+  0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x03,
+  0x31, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07,
+  0x01, 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x09, 0x05, 0x31, 0x0f, 0x17, 0x0d, 0x30, 0x38, 0x30, 0x38, 0x32, 0x33,
+  0x30, 0x31, 0x32, 0x34, 0x30, 0x37, 0x5a, 0x30, 0x23, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04, 0x31, 0x16, 0x04, 0x14,
+  0x71, 0xee, 0xac, 0x4e, 0xfd, 0x6d, 0x8c, 0x6c, 0xb9, 0x7c, 0xfe, 0x4e,
+  0x7c, 0x70, 0x08, 0xe1, 0xc4, 0xd9, 0x1f, 0x07, 0x30, 0x52, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x0f, 0x31, 0x45, 0x30,
+  0x43, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03,
+  0x07, 0x30, 0x0e, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03,
+  0x02, 0x02, 0x02, 0x00, 0x80, 0x30, 0x0d, 0x06, 0x08, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x03, 0x02, 0x02, 0x01, 0x40, 0x30, 0x07, 0x06, 0x05,
+  0x2b, 0x0e, 0x03, 0x02, 0x07, 0x30, 0x0d, 0x06, 0x08, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x03, 0x02, 0x02, 0x01, 0x28, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04,
+  0x81, 0x80, 0x0f, 0x7e, 0xb2, 0x55, 0x9c, 0x10, 0x28, 0x35, 0x37, 0xb3,
+  0x65, 0x04, 0x10, 0xe1, 0xb4, 0xe9, 0xa0, 0xa8, 0x8a, 0x9d, 0x44, 0xba,
+  0x39, 0xae, 0x64, 0x9f, 0x2e, 0x64, 0x7e, 0x96, 0x07, 0xc1, 0xd1, 0x59,
+  0x5c, 0xf1, 0x5d, 0x27, 0x63, 0x00, 0x9d, 0xed, 0x04, 0x41, 0xfc, 0x0d,
+  0xc8, 0xeb, 0x2c, 0x5d, 0xa6, 0xec, 0xb0, 0xa5, 0x07, 0xf8, 0xb2, 0x28,
+  0x1d, 0x42, 0xa3, 0xd3, 0xbf, 0xb2, 0x66, 0x4f, 0x71, 0x50, 0x70, 0xf7,
+  0x60, 0xeb, 0xa4, 0xfc, 0xcb, 0x62, 0x82, 0x98, 0xb6, 0x63, 0x19, 0xca,
+  0xb9, 0x35, 0xb0, 0x56, 0x5a, 0x11, 0x00, 0x81, 0xe8, 0xd1, 0xa2, 0x63,
+  0xcb, 0x38, 0xb3, 0xbd, 0x65, 0xb6, 0xa2, 0x36, 0x9c, 0x54, 0xc2, 0x05,
+  0xb0, 0x27, 0x2e, 0x57, 0x26, 0x0d, 0xb4, 0x8e, 0xb7, 0x9e, 0x3f, 0x89,
+  0xc8, 0x98, 0x3d, 0x06, 0xe0, 0x7f, 0x3e, 0xed, 0x8e, 0xa3
+};
+
+static unsigned char openssl_generated_cms[] = {
+  0x30, 0x82, 0x05, 0xcd, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x07, 0x02, 0xa0, 0x82, 0x05, 0xbe, 0x30, 0x82, 0x05, 0xba, 0x02,
+  0x01, 0x01, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
+  0x1a, 0x05, 0x00, 0x30, 0x1b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x01, 0x07, 0x01, 0xa0, 0x0e, 0x04, 0x0c, 0x77, 0x68, 0x61, 0x74,
+  0x65, 0x76, 0x65, 0x72, 0x20, 0x6d, 0x61, 0x6e, 0xa0, 0x82, 0x03, 0xa7,
+  0x30, 0x82, 0x03, 0xa3, 0x30, 0x82, 0x02, 0x8b, 0xa0, 0x03, 0x02, 0x01,
+  0x02, 0x02, 0x01, 0x2a, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x7e, 0x31, 0x0b, 0x30,
+  0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
+  0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70,
+  0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06,
+  0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20,
+  0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+  0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31,
+  0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x29, 0x41, 0x70,
+  0x70, 0x6c, 0x65, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x42,
+  0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+  0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+  0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x38, 0x30, 0x32, 0x30,
+  0x31, 0x30, 0x30, 0x35, 0x35, 0x35, 0x36, 0x5a, 0x17, 0x0d, 0x30, 0x38,
+  0x30, 0x33, 0x30, 0x32, 0x30, 0x30, 0x35, 0x35, 0x35, 0x36, 0x5a, 0x30,
+  0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+  0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+  0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
+  0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x29, 0x41, 0x70,
+  0x70, 0x6c, 0x65, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x42,
+  0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+  0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+  0x69, 0x74, 0x79, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03,
+  0x13, 0x13, 0x53, 0x35, 0x4c, 0x38, 0x39, 0x30, 0x30, 0x20, 0x53, 0x65,
+  0x63, 0x75, 0x72, 0x65, 0x20, 0x42, 0x6f, 0x6f, 0x74, 0x30, 0x81, 0x9f,
+  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+  0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81,
+  0x81, 0x00, 0xb2, 0x17, 0xb7, 0x7e, 0x97, 0x30, 0xa9, 0x54, 0x90, 0xc8,
+  0x5e, 0x5d, 0x76, 0x5a, 0x88, 0xf1, 0x9a, 0x0b, 0x16, 0x5b, 0x45, 0x87,
+  0xa0, 0x94, 0x71, 0xe1, 0x6a, 0x7a, 0xc1, 0x1a, 0x30, 0x57, 0xb0, 0xda,
+  0x9e, 0x55, 0xbf, 0x2c, 0xdd, 0xc6, 0x99, 0x74, 0x4a, 0x41, 0x26, 0x95,
+  0xd7, 0x71, 0x09, 0x82, 0x4a, 0xc6, 0x02, 0x0c, 0x10, 0xdc, 0x5f, 0x0a,
+  0xa5, 0xe1, 0x47, 0x59, 0xfa, 0xad, 0x04, 0x49, 0xe3, 0x0f, 0xa6, 0x48,
+  0xcb, 0xd5, 0x65, 0xa6, 0x53, 0x80, 0x03, 0xe6, 0x22, 0xc9, 0x8a, 0x26,
+  0x0f, 0x4d, 0x13, 0x37, 0x41, 0x4b, 0x5c, 0x78, 0x0f, 0x2c, 0x65, 0xa7,
+  0x96, 0xfa, 0x81, 0x7b, 0x02, 0xba, 0x3e, 0x9d, 0xbd, 0xe8, 0x70, 0x1b,
+  0x76, 0xcc, 0x69, 0x13, 0x2f, 0x42, 0xea, 0x92, 0x64, 0xf8, 0xf6, 0xa7,
+  0x17, 0xd7, 0xf6, 0x40, 0x43, 0x5e, 0x4c, 0x8e, 0xae, 0xe3, 0x02, 0x03,
+  0x01, 0x00, 0x01, 0xa3, 0x81, 0xb9, 0x30, 0x81, 0xb6, 0x30, 0x0b, 0x06,
+  0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x1d,
+  0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xc5, 0x0e, 0x2c,
+  0x3c, 0x02, 0x26, 0xe3, 0x4a, 0x4b, 0x51, 0x47, 0xab, 0x78, 0x4a, 0x6a,
+  0xb3, 0x60, 0xd2, 0x13, 0x0c, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23,
+  0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xc4, 0x7c, 0x23, 0x6e, 0x51, 0xbc,
+  0xae, 0xd8, 0x36, 0x94, 0x68, 0x42, 0x30, 0x79, 0xb7, 0xa9, 0x2b, 0x9d,
+  0x3b, 0xbc, 0x30, 0x67, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63,
+  0x64, 0x06, 0x01, 0x01, 0x01, 0x01, 0xff, 0x04, 0x56, 0x04, 0x54, 0x33,
+  0x67, 0x6d, 0x49, 0x54, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x74, 0x72, 0x65, 0x63, 0x4d, 0x4f, 0x44, 0x53, 0x10,
+  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x44,
+  0x4f, 0x52, 0x50, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x50, 0x49, 0x48, 0x43, 0x10, 0x00, 0x00, 0x00, 0x04,
+  0x00, 0x00, 0x00, 0x20, 0x87, 0x00, 0x00, 0x44, 0x52, 0x4f, 0x42, 0x10,
+  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
+  0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
+  0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x13, 0x94, 0x2a, 0x47, 0xee,
+  0xaf, 0xa5, 0xd1, 0xf7, 0x39, 0x73, 0x6b, 0x01, 0xd7, 0xe8, 0x7f, 0x61,
+  0xaf, 0x2a, 0x3e, 0x6a, 0xc9, 0x51, 0xd9, 0xb1, 0xe5, 0x1d, 0x0d, 0xe9,
+  0x22, 0x4d, 0xcd, 0x9e, 0x87, 0x43, 0x7d, 0x02, 0x34, 0x42, 0x92, 0x8b,
+  0xd7, 0x25, 0xc2, 0xee, 0xc2, 0xc4, 0xce, 0xbf, 0x6b, 0xa8, 0xf1, 0xe6,
+  0x73, 0xaa, 0x94, 0x11, 0x31, 0xdc, 0xbf, 0xce, 0x54, 0x52, 0xd0, 0xed,
+  0xbc, 0x89, 0x0e, 0x7d, 0x8a, 0xe9, 0xce, 0x2e, 0x9d, 0x9f, 0x27, 0xfa,
+  0xf7, 0x43, 0xeb, 0x80, 0xd4, 0x06, 0xb3, 0x0c, 0x05, 0x73, 0x1b, 0xc3,
+  0x1f, 0xc4, 0x19, 0x6d, 0xba, 0xac, 0x88, 0xd0, 0x15, 0x82, 0x22, 0x50,
+  0xb7, 0x88, 0xcc, 0xfa, 0x56, 0x74, 0x65, 0x39, 0xb4, 0x9a, 0xb2, 0xdc,
+  0x5c, 0x2b, 0x2b, 0x14, 0x26, 0xa6, 0xb7, 0xb8, 0x52, 0xb2, 0x46, 0x09,
+  0x3d, 0x1c, 0xfd, 0x7a, 0x6e, 0x4a, 0x90, 0x23, 0xd1, 0x62, 0x20, 0x1f,
+  0xff, 0x6c, 0xdb, 0xbd, 0xcf, 0x71, 0x85, 0x49, 0x54, 0x13, 0x3c, 0xdd,
+  0x99, 0xf2, 0x22, 0xb5, 0x08, 0x30, 0xad, 0x92, 0xf3, 0xb0, 0x45, 0x01,
+  0xfa, 0x98, 0x49, 0x44, 0x45, 0xa1, 0x9c, 0x0a, 0xd1, 0x65, 0x0a, 0xc0,
+  0x29, 0x5b, 0x68, 0x34, 0x16, 0x3b, 0x7b, 0x15, 0xbe, 0xac, 0x8a, 0x99,
+  0x0e, 0x1d, 0x3b, 0x9d, 0x16, 0x9a, 0xf5, 0x35, 0x25, 0xcc, 0xa5, 0xa9,
+  0xb9, 0x84, 0x96, 0xc0, 0xf2, 0x7d, 0x72, 0x4f, 0x7a, 0x3b, 0x12, 0x66,
+  0xfc, 0xf9, 0x02, 0x39, 0x39, 0xf2, 0x99, 0xae, 0xe7, 0xa1, 0x4b, 0x7a,
+  0xcc, 0x23, 0x91, 0xec, 0x27, 0xbd, 0xfc, 0xf2, 0x6c, 0x06, 0xa7, 0xbd,
+  0x1d, 0x40, 0xbf, 0xa5, 0xf9, 0x40, 0x4a, 0xf7, 0x4a, 0x1d, 0x3f, 0xa7,
+  0x47, 0x4d, 0xa2, 0x2b, 0x53, 0x2b, 0x09, 0xe7, 0xdf, 0xa8, 0x39, 0x31,
+  0x82, 0x01, 0xde, 0x30, 0x82, 0x01, 0xda, 0x02, 0x01, 0x01, 0x30, 0x81,
+  0x83, 0x30, 0x7e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+  0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
+  0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63,
+  0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d,
+  0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+  0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68,
+  0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55,
+  0x04, 0x03, 0x13, 0x29, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x53, 0x65,
+  0x63, 0x75, 0x72, 0x65, 0x20, 0x42, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65,
+  0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
+  0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x02, 0x01, 0x2a,
+  0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0xa0,
+  0x81, 0xb1, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x09, 0x03, 0x31, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x09, 0x05, 0x31, 0x0f, 0x17, 0x0d, 0x30, 0x38, 0x30,
+  0x32, 0x31, 0x32, 0x32, 0x30, 0x33, 0x32, 0x33, 0x30, 0x5a, 0x30, 0x23,
+  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04, 0x31,
+  0x16, 0x04, 0x14, 0xd1, 0x59, 0x39, 0x09, 0xcb, 0x32, 0x40, 0x5c, 0xa6,
+  0x1a, 0x86, 0xa2, 0x2d, 0xbc, 0x74, 0x72, 0xae, 0x2b, 0x92, 0x45, 0x30,
+  0x52, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x0f,
+  0x31, 0x45, 0x30, 0x43, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x03, 0x07, 0x30, 0x0e, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x03, 0x02, 0x02, 0x02, 0x00, 0x80, 0x30, 0x0d, 0x06, 0x08,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x02, 0x02, 0x01, 0x40, 0x30,
+  0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x07, 0x30, 0x0d, 0x06, 0x08,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x02, 0x02, 0x01, 0x28, 0x30,
+  0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
+  0x05, 0x00, 0x04, 0x81, 0x80, 0x71, 0x1d, 0xe4, 0xcf, 0xa6, 0xfe, 0x18,
+  0x20, 0x9c, 0xa8, 0x9a, 0x80, 0x03, 0x19, 0x61, 0x75, 0x47, 0x74, 0xe7,
+  0xcc, 0xe8, 0x6e, 0x4c, 0x75, 0xfe, 0x10, 0x3c, 0x11, 0xd7, 0x1d, 0x64,
+  0xef, 0xff, 0xbc, 0x95, 0x1b, 0x7b, 0x75, 0xec, 0x53, 0x50, 0xc1, 0x84,
+  0x53, 0xfd, 0x91, 0x1f, 0x55, 0x0e, 0x7b, 0x5b, 0x6e, 0x50, 0xe4, 0xad,
+  0x86, 0xc0, 0x37, 0x6b, 0x09, 0x69, 0xb9, 0xd5, 0xef, 0xa7, 0xac, 0x43,
+  0xc7, 0x1b, 0xf9, 0x87, 0x30, 0xf8, 0x0f, 0x1a, 0x55, 0xce, 0x8f, 0xb6,
+  0xcd, 0x4e, 0x8e, 0xbb, 0xee, 0x66, 0x6f, 0xe9, 0xf8, 0xa9, 0xb2, 0x90,
+  0x2c, 0x1f, 0xd3, 0x79, 0xfa, 0x17, 0x2f, 0xcd, 0xac, 0x04, 0x9c, 0x74,
+  0x2a, 0xdf, 0x46, 0x09, 0xe3, 0x37, 0xe0, 0x71, 0xa2, 0x3c, 0x6f, 0x7e,
+  0xd8, 0x0d, 0xd6, 0xcc, 0xfc, 0x69, 0x53, 0xa6, 0x1c, 0x37, 0x39, 0x9c,
+  0xd1
+};
+
+
+static unsigned char _codedir_bytes[] = {
+  0x00, 0x02, 0x00, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x2c,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x3f, 0x60,
+  0x14, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6d, 0x2e,
+  0x79, 0x6f, 0x75, 0x72, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e,
+  0x57, 0x68, 0x69, 0x63, 0x68, 0x57, 0x61, 0x79, 0x49, 0x73, 0x55, 0x70,
+  0x00, 0x99, 0xd8, 0xaf, 0x66, 0xa8, 0xb5, 0x8b, 0x53, 0x47, 0x52, 0xe5,
+  0xb9, 0xab, 0x5f, 0x0c, 0xe6, 0x5b, 0x8c, 0x3f, 0xa1, 0x3a, 0x75, 0xf6,
+  0xdb, 0x05, 0x85, 0x29, 0x14, 0x8e, 0x14, 0xdd, 0x7e, 0xa1, 0xb4, 0x72,
+  0x9c, 0xc0, 0x9e, 0xc9, 0x73, 0x8e, 0x4e, 0xcc, 0x66, 0xa6, 0x77, 0x71,
+  0x16, 0x0b, 0x09, 0xfb, 0x31, 0x79, 0x2a, 0xab, 0x0d, 0x5f, 0xf4, 0x08,
+  0x03, 0xe8, 0x8e, 0x40, 0x22, 0x9e, 0x86, 0x08, 0x62, 0xbc, 0xf3, 0x6b,
+  0x37, 0x88, 0x07, 0xd7, 0xb1, 0x20, 0xb6, 0x84, 0x1a, 0xbf, 0x0b, 0x96,
+  0x42, 0x02, 0x8a, 0x4d, 0x73, 0xeb, 0x2d, 0x6a, 0xa7, 0x84, 0x01, 0xde,
+  0xf3, 0x65, 0x0d, 0x75, 0x58, 0x5e, 0xde, 0x72, 0x8e, 0x5a, 0xf2, 0x8c,
+  0x29, 0xa3, 0xe2, 0x24, 0xbc, 0x48, 0xb5, 0x27, 0x3e, 0x21, 0x6c, 0xee,
+  0xe0, 0xd3, 0x73, 0x5b, 0xaa, 0x86, 0x71, 0x46, 0xa5, 0xe5, 0x4e, 0x2a,
+  0x77, 0x54, 0x65, 0x1d, 0x27, 0x35, 0x5a, 0xfc, 0xfb, 0xfa, 0xde, 0x0c,
+  0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
+
+};
+static unsigned int _codedir_len = 0xd5;
+
+static unsigned char fk_cms[] = {
+  0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07,
+  0x02, 0xa0, 0x80, 0x30, 0x80, 0x02, 0x01, 0x01, 0x31, 0x0b, 0x30, 0x09,
+  0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x30, 0x80, 0x06,
+  0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x00, 0x00,
+  0xa0, 0x82, 0x0c, 0x48, 0x30, 0x82, 0x03, 0x8e, 0x30, 0x82, 0x02, 0x76,
+  0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x17, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
+  0x79, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+  0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+  0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
+  0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70,
+  0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+  0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+  0x69, 0x74, 0x79, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04, 0x03,
+  0x13, 0x24, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x69, 0x50, 0x68, 0x6f,
+  0x6e, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
+  0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
+  0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x38, 0x30, 0x35, 0x30, 0x32,
+  0x32, 0x30, 0x31, 0x30, 0x30, 0x38, 0x5a, 0x17, 0x0d, 0x30, 0x39, 0x30,
+  0x35, 0x30, 0x32, 0x32, 0x30, 0x31, 0x30, 0x30, 0x38, 0x5a, 0x30, 0x5a,
+  0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+  0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a,
+  0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x36,
+  0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2d, 0x54, 0x45, 0x53,
+  0x54, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x69, 0x50, 0x68, 0x6f,
+  0x6e, 0x65, 0x20, 0x4f, 0x53, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63,
+  0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e,
+  0x67, 0x20, 0x54, 0x45, 0x53, 0x54, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06,
+  0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
+  0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xd6,
+  0x73, 0xa4, 0x41, 0xc5, 0x02, 0x35, 0xbb, 0x66, 0xb4, 0xd4, 0x60, 0x42,
+  0x36, 0xea, 0x09, 0x5f, 0x8e, 0x6d, 0xf1, 0x57, 0xdd, 0xe5, 0x3a, 0x7d,
+  0x77, 0xc1, 0x8e, 0xce, 0x34, 0x8b, 0xfc, 0xd6, 0x86, 0xe2, 0x5b, 0x2c,
+  0x1d, 0x61, 0x38, 0x5f, 0x0a, 0x01, 0x78, 0x75, 0x3a, 0xd3, 0x7c, 0x03,
+  0xb9, 0xef, 0x76, 0x73, 0x2b, 0xd0, 0xcc, 0xf3, 0x40, 0xb6, 0x1f, 0xf2,
+  0x52, 0x05, 0x57, 0xb1, 0xff, 0x43, 0xa8, 0xf2, 0x4d, 0x3f, 0xd4, 0x55,
+  0x7b, 0xb1, 0x97, 0xc5, 0x70, 0xf1, 0x78, 0xa0, 0x07, 0x63, 0x3c, 0x2f,
+  0xcd, 0xf7, 0x22, 0xd3, 0xce, 0xa1, 0x88, 0xb0, 0x58, 0xd4, 0x00, 0x89,
+  0x3b, 0xd8, 0xea, 0x18, 0x46, 0x21, 0x79, 0x6e, 0x36, 0x6f, 0xfa, 0xaa,
+  0xcc, 0xc2, 0x8d, 0xf0, 0xfd, 0x74, 0xac, 0x5a, 0x6c, 0xab, 0x69, 0xb1,
+  0xe4, 0xd8, 0xa2, 0x6d, 0x0c, 0x8e, 0x0d, 0x02, 0x03, 0x01, 0x00, 0x01,
+  0xa3, 0x81, 0xc3, 0x30, 0x81, 0xc0, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d,
+  0x0f, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x0c, 0x06, 0x03, 0x55,
+  0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x16, 0x06,
+  0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x0c, 0x30, 0x0a, 0x06,
+  0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03, 0x30, 0x11, 0x06,
+  0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x06, 0x01, 0x03, 0x01,
+  0x04, 0x02, 0x05, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
+  0x16, 0x04, 0x14, 0xdb, 0x1d, 0xec, 0xe2, 0x32, 0x88, 0xb0, 0xd7, 0x69,
+  0x9c, 0x53, 0x52, 0xc3, 0x67, 0x6b, 0x2f, 0xb5, 0xf8, 0xdb, 0x88, 0x30,
+  0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
+  0xe7, 0x34, 0x2a, 0x2e, 0x22, 0xde, 0x39, 0x60, 0x6b, 0xb4, 0x94, 0xce,
+  0x77, 0x83, 0x61, 0x2f, 0x31, 0xa0, 0x7c, 0x35, 0x30, 0x38, 0x06, 0x03,
+  0x55, 0x1d, 0x1f, 0x04, 0x31, 0x30, 0x2f, 0x30, 0x2d, 0xa0, 0x2b, 0xa0,
+  0x29, 0x86, 0x27, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77,
+  0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+  0x61, 0x70, 0x70, 0x6c, 0x65, 0x63, 0x61, 0x2f, 0x69, 0x70, 0x68, 0x6f,
+  0x6e, 0x65, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01,
+  0x01, 0x00, 0x69, 0xc4, 0x9c, 0x59, 0x97, 0x0f, 0xc8, 0x4e, 0xb3, 0xc7,
+  0x87, 0x15, 0x4b, 0x45, 0x06, 0x8a, 0x59, 0x48, 0x72, 0x0b, 0xab, 0xb1,
+  0x26, 0x4a, 0x86, 0x1d, 0x73, 0xba, 0x38, 0xef, 0x69, 0x74, 0x9b, 0x69,
+  0x06, 0x62, 0x97, 0x31, 0xe8, 0xae, 0xf5, 0xc2, 0x5b, 0x12, 0x16, 0x29,
+  0xc2, 0xae, 0x49, 0x54, 0x66, 0x45, 0x1a, 0xa9, 0xa2, 0x86, 0xa7, 0x6e,
+  0xcb, 0xe9, 0x76, 0xf1, 0x24, 0x64, 0x32, 0xde, 0x13, 0x25, 0xe7, 0x4e,
+  0xdc, 0x8c, 0xe6, 0x60, 0x7a, 0xe1, 0x80, 0x6a, 0x01, 0x04, 0x3d, 0x77,
+  0xb8, 0x5a, 0x82, 0x71, 0xb3, 0x59, 0x77, 0x9c, 0xfa, 0xac, 0xc7, 0x62,
+  0x48, 0x3b, 0xce, 0xf0, 0x9c, 0x51, 0x34, 0x72, 0x72, 0x55, 0x00, 0x2f,
+  0x53, 0x32, 0x0e, 0xf9, 0x1d, 0x0d, 0x6f, 0xd4, 0x84, 0xe2, 0xff, 0x0d,
+  0x88, 0x2b, 0x99, 0x53, 0x55, 0xab, 0x89, 0xa6, 0xa9, 0x6d, 0xd1, 0xad,
+  0x6c, 0x21, 0x40, 0x57, 0xc4, 0x44, 0x8f, 0x18, 0x79, 0x7e, 0xdd, 0xa5,
+  0x0e, 0xad, 0x5b, 0x96, 0x44, 0x58, 0xd7, 0x46, 0x64, 0x5a, 0x07, 0x81,
+  0x09, 0xe7, 0x78, 0x7e, 0x8b, 0x99, 0xa1, 0x12, 0xbe, 0x27, 0x0a, 0x29,
+  0x9b, 0xd1, 0xa9, 0x84, 0xff, 0x0e, 0x1f, 0x83, 0xb4, 0x04, 0x20, 0x8b,
+  0xd2, 0xe2, 0x9b, 0xcc, 0x66, 0xf5, 0xa6, 0x1d, 0x25, 0x70, 0x3a, 0xff,
+  0x43, 0x19, 0xfa, 0x94, 0xb9, 0x78, 0x66, 0x0b, 0xb7, 0xec, 0x33, 0xc0,
+  0x82, 0x93, 0x91, 0x4f, 0x79, 0x0d, 0x78, 0xdc, 0xd6, 0xad, 0xd1, 0x32,
+  0xa5, 0xf5, 0xaf, 0xe3, 0xd1, 0x86, 0x70, 0xa0, 0x0a, 0x8e, 0x20, 0x68,
+  0x62, 0x94, 0xe8, 0x1f, 0xc6, 0xdd, 0x62, 0xc9, 0xaa, 0x8b, 0xc8, 0x30,
+  0x2f, 0x8a, 0xe3, 0x51, 0xc3, 0x8f, 0x1a, 0x99, 0x87, 0x07, 0x00, 0xf5,
+  0x84, 0xb5, 0xad, 0x7c, 0x0d, 0x7b, 0x30, 0x82, 0x03, 0xf3, 0x30, 0x82,
+  0x02, 0xdb, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x17, 0x30, 0x0d,
+  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
+  0x00, 0x30, 0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+  0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
+  0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63,
+  0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d,
+  0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+  0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68,
+  0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55,
+  0x04, 0x03, 0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f,
+  0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x37, 0x30,
+  0x34, 0x31, 0x32, 0x31, 0x37, 0x34, 0x33, 0x32, 0x38, 0x5a, 0x17, 0x0d,
+  0x32, 0x32, 0x30, 0x34, 0x31, 0x32, 0x31, 0x37, 0x34, 0x33, 0x32, 0x38,
+  0x5a, 0x30, 0x79, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+  0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
+  0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63,
+  0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d,
+  0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+  0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68,
+  0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55,
+  0x04, 0x03, 0x13, 0x24, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x69, 0x50,
+  0x68, 0x6f, 0x6e, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+  0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
+  0x72, 0x69, 0x74, 0x79, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
+  0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
+  0x00, 0xa3, 0x1e, 0xbe, 0xf0, 0x47, 0xc0, 0xb4, 0x9e, 0x10, 0x5b, 0x46,
+  0xa4, 0xb8, 0x21, 0xb8, 0x4f, 0x86, 0x21, 0x70, 0x28, 0x45, 0x60, 0x5c,
+  0x1c, 0xc3, 0xc8, 0x0a, 0x64, 0x63, 0x88, 0xfb, 0xfc, 0x69, 0xee, 0xf8,
+  0x54, 0xfc, 0xe9, 0x5b, 0xb7, 0x06, 0x4e, 0x04, 0x2f, 0xc3, 0x6b, 0x33,
+  0xaf, 0x44, 0x4c, 0xea, 0x4b, 0x80, 0x09, 0xb4, 0x87, 0xf6, 0x5b, 0xb4,
+  0xfd, 0x64, 0xdd, 0xb3, 0x72, 0xe0, 0x13, 0xb3, 0xfd, 0x17, 0xd9, 0xbc,
+  0xe7, 0xa8, 0xed, 0xc2, 0x8c, 0x61, 0xc2, 0x2a, 0xf9, 0xec, 0xce, 0xa5,
+  0x5e, 0xd6, 0x69, 0xeb, 0x64, 0x0b, 0x8d, 0x08, 0x8f, 0xb8, 0xa0, 0x50,
+  0x46, 0x09, 0xdc, 0x19, 0xe4, 0xe5, 0xb0, 0x94, 0x6d, 0xbb, 0xf7, 0x99,
+  0x98, 0xc4, 0xe8, 0x9b, 0x41, 0x4e, 0xd4, 0xf1, 0x65, 0xe3, 0x1b, 0x52,
+  0x7a, 0xdc, 0xe8, 0x03, 0xd9, 0x6e, 0x1d, 0xda, 0x10, 0x55, 0x86, 0xa4,
+  0x29, 0x58, 0x49, 0x0c, 0xea, 0x47, 0xd7, 0x15, 0x34, 0x33, 0xf6, 0xc0,
+  0xa0, 0x44, 0x4a, 0x70, 0xbe, 0x2c, 0xb5, 0x2a, 0x30, 0x37, 0x8c, 0x2e,
+  0x15, 0xeb, 0xd1, 0xe4, 0x6c, 0x97, 0x38, 0x55, 0x56, 0xb1, 0x35, 0x2b,
+  0x58, 0xea, 0x44, 0xa3, 0x26, 0x85, 0xee, 0xc8, 0x66, 0x4a, 0xe4, 0xcf,
+  0x89, 0xf0, 0x3d, 0x63, 0xad, 0x29, 0xde, 0xad, 0xba, 0x5a, 0xb3, 0xdc,
+  0xa5, 0xa3, 0x9a, 0xa7, 0x09, 0x4e, 0x80, 0x16, 0x35, 0x65, 0xa4, 0x85,
+  0x0d, 0x63, 0x7b, 0x3e, 0x63, 0x8a, 0xda, 0x7d, 0x4a, 0x46, 0xec, 0xa3,
+  0x39, 0x18, 0x34, 0xb9, 0xc6, 0x28, 0x65, 0x18, 0xbc, 0x13, 0x60, 0x9c,
+  0x7f, 0x57, 0xac, 0x14, 0xc9, 0x89, 0xed, 0xa1, 0xb6, 0x87, 0x68, 0x52,
+  0xb6, 0x84, 0x4e, 0xb8, 0xc8, 0x83, 0xec, 0xf9, 0x9e, 0x19, 0xab, 0xb3,
+  0xc1, 0x0b, 0x86, 0xc7, 0x9f, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81,
+  0x9c, 0x30, 0x81, 0x99, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
+  0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x0f, 0x06, 0x03,
+  0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01,
+  0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
+  0xe7, 0x34, 0x2a, 0x2e, 0x22, 0xde, 0x39, 0x60, 0x6b, 0xb4, 0x94, 0xce,
+  0x77, 0x83, 0x61, 0x2f, 0x31, 0xa0, 0x7c, 0x35, 0x30, 0x1f, 0x06, 0x03,
+  0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x2b, 0xd0, 0x69,
+  0x47, 0x94, 0x76, 0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e, 0x40, 0xa6, 0xf7,
+  0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x36, 0x06, 0x03, 0x55, 0x1d, 0x1f,
+  0x04, 0x2f, 0x30, 0x2d, 0x30, 0x2b, 0xa0, 0x29, 0xa0, 0x27, 0x86, 0x25,
+  0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61,
+  0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x70,
+  0x6c, 0x65, 0x63, 0x61, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72,
+  0x6c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x1d, 0xd1, 0xd5,
+  0x7b, 0xdd, 0x74, 0x4e, 0xd7, 0x17, 0xfc, 0x82, 0x2d, 0x0c, 0x99, 0x9b,
+  0x5e, 0x42, 0x72, 0xf2, 0x69, 0xdc, 0xd5, 0x6b, 0x5e, 0x0d, 0x0c, 0x6b,
+  0x4b, 0x3e, 0x7b, 0x14, 0x25, 0xde, 0xb3, 0x94, 0xe8, 0xa0, 0xfa, 0x0f,
+  0x80, 0x89, 0xf2, 0x17, 0x3d, 0x00, 0x02, 0xa2, 0x91, 0x91, 0xbe, 0x74,
+  0x57, 0xdc, 0xaf, 0x9a, 0x9f, 0xa1, 0x0a, 0x7d, 0x30, 0xbe, 0x00, 0x2a,
+  0xcc, 0x21, 0x59, 0xeb, 0xfd, 0x49, 0xac, 0x6e, 0x75, 0x19, 0xe8, 0x9a,
+  0x7a, 0x03, 0xd1, 0x86, 0xf6, 0xe7, 0xf6, 0xb0, 0x0e, 0x4b, 0x49, 0xfa,
+  0xa3, 0xb7, 0x41, 0xba, 0xd7, 0xd1, 0xe3, 0x56, 0xa1, 0x7d, 0x83, 0xab,
+  0x97, 0xae, 0xf8, 0x51, 0x4a, 0x26, 0xc1, 0x85, 0x42, 0x13, 0x26, 0x8d,
+  0x03, 0x54, 0x66, 0x10, 0x5e, 0x60, 0x84, 0x05, 0x12, 0x31, 0x2b, 0x6b,
+  0x54, 0xc0, 0xa0, 0xc8, 0x41, 0xbc, 0x54, 0x1e, 0xe7, 0x54, 0xad, 0x13,
+  0x00, 0xd2, 0x4a, 0xc7, 0xbb, 0xc1, 0x8a, 0xaf, 0x81, 0x08, 0x8e, 0xf0,
+  0x46, 0x0a, 0xbf, 0x27, 0xa6, 0xbe, 0xdc, 0xcf, 0x39, 0x3a, 0x80, 0x70,
+  0x19, 0x23, 0x32, 0xa3, 0x6b, 0x66, 0x5d, 0x9e, 0x4d, 0xa8, 0x47, 0x49,
+  0xb2, 0x7b, 0x45, 0xb5, 0x51, 0x33, 0xa7, 0x74, 0x67, 0x09, 0x4e, 0xb6,
+  0x6c, 0x6f, 0x48, 0xf7, 0x2c, 0xb9, 0x33, 0x05, 0x44, 0x6b, 0x45, 0xbe,
+  0x74, 0x4b, 0x6f, 0xb2, 0x86, 0x91, 0xb4, 0x3e, 0x25, 0x28, 0x25, 0x9e,
+  0xb3, 0xc2, 0x51, 0x86, 0xfc, 0x4f, 0xe5, 0xaf, 0x3b, 0xaa, 0xbb, 0x44,
+  0x2c, 0x01, 0x49, 0xe2, 0x74, 0xb3, 0x34, 0xfa, 0x44, 0xef, 0x14, 0xc2,
+  0x11, 0xf2, 0x2d, 0x19, 0x1a, 0x51, 0x89, 0xd3, 0x08, 0x4a, 0x41, 0x6c,
+  0x58, 0x56, 0xde, 0x9b, 0x3a, 0xe1, 0x05, 0x57, 0xe5, 0x62, 0xcf, 0xd2,
+  0x0f, 0x30, 0x82, 0x04, 0xbb, 0x30, 0x82, 0x03, 0xa3, 0xa0, 0x03, 0x02,
+  0x01, 0x02, 0x02, 0x01, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x62, 0x31, 0x0b,
+  0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
+  0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70,
+  0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24,
+  0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65,
+  0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
+  0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
+  0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x41,
+  0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41,
+  0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x34, 0x32, 0x35, 0x32, 0x31,
+  0x34, 0x30, 0x33, 0x36, 0x5a, 0x17, 0x0d, 0x33, 0x35, 0x30, 0x32, 0x30,
+  0x39, 0x32, 0x31, 0x34, 0x30, 0x33, 0x36, 0x5a, 0x30, 0x62, 0x31, 0x0b,
+  0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
+  0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70,
+  0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24,
+  0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65,
+  0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
+  0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
+  0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x41,
+  0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41,
+  0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00,
+  0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xe4, 0x91, 0xa9,
+  0x09, 0x1f, 0x91, 0xdb, 0x1e, 0x47, 0x50, 0xeb, 0x05, 0xed, 0x5e, 0x79,
+  0x84, 0x2d, 0xeb, 0x36, 0xa2, 0x57, 0x4c, 0x55, 0xec, 0x8b, 0x19, 0x89,
+  0xde, 0xf9, 0x4b, 0x6c, 0xf5, 0x07, 0xab, 0x22, 0x30, 0x02, 0xe8, 0x18,
+  0x3e, 0xf8, 0x50, 0x09, 0xd3, 0x7f, 0x41, 0xa8, 0x98, 0xf9, 0xd1, 0xca,
+  0x66, 0x9c, 0x24, 0x6b, 0x11, 0xd0, 0xa3, 0xbb, 0xe4, 0x1b, 0x2a, 0xc3,
+  0x1f, 0x95, 0x9e, 0x7a, 0x0c, 0xa4, 0x47, 0x8b, 0x5b, 0xd4, 0x16, 0x37,
+  0x33, 0xcb, 0xc4, 0x0f, 0x4d, 0xce, 0x14, 0x69, 0xd1, 0xc9, 0x19, 0x72,
+  0xf5, 0x5d, 0x0e, 0xd5, 0x7f, 0x5f, 0x9b, 0xf2, 0x25, 0x03, 0xba, 0x55,
+  0x8f, 0x4d, 0x5d, 0x0d, 0xf1, 0x64, 0x35, 0x23, 0x15, 0x4b, 0x15, 0x59,
+  0x1d, 0xb3, 0x94, 0xf7, 0xf6, 0x9c, 0x9e, 0xcf, 0x50, 0xba, 0xc1, 0x58,
+  0x50, 0x67, 0x8f, 0x08, 0xb4, 0x20, 0xf7, 0xcb, 0xac, 0x2c, 0x20, 0x6f,
+  0x70, 0xb6, 0x3f, 0x01, 0x30, 0x8c, 0xb7, 0x43, 0xcf, 0x0f, 0x9d, 0x3d,
+  0xf3, 0x2b, 0x49, 0x28, 0x1a, 0xc8, 0xfe, 0xce, 0xb5, 0xb9, 0x0e, 0xd9,
+  0x5e, 0x1c, 0xd6, 0xcb, 0x3d, 0xb5, 0x3a, 0xad, 0xf4, 0x0f, 0x0e, 0x00,
+  0x92, 0x0b, 0xb1, 0x21, 0x16, 0x2e, 0x74, 0xd5, 0x3c, 0x0d, 0xdb, 0x62,
+  0x16, 0xab, 0xa3, 0x71, 0x92, 0x47, 0x53, 0x55, 0xc1, 0xaf, 0x2f, 0x41,
+  0xb3, 0xf8, 0xfb, 0xe3, 0x70, 0xcd, 0xe6, 0xa3, 0x4c, 0x45, 0x7e, 0x1f,
+  0x4c, 0x6b, 0x50, 0x96, 0x41, 0x89, 0xc4, 0x74, 0x62, 0x0b, 0x10, 0x83,
+  0x41, 0x87, 0x33, 0x8a, 0x81, 0xb1, 0x30, 0x58, 0xec, 0x5a, 0x04, 0x32,
+  0x8c, 0x68, 0xb3, 0x8f, 0x1d, 0xde, 0x65, 0x73, 0xff, 0x67, 0x5e, 0x65,
+  0xbc, 0x49, 0xd8, 0x76, 0x9f, 0x33, 0x14, 0x65, 0xa1, 0x77, 0x94, 0xc9,
+  0x2d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x7a, 0x30, 0x82,
+  0x01, 0x76, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
+  0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d,
+  0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30,
+  0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x2b, 0xd0,
+  0x69, 0x47, 0x94, 0x76, 0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e, 0x40, 0xa6,
+  0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
+  0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94,
+  0x76, 0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e, 0x40, 0xa6, 0xf7, 0x47, 0x4d,
+  0x7f, 0x08, 0x5e, 0x30, 0x82, 0x01, 0x11, 0x06, 0x03, 0x55, 0x1d, 0x20,
+  0x04, 0x82, 0x01, 0x08, 0x30, 0x82, 0x01, 0x04, 0x30, 0x82, 0x01, 0x00,
+  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x05, 0x01, 0x30,
+  0x81, 0xf2, 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+  0x02, 0x01, 0x16, 0x1e, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f,
+  0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
+  0x6d, 0x2f, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x63, 0x61, 0x2f, 0x30, 0x81,
+  0xc3, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30,
+  0x81, 0xb6, 0x1a, 0x81, 0xb3, 0x52, 0x65, 0x6c, 0x69, 0x61, 0x6e, 0x63,
+  0x65, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x63, 0x65,
+  0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x62, 0x79,
+  0x20, 0x61, 0x6e, 0x79, 0x20, 0x70, 0x61, 0x72, 0x74, 0x79, 0x20, 0x61,
+  0x73, 0x73, 0x75, 0x6d, 0x65, 0x73, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70,
+  0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65,
+  0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63,
+  0x61, 0x62, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72,
+  0x64, 0x20, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20,
+  0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f,
+  0x66, 0x20, 0x75, 0x73, 0x65, 0x2c, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69,
+  0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x63,
+  0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66,
+  0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x61, 0x63,
+  0x74, 0x69, 0x63, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65,
+  0x6e, 0x74, 0x73, 0x2e, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00,
+  0x5c, 0x36, 0x99, 0x4c, 0x2d, 0x78, 0xb7, 0xed, 0x8c, 0x9b, 0xdc, 0xf3,
+  0x77, 0x9b, 0xf2, 0x76, 0xd2, 0x77, 0x30, 0x4f, 0xc1, 0x1f, 0x85, 0x83,
+  0x85, 0x1b, 0x99, 0x3d, 0x47, 0x37, 0xf2, 0xa9, 0x9b, 0x40, 0x8e, 0x2c,
+  0xd4, 0xb1, 0x90, 0x12, 0xd8, 0xbe, 0xf4, 0x73, 0x9b, 0xee, 0xd2, 0x64,
+  0x0f, 0xcb, 0x79, 0x4f, 0x34, 0xd8, 0xa2, 0x3e, 0xf9, 0x78, 0xff, 0x6b,
+  0xc8, 0x07, 0xec, 0x7d, 0x39, 0x83, 0x8b, 0x53, 0x20, 0xd3, 0x38, 0xc4,
+  0xb1, 0xbf, 0x9a, 0x4f, 0x0a, 0x6b, 0xff, 0x2b, 0xfc, 0x59, 0xa7, 0x05,
+  0x09, 0x7c, 0x17, 0x40, 0x56, 0x11, 0x1e, 0x74, 0xd3, 0xb7, 0x8b, 0x23,
+  0x3b, 0x47, 0xa3, 0xd5, 0x6f, 0x24, 0xe2, 0xeb, 0xd1, 0xb7, 0x70, 0xdf,
+  0x0f, 0x45, 0xe1, 0x27, 0xca, 0xf1, 0x6d, 0x78, 0xed, 0xe7, 0xb5, 0x17,
+  0x17, 0xa8, 0xdc, 0x7e, 0x22, 0x35, 0xca, 0x25, 0xd5, 0xd9, 0x0f, 0xd6,
+  0x6b, 0xd4, 0xa2, 0x24, 0x23, 0x11, 0xf7, 0xa1, 0xac, 0x8f, 0x73, 0x81,
+  0x60, 0xc6, 0x1b, 0x5b, 0x09, 0x2f, 0x92, 0xb2, 0xf8, 0x44, 0x48, 0xf0,
+  0x60, 0x38, 0x9e, 0x15, 0xf5, 0x3d, 0x26, 0x67, 0x20, 0x8a, 0x33, 0x6a,
+  0xf7, 0x0d, 0x82, 0xcf, 0xde, 0xeb, 0xa3, 0x2f, 0xf9, 0x53, 0x6a, 0x5b,
+  0x64, 0xc0, 0x63, 0x33, 0x77, 0xf7, 0x3a, 0x07, 0x2c, 0x56, 0xeb, 0xda,
+  0x0f, 0x21, 0x0e, 0xda, 0xba, 0x73, 0x19, 0x4f, 0xb5, 0xd9, 0x36, 0x7f,
+  0xc1, 0x87, 0x55, 0xd9, 0xa7, 0x99, 0xb9, 0x32, 0x42, 0xfb, 0xd8, 0xd5,
+  0x71, 0x9e, 0x7e, 0xa1, 0x52, 0xb7, 0x1b, 0xbd, 0x93, 0x42, 0x24, 0x12,
+  0x2a, 0xc7, 0x0f, 0x1d, 0xb6, 0x4d, 0x9c, 0x5e, 0x63, 0xc8, 0x4b, 0x80,
+  0x17, 0x50, 0xaa, 0x8a, 0xd5, 0xda, 0xe4, 0xfc, 0xd0, 0x09, 0x07, 0x37,
+  0xb0, 0x75, 0x75, 0x21, 0x31, 0x82, 0x01, 0x83, 0x30, 0x82, 0x01, 0x7f,
+  0x02, 0x01, 0x01, 0x30, 0x7e, 0x30, 0x79, 0x31, 0x0b, 0x30, 0x09, 0x06,
+  0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11,
+  0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65,
+  0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55,
+  0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65,
+  0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
+  0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x2d, 0x30,
+  0x2b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x24, 0x41, 0x70, 0x70, 0x6c,
+  0x65, 0x20, 0x69, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x20, 0x43, 0x65, 0x72,
+  0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41,
+  0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x02, 0x01, 0x17, 0x30,
+  0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0xa0, 0x5d,
+  0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09,
+  0x03, 0x31, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x07, 0x01, 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x09, 0x05, 0x31, 0x0f, 0x17, 0x0d, 0x30, 0x38, 0x30, 0x35, 0x31,
+  0x30, 0x30, 0x31, 0x30, 0x30, 0x32, 0x32, 0x5a, 0x30, 0x23, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04, 0x31, 0x16, 0x04,
+  0x14, 0xf2, 0x05, 0x98, 0xf9, 0x3c, 0xf2, 0x4c, 0x9c, 0x3d, 0x9c, 0xcb,
+  0x3d, 0xa0, 0xa2, 0x4f, 0x95, 0xb2, 0x3f, 0x5e, 0x79, 0x30, 0x0d, 0x06,
+  0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
+  0x04, 0x81, 0x80, 0xa7, 0x93, 0x53, 0xf4, 0x6e, 0x7e, 0x25, 0xbf, 0xf0,
+  0xd5, 0xd1, 0xf0, 0xf0, 0x79, 0x8e, 0xcb, 0x7b, 0x7d, 0x23, 0x6f, 0xb5,
+  0x82, 0x36, 0xb6, 0x68, 0x48, 0xff, 0xc2, 0x08, 0x4b, 0x23, 0xf3, 0xe0,
+  0x48, 0xe1, 0x9e, 0xec, 0x65, 0x86, 0xf5, 0x51, 0xa5, 0xb4, 0x8c, 0xf0,
+  0x88, 0xa7, 0x5c, 0x1a, 0xb4, 0x9a, 0x8c, 0x3b, 0x82, 0xf2, 0xad, 0xff,
+  0xe8, 0xf3, 0x10, 0x1f, 0x5b, 0x4f, 0x1c, 0x54, 0x39, 0xf6, 0x84, 0x48,
+  0x06, 0x15, 0xef, 0x26, 0xb1, 0x2f, 0x97, 0xb5, 0x9e, 0x2c, 0xbb, 0x2a,
+  0x21, 0x35, 0x45, 0x80, 0x47, 0x16, 0x30, 0x60, 0x5c, 0xee, 0x93, 0xc9,
+  0xd3, 0x9a, 0x03, 0x20, 0xad, 0x0c, 0xb2, 0x83, 0x6c, 0x62, 0x8f, 0xbf,
+  0x05, 0x23, 0x16, 0x6f, 0x38, 0x76, 0x42, 0x16, 0xab, 0x15, 0x82, 0xcf,
+  0xfa, 0x0a, 0xa6, 0x85, 0x90, 0x66, 0xc4, 0x4e, 0xf9, 0xab, 0x1c, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00
+};
+static unsigned int fk_cms_len = 3601;
+
+#if 0 // currently unused
+static unsigned char smime_blob[] = {
+  0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07,
+  0x02, 0xa0, 0x80, 0x30, 0x80, 0x02, 0x01, 0x01, 0x31, 0x0b, 0x30, 0x09,
+  0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x30, 0x80, 0x06,
+  0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x00, 0x00,
+  0xa0, 0x82, 0x06, 0xf6, 0x30, 0x82, 0x03, 0x3f, 0x30, 0x82, 0x02, 0xa8,
+  0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x0d, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 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, 0x65, 0x73, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x43, 0x61,
+  0x70, 0x65, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13,
+  0x09, 0x43, 0x61, 0x70, 0x65, 0x20, 0x54, 0x6f, 0x77, 0x6e, 0x31, 0x1a,
+  0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, 0x54, 0x68, 0x61,
+  0x77, 0x74, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x74, 0x69,
+  0x6e, 0x67, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
+  0x1f, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
+  0x6f, 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20,
+  0x44, 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x24, 0x30, 0x22,
+  0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1b, 0x54, 0x68, 0x61, 0x77, 0x74,
+  0x65, 0x20, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x46,
+  0x72, 0x65, 0x65, 0x6d, 0x61, 0x69, 0x6c, 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, 0x30, 0x1e, 0x17, 0x0d, 0x30,
+  0x33, 0x30, 0x37, 0x31, 0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
+  0x17, 0x0d, 0x31, 0x33, 0x30, 0x37, 0x31, 0x36, 0x32, 0x33, 0x35, 0x39,
+  0x35, 0x39, 0x5a, 0x30, 0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+  0x04, 0x06, 0x13, 0x02, 0x5a, 0x41, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03,
+  0x55, 0x04, 0x0a, 0x13, 0x1c, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20,
+  0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x28,
+  0x50, 0x74, 0x79, 0x29, 0x20, 0x4c, 0x74, 0x64, 0x2e, 0x31, 0x2c, 0x30,
+  0x2a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x23, 0x54, 0x68, 0x61, 0x77,
+  0x74, 0x65, 0x20, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x20,
+  0x46, 0x72, 0x65, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x20, 0x49, 0x73, 0x73,
+  0x75, 0x69, 0x6e, 0x67, 0x20, 0x43, 0x41, 0x30, 0x81, 0x9f, 0x30, 0x0d,
+  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
+  0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00,
+  0xc4, 0xa6, 0x3c, 0x55, 0x73, 0x55, 0xfb, 0x4e, 0xb9, 0xca, 0x99, 0x5a,
+  0x1e, 0x68, 0xc0, 0x75, 0x04, 0x70, 0x9d, 0xdf, 0xe9, 0xff, 0xa3, 0x1e,
+  0xec, 0xbd, 0xcd, 0xf5, 0x5b, 0xf2, 0x1a, 0x76, 0xbd, 0x7f, 0x0c, 0x3a,
+  0x61, 0xf2, 0xbf, 0x51, 0xce, 0x01, 0xd4, 0xe5, 0x50, 0x0a, 0x30, 0xd7,
+  0x02, 0x63, 0x5a, 0x2c, 0x89, 0x15, 0x70, 0x8e, 0xdd, 0xc9, 0xf0, 0x2b,
+  0x85, 0x5a, 0xaa, 0x3f, 0x71, 0x56, 0xcb, 0xaf, 0x3c, 0x0b, 0x07, 0xe7,
+  0xf1, 0x1f, 0x91, 0x36, 0x24, 0x2a, 0x13, 0xcf, 0x2b, 0xd5, 0xf3, 0x82,
+  0x77, 0x3d, 0x03, 0xbe, 0x2b, 0xfe, 0xbb, 0x18, 0x3e, 0x07, 0xbf, 0x40,
+  0x80, 0x02, 0x64, 0xd7, 0xa7, 0xa6, 0xbb, 0x9f, 0x65, 0xd1, 0xc5, 0x2a,
+  0x54, 0x85, 0x0f, 0x48, 0x04, 0x7f, 0xa7, 0xb6, 0xd1, 0x3c, 0x61, 0x04,
+  0x40, 0x1e, 0x64, 0x19, 0x72, 0x60, 0xb7, 0xfb, 0x02, 0x03, 0x01, 0x00,
+  0x01, 0xa3, 0x81, 0x94, 0x30, 0x81, 0x91, 0x30, 0x12, 0x06, 0x03, 0x55,
+  0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff,
+  0x02, 0x01, 0x00, 0x30, 0x43, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x3c,
+  0x30, 0x3a, 0x30, 0x38, 0xa0, 0x36, 0xa0, 0x34, 0x86, 0x32, 0x68, 0x74,
+  0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x74, 0x68, 0x61,
+  0x77, 0x74, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x68, 0x61, 0x77,
+  0x74, 0x65, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x46, 0x72,
+  0x65, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c,
+  0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01,
+  0x06, 0x30, 0x29, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x22, 0x30, 0x20,
+  0xa4, 0x1e, 0x30, 0x1c, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04,
+  0x03, 0x13, 0x11, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4c, 0x61,
+  0x62, 0x65, 0x6c, 0x32, 0x2d, 0x31, 0x33, 0x38, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,
+  0x81, 0x81, 0x00, 0x48, 0x8c, 0xd1, 0x50, 0x83, 0xea, 0x0b, 0x2e, 0xcc,
+  0x0d, 0xa3, 0x66, 0xac, 0x67, 0x0f, 0x7f, 0xaf, 0xac, 0xbe, 0xc2, 0x17,
+  0xa1, 0x43, 0x96, 0x94, 0x9d, 0x7f, 0x4c, 0x21, 0xb8, 0xf8, 0x36, 0x1f,
+  0xaa, 0x2d, 0x9f, 0x36, 0x2f, 0xc0, 0xf4, 0x1c, 0x50, 0x20, 0x93, 0x70,
+  0x3c, 0xfd, 0xad, 0xe1, 0x61, 0x62, 0xc3, 0xd9, 0x3a, 0x19, 0x7e, 0x84,
+  0xb1, 0x99, 0x1b, 0x00, 0xc5, 0x1a, 0x0b, 0x82, 0x74, 0x9e, 0x25, 0x50,
+  0x94, 0x62, 0xc7, 0xdb, 0x27, 0x71, 0x57, 0x25, 0x8d, 0xdd, 0xa9, 0x9c,
+  0x39, 0x8e, 0x8c, 0x20, 0x4f, 0x65, 0x5f, 0x95, 0xda, 0xf7, 0xf7, 0x87,
+  0xd6, 0xc6, 0x08, 0x4e, 0xae, 0xf6, 0xea, 0x34, 0xe5, 0x10, 0x1a, 0x5b,
+  0x35, 0x4d, 0x77, 0xe3, 0x56, 0x21, 0x78, 0x82, 0xdc, 0x21, 0x19, 0x35,
+  0xde, 0x24, 0xb1, 0xd3, 0x1d, 0x46, 0xff, 0x5d, 0x5f, 0x65, 0x4f, 0x30,
+  0x82, 0x03, 0xaf, 0x30, 0x82, 0x03, 0x18, 0xa0, 0x03, 0x02, 0x01, 0x02,
+  0x02, 0x10, 0x46, 0x3a, 0x0d, 0xad, 0xbe, 0x01, 0xae, 0x6b, 0x8c, 0x72,
+  0x4f, 0x6d, 0x10, 0xda, 0x63, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x62, 0x31,
+  0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x5a, 0x41,
+  0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x1c, 0x54,
+  0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c,
+  0x74, 0x69, 0x6e, 0x67, 0x20, 0x28, 0x50, 0x74, 0x79, 0x29, 0x20, 0x4c,
+  0x74, 0x64, 0x2e, 0x31, 0x2c, 0x30, 0x2a, 0x06, 0x03, 0x55, 0x04, 0x03,
+  0x13, 0x23, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50, 0x65, 0x72,
+  0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x46, 0x72, 0x65, 0x65, 0x6d, 0x61,
+  0x69, 0x6c, 0x20, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, 0x20, 0x43,
+  0x41, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x37, 0x30, 0x38, 0x32, 0x39, 0x30,
+  0x31, 0x30, 0x31, 0x35, 0x31, 0x5a, 0x17, 0x0d, 0x30, 0x38, 0x30, 0x38,
+  0x32, 0x38, 0x30, 0x31, 0x30, 0x31, 0x35, 0x31, 0x5a, 0x30, 0x81, 0xca,
+  0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x54,
+  0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x46, 0x72, 0x65, 0x65, 0x6d, 0x61,
+  0x69, 0x6c, 0x20, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x31, 0x1e, 0x30,
+  0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01,
+  0x16, 0x0f, 0x64, 0x61, 0x76, 0x65, 0x6d, 0x61, 0x6b, 0x40, 0x6d, 0x61,
+  0x63, 0x2e, 0x63, 0x6f, 0x6d, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x11, 0x64, 0x61,
+  0x76, 0x65, 0x6d, 0x61, 0x6b, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e,
+  0x63, 0x6f, 0x6d, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x11, 0x64, 0x61, 0x76, 0x65,
+  0x6d, 0x61, 0x6b, 0x40, 0x67, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x63, 0x6f,
+  0x6d, 0x31, 0x22, 0x30, 0x20, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x01, 0x09, 0x01, 0x16, 0x13, 0x64, 0x61, 0x76, 0x65, 0x6d, 0x61,
+  0x6b, 0x40, 0x64, 0x61, 0x76, 0x65, 0x6d, 0x61, 0x6b, 0x2e, 0x63, 0x6f,
+  0x6d, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x64, 0x61, 0x76, 0x65, 0x40, 0x64,
+  0x61, 0x76, 0x65, 0x6d, 0x61, 0x6b, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82,
+  0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82,
+  0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xdc, 0xf3, 0x48, 0x8d, 0x6b,
+  0x1d, 0xf5, 0xbf, 0x73, 0x71, 0x27, 0x1c, 0xbd, 0xd2, 0x19, 0x56, 0x19,
+  0x08, 0xc3, 0x0e, 0x8b, 0xe1, 0x75, 0x66, 0x4a, 0x93, 0x7f, 0x70, 0x38,
+  0xd9, 0xc2, 0x07, 0x73, 0x4e, 0xcc, 0x81, 0xea, 0x03, 0x20, 0x68, 0x09,
+  0x94, 0xa8, 0xb9, 0x8a, 0xad, 0xe5, 0x0c, 0xd8, 0x26, 0x0b, 0x97, 0xb9,
+  0xae, 0x78, 0xd4, 0x4e, 0xbf, 0x3f, 0x81, 0xb1, 0x04, 0x68, 0xda, 0x1e,
+  0x59, 0x9f, 0x3d, 0xc9, 0xc3, 0xa4, 0xfc, 0x61, 0x86, 0x93, 0x58, 0x54,
+  0x71, 0x6c, 0xf9, 0xed, 0x99, 0x6a, 0xd8, 0xcb, 0xd7, 0xec, 0x4b, 0x3e,
+  0xb7, 0xd4, 0x87, 0xee, 0x09, 0x3d, 0x38, 0x52, 0xe0, 0x7b, 0xce, 0x2d,
+  0xda, 0xff, 0x04, 0x54, 0xd8, 0x4c, 0x43, 0xee, 0xab, 0x87, 0xe5, 0x35,
+  0x2d, 0xe6, 0xc0, 0xe8, 0x55, 0x89, 0x40, 0x14, 0x4b, 0xd7, 0x27, 0x3e,
+  0xce, 0xfe, 0x87, 0x75, 0x01, 0xf3, 0x01, 0x31, 0x23, 0xb7, 0xe5, 0xbf,
+  0xd4, 0x5a, 0x66, 0xcd, 0x47, 0x9d, 0xbf, 0x0f, 0xe0, 0x7e, 0x56, 0x30,
+  0xa6, 0x2c, 0x02, 0x8b, 0xde, 0x1f, 0xde, 0xa6, 0x18, 0xec, 0xaa, 0x2a,
+  0x35, 0xeb, 0x7b, 0x9d, 0x07, 0xde, 0x47, 0x33, 0x84, 0x5a, 0x1e, 0x3b,
+  0x86, 0x15, 0x5d, 0x73, 0xcd, 0x71, 0x53, 0x2d, 0x72, 0xef, 0xd3, 0x52,
+  0xd3, 0x3e, 0xd0, 0x3b, 0x8c, 0x75, 0x4c, 0xce, 0x42, 0x97, 0xd9, 0x18,
+  0xbf, 0xb9, 0x95, 0x71, 0xe1, 0x20, 0xe7, 0x40, 0x09, 0xde, 0x72, 0x08,
+  0x87, 0xe9, 0x2a, 0x08, 0x41, 0x2b, 0xd2, 0x0d, 0x14, 0x63, 0x30, 0x14,
+  0x74, 0x0a, 0x0d, 0x5a, 0x8a, 0x13, 0x19, 0xe7, 0x7c, 0x18, 0x8d, 0x4a,
+  0x72, 0xf1, 0xff, 0x93, 0x2d, 0xd4, 0xba, 0x8b, 0xf0, 0xd6, 0x9e, 0xd3,
+  0x9f, 0xe7, 0xd0, 0x84, 0x9b, 0x94, 0xe9, 0xfe, 0x7b, 0x4c, 0x29, 0x02,
+  0x03, 0x01, 0x00, 0x01, 0xa3, 0x79, 0x30, 0x77, 0x30, 0x67, 0x06, 0x03,
+  0x55, 0x1d, 0x11, 0x04, 0x60, 0x30, 0x5e, 0x81, 0x0f, 0x64, 0x61, 0x76,
+  0x65, 0x6d, 0x61, 0x6b, 0x40, 0x6d, 0x61, 0x63, 0x2e, 0x63, 0x6f, 0x6d,
+  0x81, 0x11, 0x64, 0x61, 0x76, 0x65, 0x6d, 0x61, 0x6b, 0x40, 0x61, 0x70,
+  0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x81, 0x11, 0x64, 0x61, 0x76,
+  0x65, 0x6d, 0x61, 0x6b, 0x40, 0x67, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x63,
+  0x6f, 0x6d, 0x81, 0x13, 0x64, 0x61, 0x76, 0x65, 0x6d, 0x61, 0x6b, 0x40,
+  0x64, 0x61, 0x76, 0x65, 0x6d, 0x61, 0x6b, 0x2e, 0x63, 0x6f, 0x6d, 0x81,
+  0x10, 0x64, 0x61, 0x76, 0x65, 0x40, 0x64, 0x61, 0x76, 0x65, 0x6d, 0x61,
+  0x6b, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13,
+  0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81,
+  0x81, 0x00, 0x24, 0x09, 0x54, 0xcc, 0xc9, 0xaf, 0x1c, 0xc8, 0x11, 0xaf,
+  0xfe, 0x27, 0x3d, 0x72, 0x15, 0x57, 0xe2, 0x6d, 0x53, 0xe3, 0x5f, 0x56,
+  0x2c, 0xaf, 0x74, 0x8b, 0xb3, 0x2c, 0xdc, 0x41, 0x85, 0x8d, 0x55, 0x82,
+  0xb6, 0x10, 0xab, 0xcb, 0x66, 0xff, 0xf0, 0xc0, 0x1e, 0x97, 0xac, 0x55,
+  0xbd, 0x43, 0xb6, 0x7e, 0x58, 0xc7, 0x05, 0xbf, 0x06, 0x26, 0xda, 0x07,
+  0x96, 0x8a, 0x80, 0x12, 0x4a, 0x99, 0xfc, 0xb1, 0x2f, 0x33, 0xfd, 0x9e,
+  0x6d, 0xdb, 0x7b, 0xe0, 0x7b, 0xc7, 0xa4, 0x9d, 0xfe, 0x2f, 0x5e, 0xfe,
+  0x42, 0x41, 0x74, 0xca, 0xc5, 0xe3, 0x42, 0xc4, 0xd7, 0x72, 0xd3, 0x7e,
+  0xd1, 0xe4, 0x17, 0x91, 0x1f, 0x79, 0x6a, 0x93, 0x22, 0x22, 0x38, 0x99,
+  0x2a, 0x0f, 0x50, 0xa6, 0xfd, 0x79, 0xc2, 0x95, 0xf0, 0x8e, 0xde, 0x51,
+  0xa8, 0x55, 0x98, 0x88, 0x8c, 0x32, 0xa4, 0x08, 0x9d, 0x80, 0x31, 0x82,
+  0x03, 0x10, 0x30, 0x82, 0x03, 0x0c, 0x02, 0x01, 0x01, 0x30, 0x76, 0x30,
+  0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+  0x5a, 0x41, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+  0x1c, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x73,
+  0x75, 0x6c, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x28, 0x50, 0x74, 0x79, 0x29,
+  0x20, 0x4c, 0x74, 0x64, 0x2e, 0x31, 0x2c, 0x30, 0x2a, 0x06, 0x03, 0x55,
+  0x04, 0x03, 0x13, 0x23, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50,
+  0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x46, 0x72, 0x65, 0x65,
+  0x6d, 0x61, 0x69, 0x6c, 0x20, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67,
+  0x20, 0x43, 0x41, 0x02, 0x10, 0x46, 0x3a, 0x0d, 0xad, 0xbe, 0x01, 0xae,
+  0x6b, 0x8c, 0x72, 0x4f, 0x6d, 0x10, 0xda, 0x63, 0x00, 0x30, 0x09, 0x06,
+  0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0xa0, 0x82, 0x01, 0x6f,
+  0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09,
+  0x03, 0x31, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x07, 0x01, 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x09, 0x05, 0x31, 0x0f, 0x17, 0x0d, 0x30, 0x38, 0x30, 0x37, 0x30,
+  0x32, 0x31, 0x36, 0x31, 0x37, 0x32, 0x31, 0x5a, 0x30, 0x23, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04, 0x31, 0x16, 0x04,
+  0x14, 0x67, 0x27, 0xe8, 0x4f, 0xae, 0xad, 0xbf, 0x26, 0x35, 0xca, 0xe3,
+  0xc3, 0x9a, 0x1a, 0xa3, 0xa2, 0xbe, 0xe0, 0x92, 0x65, 0x30, 0x81, 0x85,
+  0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x10, 0x04, 0x31,
+  0x78, 0x30, 0x76, 0x30, 0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+  0x04, 0x06, 0x13, 0x02, 0x5a, 0x41, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03,
+  0x55, 0x04, 0x0a, 0x13, 0x1c, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20,
+  0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x28,
+  0x50, 0x74, 0x79, 0x29, 0x20, 0x4c, 0x74, 0x64, 0x2e, 0x31, 0x2c, 0x30,
+  0x2a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x23, 0x54, 0x68, 0x61, 0x77,
+  0x74, 0x65, 0x20, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x20,
+  0x46, 0x72, 0x65, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x20, 0x49, 0x73, 0x73,
+  0x75, 0x69, 0x6e, 0x67, 0x20, 0x43, 0x41, 0x02, 0x10, 0x46, 0x3a, 0x0d,
+  0xad, 0xbe, 0x01, 0xae, 0x6b, 0x8c, 0x72, 0x4f, 0x6d, 0x10, 0xda, 0x63,
+  0x00, 0x30, 0x81, 0x87, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x09, 0x10, 0x02, 0x0b, 0x31, 0x78, 0xa0, 0x76, 0x30, 0x62, 0x31,
+  0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x5a, 0x41,
+  0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x1c, 0x54,
+  0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c,
+  0x74, 0x69, 0x6e, 0x67, 0x20, 0x28, 0x50, 0x74, 0x79, 0x29, 0x20, 0x4c,
+  0x74, 0x64, 0x2e, 0x31, 0x2c, 0x30, 0x2a, 0x06, 0x03, 0x55, 0x04, 0x03,
+  0x13, 0x23, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50, 0x65, 0x72,
+  0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x46, 0x72, 0x65, 0x65, 0x6d, 0x61,
+  0x69, 0x6c, 0x20, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, 0x20, 0x43,
+  0x41, 0x02, 0x10, 0x46, 0x3a, 0x0d, 0xad, 0xbe, 0x01, 0xae, 0x6b, 0x8c,
+  0x72, 0x4f, 0x6d, 0x10, 0xda, 0x63, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
+  0x01, 0x00, 0x19, 0xee, 0xcb, 0xfe, 0x88, 0x0e, 0x1e, 0x66, 0x8d, 0xe5,
+  0xac, 0xeb, 0x92, 0xc1, 0x8e, 0xb5, 0x82, 0xf1, 0x93, 0x78, 0xab, 0xbc,
+  0x1d, 0x9d, 0xa8, 0x4b, 0x7e, 0x98, 0xde, 0x67, 0x6c, 0x2b, 0xbe, 0x3d,
+  0xd9, 0xe9, 0x3b, 0x61, 0xc9, 0x4b, 0xd3, 0x4b, 0x73, 0x8a, 0x5e, 0xa6,
+  0xda, 0xcb, 0xe8, 0x82, 0x6e, 0x53, 0x8f, 0xba, 0xaf, 0xf6, 0xf9, 0xda,
+  0xb0, 0x87, 0xf5, 0x6e, 0x66, 0x2e, 0xe3, 0x5c, 0xb0, 0xc7, 0x44, 0x4d,
+  0x49, 0x59, 0x05, 0x10, 0xad, 0x4e, 0xd8, 0x53, 0x19, 0x6f, 0x7a, 0xbe,
+  0xc7, 0x87, 0xc6, 0xe9, 0x0d, 0xe2, 0x1f, 0x64, 0xa4, 0xcd, 0xfc, 0x19,
+  0xb3, 0x51, 0xdc, 0xb4, 0x48, 0x49, 0xb5, 0x7e, 0xce, 0xa1, 0x82, 0x4f,
+  0x55, 0xb6, 0xa2, 0x50, 0x2b, 0xec, 0xa0, 0xb2, 0x39, 0x16, 0x09, 0xbe,
+  0x39, 0x52, 0xf2, 0xc5, 0x4b, 0x92, 0xbf, 0x46, 0x74, 0x43, 0x8c, 0x80,
+  0x6c, 0x07, 0x2b, 0xf5, 0xa7, 0x83, 0x57, 0x55, 0xda, 0xe4, 0xdf, 0x0e,
+  0x06, 0x22, 0x71, 0xce, 0xf6, 0xd1, 0x28, 0xf9, 0x53, 0x1c, 0x57, 0x42,
+  0x47, 0xd8, 0xf0, 0xad, 0xfe, 0xf2, 0xa6, 0x0d, 0x2c, 0x5e, 0x8f, 0x99,
+  0x95, 0x58, 0x08, 0x26, 0xef, 0x70, 0x96, 0xe8, 0x65, 0x80, 0xa2, 0x1f,
+  0x93, 0x73, 0xac, 0x85, 0xc9, 0x62, 0x22, 0x48, 0x4d, 0x91, 0x86, 0xc2,
+  0x3a, 0xbc, 0xff, 0xfc, 0x91, 0x4f, 0x15, 0x7e, 0x17, 0x0d, 0x4a, 0x5a,
+  0xff, 0x6a, 0x9d, 0xbb, 0xcc, 0x27, 0x5e, 0x00, 0x03, 0x66, 0xfe, 0xf4,
+  0xe3, 0x61, 0xcb, 0x54, 0x9b, 0x7f, 0x6e, 0x7c, 0x49, 0xf0, 0x1d, 0x15,
+  0x8b, 0xe6, 0xb1, 0x3c, 0x07, 0xb9, 0x16, 0x33, 0x3c, 0x66, 0x77, 0x3c,
+  0x3d, 0x91, 0x86, 0x08, 0x49, 0x10, 0x67, 0xa8, 0x1b, 0x2f, 0x0d, 0x69,
+  0xb5, 0x0e, 0xf5, 0x2c, 0x59, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+static unsigned int smime_blob_len = 2628;
+#endif // currently unused
+
+static unsigned char scep_reply[] = {
+  0x30, 0x82, 0x05, 0x40, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x07, 0x02, 0xa0, 0x82, 0x05, 0x31, 0x30, 0x82, 0x05, 0x2d, 0x02,
+  0x01, 0x01, 0x31, 0x0e, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x30, 0x82, 0x03, 0x74, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x03,
+  0x65, 0x04, 0x82, 0x03, 0x61, 0x30, 0x82, 0x03, 0x5d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x03, 0xa0, 0x82, 0x03, 0x4e,
+  0x30, 0x82, 0x03, 0x4a, 0x02, 0x01, 0x00, 0x31, 0x81, 0xce, 0x30, 0x81,
+  0xcb, 0x02, 0x01, 0x00, 0x30, 0x34, 0x30, 0x2f, 0x31, 0x2d, 0x30, 0x2b,
+  0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x24, 0x42, 0x35, 0x41, 0x43, 0x33,
+  0x45, 0x30, 0x35, 0x2d, 0x33, 0x42, 0x35, 0x36, 0x2d, 0x34, 0x33, 0x33,
+  0x38, 0x2d, 0x42, 0x42, 0x31, 0x34, 0x2d, 0x30, 0x32, 0x37, 0x44, 0x38,
+  0x34, 0x43, 0x35, 0x32, 0x36, 0x43, 0x42, 0x02, 0x01, 0x01, 0x30, 0x0d,
+  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
+  0x00, 0x04, 0x81, 0x80, 0x15, 0xe6, 0x42, 0x9d, 0x2b, 0xbc, 0x3f, 0x8a,
+  0x97, 0x21, 0x2a, 0x86, 0x56, 0xbf, 0x48, 0xb6, 0x39, 0x40, 0xe2, 0x25,
+  0x5e, 0xc0, 0xf8, 0x5c, 0x56, 0x65, 0xb8, 0x7b, 0x55, 0x24, 0x96, 0x52,
+  0xc5, 0xca, 0x8e, 0xf1, 0xfb, 0xbe, 0x0e, 0x0f, 0xf2, 0x16, 0x9c, 0x63,
+  0x8c, 0xb2, 0xff, 0x63, 0xd1, 0x58, 0x86, 0x15, 0xb8, 0x8b, 0xf4, 0x76,
+  0x78, 0xa9, 0x57, 0xfd, 0xc3, 0x2b, 0xb7, 0x9a, 0x0f, 0x3c, 0x2d, 0x99,
+  0x23, 0x7f, 0x88, 0x3a, 0xbd, 0x9a, 0x4f, 0x91, 0xcc, 0x77, 0x5b, 0x75,
+  0xa8, 0xad, 0xb8, 0xb2, 0xaf, 0x1c, 0x98, 0xb8, 0xc6, 0xbf, 0x93, 0xcb,
+  0x86, 0x44, 0xf7, 0xfc, 0x0c, 0x0a, 0x76, 0x22, 0x62, 0x8b, 0x6b, 0x89,
+  0x0d, 0xee, 0x54, 0x0d, 0x3f, 0x85, 0x83, 0x2a, 0x3e, 0x29, 0xf5, 0x4c,
+  0x82, 0x2f, 0xbd, 0xdd, 0x34, 0x77, 0x39, 0xfe, 0xac, 0x96, 0x59, 0x16,
+  0x30, 0x82, 0x02, 0x72, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x07, 0x01, 0x30, 0x11, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x07,
+  0x04, 0x08, 0x92, 0x2c, 0x6c, 0xdc, 0xca, 0xd2, 0x38, 0xfe, 0x80, 0x82,
+  0x02, 0x50, 0x54, 0xea, 0xcb, 0x61, 0x8c, 0x51, 0xc3, 0xc9, 0x60, 0x97,
+  0xf3, 0xf2, 0x90, 0xe2, 0x97, 0xfa, 0xc5, 0x01, 0xfe, 0xa0, 0xa1, 0x3e,
+  0x5f, 0xd9, 0x7a, 0xcc, 0x7e, 0x4e, 0x11, 0x91, 0x5c, 0xeb, 0xa1, 0x2f,
+  0xfa, 0xfe, 0x6b, 0x8c, 0xca, 0x8e, 0xc7, 0xcc, 0x57, 0x1b, 0xa0, 0x9f,
+  0x76, 0x03, 0x57, 0xed, 0xbf, 0x66, 0xfc, 0x43, 0xa7, 0x2d, 0x97, 0x41,
+  0x22, 0xa6, 0x42, 0x45, 0xe6, 0x68, 0xc5, 0x6d, 0x16, 0x0e, 0x18, 0xa6,
+  0xb5, 0xc7, 0x8c, 0x23, 0x09, 0x2d, 0x65, 0x1f, 0xa8, 0xb2, 0x5c, 0x5e,
+  0x8c, 0x8a, 0x3b, 0x15, 0x63, 0x34, 0x02, 0x2f, 0xf8, 0xaf, 0x91, 0x6c,
+  0x64, 0xab, 0xaa, 0x1e, 0x35, 0xbb, 0xe3, 0x5b, 0xd3, 0xd9, 0x19, 0x31,
+  0x38, 0x52, 0x20, 0x26, 0x3d, 0x87, 0x6e, 0x8f, 0xdf, 0xc5, 0x80, 0xd8,
+  0xd8, 0xd8, 0x5d, 0xf1, 0xa2, 0x57, 0x9f, 0xd5, 0xbd, 0x60, 0x59, 0x39,
+  0x4a, 0x09, 0x6a, 0x46, 0x72, 0x33, 0x75, 0x3f, 0xbb, 0x38, 0x20, 0x18,
+  0x61, 0x6d, 0xef, 0x48, 0x76, 0x2d, 0x4f, 0xe3, 0x41, 0x36, 0xdb, 0x89,
+  0xbb, 0x05, 0x43, 0x87, 0xf4, 0x6b, 0xf2, 0xa9, 0xc6, 0xcf, 0xd5, 0xec,
+  0xf7, 0x80, 0xc6, 0x12, 0xd6, 0x3c, 0xfa, 0xeb, 0x00, 0xc1, 0x41, 0x7a,
+  0x98, 0x49, 0x80, 0xe7, 0x44, 0x0b, 0x04, 0xe4, 0xe8, 0xab, 0xf4, 0x71,
+  0x72, 0x3d, 0x3b, 0x39, 0x51, 0x2a, 0x6d, 0x80, 0xcd, 0xc3, 0x69, 0x53,
+  0x0c, 0x1b, 0xa7, 0xa8, 0x76, 0x19, 0x0f, 0x77, 0xdb, 0x13, 0x9e, 0x59,
+  0x0f, 0xad, 0xd4, 0xce, 0x78, 0x7a, 0xe0, 0x4b, 0x8b, 0xd5, 0xfb, 0x62,
+  0x11, 0x10, 0x12, 0x09, 0x41, 0xe1, 0x8f, 0xb6, 0x30, 0x64, 0xb4, 0x74,
+  0xcd, 0x84, 0xa9, 0x72, 0x25, 0xf4, 0x79, 0x3c, 0xfc, 0x87, 0x44, 0xbd,
+  0xfd, 0x65, 0x36, 0xee, 0xb5, 0xc7, 0x78, 0x7c, 0x52, 0xdd, 0x08, 0xe7,
+  0xf1, 0x5f, 0xde, 0xb3, 0x23, 0x98, 0xad, 0x33, 0xf8, 0x7f, 0x62, 0x2b,
+  0x5f, 0xe1, 0x49, 0x06, 0x58, 0xfb, 0xb6, 0x38, 0x12, 0x29, 0xe8, 0x4c,
+  0xbc, 0x2c, 0x9a, 0x4d, 0x06, 0x44, 0xfd, 0x99, 0xd9, 0xf8, 0x2c, 0xba,
+  0x46, 0xf5, 0x56, 0xf2, 0xd1, 0x4e, 0xe9, 0x76, 0xd8, 0x8f, 0x11, 0x7b,
+  0x31, 0x61, 0x59, 0x2b, 0x4f, 0x19, 0x7c, 0xa5, 0xb5, 0xa5, 0x05, 0xb2,
+  0x46, 0xab, 0x11, 0x07, 0x1d, 0xb5, 0x92, 0x24, 0x61, 0x31, 0x01, 0x05,
+  0xb2, 0x39, 0x89, 0x0c, 0x0e, 0x5e, 0xaa, 0xb6, 0x30, 0x2c, 0x75, 0x10,
+  0xf8, 0x0d, 0x7c, 0x31, 0x3c, 0xb0, 0xd5, 0x53, 0xf4, 0x4f, 0x91, 0xc4,
+  0xc9, 0x8f, 0x0b, 0x06, 0x9a, 0x77, 0x42, 0xe6, 0xf7, 0x04, 0x30, 0xcd,
+  0x1e, 0xc6, 0xb7, 0x7e, 0xfc, 0xc7, 0xb6, 0xda, 0x93, 0x91, 0x1d, 0xea,
+  0x34, 0x4d, 0x53, 0x13, 0x36, 0xf9, 0x41, 0xa4, 0x22, 0x5b, 0xdc, 0xe5,
+  0xe1, 0xfa, 0x27, 0x05, 0x49, 0xee, 0x29, 0x07, 0x7d, 0xe0, 0x40, 0x1a,
+  0x41, 0x21, 0xa1, 0x80, 0x8f, 0x0c, 0x2e, 0xf2, 0x3f, 0x40, 0xd6, 0x25,
+  0xce, 0xa5, 0x5c, 0x86, 0x4f, 0x72, 0xfd, 0xac, 0x58, 0x5e, 0x27, 0x7e,
+  0x62, 0x78, 0x0e, 0x3c, 0xb9, 0x45, 0x21, 0x88, 0x05, 0x8d, 0x83, 0x93,
+  0x2f, 0x65, 0x19, 0xb7, 0x4c, 0x37, 0x25, 0x20, 0x92, 0x2a, 0xae, 0x23,
+  0x94, 0xa8, 0x9b, 0x99, 0xe7, 0x0f, 0x8e, 0xee, 0xf1, 0xc2, 0x81, 0xd3,
+  0xdd, 0x82, 0x96, 0xcb, 0xf8, 0x55, 0xa8, 0x82, 0xed, 0xfb, 0x78, 0xe3,
+  0x73, 0x81, 0xa8, 0x64, 0x85, 0x54, 0xaa, 0x79, 0xef, 0x5e, 0x32, 0xff,
+  0x97, 0x3c, 0xb0, 0xd3, 0xa5, 0xd8, 0x37, 0x25, 0xc8, 0x14, 0x8b, 0x07,
+  0xec, 0x8f, 0x8c, 0x0d, 0xb5, 0x72, 0xa3, 0x52, 0x51, 0x83, 0x42, 0x7d,
+  0x0c, 0x12, 0xad, 0xf6, 0x01, 0x81, 0xc7, 0xa1, 0x20, 0x9e, 0x0c, 0xe8,
+  0x27, 0xb2, 0x83, 0x38, 0xfc, 0x87, 0x8a, 0x0b, 0x7c, 0x95, 0x1c, 0x0d,
+  0x35, 0x33, 0xfe, 0xd4, 0x33, 0xa5, 0x22, 0x13, 0x7b, 0xf1, 0x0f, 0xeb,
+  0x16, 0x08, 0xab, 0xe1, 0x03, 0x04, 0x4a, 0x97, 0x9f, 0xce, 0x1d, 0x36,
+  0x38, 0x91, 0x38, 0xb4, 0x02, 0xaf, 0xba, 0xff, 0xc2, 0x5c, 0x3e, 0x0e,
+  0x4d, 0xc1, 0x23, 0xc0, 0xb9, 0xc3, 0x8d, 0x82, 0x97, 0x15, 0x4c, 0x15,
+  0xaa, 0x9e, 0x74, 0xd4, 0x09, 0x85, 0x31, 0x82, 0x01, 0x9e, 0x30, 0x82,
+  0x01, 0x9a, 0x02, 0x01, 0x01, 0x30, 0x13, 0x30, 0x0e, 0x31, 0x0c, 0x30,
+  0x0a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x03, 0x6e, 0x69, 0x69, 0x02,
+  0x01, 0x01, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x02, 0x05, 0x05, 0x00, 0xa0, 0x81, 0xdf, 0x30, 0x11, 0x06, 0x0a, 0x60,
+  0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x09, 0x02, 0x31, 0x03, 0x13,
+  0x01, 0x33, 0x30, 0x11, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8,
+  0x45, 0x01, 0x09, 0x03, 0x31, 0x03, 0x13, 0x01, 0x30, 0x30, 0x18, 0x06,
+  0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x03, 0x31, 0x0b,
+  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30,
+  0x1f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04,
+  0x31, 0x12, 0x04, 0x10, 0xaa, 0x41, 0x9b, 0xe1, 0x01, 0x3c, 0xe0, 0xc0,
+  0x94, 0x74, 0x46, 0xe3, 0x09, 0x93, 0xce, 0x43, 0x30, 0x20, 0x06, 0x0a,
+  0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x09, 0x05, 0x31, 0x12,
+  0x04, 0x10, 0x38, 0x8e, 0x72, 0x76, 0x0d, 0xd6, 0x0e, 0xa6, 0x40, 0xc2,
+  0x52, 0x7c, 0x78, 0xfc, 0xf8, 0xe7, 0x30, 0x20, 0x06, 0x0a, 0x60, 0x86,
+  0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x09, 0x06, 0x31, 0x12, 0x04, 0x10,
+  0x96, 0xc2, 0x5b, 0x7e, 0x3a, 0x75, 0xd8, 0xca, 0x14, 0x4d, 0xce, 0x5e,
+  0x13, 0x02, 0x32, 0x26, 0x30, 0x38, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01,
+  0x86, 0xf8, 0x45, 0x01, 0x09, 0x07, 0x31, 0x2a, 0x13, 0x28, 0x33, 0x32,
+  0x39, 0x43, 0x36, 0x31, 0x30, 0x33, 0x31, 0x37, 0x45, 0x44, 0x33, 0x30,
+  0x33, 0x37, 0x36, 0x34, 0x38, 0x35, 0x46, 0x42, 0x38, 0x42, 0x38, 0x46,
+  0x30, 0x45, 0x35, 0x45, 0x32, 0x30, 0x38, 0x39, 0x38, 0x43, 0x39, 0x36,
+  0x45, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x81, 0x80, 0xac, 0x9d, 0xf9, 0x32,
+  0xdd, 0xb5, 0x58, 0x50, 0x43, 0x74, 0xa6, 0x55, 0xbb, 0xc4, 0xe0, 0x99,
+  0xde, 0x2b, 0xaa, 0x50, 0x05, 0x55, 0x15, 0x46, 0x05, 0x52, 0x2f, 0x9f,
+  0xf6, 0x3e, 0x99, 0xf9, 0x08, 0xc1, 0xdb, 0x06, 0x7b, 0x02, 0x9f, 0x94,
+  0xb6, 0x7a, 0xda, 0x34, 0x8e, 0xe2, 0x32, 0x23, 0x21, 0xf5, 0xcb, 0xac,
+  0x37, 0x6c, 0xc4, 0xac, 0x71, 0x61, 0x67, 0x68, 0xc6, 0x8a, 0xef, 0xe1,
+  0x1e, 0x6c, 0xc8, 0x22, 0x81, 0x09, 0x0d, 0x09, 0x18, 0x4f, 0xd2, 0x0e,
+  0xd8, 0x4e, 0x96, 0x6a, 0x3f, 0x4f, 0x87, 0xea, 0xe8, 0xc5, 0xc9, 0x99,
+  0xa4, 0x66, 0x4b, 0x73, 0xd9, 0x0d, 0xc9, 0x9e, 0x98, 0xeb, 0x12, 0xe9,
+  0xf5, 0xae, 0x7c, 0x1d, 0x76, 0x9e, 0x6b, 0x72, 0xf3, 0x79, 0xfa, 0x34,
+  0x4a, 0xf1, 0x34, 0x28, 0x13, 0xc8, 0x9f, 0x6c, 0xd2, 0x3a, 0xd7, 0xf7,
+  0x4f, 0x9e, 0x80, 0x8f
+};
+static unsigned int scep_reply_len = 1348;
+
+static unsigned char scep_ca[] = {
+  0x30, 0x82, 0x01, 0xf5, 0x30, 0x82, 0x01, 0x5e, 0xa0, 0x03, 0x02, 0x01,
+  0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x01, 0x04, 0x05, 0x00, 0x30, 0x0e, 0x31, 0x0c, 0x30,
+  0x0a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x03, 0x6e, 0x69, 0x69, 0x30,
+  0x1e, 0x17, 0x0d, 0x30, 0x39, 0x30, 0x32, 0x30, 0x35, 0x32, 0x33, 0x33,
+  0x32, 0x32, 0x35, 0x5a, 0x17, 0x0d, 0x31, 0x32, 0x30, 0x32, 0x30, 0x35,
+  0x32, 0x33, 0x33, 0x32, 0x32, 0x35, 0x5a, 0x30, 0x0e, 0x31, 0x0c, 0x30,
+  0x0a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x03, 0x6e, 0x69, 0x69, 0x30,
+  0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89,
+  0x02, 0x81, 0x81, 0x00, 0xeb, 0x64, 0x96, 0xb0, 0x2b, 0xb2, 0xaf, 0xd9,
+  0x06, 0xdf, 0xaf, 0x17, 0xd5, 0xeb, 0xec, 0x2f, 0x62, 0x2b, 0xaa, 0xda,
+  0x60, 0xb9, 0xc5, 0x45, 0xd7, 0x6a, 0x1b, 0x7c, 0xfc, 0x3a, 0x62, 0xe7,
+  0xaa, 0x85, 0x90, 0x16, 0x67, 0xe0, 0xc4, 0x40, 0xd4, 0x3e, 0x0d, 0xec,
+  0x75, 0x38, 0x26, 0xf8, 0x84, 0x4e, 0x69, 0xcc, 0xba, 0x7d, 0x11, 0x7e,
+  0xbb, 0xf0, 0x7b, 0xf9, 0x4f, 0x08, 0x47, 0xc4, 0x97, 0xa9, 0x98, 0xc6,
+  0x58, 0x1c, 0x84, 0xc0, 0x98, 0xc0, 0x52, 0x3f, 0x85, 0x56, 0x2e, 0x99,
+  0x76, 0xbd, 0x1e, 0xbc, 0x7a, 0xdc, 0xa9, 0xac, 0xcf, 0x87, 0x86, 0xf4,
+  0x7e, 0xb1, 0x81, 0xcd, 0x78, 0xc7, 0x22, 0xe1, 0xaa, 0x00, 0x17, 0xbc,
+  0xfa, 0x20, 0x36, 0x14, 0x7e, 0x0e, 0x82, 0x7c, 0x8c, 0xd5, 0x6a, 0x13,
+  0xb4, 0xdf, 0x62, 0x6d, 0x04, 0x3d, 0xf9, 0x34, 0x62, 0x9d, 0xcf, 0x63,
+  0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x63, 0x30, 0x61, 0x30, 0x0f, 0x06,
+  0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01,
+  0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
+  0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
+  0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xb8, 0x05, 0x16, 0x63, 0x98,
+  0x94, 0x51, 0x41, 0x5c, 0x09, 0xfe, 0x87, 0xd0, 0x7e, 0x74, 0x0c, 0x8a,
+  0x3e, 0x0c, 0x6a, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16,
+  0x04, 0x14, 0xb8, 0x05, 0x16, 0x63, 0x98, 0x94, 0x51, 0x41, 0x5c, 0x09,
+  0xfe, 0x87, 0xd0, 0x7e, 0x74, 0x0c, 0x8a, 0x3e, 0x0c, 0x6a, 0x30, 0x0d,
+  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x04, 0x05,
+  0x00, 0x03, 0x81, 0x81, 0x00, 0x7f, 0xa3, 0x4f, 0x48, 0x59, 0x53, 0x82,
+  0x31, 0xa9, 0xcd, 0x7a, 0x6f, 0x30, 0x7b, 0x50, 0x81, 0xab, 0xe9, 0x4e,
+  0xcd, 0xc2, 0x73, 0x82, 0xd9, 0xac, 0xcd, 0x72, 0x2c, 0x3f, 0x70, 0x1e,
+  0xdf, 0xd8, 0xb5, 0x17, 0xb1, 0x09, 0x85, 0xd6, 0x0a, 0xb8, 0x17, 0x18,
+  0x53, 0xde, 0xd1, 0x12, 0xe2, 0x50, 0x5a, 0x99, 0xe0, 0xa9, 0xb6, 0x76,
+  0x61, 0x38, 0xaf, 0x66, 0x85, 0xac, 0x24, 0xa0, 0x2b, 0xae, 0x34, 0xd3,
+  0x1d, 0xa8, 0xf9, 0x73, 0xfd, 0x41, 0x30, 0x77, 0x50, 0xbc, 0xbd, 0xd8,
+  0x0c, 0xe2, 0x5a, 0x1f, 0xa6, 0x64, 0xd8, 0x8f, 0x06, 0x65, 0xf5, 0xc7,
+  0x06, 0xee, 0x13, 0x26, 0xed, 0x7b, 0xd3, 0xdc, 0xc3, 0x77, 0x7a, 0x13,
+  0xd2, 0xf6, 0x9c, 0xc4, 0x45, 0xef, 0xdc, 0x24, 0x2e, 0x5d, 0xee, 0x56,
+  0x39, 0xaf, 0x4d, 0xca, 0x6b, 0x1d, 0x73, 0x78, 0x8c, 0xef, 0xe1, 0x82,
+  0xb3
+};
+static unsigned int scep_ca_len = 505;
+
+#include <fcntl.h>
+static inline void write_data(const char * path, CFDataRef data)
+{
+    int data_file = open(path, O_CREAT|O_WRONLY|O_TRUNC, 0644);
+    write(data_file, CFDataGetBytePtr(data), CFDataGetLength(data));
+    close(data_file);
+}
+
+/* Test basic add delete update copy matching stuff. */
+static void tests(void)
+{
+    CFArrayRef certs = NULL;
+    CFDataRef message = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
+        certsOnlyMsg, sizeof(certsOnlyMsg), kCFAllocatorNull);
+    ok(certs = SecCMSCertificatesOnlyMessageCopyCertificates(message),
+        "SecCMSCertificatesOnlyMessageCopyCertificates");
+    is(CFArrayGetCount(certs), 1, "certificate count is 1");
+    CFReleaseNull(message);
+
+    CFMutableArrayRef more_certs = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, certs);
+    CFReleaseNull(certs);
+    SecCertificateRef another_cert = NULL;
+    isnt(another_cert = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)),
+            NULL, "create certificate");
+
+    ok(message = SecCMSCreateCertificatesOnlyMessageIAP(another_cert), "create iAP specific cert only message");
+    ok(certs = SecCMSCertificatesOnlyMessageCopyCertificates(message),
+        "SecCMSCertificatesOnlyMessageCopyCertificates");
+    is(CFArrayGetCount(certs), 1, "certificate count is 1");
+    CFReleaseNull(certs);
+    CFReleaseNull(message);
+
+    CFArrayAppendValue(more_certs, another_cert);
+    CFReleaseSafe(another_cert);
+    ok(message = SecCMSCreateCertificatesOnlyMessage(more_certs), "create cert only message");
+    CFReleaseNull(message);
+    CFReleaseNull(more_certs);
+
+    message = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
+        openssl_generated_cms, sizeof(openssl_generated_cms), kCFAllocatorNull);
+    CFDataRef attached = NULL;
+    ok_status(SecCMSVerify(message, NULL, NULL, NULL, &attached), "just get contents");
+    static const char msg[] = "whatever man";
+    ok((size_t)CFDataGetLength(attached) == strlen(msg), "same length");
+    ok(!memcmp(msg, CFDataGetBytePtr(attached), strlen(msg)), "same data");
+    isnt(attached, NULL, "got attached content");
+    CFReleaseNull(attached);
+    SecPolicyRef policy = SecPolicyCreateBasicX509();
+    is_status(SecCMSVerify(message, NULL, policy, NULL, &attached), errSecAuthFailed, "let library verify");
+    SecTrustRef trust = NULL;
+    ok_status(SecCMSVerify(message, NULL, policy, &trust, NULL), "verify self");
+    isnt(NULL, trust, "got trustref");
+    CFReleaseNull(trust);
+    CFReleaseNull(policy);
+    CFReleaseNull(message);
+
+    CFDataRef detached =  CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
+        _codedir_bytes, _codedir_len, kCFAllocatorNull);
+    message = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
+        fk_cms, fk_cms_len, kCFAllocatorNull);
+    policy = SecPolicyCreateiPhoneApplicationSigning();
+    is_status(SecCMSVerify(message, detached, policy, &trust, NULL), errSecAuthFailed, "get trust");
+    is(trust, NULL, "no trustref: digest was wrong");
+    CFReleaseNull(trust);
+    CFReleaseNull(message);
+    CFReleaseNull(detached);
+
+    // @@@ add a test that coalesces multiple signed attributes with the same oid
+    message = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
+        fk_cms, fk_cms_len, kCFAllocatorNull);
+    CFDictionaryRef attrs = NULL;
+    ok_status(SecCMSVerifyCopyDataAndAttributes(message, NULL, NULL, NULL, NULL, &attrs), "get trust");
+    is(CFDictionaryGetCount(attrs), 5, "4 signed attributes + cooked date");
+    //CFShow(attrs);
+    CFDateRef signing_date = CFDictionaryGetValue(attrs, kSecCMSSignDate);
+    ok(signing_date, "should have signing date");
+    is(CFGetTypeID(signing_date), CFDateGetTypeID(), "attribute is CFDateRef");
+    //CFShow(signing_date);
+
+    CFReleaseNull(message);
+    CFReleaseNull(attrs);
+
+    SecCertificateRef cert = NULL;
+    SecKeyRef privKey = NULL;
+    SecIdentityRef identity = NULL;
+
+    isnt(cert = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)),
+            NULL, "create certificate");
+    isnt(privKey = SecKeyCreateRSAPrivateKey(NULL, _k1, sizeof(_k1),
+                kSecKeyEncodingPkcs1), NULL, "create private key");
+    isnt(identity = SecIdentityCreate(NULL, cert, privKey),
+            NULL, "create identity");
+    CFReleaseNull(privKey);
+
+    const uint8_t test[] = "hoi joh";
+    CFDataRef test_data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (unsigned char *)test, sizeof(test), kCFAllocatorNull);
+    /* const uint8_t oid_bytes[] = { 42, 134, 72, 134, 247, 13, 1, 9, 20 }; */
+    /* use an unknown (to us) oid: */
+    const uint8_t oid_bytes[] = { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x3F, 0x2A, 0x06 };
+    CFDataRef oid_data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (unsigned char *)oid_bytes, sizeof(oid_bytes), kCFAllocatorNull);
+    const uint8_t value_bytes[] = { 4, 7, 'h','o','i',' ','j','o','h' };
+    CFDataRef value_data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (unsigned char *)value_bytes, sizeof(value_bytes), kCFAllocatorNull);
+    const void *oid[] = { oid_data };
+    const void *value[] = { value_data };
+    CFDictionaryRef simple_attr = CFDictionaryCreate(kCFAllocatorDefault, oid, value, 1, NULL, NULL);
+    CFMutableDataRef message_data = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    ok_status(SecCMSSignDataAndAttributes(identity, test_data, false, message_data, simple_attr), "encode message");
+    ok_status(SecCMSVerifyCopyDataAndAttributes(message_data, NULL, policy, &trust, &message, &attrs), "decode message again");
+    CFReleaseNull(trust);
+    is(CFDictionaryGetCount(attrs), 6, "5 signed attributes + cooked date");
+    CFReleaseNull(attrs);
+    is(CFEqual(message, test_data), true, "contents preserved");
+    CFReleaseNull(message);
+    CFDataSetLength(message_data, 0);
+       CFDataRef empty_data = CFDataCreate(kCFAllocatorDefault, NULL, 0);
+       ok_status(SecCMSCreateSignedData(identity, empty_data, NULL, simple_attr, message_data), "Create signed data with no content");
+       CFRelease(empty_data);
+       //write_data("/var/tmp/empty_msg_with_attrs", message_data);
+    CFDataSetLength(message_data, 0);
+       ok_status(SecCMSCreateSignedData(identity, NULL, NULL, simple_attr, message_data), "Create signed data with no content");
+    uint8_t hash_data[CC_SHA1_DIGEST_LENGTH];
+    CCDigest(kCCDigestSHA1, test, sizeof(test), hash_data);
+    CFDataRef hash_cfdata = CFDataCreateWithBytesNoCopy(NULL, hash_data, sizeof(hash_data), kCFAllocatorNull);
+    CFDataSetLength(message_data, 0);
+    ok_status(SecCMSSignDigestAndAttributes(identity, hash_cfdata, message_data, simple_attr), "encode message");
+       //write_data("/var/tmp/sign_digest", message_data);
+    CFReleaseNull(hash_cfdata);
+    ok_status(SecCMSVerifyCopyDataAndAttributes(message_data, test_data, policy, &trust, &message, &attrs), "decode message again");
+    CFReleaseNull(attrs);
+    CFReleaseNull(message);
+    CFReleaseNull(trust);
+    CFReleaseNull(oid_data);
+    CFReleaseNull(value_data);
+    CFReleaseNull(simple_attr);
+
+    CFDataSetLength(message_data, 0);
+    CFMutableDictionaryRef params = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    CFDictionarySetValue(params, kSecCMSSignHashAlgorithm, kSecCMSHashingAlgorithmMD5);
+    ok_status(SecCMSCreateSignedData(identity, NULL, params, NULL, message_data), "sign md5 message");
+    //write_data("/var/tmp/md5_sign", message_data);
+    ok_status(SecCMSVerify(message_data, NULL, policy, &trust, NULL), "verify it");
+
+    message = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
+        mobileconfig_with_long_issuer, sizeof(mobileconfig_with_long_issuer),
+        kCFAllocatorNull);
+    ok_status(SecCMSVerify(message, false, policy, &trust, NULL), "verify profile");
+    CFReleaseNull(message);
+    SecTrustResultType result;
+    ok_status(SecTrustEvaluate(trust, &result), "evaluate trust");
+    is_status(result, kSecTrustResultRecoverableTrustFailure, "missing intermediate");
+    CFReleaseNull(trust);
+
+// MARK: -
+// MARK: SCEP test
+
+    SecCertificateRef scep_ca_cert = SecCertificateCreateWithBytes(kCFAllocatorDefault, scep_ca, scep_ca_len);
+    ok(scep_ca_cert, "got scep_ca_cert");
+
+    CFDataRef scep_reply_cfdata = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
+        scep_reply, scep_reply_len, kCFAllocatorNull);
+    CFArrayRef additional_certificates = CFArrayCreate(kCFAllocatorDefault, (const void **)&scep_ca_cert, 1, &kCFTypeArrayCallBacks);
+    is_status(SecCMSVerifySignedData(scep_reply_cfdata, NULL, policy, &trust, NULL, NULL, NULL), errSecAuthFailed, "decode scep message (without cert, none passed in)");
+    CFReleaseNull(trust);
+    ok_status(SecCMSVerifySignedData(scep_reply_cfdata, NULL, policy, &trust, additional_certificates, NULL, NULL), "decode scep message (without cert, signer passed in)");
+    CFReleaseNull(scep_reply_cfdata);
+    CFReleaseNull(additional_certificates);
+
+    CFReleaseNull(trust);
+    CFReleaseNull(policy);
+
+    CFDataSetLength(message_data, 0);
+    CFArrayRef recipients = CFArrayCreate(kCFAllocatorDefault, (const void **)&cert, 1, &kCFTypeArrayCallBacks);
+    ok_status(SecCMSCreateEnvelopedData(recipients, NULL, test_data, message_data), "encrypt for recip");
+    CFReleaseNull(recipients);
+    CFDataRef enc_data = CFDataCreateCopy(kCFAllocatorDefault, message_data);
+    CFDataSetLength(message_data, 0);
+
+    const void *keys_identity[] = { kSecValueRef };
+    const void *values_identity[] = { identity };
+    CFDictionaryRef identity_add = CFDictionaryCreate(NULL, keys_identity, values_identity,
+        array_size(keys_identity), NULL, NULL);
+    ok_status(SecItemAdd(identity_add, NULL), "add identity ref");
+
+    ok_status(SecCMSDecryptEnvelopedData(enc_data, message_data, NULL), "decrypt message");
+
+    ok_status(SecItemDelete(identity_add), "delete identity ref");
+
+    CFReleaseNull(identity_add);
+
+    CFReleaseNull(enc_data);
+    CFReleaseNull(cert);
+    CFReleaseNull(test_data);
+
+    CFReleaseNull(identity);
+    CFReleaseNull(message_data);
+}
+
+int si_60_cms(int argc, char *const *argv)
+{
+       plan_tests(43);
+
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-61-pkcs12.c b/sec/Security/Regressions/secitem/si-61-pkcs12.c
new file mode 100644 (file)
index 0000000..d06e83a
--- /dev/null
@@ -0,0 +1,647 @@
+/*
+ *  si-61-pkcs12.c
+ *  Security
+ *
+ *  Created by Conrad Sauerwald on 3/19/08.
+ *  Copyright (c) 2008-2010 Apple Inc. All Rights Reserved.
+ *
+ */
+
+#include <Security/SecImportExport.h>
+
+#include <CommonCrypto/CommonCryptor.h>
+#include <Security/SecIdentity.h>
+#include <Security/SecItem.h>
+#include <Security/SecItemPriv.h>
+#include <Security/SecBasePriv.h>
+#include <Security/SecKey.h>
+#include <Security/SecECKey.h>
+
+#include <Security/SecInternal.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "Security_regressions.h"
+
+unsigned char _user_one_p12[] = {
+  0x30, 0x82, 0x06, 0xf1, 0x02, 0x01, 0x03, 0x30, 0x82, 0x06, 0xb7, 0x06,
+  0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82,
+  0x06, 0xa8, 0x04, 0x82, 0x06, 0xa4, 0x30, 0x82, 0x06, 0xa0, 0x30, 0x82,
+  0x03, 0x9f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07,
+  0x06, 0xa0, 0x82, 0x03, 0x90, 0x30, 0x82, 0x03, 0x8c, 0x02, 0x01, 0x00,
+  0x30, 0x82, 0x03, 0x85, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x01, 0x0c, 0x01, 0x03, 0x30, 0x0e, 0x04, 0x08, 0x07, 0xfd, 0xeb,
+  0x68, 0x40, 0xd8, 0x58, 0x20, 0x02, 0x02, 0x08, 0x00, 0x80, 0x82, 0x03,
+  0x58, 0x03, 0x78, 0xbd, 0x4a, 0x74, 0xb4, 0x64, 0x25, 0xcc, 0xec, 0xb7,
+  0xad, 0xee, 0xc5, 0x80, 0x9b, 0xdd, 0x24, 0xab, 0x1f, 0xd8, 0xa4, 0x2d,
+  0x6f, 0xbc, 0x7d, 0xba, 0xf3, 0x7c, 0xc9, 0x93, 0x9c, 0xb4, 0xb7, 0x6e,
+  0x2c, 0x77, 0x8d, 0xf0, 0x64, 0x59, 0x96, 0x34, 0xfb, 0xd7, 0x95, 0x5e,
+  0x2a, 0xab, 0xf4, 0x64, 0x12, 0xdf, 0x68, 0x71, 0xcb, 0xa9, 0xc1, 0xe7,
+  0x36, 0x46, 0x06, 0xd7, 0xde, 0xc2, 0x00, 0x13, 0xfe, 0x9d, 0xb9, 0x43,
+  0xa2, 0x57, 0xd9, 0xb8, 0x6f, 0xa7, 0x09, 0xca, 0x2e, 0xc0, 0x72, 0x03,
+  0x12, 0x32, 0x4c, 0x26, 0x90, 0x6b, 0x8f, 0xc1, 0xbf, 0x2e, 0xab, 0x77,
+  0x9c, 0xaf, 0x0c, 0x96, 0x77, 0xc7, 0x93, 0x02, 0xdb, 0x6f, 0x5e, 0xfd,
+  0x67, 0xff, 0x48, 0x7f, 0x12, 0x69, 0x47, 0x29, 0x6a, 0xc5, 0x6d, 0xb2,
+  0x3f, 0xaa, 0x26, 0x42, 0x0d, 0x84, 0x7d, 0x3b, 0x19, 0xe5, 0x7c, 0xb2,
+  0x47, 0xf0, 0x9d, 0xd1, 0x06, 0x73, 0xc8, 0xd0, 0x85, 0xc5, 0xc5, 0x9f,
+  0xb4, 0xcc, 0x62, 0x17, 0xed, 0x42, 0x5b, 0x0a, 0x57, 0x2c, 0xc8, 0x6b,
+  0x39, 0x29, 0x83, 0x4f, 0xa0, 0xfa, 0xd0, 0x1d, 0xb3, 0x8f, 0xf0, 0x2e,
+  0x72, 0x66, 0x72, 0x7a, 0xc7, 0x9c, 0x67, 0x9e, 0x1c, 0xdf, 0x7c, 0xfc,
+  0x87, 0x1a, 0xcc, 0xdf, 0x6b, 0x22, 0x17, 0x4b, 0x16, 0x5a, 0x97, 0x16,
+  0x22, 0xea, 0xdb, 0x02, 0xab, 0x21, 0xcd, 0xb2, 0x4b, 0x85, 0x72, 0xbb,
+  0xe0, 0x98, 0xdc, 0x1a, 0xf8, 0xde, 0xd3, 0x0a, 0x2f, 0xc1, 0x2d, 0x91,
+  0x45, 0x7b, 0x33, 0xe6, 0x02, 0x0a, 0x12, 0xb2, 0x27, 0x4a, 0x44, 0x6f,
+  0x1b, 0x6a, 0x2f, 0x15, 0xab, 0x06, 0xcb, 0x19, 0xd4, 0x16, 0x14, 0x06,
+  0x18, 0x3e, 0x6a, 0x84, 0x61, 0x9e, 0x28, 0x61, 0xa6, 0xaa, 0x51, 0x6b,
+  0x3b, 0x66, 0x95, 0xd8, 0x9a, 0x2c, 0x65, 0x99, 0x58, 0xad, 0xcf, 0xdf,
+  0x8a, 0x0f, 0x60, 0x20, 0xc5, 0x1a, 0x3e, 0xfc, 0x28, 0x7e, 0x8f, 0x7f,
+  0xe6, 0xa5, 0x48, 0xff, 0x2b, 0x65, 0xfd, 0xa5, 0xa2, 0x9e, 0x0d, 0x1d,
+  0xe3, 0xf8, 0x68, 0x02, 0xac, 0x67, 0x0e, 0x12, 0x27, 0x37, 0x06, 0x95,
+  0x0a, 0x59, 0xdf, 0x42, 0x6b, 0x0c, 0xc0, 0x79, 0xc8, 0x38, 0xde, 0x0c,
+  0x60, 0x36, 0x89, 0xdf, 0xd0, 0x58, 0xd9, 0x67, 0x84, 0xf0, 0x54, 0x67,
+  0xd3, 0x83, 0x27, 0x13, 0x99, 0xff, 0x0e, 0x68, 0x04, 0x7e, 0x65, 0xe3,
+  0x69, 0x74, 0xec, 0x0e, 0x63, 0x2c, 0x05, 0xc2, 0x64, 0x43, 0x6d, 0x78,
+  0xa0, 0xe8, 0x76, 0x9c, 0x60, 0x6b, 0xad, 0x0f, 0x5e, 0x2d, 0x44, 0xc1,
+  0xa1, 0x2c, 0x5c, 0x2a, 0x01, 0x7b, 0xe3, 0xba, 0xbd, 0x8b, 0xd0, 0x7b,
+  0x98, 0x77, 0x5e, 0xe9, 0xb0, 0xda, 0x95, 0x97, 0x6c, 0x32, 0x60, 0x6f,
+  0x76, 0xf2, 0x07, 0x05, 0xd7, 0x3a, 0x40, 0x0b, 0x3e, 0xfc, 0xae, 0x72,
+  0x30, 0xa2, 0x9c, 0x2f, 0x66, 0xea, 0x84, 0x1e, 0xa1, 0xc8, 0x67, 0x2c,
+  0x07, 0x46, 0x84, 0xed, 0x38, 0x74, 0x75, 0xc9, 0x68, 0x7f, 0x63, 0x08,
+  0x04, 0xb8, 0xb4, 0xd3, 0x62, 0x11, 0x50, 0x32, 0x20, 0x1e, 0xce, 0xf9,
+  0x43, 0xc4, 0xe8, 0xb4, 0x01, 0x28, 0x85, 0x1b, 0x1e, 0x62, 0x60, 0x9c,
+  0x43, 0xa7, 0xab, 0xd2, 0x8f, 0x25, 0xa6, 0x2d, 0x09, 0x7d, 0x25, 0x05,
+  0x0c, 0x9e, 0x84, 0xdc, 0xd9, 0xf7, 0xf2, 0xda, 0x87, 0xce, 0x8e, 0x23,
+  0x22, 0x9c, 0x4f, 0x4a, 0x0c, 0xe2, 0x6a, 0x2b, 0x18, 0x17, 0x65, 0x08,
+  0xda, 0x18, 0x57, 0xfd, 0x34, 0x97, 0xbd, 0xc5, 0xce, 0x76, 0xa8, 0x22,
+  0xee, 0x60, 0x63, 0x78, 0x30, 0x04, 0xfa, 0x49, 0x63, 0x65, 0x5f, 0xe4,
+  0x75, 0x9f, 0x68, 0xf6, 0x93, 0x86, 0xf2, 0x76, 0x00, 0x91, 0xd1, 0x7b,
+  0xcf, 0xcc, 0x55, 0xca, 0x4a, 0x2c, 0x35, 0xe0, 0x64, 0xb2, 0xc0, 0x2c,
+  0x02, 0x84, 0xa2, 0xd8, 0x54, 0x08, 0xbe, 0x93, 0xfd, 0x77, 0x5d, 0xa5,
+  0x4e, 0xc7, 0x07, 0x39, 0xed, 0xa5, 0x68, 0x0b, 0x93, 0x65, 0xc0, 0xd3,
+  0x42, 0x55, 0xc8, 0x61, 0x92, 0x02, 0x34, 0x67, 0x93, 0x4e, 0xcb, 0xa1,
+  0x99, 0x38, 0xe6, 0x93, 0x3b, 0xe2, 0x4c, 0x7d, 0x55, 0xc4, 0xd2, 0x55,
+  0x81, 0x4a, 0xe4, 0xd7, 0x1c, 0x25, 0x85, 0xd8, 0xd2, 0x3e, 0x1c, 0xe6,
+  0xd6, 0xdb, 0x85, 0x02, 0x2b, 0x67, 0x07, 0x5e, 0xdc, 0x19, 0x82, 0x10,
+  0xa7, 0x8d, 0x2c, 0x08, 0xad, 0x4a, 0x7c, 0x54, 0x81, 0x65, 0xb6, 0xca,
+  0x4a, 0x4c, 0x5d, 0xed, 0xb4, 0x3a, 0x81, 0x0c, 0xc5, 0x65, 0x01, 0x89,
+  0x51, 0x6f, 0xbc, 0xfa, 0x90, 0x78, 0x6c, 0x81, 0x42, 0x00, 0xa3, 0x45,
+  0xa3, 0x58, 0xa7, 0x09, 0x84, 0xa6, 0x6e, 0xae, 0xc6, 0x01, 0x84, 0x9e,
+  0x8a, 0x78, 0xa9, 0xd8, 0x48, 0x07, 0x7c, 0x02, 0x44, 0x4d, 0xcf, 0xd9,
+  0x6e, 0xae, 0xbd, 0xe2, 0x8c, 0xb4, 0x92, 0x65, 0x24, 0x43, 0x67, 0xb2,
+  0x92, 0x86, 0xac, 0x81, 0x95, 0x48, 0xdc, 0xdf, 0xd7, 0x7d, 0x3b, 0xf2,
+  0x4c, 0x4b, 0x19, 0xb0, 0xdd, 0x87, 0x1d, 0xd9, 0xf6, 0x0f, 0x30, 0x40,
+  0x60, 0x78, 0x7b, 0xf8, 0xcf, 0x84, 0x60, 0x7c, 0x2d, 0xdc, 0xd3, 0x6b,
+  0xbf, 0x68, 0xd3, 0x86, 0x7e, 0x22, 0xee, 0x81, 0x25, 0xdf, 0xee, 0x2b,
+  0x2b, 0x39, 0x6b, 0xfe, 0x91, 0xa9, 0x41, 0x67, 0xe4, 0x8b, 0x14, 0xd6,
+  0x9f, 0x12, 0xaf, 0x4f, 0x89, 0x35, 0xd9, 0x6f, 0xd1, 0x48, 0xae, 0x89,
+  0xd3, 0x13, 0x8e, 0x13, 0xa0, 0xba, 0xc8, 0xef, 0xab, 0x2e, 0xdf, 0xe4,
+  0x1f, 0xbd, 0xb7, 0x26, 0x28, 0x75, 0xe4, 0x7a, 0x11, 0x29, 0x8e, 0xe6,
+  0x59, 0x62, 0x67, 0x2f, 0xd8, 0x8b, 0x87, 0xee, 0xcf, 0x80, 0x46, 0x14,
+  0xd5, 0x77, 0xd8, 0x6b, 0xb0, 0xa4, 0xa0, 0xce, 0x93, 0xa8, 0x2c, 0x5f,
+  0x4b, 0x3c, 0x56, 0x7b, 0x4e, 0x56, 0x2e, 0x7b, 0x3b, 0xa8, 0x26, 0x3e,
+  0x96, 0x57, 0x05, 0x76, 0xc4, 0xff, 0x26, 0x7a, 0xe6, 0x3b, 0x21, 0xd2,
+  0x76, 0x2b, 0xd3, 0xb8, 0x2d, 0x57, 0x7b, 0x62, 0xdb, 0x80, 0x9a, 0xde,
+  0xad, 0x4a, 0x1b, 0x85, 0xb7, 0xd0, 0xa6, 0x0e, 0x85, 0x0a, 0xbb, 0x43,
+  0x9f, 0x5c, 0x03, 0x4f, 0x9c, 0x47, 0x11, 0xb2, 0x5c, 0xc8, 0x8f, 0xb5,
+  0x8d, 0xf1, 0x28, 0x37, 0xca, 0x30, 0x82, 0x02, 0xf9, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x02, 0xea,
+  0x04, 0x82, 0x02, 0xe6, 0x30, 0x82, 0x02, 0xe2, 0x30, 0x82, 0x02, 0xde,
+  0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01,
+  0x02, 0xa0, 0x82, 0x02, 0xa6, 0x30, 0x82, 0x02, 0xa2, 0x30, 0x1c, 0x06,
+  0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x03, 0x30,
+  0x0e, 0x04, 0x08, 0xfd, 0x54, 0x70, 0x85, 0x3f, 0x2b, 0x23, 0x6c, 0x02,
+  0x02, 0x08, 0x00, 0x04, 0x82, 0x02, 0x80, 0xbc, 0x6f, 0xe7, 0x00, 0x36,
+  0xd9, 0xe9, 0xba, 0x49, 0x04, 0xd5, 0x06, 0xb0, 0xbb, 0x6b, 0xe8, 0x8d,
+  0x51, 0x46, 0x38, 0xdc, 0x00, 0xc6, 0xf0, 0xc7, 0xb0, 0x9d, 0xf9, 0x82,
+  0xec, 0x87, 0x08, 0x6a, 0x7f, 0xce, 0xb8, 0x22, 0x55, 0xae, 0x24, 0x8f,
+  0x77, 0x50, 0x40, 0xf2, 0x72, 0x9d, 0xc9, 0xc9, 0x97, 0x0d, 0x1c, 0xee,
+  0x8c, 0x30, 0x0b, 0xfe, 0x8c, 0x63, 0x1e, 0x1b, 0x6a, 0x13, 0xaa, 0xf5,
+  0x60, 0xf1, 0x38, 0x00, 0x5b, 0x55, 0x18, 0x43, 0xf5, 0xea, 0x9e, 0xdc,
+  0x12, 0xb4, 0xfd, 0xf8, 0xee, 0x62, 0x0d, 0x67, 0x32, 0x23, 0xf5, 0x3c,
+  0x43, 0x5f, 0x18, 0xea, 0x3a, 0x1b, 0x7f, 0xcb, 0x20, 0xe4, 0x80, 0xb3,
+  0xd4, 0x37, 0x1a, 0x58, 0x59, 0x3b, 0x40, 0xd7, 0x8e, 0x30, 0xbe, 0xee,
+  0x7b, 0x65, 0xa4, 0x39, 0xf5, 0x4c, 0xa8, 0x8c, 0x20, 0x79, 0xe3, 0x1f,
+  0x72, 0x82, 0x1f, 0xe3, 0x16, 0xfd, 0x29, 0xe2, 0x90, 0xa0, 0xac, 0x54,
+  0xad, 0x01, 0x18, 0x42, 0x02, 0xef, 0xae, 0x61, 0x7b, 0xf9, 0x89, 0x8c,
+  0x40, 0x97, 0xfb, 0x5a, 0x4c, 0xee, 0x9a, 0xb0, 0x02, 0xc3, 0x48, 0x28,
+  0x58, 0xb0, 0x9a, 0x98, 0xe8, 0x70, 0x53, 0xc7, 0x7d, 0x40, 0x2e, 0x6d,
+  0x0a, 0x0c, 0xa1, 0xb6, 0xac, 0x48, 0xe0, 0xde, 0x3a, 0x37, 0x52, 0x77,
+  0xc5, 0x89, 0x8f, 0xa7, 0xf8, 0xaf, 0xfc, 0x94, 0x2d, 0xb7, 0xf1, 0xff,
+  0x79, 0x44, 0x29, 0x69, 0xee, 0x6f, 0xaf, 0x3e, 0xe6, 0xe4, 0x09, 0x62,
+  0x45, 0x36, 0xb2, 0x11, 0x3d, 0x0a, 0xdc, 0x3a, 0xc6, 0x6b, 0x46, 0x48,
+  0x42, 0x60, 0xd5, 0x92, 0x49, 0x3e, 0xd8, 0xbc, 0x4b, 0x47, 0x2b, 0x2a,
+  0xe9, 0xa6, 0xe5, 0xca, 0x6a, 0x39, 0x87, 0x3b, 0xa8, 0xa4, 0xae, 0x29,
+  0x36, 0xb4, 0x39, 0xe2, 0x7e, 0x9a, 0x22, 0x69, 0xc6, 0xa3, 0x95, 0xa3,
+  0x20, 0xf9, 0x6e, 0xc9, 0xfd, 0x4c, 0x3a, 0xd4, 0x9d, 0x9c, 0xeb, 0x91,
+  0x95, 0xdc, 0x1a, 0x3b, 0xd8, 0x0d, 0x0a, 0x87, 0x52, 0xef, 0x13, 0x77,
+  0xee, 0x92, 0x25, 0xba, 0xc7, 0x7a, 0x16, 0x2d, 0x85, 0x78, 0x3e, 0xbb,
+  0x0f, 0x95, 0xed, 0x60, 0xd0, 0x01, 0x60, 0xa2, 0x69, 0x3b, 0x3c, 0x63,
+  0x5c, 0x10, 0x78, 0x15, 0x72, 0x40, 0xc6, 0x1e, 0x0e, 0x34, 0xee, 0x71,
+  0x1d, 0xdf, 0xfb, 0x5f, 0x58, 0x3a, 0xdf, 0xb9, 0xc0, 0xa1, 0xa2, 0x02,
+  0x25, 0xc7, 0x16, 0xe4, 0x50, 0x64, 0xa8, 0x84, 0x3e, 0xa0, 0xb2, 0x8a,
+  0xfa, 0xbe, 0x55, 0x17, 0xf9, 0x7c, 0x64, 0x4b, 0xa6, 0xf7, 0x50, 0x52,
+  0x06, 0x39, 0xb1, 0x30, 0x28, 0x32, 0xa7, 0x7b, 0xaf, 0x18, 0xbd, 0x8b,
+  0x25, 0x6d, 0xde, 0x95, 0x82, 0xfb, 0x65, 0x71, 0x31, 0xca, 0x3e, 0x41,
+  0xb1, 0xa9, 0xf1, 0xec, 0x3c, 0xbc, 0x24, 0x49, 0x12, 0x1a, 0x49, 0x66,
+  0x90, 0xb2, 0xc4, 0x36, 0xe3, 0xd8, 0x93, 0x66, 0x6c, 0xc6, 0x81, 0xef,
+  0xf3, 0x61, 0xab, 0x4c, 0xba, 0x8e, 0x39, 0x47, 0xeb, 0x9b, 0xdf, 0x59,
+  0x9e, 0x45, 0xdc, 0x64, 0x51, 0xfb, 0x2d, 0x4c, 0x61, 0xbe, 0x70, 0x3a,
+  0x20, 0x86, 0x09, 0x75, 0xbe, 0x03, 0xdc, 0x35, 0x00, 0xae, 0xa9, 0x3d,
+  0xb4, 0xa2, 0x3a, 0xfb, 0xc5, 0x63, 0xb6, 0xf1, 0x92, 0x58, 0x84, 0x42,
+  0xf3, 0x11, 0x47, 0x38, 0xd4, 0x47, 0x59, 0x7d, 0xc6, 0xb6, 0x31, 0x83,
+  0x7e, 0x44, 0x41, 0xca, 0x50, 0x34, 0xf6, 0xf2, 0x23, 0x1f, 0x4d, 0x7d,
+  0x4d, 0xf7, 0xe8, 0x0b, 0x58, 0x0f, 0x94, 0x1f, 0x66, 0x8b, 0xe6, 0x6d,
+  0xe3, 0x91, 0xf8, 0xe7, 0xca, 0xca, 0x86, 0xdb, 0x66, 0x7e, 0x3e, 0x0c,
+  0x7a, 0xa8, 0xd4, 0xd4, 0xa2, 0x98, 0xe7, 0x33, 0x09, 0x7a, 0x77, 0x0d,
+  0x63, 0x48, 0x0a, 0x7e, 0x27, 0x2e, 0x59, 0x87, 0xcc, 0x47, 0xa6, 0x2d,
+  0x14, 0xfc, 0x1f, 0xa7, 0x31, 0xba, 0xac, 0xef, 0x4e, 0xf2, 0x02, 0xdc,
+  0x8c, 0x7b, 0x44, 0x08, 0x4a, 0xeb, 0xbe, 0x48, 0xe1, 0xf0, 0x56, 0xb1,
+  0xe2, 0x1a, 0x5a, 0x39, 0x11, 0x3b, 0x56, 0x5b, 0x7f, 0x05, 0xd4, 0x99,
+  0x6d, 0xa1, 0x46, 0x42, 0x9a, 0x69, 0xc8, 0x97, 0x5c, 0x3b, 0xfd, 0x18,
+  0x28, 0x98, 0xaa, 0x7a, 0x66, 0xf1, 0x7d, 0xcb, 0x60, 0x38, 0xd8, 0x97,
+  0xed, 0x28, 0xec, 0xbb, 0x6e, 0xf0, 0x83, 0xdc, 0x1c, 0xae, 0xc2, 0xd3,
+  0xa5, 0x2b, 0xd5, 0x13, 0x22, 0xf6, 0x6c, 0x7c, 0x43, 0x74, 0xf3, 0xed,
+  0xd1, 0x89, 0x0a, 0x2c, 0x93, 0xb0, 0x42, 0xa3, 0x5f, 0xda, 0xa7, 0x04,
+  0x76, 0x33, 0xb8, 0x05, 0xf5, 0xaf, 0xf4, 0x91, 0x43, 0x88, 0xde, 0xfc,
+  0x68, 0xd0, 0xa4, 0x1f, 0x6e, 0x47, 0xc3, 0x73, 0x96, 0xfa, 0x4d, 0x31,
+  0x25, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x09, 0x15, 0x31, 0x16, 0x04, 0x14, 0x9e, 0x4f, 0xb2, 0x4e, 0x45, 0x98,
+  0x37, 0x90, 0x63, 0x59, 0xe3, 0x7b, 0xcc, 0xca, 0x76, 0x0a, 0xaf, 0x95,
+  0x35, 0x37, 0x30, 0x31, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
+  0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x82, 0xbc, 0x96, 0xb1, 0x5d,
+  0x7f, 0x5d, 0x93, 0x54, 0x42, 0x95, 0x55, 0x01, 0x6a, 0xcd, 0x65, 0x01,
+  0x7a, 0x06, 0xcf, 0x04, 0x08, 0x39, 0xfd, 0x29, 0x7c, 0xbe, 0x39, 0x07,
+  0xd5, 0x02, 0x02, 0x08, 0x00
+};
+
+unsigned char _user_two_p12[] = {
+  0x30, 0x82, 0x06, 0xf1, 0x02, 0x01, 0x03, 0x30, 0x82, 0x06, 0xb7, 0x06,
+  0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82,
+  0x06, 0xa8, 0x04, 0x82, 0x06, 0xa4, 0x30, 0x82, 0x06, 0xa0, 0x30, 0x82,
+  0x03, 0x9f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07,
+  0x06, 0xa0, 0x82, 0x03, 0x90, 0x30, 0x82, 0x03, 0x8c, 0x02, 0x01, 0x00,
+  0x30, 0x82, 0x03, 0x85, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x01, 0x0c, 0x01, 0x06, 0x30, 0x0e, 0x04, 0x08, 0x59, 0x5c, 0x39,
+  0x74, 0xd7, 0x82, 0x11, 0x51, 0x02, 0x02, 0x08, 0x00, 0x80, 0x82, 0x03,
+  0x58, 0xa6, 0xd1, 0xa1, 0x2f, 0x26, 0x9d, 0x85, 0x45, 0xae, 0x87, 0x8f,
+  0xd4, 0x13, 0x32, 0x90, 0xba, 0x53, 0x3b, 0x65, 0x02, 0xa9, 0xa0, 0xe6,
+  0x45, 0x30, 0xee, 0x1c, 0xf6, 0x24, 0x38, 0x22, 0x26, 0x37, 0x50, 0x2d,
+  0x7c, 0x9b, 0x66, 0xa6, 0x13, 0xed, 0xd5, 0x9f, 0xd3, 0x6d, 0xc6, 0x2b,
+  0x9c, 0x66, 0x22, 0x3f, 0x95, 0xa5, 0x99, 0xc9, 0x8b, 0xcc, 0x40, 0x4b,
+  0xa8, 0xd0, 0x2a, 0x6f, 0x16, 0x9b, 0xc3, 0xec, 0xfc, 0xa4, 0x28, 0xc5,
+  0xb0, 0xa8, 0xc2, 0x96, 0xb4, 0xa2, 0x9d, 0x8d, 0x33, 0xc3, 0x6d, 0xc8,
+  0xac, 0x64, 0x34, 0x73, 0xda, 0x1c, 0x5b, 0x07, 0xc1, 0x45, 0xac, 0xe2,
+  0x00, 0x56, 0xaf, 0x38, 0xc1, 0x30, 0xe4, 0x65, 0x24, 0x42, 0x67, 0x2d,
+  0xcf, 0x19, 0xad, 0x2a, 0xe2, 0x04, 0x2d, 0x5a, 0x48, 0xd1, 0xdc, 0xbe,
+  0x88, 0xb7, 0x31, 0x5b, 0x37, 0x75, 0x6e, 0xa5, 0xe2, 0x74, 0xf0, 0xba,
+  0xac, 0xe2, 0x24, 0x84, 0x6d, 0x94, 0x65, 0xb4, 0x55, 0x3f, 0xf8, 0x8d,
+  0xd3, 0x13, 0xa1, 0xce, 0x33, 0x4f, 0x39, 0xc7, 0x80, 0x1a, 0x0e, 0x68,
+  0x0f, 0x63, 0xc6, 0x36, 0x01, 0xaa, 0xd3, 0x3b, 0x03, 0xe4, 0xa9, 0xdd,
+  0x4d, 0x4a, 0xcc, 0xf8, 0x2b, 0x55, 0xa7, 0x47, 0x31, 0x39, 0x14, 0xd5,
+  0x0f, 0x3f, 0x38, 0xfd, 0xc7, 0xe6, 0x99, 0x36, 0xc2, 0x1b, 0xa8, 0x99,
+  0x16, 0xa8, 0x05, 0x7a, 0xc4, 0x66, 0x97, 0x13, 0x09, 0x0d, 0x15, 0x14,
+  0x66, 0x3c, 0x9b, 0x39, 0x6c, 0x10, 0xc9, 0xc5, 0xbe, 0x69, 0xd7, 0x13,
+  0x21, 0xb3, 0xd8, 0x29, 0x50, 0xf4, 0x40, 0x77, 0x09, 0xb3, 0x32, 0xf2,
+  0x88, 0xa5, 0x05, 0x5e, 0x14, 0x77, 0x41, 0xd5, 0x31, 0x82, 0xcb, 0xea,
+  0xe0, 0x56, 0xd3, 0xb0, 0x3e, 0x27, 0xd7, 0x9d, 0x46, 0x04, 0x07, 0x86,
+  0x8b, 0xb2, 0x0f, 0x45, 0xc4, 0x8b, 0xff, 0xcb, 0x39, 0x54, 0x6c, 0xe0,
+  0x9b, 0x6d, 0xbc, 0x5d, 0x1c, 0x0e, 0xb2, 0xba, 0xfe, 0x94, 0x2a, 0x9c,
+  0x4f, 0x84, 0x44, 0x17, 0xc4, 0x07, 0x0b, 0x8d, 0x6f, 0x90, 0x23, 0xfb,
+  0xf3, 0xe4, 0x0f, 0x4a, 0xf4, 0x40, 0xf5, 0xf4, 0xfe, 0xb4, 0x32, 0xde,
+  0x01, 0x0c, 0x00, 0x3a, 0x0a, 0x9e, 0xa0, 0x1a, 0x95, 0x94, 0xbe, 0x3c,
+  0x75, 0x32, 0x38, 0x50, 0x07, 0xd3, 0x70, 0x30, 0x47, 0x7a, 0xce, 0x74,
+  0x57, 0x8f, 0x7b, 0x5c, 0x2b, 0xb8, 0xc0, 0x72, 0xbf, 0x9a, 0xab, 0xc0,
+  0xe4, 0x26, 0xec, 0x91, 0x80, 0xba, 0x45, 0xa7, 0xc0, 0x18, 0xcf, 0xed,
+  0x24, 0x9f, 0x1b, 0x07, 0xcb, 0x1b, 0xd2, 0x81, 0xe8, 0x4b, 0x26, 0x0a,
+  0xf6, 0x4c, 0x81, 0x5f, 0x4f, 0x2a, 0x7c, 0x79, 0x25, 0xd6, 0x8b, 0xe7,
+  0x00, 0x82, 0xf2, 0x6e, 0x6c, 0x63, 0x38, 0x19, 0x79, 0x05, 0x0e, 0xb8,
+  0x13, 0x2b, 0x30, 0x2b, 0xd3, 0xe3, 0x85, 0x6b, 0x75, 0x32, 0xc2, 0x58,
+  0xa4, 0xf0, 0xd3, 0x0a, 0xae, 0xee, 0x3e, 0x10, 0x28, 0x5d, 0xd5, 0x09,
+  0x6f, 0x0f, 0xa2, 0x15, 0x6f, 0x3c, 0x40, 0xb9, 0x74, 0x7f, 0x35, 0xb1,
+  0xd6, 0x58, 0x6a, 0x09, 0x2c, 0x29, 0x0d, 0x69, 0x37, 0xae, 0x17, 0xd2,
+  0x98, 0xef, 0x4a, 0xbd, 0x18, 0x3f, 0x97, 0x83, 0x81, 0x63, 0x8f, 0xc5,
+  0x98, 0x2a, 0xb8, 0xe9, 0x32, 0xef, 0x6b, 0x4c, 0x26, 0xd8, 0x1d, 0x8f,
+  0x5c, 0x68, 0xe0, 0x68, 0x2f, 0x5e, 0x2c, 0x85, 0xa5, 0xbc, 0x88, 0x56,
+  0x1b, 0xc7, 0x0e, 0x22, 0x80, 0x80, 0x36, 0x43, 0x68, 0x5d, 0xd4, 0x0e,
+  0xb5, 0x08, 0x82, 0xfe, 0xae, 0xc5, 0xde, 0x61, 0x1e, 0xf8, 0xfe, 0x64,
+  0x66, 0xf2, 0xda, 0x9e, 0x8e, 0xb9, 0x8e, 0xa9, 0xcd, 0xe4, 0x17, 0xe0,
+  0x12, 0xd4, 0x37, 0x54, 0xd0, 0x24, 0xca, 0xcc, 0xc0, 0xa9, 0xd4, 0x98,
+  0x1d, 0xe9, 0x04, 0x64, 0x50, 0x3d, 0x76, 0x0f, 0xf7, 0x75, 0xde, 0xb5,
+  0x5c, 0x0a, 0x3b, 0x70, 0x3e, 0xeb, 0x0b, 0x26, 0x98, 0x0e, 0x47, 0x6b,
+  0x36, 0x3d, 0x7b, 0x04, 0x20, 0x26, 0xf7, 0xe6, 0x01, 0xbf, 0xda, 0xc9,
+  0x09, 0xce, 0x2f, 0xd9, 0xeb, 0x8a, 0x19, 0x68, 0x9b, 0x67, 0x5d, 0x2a,
+  0xef, 0x74, 0x6f, 0xcd, 0xd2, 0x3b, 0xdc, 0x65, 0xbc, 0x79, 0x40, 0x12,
+  0x52, 0x3e, 0x57, 0xc4, 0x12, 0xf2, 0x4e, 0x1a, 0x5d, 0x63, 0x55, 0x0a,
+  0xb7, 0x70, 0x85, 0x09, 0x6e, 0x97, 0x2f, 0xf8, 0x7b, 0x02, 0xb6, 0x03,
+  0xa3, 0x7d, 0x91, 0x06, 0xb9, 0xf4, 0xfc, 0x45, 0x03, 0x6a, 0xb2, 0xc0,
+  0x8c, 0x75, 0xe3, 0x16, 0x0e, 0xa7, 0x65, 0x9a, 0xd4, 0x05, 0x7e, 0x03,
+  0xe0, 0x42, 0xbd, 0x8f, 0x55, 0xac, 0xf3, 0xde, 0x70, 0x0a, 0xc6, 0xbc,
+  0x0d, 0xda, 0x14, 0x87, 0x3e, 0xa2, 0x18, 0x28, 0xa7, 0x4a, 0xea, 0x21,
+  0x12, 0x70, 0xd3, 0x31, 0xed, 0x22, 0x5e, 0xc6, 0xed, 0xf0, 0xc1, 0xee,
+  0xe6, 0x4b, 0x34, 0x22, 0x97, 0x87, 0x37, 0x24, 0x8f, 0xe4, 0x47, 0x99,
+  0x5d, 0x0a, 0x82, 0xe3, 0xca, 0x88, 0xcf, 0x35, 0xa3, 0xe5, 0xa3, 0xef,
+  0x8b, 0x2c, 0x0a, 0x2c, 0x1f, 0xe4, 0x24, 0xaa, 0xf2, 0x9e, 0x85, 0x28,
+  0xae, 0x60, 0xcc, 0x0a, 0xfc, 0x94, 0x5b, 0x4a, 0xe4, 0x6e, 0xeb, 0x59,
+  0xa3, 0x6f, 0x86, 0xac, 0xc5, 0x2c, 0xf5, 0xaa, 0x10, 0xf4, 0x9e, 0x08,
+  0xc5, 0xbe, 0x8b, 0x9e, 0xe5, 0xd7, 0x6b, 0x49, 0xde, 0x0c, 0x16, 0x38,
+  0x6f, 0xa5, 0x74, 0x62, 0x93, 0x44, 0xd8, 0xf7, 0x6d, 0x40, 0x98, 0xf7,
+  0xfd, 0x6b, 0xc9, 0xda, 0xc7, 0x49, 0xf5, 0x7c, 0x83, 0x9e, 0xc8, 0xe3,
+  0x6e, 0x51, 0x93, 0xfe, 0xb4, 0xe6, 0xa4, 0x2c, 0x18, 0xe8, 0x96, 0xb6,
+  0xb7, 0x11, 0x4d, 0xd4, 0x94, 0x34, 0xfc, 0x4f, 0x2f, 0x17, 0x58, 0x84,
+  0x5a, 0xaa, 0xb7, 0x8f, 0x41, 0x65, 0x7a, 0xac, 0xbc, 0x7d, 0x77, 0x1f,
+  0xf2, 0x99, 0xba, 0x60, 0xe1, 0xe0, 0x24, 0xc0, 0x24, 0x56, 0x08, 0x24,
+  0x39, 0x12, 0xd3, 0xa8, 0xa3, 0x51, 0x37, 0xab, 0xd6, 0xab, 0x78, 0x3c,
+  0x82, 0x91, 0xb8, 0x8e, 0xbf, 0xe6, 0xfd, 0x19, 0x05, 0x60, 0x14, 0xdf,
+  0x19, 0x2f, 0x07, 0x54, 0x11, 0xea, 0x45, 0xec, 0x37, 0xaa, 0x2b, 0x9d,
+  0xa4, 0xfe, 0xd4, 0x34, 0xdf, 0xcc, 0x33, 0xda, 0x09, 0xa9, 0xa9, 0x49,
+  0x10, 0x48, 0xc3, 0x63, 0x49, 0x30, 0x82, 0x02, 0xf9, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x02, 0xea,
+  0x04, 0x82, 0x02, 0xe6, 0x30, 0x82, 0x02, 0xe2, 0x30, 0x82, 0x02, 0xde,
+  0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01,
+  0x02, 0xa0, 0x82, 0x02, 0xa6, 0x30, 0x82, 0x02, 0xa2, 0x30, 0x1c, 0x06,
+  0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x03, 0x30,
+  0x0e, 0x04, 0x08, 0x8d, 0xff, 0x52, 0xa2, 0x8e, 0x75, 0xb1, 0x64, 0x02,
+  0x02, 0x08, 0x00, 0x04, 0x82, 0x02, 0x80, 0x57, 0x31, 0xfa, 0x59, 0x1f,
+  0xec, 0x07, 0x6b, 0xcc, 0x29, 0x14, 0x9f, 0xbe, 0x11, 0x4f, 0x1b, 0xb2,
+  0x14, 0x51, 0xca, 0x2e, 0x3c, 0x53, 0xf5, 0x8f, 0xab, 0x90, 0xa0, 0xae,
+  0xf1, 0xa8, 0xd8, 0xc9, 0x51, 0xae, 0x5b, 0x84, 0xc8, 0xfa, 0xfe, 0x54,
+  0x33, 0xf3, 0x02, 0xb2, 0x74, 0x6c, 0x77, 0xcf, 0xe8, 0xdf, 0xab, 0x45,
+  0xaf, 0xb2, 0x1e, 0x18, 0xdd, 0x57, 0xa6, 0x3a, 0xc1, 0xac, 0xab, 0x83,
+  0x48, 0x91, 0x24, 0x06, 0xce, 0x58, 0x69, 0x15, 0x23, 0xf4, 0x19, 0x8f,
+  0x53, 0xd5, 0x92, 0x76, 0x31, 0x35, 0x75, 0xd6, 0x5d, 0xb3, 0x87, 0xe2,
+  0xb3, 0x96, 0x85, 0x30, 0xe0, 0x93, 0xff, 0x02, 0x7b, 0xba, 0x89, 0x50,
+  0xa9, 0xbc, 0x9d, 0x85, 0x20, 0x17, 0x3e, 0x1c, 0xef, 0xcf, 0xf9, 0x69,
+  0xdf, 0x89, 0xe8, 0x11, 0x4b, 0xcc, 0x48, 0x9a, 0x5a, 0x1a, 0x6b, 0x86,
+  0xc4, 0x74, 0xc8, 0x8f, 0x34, 0x0a, 0xbf, 0xec, 0xc8, 0x9d, 0x0f, 0x52,
+  0xd7, 0x0e, 0x39, 0x46, 0x42, 0xf8, 0x8d, 0x14, 0xf5, 0x44, 0x73, 0xb4,
+  0x78, 0x31, 0x89, 0x02, 0xc6, 0x8d, 0xae, 0x2f, 0x9c, 0x7c, 0x7a, 0x5b,
+  0x55, 0x04, 0xe7, 0x81, 0x84, 0x36, 0xee, 0xb8, 0x47, 0x81, 0x65, 0x95,
+  0x8e, 0x35, 0x7f, 0x15, 0xdc, 0xeb, 0xdc, 0x28, 0xe2, 0x16, 0xe8, 0x86,
+  0x1c, 0x7d, 0x1a, 0xd8, 0xe5, 0x8f, 0x4c, 0x29, 0x17, 0x1a, 0x9e, 0xe9,
+  0xc2, 0xd1, 0x84, 0x78, 0x76, 0xd6, 0x93, 0x8c, 0x29, 0x62, 0x3a, 0x2d,
+  0xdd, 0xc6, 0xb4, 0xab, 0x32, 0xd9, 0x18, 0x2a, 0x1d, 0x38, 0x11, 0x48,
+  0x4d, 0x0b, 0xd0, 0x3c, 0xed, 0x51, 0x0f, 0x77, 0x97, 0x67, 0x40, 0x96,
+  0x64, 0x99, 0x34, 0x56, 0xf5, 0x45, 0xe9, 0xfe, 0x87, 0x5b, 0xb2, 0xe9,
+  0x01, 0x1a, 0xfc, 0x83, 0x7e, 0x9f, 0x8b, 0xc9, 0xb2, 0xa9, 0x99, 0x1f,
+  0xb2, 0x32, 0xed, 0xb8, 0x21, 0x00, 0xf5, 0x94, 0x56, 0x15, 0x72, 0xee,
+  0x84, 0x0b, 0x98, 0x9d, 0x9f, 0xc9, 0xf6, 0x4b, 0x65, 0x71, 0xdb, 0xc0,
+  0x49, 0xd8, 0xf8, 0x86, 0x13, 0xc4, 0x23, 0xf7, 0xe3, 0x30, 0xb6, 0x6d,
+  0x2f, 0x72, 0xdb, 0x01, 0x7b, 0x68, 0x46, 0xbe, 0xd6, 0xd5, 0xfe, 0xca,
+  0xc7, 0x87, 0xec, 0x7c, 0xb6, 0x91, 0x27, 0xa4, 0xb5, 0x9f, 0x9d, 0xf7,
+  0xeb, 0x93, 0xce, 0x55, 0xd8, 0x61, 0xcb, 0x2a, 0x45, 0xd4, 0xe6, 0x94,
+  0x9c, 0x06, 0xb3, 0xe3, 0x7b, 0xbc, 0xc8, 0xff, 0xff, 0xbb, 0x29, 0xe8,
+  0x6c, 0xb5, 0x22, 0x64, 0xa4, 0xd4, 0x7e, 0x08, 0x29, 0xae, 0x05, 0xd6,
+  0xf7, 0x88, 0x8b, 0xc4, 0x12, 0x1d, 0xef, 0x38, 0x74, 0x32, 0x8d, 0x2c,
+  0x59, 0x10, 0x5b, 0x9f, 0xac, 0x45, 0x5e, 0xef, 0x62, 0xc3, 0x66, 0x64,
+  0xc4, 0xc7, 0xb3, 0x1d, 0xb1, 0xec, 0x76, 0x90, 0x2f, 0xc8, 0x52, 0x65,
+  0x3c, 0x58, 0x02, 0x01, 0x52, 0x42, 0xbd, 0x38, 0xc4, 0xb1, 0x33, 0x5e,
+  0x9d, 0x6a, 0x19, 0x4f, 0xf1, 0xee, 0x1f, 0x1c, 0x90, 0x40, 0x40, 0x9d,
+  0x41, 0xec, 0x3d, 0xbe, 0xe3, 0x97, 0x70, 0x95, 0x5c, 0x16, 0x66, 0xfd,
+  0xc9, 0xee, 0x29, 0x14, 0x7a, 0x9b, 0x53, 0xa7, 0x8b, 0x4e, 0xf5, 0x3b,
+  0xbe, 0xb4, 0x1b, 0xab, 0x25, 0x5c, 0xcd, 0xac, 0xe0, 0x49, 0xd1, 0xbc,
+  0xcb, 0x1a, 0x8a, 0x7f, 0x62, 0x67, 0xeb, 0xe2, 0x0c, 0x4f, 0x05, 0x0f,
+  0x28, 0xcf, 0xe7, 0x8a, 0x4c, 0x62, 0x16, 0x56, 0x66, 0x83, 0x9e, 0x56,
+  0x13, 0x9d, 0xf5, 0xc4, 0xeb, 0x69, 0xae, 0x64, 0xcd, 0xa0, 0x40, 0x5f,
+  0x61, 0x2d, 0x45, 0xa6, 0x5d, 0x41, 0x88, 0x87, 0xb2, 0x49, 0x30, 0x24,
+  0x95, 0x9d, 0x30, 0x77, 0x36, 0xde, 0x75, 0x54, 0x3b, 0xac, 0xc8, 0x6b,
+  0xf5, 0xed, 0x54, 0xcb, 0xef, 0xa0, 0xc8, 0xdb, 0x1b, 0x80, 0x08, 0x34,
+  0x91, 0xe7, 0x8b, 0xbe, 0x4e, 0x46, 0xed, 0x04, 0x64, 0x51, 0x73, 0xa2,
+  0x6e, 0x52, 0xa2, 0xe4, 0xe3, 0x8a, 0x72, 0x75, 0xf8, 0xb5, 0xc4, 0xa2,
+  0x4a, 0xab, 0xa4, 0x4e, 0xf1, 0x65, 0x29, 0xee, 0xe6, 0x97, 0xb8, 0xeb,
+  0x18, 0x9e, 0x49, 0x08, 0x92, 0x54, 0xc9, 0x20, 0xff, 0xfa, 0xc5, 0x39,
+  0x36, 0xa5, 0xc5, 0xf4, 0x53, 0x91, 0x73, 0x88, 0x94, 0xf1, 0xd9, 0x5a,
+  0x5b, 0xd0, 0x6f, 0x64, 0x9e, 0x32, 0xa6, 0xbf, 0xd2, 0x8e, 0xd7, 0x01,
+  0x53, 0xe2, 0xdd, 0xde, 0xf9, 0x39, 0x4f, 0x53, 0xf0, 0x38, 0x80, 0x87,
+  0xb2, 0x6b, 0x6e, 0x67, 0x5e, 0x6c, 0xcb, 0x21, 0x8b, 0x9a, 0xb3, 0xfc,
+  0x4b, 0x50, 0x71, 0x66, 0xdd, 0x80, 0xa8, 0x0b, 0x76, 0xa7, 0xb6, 0x78,
+  0xce, 0x09, 0x16, 0x88, 0x3f, 0xbb, 0x85, 0xcc, 0x30, 0x78, 0x12, 0x31,
+  0x25, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x09, 0x15, 0x31, 0x16, 0x04, 0x14, 0x1e, 0x0f, 0x8e, 0x8c, 0x64, 0x6c,
+  0x43, 0xac, 0xd5, 0x64, 0x2c, 0xab, 0x5f, 0xa8, 0x1b, 0x09, 0x44, 0x00,
+  0x32, 0x8d, 0x30, 0x31, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
+  0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x79, 0xb8, 0x38, 0x22, 0x89,
+  0x49, 0xa9, 0x7b, 0xfa, 0x75, 0xb9, 0x92, 0xd7, 0x25, 0xf4, 0x42, 0x17,
+  0x1f, 0xf0, 0x19, 0x04, 0x08, 0x46, 0x09, 0xf3, 0x1a, 0x9a, 0xa5, 0xda,
+  0xb3, 0x02, 0x02, 0x08, 0x00
+};
+
+
+unsigned char ECDSA_fails_import_p12[] = {
+    0x30, 0x82, 0x07, 0xf8, 0x02, 0x01, 0x03, 0x30, 0x82, 0x07, 0xbf, 0x06,
+    0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82,
+    0x07, 0xb0, 0x04, 0x82, 0x07, 0xac, 0x30, 0x82, 0x07, 0xa8, 0x30, 0x82,
+    0x04, 0xdf, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07,
+    0x06, 0xa0, 0x82, 0x04, 0xd0, 0x30, 0x82, 0x04, 0xcc, 0x02, 0x01, 0x00,
+    0x30, 0x82, 0x04, 0xc5, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+    0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+    0x0d, 0x01, 0x0c, 0x01, 0x06, 0x30, 0x0e, 0x04, 0x08, 0x32, 0xb1, 0x01,
+    0x77, 0xeb, 0x95, 0x02, 0xb9, 0x02, 0x02, 0x08, 0x00, 0x80, 0x82, 0x04,
+    0x98, 0x8f, 0xa0, 0x71, 0x8a, 0x9a, 0x75, 0x78, 0x29, 0x7e, 0xc9, 0x54,
+    0x98, 0xba, 0x58, 0x7f, 0x65, 0x29, 0xb5, 0x9e, 0xb9, 0xc3, 0xfd, 0x9f,
+    0xfc, 0x43, 0x31, 0x08, 0x73, 0x45, 0x03, 0x7d, 0xfc, 0x97, 0x20, 0x8f,
+    0xb1, 0x4c, 0x85, 0xc3, 0xe9, 0xda, 0xf8, 0x73, 0xbc, 0x77, 0xe5, 0xff,
+    0xc7, 0xef, 0x74, 0xc0, 0xb6, 0x18, 0xa9, 0x76, 0x2c, 0x00, 0x2c, 0x00,
+    0x9f, 0xcb, 0x34, 0x16, 0x0b, 0xf0, 0x11, 0x7c, 0xc0, 0x65, 0x1c, 0x69,
+    0x51, 0xbb, 0x92, 0x86, 0xbf, 0x2e, 0xdf, 0x1e, 0x15, 0xad, 0x1f, 0x66,
+    0xdf, 0x5e, 0x9e, 0xb4, 0xf1, 0x9b, 0x86, 0x0d, 0x0f, 0xe6, 0xd2, 0x01,
+    0x91, 0x0e, 0x37, 0x43, 0xba, 0x5a, 0xf3, 0x4e, 0x3c, 0x5d, 0xc7, 0x0d,
+    0x14, 0x38, 0xc3, 0x4a, 0x10, 0x9a, 0x2d, 0xf8, 0x53, 0x2d, 0xfd, 0x00,
+    0xa9, 0x2b, 0xd1, 0x3f, 0xc4, 0xf8, 0x99, 0xb6, 0xaa, 0x1f, 0x70, 0xb4,
+    0x2f, 0xa4, 0xa6, 0x07, 0x1a, 0x95, 0xd1, 0x93, 0xf1, 0xd2, 0xfe, 0x3f,
+    0x7c, 0xb0, 0x55, 0x18, 0xd5, 0x9f, 0x37, 0x11, 0x3d, 0x2d, 0x1f, 0xb8,
+    0xc8, 0x47, 0xa5, 0x03, 0xa5, 0x2e, 0x91, 0x04, 0xe0, 0xd0, 0x15, 0x70,
+    0xa2, 0x05, 0xac, 0x71, 0x4a, 0x09, 0x93, 0xbb, 0x44, 0xeb, 0x78, 0x20,
+    0x7b, 0xbb, 0x0a, 0x2f, 0x0a, 0x51, 0x5c, 0x16, 0x32, 0x37, 0x82, 0x9e,
+    0xc8, 0x90, 0x96, 0xee, 0x9a, 0x4e, 0x77, 0x21, 0xfd, 0x37, 0x80, 0x2f,
+    0x55, 0xf2, 0x03, 0xb1, 0x31, 0x7e, 0x9b, 0x90, 0xa9, 0x7b, 0xb4, 0x19,
+    0x5d, 0x10, 0xfd, 0x22, 0xa5, 0x07, 0x24, 0xc5, 0xda, 0x86, 0x1e, 0xbd,
+    0x4a, 0xa6, 0xc2, 0x02, 0x71, 0xa5, 0x3d, 0xca, 0x5b, 0x19, 0x5d, 0xb6,
+    0xc4, 0x7d, 0xe7, 0x74, 0xf5, 0x71, 0xd5, 0xe5, 0x9f, 0x0a, 0x4a, 0x01,
+    0xa0, 0xe6, 0xa0, 0x73, 0x93, 0xaa, 0x3b, 0x6c, 0x03, 0x4c, 0xbd, 0x32,
+    0xc9, 0x97, 0xaf, 0x84, 0x79, 0x3d, 0x93, 0x49, 0xc6, 0xbc, 0x2a, 0x4f,
+    0xe1, 0x3e, 0x9f, 0x86, 0xe3, 0xd2, 0x16, 0xd3, 0xb3, 0xf6, 0xac, 0x3c,
+    0xb4, 0x6a, 0xa6, 0x68, 0xb8, 0xf4, 0xe7, 0x68, 0x98, 0xe6, 0xf6, 0x76,
+    0x40, 0x64, 0xeb, 0x95, 0xe2, 0xcc, 0x8b, 0x76, 0x4a, 0xab, 0x83, 0xa9,
+    0x84, 0x08, 0xf7, 0x43, 0x92, 0xcb, 0x31, 0xd1, 0x0a, 0x90, 0x8b, 0x98,
+    0x1d, 0x6a, 0x45, 0x7f, 0x83, 0x9b, 0x01, 0x8d, 0xe8, 0x25, 0x9e, 0x55,
+    0xad, 0x27, 0x7e, 0x21, 0xfd, 0x8e, 0xc8, 0x26, 0x1f, 0x43, 0x44, 0x06,
+    0x5f, 0x44, 0xbd, 0x5a, 0xf3, 0x15, 0xac, 0x1a, 0x8f, 0xc7, 0x5a, 0x40,
+    0xa9, 0x93, 0x09, 0xdc, 0xc4, 0xc9, 0xe9, 0x42, 0xf0, 0xe4, 0xda, 0x29,
+    0x90, 0x61, 0x32, 0xcb, 0x05, 0x74, 0x61, 0x71, 0x44, 0xbb, 0x3f, 0x99,
+    0xc3, 0x25, 0x29, 0x8c, 0xa1, 0xe1, 0x92, 0xe6, 0xfd, 0x55, 0x8e, 0x22,
+    0x37, 0x95, 0x08, 0x59, 0xdc, 0xa2, 0x7c, 0xfc, 0x12, 0x9a, 0x5e, 0x1a,
+    0x58, 0x8a, 0x14, 0xa7, 0x96, 0xa2, 0x9e, 0x35, 0xe1, 0x1c, 0x7d, 0xac,
+    0x86, 0x1e, 0xcf, 0x1a, 0x35, 0x7a, 0xf1, 0x31, 0x46, 0x67, 0xbd, 0x81,
+    0x9c, 0xf5, 0x70, 0x9e, 0xaf, 0x0f, 0x84, 0x10, 0xc9, 0x46, 0xce, 0xb6,
+    0xc4, 0x35, 0x88, 0xf0, 0xe1, 0xa6, 0x25, 0xa5, 0xdf, 0x4d, 0x5e, 0x10,
+    0x76, 0x2c, 0xa3, 0x85, 0x42, 0x13, 0xe2, 0x34, 0x57, 0xce, 0x8a, 0x96,
+    0x1f, 0x1b, 0x78, 0x87, 0xd6, 0x4d, 0x66, 0x36, 0x8e, 0x2c, 0xc6, 0x8b,
+    0x0a, 0x53, 0x26, 0x70, 0xa5, 0x7e, 0x7c, 0x7f, 0x94, 0x8b, 0x89, 0x75,
+    0x32, 0x1b, 0x8d, 0x27, 0x6f, 0xb1, 0x64, 0x07, 0xa1, 0xbc, 0x34, 0xe4,
+    0x9b, 0xb7, 0x96, 0x4a, 0x9b, 0x96, 0xea, 0xc1, 0x4c, 0x13, 0xa8, 0x28,
+    0xe3, 0x70, 0xdd, 0x68, 0x2b, 0xf8, 0xd2, 0xe7, 0x1a, 0xec, 0x34, 0xd2,
+    0xce, 0x7c, 0x69, 0xc5, 0xe4, 0xde, 0x98, 0x8d, 0x1d, 0x54, 0x21, 0x12,
+    0x25, 0x2d, 0xff, 0xbf, 0x1c, 0x97, 0x01, 0x25, 0x2b, 0xbe, 0xad, 0x98,
+    0x4a, 0xd3, 0x19, 0x93, 0x9c, 0x03, 0xe6, 0xa4, 0xeb, 0x6c, 0x18, 0x9d,
+    0xae, 0xcc, 0xc4, 0xb8, 0x24, 0x2d, 0xa0, 0xc1, 0x70, 0xa3, 0x5c, 0x2f,
+    0x6e, 0xee, 0x1c, 0x66, 0x67, 0x43, 0xd8, 0x50, 0x23, 0xe8, 0xd9, 0xb8,
+    0x24, 0x98, 0x3a, 0x7d, 0xcf, 0x12, 0x89, 0xae, 0x1a, 0x11, 0x26, 0xa9,
+    0x80, 0xef, 0x08, 0x20, 0xf0, 0x11, 0x95, 0xfc, 0xe8, 0xfc, 0xc3, 0x4a,
+    0x8b, 0x55, 0x2e, 0xf8, 0x93, 0x6c, 0xe1, 0x82, 0xcb, 0x33, 0xe6, 0xfa,
+    0xa1, 0xc2, 0x1d, 0x26, 0xa1, 0x38, 0xc2, 0x12, 0x53, 0x51, 0xa0, 0xbf,
+    0xa9, 0x11, 0x57, 0x18, 0x1a, 0x94, 0x28, 0xe6, 0xf6, 0x71, 0x46, 0x02,
+    0xd9, 0x1e, 0x1c, 0x07, 0xf4, 0x95, 0xb9, 0xfb, 0x30, 0x79, 0xa6, 0x8a,
+    0xe0, 0x0d, 0x35, 0xb6, 0xb4, 0x4f, 0xde, 0x59, 0x35, 0x7c, 0x1a, 0xf9,
+    0xcc, 0x42, 0x40, 0xba, 0x58, 0x07, 0xd6, 0x10, 0x20, 0x7d, 0xa4, 0x49,
+    0x17, 0x4f, 0x03, 0xa6, 0xaf, 0x30, 0xbd, 0x54, 0x6b, 0x2a, 0xc3, 0x65,
+    0x98, 0x71, 0x6c, 0xcc, 0x75, 0x4e, 0xfb, 0x68, 0x14, 0x9d, 0x50, 0xe2,
+    0x4f, 0x93, 0x48, 0x2c, 0xc3, 0x37, 0x6c, 0x7e, 0x6a, 0x87, 0x4f, 0x5a,
+    0x01, 0xcc, 0x17, 0x54, 0xe7, 0xc0, 0x3d, 0xb3, 0xb4, 0x5f, 0xb9, 0xf1,
+    0xcb, 0x5f, 0x9e, 0x48, 0xa2, 0x01, 0x82, 0xb0, 0xd9, 0x01, 0xa8, 0xf9,
+    0xac, 0xbe, 0x44, 0x23, 0xb1, 0x43, 0x85, 0xe6, 0x50, 0x64, 0x80, 0xfc,
+    0x62, 0xbd, 0xda, 0xef, 0x85, 0xb2, 0x70, 0x8a, 0x0d, 0x5a, 0x62, 0xda,
+    0xcc, 0xb3, 0xc1, 0x3a, 0x21, 0xa0, 0x09, 0xfa, 0x64, 0x79, 0xf5, 0xa5,
+    0xb6, 0x52, 0x28, 0xb5, 0x2f, 0xbd, 0x9b, 0x98, 0xae, 0x42, 0x32, 0x15,
+    0xcc, 0x1a, 0x7d, 0xa6, 0xef, 0x4a, 0xf8, 0x09, 0x72, 0x3e, 0xc3, 0x69,
+    0x31, 0x9f, 0x4b, 0x32, 0x73, 0x5f, 0xbf, 0x5f, 0xd5, 0xc3, 0x9f, 0x1e,
+    0xcf, 0x6b, 0x0c, 0xde, 0x32, 0x57, 0x1d, 0x1d, 0xc0, 0xf8, 0xe9, 0x85,
+    0x8e, 0xd0, 0xf4, 0x86, 0xad, 0xfa, 0x51, 0x07, 0xed, 0x1c, 0xb6, 0x60,
+    0x8f, 0xdc, 0x72, 0x61, 0x36, 0x2e, 0x02, 0xf9, 0xe5, 0x3e, 0x14, 0x19,
+    0xa5, 0x30, 0xb6, 0x2a, 0x7e, 0xf9, 0xbc, 0x95, 0x82, 0x0f, 0x1b, 0x61,
+    0xa5, 0xad, 0x50, 0x38, 0xa1, 0xfe, 0xa8, 0xd0, 0x86, 0x69, 0x40, 0xb9,
+    0x82, 0x21, 0xbc, 0x26, 0x9b, 0x87, 0x2f, 0xf6, 0x39, 0x9c, 0x0a, 0x71,
+    0x0d, 0x54, 0x68, 0x78, 0xcc, 0x81, 0xaf, 0x09, 0xd7, 0xa2, 0x1c, 0x7a,
+    0xfb, 0xfb, 0xae, 0xe0, 0x59, 0x23, 0x0b, 0x8a, 0x5a, 0x9c, 0x4c, 0x9d,
+    0x17, 0xfc, 0x52, 0x66, 0x43, 0xbf, 0x06, 0x6c, 0x56, 0x3f, 0xdd, 0x8e,
+    0x33, 0x2e, 0xb8, 0xd7, 0xed, 0x13, 0x44, 0x05, 0x5b, 0xbf, 0x43, 0xc7,
+    0xfd, 0x6e, 0x41, 0xf4, 0xb8, 0xf0, 0x84, 0x73, 0x60, 0xe4, 0x72, 0x24,
+    0x00, 0xec, 0xdf, 0x1b, 0x0d, 0x57, 0x26, 0x04, 0xa0, 0x8c, 0x25, 0x12,
+    0xe0, 0xc6, 0x14, 0x0e, 0x69, 0xc2, 0xc8, 0x43, 0x53, 0xc6, 0x66, 0x50,
+    0x96, 0x29, 0x50, 0x6d, 0xab, 0x02, 0x29, 0xbd, 0x17, 0xda, 0xd4, 0x5b,
+    0xbe, 0xb1, 0xe8, 0x9a, 0x32, 0x3f, 0x39, 0x12, 0x4b, 0x02, 0xb7, 0x8f,
+    0x64, 0xca, 0x24, 0x43, 0x2b, 0xee, 0x04, 0xbb, 0xbd, 0x2b, 0x9f, 0x1c,
+    0x66, 0xe0, 0x6a, 0xa5, 0xd4, 0x0e, 0x3f, 0x5e, 0xad, 0xe5, 0xc4, 0xcd,
+    0x17, 0x71, 0x57, 0x62, 0xe6, 0x7d, 0xe1, 0xc1, 0xd8, 0x3e, 0x38, 0x30,
+    0x31, 0x49, 0xb0, 0x8d, 0x64, 0x80, 0x55, 0x30, 0xc4, 0x38, 0x22, 0xad,
+    0xc7, 0x8f, 0x1a, 0xbd, 0x30, 0xf8, 0x29, 0xcc, 0xdc, 0x16, 0x6e, 0xf4,
+    0x2d, 0xc4, 0x04, 0x49, 0x9a, 0x20, 0xf3, 0x9a, 0xd9, 0xab, 0x31, 0xe4,
+    0xb4, 0x0a, 0xce, 0x4e, 0xff, 0xdd, 0xe0, 0x75, 0x59, 0xe5, 0x40, 0x2d,
+    0xb5, 0xba, 0xae, 0x73, 0x91, 0x32, 0xba, 0x0d, 0xf3, 0x4a, 0x38, 0xa3,
+    0x0c, 0x11, 0xd2, 0x6c, 0x75, 0x80, 0x7a, 0xe4, 0xd5, 0x98, 0x47, 0x05,
+    0x66, 0x6c, 0x2e, 0x9d, 0x96, 0xad, 0x99, 0x30, 0xdf, 0xc2, 0x54, 0x5a,
+    0x4d, 0xc3, 0x21, 0x80, 0x52, 0xb7, 0x21, 0xa8, 0xb3, 0xd6, 0xe6, 0xf2,
+    0xaf, 0xd3, 0x49, 0x3e, 0xff, 0xb2, 0xc2, 0xc9, 0x8b, 0xba, 0x63, 0x6c,
+    0xf8, 0x8c, 0x39, 0x16, 0x52, 0x59, 0x86, 0x20, 0x50, 0x3a, 0xe6, 0x0f,
+    0x41, 0x13, 0x68, 0xe7, 0x0f, 0x16, 0x58, 0x38, 0xff, 0xb6, 0x26, 0x69,
+    0x41, 0x07, 0xeb, 0x21, 0x45, 0xaa, 0xed, 0xae, 0xea, 0xf6, 0xda, 0x00,
+    0x72, 0x30, 0x82, 0x02, 0xc1, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+    0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x02, 0xb2, 0x04, 0x82, 0x02, 0xae,
+    0x30, 0x82, 0x02, 0xaa, 0x30, 0x82, 0x01, 0x51, 0x06, 0x0b, 0x2a, 0x86,
+    0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, 0x02, 0xa0, 0x81, 0xbc,
+    0x30, 0x81, 0xb9, 0x30, 0x1c, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+    0x0d, 0x01, 0x0c, 0x01, 0x03, 0x30, 0x0e, 0x04, 0x08, 0x3a, 0xe1, 0x16,
+    0x95, 0xa1, 0x45, 0x12, 0xa2, 0x02, 0x02, 0x08, 0x00, 0x04, 0x81, 0x98,
+    0x56, 0x4a, 0x5a, 0xd4, 0xf6, 0x2f, 0x5d, 0x91, 0x3d, 0xed, 0x38, 0x21,
+    0x90, 0x2a, 0xe1, 0x2d, 0x6e, 0xb5, 0x1c, 0xd9, 0xb0, 0x88, 0xcf, 0xb9,
+    0xc7, 0x3a, 0x2b, 0x21, 0xc3, 0xf6, 0x51, 0x91, 0x0c, 0xfb, 0x29, 0x84,
+    0xd1, 0x62, 0x5f, 0x75, 0xee, 0xe6, 0xb0, 0x83, 0x4b, 0x9e, 0x55, 0x7b,
+    0xdd, 0xd3, 0x9c, 0x36, 0x1f, 0xe8, 0x0a, 0x23, 0x4e, 0x5d, 0xde, 0x11,
+    0x71, 0x26, 0xfd, 0x8d, 0x5b, 0xa8, 0x9e, 0x19, 0x2d, 0xbc, 0x2c, 0x75,
+    0xfa, 0x0b, 0xa2, 0x4c, 0xe5, 0x07, 0xed, 0x6b, 0x95, 0x3d, 0x75, 0x12,
+    0xb2, 0xec, 0xc5, 0x20, 0x5e, 0xfb, 0x5c, 0x0b, 0x68, 0x35, 0x1f, 0xdf,
+    0xe0, 0xaa, 0xd5, 0x93, 0x27, 0x3e, 0xa2, 0xed, 0x3f, 0x6d, 0x2c, 0xc0,
+    0x6f, 0x55, 0xf0, 0x21, 0xa6, 0xfa, 0x79, 0xce, 0xc5, 0xd6, 0x39, 0xa6,
+    0x04, 0xa8, 0x4a, 0xa6, 0x95, 0xf0, 0x7e, 0xe7, 0x54, 0xee, 0xb2, 0x88,
+    0xe2, 0x66, 0x5c, 0xb8, 0x5d, 0x3b, 0x90, 0x32, 0x6a, 0xfb, 0x3e, 0xa3,
+    0x8b, 0x6b, 0x96, 0xf6, 0x42, 0x55, 0xb3, 0x9f, 0x31, 0x81, 0x82, 0x30,
+    0x5b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x14,
+    0x31, 0x4e, 0x1e, 0x4c, 0x00, 0x4d, 0x00, 0x65, 0x00, 0x73, 0x00, 0x73,
+    0x00, 0x61, 0x00, 0x67, 0x00, 0x65, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6f,
+    0x00, 0x74, 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f,
+    0x00, 0x6e, 0x00, 0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x53,
+    0x00, 0x69, 0x00, 0x67, 0x00, 0x6e, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67,
+    0x00, 0x49, 0x00, 0x64, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x69,
+    0x00, 0x74, 0x00, 0x79, 0x00, 0x31, 0x00, 0x00, 0x30, 0x23, 0x06, 0x09,
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x15, 0x31, 0x16, 0x04,
+    0x14, 0xf8, 0x15, 0x2d, 0x15, 0x6b, 0x7d, 0x28, 0xe8, 0x23, 0x88, 0xbf,
+    0xba, 0xa2, 0x3a, 0x3e, 0x9a, 0x03, 0xe6, 0xc6, 0x89, 0x30, 0x82, 0x01,
+    0x51, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a,
+    0x01, 0x02, 0xa0, 0x81, 0xbc, 0x30, 0x81, 0xb9, 0x30, 0x1c, 0x06, 0x0a,
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x03, 0x30, 0x0e,
+    0x04, 0x08, 0xe3, 0xef, 0x16, 0x96, 0x45, 0x16, 0xe5, 0xb3, 0x02, 0x02,
+    0x08, 0x00, 0x04, 0x81, 0x98, 0xf0, 0x1d, 0x35, 0x91, 0xfc, 0x16, 0x43,
+    0xaa, 0x1d, 0xb0, 0x58, 0x12, 0xde, 0x69, 0x92, 0xd0, 0xac, 0x96, 0xbe,
+    0xc7, 0xbb, 0xb8, 0xb2, 0x44, 0x4e, 0x17, 0xd1, 0xb5, 0xfb, 0x36, 0xea,
+    0xd7, 0x06, 0x3a, 0x0e, 0x9a, 0xaa, 0x23, 0xfa, 0x70, 0x51, 0xb9, 0xf9,
+    0x90, 0x78, 0xbc, 0xb3, 0x63, 0x48, 0x8c, 0x84, 0xb2, 0xa2, 0x98, 0xc9,
+    0x71, 0x46, 0x82, 0x42, 0x9f, 0x0f, 0x7b, 0xcc, 0xbe, 0xcc, 0xad, 0x3c,
+    0x30, 0xdb, 0x1d, 0x34, 0xcc, 0x89, 0x91, 0x6b, 0xee, 0x2f, 0x9c, 0x75,
+    0x8b, 0x55, 0xff, 0x2e, 0x0b, 0x1d, 0x71, 0x5e, 0xb1, 0xa2, 0xb2, 0x5e,
+    0x7e, 0x48, 0x37, 0x2f, 0x08, 0x67, 0x91, 0x9a, 0xf1, 0x05, 0x1c, 0x7a,
+    0x7f, 0xee, 0x6f, 0x1e, 0x5b, 0xd9, 0x7c, 0x2d, 0xb8, 0x09, 0x72, 0xb6,
+    0x5a, 0xbf, 0x9a, 0xd7, 0x23, 0x39, 0x6f, 0x1f, 0xf8, 0xd5, 0x72, 0x49,
+    0xea, 0xab, 0x4b, 0xa0, 0xcb, 0xa3, 0xc7, 0xef, 0xb8, 0x8c, 0xda, 0x4c,
+    0x0a, 0x8f, 0xeb, 0x7f, 0x8f, 0x42, 0xd4, 0xad, 0x45, 0x72, 0xda, 0xd9,
+    0xc4, 0x31, 0x81, 0x82, 0x30, 0x5b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+    0xf7, 0x0d, 0x01, 0x09, 0x14, 0x31, 0x4e, 0x1e, 0x4c, 0x00, 0x4d, 0x00,
+    0x65, 0x00, 0x73, 0x00, 0x73, 0x00, 0x61, 0x00, 0x67, 0x00, 0x65, 0x00,
+    0x50, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x74, 0x00, 0x65, 0x00, 0x63, 0x00,
+    0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x54, 0x00, 0x65, 0x00,
+    0x73, 0x00, 0x74, 0x00, 0x53, 0x00, 0x69, 0x00, 0x67, 0x00, 0x6e, 0x00,
+    0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x49, 0x00, 0x64, 0x00, 0x65, 0x00,
+    0x6e, 0x00, 0x74, 0x00, 0x69, 0x00, 0x74, 0x00, 0x79, 0x00, 0x31, 0x00,
+    0x00, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+    0x09, 0x15, 0x31, 0x16, 0x04, 0x14, 0xf8, 0x15, 0x2d, 0x15, 0x6b, 0x7d,
+    0x28, 0xe8, 0x23, 0x88, 0xbf, 0xba, 0xa2, 0x3a, 0x3e, 0x9a, 0x03, 0xe6,
+    0xc6, 0x89, 0x30, 0x30, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
+    0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x06, 0xfc, 0xc7, 0x98, 0xaf,
+    0x81, 0x75, 0x9f, 0x25, 0x05, 0x0c, 0x6d, 0x78, 0xac, 0x4b, 0x31, 0x23,
+    0x6c, 0x9b, 0x4d, 0x04, 0x08, 0xf5, 0x1e, 0x85, 0xf5, 0x54, 0xf6, 0x09,
+    0x53, 0x02, 0x01, 0x01
+};
+unsigned int ECDSA_fails_import_p12_len = 2044;
+
+unsigned char ECDSA_fails_import_priv_only[] = {
+    0x30, 0x25, 0x02, 0x01, 0x01, 0x04, 0x20, 0x79, 0xf4, 0x38, 0x5c, 0x35,
+    0xe1, 0x97, 0xbf, 0xc7, 0x39, 0xc1, 0x2e, 0x40, 0x52, 0x9f, 0xd1, 0xf0,
+    0x13, 0xa6, 0x94, 0xc5, 0xdc, 0x3b, 0x14, 0x5b, 0x08, 0x11, 0x28, 0xc5,
+    0xb6, 0xc4, 0xd7
+};
+unsigned int ECDSA_fails_import_priv_only_len = 39;
+
+static void tests(void)
+{
+    CFDataRef message = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
+        _user_one_p12, sizeof(_user_one_p12), kCFAllocatorNull);
+    CFArrayRef items = NULL;
+    SecCertificateRef cert = NULL;
+    SecKeyRef pkey = NULL;
+
+    is_status(SecPKCS12Import(message, NULL, NULL), errSecAuthFailed,
+        "try null password on a known good p12");
+
+    CFStringRef password = CFSTR("user-one");
+    CFDictionaryRef options = CFDictionaryCreate(NULL,
+        (const void **)&kSecImportExportPassphrase,
+        (const void **)&password, 1,
+        &kCFTypeDictionaryKeyCallBacks,
+        &kCFTypeDictionaryValueCallBacks);
+    ok_status(SecPKCS12Import(message, options, &items), "import user one");
+
+    is(CFArrayGetCount(items), 1, "one identity");
+    CFDictionaryRef item = CFArrayGetValueAtIndex(items, 0);
+    SecIdentityRef identity = NULL;
+    ok(identity = (SecIdentityRef)CFDictionaryGetValue(item, kSecImportItemIdentity), "pull identity from imported data");
+
+    ok(CFGetTypeID(identity)==SecIdentityGetTypeID(),"this is a SecIdentityRef");
+    ok_status(SecIdentityCopyPrivateKey(identity, &pkey),"get private key");
+    ok_status(SecIdentityCopyCertificate(identity, &cert), "get certificate");
+
+    CFReleaseNull(items);
+    CFReleaseNull(message);
+    CFReleaseNull(options);
+    CFReleaseNull(password);
+    CFReleaseNull(cert);
+    CFReleaseNull(pkey);
+
+    message = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
+        _user_two_p12, sizeof(_user_two_p12), kCFAllocatorNull);
+    items = NULL;
+    password = CFSTR("user-two");
+    options = CFDictionaryCreate(NULL,
+        (const void **)&kSecImportExportPassphrase,
+        (const void **)&password, 1,
+        &kCFTypeDictionaryKeyCallBacks,
+        &kCFTypeDictionaryValueCallBacks);
+
+    ok_status(SecPKCS12Import(message, options, &items), "import user two");
+    is(CFArrayGetCount(items), 1, "one identity");
+    item = CFArrayGetValueAtIndex(items, 0);
+    ok(identity = (SecIdentityRef)CFDictionaryGetValue(item, kSecImportItemIdentity), "pull identity from imported data");
+
+    ok(CFGetTypeID(identity)==SecIdentityGetTypeID(),"this is a SecIdentityRef");
+    ok_status(SecIdentityCopyPrivateKey(identity, &pkey),"get private key");
+    ok_status(SecIdentityCopyCertificate(identity, &cert), "get certificate");
+
+    CFReleaseNull(items);
+    CFReleaseNull(message);
+    CFReleaseNull(options);
+    CFReleaseNull(password);
+    CFReleaseNull(cert);
+    CFReleaseNull(pkey);
+
+
+
+    message = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
+                                          ECDSA_fails_import_p12, ECDSA_fails_import_p12_len, kCFAllocatorNull);
+    items = NULL;
+    password = CFSTR("test");
+    options = CFDictionaryCreate(NULL,
+                                 (const void **)&kSecImportExportPassphrase,
+                                 (const void **)&password, 1,
+                                 &kCFTypeDictionaryKeyCallBacks,
+                                 &kCFTypeDictionaryValueCallBacks);
+
+    ok_status(SecPKCS12Import(message, options, &items), "import ECDSA_fails_import_p12");
+    is(CFArrayGetCount(items), 1, "one identity");
+    item = CFArrayGetValueAtIndex(items, 0);
+    ok(identity = (SecIdentityRef)CFDictionaryGetValue(item, kSecImportItemIdentity), "pull identity from imported data");
+
+    ok(CFGetTypeID(identity)==SecIdentityGetTypeID(),"this is a SecIdentityRef");
+    ok_status(SecIdentityCopyPrivateKey(identity, &pkey),"get private key");
+    ok_status(SecIdentityCopyCertificate(identity, &cert), "get certificate");
+
+    CFDataRef pubdata = NULL;
+    SecKeyRef pubkey = NULL;
+
+    ok_status(SecKeyCopyPublicBytes(pkey, &pubdata), "pub key from priv key");
+    ok(pubkey = SecKeyCreateECPublicKey(kCFAllocatorDefault,
+        CFDataGetBytePtr(pubdata), CFDataGetLength(pubdata), kSecKeyEncodingBytes),
+       "recreate seckey");
+
+    /* Sign something. */
+    uint8_t something[20] = {0x80, 0xbe, 0xef, 0xba, 0xd0, };
+    size_t sigLen = SecKeyGetSize(pkey, kSecKeySignatureSize);
+    uint8_t sig[sigLen];
+    ok_status(SecKeyRawSign(pkey, kSecPaddingPKCS1,
+                            something, sizeof(something), sig, &sigLen), "sign something");
+    ok_status(SecKeyRawVerify(pubkey, kSecPaddingPKCS1,
+                              something, sizeof(something), sig, sigLen), "verify sig on something");
+
+
+    CFReleaseNull(pubdata);
+    CFReleaseNull(pubkey);
+    CFReleaseNull(pkey);
+
+    ok(pkey = SecKeyCreateECPrivateKey(kCFAllocatorDefault,
+        ECDSA_fails_import_priv_only, ECDSA_fails_import_priv_only_len,
+        kSecKeyEncodingPkcs1), "import privkey without pub");
+    ok_status(SecKeyCopyPublicBytes(pkey, &pubdata), "pub key from priv key");
+    ok(pubkey = SecKeyCreateECPublicKey(kCFAllocatorDefault,
+        CFDataGetBytePtr(pubdata), CFDataGetLength(pubdata), kSecKeyEncodingBytes),
+       "recreate seckey");
+    ok_status(SecKeyRawVerify(pubkey, kSecPaddingPKCS1,
+        something, sizeof(something), sig, sigLen), "verify sig on something");
+
+    CFReleaseNull(pubdata);
+    CFReleaseNull(pubkey);
+    CFReleaseNull(pkey);
+    CFReleaseNull(items);
+    CFReleaseNull(message);
+    CFReleaseNull(options);
+    CFReleaseNull(password);
+    CFReleaseNull(cert);
+
+}
+
+int si_61_pkcs12(int argc, char *const *argv)
+{
+       plan_tests(27);
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-62-csr.c b/sec/Security/Regressions/secitem/si-62-csr.c
new file mode 100644 (file)
index 0000000..39ed55c
--- /dev/null
@@ -0,0 +1,255 @@
+/*
+ *  si-62-csr.c
+ *  Security
+ *
+ *  Created by Conrad Sauerwald on 5/7/08.
+ *  Copyright (c) 2008-2010 Apple Inc. All Rights Reserved.
+ *
+ */
+
+#include <Security/SecKey.h>
+#include <Security/SecItem.h>
+#include <Security/SecItemPriv.h>
+#include <Security/SecCMS.h>
+#include <Security/SecCertificateRequest.h>
+#include <Security/SecSCEP.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecIdentityPriv.h>
+#include <utilities/array_size.h>
+
+#include <Security/SecInternal.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "Security_regressions.h"
+
+#include <fcntl.h>
+static inline void write_data(const char * path, CFDataRef data)
+{
+    int data_file = open(path, O_CREAT|O_WRONLY|O_TRUNC, 0644);
+    write(data_file, CFDataGetBytePtr(data), CFDataGetLength(data));
+    close(data_file);
+}
+
+
+static void tests(void)
+{
+    SecKeyRef phone_publicKey = NULL, phone_privateKey = NULL;
+    SecKeyRef ca_publicKey = NULL, ca_privateKey = NULL;
+    const void *keygen_keys[] = { kSecAttrKeyType, kSecAttrKeySizeInBits };
+    const void *keygen_vals[] = { kSecAttrKeyTypeRSA, CFSTR("512") };
+    CFDictionaryRef parameters = CFDictionaryCreate(kCFAllocatorDefault,
+        keygen_keys, keygen_vals, array_size(keygen_vals),
+        &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks );
+
+
+    CFMutableDictionaryRef subject_alt_names = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    CFDictionarySetValue(subject_alt_names, CFSTR("dnsname"), CFSTR("xey.nl"));
+
+    int key_usage = kSecKeyUsageDigitalSignature | kSecKeyUsageKeyEncipherment;
+    CFNumberRef key_usage_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &key_usage);
+
+    CFMutableDictionaryRef random_extensions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+
+    const void *key[] = { kSecCSRChallengePassword, kSecSubjectAltName, kSecCertificateKeyUsage, kSecCertificateExtensions };
+    const void *val[] = { CFSTR("magic"), subject_alt_names, key_usage_num, random_extensions };
+    CFDictionaryRef csr_parameters = CFDictionaryCreate(kCFAllocatorDefault,
+        key, val, array_size(key), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+
+    SecATV cn_phone[] = { { kSecOidCommonName, SecASN1PrintableString, CFSTR("My iPhone") }, {} };
+    SecATV c[]  = { { kSecOidCountryName, SecASN1PrintableString, CFSTR("US") }, {} };
+    SecATV st[] = { { kSecOidStateProvinceName, SecASN1PrintableString, CFSTR("CA") }, {} };
+    SecATV l[]  = { { kSecOidLocalityName, SecASN1PrintableString, CFSTR("Cupertino") }, {} };
+    SecATV o[]  = { { CFSTR("2.5.4.10"), SecASN1PrintableString, CFSTR("Apple Inc.") }, {} };
+    SecATV ou[] = { { kSecOidOrganizationalUnit, SecASN1PrintableString, CFSTR("iPhone") }, {} };
+
+    SecRDN atvs_phone[] = { cn_phone, c, st, l, o, ou, NULL };
+
+    ok_status(SecKeyGeneratePair(parameters, &phone_publicKey, &phone_privateKey), "generate key pair");
+    ok_status(SecKeyGeneratePair(parameters, &ca_publicKey, &ca_privateKey), "generate key pair");
+
+    int self_key_usage = kSecKeyUsageKeyCertSign | kSecKeyUsageCRLSign;
+    CFNumberRef self_key_usage_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &self_key_usage);
+    int path_len = 0;
+    CFNumberRef path_len_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &path_len);
+    const void *self_key[] = { kSecCertificateKeyUsage, kSecCSRBasicContraintsPathLen };
+    const void *self_val[] = { self_key_usage_num, path_len_num };
+    CFDictionaryRef self_signed_parameters = CFDictionaryCreate(kCFAllocatorDefault,
+        self_key, self_val, array_size(self_key), NULL, NULL);
+
+    const void * ca_o[] = { kSecOidOrganization, CFSTR("Apple Inc.") };
+    const void * ca_cn[] = { kSecOidCommonName, CFSTR("Root CA") };
+    CFArrayRef ca_o_dn = CFArrayCreate(kCFAllocatorDefault, ca_o, 2, NULL);
+    CFArrayRef ca_cn_dn = CFArrayCreate(kCFAllocatorDefault, ca_cn, 2, NULL);
+    const void *ca_dn_array[2];
+    ca_dn_array[0] = CFArrayCreate(kCFAllocatorDefault, (const void **)&ca_o_dn, 1, NULL);
+    ca_dn_array[1] = CFArrayCreate(kCFAllocatorDefault, (const void **)&ca_cn_dn, 1, NULL);
+    CFArrayRef ca_rdns = CFArrayCreate(kCFAllocatorDefault, ca_dn_array, 2, NULL);
+
+    SecCertificateRef ca_cert = SecGenerateSelfSignedCertificate(ca_rdns,
+        self_signed_parameters, ca_publicKey, ca_privateKey);
+       SecCertificateRef ca_cert_phone_key =
+               SecGenerateSelfSignedCertificate(ca_rdns, self_signed_parameters, phone_publicKey, phone_privateKey);
+
+       CFReleaseSafe(self_signed_parameters);
+    CFReleaseSafe(self_key_usage_num);
+    CFReleaseSafe(path_len_num);
+    CFReleaseNull(ca_o_dn);
+    CFReleaseNull(ca_cn_dn);
+    CFReleaseNull(ca_dn_array[0]);
+    CFReleaseNull(ca_dn_array[1]);
+    CFReleaseNull(ca_rdns);
+
+    isnt(ca_cert, NULL, "got back a cert");
+    ok(SecCertificateIsSelfSignedCA(ca_cert), "cert is self-signed ca cert");
+    isnt(ca_cert_phone_key, NULL, "got back a cert");
+    ok(SecCertificateIsSelfSignedCA(ca_cert_phone_key), "cert is self-signed ca cert");
+    CFDataRef data = SecCertificateCopyData(ca_cert);
+    //write_data("/tmp/ca_cert.der", data);
+    CFReleaseSafe(data);
+
+    SecIdentityRef ca_identity = SecIdentityCreate(kCFAllocatorDefault, ca_cert, ca_privateKey);
+       SecIdentityRef ca_identity_phone_key = SecIdentityCreate(kCFAllocatorDefault, ca_cert_phone_key, phone_privateKey);
+    isnt(ca_identity, NULL, "got a identity");
+    isnt(ca_identity_phone_key, NULL, "got a identity");
+    CFDictionaryRef dict = CFDictionaryCreate(NULL, &kSecValueRef, (const void **)&ca_identity, 1, NULL, NULL);
+    ok_status(SecItemAdd(dict, NULL), "add ca identity");
+    CFReleaseSafe(dict);
+    TODO: {
+        todo("Adding a cert with the same issuer/serial but a different key should return something other than errSecDuplicateItem");
+        dict = CFDictionaryCreate(NULL, &kSecValueRef, (const void **)&ca_identity_phone_key, 1, NULL, NULL);
+        is_status(errSecDuplicateItem, SecItemAdd(dict, NULL), "add ca identity");
+        CFReleaseSafe(dict);
+    }
+
+    CFDataRef csr = SecGenerateCertificateRequestWithParameters(atvs_phone, NULL, phone_publicKey, phone_privateKey);
+    isnt(csr, NULL, "got back a csr");
+    CFReleaseNull(csr);
+
+       //dict[kSecSubjectAltName, dict[ntPrincipalName, "foo@bar.org"]]
+       CFStringRef nt_princ_name_val = CFSTR("foo@bar.org");
+       CFStringRef nt_princ_name_key = CFSTR("ntPrincipalName");
+       CFDictionaryRef nt_princ = CFDictionaryCreate(NULL, (const void **)&nt_princ_name_key, (const void **)&nt_princ_name_val, 1, NULL, NULL);
+       CFDictionaryRef params = CFDictionaryCreate(NULL, &kSecSubjectAltName, (const void **)&nt_princ, 1, NULL, NULL);
+
+    csr = SecGenerateCertificateRequestWithParameters(atvs_phone, params, phone_publicKey, phone_privateKey);
+    isnt(csr, NULL, "got back a csr");
+       //write_data("/var/tmp/csr-nt-princ", csr);
+    CFReleaseNull(csr);
+       CFReleaseNull(params);
+       CFReleaseNull(nt_princ);
+
+    csr = SecGenerateCertificateRequestWithParameters(atvs_phone, csr_parameters, phone_publicKey, phone_privateKey);
+    isnt(csr, NULL, "csr w/ params");
+    //write_data("/tmp/csr", csr);
+    CFDataRef subject, extensions;
+    CFStringRef challenge;
+    ok(SecVerifyCertificateRequest(csr, NULL, &challenge, &subject, &extensions), "verify csr");
+    CFReleaseNull(csr);
+
+    uint8_t serialno_byte = 42;
+    CFDataRef serialno = CFDataCreate(kCFAllocatorDefault, &serialno_byte, sizeof(serialno_byte));
+    SecCertificateRef cert = SecIdentitySignCertificate(ca_identity, serialno,
+        phone_publicKey, subject, extensions);
+    data = SecCertificateCopyData(cert);
+    //write_data("/tmp/iphone_cert.der", data);
+    CFReleaseNull(data);
+    CFReleaseNull(subject);
+    CFReleaseNull(extensions);
+    CFReleaseNull(challenge);
+
+    const void * email[] = { CFSTR("1.2.840.113549.1.9.1"), CFSTR("foo@bar.biz") };
+    const void * cn[] = { CFSTR("2.5.4.3"), CFSTR("S/MIME Baby") };
+    CFArrayRef email_dn = CFArrayCreate(kCFAllocatorDefault, email, 2, NULL);
+    CFArrayRef cn_dn = CFArrayCreate(kCFAllocatorDefault, cn, 2, NULL);
+    const void *dn_array[2];
+    dn_array[0] = CFArrayCreate(kCFAllocatorDefault, (const void **)&email_dn, 1, NULL);
+    dn_array[1] = CFArrayCreate(kCFAllocatorDefault, (const void **)&cn_dn, 1, NULL);
+    CFArrayRef rdns = CFArrayCreate(kCFAllocatorDefault, dn_array, 2, NULL);
+    CFDictionarySetValue(subject_alt_names, CFSTR("rfc822name"), CFSTR("mongo@pawn.org"));
+
+    uint8_t random_extension_data[] = { 0xde, 0xad, 0xbe, 0xef };
+    CFDataRef random_extension_value = CFDataCreate(kCFAllocatorDefault, random_extension_data, sizeof(random_extension_data));
+    CFDictionarySetValue(random_extensions, CFSTR("1.2.840.113635.100.6.1.2"), random_extension_value);  // APPLE_FDR_ACCESS_OID
+    CFDictionarySetValue(random_extensions, CFSTR("1.2.840.113635.100.6.1.3"), CFSTR("that guy"));  // APPLE_FDR_CLIENT_IDENTIFIER_OID
+    CFReleaseNull(random_extension_value);
+
+    csr = SecGenerateCertificateRequest(rdns, csr_parameters, phone_publicKey, phone_privateKey);
+    isnt(csr, NULL, "csr w/ params");
+    //write_data("/tmp/csr_neu", csr);
+    CFReleaseNull(csr);
+    CFReleaseNull(subject_alt_names);
+    CFDictionaryRemoveAllValues(random_extensions);
+
+    CFDataRef scep_request = SecSCEPGenerateCertificateRequest(rdns,
+        csr_parameters, phone_publicKey, phone_privateKey, NULL, ca_cert);
+    isnt(scep_request, NULL, "got scep blob");
+    //write_data("/tmp/scep_request.der", scep_request);
+
+    CFReleaseNull(email_dn);
+    CFReleaseNull(cn_dn);
+    CFReleaseNull(dn_array[0]);
+    CFReleaseNull(dn_array[1]);
+    CFReleaseNull(rdns);
+
+    CFDataRef scep_reply = SecSCEPCertifyRequest(scep_request, ca_identity, serialno, false);
+    isnt(scep_reply, NULL, "produced scep reply");
+    //write_data("/tmp/scep_reply.der", scep_reply);
+
+    CFArrayRef issued_certs = NULL;
+    ok(issued_certs = SecSCEPVerifyReply(scep_request, scep_reply, ca_cert, NULL), "verify scep reply");
+
+    // take the issued cert and CA cert and pretend it's a RA/CA couple
+    CFMutableArrayRef scep_certs = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, issued_certs);
+    CFArrayAppendValue(scep_certs, ca_cert);
+    SecCertificateRef ca_certificate = NULL, ra_signing_certificate = NULL, ra_encryption_certificate = NULL;
+
+    ok_status(SecSCEPValidateCACertMessage(scep_certs, NULL,
+        &ca_certificate, &ra_signing_certificate,
+        &ra_encryption_certificate), "pull apart array again");
+    ok(CFEqual(ca_cert, ca_certificate), "found ca");
+    ok(CFArrayContainsValue(issued_certs, CFRangeMake(0, CFArrayGetCount(issued_certs)), ra_signing_certificate), "found ra");
+    ok(!ra_encryption_certificate, "no separate encryption cert");
+
+    // cleanups
+    dict = CFDictionaryCreate(NULL, &kSecValueRef, (const void **)&ca_identity, 1, NULL, NULL);
+    ok_status(SecItemDelete(dict), "delete ca identity");
+       CFReleaseSafe(dict);
+    dict = CFDictionaryCreate(NULL, &kSecValueRef, (const void **)&phone_privateKey, 1, NULL, NULL);
+    ok_status(SecItemDelete(dict), "delete phone private key");
+       CFReleaseSafe(dict);
+
+
+    CFReleaseSafe(ca_certificate);
+    CFReleaseSafe(ra_signing_certificate);
+    CFReleaseSafe(scep_certs);
+
+    CFReleaseSafe(scep_request);
+    CFReleaseSafe(scep_reply);
+    CFReleaseSafe(issued_certs);
+    CFReleaseSafe(serialno);
+
+    CFReleaseSafe(cert);
+    CFReleaseSafe(ca_identity);
+    CFReleaseSafe(ca_cert);
+       CFReleaseSafe(ca_identity_phone_key);
+       CFReleaseSafe(ca_cert_phone_key);
+    CFReleaseSafe(csr_parameters);
+    CFReleaseSafe(random_extensions);
+    CFReleaseSafe(parameters);
+    CFReleaseSafe(ca_publicKey);
+    CFReleaseSafe(ca_privateKey);
+    CFReleaseSafe(phone_publicKey);
+    CFReleaseSafe(phone_privateKey);
+}
+
+int si_62_csr(int argc, char *const *argv)
+{
+       plan_tests(24);
+
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-63-scep.c b/sec/Security/Regressions/secitem/si-63-scep.c
new file mode 100644 (file)
index 0000000..04a4f88
--- /dev/null
@@ -0,0 +1,1198 @@
+/*
+ *  si-60-cms.c
+ *  Security
+ *
+ *  Created by Michael Brouwer on 2/21/08
+ *  Copyright (c) 2008 Apple Inc. All Rights Reserved.
+ *
+ */
+#include <Security/SecInternal.h>
+#include <Security/SecCMS.h>
+#include <Security/SecSCEP.h>
+#include <Security/SecItem.h>
+#include <Security/SecItemPriv.h>
+#include <Security/SecIdentityPriv.h>
+#include <utilities/array_size.h>
+
+#include <CommonCrypto/CommonDigest.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <AssertMacros.h>
+
+#include "Security_regressions.h"
+#include <test/testcert.h>
+
+static uint8_t msscep_getcacert[] = {
+       0x30, 0x82, 0x10, 0x8d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+       0x01, 0x07, 0x02, 0xa0, 0x82, 0x10, 0x7e, 0x30, 0x82, 0x10, 0x7a, 0x02,
+       0x01, 0x01, 0x31, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+       0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x10, 0x62, 0x30, 0x82, 0x05,
+       0xcc, 0x30, 0x82, 0x04, 0xb4, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0a,
+       0x61, 0x0c, 0x81, 0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x30, 0x0d,
+       0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
+       0x00, 0x30, 0x4e, 0x31, 0x13, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
+       0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x63, 0x6f, 0x6d,
+       0x31, 0x18, 0x30, 0x16, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2,
+       0x2c, 0x64, 0x01, 0x19, 0x16, 0x08, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65,
+       0x73, 0x74, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+       0x14, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70,
+       0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17,
+       0x0d, 0x30, 0x39, 0x30, 0x32, 0x31, 0x37, 0x32, 0x32, 0x33, 0x35, 0x35,
+       0x35, 0x5a, 0x17, 0x0d, 0x31, 0x31, 0x30, 0x32, 0x31, 0x37, 0x32, 0x32,
+       0x33, 0x35, 0x35, 0x35, 0x5a, 0x30, 0x81, 0x8a, 0x31, 0x0b, 0x30, 0x09,
+       0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30,
+       0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x63, 0x61, 0x31, 0x12,
+       0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x63, 0x75, 0x70,
+       0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
+       0x55, 0x04, 0x0a, 0x13, 0x08, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73,
+       0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x02,
+       0x71, 0x61, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+       0x0c, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f,
+       0x6d, 0x31, 0x23, 0x30, 0x21, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+       0x0d, 0x01, 0x09, 0x01, 0x16, 0x14, 0x71, 0x61, 0x61, 0x64, 0x6d, 0x69,
+       0x6e, 0x40, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63,
+       0x6f, 0x6d, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+       0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00,
+       0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0x93, 0x67, 0x34, 0x15, 0xe9,
+       0x97, 0x97, 0x74, 0xbf, 0x0e, 0x1c, 0xd8, 0x44, 0x00, 0x0d, 0x42, 0x7a,
+       0x3d, 0xd1, 0xea, 0xc8, 0x95, 0xc0, 0x6b, 0x93, 0x6c, 0x6d, 0x87, 0x4a,
+       0x21, 0xf5, 0xbf, 0x16, 0x10, 0x19, 0x44, 0x2f, 0xd2, 0xd6, 0x87, 0x55,
+       0x52, 0x04, 0xb0, 0x0b, 0x3e, 0x49, 0xb7, 0x9c, 0x2b, 0x01, 0xc8, 0x6c,
+       0x3e, 0x56, 0xb5, 0xd2, 0x20, 0x29, 0x0f, 0x25, 0x04, 0xcb, 0x59, 0xce,
+       0x37, 0x69, 0xcf, 0x4e, 0x05, 0x06, 0x2d, 0xac, 0xaf, 0x33, 0xee, 0x4e,
+       0xce, 0xe1, 0x55, 0x46, 0xc6, 0x5c, 0x68, 0x56, 0xda, 0xd6, 0x0a, 0x6e,
+       0xeb, 0xdb, 0x4d, 0xf6, 0xef, 0x0d, 0xcf, 0x1e, 0x43, 0xfa, 0xc2, 0xe2,
+       0xfa, 0x87, 0xe0, 0x31, 0x16, 0x46, 0x97, 0x12, 0x26, 0xdc, 0x94, 0x16,
+       0x73, 0xb0, 0xcf, 0xad, 0x7d, 0x7d, 0x8b, 0xb8, 0xf5, 0xd1, 0x89, 0x50,
+       0x12, 0x1d, 0x49, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x02, 0xf1,
+       0x30, 0x82, 0x02, 0xed, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04,
+       0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x15, 0x06, 0x03, 0x55, 0x1d, 0x25,
+       0x04, 0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82,
+       0x37, 0x14, 0x02, 0x01, 0x30, 0x3b, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04,
+       0x01, 0x82, 0x37, 0x14, 0x02, 0x04, 0x2e, 0x1e, 0x2c, 0x00, 0x45, 0x00,
+       0x6e, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6d, 0x00,
+       0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x41, 0x00, 0x67, 0x00, 0x65, 0x00,
+       0x6e, 0x00, 0x74, 0x00, 0x4f, 0x00, 0x66, 0x00, 0x66, 0x00, 0x6c, 0x00,
+       0x69, 0x00, 0x6e, 0x00, 0x65, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
+       0x04, 0x16, 0x04, 0x14, 0xb3, 0xd0, 0xef, 0xb6, 0xe0, 0x3b, 0x3b, 0x39,
+       0xf8, 0x5a, 0x33, 0x07, 0x2f, 0x19, 0xd9, 0xcd, 0xdd, 0xe3, 0xf9, 0x1e,
+       0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80,
+       0x14, 0x40, 0xb5, 0x54, 0x10, 0x88, 0x09, 0xeb, 0x3e, 0x2e, 0x69, 0x82,
+       0xa6, 0xa0, 0xd8, 0xe4, 0xb0, 0x98, 0xc1, 0x69, 0x3d, 0x30, 0x82, 0x01,
+       0x19, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x82, 0x01, 0x10, 0x30, 0x82,
+       0x01, 0x0c, 0x30, 0x82, 0x01, 0x08, 0xa0, 0x82, 0x01, 0x04, 0xa0, 0x82,
+       0x01, 0x00, 0x86, 0x81, 0xbc, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f,
+       0x2f, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e,
+       0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
+       0x2c, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2c,
+       0x43, 0x4e, 0x3d, 0x43, 0x44, 0x50, 0x2c, 0x43, 0x4e, 0x3d, 0x50, 0x75,
+       0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30, 0x4b, 0x65, 0x79, 0x25, 0x32,
+       0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e,
+       0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e,
+       0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69,
+       0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65,
+       0x73, 0x74, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, 0x6d, 0x3f, 0x63, 0x65,
+       0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x76,
+       0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x3f,
+       0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43,
+       0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x52, 0x4c, 0x44, 0x69, 0x73, 0x74,
+       0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x69, 0x6e,
+       0x74, 0x86, 0x3f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x71, 0x61,
+       0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65,
+       0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x65, 0x72, 0x74, 0x45,
+       0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31,
+       0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63,
+       0x6f, 0x6d, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x82, 0x01, 0x2b, 0x06, 0x08,
+       0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x82, 0x01, 0x1d,
+       0x30, 0x82, 0x01, 0x19, 0x30, 0x81, 0xb4, 0x06, 0x08, 0x2b, 0x06, 0x01,
+       0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x81, 0xa7, 0x6c, 0x64, 0x61, 0x70,
+       0x3a, 0x2f, 0x2f, 0x2f, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72, 0x76,
+       0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e,
+       0x63, 0x6f, 0x6d, 0x2c, 0x43, 0x4e, 0x3d, 0x41, 0x49, 0x41, 0x2c, 0x43,
+       0x4e, 0x3d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30, 0x4b,
+       0x65, 0x79, 0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+       0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+       0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75,
+       0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x69, 0x76,
+       0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f,
+       0x6d, 0x3f, 0x63, 0x41, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+       0x61, 0x74, 0x65, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a,
+       0x65, 0x63, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x65, 0x72,
+       0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x75,
+       0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x60, 0x06, 0x08, 0x2b,
+       0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x54, 0x68, 0x74, 0x74,
+       0x70, 0x3a, 0x2f, 0x2f, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e,
+       0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
+       0x2f, 0x43, 0x65, 0x72, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x2f,
+       0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e,
+       0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x5f, 0x71, 0x61, 0x73,
+       0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73,
+       0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x0d, 0x06,
+       0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,
+       0x03, 0x82, 0x01, 0x01, 0x00, 0x7e, 0x74, 0xff, 0x77, 0xd7, 0x2e, 0x43,
+       0x11, 0xcf, 0xef, 0xb3, 0xdd, 0x98, 0xae, 0x9a, 0xa3, 0x13, 0xc3, 0x07,
+       0x37, 0x0e, 0xe5, 0x2c, 0x50, 0xa1, 0x5e, 0xe2, 0xa6, 0x94, 0x45, 0x2a,
+       0x00, 0x9d, 0xee, 0x53, 0x67, 0x10, 0x6b, 0x13, 0xc5, 0xf9, 0x1c, 0x88,
+       0x70, 0x3c, 0x73, 0x5f, 0x98, 0x2b, 0x05, 0x51, 0xf7, 0x67, 0xf6, 0xa6,
+       0x5b, 0xcb, 0xb6, 0x1c, 0xc2, 0x85, 0xef, 0x1e, 0xcd, 0x25, 0x5f, 0xfa,
+       0xba, 0xcd, 0x89, 0xf7, 0x93, 0xfe, 0x9f, 0xd6, 0xdd, 0x2c, 0x4c, 0xd5,
+       0x33, 0xec, 0xd7, 0xef, 0x6e, 0xc8, 0x0b, 0x9b, 0x8b, 0x4e, 0x75, 0x91,
+       0x0b, 0x4e, 0x96, 0x81, 0x4d, 0xee, 0x06, 0x55, 0x41, 0xfc, 0xc5, 0x2a,
+       0xa6, 0x53, 0x97, 0xb6, 0xce, 0x61, 0x22, 0x93, 0xa8, 0x71, 0x04, 0x51,
+       0xa7, 0xa8, 0x87, 0xee, 0x72, 0xb7, 0x0f, 0xa4, 0x5e, 0x6e, 0xc2, 0xcd,
+       0xfa, 0x00, 0xf8, 0x9c, 0xe5, 0xcc, 0x61, 0xce, 0x88, 0xf0, 0x55, 0xb6,
+       0xff, 0xac, 0xdb, 0xeb, 0xe6, 0xcc, 0x89, 0x7e, 0xea, 0x29, 0x7f, 0x9f,
+       0x01, 0x54, 0x8a, 0x65, 0x60, 0x31, 0xe3, 0xaa, 0xa1, 0x68, 0x16, 0x50,
+       0x7e, 0xe1, 0x9b, 0x04, 0x7f, 0xc5, 0x15, 0x77, 0xfe, 0xbd, 0xfa, 0xac,
+       0x92, 0xcb, 0x0a, 0xc2, 0x3a, 0xbc, 0xec, 0x4e, 0xc4, 0x3a, 0x9f, 0x4d,
+       0xdd, 0x2a, 0x03, 0xe3, 0x22, 0xc0, 0x66, 0x5a, 0x5c, 0x7f, 0x4c, 0x8a,
+       0x58, 0x3e, 0x90, 0x79, 0x96, 0x16, 0x1d, 0x6f, 0x53, 0x43, 0x69, 0xfe,
+       0xb6, 0x0a, 0x18, 0x8f, 0xbf, 0xb4, 0xb8, 0x99, 0xc5, 0x09, 0x20, 0x97,
+       0x10, 0x18, 0xde, 0x57, 0x54, 0x24, 0x95, 0xeb, 0xce, 0x99, 0x01, 0xdd,
+       0x42, 0xc0, 0x67, 0x0b, 0x8c, 0xdb, 0x1c, 0x77, 0x86, 0x63, 0x9d, 0x87,
+       0xf6, 0xff, 0xcf, 0xc5, 0x38, 0xff, 0x6e, 0xb6, 0x05, 0x30, 0x82, 0x05,
+       0xf2, 0x30, 0x82, 0x04, 0xda, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0a,
+       0x61, 0x0c, 0x83, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x30, 0x0d,
+       0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
+       0x00, 0x30, 0x4e, 0x31, 0x13, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
+       0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x63, 0x6f, 0x6d,
+       0x31, 0x18, 0x30, 0x16, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2,
+       0x2c, 0x64, 0x01, 0x19, 0x16, 0x08, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65,
+       0x73, 0x74, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+       0x14, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70,
+       0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17,
+       0x0d, 0x30, 0x39, 0x30, 0x32, 0x31, 0x37, 0x32, 0x32, 0x33, 0x35, 0x35,
+       0x36, 0x5a, 0x17, 0x0d, 0x31, 0x31, 0x30, 0x32, 0x31, 0x37, 0x32, 0x32,
+       0x33, 0x35, 0x35, 0x36, 0x5a, 0x30, 0x81, 0x8a, 0x31, 0x0b, 0x30, 0x09,
+       0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30,
+       0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x63, 0x61, 0x31, 0x12,
+       0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x63, 0x75, 0x70,
+       0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
+       0x55, 0x04, 0x0a, 0x13, 0x08, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73,
+       0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x02,
+       0x71, 0x61, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+       0x0c, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f,
+       0x6d, 0x31, 0x23, 0x30, 0x21, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+       0x0d, 0x01, 0x09, 0x01, 0x16, 0x14, 0x71, 0x61, 0x61, 0x64, 0x6d, 0x69,
+       0x6e, 0x40, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63,
+       0x6f, 0x6d, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+       0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00,
+       0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xa6, 0xf2, 0x65, 0xbe, 0xc6,
+       0xb3, 0x53, 0xc2, 0x94, 0x89, 0xef, 0xca, 0x3a, 0x1d, 0x08, 0x64, 0x19,
+       0x96, 0x5c, 0x8d, 0xc3, 0x15, 0x9b, 0xe5, 0x68, 0x86, 0x7d, 0xff, 0xf9,
+       0xa1, 0xa5, 0x7b, 0x85, 0x8c, 0x14, 0x41, 0xf3, 0xe1, 0x6a, 0x17, 0xff,
+       0xaf, 0x01, 0xb0, 0xbb, 0x64, 0x5d, 0xf0, 0xb8, 0x34, 0x10, 0x41, 0x3e,
+       0xee, 0x43, 0x87, 0x47, 0x4a, 0x5e, 0xc2, 0x2c, 0xe8, 0xcb, 0x23, 0x14,
+       0x9d, 0x92, 0xad, 0xe2, 0xaa, 0x53, 0xbd, 0xfa, 0xaf, 0x7a, 0x11, 0x64,
+       0xeb, 0xb2, 0xf2, 0xd6, 0xdb, 0xd2, 0x77, 0xef, 0x74, 0xb2, 0x67, 0x1b,
+       0xc7, 0xa4, 0x2e, 0x97, 0x80, 0x46, 0x92, 0xaf, 0x32, 0x18, 0x90, 0x46,
+       0x57, 0x86, 0x2d, 0x97, 0x4d, 0x11, 0x48, 0xc5, 0x43, 0x23, 0x3e, 0x6b,
+       0x0d, 0x32, 0x3e, 0xd0, 0xba, 0xf0, 0x20, 0x60, 0x0e, 0x02, 0x47, 0xae,
+       0x58, 0xb4, 0x5b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x03, 0x17,
+       0x30, 0x82, 0x03, 0x13, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04,
+       0x04, 0x03, 0x02, 0x05, 0x20, 0x30, 0x36, 0x06, 0x09, 0x2a, 0x86, 0x48,
+       0x86, 0xf7, 0x0d, 0x01, 0x09, 0x0f, 0x04, 0x29, 0x30, 0x27, 0x30, 0x0d,
+       0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x02, 0x02, 0x01,
+       0x38, 0x30, 0x0d, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03,
+       0x04, 0x02, 0x01, 0x38, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
+       0x07, 0x30, 0x15, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0e, 0x30, 0x0c,
+       0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x01,
+       0x30, 0x29, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14,
+       0x02, 0x04, 0x1c, 0x1e, 0x1a, 0x00, 0x43, 0x00, 0x45, 0x00, 0x50, 0x00,
+       0x45, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x72, 0x00, 0x79, 0x00, 0x70, 0x00,
+       0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x30, 0x1d, 0x06, 0x03, 0x55,
+       0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xe0, 0xfc, 0xd6, 0xa7, 0xca, 0xab,
+       0x38, 0x38, 0x6b, 0x79, 0x6f, 0x63, 0xb7, 0xfd, 0xc4, 0xbd, 0xb2, 0xc3,
+       0x68, 0x03, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
+       0x16, 0x80, 0x14, 0x40, 0xb5, 0x54, 0x10, 0x88, 0x09, 0xeb, 0x3e, 0x2e,
+       0x69, 0x82, 0xa6, 0xa0, 0xd8, 0xe4, 0xb0, 0x98, 0xc1, 0x69, 0x3d, 0x30,
+       0x82, 0x01, 0x19, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x82, 0x01, 0x10,
+       0x30, 0x82, 0x01, 0x0c, 0x30, 0x82, 0x01, 0x08, 0xa0, 0x82, 0x01, 0x04,
+       0xa0, 0x82, 0x01, 0x00, 0x86, 0x81, 0xbc, 0x6c, 0x64, 0x61, 0x70, 0x3a,
+       0x2f, 0x2f, 0x2f, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31,
+       0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63,
+       0x6f, 0x6d, 0x2c, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31,
+       0x30, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x44, 0x50, 0x2c, 0x43, 0x4e, 0x3d,
+       0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30, 0x4b, 0x65, 0x79,
+       0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c,
+       0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c,
+       0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61,
+       0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x69, 0x76, 0x70, 0x6e,
+       0x74, 0x65, 0x73, 0x74, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, 0x6d, 0x3f,
+       0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52,
+       0x65, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73,
+       0x74, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65, 0x63,
+       0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x52, 0x4c, 0x44, 0x69,
+       0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f,
+       0x69, 0x6e, 0x74, 0x86, 0x3f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+       0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e,
+       0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x65, 0x72,
+       0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x71, 0x61, 0x73, 0x72,
+       0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74,
+       0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x82, 0x01, 0x2b,
+       0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x82,
+       0x01, 0x1d, 0x30, 0x82, 0x01, 0x19, 0x30, 0x81, 0xb4, 0x06, 0x08, 0x2b,
+       0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x81, 0xa7, 0x6c, 0x64,
+       0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x2f, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73,
+       0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73,
+       0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x43, 0x4e, 0x3d, 0x41, 0x49, 0x41,
+       0x2c, 0x43, 0x4e, 0x3d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32,
+       0x30, 0x4b, 0x65, 0x79, 0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69,
+       0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69,
+       0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+       0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d,
+       0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2c, 0x44, 0x43, 0x3d,
+       0x63, 0x6f, 0x6d, 0x3f, 0x63, 0x41, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+       0x69, 0x63, 0x61, 0x74, 0x65, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f,
+       0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63,
+       0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+       0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x60, 0x06,
+       0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x54, 0x68,
+       0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31,
+       0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63,
+       0x6f, 0x6d, 0x2f, 0x43, 0x65, 0x72, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c,
+       0x6c, 0x2f, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76,
+       0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x5f, 0x71,
+       0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74,
+       0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x72, 0x74, 0x30,
+       0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
+       0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x83, 0x54, 0x4e, 0x01, 0x42,
+       0x95, 0x42, 0xa4, 0x56, 0x78, 0xf6, 0xa9, 0x41, 0xd8, 0xc3, 0xf2, 0xa4,
+       0xdc, 0xa3, 0xb2, 0xaa, 0x72, 0x63, 0x2c, 0xab, 0x14, 0x40, 0x8c, 0xd9,
+       0xdf, 0x61, 0xdf, 0xee, 0x8b, 0x50, 0x3b, 0xc7, 0xe1, 0x6f, 0xe5, 0x98,
+       0x4d, 0xbd, 0x3c, 0x16, 0xc3, 0xcc, 0x3a, 0xb4, 0x11, 0x87, 0xb6, 0x93,
+       0x63, 0xc6, 0x3d, 0xa2, 0xf3, 0x8c, 0xde, 0xc3, 0xcb, 0x44, 0x25, 0x7a,
+       0x75, 0xc8, 0x5c, 0x9f, 0xeb, 0x43, 0xd2, 0xb1, 0x11, 0x8d, 0x9e, 0x29,
+       0x7a, 0xf1, 0x9e, 0x59, 0xb2, 0x8b, 0xfa, 0x31, 0x2e, 0x4c, 0x8f, 0x6a,
+       0x72, 0x0c, 0x42, 0x63, 0xf1, 0xca, 0x76, 0x8e, 0x33, 0x5e, 0x69, 0x9e,
+       0x3b, 0x15, 0xba, 0xfb, 0xf8, 0x0e, 0x9d, 0x1b, 0xb1, 0x52, 0xc9, 0xc3,
+       0x3e, 0x4f, 0xa4, 0x56, 0x1f, 0x71, 0x24, 0x0a, 0x61, 0x25, 0x87, 0x75,
+       0x07, 0xc7, 0xf0, 0x6f, 0xb3, 0xd7, 0xe9, 0x20, 0x7a, 0xc1, 0x98, 0x48,
+       0x25, 0xd0, 0x17, 0x27, 0xed, 0x21, 0xe8, 0x2b, 0xb6, 0xa7, 0xa5, 0x7b,
+       0x53, 0x20, 0x27, 0x3d, 0x5d, 0xbb, 0xcd, 0x61, 0x84, 0xed, 0x66, 0x4c,
+       0xcd, 0x65, 0x6d, 0xe9, 0x2d, 0xf5, 0xe5, 0x63, 0xaf, 0xd0, 0xde, 0xa0,
+       0x89, 0x5b, 0x01, 0x05, 0x05, 0x63, 0x7e, 0x5b, 0xdb, 0xdc, 0x5a, 0xab,
+       0xa5, 0xa4, 0x62, 0x3a, 0xe7, 0xdf, 0xae, 0x55, 0x9b, 0xf8, 0x93, 0x82,
+       0x1b, 0xec, 0x00, 0x27, 0x2e, 0x73, 0x7d, 0xd8, 0xe2, 0xde, 0x76, 0xf3,
+       0x70, 0xbe, 0xc5, 0x12, 0x00, 0x79, 0x62, 0x83, 0x6b, 0x04, 0x23, 0xc9,
+       0x19, 0xa6, 0x23, 0x77, 0x45, 0xd6, 0x14, 0x01, 0xf7, 0x9c, 0x0f, 0x51,
+       0x92, 0x98, 0x5a, 0x2a, 0x57, 0xc9, 0x5a, 0xb4, 0xe3, 0x98, 0x5f, 0x7e,
+       0x07, 0x99, 0x66, 0x20, 0x17, 0x0d, 0x85, 0x2c, 0x3c, 0x98, 0x70, 0x30,
+       0x82, 0x04, 0x98, 0x30, 0x82, 0x03, 0x80, 0xa0, 0x03, 0x02, 0x01, 0x02,
+       0x02, 0x10, 0x7a, 0xdb, 0x4e, 0x56, 0x1a, 0xb8, 0x90, 0xae, 0x46, 0x6f,
+       0x06, 0x74, 0x44, 0x09, 0x68, 0x87, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+       0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x4e, 0x31,
+       0x13, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c,
+       0x64, 0x01, 0x19, 0x16, 0x03, 0x63, 0x6f, 0x6d, 0x31, 0x18, 0x30, 0x16,
+       0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19,
+       0x16, 0x08, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x31, 0x1d,
+       0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x71, 0x61, 0x73,
+       0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73,
+       0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, 0x30,
+       0x31, 0x32, 0x38, 0x30, 0x32, 0x34, 0x33, 0x33, 0x30, 0x5a, 0x17, 0x0d,
+       0x31, 0x34, 0x30, 0x31, 0x32, 0x38, 0x30, 0x32, 0x35, 0x32, 0x34, 0x33,
+       0x5a, 0x30, 0x4e, 0x31, 0x13, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
+       0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x63, 0x6f, 0x6d,
+       0x31, 0x18, 0x30, 0x16, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2,
+       0x2c, 0x64, 0x01, 0x19, 0x16, 0x08, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65,
+       0x73, 0x74, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+       0x14, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70,
+       0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01,
+       0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+       0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01,
+       0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xbe, 0xf8, 0xff, 0x61, 0xca, 0x9d,
+       0xcf, 0x07, 0x4d, 0x06, 0xf4, 0x52, 0x4b, 0x3f, 0x84, 0xc5, 0x0b, 0x71,
+       0xef, 0x7f, 0x7d, 0x35, 0xac, 0x68, 0xce, 0x84, 0xe6, 0x7c, 0x0a, 0xba,
+       0x02, 0x71, 0xcf, 0x81, 0x40, 0xcb, 0x25, 0xdb, 0x41, 0x23, 0x84, 0x88,
+       0x4d, 0x16, 0xa2, 0x41, 0xa5, 0x2a, 0x98, 0xa3, 0xb7, 0x02, 0xff, 0x54,
+       0xb6, 0xd5, 0x55, 0x75, 0x17, 0xbc, 0xd5, 0x04, 0x24, 0x35, 0x63, 0xfa,
+       0xcb, 0x98, 0x38, 0x98, 0x18, 0xd3, 0x13, 0xc1, 0xef, 0x1a, 0xfe, 0xb7,
+       0xcd, 0x2e, 0xc2, 0xb8, 0x0d, 0x3e, 0x62, 0x38, 0xc0, 0x05, 0xf9, 0x5b,
+       0xc5, 0xd5, 0xf6, 0xc4, 0x9d, 0x8e, 0xc3, 0x90, 0x32, 0xa2, 0xb1, 0x88,
+       0xa8, 0xf9, 0xd3, 0x0d, 0x02, 0x8d, 0xbe, 0x8f, 0x41, 0xe7, 0x92, 0x85,
+       0xe7, 0x4c, 0x11, 0x9a, 0x4b, 0xfb, 0x00, 0xa9, 0x9f, 0xf5, 0xfb, 0x23,
+       0xda, 0xf1, 0xfd, 0x95, 0x89, 0xd5, 0x2b, 0xc5, 0xbf, 0x9c, 0xc3, 0x93,
+       0xd0, 0xc2, 0xf8, 0x12, 0xbe, 0x26, 0x24, 0x41, 0x80, 0x64, 0x2f, 0xc0,
+       0x7b, 0x31, 0x85, 0x06, 0x3c, 0xe4, 0xc6, 0x7e, 0xbc, 0x61, 0xa7, 0xa2,
+       0xf4, 0xa7, 0xd7, 0xd7, 0xcb, 0xeb, 0xea, 0xb0, 0xc6, 0xd7, 0x13, 0xd6,
+       0x09, 0xfa, 0x45, 0xc6, 0x25, 0x6f, 0x34, 0xdc, 0x78, 0x70, 0xa0, 0xa5,
+       0xea, 0xd7, 0xe7, 0xda, 0xe2, 0x5a, 0x7a, 0xc3, 0xe3, 0x7a, 0x8d, 0xf3,
+       0x5a, 0x78, 0xfa, 0x57, 0xe1, 0xf1, 0xae, 0x6b, 0xea, 0x83, 0xd0, 0xd7,
+       0xa9, 0x43, 0x2d, 0x5d, 0x8b, 0xac, 0xbb, 0x92, 0x5b, 0x2a, 0xd7, 0x27,
+       0xbe, 0xe7, 0xa0, 0xd2, 0xc5, 0x9b, 0xd7, 0xa4, 0xc1, 0x6a, 0xf8, 0xec,
+       0xfc, 0xa6, 0x96, 0xfc, 0x09, 0x11, 0x95, 0xca, 0x75, 0xab, 0x8a, 0x5b,
+       0xd2, 0xb2, 0xb4, 0x11, 0xf1, 0x88, 0x34, 0xe3, 0xb7, 0x21, 0x02, 0x03,
+       0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x70, 0x30, 0x82, 0x01, 0x6c, 0x30,
+       0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86,
+       0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05,
+       0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
+       0x04, 0x16, 0x04, 0x14, 0x40, 0xb5, 0x54, 0x10, 0x88, 0x09, 0xeb, 0x3e,
+       0x2e, 0x69, 0x82, 0xa6, 0xa0, 0xd8, 0xe4, 0xb0, 0x98, 0xc1, 0x69, 0x3d,
+       0x30, 0x82, 0x01, 0x19, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x82, 0x01,
+       0x10, 0x30, 0x82, 0x01, 0x0c, 0x30, 0x82, 0x01, 0x08, 0xa0, 0x82, 0x01,
+       0x04, 0xa0, 0x82, 0x01, 0x00, 0x86, 0x81, 0xbc, 0x6c, 0x64, 0x61, 0x70,
+       0x3a, 0x2f, 0x2f, 0x2f, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72, 0x76,
+       0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e,
+       0x63, 0x6f, 0x6d, 0x2c, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72, 0x76,
+       0x31, 0x30, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x44, 0x50, 0x2c, 0x43, 0x4e,
+       0x3d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30, 0x4b, 0x65,
+       0x79, 0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73,
+       0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73,
+       0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72,
+       0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x69, 0x76, 0x70,
+       0x6e, 0x74, 0x65, 0x73, 0x74, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, 0x6d,
+       0x3f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65,
+       0x52, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69,
+       0x73, 0x74, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65,
+       0x63, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x52, 0x4c, 0x44,
+       0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50,
+       0x6f, 0x69, 0x6e, 0x74, 0x86, 0x3f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+       0x2f, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70,
+       0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x65,
+       0x72, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x71, 0x61, 0x73,
+       0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73,
+       0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x10, 0x06,
+       0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x01, 0x04, 0x03,
+       0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+       0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x07,
+       0x74, 0x27, 0x8c, 0xdd, 0x75, 0xa1, 0x0d, 0x97, 0xd1, 0x9d, 0x0d, 0xae,
+       0x3b, 0xf3, 0x14, 0x0f, 0xa1, 0x1c, 0x51, 0xd8, 0x68, 0xe7, 0xfd, 0xd0,
+       0xaf, 0xe7, 0x66, 0x62, 0xf8, 0x73, 0x75, 0x88, 0x6c, 0xb9, 0xb3, 0x1e,
+       0xf5, 0x82, 0x3a, 0x1d, 0x82, 0x7b, 0xa3, 0x18, 0xd9, 0x1a, 0x40, 0xf2,
+       0xcd, 0xb3, 0x83, 0xae, 0x12, 0x5b, 0xb4, 0x45, 0xd9, 0xbe, 0x51, 0x3e,
+       0x11, 0x64, 0xaf, 0x95, 0x06, 0xb6, 0xbd, 0xd1, 0xa1, 0xfd, 0xbb, 0xdb,
+       0xa4, 0xbb, 0xba, 0x3e, 0xd5, 0xd6, 0x1d, 0x37, 0x80, 0x17, 0xe8, 0x08,
+       0x75, 0x5f, 0x5d, 0x49, 0x5f, 0x70, 0xdd, 0x67, 0xde, 0x9a, 0x34, 0x95,
+       0x2e, 0x54, 0x58, 0x42, 0xaf, 0x8a, 0x57, 0xf2, 0xb4, 0x1f, 0xfb, 0x40,
+       0x9c, 0x05, 0xa0, 0x6a, 0x9a, 0x91, 0x0e, 0x27, 0xaa, 0x9e, 0xdb, 0xbf,
+       0x50, 0xc9, 0xa4, 0x2f, 0xc8, 0x71, 0x00, 0x11, 0xf8, 0x2f, 0xda, 0x98,
+       0xf4, 0x1d, 0x98, 0x2a, 0xe9, 0x29, 0xc7, 0xea, 0x74, 0x65, 0xf1, 0x6d,
+       0x06, 0x9f, 0x59, 0xa3, 0x50, 0x7e, 0x1b, 0x52, 0x5a, 0xb9, 0x5e, 0xce,
+       0xa0, 0x03, 0x53, 0xe8, 0xba, 0x36, 0x4a, 0xc2, 0x95, 0xdb, 0x34, 0x61,
+       0xc8, 0xf4, 0xa5, 0x7c, 0xd6, 0x9d, 0x64, 0x91, 0xfb, 0x23, 0xfd, 0x8b,
+       0x3a, 0xd2, 0x67, 0xb0, 0x64, 0xa7, 0x80, 0x82, 0x74, 0x85, 0x45, 0xa7,
+       0x78, 0x57, 0xb6, 0xf0, 0x0a, 0xf9, 0xa2, 0xb5, 0x7f, 0x7e, 0x88, 0x21,
+       0xd7, 0x67, 0xd2, 0xc4, 0x9c, 0x98, 0x51, 0x9b, 0x71, 0xfb, 0x39, 0xf2,
+       0xb3, 0xfd, 0x3f, 0x0b, 0x61, 0x59, 0xa0, 0x15, 0x40, 0x53, 0x71, 0xac,
+       0xf5, 0xf7, 0xee, 0x03, 0x6b, 0x1f, 0x5d, 0x29, 0x0a, 0xf7, 0x4f, 0x1a,
+       0xea, 0xa4, 0xb8, 0x02, 0x63, 0x7c, 0x37, 0x37, 0xdd, 0x46, 0x42, 0xe3,
+       0xe1, 0x82, 0x94, 0x31, 0x00
+};
+static unsigned int msscep_getcacert_len = 4241;
+
+
+static uint8_t getcacert[] = {
+       0x30, 0x82, 0x04, 0x6a, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+       0x01, 0x07, 0x02, 0xa0, 0x82, 0x04, 0x5b, 0x30, 0x82, 0x04, 0x57, 0x02,
+       0x01, 0x01, 0x31, 0x00, 0x30, 0x03, 0x06, 0x01, 0x00, 0xa0, 0x82, 0x04,
+       0x47, 0x30, 0x82, 0x02, 0x33, 0x30, 0x82, 0x01, 0x9c, 0xa0, 0x03, 0x02,
+       0x01, 0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+       0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x4d, 0x31, 0x0d,
+       0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x04, 0x4e, 0x6f, 0x6e,
+       0x65, 0x31, 0x3c, 0x30, 0x3a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x33,
+       0x41, 0x43, 0x4d, 0x45, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41,
+       0x20, 0x28, 0x35, 0x36, 0x32, 0x66, 0x30, 0x64, 0x30, 0x35, 0x2d, 0x32,
+       0x35, 0x36, 0x61, 0x2d, 0x34, 0x32, 0x65, 0x65, 0x2d, 0x39, 0x66, 0x35,
+       0x38, 0x2d, 0x38, 0x30, 0x62, 0x30, 0x61, 0x35, 0x35, 0x37, 0x38, 0x62,
+       0x66, 0x30, 0x29, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, 0x30, 0x39, 0x31,
+       0x37, 0x30, 0x30, 0x33, 0x39, 0x32, 0x33, 0x5a, 0x17, 0x0d, 0x31, 0x30,
+       0x30, 0x39, 0x31, 0x37, 0x30, 0x30, 0x33, 0x39, 0x32, 0x33, 0x5a, 0x30,
+       0x4d, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x04,
+       0x4e, 0x6f, 0x6e, 0x65, 0x31, 0x3c, 0x30, 0x3a, 0x06, 0x03, 0x55, 0x04,
+       0x03, 0x0c, 0x33, 0x41, 0x43, 0x4d, 0x45, 0x20, 0x52, 0x6f, 0x6f, 0x74,
+       0x20, 0x43, 0x41, 0x20, 0x28, 0x35, 0x36, 0x32, 0x66, 0x30, 0x64, 0x30,
+       0x35, 0x2d, 0x32, 0x35, 0x36, 0x61, 0x2d, 0x34, 0x32, 0x65, 0x65, 0x2d,
+       0x39, 0x66, 0x35, 0x38, 0x2d, 0x38, 0x30, 0x62, 0x30, 0x61, 0x35, 0x35,
+       0x37, 0x38, 0x62, 0x66, 0x30, 0x29, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06,
+       0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
+       0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xd4,
+       0x1c, 0xaa, 0x58, 0x8a, 0xda, 0xfc, 0x24, 0x21, 0x35, 0xc2, 0xb0, 0x2b,
+       0x08, 0x5d, 0xe2, 0xf5, 0xb5, 0xf0, 0xdc, 0xca, 0x04, 0xaa, 0x8e, 0x86,
+       0xff, 0xfe, 0x9b, 0x35, 0xed, 0x61, 0x3a, 0xe5, 0xbf, 0xf7, 0xbf, 0xab,
+       0xa4, 0xa8, 0x6e, 0xf5, 0xba, 0x5b, 0x0e, 0xdc, 0x28, 0x07, 0x24, 0x01,
+       0xda, 0x9e, 0x1f, 0x92, 0xa5, 0x4b, 0x51, 0xcd, 0xd9, 0x6e, 0x27, 0xfa,
+       0xda, 0x9b, 0x9c, 0x17, 0x3e, 0x1b, 0x36, 0xaf, 0xf5, 0x5d, 0x11, 0x02,
+       0xe9, 0x2e, 0xf1, 0x6e, 0xb6, 0x7f, 0xe8, 0x91, 0xbd, 0x66, 0x73, 0xdf,
+       0xb9, 0x27, 0xb7, 0x5b, 0x04, 0xb1, 0x9f, 0x52, 0x38, 0xea, 0xd0, 0x1c,
+       0x97, 0x2d, 0x4b, 0x1b, 0x03, 0xcb, 0xe6, 0xa4, 0x92, 0x2c, 0x0f, 0x5d,
+       0x34, 0x06, 0x52, 0x07, 0x35, 0x97, 0x13, 0x2f, 0x27, 0x62, 0x5a, 0x4b,
+       0xc3, 0xac, 0x5f, 0x0a, 0x40, 0x98, 0x29, 0x02, 0x03, 0x01, 0x00, 0x01,
+       0xa3, 0x23, 0x30, 0x21, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
+       0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06,
+       0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01,
+       0x86, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+       0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x35, 0xa8, 0x47, 0x69,
+       0x01, 0x12, 0x43, 0x34, 0x73, 0xe4, 0xd8, 0xa4, 0x95, 0x00, 0xea, 0xd7,
+       0x33, 0xf2, 0x7b, 0x49, 0xea, 0xa7, 0xc6, 0xe1, 0x7d, 0x06, 0xb8, 0xb4,
+       0x4f, 0x3f, 0x08, 0x97, 0xa8, 0x47, 0x82, 0x1e, 0x0a, 0x4b, 0xdb, 0x19,
+       0x9d, 0x21, 0x30, 0x2c, 0x37, 0xa0, 0x3f, 0x92, 0xf7, 0xc2, 0x39, 0x57,
+       0x2b, 0x43, 0x33, 0xf9, 0x6e, 0x40, 0x8c, 0x64, 0x2b, 0xf5, 0xb6, 0xb6,
+       0x6c, 0x2e, 0x59, 0xc4, 0xe6, 0x01, 0x87, 0xd4, 0x1c, 0x32, 0xf1, 0x68,
+       0x72, 0xeb, 0xda, 0x35, 0x69, 0x3c, 0x7d, 0x6f, 0x4c, 0xba, 0x8b, 0x4d,
+       0xaa, 0x1c, 0x11, 0x05, 0x76, 0x9e, 0x73, 0x2a, 0x20, 0xcb, 0x31, 0x9c,
+       0x74, 0x20, 0x99, 0x4c, 0xbc, 0x17, 0xd0, 0xb5, 0x6e, 0x1e, 0xad, 0x87,
+       0x83, 0xa6, 0xda, 0x15, 0x85, 0x7a, 0x8f, 0x76, 0x37, 0xa7, 0x11, 0x53,
+       0x7f, 0x12, 0xb1, 0x05, 0x30, 0x82, 0x02, 0x0c, 0x30, 0x82, 0x01, 0x75,
+       0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x64, 0x30, 0x0d, 0x06, 0x09,
+       0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
+       0x4d, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x04,
+       0x4e, 0x6f, 0x6e, 0x65, 0x31, 0x3c, 0x30, 0x3a, 0x06, 0x03, 0x55, 0x04,
+       0x03, 0x0c, 0x33, 0x41, 0x43, 0x4d, 0x45, 0x20, 0x52, 0x6f, 0x6f, 0x74,
+       0x20, 0x43, 0x41, 0x20, 0x28, 0x35, 0x36, 0x32, 0x66, 0x30, 0x64, 0x30,
+       0x35, 0x2d, 0x32, 0x35, 0x36, 0x61, 0x2d, 0x34, 0x32, 0x65, 0x65, 0x2d,
+       0x39, 0x66, 0x35, 0x38, 0x2d, 0x38, 0x30, 0x62, 0x30, 0x61, 0x35, 0x35,
+       0x37, 0x38, 0x62, 0x66, 0x30, 0x29, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39,
+       0x30, 0x39, 0x31, 0x37, 0x30, 0x30, 0x33, 0x39, 0x32, 0x33, 0x5a, 0x17,
+       0x0d, 0x31, 0x30, 0x30, 0x39, 0x31, 0x37, 0x30, 0x30, 0x33, 0x39, 0x32,
+       0x33, 0x5a, 0x30, 0x26, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04,
+       0x0a, 0x0c, 0x04, 0x4e, 0x6f, 0x6e, 0x65, 0x31, 0x15, 0x30, 0x13, 0x06,
+       0x03, 0x55, 0x04, 0x03, 0x0c, 0x0c, 0x41, 0x43, 0x4d, 0x45, 0x20, 0x53,
+       0x43, 0x45, 0x50, 0x20, 0x52, 0x41, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06,
+       0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
+       0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xd1,
+       0x6e, 0x98, 0x93, 0x0e, 0x0a, 0x27, 0x5f, 0xd9, 0x3e, 0x95, 0xe3, 0x24,
+       0xae, 0x96, 0xd2, 0x62, 0x40, 0x05, 0xb6, 0x2d, 0x4d, 0xe2, 0x8f, 0x35,
+       0x26, 0x14, 0x72, 0x04, 0xb0, 0x34, 0xaf, 0xf3, 0x61, 0x7c, 0xa0, 0x72,
+       0xe6, 0x29, 0xf3, 0xdf, 0xc2, 0x2a, 0x8c, 0x84, 0xde, 0xea, 0x7c, 0x01,
+       0x64, 0x08, 0x8c, 0xaa, 0x0b, 0x96, 0x9b, 0xb5, 0xb8, 0x86, 0x49, 0xad,
+       0x68, 0x1d, 0x7c, 0xf0, 0x1a, 0xe9, 0xf6, 0x56, 0x97, 0xe4, 0xb8, 0x20,
+       0xa6, 0x1f, 0x1a, 0x9d, 0xcc, 0x5f, 0xe8, 0xc9, 0x05, 0xab, 0x85, 0xab,
+       0xce, 0x5c, 0xcd, 0x20, 0xb7, 0x01, 0x8d, 0xda, 0x10, 0x54, 0x22, 0xbd,
+       0x93, 0xf9, 0xac, 0x12, 0x39, 0x08, 0x9d, 0x27, 0xa1, 0x92, 0xb6, 0x94,
+       0xde, 0x15, 0xcc, 0x0f, 0x9e, 0x1f, 0xe0, 0x44, 0x90, 0x57, 0x87, 0x04,
+       0x9b, 0xfb, 0xb0, 0x63, 0x9d, 0xc0, 0x4d, 0x02, 0x03, 0x01, 0x00, 0x01,
+       0xa3, 0x23, 0x30, 0x21, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
+       0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06,
+       0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05,
+       0xa0, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+       0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0xbb, 0xb7, 0xa1, 0xd6,
+       0x0c, 0xdd, 0xa8, 0xfe, 0x4a, 0x3b, 0x90, 0x42, 0x9b, 0x4f, 0xfc, 0xa4,
+       0x75, 0xf2, 0x04, 0x09, 0xd6, 0x9e, 0xfb, 0x4f, 0x99, 0xf8, 0xcb, 0x5c,
+       0xcc, 0xb0, 0xb3, 0xce, 0xd7, 0x83, 0xed, 0x4d, 0xa7, 0x93, 0xdb, 0x87,
+       0x7b, 0x09, 0x2f, 0x07, 0xb3, 0xd2, 0xa3, 0x08, 0x17, 0x53, 0xb4, 0x61,
+       0xd7, 0x58, 0x86, 0x79, 0x2c, 0x2e, 0x09, 0x75, 0xda, 0x61, 0xa8, 0x90,
+       0x1f, 0xea, 0x2f, 0x0f, 0x2a, 0xcb, 0xf5, 0x01, 0x54, 0xee, 0x23, 0x80,
+       0xbb, 0xaa, 0xb5, 0x61, 0x66, 0x23, 0xb3, 0xd2, 0xff, 0x7f, 0xb8, 0x74,
+       0xc9, 0x55, 0xb5, 0x84, 0x57, 0x5a, 0x2e, 0x81, 0x0d, 0xe5, 0x0d, 0x45,
+       0x4f, 0x37, 0xc4, 0x2d, 0xec, 0xf8, 0xf1, 0x15, 0x59, 0xc4, 0x7a, 0x49,
+       0xd0, 0x12, 0x16, 0x18, 0x6a, 0x3e, 0x74, 0xe5, 0x4e, 0x65, 0xdc, 0xcc,
+       0xba, 0x9e, 0x77, 0x7c, 0x31, 0x00
+};
+static unsigned int getcacert_len = 1134;
+
+static uint8_t msscep_md5_hash[] = {0x13, 0x7f, 0x4d, 0xaa, 0x5d, 0xa0, 0x65, 0x1b, 0xbd, 0x54, 0x8c, 0xc2, 0xd3, 0xd4, 0xce, 0xd0 };
+static uint8_t ruby_sha1_hash[] = { 0xf3, 0x5f, 0x6b, 0xd1, 0x64, 0x0b, 0xc1, 0x81, 0x98, 0xb9, 0x30, 0xd1, 0x97, 0x10, 0x3b, 0x45, 0xf0, 0x6e, 0x53, 0xdb };
+
+
+static unsigned char bmw_scep_pkt[] = {
+  0x30, 0x82, 0x16, 0x19, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x07, 0x02, 0xa0, 0x82, 0x16, 0x0a, 0x30, 0x82, 0x16, 0x06, 0x02,
+  0x01, 0x01, 0x31, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x15, 0xee, 0x30, 0x82, 0x06,
+  0x26, 0x30, 0x82, 0x05, 0x0e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0a,
+  0x3c, 0xec, 0x7e, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x30, 0x0d,
+  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
+  0x00, 0x30, 0x64, 0x31, 0x14, 0x30, 0x12, 0x06, 0x0a, 0x09, 0x92, 0x26,
+  0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x04, 0x63, 0x6f, 0x72,
+  0x70, 0x31, 0x13, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
+  0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x62, 0x6d, 0x77, 0x31, 0x16,
+  0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64,
+  0x01, 0x19, 0x16, 0x06, 0x65, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x31, 0x1f,
+  0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x42, 0x4d, 0x57,
+  0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x49, 0x73, 0x73, 0x75, 0x69,
+  0x6e, 0x67, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x1e, 0x17, 0x0d, 0x31,
+  0x30, 0x30, 0x33, 0x30, 0x34, 0x31, 0x33, 0x35, 0x33, 0x31, 0x30, 0x5a,
+  0x17, 0x0d, 0x31, 0x32, 0x30, 0x33, 0x30, 0x33, 0x31, 0x33, 0x35, 0x33,
+  0x31, 0x30, 0x5a, 0x30, 0x81, 0x83, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+  0x55, 0x04, 0x06, 0x13, 0x02, 0x44, 0x45, 0x31, 0x10, 0x30, 0x0e, 0x06,
+  0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x42, 0x61, 0x76, 0x61, 0x72, 0x69,
+  0x61, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x06,
+  0x4d, 0x75, 0x6e, 0x69, 0x63, 0x68, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03,
+  0x55, 0x04, 0x0a, 0x13, 0x09, 0x42, 0x4d, 0x57, 0x20, 0x47, 0x72, 0x6f,
+  0x75, 0x70, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+  0x11, 0x53, 0x43, 0x45, 0x50, 0x20, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e,
+  0x67, 0x20, 0x43, 0x41, 0x20, 0x32, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x74,
+  0x72, 0x75, 0x73, 0x74, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x40, 0x62,
+  0x6d, 0x77, 0x2e, 0x64, 0x65, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
+  0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xad, 0x57,
+  0x88, 0x2c, 0x2c, 0xda, 0x45, 0x32, 0x32, 0xb1, 0xba, 0xce, 0x1b, 0x0b,
+  0x5d, 0xc8, 0x5d, 0x76, 0xd2, 0x63, 0xf6, 0xc7, 0xe6, 0x45, 0xff, 0x37,
+  0xf3, 0x85, 0xbf, 0xbb, 0xa1, 0x83, 0xd1, 0xea, 0xe0, 0x3f, 0xc9, 0x05,
+  0x79, 0xe3, 0x15, 0xc3, 0x97, 0x2a, 0x81, 0x38, 0x4f, 0x33, 0xc1, 0xc9,
+  0xf5, 0xb0, 0x1b, 0xbd, 0xad, 0x52, 0x15, 0x80, 0x52, 0x7d, 0x1b, 0x68,
+  0x8f, 0xb5, 0x27, 0xda, 0xcf, 0x20, 0x7d, 0x53, 0x6e, 0xb0, 0xe8, 0x4b,
+  0x8e, 0x6b, 0xb2, 0x63, 0xe3, 0xd5, 0x2c, 0x67, 0x55, 0x73, 0x0f, 0xda,
+  0x41, 0x04, 0x56, 0xdc, 0xb3, 0x9a, 0x6b, 0xbb, 0x62, 0xf8, 0x8f, 0xe2,
+  0x91, 0x7a, 0xe8, 0xa7, 0xa9, 0xc4, 0x8b, 0x75, 0x7b, 0xb5, 0x5f, 0x4e,
+  0xe1, 0x4d, 0x80, 0x4d, 0xc9, 0xee, 0x23, 0xbc, 0xf7, 0x4f, 0x8d, 0xc0,
+  0x02, 0x20, 0x23, 0x82, 0x80, 0xf7, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
+  0x82, 0x03, 0x3c, 0x30, 0x82, 0x03, 0x38, 0x30, 0x0b, 0x06, 0x03, 0x55,
+  0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x15, 0x06, 0x03,
+  0x55, 0x1d, 0x25, 0x04, 0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01,
+  0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x01, 0x30, 0x3b, 0x06, 0x09, 0x2b,
+  0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x04, 0x2e, 0x1e, 0x2c,
+  0x00, 0x45, 0x00, 0x6e, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x6c, 0x00, 0x6c,
+  0x00, 0x6d, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x41, 0x00, 0x67,
+  0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x4f, 0x00, 0x66, 0x00, 0x66,
+  0x00, 0x6c, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x65, 0x30, 0x1d, 0x06, 0x03,
+  0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xd8, 0xeb, 0x70, 0x8b, 0x4e,
+  0xda, 0xfb, 0x52, 0x03, 0x0c, 0xa5, 0xc5, 0xfd, 0xf3, 0x29, 0x54, 0xfd,
+  0x2e, 0x8f, 0x3e, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
+  0x30, 0x16, 0x80, 0x14, 0x61, 0x0a, 0xef, 0x1a, 0x3d, 0xfe, 0x9a, 0x68,
+  0x81, 0xcb, 0xb2, 0x62, 0xe5, 0xc0, 0x21, 0x8e, 0xdd, 0xec, 0x61, 0x95,
+  0x30, 0x82, 0x01, 0x71, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x82, 0x01,
+  0x68, 0x30, 0x82, 0x01, 0x64, 0x30, 0x82, 0x01, 0x60, 0xa0, 0x82, 0x01,
+  0x5c, 0xa0, 0x82, 0x01, 0x58, 0x86, 0x81, 0xc3, 0x6c, 0x64, 0x61, 0x70,
+  0x3a, 0x2f, 0x2f, 0x2f, 0x43, 0x4e, 0x3d, 0x42, 0x4d, 0x57, 0x25, 0x32,
+  0x30, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x25, 0x32, 0x30, 0x49, 0x73, 0x73,
+  0x75, 0x69, 0x6e, 0x67, 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30,
+  0x32, 0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x4d, 0x55, 0x43, 0x31, 0x39, 0x32,
+  0x33, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x44, 0x50, 0x2c, 0x43, 0x4e, 0x3d,
+  0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30, 0x4b, 0x65, 0x79,
+  0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c,
+  0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c,
+  0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61,
+  0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x62, 0x6d, 0x77, 0x2c,
+  0x44, 0x43, 0x3d, 0x63, 0x6f, 0x72, 0x70, 0x3f, 0x63, 0x65, 0x72, 0x74,
+  0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x76, 0x6f, 0x63,
+  0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x3f, 0x62, 0x61,
+  0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x61,
+  0x73, 0x73, 0x3d, 0x63, 0x52, 0x4c, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69,
+  0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x86,
+  0x4d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x6d, 0x75, 0x63,
+  0x31, 0x39, 0x32, 0x33, 0x2e, 0x65, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2e,
+  0x62, 0x6d, 0x77, 0x2e, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x43, 0x65, 0x72,
+  0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x42, 0x4d, 0x57, 0x25,
+  0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x25, 0x32, 0x30, 0x49, 0x73,
+  0x73, 0x75, 0x69, 0x6e, 0x67, 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32,
+  0x30, 0x32, 0x2e, 0x63, 0x72, 0x6c, 0x86, 0x41, 0x68, 0x74, 0x74, 0x70,
+  0x3a, 0x2f, 0x2f, 0x73, 0x73, 0x6c, 0x63, 0x72, 0x6c, 0x2e, 0x62, 0x6d,
+  0x77, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70,
+  0x6b, 0x69, 0x2f, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f,
+  0x75, 0x70, 0x25, 0x32, 0x30, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67,
+  0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x2e, 0x63, 0x72,
+  0x6c, 0x30, 0x82, 0x01, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+  0x07, 0x01, 0x01, 0x04, 0x82, 0x01, 0x10, 0x30, 0x82, 0x01, 0x0c, 0x30,
+  0x81, 0xba, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02,
+  0x86, 0x81, 0xad, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x2f, 0x43,
+  0x4e, 0x3d, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75,
+  0x70, 0x25, 0x32, 0x30, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, 0x25,
+  0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x2c, 0x43, 0x4e, 0x3d,
+  0x41, 0x49, 0x41, 0x2c, 0x43, 0x4e, 0x3d, 0x50, 0x75, 0x62, 0x6c, 0x69,
+  0x63, 0x25, 0x32, 0x30, 0x4b, 0x65, 0x79, 0x25, 0x32, 0x30, 0x53, 0x65,
+  0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65,
+  0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x6f,
+  0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c,
+  0x44, 0x43, 0x3d, 0x62, 0x6d, 0x77, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f,
+  0x72, 0x70, 0x3f, 0x63, 0x41, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+  0x63, 0x61, 0x74, 0x65, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62,
+  0x6a, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x65,
+  0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41,
+  0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x4d, 0x06, 0x08,
+  0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x41, 0x68, 0x74,
+  0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x73, 0x6c, 0x63, 0x72, 0x6c, 0x2e,
+  0x62, 0x6d, 0x77, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x63, 0x6f, 0x6d,
+  0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47,
+  0x72, 0x6f, 0x75, 0x70, 0x25, 0x32, 0x30, 0x49, 0x73, 0x73, 0x75, 0x69,
+  0x6e, 0x67, 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x2e,
+  0x63, 0x72, 0x74, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x46,
+  0x9e, 0x81, 0xb2, 0xec, 0xa9, 0xe4, 0x3c, 0xf3, 0x9b, 0x61, 0xdf, 0x6f,
+  0xec, 0x28, 0xe9, 0x2b, 0xd4, 0xc1, 0xb2, 0x05, 0x03, 0xbd, 0x53, 0x49,
+  0xa2, 0x94, 0x3a, 0xd6, 0x23, 0xa3, 0xe8, 0x52, 0xa4, 0xe6, 0x44, 0x5e,
+  0x15, 0x89, 0xde, 0x32, 0x12, 0xba, 0x97, 0x3a, 0xd3, 0x1d, 0xa1, 0xda,
+  0x2a, 0x70, 0x3e, 0x10, 0xea, 0x2c, 0xb5, 0x19, 0xc2, 0x71, 0xcd, 0x1c,
+  0x10, 0x07, 0x4b, 0x58, 0x10, 0x61, 0x03, 0x72, 0x4f, 0x65, 0xf7, 0x38,
+  0x9d, 0xa9, 0x35, 0x0c, 0xc9, 0xdf, 0x7f, 0x91, 0xa0, 0xd4, 0x08, 0xf2,
+  0xf9, 0x1b, 0x0f, 0xaa, 0xb4, 0xb6, 0xe0, 0x3c, 0x9d, 0x0c, 0x64, 0xee,
+  0x2f, 0x47, 0xdd, 0xdb, 0x3a, 0x6f, 0x69, 0x19, 0x1f, 0xa1, 0xdd, 0x1d,
+  0xd7, 0x45, 0x04, 0x56, 0x16, 0x43, 0x22, 0x18, 0xba, 0x22, 0xd6, 0x70,
+  0xd0, 0x67, 0xb0, 0x06, 0x6a, 0x16, 0x57, 0x61, 0x83, 0x47, 0xd9, 0x40,
+  0xc9, 0x92, 0xdd, 0x74, 0xbe, 0xb9, 0xe8, 0x07, 0x40, 0xa8, 0x23, 0xc5,
+  0xd6, 0x3e, 0x26, 0xec, 0x17, 0x6c, 0x61, 0x76, 0x47, 0x42, 0x0a, 0x82,
+  0x5e, 0xdb, 0x41, 0xba, 0x42, 0x1f, 0xec, 0xb7, 0xc2, 0xe0, 0xf8, 0x3a,
+  0x39, 0x5f, 0xb2, 0x45, 0x92, 0xdc, 0xe2, 0x5e, 0x5d, 0x81, 0x14, 0xa3,
+  0x10, 0x68, 0x5a, 0xed, 0x28, 0x9f, 0xad, 0xa6, 0xc9, 0xd9, 0x61, 0xc2,
+  0x62, 0xec, 0x1b, 0x61, 0x2a, 0x67, 0xef, 0xac, 0x79, 0xc1, 0x6e, 0x35,
+  0xc4, 0xd2, 0x69, 0x05, 0x3f, 0xf2, 0x6f, 0x5a, 0x66, 0x0c, 0xea, 0xd2,
+  0x70, 0x2e, 0xbe, 0x5f, 0xd8, 0x31, 0x6c, 0x1f, 0xec, 0x62, 0xf6, 0xa7,
+  0x98, 0x1c, 0xd4, 0xf6, 0xc1, 0x28, 0x71, 0xf5, 0x63, 0xab, 0x59, 0x4b,
+  0x34, 0xb4, 0x30, 0x12, 0x91, 0x71, 0xf8, 0x50, 0x9a, 0x26, 0x4a, 0xd9,
+  0xf1, 0x30, 0x04, 0x30, 0x82, 0x06, 0x4c, 0x30, 0x82, 0x05, 0x34, 0xa0,
+  0x03, 0x02, 0x01, 0x02, 0x02, 0x0a, 0x3c, 0xec, 0x82, 0xf8, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0e, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x64, 0x31, 0x14, 0x30,
+  0x12, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01,
+  0x19, 0x16, 0x04, 0x63, 0x6f, 0x72, 0x70, 0x31, 0x13, 0x30, 0x11, 0x06,
+  0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16,
+  0x03, 0x62, 0x6d, 0x77, 0x31, 0x16, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92,
+  0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x65, 0x75,
+  0x72, 0x6f, 0x70, 0x65, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04,
+  0x03, 0x13, 0x16, 0x42, 0x4d, 0x57, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70,
+  0x20, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, 0x20, 0x43, 0x41, 0x20,
+  0x32, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x30, 0x33, 0x30, 0x34, 0x31,
+  0x33, 0x35, 0x33, 0x31, 0x31, 0x5a, 0x17, 0x0d, 0x31, 0x32, 0x30, 0x33,
+  0x30, 0x33, 0x31, 0x33, 0x35, 0x33, 0x31, 0x31, 0x5a, 0x30, 0x81, 0x83,
+  0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x44,
+  0x45, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07,
+  0x42, 0x61, 0x76, 0x61, 0x72, 0x69, 0x61, 0x31, 0x0f, 0x30, 0x0d, 0x06,
+  0x03, 0x55, 0x04, 0x07, 0x13, 0x06, 0x4d, 0x75, 0x6e, 0x69, 0x63, 0x68,
+  0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09, 0x42,
+  0x4d, 0x57, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x31, 0x1a, 0x30, 0x18,
+  0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x43, 0x45, 0x50, 0x20,
+  0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, 0x20, 0x43, 0x41, 0x20, 0x32,
+  0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x09, 0x01, 0x16, 0x12, 0x74, 0x72, 0x75, 0x73, 0x74, 0x63, 0x65,
+  0x6e, 0x74, 0x65, 0x72, 0x40, 0x62, 0x6d, 0x77, 0x2e, 0x64, 0x65, 0x30,
+  0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89,
+  0x02, 0x81, 0x81, 0x00, 0xa4, 0x78, 0xc8, 0x9b, 0xd9, 0x08, 0x24, 0xab,
+  0x07, 0x33, 0x89, 0x62, 0xcd, 0x20, 0xcb, 0x16, 0xfa, 0x1d, 0x9b, 0x8a,
+  0xcf, 0x9d, 0x61, 0xea, 0x10, 0xbd, 0xa0, 0x02, 0xf5, 0x97, 0x53, 0x96,
+  0x86, 0xb3, 0x02, 0x88, 0xf7, 0x52, 0xd8, 0x67, 0xcd, 0xe4, 0xba, 0xa7,
+  0x36, 0xfd, 0x6e, 0xd3, 0x51, 0x9a, 0xa2, 0xfb, 0xcc, 0x2c, 0xd1, 0xaa,
+  0x9c, 0x49, 0x2e, 0x36, 0xe0, 0xa2, 0x21, 0xc8, 0xfd, 0x05, 0xa9, 0x54,
+  0x16, 0x9f, 0xd3, 0x8e, 0x6a, 0xbe, 0x3e, 0x7f, 0xc8, 0xc6, 0x2d, 0x8d,
+  0xda, 0xe9, 0x73, 0x97, 0x5e, 0x80, 0xdd, 0x8c, 0xc4, 0x9b, 0x3a, 0x77,
+  0xc7, 0x6a, 0x8d, 0xe2, 0xe1, 0x54, 0x6f, 0x5e, 0xde, 0x3f, 0x71, 0x9c,
+  0x14, 0x2d, 0x15, 0x6d, 0xf1, 0x7c, 0x43, 0x97, 0xb7, 0xdf, 0x5a, 0x1a,
+  0xb8, 0xb7, 0x9c, 0x05, 0x4d, 0xf5, 0x45, 0x45, 0x59, 0xbe, 0x73, 0xbd,
+  0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x03, 0x62, 0x30, 0x82, 0x03,
+  0x5e, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02,
+  0x05, 0x20, 0x30, 0x36, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x09, 0x0f, 0x04, 0x29, 0x30, 0x27, 0x30, 0x0d, 0x06, 0x08, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x02, 0x02, 0x01, 0x38, 0x30, 0x0d,
+  0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x04, 0x02, 0x01,
+  0x38, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x07, 0x30, 0x15,
+  0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2b,
+  0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x01, 0x30, 0x29, 0x06,
+  0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x04, 0x1c,
+  0x1e, 0x1a, 0x00, 0x43, 0x00, 0x45, 0x00, 0x50, 0x00, 0x45, 0x00, 0x6e,
+  0x00, 0x63, 0x00, 0x72, 0x00, 0x79, 0x00, 0x70, 0x00, 0x74, 0x00, 0x69,
+  0x00, 0x6f, 0x00, 0x6e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
+  0x16, 0x04, 0x14, 0x11, 0xe1, 0x07, 0x5e, 0xd5, 0x49, 0xed, 0x64, 0x11,
+  0xc4, 0x33, 0xbb, 0x2a, 0x99, 0x7c, 0xb0, 0xc8, 0xd8, 0x85, 0x8d, 0x30,
+  0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
+  0x61, 0x0a, 0xef, 0x1a, 0x3d, 0xfe, 0x9a, 0x68, 0x81, 0xcb, 0xb2, 0x62,
+  0xe5, 0xc0, 0x21, 0x8e, 0xdd, 0xec, 0x61, 0x95, 0x30, 0x82, 0x01, 0x71,
+  0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x82, 0x01, 0x68, 0x30, 0x82, 0x01,
+  0x64, 0x30, 0x82, 0x01, 0x60, 0xa0, 0x82, 0x01, 0x5c, 0xa0, 0x82, 0x01,
+  0x58, 0x86, 0x81, 0xc3, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x2f,
+  0x43, 0x4e, 0x3d, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f,
+  0x75, 0x70, 0x25, 0x32, 0x30, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67,
+  0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x2c, 0x43, 0x4e,
+  0x3d, 0x53, 0x4d, 0x55, 0x43, 0x31, 0x39, 0x32, 0x33, 0x2c, 0x43, 0x4e,
+  0x3d, 0x43, 0x44, 0x50, 0x2c, 0x43, 0x4e, 0x3d, 0x50, 0x75, 0x62, 0x6c,
+  0x69, 0x63, 0x25, 0x32, 0x30, 0x4b, 0x65, 0x79, 0x25, 0x32, 0x30, 0x53,
+  0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x53,
+  0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x43,
+  0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+  0x2c, 0x44, 0x43, 0x3d, 0x62, 0x6d, 0x77, 0x2c, 0x44, 0x43, 0x3d, 0x63,
+  0x6f, 0x72, 0x70, 0x3f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+  0x61, 0x74, 0x65, 0x52, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f,
+  0x6e, 0x4c, 0x69, 0x73, 0x74, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f,
+  0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63,
+  0x52, 0x4c, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69,
+  0x6f, 0x6e, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x86, 0x4d, 0x68, 0x74, 0x74,
+  0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x6d, 0x75, 0x63, 0x31, 0x39, 0x32, 0x33,
+  0x2e, 0x65, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2e, 0x62, 0x6d, 0x77, 0x2e,
+  0x63, 0x6f, 0x72, 0x70, 0x2f, 0x43, 0x65, 0x72, 0x74, 0x45, 0x6e, 0x72,
+  0x6f, 0x6c, 0x6c, 0x2f, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72,
+  0x6f, 0x75, 0x70, 0x25, 0x32, 0x30, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e,
+  0x67, 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x2e, 0x63,
+  0x72, 0x6c, 0x86, 0x41, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73,
+  0x73, 0x6c, 0x63, 0x72, 0x6c, 0x2e, 0x62, 0x6d, 0x77, 0x67, 0x72, 0x6f,
+  0x75, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x42,
+  0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x25, 0x32,
+  0x30, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, 0x25, 0x32, 0x30, 0x43,
+  0x41, 0x25, 0x32, 0x30, 0x32, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x82, 0x01,
+  0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
+  0x82, 0x01, 0x10, 0x30, 0x82, 0x01, 0x0c, 0x30, 0x81, 0xba, 0x06, 0x08,
+  0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x81, 0xad, 0x6c,
+  0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x2f, 0x43, 0x4e, 0x3d, 0x42, 0x4d,
+  0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x25, 0x32, 0x30,
+  0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, 0x25, 0x32, 0x30, 0x43, 0x41,
+  0x25, 0x32, 0x30, 0x32, 0x2c, 0x43, 0x4e, 0x3d, 0x41, 0x49, 0x41, 0x2c,
+  0x43, 0x4e, 0x3d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30,
+  0x4b, 0x65, 0x79, 0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
+  0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
+  0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+  0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x62,
+  0x6d, 0x77, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, 0x72, 0x70, 0x3f, 0x63,
+  0x41, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65,
+  0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74,
+  0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66,
+  0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x6f,
+  0x72, 0x69, 0x74, 0x79, 0x30, 0x4d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+  0x05, 0x07, 0x30, 0x02, 0x86, 0x41, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+  0x2f, 0x73, 0x73, 0x6c, 0x63, 0x72, 0x6c, 0x2e, 0x62, 0x6d, 0x77, 0x67,
+  0x72, 0x6f, 0x75, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69,
+  0x2f, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70,
+  0x25, 0x32, 0x30, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, 0x25, 0x32,
+  0x30, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x2e, 0x63, 0x72, 0x74, 0x30,
+  0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
+  0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xa6, 0xdb, 0xab, 0x42, 0x93,
+  0x90, 0xb9, 0x6a, 0xc1, 0x92, 0xb7, 0x3c, 0xaf, 0xf2, 0x9b, 0xed, 0x2b,
+  0x14, 0xdb, 0xd8, 0x9f, 0x6b, 0xb8, 0x8e, 0x08, 0xf0, 0x0e, 0x1a, 0xfe,
+  0xb3, 0x9a, 0x6f, 0x3d, 0x28, 0x79, 0xd4, 0x88, 0xbe, 0x1c, 0x17, 0xaa,
+  0x6a, 0xa4, 0xe9, 0xf0, 0xe0, 0xee, 0x9d, 0x74, 0x25, 0xbb, 0x48, 0x16,
+  0xb1, 0x00, 0xca, 0xfa, 0x6a, 0x0c, 0x16, 0x98, 0xef, 0xf9, 0x42, 0xd6,
+  0x81, 0xb4, 0xf7, 0xa2, 0x15, 0xb6, 0xdc, 0xe8, 0x25, 0xe8, 0xdd, 0x92,
+  0x1d, 0x0c, 0x96, 0xea, 0x80, 0x41, 0x3f, 0xd7, 0xff, 0xeb, 0x53, 0xe9,
+  0x13, 0xf8, 0xdc, 0x8b, 0xe2, 0x45, 0xb8, 0xbb, 0x22, 0x81, 0xea, 0x46,
+  0xee, 0x19, 0x14, 0xe3, 0xd5, 0xb0, 0xaa, 0x2a, 0xd2, 0x52, 0xa5, 0x3f,
+  0x7e, 0xa5, 0x7d, 0x5c, 0xb0, 0x84, 0x4e, 0x77, 0x01, 0x35, 0x76, 0x31,
+  0xa3, 0x6e, 0x3f, 0x51, 0x20, 0x3f, 0x98, 0xac, 0x68, 0x28, 0x0f, 0xc6,
+  0x5a, 0xc1, 0xcf, 0x58, 0xd7, 0x75, 0xaa, 0xe2, 0x9b, 0xc3, 0xfa, 0x3c,
+  0xd6, 0x61, 0x98, 0x2b, 0xf1, 0x73, 0x78, 0x2a, 0xb2, 0x54, 0x78, 0xba,
+  0xff, 0x36, 0x15, 0x17, 0xe7, 0xe6, 0x6e, 0x82, 0xee, 0x64, 0x87, 0x81,
+  0xd9, 0x08, 0x68, 0xa4, 0xc7, 0x9b, 0xa4, 0xa9, 0xf3, 0x1e, 0xe9, 0x82,
+  0xc1, 0x3d, 0xfd, 0xe9, 0x75, 0x77, 0x81, 0x73, 0x05, 0x2e, 0x36, 0x0e,
+  0x17, 0x13, 0x48, 0x20, 0x9c, 0x24, 0xce, 0xe2, 0x22, 0x68, 0x3f, 0x37,
+  0x3d, 0xf5, 0x01, 0x0e, 0x13, 0xec, 0x3d, 0xba, 0x0d, 0x71, 0xd2, 0xe2,
+  0x67, 0x65, 0x19, 0x24, 0xa4, 0x5d, 0xae, 0x35, 0x1e, 0x39, 0x4c, 0xe4,
+  0x19, 0x48, 0x91, 0x03, 0x9e, 0xe9, 0x42, 0xfd, 0x1f, 0x1d, 0x2a, 0x98,
+  0x40, 0xd0, 0xb6, 0x92, 0xb3, 0x38, 0x0f, 0xf5, 0x7f, 0xf0, 0xc1, 0x30,
+  0x82, 0x03, 0x70, 0x30, 0x82, 0x02, 0x58, 0xa0, 0x03, 0x02, 0x01, 0x02,
+  0x02, 0x10, 0x13, 0xaa, 0xab, 0xff, 0x7f, 0x25, 0x31, 0xae, 0x49, 0x9b,
+  0x17, 0x9b, 0xef, 0xee, 0xe2, 0x97, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x40, 0x31,
+  0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x44, 0x45,
+  0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09, 0x42,
+  0x4d, 0x57, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x31, 0x1d, 0x30, 0x1b,
+  0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x42, 0x4d, 0x57, 0x20, 0x47,
+  0x72, 0x6f, 0x75, 0x70, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41,
+  0x20, 0x56, 0x32, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, 0x31, 0x32, 0x31,
+  0x30, 0x31, 0x30, 0x32, 0x36, 0x35, 0x31, 0x5a, 0x17, 0x0d, 0x33, 0x34,
+  0x31, 0x32, 0x31, 0x30, 0x31, 0x30, 0x33, 0x35, 0x34, 0x30, 0x5a, 0x30,
+  0x40, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+  0x44, 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+  0x09, 0x42, 0x4d, 0x57, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x31, 0x1d,
+  0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x42, 0x4d, 0x57,
+  0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
+  0x43, 0x41, 0x20, 0x56, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06,
+  0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
+  0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01,
+  0x01, 0x00, 0xd0, 0x27, 0x3b, 0xb7, 0xfe, 0x8d, 0x0c, 0xd6, 0xed, 0xf0,
+  0xa2, 0x49, 0x1f, 0x83, 0xed, 0x11, 0xcf, 0x56, 0x96, 0xe2, 0xe2, 0x1a,
+  0xac, 0x59, 0x4c, 0xef, 0x27, 0xf7, 0xda, 0xf8, 0x6a, 0x0d, 0xea, 0x78,
+  0x27, 0x69, 0x84, 0xd0, 0x4d, 0x94, 0xd8, 0x78, 0xc6, 0x14, 0x25, 0x98,
+  0x68, 0x69, 0xd5, 0x3a, 0xfd, 0x84, 0x39, 0xf3, 0x4a, 0xb8, 0x47, 0x51,
+  0x59, 0x8c, 0xa4, 0x24, 0x97, 0x10, 0xb5, 0x3b, 0x28, 0x4f, 0x26, 0x91,
+  0xad, 0xb2, 0x39, 0xc7, 0x8b, 0x96, 0x99, 0x62, 0x53, 0xe3, 0xee, 0xba,
+  0x1d, 0x55, 0x49, 0x98, 0x32, 0x60, 0xb3, 0x8d, 0x1a, 0x53, 0x29, 0x7b,
+  0xf1, 0xd3, 0xf4, 0xbc, 0x7d, 0xf1, 0x47, 0x78, 0x88, 0xe4, 0x14, 0x9c,
+  0x60, 0xdc, 0x8b, 0x65, 0xfd, 0x95, 0x39, 0xc0, 0x8b, 0x59, 0xcb, 0x66,
+  0xd2, 0x6a, 0x19, 0x67, 0x0e, 0xcd, 0x56, 0xf6, 0x7a, 0x2a, 0x8f, 0x2a,
+  0x4f, 0x1e, 0x15, 0x4d, 0xbe, 0xb5, 0x3e, 0xca, 0x3a, 0xc3, 0x93, 0x8a,
+  0xac, 0x28, 0x4c, 0x2d, 0xbd, 0x1f, 0x2b, 0x92, 0x43, 0x32, 0xdd, 0x97,
+  0xef, 0xb7, 0x09, 0xf3, 0x6b, 0x3d, 0x1e, 0x36, 0x16, 0x8b, 0x78, 0xce,
+  0x96, 0x45, 0x36, 0x9d, 0x3a, 0x90, 0x5e, 0x20, 0x3f, 0xb2, 0x39, 0x8b,
+  0x2f, 0x76, 0xd1, 0x2f, 0xe9, 0x2a, 0xb0, 0xd8, 0x40, 0x0b, 0xd9, 0x62,
+  0xd0, 0xe0, 0x6b, 0xa6, 0xf7, 0x00, 0xa8, 0x50, 0xac, 0xb0, 0x17, 0x20,
+  0x6c, 0x89, 0x1b, 0x32, 0x0a, 0x91, 0x8f, 0x94, 0xcf, 0x24, 0x72, 0xdb,
+  0x4f, 0xf9, 0x4c, 0x9e, 0x88, 0x49, 0xd9, 0x01, 0x03, 0xd0, 0xc7, 0xf4,
+  0xd1, 0xf8, 0xd5, 0x6b, 0x76, 0xea, 0x14, 0xa3, 0xb5, 0x24, 0x4c, 0xa5,
+  0xd2, 0xa8, 0x12, 0x79, 0xd3, 0x27, 0xb4, 0x9a, 0x47, 0xaa, 0x7b, 0x74,
+  0x90, 0xbb, 0xb5, 0x74, 0x29, 0x53, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
+  0x66, 0x30, 0x64, 0x30, 0x13, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01,
+  0x82, 0x37, 0x14, 0x02, 0x04, 0x06, 0x1e, 0x04, 0x00, 0x43, 0x00, 0x41,
+  0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01,
+  0x86, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04,
+  0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
+  0x0e, 0x04, 0x16, 0x04, 0x14, 0x17, 0xd0, 0xa6, 0x81, 0xc4, 0xba, 0xb6,
+  0x59, 0xe8, 0xac, 0xa5, 0x5f, 0xa3, 0x07, 0xad, 0xfd, 0x8b, 0x56, 0x2b,
+  0xbb, 0x30, 0x10, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37,
+  0x15, 0x01, 0x04, 0x03, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82,
+  0x01, 0x01, 0x00, 0x6c, 0x1b, 0xf2, 0x9b, 0xa7, 0x29, 0xc3, 0x7c, 0x90,
+  0xf0, 0xd2, 0x88, 0xc1, 0x5a, 0xdf, 0xea, 0x1d, 0x48, 0xeb, 0xe5, 0x83,
+  0x64, 0x31, 0xb4, 0x61, 0xa8, 0x3c, 0xfe, 0x1b, 0xf9, 0x0e, 0xc1, 0xdd,
+  0xd2, 0x81, 0xcb, 0x57, 0xcf, 0x12, 0xe0, 0x97, 0xee, 0xfe, 0x7c, 0x9e,
+  0x4d, 0xf2, 0x53, 0x68, 0x30, 0xab, 0xa7, 0x6b, 0xcd, 0xac, 0xef, 0x98,
+  0x93, 0x6e, 0x96, 0x93, 0x49, 0x0d, 0x51, 0x61, 0xb2, 0x85, 0x71, 0x7e,
+  0x3d, 0x3d, 0x90, 0x4d, 0xd6, 0x46, 0x85, 0xf8, 0x67, 0x8c, 0x53, 0x10,
+  0x0c, 0x36, 0xd4, 0xe9, 0xfb, 0x29, 0x19, 0x27, 0xfb, 0xcd, 0x87, 0xd3,
+  0x2b, 0xd3, 0xfd, 0x2e, 0xac, 0xf9, 0xeb, 0x1d, 0x82, 0xa7, 0x4f, 0x22,
+  0xba, 0x73, 0x22, 0x26, 0x64, 0x73, 0x5c, 0xaa, 0x44, 0x23, 0x9e, 0x5d,
+  0xb6, 0xd0, 0x79, 0xd8, 0x7f, 0x2e, 0xd6, 0xdb, 0x73, 0x3a, 0x09, 0xdf,
+  0x44, 0xff, 0xba, 0xa6, 0xcc, 0xcc, 0x61, 0x76, 0x8c, 0x18, 0x8c, 0x89,
+  0xa9, 0x10, 0xab, 0xda, 0x21, 0x22, 0xfb, 0x3f, 0x65, 0x0b, 0xa9, 0xd3,
+  0x0a, 0x70, 0x85, 0x8a, 0x81, 0xb7, 0x60, 0x9a, 0x6d, 0x3a, 0x42, 0xfa,
+  0xc8, 0x0b, 0x58, 0x8d, 0x47, 0x34, 0x78, 0x51, 0x66, 0xc3, 0x11, 0xa6,
+  0x22, 0x99, 0x2b, 0x64, 0x64, 0xda, 0xe3, 0xa1, 0x46, 0x81, 0xb7, 0x52,
+  0xdc, 0xd0, 0x17, 0x19, 0xf1, 0xae, 0xe0, 0x05, 0x92, 0x07, 0x92, 0x98,
+  0x0f, 0x2a, 0xf7, 0x1d, 0xe2, 0x42, 0x7f, 0x97, 0xd1, 0xea, 0x27, 0x8e,
+  0x65, 0xef, 0x00, 0x0b, 0xce, 0xbb, 0xd7, 0xa7, 0x7d, 0xf9, 0x31, 0x92,
+  0x44, 0x1c, 0x9e, 0x84, 0xc6, 0x8f, 0xed, 0x37, 0x51, 0x79, 0xaa, 0x7b,
+  0x9a, 0x9d, 0xac, 0xe2, 0xa0, 0xae, 0x4d, 0xf0, 0x91, 0x83, 0x5d, 0x85,
+  0xca, 0xfa, 0xea, 0x26, 0x0b, 0x48, 0x16, 0x30, 0x82, 0x05, 0xfc, 0x30,
+  0x82, 0x04, 0xe4, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0a, 0x1e, 0x30,
+  0xc3, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
+  0x40, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+  0x44, 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+  0x09, 0x42, 0x4d, 0x57, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x31, 0x1d,
+  0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x42, 0x4d, 0x57,
+  0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
+  0x43, 0x41, 0x20, 0x56, 0x32, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, 0x31,
+  0x32, 0x31, 0x37, 0x30, 0x39, 0x31, 0x37, 0x31, 0x39, 0x5a, 0x17, 0x0d,
+  0x32, 0x32, 0x31, 0x32, 0x31, 0x37, 0x30, 0x39, 0x32, 0x37, 0x31, 0x39,
+  0x5a, 0x30, 0x64, 0x31, 0x14, 0x30, 0x12, 0x06, 0x0a, 0x09, 0x92, 0x26,
+  0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x04, 0x63, 0x6f, 0x72,
+  0x70, 0x31, 0x13, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
+  0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x62, 0x6d, 0x77, 0x31, 0x16,
+  0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64,
+  0x01, 0x19, 0x16, 0x06, 0x65, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x31, 0x1f,
+  0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x42, 0x4d, 0x57,
+  0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x49, 0x73, 0x73, 0x75, 0x69,
+  0x6e, 0x67, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30,
+  0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
+  0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02,
+  0x82, 0x01, 0x01, 0x00, 0xb3, 0xab, 0xd3, 0x53, 0x73, 0x45, 0x6c, 0x37,
+  0xc4, 0x79, 0x7c, 0xe9, 0xfb, 0x0d, 0x6b, 0xb5, 0x9d, 0xcc, 0x95, 0xa5,
+  0xf7, 0x02, 0x04, 0x94, 0x8a, 0x2f, 0xb2, 0xea, 0x9f, 0x27, 0xe4, 0xef,
+  0x95, 0x02, 0x2f, 0x8c, 0x2f, 0x23, 0x4a, 0xd9, 0x53, 0xc8, 0x81, 0xb7,
+  0xe9, 0xb8, 0xb1, 0x52, 0x5c, 0x02, 0x7a, 0x2b, 0x4c, 0xe1, 0xeb, 0x25,
+  0xa4, 0x8b, 0x53, 0xa4, 0x45, 0x74, 0xbb, 0x20, 0xa6, 0x2e, 0x8b, 0x5b,
+  0xf0, 0x05, 0x86, 0x06, 0x79, 0x24, 0x55, 0x27, 0x10, 0x71, 0x9b, 0xf7,
+  0xac, 0x71, 0x8c, 0xa0, 0x4c, 0xe7, 0x9f, 0x1a, 0xb4, 0xa2, 0xd7, 0x5b,
+  0x17, 0xa3, 0x9f, 0xb3, 0x5b, 0x28, 0x16, 0xbe, 0x28, 0x48, 0x58, 0x6f,
+  0x19, 0x7e, 0x7c, 0x7b, 0x0d, 0x69, 0x59, 0xa1, 0x97, 0x13, 0x1a, 0x1f,
+  0x9c, 0xf3, 0x47, 0x36, 0xf2, 0xfa, 0xda, 0xad, 0xbd, 0xd2, 0xda, 0xdd,
+  0xb9, 0xcb, 0x9e, 0xef, 0xe4, 0x63, 0x1e, 0xdb, 0xf6, 0xd6, 0x4c, 0x85,
+  0xf1, 0x7f, 0x04, 0xe4, 0xf7, 0x07, 0xc4, 0x6e, 0x77, 0x36, 0xd7, 0x4e,
+  0x62, 0xb9, 0x71, 0x5b, 0x46, 0x58, 0x99, 0x81, 0xa9, 0x71, 0x43, 0x36,
+  0x4b, 0x06, 0xc2, 0x9c, 0xd9, 0x91, 0xb5, 0x5c, 0xcf, 0x95, 0x94, 0xa1,
+  0x37, 0x44, 0xce, 0x59, 0xc4, 0x1f, 0x99, 0x1e, 0x2d, 0x18, 0xb8, 0x6a,
+  0xf8, 0x13, 0x0e, 0x71, 0x4b, 0x67, 0xd7, 0x1e, 0xc8, 0x4d, 0x1f, 0x54,
+  0xd6, 0xc5, 0x94, 0x39, 0x52, 0x32, 0xca, 0x47, 0xa2, 0x01, 0x83, 0x03,
+  0x1b, 0xa8, 0xe1, 0xd4, 0x7d, 0x30, 0x1f, 0x20, 0x58, 0xb0, 0xd4, 0x6b,
+  0xeb, 0x13, 0x37, 0x10, 0x98, 0x3f, 0x89, 0x0d, 0x94, 0xa3, 0x24, 0xfd,
+  0xcf, 0x20, 0x79, 0xc2, 0x2e, 0x25, 0xcb, 0x0b, 0x47, 0x25, 0xe5, 0x79,
+  0xbe, 0x4e, 0x92, 0xd7, 0x24, 0xea, 0xc6, 0x1b, 0x02, 0x03, 0x01, 0x00,
+  0x01, 0xa3, 0x82, 0x02, 0xd2, 0x30, 0x82, 0x02, 0xce, 0x30, 0x0f, 0x06,
+  0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01,
+  0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
+  0x14, 0x61, 0x0a, 0xef, 0x1a, 0x3d, 0xfe, 0x9a, 0x68, 0x81, 0xcb, 0xb2,
+  0x62, 0xe5, 0xc0, 0x21, 0x8e, 0xdd, 0xec, 0x61, 0x95, 0x30, 0x0e, 0x06,
+  0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01,
+  0x06, 0x30, 0x10, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37,
+  0x15, 0x01, 0x04, 0x03, 0x02, 0x01, 0x00, 0x30, 0x19, 0x06, 0x09, 0x2b,
+  0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x04, 0x0c, 0x1e, 0x0a,
+  0x00, 0x53, 0x00, 0x75, 0x00, 0x62, 0x00, 0x43, 0x00, 0x41, 0x30, 0x1f,
+  0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x17,
+  0xd0, 0xa6, 0x81, 0xc4, 0xba, 0xb6, 0x59, 0xe8, 0xac, 0xa5, 0x5f, 0xa3,
+  0x07, 0xad, 0xfd, 0x8b, 0x56, 0x2b, 0xbb, 0x30, 0x82, 0x01, 0x1e, 0x06,
+  0x03, 0x55, 0x1d, 0x1f, 0x04, 0x82, 0x01, 0x15, 0x30, 0x82, 0x01, 0x11,
+  0x30, 0x82, 0x01, 0x0d, 0xa0, 0x82, 0x01, 0x09, 0xa0, 0x82, 0x01, 0x05,
+  0x86, 0x81, 0xc1, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x2f, 0x43,
+  0x4e, 0x3d, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75,
+  0x70, 0x25, 0x32, 0x30, 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43,
+  0x41, 0x25, 0x32, 0x30, 0x56, 0x32, 0x2c, 0x43, 0x4e, 0x3d, 0x73, 0x6d,
+  0x75, 0x63, 0x31, 0x38, 0x39, 0x32, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x44,
+  0x50, 0x2c, 0x43, 0x4e, 0x3d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25,
+  0x32, 0x30, 0x4b, 0x65, 0x79, 0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76,
+  0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76,
+  0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66,
+  0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43,
+  0x3d, 0x62, 0x6d, 0x77, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, 0x72, 0x70,
+  0x3f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65,
+  0x52, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69,
+  0x73, 0x74, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65,
+  0x63, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x52, 0x4c, 0x44,
+  0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50,
+  0x6f, 0x69, 0x6e, 0x74, 0x86, 0x3f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+  0x2f, 0x73, 0x73, 0x6c, 0x63, 0x72, 0x6c, 0x2e, 0x62, 0x6d, 0x77, 0x67,
+  0x72, 0x6f, 0x75, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69,
+  0x2f, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70,
+  0x25, 0x32, 0x30, 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43, 0x41,
+  0x25, 0x32, 0x30, 0x56, 0x32, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x82, 0x01,
+  0x1a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
+  0x82, 0x01, 0x0c, 0x30, 0x82, 0x01, 0x08, 0x30, 0x81, 0xb8, 0x06, 0x08,
+  0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x81, 0xab, 0x6c,
+  0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x2f, 0x43, 0x4e, 0x3d, 0x42, 0x4d,
+  0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x25, 0x32, 0x30,
+  0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30,
+  0x56, 0x32, 0x2c, 0x43, 0x4e, 0x3d, 0x41, 0x49, 0x41, 0x2c, 0x43, 0x4e,
+  0x3d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30, 0x4b, 0x65,
+  0x79, 0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73,
+  0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73,
+  0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72,
+  0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x62, 0x6d, 0x77,
+  0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, 0x72, 0x70, 0x3f, 0x63, 0x41, 0x43,
+  0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x3f, 0x62,
+  0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6c,
+  0x61, 0x73, 0x73, 0x3d, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+  0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
+  0x74, 0x79, 0x30, 0x4b, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+  0x30, 0x02, 0x86, 0x3f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73,
+  0x73, 0x6c, 0x63, 0x72, 0x6c, 0x2e, 0x62, 0x6d, 0x77, 0x67, 0x72, 0x6f,
+  0x75, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x42,
+  0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x25, 0x32,
+  0x30, 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32,
+  0x30, 0x56, 0x32, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82,
+  0x01, 0x01, 0x00, 0x68, 0x8c, 0xe9, 0xec, 0x52, 0x47, 0xe5, 0x9a, 0xac,
+  0x02, 0x1e, 0x1f, 0x49, 0x12, 0x24, 0x4a, 0xd6, 0x76, 0x41, 0xa7, 0xe6,
+  0x32, 0xf5, 0xc3, 0x96, 0xad, 0x22, 0x34, 0xd6, 0xf7, 0xce, 0xcc, 0xf5,
+  0x20, 0xcf, 0xf9, 0x81, 0x55, 0xff, 0x7a, 0xfb, 0x77, 0xe0, 0x5e, 0x37,
+  0x56, 0x55, 0x17, 0xd7, 0x1a, 0x09, 0x52, 0x2c, 0xda, 0x84, 0xed, 0x1e,
+  0xa3, 0xb3, 0x26, 0xfe, 0x93, 0xff, 0x45, 0x6a, 0x87, 0x91, 0xf9, 0x05,
+  0xe3, 0xa6, 0xcf, 0x33, 0xbc, 0xd6, 0x4a, 0x58, 0x70, 0xfa, 0x9e, 0x54,
+  0x7a, 0x79, 0x16, 0xd7, 0xea, 0xd4, 0x04, 0xaf, 0x87, 0x9a, 0x54, 0xe5,
+  0x80, 0x13, 0xfd, 0xdf, 0x83, 0xc4, 0x60, 0x12, 0x33, 0x49, 0x7b, 0x90,
+  0xd7, 0x1e, 0x09, 0x11, 0x4b, 0xd8, 0xbe, 0x06, 0xd4, 0xf0, 0x8e, 0x84,
+  0x06, 0x2a, 0xe3, 0x0b, 0xf4, 0xac, 0x9d, 0x31, 0xa1, 0x9f, 0x03, 0x91,
+  0xbe, 0xf8, 0x93, 0x6d, 0xc1, 0x9d, 0x8f, 0x18, 0xd3, 0xb9, 0x29, 0xaa,
+  0x19, 0x51, 0x15, 0xf7, 0x99, 0x3f, 0x42, 0x69, 0xfd, 0xec, 0xfb, 0xf0,
+  0x8a, 0x3f, 0x35, 0x65, 0x17, 0x1c, 0x52, 0xf4, 0xd1, 0x31, 0xc8, 0x14,
+  0x51, 0x42, 0x1b, 0xb8, 0xea, 0x7c, 0x4f, 0xbf, 0xd5, 0x78, 0x72, 0xdf,
+  0x18, 0x86, 0xc6, 0x2f, 0x2c, 0xb4, 0x45, 0x1b, 0x0b, 0x00, 0x16, 0x0e,
+  0xd6, 0x41, 0xd9, 0x4d, 0xa0, 0x9e, 0xb3, 0x56, 0x8d, 0xf8, 0x6b, 0xa0,
+  0x20, 0x4c, 0x1c, 0x6e, 0x3a, 0x80, 0xec, 0xd7, 0x85, 0x8c, 0xbb, 0xc1,
+  0x51, 0x73, 0x66, 0x47, 0x01, 0x44, 0x9a, 0x87, 0xc9, 0xed, 0x49, 0x04,
+  0xc2, 0x41, 0xea, 0x65, 0x16, 0xda, 0xd0, 0xb7, 0xe6, 0x03, 0x73, 0x74,
+  0x11, 0x3b, 0x94, 0x1b, 0x9f, 0x06, 0xb9, 0x71, 0x02, 0x70, 0x66, 0xa0,
+  0x12, 0xb5, 0x5a, 0xe8, 0x2c, 0xf9, 0x63, 0x31, 0x00
+};
+static unsigned int bmw_scep_pkt_len = 5661;
+
+#include "si-63-scep/getcacert-mdes.h"
+#include "si-63-scep/getcacert-mdesqa.h"
+
+#include <fcntl.h>
+static inline void write_data(const char * path, CFDataRef data)
+{
+    int data_file = open(path, O_CREAT|O_WRONLY|O_TRUNC, 0644);
+    write(data_file, CFDataGetBytePtr(data), CFDataGetLength(data));
+    close(data_file);
+}
+
+static inline CFMutableArrayRef maa(CFMutableArrayRef array, CFTypeRef a) {
+       CFMutableArrayRef ma = array;
+       if (!ma)
+               CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+       if (ma) {
+               CFArrayAppendValue(ma, a);
+               CFRelease(a);
+       }
+       return ma;
+}
+
+
+/* Test basic add delete update copy matching stuff. */
+static void tests(void)
+{
+       CFDataRef getcacert_blob = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
+               getcacert, getcacert_len, kCFAllocatorNull);
+       CFArrayRef certificates = NULL;
+       SecCertificateRef ca_certificate, ra_signing_certificate, ra_encryption_certificate;
+       ca_certificate = ra_signing_certificate = ra_encryption_certificate = NULL;
+       certificates = SecCMSCertificatesOnlyMessageCopyCertificates(getcacert_blob);
+       isnt(certificates, NULL, "decode cert-only pkcs#7");
+       CFDataRef sha1_fingerprint = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
+               ruby_sha1_hash, sizeof(ruby_sha1_hash), kCFAllocatorNull);
+
+       ok_status(SecSCEPValidateCACertMessage(certificates, sha1_fingerprint,
+               &ca_certificate, &ra_signing_certificate, &ra_encryption_certificate),
+                         "parse CA/RAse getcacert message");
+       CFReleaseNull(sha1_fingerprint);
+       isnt(ca_certificate, NULL, "got ca cert");
+       isnt(ra_signing_certificate, NULL, "got ra signing cert");
+       is(ra_encryption_certificate, NULL, "no separate ra encryption cert");
+
+       /* these are always going to be true, but ensure replacement payloads are equivalent */
+       ok(SecCertificateIsSelfSignedCA(ca_certificate), "self-signed ca cert");
+       ok(SecCertificateGetKeyUsage(ra_signing_certificate) & kSecKeyUsageDigitalSignature, "can sign");
+
+       CFReleaseNull(ca_certificate);
+       CFReleaseNull(ra_signing_certificate);
+       CFReleaseNull(ra_encryption_certificate);
+       CFReleaseNull(getcacert_blob);
+       CFReleaseNull(certificates);
+
+    ca_certificate = ra_signing_certificate = ra_encryption_certificate = NULL;
+       getcacert_blob = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, getcacert_mdes, getcacert_mdes_len, kCFAllocatorNull);
+       certificates = SecCMSCertificatesOnlyMessageCopyCertificates(getcacert_blob);
+    ok_status(SecSCEPValidateCACertMessage(certificates, NULL, &ca_certificate, &ra_signing_certificate, &ra_encryption_certificate), "parse WF MDES getcacert message");
+    ok(ca_certificate && ra_signing_certificate && ra_encryption_certificate, "identify all 3 certs");
+
+    CFReleaseNull(ca_certificate);
+       CFReleaseNull(ra_signing_certificate);
+       CFReleaseNull(ra_encryption_certificate);
+       CFReleaseNull(getcacert_blob);
+       CFReleaseNull(certificates);
+
+    ca_certificate = ra_signing_certificate = ra_encryption_certificate = NULL;
+    getcacert_blob = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, getcacert_mdesqa, getcacert_mdesqa_len, kCFAllocatorNull);
+       certificates = SecCMSCertificatesOnlyMessageCopyCertificates(getcacert_blob);
+    ok_status(SecSCEPValidateCACertMessage(certificates, NULL, &ca_certificate, &ra_signing_certificate, &ra_encryption_certificate), "parse WF MDESQA getcacert message");
+    ok(ca_certificate && ra_signing_certificate && ra_encryption_certificate, "identify all 3 certs");
+
+    CFReleaseNull(ca_certificate);
+       CFReleaseNull(ra_signing_certificate);
+       CFReleaseNull(ra_encryption_certificate);
+       CFReleaseNull(getcacert_blob);
+       CFReleaseNull(certificates);
+
+       sha1_fingerprint = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
+               msscep_md5_hash, sizeof(msscep_md5_hash), kCFAllocatorNull);
+       CFDataRef msscep_getcacert_blob = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
+               msscep_getcacert, msscep_getcacert_len, kCFAllocatorNull);
+       CFReleaseNull(sha1_fingerprint);
+       ca_certificate = ra_signing_certificate = ra_encryption_certificate = NULL;
+       certificates = SecCMSCertificatesOnlyMessageCopyCertificates(msscep_getcacert_blob);
+       ok_status(SecSCEPValidateCACertMessage(certificates, sha1_fingerprint,
+               &ca_certificate, &ra_signing_certificate, &ra_encryption_certificate),
+                         "parse CA/RAs/RAe msscep getcacert message");
+       isnt(ca_certificate, NULL, "got ca cert");
+       isnt(ra_signing_certificate, NULL, "got ra signing cert");
+       isnt(ra_encryption_certificate, NULL, "got ra encryption cert");
+
+       /* these are always going to be true, but ensure replacement payloads are equivalent */
+       ok(SecCertificateIsSelfSignedCA(ca_certificate), "self-signed ca cert");
+       ok(SecCertificateGetKeyUsage(ra_encryption_certificate) & kSecKeyUsageKeyEncipherment, "can sign");
+
+       /*
+       int ix;
+       uint8_t md5_hash[CC_MD5_DIGEST_LENGTH];
+       CFDataRef cert_data = SecCertificateCopyData(ca_certificate);
+       CC_MD5(CFDataGetBytePtr(cert_data), CFDataGetLength(cert_data), md5_hash);
+       for(ix = 0; ix < CC_MD5_DIGEST_LENGTH; ix++) fprintf(stdout, "0x%.02x, ", md5_hash[ix]); fprintf(stdout, "\n");
+       uint8_t sha1_hash[CC_SHA1_DIGEST_LENGTH];
+       CCDigest(kCCDigestSHA1, CFDataGetBytePtr(cert_data), CFDataGetLength(cert_data), sha1_hash);
+       for(ix = 0; ix < CC_SHA1_DIGEST_LENGTH; ix++) fprintf(stdout, "0x%.02x, ", sha1_hash[ix]); fprintf(stdout, "\n");
+       CFRelease(cert_data);
+       */
+
+       CFReleaseNull(ca_certificate);
+       CFReleaseNull(ra_signing_certificate);
+       CFReleaseNull(ra_encryption_certificate);
+       CFRelease(certificates);
+       CFRelease(msscep_getcacert_blob);
+
+
+
+
+       CFDataRef bmw_getcacert_blob = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
+               bmw_scep_pkt, bmw_scep_pkt_len, kCFAllocatorNull);
+       ca_certificate = ra_signing_certificate = ra_encryption_certificate = NULL;
+       certificates = SecCMSCertificatesOnlyMessageCopyCertificates(bmw_getcacert_blob);
+    CFMutableArrayRef certificates_mod = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, certificates);
+    CFArrayRemoveValueAtIndex(certificates_mod, 2);
+       ok_status(SecSCEPValidateCACertMessage(certificates_mod, NULL,
+               &ca_certificate, &ra_signing_certificate, &ra_encryption_certificate),
+                         "parse CA/RAs/RAe msscep getcacert message");
+    CFRelease(certificates_mod);
+       CFRelease(ca_certificate);
+       CFRelease(ra_signing_certificate);
+       CFRelease(ra_encryption_certificate);
+    certificates_mod = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, certificates);
+    CFArrayInsertValueAtIndex(certificates_mod, 0, CFArrayGetValueAtIndex(certificates_mod, 3));
+    CFArrayRemoveValueAtIndex(certificates_mod, 4);
+       ok_status(SecSCEPValidateCACertMessage(certificates_mod, NULL,
+               &ca_certificate, &ra_signing_certificate, &ra_encryption_certificate),
+                         "parse CA/RAs/RAe msscep getcacert message");
+    CFRelease(certificates_mod);
+       CFRelease(ca_certificate);
+       CFRelease(ra_signing_certificate);
+       CFRelease(ra_encryption_certificate);
+
+       ok_status(SecSCEPValidateCACertMessage(certificates, NULL,
+               &ca_certificate, &ra_signing_certificate, &ra_encryption_certificate),
+                         "parse CA/RAs/RAe msscep getcacert message");
+       isnt(ca_certificate, NULL, "got ca cert");
+       isnt(ra_signing_certificate, NULL, "got ra signing cert");
+       isnt(ra_encryption_certificate, NULL, "got ra encryption cert");
+
+       /* these are always going to be true, but ensure replacement payloads are equivalent */
+       ok(SecCertificateIsSelfSignedCA(ca_certificate), "self-signed ca cert");
+       ok(SecCertificateGetKeyUsage(ra_encryption_certificate) & kSecKeyUsageKeyEncipherment, "can sign");
+
+       CFReleaseSafe(ca_certificate);
+       CFReleaseSafe(ra_signing_certificate);
+       CFReleaseSafe(ra_encryption_certificate);
+       CFReleaseSafe(certificates);
+       CFReleaseSafe(bmw_getcacert_blob);
+
+       uint32_t key_size_in_bits = 512;
+       CFNumberRef key_size = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &key_size_in_bits);
+       const void *keygen_keys[] = { kSecAttrKeyType, kSecAttrKeySizeInBits };
+       const void *keygen_vals[] = { kSecAttrKeyTypeRSA, key_size };
+       CFDictionaryRef parameters = CFDictionaryCreate(kCFAllocatorDefault,
+               keygen_keys, keygen_vals, array_size(keygen_vals),
+               &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+       CFRelease(key_size);
+
+       SecKeyRef ca_publicKey = NULL, ca_privateKey = NULL;
+       ok_status(SecKeyGeneratePair(parameters, &ca_publicKey, &ca_privateKey), "gen key");
+       SecIdentityRef ca_identity = test_cert_create_root_certificate(CFSTR("O=Foo Bar Inc.,CN=Root CA"), ca_publicKey, ca_privateKey);
+    CFRelease(ca_publicKey);
+    CFRelease(ca_privateKey);
+
+    SecKeyRef scep_ra_publicKey = NULL, scep_ra_privateKey = NULL;
+    ok_status(SecKeyGeneratePair(parameters, &scep_ra_publicKey, &scep_ra_privateKey), "generate ra key pair");
+       SecCertificateRef scep_ra_certificate =
+               test_cert_issue_certificate(ca_identity, scep_ra_publicKey,
+               CFSTR("O=Foo Bar Inc.,CN=SCEP RA"), 42,
+               kSecKeyUsageKeyEncipherment|kSecKeyUsageDigitalSignature);
+       ok(scep_ra_certificate, "got a ra cert");
+       SecIdentityRef ra_identity = SecIdentityCreate(kCFAllocatorDefault, scep_ra_certificate, scep_ra_privateKey);
+    CFRelease(scep_ra_publicKey);
+    CFRelease(scep_ra_privateKey);
+
+       // store encryption identity in the keychain because the decrypt function looks in there only
+    CFDictionaryRef identity_add = CFDictionaryCreate(NULL,
+        &kSecValueRef, (const void **)&ra_identity, 1, NULL, NULL);
+       ok_status(SecItemAdd(identity_add, NULL), "add encryption identity to keychain");
+
+    SecKeyRef phone_publicKey = NULL, phone_privateKey = NULL;
+    ok_status(SecKeyGeneratePair(parameters, &phone_publicKey, &phone_privateKey), "generate phone key pair");
+       CFArrayRef subject = test_cert_string_to_subject(CFSTR("O=Foo Bar Inc.,CN=Shoes"));
+       SecIdentityRef self_signed_identity = SecSCEPCreateTemporaryIdentity(phone_publicKey, phone_privateKey);
+       CFStringRef magic = CFSTR("magic");
+       CFDictionaryRef csr_params = CFDictionaryCreate(kCFAllocatorDefault,
+               &kSecCSRChallengePassword, (const void **)&magic, 1, NULL, NULL);
+       CFDataRef request = SecSCEPGenerateCertificateRequest(NULL, csr_params, phone_publicKey, phone_privateKey, self_signed_identity, scep_ra_certificate);
+       CFRelease(csr_params);
+    CFRelease(phone_publicKey);
+    CFRelease(phone_privateKey);
+       isnt(request, NULL, "got a request");
+       CFDataRef serialno = CFDataCreate(kCFAllocatorDefault, (uint8_t*)"\001", 1);
+       CFDataRef pended_request = SecSCEPCertifyRequest(request, ra_identity, serialno, true);
+    CFRelease(serialno);
+       isnt(pended_request, NULL, "got a pended request (not failed)");
+       CFErrorRef server_error = NULL;
+       CFArrayRef issued_certs = NULL;
+       issued_certs = SecSCEPVerifyReply(request, pended_request, scep_ra_certificate, &server_error);
+    CFReleaseSafe(request);
+       is(issued_certs, NULL, "no certs if pended");
+       CFDataRef retry_get_cert_initial = NULL;
+    isnt(server_error, NULL, "Should have gotten PENDING error");
+       CFDictionaryRef error_dict = CFErrorCopyUserInfo(server_error);
+       retry_get_cert_initial = SecSCEPGetCertInitial(scep_ra_certificate, subject, NULL, error_dict, self_signed_identity, scep_ra_certificate);
+       isnt(retry_get_cert_initial, NULL, "got retry request");
+       //write_data("/var/tmp/get_cert_initial", retry_get_cert_initial);
+    CFRelease(subject);
+
+    ok_status(SecItemDelete(identity_add), "delete encryption identity from keychain");
+    CFReleaseSafe(identity_add);
+
+    CFRelease(self_signed_identity);
+       CFRelease(retry_get_cert_initial);
+       CFRelease(server_error);
+}
+
+int si_63_scep(int argc, char *const *argv)
+{
+       plan_tests(36);
+
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-63-scep.h b/sec/Security/Regressions/secitem/si-63-scep.h
new file mode 100644 (file)
index 0000000..a1814cf
--- /dev/null
@@ -0,0 +1,991 @@
+
+
+#if 0 // currently unused
+static unsigned char scep_reply_17_58_00_der[] = {
+       0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07,
+       0x02, 0xa0, 0x80, 0x30, 0x80, 0x02, 0x01, 0x01, 0x31, 0x0e, 0x30, 0x0c,
+       0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00,
+       0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07,
+       0x01, 0xa0, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x80, 0x30,
+       0x82, 0x01, 0xe0, 0x02, 0x01, 0x01, 0x30, 0x64, 0x30, 0x50, 0x31, 0x0b,
+       0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x47, 0x42, 0x31,
+       0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x1e, 0x42, 0x72,
+       0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x54, 0x65, 0x6c, 0x65, 0x63, 0x6f,
+       0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+       0x20, 0x70, 0x6c, 0x63, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04,
+       0x03, 0x13, 0x0f, 0x42, 0x54, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x52,
+       0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x02, 0x10, 0x09, 0x85, 0x0a, 0x8d,
+       0xdd, 0xb7, 0xcd, 0x3b, 0x23, 0x39, 0x9e, 0x08, 0x4a, 0x7b, 0x52, 0x4d,
+       0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05,
+       0x05, 0x00, 0xa0, 0x81, 0xd4, 0x30, 0x11, 0x06, 0x0a, 0x60, 0x86, 0x48,
+       0x01, 0x86, 0xf8, 0x45, 0x01, 0x09, 0x02, 0x31, 0x03, 0x13, 0x01, 0x33,
+       0x30, 0x11, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01,
+       0x09, 0x03, 0x31, 0x03, 0x13, 0x01, 0x32, 0x30, 0x15, 0x06, 0x0a, 0x60,
+       0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x09, 0x04, 0x31, 0x07, 0x13,
+       0x05, 0x31, 0x34, 0x36, 0x30, 0x36, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86,
+       0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x03, 0x31, 0x0b, 0x06, 0x09, 0x2a,
+       0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x1f, 0x06, 0x09,
+       0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04, 0x31, 0x12, 0x04,
+       0x10, 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, 0xe9, 0x80, 0x09,
+       0x98, 0xec, 0xf8, 0x42, 0x7e, 0x30, 0x20, 0x06, 0x0a, 0x60, 0x86, 0x48,
+       0x01, 0x86, 0xf8, 0x45, 0x01, 0x09, 0x06, 0x31, 0x12, 0x04, 0x10, 0x0a,
+       0xf3, 0x54, 0x37, 0x3e, 0x13, 0xdc, 0xfa, 0x98, 0xe0, 0xd9, 0xfa, 0x90,
+       0x4a, 0x33, 0xde, 0x30, 0x38, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86,
+       0xf8, 0x45, 0x01, 0x09, 0x07, 0x31, 0x2a, 0x13, 0x28, 0x45, 0x34, 0x35,
+       0x31, 0x35, 0x44, 0x33, 0x33, 0x41, 0x41, 0x46, 0x43, 0x35, 0x41, 0x39,
+       0x45, 0x31, 0x35, 0x37, 0x44, 0x37, 0x46, 0x46, 0x31, 0x35, 0x34, 0x35,
+       0x37, 0x39, 0x44, 0x39, 0x34, 0x35, 0x37, 0x45, 0x30, 0x45, 0x34, 0x31,
+       0x38, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+       0x01, 0x01, 0x05, 0x00, 0x04, 0x81, 0x80, 0x57, 0x03, 0xbf, 0x20, 0x1f,
+       0xb6, 0x37, 0xa4, 0x4a, 0x2c, 0x58, 0x9d, 0x22, 0xfd, 0x64, 0x69, 0x26,
+       0x67, 0xd5, 0xde, 0x62, 0xce, 0x1f, 0x00, 0x1f, 0x21, 0xf5, 0xbd, 0xe1,
+       0x46, 0xca, 0x93, 0x41, 0xc4, 0xc7, 0x4a, 0x5f, 0x82, 0x7b, 0x66, 0x0b,
+       0xbc, 0xb7, 0x8e, 0x2d, 0x01, 0x6e, 0xa0, 0xc6, 0xed, 0xbe, 0xea, 0xc0,
+       0xa1, 0x08, 0x9e, 0xf6, 0x9e, 0xfd, 0x5a, 0xaa, 0xff, 0xa6, 0xb6, 0x2e,
+       0xa1, 0xca, 0xb1, 0x2f, 0x88, 0x11, 0xdd, 0x93, 0x22, 0xef, 0xd4, 0x0e,
+       0xe6, 0x4c, 0x4d, 0xca, 0x5f, 0x4d, 0x02, 0xce, 0x2d, 0x05, 0xaa, 0x13,
+       0xc4, 0x4a, 0xdc, 0xd6, 0xa4, 0xc6, 0xec, 0x6b, 0xad, 0xa3, 0x00, 0xe6,
+       0x67, 0xe7, 0x4d, 0xb6, 0x0a, 0xf4, 0xb0, 0xee, 0xe3, 0xad, 0xba, 0x09,
+       0xa2, 0x59, 0xb5, 0x37, 0x23, 0x57, 0x12, 0x83, 0x7a, 0x38, 0x4b, 0x49,
+       0xb7, 0x18, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+static unsigned int scep_reply_17_58_00_der_len = 551;
+#endif // currently unused
+
+static uint8_t msscep_getcacert[] = {
+       0x30, 0x82, 0x10, 0x8d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+       0x01, 0x07, 0x02, 0xa0, 0x82, 0x10, 0x7e, 0x30, 0x82, 0x10, 0x7a, 0x02,
+       0x01, 0x01, 0x31, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+       0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x10, 0x62, 0x30, 0x82, 0x05,
+       0xcc, 0x30, 0x82, 0x04, 0xb4, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0a,
+       0x61, 0x0c, 0x81, 0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x30, 0x0d,
+       0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
+       0x00, 0x30, 0x4e, 0x31, 0x13, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
+       0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x63, 0x6f, 0x6d,
+       0x31, 0x18, 0x30, 0x16, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2,
+       0x2c, 0x64, 0x01, 0x19, 0x16, 0x08, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65,
+       0x73, 0x74, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+       0x14, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70,
+       0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17,
+       0x0d, 0x30, 0x39, 0x30, 0x32, 0x31, 0x37, 0x32, 0x32, 0x33, 0x35, 0x35,
+       0x35, 0x5a, 0x17, 0x0d, 0x31, 0x31, 0x30, 0x32, 0x31, 0x37, 0x32, 0x32,
+       0x33, 0x35, 0x35, 0x35, 0x5a, 0x30, 0x81, 0x8a, 0x31, 0x0b, 0x30, 0x09,
+       0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30,
+       0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x63, 0x61, 0x31, 0x12,
+       0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x63, 0x75, 0x70,
+       0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
+       0x55, 0x04, 0x0a, 0x13, 0x08, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73,
+       0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x02,
+       0x71, 0x61, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+       0x0c, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f,
+       0x6d, 0x31, 0x23, 0x30, 0x21, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+       0x0d, 0x01, 0x09, 0x01, 0x16, 0x14, 0x71, 0x61, 0x61, 0x64, 0x6d, 0x69,
+       0x6e, 0x40, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63,
+       0x6f, 0x6d, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+       0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00,
+       0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0x93, 0x67, 0x34, 0x15, 0xe9,
+       0x97, 0x97, 0x74, 0xbf, 0x0e, 0x1c, 0xd8, 0x44, 0x00, 0x0d, 0x42, 0x7a,
+       0x3d, 0xd1, 0xea, 0xc8, 0x95, 0xc0, 0x6b, 0x93, 0x6c, 0x6d, 0x87, 0x4a,
+       0x21, 0xf5, 0xbf, 0x16, 0x10, 0x19, 0x44, 0x2f, 0xd2, 0xd6, 0x87, 0x55,
+       0x52, 0x04, 0xb0, 0x0b, 0x3e, 0x49, 0xb7, 0x9c, 0x2b, 0x01, 0xc8, 0x6c,
+       0x3e, 0x56, 0xb5, 0xd2, 0x20, 0x29, 0x0f, 0x25, 0x04, 0xcb, 0x59, 0xce,
+       0x37, 0x69, 0xcf, 0x4e, 0x05, 0x06, 0x2d, 0xac, 0xaf, 0x33, 0xee, 0x4e,
+       0xce, 0xe1, 0x55, 0x46, 0xc6, 0x5c, 0x68, 0x56, 0xda, 0xd6, 0x0a, 0x6e,
+       0xeb, 0xdb, 0x4d, 0xf6, 0xef, 0x0d, 0xcf, 0x1e, 0x43, 0xfa, 0xc2, 0xe2,
+       0xfa, 0x87, 0xe0, 0x31, 0x16, 0x46, 0x97, 0x12, 0x26, 0xdc, 0x94, 0x16,
+       0x73, 0xb0, 0xcf, 0xad, 0x7d, 0x7d, 0x8b, 0xb8, 0xf5, 0xd1, 0x89, 0x50,
+       0x12, 0x1d, 0x49, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x02, 0xf1,
+       0x30, 0x82, 0x02, 0xed, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04,
+       0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x15, 0x06, 0x03, 0x55, 0x1d, 0x25,
+       0x04, 0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82,
+       0x37, 0x14, 0x02, 0x01, 0x30, 0x3b, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04,
+       0x01, 0x82, 0x37, 0x14, 0x02, 0x04, 0x2e, 0x1e, 0x2c, 0x00, 0x45, 0x00,
+       0x6e, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6d, 0x00,
+       0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x41, 0x00, 0x67, 0x00, 0x65, 0x00,
+       0x6e, 0x00, 0x74, 0x00, 0x4f, 0x00, 0x66, 0x00, 0x66, 0x00, 0x6c, 0x00,
+       0x69, 0x00, 0x6e, 0x00, 0x65, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
+       0x04, 0x16, 0x04, 0x14, 0xb3, 0xd0, 0xef, 0xb6, 0xe0, 0x3b, 0x3b, 0x39,
+       0xf8, 0x5a, 0x33, 0x07, 0x2f, 0x19, 0xd9, 0xcd, 0xdd, 0xe3, 0xf9, 0x1e,
+       0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80,
+       0x14, 0x40, 0xb5, 0x54, 0x10, 0x88, 0x09, 0xeb, 0x3e, 0x2e, 0x69, 0x82,
+       0xa6, 0xa0, 0xd8, 0xe4, 0xb0, 0x98, 0xc1, 0x69, 0x3d, 0x30, 0x82, 0x01,
+       0x19, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x82, 0x01, 0x10, 0x30, 0x82,
+       0x01, 0x0c, 0x30, 0x82, 0x01, 0x08, 0xa0, 0x82, 0x01, 0x04, 0xa0, 0x82,
+       0x01, 0x00, 0x86, 0x81, 0xbc, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f,
+       0x2f, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e,
+       0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
+       0x2c, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2c,
+       0x43, 0x4e, 0x3d, 0x43, 0x44, 0x50, 0x2c, 0x43, 0x4e, 0x3d, 0x50, 0x75,
+       0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30, 0x4b, 0x65, 0x79, 0x25, 0x32,
+       0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e,
+       0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e,
+       0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69,
+       0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65,
+       0x73, 0x74, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, 0x6d, 0x3f, 0x63, 0x65,
+       0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x76,
+       0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x3f,
+       0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43,
+       0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x52, 0x4c, 0x44, 0x69, 0x73, 0x74,
+       0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x69, 0x6e,
+       0x74, 0x86, 0x3f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x71, 0x61,
+       0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65,
+       0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x65, 0x72, 0x74, 0x45,
+       0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31,
+       0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63,
+       0x6f, 0x6d, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x82, 0x01, 0x2b, 0x06, 0x08,
+       0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x82, 0x01, 0x1d,
+       0x30, 0x82, 0x01, 0x19, 0x30, 0x81, 0xb4, 0x06, 0x08, 0x2b, 0x06, 0x01,
+       0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x81, 0xa7, 0x6c, 0x64, 0x61, 0x70,
+       0x3a, 0x2f, 0x2f, 0x2f, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72, 0x76,
+       0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e,
+       0x63, 0x6f, 0x6d, 0x2c, 0x43, 0x4e, 0x3d, 0x41, 0x49, 0x41, 0x2c, 0x43,
+       0x4e, 0x3d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30, 0x4b,
+       0x65, 0x79, 0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+       0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+       0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75,
+       0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x69, 0x76,
+       0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f,
+       0x6d, 0x3f, 0x63, 0x41, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+       0x61, 0x74, 0x65, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a,
+       0x65, 0x63, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x65, 0x72,
+       0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x75,
+       0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x60, 0x06, 0x08, 0x2b,
+       0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x54, 0x68, 0x74, 0x74,
+       0x70, 0x3a, 0x2f, 0x2f, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e,
+       0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
+       0x2f, 0x43, 0x65, 0x72, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x2f,
+       0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e,
+       0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x5f, 0x71, 0x61, 0x73,
+       0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73,
+       0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x0d, 0x06,
+       0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,
+       0x03, 0x82, 0x01, 0x01, 0x00, 0x7e, 0x74, 0xff, 0x77, 0xd7, 0x2e, 0x43,
+       0x11, 0xcf, 0xef, 0xb3, 0xdd, 0x98, 0xae, 0x9a, 0xa3, 0x13, 0xc3, 0x07,
+       0x37, 0x0e, 0xe5, 0x2c, 0x50, 0xa1, 0x5e, 0xe2, 0xa6, 0x94, 0x45, 0x2a,
+       0x00, 0x9d, 0xee, 0x53, 0x67, 0x10, 0x6b, 0x13, 0xc5, 0xf9, 0x1c, 0x88,
+       0x70, 0x3c, 0x73, 0x5f, 0x98, 0x2b, 0x05, 0x51, 0xf7, 0x67, 0xf6, 0xa6,
+       0x5b, 0xcb, 0xb6, 0x1c, 0xc2, 0x85, 0xef, 0x1e, 0xcd, 0x25, 0x5f, 0xfa,
+       0xba, 0xcd, 0x89, 0xf7, 0x93, 0xfe, 0x9f, 0xd6, 0xdd, 0x2c, 0x4c, 0xd5,
+       0x33, 0xec, 0xd7, 0xef, 0x6e, 0xc8, 0x0b, 0x9b, 0x8b, 0x4e, 0x75, 0x91,
+       0x0b, 0x4e, 0x96, 0x81, 0x4d, 0xee, 0x06, 0x55, 0x41, 0xfc, 0xc5, 0x2a,
+       0xa6, 0x53, 0x97, 0xb6, 0xce, 0x61, 0x22, 0x93, 0xa8, 0x71, 0x04, 0x51,
+       0xa7, 0xa8, 0x87, 0xee, 0x72, 0xb7, 0x0f, 0xa4, 0x5e, 0x6e, 0xc2, 0xcd,
+       0xfa, 0x00, 0xf8, 0x9c, 0xe5, 0xcc, 0x61, 0xce, 0x88, 0xf0, 0x55, 0xb6,
+       0xff, 0xac, 0xdb, 0xeb, 0xe6, 0xcc, 0x89, 0x7e, 0xea, 0x29, 0x7f, 0x9f,
+       0x01, 0x54, 0x8a, 0x65, 0x60, 0x31, 0xe3, 0xaa, 0xa1, 0x68, 0x16, 0x50,
+       0x7e, 0xe1, 0x9b, 0x04, 0x7f, 0xc5, 0x15, 0x77, 0xfe, 0xbd, 0xfa, 0xac,
+       0x92, 0xcb, 0x0a, 0xc2, 0x3a, 0xbc, 0xec, 0x4e, 0xc4, 0x3a, 0x9f, 0x4d,
+       0xdd, 0x2a, 0x03, 0xe3, 0x22, 0xc0, 0x66, 0x5a, 0x5c, 0x7f, 0x4c, 0x8a,
+       0x58, 0x3e, 0x90, 0x79, 0x96, 0x16, 0x1d, 0x6f, 0x53, 0x43, 0x69, 0xfe,
+       0xb6, 0x0a, 0x18, 0x8f, 0xbf, 0xb4, 0xb8, 0x99, 0xc5, 0x09, 0x20, 0x97,
+       0x10, 0x18, 0xde, 0x57, 0x54, 0x24, 0x95, 0xeb, 0xce, 0x99, 0x01, 0xdd,
+       0x42, 0xc0, 0x67, 0x0b, 0x8c, 0xdb, 0x1c, 0x77, 0x86, 0x63, 0x9d, 0x87,
+       0xf6, 0xff, 0xcf, 0xc5, 0x38, 0xff, 0x6e, 0xb6, 0x05, 0x30, 0x82, 0x05,
+       0xf2, 0x30, 0x82, 0x04, 0xda, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0a,
+       0x61, 0x0c, 0x83, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x30, 0x0d,
+       0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
+       0x00, 0x30, 0x4e, 0x31, 0x13, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
+       0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x63, 0x6f, 0x6d,
+       0x31, 0x18, 0x30, 0x16, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2,
+       0x2c, 0x64, 0x01, 0x19, 0x16, 0x08, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65,
+       0x73, 0x74, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+       0x14, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70,
+       0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17,
+       0x0d, 0x30, 0x39, 0x30, 0x32, 0x31, 0x37, 0x32, 0x32, 0x33, 0x35, 0x35,
+       0x36, 0x5a, 0x17, 0x0d, 0x31, 0x31, 0x30, 0x32, 0x31, 0x37, 0x32, 0x32,
+       0x33, 0x35, 0x35, 0x36, 0x5a, 0x30, 0x81, 0x8a, 0x31, 0x0b, 0x30, 0x09,
+       0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30,
+       0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x63, 0x61, 0x31, 0x12,
+       0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x63, 0x75, 0x70,
+       0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
+       0x55, 0x04, 0x0a, 0x13, 0x08, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73,
+       0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x02,
+       0x71, 0x61, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+       0x0c, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f,
+       0x6d, 0x31, 0x23, 0x30, 0x21, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+       0x0d, 0x01, 0x09, 0x01, 0x16, 0x14, 0x71, 0x61, 0x61, 0x64, 0x6d, 0x69,
+       0x6e, 0x40, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63,
+       0x6f, 0x6d, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+       0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00,
+       0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xa6, 0xf2, 0x65, 0xbe, 0xc6,
+       0xb3, 0x53, 0xc2, 0x94, 0x89, 0xef, 0xca, 0x3a, 0x1d, 0x08, 0x64, 0x19,
+       0x96, 0x5c, 0x8d, 0xc3, 0x15, 0x9b, 0xe5, 0x68, 0x86, 0x7d, 0xff, 0xf9,
+       0xa1, 0xa5, 0x7b, 0x85, 0x8c, 0x14, 0x41, 0xf3, 0xe1, 0x6a, 0x17, 0xff,
+       0xaf, 0x01, 0xb0, 0xbb, 0x64, 0x5d, 0xf0, 0xb8, 0x34, 0x10, 0x41, 0x3e,
+       0xee, 0x43, 0x87, 0x47, 0x4a, 0x5e, 0xc2, 0x2c, 0xe8, 0xcb, 0x23, 0x14,
+       0x9d, 0x92, 0xad, 0xe2, 0xaa, 0x53, 0xbd, 0xfa, 0xaf, 0x7a, 0x11, 0x64,
+       0xeb, 0xb2, 0xf2, 0xd6, 0xdb, 0xd2, 0x77, 0xef, 0x74, 0xb2, 0x67, 0x1b,
+       0xc7, 0xa4, 0x2e, 0x97, 0x80, 0x46, 0x92, 0xaf, 0x32, 0x18, 0x90, 0x46,
+       0x57, 0x86, 0x2d, 0x97, 0x4d, 0x11, 0x48, 0xc5, 0x43, 0x23, 0x3e, 0x6b,
+       0x0d, 0x32, 0x3e, 0xd0, 0xba, 0xf0, 0x20, 0x60, 0x0e, 0x02, 0x47, 0xae,
+       0x58, 0xb4, 0x5b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x03, 0x17,
+       0x30, 0x82, 0x03, 0x13, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04,
+       0x04, 0x03, 0x02, 0x05, 0x20, 0x30, 0x36, 0x06, 0x09, 0x2a, 0x86, 0x48,
+       0x86, 0xf7, 0x0d, 0x01, 0x09, 0x0f, 0x04, 0x29, 0x30, 0x27, 0x30, 0x0d,
+       0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x02, 0x02, 0x01,
+       0x38, 0x30, 0x0d, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03,
+       0x04, 0x02, 0x01, 0x38, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
+       0x07, 0x30, 0x15, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0e, 0x30, 0x0c,
+       0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x01,
+       0x30, 0x29, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14,
+       0x02, 0x04, 0x1c, 0x1e, 0x1a, 0x00, 0x43, 0x00, 0x45, 0x00, 0x50, 0x00,
+       0x45, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x72, 0x00, 0x79, 0x00, 0x70, 0x00,
+       0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x30, 0x1d, 0x06, 0x03, 0x55,
+       0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xe0, 0xfc, 0xd6, 0xa7, 0xca, 0xab,
+       0x38, 0x38, 0x6b, 0x79, 0x6f, 0x63, 0xb7, 0xfd, 0xc4, 0xbd, 0xb2, 0xc3,
+       0x68, 0x03, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
+       0x16, 0x80, 0x14, 0x40, 0xb5, 0x54, 0x10, 0x88, 0x09, 0xeb, 0x3e, 0x2e,
+       0x69, 0x82, 0xa6, 0xa0, 0xd8, 0xe4, 0xb0, 0x98, 0xc1, 0x69, 0x3d, 0x30,
+       0x82, 0x01, 0x19, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x82, 0x01, 0x10,
+       0x30, 0x82, 0x01, 0x0c, 0x30, 0x82, 0x01, 0x08, 0xa0, 0x82, 0x01, 0x04,
+       0xa0, 0x82, 0x01, 0x00, 0x86, 0x81, 0xbc, 0x6c, 0x64, 0x61, 0x70, 0x3a,
+       0x2f, 0x2f, 0x2f, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31,
+       0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63,
+       0x6f, 0x6d, 0x2c, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31,
+       0x30, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x44, 0x50, 0x2c, 0x43, 0x4e, 0x3d,
+       0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30, 0x4b, 0x65, 0x79,
+       0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c,
+       0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c,
+       0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61,
+       0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x69, 0x76, 0x70, 0x6e,
+       0x74, 0x65, 0x73, 0x74, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, 0x6d, 0x3f,
+       0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52,
+       0x65, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73,
+       0x74, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65, 0x63,
+       0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x52, 0x4c, 0x44, 0x69,
+       0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f,
+       0x69, 0x6e, 0x74, 0x86, 0x3f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+       0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e,
+       0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x65, 0x72,
+       0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x71, 0x61, 0x73, 0x72,
+       0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74,
+       0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x82, 0x01, 0x2b,
+       0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x82,
+       0x01, 0x1d, 0x30, 0x82, 0x01, 0x19, 0x30, 0x81, 0xb4, 0x06, 0x08, 0x2b,
+       0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x81, 0xa7, 0x6c, 0x64,
+       0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x2f, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73,
+       0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73,
+       0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x43, 0x4e, 0x3d, 0x41, 0x49, 0x41,
+       0x2c, 0x43, 0x4e, 0x3d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32,
+       0x30, 0x4b, 0x65, 0x79, 0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69,
+       0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69,
+       0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+       0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d,
+       0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2c, 0x44, 0x43, 0x3d,
+       0x63, 0x6f, 0x6d, 0x3f, 0x63, 0x41, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+       0x69, 0x63, 0x61, 0x74, 0x65, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f,
+       0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63,
+       0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+       0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x60, 0x06,
+       0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x54, 0x68,
+       0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31,
+       0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63,
+       0x6f, 0x6d, 0x2f, 0x43, 0x65, 0x72, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c,
+       0x6c, 0x2f, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76,
+       0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x5f, 0x71,
+       0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74,
+       0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x72, 0x74, 0x30,
+       0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
+       0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x83, 0x54, 0x4e, 0x01, 0x42,
+       0x95, 0x42, 0xa4, 0x56, 0x78, 0xf6, 0xa9, 0x41, 0xd8, 0xc3, 0xf2, 0xa4,
+       0xdc, 0xa3, 0xb2, 0xaa, 0x72, 0x63, 0x2c, 0xab, 0x14, 0x40, 0x8c, 0xd9,
+       0xdf, 0x61, 0xdf, 0xee, 0x8b, 0x50, 0x3b, 0xc7, 0xe1, 0x6f, 0xe5, 0x98,
+       0x4d, 0xbd, 0x3c, 0x16, 0xc3, 0xcc, 0x3a, 0xb4, 0x11, 0x87, 0xb6, 0x93,
+       0x63, 0xc6, 0x3d, 0xa2, 0xf3, 0x8c, 0xde, 0xc3, 0xcb, 0x44, 0x25, 0x7a,
+       0x75, 0xc8, 0x5c, 0x9f, 0xeb, 0x43, 0xd2, 0xb1, 0x11, 0x8d, 0x9e, 0x29,
+       0x7a, 0xf1, 0x9e, 0x59, 0xb2, 0x8b, 0xfa, 0x31, 0x2e, 0x4c, 0x8f, 0x6a,
+       0x72, 0x0c, 0x42, 0x63, 0xf1, 0xca, 0x76, 0x8e, 0x33, 0x5e, 0x69, 0x9e,
+       0x3b, 0x15, 0xba, 0xfb, 0xf8, 0x0e, 0x9d, 0x1b, 0xb1, 0x52, 0xc9, 0xc3,
+       0x3e, 0x4f, 0xa4, 0x56, 0x1f, 0x71, 0x24, 0x0a, 0x61, 0x25, 0x87, 0x75,
+       0x07, 0xc7, 0xf0, 0x6f, 0xb3, 0xd7, 0xe9, 0x20, 0x7a, 0xc1, 0x98, 0x48,
+       0x25, 0xd0, 0x17, 0x27, 0xed, 0x21, 0xe8, 0x2b, 0xb6, 0xa7, 0xa5, 0x7b,
+       0x53, 0x20, 0x27, 0x3d, 0x5d, 0xbb, 0xcd, 0x61, 0x84, 0xed, 0x66, 0x4c,
+       0xcd, 0x65, 0x6d, 0xe9, 0x2d, 0xf5, 0xe5, 0x63, 0xaf, 0xd0, 0xde, 0xa0,
+       0x89, 0x5b, 0x01, 0x05, 0x05, 0x63, 0x7e, 0x5b, 0xdb, 0xdc, 0x5a, 0xab,
+       0xa5, 0xa4, 0x62, 0x3a, 0xe7, 0xdf, 0xae, 0x55, 0x9b, 0xf8, 0x93, 0x82,
+       0x1b, 0xec, 0x00, 0x27, 0x2e, 0x73, 0x7d, 0xd8, 0xe2, 0xde, 0x76, 0xf3,
+       0x70, 0xbe, 0xc5, 0x12, 0x00, 0x79, 0x62, 0x83, 0x6b, 0x04, 0x23, 0xc9,
+       0x19, 0xa6, 0x23, 0x77, 0x45, 0xd6, 0x14, 0x01, 0xf7, 0x9c, 0x0f, 0x51,
+       0x92, 0x98, 0x5a, 0x2a, 0x57, 0xc9, 0x5a, 0xb4, 0xe3, 0x98, 0x5f, 0x7e,
+       0x07, 0x99, 0x66, 0x20, 0x17, 0x0d, 0x85, 0x2c, 0x3c, 0x98, 0x70, 0x30,
+       0x82, 0x04, 0x98, 0x30, 0x82, 0x03, 0x80, 0xa0, 0x03, 0x02, 0x01, 0x02,
+       0x02, 0x10, 0x7a, 0xdb, 0x4e, 0x56, 0x1a, 0xb8, 0x90, 0xae, 0x46, 0x6f,
+       0x06, 0x74, 0x44, 0x09, 0x68, 0x87, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+       0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x4e, 0x31,
+       0x13, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c,
+       0x64, 0x01, 0x19, 0x16, 0x03, 0x63, 0x6f, 0x6d, 0x31, 0x18, 0x30, 0x16,
+       0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19,
+       0x16, 0x08, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x31, 0x1d,
+       0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x71, 0x61, 0x73,
+       0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73,
+       0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, 0x30,
+       0x31, 0x32, 0x38, 0x30, 0x32, 0x34, 0x33, 0x33, 0x30, 0x5a, 0x17, 0x0d,
+       0x31, 0x34, 0x30, 0x31, 0x32, 0x38, 0x30, 0x32, 0x35, 0x32, 0x34, 0x33,
+       0x5a, 0x30, 0x4e, 0x31, 0x13, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
+       0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x63, 0x6f, 0x6d,
+       0x31, 0x18, 0x30, 0x16, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2,
+       0x2c, 0x64, 0x01, 0x19, 0x16, 0x08, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65,
+       0x73, 0x74, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+       0x14, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70,
+       0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01,
+       0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+       0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01,
+       0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xbe, 0xf8, 0xff, 0x61, 0xca, 0x9d,
+       0xcf, 0x07, 0x4d, 0x06, 0xf4, 0x52, 0x4b, 0x3f, 0x84, 0xc5, 0x0b, 0x71,
+       0xef, 0x7f, 0x7d, 0x35, 0xac, 0x68, 0xce, 0x84, 0xe6, 0x7c, 0x0a, 0xba,
+       0x02, 0x71, 0xcf, 0x81, 0x40, 0xcb, 0x25, 0xdb, 0x41, 0x23, 0x84, 0x88,
+       0x4d, 0x16, 0xa2, 0x41, 0xa5, 0x2a, 0x98, 0xa3, 0xb7, 0x02, 0xff, 0x54,
+       0xb6, 0xd5, 0x55, 0x75, 0x17, 0xbc, 0xd5, 0x04, 0x24, 0x35, 0x63, 0xfa,
+       0xcb, 0x98, 0x38, 0x98, 0x18, 0xd3, 0x13, 0xc1, 0xef, 0x1a, 0xfe, 0xb7,
+       0xcd, 0x2e, 0xc2, 0xb8, 0x0d, 0x3e, 0x62, 0x38, 0xc0, 0x05, 0xf9, 0x5b,
+       0xc5, 0xd5, 0xf6, 0xc4, 0x9d, 0x8e, 0xc3, 0x90, 0x32, 0xa2, 0xb1, 0x88,
+       0xa8, 0xf9, 0xd3, 0x0d, 0x02, 0x8d, 0xbe, 0x8f, 0x41, 0xe7, 0x92, 0x85,
+       0xe7, 0x4c, 0x11, 0x9a, 0x4b, 0xfb, 0x00, 0xa9, 0x9f, 0xf5, 0xfb, 0x23,
+       0xda, 0xf1, 0xfd, 0x95, 0x89, 0xd5, 0x2b, 0xc5, 0xbf, 0x9c, 0xc3, 0x93,
+       0xd0, 0xc2, 0xf8, 0x12, 0xbe, 0x26, 0x24, 0x41, 0x80, 0x64, 0x2f, 0xc0,
+       0x7b, 0x31, 0x85, 0x06, 0x3c, 0xe4, 0xc6, 0x7e, 0xbc, 0x61, 0xa7, 0xa2,
+       0xf4, 0xa7, 0xd7, 0xd7, 0xcb, 0xeb, 0xea, 0xb0, 0xc6, 0xd7, 0x13, 0xd6,
+       0x09, 0xfa, 0x45, 0xc6, 0x25, 0x6f, 0x34, 0xdc, 0x78, 0x70, 0xa0, 0xa5,
+       0xea, 0xd7, 0xe7, 0xda, 0xe2, 0x5a, 0x7a, 0xc3, 0xe3, 0x7a, 0x8d, 0xf3,
+       0x5a, 0x78, 0xfa, 0x57, 0xe1, 0xf1, 0xae, 0x6b, 0xea, 0x83, 0xd0, 0xd7,
+       0xa9, 0x43, 0x2d, 0x5d, 0x8b, 0xac, 0xbb, 0x92, 0x5b, 0x2a, 0xd7, 0x27,
+       0xbe, 0xe7, 0xa0, 0xd2, 0xc5, 0x9b, 0xd7, 0xa4, 0xc1, 0x6a, 0xf8, 0xec,
+       0xfc, 0xa6, 0x96, 0xfc, 0x09, 0x11, 0x95, 0xca, 0x75, 0xab, 0x8a, 0x5b,
+       0xd2, 0xb2, 0xb4, 0x11, 0xf1, 0x88, 0x34, 0xe3, 0xb7, 0x21, 0x02, 0x03,
+       0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x70, 0x30, 0x82, 0x01, 0x6c, 0x30,
+       0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86,
+       0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05,
+       0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
+       0x04, 0x16, 0x04, 0x14, 0x40, 0xb5, 0x54, 0x10, 0x88, 0x09, 0xeb, 0x3e,
+       0x2e, 0x69, 0x82, 0xa6, 0xa0, 0xd8, 0xe4, 0xb0, 0x98, 0xc1, 0x69, 0x3d,
+       0x30, 0x82, 0x01, 0x19, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x82, 0x01,
+       0x10, 0x30, 0x82, 0x01, 0x0c, 0x30, 0x82, 0x01, 0x08, 0xa0, 0x82, 0x01,
+       0x04, 0xa0, 0x82, 0x01, 0x00, 0x86, 0x81, 0xbc, 0x6c, 0x64, 0x61, 0x70,
+       0x3a, 0x2f, 0x2f, 0x2f, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72, 0x76,
+       0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e,
+       0x63, 0x6f, 0x6d, 0x2c, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72, 0x76,
+       0x31, 0x30, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x44, 0x50, 0x2c, 0x43, 0x4e,
+       0x3d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30, 0x4b, 0x65,
+       0x79, 0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73,
+       0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73,
+       0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72,
+       0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x69, 0x76, 0x70,
+       0x6e, 0x74, 0x65, 0x73, 0x74, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, 0x6d,
+       0x3f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65,
+       0x52, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69,
+       0x73, 0x74, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65,
+       0x63, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x52, 0x4c, 0x44,
+       0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50,
+       0x6f, 0x69, 0x6e, 0x74, 0x86, 0x3f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+       0x2f, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70,
+       0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x65,
+       0x72, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x71, 0x61, 0x73,
+       0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73,
+       0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x10, 0x06,
+       0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x01, 0x04, 0x03,
+       0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+       0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x07,
+       0x74, 0x27, 0x8c, 0xdd, 0x75, 0xa1, 0x0d, 0x97, 0xd1, 0x9d, 0x0d, 0xae,
+       0x3b, 0xf3, 0x14, 0x0f, 0xa1, 0x1c, 0x51, 0xd8, 0x68, 0xe7, 0xfd, 0xd0,
+       0xaf, 0xe7, 0x66, 0x62, 0xf8, 0x73, 0x75, 0x88, 0x6c, 0xb9, 0xb3, 0x1e,
+       0xf5, 0x82, 0x3a, 0x1d, 0x82, 0x7b, 0xa3, 0x18, 0xd9, 0x1a, 0x40, 0xf2,
+       0xcd, 0xb3, 0x83, 0xae, 0x12, 0x5b, 0xb4, 0x45, 0xd9, 0xbe, 0x51, 0x3e,
+       0x11, 0x64, 0xaf, 0x95, 0x06, 0xb6, 0xbd, 0xd1, 0xa1, 0xfd, 0xbb, 0xdb,
+       0xa4, 0xbb, 0xba, 0x3e, 0xd5, 0xd6, 0x1d, 0x37, 0x80, 0x17, 0xe8, 0x08,
+       0x75, 0x5f, 0x5d, 0x49, 0x5f, 0x70, 0xdd, 0x67, 0xde, 0x9a, 0x34, 0x95,
+       0x2e, 0x54, 0x58, 0x42, 0xaf, 0x8a, 0x57, 0xf2, 0xb4, 0x1f, 0xfb, 0x40,
+       0x9c, 0x05, 0xa0, 0x6a, 0x9a, 0x91, 0x0e, 0x27, 0xaa, 0x9e, 0xdb, 0xbf,
+       0x50, 0xc9, 0xa4, 0x2f, 0xc8, 0x71, 0x00, 0x11, 0xf8, 0x2f, 0xda, 0x98,
+       0xf4, 0x1d, 0x98, 0x2a, 0xe9, 0x29, 0xc7, 0xea, 0x74, 0x65, 0xf1, 0x6d,
+       0x06, 0x9f, 0x59, 0xa3, 0x50, 0x7e, 0x1b, 0x52, 0x5a, 0xb9, 0x5e, 0xce,
+       0xa0, 0x03, 0x53, 0xe8, 0xba, 0x36, 0x4a, 0xc2, 0x95, 0xdb, 0x34, 0x61,
+       0xc8, 0xf4, 0xa5, 0x7c, 0xd6, 0x9d, 0x64, 0x91, 0xfb, 0x23, 0xfd, 0x8b,
+       0x3a, 0xd2, 0x67, 0xb0, 0x64, 0xa7, 0x80, 0x82, 0x74, 0x85, 0x45, 0xa7,
+       0x78, 0x57, 0xb6, 0xf0, 0x0a, 0xf9, 0xa2, 0xb5, 0x7f, 0x7e, 0x88, 0x21,
+       0xd7, 0x67, 0xd2, 0xc4, 0x9c, 0x98, 0x51, 0x9b, 0x71, 0xfb, 0x39, 0xf2,
+       0xb3, 0xfd, 0x3f, 0x0b, 0x61, 0x59, 0xa0, 0x15, 0x40, 0x53, 0x71, 0xac,
+       0xf5, 0xf7, 0xee, 0x03, 0x6b, 0x1f, 0x5d, 0x29, 0x0a, 0xf7, 0x4f, 0x1a,
+       0xea, 0xa4, 0xb8, 0x02, 0x63, 0x7c, 0x37, 0x37, 0xdd, 0x46, 0x42, 0xe3,
+       0xe1, 0x82, 0x94, 0x31, 0x00
+};
+static unsigned int msscep_getcacert_len = 4241;
+
+
+static uint8_t getcacert[] = {
+       0x30, 0x82, 0x04, 0x6a, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+       0x01, 0x07, 0x02, 0xa0, 0x82, 0x04, 0x5b, 0x30, 0x82, 0x04, 0x57, 0x02,
+       0x01, 0x01, 0x31, 0x00, 0x30, 0x03, 0x06, 0x01, 0x00, 0xa0, 0x82, 0x04,
+       0x47, 0x30, 0x82, 0x02, 0x33, 0x30, 0x82, 0x01, 0x9c, 0xa0, 0x03, 0x02,
+       0x01, 0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+       0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x4d, 0x31, 0x0d,
+       0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x04, 0x4e, 0x6f, 0x6e,
+       0x65, 0x31, 0x3c, 0x30, 0x3a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x33,
+       0x41, 0x43, 0x4d, 0x45, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41,
+       0x20, 0x28, 0x35, 0x36, 0x32, 0x66, 0x30, 0x64, 0x30, 0x35, 0x2d, 0x32,
+       0x35, 0x36, 0x61, 0x2d, 0x34, 0x32, 0x65, 0x65, 0x2d, 0x39, 0x66, 0x35,
+       0x38, 0x2d, 0x38, 0x30, 0x62, 0x30, 0x61, 0x35, 0x35, 0x37, 0x38, 0x62,
+       0x66, 0x30, 0x29, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, 0x30, 0x39, 0x31,
+       0x37, 0x30, 0x30, 0x33, 0x39, 0x32, 0x33, 0x5a, 0x17, 0x0d, 0x31, 0x30,
+       0x30, 0x39, 0x31, 0x37, 0x30, 0x30, 0x33, 0x39, 0x32, 0x33, 0x5a, 0x30,
+       0x4d, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x04,
+       0x4e, 0x6f, 0x6e, 0x65, 0x31, 0x3c, 0x30, 0x3a, 0x06, 0x03, 0x55, 0x04,
+       0x03, 0x0c, 0x33, 0x41, 0x43, 0x4d, 0x45, 0x20, 0x52, 0x6f, 0x6f, 0x74,
+       0x20, 0x43, 0x41, 0x20, 0x28, 0x35, 0x36, 0x32, 0x66, 0x30, 0x64, 0x30,
+       0x35, 0x2d, 0x32, 0x35, 0x36, 0x61, 0x2d, 0x34, 0x32, 0x65, 0x65, 0x2d,
+       0x39, 0x66, 0x35, 0x38, 0x2d, 0x38, 0x30, 0x62, 0x30, 0x61, 0x35, 0x35,
+       0x37, 0x38, 0x62, 0x66, 0x30, 0x29, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06,
+       0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
+       0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xd4,
+       0x1c, 0xaa, 0x58, 0x8a, 0xda, 0xfc, 0x24, 0x21, 0x35, 0xc2, 0xb0, 0x2b,
+       0x08, 0x5d, 0xe2, 0xf5, 0xb5, 0xf0, 0xdc, 0xca, 0x04, 0xaa, 0x8e, 0x86,
+       0xff, 0xfe, 0x9b, 0x35, 0xed, 0x61, 0x3a, 0xe5, 0xbf, 0xf7, 0xbf, 0xab,
+       0xa4, 0xa8, 0x6e, 0xf5, 0xba, 0x5b, 0x0e, 0xdc, 0x28, 0x07, 0x24, 0x01,
+       0xda, 0x9e, 0x1f, 0x92, 0xa5, 0x4b, 0x51, 0xcd, 0xd9, 0x6e, 0x27, 0xfa,
+       0xda, 0x9b, 0x9c, 0x17, 0x3e, 0x1b, 0x36, 0xaf, 0xf5, 0x5d, 0x11, 0x02,
+       0xe9, 0x2e, 0xf1, 0x6e, 0xb6, 0x7f, 0xe8, 0x91, 0xbd, 0x66, 0x73, 0xdf,
+       0xb9, 0x27, 0xb7, 0x5b, 0x04, 0xb1, 0x9f, 0x52, 0x38, 0xea, 0xd0, 0x1c,
+       0x97, 0x2d, 0x4b, 0x1b, 0x03, 0xcb, 0xe6, 0xa4, 0x92, 0x2c, 0x0f, 0x5d,
+       0x34, 0x06, 0x52, 0x07, 0x35, 0x97, 0x13, 0x2f, 0x27, 0x62, 0x5a, 0x4b,
+       0xc3, 0xac, 0x5f, 0x0a, 0x40, 0x98, 0x29, 0x02, 0x03, 0x01, 0x00, 0x01,
+       0xa3, 0x23, 0x30, 0x21, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
+       0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06,
+       0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01,
+       0x86, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+       0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x35, 0xa8, 0x47, 0x69,
+       0x01, 0x12, 0x43, 0x34, 0x73, 0xe4, 0xd8, 0xa4, 0x95, 0x00, 0xea, 0xd7,
+       0x33, 0xf2, 0x7b, 0x49, 0xea, 0xa7, 0xc6, 0xe1, 0x7d, 0x06, 0xb8, 0xb4,
+       0x4f, 0x3f, 0x08, 0x97, 0xa8, 0x47, 0x82, 0x1e, 0x0a, 0x4b, 0xdb, 0x19,
+       0x9d, 0x21, 0x30, 0x2c, 0x37, 0xa0, 0x3f, 0x92, 0xf7, 0xc2, 0x39, 0x57,
+       0x2b, 0x43, 0x33, 0xf9, 0x6e, 0x40, 0x8c, 0x64, 0x2b, 0xf5, 0xb6, 0xb6,
+       0x6c, 0x2e, 0x59, 0xc4, 0xe6, 0x01, 0x87, 0xd4, 0x1c, 0x32, 0xf1, 0x68,
+       0x72, 0xeb, 0xda, 0x35, 0x69, 0x3c, 0x7d, 0x6f, 0x4c, 0xba, 0x8b, 0x4d,
+       0xaa, 0x1c, 0x11, 0x05, 0x76, 0x9e, 0x73, 0x2a, 0x20, 0xcb, 0x31, 0x9c,
+       0x74, 0x20, 0x99, 0x4c, 0xbc, 0x17, 0xd0, 0xb5, 0x6e, 0x1e, 0xad, 0x87,
+       0x83, 0xa6, 0xda, 0x15, 0x85, 0x7a, 0x8f, 0x76, 0x37, 0xa7, 0x11, 0x53,
+       0x7f, 0x12, 0xb1, 0x05, 0x30, 0x82, 0x02, 0x0c, 0x30, 0x82, 0x01, 0x75,
+       0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x64, 0x30, 0x0d, 0x06, 0x09,
+       0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
+       0x4d, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x04,
+       0x4e, 0x6f, 0x6e, 0x65, 0x31, 0x3c, 0x30, 0x3a, 0x06, 0x03, 0x55, 0x04,
+       0x03, 0x0c, 0x33, 0x41, 0x43, 0x4d, 0x45, 0x20, 0x52, 0x6f, 0x6f, 0x74,
+       0x20, 0x43, 0x41, 0x20, 0x28, 0x35, 0x36, 0x32, 0x66, 0x30, 0x64, 0x30,
+       0x35, 0x2d, 0x32, 0x35, 0x36, 0x61, 0x2d, 0x34, 0x32, 0x65, 0x65, 0x2d,
+       0x39, 0x66, 0x35, 0x38, 0x2d, 0x38, 0x30, 0x62, 0x30, 0x61, 0x35, 0x35,
+       0x37, 0x38, 0x62, 0x66, 0x30, 0x29, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39,
+       0x30, 0x39, 0x31, 0x37, 0x30, 0x30, 0x33, 0x39, 0x32, 0x33, 0x5a, 0x17,
+       0x0d, 0x31, 0x30, 0x30, 0x39, 0x31, 0x37, 0x30, 0x30, 0x33, 0x39, 0x32,
+       0x33, 0x5a, 0x30, 0x26, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04,
+       0x0a, 0x0c, 0x04, 0x4e, 0x6f, 0x6e, 0x65, 0x31, 0x15, 0x30, 0x13, 0x06,
+       0x03, 0x55, 0x04, 0x03, 0x0c, 0x0c, 0x41, 0x43, 0x4d, 0x45, 0x20, 0x53,
+       0x43, 0x45, 0x50, 0x20, 0x52, 0x41, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06,
+       0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
+       0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xd1,
+       0x6e, 0x98, 0x93, 0x0e, 0x0a, 0x27, 0x5f, 0xd9, 0x3e, 0x95, 0xe3, 0x24,
+       0xae, 0x96, 0xd2, 0x62, 0x40, 0x05, 0xb6, 0x2d, 0x4d, 0xe2, 0x8f, 0x35,
+       0x26, 0x14, 0x72, 0x04, 0xb0, 0x34, 0xaf, 0xf3, 0x61, 0x7c, 0xa0, 0x72,
+       0xe6, 0x29, 0xf3, 0xdf, 0xc2, 0x2a, 0x8c, 0x84, 0xde, 0xea, 0x7c, 0x01,
+       0x64, 0x08, 0x8c, 0xaa, 0x0b, 0x96, 0x9b, 0xb5, 0xb8, 0x86, 0x49, 0xad,
+       0x68, 0x1d, 0x7c, 0xf0, 0x1a, 0xe9, 0xf6, 0x56, 0x97, 0xe4, 0xb8, 0x20,
+       0xa6, 0x1f, 0x1a, 0x9d, 0xcc, 0x5f, 0xe8, 0xc9, 0x05, 0xab, 0x85, 0xab,
+       0xce, 0x5c, 0xcd, 0x20, 0xb7, 0x01, 0x8d, 0xda, 0x10, 0x54, 0x22, 0xbd,
+       0x93, 0xf9, 0xac, 0x12, 0x39, 0x08, 0x9d, 0x27, 0xa1, 0x92, 0xb6, 0x94,
+       0xde, 0x15, 0xcc, 0x0f, 0x9e, 0x1f, 0xe0, 0x44, 0x90, 0x57, 0x87, 0x04,
+       0x9b, 0xfb, 0xb0, 0x63, 0x9d, 0xc0, 0x4d, 0x02, 0x03, 0x01, 0x00, 0x01,
+       0xa3, 0x23, 0x30, 0x21, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
+       0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06,
+       0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05,
+       0xa0, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+       0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0xbb, 0xb7, 0xa1, 0xd6,
+       0x0c, 0xdd, 0xa8, 0xfe, 0x4a, 0x3b, 0x90, 0x42, 0x9b, 0x4f, 0xfc, 0xa4,
+       0x75, 0xf2, 0x04, 0x09, 0xd6, 0x9e, 0xfb, 0x4f, 0x99, 0xf8, 0xcb, 0x5c,
+       0xcc, 0xb0, 0xb3, 0xce, 0xd7, 0x83, 0xed, 0x4d, 0xa7, 0x93, 0xdb, 0x87,
+       0x7b, 0x09, 0x2f, 0x07, 0xb3, 0xd2, 0xa3, 0x08, 0x17, 0x53, 0xb4, 0x61,
+       0xd7, 0x58, 0x86, 0x79, 0x2c, 0x2e, 0x09, 0x75, 0xda, 0x61, 0xa8, 0x90,
+       0x1f, 0xea, 0x2f, 0x0f, 0x2a, 0xcb, 0xf5, 0x01, 0x54, 0xee, 0x23, 0x80,
+       0xbb, 0xaa, 0xb5, 0x61, 0x66, 0x23, 0xb3, 0xd2, 0xff, 0x7f, 0xb8, 0x74,
+       0xc9, 0x55, 0xb5, 0x84, 0x57, 0x5a, 0x2e, 0x81, 0x0d, 0xe5, 0x0d, 0x45,
+       0x4f, 0x37, 0xc4, 0x2d, 0xec, 0xf8, 0xf1, 0x15, 0x59, 0xc4, 0x7a, 0x49,
+       0xd0, 0x12, 0x16, 0x18, 0x6a, 0x3e, 0x74, 0xe5, 0x4e, 0x65, 0xdc, 0xcc,
+       0xba, 0x9e, 0x77, 0x7c, 0x31, 0x00
+};
+static unsigned int getcacert_len = 1134;
+
+static uint8_t msscep_md5_hash[] = {0x13, 0x7f, 0x4d, 0xaa, 0x5d, 0xa0, 0x65, 0x1b, 0xbd, 0x54, 0x8c, 0xc2, 0xd3, 0xd4, 0xce, 0xd0 };
+static uint8_t ruby_sha1_hash[] = { 0xf3, 0x5f, 0x6b, 0xd1, 0x64, 0x0b, 0xc1, 0x81, 0x98, 0xb9, 0x30, 0xd1, 0x97, 0x10, 0x3b, 0x45, 0xf0, 0x6e, 0x53, 0xdb };
+
+
+static unsigned char bmw_scep_pkt[] = {
+  0x30, 0x82, 0x16, 0x19, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x07, 0x02, 0xa0, 0x82, 0x16, 0x0a, 0x30, 0x82, 0x16, 0x06, 0x02,
+  0x01, 0x01, 0x31, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x15, 0xee, 0x30, 0x82, 0x06,
+  0x26, 0x30, 0x82, 0x05, 0x0e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0a,
+  0x3c, 0xec, 0x7e, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x30, 0x0d,
+  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
+  0x00, 0x30, 0x64, 0x31, 0x14, 0x30, 0x12, 0x06, 0x0a, 0x09, 0x92, 0x26,
+  0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x04, 0x63, 0x6f, 0x72,
+  0x70, 0x31, 0x13, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
+  0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x62, 0x6d, 0x77, 0x31, 0x16,
+  0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64,
+  0x01, 0x19, 0x16, 0x06, 0x65, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x31, 0x1f,
+  0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x42, 0x4d, 0x57,
+  0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x49, 0x73, 0x73, 0x75, 0x69,
+  0x6e, 0x67, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x1e, 0x17, 0x0d, 0x31,
+  0x30, 0x30, 0x33, 0x30, 0x34, 0x31, 0x33, 0x35, 0x33, 0x31, 0x30, 0x5a,
+  0x17, 0x0d, 0x31, 0x32, 0x30, 0x33, 0x30, 0x33, 0x31, 0x33, 0x35, 0x33,
+  0x31, 0x30, 0x5a, 0x30, 0x81, 0x83, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+  0x55, 0x04, 0x06, 0x13, 0x02, 0x44, 0x45, 0x31, 0x10, 0x30, 0x0e, 0x06,
+  0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x42, 0x61, 0x76, 0x61, 0x72, 0x69,
+  0x61, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x06,
+  0x4d, 0x75, 0x6e, 0x69, 0x63, 0x68, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03,
+  0x55, 0x04, 0x0a, 0x13, 0x09, 0x42, 0x4d, 0x57, 0x20, 0x47, 0x72, 0x6f,
+  0x75, 0x70, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+  0x11, 0x53, 0x43, 0x45, 0x50, 0x20, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e,
+  0x67, 0x20, 0x43, 0x41, 0x20, 0x32, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x74,
+  0x72, 0x75, 0x73, 0x74, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x40, 0x62,
+  0x6d, 0x77, 0x2e, 0x64, 0x65, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
+  0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xad, 0x57,
+  0x88, 0x2c, 0x2c, 0xda, 0x45, 0x32, 0x32, 0xb1, 0xba, 0xce, 0x1b, 0x0b,
+  0x5d, 0xc8, 0x5d, 0x76, 0xd2, 0x63, 0xf6, 0xc7, 0xe6, 0x45, 0xff, 0x37,
+  0xf3, 0x85, 0xbf, 0xbb, 0xa1, 0x83, 0xd1, 0xea, 0xe0, 0x3f, 0xc9, 0x05,
+  0x79, 0xe3, 0x15, 0xc3, 0x97, 0x2a, 0x81, 0x38, 0x4f, 0x33, 0xc1, 0xc9,
+  0xf5, 0xb0, 0x1b, 0xbd, 0xad, 0x52, 0x15, 0x80, 0x52, 0x7d, 0x1b, 0x68,
+  0x8f, 0xb5, 0x27, 0xda, 0xcf, 0x20, 0x7d, 0x53, 0x6e, 0xb0, 0xe8, 0x4b,
+  0x8e, 0x6b, 0xb2, 0x63, 0xe3, 0xd5, 0x2c, 0x67, 0x55, 0x73, 0x0f, 0xda,
+  0x41, 0x04, 0x56, 0xdc, 0xb3, 0x9a, 0x6b, 0xbb, 0x62, 0xf8, 0x8f, 0xe2,
+  0x91, 0x7a, 0xe8, 0xa7, 0xa9, 0xc4, 0x8b, 0x75, 0x7b, 0xb5, 0x5f, 0x4e,
+  0xe1, 0x4d, 0x80, 0x4d, 0xc9, 0xee, 0x23, 0xbc, 0xf7, 0x4f, 0x8d, 0xc0,
+  0x02, 0x20, 0x23, 0x82, 0x80, 0xf7, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
+  0x82, 0x03, 0x3c, 0x30, 0x82, 0x03, 0x38, 0x30, 0x0b, 0x06, 0x03, 0x55,
+  0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x15, 0x06, 0x03,
+  0x55, 0x1d, 0x25, 0x04, 0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01,
+  0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x01, 0x30, 0x3b, 0x06, 0x09, 0x2b,
+  0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x04, 0x2e, 0x1e, 0x2c,
+  0x00, 0x45, 0x00, 0x6e, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x6c, 0x00, 0x6c,
+  0x00, 0x6d, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x41, 0x00, 0x67,
+  0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x4f, 0x00, 0x66, 0x00, 0x66,
+  0x00, 0x6c, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x65, 0x30, 0x1d, 0x06, 0x03,
+  0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xd8, 0xeb, 0x70, 0x8b, 0x4e,
+  0xda, 0xfb, 0x52, 0x03, 0x0c, 0xa5, 0xc5, 0xfd, 0xf3, 0x29, 0x54, 0xfd,
+  0x2e, 0x8f, 0x3e, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
+  0x30, 0x16, 0x80, 0x14, 0x61, 0x0a, 0xef, 0x1a, 0x3d, 0xfe, 0x9a, 0x68,
+  0x81, 0xcb, 0xb2, 0x62, 0xe5, 0xc0, 0x21, 0x8e, 0xdd, 0xec, 0x61, 0x95,
+  0x30, 0x82, 0x01, 0x71, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x82, 0x01,
+  0x68, 0x30, 0x82, 0x01, 0x64, 0x30, 0x82, 0x01, 0x60, 0xa0, 0x82, 0x01,
+  0x5c, 0xa0, 0x82, 0x01, 0x58, 0x86, 0x81, 0xc3, 0x6c, 0x64, 0x61, 0x70,
+  0x3a, 0x2f, 0x2f, 0x2f, 0x43, 0x4e, 0x3d, 0x42, 0x4d, 0x57, 0x25, 0x32,
+  0x30, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x25, 0x32, 0x30, 0x49, 0x73, 0x73,
+  0x75, 0x69, 0x6e, 0x67, 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30,
+  0x32, 0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x4d, 0x55, 0x43, 0x31, 0x39, 0x32,
+  0x33, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x44, 0x50, 0x2c, 0x43, 0x4e, 0x3d,
+  0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30, 0x4b, 0x65, 0x79,
+  0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c,
+  0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c,
+  0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61,
+  0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x62, 0x6d, 0x77, 0x2c,
+  0x44, 0x43, 0x3d, 0x63, 0x6f, 0x72, 0x70, 0x3f, 0x63, 0x65, 0x72, 0x74,
+  0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x76, 0x6f, 0x63,
+  0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x3f, 0x62, 0x61,
+  0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x61,
+  0x73, 0x73, 0x3d, 0x63, 0x52, 0x4c, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69,
+  0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x86,
+  0x4d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x6d, 0x75, 0x63,
+  0x31, 0x39, 0x32, 0x33, 0x2e, 0x65, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2e,
+  0x62, 0x6d, 0x77, 0x2e, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x43, 0x65, 0x72,
+  0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x42, 0x4d, 0x57, 0x25,
+  0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x25, 0x32, 0x30, 0x49, 0x73,
+  0x73, 0x75, 0x69, 0x6e, 0x67, 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32,
+  0x30, 0x32, 0x2e, 0x63, 0x72, 0x6c, 0x86, 0x41, 0x68, 0x74, 0x74, 0x70,
+  0x3a, 0x2f, 0x2f, 0x73, 0x73, 0x6c, 0x63, 0x72, 0x6c, 0x2e, 0x62, 0x6d,
+  0x77, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70,
+  0x6b, 0x69, 0x2f, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f,
+  0x75, 0x70, 0x25, 0x32, 0x30, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67,
+  0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x2e, 0x63, 0x72,
+  0x6c, 0x30, 0x82, 0x01, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+  0x07, 0x01, 0x01, 0x04, 0x82, 0x01, 0x10, 0x30, 0x82, 0x01, 0x0c, 0x30,
+  0x81, 0xba, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02,
+  0x86, 0x81, 0xad, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x2f, 0x43,
+  0x4e, 0x3d, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75,
+  0x70, 0x25, 0x32, 0x30, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, 0x25,
+  0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x2c, 0x43, 0x4e, 0x3d,
+  0x41, 0x49, 0x41, 0x2c, 0x43, 0x4e, 0x3d, 0x50, 0x75, 0x62, 0x6c, 0x69,
+  0x63, 0x25, 0x32, 0x30, 0x4b, 0x65, 0x79, 0x25, 0x32, 0x30, 0x53, 0x65,
+  0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65,
+  0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x6f,
+  0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c,
+  0x44, 0x43, 0x3d, 0x62, 0x6d, 0x77, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f,
+  0x72, 0x70, 0x3f, 0x63, 0x41, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+  0x63, 0x61, 0x74, 0x65, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62,
+  0x6a, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x65,
+  0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41,
+  0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x4d, 0x06, 0x08,
+  0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x41, 0x68, 0x74,
+  0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x73, 0x6c, 0x63, 0x72, 0x6c, 0x2e,
+  0x62, 0x6d, 0x77, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x63, 0x6f, 0x6d,
+  0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47,
+  0x72, 0x6f, 0x75, 0x70, 0x25, 0x32, 0x30, 0x49, 0x73, 0x73, 0x75, 0x69,
+  0x6e, 0x67, 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x2e,
+  0x63, 0x72, 0x74, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x46,
+  0x9e, 0x81, 0xb2, 0xec, 0xa9, 0xe4, 0x3c, 0xf3, 0x9b, 0x61, 0xdf, 0x6f,
+  0xec, 0x28, 0xe9, 0x2b, 0xd4, 0xc1, 0xb2, 0x05, 0x03, 0xbd, 0x53, 0x49,
+  0xa2, 0x94, 0x3a, 0xd6, 0x23, 0xa3, 0xe8, 0x52, 0xa4, 0xe6, 0x44, 0x5e,
+  0x15, 0x89, 0xde, 0x32, 0x12, 0xba, 0x97, 0x3a, 0xd3, 0x1d, 0xa1, 0xda,
+  0x2a, 0x70, 0x3e, 0x10, 0xea, 0x2c, 0xb5, 0x19, 0xc2, 0x71, 0xcd, 0x1c,
+  0x10, 0x07, 0x4b, 0x58, 0x10, 0x61, 0x03, 0x72, 0x4f, 0x65, 0xf7, 0x38,
+  0x9d, 0xa9, 0x35, 0x0c, 0xc9, 0xdf, 0x7f, 0x91, 0xa0, 0xd4, 0x08, 0xf2,
+  0xf9, 0x1b, 0x0f, 0xaa, 0xb4, 0xb6, 0xe0, 0x3c, 0x9d, 0x0c, 0x64, 0xee,
+  0x2f, 0x47, 0xdd, 0xdb, 0x3a, 0x6f, 0x69, 0x19, 0x1f, 0xa1, 0xdd, 0x1d,
+  0xd7, 0x45, 0x04, 0x56, 0x16, 0x43, 0x22, 0x18, 0xba, 0x22, 0xd6, 0x70,
+  0xd0, 0x67, 0xb0, 0x06, 0x6a, 0x16, 0x57, 0x61, 0x83, 0x47, 0xd9, 0x40,
+  0xc9, 0x92, 0xdd, 0x74, 0xbe, 0xb9, 0xe8, 0x07, 0x40, 0xa8, 0x23, 0xc5,
+  0xd6, 0x3e, 0x26, 0xec, 0x17, 0x6c, 0x61, 0x76, 0x47, 0x42, 0x0a, 0x82,
+  0x5e, 0xdb, 0x41, 0xba, 0x42, 0x1f, 0xec, 0xb7, 0xc2, 0xe0, 0xf8, 0x3a,
+  0x39, 0x5f, 0xb2, 0x45, 0x92, 0xdc, 0xe2, 0x5e, 0x5d, 0x81, 0x14, 0xa3,
+  0x10, 0x68, 0x5a, 0xed, 0x28, 0x9f, 0xad, 0xa6, 0xc9, 0xd9, 0x61, 0xc2,
+  0x62, 0xec, 0x1b, 0x61, 0x2a, 0x67, 0xef, 0xac, 0x79, 0xc1, 0x6e, 0x35,
+  0xc4, 0xd2, 0x69, 0x05, 0x3f, 0xf2, 0x6f, 0x5a, 0x66, 0x0c, 0xea, 0xd2,
+  0x70, 0x2e, 0xbe, 0x5f, 0xd8, 0x31, 0x6c, 0x1f, 0xec, 0x62, 0xf6, 0xa7,
+  0x98, 0x1c, 0xd4, 0xf6, 0xc1, 0x28, 0x71, 0xf5, 0x63, 0xab, 0x59, 0x4b,
+  0x34, 0xb4, 0x30, 0x12, 0x91, 0x71, 0xf8, 0x50, 0x9a, 0x26, 0x4a, 0xd9,
+  0xf1, 0x30, 0x04, 0x30, 0x82, 0x06, 0x4c, 0x30, 0x82, 0x05, 0x34, 0xa0,
+  0x03, 0x02, 0x01, 0x02, 0x02, 0x0a, 0x3c, 0xec, 0x82, 0xf8, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0e, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x64, 0x31, 0x14, 0x30,
+  0x12, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01,
+  0x19, 0x16, 0x04, 0x63, 0x6f, 0x72, 0x70, 0x31, 0x13, 0x30, 0x11, 0x06,
+  0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16,
+  0x03, 0x62, 0x6d, 0x77, 0x31, 0x16, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92,
+  0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x65, 0x75,
+  0x72, 0x6f, 0x70, 0x65, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04,
+  0x03, 0x13, 0x16, 0x42, 0x4d, 0x57, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70,
+  0x20, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, 0x20, 0x43, 0x41, 0x20,
+  0x32, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x30, 0x33, 0x30, 0x34, 0x31,
+  0x33, 0x35, 0x33, 0x31, 0x31, 0x5a, 0x17, 0x0d, 0x31, 0x32, 0x30, 0x33,
+  0x30, 0x33, 0x31, 0x33, 0x35, 0x33, 0x31, 0x31, 0x5a, 0x30, 0x81, 0x83,
+  0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x44,
+  0x45, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07,
+  0x42, 0x61, 0x76, 0x61, 0x72, 0x69, 0x61, 0x31, 0x0f, 0x30, 0x0d, 0x06,
+  0x03, 0x55, 0x04, 0x07, 0x13, 0x06, 0x4d, 0x75, 0x6e, 0x69, 0x63, 0x68,
+  0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09, 0x42,
+  0x4d, 0x57, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x31, 0x1a, 0x30, 0x18,
+  0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x43, 0x45, 0x50, 0x20,
+  0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, 0x20, 0x43, 0x41, 0x20, 0x32,
+  0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x09, 0x01, 0x16, 0x12, 0x74, 0x72, 0x75, 0x73, 0x74, 0x63, 0x65,
+  0x6e, 0x74, 0x65, 0x72, 0x40, 0x62, 0x6d, 0x77, 0x2e, 0x64, 0x65, 0x30,
+  0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89,
+  0x02, 0x81, 0x81, 0x00, 0xa4, 0x78, 0xc8, 0x9b, 0xd9, 0x08, 0x24, 0xab,
+  0x07, 0x33, 0x89, 0x62, 0xcd, 0x20, 0xcb, 0x16, 0xfa, 0x1d, 0x9b, 0x8a,
+  0xcf, 0x9d, 0x61, 0xea, 0x10, 0xbd, 0xa0, 0x02, 0xf5, 0x97, 0x53, 0x96,
+  0x86, 0xb3, 0x02, 0x88, 0xf7, 0x52, 0xd8, 0x67, 0xcd, 0xe4, 0xba, 0xa7,
+  0x36, 0xfd, 0x6e, 0xd3, 0x51, 0x9a, 0xa2, 0xfb, 0xcc, 0x2c, 0xd1, 0xaa,
+  0x9c, 0x49, 0x2e, 0x36, 0xe0, 0xa2, 0x21, 0xc8, 0xfd, 0x05, 0xa9, 0x54,
+  0x16, 0x9f, 0xd3, 0x8e, 0x6a, 0xbe, 0x3e, 0x7f, 0xc8, 0xc6, 0x2d, 0x8d,
+  0xda, 0xe9, 0x73, 0x97, 0x5e, 0x80, 0xdd, 0x8c, 0xc4, 0x9b, 0x3a, 0x77,
+  0xc7, 0x6a, 0x8d, 0xe2, 0xe1, 0x54, 0x6f, 0x5e, 0xde, 0x3f, 0x71, 0x9c,
+  0x14, 0x2d, 0x15, 0x6d, 0xf1, 0x7c, 0x43, 0x97, 0xb7, 0xdf, 0x5a, 0x1a,
+  0xb8, 0xb7, 0x9c, 0x05, 0x4d, 0xf5, 0x45, 0x45, 0x59, 0xbe, 0x73, 0xbd,
+  0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x03, 0x62, 0x30, 0x82, 0x03,
+  0x5e, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02,
+  0x05, 0x20, 0x30, 0x36, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x09, 0x0f, 0x04, 0x29, 0x30, 0x27, 0x30, 0x0d, 0x06, 0x08, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x02, 0x02, 0x01, 0x38, 0x30, 0x0d,
+  0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x04, 0x02, 0x01,
+  0x38, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x07, 0x30, 0x15,
+  0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2b,
+  0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x01, 0x30, 0x29, 0x06,
+  0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x04, 0x1c,
+  0x1e, 0x1a, 0x00, 0x43, 0x00, 0x45, 0x00, 0x50, 0x00, 0x45, 0x00, 0x6e,
+  0x00, 0x63, 0x00, 0x72, 0x00, 0x79, 0x00, 0x70, 0x00, 0x74, 0x00, 0x69,
+  0x00, 0x6f, 0x00, 0x6e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
+  0x16, 0x04, 0x14, 0x11, 0xe1, 0x07, 0x5e, 0xd5, 0x49, 0xed, 0x64, 0x11,
+  0xc4, 0x33, 0xbb, 0x2a, 0x99, 0x7c, 0xb0, 0xc8, 0xd8, 0x85, 0x8d, 0x30,
+  0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
+  0x61, 0x0a, 0xef, 0x1a, 0x3d, 0xfe, 0x9a, 0x68, 0x81, 0xcb, 0xb2, 0x62,
+  0xe5, 0xc0, 0x21, 0x8e, 0xdd, 0xec, 0x61, 0x95, 0x30, 0x82, 0x01, 0x71,
+  0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x82, 0x01, 0x68, 0x30, 0x82, 0x01,
+  0x64, 0x30, 0x82, 0x01, 0x60, 0xa0, 0x82, 0x01, 0x5c, 0xa0, 0x82, 0x01,
+  0x58, 0x86, 0x81, 0xc3, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x2f,
+  0x43, 0x4e, 0x3d, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f,
+  0x75, 0x70, 0x25, 0x32, 0x30, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67,
+  0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x2c, 0x43, 0x4e,
+  0x3d, 0x53, 0x4d, 0x55, 0x43, 0x31, 0x39, 0x32, 0x33, 0x2c, 0x43, 0x4e,
+  0x3d, 0x43, 0x44, 0x50, 0x2c, 0x43, 0x4e, 0x3d, 0x50, 0x75, 0x62, 0x6c,
+  0x69, 0x63, 0x25, 0x32, 0x30, 0x4b, 0x65, 0x79, 0x25, 0x32, 0x30, 0x53,
+  0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x53,
+  0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x43,
+  0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+  0x2c, 0x44, 0x43, 0x3d, 0x62, 0x6d, 0x77, 0x2c, 0x44, 0x43, 0x3d, 0x63,
+  0x6f, 0x72, 0x70, 0x3f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+  0x61, 0x74, 0x65, 0x52, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f,
+  0x6e, 0x4c, 0x69, 0x73, 0x74, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f,
+  0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63,
+  0x52, 0x4c, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69,
+  0x6f, 0x6e, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x86, 0x4d, 0x68, 0x74, 0x74,
+  0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x6d, 0x75, 0x63, 0x31, 0x39, 0x32, 0x33,
+  0x2e, 0x65, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2e, 0x62, 0x6d, 0x77, 0x2e,
+  0x63, 0x6f, 0x72, 0x70, 0x2f, 0x43, 0x65, 0x72, 0x74, 0x45, 0x6e, 0x72,
+  0x6f, 0x6c, 0x6c, 0x2f, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72,
+  0x6f, 0x75, 0x70, 0x25, 0x32, 0x30, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e,
+  0x67, 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x2e, 0x63,
+  0x72, 0x6c, 0x86, 0x41, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73,
+  0x73, 0x6c, 0x63, 0x72, 0x6c, 0x2e, 0x62, 0x6d, 0x77, 0x67, 0x72, 0x6f,
+  0x75, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x42,
+  0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x25, 0x32,
+  0x30, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, 0x25, 0x32, 0x30, 0x43,
+  0x41, 0x25, 0x32, 0x30, 0x32, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x82, 0x01,
+  0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
+  0x82, 0x01, 0x10, 0x30, 0x82, 0x01, 0x0c, 0x30, 0x81, 0xba, 0x06, 0x08,
+  0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x81, 0xad, 0x6c,
+  0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x2f, 0x43, 0x4e, 0x3d, 0x42, 0x4d,
+  0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x25, 0x32, 0x30,
+  0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, 0x25, 0x32, 0x30, 0x43, 0x41,
+  0x25, 0x32, 0x30, 0x32, 0x2c, 0x43, 0x4e, 0x3d, 0x41, 0x49, 0x41, 0x2c,
+  0x43, 0x4e, 0x3d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30,
+  0x4b, 0x65, 0x79, 0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
+  0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
+  0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+  0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x62,
+  0x6d, 0x77, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, 0x72, 0x70, 0x3f, 0x63,
+  0x41, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65,
+  0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74,
+  0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66,
+  0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x6f,
+  0x72, 0x69, 0x74, 0x79, 0x30, 0x4d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+  0x05, 0x07, 0x30, 0x02, 0x86, 0x41, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+  0x2f, 0x73, 0x73, 0x6c, 0x63, 0x72, 0x6c, 0x2e, 0x62, 0x6d, 0x77, 0x67,
+  0x72, 0x6f, 0x75, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69,
+  0x2f, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70,
+  0x25, 0x32, 0x30, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, 0x25, 0x32,
+  0x30, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x2e, 0x63, 0x72, 0x74, 0x30,
+  0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
+  0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xa6, 0xdb, 0xab, 0x42, 0x93,
+  0x90, 0xb9, 0x6a, 0xc1, 0x92, 0xb7, 0x3c, 0xaf, 0xf2, 0x9b, 0xed, 0x2b,
+  0x14, 0xdb, 0xd8, 0x9f, 0x6b, 0xb8, 0x8e, 0x08, 0xf0, 0x0e, 0x1a, 0xfe,
+  0xb3, 0x9a, 0x6f, 0x3d, 0x28, 0x79, 0xd4, 0x88, 0xbe, 0x1c, 0x17, 0xaa,
+  0x6a, 0xa4, 0xe9, 0xf0, 0xe0, 0xee, 0x9d, 0x74, 0x25, 0xbb, 0x48, 0x16,
+  0xb1, 0x00, 0xca, 0xfa, 0x6a, 0x0c, 0x16, 0x98, 0xef, 0xf9, 0x42, 0xd6,
+  0x81, 0xb4, 0xf7, 0xa2, 0x15, 0xb6, 0xdc, 0xe8, 0x25, 0xe8, 0xdd, 0x92,
+  0x1d, 0x0c, 0x96, 0xea, 0x80, 0x41, 0x3f, 0xd7, 0xff, 0xeb, 0x53, 0xe9,
+  0x13, 0xf8, 0xdc, 0x8b, 0xe2, 0x45, 0xb8, 0xbb, 0x22, 0x81, 0xea, 0x46,
+  0xee, 0x19, 0x14, 0xe3, 0xd5, 0xb0, 0xaa, 0x2a, 0xd2, 0x52, 0xa5, 0x3f,
+  0x7e, 0xa5, 0x7d, 0x5c, 0xb0, 0x84, 0x4e, 0x77, 0x01, 0x35, 0x76, 0x31,
+  0xa3, 0x6e, 0x3f, 0x51, 0x20, 0x3f, 0x98, 0xac, 0x68, 0x28, 0x0f, 0xc6,
+  0x5a, 0xc1, 0xcf, 0x58, 0xd7, 0x75, 0xaa, 0xe2, 0x9b, 0xc3, 0xfa, 0x3c,
+  0xd6, 0x61, 0x98, 0x2b, 0xf1, 0x73, 0x78, 0x2a, 0xb2, 0x54, 0x78, 0xba,
+  0xff, 0x36, 0x15, 0x17, 0xe7, 0xe6, 0x6e, 0x82, 0xee, 0x64, 0x87, 0x81,
+  0xd9, 0x08, 0x68, 0xa4, 0xc7, 0x9b, 0xa4, 0xa9, 0xf3, 0x1e, 0xe9, 0x82,
+  0xc1, 0x3d, 0xfd, 0xe9, 0x75, 0x77, 0x81, 0x73, 0x05, 0x2e, 0x36, 0x0e,
+  0x17, 0x13, 0x48, 0x20, 0x9c, 0x24, 0xce, 0xe2, 0x22, 0x68, 0x3f, 0x37,
+  0x3d, 0xf5, 0x01, 0x0e, 0x13, 0xec, 0x3d, 0xba, 0x0d, 0x71, 0xd2, 0xe2,
+  0x67, 0x65, 0x19, 0x24, 0xa4, 0x5d, 0xae, 0x35, 0x1e, 0x39, 0x4c, 0xe4,
+  0x19, 0x48, 0x91, 0x03, 0x9e, 0xe9, 0x42, 0xfd, 0x1f, 0x1d, 0x2a, 0x98,
+  0x40, 0xd0, 0xb6, 0x92, 0xb3, 0x38, 0x0f, 0xf5, 0x7f, 0xf0, 0xc1, 0x30,
+  0x82, 0x03, 0x70, 0x30, 0x82, 0x02, 0x58, 0xa0, 0x03, 0x02, 0x01, 0x02,
+  0x02, 0x10, 0x13, 0xaa, 0xab, 0xff, 0x7f, 0x25, 0x31, 0xae, 0x49, 0x9b,
+  0x17, 0x9b, 0xef, 0xee, 0xe2, 0x97, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x40, 0x31,
+  0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x44, 0x45,
+  0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09, 0x42,
+  0x4d, 0x57, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x31, 0x1d, 0x30, 0x1b,
+  0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x42, 0x4d, 0x57, 0x20, 0x47,
+  0x72, 0x6f, 0x75, 0x70, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41,
+  0x20, 0x56, 0x32, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, 0x31, 0x32, 0x31,
+  0x30, 0x31, 0x30, 0x32, 0x36, 0x35, 0x31, 0x5a, 0x17, 0x0d, 0x33, 0x34,
+  0x31, 0x32, 0x31, 0x30, 0x31, 0x30, 0x33, 0x35, 0x34, 0x30, 0x5a, 0x30,
+  0x40, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+  0x44, 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+  0x09, 0x42, 0x4d, 0x57, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x31, 0x1d,
+  0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x42, 0x4d, 0x57,
+  0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
+  0x43, 0x41, 0x20, 0x56, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06,
+  0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
+  0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01,
+  0x01, 0x00, 0xd0, 0x27, 0x3b, 0xb7, 0xfe, 0x8d, 0x0c, 0xd6, 0xed, 0xf0,
+  0xa2, 0x49, 0x1f, 0x83, 0xed, 0x11, 0xcf, 0x56, 0x96, 0xe2, 0xe2, 0x1a,
+  0xac, 0x59, 0x4c, 0xef, 0x27, 0xf7, 0xda, 0xf8, 0x6a, 0x0d, 0xea, 0x78,
+  0x27, 0x69, 0x84, 0xd0, 0x4d, 0x94, 0xd8, 0x78, 0xc6, 0x14, 0x25, 0x98,
+  0x68, 0x69, 0xd5, 0x3a, 0xfd, 0x84, 0x39, 0xf3, 0x4a, 0xb8, 0x47, 0x51,
+  0x59, 0x8c, 0xa4, 0x24, 0x97, 0x10, 0xb5, 0x3b, 0x28, 0x4f, 0x26, 0x91,
+  0xad, 0xb2, 0x39, 0xc7, 0x8b, 0x96, 0x99, 0x62, 0x53, 0xe3, 0xee, 0xba,
+  0x1d, 0x55, 0x49, 0x98, 0x32, 0x60, 0xb3, 0x8d, 0x1a, 0x53, 0x29, 0x7b,
+  0xf1, 0xd3, 0xf4, 0xbc, 0x7d, 0xf1, 0x47, 0x78, 0x88, 0xe4, 0x14, 0x9c,
+  0x60, 0xdc, 0x8b, 0x65, 0xfd, 0x95, 0x39, 0xc0, 0x8b, 0x59, 0xcb, 0x66,
+  0xd2, 0x6a, 0x19, 0x67, 0x0e, 0xcd, 0x56, 0xf6, 0x7a, 0x2a, 0x8f, 0x2a,
+  0x4f, 0x1e, 0x15, 0x4d, 0xbe, 0xb5, 0x3e, 0xca, 0x3a, 0xc3, 0x93, 0x8a,
+  0xac, 0x28, 0x4c, 0x2d, 0xbd, 0x1f, 0x2b, 0x92, 0x43, 0x32, 0xdd, 0x97,
+  0xef, 0xb7, 0x09, 0xf3, 0x6b, 0x3d, 0x1e, 0x36, 0x16, 0x8b, 0x78, 0xce,
+  0x96, 0x45, 0x36, 0x9d, 0x3a, 0x90, 0x5e, 0x20, 0x3f, 0xb2, 0x39, 0x8b,
+  0x2f, 0x76, 0xd1, 0x2f, 0xe9, 0x2a, 0xb0, 0xd8, 0x40, 0x0b, 0xd9, 0x62,
+  0xd0, 0xe0, 0x6b, 0xa6, 0xf7, 0x00, 0xa8, 0x50, 0xac, 0xb0, 0x17, 0x20,
+  0x6c, 0x89, 0x1b, 0x32, 0x0a, 0x91, 0x8f, 0x94, 0xcf, 0x24, 0x72, 0xdb,
+  0x4f, 0xf9, 0x4c, 0x9e, 0x88, 0x49, 0xd9, 0x01, 0x03, 0xd0, 0xc7, 0xf4,
+  0xd1, 0xf8, 0xd5, 0x6b, 0x76, 0xea, 0x14, 0xa3, 0xb5, 0x24, 0x4c, 0xa5,
+  0xd2, 0xa8, 0x12, 0x79, 0xd3, 0x27, 0xb4, 0x9a, 0x47, 0xaa, 0x7b, 0x74,
+  0x90, 0xbb, 0xb5, 0x74, 0x29, 0x53, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
+  0x66, 0x30, 0x64, 0x30, 0x13, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01,
+  0x82, 0x37, 0x14, 0x02, 0x04, 0x06, 0x1e, 0x04, 0x00, 0x43, 0x00, 0x41,
+  0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01,
+  0x86, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04,
+  0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
+  0x0e, 0x04, 0x16, 0x04, 0x14, 0x17, 0xd0, 0xa6, 0x81, 0xc4, 0xba, 0xb6,
+  0x59, 0xe8, 0xac, 0xa5, 0x5f, 0xa3, 0x07, 0xad, 0xfd, 0x8b, 0x56, 0x2b,
+  0xbb, 0x30, 0x10, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37,
+  0x15, 0x01, 0x04, 0x03, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82,
+  0x01, 0x01, 0x00, 0x6c, 0x1b, 0xf2, 0x9b, 0xa7, 0x29, 0xc3, 0x7c, 0x90,
+  0xf0, 0xd2, 0x88, 0xc1, 0x5a, 0xdf, 0xea, 0x1d, 0x48, 0xeb, 0xe5, 0x83,
+  0x64, 0x31, 0xb4, 0x61, 0xa8, 0x3c, 0xfe, 0x1b, 0xf9, 0x0e, 0xc1, 0xdd,
+  0xd2, 0x81, 0xcb, 0x57, 0xcf, 0x12, 0xe0, 0x97, 0xee, 0xfe, 0x7c, 0x9e,
+  0x4d, 0xf2, 0x53, 0x68, 0x30, 0xab, 0xa7, 0x6b, 0xcd, 0xac, 0xef, 0x98,
+  0x93, 0x6e, 0x96, 0x93, 0x49, 0x0d, 0x51, 0x61, 0xb2, 0x85, 0x71, 0x7e,
+  0x3d, 0x3d, 0x90, 0x4d, 0xd6, 0x46, 0x85, 0xf8, 0x67, 0x8c, 0x53, 0x10,
+  0x0c, 0x36, 0xd4, 0xe9, 0xfb, 0x29, 0x19, 0x27, 0xfb, 0xcd, 0x87, 0xd3,
+  0x2b, 0xd3, 0xfd, 0x2e, 0xac, 0xf9, 0xeb, 0x1d, 0x82, 0xa7, 0x4f, 0x22,
+  0xba, 0x73, 0x22, 0x26, 0x64, 0x73, 0x5c, 0xaa, 0x44, 0x23, 0x9e, 0x5d,
+  0xb6, 0xd0, 0x79, 0xd8, 0x7f, 0x2e, 0xd6, 0xdb, 0x73, 0x3a, 0x09, 0xdf,
+  0x44, 0xff, 0xba, 0xa6, 0xcc, 0xcc, 0x61, 0x76, 0x8c, 0x18, 0x8c, 0x89,
+  0xa9, 0x10, 0xab, 0xda, 0x21, 0x22, 0xfb, 0x3f, 0x65, 0x0b, 0xa9, 0xd3,
+  0x0a, 0x70, 0x85, 0x8a, 0x81, 0xb7, 0x60, 0x9a, 0x6d, 0x3a, 0x42, 0xfa,
+  0xc8, 0x0b, 0x58, 0x8d, 0x47, 0x34, 0x78, 0x51, 0x66, 0xc3, 0x11, 0xa6,
+  0x22, 0x99, 0x2b, 0x64, 0x64, 0xda, 0xe3, 0xa1, 0x46, 0x81, 0xb7, 0x52,
+  0xdc, 0xd0, 0x17, 0x19, 0xf1, 0xae, 0xe0, 0x05, 0x92, 0x07, 0x92, 0x98,
+  0x0f, 0x2a, 0xf7, 0x1d, 0xe2, 0x42, 0x7f, 0x97, 0xd1, 0xea, 0x27, 0x8e,
+  0x65, 0xef, 0x00, 0x0b, 0xce, 0xbb, 0xd7, 0xa7, 0x7d, 0xf9, 0x31, 0x92,
+  0x44, 0x1c, 0x9e, 0x84, 0xc6, 0x8f, 0xed, 0x37, 0x51, 0x79, 0xaa, 0x7b,
+  0x9a, 0x9d, 0xac, 0xe2, 0xa0, 0xae, 0x4d, 0xf0, 0x91, 0x83, 0x5d, 0x85,
+  0xca, 0xfa, 0xea, 0x26, 0x0b, 0x48, 0x16, 0x30, 0x82, 0x05, 0xfc, 0x30,
+  0x82, 0x04, 0xe4, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0a, 0x1e, 0x30,
+  0xc3, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
+  0x40, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+  0x44, 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+  0x09, 0x42, 0x4d, 0x57, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x31, 0x1d,
+  0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x42, 0x4d, 0x57,
+  0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
+  0x43, 0x41, 0x20, 0x56, 0x32, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, 0x31,
+  0x32, 0x31, 0x37, 0x30, 0x39, 0x31, 0x37, 0x31, 0x39, 0x5a, 0x17, 0x0d,
+  0x32, 0x32, 0x31, 0x32, 0x31, 0x37, 0x30, 0x39, 0x32, 0x37, 0x31, 0x39,
+  0x5a, 0x30, 0x64, 0x31, 0x14, 0x30, 0x12, 0x06, 0x0a, 0x09, 0x92, 0x26,
+  0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x04, 0x63, 0x6f, 0x72,
+  0x70, 0x31, 0x13, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
+  0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x62, 0x6d, 0x77, 0x31, 0x16,
+  0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64,
+  0x01, 0x19, 0x16, 0x06, 0x65, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x31, 0x1f,
+  0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x42, 0x4d, 0x57,
+  0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x49, 0x73, 0x73, 0x75, 0x69,
+  0x6e, 0x67, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30,
+  0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
+  0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02,
+  0x82, 0x01, 0x01, 0x00, 0xb3, 0xab, 0xd3, 0x53, 0x73, 0x45, 0x6c, 0x37,
+  0xc4, 0x79, 0x7c, 0xe9, 0xfb, 0x0d, 0x6b, 0xb5, 0x9d, 0xcc, 0x95, 0xa5,
+  0xf7, 0x02, 0x04, 0x94, 0x8a, 0x2f, 0xb2, 0xea, 0x9f, 0x27, 0xe4, 0xef,
+  0x95, 0x02, 0x2f, 0x8c, 0x2f, 0x23, 0x4a, 0xd9, 0x53, 0xc8, 0x81, 0xb7,
+  0xe9, 0xb8, 0xb1, 0x52, 0x5c, 0x02, 0x7a, 0x2b, 0x4c, 0xe1, 0xeb, 0x25,
+  0xa4, 0x8b, 0x53, 0xa4, 0x45, 0x74, 0xbb, 0x20, 0xa6, 0x2e, 0x8b, 0x5b,
+  0xf0, 0x05, 0x86, 0x06, 0x79, 0x24, 0x55, 0x27, 0x10, 0x71, 0x9b, 0xf7,
+  0xac, 0x71, 0x8c, 0xa0, 0x4c, 0xe7, 0x9f, 0x1a, 0xb4, 0xa2, 0xd7, 0x5b,
+  0x17, 0xa3, 0x9f, 0xb3, 0x5b, 0x28, 0x16, 0xbe, 0x28, 0x48, 0x58, 0x6f,
+  0x19, 0x7e, 0x7c, 0x7b, 0x0d, 0x69, 0x59, 0xa1, 0x97, 0x13, 0x1a, 0x1f,
+  0x9c, 0xf3, 0x47, 0x36, 0xf2, 0xfa, 0xda, 0xad, 0xbd, 0xd2, 0xda, 0xdd,
+  0xb9, 0xcb, 0x9e, 0xef, 0xe4, 0x63, 0x1e, 0xdb, 0xf6, 0xd6, 0x4c, 0x85,
+  0xf1, 0x7f, 0x04, 0xe4, 0xf7, 0x07, 0xc4, 0x6e, 0x77, 0x36, 0xd7, 0x4e,
+  0x62, 0xb9, 0x71, 0x5b, 0x46, 0x58, 0x99, 0x81, 0xa9, 0x71, 0x43, 0x36,
+  0x4b, 0x06, 0xc2, 0x9c, 0xd9, 0x91, 0xb5, 0x5c, 0xcf, 0x95, 0x94, 0xa1,
+  0x37, 0x44, 0xce, 0x59, 0xc4, 0x1f, 0x99, 0x1e, 0x2d, 0x18, 0xb8, 0x6a,
+  0xf8, 0x13, 0x0e, 0x71, 0x4b, 0x67, 0xd7, 0x1e, 0xc8, 0x4d, 0x1f, 0x54,
+  0xd6, 0xc5, 0x94, 0x39, 0x52, 0x32, 0xca, 0x47, 0xa2, 0x01, 0x83, 0x03,
+  0x1b, 0xa8, 0xe1, 0xd4, 0x7d, 0x30, 0x1f, 0x20, 0x58, 0xb0, 0xd4, 0x6b,
+  0xeb, 0x13, 0x37, 0x10, 0x98, 0x3f, 0x89, 0x0d, 0x94, 0xa3, 0x24, 0xfd,
+  0xcf, 0x20, 0x79, 0xc2, 0x2e, 0x25, 0xcb, 0x0b, 0x47, 0x25, 0xe5, 0x79,
+  0xbe, 0x4e, 0x92, 0xd7, 0x24, 0xea, 0xc6, 0x1b, 0x02, 0x03, 0x01, 0x00,
+  0x01, 0xa3, 0x82, 0x02, 0xd2, 0x30, 0x82, 0x02, 0xce, 0x30, 0x0f, 0x06,
+  0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01,
+  0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
+  0x14, 0x61, 0x0a, 0xef, 0x1a, 0x3d, 0xfe, 0x9a, 0x68, 0x81, 0xcb, 0xb2,
+  0x62, 0xe5, 0xc0, 0x21, 0x8e, 0xdd, 0xec, 0x61, 0x95, 0x30, 0x0e, 0x06,
+  0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01,
+  0x06, 0x30, 0x10, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37,
+  0x15, 0x01, 0x04, 0x03, 0x02, 0x01, 0x00, 0x30, 0x19, 0x06, 0x09, 0x2b,
+  0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x04, 0x0c, 0x1e, 0x0a,
+  0x00, 0x53, 0x00, 0x75, 0x00, 0x62, 0x00, 0x43, 0x00, 0x41, 0x30, 0x1f,
+  0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x17,
+  0xd0, 0xa6, 0x81, 0xc4, 0xba, 0xb6, 0x59, 0xe8, 0xac, 0xa5, 0x5f, 0xa3,
+  0x07, 0xad, 0xfd, 0x8b, 0x56, 0x2b, 0xbb, 0x30, 0x82, 0x01, 0x1e, 0x06,
+  0x03, 0x55, 0x1d, 0x1f, 0x04, 0x82, 0x01, 0x15, 0x30, 0x82, 0x01, 0x11,
+  0x30, 0x82, 0x01, 0x0d, 0xa0, 0x82, 0x01, 0x09, 0xa0, 0x82, 0x01, 0x05,
+  0x86, 0x81, 0xc1, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x2f, 0x43,
+  0x4e, 0x3d, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75,
+  0x70, 0x25, 0x32, 0x30, 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43,
+  0x41, 0x25, 0x32, 0x30, 0x56, 0x32, 0x2c, 0x43, 0x4e, 0x3d, 0x73, 0x6d,
+  0x75, 0x63, 0x31, 0x38, 0x39, 0x32, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x44,
+  0x50, 0x2c, 0x43, 0x4e, 0x3d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25,
+  0x32, 0x30, 0x4b, 0x65, 0x79, 0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76,
+  0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76,
+  0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66,
+  0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43,
+  0x3d, 0x62, 0x6d, 0x77, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, 0x72, 0x70,
+  0x3f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65,
+  0x52, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69,
+  0x73, 0x74, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65,
+  0x63, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x52, 0x4c, 0x44,
+  0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50,
+  0x6f, 0x69, 0x6e, 0x74, 0x86, 0x3f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+  0x2f, 0x73, 0x73, 0x6c, 0x63, 0x72, 0x6c, 0x2e, 0x62, 0x6d, 0x77, 0x67,
+  0x72, 0x6f, 0x75, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69,
+  0x2f, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70,
+  0x25, 0x32, 0x30, 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43, 0x41,
+  0x25, 0x32, 0x30, 0x56, 0x32, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x82, 0x01,
+  0x1a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
+  0x82, 0x01, 0x0c, 0x30, 0x82, 0x01, 0x08, 0x30, 0x81, 0xb8, 0x06, 0x08,
+  0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x81, 0xab, 0x6c,
+  0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x2f, 0x43, 0x4e, 0x3d, 0x42, 0x4d,
+  0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x25, 0x32, 0x30,
+  0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30,
+  0x56, 0x32, 0x2c, 0x43, 0x4e, 0x3d, 0x41, 0x49, 0x41, 0x2c, 0x43, 0x4e,
+  0x3d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30, 0x4b, 0x65,
+  0x79, 0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73,
+  0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73,
+  0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72,
+  0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x62, 0x6d, 0x77,
+  0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, 0x72, 0x70, 0x3f, 0x63, 0x41, 0x43,
+  0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x3f, 0x62,
+  0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6c,
+  0x61, 0x73, 0x73, 0x3d, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+  0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
+  0x74, 0x79, 0x30, 0x4b, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+  0x30, 0x02, 0x86, 0x3f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73,
+  0x73, 0x6c, 0x63, 0x72, 0x6c, 0x2e, 0x62, 0x6d, 0x77, 0x67, 0x72, 0x6f,
+  0x75, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x42,
+  0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x25, 0x32,
+  0x30, 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32,
+  0x30, 0x56, 0x32, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82,
+  0x01, 0x01, 0x00, 0x68, 0x8c, 0xe9, 0xec, 0x52, 0x47, 0xe5, 0x9a, 0xac,
+  0x02, 0x1e, 0x1f, 0x49, 0x12, 0x24, 0x4a, 0xd6, 0x76, 0x41, 0xa7, 0xe6,
+  0x32, 0xf5, 0xc3, 0x96, 0xad, 0x22, 0x34, 0xd6, 0xf7, 0xce, 0xcc, 0xf5,
+  0x20, 0xcf, 0xf9, 0x81, 0x55, 0xff, 0x7a, 0xfb, 0x77, 0xe0, 0x5e, 0x37,
+  0x56, 0x55, 0x17, 0xd7, 0x1a, 0x09, 0x52, 0x2c, 0xda, 0x84, 0xed, 0x1e,
+  0xa3, 0xb3, 0x26, 0xfe, 0x93, 0xff, 0x45, 0x6a, 0x87, 0x91, 0xf9, 0x05,
+  0xe3, 0xa6, 0xcf, 0x33, 0xbc, 0xd6, 0x4a, 0x58, 0x70, 0xfa, 0x9e, 0x54,
+  0x7a, 0x79, 0x16, 0xd7, 0xea, 0xd4, 0x04, 0xaf, 0x87, 0x9a, 0x54, 0xe5,
+  0x80, 0x13, 0xfd, 0xdf, 0x83, 0xc4, 0x60, 0x12, 0x33, 0x49, 0x7b, 0x90,
+  0xd7, 0x1e, 0x09, 0x11, 0x4b, 0xd8, 0xbe, 0x06, 0xd4, 0xf0, 0x8e, 0x84,
+  0x06, 0x2a, 0xe3, 0x0b, 0xf4, 0xac, 0x9d, 0x31, 0xa1, 0x9f, 0x03, 0x91,
+  0xbe, 0xf8, 0x93, 0x6d, 0xc1, 0x9d, 0x8f, 0x18, 0xd3, 0xb9, 0x29, 0xaa,
+  0x19, 0x51, 0x15, 0xf7, 0x99, 0x3f, 0x42, 0x69, 0xfd, 0xec, 0xfb, 0xf0,
+  0x8a, 0x3f, 0x35, 0x65, 0x17, 0x1c, 0x52, 0xf4, 0xd1, 0x31, 0xc8, 0x14,
+  0x51, 0x42, 0x1b, 0xb8, 0xea, 0x7c, 0x4f, 0xbf, 0xd5, 0x78, 0x72, 0xdf,
+  0x18, 0x86, 0xc6, 0x2f, 0x2c, 0xb4, 0x45, 0x1b, 0x0b, 0x00, 0x16, 0x0e,
+  0xd6, 0x41, 0xd9, 0x4d, 0xa0, 0x9e, 0xb3, 0x56, 0x8d, 0xf8, 0x6b, 0xa0,
+  0x20, 0x4c, 0x1c, 0x6e, 0x3a, 0x80, 0xec, 0xd7, 0x85, 0x8c, 0xbb, 0xc1,
+  0x51, 0x73, 0x66, 0x47, 0x01, 0x44, 0x9a, 0x87, 0xc9, 0xed, 0x49, 0x04,
+  0xc2, 0x41, 0xea, 0x65, 0x16, 0xda, 0xd0, 0xb7, 0xe6, 0x03, 0x73, 0x74,
+  0x11, 0x3b, 0x94, 0x1b, 0x9f, 0x06, 0xb9, 0x71, 0x02, 0x70, 0x66, 0xa0,
+  0x12, 0xb5, 0x5a, 0xe8, 0x2c, 0xf9, 0x63, 0x31, 0x00
+};
+static unsigned int bmw_scep_pkt_len = 5661;
diff --git a/sec/Security/Regressions/secitem/si-63-scep/getcacert-mdes.h b/sec/Security/Regressions/secitem/si-63-scep/getcacert-mdes.h
new file mode 100644 (file)
index 0000000..15c50bc
--- /dev/null
@@ -0,0 +1,559 @@
+unsigned char getcacert_mdes[] = {
+  0x30, 0x82, 0x1a, 0x01, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x07, 0x02, 0xa0, 0x82, 0x19, 0xf2, 0x30, 0x82, 0x19, 0xee, 0x02,
+  0x01, 0x01, 0x31, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x19, 0xd6, 0x30, 0x82, 0x04,
+  0xca, 0x30, 0x82, 0x03, 0xb2, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0a,
+  0x61, 0xe8, 0x74, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x30, 0x0d,
+  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
+  0x00, 0x30, 0x7c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+  0x13, 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04,
+  0x0a, 0x13, 0x0b, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x20, 0x46, 0x61, 0x72,
+  0x67, 0x6f, 0x31, 0x2c, 0x30, 0x2a, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
+  0x23, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x20, 0x46, 0x61, 0x72, 0x67, 0x6f,
+  0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65,
+  0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x65, 0x73,
+  0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x20, 0x57,
+  0x65, 0x6c, 0x6c, 0x73, 0x20, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x20, 0x49,
+  0x6e, 0x66, 0x72, 0x61, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72,
+  0x65, 0x20, 0x43, 0x41, 0x20, 0x30, 0x32, 0x30, 0x1e, 0x17, 0x0d, 0x31,
+  0x31, 0x31, 0x31, 0x32, 0x32, 0x30, 0x33, 0x30, 0x32, 0x32, 0x31, 0x5a,
+  0x17, 0x0d, 0x31, 0x33, 0x31, 0x31, 0x32, 0x31, 0x30, 0x33, 0x30, 0x32,
+  0x32, 0x31, 0x5a, 0x30, 0x72, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+  0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03,
+  0x55, 0x04, 0x0a, 0x13, 0x0b, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x20, 0x46,
+  0x61, 0x72, 0x67, 0x6f, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04,
+  0x0b, 0x13, 0x03, 0x50, 0x4b, 0x49, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03,
+  0x55, 0x04, 0x03, 0x13, 0x0d, 0x57, 0x49, 0x46, 0x43, 0x41, 0x30, 0x32,
+  0x50, 0x2d, 0x4e, 0x44, 0x45, 0x53, 0x31, 0x27, 0x30, 0x25, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x18, 0x70,
+  0x6b, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x40, 0x77, 0x65, 0x6c,
+  0x6c, 0x73, 0x66, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x30,
+  0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30,
+  0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xe6, 0x09, 0x83, 0xa0,
+  0xfd, 0x70, 0x19, 0xba, 0x16, 0x3f, 0xcb, 0x17, 0xed, 0x53, 0x83, 0x40,
+  0xf6, 0x24, 0x6a, 0x39, 0x5e, 0x86, 0xd3, 0x92, 0xa5, 0xb9, 0x10, 0xad,
+  0x07, 0xb0, 0x05, 0xdf, 0x89, 0xee, 0x03, 0xc2, 0xb5, 0x69, 0xde, 0x9d,
+  0x5b, 0x92, 0x8d, 0x28, 0xc6, 0x09, 0x54, 0xb7, 0x34, 0x21, 0x57, 0xda,
+  0xcc, 0xb4, 0x87, 0x13, 0xdf, 0x9b, 0xd8, 0x06, 0x84, 0xc0, 0xaa, 0xc6,
+  0x5f, 0xe9, 0x51, 0xcf, 0xa0, 0x58, 0x19, 0x32, 0x10, 0xd3, 0x86, 0x36,
+  0x5e, 0x8f, 0x78, 0x82, 0x61, 0xf4, 0x15, 0x35, 0x9d, 0xe0, 0x90, 0x20,
+  0xe6, 0x3c, 0x43, 0xe8, 0x10, 0xa3, 0x40, 0xf1, 0x33, 0x03, 0xa9, 0xbd,
+  0x25, 0x18, 0x4b, 0x71, 0xca, 0xba, 0x20, 0x5f, 0xad, 0x1f, 0xf3, 0xad,
+  0xd2, 0x78, 0xda, 0x69, 0x10, 0x7b, 0x63, 0x72, 0x8e, 0x77, 0xa9, 0x04,
+  0xb5, 0x9e, 0xf2, 0x7d, 0xb8, 0x47, 0x5d, 0xde, 0x09, 0xbf, 0x81, 0x91,
+  0x78, 0xd5, 0xa5, 0xb5, 0xd8, 0xb9, 0xef, 0x39, 0xc2, 0x4b, 0x64, 0x1d,
+  0x78, 0x35, 0xea, 0xa0, 0x58, 0x1a, 0x73, 0x7e, 0x6d, 0x9f, 0x0e, 0x6b,
+  0x99, 0x59, 0xc3, 0xd4, 0xd8, 0x2f, 0xf3, 0xdb, 0xe3, 0x57, 0x29, 0xc7,
+  0x80, 0x35, 0xc1, 0x35, 0x0e, 0x3e, 0x12, 0x25, 0x8c, 0x27, 0xdd, 0xa7,
+  0xbc, 0x3b, 0x3a, 0xc9, 0xf0, 0x76, 0x39, 0x04, 0x7e, 0x49, 0xdd, 0x53,
+  0x42, 0x59, 0x97, 0x1a, 0xc5, 0x09, 0x97, 0x1b, 0x82, 0xc6, 0xb9, 0x28,
+  0xe0, 0x01, 0xb3, 0xbd, 0xd7, 0x4e, 0xae, 0xf2, 0x42, 0xd7, 0xd4, 0xd2,
+  0x76, 0x42, 0x83, 0xf5, 0xc0, 0x05, 0x36, 0x89, 0xa2, 0x96, 0x2a, 0x45,
+  0xca, 0x70, 0x0c, 0x08, 0xb5, 0x54, 0x8f, 0x13, 0x25, 0x25, 0x48, 0x27,
+  0x68, 0x4c, 0x76, 0x1c, 0xc1, 0xe1, 0x93, 0x97, 0x7d, 0x15, 0x47, 0x23,
+  0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x56, 0x30, 0x82, 0x01,
+  0x52, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
+  0x63, 0x5b, 0x90, 0x2f, 0xb6, 0xf3, 0x72, 0x91, 0x69, 0xa9, 0x8e, 0x0b,
+  0x85, 0x12, 0x70, 0xb5, 0x63, 0xb2, 0xf4, 0xd8, 0x30, 0x0b, 0x06, 0x03,
+  0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x1f, 0x06,
+  0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xbb, 0x26,
+  0xd5, 0x66, 0x3f, 0xa4, 0x02, 0x87, 0x68, 0x06, 0x98, 0x7d, 0x52, 0xc6,
+  0x0a, 0x94, 0xbb, 0x45, 0xd3, 0xc8, 0x30, 0x38, 0x06, 0x03, 0x55, 0x1d,
+  0x1f, 0x04, 0x31, 0x30, 0x2f, 0x30, 0x2d, 0xa0, 0x2b, 0xa0, 0x29, 0x86,
+  0x27, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e,
+  0x70, 0x6b, 0x69, 0x2e, 0x77, 0x65, 0x6c, 0x6c, 0x73, 0x66, 0x61, 0x72,
+  0x67, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x6e, 0x66, 0x30, 0x32,
+  0x2e, 0x63, 0x72, 0x6c, 0x30, 0x75, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+  0x05, 0x07, 0x01, 0x01, 0x04, 0x69, 0x30, 0x67, 0x30, 0x37, 0x06, 0x08,
+  0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2b, 0x68, 0x74,
+  0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x70, 0x6b, 0x69,
+  0x2e, 0x77, 0x65, 0x6c, 0x6c, 0x73, 0x66, 0x61, 0x72, 0x67, 0x6f, 0x2e,
+  0x63, 0x6f, 0x6d, 0x2f, 0x77, 0x66, 0x5f, 0x69, 0x6e, 0x66, 0x5f, 0x30,
+  0x32, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x2c, 0x06, 0x08, 0x2b, 0x06, 0x01,
+  0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a,
+  0x2f, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e,
+  0x77, 0x65, 0x6c, 0x6c, 0x73, 0x66, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x63,
+  0x6f, 0x6d, 0x2f, 0x30, 0x3b, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01,
+  0x82, 0x37, 0x14, 0x02, 0x04, 0x2e, 0x1e, 0x2c, 0x00, 0x45, 0x00, 0x6e,
+  0x00, 0x72, 0x00, 0x6f, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6d, 0x00, 0x65,
+  0x00, 0x6e, 0x00, 0x74, 0x00, 0x41, 0x00, 0x67, 0x00, 0x65, 0x00, 0x6e,
+  0x00, 0x74, 0x00, 0x4f, 0x00, 0x66, 0x00, 0x66, 0x00, 0x6c, 0x00, 0x69,
+  0x00, 0x6e, 0x00, 0x65, 0x30, 0x15, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04,
+  0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37,
+  0x14, 0x02, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x58,
+  0xc4, 0xd2, 0x4b, 0x5b, 0x2b, 0x80, 0xca, 0xb5, 0xa0, 0x17, 0x8a, 0x44,
+  0xb0, 0xd3, 0x65, 0x98, 0xa7, 0xe3, 0xf3, 0x41, 0x6a, 0x32, 0x3e, 0x6b,
+  0x20, 0x3c, 0x9e, 0x68, 0x1e, 0x0c, 0xab, 0x76, 0x91, 0x93, 0x77, 0xaa,
+  0xc6, 0x58, 0x28, 0xa0, 0x59, 0x63, 0xba, 0x3d, 0x47, 0x95, 0xad, 0xe5,
+  0x36, 0x8c, 0x57, 0x84, 0x19, 0x99, 0x41, 0xbb, 0xf3, 0x5a, 0x7a, 0xd9,
+  0xd5, 0x10, 0x52, 0xca, 0x22, 0xe9, 0xae, 0xbb, 0xbf, 0xdc, 0x02, 0xf1,
+  0x40, 0xc7, 0xb0, 0x1a, 0x59, 0x5b, 0x5c, 0xfc, 0x08, 0xc2, 0x4f, 0xf3,
+  0xde, 0x9f, 0x0d, 0x5e, 0x50, 0x88, 0x9f, 0xfb, 0x24, 0xd9, 0x8e, 0xe1,
+  0xed, 0x92, 0x60, 0x76, 0x70, 0x25, 0x7d, 0x3f, 0xaf, 0x51, 0x5b, 0xdb,
+  0x6d, 0x3d, 0xcc, 0x1c, 0x7c, 0x46, 0x21, 0xe4, 0x59, 0xdd, 0x92, 0x98,
+  0x4d, 0x03, 0xa4, 0x41, 0xd7, 0x9c, 0x67, 0xdd, 0x83, 0x87, 0xe6, 0xe4,
+  0xaa, 0x52, 0xf1, 0x96, 0x8f, 0x2e, 0xa6, 0x9d, 0xc8, 0x87, 0xcf, 0x14,
+  0xd1, 0x10, 0x3e, 0xcb, 0xd5, 0x34, 0x20, 0xa2, 0x56, 0x20, 0x05, 0xdf,
+  0x03, 0x64, 0x35, 0xa9, 0x2e, 0x73, 0xbb, 0xda, 0xef, 0xb6, 0x80, 0xbd,
+  0xf0, 0x3d, 0xd7, 0x3a, 0xa3, 0xcc, 0x8e, 0x90, 0xdd, 0xfc, 0xbe, 0x92,
+  0x10, 0xe7, 0x41, 0x51, 0x62, 0xa9, 0xbc, 0xd0, 0x80, 0x19, 0x72, 0x25,
+  0x36, 0x48, 0x5c, 0xfb, 0x03, 0x56, 0x5c, 0x1c, 0xf7, 0x7f, 0x56, 0xa7,
+  0xab, 0x52, 0x04, 0x96, 0xc7, 0x9a, 0x80, 0xd0, 0x11, 0x2e, 0x25, 0xe9,
+  0xe6, 0x2e, 0x4e, 0x79, 0xd2, 0xf1, 0xed, 0x5a, 0xff, 0x65, 0xc3, 0x3d,
+  0xb0, 0x11, 0x70, 0x35, 0xe6, 0xe2, 0x9d, 0x9e, 0x30, 0x47, 0xb9, 0x84,
+  0x80, 0xfe, 0x1d, 0x3a, 0xeb, 0x2c, 0xe4, 0x22, 0x90, 0x53, 0x64, 0x63,
+  0x8f, 0xd4, 0x97, 0x30, 0x82, 0x05, 0x32, 0x30, 0x82, 0x04, 0x1a, 0xa0,
+  0x03, 0x02, 0x01, 0x02, 0x02, 0x0a, 0x61, 0xe5, 0x9c, 0xc3, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x7c, 0x31, 0x0b, 0x30,
+  0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x14,
+  0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x57, 0x65, 0x6c,
+  0x6c, 0x73, 0x20, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x31, 0x2c, 0x30, 0x2a,
+  0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x23, 0x57, 0x65, 0x6c, 0x6c, 0x73,
+  0x20, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
+  0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
+  0x72, 0x69, 0x74, 0x69, 0x65, 0x73, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03,
+  0x55, 0x04, 0x03, 0x13, 0x20, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x20, 0x46,
+  0x61, 0x72, 0x67, 0x6f, 0x20, 0x49, 0x6e, 0x66, 0x72, 0x61, 0x73, 0x74,
+  0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x20, 0x43, 0x41, 0x20, 0x30,
+  0x32, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x31, 0x31, 0x31, 0x32, 0x32, 0x30,
+  0x32, 0x35, 0x39, 0x31, 0x35, 0x5a, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x31,
+  0x32, 0x31, 0x30, 0x32, 0x35, 0x39, 0x31, 0x35, 0x5a, 0x30, 0x72, 0x31,
+  0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
+  0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x57,
+  0x65, 0x6c, 0x6c, 0x73, 0x20, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x31, 0x0c,
+  0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x03, 0x50, 0x4b, 0x49,
+  0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x57,
+  0x49, 0x46, 0x43, 0x41, 0x30, 0x32, 0x50, 0x2d, 0x4e, 0x44, 0x45, 0x53,
+  0x31, 0x27, 0x30, 0x25, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x09, 0x01, 0x16, 0x18, 0x70, 0x6b, 0x73, 0x75, 0x70, 0x70, 0x6f,
+  0x72, 0x74, 0x40, 0x77, 0x65, 0x6c, 0x6c, 0x73, 0x66, 0x61, 0x72, 0x67,
+  0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06,
+  0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
+  0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01,
+  0x01, 0x00, 0xb9, 0x73, 0x67, 0x30, 0xb1, 0xb8, 0xc5, 0x6a, 0x86, 0xf7,
+  0xec, 0x1a, 0x22, 0x71, 0x28, 0x0e, 0x94, 0x35, 0x93, 0xc7, 0xb8, 0x91,
+  0x02, 0xb2, 0x03, 0x47, 0x73, 0xdf, 0x8a, 0x59, 0xa3, 0x28, 0xee, 0x47,
+  0x03, 0xeb, 0x3f, 0x11, 0x90, 0x1c, 0xc3, 0xd8, 0x27, 0x1e, 0x1e, 0x0a,
+  0xdc, 0xfe, 0xc3, 0x78, 0x6a, 0x4f, 0xb0, 0x7f, 0x03, 0xbb, 0xea, 0xc2,
+  0x9e, 0x9b, 0x3c, 0xf3, 0x21, 0x2e, 0x01, 0xef, 0x21, 0x6c, 0xd0, 0x6c,
+  0xc0, 0xc2, 0xdb, 0xe2, 0xe7, 0xe5, 0x4a, 0xf8, 0x5f, 0xaf, 0x45, 0x02,
+  0x84, 0xe4, 0xf6, 0xdd, 0x4b, 0xfe, 0x3f, 0x1b, 0x8b, 0x5d, 0x91, 0x5c,
+  0xa0, 0x46, 0xab, 0x02, 0x23, 0x07, 0xae, 0x49, 0x38, 0x15, 0x0c, 0x41,
+  0x15, 0xbd, 0x0a, 0xc2, 0x9b, 0x7f, 0x92, 0xeb, 0xbe, 0xf4, 0xc8, 0x4d,
+  0x3c, 0xfa, 0xeb, 0xd1, 0xac, 0xa1, 0xcc, 0x3d, 0xd4, 0x2f, 0x18, 0xec,
+  0xe2, 0xa4, 0xbf, 0x5b, 0x2d, 0x1b, 0x7b, 0xb9, 0xce, 0x97, 0x6a, 0x6c,
+  0xd6, 0x62, 0x9d, 0xe5, 0xc5, 0x8d, 0x15, 0x91, 0xe0, 0xd1, 0x34, 0x93,
+  0xac, 0x52, 0xa5, 0xdc, 0x11, 0x75, 0x1c, 0xbc, 0x0e, 0x55, 0xc2, 0x4a,
+  0x65, 0xcd, 0x00, 0x17, 0xe5, 0x4d, 0x74, 0x52, 0xe6, 0x0c, 0xdf, 0xb0,
+  0x19, 0x4f, 0x37, 0x69, 0x4b, 0x5c, 0x88, 0x49, 0xfc, 0xd3, 0x1a, 0x27,
+  0x69, 0xdc, 0xb9, 0x04, 0x34, 0x87, 0xfa, 0x2a, 0x66, 0x92, 0x69, 0xe5,
+  0xeb, 0xc2, 0x3a, 0x44, 0xed, 0x07, 0xc6, 0xd3, 0x89, 0x3a, 0xd8, 0x6d,
+  0x3c, 0x8f, 0x96, 0xa1, 0xa5, 0xa2, 0x37, 0x08, 0x35, 0xc3, 0xdd, 0xf4,
+  0x77, 0x42, 0x10, 0xa5, 0xaa, 0x56, 0x59, 0x1d, 0x77, 0x54, 0x72, 0x7d,
+  0x42, 0x38, 0x8b, 0x78, 0xd6, 0xc3, 0x7f, 0xc3, 0x2f, 0xc3, 0xa3, 0xde,
+  0xd7, 0xae, 0x5e, 0x95, 0x97, 0x93, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
+  0x82, 0x01, 0xbe, 0x30, 0x82, 0x01, 0xba, 0x30, 0x78, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x0f, 0x04, 0x6b, 0x30, 0x69,
+  0x30, 0x0e, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x02,
+  0x02, 0x02, 0x00, 0x80, 0x30, 0x0e, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x03, 0x04, 0x02, 0x02, 0x00, 0x80, 0x30, 0x0b, 0x06, 0x09,
+  0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2a, 0x30, 0x0b, 0x06,
+  0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2d, 0x30, 0x0b,
+  0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x02, 0x30,
+  0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x05,
+  0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x07, 0x30, 0x0a, 0x06,
+  0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x07, 0x30, 0x1d, 0x06,
+  0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x34, 0x69, 0x6e, 0xd2,
+  0x67, 0xb3, 0xb8, 0x85, 0xa8, 0x01, 0xaa, 0x43, 0xaf, 0x2b, 0xb4, 0xea,
+  0x0d, 0x67, 0xa3, 0x9a, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04,
+  0x04, 0x03, 0x02, 0x05, 0x20, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23,
+  0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xbb, 0x26, 0xd5, 0x66, 0x3f, 0xa4,
+  0x02, 0x87, 0x68, 0x06, 0x98, 0x7d, 0x52, 0xc6, 0x0a, 0x94, 0xbb, 0x45,
+  0xd3, 0xc8, 0x30, 0x38, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x31, 0x30,
+  0x2f, 0x30, 0x2d, 0xa0, 0x2b, 0xa0, 0x29, 0x86, 0x27, 0x68, 0x74, 0x74,
+  0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x70, 0x6b, 0x69, 0x2e,
+  0x77, 0x65, 0x6c, 0x6c, 0x73, 0x66, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x63,
+  0x6f, 0x6d, 0x2f, 0x69, 0x6e, 0x66, 0x30, 0x32, 0x2e, 0x63, 0x72, 0x6c,
+  0x30, 0x75, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01,
+  0x04, 0x69, 0x30, 0x67, 0x30, 0x37, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+  0x05, 0x07, 0x30, 0x02, 0x86, 0x2b, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+  0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x70, 0x6b, 0x69, 0x2e, 0x77, 0x65, 0x6c,
+  0x6c, 0x73, 0x66, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+  0x77, 0x66, 0x5f, 0x69, 0x6e, 0x66, 0x5f, 0x30, 0x32, 0x2e, 0x63, 0x72,
+  0x74, 0x30, 0x2c, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30,
+  0x01, 0x86, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x76, 0x61,
+  0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x77, 0x65, 0x6c, 0x6c,
+  0x73, 0x66, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30,
+  0x29, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02,
+  0x04, 0x1c, 0x1e, 0x1a, 0x00, 0x43, 0x00, 0x45, 0x00, 0x50, 0x00, 0x45,
+  0x00, 0x6e, 0x00, 0x63, 0x00, 0x72, 0x00, 0x79, 0x00, 0x70, 0x00, 0x74,
+  0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x30, 0x15, 0x06, 0x03, 0x55, 0x1d,
+  0x25, 0x04, 0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01,
+  0x82, 0x37, 0x14, 0x02, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01,
+  0x00, 0x53, 0x91, 0xf9, 0x4e, 0x41, 0xef, 0x5d, 0x9c, 0x44, 0xd0, 0xa7,
+  0x7f, 0x5c, 0xf7, 0x51, 0x67, 0xbc, 0x61, 0xb7, 0x56, 0x03, 0x1d, 0xbf,
+  0x79, 0xbd, 0xe5, 0x26, 0x57, 0xac, 0x67, 0x06, 0xe6, 0x40, 0xf1, 0x52,
+  0x3a, 0x0d, 0x1f, 0xda, 0xb4, 0xbc, 0xd2, 0x7b, 0xc9, 0x63, 0x88, 0x08,
+  0x78, 0xe2, 0xdc, 0xf9, 0x8c, 0x79, 0x80, 0x21, 0x0f, 0x41, 0x3e, 0xb8,
+  0xcd, 0xe5, 0x8d, 0x9a, 0xad, 0x06, 0x49, 0xde, 0x4b, 0x1d, 0xae, 0x65,
+  0x9e, 0x5e, 0xe1, 0x85, 0x8e, 0xc9, 0x4d, 0x0f, 0x24, 0x72, 0xc1, 0x42,
+  0x59, 0xbb, 0x7f, 0x1a, 0x2b, 0x9e, 0x26, 0x70, 0x08, 0xcc, 0xeb, 0xef,
+  0x20, 0x22, 0xa2, 0x34, 0x9d, 0xf7, 0x84, 0x50, 0x37, 0xd5, 0x54, 0xe5,
+  0xad, 0xf4, 0x79, 0x58, 0x60, 0xac, 0x31, 0x3d, 0xd8, 0x68, 0xd3, 0x44,
+  0xb0, 0x28, 0xf5, 0xb5, 0x46, 0xa2, 0x56, 0xb0, 0x74, 0xfe, 0x66, 0xa1,
+  0xaa, 0x40, 0x1a, 0x37, 0x21, 0xd7, 0x44, 0xbe, 0xa7, 0xd9, 0x97, 0x27,
+  0x79, 0xff, 0x7a, 0xe1, 0x71, 0xca, 0xec, 0x7a, 0x2c, 0x92, 0x91, 0xdd,
+  0x60, 0xfd, 0xb2, 0x9c, 0x24, 0xf0, 0xf2, 0xed, 0x39, 0x70, 0x36, 0x25,
+  0xcf, 0x14, 0x35, 0x50, 0x9c, 0x6f, 0xe5, 0x9a, 0xfc, 0x1a, 0x1c, 0x24,
+  0xa6, 0x45, 0xbe, 0x7f, 0xc9, 0xb0, 0x50, 0xf5, 0xa2, 0x7c, 0xbc, 0x48,
+  0x4f, 0xd6, 0xd0, 0x29, 0xe6, 0x3e, 0x58, 0x9d, 0xbe, 0x47, 0x10, 0x37,
+  0xb5, 0xdd, 0xe0, 0x0e, 0xe2, 0xe1, 0x7e, 0xde, 0xf0, 0xea, 0x83, 0x16,
+  0x94, 0xcd, 0x42, 0x2c, 0x82, 0x30, 0x7a, 0x33, 0x06, 0x94, 0xee, 0xce,
+  0xfd, 0x36, 0x07, 0x5c, 0x0a, 0x38, 0x98, 0x10, 0x99, 0xdd, 0x0f, 0x17,
+  0x90, 0x84, 0x73, 0x8e, 0xb3, 0xf3, 0x79, 0x4c, 0x4e, 0x72, 0x6b, 0x7a,
+  0x32, 0xdf, 0xe8, 0x16, 0x11, 0x30, 0x82, 0x05, 0x46, 0x30, 0x82, 0x04,
+  0x2e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x15, 0x35, 0xb3, 0xd1,
+  0x7f, 0x70, 0xdc, 0x8d, 0x49, 0x18, 0xfa, 0x0d, 0xe6, 0xd6, 0x1a, 0xd6,
+  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+  0x05, 0x05, 0x00, 0x30, 0x81, 0x93, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+  0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06,
+  0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x20,
+  0x46, 0x61, 0x72, 0x67, 0x6f, 0x31, 0x2c, 0x30, 0x2a, 0x06, 0x03, 0x55,
+  0x04, 0x0b, 0x13, 0x23, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x20, 0x46, 0x61,
+  0x72, 0x67, 0x6f, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+  0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
+  0x69, 0x65, 0x73, 0x31, 0x40, 0x30, 0x3e, 0x06, 0x03, 0x55, 0x04, 0x03,
+  0x13, 0x37, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x20, 0x46, 0x61, 0x72, 0x67,
+  0x6f, 0x20, 0x49, 0x6e, 0x66, 0x72, 0x61, 0x73, 0x74, 0x72, 0x75, 0x63,
+  0x74, 0x75, 0x72, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65,
+  0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
+  0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17,
+  0x0d, 0x30, 0x39, 0x30, 0x36, 0x31, 0x30, 0x32, 0x30, 0x30, 0x34, 0x32,
+  0x36, 0x5a, 0x17, 0x0d, 0x34, 0x39, 0x30, 0x36, 0x31, 0x30, 0x32, 0x30,
+  0x31, 0x33, 0x34, 0x36, 0x5a, 0x30, 0x81, 0x93, 0x31, 0x0b, 0x30, 0x09,
+  0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x14, 0x30,
+  0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x57, 0x65, 0x6c, 0x6c,
+  0x73, 0x20, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x31, 0x2c, 0x30, 0x2a, 0x06,
+  0x03, 0x55, 0x04, 0x0b, 0x13, 0x23, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x20,
+  0x46, 0x61, 0x72, 0x67, 0x6f, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+  0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+  0x69, 0x74, 0x69, 0x65, 0x73, 0x31, 0x40, 0x30, 0x3e, 0x06, 0x03, 0x55,
+  0x04, 0x03, 0x13, 0x37, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x20, 0x46, 0x61,
+  0x72, 0x67, 0x6f, 0x20, 0x49, 0x6e, 0x66, 0x72, 0x61, 0x73, 0x74, 0x72,
+  0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
+  0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+  0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30,
+  0x82, 0x01, 0x20, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0d, 0x00, 0x30,
+  0x82, 0x01, 0x08, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb0, 0x7b, 0xdc, 0xe7,
+  0x4d, 0x3c, 0x79, 0x36, 0x7d, 0x6b, 0xc3, 0xe0, 0x8a, 0x57, 0xa8, 0x20,
+  0x90, 0x4d, 0x48, 0x67, 0xde, 0x78, 0xfd, 0x7d, 0x8e, 0x54, 0xcf, 0x2d,
+  0x19, 0x24, 0x8c, 0x05, 0x52, 0xe6, 0xdd, 0xdf, 0x62, 0x5e, 0xa9, 0xb6,
+  0xc4, 0x24, 0xdb, 0x74, 0xc1, 0x83, 0x70, 0x03, 0x43, 0x00, 0x99, 0x07,
+  0x12, 0x70, 0x63, 0xba, 0x6b, 0xba, 0xa6, 0xcf, 0xb1, 0xc0, 0x25, 0x36,
+  0x96, 0xa4, 0xb0, 0xcf, 0x9d, 0x1c, 0xe3, 0x5b, 0x3d, 0x09, 0x27, 0xe0,
+  0xa2, 0xf1, 0x67, 0x15, 0x52, 0xa9, 0x2c, 0xc9, 0x55, 0xee, 0xa7, 0x24,
+  0x64, 0xb4, 0xc6, 0x0c, 0x65, 0xa1, 0x26, 0x16, 0x37, 0x1c, 0x0b, 0x90,
+  0x63, 0x46, 0xd5, 0x84, 0xe0, 0x32, 0xde, 0xb8, 0x08, 0x24, 0xe2, 0xe5,
+  0x9d, 0xa0, 0x04, 0xb2, 0x98, 0x3f, 0xdc, 0x79, 0xa0, 0xbd, 0x35, 0x77,
+  0x10, 0xd4, 0xa0, 0x06, 0xe6, 0x7e, 0x07, 0x13, 0x21, 0xcb, 0x36, 0x15,
+  0x3a, 0x47, 0x3f, 0x53, 0x6d, 0xd5, 0xd4, 0x30, 0xef, 0x1d, 0x20, 0xad,
+  0xf9, 0xd6, 0xe6, 0x45, 0x7d, 0xd0, 0x73, 0xfb, 0x9d, 0xb7, 0x97, 0xe2,
+  0x0f, 0x76, 0x07, 0x0d, 0x07, 0x8b, 0x3d, 0xc9, 0x27, 0x63, 0xa7, 0x12,
+  0xf1, 0x43, 0xf3, 0xf8, 0xd0, 0x92, 0xf2, 0x9b, 0x5a, 0x54, 0x83, 0x4c,
+  0xeb, 0x1f, 0x09, 0xd5, 0xca, 0x02, 0xcd, 0x87, 0xb5, 0x66, 0x93, 0x7b,
+  0xe7, 0x45, 0x58, 0xfa, 0xf2, 0x48, 0x26, 0x6d, 0x54, 0x04, 0x17, 0x7b,
+  0xae, 0xbb, 0x56, 0x2c, 0x14, 0x47, 0xcc, 0xad, 0x33, 0x37, 0x31, 0xa5,
+  0xd0, 0xf5, 0x48, 0xe4, 0x48, 0x47, 0x4e, 0x63, 0x1a, 0xba, 0x44, 0x51,
+  0x00, 0x3c, 0xbe, 0xbf, 0x20, 0xcf, 0x7e, 0x98, 0xd8, 0xd2, 0xd3, 0xf4,
+  0xcb, 0x57, 0x04, 0x0b, 0x00, 0x23, 0x2f, 0x0d, 0xa2, 0xb7, 0xcc, 0xad,
+  0x02, 0x01, 0x03, 0xa3, 0x82, 0x01, 0x94, 0x30, 0x82, 0x01, 0x90, 0x30,
+  0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86,
+  0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05,
+  0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
+  0x04, 0x16, 0x04, 0x14, 0x38, 0x87, 0x59, 0x2b, 0xaa, 0x1e, 0xab, 0x59,
+  0x7e, 0x6b, 0x73, 0xae, 0x57, 0x92, 0xc9, 0x39, 0xe0, 0x16, 0xb5, 0x85,
+  0x30, 0x10, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15,
+  0x01, 0x04, 0x03, 0x02, 0x01, 0x00, 0x30, 0x82, 0x01, 0x3d, 0x06, 0x03,
+  0x55, 0x1d, 0x20, 0x04, 0x82, 0x01, 0x34, 0x30, 0x82, 0x01, 0x30, 0x30,
+  0x81, 0x90, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, 0x86, 0xfb, 0x7b, 0x83,
+  0x74, 0x00, 0x00, 0x30, 0x81, 0x80, 0x30, 0x54, 0x06, 0x08, 0x2b, 0x06,
+  0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x48, 0x1e, 0x46, 0x00, 0x57,
+  0x00, 0x65, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x73, 0x00, 0x53, 0x00, 0x65,
+  0x00, 0x63, 0x00, 0x75, 0x00, 0x72, 0x00, 0x65, 0x00, 0xae, 0x00, 0x20,
+  0x00, 0x50, 0x00, 0x4b, 0x00, 0x49, 0x00, 0x20, 0x00, 0x43, 0x00, 0x65,
+  0x00, 0x72, 0x00, 0x74, 0x00, 0x69, 0x00, 0x66, 0x00, 0x69, 0x00, 0x63,
+  0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x20, 0x00, 0x50, 0x00, 0x6f,
+  0x00, 0x6c, 0x00, 0x69, 0x00, 0x63, 0x00, 0x79, 0x30, 0x28, 0x06, 0x08,
+  0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74,
+  0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x65, 0x6c,
+  0x6c, 0x73, 0x66, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+  0x63, 0x70, 0x30, 0x81, 0x9a, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, 0x86,
+  0xfb, 0x7b, 0x83, 0x74, 0x00, 0x01, 0x30, 0x81, 0x8a, 0x30, 0x5e, 0x06,
+  0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x52, 0x1e,
+  0x50, 0x20, 0x1d, 0x00, 0x57, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x6c, 0x00,
+  0x73, 0x00, 0x53, 0x00, 0x65, 0x00, 0x63, 0x00, 0x75, 0x00, 0x72, 0x00,
+  0x65, 0x00, 0xae, 0x00, 0x20, 0x00, 0x50, 0x00, 0x4b, 0x00, 0x49, 0x00,
+  0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x66, 0x00, 0x72, 0x00, 0x61, 0x00,
+  0x73, 0x00, 0x74, 0x00, 0x72, 0x00, 0x75, 0x00, 0x63, 0x00, 0x74, 0x00,
+  0x75, 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, 0x00, 0x50, 0x00, 0x6f, 0x00,
+  0x6c, 0x00, 0x69, 0x00, 0x63, 0x00, 0x79, 0x20, 0x1d, 0x30, 0x28, 0x06,
+  0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68,
+  0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x65,
+  0x6c, 0x6c, 0x73, 0x66, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x63, 0x6f, 0x6d,
+  0x2f, 0x63, 0x70, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xad,
+  0x8b, 0xe7, 0xd9, 0xe7, 0x42, 0x60, 0xe6, 0x76, 0x9c, 0x37, 0xbe, 0x0b,
+  0x55, 0x49, 0xb2, 0x43, 0x60, 0xaa, 0x43, 0x31, 0x17, 0x3f, 0x7b, 0x53,
+  0xc4, 0xba, 0xd8, 0x83, 0x08, 0xe0, 0x64, 0xd3, 0x1e, 0x59, 0x76, 0x46,
+  0xe3, 0x11, 0xf5, 0x21, 0x59, 0x50, 0x1f, 0xdc, 0xd4, 0x9c, 0x19, 0xae,
+  0x30, 0x31, 0xc6, 0xca, 0x5d, 0x2b, 0x6f, 0x21, 0x26, 0x8b, 0x58, 0x4d,
+  0xa1, 0x22, 0x12, 0x1a, 0x92, 0xd8, 0xbb, 0xad, 0xa0, 0xfb, 0x98, 0x6c,
+  0x32, 0x16, 0x41, 0x0f, 0x3b, 0x53, 0x91, 0xd6, 0x99, 0x26, 0xa2, 0xfe,
+  0x2c, 0x54, 0xd0, 0x89, 0x2a, 0x74, 0x34, 0xd5, 0xe3, 0x89, 0xe2, 0x15,
+  0xbb, 0x55, 0xa7, 0x9d, 0x51, 0xa4, 0x30, 0x09, 0x91, 0x0e, 0x33, 0x69,
+  0x7d, 0x30, 0x36, 0x75, 0x16, 0x9e, 0x40, 0xe0, 0x36, 0x25, 0x31, 0x80,
+  0x1f, 0x9e, 0xcb, 0xde, 0xff, 0x1c, 0x60, 0x2c, 0xa6, 0x73, 0x1a, 0xd3,
+  0x92, 0x52, 0xb4, 0x55, 0x4e, 0x39, 0xc9, 0xb3, 0xde, 0xaa, 0x5e, 0xb9,
+  0x57, 0x86, 0x4b, 0xb1, 0xc4, 0xe1, 0x5e, 0x51, 0xa9, 0x38, 0x56, 0xfd,
+  0x15, 0xc2, 0x0f, 0x92, 0x50, 0xd7, 0x83, 0xf9, 0x8f, 0x8a, 0x68, 0x9e,
+  0x19, 0x54, 0x9e, 0x65, 0xa3, 0xb1, 0x20, 0xf2, 0xdb, 0xf0, 0xf7, 0x41,
+  0xd3, 0xfd, 0x5b, 0x77, 0x4a, 0x53, 0x1e, 0x7b, 0x5a, 0xe6, 0x57, 0x28,
+  0xab, 0x07, 0xd0, 0x18, 0xd9, 0x86, 0x74, 0xec, 0xe5, 0x8c, 0x65, 0xaa,
+  0x93, 0xd0, 0x52, 0xc5, 0x88, 0x27, 0xdb, 0x6b, 0xd1, 0xaf, 0x76, 0x4a,
+  0x7e, 0x27, 0x8f, 0x90, 0xdc, 0x9f, 0x1b, 0xef, 0x71, 0x58, 0x0b, 0xa5,
+  0xd6, 0x3d, 0x3c, 0x40, 0xa3, 0xaa, 0xfe, 0x3d, 0x58, 0xd3, 0x2c, 0xaa,
+  0x2e, 0x59, 0xf3, 0x83, 0x52, 0x91, 0x99, 0xe9, 0xe2, 0xb7, 0x40, 0x22,
+  0x94, 0x27, 0xf6, 0x30, 0x82, 0x0a, 0x84, 0x30, 0x82, 0x09, 0x6c, 0xa0,
+  0x03, 0x02, 0x01, 0x02, 0x02, 0x0a, 0x61, 0x5f, 0x87, 0xfe, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x05, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, 0x93, 0x31, 0x0b,
+  0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
+  0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x57, 0x65,
+  0x6c, 0x6c, 0x73, 0x20, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x31, 0x2c, 0x30,
+  0x2a, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x23, 0x57, 0x65, 0x6c, 0x6c,
+  0x73, 0x20, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x20, 0x43, 0x65, 0x72, 0x74,
+  0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68,
+  0x6f, 0x72, 0x69, 0x74, 0x69, 0x65, 0x73, 0x31, 0x40, 0x30, 0x3e, 0x06,
+  0x03, 0x55, 0x04, 0x03, 0x13, 0x37, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x20,
+  0x46, 0x61, 0x72, 0x67, 0x6f, 0x20, 0x49, 0x6e, 0x66, 0x72, 0x61, 0x73,
+  0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x20, 0x52, 0x6f, 0x6f,
+  0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+  0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
+  0x79, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, 0x30, 0x36, 0x31, 0x30, 0x32,
+  0x30, 0x34, 0x33, 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x36,
+  0x31, 0x30, 0x32, 0x30, 0x35, 0x33, 0x33, 0x38, 0x5a, 0x30, 0x7c, 0x31,
+  0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
+  0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x57,
+  0x65, 0x6c, 0x6c, 0x73, 0x20, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x31, 0x2c,
+  0x30, 0x2a, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x23, 0x57, 0x65, 0x6c,
+  0x6c, 0x73, 0x20, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x20, 0x43, 0x65, 0x72,
+  0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74,
+  0x68, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x65, 0x73, 0x31, 0x29, 0x30, 0x27,
+  0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x20, 0x57, 0x65, 0x6c, 0x6c, 0x73,
+  0x20, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x20, 0x49, 0x6e, 0x66, 0x72, 0x61,
+  0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x20, 0x43, 0x41,
+  0x20, 0x30, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82,
+  0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00,
+  0xd2, 0x1f, 0xb9, 0xe5, 0x1f, 0xea, 0x57, 0x92, 0xe4, 0x94, 0xec, 0x1a,
+  0xe9, 0x02, 0xaf, 0x45, 0x7e, 0x6a, 0xe9, 0xab, 0x1b, 0xd7, 0xfa, 0xcc,
+  0x6b, 0xfa, 0x8c, 0x1e, 0x77, 0x28, 0xe9, 0x89, 0xf0, 0xc1, 0xd3, 0x98,
+  0x10, 0xe6, 0xc1, 0x40, 0xff, 0x07, 0x5e, 0xb9, 0x26, 0x34, 0x9f, 0x02,
+  0xec, 0xc1, 0x6c, 0x26, 0x9d, 0x0b, 0x43, 0x96, 0x8a, 0x78, 0x48, 0x80,
+  0xa4, 0x00, 0x41, 0xbf, 0xba, 0x9c, 0x31, 0x1b, 0x1b, 0x8a, 0xb0, 0xdd,
+  0xc2, 0xbc, 0xaf, 0x80, 0x8b, 0x2a, 0xbe, 0xa5, 0x2a, 0x4b, 0x1f, 0xd3,
+  0x12, 0xdc, 0x83, 0xfe, 0xf7, 0xa2, 0x06, 0x65, 0x64, 0x5d, 0xfc, 0x2d,
+  0x8c, 0x6b, 0x1a, 0xf9, 0xf1, 0xd8, 0xdf, 0x03, 0x3d, 0x18, 0x7b, 0xd5,
+  0x6d, 0x5a, 0xdf, 0x88, 0xfe, 0x5f, 0xb5, 0xd1, 0x42, 0xf6, 0x82, 0x2d,
+  0xfb, 0x49, 0x0b, 0xed, 0x4a, 0xa0, 0x2f, 0xc0, 0xd1, 0x49, 0xe5, 0x8b,
+  0xee, 0x80, 0x18, 0xa5, 0xf0, 0xb3, 0x58, 0x43, 0xbd, 0x08, 0x15, 0x54,
+  0xee, 0xfd, 0xf0, 0x74, 0x01, 0x71, 0xed, 0x0d, 0x94, 0xe9, 0xe4, 0x60,
+  0x78, 0xf2, 0xbf, 0x0f, 0x07, 0xa3, 0x1f, 0x48, 0xf1, 0xd6, 0x4f, 0x84,
+  0x19, 0xf6, 0xb9, 0xcf, 0x76, 0xfc, 0xa6, 0x4d, 0x7d, 0x1d, 0x60, 0xee,
+  0x0d, 0xd4, 0x3b, 0xfb, 0x66, 0x07, 0x11, 0xe1, 0xc9, 0x31, 0xea, 0x77,
+  0x82, 0xb9, 0xa2, 0xe4, 0x4b, 0x40, 0xf9, 0xee, 0x03, 0xad, 0xbb, 0xa3,
+  0x3f, 0xdf, 0x0c, 0x03, 0x28, 0x3a, 0xe8, 0xf8, 0x57, 0xce, 0x7c, 0x40,
+  0x3a, 0x9e, 0x55, 0x6d, 0x25, 0x77, 0x8d, 0xab, 0xc7, 0x2b, 0x6b, 0x32,
+  0x38, 0xd6, 0x43, 0xdc, 0x77, 0xde, 0x99, 0x05, 0x9d, 0xcc, 0x27, 0x6a,
+  0xae, 0x07, 0x6b, 0xd3, 0xe4, 0x4c, 0x7b, 0x07, 0x7e, 0x45, 0xe0, 0x1b,
+  0x98, 0x61, 0xe4, 0x9d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x06,
+  0xee, 0x30, 0x82, 0x06, 0xea, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
+  0x04, 0x16, 0x04, 0x14, 0xbb, 0x26, 0xd5, 0x66, 0x3f, 0xa4, 0x02, 0x87,
+  0x68, 0x06, 0x98, 0x7d, 0x52, 0xc6, 0x0a, 0x94, 0xbb, 0x45, 0xd3, 0xc8,
+  0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01,
+  0xf6, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
+  0x80, 0x14, 0x38, 0x87, 0x59, 0x2b, 0xaa, 0x1e, 0xab, 0x59, 0x7e, 0x6b,
+  0x73, 0xae, 0x57, 0x92, 0xc9, 0x39, 0xe0, 0x16, 0xb5, 0x85, 0x30, 0x82,
+  0x02, 0xfb, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x82, 0x02, 0xf2, 0x30,
+  0x82, 0x02, 0xee, 0x30, 0x82, 0x02, 0xea, 0xa0, 0x82, 0x02, 0xe6, 0xa0,
+  0x82, 0x02, 0xe2, 0x86, 0x81, 0xb6, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f,
+  0x2f, 0x31, 0x35, 0x31, 0x2e, 0x31, 0x35, 0x31, 0x2e, 0x36, 0x34, 0x2e,
+  0x31, 0x33, 0x37, 0x2f, 0x63, 0x6e, 0x3d, 0x57, 0x65, 0x6c, 0x6c, 0x73,
+  0x25, 0x32, 0x30, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x25, 0x32, 0x30, 0x49,
+  0x6e, 0x66, 0x72, 0x61, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72,
+  0x65, 0x25, 0x32, 0x30, 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43,
+  0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+  0x25, 0x32, 0x30, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
+  0x2c, 0x6f, 0x75, 0x3d, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x25, 0x32, 0x30,
+  0x46, 0x61, 0x72, 0x67, 0x6f, 0x25, 0x32, 0x30, 0x43, 0x65, 0x72, 0x74,
+  0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x25, 0x32, 0x30, 0x41, 0x75,
+  0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x65, 0x73, 0x2c, 0x6f, 0x3d,
+  0x57, 0x65, 0x6c, 0x6c, 0x73, 0x25, 0x32, 0x30, 0x46, 0x61, 0x72, 0x67,
+  0x6f, 0x2c, 0x63, 0x3d, 0x55, 0x53, 0x3f, 0x63, 0x65, 0x72, 0x74, 0x69,
+  0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x76, 0x6f, 0x63, 0x61,
+  0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x86, 0x81, 0xb5, 0x6c,
+  0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x35, 0x31, 0x2e, 0x31, 0x35,
+  0x31, 0x2e, 0x31, 0x39, 0x2e, 0x31, 0x35, 0x2f, 0x63, 0x6e, 0x3d, 0x57,
+  0x65, 0x6c, 0x6c, 0x73, 0x25, 0x32, 0x30, 0x46, 0x61, 0x72, 0x67, 0x6f,
+  0x25, 0x32, 0x30, 0x49, 0x6e, 0x66, 0x72, 0x61, 0x73, 0x74, 0x72, 0x75,
+  0x63, 0x74, 0x75, 0x72, 0x65, 0x25, 0x32, 0x30, 0x52, 0x6f, 0x6f, 0x74,
+  0x25, 0x32, 0x30, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
+  0x74, 0x69, 0x6f, 0x6e, 0x25, 0x32, 0x30, 0x41, 0x75, 0x74, 0x68, 0x6f,
+  0x72, 0x69, 0x74, 0x79, 0x2c, 0x6f, 0x75, 0x3d, 0x57, 0x65, 0x6c, 0x6c,
+  0x73, 0x25, 0x32, 0x30, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x25, 0x32, 0x30,
+  0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x25,
+  0x32, 0x30, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x65,
+  0x73, 0x2c, 0x6f, 0x3d, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x25, 0x32, 0x30,
+  0x46, 0x61, 0x72, 0x67, 0x6f, 0x2c, 0x63, 0x3d, 0x55, 0x53, 0x3f, 0x63,
+  0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65,
+  0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74,
+  0x86, 0x81, 0xb6, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x35,
+  0x31, 0x2e, 0x31, 0x35, 0x31, 0x2e, 0x36, 0x34, 0x2e, 0x31, 0x34, 0x37,
+  0x2f, 0x63, 0x6e, 0x3d, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x25, 0x32, 0x30,
+  0x46, 0x61, 0x72, 0x67, 0x6f, 0x25, 0x32, 0x30, 0x49, 0x6e, 0x66, 0x72,
+  0x61, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x25, 0x32,
+  0x30, 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43, 0x65, 0x72, 0x74,
+  0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x25, 0x32, 0x30,
+  0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x2c, 0x6f, 0x75,
+  0x3d, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x25, 0x32, 0x30, 0x46, 0x61, 0x72,
+  0x67, 0x6f, 0x25, 0x32, 0x30, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+  0x63, 0x61, 0x74, 0x65, 0x25, 0x32, 0x30, 0x41, 0x75, 0x74, 0x68, 0x6f,
+  0x72, 0x69, 0x74, 0x69, 0x65, 0x73, 0x2c, 0x6f, 0x3d, 0x57, 0x65, 0x6c,
+  0x6c, 0x73, 0x25, 0x32, 0x30, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x2c, 0x63,
+  0x3d, 0x55, 0x53, 0x3f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+  0x61, 0x74, 0x65, 0x52, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f,
+  0x6e, 0x4c, 0x69, 0x73, 0x74, 0x86, 0x81, 0xb5, 0x6c, 0x64, 0x61, 0x70,
+  0x3a, 0x2f, 0x2f, 0x31, 0x35, 0x31, 0x2e, 0x31, 0x35, 0x31, 0x2e, 0x31,
+  0x39, 0x2e, 0x32, 0x35, 0x2f, 0x63, 0x6e, 0x3d, 0x57, 0x65, 0x6c, 0x6c,
+  0x73, 0x25, 0x32, 0x30, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x25, 0x32, 0x30,
+  0x49, 0x6e, 0x66, 0x72, 0x61, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75,
+  0x72, 0x65, 0x25, 0x32, 0x30, 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30,
+  0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+  0x6e, 0x25, 0x32, 0x30, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
+  0x79, 0x2c, 0x6f, 0x75, 0x3d, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x25, 0x32,
+  0x30, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x25, 0x32, 0x30, 0x43, 0x65, 0x72,
+  0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x25, 0x32, 0x30, 0x41,
+  0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x65, 0x73, 0x2c, 0x6f,
+  0x3d, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x25, 0x32, 0x30, 0x46, 0x61, 0x72,
+  0x67, 0x6f, 0x2c, 0x63, 0x3d, 0x55, 0x53, 0x3f, 0x63, 0x65, 0x72, 0x74,
+  0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x76, 0x6f, 0x63,
+  0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x30, 0x82, 0x03,
+  0x86, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
+  0x82, 0x03, 0x78, 0x30, 0x82, 0x03, 0x74, 0x30, 0x22, 0x06, 0x08, 0x2b,
+  0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x16, 0x68, 0x74, 0x74,
+  0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x35, 0x31, 0x2e, 0x31, 0x35, 0x31, 0x2e,
+  0x36, 0x34, 0x2e, 0x31, 0x33, 0x35, 0x2f, 0x30, 0x21, 0x06, 0x08, 0x2b,
+  0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x15, 0x68, 0x74, 0x74,
+  0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x35, 0x31, 0x2e, 0x31, 0x35, 0x31, 0x2e,
+  0x31, 0x39, 0x2e, 0x31, 0x33, 0x2f, 0x30, 0x22, 0x06, 0x08, 0x2b, 0x06,
+  0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x16, 0x68, 0x74, 0x74, 0x70,
+  0x3a, 0x2f, 0x2f, 0x31, 0x35, 0x31, 0x2e, 0x31, 0x35, 0x31, 0x2e, 0x36,
+  0x34, 0x2e, 0x31, 0x34, 0x35, 0x2f, 0x30, 0x21, 0x06, 0x08, 0x2b, 0x06,
+  0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x15, 0x68, 0x74, 0x74, 0x70,
+  0x3a, 0x2f, 0x2f, 0x31, 0x35, 0x31, 0x2e, 0x31, 0x35, 0x31, 0x2e, 0x31,
+  0x39, 0x2e, 0x32, 0x33, 0x2f, 0x30, 0x81, 0xb7, 0x06, 0x08, 0x2b, 0x06,
+  0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x81, 0xaa, 0x6c, 0x64, 0x61,
+  0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x35, 0x31, 0x2e, 0x31, 0x35, 0x31, 0x2e,
+  0x36, 0x34, 0x2e, 0x31, 0x33, 0x37, 0x2f, 0x63, 0x6e, 0x3d, 0x57, 0x65,
+  0x6c, 0x6c, 0x73, 0x25, 0x32, 0x30, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x25,
+  0x32, 0x30, 0x49, 0x6e, 0x66, 0x72, 0x61, 0x73, 0x74, 0x72, 0x75, 0x63,
+  0x74, 0x75, 0x72, 0x65, 0x25, 0x32, 0x30, 0x52, 0x6f, 0x6f, 0x74, 0x25,
+  0x32, 0x30, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+  0x69, 0x6f, 0x6e, 0x25, 0x32, 0x30, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+  0x69, 0x74, 0x79, 0x2c, 0x6f, 0x75, 0x3d, 0x57, 0x65, 0x6c, 0x6c, 0x73,
+  0x25, 0x32, 0x30, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x25, 0x32, 0x30, 0x43,
+  0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x25, 0x32,
+  0x30, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x65, 0x73,
+  0x2c, 0x6f, 0x3d, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x25, 0x32, 0x30, 0x46,
+  0x61, 0x72, 0x67, 0x6f, 0x2c, 0x63, 0x3d, 0x55, 0x53, 0x3f, 0x63, 0x41,
+  0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x30,
+  0x81, 0xb6, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02,
+  0x86, 0x81, 0xa9, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x35,
+  0x31, 0x2e, 0x31, 0x35, 0x31, 0x2e, 0x31, 0x39, 0x2e, 0x31, 0x35, 0x2f,
+  0x63, 0x6e, 0x3d, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x25, 0x32, 0x30, 0x46,
+  0x61, 0x72, 0x67, 0x6f, 0x25, 0x32, 0x30, 0x49, 0x6e, 0x66, 0x72, 0x61,
+  0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x25, 0x32, 0x30,
+  0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43, 0x65, 0x72, 0x74, 0x69,
+  0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x25, 0x32, 0x30, 0x41,
+  0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x2c, 0x6f, 0x75, 0x3d,
+  0x57, 0x65, 0x6c, 0x6c, 0x73, 0x25, 0x32, 0x30, 0x46, 0x61, 0x72, 0x67,
+  0x6f, 0x25, 0x32, 0x30, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+  0x61, 0x74, 0x65, 0x25, 0x32, 0x30, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+  0x69, 0x74, 0x69, 0x65, 0x73, 0x2c, 0x6f, 0x3d, 0x57, 0x65, 0x6c, 0x6c,
+  0x73, 0x25, 0x32, 0x30, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x2c, 0x63, 0x3d,
+  0x55, 0x53, 0x3f, 0x63, 0x41, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+  0x63, 0x61, 0x74, 0x65, 0x30, 0x81, 0xb7, 0x06, 0x08, 0x2b, 0x06, 0x01,
+  0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x81, 0xaa, 0x6c, 0x64, 0x61, 0x70,
+  0x3a, 0x2f, 0x2f, 0x31, 0x35, 0x31, 0x2e, 0x31, 0x35, 0x31, 0x2e, 0x36,
+  0x34, 0x2e, 0x31, 0x34, 0x37, 0x2f, 0x63, 0x6e, 0x3d, 0x57, 0x65, 0x6c,
+  0x6c, 0x73, 0x25, 0x32, 0x30, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x25, 0x32,
+  0x30, 0x49, 0x6e, 0x66, 0x72, 0x61, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74,
+  0x75, 0x72, 0x65, 0x25, 0x32, 0x30, 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32,
+  0x30, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
+  0x6f, 0x6e, 0x25, 0x32, 0x30, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
+  0x74, 0x79, 0x2c, 0x6f, 0x75, 0x3d, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x25,
+  0x32, 0x30, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x25, 0x32, 0x30, 0x43, 0x65,
+  0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x25, 0x32, 0x30,
+  0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x65, 0x73, 0x2c,
+  0x6f, 0x3d, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x25, 0x32, 0x30, 0x46, 0x61,
+  0x72, 0x67, 0x6f, 0x2c, 0x63, 0x3d, 0x55, 0x53, 0x3f, 0x63, 0x41, 0x43,
+  0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x30, 0x81,
+  0xb6, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86,
+  0x81, 0xa9, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x35, 0x31,
+  0x2e, 0x31, 0x35, 0x31, 0x2e, 0x31, 0x39, 0x2e, 0x32, 0x35, 0x2f, 0x63,
+  0x6e, 0x3d, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x25, 0x32, 0x30, 0x46, 0x61,
+  0x72, 0x67, 0x6f, 0x25, 0x32, 0x30, 0x49, 0x6e, 0x66, 0x72, 0x61, 0x73,
+  0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x25, 0x32, 0x30, 0x52,
+  0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+  0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x25, 0x32, 0x30, 0x41, 0x75,
+  0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x2c, 0x6f, 0x75, 0x3d, 0x57,
+  0x65, 0x6c, 0x6c, 0x73, 0x25, 0x32, 0x30, 0x46, 0x61, 0x72, 0x67, 0x6f,
+  0x25, 0x32, 0x30, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
+  0x74, 0x65, 0x25, 0x32, 0x30, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
+  0x74, 0x69, 0x65, 0x73, 0x2c, 0x6f, 0x3d, 0x57, 0x65, 0x6c, 0x6c, 0x73,
+  0x25, 0x32, 0x30, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x2c, 0x63, 0x3d, 0x55,
+  0x53, 0x3f, 0x63, 0x41, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+  0x61, 0x74, 0x65, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
+  0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30,
+  0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
+  0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x01, 0x71, 0xac, 0x20, 0x42,
+  0xc6, 0xfe, 0xa7, 0x66, 0x46, 0x24, 0xb1, 0x58, 0xf9, 0xc7, 0xa0, 0xc0,
+  0x5e, 0x25, 0x45, 0xd2, 0xc1, 0x1b, 0x5f, 0x9f, 0xac, 0x9f, 0xa5, 0x30,
+  0x67, 0xf5, 0x50, 0xea, 0x66, 0x5e, 0x7f, 0x2e, 0xde, 0x15, 0x61, 0x87,
+  0xdf, 0x05, 0xb7, 0x34, 0xcd, 0x76, 0xc0, 0x41, 0x62, 0x94, 0x2a, 0x8f,
+  0x81, 0x3a, 0xdc, 0x7f, 0x6f, 0x86, 0x4a, 0xdf, 0x9f, 0xd5, 0xfb, 0xb5,
+  0xdc, 0x3e, 0x98, 0x2d, 0x3f, 0x98, 0xfe, 0x60, 0x4c, 0xa0, 0xfc, 0xf8,
+  0xef, 0x70, 0xb0, 0x61, 0xb0, 0xe5, 0x6c, 0xc4, 0x9d, 0x67, 0x1a, 0x21,
+  0x1f, 0x03, 0x2a, 0x60, 0x83, 0x29, 0x3a, 0x46, 0xc5, 0x16, 0x92, 0xf2,
+  0x90, 0xc0, 0xc7, 0x22, 0xda, 0xe0, 0x49, 0xfe, 0xa2, 0x12, 0xb1, 0xe0,
+  0x99, 0x1d, 0x5f, 0x7c, 0x78, 0xe7, 0x2d, 0x3b, 0x44, 0xd5, 0xbd, 0xe9,
+  0x4a, 0xd9, 0x52, 0x96, 0xe1, 0xa8, 0x6f, 0x3e, 0x64, 0x10, 0xd5, 0x3f,
+  0xea, 0xe2, 0xde, 0x96, 0x52, 0xaa, 0x14, 0x56, 0xc6, 0xe6, 0x26, 0x6d,
+  0x61, 0x51, 0x50, 0xa2, 0x3e, 0xe2, 0x6e, 0x45, 0x63, 0x53, 0xa0, 0x0f,
+  0xf8, 0xaf, 0x59, 0x97, 0x94, 0x84, 0xb8, 0x8a, 0x65, 0x14, 0xa8, 0xc3,
+  0x91, 0xc5, 0xaf, 0xe1, 0x67, 0x74, 0x42, 0x10, 0x0b, 0xc1, 0x28, 0x3a,
+  0x20, 0xd6, 0xb3, 0x18, 0xc2, 0x06, 0xaf, 0xea, 0x74, 0x6c, 0x28, 0xf7,
+  0xa1, 0xb3, 0xab, 0x5e, 0xa9, 0x14, 0x04, 0xa6, 0x58, 0xe0, 0x4c, 0xea,
+  0x0f, 0xa7, 0x50, 0x84, 0xbb, 0x19, 0x39, 0x25, 0x9f, 0xab, 0xe7, 0xcb,
+  0x7d, 0x90, 0xac, 0xd4, 0x74, 0x82, 0x2c, 0x85, 0xb3, 0x59, 0xbf, 0x8a,
+  0x5d, 0xd0, 0x16, 0x5d, 0x7d, 0xcb, 0x6c, 0xc4, 0x58, 0x29, 0xd1, 0x11,
+  0x06, 0x8e, 0xba, 0xed, 0x8d, 0xcb, 0xb9, 0xe6, 0x59, 0x32, 0x81, 0x31,
+  0x00
+};
+unsigned int getcacert_mdes_len = 6661;
diff --git a/sec/Security/Regressions/secitem/si-63-scep/getcacert-mdesqa.h b/sec/Security/Regressions/secitem/si-63-scep/getcacert-mdesqa.h
new file mode 100644 (file)
index 0000000..48ce3ef
--- /dev/null
@@ -0,0 +1,506 @@
+unsigned char getcacert_mdesqa[] = {
+  0x30, 0x82, 0x17, 0x8e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x07, 0x02, 0xa0, 0x82, 0x17, 0x7f, 0x30, 0x82, 0x17, 0x7b, 0x02,
+  0x01, 0x01, 0x31, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x17, 0x63, 0x30, 0x82, 0x05,
+  0xc6, 0x30, 0x82, 0x04, 0xae, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0a,
+  0x61, 0x05, 0x22, 0xc2, 0x00, 0x03, 0x00, 0x00, 0x00, 0x90, 0x30, 0x0d,
+  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
+  0x00, 0x30, 0x81, 0x84, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
+  0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55,
+  0x04, 0x0a, 0x13, 0x0b, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x20, 0x46, 0x61,
+  0x72, 0x67, 0x6f, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x0b,
+  0x13, 0x27, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x20, 0x46, 0x61, 0x72, 0x67,
+  0x6f, 0x20, 0x55, 0x41, 0x54, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+  0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+  0x69, 0x74, 0x69, 0x65, 0x73, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55,
+  0x04, 0x03, 0x13, 0x24, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x20, 0x46, 0x61,
+  0x72, 0x67, 0x6f, 0x20, 0x55, 0x41, 0x54, 0x20, 0x49, 0x6e, 0x66, 0x72,
+  0x61, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x20, 0x43,
+  0x41, 0x20, 0x30, 0x32, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x31, 0x30, 0x38,
+  0x31, 0x38, 0x31, 0x38, 0x34, 0x33, 0x30, 0x31, 0x5a, 0x17, 0x0d, 0x31,
+  0x33, 0x30, 0x38, 0x31, 0x37, 0x31, 0x38, 0x34, 0x33, 0x30, 0x31, 0x5a,
+  0x30, 0x72, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+  0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a,
+  0x13, 0x0b, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x20, 0x46, 0x61, 0x72, 0x67,
+  0x6f, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x03,
+  0x50, 0x4b, 0x49, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03,
+  0x13, 0x0d, 0x57, 0x49, 0x46, 0x43, 0x41, 0x30, 0x32, 0x55, 0x2d, 0x4e,
+  0x44, 0x45, 0x53, 0x31, 0x27, 0x30, 0x25, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x18, 0x70, 0x6b, 0x73, 0x75,
+  0x70, 0x70, 0x6f, 0x72, 0x74, 0x40, 0x77, 0x65, 0x6c, 0x6c, 0x73, 0x66,
+  0x61, 0x72, 0x67, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22,
+  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+  0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
+  0x02, 0x82, 0x01, 0x01, 0x00, 0xa2, 0xb6, 0xb0, 0x34, 0x16, 0x82, 0x08,
+  0x89, 0x9f, 0x8e, 0x02, 0x15, 0x7a, 0xb4, 0x15, 0x28, 0x93, 0x42, 0x1f,
+  0x26, 0x1b, 0x3d, 0x23, 0xe8, 0x3a, 0x38, 0x2e, 0x65, 0xa0, 0x0c, 0x81,
+  0x99, 0x2b, 0x70, 0x48, 0xd6, 0x67, 0x9a, 0x20, 0xb6, 0x16, 0x4a, 0x22,
+  0x4c, 0x94, 0x26, 0x56, 0x02, 0x9d, 0xe2, 0xe2, 0x71, 0x97, 0xdd, 0x13,
+  0xcd, 0x76, 0xd8, 0xe1, 0x11, 0x55, 0xc0, 0x3e, 0x05, 0x7a, 0x1f, 0x09,
+  0xb9, 0x40, 0x73, 0x5b, 0x4f, 0x43, 0x50, 0xcf, 0x01, 0x6e, 0xd2, 0xcf,
+  0x4a, 0x61, 0x77, 0xd6, 0x13, 0x9c, 0xaa, 0x98, 0x1c, 0xf6, 0x0e, 0x9e,
+  0xad, 0xf9, 0x9b, 0x53, 0x69, 0x87, 0xc6, 0x1c, 0xd1, 0x0d, 0xb7, 0x57,
+  0x81, 0xca, 0xf9, 0xc0, 0x16, 0xf4, 0xd7, 0x22, 0x41, 0x54, 0x33, 0x9b,
+  0x80, 0x4c, 0x8f, 0x49, 0xbf, 0x73, 0x2c, 0x2f, 0x3f, 0x13, 0x7a, 0x6a,
+  0xf5, 0xc4, 0x76, 0x4b, 0x82, 0xc3, 0x9e, 0xb3, 0xc8, 0x66, 0xa1, 0x93,
+  0xa3, 0xd6, 0xee, 0xdc, 0xf6, 0x04, 0x47, 0x83, 0xec, 0xf5, 0x03, 0x1f,
+  0x99, 0x62, 0x70, 0x39, 0x02, 0x6c, 0x8d, 0xa5, 0x02, 0xab, 0x40, 0xd5,
+  0x1c, 0x40, 0x34, 0xb1, 0xec, 0xfe, 0x51, 0x79, 0x14, 0xde, 0xd0, 0xe9,
+  0xfc, 0x61, 0xb4, 0x0e, 0x50, 0xdc, 0xfa, 0xf5, 0x97, 0xa7, 0x2c, 0xd9,
+  0xbd, 0x7e, 0x95, 0xd5, 0x84, 0xf4, 0x2a, 0xa1, 0x19, 0x1b, 0xee, 0xff,
+  0x98, 0xf5, 0xf5, 0x35, 0x38, 0xec, 0xc6, 0xa0, 0x5c, 0xd4, 0xcb, 0x7a,
+  0xa6, 0xfe, 0xe5, 0xd5, 0x63, 0x89, 0x44, 0xda, 0xfa, 0x2f, 0x3d, 0x62,
+  0x75, 0x52, 0x3e, 0xf9, 0xce, 0xc1, 0x51, 0x83, 0x0f, 0x8f, 0x70, 0x01,
+  0x64, 0x3e, 0xe9, 0x67, 0xa7, 0x2d, 0xa8, 0x6d, 0xfe, 0x8d, 0x85, 0xe8,
+  0x12, 0x0b, 0x36, 0xd2, 0xca, 0xff, 0xe7, 0x6e, 0x81, 0x02, 0x03, 0x01,
+  0x00, 0x01, 0xa3, 0x82, 0x02, 0x49, 0x30, 0x82, 0x02, 0x45, 0x30, 0x3b,
+  0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x04,
+  0x2e, 0x1e, 0x2c, 0x00, 0x45, 0x00, 0x6e, 0x00, 0x72, 0x00, 0x6f, 0x00,
+  0x6c, 0x00, 0x6c, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00,
+  0x41, 0x00, 0x67, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x4f, 0x00,
+  0x66, 0x00, 0x66, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x65, 0x30,
+  0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80,
+  0x30, 0x15, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0e, 0x30, 0x0c, 0x06,
+  0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x01, 0x30,
+  0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x60, 0xe1,
+  0x42, 0xb2, 0x39, 0x89, 0xfe, 0x2f, 0x42, 0x94, 0x8c, 0x41, 0x1f, 0x24,
+  0xe7, 0x81, 0xc9, 0x9a, 0xf8, 0x54, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
+  0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x05, 0x53, 0x0b, 0x60, 0x25,
+  0x90, 0xfc, 0x1c, 0x7d, 0xd5, 0xbc, 0x82, 0x11, 0x26, 0xc5, 0xd5, 0x11,
+  0xd4, 0x79, 0x89, 0x30, 0x81, 0xbf, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04,
+  0x81, 0xb7, 0x30, 0x81, 0xb4, 0x30, 0x81, 0xb1, 0xa0, 0x81, 0xae, 0xa0,
+  0x81, 0xab, 0x86, 0x81, 0xa8, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f,
+  0x31, 0x35, 0x31, 0x2e, 0x31, 0x35, 0x31, 0x2e, 0x36, 0x34, 0x2e, 0x34,
+  0x38, 0x2f, 0x63, 0x6e, 0x3d, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x25, 0x32,
+  0x30, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x25, 0x32, 0x30, 0x55, 0x41, 0x54,
+  0x25, 0x32, 0x30, 0x49, 0x6e, 0x66, 0x72, 0x61, 0x73, 0x74, 0x72, 0x75,
+  0x63, 0x74, 0x75, 0x72, 0x65, 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32,
+  0x30, 0x30, 0x32, 0x2c, 0x6f, 0x75, 0x3d, 0x57, 0x65, 0x6c, 0x6c, 0x73,
+  0x25, 0x32, 0x30, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x25, 0x32, 0x30, 0x55,
+  0x41, 0x54, 0x25, 0x32, 0x30, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+  0x63, 0x61, 0x74, 0x65, 0x25, 0x32, 0x30, 0x41, 0x75, 0x74, 0x68, 0x6f,
+  0x72, 0x69, 0x74, 0x69, 0x65, 0x73, 0x2c, 0x6f, 0x3d, 0x57, 0x65, 0x6c,
+  0x6c, 0x73, 0x25, 0x32, 0x30, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x2c, 0x63,
+  0x3d, 0x55, 0x53, 0x3f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+  0x61, 0x74, 0x65, 0x52, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f,
+  0x6e, 0x4c, 0x69, 0x73, 0x74, 0x30, 0x81, 0xdf, 0x06, 0x08, 0x2b, 0x06,
+  0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x81, 0xd2, 0x30, 0x81, 0xcf,
+  0x30, 0x81, 0xa9, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30,
+  0x02, 0x86, 0x81, 0x9c, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x31,
+  0x35, 0x31, 0x2e, 0x31, 0x35, 0x31, 0x2e, 0x36, 0x34, 0x2e, 0x34, 0x38,
+  0x2f, 0x63, 0x6e, 0x3d, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x25, 0x32, 0x30,
+  0x46, 0x61, 0x72, 0x67, 0x6f, 0x25, 0x32, 0x30, 0x55, 0x41, 0x54, 0x25,
+  0x32, 0x30, 0x49, 0x6e, 0x66, 0x72, 0x61, 0x73, 0x74, 0x72, 0x75, 0x63,
+  0x74, 0x75, 0x72, 0x65, 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30,
+  0x30, 0x32, 0x2c, 0x6f, 0x75, 0x3d, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x25,
+  0x32, 0x30, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x25, 0x32, 0x30, 0x55, 0x41,
+  0x54, 0x25, 0x32, 0x30, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+  0x61, 0x74, 0x65, 0x25, 0x32, 0x30, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+  0x69, 0x74, 0x69, 0x65, 0x73, 0x2c, 0x6f, 0x3d, 0x57, 0x65, 0x6c, 0x6c,
+  0x73, 0x25, 0x32, 0x30, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x2c, 0x63, 0x3d,
+  0x55, 0x53, 0x3f, 0x63, 0x41, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+  0x63, 0x61, 0x74, 0x65, 0x30, 0x21, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+  0x05, 0x07, 0x30, 0x01, 0x86, 0x15, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+  0x2f, 0x31, 0x35, 0x31, 0x2e, 0x31, 0x35, 0x31, 0x2e, 0x36, 0x34, 0x2e,
+  0x34, 0x36, 0x2f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x05,
+  0xcf, 0xdc, 0x26, 0x62, 0x74, 0x4b, 0x3d, 0x75, 0x63, 0x68, 0xd7, 0x6e,
+  0x95, 0xd5, 0x8f, 0xb5, 0xda, 0x76, 0x56, 0xbb, 0x30, 0x34, 0x15, 0x87,
+  0x48, 0xe5, 0xca, 0x26, 0x5a, 0x70, 0x2f, 0x04, 0x8c, 0x4a, 0x1b, 0x36,
+  0x9b, 0x35, 0xbd, 0xef, 0x4b, 0xef, 0xe9, 0xe2, 0x62, 0x1c, 0xd2, 0x87,
+  0x05, 0x1f, 0x8f, 0xee, 0x8d, 0x82, 0xe0, 0x5c, 0x04, 0x46, 0xb8, 0x73,
+  0x65, 0x4f, 0x75, 0x3f, 0x34, 0x06, 0x77, 0x06, 0x87, 0x4d, 0xd1, 0x65,
+  0xf5, 0xc0, 0x3f, 0xbd, 0x44, 0x8b, 0x08, 0x55, 0x40, 0x6d, 0x83, 0x5f,
+  0x8d, 0x1a, 0x28, 0x5d, 0x49, 0x1d, 0x9d, 0xec, 0x47, 0xbc, 0x9b, 0x41,
+  0x6d, 0x5a, 0xb1, 0x46, 0xc1, 0x23, 0xec, 0x2a, 0xe9, 0xe7, 0xd9, 0xff,
+  0xe8, 0xdb, 0xeb, 0x16, 0x54, 0x4a, 0x89, 0xa0, 0x3e, 0xad, 0x70, 0x6d,
+  0xc4, 0x52, 0xd1, 0xc6, 0x8a, 0x2c, 0xd2, 0x0b, 0x5f, 0x1f, 0xd8, 0xa3,
+  0x90, 0x63, 0x2d, 0x62, 0xd8, 0x95, 0xda, 0x45, 0xc2, 0x4e, 0x5b, 0xbc,
+  0x63, 0xb9, 0xe0, 0x36, 0xa4, 0x6a, 0xdf, 0x9c, 0x25, 0x2f, 0xbd, 0xb8,
+  0x80, 0x36, 0x29, 0x94, 0xa6, 0xbb, 0xd0, 0x17, 0x45, 0xc7, 0xea, 0xf0,
+  0x28, 0x06, 0xdc, 0xf4, 0xc8, 0xb0, 0xca, 0xa7, 0x2e, 0xdb, 0x85, 0x82,
+  0xe1, 0xd5, 0x60, 0x31, 0xd6, 0xe6, 0xf5, 0x27, 0x09, 0xe0, 0x1b, 0xae,
+  0xfc, 0x8f, 0xd4, 0xa5, 0xe4, 0xa6, 0x2f, 0x28, 0xa0, 0xb0, 0x78, 0xad,
+  0xb0, 0x03, 0xc0, 0x94, 0x37, 0x0c, 0xad, 0x6c, 0x12, 0x12, 0x18, 0x58,
+  0x43, 0x68, 0xdf, 0xea, 0x56, 0x1c, 0xfb, 0x7d, 0xfc, 0x1c, 0xf2, 0xc5,
+  0x9c, 0x06, 0x18, 0x52, 0xcf, 0xb1, 0xc3, 0xfb, 0x40, 0x2c, 0x56, 0xac,
+  0x7c, 0xfd, 0x56, 0x0e, 0xe4, 0x9e, 0x8a, 0x9e, 0x83, 0xf4, 0x77, 0xb2,
+  0x24, 0x3c, 0xd2, 0x30, 0x82, 0x06, 0x2e, 0x30, 0x82, 0x05, 0x16, 0xa0,
+  0x03, 0x02, 0x01, 0x02, 0x02, 0x0a, 0x61, 0x04, 0xaa, 0x36, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x8f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, 0x84, 0x31, 0x0b,
+  0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
+  0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x57, 0x65,
+  0x6c, 0x6c, 0x73, 0x20, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x31, 0x30, 0x30,
+  0x2e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x27, 0x57, 0x65, 0x6c, 0x6c,
+  0x73, 0x20, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x20, 0x55, 0x41, 0x54, 0x20,
+  0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20,
+  0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x65, 0x73, 0x31,
+  0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x24, 0x57, 0x65,
+  0x6c, 0x6c, 0x73, 0x20, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x20, 0x55, 0x41,
+  0x54, 0x20, 0x49, 0x6e, 0x66, 0x72, 0x61, 0x73, 0x74, 0x72, 0x75, 0x63,
+  0x74, 0x75, 0x72, 0x65, 0x20, 0x43, 0x41, 0x20, 0x30, 0x32, 0x30, 0x1e,
+  0x17, 0x0d, 0x31, 0x31, 0x30, 0x38, 0x31, 0x38, 0x31, 0x38, 0x34, 0x32,
+  0x30, 0x30, 0x5a, 0x17, 0x0d, 0x31, 0x33, 0x30, 0x38, 0x31, 0x37, 0x31,
+  0x38, 0x34, 0x32, 0x30, 0x30, 0x5a, 0x30, 0x72, 0x31, 0x0b, 0x30, 0x09,
+  0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x14, 0x30,
+  0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x57, 0x65, 0x6c, 0x6c,
+  0x73, 0x20, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x31, 0x0c, 0x30, 0x0a, 0x06,
+  0x03, 0x55, 0x04, 0x0b, 0x13, 0x03, 0x50, 0x4b, 0x49, 0x31, 0x16, 0x30,
+  0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x57, 0x49, 0x46, 0x43,
+  0x41, 0x30, 0x32, 0x55, 0x2d, 0x4e, 0x44, 0x45, 0x53, 0x31, 0x27, 0x30,
+  0x25, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01,
+  0x16, 0x18, 0x70, 0x6b, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x40,
+  0x77, 0x65, 0x6c, 0x6c, 0x73, 0x66, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x63,
+  0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
+  0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc2,
+  0xe4, 0x15, 0x91, 0x10, 0xde, 0x1b, 0xd9, 0x6f, 0xe4, 0xde, 0xc4, 0x42,
+  0xd4, 0xfb, 0x91, 0xce, 0x4c, 0xb1, 0x5a, 0xb5, 0x88, 0xc9, 0xdc, 0xb7,
+  0xa0, 0xa6, 0x1c, 0x7d, 0x4a, 0x06, 0xa2, 0xa0, 0x38, 0x83, 0x05, 0xbe,
+  0xe5, 0x7e, 0xb0, 0x38, 0x16, 0x32, 0x89, 0xa1, 0xa0, 0xe4, 0xbe, 0x8c,
+  0x19, 0x13, 0xec, 0x59, 0x4d, 0x8d, 0x47, 0x6d, 0x7d, 0x3e, 0x14, 0x84,
+  0x46, 0x65, 0xd0, 0xe9, 0x5d, 0x46, 0x39, 0xcb, 0x40, 0xbd, 0xa5, 0xc3,
+  0x9c, 0xf6, 0xed, 0x20, 0x9a, 0x12, 0x3b, 0x7d, 0x54, 0x3b, 0xdd, 0xb7,
+  0x0b, 0x82, 0xce, 0x4d, 0x8f, 0x06, 0x1a, 0x72, 0x45, 0x59, 0x28, 0x04,
+  0xb3, 0xb4, 0x74, 0x91, 0x90, 0xd3, 0x2d, 0x8f, 0x17, 0x4a, 0x56, 0x8b,
+  0xdb, 0x4d, 0x42, 0x95, 0x23, 0x90, 0xe2, 0x0d, 0x49, 0x5b, 0x68, 0x43,
+  0x2d, 0xeb, 0xec, 0x5c, 0x4e, 0x33, 0xb5, 0x0b, 0x15, 0xcd, 0xa3, 0xd1,
+  0xb7, 0xa9, 0x3b, 0xf4, 0x14, 0xd9, 0xe7, 0x9c, 0xc5, 0xa3, 0x7e, 0x26,
+  0x61, 0xf8, 0x69, 0x91, 0x54, 0xec, 0x5a, 0xee, 0x1b, 0xce, 0x70, 0xfa,
+  0xed, 0xe3, 0x1c, 0x27, 0x2e, 0x54, 0x2f, 0xd1, 0xab, 0xee, 0xad, 0x64,
+  0x9b, 0xe6, 0xc6, 0xc5, 0x3a, 0x47, 0x0a, 0x74, 0x5e, 0x92, 0xd3, 0xd1,
+  0x68, 0x85, 0x87, 0x91, 0xa8, 0xde, 0x3b, 0xff, 0x99, 0x60, 0xe4, 0x53,
+  0x45, 0xbe, 0x15, 0x8c, 0xed, 0x52, 0x9b, 0x69, 0x5b, 0x77, 0x70, 0xcd,
+  0x71, 0x46, 0x30, 0x68, 0x0b, 0xe0, 0x1f, 0x4e, 0x1a, 0x60, 0xb3, 0x45,
+  0x9c, 0xfa, 0xd7, 0x33, 0x50, 0xb8, 0x7f, 0x07, 0x3d, 0xff, 0xcc, 0x95,
+  0x3a, 0xca, 0xb3, 0x83, 0xc0, 0x4c, 0x58, 0x43, 0x67, 0x52, 0x62, 0x81,
+  0x29, 0x73, 0x46, 0x59, 0x3b, 0xbe, 0x31, 0x1a, 0xba, 0xd8, 0x6c, 0x08,
+  0xf6, 0xb5, 0xf5, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x02, 0xb1,
+  0x30, 0x82, 0x02, 0xad, 0x30, 0x29, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04,
+  0x01, 0x82, 0x37, 0x14, 0x02, 0x04, 0x1c, 0x1e, 0x1a, 0x00, 0x43, 0x00,
+  0x45, 0x00, 0x50, 0x00, 0x45, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x72, 0x00,
+  0x79, 0x00, 0x70, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x30,
+  0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0x20,
+  0x30, 0x15, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0e, 0x30, 0x0c, 0x06,
+  0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x01, 0x30,
+  0x78, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x0f,
+  0x04, 0x6b, 0x30, 0x69, 0x30, 0x0e, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x03, 0x02, 0x02, 0x02, 0x00, 0x80, 0x30, 0x0e, 0x06, 0x08,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x04, 0x02, 0x02, 0x00, 0x80,
+  0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01,
+  0x2a, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
+  0x01, 0x2d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
+  0x04, 0x01, 0x02, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
+  0x03, 0x04, 0x01, 0x05, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
+  0x07, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03,
+  0x07, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
+  0x45, 0x48, 0xc3, 0x30, 0x38, 0xf5, 0x05, 0x84, 0x43, 0x21, 0x85, 0xfc,
+  0xb2, 0xb8, 0x0f, 0x0a, 0x34, 0x78, 0x74, 0x94, 0x30, 0x1f, 0x06, 0x03,
+  0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x05, 0x53, 0x0b,
+  0x60, 0x25, 0x90, 0xfc, 0x1c, 0x7d, 0xd5, 0xbc, 0x82, 0x11, 0x26, 0xc5,
+  0xd5, 0x11, 0xd4, 0x79, 0x89, 0x30, 0x81, 0xbf, 0x06, 0x03, 0x55, 0x1d,
+  0x1f, 0x04, 0x81, 0xb7, 0x30, 0x81, 0xb4, 0x30, 0x81, 0xb1, 0xa0, 0x81,
+  0xae, 0xa0, 0x81, 0xab, 0x86, 0x81, 0xa8, 0x6c, 0x64, 0x61, 0x70, 0x3a,
+  0x2f, 0x2f, 0x31, 0x35, 0x31, 0x2e, 0x31, 0x35, 0x31, 0x2e, 0x36, 0x34,
+  0x2e, 0x34, 0x38, 0x2f, 0x63, 0x6e, 0x3d, 0x57, 0x65, 0x6c, 0x6c, 0x73,
+  0x25, 0x32, 0x30, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x25, 0x32, 0x30, 0x55,
+  0x41, 0x54, 0x25, 0x32, 0x30, 0x49, 0x6e, 0x66, 0x72, 0x61, 0x73, 0x74,
+  0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x25, 0x32, 0x30, 0x43, 0x41,
+  0x25, 0x32, 0x30, 0x30, 0x32, 0x2c, 0x6f, 0x75, 0x3d, 0x57, 0x65, 0x6c,
+  0x6c, 0x73, 0x25, 0x32, 0x30, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x25, 0x32,
+  0x30, 0x55, 0x41, 0x54, 0x25, 0x32, 0x30, 0x43, 0x65, 0x72, 0x74, 0x69,
+  0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x25, 0x32, 0x30, 0x41, 0x75, 0x74,
+  0x68, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x65, 0x73, 0x2c, 0x6f, 0x3d, 0x57,
+  0x65, 0x6c, 0x6c, 0x73, 0x25, 0x32, 0x30, 0x46, 0x61, 0x72, 0x67, 0x6f,
+  0x2c, 0x63, 0x3d, 0x55, 0x53, 0x3f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66,
+  0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74,
+  0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x30, 0x81, 0xdf, 0x06, 0x08,
+  0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x81, 0xd2, 0x30,
+  0x81, 0xcf, 0x30, 0x81, 0xa9, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+  0x07, 0x30, 0x02, 0x86, 0x81, 0x9c, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f,
+  0x2f, 0x31, 0x35, 0x31, 0x2e, 0x31, 0x35, 0x31, 0x2e, 0x36, 0x34, 0x2e,
+  0x34, 0x38, 0x2f, 0x63, 0x6e, 0x3d, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x25,
+  0x32, 0x30, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x25, 0x32, 0x30, 0x55, 0x41,
+  0x54, 0x25, 0x32, 0x30, 0x49, 0x6e, 0x66, 0x72, 0x61, 0x73, 0x74, 0x72,
+  0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x25, 0x32, 0x30, 0x43, 0x41, 0x25,
+  0x32, 0x30, 0x30, 0x32, 0x2c, 0x6f, 0x75, 0x3d, 0x57, 0x65, 0x6c, 0x6c,
+  0x73, 0x25, 0x32, 0x30, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x25, 0x32, 0x30,
+  0x55, 0x41, 0x54, 0x25, 0x32, 0x30, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+  0x69, 0x63, 0x61, 0x74, 0x65, 0x25, 0x32, 0x30, 0x41, 0x75, 0x74, 0x68,
+  0x6f, 0x72, 0x69, 0x74, 0x69, 0x65, 0x73, 0x2c, 0x6f, 0x3d, 0x57, 0x65,
+  0x6c, 0x6c, 0x73, 0x25, 0x32, 0x30, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x2c,
+  0x63, 0x3d, 0x55, 0x53, 0x3f, 0x63, 0x41, 0x43, 0x65, 0x72, 0x74, 0x69,
+  0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x30, 0x21, 0x06, 0x08, 0x2b, 0x06,
+  0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x15, 0x68, 0x74, 0x74, 0x70,
+  0x3a, 0x2f, 0x2f, 0x31, 0x35, 0x31, 0x2e, 0x31, 0x35, 0x31, 0x2e, 0x36,
+  0x34, 0x2e, 0x34, 0x36, 0x2f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01,
+  0x00, 0x01, 0xaa, 0xce, 0x9d, 0x20, 0x7e, 0x52, 0x2c, 0x9a, 0xdf, 0x41,
+  0xc7, 0x2d, 0x22, 0x23, 0xe8, 0x7c, 0xb5, 0xb9, 0x51, 0x52, 0xd8, 0xbd,
+  0x8b, 0x1c, 0x5d, 0x40, 0x78, 0x40, 0x7e, 0xbe, 0x62, 0xec, 0x26, 0xed,
+  0x7d, 0xe3, 0xbc, 0x43, 0xcb, 0xb9, 0x50, 0x98, 0x94, 0x2c, 0x52, 0xa5,
+  0x70, 0x49, 0x93, 0xe2, 0x6f, 0x76, 0xfc, 0xc0, 0xc6, 0x58, 0x20, 0x91,
+  0xf2, 0xc1, 0xc0, 0x60, 0x55, 0x30, 0x20, 0x24, 0xba, 0x3a, 0xba, 0xd5,
+  0x74, 0xda, 0x48, 0x09, 0xfd, 0x8a, 0xaf, 0x2b, 0x2b, 0xcf, 0x99, 0x82,
+  0x6c, 0xb2, 0xc0, 0xd8, 0x30, 0x3c, 0x7a, 0xc3, 0x34, 0xc8, 0xf8, 0x71,
+  0x64, 0x3d, 0xb1, 0x79, 0xd2, 0x19, 0x7b, 0x47, 0x05, 0x2d, 0x4a, 0xba,
+  0xc4, 0x23, 0x3f, 0x6f, 0xbc, 0x03, 0x95, 0x91, 0xf2, 0xf8, 0x11, 0xdc,
+  0xa1, 0x1a, 0x6c, 0x6b, 0x3b, 0x01, 0x1b, 0x05, 0xf8, 0x59, 0x7e, 0xf5,
+  0x68, 0x79, 0xed, 0x35, 0x82, 0x3e, 0xd8, 0xee, 0x74, 0x05, 0xd2, 0x2f,
+  0x67, 0xe5, 0x07, 0x0b, 0xb3, 0x7a, 0xb8, 0x10, 0x9f, 0x39, 0x59, 0xc0,
+  0xbf, 0x00, 0x1b, 0x64, 0x67, 0xa4, 0x6f, 0xb9, 0x4b, 0xcf, 0x25, 0x2b,
+  0x77, 0x11, 0x01, 0xa9, 0xf2, 0xeb, 0xd2, 0xec, 0xb2, 0xa5, 0xa8, 0x29,
+  0x32, 0x62, 0x94, 0x13, 0x57, 0xe8, 0x4a, 0x19, 0xd8, 0xb8, 0xee, 0x16,
+  0x75, 0xd3, 0x1b, 0x1c, 0x10, 0x34, 0x99, 0xb8, 0x18, 0x06, 0x36, 0xec,
+  0xc8, 0x76, 0x88, 0xbc, 0xcd, 0xde, 0xa9, 0x09, 0x8b, 0xf2, 0x91, 0xaa,
+  0x7a, 0x47, 0xc7, 0x35, 0xf0, 0xee, 0xd2, 0x6b, 0x70, 0x37, 0xd6, 0x97,
+  0x2b, 0x49, 0x92, 0xe2, 0xe8, 0xe5, 0xc1, 0x54, 0x86, 0xfe, 0x38, 0xe4,
+  0x09, 0x7a, 0x8a, 0x71, 0x8d, 0x4b, 0xc3, 0xd4, 0x0f, 0xc3, 0xa2, 0x14,
+  0x91, 0xc6, 0xb9, 0xd5, 0xbc, 0x30, 0x82, 0x05, 0x2a, 0x30, 0x82, 0x04,
+  0x12, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x01, 0x99, 0x1d, 0x09,
+  0xc6, 0xf9, 0xdc, 0xab, 0x47, 0x1a, 0x7b, 0x3c, 0x5a, 0x8d, 0x5e, 0x80,
+  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+  0x05, 0x05, 0x00, 0x30, 0x81, 0x95, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+  0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06,
+  0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x20,
+  0x46, 0x61, 0x72, 0x67, 0x6f, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55,
+  0x04, 0x0b, 0x13, 0x27, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x20, 0x46, 0x61,
+  0x72, 0x67, 0x6f, 0x20, 0x55, 0x41, 0x54, 0x20, 0x43, 0x65, 0x72, 0x74,
+  0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
+  0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x3e, 0x30, 0x3c, 0x06,
+  0x03, 0x55, 0x04, 0x03, 0x13, 0x35, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x20,
+  0x46, 0x61, 0x72, 0x67, 0x6f, 0x20, 0x55, 0x41, 0x54, 0x20, 0x49, 0x6e,
+  0x74, 0x72, 0x61, 0x6e, 0x65, 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
+  0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+  0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30,
+  0x20, 0x17, 0x0d, 0x30, 0x39, 0x30, 0x39, 0x30, 0x39, 0x30, 0x31, 0x30,
+  0x33, 0x33, 0x36, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x35, 0x39, 0x30, 0x39,
+  0x30, 0x39, 0x30, 0x31, 0x31, 0x31, 0x33, 0x31, 0x5a, 0x30, 0x81, 0x95,
+  0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+  0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b,
+  0x57, 0x65, 0x6c, 0x6c, 0x73, 0x20, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x31,
+  0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x27, 0x57, 0x65,
+  0x6c, 0x6c, 0x73, 0x20, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x20, 0x55, 0x41,
+  0x54, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+  0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
+  0x79, 0x31, 0x3e, 0x30, 0x3c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x35,
+  0x57, 0x65, 0x6c, 0x6c, 0x73, 0x20, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x20,
+  0x55, 0x41, 0x54, 0x20, 0x49, 0x6e, 0x74, 0x72, 0x61, 0x6e, 0x65, 0x74,
+  0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+  0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68,
+  0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06,
+  0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
+  0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01,
+  0x01, 0x00, 0xdd, 0xec, 0xca, 0xdf, 0xbc, 0xa8, 0x59, 0x74, 0xec, 0x18,
+  0xca, 0x3f, 0x1a, 0x62, 0xd9, 0x8e, 0x33, 0xb5, 0x52, 0x0f, 0xfd, 0x03,
+  0x45, 0x38, 0x71, 0xb4, 0xe9, 0x18, 0xf9, 0x4a, 0xd5, 0xbc, 0xa1, 0x95,
+  0x1b, 0xc4, 0x8e, 0x3e, 0x26, 0xf1, 0xb8, 0xf9, 0x92, 0x3f, 0x30, 0xd2,
+  0x03, 0x3b, 0x41, 0xf5, 0xea, 0xfd, 0x69, 0x3d, 0x4e, 0x5d, 0x61, 0xe2,
+  0x5f, 0xfb, 0x91, 0xb2, 0xcb, 0xdf, 0x1b, 0x37, 0xec, 0xa8, 0x62, 0xd5,
+  0xd0, 0xbc, 0x27, 0xc8, 0x84, 0x96, 0x82, 0xf9, 0x88, 0xea, 0xa2, 0x63,
+  0x56, 0xfe, 0xcd, 0xd4, 0x5f, 0x26, 0xc8, 0x28, 0x39, 0x80, 0xc1, 0x01,
+  0x33, 0xb5, 0x4d, 0xcc, 0x51, 0xd3, 0xd2, 0x8d, 0x99, 0xe6, 0x33, 0x12,
+  0x7a, 0xc4, 0x2f, 0x01, 0x06, 0xfb, 0x72, 0x4d, 0x1c, 0xb5, 0xd0, 0x16,
+  0x23, 0xb1, 0x6b, 0x91, 0xb0, 0x01, 0x67, 0x3e, 0x8d, 0xa8, 0x75, 0xff,
+  0x9c, 0xbb, 0xf2, 0x21, 0xe5, 0xec, 0xdc, 0x13, 0xa0, 0x80, 0x3b, 0xa2,
+  0x21, 0x4c, 0xeb, 0x27, 0xbb, 0xc9, 0x6d, 0x99, 0xc8, 0x5f, 0x4b, 0xad,
+  0xe2, 0x50, 0xa3, 0x9d, 0x32, 0xac, 0x9c, 0x6c, 0x7c, 0x4c, 0x89, 0x0a,
+  0xdd, 0x9d, 0x50, 0x40, 0x8e, 0x4a, 0xfe, 0xf5, 0xd2, 0x4f, 0xff, 0x0e,
+  0xc2, 0xe8, 0x50, 0x2f, 0x3d, 0xd4, 0xb5, 0x64, 0x8d, 0xa5, 0x72, 0x8b,
+  0xb5, 0x37, 0x3a, 0x24, 0x7e, 0xaf, 0x96, 0x55, 0x8e, 0xd4, 0xc6, 0x77,
+  0x09, 0x0b, 0xf2, 0x08, 0xe4, 0x6f, 0x10, 0xba, 0xf2, 0x06, 0xe8, 0xe4,
+  0x86, 0x00, 0x78, 0xa3, 0xdd, 0xe6, 0xed, 0x47, 0xbf, 0xdb, 0xba, 0xae,
+  0x5b, 0x5c, 0x8d, 0x70, 0xf9, 0xb6, 0x57, 0xc9, 0x64, 0xa8, 0x32, 0xcf,
+  0xe9, 0x10, 0xab, 0xc4, 0x47, 0x91, 0xae, 0x5b, 0xca, 0xab, 0x34, 0x21,
+  0xbe, 0xa1, 0xbc, 0x1d, 0xb5, 0xe9, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
+  0x82, 0x01, 0x70, 0x30, 0x82, 0x01, 0x6c, 0x30, 0x0b, 0x06, 0x03, 0x55,
+  0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x0f, 0x06, 0x03,
+  0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01,
+  0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
+  0x8d, 0xe5, 0x35, 0x30, 0xe9, 0x30, 0x29, 0x07, 0x61, 0xf5, 0x85, 0x2d,
+  0xce, 0xeb, 0x43, 0x40, 0x13, 0x87, 0xf7, 0x23, 0x30, 0x10, 0x06, 0x09,
+  0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x01, 0x04, 0x03, 0x02,
+  0x01, 0x00, 0x30, 0x82, 0x01, 0x19, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04,
+  0x82, 0x01, 0x10, 0x30, 0x82, 0x01, 0x0c, 0x30, 0x81, 0x90, 0x06, 0x0b,
+  0x60, 0x86, 0x48, 0x01, 0x86, 0xfb, 0x7b, 0x83, 0x74, 0x00, 0x00, 0x30,
+  0x81, 0x80, 0x30, 0x54, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+  0x02, 0x02, 0x30, 0x48, 0x1e, 0x46, 0x00, 0x57, 0x00, 0x65, 0x00, 0x6c,
+  0x00, 0x6c, 0x00, 0x73, 0x00, 0x53, 0x00, 0x65, 0x00, 0x63, 0x00, 0x75,
+  0x00, 0x72, 0x00, 0x65, 0x00, 0xae, 0x00, 0x20, 0x00, 0x50, 0x00, 0x4b,
+  0x00, 0x49, 0x00, 0x20, 0x00, 0x43, 0x00, 0x65, 0x00, 0x72, 0x00, 0x74,
+  0x00, 0x69, 0x00, 0x66, 0x00, 0x69, 0x00, 0x63, 0x00, 0x61, 0x00, 0x74,
+  0x00, 0x65, 0x00, 0x20, 0x00, 0x50, 0x00, 0x6f, 0x00, 0x6c, 0x00, 0x69,
+  0x00, 0x63, 0x00, 0x79, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+  0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+  0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x65, 0x6c, 0x6c, 0x73, 0x66, 0x61,
+  0x72, 0x67, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x30, 0x77,
+  0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, 0x86, 0xfb, 0x7b, 0x83, 0x74, 0x00,
+  0x01, 0x30, 0x68, 0x30, 0x3c, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+  0x07, 0x02, 0x02, 0x30, 0x30, 0x1e, 0x2e, 0x20, 0x1d, 0x00, 0x49, 0x00,
+  0x6e, 0x00, 0x66, 0x00, 0x72, 0x00, 0x61, 0x00, 0x73, 0x00, 0x74, 0x00,
+  0x72, 0x00, 0x75, 0x00, 0x63, 0x00, 0x74, 0x00, 0x75, 0x00, 0x72, 0x00,
+  0x65, 0x00, 0x20, 0x00, 0x50, 0x00, 0x6f, 0x00, 0x6c, 0x00, 0x69, 0x00,
+  0x63, 0x00, 0x79, 0x20, 0x1d, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01,
+  0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74, 0x70, 0x3a,
+  0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x65, 0x6c, 0x6c, 0x73, 0x66,
+  0x61, 0x72, 0x67, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x30,
+  0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
+  0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x32, 0x05, 0x09, 0xa9, 0xb6,
+  0x72, 0xa9, 0x12, 0xcb, 0x45, 0xef, 0x1d, 0x1d, 0x74, 0xc3, 0x68, 0xed,
+  0xad, 0x8b, 0xc3, 0x80, 0xc1, 0x41, 0x34, 0x47, 0xc1, 0x3b, 0xca, 0xae,
+  0x0f, 0x11, 0x9b, 0x1d, 0xd3, 0x7a, 0x2f, 0x70, 0xab, 0xdf, 0xc0, 0xfe,
+  0x02, 0xf5, 0x0c, 0xde, 0xf8, 0xa9, 0xe0, 0x16, 0x94, 0x1a, 0x19, 0x30,
+  0x66, 0x44, 0x13, 0xec, 0xbe, 0x7c, 0x79, 0x9d, 0x68, 0xe9, 0x91, 0x22,
+  0xe4, 0xd2, 0x3f, 0x08, 0xee, 0xc7, 0xa3, 0x5f, 0xe1, 0x01, 0xe3, 0x33,
+  0xb2, 0x4d, 0x80, 0x1a, 0x78, 0x23, 0x2b, 0x3f, 0xb4, 0x91, 0x93, 0xfd,
+  0xb4, 0x3e, 0xb4, 0xb6, 0x5b, 0x5e, 0x12, 0xcc, 0x55, 0x6e, 0xc2, 0x4f,
+  0xc6, 0x65, 0x8f, 0x33, 0x71, 0x4d, 0x87, 0xc2, 0x20, 0x61, 0x48, 0x0a,
+  0xb0, 0x7d, 0x4c, 0x80, 0xed, 0x17, 0x05, 0xc0, 0xf1, 0xff, 0xbe, 0xb0,
+  0xa4, 0xb0, 0x41, 0x88, 0xac, 0x19, 0xc6, 0x08, 0x24, 0xc7, 0x5b, 0xe6,
+  0xc6, 0x1e, 0xe3, 0x0c, 0x6f, 0xbc, 0xe4, 0xb3, 0x38, 0xc8, 0xa6, 0xea,
+  0x97, 0x5a, 0xcc, 0x2f, 0xa9, 0x6b, 0x1f, 0x8e, 0x26, 0x1d, 0x7a, 0x72,
+  0x0a, 0xa7, 0xcf, 0xab, 0xa0, 0x69, 0xe2, 0x07, 0x05, 0x0d, 0xb5, 0x64,
+  0x9d, 0xca, 0x06, 0x6d, 0xe5, 0x93, 0x30, 0xd4, 0x50, 0xac, 0x14, 0xfc,
+  0x50, 0xcc, 0x67, 0x5f, 0x8f, 0x2b, 0x19, 0xb5, 0x6c, 0xed, 0xee, 0xe7,
+  0x2f, 0x97, 0xdd, 0x43, 0x38, 0x76, 0x39, 0x6f, 0x6e, 0xb2, 0x0e, 0x5a,
+  0x54, 0xba, 0x67, 0xcc, 0x32, 0xdf, 0x4f, 0x5c, 0x01, 0xc1, 0x56, 0x69,
+  0xb2, 0x35, 0x55, 0x29, 0x3f, 0xf9, 0x7d, 0x42, 0x60, 0x23, 0xa8, 0x8d,
+  0x6a, 0xc3, 0x15, 0xfc, 0xc1, 0xdc, 0x0d, 0x26, 0x3d, 0xec, 0x33, 0x21,
+  0xef, 0x61, 0x90, 0x3b, 0x4f, 0x54, 0x3c, 0xfc, 0x88, 0x07, 0x61, 0x30,
+  0x82, 0x06, 0x35, 0x30, 0x82, 0x05, 0x1d, 0xa0, 0x03, 0x02, 0x01, 0x02,
+  0x02, 0x0a, 0x61, 0x09, 0x2f, 0xde, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+  0x05, 0x05, 0x00, 0x30, 0x81, 0x95, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+  0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06,
+  0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x20,
+  0x46, 0x61, 0x72, 0x67, 0x6f, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55,
+  0x04, 0x0b, 0x13, 0x27, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x20, 0x46, 0x61,
+  0x72, 0x67, 0x6f, 0x20, 0x55, 0x41, 0x54, 0x20, 0x43, 0x65, 0x72, 0x74,
+  0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
+  0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x3e, 0x30, 0x3c, 0x06,
+  0x03, 0x55, 0x04, 0x03, 0x13, 0x35, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x20,
+  0x46, 0x61, 0x72, 0x67, 0x6f, 0x20, 0x55, 0x41, 0x54, 0x20, 0x49, 0x6e,
+  0x74, 0x72, 0x61, 0x6e, 0x65, 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
+  0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+  0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30,
+  0x20, 0x17, 0x0d, 0x31, 0x30, 0x30, 0x38, 0x32, 0x35, 0x32, 0x33, 0x33,
+  0x33, 0x31, 0x34, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x35, 0x30, 0x30, 0x38,
+  0x32, 0x35, 0x32, 0x33, 0x34, 0x33, 0x31, 0x34, 0x5a, 0x30, 0x81, 0x84,
+  0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+  0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b,
+  0x57, 0x65, 0x6c, 0x6c, 0x73, 0x20, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x31,
+  0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x27, 0x57, 0x65,
+  0x6c, 0x6c, 0x73, 0x20, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x20, 0x55, 0x41,
+  0x54, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+  0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x65,
+  0x73, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x24,
+  0x57, 0x65, 0x6c, 0x6c, 0x73, 0x20, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x20,
+  0x55, 0x41, 0x54, 0x20, 0x49, 0x6e, 0x66, 0x72, 0x61, 0x73, 0x74, 0x72,
+  0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x20, 0x43, 0x41, 0x20, 0x30, 0x32,
+  0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00,
+  0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd0, 0xc4, 0xbe,
+  0xfa, 0x94, 0x9c, 0x17, 0xd9, 0xff, 0xa7, 0x03, 0x82, 0xcd, 0x06, 0x73,
+  0xa1, 0x43, 0x34, 0x08, 0x0c, 0x45, 0xf0, 0xaf, 0x37, 0x19, 0x71, 0x99,
+  0x8b, 0xfb, 0xd0, 0xfa, 0xbe, 0xcb, 0xbb, 0xee, 0xb2, 0x02, 0x89, 0xf2,
+  0xa4, 0xea, 0x7b, 0xb6, 0x7c, 0x04, 0x49, 0x48, 0x2d, 0x7f, 0xbd, 0x85,
+  0x31, 0x17, 0x37, 0x20, 0x8f, 0xbf, 0x46, 0x52, 0xb4, 0x5f, 0x37, 0x75,
+  0x89, 0x57, 0x1c, 0xda, 0x5b, 0x62, 0x34, 0x53, 0x64, 0x03, 0x6f, 0x96,
+  0x50, 0x74, 0x45, 0x31, 0xbc, 0x91, 0xf1, 0xed, 0x39, 0x2f, 0xc1, 0x3b,
+  0xa8, 0x9a, 0x8c, 0x42, 0x80, 0x6e, 0xb8, 0x51, 0xe7, 0x40, 0x16, 0x0d,
+  0xcb, 0x9a, 0x68, 0x41, 0x83, 0x5c, 0x62, 0x70, 0x20, 0x60, 0x25, 0x45,
+  0xba, 0xc4, 0xc2, 0xb4, 0xe3, 0x93, 0x8b, 0xfe, 0xfc, 0x79, 0xed, 0x08,
+  0x0a, 0xad, 0x16, 0x64, 0x3a, 0xc0, 0x9e, 0x45, 0xbe, 0xf8, 0xc4, 0x6c,
+  0xfe, 0x57, 0x1b, 0x29, 0xa3, 0xaa, 0x4f, 0xcc, 0x0e, 0x45, 0x07, 0xa7,
+  0x86, 0xd8, 0xfb, 0x2e, 0xab, 0x9b, 0x18, 0xe5, 0xb8, 0xbf, 0x07, 0xb5,
+  0xc4, 0x50, 0x5e, 0xde, 0x13, 0x9b, 0xc1, 0xb4, 0x17, 0x80, 0x55, 0x1d,
+  0xae, 0x7e, 0x66, 0x8e, 0xc0, 0x76, 0x3a, 0xc1, 0x41, 0x24, 0x53, 0x2d,
+  0xb4, 0x63, 0x01, 0x43, 0xa9, 0x83, 0xdf, 0x79, 0xe6, 0xa3, 0xff, 0x91,
+  0x1c, 0xfb, 0xcf, 0xbb, 0x24, 0x70, 0x76, 0x05, 0x4a, 0x98, 0x75, 0xa6,
+  0x65, 0xec, 0x08, 0xb8, 0x2c, 0x96, 0x6c, 0x44, 0xda, 0x6d, 0xda, 0x81,
+  0xd4, 0x83, 0xe2, 0x71, 0xfb, 0xfe, 0x02, 0x35, 0xf0, 0x3a, 0xa1, 0x56,
+  0x74, 0x48, 0xf8, 0xf0, 0xb3, 0x52, 0x95, 0xf5, 0x91, 0x4c, 0x88, 0xde,
+  0x7e, 0x6b, 0xe1, 0x94, 0xc6, 0x32, 0x8d, 0xb0, 0xbc, 0xf6, 0xd0, 0x90,
+  0x6b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x02, 0x92, 0x30, 0x82,
+  0x02, 0x8e, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
+  0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55,
+  0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x05, 0x53, 0x0b, 0x60, 0x25, 0x90,
+  0xfc, 0x1c, 0x7d, 0xd5, 0xbc, 0x82, 0x11, 0x26, 0xc5, 0xd5, 0x11, 0xd4,
+  0x79, 0x89, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03,
+  0x02, 0x01, 0x86, 0x30, 0x12, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01,
+  0x82, 0x37, 0x15, 0x01, 0x04, 0x05, 0x02, 0x03, 0x02, 0x00, 0x03, 0x30,
+  0x23, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x02,
+  0x04, 0x16, 0x04, 0x14, 0x81, 0x4c, 0x7a, 0x5b, 0x2b, 0x50, 0x05, 0x1d,
+  0x21, 0x04, 0x0e, 0x1f, 0x81, 0x50, 0xf3, 0x39, 0x0b, 0x09, 0xcc, 0x8f,
+  0x30, 0x19, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14,
+  0x02, 0x04, 0x0c, 0x1e, 0x0a, 0x00, 0x53, 0x00, 0x75, 0x00, 0x62, 0x00,
+  0x43, 0x00, 0x41, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
+  0x30, 0x16, 0x80, 0x14, 0x8d, 0xe5, 0x35, 0x30, 0xe9, 0x30, 0x29, 0x07,
+  0x61, 0xf5, 0x85, 0x2d, 0xce, 0xeb, 0x43, 0x40, 0x13, 0x87, 0xf7, 0x23,
+  0x30, 0x81, 0xdb, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x81, 0xd3, 0x30,
+  0x81, 0xd0, 0x30, 0x81, 0xcd, 0xa0, 0x81, 0xca, 0xa0, 0x81, 0xc7, 0x86,
+  0x81, 0xc4, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x35, 0x31,
+  0x2e, 0x31, 0x35, 0x31, 0x2e, 0x36, 0x34, 0x2e, 0x34, 0x38, 0x2f, 0x43,
+  0x4e, 0x3d, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x25, 0x32, 0x30, 0x46, 0x61,
+  0x72, 0x67, 0x6f, 0x25, 0x32, 0x30, 0x55, 0x41, 0x54, 0x25, 0x32, 0x30,
+  0x49, 0x6e, 0x74, 0x72, 0x61, 0x6e, 0x65, 0x74, 0x25, 0x32, 0x30, 0x52,
+  0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+  0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x25, 0x32, 0x30, 0x41, 0x75,
+  0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x2c, 0x25, 0x32, 0x30, 0x4f,
+  0x55, 0x3d, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x25, 0x32, 0x30, 0x46, 0x61,
+  0x72, 0x67, 0x6f, 0x25, 0x32, 0x30, 0x55, 0x41, 0x54, 0x25, 0x32, 0x30,
+  0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+  0x6e, 0x25, 0x32, 0x30, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
+  0x79, 0x2c, 0x25, 0x32, 0x30, 0x4f, 0x3d, 0x57, 0x65, 0x6c, 0x6c, 0x73,
+  0x25, 0x32, 0x30, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x2c, 0x25, 0x32, 0x30,
+  0x43, 0x3d, 0x55, 0x53, 0x3f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+  0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69,
+  0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x30, 0x81, 0xfb, 0x06, 0x08, 0x2b,
+  0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x81, 0xee, 0x30, 0x81,
+  0xeb, 0x30, 0x21, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30,
+  0x01, 0x86, 0x15, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x35,
+  0x31, 0x2e, 0x31, 0x35, 0x31, 0x2e, 0x36, 0x34, 0x2e, 0x34, 0x36, 0x2f,
+  0x30, 0x81, 0xc5, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30,
+  0x02, 0x86, 0x81, 0xb8, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x31,
+  0x35, 0x31, 0x2e, 0x31, 0x35, 0x31, 0x2e, 0x36, 0x34, 0x2e, 0x34, 0x38,
+  0x2f, 0x43, 0x4e, 0x3d, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x25, 0x32, 0x30,
+  0x46, 0x61, 0x72, 0x67, 0x6f, 0x25, 0x32, 0x30, 0x55, 0x41, 0x54, 0x25,
+  0x32, 0x30, 0x49, 0x6e, 0x74, 0x72, 0x61, 0x6e, 0x65, 0x74, 0x25, 0x32,
+  0x30, 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43, 0x65, 0x72, 0x74,
+  0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x25, 0x32, 0x30,
+  0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x2c, 0x25, 0x32,
+  0x30, 0x4f, 0x55, 0x3d, 0x57, 0x65, 0x6c, 0x6c, 0x73, 0x25, 0x32, 0x30,
+  0x46, 0x61, 0x72, 0x67, 0x6f, 0x25, 0x32, 0x30, 0x55, 0x41, 0x54, 0x25,
+  0x32, 0x30, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+  0x69, 0x6f, 0x6e, 0x25, 0x32, 0x30, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+  0x69, 0x74, 0x79, 0x2c, 0x25, 0x32, 0x30, 0x4f, 0x3d, 0x57, 0x65, 0x6c,
+  0x6c, 0x73, 0x25, 0x32, 0x30, 0x46, 0x61, 0x72, 0x67, 0x6f, 0x2c, 0x25,
+  0x32, 0x30, 0x43, 0x3d, 0x55, 0x53, 0x3f, 0x63, 0x41, 0x43, 0x65, 0x72,
+  0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,
+  0x82, 0x01, 0x01, 0x00, 0xd8, 0x78, 0x85, 0xe3, 0x2d, 0x56, 0xf7, 0x54,
+  0x51, 0xe1, 0xb9, 0xc6, 0xf6, 0x1e, 0x3c, 0x23, 0x9d, 0xa6, 0x46, 0xff,
+  0x08, 0x19, 0x9f, 0x9f, 0xc9, 0xb8, 0x6e, 0x67, 0xf2, 0x4b, 0x68, 0xbf,
+  0x6b, 0x8d, 0xf4, 0xa3, 0x09, 0x3e, 0x02, 0x8b, 0xff, 0x0e, 0xe2, 0xc4,
+  0x43, 0x60, 0x74, 0x33, 0x62, 0xec, 0xb4, 0x3b, 0xd5, 0xb3, 0xd2, 0xa3,
+  0xaa, 0xe4, 0xac, 0x6a, 0x14, 0xfe, 0x47, 0x6e, 0xcc, 0xd0, 0xfc, 0x80,
+  0x25, 0x0e, 0x43, 0xe4, 0x96, 0x43, 0x22, 0x4b, 0x6b, 0x38, 0x94, 0xa0,
+  0xa8, 0xe2, 0xcd, 0x38, 0x28, 0x7d, 0xb6, 0x9d, 0x44, 0x4b, 0xc6, 0x8a,
+  0x2e, 0xcc, 0x81, 0xaf, 0xe8, 0xfe, 0x9e, 0xf0, 0xe6, 0x40, 0xa3, 0xf3,
+  0xfe, 0x48, 0x98, 0xfb, 0xbe, 0x83, 0xf6, 0xe9, 0xa9, 0x0a, 0x56, 0xcd,
+  0x06, 0x80, 0xaa, 0xb3, 0x1d, 0x66, 0xae, 0x74, 0xcd, 0xc8, 0x85, 0xca,
+  0x30, 0xb2, 0x6d, 0xa2, 0x31, 0x8d, 0x86, 0xf8, 0x28, 0xb9, 0xdf, 0x12,
+  0x47, 0xe2, 0xf3, 0x9e, 0xd5, 0x59, 0x2e, 0x13, 0x97, 0x6f, 0x40, 0xfd,
+  0x2c, 0xf7, 0xda, 0x3e, 0xfc, 0x70, 0xcf, 0xc0, 0x36, 0xf7, 0xf8, 0xf1,
+  0x12, 0xa7, 0xf0, 0x00, 0x9b, 0xb9, 0xf5, 0x5e, 0xd4, 0xa1, 0x99, 0x49,
+  0x53, 0x54, 0xdf, 0x08, 0xa4, 0x5c, 0x31, 0x64, 0x23, 0xe4, 0x70, 0xa4,
+  0xa9, 0x38, 0x7d, 0xf6, 0x3b, 0xaf, 0x38, 0xe2, 0x78, 0xc0, 0x77, 0x2e,
+  0x79, 0x26, 0x90, 0xc3, 0x82, 0xe9, 0x07, 0xa4, 0x20, 0xab, 0xf3, 0xee,
+  0x44, 0xcf, 0x33, 0x6c, 0x35, 0x62, 0x7a, 0x2d, 0x80, 0xed, 0xbe, 0xf4,
+  0x5a, 0x3a, 0x27, 0x2d, 0x56, 0x33, 0xdc, 0x5b, 0x06, 0xde, 0x92, 0x23,
+  0x4a, 0x33, 0x07, 0x2a, 0xa2, 0xbc, 0xfc, 0x90, 0x97, 0x6e, 0xa8, 0x68,
+  0xc8, 0x87, 0x7e, 0x59, 0xe0, 0x87, 0x5b, 0xaf, 0x31, 0x00
+};
+unsigned int getcacert_mdesqa_len = 6034;
diff --git a/sec/Security/Regressions/secitem/si-64-ossl-cms.c b/sec/Security/Regressions/secitem/si-64-ossl-cms.c
new file mode 100644 (file)
index 0000000..bcf008f
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ *  si-64-ossl-cms.c
+ *  Security
+ *
+ *  Created by  on 9/28/09.
+ *  Copyright 2009 Apple Inc. All rights reserved.
+ *
+ */
+#include "si-64-ossl-cms/attached_no_data_signed_data.h"
+#include "si-64-ossl-cms/attached_signed_data.h"
+#include "si-64-ossl-cms/detached_content.h"
+#include "si-64-ossl-cms/detached_signed_data.h"
+#include "si-64-ossl-cms/signer.h"
+#include "si-64-ossl-cms/privkey.h"
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCMS.h>
+#include <Security/SecRSAKey.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecIdentityPriv.h>
+#include <utilities/SecCFWrappers.h>
+
+#include <unistd.h>
+#include <AssertMacros.h>
+
+#include "Security_regressions.h"
+
+/*
+openssl req -new -newkey rsa:512 -x509 -nodes -subj "/O=foo/CN=bar" -out signer.pem
+echo -n "hoi joh" > detached_content
+openssl smime -sign -outform der -signer signer.pem -in detached_content -inkey privkey.pem -out detached_signed_data.der
+openssl smime -nodetach -sign -outform der -signer test.pem -in detached_content -inkey privkey.pem -out attached_signed_data.der
+openssl smime -nodetach -sign -outform der -signer test.pem -inkey privkey.pem -out attached_no_data_signed_data.der < /dev/null
+
+xxd -i detached_content > detached_content.h
+xxd -i attached_no_data_signed_data.der > attached_no_data_signed_data.h
+xxd -i attached_signed_data.der > attached_signed_data.h
+xxd -i detached_signed_data.der > detached_signed_data.h
+
+openssl x509 -in test.pem -outform der -out signer.der
+xxd -i signer.der > signer.h
+
+
+attached difference:
+
+  33 NDEF:       SEQUENCE {
+    <06 09>
+  35    9:         OBJECT IDENTIFIER data (1 2 840 113549 1 7 1)
+    <A0 80>
+  46 NDEF:         [0] {
+    <24 80>
+  48 NDEF:           OCTET STRING {
+    <04 07>
+  50    7:             OCTET STRING 'hoi joh'
+    <00 00>
+         :             }
+    <00 00>
+         :           }
+    <00 00>
+         :         }
+
+  39   22:       SEQUENCE {
+    <06 09>
+  41    9:         OBJECT IDENTIFIER data (1 2 840 113549 1 7 1)
+    <A0 09>
+  52    9:         [0] {
+    <04 07>
+  54    7:           OCTET STRING 'hoi joh'
+         :           }
+         :         }
+
+detached:
+
+    <30 80>
+  33 NDEF:       SEQUENCE {
+    <06 09>
+  35    9:         OBJECT IDENTIFIER data (1 2 840 113549 1 7 1)
+    <00 00>
+         :         }
+
+    <30 0B>
+  39   11:       SEQUENCE {
+    <06 09>
+  41    9:         OBJECT IDENTIFIER data (1 2 840 113549 1 7 1)
+         :         }
+
+attached empty:
+
+    <30 80>
+  33 NDEF:       SEQUENCE {
+    <06 09>
+  35    9:         OBJECT IDENTIFIER data (1 2 840 113549 1 7 1)
+    <A0 80>
+  46 NDEF:         [0] {
+    <24 80>
+  48 NDEF:           OCTET STRING {
+    <00 00>
+         :             }
+    <00 00>
+         :           }
+    <00 00>
+         :         }
+
+    <30 0F>
+  39   15:       SEQUENCE {
+    <06 09>
+  41    9:         OBJECT IDENTIFIER data (1 2 840 113549 1 7 1)
+    <A0 02>
+  52    2:         [0] {
+    <04 00>
+  54    0:           OCTET STRING
+         :             Error: Object has zero length.
+         :           }
+         :         }
+
+
+*/
+
+#include <fcntl.h>
+static inline void write_data(const char * path, CFDataRef data)
+{
+    int data_file = open(path, O_CREAT|O_WRONLY|O_TRUNC, 0644);
+    write(data_file, CFDataGetBytePtr(data), CFDataGetLength(data));
+    close(data_file);
+}
+
+static void tests(void)
+{
+       CFDataRef attached_signed_data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, attached_signed_data_der, attached_signed_data_der_len, kCFAllocatorNull);
+       CFDataRef detached_signed_data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, detached_signed_data_der, detached_signed_data_der_len, kCFAllocatorNull);
+       CFDataRef attached_no_data_signed_data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, attached_no_data_signed_data_der, attached_no_data_signed_data_der_len, kCFAllocatorNull);
+       CFDataRef detached_data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, detached_content, detached_content_len, kCFAllocatorNull);
+       CFDataRef no_data = CFDataCreate(kCFAllocatorDefault, NULL, 0);
+       SecPolicyRef policy = SecPolicyCreateBasicX509();
+       SecTrustRef trust = NULL;
+
+       ok_status(SecCMSVerifyCopyDataAndAttributes(attached_signed_data, NULL, policy, &trust, NULL, NULL), "verify attached data");
+       CFRelease(trust);
+       ok_status(SecCMSVerifyCopyDataAndAttributes(detached_signed_data, detached_data, policy, &trust, NULL, NULL), "verify detached data");
+       CFRelease(trust);
+       ok_status(SecCMSVerifyCopyDataAndAttributes(attached_no_data_signed_data, NULL, policy, &trust, NULL, NULL), "verify attached no data");
+       CFRelease(trust);
+       ok_status(SecCMSVerifyCopyDataAndAttributes(attached_no_data_signed_data, no_data, policy, &trust, NULL, NULL), "verify attached no data");
+       CFRelease(trust);
+
+
+    SecCertificateRef cert = NULL;
+    SecKeyRef privKey = NULL;
+    SecIdentityRef identity = NULL;
+
+    isnt(cert = SecCertificateCreateWithBytes(NULL, signer_der, signer_der_len), NULL, "create certificate");
+    isnt(privKey = SecKeyCreateRSAPrivateKey(NULL, privkey_der, privkey_der_len, kSecKeyEncodingPkcs1), NULL, "create private key");
+    isnt(identity = SecIdentityCreate(NULL, cert, privKey), NULL, "create identity");
+    CFReleaseSafe(privKey);
+
+       CFMutableDataRef cms_data = CFDataCreateMutable(kCFAllocatorDefault, 0);
+       ok_status(SecCMSCreateSignedData(identity, detached_data, NULL, NULL, cms_data), "create attached data");
+       //write_data("/var/tmp/attached", cms_data);
+       CFDataSetLength(cms_data, 0);
+       CFDictionaryRef detached_cms_dict = CFDictionaryCreate(kCFAllocatorDefault, &kSecCMSSignDetached, (const void **)&kCFBooleanTrue, 1, NULL, NULL);
+       ok_status(SecCMSCreateSignedData(identity, detached_data, detached_cms_dict, NULL, cms_data), "create attached data");
+       CFRelease(detached_cms_dict);
+       //write_data("/var/tmp/detached", cms_data);
+       CFDataSetLength(cms_data, 0);
+       ok_status(SecCMSCreateSignedData(identity, NULL, NULL, NULL, cms_data), "create attached data");
+       //write_data("/var/tmp/empty_attached", cms_data);
+
+       CFReleaseSafe(cms_data);
+       CFReleaseSafe(cert);
+       CFReleaseNull(identity);
+       CFRelease(attached_signed_data);
+       CFRelease(detached_signed_data);
+       CFRelease(attached_no_data_signed_data);
+       CFRelease(detached_data);
+       CFRelease(no_data);
+       CFRelease(policy);
+}
+
+int si_64_ossl_cms(int argc, char *const *argv)
+{
+       plan_tests(10);
+
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-64-ossl-cms/attached_no_data_signed_data.h b/sec/Security/Regressions/secitem/si-64-ossl-cms/attached_no_data_signed_data.h
new file mode 100644 (file)
index 0000000..bdb2d66
--- /dev/null
@@ -0,0 +1,72 @@
+unsigned char attached_no_data_signed_data_der[] = {
+  0x30, 0x82, 0x03, 0x30, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x07, 0x02, 0xa0, 0x82, 0x03, 0x21, 0x30, 0x82, 0x03, 0x1d, 0x02,
+  0x01, 0x01, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
+  0x1a, 0x05, 0x00, 0x30, 0x0f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x01, 0x07, 0x01, 0xa0, 0x02, 0x04, 0x00, 0xa0, 0x82, 0x01, 0xb2,
+  0x30, 0x82, 0x01, 0xae, 0x30, 0x82, 0x01, 0x58, 0xa0, 0x03, 0x02, 0x01,
+  0x02, 0x02, 0x09, 0x00, 0x9f, 0x40, 0x26, 0xeb, 0xf4, 0xdb, 0xf7, 0xad,
+  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+  0x05, 0x05, 0x00, 0x30, 0x1c, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55,
+  0x04, 0x0a, 0x13, 0x03, 0x66, 0x6f, 0x6f, 0x31, 0x0c, 0x30, 0x0a, 0x06,
+  0x03, 0x55, 0x04, 0x03, 0x13, 0x03, 0x62, 0x61, 0x72, 0x30, 0x1e, 0x17,
+  0x0d, 0x30, 0x39, 0x30, 0x39, 0x32, 0x38, 0x32, 0x31, 0x32, 0x37, 0x34,
+  0x34, 0x5a, 0x17, 0x0d, 0x30, 0x39, 0x31, 0x30, 0x32, 0x38, 0x32, 0x31,
+  0x32, 0x37, 0x34, 0x34, 0x5a, 0x30, 0x1c, 0x31, 0x0c, 0x30, 0x0a, 0x06,
+  0x03, 0x55, 0x04, 0x0a, 0x13, 0x03, 0x66, 0x6f, 0x6f, 0x31, 0x0c, 0x30,
+  0x0a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x03, 0x62, 0x61, 0x72, 0x30,
+  0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00,
+  0xa8, 0x19, 0x0a, 0xa1, 0x4d, 0x1e, 0x2a, 0x06, 0x6d, 0xae, 0x9a, 0x18,
+  0x87, 0xf8, 0xab, 0xf8, 0x64, 0xe3, 0x1f, 0x6f, 0xd8, 0x8c, 0x7f, 0xb2,
+  0xae, 0xfe, 0xf1, 0x7b, 0x18, 0xdd, 0x14, 0xcd, 0x7a, 0x4f, 0xa2, 0x6f,
+  0x1f, 0xe9, 0xe2, 0x6b, 0x40, 0x55, 0x3c, 0x21, 0xc5, 0xc9, 0xf4, 0x30,
+  0x5f, 0x08, 0x2b, 0x0d, 0x7b, 0x37, 0x3d, 0x73, 0x2a, 0x90, 0x25, 0x61,
+  0x15, 0x5a, 0xfc, 0xcb, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x7d, 0x30,
+  0x7b, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
+  0xa7, 0xd4, 0x57, 0xb1, 0x87, 0xf0, 0x49, 0xd8, 0xf4, 0xbd, 0x65, 0x2f,
+  0x26, 0x58, 0x8d, 0xf8, 0x27, 0x98, 0x8d, 0x67, 0x30, 0x4c, 0x06, 0x03,
+  0x55, 0x1d, 0x23, 0x04, 0x45, 0x30, 0x43, 0x80, 0x14, 0xa7, 0xd4, 0x57,
+  0xb1, 0x87, 0xf0, 0x49, 0xd8, 0xf4, 0xbd, 0x65, 0x2f, 0x26, 0x58, 0x8d,
+  0xf8, 0x27, 0x98, 0x8d, 0x67, 0xa1, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31,
+  0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x03, 0x66, 0x6f,
+  0x6f, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x03,
+  0x62, 0x61, 0x72, 0x82, 0x09, 0x00, 0x9f, 0x40, 0x26, 0xeb, 0xf4, 0xdb,
+  0xf7, 0xad, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30,
+  0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x41, 0x00, 0x00, 0x47,
+  0x60, 0x26, 0x86, 0x07, 0xa6, 0x21, 0x33, 0xb4, 0xd0, 0x8b, 0xcf, 0xa6,
+  0xa1, 0x8d, 0x95, 0xb9, 0xb8, 0xd1, 0x5c, 0x35, 0x9a, 0x30, 0xf6, 0xc3,
+  0xf6, 0x40, 0xb5, 0x5d, 0xe2, 0xad, 0xd8, 0xcf, 0xa5, 0x09, 0xa6, 0x05,
+  0x9a, 0xe3, 0xbf, 0x68, 0x92, 0xc5, 0x8c, 0x61, 0xde, 0x1f, 0x1f, 0xc1,
+  0x1b, 0x65, 0xd8, 0x69, 0x15, 0xe0, 0xeb, 0xb1, 0x10, 0xc9, 0x2d, 0x5f,
+  0x1d, 0x81, 0x31, 0x82, 0x01, 0x42, 0x30, 0x82, 0x01, 0x3e, 0x02, 0x01,
+  0x01, 0x30, 0x29, 0x30, 0x1c, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55,
+  0x04, 0x0a, 0x13, 0x03, 0x66, 0x6f, 0x6f, 0x31, 0x0c, 0x30, 0x0a, 0x06,
+  0x03, 0x55, 0x04, 0x03, 0x13, 0x03, 0x62, 0x61, 0x72, 0x02, 0x09, 0x00,
+  0x9f, 0x40, 0x26, 0xeb, 0xf4, 0xdb, 0xf7, 0xad, 0x30, 0x09, 0x06, 0x05,
+  0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0xa0, 0x81, 0xb1, 0x30, 0x18,
+  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x03, 0x31,
+  0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01,
+  0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09,
+  0x05, 0x31, 0x0f, 0x17, 0x0d, 0x30, 0x39, 0x30, 0x39, 0x32, 0x38, 0x32,
+  0x31, 0x34, 0x31, 0x32, 0x34, 0x5a, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86,
+  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04, 0x31, 0x16, 0x04, 0x14, 0xda,
+  0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95,
+  0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09, 0x30, 0x52, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x0f, 0x31, 0x45, 0x30, 0x43,
+  0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x07,
+  0x30, 0x0e, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x02,
+  0x02, 0x02, 0x00, 0x80, 0x30, 0x0d, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x03, 0x02, 0x02, 0x01, 0x40, 0x30, 0x07, 0x06, 0x05, 0x2b,
+  0x0e, 0x03, 0x02, 0x07, 0x30, 0x0d, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x03, 0x02, 0x02, 0x01, 0x28, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x40,
+  0x64, 0xb1, 0xce, 0x47, 0xeb, 0x65, 0x79, 0xf2, 0x63, 0xa1, 0x33, 0x61,
+  0xbc, 0x9c, 0x63, 0x57, 0x16, 0x94, 0xf6, 0x63, 0x76, 0x66, 0x6c, 0x91,
+  0xc1, 0x0b, 0x4b, 0x8d, 0x5b, 0x0e, 0x79, 0x2c, 0xd1, 0xa2, 0x4f, 0xb8,
+  0x73, 0xf4, 0xd0, 0xa3, 0x64, 0xec, 0x08, 0x33, 0x9c, 0x67, 0x17, 0xdc,
+  0xd9, 0xa0, 0xcf, 0x25, 0x60, 0xc6, 0x90, 0x84, 0x52, 0x82, 0xc8, 0xb3,
+  0x04, 0xc5, 0x5a, 0xa7
+};
+unsigned int attached_no_data_signed_data_der_len = 820;
diff --git a/sec/Security/Regressions/secitem/si-64-ossl-cms/attached_signed_data.h b/sec/Security/Regressions/secitem/si-64-ossl-cms/attached_signed_data.h
new file mode 100644 (file)
index 0000000..e382134
--- /dev/null
@@ -0,0 +1,72 @@
+unsigned char attached_signed_data_der[] = {
+  0x30, 0x82, 0x03, 0x37, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x07, 0x02, 0xa0, 0x82, 0x03, 0x28, 0x30, 0x82, 0x03, 0x24, 0x02,
+  0x01, 0x01, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
+  0x1a, 0x05, 0x00, 0x30, 0x16, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x01, 0x07, 0x01, 0xa0, 0x09, 0x04, 0x07, 0x68, 0x6f, 0x69, 0x20,
+  0x6a, 0x6f, 0x68, 0xa0, 0x82, 0x01, 0xb2, 0x30, 0x82, 0x01, 0xae, 0x30,
+  0x82, 0x01, 0x58, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0x9f,
+  0x40, 0x26, 0xeb, 0xf4, 0xdb, 0xf7, 0xad, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x1c,
+  0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x03, 0x66,
+  0x6f, 0x6f, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+  0x03, 0x62, 0x61, 0x72, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, 0x30, 0x39,
+  0x32, 0x38, 0x32, 0x31, 0x32, 0x37, 0x34, 0x34, 0x5a, 0x17, 0x0d, 0x30,
+  0x39, 0x31, 0x30, 0x32, 0x38, 0x32, 0x31, 0x32, 0x37, 0x34, 0x34, 0x5a,
+  0x30, 0x1c, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+  0x03, 0x66, 0x6f, 0x6f, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04,
+  0x03, 0x13, 0x03, 0x62, 0x61, 0x72, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
+  0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0xa8, 0x19, 0x0a, 0xa1, 0x4d,
+  0x1e, 0x2a, 0x06, 0x6d, 0xae, 0x9a, 0x18, 0x87, 0xf8, 0xab, 0xf8, 0x64,
+  0xe3, 0x1f, 0x6f, 0xd8, 0x8c, 0x7f, 0xb2, 0xae, 0xfe, 0xf1, 0x7b, 0x18,
+  0xdd, 0x14, 0xcd, 0x7a, 0x4f, 0xa2, 0x6f, 0x1f, 0xe9, 0xe2, 0x6b, 0x40,
+  0x55, 0x3c, 0x21, 0xc5, 0xc9, 0xf4, 0x30, 0x5f, 0x08, 0x2b, 0x0d, 0x7b,
+  0x37, 0x3d, 0x73, 0x2a, 0x90, 0x25, 0x61, 0x15, 0x5a, 0xfc, 0xcb, 0x02,
+  0x03, 0x01, 0x00, 0x01, 0xa3, 0x7d, 0x30, 0x7b, 0x30, 0x1d, 0x06, 0x03,
+  0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xa7, 0xd4, 0x57, 0xb1, 0x87,
+  0xf0, 0x49, 0xd8, 0xf4, 0xbd, 0x65, 0x2f, 0x26, 0x58, 0x8d, 0xf8, 0x27,
+  0x98, 0x8d, 0x67, 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x45,
+  0x30, 0x43, 0x80, 0x14, 0xa7, 0xd4, 0x57, 0xb1, 0x87, 0xf0, 0x49, 0xd8,
+  0xf4, 0xbd, 0x65, 0x2f, 0x26, 0x58, 0x8d, 0xf8, 0x27, 0x98, 0x8d, 0x67,
+  0xa1, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03,
+  0x55, 0x04, 0x0a, 0x13, 0x03, 0x66, 0x6f, 0x6f, 0x31, 0x0c, 0x30, 0x0a,
+  0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x03, 0x62, 0x61, 0x72, 0x82, 0x09,
+  0x00, 0x9f, 0x40, 0x26, 0xeb, 0xf4, 0xdb, 0xf7, 0xad, 0x30, 0x0c, 0x06,
+  0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30,
+  0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
+  0x05, 0x00, 0x03, 0x41, 0x00, 0x00, 0x47, 0x60, 0x26, 0x86, 0x07, 0xa6,
+  0x21, 0x33, 0xb4, 0xd0, 0x8b, 0xcf, 0xa6, 0xa1, 0x8d, 0x95, 0xb9, 0xb8,
+  0xd1, 0x5c, 0x35, 0x9a, 0x30, 0xf6, 0xc3, 0xf6, 0x40, 0xb5, 0x5d, 0xe2,
+  0xad, 0xd8, 0xcf, 0xa5, 0x09, 0xa6, 0x05, 0x9a, 0xe3, 0xbf, 0x68, 0x92,
+  0xc5, 0x8c, 0x61, 0xde, 0x1f, 0x1f, 0xc1, 0x1b, 0x65, 0xd8, 0x69, 0x15,
+  0xe0, 0xeb, 0xb1, 0x10, 0xc9, 0x2d, 0x5f, 0x1d, 0x81, 0x31, 0x82, 0x01,
+  0x42, 0x30, 0x82, 0x01, 0x3e, 0x02, 0x01, 0x01, 0x30, 0x29, 0x30, 0x1c,
+  0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x03, 0x66,
+  0x6f, 0x6f, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+  0x03, 0x62, 0x61, 0x72, 0x02, 0x09, 0x00, 0x9f, 0x40, 0x26, 0xeb, 0xf4,
+  0xdb, 0xf7, 0xad, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a,
+  0x05, 0x00, 0xa0, 0x81, 0xb1, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x09, 0x03, 0x31, 0x0b, 0x06, 0x09, 0x2a, 0x86,
+  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x05, 0x31, 0x0f, 0x17, 0x0d,
+  0x30, 0x39, 0x30, 0x39, 0x32, 0x38, 0x32, 0x31, 0x33, 0x39, 0x34, 0x34,
+  0x5a, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x09, 0x04, 0x31, 0x16, 0x04, 0x14, 0x89, 0x77, 0xc1, 0xb6, 0xd8, 0x6c,
+  0x9b, 0x8e, 0xeb, 0x38, 0x0f, 0x62, 0x12, 0xbe, 0x66, 0x9e, 0x5e, 0x6b,
+  0xd5, 0x23, 0x30, 0x52, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x09, 0x0f, 0x31, 0x45, 0x30, 0x43, 0x30, 0x0a, 0x06, 0x08, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x07, 0x30, 0x0e, 0x06, 0x08, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x02, 0x02, 0x02, 0x00, 0x80, 0x30,
+  0x0d, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x02, 0x02,
+  0x01, 0x40, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x07, 0x30,
+  0x0d, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x02, 0x02,
+  0x01, 0x28, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x40, 0x99, 0x17, 0x50, 0x18, 0xab,
+  0x06, 0xdb, 0x31, 0xaa, 0xc6, 0x3c, 0x56, 0xa3, 0x9a, 0x2c, 0xcb, 0x80,
+  0xe4, 0x31, 0xf6, 0xe9, 0x32, 0x6b, 0x48, 0x1b, 0x66, 0xf6, 0xd4, 0xd8,
+  0xb6, 0x0a, 0x08, 0x9c, 0x32, 0xaa, 0x51, 0x6e, 0x20, 0x23, 0x43, 0x2a,
+  0x02, 0x90, 0x9c, 0x75, 0x27, 0x27, 0x69, 0x83, 0x4d, 0xa0, 0xaf, 0xda,
+  0xd3, 0x47, 0x2b, 0xe3, 0xb4, 0xd1, 0x9e, 0x69, 0xa1, 0x6a, 0xd0
+};
+unsigned int attached_signed_data_der_len = 827;
diff --git a/sec/Security/Regressions/secitem/si-64-ossl-cms/detached_content.h b/sec/Security/Regressions/secitem/si-64-ossl-cms/detached_content.h
new file mode 100644 (file)
index 0000000..6820d64
--- /dev/null
@@ -0,0 +1,4 @@
+unsigned char detached_content[] = {
+  0x68, 0x6f, 0x69, 0x20, 0x6a, 0x6f, 0x68
+};
+unsigned int detached_content_len = 7;
diff --git a/sec/Security/Regressions/secitem/si-64-ossl-cms/detached_signed_data.h b/sec/Security/Regressions/secitem/si-64-ossl-cms/detached_signed_data.h
new file mode 100644 (file)
index 0000000..3219567
--- /dev/null
@@ -0,0 +1,71 @@
+unsigned char detached_signed_data_der[] = {
+  0x30, 0x82, 0x03, 0x2c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x07, 0x02, 0xa0, 0x82, 0x03, 0x1d, 0x30, 0x82, 0x03, 0x19, 0x02,
+  0x01, 0x01, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
+  0x1a, 0x05, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x01, 0xb2, 0x30, 0x82, 0x01, 0xae,
+  0x30, 0x82, 0x01, 0x58, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00,
+  0x9f, 0x40, 0x26, 0xeb, 0xf4, 0xdb, 0xf7, 0xad, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
+  0x1c, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x03,
+  0x66, 0x6f, 0x6f, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x03,
+  0x13, 0x03, 0x62, 0x61, 0x72, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, 0x30,
+  0x39, 0x32, 0x38, 0x32, 0x31, 0x32, 0x37, 0x34, 0x34, 0x5a, 0x17, 0x0d,
+  0x30, 0x39, 0x31, 0x30, 0x32, 0x38, 0x32, 0x31, 0x32, 0x37, 0x34, 0x34,
+  0x5a, 0x30, 0x1c, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0a,
+  0x13, 0x03, 0x66, 0x6f, 0x6f, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55,
+  0x04, 0x03, 0x13, 0x03, 0x62, 0x61, 0x72, 0x30, 0x5c, 0x30, 0x0d, 0x06,
+  0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
+  0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0xa8, 0x19, 0x0a, 0xa1,
+  0x4d, 0x1e, 0x2a, 0x06, 0x6d, 0xae, 0x9a, 0x18, 0x87, 0xf8, 0xab, 0xf8,
+  0x64, 0xe3, 0x1f, 0x6f, 0xd8, 0x8c, 0x7f, 0xb2, 0xae, 0xfe, 0xf1, 0x7b,
+  0x18, 0xdd, 0x14, 0xcd, 0x7a, 0x4f, 0xa2, 0x6f, 0x1f, 0xe9, 0xe2, 0x6b,
+  0x40, 0x55, 0x3c, 0x21, 0xc5, 0xc9, 0xf4, 0x30, 0x5f, 0x08, 0x2b, 0x0d,
+  0x7b, 0x37, 0x3d, 0x73, 0x2a, 0x90, 0x25, 0x61, 0x15, 0x5a, 0xfc, 0xcb,
+  0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x7d, 0x30, 0x7b, 0x30, 0x1d, 0x06,
+  0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xa7, 0xd4, 0x57, 0xb1,
+  0x87, 0xf0, 0x49, 0xd8, 0xf4, 0xbd, 0x65, 0x2f, 0x26, 0x58, 0x8d, 0xf8,
+  0x27, 0x98, 0x8d, 0x67, 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
+  0x45, 0x30, 0x43, 0x80, 0x14, 0xa7, 0xd4, 0x57, 0xb1, 0x87, 0xf0, 0x49,
+  0xd8, 0xf4, 0xbd, 0x65, 0x2f, 0x26, 0x58, 0x8d, 0xf8, 0x27, 0x98, 0x8d,
+  0x67, 0xa1, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31, 0x0c, 0x30, 0x0a, 0x06,
+  0x03, 0x55, 0x04, 0x0a, 0x13, 0x03, 0x66, 0x6f, 0x6f, 0x31, 0x0c, 0x30,
+  0x0a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x03, 0x62, 0x61, 0x72, 0x82,
+  0x09, 0x00, 0x9f, 0x40, 0x26, 0xeb, 0xf4, 0xdb, 0xf7, 0xad, 0x30, 0x0c,
+  0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff,
+  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+  0x05, 0x05, 0x00, 0x03, 0x41, 0x00, 0x00, 0x47, 0x60, 0x26, 0x86, 0x07,
+  0xa6, 0x21, 0x33, 0xb4, 0xd0, 0x8b, 0xcf, 0xa6, 0xa1, 0x8d, 0x95, 0xb9,
+  0xb8, 0xd1, 0x5c, 0x35, 0x9a, 0x30, 0xf6, 0xc3, 0xf6, 0x40, 0xb5, 0x5d,
+  0xe2, 0xad, 0xd8, 0xcf, 0xa5, 0x09, 0xa6, 0x05, 0x9a, 0xe3, 0xbf, 0x68,
+  0x92, 0xc5, 0x8c, 0x61, 0xde, 0x1f, 0x1f, 0xc1, 0x1b, 0x65, 0xd8, 0x69,
+  0x15, 0xe0, 0xeb, 0xb1, 0x10, 0xc9, 0x2d, 0x5f, 0x1d, 0x81, 0x31, 0x82,
+  0x01, 0x42, 0x30, 0x82, 0x01, 0x3e, 0x02, 0x01, 0x01, 0x30, 0x29, 0x30,
+  0x1c, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x03,
+  0x66, 0x6f, 0x6f, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x03,
+  0x13, 0x03, 0x62, 0x61, 0x72, 0x02, 0x09, 0x00, 0x9f, 0x40, 0x26, 0xeb,
+  0xf4, 0xdb, 0xf7, 0xad, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
+  0x1a, 0x05, 0x00, 0xa0, 0x81, 0xb1, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86,
+  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x03, 0x31, 0x0b, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x05, 0x31, 0x0f, 0x17,
+  0x0d, 0x30, 0x39, 0x30, 0x39, 0x32, 0x38, 0x32, 0x31, 0x33, 0x38, 0x35,
+  0x39, 0x5a, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x09, 0x04, 0x31, 0x16, 0x04, 0x14, 0x89, 0x77, 0xc1, 0xb6, 0xd8,
+  0x6c, 0x9b, 0x8e, 0xeb, 0x38, 0x0f, 0x62, 0x12, 0xbe, 0x66, 0x9e, 0x5e,
+  0x6b, 0xd5, 0x23, 0x30, 0x52, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x01, 0x09, 0x0f, 0x31, 0x45, 0x30, 0x43, 0x30, 0x0a, 0x06, 0x08,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x07, 0x30, 0x0e, 0x06, 0x08,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x02, 0x02, 0x02, 0x00, 0x80,
+  0x30, 0x0d, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x02,
+  0x02, 0x01, 0x40, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x07,
+  0x30, 0x0d, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x02,
+  0x02, 0x01, 0x28, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x40, 0x55, 0x10, 0xbf, 0x3d,
+  0x03, 0xf3, 0x56, 0x16, 0x46, 0x37, 0x29, 0xdb, 0x66, 0x33, 0xb1, 0xc6,
+  0x7f, 0xfd, 0x82, 0x47, 0x97, 0x52, 0xcf, 0xb5, 0xe5, 0xae, 0x76, 0x15,
+  0xd7, 0xf7, 0xff, 0xc7, 0x4e, 0x93, 0x62, 0xef, 0x01, 0xd8, 0x30, 0x35,
+  0x53, 0x69, 0x6c, 0xd4, 0x2a, 0xd9, 0x98, 0x10, 0x54, 0x47, 0x9e, 0x26,
+  0x7d, 0x5e, 0x42, 0x1c, 0x71, 0x69, 0x57, 0x70, 0x15, 0xd8, 0x63, 0x62
+};
+unsigned int detached_signed_data_der_len = 816;
diff --git a/sec/Security/Regressions/secitem/si-64-ossl-cms/privkey.h b/sec/Security/Regressions/secitem/si-64-ossl-cms/privkey.h
new file mode 100644 (file)
index 0000000..46e973b
--- /dev/null
@@ -0,0 +1,30 @@
+unsigned char privkey_der[] = {
+  0x30, 0x82, 0x01, 0x3a, 0x02, 0x01, 0x00, 0x02, 0x41, 0x00, 0xa8, 0x19,
+  0x0a, 0xa1, 0x4d, 0x1e, 0x2a, 0x06, 0x6d, 0xae, 0x9a, 0x18, 0x87, 0xf8,
+  0xab, 0xf8, 0x64, 0xe3, 0x1f, 0x6f, 0xd8, 0x8c, 0x7f, 0xb2, 0xae, 0xfe,
+  0xf1, 0x7b, 0x18, 0xdd, 0x14, 0xcd, 0x7a, 0x4f, 0xa2, 0x6f, 0x1f, 0xe9,
+  0xe2, 0x6b, 0x40, 0x55, 0x3c, 0x21, 0xc5, 0xc9, 0xf4, 0x30, 0x5f, 0x08,
+  0x2b, 0x0d, 0x7b, 0x37, 0x3d, 0x73, 0x2a, 0x90, 0x25, 0x61, 0x15, 0x5a,
+  0xfc, 0xcb, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x41, 0x00, 0x87, 0x7a,
+  0x1f, 0x32, 0x1f, 0x28, 0x27, 0x70, 0xa4, 0xe7, 0x6a, 0xb4, 0x48, 0xa9,
+  0xe7, 0x57, 0xbb, 0x5f, 0xbd, 0x8f, 0x73, 0xf4, 0xd0, 0x5a, 0x5f, 0x65,
+  0x83, 0x93, 0xd5, 0x57, 0x21, 0x12, 0xa7, 0x8a, 0x07, 0xbd, 0xc8, 0x21,
+  0xee, 0xf5, 0x70, 0x9d, 0x10, 0x49, 0x17, 0x03, 0x3c, 0xad, 0xaa, 0x55,
+  0x85, 0xe2, 0xe4, 0xa2, 0x24, 0xc7, 0x08, 0xcc, 0xdf, 0x77, 0xb4, 0x2a,
+  0x0f, 0x89, 0x02, 0x21, 0x00, 0xd3, 0x08, 0x01, 0xc6, 0x74, 0xbb, 0x8f,
+  0x03, 0xf3, 0xf4, 0xf3, 0x1a, 0x8b, 0x54, 0x86, 0xc1, 0x33, 0xd6, 0x2a,
+  0xea, 0xfc, 0x59, 0x15, 0xa7, 0x09, 0xf8, 0xa2, 0xb4, 0x08, 0x0c, 0x50,
+  0x5f, 0x02, 0x21, 0x00, 0xcb, 0xea, 0xf7, 0x5a, 0x7a, 0x10, 0xc2, 0x9e,
+  0xaf, 0x22, 0xbd, 0xe9, 0x57, 0x87, 0x22, 0x55, 0xa0, 0x58, 0x50, 0x1d,
+  0x18, 0x02, 0x94, 0xe1, 0xd1, 0x8a, 0xbc, 0xed, 0x19, 0x3d, 0xbb, 0x15,
+  0x02, 0x20, 0x6c, 0x40, 0x45, 0x38, 0xda, 0x14, 0x84, 0x2e, 0x50, 0xec,
+  0x2b, 0xf0, 0x47, 0xdc, 0x9a, 0x2b, 0x6d, 0x3d, 0xc5, 0x52, 0x39, 0x14,
+  0x31, 0x89, 0x38, 0x12, 0x34, 0xd4, 0x08, 0xf4, 0xd8, 0x1d, 0x02, 0x20,
+  0x0f, 0x87, 0x8a, 0x64, 0xe2, 0x8c, 0xea, 0x35, 0x69, 0x83, 0x0c, 0xd1,
+  0x7b, 0x6f, 0xf8, 0x26, 0x6b, 0x3a, 0xae, 0x87, 0x38, 0xaf, 0xe1, 0xa4,
+  0xbc, 0xef, 0x82, 0xe9, 0xcf, 0x95, 0x4a, 0xed, 0x02, 0x20, 0x48, 0x86,
+  0x72, 0x9a, 0x7d, 0x78, 0x7d, 0x34, 0x70, 0x2f, 0x07, 0x62, 0x38, 0xa6,
+  0x4d, 0xd3, 0x55, 0x92, 0x1d, 0x15, 0x12, 0x53, 0x49, 0x34, 0xd2, 0x91,
+  0x99, 0x38, 0xdb, 0x5f, 0x38, 0x7f
+};
+unsigned int privkey_der_len = 318;
diff --git a/sec/Security/Regressions/secitem/si-64-ossl-cms/signer.h b/sec/Security/Regressions/secitem/si-64-ossl-cms/signer.h
new file mode 100644 (file)
index 0000000..377937e
--- /dev/null
@@ -0,0 +1,40 @@
+unsigned char signer_der[] = {
+  0x30, 0x82, 0x01, 0xae, 0x30, 0x82, 0x01, 0x58, 0xa0, 0x03, 0x02, 0x01,
+  0x02, 0x02, 0x09, 0x00, 0x9f, 0x40, 0x26, 0xeb, 0xf4, 0xdb, 0xf7, 0xad,
+  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+  0x05, 0x05, 0x00, 0x30, 0x1c, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55,
+  0x04, 0x0a, 0x13, 0x03, 0x66, 0x6f, 0x6f, 0x31, 0x0c, 0x30, 0x0a, 0x06,
+  0x03, 0x55, 0x04, 0x03, 0x13, 0x03, 0x62, 0x61, 0x72, 0x30, 0x1e, 0x17,
+  0x0d, 0x30, 0x39, 0x30, 0x39, 0x32, 0x38, 0x32, 0x31, 0x32, 0x37, 0x34,
+  0x34, 0x5a, 0x17, 0x0d, 0x30, 0x39, 0x31, 0x30, 0x32, 0x38, 0x32, 0x31,
+  0x32, 0x37, 0x34, 0x34, 0x5a, 0x30, 0x1c, 0x31, 0x0c, 0x30, 0x0a, 0x06,
+  0x03, 0x55, 0x04, 0x0a, 0x13, 0x03, 0x66, 0x6f, 0x6f, 0x31, 0x0c, 0x30,
+  0x0a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x03, 0x62, 0x61, 0x72, 0x30,
+  0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00,
+  0xa8, 0x19, 0x0a, 0xa1, 0x4d, 0x1e, 0x2a, 0x06, 0x6d, 0xae, 0x9a, 0x18,
+  0x87, 0xf8, 0xab, 0xf8, 0x64, 0xe3, 0x1f, 0x6f, 0xd8, 0x8c, 0x7f, 0xb2,
+  0xae, 0xfe, 0xf1, 0x7b, 0x18, 0xdd, 0x14, 0xcd, 0x7a, 0x4f, 0xa2, 0x6f,
+  0x1f, 0xe9, 0xe2, 0x6b, 0x40, 0x55, 0x3c, 0x21, 0xc5, 0xc9, 0xf4, 0x30,
+  0x5f, 0x08, 0x2b, 0x0d, 0x7b, 0x37, 0x3d, 0x73, 0x2a, 0x90, 0x25, 0x61,
+  0x15, 0x5a, 0xfc, 0xcb, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x7d, 0x30,
+  0x7b, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
+  0xa7, 0xd4, 0x57, 0xb1, 0x87, 0xf0, 0x49, 0xd8, 0xf4, 0xbd, 0x65, 0x2f,
+  0x26, 0x58, 0x8d, 0xf8, 0x27, 0x98, 0x8d, 0x67, 0x30, 0x4c, 0x06, 0x03,
+  0x55, 0x1d, 0x23, 0x04, 0x45, 0x30, 0x43, 0x80, 0x14, 0xa7, 0xd4, 0x57,
+  0xb1, 0x87, 0xf0, 0x49, 0xd8, 0xf4, 0xbd, 0x65, 0x2f, 0x26, 0x58, 0x8d,
+  0xf8, 0x27, 0x98, 0x8d, 0x67, 0xa1, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31,
+  0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x03, 0x66, 0x6f,
+  0x6f, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x03,
+  0x62, 0x61, 0x72, 0x82, 0x09, 0x00, 0x9f, 0x40, 0x26, 0xeb, 0xf4, 0xdb,
+  0xf7, 0xad, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30,
+  0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x41, 0x00, 0x00, 0x47,
+  0x60, 0x26, 0x86, 0x07, 0xa6, 0x21, 0x33, 0xb4, 0xd0, 0x8b, 0xcf, 0xa6,
+  0xa1, 0x8d, 0x95, 0xb9, 0xb8, 0xd1, 0x5c, 0x35, 0x9a, 0x30, 0xf6, 0xc3,
+  0xf6, 0x40, 0xb5, 0x5d, 0xe2, 0xad, 0xd8, 0xcf, 0xa5, 0x09, 0xa6, 0x05,
+  0x9a, 0xe3, 0xbf, 0x68, 0x92, 0xc5, 0x8c, 0x61, 0xde, 0x1f, 0x1f, 0xc1,
+  0x1b, 0x65, 0xd8, 0x69, 0x15, 0xe0, 0xeb, 0xb1, 0x10, 0xc9, 0x2d, 0x5f,
+  0x1d, 0x81
+};
+unsigned int signer_der_len = 434;
diff --git a/sec/Security/Regressions/secitem/si-65-cms-cert-policy.c b/sec/Security/Regressions/secitem/si-65-cms-cert-policy.c
new file mode 100644 (file)
index 0000000..3a15528
--- /dev/null
@@ -0,0 +1,317 @@
+/*
+ *  si-65-cms-cert-policy.c
+ *  regressions
+ *
+ *  Created by Conrad Sauerwald on 9/28/10.
+ *  Copyright 2010 Apple Inc. All rights reserved.
+ *
+ */
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/Security.h>
+#include <Security/SecCMS.h>
+#include <Security/SecInternal.h>
+#include <Security/SecPolicyPriv.h>
+#include <CommonCrypto/CommonDigest.h>
+#include "Security_regressions.h"
+
+
+const uint8_t root_ca[] = {
+  0x30, 0x82, 0x03, 0x59, 0x30, 0x82, 0x02, 0x41, 0xa0, 0x03, 0x02, 0x01,
+  0x02, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x44, 0x31, 0x0b, 0x30,
+  0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
+  0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70,
+  0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, 0x06,
+  0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+  0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68,
+  0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x30,
+  0x39, 0x32, 0x39, 0x32, 0x32, 0x31, 0x30, 0x31, 0x38, 0x5a, 0x17, 0x0d,
+  0x31, 0x30, 0x31, 0x30, 0x32, 0x39, 0x32, 0x32, 0x31, 0x30, 0x31, 0x38,
+  0x5a, 0x30, 0x44, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+  0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
+  0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63,
+  0x2e, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x17,
+  0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f,
+  0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30,
+  0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30,
+  0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xab, 0xb2, 0x30, 0x5a,
+  0xf7, 0x0b, 0xe5, 0xb1, 0xcf, 0xd8, 0x21, 0xe8, 0x13, 0x0a, 0x73, 0x31,
+  0x5e, 0x8d, 0xbb, 0xf8, 0xb4, 0xcf, 0x7a, 0x6c, 0xb3, 0xa4, 0x57, 0x7b,
+  0xa3, 0xea, 0x0c, 0x89, 0xe3, 0x4f, 0x03, 0x41, 0x02, 0xd0, 0xcd, 0x29,
+  0x43, 0x20, 0x56, 0xc5, 0x4f, 0xda, 0xb7, 0xeb, 0x43, 0x7e, 0xcd, 0x39,
+  0xca, 0xbe, 0x6f, 0xdb, 0x7e, 0x31, 0x04, 0x5e, 0xa9, 0x9e, 0x1c, 0x57,
+  0xb3, 0x2f, 0x8d, 0xa9, 0x32, 0x51, 0x22, 0xae, 0xd4, 0xc2, 0xec, 0xc3,
+  0xc4, 0xfd, 0xd8, 0xc4, 0xb1, 0xc9, 0x69, 0xe5, 0x49, 0xad, 0x50, 0xbe,
+  0xc5, 0x36, 0xfe, 0x1f, 0x36, 0x37, 0x18, 0x1a, 0x0e, 0xee, 0x1f, 0x5a,
+  0xcc, 0xa7, 0x83, 0x76, 0xc4, 0x58, 0x78, 0xdc, 0xd5, 0xd9, 0x41, 0xd9,
+  0x24, 0xe3, 0x31, 0xa3, 0x35, 0xa0, 0xe5, 0x0e, 0xae, 0xaa, 0x8b, 0xda,
+  0x71, 0xd2, 0xa4, 0xfc, 0x8c, 0xd2, 0x0e, 0x70, 0x83, 0x09, 0x19, 0x26,
+  0xb2, 0x4a, 0x2b, 0x92, 0xed, 0x4f, 0x09, 0x46, 0x5e, 0xe9, 0x50, 0x9d,
+  0xaf, 0x0c, 0x8d, 0x9e, 0xaa, 0x9b, 0xc2, 0x2f, 0xb7, 0xa3, 0x39, 0x22,
+  0x6b, 0xde, 0x97, 0xd9, 0xec, 0xb6, 0x44, 0x07, 0x2e, 0x6b, 0x7a, 0xe6,
+  0xcf, 0x8d, 0x7d, 0xeb, 0xd3, 0xc8, 0x06, 0xdf, 0x09, 0x98, 0x9f, 0x22,
+  0x88, 0x30, 0x29, 0xa7, 0xec, 0xa7, 0x3d, 0x65, 0x18, 0x0d, 0xe9, 0x7d,
+  0x32, 0x95, 0x0a, 0xe3, 0x6b, 0x14, 0x65, 0xb7, 0xa1, 0xd6, 0x83, 0x79,
+  0x07, 0x98, 0x9f, 0xff, 0x90, 0x25, 0x2c, 0xa6, 0x4d, 0xc1, 0xc2, 0x07,
+  0x51, 0x63, 0x5b, 0x3d, 0x77, 0x79, 0xc9, 0x8b, 0xae, 0xdd, 0x16, 0x21,
+  0x7d, 0xc6, 0x3d, 0xa2, 0x73, 0x80, 0x9c, 0xb1, 0x27, 0x81, 0x65, 0x92,
+  0x33, 0xd9, 0xda, 0xf0, 0xe1, 0xc4, 0x7a, 0x2d, 0xbf, 0xe0, 0x76, 0x0d,
+  0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x56, 0x30, 0x54, 0x30, 0x12, 0x06,
+  0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01,
+  0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
+  0x04, 0x16, 0x04, 0x14, 0x78, 0x2f, 0x9f, 0x48, 0x53, 0x25, 0xe3, 0x8c,
+  0x2f, 0xaf, 0x1d, 0x21, 0x86, 0xdc, 0xb0, 0x50, 0x93, 0xa9, 0x24, 0xc2,
+  0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80,
+  0x14, 0x78, 0x2f, 0x9f, 0x48, 0x53, 0x25, 0xe3, 0x8c, 0x2f, 0xaf, 0x1d,
+  0x21, 0x86, 0xdc, 0xb0, 0x50, 0x93, 0xa9, 0x24, 0xc2, 0x30, 0x0d, 0x06,
+  0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,
+  0x03, 0x82, 0x01, 0x01, 0x00, 0x5b, 0x89, 0x64, 0x90, 0xa4, 0x22, 0x05,
+  0x55, 0xd7, 0x31, 0x26, 0xd7, 0x38, 0x22, 0x23, 0xac, 0xd6, 0x35, 0xe4,
+  0x0e, 0xfd, 0xb2, 0x53, 0x6c, 0xb8, 0x22, 0x32, 0x91, 0xdf, 0xd1, 0xfc,
+  0x70, 0xb6, 0xa0, 0x2d, 0xa4, 0xea, 0x81, 0x26, 0x48, 0xca, 0x05, 0x4d,
+  0x1b, 0x5a, 0x7d, 0xc8, 0x2e, 0x6c, 0xc4, 0x1a, 0x0d, 0x0a, 0xc8, 0x5b,
+  0x0e, 0xf3, 0xeb, 0xf2, 0x02, 0xad, 0xb7, 0x6d, 0xf9, 0x02, 0xb6, 0xc9,
+  0x0b, 0xbc, 0xf2, 0x0b, 0xb1, 0x31, 0x3f, 0x6a, 0x93, 0x9d, 0x2e, 0x54,
+  0x29, 0xff, 0xc0, 0xa0, 0xd5, 0xe2, 0x1d, 0x1a, 0x62, 0x46, 0x89, 0x58,
+  0x90, 0x6a, 0x39, 0xf8, 0x76, 0x16, 0xa6, 0xde, 0x08, 0xe6, 0x76, 0xf1,
+  0xb1, 0xe1, 0x06, 0x08, 0xb1, 0x41, 0x0f, 0x44, 0x26, 0x7e, 0x9b, 0xc1,
+  0xc1, 0x21, 0x07, 0x70, 0x79, 0x36, 0xe6, 0xc2, 0x27, 0x7c, 0x2d, 0x17,
+  0x4f, 0x46, 0x8c, 0xac, 0x54, 0x4b, 0x6e, 0xbc, 0x5c, 0xca, 0x37, 0xc0,
+  0x32, 0xfe, 0x1b, 0x02, 0xf7, 0x29, 0x6e, 0x30, 0x86, 0xf0, 0x1a, 0xc7,
+  0x62, 0xa1, 0xaa, 0x8a, 0x2e, 0x5f, 0x37, 0xd9, 0xf6, 0xf5, 0x29, 0xf9,
+  0xc9, 0x4a, 0x4e, 0xc7, 0xaf, 0x4f, 0xdc, 0x99, 0xa5, 0x8d, 0x7f, 0x3b,
+  0xf4, 0x04, 0xc5, 0x9d, 0x3e, 0x8e, 0xbe, 0x58, 0x6d, 0x62, 0xd7, 0x62,
+  0x57, 0x68, 0x46, 0x4e, 0x74, 0x17, 0x1f, 0x4e, 0x27, 0x49, 0xf5, 0xc7,
+  0x5c, 0xdb, 0x30, 0x73, 0x77, 0x90, 0x2d, 0xc9, 0xed, 0x4d, 0x46, 0x68,
+  0xe0, 0x91, 0xb8, 0xea, 0xa2, 0xa5, 0x79, 0x32, 0x60, 0xb8, 0xef, 0xcd,
+  0x89, 0x0d, 0xab, 0x18, 0x9b, 0x06, 0xf9, 0xab, 0xac, 0xc1, 0xfb, 0xe3,
+  0xf0, 0xf3, 0x5c, 0xc6, 0x87, 0x2e, 0xf3, 0xec, 0x2b, 0x88, 0x37, 0xaa,
+  0x32, 0x76, 0x33, 0xf9, 0xa2, 0xb9, 0x2e, 0xc1, 0x11
+};
+
+unsigned char signed_urlbag[] = {
+  0x30, 0x82, 0x04, 0xe8, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x07, 0x02, 0xa0, 0x82, 0x04, 0xd9, 0x30, 0x82, 0x04, 0xd5, 0x02,
+  0x01, 0x01, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
+  0x1a, 0x05, 0x00, 0x30, 0x14, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x01, 0x07, 0x01, 0xa0, 0x07, 0x04, 0x05, 0x66, 0x6f, 0x6f, 0x0d,
+  0x0a, 0xa0, 0x82, 0x03, 0x04, 0x30, 0x82, 0x03, 0x00, 0x30, 0x82, 0x01,
+  0xe8, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06,
+  0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,
+  0x30, 0x44, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+  0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
+  0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+  0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x43,
+  0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+  0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e,
+  0x17, 0x0d, 0x31, 0x30, 0x30, 0x39, 0x32, 0x39, 0x32, 0x32, 0x31, 0x30,
+  0x31, 0x38, 0x5a, 0x17, 0x0d, 0x31, 0x30, 0x31, 0x30, 0x32, 0x39, 0x32,
+  0x32, 0x31, 0x30, 0x31, 0x38, 0x5a, 0x30, 0x4f, 0x31, 0x0b, 0x30, 0x09,
+  0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30,
+  0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c,
+  0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03,
+  0x55, 0x04, 0x03, 0x13, 0x22, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75,
+  0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65,
+  0x2e, 0x63, 0x6f, 0x6d, 0x20, 0x62, 0x61, 0x67, 0x20, 0x73, 0x69, 0x67,
+  0x6e, 0x65, 0x72, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d,
+  0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xb5, 0x4d, 0xea, 0xa2,
+  0xfa, 0x13, 0x1d, 0x80, 0x3d, 0xe5, 0x9d, 0x2b, 0x2f, 0x92, 0xe9, 0xff,
+  0x51, 0x2c, 0xef, 0x09, 0x15, 0x12, 0x72, 0x48, 0x12, 0x87, 0xa9, 0xe4,
+  0x8e, 0x4a, 0x37, 0x46, 0x47, 0xa1, 0xe4, 0x72, 0xb1, 0xba, 0x8f, 0xd5,
+  0xd2, 0x26, 0x8c, 0x1b, 0xf2, 0x0e, 0x36, 0xb0, 0x71, 0xa0, 0x2a, 0x23,
+  0xb6, 0x3b, 0x27, 0x36, 0x8d, 0x1d, 0xa9, 0xc0, 0xba, 0x82, 0xcc, 0x7d,
+  0x97, 0xbe, 0xa5, 0x49, 0x08, 0x26, 0x84, 0x7e, 0x99, 0x55, 0x05, 0x75,
+  0xc8, 0x9c, 0xd0, 0xa2, 0x1b, 0x9b, 0x86, 0x82, 0xd8, 0x51, 0xd1, 0xf9,
+  0x37, 0xee, 0xac, 0x8a, 0xe3, 0x59, 0xc5, 0xcf, 0x22, 0x5e, 0x95, 0x20,
+  0x47, 0x48, 0x85, 0x67, 0xb2, 0xe7, 0x9c, 0x8a, 0xc3, 0x01, 0xbe, 0xf1,
+  0x27, 0x41, 0x4f, 0x70, 0x21, 0x11, 0xff, 0x09, 0x5a, 0x08, 0x14, 0x0b,
+  0xed, 0xdd, 0x81, 0x13, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x76, 0x30,
+  0x74, 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff, 0x04,
+  0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03,
+  0x03, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x01, 0x01, 0xff, 0x04,
+  0x10, 0x30, 0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x63, 0x64, 0x05, 0x05, 0x01, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
+  0x04, 0x16, 0x04, 0x14, 0x30, 0x0f, 0xe5, 0x40, 0x51, 0xc8, 0x26, 0x61,
+  0x3a, 0xba, 0xa1, 0xd0, 0xc0, 0x61, 0x84, 0x97, 0xa6, 0x46, 0xbd, 0x50,
+  0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80,
+  0x14, 0x78, 0x2f, 0x9f, 0x48, 0x53, 0x25, 0xe3, 0x8c, 0x2f, 0xaf, 0x1d,
+  0x21, 0x86, 0xdc, 0xb0, 0x50, 0x93, 0xa9, 0x24, 0xc2, 0x30, 0x0d, 0x06,
+  0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,
+  0x03, 0x82, 0x01, 0x01, 0x00, 0x60, 0x72, 0x78, 0xf5, 0x1e, 0x3f, 0x30,
+  0x7c, 0x3a, 0xf5, 0xd6, 0xe2, 0x01, 0x62, 0x3b, 0x0e, 0x5d, 0xa1, 0xbb,
+  0x77, 0xb1, 0x68, 0x53, 0xdb, 0x9b, 0x43, 0x5e, 0x82, 0xd4, 0xd7, 0xb7,
+  0x72, 0xa1, 0x24, 0xce, 0x9e, 0x16, 0x3e, 0x91, 0xc7, 0xb0, 0x56, 0xd0,
+  0xe2, 0xd7, 0x86, 0x04, 0x46, 0x15, 0x87, 0xf8, 0xd1, 0x3c, 0x0c, 0xd7,
+  0xdf, 0x6f, 0xbb, 0x58, 0xc0, 0xf2, 0xde, 0x38, 0x0e, 0x20, 0xcc, 0x2b,
+  0x3a, 0x64, 0xee, 0x5c, 0x59, 0x15, 0x05, 0x57, 0x8b, 0x8c, 0xf8, 0x19,
+  0xc0, 0x1d, 0x0f, 0x8d, 0x11, 0xf9, 0x77, 0xc4, 0x90, 0x2b, 0x63, 0x1c,
+  0x5c, 0x36, 0x36, 0x2d, 0x99, 0xa6, 0x4c, 0x0f, 0xad, 0x85, 0xab, 0x26,
+  0x38, 0x19, 0x86, 0xf8, 0x1b, 0xd1, 0x4a, 0x1e, 0xcf, 0x0e, 0x91, 0x5a,
+  0x26, 0x8d, 0x91, 0xc7, 0x2f, 0x5c, 0x53, 0x0e, 0x0c, 0x2b, 0xf9, 0xd0,
+  0x03, 0xf3, 0x0b, 0xb8, 0x85, 0x67, 0x8b, 0xfc, 0x56, 0x1f, 0x6e, 0x2b,
+  0xa0, 0x20, 0x81, 0xe6, 0xd6, 0xc7, 0x1b, 0x68, 0xf6, 0x7a, 0xdb, 0x27,
+  0x95, 0x0d, 0xfd, 0x03, 0xd0, 0x1c, 0x95, 0x31, 0x8f, 0x9d, 0x26, 0xe1,
+  0x30, 0xf1, 0xf5, 0x6f, 0xe2, 0xb6, 0x4a, 0x3c, 0x43, 0xfd, 0x02, 0xd1,
+  0x86, 0x1e, 0x70, 0x71, 0xeb, 0xeb, 0x76, 0x6e, 0xb2, 0x17, 0x10, 0x9e,
+  0x78, 0x83, 0xb9, 0xff, 0x39, 0xa1, 0xeb, 0xf3, 0x63, 0xd6, 0x21, 0xeb,
+  0x6e, 0x27, 0xee, 0x79, 0x02, 0x44, 0x8f, 0xd2, 0x3c, 0x3f, 0x81, 0x74,
+  0x4a, 0x8a, 0xb7, 0x6d, 0x6a, 0x5c, 0x4f, 0x90, 0x58, 0x4b, 0x79, 0xdd,
+  0x80, 0xe3, 0xa6, 0x05, 0xe7, 0x65, 0xd8, 0x6d, 0xb6, 0xe0, 0x6c, 0xdc,
+  0xad, 0xc5, 0x61, 0x16, 0x0b, 0xb6, 0x9e, 0x1e, 0x89, 0x43, 0x3e, 0x93,
+  0x8d, 0x1b, 0x8a, 0x42, 0xa0, 0x00, 0xa8, 0x60, 0x61, 0x31, 0x82, 0x01,
+  0xa3, 0x30, 0x82, 0x01, 0x9f, 0x02, 0x01, 0x01, 0x30, 0x49, 0x30, 0x44,
+  0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+  0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a,
+  0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20,
+  0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x43, 0x6f, 0x6e,
+  0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41,
+  0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x02, 0x01, 0x01, 0x30,
+  0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0xa0, 0x81,
+  0xb1, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x09, 0x03, 0x31, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x01, 0x09, 0x05, 0x31, 0x0f, 0x17, 0x0d, 0x31, 0x30, 0x30, 0x39,
+  0x32, 0x39, 0x32, 0x33, 0x33, 0x34, 0x33, 0x39, 0x5a, 0x30, 0x23, 0x06,
+  0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04, 0x31, 0x16,
+  0x04, 0x14, 0x85, 0x54, 0x26, 0x06, 0x8e, 0xe8, 0x93, 0x9d, 0xf6, 0xbc,
+  0xe2, 0xc2, 0xc4, 0xb1, 0xe7, 0x34, 0x65, 0x32, 0xa1, 0x33, 0x30, 0x52,
+  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x0f, 0x31,
+  0x45, 0x30, 0x43, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x03, 0x07, 0x30, 0x0e, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x03, 0x02, 0x02, 0x02, 0x00, 0x80, 0x30, 0x0d, 0x06, 0x08, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x02, 0x02, 0x01, 0x40, 0x30, 0x07,
+  0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x07, 0x30, 0x0d, 0x06, 0x08, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x02, 0x02, 0x01, 0x28, 0x30, 0x0d,
+  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
+  0x00, 0x04, 0x81, 0x80, 0x5a, 0xc8, 0x72, 0x37, 0xe4, 0x7a, 0xdd, 0xde,
+  0x47, 0x6e, 0x27, 0x4c, 0x73, 0x70, 0x27, 0x01, 0xf3, 0x2c, 0x52, 0x1f,
+  0xa2, 0xa5, 0xbd, 0xd4, 0x6b, 0x6e, 0x44, 0x1a, 0xfc, 0x43, 0x55, 0xbc,
+  0xe5, 0x9a, 0xdb, 0x06, 0x1c, 0x67, 0x49, 0xb7, 0x06, 0x45, 0x98, 0xd8,
+  0x72, 0xc3, 0xc9, 0x6e, 0x47, 0xc8, 0x29, 0x33, 0xbd, 0x05, 0x2c, 0x9f,
+  0x74, 0x13, 0x2f, 0x57, 0x30, 0x86, 0x07, 0x08, 0xfd, 0xea, 0x38, 0x7f,
+  0xec, 0xcd, 0x47, 0x64, 0xfb, 0xea, 0x60, 0x6e, 0xea, 0xc6, 0xd4, 0x57,
+  0x46, 0xe3, 0x71, 0xc3, 0xa4, 0xfc, 0x7a, 0x2c, 0xed, 0x6b, 0xe7, 0x7f,
+  0x4c, 0xe7, 0x24, 0x8f, 0x9c, 0xd9, 0x9a, 0xa7, 0xdc, 0xf1, 0xc8, 0x20,
+  0x59, 0xd1, 0x1d, 0x26, 0xb9, 0xd3, 0x19, 0x21, 0x68, 0x86, 0x76, 0x6e,
+  0xb8, 0xd8, 0x42, 0x31, 0x2a, 0x32, 0x8d, 0x8b, 0x66, 0xce, 0x65, 0x2c
+};
+unsigned int signed_urlbag_len = 1260;
+
+static void tests(void)
+{
+    CFDataRef message = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, signed_urlbag, signed_urlbag_len, kCFAllocatorNull);
+    CFMutableDataRef munged_message = CFDataCreateMutableCopy(kCFAllocatorDefault, 0, message);
+    is(*(CFDataGetMutableBytePtr(munged_message) + 59), '\015', "modifying right byte");
+    *(CFDataGetMutableBytePtr(munged_message) + 59) = '\012';
+
+    SecPolicyRef policy = NULL;
+    SecTrustRef trust = NULL;
+    SecTrustResultType result;
+    CFDataRef root_ca_data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, root_ca, sizeof(root_ca), kCFAllocatorNull);
+    SecCertificateRef anchor = SecCertificateCreateWithData(kCFAllocatorDefault, root_ca_data);
+    CFArrayRef anchors = CFArrayCreate(kCFAllocatorDefault, (const void **)&anchor, 1, &kCFTypeArrayCallBacks);
+    CFRelease(anchor);
+    CFReleaseNull(root_ca_data);
+
+    policy = SecPolicyCreateURLBag();
+    ok_status(SecCMSVerifySignedData(message, NULL, policy, &trust, NULL, NULL, NULL), "validate message");
+
+    SecTrustSetAnchorCertificates(trust, anchors);
+    ok_status(SecTrustEvaluate(trust, &result), "evaluate trust");
+    ok(result == kSecTrustResultUnspecified, "private root");
+
+    CFReleaseNull(trust);
+
+    is_status(errSecAuthFailed, SecCMSVerifySignedData(munged_message, NULL, policy, &trust, NULL, NULL, NULL), "validate message");
+
+    CFReleaseNull(trust);
+
+    CFReleaseNull(policy);
+    CFReleaseNull(anchors);
+    CFReleaseNull(message);
+    CFReleaseNull(munged_message);
+}
+
+int si_65_cms_cert_policy(int argc, char *const *argv)
+{
+       plan_tests(5);
+
+       tests();
+
+       return 0;
+}
+
+
+
+/*
+
+# This is a shell archive.  Save it in a file, remove anything before
+# this line, and then unpack it by entering "sh file".  Note, it may
+# create directories; files and directories will be owned by you and
+# have default permissions.
+#
+# This archive contains:
+#
+#      Makefile
+#      extensions.txt
+#
+echo x - Makefile
+sed 's/^X//' >Makefile << 'END-of-Makefile'
+X
+Xall:
+X      @echo "No default action"
+X
+XCA-key.pem:
+X      @openssl genrsa -out CA-key.pem 2048
+X
+XCA-csr.pem: CA-key.pem
+X      @openssl req -new -key CA-key.pem -sha1 -days 3650 -subj "/C=US/O=Apple Inc./CN=Configuration Authority" -nodes -out CA-csr.pem
+X
+XCA-cert.pem: CA-csr.pem CA-key.pem
+X      @openssl x509 -req -sha1 -in CA-csr.pem -signkey CA-key.pem -set_serial 0 -out CA-cert.pem -extensions authority -extfile extensions.txt
+X
+Xleaf-cert.pem: CA-cert.pem CA-key.pem
+X      @openssl req -newkey rsa:1024 -sha1 -days 3650 -subj "/C=US/O=Apple Inc./CN=configuration.apple.com bag signer" -nodes -out leaf-csr.pem -keyout leaf-key.pem
+X      @openssl x509 -req -sha1 -in leaf-csr.pem -CA CA-cert.pem -CAkey CA-key.pem -out leaf-cert.pem -set_serial 1 -extfile extensions.txt -extensions leaf
+X
+Xcheck: CA-cert.pem leaf-cert.pem
+X      @echo Validate leaf
+X      @openssl verify -CAfile CA-cert.pem leaf-cert.pem
+X      @echo Output SHA-1 for private root
+X      @openssl x509 -in CA-cert.pem -outform DER | openssl dgst -binary -sha1 | xxd -i
+X      @echo Display leaf
+X      @openssl x509 -noout -text -in leaf-cert.pem
+X
+Xsigned-urlbag: CA-cert.pem leaf-cert.pem content
+X      @cat leaf-cert.pem leaf-key.pem > leaf.pem
+X      @openssl smime -sign -aes128 -outform der -nodetach -signer leaf.pem -CAfile CA-cert.pem -in content -out signed-urlbag
+X
+Xclean:
+X      @rm -f leaf-cert.pem leaf-csr.pem leaf-key.pem leaf.pem signed-urlbag
+X
+Xreal-clean:
+X      @rm -f CA-key.pem CA-csr.pem CA-cert.pem leaf-cert.pem leaf-csr.pem leaf-key.pem leaf.pem signed-urlbag
+END-of-Makefile
+echo x - extensions.txt
+sed 's/^X//' >extensions.txt << 'END-of-extensions.txt'
+X[authority]
+XbasicConstraints=critical,CA:true,pathlen:0
+XsubjectKeyIdentifier=hash
+XauthorityKeyIdentifier=keyid
+X
+X[leaf]
+XextendedKeyUsage=critical,codeSigning
+XcertificatePolicies=critical,1.2.840.113635.100.5.5.1
+XsubjectKeyIdentifier=hash
+XauthorityKeyIdentifier=keyid
+X
+X[req]
+Xdistinguished_name     = req_distinguished_name
+X
+X[req_distinguished_name]
+END-of-extensions.txt
+exit
+
+*/
diff --git a/sec/Security/Regressions/secitem/si-66-smime.c b/sec/Security/Regressions/secitem/si-66-smime.c
new file mode 100644 (file)
index 0000000..4ea447f
--- /dev/null
@@ -0,0 +1,2533 @@
+/*
+ *  si-66-smime.c
+ *  regressions
+ *
+ *  Created by Conrad Sauerwald on 9/28/10.
+ *  Copyright 2010 Apple Inc. All rights reserved.
+ *
+ */
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/Security.h>
+#include <Security/SecCMS.h>
+
+#include <Security/SecCmsBase.h>
+#include <Security/SecSMIME.h>
+#include <Security/SecCertificateRequest.h>
+#include <Security/SecIdentityPriv.h>
+
+#include <Security/SecBase.h>
+#include <Security/SecCmsMessage.h>
+#include <Security/SecCmsSignedData.h>
+#include <Security/SecCmsEnvelopedData.h>
+#include <Security/SecCmsContentInfo.h>
+#include <Security/SecCmsSignerInfo.h>
+#include <Security/SecCmsRecipientInfo.h>
+#include <Security/SecCmsEncoder.h>
+#include <Security/SecCmsDecoder.h>
+#include <Security/SecCmsDigestContext.h>
+
+#include <Security/SecInternal.h>
+#include <Security/SecPolicyPriv.h>
+#include <utilities/array_size.h>
+#include <CommonCrypto/CommonDigest.h>
+
+#include <fcntl.h>
+
+#include "Security_regressions.h"
+#include "si-66-smime/signed-receipt.h"
+
+uint8_t message_hash[] = {
+    0x61, 0x49, 0xAE, 0x84, 0xA6, 0xE6, 0xDE, 0x73,
+    0xCE, 0x39, 0xB9, 0xDB, 0xF9, 0x40, 0x7D, 0xC6,
+    0x05, 0xF3, 0x8F, 0xD7
+};
+
+unsigned char signed_bin[] = {
+  0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07,
+  0x02, 0xa0, 0x80, 0x30, 0x80, 0x02, 0x01, 0x01, 0x31, 0x0b, 0x30, 0x09,
+  0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x30, 0x80, 0x06,
+  0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x00, 0x00,
+  0xa0, 0x82, 0x09, 0x93, 0x30, 0x82, 0x04, 0x46, 0x30, 0x82, 0x03, 0xaf,
+  0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x66, 0xfd, 0x47, 0xe3, 0xc2,
+  0x19, 0xe4, 0xe8, 0x9a, 0xcd, 0x99, 0xdd, 0xf5, 0x3a, 0xcb, 0x24, 0x30,
+  0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
+  0x05, 0x00, 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, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e,
+  0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03,
+  0x55, 0x04, 0x0b, 0x13, 0x2e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x31,
+  0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d,
+  0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+  0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+  0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x35, 0x31, 0x30, 0x32,
+  0x38, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x31, 0x35,
+  0x31, 0x30, 0x32, 0x37, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30,
+  0x81, 0xdd, 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, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20,
+  0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04,
+  0x0b, 0x13, 0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20,
+  0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72,
+  0x6b, 0x31, 0x3b, 0x30, 0x39, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x32,
+  0x54, 0x65, 0x72, 0x6d, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65,
+  0x20, 0x61, 0x74, 0x20, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f,
+  0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e,
+  0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x70, 0x61, 0x20, 0x28, 0x63, 0x29,
+  0x30, 0x35, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
+  0x15, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x20, 0x4e, 0x6f, 0x74,
+  0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x31, 0x37,
+  0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2e, 0x56, 0x65, 0x72,
+  0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20,
+  0x31, 0x20, 0x49, 0x6e, 0x64, 0x69, 0x76, 0x69, 0x64, 0x75, 0x61, 0x6c,
+  0x20, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x20,
+  0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30,
+  0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
+  0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02,
+  0x82, 0x01, 0x01, 0x00, 0xc9, 0xdf, 0xac, 0xe7, 0xea, 0xf8, 0xf8, 0x03,
+  0x14, 0xc4, 0x00, 0x92, 0xd5, 0xc1, 0x7e, 0x36, 0xc2, 0x3c, 0xef, 0x7c,
+  0x72, 0x15, 0xcb, 0xc0, 0xab, 0x8c, 0x3d, 0x1c, 0x95, 0xce, 0x6f, 0x1e,
+  0x10, 0x2c, 0x3f, 0x00, 0xed, 0x97, 0x26, 0xe6, 0xb6, 0xc7, 0xe6, 0xad,
+  0x43, 0x1d, 0x3f, 0xa4, 0x87, 0x47, 0x47, 0x4c, 0x3e, 0x54, 0xf8, 0x6c,
+  0xf8, 0xc7, 0xfc, 0xb1, 0x9e, 0xbd, 0x30, 0x70, 0xbc, 0x97, 0xb1, 0x03,
+  0x05, 0xea, 0x95, 0xf1, 0xad, 0x40, 0xc5, 0x44, 0x7a, 0x4b, 0x05, 0xa2,
+  0xf2, 0x60, 0xfc, 0xd7, 0x3a, 0x65, 0x62, 0xef, 0xff, 0x10, 0x7b, 0xa2,
+  0x56, 0xbb, 0xc5, 0x4e, 0x70, 0x2d, 0xd6, 0xa2, 0x1f, 0x3c, 0xed, 0xb0,
+  0x42, 0xe8, 0x5e, 0x8d, 0x57, 0x21, 0xac, 0xa6, 0x99, 0xd9, 0x11, 0xe9,
+  0xd2, 0x1a, 0x07, 0xc0, 0x74, 0x47, 0x42, 0x0b, 0xfc, 0xc5, 0x34, 0xea,
+  0xfd, 0xe6, 0xba, 0x24, 0xd1, 0x1d, 0x08, 0x15, 0x37, 0xa2, 0xd7, 0x73,
+  0xcf, 0x01, 0x41, 0x2f, 0x63, 0xb2, 0x3a, 0x3f, 0xbe, 0xa5, 0x1a, 0x6e,
+  0xf4, 0xc9, 0x4a, 0x5b, 0x3d, 0x95, 0xa6, 0x15, 0xbb, 0x35, 0x02, 0x19,
+  0xf9, 0xd4, 0xef, 0xbc, 0x8f, 0x0e, 0x71, 0x76, 0x59, 0xbb, 0x4b, 0xb6,
+  0x3e, 0xd6, 0xfc, 0x5a, 0x16, 0xf4, 0xd6, 0x0e, 0x89, 0xf2, 0x49, 0xfe,
+  0x6c, 0x0c, 0xed, 0x15, 0xe9, 0xd9, 0x88, 0x75, 0x9c, 0x79, 0xce, 0x60,
+  0x27, 0xdd, 0xb9, 0xad, 0x75, 0xce, 0x2f, 0x73, 0x95, 0x7a, 0x40, 0x3a,
+  0x85, 0x75, 0x49, 0xb0, 0xb8, 0xdf, 0x68, 0xbc, 0xab, 0xcd, 0x13, 0x82,
+  0x85, 0x11, 0x50, 0xa3, 0xe0, 0x3c, 0x0b, 0xae, 0xc0, 0x0a, 0x53, 0xcd,
+  0xd7, 0x30, 0x6f, 0x85, 0x32, 0x46, 0x1b, 0xe4, 0x49, 0x10, 0xc2, 0x6c,
+  0xe2, 0xaf, 0x1f, 0x79, 0xff, 0xdb, 0xb4, 0xb5, 0x02, 0x03, 0x01, 0x00,
+  0x01, 0xa3, 0x81, 0xff, 0x30, 0x81, 0xfc, 0x30, 0x12, 0x06, 0x03, 0x55,
+  0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff,
+  0x02, 0x01, 0x00, 0x30, 0x44, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3d,
+  0x30, 0x3b, 0x30, 0x39, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8,
+  0x45, 0x01, 0x07, 0x17, 0x01, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b,
+  0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74,
+  0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72,
+  0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x70,
+  0x61, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02,
+  0x01, 0x06, 0x30, 0x11, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8,
+  0x42, 0x01, 0x01, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x2e, 0x06,
+  0x03, 0x55, 0x1d, 0x11, 0x04, 0x27, 0x30, 0x25, 0xa4, 0x23, 0x30, 0x21,
+  0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x50,
+  0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x33,
+  0x2d, 0x32, 0x30, 0x34, 0x38, 0x2d, 0x31, 0x35, 0x35, 0x30, 0x1d, 0x06,
+  0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x11, 0x7d, 0x5e, 0x19,
+  0x7d, 0x3c, 0x04, 0xdf, 0x6a, 0x6c, 0xd6, 0xa2, 0x8a, 0x1a, 0x3f, 0x31,
+  0xd8, 0x3b, 0x94, 0x52, 0x30, 0x31, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04,
+  0x2a, 0x30, 0x28, 0x30, 0x26, 0xa0, 0x24, 0xa0, 0x22, 0x86, 0x20, 0x68,
+  0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x76, 0x65,
+  0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70,
+  0x63, 0x61, 0x31, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81,
+  0x81, 0x00, 0x3c, 0xa3, 0xda, 0x02, 0x63, 0x3a, 0xc4, 0x93, 0xaa, 0xab,
+  0x72, 0xd3, 0xdc, 0xad, 0x50, 0x38, 0x1e, 0x0c, 0x9e, 0x16, 0x4a, 0x88,
+  0xb7, 0xee, 0xeb, 0xd9, 0xff, 0x0f, 0x8d, 0x95, 0xa0, 0xd6, 0xbb, 0xfa,
+  0x6a, 0x0b, 0xae, 0x61, 0x84, 0xd8, 0x68, 0x47, 0x89, 0xef, 0x4f, 0xac,
+  0xb2, 0x1f, 0x49, 0x41, 0x9b, 0x49, 0x33, 0x76, 0x93, 0x8b, 0x9e, 0x6e,
+  0xb9, 0x43, 0x1c, 0x60, 0xbd, 0xc2, 0xdc, 0x8a, 0x2d, 0x87, 0xc1, 0x45,
+  0xc0, 0x11, 0x72, 0x04, 0x1a, 0x6b, 0x24, 0x2a, 0x6c, 0x6f, 0xe7, 0xfc,
+  0x07, 0x13, 0x29, 0xd0, 0x77, 0x3a, 0x23, 0xe7, 0xf5, 0xc1, 0x85, 0x68,
+  0x19, 0xbf, 0xc6, 0x01, 0x54, 0x20, 0x19, 0xae, 0x35, 0x82, 0xcc, 0x62,
+  0x3c, 0x61, 0x09, 0xc6, 0xf4, 0xd5, 0xeb, 0xb0, 0x0f, 0xa6, 0x9f, 0x33,
+  0x85, 0x9a, 0xd3, 0x71, 0x8e, 0x50, 0x8f, 0x99, 0xdd, 0x62, 0x30, 0x82,
+  0x05, 0x45, 0x30, 0x82, 0x04, 0x2d, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
+  0x10, 0x64, 0x3f, 0x62, 0x62, 0xaa, 0xa9, 0x7a, 0xb1, 0x37, 0x26, 0xc1,
+  0x13, 0x1a, 0x40, 0x3b, 0x48, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, 0xdd, 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,
+  0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63,
+  0x2e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16,
+  0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75,
+  0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3b,
+  0x30, 0x39, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x32, 0x54, 0x65, 0x72,
+  0x6d, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x74,
+  0x20, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77,
+  0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f,
+  0x6d, 0x2f, 0x72, 0x70, 0x61, 0x20, 0x28, 0x63, 0x29, 0x30, 0x35, 0x31,
+  0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x15, 0x50, 0x65,
+  0x72, 0x73, 0x6f, 0x6e, 0x61, 0x20, 0x4e, 0x6f, 0x74, 0x20, 0x56, 0x61,
+  0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x31, 0x37, 0x30, 0x35, 0x06,
+  0x03, 0x55, 0x04, 0x03, 0x13, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69,
+  0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x31, 0x20, 0x49,
+  0x6e, 0x64, 0x69, 0x76, 0x69, 0x64, 0x75, 0x61, 0x6c, 0x20, 0x53, 0x75,
+  0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x20, 0x43, 0x41, 0x20,
+  0x2d, 0x20, 0x47, 0x32, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x30, 0x38,
+  0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x31,
+  0x31, 0x30, 0x38, 0x31, 0x30, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a,
+  0x30, 0x82, 0x01, 0x0e, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04,
+  0x0a, 0x13, 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c,
+  0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55,
+  0x04, 0x0b, 0x13, 0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e,
+  0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f,
+  0x72, 0x6b, 0x31, 0x46, 0x30, 0x44, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
+  0x3d, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67,
+  0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69,
+  0x74, 0x6f, 0x72, 0x79, 0x2f, 0x52, 0x50, 0x41, 0x20, 0x49, 0x6e, 0x63,
+  0x6f, 0x72, 0x70, 0x2e, 0x20, 0x62, 0x79, 0x20, 0x52, 0x65, 0x66, 0x2e,
+  0x2c, 0x4c, 0x49, 0x41, 0x42, 0x2e, 0x4c, 0x54, 0x44, 0x28, 0x63, 0x29,
+  0x39, 0x38, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
+  0x15, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x20, 0x4e, 0x6f, 0x74,
+  0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x31, 0x33,
+  0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x44, 0x69, 0x67,
+  0x69, 0x74, 0x61, 0x6c, 0x20, 0x49, 0x44, 0x20, 0x43, 0x6c, 0x61, 0x73,
+  0x73, 0x20, 0x31, 0x20, 0x2d, 0x20, 0x4e, 0x65, 0x74, 0x73, 0x63, 0x61,
+  0x70, 0x65, 0x20, 0x46, 0x75, 0x6c, 0x6c, 0x20, 0x53, 0x65, 0x72, 0x76,
+  0x69, 0x63, 0x65, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03,
+  0x14, 0x0b, 0x43, 0x6f, 0x72, 0x6d, 0x61, 0x63, 0x20, 0x44, 0x61, 0x6c,
+  0x79, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x64, 0x61, 0x6c, 0x79, 0x5f, 0x63,
+  0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82,
+  0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82,
+  0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xcf, 0x39, 0xf5, 0x4f, 0x8d,
+  0xbc, 0x6d, 0x2b, 0x04, 0xf5, 0x33, 0xb6, 0x72, 0x44, 0x51, 0xd2, 0x45,
+  0x8a, 0xa5, 0x3c, 0x08, 0x74, 0x8a, 0x38, 0x65, 0x3f, 0x52, 0xec, 0x73,
+  0x6a, 0x4c, 0x78, 0x89, 0xac, 0x74, 0x33, 0x9e, 0xb3, 0xd8, 0xa3, 0x70,
+  0xd1, 0xaa, 0xa2, 0xad, 0xc8, 0xc0, 0xb8, 0x60, 0x6a, 0x84, 0xec, 0x6b,
+  0xa8, 0xa6, 0x39, 0xc2, 0x85, 0x72, 0x09, 0x40, 0x02, 0x6f, 0xd5, 0x0a,
+  0xb2, 0x15, 0x23, 0x10, 0x76, 0x53, 0x2b, 0x38, 0x38, 0x6c, 0x46, 0xa8,
+  0x42, 0xdd, 0xaa, 0xd9, 0xde, 0xc1, 0xce, 0x66, 0xd7, 0x3f, 0x94, 0x68,
+  0x80, 0x26, 0x47, 0x38, 0xb3, 0x66, 0x08, 0x59, 0xfc, 0x42, 0x6d, 0x95,
+  0x47, 0x7f, 0x43, 0x04, 0x55, 0xa4, 0xfe, 0x39, 0xc0, 0x61, 0xda, 0xb0,
+  0xc5, 0x73, 0xad, 0x2e, 0x37, 0x00, 0x02, 0x52, 0x6d, 0x98, 0x1f, 0x5b,
+  0x85, 0x1e, 0xd6, 0x9f, 0x71, 0x8b, 0xb0, 0x61, 0x1a, 0x78, 0xda, 0xe2,
+  0xac, 0x25, 0xbf, 0xee, 0x02, 0x9a, 0x1d, 0xe5, 0xb5, 0x7a, 0x2f, 0xdb,
+  0x44, 0x81, 0xbd, 0x19, 0x27, 0x39, 0xe9, 0xca, 0x08, 0xba, 0x7c, 0x44,
+  0x1a, 0xa9, 0xc4, 0x48, 0x40, 0xc7, 0x1e, 0x26, 0xa9, 0xc7, 0x11, 0xed,
+  0xd9, 0xb5, 0x15, 0xfb, 0xae, 0x61, 0x6d, 0x74, 0x1a, 0x20, 0x45, 0x8f,
+  0xda, 0x60, 0x14, 0x5b, 0x61, 0x49, 0x48, 0x5d, 0x44, 0x2f, 0x4a, 0x96,
+  0x23, 0x39, 0x8c, 0xbf, 0x34, 0xa4, 0xcd, 0xc0, 0xde, 0x29, 0xf8, 0x37,
+  0xb2, 0xfc, 0x7e, 0x08, 0xbe, 0x56, 0xd1, 0xcf, 0x95, 0x9e, 0xf3, 0x51,
+  0x98, 0xa0, 0x43, 0x6d, 0xe2, 0x08, 0xc3, 0x67, 0x52, 0xf9, 0x2d, 0xbe,
+  0x6e, 0x82, 0xed, 0x60, 0x71, 0x3c, 0xf2, 0xb8, 0x93, 0x0a, 0xd9, 0x2d,
+  0xa9, 0x74, 0x23, 0x73, 0x22, 0x72, 0x95, 0xde, 0xdf, 0x7c, 0x95, 0x02,
+  0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xcc, 0x30, 0x81, 0xc9, 0x30, 0x09,
+  0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x44, 0x06,
+  0x03, 0x55, 0x1d, 0x20, 0x04, 0x3d, 0x30, 0x3b, 0x30, 0x39, 0x06, 0x0b,
+  0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x07, 0x17, 0x01, 0x30,
+  0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02,
+  0x01, 0x16, 0x1c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77,
+  0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e,
+  0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x70, 0x61, 0x30, 0x0b, 0x06, 0x03, 0x55,
+  0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x1d, 0x06, 0x03,
+  0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01,
+  0x05, 0x05, 0x07, 0x03, 0x04, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+  0x07, 0x03, 0x02, 0x30, 0x4a, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x43,
+  0x30, 0x41, 0x30, 0x3f, 0xa0, 0x3d, 0xa0, 0x3b, 0x86, 0x39, 0x68, 0x74,
+  0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x49, 0x6e, 0x64, 0x43, 0x31, 0x44, 0x69,
+  0x67, 0x69, 0x74, 0x61, 0x6c, 0x49, 0x44, 0x2d, 0x63, 0x72, 0x6c, 0x2e,
+  0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
+  0x2f, 0x49, 0x6e, 0x64, 0x43, 0x31, 0x44, 0x69, 0x67, 0x69, 0x74, 0x61,
+  0x6c, 0x49, 0x44, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82,
+  0x01, 0x01, 0x00, 0x65, 0x5f, 0xe6, 0x45, 0xf3, 0x1b, 0x6a, 0x3d, 0xeb,
+  0xad, 0xcb, 0x5d, 0xa4, 0x42, 0x29, 0x6e, 0x26, 0x39, 0x5f, 0x1c, 0x56,
+  0xe6, 0x21, 0x60, 0x34, 0xee, 0xb4, 0x32, 0xa9, 0x6f, 0x02, 0xb7, 0x5f,
+  0x9d, 0x78, 0x77, 0x41, 0x5b, 0xf7, 0x35, 0xd4, 0xe9, 0x24, 0x7d, 0x6c,
+  0x27, 0x59, 0xe4, 0x67, 0x2d, 0x6e, 0x3d, 0x1b, 0xa4, 0x66, 0xb5, 0xc2,
+  0xe6, 0x6a, 0x2d, 0x2a, 0xf7, 0x24, 0x94, 0x5a, 0x00, 0x58, 0xb6, 0x60,
+  0x92, 0xfb, 0x8e, 0xe6, 0x54, 0xe1, 0x97, 0x4d, 0x9a, 0x93, 0x20, 0x34,
+  0x6a, 0xa1, 0xb9, 0x7b, 0x64, 0x85, 0xbf, 0x63, 0xfd, 0x7d, 0x92, 0xaf,
+  0x3f, 0xb0, 0xef, 0x28, 0xdb, 0xa6, 0x5d, 0x83, 0x19, 0x86, 0x53, 0x34,
+  0xfe, 0xd2, 0xce, 0x38, 0x05, 0x51, 0xba, 0xa5, 0x36, 0x73, 0x4f, 0xfe,
+  0xa3, 0xf1, 0x01, 0xee, 0xb4, 0x98, 0x36, 0x94, 0x63, 0xf2, 0x3a, 0x34,
+  0x4c, 0xed, 0xae, 0x08, 0xa0, 0xfa, 0x45, 0x82, 0x01, 0xa6, 0xce, 0x29,
+  0x60, 0xcf, 0x55, 0x8f, 0x7d, 0x44, 0xbb, 0xa1, 0x7b, 0xa8, 0x64, 0x4f,
+  0x0f, 0x80, 0x7e, 0x50, 0x96, 0xcb, 0x3a, 0xac, 0x45, 0xe6, 0x3a, 0x06,
+  0x8f, 0x65, 0x8c, 0xe0, 0xe3, 0xb9, 0xf1, 0xe8, 0xf1, 0xcf, 0x9f, 0xb5,
+  0x36, 0xd4, 0x1f, 0x3f, 0x19, 0x1f, 0x3a, 0x54, 0x26, 0xa1, 0xf6, 0xc5,
+  0x43, 0xaf, 0x64, 0xa5, 0x85, 0xd1, 0x67, 0x28, 0xad, 0x1c, 0x65, 0x7c,
+  0x5c, 0xb9, 0xb3, 0x26, 0xa4, 0x55, 0x95, 0xfb, 0x26, 0x17, 0x1c, 0x52,
+  0x06, 0x31, 0xe0, 0x37, 0x60, 0x95, 0x78, 0x1e, 0xe2, 0x17, 0x7a, 0xce,
+  0xef, 0xa6, 0x6e, 0x80, 0x70, 0x61, 0xbf, 0x1f, 0x27, 0x71, 0x71, 0x39,
+  0x65, 0x78, 0xec, 0x7a, 0xa8, 0x3d, 0xf4, 0x24, 0x3b, 0x5e, 0xc0, 0xa9,
+  0x55, 0x1b, 0xc7, 0x4a, 0x8a, 0x5f, 0xa8, 0x31, 0x82, 0x04, 0x8b, 0x30,
+  0x82, 0x04, 0x87, 0x02, 0x01, 0x01, 0x30, 0x81, 0xf2, 0x30, 0x81, 0xdd,
+  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, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e,
+  0x63, 0x2e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
+  0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72,
+  0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31,
+  0x3b, 0x30, 0x39, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x32, 0x54, 0x65,
+  0x72, 0x6d, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61,
+  0x74, 0x20, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77,
+  0x77, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63,
+  0x6f, 0x6d, 0x2f, 0x72, 0x70, 0x61, 0x20, 0x28, 0x63, 0x29, 0x30, 0x35,
+  0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x15, 0x50,
+  0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x20, 0x4e, 0x6f, 0x74, 0x20, 0x56,
+  0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x31, 0x37, 0x30, 0x35,
+  0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x53,
+  0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x31, 0x20,
+  0x49, 0x6e, 0x64, 0x69, 0x76, 0x69, 0x64, 0x75, 0x61, 0x6c, 0x20, 0x53,
+  0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x20, 0x43, 0x41,
+  0x20, 0x2d, 0x20, 0x47, 0x32, 0x02, 0x10, 0x64, 0x3f, 0x62, 0x62, 0xaa,
+  0xa9, 0x7a, 0xb1, 0x37, 0x26, 0xc1, 0x13, 0x1a, 0x40, 0x3b, 0x48, 0x30,
+  0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0xa0, 0x82,
+  0x02, 0x6d, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x09, 0x03, 0x31, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x09, 0x05, 0x31, 0x0f, 0x17, 0x0d, 0x31, 0x31, 0x30,
+  0x33, 0x31, 0x37, 0x31, 0x32, 0x34, 0x31, 0x32, 0x32, 0x5a, 0x30, 0x23,
+  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04, 0x31,
+  0x16, 0x04, 0x14, 0x61, 0x49, 0xae, 0x84, 0xa6, 0xe6, 0xde, 0x73, 0xce,
+  0x39, 0xb9, 0xdb, 0xf9, 0x40, 0x7d, 0xc6, 0x05, 0xf3, 0x8f, 0xd7, 0x30,
+  0x82, 0x01, 0x03, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37,
+  0x10, 0x04, 0x31, 0x81, 0xf5, 0x30, 0x81, 0xf2, 0x30, 0x81, 0xdd, 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,
+  0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63,
+  0x2e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16,
+  0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75,
+  0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3b,
+  0x30, 0x39, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x32, 0x54, 0x65, 0x72,
+  0x6d, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x74,
+  0x20, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77,
+  0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f,
+  0x6d, 0x2f, 0x72, 0x70, 0x61, 0x20, 0x28, 0x63, 0x29, 0x30, 0x35, 0x31,
+  0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x15, 0x50, 0x65,
+  0x72, 0x73, 0x6f, 0x6e, 0x61, 0x20, 0x4e, 0x6f, 0x74, 0x20, 0x56, 0x61,
+  0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x31, 0x37, 0x30, 0x35, 0x06,
+  0x03, 0x55, 0x04, 0x03, 0x13, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69,
+  0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x31, 0x20, 0x49,
+  0x6e, 0x64, 0x69, 0x76, 0x69, 0x64, 0x75, 0x61, 0x6c, 0x20, 0x53, 0x75,
+  0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x20, 0x43, 0x41, 0x20,
+  0x2d, 0x20, 0x47, 0x32, 0x02, 0x10, 0x64, 0x3f, 0x62, 0x62, 0xaa, 0xa9,
+  0x7a, 0xb1, 0x37, 0x26, 0xc1, 0x13, 0x1a, 0x40, 0x3b, 0x48, 0x30, 0x82,
+  0x01, 0x05, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09,
+  0x10, 0x02, 0x0b, 0x31, 0x81, 0xf5, 0xa0, 0x81, 0xf2, 0x30, 0x81, 0xdd,
+  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, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e,
+  0x63, 0x2e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
+  0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72,
+  0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31,
+  0x3b, 0x30, 0x39, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x32, 0x54, 0x65,
+  0x72, 0x6d, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61,
+  0x74, 0x20, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77,
+  0x77, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63,
+  0x6f, 0x6d, 0x2f, 0x72, 0x70, 0x61, 0x20, 0x28, 0x63, 0x29, 0x30, 0x35,
+  0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x15, 0x50,
+  0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x20, 0x4e, 0x6f, 0x74, 0x20, 0x56,
+  0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x31, 0x37, 0x30, 0x35,
+  0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x53,
+  0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x31, 0x20,
+  0x49, 0x6e, 0x64, 0x69, 0x76, 0x69, 0x64, 0x75, 0x61, 0x6c, 0x20, 0x53,
+  0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x20, 0x43, 0x41,
+  0x20, 0x2d, 0x20, 0x47, 0x32, 0x02, 0x10, 0x64, 0x3f, 0x62, 0x62, 0xaa,
+  0xa9, 0x7a, 0xb1, 0x37, 0x26, 0xc1, 0x13, 0x1a, 0x40, 0x3b, 0x48, 0x30,
+  0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
+  0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0xac, 0x96, 0x0a, 0xba, 0x87, 0xb2,
+  0x35, 0xf7, 0xde, 0x40, 0xce, 0xaf, 0x58, 0x56, 0x76, 0x31, 0x95, 0xc1,
+  0x41, 0x19, 0x76, 0xde, 0x2a, 0x15, 0xed, 0xa4, 0x6d, 0xd5, 0x0a, 0x06,
+  0x15, 0xe9, 0x02, 0x4a, 0xbd, 0x65, 0x93, 0x45, 0xd0, 0x4c, 0x88, 0xa9,
+  0xa4, 0x9f, 0x8f, 0x8b, 0x09, 0x80, 0xf2, 0xbb, 0x97, 0x1c, 0x7c, 0x36,
+  0xf2, 0x52, 0x2e, 0x36, 0xfc, 0x00, 0x5b, 0xd9, 0x97, 0xd2, 0xff, 0x38,
+  0x50, 0x1b, 0x4f, 0x0b, 0x4d, 0x5c, 0x00, 0xa9, 0x6b, 0x61, 0x4f, 0x12,
+  0x7d, 0x3f, 0x61, 0x63, 0xb2, 0x88, 0xc4, 0xae, 0x46, 0x9e, 0x14, 0xcc,
+  0xa8, 0x80, 0xed, 0x17, 0x18, 0x2b, 0x90, 0xd6, 0xe9, 0x8d, 0xa5, 0x1e,
+  0x16, 0xb2, 0x5f, 0x3f, 0x03, 0x57, 0x5c, 0x2d, 0x0c, 0xf0, 0xf7, 0x68,
+  0xa9, 0x5f, 0x93, 0xf3, 0x05, 0xca, 0x6c, 0x28, 0x24, 0x36, 0x1c, 0xdd,
+  0x6c, 0x46, 0x70, 0x37, 0x9e, 0x91, 0x28, 0x57, 0x94, 0x25, 0xc5, 0xf4,
+  0xa2, 0xf7, 0xc6, 0xc3, 0x84, 0xd5, 0x59, 0xfd, 0x61, 0x97, 0xd8, 0x8e,
+  0xe8, 0x03, 0x8e, 0xe3, 0x56, 0xbb, 0x20, 0x49, 0x9c, 0xbb, 0xf4, 0xf8,
+  0x94, 0x25, 0xbd, 0x9f, 0xe2, 0xde, 0xb1, 0xe3, 0xd1, 0x4c, 0x87, 0x3a,
+  0xe4, 0xb2, 0x17, 0xf9, 0xd9, 0xbc, 0x8b, 0x8e, 0xe5, 0x16, 0x7d, 0x84,
+  0x40, 0xec, 0xa2, 0x25, 0x0d, 0xf8, 0x26, 0xe5, 0x81, 0x98, 0x98, 0x80,
+  0xe7, 0x74, 0xf7, 0x46, 0xad, 0x43, 0x08, 0x88, 0xd2, 0x4d, 0x54, 0xd9,
+  0x22, 0x01, 0x8f, 0x6b, 0xf6, 0x9c, 0x04, 0xdb, 0xd5, 0xa7, 0x70, 0x87,
+  0x6d, 0x97, 0x40, 0x61, 0x63, 0x10, 0x14, 0xaf, 0x3f, 0xaf, 0xa4, 0x8c,
+  0x58, 0x01, 0x16, 0x09, 0x70, 0x14, 0x16, 0x9e, 0xd7, 0xda, 0x0f, 0xc1,
+  0x29, 0x3e, 0x3e, 0x0c, 0x81, 0x1b, 0xcf, 0xf6, 0x04, 0x9a, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+unsigned int signed_bin_len = 3676;
+
+unsigned char test_eml[] = {
+  0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65,
+  0x3a, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74, 0x2f,
+  0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x3b,
+  0x0d, 0x0a, 0x09, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x3d,
+  0x22, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x4d, 0x61, 0x69, 0x6c, 0x3d,
+  0x5f, 0x37, 0x41, 0x46, 0x41, 0x43, 0x43, 0x44, 0x43, 0x2d, 0x32, 0x32,
+  0x42, 0x44, 0x2d, 0x34, 0x31, 0x37, 0x33, 0x2d, 0x42, 0x34, 0x42, 0x30,
+  0x2d, 0x37, 0x33, 0x39, 0x32, 0x32, 0x34, 0x46, 0x34, 0x31, 0x35, 0x45,
+  0x30, 0x22, 0x0d, 0x0a, 0x0d, 0x0a, 0x0d, 0x0a, 0x2d, 0x2d, 0x41, 0x70,
+  0x70, 0x6c, 0x65, 0x2d, 0x4d, 0x61, 0x69, 0x6c, 0x3d, 0x5f, 0x37, 0x41,
+  0x46, 0x41, 0x43, 0x43, 0x44, 0x43, 0x2d, 0x32, 0x32, 0x42, 0x44, 0x2d,
+  0x34, 0x31, 0x37, 0x33, 0x2d, 0x42, 0x34, 0x42, 0x30, 0x2d, 0x37, 0x33,
+  0x39, 0x32, 0x32, 0x34, 0x46, 0x34, 0x31, 0x35, 0x45, 0x30, 0x0d, 0x0a,
+  0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x72, 0x61, 0x6e,
+  0x73, 0x66, 0x65, 0x72, 0x2d, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e,
+  0x67, 0x3a, 0x20, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x64, 0x2d, 0x70, 0x72,
+  0x69, 0x6e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x0d, 0x0a, 0x43, 0x6f, 0x6e,
+  0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
+  0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x3b, 0x0d, 0x0a,
+  0x09, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x75, 0x73, 0x2d,
+  0x61, 0x73, 0x63, 0x69, 0x69, 0x0d, 0x0a, 0x0d, 0x0a, 0x49, 0x74, 0x20,
+  0x6c, 0x6f, 0x6f, 0x6b, 0x73, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x74,
+  0x68, 0x65, 0x20, 0x4e, 0x46, 0x41, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x73,
+  0x20, 0x77, 0x65, 0x72, 0x65, 0x20, 0x6e, 0x65, 0x76, 0x65, 0x72, 0x20,
+  0x73, 0x65, 0x6e, 0x74, 0x2e, 0x20, 0x41, 0x70, 0x6f, 0x6c, 0x6f, 0x67,
+  0x69, 0x65, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x61, 0x74,
+  0x2e, 0x20, 0x49, 0x27, 0x6d, 0x20, 0x3d, 0x0d, 0x0a, 0x73, 0x65, 0x6e,
+  0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x20, 0x6e, 0x6f,
+  0x77, 0x2e, 0x0d, 0x0a, 0x0d, 0x0a, 0x43, 0x6f, 0x72, 0x6d, 0x61, 0x63,
+  0x0d, 0x0a, 0x0d, 0x0a, 0x4f, 0x6e, 0x20, 0x31, 0x37, 0x20, 0x4d, 0x61,
+  0x72, 0x20, 0x32, 0x30, 0x31, 0x31, 0x2c, 0x20, 0x61, 0x74, 0x20, 0x31,
+  0x32, 0x3a, 0x33, 0x32, 0x2c, 0x20, 0x4a, 0x65, 0x72, 0x65, 0x6d, 0x79,
+  0x20, 0x57, 0x79, 0x6c, 0x64, 0x20, 0x77, 0x72, 0x6f, 0x74, 0x65, 0x3a,
+  0x0d, 0x0a, 0x0d, 0x0a, 0x3e, 0x20, 0x49, 0x73, 0x20, 0x74, 0x68, 0x65,
+  0x72, 0x65, 0x20, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x20, 0x66, 0x6f,
+  0x72, 0x20, 0x6e, 0x6f, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73,
+  0x20, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x20, 0x39, 0x41, 0x31, 0x36, 0x30,
+  0x20, 0x6f, 0x6e, 0x20, 0x4d, 0x6f, 0x6e, 0x64, 0x61, 0x79, 0x3f, 0x20,
+  0x20, 0x49, 0x20, 0x6e, 0x65, 0x65, 0x64, 0x20, 0x73, 0x74, 0x75, 0x66,
+  0x66, 0x20, 0x3d, 0x0d, 0x0a, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x69,
+  0x73, 0x20, 0x69, 0x6e, 0x20, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x20,
+  0x62, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x2e, 0x0d, 0x0a, 0x3e, 0x3d, 0x32,
+  0x30, 0x0d, 0x0a, 0x3e, 0x20, 0x6a, 0x65, 0x72, 0x65, 0x6d, 0x79, 0x0d,
+  0x0a, 0x3e, 0x3d, 0x32, 0x30, 0x0d, 0x0a, 0x3e, 0x20, 0x4f, 0x6e, 0x20,
+  0x4d, 0x61, 0x72, 0x20, 0x31, 0x34, 0x2c, 0x20, 0x32, 0x30, 0x31, 0x31,
+  0x2c, 0x20, 0x61, 0x74, 0x20, 0x31, 0x30, 0x3a, 0x33, 0x36, 0x20, 0x41,
+  0x4d, 0x2c, 0x20, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x20,
+  0x42, 0x75, 0x69, 0x6c, 0x64, 0x20, 0x54, 0x65, 0x61, 0x6d, 0x20, 0x77,
+  0x72, 0x6f, 0x74, 0x65, 0x3a, 0x0d, 0x0a, 0x3e, 0x3d, 0x32, 0x30, 0x0d,
+  0x0a, 0x3e, 0x3e, 0x20, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x3e,
+  0x3e, 0x20, 0x2d, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x62, 0x75, 0x69,
+  0x6c, 0x64, 0x20, 0x68, 0x61, 0x73, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x20,
+  0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72,
+  0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x6e, 0x20,
+  0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68,
+  0x20, 0x3d, 0x0d, 0x0a, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d,
+  0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x6c, 0x69, 0x63, 0x6f, 0x6e, 0x20,
+  0x6f, 0x6e, 0x6c, 0x79, 0x2e, 0x20, 0x41, 0x20, 0x66, 0x6f, 0x6c, 0x6c,
+  0x6f, 0x77, 0x2d, 0x75, 0x70, 0x20, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x20,
+  0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x74,
+  0x20, 0x69, 0x66, 0x2f, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x69,
+  0x73, 0x20, 0x3d, 0x0d, 0x0a, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x20, 0x69,
+  0x73, 0x20, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x64, 0x20, 0x66,
+  0x6f, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x20, 0x6f,
+  0x6e, 0x20, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e,
+  0x20, 0x73, 0x69, 0x6c, 0x69, 0x63, 0x6f, 0x6e, 0x2e, 0x20, 0x46, 0x6f,
+  0x72, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x3d, 0x0d, 0x0a, 0x69, 0x6e,
+  0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x73,
+  0x65, 0x65, 0x20, 0x68, 0x6f, 0x77, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x64,
+  0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x20, 0x69, 0x66, 0x20, 0x61, 0x20,
+  0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x20, 0x68, 0x61, 0x73, 0x20, 0x70,
+  0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x69,
+  0x6c, 0x69, 0x63, 0x6f, 0x6e, 0x2e, 0x0d, 0x0a, 0x3e, 0x3e, 0x20, 0x2d,
+  0x20, 0x49, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x68, 0x61, 0x76, 0x65,
+  0x20, 0x74, 0x72, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x72, 0x65, 0x73,
+  0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20,
+  0x62, 0x75, 0x69, 0x6c, 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x79, 0x6f, 0x75,
+  0x72, 0x20, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2c, 0x20, 0x73, 0x65,
+  0x65, 0x20, 0x3d, 0x0d, 0x0a, 0x50, 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d,
+  0x73, 0x20, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x20,
+  0x66, 0x6f, 0x72, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x69, 0x6e, 0x66,
+  0x6f, 0x2e, 0x0d, 0x0a, 0x3e, 0x3e, 0x3d, 0x32, 0x30, 0x0d, 0x0a, 0x3e,
+  0x3e, 0x20, 0x54, 0x33, 0x39, 0x20, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63,
+  0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x54, 0x33, 0x39, 0x20, 0x77,
+  0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x64, 0x65, 0x70, 0x72, 0x65,
+  0x63, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74,
+  0x68, 0x65, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x20, 0x72, 0x65, 0x6c,
+  0x65, 0x61, 0x73, 0x65, 0x64, 0x20, 0x3d, 0x0d, 0x0a, 0x4d, 0x6f, 0x6e,
+  0x64, 0x61, 0x79, 0x20, 0x6d, 0x6f, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x2c,
+  0x20, 0x4d, 0x61, 0x72, 0x20, 0x31, 0x34, 0x2e, 0x3d, 0x32, 0x30, 0x0d,
+  0x0a, 0x3e, 0x3e, 0x3d, 0x32, 0x30, 0x0d, 0x0a, 0x3e, 0x3e, 0x20, 0x46,
+  0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x63, 0x68,
+  0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20, 0x49, 0x66, 0x20, 0x61, 0x20,
+  0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x20, 0x77, 0x61, 0x73, 0x20, 0x65,
+  0x72, 0x61, 0x73, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c,
+  0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x3d, 0x0d, 0x0a, 0x54,
+  0x65, 0x6c, 0x6c, 0x75, 0x72, 0x69, 0x64, 0x65, 0x39, 0x41, 0x31, 0x33,
+  0x38, 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x61, 0x74, 0x65, 0x72, 0x2c, 0x20,
+  0x69, 0x74, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x68, 0x61, 0x76, 0x65,
+  0x20, 0x74, 0x6f, 0x20, 0x67, 0x6f, 0x20, 0x74, 0x68, 0x72, 0x6f, 0x75,
+  0x67, 0x68, 0x20, 0x61, 0x20, 0x6d, 0x61, 0x6e, 0x64, 0x61, 0x74, 0x6f,
+  0x72, 0x79, 0x20, 0x65, 0x72, 0x61, 0x73, 0x65, 0x20, 0x3d, 0x0d, 0x0a,
+  0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x20, 0x61, 0x67, 0x61, 0x69,
+  0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x39, 0x41, 0x31, 0x34, 0x39,
+  0x20, 0x28, 0x6f, 0x72, 0x20, 0x6c, 0x61, 0x74, 0x65, 0x72, 0x29, 0x20,
+  0x74, 0x6f, 0x20, 0x70, 0x69, 0x63, 0x6b, 0x20, 0x75, 0x70, 0x20, 0x6e,
+  0x65, 0x77, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65,
+  0x6d, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x2e, 0x20, 0x3d,
+  0x0d, 0x0a, 0x49, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x73, 0x63,
+  0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x2c, 0x20, 0x75, 0x70, 0x64, 0x61,
+  0x74, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x73, 0x20,
+  0x77, 0x69, 0x6c, 0x6c, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x20, 0x77, 0x69,
+  0x74, 0x68, 0x20, 0x61, 0x20, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x65,
+  0x72, 0x72, 0x6f, 0x72, 0x2c, 0x20, 0x73, 0x6f, 0x20, 0x74, 0x68, 0x61,
+  0x74, 0x20, 0x3d, 0x0d, 0x0a, 0x74, 0x68, 0x65, 0x20, 0x64, 0x61, 0x74,
+  0x61, 0x20, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69,
+  0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x6f,
+  0x72, 0x72, 0x75, 0x70, 0x74, 0x65, 0x64, 0x2e, 0x20, 0x50, 0x65, 0x6f,
+  0x70, 0x6c, 0x65, 0x20, 0x77, 0x68, 0x6f, 0x20, 0x68, 0x61, 0x76, 0x65,
+  0x20, 0x6e, 0x6f, 0x74, 0x20, 0x65, 0x72, 0x61, 0x73, 0x65, 0x20, 0x3d,
+  0x0d, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20,
+  0x74, 0x68, 0x65, 0x69, 0x72, 0x20, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65,
+  0x73, 0x20, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x20, 0x39, 0x41, 0x31, 0x33,
+  0x38, 0x20, 0x61, 0x72, 0x65, 0x20, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74,
+  0x6f, 0x20, 0x6b, 0x65, 0x65, 0x70, 0x20, 0x64, 0x6f, 0x69, 0x6e, 0x67,
+  0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x3d, 0x0d, 0x0a, 0x69,
+  0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x73, 0x20, 0x61, 0x73, 0x20, 0x75,
+  0x73, 0x75, 0x61, 0x6c, 0x2e, 0x20, 0x3c, 0x72, 0x64, 0x61, 0x72, 0x3a,
+  0x2f, 0x2f, 0x38, 0x35, 0x33, 0x31, 0x36, 0x37, 0x34, 0x3e, 0x3d, 0x32,
+  0x30, 0x0d, 0x0a, 0x3e, 0x3e, 0x3d, 0x32, 0x30, 0x0d, 0x0a, 0x3e, 0x3e,
+  0x20, 0x43, 0x61, 0x6c, 0x65, 0x6e, 0x64, 0x61, 0x72, 0x20, 0x61, 0x6c,
+  0x65, 0x72, 0x74, 0x73, 0x3a, 0x20, 0x41, 0x73, 0x20, 0x6f, 0x66, 0x20,
+  0x39, 0x41, 0x31, 0x34, 0x39, 0x2c, 0x20, 0x63, 0x61, 0x6c, 0x65, 0x6e,
+  0x64, 0x61, 0x72, 0x20, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x20, 0x6e,
+  0x6f, 0x77, 0x20, 0x67, 0x6f, 0x20, 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67,
+  0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x3d, 0x0d, 0x0a, 0x42, 0x75, 0x6c,
+  0x6c, 0x65, 0x74, 0x69, 0x6e, 0x20, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x20,
+  0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x20, 0x42, 0x65, 0x63,
+  0x61, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73,
+  0x2c, 0x20, 0x63, 0x61, 0x6c, 0x65, 0x6e, 0x64, 0x61, 0x72, 0x20, 0x61,
+  0x6c, 0x65, 0x72, 0x74, 0x73, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x6e,
+  0x6f, 0x74, 0x20, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x20, 0x3d, 0x0d,
+  0x0a, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x6f,
+  0x63, 0x6b, 0x20, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x75, 0x6e,
+  0x74, 0x69, 0x6c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x65, 0x61,
+  0x74, 0x75, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x69, 0x6d, 0x70, 0x6c,
+  0x65, 0x6d, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x42,
+  0x42, 0x2e, 0x20, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x20, 0x3d,
+  0x0d, 0x0a, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x63, 0x6f, 0x6e,
+  0x74, 0x69, 0x6e, 0x75, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x70, 0x70,
+  0x65, 0x61, 0x72, 0x2c, 0x20, 0x68, 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72,
+  0x2e, 0x3d, 0x32, 0x30, 0x0d, 0x0a, 0x3e, 0x3e, 0x3d, 0x32, 0x30, 0x0d,
+  0x0a, 0x3e, 0x3e, 0x20, 0x49, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x66, 0x69,
+  0x6c, 0x65, 0x64, 0x20, 0x63, 0x72, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67,
+  0x20, 0x6f, 0x6e, 0x20, 0x79, 0x6f, 0x75, 0x3f, 0x20, 0x49, 0x74, 0x27,
+  0x73, 0x20, 0x70, 0x72, 0x6f, 0x62, 0x61, 0x62, 0x6c, 0x79, 0x20, 0x64,
+  0x75, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x62, 0x75, 0x67, 0x20,
+  0x69, 0x6e, 0x20, 0x39, 0x41, 0x31, 0x34, 0x37, 0x20, 0x2d, 0x20, 0x3d,
+  0x0d, 0x0a, 0x3c, 0x72, 0x64, 0x61, 0x72, 0x3a, 0x2f, 0x2f, 0x70, 0x72,
+  0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x2f, 0x39, 0x30, 0x37, 0x34, 0x37, 0x33,
+  0x31, 0x3e, 0x3d, 0x32, 0x30, 0x0d, 0x0a, 0x3e, 0x3e, 0x20, 0x54, 0x68,
+  0x65, 0x20, 0x66, 0x69, 0x78, 0x20, 0x77, 0x65, 0x6e, 0x74, 0x20, 0x69,
+  0x6e, 0x74, 0x6f, 0x20, 0x39, 0x41, 0x31, 0x34, 0x38, 0x2c, 0x20, 0x62,
+  0x75, 0x74, 0x20, 0x69, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x75, 0x70,
+  0x64, 0x61, 0x74, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c,
+  0x20, 0x79, 0x6f, 0x75, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x61, 0x6c,
+  0x73, 0x6f, 0x20, 0x6e, 0x65, 0x65, 0x64, 0x20, 0x3d, 0x0d, 0x0a, 0x74,
+  0x6f, 0x20, 0x70, 0x6c, 0x61, 0x79, 0x20, 0x77, 0x68, 0x61, 0x63, 0x6b,
+  0x2d, 0x61, 0x2d, 0x66, 0x69, 0x6c, 0x65, 0x3a, 0x3d, 0x32, 0x30, 0x0d,
+  0x0a, 0x3e, 0x3e, 0x20, 0x72, 0x6d, 0x20, 0x2f, 0x76, 0x61, 0x72, 0x2f,
+  0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x2f, 0x4c, 0x69, 0x62, 0x72, 0x61,
+  0x72, 0x79, 0x2f, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61,
+  0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73,
+  0x2f, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x2f,
+  0x54, 0x72, 0x75, 0x74, 0x68, 0x2e, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x3d,
+  0x32, 0x30, 0x3d, 0x0d, 0x0a, 0x0d, 0x0a, 0x3e, 0x3e, 0x3d, 0x32, 0x30,
+  0x0d, 0x0a, 0x3e, 0x3e, 0x20, 0x4a, 0x32, 0x20, 0x44, 0x45, 0x56, 0x31,
+  0x20, 0x75, 0x73, 0x65, 0x72, 0x73, 0x3a, 0x20, 0x59, 0x6f, 0x75, 0x20,
+  0x6d, 0x75, 0x73, 0x74, 0x20, 0x44, 0x46, 0x55, 0x20, 0x79, 0x6f, 0x75,
+  0x72, 0x20, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x20, 0x69, 0x6e, 0x20,
+  0x6f, 0x72, 0x64, 0x65, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6e, 0x73,
+  0x74, 0x61, 0x6c, 0x6c, 0x20, 0x39, 0x41, 0x31, 0x34, 0x39, 0x20, 0x28,
+  0x6f, 0x72, 0x20, 0x3d, 0x0d, 0x0a, 0x6c, 0x61, 0x74, 0x65, 0x72, 0x29,
+  0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67,
+  0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x6e, 0x20, 0x65, 0x61, 0x72,
+  0x6c, 0x69, 0x65, 0x72, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x2e, 0x20,
+  0x3c, 0x72, 0x64, 0x61, 0x72, 0x3a, 0x2f, 0x2f, 0x39, 0x30, 0x37, 0x36,
+  0x33, 0x38, 0x31, 0x3e, 0x3d, 0x32, 0x30, 0x0d, 0x0a, 0x3e, 0x3e, 0x3d,
+  0x32, 0x30, 0x0d, 0x0a, 0x3e, 0x3e, 0x20, 0x4e, 0x39, 0x34, 0x20, 0x50,
+  0x72, 0x6f, 0x74, 0x6f, 0x31, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x50, 0x72,
+  0x6f, 0x74, 0x6f, 0x32, 0x20, 0x61, 0x72, 0x65, 0x20, 0x68, 0x65, 0x72,
+  0x65, 0x62, 0x79, 0x20, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74,
+  0x65, 0x64, 0x2e, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x4f, 0x53, 0x20,
+  0x61, 0x6e, 0x64, 0x20, 0x54, 0x65, 0x6c, 0x65, 0x70, 0x68, 0x6f, 0x6e,
+  0x79, 0x20, 0x3d, 0x0d, 0x0a, 0x74, 0x65, 0x61, 0x6d, 0x73, 0x20, 0x62,
+  0x6f, 0x74, 0x68, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x63, 0x68, 0x61,
+  0x6e, 0x67, 0x65, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x72, 0x65,
+  0x71, 0x75, 0x69, 0x72, 0x65, 0x20, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63,
+  0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x20,
+  0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x2e, 0x20, 0x49, 0x66,
+  0x20, 0x79, 0x6f, 0x75, 0x20, 0x3d, 0x0d, 0x0a, 0x73, 0x74, 0x69, 0x6c,
+  0x6c, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x50, 0x72, 0x6f, 0x74, 0x6f,
+  0x31, 0x20, 0x6f, 0x72, 0x20, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x20,
+  0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x2c, 0x20, 0x67, 0x6f,
+  0x20, 0x67, 0x65, 0x74, 0x20, 0x61, 0x20, 0x50, 0x72, 0x6f, 0x74, 0x6f,
+  0x33, 0x2e, 0x20, 0x59, 0x6f, 0x75, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20,
+  0x6e, 0x6f, 0x20, 0x3d, 0x0d, 0x0a, 0x65, 0x78, 0x63, 0x75, 0x73, 0x65,
+  0x2e, 0x3d, 0x32, 0x30, 0x0d, 0x0a, 0x3e, 0x3e, 0x3d, 0x32, 0x30, 0x0d,
+  0x0a, 0x3e, 0x3e, 0x20, 0x42, 0x61, 0x73, 0x65, 0x62, 0x61, 0x6e, 0x64,
+  0x20, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x20, 0x6f, 0x6e, 0x20,
+  0x4e, 0x39, 0x34, 0x3a, 0x20, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x20, 0x22,
+  0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x42, 0x61, 0x73, 0x65, 0x62,
+  0x61, 0x6e, 0x64, 0x22, 0x20, 0x75, 0x6e, 0x63, 0x68, 0x65, 0x63, 0x6b,
+  0x65, 0x64, 0x2e, 0x20, 0x59, 0x6f, 0x75, 0x72, 0x20, 0x3d, 0x0d, 0x0a,
+  0x42, 0x61, 0x73, 0x65, 0x62, 0x61, 0x6e, 0x64, 0x20, 0x77, 0x69, 0x6c,
+  0x6c, 0x20, 0x62, 0x65, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64,
+  0x20, 0x61, 0x6e, 0x79, 0x77, 0x61, 0x79, 0x73, 0x2c, 0x20, 0x61, 0x6e,
+  0x64, 0x20, 0x6c, 0x65, 0x61, 0x76, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x74,
+  0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x20, 0x77, 0x69, 0x6c,
+  0x6c, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x2e, 0x20, 0x3d, 0x0d, 0x0a, 0x54,
+  0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x3c, 0x72,
+  0x64, 0x61, 0x72, 0x3a, 0x2f, 0x2f, 0x38, 0x37, 0x33, 0x30, 0x38, 0x30,
+  0x34, 0x3e, 0x3d, 0x32, 0x30, 0x0d, 0x0a, 0x3e, 0x3e, 0x3d, 0x32, 0x30,
+  0x0d, 0x0a, 0x3e, 0x3e, 0x3d, 0x32, 0x30, 0x0d, 0x0a, 0x3e, 0x3e, 0x20,
+  0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x20, 0x53, 0x65, 0x74, 0x75,
+  0x70, 0x3d, 0x32, 0x30, 0x0d, 0x0a, 0x3e, 0x3e, 0x20, 0x50, 0x6c, 0x65,
+  0x61, 0x73, 0x65, 0x20, 0x6d, 0x61, 0x6b, 0x65, 0x20, 0x73, 0x75, 0x72,
+  0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x74,
+  0x75, 0x72, 0x6e, 0x20, 0x6f, 0x66, 0x66, 0x20, 0x43, 0x72, 0x61, 0x73,
+  0x68, 0x54, 0x72, 0x61, 0x63, 0x65, 0x72, 0x20, 0x77, 0x69, 0x74, 0x68,
+  0x20, 0x22, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x20, 0x77,
+  0x72, 0x69, 0x74, 0x65, 0x20, 0x3d, 0x0d, 0x0a, 0x63, 0x6f, 0x6d, 0x2e,
+  0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x43, 0x72, 0x61, 0x73, 0x68, 0x52,
+  0x65, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x20, 0x41, 0x75, 0x74, 0x6f,
+  0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x20, 0x4e, 0x4f, 0x22, 0x20, 0x6f,
+  0x6e, 0x20, 0x79, 0x6f, 0x75, 0x72, 0x20, 0x68, 0x6f, 0x73, 0x74, 0x20,
+  0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20,
+  0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x3d, 0x0d, 0x0a, 0x74, 0x68, 0x65,
+  0x20, 0x73, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x3d,
+  0x32, 0x30, 0x0d, 0x0a, 0x3e, 0x3e, 0x3d, 0x32, 0x30, 0x0d, 0x0a, 0x3e,
+  0x3e, 0x20, 0x4e, 0x6f, 0x6e, 0x2d, 0x55, 0x49, 0x20, 0x46, 0x61, 0x63,
+  0x74, 0x6f, 0x72, 0x79, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72,
+  0x65, 0x20, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x0d, 0x0a,
+  0x3e, 0x3e, 0x20, 0x3c, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c,
+  0x6f, 0x63, 0x6b, 0x65, 0x72, 0x72, 0x6f, 0x6f, 0x6d, 0x2f, 0x50, 0x61,
+  0x72, 0x74, 0x46, 0x6f, 0x72, 0x6d, 0x3f, 0x36, 0x39, 0x34, 0x2d, 0x36,
+  0x32, 0x37, 0x36, 0x2d, 0x33, 0x30, 0x34, 0x3e, 0x20, 0x69, 0x50, 0x68,
+  0x6f, 0x6e, 0x65, 0x2f, 0x69, 0x50, 0x6f, 0x64, 0x20, 0x74, 0x6f, 0x75,
+  0x63, 0x68, 0x20, 0x35, 0x2e, 0x30, 0x20, 0x3d, 0x0d, 0x0a, 0x4e, 0x6f,
+  0x6e, 0x55, 0x49, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x20, 0x28,
+  0x54, 0x65, 0x6c, 0x6c, 0x75, 0x72, 0x69, 0x64, 0x65, 0x29, 0x0d, 0x0a,
+  0x3e, 0x3e, 0x20, 0x3c, 0x6e, 0x66, 0x61, 0x3a, 0x64, 0x6f, 0x63, 0x75,
+  0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x33, 0x39, 0x34, 0x35, 0x31, 0x39, 0x36,
+  0x3e, 0x0d, 0x0a, 0x3e, 0x3e, 0x3d, 0x32, 0x30, 0x0d, 0x0a, 0x3e, 0x3e,
+  0x3d, 0x32, 0x30, 0x0d, 0x0a, 0x3e, 0x3e, 0x20, 0x54, 0x68, 0x69, 0x73,
+  0x20, 0x65, 0x2d, 0x6d, 0x61, 0x69, 0x6c, 0x20, 0x77, 0x61, 0x73, 0x20,
+  0x73, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x3d, 0x0d, 0x0a, 0x74,
+  0x65, 0x6c, 0x6c, 0x75, 0x72, 0x69, 0x64, 0x65, 0x5f, 0x72, 0x65, 0x6d,
+  0x6f, 0x74, 0x65, 0x5f, 0x6e, 0x66, 0x61, 0x40, 0x67, 0x72, 0x6f, 0x75,
+  0x70, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2c,
+  0x74, 0x65, 0x6c, 0x6c, 0x75, 0x72, 0x69, 0x64, 0x65, 0x2d, 0x6e, 0x6f,
+  0x6e, 0x75, 0x69, 0x2d, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x40, 0x67,
+  0x72, 0x6f, 0x75, 0x70, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63,
+  0x6f, 0x3d, 0x0d, 0x0a, 0x6d, 0x2c, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64,
+  0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65,
+  0x2e, 0x63, 0x6f, 0x6d, 0x20, 0x62, 0x79, 0x20, 0x45, 0x6d, 0x62, 0x65,
+  0x64, 0x64, 0x65, 0x64, 0x20, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x20, 0x54,
+  0x65, 0x61, 0x6d, 0x20, 0x3c, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x40,
+  0x67, 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e,
+  0x63, 0x6f, 0x6d, 0x3e, 0x20, 0x3d, 0x0d, 0x0a, 0x61, 0x74, 0x20, 0x30,
+  0x33, 0x2f, 0x31, 0x34, 0x2f, 0x32, 0x30, 0x31, 0x31, 0x20, 0x31, 0x30,
+  0x3a, 0x33, 0x36, 0x3a, 0x31, 0x31, 0x2e, 0x0d, 0x0a, 0x3e, 0x3e, 0x20,
+  0x41, 0x20, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c,
+  0x20, 0x63, 0x6f, 0x70, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69,
+  0x73, 0x20, 0x65, 0x2d, 0x6d, 0x61, 0x69, 0x6c, 0x20, 0x69, 0x73, 0x20,
+  0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x74,
+  0x20, 0x3d, 0x0d, 0x0a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c,
+  0x6f, 0x63, 0x6b, 0x65, 0x72, 0x72, 0x6f, 0x6f, 0x6d, 0x2f, 0x6e, 0x6f,
+  0x74, 0x65, 0x73, 0x2f, 0x6e, 0x6f, 0x6e, 0x75, 0x69, 0x5f, 0x72, 0x65,
+  0x6d, 0x6f, 0x74, 0x65, 0x2f, 0x54, 0x65, 0x6c, 0x6c, 0x75, 0x72, 0x69,
+  0x64, 0x65, 0x2f, 0x54, 0x65, 0x6c, 0x6c, 0x75, 0x72, 0x69, 0x64, 0x65,
+  0x39, 0x41, 0x31, 0x36, 0x30, 0x2e, 0x70, 0x68, 0x70, 0x2e, 0x0d, 0x0a,
+  0x3e, 0x3e, 0x20, 0x3d, 0x32, 0x30, 0x0d, 0x0a, 0x3e, 0x3d, 0x32, 0x30,
+  0x0d, 0x0a, 0x0d, 0x0a, 0x0d, 0x0a, 0x2d, 0x2d, 0x41, 0x70, 0x70, 0x6c,
+  0x65, 0x2d, 0x4d, 0x61, 0x69, 0x6c, 0x3d, 0x5f, 0x37, 0x41, 0x46, 0x41,
+  0x43, 0x43, 0x44, 0x43, 0x2d, 0x32, 0x32, 0x42, 0x44, 0x2d, 0x34, 0x31,
+  0x37, 0x33, 0x2d, 0x42, 0x34, 0x42, 0x30, 0x2d, 0x37, 0x33, 0x39, 0x32,
+  0x32, 0x34, 0x46, 0x34, 0x31, 0x35, 0x45, 0x30, 0x0d, 0x0a, 0x43, 0x6f,
+  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66,
+  0x65, 0x72, 0x2d, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3a,
+  0x20, 0x37, 0x62, 0x69, 0x74, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65,
+  0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78,
+  0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3b, 0x0d, 0x0a, 0x09, 0x63, 0x68,
+  0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x75, 0x73, 0x2d, 0x61, 0x73, 0x63,
+  0x69, 0x69, 0x0d, 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e,
+  0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64,
+  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65,
+  0x3d, 0x22, 0x77, 0x6f, 0x72, 0x64, 0x2d, 0x77, 0x72, 0x61, 0x70, 0x3a,
+  0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x2d, 0x77, 0x6f, 0x72, 0x64, 0x3b,
+  0x20, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x6e, 0x62, 0x73,
+  0x70, 0x2d, 0x6d, 0x6f, 0x64, 0x65, 0x3a, 0x20, 0x73, 0x70, 0x61, 0x63,
+  0x65, 0x3b, 0x20, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x6c,
+  0x69, 0x6e, 0x65, 0x2d, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3a, 0x20, 0x61,
+  0x66, 0x74, 0x65, 0x72, 0x2d, 0x77, 0x68, 0x69, 0x74, 0x65, 0x2d, 0x73,
+  0x70, 0x61, 0x63, 0x65, 0x3b, 0x20, 0x22, 0x3e, 0x49, 0x74, 0x20, 0x6c,
+  0x6f, 0x6f, 0x6b, 0x73, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x74, 0x68,
+  0x65, 0x20, 0x4e, 0x46, 0x41, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x20,
+  0x77, 0x65, 0x72, 0x65, 0x20, 0x6e, 0x65, 0x76, 0x65, 0x72, 0x20, 0x73,
+  0x65, 0x6e, 0x74, 0x2e, 0x20, 0x41, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x69,
+  0x65, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x61, 0x74, 0x2e,
+  0x20, 0x49, 0x27, 0x6d, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67,
+  0x20, 0x74, 0x68, 0x65, 0x6d, 0x20, 0x6e, 0x6f, 0x77, 0x2e, 0x3c, 0x64,
+  0x69, 0x76, 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76,
+  0x3e, 0x3c, 0x64, 0x69, 0x76, 0x3e, 0x43, 0x6f, 0x72, 0x6d, 0x61, 0x63,
+  0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x3e, 0x3c,
+  0x62, 0x72, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x64, 0x69, 0x76,
+  0x3e, 0x4f, 0x6e, 0x20, 0x31, 0x37, 0x20, 0x4d, 0x61, 0x72, 0x20, 0x32,
+  0x30, 0x31, 0x31, 0x2c, 0x20, 0x61, 0x74, 0x20, 0x31, 0x32, 0x3a, 0x33,
+  0x32, 0x2c, 0x20, 0x4a, 0x65, 0x72, 0x65, 0x6d, 0x79, 0x20, 0x57, 0x79,
+  0x6c, 0x64, 0x20, 0x77, 0x72, 0x6f, 0x74, 0x65, 0x3a, 0x3c, 0x2f, 0x64,
+  0x69, 0x76, 0x3e, 0x3c, 0x62, 0x72, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73,
+  0x3d, 0x22, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x69, 0x6e, 0x74, 0x65,
+  0x72, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2d, 0x6e, 0x65, 0x77, 0x6c,
+  0x69, 0x6e, 0x65, 0x22, 0x3e, 0x3c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x71,
+  0x75, 0x6f, 0x74, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x63,
+  0x69, 0x74, 0x65, 0x22, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x73, 0x74,
+  0x79, 0x6c, 0x65, 0x3d, 0x22, 0x77, 0x6f, 0x72, 0x64, 0x2d, 0x77, 0x72,
+  0x61, 0x70, 0x3a, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x2d, 0x77, 0x6f,
+  0x72, 0x64, 0x3b, 0x20, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d,
+  0x6e, 0x62, 0x73, 0x70, 0x2d, 0x6d, 0x6f, 0x64, 0x65, 0x3a, 0x20, 0x73,
+  0x70, 0x61, 0x63, 0x65, 0x3b, 0x20, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69,
+  0x74, 0x2d, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x62, 0x72, 0x65, 0x61, 0x6b,
+  0x3a, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x2d, 0x77, 0x68, 0x69, 0x74,
+  0x65, 0x2d, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3b, 0x20, 0x22, 0x3e, 0x49,
+  0x73, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x72, 0x65, 0x61, 0x73,
+  0x6f, 0x6e, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x20, 0x75, 0x70,
+  0x64, 0x61, 0x74, 0x65, 0x73, 0x20, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x20,
+  0x39, 0x41, 0x31, 0x36, 0x30, 0x20, 0x6f, 0x6e, 0x20, 0x4d, 0x6f, 0x6e,
+  0x64, 0x61, 0x79, 0x3f, 0x20, 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x49,
+  0x20, 0x6e, 0x65, 0x65, 0x64, 0x20, 0x73, 0x74, 0x75, 0x66, 0x66, 0x20,
+  0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x69, 0x73, 0x20, 0x69, 0x6e, 0x20,
+  0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x64,
+  0x73, 0x2e, 0x3c, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0x3c,
+  0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x3e, 0x6a, 0x65,
+  0x72, 0x65, 0x6d, 0x79, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x64,
+  0x69, 0x76, 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x3e,
+  0x3c, 0x64, 0x69, 0x76, 0x3e, 0x4f, 0x6e, 0x20, 0x4d, 0x61, 0x72, 0x20,
+  0x31, 0x34, 0x2c, 0x20, 0x32, 0x30, 0x31, 0x31, 0x2c, 0x20, 0x61, 0x74,
+  0x20, 0x31, 0x30, 0x3a, 0x33, 0x36, 0x20, 0x41, 0x4d, 0x2c, 0x20, 0x45,
+  0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x20, 0x42, 0x75, 0x69, 0x6c,
+  0x64, 0x20, 0x54, 0x65, 0x61, 0x6d, 0x20, 0x77, 0x72, 0x6f, 0x74, 0x65,
+  0x3a, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x62, 0x72, 0x20, 0x63,
+  0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2d,
+  0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2d,
+  0x6e, 0x65, 0x77, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x3e, 0x3c, 0x62, 0x6c,
+  0x6f, 0x63, 0x6b, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x20, 0x74, 0x79, 0x70,
+  0x65, 0x3d, 0x22, 0x63, 0x69, 0x74, 0x65, 0x22, 0x3e, 0x3c, 0x64, 0x69,
+  0x76, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x77, 0x6f, 0x72,
+  0x64, 0x2d, 0x77, 0x72, 0x61, 0x70, 0x3a, 0x20, 0x62, 0x72, 0x65, 0x61,
+  0x6b, 0x2d, 0x77, 0x6f, 0x72, 0x64, 0x3b, 0x20, 0x2d, 0x77, 0x65, 0x62,
+  0x6b, 0x69, 0x74, 0x2d, 0x6e, 0x62, 0x73, 0x70, 0x2d, 0x6d, 0x6f, 0x64,
+  0x65, 0x3a, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3b, 0x20, 0x2d, 0x77,
+  0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x62,
+  0x72, 0x65, 0x61, 0x6b, 0x3a, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x2d,
+  0x77, 0x68, 0x69, 0x74, 0x65, 0x2d, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3b,
+  0x20, 0x22, 0x3e, 0x0d, 0x0a, 0x0d, 0x0a, 0x3c, 0x74, 0x61, 0x62, 0x6c,
+  0x65, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3d, 0x22, 0x30, 0x22,
+  0x20, 0x63, 0x65, 0x6c, 0x6c, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67,
+  0x3d, 0x22, 0x30, 0x22, 0x20, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x70, 0x61,
+  0x63, 0x69, 0x6e, 0x67, 0x3d, 0x22, 0x30, 0x22, 0x20, 0x77, 0x69, 0x64,
+  0x74, 0x68, 0x3d, 0x22, 0x31, 0x30, 0x30, 0x25, 0x22, 0x3e, 0x0d, 0x0a,
+  0x3c, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x74, 0x72, 0x3e, 0x3c,
+  0x74, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x22, 0x74,
+  0x6f, 0x70, 0x22, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 0x34,
+  0x38, 0x25, 0x22, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x77,
+  0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x34, 0x38, 0x25, 0x22, 0x3e, 0x0d,
+  0x0a, 0x0d, 0x0a, 0x3c, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x63, 0x6c, 0x61,
+  0x73, 0x73, 0x3d, 0x22, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x73, 0x74,
+  0x79, 0x6c, 0x65, 0x2d, 0x73, 0x70, 0x61, 0x6e, 0x22, 0x20, 0x66, 0x61,
+  0x63, 0x65, 0x3d, 0x22, 0x48, 0x65, 0x6c, 0x76, 0x65, 0x74, 0x69, 0x63,
+  0x61, 0x22, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x3d, 0x22, 0x33, 0x22, 0x3e,
+  0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d,
+  0x22, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x73, 0x74, 0x79, 0x6c, 0x65,
+  0x2d, 0x73, 0x70, 0x61, 0x6e, 0x22, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65,
+  0x3d, 0x22, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a,
+  0x20, 0x31, 0x32, 0x70, 0x78, 0x3b, 0x22, 0x3e, 0x0d, 0x0a, 0x3c, 0x64,
+  0x69, 0x76, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61,
+  0x72, 0x67, 0x69, 0x6e, 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x20, 0x31, 0x70,
+  0x78, 0x3b, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x72, 0x69,
+  0x67, 0x68, 0x74, 0x3a, 0x20, 0x30, 0x70, 0x78, 0x3b, 0x20, 0x6d, 0x61,
+  0x72, 0x67, 0x69, 0x6e, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a,
+  0x20, 0x33, 0x70, 0x78, 0x3b, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e,
+  0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x20, 0x30, 0x70, 0x78, 0x3b, 0x20,
+  0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63,
+  0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x44, 0x44, 0x44, 0x44, 0x44,
+  0x44, 0x3b, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20,
+  0x33, 0x70, 0x78, 0x3b, 0x22, 0x3e, 0x0d, 0x0a, 0x3c, 0x62, 0x3e, 0x4e,
+  0x6f, 0x74, 0x65, 0x73, 0x3c, 0x2f, 0x62, 0x3e, 0x0d, 0x0a, 0x3c, 0x2f,
+  0x64, 0x69, 0x76, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x73, 0x74, 0x79,
+  0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x74,
+  0x6f, 0x70, 0x3a, 0x20, 0x30, 0x70, 0x78, 0x3b, 0x20, 0x6d, 0x61, 0x72,
+  0x67, 0x69, 0x6e, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x30,
+  0x70, 0x78, 0x3b, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x62,
+  0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x20, 0x30, 0x70, 0x78, 0x3b, 0x20,
+  0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a,
+  0x20, 0x30, 0x70, 0x78, 0x3b, 0x20, 0x22, 0x3e, 0x0d, 0x0a, 0x2d, 0x20,
+  0x54, 0x68, 0x69, 0x73, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x20, 0x68,
+  0x61, 0x73, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x20, 0x61, 0x70, 0x70, 0x72,
+  0x6f, 0x76, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x73,
+  0x74, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x6e, 0x20, 0x64, 0x65, 0x76, 0x69,
+  0x63, 0x65, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x64, 0x65, 0x76,
+  0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x6c,
+  0x69, 0x63, 0x6f, 0x6e, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x2e, 0x20, 0x20,
+  0x41, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x2d, 0x75, 0x70, 0x20,
+  0x65, 0x6d, 0x61, 0x69, 0x6c, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62,
+  0x65, 0x20, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x66, 0x2f, 0x77, 0x68,
+  0x65, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x62, 0x75, 0x69, 0x6c,
+  0x64, 0x20, 0x69, 0x73, 0x20, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65,
+  0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c,
+  0x6c, 0x20, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74,
+  0x69, 0x6f, 0x6e, 0x20, 0x73, 0x69, 0x6c, 0x69, 0x63, 0x6f, 0x6e, 0x2e,
+  0x20, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x69,
+  0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20,
+  0x73, 0x65, 0x65, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d,
+  0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x65, 0x69, 0x67, 0x68,
+  0x74, 0x62, 0x61, 0x6c, 0x6c, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e,
+  0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x75, 0x6e, 0x61, 0x2f, 0x69, 0x6e, 0x64,
+  0x65, 0x78, 0x2e, 0x70, 0x68, 0x70, 0x2f, 0x48, 0x6f, 0x77, 0x5f, 0x74,
+  0x6f, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x5f, 0x69,
+  0x66, 0x5f, 0x61, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x68,
+  0x61, 0x73, 0x5f, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f,
+  0x6e, 0x5f, 0x53, 0x69, 0x6c, 0x69, 0x63, 0x6f, 0x6e, 0x22, 0x3e, 0x68,
+  0x6f, 0x77, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69,
+  0x66, 0x79, 0x20, 0x69, 0x66, 0x20, 0x61, 0x20, 0x64, 0x65, 0x76, 0x69,
+  0x63, 0x65, 0x20, 0x68, 0x61, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x64, 0x75,
+  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x69, 0x6c, 0x69, 0x63, 0x6f,
+  0x6e, 0x3c, 0x2f, 0x61, 0x3e, 0x2e, 0x3c, 0x62, 0x72, 0x3e, 0x0d, 0x0a,
+  0x2d, 0x20, 0x49, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x68, 0x61, 0x76,
+  0x65, 0x20, 0x74, 0x72, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x72, 0x65,
+  0x73, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x69, 0x73,
+  0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x79, 0x6f,
+  0x75, 0x72, 0x20, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2c, 0x20, 0x73,
+  0x65, 0x65, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22,
+  0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x65, 0x69, 0x67, 0x68, 0x74,
+  0x62, 0x61, 0x6c, 0x6c, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63,
+  0x6f, 0x6d, 0x2f, 0x6c, 0x75, 0x6e, 0x61, 0x2f, 0x69, 0x6e, 0x64, 0x65,
+  0x78, 0x2e, 0x70, 0x68, 0x70, 0x2f, 0x48, 0x6f, 0x77, 0x5f, 0x74, 0x6f,
+  0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x67, 0x6f, 0x6f, 0x64, 0x5f, 0x62,
+  0x75, 0x67, 0x73, 0x23, 0x50, 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x73,
+  0x5f, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x3e,
+  0x50, 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x73, 0x20, 0x52, 0x65, 0x73,
+  0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x66,
+  0x6f, 0x72, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x69, 0x6e, 0x66, 0x6f,
+  0x2e, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c,
+  0x62, 0x72, 0x3e, 0x0d, 0x0a, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e,
+  0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0x0d, 0x0a, 0x3c, 0x66, 0x6f,
+  0x6e, 0x74, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x41, 0x70,
+  0x70, 0x6c, 0x65, 0x2d, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x2d, 0x73, 0x70,
+  0x61, 0x6e, 0x22, 0x20, 0x66, 0x61, 0x63, 0x65, 0x3d, 0x22, 0x48, 0x65,
+  0x6c, 0x76, 0x65, 0x74, 0x69, 0x63, 0x61, 0x22, 0x20, 0x73, 0x69, 0x7a,
+  0x65, 0x3d, 0x22, 0x33, 0x22, 0x3e, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20,
+  0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x41, 0x70, 0x70, 0x6c, 0x65,
+  0x2d, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x2d, 0x73, 0x70, 0x61, 0x6e, 0x22,
+  0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x66, 0x6f, 0x6e, 0x74,
+  0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x31, 0x32, 0x70, 0x78, 0x3b,
+  0x22, 0x3e, 0x0d, 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x73, 0x74, 0x79,
+  0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x74,
+  0x6f, 0x70, 0x3a, 0x20, 0x30, 0x70, 0x78, 0x3b, 0x20, 0x6d, 0x61, 0x72,
+  0x67, 0x69, 0x6e, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x30,
+  0x70, 0x78, 0x3b, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x62,
+  0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x20, 0x30, 0x70, 0x78, 0x3b, 0x20,
+  0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a,
+  0x20, 0x30, 0x70, 0x78, 0x3b, 0x20, 0x22, 0x3e, 0x0d, 0x0a, 0x3c, 0x66,
+  0x6f, 0x6e, 0x74, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x23,
+  0x46, 0x46, 0x30, 0x30, 0x30, 0x30, 0x22, 0x3e, 0x3c, 0x62, 0x3e, 0x54,
+  0x33, 0x39, 0x20, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x69,
+  0x6f, 0x6e, 0x3a, 0x3c, 0x2f, 0x62, 0x3e, 0x3c, 0x2f, 0x66, 0x6f, 0x6e,
+  0x74, 0x3e, 0x20, 0x54, 0x33, 0x39, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20,
+  0x62, 0x65, 0x20, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65,
+  0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62,
+  0x75, 0x69, 0x6c, 0x64, 0x20, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65,
+  0x64, 0x20, 0x4d, 0x6f, 0x6e, 0x64, 0x61, 0x79, 0x20, 0x6d, 0x6f, 0x72,
+  0x6e, 0x69, 0x6e, 0x67, 0x2c, 0x20, 0x4d, 0x61, 0x72, 0x20, 0x31, 0x34,
+  0x2e, 0x0d, 0x0a, 0x3c, 0x62, 0x72, 0x3e, 0x0d, 0x0a, 0x0d, 0x0a, 0x3c,
+  0x62, 0x72, 0x3e, 0x0d, 0x0a, 0x3c, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x63,
+  0x6f, 0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x23, 0x30, 0x30, 0x30, 0x30, 0x43,
+  0x43, 0x22, 0x3e, 0x3c, 0x62, 0x3e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79,
+  0x73, 0x74, 0x65, 0x6d, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73,
+  0x3a, 0x3c, 0x2f, 0x62, 0x3e, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e,
+  0x20, 0x49, 0x66, 0x20, 0x61, 0x20, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65,
+  0x20, 0x77, 0x61, 0x73, 0x20, 0x65, 0x72, 0x61, 0x73, 0x65, 0x20, 0x69,
+  0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74,
+  0x68, 0x20, 0x54, 0x65, 0x6c, 0x6c, 0x75, 0x72, 0x69, 0x64, 0x65, 0x39,
+  0x41, 0x31, 0x33, 0x38, 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x61, 0x74, 0x65,
+  0x72, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x68,
+  0x61, 0x76, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x67, 0x6f, 0x20, 0x74, 0x68,
+  0x72, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x61, 0x20, 0x6d, 0x61, 0x6e, 0x64,
+  0x61, 0x74, 0x6f, 0x72, 0x79, 0x20, 0x65, 0x72, 0x61, 0x73, 0x65, 0x20,
+  0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x20, 0x61, 0x67, 0x61, 0x69,
+  0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x39, 0x41, 0x31, 0x34, 0x39,
+  0x20, 0x28, 0x6f, 0x72, 0x20, 0x6c, 0x61, 0x74, 0x65, 0x72, 0x29, 0x20,
+  0x74, 0x6f, 0x20, 0x70, 0x69, 0x63, 0x6b, 0x20, 0x75, 0x70, 0x20, 0x6e,
+  0x65, 0x77, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65,
+  0x6d, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x2e, 0x20, 0x49,
+  0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x73, 0x63, 0x65, 0x6e, 0x61,
+  0x72, 0x69, 0x6f, 0x2c, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20,
+  0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x73, 0x20, 0x77, 0x69, 0x6c,
+  0x6c, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20,
+  0x61, 0x20, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x65, 0x72, 0x72, 0x6f,
+  0x72, 0x2c, 0x20, 0x73, 0x6f, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74,
+  0x68, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x6f, 0x6e, 0x20, 0x70,
+  0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20,
+  0x6e, 0x6f, 0x74, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x75, 0x70, 0x74, 0x65,
+  0x64, 0x2e, 0x20, 0x20, 0x50, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x20, 0x77,
+  0x68, 0x6f, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20,
+  0x65, 0x72, 0x61, 0x73, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c,
+  0x6c, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x69, 0x72, 0x20, 0x64, 0x65,
+  0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x20,
+  0x39, 0x41, 0x31, 0x33, 0x38, 0x20, 0x61, 0x72, 0x65, 0x20, 0x61, 0x62,
+  0x6c, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x6b, 0x65, 0x65, 0x70, 0x20, 0x64,
+  0x6f, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20,
+  0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x73, 0x20, 0x61, 0x73, 0x20,
+  0x75, 0x73, 0x75, 0x61, 0x6c, 0x2e, 0x20, 0x20, 0x26, 0x6c, 0x74, 0x3b,
+  0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x72, 0x64, 0x61,
+  0x72, 0x3a, 0x2f, 0x2f, 0x38, 0x35, 0x33, 0x31, 0x36, 0x37, 0x34, 0x22,
+  0x3e, 0x72, 0x64, 0x61, 0x72, 0x3a, 0x2f, 0x2f, 0x38, 0x35, 0x33, 0x31,
+  0x36, 0x37, 0x34, 0x3c, 0x2f, 0x61, 0x3e, 0x26, 0x67, 0x74, 0x3b, 0x0d,
+  0x0a, 0x3c, 0x62, 0x72, 0x3e, 0x0d, 0x0a, 0x0d, 0x0a, 0x3c, 0x62, 0x72,
+  0x3e, 0x0d, 0x0a, 0x3c, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x63, 0x6f, 0x6c,
+  0x6f, 0x72, 0x3d, 0x22, 0x23, 0x30, 0x30, 0x30, 0x30, 0x43, 0x43, 0x22,
+  0x3e, 0x3c, 0x62, 0x3e, 0x43, 0x61, 0x6c, 0x65, 0x6e, 0x64, 0x61, 0x72,
+  0x20, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x3a, 0x3c, 0x2f, 0x62, 0x3e,
+  0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0x20, 0x41, 0x73, 0x20, 0x6f,
+  0x66, 0x20, 0x39, 0x41, 0x31, 0x34, 0x39, 0x2c, 0x20, 0x63, 0x61, 0x6c,
+  0x65, 0x6e, 0x64, 0x61, 0x72, 0x20, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73,
+  0x20, 0x6e, 0x6f, 0x77, 0x20, 0x67, 0x6f, 0x20, 0x74, 0x68, 0x72, 0x6f,
+  0x75, 0x67, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x42, 0x75, 0x6c, 0x6c,
+  0x65, 0x74, 0x69, 0x6e, 0x20, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x20, 0x73,
+  0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x20, 0x42, 0x65, 0x63, 0x61,
+  0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2c,
+  0x20, 0x63, 0x61, 0x6c, 0x65, 0x6e, 0x64, 0x61, 0x72, 0x20, 0x61, 0x6c,
+  0x65, 0x72, 0x74, 0x73, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x6e, 0x6f,
+  0x74, 0x20, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x20, 0x6f, 0x76, 0x65,
+  0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x73,
+  0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x20,
+  0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65,
+  0x20, 0x69, 0x73, 0x20, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e,
+  0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x42, 0x42, 0x2e, 0x20, 0x49,
+  0x6e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c,
+  0x64, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x20, 0x74,
+  0x6f, 0x20, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x2c, 0x20, 0x68, 0x6f,
+  0x77, 0x65, 0x76, 0x65, 0x72, 0x2e, 0x0d, 0x0a, 0x3c, 0x62, 0x72, 0x3e,
+  0x0d, 0x0a, 0x0d, 0x0a, 0x3c, 0x62, 0x72, 0x3e, 0x0d, 0x0a, 0x3c, 0x66,
+  0x6f, 0x6e, 0x74, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x23,
+  0x30, 0x30, 0x30, 0x30, 0x43, 0x43, 0x22, 0x3e, 0x3c, 0x62, 0x3e, 0x49,
+  0x73, 0x20, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x64, 0x20, 0x63,
+  0x72, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x6e, 0x20, 0x79,
+  0x6f, 0x75, 0x3f, 0x3c, 0x2f, 0x62, 0x3e, 0x3c, 0x2f, 0x66, 0x6f, 0x6e,
+  0x74, 0x3e, 0x20, 0x20, 0x49, 0x74, 0x27, 0x73, 0x20, 0x70, 0x72, 0x6f,
+  0x62, 0x61, 0x62, 0x6c, 0x79, 0x20, 0x64, 0x75, 0x65, 0x20, 0x74, 0x6f,
+  0x20, 0x61, 0x20, 0x62, 0x75, 0x67, 0x20, 0x69, 0x6e, 0x20, 0x39, 0x41,
+  0x31, 0x34, 0x37, 0x20, 0x2d, 0x20, 0x26, 0x6c, 0x74, 0x3b, 0x3c, 0x61,
+  0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x72, 0x64, 0x61, 0x72, 0x3a,
+  0x2f, 0x2f, 0x70, 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x2f, 0x39, 0x30,
+  0x37, 0x34, 0x37, 0x33, 0x31, 0x22, 0x3e, 0x72, 0x64, 0x61, 0x72, 0x3a,
+  0x2f, 0x2f, 0x70, 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x2f, 0x39, 0x30,
+  0x37, 0x34, 0x37, 0x33, 0x31, 0x3c, 0x2f, 0x61, 0x3e, 0x26, 0x67, 0x74,
+  0x3b, 0x0d, 0x0a, 0x3c, 0x62, 0x72, 0x3e, 0x0d, 0x0a, 0x54, 0x68, 0x65,
+  0x20, 0x66, 0x69, 0x78, 0x20, 0x77, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x6e,
+  0x74, 0x6f, 0x20, 0x39, 0x41, 0x31, 0x34, 0x38, 0x2c, 0x20, 0x62, 0x75,
+  0x74, 0x20, 0x69, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x75, 0x70, 0x64,
+  0x61, 0x74, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x20,
+  0x79, 0x6f, 0x75, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x61, 0x6c, 0x73,
+  0x6f, 0x20, 0x6e, 0x65, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x6c,
+  0x61, 0x79, 0x20, 0x77, 0x68, 0x61, 0x63, 0x6b, 0x2d, 0x61, 0x2d, 0x66,
+  0x69, 0x6c, 0x65, 0x3a, 0x0d, 0x0a, 0x3c, 0x62, 0x72, 0x3e, 0x0d, 0x0a,
+  0x3c, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3d,
+  0x22, 0x23, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x22, 0x20, 0x73, 0x69,
+  0x7a, 0x65, 0x3d, 0x22, 0x32, 0x22, 0x3e, 0x3c, 0x62, 0x3e, 0x72, 0x6d,
+  0x20, 0x2f, 0x76, 0x61, 0x72, 0x2f, 0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x65,
+  0x2f, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x2f, 0x43, 0x6f, 0x6e,
+  0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72,
+  0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x50, 0x75, 0x62, 0x6c, 0x69,
+  0x63, 0x49, 0x6e, 0x66, 0x6f, 0x2f, 0x54, 0x72, 0x75, 0x74, 0x68, 0x2e,
+  0x70, 0x6c, 0x69, 0x73, 0x74, 0x3c, 0x2f, 0x62, 0x3e, 0x3c, 0x2f, 0x66,
+  0x6f, 0x6e, 0x74, 0x3e, 0x0d, 0x0a, 0x3c, 0x62, 0x72, 0x3e, 0x0d, 0x0a,
+  0x0d, 0x0a, 0x3c, 0x62, 0x72, 0x3e, 0x0d, 0x0a, 0x3c, 0x66, 0x6f, 0x6e,
+  0x74, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x23, 0x30, 0x30,
+  0x30, 0x30, 0x43, 0x43, 0x22, 0x3e, 0x3c, 0x62, 0x3e, 0x4a, 0x32, 0x20,
+  0x44, 0x45, 0x56, 0x31, 0x20, 0x75, 0x73, 0x65, 0x72, 0x73, 0x3a, 0x3c,
+  0x2f, 0x62, 0x3e, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0x20, 0x59,
+  0x6f, 0x75, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x44, 0x46, 0x55, 0x20,
+  0x79, 0x6f, 0x75, 0x72, 0x20, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x20,
+  0x69, 0x6e, 0x20, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x20, 0x74, 0x6f, 0x20,
+  0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x20, 0x39, 0x41, 0x31, 0x34,
+  0x39, 0x20, 0x28, 0x6f, 0x72, 0x20, 0x6c, 0x61, 0x74, 0x65, 0x72, 0x29,
+  0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67,
+  0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x6e, 0x20, 0x65, 0x61, 0x72,
+  0x6c, 0x69, 0x65, 0x72, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x2e, 0x20,
+  0x26, 0x6c, 0x74, 0x3b, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d,
+  0x22, 0x72, 0x64, 0x61, 0x72, 0x3a, 0x2f, 0x2f, 0x39, 0x30, 0x37, 0x36,
+  0x33, 0x38, 0x31, 0x22, 0x3e, 0x72, 0x64, 0x61, 0x72, 0x3a, 0x2f, 0x2f,
+  0x39, 0x30, 0x37, 0x36, 0x33, 0x38, 0x31, 0x3c, 0x2f, 0x61, 0x3e, 0x26,
+  0x67, 0x74, 0x3b, 0x0d, 0x0a, 0x3c, 0x62, 0x72, 0x3e, 0x0d, 0x0a, 0x0d,
+  0x0a, 0x3c, 0x62, 0x72, 0x3e, 0x0d, 0x0a, 0x3c, 0x66, 0x6f, 0x6e, 0x74,
+  0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x23, 0x30, 0x30, 0x30,
+  0x30, 0x43, 0x43, 0x22, 0x3e, 0x3c, 0x62, 0x3e, 0x4e, 0x39, 0x34, 0x20,
+  0x50, 0x72, 0x6f, 0x74, 0x6f, 0x31, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x50,
+  0x72, 0x6f, 0x74, 0x6f, 0x32, 0x20, 0x61, 0x72, 0x65, 0x20, 0x68, 0x65,
+  0x72, 0x65, 0x62, 0x79, 0x20, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61,
+  0x74, 0x65, 0x64, 0x2e, 0x3c, 0x2f, 0x62, 0x3e, 0x3c, 0x2f, 0x66, 0x6f,
+  0x6e, 0x74, 0x3e, 0x20, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x4f, 0x53,
+  0x20, 0x61, 0x6e, 0x64, 0x20, 0x54, 0x65, 0x6c, 0x65, 0x70, 0x68, 0x6f,
+  0x6e, 0x79, 0x20, 0x74, 0x65, 0x61, 0x6d, 0x73, 0x20, 0x62, 0x6f, 0x74,
+  0x68, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67,
+  0x65, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x72, 0x65, 0x71, 0x75,
+  0x69, 0x72, 0x65, 0x20, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74,
+  0x69, 0x6e, 0x67, 0x20, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x20, 0x68, 0x61,
+  0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x2e, 0x20, 0x20, 0x49, 0x66, 0x20,
+  0x79, 0x6f, 0x75, 0x20, 0x73, 0x74, 0x69, 0x6c, 0x6c, 0x20, 0x68, 0x61,
+  0x76, 0x65, 0x20, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x31, 0x20, 0x6f, 0x72,
+  0x20, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x20, 0x68, 0x61, 0x72, 0x64,
+  0x77, 0x61, 0x72, 0x65, 0x2c, 0x20, 0x67, 0x6f, 0x20, 0x67, 0x65, 0x74,
+  0x20, 0x61, 0x20, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x2e, 0x20, 0x20,
+  0x59, 0x6f, 0x75, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x6e, 0x6f, 0x20,
+  0x65, 0x78, 0x63, 0x75, 0x73, 0x65, 0x2e, 0x0d, 0x0a, 0x3c, 0x62, 0x72,
+  0x3e, 0x0d, 0x0a, 0x0d, 0x0a, 0x3c, 0x62, 0x72, 0x3e, 0x0d, 0x0a, 0x3c,
+  0x66, 0x6f, 0x6e, 0x74, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3d, 0x22,
+  0x23, 0x30, 0x30, 0x43, 0x43, 0x30, 0x30, 0x22, 0x3e, 0x3c, 0x62, 0x3e,
+  0x42, 0x61, 0x73, 0x65, 0x62, 0x61, 0x6e, 0x64, 0x20, 0x55, 0x70, 0x64,
+  0x61, 0x74, 0x65, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x4e, 0x39, 0x34, 0x3a,
+  0x3c, 0x2f, 0x62, 0x3e, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0x20,
+  0x4c, 0x65, 0x61, 0x76, 0x65, 0x20, 0x22, 0x55, 0x70, 0x64, 0x61, 0x74,
+  0x65, 0x20, 0x42, 0x61, 0x73, 0x65, 0x62, 0x61, 0x6e, 0x64, 0x22, 0x20,
+  0x75, 0x6e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x2e, 0x20, 0x20,
+  0x59, 0x6f, 0x75, 0x72, 0x20, 0x42, 0x61, 0x73, 0x65, 0x62, 0x61, 0x6e,
+  0x64, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x75, 0x70,
+  0x64, 0x61, 0x74, 0x65, 0x64, 0x20, 0x61, 0x6e, 0x79, 0x77, 0x61, 0x79,
+  0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6c, 0x65, 0x61, 0x76, 0x69,
+  0x6e, 0x67, 0x20, 0x69, 0x74, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65,
+  0x64, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x2e,
+  0x20, 0x20, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x20, 0x62, 0x79,
+  0x20, 0x26, 0x6c, 0x74, 0x3b, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66,
+  0x3d, 0x22, 0x72, 0x64, 0x61, 0x72, 0x3a, 0x2f, 0x2f, 0x38, 0x37, 0x33,
+  0x30, 0x38, 0x30, 0x34, 0x22, 0x3e, 0x72, 0x64, 0x61, 0x72, 0x3a, 0x2f,
+  0x2f, 0x38, 0x37, 0x33, 0x30, 0x38, 0x30, 0x34, 0x3c, 0x2f, 0x61, 0x3e,
+  0x26, 0x67, 0x74, 0x3b, 0x0d, 0x0a, 0x3c, 0x62, 0x72, 0x3e, 0x0d, 0x0a,
+  0x0d, 0x0a, 0x3c, 0x62, 0x72, 0x3e, 0x0d, 0x0a, 0x0d, 0x0a, 0x3c, 0x62,
+  0x72, 0x3e, 0x0d, 0x0a, 0x3c, 0x62, 0x3e, 0x20, 0x4d, 0x61, 0x63, 0x68,
+  0x69, 0x6e, 0x65, 0x20, 0x53, 0x65, 0x74, 0x75, 0x70, 0x20, 0x3c, 0x2f,
+  0x62, 0x3e, 0x0d, 0x0a, 0x3c, 0x62, 0x72, 0x3e, 0x0d, 0x0a, 0x3c, 0x66,
+  0x6f, 0x6e, 0x74, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x23,
+  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x22, 0x20, 0x73, 0x69, 0x7a, 0x65,
+  0x3d, 0x22, 0x32, 0x22, 0x3e, 0x3c, 0x62, 0x3e, 0x50, 0x6c, 0x65, 0x61,
+  0x73, 0x65, 0x20, 0x6d, 0x61, 0x6b, 0x65, 0x20, 0x73, 0x75, 0x72, 0x65,
+  0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x74, 0x75,
+  0x72, 0x6e, 0x20, 0x6f, 0x66, 0x66, 0x20, 0x43, 0x72, 0x61, 0x73, 0x68,
+  0x54, 0x72, 0x61, 0x63, 0x65, 0x72, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20,
+  0x22, 0x3c, 0x62, 0x3e, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73,
+  0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x2e, 0x61,
+  0x70, 0x70, 0x6c, 0x65, 0x2e, 0x43, 0x72, 0x61, 0x73, 0x68, 0x52, 0x65,
+  0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x20, 0x41, 0x75, 0x74, 0x6f, 0x53,
+  0x75, 0x62, 0x6d, 0x69, 0x74, 0x20, 0x4e, 0x4f, 0x3c, 0x2f, 0x62, 0x3e,
+  0x22, 0x20, 0x6f, 0x6e, 0x20, 0x79, 0x6f, 0x75, 0x72, 0x20, 0x68, 0x6f,
+  0x73, 0x74, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x77, 0x68,
+  0x65, 0x6e, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65,
+  0x20, 0x73, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x3c,
+  0x2f, 0x62, 0x3e, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0x0d, 0x0a,
+  0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x62,
+  0x72, 0x3e, 0x0d, 0x0a, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x3c,
+  0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0x0d, 0x0a, 0x3c, 0x66, 0x6f, 0x6e,
+  0x74, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x41, 0x70, 0x70,
+  0x6c, 0x65, 0x2d, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x2d, 0x73, 0x70, 0x61,
+  0x6e, 0x22, 0x20, 0x66, 0x61, 0x63, 0x65, 0x3d, 0x22, 0x48, 0x65, 0x6c,
+  0x76, 0x65, 0x74, 0x69, 0x63, 0x61, 0x22, 0x20, 0x73, 0x69, 0x7a, 0x65,
+  0x3d, 0x22, 0x33, 0x22, 0x3e, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x63,
+  0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2d,
+  0x73, 0x74, 0x79, 0x6c, 0x65, 0x2d, 0x73, 0x70, 0x61, 0x6e, 0x22, 0x20,
+  0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x66, 0x6f, 0x6e, 0x74, 0x2d,
+  0x73, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x31, 0x32, 0x70, 0x78, 0x3b, 0x22,
+  0x3e, 0x0d, 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x73, 0x74, 0x79, 0x6c,
+  0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x74, 0x6f,
+  0x70, 0x3a, 0x20, 0x31, 0x70, 0x78, 0x3b, 0x20, 0x6d, 0x61, 0x72, 0x67,
+  0x69, 0x6e, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x30, 0x70,
+  0x78, 0x3b, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x62, 0x6f,
+  0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x20, 0x33, 0x70, 0x78, 0x3b, 0x20, 0x6d,
+  0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x20,
+  0x30, 0x70, 0x78, 0x3b, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f,
+  0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23,
+  0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x3b, 0x20, 0x70, 0x61, 0x64, 0x64,
+  0x69, 0x6e, 0x67, 0x3a, 0x20, 0x33, 0x70, 0x78, 0x3b, 0x22, 0x3e, 0x0d,
+  0x0a, 0x3c, 0x62, 0x3e, 0x4e, 0x6f, 0x6e, 0x2d, 0x55, 0x49, 0x20, 0x46,
+  0x61, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77,
+  0x61, 0x72, 0x65, 0x20, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64,
+  0x3c, 0x2f, 0x62, 0x3e, 0x0d, 0x0a, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e,
+  0x3c, 0x64, 0x69, 0x76, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22,
+  0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x20,
+  0x30, 0x70, 0x78, 0x3b, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d,
+  0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x30, 0x70, 0x78, 0x3b, 0x20,
+  0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f,
+  0x6d, 0x3a, 0x20, 0x30, 0x70, 0x78, 0x3b, 0x20, 0x6d, 0x61, 0x72, 0x67,
+  0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x20, 0x30, 0x70, 0x78,
+  0x3b, 0x20, 0x22, 0x3e, 0x0d, 0x0a, 0x26, 0x6c, 0x74, 0x3b, 0x3c, 0x61,
+  0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a,
+  0x2f, 0x2f, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x72, 0x6f, 0x6f, 0x6d,
+  0x2f, 0x50, 0x61, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x6d, 0x3f, 0x36, 0x39,
+  0x34, 0x2d, 0x36, 0x32, 0x37, 0x36, 0x2d, 0x33, 0x30, 0x34, 0x22, 0x3e,
+  0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c, 0x6f, 0x63, 0x6b, 0x65,
+  0x72, 0x72, 0x6f, 0x6f, 0x6d, 0x2f, 0x50, 0x61, 0x72, 0x74, 0x46, 0x6f,
+  0x72, 0x6d, 0x3f, 0x36, 0x39, 0x34, 0x2d, 0x36, 0x32, 0x37, 0x36, 0x2d,
+  0x33, 0x30, 0x34, 0x3c, 0x2f, 0x61, 0x3e, 0x26, 0x67, 0x74, 0x3b, 0x20,
+  0x69, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x2f, 0x69, 0x50, 0x6f, 0x64, 0x20,
+  0x74, 0x6f, 0x75, 0x63, 0x68, 0x20, 0x35, 0x2e, 0x30, 0x20, 0x4e, 0x6f,
+  0x6e, 0x55, 0x49, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x20, 0x28,
+  0x54, 0x65, 0x6c, 0x6c, 0x75, 0x72, 0x69, 0x64, 0x65, 0x29, 0x3c, 0x62,
+  0x72, 0x3e, 0x0d, 0x0a, 0x26, 0x6c, 0x74, 0x3b, 0x3c, 0x61, 0x20, 0x68,
+  0x72, 0x65, 0x66, 0x3d, 0x22, 0x6e, 0x66, 0x61, 0x3a, 0x64, 0x6f, 0x63,
+  0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x33, 0x39, 0x34, 0x35, 0x31, 0x39,
+  0x36, 0x22, 0x3e, 0x6e, 0x66, 0x61, 0x3a, 0x64, 0x6f, 0x63, 0x75, 0x6d,
+  0x65, 0x6e, 0x74, 0x2f, 0x33, 0x39, 0x34, 0x35, 0x31, 0x39, 0x36, 0x3c,
+  0x2f, 0x61, 0x3e, 0x26, 0x67, 0x74, 0x3b, 0x3c, 0x62, 0x72, 0x3e, 0x3c,
+  0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0x0d, 0x0a, 0x3c,
+  0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74,
+  0x3e, 0x0d, 0x0a, 0x3c, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x7a,
+  0x65, 0x3d, 0x22, 0x31, 0x22, 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0x0d, 0x0a,
+  0x54, 0x68, 0x69, 0x73, 0x20, 0x65, 0x2d, 0x6d, 0x61, 0x69, 0x6c, 0x20,
+  0x77, 0x61, 0x73, 0x20, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x20,
+  0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x6d, 0x61, 0x69,
+  0x6c, 0x74, 0x6f, 0x3a, 0x74, 0x65, 0x6c, 0x6c, 0x75, 0x72, 0x69, 0x64,
+  0x65, 0x5f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x5f, 0x6e, 0x66, 0x61,
+  0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65,
+  0x2e, 0x63, 0x6f, 0x6d, 0x22, 0x3e, 0x74, 0x65, 0x6c, 0x6c, 0x75, 0x72,
+  0x69, 0x64, 0x65, 0x5f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x5f, 0x6e,
+  0x66, 0x61, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x61, 0x70, 0x70,
+  0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x3c, 0x2f, 0x61, 0x3e, 0x2c, 0x3c,
+  0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x6d, 0x61, 0x69, 0x6c,
+  0x74, 0x6f, 0x3a, 0x74, 0x65, 0x6c, 0x6c, 0x75, 0x72, 0x69, 0x64, 0x65,
+  0x2d, 0x6e, 0x6f, 0x6e, 0x75, 0x69, 0x2d, 0x62, 0x75, 0x69, 0x6c, 0x64,
+  0x73, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x61, 0x70, 0x70, 0x6c,
+  0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x22, 0x3e, 0x74, 0x65, 0x6c, 0x6c, 0x75,
+  0x72, 0x69, 0x64, 0x65, 0x2d, 0x6e, 0x6f, 0x6e, 0x75, 0x69, 0x2d, 0x62,
+  0x75, 0x69, 0x6c, 0x64, 0x73, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2e,
+  0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x3c, 0x2f, 0x61,
+  0x3e, 0x2c, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x6d,
+  0x61, 0x69, 0x6c, 0x74, 0x6f, 0x3a, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64,
+  0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65,
+  0x2e, 0x63, 0x6f, 0x6d, 0x22, 0x3e, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64,
+  0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65,
+  0x2e, 0x63, 0x6f, 0x6d, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x62, 0x79, 0x20,
+  0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x20, 0x42, 0x75, 0x69,
+  0x6c, 0x64, 0x20, 0x54, 0x65, 0x61, 0x6d, 0x20, 0x26, 0x6c, 0x74, 0x3b,
+  0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x6d, 0x61, 0x69,
+  0x6c, 0x74, 0x6f, 0x3a, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x40, 0x67,
+  0x72, 0x6f, 0x75, 0x70, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63,
+  0x6f, 0x6d, 0x22, 0x3e, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x40, 0x67,
+  0x72, 0x6f, 0x75, 0x70, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63,
+  0x6f, 0x6d, 0x3c, 0x2f, 0x61, 0x3e, 0x26, 0x67, 0x74, 0x3b, 0x20, 0x61,
+  0x74, 0x20, 0x30, 0x33, 0x2f, 0x31, 0x34, 0x2f, 0x32, 0x30, 0x31, 0x31,
+  0x20, 0x31, 0x30, 0x3a, 0x33, 0x36, 0x3a, 0x31, 0x31, 0x2e, 0x3c, 0x62,
+  0x72, 0x3e, 0x41, 0x20, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x63,
+  0x61, 0x6c, 0x20, 0x63, 0x6f, 0x70, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74,
+  0x68, 0x69, 0x73, 0x20, 0x65, 0x2d, 0x6d, 0x61, 0x69, 0x6c, 0x20, 0x69,
+  0x73, 0x20, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x20,
+  0x61, 0x74, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22,
+  0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c, 0x6f, 0x63, 0x6b, 0x65,
+  0x72, 0x72, 0x6f, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e,
+  0x63, 0x6f, 0x6d, 0x2f, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x2f, 0x6e, 0x6f,
+  0x6e, 0x75, 0x69, 0x5f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2f, 0x54,
+  0x65, 0x6c, 0x6c, 0x75, 0x72, 0x69, 0x64, 0x65, 0x2f, 0x54, 0x65, 0x6c,
+  0x6c, 0x75, 0x72, 0x69, 0x64, 0x65, 0x39, 0x41, 0x31, 0x36, 0x30, 0x2e,
+  0x70, 0x68, 0x70, 0x22, 0x3e, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+  0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x72, 0x6f, 0x6f, 0x6d, 0x2f, 0x6e,
+  0x6f, 0x74, 0x65, 0x73, 0x2f, 0x6e, 0x6f, 0x6e, 0x75, 0x69, 0x5f, 0x72,
+  0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2f, 0x54, 0x65, 0x6c, 0x6c, 0x75, 0x72,
+  0x69, 0x64, 0x65, 0x2f, 0x54, 0x65, 0x6c, 0x6c, 0x75, 0x72, 0x69, 0x64,
+  0x65, 0x39, 0x41, 0x31, 0x36, 0x30, 0x2e, 0x70, 0x68, 0x70, 0x3c, 0x2f,
+  0x61, 0x3e, 0x2e, 0x0d, 0x0a, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e,
+  0x0d, 0x0a, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x61,
+  0x6e, 0x64, 0x2d, 0x55, 0x73, 0x65, 0x64, 0x3a, 0x20, 0x2f, 0x56, 0x6f,
+  0x6c, 0x75, 0x6d, 0x65, 0x73, 0x2f, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x2f,
+  0x62, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x73,
+  0x2f, 0x73, 0x68, 0x69, 0x70, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x20, 0x2d,
+  0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x54, 0x65, 0x6c, 0x6c, 0x75,
+  0x72, 0x69, 0x64, 0x65, 0x39, 0x41, 0x31, 0x36, 0x30, 0x20, 0x2d, 0x73,
+  0x74, 0x79, 0x6c, 0x65, 0x20, 0x6e, 0x6f, 0x6e, 0x75, 0x69, 0x5f, 0x72,
+  0x65, 0x6d, 0x6f, 0x74, 0x65, 0x20, 0x2d, 0x6e, 0x6f, 0x69, 0x6e, 0x70,
+  0x75, 0x74, 0x20, 0x2d, 0x72, 0x65, 0x61, 0x6c, 0x20, 0x2d, 0x2d, 0x3e,
+  0x0d, 0x0a, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0x43, 0x75, 0x72, 0x72, 0x65,
+  0x6e, 0x74, 0x2d, 0x57, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x2d, 0x44,
+  0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x3a, 0x20, 0x2f, 0x56,
+  0x69, 0x65, 0x77, 0x73, 0x2f, 0x54, 0x65, 0x6c, 0x6c, 0x75, 0x72, 0x69,
+  0x64, 0x65, 0x2f, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x63, 0x72,
+  0x69, 0x70, 0x74, 0x73, 0x20, 0x2d, 0x2d, 0x3e, 0x0d, 0x0a, 0x3c, 0x21,
+  0x2d, 0x2d, 0x20, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x2d, 0x45, 0x6d,
+  0x61, 0x69, 0x6c, 0x2d, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x3a,
+  0x20, 0x64, 0x61, 0x6c, 0x79, 0x5f, 0x63, 0x40, 0x61, 0x70, 0x70, 0x6c,
+  0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x20, 0x2d, 0x2d, 0x3e, 0x0d, 0x0a, 0x3c,
+  0x21, 0x2d, 0x2d, 0x20, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x2d, 0x53,
+  0x56, 0x4e, 0x2d, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x3a,
+  0x20, 0x64, 0x61, 0x6c, 0x79, 0x5f, 0x63, 0x20, 0x2d, 0x2d, 0x3e, 0x0d,
+  0x0a, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72,
+  0x2d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
+  0x74, 0x2d, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20,
+  0x64, 0x61, 0x6c, 0x79, 0x5f, 0x63, 0x20, 0x2d, 0x2d, 0x3e, 0x0d, 0x0a,
+  0x3c, 0x21, 0x2d, 0x2d, 0x20, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x2d,
+  0x53, 0x75, 0x64, 0x6f, 0x2d, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d,
+  0x65, 0x3a, 0x20, 0x64, 0x61, 0x6c, 0x79, 0x5f, 0x63, 0x20, 0x2d, 0x2d,
+  0x3e, 0x0d, 0x0a, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0x53, 0x65, 0x6e, 0x64,
+  0x65, 0x72, 0x2d, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x3a,
+  0x20, 0x72, 0x6f, 0x6f, 0x74, 0x20, 0x28, 0x30, 0x29, 0x20, 0x2d, 0x2d,
+  0x3e, 0x0d, 0x0a, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0x53, 0x68, 0x69, 0x70,
+  0x70, 0x69, 0x6e, 0x67, 0x2d, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6c, 0x69,
+  0x73, 0x74, 0x2d, 0x4c, 0x6f, 0x67, 0x3a, 0x20, 0x2f, 0x56, 0x6f, 0x6c,
+  0x75, 0x6d, 0x65, 0x73, 0x2f, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x33, 0x2f,
+  0x56, 0x69, 0x65, 0x77, 0x73, 0x33, 0x2f, 0x54, 0x65, 0x6c, 0x6c, 0x75,
+  0x72, 0x69, 0x64, 0x65, 0x2f, 0x2e, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x43,
+  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x54, 0x65, 0x6c, 0x6c,
+  0x75, 0x72, 0x69, 0x64, 0x65, 0x39, 0x41, 0x31, 0x36, 0x30, 0x2f, 0x73,
+  0x68, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x63, 0x68, 0x65, 0x63, 0x6b,
+  0x6c, 0x69, 0x73, 0x74, 0x2e, 0x6e, 0x6f, 0x6e, 0x75, 0x69, 0x5f, 0x72,
+  0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x30, 0x33, 0x31, 0x34, 0x32, 0x30,
+  0x31, 0x31, 0x2e, 0x31, 0x30, 0x33, 0x36, 0x31, 0x31, 0x20, 0x2d, 0x2d,
+  0x3e, 0x0d, 0x0a, 0x0d, 0x0a, 0x0d, 0x0a, 0x3c, 0x74, 0x61, 0x62, 0x6c,
+  0x65, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3d, 0x22, 0x30, 0x22,
+  0x3e, 0x3c, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x74, 0x72, 0x3e,
+  0x3c, 0x74, 0x64, 0x3e, 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x3c, 0x2f,
+  0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0x3c, 0x2f, 0x74, 0x62,
+  0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e,
+  0x0d, 0x0a, 0x0d, 0x0a, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74,
+  0x72, 0x3e, 0x3c, 0x2f, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f,
+  0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e,
+  0x3c, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x71, 0x75, 0x6f, 0x74, 0x65,
+  0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0x3c,
+  0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c,
+  0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x3e,
+  0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x2f,
+  0x64, 0x69, 0x76, 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
+  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0d, 0x0a, 0x2d, 0x2d, 0x41, 0x70,
+  0x70, 0x6c, 0x65, 0x2d, 0x4d, 0x61, 0x69, 0x6c, 0x3d, 0x5f, 0x37, 0x41,
+  0x46, 0x41, 0x43, 0x43, 0x44, 0x43, 0x2d, 0x32, 0x32, 0x42, 0x44, 0x2d,
+  0x34, 0x31, 0x37, 0x33, 0x2d, 0x42, 0x34, 0x42, 0x30, 0x2d, 0x37, 0x33,
+  0x39, 0x32, 0x32, 0x34, 0x46, 0x34, 0x31, 0x35, 0x45, 0x30, 0x2d, 0x2d,
+  0x0d, 0x0a
+};
+unsigned int test_eml_len = 10106;
+
+
+unsigned char __9148843_txt[] = {
+    0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65,
+    0x3a, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74, 0x2f,
+    0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x3b,
+    0x0d, 0x0a, 0x09, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x3d,
+    0x22, 0x42, 0x5f, 0x33, 0x33, 0x38, 0x33, 0x31, 0x34, 0x33, 0x31, 0x38,
+    0x38, 0x5f, 0x31, 0x30, 0x35, 0x35, 0x36, 0x38, 0x31, 0x33, 0x22, 0x0d,
+    0x0a, 0x0d, 0x0a, 0x0d, 0x0a, 0x2d, 0x2d, 0x42, 0x5f, 0x33, 0x33, 0x38,
+    0x33, 0x31, 0x34, 0x33, 0x31, 0x38, 0x38, 0x5f, 0x31, 0x30, 0x35, 0x35,
+    0x36, 0x38, 0x31, 0x33, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e,
+    0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
+    0x2f, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x3b, 0x0d, 0x0a, 0x09, 0x63, 0x68,
+    0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x22, 0x49, 0x53, 0x4f, 0x2d, 0x38,
+    0x38, 0x35, 0x39, 0x2d, 0x31, 0x22, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74,
+    0x65, 0x6e, 0x74, 0x2d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72,
+    0x2d, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x71,
+    0x75, 0x6f, 0x74, 0x65, 0x64, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x61,
+    0x62, 0x6c, 0x65, 0x0d, 0x0a, 0x0d, 0x0a, 0x0d, 0x0a, 0x49, 0x6d, 0x70,
+    0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20,
+    0x74, 0x68, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e,
+    0x20, 0x6d, 0x65, 0x6e, 0x75, 0x20, 0x64, 0x69, 0x64, 0x6e, 0x27, 0x74,
+    0x20, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x61,
+    0x74, 0x20, 0x70, 0x37, 0x73, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x66,
+    0x72, 0x6f, 0x6d, 0x20, 0x43, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x2e, 0x0d,
+    0x0a, 0x0d, 0x0a, 0x42, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x69, 0x72,
+    0x20, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x20, 0x68, 0x61, 0x64, 0x20, 0x61,
+    0x20, 0x46, 0x41, 0x51, 0x20, 0x6f, 0x6e, 0x20, 0x68, 0x6f, 0x77, 0x20,
+    0x74, 0x6f, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x20, 0x79, 0x6f,
+    0x75, 0x72, 0x20, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x0d, 0x0a, 0x0d, 0x0a,
+    0x46, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x69, 0x6e,
+    0x64, 0x6f, 0x77, 0x73, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, 0x49,
+    0x20, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x68,
+    0x65, 0x20, 0x63, 0x65, 0x72, 0x74, 0x2c, 0x20, 0x69, 0x6e, 0x63, 0x6c,
+    0x75, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72,
+    0x69, 0x76, 0x61, 0x74, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x2c, 0x20, 0x74,
+    0x68, 0x65, 0x6e, 0x0d, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x65, 0x61, 0x64,
+    0x20, 0x6f, 0x66, 0x20, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x63,
+    0x6c, 0x69, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x6e, 0x20, 0x74,
+    0x68, 0x65, 0x20, 0x6d, 0x61, 0x63, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c,
+    0x20, 0x68, 0x61, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6d, 0x70, 0x6f,
+    0x72, 0x74, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20,
+    0x6b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x0d, 0x0a, 0x6d, 0x65,
+    0x6e, 0x75, 0x2e, 0x20, 0x20, 0x41, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x61,
+    0x74, 0x20, 0x74, 0x6f, 0x6f, 0x6b, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68,
+    0x65, 0x20, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x20, 0x6b, 0x65,
+    0x79, 0x2e, 0x0d, 0x0a, 0x0d, 0x0a, 0x53, 0x6f, 0x20, 0x6e, 0x6f, 0x77,
+    0x2c, 0x20, 0x49, 0x27, 0x76, 0x65, 0x20, 0x64, 0x65, 0x6c, 0x65, 0x74,
+    0x65, 0x64, 0x20, 0x79, 0x6f, 0x75, 0x72, 0x20, 0x63, 0x65, 0x72, 0x74,
+    0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x68, 0x6f, 0x70, 0x65, 0x66, 0x75,
+    0x6c, 0x6c, 0x79, 0x2c, 0x20, 0x6f, 0x75, 0x74, 0x6c, 0x6f, 0x6f, 0x6b,
+    0x20, 0x70, 0x69, 0x63, 0x6b, 0x73, 0x20, 0x69, 0x74, 0x20, 0x75, 0x70,
+    0x20, 0x6f, 0x66, 0x66, 0x20, 0x6f, 0x66, 0x0d, 0x0a, 0x65, 0x78, 0x63,
+    0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x0d, 0x0a, 0x0d, 0x0a, 0x42, 0x75,
+    0x74, 0x20, 0x6e, 0x6f, 0x2e, 0x20, 0x20, 0x49, 0x27, 0x6d, 0x20, 0x67,
+    0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x77, 0x61, 0x72,
+    0x6e, 0x69, 0x6e, 0x67, 0x3d, 0x38, 0x41, 0x61, 0x6e, 0x64, 0x20, 0x74,
+    0x68, 0x65, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f,
+    0x20, 0x65, 0x6e, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x79, 0x6f, 0x75, 0x20,
+    0x75, 0x6e, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x2e,
+    0x0d, 0x0a, 0x57, 0x69, 0x6c, 0x6c, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x20,
+    0x69, 0x6e, 0x74, 0x6f, 0x20, 0x6f, 0x75, 0x74, 0x6c, 0x6f, 0x6f, 0x6b,
+    0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x0d, 0x0a, 0x0d,
+    0x0a, 0x46, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x76,
+    0x69, 0x63, 0x65, 0x73, 0x20, 0x3d, 0x41, 0x44, 0x20, 0x49, 0x27, 0x6c,
+    0x6c, 0x20, 0x6e, 0x65, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x6d, 0x61,
+    0x69, 0x6c, 0x20, 0x6d, 0x79, 0x73, 0x65, 0x6c, 0x66, 0x20, 0x74, 0x68,
+    0x65, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x78, 0x33, 0x27, 0x73, 0x20,
+    0x70, 0x37, 0x73, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x3f, 0x0d, 0x0a, 0x0d,
+    0x0a, 0x54, 0x68, 0x61, 0x6e, 0x6b, 0x73, 0x2e, 0x0d, 0x0a, 0x2d, 0x63,
+    0x72, 0x69, 0x73, 0x0d, 0x0a, 0x0d, 0x0a, 0x0d, 0x0a, 0x0d, 0x0a, 0x0d,
+    0x0a, 0x0d, 0x0a, 0x2d, 0x2d, 0x42, 0x5f, 0x33, 0x33, 0x38, 0x33, 0x31,
+    0x34, 0x33, 0x31, 0x38, 0x38, 0x5f, 0x31, 0x30, 0x35, 0x35, 0x36, 0x38,
+    0x31, 0x33, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d,
+    0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68,
+    0x74, 0x6d, 0x6c, 0x3b, 0x0d, 0x0a, 0x09, 0x63, 0x68, 0x61, 0x72, 0x73,
+    0x65, 0x74, 0x3d, 0x22, 0x49, 0x53, 0x4f, 0x2d, 0x38, 0x38, 0x35, 0x39,
+    0x2d, 0x31, 0x22, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
+    0x2d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2d, 0x65, 0x6e,
+    0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x71, 0x75, 0x6f, 0x74,
+    0x65, 0x64, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x61, 0x62, 0x6c, 0x65,
+    0x0d, 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x3c, 0x68,
+    0x65, 0x61, 0x64, 0x3e, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x3c,
+    0x62, 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x33,
+    0x44, 0x22, 0x77, 0x6f, 0x72, 0x64, 0x2d, 0x77, 0x72, 0x61, 0x70, 0x3a,
+    0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x2d, 0x77, 0x6f, 0x72, 0x64, 0x3b,
+    0x20, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x6e, 0x62, 0x73,
+    0x70, 0x2d, 0x6d, 0x6f, 0x64, 0x65, 0x3a, 0x20, 0x73, 0x3d, 0x0d, 0x0a,
+    0x70, 0x61, 0x63, 0x65, 0x3b, 0x20, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69,
+    0x74, 0x2d, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x62, 0x72, 0x65, 0x61, 0x6b,
+    0x3a, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x2d, 0x77, 0x68, 0x69, 0x74,
+    0x65, 0x2d, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3b, 0x20, 0x63, 0x6f, 0x6c,
+    0x6f, 0x72, 0x3a, 0x20, 0x72, 0x67, 0x62, 0x28, 0x30, 0x2c, 0x20, 0x30,
+    0x2c, 0x20, 0x30, 0x29, 0x3b, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73,
+    0x69, 0x7a, 0x65, 0x3a, 0x3d, 0x0d, 0x0a, 0x20, 0x31, 0x34, 0x70, 0x78,
+    0x3b, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x66, 0x61, 0x6d, 0x69, 0x6c,
+    0x79, 0x3a, 0x20, 0x43, 0x61, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x2c, 0x20,
+    0x73, 0x61, 0x6e, 0x73, 0x2d, 0x73, 0x65, 0x72, 0x69, 0x66, 0x3b, 0x20,
+    0x22, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0x3c,
+    0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x3e, 0x49, 0x6d,
+    0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x72, 0x6f, 0x3d,
+    0x0d, 0x0a, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x63,
+    0x68, 0x61, 0x69, 0x6e, 0x20, 0x6d, 0x65, 0x6e, 0x75, 0x20, 0x64, 0x69,
+    0x64, 0x6e, 0x27, 0x74, 0x20, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x6f, 0x6e,
+    0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x70, 0x37, 0x73, 0x20, 0x66, 0x69,
+    0x6c, 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x43, 0x6f, 0x6d, 0x6f,
+    0x64, 0x6f, 0x2e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x64, 0x69,
+    0x76, 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0x3d, 0x0d, 0x0a, 0x3c, 0x2f, 0x64,
+    0x69, 0x76, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x3e, 0x42, 0x75, 0x74, 0x20,
+    0x74, 0x68, 0x65, 0x69, 0x72, 0x20, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x20,
+    0x68, 0x61, 0x64, 0x20, 0x61, 0x20, 0x46, 0x41, 0x51, 0x20, 0x6f, 0x6e,
+    0x20, 0x68, 0x6f, 0x77, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x61, 0x63, 0x6b,
+    0x75, 0x70, 0x20, 0x79, 0x6f, 0x75, 0x72, 0x20, 0x63, 0x65, 0x72, 0x74,
+    0x2e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x3e,
+    0x3c, 0x3d, 0x0d, 0x0a, 0x62, 0x72, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76,
+    0x3e, 0x3c, 0x64, 0x69, 0x76, 0x3e, 0x46, 0x72, 0x6f, 0x6d, 0x20, 0x74,
+    0x68, 0x65, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x20, 0x73,
+    0x69, 0x64, 0x65, 0x2c, 0x20, 0x49, 0x20, 0x65, 0x78, 0x70, 0x6f, 0x72,
+    0x74, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x65, 0x72, 0x74,
+    0x2c, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x69, 0x6e, 0x67, 0x20,
+    0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x69, 0x76, 0x3d, 0x0d, 0x0a, 0x61,
+    0x74, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x6e,
+    0x20, 0x69, 0x6e, 0x73, 0x74, 0x65, 0x61, 0x64, 0x20, 0x6f, 0x66, 0x20,
+    0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x63, 0x6c, 0x69, 0x63, 0x6b,
+    0x69, 0x6e, 0x67, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d,
+    0x61, 0x63, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, 0x68, 0x61, 0x64,
+    0x20, 0x74, 0x6f, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x66,
+    0x72, 0x6f, 0x6d, 0x3d, 0x0d, 0x0a, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6b,
+    0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x20, 0x6d, 0x65, 0x6e, 0x75,
+    0x2e, 0x20, 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x41, 0x6e, 0x64, 0x20,
+    0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x6f, 0x6f, 0x6b, 0x20, 0x69, 0x6e,
+    0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65,
+    0x20, 0x6b, 0x65, 0x79, 0x2e, 0x20, 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b,
+    0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x3d, 0x0d,
+    0x0a, 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e,
+    0x3c, 0x64, 0x69, 0x76, 0x3e, 0x53, 0x6f, 0x20, 0x6e, 0x6f, 0x77, 0x2c,
+    0x20, 0x49, 0x27, 0x76, 0x65, 0x20, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65,
+    0x64, 0x20, 0x79, 0x6f, 0x75, 0x72, 0x20, 0x63, 0x65, 0x72, 0x74, 0x2c,
+    0x20, 0x61, 0x6e, 0x64, 0x20, 0x68, 0x6f, 0x70, 0x65, 0x66, 0x75, 0x6c,
+    0x6c, 0x79, 0x2c, 0x20, 0x6f, 0x75, 0x74, 0x6c, 0x6f, 0x6f, 0x6b, 0x20,
+    0x70, 0x69, 0x63, 0x6b, 0x73, 0x3d, 0x0d, 0x0a, 0x20, 0x69, 0x74, 0x20,
+    0x75, 0x70, 0x20, 0x6f, 0x66, 0x66, 0x20, 0x6f, 0x66, 0x20, 0x65, 0x78,
+    0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x3c, 0x2f, 0x64, 0x69, 0x76,
+    0x3e, 0x3c, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x2f,
+    0x64, 0x69, 0x76, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x3e, 0x42, 0x75, 0x74,
+    0x20, 0x6e, 0x6f, 0x2e, 0x20, 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x49,
+    0x27, 0x6d, 0x20, 0x67, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x61,
+    0x3d, 0x0d, 0x0a, 0x20, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x26,
+    0x23, 0x38, 0x32, 0x33, 0x30, 0x3b, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68,
+    0x65, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20,
+    0x65, 0x6e, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x75,
+    0x6e, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x2e, 0x20,
+    0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x57, 0x69, 0x6c, 0x6c, 0x20, 0x6c,
+    0x6f, 0x6f, 0x6b, 0x20, 0x69, 0x6e, 0x74, 0x3d, 0x0d, 0x0a, 0x6f, 0x20,
+    0x6f, 0x75, 0x74, 0x6c, 0x6f, 0x6f, 0x6b, 0x20, 0x6f, 0x70, 0x74, 0x69,
+    0x6f, 0x6e, 0x73, 0x2e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x64,
+    0x69, 0x76, 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76,
+    0x3e, 0x3c, 0x64, 0x69, 0x76, 0x3e, 0x46, 0x6f, 0x72, 0x20, 0x74, 0x68,
+    0x65, 0x20, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x26, 0x23,
+    0x38, 0x32, 0x31, 0x31, 0x3b, 0x20, 0x49, 0x27, 0x6c, 0x6c, 0x20, 0x6e,
+    0x65, 0x65, 0x3d, 0x0d, 0x0a, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x6d, 0x61,
+    0x69, 0x6c, 0x20, 0x6d, 0x79, 0x73, 0x65, 0x6c, 0x66, 0x20, 0x74, 0x68,
+    0x65, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x78, 0x33, 0x27, 0x73, 0x20,
+    0x70, 0x37, 0x73, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x3f, 0x3c, 0x2f, 0x64,
+    0x69, 0x76, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x62, 0x72, 0x3e,
+    0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x3e, 0x54,
+    0x68, 0x61, 0x6e, 0x6b, 0x73, 0x2e, 0x3c, 0x2f, 0x64, 0x3d, 0x0d, 0x0a,
+    0x69, 0x76, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x3e, 0x2d, 0x63, 0x72, 0x69,
+    0x73, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x3e,
+    0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x64,
+    0x69, 0x76, 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76,
+    0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74,
+    0x6d, 0x6c, 0x3e, 0x0d, 0x0a, 0x0d, 0x0a, 0x2d, 0x2d, 0x42, 0x5f, 0x33,
+    0x33, 0x38, 0x33, 0x31, 0x34, 0x33, 0x31, 0x38, 0x38, 0x5f, 0x31, 0x30,
+    0x35, 0x35, 0x36, 0x38, 0x31, 0x33, 0x2d, 0x2d, 0x0d, 0x0a
+};
+unsigned int __9148843_txt_len = 2074;
+
+unsigned char __9148843_bin[] = {
+    0x30, 0x82, 0x10, 0xe2, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+    0x01, 0x07, 0x02, 0xa0, 0x82, 0x10, 0xd3, 0x30, 0x82, 0x10, 0xcf, 0x02,
+    0x01, 0x01, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
+    0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x2a,
+    0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x0e, 0x4b,
+    0x30, 0x82, 0x05, 0x7f, 0x30, 0x82, 0x04, 0x67, 0xa0, 0x03, 0x02, 0x01,
+    0x02, 0x02, 0x11, 0x00, 0xaf, 0x2d, 0x1b, 0x38, 0x9e, 0x12, 0x6c, 0xdd,
+    0xb1, 0x9a, 0xf5, 0x74, 0xe8, 0x86, 0xc1, 0x6a, 0x30, 0x0d, 0x06, 0x09,
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
+    0x81, 0xae, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+    0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08,
+    0x13, 0x02, 0x55, 0x54, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04,
+    0x07, 0x13, 0x0e, 0x53, 0x61, 0x6c, 0x74, 0x20, 0x4c, 0x61, 0x6b, 0x65,
+    0x20, 0x43, 0x69, 0x74, 0x79, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55,
+    0x04, 0x0a, 0x13, 0x15, 0x54, 0x68, 0x65, 0x20, 0x55, 0x53, 0x45, 0x52,
+    0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72,
+    0x6b, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x18,
+    0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x75,
+    0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
+    0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2d, 0x55,
+    0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72, 0x73, 0x74,
+    0x2d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x41, 0x75, 0x74, 0x68,
+    0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61,
+    0x6e, 0x64, 0x20, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x30, 0x1e, 0x17, 0x0d,
+    0x31, 0x31, 0x30, 0x33, 0x31, 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+    0x5a, 0x17, 0x0d, 0x31, 0x32, 0x30, 0x33, 0x31, 0x35, 0x32, 0x33, 0x35,
+    0x39, 0x35, 0x39, 0x5a, 0x30, 0x29, 0x31, 0x27, 0x30, 0x25, 0x06, 0x09,
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x18, 0x63,
+    0x62, 0x61, 0x72, 0x61, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x78,
+    0x33, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30,
+    0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+    0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30,
+    0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xce, 0xd7, 0x63, 0x3c,
+    0x7e, 0x05, 0x5d, 0x3a, 0xa4, 0xf0, 0xbd, 0xeb, 0x71, 0x90, 0x53, 0xb3,
+    0x44, 0xb0, 0xab, 0x68, 0xab, 0x51, 0x9b, 0x35, 0x93, 0x79, 0x9c, 0xd3,
+    0x61, 0x1a, 0xda, 0xf8, 0x32, 0xe9, 0x04, 0x6e, 0xf2, 0x8d, 0x55, 0xd5,
+    0x69, 0x8e, 0xf4, 0xaf, 0x22, 0xb9, 0x66, 0x0a, 0x46, 0x29, 0xe4, 0x31,
+    0xd9, 0x2d, 0x79, 0x89, 0xb0, 0xdc, 0xc0, 0xd8, 0x77, 0x34, 0x61, 0xd4,
+    0xb1, 0x32, 0x61, 0xa6, 0x76, 0x17, 0x5f, 0x27, 0x3f, 0xb9, 0x18, 0x8e,
+    0x42, 0x52, 0x30, 0x48, 0x9f, 0xac, 0xef, 0x25, 0x73, 0xcc, 0x72, 0xb8,
+    0x8e, 0x23, 0x4e, 0xbd, 0x12, 0x78, 0xbc, 0x90, 0x89, 0xf1, 0xa6, 0x07,
+    0x03, 0x00, 0xa8, 0x14, 0x55, 0x44, 0xe6, 0x10, 0x12, 0xd9, 0x4b, 0xda,
+    0xa5, 0x37, 0x1c, 0x17, 0xd9, 0xd6, 0xf7, 0x85, 0x31, 0x8f, 0x4c, 0x52,
+    0x0e, 0xff, 0x55, 0x9b, 0x8b, 0x66, 0x99, 0xec, 0xdb, 0x6a, 0x0b, 0xc2,
+    0x5b, 0x5d, 0xac, 0xc2, 0x9f, 0x79, 0x41, 0xfd, 0x06, 0xe5, 0x90, 0x07,
+    0x7c, 0x3c, 0x65, 0x8d, 0x0e, 0x00, 0x07, 0x9c, 0x6d, 0x76, 0x23, 0x9d,
+    0x23, 0x74, 0xc1, 0x4c, 0x3e, 0x6c, 0xf2, 0x0d, 0x45, 0xe8, 0x0d, 0xe0,
+    0x2d, 0x9a, 0x4f, 0xa7, 0xdd, 0x84, 0x82, 0xb4, 0x60, 0xc4, 0x2d, 0x47,
+    0x2e, 0x5e, 0x17, 0xf4, 0x0c, 0x12, 0xa1, 0x84, 0xc1, 0x37, 0xaf, 0xe5,
+    0x86, 0xbd, 0xc7, 0x46, 0x07, 0x12, 0x79, 0x78, 0x32, 0xfd, 0x1b, 0x18,
+    0xd8, 0xfe, 0xd3, 0x67, 0xff, 0xff, 0xaa, 0x18, 0x22, 0x71, 0x93, 0xd9,
+    0xb8, 0x85, 0x8d, 0x13, 0x54, 0x6a, 0x7c, 0xf8, 0x10, 0x30, 0x7c, 0x45,
+    0xc5, 0x85, 0x79, 0x7f, 0x3b, 0x56, 0xe4, 0x4c, 0x80, 0x40, 0x53, 0xe2,
+    0x08, 0x04, 0x8f, 0x97, 0x64, 0x5c, 0xc2, 0x55, 0x2b, 0xe7, 0x3c, 0xaf,
+    0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x02, 0x1a, 0x30, 0x82, 0x02,
+    0x16, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
+    0x80, 0x14, 0x89, 0x82, 0x67, 0x7d, 0xc4, 0x9d, 0x26, 0x70, 0x00, 0x4b,
+    0xb4, 0x50, 0x48, 0x7c, 0xde, 0x3d, 0xae, 0x04, 0x6e, 0x7d, 0x30, 0x1d,
+    0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xd4, 0xcb, 0xdf,
+    0x8e, 0x0b, 0x1e, 0x96, 0x20, 0xb8, 0xa1, 0x5c, 0x6d, 0x03, 0xec, 0x61,
+    0x52, 0x4e, 0xf5, 0xfd, 0x05, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f,
+    0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0c, 0x06,
+    0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30,
+    0x20, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x19, 0x30, 0x17, 0x06, 0x08,
+    0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x04, 0x06, 0x0b, 0x2b, 0x06,
+    0x01, 0x04, 0x01, 0xb2, 0x31, 0x01, 0x03, 0x05, 0x02, 0x30, 0x11, 0x06,
+    0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x01, 0x04, 0x04,
+    0x03, 0x02, 0x05, 0x20, 0x30, 0x46, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04,
+    0x3f, 0x30, 0x3d, 0x30, 0x3b, 0x06, 0x0c, 0x2b, 0x06, 0x01, 0x04, 0x01,
+    0xb2, 0x31, 0x01, 0x02, 0x01, 0x01, 0x01, 0x30, 0x2b, 0x30, 0x29, 0x06,
+    0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1d, 0x68,
+    0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x73, 0x65, 0x63, 0x75, 0x72,
+    0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x2e, 0x6e, 0x65, 0x74,
+    0x2f, 0x43, 0x50, 0x53, 0x30, 0x81, 0xa5, 0x06, 0x03, 0x55, 0x1d, 0x1f,
+    0x04, 0x81, 0x9d, 0x30, 0x81, 0x9a, 0x30, 0x4c, 0xa0, 0x4a, 0xa0, 0x48,
+    0x86, 0x46, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c,
+    0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f,
+    0x6d, 0x2f, 0x55, 0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69,
+    0x72, 0x73, 0x74, 0x2d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x41, 0x75,
+    0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+    0x61, 0x6e, 0x64, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x63, 0x72, 0x6c,
+    0x30, 0x4a, 0xa0, 0x48, 0xa0, 0x46, 0x86, 0x44, 0x68, 0x74, 0x74, 0x70,
+    0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64,
+    0x6f, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x55, 0x54, 0x4e, 0x2d, 0x55, 0x53,
+    0x45, 0x52, 0x46, 0x69, 0x72, 0x73, 0x74, 0x2d, 0x43, 0x6c, 0x69, 0x65,
+    0x6e, 0x74, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61,
+    0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6e, 0x64, 0x45, 0x6d, 0x61, 0x69, 0x6c,
+    0x2e, 0x63, 0x72, 0x6c, 0x30, 0x6c, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+    0x05, 0x07, 0x01, 0x01, 0x04, 0x60, 0x30, 0x5e, 0x30, 0x36, 0x06, 0x08,
+    0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2a, 0x68, 0x74,
+    0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
+    0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x55, 0x54,
+    0x4e, 0x41, 0x41, 0x41, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x41,
+    0x2e, 0x63, 0x72, 0x74, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+    0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+    0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f,
+    0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x23, 0x06, 0x03, 0x55, 0x1d,
+    0x11, 0x04, 0x1c, 0x30, 0x1a, 0x81, 0x18, 0x63, 0x62, 0x61, 0x72, 0x61,
+    0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x78, 0x33, 0x2e, 0x61, 0x70,
+    0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+    0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82,
+    0x01, 0x01, 0x00, 0x27, 0x44, 0x7e, 0x4f, 0x33, 0xde, 0x86, 0x2f, 0x1c,
+    0x6a, 0x84, 0x70, 0xbb, 0xdf, 0xf7, 0x6f, 0x9f, 0x2f, 0xf6, 0xe1, 0xc1,
+    0xe4, 0x68, 0x3b, 0x0c, 0x45, 0x1f, 0x66, 0x23, 0x31, 0xa2, 0xff, 0xe8,
+    0x7f, 0xe0, 0xeb, 0x09, 0x86, 0x54, 0xa3, 0xc4, 0xcb, 0x3b, 0xa1, 0x3b,
+    0xf7, 0x6e, 0x4f, 0xdd, 0xc0, 0x4a, 0x72, 0x0b, 0x8b, 0xb9, 0x08, 0xb4,
+    0x6f, 0x50, 0x47, 0x19, 0xfe, 0x75, 0x82, 0x1e, 0x34, 0xd8, 0x52, 0xe4,
+    0x74, 0xde, 0x2f, 0x69, 0xc3, 0x68, 0xd3, 0xe9, 0x2c, 0x93, 0xe9, 0x71,
+    0x9f, 0x69, 0x6a, 0x92, 0x33, 0xa7, 0xe4, 0x03, 0x39, 0xec, 0x84, 0x4a,
+    0x32, 0xbf, 0x79, 0xf0, 0xe2, 0xce, 0xec, 0x17, 0x64, 0x18, 0xc3, 0xf5,
+    0x34, 0xae, 0x9d, 0x2f, 0xcb, 0xc9, 0x71, 0x09, 0x37, 0x7f, 0x5e, 0xff,
+    0xde, 0x59, 0x5d, 0xb5, 0x06, 0xc4, 0x89, 0x0d, 0x84, 0x2b, 0x30, 0xef,
+    0x38, 0xe1, 0xb7, 0x63, 0xc3, 0x33, 0xd7, 0xb9, 0x8a, 0xb2, 0x52, 0x71,
+    0x29, 0x7a, 0xbd, 0x52, 0x13, 0xdd, 0x92, 0xdc, 0xb1, 0x77, 0xf2, 0xc6,
+    0xc7, 0xc8, 0x75, 0xf0, 0x74, 0x13, 0xa5, 0x4b, 0x4d, 0xf3, 0x51, 0x97,
+    0x2e, 0xf6, 0xcd, 0x6d, 0xd1, 0x7a, 0x97, 0x04, 0x35, 0x5b, 0x3d, 0xff,
+    0xca, 0xa0, 0xec, 0x3b, 0xc0, 0x89, 0x6b, 0xf9, 0xac, 0xb4, 0xd8, 0x57,
+    0x98, 0x84, 0x69, 0x4c, 0x6d, 0xbf, 0x5e, 0xcc, 0x20, 0x05, 0x89, 0x5f,
+    0x49, 0x81, 0x16, 0x9b, 0x22, 0x82, 0xc2, 0x91, 0xdf, 0x53, 0x50, 0xf5,
+    0xec, 0x12, 0xbe, 0xb8, 0xf4, 0x70, 0x9a, 0xaf, 0xe8, 0x91, 0x82, 0x1c,
+    0x7d, 0xc9, 0x49, 0xad, 0x75, 0xac, 0x0a, 0xf3, 0xcc, 0xcf, 0x3e, 0xeb,
+    0xcc, 0xfd, 0x8e, 0x58, 0x3c, 0x70, 0x44, 0xce, 0x76, 0x63, 0xe6, 0xb6,
+    0xe1, 0xc0, 0xec, 0x7c, 0x36, 0x1f, 0xdb, 0x30, 0x82, 0x04, 0x8a, 0x30,
+    0x82, 0x03, 0x72, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x27, 0xf4,
+    0xea, 0x11, 0xf4, 0x7a, 0x86, 0xc4, 0x6e, 0x9d, 0xbb, 0x6e, 0xa9, 0x17,
+    0x07, 0x07, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+    0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x6f, 0x31, 0x0b, 0x30, 0x09, 0x06,
+    0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x53, 0x45, 0x31, 0x14, 0x30, 0x12,
+    0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x41, 0x64, 0x64, 0x54, 0x72,
+    0x75, 0x73, 0x74, 0x20, 0x41, 0x42, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03,
+    0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73,
+    0x74, 0x20, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x54,
+    0x54, 0x50, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x22,
+    0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x41, 0x64, 0x64,
+    0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e,
+    0x61, 0x6c, 0x20, 0x43, 0x41, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e,
+    0x17, 0x0d, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, 0x30, 0x38, 0x30, 0x39,
+    0x31, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x30, 0x30, 0x35, 0x33, 0x30, 0x31,
+    0x30, 0x34, 0x38, 0x33, 0x38, 0x5a, 0x30, 0x81, 0xae, 0x31, 0x0b, 0x30,
+    0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b,
+    0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x55, 0x54, 0x31,
+    0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0e, 0x53, 0x61,
+    0x6c, 0x74, 0x20, 0x4c, 0x61, 0x6b, 0x65, 0x20, 0x43, 0x69, 0x74, 0x79,
+    0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x15, 0x54,
+    0x68, 0x65, 0x20, 0x55, 0x53, 0x45, 0x52, 0x54, 0x52, 0x55, 0x53, 0x54,
+    0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x21, 0x30, 0x1f,
+    0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a,
+    0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x72,
+    0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x31, 0x36, 0x30, 0x34, 0x06,
+    0x03, 0x55, 0x04, 0x03, 0x13, 0x2d, 0x55, 0x54, 0x4e, 0x2d, 0x55, 0x53,
+    0x45, 0x52, 0x46, 0x69, 0x72, 0x73, 0x74, 0x2d, 0x43, 0x6c, 0x69, 0x65,
+    0x6e, 0x74, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63,
+    0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x45, 0x6d,
+    0x61, 0x69, 0x6c, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+    0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82,
+    0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00,
+    0xb2, 0x39, 0x85, 0xa4, 0xf2, 0x7d, 0xab, 0x41, 0x3b, 0x62, 0x46, 0x37,
+    0xae, 0xcd, 0xc1, 0x60, 0x75, 0xbc, 0x39, 0x65, 0xf9, 0x4a, 0x1a, 0x47,
+    0xa2, 0xb9, 0xcc, 0x48, 0xcc, 0x6a, 0x98, 0xd5, 0x4d, 0x35, 0x19, 0xb9,
+    0xa4, 0x42, 0xe5, 0xce, 0x49, 0xe2, 0x8a, 0x2f, 0x1e, 0x7c, 0xd2, 0x31,
+    0x07, 0xc7, 0x4e, 0xb4, 0x83, 0x64, 0x9d, 0x2e, 0x29, 0xd5, 0xa2, 0x64,
+    0xc4, 0x85, 0xbd, 0x85, 0x51, 0x35, 0x79, 0xa4, 0x4e, 0x68, 0x90, 0x7b,
+    0x1c, 0x7a, 0xa4, 0x92, 0xa8, 0x17, 0xf2, 0x98, 0x15, 0xf2, 0x93, 0xcc,
+    0xc9, 0xa4, 0x32, 0x95, 0xbb, 0x0c, 0x4f, 0x30, 0xbd, 0x98, 0xa0, 0x0b,
+    0x8b, 0xe5, 0x6e, 0x1b, 0xa2, 0x46, 0xfa, 0x78, 0xbc, 0xa2, 0x6f, 0xab,
+    0x59, 0x5e, 0xa5, 0x2f, 0xcf, 0xca, 0xda, 0x6d, 0xaa, 0x2f, 0xeb, 0xac,
+    0xa1, 0xb3, 0x6a, 0xaa, 0xb7, 0x2e, 0x67, 0x35, 0x8b, 0x79, 0xe1, 0x1e,
+    0x69, 0x88, 0xe2, 0xe6, 0x46, 0xcd, 0xa0, 0xa5, 0xea, 0xbe, 0x0b, 0xce,
+    0x76, 0x3a, 0x7a, 0x0e, 0x9b, 0xea, 0xfc, 0xda, 0x27, 0x5b, 0x3d, 0x73,
+    0x1f, 0x22, 0xe6, 0x48, 0x61, 0xc6, 0x4c, 0xf3, 0x69, 0xb1, 0xa8, 0x2e,
+    0x1b, 0xb6, 0xd4, 0x31, 0x20, 0x2c, 0xbc, 0x82, 0x8a, 0x8e, 0xa4, 0x0e,
+    0xa5, 0xd7, 0x89, 0x43, 0xfc, 0x16, 0x5a, 0xaf, 0x1d, 0x71, 0xd7, 0x11,
+    0x59, 0xda, 0xba, 0x87, 0x0d, 0xaf, 0xfa, 0xf3, 0xe1, 0xc2, 0xf0, 0xa4,
+    0xc5, 0x67, 0x8c, 0xd6, 0xd6, 0x54, 0x3a, 0xde, 0x0a, 0xa4, 0xba, 0x03,
+    0x77, 0xb3, 0x65, 0xc8, 0xfd, 0x1e, 0xd3, 0x74, 0x62, 0xaa, 0x18, 0xca,
+    0x68, 0x93, 0x1e, 0xa1, 0x85, 0x7e, 0xf5, 0x47, 0x65, 0xcb, 0xf8, 0x4d,
+    0x57, 0x28, 0x74, 0xd2, 0x34, 0xff, 0x30, 0xb6, 0xee, 0xf6, 0x62, 0x30,
+    0x14, 0x8c, 0x2c, 0xeb, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xe1,
+    0x30, 0x81, 0xde, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
+    0x30, 0x16, 0x80, 0x14, 0xad, 0xbd, 0x98, 0x7a, 0x34, 0xb4, 0x26, 0xf7,
+    0xfa, 0xc4, 0x26, 0x54, 0xef, 0x03, 0xbd, 0xe0, 0x24, 0xcb, 0x54, 0x1a,
+    0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x89,
+    0x82, 0x67, 0x7d, 0xc4, 0x9d, 0x26, 0x70, 0x00, 0x4b, 0xb4, 0x50, 0x48,
+    0x7c, 0xde, 0x3d, 0xae, 0x04, 0x6e, 0x7d, 0x30, 0x0e, 0x06, 0x03, 0x55,
+    0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30,
+    0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30,
+    0x03, 0x01, 0x01, 0xff, 0x30, 0x7b, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04,
+    0x74, 0x30, 0x72, 0x30, 0x38, 0xa0, 0x36, 0xa0, 0x34, 0x86, 0x32, 0x68,
+    0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x63, 0x6f,
+    0x6d, 0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x41,
+    0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72,
+    0x6e, 0x61, 0x6c, 0x43, 0x41, 0x52, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72,
+    0x6c, 0x30, 0x36, 0xa0, 0x34, 0xa0, 0x32, 0x86, 0x30, 0x68, 0x74, 0x74,
+    0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6f,
+    0x64, 0x6f, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x41, 0x64, 0x64, 0x54, 0x72,
+    0x75, 0x73, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43,
+    0x41, 0x52, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0d, 0x06,
+    0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,
+    0x03, 0x82, 0x01, 0x01, 0x00, 0x19, 0xd8, 0x89, 0x11, 0x6f, 0x28, 0xac,
+    0xa6, 0x00, 0xa2, 0xe7, 0x87, 0xc1, 0x9b, 0x90, 0x03, 0xdb, 0x7e, 0xa1,
+    0x12, 0xfd, 0x1e, 0xf3, 0xe2, 0xf0, 0x01, 0xa9, 0x94, 0x54, 0x42, 0x6b,
+    0x9a, 0x09, 0xc4, 0xa0, 0x6d, 0xd7, 0x90, 0x92, 0x04, 0x03, 0x66, 0x79,
+    0x43, 0x71, 0xfc, 0xf8, 0x6f, 0xaf, 0xdb, 0x76, 0x45, 0xe2, 0x37, 0x1a,
+    0x3d, 0xdd, 0xe4, 0x59, 0x04, 0x78, 0xac, 0x1c, 0xf4, 0x83, 0x46, 0xf3,
+    0x7a, 0xcf, 0x5b, 0x84, 0x72, 0x2d, 0xe5, 0x46, 0xc1, 0xba, 0x18, 0x11,
+    0x29, 0xf3, 0xcb, 0x49, 0x79, 0x87, 0x3c, 0xba, 0x6d, 0x05, 0x9d, 0xa4,
+    0x6d, 0x68, 0x4f, 0xad, 0x72, 0x14, 0x36, 0xa8, 0xb9, 0xb1, 0xfd, 0xbf,
+    0xcf, 0x7f, 0xf0, 0xa4, 0x6a, 0x94, 0x35, 0x50, 0x8f, 0xcf, 0x81, 0x6d,
+    0x55, 0xb1, 0xdd, 0x59, 0x30, 0x4a, 0xdf, 0x6d, 0xa0, 0x9c, 0x64, 0x1f,
+    0x49, 0x7c, 0xef, 0x36, 0xbb, 0xf4, 0xe3, 0x69, 0xf4, 0xf8, 0x39, 0x8f,
+    0x5a, 0xad, 0x4b, 0x85, 0x3a, 0xb7, 0x0e, 0xed, 0xd3, 0xcf, 0x0d, 0x44,
+    0xa2, 0xfb, 0x04, 0xbf, 0xe4, 0x2f, 0x70, 0x8e, 0x25, 0xfb, 0x5a, 0x54,
+    0x06, 0xb3, 0xd0, 0xc4, 0xbc, 0x6d, 0x8d, 0xfb, 0x73, 0x32, 0x2c, 0xe9,
+    0x9b, 0x84, 0x24, 0x2d, 0xd6, 0x7f, 0x91, 0x7a, 0x68, 0x02, 0x50, 0x1f,
+    0x0e, 0x3f, 0x4d, 0xe9, 0xcc, 0xf5, 0xbb, 0x67, 0xe8, 0xdc, 0x1c, 0x2e,
+    0x3b, 0xfc, 0x4e, 0xcd, 0xfe, 0x02, 0x8e, 0xe3, 0xa8, 0x13, 0x0a, 0xa5,
+    0x26, 0x44, 0x65, 0xe9, 0x10, 0xf2, 0x4d, 0x52, 0xa7, 0xae, 0xdc, 0x3e,
+    0xca, 0x6b, 0x32, 0x5c, 0x41, 0x6c, 0xfe, 0xf5, 0x5d, 0xa0, 0xea, 0xff,
+    0xd1, 0xfa, 0x9b, 0x86, 0x58, 0x6d, 0x3d, 0x96, 0x47, 0xe5, 0xfe, 0x2e,
+    0x95, 0x04, 0xc2, 0x00, 0xcc, 0x8e, 0xa1, 0xf2, 0xbb, 0x30, 0x82, 0x04,
+    0x36, 0x30, 0x82, 0x03, 0x1e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01,
+    0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+    0x01, 0x05, 0x05, 0x00, 0x30, 0x6f, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+    0x55, 0x04, 0x06, 0x13, 0x02, 0x53, 0x45, 0x31, 0x14, 0x30, 0x12, 0x06,
+    0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75,
+    0x73, 0x74, 0x20, 0x41, 0x42, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55,
+    0x04, 0x0b, 0x13, 0x1d, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74,
+    0x20, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x54, 0x54,
+    0x50, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x22, 0x30,
+    0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x41, 0x64, 0x64, 0x54,
+    0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61,
+    0x6c, 0x20, 0x43, 0x41, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17,
+    0x0d, 0x30, 0x30, 0x30, 0x35, 0x33, 0x30, 0x31, 0x30, 0x34, 0x38, 0x33,
+    0x38, 0x5a, 0x17, 0x0d, 0x32, 0x30, 0x30, 0x35, 0x33, 0x30, 0x31, 0x30,
+    0x34, 0x38, 0x33, 0x38, 0x5a, 0x30, 0x6f, 0x31, 0x0b, 0x30, 0x09, 0x06,
+    0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x53, 0x45, 0x31, 0x14, 0x30, 0x12,
+    0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x41, 0x64, 0x64, 0x54, 0x72,
+    0x75, 0x73, 0x74, 0x20, 0x41, 0x42, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03,
+    0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73,
+    0x74, 0x20, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x54,
+    0x54, 0x50, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x22,
+    0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x41, 0x64, 0x64,
+    0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e,
+    0x61, 0x6c, 0x20, 0x43, 0x41, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x82,
+    0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+    0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82,
+    0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb7, 0xf7, 0x1a, 0x33, 0xe6,
+    0xf2, 0x00, 0x04, 0x2d, 0x39, 0xe0, 0x4e, 0x5b, 0xed, 0x1f, 0xbc, 0x6c,
+    0x0f, 0xcd, 0xb5, 0xfa, 0x23, 0xb6, 0xce, 0xde, 0x9b, 0x11, 0x33, 0x97,
+    0xa4, 0x29, 0x4c, 0x7d, 0x93, 0x9f, 0xbd, 0x4a, 0xbc, 0x93, 0xed, 0x03,
+    0x1a, 0xe3, 0x8f, 0xcf, 0xe5, 0x6d, 0x50, 0x5a, 0xd6, 0x97, 0x29, 0x94,
+    0x5a, 0x80, 0xb0, 0x49, 0x7a, 0xdb, 0x2e, 0x95, 0xfd, 0xb8, 0xca, 0xbf,
+    0x37, 0x38, 0x2d, 0x1e, 0x3e, 0x91, 0x41, 0xad, 0x70, 0x56, 0xc7, 0xf0,
+    0x4f, 0x3f, 0xe8, 0x32, 0x9e, 0x74, 0xca, 0xc8, 0x90, 0x54, 0xe9, 0xc6,
+    0x5f, 0x0f, 0x78, 0x9d, 0x9a, 0x40, 0x3c, 0x0e, 0xac, 0x61, 0xaa, 0x5e,
+    0x14, 0x8f, 0x9e, 0x87, 0xa1, 0x6a, 0x50, 0xdc, 0xd7, 0x9a, 0x4e, 0xaf,
+    0x05, 0xb3, 0xa6, 0x71, 0x94, 0x9c, 0x71, 0xb3, 0x50, 0x60, 0x0a, 0xc7,
+    0x13, 0x9d, 0x38, 0x07, 0x86, 0x02, 0xa8, 0xe9, 0xa8, 0x69, 0x26, 0x18,
+    0x90, 0xab, 0x4c, 0xb0, 0x4f, 0x23, 0xab, 0x3a, 0x4f, 0x84, 0xd8, 0xdf,
+    0xce, 0x9f, 0xe1, 0x69, 0x6f, 0xbb, 0xd7, 0x42, 0xd7, 0x6b, 0x44, 0xe4,
+    0xc7, 0xad, 0xee, 0x6d, 0x41, 0x5f, 0x72, 0x5a, 0x71, 0x08, 0x37, 0xb3,
+    0x79, 0x65, 0xa4, 0x59, 0xa0, 0x94, 0x37, 0xf7, 0x00, 0x2f, 0x0d, 0xc2,
+    0x92, 0x72, 0xda, 0xd0, 0x38, 0x72, 0xdb, 0x14, 0xa8, 0x45, 0xc4, 0x5d,
+    0x2a, 0x7d, 0xb7, 0xb4, 0xd6, 0xc4, 0xee, 0xac, 0xcd, 0x13, 0x44, 0xb7,
+    0xc9, 0x2b, 0xdd, 0x43, 0x00, 0x25, 0xfa, 0x61, 0xb9, 0x69, 0x6a, 0x58,
+    0x23, 0x11, 0xb7, 0xa7, 0x33, 0x8f, 0x56, 0x75, 0x59, 0xf5, 0xcd, 0x29,
+    0xd7, 0x46, 0xb7, 0x0a, 0x2b, 0x65, 0xb6, 0xd3, 0x42, 0x6f, 0x15, 0xb2,
+    0xb8, 0x7b, 0xfb, 0xef, 0xe9, 0x5d, 0x53, 0xd5, 0x34, 0x5a, 0x27, 0x02,
+    0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xdc, 0x30, 0x81, 0xd9, 0x30, 0x1d,
+    0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xad, 0xbd, 0x98,
+    0x7a, 0x34, 0xb4, 0x26, 0xf7, 0xfa, 0xc4, 0x26, 0x54, 0xef, 0x03, 0xbd,
+    0xe0, 0x24, 0xcb, 0x54, 0x1a, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f,
+    0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d,
+    0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30,
+    0x81, 0x99, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0x91, 0x30, 0x81,
+    0x8e, 0x80, 0x14, 0xad, 0xbd, 0x98, 0x7a, 0x34, 0xb4, 0x26, 0xf7, 0xfa,
+    0xc4, 0x26, 0x54, 0xef, 0x03, 0xbd, 0xe0, 0x24, 0xcb, 0x54, 0x1a, 0xa1,
+    0x73, 0xa4, 0x71, 0x30, 0x6f, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+    0x04, 0x06, 0x13, 0x02, 0x53, 0x45, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03,
+    0x55, 0x04, 0x0a, 0x13, 0x0b, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73,
+    0x74, 0x20, 0x41, 0x42, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04,
+    0x0b, 0x13, 0x1d, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
+    0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x54, 0x54, 0x50,
+    0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x22, 0x30, 0x20,
+    0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x41, 0x64, 0x64, 0x54, 0x72,
+    0x75, 0x73, 0x74, 0x20, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
+    0x20, 0x43, 0x41, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x82, 0x01, 0x01, 0x30,
+    0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
+    0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xb0, 0x9b, 0xe0, 0x85, 0x25,
+    0xc2, 0xd6, 0x23, 0xe2, 0x0f, 0x96, 0x06, 0x92, 0x9d, 0x41, 0x98, 0x9c,
+    0xd9, 0x84, 0x79, 0x81, 0xd9, 0x1e, 0x5b, 0x14, 0x07, 0x23, 0x36, 0x65,
+    0x8f, 0xb0, 0xd8, 0x77, 0xbb, 0xac, 0x41, 0x6c, 0x47, 0x60, 0x83, 0x51,
+    0xb0, 0xf9, 0x32, 0x3d, 0xe7, 0xfc, 0xf6, 0x26, 0x13, 0xc7, 0x80, 0x16,
+    0xa5, 0xbf, 0x5a, 0xfc, 0x87, 0xcf, 0x78, 0x79, 0x89, 0x21, 0x9a, 0xe2,
+    0x4c, 0x07, 0x0a, 0x86, 0x35, 0xbc, 0xf2, 0xde, 0x51, 0xc4, 0xd2, 0x96,
+    0xb7, 0xdc, 0x7e, 0x4e, 0xee, 0x70, 0xfd, 0x1c, 0x39, 0xeb, 0x0c, 0x02,
+    0x51, 0x14, 0x2d, 0x8e, 0xbd, 0x16, 0xe0, 0xc1, 0xdf, 0x46, 0x75, 0xe7,
+    0x24, 0xad, 0xec, 0xf4, 0x42, 0xb4, 0x85, 0x93, 0x70, 0x10, 0x67, 0xba,
+    0x9d, 0x06, 0x35, 0x4a, 0x18, 0xd3, 0x2b, 0x7a, 0xcc, 0x51, 0x42, 0xa1,
+    0x7a, 0x63, 0xd1, 0xe6, 0xbb, 0xa1, 0xc5, 0x2b, 0xc2, 0x36, 0xbe, 0x13,
+    0x0d, 0xe6, 0xbd, 0x63, 0x7e, 0x79, 0x7b, 0xa7, 0x09, 0x0d, 0x40, 0xab,
+    0x6a, 0xdd, 0x8f, 0x8a, 0xc3, 0xf6, 0xf6, 0x8c, 0x1a, 0x42, 0x05, 0x51,
+    0xd4, 0x45, 0xf5, 0x9f, 0xa7, 0x62, 0x21, 0x68, 0x15, 0x20, 0x43, 0x3c,
+    0x99, 0xe7, 0x7c, 0xbd, 0x24, 0xd8, 0xa9, 0x91, 0x17, 0x73, 0x88, 0x3f,
+    0x56, 0x1b, 0x31, 0x38, 0x18, 0xb4, 0x71, 0x0f, 0x9a, 0xcd, 0xc8, 0x0e,
+    0x9e, 0x8e, 0x2e, 0x1b, 0xe1, 0x8c, 0x98, 0x83, 0xcb, 0x1f, 0x31, 0xf1,
+    0x44, 0x4c, 0xc6, 0x04, 0x73, 0x49, 0x76, 0x60, 0x0f, 0xc7, 0xf8, 0xbd,
+    0x17, 0x80, 0x6b, 0x2e, 0xe9, 0xcc, 0x4c, 0x0e, 0x5a, 0x9a, 0x79, 0x0f,
+    0x20, 0x0a, 0x2e, 0xd5, 0x9e, 0x63, 0x26, 0x1e, 0x55, 0x92, 0x94, 0xd8,
+    0x82, 0x17, 0x5a, 0x7b, 0xd0, 0xbc, 0xc7, 0x8f, 0x4e, 0x86, 0x04, 0x31,
+    0x82, 0x02, 0x5b, 0x30, 0x82, 0x02, 0x57, 0x02, 0x01, 0x01, 0x30, 0x81,
+    0xc4, 0x30, 0x81, 0xae, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
+    0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+    0x04, 0x08, 0x13, 0x02, 0x55, 0x54, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03,
+    0x55, 0x04, 0x07, 0x13, 0x0e, 0x53, 0x61, 0x6c, 0x74, 0x20, 0x4c, 0x61,
+    0x6b, 0x65, 0x20, 0x43, 0x69, 0x74, 0x79, 0x31, 0x1e, 0x30, 0x1c, 0x06,
+    0x03, 0x55, 0x04, 0x0a, 0x13, 0x15, 0x54, 0x68, 0x65, 0x20, 0x55, 0x53,
+    0x45, 0x52, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x4e, 0x65, 0x74, 0x77,
+    0x6f, 0x72, 0x6b, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b,
+    0x13, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77,
+    0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63,
+    0x6f, 0x6d, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+    0x2d, 0x55, 0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72,
+    0x73, 0x74, 0x2d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x41, 0x75,
+    0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+    0x20, 0x61, 0x6e, 0x64, 0x20, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x02, 0x11,
+    0x00, 0xaf, 0x2d, 0x1b, 0x38, 0x9e, 0x12, 0x6c, 0xdd, 0xb1, 0x9a, 0xf5,
+    0x74, 0xe8, 0x86, 0xc1, 0x6a, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
+    0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0xa0, 0x69, 0x30, 0x2f,
+    0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04, 0x31,
+    0x22, 0x04, 0x20, 0xee, 0x23, 0x94, 0x10, 0x19, 0x64, 0xd2, 0xf2, 0x09,
+    0x6b, 0x57, 0xaa, 0x16, 0x27, 0x95, 0x95, 0x2e, 0xc1, 0x49, 0xca, 0x2b,
+    0x20, 0x19, 0xd4, 0xab, 0x50, 0x5c, 0x56, 0x9a, 0x15, 0x1c, 0x77, 0x30,
+    0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x03,
+    0x31, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07,
+    0x01, 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+    0x09, 0x05, 0x31, 0x0f, 0x17, 0x0d, 0x31, 0x31, 0x30, 0x33, 0x31, 0x37,
+    0x30, 0x30, 0x35, 0x39, 0x34, 0x38, 0x5a, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+    0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
+    0x01, 0x00, 0x0e, 0xeb, 0xf2, 0x8a, 0x07, 0x49, 0xc3, 0xcc, 0xf7, 0x63,
+    0x08, 0x12, 0xdd, 0x3d, 0xbe, 0x53, 0x4c, 0x98, 0xeb, 0x0f, 0xd9, 0x07,
+    0xa4, 0x5e, 0x7d, 0xdf, 0xaf, 0xfb, 0x27, 0xaa, 0xa9, 0xee, 0xc8, 0x0b,
+    0x97, 0xee, 0xf6, 0x39, 0x1a, 0x58, 0x51, 0x38, 0xf6, 0x09, 0x78, 0xc3,
+    0xfe, 0xb2, 0x21, 0xdc, 0xf0, 0xff, 0x50, 0xf0, 0xc7, 0xe7, 0x6b, 0xe6,
+    0x47, 0x67, 0x15, 0x6a, 0x60, 0x1d, 0x1d, 0x39, 0x87, 0x86, 0xd3, 0x56,
+    0x0f, 0x92, 0xd9, 0xd4, 0x4b, 0xaa, 0x6c, 0xa5, 0x0f, 0x97, 0xa1, 0xe9,
+    0xda, 0x4f, 0xe9, 0x8e, 0xcd, 0xce, 0xa1, 0xf7, 0x41, 0xd1, 0xb1, 0xae,
+    0xa4, 0xa1, 0x87, 0x0d, 0x29, 0xae, 0x9f, 0x13, 0x3f, 0xc8, 0x2f, 0x3b,
+    0xd1, 0x49, 0x42, 0xa6, 0x0f, 0xc7, 0x22, 0x1f, 0x5a, 0x3e, 0x39, 0x1e,
+    0x19, 0x4a, 0xc6, 0xbb, 0x36, 0x96, 0x9e, 0x59, 0x15, 0x79, 0x13, 0x69,
+    0x07, 0xd7, 0x29, 0x9f, 0x14, 0x74, 0xae, 0x6e, 0x2b, 0xe9, 0xe3, 0xc5,
+    0x26, 0xbe, 0x80, 0x22, 0x8c, 0x9e, 0xe3, 0xc0, 0x2b, 0xc2, 0xae, 0x9c,
+    0x26, 0x0d, 0x6f, 0xf8, 0x44, 0x9b, 0x4d, 0x85, 0x51, 0xa6, 0x0c, 0xa4,
+    0x3d, 0x87, 0xf4, 0x4a, 0x94, 0xf3, 0xc7, 0xfe, 0x70, 0x10, 0x7b, 0x76,
+    0xd4, 0xdb, 0x17, 0x99, 0x45, 0x81, 0x0e, 0xf2, 0xb2, 0x9b, 0x9d, 0x8e,
+    0xc8, 0x56, 0xe0, 0xfc, 0xfd, 0x68, 0x6a, 0x4d, 0x40, 0x38, 0xfd, 0x8d,
+    0x2f, 0xac, 0x2b, 0x3c, 0x3e, 0x84, 0xe4, 0x5f, 0xd0, 0xbe, 0x1b, 0xc3,
+    0x5a, 0x72, 0x28, 0xc1, 0x4b, 0x19, 0xca, 0xc6, 0x51, 0x78, 0x52, 0x84,
+    0xa5, 0x4e, 0x18, 0xb0, 0xd6, 0xa7, 0x4f, 0x86, 0xb2, 0x16, 0xcd, 0xc9,
+    0xe8, 0x9d, 0x91, 0x46, 0xee, 0xde, 0xa8, 0x2f, 0x06, 0x08, 0x91, 0xf2,
+    0x46, 0xac, 0xbc, 0x6a, 0x90, 0xa4
+};
+unsigned int __9148843_bin_len = 4326;
+
+unsigned char __9639569_bin[] = {
+    0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07,
+    0x03, 0xa0, 0x80, 0x30, 0x80, 0x02, 0x01, 0x02, 0x31, 0x82, 0x02, 0x60,
+    0x30, 0x82, 0x01, 0x2c, 0x02, 0x01, 0x02, 0x80, 0x14, 0x12, 0x1c, 0x30,
+    0x39, 0xea, 0x76, 0xa1, 0xf7, 0x8b, 0x30, 0x44, 0x9e, 0xc1, 0x9b, 0x89,
+    0x1a, 0x03, 0x07, 0x6e, 0x21, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+    0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00,
+    0x6a, 0xab, 0xbd, 0x6a, 0xe2, 0x39, 0xdc, 0xcd, 0x09, 0x6b, 0xa7, 0xb0,
+    0x61, 0x71, 0xfc, 0x8c, 0xc0, 0x6a, 0x60, 0x1b, 0xa5, 0x49, 0xbf, 0x71,
+    0x26, 0xb8, 0x3e, 0x7b, 0x21, 0xb3, 0xc3, 0x18, 0xf6, 0x1b, 0x09, 0xd1,
+    0xfb, 0xc3, 0x53, 0x86, 0x01, 0x6a, 0x70, 0xc6, 0x26, 0x58, 0x72, 0xa3,
+    0xed, 0x43, 0x70, 0x46, 0x8b, 0xf9, 0xc4, 0x6d, 0x52, 0x74, 0xec, 0x14,
+    0x7d, 0x2d, 0x7d, 0x29, 0x18, 0x4f, 0xbf, 0x28, 0xaa, 0x02, 0xfa, 0xf1,
+    0xcd, 0x4c, 0xcf, 0x45, 0x15, 0xa4, 0xa6, 0xf7, 0x5b, 0xc6, 0xf0, 0xe6,
+    0x41, 0x01, 0xca, 0x2f, 0x4f, 0x83, 0xf8, 0xf2, 0xab, 0x07, 0xec, 0xcb,
+    0x0a, 0x8e, 0x22, 0x43, 0x0c, 0x96, 0x49, 0x3a, 0xec, 0xae, 0xae, 0xcd,
+    0xaa, 0x4f, 0x87, 0x99, 0x15, 0xae, 0x82, 0x23, 0xb0, 0x5e, 0xa8, 0xe1,
+    0xda, 0xd1, 0x3e, 0xa9, 0x04, 0x49, 0x10, 0x61, 0xcc, 0xe7, 0x64, 0x14,
+    0x85, 0x57, 0x26, 0xbc, 0x2a, 0x43, 0x68, 0xf2, 0xe4, 0x94, 0x1a, 0x3a,
+    0xf3, 0x36, 0x19, 0xc5, 0xe0, 0x63, 0xa5, 0xfa, 0x4f, 0x83, 0x18, 0x47,
+    0xa3, 0x0b, 0xe2, 0x74, 0xd7, 0x03, 0x1a, 0x1e, 0x9e, 0x41, 0x4b, 0x7f,
+    0x88, 0xea, 0xf2, 0x24, 0x86, 0x61, 0x7b, 0xf0, 0x9a, 0xbe, 0x00, 0xe2,
+    0xdd, 0x1d, 0x7e, 0x03, 0xfb, 0x7a, 0x83, 0x01, 0x60, 0xf1, 0xeb, 0x36,
+    0x0a, 0x26, 0x7d, 0xbd, 0x46, 0x49, 0x0a, 0xe4, 0x8f, 0x97, 0x1a, 0xe1,
+    0x7e, 0x47, 0xb2, 0xb2, 0x22, 0x61, 0x21, 0x1b, 0x7f, 0x09, 0x8a, 0x1a,
+    0xea, 0xef, 0x95, 0x61, 0x92, 0xb7, 0x27, 0x88, 0x06, 0x38, 0x60, 0x34,
+    0x98, 0x8c, 0x46, 0x89, 0x9d, 0x1d, 0x37, 0xb9, 0xf8, 0x91, 0x23, 0x40,
+    0x7f, 0xed, 0xf3, 0xa9, 0xcc, 0xf3, 0xce, 0x15, 0x80, 0xad, 0xe5, 0x2f,
+    0x9a, 0xa0, 0x56, 0x4e, 0x30, 0x82, 0x01, 0x2c, 0x02, 0x01, 0x02, 0x80,
+    0x14, 0x7b, 0x87, 0x51, 0x34, 0x36, 0xcd, 0x3c, 0x3e, 0x01, 0xd6, 0x7a,
+    0x60, 0xc2, 0x95, 0x1c, 0x12, 0xd7, 0x79, 0x3f, 0xa5, 0x30, 0x0d, 0x06,
+    0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
+    0x04, 0x82, 0x01, 0x00, 0x09, 0xe3, 0x84, 0xb4, 0x92, 0x4e, 0x8a, 0xe1,
+    0x16, 0xfb, 0x8d, 0x95, 0x03, 0x2d, 0x32, 0xbf, 0x36, 0xd4, 0xd2, 0xc1,
+    0x40, 0xf8, 0x39, 0x27, 0x53, 0x83, 0x95, 0xe4, 0x6d, 0x54, 0x75, 0xbe,
+    0xd9, 0xef, 0xc7, 0x5f, 0xf1, 0x5e, 0x45, 0xf7, 0xf9, 0x4b, 0x28, 0x23,
+    0x93, 0xad, 0xb6, 0x70, 0x14, 0x56, 0x23, 0x13, 0x7f, 0x14, 0x59, 0x43,
+    0x23, 0xdc, 0x19, 0x8e, 0xc0, 0xde, 0x16, 0x27, 0x25, 0x29, 0x16, 0x02,
+    0xae, 0x7e, 0x0d, 0x4a, 0x4c, 0xb0, 0x14, 0x4a, 0xf2, 0x43, 0x7f, 0xf9,
+    0xb7, 0xd6, 0x1c, 0x05, 0xd1, 0xcc, 0x01, 0x6d, 0x62, 0x26, 0x92, 0x32,
+    0x21, 0x00, 0x68, 0x09, 0x5d, 0x47, 0xab, 0xbd, 0x4d, 0x3e, 0x1a, 0xa7,
+    0xa3, 0x78, 0xcd, 0xcf, 0x8e, 0xed, 0xfd, 0xe9, 0xf0, 0x40, 0x6f, 0x8b,
+    0xa1, 0x97, 0x2c, 0xd8, 0x6b, 0xc1, 0x63, 0xe2, 0x8f, 0x3e, 0xea, 0x9a,
+    0x63, 0x45, 0xaa, 0x34, 0x5c, 0x86, 0xf0, 0x48, 0x80, 0x82, 0x3a, 0xa5,
+    0xce, 0xd7, 0xa6, 0xa4, 0x6b, 0x6b, 0x3d, 0x2f, 0x5e, 0x2c, 0x68, 0x11,
+    0xab, 0x43, 0x09, 0x22, 0x8a, 0x36, 0x71, 0x51, 0x2f, 0x6a, 0xd2, 0x08,
+    0xee, 0x2b, 0x4d, 0x44, 0xf3, 0x68, 0xf0, 0x39, 0x72, 0x2d, 0x69, 0x67,
+    0x52, 0xe0, 0xf3, 0x4f, 0x97, 0xaa, 0x68, 0xa8, 0x41, 0xf5, 0x9b, 0xf9,
+    0x9d, 0xdc, 0x3c, 0x76, 0x9d, 0x96, 0x1e, 0xbe, 0x8b, 0x4b, 0x03, 0x4f,
+    0x7e, 0xc9, 0x73, 0x74, 0xf1, 0x1d, 0xe7, 0xed, 0xa7, 0xc0, 0xf9, 0xa8,
+    0x1f, 0x8e, 0x17, 0x18, 0x1b, 0xb9, 0xca, 0x1d, 0xe1, 0x4b, 0x88, 0x2d,
+    0xb2, 0x12, 0x54, 0xa3, 0xb3, 0xda, 0x8a, 0x58, 0xd5, 0xab, 0x63, 0x3d,
+    0xd3, 0x9b, 0x57, 0x60, 0xd4, 0x8b, 0x8e, 0x18, 0x7d, 0x21, 0xb3, 0x49,
+    0x44, 0xe8, 0x50, 0xfd, 0x70, 0xe8, 0xee, 0xc2, 0x30, 0x80, 0x06, 0x09,
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x1d, 0x06,
+    0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2a, 0x04, 0x10,
+    0xe3, 0x4a, 0x6c, 0xc9, 0x93, 0x60, 0x24, 0x8d, 0xff, 0xef, 0xcf, 0x73,
+    0xe2, 0xc3, 0x8c, 0x0c, 0xa0, 0x80, 0x04, 0x82, 0x04, 0x00, 0x6b, 0x25,
+    0x2d, 0x0a, 0x58, 0x95, 0xbc, 0x58, 0x4d, 0x65, 0x78, 0xe6, 0x4d, 0xb0,
+    0xb5, 0xd0, 0xfe, 0x20, 0xcf, 0x48, 0x69, 0x51, 0x2c, 0xd7, 0x53, 0x4d,
+    0x93, 0xfb, 0xc4, 0x7f, 0x2e, 0xf4, 0xf3, 0x35, 0x36, 0x70, 0x24, 0xf0,
+    0xd9, 0xbc, 0x93, 0x9b, 0x39, 0x24, 0xbd, 0x35, 0x34, 0x84, 0x87, 0xea,
+    0x88, 0x82, 0xfb, 0xa4, 0xeb, 0x9b, 0x8d, 0x2c, 0x25, 0xbd, 0x4c, 0xc0,
+    0xee, 0x78, 0x01, 0x30, 0x4f, 0x36, 0x61, 0x54, 0xb9, 0x24, 0x92, 0x3d,
+    0x0f, 0xd4, 0x89, 0xdf, 0xb3, 0x49, 0xfc, 0xc6, 0xd9, 0xc4, 0x62, 0x74,
+    0x96, 0x2a, 0x17, 0x96, 0x4a, 0xa6, 0xb3, 0x04, 0x31, 0x48, 0x44, 0xf2,
+    0xc9, 0x7f, 0x1a, 0xd6, 0x67, 0x43, 0xf3, 0x8b, 0x7b, 0xdb, 0x77, 0x3e,
+    0xa6, 0xf7, 0xa1, 0xc8, 0x59, 0x8b, 0xa2, 0x0a, 0x32, 0x09, 0xa2, 0x19,
+    0x50, 0x4d, 0xcb, 0xe9, 0x35, 0xf3, 0xb0, 0x65, 0x8c, 0xc6, 0x32, 0xde,
+    0x32, 0xd5, 0xfe, 0x90, 0x44, 0x98, 0xa7, 0xc9, 0x27, 0x91, 0x37, 0x7f,
+    0xed, 0x8b, 0xfa, 0x27, 0x6f, 0xdb, 0x65, 0x32, 0x2c, 0x8f, 0x40, 0xdc,
+    0x59, 0x81, 0xb6, 0x9b, 0x8c, 0x0f, 0x17, 0x46, 0xfa, 0x69, 0x01, 0x59,
+    0x4d, 0xf2, 0x5c, 0xc8, 0x31, 0x87, 0x32, 0x4b, 0x7b, 0xef, 0xdb, 0xbe,
+    0x88, 0xf2, 0x61, 0x02, 0xa7, 0xd9, 0x21, 0x4d, 0x8f, 0x9d, 0x69, 0xdb,
+    0xe9, 0x6c, 0x0e, 0xd4, 0x22, 0x5b, 0xee, 0xf6, 0x89, 0xed, 0xc8, 0x6a,
+    0x0e, 0x75, 0x55, 0xc9, 0xc5, 0x90, 0xea, 0x6a, 0x80, 0xc3, 0xc5, 0x97,
+    0x46, 0x8a, 0x9b, 0x51, 0xf6, 0xf5, 0xbe, 0xa7, 0x27, 0x37, 0x6f, 0x43,
+    0xbf, 0x07, 0x72, 0x7c, 0xa9, 0x64, 0x1b, 0x47, 0x5d, 0x59, 0x0f, 0x57,
+    0x1f, 0x63, 0xeb, 0xc2, 0x01, 0x22, 0x03, 0x93, 0xfe, 0xa6, 0xc3, 0x11,
+    0xdd, 0x10, 0x7b, 0xb9, 0xc3, 0x96, 0x9a, 0xf6, 0x67, 0x75, 0x54, 0x4f,
+    0x27, 0xcd, 0x7e, 0xc0, 0x8f, 0xa3, 0xce, 0x2f, 0xfa, 0x06, 0xd5, 0x46,
+    0x2e, 0xf4, 0x67, 0x41, 0x92, 0x7c, 0x3e, 0x2c, 0xd3, 0xea, 0xbc, 0xce,
+    0xfb, 0x30, 0xd8, 0x7c, 0x91, 0xb6, 0x4b, 0x02, 0xc2, 0x01, 0xd7, 0xab,
+    0x71, 0xd6, 0x6e, 0xd4, 0xa3, 0xb6, 0x55, 0x8c, 0x61, 0xf0, 0x68, 0xb9,
+    0xea, 0xc9, 0xb0, 0x92, 0xea, 0xbb, 0xff, 0x50, 0x8c, 0x84, 0x83, 0x2a,
+    0xe0, 0xb2, 0x2e, 0xa6, 0x44, 0x30, 0xd3, 0x1a, 0x54, 0x65, 0x0d, 0xb8,
+    0xbf, 0xc0, 0x50, 0x38, 0x6e, 0x83, 0x87, 0x86, 0x05, 0x72, 0xce, 0x6b,
+    0x30, 0x00, 0x42, 0x3a, 0x8d, 0xd5, 0xf3, 0x85, 0x5e, 0xaa, 0x66, 0x1b,
+    0x84, 0x8d, 0xf3, 0x5d, 0xa6, 0x09, 0x86, 0xfb, 0xd4, 0x8a, 0x5e, 0x98,
+    0x44, 0x9a, 0x1b, 0xbf, 0xce, 0xec, 0x92, 0xee, 0xa5, 0xdb, 0xea, 0x2e,
+    0x44, 0x8c, 0xc2, 0x7b, 0xb8, 0x81, 0x83, 0x26, 0x22, 0x44, 0xf4, 0x6d,
+    0xc9, 0x2d, 0xb4, 0xbf, 0x9f, 0xdc, 0x42, 0xe8, 0xa3, 0x62, 0xd9, 0x06,
+    0xc3, 0xb6, 0x8a, 0x8d, 0xfd, 0xd4, 0x71, 0x52, 0x22, 0x48, 0x5a, 0xf3,
+    0x31, 0x39, 0xf0, 0xdd, 0xfe, 0xa9, 0x39, 0x3e, 0xce, 0x98, 0x2b, 0x27,
+    0x2d, 0xa7, 0x45, 0x77, 0x34, 0x1b, 0x5a, 0xba, 0xf2, 0x77, 0x3e, 0x67,
+    0x37, 0x56, 0x2c, 0x82, 0x7a, 0x0e, 0x1b, 0xd3, 0xa5, 0xe1, 0x0f, 0x22,
+    0xa0, 0xea, 0x5a, 0x55, 0x65, 0x5e, 0x50, 0x95, 0x4b, 0xe7, 0xd7, 0xcb,
+    0x7c, 0x3e, 0x3b, 0x88, 0xa8, 0xbb, 0x0b, 0x4e, 0x72, 0xdb, 0x08, 0x77,
+    0xa3, 0xe9, 0xc6, 0xfe, 0x69, 0xfb, 0x61, 0x05, 0xdb, 0x8b, 0x24, 0xe3,
+    0x3d, 0x0e, 0x99, 0x8b, 0xb3, 0x79, 0x50, 0xb4, 0xe9, 0xb7, 0xbc, 0x0e,
+    0xd0, 0x67, 0xfc, 0x20, 0x91, 0x13, 0xb2, 0xa4, 0x35, 0x12, 0x52, 0x41,
+    0x18, 0xe4, 0x10, 0xb5, 0xa0, 0xb7, 0x60, 0x7e, 0x38, 0xa6, 0x42, 0x78,
+    0x9e, 0xd9, 0x2c, 0xe3, 0xea, 0x72, 0x1b, 0x3b, 0x4e, 0x53, 0xc4, 0x7a,
+    0x46, 0x9f, 0x46, 0x59, 0x28, 0xaa, 0x3c, 0x78, 0xfd, 0x7c, 0x07, 0x41,
+    0xe2, 0x70, 0xa3, 0x26, 0xed, 0x47, 0x70, 0x84, 0x13, 0xea, 0x10, 0xaf,
+    0x0e, 0x12, 0xd5, 0x2c, 0x67, 0x0b, 0x20, 0x27, 0x46, 0x33, 0xd9, 0xec,
+    0xd8, 0x4b, 0x14, 0x3b, 0x97, 0xd2, 0xad, 0x3e, 0xe0, 0x05, 0x6b, 0x8f,
+    0x2b, 0xaa, 0xe0, 0x5e, 0x54, 0x7e, 0x06, 0x9d, 0x94, 0xbf, 0x4a, 0x23,
+    0xc1, 0x9b, 0x9f, 0xed, 0xee, 0x41, 0x22, 0x6f, 0xb7, 0x4c, 0x6f, 0x22,
+    0x67, 0x2d, 0xa4, 0x58, 0xc9, 0xcf, 0x4f, 0xca, 0x01, 0x98, 0x99, 0xef,
+    0x1b, 0x81, 0x9f, 0x7d, 0xca, 0xb1, 0x1a, 0x89, 0xda, 0x6b, 0x2a, 0x61,
+    0xbe, 0x91, 0x1f, 0xc2, 0x65, 0xf4, 0x72, 0xec, 0xa8, 0x69, 0x36, 0x4a,
+    0x77, 0x34, 0xcf, 0x88, 0x4a, 0x90, 0xa8, 0x6e, 0x24, 0xd3, 0xb5, 0x6c,
+    0x3b, 0xa1, 0x68, 0xb7, 0x16, 0xe1, 0x36, 0x71, 0xe2, 0x51, 0x4b, 0xd6,
+    0x79, 0x2e, 0x52, 0x9c, 0xd5, 0x79, 0x13, 0xb9, 0x8b, 0x78, 0xb0, 0xd2,
+    0x89, 0x23, 0x87, 0x91, 0x20, 0x5e, 0x29, 0x3e, 0xb2, 0x7b, 0x46, 0x82,
+    0x13, 0x7f, 0x74, 0xd9, 0x42, 0xad, 0x87, 0xae, 0xb3, 0x6c, 0xcf, 0x1b,
+    0xa1, 0xf0, 0x6b, 0xaf, 0x0b, 0x8a, 0xca, 0x2a, 0x9e, 0xe7, 0x33, 0x62,
+    0xbd, 0xf3, 0x26, 0x84, 0x4e, 0xf6, 0x10, 0x41, 0x9e, 0x61, 0xac, 0xe3,
+    0x56, 0x34, 0x9c, 0x62, 0xb0, 0xfa, 0x22, 0xee, 0xd9, 0x64, 0xda, 0xb0,
+    0x13, 0x76, 0xe8, 0xf1, 0x0f, 0x85, 0x9c, 0x9a, 0x07, 0x5f, 0xc8, 0xef,
+    0x6d, 0xb8, 0x56, 0x38, 0x78, 0x76, 0x19, 0x93, 0xbd, 0xc6, 0x82, 0xd8,
+    0x74, 0x5b, 0x14, 0x80, 0x36, 0xd0, 0x25, 0x98, 0x0f, 0x48, 0xe4, 0x4c,
+    0x9a, 0xe6, 0x04, 0x21, 0xcb, 0x97, 0xc4, 0x25, 0x86, 0xdc, 0xf1, 0x50,
+    0xa9, 0x91, 0x2b, 0xfc, 0x0e, 0xd3, 0x93, 0x74, 0x6e, 0x3e, 0xef, 0x18,
+    0x0f, 0x82, 0x85, 0x8f, 0xdb, 0x4d, 0xd1, 0x91, 0x93, 0xa5, 0x22, 0xed,
+    0x02, 0x58, 0x94, 0x65, 0xfc, 0x91, 0x26, 0x59, 0x54, 0x02, 0x26, 0x26,
+    0x6a, 0xa4, 0x33, 0x08, 0x42, 0x6a, 0x67, 0x1f, 0x14, 0x15, 0xc6, 0x54,
+    0xe0, 0x1a, 0x8e, 0xd5, 0xf6, 0xa0, 0x9c, 0x8f, 0x3c, 0x63, 0xd7, 0xfc,
+    0x8c, 0x93, 0xab, 0x32, 0xaf, 0x5f, 0x1b, 0xfd, 0xab, 0xf0, 0xf5, 0x4c,
+    0x0f, 0x26, 0xb6, 0x03, 0x1f, 0xa1, 0x6e, 0x5a, 0x85, 0xca, 0x47, 0x7c,
+    0x5c, 0xc5, 0x6a, 0xfa, 0x9c, 0x4f, 0x3c, 0xb5, 0x2e, 0x61, 0xad, 0x89,
+    0xe8, 0xbc, 0xc8, 0xe3, 0x66, 0x25, 0x43, 0x05, 0x86, 0x70, 0x43, 0x53,
+    0xa5, 0xb4, 0x1d, 0xcc, 0x7d, 0x86, 0x16, 0x45, 0x4a, 0x3d, 0x6a, 0xae,
+    0xae, 0xf3, 0x86, 0xcb, 0xe1, 0x9d, 0x23, 0xa0, 0xea, 0xb7, 0x37, 0x6a,
+    0x96, 0x8f, 0x7a, 0x18, 0x12, 0xbd, 0x0f, 0xa5, 0x10, 0xf2, 0x0f, 0x83,
+    0x27, 0x72, 0xc1, 0xcd, 0x98, 0xf6, 0xb6, 0xf5, 0x89, 0xb2, 0x95, 0x3c,
+    0x04, 0x51, 0x0a, 0x9b, 0xa4, 0xa2, 0x99, 0x88, 0x7a, 0x43, 0xff, 0xdc,
+    0x61, 0x33, 0x11, 0xdb, 0xf6, 0xb6, 0x4d, 0xfd, 0x06, 0xce, 0x16, 0xb9,
+    0xb0, 0x18, 0xbd, 0xaa, 0x03, 0x2c, 0x3c, 0x87, 0xfe, 0xda, 0x0e, 0x8a,
+    0x16, 0x37, 0x72, 0x71, 0xa2, 0xaa, 0xd9, 0x3a, 0x04, 0xc0, 0x8a, 0xf3,
+    0xfa, 0xca, 0xae, 0xde, 0x42, 0xc5, 0xf6, 0x83, 0x1b, 0x2c, 0x22, 0x7e,
+    0x36, 0xcc, 0x4d, 0xc5, 0x08, 0xbb, 0xfa, 0x76, 0x21, 0xee, 0xc4, 0x3e,
+    0x11, 0x6c, 0x04, 0x82, 0x04, 0x00, 0xb1, 0xdf, 0x82, 0x09, 0xdf, 0xb1,
+    0xaa, 0xae, 0x7a, 0x11, 0x13, 0xf6, 0x12, 0x8e, 0x8b, 0xa0, 0x0b, 0xb2,
+    0xd3, 0xb0, 0x5a, 0xed, 0x0e, 0xeb, 0xbc, 0x4d, 0x55, 0x53, 0x1f, 0x49,
+    0xcd, 0xca, 0xb5, 0x61, 0x42, 0xa2, 0xe0, 0xb4, 0xe6, 0x44, 0x80, 0xa8,
+    0xce, 0xb0, 0x19, 0x32, 0xf2, 0xb3, 0x4b, 0x15, 0xfa, 0xea, 0xe9, 0x45,
+    0x69, 0xc7, 0xa8, 0x78, 0x4c, 0xe2, 0xbd, 0x8d, 0x85, 0x77, 0x2d, 0x1f,
+    0x68, 0x9f, 0x5f, 0xef, 0xb9, 0x1b, 0xd7, 0x52, 0x75, 0x80, 0xc3, 0xc8,
+    0xb9, 0xaa, 0x1e, 0x18, 0xf4, 0x9e, 0x30, 0xb5, 0x27, 0xa8, 0xa0, 0xfd,
+    0xdd, 0x59, 0x7a, 0xcf, 0xf2, 0x97, 0x15, 0xc9, 0xa2, 0x3f, 0x99, 0x92,
+    0x70, 0x32, 0x24, 0x5c, 0x31, 0x92, 0xe6, 0x3e, 0x0a, 0xc8, 0xe5, 0xdf,
+    0x5a, 0xe0, 0x60, 0xdd, 0x46, 0x55, 0x4b, 0x98, 0x66, 0x07, 0xe2, 0xf4,
+    0xab, 0x71, 0xa6, 0x6b, 0x66, 0xc3, 0xe5, 0x6f, 0xfb, 0xb8, 0x29, 0x88,
+    0x74, 0x34, 0xb8, 0x2f, 0xd4, 0xcb, 0x42, 0x9e, 0xbf, 0x03, 0x5a, 0x5b,
+    0x22, 0xd3, 0x54, 0xa6, 0x48, 0x6c, 0x44, 0xa1, 0xc2, 0x98, 0xc2, 0x80,
+    0x8f, 0x45, 0x56, 0x44, 0x61, 0xe1, 0x39, 0x19, 0x05, 0xe7, 0xae, 0x30,
+    0x1d, 0x99, 0x50, 0xbe, 0x53, 0x6b, 0x4f, 0x1b, 0xee, 0xbf, 0x56, 0xeb,
+    0xbb, 0x81, 0x3b, 0x05, 0xe7, 0x81, 0xa1, 0xfe, 0x6a, 0xd9, 0x70, 0x3c,
+    0x28, 0xae, 0xa9, 0xe1, 0xd7, 0xa2, 0xd2, 0x14, 0x31, 0xc6, 0xf7, 0x76,
+    0xff, 0x34, 0xe9, 0xc8, 0xbc, 0xed, 0x47, 0xf4, 0xd9, 0x2a, 0x7c, 0xb6,
+    0x4b, 0xb5, 0x49, 0x1e, 0x52, 0xf6, 0x6c, 0xc9, 0xcc, 0xec, 0xda, 0xd6,
+    0xfc, 0x1f, 0x5c, 0x01, 0x81, 0xce, 0x4c, 0x13, 0x23, 0xc8, 0xea, 0xad,
+    0x8c, 0x6b, 0x7a, 0x3f, 0xef, 0x81, 0x42, 0xf3, 0xf7, 0xc7, 0x71, 0x9a,
+    0x1c, 0x2a, 0x47, 0x48, 0x8c, 0x83, 0x41, 0x27, 0x52, 0x2e, 0xb1, 0xac,
+    0x43, 0xb0, 0xc9, 0x18, 0x38, 0x0d, 0x43, 0xa2, 0xcf, 0xbd, 0x22, 0x78,
+    0xca, 0x48, 0x8f, 0x58, 0x83, 0x9d, 0x29, 0x06, 0xf1, 0x20, 0x81, 0x20,
+    0x82, 0xe0, 0x2d, 0x83, 0xf7, 0xbc, 0x4f, 0x70, 0xa4, 0x75, 0x3e, 0xb9,
+    0x85, 0x61, 0x96, 0xf8, 0x14, 0x60, 0x7d, 0xaf, 0xd1, 0x8f, 0x45, 0x37,
+    0xec, 0x30, 0xa9, 0x4d, 0x36, 0xea, 0x85, 0x91, 0x55, 0x62, 0xd5, 0x8c,
+    0xe6, 0x12, 0x79, 0xdb, 0x38, 0xd7, 0xe2, 0x13, 0x83, 0x44, 0x39, 0x4d,
+    0xde, 0x50, 0x9b, 0x79, 0x3b, 0x8d, 0x38, 0xdc, 0x4e, 0xd7, 0xa4, 0xae,
+    0x13, 0x24, 0x3b, 0x0b, 0x58, 0x89, 0x10, 0x54, 0x17, 0x3d, 0xb9, 0x7e,
+    0x7f, 0xed, 0x4e, 0xeb, 0xf4, 0x09, 0x03, 0x68, 0x90, 0xc6, 0xd2, 0x01,
+    0xdd, 0xe4, 0x2e, 0xe0, 0x72, 0x3c, 0xb5, 0x4e, 0x52, 0xa5, 0x82, 0x0f,
+    0x5f, 0x9f, 0xe1, 0xc8, 0xfd, 0xbf, 0x7d, 0xc2, 0xfc, 0x0e, 0x5a, 0x3c,
+    0x0b, 0x7e, 0xda, 0xf5, 0x7e, 0x8b, 0x51, 0x9a, 0xe9, 0x4d, 0xe4, 0x81,
+    0xe7, 0x31, 0xa7, 0x96, 0xd1, 0x5a, 0xdb, 0x4a, 0xad, 0xb1, 0x95, 0xec,
+    0xc3, 0x0f, 0xf3, 0x0d, 0xea, 0x03, 0x13, 0x8a, 0x38, 0x3e, 0xda, 0xea,
+    0x8f, 0x31, 0x33, 0xe6, 0x2d, 0xbb, 0x77, 0xfe, 0xd4, 0x28, 0x8c, 0x02,
+    0xed, 0x1d, 0x0a, 0xc6, 0x60, 0x1c, 0xd0, 0x6f, 0xd2, 0x10, 0xbd, 0x71,
+    0x27, 0x31, 0x04, 0x9d, 0xa3, 0xb3, 0x9f, 0x63, 0xf3, 0x5e, 0x06, 0xa8,
+    0x44, 0xd2, 0x4a, 0x96, 0x91, 0x9e, 0x61, 0xcd, 0x2b, 0x2c, 0xb8, 0xb0,
+    0xf8, 0xf6, 0xd0, 0xa9, 0x0f, 0x56, 0xcd, 0x88, 0x3f, 0xbc, 0x0e, 0x54,
+    0x27, 0x20, 0x18, 0x7d, 0x3e, 0xe8, 0x6b, 0x1b, 0xab, 0x65, 0xbf, 0xe9,
+    0xe4, 0xb1, 0x85, 0xe7, 0x4a, 0xdf, 0xae, 0xd0, 0x8d, 0xc0, 0x42, 0x51,
+    0x38, 0x6a, 0x0a, 0x72, 0x8f, 0x5e, 0x8b, 0x31, 0x7e, 0xf7, 0x5f, 0xa0,
+    0x63, 0x08, 0x42, 0x2d, 0x00, 0x25, 0xdc, 0xe3, 0x3b, 0x5e, 0xb7, 0x15,
+    0xd1, 0x3b, 0x41, 0x24, 0x66, 0x62, 0x8a, 0xde, 0x2b, 0x74, 0x13, 0x49,
+    0xbc, 0x9f, 0x5f, 0x19, 0x09, 0x71, 0xed, 0x83, 0x45, 0xe8, 0x78, 0xfb,
+    0x3b, 0x18, 0xd4, 0x55, 0x13, 0x4c, 0x19, 0x91, 0x64, 0x71, 0x13, 0x2b,
+    0xc2, 0x71, 0x05, 0x34, 0x26, 0x38, 0x15, 0x58, 0xe8, 0x22, 0x1b, 0x2e,
+    0x09, 0x18, 0x7f, 0xe1, 0xb0, 0xb0, 0xaa, 0xd3, 0x48, 0x6f, 0xab, 0x79,
+    0x5f, 0x55, 0x8e, 0x2b, 0x67, 0x79, 0x2d, 0x4e, 0x7f, 0xd3, 0xf8, 0x94,
+    0xb3, 0xf3, 0x0c, 0xe2, 0xae, 0xd3, 0x50, 0x2f, 0xfd, 0x3e, 0xd8, 0x30,
+    0xb6, 0x20, 0xf7, 0xe1, 0xcb, 0x50, 0x36, 0xe5, 0x7a, 0xdb, 0x32, 0x6d,
+    0x9f, 0x01, 0x85, 0x37, 0xa9, 0xaf, 0xdd, 0xcd, 0x5c, 0xe3, 0xd3, 0x8f,
+    0xcb, 0x82, 0x0e, 0x9c, 0x1e, 0x35, 0x1e, 0x6b, 0xef, 0xe0, 0xd2, 0xec,
+    0x84, 0xc4, 0x4e, 0x0b, 0xe6, 0xfb, 0x4f, 0x26, 0xff, 0x19, 0x24, 0x83,
+    0xcf, 0x4c, 0x4b, 0xb6, 0x95, 0x5c, 0x4c, 0x94, 0x9c, 0x74, 0x72, 0x89,
+    0x30, 0xd8, 0x3a, 0x47, 0xea, 0x8d, 0xe8, 0x55, 0x60, 0xdb, 0x33, 0x5a,
+    0xf5, 0x5c, 0xcf, 0x5f, 0xa0, 0xe8, 0x3c, 0xe2, 0x09, 0x91, 0x34, 0x7a,
+    0x07, 0x52, 0x71, 0x12, 0x29, 0x4a, 0xc8, 0x51, 0xda, 0x4e, 0x81, 0x3c,
+    0x1e, 0x24, 0xd3, 0xb7, 0xbc, 0x3c, 0x18, 0x91, 0x81, 0x80, 0x62, 0xa1,
+    0xde, 0x36, 0xac, 0x91, 0x2c, 0xd9, 0x62, 0x27, 0x9a, 0x43, 0xca, 0xd1,
+    0xea, 0x4d, 0x7c, 0xc1, 0x9e, 0x55, 0x37, 0x89, 0xc2, 0xe3, 0x2d, 0xbc,
+    0xe5, 0x8e, 0x5d, 0x44, 0x7b, 0x4a, 0x96, 0x5b, 0xc8, 0x42, 0x56, 0xab,
+    0xc6, 0x24, 0x3e, 0xd4, 0x31, 0x17, 0x02, 0x10, 0x90, 0xcb, 0x4c, 0x9c,
+    0xbc, 0x29, 0x05, 0x91, 0x5a, 0x9d, 0xcf, 0x6e, 0x8a, 0xef, 0x66, 0xf1,
+    0xbc, 0xfb, 0x6c, 0xcc, 0x12, 0x2c, 0x59, 0x0a, 0xab, 0xeb, 0xd7, 0x12,
+    0x59, 0x47, 0x06, 0xd2, 0x0e, 0x49, 0xa4, 0x57, 0x40, 0x0e, 0xdf, 0x43,
+    0x77, 0x7f, 0xec, 0xbd, 0x9d, 0xfb, 0x0a, 0x25, 0x24, 0xda, 0x02, 0x98,
+    0x17, 0xd9, 0x5d, 0xb4, 0xc6, 0x68, 0x48, 0x13, 0x8e, 0x75, 0x0e, 0x42,
+    0x6e, 0x06, 0x9e, 0x8d, 0x56, 0xd9, 0x5d, 0xbd, 0x53, 0x11, 0xe7, 0x50,
+    0xf6, 0x97, 0xeb, 0xdf, 0xed, 0x91, 0x64, 0xe0, 0x6c, 0xf1, 0xce, 0xf5,
+    0x1f, 0x9d, 0x9e, 0x22, 0x52, 0xf8, 0x60, 0x86, 0x68, 0xff, 0x5f, 0x90,
+    0x3e, 0x7e, 0x2b, 0x74, 0xd6, 0x5d, 0xa0, 0xaa, 0x0e, 0x38, 0x1d, 0x1d,
+    0xc2, 0xe5, 0x3a, 0xd2, 0xc0, 0x32, 0xc9, 0x74, 0xe2, 0x52, 0x03, 0xe3,
+    0xce, 0x45, 0x8e, 0x64, 0xfa, 0xb4, 0x26, 0x8e, 0x2e, 0xc8, 0x57, 0xf7,
+    0xe7, 0x09, 0x74, 0x87, 0x61, 0x5c, 0x15, 0x67, 0xa1, 0xb7, 0xda, 0x45,
+    0x49, 0x76, 0x76, 0xb4, 0x65, 0x45, 0x50, 0x1c, 0x1e, 0x2c, 0x25, 0xd2,
+    0xbf, 0x84, 0x2f, 0x82, 0x35, 0xe0, 0x40, 0x0f, 0x65, 0x58, 0x80, 0x7f,
+    0x8f, 0x19, 0x2c, 0x18, 0x8c, 0x42, 0xcf, 0x32, 0x23, 0xde, 0xe1, 0x40,
+    0x69, 0x51, 0xbd, 0xb6, 0x7f, 0x7b, 0x28, 0x59, 0x24, 0x6d, 0xdd, 0x39,
+    0x17, 0xfe, 0x1d, 0x42, 0x30, 0x58, 0x35, 0x0e, 0x7d, 0xe1, 0xff, 0xd3,
+    0x1d, 0xba, 0xaa, 0x40, 0x33, 0x0d, 0x4e, 0x12, 0x38, 0x29, 0x28, 0x84,
+    0x8f, 0x16, 0x6e, 0x9b, 0x2e, 0x0f, 0xa0, 0xfb, 0xdd, 0x24, 0x78, 0xd3,
+    0xae, 0xee, 0xc5, 0xc5, 0x6a, 0xae, 0x6b, 0xc0, 0x1d, 0x28, 0x04, 0x82,
+    0x04, 0x00, 0x80, 0x75, 0xee, 0x23, 0x2b, 0x33, 0xe0, 0x1e, 0x22, 0x39,
+    0x2b, 0x70, 0xc6, 0x6d, 0xb5, 0xc1, 0x8f, 0x2d, 0x95, 0x87, 0xec, 0xcc,
+    0x5b, 0x50, 0x98, 0x46, 0xee, 0x83, 0x36, 0x83, 0xf5, 0xa2, 0x8e, 0x12,
+    0xeb, 0x01, 0x2a, 0x76, 0xdb, 0x91, 0xda, 0x8b, 0x83, 0x4f, 0xc7, 0xe8,
+    0x8d, 0xf6, 0xa8, 0x07, 0x55, 0x5e, 0xa4, 0x72, 0x83, 0x74, 0x4d, 0xb6,
+    0xf4, 0x2a, 0x58, 0x88, 0x45, 0xc4, 0xfa, 0x30, 0xef, 0x8e, 0x10, 0x35,
+    0x50, 0x21, 0x35, 0xc2, 0xa1, 0xc2, 0x96, 0x5e, 0x8d, 0x76, 0xa5, 0x66,
+    0xba, 0x72, 0x0f, 0x28, 0x83, 0x50, 0x9c, 0x65, 0x84, 0xe8, 0xf8, 0x73,
+    0x8f, 0x52, 0x1b, 0xc7, 0x59, 0x4b, 0x73, 0x2f, 0xb5, 0xeb, 0xaf, 0x03,
+    0x53, 0x63, 0x60, 0x57, 0x8b, 0x22, 0x5b, 0x45, 0x85, 0x95, 0xc6, 0x4b,
+    0xa5, 0xe7, 0xd4, 0xf6, 0x90, 0x70, 0xb7, 0xca, 0x34, 0x64, 0x2a, 0x28,
+    0x3c, 0x9b, 0xb2, 0x75, 0x5c, 0xb6, 0xf1, 0x8b, 0x6e, 0xea, 0xdf, 0x4e,
+    0x03, 0x34, 0x28, 0xff, 0x1b, 0xdf, 0x01, 0x7a, 0x23, 0x60, 0x20, 0xde,
+    0xeb, 0xa0, 0x60, 0xa0, 0x21, 0xe5, 0x30, 0x2c, 0x53, 0x69, 0x00, 0xa3,
+    0xc6, 0x1e, 0x06, 0x25, 0x33, 0xc0, 0x5a, 0xe3, 0xb6, 0xf0, 0x4a, 0x61,
+    0x8d, 0x53, 0x20, 0x92, 0xcf, 0x4e, 0x5a, 0xe1, 0x7f, 0xb3, 0x94, 0x20,
+    0x89, 0xfa, 0xdb, 0x22, 0xc6, 0x12, 0x50, 0x72, 0x86, 0x31, 0x24, 0xc5,
+    0x4e, 0x4e, 0x7f, 0xe1, 0x3b, 0x6b, 0xd6, 0xee, 0x3e, 0x0b, 0x2e, 0x1c,
+    0x88, 0xce, 0x43, 0xc6, 0x7d, 0xf9, 0x85, 0xe1, 0x74, 0x1b, 0xa4, 0x30,
+    0x8e, 0x6e, 0x0a, 0xda, 0xb9, 0x75, 0x2f, 0xc2, 0x07, 0xee, 0x4a, 0xc6,
+    0x16, 0xac, 0x4c, 0xeb, 0xcd, 0xf6, 0xd5, 0x53, 0xc3, 0x91, 0x2b, 0x8c,
+    0x42, 0x87, 0x7d, 0x20, 0xdb, 0xb2, 0x6a, 0xb3, 0xd2, 0xab, 0x84, 0x06,
+    0xc1, 0x7a, 0x2c, 0xa7, 0x2b, 0x89, 0x8c, 0x0a, 0xd4, 0xe7, 0x23, 0x2e,
+    0xfb, 0xad, 0xf2, 0x48, 0xf4, 0x6a, 0xcf, 0x65, 0x09, 0x4f, 0x19, 0xdc,
+    0xa5, 0x64, 0x0b, 0xfb, 0x8a, 0x91, 0xb0, 0x3d, 0x95, 0x86, 0x27, 0x78,
+    0x4a, 0xfd, 0xed, 0xfb, 0x51, 0xda, 0x55, 0x1a, 0xeb, 0xb5, 0xf4, 0xd2,
+    0x4b, 0xab, 0x31, 0xab, 0x8a, 0x24, 0x8b, 0x19, 0x28, 0x0d, 0x65, 0x2f,
+    0x79, 0x27, 0x75, 0xbd, 0x7e, 0x55, 0xf7, 0x9d, 0xc1, 0x6c, 0xda, 0x53,
+    0x78, 0x02, 0x3f, 0x9d, 0x04, 0x13, 0xfd, 0x9d, 0xb0, 0x29, 0x21, 0x9f,
+    0x9f, 0x9c, 0x0e, 0x80, 0xd1, 0x8e, 0x98, 0xef, 0xbe, 0x25, 0x9f, 0x13,
+    0x76, 0xd3, 0x5c, 0x4e, 0x43, 0x28, 0x46, 0xb0, 0x39, 0x53, 0x32, 0x09,
+    0xa2, 0x78, 0xbb, 0x02, 0x28, 0x05, 0x06, 0x2e, 0x2f, 0x80, 0x97, 0x1c,
+    0xa2, 0xa9, 0x78, 0x87, 0x5d, 0x0a, 0x8c, 0x60, 0x75, 0x81, 0xbd, 0x46,
+    0x07, 0xad, 0x8b, 0xbc, 0xb3, 0xed, 0x5b, 0xde, 0x66, 0xc9, 0xda, 0x91,
+    0x76, 0x9e, 0xf4, 0x74, 0xf5, 0xc6, 0xff, 0x12, 0x8d, 0x73, 0x01, 0x34,
+    0x4f, 0x11, 0xcd, 0xd2, 0x29, 0x87, 0x76, 0x4b, 0x6d, 0x6d, 0xca, 0x3b,
+    0xc9, 0xc1, 0xa5, 0x60, 0xd7, 0xd0, 0xaf, 0xc5, 0x36, 0x6e, 0x61, 0x61,
+    0xa0, 0x4d, 0xf2, 0xdf, 0xca, 0x9f, 0x02, 0xf5, 0x27, 0x2e, 0x9e, 0x5b,
+    0xf3, 0x44, 0xb1, 0x25, 0xef, 0x62, 0xbd, 0x92, 0x1b, 0x3c, 0xb8, 0xac,
+    0x69, 0xd8, 0x40, 0x5e, 0x5e, 0x06, 0x8e, 0xa4, 0xbd, 0x7d, 0x49, 0xfa,
+    0x3e, 0xd4, 0x4c, 0xcd, 0x69, 0x07, 0x36, 0x50, 0xa8, 0x67, 0xf5, 0x91,
+    0x41, 0xf5, 0x73, 0xcf, 0x11, 0x5f, 0x9d, 0x93, 0xae, 0xee, 0x81, 0x71,
+    0x89, 0x32, 0x1c, 0x7e, 0x72, 0xb8, 0xef, 0xe3, 0x1b, 0x9f, 0x90, 0xdd,
+    0x17, 0xc0, 0x55, 0x39, 0x1a, 0x14, 0x60, 0x4c, 0x22, 0x88, 0x91, 0xbe,
+    0xb0, 0xf1, 0x4e, 0x97, 0x76, 0x71, 0x21, 0x91, 0x0c, 0x7c, 0x80, 0x4c,
+    0x3b, 0xdc, 0x11, 0x91, 0x51, 0x0c, 0x24, 0xd7, 0x02, 0xc8, 0xe7, 0x9f,
+    0x1e, 0xed, 0xbc, 0xa1, 0x08, 0x08, 0xe6, 0x65, 0x73, 0x01, 0xe1, 0xe1,
+    0xc7, 0xb0, 0x61, 0x7c, 0x16, 0x2b, 0xc0, 0x04, 0x0c, 0xd2, 0x63, 0x15,
+    0x63, 0xf6, 0xef, 0x4d, 0xf4, 0x6f, 0x64, 0x6e, 0x6d, 0x1f, 0xf2, 0x58,
+    0x84, 0xaf, 0x0f, 0x96, 0x14, 0xc1, 0x2d, 0x8e, 0xed, 0xcb, 0xab, 0x8f,
+    0x4d, 0x14, 0xb0, 0x2a, 0x70, 0x41, 0x7c, 0x3e, 0x70, 0x65, 0x06, 0xb3,
+    0x7b, 0x03, 0x73, 0xde, 0xf3, 0x88, 0x6b, 0x58, 0x8f, 0x1c, 0xd0, 0x7d,
+    0xfe, 0xd6, 0xd2, 0x6d, 0x3c, 0x52, 0x83, 0xac, 0x44, 0x8b, 0x04, 0x58,
+    0xe4, 0xac, 0x4b, 0x0e, 0xde, 0x90, 0x05, 0x64, 0x3c, 0x1b, 0xb0, 0xf6,
+    0x14, 0x7f, 0x99, 0x74, 0x23, 0x42, 0xad, 0x96, 0x6a, 0x30, 0x31, 0x17,
+    0x6d, 0x91, 0x3b, 0x8f, 0x1c, 0xab, 0x8b, 0xc3, 0x79, 0xc2, 0x08, 0xb6,
+    0x32, 0xdb, 0xfb, 0x52, 0xcf, 0x4c, 0xf1, 0x0b, 0x87, 0xd2, 0x29, 0xe0,
+    0xc8, 0xf2, 0x1a, 0x5e, 0x8a, 0x69, 0xfa, 0x61, 0x53, 0xf7, 0xec, 0x3d,
+    0xaa, 0x33, 0xa1, 0x36, 0x0f, 0x22, 0x0c, 0xc1, 0x88, 0xfc, 0x8a, 0x4b,
+    0xbc, 0x06, 0xf0, 0x21, 0xf5, 0x38, 0x4e, 0x4b, 0x04, 0x5b, 0x5c, 0x11,
+    0xcc, 0x62, 0x61, 0xa3, 0xae, 0x2e, 0x50, 0x80, 0xe9, 0x80, 0xa6, 0x55,
+    0x21, 0x9f, 0xdb, 0xf0, 0x2c, 0xaa, 0xac, 0x01, 0x59, 0x9f, 0xa4, 0x72,
+    0x80, 0xb3, 0xdf, 0x92, 0xe7, 0x82, 0xa6, 0xcd, 0xc1, 0x4b, 0x1b, 0x25,
+    0x4e, 0xb9, 0xfc, 0x36, 0x1a, 0xd8, 0xc7, 0xc9, 0xc5, 0x0f, 0xf9, 0x64,
+    0xa7, 0x46, 0xb5, 0x0d, 0xf9, 0x82, 0x52, 0x4d, 0x2d, 0x7e, 0x78, 0xdb,
+    0x25, 0x4f, 0xe8, 0x3e, 0xef, 0xea, 0x1b, 0x2f, 0xaf, 0x58, 0xad, 0xc4,
+    0x97, 0xe6, 0x13, 0xc7, 0x37, 0x02, 0x5d, 0xb8, 0xff, 0x10, 0x22, 0xc9,
+    0x2c, 0x49, 0xb6, 0xd6, 0x14, 0xe3, 0xe9, 0x3f, 0x03, 0xa3, 0xe4, 0x6b,
+    0xf9, 0xb6, 0xb2, 0x0a, 0xcc, 0x24, 0x95, 0xca, 0x2f, 0x8e, 0xb0, 0x89,
+    0xe7, 0x37, 0xac, 0xa3, 0x34, 0x37, 0x0f, 0xc9, 0x88, 0x19, 0x63, 0x82,
+    0x92, 0xaf, 0x0b, 0x94, 0x68, 0xd7, 0xd9, 0xc8, 0x62, 0x82, 0xe8, 0x0d,
+    0x99, 0xfd, 0x43, 0x2e, 0x69, 0xee, 0x51, 0xfd, 0x0a, 0xd2, 0x8f, 0x2e,
+    0xe4, 0xc4, 0x73, 0x80, 0x25, 0x07, 0x4b, 0x9c, 0x72, 0xba, 0xc2, 0xc1,
+    0x03, 0xf5, 0xfa, 0xae, 0xc8, 0xab, 0xac, 0x87, 0x15, 0x76, 0xa0, 0x4d,
+    0x15, 0x59, 0xfc, 0x40, 0x5e, 0xc0, 0x86, 0x66, 0xde, 0xf6, 0xce, 0xdb,
+    0x8d, 0x50, 0xed, 0x9c, 0x5b, 0x3f, 0x47, 0x00, 0x93, 0x3c, 0xe9, 0x29,
+    0x14, 0x01, 0xa8, 0xdb, 0x3a, 0xd9, 0xd4, 0xb0, 0x33, 0xe0, 0xc8, 0xaa,
+    0x0c, 0xf7, 0x3a, 0x73, 0x88, 0x20, 0x68, 0x62, 0xc4, 0xcb, 0xc2, 0x94,
+    0xf0, 0x05, 0xb0, 0x85, 0xfb, 0x37, 0xab, 0xe2, 0x98, 0xc4, 0x5f, 0xba,
+    0xda, 0x6a, 0x6c, 0xa5, 0x1e, 0x92, 0x4f, 0x91, 0xa9, 0xa7, 0xbd, 0x39,
+    0x6e, 0x44, 0xad, 0xc3, 0x85, 0xc4, 0xb3, 0x2b, 0xe5, 0xc9, 0x1f, 0x53,
+    0x02, 0x9d, 0x89, 0x42, 0xd7, 0x36, 0x11, 0x11, 0x1f, 0x64, 0x33, 0xe9,
+    0xb9, 0x77, 0x72, 0x8e, 0x8e, 0xc9, 0x5f, 0xc5, 0xf9, 0x3f, 0xf7, 0xe3,
+    0xaf, 0xf3, 0xd0, 0x8c, 0xe9, 0x49, 0x74, 0x61, 0xb6, 0xf1, 0x46, 0x50,
+    0xd3, 0xd4, 0xde, 0x2c, 0x63, 0xa6, 0xbd, 0x26, 0x21, 0x2a, 0x91, 0xd3,
+    0x22, 0xc1, 0x72, 0x12, 0xa2, 0xb8, 0x04, 0x82, 0x02, 0x90, 0xc1, 0xbe,
+    0x28, 0x92, 0x4b, 0x84, 0xce, 0x57, 0xc3, 0xd2, 0x44, 0x9c, 0xa0, 0x70,
+    0xcd, 0xb5, 0x08, 0x37, 0x6a, 0x43, 0x5c, 0xc0, 0x53, 0x15, 0xff, 0x69,
+    0x15, 0x75, 0x91, 0x17, 0xb7, 0x13, 0x3e, 0xfd, 0xcb, 0xb4, 0x05, 0x2f,
+    0x37, 0xbb, 0xc0, 0x34, 0x4c, 0xc3, 0xf7, 0xc3, 0x2b, 0x6c, 0x57, 0xf0,
+    0x7d, 0x60, 0x28, 0x98, 0x92, 0x43, 0x2e, 0xce, 0x57, 0x17, 0x73, 0x86,
+    0x57, 0x52, 0xea, 0xab, 0xea, 0x66, 0x4f, 0x0b, 0x9f, 0x39, 0xab, 0x64,
+    0x4c, 0x8b, 0xb8, 0x42, 0x88, 0x71, 0x5f, 0xbc, 0x86, 0x94, 0xf1, 0x71,
+    0xea, 0x87, 0xd5, 0x55, 0x47, 0x9b, 0xe3, 0xf6, 0xcc, 0xda, 0x40, 0x75,
+    0x1b, 0x7e, 0xa0, 0x33, 0xe5, 0x77, 0x75, 0xdb, 0x93, 0x26, 0x47, 0xbc,
+    0x44, 0xf2, 0xa5, 0x41, 0x08, 0xc2, 0xeb, 0xd0, 0x35, 0x7d, 0x68, 0xed,
+    0xab, 0xce, 0x9d, 0x05, 0x17, 0x0b, 0xdb, 0xd9, 0x4b, 0x61, 0x35, 0x75,
+    0xe2, 0xe9, 0xce, 0xca, 0xca, 0x11, 0xfc, 0xbb, 0xea, 0x47, 0x36, 0x76,
+    0xe6, 0x78, 0x10, 0xf2, 0x3a, 0xd6, 0x7a, 0x7f, 0xb6, 0x5b, 0x74, 0xb8,
+    0x8e, 0x82, 0x2a, 0x6f, 0xd5, 0x40, 0x0c, 0xcb, 0x30, 0x43, 0x4c, 0x8b,
+    0x18, 0xdf, 0x31, 0xf2, 0xdd, 0xf7, 0x1d, 0x2e, 0xea, 0xf8, 0xaa, 0x42,
+    0xc3, 0xc1, 0x6e, 0x98, 0x2b, 0x63, 0xbb, 0x3b, 0x0a, 0x91, 0x85, 0x4a,
+    0xee, 0xaf, 0xc6, 0xd8, 0x52, 0x93, 0xfb, 0x88, 0x96, 0x5e, 0xc7, 0x0d,
+    0xde, 0x30, 0xcc, 0x9f, 0xf3, 0xd4, 0xeb, 0x82, 0x8a, 0x16, 0x81, 0xa5,
+    0xc6, 0x5c, 0x8c, 0xd5, 0x6c, 0x58, 0x12, 0xab, 0x8a, 0xad, 0x42, 0xb5,
+    0xfa, 0x94, 0x59, 0x86, 0x51, 0x6d, 0x22, 0xf2, 0xe0, 0x20, 0xb3, 0xc4,
+    0x25, 0x44, 0x41, 0xb0, 0xc8, 0xde, 0xaa, 0x64, 0xd5, 0xdf, 0x35, 0x49,
+    0x0f, 0x7f, 0x22, 0xda, 0x26, 0x3a, 0x88, 0x36, 0x3b, 0xb4, 0x08, 0x82,
+    0x0c, 0x64, 0x9f, 0xa6, 0x55, 0x4c, 0x0f, 0xe4, 0xd0, 0x19, 0xb5, 0x8a,
+    0xd8, 0xd9, 0x3b, 0x00, 0x8b, 0x2a, 0x6e, 0x13, 0x08, 0xb1, 0x77, 0x21,
+    0x67, 0x92, 0x9c, 0xdf, 0x6c, 0x9c, 0xd0, 0xac, 0xc9, 0x47, 0xfe, 0x54,
+    0xa6, 0x4e, 0xd8, 0x88, 0xfd, 0x50, 0x48, 0xb0, 0x17, 0x36, 0xd9, 0x0a,
+    0xb4, 0x31, 0x6d, 0xa1, 0x11, 0xb6, 0x93, 0x96, 0xa2, 0x84, 0x36, 0x82,
+    0xfe, 0x3d, 0xc7, 0x5d, 0x2f, 0x83, 0x16, 0xfb, 0x21, 0x1b, 0x03, 0xf9,
+    0xaf, 0xef, 0x9d, 0x69, 0xfb, 0x78, 0x9a, 0xd5, 0x77, 0xc5, 0xca, 0x00,
+    0xcd, 0xb1, 0x97, 0x58, 0xf5, 0x84, 0xfd, 0x6b, 0x1c, 0x50, 0xd1, 0xfc,
+    0xbd, 0xf6, 0x25, 0x9e, 0x6f, 0x21, 0x84, 0xcc, 0xb4, 0xd0, 0x09, 0xc2,
+    0xa2, 0x6f, 0x42, 0xa9, 0x02, 0x43, 0xa0, 0xd9, 0x4f, 0x64, 0x5f, 0xcd,
+    0xc8, 0x83, 0x13, 0xa5, 0x10, 0xdb, 0xed, 0xf7, 0x76, 0x2b, 0x61, 0xd7,
+    0x50, 0xc8, 0x21, 0x2c, 0x70, 0xe0, 0x24, 0xfd, 0x37, 0xa8, 0x75, 0x94,
+    0x56, 0x90, 0x6f, 0x3f, 0xec, 0x82, 0x66, 0xb8, 0xa9, 0x78, 0x52, 0x09,
+    0xb1, 0xa3, 0x1b, 0x8e, 0x9d, 0xbc, 0x48, 0x92, 0x6a, 0xa5, 0x51, 0xaa,
+    0xd3, 0xcd, 0x08, 0xb4, 0xe9, 0x84, 0x28, 0xca, 0xcf, 0xc5, 0x15, 0xd9,
+    0xa7, 0x50, 0x8e, 0x95, 0x84, 0xcb, 0x9b, 0x37, 0xaa, 0xda, 0x18, 0x22,
+    0x46, 0x40, 0xf0, 0x09, 0x87, 0xc7, 0x9c, 0x52, 0xe1, 0x5a, 0xe2, 0xaa,
+    0xc3, 0xf7, 0x66, 0x94, 0x21, 0x1b, 0xaf, 0x44, 0x4d, 0xb9, 0x51, 0x39,
+    0x9f, 0x3b, 0x2f, 0xac, 0x80, 0xf3, 0xfe, 0xc5, 0xa5, 0x50, 0x5c, 0x4e,
+    0x80, 0xc8, 0x5f, 0xbd, 0xaa, 0x19, 0xf1, 0x8a, 0x40, 0xa9, 0xb6, 0x4d,
+    0xa9, 0x06, 0xe9, 0x3f, 0xf9, 0x27, 0x9e, 0xcf, 0x15, 0x65, 0x27, 0xb3,
+    0x30, 0x12, 0x4d, 0x1f, 0x7f, 0x9d, 0x26, 0xa1, 0xbe, 0x83, 0x28, 0xaf,
+    0xd5, 0xae, 0xaa, 0x14, 0xfd, 0x19, 0x16, 0xaa, 0x70, 0x21, 0xbf, 0xfa,
+    0x5f, 0xa3, 0xf7, 0x53, 0xc1, 0xa5, 0x35, 0x5a, 0x07, 0x65, 0x89, 0x68,
+    0xac, 0x95, 0x4d, 0xc8, 0xf2, 0xa0, 0xe3, 0x9f, 0xbd, 0xe3, 0x39, 0xd1,
+    0x82, 0x86, 0xbf, 0xc5, 0x47, 0xba, 0x52, 0x5c, 0xb4, 0xd0, 0xaf, 0x49,
+    0x65, 0x1a, 0x6a, 0x78, 0x52, 0xbb, 0xbe, 0xf0, 0xbe, 0x15, 0x9a, 0xae,
+    0x46, 0xd0, 0xcb, 0xa0, 0xe9, 0xd2, 0x09, 0xc0, 0x87, 0xc8, 0x52, 0x63,
+    0xc0, 0xcc, 0x9b, 0x23, 0x88, 0x19, 0xb9, 0xac, 0xa4, 0xc0, 0x41, 0x6f,
+    0xf3, 0xff, 0x31, 0x0e, 0x35, 0x00, 0xb0, 0xae, 0xf2, 0xe1, 0xcb, 0x4f,
+    0x87, 0xbc, 0xa9, 0xe5, 0x1b, 0x63, 0x37, 0xa5, 0x18, 0xca, 0x8a, 0xd1,
+    0xea, 0x25, 0xff, 0x56, 0xaa, 0xda, 0x8b, 0x82, 0x0d, 0x73, 0x4e, 0x68,
+    0xad, 0x35, 0x97, 0x96, 0xa7, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00
+};
+unsigned int __9639569_bin_len = 4432;
+
+unsigned char local_p12[] = {
+    0x30, 0x82, 0x09, 0x91, 0x02, 0x01, 0x03, 0x30, 0x82, 0x09, 0x57, 0x06,
+    0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82,
+    0x09, 0x48, 0x04, 0x82, 0x09, 0x44, 0x30, 0x82, 0x09, 0x40, 0x30, 0x82,
+    0x03, 0xf7, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07,
+    0x06, 0xa0, 0x82, 0x03, 0xe8, 0x30, 0x82, 0x03, 0xe4, 0x02, 0x01, 0x00,
+    0x30, 0x82, 0x03, 0xdd, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+    0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+    0x0d, 0x01, 0x0c, 0x01, 0x06, 0x30, 0x0e, 0x04, 0x08, 0x15, 0x50, 0xc8,
+    0xd1, 0xa1, 0xce, 0xa4, 0x13, 0x02, 0x02, 0x08, 0x00, 0x80, 0x82, 0x03,
+    0xb0, 0x15, 0x2c, 0xb2, 0x09, 0xc8, 0x93, 0xc5, 0xe7, 0x94, 0x3b, 0x3f,
+    0xa4, 0xa4, 0x7e, 0x94, 0x9e, 0x83, 0x86, 0xfa, 0x19, 0x0d, 0xe3, 0x82,
+    0x74, 0x9c, 0x24, 0x93, 0x7d, 0xf7, 0x84, 0xe7, 0x35, 0x9c, 0x1f, 0x3f,
+    0x15, 0x25, 0x8e, 0xba, 0xa6, 0xd9, 0xe1, 0x23, 0x0d, 0xbd, 0x6c, 0x16,
+    0x6a, 0xc3, 0xb9, 0x24, 0x65, 0xcf, 0xb8, 0x93, 0x72, 0xd5, 0x3f, 0xd6,
+    0x0b, 0xda, 0x51, 0x58, 0x5c, 0x96, 0xfa, 0x28, 0x13, 0x8c, 0x68, 0x24,
+    0x52, 0x3e, 0x6f, 0x1d, 0x18, 0x2f, 0x51, 0xc7, 0xc4, 0x6b, 0x64, 0x2f,
+    0xdc, 0xea, 0x7f, 0x00, 0x0a, 0x58, 0xe5, 0x9c, 0xa0, 0x3b, 0x33, 0x80,
+    0xdc, 0x7f, 0x0b, 0x92, 0xc8, 0xf0, 0x5c, 0x00, 0xbd, 0x8a, 0x6f, 0x35,
+    0xfa, 0x8f, 0x23, 0x2c, 0x38, 0xd6, 0x70, 0xac, 0x76, 0x9c, 0x80, 0x7f,
+    0xc7, 0x06, 0xd1, 0xcc, 0x0b, 0x81, 0x65, 0x9b, 0x9d, 0xdf, 0x1a, 0x84,
+    0x8d, 0xb6, 0x26, 0xa2, 0x5b, 0x19, 0x62, 0x79, 0xa4, 0x38, 0xee, 0xcc,
+    0xaf, 0x19, 0x24, 0xe9, 0x17, 0xea, 0x78, 0x48, 0xff, 0xda, 0xff, 0x02,
+    0x02, 0x10, 0x67, 0x71, 0xd5, 0x3d, 0x6d, 0x50, 0x77, 0x8a, 0xcc, 0x0a,
+    0x3a, 0x60, 0x16, 0x9e, 0x7f, 0x9d, 0xfa, 0x00, 0x56, 0x80, 0xa1, 0x01,
+    0x58, 0x89, 0xa5, 0x2e, 0x93, 0x5e, 0xd8, 0xb3, 0xf6, 0x72, 0x4d, 0x9e,
+    0xe1, 0xa7, 0xeb, 0x5b, 0x7e, 0xb5, 0xca, 0x66, 0x92, 0xfb, 0xbe, 0x5e,
+    0x85, 0xa3, 0x85, 0xe9, 0x4e, 0x58, 0x90, 0xf9, 0xd3, 0xbc, 0x8d, 0xd4,
+    0x2e, 0xbb, 0x28, 0x88, 0x55, 0x90, 0xb9, 0xd8, 0x28, 0x7a, 0x79, 0xb5,
+    0x2b, 0x28, 0xad, 0x51, 0x9a, 0xc2, 0x0c, 0xeb, 0xe4, 0x83, 0x35, 0x0f,
+    0xde, 0x4c, 0x8a, 0x21, 0xb9, 0xf4, 0xc6, 0x2e, 0xc2, 0x0e, 0x4a, 0xab,
+    0x71, 0xe3, 0x4e, 0x43, 0x88, 0x03, 0x68, 0x92, 0xa8, 0x11, 0x58, 0x3b,
+    0xe3, 0x59, 0xda, 0x29, 0x68, 0x15, 0x00, 0x96, 0x69, 0x59, 0x1d, 0x5b,
+    0x6c, 0xf9, 0xa2, 0xa7, 0xa6, 0x07, 0xc4, 0x62, 0x77, 0x7e, 0x48, 0x6f,
+    0x7b, 0x18, 0xf5, 0xe8, 0x2d, 0xf7, 0xed, 0x0f, 0x27, 0xff, 0x20, 0x9b,
+    0xa8, 0x3b, 0x53, 0xf7, 0x0f, 0x43, 0xd1, 0xdc, 0x37, 0x72, 0x09, 0x9e,
+    0x11, 0x34, 0xa3, 0xfc, 0x56, 0x75, 0xff, 0x17, 0x8b, 0x1b, 0x2d, 0x51,
+    0x88, 0x74, 0x6e, 0xe9, 0x8e, 0xbd, 0x22, 0x84, 0x93, 0x73, 0x8d, 0xca,
+    0xeb, 0x91, 0x3c, 0x72, 0xf5, 0x92, 0x3f, 0x56, 0x1a, 0x58, 0x5b, 0x14,
+    0x19, 0x5a, 0x2f, 0x85, 0xf6, 0x80, 0x35, 0xd3, 0xcb, 0x54, 0xc9, 0x07,
+    0xc0, 0x25, 0x41, 0xa7, 0x18, 0x8a, 0x5d, 0xbb, 0x7b, 0xcd, 0x40, 0x4e,
+    0x3e, 0xb7, 0x99, 0xf4, 0x57, 0x10, 0xcb, 0x6d, 0x89, 0xdc, 0x1b, 0x61,
+    0xf5, 0xc7, 0xc9, 0xe0, 0xae, 0x88, 0x20, 0x94, 0xe9, 0xdc, 0xa6, 0x84,
+    0xf1, 0x3d, 0x67, 0x81, 0xf0, 0x17, 0x7a, 0xad, 0x43, 0x6b, 0x6d, 0xae,
+    0xe5, 0x88, 0x88, 0x11, 0x3c, 0xe8, 0xdd, 0xfb, 0x05, 0x34, 0xb6, 0x3c,
+    0x23, 0x4c, 0xf2, 0xf0, 0x18, 0x53, 0xaf, 0x5e, 0x04, 0x0c, 0x41, 0xe2,
+    0x20, 0x69, 0x89, 0x44, 0x97, 0x7a, 0x23, 0xa4, 0x2d, 0x3b, 0x4e, 0x38,
+    0xce, 0xa1, 0x15, 0x8b, 0xce, 0x7b, 0x47, 0x1d, 0x05, 0xfa, 0xc0, 0xe9,
+    0xf6, 0x5e, 0xdc, 0xaf, 0xe4, 0xe8, 0x01, 0xbc, 0xc4, 0xe0, 0x17, 0xfe,
+    0xe8, 0xfd, 0x4d, 0x3b, 0x07, 0x40, 0x54, 0xc5, 0x6b, 0xac, 0xf5, 0xe9,
+    0xb2, 0x72, 0x80, 0xa5, 0x7b, 0xe6, 0x5a, 0x1a, 0x7e, 0x4f, 0xd7, 0x2c,
+    0x4a, 0x37, 0x9d, 0x16, 0xb4, 0x01, 0x99, 0xf4, 0x0d, 0x3e, 0x66, 0x1d,
+    0xe4, 0x76, 0xa2, 0xef, 0xd4, 0xee, 0xb2, 0xec, 0xbe, 0xef, 0x32, 0x69,
+    0xc4, 0x9f, 0x21, 0x4a, 0x8f, 0x8e, 0x7f, 0xed, 0xe1, 0x43, 0x18, 0x75,
+    0x96, 0xbc, 0xd9, 0x53, 0x99, 0xf3, 0x74, 0x51, 0x9e, 0xd0, 0x6a, 0x04,
+    0xe4, 0xc0, 0xca, 0x08, 0x81, 0x91, 0x6d, 0x2a, 0x84, 0xd3, 0x5e, 0x91,
+    0x0c, 0x9e, 0x7a, 0x4b, 0xd0, 0x0e, 0xaa, 0x3f, 0xbb, 0x14, 0x6a, 0x6d,
+    0xc5, 0xd7, 0xe7, 0xbb, 0xd9, 0x2c, 0x0b, 0xa3, 0xea, 0x4d, 0x06, 0xe7,
+    0x1c, 0x01, 0x71, 0x03, 0x13, 0x58, 0xdd, 0x02, 0x7a, 0xa1, 0x52, 0x2c,
+    0x39, 0xe5, 0x41, 0x90, 0x75, 0xf8, 0x23, 0x56, 0x4e, 0x1e, 0xfa, 0x33,
+    0xbf, 0xd1, 0x34, 0xf3, 0x4d, 0xf0, 0x30, 0x9a, 0xd3, 0x16, 0xa8, 0x73,
+    0xb7, 0xab, 0x89, 0x5a, 0xe6, 0x2e, 0x4b, 0x32, 0xb3, 0x1e, 0x23, 0x07,
+    0x6b, 0x47, 0xca, 0xe5, 0x23, 0xad, 0x11, 0x5d, 0x12, 0x05, 0x25, 0x91,
+    0x64, 0x0c, 0xc3, 0x46, 0xb8, 0x3d, 0x69, 0x5e, 0xb1, 0x76, 0xe4, 0xe0,
+    0x30, 0x06, 0x14, 0x73, 0xa0, 0xaf, 0xe3, 0x54, 0xb8, 0x27, 0x72, 0x41,
+    0xac, 0x5e, 0x4b, 0x19, 0xb5, 0x54, 0xb3, 0x46, 0xb6, 0x87, 0xe3, 0x8b,
+    0x85, 0x5e, 0x69, 0x2f, 0x62, 0x59, 0x65, 0x8b, 0xcd, 0xbd, 0xe3, 0xa6,
+    0xf9, 0x2c, 0x06, 0xfe, 0xfe, 0x45, 0xd3, 0xb8, 0xe4, 0x34, 0x96, 0xf5,
+    0xc0, 0x00, 0x52, 0xc2, 0x13, 0x65, 0x81, 0xe4, 0x4b, 0x69, 0x02, 0x59,
+    0x25, 0x98, 0x85, 0x98, 0xc7, 0xb2, 0x2d, 0x2b, 0x94, 0x84, 0x4a, 0x84,
+    0xda, 0x15, 0xe3, 0x63, 0x20, 0xae, 0x9e, 0x97, 0xf5, 0x01, 0x38, 0x60,
+    0x37, 0x0b, 0x38, 0x93, 0x72, 0x2a, 0xfb, 0xe9, 0xf3, 0xd1, 0xe7, 0x4c,
+    0x95, 0x8f, 0x6e, 0xf2, 0xd6, 0xa9, 0xe2, 0x9f, 0x81, 0x5f, 0x58, 0x99,
+    0xe0, 0x51, 0x4b, 0xbf, 0x84, 0x86, 0xec, 0x27, 0x4f, 0x75, 0xa3, 0x8c,
+    0xba, 0xf3, 0x0c, 0x2b, 0xb3, 0xe1, 0x64, 0xb1, 0x96, 0x10, 0x1e, 0xcc,
+    0x16, 0x1a, 0x5e, 0x0e, 0x85, 0xb2, 0x09, 0x3f, 0xd1, 0x03, 0x82, 0x4d,
+    0x4b, 0xbf, 0x41, 0x9c, 0x26, 0xca, 0xec, 0x81, 0x56, 0xa2, 0x7d, 0x07,
+    0x14, 0x4f, 0xc4, 0x20, 0x47, 0xcb, 0x1b, 0x51, 0x2c, 0x08, 0xb3, 0x4f,
+    0x91, 0x4e, 0x02, 0x7d, 0x90, 0x5a, 0x08, 0xdf, 0xbe, 0x59, 0x47, 0x3b,
+    0x02, 0x4c, 0x15, 0xb5, 0x12, 0x9f, 0x74, 0x54, 0xb2, 0x60, 0xf1, 0x2e,
+    0x1d, 0x4e, 0x4d, 0x43, 0x2b, 0x69, 0xff, 0x5f, 0xb4, 0x69, 0x1f, 0x6e,
+    0x4d, 0xdd, 0xfe, 0x26, 0x14, 0xd9, 0x1c, 0xa0, 0x96, 0x3b, 0xcf, 0x49,
+    0xf0, 0xbe, 0x23, 0x72, 0x93, 0x81, 0x7b, 0xfb, 0x5e, 0xa8, 0x8c, 0x83,
+    0x79, 0x33, 0x16, 0x08, 0x5c, 0x2d, 0x87, 0xe6, 0x17, 0xa7, 0x41, 0x12,
+    0x46, 0x52, 0xa1, 0xa0, 0x31, 0xc1, 0xe3, 0x64, 0xc4, 0x78, 0x10, 0xb3,
+    0x94, 0x71, 0x25, 0x11, 0xff, 0x27, 0xd7, 0xe9, 0x73, 0x6c, 0x0d, 0xaf,
+    0xe1, 0xc4, 0x8d, 0x04, 0x2a, 0x14, 0x94, 0x71, 0xe6, 0xb3, 0x32, 0xb4,
+    0x8c, 0x70, 0x36, 0x6f, 0x83, 0x44, 0xba, 0xad, 0x2c, 0xd0, 0xaa, 0x4c,
+    0xfc, 0x43, 0xd6, 0x28, 0x15, 0x01, 0x9e, 0x3f, 0x66, 0x30, 0x82, 0x05,
+    0x41, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01,
+    0xa0, 0x82, 0x05, 0x32, 0x04, 0x82, 0x05, 0x2e, 0x30, 0x82, 0x05, 0x2a,
+    0x30, 0x82, 0x05, 0x26, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+    0x01, 0x0c, 0x0a, 0x01, 0x02, 0xa0, 0x82, 0x04, 0xee, 0x30, 0x82, 0x04,
+    0xea, 0x30, 0x1c, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+    0x0c, 0x01, 0x03, 0x30, 0x0e, 0x04, 0x08, 0x90, 0xc5, 0x25, 0x0c, 0x5b,
+    0x6d, 0xe4, 0xa9, 0x02, 0x02, 0x08, 0x00, 0x04, 0x82, 0x04, 0xc8, 0x2f,
+    0x02, 0x82, 0x9e, 0x88, 0x18, 0xb2, 0xa0, 0xdc, 0xe8, 0x45, 0xda, 0x94,
+    0x35, 0xa9, 0x61, 0x60, 0x66, 0xba, 0xa5, 0xd8, 0x27, 0x89, 0xd7, 0x67,
+    0xb1, 0x46, 0x34, 0x97, 0x88, 0xed, 0xf1, 0x88, 0x60, 0xec, 0xa1, 0x59,
+    0x78, 0x80, 0xfd, 0x4c, 0x7a, 0x42, 0x5b, 0x8b, 0x25, 0xd3, 0x07, 0xaa,
+    0x3e, 0x60, 0x71, 0x54, 0xfd, 0xc2, 0xfe, 0x08, 0xdf, 0x7d, 0x3f, 0xed,
+    0x51, 0x5f, 0x80, 0x97, 0x19, 0x99, 0x40, 0x59, 0x2f, 0x93, 0x80, 0x55,
+    0xf4, 0x2a, 0xba, 0xed, 0x37, 0x20, 0xe6, 0x56, 0x1c, 0x01, 0xe7, 0x0b,
+    0x98, 0x37, 0x64, 0xf1, 0xc9, 0xaf, 0x47, 0x7e, 0x9b, 0x69, 0x23, 0x9f,
+    0x68, 0x64, 0xf7, 0xbf, 0xba, 0x4a, 0x20, 0xe0, 0x4a, 0x3e, 0x8a, 0xde,
+    0x63, 0x0d, 0xcf, 0x37, 0x40, 0x2a, 0xb6, 0x95, 0x42, 0xb7, 0x1e, 0xf4,
+    0xaa, 0x58, 0x8e, 0x0e, 0x4a, 0x65, 0xb3, 0x47, 0xb0, 0x7e, 0x1d, 0x27,
+    0x1a, 0x82, 0xed, 0xec, 0x58, 0xe0, 0xc6, 0x10, 0xaf, 0xdd, 0x5f, 0x29,
+    0xf3, 0x4f, 0xa3, 0x96, 0x94, 0x51, 0x93, 0x1f, 0xeb, 0xaf, 0x94, 0x41,
+    0x27, 0x38, 0xc0, 0x9e, 0xba, 0x30, 0xe1, 0x38, 0xfb, 0x87, 0xaa, 0x93,
+    0x27, 0xb3, 0xa3, 0xae, 0xce, 0xca, 0x01, 0xbd, 0x7a, 0xc8, 0x8c, 0x1d,
+    0x02, 0x12, 0xc1, 0x3d, 0xa9, 0x7b, 0xd5, 0x82, 0x44, 0x01, 0x69, 0xf9,
+    0x36, 0x7c, 0x42, 0x6b, 0x46, 0x60, 0x28, 0x96, 0x3a, 0xbd, 0x6f, 0x57,
+    0x34, 0x62, 0x7f, 0x09, 0x61, 0x50, 0xd4, 0xed, 0x3c, 0xdd, 0xa1, 0x38,
+    0x7a, 0xe4, 0xaa, 0x07, 0x68, 0x13, 0x26, 0x8f, 0x0d, 0xbd, 0xa9, 0x91,
+    0x0f, 0x05, 0x42, 0x46, 0xf8, 0x08, 0x51, 0x2f, 0x3a, 0x5e, 0x88, 0x0d,
+    0x69, 0x81, 0xfb, 0x59, 0x2b, 0xb5, 0x7f, 0x8c, 0x2a, 0xcf, 0x2a, 0xeb,
+    0x6f, 0x80, 0x23, 0x27, 0xc6, 0x08, 0x29, 0xc5, 0x1a, 0xc1, 0xe9, 0xb8,
+    0x64, 0xce, 0x9c, 0xf2, 0x40, 0x83, 0x6d, 0x12, 0xd3, 0x8e, 0xf5, 0xf4,
+    0x07, 0x14, 0x28, 0xf5, 0x7e, 0x94, 0x88, 0xf1, 0xb5, 0xaf, 0x83, 0x3e,
+    0x67, 0x6a, 0xda, 0x22, 0xc9, 0x49, 0x2a, 0x20, 0x4b, 0x2b, 0xc2, 0x42,
+    0x57, 0x10, 0xfd, 0x18, 0xce, 0xbf, 0xd7, 0xd7, 0x1f, 0xb4, 0xa6, 0x64,
+    0x32, 0x0c, 0x63, 0x20, 0x46, 0x9b, 0x00, 0xd8, 0xe7, 0x1a, 0x10, 0x01,
+    0xf8, 0xb8, 0xb8, 0x87, 0x46, 0x74, 0x55, 0x95, 0xe2, 0x9b, 0xe6, 0xaf,
+    0x10, 0x41, 0x86, 0xaf, 0xf5, 0x3a, 0x39, 0x9e, 0x76, 0x23, 0x30, 0xe4,
+    0x00, 0x67, 0x0a, 0x30, 0x74, 0x9a, 0x85, 0x2c, 0x3c, 0xd1, 0xa7, 0xdf,
+    0x2f, 0x55, 0xee, 0xef, 0x4f, 0x3d, 0x99, 0x46, 0x62, 0xbf, 0x81, 0xbf,
+    0xff, 0x43, 0x45, 0x60, 0x4b, 0x42, 0x7a, 0xb2, 0x97, 0x10, 0xe7, 0xd9,
+    0xcf, 0x7f, 0x48, 0xd4, 0x97, 0x1e, 0xda, 0x77, 0xea, 0x6a, 0xdc, 0x8b,
+    0xb9, 0x95, 0xe9, 0x66, 0x32, 0x0c, 0x1b, 0x12, 0x88, 0xde, 0xdc, 0xc6,
+    0x3f, 0x6d, 0x4e, 0x04, 0xb6, 0x00, 0xc8, 0x54, 0xf0, 0x27, 0x55, 0xf7,
+    0x15, 0x3c, 0xe5, 0xe8, 0x3b, 0xae, 0xcc, 0x8a, 0xd9, 0x25, 0xec, 0x3f,
+    0x06, 0xd1, 0x49, 0x3f, 0x83, 0x56, 0x07, 0x11, 0x4e, 0x3f, 0xd7, 0x1e,
+    0x9f, 0x49, 0x76, 0x0e, 0x3c, 0x02, 0xcf, 0x95, 0x4b, 0x29, 0x8a, 0xc3,
+    0x95, 0x07, 0x52, 0x90, 0xe9, 0xfc, 0x88, 0x95, 0xe6, 0x68, 0x07, 0x86,
+    0xbc, 0x52, 0x0d, 0xf6, 0x3c, 0x20, 0xd6, 0xba, 0xcf, 0x36, 0x39, 0x3f,
+    0x72, 0x97, 0x23, 0xaa, 0x25, 0x19, 0x79, 0x1f, 0xc8, 0x77, 0xff, 0x73,
+    0xdc, 0x76, 0xfd, 0xbd, 0x72, 0xde, 0xd2, 0xbe, 0x7d, 0x39, 0xc4, 0x38,
+    0x30, 0xf0, 0x89, 0x48, 0xf7, 0x82, 0xc9, 0x6a, 0x87, 0xf0, 0x42, 0x78,
+    0x3f, 0x6d, 0x64, 0xa6, 0xf6, 0xbc, 0x72, 0x92, 0x31, 0xd3, 0x1b, 0xac,
+    0x81, 0xc3, 0x1e, 0x07, 0x9d, 0xc0, 0x82, 0xf9, 0x27, 0x96, 0x86, 0x13,
+    0xfc, 0x26, 0x79, 0x7f, 0x16, 0x84, 0x9f, 0x90, 0x61, 0x83, 0x67, 0x82,
+    0xd0, 0x11, 0x35, 0x7b, 0x03, 0x6b, 0xe8, 0xfa, 0xb6, 0x49, 0x7e, 0x94,
+    0xed, 0x68, 0x84, 0x75, 0x95, 0x34, 0x6f, 0x4a, 0x40, 0xff, 0x3c, 0xd6,
+    0x56, 0xc2, 0x0e, 0xd0, 0x2c, 0xf1, 0x22, 0x95, 0xce, 0x77, 0x36, 0xda,
+    0x49, 0xd6, 0x2a, 0x7a, 0x85, 0x16, 0x7d, 0xd7, 0xa2, 0x9e, 0x32, 0x60,
+    0xf9, 0xad, 0xdc, 0xdc, 0xfd, 0xe0, 0x47, 0x43, 0xee, 0x5b, 0xb1, 0x1b,
+    0xd7, 0x60, 0xcf, 0xcf, 0x8b, 0x64, 0x72, 0x5c, 0x80, 0xe5, 0x2f, 0xce,
+    0xd4, 0x68, 0xec, 0x88, 0xb8, 0x37, 0x38, 0x81, 0xba, 0x29, 0x4c, 0xbe,
+    0xb5, 0x0d, 0xda, 0xce, 0x9e, 0x37, 0xc6, 0xd7, 0xd5, 0x05, 0x7a, 0x1e,
+    0x94, 0xdf, 0x23, 0xa3, 0x95, 0x7d, 0x58, 0xfc, 0xfd, 0x5d, 0x4a, 0x50,
+    0xa4, 0x9a, 0x84, 0x1a, 0x74, 0x80, 0xde, 0xf5, 0xa2, 0xf3, 0x36, 0xc7,
+    0x69, 0x90, 0xf0, 0x34, 0xa9, 0x0b, 0x20, 0x45, 0x12, 0x3e, 0x08, 0x81,
+    0x76, 0x3d, 0x87, 0xf3, 0x27, 0x9d, 0x5f, 0x6c, 0x93, 0x0d, 0x1f, 0x43,
+    0x47, 0xce, 0x75, 0x09, 0x06, 0x81, 0xd5, 0xfc, 0xfa, 0xc4, 0x4d, 0x7f,
+    0x58, 0x58, 0xd3, 0x41, 0xe6, 0x10, 0x47, 0xcb, 0x6f, 0x5c, 0x73, 0x34,
+    0xfa, 0x06, 0x4a, 0x2d, 0x5a, 0x59, 0xb7, 0x60, 0x57, 0x3b, 0x81, 0xb1,
+    0x1c, 0xd7, 0x31, 0x1c, 0x07, 0x2b, 0x0f, 0xd7, 0x25, 0x2e, 0xc5, 0x53,
+    0x53, 0xe0, 0x2b, 0x52, 0x0d, 0x65, 0xad, 0xa7, 0x6d, 0x5e, 0xc1, 0x93,
+    0x74, 0x0c, 0x0e, 0x38, 0x37, 0x94, 0x6a, 0x89, 0xc0, 0xc8, 0xe5, 0xad,
+    0x21, 0x97, 0xe9, 0xc3, 0x1d, 0x74, 0x9b, 0xaa, 0xeb, 0x77, 0x27, 0x07,
+    0x25, 0xc1, 0xe7, 0x1b, 0x83, 0x34, 0x82, 0xb9, 0x27, 0xdb, 0x27, 0x10,
+    0xe8, 0xeb, 0xbf, 0x7a, 0x69, 0xae, 0x75, 0x35, 0xf8, 0xbd, 0x60, 0xf4,
+    0x22, 0xbd, 0x2f, 0x92, 0x9c, 0xc1, 0xdf, 0x97, 0xca, 0xb7, 0x14, 0xb6,
+    0xc9, 0xb6, 0x58, 0xff, 0x99, 0x96, 0x6e, 0x32, 0x83, 0x9b, 0xb1, 0xdb,
+    0x6f, 0x70, 0xe4, 0x4a, 0xfa, 0xa9, 0x34, 0x1d, 0x25, 0xaa, 0xd7, 0x25,
+    0x17, 0xf5, 0xd2, 0x6a, 0xef, 0xff, 0x08, 0x1e, 0x0d, 0x48, 0x76, 0xc3,
+    0x7f, 0x06, 0xc6, 0xce, 0x6d, 0xd4, 0xdc, 0x30, 0x93, 0xeb, 0x16, 0x4d,
+    0x5f, 0x2a, 0x38, 0x59, 0x12, 0xe3, 0x14, 0x6a, 0x20, 0x5e, 0x84, 0xd7,
+    0x7a, 0x6c, 0xd9, 0x97, 0x34, 0x9e, 0x6d, 0xff, 0xb2, 0xe3, 0x13, 0x37,
+    0x4c, 0xcf, 0xec, 0x78, 0x0b, 0x1c, 0x54, 0xf8, 0xaa, 0x3a, 0x93, 0x8c,
+    0xdf, 0xfc, 0x59, 0xcd, 0x21, 0xf9, 0x4d, 0x37, 0x8c, 0xd1, 0xd9, 0xcb,
+    0xe5, 0xb2, 0x4a, 0x8b, 0xcc, 0x0a, 0x37, 0xd4, 0x07, 0x6e, 0x1c, 0x9d,
+    0x71, 0xd6, 0x6a, 0x8b, 0x60, 0x11, 0xf0, 0x98, 0xce, 0x95, 0xb0, 0x43,
+    0x3a, 0x7f, 0x2b, 0x5b, 0x89, 0xe1, 0x77, 0x05, 0xa5, 0x81, 0xa3, 0xd0,
+    0xa5, 0xc4, 0x97, 0xd9, 0xc5, 0xb0, 0x26, 0x0d, 0xd8, 0x14, 0x03, 0xf3,
+    0xec, 0x4c, 0x5c, 0xd4, 0xc2, 0x92, 0xad, 0xe5, 0x05, 0x66, 0x95, 0xd9,
+    0x25, 0x57, 0x00, 0x3b, 0x1c, 0xf2, 0xda, 0xe9, 0xd4, 0xea, 0x0b, 0x26,
+    0x7d, 0x63, 0x32, 0x86, 0x06, 0x58, 0xb4, 0x54, 0x41, 0x8d, 0x96, 0x33,
+    0x77, 0xa6, 0x28, 0x9c, 0xee, 0x73, 0x02, 0x08, 0x87, 0x80, 0x3c, 0x21,
+    0x46, 0xe5, 0x48, 0x0d, 0xbb, 0xfa, 0xaf, 0x79, 0x72, 0xfc, 0x23, 0xf4,
+    0xad, 0xf0, 0xcf, 0x08, 0x0a, 0x2d, 0x44, 0x55, 0xe8, 0x5c, 0xdb, 0x5b,
+    0xaf, 0x51, 0x9c, 0xd1, 0x09, 0x89, 0xf8, 0xe9, 0xfc, 0x21, 0x47, 0xd5,
+    0xa4, 0x4f, 0x7c, 0xdc, 0x13, 0x94, 0x8b, 0xd0, 0x9c, 0xdc, 0xb6, 0x5f,
+    0x94, 0x1f, 0xef, 0xb5, 0x42, 0x29, 0x3e, 0x7e, 0xf9, 0x34, 0x4f, 0x83,
+    0xc2, 0xca, 0x49, 0x0a, 0xe4, 0x65, 0xf3, 0xa2, 0x81, 0x2b, 0xbe, 0x75,
+    0x73, 0x3e, 0xbb, 0x9f, 0xcb, 0xab, 0x85, 0x7a, 0x84, 0xc8, 0xaf, 0xdb,
+    0xaf, 0x47, 0x6b, 0x17, 0x08, 0xa8, 0xa7, 0xe5, 0x80, 0x66, 0xd5, 0xc9,
+    0x54, 0xdb, 0x02, 0x59, 0x92, 0xd3, 0xc8, 0x90, 0x14, 0x6e, 0x85, 0xda,
+    0x70, 0xc5, 0x32, 0x91, 0xa1, 0xac, 0xf7, 0xb7, 0x9b, 0x36, 0x48, 0x47,
+    0x6e, 0x33, 0xd4, 0x99, 0x52, 0x97, 0xc9, 0x0a, 0xd3, 0xd5, 0x89, 0x29,
+    0xf0, 0x4c, 0x78, 0x45, 0x55, 0xc4, 0xd9, 0x29, 0x5f, 0x02, 0x4c, 0xb3,
+    0xf6, 0xb2, 0xa9, 0x70, 0x87, 0x45, 0x81, 0x81, 0x4f, 0x50, 0x65, 0x95,
+    0xf4, 0x3b, 0x46, 0xae, 0xfd, 0xb8, 0x29, 0x11, 0x5d, 0xae, 0x10, 0xd3,
+    0xa4, 0xb7, 0x83, 0x4d, 0x13, 0xf8, 0x7d, 0xf0, 0x5e, 0x0a, 0x85, 0xc2,
+    0x6a, 0x80, 0x2a, 0x3b, 0xea, 0x11, 0x56, 0xe7, 0x3e, 0x49, 0xf0, 0xd7,
+    0x6e, 0x36, 0x5f, 0xa6, 0x9b, 0x27, 0xb3, 0x04, 0x99, 0x15, 0x11, 0x96,
+    0x4a, 0x99, 0x7a, 0x28, 0xc7, 0x78, 0xea, 0x15, 0x1c, 0xfc, 0x18, 0x31,
+    0x25, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+    0x09, 0x15, 0x31, 0x16, 0x04, 0x14, 0xe0, 0xfa, 0xf1, 0x0c, 0x0f, 0xef,
+    0x47, 0xfb, 0x9c, 0x6b, 0x13, 0x7a, 0x0f, 0x9e, 0x18, 0x90, 0x5c, 0x9f,
+    0x21, 0x98, 0x30, 0x31, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
+    0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x63, 0x91, 0xb1, 0x0f, 0xba,
+    0x4a, 0x54, 0xe4, 0xd6, 0xb8, 0xd8, 0xd2, 0x28, 0x7e, 0x2a, 0x2d, 0xad,
+    0xe9, 0x78, 0xab, 0x04, 0x08, 0x72, 0x3c, 0x51, 0x37, 0x42, 0x57, 0xf5,
+    0x0f, 0x02, 0x02, 0x08, 0x00
+};
+unsigned int local_p12_len = 2453;
+
+unsigned char smime_skid[] = {
+    0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07,
+    0x03, 0xa0, 0x80, 0x30, 0x80, 0x02, 0x01, 0x02, 0x31, 0x82, 0x01, 0x30,
+    0x30, 0x82, 0x01, 0x2c, 0x02, 0x01, 0x02, 0x80, 0x14, 0x04, 0x9a, 0xee,
+    0xa7, 0x0f, 0xa4, 0x1e, 0x67, 0x89, 0x56, 0xc9, 0x54, 0x71, 0x3e, 0x7f,
+    0x8e, 0x73, 0x40, 0x14, 0x0c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+    0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00,
+    0x4e, 0x31, 0xbe, 0xb4, 0x0d, 0x97, 0xf0, 0x66, 0x85, 0x1f, 0x38, 0xc5,
+    0x80, 0x7b, 0xbd, 0xfd, 0xac, 0xb4, 0x48, 0x85, 0x31, 0xc5, 0x13, 0x09,
+    0xfd, 0xed, 0x8a, 0xce, 0x28, 0x52, 0x90, 0x48, 0xdf, 0xc2, 0x59, 0x43,
+    0x08, 0xbc, 0x29, 0x84, 0xd7, 0x69, 0x26, 0x6c, 0xb8, 0xa2, 0xf9, 0xd0,
+    0xbd, 0x73, 0x29, 0x92, 0xee, 0xfd, 0x20, 0xb0, 0x67, 0xbd, 0xf1, 0x36,
+    0x7d, 0x3b, 0x2b, 0x96, 0x6f, 0x71, 0x2a, 0x8d, 0xf5, 0x80, 0xfe, 0xc5,
+    0x96, 0x9e, 0x19, 0x4b, 0x6f, 0xe4, 0xcf, 0x49, 0xb1, 0x9b, 0xa6, 0xc3,
+    0x2c, 0xf9, 0xcb, 0xc4, 0xde, 0xa3, 0x0f, 0xe9, 0x5a, 0xbb, 0xcf, 0xcc,
+    0x20, 0xde, 0xc2, 0x84, 0xb3, 0x69, 0x09, 0x24, 0xb5, 0xbb, 0x7f, 0x73,
+    0xfe, 0x64, 0xe2, 0xfc, 0x37, 0xdb, 0xfc, 0x9d, 0x9f, 0x4d, 0x29, 0xb9,
+    0x98, 0xc8, 0x2a, 0x50, 0xcd, 0xd5, 0xee, 0x7d, 0xb1, 0x85, 0x0d, 0xec,
+    0x19, 0x34, 0x87, 0xa6, 0x48, 0x09, 0xd5, 0xd4, 0x32, 0xdd, 0x01, 0x2d,
+    0xae, 0x63, 0x25, 0x62, 0xe9, 0x98, 0x2d, 0x24, 0xb9, 0xea, 0xcd, 0x5a,
+    0x74, 0x0b, 0x54, 0xf8, 0x42, 0xaf, 0x2f, 0xe6, 0xc8, 0x8e, 0xa5, 0x4a,
+    0x08, 0xf0, 0x2d, 0x2f, 0x14, 0x80, 0x63, 0xe7, 0x30, 0x2c, 0x0b, 0x5e,
+    0xff, 0xc5, 0x99, 0x29, 0x31, 0xa6, 0x5b, 0x72, 0x25, 0xb9, 0xcc, 0x3c,
+    0x27, 0x5d, 0x38, 0x9f, 0x68, 0xf2, 0xfd, 0x96, 0x4e, 0xb8, 0x6d, 0x45,
+    0x0e, 0xdc, 0xcb, 0xab, 0x25, 0xeb, 0x38, 0xef, 0xa4, 0x0a, 0xef, 0x78,
+    0x11, 0xe9, 0xd1, 0xd7, 0xf4, 0x14, 0x48, 0x8a, 0x28, 0x42, 0xa8, 0x2d,
+    0x18, 0x51, 0x90, 0x77, 0xb1, 0x54, 0xb1, 0xc8, 0x2d, 0x02, 0x30, 0x7e,
+    0x24, 0x45, 0x1b, 0x84, 0xd8, 0x09, 0x10, 0x29, 0x8f, 0xed, 0x18, 0x4f,
+    0x12, 0x8c, 0x9e, 0xaf, 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+    0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x14, 0x06, 0x08, 0x2a, 0x86, 0x48,
+    0x86, 0xf7, 0x0d, 0x03, 0x07, 0x04, 0x08, 0xbd, 0x73, 0xd9, 0x93, 0x86,
+    0xdf, 0xec, 0x93, 0xa0, 0x80, 0x04, 0x10, 0xab, 0x6b, 0xf8, 0x3d, 0x05,
+    0x26, 0x12, 0x98, 0xf6, 0x19, 0x15, 0x77, 0xb1, 0x8a, 0x02, 0xaf, 0x04,
+    0x08, 0xb7, 0x1e, 0x0e, 0x28, 0x8c, 0xd2, 0xee, 0xb8, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+unsigned int smime_skid_len = 403;
+
+
+static void tests(void)
+{
+    SecCertificateRef smime_cert = NULL;
+    CFDataRef message = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, test_eml, test_eml_len, kCFAllocatorNull);
+    CFDataRef signature = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, signed_bin, signed_bin_len, kCFAllocatorNull);
+
+    SecPolicyRef policy = NULL;
+    SecTrustRef trust = NULL;
+    SecTrustResultType result;
+
+    policy = SecPolicyCreateSMIME(kSecSignSMIMEUsage, CFSTR("Daly_c@apple.com"));
+    ok_status(SecCMSVerifySignedData(signature, message, policy, &trust, NULL, NULL, NULL), "validate message");
+
+    ok_status(SecTrustEvaluate(trust, &result), "evaluate trust");
+    ok(result == kSecTrustResultUnspecified, "private root");
+    smime_cert = SecTrustGetCertificateAtIndex(trust, 0);
+    CFRetain(smime_cert);
+    CFReleaseNull(trust);
+
+    CFReleaseNull(policy);
+    CFReleaseNull(message);
+    CFReleaseNull(signature);
+
+
+    SecKeyRef publicKey = NULL, privateKey = NULL;
+    const void *keygen_keys[] = { kSecAttrKeyType, kSecAttrKeySizeInBits };
+    const void *keygen_vals[] = { kSecAttrKeyTypeRSA, CFSTR("512") };
+    CFDictionaryRef parameters = CFDictionaryCreate(kCFAllocatorDefault,
+            keygen_keys, keygen_vals, array_size(keygen_vals),
+            &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks );
+
+    ok_status(SecKeyGeneratePair(parameters, &publicKey, &privateKey), "generate key pair");
+
+    CFMutableDictionaryRef subject_alt_names = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    CFDictionarySetValue(subject_alt_names, CFSTR("rfc822name"), CFSTR("xey@nl"));
+    int key_usage = kSecKeyUsageDigitalSignature | kSecKeyUsageKeyEncipherment;
+    CFNumberRef key_usage_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &key_usage);
+    const void *self_key[] = { kSecCertificateKeyUsage, kSecSubjectAltName };
+    const void *self_val[] = { key_usage_num, subject_alt_names };
+    CFDictionaryRef self_signed_parameters = CFDictionaryCreate(kCFAllocatorDefault,
+                                                                self_key, self_val, array_size(self_key), NULL, NULL);
+
+    const void * cn[] = { kSecOidCommonName, CFSTR("Root CA") };
+    CFArrayRef cn_dn = CFArrayCreate(kCFAllocatorDefault, cn, 2, NULL);
+    CFArrayRef rdns = CFArrayCreate(kCFAllocatorDefault, (const void **)&cn_dn, 1, NULL);
+    SecCertificateRef cert = SecGenerateSelfSignedCertificate(rdns,
+                         self_signed_parameters, publicKey, privateKey);
+
+    CFReleaseSafe(rdns);
+    CFReleaseSafe(self_signed_parameters);
+    SECOidTag algorithmTag;
+    int keySize;
+    SecCertificateRef recipients[] = { cert, NULL };
+    ok_status(SecSMIMEFindBulkAlgForRecipients(recipients, &algorithmTag, &keySize), "get cipher for 512 bit key");
+    is(algorithmTag, (SECOidTag)SEC_OID_DES_CBC, "weak asym, des is okay");
+    is(keySize, 64, "superfluous");
+    recipients[0] = smime_cert;
+    ok_status(SecSMIMEFindBulkAlgForRecipients(recipients, &algorithmTag, &keySize), "get cipher for 1024 bit key");
+    is(algorithmTag, (SECOidTag)SEC_OID_DES_EDE3_CBC, "okay asym, 3des for interop");
+    is(keySize, 192, "superfluous");
+
+    //SecCmsSignerInfoAddSMIMEEncKeyPrefs
+    SecCmsMessageRef cmsg = NULL;
+    SecCmsContentInfoRef cinfo;
+    SecCmsSignedDataRef sigd = NULL;
+    SecCmsSignerInfoRef signerinfo;
+    CFMutableDataRef signed_data = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    SecIdentityRef signer;
+
+    ok(signer = SecIdentityCreate(kCFAllocatorDefault, cert, privateKey), "identity");
+    ok(cmsg = SecCmsMessageCreate(), "create message");
+    ok(sigd = SecCmsSignedDataCreate(cmsg), "create signed message");
+    ok(cinfo = SecCmsMessageGetContentInfo(cmsg), "get content info");
+    ok_status(SecCmsContentInfoSetContentSignedData(cinfo, sigd), "signed message into message");
+    ok(cinfo = SecCmsSignedDataGetContentInfo(sigd), "reset content info");
+    ok_status(SecCmsContentInfoSetContentData(cinfo, NULL, false), "attached");
+    ok(signerinfo = SecCmsSignerInfoCreate(sigd, signer, SEC_OID_SHA1), "set up signer");
+    // ok_status(SecCmsSignerInfoIncludeCerts(signerinfo, SecCmsCMCertChain, certUsageAnyCA), out);
+    ok_status(SecCmsSignerInfoAddSigningTime(signerinfo, CFAbsoluteTimeGetCurrent()), "set current time");
+    ok_status(SecCmsSignerInfoAddSMIMEEncKeyPrefs(signerinfo, cert, NULL), "set signing cert as preferred encryption cert");
+    //SecCmsSignerInfoAddMSSMIMEEncKeyPrefs
+
+    ok_status(SecCmsMessageEncode(cmsg, NULL, signed_data), "encode signed message");
+    if (cmsg) SecCmsMessageDestroy(cmsg);
+
+    int data_file = open("/var/tmp/smime", O_CREAT|O_WRONLY|O_TRUNC, 0644);
+    write(data_file, CFDataGetBytePtr(signed_data), CFDataGetLength(signed_data));
+    close(data_file);
+
+    CFReleaseNull(smime_cert);
+
+    policy = SecPolicyCreateSMIME(kSecSignSMIMEUsage, CFSTR("cbaray@applex3.apple.com"));
+    CFDataRef sig = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
+                                                __9148843_bin, __9148843_bin_len, kCFAllocatorNull);
+    CFDataRef eml = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
+                                                __9148843_txt, __9148843_txt_len, kCFAllocatorNull);
+    ok_status(SecCMSVerifySignedData(sig, eml, policy, &trust, NULL, NULL, NULL),
+              "validate message, not signer");
+    // set date to Thu, 17 Mar 2011 00:59:48 +0000
+    ok_status(SecTrustEvaluate(trust, &result), "validate signer");
+    is_status(result, kSecTrustResultUnspecified, "valid");
+    CFReleaseNull(eml);
+    CFReleaseNull(sig);
+    CFReleaseNull(policy);
+
+    CFDataRef msg = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, __9639569_bin, __9639569_bin_len, kCFAllocatorNull);
+    CFMutableDataRef data = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    is_status(errSecDecode, SecCMSDecryptEnvelopedData(msg, data, NULL), "decrypt cms with subjkeyid; expect failure");
+    CFRelease(msg);
+
+    CFDataRef local_p12_data = CFDataCreate(kCFAllocatorDefault, local_p12, local_p12_len);
+    CFStringRef local_p12_password = CFStringCreateWithCString(NULL, "leaf", kCFStringEncodingUTF8);
+    CFDictionaryRef options = CFDictionaryCreate(NULL, (const void * *)&kSecImportExportPassphrase, (const void * *)&local_p12_password, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    CFRelease(local_p12_password);
+    CFArrayRef items = NULL;
+    ok_status(SecPKCS12Import(local_p12_data, options, &items), "get admin lab identity");
+    CFRelease(local_p12_data);
+    CFRelease(options);
+    CFDictionaryRef item_dict = CFArrayGetValueAtIndex(items, 0);
+    SecIdentityRef local_identity = (SecIdentityRef)CFDictionaryGetValue(item_dict, kSecImportItemIdentity);
+    CFDictionaryRef    dict = CFDictionaryCreate(NULL, &kSecValueRef, (const void **)&local_identity, 1, NULL, NULL);
+    ok_status(SecItemAdd(dict, NULL), "add p12 identy");
+
+    const uint8_t foo[] = "here's something";
+    CFDataRef sample = CFDataCreate(kCFAllocatorDefault, foo, strlen((char *)foo));
+
+#if 0
+    SecCertificateRef local_cert = NULL;
+    ok_status(SecIdentityCopyCertificate(local_identity, &local_cert), "get cert");
+    CFDataSetLength(data, 0);
+    ok_status(SecCMSCreateEnvelopedData(local_cert, NULL, sample, data), "envelope data (should use signer identifier)");
+    int data_file = open("/var/tmp/smime", O_CREAT|O_WRONLY|O_TRUNC, 0644);
+    write(data_file, CFDataGetBytePtr(data), CFDataGetLength(data));
+    close(data_file);
+#endif
+
+    msg = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, smime_skid, smime_skid_len, kCFAllocatorNull);
+    CFMutableDataRef dec = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    ok_status(SecCMSDecryptEnvelopedData(msg, dec, NULL), "decrypt cms with subjkeyid; expect success");
+    ok(CFEqual(sample, dec), "decoded properly");
+
+    ok_status(SecItemDelete(dict), "delete p12 identy");
+
+    CFRelease(msg);
+    CFRelease(dec);
+
+    CFRelease(sample);
+    CFRelease(items);
+    CFRelease(dict);
+
+    // parse signed-receipt
+    msg = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, signed_receipt_bin, signed_receipt_bin_len, kCFAllocatorNull);
+    policy = SecPolicyCreateBasicX509();
+    ok(errSecDecode == SecCMSVerifySignedData(msg, NULL, policy, &trust, NULL, NULL, NULL), "decode signed receipt w/ special oid");
+    CFReleaseNull(policy);
+    CFReleaseNull(msg);
+}
+
+int si_66_smime(int argc, char *const *argv)
+{
+       plan_tests(31);
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-66-smime/signed-receipt.h b/sec/Security/Regressions/secitem/si-66-smime/signed-receipt.h
new file mode 100644 (file)
index 0000000..1fffff9
--- /dev/null
@@ -0,0 +1,217 @@
+unsigned char signed_receipt_bin[] = {
+  0x30, 0x82, 0x09, 0xfb, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x07, 0x02, 0xa0, 0x82, 0x09, 0xec, 0x30, 0x82, 0x09, 0xe8, 0x02,
+  0x01, 0x03, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
+  0x1a, 0x05, 0x00, 0x30, 0x81, 0xc6, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x01, 0xa0, 0x81, 0xb6, 0x04, 0x81,
+  0xb3, 0x30, 0x81, 0xb0, 0x02, 0x01, 0x01, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x04, 0x1d, 0x00, 0x00, 0x00, 0x00,
+  0x10, 0x00, 0x00, 0x00, 0x67, 0x72, 0xa8, 0x9c, 0x02, 0xbc, 0x8c, 0x4c,
+  0x94, 0xd4, 0x9d, 0xd3, 0x8d, 0x37, 0x24, 0xf8, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x04, 0x81, 0x80, 0x75, 0x54, 0xef, 0x4f, 0xe5, 0xd3, 0xc7, 0x25,
+  0x5c, 0xb6, 0xd4, 0x8f, 0x55, 0x21, 0xb6, 0x0d, 0xcd, 0x3a, 0x68, 0xab,
+  0x49, 0x88, 0x1a, 0xf2, 0x7e, 0xe5, 0xf4, 0x33, 0x47, 0x8d, 0x0d, 0x54,
+  0x97, 0xdf, 0xa7, 0x2b, 0x71, 0x7c, 0x4c, 0x9d, 0x0e, 0xd9, 0xff, 0x6c,
+  0x5d, 0x93, 0x58, 0x31, 0xa1, 0x66, 0x85, 0xcb, 0x99, 0xfb, 0x05, 0x0b,
+  0x41, 0x2a, 0xca, 0x0e, 0xfd, 0x70, 0xe4, 0x64, 0xcd, 0xdf, 0x1b, 0x81,
+  0xc1, 0x20, 0x9d, 0xaa, 0xee, 0x5d, 0xdf, 0xdd, 0xb2, 0x8f, 0xa2, 0xad,
+  0xd3, 0xbf, 0x1e, 0x7e, 0xe4, 0xe4, 0x4d, 0x79, 0x7e, 0xe5, 0xa1, 0x63,
+  0x07, 0x7f, 0x9d, 0x5f, 0xc4, 0x21, 0xc2, 0xab, 0x7f, 0x39, 0xf4, 0xb4,
+  0xfe, 0xd7, 0xc0, 0xf6, 0xff, 0x42, 0x16, 0x53, 0x27, 0x9a, 0xb1, 0xf0,
+  0x7b, 0xd5, 0x2e, 0x1c, 0x97, 0x83, 0xf0, 0xa6, 0x31, 0x14, 0x00, 0xfa,
+  0xa0, 0x82, 0x07, 0x6f, 0x30, 0x82, 0x03, 0xb0, 0x30, 0x82, 0x02, 0x98,
+  0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0c, 0x20, 0x48, 0x00, 0x00, 0x01,
+  0x31, 0x18, 0x2d, 0x8a, 0x67, 0x00, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x59,
+  0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1d, 0x47,
+  0x61, 0x6d, 0x61, 0x6e, 0x69, 0x61, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
+  0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
+  0x72, 0x69, 0x74, 0x79, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04,
+  0x0a, 0x13, 0x07, 0x47, 0x61, 0x6d, 0x61, 0x6e, 0x69, 0x61, 0x31, 0x10,
+  0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x07, 0x47, 0x61, 0x6d,
+  0x61, 0x6e, 0x69, 0x61, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
+  0x06, 0x13, 0x02, 0x54, 0x57, 0x30, 0x22, 0x18, 0x0f, 0x32, 0x30, 0x31,
+  0x31, 0x30, 0x37, 0x31, 0x30, 0x31, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a,
+  0x18, 0x0f, 0x32, 0x30, 0x33, 0x31, 0x30, 0x37, 0x31, 0x31, 0x31, 0x36,
+  0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x59, 0x31, 0x12, 0x30, 0x10, 0x06,
+  0x03, 0x55, 0x04, 0x03, 0x13, 0x09, 0x6a, 0x61, 0x63, 0x6b, 0x79, 0x77,
+  0x61, 0x6e, 0x67, 0x31, 0x24, 0x30, 0x22, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x15, 0x6a, 0x61, 0x63, 0x6b,
+  0x79, 0x77, 0x61, 0x6e, 0x67, 0x40, 0x67, 0x61, 0x6d, 0x61, 0x6e, 0x69,
+  0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55,
+  0x04, 0x0a, 0x13, 0x07, 0x47, 0x61, 0x6d, 0x61, 0x6e, 0x69, 0x61, 0x31,
+  0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x54, 0x57,
+  0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81,
+  0x89, 0x02, 0x81, 0x81, 0x00, 0x8c, 0x66, 0xd2, 0x05, 0xf9, 0xcd, 0x46,
+  0x56, 0xd3, 0xd9, 0x9e, 0xf8, 0xee, 0x81, 0x1f, 0xe4, 0xbb, 0x87, 0xdc,
+  0x88, 0x6d, 0x88, 0x29, 0x4f, 0xb8, 0x5c, 0x46, 0x58, 0x46, 0x09, 0x02,
+  0x7d, 0xed, 0x46, 0xdc, 0x33, 0xc7, 0xa0, 0x82, 0xcb, 0x1a, 0x33, 0x7a,
+  0x00, 0x4e, 0xf7, 0x89, 0xff, 0x85, 0x77, 0x0c, 0x97, 0x73, 0xe2, 0x8b,
+  0xe0, 0xa7, 0x2a, 0xca, 0x48, 0x48, 0x35, 0x05, 0xf6, 0xb5, 0x70, 0x9d,
+  0xec, 0xfa, 0xb6, 0x38, 0xe6, 0x77, 0x5d, 0xff, 0x61, 0x8d, 0x7a, 0x81,
+  0xa7, 0xf5, 0x6c, 0x8d, 0xd9, 0x7a, 0x0e, 0xf4, 0x4c, 0xe1, 0x2c, 0x8b,
+  0x7e, 0x66, 0xfd, 0x96, 0x80, 0x77, 0x6f, 0x0f, 0xac, 0x03, 0x2b, 0x78,
+  0xcf, 0xb0, 0x1e, 0x90, 0x1d, 0x76, 0xa2, 0xf9, 0x41, 0x42, 0x1f, 0x0b,
+  0xae, 0x62, 0x87, 0xf3, 0x5c, 0x3d, 0x29, 0xe6, 0x5f, 0x61, 0x5c, 0x79,
+  0x5d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xf7, 0x30, 0x81, 0xf4,
+  0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x10,
+  0xd0, 0x48, 0x86, 0x45, 0x40, 0xf3, 0x99, 0x6c, 0x70, 0x31, 0xec, 0x69,
+  0xe8, 0x5e, 0xb5, 0x4d, 0x8c, 0x6d, 0x18, 0x30, 0x1f, 0x06, 0x03, 0x55,
+  0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x6f, 0xc2, 0x94, 0x33,
+  0xd8, 0xf4, 0xa8, 0xc3, 0x90, 0xcc, 0x7d, 0xde, 0x6f, 0x5a, 0x57, 0xe6,
+  0xa1, 0x9d, 0xa9, 0x43, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04,
+  0x36, 0x30, 0x34, 0x30, 0x32, 0xa0, 0x30, 0xa0, 0x2e, 0x86, 0x2c, 0x68,
+  0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x65, 0x67, 0x61, 0x6d, 0x61, 0x68,
+  0x6f, 0x6d, 0x65, 0x2e, 0x67, 0x61, 0x6d, 0x61, 0x6e, 0x69, 0x61, 0x2e,
+  0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x41, 0x32, 0x2f, 0x72, 0x65, 0x76, 0x6f,
+  0x6b, 0x65, 0x64, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x30, 0x06, 0x03, 0x55,
+  0x1d, 0x11, 0x04, 0x29, 0x30, 0x27, 0xa0, 0x25, 0x06, 0x0a, 0x2b, 0x06,
+  0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x03, 0xa0, 0x17, 0x0c, 0x15,
+  0x6a, 0x61, 0x63, 0x6b, 0x79, 0x77, 0x61, 0x6e, 0x67, 0x40, 0x67, 0x61,
+  0x6d, 0x61, 0x6e, 0x69, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x29, 0x06,
+  0x03, 0x55, 0x1d, 0x25, 0x04, 0x22, 0x30, 0x20, 0x06, 0x08, 0x2b, 0x06,
+  0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+  0x05, 0x07, 0x03, 0x04, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82,
+  0x37, 0x14, 0x02, 0x02, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04,
+  0x04, 0x03, 0x02, 0x06, 0xc0, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13,
+  0x04, 0x02, 0x30, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00,
+  0x9f, 0xef, 0x02, 0x6d, 0x85, 0xa1, 0x46, 0xac, 0xeb, 0xa5, 0x98, 0x59,
+  0xa8, 0x17, 0xaf, 0x46, 0x77, 0xc7, 0x8b, 0xad, 0x10, 0x2f, 0xef, 0x2d,
+  0xe4, 0x67, 0xb3, 0xe6, 0x71, 0x72, 0x22, 0x0c, 0x4a, 0xb9, 0x50, 0xd4,
+  0x12, 0x85, 0x3c, 0xd3, 0x5a, 0xe6, 0xad, 0x58, 0x50, 0xf7, 0x5c, 0x83,
+  0xa5, 0x03, 0x45, 0xad, 0xe3, 0xf0, 0x00, 0x2e, 0x99, 0x5b, 0xcf, 0x6c,
+  0xd9, 0xa0, 0x6d, 0x8a, 0x22, 0x07, 0x5c, 0xca, 0x05, 0x21, 0xb3, 0xb8,
+  0xcf, 0x6d, 0xdb, 0x82, 0x1f, 0x68, 0x40, 0x2b, 0xb7, 0xa5, 0x5f, 0x99,
+  0xa6, 0x84, 0xff, 0xb4, 0x74, 0xfc, 0x7c, 0x43, 0x0f, 0x11, 0xfd, 0xa8,
+  0x0d, 0x8a, 0xfa, 0x99, 0xd1, 0xee, 0x30, 0x10, 0xfe, 0x55, 0xfd, 0xc2,
+  0xaf, 0xa9, 0x7c, 0x3b, 0xc3, 0x16, 0x60, 0x03, 0xb5, 0x0e, 0x82, 0xe9,
+  0xf8, 0x2f, 0x08, 0xce, 0xc7, 0x6c, 0xce, 0x17, 0x75, 0xf8, 0x2e, 0xc7,
+  0xc5, 0x76, 0x07, 0xdf, 0xf7, 0x91, 0x1a, 0xf6, 0x7f, 0x0f, 0x1d, 0x14,
+  0x25, 0x11, 0x0c, 0xa0, 0x06, 0x5e, 0x2a, 0x77, 0x5d, 0x8f, 0xb1, 0xd8,
+  0xef, 0x91, 0x26, 0xa1, 0x36, 0x18, 0x3c, 0x80, 0x40, 0xe0, 0xc9, 0x0d,
+  0x46, 0x59, 0xba, 0x0f, 0x5e, 0x43, 0xe1, 0xca, 0x64, 0x2e, 0x16, 0x69,
+  0xa3, 0x4b, 0x19, 0x1d, 0x9a, 0xe7, 0x87, 0xc7, 0x3c, 0x26, 0x53, 0x18,
+  0xce, 0xbb, 0x85, 0xa7, 0x95, 0x29, 0xd3, 0x48, 0xf9, 0x8c, 0xa1, 0x9d,
+  0x7e, 0x4a, 0x48, 0xa5, 0x0e, 0x8f, 0x48, 0xd5, 0x3e, 0x0f, 0x4f, 0x9d,
+  0x29, 0xfa, 0xe5, 0xf6, 0x1c, 0xe3, 0x2e, 0xc0, 0x23, 0x19, 0x5c, 0xa3,
+  0x46, 0x76, 0xd0, 0x15, 0xc3, 0xcb, 0xe7, 0x03, 0xd3, 0x7b, 0x72, 0xe1,
+  0xe0, 0x88, 0xcd, 0x6e, 0xac, 0xaf, 0xfb, 0x4f, 0xc5, 0x56, 0x26, 0xcd,
+  0xa5, 0x83, 0xd6, 0x8a, 0x30, 0x82, 0x03, 0xb7, 0x30, 0x82, 0x02, 0x9f,
+  0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
+  0x59, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1d,
+  0x47, 0x61, 0x6d, 0x61, 0x6e, 0x69, 0x61, 0x20, 0x43, 0x65, 0x72, 0x74,
+  0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68,
+  0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55,
+  0x04, 0x0a, 0x13, 0x07, 0x47, 0x61, 0x6d, 0x61, 0x6e, 0x69, 0x61, 0x31,
+  0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x07, 0x47, 0x61,
+  0x6d, 0x61, 0x6e, 0x69, 0x61, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+  0x04, 0x06, 0x13, 0x02, 0x54, 0x57, 0x30, 0x2a, 0x18, 0x13, 0x32, 0x30,
+  0x30, 0x34, 0x30, 0x38, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+  0x2d, 0x30, 0x38, 0x30, 0x30, 0x18, 0x13, 0x32, 0x30, 0x32, 0x34, 0x30,
+  0x37, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x2d, 0x30, 0x38,
+  0x30, 0x30, 0x30, 0x59, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04,
+  0x03, 0x13, 0x1d, 0x47, 0x61, 0x6d, 0x61, 0x6e, 0x69, 0x61, 0x20, 0x43,
+  0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41,
+  0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x10, 0x30, 0x0e,
+  0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x07, 0x47, 0x61, 0x6d, 0x61, 0x6e,
+  0x69, 0x61, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
+  0x07, 0x47, 0x61, 0x6d, 0x61, 0x6e, 0x69, 0x61, 0x31, 0x0b, 0x30, 0x09,
+  0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x54, 0x57, 0x30, 0x82, 0x01,
+  0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01,
+  0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xeb, 0xa6, 0x1a, 0x6c, 0x85, 0xa7,
+  0x38, 0x2d, 0x22, 0x6f, 0xbf, 0x7e, 0x1d, 0x6e, 0xbf, 0x40, 0x43, 0xf4,
+  0xed, 0xb4, 0xba, 0xb9, 0x31, 0x44, 0xe3, 0x1a, 0xad, 0x5e, 0x31, 0x2f,
+  0xac, 0x3f, 0x1c, 0x3a, 0xd5, 0xc7, 0x52, 0xd7, 0xd1, 0x88, 0xea, 0x9a,
+  0x92, 0x13, 0xe4, 0x6e, 0x77, 0xbb, 0xde, 0xab, 0xb8, 0x86, 0x59, 0xf7,
+  0xaa, 0xae, 0xe5, 0x8c, 0xe7, 0xf0, 0x64, 0x63, 0x90, 0xe8, 0x98, 0x33,
+  0x97, 0xce, 0xd9, 0xe9, 0x02, 0x46, 0xf8, 0x8e, 0x61, 0x69, 0xf1, 0x52,
+  0x99, 0x93, 0xe6, 0xbd, 0x08, 0xe0, 0xeb, 0xf1, 0xeb, 0x9a, 0x17, 0x72,
+  0xcc, 0xfc, 0xd1, 0xbc, 0xfb, 0x6a, 0x8d, 0x97, 0x1c, 0x66, 0xa3, 0x96,
+  0x43, 0x7a, 0x64, 0x7b, 0xd7, 0xb6, 0xa8, 0xaf, 0xc8, 0x3d, 0x91, 0x41,
+  0x87, 0xb2, 0xca, 0x83, 0xce, 0x4f, 0x6c, 0xb3, 0xdd, 0x54, 0x62, 0xff,
+  0x66, 0xa4, 0xa8, 0xea, 0x61, 0x4e, 0x33, 0xe6, 0x31, 0xc1, 0x12, 0x6a,
+  0x38, 0x7a, 0xc6, 0x5a, 0x06, 0x70, 0x04, 0x1f, 0x6c, 0x52, 0x4e, 0x98,
+  0xe8, 0x12, 0xc9, 0x53, 0xae, 0xe9, 0xf5, 0xe5, 0x94, 0x98, 0x4c, 0x0e,
+  0x5c, 0xa6, 0xf3, 0xb5, 0x69, 0x7f, 0xc6, 0xe5, 0x30, 0xbf, 0x44, 0x18,
+  0x94, 0x56, 0x3c, 0x2c, 0x07, 0xc1, 0x79, 0xb0, 0xa3, 0xcd, 0x32, 0x65,
+  0x27, 0x69, 0xf6, 0x06, 0xc4, 0xbd, 0x5f, 0x08, 0xb5, 0x25, 0x41, 0xb5,
+  0x99, 0x13, 0x21, 0xb4, 0x66, 0x6c, 0xe7, 0xf1, 0xe0, 0xf9, 0x59, 0x8e,
+  0xe6, 0xa4, 0x0f, 0xf5, 0x05, 0x5b, 0x53, 0x4f, 0xd4, 0xaf, 0xbe, 0x9c,
+  0x9c, 0x9b, 0xdd, 0x8e, 0x29, 0xcc, 0x89, 0x15, 0x00, 0x5a, 0x99, 0x19,
+  0x39, 0xea, 0x40, 0x4d, 0xea, 0x27, 0x61, 0x31, 0x60, 0xb7, 0x60, 0x4b,
+  0x96, 0x51, 0x55, 0x25, 0xe0, 0x0b, 0xbd, 0x24, 0xaa, 0x7f, 0x02, 0x03,
+  0x01, 0x00, 0x01, 0xa3, 0x7e, 0x30, 0x7c, 0x30, 0x1d, 0x06, 0x03, 0x55,
+  0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x6f, 0xc2, 0x94, 0x33, 0xd8, 0xf4,
+  0xa8, 0xc3, 0x90, 0xcc, 0x7d, 0xde, 0x6f, 0x5a, 0x57, 0xe6, 0xa1, 0x9d,
+  0xa9, 0x43, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x08, 0x30,
+  0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x0b, 0x06, 0x03, 0x55,
+  0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0xe6, 0x30, 0x3d, 0x06, 0x03,
+  0x55, 0x1d, 0x25, 0x04, 0x36, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01,
+  0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+  0x07, 0x03, 0x02, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03,
+  0x04, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03, 0x06,
+  0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x02, 0x30,
+  0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
+  0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x5b, 0x0b, 0xa2, 0x48, 0x62,
+  0x5d, 0xd5, 0x54, 0x88, 0x2f, 0x21, 0x6a, 0x29, 0xdb, 0x0b, 0x4a, 0x18,
+  0x67, 0xab, 0xe5, 0x4f, 0xa3, 0x81, 0x81, 0x40, 0x99, 0x95, 0x36, 0xe8,
+  0x2f, 0xa2, 0x88, 0x6d, 0x4c, 0x45, 0x09, 0xeb, 0x0d, 0x24, 0xc3, 0x91,
+  0xfa, 0xda, 0xe0, 0xb5, 0xbe, 0x57, 0x15, 0x06, 0x9b, 0x26, 0x98, 0x27,
+  0x29, 0x6e, 0xd7, 0x44, 0x38, 0xd4, 0xa7, 0x6b, 0x65, 0x0b, 0xa2, 0x66,
+  0x39, 0x16, 0x76, 0x78, 0xab, 0x50, 0xc0, 0xf3, 0xba, 0x23, 0xc0, 0x8a,
+  0x3f, 0xee, 0x35, 0xc4, 0xf6, 0x54, 0x58, 0x9d, 0x37, 0x1c, 0x44, 0x0c,
+  0x6c, 0x01, 0x8d, 0xf2, 0x10, 0xe2, 0xe6, 0x33, 0x6d, 0xcb, 0x7f, 0x36,
+  0x6e, 0x8a, 0x41, 0x3c, 0xc3, 0x1c, 0x1d, 0x87, 0xb5, 0xa6, 0xf6, 0x69,
+  0x4c, 0x84, 0x77, 0xd2, 0xb2, 0x77, 0xc9, 0x5f, 0xd6, 0x41, 0x7e, 0xb4,
+  0x27, 0x16, 0x55, 0x9f, 0xfe, 0xbd, 0x73, 0x74, 0xfc, 0xd3, 0xb9, 0x28,
+  0x06, 0x6e, 0x2a, 0x14, 0x73, 0x13, 0x22, 0xd2, 0xd2, 0xa6, 0x30, 0xf7,
+  0xca, 0x08, 0x53, 0xe6, 0x31, 0x0d, 0x2d, 0x18, 0x64, 0x80, 0xa3, 0x83,
+  0x27, 0xca, 0x5a, 0xd0, 0x14, 0xbd, 0xac, 0x44, 0xbc, 0x28, 0x6d, 0x06,
+  0xf0, 0x56, 0xbf, 0x7c, 0xae, 0x8f, 0xb3, 0x28, 0x0d, 0xc8, 0xbf, 0xf8,
+  0x72, 0xdf, 0xe6, 0xa2, 0x0a, 0x39, 0xa6, 0x2c, 0xe6, 0xae, 0x2b, 0x28,
+  0x7d, 0x29, 0x9f, 0x95, 0x1d, 0xf3, 0xce, 0x1f, 0xaa, 0x99, 0x74, 0xaf,
+  0x52, 0xb8, 0x1b, 0x9e, 0x54, 0xab, 0xde, 0xed, 0x90, 0xb7, 0x23, 0xcf,
+  0x9f, 0x06, 0xab, 0xa0, 0x70, 0x05, 0x12, 0x57, 0xde, 0x2a, 0x41, 0x2f,
+  0x3b, 0xa5, 0x6f, 0x13, 0x6a, 0xb4, 0xa8, 0xad, 0x4f, 0x79, 0x87, 0x8f,
+  0xd9, 0x9d, 0xfe, 0x54, 0x32, 0xc5, 0x04, 0xdb, 0x23, 0xd6, 0xf8, 0x31,
+  0x82, 0x01, 0x98, 0x30, 0x82, 0x01, 0x94, 0x02, 0x01, 0x01, 0x30, 0x69,
+  0x30, 0x59, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+  0x1d, 0x47, 0x61, 0x6d, 0x61, 0x6e, 0x69, 0x61, 0x20, 0x43, 0x65, 0x72,
+  0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74,
+  0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03,
+  0x55, 0x04, 0x0a, 0x13, 0x07, 0x47, 0x61, 0x6d, 0x61, 0x6e, 0x69, 0x61,
+  0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x07, 0x47,
+  0x61, 0x6d, 0x61, 0x6e, 0x69, 0x61, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+  0x55, 0x04, 0x06, 0x13, 0x02, 0x54, 0x57, 0x02, 0x0c, 0x20, 0x48, 0x00,
+  0x00, 0x01, 0x31, 0x18, 0x2d, 0x8a, 0x67, 0x00, 0x00, 0x30, 0x09, 0x06,
+  0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0xa0, 0x81, 0x86, 0x30,
+  0x1a, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x03,
+  0x31, 0x0d, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09,
+  0x10, 0x01, 0x01, 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x01, 0x09, 0x05, 0x31, 0x0f, 0x17, 0x0d, 0x31, 0x31, 0x31, 0x31,
+  0x32, 0x31, 0x30, 0x39, 0x35, 0x36, 0x35, 0x39, 0x5a, 0x30, 0x23, 0x06,
+  0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04, 0x31, 0x16,
+  0x04, 0x14, 0xe1, 0xe1, 0x34, 0xea, 0x7e, 0x58, 0xaa, 0x15, 0xd8, 0xc1,
+  0x0a, 0x1c, 0x13, 0x99, 0x64, 0xac, 0x13, 0x13, 0x7b, 0xd6, 0x30, 0x25,
+  0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02,
+  0x05, 0x31, 0x16, 0x04, 0x14, 0xd8, 0x83, 0xd3, 0x75, 0x21, 0x07, 0xd2,
+  0x93, 0x36, 0xb9, 0xc2, 0x96, 0xca, 0xaf, 0x22, 0xc9, 0xe8, 0xe3, 0xa1,
+  0xe4, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x01, 0x01, 0x05, 0x00, 0x04, 0x81, 0x80, 0x73, 0xac, 0x88, 0x1f, 0x13,
+  0xc4, 0x89, 0x18, 0xa3, 0x17, 0x1b, 0x01, 0x7e, 0x01, 0x7a, 0x96, 0x1d,
+  0x83, 0x20, 0x75, 0xae, 0x3e, 0x32, 0x5a, 0x2e, 0x53, 0x11, 0xee, 0x4f,
+  0x31, 0x20, 0x4c, 0x9e, 0x9a, 0x41, 0x4a, 0x80, 0x50, 0x4c, 0x67, 0x26,
+  0x49, 0xd9, 0x5c, 0xcb, 0xba, 0x38, 0x27, 0x8e, 0x5b, 0x21, 0x08, 0x35,
+  0x65, 0x64, 0xb8, 0xa9, 0x1a, 0x33, 0x3c, 0xe3, 0x1b, 0x6a, 0x70, 0x32,
+  0x13, 0xe0, 0xa6, 0xbb, 0x8d, 0x66, 0x2d, 0xd4, 0xff, 0x36, 0x34, 0xf6,
+  0x89, 0x1b, 0x1f, 0x39, 0x50, 0x86, 0x31, 0x51, 0xc9, 0x38, 0x4a, 0x7c,
+  0x77, 0x13, 0xe9, 0xfc, 0x87, 0xba, 0xe2, 0x98, 0x06, 0x12, 0xec, 0xd9,
+  0x9c, 0x73, 0x2f, 0x1e, 0xd0, 0x40, 0x41, 0xa2, 0x51, 0xec, 0xb8, 0x45,
+  0xa5, 0x97, 0x4a, 0x55, 0x82, 0x52, 0x58, 0x13, 0x12, 0xa3, 0xf6, 0x6f,
+  0xa8, 0xee, 0x6d
+};
+unsigned int signed_receipt_bin_len = 2559;
diff --git a/sec/Security/Regressions/secitem/si-67-sectrust-blacklist.c b/sec/Security/Regressions/secitem/si-67-sectrust-blacklist.c
new file mode 100644 (file)
index 0000000..2fff270
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ *  si-67-sectrust-blacklist.c
+ *  regressions
+ *
+ *  Created by Conrad Sauerwald on 3/24/11.
+ *  Copyright 2011 Apple Inc. All rights reserved.
+ *
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecInternal.h>
+#include <Security/SecPolicyPriv.h>
+#include <Security/SecTrust.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "si-67-sectrust-blacklist/Global Trustee.cer.h"
+#include "si-67-sectrust-blacklist/login.yahoo.com.1.cer.h"
+#include "si-67-sectrust-blacklist/UTN-USERFirst-Hardware.cer.h"
+#include "si-67-sectrust-blacklist/login.yahoo.com.2.cer.h"
+#include "si-67-sectrust-blacklist/addons.mozilla.org.cer.h"
+#include "si-67-sectrust-blacklist/login.yahoo.com.cer.h"
+#include "si-67-sectrust-blacklist/login.live.com.cer.h"
+#include "si-67-sectrust-blacklist/mail.google.com.cer.h"
+#include "si-67-sectrust-blacklist/login.skype.com.cer.h"
+#include "si-67-sectrust-blacklist/www.google.com.cer.h"
+
+#include "Security_regressions.h"
+
+static void validate_one_cert(uint8_t *data, size_t len, int chain_length, SecTrustResultType trust_result)
+{
+    SecTrustRef trust;
+       SecCertificateRef cert;
+    SecPolicyRef policy = SecPolicyCreateSSL(false, NULL);
+    CFArrayRef certs;
+
+       isnt(cert = SecCertificateCreateWithBytes(NULL, data, len),
+               NULL, "create cert");
+    certs = CFArrayCreate(NULL, (const void **)&cert, 1, NULL);
+    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
+        "create trust with single cert");
+       //CFDateRef date = CFDateCreate(NULL, 1301008576);
+    //ok_status(SecTrustSetVerifyDate(trust, date), "set date");
+    //CFRelease(date);
+
+       SecTrustResultType trustResult;
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
+       is(SecTrustGetCertificateCount(trust), chain_length, "cert count");
+    is_status(trustResult, trust_result, "correct trustResult");
+    CFRelease(trust);
+    CFRelease(policy);
+    CFRelease(certs);
+    CFRelease(cert);
+}
+
+static void tests(void)
+{
+    validate_one_cert(Global_Trustee_cer, sizeof(Global_Trustee_cer), 3, kSecTrustResultFatalTrustFailure);
+    validate_one_cert(login_yahoo_com_1_cer, sizeof(login_yahoo_com_1_cer), 3, kSecTrustResultFatalTrustFailure);
+    /* this is the root, which isn't ok for ssl and fails here, but at the
+       same time it proves that kSecTrustResultFatalTrustFailure isn't
+       returned for policy failures that aren't blacklisting */
+    validate_one_cert(login_yahoo_com_2_cer, sizeof(login_yahoo_com_2_cer), 3, kSecTrustResultFatalTrustFailure);
+    validate_one_cert(addons_mozilla_org_cer, sizeof(addons_mozilla_org_cer), 3, kSecTrustResultFatalTrustFailure);
+    validate_one_cert(login_yahoo_com_cer, sizeof(login_yahoo_com_cer), 3, kSecTrustResultFatalTrustFailure);
+    validate_one_cert(login_live_com_cer, sizeof(login_live_com_cer), 3, kSecTrustResultFatalTrustFailure);
+    validate_one_cert(mail_google_com_cer, sizeof(mail_google_com_cer), 3, kSecTrustResultFatalTrustFailure);
+    validate_one_cert(login_skype_com_cer, sizeof(login_skype_com_cer), 3, kSecTrustResultFatalTrustFailure);
+    validate_one_cert(www_google_com_cer, sizeof(www_google_com_cer), 3, kSecTrustResultFatalTrustFailure);
+}
+
+int si_67_sectrust_blacklist(int argc, char *const *argv)
+{
+       plan_tests(45);
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-67-sectrust-blacklist/Global Trustee.cer.h b/sec/Security/Regressions/secitem/si-67-sectrust-blacklist/Global Trustee.cer.h
new file mode 100644 (file)
index 0000000..4253e07
--- /dev/null
@@ -0,0 +1,150 @@
+unsigned char Global_Trustee_cer[] = {
+  0x30, 0x82, 0x06, 0xdd, 0x30, 0x82, 0x05, 0xc5, 0xa0, 0x03, 0x02, 0x01,
+  0x02, 0x02, 0x11, 0x00, 0xd8, 0xf3, 0x5f, 0x4e, 0xb7, 0x87, 0x2b, 0x2d,
+  0xab, 0x06, 0x92, 0xe3, 0x15, 0x38, 0x2f, 0xb0, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
+  0x81, 0x97, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+  0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08,
+  0x13, 0x02, 0x55, 0x54, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04,
+  0x07, 0x13, 0x0e, 0x53, 0x61, 0x6c, 0x74, 0x20, 0x4c, 0x61, 0x6b, 0x65,
+  0x20, 0x43, 0x69, 0x74, 0x79, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55,
+  0x04, 0x0a, 0x13, 0x15, 0x54, 0x68, 0x65, 0x20, 0x55, 0x53, 0x45, 0x52,
+  0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72,
+  0x6b, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x18,
+  0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x75,
+  0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
+  0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x55,
+  0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72, 0x73, 0x74,
+  0x2d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x30, 0x1e, 0x17,
+  0x0d, 0x31, 0x31, 0x30, 0x33, 0x31, 0x35, 0x30, 0x30, 0x30, 0x30, 0x30,
+  0x30, 0x5a, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x33, 0x31, 0x34, 0x32, 0x33,
+  0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xe3, 0x31, 0x0b, 0x30, 0x09,
+  0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0e, 0x30,
+  0x0c, 0x06, 0x03, 0x55, 0x04, 0x11, 0x13, 0x05, 0x33, 0x38, 0x34, 0x37,
+  0x37, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07,
+  0x46, 0x6c, 0x6f, 0x72, 0x69, 0x64, 0x61, 0x31, 0x0e, 0x30, 0x0c, 0x06,
+  0x03, 0x55, 0x04, 0x07, 0x13, 0x05, 0x54, 0x61, 0x6d, 0x70, 0x61, 0x31,
+  0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x09, 0x13, 0x0e, 0x53, 0x65,
+  0x61, 0x20, 0x56, 0x69, 0x6c, 0x6c, 0x61, 0x67, 0x65, 0x20, 0x31, 0x30,
+  0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x47,
+  0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65,
+  0x65, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0e,
+  0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74,
+  0x65, 0x65, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
+  0x1f, 0x48, 0x6f, 0x73, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x47,
+  0x54, 0x49, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x43, 0x6f, 0x72,
+  0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x14, 0x30, 0x12,
+  0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0b, 0x50, 0x6c, 0x61, 0x74, 0x69,
+  0x6e, 0x75, 0x6d, 0x53, 0x53, 0x4c, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03,
+  0x55, 0x04, 0x03, 0x13, 0x0e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20,
+  0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x65, 0x30, 0x82, 0x02, 0x22, 0x30,
+  0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
+  0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02,
+  0x82, 0x02, 0x01, 0x00, 0xd9, 0x74, 0xf2, 0xaa, 0x41, 0x1d, 0xdf, 0xf5,
+  0xc2, 0x16, 0x43, 0x49, 0x5c, 0x29, 0xbf, 0xb6, 0x89, 0x74, 0x29, 0xbc,
+  0x9c, 0x8d, 0x0c, 0x46, 0x4f, 0x59, 0x7e, 0xb2, 0x41, 0x17, 0x66, 0x34,
+  0x0c, 0x65, 0x89, 0xe1, 0x6c, 0x25, 0xe3, 0x86, 0x0a, 0x9e, 0x22, 0x45,
+  0x22, 0x8c, 0xdd, 0x9d, 0xe6, 0xa3, 0x95, 0xde, 0xdc, 0x88, 0x02, 0x55,
+  0x5c, 0xe3, 0x5b, 0x91, 0x75, 0xeb, 0x26, 0x69, 0x63, 0xb9, 0x2e, 0xc6,
+  0xca, 0x2e, 0x27, 0xdf, 0x88, 0xba, 0x02, 0x20, 0x6e, 0xfe, 0xb9, 0x0b,
+  0x29, 0xd7, 0xa7, 0xd6, 0xd7, 0x48, 0x1a, 0x1c, 0xce, 0xdd, 0x1f, 0xa9,
+  0x27, 0x0e, 0x62, 0x4f, 0xa1, 0x96, 0x1e, 0xdd, 0x54, 0x3a, 0x34, 0x63,
+  0x4a, 0x76, 0xf5, 0x77, 0x7d, 0x59, 0x67, 0xd8, 0x10, 0xd4, 0xb5, 0x0f,
+  0x3a, 0x43, 0x22, 0x98, 0xdb, 0xf4, 0x09, 0xc4, 0x0a, 0x70, 0xce, 0xdd,
+  0x90, 0xd4, 0x2f, 0xef, 0x74, 0x13, 0xc3, 0xcd, 0xc2, 0x89, 0x39, 0x62,
+  0x15, 0x9d, 0xe6, 0x74, 0xa8, 0xe8, 0x9b, 0xf0, 0x63, 0x6e, 0x9c, 0x89,
+  0xb6, 0x0e, 0xad, 0x9b, 0xf7, 0xcc, 0x82, 0xe8, 0xe8, 0x2d, 0xb8, 0x0b,
+  0xda, 0x22, 0xec, 0x49, 0x85, 0x07, 0x88, 0x99, 0x98, 0x3f, 0xf4, 0x74,
+  0xa9, 0x09, 0xf7, 0x81, 0x7c, 0x97, 0x0b, 0x59, 0x99, 0x18, 0x72, 0x8b,
+  0xdb, 0x94, 0x82, 0x2b, 0xa7, 0xe8, 0xaa, 0x6b, 0x97, 0xbf, 0x88, 0x7e,
+  0x75, 0xb0, 0x8b, 0x45, 0x45, 0x0c, 0xc7, 0xa8, 0x09, 0xea, 0x1b, 0x41,
+  0x58, 0x30, 0x3b, 0x5f, 0x78, 0x65, 0x15, 0x34, 0xd2, 0xe4, 0x3c, 0x34,
+  0x0d, 0x1d, 0xd8, 0x64, 0x3c, 0x8a, 0xa5, 0x56, 0x49, 0x99, 0x28, 0x2d,
+  0x4b, 0xf2, 0xcf, 0xcd, 0xd9, 0x6e, 0x49, 0x64, 0x9b, 0xa9, 0x79, 0x90,
+  0x77, 0x55, 0xa9, 0x08, 0x1b, 0xad, 0x1a, 0x74, 0x9e, 0xe0, 0x03, 0x93,
+  0x0a, 0x09, 0xb7, 0xad, 0xa7, 0xb4, 0x5c, 0xef, 0x83, 0x6c, 0xb7, 0x9a,
+  0xb4, 0xc6, 0x68, 0x40, 0x80, 0x1d, 0x42, 0xd1, 0x6e, 0x79, 0x9b, 0xa9,
+  0x19, 0x21, 0x9a, 0x9c, 0xf9, 0x86, 0x2d, 0x00, 0xd1, 0x34, 0xfe, 0xe0,
+  0xb6, 0xf9, 0x55, 0xb6, 0xf5, 0x26, 0xc5, 0x95, 0x16, 0xa5, 0x7c, 0x73,
+  0x9f, 0x0a, 0x29, 0x89, 0xac, 0x3a, 0x98, 0xf7, 0x9b, 0x74, 0x67, 0xb7,
+  0x90, 0xb7, 0x5d, 0x09, 0x23, 0x6a, 0x6a, 0xed, 0x2c, 0x10, 0xee, 0x53,
+  0x0a, 0x10, 0xf0, 0x16, 0x1f, 0x57, 0xb3, 0xb1, 0x0d, 0x79, 0x91, 0x19,
+  0xb0, 0xeb, 0xcd, 0x30, 0x3f, 0xa0, 0x14, 0x5f, 0xb3, 0xc6, 0xfd, 0x5c,
+  0x33, 0xa7, 0xb0, 0xff, 0x98, 0xb0, 0x55, 0x8c, 0xb9, 0xa5, 0xf2, 0x6f,
+  0x47, 0x24, 0x49, 0x21, 0x69, 0xcc, 0x42, 0xa2, 0x51, 0x00, 0x40, 0x85,
+  0x8c, 0x82, 0x82, 0xab, 0x32, 0xa5, 0xcb, 0x9a, 0xdc, 0xd0, 0xd9, 0x18,
+  0x0d, 0xdf, 0x19, 0xf4, 0xaf, 0x83, 0x0d, 0xc1, 0x3e, 0x31, 0xdb, 0x24,
+  0x48, 0xb6, 0x75, 0x80, 0xa1, 0xe1, 0xc9, 0x77, 0x64, 0x1e, 0xa7, 0xe5,
+  0x8b, 0x7f, 0x15, 0x4d, 0x4b, 0xa7, 0xc2, 0xd0, 0xed, 0x79, 0x95, 0x5e,
+  0x91, 0x31, 0xec, 0x18, 0xff, 0x4e, 0x9f, 0x48, 0x14, 0xea, 0x75, 0xba,
+  0x21, 0xce, 0x29, 0x76, 0xe9, 0x1f, 0x4e, 0x51, 0x87, 0x2e, 0xb3, 0xcc,
+  0x04, 0x60, 0xba, 0x23, 0x1f, 0x1f, 0x65, 0xb2, 0x0a, 0xb8, 0xd5, 0x6e,
+  0x8f, 0x4b, 0x42, 0x89, 0x47, 0xa9, 0x81, 0x90, 0x5b, 0x2b, 0xb2, 0xb6,
+  0xae, 0xe6, 0xa0, 0x70, 0x7b, 0x78, 0x90, 0x0a, 0x7a, 0xc5, 0xe5, 0xe7,
+  0xc5, 0xfb, 0x0a, 0xf6, 0x2f, 0x69, 0x8c, 0x8c, 0x1f, 0x57, 0xe0, 0x06,
+  0x99, 0xff, 0x11, 0xd5, 0x52, 0x32, 0x20, 0x97, 0x27, 0x98, 0xee, 0x65,
+  0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0xd4, 0x30, 0x82, 0x01,
+  0xd0, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
+  0x80, 0x14, 0xa1, 0x72, 0x5f, 0x26, 0x1b, 0x28, 0x98, 0x43, 0x95, 0x5d,
+  0x07, 0x37, 0xd5, 0x85, 0x96, 0x9d, 0x4b, 0xd2, 0xc3, 0x45, 0x30, 0x1d,
+  0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xb7, 0xc3, 0xde,
+  0x1a, 0x43, 0xed, 0x41, 0x97, 0xa9, 0x8f, 0x29, 0x78, 0x9c, 0x03, 0xb9,
+  0xac, 0x40, 0x42, 0x00, 0xac, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f,
+  0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0c, 0x06,
+  0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30,
+  0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08,
+  0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06,
+  0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x46, 0x06, 0x03, 0x55, 0x1d,
+  0x20, 0x04, 0x3f, 0x30, 0x3d, 0x30, 0x3b, 0x06, 0x0c, 0x2b, 0x06, 0x01,
+  0x04, 0x01, 0xb2, 0x31, 0x01, 0x02, 0x01, 0x03, 0x04, 0x30, 0x2b, 0x30,
+  0x29, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16,
+  0x1d, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x73, 0x65, 0x63,
+  0x75, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x2e, 0x63,
+  0x6f, 0x6d, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x7b, 0x06, 0x03, 0x55, 0x1d,
+  0x1f, 0x04, 0x74, 0x30, 0x72, 0x30, 0x38, 0xa0, 0x36, 0xa0, 0x34, 0x86,
+  0x32, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e,
+  0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d,
+  0x2f, 0x55, 0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72,
+  0x73, 0x74, 0x2d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x2e,
+  0x63, 0x72, 0x6c, 0x30, 0x36, 0xa0, 0x34, 0xa0, 0x32, 0x86, 0x30, 0x68,
+  0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x63, 0x6f,
+  0x6d, 0x6f, 0x64, 0x6f, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x55, 0x54, 0x4e,
+  0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72, 0x73, 0x74, 0x2d, 0x48,
+  0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x2e, 0x63, 0x72, 0x6c, 0x30,
+  0x71, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
+  0x65, 0x30, 0x63, 0x30, 0x3b, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+  0x07, 0x30, 0x02, 0x86, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+  0x63, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x63, 0x61,
+  0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x55, 0x54, 0x4e, 0x41, 0x64, 0x64, 0x54,
+  0x72, 0x75, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x41,
+  0x2e, 0x63, 0x72, 0x74, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+  0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+  0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f,
+  0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x19, 0x06, 0x03, 0x55, 0x1d,
+  0x11, 0x04, 0x12, 0x30, 0x10, 0x82, 0x0e, 0x67, 0x6c, 0x6f, 0x62, 0x61,
+  0x6c, 0x20, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x65, 0x30, 0x0d, 0x06,
+  0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,
+  0x03, 0x82, 0x01, 0x01, 0x00, 0x8f, 0xba, 0x75, 0xba, 0x39, 0xd4, 0x26,
+  0xd3, 0x70, 0x0f, 0xc4, 0xb3, 0x02, 0xa7, 0xc5, 0x12, 0x23, 0x71, 0xc9,
+  0xfe, 0x63, 0xe9, 0xa3, 0x62, 0x78, 0x24, 0x44, 0x4f, 0xd4, 0xb9, 0x11,
+  0x3e, 0x1f, 0xc7, 0x28, 0xe7, 0x55, 0x6b, 0xee, 0xf4, 0xe1, 0x00, 0x91,
+  0x86, 0x8a, 0xc9, 0x09, 0x6b, 0x9f, 0x2e, 0xa4, 0x45, 0x39, 0xd1, 0x61,
+  0x62, 0x5e, 0x93, 0xa5, 0x05, 0x45, 0x78, 0x9f, 0x60, 0x12, 0x2c, 0xf4,
+  0x6c, 0x65, 0x65, 0x0d, 0xcc, 0x46, 0x34, 0x8b, 0x28, 0xba, 0xa0, 0xc6,
+  0xf4, 0x99, 0x71, 0x64, 0xf3, 0x22, 0x76, 0xac, 0x4f, 0xf3, 0x62, 0xc9,
+  0xa7, 0x33, 0x5a, 0x07, 0x1f, 0x3d, 0xc9, 0x86, 0x80, 0xdc, 0xdb, 0x04,
+  0x2f, 0x87, 0x27, 0xe8, 0xbf, 0x48, 0x44, 0x81, 0xc0, 0xf0, 0x49, 0x23,
+  0x6e, 0x1f, 0xe5, 0xe4, 0x03, 0x86, 0x24, 0x13, 0xa2, 0x85, 0x62, 0x7c,
+  0x58, 0x04, 0xca, 0xe6, 0x8d, 0x13, 0x72, 0x0a, 0xba, 0x56, 0x44, 0xa2,
+  0x0f, 0xbc, 0xfb, 0xa0, 0x3d, 0x0d, 0x2a, 0x7f, 0xfb, 0x9e, 0xa9, 0x09,
+  0x3d, 0xb7, 0x5a, 0xd4, 0x8a, 0x8d, 0xe1, 0x25, 0xe8, 0xa4, 0x09, 0x84,
+  0x70, 0xad, 0x12, 0x44, 0xb9, 0xcf, 0xb9, 0x33, 0x7a, 0xba, 0x5c, 0xe6,
+  0x4b, 0xa6, 0xbb, 0x05, 0x06, 0x98, 0xff, 0xf2, 0x98, 0x52, 0x7b, 0x77,
+  0x80, 0x27, 0x4a, 0xd9, 0xe2, 0xfa, 0xb9, 0x52, 0xd4, 0xfb, 0xfb, 0xe6,
+  0xd6, 0x2d, 0x9e, 0x8f, 0xc1, 0x15, 0x44, 0x8d, 0x9b, 0x74, 0x2f, 0xee,
+  0x94, 0x5a, 0x4e, 0xd3, 0xc4, 0x8b, 0x8a, 0xac, 0x43, 0x9d, 0x73, 0xf6,
+  0xae, 0x0c, 0x87, 0x89, 0xad, 0x87, 0xc9, 0xc9, 0xc7, 0xdd, 0xba, 0x14,
+  0x60, 0x7a, 0xf8, 0xb5, 0x35, 0x9d, 0xc2, 0x8d, 0xc6, 0x96, 0x81, 0x0d,
+  0xa9, 0x52, 0x8a, 0x29, 0x40, 0x04, 0xe9, 0x19, 0xb4
+};
+unsigned int Global_Trustee_cer_len = 1761;
diff --git a/sec/Security/Regressions/secitem/si-67-sectrust-blacklist/UTN-USERFirst-Hardware.cer.h b/sec/Security/Regressions/secitem/si-67-sectrust-blacklist/UTN-USERFirst-Hardware.cer.h
new file mode 100644 (file)
index 0000000..320e0e3
--- /dev/null
@@ -0,0 +1,99 @@
+unsigned char UTN_USERFirst_Hardware_cer[] = {
+  0x30, 0x82, 0x04, 0x74, 0x30, 0x82, 0x03, 0x5c, 0xa0, 0x03, 0x02, 0x01,
+  0x02, 0x02, 0x10, 0x44, 0xbe, 0x0c, 0x8b, 0x50, 0x00, 0x24, 0xb4, 0x11,
+  0xd3, 0x36, 0x2a, 0xfe, 0x65, 0x0a, 0xfd, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81,
+  0x97, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+  0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
+  0x02, 0x55, 0x54, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x07,
+  0x13, 0x0e, 0x53, 0x61, 0x6c, 0x74, 0x20, 0x4c, 0x61, 0x6b, 0x65, 0x20,
+  0x43, 0x69, 0x74, 0x79, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04,
+  0x0a, 0x13, 0x15, 0x54, 0x68, 0x65, 0x20, 0x55, 0x53, 0x45, 0x52, 0x54,
+  0x52, 0x55, 0x53, 0x54, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
+  0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x18, 0x68,
+  0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x75, 0x73,
+  0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x31,
+  0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x55, 0x54,
+  0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72, 0x73, 0x74, 0x2d,
+  0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x30, 0x1e, 0x17, 0x0d,
+  0x39, 0x39, 0x30, 0x37, 0x30, 0x39, 0x31, 0x38, 0x31, 0x30, 0x34, 0x32,
+  0x5a, 0x17, 0x0d, 0x31, 0x39, 0x30, 0x37, 0x30, 0x39, 0x31, 0x38, 0x31,
+  0x39, 0x32, 0x32, 0x5a, 0x30, 0x81, 0x97, 0x31, 0x0b, 0x30, 0x09, 0x06,
+  0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09,
+  0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x55, 0x54, 0x31, 0x17, 0x30,
+  0x15, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0e, 0x53, 0x61, 0x6c, 0x74,
+  0x20, 0x4c, 0x61, 0x6b, 0x65, 0x20, 0x43, 0x69, 0x74, 0x79, 0x31, 0x1e,
+  0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x15, 0x54, 0x68, 0x65,
+  0x20, 0x55, 0x53, 0x45, 0x52, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x4e,
+  0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03,
+  0x55, 0x04, 0x0b, 0x13, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+  0x77, 0x77, 0x77, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73,
+  0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55,
+  0x04, 0x03, 0x13, 0x16, 0x55, 0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52,
+  0x46, 0x69, 0x72, 0x73, 0x74, 0x2d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61,
+  0x72, 0x65, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
+  0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb1,
+  0xf7, 0xc3, 0x38, 0x3f, 0xb4, 0xa8, 0x7f, 0xcf, 0x39, 0x82, 0x51, 0x67,
+  0xd0, 0x6d, 0x9f, 0xd2, 0xff, 0x58, 0xf3, 0xe7, 0x9f, 0x2b, 0xec, 0x0d,
+  0x89, 0x54, 0x99, 0xb9, 0x38, 0x99, 0x16, 0xf7, 0xe0, 0x21, 0x79, 0x48,
+  0xc2, 0xbb, 0x61, 0x74, 0x12, 0x96, 0x1d, 0x3c, 0x6a, 0x72, 0xd5, 0x3c,
+  0x10, 0x67, 0x3a, 0x39, 0xed, 0x2b, 0x13, 0xcd, 0x66, 0xeb, 0x95, 0x09,
+  0x33, 0xa4, 0x6c, 0x97, 0xb1, 0xe8, 0xc6, 0xec, 0xc1, 0x75, 0x79, 0x9c,
+  0x46, 0x5e, 0x8d, 0xab, 0xd0, 0x6a, 0xfd, 0xb9, 0x2a, 0x55, 0x17, 0x10,
+  0x54, 0xb3, 0x19, 0xf0, 0x9a, 0xf6, 0xf1, 0xb1, 0x5d, 0xb6, 0xa7, 0x6d,
+  0xfb, 0xe0, 0x71, 0x17, 0x6b, 0xa2, 0x88, 0xfb, 0x00, 0xdf, 0xfe, 0x1a,
+  0x31, 0x77, 0x0c, 0x9a, 0x01, 0x7a, 0xb1, 0x32, 0xe3, 0x2b, 0x01, 0x07,
+  0x38, 0x6e, 0xc3, 0xa5, 0x5e, 0x23, 0xbc, 0x45, 0x9b, 0x7b, 0x50, 0xc1,
+  0xc9, 0x30, 0x8f, 0xdb, 0xe5, 0x2b, 0x7a, 0xd3, 0x5b, 0xfb, 0x33, 0x40,
+  0x1e, 0xa0, 0xd5, 0x98, 0x17, 0xbc, 0x8b, 0x87, 0xc3, 0x89, 0xd3, 0x5d,
+  0xa0, 0x8e, 0xb2, 0xaa, 0xaa, 0xf6, 0x8e, 0x69, 0x88, 0x06, 0xc5, 0xfa,
+  0x89, 0x21, 0xf3, 0x08, 0x9d, 0x69, 0x2e, 0x09, 0x33, 0x9b, 0x29, 0x0d,
+  0x46, 0x0f, 0x8c, 0xcc, 0x49, 0x34, 0xb0, 0x69, 0x51, 0xbd, 0xf9, 0x06,
+  0xcd, 0x68, 0xad, 0x66, 0x4c, 0xbc, 0x3e, 0xac, 0x61, 0xbd, 0x0a, 0x88,
+  0x0e, 0xc8, 0xdf, 0x3d, 0xee, 0x7c, 0x04, 0x4c, 0x9d, 0x0a, 0x5e, 0x6b,
+  0x91, 0xd6, 0xee, 0xc7, 0xed, 0x28, 0x8d, 0xab, 0x4d, 0x87, 0x89, 0x73,
+  0xd0, 0x6e, 0xa4, 0xd0, 0x1e, 0x16, 0x8b, 0x14, 0xe1, 0x76, 0x44, 0x03,
+  0x7f, 0x63, 0xac, 0xe4, 0xcd, 0x49, 0x9c, 0xc5, 0x92, 0xf4, 0xab, 0x32,
+  0xa1, 0x48, 0x5b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xb9, 0x30,
+  0x81, 0xb6, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03,
+  0x02, 0x01, 0xc6, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
+  0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03,
+  0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xa1, 0x72, 0x5f, 0x26, 0x1b,
+  0x28, 0x98, 0x43, 0x95, 0x5d, 0x07, 0x37, 0xd5, 0x85, 0x96, 0x9d, 0x4b,
+  0xd2, 0xc3, 0x45, 0x30, 0x44, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x3d,
+  0x30, 0x3b, 0x30, 0x39, 0xa0, 0x37, 0xa0, 0x35, 0x86, 0x33, 0x68, 0x74,
+  0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x75, 0x73, 0x65,
+  0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x55,
+  0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72, 0x73, 0x74,
+  0x2d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x2e, 0x63, 0x72,
+  0x6c, 0x30, 0x31, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x2a, 0x30, 0x28,
+  0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08,
+  0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x05, 0x06, 0x08, 0x2b, 0x06,
+  0x01, 0x05, 0x05, 0x07, 0x03, 0x06, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+  0x05, 0x07, 0x03, 0x07, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00,
+  0x47, 0x19, 0x0f, 0xde, 0x74, 0xc6, 0x99, 0x97, 0xaf, 0xfc, 0xad, 0x28,
+  0x5e, 0x75, 0x8e, 0xeb, 0x2d, 0x67, 0xee, 0x4e, 0x7b, 0x2b, 0xd7, 0x0c,
+  0xff, 0xf6, 0xde, 0xcb, 0x55, 0xa2, 0x0a, 0xe1, 0x4c, 0x54, 0x65, 0x93,
+  0x60, 0x6b, 0x9f, 0x12, 0x9c, 0xad, 0x5e, 0x83, 0x2c, 0xeb, 0x5a, 0xae,
+  0xc0, 0xe4, 0x2d, 0xf4, 0x00, 0x63, 0x1d, 0xb8, 0xc0, 0x6c, 0xf2, 0xcf,
+  0x49, 0xbb, 0x4d, 0x93, 0x6f, 0x06, 0xa6, 0x0a, 0x22, 0xb2, 0x49, 0x62,
+  0x08, 0x4e, 0xff, 0xc8, 0xc8, 0x14, 0xb2, 0x88, 0x16, 0x5d, 0xe7, 0x01,
+  0xe4, 0x12, 0x95, 0xe5, 0x45, 0x34, 0xb3, 0x8b, 0x69, 0xbd, 0xcf, 0xb4,
+  0x85, 0x8f, 0x75, 0x51, 0x9e, 0x7d, 0x3a, 0x38, 0x3a, 0x14, 0x48, 0x12,
+  0xc6, 0xfb, 0xa7, 0x3b, 0x1a, 0x8d, 0x0d, 0x82, 0x40, 0x07, 0xe8, 0x04,
+  0x08, 0x90, 0xa1, 0x89, 0xcb, 0x19, 0x50, 0xdf, 0xca, 0x1c, 0x01, 0xbc,
+  0x1d, 0x04, 0x19, 0x7b, 0x10, 0x76, 0x97, 0x3b, 0xee, 0x90, 0x90, 0xca,
+  0xc4, 0x0e, 0x1f, 0x16, 0x6e, 0x75, 0xef, 0x33, 0xf8, 0xd3, 0x6f, 0x5b,
+  0x1e, 0x96, 0xe3, 0xe0, 0x74, 0x77, 0x74, 0x7b, 0x8a, 0xa2, 0x6e, 0x2d,
+  0xdd, 0x76, 0xd6, 0x39, 0x30, 0x82, 0xf0, 0xab, 0x9c, 0x52, 0xf2, 0x2a,
+  0xc7, 0xaf, 0x49, 0x5e, 0x7e, 0xc7, 0x68, 0xe5, 0x82, 0x81, 0xc8, 0x6a,
+  0x27, 0xf9, 0x27, 0x88, 0x2a, 0xd5, 0x58, 0x50, 0x95, 0x1f, 0xf0, 0x3b,
+  0x1c, 0x57, 0xbb, 0x7d, 0x14, 0x39, 0x62, 0x2b, 0x9a, 0xc9, 0x94, 0x92,
+  0x2a, 0xa3, 0x22, 0x0c, 0xff, 0x89, 0x26, 0x7d, 0x5f, 0x23, 0x2b, 0x47,
+  0xd7, 0x15, 0x1d, 0xa9, 0x6a, 0x9e, 0x51, 0x0d, 0x2a, 0x51, 0x9e, 0x81,
+  0xf9, 0xd4, 0x3b, 0x5e, 0x70, 0x12, 0x7f, 0x10, 0x32, 0x9c, 0x1e, 0xbb,
+  0x9d, 0xf8, 0x66, 0xa8
+};
+unsigned int UTN_USERFirst_Hardware_cer_len = 1144;
diff --git a/sec/Security/Regressions/secitem/si-67-sectrust-blacklist/addons.mozilla.org.cer.h b/sec/Security/Regressions/secitem/si-67-sectrust-blacklist/addons.mozilla.org.cer.h
new file mode 100644 (file)
index 0000000..ae288d3
--- /dev/null
@@ -0,0 +1,131 @@
+unsigned char addons_mozilla_org_cer[] = {
+  0x30, 0x82, 0x05, 0xf8, 0x30, 0x82, 0x04, 0xe0, 0xa0, 0x03, 0x02, 0x01,
+  0x02, 0x02, 0x11, 0x00, 0x92, 0x39, 0xd5, 0x34, 0x8f, 0x40, 0xd1, 0x69,
+  0x5a, 0x74, 0x54, 0x70, 0xe1, 0xf2, 0x3f, 0x43, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
+  0x81, 0x97, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+  0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08,
+  0x13, 0x02, 0x55, 0x54, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04,
+  0x07, 0x13, 0x0e, 0x53, 0x61, 0x6c, 0x74, 0x20, 0x4c, 0x61, 0x6b, 0x65,
+  0x20, 0x43, 0x69, 0x74, 0x79, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55,
+  0x04, 0x0a, 0x13, 0x15, 0x54, 0x68, 0x65, 0x20, 0x55, 0x53, 0x45, 0x52,
+  0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72,
+  0x6b, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x18,
+  0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x75,
+  0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
+  0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x55,
+  0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72, 0x73, 0x74,
+  0x2d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x30, 0x1e, 0x17,
+  0x0d, 0x31, 0x31, 0x30, 0x33, 0x31, 0x35, 0x30, 0x30, 0x30, 0x30, 0x30,
+  0x30, 0x5a, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x33, 0x31, 0x34, 0x32, 0x33,
+  0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xe2, 0x31, 0x0b, 0x30, 0x09,
+  0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0e, 0x30,
+  0x0c, 0x06, 0x03, 0x55, 0x04, 0x11, 0x13, 0x05, 0x33, 0x38, 0x34, 0x37,
+  0x37, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07,
+  0x46, 0x6c, 0x6f, 0x72, 0x69, 0x64, 0x61, 0x31, 0x10, 0x30, 0x0e, 0x06,
+  0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73,
+  0x68, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x09, 0x13, 0x0e,
+  0x53, 0x65, 0x61, 0x20, 0x56, 0x69, 0x6c, 0x6c, 0x61, 0x67, 0x65, 0x20,
+  0x31, 0x30, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+  0x0b, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x4c, 0x74, 0x64, 0x2e,
+  0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x54,
+  0x65, 0x63, 0x68, 0x20, 0x44, 0x65, 0x70, 0x74, 0x2e, 0x31, 0x28, 0x30,
+  0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x48, 0x6f, 0x73, 0x74,
+  0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x47, 0x54, 0x49, 0x20, 0x47, 0x72,
+  0x6f, 0x75, 0x70, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74,
+  0x69, 0x6f, 0x6e, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b,
+  0x13, 0x0b, 0x50, 0x6c, 0x61, 0x74, 0x69, 0x6e, 0x75, 0x6d, 0x53, 0x53,
+  0x4c, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12,
+  0x61, 0x64, 0x64, 0x6f, 0x6e, 0x73, 0x2e, 0x6d, 0x6f, 0x7a, 0x69, 0x6c,
+  0x6c, 0x61, 0x2e, 0x6f, 0x72, 0x67, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
+  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
+  0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82,
+  0x01, 0x01, 0x00, 0xab, 0xc6, 0x6d, 0x36, 0xf3, 0x15, 0x73, 0x78, 0x83,
+  0x73, 0xce, 0x74, 0x85, 0xd5, 0xae, 0xec, 0xb2, 0xf0, 0xe0, 0x24, 0x1f,
+  0x13, 0x83, 0xb8, 0x20, 0xac, 0xbb, 0x9a, 0xfe, 0x88, 0xbb, 0xab, 0xa1,
+  0x1d, 0x0b, 0x1f, 0x45, 0x00, 0xaa, 0x49, 0xb7, 0x35, 0x37, 0x0c, 0x6a,
+  0xef, 0x47, 0x4c, 0xb9, 0xd1, 0xbe, 0xe3, 0x57, 0x12, 0x04, 0x8d, 0x92,
+  0xc7, 0xb6, 0xec, 0x01, 0xbc, 0xb6, 0xda, 0xc7, 0x81, 0x38, 0x20, 0xad,
+  0x72, 0x85, 0xe6, 0x0e, 0xfc, 0x81, 0x6c, 0x07, 0xad, 0x68, 0x76, 0x38,
+  0xc5, 0x44, 0xd7, 0xcc, 0xc6, 0x4a, 0xc5, 0x97, 0x3e, 0x64, 0xf4, 0x51,
+  0xe6, 0xf0, 0x7e, 0xb2, 0xec, 0x56, 0xf7, 0x25, 0x82, 0x4d, 0x49, 0x98,
+  0xcb, 0x16, 0x98, 0xdd, 0x23, 0xf1, 0x89, 0x91, 0xd1, 0x17, 0x97, 0x40,
+  0x99, 0x26, 0xd6, 0xe2, 0xa2, 0x2b, 0x5e, 0xdf, 0xbd, 0x89, 0xf2, 0x1b,
+  0x1a, 0x53, 0x2d, 0xcc, 0x50, 0x41, 0x7a, 0xd0, 0x3d, 0x2a, 0x0c, 0x55,
+  0x70, 0x14, 0x01, 0xe9, 0x58, 0x49, 0x10, 0x7a, 0x0b, 0x93, 0x82, 0x8b,
+  0xe1, 0x1e, 0xed, 0x3a, 0x80, 0x10, 0x82, 0xce, 0x96, 0x8a, 0x34, 0xf0,
+  0xcc, 0xd7, 0xd3, 0xb9, 0xb4, 0x50, 0x87, 0x55, 0x54, 0x09, 0xb8, 0x9d,
+  0x42, 0x28, 0x55, 0x00, 0xe5, 0x8c, 0x35, 0x54, 0xbf, 0xdd, 0x25, 0x91,
+  0x46, 0xb7, 0x0d, 0xe5, 0x5d, 0x83, 0xa8, 0xe5, 0x8b, 0xfb, 0x84, 0xe4,
+  0x3c, 0xae, 0x76, 0xda, 0xc4, 0x43, 0x2b, 0x5b, 0x74, 0x0b, 0xf8, 0xbe,
+  0x5d, 0x68, 0xf1, 0x78, 0x5b, 0xb5, 0xce, 0x7d, 0xf1, 0x5d, 0x99, 0x40,
+  0xda, 0xca, 0xee, 0x38, 0x81, 0x50, 0xbe, 0x98, 0xa1, 0x6c, 0xb8, 0x24,
+  0xad, 0xf3, 0xaf, 0x8c, 0x0f, 0xd7, 0x11, 0x28, 0x2c, 0x84, 0x18, 0x4c,
+  0x7d, 0xb5, 0xd9, 0x8f, 0x30, 0xb5, 0x1b, 0x02, 0x03, 0x01, 0x00, 0x01,
+  0xa3, 0x82, 0x01, 0xf0, 0x30, 0x82, 0x01, 0xec, 0x30, 0x1f, 0x06, 0x03,
+  0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xa1, 0x72, 0x5f,
+  0x26, 0x1b, 0x28, 0x98, 0x43, 0x95, 0x5d, 0x07, 0x37, 0xd5, 0x85, 0x96,
+  0x9d, 0x4b, 0xd2, 0xc3, 0x45, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
+  0x04, 0x16, 0x04, 0x14, 0xdd, 0x80, 0xd2, 0x54, 0x3d, 0xf7, 0x4c, 0x70,
+  0xca, 0xa3, 0xb0, 0xdd, 0x34, 0x7a, 0x32, 0xe4, 0xe8, 0x3b, 0x5a, 0x3b,
+  0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04,
+  0x03, 0x02, 0x05, 0xa0, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
+  0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
+  0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+  0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03,
+  0x02, 0x30, 0x46, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3f, 0x30, 0x3d,
+  0x30, 0x3b, 0x06, 0x0c, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xb2, 0x31, 0x01,
+  0x02, 0x01, 0x03, 0x04, 0x30, 0x2b, 0x30, 0x29, 0x06, 0x08, 0x2b, 0x06,
+  0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1d, 0x68, 0x74, 0x74, 0x70,
+  0x73, 0x3a, 0x2f, 0x2f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x2e, 0x63,
+  0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x50,
+  0x53, 0x30, 0x7b, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x74, 0x30, 0x72,
+  0x30, 0x38, 0xa0, 0x36, 0xa0, 0x34, 0x86, 0x32, 0x68, 0x74, 0x74, 0x70,
+  0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64,
+  0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x55, 0x54, 0x4e, 0x2d,
+  0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72, 0x73, 0x74, 0x2d, 0x48, 0x61,
+  0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x36,
+  0xa0, 0x34, 0xa0, 0x32, 0x86, 0x30, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+  0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x2e,
+  0x6e, 0x65, 0x74, 0x2f, 0x55, 0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52,
+  0x46, 0x69, 0x72, 0x73, 0x74, 0x2d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61,
+  0x72, 0x65, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x71, 0x06, 0x08, 0x2b, 0x06,
+  0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x65, 0x30, 0x63, 0x30, 0x3b,
+  0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2f,
+  0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x74, 0x2e, 0x63,
+  0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+  0x55, 0x54, 0x4e, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x53,
+  0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x74, 0x30,
+  0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86,
+  0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70,
+  0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f,
+  0x6d, 0x30, 0x35, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x2e, 0x30, 0x2c,
+  0x82, 0x12, 0x61, 0x64, 0x64, 0x6f, 0x6e, 0x73, 0x2e, 0x6d, 0x6f, 0x7a,
+  0x69, 0x6c, 0x6c, 0x61, 0x2e, 0x6f, 0x72, 0x67, 0x82, 0x16, 0x77, 0x77,
+  0x77, 0x2e, 0x61, 0x64, 0x64, 0x6f, 0x6e, 0x73, 0x2e, 0x6d, 0x6f, 0x7a,
+  0x69, 0x6c, 0x6c, 0x61, 0x2e, 0x6f, 0x72, 0x67, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,
+  0x82, 0x01, 0x01, 0x00, 0x33, 0x3b, 0x63, 0x15, 0xfc, 0xb1, 0xec, 0x14,
+  0x2c, 0x93, 0xdd, 0x75, 0x94, 0xde, 0x81, 0x5a, 0xd9, 0x4e, 0x99, 0xbe,
+  0xfb, 0x4a, 0xa4, 0x39, 0x55, 0x4d, 0xa1, 0x40, 0x7a, 0xde, 0x13, 0x2a,
+  0x87, 0xa9, 0x37, 0xcf, 0xe8, 0xd5, 0xfb, 0xad, 0xd1, 0x7b, 0x6d, 0x6f,
+  0x8c, 0x20, 0x87, 0x82, 0x54, 0xe6, 0x57, 0x49, 0xbc, 0x20, 0x28, 0x84,
+  0xcd, 0xd6, 0x01, 0xd9, 0x93, 0x8b, 0x17, 0x6e, 0x23, 0x66, 0xe5, 0x84,
+  0xc8, 0x80, 0x3f, 0xc6, 0xa1, 0x70, 0x80, 0xe4, 0xec, 0x4d, 0x1d, 0xf9,
+  0xfc, 0x91, 0x5a, 0x73, 0x62, 0x29, 0x9a, 0xf7, 0x20, 0x1c, 0x61, 0xe0,
+  0x8b, 0x39, 0x9f, 0xca, 0xbc, 0x7e, 0x8d, 0xdd, 0xbc, 0xd9, 0xb1, 0xe3,
+  0x9f, 0x9e, 0xdf, 0x15, 0x53, 0x91, 0x21, 0x52, 0x0b, 0xd9, 0x1a, 0x23,
+  0x0f, 0x66, 0x36, 0xdb, 0xac, 0x93, 0x96, 0x4a, 0xa3, 0xa5, 0x22, 0xcf,
+  0x29, 0xf7, 0xa2, 0x99, 0xa8, 0xf6, 0xb6, 0xd9, 0x40, 0xae, 0xd9, 0x7e,
+  0xb6, 0xf6, 0x58, 0x2e, 0x9b, 0xac, 0x36, 0xca, 0x64, 0x8f, 0x65, 0x52,
+  0xdc, 0x86, 0x9c, 0x82, 0xab, 0x6e, 0x50, 0x4b, 0xda, 0x5f, 0xfa, 0x05,
+  0x00, 0x88, 0x30, 0x0e, 0xde, 0x8d, 0x56, 0xbf, 0x81, 0x47, 0x8d, 0x3d,
+  0x06, 0xe2, 0xb2, 0x62, 0x92, 0x67, 0x8f, 0x9e, 0xc8, 0x9a, 0xb2, 0xe5,
+  0x06, 0xb8, 0x70, 0x24, 0xb8, 0x77, 0x7c, 0x23, 0x0a, 0x38, 0xc3, 0x79,
+  0x08, 0xd8, 0xb1, 0x51, 0x9d, 0xac, 0x95, 0x11, 0xc7, 0x40, 0x17, 0x9e,
+  0xa3, 0x1c, 0x8f, 0xf2, 0x11, 0xa7, 0x68, 0x27, 0xda, 0x49, 0x05, 0x84,
+  0x18, 0x7c, 0x58, 0x2d, 0x01, 0x67, 0x5c, 0xe5, 0x9f, 0xa1, 0x29, 0xbb,
+  0x4a, 0x39, 0x45, 0x2f, 0xbf, 0x11, 0xaa, 0x79, 0xa2, 0xed, 0xb4, 0xd4,
+  0xb5, 0x65, 0x43, 0xb7, 0x93, 0x46, 0x8a, 0xd3
+};
+unsigned int addons_mozilla_org_cer_len = 1532;
diff --git a/sec/Security/Regressions/secitem/si-67-sectrust-blacklist/login.live.com.cer.h b/sec/Security/Regressions/secitem/si-67-sectrust-blacklist/login.live.com.cer.h
new file mode 100644 (file)
index 0000000..fb39259
--- /dev/null
@@ -0,0 +1,130 @@
+unsigned char login_live_com_cer[] = {
+  0x30, 0x82, 0x05, 0xec, 0x30, 0x82, 0x04, 0xd4, 0xa0, 0x03, 0x02, 0x01,
+  0x02, 0x02, 0x11, 0x00, 0xb0, 0xb7, 0x13, 0x3e, 0xd0, 0x96, 0xf9, 0xb5,
+  0x6f, 0xae, 0x91, 0xc8, 0x74, 0xbd, 0x3a, 0xc0, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
+  0x81, 0x97, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+  0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08,
+  0x13, 0x02, 0x55, 0x54, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04,
+  0x07, 0x13, 0x0e, 0x53, 0x61, 0x6c, 0x74, 0x20, 0x4c, 0x61, 0x6b, 0x65,
+  0x20, 0x43, 0x69, 0x74, 0x79, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55,
+  0x04, 0x0a, 0x13, 0x15, 0x54, 0x68, 0x65, 0x20, 0x55, 0x53, 0x45, 0x52,
+  0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72,
+  0x6b, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x18,
+  0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x75,
+  0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
+  0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x55,
+  0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72, 0x73, 0x74,
+  0x2d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x30, 0x1e, 0x17,
+  0x0d, 0x31, 0x31, 0x30, 0x33, 0x31, 0x35, 0x30, 0x30, 0x30, 0x30, 0x30,
+  0x30, 0x5a, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x33, 0x31, 0x34, 0x32, 0x33,
+  0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xde, 0x31, 0x0b, 0x30, 0x09,
+  0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0e, 0x30,
+  0x0c, 0x06, 0x03, 0x55, 0x04, 0x11, 0x13, 0x05, 0x33, 0x38, 0x34, 0x37,
+  0x37, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07,
+  0x46, 0x6c, 0x6f, 0x72, 0x69, 0x64, 0x61, 0x31, 0x10, 0x30, 0x0e, 0x06,
+  0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73,
+  0x68, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x09, 0x13, 0x0e,
+  0x53, 0x65, 0x61, 0x20, 0x56, 0x69, 0x6c, 0x6c, 0x61, 0x67, 0x65, 0x20,
+  0x31, 0x30, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+  0x0b, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x4c, 0x74, 0x64, 0x2e,
+  0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x54,
+  0x65, 0x63, 0x68, 0x20, 0x44, 0x65, 0x70, 0x74, 0x2e, 0x31, 0x28, 0x30,
+  0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x48, 0x6f, 0x73, 0x74,
+  0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x47, 0x54, 0x49, 0x20, 0x47, 0x72,
+  0x6f, 0x75, 0x70, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74,
+  0x69, 0x6f, 0x6e, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b,
+  0x13, 0x0b, 0x50, 0x6c, 0x61, 0x74, 0x69, 0x6e, 0x75, 0x6d, 0x53, 0x53,
+  0x4c, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0e,
+  0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x2e, 0x63,
+  0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
+  0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xf3,
+  0xfc, 0x2b, 0x2f, 0xef, 0xe1, 0xad, 0x59, 0xf0, 0x42, 0x3c, 0xc2, 0xf1,
+  0x82, 0xbf, 0x2c, 0x41, 0x93, 0xd1, 0xf6, 0x98, 0x33, 0x95, 0x4c, 0xbc,
+  0x62, 0xf1, 0x95, 0x58, 0x08, 0xb6, 0xe9, 0x7b, 0x77, 0x48, 0xb0, 0xd3,
+  0xdc, 0x17, 0x3f, 0xbc, 0x6e, 0xe6, 0xec, 0x1e, 0xec, 0x8d, 0x17, 0xfe,
+  0x1c, 0x24, 0xc6, 0x3e, 0x67, 0x3d, 0x92, 0x95, 0xa2, 0x30, 0xc0, 0xa7,
+  0x57, 0x20, 0xcf, 0x70, 0x88, 0x97, 0x4a, 0x05, 0x93, 0x79, 0x93, 0x42,
+  0x97, 0x2f, 0x3e, 0xff, 0xc4, 0x14, 0x14, 0x28, 0xa2, 0x13, 0x36, 0xb4,
+  0xf8, 0xee, 0xbe, 0x1d, 0xbc, 0x78, 0x5d, 0x61, 0x93, 0x5f, 0xeb, 0x88,
+  0xd7, 0xd1, 0xe4, 0x2b, 0x9a, 0xcd, 0x58, 0xe2, 0x07, 0x45, 0x9f, 0x4f,
+  0xb8, 0xb9, 0x40, 0x6a, 0x33, 0x2c, 0x5b, 0x21, 0x03, 0x5a, 0x4a, 0x94,
+  0xf2, 0x7a, 0x97, 0x59, 0x1b, 0xa8, 0xb5, 0x42, 0xd8, 0x83, 0x00, 0xaa,
+  0x34, 0xcc, 0xa7, 0x76, 0xd0, 0x47, 0x03, 0x5f, 0x05, 0xaf, 0x3b, 0xe1,
+  0xb9, 0xa1, 0x34, 0x25, 0xb7, 0x6c, 0x5f, 0x9a, 0x30, 0x84, 0x98, 0xc2,
+  0xc2, 0xd7, 0xf2, 0xb8, 0x42, 0x4a, 0x10, 0x55, 0xbd, 0xfa, 0x53, 0x81,
+  0x5d, 0x8d, 0x68, 0x66, 0x45, 0x2c, 0x52, 0x7e, 0xe5, 0xc4, 0x04, 0xc3,
+  0x54, 0xe7, 0xc3, 0x39, 0xda, 0x7a, 0x4a, 0xc5, 0xb9, 0x98, 0x82, 0x20,
+  0xe1, 0x2c, 0x60, 0x57, 0xbf, 0xba, 0xf2, 0x46, 0x00, 0xbc, 0x5f, 0x3a,
+  0xdc, 0xe3, 0x33, 0x97, 0xf8, 0x4a, 0x98, 0xb9, 0xec, 0x33, 0x4f, 0x2d,
+  0x60, 0x6c, 0x15, 0x92, 0xa6, 0x81, 0x4a, 0x0b, 0xe9, 0xec, 0x76, 0x70,
+  0x34, 0x31, 0x17, 0x70, 0xe6, 0x70, 0x4b, 0x8e, 0x8b, 0xd3, 0x75, 0xcb,
+  0x78, 0x49, 0xab, 0x66, 0x9b, 0x86, 0x9f, 0x8f, 0xa9, 0xc4, 0x01, 0xe8,
+  0xca, 0x1b, 0xe7, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0xe8,
+  0x30, 0x82, 0x01, 0xe4, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
+  0x18, 0x30, 0x16, 0x80, 0x14, 0xa1, 0x72, 0x5f, 0x26, 0x1b, 0x28, 0x98,
+  0x43, 0x95, 0x5d, 0x07, 0x37, 0xd5, 0x85, 0x96, 0x9d, 0x4b, 0xd2, 0xc3,
+  0x45, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
+  0xd4, 0x64, 0xf6, 0xa9, 0xe8, 0xa5, 0x7e, 0xd7, 0xbf, 0x63, 0x52, 0x03,
+  0x83, 0x53, 0xdb, 0xc5, 0x41, 0x8d, 0xea, 0x80, 0x30, 0x0e, 0x06, 0x03,
+  0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0,
+  0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02,
+  0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30,
+  0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06,
+  0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x46, 0x06,
+  0x03, 0x55, 0x1d, 0x20, 0x04, 0x3f, 0x30, 0x3d, 0x30, 0x3b, 0x06, 0x0c,
+  0x2b, 0x06, 0x01, 0x04, 0x01, 0xb2, 0x31, 0x01, 0x02, 0x01, 0x03, 0x04,
+  0x30, 0x2b, 0x30, 0x29, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+  0x02, 0x01, 0x16, 0x1d, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f,
+  0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64,
+  0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x7b, 0x06,
+  0x03, 0x55, 0x1d, 0x1f, 0x04, 0x74, 0x30, 0x72, 0x30, 0x38, 0xa0, 0x36,
+  0xa0, 0x34, 0x86, 0x32, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63,
+  0x72, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e,
+  0x63, 0x6f, 0x6d, 0x2f, 0x55, 0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52,
+  0x46, 0x69, 0x72, 0x73, 0x74, 0x2d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61,
+  0x72, 0x65, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x36, 0xa0, 0x34, 0xa0, 0x32,
+  0x86, 0x30, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c,
+  0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x2e, 0x6e, 0x65, 0x74, 0x2f,
+  0x55, 0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72, 0x73,
+  0x74, 0x2d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x2e, 0x63,
+  0x72, 0x6c, 0x30, 0x71, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+  0x01, 0x01, 0x04, 0x65, 0x30, 0x63, 0x30, 0x3b, 0x06, 0x08, 0x2b, 0x06,
+  0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2f, 0x68, 0x74, 0x74, 0x70,
+  0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64,
+  0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x55, 0x54, 0x4e, 0x41,
+  0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65,
+  0x72, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x24, 0x06, 0x08, 0x2b,
+  0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74,
+  0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x63, 0x6f, 0x6d,
+  0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x2d, 0x06,
+  0x03, 0x55, 0x1d, 0x11, 0x04, 0x26, 0x30, 0x24, 0x82, 0x0e, 0x6c, 0x6f,
+  0x67, 0x69, 0x6e, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
+  0x82, 0x12, 0x77, 0x77, 0x77, 0x2e, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x2e,
+  0x6c, 0x69, 0x76, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,
+  0x82, 0x01, 0x01, 0x00, 0x54, 0xe3, 0xa4, 0x9a, 0x24, 0xd2, 0xf3, 0x1d,
+  0x42, 0xad, 0x1b, 0xf0, 0x1e, 0xab, 0xfb, 0xda, 0xd5, 0xaa, 0xe9, 0xcf,
+  0x5a, 0xb3, 0x1e, 0x57, 0x7b, 0x31, 0xf2, 0x6e, 0x57, 0x4b, 0x31, 0xaf,
+  0x33, 0xbb, 0xb6, 0x0d, 0x15, 0xc7, 0x5e, 0x59, 0x01, 0xce, 0x44, 0xb5,
+  0xb7, 0xbf, 0x09, 0xc9, 0xd5, 0xdc, 0x69, 0x84, 0xe9, 0xc5, 0x1a, 0xb7,
+  0xf0, 0x3e, 0xd4, 0xc0, 0x24, 0xbd, 0x29, 0x5f, 0xb4, 0xe9, 0xd6, 0x58,
+  0xeb, 0x45, 0x11, 0x89, 0x34, 0x34, 0xd3, 0x11, 0xeb, 0x34, 0xce, 0x2a,
+  0x4f, 0x00, 0x3d, 0xf6, 0x72, 0xef, 0x69, 0x66, 0xc0, 0x9f, 0x9a, 0xac,
+  0x7e, 0x70, 0x50, 0xac, 0x55, 0x47, 0xda, 0xbe, 0x43, 0x5b, 0xec, 0x8b,
+  0xc8, 0xc5, 0x23, 0x84, 0xc9, 0x9f, 0xb6, 0x52, 0x08, 0xcf, 0x91, 0x1b,
+  0x2f, 0x80, 0x69, 0xe6, 0x34, 0x33, 0xe6, 0xb3, 0x9f, 0xa4, 0xe5, 0x0d,
+  0x9a, 0x15, 0xf9, 0x57, 0xfc, 0x0b, 0xa9, 0x41, 0x0b, 0xf5, 0xff, 0x58,
+  0x41, 0x92, 0x22, 0x27, 0x66, 0x12, 0x06, 0xc7, 0x2a, 0xd8, 0x59, 0xa7,
+  0xc6, 0xdf, 0x44, 0x12, 0x4f, 0xc0, 0xa8, 0x7f, 0xa7, 0x41, 0xc8, 0xc8,
+  0x69, 0xff, 0xba, 0x05, 0x2e, 0x97, 0xad, 0x3b, 0xd0, 0xeb, 0xf3, 0x15,
+  0x6d, 0x7e, 0x1b, 0xe5, 0xba, 0xdd, 0x34, 0xbe, 0x22, 0x11, 0xec, 0x68,
+  0x98, 0x33, 0x81, 0x02, 0x6a, 0x0b, 0x13, 0x55, 0x79, 0x31, 0x75, 0x4e,
+  0x3a, 0xc8, 0xb6, 0x13, 0xbd, 0x97, 0x6f, 0x37, 0x0a, 0x0b, 0x2d, 0x88,
+  0x0e, 0xde, 0x67, 0x90, 0xc2, 0xb3, 0xca, 0x20, 0xca, 0x9a, 0x51, 0xf4,
+  0x64, 0x3e, 0xdb, 0xf4, 0x2e, 0x45, 0xf2, 0xc7, 0x47, 0x17, 0xa8, 0xf4,
+  0xfa, 0x90, 0x5a, 0x7f, 0x80, 0xa6, 0x82, 0xac, 0xe4, 0x6c, 0x81, 0x46,
+  0xbb, 0x52, 0x85, 0x20, 0x24, 0xf8, 0x80, 0xea
+};
+unsigned int login_live_com_cer_len = 1520;
diff --git a/sec/Security/Regressions/secitem/si-67-sectrust-blacklist/login.skype.com.cer.h b/sec/Security/Regressions/secitem/si-67-sectrust-blacklist/login.skype.com.cer.h
new file mode 100644 (file)
index 0000000..0ffd13a
--- /dev/null
@@ -0,0 +1,130 @@
+unsigned char login_skype_com_cer[] = {
+  0x30, 0x82, 0x05, 0xef, 0x30, 0x82, 0x04, 0xd7, 0xa0, 0x03, 0x02, 0x01,
+  0x02, 0x02, 0x11, 0x00, 0xe9, 0x02, 0x8b, 0x95, 0x78, 0xe4, 0x15, 0xdc,
+  0x1a, 0x71, 0x0a, 0x2b, 0x88, 0x15, 0x44, 0x47, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
+  0x81, 0x97, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+  0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08,
+  0x13, 0x02, 0x55, 0x54, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04,
+  0x07, 0x13, 0x0e, 0x53, 0x61, 0x6c, 0x74, 0x20, 0x4c, 0x61, 0x6b, 0x65,
+  0x20, 0x43, 0x69, 0x74, 0x79, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55,
+  0x04, 0x0a, 0x13, 0x15, 0x54, 0x68, 0x65, 0x20, 0x55, 0x53, 0x45, 0x52,
+  0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72,
+  0x6b, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x18,
+  0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x75,
+  0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
+  0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x55,
+  0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72, 0x73, 0x74,
+  0x2d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x30, 0x1e, 0x17,
+  0x0d, 0x31, 0x31, 0x30, 0x33, 0x31, 0x35, 0x30, 0x30, 0x30, 0x30, 0x30,
+  0x30, 0x5a, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x33, 0x31, 0x34, 0x32, 0x33,
+  0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xdf, 0x31, 0x0b, 0x30, 0x09,
+  0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0e, 0x30,
+  0x0c, 0x06, 0x03, 0x55, 0x04, 0x11, 0x13, 0x05, 0x33, 0x38, 0x34, 0x37,
+  0x37, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07,
+  0x46, 0x6c, 0x6f, 0x72, 0x69, 0x64, 0x61, 0x31, 0x10, 0x30, 0x0e, 0x06,
+  0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73,
+  0x68, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x09, 0x13, 0x0e,
+  0x53, 0x65, 0x61, 0x20, 0x56, 0x69, 0x6c, 0x6c, 0x61, 0x67, 0x65, 0x20,
+  0x31, 0x30, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+  0x0b, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x4c, 0x74, 0x64, 0x2e,
+  0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x54,
+  0x65, 0x63, 0x68, 0x20, 0x44, 0x65, 0x70, 0x74, 0x2e, 0x31, 0x28, 0x30,
+  0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x48, 0x6f, 0x73, 0x74,
+  0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x47, 0x54, 0x49, 0x20, 0x47, 0x72,
+  0x6f, 0x75, 0x70, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74,
+  0x69, 0x6f, 0x6e, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b,
+  0x13, 0x0b, 0x50, 0x6c, 0x61, 0x74, 0x69, 0x6e, 0x75, 0x6d, 0x53, 0x53,
+  0x4c, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0f,
+  0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x2e, 0x73, 0x6b, 0x79, 0x70, 0x65, 0x2e,
+  0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82,
+  0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00,
+  0xb0, 0x78, 0x99, 0x86, 0x0e, 0xa2, 0x73, 0x23, 0xd4, 0x5a, 0xc3, 0x49,
+  0xeb, 0xb1, 0x36, 0x8c, 0x7c, 0xca, 0x84, 0xae, 0x3c, 0xaf, 0x38, 0x88,
+  0x28, 0x99, 0x8d, 0x2d, 0x58, 0x13, 0xb1, 0x97, 0x78, 0x3e, 0x52, 0x20,
+  0x67, 0xac, 0x5b, 0x73, 0x98, 0x6c, 0x32, 0x55, 0xc9, 0x70, 0xd1, 0xd9,
+  0xaa, 0x15, 0xe8, 0x2e, 0x26, 0x85, 0x81, 0xbc, 0x56, 0xe4, 0xbc, 0x80,
+  0x63, 0xdb, 0x4e, 0xd7, 0xf5, 0x02, 0xbe, 0x51, 0x63, 0x1e, 0x3c, 0xdb,
+  0xdf, 0xd7, 0x00, 0x5d, 0x5a, 0xb9, 0xe5, 0x7b, 0x6a, 0xea, 0x38, 0x20,
+  0xb2, 0x3b, 0xb6, 0xee, 0x75, 0x54, 0x84, 0xf9, 0xa6, 0xca, 0x38, 0x70,
+  0xdd, 0xbf, 0xb0, 0xff, 0xa5, 0x85, 0x5d, 0xb4, 0x41, 0xfe, 0xdd, 0x3d,
+  0xd9, 0x2a, 0xe1, 0x30, 0x43, 0x1a, 0x98, 0x79, 0x93, 0xa0, 0x5f, 0xe0,
+  0x67, 0x6c, 0x95, 0xfa, 0x3e, 0x7a, 0xae, 0x71, 0x7b, 0xe3, 0x6d, 0x88,
+  0x42, 0x3f, 0x25, 0xd4, 0xee, 0xbe, 0x68, 0x68, 0xac, 0xad, 0xac, 0x60,
+  0xe0, 0x20, 0xa3, 0x39, 0x83, 0xb9, 0x5b, 0x28, 0xa3, 0x93, 0x6d, 0xa1,
+  0xbd, 0x76, 0x0a, 0xe3, 0xeb, 0xae, 0x87, 0x27, 0x0e, 0x54, 0x8f, 0xb4,
+  0x48, 0x0c, 0x9a, 0x54, 0xf4, 0x5d, 0x8e, 0x37, 0x50, 0xdc, 0x5e, 0xa4,
+  0x8b, 0x6b, 0x4b, 0xdc, 0xa6, 0xf3, 0x34, 0xbe, 0x77, 0x59, 0x22, 0x88,
+  0xff, 0x19, 0x2b, 0x6d, 0x76, 0x64, 0x73, 0xda, 0x0c, 0x87, 0x07, 0x2b,
+  0x9a, 0x37, 0x3a, 0xd0, 0xe2, 0x8c, 0xf6, 0x36, 0x32, 0x6b, 0x9a, 0x79,
+  0xcc, 0xd2, 0x3b, 0x93, 0x6f, 0x1a, 0x4d, 0x6c, 0xe6, 0xc1, 0x9d, 0x40,
+  0xac, 0x2d, 0x74, 0xc3, 0xbe, 0xea, 0x5c, 0x73, 0x65, 0x01, 0x29, 0xb1,
+  0x2a, 0xbf, 0x70, 0x59, 0xc1, 0xce, 0xc6, 0xc3, 0xa2, 0xc8, 0x45, 0x5f,
+  0xba, 0x67, 0x3d, 0x0f, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01,
+  0xea, 0x30, 0x82, 0x01, 0xe6, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23,
+  0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xa1, 0x72, 0x5f, 0x26, 0x1b, 0x28,
+  0x98, 0x43, 0x95, 0x5d, 0x07, 0x37, 0xd5, 0x85, 0x96, 0x9d, 0x4b, 0xd2,
+  0xc3, 0x45, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
+  0x14, 0xd5, 0x8e, 0x5a, 0x51, 0x13, 0xb4, 0x29, 0x0d, 0x31, 0xb6, 0x1c,
+  0x8d, 0x3e, 0x51, 0x51, 0x31, 0x0a, 0x33, 0xaa, 0x81, 0x30, 0x0e, 0x06,
+  0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05,
+  0xa0, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04,
+  0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16,
+  0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01,
+  0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x46,
+  0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3f, 0x30, 0x3d, 0x30, 0x3b, 0x06,
+  0x0c, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xb2, 0x31, 0x01, 0x02, 0x01, 0x03,
+  0x04, 0x30, 0x2b, 0x30, 0x29, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+  0x07, 0x02, 0x01, 0x16, 0x1d, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f,
+  0x2f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6f,
+  0x64, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x7b,
+  0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x74, 0x30, 0x72, 0x30, 0x38, 0xa0,
+  0x36, 0xa0, 0x34, 0x86, 0x32, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+  0x63, 0x72, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x63, 0x61,
+  0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x55, 0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45,
+  0x52, 0x46, 0x69, 0x72, 0x73, 0x74, 0x2d, 0x48, 0x61, 0x72, 0x64, 0x77,
+  0x61, 0x72, 0x65, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x36, 0xa0, 0x34, 0xa0,
+  0x32, 0x86, 0x30, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72,
+  0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x2e, 0x6e, 0x65, 0x74,
+  0x2f, 0x55, 0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72,
+  0x73, 0x74, 0x2d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x2e,
+  0x63, 0x72, 0x6c, 0x30, 0x71, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+  0x07, 0x01, 0x01, 0x04, 0x65, 0x30, 0x63, 0x30, 0x3b, 0x06, 0x08, 0x2b,
+  0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2f, 0x68, 0x74, 0x74,
+  0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x6f,
+  0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x55, 0x54, 0x4e,
+  0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76,
+  0x65, 0x72, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x24, 0x06, 0x08,
+  0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74,
+  0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x63, 0x6f,
+  0x6d, 0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x2f,
+  0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x28, 0x30, 0x26, 0x82, 0x0f, 0x6c,
+  0x6f, 0x67, 0x69, 0x6e, 0x2e, 0x73, 0x6b, 0x79, 0x70, 0x65, 0x2e, 0x63,
+  0x6f, 0x6d, 0x82, 0x13, 0x77, 0x77, 0x77, 0x2e, 0x6c, 0x6f, 0x67, 0x69,
+  0x6e, 0x2e, 0x73, 0x6b, 0x79, 0x70, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30,
+  0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
+  0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x08, 0xf2, 0x81, 0x75, 0x91,
+  0xbb, 0xce, 0x12, 0x04, 0x18, 0xc2, 0x4d, 0x5a, 0xfb, 0x46, 0x90, 0x0a,
+  0x54, 0x44, 0xf4, 0xf2, 0xdd, 0x07, 0x81, 0xf0, 0x1f, 0xa6, 0x7a, 0x6f,
+  0x9f, 0xcf, 0xb8, 0x0e, 0x2c, 0x4f, 0x9c, 0xc4, 0x9a, 0xf5, 0xa8, 0xf6,
+  0xba, 0xa4, 0xc9, 0x7a, 0x5d, 0xb1, 0xe2, 0x5a, 0xca, 0x3c, 0xfa, 0x60,
+  0xa8, 0x68, 0x3e, 0xcb, 0xba, 0x2d, 0xe2, 0xcd, 0xd6, 0xb6, 0xe4, 0x92,
+  0x3c, 0x69, 0xad, 0x57, 0xea, 0xa8, 0x2f, 0x38, 0x10, 0x84, 0x72, 0xe5,
+  0x68, 0x71, 0xed, 0xbe, 0xeb, 0x6e, 0x18, 0xef, 0x63, 0x7a, 0xbe, 0xe7,
+  0x24, 0xff, 0xc0, 0x63, 0xfd, 0x58, 0x3b, 0x4c, 0x81, 0x92, 0xd8, 0x29,
+  0xab, 0x8e, 0x35, 0x5d, 0xd7, 0xd3, 0x09, 0x6b, 0x85, 0xd3, 0xd5, 0x73,
+  0x05, 0x44, 0xe2, 0xe5, 0xbb, 0x83, 0x53, 0x10, 0xcb, 0xf2, 0xcf, 0xb7,
+  0x6e, 0xe1, 0x69, 0xb7, 0xa1, 0x92, 0x64, 0xc5, 0xcf, 0xcd, 0x82, 0xbb,
+  0x36, 0xa0, 0x38, 0xad, 0xd7, 0x24, 0xdf, 0x53, 0xfc, 0x3f, 0x62, 0xb7,
+  0xb7, 0xd5, 0xc7, 0x57, 0xe3, 0x93, 0x31, 0x70, 0x8e, 0x24, 0x89, 0x86,
+  0xca, 0x63, 0x2b, 0x39, 0xba, 0x5d, 0xd9, 0x6a, 0x60, 0xec, 0xa1, 0x4e,
+  0x8a, 0xfe, 0x53, 0xf8, 0x5e, 0x92, 0xdf, 0x2f, 0x5c, 0x26, 0x17, 0x6d,
+  0x03, 0x7d, 0x02, 0x0f, 0x0f, 0xaa, 0x43, 0x67, 0x6d, 0xb0, 0x62, 0xbf,
+  0x7e, 0x53, 0xdd, 0xcc, 0xec, 0x78, 0x73, 0x95, 0xe5, 0xa5, 0xf6, 0x00,
+  0xa3, 0x04, 0xfd, 0x3f, 0x04, 0x2a, 0xb3, 0x98, 0xc5, 0xb7, 0x03, 0x1c,
+  0xdb, 0xc9, 0x50, 0xab, 0xb0, 0x05, 0x1d, 0x1e, 0xbe, 0x56, 0xb4, 0xcf,
+  0x3e, 0x42, 0x13, 0x94, 0x9e, 0xf9, 0xe7, 0x01, 0x81, 0xa5, 0x78, 0x6f,
+  0x0c, 0x7a, 0x76, 0xac, 0x05, 0x86, 0xec, 0xac, 0xc2, 0x11, 0xac
+};
+unsigned int login_skype_com_cer_len = 1523;
diff --git a/sec/Security/Regressions/secitem/si-67-sectrust-blacklist/login.yahoo.com.1.cer.h b/sec/Security/Regressions/secitem/si-67-sectrust-blacklist/login.yahoo.com.1.cer.h
new file mode 100644 (file)
index 0000000..5c1a3ee
--- /dev/null
@@ -0,0 +1,129 @@
+unsigned char login_yahoo_com_1_cer[] = {
+  0x30, 0x82, 0x05, 0xd9, 0x30, 0x82, 0x04, 0xc1, 0xa0, 0x03, 0x02, 0x01,
+  0x02, 0x02, 0x10, 0x39, 0x2a, 0x43, 0x4f, 0x0e, 0x07, 0xdf, 0x1f, 0x8a,
+  0xa3, 0x05, 0xde, 0x34, 0xe0, 0xc2, 0x29, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81,
+  0x97, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+  0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
+  0x02, 0x55, 0x54, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x07,
+  0x13, 0x0e, 0x53, 0x61, 0x6c, 0x74, 0x20, 0x4c, 0x61, 0x6b, 0x65, 0x20,
+  0x43, 0x69, 0x74, 0x79, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04,
+  0x0a, 0x13, 0x15, 0x54, 0x68, 0x65, 0x20, 0x55, 0x53, 0x45, 0x52, 0x54,
+  0x52, 0x55, 0x53, 0x54, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
+  0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x18, 0x68,
+  0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x75, 0x73,
+  0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x31,
+  0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x55, 0x54,
+  0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72, 0x73, 0x74, 0x2d,
+  0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x30, 0x1e, 0x17, 0x0d,
+  0x31, 0x31, 0x30, 0x33, 0x31, 0x35, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+  0x5a, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x33, 0x31, 0x34, 0x32, 0x33, 0x35,
+  0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xdf, 0x31, 0x0b, 0x30, 0x09, 0x06,
+  0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0e, 0x30, 0x0c,
+  0x06, 0x03, 0x55, 0x04, 0x11, 0x13, 0x05, 0x33, 0x38, 0x34, 0x37, 0x37,
+  0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x46,
+  0x6c, 0x6f, 0x72, 0x69, 0x64, 0x61, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03,
+  0x55, 0x04, 0x07, 0x13, 0x07, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68,
+  0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x09, 0x13, 0x0e, 0x53,
+  0x65, 0x61, 0x20, 0x56, 0x69, 0x6c, 0x6c, 0x61, 0x67, 0x65, 0x20, 0x31,
+  0x30, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b,
+  0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x4c, 0x74, 0x64, 0x2e, 0x31,
+  0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x54, 0x65,
+  0x63, 0x68, 0x20, 0x44, 0x65, 0x70, 0x74, 0x2e, 0x31, 0x28, 0x30, 0x26,
+  0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x48, 0x6f, 0x73, 0x74, 0x65,
+  0x64, 0x20, 0x62, 0x79, 0x20, 0x47, 0x54, 0x49, 0x20, 0x47, 0x72, 0x6f,
+  0x75, 0x70, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69,
+  0x6f, 0x6e, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
+  0x0b, 0x50, 0x6c, 0x61, 0x74, 0x69, 0x6e, 0x75, 0x6d, 0x53, 0x53, 0x4c,
+  0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0f, 0x6c,
+  0x6f, 0x67, 0x69, 0x6e, 0x2e, 0x79, 0x61, 0x68, 0x6f, 0x6f, 0x2e, 0x63,
+  0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
+  0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa1,
+  0xa4, 0x05, 0x3d, 0xed, 0x85, 0x45, 0x93, 0x8a, 0x18, 0x4d, 0xc6, 0x03,
+  0x00, 0x57, 0xe2, 0x40, 0x77, 0xf0, 0x1c, 0xeb, 0xd0, 0x19, 0xdf, 0x22,
+  0x5d, 0x08, 0x7f, 0xd1, 0x07, 0x3c, 0x41, 0x89, 0x46, 0x17, 0xa3, 0x09,
+  0xfa, 0xfc, 0xf8, 0xa9, 0x04, 0xd1, 0x96, 0x8f, 0xab, 0xd7, 0x4f, 0x3c,
+  0xf9, 0xad, 0x18, 0xa9, 0x74, 0x81, 0xc4, 0x57, 0x0a, 0x3a, 0x26, 0x16,
+  0xce, 0x62, 0x3e, 0xbc, 0x3f, 0x6c, 0x21, 0xee, 0x93, 0x8d, 0xcb, 0x0d,
+  0xa0, 0x1f, 0x9a, 0x96, 0xd0, 0x8f, 0xad, 0xf5, 0x93, 0x93, 0x82, 0xee,
+  0x72, 0x0c, 0xa1, 0x75, 0x15, 0xa3, 0x7b, 0x84, 0x56, 0xb8, 0xad, 0xff,
+  0x52, 0x11, 0x71, 0x84, 0xbc, 0x3a, 0x30, 0x0b, 0x7e, 0x98, 0xa8, 0xe1,
+  0xa8, 0x3f, 0x37, 0x52, 0xd0, 0xf1, 0x7c, 0x6f, 0x90, 0xd8, 0x45, 0x0a,
+  0xac, 0x39, 0x72, 0x6a, 0x61, 0xd5, 0xbb, 0xc3, 0x8c, 0xf9, 0xc2, 0xcc,
+  0xdf, 0xfd, 0x3a, 0x71, 0xb9, 0xaf, 0xbc, 0xdc, 0x3a, 0xdc, 0x0c, 0xb6,
+  0xb1, 0xd2, 0xd1, 0x89, 0xbb, 0x41, 0xb6, 0xf2, 0xde, 0x57, 0xd5, 0x15,
+  0xdf, 0xfc, 0xfd, 0xe2, 0x31, 0xc5, 0xdf, 0xca, 0xc1, 0xd8, 0x8f, 0x2c,
+  0xbf, 0xf0, 0x0e, 0x5b, 0x71, 0xe0, 0x34, 0x71, 0xc3, 0xc5, 0x4d, 0x7d,
+  0x7a, 0xd4, 0xfa, 0xed, 0x30, 0x4b, 0x2f, 0xea, 0xb6, 0x2e, 0x9e, 0x93,
+  0x3c, 0xe2, 0x3a, 0xf8, 0x42, 0xa2, 0x1a, 0xee, 0xdc, 0xdf, 0xcd, 0x0f,
+  0xa9, 0xf6, 0x79, 0x84, 0x1a, 0x8e, 0x6c, 0x02, 0xb6, 0x86, 0xe5, 0xbf,
+  0x51, 0x6a, 0x66, 0xf8, 0xf3, 0x9c, 0xd3, 0x59, 0x0c, 0x7b, 0xa5, 0x99,
+  0x78, 0xcd, 0x7c, 0x99, 0xfa, 0xc6, 0x96, 0x47, 0xd8, 0x32, 0xd4, 0x74,
+  0x76, 0x0e, 0x77, 0x4b, 0x20, 0x74, 0xa4, 0xb7, 0x89, 0x75, 0x92, 0x4a,
+  0xb4, 0x5b, 0x55, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0xd5,
+  0x30, 0x82, 0x01, 0xd1, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
+  0x18, 0x30, 0x16, 0x80, 0x14, 0xa1, 0x72, 0x5f, 0x26, 0x1b, 0x28, 0x98,
+  0x43, 0x95, 0x5d, 0x07, 0x37, 0xd5, 0x85, 0x96, 0x9d, 0x4b, 0xd2, 0xc3,
+  0x45, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
+  0x86, 0x49, 0x45, 0xfc, 0x33, 0x19, 0x33, 0xd4, 0x04, 0xed, 0x27, 0x61,
+  0xee, 0xe8, 0x01, 0xc9, 0x0c, 0x7f, 0x2f, 0x7e, 0x30, 0x0e, 0x06, 0x03,
+  0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0,
+  0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02,
+  0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30,
+  0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06,
+  0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x46, 0x06,
+  0x03, 0x55, 0x1d, 0x20, 0x04, 0x3f, 0x30, 0x3d, 0x30, 0x3b, 0x06, 0x0c,
+  0x2b, 0x06, 0x01, 0x04, 0x01, 0xb2, 0x31, 0x01, 0x02, 0x01, 0x03, 0x04,
+  0x30, 0x2b, 0x30, 0x29, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+  0x02, 0x01, 0x16, 0x1d, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f,
+  0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64,
+  0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x7b, 0x06,
+  0x03, 0x55, 0x1d, 0x1f, 0x04, 0x74, 0x30, 0x72, 0x30, 0x38, 0xa0, 0x36,
+  0xa0, 0x34, 0x86, 0x32, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63,
+  0x72, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e,
+  0x63, 0x6f, 0x6d, 0x2f, 0x55, 0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52,
+  0x46, 0x69, 0x72, 0x73, 0x74, 0x2d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61,
+  0x72, 0x65, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x36, 0xa0, 0x34, 0xa0, 0x32,
+  0x86, 0x30, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c,
+  0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x2e, 0x6e, 0x65, 0x74, 0x2f,
+  0x55, 0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72, 0x73,
+  0x74, 0x2d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x2e, 0x63,
+  0x72, 0x6c, 0x30, 0x71, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+  0x01, 0x01, 0x04, 0x65, 0x30, 0x63, 0x30, 0x3b, 0x06, 0x08, 0x2b, 0x06,
+  0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2f, 0x68, 0x74, 0x74, 0x70,
+  0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64,
+  0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x55, 0x54, 0x4e, 0x41,
+  0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65,
+  0x72, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x24, 0x06, 0x08, 0x2b,
+  0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74,
+  0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x63, 0x6f, 0x6d,
+  0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1a, 0x06,
+  0x03, 0x55, 0x1d, 0x11, 0x04, 0x13, 0x30, 0x11, 0x82, 0x0f, 0x6c, 0x6f,
+  0x67, 0x69, 0x6e, 0x2e, 0x79, 0x61, 0x68, 0x6f, 0x6f, 0x2e, 0x63, 0x6f,
+  0x6d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x57, 0x62, 0xe1,
+  0x77, 0xeb, 0xfc, 0x1f, 0xbf, 0x88, 0x53, 0xaf, 0x58, 0xd3, 0xd4, 0xd6,
+  0x6d, 0x67, 0x30, 0x17, 0x40, 0xbe, 0xe0, 0x1f, 0x64, 0xde, 0x87, 0x15,
+  0xcc, 0xe0, 0xa4, 0x56, 0xa9, 0xd1, 0x9f, 0xf9, 0x01, 0xfe, 0x02, 0xb1,
+  0xb1, 0xea, 0xe2, 0x5f, 0xee, 0x71, 0x16, 0x31, 0xf9, 0x08, 0xd5, 0xc2,
+  0xd7, 0x9a, 0x9b, 0xb2, 0x5a, 0x38, 0xd7, 0xa9, 0x7f, 0xe9, 0x87, 0x6b,
+  0x31, 0xf9, 0x0b, 0xac, 0xd9, 0xfd, 0x50, 0x71, 0xe0, 0xdb, 0x82, 0x92,
+  0x0f, 0x81, 0x9c, 0x8d, 0x77, 0xe9, 0xeb, 0x2e, 0xea, 0xd4, 0x23, 0x41,
+  0x87, 0xec, 0x2d, 0xb2, 0x78, 0xb3, 0x8e, 0xb1, 0x67, 0xd2, 0xee, 0x71,
+  0x03, 0x08, 0x12, 0x99, 0xb3, 0x02, 0x29, 0x6f, 0xde, 0x8b, 0xde, 0xc1,
+  0xa9, 0x03, 0x0a, 0x5a, 0x33, 0x1c, 0x3d, 0x11, 0x03, 0xc6, 0x48, 0x0c,
+  0x98, 0x9c, 0x15, 0x2e, 0xd9, 0xa6, 0x85, 0x52, 0xe7, 0x05, 0x8a, 0xae,
+  0x30, 0x23, 0xeb, 0xed, 0x28, 0x6c, 0x60, 0xe9, 0x2d, 0x7f, 0x8f, 0x47,
+  0x8b, 0x2f, 0xd0, 0xdc, 0xe6, 0xbb, 0x0f, 0x7e, 0x5f, 0xf2, 0x48, 0x81,
+  0x8e, 0x50, 0x04, 0x63, 0xb1, 0x51, 0x80, 0x75, 0x9a, 0xa9, 0xb6, 0x10,
+  0x1c, 0x10, 0x5f, 0x6f, 0x18, 0x6f, 0xe0, 0x0e, 0x96, 0x45, 0xce, 0xee,
+  0xf1, 0xb5, 0x20, 0xdb, 0xef, 0xda, 0x6e, 0xc8, 0x95, 0xe3, 0xf6, 0x45,
+  0xfd, 0xca, 0xfc, 0xa5, 0x5f, 0x49, 0x6d, 0x06, 0x1e, 0xd2, 0xde, 0x61,
+  0x3d, 0x15, 0x7d, 0x37, 0xe5, 0x1c, 0x35, 0x8e, 0x06, 0xc2, 0x6b, 0xf7,
+  0xb4, 0xa8, 0x28, 0x2c, 0x31, 0xcb, 0xaa, 0xb4, 0xa7, 0x97, 0x4f, 0x9d,
+  0x8a, 0xf6, 0xaf, 0x7e, 0x37, 0xb9, 0x7b, 0x3d, 0xdf, 0x92, 0x66, 0x8b,
+  0x8f, 0x4e, 0x9d, 0xc6, 0x36, 0xe7, 0x5c, 0xa6, 0xab, 0x12, 0x0f, 0xd6,
+  0xcf
+};
+unsigned int login_yahoo_com_1_cer_len = 1501;
diff --git a/sec/Security/Regressions/secitem/si-67-sectrust-blacklist/login.yahoo.com.2.cer.h b/sec/Security/Regressions/secitem/si-67-sectrust-blacklist/login.yahoo.com.2.cer.h
new file mode 100644 (file)
index 0000000..107dd15
--- /dev/null
@@ -0,0 +1,129 @@
+unsigned char login_yahoo_com_2_cer[] = {
+  0x30, 0x82, 0x05, 0xd9, 0x30, 0x82, 0x04, 0xc1, 0xa0, 0x03, 0x02, 0x01,
+  0x02, 0x02, 0x10, 0x3e, 0x75, 0xce, 0xd4, 0x6b, 0x69, 0x30, 0x21, 0x21,
+  0x88, 0x30, 0xae, 0x86, 0xa8, 0x2a, 0x71, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81,
+  0x97, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+  0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
+  0x02, 0x55, 0x54, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x07,
+  0x13, 0x0e, 0x53, 0x61, 0x6c, 0x74, 0x20, 0x4c, 0x61, 0x6b, 0x65, 0x20,
+  0x43, 0x69, 0x74, 0x79, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04,
+  0x0a, 0x13, 0x15, 0x54, 0x68, 0x65, 0x20, 0x55, 0x53, 0x45, 0x52, 0x54,
+  0x52, 0x55, 0x53, 0x54, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
+  0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x18, 0x68,
+  0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x75, 0x73,
+  0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x31,
+  0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x55, 0x54,
+  0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72, 0x73, 0x74, 0x2d,
+  0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x30, 0x1e, 0x17, 0x0d,
+  0x31, 0x31, 0x30, 0x33, 0x31, 0x35, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+  0x5a, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x33, 0x31, 0x34, 0x32, 0x33, 0x35,
+  0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xdf, 0x31, 0x0b, 0x30, 0x09, 0x06,
+  0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0e, 0x30, 0x0c,
+  0x06, 0x03, 0x55, 0x04, 0x11, 0x13, 0x05, 0x33, 0x38, 0x34, 0x37, 0x37,
+  0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x46,
+  0x6c, 0x6f, 0x72, 0x69, 0x64, 0x61, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03,
+  0x55, 0x04, 0x07, 0x13, 0x07, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68,
+  0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x09, 0x13, 0x0e, 0x53,
+  0x65, 0x61, 0x20, 0x56, 0x69, 0x6c, 0x6c, 0x61, 0x67, 0x65, 0x20, 0x31,
+  0x30, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b,
+  0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x4c, 0x74, 0x64, 0x2e, 0x31,
+  0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x54, 0x65,
+  0x63, 0x68, 0x20, 0x44, 0x65, 0x70, 0x74, 0x2e, 0x31, 0x28, 0x30, 0x26,
+  0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x48, 0x6f, 0x73, 0x74, 0x65,
+  0x64, 0x20, 0x62, 0x79, 0x20, 0x47, 0x54, 0x49, 0x20, 0x47, 0x72, 0x6f,
+  0x75, 0x70, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69,
+  0x6f, 0x6e, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
+  0x0b, 0x50, 0x6c, 0x61, 0x74, 0x69, 0x6e, 0x75, 0x6d, 0x53, 0x53, 0x4c,
+  0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0f, 0x6c,
+  0x6f, 0x67, 0x69, 0x6e, 0x2e, 0x79, 0x61, 0x68, 0x6f, 0x6f, 0x2e, 0x63,
+  0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
+  0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa1,
+  0xa4, 0x05, 0x3d, 0xed, 0x85, 0x45, 0x93, 0x8a, 0x18, 0x4d, 0xc6, 0x03,
+  0x00, 0x57, 0xe2, 0x40, 0x77, 0xf0, 0x1c, 0xeb, 0xd0, 0x19, 0xdf, 0x22,
+  0x5d, 0x08, 0x7f, 0xd1, 0x07, 0x3c, 0x41, 0x89, 0x46, 0x17, 0xa3, 0x09,
+  0xfa, 0xfc, 0xf8, 0xa9, 0x04, 0xd1, 0x96, 0x8f, 0xab, 0xd7, 0x4f, 0x3c,
+  0xf9, 0xad, 0x18, 0xa9, 0x74, 0x81, 0xc4, 0x57, 0x0a, 0x3a, 0x26, 0x16,
+  0xce, 0x62, 0x3e, 0xbc, 0x3f, 0x6c, 0x21, 0xee, 0x93, 0x8d, 0xcb, 0x0d,
+  0xa0, 0x1f, 0x9a, 0x96, 0xd0, 0x8f, 0xad, 0xf5, 0x93, 0x93, 0x82, 0xee,
+  0x72, 0x0c, 0xa1, 0x75, 0x15, 0xa3, 0x7b, 0x84, 0x56, 0xb8, 0xad, 0xff,
+  0x52, 0x11, 0x71, 0x84, 0xbc, 0x3a, 0x30, 0x0b, 0x7e, 0x98, 0xa8, 0xe1,
+  0xa8, 0x3f, 0x37, 0x52, 0xd0, 0xf1, 0x7c, 0x6f, 0x90, 0xd8, 0x45, 0x0a,
+  0xac, 0x39, 0x72, 0x6a, 0x61, 0xd5, 0xbb, 0xc3, 0x8c, 0xf9, 0xc2, 0xcc,
+  0xdf, 0xfd, 0x3a, 0x71, 0xb9, 0xaf, 0xbc, 0xdc, 0x3a, 0xdc, 0x0c, 0xb6,
+  0xb1, 0xd2, 0xd1, 0x89, 0xbb, 0x41, 0xb6, 0xf2, 0xde, 0x57, 0xd5, 0x15,
+  0xdf, 0xfc, 0xfd, 0xe2, 0x31, 0xc5, 0xdf, 0xca, 0xc1, 0xd8, 0x8f, 0x2c,
+  0xbf, 0xf0, 0x0e, 0x5b, 0x71, 0xe0, 0x34, 0x71, 0xc3, 0xc5, 0x4d, 0x7d,
+  0x7a, 0xd4, 0xfa, 0xed, 0x30, 0x4b, 0x2f, 0xea, 0xb6, 0x2e, 0x9e, 0x93,
+  0x3c, 0xe2, 0x3a, 0xf8, 0x42, 0xa2, 0x1a, 0xee, 0xdc, 0xdf, 0xcd, 0x0f,
+  0xa9, 0xf6, 0x79, 0x84, 0x1a, 0x8e, 0x6c, 0x02, 0xb6, 0x86, 0xe5, 0xbf,
+  0x51, 0x6a, 0x66, 0xf8, 0xf3, 0x9c, 0xd3, 0x59, 0x0c, 0x7b, 0xa5, 0x99,
+  0x78, 0xcd, 0x7c, 0x99, 0xfa, 0xc6, 0x96, 0x47, 0xd8, 0x32, 0xd4, 0x74,
+  0x76, 0x0e, 0x77, 0x4b, 0x20, 0x74, 0xa4, 0xb7, 0x89, 0x75, 0x92, 0x4a,
+  0xb4, 0x5b, 0x55, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0xd5,
+  0x30, 0x82, 0x01, 0xd1, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
+  0x18, 0x30, 0x16, 0x80, 0x14, 0xa1, 0x72, 0x5f, 0x26, 0x1b, 0x28, 0x98,
+  0x43, 0x95, 0x5d, 0x07, 0x37, 0xd5, 0x85, 0x96, 0x9d, 0x4b, 0xd2, 0xc3,
+  0x45, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
+  0x86, 0x49, 0x45, 0xfc, 0x33, 0x19, 0x33, 0xd4, 0x04, 0xed, 0x27, 0x61,
+  0xee, 0xe8, 0x01, 0xc9, 0x0c, 0x7f, 0x2f, 0x7e, 0x30, 0x0e, 0x06, 0x03,
+  0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0,
+  0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02,
+  0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30,
+  0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06,
+  0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x46, 0x06,
+  0x03, 0x55, 0x1d, 0x20, 0x04, 0x3f, 0x30, 0x3d, 0x30, 0x3b, 0x06, 0x0c,
+  0x2b, 0x06, 0x01, 0x04, 0x01, 0xb2, 0x31, 0x01, 0x02, 0x01, 0x03, 0x04,
+  0x30, 0x2b, 0x30, 0x29, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+  0x02, 0x01, 0x16, 0x1d, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f,
+  0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64,
+  0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x7b, 0x06,
+  0x03, 0x55, 0x1d, 0x1f, 0x04, 0x74, 0x30, 0x72, 0x30, 0x38, 0xa0, 0x36,
+  0xa0, 0x34, 0x86, 0x32, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63,
+  0x72, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e,
+  0x63, 0x6f, 0x6d, 0x2f, 0x55, 0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52,
+  0x46, 0x69, 0x72, 0x73, 0x74, 0x2d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61,
+  0x72, 0x65, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x36, 0xa0, 0x34, 0xa0, 0x32,
+  0x86, 0x30, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c,
+  0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x2e, 0x6e, 0x65, 0x74, 0x2f,
+  0x55, 0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72, 0x73,
+  0x74, 0x2d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x2e, 0x63,
+  0x72, 0x6c, 0x30, 0x71, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+  0x01, 0x01, 0x04, 0x65, 0x30, 0x63, 0x30, 0x3b, 0x06, 0x08, 0x2b, 0x06,
+  0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2f, 0x68, 0x74, 0x74, 0x70,
+  0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64,
+  0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x55, 0x54, 0x4e, 0x41,
+  0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65,
+  0x72, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x24, 0x06, 0x08, 0x2b,
+  0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74,
+  0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x63, 0x6f, 0x6d,
+  0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1a, 0x06,
+  0x03, 0x55, 0x1d, 0x11, 0x04, 0x13, 0x30, 0x11, 0x82, 0x0f, 0x6c, 0x6f,
+  0x67, 0x69, 0x6e, 0x2e, 0x79, 0x61, 0x68, 0x6f, 0x6f, 0x2e, 0x63, 0x6f,
+  0x6d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x53, 0x69, 0x98,
+  0x8e, 0x28, 0x4e, 0x9c, 0x2b, 0x5b, 0x1d, 0xcc, 0x6b, 0x77, 0x28, 0x3d,
+  0xbb, 0xfa, 0xa5, 0x4e, 0x7e, 0x56, 0x29, 0xa4, 0xea, 0x10, 0xe2, 0xf4,
+  0xe6, 0x2d, 0x06, 0xd1, 0x84, 0xdb, 0x23, 0xce, 0x97, 0xf3, 0x68, 0xb6,
+  0x0f, 0x3a, 0xde, 0x15, 0x0b, 0x24, 0x1d, 0x91, 0xe3, 0x6c, 0x2e, 0x30,
+  0xb7, 0xe9, 0x70, 0xb0, 0xc3, 0x46, 0x80, 0xf0, 0xd3, 0xb1, 0x51, 0xbf,
+  0x4f, 0xd6, 0x78, 0xa0, 0xfc, 0xac, 0xc6, 0xcf, 0x31, 0x04, 0x63, 0xe2,
+  0x34, 0x55, 0x05, 0x4a, 0x3d, 0xf6, 0x30, 0xba, 0xf3, 0x33, 0xe5, 0xba,
+  0xd2, 0x96, 0xf3, 0xd5, 0xb1, 0xb6, 0x93, 0x89, 0x1a, 0xa4, 0x68, 0xbe,
+  0x7e, 0xed, 0x63, 0xb4, 0x1a, 0x48, 0xc0, 0x53, 0xe4, 0xa3, 0xf0, 0x39,
+  0x0c, 0x32, 0x92, 0xc7, 0x43, 0x0d, 0x1a, 0x71, 0xed, 0xd0, 0x46, 0x93,
+  0xbf, 0x93, 0x62, 0x6c, 0x33, 0x4b, 0xcd, 0x36, 0x0d, 0x69, 0x5e, 0xbb,
+  0x6c, 0x96, 0x99, 0x21, 0x69, 0xc4, 0x4b, 0x67, 0x72, 0xdb, 0x6c, 0x6a,
+  0xb8, 0xf7, 0x68, 0xed, 0xc5, 0x8f, 0xad, 0x63, 0x65, 0x95, 0x0a, 0x4c,
+  0xe0, 0xf9, 0x0f, 0x7e, 0x37, 0x3d, 0xaa, 0xd4, 0x93, 0xba, 0x67, 0x09,
+  0xc3, 0xa5, 0xa4, 0x0d, 0x03, 0x5a, 0x6d, 0xd5, 0x0b, 0xfe, 0xf0, 0x40,
+  0x14, 0xb4, 0xf6, 0xb8, 0x69, 0x7c, 0x6d, 0xc2, 0x32, 0x4b, 0x9f, 0xb5,
+  0x1a, 0xe7, 0x46, 0xae, 0x4c, 0x5a, 0x2b, 0xaa, 0x7a, 0x5e, 0x90, 0x57,
+  0x95, 0xfa, 0xdb, 0x66, 0x02, 0x20, 0x1e, 0x6a, 0x69, 0x66, 0x15, 0x9c,
+  0xc2, 0xb6, 0xf5, 0xbc, 0x50, 0xb5, 0xfd, 0x45, 0xc7, 0x1f, 0x68, 0xb4,
+  0x47, 0x59, 0xac, 0xc4, 0x1b, 0x28, 0x93, 0x4e, 0x52, 0x53, 0x12, 0x03,
+  0x58, 0x4b, 0x71, 0x83, 0x9f, 0x66, 0xe6, 0xac, 0x79, 0x48, 0xfe, 0xfe,
+  0x47
+};
+unsigned int login_yahoo_com_2_cer_len = 1501;
diff --git a/sec/Security/Regressions/secitem/si-67-sectrust-blacklist/login.yahoo.com.cer.h b/sec/Security/Regressions/secitem/si-67-sectrust-blacklist/login.yahoo.com.cer.h
new file mode 100644 (file)
index 0000000..4f5ba04
--- /dev/null
@@ -0,0 +1,130 @@
+unsigned char login_yahoo_com_cer[] = {
+  0x30, 0x82, 0x05, 0xef, 0x30, 0x82, 0x04, 0xd7, 0xa0, 0x03, 0x02, 0x01,
+  0x02, 0x02, 0x11, 0x00, 0xd7, 0x55, 0x8f, 0xda, 0xf5, 0xf1, 0x10, 0x5b,
+  0xb2, 0x13, 0x28, 0x2b, 0x70, 0x77, 0x29, 0xa3, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
+  0x81, 0x97, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+  0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08,
+  0x13, 0x02, 0x55, 0x54, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04,
+  0x07, 0x13, 0x0e, 0x53, 0x61, 0x6c, 0x74, 0x20, 0x4c, 0x61, 0x6b, 0x65,
+  0x20, 0x43, 0x69, 0x74, 0x79, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55,
+  0x04, 0x0a, 0x13, 0x15, 0x54, 0x68, 0x65, 0x20, 0x55, 0x53, 0x45, 0x52,
+  0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72,
+  0x6b, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x18,
+  0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x75,
+  0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
+  0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x55,
+  0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72, 0x73, 0x74,
+  0x2d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x30, 0x1e, 0x17,
+  0x0d, 0x31, 0x31, 0x30, 0x33, 0x31, 0x35, 0x30, 0x30, 0x30, 0x30, 0x30,
+  0x30, 0x5a, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x33, 0x31, 0x34, 0x32, 0x33,
+  0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xdf, 0x31, 0x0b, 0x30, 0x09,
+  0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0e, 0x30,
+  0x0c, 0x06, 0x03, 0x55, 0x04, 0x11, 0x13, 0x05, 0x33, 0x38, 0x34, 0x37,
+  0x37, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07,
+  0x46, 0x6c, 0x6f, 0x72, 0x69, 0x64, 0x61, 0x31, 0x10, 0x30, 0x0e, 0x06,
+  0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73,
+  0x68, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x09, 0x13, 0x0e,
+  0x53, 0x65, 0x61, 0x20, 0x56, 0x69, 0x6c, 0x6c, 0x61, 0x67, 0x65, 0x20,
+  0x31, 0x30, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+  0x0b, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x4c, 0x74, 0x64, 0x2e,
+  0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x54,
+  0x65, 0x63, 0x68, 0x20, 0x44, 0x65, 0x70, 0x74, 0x2e, 0x31, 0x28, 0x30,
+  0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x48, 0x6f, 0x73, 0x74,
+  0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x47, 0x54, 0x49, 0x20, 0x47, 0x72,
+  0x6f, 0x75, 0x70, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74,
+  0x69, 0x6f, 0x6e, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b,
+  0x13, 0x0b, 0x50, 0x6c, 0x61, 0x74, 0x69, 0x6e, 0x75, 0x6d, 0x53, 0x53,
+  0x4c, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0f,
+  0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x2e, 0x79, 0x61, 0x68, 0x6f, 0x6f, 0x2e,
+  0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82,
+  0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00,
+  0xa1, 0xa4, 0x05, 0x3d, 0xed, 0x85, 0x45, 0x93, 0x8a, 0x18, 0x4d, 0xc6,
+  0x03, 0x00, 0x57, 0xe2, 0x40, 0x77, 0xf0, 0x1c, 0xeb, 0xd0, 0x19, 0xdf,
+  0x22, 0x5d, 0x08, 0x7f, 0xd1, 0x07, 0x3c, 0x41, 0x89, 0x46, 0x17, 0xa3,
+  0x09, 0xfa, 0xfc, 0xf8, 0xa9, 0x04, 0xd1, 0x96, 0x8f, 0xab, 0xd7, 0x4f,
+  0x3c, 0xf9, 0xad, 0x18, 0xa9, 0x74, 0x81, 0xc4, 0x57, 0x0a, 0x3a, 0x26,
+  0x16, 0xce, 0x62, 0x3e, 0xbc, 0x3f, 0x6c, 0x21, 0xee, 0x93, 0x8d, 0xcb,
+  0x0d, 0xa0, 0x1f, 0x9a, 0x96, 0xd0, 0x8f, 0xad, 0xf5, 0x93, 0x93, 0x82,
+  0xee, 0x72, 0x0c, 0xa1, 0x75, 0x15, 0xa3, 0x7b, 0x84, 0x56, 0xb8, 0xad,
+  0xff, 0x52, 0x11, 0x71, 0x84, 0xbc, 0x3a, 0x30, 0x0b, 0x7e, 0x98, 0xa8,
+  0xe1, 0xa8, 0x3f, 0x37, 0x52, 0xd0, 0xf1, 0x7c, 0x6f, 0x90, 0xd8, 0x45,
+  0x0a, 0xac, 0x39, 0x72, 0x6a, 0x61, 0xd5, 0xbb, 0xc3, 0x8c, 0xf9, 0xc2,
+  0xcc, 0xdf, 0xfd, 0x3a, 0x71, 0xb9, 0xaf, 0xbc, 0xdc, 0x3a, 0xdc, 0x0c,
+  0xb6, 0xb1, 0xd2, 0xd1, 0x89, 0xbb, 0x41, 0xb6, 0xf2, 0xde, 0x57, 0xd5,
+  0x15, 0xdf, 0xfc, 0xfd, 0xe2, 0x31, 0xc5, 0xdf, 0xca, 0xc1, 0xd8, 0x8f,
+  0x2c, 0xbf, 0xf0, 0x0e, 0x5b, 0x71, 0xe0, 0x34, 0x71, 0xc3, 0xc5, 0x4d,
+  0x7d, 0x7a, 0xd4, 0xfa, 0xed, 0x30, 0x4b, 0x2f, 0xea, 0xb6, 0x2e, 0x9e,
+  0x93, 0x3c, 0xe2, 0x3a, 0xf8, 0x42, 0xa2, 0x1a, 0xee, 0xdc, 0xdf, 0xcd,
+  0x0f, 0xa9, 0xf6, 0x79, 0x84, 0x1a, 0x8e, 0x6c, 0x02, 0xb6, 0x86, 0xe5,
+  0xbf, 0x51, 0x6a, 0x66, 0xf8, 0xf3, 0x9c, 0xd3, 0x59, 0x0c, 0x7b, 0xa5,
+  0x99, 0x78, 0xcd, 0x7c, 0x99, 0xfa, 0xc6, 0x96, 0x47, 0xd8, 0x32, 0xd4,
+  0x74, 0x76, 0x0e, 0x77, 0x4b, 0x20, 0x74, 0xa4, 0xb7, 0x89, 0x75, 0x92,
+  0x4a, 0xb4, 0x5b, 0x55, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01,
+  0xea, 0x30, 0x82, 0x01, 0xe6, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23,
+  0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xa1, 0x72, 0x5f, 0x26, 0x1b, 0x28,
+  0x98, 0x43, 0x95, 0x5d, 0x07, 0x37, 0xd5, 0x85, 0x96, 0x9d, 0x4b, 0xd2,
+  0xc3, 0x45, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
+  0x14, 0x86, 0x49, 0x45, 0xfc, 0x33, 0x19, 0x33, 0xd4, 0x04, 0xed, 0x27,
+  0x61, 0xee, 0xe8, 0x01, 0xc9, 0x0c, 0x7f, 0x2f, 0x7e, 0x30, 0x0e, 0x06,
+  0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05,
+  0xa0, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04,
+  0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16,
+  0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01,
+  0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x46,
+  0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3f, 0x30, 0x3d, 0x30, 0x3b, 0x06,
+  0x0c, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xb2, 0x31, 0x01, 0x02, 0x01, 0x03,
+  0x04, 0x30, 0x2b, 0x30, 0x29, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+  0x07, 0x02, 0x01, 0x16, 0x1d, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f,
+  0x2f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6f,
+  0x64, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x7b,
+  0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x74, 0x30, 0x72, 0x30, 0x38, 0xa0,
+  0x36, 0xa0, 0x34, 0x86, 0x32, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+  0x63, 0x72, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x63, 0x61,
+  0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x55, 0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45,
+  0x52, 0x46, 0x69, 0x72, 0x73, 0x74, 0x2d, 0x48, 0x61, 0x72, 0x64, 0x77,
+  0x61, 0x72, 0x65, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x36, 0xa0, 0x34, 0xa0,
+  0x32, 0x86, 0x30, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72,
+  0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x2e, 0x6e, 0x65, 0x74,
+  0x2f, 0x55, 0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72,
+  0x73, 0x74, 0x2d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x2e,
+  0x63, 0x72, 0x6c, 0x30, 0x71, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+  0x07, 0x01, 0x01, 0x04, 0x65, 0x30, 0x63, 0x30, 0x3b, 0x06, 0x08, 0x2b,
+  0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2f, 0x68, 0x74, 0x74,
+  0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x6f,
+  0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x55, 0x54, 0x4e,
+  0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76,
+  0x65, 0x72, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x24, 0x06, 0x08,
+  0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74,
+  0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x63, 0x6f,
+  0x6d, 0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x2f,
+  0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x28, 0x30, 0x26, 0x82, 0x0f, 0x6c,
+  0x6f, 0x67, 0x69, 0x6e, 0x2e, 0x79, 0x61, 0x68, 0x6f, 0x6f, 0x2e, 0x63,
+  0x6f, 0x6d, 0x82, 0x13, 0x77, 0x77, 0x77, 0x2e, 0x6c, 0x6f, 0x67, 0x69,
+  0x6e, 0x2e, 0x79, 0x61, 0x68, 0x6f, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x30,
+  0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
+  0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x3d, 0x57, 0xc9, 0x48, 0x24,
+  0x5c, 0xee, 0x64, 0x81, 0xf5, 0xae, 0xbe, 0x55, 0x29, 0x16, 0xff, 0x2a,
+  0x2f, 0x84, 0xed, 0xd9, 0xf8, 0xa3, 0x03, 0xc8, 0x30, 0x66, 0xbb, 0xc8,
+  0xd4, 0x81, 0x2d, 0x21, 0xf7, 0x08, 0xf7, 0xac, 0x96, 0x42, 0x9a, 0x41,
+  0x75, 0x7a, 0xba, 0x5d, 0x10, 0x23, 0xcb, 0x92, 0x42, 0x61, 0xfa, 0x8a,
+  0xda, 0x6d, 0x65, 0x34, 0x19, 0xe5, 0xa9, 0xd6, 0x2d, 0x13, 0x78, 0xd7,
+  0x81, 0x44, 0x92, 0xa9, 0x6e, 0x80, 0x63, 0x15, 0xcb, 0xfe, 0x35, 0x1f,
+  0x02, 0xd1, 0x8a, 0x14, 0xb0, 0xa8, 0xcc, 0x94, 0x20, 0x3b, 0xa8, 0x1a,
+  0xf0, 0x5d, 0x36, 0x50, 0xdb, 0x0d, 0xae, 0xe9, 0x64, 0xe4, 0xf6, 0x8d,
+  0x69, 0x7d, 0x30, 0xc8, 0x14, 0x17, 0x00, 0x4a, 0xe5, 0xa6, 0x35, 0xfb,
+  0x7d, 0x0d, 0x22, 0x9d, 0x79, 0x76, 0x52, 0x2c, 0xbc, 0x97, 0x06, 0x88,
+  0x9a, 0x15, 0xf4, 0x73, 0xe6, 0xf1, 0xf5, 0x98, 0xa5, 0xcd, 0x07, 0x44,
+  0x91, 0xb8, 0xa7, 0x68, 0x67, 0x45, 0xd2, 0x72, 0x11, 0x60, 0xe2, 0x71,
+  0xb7, 0x50, 0x55, 0xe2, 0x8a, 0xa9, 0x0d, 0xd6, 0x92, 0xee, 0x04, 0x2a,
+  0x8b, 0x30, 0xa0, 0xa2, 0x05, 0x46, 0x34, 0x6d, 0x92, 0xc6, 0x3b, 0xaa,
+  0x4d, 0xa0, 0xd0, 0xab, 0x01, 0x19, 0x0a, 0x32, 0xb7, 0xe8, 0xe3, 0xcf,
+  0xf1, 0xd2, 0x97, 0x49, 0x7b, 0xac, 0xa4, 0x97, 0xf7, 0xf0, 0x57, 0xae,
+  0x63, 0x77, 0x9a, 0x7f, 0x96, 0xda, 0x4d, 0xfd, 0xbe, 0xdc, 0x07, 0x36,
+  0xe3, 0x25, 0xbd, 0x89, 0x79, 0x8e, 0x29, 0x12, 0x13, 0x8b, 0x88, 0x07,
+  0xfb, 0x6b, 0xdb, 0xa4, 0xcd, 0xb3, 0x2d, 0x27, 0xe9, 0xd4, 0xca, 0x60,
+  0xd7, 0x85, 0x53, 0xfb, 0x74, 0xc6, 0x5c, 0x35, 0x8c, 0x70, 0x1f, 0xf9,
+  0xb2, 0xb7, 0x92, 0x27, 0x20, 0xc7, 0x94, 0xd5, 0x67, 0x14, 0x30
+};
+unsigned int login_yahoo_com_cer_len = 1523;
diff --git a/sec/Security/Regressions/secitem/si-67-sectrust-blacklist/mail.google.com.cer.h b/sec/Security/Regressions/secitem/si-67-sectrust-blacklist/mail.google.com.cer.h
new file mode 100644 (file)
index 0000000..21f5c08
--- /dev/null
@@ -0,0 +1,130 @@
+unsigned char mail_google_com_cer[] = {
+  0x30, 0x82, 0x05, 0xee, 0x30, 0x82, 0x04, 0xd6, 0xa0, 0x03, 0x02, 0x01,
+  0x02, 0x02, 0x10, 0x04, 0x7e, 0xcb, 0xe9, 0xfc, 0xa5, 0x5f, 0x7b, 0xd0,
+  0x9e, 0xae, 0x36, 0xe1, 0x0c, 0xae, 0x1e, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81,
+  0x97, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+  0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
+  0x02, 0x55, 0x54, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x07,
+  0x13, 0x0e, 0x53, 0x61, 0x6c, 0x74, 0x20, 0x4c, 0x61, 0x6b, 0x65, 0x20,
+  0x43, 0x69, 0x74, 0x79, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04,
+  0x0a, 0x13, 0x15, 0x54, 0x68, 0x65, 0x20, 0x55, 0x53, 0x45, 0x52, 0x54,
+  0x52, 0x55, 0x53, 0x54, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
+  0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x18, 0x68,
+  0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x75, 0x73,
+  0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x31,
+  0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x55, 0x54,
+  0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72, 0x73, 0x74, 0x2d,
+  0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x30, 0x1e, 0x17, 0x0d,
+  0x31, 0x31, 0x30, 0x33, 0x31, 0x35, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+  0x5a, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x33, 0x31, 0x34, 0x32, 0x33, 0x35,
+  0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xdf, 0x31, 0x0b, 0x30, 0x09, 0x06,
+  0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0e, 0x30, 0x0c,
+  0x06, 0x03, 0x55, 0x04, 0x11, 0x13, 0x05, 0x33, 0x38, 0x34, 0x37, 0x37,
+  0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x46,
+  0x6c, 0x6f, 0x72, 0x69, 0x64, 0x61, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03,
+  0x55, 0x04, 0x07, 0x13, 0x07, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68,
+  0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x09, 0x13, 0x0e, 0x53,
+  0x65, 0x61, 0x20, 0x56, 0x69, 0x6c, 0x6c, 0x61, 0x67, 0x65, 0x20, 0x31,
+  0x30, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b,
+  0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x4c, 0x74, 0x64, 0x2e, 0x31,
+  0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x54, 0x65,
+  0x63, 0x68, 0x20, 0x44, 0x65, 0x70, 0x74, 0x2e, 0x31, 0x28, 0x30, 0x26,
+  0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x48, 0x6f, 0x73, 0x74, 0x65,
+  0x64, 0x20, 0x62, 0x79, 0x20, 0x47, 0x54, 0x49, 0x20, 0x47, 0x72, 0x6f,
+  0x75, 0x70, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69,
+  0x6f, 0x6e, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
+  0x0b, 0x50, 0x6c, 0x61, 0x74, 0x69, 0x6e, 0x75, 0x6d, 0x53, 0x53, 0x4c,
+  0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0f, 0x6d,
+  0x61, 0x69, 0x6c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63,
+  0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
+  0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb0,
+  0x73, 0xf0, 0xf2, 0x04, 0xee, 0xc2, 0xa2, 0x46, 0xca, 0x34, 0x2a, 0xaa,
+  0xbb, 0x60, 0x23, 0xd1, 0x11, 0x76, 0x1f, 0x1f, 0x3a, 0xd0, 0x65, 0x83,
+  0x4e, 0x9a, 0x45, 0xa8, 0x43, 0x70, 0x85, 0x76, 0xf0, 0x1f, 0x87, 0x00,
+  0x02, 0x1f, 0x6e, 0x3b, 0x17, 0x17, 0xc4, 0xb5, 0xe9, 0x19, 0x46, 0xa2,
+  0x92, 0x25, 0x8d, 0x62, 0x2a, 0xb4, 0x63, 0x30, 0x1f, 0xb9, 0x85, 0xf8,
+  0x35, 0xe1, 0x16, 0x5a, 0x76, 0x49, 0xcc, 0x50, 0x48, 0x53, 0x39, 0x59,
+  0x89, 0xd6, 0x84, 0x02, 0xfb, 0x9a, 0xec, 0x1b, 0xc7, 0x51, 0xd5, 0x76,
+  0x95, 0x90, 0xd4, 0x3a, 0x2a, 0xb8, 0xa6, 0xde, 0x02, 0x4d, 0x06, 0xfb,
+  0xcd, 0xed, 0xa5, 0x46, 0x41, 0x5f, 0x55, 0x74, 0xe5, 0xec, 0x7e, 0x40,
+  0xdc, 0x50, 0x9c, 0xb5, 0xe4, 0x35, 0x5d, 0x1e, 0x68, 0x20, 0xf8, 0xe9,
+  0xde, 0xa3, 0x6a, 0x28, 0xbf, 0x41, 0xd2, 0xa1, 0xb3, 0xe2, 0x25, 0x8d,
+  0x0c, 0x1b, 0xca, 0x3d, 0x93, 0x0c, 0x18, 0xae, 0xdf, 0xc5, 0xbc, 0xfd,
+  0xbc, 0x82, 0xba, 0x68, 0x00, 0xd7, 0x16, 0x32, 0x71, 0x9f, 0x65, 0xb5,
+  0x11, 0xda, 0x68, 0x59, 0xd0, 0xa6, 0x57, 0x64, 0x1b, 0xc9, 0xfe, 0x98,
+  0xe5, 0xf5, 0xa5, 0x65, 0xea, 0xe1, 0xdb, 0xee, 0xf4, 0xb3, 0x9d, 0xb3,
+  0x8e, 0xea, 0x87, 0xae, 0x16, 0xd2, 0x1e, 0xa0, 0x7c, 0x7c, 0x69, 0x3f,
+  0x29, 0x16, 0x85, 0x01, 0x53, 0xa7, 0x6c, 0xf1, 0x60, 0xab, 0xdd, 0xa2,
+  0xfc, 0x25, 0x47, 0xd4, 0x32, 0xd1, 0x12, 0xdd, 0xf7, 0x48, 0x12, 0xe0,
+  0xfc, 0x9c, 0xa2, 0x77, 0x98, 0xe9, 0x89, 0x99, 0xb8, 0xf8, 0x38, 0xf1,
+  0x8c, 0x06, 0xc2, 0x7a, 0x23, 0x36, 0x6d, 0x9b, 0x9d, 0xcd, 0x30, 0xc8,
+  0xc7, 0x34, 0x17, 0x1e, 0xbb, 0x7d, 0x42, 0xc8, 0xab, 0xe7, 0x15, 0x16,
+  0xf6, 0x73, 0xb5, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0xea,
+  0x30, 0x82, 0x01, 0xe6, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
+  0x18, 0x30, 0x16, 0x80, 0x14, 0xa1, 0x72, 0x5f, 0x26, 0x1b, 0x28, 0x98,
+  0x43, 0x95, 0x5d, 0x07, 0x37, 0xd5, 0x85, 0x96, 0x9d, 0x4b, 0xd2, 0xc3,
+  0x45, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
+  0x18, 0x2a, 0xa2, 0xc8, 0xd4, 0x7a, 0x3f, 0x7b, 0xad, 0x04, 0x8b, 0xbd,
+  0x6f, 0x9e, 0x10, 0x46, 0x13, 0x78, 0x71, 0x9d, 0x30, 0x0e, 0x06, 0x03,
+  0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0,
+  0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02,
+  0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30,
+  0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06,
+  0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x46, 0x06,
+  0x03, 0x55, 0x1d, 0x20, 0x04, 0x3f, 0x30, 0x3d, 0x30, 0x3b, 0x06, 0x0c,
+  0x2b, 0x06, 0x01, 0x04, 0x01, 0xb2, 0x31, 0x01, 0x02, 0x01, 0x03, 0x04,
+  0x30, 0x2b, 0x30, 0x29, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+  0x02, 0x01, 0x16, 0x1d, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f,
+  0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64,
+  0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x7b, 0x06,
+  0x03, 0x55, 0x1d, 0x1f, 0x04, 0x74, 0x30, 0x72, 0x30, 0x38, 0xa0, 0x36,
+  0xa0, 0x34, 0x86, 0x32, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63,
+  0x72, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e,
+  0x63, 0x6f, 0x6d, 0x2f, 0x55, 0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52,
+  0x46, 0x69, 0x72, 0x73, 0x74, 0x2d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61,
+  0x72, 0x65, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x36, 0xa0, 0x34, 0xa0, 0x32,
+  0x86, 0x30, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c,
+  0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x2e, 0x6e, 0x65, 0x74, 0x2f,
+  0x55, 0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72, 0x73,
+  0x74, 0x2d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x2e, 0x63,
+  0x72, 0x6c, 0x30, 0x71, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+  0x01, 0x01, 0x04, 0x65, 0x30, 0x63, 0x30, 0x3b, 0x06, 0x08, 0x2b, 0x06,
+  0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2f, 0x68, 0x74, 0x74, 0x70,
+  0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64,
+  0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x55, 0x54, 0x4e, 0x41,
+  0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65,
+  0x72, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x24, 0x06, 0x08, 0x2b,
+  0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74,
+  0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x63, 0x6f, 0x6d,
+  0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x2f, 0x06,
+  0x03, 0x55, 0x1d, 0x11, 0x04, 0x28, 0x30, 0x26, 0x82, 0x0f, 0x6d, 0x61,
+  0x69, 0x6c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
+  0x6d, 0x82, 0x13, 0x77, 0x77, 0x77, 0x2e, 0x6d, 0x61, 0x69, 0x6c, 0x2e,
+  0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x0d,
+  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
+  0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x67, 0x06, 0x08, 0x0a, 0x27, 0xc5,
+  0x93, 0x6e, 0x02, 0xf2, 0xde, 0x17, 0x3f, 0xd0, 0xd3, 0x1b, 0x7c, 0xff,
+  0xb5, 0xcd, 0x7a, 0xc7, 0x77, 0xc7, 0xbe, 0xdf, 0x12, 0xca, 0x19, 0xde,
+  0xb0, 0x13, 0x57, 0x0c, 0x03, 0x91, 0xc4, 0x79, 0x52, 0xcf, 0x7f, 0xb7,
+  0x5e, 0x55, 0x20, 0x84, 0x49, 0xdd, 0xf5, 0xd0, 0x29, 0x2f, 0x0e, 0x04,
+  0xda, 0x59, 0x9e, 0x0e, 0x13, 0x9f, 0xf4, 0xc0, 0x32, 0x9b, 0xff, 0xa1,
+  0x11, 0x24, 0x2a, 0x97, 0xa3, 0xf2, 0x3f, 0x3d, 0x2a, 0x6b, 0xa8, 0xad,
+  0x8c, 0x19, 0x75, 0x95, 0x0e, 0x1d, 0x25, 0xfd, 0x4f, 0xc4, 0x7a, 0x15,
+  0xc3, 0x1d, 0xc7, 0x13, 0x40, 0xc8, 0x0d, 0xbe, 0x97, 0x60, 0x72, 0xa6,
+  0xfe, 0x25, 0xbe, 0x8f, 0xec, 0xd5, 0xa6, 0x86, 0xc3, 0x21, 0x5c, 0x59,
+  0x52, 0xd9, 0x6a, 0x0b, 0x5c, 0x9f, 0x4b, 0xde, 0xb5, 0xf9, 0xec, 0xe2,
+  0xf4, 0xc5, 0xcc, 0x62, 0x53, 0x76, 0x89, 0x65, 0xe4, 0x29, 0xda, 0xb7,
+  0xbf, 0x96, 0xe0, 0x60, 0x8d, 0x0d, 0xb7, 0x09, 0x55, 0xd6, 0x40, 0x55,
+  0x1d, 0xc1, 0xf2, 0x96, 0x21, 0x75, 0xaf, 0x89, 0x86, 0x1f, 0x5d, 0x81,
+  0x97, 0x29, 0x28, 0x1e, 0x29, 0xd7, 0x96, 0xc1, 0x20, 0x03, 0x32, 0x7b,
+  0x00, 0x3b, 0x6a, 0x37, 0x17, 0x5a, 0xa3, 0xb3, 0x1a, 0x6f, 0x32, 0x3b,
+  0x6e, 0xf1, 0xa3, 0x5d, 0xab, 0xab, 0xcc, 0x2a, 0xcb, 0x30, 0x0c, 0x1f,
+  0x35, 0x23, 0x8b, 0x69, 0x44, 0x5c, 0xea, 0xac, 0x28, 0x60, 0xed, 0xab,
+  0x6b, 0x63, 0x9e, 0xf6, 0x92, 0xbc, 0xbd, 0x9a, 0x5a, 0x26, 0x4c, 0xc5,
+  0x98, 0xb8, 0x0e, 0x19, 0x3e, 0xfc, 0x05, 0x31, 0xe3, 0x16, 0xd9, 0xfd,
+  0x90, 0x05, 0x03, 0x86, 0xc6, 0x57, 0x01, 0x1f, 0x7f, 0x78, 0xa0, 0xcf,
+  0x33, 0x6a, 0xaa, 0x66, 0x6b, 0x22, 0xd0, 0xa7, 0x49, 0x23
+};
+unsigned int mail_google_com_cer_len = 1522;
diff --git a/sec/Security/Regressions/secitem/si-67-sectrust-blacklist/www.google.com.cer.h b/sec/Security/Regressions/secitem/si-67-sectrust-blacklist/www.google.com.cer.h
new file mode 100644 (file)
index 0000000..0754b97
--- /dev/null
@@ -0,0 +1,129 @@
+unsigned char www_google_com_cer[] = {
+  0x30, 0x82, 0x05, 0xe4, 0x30, 0x82, 0x04, 0xcc, 0xa0, 0x03, 0x02, 0x01,
+  0x02, 0x02, 0x11, 0x00, 0xf5, 0xc8, 0x6a, 0xf3, 0x61, 0x62, 0xf1, 0x3a,
+  0x64, 0xf5, 0x4f, 0x6d, 0xc9, 0x58, 0x7c, 0x06, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
+  0x81, 0x97, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+  0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08,
+  0x13, 0x02, 0x55, 0x54, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04,
+  0x07, 0x13, 0x0e, 0x53, 0x61, 0x6c, 0x74, 0x20, 0x4c, 0x61, 0x6b, 0x65,
+  0x20, 0x43, 0x69, 0x74, 0x79, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55,
+  0x04, 0x0a, 0x13, 0x15, 0x54, 0x68, 0x65, 0x20, 0x55, 0x53, 0x45, 0x52,
+  0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72,
+  0x6b, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x18,
+  0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x75,
+  0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
+  0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x55,
+  0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72, 0x73, 0x74,
+  0x2d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x30, 0x1e, 0x17,
+  0x0d, 0x31, 0x31, 0x30, 0x33, 0x31, 0x35, 0x30, 0x30, 0x30, 0x30, 0x30,
+  0x30, 0x5a, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x33, 0x31, 0x34, 0x32, 0x33,
+  0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xde, 0x31, 0x0b, 0x30, 0x09,
+  0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0e, 0x30,
+  0x0c, 0x06, 0x03, 0x55, 0x04, 0x11, 0x13, 0x05, 0x33, 0x38, 0x34, 0x37,
+  0x37, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07,
+  0x46, 0x6c, 0x6f, 0x72, 0x69, 0x64, 0x61, 0x31, 0x10, 0x30, 0x0e, 0x06,
+  0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73,
+  0x68, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x09, 0x13, 0x0e,
+  0x53, 0x65, 0x61, 0x20, 0x56, 0x69, 0x6c, 0x6c, 0x61, 0x67, 0x65, 0x20,
+  0x31, 0x30, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+  0x0b, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x4c, 0x74, 0x64, 0x2e,
+  0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x54,
+  0x65, 0x63, 0x68, 0x20, 0x44, 0x65, 0x70, 0x74, 0x2e, 0x31, 0x28, 0x30,
+  0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x48, 0x6f, 0x73, 0x74,
+  0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x47, 0x54, 0x49, 0x20, 0x47, 0x72,
+  0x6f, 0x75, 0x70, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74,
+  0x69, 0x6f, 0x6e, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b,
+  0x13, 0x0b, 0x50, 0x6c, 0x61, 0x74, 0x69, 0x6e, 0x75, 0x6d, 0x53, 0x53,
+  0x4c, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0e,
+  0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63,
+  0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
+  0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb0,
+  0x73, 0xf0, 0xf2, 0x04, 0xee, 0xc2, 0xa2, 0x46, 0xca, 0x34, 0x2a, 0xaa,
+  0xbb, 0x60, 0x23, 0xd1, 0x11, 0x76, 0x1f, 0x1f, 0x3a, 0xd0, 0x65, 0x83,
+  0x4e, 0x9a, 0x45, 0xa8, 0x43, 0x70, 0x85, 0x76, 0xf0, 0x1f, 0x87, 0x00,
+  0x02, 0x1f, 0x6e, 0x3b, 0x17, 0x17, 0xc4, 0xb5, 0xe9, 0x19, 0x46, 0xa2,
+  0x92, 0x25, 0x8d, 0x62, 0x2a, 0xb4, 0x63, 0x30, 0x1f, 0xb9, 0x85, 0xf8,
+  0x35, 0xe1, 0x16, 0x5a, 0x76, 0x49, 0xcc, 0x50, 0x48, 0x53, 0x39, 0x59,
+  0x89, 0xd6, 0x84, 0x02, 0xfb, 0x9a, 0xec, 0x1b, 0xc7, 0x51, 0xd5, 0x76,
+  0x95, 0x90, 0xd4, 0x3a, 0x2a, 0xb8, 0xa6, 0xde, 0x02, 0x4d, 0x06, 0xfb,
+  0xcd, 0xed, 0xa5, 0x46, 0x41, 0x5f, 0x55, 0x74, 0xe5, 0xec, 0x7e, 0x40,
+  0xdc, 0x50, 0x9c, 0xb5, 0xe4, 0x35, 0x5d, 0x1e, 0x68, 0x20, 0xf8, 0xe9,
+  0xde, 0xa3, 0x6a, 0x28, 0xbf, 0x41, 0xd2, 0xa1, 0xb3, 0xe2, 0x25, 0x8d,
+  0x0c, 0x1b, 0xca, 0x3d, 0x93, 0x0c, 0x18, 0xae, 0xdf, 0xc5, 0xbc, 0xfd,
+  0xbc, 0x82, 0xba, 0x68, 0x00, 0xd7, 0x16, 0x32, 0x71, 0x9f, 0x65, 0xb5,
+  0x11, 0xda, 0x68, 0x59, 0xd0, 0xa6, 0x57, 0x64, 0x1b, 0xc9, 0xfe, 0x98,
+  0xe5, 0xf5, 0xa5, 0x65, 0xea, 0xe1, 0xdb, 0xee, 0xf4, 0xb3, 0x9d, 0xb3,
+  0x8e, 0xea, 0x87, 0xae, 0x16, 0xd2, 0x1e, 0xa0, 0x7c, 0x7c, 0x69, 0x3f,
+  0x29, 0x16, 0x85, 0x01, 0x53, 0xa7, 0x6c, 0xf1, 0x60, 0xab, 0xdd, 0xa2,
+  0xfc, 0x25, 0x47, 0xd4, 0x32, 0xd1, 0x12, 0xdd, 0xf7, 0x48, 0x12, 0xe0,
+  0xfc, 0x9c, 0xa2, 0x77, 0x98, 0xe9, 0x89, 0x99, 0xb8, 0xf8, 0x38, 0xf1,
+  0x8c, 0x06, 0xc2, 0x7a, 0x23, 0x36, 0x6d, 0x9b, 0x9d, 0xcd, 0x30, 0xc8,
+  0xc7, 0x34, 0x17, 0x1e, 0xbb, 0x7d, 0x42, 0xc8, 0xab, 0xe7, 0x15, 0x16,
+  0xf6, 0x73, 0xb5, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0xe0,
+  0x30, 0x82, 0x01, 0xdc, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
+  0x18, 0x30, 0x16, 0x80, 0x14, 0xa1, 0x72, 0x5f, 0x26, 0x1b, 0x28, 0x98,
+  0x43, 0x95, 0x5d, 0x07, 0x37, 0xd5, 0x85, 0x96, 0x9d, 0x4b, 0xd2, 0xc3,
+  0x45, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
+  0x18, 0x2a, 0xa2, 0xc8, 0xd4, 0x7a, 0x3f, 0x7b, 0xad, 0x04, 0x8b, 0xbd,
+  0x6f, 0x9e, 0x10, 0x46, 0x13, 0x78, 0x71, 0x9d, 0x30, 0x0e, 0x06, 0x03,
+  0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0,
+  0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02,
+  0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30,
+  0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06,
+  0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x46, 0x06,
+  0x03, 0x55, 0x1d, 0x20, 0x04, 0x3f, 0x30, 0x3d, 0x30, 0x3b, 0x06, 0x0c,
+  0x2b, 0x06, 0x01, 0x04, 0x01, 0xb2, 0x31, 0x01, 0x02, 0x01, 0x03, 0x04,
+  0x30, 0x2b, 0x30, 0x29, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+  0x02, 0x01, 0x16, 0x1d, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f,
+  0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64,
+  0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x7b, 0x06,
+  0x03, 0x55, 0x1d, 0x1f, 0x04, 0x74, 0x30, 0x72, 0x30, 0x38, 0xa0, 0x36,
+  0xa0, 0x34, 0x86, 0x32, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63,
+  0x72, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e,
+  0x63, 0x6f, 0x6d, 0x2f, 0x55, 0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52,
+  0x46, 0x69, 0x72, 0x73, 0x74, 0x2d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61,
+  0x72, 0x65, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x36, 0xa0, 0x34, 0xa0, 0x32,
+  0x86, 0x30, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c,
+  0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x2e, 0x6e, 0x65, 0x74, 0x2f,
+  0x55, 0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72, 0x73,
+  0x74, 0x2d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x2e, 0x63,
+  0x72, 0x6c, 0x30, 0x71, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+  0x01, 0x01, 0x04, 0x65, 0x30, 0x63, 0x30, 0x3b, 0x06, 0x08, 0x2b, 0x06,
+  0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2f, 0x68, 0x74, 0x74, 0x70,
+  0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64,
+  0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x55, 0x54, 0x4e, 0x41,
+  0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65,
+  0x72, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x24, 0x06, 0x08, 0x2b,
+  0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74,
+  0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x63, 0x6f, 0x6d,
+  0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x25, 0x06,
+  0x03, 0x55, 0x1d, 0x11, 0x04, 0x1e, 0x30, 0x1c, 0x82, 0x0e, 0x77, 0x77,
+  0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
+  0x82, 0x0a, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
+  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+  0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x71, 0xc0, 0x99, 0x3f,
+  0x5e, 0xf6, 0xbd, 0x33, 0xff, 0x9e, 0x16, 0xcb, 0xa8, 0xbf, 0xdd, 0x70,
+  0xf9, 0xd2, 0x53, 0x3b, 0x36, 0xae, 0xc9, 0x17, 0xc8, 0xae, 0x5e, 0x4d,
+  0xdd, 0x62, 0xf7, 0xb7, 0xd3, 0x3e, 0x77, 0xa3, 0xfe, 0xc0, 0x7b, 0x32,
+  0xb5, 0xc9, 0x94, 0x05, 0x52, 0x50, 0xf2, 0x5f, 0x3d, 0x79, 0x84, 0x49,
+  0x4f, 0x5d, 0x6c, 0xb0, 0xd7, 0x59, 0xbd, 0xd4, 0x6c, 0x88, 0xfa, 0xfc,
+  0xc5, 0x65, 0x86, 0xeb, 0x28, 0x52, 0xa2, 0x42, 0xf6, 0x7c, 0xbc, 0x6a,
+  0xc7, 0x07, 0x2e, 0x25, 0xd1, 0x90, 0x62, 0x20, 0xc6, 0x8d, 0x51, 0xc2,
+  0x2c, 0x45, 0x39, 0x4e, 0x03, 0xda, 0xf7, 0x18, 0xe8, 0xcc, 0x0a, 0x3a,
+  0xd9, 0x45, 0xd8, 0x6c, 0x6e, 0x34, 0x8b, 0x62, 0x9c, 0x4e, 0x15, 0xf9,
+  0x43, 0xee, 0xe5, 0x97, 0xc0, 0x3f, 0xad, 0x35, 0x13, 0xc5, 0x2b, 0x06,
+  0xc7, 0x41, 0xfd, 0xe2, 0xf7, 0x7e, 0x45, 0xad, 0x9b, 0xd1, 0xe1, 0x66,
+  0xed, 0xf8, 0x7a, 0x4b, 0x94, 0x39, 0x7a, 0x2f, 0xeb, 0xe8, 0x3f, 0x43,
+  0xd8, 0x35, 0xd6, 0x56, 0xfa, 0x74, 0xe7, 0x6d, 0xe6, 0xed, 0xac, 0x65,
+  0x84, 0xfe, 0xd0, 0x4d, 0x06, 0x12, 0xde, 0xda, 0x59, 0x00, 0x3c, 0x09,
+  0x5c, 0xcf, 0x88, 0x4b, 0xe8, 0x3d, 0xb4, 0x15, 0x21, 0x92, 0xcc, 0x6d,
+  0xa6, 0x51, 0xe2, 0x8e, 0x97, 0xf1, 0xf4, 0x82, 0x46, 0xcb, 0xc4, 0x53,
+  0x5e, 0xda, 0x5c, 0x9d, 0x65, 0x92, 0x01, 0x65, 0x89, 0x00, 0xe5, 0xb6,
+  0x99, 0xff, 0x26, 0x40, 0xf1, 0x2f, 0x19, 0x31, 0x08, 0x1a, 0xb1, 0x67,
+  0x55, 0x86, 0x0d, 0xae, 0x35, 0x33, 0x86, 0xbc, 0x97, 0x48, 0x92, 0xd7,
+  0x96, 0x60, 0xf8, 0xce, 0xfc, 0x96, 0xeb, 0x87, 0xc4, 0x73, 0xcc, 0x94,
+  0x9b, 0x58, 0x5b, 0xf3, 0x7a, 0xa4, 0x27, 0x13, 0xd6, 0x4f, 0xf4, 0x69
+};
+unsigned int www_google_com_cer_len = 1512;
diff --git a/sec/Security/Regressions/secitem/si-68-secmatchissuer.c b/sec/Security/Regressions/secitem/si-68-secmatchissuer.c
new file mode 100644 (file)
index 0000000..093b3b4
--- /dev/null
@@ -0,0 +1,192 @@
+
+//
+//  si-68-secmatchissuer.c
+//  regressions
+//
+//  Created by Conrad Sauerwald on 6/18/12.
+//
+//
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/Security.h>
+#include <libDER/libDER.h>
+#include <libDER/DER_Decode.h>
+#include <libDER/asn1Types.h>
+#include <Security/SecCertificateInternal.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecIdentityPriv.h>
+#include <Security/SecItem.h>
+#include <Security/SecInternal.h>
+#include <utilities/array_size.h>
+
+#include "Security_regressions.h"
+#include <test/testcert.h>
+
+/*
+static OSStatus add_item_to_keychain(CFTypeRef item, CFDataRef * persistent_ref)
+{
+    const void *keys[] = { kSecValueRef, kSecReturnPersistentRef };
+    const void *vals[] = { item, kCFBooleanTrue };
+    CFDictionaryRef add_query = CFDictionaryCreate(NULL, keys, vals, array_size(keys), NULL, NULL);
+    OSStatus status = errSecAllocate;
+    if (add_query) {
+        status = SecItemAdd(add_query, (CFTypeRef *)persistent_ref);
+        CFRelease(add_query);
+    }
+    return status;
+}
+
+static OSStatus remove_item_from_keychain(CFTypeRef item, CFDataRef * persistent_ref)
+{
+    const void *keys[] = { kSecValueRef, kSecReturnPersistentRef };
+    const void *vals[] = { item, kCFBooleanTrue };
+    CFDictionaryRef add_query = CFDictionaryCreate(NULL, keys, vals, array_size(keys), NULL, NULL);
+    OSStatus status = errSecAllocate;
+    if (add_query) {
+        status = SecItemAdd(add_query, (CFTypeRef *)persistent_ref);
+        CFRelease(add_query);
+    }
+    return status;
+}
+*/
+
+static OSStatus add_item(CFTypeRef item)
+{
+    CFDictionaryRef add_query = CFDictionaryCreate(NULL, &kSecValueRef, &item, 1, NULL, NULL);
+    OSStatus status = SecItemAdd(add_query, NULL);
+    CFRelease(add_query);
+    return status;
+}
+
+static OSStatus remove_item(CFTypeRef item)
+{
+    CFDictionaryRef remove_query = CFDictionaryCreate(NULL, &kSecValueRef, &item, 1, NULL, NULL);
+    OSStatus status = SecItemDelete(remove_query);
+    CFRelease(remove_query);
+    return status;
+}
+
+static void tests(void)
+{
+
+// MARK: test SecDistinguishedNameCopyNormalizedContent
+
+    unsigned char example_dn[] = {
+        0x30, 0x4f, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+        0x02, 0x43, 0x5a, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0a,
+        0x0c, 0x1e, 0x4d, 0x69, 0x6e, 0x69, 0x73, 0x74, 0x65, 0x72, 0x73, 0x74,
+        0x76, 0x6f, 0x20, 0x73, 0x70, 0x72, 0x61, 0x76, 0x65, 0x64, 0x6c, 0x6e,
+        0x6f, 0x73, 0x74, 0x69, 0x20, 0xc4, 0x8c, 0x52, 0x31, 0x17, 0x30, 0x15,
+        0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0e, 0x4d, 0x53, 0x70, 0x20, 0x52,
+        0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x20, 0x30, 0x31
+    };
+    unsigned int example_dn_len = 81;
+
+    CFDataRef normalized_dn = NULL, dn = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, example_dn, example_dn_len, kCFAllocatorNull);
+    ok(dn, "got dn as data");
+    ok(normalized_dn = SecDistinguishedNameCopyNormalizedContent(dn), "convert to normalized form");
+    //CFShow(dn);
+    //CFShow(normalized_dn);
+    CFReleaseNull(dn);
+    CFReleaseNull(normalized_dn);
+    
+// MARK: generate certificate hierarchy
+
+       SecKeyRef public_key = NULL, private_key = NULL;
+    ok_status(test_cert_generate_key(512, kSecAttrKeyTypeRSA, &private_key, &public_key), "generate keypair");
+       // make organization random uuid to avoid previous run to spoil the fun
+
+    CFUUIDRef UUID = CFUUIDCreate(kCFAllocatorDefault);
+    CFStringRef uuidString = CFUUIDCreateString(kCFAllocatorDefault, UUID);
+    CFStringRef root_authority_name = CFStringCreateWithFormat(kCFAllocatorDefault, 0, CFSTR("O=%@,CN=Root CA"), uuidString);
+    CFStringRef intermediate_authority_name = CFStringCreateWithFormat(kCFAllocatorDefault, 0, CFSTR("O=%@,CN=Intermediate CA"), uuidString);
+    CFStringRef leaf_name = CFStringCreateWithFormat(kCFAllocatorDefault, 0, CFSTR("O=%@,CN=Client"), uuidString);
+    CFRelease(uuidString);
+    CFRelease(UUID);
+
+    SecIdentityRef ca_identity =
+        test_cert_create_root_certificate(root_authority_name, public_key, private_key);
+    CFRelease(root_authority_name);
+
+    SecCertificateRef ca_cert = NULL;
+    SecIdentityCopyCertificate(ca_identity, &ca_cert);
+    //CFShow(ca_cert);
+    
+       SecCertificateRef intermediate_cert =
+        test_cert_issue_certificate(ca_identity, public_key, intermediate_authority_name, 42, kSecKeyUsageKeyCertSign);
+    CFRelease(intermediate_authority_name);
+    SecIdentityRef intermediate_identity = SecIdentityCreate(kCFAllocatorDefault, intermediate_cert, private_key);
+    
+    ok_status(add_item(intermediate_cert), "add intermediate");
+    //CFShow(intermediate_cert);
+    
+       SecCertificateRef leaf_cert = test_cert_issue_certificate(intermediate_identity, public_key,
+          leaf_name, 4242, kSecKeyUsageDigitalSignature);
+    CFRelease(leaf_name);
+    SecIdentityRef leaf_identity = SecIdentityCreate(kCFAllocatorDefault, leaf_cert, private_key);
+    
+    ok_status(add_item(leaf_identity), "add leaf");
+    //CFShow(leaf_cert);
+
+    // this is already canonical - see if we can get the raw one
+    CFDataRef issuer = SecCertificateGetNormalizedIssuerContent(intermediate_cert);
+    ok(CFDataGetLength(issuer) < 128, "max 127 bytes of content - or else you'll need to properly encode issuer sequence");
+    CFMutableDataRef canonical_issuer = CFDataCreateMutable(kCFAllocatorDefault, CFDataGetLength(issuer) + 2);
+    CFDataSetLength(canonical_issuer, CFDataGetLength(issuer) + 2);
+    uint8_t * ptr = CFDataGetMutableBytePtr(canonical_issuer);
+    memcpy(ptr+2, CFDataGetBytePtr(issuer), CFDataGetLength(issuer));
+    ptr[0] = 0x30;
+    ptr[1] = CFDataGetLength(issuer);
+
+    CFMutableArrayRef all_distinguished_names = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+    CFArrayAppendValue(all_distinguished_names, canonical_issuer);
+
+    {
+        CFReleaseNull(canonical_issuer);
+        const void *keys[] = { kSecClass, kSecReturnRef, kSecMatchLimit, kSecMatchIssuers };
+        const void *vals[] = { kSecClassIdentity, kCFBooleanTrue, kSecMatchLimitAll, all_distinguished_names };
+        CFDictionaryRef all_identities_query = CFDictionaryCreate(kCFAllocatorDefault, keys, vals, array_size(keys), NULL, NULL);
+        CFTypeRef all_matching_identities = NULL;
+        ok_status(SecItemCopyMatching(all_identities_query, &all_matching_identities), "find all identities matching");
+        CFReleaseNull(all_identities_query);
+        ok(((CFArrayGetTypeID() == CFGetTypeID(all_matching_identities)) && (CFArrayGetCount(all_matching_identities) == 2)), "return 2");
+        //CFShow(all_matching_identities);
+    }
+
+    {
+        int limit = 0x7fff; // To regress-test <rdar://problem/14603111>
+        CFNumberRef cfLimit = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &limit);
+        const void *keys[] = { kSecClass, kSecReturnRef, kSecMatchLimit, kSecMatchIssuers };
+        const void *vals[] = { kSecClassCertificate, kCFBooleanTrue, cfLimit, all_distinguished_names };
+        CFDictionaryRef all_identities_query = CFDictionaryCreate(kCFAllocatorDefault, keys, vals, array_size(keys), NULL, NULL);
+        CFTypeRef all_matching_certificates = NULL;
+        ok_status(SecItemCopyMatching(all_identities_query, &all_matching_certificates), "find all certificates matching");
+        CFReleaseNull(all_identities_query);
+        ok(((CFArrayGetTypeID() == CFGetTypeID(all_matching_certificates)) && (CFArrayGetCount(all_matching_certificates) == 2)), "return 2");
+        //CFShow(all_matching_certificates);
+        CFReleaseSafe(cfLimit);
+    }
+
+    remove_item(leaf_identity);
+    CFRelease(leaf_identity);
+    CFRelease(leaf_cert);
+    
+    remove_item(intermediate_cert);
+    CFRelease(intermediate_cert);
+    CFRelease(intermediate_identity);
+    
+    CFRelease(ca_cert);
+    CFRelease(ca_identity);
+    
+    CFRelease(public_key);
+    CFRelease(private_key);
+    
+}
+
+int si_68_secmatchissuer(int argc, char *const *argv)
+{
+       plan_tests(10);
+    
+       tests();
+    
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-69-keydesc.c b/sec/Security/Regressions/secitem/si-69-keydesc.c
new file mode 100644 (file)
index 0000000..8a508be
--- /dev/null
@@ -0,0 +1,131 @@
+//
+//  si-69-keydesc.c
+//  Regressions
+//
+//  Created by Michelle Olofson on 1/28/13.
+//
+//
+
+#include <Security/SecCMS.h>
+#include <Security/SecItem.h>
+#include <Security/SecKey.h>
+#include <Security/SecItemPriv.h>
+#include <Security/SecInternal.h>
+#include <Security/SecPolicyPriv.h>
+#include <Security/SecBasePriv.h>
+#include <Security/SecRSAKey.h>
+#include <Security/SecECKey.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecIdentityPriv.h>
+#include <Security/SecCertificateRequest.h>
+
+#include <CommonCrypto/CommonDigest.h>
+#include <CommonCrypto/CommonDigestSPI.h>
+
+#include <corecrypto/ccec.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "AssertMacros.h"
+#include "Security_regressions.h"
+
+
+unsigned char rsaPubKey[] = {
+    0x30, 0x68, 0x02, 0x61, 0x00, 0xc0, 0x63, 0x42, 0xb4, 0xf0, 0x6f, 0x2c, 0xda, 0x71, 0xef, 0x9d, 0x9d, 0x3e, 0x3e, 0x93, 0xc9, 0xd4, 0x2e, 0xe5, 0x62, 0x32, 0x6a, 0xbb, 0xeb, 0x34, 0x57, 0xeb, 0x8a, 0xf8, 0x62, 0xf9, 0xc0, 0x1c, 0x14, 0x54, 0x99, 0x04, 0x6b, 0x19, 0x92, 0xdd, 0xa3, 0x7d, 0x8c, 0x86, 0x48, 0xc9, 0xa6, 0x03, 0x63, 0xf8, 0xab, 0x9c, 0xb9, 0x2b, 0x49, 0x4c, 0x53, 0xb1, 0x39, 0xf9, 0x4a, 0xbc, 0x8b, 0xfc, 0xea, 0x93, 0xb6, 0x2e, 0x41, 0x1f, 0x21, 0x50, 0xca, 0xf7, 0x99, 0xc7, 0x77, 0x73, 0x03, 0x14, 0x58, 0x51, 0x1a, 0xa7, 0x68, 0xe5, 0x8d, 0x68, 0x6b, 0xca, 0x33, 0x4f, 0xcc, 0x6b, 0x41, 0x02, 0x03, 0x01, 0x00, 0x01
+};
+
+unsigned char ecPubKey[] = {
+    0x04, 0x01, 0x41, 0x34, 0x87, 0xfd, 0xe1, 0x51, 0x5d, 0x29, 0x12, 0x07, 0xc2, 0x57, 0x54, 0x19, 0xd2, 0xd9, 0x18, 0x95, 0x07, 0x17, 0x8a, 0xf7, 0x2d, 0x2b, 0xf9, 0xbc, 0xe6, 0x1b, 0xe7, 0x81, 0x35, 0x13, 0x5f, 0x1d, 0xfa, 0xed, 0x7e, 0x70, 0x2b, 0xcd, 0x01, 0xa0, 0xaa, 0x7f, 0xe4, 0x0f, 0x4e, 0x19, 0x56, 0xb0, 0x15, 0xfb, 0xd8, 0xc9, 0xe7, 0x48, 0xcf, 0xc7, 0x5e, 0xe8, 0xcc, 0x74, 0x34, 0x61, 0xa5, 0x01, 0x02, 0x67, 0x03, 0x16, 0xce, 0x3d, 0x31, 0x37, 0x9c, 0x0b, 0x03, 0x65, 0x94, 0xaa, 0xd0, 0x1d, 0xa9, 0x5a, 0xe3, 0x0a, 0xf9, 0x82, 0xef, 0x43, 0x75, 0x5b, 0x46, 0x52, 0x6c, 0x0a, 0x02, 0x3f, 0xc3, 0xd3, 0x42, 0x0d, 0xa7, 0x90, 0x8c, 0x4b, 0x15, 0x88, 0x89, 0x24, 0xed, 0x91, 0x0a, 0xa1, 0x20, 0x0d, 0x82, 0xed, 0x87, 0x8c, 0x98, 0x8e, 0xbe, 0xbc, 0xa3, 0xa7, 0xca, 0x50, 0x2d, 0x71, 0x73
+};
+
+const char *rsaKeyDescription = "<SecKeyRef algorithm id: 1, key type: RSAPublicKey, version: 2, block size: 768 bits, exponent: {hex: 10001, decimal: 65537}, modulus: C06342B4F06F2CDA71EF9D9D3E3E93C9D42EE562326ABBEB3457EB8AF862F9C01C145499046B1992DDA37D8C8648C9A60363F8AB9CB92B494C53B139F94ABC8BFCEA93B62E411F2150CAF799C77773031458511AA768E58D686BCA334FCC6B41";
+
+const char *ecKeyDescription = "<SecKeyRef curve type: kSecECCurveSecp521r1, algorithm id: 3, key type: ECPublicKey, version: 2, block size: 528 bits, y: 73712D50CAA7A3BCBE8E988C87ED820D20A10A91ED248988154B8C90A70D42D3C33F020A6C52465B7543EF82F90AE35AA91DD0AA9465030B9C37313DCE1603670201, x: A5613474CCE85EC7CF48E7C9D8FB15B056194E0FE47FAAA001CD2B707EEDFA1D5F133581E71BE6BCF92B2DF78A17079518D9D2195457C20712295D51E1FD87344101";
+
+static void testECKeyDesc() {
+
+    SecKeyRef pubKey = NULL;
+    CFStringRef pubRef = NULL;
+    long pubLength = 0;
+
+    pubKey = SecKeyCreateECPublicKey(kCFAllocatorDefault, ecPubKey, sizeof(ecPubKey), kSecKeyEncodingBytes);
+    require_quiet( pubKey, fail);
+    
+    pubRef = CFCopyDescription(pubKey);
+    require_quiet(pubRef, fail);
+
+    pubLength = CFStringGetLength(pubRef)+1;
+    char *publicDescription = (char*)malloc(pubLength);
+    
+    if(false == CFStringGetCString(pubRef, publicDescription, pubLength, kCFStringEncodingUTF8))
+    {
+       free(publicDescription);
+       goto fail;
+    }
+    
+    ok_status(strncmp(ecKeyDescription, publicDescription, strlen(ecKeyDescription)-17), "ec key description");
+    free(publicDescription);
+
+fail:
+    CFReleaseSafe(pubRef);
+    CFReleaseSafe(pubKey);
+}
+
+/*
+ * tests the description for
+ * RSA keypairs
+ */
+
+static void testRSAKeyDesc()
+{   
+    SecKeyRef pubKey = NULL;
+    CFStringRef pubRef = NULL;
+    long pubLength = 0;
+       
+    pubKey = SecKeyCreateRSAPublicKey(kCFAllocatorDefault, rsaPubKey, sizeof(rsaPubKey), kSecKeyEncodingBytes);
+    require_quiet( pubKey, fail);
+    
+    pubRef = CFCopyDescription(pubKey);
+    require_quiet(pubRef, fail);
+    
+    pubLength = CFStringGetLength(pubRef)+1;
+    char *publicDescription = (char*)malloc(pubLength);
+    require_quiet(publicDescription != NULL, fail);
+
+    if(false == CFStringGetCString(pubRef, publicDescription, pubLength, kCFStringEncodingUTF8))
+    {
+       free(publicDescription);
+       goto fail;
+    }
+    
+    ok_status(strncmp(rsaKeyDescription, publicDescription, strlen(rsaKeyDescription)-17), "rsa key description");
+    free(publicDescription);
+
+fail:
+    CFReleaseSafe(pubRef);
+    CFReleaseSafe(pubKey);
+        
+}
+
+static void tests(void)
+{
+    //test rsa public key description
+    testRSAKeyDesc();
+    
+    //test ec public key description
+    testECKeyDesc();
+
+}
+
+int si_69_keydesc(int argc, char *const *argv)
+{
+
+    plan_tests(2);
+   
+       tests();
+    
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-70-sectrust-unified.c b/sec/Security/Regressions/secitem/si-70-sectrust-unified.c
new file mode 100644 (file)
index 0000000..f191988
--- /dev/null
@@ -0,0 +1,250 @@
+
+//
+//  si-70-sectrust-unified.c
+//  regressions
+//
+//  Created by Ken McLeod on 2/4/13.
+//
+//
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/Security.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecInternal.h>
+#include <utilities/array_size.h>
+
+#include "Security_regressions.h"
+#include <test/testcert.h>
+
+/* This is a minimal test case to ensure that the functionality of
+ * <rdar://problem/11736016> TLF: SecTrust Unification is present
+ * and working. Needs to be expanded and split up into separate
+ * test case files in the future.
+ */
+
+/* SecPolicy: new in 7.0 */
+//CFDictionaryRef SecPolicyCopyProperties(SecPolicyRef policyRef)
+//OSStatus SecTrustSetPolicies(SecTrustRef trust, CFTypeRef policies) /* (this was SPI in 6.0) */
+//SecPolicyRef SecPolicyCreateRevocation(CFIndex revocationFlags)
+//SecPolicyRef SecPolicyCreateWithProperties(CFTypeRef policyIdentifier, CFDictionaryRef properties)
+
+/* SecTrust new in 7.0 */
+//OSStatus SecTrustCopyPolicies(SecTrustRef trust, CFArrayRef *policies)
+//OSStatus SecTrustSetNetworkFetchAllowed(SecTrustRef trust, Boolean allowFetch)
+//OSStatus SecTrustGetNetworkFetchAllowed(SecTrustRef trust, Boolean *allowFetch)
+//OSStatus SecTrustCopyCustomAnchorCertificates(SecTrustRef trust, CFArrayRef *anchors)
+//CFDictionaryRef SecTrustCopyResult(SecTrustRef trust)
+//OSStatus SecTrustSetOCSPResponse(SecTrustRef trust, CFTypeRef responseData)
+
+
+/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc/OU=Internet Operations/CN=xedge2.apple.com
+   issuer :/C=US/O=Entrust.net/OU=www.entrust.net/CPS incorp. by ref. (limits liab.)/OU=(c) 1999 Entrust.net Limited/CN=Entrust.net Secure Server Certification Authority */
+const uint8_t xedge2_cert[1385]={
+0x30,0x82,0x05,0x65,0x30,0x82,0x04,0xCE,0xA0,0x03,0x02,0x01,0x02,0x02,0x04,0x46,
+0x9C,0xDF,0x96,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,
+0x05,0x00,0x30,0x81,0xC3,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
+0x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x13,0x0B,0x45,0x6E,0x74,
+0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x31,0x3B,0x30,0x39,0x06,0x03,0x55,0x04,
+0x0B,0x13,0x32,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,
+0x65,0x74,0x2F,0x43,0x50,0x53,0x20,0x69,0x6E,0x63,0x6F,0x72,0x70,0x2E,0x20,0x62,
+0x79,0x20,0x72,0x65,0x66,0x2E,0x20,0x28,0x6C,0x69,0x6D,0x69,0x74,0x73,0x20,0x6C,
+0x69,0x61,0x62,0x2E,0x29,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x0B,0x13,0x1C,
+0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x39,0x20,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,
+0x2E,0x6E,0x65,0x74,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x3A,0x30,0x38,
+0x06,0x03,0x55,0x04,0x03,0x13,0x31,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,
+0x65,0x74,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x53,0x65,0x72,0x76,0x65,0x72,
+0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,
+0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x30,0x38,0x30,0x31,
+0x32,0x39,0x31,0x38,0x33,0x33,0x31,0x33,0x5A,0x17,0x0D,0x31,0x30,0x30,0x31,0x32,
+0x38,0x31,0x39,0x30,0x33,0x31,0x32,0x5A,0x30,0x81,0x83,0x31,0x0B,0x30,0x09,0x06,
+0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,
+0x08,0x13,0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61,0x31,0x12,0x30,
+0x10,0x06,0x03,0x55,0x04,0x07,0x13,0x09,0x43,0x75,0x70,0x65,0x72,0x74,0x69,0x6E,
+0x6F,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x0A,0x13,0x09,0x41,0x70,0x70,0x6C,
+0x65,0x20,0x49,0x6E,0x63,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0B,0x13,0x13,
+0x49,0x6E,0x74,0x65,0x72,0x6E,0x65,0x74,0x20,0x4F,0x70,0x65,0x72,0x61,0x74,0x69,
+0x6F,0x6E,0x73,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x03,0x13,0x10,0x78,0x65,
+0x64,0x67,0x65,0x32,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x81,
+0x9F,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,
+0x03,0x81,0x8D,0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xC7,0xF3,0xA1,0x0E,0x0E,
+0xA4,0xDF,0xC5,0x3F,0x24,0x87,0xC3,0x6E,0xE7,0xD0,0x7C,0x2B,0x5A,0x1C,0xF3,0x67,
+0x6C,0x6B,0x56,0x0A,0x95,0xC9,0xE5,0x13,0x28,0x6E,0x16,0x9D,0x4F,0xB1,0x76,0xFB,
+0x7D,0x42,0x5B,0x2A,0x7C,0xCC,0x97,0x75,0xAA,0xA6,0xA9,0xDE,0xB2,0xEC,0xEF,0xE2,
+0xAB,0x40,0xAE,0x9A,0x23,0xF0,0x6A,0x10,0xB3,0x75,0x27,0xF0,0xF4,0x7D,0x08,0x67,
+0x8F,0xCE,0x41,0x24,0x74,0xAA,0x37,0xB6,0xC1,0x32,0x61,0xCF,0x7D,0x1C,0x21,0xCD,
+0xCF,0x7C,0x9E,0xE2,0x48,0x03,0x7E,0x78,0xB3,0x86,0x3D,0x06,0x6B,0x39,0xEC,0xC8,
+0x73,0x68,0xDB,0xE7,0x5B,0x97,0xF4,0xF9,0xA3,0xE7,0xFB,0x81,0x2E,0x4D,0x0B,0x3F,
+0xA9,0xCA,0xDE,0x32,0x26,0xF3,0xF0,0x97,0x72,0x65,0xAB,0x02,0x03,0x01,0x00,0x01,
+0xA3,0x82,0x02,0xA2,0x30,0x82,0x02,0x9E,0x30,0x0B,0x06,0x03,0x55,0x1D,0x0F,0x04,
+0x04,0x03,0x02,0x05,0xA0,0x30,0x2B,0x06,0x03,0x55,0x1D,0x10,0x04,0x24,0x30,0x22,
+0x80,0x0F,0x32,0x30,0x30,0x38,0x30,0x31,0x32,0x39,0x31,0x38,0x33,0x33,0x31,0x33,
+0x5A,0x81,0x0F,0x32,0x30,0x31,0x30,0x30,0x31,0x32,0x38,0x31,0x39,0x30,0x33,0x31,
+0x32,0x5A,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,0x04,
+0x04,0x03,0x02,0x06,0x40,0x30,0x13,0x06,0x03,0x55,0x1D,0x25,0x04,0x0C,0x30,0x0A,
+0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01,0x30,0x82,0x01,0x68,0x06,0x03,
+0x55,0x1D,0x20,0x04,0x82,0x01,0x5F,0x30,0x82,0x01,0x5B,0x30,0x82,0x01,0x57,0x06,
+0x09,0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x4B,0x02,0x30,0x82,0x01,0x48,0x30,0x26,
+0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1A,0x68,0x74,0x74,0x70,
+0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,
+0x65,0x74,0x2F,0x63,0x70,0x73,0x30,0x82,0x01,0x1C,0x06,0x08,0x2B,0x06,0x01,0x05,
+0x05,0x07,0x02,0x02,0x30,0x82,0x01,0x0E,0x1A,0x82,0x01,0x0A,0x54,0x68,0x65,0x20,
+0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x20,0x53,0x53,0x4C,0x20,0x57,0x65,0x62,0x20,
+0x53,0x65,0x72,0x76,0x65,0x72,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,
+0x74,0x69,0x6F,0x6E,0x20,0x50,0x72,0x61,0x63,0x74,0x69,0x63,0x65,0x20,0x53,0x74,
+0x61,0x74,0x65,0x6D,0x65,0x6E,0x74,0x20,0x28,0x43,0x50,0x53,0x29,0x20,0x61,0x76,
+0x61,0x69,0x6C,0x61,0x62,0x6C,0x65,0x20,0x61,0x74,0x20,0x77,0x77,0x77,0x2E,0x65,
+0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x2F,0x63,0x70,0x73,0x20,0x20,
+0x69,0x73,0x20,0x68,0x65,0x72,0x65,0x62,0x79,0x20,0x69,0x6E,0x63,0x6F,0x72,0x70,
+0x6F,0x72,0x61,0x74,0x65,0x64,0x20,0x69,0x6E,0x74,0x6F,0x20,0x79,0x6F,0x75,0x72,
+0x20,0x75,0x73,0x65,0x20,0x6F,0x72,0x20,0x72,0x65,0x6C,0x69,0x61,0x6E,0x63,0x65,
+0x20,0x6F,0x6E,0x20,0x74,0x68,0x69,0x73,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,
+0x63,0x61,0x74,0x65,0x2E,0x20,0x20,0x54,0x68,0x69,0x73,0x20,0x43,0x50,0x53,0x20,
+0x63,0x6F,0x6E,0x74,0x61,0x69,0x6E,0x73,0x20,0x6C,0x69,0x6D,0x69,0x74,0x61,0x74,
+0x69,0x6F,0x6E,0x73,0x20,0x6F,0x6E,0x20,0x77,0x61,0x72,0x72,0x61,0x6E,0x74,0x69,
+0x65,0x73,0x20,0x61,0x6E,0x64,0x20,0x6C,0x69,0x61,0x62,0x69,0x6C,0x69,0x74,0x69,
+0x65,0x73,0x2E,0x20,0x43,0x6F,0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x20,0x28,0x63,
+0x29,0x20,0x32,0x30,0x30,0x32,0x20,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x20,0x4C,
+0x69,0x6D,0x69,0x74,0x65,0x64,0x30,0x33,0x06,0x03,0x55,0x1D,0x1F,0x04,0x2C,0x30,
+0x2A,0x30,0x28,0xA0,0x26,0xA0,0x24,0x86,0x22,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,
+0x63,0x72,0x6C,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x2F,
+0x73,0x65,0x72,0x76,0x65,0x72,0x31,0x2E,0x63,0x72,0x6C,0x30,0x33,0x06,0x08,0x2B,
+0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x27,0x30,0x25,0x30,0x23,0x06,0x08,0x2B,
+0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x17,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,
+0x6F,0x63,0x73,0x70,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,
+0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xF0,0x17,0x62,
+0x13,0x55,0x3D,0xB3,0xFF,0x0A,0x00,0x6B,0xFB,0x50,0x84,0x97,0xF3,0xED,0x62,0xD0,
+0x1A,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x2D,0xEF,0xD9,0xAF,
+0x1A,0x89,0x40,0x53,0x75,0x48,0x26,0x59,0x2F,0xEC,0x11,0x18,0xC0,0xD1,0x7A,0x34,
+0x30,0x09,0x06,0x03,0x55,0x1D,0x13,0x04,0x02,0x30,0x00,0x30,0x19,0x06,0x09,0x2A,
+0x86,0x48,0x86,0xF6,0x7D,0x07,0x41,0x00,0x04,0x0C,0x30,0x0A,0x1B,0x04,0x56,0x37,
+0x2E,0x31,0x03,0x02,0x03,0x28,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,
+0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x77,0x33,0x2A,0x69,0x45,0x5A,0xB2,
+0xF5,0x74,0xF7,0xDF,0xC7,0x08,0x85,0x86,0x88,0x98,0x41,0x7F,0x57,0x49,0x01,0xBA,
+0x13,0x21,0x40,0xD0,0x0A,0x5C,0xA7,0x37,0xDF,0xB3,0x7E,0xF8,0xED,0x04,0x63,0xC3,
+0xE8,0x0F,0xA0,0xE5,0xC4,0x4F,0x3A,0x90,0xE4,0x87,0x5F,0xEC,0xDB,0x65,0x8B,0x6E,
+0x88,0x6E,0x6E,0xE4,0xBC,0x6A,0x7E,0x37,0x47,0x04,0xFF,0x09,0xC6,0x70,0xE1,0x65,
+0x8F,0xE3,0xE9,0x60,0xEB,0xE8,0x8E,0x29,0xAE,0xF9,0x81,0xCA,0x9A,0x97,0x3C,0x6F,
+0x7C,0xFA,0xA8,0x49,0xB4,0x33,0x76,0x9C,0x65,0x92,0x12,0xF6,0x7F,0x6A,0x62,0x84,
+0x29,0x5F,0x14,0x26,0x6E,0x07,0x6F,0x5C,0xB5,0x7C,0x21,0x64,0x7C,0xD9,0x93,0xF4,
+0x9C,0xC8,0xE7,0xEC,0xC6,0xAC,0x13,0xC4,0xF0
+};
+
+
+static void tests(void)
+{
+       SecTrustResultType trustResult;
+       SecTrustRef trust = NULL;
+    SecPolicyRef policy = NULL;
+    CFArrayRef certs = NULL;
+       CFDateRef date = NULL;
+
+       const void *cert_xedge2;
+       isnt(cert_xedge2 = SecCertificateCreateWithBytes(NULL, xedge2_cert,
+        sizeof(xedge2_cert)), NULL, "create cert_xedge2");
+    certs = CFArrayCreate(NULL, &cert_xedge2, 1, NULL);
+
+    bool server = true;
+    policy = SecPolicyCreateSSL(server, CFSTR("xedge.apple.com")); // deliberate hostname mismatch
+    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
+        "create trust for ssl server xedge.apple.com");
+    CFReleaseSafe(certs);
+    date = CFDateCreate(NULL, 252288000.0); /* Jan 1st 2009 */
+    ok_status(SecTrustSetVerifyDate(trust, date), "set trust date to Jan 1st 2009");
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge trust");
+    is_status(trustResult, kSecTrustResultRecoverableTrustFailure,
+               "trust is kSecTrustResultRecoverableTrustFailure (hostname mismatch)");
+
+       /* Test SecPolicyCreateRevocation */
+       {
+               /* FIXME need to do more than just call the function, but it's a start */
+               SecPolicyRef revocation = SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod);
+               isnt(revocation, NULL, "create revocation policy");
+               CFReleaseSafe(revocation);
+       }
+
+       /* Test SecTrustCopyPolicies */
+       {
+               CFArrayRef policies = NULL;
+               ok_status(SecTrustCopyPolicies(trust, &policies), "copy policies");
+               is((policies && (CFArrayGetCount(policies) > 0)), true, "non-empty policies");
+               CFReleaseSafe(policies);
+       }
+
+       /* Test SecTrustSetNetworkFetchAllowed */
+       {
+               Boolean curAllow, allow;
+               ok_status(SecTrustGetNetworkFetchAllowed(trust, &curAllow));
+               allow = !curAllow; /* flip it and see if the setting sticks */
+               ok_status(SecTrustSetNetworkFetchAllowed(trust, allow));
+               ok_status(SecTrustGetNetworkFetchAllowed(trust, &curAllow));
+               is((allow == curAllow), true, "network fetch toggle");
+       }
+
+       /* Test setting OCSP response data */
+       {
+               CFDataRef resp = (CFDataRef) CFDataCreateMutable(NULL, 0);
+               /* FIXME: use actual OCSPResponse DER blob */
+               CFDataIncreaseLength((CFMutableDataRef)resp, 64); /* arbitrary length, zero-filled data */
+
+               is_status(SecTrustSetOCSPResponse(NULL, resp), errSecParam, "SecTrustSetOCSPResponse param 1 check OK");
+               is_status(SecTrustSetOCSPResponse(trust, NULL), errSecSuccess, "SecTrustSetOCSPResponse param 2 check OK");
+               is_status(SecTrustSetOCSPResponse(trust, resp), errSecSuccess, "SecTrustSetOCSPResponse OK");
+        CFReleaseSafe(resp);
+       }
+
+       /* Test creation of a policy via SecPolicyCreateWithProperties */
+       CFReleaseNull(policy);
+       {
+               const void *keys[] = { kSecPolicyName, kSecPolicyClient };
+               const void *values[] = { CFSTR("xedge2.apple.com"), kCFBooleanFalse };
+               CFDictionaryRef properties = CFDictionaryCreate(NULL, keys, values,
+                               array_size(keys),
+                               &kCFTypeDictionaryKeyCallBacks,
+                               &kCFTypeDictionaryValueCallBacks);
+               policy = SecPolicyCreateWithProperties(kSecPolicyAppleSSL, properties);
+               isnt(policy, NULL, "SecPolicyCreateWithProperties");
+               CFReleaseSafe(properties);
+       }
+
+       /* Test introspection of a policy's properties via SecPolicyCopyProperties */
+       {
+               CFDictionaryRef properties = NULL;
+               isnt(properties = SecPolicyCopyProperties(policy), NULL, "copy policy properties");
+               CFTypeRef value = NULL;
+               is(CFDictionaryGetValueIfPresent(properties, kSecPolicyName, (const void **)&value) &&
+                       kCFCompareEqualTo == CFStringCompare((CFStringRef)value, CFSTR("xedge2.apple.com"), 0),
+               true, "has policy name");
+               is(CFDictionaryGetValueIfPresent(properties, kSecPolicyOid, (const void **)&value) &&
+                       CFEqual(value, kSecPolicyAppleSSL) , true, "has SSL policy");
+        CFReleaseSafe(properties);
+       }
+       /* Test setting new policy on a trust via SecTrustSetPolicies */
+       ok_status(SecTrustSetPolicies(trust, policy));
+       /* Evaluation should now succeed, since our new policy has the correct hostname */
+    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust");
+    is_status(trustResult, kSecTrustResultUnspecified,
+               "trust is kSecTrustResultUnspecified");
+
+       /* Make sure we can get the results */
+       {
+               CFDictionaryRef results = NULL;
+               SecTrustResultType anotherResult = kSecTrustResultInvalid;
+               ok_status(SecTrustGetTrustResult(trust, &anotherResult), "get trust result");
+               is_status(trustResult, anotherResult, "trust is kSecTrustResultUnspecified");
+
+               isnt(results = SecTrustCopyResult(trust), NULL, "copy trust results");
+               CFReleaseSafe(results);
+       }
+
+       CFReleaseSafe(trust);
+       CFReleaseSafe(policy);
+       CFReleaseSafe(date);
+       CFReleaseSafe(cert_xedge2);
+}
+
+int si_70_sectrust_unified(int argc, char *const *argv)
+{
+       plan_tests(25);
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-71-mobile-store-policy.c b/sec/Security/Regressions/secitem/si-71-mobile-store-policy.c
new file mode 100644 (file)
index 0000000..729a06f
--- /dev/null
@@ -0,0 +1,424 @@
+/*
+ *  si-70-mobile-store-policy.c
+ *  Security
+ *
+ *  Created by James Murphy on 05/15/13.
+ *  Copyright (c) 2013 Apple Inc. All Rights Reserved.
+ *
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecCertificateInternal.h>
+#include <Security/SecItem.h>
+#include <Security/SecItemPriv.h>
+#include <Security/SecIdentityPriv.h>
+#include <Security/SecIdentity.h>
+#include <Security/SecPolicy.h>
+#include <Security/SecPolicyPriv.h>
+#include <Security/SecPolicyInternal.h>
+#include <utilities/SecCFRelease.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "Security_regressions.h"
+
+#if defined(NO_SERVER) && NO_SERVER == 1
+
+static const uint8_t kDemoContentSigningCert[] = {
+       0x30, 0x82, 0x04, 0x1a, 0x30, 0x82, 0x03, 0x02, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x47,
+       0x62, 0x58, 0xaa, 0x2c, 0xdd, 0x90, 0xc1, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+       0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0x87, 0x31, 0x3b, 0x30, 0x39, 0x06, 0x03, 0x55,
+       0x04, 0x03, 0x0c, 0x32, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d,
+       0x20, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x32, 0x20, 0x43,
+       0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
+       0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c,
+       0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
+       0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x13,
+       0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49,
+       0x6e, 0x63, 0x2e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
+       0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30, 0x36, 0x30, 0x34, 0x32, 0x31, 0x34, 0x37, 0x31, 0x37,
+       0x5a, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x36, 0x30, 0x33, 0x32, 0x31, 0x34, 0x37, 0x31, 0x37, 0x5a,
+       0x30, 0x53, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x14, 0x44, 0x65, 0x6d,
+       0x6f, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e,
+       0x67, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x07, 0x43, 0x6f, 0x72, 0x65,
+       0x20, 0x4f, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70,
+       0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
+       0x06, 0x13, 0x02, 0x55, 0x53, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+       0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01,
+       0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xaf, 0x2a, 0xac, 0x4b, 0x91, 0x1e, 0x4d, 0x9f, 0x1d, 0x23,
+       0xf3, 0xff, 0x1c, 0xbe, 0x87, 0xbe, 0x3e, 0x2a, 0x0f, 0x35, 0xf4, 0xad, 0x80, 0x01, 0xc3, 0xf6,
+       0x6b, 0x12, 0xc4, 0xfa, 0x0f, 0xf5, 0xbc, 0xc0, 0x79, 0x76, 0xad, 0x77, 0xb1, 0x8d, 0xdc, 0xe7,
+       0xa0, 0x8a, 0xe0, 0x6a, 0xa3, 0xdb, 0x24, 0xb6, 0x0b, 0xa5, 0x29, 0x13, 0xe0, 0xd4, 0x96, 0xc7,
+       0x1e, 0xee, 0x9b, 0x56, 0x63, 0xdd, 0xab, 0x9b, 0x4e, 0x7d, 0x09, 0xa7, 0x3f, 0xf9, 0xec, 0x96,
+       0xcb, 0x88, 0x62, 0x91, 0xfe, 0xb8, 0x10, 0xe4, 0x40, 0x10, 0xb5, 0x34, 0x8a, 0x8e, 0x9a, 0x28,
+       0x16, 0xc3, 0x8e, 0x06, 0xda, 0x32, 0x04, 0x64, 0x60, 0x3b, 0xae, 0x70, 0x24, 0xb0, 0xcc, 0x6c,
+       0x76, 0x69, 0xb3, 0x52, 0x8f, 0x9c, 0x7a, 0xfb, 0x68, 0x55, 0x88, 0x2f, 0xd8, 0x18, 0xe0, 0x51,
+       0x43, 0xdb, 0x91, 0x9f, 0x10, 0xcf, 0xd8, 0x93, 0x6e, 0x5d, 0xef, 0x90, 0xac, 0x47, 0x56, 0xf7,
+       0x32, 0xd3, 0xf0, 0xb4, 0x9d, 0x68, 0x94, 0xdd, 0x4f, 0xf9, 0x5a, 0xb4, 0x9a, 0x81, 0xf8, 0xef,
+       0xae, 0xd8, 0x27, 0x4d, 0xec, 0xc5, 0x7d, 0xc2, 0xfe, 0x80, 0x23, 0x4d, 0x13, 0xc9, 0x90, 0x5a,
+       0x91, 0x86, 0x30, 0x42, 0x7d, 0x38, 0xda, 0x17, 0xa8, 0x46, 0x3e, 0x76, 0x8c, 0xca, 0x5e, 0x20,
+       0x1d, 0x3b, 0x85, 0xda, 0x87, 0x9d, 0xf1, 0xc7, 0x1d, 0x3c, 0x13, 0x4a, 0x56, 0xd4, 0x23, 0x52,
+       0x96, 0x6b, 0xb8, 0x99, 0x79, 0x03, 0x88, 0xbd, 0xf0, 0xf2, 0x28, 0x79, 0x1b, 0xe7, 0x8e, 0xfc,
+       0xd0, 0x30, 0xf3, 0x0b, 0x3e, 0x15, 0xff, 0x20, 0x5c, 0x42, 0x67, 0x7e, 0x0e, 0x52, 0x86, 0x50,
+       0xa0, 0x36, 0xb8, 0xc3, 0xee, 0x3d, 0xd8, 0xd6, 0x77, 0x15, 0xb7, 0x8f, 0xed, 0xf6, 0x42, 0xe4,
+       0xfc, 0x52, 0xf6, 0x45, 0x67, 0x41, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xbc, 0x30, 0x81,
+       0xb9, 0x30, 0x3e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x32, 0x30,
+       0x30, 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x22, 0x68,
+       0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65,
+       0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x30, 0x34, 0x2d, 0x61, 0x73, 0x69, 0x30,
+       0x32, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x55, 0xac, 0xda, 0x4b,
+       0xad, 0xf1, 0xe8, 0xe4, 0x2f, 0x72, 0xc2, 0x02, 0x2b, 0xaa, 0x01, 0x23, 0x9c, 0x96, 0x86, 0xdb,
+       0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1f,
+       0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x12, 0x75, 0x7c, 0x47, 0x92,
+       0xfd, 0x83, 0xe3, 0xbe, 0x2e, 0xfc, 0x59, 0x7f, 0x67, 0x43, 0x81, 0x35, 0x10, 0x45, 0xec, 0x30,
+       0x19, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x01, 0x01, 0xff, 0x04, 0x0f, 0x30, 0x0d, 0x30, 0x0b, 0x06,
+       0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x05, 0x0c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
+       0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+       0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x27, 0x50,
+       0xf8, 0x85, 0xe0, 0x6a, 0xf6, 0x74, 0x26, 0xcb, 0x5a, 0x23, 0xef, 0xd8, 0x32, 0xa0, 0x87, 0xf0,
+       0x01, 0x29, 0x1c, 0x64, 0x84, 0x9e, 0xc6, 0x3b, 0xd7, 0x9e, 0x40, 0x8b, 0x0a, 0x8c, 0x9d, 0xd5,
+       0x9b, 0x77, 0xc6, 0x5c, 0xe6, 0x52, 0xfb, 0x5b, 0x41, 0x2b, 0xbb, 0x8c, 0x24, 0xd5, 0xaf, 0xa1,
+       0xab, 0x2b, 0xda, 0x3e, 0x11, 0x6b, 0x51, 0xe5, 0xc8, 0xb9, 0xf7, 0x1b, 0x0c, 0x89, 0x6e, 0x29,
+       0x1a, 0x88, 0x24, 0xf9, 0x03, 0x2d, 0x46, 0x14, 0x07, 0xff, 0x3f, 0xd2, 0x2b, 0x87, 0x9b, 0xdb,
+       0x5c, 0x06, 0x4a, 0x20, 0x4d, 0xf6, 0x33, 0xb1, 0x06, 0x93, 0x87, 0x27, 0x5c, 0x93, 0xca, 0xf6,
+       0x81, 0x79, 0x71, 0x82, 0x1b, 0x88, 0x1d, 0x5a, 0x67, 0xc6, 0x2c, 0xd7, 0x68, 0x69, 0xbb, 0x07,
+       0x1d, 0x12, 0xae, 0x78, 0x4c, 0xfa, 0x4e, 0xc5, 0x80, 0x5c, 0x2d, 0xd4, 0xb0, 0xcf, 0x71, 0x64,
+       0x9e, 0xf8, 0xf3, 0x99, 0xd4, 0xd9, 0xdb, 0xbf, 0xd7, 0xb8, 0x97, 0x24, 0x3f, 0x34, 0x19, 0x52,
+       0x73, 0xac, 0xca, 0x31, 0xac, 0x0d, 0xb5, 0x72, 0x11, 0x2d, 0x03, 0x7b, 0xce, 0xf6, 0x1e, 0x84,
+       0x09, 0x3b, 0x47, 0xa0, 0x6a, 0xd6, 0x54, 0x60, 0x6d, 0x76, 0x6d, 0x02, 0xbb, 0xa8, 0x69, 0xa8,
+       0x58, 0xb5, 0xe2, 0x34, 0xdb, 0x8d, 0xb2, 0x96, 0x17, 0x47, 0x6d, 0xbc, 0xe9, 0xc6, 0xc9, 0xae,
+       0xc0, 0x54, 0xcf, 0x98, 0xc9, 0xea, 0x92, 0x69, 0x7f, 0x92, 0x82, 0x19, 0x63, 0x45, 0x5b, 0xeb,
+       0x85, 0x0b, 0xaa, 0x7e, 0x4a, 0x77, 0xb4, 0xf9, 0x45, 0xe8, 0x0e, 0x1e, 0x1f, 0xab, 0x1c, 0x86,
+       0x59, 0xa8, 0x82, 0x1e, 0x73, 0x86, 0x44, 0xfc, 0x67, 0x2a, 0x71, 0xeb, 0xb9, 0x9e, 0xd0, 0x28,
+       0xd7, 0xb1, 0xef, 0xa3, 0x8c, 0x0d, 0x18, 0xd4, 0x8c, 0x1c, 0xb3, 0x0e, 0xba, 0x30
+};
+
+static const uint8_t kTestDemoContentSigningCert[] = {
+       0x30, 0x82, 0x04, 0x20, 0x30, 0x82, 0x03, 0x08, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x75,
+       0x93, 0x8a, 0xaa, 0xe6, 0x6e, 0x3c, 0x5a, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+       0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0x87, 0x31, 0x3b, 0x30, 0x39, 0x06, 0x03, 0x55,
+       0x04, 0x03, 0x0c, 0x32, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d,
+       0x20, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x32, 0x20, 0x43,
+       0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
+       0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c,
+       0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
+       0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x13,
+       0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49,
+       0x6e, 0x63, 0x2e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
+       0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30, 0x36, 0x30, 0x34, 0x30, 0x30, 0x30, 0x32, 0x35, 0x32,
+       0x5a, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x36, 0x30, 0x33, 0x30, 0x30, 0x30, 0x32, 0x35, 0x32, 0x5a,
+       0x30, 0x58, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x19, 0x54, 0x65, 0x73,
+       0x74, 0x20, 0x44, 0x65, 0x6d, 0x6f, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x53,
+       0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c,
+       0x07, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x4f, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
+       0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x0b, 0x30,
+       0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
+       0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
+       0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xac, 0xc5, 0x87, 0x0d, 0x3b,
+       0x14, 0xba, 0x87, 0x63, 0x3d, 0xc9, 0x8d, 0xc1, 0x3a, 0xa9, 0x71, 0x14, 0x30, 0x6b, 0x64, 0x58,
+       0x35, 0xb2, 0xff, 0xcf, 0xe1, 0xe1, 0x5c, 0xa8, 0x5d, 0x99, 0xed, 0x11, 0x53, 0xf5, 0x6f, 0x92,
+       0x39, 0x28, 0x5a, 0x0f, 0x76, 0x86, 0x40, 0x44, 0x6a, 0x7b, 0x23, 0x05, 0x50, 0xfd, 0x1b, 0x29,
+       0xd9, 0x83, 0xfe, 0x0b, 0x65, 0xc6, 0x35, 0x8c, 0x69, 0x4e, 0x93, 0xa3, 0x32, 0x74, 0x18, 0xd4,
+       0x06, 0xaf, 0xe5, 0x74, 0xb9, 0x63, 0x89, 0x41, 0x25, 0x2f, 0x15, 0xb6, 0x71, 0x45, 0x02, 0x5e,
+       0x71, 0x11, 0xec, 0xea, 0xb8, 0x3a, 0x3d, 0xf2, 0x87, 0x2b, 0x71, 0xb8, 0x7e, 0xc8, 0xc7, 0x06,
+       0x12, 0x87, 0x21, 0x61, 0x2f, 0xeb, 0x33, 0x44, 0xe1, 0x3e, 0xa7, 0x77, 0x6a, 0xfe, 0x5d, 0xee,
+       0x4c, 0x77, 0x57, 0x74, 0xf7, 0x64, 0x2b, 0x6f, 0x12, 0x1b, 0x0e, 0xec, 0x49, 0x41, 0x81, 0x93,
+       0x6b, 0xf9, 0x3b, 0x4e, 0x83, 0x53, 0xd7, 0x05, 0xe0, 0x29, 0x78, 0xf2, 0xd3, 0xe5, 0x81, 0x6f,
+       0x47, 0xd1, 0xc8, 0xae, 0xb3, 0x22, 0xa9, 0x29, 0x61, 0xe2, 0x36, 0x26, 0xb9, 0x0d, 0x9d, 0x23,
+       0x90, 0x45, 0x8b, 0x42, 0xbc, 0x8b, 0x60, 0xd5, 0xd2, 0x56, 0xc6, 0x09, 0xfd, 0x45, 0xff, 0x8c,
+       0x54, 0x69, 0x74, 0x81, 0x90, 0x7a, 0x31, 0x6f, 0xf0, 0x16, 0x4c, 0xef, 0x1c, 0xa9, 0x97, 0xc9,
+       0x4e, 0xfe, 0x7d, 0x87, 0x7a, 0x47, 0x3f, 0xa5, 0xc8, 0x20, 0xd3, 0x4a, 0xe2, 0xf3, 0xf6, 0x3a,
+       0xf1, 0xef, 0x24, 0x5e, 0x35, 0xc8, 0xdf, 0x7b, 0x12, 0xda, 0xcc, 0xef, 0xbb, 0xf2, 0xfa, 0x28,
+       0xf6, 0x38, 0x57, 0xcf, 0x41, 0xd6, 0x43, 0x21, 0x62, 0xc6, 0xa3, 0x3f, 0xf5, 0xd1, 0x86, 0x41,
+       0x42, 0xb6, 0x69, 0xca, 0xb0, 0x8a, 0xba, 0xba, 0xbe, 0x97, 0x85, 0x02, 0x03, 0x01, 0x00, 0x01,
+       0xa3, 0x81, 0xbd, 0x30, 0x81, 0xba, 0x30, 0x3e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+       0x01, 0x01, 0x04, 0x32, 0x30, 0x30, 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+       0x30, 0x01, 0x86, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e,
+       0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x30, 0x34,
+       0x2d, 0x61, 0x73, 0x69, 0x30, 0x33, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
+       0x14, 0x0a, 0x8f, 0x13, 0x24, 0x0d, 0xc4, 0xe4, 0xe7, 0x97, 0x65, 0x35, 0xc8, 0x19, 0x91, 0x38,
+       0x28, 0xce, 0x9b, 0x50, 0xdb, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04,
+       0x02, 0x30, 0x00, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
+       0x12, 0x75, 0x7c, 0x47, 0x92, 0xfd, 0x83, 0xe3, 0xbe, 0x2e, 0xfc, 0x59, 0x7f, 0x67, 0x43, 0x81,
+       0x35, 0x10, 0x45, 0xec, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x01, 0x01, 0xff, 0x04, 0x10,
+       0x30, 0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x05, 0x0c, 0x01,
+       0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80,
+       0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
+       0x82, 0x01, 0x01, 0x00, 0x59, 0x19, 0xdd, 0x6c, 0xf5, 0xb6, 0xf9, 0x93, 0x69, 0xe5, 0xcd, 0x64,
+       0x5c, 0x4c, 0xaa, 0xd8, 0x86, 0x44, 0x6b, 0xca, 0x48, 0x6f, 0x2b, 0x15, 0x8f, 0xef, 0x1a, 0x5c,
+       0xc9, 0xb2, 0x5b, 0x51, 0xee, 0xae, 0xf8, 0xeb, 0x7e, 0x05, 0x4a, 0xa1, 0x27, 0xd3, 0x15, 0x41,
+       0xa1, 0x2c, 0x7e, 0x81, 0x96, 0xa8, 0xba, 0x8d, 0x1c, 0xc0, 0x0a, 0xce, 0xfd, 0x4b, 0xbc, 0x56,
+       0x80, 0xe8, 0xf1, 0x04, 0x05, 0xd9, 0x17, 0x3d, 0x29, 0x6d, 0x99, 0xf5, 0xcc, 0x3a, 0x80, 0x7c,
+       0x03, 0xb0, 0x8a, 0x4e, 0x2c, 0xdb, 0x24, 0x42, 0xa7, 0xa6, 0x8b, 0x2e, 0xff, 0x9c, 0xec, 0xce,
+       0xe0, 0x0f, 0xd3, 0x5c, 0x0a, 0xed, 0x35, 0x14, 0xd0, 0x33, 0x76, 0xe0, 0x46, 0x09, 0x35, 0x54,
+       0x40, 0x9b, 0x56, 0x8a, 0x45, 0x17, 0xa7, 0x50, 0x95, 0x5c, 0x9f, 0x5e, 0x95, 0x26, 0x89, 0xfe,
+       0x79, 0xc6, 0x01, 0x3b, 0xf9, 0x64, 0x83, 0x28, 0x2b, 0x2d, 0x24, 0xbd, 0xb8, 0x4a, 0xca, 0x9a,
+       0xba, 0x59, 0x5f, 0x72, 0xdd, 0x90, 0xcc, 0x4c, 0xed, 0x49, 0xf6, 0x11, 0x10, 0x7c, 0x34, 0x86,
+       0x3f, 0x3e, 0x9a, 0xc0, 0xe6, 0xda, 0xf0, 0x6d, 0xb0, 0xd2, 0xf0, 0x46, 0x1e, 0x33, 0x53, 0x4a,
+       0x5c, 0xd3, 0xdc, 0x9b, 0x74, 0x3d, 0x3e, 0x85, 0x9c, 0x19, 0xca, 0xb5, 0x26, 0xd5, 0xda, 0x22,
+       0x7d, 0x52, 0xe6, 0x8c, 0x95, 0xd8, 0x30, 0x61, 0xf5, 0x3e, 0x05, 0x40, 0xe5, 0xd0, 0xcb, 0x91,
+       0x28, 0x17, 0x4c, 0xf3, 0xf8, 0x06, 0x4c, 0x71, 0x80, 0xe0, 0x7c, 0x11, 0x7b, 0x00, 0xed, 0xe6,
+       0x93, 0x8c, 0x12, 0x9e, 0xcc, 0x65, 0x5a, 0xb6, 0x61, 0x21, 0xe0, 0x0f, 0x3a, 0x8e, 0xcf, 0x12,
+       0xea, 0x16, 0xbb, 0x91, 0x7e, 0x6c, 0x11, 0xb2, 0x29, 0x8a, 0x41, 0x46, 0xc3, 0xae, 0xd9, 0xf7,
+       0x15, 0xe8, 0xaa, 0x86
+};
+
+static const uint8_t kMobileIntermediate[] = {
+       0x30, 0x82, 0x04, 0x13, 0x30, 0x82, 0x02, 0xfb, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x60,
+       0x25, 0x4e, 0x56, 0x81, 0x16, 0xcf, 0xf1, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+       0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
+       0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a,
+       0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03,
+       0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
+       0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
+       0x74, 0x79, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x41, 0x70, 0x70,
+       0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x32,
+       0x30, 0x39, 0x31, 0x33, 0x32, 0x32, 0x33, 0x35, 0x33, 0x37, 0x5a, 0x17, 0x0d, 0x32, 0x37, 0x30,
+       0x39, 0x31, 0x33, 0x32, 0x32, 0x33, 0x35, 0x33, 0x37, 0x5a, 0x30, 0x81, 0x87, 0x31, 0x3b, 0x30,
+       0x39, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x32, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x53, 0x79,
+       0x73, 0x74, 0x65, 0x6d, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+       0x20, 0x32, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+       0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03,
+       0x55, 0x04, 0x0b, 0x0c, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
+       0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
+       0x74, 0x79, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70,
+       0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+       0x13, 0x02, 0x55, 0x53, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+       0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
+       0x02, 0x82, 0x01, 0x01, 0x00, 0x9e, 0x48, 0xf6, 0x8f, 0xab, 0x1b, 0x89, 0xa5, 0x9f, 0x34, 0x47,
+       0xb6, 0x38, 0x30, 0xa7, 0xb0, 0x62, 0xa4, 0x99, 0x84, 0x2a, 0x74, 0x4b, 0x47, 0x5b, 0x66, 0x35,
+       0x69, 0xfe, 0x97, 0x01, 0x64, 0x18, 0x9d, 0x0a, 0xf8, 0xd7, 0x33, 0x2a, 0x64, 0xd8, 0xbc, 0x03,
+       0x4f, 0xcd, 0x4d, 0x80, 0x90, 0xd2, 0xc3, 0xc5, 0xd1, 0x8c, 0xc1, 0x73, 0xf6, 0x5a, 0x50, 0x70,
+       0xcd, 0xe0, 0x94, 0x35, 0x82, 0xc4, 0x59, 0xca, 0xba, 0xa9, 0x94, 0xbd, 0x88, 0x36, 0x7a, 0x32,
+       0xdf, 0x08, 0x29, 0xe0, 0x9c, 0x19, 0x1c, 0x68, 0x02, 0x60, 0x87, 0xfc, 0x2e, 0x8a, 0x3c, 0x37,
+       0x4d, 0x7c, 0x81, 0xbb, 0x6c, 0x6f, 0x72, 0x45, 0xf5, 0xb3, 0x96, 0x66, 0x5e, 0xab, 0x97, 0x54,
+       0x50, 0x03, 0xc0, 0x41, 0xfc, 0xb5, 0xa8, 0xf7, 0x78, 0xde, 0x4c, 0x9a, 0x67, 0xf4, 0x4d, 0x27,
+       0x54, 0x9e, 0xc8, 0x75, 0xea, 0x8c, 0x76, 0xc1, 0xb5, 0x79, 0xe3, 0x60, 0xce, 0x98, 0x21, 0x38,
+       0x7b, 0x9a, 0x53, 0xe8, 0x57, 0x69, 0x13, 0xf0, 0xf0, 0x86, 0x91, 0x2e, 0xad, 0x75, 0xb9, 0x53,
+       0x4a, 0x30, 0xf6, 0x6d, 0x96, 0x8e, 0x5e, 0xe7, 0xe9, 0xa5, 0x16, 0xe7, 0xb4, 0x5b, 0xe7, 0xe9,
+       0x6e, 0x4f, 0xe7, 0x38, 0xda, 0x53, 0x39, 0x60, 0x0e, 0xfd, 0xd0, 0x0b, 0x19, 0x52, 0x5d, 0x79,
+       0x3a, 0x5d, 0x7b, 0x0d, 0x19, 0x91, 0x72, 0x94, 0x0e, 0x03, 0xa6, 0x14, 0xca, 0xdd, 0x7a, 0x27,
+       0xed, 0x22, 0x21, 0xeb, 0x67, 0x01, 0xc0, 0x98, 0x4f, 0xf7, 0x78, 0x81, 0x34, 0xfb, 0x08, 0x48,
+       0xb6, 0xec, 0xa4, 0xdb, 0x60, 0xd3, 0x9d, 0xa7, 0x46, 0x6c, 0x50, 0xa6, 0x14, 0x4a, 0x30, 0xee,
+       0x77, 0x87, 0x64, 0xb6, 0xb2, 0xb4, 0x92, 0xfc, 0x45, 0xb3, 0x80, 0x59, 0xbd, 0x85, 0x9c, 0x2f,
+       0xd1, 0xd7, 0x59, 0xe3, 0x0f, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa6, 0x30, 0x81, 0xa3,
+       0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x12, 0x75, 0x7c, 0x47, 0x92,
+       0xfd, 0x83, 0xe3, 0xbe, 0x2e, 0xfc, 0x59, 0x7f, 0x67, 0x43, 0x81, 0x35, 0x10, 0x45, 0xec, 0x30,
+       0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff,
+       0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x2b, 0xd0, 0x69,
+       0x47, 0x94, 0x76, 0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e, 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08,
+       0x5e, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x27, 0x30, 0x25, 0x30, 0x23, 0xa0, 0x21,
+       0xa0, 0x1f, 0x86, 0x1d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x61,
+       0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72,
+       0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01,
+       0x06, 0x30, 0x10, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x06, 0x02, 0x0a, 0x04,
+       0x02, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
+       0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xaa, 0x3d, 0x38, 0x8a, 0x96, 0x9b, 0xc7, 0x94, 0x97,
+       0x3d, 0x3e, 0x5b, 0x1f, 0x09, 0x43, 0xe1, 0x1a, 0x6e, 0x6a, 0x4d, 0xd6, 0x38, 0xbb, 0x8a, 0x6d,
+       0x00, 0xc9, 0x93, 0xdc, 0x3e, 0xa2, 0xc3, 0x2a, 0x97, 0xc1, 0x4f, 0x07, 0xa0, 0xa3, 0x14, 0x6c,
+       0xd9, 0x0b, 0x9a, 0xcd, 0xb1, 0xcf, 0x7c, 0xc0, 0x67, 0x75, 0x12, 0xee, 0x2e, 0xb0, 0x28, 0x17,
+       0x18, 0x7e, 0x73, 0x3d, 0xb4, 0x04, 0x91, 0x39, 0x7c, 0x37, 0xfb, 0xbd, 0x34, 0x01, 0xa0, 0xde,
+       0x77, 0xa7, 0x5b, 0xb6, 0x47, 0x8e, 0x73, 0x3a, 0x8f, 0x7b, 0x63, 0x58, 0xc4, 0xa3, 0x6d, 0x19,
+       0x4d, 0x9d, 0x9e, 0xd6, 0x3e, 0xbe, 0x18, 0x53, 0xe9, 0x30, 0x4d, 0xd2, 0xad, 0xef, 0x4b, 0xf6,
+       0xa4, 0x84, 0xcf, 0x25, 0xfc, 0xea, 0x0d, 0x33, 0x58, 0x51, 0x00, 0xe2, 0x4b, 0xfe, 0x74, 0xd9,
+       0x47, 0x13, 0x9e, 0xa7, 0xd7, 0x37, 0x6a, 0xea, 0x27, 0x0c, 0x6c, 0x7e, 0x8a, 0x93, 0xee, 0x60,
+       0x10, 0x30, 0x1b, 0xf5, 0x59, 0x2a, 0x14, 0x4f, 0xd8, 0x7f, 0xe7, 0xb0, 0xe6, 0x3d, 0xfe, 0x72,
+       0xe0, 0xc8, 0x52, 0x21, 0x15, 0x37, 0x18, 0x59, 0xd4, 0x7c, 0x5c, 0x8d, 0x55, 0x0b, 0x9b, 0xfb,
+       0x3a, 0x75, 0x0f, 0xf6, 0x06, 0x29, 0xb6, 0xc2, 0x7f, 0x8d, 0x95, 0xce, 0x68, 0x77, 0x73, 0xae,
+       0xde, 0x81, 0xfa, 0xce, 0x09, 0x72, 0xb1, 0x6c, 0xce, 0xe4, 0x94, 0x9e, 0x85, 0xf8, 0xdc, 0xba,
+       0xc4, 0x5f, 0x77, 0xe9, 0x9e, 0x03, 0x99, 0x34, 0x8d, 0xcc, 0xdc, 0x9f, 0x56, 0x98, 0xed, 0x28,
+       0xed, 0x06, 0x56, 0x80, 0xea, 0x52, 0x3a, 0x95, 0xc4, 0x64, 0x8f, 0x0c, 0xd9, 0x57, 0xbd, 0xc2,
+       0xa9, 0x8d, 0xa0, 0x3a, 0xe2, 0x6c, 0x5a, 0x2a, 0x7b, 0xda, 0xf6, 0x81, 0x1a, 0x03, 0x17, 0x6b,
+       0x0c, 0x0c, 0xda, 0xbd, 0x8e, 0x23, 0x06                                                      
+                              
+};
+
+// Escrow Service Key F98EB04C6AA62F4022709406305387C61415DDD770A24039C1415F24BF918803
+static const uint8_t kEscrowLeafCert[] = {
+       0x30, 0x82, 0x04, 0x07, 0x30, 0x82, 0x02, 0xef, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x05, 0x00,
+       0x9b, 0x6e, 0xef, 0x8d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+       0x0b, 0x05, 0x00, 0x30, 0x79, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x05, 0x13, 0x03,
+       0x31, 0x30, 0x30, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
+       0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65,
+       0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d,
+       0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+       0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x1f, 0x30,
+       0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x45, 0x73, 0x63, 0x72, 0x6f, 0x77, 0x20, 0x53,
+       0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e,
+       0x17, 0x0d, 0x31, 0x33, 0x30, 0x38, 0x30, 0x32, 0x32, 0x33, 0x32, 0x34, 0x34, 0x38, 0x5a, 0x17,
+       0x0d, 0x31, 0x35, 0x30, 0x38, 0x30, 0x32, 0x32, 0x33, 0x32, 0x34, 0x34, 0x38, 0x5a, 0x30, 0x81,
+       0x9b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b,
+       0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41, 0x31, 0x13, 0x30, 0x11, 0x06,
+       0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+       0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x03, 0x45, 0x54, 0x53, 0x31, 0x5c,
+       0x30, 0x5a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x53, 0x45, 0x73, 0x63, 0x72, 0x6f, 0x77, 0x20,
+       0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x39, 0x42, 0x36, 0x45,
+       0x45, 0x46, 0x38, 0x44, 0x37, 0x42, 0x33, 0x43, 0x34, 0x39, 0x31, 0x32, 0x46, 0x35, 0x35, 0x35,
+       0x32, 0x32, 0x32, 0x32, 0x42, 0x42, 0x34, 0x31, 0x44, 0x38, 0x34, 0x43, 0x43, 0x31, 0x39, 0x43,
+       0x33, 0x35, 0x37, 0x37, 0x32, 0x35, 0x41, 0x36, 0x43, 0x35, 0x46, 0x34, 0x45, 0x35, 0x43, 0x43,
+       0x36, 0x30, 0x37, 0x41, 0x32, 0x44, 0x37, 0x32, 0x31, 0x35, 0x41, 0x43, 0x30, 0x82, 0x01, 0x22,
+       0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
+       0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc5, 0xc7, 0x51,
+       0xf1, 0x3f, 0x9a, 0x5d, 0xd7, 0xc1, 0x03, 0x42, 0x30, 0x84, 0xdb, 0xbc, 0x6c, 0x00, 0x6c, 0xcc,
+       0x57, 0x97, 0xaf, 0xfe, 0x9e, 0xa0, 0x06, 0x9f, 0xe8, 0xa9, 0x59, 0xe1, 0xf8, 0xed, 0x23, 0x05,
+       0x57, 0xe3, 0xd8, 0xdf, 0xf8, 0x31, 0x80, 0x8b, 0x31, 0x08, 0x2a, 0xc3, 0x7b, 0x16, 0xba, 0x27,
+       0x84, 0x4e, 0xbb, 0x55, 0x5b, 0xd2, 0xda, 0x2d, 0xea, 0xda, 0x5c, 0xf0, 0x21, 0x58, 0x63, 0x74,
+       0xa9, 0x90, 0x99, 0xbe, 0x87, 0x19, 0x7d, 0x87, 0xfc, 0xcb, 0xb6, 0xc9, 0x39, 0x51, 0x6a, 0xa7,
+       0x81, 0x05, 0x50, 0x2d, 0xa2, 0x10, 0x6d, 0x58, 0xa5, 0x62, 0x29, 0x53, 0xce, 0xa6, 0x53, 0xad,
+       0x3f, 0x50, 0xda, 0x1a, 0x1e, 0x2c, 0xe3, 0xae, 0x24, 0x88, 0xa5, 0x4c, 0xa3, 0x3a, 0xe1, 0xc6,
+       0xa9, 0xcf, 0xb5, 0x53, 0x30, 0xbf, 0x7b, 0xea, 0x77, 0x21, 0x24, 0xfd, 0x91, 0x4c, 0x6f, 0x60,
+       0x9f, 0x78, 0xf9, 0xed, 0x84, 0xe5, 0xee, 0xab, 0x07, 0xc5, 0x34, 0xa9, 0xe2, 0x0a, 0xf5, 0xf5,
+       0xfa, 0x66, 0x75, 0xc8, 0x3e, 0x9c, 0xdd, 0xea, 0x60, 0xf0, 0x83, 0x03, 0x19, 0x08, 0xa4, 0x85,
+       0xb0, 0xf3, 0xb1, 0xf1, 0x7a, 0x3d, 0xb4, 0xc8, 0xdd, 0x25, 0x5a, 0x1b, 0xf5, 0xa0, 0x78, 0xf9,
+       0xbb, 0x08, 0x27, 0x6f, 0xa9, 0xf9, 0x17, 0xe8, 0xcb, 0x01, 0xa3, 0x5a, 0xd0, 0x67, 0xfb, 0xb7,
+       0xef, 0xb7, 0x5c, 0x20, 0x94, 0x17, 0x5d, 0x46, 0xbd, 0xd2, 0xfe, 0xb6, 0x68, 0x88, 0x9f, 0xa6,
+       0x0b, 0x97, 0x0f, 0x2e, 0x10, 0x23, 0x52, 0x9e, 0x69, 0x8b, 0xf4, 0x80, 0x83, 0x0e, 0x5b, 0x04,
+       0xfc, 0x4e, 0xa1, 0x32, 0x44, 0x8a, 0x63, 0x3e, 0x3b, 0x0b, 0x70, 0x15, 0xd4, 0x17, 0xc1, 0xbe,
+       0xbb, 0x01, 0x37, 0xe8, 0xfb, 0x58, 0x8b, 0x3d, 0xec, 0xc4, 0x47, 0x82, 0xe5, 0x02, 0x03, 0x01,
+       0x00, 0x01, 0xa3, 0x73, 0x30, 0x71, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
+       0x04, 0x02, 0x30, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04,
+       0x03, 0x02, 0x05, 0x20, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xb7,
+       0x34, 0x54, 0x7b, 0x16, 0x2a, 0x38, 0x22, 0xd5, 0x79, 0x7b, 0xbf, 0x5c, 0x62, 0x16, 0x59, 0xc5,
+       0x53, 0x9f, 0xac, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
+       0xfd, 0x78, 0x96, 0x53, 0x80, 0xd6, 0xf6, 0xdc, 0xa6, 0xc3, 0x59, 0x06, 0x38, 0xed, 0x79, 0x3e,
+       0x8f, 0x50, 0x1b, 0x50, 0x30, 0x11, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x06,
+       0x17, 0x01, 0x04, 0x03, 0x02, 0x01, 0x0a, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+       0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x01, 0x41, 0x68, 0xd9, 0xd5,
+       0xb5, 0xbe, 0x2d, 0xa1, 0xe7, 0x52, 0x28, 0x2c, 0x4f, 0xe7, 0x43, 0x39, 0x4d, 0x1f, 0xeb, 0x09,
+       0xd9, 0xc7, 0xca, 0x6f, 0x63, 0x60, 0x7f, 0x7c, 0xb5, 0x7c, 0x5e, 0x4b, 0xab, 0xd5, 0x8b, 0x34,
+       0x5b, 0x50, 0xda, 0x3e, 0x37, 0xa8, 0x26, 0xf5, 0xdb, 0x76, 0xc4, 0x4a, 0x48, 0x09, 0xcf, 0x04,
+       0x0a, 0x17, 0x6c, 0x8d, 0x3c, 0x6e, 0x1e, 0x41, 0xfc, 0xef, 0x45, 0xbd, 0x72, 0x59, 0x5e, 0x10,
+       0x61, 0x4e, 0xad, 0x0e, 0xe4, 0x76, 0x3c, 0xf7, 0x87, 0xef, 0x54, 0xdd, 0x61, 0xe9, 0x91, 0x0f,
+       0x7e, 0x52, 0xd6, 0x9e, 0x02, 0xd7, 0xb6, 0xcc, 0xa4, 0x9e, 0x7d, 0xba, 0x5f, 0xb4, 0x40, 0xc9,
+       0xe6, 0x95, 0x61, 0xae, 0xb9, 0x89, 0xba, 0x25, 0x1b, 0xb6, 0xde, 0x08, 0x7f, 0x88, 0xef, 0x7c,
+       0x59, 0x4d, 0x73, 0xc7, 0xf5, 0x07, 0x94, 0x13, 0x7b, 0xfc, 0x9f, 0x75, 0x0d, 0x1a, 0x69, 0xf0,
+       0x51, 0x36, 0x1e, 0x46, 0x76, 0xc8, 0x27, 0x4e, 0x65, 0x58, 0x66, 0x41, 0x5e, 0x9d, 0xfe, 0xf1,
+       0x10, 0xd5, 0x3c, 0x5b, 0xea, 0xcd, 0x96, 0x37, 0x4d, 0x76, 0x88, 0x60, 0xfb, 0x3f, 0xb2, 0x7a,
+       0x00, 0xb4, 0xe0, 0xb6, 0xb9, 0x76, 0x6e, 0x02, 0xb6, 0xf7, 0x8d, 0x8b, 0x3a, 0x5c, 0xde, 0x4e,
+       0xb9, 0xa4, 0x05, 0xc6, 0x14, 0xa6, 0x3f, 0x6c, 0xbd, 0xfd, 0xee, 0x0b, 0xf5, 0x5c, 0x27, 0x56,
+       0xc5, 0x48, 0x55, 0x78, 0x72, 0xdc, 0xca, 0x95, 0xb7, 0x02, 0xb2, 0xdc, 0x4e, 0xbd, 0xe2, 0x78,
+       0x87, 0xcc, 0xb5, 0xb0, 0x7c, 0x22, 0x52, 0xc1, 0xb0, 0x5a, 0x09, 0x9d, 0xb6, 0xbe, 0xe7, 0x4b,
+       0xa2, 0x0e, 0x20, 0x43, 0x28, 0x77, 0x88, 0x1f, 0xd6, 0xa4, 0xb9, 0x56, 0xd0, 0xd0, 0xa6, 0x0f,
+       0xa3, 0xef, 0x2e, 0xb7, 0x1d, 0x40, 0x61, 0xf8, 0xb9, 0x17, 0x4c,               
+};
+
+
+#if 0
+static inline void test_mobile(void)
+{
+       SecCertificateRef aCert = NULL;
+       SecCertificateRef intermediateCert = NULL;
+       SecCertificateRef rootCert = NULL;
+       SecTrustResultType trustResult = kSecTrustResultUnspecified;
+       SecPolicyRef policy = NULL;
+       CFArrayRef certs = NULL;
+       SecTrustRef trust = NULL;
+       
+       isnt(aCert = SecCertificateCreateWithBytes(NULL, kDemoContentSigningCert, sizeof(kDemoContentSigningCert)),
+           NULL, "create aCert from kDemoContentSigningCert");
+       
+       isnt(intermediateCert = SecCertificateCreateWithBytes(NULL, kMobileIntermediate, sizeof(kMobileIntermediate)),
+       NULL, "create intermediate from kMobileIntermediate");
+               
+       SecCertificateRef refs[] = {aCert, intermediateCert};
+       certs = CFArrayCreate(NULL, (const void **)refs, 2, NULL);
+       
+       isnt(policy = SecPolicyCreateMobileStoreSigner(),
+               NULL, "create mobile policy");
+               
+       ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
+        "create trust for mobile store test cert");
+       
+       ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate mobile store trust");
+       
+       is_status(trustResult, kSecTrustResultUnspecified,
+               "trust is kSecTrustResultRecoverableTrustFailure");
+               
+       CFReleaseSafe(trust);
+       CFReleaseSafe(policy);
+       CFReleaseSafe(aCert);
+     
+       isnt(aCert = SecCertificateCreateWithBytes(NULL, kTestDemoContentSigningCert, sizeof(kTestDemoContentSigningCert)),
+           NULL, "create aCert from kDemoContentSigningCert");
+       
+       isnt(policy = SecPolicyCreateTestMobileStoreSigner(),
+               NULL, "create Test mobile policy");
+               
+       ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
+        "create trust for mobile store test cert");
+                       
+       ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate test mobile store trust");
+       
+       is_status(trustResult, kSecTrustResultUnspecified,
+               "trust is kSecTrustResultRecoverableTrustFailure");
+       
+       CFReleaseSafe(trust);
+       CFReleaseSafe(policy);
+       CFReleaseSafe(aCert);
+       CFReleaseSafe(certs);
+       CFReleaseSafe(intermediateCert);
+       CFReleaseSafe(rootCert);
+       
+}
+#endif // 0  
+
+static void test_escrow_with_anchor_roots(CFArrayRef anchors)
+{
+       SecCertificateRef escrowLeafCert = NULL;
+       SecTrustResultType trustResult = kSecTrustResultUnspecified;
+       SecPolicyRef policy = NULL;
+       CFArrayRef certs = NULL;
+       SecTrustRef trust = NULL;
+       
+       isnt(escrowLeafCert = SecCertificateCreateWithBytes(NULL, kEscrowLeafCert, sizeof(kEscrowLeafCert)),
+           NULL, "could not create aCert from kEscrowLeafCert");
+               
+       certs = CFArrayCreate(NULL, (const void **)&escrowLeafCert, 1, NULL);   
+       
+       isnt(policy = SecPolicyCreateEscrowServiceSigner(),
+               NULL, "could not create Escrow policy for GM Escrow Leaf cert");
+                               
+       ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
+        "coult not create trust for escrow service test GM Escrow Leaf cert"); 
+       
+       SecTrustSetAnchorCertificates(trust,  anchors);
+       
+       ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate escrow service trust for GM Escrow Leaf cert");
+               
+       is_status(trustResult, kSecTrustResultUnspecified,
+               "trust is not kSecTrustResultUnspecified for GM Escrow Leaf cert");
+               
+       CFReleaseSafe(trust);
+       CFReleaseSafe(policy);
+       CFReleaseSafe(certs);
+       CFReleaseSafe(escrowLeafCert);
+       
+}
+
+static inline void test_escrow()
+{
+       CFArrayRef anchors = NULL;
+       isnt(anchors = SecCertificateCopyEscrowRoots(kSecCertificateProductionEscrowRoot), NULL, "unable to get production anchors");
+       test_escrow_with_anchor_roots(anchors);
+       CFReleaseSafe(anchors); 
+}
+
+static void tests(void)
+{
+    test_escrow();
+}
+
+#endif /* defined(NO_SERVER) && NO_SERVER == 1 */
+
+int si_71_mobile_store_policy(int argc, char *const *argv)
+{
+#if defined(NO_SERVER) && NO_SERVER == 1
+
+       plan_tests(21);
+    
+       tests();
+#endif 
+    return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-72-syncableitems.c b/sec/Security/Regressions/secitem/si-72-syncableitems.c
new file mode 100644 (file)
index 0000000..b55e3fe
--- /dev/null
@@ -0,0 +1,176 @@
+
+//
+//  si-72-syncableitems.c
+//  regressions
+//
+//  Created by Ken McLeod on 5/18/13.
+//
+//
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/Security.h>
+#include <Security/SecItemPriv.h>
+#include <Security/SecInternal.h>
+#include <utilities/array_size.h>
+
+#include "Security_regressions.h"
+
+static void tests(void)
+{
+    CFUUIDRef uuid = CFUUIDCreate(0);
+       const CFStringRef uuidstr = CFUUIDCreateString(0, uuid);
+       const CFStringRef account = CFStringCreateWithFormat(NULL, NULL, CFSTR("Test Account %@"), uuidstr);
+       const CFStringRef service = CFSTR("Test Service");
+       const CFStringRef label = CFSTR("Test Synchronizable Item");
+       const CFStringRef comment = CFSTR("Test Comment");
+       const CFDataRef passwordData = CFDataCreate(NULL, (const UInt8*)"Test", (CFIndex)5);
+
+    CFReleaseSafe(uuid);
+    CFReleaseSafe(uuidstr);
+    
+       CFDictionaryRef query = NULL;
+       CFDictionaryRef attrs = NULL;
+       CFDictionaryRef result = NULL;
+
+       /* Test adding a synchronizable item */
+       {
+               const void *keys[] = {
+                       kSecClass, kSecAttrLabel, kSecAttrComment, kSecAttrAccount, kSecAttrService,
+                       kSecAttrSynchronizable,
+                       kSecValueData, kSecReturnAttributes };
+               const void *values[] = {
+                       kSecClassGenericPassword, label, comment, account, service,
+                       kCFBooleanTrue,
+                       passwordData, kCFBooleanTrue };
+
+               attrs = CFDictionaryCreate(NULL, keys, values,
+                       array_size(keys),
+                       &kCFTypeDictionaryKeyCallBacks,
+                       &kCFTypeDictionaryValueCallBacks);
+
+               is_status(SecItemAdd(attrs, (CFTypeRef *)&result),
+                               errSecSuccess, "SecItemAdd sync=true");
+
+               CFReleaseSafe(attrs);
+               CFReleaseNull(result);
+       }
+
+       /* Test finding the synchronizable item we just added, using sync=true */
+       {
+               const void *keys[] = {
+                       kSecClass, // class attribute is required
+                       kSecAttrAccount, kSecAttrService, // we'll look up by account and service, which determine uniqueness
+                       kSecAttrSynchronizable, // we want to get synchronizable results
+                       kSecReturnAttributes };
+               const void *values[] = {
+                       kSecClassGenericPassword,
+                       account, service,
+                       kCFBooleanTrue, // only return synchronizable results
+                       kCFBooleanTrue };
+
+               query = CFDictionaryCreate(NULL, keys, values,
+                       array_size(keys),
+                       &kCFTypeDictionaryKeyCallBacks,
+                       &kCFTypeDictionaryValueCallBacks);
+
+               is_status(SecItemCopyMatching(query, (CFTypeRef *)&result),
+                       errSecSuccess, "SecItemCopyMatching sync=true");
+
+               CFReleaseSafe(query);
+               CFReleaseNull(result);
+       }
+
+       /* Test finding the synchronizable item we just added, using sync=any */
+       {
+               const void *keys[] = {
+                       kSecClass, // class attribute is required
+                       kSecAttrAccount, kSecAttrService, // we'll look up by account and service, which determine uniqueness
+                       kSecAttrSynchronizable, // we want to get synchronizable results
+                       kSecReturnAttributes };
+               const void *values[] = {
+                       kSecClassGenericPassword,
+                       account, service,
+                       kSecAttrSynchronizableAny, // return any match, regardless of whether it is synchronizable
+                       kCFBooleanTrue };
+
+               query = CFDictionaryCreate(NULL, keys, values,
+                       array_size(keys),
+                       &kCFTypeDictionaryKeyCallBacks,
+                       &kCFTypeDictionaryValueCallBacks);
+
+               is_status(SecItemCopyMatching(query, (CFTypeRef *)&result),
+                       errSecSuccess, "SecItemCopyMatching sync=any");
+
+               CFReleaseSafe(query);
+               CFReleaseNull(result);
+       }
+
+       /* Test updating the synchronizable item */
+       {
+               const void *keys[] = {
+                       kSecClass, // class attribute is required
+                       kSecAttrAccount, kSecAttrService, // we'll look up by account and service, which determine uniqueness
+                       kSecAttrSynchronizable }; // we want synchronizable results
+               const void *values[] = {
+                       kSecClassGenericPassword,
+                       account, service,
+                       kCFBooleanTrue }; // we only want to find the synchronizable item here, not a non-synchronizable one
+
+               query = CFDictionaryCreate(NULL, keys, values,
+                       array_size(keys),
+                       &kCFTypeDictionaryKeyCallBacks,
+                       &kCFTypeDictionaryValueCallBacks);
+
+               const void *update_keys[] = { kSecAttrComment };
+               const void *update_values[] = { CFSTR("Updated Comment") };
+               attrs = CFDictionaryCreate(NULL, update_keys, update_values,
+                       array_size(update_keys),
+                       &kCFTypeDictionaryKeyCallBacks,
+                       &kCFTypeDictionaryValueCallBacks);
+
+               is_status(SecItemUpdate(query, attrs),
+                       errSecSuccess, "SecItemUpdate sync=true");
+
+               CFReleaseSafe(query);
+               CFReleaseSafe(attrs);
+       }
+
+       /* Test finding the updated item with its new attribute */
+       {
+               const void *keys[] = {
+                       kSecClass, // class attribute is required
+                       kSecAttrAccount, kSecAttrService, // we'll look up by account and service, which determine uniqueness
+                       kSecAttrComment, // also search on the attr we just changed, so we know we've found the updated item
+                       kSecAttrSynchronizable }; // we want synchronizable results
+               const void *values[] = {
+                       kSecClassGenericPassword,
+                       account, service,
+                       CFSTR("Updated Comment"),
+                       kCFBooleanTrue }; // we only want to find the synchronizable item here, not a non-synchronizable one
+
+               query = CFDictionaryCreate(NULL, keys, values,
+                       array_size(keys),
+                       &kCFTypeDictionaryKeyCallBacks,
+                       &kCFTypeDictionaryValueCallBacks);
+
+               is_status(SecItemCopyMatching(query, (CFTypeRef *)&result),
+                       errSecSuccess, "SecItemCopyMatching post-update");
+
+               CFReleaseSafe(result);
+               // re-use query in next test...
+       }
+
+       /* Test deleting the item */
+       {
+               is_status(SecItemDelete(query), errSecSuccess, "SecItemDelete sync=true");
+
+               CFReleaseSafe(query);
+       }
+}
+
+int si_72_syncableitems(int argc, char * const *argv)
+{
+       plan_tests(6);
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-73-secpasswordgenerate.c b/sec/Security/Regressions/secitem/si-73-secpasswordgenerate.c
new file mode 100644 (file)
index 0000000..30e79f7
--- /dev/null
@@ -0,0 +1,932 @@
+//
+//  si-73-secpasswordgenerate.c
+//  sec
+//
+
+#include <stdio.h>
+#include <Security/SecPasswordGenerate.h>
+#include <utilities/SecCFRelease.h>
+#include "Security_regressions.h"
+
+static void tests(void)
+{
+    CFErrorRef error = NULL;
+    CFStringRef password = NULL;
+    CFMutableArrayRef requiredCharacterSets = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+    CFMutableDictionaryRef passwordRequirements = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+
+    CFCharacterSetRef uppercaseLetterCharacterSet = CFCharacterSetGetPredefined(kCFCharacterSetUppercaseLetter);
+    CFCharacterSetRef lowercaseLetterCharacterSet = CFCharacterSetGetPredefined(kCFCharacterSetLowercaseLetter);
+    CFCharacterSetRef decimalDigitCharacterSet = CFCharacterSetGetPredefined(kCFCharacterSetDecimalDigit);
+    
+    CFArrayAppendValue(requiredCharacterSets, uppercaseLetterCharacterSet);
+    CFArrayAppendValue(requiredCharacterSets, lowercaseLetterCharacterSet);
+    CFArrayAppendValue(requiredCharacterSets, decimalDigitCharacterSet);
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordDefaultForType, CFSTR("true"));
+    
+    //test default PIN
+    password = SecPasswordGenerate(kSecPasswordTypePIN, &error, passwordRequirements);
+    isnt(password, NULL);
+    ok(error == NULL);
+    CFReleaseNull(password);
+    error = NULL;
+    
+    //test default icloud recovery code
+    password = SecPasswordGenerate(kSecPasswordTypeiCloudRecovery, &error, passwordRequirements);
+    isnt(password, NULL);
+    ok(error == NULL);
+    CFReleaseNull(password);
+    error = NULL;
+    
+    //test default wifi
+    passwordRequirements = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordDefaultForType, CFSTR("true"));
+    password = SecPasswordGenerate(kSecPasswordTypeWifi, &error, passwordRequirements);
+    isnt(password, NULL);
+    ok(error == NULL);
+    CFReleaseNull(password);
+    error = NULL;
+    CFRelease(passwordRequirements);
+    
+    //test default safari
+    passwordRequirements = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordDefaultForType, CFSTR("true"));
+    password = SecPasswordGenerate(kSecPasswordTypeSafari, &error, passwordRequirements);
+    isnt(password, NULL);
+    ok(error == NULL);
+
+    error = NULL;
+    CFReleaseNull(password);
+    CFRelease(passwordRequirements);
+
+    //test icloud recovery code generation
+    password = SecPasswordGenerate(kSecPasswordTypeiCloudRecovery, &error, NULL);
+    isnt(password, NULL);
+    ok(error == NULL);
+
+    error = NULL;
+    CFReleaseNull(password);
+    
+    //dictionary setup
+    int min = 20;
+    int max = 32;
+    
+    CFNumberRef minRef = CFNumberCreate(NULL, kCFNumberIntType, &min);
+    CFNumberRef maxRef = CFNumberCreate(NULL, kCFNumberIntType, &max);
+    
+    passwordRequirements = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMinLengthKey, minRef);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMaxLengthKey, maxRef);
+    CFStringRef allowedCharacters = CFSTR("abcdsefw2345");
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordAllowedCharactersKey, allowedCharacters);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordRequiredCharactersKey, requiredCharacterSets);
+    
+    //test wifi code generation
+    //test with min/max in range of default
+    password = SecPasswordGenerate(kSecPasswordTypeWifi, &error, passwordRequirements);
+    isnt(password, NULL);
+    ok(error == NULL);
+
+    error = NULL;
+    CFReleaseNull(password);
+    CFRelease(passwordRequirements);
+    CFRelease(minRef);
+    CFRelease(maxRef);
+    CFRelease(allowedCharacters);
+    
+
+    //test with max == min
+    min = 24;
+    max = 24;
+    
+    minRef = CFNumberCreate(NULL, kCFNumberIntType, &min);
+    maxRef = CFNumberCreate(NULL, kCFNumberIntType, &max);
+    
+    passwordRequirements = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMinLengthKey, minRef);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMaxLengthKey, maxRef);
+    allowedCharacters = CFSTR("abcdsefw2345");
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordAllowedCharactersKey, allowedCharacters);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordRequiredCharactersKey, requiredCharacterSets);
+    password = SecPasswordGenerate(kSecPasswordTypeWifi, &error, passwordRequirements);
+    isnt(password, NULL);
+    ok(error == NULL);
+
+    error = NULL;
+    CFReleaseNull(password);
+    CFRelease(passwordRequirements);
+    CFRelease(minRef);
+    CFRelease(maxRef);
+    CFRelease(allowedCharacters);
+    
+    passwordRequirements = NULL;
+    
+    //test disallowed characters
+    min = 24;
+    max = 56;
+    
+    minRef = CFNumberCreate(NULL, kCFNumberIntType, &min);
+    maxRef = CFNumberCreate(NULL, kCFNumberIntType, &max);
+    
+    passwordRequirements = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMinLengthKey, minRef);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMaxLengthKey, maxRef);
+    allowedCharacters = CFSTR("abcdefghijklmnopqrstuvwxyz0123456789");
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordAllowedCharactersKey, allowedCharacters);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordRequiredCharactersKey, requiredCharacterSets);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordDisallowedCharacters, CFSTR("aidfl"));
+
+    password = SecPasswordGenerate(kSecPasswordTypeWifi, &error, passwordRequirements);
+    isnt(password, NULL);
+    ok(error == NULL);
+
+    error = NULL;
+    CFReleaseNull(password);
+    CFRelease(passwordRequirements);
+    CFRelease(minRef);
+    CFRelease(maxRef);
+    CFRelease(allowedCharacters);
+    passwordRequirements = NULL;
+
+    //test can't start with characters
+    min = 24;
+    max = 56;
+    
+    minRef = CFNumberCreate(NULL, kCFNumberIntType, &min);
+    maxRef = CFNumberCreate(NULL, kCFNumberIntType, &max);
+    
+    passwordRequirements = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMinLengthKey, minRef);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMaxLengthKey, maxRef);
+    allowedCharacters = CFSTR("diujk");
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordAllowedCharactersKey, allowedCharacters);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordRequiredCharactersKey, requiredCharacterSets);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordCantStartWithChars, CFSTR("d"));
+    
+    password = SecPasswordGenerate(kSecPasswordTypeWifi, &error, passwordRequirements);
+    isnt(password, NULL);
+    ok(error == NULL);
+
+    error = NULL;
+    CFReleaseNull(password);
+    CFRelease(passwordRequirements);
+    CFRelease(minRef);
+    CFRelease(maxRef);
+    CFRelease(allowedCharacters);
+    passwordRequirements = NULL;
+   
+    
+    //test can't end with characters
+    min = 24;
+    max = 56;
+    
+    minRef = CFNumberCreate(NULL, kCFNumberIntType, &min);
+    maxRef = CFNumberCreate(NULL, kCFNumberIntType, &max);
+    
+    passwordRequirements = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMinLengthKey, minRef);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMaxLengthKey, maxRef);
+    allowedCharacters = CFSTR("diujk89");
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordAllowedCharactersKey, allowedCharacters);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordRequiredCharactersKey, requiredCharacterSets);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordCantEndWithChars, CFSTR("d"));
+    
+    password = SecPasswordGenerate(kSecPasswordTypeWifi, &error, passwordRequirements);
+    isnt(password, NULL);
+    ok(error == NULL);
+
+    error = NULL;
+    CFReleaseNull(password);
+    CFRelease(passwordRequirements);
+    CFRelease(minRef);
+    CFRelease(maxRef);
+    CFRelease(allowedCharacters);
+    passwordRequirements = NULL;
+    
+    
+    //test 4 digit pin generation
+    for(int i =0 ; i< 100; i++){
+        password = SecPasswordGenerate(kSecPasswordTypePIN, &error, passwordRequirements);
+        isnt(password, NULL);
+        ok(error == NULL);
+
+        error = NULL;
+        CFReleaseNull(password);
+    }
+        
+    //test 6 digit pin
+    min = 4;
+    max = 6;
+    
+    minRef = CFNumberCreate(NULL, kCFNumberIntType, &min);
+    maxRef = CFNumberCreate(NULL, kCFNumberIntType, &max);
+    
+    passwordRequirements = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMinLengthKey, minRef);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMaxLengthKey, maxRef);
+    password = SecPasswordGenerate(kSecPasswordTypePIN, &error, passwordRequirements);
+    isnt(password, NULL);
+    ok(error == NULL);
+
+    error = NULL;
+    CFReleaseNull(password);
+    CFRelease(minRef);
+    CFRelease(maxRef);
+    CFRelease(passwordRequirements);
+
+    //test 5 digit pin
+    min = 4;
+    max = 5;
+    
+    minRef = CFNumberCreate(NULL, kCFNumberIntType, &min);
+    maxRef = CFNumberCreate(NULL, kCFNumberIntType, &max);
+    
+    passwordRequirements = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMinLengthKey, minRef);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMaxLengthKey, maxRef);
+    password = SecPasswordGenerate(kSecPasswordTypePIN, &error, passwordRequirements);
+    isnt(password, NULL);
+    ok(error == NULL);
+
+    error = NULL;
+    CFReleaseNull(password);
+    CFRelease(minRef);
+    CFRelease(maxRef);
+    CFRelease(passwordRequirements);
+    //test safari password
+    min = 20;
+    max = 32;
+    
+    minRef = CFNumberCreate(NULL, kCFNumberIntType, &min);
+    maxRef = CFNumberCreate(NULL, kCFNumberIntType, &max);
+    
+    passwordRequirements = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMinLengthKey, minRef);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMaxLengthKey, maxRef);
+    allowedCharacters = CFSTR("abcdsefw2345");
+    requiredCharacterSets = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+    CFArrayAppendValue(requiredCharacterSets, uppercaseLetterCharacterSet);
+    CFArrayAppendValue(requiredCharacterSets, lowercaseLetterCharacterSet);
+    CFArrayAppendValue(requiredCharacterSets, decimalDigitCharacterSet);
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordAllowedCharactersKey, allowedCharacters);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordRequiredCharactersKey, requiredCharacterSets);
+    
+    password = SecPasswordGenerate(kSecPasswordTypeSafari, &error, passwordRequirements);
+    isnt(password, NULL);
+    ok(error == NULL);
+
+    error = NULL;
+    CFReleaseNull(password);
+    CFRelease(passwordRequirements);
+    CFRelease(minRef);
+    CFRelease(maxRef);
+    CFRelease(allowedCharacters);
+    CFRelease(requiredCharacterSets);
+    
+    //test flexible group size and number of groups in the password
+    //test safari password
+    min = 12;
+    max = 19;
+    int groupSize = 5;
+    int numberOfGroups = 23;
+    
+    CFTypeRef groupSizeRef = CFNumberCreate(NULL, kCFNumberIntType, &groupSize);
+    CFTypeRef numberOfGroupsRef = CFNumberCreate(NULL, kCFNumberIntType, &numberOfGroups);
+    
+    minRef = CFNumberCreate(NULL, kCFNumberIntType, &min);
+    maxRef = CFNumberCreate(NULL, kCFNumberIntType, &max);
+    
+    passwordRequirements = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMinLengthKey, minRef);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMaxLengthKey, maxRef);
+    allowedCharacters = CFSTR("abcdsefw2345");
+    requiredCharacterSets = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+    CFArrayAppendValue(requiredCharacterSets, uppercaseLetterCharacterSet);
+    CFArrayAppendValue(requiredCharacterSets, lowercaseLetterCharacterSet);
+    CFArrayAppendValue(requiredCharacterSets, decimalDigitCharacterSet);
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordAllowedCharactersKey, allowedCharacters);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordRequiredCharactersKey, requiredCharacterSets);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordGroupSize, groupSizeRef);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordNumberOfGroups, numberOfGroupsRef);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordSeparator, CFSTR("*"));
+
+    password = SecPasswordGenerate(kSecPasswordTypeSafari, &error, passwordRequirements);
+    isnt(password, NULL);
+    ok(error == NULL);
+
+    error = NULL;
+    CFReleaseNull(password);
+    CFRelease(passwordRequirements);
+    CFRelease(minRef);
+    CFRelease(maxRef);
+    CFRelease(allowedCharacters);
+    CFRelease(requiredCharacterSets);
+    
+    //test at least N characters 
+    //test safari password
+    min = 24;
+    max = 32;
+    int N = 5;
+
+    minRef = CFNumberCreate(NULL, kCFNumberIntType, &min);
+    maxRef = CFNumberCreate(NULL, kCFNumberIntType, &max);
+    CFNumberRef threshold = CFNumberCreate(NULL, kCFNumberIntType, &N);
+    
+    CFStringRef characters = CFSTR("ab");
+    CFMutableDictionaryRef atLeast = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(atLeast, kSecPasswordCharacters, characters);
+    CFDictionaryAddValue(atLeast, kSecPasswordCharacterCount, threshold);
+    
+    passwordRequirements = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMinLengthKey, minRef);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMaxLengthKey, maxRef);
+    allowedCharacters = CFSTR("abcdsefw2345");
+    requiredCharacterSets = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+    CFArrayAppendValue(requiredCharacterSets, uppercaseLetterCharacterSet);
+    CFArrayAppendValue(requiredCharacterSets, lowercaseLetterCharacterSet);
+    CFArrayAppendValue(requiredCharacterSets, decimalDigitCharacterSet);
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordAllowedCharactersKey, allowedCharacters);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordRequiredCharactersKey, requiredCharacterSets);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordContainsAtLeastNSpecificCharacters, atLeast);
+
+    password = SecPasswordGenerate(kSecPasswordTypeSafari, &error, passwordRequirements);
+    isnt(password, NULL);
+    ok(error == NULL);
+
+    error = NULL;
+    CFReleaseNull(password);
+    CFRelease(passwordRequirements);
+    CFRelease(minRef);
+    CFRelease(maxRef);
+    CFRelease(allowedCharacters);
+    CFRelease(requiredCharacterSets);
+
+    //test no More than N characters
+    //test safari password
+    min = 24;
+    max = 32;
+    N = 5;
+    
+
+    threshold = CFNumberCreate(NULL, kCFNumberIntType, &N);
+    minRef = CFNumberCreate(NULL, kCFNumberIntType, &min);
+    maxRef = CFNumberCreate(NULL, kCFNumberIntType, &max);
+    
+    CFMutableDictionaryRef noMoreThan = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFStringRef noMore = CFSTR("ab");
+    CFDictionaryAddValue(noMoreThan, kSecPasswordCharacters, noMore);
+    CFDictionaryAddValue(noMoreThan, kSecPasswordCharacterCount, threshold);
+    
+    passwordRequirements = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMinLengthKey, minRef);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMaxLengthKey, maxRef);
+    allowedCharacters = CFSTR("abcdsefw2345");
+    requiredCharacterSets = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+    CFArrayAppendValue(requiredCharacterSets, uppercaseLetterCharacterSet);
+    CFArrayAppendValue(requiredCharacterSets, lowercaseLetterCharacterSet);
+    CFArrayAppendValue(requiredCharacterSets, decimalDigitCharacterSet);
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordAllowedCharactersKey, allowedCharacters);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordRequiredCharactersKey, requiredCharacterSets);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordContainsNoMoreThanNSpecificCharacters, noMoreThan);
+    
+    password = SecPasswordGenerate(kSecPasswordTypeSafari, &error, passwordRequirements);
+    isnt(password, NULL);
+    ok(error == NULL);
+
+    error = NULL;
+    CFReleaseNull(password);
+    CFRelease(passwordRequirements);
+    CFRelease(minRef);
+    CFRelease(maxRef);
+    CFRelease(allowedCharacters);
+    CFRelease(requiredCharacterSets);
+
+    //test identical character threshold
+    //test safari password
+    min = 12;
+    max = 19;
+    N = 2;
+    
+    threshold = CFNumberCreate(NULL, kCFNumberIntType, &N);
+    minRef = CFNumberCreate(NULL, kCFNumberIntType, &min);
+    maxRef = CFNumberCreate(NULL, kCFNumberIntType, &max);
+    
+    passwordRequirements = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMinLengthKey, minRef);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMaxLengthKey, maxRef);
+    allowedCharacters = CFSTR("abcdsefw2345");
+    requiredCharacterSets = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+    CFArrayAppendValue(requiredCharacterSets, uppercaseLetterCharacterSet);
+    CFArrayAppendValue(requiredCharacterSets, lowercaseLetterCharacterSet);
+    CFArrayAppendValue(requiredCharacterSets, decimalDigitCharacterSet);
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordAllowedCharactersKey, allowedCharacters);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordRequiredCharactersKey, requiredCharacterSets);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordContainsNoMoreThanNConsecutiveIdenticalCharacters, threshold);
+    
+    password = SecPasswordGenerate(kSecPasswordTypeSafari, &error, passwordRequirements);
+    isnt(password, NULL);
+    ok(error == NULL);
+
+    error = NULL;
+    CFReleaseNull(password);
+    CFRelease(passwordRequirements);
+    CFRelease(minRef);
+    CFRelease(maxRef);
+    CFRelease(allowedCharacters);
+    CFRelease(requiredCharacterSets);
+
+/////////////////now test all the error cases
+    //test with no required characters
+    
+    min = 24;
+    max = 32;
+    
+    minRef = CFNumberCreate(NULL, kCFNumberIntType, &min);
+    maxRef = CFNumberCreate(NULL, kCFNumberIntType, &max);
+    passwordRequirements = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+
+    allowedCharacters = CFSTR("abcdsefw2345");
+    requiredCharacterSets = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordAllowedCharactersKey, allowedCharacters);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordRequiredCharactersKey, requiredCharacterSets);
+    password = SecPasswordGenerate(kSecPasswordTypeWifi, &error, passwordRequirements);
+    ok(password == NULL);
+    ok(error != NULL);
+
+    CFRelease(error);
+    error = NULL;
+    CFRelease(minRef);
+    CFRelease(maxRef);
+    CFRelease(allowedCharacters);
+    CFRelease(passwordRequirements);
+
+    //test with no allowed characters
+    min = 24;
+    max = 32;
+    
+    minRef = CFNumberCreate(NULL, kCFNumberIntType, &min);
+    maxRef = CFNumberCreate(NULL, kCFNumberIntType, &max);
+    
+    passwordRequirements = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMinLengthKey, minRef);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMaxLengthKey, maxRef);
+    allowedCharacters = CFSTR("");
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordAllowedCharactersKey, allowedCharacters);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordRequiredCharactersKey, requiredCharacterSets);
+    password = SecPasswordGenerate(kSecPasswordTypeWifi, &error, passwordRequirements);
+    ok(password == NULL);
+    ok(error != NULL);
+
+    CFRelease(error);
+    error = NULL;
+    CFRelease(minRef);
+    CFRelease(maxRef);
+    CFRelease(passwordRequirements);
+
+    //test with min > max
+    min = 32;
+    max = 20;
+    
+    minRef = CFNumberCreate(NULL, kCFNumberIntType, &min);
+    maxRef = CFNumberCreate(NULL, kCFNumberIntType, &max);
+    
+    passwordRequirements = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMinLengthKey, minRef);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMaxLengthKey, maxRef);
+    allowedCharacters = CFSTR("abcdsefw2345");
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordAllowedCharactersKey, allowedCharacters);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordRequiredCharactersKey, requiredCharacterSets);
+    password = SecPasswordGenerate(kSecPasswordTypeWifi, &error, passwordRequirements);
+    ok(password == NULL);
+    ok(error != NULL);
+
+    error = NULL;
+    CFRelease(minRef);
+    CFRelease(maxRef);
+    CFRelease(allowedCharacters);
+    CFRelease(passwordRequirements);
+
+    //test by ommitting dictionary parameters
+    
+    //omit max length
+    min = 20;
+    max = 32;
+    
+    minRef = CFNumberCreate(NULL, kCFNumberIntType, &min);
+    maxRef = CFNumberCreate(NULL, kCFNumberIntType, &max);
+    
+    passwordRequirements = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMinLengthKey, minRef);
+    allowedCharacters = CFSTR("abcdsefw2345");
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordAllowedCharactersKey, allowedCharacters);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordRequiredCharactersKey, requiredCharacterSets);
+    password = SecPasswordGenerate(kSecPasswordTypeWifi, &error, passwordRequirements);
+    ok(password == NULL);
+    ok(error != NULL);
+
+    error = NULL;
+    CFRelease(minRef);
+    CFRelease(maxRef);
+    CFRelease(allowedCharacters);
+    CFRelease(passwordRequirements);
+
+    //omit min length
+    min = 20;
+    max = 32;
+    
+    minRef = CFNumberCreate(NULL, kCFNumberIntType, &min);
+    maxRef = CFNumberCreate(NULL, kCFNumberIntType, &max);
+    
+    passwordRequirements = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMaxLengthKey, maxRef);
+    allowedCharacters = CFSTR("abcdsefw2345");
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordAllowedCharactersKey, allowedCharacters);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordRequiredCharactersKey, requiredCharacterSets);
+    password = SecPasswordGenerate(kSecPasswordTypeWifi, &error, passwordRequirements);
+    ok(password == NULL);
+    ok(error != NULL);
+
+    error = NULL;
+    CFRelease(minRef);
+    CFRelease(maxRef);
+    CFRelease(allowedCharacters);
+    CFRelease(passwordRequirements);
+
+    //omit allowed characters
+    min = 20;
+    max = 32;
+    
+    minRef = CFNumberCreate(NULL, kCFNumberIntType, &min);
+    maxRef = CFNumberCreate(NULL, kCFNumberIntType, &max);
+    
+    passwordRequirements = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMinLengthKey, minRef);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMaxLengthKey, maxRef);
+    allowedCharacters = CFSTR("abcdsefw2345");
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordRequiredCharactersKey, requiredCharacterSets);
+    password = SecPasswordGenerate(kSecPasswordTypeWifi, &error, passwordRequirements);
+    ok(password == NULL);
+    ok(error != NULL);
+
+    error = NULL;
+    CFRelease(minRef);
+    CFRelease(maxRef);
+    CFRelease(allowedCharacters);
+    CFRelease(passwordRequirements);
+
+    //omit required characters
+    min = 20;
+    max = 32;
+    
+    minRef = CFNumberCreate(NULL, kCFNumberIntType, &min);
+    maxRef = CFNumberCreate(NULL, kCFNumberIntType, &max);
+    
+    passwordRequirements = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMinLengthKey, minRef);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMaxLengthKey, maxRef);
+    allowedCharacters = CFSTR("abcdsefw2345");
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordAllowedCharactersKey, allowedCharacters);
+    password = SecPasswordGenerate(kSecPasswordTypeWifi, &error, passwordRequirements);
+    ok(password == NULL);
+    ok(error != NULL);
+    
+    error = NULL;
+    CFRelease(minRef);
+    CFRelease(maxRef);
+    CFRelease(allowedCharacters);
+    CFRelease(passwordRequirements);
+
+    //pass in wrong type for min
+    min = 20;
+    max = 32;
+    
+    minRef = CFNumberCreate(NULL, kCFNumberIntType, &min);
+    maxRef = CFNumberCreate(NULL, kCFNumberIntType, &max);
+    
+    passwordRequirements = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMinLengthKey, allowedCharacters);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMaxLengthKey, maxRef);
+    allowedCharacters = CFSTR("abcdsefw2345");
+    requiredCharacterSets = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+    CFArrayAppendValue(requiredCharacterSets, uppercaseLetterCharacterSet);
+    CFArrayAppendValue(requiredCharacterSets, lowercaseLetterCharacterSet);
+    CFArrayAppendValue(requiredCharacterSets, decimalDigitCharacterSet);
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordAllowedCharactersKey, allowedCharacters);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordRequiredCharactersKey, requiredCharacterSets);
+    
+    password = SecPasswordGenerate(kSecPasswordTypeWifi, &error, passwordRequirements);
+    ok(password == NULL);
+    ok(error != NULL);
+
+    error = NULL;
+    CFRelease(passwordRequirements);
+    CFRelease(minRef);
+    CFRelease(maxRef);
+    CFRelease(allowedCharacters);
+    
+    //pass in wrong type for max
+    min = 20;
+    max = 32;
+    
+    minRef = CFNumberCreate(NULL, kCFNumberIntType, &min);
+    maxRef = CFNumberCreate(NULL, kCFNumberIntType, &max);
+    
+    passwordRequirements = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMinLengthKey, minRef);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMaxLengthKey, allowedCharacters);
+    allowedCharacters = CFSTR("abcdsefw2345");
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordAllowedCharactersKey, allowedCharacters);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordRequiredCharactersKey, requiredCharacterSets);
+
+    password = SecPasswordGenerate(kSecPasswordTypeWifi, &error, passwordRequirements);
+    ok(password == NULL);    
+    ok(error != NULL);
+
+    error = NULL;
+    CFRelease(passwordRequirements);
+    CFRelease(minRef);
+    CFRelease(maxRef);
+    CFRelease(allowedCharacters);
+    
+    //pass in wrong type for allowed
+    min = 20;
+    max = 32;
+    
+    minRef = CFNumberCreate(NULL, kCFNumberIntType, &min);
+    maxRef = CFNumberCreate(NULL, kCFNumberIntType, &max);
+    
+    passwordRequirements = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMinLengthKey, minRef);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMaxLengthKey, maxRef);
+    allowedCharacters = CFSTR("abcdsefw2345");
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordAllowedCharactersKey, minRef);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordRequiredCharactersKey, requiredCharacterSets);
+
+    password = SecPasswordGenerate(kSecPasswordTypeWifi, &error, passwordRequirements);
+    ok(password == NULL);
+    ok(error != NULL);
+
+    error = NULL;
+    CFRelease(passwordRequirements);
+    CFRelease(minRef);
+    CFRelease(maxRef);
+    CFRelease(allowedCharacters);
+    
+    //pass in wrong type for required
+    min = 20;
+    max = 32;
+    
+    minRef = CFNumberCreate(NULL, kCFNumberIntType, &min);
+    maxRef = CFNumberCreate(NULL, kCFNumberIntType, &max);
+    
+    passwordRequirements = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMinLengthKey, minRef);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMaxLengthKey, maxRef);
+    allowedCharacters = CFSTR("abcdsefw2345");
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordAllowedCharactersKey, allowedCharacters);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordRequiredCharactersKey, minRef);
+    password = SecPasswordGenerate(kSecPasswordTypeWifi, &error, passwordRequirements);
+    ok(password == NULL);
+    ok(error != NULL);
+
+    error = NULL;
+    CFRelease(passwordRequirements);
+    CFRelease(minRef);
+    CFRelease(maxRef);
+    CFRelease(allowedCharacters);
+    
+    //pass in wrong type for no less than
+    min = 20;
+    max = 32;
+    
+    minRef = CFNumberCreate(NULL, kCFNumberIntType, &min);
+    maxRef = CFNumberCreate(NULL, kCFNumberIntType, &max);
+    
+    passwordRequirements = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    requiredCharacterSets = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+    CFArrayAppendValue(requiredCharacterSets, uppercaseLetterCharacterSet);
+    CFArrayAppendValue(requiredCharacterSets, lowercaseLetterCharacterSet);
+    CFArrayAppendValue(requiredCharacterSets, decimalDigitCharacterSet);
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordAllowedCharactersKey, allowedCharacters);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordRequiredCharactersKey, requiredCharacterSets);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMinLengthKey, minRef);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMaxLengthKey, maxRef);
+    allowedCharacters = CFSTR("abcdsefw2345");
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordAllowedCharactersKey, allowedCharacters);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordRequiredCharactersKey, minRef);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordContainsAtLeastNSpecificCharacters, CFSTR("hehe"));
+    password = SecPasswordGenerate(kSecPasswordTypeWifi, &error, passwordRequirements);
+    ok(password == NULL);
+    ok(error != NULL);
+
+    error = NULL;
+    CFRelease(passwordRequirements);
+    CFRelease(minRef);
+    CFRelease(maxRef);
+    CFRelease(allowedCharacters);
+
+    //pass in wrong type for no more than
+    min = 20;
+    max = 32;
+    
+    minRef = CFNumberCreate(NULL, kCFNumberIntType, &min);
+    maxRef = CFNumberCreate(NULL, kCFNumberIntType, &max);
+    
+    passwordRequirements = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    requiredCharacterSets = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+    CFArrayAppendValue(requiredCharacterSets, uppercaseLetterCharacterSet);
+    CFArrayAppendValue(requiredCharacterSets, lowercaseLetterCharacterSet);
+    CFArrayAppendValue(requiredCharacterSets, decimalDigitCharacterSet);
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordAllowedCharactersKey, allowedCharacters);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordRequiredCharactersKey, requiredCharacterSets);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMinLengthKey, minRef);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMaxLengthKey, maxRef);
+    allowedCharacters = CFSTR("abcdsefw2345");
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordAllowedCharactersKey, allowedCharacters);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordRequiredCharactersKey, minRef);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordContainsNoMoreThanNSpecificCharacters, CFSTR("hehe"));
+
+    password = SecPasswordGenerate(kSecPasswordTypeWifi, &error, passwordRequirements);
+    ok(password == NULL);
+    ok(error != NULL);
+
+    error = NULL;
+    CFRelease(passwordRequirements);
+    CFRelease(minRef);
+    CFRelease(maxRef);
+    CFRelease(allowedCharacters);
+
+    //pass in wrong disallowed characters
+    min = 20;
+    max = 32;
+    
+    minRef = CFNumberCreate(NULL, kCFNumberIntType, &min);
+    maxRef = CFNumberCreate(NULL, kCFNumberIntType, &max);
+    
+    passwordRequirements = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    requiredCharacterSets = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+    CFArrayAppendValue(requiredCharacterSets, uppercaseLetterCharacterSet);
+    CFArrayAppendValue(requiredCharacterSets, lowercaseLetterCharacterSet);
+    CFArrayAppendValue(requiredCharacterSets, decimalDigitCharacterSet);
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordAllowedCharactersKey, allowedCharacters);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordRequiredCharactersKey, requiredCharacterSets);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMinLengthKey, minRef);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMaxLengthKey, maxRef);
+    allowedCharacters = CFSTR("abcdsefw2345");
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordAllowedCharactersKey, allowedCharacters);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordRequiredCharactersKey, minRef);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordDisallowedCharacters, requiredCharacterSets);
+    
+    password = SecPasswordGenerate(kSecPasswordTypeWifi, &error, passwordRequirements);
+    ok(password == NULL);
+    ok(error != NULL);
+    
+    error = NULL;
+    CFRelease(passwordRequirements);
+    CFRelease(minRef);
+    CFRelease(maxRef);
+    CFRelease(allowedCharacters);
+    
+    //pass in wrong type for no more than's dictionary
+    min = 20;
+    max = 32;
+    
+    minRef = CFNumberCreate(NULL, kCFNumberIntType, &min);
+    maxRef = CFNumberCreate(NULL, kCFNumberIntType, &max);
+    
+    CFMutableDictionaryRef wrongCount = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(wrongCount, kSecPasswordCharacters, CFSTR("lkj"));
+    CFDictionaryAddValue(wrongCount, kSecPasswordCharacterCount, CFSTR("sdf"));
+    
+    passwordRequirements = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    requiredCharacterSets = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+    CFArrayAppendValue(requiredCharacterSets, uppercaseLetterCharacterSet);
+    CFArrayAppendValue(requiredCharacterSets, lowercaseLetterCharacterSet);
+    CFArrayAppendValue(requiredCharacterSets, decimalDigitCharacterSet);
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordAllowedCharactersKey, allowedCharacters);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordRequiredCharactersKey, requiredCharacterSets);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMinLengthKey, minRef);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordMaxLengthKey, maxRef);
+    allowedCharacters = CFSTR("abcdsefw2345");
+    
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordAllowedCharactersKey, allowedCharacters);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordRequiredCharactersKey, minRef);
+    CFDictionaryAddValue(passwordRequirements, kSecPasswordContainsNoMoreThanNSpecificCharacters, wrongCount);
+    
+    password = SecPasswordGenerate(kSecPasswordTypeWifi, &error, passwordRequirements);
+    ok(password == NULL);
+    ok(error != NULL);
+
+    error = NULL;
+    CFRelease(wrongCount);
+    CFRelease(passwordRequirements);
+    CFRelease(minRef);
+    CFRelease(maxRef);
+    CFRelease(allowedCharacters);
+
+    password = CFSTR("Apple1?");
+    isnt(true, SecPasswordIsPasswordWeak(password));
+    CFRelease(password);
+    
+    password = CFSTR("Singhal190");
+    isnt(true, SecPasswordIsPasswordWeak(password));
+    CFRelease(password);
+    
+    password = CFSTR("1Hollow2");
+    isnt(true, SecPasswordIsPasswordWeak(password));
+    CFRelease(password);
+    
+    password = CFSTR("1Hollow/");
+    isnt(true, SecPasswordIsPasswordWeak(password));
+    CFRelease(password);
+    
+    password = CFSTR("baj/paj1");
+    isnt(true, SecPasswordIsPasswordWeak(password));
+    CFRelease(password);
+    
+    password = CFSTR("Zaxs1009?");
+    isnt(true, SecPasswordIsPasswordWeak(password));
+    CFRelease(password);
+    
+    password = CFSTR("6666");
+    isnt(false, SecPasswordIsPasswordWeak(password));
+    CFRelease(password);
+    
+    password = CFSTR("123456");
+    isnt(false, SecPasswordIsPasswordWeak(password));
+    CFRelease(password);
+    
+    password = CFSTR("654321");
+    isnt(false, SecPasswordIsPasswordWeak(password));
+    CFRelease(password);
+
+    password = CFSTR("A");
+    isnt(false, SecPasswordIsPasswordWeak(password));
+    CFRelease(password);
+
+    password = CFSTR("password");
+    isnt(true, SecPasswordIsPasswordWeak(password));
+    CFRelease(password);
+
+    password = CFSTR("password1");
+    isnt(true, SecPasswordIsPasswordWeak(password));
+    CFRelease(password);
+
+    password = CFSTR("P@ssw0rd");
+    isnt(true, SecPasswordIsPasswordWeak(password));
+    CFRelease(password);
+
+    password = CFSTR("facebook!{}");
+    isnt(true, SecPasswordIsPasswordWeak(password));
+    CFRelease(password);
+    
+    password = CFSTR("12345678");
+    isnt(false, SecPasswordIsPasswordWeak(password));
+    CFRelease(password);
+}
+
+int si_73_secpasswordgenerate(int argc, char *const *argv)
+{
+       plan_tests(279);
+       tests();
+    
+       return 0;
+}
diff --git a/sec/Security/Regressions/secitem/si-74-OTAPKISigner.c b/sec/Security/Regressions/secitem/si-74-OTAPKISigner.c
new file mode 100644 (file)
index 0000000..2bf3ee8
--- /dev/null
@@ -0,0 +1,993 @@
+/*
+ *  si-74-OTAPKISigner.c
+ *  Security
+ *
+ *  Created by James Murphy on 07/02/13.
+ *  Copyright (c) 2013 Apple Inc. All Rights Reserved.
+ *
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecCertificateInternal.h>
+#include <Security/SecItem.h>
+#include <Security/SecItemPriv.h>
+#include <Security/SecIdentityPriv.h>
+#include <Security/SecIdentity.h>
+#include <Security/SecPolicy.h>
+#include <Security/SecPolicyPriv.h>
+#include <Security/SecPolicyInternal.h>
+#include <Security/SecCMS.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "Security_regressions.h"
+
+#if TARGET_OS_IPHONE
+
+#define CFReleaseSafe(CF) { CFTypeRef _cf = (CF); if (_cf) {  CFRelease(_cf); } }
+
+static const UInt8 kSignedPList[] = {
+       0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x80, 0x30,
+       0x80, 0x02, 0x01, 0x01, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
+       0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+       0x07, 0x01, 0xa0, 0x80, 0x24, 0x80, 0x04, 0x36, 0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30,
+       0xd1, 0x01, 0x02, 0x53, 0x66, 0x6f, 0x6f, 0x53, 0x62, 0x61, 0x72, 0x08, 0x0b, 0x0f, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x30, 0x82, 0x07, 0xab, 0x30, 0x82, 0x05, 0x93, 0xa0, 0x03,
+       0x02, 0x01, 0x02, 0x02, 0x08, 0x04, 0x2e, 0x97, 0xbb, 0x62, 0x84, 0xd9, 0x1c, 0x30, 0x0d, 0x06,
+       0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0x84, 0x31,
+       0x38, 0x30, 0x36, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x2f, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20,
+       0x50, 0x4b, 0x49, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x52, 0x6f, 0x6f,
+       0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
+       0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55,
+       0x04, 0x0b, 0x0c, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+       0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
+       0x79, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c,
+       0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+       0x02, 0x55, 0x53, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30, 0x36, 0x32, 0x35, 0x30, 0x30, 0x30,
+       0x39, 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x32, 0x38, 0x30, 0x36, 0x32, 0x31, 0x30, 0x30, 0x30, 0x39,
+       0x33, 0x38, 0x5a, 0x30, 0x59, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1a,
+       0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x4b, 0x49, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e,
+       0x67, 0x73, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03,
+       0x55, 0x04, 0x0b, 0x0c, 0x07, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x4f, 0x53, 0x31, 0x13, 0x30, 0x11,
+       0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63,
+       0x2e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x30, 0x82,
+       0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
+       0x00, 0x03, 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, 0x01, 0x00, 0xad,
+       0xef, 0x52, 0xc8, 0xda, 0x8e, 0x3c, 0xcc, 0x06, 0xcf, 0xfc, 0xed, 0xdb, 0x92, 0xb3, 0xa8, 0xe0,
+       0x3b, 0x14, 0x40, 0x34, 0xad, 0x91, 0xf3, 0xbe, 0x1a, 0x00, 0xbb, 0x06, 0xa2, 0xd7, 0x24, 0x6f,
+       0xd5, 0xd3, 0xdf, 0xd9, 0xff, 0x0b, 0x4d, 0x6d, 0xc5, 0xdd, 0x7a, 0x37, 0xfa, 0x08, 0x49, 0x0e,
+       0x36, 0x5e, 0xab, 0x83, 0x8d, 0xeb, 0x83, 0x00, 0xf9, 0xaa, 0xe4, 0x88, 0x09, 0x87, 0x05, 0x6b,
+       0x01, 0x6e, 0x49, 0x54, 0xa1, 0x3b, 0x5c, 0xfc, 0x2b, 0x0f, 0x1f, 0xa9, 0x7c, 0xc1, 0xc5, 0xe1,
+       0x32, 0xd7, 0x86, 0x49, 0x80, 0x0f, 0xf8, 0xe3, 0x3b, 0xa3, 0x12, 0x06, 0x5d, 0xf4, 0x43, 0xc0,
+       0xb2, 0xc7, 0xcf, 0xb4, 0x14, 0x2c, 0x50, 0x70, 0x57, 0xb9, 0xb2, 0xe7, 0x72, 0x9a, 0x9f, 0x45,
+       0x0b, 0x0d, 0xe5, 0xab, 0x3e, 0x23, 0x91, 0xe0, 0x88, 0x84, 0x3a, 0xec, 0xaa, 0x80, 0xab, 0x37,
+       0xa3, 0x0c, 0x63, 0x99, 0x1c, 0xde, 0x1b, 0x29, 0x95, 0x4b, 0xff, 0xcd, 0x92, 0x10, 0xa3, 0x50,
+       0x93, 0x89, 0x4f, 0xdc, 0x30, 0x0d, 0x29, 0x2a, 0x80, 0x04, 0x32, 0xb3, 0xb9, 0xa7, 0x79, 0x5f,
+       0x18, 0xce, 0xc1, 0x90, 0xe6, 0xd6, 0x0c, 0xeb, 0x91, 0x27, 0x6f, 0x17, 0xd2, 0x93, 0xda, 0xa1,
+       0xa8, 0x3f, 0x20, 0xe9, 0xeb, 0x54, 0x37, 0xd7, 0x54, 0xfd, 0x44, 0xa2, 0x8d, 0xa4, 0x30, 0x6e,
+       0xbf, 0xd0, 0xbd, 0xc4, 0x7d, 0x93, 0xeb, 0xf6, 0xfa, 0x1e, 0xc1, 0xd5, 0xee, 0xfe, 0xb7, 0x56,
+       0x51, 0xb3, 0x0b, 0x3f, 0xf4, 0xb1, 0x77, 0x75, 0xaf, 0x10, 0x14, 0x98, 0x74, 0x41, 0x40, 0xdb,
+       0xe4, 0x6b, 0x3f, 0x49, 0xce, 0xb8, 0x80, 0x20, 0x72, 0x92, 0xcb, 0x63, 0x63, 0x44, 0x4e, 0xe8,
+       0xe4, 0xde, 0xe9, 0xc3, 0x0a, 0x75, 0xd8, 0xbf, 0xc5, 0x8e, 0xcb, 0xcf, 0xec, 0x65, 0x49, 0x56,
+       0xa1, 0x9f, 0xb6, 0x39, 0x53, 0x69, 0xb4, 0x04, 0xe8, 0xd0, 0x28, 0xc6, 0x69, 0xde, 0xdb, 0x30,
+       0xa7, 0xb0, 0xbf, 0x6f, 0xfe, 0x7b, 0x45, 0x87, 0x07, 0xf0, 0x85, 0x34, 0x71, 0xca, 0xe5, 0x07,
+       0x61, 0xce, 0x53, 0xf3, 0xd6, 0x69, 0x70, 0x5a, 0x4b, 0x7e, 0xda, 0x9b, 0x77, 0x17, 0x65, 0x6c,
+       0x4d, 0xd5, 0x59, 0x00, 0x6f, 0x47, 0x65, 0x30, 0x98, 0xd9, 0x7b, 0xa7, 0x51, 0x8b, 0x47, 0x7d,
+       0x8f, 0x5a, 0x91, 0x72, 0xe4, 0x86, 0x4f, 0xb0, 0xb4, 0x12, 0x42, 0x55, 0x95, 0x59, 0xa3, 0xc6,
+       0xdf, 0xba, 0x20, 0x0e, 0x5d, 0x0f, 0x6a, 0x6a, 0xc2, 0x08, 0x93, 0x9f, 0x0e, 0x8b, 0x61, 0x20,
+       0x9e, 0x2b, 0x64, 0x26, 0x15, 0x52, 0x9b, 0xef, 0x34, 0x7c, 0x12, 0xa4, 0xe4, 0xf7, 0xfc, 0x9a,
+       0xa6, 0xe6, 0xe9, 0x6f, 0xfc, 0xbb, 0x16, 0xc4, 0x0f, 0x0b, 0xac, 0x84, 0x9d, 0xc8, 0xe9, 0x98,
+       0xe1, 0xf4, 0x35, 0xfb, 0x97, 0x63, 0x14, 0x6c, 0x15, 0x51, 0x51, 0x5b, 0xc8, 0x64, 0x25, 0x46,
+       0x44, 0x6d, 0xbd, 0x17, 0xdd, 0x17, 0x4d, 0x34, 0x77, 0xa8, 0x6d, 0x4b, 0x97, 0x4b, 0x77, 0xf5,
+       0x77, 0x07, 0x1b, 0x93, 0x18, 0xf3, 0x44, 0x4e, 0x79, 0xe2, 0xfc, 0x96, 0x76, 0x5e, 0x69, 0x85,
+       0xf6, 0xb6, 0x97, 0xbb, 0xb0, 0x41, 0x1f, 0x03, 0x8b, 0xcb, 0xc0, 0xa9, 0x10, 0x67, 0x8f, 0x6f,
+       0x67, 0xab, 0xb0, 0xbd, 0x1f, 0xc7, 0x11, 0xfd, 0xb8, 0x29, 0x47, 0x41, 0xd4, 0x34, 0x0f, 0x5b,
+       0x9d, 0x64, 0xfb, 0x8f, 0x5f, 0x37, 0xd1, 0x9a, 0x4a, 0x2d, 0x62, 0xd1, 0x74, 0x2e, 0x6b, 0x7f,
+       0xdf, 0xb3, 0xea, 0x5f, 0xfa, 0x63, 0xd4, 0x4f, 0xb3, 0x89, 0x76, 0x67, 0x36, 0x71, 0xcd, 0xaf,
+       0xd7, 0x9c, 0x95, 0xa8, 0xce, 0xee, 0x29, 0x25, 0xb1, 0x2a, 0xac, 0x99, 0x10, 0x9b, 0x03, 0x02,
+       0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x02, 0x49, 0x30, 0x82, 0x02, 0x45, 0x30, 0x1d, 0x06, 0x03,
+       0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xcd, 0xbf, 0x6f, 0x14, 0xff, 0x8b, 0xb7, 0xf7, 0x29,
+       0xcd, 0xa4, 0x8c, 0xc1, 0xb1, 0x30, 0x92, 0x37, 0x8b, 0xd4, 0xef, 0x30, 0x0c, 0x06, 0x03, 0x55,
+       0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23,
+       0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x35, 0x07, 0x82, 0xfe, 0x0e, 0x8f, 0xf5, 0xa0, 0x7c, 0x2e,
+       0xf9, 0x65, 0x7b, 0xa8, 0x48, 0xe8, 0x8f, 0x61, 0xb6, 0x1c, 0x30, 0x82, 0x01, 0xe3, 0x06, 0x03,
+       0x55, 0x1d, 0x20, 0x01, 0x01, 0xff, 0x04, 0x82, 0x01, 0xd7, 0x30, 0x82, 0x01, 0xd3, 0x30, 0x82,
+       0x01, 0xc2, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x05, 0x01, 0x30, 0x82, 0x01,
+       0xb3, 0x30, 0x82, 0x01, 0x78, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30,
+       0x82, 0x01, 0x6a, 0x1e, 0x82, 0x01, 0x66, 0x00, 0x52, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x69, 0x00,
+       0x61, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x65, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00,
+       0x74, 0x00, 0x68, 0x00, 0x69, 0x00, 0x73, 0x00, 0x20, 0x00, 0x63, 0x00, 0x65, 0x00, 0x72, 0x00,
+       0x74, 0x00, 0x69, 0x00, 0x66, 0x00, 0x69, 0x00, 0x63, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00,
+       0x20, 0x00, 0x62, 0x00, 0x79, 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x79, 0x00, 0x20, 0x00,
+       0x70, 0x00, 0x61, 0x00, 0x72, 0x00, 0x74, 0x00, 0x79, 0x00, 0x20, 0x00, 0x61, 0x00, 0x73, 0x00,
+       0x73, 0x00, 0x75, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x73, 0x00, 0x20, 0x00, 0x61, 0x00, 0x63, 0x00,
+       0x63, 0x00, 0x65, 0x00, 0x70, 0x00, 0x74, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x65, 0x00,
+       0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00,
+       0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x61, 0x00, 0x70, 0x00, 0x70, 0x00,
+       0x6c, 0x00, 0x69, 0x00, 0x63, 0x00, 0x61, 0x00, 0x62, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x20, 0x00,
+       0x73, 0x00, 0x74, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x61, 0x00, 0x72, 0x00, 0x64, 0x00,
+       0x20, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x6d, 0x00, 0x73, 0x00, 0x20, 0x00, 0x61, 0x00,
+       0x6e, 0x00, 0x64, 0x00, 0x20, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x69, 0x00,
+       0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00,
+       0x20, 0x00, 0x75, 0x00, 0x73, 0x00, 0x65, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x63, 0x00, 0x65, 0x00,
+       0x72, 0x00, 0x74, 0x00, 0x69, 0x00, 0x66, 0x00, 0x69, 0x00, 0x63, 0x00, 0x61, 0x00, 0x74, 0x00,
+       0x65, 0x00, 0x20, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x63, 0x00, 0x79, 0x00,
+       0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20, 0x00, 0x63, 0x00, 0x65, 0x00, 0x72, 0x00,
+       0x74, 0x00, 0x69, 0x00, 0x66, 0x00, 0x69, 0x00, 0x63, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00,
+       0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x70, 0x00, 0x72, 0x00, 0x61, 0x00, 0x63, 0x00, 0x74, 0x00,
+       0x69, 0x00, 0x63, 0x00, 0x65, 0x00, 0x20, 0x00, 0x73, 0x00, 0x74, 0x00, 0x61, 0x00, 0x74, 0x00,
+       0x65, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x73, 0x00, 0x2e, 0x30, 0x35, 0x06,
+       0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x29, 0x68, 0x74, 0x74, 0x70, 0x3a,
+       0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+       0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x61, 0x75, 0x74, 0x68, 0x6f,
+       0x72, 0x69, 0x74, 0x79, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x05,
+       0x0d, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07,
+       0x80, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00,
+       0x03, 0x82, 0x02, 0x01, 0x00, 0xc3, 0xd1, 0x52, 0x94, 0x51, 0xa7, 0x6d, 0xe9, 0xf8, 0x1a, 0xba,
+       0x15, 0x2c, 0x38, 0x6b, 0xd6, 0xba, 0xcf, 0x12, 0x20, 0x1d, 0x46, 0xef, 0x99, 0x48, 0x95, 0x9d,
+       0x1e, 0x49, 0x1b, 0xe7, 0x95, 0xde, 0x73, 0x28, 0xc1, 0x90, 0xfe, 0xeb, 0x39, 0xe1, 0xa8, 0xa8,
+       0x5c, 0x4e, 0x71, 0x03, 0x1b, 0x22, 0x37, 0x07, 0xed, 0x24, 0xa4, 0xee, 0x5d, 0x0a, 0xf8, 0x04,
+       0xf8, 0xba, 0x34, 0x50, 0xc0, 0x49, 0xd7, 0xa4, 0x4f, 0xdd, 0x06, 0x81, 0x33, 0x3a, 0x69, 0x4e,
+       0x43, 0x85, 0x15, 0xde, 0x05, 0x37, 0xf5, 0xb3, 0xd5, 0x68, 0x4c, 0x30, 0x6a, 0x52, 0x35, 0x6a,
+       0xb0, 0x2b, 0x8e, 0xe1, 0xde, 0xa6, 0xd2, 0xfc, 0xe2, 0x9f, 0xdc, 0x95, 0x65, 0x13, 0x45, 0x91,
+       0xc1, 0x7b, 0xff, 0x90, 0x6a, 0x4c, 0xd3, 0x20, 0x5c, 0x1b, 0x99, 0xea, 0x82, 0xec, 0xfd, 0x0b,
+       0x89, 0x25, 0x6c, 0x31, 0x3d, 0xa8, 0x52, 0xba, 0x8e, 0xdf, 0x20, 0xcb, 0x5f, 0x00, 0xf8, 0x6b,
+       0xf2, 0x63, 0x5d, 0x2a, 0x55, 0xc6, 0xee, 0x34, 0xa4, 0x86, 0xab, 0x47, 0x89, 0xcd, 0xb6, 0xaa,
+       0xe0, 0x5c, 0x9a, 0x57, 0x7d, 0x3e, 0xaa, 0x8b, 0x74, 0xfc, 0x94, 0xc7, 0x9d, 0x0e, 0xa2, 0x92,
+       0xa9, 0xc5, 0xdd, 0x71, 0x53, 0x54, 0x38, 0xb0, 0x22, 0x88, 0xdc, 0x46, 0xcd, 0x45, 0xc7, 0x33,
+       0xc7, 0x2f, 0xed, 0x5f, 0x4d, 0x05, 0x9d, 0xba, 0x2e, 0xf7, 0xa4, 0xb5, 0xfa, 0x79, 0x11, 0x41,
+       0xd1, 0x1b, 0x50, 0xab, 0xef, 0xdf, 0xa8, 0x5c, 0x28, 0xc7, 0x8e, 0x86, 0xa2, 0x85, 0x8a, 0x90,
+       0xf4, 0xda, 0x71, 0x1f, 0xff, 0x7f, 0x02, 0x4c, 0x24, 0x95, 0x0d, 0x31, 0xa3, 0x8b, 0x62, 0xae,
+       0x45, 0xe2, 0x44, 0x6c, 0x01, 0x1d, 0xdc, 0x67, 0xbe, 0xfb, 0x16, 0x4f, 0x4c, 0xf0, 0x81, 0xa8,
+       0xbd, 0xe1, 0x29, 0x6f, 0x1c, 0xff, 0xa4, 0x82, 0x96, 0xa3, 0x67, 0xad, 0xa6, 0x99, 0xd6, 0x29,
+       0x02, 0x7f, 0xfc, 0xe3, 0x8d, 0xe3, 0x0d, 0x17, 0x91, 0x84, 0xcf, 0x4b, 0x05, 0xdd, 0x29, 0x96,
+       0xb4, 0x58, 0x56, 0x9b, 0x65, 0x17, 0xdd, 0x16, 0x1f, 0xf8, 0x59, 0x8d, 0xfb, 0xa0, 0xb0, 0xc7,
+       0x0b, 0x74, 0x64, 0xef, 0x8c, 0xcb, 0xba, 0x10, 0x48, 0x37, 0x28, 0xc9, 0x7f, 0x17, 0xac, 0x5f,
+       0x04, 0xa0, 0x50, 0x6d, 0x18, 0x5f, 0x23, 0xe3, 0x9c, 0xb6, 0xe0, 0x6c, 0xc0, 0xe1, 0x5e, 0xba,
+       0x8f, 0x70, 0xf1, 0xca, 0xc5, 0x97, 0x95, 0xf7, 0x4c, 0xdd, 0x6c, 0x8c, 0xbb, 0x4d, 0x68, 0x18,
+       0x59, 0xb3, 0x1b, 0x6f, 0x81, 0xe7, 0xd8, 0x44, 0xdc, 0x6e, 0x84, 0xce, 0x5b, 0x0c, 0x66, 0xef,
+       0xc4, 0x72, 0x00, 0xf2, 0x5a, 0xef, 0x82, 0x63, 0x18, 0xf7, 0xd3, 0xb8, 0x25, 0xc4, 0x91, 0x80,
+       0x04, 0x54, 0x61, 0x5b, 0xf5, 0xe2, 0xda, 0xfb, 0x1d, 0xd4, 0x19, 0x99, 0x18, 0xbd, 0x9a, 0x1e,
+       0x96, 0xe9, 0x1c, 0xd5, 0xd0, 0x06, 0xf5, 0x37, 0x91, 0x3b, 0x4d, 0xa5, 0x2a, 0xda, 0x3c, 0xcd,
+       0xa6, 0xda, 0x53, 0xb8, 0x4a, 0x1e, 0xb9, 0x51, 0xed, 0xc3, 0x47, 0xc6, 0xfa, 0xdc, 0x2e, 0xb3,
+       0xdd, 0x63, 0x65, 0xba, 0x17, 0xdb, 0x65, 0x8b, 0x63, 0x77, 0x31, 0x6d, 0xd9, 0xb7, 0x18, 0x33,
+       0x91, 0xa1, 0x1f, 0xed, 0x0d, 0x49, 0x7f, 0x29, 0xd6, 0xd4, 0xf6, 0x12, 0x0f, 0xb2, 0x0c, 0xc9,
+       0x0f, 0x61, 0xb1, 0x48, 0x58, 0x52, 0xac, 0x80, 0x92, 0xb4, 0x2d, 0x4c, 0xa8, 0x94, 0xf6, 0x99,
+       0xc8, 0xb7, 0x1a, 0x7f, 0x3a, 0x52, 0x49, 0x9f, 0x44, 0xff, 0x0d, 0x38, 0x27, 0x3f, 0xad, 0xf6,
+       0xa4, 0x8f, 0xd9, 0x4b, 0x30, 0x6f, 0xe0, 0xb8, 0x20, 0x94, 0x82, 0x4c, 0x96, 0xea, 0x27, 0x28,
+       0x61, 0x1a, 0x41, 0x6d, 0xd4, 0x30, 0x82, 0x07, 0xca, 0x30, 0x82, 0x05, 0xb2, 0xa0, 0x03, 0x02,
+       0x01, 0x02, 0x02, 0x08, 0x4e, 0xa1, 0x31, 0xe7, 0xca, 0x50, 0xb8, 0x97, 0x30, 0x0d, 0x06, 0x09,
+       0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0d, 0x05, 0x00, 0x30, 0x81, 0x84, 0x31, 0x38,
+       0x30, 0x36, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x2f, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x50,
+       0x4b, 0x49, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x52, 0x6f, 0x6f, 0x74,
+       0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41,
+       0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04,
+       0x0b, 0x0c, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+       0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
+       0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65,
+       0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+       0x55, 0x53, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30, 0x36, 0x32, 0x34, 0x32, 0x33, 0x33, 0x33,
+       0x33, 0x39, 0x5a, 0x17, 0x0d, 0x34, 0x33, 0x30, 0x36, 0x31, 0x37, 0x32, 0x33, 0x33, 0x33, 0x33,
+       0x39, 0x5a, 0x30, 0x81, 0x84, 0x31, 0x38, 0x30, 0x36, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x2f,
+       0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x4b, 0x49, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e,
+       0x67, 0x73, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+       0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31,
+       0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20,
+       0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
+       0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
+       0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x0b, 0x30, 0x09,
+       0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06,
+       0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f,
+       0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, 0x01, 0x00, 0xce, 0x15, 0xf7, 0x6f, 0xd8, 0x42,
+       0x0c, 0x6f, 0x45, 0xb4, 0x04, 0x59, 0x24, 0xcb, 0x70, 0x88, 0x84, 0x77, 0xa1, 0x91, 0x54, 0xf4,
+       0x87, 0x61, 0xb3, 0xd3, 0xfc, 0xbe, 0xb6, 0x05, 0x3c, 0xb9, 0xb7, 0x7d, 0x7c, 0xbc, 0x0b, 0xe8,
+       0x87, 0x07, 0xcf, 0x20, 0xbe, 0xaa, 0xeb, 0x24, 0xc5, 0xe4, 0x5c, 0xcd, 0xcb, 0x89, 0x9f, 0x7a,
+       0xea, 0xb4, 0x5d, 0x3b, 0x29, 0x6c, 0xba, 0x4d, 0x15, 0xfb, 0x59, 0xd0, 0x5a, 0xea, 0x41, 0x4e,
+       0x0d, 0x1d, 0xf7, 0x66, 0x77, 0xa2, 0x96, 0x56, 0xed, 0xd1, 0x16, 0x7b, 0xea, 0xf5, 0x60, 0xdf,
+       0x32, 0x9c, 0xa9, 0xfd, 0xbf, 0xb8, 0x34, 0x6f, 0x57, 0x17, 0xe6, 0x04, 0x37, 0x71, 0x07, 0xc0,
+       0xe9, 0x0f, 0x3c, 0xed, 0x4f, 0x31, 0x87, 0x05, 0xa4, 0xed, 0xab, 0xac, 0xd6, 0x50, 0x05, 0x5b,
+       0xca, 0xd3, 0xf9, 0xd6, 0xaa, 0xaa, 0x88, 0x57, 0x66, 0xf6, 0x6d, 0x8d, 0x4b, 0x71, 0x29, 0xd4,
+       0x3d, 0x1d, 0xbc, 0x82, 0x6e, 0x81, 0xe9, 0x19, 0xf5, 0xe1, 0x12, 0x9f, 0x47, 0xdb, 0x5c, 0xed,
+       0x88, 0xba, 0x51, 0xe7, 0x3a, 0xa0, 0x77, 0x2d, 0xe6, 0xcc, 0xb4, 0x34, 0xdf, 0xad, 0xbd, 0x7b,
+       0xf8, 0xa7, 0x79, 0x51, 0x2d, 0xe6, 0xc2, 0xee, 0xd2, 0x96, 0xfa, 0x60, 0x60, 0x32, 0x40, 0x41,
+       0x37, 0x12, 0xeb, 0x63, 0x99, 0x3d, 0xf3, 0x21, 0xbe, 0xdf, 0xa1, 0x77, 0xe6, 0x81, 0xa9, 0x99,
+       0x0c, 0x4b, 0x43, 0x0c, 0x05, 0x6a, 0x6b, 0x8f, 0x05, 0x02, 0xd9, 0x43, 0xab, 0x72, 0x76, 0xca,
+       0xa7, 0x75, 0x63, 0x85, 0xe3, 0xa5, 0x5c, 0xc0, 0xd6, 0xd4, 0x1c, 0xeb, 0xac, 0x2c, 0x9a, 0x15,
+       0x6b, 0x4e, 0x99, 0x74, 0x7d, 0xd2, 0x69, 0x9f, 0xa8, 0xf7, 0x65, 0xde, 0xeb, 0x36, 0x85, 0xd5,
+       0x7e, 0x4a, 0x7a, 0x8a, 0xeb, 0x7c, 0xcd, 0x43, 0x9e, 0x05, 0xdb, 0x34, 0xc3, 0x69, 0xbd, 0xc2,
+       0xe7, 0xfb, 0xa0, 0x43, 0xb3, 0xd7, 0x15, 0x28, 0x8a, 0x91, 0xce, 0xd7, 0xa7, 0xa4, 0xcc, 0xf4,
+       0x1b, 0x37, 0x33, 0x76, 0xc4, 0x58, 0xb9, 0x2d, 0x89, 0xe2, 0xb6, 0x2c, 0x56, 0x10, 0x96, 0xcc,
+       0xa6, 0x07, 0x79, 0x11, 0x7d, 0x26, 0xd2, 0x85, 0x22, 0x19, 0x20, 0xb7, 0xef, 0xc3, 0xd9, 0x4e,
+       0x18, 0xf3, 0xaa, 0x05, 0xce, 0x87, 0x99, 0xde, 0x76, 0x90, 0x08, 0x74, 0xac, 0x61, 0x31, 0xf8,
+       0x51, 0xa0, 0xc9, 0x70, 0xfc, 0xb9, 0x22, 0xfe, 0xd2, 0x0d, 0xc8, 0x49, 0x64, 0x00, 0xe4, 0xf1,
+       0x53, 0xfd, 0xa1, 0xe6, 0xff, 0x8e, 0xd6, 0xde, 0x9e, 0xcc, 0x3d, 0x37, 0x3a, 0x10, 0x62, 0x59,
+       0xb2, 0x34, 0x8a, 0x1d, 0xf7, 0x9e, 0xa0, 0xbb, 0xf4, 0x53, 0xd9, 0xb8, 0x18, 0x88, 0x12, 0x5c,
+       0x92, 0x0d, 0xc9, 0x94, 0x7f, 0x24, 0xb9, 0x9f, 0xda, 0x07, 0xb6, 0x79, 0x77, 0x09, 0xa3, 0x29,
+       0x3a, 0x70, 0x63, 0x3b, 0x22, 0x42, 0x14, 0xd0, 0xf9, 0x7b, 0x90, 0x52, 0x2b, 0x3f, 0x7f, 0xb7,
+       0x41, 0x20, 0x0d, 0x7e, 0x70, 0xd7, 0x88, 0x36, 0xa2, 0xe9, 0x81, 0x77, 0xf4, 0xb0, 0x15, 0x43,
+       0x9c, 0x5f, 0x4d, 0x3e, 0x4f, 0x83, 0x79, 0x06, 0x73, 0x7a, 0xe7, 0xcb, 0x79, 0x1d, 0xec, 0xa3,
+       0xce, 0x93, 0x5c, 0x68, 0xbf, 0x5a, 0xe6, 0x4c, 0x23, 0x86, 0x41, 0x7f, 0xb4, 0xfc, 0xd0, 0x2c,
+       0x1b, 0x64, 0x39, 0x64, 0xb7, 0xd2, 0x1d, 0xd0, 0x2d, 0x16, 0x77, 0xfe, 0x4d, 0xad, 0xf0, 0x4f,
+       0x38, 0xb3, 0xf9, 0x5a, 0xee, 0x0e, 0x1d, 0xb6, 0xf9, 0x3f, 0xba, 0x77, 0x5a, 0x20, 0xd2, 0x74,
+       0x1a, 0x4b, 0x5a, 0xaf, 0x62, 0xb5, 0xd3, 0xef, 0x37, 0x49, 0xfe, 0x1e, 0xcd, 0xb5, 0xba, 0xb5,
+       0xa6, 0x46, 0x7b, 0x38, 0x63, 0x62, 0x3c, 0x18, 0x7d, 0x57, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
+       0x82, 0x02, 0x3c, 0x30, 0x82, 0x02, 0x38, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16,
+       0x04, 0x14, 0x35, 0x07, 0x82, 0xfe, 0x0e, 0x8f, 0xf5, 0xa0, 0x7c, 0x2e, 0xf9, 0x65, 0x7b, 0xa8,
+       0x48, 0xe8, 0x8f, 0x61, 0xb6, 0x1c, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
+       0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
+       0x30, 0x16, 0x80, 0x14, 0x35, 0x07, 0x82, 0xfe, 0x0e, 0x8f, 0xf5, 0xa0, 0x7c, 0x2e, 0xf9, 0x65,
+       0x7b, 0xa8, 0x48, 0xe8, 0x8f, 0x61, 0xb6, 0x1c, 0x30, 0x82, 0x01, 0xd3, 0x06, 0x03, 0x55, 0x1d,
+       0x20, 0x04, 0x82, 0x01, 0xca, 0x30, 0x82, 0x01, 0xc6, 0x30, 0x82, 0x01, 0xc2, 0x06, 0x09, 0x2a,
+       0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x05, 0x01, 0x30, 0x82, 0x01, 0xb3, 0x30, 0x82, 0x01, 0x78,
+       0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x82, 0x01, 0x6a, 0x1e, 0x82,
+       0x01, 0x66, 0x00, 0x52, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x63,
+       0x00, 0x65, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x69,
+       0x00, 0x73, 0x00, 0x20, 0x00, 0x63, 0x00, 0x65, 0x00, 0x72, 0x00, 0x74, 0x00, 0x69, 0x00, 0x66,
+       0x00, 0x69, 0x00, 0x63, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x20, 0x00, 0x62, 0x00, 0x79,
+       0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x79, 0x00, 0x20, 0x00, 0x70, 0x00, 0x61, 0x00, 0x72,
+       0x00, 0x74, 0x00, 0x79, 0x00, 0x20, 0x00, 0x61, 0x00, 0x73, 0x00, 0x73, 0x00, 0x75, 0x00, 0x6d,
+       0x00, 0x65, 0x00, 0x73, 0x00, 0x20, 0x00, 0x61, 0x00, 0x63, 0x00, 0x63, 0x00, 0x65, 0x00, 0x70,
+       0x00, 0x74, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x65, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66,
+       0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65,
+       0x00, 0x6e, 0x00, 0x20, 0x00, 0x61, 0x00, 0x70, 0x00, 0x70, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x63,
+       0x00, 0x61, 0x00, 0x62, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x20, 0x00, 0x73, 0x00, 0x74, 0x00, 0x61,
+       0x00, 0x6e, 0x00, 0x64, 0x00, 0x61, 0x00, 0x72, 0x00, 0x64, 0x00, 0x20, 0x00, 0x74, 0x00, 0x65,
+       0x00, 0x72, 0x00, 0x6d, 0x00, 0x73, 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20,
+       0x00, 0x63, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x69, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f,
+       0x00, 0x6e, 0x00, 0x73, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x75, 0x00, 0x73,
+       0x00, 0x65, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x63, 0x00, 0x65, 0x00, 0x72, 0x00, 0x74, 0x00, 0x69,
+       0x00, 0x66, 0x00, 0x69, 0x00, 0x63, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x20, 0x00, 0x70,
+       0x00, 0x6f, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x63, 0x00, 0x79, 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e,
+       0x00, 0x64, 0x00, 0x20, 0x00, 0x63, 0x00, 0x65, 0x00, 0x72, 0x00, 0x74, 0x00, 0x69, 0x00, 0x66,
+       0x00, 0x69, 0x00, 0x63, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20,
+       0x00, 0x70, 0x00, 0x72, 0x00, 0x61, 0x00, 0x63, 0x00, 0x74, 0x00, 0x69, 0x00, 0x63, 0x00, 0x65,
+       0x00, 0x20, 0x00, 0x73, 0x00, 0x74, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x65,
+       0x00, 0x6e, 0x00, 0x74, 0x00, 0x73, 0x00, 0x2e, 0x30, 0x35, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+       0x05, 0x07, 0x02, 0x01, 0x16, 0x29, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77,
+       0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69,
+       0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30,
+       0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30,
+       0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0d, 0x05, 0x00, 0x03, 0x82,
+       0x02, 0x01, 0x00, 0x6f, 0x8a, 0xb7, 0x35, 0x73, 0x5a, 0xc5, 0x34, 0xf7, 0x8c, 0xf0, 0xd1, 0x4a,
+       0x17, 0x52, 0x1c, 0x70, 0xf0, 0xe0, 0x53, 0xb4, 0x16, 0xde, 0x81, 0xda, 0x2a, 0xa4, 0xf9, 0x5b,
+       0x0e, 0xa6, 0x17, 0x86, 0x52, 0xc6, 0x70, 0x73, 0xf3, 0x3f, 0x1c, 0x87, 0x94, 0xdd, 0xfe, 0x02,
+       0x0b, 0x85, 0xc9, 0xb9, 0xcf, 0x15, 0x91, 0x05, 0x2e, 0x7e, 0xeb, 0xe6, 0xce, 0x0e, 0x4e, 0xd1,
+       0xf7, 0xe2, 0xd7, 0xf4, 0x60, 0xd2, 0xfc, 0x1d, 0xbf, 0xad, 0x61, 0x28, 0xf8, 0x53, 0x31, 0xb3,
+       0x92, 0xef, 0xa4, 0x05, 0x34, 0x97, 0x57, 0x97, 0x56, 0x3b, 0x12, 0x20, 0x2d, 0x88, 0x76, 0x81,
+       0x0e, 0x77, 0x85, 0xf1, 0x37, 0xc6, 0x19, 0x8b, 0x23, 0xc2, 0x42, 0x55, 0x40, 0xc9, 0x91, 0x5c,
+       0x78, 0xc5, 0xe6, 0x77, 0xfe, 0x72, 0x5f, 0xb2, 0x2c, 0x00, 0xf2, 0xe6, 0x8c, 0xcc, 0x02, 0x49,
+       0xd9, 0x78, 0x20, 0xae, 0xbd, 0x75, 0x61, 0x6a, 0xaa, 0xc5, 0x71, 0x3e, 0x5d, 0x02, 0xdf, 0xd2,
+       0x91, 0x5c, 0x0a, 0x85, 0xc9, 0x59, 0x7d, 0x4e, 0x89, 0x21, 0x59, 0x59, 0xe3, 0xc7, 0xdc, 0xff,
+       0x1e, 0x62, 0x1e, 0xb9, 0x62, 0x2c, 0x34, 0x49, 0x15, 0xd9, 0xdf, 0x47, 0x99, 0x39, 0xcc, 0x1a,
+       0x01, 0xc0, 0xda, 0x48, 0x44, 0xd4, 0x8b, 0xd3, 0x17, 0x7e, 0x39, 0xf9, 0x00, 0xe1, 0x2a, 0x46,
+       0xaa, 0x14, 0x22, 0xa1, 0x38, 0x09, 0x0b, 0xb7, 0x0c, 0x88, 0xa5, 0x73, 0xfd, 0xc4, 0x6b, 0xee,
+       0x07, 0xb4, 0x1b, 0xb3, 0x4a, 0xab, 0xae, 0xf6, 0xe7, 0x04, 0x61, 0x4b, 0x34, 0x7a, 0xe4, 0xff,
+       0xf9, 0x30, 0x28, 0x61, 0x92, 0x52, 0x58, 0x10, 0x15, 0x3a, 0x9f, 0x0a, 0xaf, 0x15, 0x29, 0x6c,
+       0x67, 0xc4, 0xb4, 0xcf, 0xe6, 0xf9, 0x46, 0x68, 0xe2, 0x2a, 0x97, 0x29, 0x16, 0xed, 0x1a, 0x9b,
+       0x9a, 0x45, 0x70, 0x3c, 0xf2, 0xdf, 0x29, 0x20, 0x9e, 0x33, 0x4b, 0x5b, 0x8d, 0xf6, 0x19, 0xec,
+       0x4b, 0xae, 0x1a, 0x2f, 0x53, 0x03, 0x9a, 0xfd, 0x68, 0x39, 0x58, 0xf7, 0x2e, 0x07, 0x9c, 0xf1,
+       0x3c, 0x1b, 0x47, 0x43, 0x19, 0x81, 0x0e, 0x0a, 0xbb, 0x84, 0xa0, 0xda, 0x87, 0xbc, 0x8a, 0x2a,
+       0xb7, 0x9c, 0xe1, 0xf9, 0xeb, 0x37, 0xb0, 0x11, 0x20, 0x7e, 0x4c, 0x11, 0x2e, 0x54, 0x30, 0xce,
+       0xaf, 0x63, 0xed, 0x6a, 0x63, 0x1f, 0x1e, 0x61, 0x62, 0x04, 0xf3, 0x3a, 0x5f, 0x26, 0x6c, 0x5c,
+       0xd7, 0xba, 0x4f, 0xf2, 0x61, 0x26, 0x29, 0x99, 0xea, 0x61, 0x84, 0x0d, 0x68, 0xa2, 0x5d, 0x9b,
+       0x5c, 0xe7, 0x86, 0x1d, 0xef, 0xf4, 0x6f, 0x3b, 0x6c, 0x67, 0xf0, 0x70, 0xe9, 0xc5, 0xdc, 0x0a,
+       0x9d, 0x0f, 0xdc, 0xcc, 0x0e, 0x7b, 0xf8, 0xc4, 0xee, 0x64, 0xe4, 0xd9, 0x3f, 0x14, 0xae, 0x8f,
+       0xc8, 0x18, 0x4d, 0xa1, 0xe4, 0x40, 0x2c, 0xe9, 0x13, 0xc6, 0xc1, 0xe0, 0xb9, 0x13, 0xbe, 0xd9,
+       0x93, 0x66, 0x56, 0x35, 0x5c, 0xc1, 0x38, 0x7d, 0xa1, 0xbb, 0x87, 0xa5, 0x90, 0x33, 0x4f, 0xea,
+       0xb6, 0x37, 0x19, 0x61, 0x81, 0x40, 0xba, 0xd7, 0x07, 0x69, 0x05, 0x15, 0x96, 0xe9, 0xde, 0x4f,
+       0x8a, 0x2b, 0x99, 0x5a, 0x17, 0x3f, 0x9f, 0xcf, 0x86, 0xf5, 0x37, 0x0a, 0xa1, 0x0e, 0x25, 0x65,
+       0x2d, 0x52, 0xce, 0x87, 0x10, 0x0f, 0x25, 0xc2, 0x1e, 0x0f, 0x71, 0x93, 0xb5, 0xc0, 0xb3, 0xb4,
+       0xd1, 0x65, 0xa8, 0xb4, 0xf6, 0xa5, 0x71, 0xad, 0x45, 0xdb, 0xdf, 0xec, 0xe3, 0x2a, 0x7e, 0x99,
+       0x96, 0x5a, 0x5d, 0x69, 0xfa, 0xdb, 0x13, 0x39, 0xb8, 0xf5, 0x58, 0xbb, 0x87, 0x69, 0x8d, 0x2c,
+       0x6d, 0x39, 0xff, 0x26, 0xce, 0x2c, 0xa8, 0x5a, 0x7e, 0x4b, 0x3f, 0xed, 0xac, 0x5f, 0xf0, 0xef,
+       0x48, 0xd3, 0xf8, 0x00, 0x00, 0x31, 0x82, 0x03, 0x28, 0x30, 0x82, 0x03, 0x24, 0x02, 0x01, 0x01,
+       0x30, 0x81, 0x91, 0x30, 0x81, 0x84, 0x31, 0x38, 0x30, 0x36, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
+       0x2f, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x4b, 0x49, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69,
+       0x6e, 0x67, 0x73, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+       0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
+       0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65,
+       0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41,
+       0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
+       0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x0b, 0x30,
+       0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x02, 0x08, 0x04, 0x2e, 0x97, 0xbb,
+       0x62, 0x84, 0xd9, 0x1c, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02,
+       0x01, 0x05, 0x00, 0xa0, 0x69, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+       0x09, 0x03, 0x31, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30,
+       0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x05, 0x31, 0x0f, 0x17, 0x0d,
+       0x31, 0x33, 0x30, 0x36, 0x32, 0x35, 0x30, 0x30, 0x33, 0x39, 0x33, 0x33, 0x5a, 0x30, 0x2f, 0x06,
+       0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04, 0x31, 0x22, 0x04, 0x20, 0x40, 0xe5,
+       0x7f, 0xba, 0xdb, 0xb7, 0xe8, 0x35, 0xa0, 0x59, 0xd4, 0xa0, 0x57, 0x5c, 0x60, 0x53, 0x98, 0x48,
+       0xda, 0x3b, 0x79, 0xf4, 0x73, 0x63, 0xd7, 0x90, 0xf0, 0x10, 0x2b, 0x71, 0x6e, 0x36, 0x30, 0x0d,
+       0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x02,
+       0x00, 0x6a, 0x51, 0xe7, 0xdc, 0x34, 0x87, 0x3c, 0x45, 0xd1, 0xeb, 0x6d, 0x20, 0x26, 0xcd, 0x53,
+       0x01, 0x82, 0x71, 0x25, 0x73, 0xce, 0xe3, 0x9f, 0xfb, 0xca, 0x4c, 0x89, 0x01, 0x96, 0x6a, 0x1c,
+       0x02, 0x57, 0xb1, 0xd1, 0x99, 0x43, 0x29, 0x4e, 0xfc, 0xf3, 0x30, 0x9e, 0xbc, 0x7e, 0xc4, 0x04,
+       0xa3, 0x5d, 0x1a, 0x3c, 0x54, 0xc2, 0xba, 0x38, 0xdc, 0x8d, 0x12, 0xaf, 0xb4, 0x12, 0xe4, 0xeb,
+       0x8a, 0x03, 0xb0, 0xc7, 0xaa, 0x72, 0xf4, 0x8b, 0x87, 0xd0, 0x0e, 0xd7, 0x9f, 0x45, 0xcb, 0xa5,
+       0x0f, 0x4c, 0x60, 0x2b, 0xe5, 0xf7, 0xe8, 0xf1, 0x0a, 0xc0, 0x29, 0x0f, 0xe0, 0xa7, 0x0a, 0xc0,
+       0x4b, 0xd9, 0x16, 0x04, 0xde, 0x4d, 0xc1, 0x5c, 0xbd, 0xad, 0x84, 0xb3, 0x8e, 0x72, 0x7d, 0xcc,
+       0x73, 0x77, 0xe9, 0xeb, 0x3a, 0x36, 0xbc, 0xbd, 0x58, 0x0b, 0x97, 0x12, 0xd2, 0x9c, 0x3b, 0xd1,
+       0x32, 0x2d, 0xbd, 0xe7, 0x40, 0xc8, 0x4c, 0x82, 0xbb, 0xe4, 0x49, 0xbc, 0x64, 0x50, 0xe3, 0x8b,
+       0xba, 0xa2, 0xac, 0x31, 0xdb, 0xcd, 0x57, 0x79, 0xeb, 0x91, 0x87, 0xc7, 0x52, 0x70, 0xfe, 0xaa,
+       0xd0, 0x7d, 0xd2, 0x78, 0x48, 0x77, 0xbc, 0xd9, 0xa7, 0x2b, 0x01, 0x20, 0x36, 0xd0, 0x99, 0x61,
+       0x90, 0xfc, 0xb2, 0x8a, 0xfd, 0x02, 0xad, 0x60, 0xb6, 0x89, 0x82, 0xca, 0x8a, 0xc3, 0x6f, 0xd7,
+       0x91, 0xb1, 0x4c, 0x25, 0x6a, 0x00, 0x59, 0xaa, 0x2c, 0xa0, 0xfc, 0x8b, 0x54, 0x64, 0xbd, 0x04,
+       0x46, 0x8f, 0x7c, 0x1d, 0x53, 0xd4, 0x57, 0x9c, 0x06, 0x1f, 0xd8, 0x8e, 0x8b, 0x79, 0x0a, 0xe6,
+       0xf5, 0xf3, 0xab, 0x10, 0x8c, 0xe1, 0x65, 0xd7, 0x0f, 0xf1, 0x9f, 0xe3, 0xf7, 0xd1, 0xca, 0xb2,
+       0x6d, 0xcb, 0x6b, 0x50, 0x94, 0x1f, 0x1f, 0x4d, 0x55, 0xd1, 0xcb, 0x99, 0x86, 0xfe, 0xa4, 0xe5,
+       0x05, 0x6c, 0x09, 0x54, 0x3a, 0xc7, 0x1c, 0x6e, 0xa5, 0x9c, 0x49, 0x69, 0xbb, 0xc3, 0x24, 0x8c,
+       0x94, 0xf6, 0x67, 0xbd, 0x7b, 0xe9, 0x71, 0x31, 0x14, 0xcf, 0xf3, 0xf4, 0xdc, 0xd9, 0xdf, 0x99,
+       0x31, 0x3d, 0x6f, 0xda, 0xba, 0x7c, 0x62, 0xbd, 0x2c, 0x01, 0x2c, 0x03, 0xa5, 0xfb, 0x22, 0xac,
+       0x55, 0x60, 0x89, 0xe4, 0xf2, 0xb4, 0xb7, 0xed, 0x18, 0x9d, 0xa5, 0xe9, 0x55, 0xe6, 0xef, 0xbb,
+       0x79, 0xe6, 0xf9, 0xd0, 0xf0, 0x62, 0x71, 0x30, 0x12, 0xdf, 0xde, 0x15, 0x42, 0x46, 0x2c, 0x5a,
+       0x81, 0x6f, 0x3c, 0x38, 0x7f, 0x75, 0x00, 0x95, 0x68, 0xea, 0x43, 0x1c, 0x6a, 0xf9, 0x81, 0xde,
+       0xb5, 0x0c, 0x0e, 0x50, 0xb5, 0x67, 0x9a, 0xea, 0x37, 0x6d, 0x9d, 0xd3, 0xd0, 0x69, 0x89, 0x5c,
+       0x51, 0x27, 0x37, 0x10, 0x6f, 0x6e, 0x13, 0xdb, 0xb8, 0xb8, 0xe9, 0xd0, 0x84, 0x12, 0xf2, 0x3d,
+       0x71, 0xc9, 0x7c, 0xe6, 0x9a, 0x1c, 0x50, 0xee, 0x43, 0x25, 0xff, 0x0b, 0x31, 0x88, 0x5b, 0xfa,
+       0xc9, 0x84, 0x31, 0xb8, 0x6f, 0x67, 0x37, 0x7f, 0xa5, 0x0c, 0xaf, 0x15, 0x2a, 0x15, 0x04, 0xbd,
+       0x1c, 0x76, 0xcb, 0x34, 0xb2, 0x38, 0x77, 0x2f, 0x1a, 0x09, 0x8b, 0x01, 0x44, 0xf5, 0x5f, 0x47,
+       0x40, 0x64, 0x2a, 0x21, 0x4a, 0x88, 0xa2, 0xdd, 0xe6, 0xc5, 0xc4, 0x9d, 0xfd, 0x7c, 0x3d, 0xe3,
+       0x1a, 0x79, 0x30, 0x90, 0xda, 0x17, 0x4d, 0x92, 0x86, 0xe6, 0xf7, 0x19, 0x93, 0x58, 0x1f, 0x21,
+       0x16, 0x60, 0x01, 0x6a, 0xbb, 0x69, 0xc4, 0xfd, 0x29, 0xfc, 0xac, 0x04, 0xcb, 0x97, 0x7b, 0x47,
+       0x51, 0xf6, 0x29, 0xca, 0x48, 0x52, 0x02, 0xb6, 0x27, 0x1c, 0xf2, 0x96, 0x06, 0x48, 0x23, 0x9d,
+       0xf6, 0x93, 0xda, 0x5d, 0x83, 0x61, 0x2b, 0xbd, 0x52, 0x0c, 0x4d, 0x89, 0xf3, 0x2f, 0xa2, 0x67,
+       0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 
+};
+
+static const UInt8 kSignedManifestData[] = {
+       0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x80, 0x30,
+       0x80, 0x02, 0x01, 0x01, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
+       0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+       0x07, 0x01, 0xa0, 0x80, 0x24, 0x80, 0x04, 0x82, 0x01, 0xeb, 0x62, 0x70, 0x6c, 0x69, 0x73, 0x74,
+       0x30, 0x30, 0xd8, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
+       0x0e, 0x0f, 0x10, 0x5d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4e, 0x75, 0x6d, 0x62, 0x65,
+       0x72, 0x5d, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x2e, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x5f,
+       0x10, 0x0f, 0x63, 0x65, 0x72, 0x74, 0x73, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x64, 0x61, 0x74,
+       0x61, 0x5d, 0x45, 0x56, 0x52, 0x6f, 0x6f, 0x74, 0x73, 0x2e, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x5f,
+       0x10, 0x14, 0x47, 0x72, 0x61, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x73,
+       0x2e, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x10, 0x12, 0x41, 0x73, 0x73, 0x65, 0x74, 0x56, 0x65,
+       0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x10, 0x0f, 0x63, 0x65,
+       0x72, 0x74, 0x73, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x10, 0x19,
+       0x41, 0x70, 0x70, 0x6c, 0x65, 0x45, 0x53, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
+       0x74, 0x65, 0x73, 0x2e, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x77, 0xfc, 0xe6, 0x2c, 0x4f, 0x10,
+       0x20, 0x08, 0x89, 0x3f, 0xe7, 0x83, 0xdf, 0x07, 0x61, 0xaf, 0x65, 0x58, 0x66, 0xce, 0x74, 0xb5,
+       0x46, 0x56, 0xc2, 0x03, 0x35, 0x4a, 0xd4, 0x88, 0xa7, 0x32, 0x6e, 0xdd, 0xcb, 0xb9, 0xb5, 0x21,
+       0x6c, 0x4f, 0x10, 0x20, 0x2e, 0xa3, 0x40, 0x44, 0x60, 0xdb, 0x4f, 0x51, 0x3c, 0x06, 0x27, 0x4e,
+       0x00, 0x7b, 0x25, 0x35, 0x13, 0x9a, 0x61, 0xc4, 0xa8, 0x0a, 0xaa, 0xcd, 0x70, 0xe7, 0x75, 0x7e,
+       0x4d, 0x52, 0xbb, 0x24, 0x4f, 0x10, 0x20, 0x41, 0x11, 0x04, 0x71, 0xcb, 0x9b, 0xfb, 0xaf, 0xcf,
+       0x6f, 0x1d, 0xee, 0x8e, 0x14, 0x3c, 0x1d, 0x39, 0x64, 0x68, 0xc8, 0x48, 0xb1, 0xee, 0x8a, 0xd1,
+       0x05, 0x62, 0x40, 0x4f, 0x79, 0x22, 0x30, 0x4f, 0x10, 0x20, 0xa5, 0x0a, 0x89, 0x37, 0xf0, 0xa8,
+       0x87, 0x2b, 0xcc, 0x33, 0xc1, 0x5a, 0xe6, 0xd3, 0x01, 0x43, 0x83, 0x50, 0x8d, 0x49, 0x84, 0x96,
+       0x22, 0xaf, 0x3e, 0x26, 0x10, 0x78, 0x8a, 0x3a, 0x0c, 0x78, 0x4f, 0x10, 0x20, 0x6c, 0xcb, 0x07,
+       0xc1, 0x68, 0x6f, 0xf9, 0xa3, 0x0c, 0x12, 0xd7, 0xb8, 0xe2, 0x51, 0x3d, 0xe2, 0xd5, 0x43, 0xeb,
+       0xb5, 0x6d, 0x80, 0x6d, 0x8c, 0xca, 0x17, 0xd5, 0x31, 0x1a, 0x65, 0x48, 0x15, 0x4f, 0x10, 0x20,
+       0xa6, 0x4c, 0x19, 0xd2, 0xb8, 0xe4, 0xbf, 0x59, 0x9a, 0x68, 0xe5, 0x34, 0x08, 0xc3, 0x61, 0x91,
+       0xf9, 0x06, 0xf1, 0x16, 0x02, 0x1c, 0xfd, 0xaf, 0x46, 0xfb, 0xad, 0xc7, 0xb4, 0x57, 0x1d, 0x54,
+       0x4f, 0x10, 0x20, 0x94, 0x47, 0xd4, 0x5d, 0xaf, 0x6a, 0x4f, 0xba, 0xc4, 0xe8, 0x6b, 0x10, 0x32,
+       0x2a, 0x37, 0x90, 0x3c, 0x5a, 0x5b, 0x9f, 0x33, 0x48, 0x59, 0xd3, 0x1d, 0xf5, 0x57, 0x90, 0xde,
+       0xb3, 0x5b, 0xf6, 0x00, 0x08, 0x00, 0x19, 0x00, 0x27, 0x00, 0x35, 0x00, 0x47, 0x00, 0x55, 0x00,
+       0x6c, 0x00, 0x81, 0x00, 0x93, 0x00, 0xaf, 0x00, 0xb4, 0x00, 0xd7, 0x00, 0xfa, 0x01, 0x1d, 0x01,
+       0x40, 0x01, 0x63, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x01, 0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x30, 0x82, 0x07,
+       0xab, 0x30, 0x82, 0x05, 0x93, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x04, 0x2e, 0x97, 0xbb,
+       0x62, 0x84, 0xd9, 0x1c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+       0x0b, 0x05, 0x00, 0x30, 0x81, 0x84, 0x31, 0x38, 0x30, 0x36, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
+       0x2f, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x4b, 0x49, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69,
+       0x6e, 0x67, 0x73, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+       0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
+       0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65,
+       0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41,
+       0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
+       0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x0b, 0x30,
+       0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33,
+       0x30, 0x36, 0x32, 0x35, 0x30, 0x30, 0x30, 0x39, 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x32, 0x38, 0x30,
+       0x36, 0x32, 0x31, 0x30, 0x30, 0x30, 0x39, 0x33, 0x38, 0x5a, 0x30, 0x59, 0x31, 0x23, 0x30, 0x21,
+       0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x4b, 0x49,
+       0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e,
+       0x67, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x07, 0x43, 0x6f, 0x72, 0x65,
+       0x20, 0x4f, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70,
+       0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
+       0x06, 0x13, 0x02, 0x55, 0x53, 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+       0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02,
+       0x0a, 0x02, 0x82, 0x02, 0x01, 0x00, 0xad, 0xef, 0x52, 0xc8, 0xda, 0x8e, 0x3c, 0xcc, 0x06, 0xcf,
+       0xfc, 0xed, 0xdb, 0x92, 0xb3, 0xa8, 0xe0, 0x3b, 0x14, 0x40, 0x34, 0xad, 0x91, 0xf3, 0xbe, 0x1a,
+       0x00, 0xbb, 0x06, 0xa2, 0xd7, 0x24, 0x6f, 0xd5, 0xd3, 0xdf, 0xd9, 0xff, 0x0b, 0x4d, 0x6d, 0xc5,
+       0xdd, 0x7a, 0x37, 0xfa, 0x08, 0x49, 0x0e, 0x36, 0x5e, 0xab, 0x83, 0x8d, 0xeb, 0x83, 0x00, 0xf9,
+       0xaa, 0xe4, 0x88, 0x09, 0x87, 0x05, 0x6b, 0x01, 0x6e, 0x49, 0x54, 0xa1, 0x3b, 0x5c, 0xfc, 0x2b,
+       0x0f, 0x1f, 0xa9, 0x7c, 0xc1, 0xc5, 0xe1, 0x32, 0xd7, 0x86, 0x49, 0x80, 0x0f, 0xf8, 0xe3, 0x3b,
+       0xa3, 0x12, 0x06, 0x5d, 0xf4, 0x43, 0xc0, 0xb2, 0xc7, 0xcf, 0xb4, 0x14, 0x2c, 0x50, 0x70, 0x57,
+       0xb9, 0xb2, 0xe7, 0x72, 0x9a, 0x9f, 0x45, 0x0b, 0x0d, 0xe5, 0xab, 0x3e, 0x23, 0x91, 0xe0, 0x88,
+       0x84, 0x3a, 0xec, 0xaa, 0x80, 0xab, 0x37, 0xa3, 0x0c, 0x63, 0x99, 0x1c, 0xde, 0x1b, 0x29, 0x95,
+       0x4b, 0xff, 0xcd, 0x92, 0x10, 0xa3, 0x50, 0x93, 0x89, 0x4f, 0xdc, 0x30, 0x0d, 0x29, 0x2a, 0x80,
+       0x04, 0x32, 0xb3, 0xb9, 0xa7, 0x79, 0x5f, 0x18, 0xce, 0xc1, 0x90, 0xe6, 0xd6, 0x0c, 0xeb, 0x91,
+       0x27, 0x6f, 0x17, 0xd2, 0x93, 0xda, 0xa1, 0xa8, 0x3f, 0x20, 0xe9, 0xeb, 0x54, 0x37, 0xd7, 0x54,
+       0xfd, 0x44, 0xa2, 0x8d, 0xa4, 0x30, 0x6e, 0xbf, 0xd0, 0xbd, 0xc4, 0x7d, 0x93, 0xeb, 0xf6, 0xfa,
+       0x1e, 0xc1, 0xd5, 0xee, 0xfe, 0xb7, 0x56, 0x51, 0xb3, 0x0b, 0x3f, 0xf4, 0xb1, 0x77, 0x75, 0xaf,
+       0x10, 0x14, 0x98, 0x74, 0x41, 0x40, 0xdb, 0xe4, 0x6b, 0x3f, 0x49, 0xce, 0xb8, 0x80, 0x20, 0x72,
+       0x92, 0xcb, 0x63, 0x63, 0x44, 0x4e, 0xe8, 0xe4, 0xde, 0xe9, 0xc3, 0x0a, 0x75, 0xd8, 0xbf, 0xc5,
+       0x8e, 0xcb, 0xcf, 0xec, 0x65, 0x49, 0x56, 0xa1, 0x9f, 0xb6, 0x39, 0x53, 0x69, 0xb4, 0x04, 0xe8,
+       0xd0, 0x28, 0xc6, 0x69, 0xde, 0xdb, 0x30, 0xa7, 0xb0, 0xbf, 0x6f, 0xfe, 0x7b, 0x45, 0x87, 0x07,
+       0xf0, 0x85, 0x34, 0x71, 0xca, 0xe5, 0x07, 0x61, 0xce, 0x53, 0xf3, 0xd6, 0x69, 0x70, 0x5a, 0x4b,
+       0x7e, 0xda, 0x9b, 0x77, 0x17, 0x65, 0x6c, 0x4d, 0xd5, 0x59, 0x00, 0x6f, 0x47, 0x65, 0x30, 0x98,
+       0xd9, 0x7b, 0xa7, 0x51, 0x8b, 0x47, 0x7d, 0x8f, 0x5a, 0x91, 0x72, 0xe4, 0x86, 0x4f, 0xb0, 0xb4,
+       0x12, 0x42, 0x55, 0x95, 0x59, 0xa3, 0xc6, 0xdf, 0xba, 0x20, 0x0e, 0x5d, 0x0f, 0x6a, 0x6a, 0xc2,
+       0x08, 0x93, 0x9f, 0x0e, 0x8b, 0x61, 0x20, 0x9e, 0x2b, 0x64, 0x26, 0x15, 0x52, 0x9b, 0xef, 0x34,
+       0x7c, 0x12, 0xa4, 0xe4, 0xf7, 0xfc, 0x9a, 0xa6, 0xe6, 0xe9, 0x6f, 0xfc, 0xbb, 0x16, 0xc4, 0x0f,
+       0x0b, 0xac, 0x84, 0x9d, 0xc8, 0xe9, 0x98, 0xe1, 0xf4, 0x35, 0xfb, 0x97, 0x63, 0x14, 0x6c, 0x15,
+       0x51, 0x51, 0x5b, 0xc8, 0x64, 0x25, 0x46, 0x44, 0x6d, 0xbd, 0x17, 0xdd, 0x17, 0x4d, 0x34, 0x77,
+       0xa8, 0x6d, 0x4b, 0x97, 0x4b, 0x77, 0xf5, 0x77, 0x07, 0x1b, 0x93, 0x18, 0xf3, 0x44, 0x4e, 0x79,
+       0xe2, 0xfc, 0x96, 0x76, 0x5e, 0x69, 0x85, 0xf6, 0xb6, 0x97, 0xbb, 0xb0, 0x41, 0x1f, 0x03, 0x8b,
+       0xcb, 0xc0, 0xa9, 0x10, 0x67, 0x8f, 0x6f, 0x67, 0xab, 0xb0, 0xbd, 0x1f, 0xc7, 0x11, 0xfd, 0xb8,
+       0x29, 0x47, 0x41, 0xd4, 0x34, 0x0f, 0x5b, 0x9d, 0x64, 0xfb, 0x8f, 0x5f, 0x37, 0xd1, 0x9a, 0x4a,
+       0x2d, 0x62, 0xd1, 0x74, 0x2e, 0x6b, 0x7f, 0xdf, 0xb3, 0xea, 0x5f, 0xfa, 0x63, 0xd4, 0x4f, 0xb3,
+       0x89, 0x76, 0x67, 0x36, 0x71, 0xcd, 0xaf, 0xd7, 0x9c, 0x95, 0xa8, 0xce, 0xee, 0x29, 0x25, 0xb1,
+       0x2a, 0xac, 0x99, 0x10, 0x9b, 0x03, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x02, 0x49, 0x30,
+       0x82, 0x02, 0x45, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xcd, 0xbf,
+       0x6f, 0x14, 0xff, 0x8b, 0xb7, 0xf7, 0x29, 0xcd, 0xa4, 0x8c, 0xc1, 0xb1, 0x30, 0x92, 0x37, 0x8b,
+       0xd4, 0xef, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00,
+       0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x35, 0x07, 0x82,
+       0xfe, 0x0e, 0x8f, 0xf5, 0xa0, 0x7c, 0x2e, 0xf9, 0x65, 0x7b, 0xa8, 0x48, 0xe8, 0x8f, 0x61, 0xb6,
+       0x1c, 0x30, 0x82, 0x01, 0xe3, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x01, 0x01, 0xff, 0x04, 0x82, 0x01,
+       0xd7, 0x30, 0x82, 0x01, 0xd3, 0x30, 0x82, 0x01, 0xc2, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+       0x63, 0x64, 0x05, 0x01, 0x30, 0x82, 0x01, 0xb3, 0x30, 0x82, 0x01, 0x78, 0x06, 0x08, 0x2b, 0x06,
+       0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x82, 0x01, 0x6a, 0x1e, 0x82, 0x01, 0x66, 0x00, 0x52,
+       0x00, 0x65, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x65, 0x00, 0x20,
+       0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x69, 0x00, 0x73, 0x00, 0x20,
+       0x00, 0x63, 0x00, 0x65, 0x00, 0x72, 0x00, 0x74, 0x00, 0x69, 0x00, 0x66, 0x00, 0x69, 0x00, 0x63,
+       0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x20, 0x00, 0x62, 0x00, 0x79, 0x00, 0x20, 0x00, 0x61,
+       0x00, 0x6e, 0x00, 0x79, 0x00, 0x20, 0x00, 0x70, 0x00, 0x61, 0x00, 0x72, 0x00, 0x74, 0x00, 0x79,
+       0x00, 0x20, 0x00, 0x61, 0x00, 0x73, 0x00, 0x73, 0x00, 0x75, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x73,
+       0x00, 0x20, 0x00, 0x61, 0x00, 0x63, 0x00, 0x63, 0x00, 0x65, 0x00, 0x70, 0x00, 0x74, 0x00, 0x61,
+       0x00, 0x6e, 0x00, 0x63, 0x00, 0x65, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x74,
+       0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x20,
+       0x00, 0x61, 0x00, 0x70, 0x00, 0x70, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x63, 0x00, 0x61, 0x00, 0x62,
+       0x00, 0x6c, 0x00, 0x65, 0x00, 0x20, 0x00, 0x73, 0x00, 0x74, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64,
+       0x00, 0x61, 0x00, 0x72, 0x00, 0x64, 0x00, 0x20, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x6d,
+       0x00, 0x73, 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20, 0x00, 0x63, 0x00, 0x6f,
+       0x00, 0x6e, 0x00, 0x64, 0x00, 0x69, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x73,
+       0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x75, 0x00, 0x73, 0x00, 0x65, 0x00, 0x2c,
+       0x00, 0x20, 0x00, 0x63, 0x00, 0x65, 0x00, 0x72, 0x00, 0x74, 0x00, 0x69, 0x00, 0x66, 0x00, 0x69,
+       0x00, 0x63, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x20, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x6c,
+       0x00, 0x69, 0x00, 0x63, 0x00, 0x79, 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20,
+       0x00, 0x63, 0x00, 0x65, 0x00, 0x72, 0x00, 0x74, 0x00, 0x69, 0x00, 0x66, 0x00, 0x69, 0x00, 0x63,
+       0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x70, 0x00, 0x72,
+       0x00, 0x61, 0x00, 0x63, 0x00, 0x74, 0x00, 0x69, 0x00, 0x63, 0x00, 0x65, 0x00, 0x20, 0x00, 0x73,
+       0x00, 0x74, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74,
+       0x00, 0x73, 0x00, 0x2e, 0x30, 0x35, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01,
+       0x16, 0x29, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70,
+       0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
+       0x74, 0x65, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x0b, 0x06, 0x09, 0x2a,
+       0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x05, 0x0d, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
+       0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+       0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0xc3, 0xd1, 0x52, 0x94,
+       0x51, 0xa7, 0x6d, 0xe9, 0xf8, 0x1a, 0xba, 0x15, 0x2c, 0x38, 0x6b, 0xd6, 0xba, 0xcf, 0x12, 0x20,
+       0x1d, 0x46, 0xef, 0x99, 0x48, 0x95, 0x9d, 0x1e, 0x49, 0x1b, 0xe7, 0x95, 0xde, 0x73, 0x28, 0xc1,
+       0x90, 0xfe, 0xeb, 0x39, 0xe1, 0xa8, 0xa8, 0x5c, 0x4e, 0x71, 0x03, 0x1b, 0x22, 0x37, 0x07, 0xed,
+       0x24, 0xa4, 0xee, 0x5d, 0x0a, 0xf8, 0x04, 0xf8, 0xba, 0x34, 0x50, 0xc0, 0x49, 0xd7, 0xa4, 0x4f,
+       0xdd, 0x06, 0x81, 0x33, 0x3a, 0x69, 0x4e, 0x43, 0x85, 0x15, 0xde, 0x05, 0x37, 0xf5, 0xb3, 0xd5,
+       0x68, 0x4c, 0x30, 0x6a, 0x52, 0x35, 0x6a, 0xb0, 0x2b, 0x8e, 0xe1, 0xde, 0xa6, 0xd2, 0xfc, 0xe2,
+       0x9f, 0xdc, 0x95, 0x65, 0x13, 0x45, 0x91, 0xc1, 0x7b, 0xff, 0x90, 0x6a, 0x4c, 0xd3, 0x20, 0x5c,
+       0x1b, 0x99, 0xea, 0x82, 0xec, 0xfd, 0x0b, 0x89, 0x25, 0x6c, 0x31, 0x3d, 0xa8, 0x52, 0xba, 0x8e,
+       0xdf, 0x20, 0xcb, 0x5f, 0x00, 0xf8, 0x6b, 0xf2, 0x63, 0x5d, 0x2a, 0x55, 0xc6, 0xee, 0x34, 0xa4,
+       0x86, 0xab, 0x47, 0x89, 0xcd, 0xb6, 0xaa, 0xe0, 0x5c, 0x9a, 0x57, 0x7d, 0x3e, 0xaa, 0x8b, 0x74,
+       0xfc, 0x94, 0xc7, 0x9d, 0x0e, 0xa2, 0x92, 0xa9, 0xc5, 0xdd, 0x71, 0x53, 0x54, 0x38, 0xb0, 0x22,
+       0x88, 0xdc, 0x46, 0xcd, 0x45, 0xc7, 0x33, 0xc7, 0x2f, 0xed, 0x5f, 0x4d, 0x05, 0x9d, 0xba, 0x2e,
+       0xf7, 0xa4, 0xb5, 0xfa, 0x79, 0x11, 0x41, 0xd1, 0x1b, 0x50, 0xab, 0xef, 0xdf, 0xa8, 0x5c, 0x28,
+       0xc7, 0x8e, 0x86, 0xa2, 0x85, 0x8a, 0x90, 0xf4, 0xda, 0x71, 0x1f, 0xff, 0x7f, 0x02, 0x4c, 0x24,
+       0x95, 0x0d, 0x31, 0xa3, 0x8b, 0x62, 0xae, 0x45, 0xe2, 0x44, 0x6c, 0x01, 0x1d, 0xdc, 0x67, 0xbe,
+       0xfb, 0x16, 0x4f, 0x4c, 0xf0, 0x81, 0xa8, 0xbd, 0xe1, 0x29, 0x6f, 0x1c, 0xff, 0xa4, 0x82, 0x96,
+       0xa3, 0x67, 0xad, 0xa6, 0x99, 0xd6, 0x29, 0x02, 0x7f, 0xfc, 0xe3, 0x8d, 0xe3, 0x0d, 0x17, 0x91,
+       0x84, 0xcf, 0x4b, 0x05, 0xdd, 0x29, 0x96, 0xb4, 0x58, 0x56, 0x9b, 0x65, 0x17, 0xdd, 0x16, 0x1f,
+       0xf8, 0x59, 0x8d, 0xfb, 0xa0, 0xb0, 0xc7, 0x0b, 0x74, 0x64, 0xef, 0x8c, 0xcb, 0xba, 0x10, 0x48,
+       0x37, 0x28, 0xc9, 0x7f, 0x17, 0xac, 0x5f, 0x04, 0xa0, 0x50, 0x6d, 0x18, 0x5f, 0x23, 0xe3, 0x9c,
+       0xb6, 0xe0, 0x6c, 0xc0, 0xe1, 0x5e, 0xba, 0x8f, 0x70, 0xf1, 0xca, 0xc5, 0x97, 0x95, 0xf7, 0x4c,
+       0xdd, 0x6c, 0x8c, 0xbb, 0x4d, 0x68, 0x18, 0x59, 0xb3, 0x1b, 0x6f, 0x81, 0xe7, 0xd8, 0x44, 0xdc,
+       0x6e, 0x84, 0xce, 0x5b, 0x0c, 0x66, 0xef, 0xc4, 0x72, 0x00, 0xf2, 0x5a, 0xef, 0x82, 0x63, 0x18,
+       0xf7, 0xd3, 0xb8, 0x25, 0xc4, 0x91, 0x80, 0x04, 0x54, 0x61, 0x5b, 0xf5, 0xe2, 0xda, 0xfb, 0x1d,
+       0xd4, 0x19, 0x99, 0x18, 0xbd, 0x9a, 0x1e, 0x96, 0xe9, 0x1c, 0xd5, 0xd0, 0x06, 0xf5, 0x37, 0x91,
+       0x3b, 0x4d, 0xa5, 0x2a, 0xda, 0x3c, 0xcd, 0xa6, 0xda, 0x53, 0xb8, 0x4a, 0x1e, 0xb9, 0x51, 0xed,
+       0xc3, 0x47, 0xc6, 0xfa, 0xdc, 0x2e, 0xb3, 0xdd, 0x63, 0x65, 0xba, 0x17, 0xdb, 0x65, 0x8b, 0x63,
+       0x77, 0x31, 0x6d, 0xd9, 0xb7, 0x18, 0x33, 0x91, 0xa1, 0x1f, 0xed, 0x0d, 0x49, 0x7f, 0x29, 0xd6,
+       0xd4, 0xf6, 0x12, 0x0f, 0xb2, 0x0c, 0xc9, 0x0f, 0x61, 0xb1, 0x48, 0x58, 0x52, 0xac, 0x80, 0x92,
+       0xb4, 0x2d, 0x4c, 0xa8, 0x94, 0xf6, 0x99, 0xc8, 0xb7, 0x1a, 0x7f, 0x3a, 0x52, 0x49, 0x9f, 0x44,
+       0xff, 0x0d, 0x38, 0x27, 0x3f, 0xad, 0xf6, 0xa4, 0x8f, 0xd9, 0x4b, 0x30, 0x6f, 0xe0, 0xb8, 0x20,
+       0x94, 0x82, 0x4c, 0x96, 0xea, 0x27, 0x28, 0x61, 0x1a, 0x41, 0x6d, 0xd4, 0x30, 0x82, 0x07, 0xca,
+       0x30, 0x82, 0x05, 0xb2, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x4e, 0xa1, 0x31, 0xe7, 0xca,
+       0x50, 0xb8, 0x97, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0d,
+       0x05, 0x00, 0x30, 0x81, 0x84, 0x31, 0x38, 0x30, 0x36, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x2f,
+       0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x4b, 0x49, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e,
+       0x67, 0x73, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+       0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31,
+       0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20,
+       0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
+       0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
+       0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x0b, 0x30, 0x09,
+       0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30,
+       0x36, 0x32, 0x34, 0x32, 0x33, 0x33, 0x33, 0x33, 0x39, 0x5a, 0x17, 0x0d, 0x34, 0x33, 0x30, 0x36,
+       0x31, 0x37, 0x32, 0x33, 0x33, 0x33, 0x33, 0x39, 0x5a, 0x30, 0x81, 0x84, 0x31, 0x38, 0x30, 0x36,
+       0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x2f, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x4b, 0x49,
+       0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43,
+       0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
+       0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c,
+       0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
+       0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x13,
+       0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49,
+       0x6e, 0x63, 0x2e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
+       0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+       0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, 0x01,
+       0x00, 0xce, 0x15, 0xf7, 0x6f, 0xd8, 0x42, 0x0c, 0x6f, 0x45, 0xb4, 0x04, 0x59, 0x24, 0xcb, 0x70,
+       0x88, 0x84, 0x77, 0xa1, 0x91, 0x54, 0xf4, 0x87, 0x61, 0xb3, 0xd3, 0xfc, 0xbe, 0xb6, 0x05, 0x3c,
+       0xb9, 0xb7, 0x7d, 0x7c, 0xbc, 0x0b, 0xe8, 0x87, 0x07, 0xcf, 0x20, 0xbe, 0xaa, 0xeb, 0x24, 0xc5,
+       0xe4, 0x5c, 0xcd, 0xcb, 0x89, 0x9f, 0x7a, 0xea, 0xb4, 0x5d, 0x3b, 0x29, 0x6c, 0xba, 0x4d, 0x15,
+       0xfb, 0x59, 0xd0, 0x5a, 0xea, 0x41, 0x4e, 0x0d, 0x1d, 0xf7, 0x66, 0x77, 0xa2, 0x96, 0x56, 0xed,
+       0xd1, 0x16, 0x7b, 0xea, 0xf5, 0x60, 0xdf, 0x32, 0x9c, 0xa9, 0xfd, 0xbf, 0xb8, 0x34, 0x6f, 0x57,
+       0x17, 0xe6, 0x04, 0x37, 0x71, 0x07, 0xc0, 0xe9, 0x0f, 0x3c, 0xed, 0x4f, 0x31, 0x87, 0x05, 0xa4,
+       0xed, 0xab, 0xac, 0xd6, 0x50, 0x05, 0x5b, 0xca, 0xd3, 0xf9, 0xd6, 0xaa, 0xaa, 0x88, 0x57, 0x66,
+       0xf6, 0x6d, 0x8d, 0x4b, 0x71, 0x29, 0xd4, 0x3d, 0x1d, 0xbc, 0x82, 0x6e, 0x81, 0xe9, 0x19, 0xf5,
+       0xe1, 0x12, 0x9f, 0x47, 0xdb, 0x5c, 0xed, 0x88, 0xba, 0x51, 0xe7, 0x3a, 0xa0, 0x77, 0x2d, 0xe6,
+       0xcc, 0xb4, 0x34, 0xdf, 0xad, 0xbd, 0x7b, 0xf8, 0xa7, 0x79, 0x51, 0x2d, 0xe6, 0xc2, 0xee, 0xd2,
+       0x96, 0xfa, 0x60, 0x60, 0x32, 0x40, 0x41, 0x37, 0x12, 0xeb, 0x63, 0x99, 0x3d, 0xf3, 0x21, 0xbe,
+       0xdf, 0xa1, 0x77, 0xe6, 0x81, 0xa9, 0x99, 0x0c, 0x4b, 0x43, 0x0c, 0x05, 0x6a, 0x6b, 0x8f, 0x05,
+       0x02, 0xd9, 0x43, 0xab, 0x72, 0x76, 0xca, 0xa7, 0x75, 0x63, 0x85, 0xe3, 0xa5, 0x5c, 0xc0, 0xd6,
+       0xd4, 0x1c, 0xeb, 0xac, 0x2c, 0x9a, 0x15, 0x6b, 0x4e, 0x99, 0x74, 0x7d, 0xd2, 0x69, 0x9f, 0xa8,
+       0xf7, 0x65, 0xde, 0xeb, 0x36, 0x85, 0xd5, 0x7e, 0x4a, 0x7a, 0x8a, 0xeb, 0x7c, 0xcd, 0x43, 0x9e,
+       0x05, 0xdb, 0x34, 0xc3, 0x69, 0xbd, 0xc2, 0xe7, 0xfb, 0xa0, 0x43, 0xb3, 0xd7, 0x15, 0x28, 0x8a,
+       0x91, 0xce, 0xd7, 0xa7, 0xa4, 0xcc, 0xf4, 0x1b, 0x37, 0x33, 0x76, 0xc4, 0x58, 0xb9, 0x2d, 0x89,
+       0xe2, 0xb6, 0x2c, 0x56, 0x10, 0x96, 0xcc, 0xa6, 0x07, 0x79, 0x11, 0x7d, 0x26, 0xd2, 0x85, 0x22,
+       0x19, 0x20, 0xb7, 0xef, 0xc3, 0xd9, 0x4e, 0x18, 0xf3, 0xaa, 0x05, 0xce, 0x87, 0x99, 0xde, 0x76,
+       0x90, 0x08, 0x74, 0xac, 0x61, 0x31, 0xf8, 0x51, 0xa0, 0xc9, 0x70, 0xfc, 0xb9, 0x22, 0xfe, 0xd2,
+       0x0d, 0xc8, 0x49, 0x64, 0x00, 0xe4, 0xf1, 0x53, 0xfd, 0xa1, 0xe6, 0xff, 0x8e, 0xd6, 0xde, 0x9e,
+       0xcc, 0x3d, 0x37, 0x3a, 0x10, 0x62, 0x59, 0xb2, 0x34, 0x8a, 0x1d, 0xf7, 0x9e, 0xa0, 0xbb, 0xf4,
+       0x53, 0xd9, 0xb8, 0x18, 0x88, 0x12, 0x5c, 0x92, 0x0d, 0xc9, 0x94, 0x7f, 0x24, 0xb9, 0x9f, 0xda,
+       0x07, 0xb6, 0x79, 0x77, 0x09, 0xa3, 0x29, 0x3a, 0x70, 0x63, 0x3b, 0x22, 0x42, 0x14, 0xd0, 0xf9,
+       0x7b, 0x90, 0x52, 0x2b, 0x3f, 0x7f, 0xb7, 0x41, 0x20, 0x0d, 0x7e, 0x70, 0xd7, 0x88, 0x36, 0xa2,
+       0xe9, 0x81, 0x77, 0xf4, 0xb0, 0x15, 0x43, 0x9c, 0x5f, 0x4d, 0x3e, 0x4f, 0x83, 0x79, 0x06, 0x73,
+       0x7a, 0xe7, 0xcb, 0x79, 0x1d, 0xec, 0xa3, 0xce, 0x93, 0x5c, 0x68, 0xbf, 0x5a, 0xe6, 0x4c, 0x23,
+       0x86, 0x41, 0x7f, 0xb4, 0xfc, 0xd0, 0x2c, 0x1b, 0x64, 0x39, 0x64, 0xb7, 0xd2, 0x1d, 0xd0, 0x2d,
+       0x16, 0x77, 0xfe, 0x4d, 0xad, 0xf0, 0x4f, 0x38, 0xb3, 0xf9, 0x5a, 0xee, 0x0e, 0x1d, 0xb6, 0xf9,
+       0x3f, 0xba, 0x77, 0x5a, 0x20, 0xd2, 0x74, 0x1a, 0x4b, 0x5a, 0xaf, 0x62, 0xb5, 0xd3, 0xef, 0x37,
+       0x49, 0xfe, 0x1e, 0xcd, 0xb5, 0xba, 0xb5, 0xa6, 0x46, 0x7b, 0x38, 0x63, 0x62, 0x3c, 0x18, 0x7d,
+       0x57, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x02, 0x3c, 0x30, 0x82, 0x02, 0x38, 0x30, 0x1d,
+       0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x35, 0x07, 0x82, 0xfe, 0x0e, 0x8f, 0xf5,
+       0xa0, 0x7c, 0x2e, 0xf9, 0x65, 0x7b, 0xa8, 0x48, 0xe8, 0x8f, 0x61, 0xb6, 0x1c, 0x30, 0x0f, 0x06,
+       0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1f,
+       0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x35, 0x07, 0x82, 0xfe, 0x0e,
+       0x8f, 0xf5, 0xa0, 0x7c, 0x2e, 0xf9, 0x65, 0x7b, 0xa8, 0x48, 0xe8, 0x8f, 0x61, 0xb6, 0x1c, 0x30,
+       0x82, 0x01, 0xd3, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x82, 0x01, 0xca, 0x30, 0x82, 0x01, 0xc6,
+       0x30, 0x82, 0x01, 0xc2, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x05, 0x01, 0x30,
+       0x82, 0x01, 0xb3, 0x30, 0x82, 0x01, 0x78, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02,
+       0x02, 0x30, 0x82, 0x01, 0x6a, 0x1e, 0x82, 0x01, 0x66, 0x00, 0x52, 0x00, 0x65, 0x00, 0x6c, 0x00,
+       0x69, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x65, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x6e, 0x00,
+       0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x69, 0x00, 0x73, 0x00, 0x20, 0x00, 0x63, 0x00, 0x65, 0x00,
+       0x72, 0x00, 0x74, 0x00, 0x69, 0x00, 0x66, 0x00, 0x69, 0x00, 0x63, 0x00, 0x61, 0x00, 0x74, 0x00,
+       0x65, 0x00, 0x20, 0x00, 0x62, 0x00, 0x79, 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x79, 0x00,
+       0x20, 0x00, 0x70, 0x00, 0x61, 0x00, 0x72, 0x00, 0x74, 0x00, 0x79, 0x00, 0x20, 0x00, 0x61, 0x00,
+       0x73, 0x00, 0x73, 0x00, 0x75, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x73, 0x00, 0x20, 0x00, 0x61, 0x00,
+       0x63, 0x00, 0x63, 0x00, 0x65, 0x00, 0x70, 0x00, 0x74, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x63, 0x00,
+       0x65, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00,
+       0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x61, 0x00, 0x70, 0x00,
+       0x70, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x63, 0x00, 0x61, 0x00, 0x62, 0x00, 0x6c, 0x00, 0x65, 0x00,
+       0x20, 0x00, 0x73, 0x00, 0x74, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x61, 0x00, 0x72, 0x00,
+       0x64, 0x00, 0x20, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x6d, 0x00, 0x73, 0x00, 0x20, 0x00,
+       0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x64, 0x00,
+       0x69, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x20, 0x00, 0x6f, 0x00,
+       0x66, 0x00, 0x20, 0x00, 0x75, 0x00, 0x73, 0x00, 0x65, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x63, 0x00,
+       0x65, 0x00, 0x72, 0x00, 0x74, 0x00, 0x69, 0x00, 0x66, 0x00, 0x69, 0x00, 0x63, 0x00, 0x61, 0x00,
+       0x74, 0x00, 0x65, 0x00, 0x20, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x63, 0x00,
+       0x79, 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20, 0x00, 0x63, 0x00, 0x65, 0x00,
+       0x72, 0x00, 0x74, 0x00, 0x69, 0x00, 0x66, 0x00, 0x69, 0x00, 0x63, 0x00, 0x61, 0x00, 0x74, 0x00,
+       0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x70, 0x00, 0x72, 0x00, 0x61, 0x00, 0x63, 0x00,
+       0x74, 0x00, 0x69, 0x00, 0x63, 0x00, 0x65, 0x00, 0x20, 0x00, 0x73, 0x00, 0x74, 0x00, 0x61, 0x00,
+       0x74, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x73, 0x00, 0x2e, 0x30,
+       0x35, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x29, 0x68, 0x74, 0x74,
+       0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
+       0x6d, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x61, 0x75, 0x74,
+       0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
+       0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+       0x01, 0x01, 0x0d, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x6f, 0x8a, 0xb7, 0x35, 0x73, 0x5a,
+       0xc5, 0x34, 0xf7, 0x8c, 0xf0, 0xd1, 0x4a, 0x17, 0x52, 0x1c, 0x70, 0xf0, 0xe0, 0x53, 0xb4, 0x16,
+       0xde, 0x81, 0xda, 0x2a, 0xa4, 0xf9, 0x5b, 0x0e, 0xa6, 0x17, 0x86, 0x52, 0xc6, 0x70, 0x73, 0xf3,
+       0x3f, 0x1c, 0x87, 0x94, 0xdd, 0xfe, 0x02, 0x0b, 0x85, 0xc9, 0xb9, 0xcf, 0x15, 0x91, 0x05, 0x2e,
+       0x7e, 0xeb, 0xe6, 0xce, 0x0e, 0x4e, 0xd1, 0xf7, 0xe2, 0xd7, 0xf4, 0x60, 0xd2, 0xfc, 0x1d, 0xbf,
+       0xad, 0x61, 0x28, 0xf8, 0x53, 0x31, 0xb3, 0x92, 0xef, 0xa4, 0x05, 0x34, 0x97, 0x57, 0x97, 0x56,
+       0x3b, 0x12, 0x20, 0x2d, 0x88, 0x76, 0x81, 0x0e, 0x77, 0x85, 0xf1, 0x37, 0xc6, 0x19, 0x8b, 0x23,
+       0xc2, 0x42, 0x55, 0x40, 0xc9, 0x91, 0x5c, 0x78, 0xc5, 0xe6, 0x77, 0xfe, 0x72, 0x5f, 0xb2, 0x2c,
+       0x00, 0xf2, 0xe6, 0x8c, 0xcc, 0x02, 0x49, 0xd9, 0x78, 0x20, 0xae, 0xbd, 0x75, 0x61, 0x6a, 0xaa,
+       0xc5, 0x71, 0x3e, 0x5d, 0x02, 0xdf, 0xd2, 0x91, 0x5c, 0x0a, 0x85, 0xc9, 0x59, 0x7d, 0x4e, 0x89,
+       0x21, 0x59, 0x59, 0xe3, 0xc7, 0xdc, 0xff, 0x1e, 0x62, 0x1e, 0xb9, 0x62, 0x2c, 0x34, 0x49, 0x15,
+       0xd9, 0xdf, 0x47, 0x99, 0x39, 0xcc, 0x1a, 0x01, 0xc0, 0xda, 0x48, 0x44, 0xd4, 0x8b, 0xd3, 0x17,
+       0x7e, 0x39, 0xf9, 0x00, 0xe1, 0x2a, 0x46, 0xaa, 0x14, 0x22, 0xa1, 0x38, 0x09, 0x0b, 0xb7, 0x0c,
+       0x88, 0xa5, 0x73, 0xfd, 0xc4, 0x6b, 0xee, 0x07, 0xb4, 0x1b, 0xb3, 0x4a, 0xab, 0xae, 0xf6, 0xe7,
+       0x04, 0x61, 0x4b, 0x34, 0x7a, 0xe4, 0xff, 0xf9, 0x30, 0x28, 0x61, 0x92, 0x52, 0x58, 0x10, 0x15,
+       0x3a, 0x9f, 0x0a, 0xaf, 0x15, 0x29, 0x6c, 0x67, 0xc4, 0xb4, 0xcf, 0xe6, 0xf9, 0x46, 0x68, 0xe2,
+       0x2a, 0x97, 0x29, 0x16, 0xed, 0x1a, 0x9b, 0x9a, 0x45, 0x70, 0x3c, 0xf2, 0xdf, 0x29, 0x20, 0x9e,
+       0x33, 0x4b, 0x5b, 0x8d, 0xf6, 0x19, 0xec, 0x4b, 0xae, 0x1a, 0x2f, 0x53, 0x03, 0x9a, 0xfd, 0x68,
+       0x39, 0x58, 0xf7, 0x2e, 0x07, 0x9c, 0xf1, 0x3c, 0x1b, 0x47, 0x43, 0x19, 0x81, 0x0e, 0x0a, 0xbb,
+       0x84, 0xa0, 0xda, 0x87, 0xbc, 0x8a, 0x2a, 0xb7, 0x9c, 0xe1, 0xf9, 0xeb, 0x37, 0xb0, 0x11, 0x20,
+       0x7e, 0x4c, 0x11, 0x2e, 0x54, 0x30, 0xce, 0xaf, 0x63, 0xed, 0x6a, 0x63, 0x1f, 0x1e, 0x61, 0x62,
+       0x04, 0xf3, 0x3a, 0x5f, 0x26, 0x6c, 0x5c, 0xd7, 0xba, 0x4f, 0xf2, 0x61, 0x26, 0x29, 0x99, 0xea,
+       0x61, 0x84, 0x0d, 0x68, 0xa2, 0x5d, 0x9b, 0x5c, 0xe7, 0x86, 0x1d, 0xef, 0xf4, 0x6f, 0x3b, 0x6c,
+       0x67, 0xf0, 0x70, 0xe9, 0xc5, 0xdc, 0x0a, 0x9d, 0x0f, 0xdc, 0xcc, 0x0e, 0x7b, 0xf8, 0xc4, 0xee,
+       0x64, 0xe4, 0xd9, 0x3f, 0x14, 0xae, 0x8f, 0xc8, 0x18, 0x4d, 0xa1, 0xe4, 0x40, 0x2c, 0xe9, 0x13,
+       0xc6, 0xc1, 0xe0, 0xb9, 0x13, 0xbe, 0xd9, 0x93, 0x66, 0x56, 0x35, 0x5c, 0xc1, 0x38, 0x7d, 0xa1,
+       0xbb, 0x87, 0xa5, 0x90, 0x33, 0x4f, 0xea, 0xb6, 0x37, 0x19, 0x61, 0x81, 0x40, 0xba, 0xd7, 0x07,
+       0x69, 0x05, 0x15, 0x96, 0xe9, 0xde, 0x4f, 0x8a, 0x2b, 0x99, 0x5a, 0x17, 0x3f, 0x9f, 0xcf, 0x86,
+       0xf5, 0x37, 0x0a, 0xa1, 0x0e, 0x25, 0x65, 0x2d, 0x52, 0xce, 0x87, 0x10, 0x0f, 0x25, 0xc2, 0x1e,
+       0x0f, 0x71, 0x93, 0xb5, 0xc0, 0xb3, 0xb4, 0xd1, 0x65, 0xa8, 0xb4, 0xf6, 0xa5, 0x71, 0xad, 0x45,
+       0xdb, 0xdf, 0xec, 0xe3, 0x2a, 0x7e, 0x99, 0x96, 0x5a, 0x5d, 0x69, 0xfa, 0xdb, 0x13, 0x39, 0xb8,
+       0xf5, 0x58, 0xbb, 0x87, 0x69, 0x8d, 0x2c, 0x6d, 0x39, 0xff, 0x26, 0xce, 0x2c, 0xa8, 0x5a, 0x7e,
+       0x4b, 0x3f, 0xed, 0xac, 0x5f, 0xf0, 0xef, 0x48, 0xd3, 0xf8, 0x00, 0x00, 0x31, 0x82, 0x03, 0x28,
+       0x30, 0x82, 0x03, 0x24, 0x02, 0x01, 0x01, 0x30, 0x81, 0x91, 0x30, 0x81, 0x84, 0x31, 0x38, 0x30,
+       0x36, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x2f, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x4b,
+       0x49, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
+       0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
+       0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b,
+       0x0c, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+       0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31,
+       0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20,
+       0x49, 0x6e, 0x63, 0x2e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+       0x53, 0x02, 0x08, 0x04, 0x2e, 0x97, 0xbb, 0x62, 0x84, 0xd9, 0x1c, 0x30, 0x0d, 0x06, 0x09, 0x60,
+       0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0xa0, 0x69, 0x30, 0x18, 0x06, 0x09,
+       0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x03, 0x31, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48,
+       0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+       0x01, 0x09, 0x05, 0x31, 0x0f, 0x17, 0x0d, 0x31, 0x33, 0x30, 0x36, 0x32, 0x38, 0x31, 0x37, 0x35,
+       0x35, 0x32, 0x34, 0x5a, 0x30, 0x2f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09,
+       0x04, 0x31, 0x22, 0x04, 0x20, 0x7f, 0xe5, 0xca, 0xfa, 0x9e, 0x7f, 0xd9, 0x3b, 0xec, 0x98, 0x25,
+       0x4f, 0x65, 0x73, 0x30, 0x1f, 0x7a, 0xe3, 0x51, 0xd3, 0xa4, 0xa9, 0x18, 0x7e, 0xeb, 0x6f, 0xdb,
+       0x13, 0xcb, 0x2f, 0x82, 0x4b, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+       0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x02, 0x00, 0x5e, 0xc2, 0x3f, 0x3d, 0x74, 0x0e, 0x23, 0x44,
+       0xec, 0x4f, 0x51, 0x96, 0x08, 0x28, 0x05, 0xe1, 0x2e, 0xd6, 0xba, 0x3a, 0x51, 0xf4, 0x46, 0xff,
+       0x2c, 0x96, 0x4a, 0x05, 0xa0, 0xa1, 0x89, 0xc8, 0x8d, 0x28, 0xb8, 0x1d, 0xc2, 0xc7, 0xa3, 0x6e,
+       0x43, 0x9b, 0xa0, 0xe8, 0xcb, 0x3a, 0x5e, 0xa7, 0xa7, 0xe7, 0x34, 0x93, 0xc9, 0x31, 0xf7, 0xde,
+       0x92, 0x55, 0x95, 0x22, 0x96, 0xdf, 0xbb, 0x6e, 0xb3, 0xb1, 0x8c, 0x20, 0x9f, 0x6f, 0x20, 0x85,
+       0xae, 0x3a, 0x48, 0x69, 0xfe, 0x5d, 0xd9, 0xf0, 0xe9, 0xd1, 0x86, 0x74, 0xc8, 0x13, 0x58, 0x27,
+       0xc6, 0xb5, 0x00, 0x76, 0xa3, 0x75, 0x01, 0x53, 0xfe, 0x8f, 0x7d, 0xe4, 0x69, 0x51, 0x3b, 0x19,
+       0x4b, 0xef, 0x34, 0x6e, 0x33, 0xf1, 0x03, 0x4d, 0xfc, 0x08, 0xd9, 0xe3, 0x47, 0x19, 0x83, 0x83,
+       0xb9, 0xa1, 0x83, 0x14, 0x5a, 0x70, 0x4f, 0xf7, 0x72, 0x2c, 0x00, 0x04, 0xce, 0x3f, 0x5d, 0xf2,
+       0xd3, 0xd8, 0x03, 0x7d, 0xe6, 0xb7, 0xf3, 0xe5, 0x88, 0x44, 0x91, 0x3e, 0x2f, 0x15, 0x51, 0x36,
+       0xbd, 0x16, 0xcb, 0x96, 0xc0, 0xda, 0x33, 0xa5, 0x82, 0x07, 0xc0, 0x6f, 0x20, 0x81, 0x0a, 0x5a,
+       0x14, 0xc9, 0x35, 0xe3, 0xf7, 0x08, 0x7a, 0x10, 0x80, 0x66, 0x08, 0xa5, 0x88, 0x22, 0xf6, 0xab,
+       0x37, 0xbc, 0xc0, 0x75, 0x2c, 0xca, 0xed, 0x5b, 0x83, 0x0c, 0x4b, 0xed, 0x11, 0x05, 0xb1, 0xf9,
+       0x91, 0x2b, 0x2a, 0x3e, 0x0f, 0xa7, 0x1e, 0xfe, 0x68, 0xb9, 0x88, 0x02, 0x0b, 0x51, 0xf2, 0x38,
+       0x3c, 0xc1, 0xb7, 0x56, 0x57, 0x20, 0x7b, 0xcf, 0xfa, 0x19, 0x85, 0x1f, 0x64, 0x2f, 0x55, 0xb8,
+       0xde, 0x80, 0xee, 0x04, 0x99, 0xa9, 0x53, 0x42, 0x15, 0x27, 0x27, 0x22, 0x2e, 0xae, 0xee, 0x98,
+       0x17, 0x3e, 0xd6, 0xcf, 0xc7, 0x1c, 0x8c, 0x1a, 0xb9, 0x6a, 0x0c, 0x34, 0xe7, 0xb2, 0x4f, 0xa3,
+       0x25, 0xbc, 0xe6, 0x12, 0xae, 0x51, 0xe8, 0xa3, 0x25, 0x6f, 0xc7, 0x10, 0x3e, 0xcf, 0x74, 0x7c,
+       0x97, 0x4a, 0x4d, 0xaf, 0xa2, 0x60, 0x9c, 0x99, 0xc7, 0x2a, 0x17, 0x86, 0x13, 0x7b, 0xc6, 0xde,
+       0xf1, 0x72, 0xdd, 0x7d, 0x4a, 0x61, 0xce, 0x08, 0xb1, 0x04, 0x6e, 0xcf, 0xc0, 0x50, 0xfd, 0xe9,
+       0x80, 0x04, 0xed, 0xb9, 0xbf, 0xc6, 0xcd, 0xa1, 0xad, 0xe7, 0x34, 0x8f, 0x31, 0xb2, 0x6e, 0x25,
+       0xba, 0x54, 0x22, 0x23, 0x19, 0x06, 0xe6, 0xea, 0xe7, 0x06, 0x9f, 0x64, 0x44, 0x39, 0x71, 0xc1,
+       0xaa, 0xa6, 0xa4, 0xef, 0xaa, 0xdb, 0x6b, 0x9e, 0xce, 0x29, 0x97, 0x55, 0x2f, 0x06, 0x5c, 0x6c,
+       0x10, 0xe6, 0xa5, 0x8c, 0x30, 0xf6, 0x81, 0x65, 0xee, 0x74, 0xb3, 0x40, 0xaa, 0x3b, 0x70, 0xcb,
+       0x80, 0x50, 0x22, 0x01, 0x0d, 0x12, 0x11, 0x72, 0x6d, 0x10, 0x54, 0x6e, 0xa4, 0x9e, 0x5e, 0xcd,
+       0xcc, 0xa0, 0x30, 0xf8, 0x61, 0xab, 0x36, 0x4a, 0x3a, 0xf0, 0x5a, 0xe3, 0xf5, 0x38, 0x70, 0x05,
+       0xdd, 0x04, 0x2e, 0x2b, 0x3a, 0xf8, 0x9a, 0x39, 0x48, 0x5f, 0x3f, 0xc6, 0x60, 0xaf, 0x9e, 0xca,
+       0x47, 0xb9, 0xfa, 0xb0, 0x1e, 0x45, 0x56, 0x47, 0xe0, 0xf1, 0x00, 0x47, 0x60, 0xb0, 0xca, 0x06,
+       0xef, 0xe8, 0xe9, 0x3b, 0xcd, 0x61, 0x8f, 0xc3, 0x14, 0xbc, 0x61, 0x9b, 0x08, 0x4e, 0xf5, 0x4a,
+       0xf9, 0x9a, 0x35, 0x5f, 0x84, 0x97, 0x43, 0x24, 0x62, 0x60, 0xd2, 0xa7, 0xd7, 0xe6, 0x10, 0xe7,
+       0xf1, 0xe4, 0xd0, 0x96, 0x1f, 0x7c, 0x93, 0xbc, 0x3a, 0x28, 0x59, 0x10, 0x3e, 0x32, 0x71, 0xa4,
+       0x9f, 0xab, 0xf6, 0x30, 0x07, 0xca, 0x7e, 0xcd, 0x35, 0xdb, 0xc1, 0xa2, 0x99, 0x8e, 0x7f, 0x85,
+       0xba, 0x92, 0xf6, 0x76, 0x99, 0xa3, 0xbc, 0xaf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static const UInt8 kApplePKISettingsRootCACert[] = {
+       0x30, 0x82, 0x07, 0xca, 0x30, 0x82, 0x05, 0xb2, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x4e,
+       0xa1, 0x31, 0xe7, 0xca, 0x50, 0xb8, 0x97, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+       0x0d, 0x01, 0x01, 0x0d, 0x05, 0x00, 0x30, 0x81, 0x84, 0x31, 0x38, 0x30, 0x36, 0x06, 0x03, 0x55,
+       0x04, 0x03, 0x0c, 0x2f, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x4b, 0x49, 0x20, 0x53, 0x65,
+       0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74,
+       0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+       0x69, 0x74, 0x79, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x1d, 0x41, 0x70,
+       0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+       0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x13, 0x30, 0x11, 0x06,
+       0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+       0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x30, 0x1e, 0x17,
+       0x0d, 0x31, 0x33, 0x30, 0x36, 0x32, 0x34, 0x32, 0x33, 0x33, 0x33, 0x33, 0x39, 0x5a, 0x17, 0x0d,
+       0x34, 0x33, 0x30, 0x36, 0x31, 0x37, 0x32, 0x33, 0x33, 0x33, 0x33, 0x39, 0x5a, 0x30, 0x81, 0x84,
+       0x31, 0x38, 0x30, 0x36, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x2f, 0x41, 0x70, 0x70, 0x6c, 0x65,
+       0x20, 0x50, 0x4b, 0x49, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x52, 0x6f,
+       0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+       0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03,
+       0x55, 0x04, 0x0b, 0x0c, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
+       0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
+       0x74, 0x79, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70,
+       0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+       0x13, 0x02, 0x55, 0x53, 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+       0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a,
+       0x02, 0x82, 0x02, 0x01, 0x00, 0xce, 0x15, 0xf7, 0x6f, 0xd8, 0x42, 0x0c, 0x6f, 0x45, 0xb4, 0x04,
+       0x59, 0x24, 0xcb, 0x70, 0x88, 0x84, 0x77, 0xa1, 0x91, 0x54, 0xf4, 0x87, 0x61, 0xb3, 0xd3, 0xfc,
+       0xbe, 0xb6, 0x05, 0x3c, 0xb9, 0xb7, 0x7d, 0x7c, 0xbc, 0x0b, 0xe8, 0x87, 0x07, 0xcf, 0x20, 0xbe,
+       0xaa, 0xeb, 0x24, 0xc5, 0xe4, 0x5c, 0xcd, 0xcb, 0x89, 0x9f, 0x7a, 0xea, 0xb4, 0x5d, 0x3b, 0x29,
+       0x6c, 0xba, 0x4d, 0x15, 0xfb, 0x59, 0xd0, 0x5a, 0xea, 0x41, 0x4e, 0x0d, 0x1d, 0xf7, 0x66, 0x77,
+       0xa2, 0x96, 0x56, 0xed, 0xd1, 0x16, 0x7b, 0xea, 0xf5, 0x60, 0xdf, 0x32, 0x9c, 0xa9, 0xfd, 0xbf,
+       0xb8, 0x34, 0x6f, 0x57, 0x17, 0xe6, 0x04, 0x37, 0x71, 0x07, 0xc0, 0xe9, 0x0f, 0x3c, 0xed, 0x4f,
+       0x31, 0x87, 0x05, 0xa4, 0xed, 0xab, 0xac, 0xd6, 0x50, 0x05, 0x5b, 0xca, 0xd3, 0xf9, 0xd6, 0xaa,
+       0xaa, 0x88, 0x57, 0x66, 0xf6, 0x6d, 0x8d, 0x4b, 0x71, 0x29, 0xd4, 0x3d, 0x1d, 0xbc, 0x82, 0x6e,
+       0x81, 0xe9, 0x19, 0xf5, 0xe1, 0x12, 0x9f, 0x47, 0xdb, 0x5c, 0xed, 0x88, 0xba, 0x51, 0xe7, 0x3a,
+       0xa0, 0x77, 0x2d, 0xe6, 0xcc, 0xb4, 0x34, 0xdf, 0xad, 0xbd, 0x7b, 0xf8, 0xa7, 0x79, 0x51, 0x2d,
+       0xe6, 0xc2, 0xee, 0xd2, 0x96, 0xfa, 0x60, 0x60, 0x32, 0x40, 0x41, 0x37, 0x12, 0xeb, 0x63, 0x99,
+       0x3d, 0xf3, 0x21, 0xbe, 0xdf, 0xa1, 0x77, 0xe6, 0x81, 0xa9, 0x99, 0x0c, 0x4b, 0x43, 0x0c, 0x05,
+       0x6a, 0x6b, 0x8f, 0x05, 0x02, 0xd9, 0x43, 0xab, 0x72, 0x76, 0xca, 0xa7, 0x75, 0x63, 0x85, 0xe3,
+       0xa5, 0x5c, 0xc0, 0xd6, 0xd4, 0x1c, 0xeb, 0xac, 0x2c, 0x9a, 0x15, 0x6b, 0x4e, 0x99, 0x74, 0x7d,
+       0xd2, 0x69, 0x9f, 0xa8, 0xf7, 0x65, 0xde, 0xeb, 0x36, 0x85, 0xd5, 0x7e, 0x4a, 0x7a, 0x8a, 0xeb,
+       0x7c, 0xcd, 0x43, 0x9e, 0x05, 0xdb, 0x34, 0xc3, 0x69, 0xbd, 0xc2, 0xe7, 0xfb, 0xa0, 0x43, 0xb3,
+       0xd7, 0x15, 0x28, 0x8a, 0x91, 0xce, 0xd7, 0xa7, 0xa4, 0xcc, 0xf4, 0x1b, 0x37, 0x33, 0x76, 0xc4,
+       0x58, 0xb9, 0x2d, 0x89, 0xe2, 0xb6, 0x2c, 0x56, 0x10, 0x96, 0xcc, 0xa6, 0x07, 0x79, 0x11, 0x7d,
+       0x26, 0xd2, 0x85, 0x22, 0x19, 0x20, 0xb7, 0xef, 0xc3, 0xd9, 0x4e, 0x18, 0xf3, 0xaa, 0x05, 0xce,
+       0x87, 0x99, 0xde, 0x76, 0x90, 0x08, 0x74, 0xac, 0x61, 0x31, 0xf8, 0x51, 0xa0, 0xc9, 0x70, 0xfc,
+       0xb9, 0x22, 0xfe, 0xd2, 0x0d, 0xc8, 0x49, 0x64, 0x00, 0xe4, 0xf1, 0x53, 0xfd, 0xa1, 0xe6, 0xff,
+       0x8e, 0xd6, 0xde, 0x9e, 0xcc, 0x3d, 0x37, 0x3a, 0x10, 0x62, 0x59, 0xb2, 0x34, 0x8a, 0x1d, 0xf7,
+       0x9e, 0xa0, 0xbb, 0xf4, 0x53, 0xd9, 0xb8, 0x18, 0x88, 0x12, 0x5c, 0x92, 0x0d, 0xc9, 0x94, 0x7f,
+       0x24, 0xb9, 0x9f, 0xda, 0x07, 0xb6, 0x79, 0x77, 0x09, 0xa3, 0x29, 0x3a, 0x70, 0x63, 0x3b, 0x22,
+       0x42, 0x14, 0xd0, 0xf9, 0x7b, 0x90, 0x52, 0x2b, 0x3f, 0x7f, 0xb7, 0x41, 0x20, 0x0d, 0x7e, 0x70,
+       0xd7, 0x88, 0x36, 0xa2, 0xe9, 0x81, 0x77, 0xf4, 0xb0, 0x15, 0x43, 0x9c, 0x5f, 0x4d, 0x3e, 0x4f,
+       0x83, 0x79, 0x06, 0x73, 0x7a, 0xe7, 0xcb, 0x79, 0x1d, 0xec, 0xa3, 0xce, 0x93, 0x5c, 0x68, 0xbf,
+       0x5a, 0xe6, 0x4c, 0x23, 0x86, 0x41, 0x7f, 0xb4, 0xfc, 0xd0, 0x2c, 0x1b, 0x64, 0x39, 0x64, 0xb7,
+       0xd2, 0x1d, 0xd0, 0x2d, 0x16, 0x77, 0xfe, 0x4d, 0xad, 0xf0, 0x4f, 0x38, 0xb3, 0xf9, 0x5a, 0xee,
+       0x0e, 0x1d, 0xb6, 0xf9, 0x3f, 0xba, 0x77, 0x5a, 0x20, 0xd2, 0x74, 0x1a, 0x4b, 0x5a, 0xaf, 0x62,
+       0xb5, 0xd3, 0xef, 0x37, 0x49, 0xfe, 0x1e, 0xcd, 0xb5, 0xba, 0xb5, 0xa6, 0x46, 0x7b, 0x38, 0x63,
+       0x62, 0x3c, 0x18, 0x7d, 0x57, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x02, 0x3c, 0x30, 0x82,
+       0x02, 0x38, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x35, 0x07, 0x82,
+       0xfe, 0x0e, 0x8f, 0xf5, 0xa0, 0x7c, 0x2e, 0xf9, 0x65, 0x7b, 0xa8, 0x48, 0xe8, 0x8f, 0x61, 0xb6,
+       0x1c, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01,
+       0x01, 0xff, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x35,
+       0x07, 0x82, 0xfe, 0x0e, 0x8f, 0xf5, 0xa0, 0x7c, 0x2e, 0xf9, 0x65, 0x7b, 0xa8, 0x48, 0xe8, 0x8f,
+       0x61, 0xb6, 0x1c, 0x30, 0x82, 0x01, 0xd3, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x82, 0x01, 0xca,
+       0x30, 0x82, 0x01, 0xc6, 0x30, 0x82, 0x01, 0xc2, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63,
+       0x64, 0x05, 0x01, 0x30, 0x82, 0x01, 0xb3, 0x30, 0x82, 0x01, 0x78, 0x06, 0x08, 0x2b, 0x06, 0x01,
+       0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x82, 0x01, 0x6a, 0x1e, 0x82, 0x01, 0x66, 0x00, 0x52, 0x00,
+       0x65, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x65, 0x00, 0x20, 0x00,
+       0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x69, 0x00, 0x73, 0x00, 0x20, 0x00,
+       0x63, 0x00, 0x65, 0x00, 0x72, 0x00, 0x74, 0x00, 0x69, 0x00, 0x66, 0x00, 0x69, 0x00, 0x63, 0x00,
+       0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x20, 0x00, 0x62, 0x00, 0x79, 0x00, 0x20, 0x00, 0x61, 0x00,
+       0x6e, 0x00, 0x79, 0x00, 0x20, 0x00, 0x70, 0x00, 0x61, 0x00, 0x72, 0x00, 0x74, 0x00, 0x79, 0x00,
+       0x20, 0x00, 0x61, 0x00, 0x73, 0x00, 0x73, 0x00, 0x75, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x73, 0x00,
+       0x20, 0x00, 0x61, 0x00, 0x63, 0x00, 0x63, 0x00, 0x65, 0x00, 0x70, 0x00, 0x74, 0x00, 0x61, 0x00,
+       0x6e, 0x00, 0x63, 0x00, 0x65, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x74, 0x00,
+       0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x20, 0x00,
+       0x61, 0x00, 0x70, 0x00, 0x70, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x63, 0x00, 0x61, 0x00, 0x62, 0x00,
+       0x6c, 0x00, 0x65, 0x00, 0x20, 0x00, 0x73, 0x00, 0x74, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00,
+       0x61, 0x00, 0x72, 0x00, 0x64, 0x00, 0x20, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x6d, 0x00,
+       0x73, 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20, 0x00, 0x63, 0x00, 0x6f, 0x00,
+       0x6e, 0x00, 0x64, 0x00, 0x69, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x73, 0x00,
+       0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x75, 0x00, 0x73, 0x00, 0x65, 0x00, 0x2c, 0x00,
+       0x20, 0x00, 0x63, 0x00, 0x65, 0x00, 0x72, 0x00, 0x74, 0x00, 0x69, 0x00, 0x66, 0x00, 0x69, 0x00,
+       0x63, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x20, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x6c, 0x00,
+       0x69, 0x00, 0x63, 0x00, 0x79, 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20, 0x00,
+       0x63, 0x00, 0x65, 0x00, 0x72, 0x00, 0x74, 0x00, 0x69, 0x00, 0x66, 0x00, 0x69, 0x00, 0x63, 0x00,
+       0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x70, 0x00, 0x72, 0x00,
+       0x61, 0x00, 0x63, 0x00, 0x74, 0x00, 0x69, 0x00, 0x63, 0x00, 0x65, 0x00, 0x20, 0x00, 0x73, 0x00,
+       0x74, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00,
+       0x73, 0x00, 0x2e, 0x30, 0x35, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16,
+       0x29, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c,
+       0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+       0x65, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
+       0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+       0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0d, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x6f, 0x8a,
+       0xb7, 0x35, 0x73, 0x5a, 0xc5, 0x34, 0xf7, 0x8c, 0xf0, 0xd1, 0x4a, 0x17, 0x52, 0x1c, 0x70, 0xf0,
+       0xe0, 0x53, 0xb4, 0x16, 0xde, 0x81, 0xda, 0x2a, 0xa4, 0xf9, 0x5b, 0x0e, 0xa6, 0x17, 0x86, 0x52,
+       0xc6, 0x70, 0x73, 0xf3, 0x3f, 0x1c, 0x87, 0x94, 0xdd, 0xfe, 0x02, 0x0b, 0x85, 0xc9, 0xb9, 0xcf,
+       0x15, 0x91, 0x05, 0x2e, 0x7e, 0xeb, 0xe6, 0xce, 0x0e, 0x4e, 0xd1, 0xf7, 0xe2, 0xd7, 0xf4, 0x60,
+       0xd2, 0xfc, 0x1d, 0xbf, 0xad, 0x61, 0x28, 0xf8, 0x53, 0x31, 0xb3, 0x92, 0xef, 0xa4, 0x05, 0x34,
+       0x97, 0x57, 0x97, 0x56, 0x3b, 0x12, 0x20, 0x2d, 0x88, 0x76, 0x81, 0x0e, 0x77, 0x85, 0xf1, 0x37,
+       0xc6, 0x19, 0x8b, 0x23, 0xc2, 0x42, 0x55, 0x40, 0xc9, 0x91, 0x5c, 0x78, 0xc5, 0xe6, 0x77, 0xfe,
+       0x72, 0x5f, 0xb2, 0x2c, 0x00, 0xf2, 0xe6, 0x8c, 0xcc, 0x02, 0x49, 0xd9, 0x78, 0x20, 0xae, 0xbd,
+       0x75, 0x61, 0x6a, 0xaa, 0xc5, 0x71, 0x3e, 0x5d, 0x02, 0xdf, 0xd2, 0x91, 0x5c, 0x0a, 0x85, 0xc9,
+       0x59, 0x7d, 0x4e, 0x89, 0x21, 0x59, 0x59, 0xe3, 0xc7, 0xdc, 0xff, 0x1e, 0x62, 0x1e, 0xb9, 0x62,
+       0x2c, 0x34, 0x49, 0x15, 0xd9, 0xdf, 0x47, 0x99, 0x39, 0xcc, 0x1a, 0x01, 0xc0, 0xda, 0x48, 0x44,
+       0xd4, 0x8b, 0xd3, 0x17, 0x7e, 0x39, 0xf9, 0x00, 0xe1, 0x2a, 0x46, 0xaa, 0x14, 0x22, 0xa1, 0x38,
+       0x09, 0x0b, 0xb7, 0x0c, 0x88, 0xa5, 0x73, 0xfd, 0xc4, 0x6b, 0xee, 0x07, 0xb4, 0x1b, 0xb3, 0x4a,
+       0xab, 0xae, 0xf6, 0xe7, 0x04, 0x61, 0x4b, 0x34, 0x7a, 0xe4, 0xff, 0xf9, 0x30, 0x28, 0x61, 0x92,
+       0x52, 0x58, 0x10, 0x15, 0x3a, 0x9f, 0x0a, 0xaf, 0x15, 0x29, 0x6c, 0x67, 0xc4, 0xb4, 0xcf, 0xe6,
+       0xf9, 0x46, 0x68, 0xe2, 0x2a, 0x97, 0x29, 0x16, 0xed, 0x1a, 0x9b, 0x9a, 0x45, 0x70, 0x3c, 0xf2,
+       0xdf, 0x29, 0x20, 0x9e, 0x33, 0x4b, 0x5b, 0x8d, 0xf6, 0x19, 0xec, 0x4b, 0xae, 0x1a, 0x2f, 0x53,
+       0x03, 0x9a, 0xfd, 0x68, 0x39, 0x58, 0xf7, 0x2e, 0x07, 0x9c, 0xf1, 0x3c, 0x1b, 0x47, 0x43, 0x19,
+       0x81, 0x0e, 0x0a, 0xbb, 0x84, 0xa0, 0xda, 0x87, 0xbc, 0x8a, 0x2a, 0xb7, 0x9c, 0xe1, 0xf9, 0xeb,
+       0x37, 0xb0, 0x11, 0x20, 0x7e, 0x4c, 0x11, 0x2e, 0x54, 0x30, 0xce, 0xaf, 0x63, 0xed, 0x6a, 0x63,
+       0x1f, 0x1e, 0x61, 0x62, 0x04, 0xf3, 0x3a, 0x5f, 0x26, 0x6c, 0x5c, 0xd7, 0xba, 0x4f, 0xf2, 0x61,
+       0x26, 0x29, 0x99, 0xea, 0x61, 0x84, 0x0d, 0x68, 0xa2, 0x5d, 0x9b, 0x5c, 0xe7, 0x86, 0x1d, 0xef,
+       0xf4, 0x6f, 0x3b, 0x6c, 0x67, 0xf0, 0x70, 0xe9, 0xc5, 0xdc, 0x0a, 0x9d, 0x0f, 0xdc, 0xcc, 0x0e,
+       0x7b, 0xf8, 0xc4, 0xee, 0x64, 0xe4, 0xd9, 0x3f, 0x14, 0xae, 0x8f, 0xc8, 0x18, 0x4d, 0xa1, 0xe4,
+       0x40, 0x2c, 0xe9, 0x13, 0xc6, 0xc1, 0xe0, 0xb9, 0x13, 0xbe, 0xd9, 0x93, 0x66, 0x56, 0x35, 0x5c,
+       0xc1, 0x38, 0x7d, 0xa1, 0xbb, 0x87, 0xa5, 0x90, 0x33, 0x4f, 0xea, 0xb6, 0x37, 0x19, 0x61, 0x81,
+       0x40, 0xba, 0xd7, 0x07, 0x69, 0x05, 0x15, 0x96, 0xe9, 0xde, 0x4f, 0x8a, 0x2b, 0x99, 0x5a, 0x17,
+       0x3f, 0x9f, 0xcf, 0x86, 0xf5, 0x37, 0x0a, 0xa1, 0x0e, 0x25, 0x65, 0x2d, 0x52, 0xce, 0x87, 0x10,
+       0x0f, 0x25, 0xc2, 0x1e, 0x0f, 0x71, 0x93, 0xb5, 0xc0, 0xb3, 0xb4, 0xd1, 0x65, 0xa8, 0xb4, 0xf6,
+       0xa5, 0x71, 0xad, 0x45, 0xdb, 0xdf, 0xec, 0xe3, 0x2a, 0x7e, 0x99, 0x96, 0x5a, 0x5d, 0x69, 0xfa,
+       0xdb, 0x13, 0x39, 0xb8, 0xf5, 0x58, 0xbb, 0x87, 0x69, 0x8d, 0x2c, 0x6d, 0x39, 0xff, 0x26, 0xce,
+       0x2c, 0xa8, 0x5a, 0x7e, 0x4b, 0x3f, 0xed, 0xac, 0x5f, 0xf0, 0xef, 0x48, 0xd3, 0xf8      
+};
+
+static const UInt8 kBasePList[] = {
+       0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xd1, 0x01, 0x02, 0x53, 0x66, 0x6f, 0x6f, 0x53,
+       0x62, 0x61, 0x72, 0x08, 0x0b, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x13
+};
+
+static const UInt8 kBaseManifestData[] = {
+       0x3c, 0x3f, 0x78, 0x6d, 0x6c, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x31,
+       0x2e, 0x30, 0x22, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3d, 0x22, 0x55, 0x54,
+       0x46, 0x2d, 0x38, 0x22, 0x3f, 0x3e, 0x0a, 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45,
+       0x20, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x22, 0x2d,
+       0x2f, 0x2f, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2f, 0x2f, 0x44, 0x54, 0x44, 0x20, 0x50, 0x4c, 0x49,
+       0x53, 0x54, 0x20, 0x31, 0x2e, 0x30, 0x2f, 0x2f, 0x45, 0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74,
+       0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
+       0x6d, 0x2f, 0x44, 0x54, 0x44, 0x73, 0x2f, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x4c,
+       0x69, 0x73, 0x74, 0x2d, 0x31, 0x2e, 0x30, 0x2e, 0x64, 0x74, 0x64, 0x22, 0x3e, 0x0a, 0x3c, 0x70,
+       0x6c, 0x69, 0x73, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x31, 0x2e,
+       0x30, 0x22, 0x3e, 0x0a, 0x3c, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x3c, 0x6b, 0x65, 0x79,
+       0x3e, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x45, 0x53, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+       0x61, 0x74, 0x65, 0x73, 0x2e, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e,
+       0x0a, 0x09, 0x3c, 0x64, 0x61, 0x74, 0x61, 0x3e, 0x0a, 0x09, 0x6c, 0x45, 0x66, 0x55, 0x58, 0x61,
+       0x39, 0x71, 0x54, 0x37, 0x72, 0x45, 0x36, 0x47, 0x73, 0x51, 0x4d, 0x69, 0x6f, 0x33, 0x6b, 0x44,
+       0x78, 0x61, 0x57, 0x35, 0x38, 0x7a, 0x53, 0x46, 0x6e, 0x54, 0x48, 0x66, 0x56, 0x58, 0x6b, 0x4e,
+       0x36, 0x7a, 0x57, 0x2f, 0x59, 0x3d, 0x0a, 0x09, 0x3c, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x3e, 0x0a,
+       0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69,
+       0x6f, 0x6e, 0x2e, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09,
+       0x3c, 0x64, 0x61, 0x74, 0x61, 0x3e, 0x0a, 0x09, 0x62, 0x4d, 0x73, 0x48, 0x77, 0x57, 0x68, 0x76,
+       0x2b, 0x61, 0x4d, 0x4d, 0x45, 0x74, 0x65, 0x34, 0x34, 0x6c, 0x45, 0x39, 0x34, 0x74, 0x56, 0x44,
+       0x36, 0x37, 0x56, 0x74, 0x67, 0x47, 0x32, 0x4d, 0x79, 0x68, 0x66, 0x56, 0x4d, 0x52, 0x70, 0x6c,
+       0x53, 0x42, 0x55, 0x3d, 0x0a, 0x09, 0x3c, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x3e, 0x0a, 0x09, 0x3c,
+       0x6b, 0x65, 0x79, 0x3e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x2e, 0x70, 0x6c, 0x69, 0x73,
+       0x74, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x3c, 0x64, 0x61, 0x74, 0x61, 0x3e, 0x0a,
+       0x09, 0x43, 0x49, 0x6b, 0x2f, 0x35, 0x34, 0x50, 0x66, 0x42, 0x32, 0x47, 0x76, 0x5a, 0x56, 0x68,
+       0x6d, 0x7a, 0x6e, 0x53, 0x31, 0x52, 0x6c, 0x62, 0x43, 0x41, 0x7a, 0x56, 0x4b, 0x31, 0x49, 0x69,
+       0x6e, 0x4d, 0x6d, 0x37, 0x64, 0x79, 0x37, 0x6d, 0x31, 0x49, 0x57, 0x77, 0x3d, 0x0a, 0x09, 0x3c,
+       0x2f, 0x64, 0x61, 0x74, 0x61, 0x3e, 0x0a, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x45, 0x56, 0x52,
+       0x6f, 0x6f, 0x74, 0x73, 0x2e, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e,
+       0x0a, 0x09, 0x3c, 0x64, 0x61, 0x74, 0x61, 0x3e, 0x0a, 0x09, 0x51, 0x52, 0x45, 0x45, 0x63, 0x63,
+       0x75, 0x62, 0x2b, 0x36, 0x2f, 0x50, 0x62, 0x78, 0x33, 0x75, 0x6a, 0x68, 0x51, 0x38, 0x48, 0x54,
+       0x6c, 0x6b, 0x61, 0x4d, 0x68, 0x49, 0x73, 0x65, 0x36, 0x4b, 0x30, 0x51, 0x56, 0x69, 0x51, 0x45,
+       0x39, 0x35, 0x49, 0x6a, 0x41, 0x3d, 0x0a, 0x09, 0x3c, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x3e, 0x0a,
+       0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x47, 0x72, 0x61, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x64,
+       0x4b, 0x65, 0x79, 0x73, 0x2e, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e,
+       0x0a, 0x09, 0x3c, 0x64, 0x61, 0x74, 0x61, 0x3e, 0x0a, 0x09, 0x70, 0x51, 0x71, 0x4a, 0x4e, 0x2f,
+       0x43, 0x6f, 0x68, 0x79, 0x76, 0x4d, 0x4d, 0x38, 0x46, 0x61, 0x35, 0x74, 0x4d, 0x42, 0x51, 0x34,
+       0x4e, 0x51, 0x6a, 0x55, 0x6d, 0x45, 0x6c, 0x69, 0x4b, 0x76, 0x50, 0x69, 0x59, 0x51, 0x65, 0x49,
+       0x6f, 0x36, 0x44, 0x48, 0x67, 0x3d, 0x0a, 0x09, 0x3c, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x3e, 0x0a,
+       0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4e, 0x75, 0x6d,
+       0x62, 0x65, 0x72, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x3c, 0x69, 0x6e, 0x74, 0x65,
+       0x67, 0x65, 0x72, 0x3e, 0x32, 0x30, 0x31, 0x33, 0x30, 0x36, 0x32, 0x37, 0x30, 0x30, 0x3c, 0x2f,
+       0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x3e, 0x0a, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63,
+       0x65, 0x72, 0x74, 0x73, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x3c, 0x2f,
+       0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x3c, 0x64, 0x61, 0x74, 0x61, 0x3e, 0x0a, 0x09, 0x70, 0x6b,
+       0x77, 0x5a, 0x30, 0x72, 0x6a, 0x6b, 0x76, 0x31, 0x6d, 0x61, 0x61, 0x4f, 0x55, 0x30, 0x43, 0x4d,
+       0x4e, 0x68, 0x6b, 0x66, 0x6b, 0x47, 0x38, 0x52, 0x59, 0x43, 0x48, 0x50, 0x32, 0x76, 0x52, 0x76,
+       0x75, 0x74, 0x78, 0x37, 0x52, 0x58, 0x48, 0x56, 0x51, 0x3d, 0x0a, 0x09, 0x3c, 0x2f, 0x64, 0x61,
+       0x74, 0x61, 0x3e, 0x0a, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x65, 0x72, 0x74, 0x73, 0x54,
+       0x61, 0x62, 0x6c, 0x65, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a,
+       0x09, 0x3c, 0x64, 0x61, 0x74, 0x61, 0x3e, 0x0a, 0x09, 0x4c, 0x71, 0x4e, 0x41, 0x52, 0x47, 0x44,
+       0x62, 0x54, 0x31, 0x45, 0x38, 0x42, 0x69, 0x64, 0x4f, 0x41, 0x48, 0x73, 0x6c, 0x4e, 0x52, 0x4f,
+       0x61, 0x59, 0x63, 0x53, 0x6f, 0x43, 0x71, 0x72, 0x4e, 0x63, 0x4f, 0x64, 0x31, 0x66, 0x6b, 0x31,
+       0x53, 0x75, 0x79, 0x51, 0x3d, 0x0a, 0x09, 0x3c, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x3e, 0x0a, 0x3c,
+       0x2f, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x3c, 0x2f, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x3e, 0x0a
+};
+static void test_OTA_PKI()
+{
+       CFDataRef signed_plist_data = NULL;
+       isnt(signed_plist_data = CFDataCreate(kCFAllocatorDefault, kSignedPList, sizeof(kSignedPList)), 
+               NULL, "create CMS signed message from kSignedPList");
+               
+       SecPolicyRef policy = NULL;
+       SecTrustRef trustRef = NULL;
+       CFDataRef payload = NULL;
+       isnt(policy = SecPolicyCreateOTAPKISigner(), NULL, "create the OTAPKISigner policy");
+       ok_status(SecCMSVerifyCopyDataAndAttributes(signed_plist_data, NULL, policy, &trustRef, &payload, NULL));
+       isnt(payload, NULL, "payload from the CMS message (plist)");
+       isnt(trustRef, NULL, "trustRef from the CMS message (plist)");
+       
+       CFDataRef apple_pki_settings_root_certificate_authority_cert_data = NULL;
+       isnt(apple_pki_settings_root_certificate_authority_cert_data = CFDataCreate(kCFAllocatorDefault, kApplePKISettingsRootCACert, sizeof(kApplePKISettingsRootCACert)), 
+               NULL, "Get the Apple PKI Settings Root Certification Authority Cert Data");
+       
+       SecCertificateRef       apple_pki_settings_root_certificate_authority_cert = NULL;
+       isnt(apple_pki_settings_root_certificate_authority_cert = SecCertificateCreateWithData(kCFAllocatorDefault, apple_pki_settings_root_certificate_authority_cert_data),
+               NULL, "Get the Apple PKI Settings Root Certification Authority Cert");
+    
+       CFArrayRef anchors = CFArrayCreate(kCFAllocatorDefault, (const void **)&apple_pki_settings_root_certificate_authority_cert, 1, &kCFTypeArrayCallBacks);
+       CFReleaseSafe(apple_pki_settings_root_certificate_authority_cert);
+       apple_pki_settings_root_certificate_authority_cert = NULL;
+               
+       SecTrustSetAnchorCertificates(trustRef,  anchors);
+               
+       SecTrustResultType trust_result = kSecTrustResultRecoverableTrustFailure;
+    
+    ok_status(SecTrustEvaluate(trustRef, &trust_result), "Evaluate trust of the CMS message (plist)");
+    
+    is_status(trust_result, kSecTrustResultUnspecified, "trust is kSecTrustResultRecoverableTrustFailure (plist)");
+       
+       CFPropertyListFormat plist_format;
+       CFErrorRef error = NULL;
+       CFPropertyListRef propertyRef = NULL;
+       isnt(propertyRef = CFPropertyListCreateWithData(kCFAllocatorDefault, payload, 0, &plist_format, &error), 
+               NULL, "create Plist object from the payload");
+       is(error, NULL, "error returned from CFPropertyListCreateWithData (payload plist)");
+               
+       CFDataRef base_plist_data = NULL;
+       isnt(base_plist_data = CFDataCreate(kCFAllocatorDefault, kBasePList, sizeof(kBasePList)), 
+               NULL, "create base plist data object");
+               
+       CFPropertyListRef base_propertyRef = NULL;
+       isnt(base_propertyRef = CFPropertyListCreateWithData(kCFAllocatorDefault, base_plist_data, 0, &plist_format, &error), 
+               NULL, "create base Plist object from the payload");
+       is(error, NULL, "error returned from CFPropertyListCreateWithData (base plist)");
+               
+       ok(CFEqual(base_propertyRef, propertyRef));     
+       
+       CFReleaseSafe(signed_plist_data);
+       
+       CFReleaseSafe(trustRef);
+       CFReleaseSafe(payload);
+       CFReleaseSafe(propertyRef);
+       CFReleaseSafe(base_plist_data);
+       CFReleaseSafe(base_propertyRef);        
+       
+       // Now do this same test with a 'real' manifest file
+       CFDataRef signed_manifest_data = NULL;
+       isnt(signed_manifest_data = CFDataCreate(kCFAllocatorDefault, kSignedManifestData, sizeof(kSignedManifestData)), 
+               NULL, "create CMS signed message from kSignedManifestData");
+       
+       trustRef = NULL;
+       payload = NULL;
+       
+       ok_status(SecCMSVerifyCopyDataAndAttributes(signed_manifest_data, NULL, policy, &trustRef, &payload, NULL));
+    CFReleaseSafe(signed_manifest_data);
+       isnt(payload, NULL, "payload from the CMS message (manifest)");
+       isnt(trustRef, NULL, "trustRef from the CMS message (manifest)");
+       SecTrustSetAnchorCertificates(trustRef,  anchors);
+       trust_result = kSecTrustResultRecoverableTrustFailure;
+       
+       ok_status(SecTrustEvaluate(trustRef, &trust_result), "Evaluate trust of the CMS message (plist)");
+    
+    is_status(trust_result, kSecTrustResultUnspecified, "trust is kSecTrustResultRecoverableTrustFailure (plist)");
+
+       CFPropertyListRef manifestRef = NULL;
+               
+       isnt(manifestRef = CFPropertyListCreateWithData(kCFAllocatorDefault, payload, 0, &plist_format, &error), 
+               NULL, "create manifest plist object from the payload"); 
+       is(error, NULL, "error returned from CFPropertyListCreateWithData (manifest plist)");
+       
+       CFDataRef base_manifest_data = NULL;
+       isnt(base_manifest_data = CFDataCreate(kCFAllocatorDefault, kBaseManifestData, sizeof(kBaseManifestData)), 
+               NULL, "create base manifest data object");
+               
+       CFPropertyListRef base_manifestRef = NULL;
+       isnt(base_manifestRef = CFPropertyListCreateWithData(kCFAllocatorDefault, base_manifest_data, 0, &plist_format, &error), 
+               NULL, "create base manifest object from the payload");
+       is(error, NULL, "error returned from CFPropertyListCreateWithData (manifest plist)");
+       
+       ok(CFEqual(base_manifestRef, manifestRef));     
+               
+       CFReleaseSafe(policy);
+       CFReleaseSafe(trustRef);
+       CFReleaseSafe(payload);
+       CFReleaseSafe(manifestRef);
+       CFReleaseSafe(base_manifest_data);
+       CFReleaseSafe(base_manifestRef);        
+       
+}
+
+static void tests(void)
+{
+    test_OTA_PKI();
+}
+
+int si_74_OTA_PKI_Signer(int argc, char *const *argv)
+{
+       
+//#if defined(NO_SERVER) && NO_SERVER == 1
+       plan_tests(27);
+
+       tests();
+//#endif
+
+       return 0;
+}
+
+#endif
diff --git a/sec/Security/Regressions/secitem/si-75-AppleIDRecordSigning.c b/sec/Security/Regressions/secitem/si-75-AppleIDRecordSigning.c
new file mode 100644 (file)
index 0000000..a6c8809
--- /dev/null
@@ -0,0 +1,233 @@
+//
+//  si-75-AppleIDRecordSigning.c
+//  sec
+//
+//  Created by local on 7/31/13.
+//
+//
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecCertificateInternal.h>
+#include <Security/SecItem.h>
+#include <Security/SecItemPriv.h>
+#include <Security/SecIdentityPriv.h>
+#include <Security/SecIdentity.h>
+#include <Security/SecPolicy.h>
+#include <Security/SecPolicyPriv.h>
+#include <Security/SecPolicyInternal.h>
+#include <Security/SecCMS.h>
+#include <utilities/SecCFWrappers.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "Security_regressions.h"
+
+static const UInt8 kLeafCert[] = {
+       0x30, 0x82, 0x05, 0x11, 0x30, 0x82, 0x03, 0xf9, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x3d,
+       0x73, 0xc1, 0x2f, 0x55, 0xba, 0x4c, 0x53, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+       0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0x8a, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+       0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c,
+       0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06,
+       0x03, 0x55, 0x04, 0x0b, 0x0c, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74,
+       0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+       0x69, 0x74, 0x79, 0x31, 0x3e, 0x30, 0x3c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x35, 0x41, 0x70,
+       0x70, 0x6c, 0x65, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
+       0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x43, 0x65, 0x72, 0x74,
+       0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+       0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30, 0x37, 0x32, 0x39, 0x31, 0x39, 0x33,
+       0x36, 0x31, 0x38, 0x5a, 0x17, 0x0d, 0x31, 0x35, 0x30, 0x37, 0x32, 0x39, 0x31, 0x39, 0x33, 0x36,
+       0x31, 0x38, 0x5a, 0x30, 0x30, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x25,
+       0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x44, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74,
+       0x69, 0x6f, 0x6e, 0x20, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69,
+       0x6e, 0x67, 0x20, 0x30, 0x31, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+       0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01,
+       0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb1, 0x13, 0xc4, 0x56, 0xe4, 0x16, 0x44, 0x9e, 0xbd, 0x35,
+       0x6a, 0x2e, 0xce, 0x47, 0x03, 0x3c, 0x28, 0x25, 0xcd, 0x89, 0x90, 0xc8, 0xfe, 0xb5, 0x02, 0x1f,
+       0xc3, 0x20, 0x04, 0xf6, 0x34, 0x74, 0x1f, 0x2a, 0xd3, 0x67, 0xe5, 0x90, 0xb8, 0x43, 0xad, 0x1c,
+       0xf0, 0xa0, 0x8e, 0xd5, 0x63, 0xff, 0x7c, 0x60, 0x03, 0x5b, 0x18, 0x02, 0x01, 0x56, 0x69, 0xda,
+       0xff, 0x08, 0xdd, 0x56, 0x22, 0x38, 0x09, 0xd8, 0xe8, 0x1e, 0x2f, 0xda, 0x57, 0x93, 0x36, 0xa1,
+       0x4d, 0x24, 0x72, 0x4d, 0x3c, 0x89, 0xde, 0x66, 0x61, 0x4c, 0xe2, 0x42, 0x2f, 0x09, 0x7d, 0x43,
+       0x49, 0xe0, 0x8b, 0x25, 0x34, 0x89, 0x8b, 0x3b, 0x8d, 0xd5, 0xbd, 0x24, 0x81, 0xf8, 0xc5, 0x99,
+       0x3a, 0x36, 0xfc, 0xf2, 0x20, 0x7d, 0xc7, 0xcb, 0xf5, 0x29, 0x3c, 0xc4, 0xed, 0x2d, 0xa2, 0xca,
+       0xa2, 0x21, 0x4f, 0x0b, 0x4b, 0xf6, 0xb5, 0x6b, 0x45, 0xa0, 0x4a, 0xeb, 0x5f, 0x47, 0x1f, 0xb5,
+       0x4d, 0x44, 0x10, 0xc6, 0xc4, 0xa4, 0x5a, 0x97, 0x70, 0x26, 0x62, 0x27, 0xba, 0xcc, 0xdd, 0x42,
+       0x46, 0xd7, 0x78, 0x3d, 0xe8, 0xe3, 0x6f, 0x46, 0x0b, 0xe6, 0xa2, 0xe8, 0x01, 0x83, 0xfb, 0xe3,
+       0x8c, 0xba, 0x76, 0x86, 0x56, 0xa7, 0x85, 0xf9, 0x18, 0xcb, 0x86, 0xc1, 0x31, 0x0d, 0xee, 0x56,
+       0x98, 0x4c, 0x63, 0x05, 0x3d, 0xbc, 0xcd, 0x96, 0x83, 0x37, 0x74, 0x86, 0xa4, 0x73, 0x44, 0x4c,
+       0x9d, 0x4e, 0x5a, 0xe8, 0x9d, 0xdf, 0x3e, 0xfe, 0x00, 0x61, 0x45, 0xd8, 0xf5, 0x5c, 0x30, 0x82,
+       0x95, 0x5b, 0xdc, 0x92, 0x2d, 0x15, 0x29, 0x8c, 0x61, 0xec, 0xbc, 0x6b, 0x0a, 0xf0, 0xb6, 0x74,
+       0xf2, 0x64, 0xe6, 0xf1, 0xd4, 0x01, 0x8b, 0x2f, 0x80, 0xe8, 0x5b, 0x5d, 0xe7, 0xa7, 0xa1, 0x68,
+       0xc1, 0x6b, 0x1d, 0x5e, 0x1d, 0xb7, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0xd2, 0x30,
+       0x82, 0x01, 0xce, 0x30, 0x40, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
+       0x34, 0x30, 0x32, 0x30, 0x30, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86,
+       0x24, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x61, 0x70, 0x70,
+       0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x30, 0x34, 0x2d, 0x61, 0x61,
+       0x69, 0x63, 0x61, 0x30, 0x34, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
+       0x3b, 0xea, 0x41, 0x8f, 0x09, 0xf9, 0x35, 0xf8, 0xe3, 0x61, 0xcd, 0x8b, 0x40, 0xc7, 0x9f, 0x8d,
+       0x4a, 0x1e, 0x0c, 0x27, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30,
+       0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x31, 0xea, 0x76, 0xa9,
+       0x23, 0x74, 0xa5, 0xdf, 0xd4, 0xfd, 0xee, 0xa0, 0xc1, 0xa6, 0x9e, 0xc6, 0x11, 0x0e, 0x11, 0xec,
+       0x30, 0x82, 0x01, 0x1c, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x82, 0x01, 0x13, 0x30, 0x82, 0x01,
+       0x0f, 0x30, 0x82, 0x01, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x05, 0x01,
+       0x30, 0x81, 0xfd, 0x30, 0x81, 0xc3, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02,
+       0x30, 0x81, 0xb6, 0x0c, 0x81, 0xb3, 0x52, 0x65, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f,
+       0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
+       0x74, 0x65, 0x20, 0x62, 0x79, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x70, 0x61, 0x72, 0x74, 0x79, 0x20,
+       0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x73, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x61, 0x6e,
+       0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x61,
+       0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61,
+       0x72, 0x64, 0x20, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e,
+       0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x2c, 0x20,
+       0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x70, 0x6f, 0x6c, 0x69,
+       0x63, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
+       0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x20, 0x73, 0x74,
+       0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x30, 0x35, 0x06, 0x08, 0x2b, 0x06, 0x01,
+       0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x29, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77,
+       0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x65, 0x72, 0x74,
+       0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
+       0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80,
+       0x30, 0x0f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x06, 0x19, 0x04, 0x02, 0x05,
+       0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00,
+       0x03, 0x82, 0x01, 0x01, 0x00, 0x97, 0xda, 0x8f, 0xab, 0x57, 0xa2, 0xfb, 0x85, 0xa5, 0x64, 0xbb,
+       0xe9, 0xed, 0x6c, 0x13, 0x54, 0x3e, 0x3c, 0x00, 0xb5, 0xa4, 0xd2, 0x8a, 0xd9, 0xe6, 0xda, 0x9e,
+       0x2b, 0x49, 0xc4, 0x80, 0x09, 0xa9, 0x0e, 0xda, 0xf3, 0xb1, 0x16, 0xa7, 0xbb, 0x14, 0x4e, 0xdf,
+       0x95, 0xca, 0x3e, 0xc1, 0x2f, 0xcf, 0x0d, 0xa3, 0x0c, 0x5b, 0x36, 0x6f, 0x48, 0xe3, 0x44, 0x6e,
+       0x96, 0xb1, 0x1c, 0xfc, 0x71, 0x3f, 0x88, 0xb0, 0x07, 0x20, 0x62, 0x62, 0x3d, 0x96, 0x56, 0x84,
+       0xb2, 0x5e, 0xa6, 0x1b, 0x57, 0xca, 0x53, 0x75, 0xda, 0x11, 0x9c, 0xb4, 0x14, 0x57, 0x49, 0x07,
+       0x14, 0xa3, 0xda, 0xd5, 0xe4, 0x1e, 0xb6, 0x14, 0xd4, 0x67, 0x7a, 0x0a, 0xf3, 0xcc, 0xc1, 0x23,
+       0x5c, 0x53, 0x62, 0x61, 0x6a, 0x94, 0x37, 0xfb, 0x6b, 0x87, 0xcf, 0xc2, 0xa6, 0x13, 0xbc, 0x49,
+       0x42, 0x21, 0xde, 0x98, 0x83, 0x45, 0xf4, 0x9e, 0xc4, 0x67, 0x14, 0xc4, 0x4b, 0x26, 0xed, 0xf8,
+       0xb5, 0xd7, 0x22, 0xaa, 0x54, 0x93, 0x60, 0xf6, 0xaf, 0x23, 0xd0, 0x8e, 0xe8, 0xa0, 0x94, 0xfa,
+       0xf6, 0x96, 0x12, 0x14, 0x24, 0xe0, 0x46, 0xbb, 0xf4, 0xf2, 0x7b, 0xe1, 0x76, 0x84, 0xc0, 0x38,
+       0x72, 0x83, 0x35, 0x09, 0xc8, 0xb2, 0xe7, 0x5c, 0x00, 0xbe, 0xb2, 0x0e, 0x20, 0x33, 0x00, 0x4d,
+       0x09, 0xde, 0xdf, 0x1e, 0x09, 0xd0, 0xa5, 0xf8, 0x60, 0x05, 0x72, 0x26, 0x72, 0x2b, 0xc5, 0x05,
+       0xf7, 0xd0, 0xe7, 0xa8, 0xc7, 0x54, 0x77, 0x2a, 0x84, 0xe5, 0xf9, 0x4f, 0x83, 0x96, 0x67, 0x2d,
+       0x3d, 0x36, 0xf5, 0xba, 0x42, 0xa6, 0x21, 0x77, 0x87, 0x8e, 0xa4, 0xa6, 0xf3, 0xa8, 0x90, 0x4b,
+       0x27, 0x25, 0x8c, 0x78, 0x45, 0xd8, 0x95, 0x2c, 0x0e, 0x19, 0xef, 0xc9, 0x80, 0x7a, 0x97, 0xb6,
+       0x37, 0x1e, 0x31, 0x59, 0x3c                                
+};
+
+static const UInt8 kIntermediateCert[] = {
+       0x30, 0x82, 0x04, 0x17, 0x30, 0x82, 0x02, 0xff, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x1b,
+       0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
+       0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
+       0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49,
+       0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70,
+       0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+       0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x16, 0x30, 0x14, 0x06,
+       0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74,
+       0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x30, 0x35, 0x32, 0x36, 0x31, 0x39, 0x31,
+       0x36, 0x30, 0x39, 0x5a, 0x17, 0x0d, 0x31, 0x37, 0x30, 0x37, 0x32, 0x36, 0x31, 0x39, 0x31, 0x36,
+       0x30, 0x39, 0x5a, 0x30, 0x81, 0x8a, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+       0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70,
+       0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04,
+       0x0b, 0x0c, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+       0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
+       0x31, 0x3e, 0x30, 0x3c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x35, 0x41, 0x70, 0x70, 0x6c, 0x65,
+       0x20, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x6e, 0x74,
+       0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+       0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
+       0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+       0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
+       0x00, 0xe3, 0x5b, 0xb3, 0x27, 0x6a, 0x0c, 0xbf, 0x6e, 0xaa, 0x4c, 0xe7, 0xc5, 0x3f, 0x6f, 0x6d,
+       0x4c, 0xe6, 0xa2, 0x95, 0xd5, 0xeb, 0xd5, 0x02, 0xaf, 0x70, 0x74, 0x46, 0xb9, 0xd1, 0x8f, 0xac,
+       0x3b, 0xb7, 0xde, 0x0c, 0x84, 0xd0, 0x90, 0x5f, 0xff, 0xe7, 0x59, 0x43, 0xce, 0xba, 0xd5, 0xc6,
+       0xc5, 0xed, 0x4f, 0xfc, 0xbf, 0xc3, 0x97, 0x59, 0x39, 0xf9, 0x64, 0xe8, 0x0e, 0x4a, 0x9f, 0x9f,
+       0xf6, 0xec, 0x7a, 0x88, 0xea, 0xdf, 0xb6, 0xe7, 0x62, 0x01, 0x7f, 0x9a, 0x0f, 0xc5, 0x4a, 0x16,
+       0xeb, 0xac, 0xe6, 0x98, 0x5f, 0x42, 0x3e, 0x82, 0xcb, 0x1d, 0xb3, 0x6a, 0xef, 0x1b, 0xc2, 0x8b,
+       0xb6, 0x09, 0x99, 0xc9, 0xf0, 0x2c, 0x12, 0xd7, 0x2b, 0x88, 0xbe, 0x2a, 0xa8, 0xf6, 0x61, 0x3b,
+       0x89, 0xea, 0xbf, 0x7f, 0x69, 0x46, 0x02, 0xcc, 0x64, 0x3e, 0x24, 0xe9, 0x5f, 0x8e, 0xf4, 0xfb,
+       0xe2, 0x8a, 0xfe, 0x03, 0xfa, 0x29, 0x2c, 0xda, 0xc9, 0x94, 0x48, 0xd0, 0xde, 0xee, 0x2f, 0x88,
+       0x4c, 0xf7, 0x20, 0xb5, 0x6c, 0x22, 0xca, 0xe9, 0x86, 0xc5, 0x4b, 0x5d, 0xcf, 0x83, 0xaf, 0x4f,
+       0xc6, 0xb0, 0x0c, 0xb3, 0xeb, 0xd0, 0x99, 0x6d, 0xad, 0xf7, 0x26, 0x6f, 0x09, 0x2f, 0x87, 0xb8,
+       0xe2, 0xb4, 0x32, 0x51, 0x8d, 0xf6, 0xcc, 0x2f, 0x88, 0x97, 0xdc, 0xd7, 0x0c, 0x6b, 0x92, 0xca,
+       0xa7, 0x1e, 0xd2, 0xfa, 0x23, 0x3e, 0x81, 0xf6, 0x09, 0xa6, 0x89, 0x8a, 0x3d, 0x48, 0x09, 0x8d,
+       0x08, 0x0d, 0xb0, 0x5d, 0xba, 0x05, 0x59, 0xf1, 0x79, 0x05, 0xa4, 0x09, 0x5b, 0x66, 0xa6, 0xed,
+       0x8b, 0x93, 0xbc, 0xc7, 0x5d, 0x79, 0x37, 0xe1, 0x44, 0x35, 0x91, 0x8e, 0xd8, 0xd7, 0x0f, 0x95,
+       0x92, 0x67, 0x43, 0xac, 0x75, 0x2b, 0x12, 0x49, 0x23, 0x36, 0x11, 0x5d, 0xd3, 0xf2, 0x82, 0xb8,
+       0x13, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xae, 0x30, 0x81, 0xab, 0x30, 0x0e, 0x06, 0x03,
+       0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x0f, 0x06, 0x03,
+       0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06,
+       0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x31, 0xea, 0x76, 0xa9, 0x23, 0x74, 0xa5, 0xdf,
+       0xd4, 0xfd, 0xee, 0xa0, 0xc1, 0xa6, 0x9e, 0xc6, 0x11, 0x0e, 0x11, 0xec, 0x30, 0x1f, 0x06, 0x03,
+       0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76, 0x09,
+       0xfe, 0xf4, 0x6b, 0x8d, 0x2e, 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x36, 0x06,
+       0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2f, 0x30, 0x2d, 0x30, 0x2b, 0xa0, 0x29, 0xa0, 0x27, 0x86, 0x25,
+       0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65,
+       0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x63, 0x61, 0x2f, 0x72, 0x6f, 0x6f,
+       0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x10, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64,
+       0x06, 0x02, 0x03, 0x04, 0x02, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+       0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x8d, 0x65, 0x84, 0xd1, 0xff,
+       0x3b, 0x3d, 0x27, 0x62, 0x90, 0x15, 0xf6, 0x59, 0xce, 0x3b, 0xc9, 0xc2, 0xff, 0x9c, 0x45, 0x3c,
+       0x8f, 0xc6, 0xf9, 0x44, 0x87, 0xcb, 0xfd, 0xe0, 0x79, 0x36, 0x20, 0x2d, 0x1e, 0xf7, 0x2a, 0xca,
+       0x09, 0x4d, 0x28, 0xf4, 0xfe, 0xbf, 0x30, 0x13, 0xc1, 0x91, 0x76, 0x59, 0x19, 0x8a, 0xc0, 0x4c,
+       0x99, 0xef, 0x5a, 0xf5, 0xbd, 0x8e, 0x87, 0x93, 0x70, 0x3b, 0x9c, 0xcc, 0x16, 0x74, 0x49, 0x55,
+       0x65, 0x3a, 0xf5, 0x5b, 0x6a, 0xca, 0x17, 0x2b, 0xe7, 0x9d, 0x28, 0x93, 0x98, 0xa0, 0x67, 0x34,
+       0x1a, 0xe2, 0xe9, 0x96, 0x0d, 0x47, 0xef, 0xc8, 0x9c, 0x37, 0xe4, 0xd3, 0xda, 0xf5, 0xa1, 0xd8,
+       0x42, 0xeb, 0xbd, 0x51, 0x16, 0x03, 0x35, 0x94, 0x1d, 0x5a, 0x31, 0x42, 0x3d, 0x78, 0x81, 0xfe,
+       0x4f, 0xa2, 0xbf, 0x3a, 0xbc, 0x78, 0x09, 0xe4, 0xcb, 0x28, 0x6e, 0x66, 0x4f, 0xe9, 0x4f, 0xb7,
+       0xb5, 0xd2, 0xa2, 0x3d, 0x19, 0xb1, 0x23, 0x1d, 0x3f, 0x66, 0x93, 0xb2, 0x51, 0xc3, 0x00, 0x3b,
+       0x92, 0xaa, 0xe3, 0xfd, 0x2c, 0x17, 0x22, 0xd9, 0x40, 0x94, 0x28, 0x30, 0x08, 0x54, 0xf8, 0x29,
+       0x2a, 0xd5, 0xae, 0xed, 0x77, 0xc3, 0xd4, 0x80, 0x32, 0xa0, 0xc2, 0x67, 0xa3, 0x61, 0xd1, 0xb1,
+       0x67, 0x99, 0x5a, 0x05, 0xd7, 0xbb, 0x5d, 0x25, 0x55, 0xbc, 0x16, 0xfd, 0x0e, 0x4e, 0x86, 0x6a,
+       0x9e, 0x90, 0x9d, 0xc8, 0x34, 0x80, 0x01, 0xf4, 0x2b, 0x50, 0x52, 0xea, 0x46, 0x33, 0x20, 0x54,
+       0xb8, 0x7b, 0x23, 0xce, 0x4d, 0x45, 0x32, 0x2e, 0x66, 0x5b, 0x1d, 0x8c, 0xd9, 0x16, 0xca, 0x6c,
+       0xad, 0x83, 0xdd, 0x04, 0xcf, 0xb6, 0x51, 0x8d, 0xa3, 0xb6, 0xa1, 0x37, 0xa8, 0xa9, 0x8b, 0x94,
+       0xb6, 0xc4, 0xc0, 0x5a, 0x2e, 0xf8, 0xd4, 0xa3, 0x28, 0x9d, 0xaa,               
+
+       
+};
+
+static void tests(void)
+{
+    SecTrustResultType trustResult = kSecTrustResultProceed;
+       SecPolicyRef policy = NULL;
+       SecTrustRef trust = NULL;
+       CFArrayRef certs = NULL;
+       
+       CFDataRef appleid_record_signing_cert_data = NULL;
+       isnt(appleid_record_signing_cert_data = CFDataCreate(kCFAllocatorDefault, kLeafCert, sizeof(kLeafCert)), 
+               NULL, "Get the AppleID Record Signing Leaf Certificate Data");
+               
+       SecCertificateRef appleid_record_signing_cert = NULL;
+       isnt(appleid_record_signing_cert = SecCertificateCreateWithData(kCFAllocatorDefault, appleid_record_signing_cert_data),
+               NULL, "Get the AppleID Record Signing Leaf Certificate Data");
+               
+       CFDataRef appleid_intermediate_cert_data = NULL;
+       isnt(appleid_intermediate_cert_data = CFDataCreate(kCFAllocatorDefault, kIntermediateCert, sizeof(kIntermediateCert)), 
+               NULL, "Get the AppleID Intermediate Certificate Data");
+               
+       SecCertificateRef appleid_intermediate_cert = NULL;
+       isnt(appleid_intermediate_cert = SecCertificateCreateWithData(kCFAllocatorDefault, appleid_intermediate_cert_data),
+               NULL, "Get the AppleID Intermediate Certificate");
+               
+       SecCertificateRef certs_to_use[] = {appleid_record_signing_cert, appleid_intermediate_cert};
+               
+       certs = CFArrayCreate(NULL, (const void **)certs_to_use, 2, NULL);
+               
+       isnt(policy = SecPolicyCreateAppleIDValidationRecordSigningPolicy(),
+               NULL, "Create AppleID Record signing policy SecPolicyRef");
+                               
+       ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
+        "Create AppleID record signing leaf");
+
+       ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate escrow service trust for club 1");
+               
+       is_status(trustResult, kSecTrustResultUnspecified,
+               "Trust is kSecTrustResultUnspecified AppleID record signing leaf");
+               
+       CFReleaseSafe(trust);
+       CFReleaseSafe(policy);
+       CFReleaseSafe(certs);
+       CFReleaseSafe(appleid_record_signing_cert);
+}
+
+
+int si_75_AppleIDRecordSigning(int argc, char *const *argv)
+{
+               plan_tests(8);
+               tests();
+               return 0;
+}
diff --git a/sec/Security/Regressions/vmdh/vmdh-40.c b/sec/Security/Regressions/vmdh/vmdh-40.c
new file mode 100644 (file)
index 0000000..7fc741f
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2006-2007 Apple Inc. All Rights Reserved.
+ */
+
+#include <Security/vmdh.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "Security_regressions.h"
+
+static uint8_t dh512_p[] = {
+    0xb7, 0x15, 0xb9, 0x4d, 0x16, 0xbc, 0x9f, 0xa9,
+    0x2f, 0xee, 0x52, 0x28, 0x12, 0x91, 0x81, 0xaa,
+    0x16, 0x65, 0x90, 0x99, 0x73, 0xff, 0x2d, 0xae,
+    0xeb, 0x5b, 0x11, 0x7f, 0x98, 0x57, 0x54, 0xe2,
+    0x85, 0x30, 0x28, 0x58, 0xac, 0x7a, 0x5e, 0x67,
+    0x45, 0x01, 0x2c, 0x3f, 0xff, 0xc8, 0x6a, 0x64,
+    0x1d, 0x3e, 0x2d, 0xe2, 0x30, 0xb3, 0x7f, 0x64,
+    0xca, 0x96, 0xe2, 0x0b, 0x51, 0xab, 0x53, 0xa3,
+};
+
+static uint32_t dh512_g = 2;
+
+static uint8_t dh512_r[] = {
+    0x00, 0x01, 0x65, 0xf4, 0x48, 0x8c, 0xe7, 0xdc,
+    0x75, 0xa5, 0xee, 0x3f, 0x93, 0x64, 0xcd, 0xf1,
+    0x81, 0x7b, 0xfb, 0xd9, 0x12, 0x79, 0xa8, 0x2d,
+    0xdb, 0x31, 0x72, 0xe5, 0x01, 0xe8, 0xb5, 0x32,
+    0x1a, 0xe1, 0x8e, 0x30, 0x9c, 0x67, 0x58, 0xcc,
+    0xf9, 0x72, 0x35, 0xc3, 0x66, 0xeb, 0xe4, 0x50,
+    0x41, 0x6e, 0xe2, 0x94, 0x97, 0xfb, 0x4b, 0xab,
+    0x50, 0x99, 0x2c, 0xaa, 0xf7, 0x6f, 0xa0, 0x51,
+    0x55, 0x37,
+};
+
+/* Test basic add delete update copy matching stuff. */
+static void tests(void)
+{
+    vmdh_t vmdh;
+    ok((vmdh = vmdh_create(dh512_g, dh512_p, sizeof(dh512_p),
+        dh512_r, sizeof(dh512_r))), "vmdh_create");
+    uint8_t pub_key[512];
+    size_t pub_key_len = sizeof(pub_key);
+    ok((vmdh_generate_key(vmdh, pub_key, &pub_key_len)),
+        "vmdh_generate_key");
+
+    uint8_t pw[] = { 0x31, 0x32, 0x33, 0x34 };
+    size_t pw_len = sizeof(pw);
+
+    uint8_t encpw[vmdh_encpw_len(sizeof(pw))];
+    size_t encpw_len = sizeof(encpw);
+
+    ok(vmdh_encrypt_password(vmdh, pub_key, pub_key_len, pw, pw_len,
+        encpw, &encpw_len), "vmdh_encrypt_password");
+
+    is(encpw_len, (size_t)16, "encrypted pw is 16 bytes");
+
+    vmdh_destroy(vmdh);
+}
+
+int vmdh_40(int argc, char *const *argv)
+{
+       plan_tests(4);
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/vmdh/vmdh-41-example.c b/sec/Security/Regressions/vmdh/vmdh-41-example.c
new file mode 100644 (file)
index 0000000..c56d4e0
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2006-2008,2010 Apple Inc. All Rights Reserved.
+ */
+
+#include <Security/vmdh.h>
+#include <Security/SecBase64.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <corecrypto/ccdh.h>
+
+#include "Security_regressions.h"
+
+#if 0
+#include <openssl/dh.h>
+#endif
+
+/* How to reach in the internals of SecDH/vmdh struct */
+static inline ccdh_gp_t vmdh_gp(struct vmdh *dh)
+{
+    void *p = dh;
+    ccdh_gp_t gp = { .gp = p };
+    return gp;
+}
+
+static inline ccdh_full_ctx_t vmdh_priv(struct vmdh *dh)
+{
+    void *p = dh;
+    cczp_t zp = { .u = p };
+    cc_size s = ccn_sizeof_n(cczp_n(zp));
+    ccdh_full_ctx_t priv = { .hdr = (struct ccdh_ctx_header *)(p+ccdh_gp_size(s)) };
+    return priv;
+}
+
+static uint32_t param_g = 5;
+
+static const uint8_t param_p[] = {
+    0xD7, 0x48, 0x26, 0xCE, 0x1B, 0x1E, 0x26, 0xEE,
+    0x2B, 0x03, 0xAA, 0xAF, 0x3E, 0x1A, 0x82, 0x39,
+    0x43, 0x2E, 0xB4, 0x36, 0x71, 0xF7, 0x5A, 0x6B,
+    0x62, 0x8D, 0x40, 0xFC, 0x39, 0xB8, 0x85, 0xB5,
+    0xA2, 0x50, 0x56, 0xE3, 0xCB, 0xF1, 0xE4, 0xFE,
+    0xA8, 0x64, 0x63, 0xA0, 0x6F, 0x19, 0xF4, 0xB0,
+    0x12, 0x11, 0x82, 0x02, 0xBB, 0xBD, 0xFF, 0xA5,
+    0x8C, 0xED, 0xBF, 0xBE, 0xF0, 0xF6, 0x18, 0xDB,
+};
+
+static const uint8_t client_priv[] = {
+    0x48, 0x52, 0x51, 0x7B, 0x04, 0xF6, 0x8B, 0xF4,
+    0x25, 0x9D, 0x08, 0x9F, 0x22, 0xB2, 0xDC, 0x6D,
+    0x84, 0x36, 0x1B, 0xBB, 0xC9, 0xEE, 0x91, 0x2F,
+    0x24, 0xFD, 0xF5, 0xEF, 0xC4, 0x8B, 0xAB, 0x39,
+    0x77, 0xE5, 0x6B, 0x31, 0x82, 0x96, 0x3C, 0x6E,
+    0xDC, 0x0A, 0x40, 0x39, 0x8F, 0xF3, 0x4A, 0x63,
+    0x00, 0x39, 0x8C, 0x52, 0x01, 0xB9, 0x48, 0xF4,
+    0xB1, 0xD2, 0x3B, 0x24, 0xF3, 0x30, 0x0B, 0x61,
+};
+
+static const uint8_t client_pub[] = {
+    0x73, 0x00, 0x67, 0x2E, 0x71, 0x38, 0x55, 0x6A,
+    0x9C, 0xA4, 0x1E, 0x7A, 0x53, 0x3A, 0x22, 0xD8,
+    0xF0, 0x37, 0xBD, 0x57, 0x9F, 0x4A, 0xD1, 0xD1,
+    0x16, 0x2F, 0x23, 0xB7, 0x3C, 0xBC, 0x15, 0x6A,
+    0x1D, 0x38, 0xE2, 0x2D, 0x4E, 0xCB, 0x8E, 0x9C,
+    0xFE, 0x86, 0x2A, 0xCA, 0xA5, 0xA6, 0xE6, 0x4E,
+    0x67, 0x2A, 0x0C, 0x37, 0x06, 0x95, 0x5B, 0xF5,
+    0xA8, 0x69, 0xBE, 0x72, 0x54, 0x0C, 0x63, 0xDD,
+};
+
+static const uint8_t server_priv[] = {
+    0x7A, 0x20, 0x70, 0x42, 0xF2, 0x19, 0x0F, 0x54,
+    0xA4, 0xD6, 0x45, 0x85, 0xFF, 0xE3, 0x4F, 0x95,
+    0x77, 0x4E, 0x05, 0xA9, 0xCF, 0x60, 0xFA, 0x54,
+    0xEC, 0xBC, 0x8B, 0x67, 0xFD, 0x59, 0x12, 0xEF,
+    0xC0, 0xD3, 0x75, 0x66, 0x3F, 0xE4, 0x50, 0x97,
+    0x94, 0x12, 0xB4, 0xE3, 0xB2, 0x5E, 0x69, 0x90,
+    0x18, 0x56, 0xAF, 0x50, 0x2D, 0xB9, 0xC9, 0x11,
+    0x8B, 0xF7, 0x75, 0x70, 0xDF, 0x16, 0xCB, 0x8F,
+};
+
+static const uint8_t server_pub[] = {
+    0x36, 0x21, 0x01, 0x4B, 0x8C, 0xD4, 0xFD, 0xA3,
+    0xBA, 0x12, 0x7B, 0xD7, 0x48, 0x83, 0x74, 0x09,
+    0x74, 0x46, 0xAA, 0xE0, 0x22, 0x1B, 0x2F, 0x25,
+    0xE7, 0x25, 0x25, 0x4B, 0x7E, 0xAE, 0xEA, 0x30,
+    0xE0, 0xFD, 0xC8, 0x5A, 0xD5, 0xD2, 0x9C, 0x54,
+    0xCE, 0x0E, 0x8A, 0xB1, 0x16, 0xD8, 0xA3, 0xFA,
+    0xD9, 0x85, 0xA8, 0x42, 0x4E, 0xF5, 0x77, 0x9F,
+    0x2D, 0xAB, 0x4C, 0xE2, 0x1C, 0xE7, 0xCE, 0xD9,
+};
+
+static const uint8_t pw[] = {
+       0x31, 0x32, 0x33, 0x34
+};
+
+/* base64 would be:
+rHWs3KX/1ubFTzfim+9mLw==
+*/
+static const uint8_t pw_encr[] = {
+       0xac, 0x75, 0xac, 0xdc, 0xa5, 0xff, 0xd6, 0xe6,
+       0xc5, 0x4f, 0x37, 0xe2, 0x9b, 0xef, 0x66, 0x2f
+};
+
+#if 0
+static void hexdump(const uint8_t *bytes, size_t len) {
+       size_t ix;
+       for (ix = 0; ix < len; ++ix) {
+               printf("%02X", bytes[ix]);
+       }
+       printf("\n");
+}
+#endif
+
+/* Test basic add delete update copy matching stuff. */
+static void tests(void)
+{
+    vmdh_t vmdh;
+    ok((vmdh = vmdh_create(param_g, param_p, sizeof(param_p),
+        NULL, 0)), "vmdh_create");
+
+    /* No SecDH API to import a private key, so we have to reach inside the opaque struct */
+    ccdh_gp_t gp = vmdh_gp(vmdh);
+    ccdh_full_ctx_t priv = vmdh_priv(vmdh);
+    ok_status(ccdh_import_priv(gp, sizeof(client_priv), client_priv, priv), "Import private DH key");
+
+    uint8_t encpw[vmdh_encpw_len(sizeof(pw))];
+    size_t encpw_len = sizeof(encpw);
+
+    ok(vmdh_encrypt_password(vmdh, server_pub, sizeof(server_pub),
+               pw, sizeof(pw), encpw, &encpw_len), "vmdh_encrypt_password");
+    vmdh_destroy(vmdh);
+
+    is(encpw_len, sizeof(pw_encr), "check ciphertext size");
+       ok(!memcmp(encpw, pw_encr, sizeof(pw_encr)), "does ciphertext match?");
+
+#if 0
+       hexdump(encpw, encpw_len);
+       hexdump(pw_encr, sizeof(pw_encr));
+
+       DH *dh = DH_new();
+       dh->p = BN_bin2bn(param_p, sizeof(param_p), BN_new());
+       BN_hex2bn(&dh->g, "05");
+       dh->pub_key = BN_bin2bn(client_pub, sizeof(client_pub), BN_new());
+       dh->priv_key = BN_bin2bn(client_priv, sizeof(client_priv), BN_new());
+       BIGNUM *bn_server_pub = BN_bin2bn(server_pub, sizeof(server_pub), BN_new());
+       unsigned char key[1024];
+       DH_compute_key(key, bn_server_pub, dh);
+       printf("shared secret:\n");
+       hexdump(key, 16);
+#endif
+}
+
+int vmdh_41_example(int argc, char *const *argv)
+{
+       plan_tests(5);
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/Security/Regressions/vmdh/vmdh-42-example2.c b/sec/Security/Regressions/vmdh/vmdh-42-example2.c
new file mode 100644 (file)
index 0000000..5e35b37
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2006-2008,2010 Apple Inc. All Rights Reserved.
+ */
+
+#include <Security/vmdh.h>
+#include <Security/SecBase64.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <corecrypto/ccdh.h>
+
+#include "Security_regressions.h"
+
+#if 0
+#include <openssl/dh.h>
+#endif
+
+/* How to reach in the internals of SecDH/vmdh struct */
+static inline ccdh_gp_t vmdh_gp(struct vmdh *dh)
+{
+    void *p = dh;
+    ccdh_gp_t gp = { .gp = p };
+    return gp;
+}
+
+static inline ccdh_full_ctx_t vmdh_priv(struct vmdh *dh)
+{
+    void *p = dh;
+    cczp_t zp = { .u = p };
+    cc_size s = ccn_sizeof_n(cczp_n(zp));
+    ccdh_full_ctx_t priv = { .hdr = (struct ccdh_ctx_header *)(p+ccdh_gp_size(s)) };
+    return priv;
+}
+
+static uint32_t param_g = 5;
+
+static const uint8_t param_p[] = {
+    0xED, 0x42, 0x06, 0xE1, 0xDD, 0x09, 0x93, 0xA6,
+    0x81, 0xAE, 0x00, 0x0D, 0xBF, 0x84, 0x7F, 0x7D,
+    0x87, 0x64, 0x6B, 0x77, 0x24, 0x03, 0xB8, 0xC0,
+    0xDC, 0xBE, 0x5B, 0x9C, 0x8E, 0x71, 0x09, 0x24,
+    0x53, 0x77, 0x7F, 0x5D, 0x1A, 0xAD, 0x92, 0xD8,
+    0xFE, 0xCD, 0x5C, 0xB4, 0xCA, 0x09, 0x17, 0x11,
+    0xF3, 0x82, 0x01, 0x39, 0x4A, 0x09, 0xBA, 0x29,
+    0x95, 0x2B, 0xC4, 0xCC, 0x56, 0x21, 0x97, 0x13
+};
+
+static const uint8_t client_priv[] = {
+    0x32, 0x34, 0x73, 0x16, 0x7d, 0x79, 0xde, 0x47,
+    0x22, 0x93, 0xf5, 0x86, 0x47, 0xf6, 0x7f, 0x7a,
+    0xb6, 0x30, 0x16, 0x5b, 0xbf, 0xe1, 0x36, 0x0b,
+    0xb4, 0xd2, 0x84, 0x3e, 0x57, 0x5f, 0xcb, 0xc6,
+    0x6a, 0xae, 0x5d, 0x59, 0x4b, 0x70, 0x53, 0x22,
+    0xb0, 0x51, 0x89, 0x30, 0x74, 0xfc, 0x95, 0x51,
+    0x9c, 0xc9, 0xf7, 0xac, 0x8c, 0x37, 0xfd, 0xc1,
+    0x0e, 0x02, 0x6e, 0x69, 0x6c, 0xca, 0x2a, 0x95
+};
+
+static const uint8_t client_pub[] = {
+    0x15, 0xDF, 0x17, 0x6E, 0xB4, 0x95, 0xA7, 0x92,
+    0x41, 0xB6, 0xF1, 0x93, 0x19, 0xDB, 0x34, 0xF1,
+    0xE0, 0x0D, 0x62, 0xCD, 0x55, 0xC7, 0x0B, 0x27,
+    0xB7, 0x53, 0x1A, 0x28, 0x65, 0x11, 0xF0, 0xF6,
+    0xA6, 0xE1, 0x5B, 0x86, 0x1D, 0x67, 0x85, 0x19,
+    0x6D, 0xD6, 0x80, 0xFF, 0x5C, 0xEB, 0xC3, 0x2D,
+    0xC3, 0xCB, 0xD2, 0xD4, 0x66, 0x93, 0xF4, 0xFC,
+    0xF1, 0xF4, 0x8B, 0x61, 0x0F, 0x02, 0xF5, 0x19
+};
+
+static const uint8_t server_pub[] = {
+    0x73, 0xC5, 0xF8, 0xF8, 0xB8, 0x9C, 0xB0, 0x5F,
+    0xD6, 0xC6, 0x49, 0x5C, 0x70, 0xF5, 0x90, 0xB3,
+    0x8A, 0xD3, 0xD0, 0x12, 0x99, 0x47, 0x60, 0xC2,
+    0x5B, 0xF7, 0x18, 0x3A, 0x19, 0xF5, 0x01, 0xA3,
+    0x67, 0xBF, 0x57, 0x28, 0x7E, 0x99, 0xA8, 0xDB,
+    0x97, 0xA4, 0xAF, 0xF2, 0x68, 0x47, 0xAB, 0x48,
+    0xE3, 0x4D, 0xF2, 0x94, 0xB4, 0xCC, 0xFC, 0x0C,
+    0x50, 0xAD, 0xEF, 0x2E, 0x80, 0xA6, 0x20, 0x29
+};
+
+static const uint8_t pw[] = {
+       0x31, 0x32, 0x33, 0x34
+};
+
+static const uint8_t pw_encr[] = {
+    0x42, 0xd7, 0xa1, 0x08, 0x15, 0x8f, 0xdd, 0xc8,
+    0xe8, 0x75, 0xea, 0xa2, 0xc2, 0x20, 0x28, 0xfa
+};
+
+#if 0
+static void hexdump(const uint8_t *bytes, size_t len) {
+       size_t ix;
+       for (ix = 0; ix < len; ++ix) {
+               printf("%02X", bytes[ix]);
+       }
+       printf("\n");
+}
+#endif
+
+static void tests(void)
+{
+    vmdh_t vmdh;
+    ok((vmdh = vmdh_create(param_g, param_p, sizeof(param_p),
+        NULL, 0)), "vmdh_create");
+
+    /* No SecDH API to import a private key, so we have to reach inside the opaque struct */
+    ccdh_gp_t gp = vmdh_gp(vmdh);
+    ccdh_full_ctx_t priv = vmdh_priv(vmdh);
+
+    ok_status(ccdh_import_priv(gp, sizeof(client_priv), client_priv, priv), "Import DH private key");
+
+    uint8_t encpw[vmdh_encpw_len(sizeof(pw))];
+    size_t encpw_len = sizeof(encpw);
+
+    ok(vmdh_encrypt_password(vmdh, server_pub, sizeof(server_pub),
+               pw, sizeof(pw), encpw, &encpw_len), "vmdh_encrypt_password");
+    vmdh_destroy(vmdh);
+
+    is(encpw_len, sizeof(pw_encr), "check ciphertext size");
+       ok(!memcmp(encpw, pw_encr, sizeof(pw_encr)), "does ciphertext match?");
+
+#if 0
+       hexdump(encpw, encpw_len);
+       hexdump(pw_encr, sizeof(pw_encr));
+
+       DH *dh = DH_new();
+       dh->p = BN_bin2bn(param_p, sizeof(param_p), BN_new());
+       BN_hex2bn(&dh->g, "05");
+       dh->pub_key = BN_bin2bn(client_pub, sizeof(client_pub), BN_new());
+       dh->priv_key = BN_bin2bn(client_priv, sizeof(client_priv), BN_new());
+       BIGNUM *bn_server_pub = BN_bin2bn(server_pub, sizeof(server_pub), BN_new());
+       unsigned char key[1024];
+       DH_compute_key(key, bn_server_pub, dh);
+       printf("shared secret:\n");
+       hexdump(key, 16);
+#endif
+}
+
+int vmdh_42_example2(int argc, char *const *argv)
+{
+       plan_tests(5);
+
+       tests();
+
+       return 0;
+}
index 963000cfd219b772cacdb393203979136874b857..05418207264d98021600f30017b940deaca53354 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2000-2009 Apple Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2000-2009,2011-2013 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
 /*!
        @header SecBase
  * @APPLE_LICENSE_HEADER_END@
  */
 
 /*!
        @header SecBase
-       SecBase contains common declarations for the Security functions. 
+       SecBase contains common declarations for the Security functions.
 */
 
 #ifndef _SECURITY_SECBASE_H_
 #define _SECURITY_SECBASE_H_
 
 #include <Availability.h>
 */
 
 #ifndef _SECURITY_SECBASE_H_
 #define _SECURITY_SECBASE_H_
 
 #include <Availability.h>
+#include <sys/cdefs.h>
 
 
-#if defined(__cplusplus)
-extern "C" {
+#if defined(__clang__)
+#define SEC_DEPRECATED_ATTRIBUTE DEPRECATED_ATTRIBUTE
+#else
+#define SEC_DEPRECATED_ATTRIBUTE
 #endif
 
 #endif
 
+__BEGIN_DECLS
+
 /*!
     @typedef SecCertificateRef
 /*!
     @typedef SecCertificateRef
-    @abstract CFType representing a X.509 certificate, see
-    SecCertificate.h for details.
+    @abstract CFType representing a X.509 certificate.
+    See SecCertificate.h for details.
 */
 typedef struct __SecCertificate *SecCertificateRef;
 
 /*!
     @typedef SecIdentityRef
     @abstract CFType representing an identity, which contains
 */
 typedef struct __SecCertificate *SecCertificateRef;
 
 /*!
     @typedef SecIdentityRef
     @abstract CFType representing an identity, which contains
-    a SecKeyRef and an ascociated SecCertificateRef, see
+    a SecKeyRef and an associated SecCertificateRef. See
     SecIdentity.h for details.
 */
 typedef struct __SecIdentity *SecIdentityRef;
 
 /*!
     @typedef SecKeyRef
     SecIdentity.h for details.
 */
 typedef struct __SecIdentity *SecIdentityRef;
 
 /*!
     @typedef SecKeyRef
-    @abstract CFType representing an asymetric key, see
+    @abstract CFType representing a cryptographic key. See
     SecKey.h for details.
 */
 typedef struct __SecKey *SecKeyRef;
 
     SecKey.h for details.
 */
 typedef struct __SecKey *SecKeyRef;
 
+/*!
+    @typedef SecPolicyRef
+    @abstract CFType representing a X.509 certificate trust policy.
+    See SecPolicy.h for details.
+*/
+typedef struct __SecPolicy *SecPolicyRef;
+
 /***********************************************
  *** OSStatus values unique to Security APIs ***
  ***********************************************/
 /***********************************************
  *** OSStatus values unique to Security APIs ***
  ***********************************************/
@@ -71,20 +83,23 @@ typedef struct __SecKey *SecKeyRef;
 
 enum
 {
 
 enum
 {
-    errSecSuccess                = 0,       /* No error. */
-    errSecUnimplemented          = -4,      /* Function or operation not implemented. */
-    errSecParam                  = -50,     /* One or more parameters passed to a function where not valid. */
-    errSecAllocate               = -108,    /* Failed to allocate memory. */
-    errSecNotAvailable           = -25291,     /* No keychain is available. You may need to restart your computer. */
-    errSecDuplicateItem          = -25299,     /* The specified item already exists in the keychain. */
-    errSecItemNotFound           = -25300,     /* The specified item could not be found in the keychain. */
-    errSecInteractionNotAllowed  = -25308,     /* User interaction is not allowed. */
-    errSecDecode                 = -26275,  /* Unable to decode the provided data. */
-    errSecAuthFailed             = -25293,     /* The user name or passphrase you entered is not correct. */
+    errSecSuccess                               = 0,       /* No error. */
+    errSecUnimplemented                         = -4,      /* Function or operation not implemented. */
+    errSecIO                                    = -36,     /*I/O error (bummers)*/
+    errSecOpWr                                  = -49,     /*file already open with with write permission*/
+    errSecParam                                 = -50,     /* One or more parameters passed to a function where not valid. */
+    errSecAllocate                              = -108,    /* Failed to allocate memory. */
+    errSecUserCanceled                          = -128,    /* User canceled the operation. */
+    errSecBadReq                                = -909,    /* Bad parameter or invalid state for operation. */
+    errSecInternalComponent                     = -2070,
+    errSecNotAvailable                          = -25291,  /* No keychain is available. You may need to restart your computer. */
+    errSecDuplicateItem                         = -25299,  /* The specified item already exists in the keychain. */
+    errSecItemNotFound                          = -25300,  /* The specified item could not be found in the keychain. */
+    errSecInteractionNotAllowed                 = -25308,  /* User interaction is not allowed. */
+    errSecDecode                                = -26275,  /* Unable to decode the provided data. */
+    errSecAuthFailed                            = -25293,  /* The user name or passphrase you entered is not correct. */
 };
 
 };
 
-#if defined(__cplusplus)
-}
-#endif
+__END_DECLS
 
 #endif /* !_SECURITY_SECBASE_H_ */
 
 #endif /* !_SECURITY_SECBASE_H_ */
index 9b380747c503b8088812ab7e6c29bd6f4a556d3f..5fc4a24c78614b969039876827c0b79893b6fcda 100644 (file)
 #define _SECURITY_SECBASEPRIV_H_
 
 #include <Security/SecBase.h>
 #define _SECURITY_SECBASEPRIV_H_
 
 #include <Security/SecBase.h>
-#include <MacErrors.h>
 
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 /*******************************************************
  *** Private OSStatus values unique to Security APIs ***
 
 /*******************************************************
  *** Private OSStatus values unique to Security APIs ***
@@ -106,6 +103,7 @@ enum
     errSecReturnDataUnsupported  = errSecParam, // -34008,  /* The caller passed in a kSecReturnData key to a function which does not support it. */
     errSecReturnAttributesUnsupported = errSecParam, // -34009,  /* The caller passed in a kSecReturnAttributes key to a function which does not support it. */
     errSecReturnRefUnsupported   = errSecParam, // -34010,  /* The caller passed in a kSecReturnRef key to a function which does not support it. */
     errSecReturnDataUnsupported  = errSecParam, // -34008,  /* The caller passed in a kSecReturnData key to a function which does not support it. */
     errSecReturnAttributesUnsupported = errSecParam, // -34009,  /* The caller passed in a kSecReturnAttributes key to a function which does not support it. */
     errSecReturnRefUnsupported   = errSecParam, // -34010,  /* The caller passed in a kSecReturnRef key to a function which does not support it. */
+    errSecReturnPersitentRefUnsupported   = errSecParam, // -34010,  /* The caller passed in a kSecReturnPersistentRef key to a function which does not support it. */
     errSecValueRefUnsupported    = errSecParam, // -34012,  /* The caller passed in a kSecValueRef key to a function which does not support it. */
     errSecValuePersistentRefUnsupported = errSecParam, // -34013,  /* The caller passed in a kSecValuePersistentRef key to a function which does not support it. */
     errSecReturnMissingPointer   = errSecParam, // -34014,  /* The caller passed asked for something to be returned but did not pass in a result pointer. */
     errSecValueRefUnsupported    = errSecParam, // -34012,  /* The caller passed in a kSecValueRef key to a function which does not support it. */
     errSecValuePersistentRefUnsupported = errSecParam, // -34013,  /* The caller passed in a kSecValuePersistentRef key to a function which does not support it. */
     errSecReturnMissingPointer   = errSecParam, // -34014,  /* The caller passed asked for something to be returned but did not pass in a result pointer. */
@@ -122,8 +120,6 @@ enum
 };
 
 
 };
 
 
-#if defined(__cplusplus)
-}
-#endif
+__END_DECLS
 
 #endif /* !_SECURITY_SECBASEPRIV_H_ */
 
 #endif /* !_SECURITY_SECBASEPRIV_H_ */
index d61b98c1efc9c78c895ae38898e5f06dab96df37..7e790043a22b488c6b5a2d084aae2f18af932358 100644 (file)
@@ -58,6 +58,7 @@
 #include <Security/SecCertificatePriv.h>
 
 #include "SecCMS.h"
 #include <Security/SecCertificatePriv.h>
 
 #include "SecCMS.h"
+#include <Security/SecTrustPriv.h>
 
 
 #include <security_asn1/secasn1.h>
 
 
 #include <security_asn1/secasn1.h>
@@ -78,6 +79,8 @@ CFTypeRef kSecCMSCertChainMode = CFSTR("kSecCMSCertChainMode");
 CFTypeRef kSecCMSCertChainModeNone = CFSTR("0");
 CFTypeRef kSecCMSAdditionalCerts = CFSTR("kSecCMSAdditionalCerts");
 CFTypeRef kSecCMSSignedAttributes = CFSTR("kSecCMSSignedAttributes");
 CFTypeRef kSecCMSCertChainModeNone = CFSTR("0");
 CFTypeRef kSecCMSAdditionalCerts = CFSTR("kSecCMSAdditionalCerts");
 CFTypeRef kSecCMSSignedAttributes = CFSTR("kSecCMSSignedAttributes");
+CFTypeRef kSecCMSSignDate = CFSTR("kSecCMSSignDate");
+CFTypeRef kSecCMSAllCerts = CFSTR("kSecCMSAllCerts");
 
 OSStatus SecCMSCreateEnvelopedData(CFTypeRef recipient_or_cfarray_thereof, 
     CFDictionaryRef params, CFDataRef data, CFMutableDataRef enveloped_data)
 
 OSStatus SecCMSCreateEnvelopedData(CFTypeRef recipient_or_cfarray_thereof, 
     CFDictionaryRef params, CFDataRef data, CFMutableDataRef enveloped_data)
@@ -130,7 +133,7 @@ OSStatus SecCMSCreateEnvelopedData(CFTypeRef recipient_or_cfarray_thereof,
     }
     require_noerr(SecCmsMessageEncode(cmsg, (data && input.Length) ? &input : NULL, enveloped_data), out);
     
     }
     require_noerr(SecCmsMessageEncode(cmsg, (data && input.Length) ? &input : NULL, enveloped_data), out);
     
-    status = noErr;
+    status = errSecSuccess;
 out:
     if (cmsg) SecCmsMessageDestroy(cmsg);
     return status;
 out:
     if (cmsg) SecCmsMessageDestroy(cmsg);
     return status;
@@ -163,10 +166,10 @@ OSStatus SecCMSDecryptEnvelopedData(CFDataRef message,
     if (content)
         CFDataAppendBytes(data, content->Data, content->Length);
     if (recipient) {
     if (content)
         CFDataAppendBytes(data, content->Data, content->Length);
     if (recipient) {
-        CFRetain(used_recipient);
+        CFRetainSafe(used_recipient);
         *recipient = used_recipient;
     }
         *recipient = used_recipient;
     }
-    status = noErr;
+    status = errSecSuccess;
 out:
     if (cmsg) SecCmsMessageDestroy(cmsg);
     return status;
 out:
     if (cmsg) SecCmsMessageDestroy(cmsg);
     return status;
@@ -292,7 +295,7 @@ static OSStatus SecCMSSignDataOrDigestAndAttributes(SecIdentityRef identity,
     else
         require_noerr(SecCmsMessageEncode(cmsg, (data && input.Length) ? &input : NULL, signed_data), out);
     
     else
         require_noerr(SecCmsMessageEncode(cmsg, (data && input.Length) ? &input : NULL, signed_data), out);
     
-    status = noErr;
+    status = errSecSuccess;
 out:
     if (cmsg) SecCmsMessageDestroy(cmsg);
     return status;
 out:
     if (cmsg) SecCmsMessageDestroy(cmsg);
     return status;
@@ -355,7 +358,7 @@ OSStatus SecCMSCreateSignedData(SecIdentityRef identity, CFDataRef data,
 }
 
 
 }
 
 
-static CFMutableArrayRef signed_attribute_values(SecCmsAttribute *attr)
+static CFMutableArrayRef copy_signed_attribute_values(SecCmsAttribute *attr)
 {
     CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
     SecAsn1Item **item = attr->values;
 {
     CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
     SecAsn1Item **item = attr->values;
@@ -371,7 +374,7 @@ static CFMutableArrayRef signed_attribute_values(SecCmsAttribute *attr)
 }
 
 static OSStatus SecCMSVerifySignedData_internal(CFDataRef message, CFDataRef detached_contents,
 }
 
 static OSStatus SecCMSVerifySignedData_internal(CFDataRef message, CFDataRef detached_contents,
-    SecPolicyRef policy, SecTrustRef *trustref, CFArrayRef additional_certs,
+    CFTypeRef policy, SecTrustRef *trustref, CFArrayRef additional_certs,
     CFDataRef *attached_contents, CFDictionaryRef *signed_attributes)
 {
     SecCmsMessageRef cmsg = NULL;
     CFDataRef *attached_contents, CFDictionaryRef *signed_attributes)
 {
     SecCmsMessageRef cmsg = NULL;
@@ -408,7 +411,7 @@ static OSStatus SecCMSVerifySignedData_internal(CFDataRef message, CFDataRef det
             out, status = errSecAuthFailed);
     }
     
             out, status = errSecAuthFailed);
     }
     
-#if 0
+    #if 0
     if (nsigners > 1)
         trustrefs = CFArrayCreateMutable(kCFAllocatorDefault, nsigners, &kCFTypeArrayCallBacks);
         
     if (nsigners > 1)
         trustrefs = CFArrayCreateMutable(kCFAllocatorDefault, nsigners, &kCFTypeArrayCallBacks);
         
@@ -429,7 +432,7 @@ static OSStatus SecCMSVerifySignedData_internal(CFDataRef message, CFDataRef det
     trustrefs = NULL;
 #endif
 
     trustrefs = NULL;
 #endif
 
-    status = noErr;
+    status = errSecSuccess;
 
     if (attached_contents) {
         const SecAsn1Item *content = SecCmsMessageGetContent(cmsg);
 
     if (attached_contents) {
         const SecAsn1Item *content = SecCmsMessageGetContent(cmsg);
@@ -447,7 +450,7 @@ static OSStatus SecCMSVerifySignedData_internal(CFDataRef message, CFDataRef det
         if (signed_attrs) while (*signed_attrs) {
             CFDataRef type = CFDataCreate(kCFAllocatorDefault, (*signed_attrs)->type.Data, (*signed_attrs)->type.Length);
             if (type) {
         if (signed_attrs) while (*signed_attrs) {
             CFDataRef type = CFDataCreate(kCFAllocatorDefault, (*signed_attrs)->type.Data, (*signed_attrs)->type.Length);
             if (type) {
-                CFMutableArrayRef attr = signed_attribute_values(*signed_attrs);
+                CFMutableArrayRef attr = copy_signed_attribute_values(*signed_attrs);
                 if (attr) {
                     CFMutableArrayRef existing_attrs = (CFMutableArrayRef)CFDictionaryGetValue(attrs, type);
                     if (existing_attrs) {
                 if (attr) {
                     CFMutableArrayRef existing_attrs = (CFMutableArrayRef)CFDictionaryGetValue(attrs, type);
                     if (existing_attrs) {
@@ -462,23 +465,52 @@ static OSStatus SecCMSVerifySignedData_internal(CFDataRef message, CFDataRef det
             }
             signed_attrs++;
         }
             }
             signed_attrs++;
         }
+        CFMutableArrayRef certs = NULL;
+        
+        SecAsn1Item **cert_datas = SecCmsSignedDataGetCertificateList(sigd);
+        certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+        SecAsn1Item *cert_data;
+        if (cert_datas) while ((cert_data = *cert_datas) != NULL) {
+            SecCertificateRef cert = SecCertificateCreateWithBytes(NULL, cert_data->Data, cert_data->Length);
+            if (cert) {
+                CFArrayAppendValue(certs, cert);
+                CFRelease(cert);
+            }
+            cert_datas++;
+        }
+        
+        CFDictionaryAddValue(attrs, kSecCMSAllCerts, certs);
+
+        /* Add "cooked" values separately */
+        CFAbsoluteTime signing_time;
+        if (errSecSuccess == SecCmsSignerInfoGetSigningTime(sigd->signerInfos[0], &signing_time)) {
+                CFDateRef signing_date = CFDateCreate(kCFAllocatorDefault, signing_time);
+            if (signing_date){
+                CFDictionarySetValue(attrs, kSecCMSSignDate, signing_date);
+                CFReleaseSafe(signing_date);
+            }
+        }
+
         *signed_attributes = attrs;
     }
     
         *signed_attributes = attrs;
     }
     
+    
 out:
     if (cmsg) SecCmsMessageDestroy(cmsg);
     return status;
 }
 
 OSStatus SecCMSVerifyCopyDataAndAttributes(CFDataRef message, CFDataRef detached_contents,
 out:
     if (cmsg) SecCmsMessageDestroy(cmsg);
     return status;
 }
 
 OSStatus SecCMSVerifyCopyDataAndAttributes(CFDataRef message, CFDataRef detached_contents,
-    SecPolicyRef policy, SecTrustRef *trustref,
+    CFTypeRef policy, SecTrustRef *trustref,
     CFDataRef *attached_contents, CFDictionaryRef *signed_attributes)
 {
     CFDataRef *attached_contents, CFDictionaryRef *signed_attributes)
 {
-    return SecCMSVerifySignedData_internal(message, detached_contents, policy, trustref, NULL, attached_contents, signed_attributes);
+    OSStatus status = SecCMSVerifySignedData_internal(message, detached_contents, policy, trustref, NULL, attached_contents, signed_attributes);
+    
+    return status;
 }
 
 OSStatus SecCMSVerifySignedData(CFDataRef message, CFDataRef detached_contents,
 }
 
 OSStatus SecCMSVerifySignedData(CFDataRef message, CFDataRef detached_contents,
-    SecPolicyRef policy, SecTrustRef *trustref, CFArrayRef additional_certificates,
+    CFTypeRef policy, SecTrustRef *trustref, CFArrayRef additional_certificates,
     CFDataRef *attached_contents, CFDictionaryRef *message_attributes)
 {
     CFDictionaryRef signed_attributes = NULL;
     CFDataRef *attached_contents, CFDictionaryRef *message_attributes)
 {
     CFDictionaryRef signed_attributes = NULL;
@@ -487,12 +519,12 @@ OSStatus SecCMSVerifySignedData(CFDataRef message, CFDataRef detached_contents,
         *message_attributes = CFDictionaryCreate(kCFAllocatorDefault, &kSecCMSSignedAttributes, (const void **)&signed_attributes, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
     }
     CFReleaseSafe(signed_attributes);
         *message_attributes = CFDictionaryCreate(kCFAllocatorDefault, &kSecCMSSignedAttributes, (const void **)&signed_attributes, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
     }
     CFReleaseSafe(signed_attributes);
-
+   
     return status;
 }
 
 OSStatus SecCMSVerify(CFDataRef message, CFDataRef detached_contents,
     return status;
 }
 
 OSStatus SecCMSVerify(CFDataRef message, CFDataRef detached_contents,
-    SecPolicyRef policy, SecTrustRef *trustref,
+    CFTypeRef policy, SecTrustRef *trustref,
     CFDataRef *attached_contents) {
         return SecCMSVerifySignedData_internal(message, detached_contents, policy, trustref, NULL, attached_contents, NULL);
 }
     CFDataRef *attached_contents) {
         return SecCMSVerifySignedData_internal(message, detached_contents, policy, trustref, NULL, attached_contents, NULL);
 }
@@ -591,7 +623,7 @@ CFDataRef SecCMSCreateCertificatesOnlyMessage(CFTypeRef cert_or_array_thereof) {
     CFDataAppendBytes(cert_only_signed_data, cert_only_signed_data_item.Data, 
         cert_only_signed_data_item.Length);
     
     CFDataAppendBytes(cert_only_signed_data, cert_only_signed_data_item.Data, 
         cert_only_signed_data_item.Length);
     
-    status = noErr;
+    status = errSecSuccess;
 out:
     CFReleaseSafe(cert_array);
     if (status) CFReleaseSafe(cert_only_signed_data);
 out:
     CFReleaseSafe(cert_array);
     if (status) CFReleaseSafe(cert_only_signed_data);
index 05f65bb48d8ff2532d02df84cc6110a4d5206025..8b0586cd46cc018211ceb7e0f9423ca6ee36e429 100644 (file)
@@ -33,9 +33,7 @@
 #ifndef _SECURITY_SECCMS_H_
 #define _SECURITY_SECCMS_H_
 
 #ifndef _SECURITY_SECCMS_H_
 #define _SECURITY_SECCMS_H_
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 extern const void * kSecCMSBulkEncryptionAlgorithm;
 extern const void * kSecCMSSignDigest;
 
 extern const void * kSecCMSBulkEncryptionAlgorithm;
 extern const void * kSecCMSSignDigest;
@@ -44,6 +42,8 @@ extern const void * kSecCMSSignHashAlgorithm;
 extern const void * kSecCMSCertChainMode;
 extern const void * kSecCMSAdditionalCerts;
 extern const void * kSecCMSSignedAttributes;
 extern const void * kSecCMSCertChainMode;
 extern const void * kSecCMSAdditionalCerts;
 extern const void * kSecCMSSignedAttributes;
+extern const void * kSecCMSSignDate;
+extern const void * kSecCMSAllCerts;
 
 extern const void * kSecCMSEncryptionAlgorithmDESCBC;
 extern const void * kSecCMSEncryptionAlgorithmAESCBC;
 
 extern const void * kSecCMSEncryptionAlgorithmDESCBC;
 extern const void * kSecCMSEncryptionAlgorithmAESCBC;
@@ -55,9 +55,9 @@ extern const void * kSecCMSCertChainModeNone;
     @abstract verify a signed data cms blob.
     @param message the cms message to be parsed
     @param detached_contents to pass detached contents (optional)
     @abstract verify a signed data cms blob.
     @param message the cms message to be parsed
     @param detached_contents to pass detached contents (optional)
-    @param policy specifies which policy should be used (optional).  if none is 
-        passed the blob will **not** be verified and only the attached contents 
-        will be returned.
+    @param policy specifies policy or array thereof should be used (optional).  
+       if none is passed the blob will **not** be verified and only 
+       the attached contents will be returned.
     @param trustref (output/optional) if specified, the trust chain built during 
         verification will not be evaluated but returned to the caller to do so.
        @param attached_contents (output/optional) return a copy of the attached 
     @param trustref (output/optional) if specified, the trust chain built during 
         verification will not be evaluated but returned to the caller to do so.
        @param attached_contents (output/optional) return a copy of the attached 
@@ -72,7 +72,7 @@ extern const void * kSecCMSCertChainModeNone;
         errSecParam garbage in, garbage out.
 */
 OSStatus SecCMSVerifyCopyDataAndAttributes(CFDataRef message, CFDataRef detached_contents,
         errSecParam garbage in, garbage out.
 */
 OSStatus SecCMSVerifyCopyDataAndAttributes(CFDataRef message, CFDataRef detached_contents,
-    SecPolicyRef policy, SecTrustRef *trustref,
+    CFTypeRef policy, SecTrustRef *trustref,
     CFDataRef *attached_contents, CFDictionaryRef *signed_attributes);
 
 /*!
     CFDataRef *attached_contents, CFDictionaryRef *signed_attributes);
 
 /*!
@@ -80,7 +80,7 @@ OSStatus SecCMSVerifyCopyDataAndAttributes(CFDataRef message, CFDataRef detached
     @abstract same as SecCMSVerifyCopyDataAndAttributes, for binary compatibility.
 */
 OSStatus SecCMSVerify(CFDataRef message, CFDataRef detached_contents,
     @abstract same as SecCMSVerifyCopyDataAndAttributes, for binary compatibility.
 */
 OSStatus SecCMSVerify(CFDataRef message, CFDataRef detached_contents,
-    SecPolicyRef policy, SecTrustRef *trustref, CFDataRef *attached_contents);
+    CFTypeRef policy, SecTrustRef *trustref, CFDataRef *attached_contents);
 
 
 /* Return an array of certificates contained in message, if message is of the
 
 
 /* Return an array of certificates contained in message, if message is of the
@@ -165,11 +165,9 @@ OSStatus SecCMSDecryptEnvelopedData(CFDataRef message,
     CFMutableDataRef data, SecCertificateRef *recipient);
 
 OSStatus SecCMSVerifySignedData(CFDataRef message, CFDataRef detached_contents,
     CFMutableDataRef data, SecCertificateRef *recipient);
 
 OSStatus SecCMSVerifySignedData(CFDataRef message, CFDataRef detached_contents,
-    SecPolicyRef policy, SecTrustRef *trustref, CFArrayRef additional_certificates,
+    CFTypeRef policy, SecTrustRef *trustref, CFArrayRef additional_certificates,
     CFDataRef *attached_contents, CFDictionaryRef *message_attributes);
 
     CFDataRef *attached_contents, CFDictionaryRef *message_attributes);
 
-#if defined(__cplusplus)
-}
-#endif
+__END_DECLS
 
 #endif /* !_SECURITY_SECCMS_H_ */
 
 #endif /* !_SECURITY_SECCMS_H_ */
index 7ae67bebc630a6bc378b8357659032400c45f9fe..6067db946ab73b06dffc76aa9325d2ba13407548 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2006-2011 Apple Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2006-2012 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
-/* 
+/*
  * SecCertificate.c - CoreFoundation based certificate object
  */
 
  * SecCertificate.c - CoreFoundation based certificate object
  */
 
@@ -32,7 +32,7 @@
 #endif
 
 #include <Security/SecCertificateInternal.h>
 #endif
 
 #include <Security/SecCertificateInternal.h>
-
+#include <utilities/SecIOFormat.h>
 #include <CommonCrypto/CommonDigest.h>
 #include <CoreFoundation/CFRuntime.h>
 #include <CoreFoundation/CFString.h>
 #include <CommonCrypto/CommonDigest.h>
 #include <CoreFoundation/CFRuntime.h>
 #include <CoreFoundation/CFString.h>
@@ -41,6 +41,7 @@
 #include <CoreFoundation/CFNumber.h>
 #include <CoreFoundation/CFCalendar.h>
 #include <CoreFoundation/CFTimeZone.h>
 #include <CoreFoundation/CFNumber.h>
 #include <CoreFoundation/CFCalendar.h>
 #include <CoreFoundation/CFTimeZone.h>
+#include <CoreFoundation/CFXPCBridge.h>
 #include <pthread.h>
 #include <string.h>
 #include <AssertMacros.h>
 #include <pthread.h>
 #include <string.h>
 #include <AssertMacros.h>
 #include "SecItem.h"
 #include "SecItemPriv.h"
 #include <stdbool.h>
 #include "SecItem.h"
 #include "SecItemPriv.h"
 #include <stdbool.h>
-#include <security_utilities/debugging.h>
+#include <utilities/debugging.h>
+#include <utilities/SecCFWrappers.h>
+#include <utilities/SecCFError.h>
+#include <utilities/array_size.h>
 #include <stdlib.h>
 #include <libkern/OSByteOrder.h>
 #include <ctype.h>
 #include <Security/SecInternal.h>
 #include <Security/SecFrameworkStrings.h>
 #include "SecBase64.h"
 #include <stdlib.h>
 #include <libkern/OSByteOrder.h>
 #include <ctype.h>
 #include <Security/SecInternal.h>
 #include <Security/SecFrameworkStrings.h>
 #include "SecBase64.h"
+#include "AppleBaselineEscrowCertificates.h"
+#include "securityd_client.h"
 
 typedef struct SecCertificateExtension {
        DERItem extnID;
 
 typedef struct SecCertificateExtension {
        DERItem extnID;
@@ -78,7 +84,7 @@ typedef struct KnownExtension {
 enum {
     kSecSelfSignedUnknown = 0,
     kSecSelfSignedFalse,
 enum {
     kSecSelfSignedUnknown = 0,
     kSecSelfSignedFalse,
-    kSecSelfSignedTrue,    
+    kSecSelfSignedTrue,
 };
 #endif
 
 };
 #endif
 
@@ -137,7 +143,7 @@ struct __SecCertificate {
     /* If KeyUsage extension is not present this is 0, otherwise it's
        the value of the extension. */
     SecKeyUsage _keyUsage;
     /* If KeyUsage extension is not present this is 0, otherwise it's
        the value of the extension. */
     SecKeyUsage _keyUsage;
-    
+
        /* OCTECTS of SubjectKeyIdentifier extensions KeyIdentifier.
           Length = 0 if not present. */
     DERItem                            _subjectKeyIdentifier;
        /* OCTECTS of SubjectKeyIdentifier extensions KeyIdentifier.
           Length = 0 if not present. */
     DERItem                            _subjectKeyIdentifier;
@@ -189,28 +195,33 @@ struct __SecCertificate {
 
 };
 
 
 };
 
+#define SEC_CONST_DECL(k,v) CFTypeRef k = (CFTypeRef)(CFSTR(v));
+
+SEC_CONST_DECL (kSecCertificateProductionEscrowKey, "ProductionEscrowKey");
+SEC_CONST_DECL (kSecCertificateEscrowFileName, "AppleESCertificates");
+
 /* Public Constants for property list keys. */
 /* Public Constants for property list keys. */
-CFStringRef kSecPropertyKeyType             = CFSTR("type");
-CFStringRef kSecPropertyKeyLabel            = CFSTR("label");
-CFStringRef kSecPropertyKeyLocalizedLabel   = CFSTR("localized label");
-CFStringRef kSecPropertyKeyValue            = CFSTR("value");
+SEC_CONST_DECL (kSecPropertyKeyType, "type");
+SEC_CONST_DECL (kSecPropertyKeyLabel, "label");
+SEC_CONST_DECL (kSecPropertyKeyLocalizedLabel, "localized label");
+SEC_CONST_DECL (kSecPropertyKeyValue, "value");
 
 /* Public Constants for property list values. */
 
 /* Public Constants for property list values. */
-CFStringRef kSecPropertyTypeWarning         = CFSTR("warning");
-CFStringRef kSecPropertyTypeError           = CFSTR("error");
-CFStringRef kSecPropertyTypeSuccess         = CFSTR("success");
-CFStringRef kSecPropertyTypeTitle           = CFSTR("title");
-CFStringRef kSecPropertyTypeSection         = CFSTR("section");
-CFStringRef kSecPropertyTypeData            = CFSTR("data");
-CFStringRef kSecPropertyTypeString          = CFSTR("string");
-CFStringRef kSecPropertyTypeURL             = CFSTR("url");
-CFStringRef kSecPropertyTypeDate            = CFSTR("date");
+SEC_CONST_DECL (kSecPropertyTypeWarning, "warning");
+SEC_CONST_DECL (kSecPropertyTypeError, "error");
+SEC_CONST_DECL (kSecPropertyTypeSuccess, "success");
+SEC_CONST_DECL (kSecPropertyTypeTitle, "title");
+SEC_CONST_DECL (kSecPropertyTypeSection, "section");
+SEC_CONST_DECL (kSecPropertyTypeData, "data");
+SEC_CONST_DECL (kSecPropertyTypeString, "string");
+SEC_CONST_DECL (kSecPropertyTypeURL, "url");
+SEC_CONST_DECL (kSecPropertyTypeDate, "date");
 
 /* Extension parsing routine. */
 typedef void (*SecCertificateExtensionParser)(SecCertificateRef certificate,
        const SecCertificateExtension *extn);
 
 
 /* Extension parsing routine. */
 typedef void (*SecCertificateExtensionParser)(SecCertificateRef certificate,
        const SecCertificateExtension *extn);
 
-/* CFRuntime regsitration data. */
+/* CFRuntime registration data. */
 static pthread_once_t kSecCertificateRegisterClass = PTHREAD_ONCE_INIT;
 static CFTypeID kSecCertificateTypeID = _kCFRuntimeNotATypeID;
 
 static pthread_once_t kSecCertificateRegisterClass = PTHREAD_ONCE_INIT;
 static CFTypeID kSecCertificateTypeID = _kCFRuntimeNotATypeID;
 
@@ -218,14 +229,14 @@ static CFTypeID kSecCertificateTypeID = _kCFRuntimeNotATypeID;
    SecCertificateExtensionParser extension parsing routines. */
 static CFDictionaryRef gExtensionParsers;
 
    SecCertificateExtensionParser extension parsing routines. */
 static CFDictionaryRef gExtensionParsers;
 
-/* Forward declartions of static functions. */
+/* Forward declarations of static functions. */
 static CFStringRef SecCertificateDescribe(CFTypeRef cf);
 static void SecCertificateDestroy(CFTypeRef cf);
 static bool derDateGetAbsoluteTime(const DERItem *dateChoice,
     CFAbsoluteTime *absTime);
 
 /* Static functions. */
 static CFStringRef SecCertificateDescribe(CFTypeRef cf);
 static void SecCertificateDestroy(CFTypeRef cf);
 static bool derDateGetAbsoluteTime(const DERItem *dateChoice,
     CFAbsoluteTime *absTime);
 
 /* Static functions. */
-static CFStringRef SecCertificateDescribe(CFTypeRef cf) {
+static CF_RETURNS_RETAINED CFStringRef SecCertificateDescribe(CFTypeRef cf) {
     SecCertificateRef certificate = (SecCertificateRef)cf;
     CFStringRef subject = SecCertificateCopySubjectSummary(certificate);
     CFStringRef issuer = SecCertificateCopyIssuerSummary(certificate);
     SecCertificateRef certificate = (SecCertificateRef)cf;
     CFStringRef subject = SecCertificateCopySubjectSummary(certificate);
     CFStringRef issuer = SecCertificateCopyIssuerSummary(certificate);
@@ -366,7 +377,7 @@ static OSStatus parseGeneralNamesContent(const DERItem *generalNamesContent,
                        return status;
        }
     require_quiet(drtn == DR_EndOfSequence, badDER);
                        return status;
        }
     require_quiet(drtn == DR_EndOfSequence, badDER);
-       return noErr;
+       return errSecSuccess;
 
 badDER:
        return errSecInvalidCertificate;
 
 badDER:
        return errSecInvalidCertificate;
@@ -472,7 +483,7 @@ static OSStatus parseGeneralNameContentProperty(DERTag tag,
                goto badDER;
                break;
        }
                goto badDER;
                break;
        }
-       return noErr;
+       return errSecSuccess;
 badDER:
        return errSecInvalidCertificate;
 }
 badDER:
        return errSecInvalidCertificate;
 }
@@ -508,7 +519,7 @@ static OSStatus parseGeneralNamesContent(const DERItem *generalNamesContent,
     }
        *count = generalNamesCount;
        *name = generalNames;
     }
        *count = generalNamesCount;
        *name = generalNames;
-       return noErr;
+       return errSecSuccess;
 
 badDER:
        if (generalNames)
 
 badDER:
        if (generalNames)
@@ -524,7 +535,7 @@ static OSStatus parseGeneralNames(const DERItem *generalNames,
     require_quiet(generalNamesContent.tag == ASN1_CONSTR_SEQUENCE,
         badDER);
     parseGeneralNamesContent(&generalNamesContent.content, count, name);
     require_quiet(generalNamesContent.tag == ASN1_CONSTR_SEQUENCE,
         badDER);
     parseGeneralNamesContent(&generalNamesContent.content, count, name);
-    return noErr;
+    return errSecSuccess;
 badDER:
        return errSecInvalidCertificate;
 }
 badDER:
        return errSecInvalidCertificate;
 }
@@ -559,7 +570,7 @@ static OSStatus parseRDNContent(const DERItem *rdnSetContent, void *context,
        }
        require_quiet(drtn == DR_EndOfSequence, badDER);
 
        }
        require_quiet(drtn == DR_EndOfSequence, badDER);
 
-       return noErr;
+       return errSecSuccess;
 badDER:
        return errSecInvalidCertificate;
 }
 badDER:
        return errSecInvalidCertificate;
 }
@@ -579,7 +590,7 @@ static OSStatus parseX501NameContent(const DERItem *x501NameContent, void *conte
        }
        require_quiet(drtn == DR_EndOfSequence, badDER);
 
        }
        require_quiet(drtn == DR_EndOfSequence, badDER);
 
-       return noErr;
+       return errSecSuccess;
 
 badDER:
        return errSecInvalidCertificate;
 
 badDER:
        return errSecInvalidCertificate;
@@ -1005,7 +1016,7 @@ static void SecCEPAuthorityInfoAccess(SecCertificateRef certificate,
         }
         default:
             secdebug("cert", "bad general name for id-ad-ocsp AccessDescription t: 0x%02x v: %.*s",
         }
         default:
             secdebug("cert", "bad general name for id-ad-ocsp AccessDescription t: 0x%02x v: %.*s",
-                generalNameContent.tag, generalNameContent.content.length, generalNameContent.content.data);
+                generalNameContent.tag, (int) generalNameContent.content.length, generalNameContent.content.data);
             goto badDER;
             break;
         }
             goto badDER;
             break;
         }
@@ -1016,6 +1027,48 @@ badDER:
     secdebug("cert", "failed to parse Authority Information Access extension");
 }
 
     secdebug("cert", "failed to parse Authority Information Access extension");
 }
 
+/* Apple Worldwide Developer Relations Certificate Authority subject name.
+ * This is a DER sequence with the leading tag and length bytes removed,
+ * to match what tbsCert.issuer contains.
+ */
+static const unsigned char Apple_WWDR_CA_Subject_Name[]={
+                 0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,
+  0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0A,0x41,0x70,0x70,0x6C,0x65,
+  0x20,0x49,0x6E,0x63,0x2E,0x31,0x2C,0x30,0x2A,0x06,0x03,0x55,0x04,0x0B,0x0C,0x23,
+  0x41,0x70,0x70,0x6C,0x65,0x20,0x57,0x6F,0x72,0x6C,0x64,0x77,0x69,0x64,0x65,0x20,
+  0x44,0x65,0x76,0x65,0x6C,0x6F,0x70,0x65,0x72,0x20,0x52,0x65,0x6C,0x61,0x74,0x69,
+  0x6F,0x6E,0x73,0x31,0x44,0x30,0x42,0x06,0x03,0x55,0x04,0x03,0x0C,0x3B,0x41,0x70,
+  0x70,0x6C,0x65,0x20,0x57,0x6F,0x72,0x6C,0x64,0x77,0x69,0x64,0x65,0x20,0x44,0x65,
+  0x76,0x65,0x6C,0x6F,0x70,0x65,0x72,0x20,0x52,0x65,0x6C,0x61,0x74,0x69,0x6F,0x6E,
+  0x73,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,
+  0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79
+};
+
+static void checkForMissingRevocationInfo(SecCertificateRef certificate) {
+       if (!certificate ||
+               certificate->_crlDistributionPoints ||
+               certificate->_ocspResponders) {
+               /* We already have an OCSP or CRL URI (or no cert) */
+               return;
+       }
+       /* Specify an appropriate OCSP responder if we recognize the issuer. */
+       CFURLRef url = NULL;
+       if (sizeof(Apple_WWDR_CA_Subject_Name) == certificate->_issuer.length &&
+               !memcmp(certificate->_issuer.data, Apple_WWDR_CA_Subject_Name,
+                               sizeof(Apple_WWDR_CA_Subject_Name))) {
+               const char *WWDR_OCSP_URI = "http://ocsp.apple.com/ocsp-wwdr01";
+               url = CFURLCreateWithBytes(kCFAllocatorDefault,
+                               (const UInt8*)WWDR_OCSP_URI, strlen(WWDR_OCSP_URI),
+                               kCFStringEncodingASCII, NULL);
+       }
+       if (url) {
+               CFMutableArrayRef *urls = &certificate->_ocspResponders;
+               *urls = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+               CFArrayAppendValue(*urls, url);
+               CFRelease(url);
+       }
+}
+
 static void SecCEPSubjectInfoAccess(SecCertificateRef certificate,
        const SecCertificateExtension *extn) {
        secdebug("cert", "critical: %s", extn->critical ? "yes" : "no");
 static void SecCEPSubjectInfoAccess(SecCertificateRef certificate,
        const SecCertificateExtension *extn) {
        secdebug("cert", "critical: %s", extn->critical ? "yes" : "no");
@@ -1031,6 +1084,12 @@ static void SecCEPEntrustVersInfo(SecCertificateRef certificate,
        secdebug("cert", "critical: %s", extn->critical ? "yes" : "no");
 }
 
        secdebug("cert", "critical: %s", extn->critical ? "yes" : "no");
 }
 
+static void SecCEPEscrowMarker(SecCertificateRef certificate,
+                               const SecCertificateExtension *extn) {
+       secdebug("cert", "critical: %s", extn->critical ? "yes" : "no");
+}
+
+
 /* Dictionary key callback for comparing to DERItems. */
 static Boolean SecDERItemEqual(const void *value1, const void *value2) {
        return DEROidCompare((const DERItem *)value1, (const DERItem *)value2);
 /* Dictionary key callback for comparing to DERItems. */
 static Boolean SecDERItemEqual(const void *value1, const void *value2) {
        return DEROidCompare((const DERItem *)value1, (const DERItem *)value2);
@@ -1092,7 +1151,8 @@ static void SecCertificateRegisterClass(void) {
                &oidAuthorityInfoAccess,
                &oidSubjectInfoAccess,
                &oidNetscapeCertType,
                &oidAuthorityInfoAccess,
                &oidSubjectInfoAccess,
                &oidNetscapeCertType,
-               &oidEntrustVersInfo
+               &oidEntrustVersInfo,
+        &oidApplePolicyEscrowService
        };
        static const void *extnParsers[] = {
                SecCEPSubjectKeyIdentifier,
        };
        static const void *extnParsers[] = {
                SecCEPSubjectKeyIdentifier,
@@ -1111,10 +1171,11 @@ static void SecCertificateRegisterClass(void) {
                SecCEPAuthorityInfoAccess,
                SecCEPSubjectInfoAccess,
                SecCEPNetscapeCertType,
                SecCEPAuthorityInfoAccess,
                SecCEPSubjectInfoAccess,
                SecCEPNetscapeCertType,
-               SecCEPEntrustVersInfo
+               SecCEPEntrustVersInfo,
+        SecCEPEscrowMarker,
        };
        gExtensionParsers = CFDictionaryCreate(kCFAllocatorDefault, extnOIDs,
        };
        gExtensionParsers = CFDictionaryCreate(kCFAllocatorDefault, extnOIDs,
-               extnParsers, sizeof(extnOIDs) / sizeof(*extnOIDs),
+               extnParsers, array_size(extnOIDs),
                &SecDERItemKeyCallBacks, NULL);
 }
 
                &SecDERItemKeyCallBacks, NULL);
 }
 
@@ -1315,6 +1376,16 @@ badDER:
     return NULL;
 }
 
     return NULL;
 }
 
+CFDataRef SecDistinguishedNameCopyNormalizedContent(CFDataRef distinguished_name)
+{
+    const DERItem name = { (unsigned char *)CFDataGetBytePtr(distinguished_name), CFDataGetLength(distinguished_name) };
+    DERDecodedInfo content;
+    /* Decode top level sequence into DERItem */
+    if (!DERDecodeItem(&name, &content) && (content.tag == ASN1_CONSTR_SEQUENCE))
+        return createNormalizedX501Name(kCFAllocatorDefault, &content.content);
+    return NULL;
+}
+
 /* AUDIT[securityd]:
    certificate->_der is a caller provided data of any length (might be 0).
 
 /* AUDIT[securityd]:
    certificate->_der is a caller provided data of any length (might be 0).
 
@@ -1325,11 +1396,12 @@ static bool SecCertificateParse(SecCertificateRef certificate)
        DERReturn drtn;
 
     check(certificate);
        DERReturn drtn;
 
     check(certificate);
+    require_quiet(certificate, badCert);
     CFAllocatorRef allocator = CFGetAllocator(certificate);
 
        /* top level decode */
        DERSignedCertCrl signedCert;
     CFAllocatorRef allocator = CFGetAllocator(certificate);
 
        /* top level decode */
        DERSignedCertCrl signedCert;
-       drtn = DERParseSequence(&certificate->_der, DERNumSignedCertCrlItemSpecs, 
+       drtn = DERParseSequence(&certificate->_der, DERNumSignedCertCrlItemSpecs,
                DERSignedCertCrlItemSpecs, &signedCert,
                sizeof(signedCert));
        require_noerr_quiet(drtn, badCert);
                DERSignedCertCrlItemSpecs, &signedCert,
                sizeof(signedCert));
        require_noerr_quiet(drtn, badCert);
@@ -1338,7 +1410,7 @@ static bool SecCertificateParse(SecCertificateRef certificate)
 
        /* decode the TBSCert - it was saved in full DER form */
     DERTBSCert tbsCert;
 
        /* decode the TBSCert - it was saved in full DER form */
     DERTBSCert tbsCert;
-       drtn = DERParseSequence(&signedCert.tbs, 
+       drtn = DERParseSequence(&signedCert.tbs,
                DERNumTBSCertItemSpecs, DERTBSCertItemSpecs,
                &tbsCert, sizeof(tbsCert));
        require_noerr_quiet(drtn, badCert);
                DERNumTBSCertItemSpecs, DERTBSCertItemSpecs,
                &tbsCert, sizeof(tbsCert));
        require_noerr_quiet(drtn, badCert);
@@ -1478,7 +1550,7 @@ static bool SecCertificateParse(SecCertificateRef certificate)
         }
         require_quiet(drtn == DR_EndOfSequence, badCert);
 
         }
         require_quiet(drtn == DR_EndOfSequence, badCert);
 
-        /* Put some upper limit on the number of extentions allowed. */
+        /* Put some upper limit on the number of extensions allowed. */
         require_quiet(extensionCount < 10000, badCert);
         certificate->_extensionCount = extensionCount;
         certificate->_extensions =
         require_quiet(extensionCount < 10000, badCert);
         certificate->_extensionCount = extensionCount;
         certificate->_extensions =
@@ -1515,8 +1587,9 @@ static bool SecCertificateParse(SecCertificateRef certificate)
                        } else {
                                secdebug("cert", "Found unknown non critical extension");
                        }
                        } else {
                                secdebug("cert", "Found unknown non critical extension");
                        }
-        }
-    }
+               }
+       }
+       checkForMissingRevocationInfo(certificate);
 
        return true;
 
 
        return true;
 
@@ -1637,7 +1710,7 @@ const UInt8 *SecCertificateGetBytePtr(SecCertificateRef certificate) {
 
 CFStringRef SecDERItemCopyOIDDecimalRepresentation(CFAllocatorRef allocator,
     const DERItem *oid) {
 
 CFStringRef SecDERItemCopyOIDDecimalRepresentation(CFAllocatorRef allocator,
     const DERItem *oid) {
-       
+
        if (oid->length == 0) {
         return SecCopyCertString(SEC_NULL_KEY);
     }
        if (oid->length == 0) {
         return SecCopyCertString(SEC_NULL_KEY);
     }
@@ -1668,7 +1741,7 @@ CFStringRef SecDERItemCopyOIDDecimalRepresentation(CFAllocatorRef allocator,
         /* A max number of 20 values is allowed. */
                if (!(oid->data[x] & 0x80))
                {
         /* A max number of 20 values is allowed. */
                if (!(oid->data[x] & 0x80))
                {
-            CFStringAppendFormat(result, NULL, CFSTR(".%lu"), value);
+            CFStringAppendFormat(result, NULL, CFSTR(".%" PRIu32), value);
                        value = 0;
                }
        }
                        value = 0;
                }
        }
@@ -1684,7 +1757,7 @@ static CFStringRef copyLocalizedOidDescription(CFAllocatorRef allocator,
     /* Build the key we use to lookup the localized OID description. */
     CFMutableStringRef oidKey = CFStringCreateMutable(allocator,
         oid->length * 3 + 5);
     /* Build the key we use to lookup the localized OID description. */
     CFMutableStringRef oidKey = CFStringCreateMutable(allocator,
         oid->length * 3 + 5);
-    CFStringAppendFormat(oidKey, NULL, CFSTR("06 %02X"), oid->length);
+    CFStringAppendFormat(oidKey, NULL, CFSTR("06 %02lX"), oid->length);
     DERSize ix;
     for (ix = 0; ix < oid->length; ++ix)
         CFStringAppendFormat(oidKey, NULL, CFSTR(" %02X"), oid->data[ix]);
     DERSize ix;
     for (ix = 0; ix < oid->length; ++ix)
         CFStringAppendFormat(oidKey, NULL, CFSTR(" %02X"), oid->data[ix]);
@@ -1896,7 +1969,7 @@ CFAbsoluteTime SecAbsoluteTimeFromDateContent(DERTag tag, const uint8_t *bytes,
 
     secdebug("dateparse",
         "date %.*s year: %04d%02d%02d%02d%02d%02d%+05g",
 
     secdebug("dateparse",
         "date %.*s year: %04d%02d%02d%02d%02d%02d%+05g",
-        length, bytes, year, month,
+        (int) length, bytes, year, month,
         day, hour, minute, second,
         timeZoneOffset / 60);
 
         day, hour, minute, second,
         timeZoneOffset / 60);
 
@@ -2046,7 +2119,7 @@ static void appendURLProperty(CFMutableArrayRef properties,
     CFStringRef label, const DERItem *url) {
        DERDecodedInfo decoded;
        DERReturn drtn;
     CFStringRef label, const DERItem *url) {
        DERDecodedInfo decoded;
        DERReturn drtn;
-       
+
        drtn = DERDecodeItem(url, &decoded);
     if (drtn || decoded.tag != ASN1_IA5_STRING) {
                appendInvalidProperty(properties, label, url);
        drtn = DERDecodeItem(url, &decoded);
     if (drtn || decoded.tag != ASN1_IA5_STRING) {
                appendInvalidProperty(properties, label, url);
@@ -2067,7 +2140,7 @@ static void appendOIDProperty(CFMutableArrayRef properties,
 static void appendAlgorithmProperty(CFMutableArrayRef properties,
     CFStringRef label, const DERAlgorithmId *algorithm) {
     CFMutableArrayRef alg_props =
 static void appendAlgorithmProperty(CFMutableArrayRef properties,
     CFStringRef label, const DERAlgorithmId *algorithm) {
     CFMutableArrayRef alg_props =
-        CFArrayCreateMutable(CFGetAllocator(properties), 0, 
+        CFArrayCreateMutable(CFGetAllocator(properties), 0,
             &kCFTypeArrayCallBacks);
     appendOIDProperty(alg_props, SEC_ALGORITHM_KEY, NULL, &algorithm->oid);
     if (algorithm->params.length) {
             &kCFTypeArrayCallBacks);
     appendOIDProperty(alg_props, SEC_ALGORITHM_KEY, NULL, &algorithm->oid);
     if (algorithm->params.length) {
@@ -2166,7 +2239,7 @@ static CFStringRef copyIntegerContentDescription(CFAllocatorRef allocator,
        const DERItem *integer) {
        uint64_t value = 0;
        CFIndex ix, length = integer->length;
        const DERItem *integer) {
        uint64_t value = 0;
        CFIndex ix, length = integer->length;
-       
+
        if (length == 0 || length > 8)
                return copyHexDescription(allocator, integer);
 
        if (length == 0 || length > 8)
                return copyHexDescription(allocator, integer);
 
@@ -2232,7 +2305,7 @@ static CFStringRef copyDERThingDescription(CFAllocatorRef allocator,
        const DERItem *derThing, bool printableOnly) {
        DERDecodedInfo decoded;
        DERReturn drtn;
        const DERItem *derThing, bool printableOnly) {
        DERDecodedInfo decoded;
        DERReturn drtn;
-       
+
        drtn = DERDecodeItem(derThing, &decoded);
     if (drtn) {
         /* TODO: Perhaps put something in the label saying we couldn't parse
        drtn = DERDecodeItem(derThing, &decoded);
     if (drtn) {
         /* TODO: Perhaps put something in the label saying we couldn't parse
@@ -2292,7 +2365,7 @@ static OSStatus appendRDNProperty(void *context, const DERItem *rdnType,
     appendDERThingProperty(properties, label, localizedLabel, rdnValue);
     CFRelease(label);
     CFRelease(localizedLabel);
     appendDERThingProperty(properties, label, localizedLabel, rdnValue);
     CFRelease(label);
     CFRelease(localizedLabel);
-    return noErr;
+    return errSecSuccess;
 }
 
 static CFArrayRef createPropertiesForRDNContent(CFAllocatorRef allocator,
 }
 
 static CFArrayRef createPropertiesForRDNContent(CFAllocatorRef allocator,
@@ -2305,13 +2378,13 @@ static CFArrayRef createPropertiesForRDNContent(CFAllocatorRef allocator,
         CFArrayRemoveAllValues(properties);
                appendInvalidProperty(properties, SEC_RDN_KEY, rdnSetContent);
        }
         CFArrayRemoveAllValues(properties);
                appendInvalidProperty(properties, SEC_RDN_KEY, rdnSetContent);
        }
-       
+
        return properties;
 }
 
 /*
     From rfc3739 - 3.1.2.  Subject
        return properties;
 }
 
 /*
     From rfc3739 - 3.1.2.  Subject
-    
+
     When parsing the subject here are some tips for a short name of the cert.
       Choice   I:  commonName
       Choice  II:  givenName
     When parsing the subject here are some tips for a short name of the cert.
       Choice   I:  commonName
       Choice  II:  givenName
@@ -2337,7 +2410,7 @@ static CFArrayRef createPropertiesForX501NameContent(CFAllocatorRef allocator,
         CFArrayRemoveAllValues(properties);
         appendInvalidProperty(properties, SEC_X501_NAME_KEY, x501NameContent);
        }
         CFArrayRemoveAllValues(properties);
         appendInvalidProperty(properties, SEC_X501_NAME_KEY, x501NameContent);
        }
-       
+
        return properties;
 }
 
        return properties;
 }
 
@@ -2350,7 +2423,7 @@ static CFArrayRef createPropertiesForX501Name(CFAllocatorRef allocator,
         CFArrayRemoveAllValues(properties);
         appendInvalidProperty(properties, SEC_X501_NAME_KEY, x501Name);
        }
         CFArrayRemoveAllValues(properties);
         appendInvalidProperty(properties, SEC_X501_NAME_KEY, x501Name);
        }
-       
+
        return properties;
 }
 
        return properties;
 }
 
@@ -2525,7 +2598,7 @@ static void appendKeyUsage(CFMutableArrayRef properties,
         SEC_DECIPHER_ONLY_KEY
     };
     appendBitStringNames(properties, SEC_USAGE_KEY, extnValue,
         SEC_DECIPHER_ONLY_KEY
     };
     appendBitStringNames(properties, SEC_USAGE_KEY, extnValue,
-        usageNames, sizeof(usageNames) / sizeof(*usageNames));
+        usageNames, array_size(usageNames));
 }
 #endif
 
 }
 #endif
 
@@ -2815,7 +2888,7 @@ static void appendCrlDistributionPoints(CFMutableArrayRef properties,
             };
             appendBitStringContentNames(properties, SEC_REASONS_KEY,
                 &dp.reasons,
             };
             appendBitStringContentNames(properties, SEC_REASONS_KEY,
                 &dp.reasons,
-                reasonNames, sizeof(reasonNames) / sizeof(*reasonNames));
+                reasonNames, array_size(reasonNames));
         }
         if (dp.cRLIssuer.length) {
             CFMutableArrayRef crlIssuer = CFArrayCreateMutable(allocator, 0,
         }
         if (dp.cRLIssuer.length) {
             CFMutableArrayRef crlIssuer = CFArrayCreateMutable(allocator, 0,
@@ -3132,7 +3205,7 @@ static void appendNetscapeCertType(CFMutableArrayRef properties,
         SEC_OBJECT_SIGNING_CA_KEY
     };
     appendBitStringNames(properties, SEC_USAGE_KEY, extnValue,
         SEC_OBJECT_SIGNING_CA_KEY
     };
     appendBitStringNames(properties, SEC_USAGE_KEY, extnValue,
-        certTypes, sizeof(certTypes) / sizeof(*certTypes));
+        certTypes, array_size(certTypes));
 }
 
 #if 0
 }
 
 #if 0
@@ -3140,12 +3213,12 @@ static void appendEntrustVersInfo(CFMutableArrayRef properties,
     const DERItem *extnValue) {
 }
 
     const DERItem *extnValue) {
 }
 
-/* 
- * The list of Qualified Cert Statement statementIds we understand, even though 
- * we don't actually do anything with them; if these are found in a Qualified 
+/*
+ * The list of Qualified Cert Statement statementIds we understand, even though
+ * we don't actually do anything with them; if these are found in a Qualified
  * Cert Statement that's critical, we can truthfully say "yes we understand this".
  */
  * Cert Statement that's critical, we can truthfully say "yes we understand this".
  */
-static const CSSM_OID_PTR knownQualifiedCertStatements[] = 
+static const CSSM_OID_PTR knownQualifiedCertStatements[] =
 {
     /* id-qcs := { id-pkix 11 } */
        (const CSSM_OID_PTR)&CSSMOID_OID_QCS_SYNTAX_V1, /* id-qcs 1 */
 {
     /* id-qcs := { id-pkix 11 } */
        (const CSSM_OID_PTR)&CSSMOID_OID_QCS_SYNTAX_V1, /* id-qcs 1 */
@@ -3434,7 +3507,7 @@ static OSStatus obtainSummaryFromX501Name(void *context,
         CFReleaseSafe(string);
     }
 
         CFReleaseSafe(string);
     }
 
-       return noErr;
+       return errSecSuccess;
 }
 
 CFStringRef SecCertificateCopySubjectSummary(SecCertificateRef certificate) {
 }
 
 CFStringRef SecCertificateCopySubjectSummary(SecCertificateRef certificate) {
@@ -3752,11 +3825,11 @@ OSStatus SecCertificateIsSignedBy(SecCertificateRef certificate,
         certificate->_tbs.data, certificate->_tbs.length,
         certificate->_signature.data, certificate->_signature.length);
        if (status) {
         certificate->_tbs.data, certificate->_tbs.length,
         certificate->_signature.data, certificate->_signature.length);
        if (status) {
-               secdebug("verify", "signature verify failed: %d", status);
+               secdebug("verify", "signature verify failed: %" PRIdOSStatus, status);
                return errSecNotSigner;
        }
 
                return errSecNotSigner;
        }
 
-    return noErr;
+    return errSecSuccess;
 }
 
 #if 0
 }
 
 #if 0
@@ -3822,7 +3895,7 @@ static OSStatus SecCertificateIsIssuedBy(SecCertificateRef certificate,
                return errSecNotSigner;
        }
 
                return errSecNotSigner;
        }
 
-    return noErr;
+    return errSecSuccess;
 }
 
 static OSStatus _SecCertificateSetParent(SecCertificateRef certificate,
 }
 
 static OSStatus _SecCertificateSetParent(SecCertificateRef certificate,
@@ -3838,7 +3911,7 @@ static OSStatus _SecCertificateSetParent(SecCertificateRef certificate,
     OSStatus status = SecCertificateIsIssuedBy(certificate, issuer,
         signatureCheckOnly);
 #else
     OSStatus status = SecCertificateIsIssuedBy(certificate, issuer,
         signatureCheckOnly);
 #else
-       OSStatus status = noErr;
+       OSStatus status = errSecSuccess;
 #endif
     if (!status) {
         if (CFEqual(certificate, issuer)) {
 #endif
     if (!status) {
         if (CFEqual(certificate, issuer)) {
@@ -3846,7 +3919,7 @@ static OSStatus _SecCertificateSetParent(SecCertificateRef certificate,
                however we do record that we are properly self signed. */
             certificate->_isSelfSigned = kSecSelfSignedTrue;
             secdebug("cert", "set self as parent");
                however we do record that we are properly self signed. */
             certificate->_isSelfSigned = kSecSelfSignedTrue;
             secdebug("cert", "set self as parent");
-            return noErr;
+            return errSecSuccess;
         }
 
         CFRetain(issuer);
         }
 
         CFRetain(issuer);
@@ -3859,7 +3932,7 @@ static OSStatus _SecCertificateSetParent(SecCertificateRef certificate,
 
 static bool SecCertificateIsSelfSigned(SecCertificateRef certificate) {
     if (certificate->_isSelfSigned == kSecSelfSignedUnknown) {
 
 static bool SecCertificateIsSelfSigned(SecCertificateRef certificate) {
     if (certificate->_isSelfSigned == kSecSelfSignedUnknown) {
-        certificate->_isSelfSigned = 
+        certificate->_isSelfSigned =
             (SecCertificateIsIssuedBy(certificate, certificate, false) ?
              kSecSelfSignedTrue : kSecSelfSignedFalse);
     }
             (SecCertificateIsIssuedBy(certificate, certificate, false) ?
              kSecSelfSignedTrue : kSecSelfSignedFalse);
     }
@@ -3928,7 +4001,7 @@ OSStatus SecCertificateCompleteChain(SecCertificateRef certificate,
     for (;;) {
         if (certificate->_parent == NULL) {
             if (SecCertificateIsSelfSigned(certificate))
     for (;;) {
         if (certificate->_parent == NULL) {
             if (SecCertificateIsSelfSigned(certificate))
-                return noErr;
+                return errSecSuccess;
             if (!other_certificates ||
                 !SecCertificateSetParentFrom(certificate, other_certificates,\
                     false)) {
             if (!other_certificates ||
                 !SecCertificateSetParentFrom(certificate, other_certificates,\
                     false)) {
@@ -3954,7 +4027,7 @@ static OSStatus appendIPAddressesFromGeneralNames(void *context,
                        return errSecInvalidCertificate;
                }
        }
                        return errSecInvalidCertificate;
                }
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 CFArrayRef SecCertificateCopyIPAddresses(SecCertificateRef certificate) {
 }
 
 CFArrayRef SecCertificateCopyIPAddresses(SecCertificateRef certificate) {
@@ -3987,7 +4060,7 @@ static OSStatus appendDNSNamesFromGeneralNames(void *context, SecCEGeneralNameTy
                        return errSecInvalidCertificate;
                }
        }
                        return errSecInvalidCertificate;
                }
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 /* Return true if the passed in string matches the
 }
 
 /* Return true if the passed in string matches the
@@ -4089,7 +4162,7 @@ static OSStatus appendDNSNamesFromX501Name(void *context, const DERItem *type,
                        return errSecInvalidCertificate;
                }
        }
                        return errSecInvalidCertificate;
                }
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 /* Not everything returned by this function is going to be a proper DNS name,
 }
 
 /* Not everything returned by this function is going to be a proper DNS name,
@@ -4099,7 +4172,7 @@ CFArrayRef SecCertificateCopyDNSNames(SecCertificateRef certificate) {
        /* These can exist in the subject alt name or in the subject. */
        CFMutableArrayRef dnsNames = CFArrayCreateMutable(kCFAllocatorDefault,
                0, &kCFTypeArrayCallBacks);
        /* These can exist in the subject alt name or in the subject. */
        CFMutableArrayRef dnsNames = CFArrayCreateMutable(kCFAllocatorDefault,
                0, &kCFTypeArrayCallBacks);
-       OSStatus status = noErr;
+       OSStatus status = errSecSuccess;
        if (certificate->_subjectAltName) {
                status = parseGeneralNames(&certificate->_subjectAltName->extnValue,
                        dnsNames, appendDNSNamesFromGeneralNames);
        if (certificate->_subjectAltName) {
                status = parseGeneralNames(&certificate->_subjectAltName->extnValue,
                        dnsNames, appendDNSNamesFromGeneralNames);
@@ -4142,7 +4215,7 @@ static OSStatus appendRFC822NamesFromGeneralNames(void *context,
                        return errSecInvalidCertificate;
                }
        }
                        return errSecInvalidCertificate;
                }
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 static OSStatus appendRFC822NamesFromX501Name(void *context, const DERItem *type,
 }
 
 static OSStatus appendRFC822NamesFromX501Name(void *context, const DERItem *type,
@@ -4158,14 +4231,14 @@ static OSStatus appendRFC822NamesFromX501Name(void *context, const DERItem *type
                        return errSecInvalidCertificate;
                }
        }
                        return errSecInvalidCertificate;
                }
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 CFArrayRef SecCertificateCopyRFC822Names(SecCertificateRef certificate) {
        /* These can exist in the subject alt name or in the subject. */
        CFMutableArrayRef rfc822Names = CFArrayCreateMutable(kCFAllocatorDefault,
                0, &kCFTypeArrayCallBacks);
 }
 
 CFArrayRef SecCertificateCopyRFC822Names(SecCertificateRef certificate) {
        /* These can exist in the subject alt name or in the subject. */
        CFMutableArrayRef rfc822Names = CFArrayCreateMutable(kCFAllocatorDefault,
                0, &kCFTypeArrayCallBacks);
-       OSStatus status = noErr;
+       OSStatus status = errSecSuccess;
        if (certificate->_subjectAltName) {
                status = parseGeneralNames(&certificate->_subjectAltName->extnValue,
                        rfc822Names, appendRFC822NamesFromGeneralNames);
        if (certificate->_subjectAltName) {
                status = parseGeneralNames(&certificate->_subjectAltName->extnValue,
                        rfc822Names, appendRFC822NamesFromGeneralNames);
@@ -4194,7 +4267,7 @@ static OSStatus appendCommonNamesFromX501Name(void *context,
                        return errSecInvalidCertificate;
                }
        }
                        return errSecInvalidCertificate;
                }
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 CFArrayRef SecCertificateCopyCommonNames(SecCertificateRef certificate) {
 }
 
 CFArrayRef SecCertificateCopyCommonNames(SecCertificateRef certificate) {
@@ -4223,7 +4296,7 @@ static OSStatus appendOrganizationFromX501Name(void *context,
                        return errSecInvalidCertificate;
                }
        }
                        return errSecInvalidCertificate;
                }
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 CFArrayRef SecCertificateCopyOrganization(SecCertificateRef certificate) {
 }
 
 CFArrayRef SecCertificateCopyOrganization(SecCertificateRef certificate) {
@@ -4239,6 +4312,35 @@ CFArrayRef SecCertificateCopyOrganization(SecCertificateRef certificate) {
        return organization;
 }
 
        return organization;
 }
 
+static OSStatus appendOrganizationalUnitFromX501Name(void *context,
+       const DERItem *type, const DERItem *value, CFIndex rdnIX) {
+       CFMutableArrayRef organizationalUnit = (CFMutableArrayRef)context;
+       if (DEROidCompare(type, &oidOrganizationalUnitName)) {
+               CFStringRef string = copyDERThingDescription(kCFAllocatorDefault,
+                       value, true);
+               if (string) {
+                       CFArrayAppendValue(organizationalUnit, string);
+                       CFRelease(string);
+               } else {
+                       return errSecInvalidCertificate;
+               }
+       }
+       return errSecSuccess;
+}
+
+CFArrayRef SecCertificateCopyOrganizationalUnit(SecCertificateRef certificate) {
+       CFMutableArrayRef organizationalUnit = CFArrayCreateMutable(kCFAllocatorDefault,
+               0, &kCFTypeArrayCallBacks);
+       OSStatus status;
+       status = parseX501NameContent(&certificate->_subject, organizationalUnit,
+        appendOrganizationalUnitFromX501Name);
+       if (status || CFArrayGetCount(organizationalUnit) == 0) {
+               CFRelease(organizationalUnit);
+               organizationalUnit = NULL;
+       }
+       return organizationalUnit;
+}
+
 const SecCEBasicConstraints *
 SecCertificateGetBasicConstraints(SecCertificateRef certificate) {
        if (certificate->_basicConstraints.present)
 const SecCEBasicConstraints *
 SecCertificateGetBasicConstraints(SecCertificateRef certificate) {
        if (certificate->_basicConstraints.present)
@@ -4290,7 +4392,7 @@ static OSStatus appendNTPrincipalNamesFromGeneralNames(void *context,
             CFRelease(string);
                }
        }
             CFRelease(string);
                }
        }
-       return noErr;
+       return errSecSuccess;
 
 badDER:
     return errSecInvalidCertificate;
 
 badDER:
     return errSecInvalidCertificate;
@@ -4300,7 +4402,7 @@ badDER:
 CFArrayRef SecCertificateCopyNTPrincipalNames(SecCertificateRef certificate) {
        CFMutableArrayRef ntPrincipalNames = CFArrayCreateMutable(kCFAllocatorDefault,
                0, &kCFTypeArrayCallBacks);
 CFArrayRef SecCertificateCopyNTPrincipalNames(SecCertificateRef certificate) {
        CFMutableArrayRef ntPrincipalNames = CFArrayCreateMutable(kCFAllocatorDefault,
                0, &kCFTypeArrayCallBacks);
-       OSStatus status = noErr;
+       OSStatus status = errSecSuccess;
        if (certificate->_subjectAltName) {
                status = parseGeneralNames(&certificate->_subjectAltName->extnValue,
                        ntPrincipalNames, appendNTPrincipalNamesFromGeneralNames);
        if (certificate->_subjectAltName) {
                status = parseGeneralNames(&certificate->_subjectAltName->extnValue,
                        ntPrincipalNames, appendNTPrincipalNamesFromGeneralNames);
@@ -4402,7 +4504,7 @@ static OSStatus appendToRFC2253String(void *context,
 
     CFReleaseSafe(oid);
 
 
     CFReleaseSafe(oid);
 
-       return noErr;
+       return errSecSuccess;
 }
 
 CFStringRef SecCertificateCopySubjectString(SecCertificateRef certificate) {
 }
 
 CFStringRef SecCertificateCopySubjectString(SecCertificateRef certificate) {
@@ -4419,19 +4521,19 @@ static OSStatus appendToCompanyNameString(void *context,
        const DERItem *type, const DERItem *value, CFIndex rdnIX) {
        CFMutableStringRef string = (CFMutableStringRef)context;
     if (CFStringGetLength(string) != 0)
        const DERItem *type, const DERItem *value, CFIndex rdnIX) {
        CFMutableStringRef string = (CFMutableStringRef)context;
     if (CFStringGetLength(string) != 0)
-        return noErr;
+        return errSecSuccess;
 
     if (!DEROidCompare(type, &oidOrganizationName))
 
     if (!DEROidCompare(type, &oidOrganizationName))
-        return noErr;
+        return errSecSuccess;
 
     CFStringRef raw;
     raw = copyDERThingDescription(kCFAllocatorDefault, value, true);
     if (!raw)
 
     CFStringRef raw;
     raw = copyDERThingDescription(kCFAllocatorDefault, value, true);
     if (!raw)
-        return noErr;
+        return errSecSuccess;
     CFStringAppend(string, raw);
     CFRelease(raw);
 
     CFStringAppend(string, raw);
     CFRelease(raw);
 
-       return noErr;
+       return errSecSuccess;
 }
 
 CFStringRef SecCertificateCopyCompanyName(SecCertificateRef certificate) {
 }
 
 CFStringRef SecCertificateCopyCompanyName(SecCertificateRef certificate) {
@@ -4569,7 +4671,7 @@ bool SecCertificateHasCriticalSubjectAltName(SecCertificateRef certificate) {
 }
 
 bool SecCertificateHasSubject(SecCertificateRef certificate) {
 }
 
 bool SecCertificateHasSubject(SecCertificateRef certificate) {
-       /* Since the _subject field is the content of the subject and not the 
+       /* Since the _subject field is the content of the subject and not the
           whole thing, we can simply check for a 0 length subject here. */
        return certificate->_subject.length != 0;
 }
           whole thing, we can simply check for a 0 length subject here. */
        return certificate->_subject.length != 0;
 }
@@ -4644,7 +4746,7 @@ SecCertificateRef SecCertificateCreateFromAttributeDictionary(
        /* @@@ Support having an allocator in refAttributes. */
        CFAllocatorRef allocator = NULL;
        CFDataRef data = CFDictionaryGetValue(refAttributes, kSecValueData);
        /* @@@ Support having an allocator in refAttributes. */
        CFAllocatorRef allocator = NULL;
        CFDataRef data = CFDictionaryGetValue(refAttributes, kSecValueData);
-       return SecCertificateCreateWithData(allocator, data);
+       return data ? SecCertificateCreateWithData(allocator, data) : NULL;
 }
 #endif
 
 }
 #endif
 
@@ -4658,19 +4760,19 @@ bool SecCertificateIsSelfSignedCA(SecCertificateRef certificate) {
         SecCertificateGetNormalizedSubjectContent(certificate);
     require_quiet(normalizedIssuer && normalizedSubject &&
         CFEqual(normalizedIssuer, normalizedSubject), out);
         SecCertificateGetNormalizedSubjectContent(certificate);
     require_quiet(normalizedIssuer && normalizedSubject &&
         CFEqual(normalizedIssuer, normalizedSubject), out);
-    
+
     CFDataRef authorityKeyID = SecCertificateGetAuthorityKeyID(certificate);
     CFDataRef subjectKeyID = SecCertificateGetSubjectKeyID(certificate);
     if (authorityKeyID) {
         require_quiet(subjectKeyID && CFEqual(subjectKeyID, authorityKeyID), out);
     }
     CFDataRef authorityKeyID = SecCertificateGetAuthorityKeyID(certificate);
     CFDataRef subjectKeyID = SecCertificateGetSubjectKeyID(certificate);
     if (authorityKeyID) {
         require_quiet(subjectKeyID && CFEqual(subjectKeyID, authorityKeyID), out);
     }
-    
+
     if (SecCertificateVersion(certificate) >= 3) {
         const SecCEBasicConstraints *basicConstraints = SecCertificateGetBasicConstraints(certificate);
         require_quiet(basicConstraints && basicConstraints->isCA, out);
         require_noerr_quiet(SecCertificateIsSignedBy(certificate, publicKey), out);
     }
     if (SecCertificateVersion(certificate) >= 3) {
         const SecCEBasicConstraints *basicConstraints = SecCertificateGetBasicConstraints(certificate);
         require_quiet(basicConstraints && basicConstraints->isCA, out);
         require_noerr_quiet(SecCertificateIsSignedBy(certificate, publicKey), out);
     }
-    
+
     result = true;
 out:
     CFReleaseSafe(publicKey);
     result = true;
 out:
     CFReleaseSafe(publicKey);
@@ -4683,7 +4785,7 @@ SecKeyUsage SecCertificateGetKeyUsage(SecCertificateRef certificate) {
 
 CFArrayRef SecCertificateCopyExtendedKeyUsage(SecCertificateRef certificate)
 {
 
 CFArrayRef SecCertificateCopyExtendedKeyUsage(SecCertificateRef certificate)
 {
-    CFMutableArrayRef extended_key_usage_oids = 
+    CFMutableArrayRef extended_key_usage_oids =
         CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
     require_quiet(extended_key_usage_oids, out);
     int ix;
         CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
     require_quiet(extended_key_usage_oids, out);
     int ix;
@@ -4697,10 +4799,10 @@ CFArrayRef SecCertificateCopyExtendedKeyUsage(SecCertificateRef certificate)
             require_noerr_quiet(drtn, out);
             require_quiet(tag == ASN1_CONSTR_SEQUENCE, out);
             DERDecodedInfo currDecoded;
             require_noerr_quiet(drtn, out);
             require_quiet(tag == ASN1_CONSTR_SEQUENCE, out);
             DERDecodedInfo currDecoded;
-            
+
             while ((drtn = DERDecodeSeqNext(&derSeq, &currDecoded)) == DR_Success) {
                 require_quiet(currDecoded.tag == ASN1_OBJECT_ID, out);
             while ((drtn = DERDecodeSeqNext(&derSeq, &currDecoded)) == DR_Success) {
                 require_quiet(currDecoded.tag == ASN1_OBJECT_ID, out);
-                CFDataRef oid = CFDataCreate(kCFAllocatorDefault, 
+                CFDataRef oid = CFDataCreate(kCFAllocatorDefault,
                     currDecoded.content.data, currDecoded.content.length);
                 if (oid) {
                     CFArrayAppendValue(extended_key_usage_oids, oid);
                     currDecoded.content.data, currDecoded.content.length);
                 if (oid) {
                     CFArrayAppendValue(extended_key_usage_oids, oid);
@@ -4716,7 +4818,70 @@ out:
     return NULL;
 }
 
     return NULL;
 }
 
-static bool cert_contains_marker_extension(SecCertificateRef certificate, CFDataRef oid)
+static bool matches_expected(DERItem der, CFTypeRef expected) {
+    if (der.length > 1) {
+        DERDecodedInfo decoded;
+        DERDecodeItem(&der, &decoded);
+        switch (decoded.tag) {
+            case ASN1_NULL:
+            {
+                return decoded.content.length == 0 && expected == NULL;
+            }
+            break;
+                
+            case ASN1_UTF8_STRING: {
+                if (isString(expected)) {
+                    CFStringRef expectedString = (CFStringRef) expected;
+                    CFStringRef itemString = CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, decoded.content.data, decoded.content.length, kCFStringEncodingUTF8, false, kCFAllocatorNull);
+
+                    bool result = (kCFCompareEqualTo == CFStringCompare(expectedString, itemString, 0));
+                    CFReleaseNull(itemString);
+                    return result;
+                }
+            }
+            break;
+                
+            case ASN1_OCTET_STRING: {
+                if (isData(expected)) {
+                    CFDataRef expectedData = (CFDataRef) expected;
+                    CFDataRef itemData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, decoded.content.data, decoded.content.length, kCFAllocatorNull);
+
+                    bool result = CFEqual(expectedData, itemData);
+                    CFReleaseNull(itemData);
+                    return result;
+                }
+            }
+            break;
+                
+            case ASN1_INTEGER: {
+                SInt32 expected_value = 0;
+                if (isString(expected))
+                {
+                    CFStringRef aStr = (CFStringRef)expected;
+                    expected_value = CFStringGetIntValue(aStr);
+                }
+                else if (isNumber(expected))
+                {
+                    CFNumberGetValue(expected, kCFNumberSInt32Type, &expected_value);
+                }
+                
+                uint32_t num_value = 0;
+                if (!DERParseInteger(&decoded.content, &num_value))
+                {
+                    return ((uint32_t)expected_value == num_value);
+                }
+            }
+            break;
+                
+            default:
+                break;
+        }
+    }
+
+    return false;
+}
+
+static bool cert_contains_marker_extension_value(SecCertificateRef certificate, CFDataRef oid, CFTypeRef expectedValue)
 {
     CFIndex ix;
     const uint8_t *oid_data = CFDataGetBytePtr(oid);
 {
     CFIndex ix;
     const uint8_t *oid_data = CFDataGetBytePtr(oid);
@@ -4727,22 +4892,162 @@ static bool cert_contains_marker_extension(SecCertificateRef certificate, CFData
         if (extn->extnID.length == oid_len
             && !memcmp(extn->extnID.data, oid_data, extn->extnID.length))
         {
         if (extn->extnID.length == oid_len
             && !memcmp(extn->extnID.data, oid_data, extn->extnID.length))
         {
-            if ((extn->extnValue.length == 2) && (*extn->extnValue.data == ASN1_NULL))
-                return true;
+                       return matches_expected(extn->extnValue, expectedValue);
         }
     }
     return false;
 }
 
         }
     }
     return false;
 }
 
+static bool cert_contains_marker_extension(SecCertificateRef certificate, CFTypeRef oid)
+{
+    return cert_contains_marker_extension_value(certificate, oid, NULL);
+}
+
+struct search_context {
+    bool found;
+    SecCertificateRef certificate;
+};
+
+static bool GetDecimalValueOfString(CFStringRef string, uint32_t* value)
+{
+    CFCharacterSetRef nonDecimalDigit = CFCharacterSetCreateInvertedSet(NULL, CFCharacterSetGetPredefined(kCFCharacterSetDecimalDigit));
+    bool result = false;
+
+    if ( CFStringGetLength(string) > 0
+      && !CFStringFindCharacterFromSet(string, nonDecimalDigit, CFRangeMake(0, CFStringGetLength(string)), kCFCompareForcedOrdering, NULL))
+    {
+        if (value)
+            *value = CFStringGetIntValue(string);
+        result = true;
+    }
+
+    CFReleaseNull(nonDecimalDigit);
+
+    return result;
+}
+
+static CFDataRef CreateOidDataFromString(CFAllocatorRef allocator, CFStringRef string)
+{
+    CFMutableDataRef currentResult = NULL;
+    CFDataRef encodedResult = NULL;
+    
+    CFArrayRef parts = NULL;
+    CFIndex count = 0;
+
+    if (!string)
+        goto exit;
+
+    parts = CFStringCreateArrayBySeparatingStrings(NULL, string, CFSTR("."));
+
+    if (!parts)
+        goto exit;
+
+    count = CFArrayGetCount(parts);
+    if (count == 0)
+        goto exit;
+
+    // assume no more than 5 bytes needed to represent any part of the oid,
+    // since we limit parts to 32-bit values,
+    // but the first two parts only need 1 byte
+    currentResult = CFDataCreateMutable(allocator, 1+(count-2)*5);
+
+    CFStringRef part;
+    uint32_t x;
+    uint8_t firstByte;
+
+    part = CFArrayGetValueAtIndex(parts, 0);
+
+    if (!GetDecimalValueOfString(part, &x) || x > 6)
+        goto exit;
+
+    firstByte = x * 40;
+
+
+    if (count > 1) {
+        part = CFArrayGetValueAtIndex(parts, 1);
+
+        if (!GetDecimalValueOfString(part, &x) || x > 39)
+            goto exit;
+
+        firstByte += x;
+    }
+
+    CFDataAppendBytes(currentResult, &firstByte, 1);
+
+    for (CFIndex i = 2; i < count && GetDecimalValueOfString(CFArrayGetValueAtIndex(parts, i), &x); ++i) {
+        uint8_t b[5] = {0, 0, 0, 0, 0};
+        b[4] = (x & 0x7F);
+        b[3] = 0x80 | ((x >> 7) & 0x7F);
+        b[2] = 0x80 | ((x >> 14) & 0x7F);
+        b[1] = 0x80 | ((x >> 21) & 0x7F);
+        b[0] = 0x80 | ((x >> 28) & 0x7F);
+
+        // Skip the unused extension bytes.
+        size_t skipBytes = 0;
+        while (b[skipBytes] == 0x80)
+            ++skipBytes;
+
+        CFDataAppendBytes(currentResult, b + skipBytes, sizeof(b) - skipBytes);
+    }
+
+    encodedResult = currentResult;
+    currentResult = NULL;
+
+exit:
+    CFReleaseNull(parts);
+    CFReleaseNull(currentResult);
+
+    return encodedResult;
+}
+
+static void check_for_marker(const void *key, const void *value, void *context)
+{
+    struct search_context * search_ctx = (struct search_context *) context;
+    CFStringRef key_string = (CFStringRef) key;
+    CFTypeRef value_ref = (CFTypeRef) value;
+
+    // If we could have short circuted the iteration
+    // we would have, but the best we can do
+    // is not waste time comparing once a match
+    // was found.
+    if (search_ctx->found)
+        return;
+
+    if (CFGetTypeID(key_string) != CFStringGetTypeID())
+        return;
+
+    CFDataRef key_data = CreateOidDataFromString(NULL, key_string);
+
+    if (NULL == key_data)
+        return;
+
+    if (cert_contains_marker_extension_value(search_ctx->certificate, key_data, value_ref))
+        search_ctx->found = true;
+
+    CFReleaseNull(key_data);
+}
+
+//
+// CFType Ref is either:
+//
+// CFData - OID to match with no data permitted
+// CFDictionary - OID -> Value table for expected values Single Object or Array
+// CFArray - Array of the above.
+//
+// This returns true if any of the requirements are met.
 bool SecCertificateHasMarkerExtension(SecCertificateRef certificate, CFTypeRef oids)
 {
     if (CFGetTypeID(oids) == CFArrayGetTypeID()) {
         CFIndex ix, length = CFArrayGetCount(oids);
         for (ix = 0; ix < length; ix++)
 bool SecCertificateHasMarkerExtension(SecCertificateRef certificate, CFTypeRef oids)
 {
     if (CFGetTypeID(oids) == CFArrayGetTypeID()) {
         CFIndex ix, length = CFArrayGetCount(oids);
         for (ix = 0; ix < length; ix++)
-            if (cert_contains_marker_extension(certificate, (CFDataRef)CFArrayGetValueAtIndex(oids, ix)))
+            if (SecCertificateHasMarkerExtension(certificate, CFArrayGetValueAtIndex((CFArrayRef)oids, ix)))
                 return true;
                 return true;
+    } else if (CFGetTypeID(oids) == CFDictionaryGetTypeID()) {
+        struct search_context context = { .found = false, .certificate = certificate };
+        CFDictionaryApplyFunction((CFDictionaryRef) oids, &check_for_marker, &context);
+        return context.found;
     } else if (CFGetTypeID(oids) == CFDataGetTypeID()) {
     } else if (CFGetTypeID(oids) == CFDataGetTypeID()) {
-        return cert_contains_marker_extension(certificate, (CFDataRef)oids);
+        return cert_contains_marker_extension(certificate, oids);
     }
     return false;
 }
     }
     return false;
 }
@@ -4770,48 +5075,191 @@ SecCertificateRef SecCertificateCreateWithPEM(CFAllocatorRef allocator,
     }
 out:
     return cert;
     }
 out:
     return cert;
-}       
+}
 
 
-static void convertCertificateToCFData(const void *value, void *context) {
-    CFMutableArrayRef result = (CFMutableArrayRef)context;
-    SecCertificateRef certificate = (SecCertificateRef)value;
-    CFDataRef data = SecCertificateCopyData(certificate);
-    CFArrayAppendValue(result, data);
-    CFRelease(data);
+
+//
+// -- MARK -- XPC encoding/decoding
+//
+
+bool SecCertificateAppendToXPCArray(SecCertificateRef certificate, xpc_object_t xpc_certificates, CFErrorRef *error) {
+    if (!certificate)
+        return true; // NOOP
+    
+    size_t length = SecCertificateGetLength(certificate);
+    const uint8_t *bytes = SecCertificateGetBytePtr(certificate);
+    if (!length || !bytes)
+        return SecError(errSecParam, error, CFSTR("failed to der encode certificate"));
+
+    xpc_array_set_data(xpc_certificates, XPC_ARRAY_APPEND, bytes, length);
+    return true;
 }
 
 }
 
-/* Return an array of CFDataRefs from an array of SecCertificateRefs. */
-CFArrayRef SecCertificateArrayCopyDataArray(CFArrayRef certificates) {
-    CFIndex count = CFArrayGetCount(certificates);
-    CFMutableArrayRef result = CFArrayCreateMutable(kCFAllocatorDefault, count, &kCFTypeArrayCallBacks);
-    CFRange all_certs = { 0, count };
-    CFArrayApplyFunction(certificates, all_certs, convertCertificateToCFData, result);
-    return result;
+SecCertificateRef SecCertificateCreateWithXPCArrayAtIndex(xpc_object_t xpc_certificates, size_t index, CFErrorRef *error) {
+    SecCertificateRef certificate = NULL;
+    size_t length = 0;
+    const uint8_t *bytes = xpc_array_get_data(xpc_certificates, index, &length);
+    if (bytes) {
+        certificate = SecCertificateCreateWithBytes(kCFAllocatorDefault, bytes, length);
+    }
+    if (!certificate)
+        SecError(errSecParam, error, CFSTR("certificates[%zu] failed to decode"), index);
+    
+    return certificate;
 }
 
 }
 
-/* AUDIT[securityd](done):
-   value (ok) is an element in a caller provided array.
- */
-static void convertCFDataToCertificate(const void *value, void *context) {
-    CFMutableArrayRef result = (CFMutableArrayRef)context;
-    CFDataRef data = (CFDataRef)value;
-    if (data && CFGetTypeID(data) == CFDataGetTypeID()) {
-        SecCertificateRef certificate = SecCertificateCreateWithData(kCFAllocatorDefault, data);
-        if (certificate) {
-            CFArrayAppendValue(result, certificate);
-            CFRelease(certificate);
+xpc_object_t SecCertificateArrayCopyXPCArray(CFArrayRef certificates, CFErrorRef *error) {
+    xpc_object_t xpc_certificates;
+    require_action_quiet(xpc_certificates = xpc_array_create(NULL, 0), exit,
+                         SecError(errSecAllocate, error, CFSTR("failed to create xpc_array")));
+    CFIndex ix, count = CFArrayGetCount(certificates);
+    for (ix = 0; ix < count; ++ix) {
+        if (!SecCertificateAppendToXPCArray((SecCertificateRef)CFArrayGetValueAtIndex(certificates, ix), xpc_certificates, error)) {
+            xpc_release(xpc_certificates);
+            return NULL;
+        }
+    }
+
+exit:
+    return xpc_certificates;
+}
+
+CFArrayRef SecCertificateXPCArrayCopyArray(xpc_object_t xpc_certificates, CFErrorRef *error) {
+    CFMutableArrayRef certificates = NULL;
+    require_action_quiet(xpc_get_type(xpc_certificates) == XPC_TYPE_ARRAY, exit,
+                         SecError(errSecParam, error, CFSTR("certificates xpc value is not an array")));
+    size_t count = xpc_array_get_count(xpc_certificates);
+    require_action_quiet(certificates = CFArrayCreateMutable(kCFAllocatorDefault, count, &kCFTypeArrayCallBacks), exit,
+                         SecError(errSecAllocate, error, CFSTR("failed to create CFArray of capacity %zu"), count));
+
+    size_t ix;
+    for (ix = 0; ix < count; ++ix) {
+        SecCertificateRef cert = SecCertificateCreateWithXPCArrayAtIndex(xpc_certificates, ix, error);
+        if (!cert) {
+            CFRelease(certificates);
+            return NULL;
         }
         }
+        CFArraySetValueAtIndex(certificates, ix, cert);
+        CFRelease(cert);
     }
     }
+
+exit:
+    return certificates;
 }
 
 }
 
-/* AUDIT[securityd](done):
-   certificates (ok) is a caller provided array, only its cf type has
-   been checked.
- */
-CFArrayRef SecCertificateDataArrayCopyArray(CFArrayRef certificates) {
-    CFIndex count = CFArrayGetCount(certificates);
-    CFMutableArrayRef result = CFArrayCreateMutable(NULL, count, &kCFTypeArrayCallBacks);
-    CFRange all_certs = { 0, count };
-    CFArrayApplyFunction(certificates, all_certs, convertCFDataToCertificate, result);
-    return result;
+#define do_if_registered(sdp, ...) if (gSecurityd && gSecurityd->sdp) { return gSecurityd->sdp(__VA_ARGS__); }
+
+
+static CFArrayRef CopyEscrowCertificates(CFErrorRef* error)
+{
+       __block CFArrayRef result = NULL;
+       
+       do_if_registered(ota_CopyEscrowCertificates, error);
+       
+       securityd_send_sync_and_do(kSecXPCOpOTAGetEscrowCertificates, error, NULL, 
+               ^bool(xpc_object_t response, CFErrorRef *error) 
+               {
+               xpc_object_t xpc_array = xpc_dictionary_get_value(response, kSecXPCKeyResult);
+
+               if (response && (NULL != xpc_array)) 
+                       {
+                   result = (CFArrayRef)_CFXPCCreateCFObjectFromXPCObject(xpc_array);
+               }
+                       else
+                       {
+                       return SecError(errSecInternal, error, CFSTR("Did not get the Escrow certificates"));
+                       }
+               return result != NULL;
+       });
+       return result;
+}
+
+CFArrayRef SecCertificateCopyEscrowRoots(SecCertificateEscrowRootType escrowRootType)
+{
+    CFArrayRef result = NULL;
+       int iCnt;
+       CFDataRef certData = NULL;
+    int numRoots = 0;
+
+       // The request is for the base line certificates.  
+       // Use the hard coded data to generate the return array
+       if (kSecCertificateBaselineEscrowRoot == escrowRootType)
+       {
+               // Get the hard coded set of roots
+               numRoots = kNumberOfBaseLineEscrowRoots;
+           SecCertificateRef baseLineCerts[numRoots];
+           struct RootRecord* pRootRecord = NULL;
+           
+           for (iCnt = 0; iCnt < numRoots; iCnt++)
+           {
+               pRootRecord = kBaseLineEscrowRoots[iCnt];
+               if (NULL != pRootRecord && pRootRecord->_length > 0 && NULL != pRootRecord->_bytes)
+               {
+                               certData = CFDataCreate(kCFAllocatorDefault, pRootRecord->_bytes, pRootRecord->_length);
+                               if (NULL != certData)
+                               {
+                                       baseLineCerts[iCnt] = SecCertificateCreateWithData(kCFAllocatorDefault, certData);
+                                       CFRelease(certData);
+                               }
+               }
+           }
+               result = CFArrayCreate(kCFAllocatorDefault, (const void **)baseLineCerts, numRoots, &kCFTypeArrayCallBacks);
+               for (iCnt = 0; iCnt < numRoots; iCnt++)
+               {
+                       if (NULL != baseLineCerts[iCnt])
+                       {
+                               CFRelease(baseLineCerts[iCnt]); 
+                       }
+               }
+       }
+       // The request is for the current certificates.  
+       else if (kSecCertificateProductionEscrowRoot == escrowRootType)
+       {
+               CFErrorRef error = NULL;
+               CFArrayRef cert_datas = CopyEscrowCertificates(&error);
+               if (NULL != error || NULL == cert_datas)
+               {
+                       if (NULL != error)
+                       {
+                               CFRelease(error);
+                       }
+                       
+                       if (NULL != cert_datas)
+                       {
+                               CFRelease(cert_datas);
+                       }
+                       return result;
+               }
+               
+        numRoots = (int)(CFArrayGetCount(cert_datas));
+
+               SecCertificateRef assetCerts[numRoots];
+               for (iCnt = 0; iCnt < numRoots; iCnt++)
+               {
+                       certData = (CFDataRef)CFArrayGetValueAtIndex(cert_datas, iCnt);
+                       if (NULL != certData)
+                       {
+                               SecCertificateRef aCertRef = SecCertificateCreateWithData(kCFAllocatorDefault, certData);
+                               assetCerts[iCnt] = aCertRef;            
+                       }
+                       else
+                       {
+                               assetCerts[iCnt] = NULL;
+                       }
+               }
+               
+               if (numRoots > 0)
+               {
+                       result = CFArrayCreate(kCFAllocatorDefault, (const void **)assetCerts, numRoots, &kCFTypeArrayCallBacks);
+                       for (iCnt = 0; iCnt < numRoots; iCnt++)
+                       {
+                               if (NULL != assetCerts[iCnt])
+                               {
+                                       CFRelease(assetCerts[iCnt]);    
+                               }
+                       }
+               }
+               CFReleaseSafe(cert_datas);
+       }
+       return result;
 }
 }
index da35eebe42df3f33259763a3121b2eab021c0f56..74a683f27ad2d64cf784d64fb7136ec61634ac64 100644 (file)
@@ -37,9 +37,7 @@
 #include <Security/SecBase.h>
 #include <CoreFoundation/CFData.h>
 
 #include <Security/SecBase.h>
 #include <CoreFoundation/CFData.h>
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 /*!
        @function SecCertificateGetTypeID
 
 /*!
        @function SecCertificateGetTypeID
@@ -84,8 +82,6 @@ CFDataRef SecCertificateCopyData(SecCertificateRef certificate)
 CFStringRef SecCertificateCopySubjectSummary(SecCertificateRef certificate)
     __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
 
 CFStringRef SecCertificateCopySubjectSummary(SecCertificateRef certificate)
     __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
 
-#if defined(__cplusplus)
-}
-#endif
+__END_DECLS
 
 #endif /* !_SECURITY_SECCERTIFICATE_H_ */
 
 #endif /* !_SECURITY_SECCERTIFICATE_H_ */
index c41d100ce64fb61a9881a1ff6a99293070673068..11f7a8ff6fad72770464eae54ab37ddd1248f728 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2007-2010 Apple Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2007-2012 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -32,9 +32,7 @@
 #include <Security/certextensions.h>
 #include <libDER/DER_Keys.h>
 
 #include <Security/certextensions.h>
 #include <libDER/DER_Keys.h>
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 CFDataRef SecCertificateGetAuthorityKeyID(SecCertificateRef certificate);
 CFDataRef SecCertificateGetSubjectKeyID(SecCertificateRef certificate);
 
 CFDataRef SecCertificateGetAuthorityKeyID(SecCertificateRef certificate);
 CFDataRef SecCertificateGetSubjectKeyID(SecCertificateRef certificate);
@@ -68,6 +66,9 @@ CFDataRef SecCertificateGetNormalizedIssuerContent(SecCertificateRef certificate
    fields) for the receiving certificates subject. */
 CFDataRef SecCertificateGetNormalizedSubjectContent(SecCertificateRef certificate);
 
    fields) for the receiving certificates subject. */
 CFDataRef SecCertificateGetNormalizedSubjectContent(SecCertificateRef certificate);
 
+/* Return the normalized name or NULL if it fails to parse */
+CFDataRef SecDistinguishedNameCopyNormalizedContent(CFDataRef distinguished_name);
+
 /* Return true iff the certificate has a subject. */
 bool SecCertificateHasSubject(SecCertificateRef certificate);
 /* Return true iff the certificate has a critical subject alt name. */
 /* Return true iff the certificate has a subject. */
 bool SecCertificateHasSubject(SecCertificateRef certificate);
 /* Return true iff the certificate has a critical subject alt name. */
@@ -126,14 +127,14 @@ const DERAlgorithmId *SecCertificateGetPublicKeyAlgorithm(
 /* Return the raw public key data for certificate.  */
 const DERItem *SecCertificateGetPublicKeyData(SecCertificateRef certificate);
 
 /* Return the raw public key data for certificate.  */
 const DERItem *SecCertificateGetPublicKeyData(SecCertificateRef certificate);
 
-#pragma mark -
-#pragma mark Certificate Operations
+// MARK: -
+// MARK: Certificate Operations
 
 OSStatus SecCertificateIsSignedBy(SecCertificateRef certificate,
     SecKeyRef issuerKey);
 
 
 OSStatus SecCertificateIsSignedBy(SecCertificateRef certificate,
     SecKeyRef issuerKey);
 
-#pragma mark -
-#pragma mark Certificate Creation
+// MARK: -
+// MARK: Certificate Creation
 
 #ifdef OPTIONAL_METHODS
 /* Return a certificate for the PEM representation of this certificate.
 
 #ifdef OPTIONAL_METHODS
 /* Return a certificate for the PEM representation of this certificate.
@@ -303,8 +304,6 @@ CFAbsoluteTime SecAbsoluteTimeFromDateContent(DERTag tag, const uint8_t *bytes,
 
 bool SecCertificateHasMarkerExtension(SecCertificateRef certificate, CFTypeRef oid);
 
 
 bool SecCertificateHasMarkerExtension(SecCertificateRef certificate, CFTypeRef oid);
 
-#if defined(__cplusplus)
-}
-#endif
+__END_DECLS
 
 #endif /* !_SECURITY_SECCERTIFICATEINTERNAL_H_ */
 
 #endif /* !_SECURITY_SECCERTIFICATEINTERNAL_H_ */
index a88d9897de8ac7a9149443fd0608065a50be368e..2b46451abb073df2efa8009a3af0efc3334e6abd 100644 (file)
@@ -32,6 +32,7 @@
 #include <Security/SecItem.h>
 #include <Security/SecCertificateInternal.h>
 #include <Security/SecFramework.h>
 #include <Security/SecItem.h>
 #include <Security/SecCertificateInternal.h>
 #include <Security/SecFramework.h>
+#include <utilities/SecIOFormat.h>
 #include <CoreFoundation/CFRuntime.h>
 #include <CoreFoundation/CFSet.h>
 #include <CoreFoundation/CFString.h>
 #include <CoreFoundation/CFRuntime.h>
 #include <CoreFoundation/CFSet.h>
 #include <CoreFoundation/CFString.h>
 #include <string.h>
 #include <stdlib.h>
 #include <pthread.h>
 #include <string.h>
 #include <stdlib.h>
 #include <pthread.h>
-#include <MacErrors.h>
+#include <Security/SecBase.h>
 #include "SecRSAKey.h"
 #include <libDER/oids.h>
 #include "SecRSAKey.h"
 #include <libDER/oids.h>
-#include <security_utilities/debugging.h>
+#include <utilities/debugging.h>
 #include <Security/SecInternal.h>
 #include <Security/SecInternal.h>
+#include <AssertMacros.h>
+#include <utilities/SecCFError.h>
 
 
-#pragma mark -
-#pragma mark SecCertificatePath
+// MARK: -
+// MARK: SecCertificatePath
 /********************************************************
  ************* SecCertificatePath object ****************
  ********************************************************/
 /********************************************************
  ************* SecCertificatePath object ****************
  ********************************************************/
@@ -117,12 +120,12 @@ static CFHashCode SecCertificatePathHash(CFTypeRef cf) {
        return hashCode;
 }
 
        return hashCode;
 }
 
-static CFStringRef SecCertificatePathDescribe(CFTypeRef cf) {
+static CFStringRef SecCertificateCopyPathDescription(CFTypeRef cf) {
        SecCertificatePathRef certificatePath = (SecCertificatePathRef) cf;
     CFMutableStringRef desc = CFStringCreateMutable(kCFAllocatorDefault, 0);
     CFStringRef typeStr = CFCopyTypeIDDescription(CFGetTypeID(cf));
     CFStringAppendFormat(desc, NULL,
        SecCertificatePathRef certificatePath = (SecCertificatePathRef) cf;
     CFMutableStringRef desc = CFStringCreateMutable(kCFAllocatorDefault, 0);
     CFStringRef typeStr = CFCopyTypeIDDescription(CFGetTypeID(cf));
     CFStringAppendFormat(desc, NULL,
-        CFSTR("<%@ lvs: %d certs: "), typeStr,
+        CFSTR("<%@ lvs: %" PRIdCFIndex " certs: "), typeStr,
         certificatePath->lastVerifiedSigner);
     CFRelease(typeStr);
     CFIndex ix;
         certificatePath->lastVerifiedSigner);
     CFRelease(typeStr);
     CFIndex ix;
@@ -149,7 +152,7 @@ static void SecCertificatePathRegisterClass(void) {
                SecCertificatePathEqual,                                                /* equal */
                SecCertificatePathHash,                                                 /* hash */
                NULL,                                                                                   /* copyFormattingDesc */
                SecCertificatePathEqual,                                                /* equal */
                SecCertificatePathHash,                                                 /* hash */
                NULL,                                                                                   /* copyFormattingDesc */
-               SecCertificatePathDescribe                                              /* copyDebugDesc */
+               SecCertificateCopyPathDescription                               /* copyDebugDesc */
        };
 
     kSecCertificatePathTypeID =
        };
 
     kSecCertificatePathTypeID =
@@ -203,21 +206,20 @@ SecCertificatePathRef SecCertificatePathCreate(SecCertificatePathRef path,
                CFRetain(result->certificates[ix]);
        }
        result->certificates[count - 1] = certificate;
                CFRetain(result->certificates[ix]);
        }
        result->certificates[count - 1] = certificate;
-       CFRetain(certificate);
+       CFRetainSafe(certificate);
 
     return result;
 }
 
 
     return result;
 }
 
-/* Create a new certificate path from an array of CFDataRefs. */
-SecCertificatePathRef SecCertificatePathCreateWithArray(CFArrayRef certificates) {
-       CFIndex count = CFArrayGetCount(certificates);
-    CFIndex size = sizeof(struct SecCertificatePath) +
-               count * sizeof(SecCertificateRef);
-    SecCertificatePathRef result =
-               (SecCertificatePathRef)_CFRuntimeCreateInstance(kCFAllocatorDefault,
-               SecCertificatePathGetTypeID(), size - sizeof(CFRuntimeBase), 0);
-       if (!result)
-        return NULL;
+/* Create a new certificate path from an xpc_array of data. */
+SecCertificatePathRef SecCertificatePathCreateWithXPCArray(xpc_object_t xpc_path, CFErrorRef *error) {
+    SecCertificatePathRef result = NULL;
+    require_action_quiet(xpc_path, exit, SecError(errSecParam, error, CFSTR("xpc_path is NULL")));
+    require_action_quiet(xpc_get_type(xpc_path) == XPC_TYPE_ARRAY, exit, SecError(errSecDecode, error, CFSTR("xpc_path value is not an array")));
+    size_t count;
+    require_action_quiet(count = xpc_array_get_count(xpc_path), exit, SecError(errSecDecode, error, CFSTR("xpc_path array count == 0")));
+    size_t size = sizeof(struct SecCertificatePath) + count * sizeof(SecCertificateRef);
+    require_action_quiet(result = (SecCertificatePathRef)_CFRuntimeCreateInstance(kCFAllocatorDefault, SecCertificatePathGetTypeID(), size - sizeof(CFRuntimeBase), 0), exit, SecError(errSecDecode, error, CFSTR("_CFRuntimeCreateInstance returned NULL")));
 
        result->count = count;
        result->nextParentSource = 0;
 
        result->count = count;
        result->nextParentSource = 0;
@@ -225,13 +227,19 @@ SecCertificatePathRef SecCertificatePathCreateWithArray(CFArrayRef certificates)
        result->selfIssued = -1;
        result->isSelfSigned = false;
        result->isAnchored = false;
        result->selfIssued = -1;
        result->isSelfSigned = false;
        result->isAnchored = false;
-       CFIndex ix;
+       size_t ix;
        for (ix = 0; ix < count; ++ix) {
        for (ix = 0; ix < count; ++ix) {
-        CFDataRef data = CFArrayGetValueAtIndex(certificates, ix);
-        SecCertificateRef certificate = SecCertificateCreateWithData(kCFAllocatorDefault, data);
-               result->certificates[ix] = certificate;
+        SecCertificateRef certificate = SecCertificateCreateWithXPCArrayAtIndex(xpc_path, ix, error);
+        if (certificate) {
+            result->certificates[ix] = certificate;
+        } else {
+            result->count = ix; // total allocated
+            CFReleaseNull(result);
+            break;
+        }
        }
 
        }
 
+exit:
     return result;
 }
 
     return result;
 }
 
@@ -323,16 +331,20 @@ SecCertificatePathRef SecCertificatePathCopyAddingLeaf(SecCertificatePathRef pat
 }
 
 /* Create an array of CFDataRefs from a certificate path. */
 }
 
 /* Create an array of CFDataRefs from a certificate path. */
-CFArrayRef SecCertificatePathCopyArray(SecCertificatePathRef path) {
-    CFIndex ix, count = path->count;
-    CFMutableArrayRef result = CFArrayCreateMutable(kCFAllocatorDefault, count,
-        &kCFTypeArrayCallBacks);
+xpc_object_t SecCertificatePathCopyXPCArray(SecCertificatePathRef path, CFErrorRef *error) {
+    xpc_object_t xpc_chain = NULL;
+    size_t ix, count = path->count;
+    require_action_quiet(xpc_chain = xpc_array_create(NULL, 0), exit, SecError(errSecParam, error, CFSTR("xpc_array_create failed")));
        for (ix = 0; ix < count; ++ix) {
        for (ix = 0; ix < count; ++ix) {
-        CFDataRef data = SecCertificateCopyData(path->certificates[ix]);
-        CFArrayAppendValue(result, data);
-        CFRelease(data);
-       }
-    return result;
+        SecCertificateRef cert = SecCertificatePathGetCertificateAtIndex(path, ix);
+        if (!SecCertificateAppendToXPCArray(cert, xpc_chain, error)) {
+            xpc_release(xpc_chain);
+            return NULL;
+        }
+    }
+
+exit:
+    return xpc_chain;
 }
 
 /* Record the fact that we found our own root cert as our parent
 }
 
 /* Record the fact that we found our own root cert as our parent
@@ -340,7 +352,7 @@ CFArrayRef SecCertificatePathCopyArray(SecCertificatePathRef path) {
 void SecCertificatePathSetSelfIssued(
        SecCertificatePathRef certificatePath) {
        if (certificatePath->selfIssued >= 0) {
 void SecCertificatePathSetSelfIssued(
        SecCertificatePathRef certificatePath) {
        if (certificatePath->selfIssued >= 0) {
-               secdebug("trust", "%@ is already issued at %d", certificatePath,
+               secdebug("trust", "%@ is already issued at %" PRIdCFIndex, certificatePath,
                        certificatePath->selfIssued);
                return;
        }
                        certificatePath->selfIssued);
                return;
        }
@@ -381,7 +393,7 @@ CFIndex SecCertificatePathGetNextSourceIndex(
 CFIndex SecCertificatePathGetCount(
        SecCertificatePathRef certificatePath) {
        check(certificatePath);
 CFIndex SecCertificatePathGetCount(
        SecCertificatePathRef certificatePath) {
        check(certificatePath);
-       return certificatePath->count;
+       return certificatePath ? certificatePath->count : 0;
 }
 
 SecCertificateRef SecCertificatePathGetCertificateAtIndex(
 }
 
 SecCertificateRef SecCertificatePathGetCertificateAtIndex(
@@ -460,6 +472,8 @@ SecKeyRef SecCertificatePathCopyPublicKeyAtIndex(
 SecPathVerifyStatus SecCertificatePathVerify(
        SecCertificatePathRef certificatePath) {
        check(certificatePath);
 SecPathVerifyStatus SecCertificatePathVerify(
        SecCertificatePathRef certificatePath) {
        check(certificatePath);
+    if (!certificatePath)
+        return kSecPathVerifyFailed;
        for (;
                certificatePath->lastVerifiedSigner < certificatePath->count - 1;
                ++certificatePath->lastVerifiedSigner) {
        for (;
                certificatePath->lastVerifiedSigner < certificatePath->count - 1;
                ++certificatePath->lastVerifiedSigner) {
@@ -523,7 +537,7 @@ CFIndex SecCertificatePathScore(
 
        /* Paths that don't verify score terribly. */
        if (certificatePath->lastVerifiedSigner != certificatePath->count - 1) {
 
        /* Paths that don't verify score terribly. */
        if (certificatePath->lastVerifiedSigner != certificatePath->count - 1) {
-               secdebug("trust", "lvs: %d count: %d",
+               secdebug("trust", "lvs: %" PRIdCFIndex " count: %" PRIdCFIndex,
                        certificatePath->lastVerifiedSigner, certificatePath->count);
                score -= 100000;
        }
                        certificatePath->lastVerifiedSigner, certificatePath->count);
                score -= 100000;
        }
index cccacb8bf615d1b6dcbff11cf318bccfab28325f..b102a05e1d1ff7f55bbfd59fefe9dfe3e9d69fa9 100644 (file)
 #include <CoreFoundation/CFArray.h>
 #include <CoreFoundation/CFDictionary.h>
 #include <CoreFoundation/CFDate.h>
 #include <CoreFoundation/CFArray.h>
 #include <CoreFoundation/CFDictionary.h>
 #include <CoreFoundation/CFDate.h>
+#include <CoreFoundation/CFError.h>
+#include <xpc/xpc.h>
 
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 typedef struct SecCertificatePath *SecCertificatePathRef;
 
 
 typedef struct SecCertificatePath *SecCertificatePathRef;
 
@@ -47,11 +47,11 @@ CFTypeID SecCertificatePathGetTypeID(void);
 SecCertificatePathRef SecCertificatePathCreate(SecCertificatePathRef path,
        SecCertificateRef certificate);
 
 SecCertificatePathRef SecCertificatePathCreate(SecCertificatePathRef path,
        SecCertificateRef certificate);
 
-/* Create a new certificate path from an array of CFDataRefs. */
-SecCertificatePathRef SecCertificatePathCreateWithArray(CFArrayRef certificates);
+/* Create a new certificate path from an xpc_array of datas. */
+SecCertificatePathRef SecCertificatePathCreateWithXPCArray(xpc_object_t xpc_path, CFErrorRef *error);
 
 /* Create an array of CFDataRefs from a certificate path. */
 
 /* Create an array of CFDataRefs from a certificate path. */
-CFArrayRef SecCertificatePathCopyArray(SecCertificatePathRef path);
+xpc_object_t SecCertificatePathCopyXPCArray(SecCertificatePathRef path, CFErrorRef *error);
 
 SecCertificatePathRef SecCertificatePathCopyAddingLeaf(SecCertificatePathRef path,
 SecCertificateRef leaf);
 
 SecCertificatePathRef SecCertificatePathCopyAddingLeaf(SecCertificatePathRef path,
 SecCertificateRef leaf);
@@ -119,8 +119,6 @@ CFIndex SecCertificatePathScore(SecCertificatePathRef certificatePath,
 Node based version is possible.  We need to make sure we extract algorithm oid and parameters in the chain.  When constructing a new path (with a new parent from a path with the child at it's head), we duplicate each child node for which we could not previously establish a public key because the parameters were missing and there was no cert with the same algorithm in the chain which does have parameters.  This is because, when extended with a different parent certificate that has different parameters for the childs algorithm, the signatures in the child chain must be reverified using the new parameters and therefore might yeild a different result.
 We could allow more sharing if we stored the parameters found in the search up the chain in each node, and only duplicate the nodes if the parameters differ and then reset the isSigned status of each node with changed parameters. */
 
 Node based version is possible.  We need to make sure we extract algorithm oid and parameters in the chain.  When constructing a new path (with a new parent from a path with the child at it's head), we duplicate each child node for which we could not previously establish a public key because the parameters were missing and there was no cert with the same algorithm in the chain which does have parameters.  This is because, when extended with a different parent certificate that has different parameters for the childs algorithm, the signatures in the child chain must be reverified using the new parameters and therefore might yeild a different result.
 We could allow more sharing if we stored the parameters found in the search up the chain in each node, and only duplicate the nodes if the parameters differ and then reset the isSigned status of each node with changed parameters. */
 
-#if defined(__cplusplus)
-}
-#endif
+__END_DECLS
 
 #endif /* !_SECURITY_SECCERTIFICATEPATH_H_ */
 
 #endif /* !_SECURITY_SECCERTIFICATEPATH_H_ */
index 93855003a92f730db31d178b8a339962a5cc0bed..77674ea733916946d307772e9a214f6a7854099a 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2006-2010 Apple Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2006-2012 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -27,7 +27,7 @@
        type of keychain item that represents a certificate.  You can store a
        certificate in a keychain, but a certificate can also be a transient
        object.
        type of keychain item that represents a certificate.  You can store a
        certificate in a keychain, but a certificate can also be a transient
        object.
-       
+
        You can use a certificate as a keychain item in most functions.
        Certificates are able to compute their parent certificates, and much more.
 */
        You can use a certificate as a keychain item in most functions.
        Certificates are able to compute their parent certificates, and much more.
 */
 #include <CoreFoundation/CFData.h>
 #include <CoreFoundation/CFDate.h>
 #include <CoreFoundation/CFDictionary.h>
 #include <CoreFoundation/CFData.h>
 #include <CoreFoundation/CFDate.h>
 #include <CoreFoundation/CFDictionary.h>
+#include <CoreFoundation/CFError.h>
 #include <stdbool.h>
 #include <stdbool.h>
+#include <xpc/xpc.h>
 
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 typedef uint32_t SecKeyUsage;
 enum {
 
 typedef uint32_t SecKeyUsage;
 enum {
@@ -63,6 +63,17 @@ enum {
     kSecKeyUsageAll              = 0x7FFFFFFF
 };
 
     kSecKeyUsageAll              = 0x7FFFFFFF
 };
 
+typedef uint32_t SecCertificateEscrowRootType;
+enum {
+    kSecCertificateBaselineEscrowRoot = 0,
+    kSecCertificateProductionEscrowRoot = 1,
+};
+
+/* The names of the files that contain the escrow certificates */
+extern CFTypeRef kSecCertificateProductionEscrowKey;
+extern CFTypeRef kSecCertificateEscrowFileName;
+
+
 /* Return a certificate for the DER representation of this certificate.
    Return NULL if the passed-in data is not a valid DER-encoded X.509
    certificate. */
 /* Return a certificate for the DER representation of this certificate.
    Return NULL if the passed-in data is not a valid DER-encoded X.509
    certificate. */
@@ -75,8 +86,8 @@ CFIndex SecCertificateGetLength(SecCertificateRef certificate);
 /* Return the bytes of the DER representation of this certificate. */
 const UInt8 *SecCertificateGetBytePtr(SecCertificateRef certificate);
 
 /* Return the bytes of the DER representation of this certificate. */
 const UInt8 *SecCertificateGetBytePtr(SecCertificateRef certificate);
 
-#pragma mark -
-#pragma mark Certificate Accessors
+// MARK: -
+// MARK: Certificate Accessors
 
 CFDataRef SecCertificateGetSHA1Digest(SecCertificateRef certificate);
 
 
 CFDataRef SecCertificateGetSHA1Digest(SecCertificateRef certificate);
 
@@ -134,6 +145,10 @@ CFArrayRef SecCertificateCopyCommonNames(SecCertificateRef certificate);
    certificate's subject if any. */
 CFArrayRef SecCertificateCopyOrganization(SecCertificateRef certificate);
 
    certificate's subject if any. */
 CFArrayRef SecCertificateCopyOrganization(SecCertificateRef certificate);
 
+/* Return an array of CFStringRefs representing the organizational unit in the
+   certificate's subject if any. */
+CFArrayRef SecCertificateCopyOrganizationalUnit(SecCertificateRef certificate);
+
 /* Return an array of CFStringRefs representing the NTPrincipalNames in the
    certificate if any. */
 CFArrayRef SecCertificateCopyNTPrincipalNames(SecCertificateRef certificate);
 /* Return an array of CFStringRefs representing the NTPrincipalNames in the
    certificate if any. */
 CFArrayRef SecCertificateCopyNTPrincipalNames(SecCertificateRef certificate);
@@ -163,15 +178,21 @@ CFArrayRef SecCertificateCopyExtendedKeyUsage(SecCertificateRef certificate);
 SecCertificateRef SecCertificateCreateWithPEM(CFAllocatorRef allocator,
        CFDataRef pem_certificate);
 
 SecCertificateRef SecCertificateCreateWithPEM(CFAllocatorRef allocator,
        CFDataRef pem_certificate);
 
-/* Return an array of CFDataRefs from an array of SecCertificateRefs. */
-CFArrayRef SecCertificateArrayCopyDataArray(CFArrayRef certificates);
+/* Append certificate to xpc_certificates. */
+bool SecCertificateAppendToXPCArray(SecCertificateRef certificate, xpc_object_t xpc_certificates, CFErrorRef *error);
+
+/* Decode certificate from xpc_certificates[index] as encoded by SecCertificateAppendToXPCArray(). */
+SecCertificateRef SecCertificateCreateWithXPCArrayAtIndex(xpc_object_t xpc_certificates, size_t index, CFErrorRef *error);
+
+/* Retrieve the array of valid Escrow certificates for a given root type */
+CFArrayRef SecCertificateCopyEscrowRoots(SecCertificateEscrowRootType escrowRootType);
 
 
-/* Return an array of SecCertificateRefs from an array of CFDataRefs. */
-CFArrayRef SecCertificateDataArrayCopyArray(CFArrayRef certificates);
+/* Return an xpc_array of data from an array of SecCertificateRefs. */
+xpc_object_t SecCertificateArrayCopyXPCArray(CFArrayRef certificates, CFErrorRef *error);
 
 
+/* Return an array of SecCertificateRefs from a xpc_object array of datas. */
+CFArrayRef SecCertificateXPCArrayCopyArray(xpc_object_t xpc_certificates, CFErrorRef *error);
 
 
-#if defined(__cplusplus)
-}
-#endif
+__END_DECLS
 
 #endif /* !_SECURITY_SECCERTIFICATEPRIV_H_ */
 
 #endif /* !_SECURITY_SECCERTIFICATEPRIV_H_ */
index d0001905264f8061ed2bb8118d502b9f3d0998e1..7f748f4f5b553b7685299554fcad34fb5b95d146 100644 (file)
@@ -51,6 +51,7 @@ OSStatus SecCmsArraySortByDER(void **objs, const SecAsn1Template *objtemplate, v
 #include <Security/SecRSAKey.h>
 #include <Security/SecKeyPriv.h>
 #include <CommonCrypto/CommonDigest.h>
 #include <Security/SecRSAKey.h>
 #include <Security/SecKeyPriv.h>
 #include <CommonCrypto/CommonDigest.h>
+#include <CommonCrypto/CommonDigestSPI.h>
 #include <CoreFoundation/CFNumber.h>
 #include <CoreFoundation/CFString.h>
 
 #include <CoreFoundation/CFNumber.h>
 #include <CoreFoundation/CFString.h>
 
@@ -70,22 +71,28 @@ CFTypeRef kSecOidOrganizationalUnit = CFSTR("OU");
 const unsigned char SecASN1PrintableString = SEC_ASN1_PRINTABLE_STRING;
 const unsigned char SecASN1UTF8String = SEC_ASN1_UTF8_STRING;
 
 const unsigned char SecASN1PrintableString = SEC_ASN1_PRINTABLE_STRING;
 const unsigned char SecASN1UTF8String = SEC_ASN1_UTF8_STRING;
 
-static void mod128_oid_encoding(CFMutableDataRef dst, uint32_t src, bool final)
+static uint8_t * mod128_oid_encoding_ptr(uint8_t *ptr, uint32_t src, bool final)
 {
     if (src > 128)
 {
     if (src > 128)
-        mod128_oid_encoding(dst, src / 128, false);
+        ptr = mod128_oid_encoding_ptr(ptr, src / 128, false);
     
     unsigned char octet = src % 128;
     if (!final)
         octet |= 128;
     
     unsigned char octet = src % 128;
     if (!final)
         octet |= 128;
-    CFDataAppendBytes(dst, &octet, 1);
+    *ptr++ = octet;
+
+    return ptr;
 }
 
 }
 
-static CFDataRef oid_der(CFStringRef oid_string)
+static uint8_t * oid_der_data(PRArenaPool *poolp, CFStringRef oid_string, size_t *oid_data_len)
 {
 {
-    CFMutableDataRef oid_der_data = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    /* estimate encoded length from base 10 (4 bits) to base 128 (7 bits) */
+    size_t tmp_oid_length = ((CFStringGetLength(oid_string) * 4) / 7) + 1;
+    uint8_t *tmp_oid_data = PORT_ArenaAlloc(poolp, tmp_oid_length);
+    uint8_t *tmp_oid_data_ptr = tmp_oid_data;
+
     CFArrayRef oid = CFStringCreateArrayBySeparatingStrings(kCFAllocatorDefault,
     CFArrayRef oid = CFStringCreateArrayBySeparatingStrings(kCFAllocatorDefault,
-        oid_string, CFSTR("."));
+                                                            oid_string, CFSTR("."));
     CFIndex i = 0, count = CFArrayGetCount(oid);
     SInt32 first_digit = 0, digit;
     for (i = 0; i < count; i++) {
     CFIndex i = 0, count = CFArrayGetCount(oid);
     SInt32 first_digit = 0, digit;
     for (i = 0; i < count; i++) {
@@ -99,16 +106,18 @@ static CFDataRef oid_der(CFStringRef oid_string)
                 digit = 40 * first_digit + oid_octet_int_value;
             else
                 digit = oid_octet_int_value;
                 digit = 40 * first_digit + oid_octet_int_value;
             else
                 digit = oid_octet_int_value;
-            mod128_oid_encoding(oid_der_data, digit, true);
+            tmp_oid_data_ptr = mod128_oid_encoding_ptr(tmp_oid_data_ptr, digit, true);
         }
     }
     CFReleaseSafe(oid);
         }
     }
     CFReleaseSafe(oid);
-    return oid_der_data;
+
+    *oid_data_len = tmp_oid_data_ptr - tmp_oid_data;
+    return tmp_oid_data;
 out:
 out:
-    CFReleaseSafe(oid_der_data);
     return NULL;
 }
 
     return NULL;
 }
 
+
 /*
 Get challenge password conversion and apply this:
 
 /*
 Get challenge password conversion and apply this:
 
@@ -190,13 +199,8 @@ static bool make_nss_atv(PRArenaPool *poolp,
         } else if (CFEqual(kSecOidOrganizationalUnit, oid)) {
             oid_length = oidOrganizationalUnitName.length; oid_data = oidOrganizationalUnitName.data;
         } else {
         } else if (CFEqual(kSecOidOrganizationalUnit, oid)) {
             oid_length = oidOrganizationalUnitName.length; oid_data = oidOrganizationalUnitName.data;
         } else {
-            CFDataRef oid_der_data = oid_der(oid);
-            require(oid_der_data, out);
-            oid_length = CFDataGetLength(oid_der_data);
-            oid_data = PORT_ArenaAlloc(poolp, oid_length);
-            require(oid_length && oid_data, out);
-            memcpy(oid_data, CFDataGetBytePtr(oid_der_data), oid_length);
-            CFReleaseSafe(oid_der_data);
+            oid_data = oid_der_data(poolp, oid, &oid_length);
+            require(oid_data, out);
         }
     } else if (CFGetTypeID(oid) == CFDataGetTypeID()) {
         /* will remain valid for the duration of the operation, still maybe copy into pool */
         }
     } else if (CFGetTypeID(oid) == CFDataGetTypeID()) {
         /* will remain valid for the duration of the operation, still maybe copy into pool */
@@ -395,6 +399,7 @@ CFTypeRef kSecCSRChallengePassword = CFSTR("csrChallengePassword");
 CFTypeRef kSecSubjectAltName = CFSTR("subjectAltName");
 CFTypeRef kSecCertificateKeyUsage = CFSTR("keyUsage");
 CFTypeRef kSecCSRBasicContraintsPathLen = CFSTR("basicConstraints");
 CFTypeRef kSecSubjectAltName = CFSTR("subjectAltName");
 CFTypeRef kSecCertificateKeyUsage = CFSTR("keyUsage");
 CFTypeRef kSecCSRBasicContraintsPathLen = CFSTR("basicConstraints");
+CFTypeRef kSecCertificateExtensions = CFSTR("certificateExtensions");
 
 static const uint8_t pkcs9ExtensionsRequested[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 14 };
 static const uint8_t pkcs9ChallengePassword[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 7 };
 
 static const uint8_t pkcs9ExtensionsRequested[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 14 };
 static const uint8_t pkcs9ChallengePassword[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 7 };
@@ -413,12 +418,54 @@ static inline uint32_t highest_bit(uint32_t n)
             (n);
 }
 
             (n);
 }
 
+struct add_custom_extension_args {
+    PLArenaPool *poolp;
+    NSS_CertExtension *csr_extension;
+    uint32_t num_extensions;
+    uint32_t max_extensions;
+};
+
+static void add_custom_extension(const void *key, const void *value, void *context)
+{
+    struct add_custom_extension_args *args = (struct add_custom_extension_args *)context;
+    size_t der_data_len;
+
+    require(args->num_extensions < args->max_extensions, out);
+
+    uint8_t * der_data = oid_der_data(args->poolp, key, &der_data_len);
+    SecAsn1Item encoded_value = {};
+
+    if (CFGetTypeID(value) == CFStringGetTypeID()) {
+        CFIndex buffer_size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(value), kCFStringEncodingUTF8);
+        char *buffer = (char *)PORT_ArenaZNewArray(args->poolp, uint8_t, buffer_size);
+        if (!CFStringGetCString(value, buffer, buffer_size, kCFStringEncodingUTF8))
+            goto out;
+
+        SecAsn1Item buffer_item = { strlen(buffer), (uint8_t*)buffer };
+        SEC_ASN1EncodeItem(args->poolp, &encoded_value, &buffer_item, kSecAsn1UTF8StringTemplate);
+    } else if (CFGetTypeID(value) == CFDataGetTypeID()) {
+        SecAsn1Item data_item = { CFDataGetLength(value), (uint8_t*)CFDataGetBytePtr(value) };
+        SEC_ASN1EncodeItem(args->poolp, &encoded_value, &data_item, kSecAsn1OctetStringTemplate);
+    } else
+        goto out;
+
+
+    if (der_data && encoded_value.Length) {
+        args->csr_extension[args->num_extensions].value = encoded_value;
+        args->csr_extension[args->num_extensions].extnId.Length = der_data_len;
+        args->csr_extension[args->num_extensions].extnId.Data = der_data;
+        args->num_extensions++;
+    }
+out:
+    return;
+}
+
 static
 NSS_CertExtension **
 extensions_from_parameters(PRArenaPool *poolp, CFDictionaryRef parameters)
 {
 static
 NSS_CertExtension **
 extensions_from_parameters(PRArenaPool *poolp, CFDictionaryRef parameters)
 {
-    uint32_t num_extensions = 0, max_extensions = 4;
-    NSS_CertExtension **csr_extensions = PORT_ArenaZNewArray(poolp, NSS_CertExtension *, max_extensions);
+    uint32_t num_extensions = 0, max_extensions = 10;
+    NSS_CertExtension **csr_extensions = PORT_ArenaZNewArray(poolp, NSS_CertExtension *, max_extensions + 1); /* NULL terminated array */
     NSS_CertExtension *csr_extension = PORT_ArenaZNewArray(poolp, NSS_CertExtension, max_extensions);
 
     CFNumberRef basic_contraints_num = CFDictionaryGetValue(parameters, kSecCSRBasicContraintsPathLen);
     NSS_CertExtension *csr_extension = PORT_ArenaZNewArray(poolp, NSS_CertExtension, max_extensions);
 
     CFNumberRef basic_contraints_num = CFDictionaryGetValue(parameters, kSecCSRBasicContraintsPathLen);
@@ -429,7 +476,7 @@ extensions_from_parameters(PRArenaPool *poolp, CFDictionaryRef parameters)
         int basic_contraints_path_len = 0;
         require(CFNumberGetValue(basic_contraints_num, kCFNumberIntType, &basic_contraints_path_len), out);
         if (basic_contraints_path_len >= 0 && basic_contraints_path_len < 256) {
         int basic_contraints_path_len = 0;
         require(CFNumberGetValue(basic_contraints_num, kCFNumberIntType, &basic_contraints_path_len), out);
         if (basic_contraints_path_len >= 0 && basic_contraints_path_len < 256) {
-            path_len = basic_contraints_path_len;
+            path_len = (uint8_t)basic_contraints_path_len;
             basic_contraints.pathLenConstraint.Length = sizeof(path_len);
             basic_contraints.pathLenConstraint.Data = &path_len;
         }
             basic_contraints.pathLenConstraint.Length = sizeof(path_len);
             basic_contraints.pathLenConstraint.Data = &path_len;
         }
@@ -483,15 +530,30 @@ extensions_from_parameters(PRArenaPool *poolp, CFDictionaryRef parameters)
         }
     }
 
         }
     }
 
+    CFDictionaryRef custom_extension_requested = CFDictionaryGetValue(parameters, kSecCertificateExtensions);
+    if (custom_extension_requested) {
+        require(CFGetTypeID(custom_extension_requested) == CFDictionaryGetTypeID(), out);
+        struct add_custom_extension_args args = {
+            poolp,
+            csr_extension,
+            num_extensions,
+            max_extensions
+        };
+        CFDictionaryApplyFunction(custom_extension_requested, add_custom_extension, &args);
+        num_extensions = args.num_extensions;
+    }
+
     /* extensions requested (subjectAltName, keyUsage) sequence of extension sequences */
     uint32_t ix = 0;
     /* extensions requested (subjectAltName, keyUsage) sequence of extension sequences */
     uint32_t ix = 0;
-    for (ix = 0; ix <= num_extensions; ix++)
+    for (ix = 0; ix < num_extensions; ix++)
         csr_extensions[ix] = csr_extension[ix].extnId.Length ? &csr_extension[ix] : NULL;
 
 out:
     return csr_extensions;
 }
 
         csr_extensions[ix] = csr_extension[ix].extnId.Length ? &csr_extension[ix] : NULL;
 
 out:
     return csr_extensions;
 }
 
+
+
 static
 NSS_Attribute **nss_attributes_from_parameters_dict(PRArenaPool *poolp, CFDictionaryRef parameters)
 {
 static
 NSS_Attribute **nss_attributes_from_parameters_dict(PRArenaPool *poolp, CFDictionaryRef parameters)
 {
@@ -647,11 +709,10 @@ CFDataRef SecGenerateCertificateRequestWithParameters(SecRDN *subject,
     /* encode request info by itself to calculate signature */
     SecAsn1Item reqinfo = {};
     SEC_ASN1EncodeItem(poolp, &reqinfo, &certReq.reqInfo, kSecAsn1CertRequestInfoTemplate);
     /* encode request info by itself to calculate signature */
     SecAsn1Item reqinfo = {};
     SEC_ASN1EncodeItem(poolp, &reqinfo, &certReq.reqInfo, kSecAsn1CertRequestInfoTemplate);
-    require(reqinfo.Length<=UINT32_MAX, out);
 
     /* calculate signature */
     uint8_t reqinfo_hash[CC_SHA1_DIGEST_LENGTH];
 
     /* calculate signature */
     uint8_t reqinfo_hash[CC_SHA1_DIGEST_LENGTH];
-    CC_SHA1(reqinfo.Data, (CC_LONG)reqinfo.Length, reqinfo_hash);
+    CCDigest(kCCDigestSHA1, reqinfo.Data, (CC_LONG)reqinfo.Length, reqinfo_hash);
     require_noerr_quiet(SecKeyRawSign(privateKey, kSecPaddingPKCS1SHA1, 
         reqinfo_hash, sizeof(reqinfo_hash), signature, &signature_length), out);
     
     require_noerr_quiet(SecKeyRawSign(privateKey, kSecPaddingPKCS1SHA1, 
         reqinfo_hash, sizeof(reqinfo_hash), signature, &signature_length), out);
     
@@ -715,11 +776,10 @@ CFDataRef SecGenerateCertificateRequest(CFArrayRef subject,
     /* encode request info by itself to calculate signature */
     SecAsn1Item reqinfo = {};
     SEC_ASN1EncodeItem(poolp, &reqinfo, &certReq.reqInfo, kSecAsn1CertRequestInfoTemplate);
     /* encode request info by itself to calculate signature */
     SecAsn1Item reqinfo = {};
     SEC_ASN1EncodeItem(poolp, &reqinfo, &certReq.reqInfo, kSecAsn1CertRequestInfoTemplate);
-    require(reqinfo.Length<=UINT32_MAX, out);
 
     /* calculate signature */
     uint8_t reqinfo_hash[CC_SHA1_DIGEST_LENGTH];
 
     /* calculate signature */
     uint8_t reqinfo_hash[CC_SHA1_DIGEST_LENGTH];
-    CC_SHA1(reqinfo.Data, reqinfo.Length, reqinfo_hash);
+    CCDigest(kCCDigestSHA1, reqinfo.Data, reqinfo.Length, reqinfo_hash);
     require_noerr_quiet(SecKeyRawSign(privateKey, kSecPaddingPKCS1SHA1, 
         reqinfo_hash, sizeof(reqinfo_hash), signature, &signature_length), out);
     
     require_noerr_quiet(SecKeyRawSign(privateKey, kSecPaddingPKCS1SHA1, 
         reqinfo_hash, sizeof(reqinfo_hash), signature, &signature_length), out);
     
@@ -770,7 +830,7 @@ bool SecVerifyCertificateRequest(CFDataRef csr, SecKeyRef *publicKey,
     /* calculate signature */
     uint8_t reqinfo_hash[CC_SHA1_DIGEST_LENGTH];
     require(reqinfo.Length<=UINT32_MAX, out);
     /* calculate signature */
     uint8_t reqinfo_hash[CC_SHA1_DIGEST_LENGTH];
     require(reqinfo.Length<=UINT32_MAX, out);
-    CC_SHA1(reqinfo.Data, (CC_LONG)reqinfo.Length, reqinfo_hash);
+    CCDigest(kCCDigestSHA1, reqinfo.Data, (CC_LONG)reqinfo.Length, reqinfo_hash);
 
     /* @@@ check for version 0 */
 
 
     /* @@@ check for version 0 */
 
@@ -925,8 +985,7 @@ SecGenerateSelfSignedCertificate(CFArrayRef subject, CFDictionaryRef parameters,
 
         /* calculate signature */
         uint8_t tbscert_hash[CC_SHA1_DIGEST_LENGTH];
 
         /* calculate signature */
         uint8_t tbscert_hash[CC_SHA1_DIGEST_LENGTH];
-        require(tbscert.Length<=UINT32_MAX, out);
-        CC_SHA1(tbscert.Data, tbscert.Length, tbscert_hash);
+        CCDigest(kCCDigestSHA1, tbscert.Data, tbscert.Length, tbscert_hash);
         uint8_t signature[8 * CFDataGetLength(pkcs1_pubkey)];
         size_t signature_length = sizeof(signature);
         require_noerr_quiet(SecKeyRawSign(privateKey, kSecPaddingPKCS1SHA1, 
         uint8_t signature[8 * CFDataGetLength(pkcs1_pubkey)];
         size_t signature_length = sizeof(signature);
         require_noerr_quiet(SecKeyRawSign(privateKey, kSecPaddingPKCS1SHA1, 
@@ -986,7 +1045,7 @@ SecIdentitySignCertificate(SecIdentityRef issuer, CFDataRef serialno,
 
     SecCertificateRef issuer_cert = NULL;
     require_noerr(SecIdentityCopyCertificate(issuer, &issuer_cert), out);
 
     SecCertificateRef issuer_cert = NULL;
     require_noerr(SecIdentityCopyCertificate(issuer, &issuer_cert), out);
-    CFDataRef issuer_name = SecCertificateCopyIssuerSequence(issuer_cert);
+    CFDataRef issuer_name = SecCertificateCopySubjectSequence(issuer_cert);
     SecAsn1Item issuer_item = { CFDataGetLength(issuer_name), (uint8_t*)CFDataGetBytePtr(issuer_name) };
     require_noerr_action_quiet(SEC_ASN1DecodeItem(poolp, &cert_tmpl.tbs.issuer.rdns, 
         kSecAsn1NameTemplate, &issuer_item), out, CFReleaseNull(issuer_name));
     SecAsn1Item issuer_item = { CFDataGetLength(issuer_name), (uint8_t*)CFDataGetBytePtr(issuer_name) };
     require_noerr_action_quiet(SEC_ASN1DecodeItem(poolp, &cert_tmpl.tbs.issuer.rdns, 
         kSecAsn1NameTemplate, &issuer_item), out, CFReleaseNull(issuer_name));
@@ -1033,8 +1092,7 @@ SecIdentitySignCertificate(SecIdentityRef issuer, CFDataRef serialno,
 
         /* calculate signature */
         uint8_t tbscert_hash[CC_SHA1_DIGEST_LENGTH];
 
         /* calculate signature */
         uint8_t tbscert_hash[CC_SHA1_DIGEST_LENGTH];
-        require(tbscert.Length<=UINT32_MAX, out);
-        CC_SHA1(tbscert.Data, tbscert.Length, tbscert_hash);
+        CCDigest(kCCDigestSHA1, tbscert.Data, tbscert.Length, tbscert_hash);
         uint8_t signature[8 * CFDataGetLength(pkcs1_pubkey)];
         size_t signature_length = sizeof(signature);
         
         uint8_t signature[8 * CFDataGetLength(pkcs1_pubkey)];
         size_t signature_length = sizeof(signature);
         
index 2d808d97d46f7aaeb9c61584321b28aa2c14ce6f..62bf9d1447d23c39f1371c836acce383db5fc37a 100644 (file)
@@ -31,9 +31,7 @@
 #include <Security/SecCertificatePriv.h>
 #include <Security/SecKey.h>
 
 #include <Security/SecCertificatePriv.h>
 #include <Security/SecKey.h>
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 extern const void * kSecOidCommonName;
 extern const void * kSecOidCountryName;
 
 extern const void * kSecOidCommonName;
 extern const void * kSecOidCountryName;
@@ -59,11 +57,16 @@ extern const unsigned char SecASN1UTF8String;
             a CA cert.  If 0 <= number < 256, specifies path length, otherwise
             path length will be omitted.  Basic contraints will always be 
             marked critical.
             a CA cert.  If 0 <= number < 256, specifies path length, otherwise
             path length will be omitted.  Basic contraints will always be 
             marked critical.
+        @param kSecCertificateExtensions     CFDictionaryRef
+            if set all keys (strings with oids in dotted notation) will be added
+            as extensions with accompanying value in binary (CFDataRef) or
+            appropriate string (CFStringRef) type (based on used character set).
 */
 extern const void * kSecCSRChallengePassword;
 extern const void * kSecSubjectAltName;
 extern const void * kSecCertificateKeyUsage;
 extern const void * kSecCSRBasicContraintsPathLen;
 */
 extern const void * kSecCSRChallengePassword;
 extern const void * kSecSubjectAltName;
 extern const void * kSecCertificateKeyUsage;
 extern const void * kSecCSRBasicContraintsPathLen;
+extern const void * kSecCertificateExtensions;
 
 typedef struct {
     const void *oid;          /* kSecOid constant or CFDataRef with oid */
 
 typedef struct {
     const void *oid;          /* kSecOid constant or CFDataRef with oid */
@@ -90,10 +93,10 @@ Example for subject:
     SecRDN atvs[] = { cn, c, o, NULL };
 */
 CFDataRef SecGenerateCertificateRequestWithParameters(SecRDN *subject, 
     SecRDN atvs[] = { cn, c, o, NULL };
 */
 CFDataRef SecGenerateCertificateRequestWithParameters(SecRDN *subject, 
-    CFDictionaryRef parameters, SecKeyRef publicKey, SecKeyRef privateKey);
+    CFDictionaryRef parameters, SecKeyRef publicKey, SecKeyRef privateKey) CF_RETURNS_RETAINED;
 
 CFDataRef SecGenerateCertificateRequest(CFArrayRef subject, 
 
 CFDataRef SecGenerateCertificateRequest(CFArrayRef subject, 
-    CFDictionaryRef parameters, SecKeyRef publicKey, SecKeyRef privateKey);
+    CFDictionaryRef parameters, SecKeyRef publicKey, SecKeyRef privateKey) CF_RETURNS_RETAINED;
 
 /*
        @function SecVerifyCertificateRequest
 
 /*
        @function SecVerifyCertificateRequest
@@ -120,8 +123,6 @@ SecIdentitySignCertificate(SecIdentityRef issuer, CFDataRef serialno,
 CFDataRef
 SecGenerateCertificateRequestSubject(SecCertificateRef ca_certificate, CFArrayRef subject);
 
 CFDataRef
 SecGenerateCertificateRequestSubject(SecCertificateRef ca_certificate, CFArrayRef subject);
 
-#if defined(__cplusplus)
-}
-#endif
+__END_DECLS
 
 #endif /* _SECURITY_SECCERTIFICATEREQUEST_H_ */
 
 #endif /* _SECURITY_SECCERTIFICATEREQUEST_H_ */
index 0071d46de6961cc431a18607d7e59576173fb308..e33bb2c58ab44f60f46628cbc1f6ba6df6475bd3 100644 (file)
 #include <libDER/DER_Encode.h>
 #include <libDER/asn1Types.h>
 #include <libkern/OSByteOrder.h>
 #include <libDER/DER_Encode.h>
 #include <libDER/asn1Types.h>
 #include <libkern/OSByteOrder.h>
-#include <security_utilities/debugging.h>
+#include "utilities/debugging.h"
 #include <Security/SecInternal.h>
 #include <Security/SecRandom.h>
 #include <stdlib.h>
 #include <Security/SecInternal.h>
 #include <Security/SecRandom.h>
 #include <stdlib.h>
-#include <MacErrors.h>
+#include <Security/SecBase.h>
 #include <Security/SecBasePriv.h>
 
 #ifdef DEBUG
 #include <Security/SecBasePriv.h>
 
 #ifdef DEBUG
@@ -74,13 +74,13 @@ der2OSStatus(DERReturn derReturn)
 {
        switch(derReturn)
        {
 {
        switch(derReturn)
        {
-       case DR_Success:                                return noErr;
+       case DR_Success:                                return errSecSuccess;
        case DR_EndOfSequence:                  return errSecDecode; 
        case DR_UnexpectedTag:                  return errSecDecode;
        case DR_DecodeError:                    return errSecDecode;
        case DR_EndOfSequence:                  return errSecDecode; 
        case DR_UnexpectedTag:                  return errSecDecode;
        case DR_DecodeError:                    return errSecDecode;
-       case DR_Unimplemented:                  return unimpErr;
+       case DR_Unimplemented:                  return errSecUnimplemented;
        case DR_IncompleteSeq:                  return errSecDecode;
        case DR_IncompleteSeq:                  return errSecDecode;
-       case DR_ParamErr:                               return paramErr;
+       case DR_ParamErr:                               return errSecParam;
        case DR_BufOverflow:                    return errSecBufferTooSmall;
        default:                                                return errSecInternal;
        }
        case DR_BufOverflow:                    return errSecBufferTooSmall;
        default:                                                return errSecInternal;
        }
@@ -122,7 +122,7 @@ OSStatus SecDHCreate(uint32_t g, const uint8_t *p, size_t p_len,
 
     *pdh = (SecDHContext) context;
 
 
     *pdh = (SecDHContext) context;
 
-    return noErr;
+    return errSecSuccess;
 
 errOut:
     SecDHDestroy(context);
 
 errOut:
     SecDHDestroy(context);
@@ -189,7 +189,7 @@ OSStatus SecDHCreateFromParameters(const uint8_t *params,
     size_t context_size = ccdh_gp_size(p_len)+ccdh_full_ctx_size(p_len);
     void *context = malloc(context_size);
     if(context==NULL)
     size_t context_size = ccdh_gp_size(p_len)+ccdh_full_ctx_size(p_len);
     void *context = malloc(context_size);
     if(context==NULL)
-        return memFullErr;
+        return errSecAllocate;
 
     bzero(context, context_size);
 
 
     bzero(context, context_size);
 
@@ -213,7 +213,7 @@ OSStatus SecDHCreateFromParameters(const uint8_t *params,
         goto errOut;
 
     *pdh = (SecDHContext) context;
         goto errOut;
 
     *pdh = (SecDHContext) context;
-    return noErr;
+    return errSecSuccess;
 
 errOut:
     SecDHDestroy(context);
 
 errOut:
     SecDHDestroy(context);
@@ -264,7 +264,7 @@ OSStatus SecDHGenerateKeypair(SecDHContext dh, uint8_t *pub_key,
     ccn_write_uint(ccdh_gp_n(gp),ccdh_ctx_y(priv), ylen, pub_key);
     *pub_key_len = ylen;
 
     ccn_write_uint(ccdh_gp_n(gp),ccdh_ctx_y(priv), ylen, pub_key);
     *pub_key_len = ylen;
 
-    return noErr;
+    return errSecSuccess;
 }
 
 OSStatus SecDHComputeKey(SecDHContext dh,
 }
 
 OSStatus SecDHComputeKey(SecDHContext dh,
@@ -288,7 +288,7 @@ OSStatus SecDHComputeKey(SecDHContext dh,
     if(out_size < *computed_key_len)
         *computed_key_len=out_size;
 
     if(out_size < *computed_key_len)
         *computed_key_len=out_size;
 
-    return noErr;
+    return errSecSuccess;
 }
 
 void SecDHDestroy(SecDHContext dh) {
 }
 
 void SecDHDestroy(SecDHContext dh) {
index e9eb598297fb6c4ecdda0bd916c4035a1905b860..2bfdb10996167913c42dfd278b5371eb81048872 100644 (file)
@@ -55,7 +55,7 @@ typedef struct OpaqueSecDHContext *SecDHContext;
        @discussion The recip and recip_len parameters are constant for a given p.
        They are optional, although providing them improves performance.
     @result On success, a newly allocated SecDHContext is returned in dh and
        @discussion The recip and recip_len parameters are constant for a given p.
        They are optional, although providing them improves performance.
     @result On success, a newly allocated SecDHContext is returned in dh and
-       noErr is returned.  On failure, NULL is returned in dh and an OSStatus error
+       errSecSuccess is returned.  On failure, NULL is returned in dh and an OSStatus error
        code is returned.
     The caller should call SecDHDestroy once the returned context is no longer
     needed.
        code is returned.
     The caller should call SecDHDestroy once the returned context is no longer
     needed.
@@ -70,7 +70,7 @@ OSStatus SecDHCreate(uint32_t g, const uint8_t *p, size_t p_len, uint32_t l,
        @param params_len Length of params, in bytes
        @param dh (output) A pointer to a SecDHContext
     @result On success, a newly allocated SecDHContext is returned in dh and
        @param params_len Length of params, in bytes
        @param dh (output) A pointer to a SecDHContext
     @result On success, a newly allocated SecDHContext is returned in dh and
-       noErr is returned.  On failure, NULL is returned in dh and an OSStatus error
+       errSecSuccess is returned.  On failure, NULL is returned in dh and an OSStatus error
        code is returned.
     The caller should call SecDHDestroy once the returned context is no longer
     needed.
        code is returned.
     The caller should call SecDHDestroy once the returned context is no longer
     needed.
@@ -85,7 +85,7 @@ OSStatus SecDHCreateFromParameters(const uint8_t *params, size_t params_len,
        @param alg_len Length of alg, in bytes
        @param dh (output) A pointer to a SecDHContext
     @result On success, a newly allocated SecDHContext is returned in dh and
        @param alg_len Length of alg, in bytes
        @param dh (output) A pointer to a SecDHContext
     @result On success, a newly allocated SecDHContext is returned in dh and
-       noErr is returned.  On failure, NULL is returned in dh and an OSStatus error
+       errSecSuccess is returned.  On failure, NULL is returned in dh and an OSStatus error
        code is returned.
     The caller should call SecDHDestroy once the returned context is no longer
     needed.
        code is returned.
     The caller should call SecDHDestroy once the returned context is no longer
     needed.
@@ -118,7 +118,7 @@ size_t SecDHGetMaxKeyLength(SecDHContext dh);
        on output, the number of bytes actually in pub_key.  
        @discussion Reusing a SecDHContext for multiple SecDHGenerateKeypair()
        invocations is permitted.
        on output, the number of bytes actually in pub_key.  
        @discussion Reusing a SecDHContext for multiple SecDHGenerateKeypair()
        invocations is permitted.
-    @result noErr on success, or an OSStatus error code on failure.
+    @result errSecSuccess on success, or an OSStatus error code on failure.
  */
 OSStatus SecDHGenerateKeypair(SecDHContext dh, uint8_t *pub_key,
        size_t *pub_key_len);
  */
 OSStatus SecDHGenerateKeypair(SecDHContext dh, uint8_t *pub_key,
        size_t *pub_key_len);
@@ -144,7 +144,7 @@ OSStatus SecDHGenerateKeypair(SecDHContext dh, uint8_t *pub_key,
        computed key, only the first *computed_key_len bytes will be returned.
        No leading zero bytes will be returned, and the computed_key is returned
        as an unsigned big-endian byte array.
        computed key, only the first *computed_key_len bytes will be returned.
        No leading zero bytes will be returned, and the computed_key is returned
        as an unsigned big-endian byte array.
-    @result noErr on success, or an OSStatus error code on failure.
+    @result errSecSuccess on success, or an OSStatus error code on failure.
  */
 OSStatus SecDHComputeKey(SecDHContext dh,
        const uint8_t *pub_key, size_t pub_key_len,
  */
 OSStatus SecDHComputeKey(SecDHContext dh,
        const uint8_t *pub_key, size_t pub_key_len,
index 09cbd0ca2c58faf8e209f9f176b0bdb6bfb20a88..a574a9f43c3dea85081ea3890aabce68bdb4932e 100644 (file)
 #include <CoreFoundation/CFNumber.h>
 #include <Security/SecFramework.h>
 #include <Security/SecRandom.h>
 #include <CoreFoundation/CFNumber.h>
 #include <Security/SecFramework.h>
 #include <Security/SecRandom.h>
-#include <security_utilities/debugging.h>
+#include <utilities/debugging.h>
 #include "SecItemPriv.h"
 #include <Security/SecInternal.h>
 #include <corecrypto/ccec.h>
 #include <corecrypto/ccsha1.h>
 #include <corecrypto/ccsha2.h>
 #include <corecrypto/ccrng.h>
 #include "SecItemPriv.h"
 #include <Security/SecInternal.h>
 #include <corecrypto/ccec.h>
 #include <corecrypto/ccsha1.h>
 #include <corecrypto/ccsha2.h>
 #include <corecrypto/ccrng.h>
+#include <corecrypto/ccder_decode_eckey.h>
 
 #define kMaximumECKeySize 521
 
 
 #define kMaximumECKeySize 521
 
@@ -54,7 +55,6 @@ static CFIndex SecECKeyGetAlgorithmID(SecKeyRef key) {
 }
 
 
 }
 
 
-
 /*
  *
  * Public Key
 /*
  *
  * Public Key
@@ -70,80 +70,48 @@ static void SecECPublicKeyDestroy(SecKeyRef key) {
         cc_zero(ccec_pub_ctx_size(ccn_sizeof_n(ccec_ctx_n(pubkey))), pubkey.pub);
 }
 
         cc_zero(ccec_pub_ctx_size(ccn_sizeof_n(ccec_ctx_n(pubkey))), pubkey.pub);
 }
 
-static ccec_const_cp_t getCPForBits(size_t bits)
+static ccec_const_cp_t getCPForPublicSize(CFIndex encoded_length)
 {
 {
-    switch (bits) {
-        case 192:
-            return ccec_cp_192();
-        case 224:
-            return ccec_cp_224();
-        case 256:
-            return ccec_cp_256();
-        case 384:
-            return ccec_cp_384();
-        case 521:
-            return ccec_cp_521();
-        default:
-        {
-            ccec_const_cp_t nullCP = { .zp = NULL };
-            return nullCP;
-        }
+    size_t keysize = ccec_x963_import_pub_size(encoded_length);
+    if(ccec_keysize_is_supported(keysize)) {
+        return ccec_get_cp(keysize);
     }
     }
+    ccec_const_cp_t nullCP = { .zp = NULL };
+    return nullCP;
 }
 }
-static ccec_const_cp_t getCPForPublicSize(CFIndex publicLength)
+
+static ccec_const_cp_t getCPForPrivateSize(CFIndex encoded_length)
 {
 {
-    ccec_const_cp_t cp;
-    switch (publicLength) {
-        case 49:
-            cp = ccec_cp_192();
-            break;
-        case 57:
-            cp = ccec_cp_224();
-            break;
-        case 65:
-            cp = ccec_cp_256();
-            break;
-        case 97:
-            cp = ccec_cp_384();
-            break;
-        case 133:
-            cp = ccec_cp_521();
-            break;
-        default:
-        {
-            ccec_const_cp_t nullCP = { .zp = NULL };
-            return nullCP;
-        }
+    size_t keysize = ccec_x963_import_priv_size(encoded_length);
+    if(ccec_keysize_is_supported(keysize)) {
+        return ccec_get_cp(keysize);
     }
     }
-    return cp;
+    ccec_const_cp_t nullCP = { .zp = NULL };
+    return nullCP;
 }
 
 }
 
-static ccec_const_cp_t getCPForPrivateSize(CFIndex publicLength)
+static ccoid_t ccoid_secp192r1 = CC_EC_OID_SECP192R1;
+static ccoid_t ccoid_secp256r1 = CC_EC_OID_SECP256R1;
+static ccoid_t ccoid_secp224r1 = CC_EC_OID_SECP224R1;
+static ccoid_t ccoid_secp384r1 = CC_EC_OID_SECP384R1;
+static ccoid_t ccoid_secp521r1 = CC_EC_OID_SECP521R1;
+
+static ccec_const_cp_t ccec_cp_for_oid(ccoid_t oid)
 {
 {
-    ccec_const_cp_t cp;
-    switch (publicLength) {
-        case 49 + 24:
-            cp = ccec_cp_192();
-            break;
-        case 57 + 28:
-            cp = ccec_cp_224();
-            break;
-        case 65 + 32:
-            cp = ccec_cp_256();
-            break;
-        case 97 + 48:
-            cp = ccec_cp_384();
-            break;
-        case 133 + 66:
-            cp = ccec_cp_521();
-            break;
-        default:
-        {
-            ccec_const_cp_t nullCP = { .zp = NULL };
-            return nullCP;
+    if (oid.oid) {
+        if (ccoid_equal(oid, ccoid_secp192r1)) {
+            return ccec_cp_192();
+        } else if (ccoid_equal(oid, ccoid_secp256r1)) {
+            return ccec_cp_256();
+        } else if (ccoid_equal(oid, ccoid_secp224r1)) {
+            return ccec_cp_224();
+        } else if (ccoid_equal(oid, ccoid_secp384r1)) {
+            return ccec_cp_384();
+        } else if (ccoid_equal(oid, ccoid_secp521r1)) {
+            return ccec_cp_521();
         }
     }
         }
     }
-    return cp;
+    return (ccec_const_cp_t){NULL};
 }
 
 static OSStatus SecECPublicKeyInit(SecKeyRef key,
 }
 
 static OSStatus SecECPublicKeyInit(SecKeyRef key,
@@ -232,7 +200,7 @@ static size_t SecECPublicKeyBlockSize(SecKeyRef key) {
     /* Get key size in octets */
     ccec_pub_ctx_t pubkey;
     pubkey.pub = key->key;
     /* Get key size in octets */
     ccec_pub_ctx_t pubkey;
     pubkey.pub = key->key;
-    return ccec_ccn_size(ccec_ctx_cp(pubkey));
+    return ccec_ctx_size(pubkey);
 }
 
 /* Encode the public key and return it in a newly allocated CFDataRef. */
 }
 
 /* Encode the public key and return it in a newly allocated CFDataRef. */
@@ -266,6 +234,75 @@ static CFDictionaryRef SecECPublicKeyCopyAttributeDictionary(SecKeyRef key) {
     return SecKeyGeneratePublicAttributeDictionary(key, kSecAttrKeyTypeEC);
 }
 
     return SecKeyGeneratePublicAttributeDictionary(key, kSecAttrKeyTypeEC);
 }
 
+static CFStringRef SecECPublicKeyCopyKeyDescription(SecKeyRef key)
+{
+    ccec_pub_ctx_t ecPubkey;
+    CFStringRef keyDescription = NULL;
+    size_t xlen, ylen, ix;
+    CFMutableStringRef xString = NULL;
+    CFMutableStringRef yString = NULL;
+
+    ecPubkey.pub = key->key;
+    
+    //curve
+    long curveType = (long)SecECKeyGetNamedCurve(key);
+    char* curve= NULL;
+    
+    switch (curveType)
+       {
+        case 23:
+            curve = "kSecECCurveSecp256r1";
+            break;
+        case 24:
+            curve = "kSecECCurveSecp384r1";
+            break;
+        case 25:
+            curve = "kSecECCurveSecp521r1";
+            break;
+        case -1:
+            curve = "kSecECCurveNone";
+            break;
+        default:
+            curve = "kSecECCurveNone";
+            break;
+    }
+
+    uint8_t *xunit = (uint8_t*)ccec_ctx_x(ecPubkey);
+    require_quiet( NULL != xunit, fail);
+    xlen = (size_t)strlen((char*)xunit);
+
+       
+    xString = CFStringCreateMutable(kCFAllocatorDefault, xlen * 2);
+    require_quiet( NULL != xString, fail);
+    
+    for (ix = 0; ix < xlen; ++ix)
+    {
+               CFStringAppendFormat(xString, NULL, CFSTR("%02X"), xunit[ix]);
+    }
+
+    uint8_t *yunit = (uint8_t*)ccec_ctx_y(ecPubkey);
+    require_quiet( NULL != yunit, fail);
+    ylen = (size_t)strlen((char*)yunit);
+    
+    yString = CFStringCreateMutable(kCFAllocatorDefault, ylen*2);
+    require_quiet( NULL != yString, fail);
+
+    for(ix = 0; ix < ylen; ++ix)
+    {
+        CFStringAppendFormat(yString, NULL, CFSTR("%02X"), yunit[ix]);
+    }
+    
+    keyDescription = CFStringCreateWithFormat(kCFAllocatorDefault,NULL,CFSTR( "<SecKeyRef curve type: %s, algorithm id: %lu, key type: %s, version: %d, block size: %zu bits, y: %@, x: %@, addr: %p>"), curve, (long)SecKeyGetAlgorithmID(key), key->key_class->name, key->key_class->version, (8*SecKeyGetBlockSize(key)), yString, xString, key);
+    
+fail:
+       CFReleaseSafe(xString);
+       CFReleaseSafe(yString);
+       if(!keyDescription)
+               keyDescription = CFStringCreateWithFormat(kCFAllocatorDefault,NULL,CFSTR("<SecKeyRef curve type: %s, algorithm id: %lu, key type: %s, version: %d, block size: %zu bits, addr: %p>"), curve,(long)SecKeyGetAlgorithmID(key), key->key_class->name, key->key_class->version, (8*SecKeyGetBlockSize(key)), key);
+    
+       return keyDescription;
+}
+
 SecKeyDescriptor kSecECPublicKeyDescriptor = {
     kSecKeyDescriptorVersion,
     "ECPublicKey",
 SecKeyDescriptor kSecECPublicKeyDescriptor = {
     kSecKeyDescriptorVersion,
     "ECPublicKey",
@@ -279,6 +316,7 @@ SecKeyDescriptor kSecECPublicKeyDescriptor = {
     NULL, /* SecKeyComputeMethod */
     SecECPublicKeyBlockSize,
        SecECPublicKeyCopyAttributeDictionary,
     NULL, /* SecKeyComputeMethod */
     SecECPublicKeyBlockSize,
        SecECPublicKeyCopyAttributeDictionary,
+    SecECPublicKeyCopyKeyDescription,
     SecECKeyGetAlgorithmID,
     SecECPublicKeyCopyPublicOctets,
 };
     SecECKeyGetAlgorithmID,
     SecECPublicKeyCopyPublicOctets,
 };
@@ -317,9 +355,28 @@ static OSStatus SecECPrivateKeyInit(SecKeyRef key,
 
     switch (encoding) {
     case kSecKeyEncodingPkcs1:
 
     switch (encoding) {
     case kSecKeyEncodingPkcs1:
+    {
         /* TODO: DER import size (and thus cp), pub.x, pub.y and k. */
         //err = ecc_import(keyData, keyDataLength, fullkey);
         /* TODO: DER import size (and thus cp), pub.x, pub.y and k. */
         //err = ecc_import(keyData, keyDataLength, fullkey);
+
+        /* DER != PKCS#1, but we'll go along with it */
+        ccoid_t oid;
+        size_t n;
+        ccec_const_cp_t cp;
+
+        require_noerr(ccec_der_import_priv_keytype(keyDataLength, keyData, &oid, &n), abort);
+        cp = ccec_cp_for_oid(oid);
+        if (cp.zp == NULL) {
+            cp = ccec_curve_for_length_lookup(n * 8 /* bytes -> bits */,
+                ccec_cp_192(), ccec_cp_224(), ccec_cp_256(), ccec_cp_384(), ccec_cp_521(), NULL);
+        }
+        require_action(cp.zp != NULL, abort, err = errSecDecode);
+        ccec_ctx_init(cp, fullkey);
+
+        require_noerr(ccec_der_import_priv(cp, keyDataLength, keyData, fullkey), abort);
+        err = errSecSuccess;
         break;
         break;
+    }
     case kSecKeyEncodingBytes:
     {
         ccec_const_cp_t cp = getCPForPrivateSize(keyDataLength);
     case kSecKeyEncodingBytes:
     {
         ccec_const_cp_t cp = getCPForPrivateSize(keyDataLength);
@@ -353,7 +410,7 @@ static OSStatus SecECPrivateKeyInit(SecKeyRef key,
         CFTypeRef ksize = CFDictionaryGetValue(parameters, kSecAttrKeySizeInBits);
         CFIndex keyLengthInBits = getIntValue(ksize);
 
         CFTypeRef ksize = CFDictionaryGetValue(parameters, kSecAttrKeySizeInBits);
         CFIndex keyLengthInBits = getIntValue(ksize);
 
-        ccec_const_cp_t cp = getCPForBits(keyLengthInBits);
+        ccec_const_cp_t cp = ccec_get_cp(keyLengthInBits);
 
         if (!cp.zp) {
             secwarning("Invalid or missing key size in: %@", parameters);
 
         if (!cp.zp) {
             secwarning("Invalid or missing key size in: %@", parameters);
@@ -398,7 +455,7 @@ ccdigest_lookup_by_oid(unsigned long oid_size, const void *oid) {
         &ccsha512_di
     };
     size_t i;
         &ccsha512_di
     };
     size_t i;
-    for (i = 0; i < sizeof(dis) / sizeof(*dis); ++i) {
+    for (i = 0; i < array_size(dis); ++i) {
         if (oid_size == dis[i]->oid_size && !memcmp(dis[i]->oid, oid, oid_size))
             return dis[i];
     }
         if (oid_size == dis[i]->oid_size && !memcmp(dis[i]->oid, oid, oid_size))
             return dis[i];
     }
@@ -425,7 +482,7 @@ static size_t SecECPrivateKeyBlockSize(SecKeyRef key) {
     ccec_full_ctx_t fullkey;
     fullkey.hdr = key->key;
     /* Get key size in octets */
     ccec_full_ctx_t fullkey;
     fullkey.hdr = key->key;
     /* Get key size in octets */
-    return ccec_ccn_size(ccec_ctx_cp(fullkey));
+    return ccec_ctx_size(fullkey);
 }
 
 static OSStatus SecECPrivateKeyCopyPublicOctets(SecKeyRef key, CFDataRef *serailziation)
 }
 
 static OSStatus SecECPrivateKeyCopyPublicOctets(SecKeyRef key, CFDataRef *serailziation)
@@ -478,6 +535,34 @@ errOut:
 
        return dict;
 }
 
        return dict;
 }
+static CFStringRef SecECPrivateKeyCopyKeyDescription(SecKeyRef key) {
+    
+    //curve
+    long curveType = (long)SecECKeyGetNamedCurve(key);
+    char* curve= NULL;
+    
+    switch (curveType)
+       {
+        case 23:
+            curve = "kSecECCurveSecp256r1";
+            break;
+        case 24:
+            curve = "kSecECCurveSecp384r1";
+            break;
+        case 25:
+            curve = "kSecECCurveSecp521r1";
+            break;
+        case -1:
+            curve = "kSecECCurveNone";
+            break;
+        default:
+            curve = "kSecECCurveNone";
+            break;
+    }
+    
+       return CFStringCreateWithFormat(kCFAllocatorDefault,NULL,CFSTR( "<SecKeyRef curve type: %s, algorithm id: %lu, key type: %s, version: %d, block size: %zu bits, addr: %p>"), curve, (long)SecKeyGetAlgorithmID(key), key->key_class->name, key->key_class->version, (8*SecKeyGetBlockSize(key)), key);
+
+}
 
 SecKeyDescriptor kSecECPrivateKeyDescriptor = {
     kSecKeyDescriptorVersion,
 
 SecKeyDescriptor kSecECPrivateKeyDescriptor = {
     kSecKeyDescriptorVersion,
@@ -492,6 +577,7 @@ SecKeyDescriptor kSecECPrivateKeyDescriptor = {
     NULL, /* SecKeyComputeMethod */
     SecECPrivateKeyBlockSize,
        SecECPrivateKeyCopyAttributeDictionary,
     NULL, /* SecKeyComputeMethod */
     SecECPrivateKeyBlockSize,
        SecECPrivateKeyCopyAttributeDictionary,
+    SecECPrivateKeyCopyKeyDescription,
     SecECKeyGetAlgorithmID,
     SecECPrivateKeyCopyPublicOctets,
 };
     SecECKeyGetAlgorithmID,
     SecECPrivateKeyCopyPublicOctets,
 };
@@ -551,7 +637,7 @@ SecECNamedCurve SecECKeyGetNamedCurve(SecKeyRef key) {
 
     ccec_pub_ctx_t pubkey;
     pubkey.pub = key->key;
 
     ccec_pub_ctx_t pubkey;
     pubkey.pub = key->key;
-    switch (ccec_cp_prime_size(ccec_ctx_cp(pubkey))) {
+    switch (ccec_ctx_size(pubkey)) {
 #if 0
     case 24:
         return kSecECCurveSecp192r1;
 #if 0
     case 24:
         return kSecECCurveSecp192r1;
index adf37412b4b93a9115103c8a27f271e4ee36bbba..2433818f98daf4811b7310a4cec60e9177eb1e53 100644 (file)
@@ -34,9 +34,7 @@
 #include <Security/SecKeyPriv.h>
 #include <CoreFoundation/CFData.h>
 
 #include <Security/SecKeyPriv.h>
 #include <CoreFoundation/CFData.h>
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 typedef struct SecECPublicKeyParams {
        uint8_t             *modulus;                   /* modulus */
 
 typedef struct SecECPublicKeyParams {
        uint8_t             *modulus;                   /* modulus */
@@ -76,8 +74,6 @@ typedef enum
 SecECNamedCurve SecECKeyGetNamedCurve(SecKeyRef ecPrivateKey);
 CFDataRef SecECKeyCopyPublicBits(SecKeyRef key);
 
 SecECNamedCurve SecECKeyGetNamedCurve(SecKeyRef ecPrivateKey);
 CFDataRef SecECKeyCopyPublicBits(SecKeyRef key);
 
-#if defined(__cplusplus)
-}
-#endif
+__END_DECLS
 
 #endif /* !_SECURITY_SECECKEY_H_ */
 
 #endif /* !_SECURITY_SECECKEY_H_ */
diff --git a/sec/Security/SecExports.exp-in b/sec/Security/SecExports.exp-in
new file mode 100644 (file)
index 0000000..58479bd
--- /dev/null
@@ -0,0 +1,721 @@
+//  SecExports.exp-in
+//  sec
+//
+//  Created by Mitch Adler on 4/2/13.
+//
+
+//
+// CFError to OSStatus conversion
+//
+
+_SecErrorGetOSStatus
+
+//
+// Password
+//
+
+_kSecPasswordMinLengthKey
+_kSecPasswordMaxLengthKey
+_kSecPasswordAllowedCharactersKey
+_kSecPasswordRequiredCharactersKey
+_kSecPasswordDefaultForType
+_kSecPasswordDisallowedCharacters
+_kSecPasswordCantStartWithChars
+_kSecPasswordCantEndWithChars
+_kSecPasswordContainsNoMoreThanNSpecificCharacters
+_kSecPasswordContainsAtLeastNSpecificCharacters
+_kSecPasswordContainsNoMoreThanNConsecutiveIdenticalCharacters
+_kSecPasswordGroupSize
+_kSecPasswordNumberOfGroups
+_kSecPasswordSeparator
+_kSecPasswordCharacterCount
+_kSecPasswordCharacters
+_SecPasswordIsPasswordWeak
+_SecPasswordGenerate
+_SecPasswordCopyDefaultPasswordLength
+
+//
+// Base64
+//
+
+_SecBase64Encode
+_SecBase64Encode2
+
+//
+// Trust
+//
+
+_kSecPolicyAppleX509Basic
+_kSecPolicyAppleSSL
+_kSecPolicyAppleSMIME
+_kSecPolicyAppleEAP
+_kSecPolicyAppleIPsec
+_kSecPolicyAppleCodeSigning
+_kSecPolicyAppleIDValidation
+_kSecPolicyAppleIDValidationRecordSigningPolicy
+_kSecPolicyAppleTimeStamping
+_kSecPolicyAppleRevocation
+_kSecPolicyApplePassbookSigning
+_kSecPolicyAppleMobileStore
+_kSecPolicyAppleTestMobileStore
+_kSecPolicyAppleOTAPKISigner
+_kSecPolicyAppleTestOTAPKISigner
+_kSecPolicyAppleEscrowService
+_kSecPolicyAppleProfileSigner
+_kSecPolicyAppleQAProfileSigner
+_kSecPolicyCheckAnchorSHA1
+_kSecPolicyCheckAnchorTrusted
+_kSecPolicyCheckBasicCertificateProcessing
+_kSecPolicyCheckBasicContraints
+_kSecPolicyCheckBlackListedKey
+_kSecPolicyCheckBlackListedLeaf
+_kSecPolicyCheckCertificatePolicy
+_kSecPolicyCheckChainLength
+_kSecPolicyCheckCriticalExtensions
+_kSecPolicyCheckEAPTrustedServerNames
+_kSecPolicyCheckEmail
+_kSecPolicyCheckExtendedKeyUsage
+_kSecPolicyCheckExtendedValidation
+_kSecPolicyCheckGrayListedKey
+_kSecPolicyCheckGrayListedLeaf
+_kSecPolicyCheckIdLinkage
+_kSecPolicyCheckIntermediateMarkerOid
+_kSecPolicyCheckIssuerCommonName
+_kSecPolicyCheckKeyUsage
+_kSecPolicyCheckLeafMarkerOid
+_kSecPolicyCheckNoNetworkAccess
+_kSecPolicyCheckNonEmptySubject
+_kSecPolicyCheckNotValidBefore
+_kSecPolicyCheckQualifiedCertStatements
+_kSecPolicyCheckRevocation
+_kSecPolicyCheckSSLHostname
+_kSecPolicyCheckSubjectCommonName
+_kSecPolicyCheckSubjectCommonNamePrefix
+_kSecPolicyCheckSubjectCommonNameTEST
+_kSecPolicyCheckSubjectOrganization
+_kSecPolicyCheckSubjectOrganizationalUnit
+_kSecPolicyCheckValidIntermediates
+_kSecPolicyCheckValidLeaf
+_kSecPolicyCheckValidRoot
+_kSecPolicyClient
+_kSecPolicyName
+_kSecPolicyOid
+_kSecPolicyRevocationFlags
+_kSecPolicyTeamIdentifier
+
+
+_SecPolicyCopyEscrowRootCertificate
+_SecPolicyCopyProperties
+_SecPolicyCreate
+_SecPolicyCreateAppleIDAuthorityPolicy
+#if TARGET_OS_IPHONE
+_SecPolicyCreateAppleIDValidationRecordSigningPolicy
+#endif
+_SecPolicyCreateBasicX509
+_SecPolicyCreateCodeSigning
+_SecPolicyCreateConfigurationProfileSigner
+_SecPolicyCreateQAConfigurationProfileSigner
+#if TARGET_OS_IPHONE
+_SecPolicyCreateOTAPKISigner
+_SecPolicyCreateTestOTAPKISigner
+#endif
+_SecPolicyCreateEAP
+_SecPolicyCreateEscrowServiceSigner
+_SecPolicyCreateFactoryDeviceCertificate
+_SecPolicyCreateIPSec
+_SecPolicyCreateMobileStoreSigner
+_SecPolicyCreateTestMobileStoreSigner
+_SecPolicyCreateOCSPSigner
+_SecPolicyCreateRevocation
+_SecPolicyCreatePassbookCardSigner
+_SecPolicyCreateShoeboxCardSigner
+_SecPolicyCreateSMIME
+_SecPolicyCreateSSL
+_SecPolicyCreateiAP
+_SecPolicyCreateiPhoneActivation
+_SecPolicyCreateiPhoneApplicationSigning
+_SecPolicyCreateiPhoneDeviceCertificate
+_SecPolicyCreateiPhoneProfileApplicationSigning
+_SecPolicyCreateiPhoneProvisioningProfileSigning
+_SecPolicyCreateiTunesStoreURLBag
+_SecPolicyCreateLockdownPairing
+_SecPolicyCreateMobileAsset
+_SecPolicyCreateOTATasking
+_SecPolicyCreateURLBag
+_SecPolicyCreateWithProperties
+_SecPolicyGetTypeID
+
+
+_kSecPropertyKeyLabel
+_kSecPropertyKeyLocalizedLabel
+_kSecPropertyKeyType
+_kSecPropertyKeyValue
+_kSecPropertyTypeData
+_kSecPropertyTypeDate
+_kSecPropertyTypeError
+_kSecPropertyTypeSection
+_kSecPropertyTypeString
+_kSecPropertyTypeSuccess
+_kSecPropertyTypeTitle
+_kSecPropertyTypeURL
+_kSecPropertyTypeWarning
+
+_kSecTrustEvaluationDate
+_kSecTrustExtendedValidation
+_kSecTrustOrganizationName
+_kSecTrustResultValue
+_kSecTrustRevocationChecked
+_kSecTrustRevocationValidUntilDate
+_kSecTrustInfoCompanyNameKey
+_kSecTrustInfoExtendedValidationKey
+_kSecTrustInfoRevocationKey
+_kSecTrustInfoRevocationValidUntilKey
+
+_SecTrustCopyCustomAnchorCertificates
+_SecTrustCopyDetailedPropertiesAtIndex
+_SecTrustCopyExceptions
+_SecTrustCopyFailureDescription
+_SecTrustCopyInfo
+_SecTrustCopyPolicies
+_SecTrustCopyProperties
+_SecTrustCopyPublicKey
+_SecTrustCopyResult
+_SecTrustCopySummaryPropertiesAtIndex
+_SecTrustCreateWithCertificates
+_SecTrustEvaluate
+_SecTrustEvaluateAsync
+_SecTrustGetCertificateAtIndex
+_SecTrustGetCertificateCount
+_SecTrustGetDetails
+_SecTrustGetNetworkFetchAllowed
+_SecTrustGetOTAPKIAssetVersionNumber
+_SecTrustOTAPKIGetUpdatedAsset
+_SecTrustGetTrustResult
+_SecTrustGetTypeID
+_SecTrustGetVerifyTime
+_SecTrustSetAnchorCertificates
+_SecTrustSetAnchorCertificatesOnly
+_SecTrustSetExceptions
+_SecTrustSetNetworkFetchAllowed
+_SecTrustSetOCSPResponse
+_SecTrustSetPolicies
+_SecTrustSetVerifyDate
+_SecTrustStoreContains
+_SecTrustStoreForDomain
+_SecTrustStoreGetSettingsVersionNumber
+_SecTrustStoreRemoveCertificate
+_SecTrustStoreSetTrustSettings
+
+//
+// Identity
+//
+
+_SecIdentityCopyCertificate
+_SecIdentityCopyPrivateKey
+_SecIdentityCreate
+_SecIdentityGetTypeID
+_SecIdentitySignCertificate
+
+//
+// Certificate
+//
+
+_kSecCertificateKeyUsage
+_kSecCertificateExtensions
+_SecCertificateCopyCommonNames
+_SecCertificateCopyCompanyName
+_SecCertificateCopyEscrowRoots
+_SecCertificateCopyDNSNames
+_SecCertificateCopyData
+_SecCertificateCopyExtendedKeyUsage
+_SecCertificateCopyIPAddresses
+_SecCertificateCopyIssuerSHA1Digest
+_SecCertificateCopyIssuerSequence
+_SecCertificateCopyIssuerSummary
+_SecCertificateCopyNTPrincipalNames
+_SecCertificateCopyOrganization
+_SecCertificateCopyOrganizationalUnit
+_SecCertificateCopyProperties
+_SecCertificateCopyPublicKey
+_SecCertificateCopyPublicKeySHA1Digest
+_SecCertificateCopyRFC822Names
+_SecCertificateCopySerialNumber
+_SecCertificateCopySubjectSequence
+_SecCertificateCopySubjectString
+_SecCertificateCopySubjectSummary
+_SecCertificateCopySummaryProperties
+_SecCertificateCreate
+_SecCertificateCreateWithBytes
+_SecCertificateCreateWithData
+_SecCertificateCreateWithPEM
+_SecCertificateGetAuthorityKeyID
+_SecCertificateGetBasicConstraints
+_SecCertificateGetBytePtr
+_SecCertificateGetCAIssuers
+_SecCertificateGetCertificatePolicies
+_SecCertificateGetInhibitAnyPolicySkipCerts
+_SecCertificateGetKeyUsage
+_SecCertificateGetLength
+_SecCertificateGetNormalizedIssuerContent
+_SecCertificateGetNormalizedSubjectContent
+_SecDistinguishedNameCopyNormalizedContent
+_SecCertificateGetOCSPResponders
+_SecCertificateGetPolicyConstraints
+_SecCertificateGetPublicKeyAlgorithm
+_SecCertificateGetPublicKeyData
+_SecCertificateGetSHA1Digest
+_SecCertificateGetSubjectKeyID
+_SecCertificateGetTypeID
+_SecCertificateHasCriticalSubjectAltName
+_SecCertificateHasMarkerExtension
+_SecCertificateHasSubject
+_SecCertificateHasUnknownCriticalExtension
+_SecCertificateIsSelfSignedCA
+_SecCertificateIsValid
+_SecCertificateNotValidAfter
+_SecCertificateNotValidBefore
+_SecCertificatePathCopyAddingLeaf
+_SecCertificatePathCopyFromParent
+_SecCertificatePathCopyPublicKeyAtIndex
+_SecCertificatePathCreate
+_SecCertificatePathGetCertificateAtIndex
+_SecCertificatePathGetCount
+_SecCertificatePathGetIndexOfCertificate
+_SecCertificatePathGetNextSourceIndex
+_SecCertificatePathGetRoot
+_SecCertificatePathIsAnchored
+_SecCertificatePathScore
+_SecCertificatePathSelfSignedIndex
+_SecCertificatePathSetIsAnchored
+_SecCertificatePathSetNextSourceIndex
+_SecCertificatePathSetSelfIssued
+_SecCertificatePathVerify
+_SecCertificateVersion
+_kSecCertificateProductionEscrowKey
+_kSecCertificateEscrowFileName
+
+//
+// SCEP
+//
+_SecSCEPCreateTemporaryIdentity
+_SecSCEPCertifyRequest
+_SecSCEPGenerateCertificateRequest
+_SecSCEPVerifyReply
+_SecSCEPValidateCACertMessage
+_SecSCEPGetCertInitial
+
+//
+// CSR
+//
+
+_kSecSubjectAltName
+_SecVerifyCertificateRequest
+_SecGenerateCertificateRequest
+_SecGenerateCertificateRequestWithParameters
+_SecGenerateSelfSignedCertificate
+
+//
+// OTR
+//
+_SecOTRDHKGenerateOTRKeys
+_SecOTRFullDHKCreate
+_SecOTRPublicDHKCreateFromFullKey
+_SecOTRSessionCreateFromID
+_SecOTRSessionCreateFromIDAndFlags
+_SecOTRSessionCreateFromData
+_SecOTRSessionReset
+_SecOTRSAppendSerialization
+_SecOTRSAppendStartPacket
+_SecOTRSAppendRestartPacket
+_SecOTRSProcessPacket
+_SecOTRSEndSession
+_SecOTRSGetIsReadyForMessages
+_SecOTRSGetIsIdle
+_SecOTRSGetMessageKind
+_SecOTRSSignAndProtectMessage
+_SecOTRSVerifyAndExposeMessage
+_SecOTRSPrecalculateKeys
+_SecOTRFIAppendSerialization
+_SecOTRFIPurgeAllFromKeychain
+_SecOTRFIPurgeFromKeychain
+_SecOTRFullIdentityCreate
+_SecOTRFullIdentityCreateFromData
+_SecOTRFullIdentityCreateFromSecKeyRef
+_SecOTRPIAppendSerialization
+_SecOTRPublicIdentityCopyFromPrivate
+_SecOTRPublicIdentityCreateFromData
+_SecOTRPublicIdentityCreateFromSecKeyRef
+_SecOTRPacketTypeString
+
+//
+// DH
+//
+
+_SecDHComputeKey
+_SecDHCreate
+_SecDHCreateFromAlgorithmId
+_SecDHCreateFromParameters
+_SecDHDestroy
+_SecDHGenerateKeypair
+_SecDHGetMaxKeyLength
+
+//
+// Securityd client
+//
+
+_gSecurityd
+
+//
+// XPC
+//
+
+_kSecXPCKeyPeerInfos
+_kSecXPCKeyOperation
+_kSecXPCKeyResult
+_kSecXPCKeyError
+_kSecXPCKeyUserLabel
+_kSecXPCKeyUserPassword
+_sSecXPCErrorDomain
+_kSecXPCKeyOTAFileDirectory
+
+
+//
+// CMS
+//
+
+_kSecCMSBulkEncryptionAlgorithm
+_kSecCMSSignDigest
+_kSecCMSSignDetached
+_kSecCMSSignHashAlgorithm
+_kSecCMSEncryptionAlgorithmDESCBC
+_kSecCMSEncryptionAlgorithmAESCBC
+_kSecCMSHashingAlgorithmMD5
+_kSecCMSCertChainMode
+_kSecCMSAdditionalCerts
+_kSecCMSSignedAttributes
+_kSecCMSSignDate
+_kSecCMSAllCerts
+_kSecCMSCertChainModeNone
+_SecCmsContentInfoGetBulkKey
+_SecCmsContentInfoGetBulkKeySize
+_SecCmsContentInfoGetChildContentInfo
+_SecCmsContentInfoGetContent
+_SecCmsContentInfoGetContentEncAlg
+_SecCmsContentInfoGetContentEncAlgTag
+_SecCmsContentInfoGetContentTypeOID
+_SecCmsContentInfoGetContentTypeTag
+_SecCmsContentInfoGetInnerContent
+_SecCmsContentInfoSetBulkKey
+_SecCmsContentInfoSetContentData
+_SecCmsContentInfoSetContentDigestedData
+_SecCmsContentInfoSetContentEncAlg
+_SecCmsContentInfoSetContentEncAlgID
+_SecCmsContentInfoSetContentEncryptedData
+_SecCmsContentInfoSetContentEnvelopedData
+_SecCmsContentInfoSetContentSignedData
+_SecCmsDecoderCreate
+_SecCmsDecoderDestroy
+_SecCmsDecoderFinish
+_SecCmsDecoderUpdate
+_SecCmsDigestContextCancel
+_SecCmsDigestContextDestroy
+_SecCmsDigestContextFinishMultiple
+_SecCmsDigestContextStartMultiple
+_SecCmsDigestContextUpdate
+_SecCmsDigestedDataCreate
+_SecCmsDigestedDataDestroy
+_SecCmsDigestedDataGetContentInfo
+_SecCmsEncoderCreate
+_SecCmsEncoderDestroy
+_SecCmsEncoderFinish
+_SecCmsEncoderUpdate
+_SecCmsEncryptedDataCreate
+_SecCmsEncryptedDataDestroy
+_SecCmsEncryptedDataGetContentInfo
+_SecCmsEnvelopedDataCreate
+_SecCmsEnvelopedDataDestroy
+_SecCmsEnvelopedDataGetContentInfo
+_SecCmsMessageContainsCertsOrCrls
+_SecCmsMessageContentLevel
+_SecCmsMessageContentLevelCount
+_SecCmsMessageCopy
+_SecCmsMessageCreate
+_SecCmsMessageDecode
+_SecCmsMessageDestroy
+_SecCmsMessageEncode
+_SecCmsMessageGetContent
+_SecCmsMessageGetContentInfo
+_SecCmsMessageIsContentEmpty
+_SecCmsMessageIsEncrypted
+_SecCmsMessageIsSigned
+_SecCmsRecipientInfoCreate
+_SecCmsRecipientInfoCreateWithSubjKeyID
+_SecCmsSignedDataAddCertChain
+_SecCmsSignedDataAddCertList
+_SecCmsSignedDataAddCertificate
+_SecCmsSignedDataContainsCertsOrCrls
+_SecCmsSignedDataCreate
+_SecCmsSignedDataCreateCertsOnly
+_SecCmsSignedDataDestroy
+_SecCmsSignedDataGetCertificateList
+_SecCmsSignedDataGetContentInfo
+_SecCmsSignedDataGetDigestAlgs
+_SecCmsSignedDataGetSignerInfo
+_SecCmsSignedDataGetSignerInfos
+_SecCmsSignedDataHasDigests
+_SecCmsSignedDataImportCerts
+_SecCmsSignedDataSetDigestContext
+_SecCmsSignedDataSignerInfoCount
+_SecCmsSignedDataVerifyCertsOnly
+_SecCmsSignedDataVerifySignerInfo
+_SecCmsSignerInfoAddCounterSignature
+_SecCmsSignerInfoAddMSSMIMEEncKeyPrefs
+_SecCmsSignerInfoAddSMIMECaps
+_SecCmsSignerInfoAddSMIMEEncKeyPrefs
+_SecCmsSignerInfoAddSigningTime
+_SecCmsSignerInfoCreate
+_SecCmsSignerInfoCreateWithSubjKeyID
+_SecCmsSignerInfoGetCertList
+_SecCmsSignerInfoGetDigestAlg
+_SecCmsSignerInfoGetDigestAlgTag
+_SecCmsSignerInfoGetSignerCommonName
+_SecCmsSignerInfoGetSignerEmailAddress
+_SecCmsSignerInfoGetSigningCertificate
+_SecCmsSignerInfoGetSigningTime
+_SecCmsSignerInfoGetVerificationStatus
+_SecCmsSignerInfoIncludeCerts
+_SecCmsSignerInfoSaveSMIMEProfile
+_SecCmsUtilVerificationStatusToString
+_SecCMSCertificatesOnlyMessageCopyCertificates
+_SecCMSCreateCertificatesOnlyMessage
+_SecCMSCreateCertificatesOnlyMessageIAP
+_SecCMSCreateEnvelopedData
+_SecCMSDecryptEnvelopedData
+_SecCMSSignDataAndAttributes
+_SecCMSSignDigestAndAttributes
+_SecCMSVerify
+_SecCMSVerifyCopyDataAndAttributes
+_SecCMSVerifySignedData
+_SecCMSCreateSignedData
+
+//
+// pbkdf2
+//
+
+_pbkdf2
+_pbkdf2_hmac_sha1
+_hmac_sha1_PRF
+_SecKeyFromPassphraseDataHMACSHA1
+
+//
+// Key
+//
+
+_SecKeyCopyAttributeDictionary
+_SecKeyCopyMatchingPrivateKey
+_SecKeyCopyPersistentRef
+_SecKeyCopyPublicBytes
+_SecKeyCreate
+_SecKeyCreatePublicFromPrivate
+_SecKeyCreateFromAttributeDictionary
+_SecKeyCreateECPrivateKey
+_SecKeyCreateECPublicKey
+_SecKeyCreateFromPublicBytes
+_SecKeyCreateFromPublicData
+_SecKeyCreatePersistentRefToMatchingPrivateKey
+_SecKeyCreateRSAPrivateKey
+_SecKeyCreateRSAPublicKey
+_SecKeyDecrypt
+_SecKeyFindWithPersistentRef
+_SecKeyDigestAndSign
+_SecKeyDigestAndVerify
+_SecKeyEncrypt
+_SecKeyGeneratePair
+_SecKeyGetAlgorithmID
+_SecKeyGetBlockSize
+_SecKeyGetSize
+_SecKeyGetTypeID
+_SecKeyRawSign
+_SecKeyRawVerify
+_kSecPrivateKeyAttrs
+_kSecPublicKeyAttrs
+
+//
+// Keychain/SecItem
+//
+
+_kSecAttrAFPServerSignature
+_kSecAttrAccessGroup
+_kSecAttrAccessible
+_kSecAttrAccessibleAfterFirstUnlock
+_kSecAttrAccessibleAlways
+_kSecAttrAccessibleWhenUnlocked
+_kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
+_kSecAttrAccessibleAlwaysThisDeviceOnly
+_kSecAttrAccessibleWhenUnlockedThisDeviceOnly
+_kSecAttrAccount
+_kSecAttrAddress
+_kSecAttrAlias
+_kSecAttrApplicationLabel
+_kSecAttrApplicationTag
+_kSecAttrAuthenticationType
+_kSecAttrAuthenticationTypeDPA
+_kSecAttrAuthenticationTypeDefault
+_kSecAttrAuthenticationTypeHTMLForm
+_kSecAttrAuthenticationTypeHTTPBasic
+_kSecAttrAuthenticationTypeHTTPDigest
+_kSecAttrAuthenticationTypeMSN
+_kSecAttrAuthenticationTypeNTLM
+_kSecAttrAuthenticationTypeRPA
+_kSecAttrCRLEncoding
+_kSecAttrCRLType
+_kSecAttrCanDecrypt
+_kSecAttrCanDerive
+_kSecAttrCanEncrypt
+_kSecAttrCanSign
+_kSecAttrCanSignRecover
+_kSecAttrCanUnwrap
+_kSecAttrCanVerify
+_kSecAttrCanVerifyRecover
+_kSecAttrCanWrap
+_kSecAttrCertificateEncoding
+_kSecAttrCertificateType
+_kSecAttrComment
+_kSecAttrCreationDate
+_kSecAttrCreator
+_kSecAttrDescription
+_kSecAttrEffectiveKeySize
+_kSecAttrEndDate
+_kSecAttrGeneric
+_kSecAttrHasCustomIcon
+_kSecAttrIsExtractable
+_kSecAttrIsInvisible
+_kSecAttrIsModifiable
+_kSecAttrIsNegative
+_kSecAttrIsPermanent
+_kSecAttrIsPrivate
+_kSecAttrIsSensitive
+_kSecAttrIssuer
+_kSecAttrKeyClass
+_kSecAttrKeyClassPrivate
+_kSecAttrKeyClassPublic
+_kSecAttrKeyClassSymmetric
+_kSecAttrKeyCreator
+_kSecAttrKeySizeInBits
+_kSecAttrKeyType
+_kSecAttrKeyTypeEC
+_kSecAttrKeyTypeRSA
+_kSecAttrLabel
+_kSecAttrModificationDate
+_kSecAttrPath
+_kSecAttrPort
+_kSecAttrProtocol
+_kSecAttrProtocolAFP
+_kSecAttrProtocolAppleTalk
+_kSecAttrProtocolDAAP
+_kSecAttrProtocolEPPC
+_kSecAttrProtocolFTP
+_kSecAttrProtocolFTPAccount
+_kSecAttrProtocolFTPProxy
+_kSecAttrProtocolFTPS
+_kSecAttrProtocolHTTP
+_kSecAttrProtocolHTTPProxy
+_kSecAttrProtocolHTTPS
+_kSecAttrProtocolHTTPSProxy
+_kSecAttrProtocolIMAP
+_kSecAttrProtocolIMAPS
+_kSecAttrProtocolIPP
+_kSecAttrProtocolIRC
+_kSecAttrProtocolIRCS
+_kSecAttrProtocolLDAP
+_kSecAttrProtocolLDAPS
+_kSecAttrProtocolNNTP
+_kSecAttrProtocolNNTPS
+_kSecAttrProtocolPOP3
+_kSecAttrProtocolPOP3S
+_kSecAttrProtocolRTSP
+_kSecAttrProtocolRTSPProxy
+_kSecAttrProtocolSMB
+_kSecAttrProtocolSMTP
+_kSecAttrProtocolSOCKS
+_kSecAttrProtocolSSH
+_kSecAttrProtocolTelnet
+_kSecAttrProtocolTelnetS
+_kSecAttrPublicKeyHash
+_kSecAttrScriptCode
+_kSecAttrSecurityDomain
+_kSecAttrSerialNumber
+_kSecAttrServer
+_kSecAttrService
+_kSecAttrStartDate
+_kSecAttrSubject
+_kSecAttrSubjectKeyID
+_kSecAttrSynchronizable
+_kSecAttrSynchronizableAny
+_kSecAttrTombstone
+_kSecAttrType
+_kSecAttrVolume
+_kSecAttrWasAlwaysSensitive
+_kSecAttrWasNeverExtractable
+_kSecClass
+_kSecClassAppleSharePassword
+_kSecClassCertificate
+_kSecClassGenericPassword
+_kSecClassIdentity
+_kSecClassInternetPassword
+_kSecClassKey
+_kSecImportExportPassphrase
+_kSecImportItemCertChain
+_kSecImportItemIdentity
+_kSecImportItemKeyID
+_kSecImportItemLabel
+_kSecImportItemTrust
+_kSecUseItemList
+_kSecUseTombstones
+_kSecValueData
+_kSecValuePersistentRef
+_kSecValueRef
+_kSecMatchCaseInsensitive
+_kSecMatchEmailAddressIfPresent
+_kSecMatchIssuers
+_kSecMatchItemList
+_kSecMatchLimit
+_kSecMatchLimitAll
+_kSecMatchLimitOne
+_kSecMatchPolicy
+_kSecMatchSearchList
+_kSecMatchSubjectContains
+_kSecMatchTrustedOnly
+_kSecMatchValidOnDate
+_kSecReturnAttributes
+_kSecReturnData
+_kSecReturnPersistentRef
+_kSecReturnRef
+_SecItemAdd
+_SecItemCopyDisplayNames
+_SecItemCopyMatching
+_SecItemDelete
+_SecItemDeleteAll
+_SecItemUpdate
+__SecItemMakePersistentRef
+__SecItemParsePersistentRef
+__SecKeychainCopyBackup
+__SecKeychainCopyOTABackup
+__SecKeychainRestoreBackup
+__SecKeychainSyncUpdate
+__SecKeychainBackupSyncable
+__SecKeychainRestoreSyncable
+
+_kSecXPCKeyAttributesToUpdate
+_kSecXPCKeyBackup
+_kSecXPCKeyCertificate
+_kSecXPCKeyDigest
+_kSecXPCKeyDomain
+_kSecXPCKeyKeybag
+_kSecXPCKeyQuery
+_kSecXPCKeySettings
+
+_SecCertificatePathCopyXPCArray
+_SecCertificateXPCArrayCopyArray
+_SecPolicyXPCArrayCopyArray
+_SecServerSetMachServiceName
index ed6f42b26ae43d43af2c7375be220fa80687de0b..b9a4bf5f96e03cef06cbf2c1de9ac1c45a412814 100644 (file)
 #include <CoreFoundation/CFURLAccess.h>
 #include <Security/SecRandom.h>
 #include <CommonCrypto/CommonDigest.h>
 #include <CoreFoundation/CFURLAccess.h>
 #include <Security/SecRandom.h>
 #include <CommonCrypto/CommonDigest.h>
+#include <CommonCrypto/CommonDigestSPI.h>
 #include <Security/SecAsn1Coder.h>
 #include <Security/oidsalg.h>
 #include <fcntl.h>
 #include <sys/types.h>
 #include <unistd.h>
 #include <Security/SecAsn1Coder.h>
 #include <Security/oidsalg.h>
 #include <fcntl.h>
 #include <sys/types.h>
 #include <unistd.h>
-#include <security_utilities/debugging.h>
-#include <MacErrors.h>
+#include <utilities/debugging.h>
+#include <Security/SecBase.h>
 #include <errno.h>
 #include <errno.h>
+#include <inttypes.h>
 
 /* Security.framework's bundle id. */
 static CFStringRef kSecFrameworkBundleID = CFSTR("com.apple.Security");
 
 /* Security.framework's bundle id. */
 static CFStringRef kSecFrameworkBundleID = CFSTR("com.apple.Security");
@@ -97,7 +99,7 @@ CFDataRef SecFrameworkCopyResourceContents(CFStringRef resourceName,
         SInt32 error;
         if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault,
             url, &data, NULL, NULL, &error)) {
         SInt32 error;
         if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault,
             url, &data, NULL, NULL, &error)) {
-            secwarning("read: %@: %d", error);
+            secwarning("read: %ld", (long) error);
         }
         CFRelease(url);
     }
         }
         CFRelease(url);
     }
@@ -112,7 +114,7 @@ CFDataRef SecSHA1DigestCreate(CFAllocatorRef allocator,
                CC_SHA1_DIGEST_LENGTH);
        CFDataSetLength(digest, CC_SHA1_DIGEST_LENGTH);
        //FIXME: Cast from CFIndex to CC_LONG
                CC_SHA1_DIGEST_LENGTH);
        CFDataSetLength(digest, CC_SHA1_DIGEST_LENGTH);
        //FIXME: Cast from CFIndex to CC_LONG
-       CC_SHA1(data, (CC_LONG)length, CFDataGetMutableBytePtr(digest));
+       CCDigest(kCCDigestSHA1, data, (CC_LONG)length, CFDataGetMutableBytePtr(digest));
        return digest;
 }
 
        return digest;
 }
 
@@ -161,7 +163,7 @@ static void SecDevRandomOpen(void) {
 
 int SecRandomCopyBytes(SecRandomRef rnd, size_t count, uint8_t *bytes) {
     if (rnd != kSecRandomDefault)
 
 int SecRandomCopyBytes(SecRandomRef rnd, size_t count, uint8_t *bytes) {
     if (rnd != kSecRandomDefault)
-        return paramErr;
+        return errSecParam;
     pthread_once(&kSecDevRandomOpen, SecDevRandomOpen);
     if (kSecRandomFD < 0)
         return -1;
     pthread_once(&kSecDevRandomOpen, SecDevRandomOpen);
     if (kSecRandomFD < 0)
         return -1;
@@ -208,7 +210,7 @@ SecRandomRef SecRandomCreate(CFIndex randomAlg, CFIndex seedLength,
 
        if (seedLength) {
                /* Digest the seed and put it into output. */
 
        if (seedLength) {
                /* Digest the seed and put it into output. */
-               CC_SHA1(seed, seedLength, result->block);
+               CCDigest(kCCDigestSHA1, seed, seedLength, result->block);
        } else {
                /* Seed 20 bytes from "/dev/srandom". */
                int fd = open("/dev/srandom", O_RDONLY);
        } else {
                /* Seed 20 bytes from "/dev/srandom". */
                int fd = open("/dev/srandom", O_RDONLY);
index bfba8ee9491bb5943d28299f3026290cd1311f79..6b1f6e0e333db519e16747b43c086733f885571e 100644 (file)
@@ -34,9 +34,7 @@
 #include <CoreFoundation/CFURL.h>
 #include <Security/SecAsn1Types.h>
 
 #include <CoreFoundation/CFURL.h>
 #include <Security/SecAsn1Types.h>
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 #define SecString(key, comment)  CFSTR(key)
 #define SecStringFromTable(key, tbl, comment)  CFSTR(key)
 
 #define SecString(key, comment)  CFSTR(key)
 #define SecStringFromTable(key, tbl, comment)  CFSTR(key)
@@ -61,8 +59,9 @@ CFDataRef SecDigestCreate(CFAllocatorRef allocator,
     const SecAsn1Oid *algorithm, const SecAsn1Item *params,
        const UInt8 *data, CFIndex length);
 
     const SecAsn1Oid *algorithm, const SecAsn1Item *params,
        const UInt8 *data, CFIndex length);
 
-#if defined(__cplusplus)
-}
-#endif
+// Wrapper to provide a CFErrorRef for legacy API.
+OSStatus SecOSStatusWith(bool (^perform)(CFErrorRef *error));
+
+__END_DECLS
 
 #endif /* !_SECURITY_SECFRAMEWORK_H_ */
 
 #endif /* !_SECURITY_SECFRAMEWORK_H_ */
index 4e02039a37b2c4ffe27e00a3abaeca325064a486..51f847e86bf003d03133c63532d1c0d55affcde5 100644 (file)
 
 #include <Security/SecFramework.h>
 
 
 #include <Security/SecFramework.h>
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 #define SecCopyCertString(KEY) SecFrameworkCopyLocalizedString(KEY, CFSTR("Certificate"))
 
 #define SecCopyCertString(KEY) SecFrameworkCopyLocalizedString(KEY, CFSTR("Certificate"))
+#define SecCopyCKString(KEY) SecFrameworkCopyLocalizedString(KEY, CFSTR("CloudKeychain"))
 
 /* SecCertificate Strings */
 #define SEC_NULL_KEY                SecStringWithDefaultValue("<NULL>", "Certificate", 0, "<NULL>", "Value of a field if its length is 0")
 
 /* SecCertificate Strings */
 #define SEC_NULL_KEY                SecStringWithDefaultValue("<NULL>", "Certificate", 0, "<NULL>", "Value of a field if its length is 0")
@@ -182,8 +181,41 @@ extern "C" {
 #define SEC_POLICY__REQ_NOT_MET_KEY SecStringWithDefaultValue("Policy requirements not met.", "Certificate", 0, "Policy requirements not met.", "")
 #define SEC_CHAIN_VALIDITY_ERR_KEY  SecStringWithDefaultValue("One or more certificates have expired or are not valid yet.", "Certificate", 0, "One or more certificates have expired or are not valid yet.", "")
 
 #define SEC_POLICY__REQ_NOT_MET_KEY SecStringWithDefaultValue("Policy requirements not met.", "Certificate", 0, "Policy requirements not met.", "")
 #define SEC_CHAIN_VALIDITY_ERR_KEY  SecStringWithDefaultValue("One or more certificates have expired or are not valid yet.", "Certificate", 0, "One or more certificates have expired or are not valid yet.", "")
 
-#if defined(__cplusplus)
-}
-#endif
+#define SEC_CK_PASSWORD_INCORRECT   SecStringWithDefaultValue("iCloud Password incorrect, try again", "CloudKeychain", 0, "iCloud password is incorrect, try again", "Title for alert when password has been entered incorrectly")
+#define SEC_CK_ALLOW                SecStringWithDefaultValue("Allow", "CloudKeychain", 0, "Allow", "Allow button")
+#define SEC_CK_DONT_ALLOW           SecStringWithDefaultValue("Don't Allow", "CloudKeychain", 0, "Don't Allow", "Don't Allow button")
+#define SEC_CK_ICLOUD_PASSWORD      SecStringWithDefaultValue("Password", "CloudKeychain", 0, "Password", "Password prompt text")
+#define SEC_CK_JOIN_PROMPT          SecStringWithDefaultValue("Enter the Apple ID password for “%@” to allow %@ to use iCloud Keychain.", "CloudKeychain", 0, "Enter the Apple ID password for “%@” to allow %@ to use iCloud Keychain.", "Message for alert when a new device is joining the circle")
+#define SEC_CK_JOIN_TITLE           SecStringWithDefaultValue("Allow “%@” to use your passwords?", "CloudKeychain", 0, "Allow “%@” to use iCloud Keychain?", "Title for alert when a new device is joining the circle")
+
+#define SEC_CK_ARS0_TITLE             SecStringWithDefaultValue("Waiting for Approval to Use iCloud Keychain", "CloudKeychain", 0, "Waiting for Approval to Use iCloud Keychain", "Title for alert when this device's application has been pending for a long time & no security code is set")
+#define SEC_CK_ARS0_BODY              SecStringWithDefaultValue("%@ must be approved from one of your other devices using iCloud Keychain. If no other devices are available, reset iCloud Keychain in Settings.%@", "CloudKeychain", 0, "%@ must be approved from one of your other devices using iCloud Keychain. If no other devices are available, reset iCloud Keychain in Settings.%@", "Explanation of the waiting for approval alert")
+#define SEC_CK_ARS1_TITLE             SecStringWithDefaultValue("Use Security Code to Turn On iCloud Keychain?", "CloudKeychain", 0, "Use Security Code to Turn On iCloud Keychain?", "Title for alert when this device's application has been pending for a long time & a security code is set")
+#define SEC_CK_ARS1_BODY              SecStringWithDefaultValue("This iPhone is still waiting for approval from one of your other devices using iCloud Keychain. You can use your Security Code to turn on iCloud Keychain.%@", "CloudKeychain", 0, "This iPhone is still waiting for approval from one of your other devices using iCloud Keychain. You can use your Security Code to turn on iCloud Keychain.%@", "Explanation of the waiting for approval alert")
+#define SEC_CK_AR_APPROVE_OTHER     SecStringWithDefaultValue("Approve with Other Device", "CloudKeychain", 0, "Approve with Other Device", "Button text for approval with other device")
+#define SEC_CK_AR_USE_CODE          SecStringWithDefaultValue("Use Security Code", "CloudKeychain", 0, "Use Security Code", "Button text for approval via security code")
+
+#define SEC_CK_TID_FUTURE           SecStringWithDefaultValue("the future", "CloudKeychain", 0, "the future", "the future")
+#define SEC_CK_TID_NOW              SecStringWithDefaultValue("now", "CloudKeychain", 0, "now", "now")
+#define SEC_CK_TID_SUBSECOND        SecStringWithDefaultValue("less then a second", "CloudKeychain", 0, "less then a second", "Less then then one second")
+#define SEC_CK_TID_SECONDS          SecStringWithDefaultValue("seconds", "CloudKeychain", 0, "seconds", "More then one second")
+#define SEC_CK_TID_MINUTES          SecStringWithDefaultValue("minutes", "CloudKeychain", 0, "minutes", "More then one minute")
+#define SEC_CK_TID_HOURS            SecStringWithDefaultValue("hours", "CloudKeychain", 0, "hours", "More then one hour")
+#define SEC_CK_TID_DAY              SecStringWithDefaultValue("day", "CloudKeychain", 0, "day", "One day")
+#define SEC_CK_TID_DAYS             SecStringWithDefaultValue("days", "CloudKeychain", 0, "days", "More then one day")
+
+#define SEC_CK_CR_TITLE             SecStringWithDefaultValue("iCloud Keychain Reset", "CloudKeychain", 0, "iCloud Keychain Reset", "Title for alert when this device has left the circle")
+#define SEC_CK_CR_BODY_REVOKED      SecStringWithDefaultValue("%@ is no longer participating in iCloud Keychain because it was reset by another device", "CloudKeychain", 0, "%@ is no longer participating in iCloud Keychain because it was reset by another device", "Body text for kSOSMembershipRevoked")
+#define SEC_CK_CR_BODY_LEFT_UNTRUSTED SecStringWithDefaultValue("%@ is no longer participating in iCloud Keychain!", "CloudKeychain", 0, "%@ is no longer participating in iCloud Keychain!", "Body text for kSOSLeftUntrustedCircle")
+#define SEC_CK_CR_BODY_UNKNOWN      SecStringWithDefaultValue("%@ is no longer participating in iCloud Keychain.", "CloudKeychain", 0, "%@ is no longer participating in iCloud Keychain.", "Body text for unknown departure reason")
+#define SEC_CK_CR_OK                           SecStringWithDefaultValue("OK", "CloudKeychain", 0, "OK", "Button text for confused user who just wants the alert to go away")
+#define SEC_CK_CR_USE_CODE          SecStringWithDefaultValue("Use Security Code", "CloudKeychain", 0, "Use Security Code", "Button text for approval via security code")
+
+#define SEC_CK_THIS_IPHONE          SecStringWithDefaultValue("This iPhone", "CloudKeychain", 0, "This iPhone", "This iPhone")
+#define SEC_CK_THIS_IPOD            SecStringWithDefaultValue("This iPod", "CloudKeychain", 0, "This iPod", "This iPod")
+#define SEC_CK_THIS_IPAD            SecStringWithDefaultValue("This iPad", "CloudKeychain", 0, "This iPad", "This iPad")
+#define SEC_CK_THIS_DEVICE          SecStringWithDefaultValue("This device", "CloudKeychain", 0, "This device", "This device")
+
+__END_DECLS
 
 #endif /* !_SECURITY_SECFRAMEWORKSTRINGS_H_ */
 
 #endif /* !_SECURITY_SECFRAMEWORKSTRINGS_H_ */
index 5c9e833e1abad0e065fc2dab224c879e2f12f1da..7efb22dd1be777568da22dafdd32be5418d3bd10 100644 (file)
@@ -50,11 +50,11 @@ static pthread_once_t kSecIdentityRegisterClass = PTHREAD_ONCE_INIT;
 static CFTypeID kSecIdentityTypeID = _kCFRuntimeNotATypeID;
 
 /* Forward declartions of static functions. */
 static CFTypeID kSecIdentityTypeID = _kCFRuntimeNotATypeID;
 
 /* Forward declartions of static functions. */
-static CFStringRef SecIdentityDescribe(CFTypeRef cf);
+static CFStringRef SecIdentityCopyDescription(CFTypeRef cf);
 static void SecIdentityDestroy(CFTypeRef cf);
 
 /* Static functions. */
 static void SecIdentityDestroy(CFTypeRef cf);
 
 /* Static functions. */
-static CFStringRef SecIdentityDescribe(CFTypeRef cf) {
+static CFStringRef SecIdentityCopyDescription(CFTypeRef cf) {
     SecIdentityRef identity = (SecIdentityRef)cf;
     return CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
         CFSTR("<SecIdentityRef: %p>"), identity);
     SecIdentityRef identity = (SecIdentityRef)cf;
     return CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
         CFSTR("<SecIdentityRef: %p>"), identity);
@@ -93,7 +93,7 @@ static void SecIdentityRegisterClass(void) {
                SecIdentityEqual,                                                               /* equal */
                SecIdentityHash,                                                                /* hash */
                NULL,                                                                                   /* copyFormattingDesc */
                SecIdentityEqual,                                                               /* equal */
                SecIdentityHash,                                                                /* hash */
                NULL,                                                                                   /* copyFormattingDesc */
-               SecIdentityDescribe                                                             /* copyDebugDesc */
+               SecIdentityCopyDescription                                              /* copyDebugDesc */
        };
 
     kSecIdentityTypeID = _CFRuntimeRegisterClass(&kSecIdentityClass);
        };
 
     kSecIdentityTypeID = _CFRuntimeRegisterClass(&kSecIdentityClass);
index b1587cbd8303e71c81d008b348f8450ff077e0e5..e999401f443be9c79f4d27653ab475719750733a 100644 (file)
@@ -33,9 +33,7 @@
 #include <Security/SecBase.h>
 #include <CoreFoundation/CFBase.h>
 
 #include <Security/SecBase.h>
 #include <CoreFoundation/CFBase.h>
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 /*!
        @function SecIdentityGetTypeID
 
 /*!
        @function SecIdentityGetTypeID
@@ -72,8 +70,6 @@ OSStatus SecIdentityCopyPrivateKey(
             SecKeyRef *privateKeyRef)
     __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_2_0);
 
             SecKeyRef *privateKeyRef)
     __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_2_0);
 
-#if defined(__cplusplus)
-}
-#endif
+__END_DECLS
 
 #endif /* !_SECURITY_SECIDENTITY_H_ */
 
 #endif /* !_SECURITY_SECIDENTITY_H_ */
index 5bd15e952acce4ba5e11f3afb79639b2c9d19f72..57dfd1b6ada5befa7f17ac78ba415403f7412395 100644 (file)
@@ -33,9 +33,7 @@
 #include <Security/SecBase.h>
 #include <CoreFoundation/CFBase.h>
 
 #include <Security/SecBase.h>
 #include <CoreFoundation/CFBase.h>
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 /*!    @function SecIdentityCreate.
        @abstract create a new identity object from the passed-in certificate
 
 /*!    @function SecIdentityCreate.
        @abstract create a new identity object from the passed-in certificate
@@ -45,8 +43,6 @@ extern "C" {
 SecIdentityRef SecIdentityCreate(CFAllocatorRef allocator,
        SecCertificateRef certificate, SecKeyRef privateKey);
 
 SecIdentityRef SecIdentityCreate(CFAllocatorRef allocator,
        SecCertificateRef certificate, SecKeyRef privateKey);
 
-#if defined(__cplusplus)
-}
-#endif
+__END_DECLS
 
 #endif /* !_SECURITY_SECIDENTITYPRIV_H_ */
 
 #endif /* !_SECURITY_SECIDENTITYPRIV_H_ */
index 0f7853d5d226857f72872fa09a364b999090bc29..aebc2e54ee2b37e911604304817147c1f5e17838 100644 (file)
 #include <Security/SecBasePriv.h>
 #include <Security/SecItem.h>
 #include <Security/SecRSAKey.h>
 #include <Security/SecBasePriv.h>
 #include <Security/SecItem.h>
 #include <Security/SecRSAKey.h>
+#include <Security/SecECKey.h>
 #include <Security/SecCertificate.h>
 #include <Security/SecIdentityPriv.h>
 #include <Security/SecPolicy.h>
 #include <Security/SecTrust.h>
 #include <Security/SecInternal.h>
 #include <Security/SecCertificate.h>
 #include <Security/SecIdentityPriv.h>
 #include <Security/SecPolicy.h>
 #include <Security/SecTrust.h>
 #include <Security/SecInternal.h>
+#include <libDER/oids.h>
 
 #include <AssertMacros.h>
 
 
 #include <AssertMacros.h>
 
@@ -82,11 +84,22 @@ static void build_trust_chains(const void *key, const void *value,
     require(key_bytes, out);
     CFDataRef cert_bytes = CFDictionaryGetValue(value, CFSTR("cert"));
     require(cert_bytes, out);
     require(key_bytes, out);
     CFDataRef cert_bytes = CFDictionaryGetValue(value, CFSTR("cert"));
     require(cert_bytes, out);
+    CFDataRef algoid_bytes = CFDictionaryGetValue(value, CFSTR("algid"));
+
+
+    DERItem algorithm = { (DERByte *)CFDataGetBytePtr(algoid_bytes), CFDataGetLength(algoid_bytes) };
+    if (DEROidCompare(&oidEcPubKey, &algorithm)) {
+        require (private_key = SecKeyCreateECPrivateKey(kCFAllocatorDefault,
+                                                         CFDataGetBytePtr(key_bytes), CFDataGetLength(key_bytes),
+                                                         kSecKeyEncodingPkcs1), out);
+    } else if (DEROidCompare(&oidRsa, &algorithm)) {
+        require (private_key = SecKeyCreateRSAPrivateKey(kCFAllocatorDefault,
+                                                         CFDataGetBytePtr(key_bytes), CFDataGetLength(key_bytes),
+                                                         kSecKeyEncodingPkcs1), out);
+    } else {
+        goto out;
+    }
 
 
-    /* p12import only passes up rsa keys */
-    require (private_key = SecKeyCreateRSAPrivateKey(kCFAllocatorDefault, 
-        CFDataGetBytePtr(key_bytes), CFDataGetLength(key_bytes),
-        kSecKeyEncodingPkcs1), out);
     require(cert = SecCertificateCreateWithData(kCFAllocatorDefault, cert_bytes), out);
     require(identity = SecIdentityCreate(kCFAllocatorDefault, cert, private_key), out);
     CFDictionarySetValue(identity_dict, kSecImportItemIdentity, identity);
     require(cert = SecCertificateCreateWithData(kCFAllocatorDefault, cert_bytes), out);
     require(identity = SecIdentityCreate(kCFAllocatorDefault, cert, private_key), out);
     CFDictionarySetValue(identity_dict, kSecImportItemIdentity, identity);
@@ -149,11 +162,11 @@ OSStatus SecPKCS12Import(CFDataRef pkcs12_data, CFDictionaryRef options, CFArray
     SecAsn1CoderRelease(context.coder);
     
     switch (status) {
     SecAsn1CoderRelease(context.coder);
     
     switch (status) {
-    case p12_noErr: return noErr;
+    case p12_noErr: return errSecSuccess;
     case p12_passwordErr: return errSecAuthFailed;
     case p12_decodeErr: return errSecDecode;
     default: return errSecInternal;
     };
     case p12_passwordErr: return errSecAuthFailed;
     case p12_decodeErr: return errSecDecode;
     default: return errSecInternal;
     };
-    return noErr;
+    return errSecSuccess;
 }
 
 }
 
index 85246c77c087fe6a6f87dc18cb28e58abbdf0dab..dc127a978033f005d4eda50b3ffcf244901c1a5d 100644 (file)
@@ -34,9 +34,7 @@
 #include <CoreFoundation/CFData.h>
 #include <CoreFoundation/CFDictionary.h>
 
 #include <CoreFoundation/CFData.h>
 #include <CoreFoundation/CFDictionary.h>
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 /*!
     @enum Import/Export options
 
 /*!
     @enum Import/Export options
@@ -91,8 +89,6 @@ extern CFStringRef kSecImportItemIdentity
 OSStatus SecPKCS12Import(CFDataRef pkcs12_data, CFDictionaryRef options,
     CFArrayRef *items) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
 
 OSStatus SecPKCS12Import(CFDataRef pkcs12_data, CFDictionaryRef options,
     CFArrayRef *items) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
 
-#if defined(__cplusplus)
-}
-#endif
+__END_DECLS
 
 #endif /* !_SECURITY_SECIMPORTEXPORT_H_ */
 
 #endif /* !_SECURITY_SECIMPORTEXPORT_H_ */
index f59f8758a0857904048d05e32bcd6e338cbd144f..2d89ba63684429752be7712f7c31480d3afaa09b 100644 (file)
 #include <CoreFoundation/CFNumber.h>
 #include <CoreFoundation/CFString.h>
 
 #include <CoreFoundation/CFNumber.h>
 #include <CoreFoundation/CFString.h>
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+#include "utilities/SecCFRelease.h"
 
 
-#define CFReleaseSafe(CF) { CFTypeRef _cf = (CF); if (_cf) CFRelease(_cf); }
-#define CFReleaseNull(CF) { CFTypeRef _cf = (CF); \
-       if (_cf) { (CF) = NULL; CFRelease(_cf); } }
-#define CFRetainSafe(CF) { CFTypeRef _cf = (CF); if (_cf) CFRetain(_cf); }
+__BEGIN_DECLS
 
 #define DICT_DECLARE(MAXVALUES) \
        CFIndex numValues = 0, maxValues = (MAXVALUES); \
 
 #define DICT_DECLARE(MAXVALUES) \
        CFIndex numValues = 0, maxValues = (MAXVALUES); \
@@ -76,9 +71,6 @@ static inline CFIndex getIntValue(CFTypeRef cf) {
     return -1;
 }
 
     return -1;
 }
 
-
-#if defined(__cplusplus)
-}
-#endif
+__END_DECLS
 
 #endif /* !_SECURITY_SECINTERNAL_H_ */
 
 #endif /* !_SECURITY_SECINTERNAL_H_ */
index 16cc3a5283fa0d399223a484ca486f7984b88415..63906855e59e26acc510a1fe68307fbd10780cbb 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2006-2010 Apple Inc. All Rights Reserved.
+ * Copyright (c) 2006-2013 Apple Inc. All Rights Reserved.
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -27,6 +27,7 @@
     passwords.)
  */
 
     passwords.)
  */
 
+#include <Security/SecBasePriv.h>
 #include <Security/SecItem.h>
 #include <Security/SecItemPriv.h>
 #include <Security/SecItemInternal.h>
 #include <Security/SecItem.h>
 #include <Security/SecItemPriv.h>
 #include <Security/SecItemInternal.h>
@@ -39,9 +40,9 @@
 #include <Security/SecRandom.h>
 #include <Security/SecBasePriv.h>
 #endif // *** END SECITEM_SHIM_OSX ***
 #include <Security/SecRandom.h>
 #include <Security/SecBasePriv.h>
 #endif // *** END SECITEM_SHIM_OSX ***
+#include <Security/SecTask.h>
 #include <errno.h>
 #include <limits.h>
 #include <errno.h>
 #include <limits.h>
-#include <pthread.h>
 #include <sqlite3.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <sqlite3.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <CoreFoundation/CFURL.h>
 #include <CommonCrypto/CommonDigest.h>
 #include <libkern/OSByteOrder.h>
 #include <CoreFoundation/CFURL.h>
 #include <CommonCrypto/CommonDigest.h>
 #include <libkern/OSByteOrder.h>
-#include <security_utilities/debugging.h>
+#include <utilities/array_size.h>
+#include <utilities/debugging.h>
+#include <utilities/SecCFError.h>
+#include <utilities/SecCFWrappers.h>
+#include <utilities/SecIOFormat.h>
+#include <utilities/SecXPCError.h>
+#include <utilities/der_plist.h>
 #include <assert.h>
 #include <assert.h>
+
 #include <Security/SecInternal.h>
 #include <TargetConditionals.h>
 #include "securityd_client.h"
 #include <Security/SecInternal.h>
 #include <TargetConditionals.h>
 #include "securityd_client.h"
-#include "securityd_server.h"
+#include "SecuritydXPC.h"
 #include <AssertMacros.h>
 #include <asl.h>
 #include <sys/types.h>
 #include <AssertMacros.h>
 #include <asl.h>
 #include <sys/types.h>
 /* label when certificate data is joined with key data */
 #define CERTIFICATE_DATA_COLUMN_LABEL "certdata" 
 
 /* label when certificate data is joined with key data */
 #define CERTIFICATE_DATA_COLUMN_LABEL "certdata" 
 
+#include <utilities/SecDb.h>
+#include <IOKit/IOReturn.h>
+
+/* Return an OSStatus for a sqlite3 error code. */
+static OSStatus osstatus_for_s3e(int s3e)
+{
+       if (s3e > 0 && s3e <= SQLITE_DONE) switch (s3e)
+       {
+        case SQLITE_OK:
+            return 0;
+        case SQLITE_ERROR:
+            return errSecNotAvailable; /* errSecDuplicateItem; */
+        case SQLITE_FULL: /* Happens if we run out of uniqueids */
+            return errSecNotAvailable; /* TODO: Replace with a better error code. */
+        case SQLITE_PERM:
+        case SQLITE_READONLY:
+            return errSecNotAvailable;
+        case SQLITE_CANTOPEN:
+            return errSecNotAvailable;
+        case SQLITE_EMPTY:
+            return errSecNotAvailable;
+        case SQLITE_CONSTRAINT:
+            return errSecDuplicateItem;
+        case SQLITE_ABORT:
+            return -1;
+        case SQLITE_MISMATCH:
+            return errSecNoSuchAttr;
+        case SQLITE_AUTH:
+            return errSecNotAvailable;
+        case SQLITE_NOMEM:
+            return -2; /* TODO: Replace with a real error code. */
+        case SQLITE_INTERNAL:
+        default:
+            return errSecNotAvailable; /* TODO: Replace with a real error code. */
+       }
+    return s3e;
+}
+
+static OSStatus osstatus_for_kern_return(CFIndex kernResult)
+{
+       switch (kernResult)
+       {
+        case KERN_SUCCESS:
+            return errSecSuccess;
+        case kIOReturnNotReadable:
+        case kIOReturnNotWritable:
+            return errSecAuthFailed;
+        case kIOReturnNotPermitted:
+        case kIOReturnNotPrivileged:
+        case kIOReturnLockedRead:
+        case kIOReturnLockedWrite:
+            return errSecInteractionNotAllowed;
+        case kIOReturnError:
+            return errSecDecode;
+        case kIOReturnBadArgument:
+            return errSecParam;
+        default:
+            return errSecNotAvailable; /* TODO: Replace with a real error code. */
+       }
+}
+
+static OSStatus osstatus_for_xpc_error(CFIndex xpcError) {
+    switch (xpcError)
+       {
+        case kSecXPCErrorSuccess:
+            return errSecSuccess;
+        case kSecXPCErrorUnexpectedType:
+        case kSecXPCErrorUnexpectedNull:
+            return errSecParam;
+        case kSecXPCErrorConnectionFailed:
+            return errSecNotAvailable;
+        case kSecXPCErrorUnknown:
+        default:
+            return errSecInternal;
+    }
+}
+
+static OSStatus osstatus_for_der_error(CFIndex derError) {
+    switch (derError)
+       {
+        case kSecDERErrorUnknownEncoding:
+        //case kSecDERErrorUnsupportedDERType:
+            return errSecDecode;
+        case kSecDERErrorUnsupportedCFObject:
+        case kSecDERErrorUnsupportedNumberType:
+            return errSecParam;
+        case kSecDERErrorAllocationFailure:
+        case kSecDERErrorUnderlyingError:
+            return errSecAllocate;
+        default:
+            return errSecInternal;
+    }
+}
+
+// Convert from securityd error codes to OSStatus for legacy API.
+OSStatus SecErrorGetOSStatus(CFErrorRef error) {
+    OSStatus status;
+    if (error == NULL) {
+        status = errSecSuccess;
+    } else {
+        CFStringRef domain = CFErrorGetDomain(error);
+        if (domain == NULL) {
+            secerror("No error domain for error: %@", error);
+            status = errSecInternal;
+        } else if (CFEqual(kSecErrorDomain, domain)) {
+            status = (OSStatus)CFErrorGetCode(error);
+        } else if (CFEqual(kSecDbErrorDomain, domain)) {
+            status = osstatus_for_s3e((int)CFErrorGetCode(error));
+        } else if (CFEqual(kSecErrnoDomain, domain)) {
+            status = (OSStatus)CFErrorGetCode(error);
+        } else if (CFEqual(kSecKernDomain, domain)) {
+            status = osstatus_for_kern_return(CFErrorGetCode(error));
+        } else if (CFEqual(sSecXPCErrorDomain, domain)) {
+            status = osstatus_for_xpc_error(CFErrorGetCode(error));
+        } else if (CFEqual(sSecDERErrorDomain, domain)) {
+            status = osstatus_for_der_error(CFErrorGetCode(error));
+        } else {
+            secerror("unknown error domain: %@ for error: %@", domain, error);
+            status = errSecInternal;
+        }
+    }
+    return status;
+}
+
+// Wrapper to provide a CFErrorRef for legacy API.
+OSStatus SecOSStatusWith(bool (^perform)(CFErrorRef *error)) {
+    CFErrorRef error = NULL;
+    OSStatus status;
+    if (perform(&error)) {
+        assert(error == NULL);
+        status = errSecSuccess;
+    } else {
+        assert(error);
+        status = SecErrorGetOSStatus(error);
+        if (status != errSecItemNotFound)           // Occurs in normal operation, so exclude
+            secerror("error:[%" PRIdOSStatus "] %@", status, error);
+        CFReleaseNull(error);
+    }
+    return status;
+}
+
+
 /* IPC uses CFPropertyList to un/marshall input/output data and can handle:
    CFData, CFString, CFArray, CFDictionary, CFDate, CFBoolean, and CFNumber
 
 /* IPC uses CFPropertyList to un/marshall input/output data and can handle:
    CFData, CFString, CFArray, CFDictionary, CFDate, CFBoolean, and CFNumber
 
@@ -152,6 +302,11 @@ SecItemCreateFromAttributeDictionary(CFDictionaryRef refAttributes) {
        }
        return ref;
 }
        }
        return ref;
 }
+#else
+
+extern CFTypeRef SecItemCreateFromAttributeDictionary(CFDictionaryRef refAttributes);
+
+#endif
 
 /* Turn the returned dictionary that contains all the attributes to create a
    ref into the exact result the client asked for */
 
 /* Turn the returned dictionary that contains all the attributes to create a
    ref into the exact result the client asked for */
@@ -186,10 +341,10 @@ OSStatus
 SecItemCopyDisplayNames(CFArrayRef items, CFArrayRef *displayNames)
 {
     // @@@ TBI
 SecItemCopyDisplayNames(CFArrayRef items, CFArrayRef *displayNames)
 {
     // @@@ TBI
-    return -1 /* unimpErr */;
+    return -1 /* errSecUnimplemented */;
 }
 
 }
 
-
+#ifndef SECITEM_SHIM_OSX
 static void merge_dictionary_by_overwrite(const void *key, const void *value, void *context)
 {
        if (!CFEqual(key, kSecValueRef))
 static void merge_dictionary_by_overwrite(const void *key, const void *value, void *context)
 {
        if (!CFEqual(key, kSecValueRef))
@@ -241,10 +396,10 @@ static OSStatus cook_query(CFDictionaryRef query, CFMutableDictionaryRef *explod
         }
     }
        *explode = args;
         }
     }
        *explode = args;
-       return noErr;
+       return errSecSuccess;
 }
 
 }
 
-typedef OSStatus (*secitem_operation)(CFDictionaryRef attributes, ...);
+typedef OSStatus (*secitem_operation)(CFDictionaryRef attributes, CFTypeRef *result);
 
 static bool explode_identity(CFDictionaryRef attributes, secitem_operation operation, 
     OSStatus *return_status, CFTypeRef *return_result)
 
 static bool explode_identity(CFDictionaryRef attributes, secitem_operation operation, 
     OSStatus *return_status, CFTypeRef *return_result)
@@ -292,10 +447,10 @@ static bool explode_identity(CFDictionaryRef attributes, secitem_operation opera
                                                const void *vals[] = { kSecClassCertificate, pkhh };
                                                if (pkhh)
                                                        query_dict = CFDictionaryCreate(NULL, keys, 
                                                const void *vals[] = { kSecClassCertificate, pkhh };
                                                if (pkhh)
                                                        query_dict = CFDictionaryCreate(NULL, keys, 
-                                                   vals, (sizeof(keys) / sizeof(*keys)), 
+                                                   vals, (array_size(keys)),
                                                                NULL, NULL);
                                                if (query_dict)
                                                                NULL, NULL);
                                                if (query_dict)
-                                                       if (noErr == SecItemCopyMatching(query_dict, NULL))
+                                                       if (errSecSuccess == SecItemCopyMatching(query_dict, NULL))
                                                                skip_key_operation = true;
                                                CFReleaseSafe(query_dict);
                                                CFReleaseSafe(key_dict);
                                                                skip_key_operation = true;
                                                CFReleaseSafe(query_dict);
                                                CFReleaseSafe(key_dict);
@@ -374,7 +529,7 @@ static void infer_cert_label(CFDictionaryRef attributes, CFMutableDictionaryRef
 }
 
 /* A persistent ref is just the class and the rowid of the record. */
 }
 
 /* A persistent ref is just the class and the rowid of the record. */
-CFDataRef _SecItemMakePersistentRef(CFTypeRef class, sqlite_int64 rowid)
+CF_RETURNS_RETAINED CFDataRef _SecItemMakePersistentRef(CFTypeRef class, sqlite_int64 rowid)
 {
     uint8_t bytes[sizeof(sqlite_int64) + 4];
     if (rowid < 0)
 {
     uint8_t bytes[sizeof(sqlite_int64) + 4];
     if (rowid < 0)
@@ -393,12 +548,12 @@ CFDataRef _SecItemMakePersistentRef(CFTypeRef class, sqlite_int64 rowid)
  */
 bool _SecItemParsePersistentRef(CFDataRef persistent_ref, CFStringRef *return_class, sqlite_int64 *return_rowid)
 {
  */
 bool _SecItemParsePersistentRef(CFDataRef persistent_ref, CFStringRef *return_class, sqlite_int64 *return_rowid)
 {
-    bool valid_ref = false;
+       bool valid_ref = false;
     if (CFGetTypeID(persistent_ref) == CFDataGetTypeID() &&
         CFDataGetLength(persistent_ref) == (CFIndex)(sizeof(sqlite_int64) + 4)) {
         const uint8_t *bytes = CFDataGetBytePtr(persistent_ref);
         sqlite_int64 rowid = OSReadBigInt64(bytes + 4, 0);
     if (CFGetTypeID(persistent_ref) == CFDataGetTypeID() &&
         CFDataGetLength(persistent_ref) == (CFIndex)(sizeof(sqlite_int64) + 4)) {
         const uint8_t *bytes = CFDataGetBytePtr(persistent_ref);
         sqlite_int64 rowid = OSReadBigInt64(bytes + 4, 0);
-        
+               
         CFStringRef class = CFStringCreateWithBytes(kCFAllocatorDefault, 
             bytes, CFStringGetLength(kSecClassGenericPassword), 
             kCFStringEncodingUTF8, true);
         CFStringRef class = CFStringCreateWithBytes(kCFAllocatorDefault, 
             bytes, CFStringGetLength(kSecClassGenericPassword), 
             kCFStringEncodingUTF8, true);
@@ -408,8 +563,9 @@ bool _SecItemParsePersistentRef(CFDataRef persistent_ref, CFStringRef *return_cl
             kSecClassCertificate,
             kSecClassKey,
             kSecClassIdentity };
             kSecClassCertificate,
             kSecClassKey,
             kSecClassIdentity };
+        
         unsigned i;
         unsigned i;
-        for (i=0; i< sizeof(valid_classes)/sizeof(*valid_classes); i++) {
+        for (i=0; i< array_size(valid_classes); i++) {
             if (CFEqual(valid_classes[i], class)) {
                 if (return_class)
                     *return_class = valid_classes[i];
             if (CFEqual(valid_classes[i], class)) {
                 if (return_class)
                     *return_class = valid_classes[i];
@@ -424,16 +580,24 @@ bool _SecItemParsePersistentRef(CFDataRef persistent_ref, CFStringRef *return_cl
     return valid_ref;
 }
 
     return valid_ref;
 }
 
+#endif // *** END SECITEM_SHIM_OSX ***
+
 static bool cf_bool_value(CFTypeRef cf_bool)
 {
        return (cf_bool && CFEqual(kCFBooleanTrue, cf_bool));
 }
 
 static bool cf_bool_value(CFTypeRef cf_bool)
 {
        return (cf_bool && CFEqual(kCFBooleanTrue, cf_bool));
 }
 
+
 static void
 result_post(CFDictionaryRef query, CFTypeRef raw_result, CFTypeRef *result) {
     if (!raw_result)
         return;
 
 static void
 result_post(CFDictionaryRef query, CFTypeRef raw_result, CFTypeRef *result) {
     if (!raw_result)
         return;
 
+    if (!result) {
+        CFRelease(raw_result);
+        return;
+    }
+
        bool return_ref = cf_bool_value(CFDictionaryGetValue(query, kSecReturnRef));
        bool return_data = cf_bool_value(CFDictionaryGetValue(query, kSecReturnData));
        bool return_attributes = cf_bool_value(CFDictionaryGetValue(query, kSecReturnAttributes));
        bool return_ref = cf_bool_value(CFDictionaryGetValue(query, kSecReturnRef));
        bool return_data = cf_bool_value(CFDictionaryGetValue(query, kSecReturnData));
        bool return_attributes = cf_bool_value(CFDictionaryGetValue(query, kSecReturnAttributes));
@@ -457,7 +621,81 @@ result_post(CFDictionaryRef query, CFTypeRef raw_result, CFTypeRef *result) {
        } else
                *result = raw_result;
 }
        } else
                *result = raw_result;
 }
-#endif // *** END SECITEM_SHIM_OSX ***
+
+#if SECITEM_SHIM_OSX
+/* TODO: Should be in some header */
+OSStatus SecItemAdd_ios(CFDictionaryRef attributes, CFTypeRef *result);
+OSStatus SecItemCopyMatching_ios(CFDictionaryRef query, CFTypeRef *result);
+OSStatus SecItemUpdate_ios(CFDictionaryRef query, CFDictionaryRef attributesToUpdate);
+OSStatus SecItemDelete_ios(CFDictionaryRef query);
+#endif
+
+static bool cftype_to_bool_cftype_error_request(enum SecXPCOperation op, CFTypeRef attributes, CFTypeRef *result, CFErrorRef *error)
+{
+    return securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
+        return SecXPCDictionarySetPList(message, kSecXPCKeyQuery, attributes, error);
+    }, ^bool(xpc_object_t response, CFErrorRef *error) {
+        if (result) {
+            return SecXPCDictionaryCopyPListOptional(response, kSecXPCKeyResult, result, error);
+        }
+        return true;
+    });
+}
+
+static bool cftype_ag_to_bool_cftype_error_request(enum SecXPCOperation op, CFTypeRef attributes, __unused CFArrayRef accessGroups, CFTypeRef *result, CFErrorRef *error) {
+    return cftype_to_bool_cftype_error_request(op, attributes, result, error);
+}
+
+static bool dict_to_error_request(enum SecXPCOperation op, CFDictionaryRef query, CFErrorRef *error)
+{
+    return securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
+        return SecXPCDictionarySetPList(message, kSecXPCKeyQuery, query, error);
+    }, NULL);
+}
+
+static bool dict_ag_to_error_request(enum SecXPCOperation op, CFDictionaryRef query, __unused CFArrayRef accessGroups, CFErrorRef *error)
+{
+    return dict_to_error_request(op, query, error);
+}
+
+static CFDataRef data_data_to_data_error_request(enum SecXPCOperation op, CFDataRef keybag, CFDataRef passcode, CFErrorRef *error) {
+    __block CFDataRef result = NULL;
+    securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
+        return SecXPCDictionarySetDataOptional(message, kSecXPCKeyKeybag, keybag, error)
+        && SecXPCDictionarySetDataOptional(message, kSecXPCKeyUserPassword, passcode, error);
+    }, ^bool(xpc_object_t response, CFErrorRef *error) {
+        return (result = SecXPCDictionaryCopyData(response, kSecXPCKeyResult, error));
+    });
+    return result;
+}
+
+static bool data_data_data_to_error_request(enum SecXPCOperation op, CFDataRef backup, CFDataRef keybag, CFDataRef passcode, CFErrorRef *error) {
+    return securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
+        return SecXPCDictionarySetData(message, kSecXPCKeyBackup, backup, error)
+        && SecXPCDictionarySetData(message, kSecXPCKeyKeybag, keybag, error)
+        && SecXPCDictionarySetDataOptional(message, kSecXPCKeyUserPassword, passcode, error);
+    } , NULL);
+}
+
+static bool dict_data_data_to_error_request(enum SecXPCOperation op, CFDictionaryRef backup, CFDataRef keybag, CFDataRef passcode, CFErrorRef *error) {
+    return securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
+        return SecXPCDictionarySetPList(message, kSecXPCKeyBackup, backup, error)
+        && SecXPCDictionarySetData(message, kSecXPCKeyKeybag, keybag, error)
+        && SecXPCDictionarySetDataOptional(message, kSecXPCKeyUserPassword, passcode, error);
+    } , NULL);
+}
+
+static CFDictionaryRef data_data_dict_to_dict_error_request(enum SecXPCOperation op, CFDictionaryRef backup, CFDataRef keybag, CFDataRef passcode, CFErrorRef *error) {
+    __block CFDictionaryRef dict = NULL;
+    securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
+        return SecXPCDictionarySetPListOptional(message, kSecXPCKeyBackup, backup, error)
+        && SecXPCDictionarySetData(message, kSecXPCKeyKeybag, keybag, error)
+        && SecXPCDictionarySetDataOptional(message, kSecXPCKeyUserPassword, passcode, error);
+    }, ^bool(xpc_object_t response, CFErrorRef *error) {
+        return (dict = SecXPCDictionaryCopyDictionary(response, kSecXPCKeyResult, error));
+    });
+    return dict;
+}
 
 OSStatus
 #if SECITEM_SHIM_OSX
 
 OSStatus
 #if SECITEM_SHIM_OSX
@@ -467,7 +705,6 @@ SecItemAdd(CFDictionaryRef attributes, CFTypeRef *result)
 #endif // *** END SECITEM_SHIM_OSX ***
 {
     CFMutableDictionaryRef args = NULL;
 #endif // *** END SECITEM_SHIM_OSX ***
 {
     CFMutableDictionaryRef args = NULL;
-    CFTypeRef raw_result = NULL;
     OSStatus status;
 
 #ifndef SECITEM_SHIM_OSX
     OSStatus status;
 
 #ifndef SECITEM_SHIM_OSX
@@ -477,40 +714,62 @@ SecItemAdd(CFDictionaryRef attributes, CFTypeRef *result)
 #endif // *** END SECITEM_SHIM_OSX ***
        if (args)
                attributes = args;
 #endif // *** END SECITEM_SHIM_OSX ***
        if (args)
                attributes = args;
-    status = SECURITYD_AG(sec_item_add, attributes, &raw_result);
-#ifndef SECITEM_SHIM_OSX
-    result_post(attributes, raw_result, result);
-#endif // *** END SECITEM_SHIM_OSX ***
 
 
+    status = SecOSStatusWith(^bool (CFErrorRef *error) {
+        CFTypeRef raw_result = NULL;
+        if (!SECURITYD_XPC(sec_item_add, cftype_ag_to_bool_cftype_error_request, attributes, SecAccessGroupsGetCurrent(), &raw_result, error))
+            return false;
+
+        result_post(attributes, raw_result, result);
+        return true;
+    });
+
+#ifndef SECITEM_SHIM_OSX
 errOut:
 errOut:
+#endif // *** END SECITEM_SHIM_OSX ***
     CFReleaseSafe(args);
        return status;
 }
 
     CFReleaseSafe(args);
        return status;
 }
 
+
 OSStatus
 #if SECITEM_SHIM_OSX
 OSStatus
 #if SECITEM_SHIM_OSX
-SecItemCopyMatching_ios(CFDictionaryRef query, CFTypeRef *result)
+SecItemCopyMatching_ios(CFDictionaryRef inQuery, CFTypeRef *result)
 #else
 #else
-SecItemCopyMatching(CFDictionaryRef query, CFTypeRef *result)
+SecItemCopyMatching(CFDictionaryRef inQuery, CFTypeRef *result)
 #endif // *** END SECITEM_SHIM_OSX ***
 {
 #endif // *** END SECITEM_SHIM_OSX ***
 {
-    CFMutableDictionaryRef args = NULL;
-    CFTypeRef raw_result = NULL;
+    __block CFDictionaryRef query = inQuery;
+    __block CFMutableDictionaryRef args = NULL;
     OSStatus status;
 
 #ifndef SECITEM_SHIM_OSX
     require_quiet(!explode_identity(query, (secitem_operation)SecItemCopyMatching, &status, result), errOut);
     require_noerr_quiet(status = cook_query(query, &args), errOut);
     OSStatus status;
 
 #ifndef SECITEM_SHIM_OSX
     require_quiet(!explode_identity(query, (secitem_operation)SecItemCopyMatching, &status, result), errOut);
     require_noerr_quiet(status = cook_query(query, &args), errOut);
-#endif // *** END SECITEM_SHIM_OSX ***    
+#endif // *** END SECITEM_SHIM_OSX ***
        if (args)
                query = args;
 
        if (args)
                query = args;
 
-    status = SECURITYD_AG(sec_item_copy_matching, query, &raw_result);
-#ifndef SECITEM_SHIM_OSX
-    result_post(query, raw_result, result);
-#endif // *** END SECITEM_SHIM_OSX ***    
+    status = SecOSStatusWith(^bool (CFErrorRef *error) {
+        CFTypeRef raw_result = NULL;
+        if (!SECURITYD_XPC(sec_item_copy_matching, cftype_ag_to_bool_cftype_error_request, query, SecAccessGroupsGetCurrent(), &raw_result, error))
+            return false;
+
+#ifdef SECITEM_SHIM_OSX
+        if ((!cf_bool_value(CFDictionaryGetValue(query, kSecReturnPersistentRef)))  && cf_bool_value(CFDictionaryGetValue(query, kSecReturnRef))) {
+            CFReleaseSafe(args);
+            args = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, query);
+            CFDictionaryAddValue(args, kSecReturnPersistentRef, kCFBooleanTrue);
+            query = args;
+        }
+#endif
+        result_post(query, raw_result, result);
+        return true;
+    });
 
 
+#ifndef SECITEM_SHIM_OSX
 errOut:
 errOut:
+#endif // *** END SECITEM_SHIM_OSX ***
     CFReleaseSafe(args);
        return status;
 }
     CFReleaseSafe(args);
        return status;
 }
@@ -523,37 +782,53 @@ SecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate)
 #endif // *** END SECITEM_SHIM_OSX ***
 {
     CFMutableDictionaryRef args = NULL;
 #endif // *** END SECITEM_SHIM_OSX ***
 {
     CFMutableDictionaryRef args = NULL;
-    OSStatus status;
-
+    __block OSStatus status; // TODO loose block once gSecurityd functions return CFErrorRefs
 #ifndef SECITEM_SHIM_OSX
 #ifndef SECITEM_SHIM_OSX
-       require_noerr_quiet(status = cook_query(query, &args), errOut);
-#endif // *** END SECITEM_SHIM_OSX ***     
+    require_noerr_quiet(status = cook_query(query, &args), errOut);
+#endif
     if (args)
         query = args;
 
     if (args)
         query = args;
 
-    if (gSecurityd) {
-        status = gSecurityd->sec_item_update(query, attributesToUpdate, SecAccessGroupsGetCurrent());
-    } else {
-        const void *values[] = { (const void *)query, (const void *)attributesToUpdate };
-        CFArrayRef pair = CFArrayCreate(kCFAllocatorDefault, values, 2, NULL/*&kCFTypeArrayCallBacks*/);
-        if (pair) {
-            status = ServerCommandSendReceive(sec_item_update_id, pair, NULL);
-            CFRelease(pair);
+    status = SecOSStatusWith(^bool (CFErrorRef *error) {
+        bool ok = false;
+        if (gSecurityd) {
+            // Ensure the dictionary passed to securityd has proper kCFTypeDictionaryKeyCallBacks.
+            CFMutableDictionaryRef tmp = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, NULL);
+            CFDictionaryForEach(attributesToUpdate, ^(const void *key, const void *value) { CFDictionaryAddValue(tmp, key, value); });
+            ok = gSecurityd->sec_item_update(query, tmp, SecAccessGroupsGetCurrent(), error);
+            CFRelease(tmp);
         } else {
         } else {
-            status = errSecAllocate;
+            xpc_object_t message = securityd_create_message(sec_item_update_id, error);
+            if (message) {
+                if (SecXPCDictionarySetPList(message, kSecXPCKeyQuery, query, error) &&
+                    SecXPCDictionarySetPList(message, kSecXPCKeyAttributesToUpdate, attributesToUpdate, error)) {
+                    xpc_object_t reply = securityd_message_with_reply_sync(message, error);
+                    if (reply) {
+                        ok = securityd_message_no_error(reply, error);
+                        xpc_release(reply);
+                    }
+                }
+                xpc_release(message);
+            }
         }
         }
-    }
+        return ok;
+    });
 
 
+#ifndef SECITEM_SHIM_OSX
 errOut:
 errOut:
+#endif
     CFReleaseSafe(args);
     CFReleaseSafe(args);
-       return status;
+    return status;
 }
 
 }
 
+#ifndef SECITEM_SHIM_OSX
 static void copy_all_keys_and_values(const void *key, const void *value, void *context)
 {
     CFDictionaryAddValue((CFMutableDictionaryRef)context, key, value);
 }
 static void copy_all_keys_and_values(const void *key, const void *value, void *context)
 {
     CFDictionaryAddValue((CFMutableDictionaryRef)context, key, value);
 }
+#endif 
 
 
+#ifndef SECITEM_SHIM_OSX
 static OSStatus explode_persistent_identity_ref(CFDictionaryRef query, CFMutableDictionaryRef *delete_query)
 {
     OSStatus status = errSecSuccess;
 static OSStatus explode_persistent_identity_ref(CFDictionaryRef query, CFMutableDictionaryRef *delete_query)
 {
     OSStatus status = errSecSuccess;
@@ -564,7 +839,7 @@ static OSStatus explode_persistent_identity_ref(CFDictionaryRef query, CFMutable
         const void *keys[] = { kSecReturnRef, kSecValuePersistentRef };
         const void *vals[] = { kCFBooleanTrue, persist };
         CFDictionaryRef persistent_query = CFDictionaryCreate(NULL, keys, 
         const void *keys[] = { kSecReturnRef, kSecValuePersistentRef };
         const void *vals[] = { kCFBooleanTrue, persist };
         CFDictionaryRef persistent_query = CFDictionaryCreate(NULL, keys, 
-            vals, (sizeof(keys) / sizeof(*keys)), NULL, NULL);
+            vals, (array_size(keys)), NULL, NULL);
         CFTypeRef item_query = NULL;
         status = SecItemCopyMatching(persistent_query, &item_query);
         CFReleaseNull(persistent_query);
         CFTypeRef item_query = NULL;
         status = SecItemCopyMatching(persistent_query, &item_query);
         CFReleaseNull(persistent_query);
@@ -584,6 +859,7 @@ static OSStatus explode_persistent_identity_ref(CFDictionaryRef query, CFMutable
 
     return status;
 }
 
     return status;
 }
+#endif
 
 OSStatus
 #if SECITEM_SHIM_OSX
 
 OSStatus
 #if SECITEM_SHIM_OSX
@@ -605,14 +881,13 @@ SecItemDelete(CFDictionaryRef query)
     if (args2)
         query = args2;
 
     if (args2)
         query = args2;
 
-    if (gSecurityd) {
-        status = gSecurityd->sec_item_delete(query,
-            SecAccessGroupsGetCurrent());
-    } else {
-        status = ServerCommandSendReceive(sec_item_delete_id, query, NULL);
-    }
-
+    status = SecOSStatusWith(^bool (CFErrorRef *error) {
+        return SECURITYD_XPC(sec_item_delete, dict_ag_to_error_request, query, SecAccessGroupsGetCurrent(), error);
+    });
+    
+#ifndef SECITEM_SHIM_OSX
 errOut:
 errOut:
+#endif // *** END SECITEM_SHIM_OSX ***
     CFReleaseSafe(args1);
     CFReleaseSafe(args2);
        return status;
     CFReleaseSafe(args1);
     CFReleaseSafe(args2);
        return status;
@@ -621,143 +896,69 @@ errOut:
 OSStatus
 SecItemDeleteAll(void)
 {
 OSStatus
 SecItemDeleteAll(void)
 {
-    OSStatus status = noErr;
-    if (gSecurityd) {
+    return SecOSStatusWith(^bool (CFErrorRef *error) {
+        bool ok;
+        if (gSecurityd) {
 #ifndef SECITEM_SHIM_OSX
 #ifndef SECITEM_SHIM_OSX
-        SecTrustStoreRef ts = SecTrustStoreForDomain(kSecTrustStoreDomainUser);
-        if (!gSecurityd->sec_truststore_remove_all(ts))
-            status = errSecInternal;
-#endif // *** END SECITEM_SHIM_OSX ***    
-        if (!gSecurityd->sec_item_delete_all())
-            status = errSecInternal;
-    } else {
-        status = ServerCommandSendReceive(sec_delete_all_id, NULL, NULL);
-    }
-    return status;
-}
-
-OSStatus _SecMigrateKeychain(int32_t handle_in, CFDataRef data_in,
-    int32_t *handle_out, CFDataRef *data_out)
-{
-    CFMutableArrayRef args = NULL;
-    CFTypeRef raw_result = NULL;
-    CFNumberRef hin = NULL, hout = NULL;
-    OSStatus status = errSecAllocate;
-
-    require_quiet(args = CFArrayCreateMutable(kCFAllocatorDefault, 2, NULL), errOut);
-    require_quiet(hin = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &handle_in), errOut);
-    CFArrayAppendValue(args, hin);
-    if (data_in)
-        CFArrayAppendValue(args, data_in);
-
-    require_noerr_quiet(status = SECURITYD(sec_migrate_keychain, args, &raw_result), errOut);
-    hout = CFArrayGetValueAtIndex(raw_result, 0);
-    if (data_out) {
-        CFDataRef data;
-        if (CFArrayGetCount(raw_result) > 1) {
-            data = CFArrayGetValueAtIndex(raw_result, 1);
-            require_quiet(CFGetTypeID(data) == CFDataGetTypeID(), errOut);
-            CFRetain(data);
+            SecTrustStoreRef ts = SecTrustStoreForDomain(kSecTrustStoreDomainUser);
+            if (!gSecurityd->sec_truststore_remove_all(ts, error))
+                ok = SecError(errSecInternal, error, CFSTR("sec_truststore_remove_all is NULL"));
+#endif // *** END SECITEM_SHIM_OSX ***
+            if (!gSecurityd->sec_item_delete_all(error))
+                ok = SecError(errSecInternal, error, CFSTR("sec_item_delete_all is NULL"));
+            ok = true;
         } else {
         } else {
-            data = NULL;
+            ok = securityd_send_sync_and_do(sec_delete_all_id, error, NULL, NULL);
         }
         }
-        *data_out = data;
-    }
-
-errOut:
-    CFReleaseSafe(hin);
-    CFReleaseSafe(args);
-    CFReleaseSafe(raw_result);
-       return status;
+        return ok;
+    });
 }
 
 }
 
-/* TODO: Move to a location shared between securityd and Security framework. */
-const char *restore_keychain_location = "/Library/Keychains/keychain.restoring";
-
-OSStatus _SecRestoreKeychain(const char *path)
-{
-    OSStatus status = errSecInternal;
-
-    require_quiet(!geteuid(), out);
-    struct passwd *pass = NULL;
-    require_quiet(pass = getpwnam("_securityd"), out);
-    uid_t securityUID = pass->pw_uid;
-    struct group *grp = NULL;
-    require_quiet(grp = getgrnam("wheel"), out);
-    gid_t wheelGID = grp->gr_gid;
-
-    require_noerr_quiet(rename(path , restore_keychain_location), out);
-    require_noerr_quiet(chmod(restore_keychain_location, 0600), out);
-    require_noerr_quiet(chown(restore_keychain_location, securityUID, wheelGID),
-        out);
+CFDataRef _SecKeychainCopyOTABackup(void) {
+    return SECURITYD_XPC(sec_keychain_backup, data_data_to_data_error_request, NULL, NULL, NULL);
+}
 
 
-    status = ServerCommandSendReceive(sec_restore_keychain_id, NULL, NULL);
-    require_noerr_quiet(unlink(restore_keychain_location), out);
+CFDataRef _SecKeychainCopyBackup(CFDataRef backupKeybag, CFDataRef password) {
+    return SECURITYD_XPC(sec_keychain_backup, data_data_to_data_error_request, backupKeybag, password, NULL);
+}
 
 
-out:    
-    return status;
+OSStatus _SecKeychainRestoreBackup(CFDataRef backup, CFDataRef backupKeybag,
+    CFDataRef password) {
+    return SecOSStatusWith(^bool (CFErrorRef *error) {
+        return SECURITYD_XPC(sec_keychain_restore, data_data_data_to_error_request, backup, backupKeybag, password, error);
+    });
 }
 
 }
 
-CFDataRef _SecKeychainCopyOTABackup(void) {
-    CFTypeRef raw_result = NULL;
-    CFDataRef backup = NULL;
-    OSStatus status;
+bool _SecKeychainSyncUpdate(CFDictionaryRef updates, CFErrorRef *error) {
+    return SECURITYD_XPC(sec_keychain_sync_update, dict_to_error_request, updates, error);
+}
 
 
-    require_noerr_quiet(status = SECURITYD(sec_keychain_backup, NULL,
-                                           &raw_result), errOut);
-    if (raw_result && CFGetTypeID(raw_result) == CFDataGetTypeID()) {
-        backup = raw_result;
-        raw_result = NULL; /* So it doesn't get released below. */
-    }
+OSStatus _SecKeychainBackupSyncable(CFDataRef keybag, CFDataRef password, CFDictionaryRef backup_in, CFDictionaryRef *backup_out)
+{
+    return SecOSStatusWith(^bool (CFErrorRef *error) {
+        *backup_out = SECURITYD_XPC(sec_keychain_backup_syncable, data_data_dict_to_dict_error_request, backup_in, keybag, password, error);
+        return *backup_out != NULL;
+    });
+}
 
 
-errOut:
-    CFReleaseSafe(raw_result);
-       return backup;
+OSStatus _SecKeychainRestoreSyncable(CFDataRef keybag, CFDataRef password, CFDictionaryRef backup_in)
+{
+    return SecOSStatusWith(^bool (CFErrorRef *error) {
+        return SECURITYD_XPC(sec_keychain_restore_syncable, dict_data_data_to_error_request, backup_in, keybag, password, error);
+    });
 }
 
 }
 
-CFDataRef _SecKeychainCopyBackup(CFDataRef backupKeybag, CFDataRef password) {
-    CFMutableArrayRef args;
-    CFTypeRef raw_result = NULL;
-    CFDataRef backup = NULL;
-    OSStatus status;
 
 
-    require_quiet(args = CFArrayCreateMutable(kCFAllocatorDefault, 2, NULL),
-        errOut);
-    CFArrayAppendValue(args, backupKeybag);
-    if (password)
-        CFArrayAppendValue(args, password);
-
-    require_noerr_quiet(status = SECURITYD(sec_keychain_backup, args,
-        &raw_result), errOut);
-    if (raw_result && CFGetTypeID(raw_result) == CFDataGetTypeID()) {
-        backup = raw_result;
-        raw_result = NULL; /* So it doesn't get released below. */
-    }
+#ifndef SECITEM_SHIM_OSX
+OSStatus SecTaskValidateForRequirement(SecTaskRef task, CFStringRef requirement);
 
 
-errOut:
-    CFReleaseSafe(args);
-    CFReleaseSafe(raw_result);
-       return backup;
+OSStatus SecTaskValidateForRequirement(SecTaskRef task, CFStringRef requirement)
+{
+    return -1; /* this is only on OS X currently */
 }
 
 }
 
-bool _SecKeychainRestoreBackup(CFDataRef backup, CFDataRef backupKeybag,
-    CFDataRef password) {
-    CFMutableArrayRef args = NULL;
-    CFTypeRef raw_result = NULL;
-    OSStatus status = errSecAllocate;
-
-    require_quiet(args = CFArrayCreateMutable(kCFAllocatorDefault, 3, NULL),
-        errOut);
-    CFArrayAppendValue(args, backup);
-    CFArrayAppendValue(args, backupKeybag);
-    if (password)
-        CFArrayAppendValue(args, password);
+#else
 
 
-    require_noerr_quiet(status = SECURITYD(sec_keychain_restore, args, NULL),
-    errOut);
+extern OSStatus SecTaskValidateForRequirement(SecTaskRef task, CFStringRef requirement);
 
 
-errOut:
-    CFReleaseSafe(args);
-    CFReleaseSafe(raw_result);
-       return status;
-}
+#endif
index bf08e35838f44a442c862fc28b149b862e9871cd..0afcc9ed7f2723db4b175ed09b22caaebb9d5e4c 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2006-2010 Apple Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2006-2013 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -35,9 +35,7 @@
 #include <CoreFoundation/CFArray.h>
 #include <CoreFoundation/CFDictionary.h>
 
 #include <CoreFoundation/CFArray.h>
 #include <CoreFoundation/CFDictionary.h>
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 /*!
     @enum Class Key Constant
 
 /*!
     @enum Class Key Constant
@@ -152,28 +150,80 @@ extern CFTypeRef kSecClassIdentity
         certificate, this class shares attributes of both kSecClassKey and
         kSecClassCertificate.
 
         certificate, this class shares attributes of both kSecClassKey and
         kSecClassCertificate.
 
-    @constant kSecAttrAccessible Specifies a dictionary key whose value
-        indicates when your application needs access to an items data.  You
-        should choose the most restrictive option that meets your applications
-        needs to allow the system to protect that item in the best way
-        possible.
-    @constant kSecAttrAccessGroup Specifies a dictionary key whose value is
-        a CFStringRef indicating which access group an item is in.  The access
-        groups that a particular application has access to are determined by
-        two entitlements for that application.  The application-identifier
-        entitlement contains the applications single access group, unless
-        there is a keychain-access-groups entitlement present.  The latter
-        has as its value a list of access groups.   The first (or only)
-        access group an application is in is the default one new items are
-        created in.  By default SecItemCopyMatching searches all the access
-        groups an item is a member of.  Specifying this attribute to
-        SecItemAdd, changes the access group an item will be added to, or
-        limits which access groups are searched for SecItemUpdate,
-        SecItemDelete or SecItemCopyMatching calls.  To share keychain items
-        between multiple applications they need to have a common group listed
-        in their keychain-access-groups entitlement, and they must both specify
-        this shared access group name as the value for this key in the
-        dictionary passed to SecItemAdd().
+     @constant kSecAttrAccessible Specifies a dictionary key whose value
+     indicates when your application needs access to an item's data.  You
+     should choose the most restrictive option that meets your application's
+     needs to allow the system to protect that item in the best way possible.
+     See the "kSecAttrAccessible Value Constants" section for a list of
+     values which can be specified.
+     IMPORTANT: This attribute is currently not supported for OS X keychain
+     items, unless the kSecAttrSynchronizable attribute is also present. If
+     both attributes are specified on either OS X or iOS, the value for the
+     kSecAttrAccessible key may only be one whose name does not end with
+     "ThisDeviceOnly", as those cannot sync to another device.
+
+     @constant kSecAttrAccessGroup Specifies a dictionary key whose value is
+     a CFStringRef indicating which access group a item is in.  The access
+     groups that a particular application has membership in are determined by
+     two entitlements for that application.  The application-identifier
+     entitlement contains the application's single access group, unless
+     there is a keychain-access-groups entitlement present.  The latter
+     has as its value a list of access groups; the first item in this list
+     is the default access group. Unless a specific access group is provided
+     as the value of kSecAttrAccessGroup when SecItemAdd is called, new items
+     are created in the application's default access group.  Specifying this
+     attribute in SecItemCopyMatching, SecItemUpdate, or SecItemDelete calls
+     limits the search to the specified access group (of which the calling
+     application must be a member to obtain matching results.)  To share
+     keychain items between multiple applications, each application must have
+     a common group listed in its keychain-access-groups entitlement, and each
+     must specify this shared access group name as the value for the
+     kSecAttrAccessGroup key in the dictionary passed to SecItem functions.
+
+     @constant kSecAttrSynchronizable Specifies a dictionary key whose value is
+     a CFBooleanRef indicating whether the item in question can be synchronized.
+     To add a new item which can be synced to other devices, or to obtain
+     synchronizable results from a query, supply this key with a value of
+     kCFBooleanTrue. If the key is not supplied, or has a value of
+     kCFBooleanFalse, then no synchronizable items will be added or returned.
+     A predefined value, kSecAttrSynchronizableAny, may be provided instead of
+     kCFBooleanTrue if both synchronizable and non-synchronizable results are
+     desired.
+
+     IMPORTANT: Specifying the kSecAttrSynchronizable key has several caveats:
+
+         - Updating or deleting items using the kSecAttrSynchronizable key will
+           affect all copies of the item, not just the one on your local device.
+           Be sure that it makes sense to use the same password on all devices
+           before deciding to make a password synchronizable.
+         - Only password items can currently be synchronized. Keychain syncing
+           is not supported for certificates or cryptographic keys.
+         - Items stored or obtained using the kSecAttrSynchronizable key cannot
+           specify SecAccessRef-based access control with kSecAttrAccess. If a
+           password is intended to be shared between multiple applications, the
+           kSecAttrAccessGroup key must be specified, and each application
+           using this password must have a 'keychain-access-groups' entitlement
+           with the specified access group value.
+         - Items stored or obtained using the kSecAttrSynchronizable key may
+           not also specify a kSecAttrAccessible value which is incompatible
+           with syncing (namely, those whose names end with "ThisDeviceOnly".)
+         - Items stored or obtained using the kSecAttrSynchronizable key cannot
+           be specified by reference. You must pass kSecReturnAttributes and/or
+           kSecReturnData to retrieve results; kSecReturnRef is currently not
+           supported for synchronizable items.
+         - Persistent references to synchronizable items should be avoided;
+           while they may work locally, they cannot be moved between devices,
+           and may not resolve if the item is modified on some other device.
+         - When specifying a query that uses the kSecAttrSynchronizable key,
+           search keys are limited to the item's class and attributes.
+           The only search constant which may be used is kSecMatchLimit; other
+           constants using the kSecMatch prefix are not supported at this time.
+
+     @constant kSecAttrSynchronizableAny Specifies that both synchronizable and
+     non-synchronizable results should be returned from this query. This may be
+     used as a value for the kSecAttrSynchronizable dictionary key in a call to
+     SecItemCopyMatching, SecItemUpdate, or SecItemDelete.
+
     @constant kSecAttrCreationDate (read-only) Specifies a dictionary key whose
         value is the item's creation date. You use this key to get a value
         of type CFDateRef that represents the date the item was created.
     @constant kSecAttrCreationDate (read-only) Specifies a dictionary key whose
         value is the item's creation date. You use this key to get a value
         of type CFDateRef that represents the date the item was created.
@@ -241,7 +291,7 @@ extern CFTypeRef kSecClassIdentity
         is the item's authentication type attribute. You use this key to set
         or get a value of type CFNumberRef that denotes the authentication
         scheme for this item (see the kSecAttrAuthenticationType value
         is the item's authentication type attribute. You use this key to set
         or get a value of type CFNumberRef that denotes the authentication
         scheme for this item (see the kSecAttrAuthenticationType value
-               constants below).
+        constants below).
     @constant kSecAttrPort Specifies a dictionary key whose value is the item's
         port attribute. You use this key to set or get a CFNumberRef value
         that represents an Internet port number. (Items of class
     @constant kSecAttrPort Specifies a dictionary key whose value is the item's
         port attribute. You use this key to set or get a CFNumberRef value
         that represents an Internet port number. (Items of class
@@ -331,9 +381,13 @@ extern CFTypeRef kSecClassIdentity
         unwrap another key.
 */
 extern CFTypeRef kSecAttrAccessible
         unwrap another key.
 */
 extern CFTypeRef kSecAttrAccessible
-    __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_4_0);
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0);
 extern CFTypeRef kSecAttrAccessGroup
 extern CFTypeRef kSecAttrAccessGroup
-    __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_3_0);
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_3_0);
+extern CFTypeRef kSecAttrSynchronizable
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFTypeRef kSecAttrSynchronizableAny
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
 extern CFTypeRef kSecAttrCreationDate
     __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
 extern CFTypeRef kSecAttrModificationDate
 extern CFTypeRef kSecAttrCreationDate
     __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
 extern CFTypeRef kSecAttrModificationDate
@@ -418,52 +472,52 @@ extern CFTypeRef kSecAttrCanUnwrap
     @discussion Predefined item attribute constants used to get or set values
         in a dictionary. The kSecAttrAccessible constant is the key and its
         value is one of the constants defined here.
     @discussion Predefined item attribute constants used to get or set values
         in a dictionary. The kSecAttrAccessible constant is the key and its
         value is one of the constants defined here.
-        When ask SecItemCopyMatching to return the items data the error
-        errSecInteractionNotAllowed will be returned if the items data is not
+        When asking SecItemCopyMatching to return the item's data, the error
+        errSecInteractionNotAllowed will be returned if the item's data is not
         available until a device unlock occurs.
         available until a device unlock occurs.
-    @constant kSecAttrAccessibleWhenUnlocked item's data can only be accessed
+    @constant kSecAttrAccessibleWhenUnlocked Item data can only be accessed
         while the device is unlocked. This is recommended for items that only
         need be accesible while the application is in the foreground.  Items
         with this attribute will migrate to a new device when using encrypted
         backups.
         while the device is unlocked. This is recommended for items that only
         need be accesible while the application is in the foreground.  Items
         with this attribute will migrate to a new device when using encrypted
         backups.
-    @constant kSecAttrAccessibleAfterFirstUnlock item's data can only be
+    @constant kSecAttrAccessibleAfterFirstUnlock Item data can only be
         accessed once the device has been unlocked after a restart.  This is
         recommended for items that need to be accesible by background
         applications. Items with this attribute will migrate to a new device
         when using encrypted backups.
         accessed once the device has been unlocked after a restart.  This is
         recommended for items that need to be accesible by background
         applications. Items with this attribute will migrate to a new device
         when using encrypted backups.
-    @constant kSecAttrAccessibleAlways item's data can always be accessed
+    @constant kSecAttrAccessibleAlways Item data can always be accessed
         regardless of the lock state of the device.  This is not recommended
         for anything except system use. Items with this attribute will migrate
         to a new device when using encrypted backups.
         regardless of the lock state of the device.  This is not recommended
         for anything except system use. Items with this attribute will migrate
         to a new device when using encrypted backups.
-    @constant kSecAttrAccessibleWhenUnlockedThisDeviceOnly item's data can only
+    @constant kSecAttrAccessibleWhenUnlockedThisDeviceOnly Item data can only
         be accessed while the device is unlocked. This is recommended for items
         that only need be accesible while the application is in the foreground.
         Items with this attribute will never migrate to a new device, so after
         be accessed while the device is unlocked. This is recommended for items
         that only need be accesible while the application is in the foreground.
         Items with this attribute will never migrate to a new device, so after
-        a backup is restored to a new device these items will be missing.
-    @constant kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly item's data can
+        a backup is restored to a new device, these items will be missing.
+    @constant kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly Item data can
         only be accessed once the device has been unlocked after a restart.
         This is recommended for items that need to be accessible by background
         applications. Items with this attribute will never migrate to a new
         device, so after a backup is restored to a new device these items will
         be missing.
         only be accessed once the device has been unlocked after a restart.
         This is recommended for items that need to be accessible by background
         applications. Items with this attribute will never migrate to a new
         device, so after a backup is restored to a new device these items will
         be missing.
-    @constant kSecAttrAccessibleAlwaysThisDeviceOnly item's data can
-        always be accessed regardless of the lock state of the device.  This
+    @constant kSecAttrAccessibleAlwaysThisDeviceOnly Item data can always
+        be accessed regardless of the lock state of the device.  This option
         is not recommended for anything except system use. Items with this
         attribute will never migrate to a new device, so after a backup is
         is not recommended for anything except system use. Items with this
         attribute will never migrate to a new device, so after a backup is
-        restored to a new device these items will be missing.
+        restored to a new device, these items will be missing.
 */
 extern CFTypeRef kSecAttrAccessibleWhenUnlocked
 */
 extern CFTypeRef kSecAttrAccessibleWhenUnlocked
-    __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_4_0);
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0);
 extern CFTypeRef kSecAttrAccessibleAfterFirstUnlock
 extern CFTypeRef kSecAttrAccessibleAfterFirstUnlock
-    __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_4_0);
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0);
 extern CFTypeRef kSecAttrAccessibleAlways
 extern CFTypeRef kSecAttrAccessibleAlways
-    __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_4_0);
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0);
 extern CFTypeRef kSecAttrAccessibleWhenUnlockedThisDeviceOnly
 extern CFTypeRef kSecAttrAccessibleWhenUnlockedThisDeviceOnly
-    __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_4_0);
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0);
 extern CFTypeRef kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
 extern CFTypeRef kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
-    __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_4_0);
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0);
 extern CFTypeRef kSecAttrAccessibleAlwaysThisDeviceOnly
 extern CFTypeRef kSecAttrAccessibleAlwaysThisDeviceOnly
-    __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_4_0);
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0);
 
 /*!
     @enum kSecAttrProtocol Value Constants
 
 /*!
     @enum kSecAttrProtocol Value Constants
@@ -623,7 +677,7 @@ extern CFTypeRef kSecAttrKeyClassSymmetric
 extern CFTypeRef kSecAttrKeyTypeRSA
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0);
 extern CFTypeRef kSecAttrKeyTypeEC
 extern CFTypeRef kSecAttrKeyTypeRSA
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0);
 extern CFTypeRef kSecAttrKeyTypeEC
-    __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_4_0);
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0);
 
 /*!
     @enum Search Constants
 
 /*!
     @enum Search Constants
@@ -635,7 +689,7 @@ extern CFTypeRef kSecAttrKeyTypeEC
         SecPolicyRef. If provided, returned certificates or identities must
         verify with this policy.
     @constant kSecMatchIssuers Specifies a dictionary key whose value is a
         SecPolicyRef. If provided, returned certificates or identities must
         verify with this policy.
     @constant kSecMatchIssuers Specifies a dictionary key whose value is a
-        CFArray of X.500 names (of type CFDataRef). If provided, returned 
+        CFArray of X.500 names (of type CFDataRef). If provided, returned
         certificates or identities will be limited to those whose
         certificate chain contains one of the issuers provided in this list.
     @constant kSecMatchEmailAddressIfPresent Specifies a dictionary key whose
         certificates or identities will be limited to those whose
         certificate chain contains one of the issuers provided in this list.
     @constant kSecMatchEmailAddressIfPresent Specifies a dictionary key whose
@@ -735,7 +789,7 @@ extern CFTypeRef kSecReturnPersistentRef
     @discussion Predefined value type keys used to pass values in a dictionary.
         You can specify zero or more of these types depending on the function
         you are calling.  For SecItemCopyMatching or SecItemAdd these are
     @discussion Predefined value type keys used to pass values in a dictionary.
         You can specify zero or more of these types depending on the function
         you are calling.  For SecItemCopyMatching or SecItemAdd these are
-        used as keys in the results dictionary. 
+        used as keys in the results dictionary.
     @constant kSecValueData Specifies a dictionary key whose value is of type
         CFDataRef.  For keys and password items, data is secret (encrypted)
         and may require the user to enter a password for access.
     @constant kSecValueData Specifies a dictionary key whose value is of type
         CFDataRef.  For keys and password items, data is secret (encrypted)
         and may require the user to enter a password for access.
@@ -782,7 +836,7 @@ extern CFTypeRef kSecUseItemList
     @result A result code. See "Security Error Codes" (SecBase.h).
     @discussion Attributes defining a search are specified by adding key/value
         pairs to the query dictionary.
     @result A result code. See "Security Error Codes" (SecBase.h).
     @discussion Attributes defining a search are specified by adding key/value
         pairs to the query dictionary.
-        
+
     A typical query consists of:
 
       * a kSecClass key, whose value is a constant from the Class
     A typical query consists of:
 
       * a kSecClass key, whose value is a constant from the Class
@@ -822,7 +876,7 @@ extern CFTypeRef kSecUseItemList
     provided array must be of the same type.
 
     To convert from a persistent item reference to a normal item reference,
     provided array must be of the same type.
 
     To convert from a persistent item reference to a normal item reference,
-    specify a kSecValuePersistentRef whose value a CFDataRef (the persistent 
+    specify a kSecValuePersistentRef whose value a CFDataRef (the persistent
     reference), and a kSecReturnRef whose value is kCFBooleanTrue.
 */
 OSStatus SecItemCopyMatching(CFDictionaryRef query, CFTypeRef *result)
     reference), and a kSecReturnRef whose value is kCFBooleanTrue.
 */
 OSStatus SecItemCopyMatching(CFDictionaryRef query, CFTypeRef *result)
@@ -903,8 +957,8 @@ OSStatus SecItemUpdate(CFDictionaryRef query,
         kSecValueRef with a reference returned by using the kSecReturnRef
         key in a previous call to SecItemCopyMatching or SecItemAdd.
       * To delete an item identified by a persistent reference, specify
         kSecValueRef with a reference returned by using the kSecReturnRef
         key in a previous call to SecItemCopyMatching or SecItemAdd.
       * To delete an item identified by a persistent reference, specify
-        kSecValuePersistentRef with a persistent reference returned by 
-        using the kSecReturnPersistentRef key to SecItemCopyMatching or 
+        kSecValuePersistentRef with a persistent reference returned by
+        using the kSecReturnPersistentRef key to SecItemCopyMatching or
         SecItemAdd.
       * To delete multiple items specify kSecMatchItemList with an array
         of references.
         SecItemAdd.
       * To delete multiple items specify kSecMatchItemList with an array
         of references.
@@ -914,8 +968,6 @@ OSStatus SecItemUpdate(CFDictionaryRef query,
 OSStatus SecItemDelete(CFDictionaryRef query)
     __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
 
 OSStatus SecItemDelete(CFDictionaryRef query)
     __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
 
-#if defined(__cplusplus)
-}
-#endif
+__END_DECLS
 
 #endif /* !_SECURITY_SECITEM_H_ */
 
 #endif /* !_SECURITY_SECITEM_H_ */
index abb6793fd0798d41acab86a8f35e353084e4688d..8e0fec3b31efdf605f7ab3b09f917c2b2a27b6e5 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2006-2008,2010 Apple Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2006-2008,2010-2013 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -102,6 +102,8 @@ SEC_CONST_DECL (kSecAttrHasCustomIcon, "cusi");
 SEC_CONST_DECL (kSecAttrCRLType, "crlt");
 SEC_CONST_DECL (kSecAttrCRLEncoding, "crle");
 SEC_CONST_DECL (kSecAttrSynchronizable, "sync");
 SEC_CONST_DECL (kSecAttrCRLType, "crlt");
 SEC_CONST_DECL (kSecAttrCRLEncoding, "crle");
 SEC_CONST_DECL (kSecAttrSynchronizable, "sync");
+SEC_CONST_DECL (kSecAttrSynchronizableAny, "syna");
+SEC_CONST_DECL (kSecAttrTombstone, "tomb");
 
 /* Search Constants */
 SEC_CONST_DECL (kSecMatchPolicy, "m_Policy");
 
 /* Search Constants */
 SEC_CONST_DECL (kSecMatchPolicy, "m_Policy");
@@ -131,6 +133,7 @@ SEC_CONST_DECL (kSecValuePersistentRef, "v_PersistentRef");
 
 /* Other Constants */
 SEC_CONST_DECL (kSecUseItemList, "u_ItemList");
 
 /* Other Constants */
 SEC_CONST_DECL (kSecUseItemList, "u_ItemList");
+SEC_CONST_DECL (kSecUseTombstones, "u_Tomb");
 #if defined(MULTIPLE_KEYCHAINS)
 /* Other Constants (Private) */
 SEC_CONST_DECL (kSecUseKeychain, "u_Keychain");
 #if defined(MULTIPLE_KEYCHAINS)
 /* Other Constants (Private) */
 SEC_CONST_DECL (kSecUseKeychain, "u_Keychain");
@@ -197,11 +200,17 @@ SEC_CONST_DECL (kSecAttrKeyClassPublic, "0");
 SEC_CONST_DECL (kSecAttrKeyClassPrivate, "1");
 SEC_CONST_DECL (kSecAttrKeyClassSymmetric, "2");
 
 SEC_CONST_DECL (kSecAttrKeyClassPrivate, "1");
 SEC_CONST_DECL (kSecAttrKeyClassSymmetric, "2");
 
-/* kSecAttrKeyType Value Constants. */
+/* kSecAttrKeyType Value Constants.  Based on CSSM_ALGORITHMS. */
 SEC_CONST_DECL (kSecAttrKeyTypeRSA, "42");
 SEC_CONST_DECL (kSecAttrKeyTypeRSA, "42");
-SEC_CONST_DECL (kSecAttrKeyTypeEC, "43");
+SEC_CONST_DECL (kSecAttrKeyTypeEC, "73");  /* rdar://10755886 */
 
 /* Constants used by SecKeyGeneratePair() - in SecKey.h.  Never used in
    any SecItem apis directly. */
 SEC_CONST_DECL (kSecPrivateKeyAttrs, "private");
 SEC_CONST_DECL (kSecPublicKeyAttrs, "public");
 
 /* Constants used by SecKeyGeneratePair() - in SecKey.h.  Never used in
    any SecItem apis directly. */
 SEC_CONST_DECL (kSecPrivateKeyAttrs, "private");
 SEC_CONST_DECL (kSecPublicKeyAttrs, "public");
+
+/* Constants used by SecPassword - in SecPasswordStrength */
+SEC_CONST_DECL (kSecPasswordMaxLength, "PasswordMaxLength");
+SEC_CONST_DECL (kSecPasswordMinLength, "PasswordMaxLength");
+SEC_CONST_DECL (kSecPasswordAllowedCharacters, "PasswordAllowedCharacters");
+SEC_CONST_DECL (kSecPasswordRequiredCharacters, "PasswordRequiredCharacters");
index aa494701289413b51102c0f40a01eff6e844bca7..bc59891da83e9684a7ec52e6a27ac4bf4b5c452d 100644 (file)
 #include <CoreFoundation/CFData.h>
 #include <sqlite3.h>
 
 #include <CoreFoundation/CFData.h>
 #include <sqlite3.h>
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
+
+#define kSecServerKeychainChangedNotification "com.apple.security.keychainchanged"
 
 CFDataRef _SecItemMakePersistentRef(CFTypeRef class, sqlite_int64 rowid);
 
 bool _SecItemParsePersistentRef(CFDataRef persistent_ref, CFStringRef *return_class,
     sqlite_int64 *return_rowid);
 
 
 CFDataRef _SecItemMakePersistentRef(CFTypeRef class, sqlite_int64 rowid);
 
 bool _SecItemParsePersistentRef(CFDataRef persistent_ref, CFStringRef *return_class,
     sqlite_int64 *return_rowid);
 
-
 OSStatus _SecRestoreKeychain(const char *path);
 
 OSStatus _SecRestoreKeychain(const char *path);
 
-#if defined(__cplusplus)
-}
-#endif
+OSStatus SecOSStatusWith(bool (^perform)(CFErrorRef *error));
+
+__END_DECLS
 
 #endif /* !_SECURITY_SECITEMINTERNAL_H_ */
 
 #endif /* !_SECURITY_SECITEMINTERNAL_H_ */
index 99fa33ac9c21b0b32b18c8342f88b73b4e345e81..51472bc80bdd09c56887b352f8f2ff2907f08e23 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2006-2010 Apple Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2006-2013 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
 #define _SECURITY_SECITEMPRIV_H_
 
 #include <CoreFoundation/CFData.h>
 #define _SECURITY_SECITEMPRIV_H_
 
 #include <CoreFoundation/CFData.h>
+#include <CoreFoundation/CFError.h>
 
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 /*!
     @enum Class Value Constants (Private)
 
 /*!
     @enum Class Value Constants (Private)
@@ -235,8 +234,8 @@ extern CFTypeRef kSecClassAppleSharePassword;
     @constant kSecAttrCanVerifyRecover Specifies a dictionary key whole value is
         a CFBooleanRef indicating whether the key in question can be used to
         perform verify recovery.
     @constant kSecAttrCanVerifyRecover Specifies a dictionary key whole value is
         a CFBooleanRef indicating whether the key in question can be used to
         perform verify recovery.
-    @constant kSecAttrSynchronizable Specifies a dictionary key whose value is
-        a CFBooleanRef indicating that the item in question can be synchronized.
+    @constant kSecAttrTombstone Specifies a dictionary key whose value is
+        a CFBooleanRef indicating that the item in question is a tombstone.
 */
 extern CFTypeRef kSecAttrScriptCode;
 extern CFTypeRef kSecAttrAlias;
 */
 extern CFTypeRef kSecAttrScriptCode;
 extern CFTypeRef kSecAttrAlias;
@@ -257,11 +256,19 @@ extern CFTypeRef kSecAttrIsExtractable;
 extern CFTypeRef kSecAttrWasNeverExtractable;
 extern CFTypeRef kSecAttrCanSignRecover;
 extern CFTypeRef kSecAttrCanVerifyRecover;
 extern CFTypeRef kSecAttrWasNeverExtractable;
 extern CFTypeRef kSecAttrCanSignRecover;
 extern CFTypeRef kSecAttrCanVerifyRecover;
-extern CFTypeRef kSecAttrSynchronizable;
+extern CFTypeRef kSecAttrTombstone;
 
 /*!
     @enum Other Constants (Private)
     @discussion Predefined constants used to set values in a dictionary.
 
 /*!
     @enum Other Constants (Private)
     @discussion Predefined constants used to set values in a dictionary.
+    @constant kSecUseTombstones Specifies a dictionary key whose value is a
+        CFBooleanRef if present this overrides the default behaviour for when
+        we make tombstones.  The default being we create tombstones for
+        synchronizable items unless we are explicitly deleting or updating a
+        tombstone.  Setting this to false when calling SecItemDelete or
+        SecItemUpdate will ensure no tombstones are created.  Setting it to
+        true will ensure we create tombstones even when deleting or updating non
+        synchronizable items.
     @constant kSecUseKeychain Specifies a dictionary key whose value is a
         keychain reference. You use this key to specify a value of type
         SecKeychainRef that indicates the keychain to which SecItemAdd
     @constant kSecUseKeychain Specifies a dictionary key whose value is a
         keychain reference. You use this key to specify a value of type
         SecKeychainRef that indicates the keychain to which SecItemAdd
@@ -273,6 +280,8 @@ extern CFTypeRef kSecAttrSynchronizable;
         explicit kSecUseItemList is also provided.  This key can be used
         for the SecItemCopyMatching, SecItemUpdate and SecItemDelete calls.
 */
         explicit kSecUseItemList is also provided.  This key can be used
         for the SecItemCopyMatching, SecItemUpdate and SecItemDelete calls.
 */
+extern CFTypeRef kSecUseTombstones
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
 #if defined(MULTIPLE_KEYCHAINS)
 extern CFTypeRef kSecUseKeychain;
 extern CFTypeRef kSecUseKeychainList;
 #if defined(MULTIPLE_KEYCHAINS)
 extern CFTypeRef kSecUseKeychain;
 extern CFTypeRef kSecUseKeychainList;
@@ -305,26 +314,6 @@ OSStatus SecItemCopyDisplayNames(CFArrayRef items, CFArrayRef *displayNames);
 */
 OSStatus SecItemDeleteAll(void);
 
 */
 OSStatus SecItemDeleteAll(void);
 
-enum {
-    kSecMigrateKeychainImport = -1,
-    kSecMigrateKeychainExport = 0
-};
-
-/* Call this function with a 0 handle_in and NULL data_in to start an export.
-   data_out will be returned if data needs to be transmitted to the client
-   (caller is responsible for CFReleasing returned CFDataRef). If handle_out
-   is set to nonzero on return, then the caller should call this function again
-   with the returned handle passed as handle_in and the response from the
-   importing client on the other end of the connection as data_in.  Caller
-   should continue passing data_out to the importing device and continue
-   providing additional data until handle_out is set to zero.
-
-   When importing, call this function with handle_in set to 0 and data_in to
-   the data to be imported, if more data is expected, handle_out will be
-   non zero upon return. */
-OSStatus _SecMigrateKeychain(int32_t handle_in, CFDataRef data_in,
-    int32_t *handle_out, CFDataRef *data_out);
-
 /*
     Ensure the escrow keybag has been used to unlock the system keybag before
     calling either of these APIs.
 /*
     Ensure the escrow keybag has been used to unlock the system keybag before
     calling either of these APIs.
@@ -334,11 +323,19 @@ OSStatus _SecMigrateKeychain(int32_t handle_in, CFDataRef data_in,
  */
 CFDataRef _SecKeychainCopyBackup(CFDataRef backupKeybag, CFDataRef password);
 CFDataRef _SecKeychainCopyOTABackup(void);
  */
 CFDataRef _SecKeychainCopyBackup(CFDataRef backupKeybag, CFDataRef password);
 CFDataRef _SecKeychainCopyOTABackup(void);
-bool _SecKeychainRestoreBackup(CFDataRef backup, CFDataRef backupKeybag,
+OSStatus _SecKeychainRestoreBackup(CFDataRef backup, CFDataRef backupKeybag,
     CFDataRef password);
 
     CFDataRef password);
 
-#if defined(__cplusplus)
-}
-#endif
+OSStatus _SecKeychainBackupSyncable(CFDataRef keybag, CFDataRef password, CFDictionaryRef backup_in, CFDictionaryRef *backup_out);
+OSStatus _SecKeychainRestoreSyncable(CFDataRef keybag, CFDataRef password, CFDictionaryRef backup_in);
+
+/* Called by clients to push sync circle and message changes to us.
+   Requires caller to have the kSecEntitlementKeychainSyncUpdates entitlement. */
+bool _SecKeychainSyncUpdate(CFDictionaryRef updates, CFErrorRef *error);
+
+/* Returns an OSStatus value for the given CFErrorRef, returns errSecInternal if the domain of the providied error is not recognized.  Passing NULL returns errSecSuccess (0). */
+OSStatus SecErrorGetOSStatus(CFErrorRef error);
+
+__END_DECLS
 
 #endif /* !_SECURITY_SECITEMPRIV_H_ */
 
 #endif /* !_SECURITY_SECITEMPRIV_H_ */
index f09fadfe0072ed65eaa6c4aca05688e53ddfdbae..227a6c0755ba2058a3db98ec2fcca9e5da1a47d0 100644 (file)
@@ -1,15 +1,15 @@
 /*
  * Copyright (c) 2006-2011 Apple Inc. All Rights Reserved.
 /*
  * Copyright (c) 2006-2011 Apple Inc. All Rights Reserved.
- * 
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
-/* 
+/*
  * SecKey.c - CoreFoundation based key object
  */
 
  * SecKey.c - CoreFoundation based key object
  */
 
 #include <Security/SecItemPriv.h>
 #include <Security/SecFramework.h>
 
 #include <Security/SecItemPriv.h>
 #include <Security/SecFramework.h>
 
+#include <utilities/SecIOFormat.h>
+
+#include <utilities/SecCFWrappers.h>
+
 #include "SecRSAKeyPriv.h"
 #include "SecECKey.h"
 #include "SecBasePriv.h"
 
 #include <CoreFoundation/CFNumber.h>
 #include <CoreFoundation/CFString.h>
 #include "SecRSAKeyPriv.h"
 #include "SecECKey.h"
 #include "SecBasePriv.h"
 
 #include <CoreFoundation/CFNumber.h>
 #include <CoreFoundation/CFString.h>
-#include <MacErrors.h>
+#include <Security/SecBase.h>
 #include <pthread.h>
 #include <string.h>
 #include <AssertMacros.h>
 #include <pthread.h>
 #include <string.h>
 #include <AssertMacros.h>
-#include <security_utilities/debugging.h>
+#include <utilities/debugging.h>
+#include <utilities/SecCFError.h>
 #include <CommonCrypto/CommonDigest.h>
 #include <Security/SecAsn1Coder.h>
 #include <Security/oidsalg.h>
 #include <CommonCrypto/CommonDigest.h>
 #include <Security/SecAsn1Coder.h>
 #include <Security/oidsalg.h>
 #include <Security/SecRandom.h>
 #include <corecrypto/ccrng_system.h>
 #include <asl.h>
 #include <Security/SecRandom.h>
 #include <corecrypto/ccrng_system.h>
 #include <asl.h>
+#include <stdlib.h>
 
 static pthread_once_t kSecKeyRegisterClass = PTHREAD_ONCE_INIT;
 static CFTypeID kSecKeyTypeID = _kCFRuntimeNotATypeID;
 
 /* Forward declartions of static functions. */
 
 static pthread_once_t kSecKeyRegisterClass = PTHREAD_ONCE_INIT;
 static CFTypeID kSecKeyTypeID = _kCFRuntimeNotATypeID;
 
 /* Forward declartions of static functions. */
-static CFStringRef SecKeyDescribe(CFTypeRef cf);
+static CFStringRef SecKeyCopyDescription(CFTypeRef cf);
 static void SecKeyDestroy(CFTypeRef cf);
 
 /* Static functions. */
 static void SecKeyDestroy(CFTypeRef cf);
 
 /* Static functions. */
@@ -66,26 +72,27 @@ static void SecKeyDestroy(CFTypeRef cf);
 #define DER_MAX_DIGEST_INFO_LEN  (10 + MAX_DIGEST_LEN + MAX_OID_LEN)
 
 /* Encode the digestInfo header into digestInfo and return the offset from
 #define DER_MAX_DIGEST_INFO_LEN  (10 + MAX_DIGEST_LEN + MAX_OID_LEN)
 
 /* Encode the digestInfo header into digestInfo and return the offset from
-   digestInfo at which to put the actual digest.  Returns 0 if digestInfo
-   won't fit within digestInfoLength bytes.
-
-    0x30, topLen,
-        0x30, algIdLen,
-            0x06, oid.Len, oid.Data,
-            0x05, 0x00
-        0x04, digestLen
-            digestData
-*/
+ digestInfo at which to put the actual digest.  Returns 0 if digestInfo
+ won't fit within digestInfoLength bytes.
+ 0x30, topLen,
+ 0x30, algIdLen,
+ 0x06, oid.Len, oid.Data,
+ 0x05, 0x00
+ 0x04, digestLen
+ digestData
+ */
+
 static size_t DEREncodeDigestInfoPrefix(const SecAsn1Oid *oid,
 static size_t DEREncodeDigestInfoPrefix(const SecAsn1Oid *oid,
-    size_t digestLength, uint8_t *digestInfo, size_t digestInfoLength) {
+                                        size_t digestLength, uint8_t *digestInfo, size_t digestInfoLength) {
     size_t algIdLen = oid->Length + 4;
     size_t topLen = algIdLen + digestLength + 4;
        size_t totalLen = topLen + 2;
     size_t algIdLen = oid->Length + 4;
     size_t topLen = algIdLen + digestLength + 4;
        size_t totalLen = topLen + 2;
-
+    
     if (totalLen > digestInfoLength) {
         return 0;
     }
     if (totalLen > digestInfoLength) {
         return 0;
     }
-
+    
     size_t ix = 0;
     digestInfo[ix++] = (SEC_ASN1_SEQUENCE | SEC_ASN1_CONSTRUCTED);
     digestInfo[ix++] = topLen;
     size_t ix = 0;
     digestInfo[ix++] = (SEC_ASN1_SEQUENCE | SEC_ASN1_CONSTRUCTED);
     digestInfo[ix++] = topLen;
@@ -99,7 +106,7 @@ static size_t DEREncodeDigestInfoPrefix(const SecAsn1Oid *oid,
     digestInfo[ix++] = 0;
     digestInfo[ix++] = SEC_ASN1_OCTET_STRING;
     digestInfo[ix++] = digestLength;
     digestInfo[ix++] = 0;
     digestInfo[ix++] = SEC_ASN1_OCTET_STRING;
     digestInfo[ix++] = digestLength;
-
+    
     return ix;
 }
 
     return ix;
 }
 
@@ -111,29 +118,47 @@ static void register_algs(void) {
 }
 
 
 }
 
 
+static CFDataRef SecKeyCopyPublicKeyHash(SecKeyRef key)
+{
+       CFDataRef pubKeyDigest = NULL, pubKeyBlob = NULL;
+
+       /* encode the public key. */
+    require_noerr(SecKeyCopyPublicBytes(key, &pubKeyBlob), errOut);
+    require(pubKeyBlob, errOut);
+    
+       /* Calculate the digest of the public key. */
+       require(pubKeyDigest = SecSHA1DigestCreate(CFGetAllocator(key),
+                                               CFDataGetBytePtr(pubKeyBlob), CFDataGetLength(pubKeyBlob)),
+                       errOut);
+errOut:
+    CFReleaseNull(pubKeyBlob);
+    return pubKeyDigest;
+}
+
+
 /*
  */
 /*
  */
-static CFDictionaryRef SecKeyGenerateAttributeDictionaryFor(SecKeyRef key,
-                                                     CFTypeRef keyType,
-                                                     CFDataRef privateBlob)
+static CF_RETURNS_RETAINED CFDictionaryRef SecKeyGenerateAttributeDictionaryFor(SecKeyRef key,
+                                                                                CFTypeRef keyType,
+                                                                                CFDataRef privateBlob)
 {
        CFAllocatorRef allocator = CFGetAllocator(key);
        DICT_DECLARE(25);
        CFDataRef pubKeyDigest = NULL, pubKeyBlob = NULL;
        CFDictionaryRef dict = NULL;
 {
        CFAllocatorRef allocator = CFGetAllocator(key);
        DICT_DECLARE(25);
        CFDataRef pubKeyDigest = NULL, pubKeyBlob = NULL;
        CFDictionaryRef dict = NULL;
-
+    
     size_t sizeValue = SecKeyGetSize(key, kSecKeyKeySizeInBits);
     CFNumberRef sizeInBits = CFNumberCreate(allocator, kCFNumberLongType, &sizeValue);
     size_t sizeValue = SecKeyGetSize(key, kSecKeyKeySizeInBits);
     CFNumberRef sizeInBits = CFNumberCreate(allocator, kCFNumberLongType, &sizeValue);
-
+    
        /* encode the public key. */
     require_noerr(SecKeyCopyPublicBytes(key, &pubKeyBlob), errOut);
     require(pubKeyBlob, errOut);
        /* encode the public key. */
     require_noerr(SecKeyCopyPublicBytes(key, &pubKeyBlob), errOut);
     require(pubKeyBlob, errOut);
-
+    
        /* Calculate the digest of the public key. */
        require(pubKeyDigest = SecSHA1DigestCreate(allocator,
                                                CFDataGetBytePtr(pubKeyBlob), CFDataGetLength(pubKeyBlob)),
                        errOut);
        /* Calculate the digest of the public key. */
        require(pubKeyDigest = SecSHA1DigestCreate(allocator,
                                                CFDataGetBytePtr(pubKeyBlob), CFDataGetLength(pubKeyBlob)),
                        errOut);
-
+    
        DICT_ADDPAIR(kSecClass, kSecClassKey);
        DICT_ADDPAIR(kSecAttrKeyClass, privateBlob ? kSecAttrKeyClassPrivate : kSecAttrKeyClassPublic);
        DICT_ADDPAIR(kSecAttrApplicationLabel, pubKeyDigest);
        DICT_ADDPAIR(kSecClass, kSecClassKey);
        DICT_ADDPAIR(kSecAttrKeyClass, privateBlob ? kSecAttrKeyClassPrivate : kSecAttrKeyClassPublic);
        DICT_ADDPAIR(kSecAttrApplicationLabel, pubKeyDigest);
@@ -158,13 +183,13 @@ static CFDictionaryRef SecKeyGenerateAttributeDictionaryFor(SecKeyRef key,
        DICT_ADDPAIR(kSecAttrCanUnwrap, kCFBooleanTrue);
        DICT_ADDPAIR(kSecValueData, privateBlob ? privateBlob : pubKeyBlob);
     dict = DICT_CREATE(allocator);
        DICT_ADDPAIR(kSecAttrCanUnwrap, kCFBooleanTrue);
        DICT_ADDPAIR(kSecValueData, privateBlob ? privateBlob : pubKeyBlob);
     dict = DICT_CREATE(allocator);
-
+    
 errOut:
        // @@@ Zero out key material.
        CFReleaseSafe(pubKeyDigest);
        CFReleaseSafe(pubKeyBlob);
        CFReleaseSafe(sizeInBits);
 errOut:
        // @@@ Zero out key material.
        CFReleaseSafe(pubKeyDigest);
        CFReleaseSafe(pubKeyBlob);
        CFReleaseSafe(sizeInBits);
-
+    
        return dict;
 }
 
        return dict;
 }
 
@@ -183,9 +208,13 @@ CFDictionaryRef SecKeyGeneratePublicAttributeDictionary(SecKeyRef key, CFTypeRef
 /*
  */
 
 /*
  */
 
-static CFStringRef SecKeyDescribe(CFTypeRef cf) {
+static CFStringRef SecKeyCopyDescription(CFTypeRef cf) {
     SecKeyRef key = (SecKeyRef)cf;
     SecKeyRef key = (SecKeyRef)cf;
-    return CFStringCreateWithFormat(kCFAllocatorDefault,NULL,CFSTR("<SecKeyRef: %p>"), key);
+    
+    if(key->key_class->describe)
+        return key->key_class->describe(key);
+    else
+        return CFStringCreateWithFormat(kCFAllocatorDefault,NULL,CFSTR("<SecKeyRef: %p>"), key); 
 }
 
 static void SecKeyDestroy(CFTypeRef cf) {
 }
 
 static void SecKeyDestroy(CFTypeRef cf) {
@@ -194,7 +223,8 @@ static void SecKeyDestroy(CFTypeRef cf) {
         key->key_class->destroy(key);
 }
 
         key->key_class->destroy(key);
 }
 
-static Boolean SecKeyEqual(CFTypeRef cf1, CFTypeRef cf2) {
+static Boolean SecKeyEqual(CFTypeRef cf1, CFTypeRef cf2)
+{
     SecKeyRef key1 = (SecKeyRef)cf1;
     SecKeyRef key2 = (SecKeyRef)cf2;
     if (key1 == key2)
     SecKeyRef key1 = (SecKeyRef)cf1;
     SecKeyRef key2 = (SecKeyRef)cf2;
     if (key1 == key2)
@@ -203,7 +233,7 @@ static Boolean SecKeyEqual(CFTypeRef cf1, CFTypeRef cf2) {
         return false;
     if (key1->key_class->extraBytes)
         return !memcmp(key1->key, key2->key, key1->key_class->extraBytes);
         return false;
     if (key1->key_class->extraBytes)
         return !memcmp(key1->key, key2->key, key1->key_class->extraBytes);
-
+    
     /* TODO: Won't work when we get reference keys. */
     CFDictionaryRef d1, d2;
     d1 = SecKeyCopyAttributeDictionary(key1);
     /* TODO: Won't work when we get reference keys. */
     CFDictionaryRef d1, d2;
     d1 = SecKeyCopyAttributeDictionary(key1);
@@ -224,9 +254,9 @@ static void SecKeyRegisterClass(void) {
                SecKeyEqual,                                                                            /* equal */
                NULL,                                                                                           /* hash */
                NULL,                                                                                           /* copyFormattingDesc */
                SecKeyEqual,                                                                            /* equal */
                NULL,                                                                                           /* hash */
                NULL,                                                                                           /* copyFormattingDesc */
-               SecKeyDescribe                                      /* copyDebugDesc */
+               SecKeyCopyDescription                               /* copyDebugDesc */
        };
        };
-
+    
     kSecKeyTypeID = _CFRuntimeRegisterClass(&kSecKeyClass);
     register_algs();
 }
     kSecKeyTypeID = _CFRuntimeRegisterClass(&kSecKeyClass);
     register_algs();
 }
@@ -246,7 +276,7 @@ static bool getBoolForKey(CFDictionaryRef dict, CFStringRef key, bool default_va
                        secwarning("Value %@ for key %@ is not bool", value, key);
                }
        }
                        secwarning("Value %@ for key %@ is not bool", value, key);
                }
        }
-
+    
        return default_value;
 }
 
        return default_value;
 }
 
@@ -267,7 +297,7 @@ static CFMutableDictionaryRef merge_params(CFDictionaryRef dict,
                                            CFStringRef key) {
        CFDictionaryRef subdict = CFDictionaryGetValue(dict, key);
        CFMutableDictionaryRef result;
                                            CFStringRef key) {
        CFDictionaryRef subdict = CFDictionaryGetValue(dict, key);
        CFMutableDictionaryRef result;
-
+    
        if (subdict) {
                result = CFDictionaryCreateMutableCopy(NULL, 0, subdict);
                /* Add everything in dict not already in result to result. */
        if (subdict) {
                result = CFDictionaryCreateMutableCopy(NULL, 0, subdict);
                /* Add everything in dict not already in result to result. */
@@ -275,13 +305,13 @@ static CFMutableDictionaryRef merge_params(CFDictionaryRef dict,
        } else {
                result = CFDictionaryCreateMutableCopy(NULL, 0, dict);
        }
        } else {
                result = CFDictionaryCreateMutableCopy(NULL, 0, dict);
        }
-
+    
        /* Remove values that only belong in the top level dict. */
        CFDictionaryRemoveValue(result, kSecPublicKeyAttrs);
        CFDictionaryRemoveValue(result, kSecPrivateKeyAttrs);
        CFDictionaryRemoveValue(result, kSecAttrKeyType);
        CFDictionaryRemoveValue(result, kSecAttrKeySizeInBits);
        /* Remove values that only belong in the top level dict. */
        CFDictionaryRemoveValue(result, kSecPublicKeyAttrs);
        CFDictionaryRemoveValue(result, kSecPrivateKeyAttrs);
        CFDictionaryRemoveValue(result, kSecAttrKeyType);
        CFDictionaryRemoveValue(result, kSecAttrKeySizeInBits);
-
+    
        return result;
 }
 
        return result;
 }
 
@@ -292,27 +322,27 @@ OSStatus SecKeyGeneratePair(CFDictionaryRef parameters,
     SecKeyRef privKey = NULL;
        SecKeyRef pubKey = NULL;
     CFMutableDictionaryRef pubParams = merge_params(parameters, kSecPublicKeyAttrs),
     SecKeyRef privKey = NULL;
        SecKeyRef pubKey = NULL;
     CFMutableDictionaryRef pubParams = merge_params(parameters, kSecPublicKeyAttrs),
-                           privParams = merge_params(parameters, kSecPrivateKeyAttrs);
+    privParams = merge_params(parameters, kSecPrivateKeyAttrs);
        CFStringRef ktype = CFDictionaryGetValue(parameters, kSecAttrKeyType);
        CFStringRef ktype = CFDictionaryGetValue(parameters, kSecAttrKeyType);
-
+    
     require(ktype, errOut);
     require(ktype, errOut);
-
+    
     if (CFEqual(ktype, kSecAttrKeyTypeEC)) {
         result = SecECKeyGeneratePair(parameters, &pubKey, &privKey);
     } else if (CFEqual(ktype, kSecAttrKeyTypeRSA)) {
         result = SecRSAKeyGeneratePair(parameters, &pubKey, &privKey);
     }
     if (CFEqual(ktype, kSecAttrKeyTypeEC)) {
         result = SecECKeyGeneratePair(parameters, &pubKey, &privKey);
     } else if (CFEqual(ktype, kSecAttrKeyTypeRSA)) {
         result = SecRSAKeyGeneratePair(parameters, &pubKey, &privKey);
     }
-
+    
     require_noerr(result, errOut);
     require_noerr(result, errOut);
-
+    
     /* Store the keys in the keychain if they are marked as permanent. */
     if (getBoolForKey(pubParams, kSecAttrIsPermanent, false)) {
     /* Store the keys in the keychain if they are marked as permanent. */
     if (getBoolForKey(pubParams, kSecAttrIsPermanent, false)) {
-        require_noerr(result = add_ref(pubKey, pubParams), errOut);
+        require_noerr_quiet(result = add_ref(pubKey, pubParams), errOut);
     }
     if (getBoolForKey(privParams, kSecAttrIsPermanent, false)) {
     }
     if (getBoolForKey(privParams, kSecAttrIsPermanent, false)) {
-        require_noerr(result = add_ref(privKey, privParams), errOut);
+        require_noerr_quiet(result = add_ref(privKey, privParams), errOut);
     }
     }
-
+    
     if (publicKey) {
         *publicKey = pubKey;
         pubKey = NULL;
     if (publicKey) {
         *publicKey = pubKey;
         pubKey = NULL;
@@ -321,24 +351,78 @@ OSStatus SecKeyGeneratePair(CFDictionaryRef parameters,
         *privateKey = privKey;
         privKey = NULL;
     }
         *privateKey = privKey;
         privKey = NULL;
     }
-
+    
 errOut:
        CFReleaseSafe(pubParams);
        CFReleaseSafe(privParams);
     CFReleaseSafe(pubKey);
     CFReleaseSafe(privKey);
 errOut:
        CFReleaseSafe(pubParams);
        CFReleaseSafe(privParams);
     CFReleaseSafe(pubKey);
     CFReleaseSafe(privKey);
+    
+    return result;
+}
 
 
+SecKeyRef SecKeyCreatePublicFromPrivate(SecKeyRef privateKey) {
+    CFDataRef serializedPublic = NULL;
+    SecKeyRef result = NULL;
+    
+    require_noerr_quiet(SecKeyCopyPublicBytes(privateKey, &serializedPublic), fail);
+    require_quiet(serializedPublic, fail);
+    
+    result = SecKeyCreateFromPublicData(kCFAllocatorDefault, SecKeyGetAlgorithmID(privateKey), serializedPublic);
+    
+fail:
+    CFReleaseSafe(serializedPublic);
+    
     return result;
 }
 
     return result;
 }
 
+static CFDictionaryRef CreatePrivateKeyMatchingQuery(SecKeyRef publicKey, bool returnPersistentRef)
+{
+    CFDataRef public_key_hash = SecKeyCopyPublicKeyHash(publicKey);
+    
+    CFDictionaryRef query = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
+                                                         kSecClass,                 kSecClassKey,
+                                                         kSecAttrKeyClass,          kSecAttrKeyClassPrivate,
+                                                         kSecAttrSynchronizable,    kSecAttrSynchronizableAny,
+                                                         kSecAttrApplicationLabel,  public_key_hash,
+                                                         kSecReturnPersistentRef,   kCFBooleanTrue,
+                                                         NULL);
+    CFReleaseNull(public_key_hash);
+    
+    return query;
+}
+
+CFDataRef SecKeyCreatePersistentRefToMatchingPrivateKey(SecKeyRef publicKey, CFErrorRef *error) {
+    CFTypeRef persistentRef = NULL;
+    CFDictionaryRef query = CreatePrivateKeyMatchingQuery(publicKey, true);
+
+    require_quiet(SecError(SecItemCopyMatching(query, &persistentRef),error ,
+                           CFSTR("Error finding persistent ref to key from public: %@"), publicKey), fail);
+fail:
+    CFReleaseNull(query);
+    return (CFDataRef)persistentRef;
+}
+
+SecKeyRef SecKeyCopyMatchingPrivateKey(SecKeyRef publicKey, CFErrorRef *error) {
+    CFTypeRef private_key = NULL;
+    
+    CFDictionaryRef query = CreatePrivateKeyMatchingQuery(publicKey, false);    
+    
+    require_quiet(SecError(SecItemCopyMatching(query, &private_key), error,
+                           CFSTR("Error finding private key from public: %@"), publicKey), fail);
+fail:
+    CFReleaseNull(query);
+    return (SecKeyRef)private_key;
+}
+
 SecKeyRef SecKeyCreatePublicFromDER(CFAllocatorRef allocator,
 SecKeyRef SecKeyCreatePublicFromDER(CFAllocatorRef allocator,
-    const SecAsn1Oid *oid, const SecAsn1Item *params,
-    const SecAsn1Item *keyData) {
+                                    const SecAsn1Oid *oid, const SecAsn1Item *params,
+                                    const SecAsn1Item *keyData) {
     SecKeyRef publicKey = NULL;
        if (SecAsn1OidCompare(oid, &CSSMOID_RSA)) {
         /* pkcs1 1 */
                publicKey = SecKeyCreateRSAPublicKey(kCFAllocatorDefault,
     SecKeyRef publicKey = NULL;
        if (SecAsn1OidCompare(oid, &CSSMOID_RSA)) {
         /* pkcs1 1 */
                publicKey = SecKeyCreateRSAPublicKey(kCFAllocatorDefault,
-                       keyData->Data, keyData->Length, kSecKeyEncodingPkcs1);
+                                             keyData->Data, keyData->Length, kSecKeyEncodingPkcs1);
        } else if (SecAsn1OidCompare(oid, &CSSMOID_ecPublicKey)) {
         SecDERKey derKey = {
             .oid = oid->Data,
        } else if (SecAsn1OidCompare(oid, &CSSMOID_ecPublicKey)) {
         SecDERKey derKey = {
             .oid = oid->Data,
@@ -351,22 +435,22 @@ SecKeyRef SecKeyCreatePublicFromDER(CFAllocatorRef allocator,
             derKey.parametersLength = params->Length;
         }
                publicKey = SecKeyCreateECPublicKey(kCFAllocatorDefault,
             derKey.parametersLength = params->Length;
         }
                publicKey = SecKeyCreateECPublicKey(kCFAllocatorDefault,
-                       (const uint8_t *)&derKey, sizeof(derKey), kSecDERKeyEncoding);
+                                            (const uint8_t *)&derKey, sizeof(derKey), kSecDERKeyEncoding);
     } else {
                secwarning("Unsupported algorithm oid");
        }
     } else {
                secwarning("Unsupported algorithm oid");
        }
-
+    
     return publicKey;
 }
 
 SecKeyRef SecKeyCreate(CFAllocatorRef allocator,
     return publicKey;
 }
 
 SecKeyRef SecKeyCreate(CFAllocatorRef allocator,
-    const SecKeyDescriptor *key_class, const uint8_t *keyData,
-       CFIndex keyDataLength, SecKeyEncoding encoding) {
+                       const SecKeyDescriptor *key_class, const uint8_t *keyData,
+                       CFIndex keyDataLength, SecKeyEncoding encoding) {
        check(key_class);
        check(key_class);
-
+    
     size_t size = sizeof(struct __SecKey) + key_class->extraBytes;
     SecKeyRef result = (SecKeyRef)_CFRuntimeCreateInstance(allocator,
     size_t size = sizeof(struct __SecKey) + key_class->extraBytes;
     SecKeyRef result = (SecKeyRef)_CFRuntimeCreateInstance(allocator,
-        SecKeyGetTypeID(), size - sizeof(CFRuntimeBase), NULL);
+                                                           SecKeyGetTypeID(), size - sizeof(CFRuntimeBase), NULL);
        if (result) {
                memset((char*)result + sizeof(result->_base), 0, size - sizeof(result->_base));
         result->key_class = key_class;
        if (result) {
                memset((char*)result + sizeof(result->_base), 0, size - sizeof(result->_base));
         result->key_class = key_class;
@@ -378,7 +462,7 @@ SecKeyRef SecKeyCreate(CFAllocatorRef allocator,
                        OSStatus status;
                        status = key_class->init(result, keyData, keyDataLength, encoding);
                        if (status) {
                        OSStatus status;
                        status = key_class->init(result, keyData, keyDataLength, encoding);
                        if (status) {
-                               secwarning("init %s key: %d", key_class->name, status);
+                               secwarning("init %s key: %" PRIdOSStatus, key_class->name, status);
                                CFRelease(result);
                                result = NULL;
                        }
                                CFRelease(result);
                                result = NULL;
                        }
@@ -393,147 +477,145 @@ enum {
 };
 
 static OSStatus SecKeyDigestInfoSignVerify(
 };
 
 static OSStatus SecKeyDigestInfoSignVerify(
-    SecKeyRef           key,            /* Private key */
-       SecPadding          padding,            /* kSecPaddingPKCS1@@@ */
-       const uint8_t       *dataToSign,        /* signature over this data */
-       size_t              dataToSignLen,      /* length of dataToSign */
-       uint8_t             *sig,                       /* signature, RETURNED */
-       size_t              *sigLen,        /* IN/OUT */
-    int mode) {
+                                           SecKeyRef           key,            /* Private key */
+                                           SecPadding          padding,                /* kSecPaddingPKCS1@@@ */
+                                           const uint8_t       *dataToSign,    /* signature over this data */
+                                           size_t              dataToSignLen,  /* length of dataToSign */
+                                           uint8_t             *sig,                   /* signature, RETURNED */
+                                           size_t              *sigLen,        /* IN/OUT */
+                                           int mode) {
     size_t digestInfoLength = DER_MAX_DIGEST_INFO_LEN;
     uint8_t digestInfo[digestInfoLength];
     const SecAsn1Oid *digestOid;
     size_t digestLen;
     size_t digestInfoLength = DER_MAX_DIGEST_INFO_LEN;
     uint8_t digestInfo[digestInfoLength];
     const SecAsn1Oid *digestOid;
     size_t digestLen;
-
+    
     switch (padding) {
 #if 0
     switch (padding) {
 #if 0
-    case kSecPaddingPKCS1MD2:
-        digestLen = CC_MD2_DIGEST_LENGTH;
-        digestOid = &CSSMOID_MD2;
-        break;
-    case kSecPaddingPKCS1MD4:
-        digestLen = CC_MD4_DIGEST_LENGTH;
-        digestOid = &CSSMOID_MD4;
-        break;
-    case kSecPaddingPKCS1MD5:
-        digestLen = CC_MD5_DIGEST_LENGTH;
-        digestOid = &CSSMOID_MD5;
-        break;
-#endif
-    case kSecPaddingPKCS1SHA1:
-        digestLen = CC_SHA1_DIGEST_LENGTH;
-        digestOid = &CSSMOID_SHA1;
-        break;
-#if 0
-    case kSecPaddingPKCS1SHA224:
-        digestLen = CC_SHA224_DIGEST_LENGTH;
-        digestOid = &CSSMOID_SHA224;
-        break;
-    case kSecPaddingPKCS1SHA256:
-        digestLen = CCSHA256_OUTPUT_SIZE;
-        digestOid = &CSSMOID_SHA256;
-        break;
-    case kSecPaddingPKCS1SHA384:
-        digestLen = CC_SHA384_DIGEST_LENGTH;
-        digestOid = &CSSMOID_SHA384;
-        break;
-    case kSecPaddingPKCS1SHA512:
-        digestLen = CC_SHA512_DIGEST_LENGTH;
-        digestOid = &CSSMOID_SHA512;
-        break;
+        case kSecPaddingPKCS1MD2:
+            digestLen = CC_MD2_DIGEST_LENGTH;
+            digestOid = &CSSMOID_MD2;
+            break;
+        case kSecPaddingPKCS1MD4:
+            digestLen = CC_MD4_DIGEST_LENGTH;
+            digestOid = &CSSMOID_MD4;
+            break;
+        case kSecPaddingPKCS1MD5:
+            digestLen = CC_MD5_DIGEST_LENGTH;
+            digestOid = &CSSMOID_MD5;
+            break;
 #endif
 #endif
-    default:
-        return errSecUnsupportedPadding;
+        case kSecPaddingPKCS1SHA1:
+            digestLen = CC_SHA1_DIGEST_LENGTH;
+            digestOid = &CSSMOID_SHA1;
+            break;
+        case kSecPaddingPKCS1SHA224:
+            digestLen = CC_SHA224_DIGEST_LENGTH;
+            digestOid = &CSSMOID_SHA224;
+            break;
+        case kSecPaddingPKCS1SHA256:
+            digestLen = CC_SHA256_DIGEST_LENGTH;
+            digestOid = &CSSMOID_SHA256;
+            break;
+        case kSecPaddingPKCS1SHA384:
+            digestLen = CC_SHA384_DIGEST_LENGTH;
+            digestOid = &CSSMOID_SHA384;
+            break;
+        case kSecPaddingPKCS1SHA512:
+            digestLen = CC_SHA512_DIGEST_LENGTH;
+            digestOid = &CSSMOID_SHA512;
+            break;
+        default:
+            return errSecUnsupportedPadding;
     }
     }
-
+    
     if (dataToSignLen != digestLen)
         return errSecParam;
     if (dataToSignLen != digestLen)
         return errSecParam;
-
+    
     size_t offset = DEREncodeDigestInfoPrefix(digestOid, digestLen,
     size_t offset = DEREncodeDigestInfoPrefix(digestOid, digestLen,
-        digestInfo, digestInfoLength);
+                                              digestInfo, digestInfoLength);
     if (!offset)
         return errSecBufferTooSmall;
     if (!offset)
         return errSecBufferTooSmall;
-
+    
     /* Append the digest to the digestInfo prefix and adjust the length. */
     memcpy(&digestInfo[offset], dataToSign, digestLen);
     digestInfoLength = offset + digestLen;
     /* Append the digest to the digestInfo prefix and adjust the length. */
     memcpy(&digestInfo[offset], dataToSign, digestLen);
     digestInfoLength = offset + digestLen;
-
+    
     if (mode == kSecKeyDigestInfoSign) {
         return key->key_class->rawSign(key, kSecPaddingPKCS1,
     if (mode == kSecKeyDigestInfoSign) {
         return key->key_class->rawSign(key, kSecPaddingPKCS1,
-            digestInfo, digestInfoLength, sig, sigLen);
+                                       digestInfo, digestInfoLength, sig, sigLen);
     } else {
         return key->key_class->rawVerify(key, kSecPaddingPKCS1,
     } else {
         return key->key_class->rawVerify(key, kSecPaddingPKCS1,
-            digestInfo, digestInfoLength, sig, *sigLen);
+                                         digestInfo, digestInfoLength, sig, *sigLen);
     }
     }
-
-    return noErr;
+    
+    return errSecSuccess;
 }
 
 OSStatus SecKeyRawSign(
 }
 
 OSStatus SecKeyRawSign(
-    SecKeyRef           key,            /* Private key */
-       SecPadding          padding,            /* kSecPaddingNone or kSecPaddingPKCS1 */
-       const uint8_t       *dataToSign,        /* signature over this data */
-       size_t              dataToSignLen,      /* length of dataToSign */
-       uint8_t             *sig,                       /* signature, RETURNED */
-       size_t              *sigLen) {          /* IN/OUT */
+                       SecKeyRef           key,            /* Private key */
+                       SecPadding          padding,            /* kSecPaddingNone or kSecPaddingPKCS1 */
+                       const uint8_t       *dataToSign,        /* signature over this data */
+                       size_t              dataToSignLen,      /* length of dataToSign */
+                       uint8_t             *sig,                       /* signature, RETURNED */
+                       size_t              *sigLen) {          /* IN/OUT */
     if (!key->key_class->rawSign)
         return errSecUnsupportedOperation;
     if (!key->key_class->rawSign)
         return errSecUnsupportedOperation;
-
+    
     if (padding < kSecPaddingPKCS1MD2) {
         return key->key_class->rawSign(key, padding, dataToSign, dataToSignLen,
     if (padding < kSecPaddingPKCS1MD2) {
         return key->key_class->rawSign(key, padding, dataToSign, dataToSignLen,
-            sig, sigLen);
+                                       sig, sigLen);
     } else {
         return SecKeyDigestInfoSignVerify(key, padding, dataToSign, dataToSignLen,
     } else {
         return SecKeyDigestInfoSignVerify(key, padding, dataToSign, dataToSignLen,
-        sig, sigLen, kSecKeyDigestInfoSign);
+                                          sig, sigLen, kSecKeyDigestInfoSign);
     }
 }
 
 OSStatus SecKeyRawVerify(
     }
 }
 
 OSStatus SecKeyRawVerify(
-    SecKeyRef           key,            /* Public key */
-       SecPadding          padding,            /* kSecPaddingNone or kSecPaddingPKCS1 */
-       const uint8_t       *signedData,        /* signature over this data */
-       size_t              signedDataLen,      /* length of dataToSign */
-       const uint8_t       *sig,                       /* signature */
-       size_t              sigLen) {           /* length of signature */
+                         SecKeyRef           key,            /* Public key */
+                         SecPadding          padding,          /* kSecPaddingNone or kSecPaddingPKCS1 */
+                         const uint8_t       *signedData,      /* signature over this data */
+                         size_t              signedDataLen,    /* length of dataToSign */
+                         const uint8_t       *sig,                     /* signature */
+                         size_t              sigLen) {         /* length of signature */
     if (!key->key_class->rawVerify)
         return errSecUnsupportedOperation;
     if (!key->key_class->rawVerify)
         return errSecUnsupportedOperation;
-
+    
     if (padding < kSecPaddingPKCS1MD2) {
         return key->key_class->rawVerify(key, padding, signedData, signedDataLen,
     if (padding < kSecPaddingPKCS1MD2) {
         return key->key_class->rawVerify(key, padding, signedData, signedDataLen,
-            sig, sigLen);
+                                         sig, sigLen);
     } else {
         /* Casting away the constness of sig is safe since
     } else {
         /* Casting away the constness of sig is safe since
-           SecKeyDigestInfoSignVerify only modifies sig if
-           mode == kSecKeyDigestInfoSign. */
+         SecKeyDigestInfoSignVerify only modifies sig if
+         mode == kSecKeyDigestInfoSign. */
         return SecKeyDigestInfoSignVerify(key, padding,
         return SecKeyDigestInfoSignVerify(key, padding,
-            signedData, signedDataLen, (uint8_t *)sig, &sigLen,
-            kSecKeyDigestInfoVerify);
+                                          signedData, signedDataLen, (uint8_t *)sig, &sigLen,
+                                          kSecKeyDigestInfoVerify);
     }
 }
 
 OSStatus SecKeyEncrypt(
     }
 }
 
 OSStatus SecKeyEncrypt(
-    SecKeyRef           key,                /* Public key */
-       SecPadding          padding,                    /* kSecPaddingNone, kSecPaddingPKCS1, kSecPaddingOAEP */
-       const uint8_t           *plainText,
-       size_t              plainTextLen,               /* length of plainText */
-       uint8_t             *cipherText,        
-       size_t              *cipherTextLen) {   /* IN/OUT */
+                       SecKeyRef           key,                /* Public key */
+                       SecPadding          padding,                    /* kSecPaddingNone, kSecPaddingPKCS1, kSecPaddingOAEP */
+                       const uint8_t           *plainText,
+                       size_t              plainTextLen,               /* length of plainText */
+                       uint8_t             *cipherText,
+                       size_t              *cipherTextLen) {   /* IN/OUT */
     if (key->key_class->encrypt)
         return key->key_class->encrypt(key, padding, plainText, plainTextLen,
     if (key->key_class->encrypt)
         return key->key_class->encrypt(key, padding, plainText, plainTextLen,
-            cipherText, cipherTextLen);
+                                       cipherText, cipherTextLen);
     return errSecUnsupportedOperation;
 }
 
 OSStatus SecKeyDecrypt(
     return errSecUnsupportedOperation;
 }
 
 OSStatus SecKeyDecrypt(
-    SecKeyRef           key,                /* Private key */
-       SecPadding          padding,                    /* kSecPaddingNone, kSecPaddingPKCS1, kSecPaddingOAEP */
-       const uint8_t       *cipherText,
-       size_t              cipherTextLen,              /* length of cipherText */
-       uint8_t             *plainText, 
-       size_t              *plainTextLen) {    /* IN/OUT */
+                       SecKeyRef           key,                /* Private key */
+                       SecPadding          padding,                    /* kSecPaddingNone, kSecPaddingPKCS1, kSecPaddingOAEP */
+                       const uint8_t       *cipherText,
+                       size_t              cipherTextLen,              /* length of cipherText */
+                       uint8_t             *plainText,
+                       size_t              *plainTextLen) {    /* IN/OUT */
     if (key->key_class->decrypt)
         return key->key_class->decrypt(key, padding, cipherText, cipherTextLen,
     if (key->key_class->decrypt)
         return key->key_class->decrypt(key, padding, cipherText, cipherTextLen,
-            plainText, plainTextLen);
+                                       plainText, plainTextLen);
     return errSecUnsupportedOperation;
 }
 
     return errSecUnsupportedOperation;
 }
 
@@ -558,26 +640,44 @@ SecKeyRef SecKeyCreateFromAttributeDictionary(CFDictionaryRef refAttributes) {
        CFTypeRef ktype = CFDictionaryGetValue(refAttributes, kSecAttrKeyType);
        SInt32 algorithm;
        SecKeyRef ref;
        CFTypeRef ktype = CFDictionaryGetValue(refAttributes, kSecAttrKeyType);
        SInt32 algorithm;
        SecKeyRef ref;
-
+    
        /* First figure out the key type (algorithm). */
        if (CFGetTypeID(ktype) == CFNumberGetTypeID()) {
                CFNumberGetValue(ktype, kCFNumberSInt32Type, &algorithm);
        /* First figure out the key type (algorithm). */
        if (CFGetTypeID(ktype) == CFNumberGetTypeID()) {
                CFNumberGetValue(ktype, kCFNumberSInt32Type, &algorithm);
-       } else {
+       } else if (isString(ktype)) {
+        algorithm = CFStringGetIntValue(ktype);
+        CFStringRef t = CFStringCreateWithFormat(0, 0, CFSTR("%ld"), (long) algorithm);
+        if (!CFEqual(t, ktype)) {
+            secwarning("Unsupported key class: %@", ktype);
+            CFReleaseSafe(t);
+            return NULL;
+        }
+        CFReleaseSafe(t);
+    } else {
                secwarning("Unsupported key type: %@", ktype);
                return NULL;
        }
                secwarning("Unsupported key type: %@", ktype);
                return NULL;
        }
-
+    
        /* TODO: The code below won't scale well, consider moving to something
        /* TODO: The code below won't scale well, consider moving to something
-          table driven. */
+     table driven. */
        SInt32 class;
        CFTypeRef kclass = CFDictionaryGetValue(refAttributes, kSecAttrKeyClass);
        if (CFGetTypeID(kclass) == CFNumberGetTypeID()) {
                CFNumberGetValue(kclass, kCFNumberSInt32Type, &class);
        SInt32 class;
        CFTypeRef kclass = CFDictionaryGetValue(refAttributes, kSecAttrKeyClass);
        if (CFGetTypeID(kclass) == CFNumberGetTypeID()) {
                CFNumberGetValue(kclass, kCFNumberSInt32Type, &class);
-       } else {
+       } else if (isString(kclass)) {
+        class = CFStringGetIntValue(kclass);
+        CFStringRef t = CFStringCreateWithFormat(0, 0, CFSTR("%ld"), (long) class);
+        if (!CFEqual(t, kclass)) {
+            CFReleaseSafe(t);
+            secwarning("Unsupported key class: %@", kclass);
+            return NULL;
+        }
+        CFReleaseSafe(t);
+    } else {
                secwarning("Unsupported key class: %@", kclass);
                return NULL;
        }
                secwarning("Unsupported key class: %@", kclass);
                return NULL;
        }
-
+    
     switch (class) {
         case 0: // kSecAttrKeyClassPublic
             switch (algorithm) {
     switch (class) {
         case 0: // kSecAttrKeyClassPublic
             switch (algorithm) {
@@ -587,6 +687,7 @@ SecKeyRef SecKeyCreateFromAttributeDictionary(CFDictionaryRef refAttributes) {
                                                    kSecKeyEncodingBytes);
                     break;
                 case 43: // kSecAlgorithmECDSA
                                                    kSecKeyEncodingBytes);
                     break;
                 case 43: // kSecAlgorithmECDSA
+                case 73: // kSecAlgorithmEC
                     ref = SecKeyCreateECPublicKey(allocator,
                                                   CFDataGetBytePtr(data), CFDataGetLength(data),
                                                   kSecKeyEncodingBytes);
                     ref = SecKeyCreateECPublicKey(allocator,
                                                   CFDataGetBytePtr(data), CFDataGetLength(data),
                                                   kSecKeyEncodingBytes);
@@ -605,6 +706,7 @@ SecKeyRef SecKeyCreateFromAttributeDictionary(CFDictionaryRef refAttributes) {
                                                     kSecKeyEncodingBytes);
                     break;
                 case 43: // kSecAlgorithmECDSA
                                                     kSecKeyEncodingBytes);
                     break;
                 case 43: // kSecAlgorithmECDSA
+                case 73: // kSecAlgorithmEC
                     ref = SecKeyCreateECPrivateKey(allocator,
                                                    CFDataGetBytePtr(data), CFDataGetLength(data),
                                                    kSecKeyEncodingBytes);
                     ref = SecKeyCreateECPrivateKey(allocator,
                                                    CFDataGetBytePtr(data), CFDataGetLength(data),
                                                    kSecKeyEncodingBytes);
@@ -623,152 +725,152 @@ SecKeyRef SecKeyCreateFromAttributeDictionary(CFDictionaryRef refAttributes) {
             secwarning("Unsupported key class: %@", kclass);
             ref = NULL;
     }
             secwarning("Unsupported key class: %@", kclass);
             ref = NULL;
     }
-
+    
        return ref;
 }
 
 /* TODO: This function should ensure that this keys algorithm matches the
        return ref;
 }
 
 /* TODO: This function should ensure that this keys algorithm matches the
  signature algorithm. */
+ signature algorithm. */
 static OSStatus SecKeyGetDigestInfo(SecKeyRef this, const SecAsn1AlgId *algId,
 static OSStatus SecKeyGetDigestInfo(SecKeyRef this, const SecAsn1AlgId *algId,
-    const uint8_t *data, size_t dataLen, bool digestData,
-    uint8_t *digestInfo, size_t *digestInfoLen /* IN/OUT */) {
+                                    const uint8_t *data, size_t dataLen, bool digestData,
+                                    uint8_t *digestInfo, size_t *digestInfoLen /* IN/OUT */) {
     unsigned char *(*digestFcn)(const void *, CC_LONG, unsigned char *);
     CFIndex keyAlgID = kSecNullAlgorithmID;
     const SecAsn1Oid *digestOid;
     size_t digestLen;
     size_t offset = 0;
     unsigned char *(*digestFcn)(const void *, CC_LONG, unsigned char *);
     CFIndex keyAlgID = kSecNullAlgorithmID;
     const SecAsn1Oid *digestOid;
     size_t digestLen;
     size_t offset = 0;
-
+    
     /* Since these oids all have the same prefix, use switch. */
     if ((algId->algorithm.Length == CSSMOID_RSA.Length) &&
         !memcmp(algId->algorithm.Data, CSSMOID_RSA.Data,
     /* Since these oids all have the same prefix, use switch. */
     if ((algId->algorithm.Length == CSSMOID_RSA.Length) &&
         !memcmp(algId->algorithm.Data, CSSMOID_RSA.Data,
-            algId->algorithm.Length - 1)) {
-        keyAlgID = kSecRSAAlgorithmID;
-        switch (algId->algorithm.Data[algId->algorithm.Length - 1]) {
+                algId->algorithm.Length - 1)) {
+            keyAlgID = kSecRSAAlgorithmID;
+            switch (algId->algorithm.Data[algId->algorithm.Length - 1]) {
 #if 0
 #if 0
-        case 2: /* oidMD2WithRSA */
-            digestFcn = CC_MD2;
-            digestLen = CC_MD2_DIGEST_LENGTH;
-            digestOid = &CSSMOID_MD2;
-            break;
-        case 3: /* oidMD4WithRSA */
-            digestFcn = CC_MD4;
-            digestLen = CC_MD4_DIGEST_LENGTH;
-            digestOid = &CSSMOID_MD4;
-            break;
-        case 4: /* oidMD5WithRSA */
-            digestFcn = CC_MD5;
-            digestLen = CC_MD5_DIGEST_LENGTH;
-            digestOid = &CSSMOID_MD5;
-            break;
+                case 2: /* oidMD2WithRSA */
+                    digestFcn = CC_MD2;
+                    digestLen = CC_MD2_DIGEST_LENGTH;
+                    digestOid = &CSSMOID_MD2;
+                    break;
+                case 3: /* oidMD4WithRSA */
+                    digestFcn = CC_MD4;
+                    digestLen = CC_MD4_DIGEST_LENGTH;
+                    digestOid = &CSSMOID_MD4;
+                    break;
+                case 4: /* oidMD5WithRSA */
+                    digestFcn = CC_MD5;
+                    digestLen = CC_MD5_DIGEST_LENGTH;
+                    digestOid = &CSSMOID_MD5;
+                    break;
 #endif /* 0 */
 #endif /* 0 */
-        case 5: /* oidSHA1WithRSA */
-            digestFcn = CC_SHA1;
-            digestLen = CC_SHA1_DIGEST_LENGTH;
-            digestOid = &CSSMOID_SHA1;
-            break;
-        case 11: /* oidSHA256WithRSA */
-            digestFcn = CC_SHA256;
-            digestLen = CC_SHA256_DIGEST_LENGTH;
-            digestOid = &CSSMOID_SHA256;
-            break;
-        case 12: /* oidSHA384WithRSA */
-            /* pkcs1 12 */
-            digestFcn = CC_SHA384;
-            digestLen = CC_SHA384_DIGEST_LENGTH;
-            digestOid = &CSSMOID_SHA384;
-            break;
-        case 13: /* oidSHA512WithRSA */
-            digestFcn = CC_SHA512;
-            digestLen = CC_SHA512_DIGEST_LENGTH;
-            digestOid = &CSSMOID_SHA512;
-            break;
-        case 14: /* oidSHA224WithRSA */
-            digestFcn = CC_SHA224;
-            digestLen = CC_SHA224_DIGEST_LENGTH;
-            digestOid = &CSSMOID_SHA224;
-            break;
-        default:
-            secdebug("key", "unsupported rsa signature algorithm");
-            return errSecUnsupportedAlgorithm;
-        }
-    } else if ((algId->algorithm.Length == CSSMOID_ECDSA_WithSHA224.Length) &&
-        !memcmp(algId->algorithm.Data, CSSMOID_ECDSA_WithSHA224.Data,
-            algId->algorithm.Length - 1)) {
-        keyAlgID = kSecECDSAAlgorithmID;
-        switch (algId->algorithm.Data[algId->algorithm.Length - 1]) {
-        case 1: /* oidSHA224WithECDSA */
-            digestFcn = CC_SHA224;
-            digestLen = CC_SHA224_DIGEST_LENGTH;
-            break;
-        case 2: /* oidSHA256WithECDSA */
-            digestFcn = CC_SHA256;
-            digestLen = CC_SHA256_DIGEST_LENGTH;
-            break;
-        case 3: /* oidSHA384WithECDSA */
-            /* pkcs1 12 */
-            digestFcn = CC_SHA384;
-            digestLen = CC_SHA384_DIGEST_LENGTH;
-            break;
-        case 4: /* oidSHA512WithECDSA */
-            digestFcn = CC_SHA512;
-            digestLen = CC_SHA512_DIGEST_LENGTH;
-            break;
-        default:
-            secdebug("key", "unsupported ecdsa signature algorithm");
-            return errSecUnsupportedAlgorithm;
-        }
-    } else if (SecAsn1OidCompare(&algId->algorithm, &CSSMOID_ECDSA_WithSHA1)) {
-        keyAlgID = kSecECDSAAlgorithmID;
-        digestFcn = CC_SHA1;
-        digestLen = CC_SHA1_DIGEST_LENGTH;
-    } else if (SecAsn1OidCompare(&algId->algorithm, &CSSMOID_SHA1)) {
-        digestFcn = CC_SHA1;
-        digestLen = CC_SHA1_DIGEST_LENGTH;
-        digestOid = &CSSMOID_SHA1;
-    } else if ((algId->algorithm.Length == CSSMOID_SHA224.Length) &&
-        !memcmp(algId->algorithm.Data, CSSMOID_SHA224.Data, algId->algorithm.Length - 1))
-    {
-        switch (algId->algorithm.Data[algId->algorithm.Length - 1]) {
-            case 4: /* OID_SHA224 */
-                digestFcn = CC_SHA224;
-                digestLen = CC_SHA224_DIGEST_LENGTH;
-                digestOid = &CSSMOID_SHA224;
-                break;
-            case 1: /* OID_SHA256 */
-                digestFcn = CC_SHA256;
-                digestLen = CC_SHA256_DIGEST_LENGTH;
-                digestOid = &CSSMOID_SHA256;
-                break;
-            case 2: /* OID_SHA384 */
-                /* pkcs1 12 */
-                digestFcn = CC_SHA384;
-                digestLen = CC_SHA384_DIGEST_LENGTH;
-                digestOid = &CSSMOID_SHA384;
-                break;
-            case 3: /* OID_SHA512 */
-                digestFcn = CC_SHA512;
-                digestLen = CC_SHA512_DIGEST_LENGTH;
-                digestOid = &CSSMOID_SHA512;
-                break;
-            default:
-                secdebug("key", "unsupported sha-2 signature algorithm");
-                return errSecUnsupportedAlgorithm;
-        }
-    } else if (SecAsn1OidCompare(&algId->algorithm, &CSSMOID_MD5)) {
-        digestFcn = CC_MD5;
-        digestLen = CC_MD5_DIGEST_LENGTH;
-        digestOid = &CSSMOID_MD5;
-    } else {
-        secdebug("key", "unsupported digesting algorithm");
-        return errSecUnsupportedAlgorithm;
-    }
-
+                case 5: /* oidSHA1WithRSA */
+                    digestFcn = CC_SHA1;
+                    digestLen = CC_SHA1_DIGEST_LENGTH;
+                    digestOid = &CSSMOID_SHA1;
+                    break;
+                case 11: /* oidSHA256WithRSA */
+                    digestFcn = CC_SHA256;
+                    digestLen = CC_SHA256_DIGEST_LENGTH;
+                    digestOid = &CSSMOID_SHA256;
+                    break;
+                case 12: /* oidSHA384WithRSA */
+                    /* pkcs1 12 */
+                    digestFcn = CC_SHA384;
+                    digestLen = CC_SHA384_DIGEST_LENGTH;
+                    digestOid = &CSSMOID_SHA384;
+                    break;
+                case 13: /* oidSHA512WithRSA */
+                    digestFcn = CC_SHA512;
+                    digestLen = CC_SHA512_DIGEST_LENGTH;
+                    digestOid = &CSSMOID_SHA512;
+                    break;
+                case 14: /* oidSHA224WithRSA */
+                    digestFcn = CC_SHA224;
+                    digestLen = CC_SHA224_DIGEST_LENGTH;
+                    digestOid = &CSSMOID_SHA224;
+                    break;
+                default:
+                    secdebug("key", "unsupported rsa signature algorithm");
+                    return errSecUnsupportedAlgorithm;
+            }
+        } else if ((algId->algorithm.Length == CSSMOID_ECDSA_WithSHA224.Length) &&
+                   !memcmp(algId->algorithm.Data, CSSMOID_ECDSA_WithSHA224.Data,
+                           algId->algorithm.Length - 1)) {
+                       keyAlgID = kSecECDSAAlgorithmID;
+                       switch (algId->algorithm.Data[algId->algorithm.Length - 1]) {
+                           case 1: /* oidSHA224WithECDSA */
+                               digestFcn = CC_SHA224;
+                               digestLen = CC_SHA224_DIGEST_LENGTH;
+                               break;
+                           case 2: /* oidSHA256WithECDSA */
+                               digestFcn = CC_SHA256;
+                               digestLen = CC_SHA256_DIGEST_LENGTH;
+                               break;
+                           case 3: /* oidSHA384WithECDSA */
+                               /* pkcs1 12 */
+                               digestFcn = CC_SHA384;
+                               digestLen = CC_SHA384_DIGEST_LENGTH;
+                               break;
+                           case 4: /* oidSHA512WithECDSA */
+                               digestFcn = CC_SHA512;
+                               digestLen = CC_SHA512_DIGEST_LENGTH;
+                               break;
+                           default:
+                               secdebug("key", "unsupported ecdsa signature algorithm");
+                               return errSecUnsupportedAlgorithm;
+                       }
+                   } else if (SecAsn1OidCompare(&algId->algorithm, &CSSMOID_ECDSA_WithSHA1)) {
+                       keyAlgID = kSecECDSAAlgorithmID;
+                       digestFcn = CC_SHA1;
+                       digestLen = CC_SHA1_DIGEST_LENGTH;
+                   } else if (SecAsn1OidCompare(&algId->algorithm, &CSSMOID_SHA1)) {
+                       digestFcn = CC_SHA1;
+                       digestLen = CC_SHA1_DIGEST_LENGTH;
+                       digestOid = &CSSMOID_SHA1;
+                   } else if ((algId->algorithm.Length == CSSMOID_SHA224.Length) &&
+                              !memcmp(algId->algorithm.Data, CSSMOID_SHA224.Data, algId->algorithm.Length - 1))
+                   {
+                       switch (algId->algorithm.Data[algId->algorithm.Length - 1]) {
+                           case 4: /* OID_SHA224 */
+                               digestFcn = CC_SHA224;
+                               digestLen = CC_SHA224_DIGEST_LENGTH;
+                               digestOid = &CSSMOID_SHA224;
+                               break;
+                           case 1: /* OID_SHA256 */
+                               digestFcn = CC_SHA256;
+                               digestLen = CC_SHA256_DIGEST_LENGTH;
+                               digestOid = &CSSMOID_SHA256;
+                               break;
+                           case 2: /* OID_SHA384 */
+                               /* pkcs1 12 */
+                               digestFcn = CC_SHA384;
+                               digestLen = CC_SHA384_DIGEST_LENGTH;
+                               digestOid = &CSSMOID_SHA384;
+                               break;
+                           case 3: /* OID_SHA512 */
+                               digestFcn = CC_SHA512;
+                               digestLen = CC_SHA512_DIGEST_LENGTH;
+                               digestOid = &CSSMOID_SHA512;
+                               break;
+                           default:
+                               secdebug("key", "unsupported sha-2 signature algorithm");
+                               return errSecUnsupportedAlgorithm;
+                       }
+                   } else if (SecAsn1OidCompare(&algId->algorithm, &CSSMOID_MD5)) {
+                       digestFcn = CC_MD5;
+                       digestLen = CC_MD5_DIGEST_LENGTH;
+                       digestOid = &CSSMOID_MD5;
+                   } else {
+                       secdebug("key", "unsupported digesting algorithm");
+                       return errSecUnsupportedAlgorithm;
+                   }
+    
     /* check key is appropriate for signature (superfluous for digest only oid) */
     if (keyAlgID == kSecNullAlgorithmID)
         keyAlgID = SecKeyGetAlgorithmID(this);
     else if (keyAlgID != SecKeyGetAlgorithmID(this))
         return errSecUnsupportedAlgorithm;
     /* check key is appropriate for signature (superfluous for digest only oid) */
     if (keyAlgID == kSecNullAlgorithmID)
         keyAlgID = SecKeyGetAlgorithmID(this);
     else if (keyAlgID != SecKeyGetAlgorithmID(this))
         return errSecUnsupportedAlgorithm;
-
+    
     switch(keyAlgID) {
         case kSecRSAAlgorithmID:
             offset = DEREncodeDigestInfoPrefix(digestOid, digestLen,
     switch(keyAlgID) {
         case kSecRSAAlgorithmID:
             offset = DEREncodeDigestInfoPrefix(digestOid, digestLen,
@@ -786,71 +888,74 @@ static OSStatus SecKeyGetDigestInfo(SecKeyRef this, const SecAsn1AlgId *algId,
             secdebug("key", "unsupported signature algorithm");
             return errSecUnsupportedAlgorithm;
     }
             secdebug("key", "unsupported signature algorithm");
             return errSecUnsupportedAlgorithm;
     }
-
+    
     if (digestData) {
         if(dataLen>UINT32_MAX) /* Check for overflow with CC_LONG cast */
     if (digestData) {
         if(dataLen>UINT32_MAX) /* Check for overflow with CC_LONG cast */
-            return paramErr;
+            return errSecParam;
         digestFcn(data, (CC_LONG)dataLen, &digestInfo[offset]);
         *digestInfoLen = offset + digestLen;
     } else {
         if (dataLen != digestLen)
         digestFcn(data, (CC_LONG)dataLen, &digestInfo[offset]);
         *digestInfoLen = offset + digestLen;
     } else {
         if (dataLen != digestLen)
-            return paramErr;
+            return errSecParam;
         memcpy(&digestInfo[offset], data, dataLen);
         *digestInfoLen = offset + dataLen;
     }
         memcpy(&digestInfo[offset], data, dataLen);
         *digestInfoLen = offset + dataLen;
     }
-
-    return noErr;
+    
+    return errSecSuccess;
 }
 
 OSStatus SecKeyDigestAndVerify(
 }
 
 OSStatus SecKeyDigestAndVerify(
-    SecKeyRef           this,            /* Private key */
-       const SecAsn1AlgId  *algId,         /* algorithm oid/params */
-       const uint8_t       *dataToDigest,      /* signature over this data */
-       size_t              dataToDigestLen,/* length of dataToDigest */
-       const uint8_t       *sig,                       /* signature to verify */
-       size_t              sigLen) {           /* length of sig */
+                               SecKeyRef           this,            /* Private key */
+                               const SecAsn1AlgId  *algId,         /* algorithm oid/params */
+                               const uint8_t       *dataToDigest,      /* signature over this data */
+                               size_t              dataToDigestLen,/* length of dataToDigest */
+                               const uint8_t       *sig,                       /* signature to verify */
+                               size_t              sigLen) {           /* length of sig */
     size_t digestInfoLength = DER_MAX_DIGEST_INFO_LEN;
     uint8_t digestInfo[digestInfoLength];
     OSStatus status;
     size_t digestInfoLength = DER_MAX_DIGEST_INFO_LEN;
     uint8_t digestInfo[digestInfoLength];
     OSStatus status;
-
+    
+    if (this == NULL)
+        return errSecParam;
+    
     status = SecKeyGetDigestInfo(this, algId, dataToDigest, dataToDigestLen, true,
     status = SecKeyGetDigestInfo(this, algId, dataToDigest, dataToDigestLen, true,
-        digestInfo, &digestInfoLength);
+                                 digestInfo, &digestInfoLength);
     if (status)
         return status;
     return SecKeyRawVerify(this, kSecPaddingPKCS1,
     if (status)
         return status;
     return SecKeyRawVerify(this, kSecPaddingPKCS1,
-        digestInfo, digestInfoLength, sig, sigLen);
+                           digestInfo, digestInfoLength, sig, sigLen);
 }
 
 OSStatus SecKeyDigestAndSign(
 }
 
 OSStatus SecKeyDigestAndSign(
-    SecKeyRef           this,            /* Private key */
-       const SecAsn1AlgId  *algId,         /* algorithm oid/params */
-       const uint8_t       *dataToDigest,      /* signature over this data */
-       size_t              dataToDigestLen,/* length of dataToDigest */
-       uint8_t             *sig,                       /* signature, RETURNED */
-       size_t              *sigLen) {          /* IN/OUT */
+                             SecKeyRef           this,            /* Private key */
+                             const SecAsn1AlgId  *algId,         /* algorithm oid/params */
+                             const uint8_t       *dataToDigest,        /* signature over this data */
+                             size_t              dataToDigestLen,/* length of dataToDigest */
+                             uint8_t             *sig,                 /* signature, RETURNED */
+                             size_t              *sigLen) {            /* IN/OUT */
     size_t digestInfoLength = DER_MAX_DIGEST_INFO_LEN;
     uint8_t digestInfo[digestInfoLength];
     OSStatus status;
     size_t digestInfoLength = DER_MAX_DIGEST_INFO_LEN;
     uint8_t digestInfo[digestInfoLength];
     OSStatus status;
-
+    
     status = SecKeyGetDigestInfo(this, algId, dataToDigest, dataToDigestLen, true /* digest data */,
     status = SecKeyGetDigestInfo(this, algId, dataToDigest, dataToDigestLen, true /* digest data */,
-        digestInfo, &digestInfoLength);
+                                 digestInfo, &digestInfoLength);
     if (status)
         return status;
     return SecKeyRawSign(this, kSecPaddingPKCS1,
     if (status)
         return status;
     return SecKeyRawSign(this, kSecPaddingPKCS1,
-        digestInfo, digestInfoLength, sig, sigLen);
+                         digestInfo, digestInfoLength, sig, sigLen);
 }
 
 OSStatus SecKeyVerifyDigest(
 }
 
 OSStatus SecKeyVerifyDigest(
-                               SecKeyRef           this,            /* Private key */
-                               const SecAsn1AlgId  *algId,         /* algorithm oid/params */
-                               const uint8_t       *digestData,        /* signature over this digest */
-                               size_t              digestDataLen,/* length of dataToDigest */
-                               const uint8_t       *sig,                       /* signature to verify */
-                               size_t              sigLen) {           /* length of sig */
+                            SecKeyRef           this,            /* Private key */
+                            const SecAsn1AlgId  *algId,         /* algorithm oid/params */
+                            const uint8_t       *digestData,   /* signature over this digest */
+                            size_t              digestDataLen,/* length of dataToDigest */
+                            const uint8_t       *sig,                  /* signature to verify */
+                            size_t              sigLen) {              /* length of sig */
     size_t digestInfoLength = DER_MAX_DIGEST_INFO_LEN;
     uint8_t digestInfo[digestInfoLength];
     OSStatus status;
     size_t digestInfoLength = DER_MAX_DIGEST_INFO_LEN;
     uint8_t digestInfo[digestInfoLength];
     OSStatus status;
-
+    
     status = SecKeyGetDigestInfo(this, algId, digestData, digestDataLen, false /* data is digest */,
                                  digestInfo, &digestInfoLength);
     if (status)
     status = SecKeyGetDigestInfo(this, algId, digestData, digestDataLen, false /* data is digest */,
                                  digestInfo, &digestInfoLength);
     if (status)
@@ -860,16 +965,16 @@ OSStatus SecKeyVerifyDigest(
 }
 
 OSStatus SecKeySignDigest(
 }
 
 OSStatus SecKeySignDigest(
-                             SecKeyRef           this,            /* Private key */
-                             const SecAsn1AlgId  *algId,         /* algorithm oid/params */
-                             const uint8_t       *digestData,  /* signature over this digest */
-                             size_t              digestDataLen,/* length of digestData */
-                             uint8_t             *sig,                 /* signature, RETURNED */
-                             size_t              *sigLen) {            /* IN/OUT */
+                          SecKeyRef           this,            /* Private key */
+                          const SecAsn1AlgId  *algId,         /* algorithm oid/params */
+                          const uint8_t       *digestData,     /* signature over this digest */
+                          size_t              digestDataLen,/* length of digestData */
+                          uint8_t             *sig,                    /* signature, RETURNED */
+                          size_t              *sigLen) {               /* IN/OUT */
     size_t digestInfoLength = DER_MAX_DIGEST_INFO_LEN;
     uint8_t digestInfo[digestInfoLength];
     OSStatus status;
     size_t digestInfoLength = DER_MAX_DIGEST_INFO_LEN;
     uint8_t digestInfo[digestInfoLength];
     OSStatus status;
-
+    
     status = SecKeyGetDigestInfo(this, algId, digestData, digestDataLen, false,
                                  digestInfo, &digestInfoLength);
     if (status)
     status = SecKeyGetDigestInfo(this, algId, digestData, digestDataLen, false,
                                  digestInfo, &digestInfoLength);
     if (status)
@@ -920,27 +1025,75 @@ SecKeyRef SecKeyCreateFromPublicData(CFAllocatorRef allocator, CFIndex algorithm
 size_t SecKeyGetSize(SecKeyRef key, SecKeySize whichSize)
 {
     size_t result = SecKeyGetBlockSize(key);
 size_t SecKeyGetSize(SecKeyRef key, SecKeySize whichSize)
 {
     size_t result = SecKeyGetBlockSize(key);
-
+    
     if (kSecECDSAAlgorithmID == SecKeyGetAlgorithmID(key)) {
         switch (whichSize) {
             case kSecKeyEncryptedDataSize:
                 result = 0;
                 break;
             case kSecKeySignatureSize:
     if (kSecECDSAAlgorithmID == SecKeyGetAlgorithmID(key)) {
         switch (whichSize) {
             case kSecKeyEncryptedDataSize:
                 result = 0;
                 break;
             case kSecKeySignatureSize:
-                result = 2 * result + 6;
-                if (result >= 66)
-                    result += 2;
+                result = (result >= 66 ? 9 : 8) + 2 * result;
                 break;
             case kSecKeyKeySizeInBits:
                 if (result >= 66)
                     return 521;
         }
     }
                 break;
             case kSecKeyKeySizeInBits:
                 if (result >= 66)
                     return 521;
         }
     }
-            
+    
     if (whichSize == kSecKeyKeySizeInBits)
     if (whichSize == kSecKeyKeySizeInBits)
-            result *= 8;
-        
+        result *= 8;
+    
     return result;
     return result;
+    
+}
 
 
+OSStatus SecKeyFindWithPersistentRef(CFDataRef persistentRef, SecKeyRef* lookedUpData)
+{
+    CFDictionaryRef query = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
+                                                         kSecReturnRef,             kCFBooleanTrue,
+                                                         kSecClass,                 kSecClassKey,
+                                                         kSecValuePersistentRef,    persistentRef,
+                                                         NULL);
+    CFTypeRef foundRef = NULL;
+    OSStatus status = SecItemCopyMatching(query, &foundRef);
+    
+    if (status == errSecSuccess) {
+        if (CFGetTypeID(foundRef) == SecKeyGetTypeID()) {
+            *lookedUpData = (SecKeyRef) foundRef;
+            foundRef = NULL;
+            status = errSecSuccess;
+        } else {
+            status = errSecItemNotFound;
+        }
+    }
+    
+    CFReleaseSafe(foundRef);
+    CFReleaseSafe(query);
+    
+    return status;
 }
 
 }
 
+OSStatus SecKeyCopyPersistentRef(SecKeyRef key, CFDataRef* persistentRef)
+{
+    CFDictionaryRef query = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
+                                                         kSecReturnPersistentRef,   kCFBooleanTrue,
+                                                         kSecValueRef,              key,
+                                                         kSecAttrSynchronizable,    kSecAttrSynchronizableAny,
+                                                         NULL);
+    CFTypeRef foundRef = NULL;
+    OSStatus status = SecItemCopyMatching(query, &foundRef);
+    
+    if (status == errSecSuccess) {
+        if (CFGetTypeID(foundRef) == CFDataGetTypeID()) {
+            *persistentRef = foundRef;
+            foundRef = NULL;
+        } else {
+            status = errSecItemNotFound;
+        }
+    }
+    
+    CFReleaseSafe(foundRef);
+    CFReleaseSafe(query);
+    
+    return status;
+}
index c0d26c60dd7dd4cbde6a68956736a1f13e96b149..74c08f462b54ca5c4afefe5264e9298f1a54ddc9 100644 (file)
@@ -37,9 +37,7 @@
 #include <CoreFoundation/CFDictionary.h>
 #include <sys/types.h>
 
 #include <CoreFoundation/CFDictionary.h>
 #include <sys/types.h>
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 /* Padding Types (iPhone OS 2.0 and later only). */
 typedef uint32_t SecPadding;
 
 /* Padding Types (iPhone OS 2.0 and later only). */
 typedef uint32_t SecPadding;
@@ -63,6 +61,26 @@ enum
        hash; standard ASN.1 padding will be done, as well as PKCS1 padding
        of the underlying RSA operation. */
     kSecPaddingPKCS1SHA1 = 0x8002,
        hash; standard ASN.1 padding will be done, as well as PKCS1 padding
        of the underlying RSA operation. */
     kSecPaddingPKCS1SHA1 = 0x8002,
+
+    /* For SecKeyRawSign/SecKeyRawVerify only, data to be signed is a SHA224
+     hash; standard ASN.1 padding will be done, as well as PKCS1 padding
+     of the underlying RSA operation. */
+    kSecPaddingPKCS1SHA224 = 0x8003,
+
+    /* For SecKeyRawSign/SecKeyRawVerify only, data to be signed is a SHA256
+     hash; standard ASN.1 padding will be done, as well as PKCS1 padding
+     of the underlying RSA operation. */
+    kSecPaddingPKCS1SHA256 = 0x8004,
+
+    /* For SecKeyRawSign/SecKeyRawVerify only, data to be signed is a SHA384
+     hash; standard ASN.1 padding will be done, as well as PKCS1 padding
+     of the underlying RSA operation. */
+    kSecPaddingPKCS1SHA384 = 0x8005,
+
+    /* For SecKeyRawSign/SecKeyRawVerify only, data to be signed is a SHA512
+     hash; standard ASN.1 padding will be done, as well as PKCS1 padding
+     of the underlying RSA operation. */
+    kSecPaddingPKCS1SHA512 = 0x8006,
 };
 
 
 };
 
 
@@ -273,8 +291,6 @@ size_t SecKeyGetBlockSize(SecKeyRef key)
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0);
     
 
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0);
     
 
-#if defined(__cplusplus)
-}
-#endif
+__END_DECLS
 
 #endif /* !_SECURITY_SECKEY_H_ */
 
 #endif /* !_SECURITY_SECKEY_H_ */
index 0938a73b0d415771a92fea69e87552f29b7d2084..337f5ffbdac69ed652365fc958d2883b0f2d1875 100644 (file)
 #include <Security/SecKeyPriv.h>
 #include <corecrypto/ccrng.h>
 
 #include <Security/SecKeyPriv.h>
 #include <corecrypto/ccrng.h>
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 struct ccrng_state *ccrng_seckey;
 
 
 struct ccrng_state *ccrng_seckey;
 
-#if defined(__cplusplus)
-}
-#endif
+__END_DECLS
 
 #endif /* !_SECURITY_SECKEYINTERNAL_H_ */
 
 #endif /* !_SECURITY_SECKEYINTERNAL_H_ */
index 7726b958d7f47f05e20a79908ba1f2b9a34a4530..02ffebfea5ee856cf9107b81f74b143593d45b02 100644 (file)
 #include <Security/SecKey.h>
 #include <Security/SecAsn1Types.h>
 #include <CoreFoundation/CFRuntime.h>
 #include <Security/SecKey.h>
 #include <Security/SecAsn1Types.h>
 #include <CoreFoundation/CFRuntime.h>
-#include <CoreFoundation/CFData.h>
+#include <CoreFoundation/CoreFoundation.h>
 
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 typedef struct __SecDERKey {
        uint8_t             *oid;
 
 typedef struct __SecDERKey {
        uint8_t             *oid;
@@ -83,6 +81,10 @@ enum {
     /* Encoding came from SecKeyCopyPublicBytes for a public key,
        or internally from a private key */
     kSecKeyEncodingBytes = 7,
     /* Encoding came from SecKeyCopyPublicBytes for a public key,
        or internally from a private key */
     kSecKeyEncodingBytes = 7,
+    
+    /* Handing in a private key from corecrypto directly. */
+    kSecKeyCoreCrypto = 8,
+
 };
 
 typedef OSStatus (*SecKeyInitMethod)(SecKeyRef, const uint8_t *, CFIndex,
 };
 
 typedef OSStatus (*SecKeyInitMethod)(SecKeyRef, const uint8_t *, CFIndex,
@@ -107,7 +109,7 @@ typedef size_t (*SecKeyBlockSizeMethod)(SecKeyRef key);
 typedef CFDictionaryRef (*SecKeyCopyDictionaryMethod)(SecKeyRef key);
 typedef CFIndex (*SecKeyGetAlgorithmIDMethod)(SecKeyRef key);
 typedef OSStatus (*SecKeyCopyPublicBytesMethod)(SecKeyRef key, CFDataRef *serailziation);
 typedef CFDictionaryRef (*SecKeyCopyDictionaryMethod)(SecKeyRef key);
 typedef CFIndex (*SecKeyGetAlgorithmIDMethod)(SecKeyRef key);
 typedef OSStatus (*SecKeyCopyPublicBytesMethod)(SecKeyRef key, CFDataRef *serailziation);
-
+typedef CFStringRef (*SecKeyDescribeMethod)(SecKeyRef key);
 
 #define kSecKeyDescriptorVersion  (2)
 
 
 #define kSecKeyDescriptorVersion  (2)
 
@@ -142,6 +144,8 @@ typedef struct __SecKeyDescriptor {
     SecKeyBlockSizeMethod blockSize;
     /* Called by SecKeyCopyAttributeDictionary(), which is private. */
     SecKeyCopyDictionaryMethod copyDictionary;
     SecKeyBlockSizeMethod blockSize;
     /* Called by SecKeyCopyAttributeDictionary(), which is private. */
     SecKeyCopyDictionaryMethod copyDictionary;
+    /* Called by SecKeyDescribeMethod(). */
+    SecKeyDescribeMethod describe;
 #if kSecKeyDescriptorVersion > 0
     /* Called by SecKeyCopyAttributeDictionary(), which is private. */
     SecKeyGetAlgorithmIDMethod getAlgorithmID;
 #if kSecKeyDescriptorVersion > 0
     /* Called by SecKeyCopyAttributeDictionary(), which is private. */
     SecKeyGetAlgorithmIDMethod getAlgorithmID;
@@ -179,6 +183,11 @@ SecKeyRef SecKeyCreatePublicFromDER(CFAllocatorRef allocator,
     const SecAsn1Oid *oid1, const SecAsn1Item *params,
     const SecAsn1Item *keyData);
 
     const SecAsn1Oid *oid1, const SecAsn1Item *params,
     const SecAsn1Item *keyData);
 
+/* Create public key from private key */
+SecKeyRef SecKeyCreatePublicFromPrivate(SecKeyRef privateKey);
+SecKeyRef SecKeyCopyMatchingPrivateKey(SecKeyRef publicKey, CFErrorRef *error);
+CFDataRef SecKeyCreatePersistentRefToMatchingPrivateKey(SecKeyRef publicKey, CFErrorRef *error);
+
 /* Return an attribute dictionary used to store this item in a keychain. */
 CFDictionaryRef SecKeyCopyAttributeDictionary(SecKeyRef key);
 
 /* Return an attribute dictionary used to store this item in a keychain. */
 CFDictionaryRef SecKeyCopyAttributeDictionary(SecKeyRef key);
 
@@ -222,10 +231,11 @@ OSStatus SecKeyCopyPublicBytes(SecKeyRef key, CFDataRef* serializedPublic);
 SecKeyRef SecKeyCreateFromPublicBytes(CFAllocatorRef allocator, CFIndex algorithmID, const uint8_t *keyData, CFIndex keyDataLength);
 SecKeyRef SecKeyCreateFromPublicData(CFAllocatorRef allocator, CFIndex algorithmID, CFDataRef serialized);
 
 SecKeyRef SecKeyCreateFromPublicBytes(CFAllocatorRef allocator, CFIndex algorithmID, const uint8_t *keyData, CFIndex keyDataLength);
 SecKeyRef SecKeyCreateFromPublicData(CFAllocatorRef allocator, CFIndex algorithmID, CFDataRef serialized);
 
-
+CF_RETURNS_RETAINED
 CFDictionaryRef SecKeyGeneratePrivateAttributeDictionary(SecKeyRef key,
                                                          CFTypeRef keyType,
                                                          CFDataRef privateBlob);
 CFDictionaryRef SecKeyGeneratePrivateAttributeDictionary(SecKeyRef key,
                                                          CFTypeRef keyType,
                                                          CFDataRef privateBlob);
+CF_RETURNS_RETAINED
 CFDictionaryRef SecKeyGeneratePublicAttributeDictionary(SecKeyRef key, CFTypeRef keyType);
 
 enum {
 CFDictionaryRef SecKeyGeneratePublicAttributeDictionary(SecKeyRef key, CFTypeRef keyType);
 
 enum {
@@ -258,9 +268,28 @@ size_t SecKeyGetSize(SecKeyRef key, SecKeySize whichSize)
 __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0);
     
 
 __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0);
     
 
+/*!
+ @function SecKeyLookupPersistentRef
+ @abstract Looks up a SecKeyRef via persistent ref.
+ @param persistentRef The persistent ref data for looking up.
+ @param lookedUpData retained SecKeyRef for the found object.
+ @result Errors when using SecItemFind for the persistent ref.
+ */
+OSStatus SecKeyFindWithPersistentRef(CFDataRef persistentRef, SecKeyRef* lookedUpData)
+__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+
+/*!
+ @function SecKeyCopyPersistentRef
+ @abstract Gets a persistent reference for a key.
+ @param key Key to make a persistent ref for.
+ @param persistentRef Allocated data representing the persistent ref.
+ @result Errors when using SecItemFind for the persistent ref.
+ */
+OSStatus SecKeyCopyPersistentRef(SecKeyRef key, CFDataRef* persistentRef)
+__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
 
 
-#if defined(__cplusplus)
-}
-#endif
+
+
+__END_DECLS
 
 #endif /* !_SECURITY_SECKEYPRIV_H_ */
 
 #endif /* !_SECURITY_SECKEYPRIV_H_ */
diff --git a/sec/Security/SecOTR.h b/sec/Security/SecOTR.h
new file mode 100644 (file)
index 0000000..5937338
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ *  SecOTR.h
+ *  libsecurity_libSecOTR
+ *
+ *  Created by Mitch Adler on 2/2/11.
+ *  Copyright 2011 Apple Inc. All rights reserved.
+ *
+ */
+
+#ifndef _SECOTR_H_
+#define _SECOTR_H_
+
+/*
+ * Message Protection interfaces
+*/
+
+#include <CoreFoundation/CFBase.h>
+#include <CoreFoundation/CFData.h>
+#include <CoreFoundation/CFError.h>
+#include <Security/SecKey.h>
+
+#include <stdint.h>
+
+__BEGIN_DECLS
+
+/*!
+    @typedef 
+    @abstract   Full identity (public and private) for Message Protection
+    @discussion Abstracts what kind of crypto is going on beyond it being public/priate
+*/
+typedef struct _SecOTRFullIdentity* SecOTRFullIdentityRef;
+
+/*!
+     @typedef 
+     @abstract   Public identity for Message Protection message validation and encryption to send
+     @discussion Abstracts what kind of crypto is going on beyond it being public/priate
+ */
+typedef struct _SecOTRPublicIdentity* SecOTRPublicIdentityRef;
+
+/*
+ * Full identity functions
+ */
+SecOTRFullIdentityRef SecOTRFullIdentityCreate(CFAllocatorRef allocator, CFErrorRef *error);
+    
+SecOTRFullIdentityRef SecOTRFullIdentityCreateFromSecKeyRef(CFAllocatorRef allocator, SecKeyRef privateKey,
+                                                                CFErrorRef *error);
+SecOTRFullIdentityRef SecOTRFullIdentityCreateFromData(CFAllocatorRef allocator, CFDataRef serializedData, CFErrorRef *error);
+    
+SecOTRFullIdentityRef SecOTRFullIdentityCreateFromBytes(CFAllocatorRef allocator, const uint8_t**bytes, size_t *size, CFErrorRef *error);
+
+bool SecOTRFIPurgeFromKeychain(SecOTRFullIdentityRef thisID, CFErrorRef *error);
+
+bool SecOTRFIAppendSerialization(SecOTRFullIdentityRef fullID, CFMutableDataRef serializeInto, CFErrorRef *error);
+
+
+bool SecOTRFIPurgeAllFromKeychain(CFErrorRef *error);
+
+
+/*
+ * Public identity functions
+ */
+SecOTRPublicIdentityRef SecOTRPublicIdentityCopyFromPrivate(CFAllocatorRef allocator, SecOTRFullIdentityRef fullID, CFErrorRef *error);
+    
+SecOTRPublicIdentityRef SecOTRPublicIdentityCreateFromSecKeyRef(CFAllocatorRef allocator, SecKeyRef publicKey,
+                                                                    CFErrorRef *error);
+    
+SecOTRPublicIdentityRef SecOTRPublicIdentityCreateFromData(CFAllocatorRef allocator, CFDataRef serializedData, CFErrorRef *error);
+SecOTRPublicIdentityRef SecOTRPublicIdentityCreateFromBytes(CFAllocatorRef allocator, const uint8_t**bytes, size_t * size, CFErrorRef *error);
+
+bool SecOTRPIAppendSerialization(SecOTRPublicIdentityRef publicID, CFMutableDataRef serializeInto, CFErrorRef *error);
+
+void SecOTRAdvertiseHashes(bool advertise);
+    
+__END_DECLS
+        
+#endif
diff --git a/sec/Security/SecOTRDHKey.c b/sec/Security/SecOTRDHKey.c
new file mode 100644 (file)
index 0000000..7f6aa75
--- /dev/null
@@ -0,0 +1,309 @@
+//
+//  SecOTRDHKey.c
+//  libsecurity_libSecOTR
+//
+//  Created by Mitch Adler on 3/2/11.
+//  Copyright 2011 Apple Inc. All rights reserved.
+//
+#include "SecOTRDHKey.h"
+#include <utilities/SecCFWrappers.h>
+
+#include "SecOTRMath.h"
+#include "SecOTRPacketData.h"
+
+#include <corecrypto/ccn.h>
+#include <corecrypto/ccsha1.h>
+#include <corecrypto/ccec_priv.h>
+#include <corecrypto/ccec.h>
+
+#include <CommonCrypto/CommonRandomSPI.h>
+
+#ifdef USECOMMONCRYPTO
+#include <CommonCrypto/CommonDigest.h>
+#endif
+
+#define kECKeySize 256
+
+struct _SecOTRFullDHKey {
+    CFRuntimeBase _base;
+
+    ccec_full_ctx_decl(ccn_sizeof(kECKeySize), _key);
+    uint8_t keyHash[CCSHA1_OUTPUT_SIZE];
+
+};
+
+CFGiblisFor(SecOTRFullDHKey);
+
+static size_t AppendECPublicKeyAsDATA(CFMutableDataRef data, ccec_pub_ctx_t public_key)
+{
+    size_t size = ccec_export_pub_size(public_key);
+
+    AppendLong(data, (uint32_t)size); /* cast: no overflow, pub size always fit in 32 bits */
+    ccec_export_pub(public_key, CFDataIncreaseLengthAndGetMutableBytes(data, (CFIndex)size));
+
+    return size;
+}
+
+
+static CF_RETURNS_RETAINED CFStringRef SecOTRFullDHKeyCopyDescription(CFTypeRef cf)
+{
+    SecOTRFullDHKeyRef session = (SecOTRFullDHKeyRef)cf;
+    return CFStringCreateWithFormat(kCFAllocatorDefault,NULL,CFSTR("<SecOTRFullDHKeyRef: %p>"), session);
+}
+
+static void SecOTRFullDHKeyDestroy(CFTypeRef cf)
+{
+    SecOTRFullDHKeyRef fullKey = (SecOTRFullDHKeyRef)cf;
+    
+    bzero(fullKey->_key, sizeof(fullKey->_key));
+}
+
+SecOTRFullDHKeyRef SecOTRFullDHKCreate(CFAllocatorRef allocator)
+{
+    SecOTRFullDHKeyRef newFDHK = CFTypeAllocate(SecOTRFullDHKey, struct _SecOTRFullDHKey, allocator);
+
+    SecFDHKNewKey(newFDHK);
+    
+    return newFDHK;
+}
+
+SecOTRFullDHKeyRef SecOTRFullDHKCreateFromBytes(CFAllocatorRef allocator, const uint8_t**bytes, size_t*size)
+{
+    SecOTRFullDHKeyRef newFDHK = CFTypeAllocate(SecOTRFullDHKey, struct _SecOTRFullDHKey, allocator);
+
+    ccec_ctx_init(ccec_cp_256(), newFDHK->_key);
+
+    uint32_t publicKeySize;
+    require_noerr(ReadLong(bytes, size, &publicKeySize), fail);
+
+    require(publicKeySize <= *size, fail);
+    require_noerr(ccec_import_pub(ccec_cp_256(), publicKeySize, *bytes, newFDHK->_key), fail);
+    ccdigest(ccsha1_di(), publicKeySize, *bytes, newFDHK->keyHash);
+    
+    *size -= publicKeySize;
+    *bytes += publicKeySize;
+
+    require_noerr(ReadMPI(bytes, size, ccec_ctx_n(newFDHK->_key), ccec_ctx_k(newFDHK->_key)), fail);
+
+    return newFDHK;
+
+fail:
+    CFReleaseNull(newFDHK);
+    return NULL;
+}
+
+void SecFDHKNewKey(SecOTRFullDHKeyRef fullKey)
+{
+    struct ccrng_state *rng=ccDRBGGetRngState();
+
+#if defined(CCECDH_AVAILABLE)
+    ccecdh_generate_key(ccec_cp_256(), rng, fullKey->_key);
+#else
+    ccec_generate_key(ccec_cp_256(), rng, fullKey->_key);
+#endif
+    
+    size_t size = ccec_export_pub_size(fullKey->_key);
+    uint8_t publicKey[size];
+
+    ccec_export_pub(fullKey->_key, publicKey);
+    ccdigest(ccsha1_di(), size, publicKey, fullKey->keyHash);
+}
+
+void SecFDHKAppendSerialization(SecOTRFullDHKeyRef fullKey, CFMutableDataRef appendTo)
+{
+    AppendECPublicKeyAsDATA(appendTo, fullKey->_key);
+    AppendMPI(appendTo, ccec_ctx_n(fullKey->_key), ccec_ctx_k(fullKey->_key));
+}
+
+
+void SecFDHKAppendPublicSerialization(SecOTRFullDHKeyRef fullKey, CFMutableDataRef appendTo)
+{
+    if(ccec_ctx_bitlen(fullKey->_key) != kECKeySize) return;
+    AppendECPublicKeyAsDATA(appendTo, fullKey->_key);
+}
+
+
+uint8_t* SecFDHKGetHash(SecOTRFullDHKeyRef fullKey)
+{
+    return fullKey->keyHash;
+}
+
+
+
+
+//
+//
+//
+struct _SecOTRPublicDHKey {
+    CFRuntimeBase _base;
+
+    ccec_pub_ctx_decl(ccn_sizeof(kECKeySize), _key);
+    uint8_t keyHash[CCSHA1_OUTPUT_SIZE];
+
+};
+
+CFGiblisFor(SecOTRPublicDHKey);
+
+static CF_RETURNS_RETAINED CFStringRef SecOTRPublicDHKeyCopyDescription(CFTypeRef cf) {
+    SecOTRPublicDHKeyRef session = (SecOTRPublicDHKeyRef)cf;
+    return CFStringCreateWithFormat(kCFAllocatorDefault,NULL,CFSTR("<SecOTRPublicDHKeyRef: %p>"), session);
+}
+
+static void SecOTRPublicDHKeyDestroy(CFTypeRef cf) {
+    SecOTRPublicDHKeyRef pubKey = (SecOTRPublicDHKeyRef)cf;
+    (void) pubKey;
+}
+
+static void ccec_copy_public(ccec_pub_ctx_t source, ccec_pub_ctx_t dest)
+{
+    ccec_ctx_cp(dest) = ccec_ctx_cp(source);
+    // TODO: +1?!
+    ccn_set(3*ccec_ctx_n(source), (cc_unit*) ccec_ctx_point(dest)._p, (cc_unit*) ccec_ctx_point(source)._p);
+}
+
+SecOTRPublicDHKeyRef SecOTRPublicDHKCreateFromFullKey(CFAllocatorRef allocator, SecOTRFullDHKeyRef full)
+{
+    SecOTRPublicDHKeyRef newPDHK = CFTypeAllocate(SecOTRPublicDHKey, struct _SecOTRPublicDHKey, allocator);
+    
+    ccec_copy_public(full->_key, newPDHK->_key);
+    memcpy(newPDHK->keyHash, full->keyHash, CCSHA1_OUTPUT_SIZE);
+
+    return newPDHK;
+}
+
+SecOTRPublicDHKeyRef SecOTRPublicDHKCreateFromSerialization(CFAllocatorRef allocator, const uint8_t** bytes, size_t *size)
+{
+    SecOTRPublicDHKeyRef newPDHK = CFTypeAllocate(SecOTRPublicDHKey, struct _SecOTRPublicDHKey, allocator);
+
+    uint32_t publicKeySize;
+    require_noerr(ReadLong(bytes, size, &publicKeySize), fail);
+
+    require(publicKeySize <= *size, fail);
+
+    require_noerr(ccec_import_pub(ccec_cp_256(), publicKeySize, *bytes, newPDHK->_key), fail);
+    ccdigest(ccsha1_di(), publicKeySize, *bytes, newPDHK->keyHash);
+
+    *size -= publicKeySize;
+    *bytes += publicKeySize;
+
+    return newPDHK;
+fail:
+    CFReleaseNull(newPDHK);
+    return NULL;
+}
+
+SecOTRPublicDHKeyRef SecOTRPublicDHKCreateFromBytes(CFAllocatorRef allocator, const uint8_t** bytes, size_t *size)
+{
+    SecOTRPublicDHKeyRef newPDHK = CFTypeAllocate(SecOTRPublicDHKey, struct _SecOTRPublicDHKey, allocator);
+    
+    require_noerr(ccec_import_pub(ccec_cp_256(), *size, *bytes, newPDHK->_key), fail);
+    ccdigest(ccsha1_di(), *size, *bytes, newPDHK->keyHash);
+
+    return newPDHK;
+fail:
+    CFReleaseNull(newPDHK);
+    return NULL;
+}
+
+void SecPDHKAppendSerialization(SecOTRPublicDHKeyRef pubKey, CFMutableDataRef appendTo)
+{
+    AppendECPublicKeyAsDATA(appendTo, pubKey->_key);
+}
+
+
+uint8_t* SecPDHKGetHash(SecOTRPublicDHKeyRef pubKey)
+{
+    return pubKey->keyHash;
+}
+
+
+void SecPDHKeyGenerateS(SecOTRFullDHKeyRef myKey, SecOTRPublicDHKeyRef theirKey, cc_unit* s)
+{
+    ccn_zero(kExponentiationUnits, s);
+
+    size_t keyLen = ccn_sizeof_n(kExponentiationUnits);
+    ccec_compute_key(myKey->_key, theirKey->_key, &keyLen, (uint8_t*)s);
+}
+
+static int ccec_cmp(ccec_pub_ctx_t l, ccec_pub_ctx_t r)
+{
+    size_t lsize = ccec_export_pub_size(l);
+    size_t rsize = ccec_export_pub_size(r);
+    
+    int result = 0;
+    
+    if (lsize == rsize) {
+        uint8_t lpub[lsize];
+        uint8_t rpub[rsize];
+        
+        ccec_export_pub(l, lpub);
+        ccec_export_pub(r, rpub);
+        
+        result = memcmp(lpub, rpub, lsize);
+    } else {
+        result = rsize < lsize ? -1 : 1;
+    }
+    
+    return result;
+}
+
+bool SecDHKIsGreater(SecOTRFullDHKeyRef myKey, SecOTRPublicDHKeyRef theirKey)
+{
+    return ccec_cmp(myKey->_key, theirKey->_key) > 0;
+}
+
+static void DeriveKeys(CFDataRef dataToHash,
+                       uint8_t* messageKey,
+                       uint8_t* macKey)
+{
+    if (messageKey == NULL && macKey == NULL)
+        return;
+
+    uint8_t hashedSharedKey[CCSHA1_OUTPUT_SIZE];
+
+#ifdef USECOMMONCRYPTO
+    (void) CCDigest(kCCDigestSHA1, CFDataGetBytePtr(dataToHash), (uint32_t)CFDataGetLength(dataToHash), hashedSharedKey);
+#else
+    ccdigest(ccsha1_di(), CFDataGetLength(dataToHash), CFDataGetBytePtr(dataToHash), hashedSharedKey);
+#endif
+
+    if (messageKey)
+        memcpy(messageKey, hashedSharedKey, kOTRMessageKeyBytes);
+    
+    if (macKey) {
+#ifdef USECOMMONCRYPTO
+        (void) CCDigest(kCCDigestSHA1, messageKey, kOTRMessageKeyBytes, macKey);
+#else
+        ccdigest(ccsha1_di(), kOTRMessageKeyBytes, messageKey, macKey);
+#endif
+    }
+    
+    bzero(hashedSharedKey, sizeof(hashedSharedKey));
+}
+
+void SecOTRDHKGenerateOTRKeys(SecOTRFullDHKeyRef myKey, SecOTRPublicDHKeyRef theirKey,
+                           uint8_t* sendMessageKey, uint8_t* sendMacKey,
+                           uint8_t* receiveMessageKey, uint8_t* receiveMacKey)
+{
+    CFMutableDataRef dataToHash = CFDataCreateMutable(kCFAllocatorDefault, 0);
+
+    {
+        cc_unit s[kExponentiationUnits];
+
+        SecPDHKeyGenerateS(myKey, theirKey, s);
+        AppendByte(dataToHash, SecDHKIsGreater(myKey, theirKey) ? 0x01 : 0x02);
+        AppendMPI(dataToHash, kExponentiationUnits, s);
+
+        ccn_zero(kExponentiationUnits, s);
+    }
+
+    DeriveKeys(dataToHash, receiveMessageKey, receiveMacKey);
+
+    uint8_t *messageTypeByte = CFDataGetMutableBytePtr(dataToHash);
+
+    *messageTypeByte ^= 0x03; // Invert the bits since it's either 1 or 2.
+
+    DeriveKeys(dataToHash, sendMessageKey, sendMacKey);
+
+    CFReleaseNull(dataToHash);
+}
diff --git a/sec/Security/SecOTRDHKey.h b/sec/Security/SecOTRDHKey.h
new file mode 100644 (file)
index 0000000..70594f1
--- /dev/null
@@ -0,0 +1,46 @@
+//
+//  SecOTRDHKey.h
+//  libsecurity_libSecOTR
+//
+//  Created by Mitch Adler on 3/2/11.
+//  Copyright 2011 Apple Inc. All rights reserved.
+//
+#ifndef _SECOTRDHKEY_H_
+#define _SECOTRDHKEY_H_
+
+#include <CoreFoundation/CFBase.h>
+#include <CoreFoundation/CFData.h>
+#include <corecrypto/ccn.h>
+
+__BEGIN_DECLS
+
+typedef struct _SecOTRFullDHKey* SecOTRFullDHKeyRef;
+typedef struct _SecOTRPublicDHKey* SecOTRPublicDHKeyRef;
+
+SecOTRFullDHKeyRef SecOTRFullDHKCreate(CFAllocatorRef allocator);
+SecOTRFullDHKeyRef SecOTRFullDHKCreateFromBytes(CFAllocatorRef allocator, const uint8_t**bytes, size_t*size);
+
+void SecFDHKNewKey(SecOTRFullDHKeyRef key);
+void SecFDHKAppendSerialization(SecOTRFullDHKeyRef fullKey, CFMutableDataRef appendTo);
+void SecFDHKAppendPublicSerialization(SecOTRFullDHKeyRef fullKey, CFMutableDataRef appendTo);
+uint8_t* SecFDHKGetHash(SecOTRFullDHKeyRef pubKey);
+
+
+SecOTRPublicDHKeyRef SecOTRPublicDHKCreateFromFullKey(CFAllocatorRef allocator, SecOTRFullDHKeyRef full);
+SecOTRPublicDHKeyRef SecOTRPublicDHKCreateFromSerialization(CFAllocatorRef allocator, const uint8_t**bytes, size_t*size);
+SecOTRPublicDHKeyRef SecOTRPublicDHKCreateFromBytes(CFAllocatorRef allocator, const uint8_t** bytes, size_t *size);
+
+void SecPDHKAppendSerialization(SecOTRPublicDHKeyRef pubKey, CFMutableDataRef appendTo);
+uint8_t* SecPDHKGetHash(SecOTRPublicDHKeyRef pubKey);
+
+void SecPDHKeyGenerateS(SecOTRFullDHKeyRef myKey, SecOTRPublicDHKeyRef theirKey, cc_unit* s);
+
+bool SecDHKIsGreater(SecOTRFullDHKeyRef myKey, SecOTRPublicDHKeyRef theirKey);
+
+void SecOTRDHKGenerateOTRKeys(SecOTRFullDHKeyRef myKey, SecOTRPublicDHKeyRef theirKey,
+                           uint8_t* sendMessageKey, uint8_t* sendMacKey,
+                           uint8_t* receiveMessageKey, uint8_t* receiveMacKey);
+
+__END_DECLS
+
+#endif
diff --git a/sec/Security/SecOTRErrors.h b/sec/Security/SecOTRErrors.h
new file mode 100644 (file)
index 0000000..c5cea30
--- /dev/null
@@ -0,0 +1,27 @@
+//
+//  SecOTRErrors.h
+//  libsecurity_libSecOTR
+//
+//  Created by Keith Henrickson on 4/30/12.
+//
+//
+
+#ifndef messsageProtection_SecMessageProtectionErrors_h
+#define messsageProtection_SecMessageProtectionErrors_h
+
+static const CFIndex kSecOTRErrorFailedToEncrypt = -1;
+static const CFIndex kSecOTRErrorFailedToDecrypt = -2;
+static const CFIndex kSecOTRErrorFailedToVerify = -3;
+static const CFIndex kSecOTRErrorFailedToSign = -4;
+static const CFIndex kSecOTRErrorSignatureDidNotMatch = -5;
+static const CFIndex kSecOTRErrorFailedSelfTest = -6;
+static const CFIndex kSecOTRErrorParameterError = -7;
+static const CFIndex kSecOTRErrorUnknownFormat = -8;
+static const CFIndex kSecOTRErrorCreatePublicIdentity = -9;
+static const CFIndex kSecOTRErrorCreatePublicBytes = -10;
+
+// Errors 100-199 reserved for errors being genrated by workarounds/known issues failing
+static const CFIndex kSecOTRErrorSignatureTooLarge = -100;
+static const CFIndex kSecOTRErrorSignatureDidNotRecreate = -101;
+
+#endif
diff --git a/sec/Security/SecOTRFullIdentity.c b/sec/Security/SecOTRFullIdentity.c
new file mode 100644 (file)
index 0000000..2bb032f
--- /dev/null
@@ -0,0 +1,509 @@
+/*
+ *  SecOTRFullIdentity.c
+ *  libsecurity_libSecOTR
+ *
+ *  Created by Mitch Adler on 2/9/11.
+ *  Copyright 2011 Apple Inc. All rights reserved.
+ *
+ */
+
+#include "SecOTR.h"
+#include "SecOTRIdentityPriv.h"
+#include <utilities/array_size.h>
+#include <utilities/SecCFWrappers.h>
+
+#include <AssertMacros.h>
+
+#include <CoreFoundation/CFNumber.h>
+#include <CoreFoundation/CFString.h>
+#include <CoreFoundation/CFData.h>
+
+#include <Security/SecItem.h>
+#include <Security/SecKeyPriv.h>
+
+#include <Security/oidsalg.h>
+#include <Security/SecCertificatePriv.h>
+
+#include "SecOTRErrors.h"
+
+#include <TargetConditionals.h>
+
+//
+// Algorthim ID initialization
+//
+
+#define kMessageIdentityRSAKeyBits 1280
+#define kMessageIdentityECKeyBits 256
+
+void EnsureOTRAlgIDInited(void)
+{
+    static dispatch_once_t kSignatureAlgID_ONCE;
+    static SecAsn1AlgId kOTRECSignatureAlgID;
+
+    dispatch_once(&kSignatureAlgID_ONCE, ^{
+        kOTRECSignatureAlgID.algorithm = CSSMOID_ECDSA_WithSHA1;
+        kOTRSignatureAlgIDPtr = &kOTRECSignatureAlgID;
+    });
+}
+
+
+static CFStringRef sSigningKeyName = CFSTR("OTR Signing Key");
+
+//
+// SecOTRFullIdentity implementation
+//
+
+CFGiblisFor(SecOTRFullIdentity);
+
+static CF_RETURNS_RETAINED CFStringRef SecOTRFullIdentityCopyDescription(CFTypeRef cf) {
+    SecOTRFullIdentityRef requestor = (SecOTRFullIdentityRef)cf;
+    return CFStringCreateWithFormat(kCFAllocatorDefault,NULL,CFSTR("<SecOTRPublicIdentity: %p %02x%02x%02x%02x%02x%02x%02x%02x>"),
+                                    requestor,
+                                    requestor->publicIDHash[0], requestor->publicIDHash[1],
+                                    requestor->publicIDHash[2], requestor->publicIDHash[3],
+                                    requestor->publicIDHash[4], requestor->publicIDHash[5],
+                                    requestor->publicIDHash[6], requestor->publicIDHash[7]);
+}
+
+static void SecOTRFullIdentityDestroy(CFTypeRef cf) {
+    SecOTRFullIdentityRef requestor = (SecOTRFullIdentityRef)cf;
+
+    CFReleaseNull(requestor->privateSigningKey);
+    CFReleaseNull(requestor->publicSigningKey);
+}
+
+
+//
+// Shared statics
+//
+
+static OSStatus SecOTRFIPurgeFromKeychainByValue(SecKeyRef key, CFStringRef label)
+{
+    OSStatus status;
+    const void *keys[] =   { kSecClass,
+        kSecAttrLabel,
+        kSecValueRef,
+    };
+    const void *values[] = { kSecClassKey,
+        label,
+        key,
+    };
+    CFDictionaryRef dict = CFDictionaryCreate(NULL, keys, values, array_size(values), NULL, NULL);
+    status = SecItemDelete(dict);
+    CFReleaseSafe(dict);
+
+    return status;
+}
+
+static bool SecKeyDigestAndSignWithError(
+                                  SecKeyRef           key,            /* Private key */
+                                  const SecAsn1AlgId  *algId,         /* algorithm oid/params */
+                                  const uint8_t       *dataToDigest,   /* signature over this data */
+                                  size_t              dataToDigestLen,/* length of dataToDigest */
+                                  uint8_t             *sig,                    /* signature, RETURNED */
+                                  size_t              *sigLen,         /* IN/OUT */
+                                  CFErrorRef          *error) {
+
+    OSStatus status = SecKeyDigestAndSign(key, algId, dataToDigest, dataToDigestLen, sig, sigLen);
+    require_noerr(status, fail);
+    return true;
+fail:
+    SecOTRCreateError(secOTRErrorOSError, status, CFSTR("Error signing message. OSStatus in error code."), NULL, error);
+    return false;
+}
+
+//
+// SecOTRFullIdentity Functions
+//
+
+static bool SecOTRFICachePublicHash(SecOTRFullIdentityRef fullID, CFErrorRef *error)
+{
+    SecOTRPublicIdentityRef pubID = SecOTRPublicIdentityCopyFromPrivate(NULL, fullID, error);
+
+    require(pubID, fail);
+
+    SecOTRPICopyHash(pubID, fullID->publicIDHash);
+
+fail:
+    CFReleaseSafe(pubID);
+    return (pubID != NULL); // This is safe because we're not accessing the value after release, just checking if it ever had a value of some nature.
+}
+
+#if !TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
+#define SEC_CONST_DECL(k,v) CFTypeRef k = (CFTypeRef)(CFSTR(v));
+SEC_CONST_DECL (kSecAttrAccessible, "pdmn");
+SEC_CONST_DECL (kSecAttrAccessibleAlwaysThisDeviceOnly, "dku");
+#endif
+
+SecOTRFullIdentityRef SecOTRFullIdentityCreate(CFAllocatorRef allocator, CFErrorRef *error)
+{
+    CFDictionaryRef keygen_parameters = NULL;
+    SecOTRFullIdentityRef newID = CFTypeAllocate(SecOTRFullIdentity, struct _SecOTRFullIdentity, allocator);
+    SecKeyRef tempSigningKey = NULL;
+
+    newID->publicSigningKey = NULL;
+    newID->privateSigningKey = NULL;
+
+    require(newID, out);
+
+    EnsureOTRAlgIDInited();
+
+    const int signing_keySizeLocal = kMessageIdentityECKeyBits;
+    CFNumberRef signing_bitsize = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &signing_keySizeLocal);
+
+    const void *signing_keygen_keys[] = { kSecAttrKeyType,
+                                          kSecAttrKeySizeInBits,
+                                          kSecAttrIsPermanent,
+                                          kSecAttrAccessible,
+                                          kSecAttrLabel,
+                                        };
+
+    const void *signing_keygen_vals[] = { kSecAttrKeyTypeEC,
+                                          signing_bitsize,
+                                          kCFBooleanTrue,
+                                          kSecAttrAccessibleAlwaysThisDeviceOnly,
+                                          sSigningKeyName
+                                        };
+    keygen_parameters = CFDictionaryCreate(kCFAllocatorDefault,
+                                           signing_keygen_keys, signing_keygen_vals, array_size(signing_keygen_vals),
+                                           &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks );
+    CFReleaseNull(signing_bitsize);
+    require_noerr(SecKeyGeneratePair(keygen_parameters, &tempSigningKey, &newID->privateSigningKey), out);
+    CFReleaseNull(keygen_parameters);
+
+    newID->publicSigningKey = SecKeyCreatePublicFromPrivate(tempSigningKey);
+
+    (void) SecOTRFIPurgeFromKeychainByValue(tempSigningKey, sSigningKeyName);
+    CFReleaseNull(tempSigningKey);
+
+    require(SecOTRFICachePublicHash(newID, error), out);
+
+    return newID;
+
+out:
+    if (NULL != newID) {
+        SecOTRFIPurgeFromKeychain(newID, NULL);
+    }
+    CFReleaseSafe(keygen_parameters);
+    CFReleaseSafe(newID);
+    CFReleaseSafe(tempSigningKey);
+    return NULL;
+}
+
+
+static
+OSStatus SecOTRFICreatePrivateKeyReadPersistentRef(const uint8_t **bytes, size_t *size, SecKeyRef* privateKey)
+{
+    OSStatus status = errSecParam;
+    uint16_t dataSize;
+    CFDataRef persistentRef = NULL;
+
+    require_noerr_quiet(readSize(bytes, size, &dataSize), fail);
+    require_quiet(dataSize <= *size, fail);
+
+    SecKeyRef lookedUpKey = NULL;
+    persistentRef = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, *bytes, dataSize, kCFAllocatorNull);
+    require_quiet(persistentRef, fail);
+
+    require_noerr_quiet(SecKeyFindWithPersistentRef(persistentRef, &lookedUpKey), fail);
+
+    *privateKey = lookedUpKey;
+
+    *bytes += dataSize;
+    *size -= dataSize;
+
+    status = errSecSuccess;
+
+fail:
+    CFReleaseSafe(persistentRef);
+
+    return status;
+}
+
+static
+OSStatus SecOTRFICreateKeysFromReadPersistentRef(const uint8_t **bytes, size_t *size, SecKeyRef *publicKey, SecKeyRef* privateKey)
+{
+    SecKeyRef foundKey = NULL;
+
+    OSStatus status = SecOTRFICreatePrivateKeyReadPersistentRef(bytes, size, &foundKey);
+    require_noerr_quiet(status, fail);
+    require_quiet(foundKey, fail);
+
+    *publicKey = SecKeyCreatePublicFromPrivate(*privateKey);
+    require_action_quiet(*publicKey, fail, status = errSecParam);
+
+    *privateKey = foundKey;
+    foundKey = NULL;
+
+    status = errSecSuccess;
+
+fail:
+    CFReleaseSafe(foundKey);
+    return status;
+}
+
+typedef SecKeyRef (*SecOTRPublicKeyCreateFunction)(CFAllocatorRef allocator, const uint8_t** data, size_t* limit);
+
+static
+OSStatus SecOTRFICreateKeysFromReadPersistentRefAndPublicKey(const uint8_t **bytes, size_t *size, SecKeyRef *publicKey, SecKeyRef* privateKey, SecOTRPublicKeyCreateFunction createPublic)
+{
+    SecKeyRef foundKey = NULL;
+
+    OSStatus status = SecOTRFICreatePrivateKeyReadPersistentRef(bytes, size, &foundKey);
+    require_noerr_quiet(status, fail);
+    require_quiet(foundKey, fail);
+
+    *publicKey = (*createPublic)(NULL, bytes, size);
+    require_action_quiet(*publicKey, fail, status = errSecParam);
+
+    *privateKey = foundKey;
+
+fail:
+    return status;
+}
+
+static
+OSStatus SecOTRFIInitFromV1Bytes(SecOTRFullIdentityRef newID, CFAllocatorRef allocator,
+                                const uint8_t **bytes,size_t *size) {
+    require(**bytes == 1, fail);
+    ++*bytes;
+    --*size;
+
+    require_noerr_quiet(SecOTRFICreateKeysFromReadPersistentRef(bytes, size, &newID->publicSigningKey, &newID->privateSigningKey), fail);
+
+    return errSecSuccess;
+
+fail:
+    CFReleaseNull(newID->publicSigningKey);
+    CFReleaseNull(newID->privateSigningKey);
+
+    return errSecParam;
+}
+
+static
+OSStatus SecOTRFIInitFromV2Bytes(SecOTRFullIdentityRef newID, CFAllocatorRef allocator,
+                                const uint8_t **bytes,size_t *size) {
+    require(**bytes == 2, fail);
+    ++*bytes;
+    --*size;
+
+    require_noerr_quiet(SecOTRFICreateKeysFromReadPersistentRefAndPublicKey(bytes, size, &newID->publicSigningKey, &newID->privateSigningKey, &CreateECPublicKeyFrom), fail);
+
+    return errSecSuccess;
+
+fail:
+    CFReleaseNull(newID->publicSigningKey);
+    CFReleaseNull(newID->privateSigningKey);
+
+    return errSecParam;
+}
+
+SecOTRFullIdentityRef SecOTRFullIdentityCreateFromSecKeyRef(CFAllocatorRef allocator, SecKeyRef privateKey,
+                                                            CFErrorRef *error) {
+    // TODO - make sure this is an appropriate key type
+    SecOTRFullIdentityRef newID = CFTypeAllocate(SecOTRFullIdentity, struct _SecOTRFullIdentity, allocator);
+    newID->privateSigningKey = privateKey;
+    CFRetain(newID->privateSigningKey);
+    newID->publicSigningKey = SecKeyCreatePublicFromPrivate(privateKey);
+    require(SecOTRFICachePublicHash(newID, error), fail);
+    return newID;
+fail:
+    CFRelease(newID->privateSigningKey);
+    CFRelease(newID->publicSigningKey);
+    CFReleaseSafe(newID);
+    return NULL;
+}
+
+SecOTRFullIdentityRef SecOTRFullIdentityCreateFromBytes(CFAllocatorRef allocator, const uint8_t**bytes, size_t *size, CFErrorRef *error)
+{
+    SecOTRFullIdentityRef newID = CFTypeAllocate(SecOTRFullIdentity, struct _SecOTRFullIdentity, allocator);
+    EnsureOTRAlgIDInited();
+
+    require(*size > 0, fail);
+
+    switch (**bytes) {
+        case 1:
+            require_noerr_quiet(SecOTRFIInitFromV1Bytes(newID, allocator, bytes, size), fail);
+            break;
+        case 2:
+            require_noerr_quiet(SecOTRFIInitFromV2Bytes(newID, allocator, bytes, size), fail);
+            break;
+        case 0: // Version 0 was used in seeds of 5.0, transition from those seeds unsupported - keys were in exported data.
+        default:
+            require(false, fail);
+            break;
+    }
+
+    require(SecOTRFICachePublicHash(newID, error), fail);
+
+    return newID;
+
+fail:
+    if (NULL != newID) {
+        SecOTRFIPurgeFromKeychain(newID, NULL);
+    }
+    CFReleaseSafe(newID);
+    return NULL;
+}
+
+SecOTRFullIdentityRef SecOTRFullIdentityCreateFromData(CFAllocatorRef allocator, CFDataRef data, CFErrorRef *error)
+{
+    if (data == NULL)
+        return NULL;
+
+    size_t size = (size_t)CFDataGetLength(data);
+    const uint8_t* bytes = CFDataGetBytePtr(data);
+
+    return SecOTRFullIdentityCreateFromBytes(allocator, &bytes, &size, error);
+}
+
+bool SecOTRFIPurgeFromKeychain(SecOTRFullIdentityRef thisID, CFErrorRef *error)
+{
+    OSStatus result = SecOTRFIPurgeFromKeychainByValue(thisID->privateSigningKey, sSigningKeyName);
+    if (errSecSuccess == result) {
+        return true;
+    } else {
+        SecOTRCreateError(secOTRErrorOSError, result, CFSTR("OSStatus returned in error code"), NULL, error);
+        return false;
+    }
+}
+
+
+static OSStatus SecOTRFIPurgeAllFromKeychainByLabel(CFStringRef label)
+{
+    OSStatus status;
+    const void *keys[] =   { kSecClass,
+        kSecAttrKeyClass,
+        kSecAttrLabel,
+    };
+    const void *values[] = { kSecClassKey,
+        kSecAttrKeyClassPrivate,
+        label,
+    };
+    CFDictionaryRef dict = CFDictionaryCreate(NULL, keys, values, array_size(values), NULL, NULL);
+    bool deleteAtLeastOne = false;
+    int loopLimiter = 500;
+    do {
+        status = SecItemDelete(dict);
+        if (status == errSecSuccess) {
+            deleteAtLeastOne = true;
+        }
+        loopLimiter--;
+    } while ((status == errSecSuccess) && (loopLimiter > 0));
+    if ((status == errSecItemNotFound) && (deleteAtLeastOne)) {
+        // We've looped until we can't delete any more keys.
+        // Since this will produce an expected 'itemNotFound', but we don't want to break the contract above
+        // (and also we want to make sense)
+        // we muffle the non-error to a success case, which it is.
+        status = errSecSuccess;
+    }
+    CFReleaseSafe(dict);
+
+    return status;
+}
+
+bool SecOTRFIPurgeAllFromKeychain(CFErrorRef *error)
+{
+    OSStatus result = SecOTRFIPurgeAllFromKeychainByLabel(sSigningKeyName);
+    if (errSecSuccess == result) {
+        return true;
+    } else {
+        SecOTRCreateError(secOTRErrorOSError, result, CFSTR("OSStatus returned in error code"), NULL, error);
+        return false;
+    }
+}
+
+static OSStatus appendPersistentRefData(SecKeyRef theKey, CFMutableDataRef serializeInto, CFStringRef name)
+{
+    OSStatus status;
+    CFDataRef persistent_ref = NULL;
+    require_noerr(status = SecKeyCopyPersistentRef(theKey, &persistent_ref), fail);
+
+    status = appendSizeAndData(persistent_ref, serializeInto);
+
+fail:
+    CFReleaseSafe(persistent_ref);
+
+    return status;
+}
+
+static OSStatus SecOTRFIAppendV2Serialization(SecOTRFullIdentityRef fullID, CFMutableDataRef serializeInto)
+{
+    const uint8_t version = 2;
+    CFIndex start = CFDataGetLength(serializeInto);
+
+    CFDataAppendBytes(serializeInto, &version, sizeof(version));
+
+    require(errSecSuccess == appendPersistentRefData(fullID->privateSigningKey, serializeInto, sSigningKeyName), fail);
+    require(errSecSuccess == appendPublicOctetsAndSize(fullID->publicSigningKey, serializeInto), fail);
+    return errSecSuccess;
+
+fail:
+    CFDataSetLength(serializeInto, start);
+
+    return errSecParam;
+}
+
+
+bool SecOTRFIAppendSerialization(SecOTRFullIdentityRef fullID, CFMutableDataRef serializeInto, CFErrorRef *error)
+{
+    OSStatus status = SecOTRFIAppendV2Serialization(fullID, serializeInto);
+    if (errSecSuccess == status) {
+        return true;
+    } else {
+        SecOTRCreateError(secOTRErrorOSError, status, CFSTR("OSStatus returned in error code"), NULL, error);
+        return false;
+    }
+}
+
+size_t SecOTRFISignatureSize(SecOTRFullIdentityRef fullID)
+{
+    return SecKeyGetSize(fullID->publicSigningKey, kSecKeySignatureSize);
+}
+
+bool SecOTRFIAppendSignature(SecOTRFullIdentityRef fullID,
+                                CFDataRef dataToHash,
+                                CFMutableDataRef appendTo,
+                                CFErrorRef *error)
+{
+    const size_t signatureSize = SecOTRFISignatureSize(fullID);
+    const CFIndex sourceLength = CFDataGetLength(dataToHash);
+    const uint8_t* sourceData = CFDataGetBytePtr(dataToHash);
+
+    CFIndex start = CFDataGetLength(appendTo);
+
+    require(((CFIndex)signatureSize) >= 0, fail);
+
+    CFDataIncreaseLength(appendTo, (CFIndex)signatureSize + 1);
+
+    uint8_t *size = CFDataGetMutableBytePtr(appendTo) + start;
+    uint8_t* signatureStart = size + 1;
+    size_t signatureUsed = signatureSize;
+
+   require(SecKeyDigestAndSignWithError(fullID->privateSigningKey, kOTRSignatureAlgIDPtr,
+                                    sourceData, (size_t)sourceLength,
+                                    signatureStart, &signatureUsed, error), fail);
+
+    require(signatureUsed < 256, fail);
+    require(((CFIndex)signatureUsed) >= 0, fail);
+    *size = signatureUsed;
+
+    CFDataSetLength(appendTo, start + (CFIndex)signatureUsed + 1);
+
+    return true;
+
+fail:
+    CFDataSetLength(appendTo, start);
+
+    return false;
+}
+
+void SecOTRFIAppendPublicHash(SecOTRFullIdentityRef fullID, CFMutableDataRef appendTo)
+{
+    CFDataAppendBytes(appendTo, fullID->publicIDHash, sizeof(fullID->publicIDHash));
+}
+
+bool SecOTRFIComparePublicHash(SecOTRFullIdentityRef fullID, const uint8_t hash[kMPIDHashSize])
+{
+    return 0 == memcmp(hash, fullID->publicIDHash, kMPIDHashSize);
+}
diff --git a/sec/Security/SecOTRIdentityPriv.h b/sec/Security/SecOTRIdentityPriv.h
new file mode 100644 (file)
index 0000000..2ade61e
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ *  SecOTRIdentityPriv.h
+ *  libsecurity_libSecOTR
+ *
+ *  Created by Mitch Adler on 2/9/11.
+ *  Copyright 2011 Apple Inc. All rights reserved.
+ *
+ */
+
+#ifndef _SECOTRIDENTITYPRIV_H_
+
+#include <CoreFoundation/CFRuntime.h>
+#include <CoreFoundation/CFData.h>
+
+#include <Security/SecKey.h>
+
+#include <Security/oidsalg.h>
+
+#include <CommonCrypto/CommonDigest.h> // DIGEST_LENGTH
+#include <Security/SecOTR.h>
+
+__BEGIN_DECLS
+
+extern CFStringRef sErrorDomain;
+    
+// OAEP Padding, uses lots of space. Might need this to be data
+// Driven when we support more key types.
+#define kPaddingOverhead (2 + 2 * CC_SHA1_DIGEST_LENGTH + 1)
+    
+//
+// Identity opaque structs
+//
+
+#define kMPIDHashSize   CC_SHA1_DIGEST_LENGTH
+
+struct _SecOTRFullIdentity {
+    CFRuntimeBase _base;
+    
+    SecKeyRef   publicSigningKey;
+    SecKeyRef   privateSigningKey;
+    
+    uint8_t     publicIDHash[kMPIDHashSize];
+};
+
+
+struct _SecOTRPublicIdentity {
+    CFRuntimeBase _base;
+    
+    SecKeyRef   publicSigningKey;
+
+    bool        wantsHashes;
+
+    uint8_t     hash[kMPIDHashSize];
+};
+
+enum SecOTRError {
+    secOTRErrorLocal,
+    secOTRErrorOSError,
+};
+
+const SecAsn1AlgId *kOTRSignatureAlgIDPtr;
+void EnsureOTRAlgIDInited(void);
+    
+// Private functions for Public and Full IDs
+SecOTRFullIdentityRef SecOTRFullIdentityCreateWithSize(CFAllocatorRef allocator, int bits);
+
+bool SecOTRFIAppendSignature(SecOTRFullIdentityRef fullID,
+                                CFDataRef dataToHash,
+                                CFMutableDataRef appendTo,
+                                CFErrorRef *error);
+
+void SecOTRFIAppendPublicHash(SecOTRFullIdentityRef fullID, CFMutableDataRef appendTo);
+bool SecOTRFIComparePublicHash(SecOTRFullIdentityRef fullID, const uint8_t hash[kMPIDHashSize]);
+
+size_t SecOTRFISignatureSize(SecOTRFullIdentityRef privateID);
+
+bool SecOTRPIVerifySignature(SecOTRPublicIdentityRef publicID,
+                                const uint8_t *dataToHash, size_t amountToHash,
+                                const uint8_t *signatureStart, size_t signatureSize, CFErrorRef *error);
+
+bool SecOTRPIEqualToBytes(SecOTRPublicIdentityRef id, const uint8_t*bytes, CFIndex size);
+bool SecOTRPIEqual(SecOTRPublicIdentityRef left, SecOTRPublicIdentityRef right);
+
+size_t SecOTRPISignatureSize(SecOTRPublicIdentityRef publicID);
+    
+void SecOTRPICopyHash(SecOTRPublicIdentityRef publicID, uint8_t hash[kMPIDHashSize]);
+void SecOTRPIAppendHash(SecOTRPublicIdentityRef publicID, CFMutableDataRef appendTo);
+
+bool SecOTRPICompareHash(SecOTRPublicIdentityRef publicID, const uint8_t hash[kMPIDHashSize]);
+
+// Utility streaming functions
+OSStatus insertSize(CFIndex size, uint8_t* here);
+OSStatus appendSize(CFIndex size, CFMutableDataRef into);
+OSStatus readSize(const uint8_t** data, size_t* limit, uint16_t* size);
+
+OSStatus appendPublicOctets(SecKeyRef fromKey, CFMutableDataRef appendTo);
+OSStatus appendPublicOctetsAndSize(SecKeyRef fromKey, CFMutableDataRef appendTo);
+OSStatus appendSizeAndData(CFDataRef data, CFMutableDataRef appendTo);
+
+SecKeyRef CreateECPrivateKeyFrom(CFAllocatorRef allocator, const uint8_t** data, size_t* limit);
+SecKeyRef CreateECPublicKeyFrom(CFAllocatorRef allocator, const uint8_t** data, size_t* limit);
+    
+void SecOTRCreateError(enum SecOTRError family, CFIndex errorCode, CFStringRef descriptionString, CFErrorRef previousError, CFErrorRef *newError);
+
+__END_DECLS
+
+#endif
diff --git a/sec/Security/SecOTRMath.c b/sec/Security/SecOTRMath.c
new file mode 100644 (file)
index 0000000..65615ff
--- /dev/null
@@ -0,0 +1,186 @@
+//
+//  OTRMath.c
+//  libsecurity_libSecOTR
+//
+//  Created by Mitch Adler on 1/28/11.
+//  Copyright 2011 Apple Inc. All rights reserved.
+//
+
+#include "SecOTRMath.h"
+#include "SecOTRMathPrivate.h"
+
+#include "SecOTRPacketData.h"
+
+#include <AssertMacros.h>
+
+#include <pthread.h>
+
+#include <Security/SecRandom.h>
+
+#include <corecrypto/ccsha2.h>
+#include <corecrypto/cczp.h>
+
+#include <limits.h>
+
+static inline
+void cczp_init_from_bytes(cc_size n, cczp_t zp, size_t pSize, const void *p, size_t rSize, const void* r)
+{
+    CCZP_N(zp) = n;
+    zp.zp->mod_prime = cczp_mod;
+    ccn_read_uint(n, CCZP_PRIME(zp), pSize, p);
+    ccn_read_uint(n+1, CCZP_RECIP(zp), rSize, r);
+
+}
+
+static pthread_once_t   kOTRImportGroupData = PTHREAD_ONCE_INIT;
+
+static cc_unit sOTRGenerator[kOTRDHGroupUnits];
+static cczp_decl_n(kOTRDHGroupUnits, sOTRGroup_zp);
+
+static void setupGroupValues()
+{
+    __Check( kExponentiationUnits == kOTRDHGroupUnits );
+
+    cczp_init_from_bytes(kOTRDHGroupUnits, sOTRGroup_zp,
+                         sizeof(kOTRDHGroup), kOTRDHGroup,
+                         sizeof(kOTRDHGroup_Recip), kOTRDHGroup_Recip);
+    
+    ccn_seti(kOTRDHGroupUnits, sOTRGenerator, kOTRGeneratorValue);
+}
+
+void OTRExponentiate(cc_unit* res, const cc_unit* base, const cc_unit* exponent)
+{
+    pthread_once(&kOTRImportGroupData, setupGroupValues);
+    
+    cczp_power(sOTRGroup_zp, res, base, exponent);
+}
+
+void OTRGroupExponentiate(cc_unit* res, const cc_unit* exponent)
+{
+    pthread_once(&kOTRImportGroupData, setupGroupValues);
+
+    OTRExponentiate(res, sOTRGenerator, exponent);
+}
+
+//
+// Random Number Generation
+//
+
+OSStatus GetRandomBytesInLSBs(size_t bytesOfRandomness, size_t n, cc_unit* place)
+{
+    OSStatus result = errSecParam;
+    require(bytesOfRandomness * 8 <= ccn_bitsof_n(n), fail);
+    {
+        uint8_t randomBytes[bytesOfRandomness];
+        
+        result = SecRandomCopyBytes(kSecRandomDefault, sizeof(randomBytes), randomBytes);
+        
+        require_noerr(result, fail);
+        
+        ccn_read_uint(n, place, sizeof(randomBytes), randomBytes);
+        
+        bzero(randomBytes, bytesOfRandomness);
+    }
+fail:
+    return result;
+}
+
+OSStatus FillWithRandomBytes(size_t n, cc_unit* place)
+{
+    return GetRandomBytesInLSBs(ccn_sizeof(n), n, place);
+}
+
+
+static const uint8_t kIVZero[16] = { };
+
+static void AES_CTR_Transform(size_t keySize, const uint8_t* key,
+                       const uint8_t iv[16],
+                       size_t howMuch, const uint8_t* from, uint8_t* to)
+{
+    const struct ccmode_ctr* ctr_encrypt = ccaes_ctr_crypt_mode();
+    ccctr_ctx_decl(ctr_encrypt->size, ctr_ctx);
+    ctr_encrypt->init(ctr_encrypt, ctr_ctx, keySize, key, iv);
+    
+    ctr_encrypt->ctr(ctr_ctx, howMuch, from, to);
+}
+
+void AES_CTR_HighHalf_Transform(size_t keySize, const uint8_t* key,
+                                uint64_t highHalf,
+                                size_t howMuch, const uint8_t* from, uint8_t* to)
+{
+    uint8_t iv[16] = { highHalf >> 56, highHalf >> 48, highHalf >> 40, highHalf >> 32,
+                       highHalf >> 24, highHalf >> 16, highHalf >> 8 , highHalf >> 0,
+                                    0,              0,             0,              0,
+                                    0,              0,             0,              0 };
+    AES_CTR_Transform(keySize, key, iv, howMuch, from, to);
+}
+
+void AES_CTR_IV0_Transform(size_t keySize, const uint8_t* key,
+                           size_t howMuch, const uint8_t* from, uint8_t* to)
+{
+    AES_CTR_Transform(keySize, key, kIVZero, howMuch, from, to);
+}
+
+
+//
+// Key Derivation
+//
+
+static void HashMPIWithPrefix(uint8_t byte, cc_size sN, const cc_unit* s, uint8_t* buffer)
+{
+    CFMutableDataRef dataToHash = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    CFDataAppendBytes(dataToHash, &byte, 1);
+    
+    AppendMPI(dataToHash, sN, s);
+    
+    uint8_t *bytesToHash = CFDataGetMutableBytePtr(dataToHash);
+    CFIndex  amountToHash = CFDataGetLength(dataToHash);
+    
+    /* 64 bits cast: amountToHash is the size of an identity +1 , which is currently hardcoded and never more than 2^32 bytes */
+    assert((unsigned long)amountToHash<UINT32_MAX); /* Debug check, Correct as long as CFIndex is a signed long and CC_LONG is a uint32_t */
+
+    (void) CC_SHA256(bytesToHash, (CC_LONG)amountToHash, buffer);
+    
+    bzero(bytesToHash, (size_t)amountToHash);
+    CFReleaseNull(dataToHash);
+}
+
+void DeriveOTR256BitsFromS(KeyType whichKey, cc_size sN, const cc_unit* s, size_t keySize, uint8_t* key)
+{
+    HashMPIWithPrefix(whichKey, sN, s, key);
+}
+
+void DeriveOTR128BitPairFromS(KeyType whichKey, size_t sSize, const cc_unit* s,
+                              size_t firstKeySize, uint8_t* firstKey,
+                              size_t secondKeySize, uint8_t* secondKey)
+{
+    uint8_t hashBuffer[CCSHA256_OUTPUT_SIZE];
+    
+    HashMPIWithPrefix(whichKey, sSize, s, hashBuffer);
+    
+    if (firstKey) {
+        firstKeySize = firstKeySize > CCSHA256_OUTPUT_SIZE/2 ? CCSHA256_OUTPUT_SIZE/2 : firstKeySize;
+        memcpy(firstKey, hashBuffer, firstKeySize);
+    }
+    if (secondKey) {
+        secondKeySize = secondKeySize > CCSHA256_OUTPUT_SIZE/2 ? CCSHA256_OUTPUT_SIZE/2 : secondKeySize;
+        memcpy(secondKey, hashBuffer, secondKeySize);
+    }
+    
+    bzero(hashBuffer, CCSHA256_OUTPUT_SIZE);
+
+}
+
+void DeriveOTR64BitsFromS(KeyType whichKey, size_t sn, const cc_unit* s,
+                          size_t topKeySize, uint8_t* topKey)
+{
+    uint8_t hashBuffer[CCSHA256_OUTPUT_SIZE];
+    
+    HashMPIWithPrefix(whichKey, sn, s, hashBuffer);
+    
+    topKeySize = topKeySize > CCSHA256_OUTPUT_SIZE/2 ? CCSHA256_OUTPUT_SIZE/2 : topKeySize;
+    memcpy(topKey, hashBuffer, topKeySize);
+    
+    bzero(hashBuffer, CCSHA256_OUTPUT_SIZE);
+}
+
diff --git a/sec/Security/SecOTRMath.h b/sec/Security/SecOTRMath.h
new file mode 100644 (file)
index 0000000..936e106
--- /dev/null
@@ -0,0 +1,65 @@
+//
+//  OTRMath.h
+//  libsecurity_libSecOTR
+//
+//  Created by Mitch Adler on 1/28/11.
+//  Copyright 2011 Apple Inc. All rights reserved.
+//
+
+#ifndef _SECOTRMATH_H_
+#define _SECOTRMATH_H_
+
+#include <CoreFoundation/CFBase.h>
+
+#include <corecrypto/ccn.h>
+#include <corecrypto/ccaes.h>
+#include <corecrypto/ccmode.h>
+
+#define kOTRAuthKeyBytes 16
+#define kOTRAuthMACKeyBytes 32
+
+#define kOTRMessageKeyBytes 16
+#define kOTRMessageMacKeyBytes 20
+
+#define kExponentiationBits 1536
+#define kExponentiationUnits ccn_nof(kExponentiationBits)
+#define kExponentiationBytes ((kExponentiationBits+7)/8)
+
+#define kSHA256HMAC160Bits  160
+#define kSHA256HMAC160Bytes (kSHA256HMAC160Bits/8)
+
+// Result and exponent are expected to be kExponentiationUnits big.
+void OTRExponentiate(cc_unit* res, const cc_unit* base, const cc_unit* exponent);
+void OTRGroupExponentiate(cc_unit* result, const cc_unit* exponent);
+
+OSStatus GetRandomBytesInLSBs(size_t bytesOfRandomness, size_t n, cc_unit* place);
+OSStatus FillWithRandomBytes(size_t n, cc_unit* place);
+
+typedef enum {
+    kSSID = 0x00,
+    kCs = 0x01,
+    kM1 = 0x02,
+    kM2 = 0x03,
+    kM1Prime = 0x04,
+    kM2Prime = 0x05
+} KeyType;
+
+
+void DeriveOTR256BitsFromS(KeyType whichKey, size_t sSize, const cc_unit* s, size_t keySize, uint8_t* key);
+void DeriveOTR128BitPairFromS(KeyType whichHalf, size_t sSize, const cc_unit* s,
+                              size_t firstKeySize, uint8_t* firstKey,
+                              size_t secondKeySize, uint8_t* secondKey);
+void DeriveOTR64BitsFromS(KeyType whichKey, size_t sSize, const cc_unit* s,
+                          size_t firstKeySize, uint8_t* firstKey);
+
+
+void AES_CTR_HighHalf_Transform(size_t keySize, const uint8_t* key,
+                                uint64_t highHalf,
+                                size_t howMuch, const uint8_t* from,
+                                uint8_t* to);
+
+void AES_CTR_IV0_Transform(size_t keySize, const uint8_t* key,
+                           size_t howMuch, const uint8_t* from,
+                           uint8_t* to);
+
+#endif
diff --git a/sec/Security/SecOTRMathPrivate.h b/sec/Security/SecOTRMathPrivate.h
new file mode 100644 (file)
index 0000000..5084e5e
--- /dev/null
@@ -0,0 +1,121 @@
+//
+//  OTRMathPrivate.h
+//  libsecurity_libSecOTR
+//
+//  Created by Mitch Adler on 1/28/11.
+//  Copyright 2011 Apple Inc. All rights reserved.
+//
+
+#ifndef _OTRMATHPRIVATE_H_
+#define _OTRMATHPRIVATE_H_
+
+#include <Security/SecOTRMath.h>
+
+static const cc_unit kOTRGeneratorValue = 2;
+
+#define kOTRDHGroupUnits ccn_nof_size(sizeof(kOTRDHGroup))
+static const uint8_t kOTRDHGroup[] = {
+    0xFF, 0xFF, 0xFF, 0xFF,
+    0xFF, 0xFF, 0xFF, 0xFF,
+    0xC9, 0x0F, 0xDA, 0xA2,
+    0x21, 0x68, 0xC2, 0x34,
+    0xC4, 0xC6, 0x62, 0x8B,
+    0x80, 0xDC, 0x1C, 0xD1,
+    0x29, 0x02, 0x4E, 0x08,
+    0x8A, 0x67, 0xCC, 0x74,
+    0x02, 0x0B, 0xBE, 0xA6,
+    0x3B, 0x13, 0x9B, 0x22,
+    0x51, 0x4A, 0x08, 0x79,
+    0x8E, 0x34, 0x04, 0xDD,
+    0xEF, 0x95, 0x19, 0xB3,
+    0xCD, 0x3A, 0x43, 0x1B,
+    0x30, 0x2B, 0x0A, 0x6D,
+    0xF2, 0x5F, 0x14, 0x37,
+    0x4F, 0xE1, 0x35, 0x6D,
+    0x6D, 0x51, 0xC2, 0x45,
+    0xE4, 0x85, 0xB5, 0x76,
+    0x62, 0x5E, 0x7E, 0xC6,
+    0xF4, 0x4C, 0x42, 0xE9,
+    0xA6, 0x37, 0xED, 0x6B,
+    0x0B, 0xFF, 0x5C, 0xB6,
+    0xF4, 0x06, 0xB7, 0xED,
+    0xEE, 0x38, 0x6B, 0xFB,
+    0x5A, 0x89, 0x9F, 0xA5,
+    0xAE, 0x9F, 0x24, 0x11,
+    0x7C, 0x4B, 0x1F, 0xE6,
+    0x49, 0x28, 0x66, 0x51,
+    0xEC, 0xE4, 0x5B, 0x3D,
+    0xC2, 0x00, 0x7C, 0xB8,
+    0xA1, 0x63, 0xBF, 0x05,
+    0x98, 0xDA, 0x48, 0x36,
+    0x1C, 0x55, 0xD3, 0x9A,
+    0x69, 0x16, 0x3F, 0xA8,
+    0xFD, 0x24, 0xCF, 0x5F,
+    0x83, 0x65, 0x5D, 0x23,
+    0xDC, 0xA3, 0xAD, 0x96,
+    0x1C, 0x62, 0xF3, 0x56,
+    0x20, 0x85, 0x52, 0xBB,
+    0x9E, 0xD5, 0x29, 0x07,
+    0x70, 0x96, 0x96, 0x6D,
+    0x67, 0x0C, 0x35, 0x4E,
+    0x4A, 0xBC, 0x98, 0x04,
+    0xF1, 0x74, 0x6C, 0x08,
+    0xCA, 0x23, 0x73, 0x27,
+    0xFF, 0xFF, 0xFF, 0xFF,
+    0xFF, 0xFF, 0xFF, 0xFF
+};
+
+#define kOTRDHGroupRecipUnits ccn_nof_size(sizeof(kOTRDHGroup_Recip))
+static const uint8_t kOTRDHGroup_Recip[] = {
+    0x01, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x36, 0xF0, 0x25,
+    0x5D, 0xDE, 0x97, 0x3D,
+    0xCB, 0x47, 0x03, 0xCE,
+    0x7E, 0x2E, 0x81, 0x51,
+    0x97, 0xA6, 0xDB, 0x0F,
+    0x58, 0x84, 0x48, 0xB6,
+    0x11, 0x64, 0xCF, 0xCA,
+    0xC5, 0xF1, 0x87, 0x2E,
+    0x51, 0xB1, 0xF9, 0xFB,
+    0xB5, 0xBF, 0x16, 0xFB,
+    0xE7, 0x96, 0x89, 0xFC,
+    0x09, 0x03, 0xA8, 0x01,
+    0xE3, 0xD4, 0x80, 0x2F,
+    0xB8, 0xD3, 0x29, 0x55,
+    0x0D, 0xC8, 0xC9, 0xD3,
+    0xD9, 0x22, 0xEE, 0xCE,
+    0x9A, 0x54, 0x75, 0xDB,
+    0x33, 0xDB, 0x7B, 0x83,
+    0xBB, 0x5C, 0x0E, 0x13,
+    0xD1, 0x68, 0x04, 0x9B,
+    0xBC, 0x86, 0xC5, 0x81,
+    0x76, 0x47, 0xB0, 0x88,
+    0xD1, 0x7A, 0xA5, 0xCC,
+    0x40, 0xE0, 0x20, 0x35,
+    0x58, 0x8E, 0xDB, 0x2D,
+    0xE1, 0x89, 0x93, 0x41,
+    0x37, 0x19, 0xFC, 0x25,
+    0x8D, 0x79, 0xBC, 0x21,
+    0x7A, 0xC4, 0xB8, 0x73,
+    0x9C, 0xBE, 0xA0, 0x38,
+    0xAA, 0xA8, 0x8D, 0x0D,
+    0x2F, 0x78, 0xA7, 0x7A,
+    0x8A, 0x6F, 0xC7, 0xFA,
+    0xA8, 0xB2, 0xBD, 0xCA,
+    0x9B, 0xE7, 0x50, 0x2D,
+    0x2F, 0x5F, 0x6A, 0x7B,
+    0x65, 0xF5, 0xE4, 0xF0,
+    0x7A, 0xB8, 0xB2, 0x86,
+    0xE4, 0x11, 0x15, 0xF0,
+    0x24, 0xA6, 0xE9, 0x76,
+    0xBD, 0x2B, 0xCE, 0x3E,
+    0x51, 0x90, 0xB8, 0x91,
+    0xAB, 0xBF, 0x23, 0x31,
+    0xE9, 0xC9, 0x42, 0x97,
+    0x73, 0xF1, 0x15, 0xD2,
+    0x7D, 0x32, 0xC6, 0x95,
+    0xE0
+};
+
+#endif
diff --git a/sec/Security/SecOTRPacketData.c b/sec/Security/SecOTRPacketData.c
new file mode 100644 (file)
index 0000000..577ee05
--- /dev/null
@@ -0,0 +1,10 @@
+//
+//  SecOTRPacketData.c
+//  libsecurity_libSecOTR
+//
+//  Created by Mitch Adler on 2/26/11.
+//  Copyright 2011 Apple Inc. All rights reserved.
+//
+
+#include "SecOTRPacketData.h"
+
diff --git a/sec/Security/SecOTRPacketData.h b/sec/Security/SecOTRPacketData.h
new file mode 100644 (file)
index 0000000..3976967
--- /dev/null
@@ -0,0 +1,435 @@
+//
+//  SecOTRPacketData.h
+//  libsecurity_libSecOTR
+//
+//  Created by Mitch Adler on 2/26/11.
+//  Copyright 2011 Apple Inc. All rights reserved.
+//
+
+#ifndef _SECOTRPACKETDATA_H_
+#define _SECOTRPACKETDATA_H_
+
+#include <CoreFoundation/CFBase.h>
+#include <CoreFoundation/CFRuntime.h>
+#include <CoreFoundation/CFData.h>
+
+#include <corecrypto/ccn.h>
+
+#include <CommonCrypto/CommonDigest.h>
+
+#include <Security/SecBase.h>
+
+#include <utilities/SecCFWrappers.h>
+#include <Security/SecOTRPackets.h>
+
+#include <AssertMacros.h>
+
+__BEGIN_DECLS
+
+static OSStatus ReadAndVerifyByte(const uint8_t**bytes, size_t*size, uint8_t expected);
+static OSStatus ReadAndVerifyShort(const uint8_t**bytes, size_t*size, uint16_t expected);
+static OSStatus ReadAndVerifyMessageType(const uint8_t**bytes, size_t*size, OTRMessageType expected);
+
+static OSStatus SizeAndSkipDATA(const uint8_t **bytes, size_t *size,
+                                const uint8_t **dataBytes, size_t *dataSize);
+static OSStatus SizeAndSkipMPI(const uint8_t **bytes, size_t *size,
+                               const uint8_t **mpiBytes, size_t *mpiSize);
+
+    
+static OSStatus ReadLongLong(const uint8_t**bytesPtr, size_t*sizePtr, uint64_t* value);
+static OSStatus ReadLong(const uint8_t**bytesPtr, size_t*sizePtr, uint32_t* value);
+static OSStatus ReadShort(const uint8_t**bytesPtr, size_t*sizePtr, uint16_t* value);
+static OSStatus ReadByte(const uint8_t**bytesPtr, size_t*sizePtr, uint8_t* value);
+static OSStatus ReadMessageType(const uint8_t**bytesPtr, size_t*sizePtr, OTRMessageType* type);
+static OSStatus ReadMPI(const uint8_t**bytesPtr, size_t*sizePtr, cc_size n, cc_unit *x);
+static OSStatus ReadDATA(const uint8_t**bytesPtr, size_t*sizePtr, size_t* dataSize, uint8_t* data);
+static OSStatus CreatePublicKey(const uint8_t**bytesPtr, size_t*sizePtr, SecOTRPublicIdentityRef* publicId);
+static CFMutableDataRef CFDataCreateMutableFromOTRDATA(CFAllocatorRef allocator, const uint8_t**bytesPtr, size_t*sizePtr);
+    
+static void AppendLongLong(CFMutableDataRef appendTo, uint64_t value);
+static void AppendLong(CFMutableDataRef appendTo, uint32_t value);
+static void AppendShort(CFMutableDataRef appendTo, uint16_t value);
+static void AppendByte(CFMutableDataRef appendTo, uint8_t type);
+static void AppendMessageType(CFMutableDataRef appendTo, OTRMessageType type);
+static void AppendMPI(CFMutableDataRef appendTo, cc_size n, const cc_unit *x);
+static void AppendDATA(CFMutableDataRef appendTo, size_t size, const uint8_t*data);
+static void AppendPublicKey(CFMutableDataRef appendTo, SecOTRPublicIdentityRef publicId);
+
+    
+//
+// Inline implementation
+//
+
+static uint16_t kCurrentOTRVersion = 0x2;
+    
+static inline OSStatus ReadLongLong(const uint8_t**bytesPtr, size_t*sizePtr, uint64_t* value)
+{
+    require(bytesPtr != NULL, fail);
+    require(sizePtr != NULL, fail);
+    require(value != NULL, fail);
+    require(*sizePtr >= 4, fail);
+    
+    *value = ((uint64_t)(*bytesPtr)[0]) << 56 |
+             ((uint64_t)(*bytesPtr)[1]) << 48 |
+             ((uint64_t)(*bytesPtr)[2]) << 40 |
+             ((uint64_t)(*bytesPtr)[3]) << 32 |
+             ((uint64_t)(*bytesPtr)[4]) << 24 |
+             ((uint64_t)(*bytesPtr)[5]) << 16 |
+             ((uint64_t)(*bytesPtr)[6]) << 8  |
+             ((uint64_t)(*bytesPtr)[7]) << 0;
+    
+    *bytesPtr += 8;
+    *sizePtr -= 8;
+    
+    return errSecSuccess;
+fail:
+    return errSecParam;
+}
+
+static inline OSStatus ReadLong(const uint8_t**bytesPtr, size_t*sizePtr, uint32_t* value)
+{
+    require(bytesPtr != NULL, fail);
+    require(sizePtr != NULL, fail);
+    require(value != NULL, fail);
+    require(*sizePtr >= 4, fail);
+    
+    *value = (uint32_t)(*bytesPtr)[0] << 24 |
+    (uint32_t)(*bytesPtr)[1] << 16 |
+    (uint32_t)(*bytesPtr)[2] << 8  |
+    (uint32_t)(*bytesPtr)[3] << 0;
+    
+    *bytesPtr += 4;
+    *sizePtr -= 4;
+    
+    return errSecSuccess;
+fail:
+    return errSecParam;
+}
+    
+static inline OSStatus ReadShort(const uint8_t**bytesPtr, size_t*sizePtr, uint16_t* value)
+{
+    require(bytesPtr != NULL, fail);
+    require(sizePtr != NULL, fail);
+    require(value != NULL, fail);
+    require(*sizePtr >= 2, fail);
+    
+    *value = (*bytesPtr)[0] << 8  |
+    (*bytesPtr)[1] << 0;
+    
+    *bytesPtr += 2;
+    *sizePtr -= 2;
+    
+    return errSecSuccess;
+fail:
+    return errSecParam;
+}
+
+static inline OSStatus ReadByte(const uint8_t**bytesPtr, size_t*sizePtr, uint8_t* value)
+{
+    require(bytesPtr != NULL, fail);
+    require(sizePtr != NULL, fail);
+    require(value != NULL, fail);
+    require(*sizePtr >= 1, fail);
+    
+    *value = *bytesPtr[0];
+    
+    *bytesPtr += 1;
+    *sizePtr -= 1;
+    
+    return errSecSuccess;
+fail:
+    return errSecParam;
+}
+    
+static inline OSStatus ReadMessageType(const uint8_t**bytesPtr, size_t*sizePtr, OTRMessageType* type)
+{
+    OSStatus result = errSecParam;
+    uint8_t value;
+
+    require(type != NULL, fail);
+    require_noerr(result = ReadByte(bytesPtr, sizePtr, &value), fail);
+    
+    *type = value;
+fail:
+    return result;
+}
+
+static inline OSStatus ReadMPI(const uint8_t**bytesPtr, size_t*sizePtr, cc_size n, cc_unit *x)
+{
+    require(bytesPtr != NULL, fail);
+    require(sizePtr != NULL, fail);
+    require(x != NULL, fail);
+    require(*sizePtr >= 5, fail);
+    
+    uint32_t mpiLength;
+    
+    ReadLong(bytesPtr, sizePtr, &mpiLength);
+    
+    require(mpiLength <= *sizePtr, fail);
+    
+    ccn_read_uint(n, x, mpiLength, *bytesPtr);
+    
+    *bytesPtr += mpiLength;
+    *sizePtr -= mpiLength;
+    
+    return errSecSuccess;
+fail:
+    return errSecParam;
+    
+}
+    
+static inline OSStatus ReadDATA(const uint8_t**bytesPtr, size_t*sizePtr, size_t* dataSize, uint8_t* data)
+{
+    require(bytesPtr != NULL, fail);
+    require(sizePtr != NULL, fail);
+    require(data != NULL, fail);
+    require(*sizePtr >= 5, fail);
+    
+    uint32_t dataLength;
+    
+    ReadLong(bytesPtr, sizePtr, &dataLength);
+    
+    require(dataLength <= *sizePtr, fail);
+    memmove(data, bytesPtr, dataLength);
+    
+    *bytesPtr += dataLength;
+    *sizePtr -= dataLength;
+    
+    *dataSize = dataLength;
+    
+    return errSecSuccess;
+fail:
+    return errSecParam;
+    
+}
+    
+static inline OSStatus CreatePublicKey(const uint8_t**bytesPtr, size_t*sizePtr, SecOTRPublicIdentityRef* publicId)
+{
+    require(bytesPtr != NULL, fail);
+    require(sizePtr != NULL, fail);
+    require(publicId != NULL, fail);
+    require(*sizePtr >= 7, fail);
+
+    uint16_t type = 0;
+    ReadShort(bytesPtr, sizePtr, &type);
+
+    require(type == 0xF000, fail);
+    require(*sizePtr >= 5, fail);
+    
+    uint32_t serializedIDLength = 0;
+    ReadLong(bytesPtr, sizePtr, &serializedIDLength);
+    
+    require(*sizePtr >= serializedIDLength, fail);
+    require(((CFIndex)serializedIDLength) >= 0, fail);
+    
+    CFDataRef serializedBytes = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, *bytesPtr, (CFIndex)serializedIDLength, kCFAllocatorNull);
+    
+    *publicId = SecOTRPublicIdentityCreateFromData(kCFAllocatorDefault, serializedBytes, NULL);
+    
+    *bytesPtr += serializedIDLength;
+    *sizePtr -= serializedIDLength;
+    
+    CFReleaseNull(serializedBytes);
+    
+    return errSecSuccess;
+fail:
+    return errSecParam;
+    
+}
+    
+static inline CFMutableDataRef CFDataCreateMutableFromOTRDATA(CFAllocatorRef allocator, const uint8_t**bytesPtr, size_t*sizePtr)
+{
+    CFMutableDataRef result = NULL;
+    uint32_t sizeInStream;
+    require_noerr(ReadLong(bytesPtr, sizePtr, &sizeInStream), exit);
+    require(sizeInStream <= *sizePtr, exit);
+    require(((CFIndex)sizeInStream) >= 0, exit);
+    
+    result = CFDataCreateMutable(allocator, 0);
+    
+    CFDataAppendBytes(result, *bytesPtr, (CFIndex)sizeInStream);
+    
+    *bytesPtr += sizeInStream;
+    *sizePtr += sizeInStream;
+    
+exit:
+    return result;
+}
+
+
+//
+// Parse and verify functions
+//
+static inline OSStatus ReadAndVerifyByte(const uint8_t**bytes, size_t*size, uint8_t expected)
+{
+    uint8_t found;
+    OSStatus result = ReadByte(bytes, size, &found);
+    require_noerr(result, exit);
+    require_action(found == expected, exit, result = errSecDecode);
+exit:
+    return result;
+}
+
+static inline OSStatus ReadAndVerifyShort(const uint8_t**bytes, size_t*size, uint16_t expected)
+{
+    uint16_t found;
+    OSStatus result = ReadShort(bytes, size, &found);
+    require_noerr(result, exit);
+    require_action(found == expected, exit, result = errSecDecode);
+exit:
+    return result;
+}
+
+static inline OSStatus ReadAndVerifyMessageType(const uint8_t**bytes, size_t*size, OTRMessageType expected)
+{
+    OTRMessageType found;
+    OSStatus result = ReadMessageType(bytes, size, &found);
+    require_noerr(result, exit);
+    require_action(found == expected, exit, result = errSecDecode);
+exit:
+    return result;
+}
+
+static inline OSStatus ReadAndVerifyVersion(const uint8_t**bytes, size_t*size)
+{
+    return ReadAndVerifyShort(bytes, size, kCurrentOTRVersion);
+}
+
+static inline OSStatus ReadAndVerifyHeader(const uint8_t**bytes, size_t*size, OTRMessageType expected)
+{
+    OSStatus result = ReadAndVerifyVersion(bytes, size);
+    require_noerr(result, exit);
+    
+    result = ReadAndVerifyMessageType(bytes, size, expected);
+    require_noerr(result, exit);
+    
+exit:
+    return result;
+}
+
+static inline OSStatus ReadHeader(const uint8_t**bytes, size_t*size, OTRMessageType *messageType)
+{
+    OSStatus result = ReadAndVerifyVersion(bytes, size);
+    require_noerr(result, exit);
+    
+    result = ReadMessageType(bytes, size, messageType);
+    require_noerr(result, exit);
+    
+exit:
+    return result;
+}
+
+static inline OSStatus SizeAndSkipDATA(const uint8_t **bytes, size_t *size,
+                                const uint8_t **dataBytes, size_t *dataSize)
+{
+    OSStatus result;
+    uint32_t sizeRead;
+    result = ReadLong(bytes, size, &sizeRead);
+    
+    require_noerr(result, exit);
+    require_action(sizeRead <= *size, exit, result = errSecDecode);
+    
+    *dataSize = sizeRead;
+    *dataBytes = *bytes;
+    *bytes += sizeRead;
+    *size -= sizeRead;
+exit:
+    return result;
+}
+
+static inline OSStatus SizeAndSkipMPI(const uint8_t **bytes, size_t *size,
+                               const uint8_t **mpiBytes, size_t *mpiSize)
+{
+    // MPIs looke like data for skipping.
+    return SizeAndSkipDATA(bytes, size, mpiBytes, mpiSize);
+}
+
+    
+//
+// Appending functions
+//
+static inline void AppendLongLong(CFMutableDataRef appendTo, uint64_t value)
+{
+    uint8_t bigEndian[sizeof(value)] = { value >> 56, value >> 48, value >> 40, value >> 32,
+                                         value >> 24, value >> 16, value >> 8 , value >> 0  };
+    
+    CFDataAppendBytes(appendTo, bigEndian, sizeof(bigEndian));
+}
+
+static inline void AppendLong(CFMutableDataRef appendTo, uint32_t value)
+{
+    uint8_t bigEndian[sizeof(value)] = { value >> 24, value >> 16, value >> 8, value };
+    
+    CFDataAppendBytes(appendTo, bigEndian, sizeof(bigEndian));
+}
+
+static inline void AppendShort(CFMutableDataRef appendTo, uint16_t value)
+{
+    uint8_t bigEndian[sizeof(value)] = { value >> 8, value };
+    
+    CFDataAppendBytes(appendTo, bigEndian, sizeof(bigEndian));
+}
+
+static inline void AppendByte(CFMutableDataRef appendTo, uint8_t byte)
+{
+    CFDataAppendBytes(appendTo, &byte, 1);
+}
+
+static inline void AppendMessageType(CFMutableDataRef appendTo, OTRMessageType type)
+{
+    AppendByte(appendTo, type);
+}
+
+static inline void AppendMPI(CFMutableDataRef appendTo, cc_size n, const cc_unit *x)
+{
+    size_t size = ccn_write_uint_size(n, x);
+    /* 64 bits cast: we are appending an identity, whose size is hardcoded and less then 2^32 bytes */
+    /* Worst case is we encoded a truncated length. No security issue. */
+    assert(size<UINT32_MAX); /* Debug check */
+    AppendLong(appendTo, (uint32_t)size);
+    assert(((CFIndex)size) >= 0);
+    uint8_t* insertionPtr = CFDataIncreaseLengthAndGetMutableBytes(appendTo, (CFIndex)size);
+    ccn_write_uint(n, x, size, insertionPtr);
+}
+
+static inline void AppendDATA(CFMutableDataRef appendTo, size_t size, const uint8_t*data)
+{
+    /* 64 bits cast: we are appending Public Key or Signature, whose sizes are hardcoded and less then 2^32 bytes */
+    /* Worst case is we encoded a truncated length. No security issue. */
+    assert(size<=UINT32_MAX); /* Debug check */
+    AppendLong(appendTo, (uint32_t)size);
+    assert(((CFIndex)size) >= 0);
+    CFDataAppendBytes(appendTo, data, (CFIndex)size);
+}
+    
+static inline void AppendCFDataAsDATA(CFMutableDataRef appendTo, CFDataRef dataToAppend)
+{
+    AppendDATA(appendTo, (size_t)CFDataGetLength(dataToAppend), CFDataGetBytePtr(dataToAppend));
+}
+
+static inline void AppendPublicKey(CFMutableDataRef appendTo, SecOTRPublicIdentityRef publicId)
+{
+    AppendShort(appendTo, 0xF000); // Custom type reserved by no one
+    
+    CFMutableDataRef serializedID = CFDataCreateMutable(kCFAllocatorDefault, 0);
+
+    SecOTRPIAppendSerialization(publicId, serializedID, NULL);
+    AppendDATA(appendTo, (size_t)CFDataGetLength(serializedID), CFDataGetBytePtr(serializedID));
+    
+    CFReleaseNull(serializedID);
+}
+
+static inline void AppendVersion(CFMutableDataRef appendTo)
+{
+    AppendShort(appendTo, kCurrentOTRVersion);
+}
+
+static inline void AppendHeader(CFMutableDataRef appendTo, OTRMessageType type)
+{
+    AppendVersion(appendTo);
+    AppendMessageType(appendTo, type);
+}
+
+__END_DECLS
+
+#endif
diff --git a/sec/Security/SecOTRPackets.c b/sec/Security/SecOTRPackets.c
new file mode 100644 (file)
index 0000000..f13d967
--- /dev/null
@@ -0,0 +1,264 @@
+//
+//  SecOTRPackets.c
+//  libsecurity_libSecOTR
+//
+//  Created by Mitch Adler on 2/23/11.
+//  Copyright 2011 Apple Inc. All rights reserved.
+//
+
+#include "SecOTRSessionPriv.h"
+#include "SecOTRPackets.h"
+
+#include "SecOTR.h"
+#include "SecOTRIdentityPriv.h"
+
+//*****************************************#include "SecCFWrappers.h"
+#include "SecOTRPacketData.h"
+#include "SecOTRDHKey.h"
+
+#ifdef USECOMMONCRYPTO
+#include <CommonCrypto/CommonHMAC.h>
+#endif
+
+#include <corecrypto/ccn.h>
+#include <corecrypto/ccdigest.h>
+
+#include <corecrypto/ccaes.h>
+#include <corecrypto/ccmode.h>
+#include <corecrypto/ccmode_factory.h>
+#include <corecrypto/cchmac.h>
+#include <corecrypto/ccsha2.h>
+
+//
+// Crypto functions
+//
+
+static inline void AppendSHA256HMAC(CFMutableDataRef appendTo,
+                                    size_t keybytes,
+                                    const uint8_t* key,
+                                    size_t howMuch,
+                                    const uint8_t* from)
+{
+    uint8_t *to = CFDataIncreaseLengthAndGetMutableBytes(appendTo, CCSHA256_OUTPUT_SIZE);
+    
+#ifdef USECOMMONCRYPTO
+    CCHmac(kCCHmacAlgSHA256, key, keybytes, from, howMuch, to);
+#else
+    cchmac(ccsha256_di(), keybytes, key, howMuch, from, to);
+#endif
+}
+
+// First 160 bits of the HMAC
+static inline void AppendSHA256HMAC_160(CFMutableDataRef appendTo,
+                                    size_t keySize,
+                                    const uint8_t* key,
+                                    size_t howMuch,
+                                    const uint8_t* from)
+{
+    AppendSHA256HMAC(appendTo, keySize, key, howMuch, from);
+    const CFIndex bytesToRemove = CCSHA256_OUTPUT_SIZE - kSHA256HMAC160Bytes;
+    const CFRange rangeToDelete = CFRangeMake(CFDataGetLength(appendTo) - bytesToRemove, bytesToRemove);
+    
+    CFDataDeleteBytes(appendTo, rangeToDelete);
+}
+
+static inline void DeriveAndAppendSHA256HMAC(CFMutableDataRef appendTo,
+                                             cc_size sN,
+                                             const cc_unit* s,
+                                             KeyType whichKey,
+                                             size_t howMuch,
+                                             const uint8_t* from)
+{
+    size_t localKeySize = CCSHA256_OUTPUT_SIZE;
+    uint8_t localKey[localKeySize];
+    
+    DeriveOTR256BitsFromS(whichKey, sN, s, localKeySize, localKey);
+    
+    AppendSHA256HMAC(appendTo, localKeySize, localKey, howMuch, from);
+    
+    bzero(localKey, localKeySize);
+}
+
+static inline void DeriveAndAppendSHA256HMAC_160(CFMutableDataRef appendTo,
+                                                 cc_size sN,
+                                                 const cc_unit* s,
+                                                 KeyType whichKey,
+                                                 size_t howMuch,
+                                                 const uint8_t* from)
+{
+    size_t localKeySize = CCSHA256_OUTPUT_SIZE;
+    uint8_t localKey[localKeySize];
+    
+    DeriveOTR256BitsFromS(whichKey, sN, s, localKeySize, localKey);
+    
+    AppendSHA256HMAC_160(appendTo, localKeySize, localKey, howMuch, from);
+    
+    bzero(localKey, sizeof(localKey));
+}
+
+//
+// Message creators
+//
+
+void SecOTRAppendDHMessage(SecOTRSessionRef session,
+                           CFMutableDataRef appendTo)
+{
+    //
+    // Message Type: kDHMessage (0x02)
+    // AES_CTR(r, 0) of G^X MPI
+    // SHA256(gxmpi)
+    //
+    
+    if(!session) return;
+    CFMutableDataRef gxmpi = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    if(!gxmpi) return;
+
+    AppendHeader(appendTo, kDHMessage);
+
+    SecFDHKAppendPublicSerialization(session->_myKey, gxmpi);
+
+    size_t gxmpiSize = (size_t)CFDataGetLength(gxmpi);
+    if(gxmpiSize == 0) {
+        CFReleaseNull(gxmpi);
+        return;
+    }
+    const uint8_t* gxmpiLocation = CFDataGetBytePtr(gxmpi);
+
+    /* 64 bits cast: gxmpiSize is the size of the EC public key, which is hardcoded and never more than 2^32 bytes. */
+    assert(gxmpiSize<UINT32_MAX); /* debug check only */
+    AppendLong(appendTo, (uint32_t)gxmpiSize);
+    assert(gxmpiSize<INT32_MAX);
+    uint8_t* encGxmpiLocation = CFDataIncreaseLengthAndGetMutableBytes(appendTo, (CFIndex)gxmpiSize);
+    AES_CTR_IV0_Transform(sizeof(session->_r), session->_r, gxmpiSize, gxmpiLocation, encGxmpiLocation);
+    
+    AppendLong(appendTo, CCSHA256_OUTPUT_SIZE);
+    uint8_t* hashLocation = CFDataIncreaseLengthAndGetMutableBytes(appendTo, CCSHA256_OUTPUT_SIZE);
+
+#ifdef USECOMMONCRYPTO
+    (void) CC_SHA256(gxmpiLocation, (uint32_t)gxmpiSize, hashLocation);
+#else
+    ccdigest(ccsha256_di(), gxmpiSize, gxmpiLocation, hashLocation);
+#endif
+    CFReleaseNull(gxmpi);
+}
+
+void SecOTRAppendDHKeyMessage(SecOTRSessionRef session,
+                              CFMutableDataRef appendTo)
+{
+    //
+    // Message Type: kDHKeyMessage (0x0A)
+    // G^X Data MPI
+    //
+    
+    AppendHeader(appendTo, kDHKeyMessage);
+    SecFDHKAppendPublicSerialization(session->_myKey, appendTo);
+}
+
+static uint8_t* AppendEncryptedSignature(SecOTRSessionRef session,
+                                         const cc_unit* s,
+                                         bool usePrime,
+                                         CFMutableDataRef appendTo)
+{
+    CFMutableDataRef signature = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    CFMutableDataRef mbData = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    CFMutableDataRef mb = CFDataCreateMutable(kCFAllocatorDefault, 0);
+
+    SecFDHKAppendPublicSerialization(session->_myKey, mbData);
+    SecPDHKAppendSerialization(session->_theirKey, mbData);
+    
+    CFIndex publicKeyOffset = CFDataGetLength(mbData);
+
+    SecOTRPublicIdentityRef myPublic = SecOTRPublicIdentityCopyFromPrivate(kCFAllocatorDefault, session->_me, NULL);
+    AppendPublicKey(mbData, myPublic);
+    CFReleaseNull(myPublic);
+
+    AppendLong(mbData, session->_keyID);
+    
+    DeriveAndAppendSHA256HMAC(mb,
+                              kExponentiationUnits, s,
+                              usePrime ? kM1Prime : kM1,
+                              (size_t)CFDataGetLength(mbData), CFDataGetBytePtr(mbData));
+    
+    CFDataDeleteBytes(mbData, CFRangeMake(0, publicKeyOffset));
+
+    CFMutableDataRef xb = mbData; mbData = NULL;
+    SecOTRFIAppendSignature(session->_me, mb, signature, NULL);
+    CFReleaseNull(mb);
+
+    AppendCFDataAsDATA(xb, signature);
+    CFReleaseNull(signature);
+
+    CFIndex dataLength = CFDataGetLength(xb);
+
+    CFIndex signatureStartIndex = CFDataGetLength(appendTo);
+    /* 64 bits cast: We are appending the signature we just generated, which is never bigger than 2^32 bytes. */
+    assert(((unsigned long)dataLength)<=UINT32_MAX); /* debug check, correct as long as CFIndex is a signed long */
+    AppendLong(appendTo, (uint32_t)dataLength);
+    uint8_t *destination = CFDataIncreaseLengthAndGetMutableBytes(appendTo, dataLength);
+
+    uint8_t c[kOTRAuthKeyBytes];
+    DeriveOTR128BitPairFromS(kCs, kExponentiationUnits, s,
+                             sizeof(c), usePrime ? NULL : c,
+                             sizeof(c), usePrime ? c : NULL);
+
+    AES_CTR_IV0_Transform(sizeof(c), c,
+                          (size_t)dataLength, CFDataGetBytePtr(xb),
+                          destination);
+    bzero(c, sizeof(c));
+    CFReleaseNull(xb);
+    
+    return CFDataGetMutableBytePtr(appendTo) + signatureStartIndex;
+}
+
+
+static void AppendMACedEncryptedSignature(SecOTRSessionRef session,
+                                          bool usePrime,
+                                          CFMutableDataRef appendTo)
+{
+    
+    cc_unit s[kExponentiationUnits];
+    
+    SecPDHKeyGenerateS(session->_myKey, session->_theirKey, s);
+
+    CFIndex signatureStartOffset = CFDataGetLength(appendTo);
+    const uint8_t *signatureStart = AppendEncryptedSignature(session, s, usePrime, appendTo);
+    size_t signatureSize = (size_t)CFDataGetLength(appendTo) - (size_t)signatureStartOffset;
+    
+    
+    DeriveAndAppendSHA256HMAC_160(appendTo,
+                                  kExponentiationUnits, s,
+                                  usePrime ? kM2Prime : kM2,
+                                  signatureSize, signatureStart);
+    bzero(s, sizeof(s));
+}
+
+
+void SecOTRAppendRevealSignatureMessage(SecOTRSessionRef session,
+                                        CFMutableDataRef appendTo)
+{
+    //
+    // Message Type: kRevealSignatureMessage (0x11)
+    // G^X Data MPI
+    //
+    
+    AppendHeader(appendTo, kRevealSignatureMessage);
+    
+    AppendLong(appendTo, kOTRAuthKeyBytes);
+    uint8_t* keyPosition = CFDataIncreaseLengthAndGetMutableBytes(appendTo, kOTRAuthKeyBytes);
+    memcpy(keyPosition, session->_r, kOTRAuthKeyBytes);
+    
+    AppendMACedEncryptedSignature(session, false, appendTo);
+}
+
+void SecOTRAppendSignatureMessage(SecOTRSessionRef session,
+                                        CFMutableDataRef appendTo)
+{
+    //
+    // Message Type: kSignatureMessage (0x12)
+    // G^X Data MPI
+    //
+    
+    AppendHeader(appendTo, kSignatureMessage);
+    AppendMACedEncryptedSignature(session, true, appendTo);
+}
+
diff --git a/sec/Security/SecOTRPackets.h b/sec/Security/SecOTRPackets.h
new file mode 100644 (file)
index 0000000..09a81ad
--- /dev/null
@@ -0,0 +1,31 @@
+//
+//  SecOTRPackets.h
+//  libsecurity_libSecOTR
+//
+//  Created by Mitch Adler on 2/23/11.
+//  Copyright 2011 Apple Inc. All rights reserved.
+//
+
+#include <Security/SecOTRSession.h>
+
+#include <CoreFoundation/CFData.h>
+
+#ifndef _SECOTRPACKETS_H_
+#define _SECOTRPACKETS_H_
+
+void SecOTRAppendDHMessage(SecOTRSessionRef session, CFMutableDataRef appendTo);
+void SecOTRAppendDHKeyMessage(SecOTRSessionRef session, CFMutableDataRef appendTo);
+void SecOTRAppendRevealSignatureMessage(SecOTRSessionRef session, CFMutableDataRef appendTo);
+void SecOTRAppendSignatureMessage(SecOTRSessionRef session, CFMutableDataRef appendTo);
+
+typedef enum {
+    kDHMessage = 0x02,
+    kDataMessage = 0x03,
+    kDHKeyMessage = 0x0A,
+    kRevealSignatureMessage = 0x11,
+    kSignatureMessage = 0x12,
+    
+    kInvalidMessage = 0xFF
+} OTRMessageType;
+
+#endif
diff --git a/sec/Security/SecOTRPublicIdentity.c b/sec/Security/SecOTRPublicIdentity.c
new file mode 100644 (file)
index 0000000..e37c7ef
--- /dev/null
@@ -0,0 +1,352 @@
+/*
+ *  SecOTRPublicIdentity.c
+ *  libsecurity_libSecOTR
+ *
+ *  Created by Mitch Adler on 2/9/11.
+ *  Copyright 2011 Apple Inc. All rights reserved.
+ *
+ */
+
+#include "SecOTR.h"
+#include "SecOTRIdentityPriv.h"
+#include <utilities/SecCFWrappers.h>
+
+#include <AssertMacros.h>
+
+#include <CoreFoundation/CFNumber.h>
+#include <CoreFoundation/CFString.h>
+#include <CoreFoundation/CFData.h>
+
+#include <Security/SecKey.h>
+#include <Security/SecKeyPriv.h>
+
+#include <corecrypto/ccn.h>
+#include <corecrypto/ccec.h>
+#include <corecrypto/ccder.h>
+
+#import <sys/syslog.h>
+
+#include "SecOTRErrors.h"
+#include <TargetConditionals.h>
+
+#include <CommonCrypto/CommonDigest.h>
+#include <CommonCrypto/CommonDigestSPI.h>
+
+/* 
+ * Support for encoding and decoding DH parameter blocks.
+ * Apple form encodes the reciprocal of the prime p.
+ */
+
+enum {
+    kOTRPIDER_SigningID = 1,
+    kOTRPIDER_SupportsHashes =3,
+};
+
+//
+// SecOTRPublicIdentity implementation
+//
+
+CFGiblisFor(SecOTRPublicIdentity);
+
+static bool sAdvertiseHashes = false;
+
+static CF_RETURNS_RETAINED CFStringRef SecOTRPublicIdentityCopyDescription(CFTypeRef cf) {
+    SecOTRPublicIdentityRef requestor = (SecOTRPublicIdentityRef)cf;
+   return CFStringCreateWithFormat(kCFAllocatorDefault,NULL,CFSTR("<SecOTRPublicIdentity: %p %02x%02x%02x%02x%02x%02x%02x%02x>"),
+                                    requestor,
+                                    requestor->hash[0], requestor->hash[1],
+                                    requestor->hash[2], requestor->hash[3],
+                                    requestor->hash[4], requestor->hash[5],
+                                    requestor->hash[6], requestor->hash[7]);
+}
+
+static void SecOTRPublicIdentityDestroy(CFTypeRef cf) {
+    SecOTRPublicIdentityRef requestor = (SecOTRPublicIdentityRef)cf;
+    
+    CFReleaseNull(requestor->publicSigningKey);
+}
+
+static bool SecKeyDigestAndVerifyWithError(
+                                           SecKeyRef           key,            /* Public key */
+                                           const SecAsn1AlgId  *algId,         /* algorithm oid/params */
+                                           const uint8_t       *dataToDigest,  /* signature over this data */
+                                           size_t              dataToDigestLen,/* length of dataToDigest */
+                                           uint8_t             *sig,                   /* signature to verify */
+                                           size_t              sigLen,         /* length of sig */
+                                           CFErrorRef          *error) {
+    
+    OSStatus status = SecKeyDigestAndVerify(key, algId, dataToDigest, dataToDigestLen, sig, sigLen);
+    require_noerr(status, fail);
+    return true;
+fail:
+    SecOTRCreateError(secOTRErrorOSError, status, CFSTR("Error verifying message. OSStatus in error code."), NULL, error);
+    return false;
+}
+
+static bool SecOTRPICacheHash(SecOTRPublicIdentityRef pubID, CFErrorRef *error)
+{
+    bool result = false;
+    
+    CFMutableDataRef stream = CFDataCreateMutable(NULL, 0);
+
+    require(SecOTRPIAppendSerialization(pubID, stream, error), fail);
+
+    CCDigest(kCCDigestSHA1, CFDataGetBytePtr(stream), (CC_LONG)CFDataGetLength(stream), pubID->hash);
+    
+    result = true;
+
+fail:
+    CFReleaseSafe(stream);
+    return result;
+}
+
+void SecOTRAdvertiseHashes(bool advertise) {
+    sAdvertiseHashes = advertise;
+}
+
+SecOTRPublicIdentityRef SecOTRPublicIdentityCopyFromPrivate(CFAllocatorRef allocator, SecOTRFullIdentityRef fullID, CFErrorRef *error)
+{
+    SecOTRPublicIdentityRef result = CFTypeAllocate(SecOTRPublicIdentity, struct _SecOTRPublicIdentity, allocator);
+
+    EnsureOTRAlgIDInited();
+
+    result->publicSigningKey = fullID->publicSigningKey;
+    CFRetain(result->publicSigningKey);
+    
+    require(SecOTRPICacheHash(result, error), fail);
+
+    return result;
+
+fail:
+    CFReleaseSafe(result);
+    return NULL;
+}
+
+
+SecOTRPublicIdentityRef SecOTRPublicIdentityCreateFromSecKeyRef(CFAllocatorRef allocator, SecKeyRef publicKey,
+                                                            CFErrorRef *error) {
+    // TODO - make sure this is an appropriate key type
+    SecOTRPublicIdentityRef result = CFTypeAllocate(SecOTRPublicIdentity, struct _SecOTRPublicIdentity, allocator);
+    result->publicSigningKey = publicKey;
+    CFRetain(result->publicSigningKey);
+    require(SecOTRPICacheHash(result, error), fail);
+    return result;
+fail:
+    CFRelease(result->publicSigningKey);
+    CFReleaseSafe(result);
+    return NULL;
+}
+
+typedef SecKeyRef (*SecOTRPublicKeyCreateFunction)(CFAllocatorRef allocator, const uint8_t** data, size_t* limit);
+
+static SecKeyRef SecOTRCreatePublicKeyFrom(const uint8_t* keyData, size_t keyDataSize, ccder_tag tagContainingKey, SecOTRPublicKeyCreateFunction createFunction)
+{
+    SecKeyRef createdKey = NULL;
+    
+    createdKey = createFunction(kCFAllocatorDefault, &keyData, &keyDataSize);
+    
+    require(createdKey != NULL, fail);
+    require(keyDataSize == 0, fail);
+
+    return createdKey;
+
+fail:
+    CFReleaseSafe(createdKey);
+    return NULL;
+}
+                                          
+
+SecOTRPublicIdentityRef SecOTRPublicIdentityCreateFromBytes(CFAllocatorRef allocator, const uint8_t**bytes, size_t* size, CFErrorRef *error)
+{
+    CFErrorRef stackedError = NULL;
+    
+    SecOTRPublicIdentityRef newID = CFTypeAllocate(SecOTRPublicIdentity, struct _SecOTRPublicIdentity, allocator);
+    
+    EnsureOTRAlgIDInited();
+    
+    const uint8_t* fullSequenceEnd = *bytes + *size;
+
+    const uint8_t* keyData = ccder_decode_sequence_tl(&fullSequenceEnd, *bytes, fullSequenceEnd);
+    size_t fullSize = (size_t)(fullSequenceEnd - *bytes);
+    
+    size_t   keyDataSize;
+    keyData = ccder_decode_tl(CCDER_CONTEXT_SPECIFIC | kOTRPIDER_SigningID, &keyDataSize, keyData, fullSequenceEnd);
+    newID->publicSigningKey = SecOTRCreatePublicKeyFrom(keyData, keyDataSize, kOTRPIDER_SigningID, &CreateECPublicKeyFrom);
+    require(newID->publicSigningKey != NULL, fail);
+    keyData += keyDataSize;
+    
+    newID->wantsHashes = (NULL != ccder_decode_tl(CCDER_CONTEXT_SPECIFIC | kOTRPIDER_SupportsHashes, &keyDataSize, keyData, fullSequenceEnd));
+
+    require(SecOTRPICacheHash(newID, &stackedError), fail);
+    
+    *bytes += fullSize;
+    *size -= fullSize;
+
+    return newID;
+    
+fail:
+    SecOTRCreateError(secOTRErrorLocal, kSecOTRErrorCreatePublicIdentity, CFSTR("Error creating public identity from bytes"), stackedError, error);
+    CFReleaseSafe(newID);
+    return NULL;
+}
+
+SecOTRPublicIdentityRef SecOTRPublicIdentityCreateFromData(CFAllocatorRef allocator, CFDataRef serializedData, CFErrorRef *error)
+{
+    if (serializedData == NULL)
+        return NULL;
+
+    size_t length = (size_t)CFDataGetLength(serializedData);
+    const uint8_t* bytes = CFDataGetBytePtr(serializedData);
+    return SecOTRPublicIdentityCreateFromBytes(allocator, &bytes, &length, error);
+}
+
+bool SecOTRPIEqualToBytes(SecOTRPublicIdentityRef id, const uint8_t*bytes, CFIndex size)
+{
+    CFDataRef dataToMatch = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, bytes, size, kCFAllocatorNull);
+    CFMutableDataRef idStreamed = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    
+    SecOTRPIAppendSerialization(id, idStreamed, NULL);
+    
+    bool equal = CFEqualSafe(dataToMatch, idStreamed);
+    
+    CFReleaseNull(dataToMatch);
+    CFReleaseNull(idStreamed);
+    
+    return equal;
+}
+
+bool SecOTRPIEqual(SecOTRPublicIdentityRef left, SecOTRPublicIdentityRef right)
+{
+    if (left == right)
+        return true;
+
+    CFMutableDataRef leftData = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    CFMutableDataRef rightData = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    
+    SecOTRPIAppendSerialization(left, leftData, NULL);
+    SecOTRPIAppendSerialization(right, rightData, NULL);
+    
+    bool match = CFEqualSafe(leftData, rightData);
+    
+    CFReleaseNull(leftData);
+    CFReleaseNull(rightData);
+    
+    return match;
+}
+
+size_t SecOTRPISignatureSize(SecOTRPublicIdentityRef publicID)
+{
+    return SecKeyGetSize(publicID->publicSigningKey, kSecKeySignatureSize);
+}
+
+bool SecOTRPIAppendSerialization(SecOTRPublicIdentityRef publicID, CFMutableDataRef serializeInto, CFErrorRef *error)
+{
+    CFIndex start = CFDataGetLength(serializeInto);
+    
+    CFMutableDataRef signingKeySerialized = NULL;
+
+    signingKeySerialized = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    
+    uint8_t outputBuffer[16384];
+    uint8_t* outputBufferEnd = outputBuffer + sizeof(outputBuffer);
+    
+    uint8_t sendHashes[1];
+    sendHashes[0] = 0xFF;
+
+    require_noerr(appendPublicOctetsAndSize(publicID->publicSigningKey, signingKeySerialized), fail);
+
+    uint8_t *result = ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, outputBufferEnd, outputBuffer,
+        ccder_encode_implicit_raw_octet_string(CCDER_CONTEXT_SPECIFIC | kOTRPIDER_SigningID, (size_t)CFDataGetLength(signingKeySerialized), CFDataGetBytePtr(signingKeySerialized), outputBuffer,
+        sAdvertiseHashes ? ccder_encode_implicit_raw_octet_string(CCDER_CONTEXT_SPECIFIC | kOTRPIDER_SupportsHashes, sizeof(sendHashes), sendHashes, outputBuffer, outputBufferEnd) : outputBufferEnd));
+    
+    CFDataAppendBytes(serializeInto, result, outputBufferEnd - result);
+    
+    CFReleaseSafe(signingKeySerialized);
+
+    return true;
+    
+fail:
+    CFReleaseSafe(signingKeySerialized);
+    
+    CFDataSetLength(serializeInto, start);
+    
+    SecOTRCreateError(secOTRErrorLocal, kSecOTRErrorCreatePublicBytes, CFSTR("Unable to create public key bytes"), NULL, error);
+    return false;
+}
+
+static const uint8_t *mp_decode_forced_uint(cc_size n, cc_unit *r, const uint8_t *der, const uint8_t *der_end) {
+    size_t len;
+    der = ccder_decode_tl(CCDER_INTEGER, &len, der, der_end);
+    if (der && ccn_read_uint(n, r, len, der) >= 0)
+        return der + len;
+    
+    return NULL;
+}
+    
+static void SecOTRPIRecreateSignature(const uint8_t *oldSignature, size_t oldSignatureSize, uint8_t **newSignature, size_t *newSignatureSize)
+{
+    cc_unit r[ccec_cp_n(ccec_cp_256())], s[ccec_cp_n(ccec_cp_256())];
+    cc_size n = ccec_cp_n(ccec_cp_256());
+
+    const uint8_t *oldSignatureEnd = oldSignature + oldSignatureSize;
+    
+    oldSignature = ccder_decode_sequence_tl(&oldSignatureEnd, oldSignature, oldSignatureEnd);
+    oldSignature = mp_decode_forced_uint(n, r, oldSignature, oldSignatureEnd);
+    oldSignature = mp_decode_forced_uint(n, s, oldSignature, oldSignatureEnd);
+    
+    const uint8_t *outputPointer = *newSignature;
+    uint8_t *outputEndPointer = *newSignature + *newSignatureSize;
+    
+    *newSignature = ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, outputEndPointer, outputPointer, ccder_encode_integer(n, r, outputPointer, ccder_encode_integer(n, s, outputPointer, outputEndPointer)));
+    long newSigSize = outputEndPointer - *newSignature;
+    *newSignatureSize = (newSigSize >= 0) ? (size_t)newSigSize : 0;
+}
+
+bool SecOTRPIVerifySignature(SecOTRPublicIdentityRef publicID,
+                                const uint8_t *dataToHash, size_t amountToHash,
+                                const uint8_t *signatureStart, size_t signatureSize, CFErrorRef *error)
+{
+    require(signatureSize > 0, fail);
+    require(*signatureStart == signatureSize - 1, fail);
+    signatureSize -= 1;
+    signatureStart += 1;
+
+    require(SecKeyDigestAndVerifyWithError(publicID->publicSigningKey, kOTRSignatureAlgIDPtr,
+                                 dataToHash, amountToHash,
+                                 (uint8_t*)signatureStart, signatureSize, NULL), fail);
+    return true;
+fail:
+    // Workaround some type of compiler bug that won't recognize uint8_t after a label
+    ;
+    
+    uint8_t replacementSignature[signatureSize + 3];
+    size_t replacementSignatureLen = sizeof(replacementSignature);
+    uint8_t *replacementSignaturePtr = replacementSignature;
+    
+    SecOTRPIRecreateSignature(signatureStart, signatureSize, &replacementSignaturePtr, &replacementSignatureLen);
+    
+    require_action(replacementSignaturePtr, fail2, SecOTRCreateError(secOTRErrorLocal, kSecOTRErrorSignatureDidNotRecreate, CFSTR("Unable to recreate signature blob."), NULL, error));
+
+    require(SecKeyDigestAndVerifyWithError(publicID->publicSigningKey, kOTRSignatureAlgIDPtr,
+                                           dataToHash, amountToHash,
+                                           replacementSignaturePtr, replacementSignatureLen, error), fail2);
+    return true;
+
+fail2:
+    return false;
+}
+
+void SecOTRPICopyHash(SecOTRPublicIdentityRef publicID, uint8_t hash[kMPIDHashSize])
+{
+    memcpy(hash, publicID->hash, kMPIDHashSize);
+}
+
+void SecOTRPIAppendHash(SecOTRPublicIdentityRef publicID, CFMutableDataRef appendTo)
+{
+    CFDataAppendBytes(appendTo, publicID->hash, sizeof(publicID->hash));
+}
+
+bool SecOTRPICompareHash(SecOTRPublicIdentityRef publicID, const uint8_t hash[kMPIDHashSize])
+{
+    return 0 == memcmp(hash, publicID->hash, kMPIDHashSize);
+}
diff --git a/sec/Security/SecOTRSession.c b/sec/Security/SecOTRSession.c
new file mode 100644 (file)
index 0000000..75dd6c6
--- /dev/null
@@ -0,0 +1,777 @@
+//
+//  SecOTRSession.c
+//  libsecurity_libSecOTR
+//
+//  Created by Mitch Adler on 2/22/11.
+//  Copyright 2011 Apple Inc. All rights reserved.
+//
+
+#include "SecOTRSession.h"
+
+#include "SecOTRMath.h"
+#include "SecOTRDHKey.h"
+#include "SecOTRSessionPriv.h"
+#include "SecOTRPackets.h"
+#include "SecOTRPacketData.h"
+
+#include <utilities/SecCFWrappers.h>
+
+#include <CoreFoundation/CFRuntime.h>
+#include <CoreFoundation/CFString.h>
+
+#include <Security/SecBasePriv.h>
+#include <Security/SecRandom.h>
+#include <Security/SecBase64.h>
+
+#include <AssertMacros.h>
+
+#ifdef USECOMMONCRYPTO
+#include <CommonCrypto/CommonHMAC.h>
+#endif
+
+#include <corecrypto/cchmac.h>
+#include <corecrypto/ccsha2.h>
+#include <corecrypto/ccsha1.h>
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <syslog.h>
+
+#include "utilities/comparison.h"
+
+CFGiblisFor(SecOTRSession);
+
+static OTRMessageType SecOTRSGetMessageType(CFDataRef message)
+{
+    OTRMessageType type = kInvalidMessage;
+
+    CFMutableDataRef decodedBytes = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    SecOTRGetIncomingBytes(message, decodedBytes);
+
+    const uint8_t *bytes = CFDataGetBytePtr(decodedBytes);
+    size_t size = CFDataGetLength(decodedBytes);
+
+    require_noerr(ReadHeader(&bytes, &size, &type), fail);
+
+fail:
+    CFReleaseNull(decodedBytes);
+
+    return type;
+}
+
+const char *SecOTRPacketTypeString(CFDataRef message)
+{
+    if (!message) return "NoMessage";
+    switch (SecOTRSGetMessageType(message)) {
+        case kDHMessage:                return "DHMessage (0x02)";
+        case kDataMessage:              return "DataMessage (0x03)";
+        case kDHKeyMessage:             return "DHKeyMessage (0x0A)";
+        case kRevealSignatureMessage:   return "RevealSignatureMessage (0x11)";
+        case kSignatureMessage:         return "SignatureMessage (0x12)";
+        case kInvalidMessage:           return "InvalidMessage (0xFF)";
+        default:                        return "UnknownMessage";
+    }
+}
+
+static const char *SecOTRAuthStateString(SecOTRAuthState authState)
+{
+    switch (authState) {
+        case kIdle:                     return "Idle";
+        case kAwaitingDHKey:            return "AwaitingDHKey";
+        case kAwaitingRevealSignature:  return "AwaitingRevealSignature";
+        case kAwaitingSignature:        return "AwaitingSignature";
+        case kDone:                     return "Done";
+        default:                        return "InvalidState";
+    }
+}
+
+static CF_RETURNS_RETAINED CFStringRef SecOTRSessionCopyDescription(CFTypeRef cf) {
+    SecOTRSessionRef session = (SecOTRSessionRef)cf;
+    return CFStringCreateWithFormat(kCFAllocatorDefault,NULL,CFSTR("<%s %s%s%s%s %d:%d %s%s>"),
+                                    SecOTRAuthStateString(session->_state),
+                                    session->_me ? "F" : "-",
+                                    session->_them ? "P" : "-",
+                                    session->_receivedDHMessage ? "D" : "-",
+                                    session->_receivedDHKeyMessage ? "K" : "-",
+                                    session->_keyID,
+                                    session->_theirKeyID,
+                                    session->_theirPreviousKey ? "P" : "-",
+                                    session->_theirKey ? "T" : "-");
+}
+
+static void SecOTRSessionDestroy(CFTypeRef cf) {
+    SecOTRSessionRef session = (SecOTRSessionRef)cf;
+
+    CFReleaseNull(session->_receivedDHMessage);
+    CFReleaseNull(session->_receivedDHKeyMessage);
+
+    CFReleaseNull(session->_me);
+    CFReleaseNull(session->_myKey);
+    CFReleaseNull(session->_myNextKey);
+
+    CFReleaseNull(session->_them);
+    CFReleaseNull(session->_theirKey);
+    CFReleaseNull(session->_theirPreviousKey);
+
+    CFReleaseNull(session->_macKeysToExpose);
+
+    dispatch_release(session->_queue);
+}
+
+static void SecOTRSessionResetInternal(SecOTRSessionRef session)
+{
+    session->_state = kIdle;
+    
+    CFReleaseNull(session->_receivedDHMessage);
+    CFReleaseNull(session->_receivedDHKeyMessage);
+
+    session->_keyID = 0;
+    CFReleaseNull(session->_myKey);
+    CFReleaseNull(session->_myNextKey);
+    //session->_myNextKey = SecOTRFullDHKCreate(kCFAllocatorDefault);
+    session->_theirKeyID = 0;
+    CFReleaseNull(session->_theirKey);
+    CFReleaseNull(session->_theirPreviousKey);
+    CFReleaseNull(session->_macKeysToExpose);
+    session->_macKeysToExpose = CFDataCreateMutable(kCFAllocatorDefault, 0);
+
+    bzero(session->_keyCache, sizeof(session->_keyCache));
+}
+
+void SecOTRSessionReset(SecOTRSessionRef session)
+{
+    dispatch_sync_f(session->_queue, session, (dispatch_function_t) SecOTRSessionResetInternal);
+}
+
+
+SecOTRSessionRef SecOTRSessionCreateFromID(CFAllocatorRef allocator,
+                                           SecOTRFullIdentityRef myID,
+                                           SecOTRPublicIdentityRef theirID)
+{
+    SecOTRSessionRef newID = CFTypeAllocate(SecOTRSession, struct _SecOTRSession, allocator);
+
+    newID->_queue = dispatch_queue_create("OTRSession", DISPATCH_QUEUE_SERIAL);
+
+    newID->_me = myID;
+    newID->_them = theirID;
+    newID->_receivedDHMessage = NULL;
+    newID->_receivedDHKeyMessage = NULL;
+    newID->_myKey = NULL;
+    newID->_myNextKey = NULL;
+    newID->_theirKey = NULL;
+    newID->_theirPreviousKey = NULL;
+    newID->_macKeysToExpose = NULL;
+    newID->_textOutput = false;
+
+    SecOTRSessionResetInternal(newID);
+
+    CFRetain(newID->_me);
+    CFRetain(newID->_them);
+
+    return newID;
+}
+
+SecOTRSessionRef SecOTRSessionCreateFromIDAndFlags(CFAllocatorRef allocator,
+                                           SecOTRFullIdentityRef myID,
+                                           SecOTRPublicIdentityRef theirID,
+                                           uint32_t flags)
+{
+    SecOTRSessionRef newID = SecOTRSessionCreateFromID(allocator, myID, theirID);
+    if (flags & kSecOTRSendTextMessages) {
+        newID->_textOutput = true;
+    }
+    return newID;
+}
+
+static uint64_t constant_zero = 0;
+
+static void SecOTRSFindKeysForMessage(SecOTRSessionRef session,
+                                      SecOTRFullDHKeyRef myKey,
+                                      SecOTRPublicDHKeyRef theirKey,
+                                      bool sending,
+                                      uint8_t** messageKey, uint8_t** macKey, uint64_t **counter)
+{
+    SecOTRCacheElement* emptyKeys = NULL;
+    SecOTRCacheElement* cachedKeys = NULL;
+    
+    if ((NULL == myKey) || (NULL == theirKey)) {
+        if (messageKey)
+            *messageKey = NULL;
+        if (macKey)
+            *macKey = NULL;
+        if (counter)
+            *counter = &constant_zero;
+            
+        return;
+    }
+    
+    for(int i = 0; i < kOTRKeyCacheSize; ++i)
+    {
+        if (0 == constant_memcmp(session->_keyCache[i]._fullKeyHash, SecFDHKGetHash(myKey), CCSHA1_OUTPUT_SIZE)
+         && (0 == constant_memcmp(session->_keyCache[i]._publicKeyHash, SecPDHKGetHash(theirKey), CCSHA1_OUTPUT_SIZE))) {
+            cachedKeys = &session->_keyCache[i];
+            break;
+        }
+
+        if (emptyKeys == NULL
+         && session->_keyCache[i]._fullKey == NULL) {
+            emptyKeys = &session->_keyCache[i];
+        }
+    }
+
+    if (cachedKeys == NULL) {
+        if (emptyKeys == NULL) {
+            syslog(LOG_ERR, "SecOTRSession key cache was full. Should never happen, spooky.\n");
+            emptyKeys = &session->_keyCache[0];
+        }
+
+        // Fill in the entry.
+        emptyKeys->_fullKey = myKey;
+        memcpy(emptyKeys->_fullKeyHash, SecFDHKGetHash(myKey), CCSHA1_OUTPUT_SIZE);
+        emptyKeys->_publicKey = theirKey;
+        memcpy(emptyKeys->_publicKeyHash, SecPDHKGetHash(theirKey), CCSHA1_OUTPUT_SIZE);
+        
+        emptyKeys->_counter = 0;
+        emptyKeys->_theirCounter = 0;
+
+        SecOTRDHKGenerateOTRKeys(emptyKeys->_fullKey, emptyKeys->_publicKey,
+                              emptyKeys->_sendEncryptionKey, emptyKeys->_sendMacKey,
+                              emptyKeys->_receiveEncryptionKey, emptyKeys->_receiveMacKey);
+
+        cachedKeys = emptyKeys;
+    }
+    
+    if (messageKey)
+        *messageKey = sending ? cachedKeys->_sendEncryptionKey : cachedKeys->_receiveEncryptionKey;
+    if (macKey)
+        *macKey = sending ? cachedKeys->_sendMacKey : cachedKeys->_receiveMacKey;
+    if (counter)
+        *counter = sending ? &cachedKeys->_counter : &cachedKeys->_theirCounter;
+}
+
+SecOTRSessionRef SecOTRSessionCreateFromData(CFAllocatorRef allocator, CFDataRef data)
+{
+    if (data == NULL)
+        return NULL;
+
+    SecOTRSessionRef result = NULL;
+    SecOTRSessionRef session = CFTypeAllocate(SecOTRSession, struct _SecOTRSession, allocator);
+
+    const uint8_t *bytes = CFDataGetBytePtr(data);
+    size_t size = (size_t)CFDataGetLength(data);
+
+    session->_queue = dispatch_queue_create("OTRSession", DISPATCH_QUEUE_SERIAL);
+
+    session->_me = NULL;
+    session->_them = NULL;
+    session->_myKey = NULL;
+    session->_myNextKey = NULL;
+    session->_theirKey = NULL;
+    session->_theirPreviousKey = NULL;
+    session->_receivedDHMessage = NULL;
+    session->_receivedDHKeyMessage = NULL;
+    bzero(session->_keyCache, sizeof(session->_keyCache));
+
+    uint8_t version;
+    require_noerr(ReadByte(&bytes, &size, &version), fail);
+    require(version <= 3, fail);
+
+    require_noerr(ReadLong(&bytes, &size, &session->_state), fail);
+    session->_me = SecOTRFullIdentityCreateFromBytes(kCFAllocatorDefault, &bytes, &size, NULL);
+    require(session->_me != NULL, fail);
+    session->_them = SecOTRPublicIdentityCreateFromBytes(kCFAllocatorDefault, &bytes, &size, NULL);
+    require(session->_them != NULL, fail);
+    
+    require(size > sizeof(session->_r), fail);
+    memcpy(session->_r, bytes, sizeof(session->_r));
+    bytes += sizeof(session->_r);
+    size -= sizeof(session->_r);
+
+    {
+        uint8_t hasMessage = false;
+        ReadByte(&bytes, &size, &hasMessage);
+        if (hasMessage) {
+            session->_receivedDHMessage = CFDataCreateMutableFromOTRDATA(kCFAllocatorDefault, &bytes, &size);
+        }
+    }
+
+    if (version >= 2) {
+        uint8_t hasMessage = false;
+        ReadByte(&bytes, &size, &hasMessage);
+        if (hasMessage) {
+            session->_receivedDHKeyMessage = CFDataCreateMutableFromOTRDATA(kCFAllocatorDefault, &bytes, &size);
+        }
+    }
+
+    if (version < 3) {
+        uint8_t ready;
+        require_noerr(ReadByte(&bytes, &size, &ready), fail);
+        if (ready && session->_state == kIdle)
+            session->_state = kDone;
+    }
+
+    require_noerr(ReadLong(&bytes, &size, &session->_keyID), fail);
+    if (session->_keyID > 0) {
+        session->_myKey = SecOTRFullDHKCreateFromBytes(kCFAllocatorDefault, &bytes, &size);
+        require(session->_myKey != NULL, fail);
+        session->_myNextKey = SecOTRFullDHKCreateFromBytes(kCFAllocatorDefault, &bytes, &size);
+        require(session->_myNextKey != NULL, fail);
+    }
+    
+    require_noerr(ReadLong(&bytes, &size, &session->_theirKeyID), fail);
+    if (session->_theirKeyID > 0) {
+        if (session->_theirKeyID > 1) {
+            session->_theirPreviousKey = SecOTRPublicDHKCreateFromSerialization(kCFAllocatorDefault, &bytes, &size);
+            require(session->_theirPreviousKey != NULL, fail);
+        }
+        session->_theirKey = SecOTRPublicDHKCreateFromSerialization(kCFAllocatorDefault, &bytes, &size);
+        require(session->_theirKey != NULL, fail);
+    }
+
+    uint64_t *counter;
+    SecOTRSFindKeysForMessage(session, session->_myKey, session->_theirKey, false, NULL, NULL, &counter);
+    require_noerr(ReadLongLong(&bytes, &size, counter), fail);
+    SecOTRSFindKeysForMessage(session, session->_myKey, session->_theirKey, true, NULL, NULL, &counter);
+    require_noerr(ReadLongLong(&bytes, &size, counter), fail);
+    SecOTRSFindKeysForMessage(session, session->_myKey, session->_theirPreviousKey, false, NULL, NULL, &counter);
+    require_noerr(ReadLongLong(&bytes, &size, counter), fail);
+    SecOTRSFindKeysForMessage(session, session->_myKey, session->_theirPreviousKey, true, NULL, NULL, &counter);
+    require_noerr(ReadLongLong(&bytes, &size, counter), fail);
+    SecOTRSFindKeysForMessage(session, session->_myNextKey, session->_theirKey, false, NULL, NULL, &counter);
+    require_noerr(ReadLongLong(&bytes, &size, counter), fail);
+    SecOTRSFindKeysForMessage(session, session->_myNextKey, session->_theirKey, true, NULL, NULL, &counter);
+    require_noerr(ReadLongLong(&bytes, &size, counter), fail);
+    SecOTRSFindKeysForMessage(session, session->_myNextKey, session->_theirPreviousKey, false, NULL, NULL, &counter);
+    require_noerr(ReadLongLong(&bytes, &size, counter), fail);
+    SecOTRSFindKeysForMessage(session, session->_myNextKey, session->_theirPreviousKey, true, NULL, NULL, &counter);
+    require_noerr(ReadLongLong(&bytes, &size, counter), fail);
+    
+    session->_macKeysToExpose = CFDataCreateMutableFromOTRDATA(kCFAllocatorDefault, &bytes, &size);
+    require(session->_macKeysToExpose != NULL, fail);
+    
+    uint8_t textMode;
+    require_noerr(ReadByte(&bytes, &size, &textMode), fail);
+    session->_textOutput = (textMode != 0);
+
+    result = session;
+    session = NULL;
+
+fail:
+    CFReleaseNull(session);
+    return result;
+}
+
+
+OSStatus SecOTRSAppendSerialization(SecOTRSessionRef session, CFMutableDataRef serializeInto)
+{
+    __block OSStatus result  = errSecParam;
+
+    require(session, abort);
+    require(serializeInto, abort);
+
+    CFIndex start = CFDataGetLength(serializeInto);
+
+    dispatch_sync(session->_queue, ^{
+        const uint8_t version = 3;
+
+        CFDataAppendBytes(serializeInto, &version, sizeof(version));
+
+        AppendLong(serializeInto, session->_state);
+
+        result = (SecOTRFIAppendSerialization(session->_me, serializeInto, NULL)) ? errSecSuccess : errSecParam;
+    
+        if (result == errSecSuccess) {
+            result = (SecOTRPIAppendSerialization(session->_them, serializeInto, NULL)) ? errSecSuccess : errSecParam;
+        }
+    
+        if (result == errSecSuccess) {
+            CFDataAppendBytes(serializeInto, session->_r, sizeof(session->_r));
+
+            if (session->_receivedDHMessage == NULL) {
+                AppendByte(serializeInto, 0);
+            } else {
+                AppendByte(serializeInto, 1);
+                AppendCFDataAsDATA(serializeInto, session->_receivedDHMessage);
+            }
+
+            if (session->_receivedDHKeyMessage == NULL) {
+                AppendByte(serializeInto, 0);
+            } else {
+                AppendByte(serializeInto, 1);
+                AppendCFDataAsDATA(serializeInto, session->_receivedDHKeyMessage);
+            }
+
+            AppendLong(serializeInto, session->_keyID);
+            if (session->_keyID > 0) {
+                SecFDHKAppendSerialization(session->_myKey, serializeInto);
+                SecFDHKAppendSerialization(session->_myNextKey, serializeInto);
+            }
+
+            AppendLong(serializeInto, session->_theirKeyID);
+            if (session->_theirKeyID > 0) {
+                if (session->_theirKeyID > 1) {
+                    SecPDHKAppendSerialization(session->_theirPreviousKey, serializeInto);
+                }
+                SecPDHKAppendSerialization(session->_theirKey, serializeInto);
+            }
+            
+            uint64_t *counter;
+            SecOTRSFindKeysForMessage(session, session->_myKey, session->_theirKey, false, NULL, NULL, &counter);
+            AppendLongLong(serializeInto, *counter);
+            SecOTRSFindKeysForMessage(session, session->_myKey, session->_theirKey, true, NULL, NULL, &counter);
+            AppendLongLong(serializeInto, *counter);
+            SecOTRSFindKeysForMessage(session, session->_myKey, session->_theirPreviousKey, false, NULL, NULL, &counter);
+            AppendLongLong(serializeInto, *counter);
+            SecOTRSFindKeysForMessage(session, session->_myKey, session->_theirPreviousKey, true, NULL, NULL, &counter);
+            AppendLongLong(serializeInto, *counter);
+            SecOTRSFindKeysForMessage(session, session->_myNextKey, session->_theirKey, false, NULL, NULL, &counter);
+            AppendLongLong(serializeInto, *counter);
+            SecOTRSFindKeysForMessage(session, session->_myNextKey, session->_theirKey, true, NULL, NULL, &counter);
+            AppendLongLong(serializeInto, *counter);
+            SecOTRSFindKeysForMessage(session, session->_myNextKey, session->_theirPreviousKey, false, NULL, NULL, &counter);
+            AppendLongLong(serializeInto, *counter);
+            SecOTRSFindKeysForMessage(session, session->_myNextKey, session->_theirPreviousKey, true, NULL, NULL, &counter);
+            AppendLongLong(serializeInto, *counter);
+
+            AppendCFDataAsDATA(serializeInto, session->_macKeysToExpose);
+            
+            AppendByte(serializeInto, session->_textOutput ? 1 : 0);
+        }
+    });
+
+    if (result != errSecSuccess)
+        CFDataSetLength(serializeInto, start);
+
+abort:
+    return result;
+}
+
+
+bool SecOTRSGetIsReadyForMessages(SecOTRSessionRef session)
+{
+    __block bool result;
+
+    dispatch_sync(session->_queue, ^{ result = session->_state == kDone; });
+
+    return result;
+}
+
+bool SecOTRSGetIsIdle(SecOTRSessionRef session)
+{
+    __block bool result;
+    
+    dispatch_sync(session->_queue, ^{ result = session->_state == kIdle; });
+    
+    return result;
+}
+
+static void SecOTRSExpireCachedKeysForFullKey(SecOTRSessionRef session, SecOTRFullDHKeyRef myKey)
+{
+    for(int i = 0; i < kOTRKeyCacheSize; ++i)
+    {
+        if (0 == constant_memcmp(session->_keyCache[i]._fullKeyHash, SecFDHKGetHash(myKey), CCSHA1_OUTPUT_SIZE)) {
+            CFDataAppendBytes(session->_macKeysToExpose, session->_keyCache[i]._receiveMacKey, sizeof(session->_keyCache[i]._receiveMacKey));
+
+            bzero(&session->_keyCache[i], sizeof(session->_keyCache[i]));
+        }
+    }
+}
+
+static void SecOTRSExpireCachedKeysForPublicKey(SecOTRSessionRef session, SecOTRPublicDHKeyRef theirKey)
+{
+    for(int i = 0; i < kOTRKeyCacheSize; ++i)
+    {
+        if (0 == constant_memcmp(session->_keyCache[i]._publicKeyHash, SecPDHKGetHash(theirKey), CCSHA1_OUTPUT_SIZE)) {
+            CFDataAppendBytes(session->_macKeysToExpose, session->_keyCache[i]._receiveMacKey, sizeof(session->_keyCache[i]._receiveMacKey));
+
+            bzero(&session->_keyCache[i], sizeof(session->_keyCache[i]));
+        }
+    }
+}
+
+static void SecOTRSPrecalculateForPair(SecOTRSessionRef session,
+                                       SecOTRFullDHKeyRef myKey,
+                                       SecOTRPublicDHKeyRef theirKey)
+{
+    if (myKey == NULL || theirKey == NULL)
+        return;
+
+    SecOTRSFindKeysForMessage(session, myKey, theirKey, true, NULL, NULL, NULL);
+    SecOTRSFindKeysForMessage(session, myKey, theirKey, false, NULL, NULL, NULL);
+}
+
+static void SecOTRSPrecalculateKeysInternal(SecOTRSessionRef session)
+{
+    SecOTRSPrecalculateForPair(session, session->_myKey, session->_theirKey);
+    SecOTRSPrecalculateForPair(session, session->_myNextKey, session->_theirKey);
+    SecOTRSPrecalculateForPair(session, session->_myKey, session->_theirPreviousKey);
+    SecOTRSPrecalculateForPair(session, session->_myNextKey, session->_theirPreviousKey);
+}
+
+void SecOTRSPrecalculateKeys(SecOTRSessionRef session)
+{
+    dispatch_sync_f(session->_queue, session, (dispatch_function_t) SecOTRSPrecalculateKeysInternal);
+}
+
+enum SecOTRSMessageKind SecOTRSGetMessageKind(SecOTRSessionRef session, CFDataRef message)
+{
+    enum SecOTRSMessageKind kind = kOTRUnknownPacket;
+
+    CFMutableDataRef decodedBytes = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    SecOTRGetIncomingBytes(message, decodedBytes);
+    
+    const uint8_t *bytes = CFDataGetBytePtr(decodedBytes);
+    size_t size = CFDataGetLength(decodedBytes);
+
+    OTRMessageType type;
+    require_noerr(ReadHeader(&bytes, &size, &type), fail);
+    
+    kind = (type == kDataMessage) ? kOTRDataPacket : kOTRNegotiationPacket;
+
+fail:
+    CFReleaseNull(decodedBytes);
+    
+    return kind;
+}
+
+OSStatus SecOTRSSignAndProtectMessage(SecOTRSessionRef session,
+                                      CFDataRef sourceMessage,
+                                      CFMutableDataRef protectedMessage)
+{
+    __block OSStatus result = errSecParam;
+
+    require(session, abort);
+    require(sourceMessage, abort);
+    require(protectedMessage, abort);
+
+    dispatch_sync(session->_queue, ^{
+        if (session->_myKey == NULL ||
+            session->_theirKey == NULL) {
+            return;
+        }
+        
+        CFMutableDataRef destinationMessage;
+        if (session->_textOutput) {
+            destinationMessage = CFDataCreateMutable(kCFAllocatorDefault, 0);
+        } else {
+            destinationMessage = protectedMessage;
+        }
+
+        uint8_t *messageKey;
+        uint8_t *macKey;
+        uint64_t *counter;
+
+        CFIndex start = CFDataGetLength(destinationMessage);
+
+        SecOTRSFindKeysForMessage(session, session->_myKey, session->_theirKey,
+                                  true,
+                                  &messageKey, &macKey, &counter);
+
+        AppendHeader(destinationMessage, kDataMessage);
+        AppendByte(destinationMessage, 0); // Flags, all zero
+
+        AppendLong(destinationMessage, session->_keyID);
+        AppendLong(destinationMessage, session->_theirKeyID);
+        SecFDHKAppendPublicSerialization(session->_myNextKey, destinationMessage);
+        AppendLongLong(destinationMessage, ++*counter);
+
+        CFIndex sourceSize = CFDataGetLength(sourceMessage);
+        assert(((unsigned long)sourceSize)<=UINT32_MAX); /* this is correct as long as CFIndex is a signed long */
+        AppendLong(destinationMessage, (uint32_t)sourceSize);
+        uint8_t* encryptedDataPointer = CFDataIncreaseLengthAndGetMutableBytes(destinationMessage, sourceSize);
+        AES_CTR_HighHalf_Transform(kOTRMessageKeyBytes, messageKey,
+                                   *counter,
+                                   (size_t)sourceSize, CFDataGetBytePtr(sourceMessage),
+                                   encryptedDataPointer);
+
+        CFIndex macedContentsSize = CFDataGetLength(destinationMessage) - start;
+        CFIndex macSize = CCSHA1_OUTPUT_SIZE;
+        uint8_t* macDataPointer = CFDataIncreaseLengthAndGetMutableBytes(destinationMessage, macSize);
+
+#ifdef USECOMMONCRYPTO
+        CCHmac(kCCHmacAlgSHA1,
+               macKey, kOTRMessageMacKeyBytes,
+               CFDataGetBytePtr(destinationMessage) + start, (size_t)macedContentsSize,
+               macDataPointer);
+#else
+        cchmac(ccsha1_di(),
+               kOTRMessageMacKeyBytes, macKey,
+               macedContentsSize, CFDataGetBytePtr(destinationMessage) + start,
+               macDataPointer);
+#endif
+
+        CFDataAppend(destinationMessage, session->_macKeysToExpose);
+
+        CFDataSetLength(session->_macKeysToExpose, 0);
+        
+        if (session->_textOutput) {
+            SecOTRPrepareOutgoingBytes(destinationMessage, protectedMessage);
+            CFReleaseSafe(destinationMessage);
+        }
+
+        result = errSecSuccess;
+    });
+
+abort:
+    return result;
+}
+
+OSStatus SecOTRSVerifyAndExposeMessage(SecOTRSessionRef session,
+                                       CFDataRef incomingMessage,
+                                       CFMutableDataRef exposedMessageContents)
+{
+    __block SecOTRPublicDHKeyRef newKey = NULL;
+    __block OSStatus result = errSecParam;
+
+
+    require(session, abort);
+    require(incomingMessage, abort);
+    require(exposedMessageContents, abort);
+
+    dispatch_sync(session->_queue, ^{
+        const uint8_t* bytes;
+        size_t  size;
+        CFMutableDataRef decodedBytes = CFDataCreateMutable(kCFAllocatorDefault, 0);
+        SecOTRGetIncomingBytes(incomingMessage, decodedBytes);
+        
+        bytes = CFDataGetBytePtr(decodedBytes);
+        size = CFDataGetLength(decodedBytes);
+
+        const uint8_t* macDataStart = bytes;
+
+        uint32_t theirID;
+        uint32_t myID;
+
+        if ((result = ReadAndVerifyHeader(&bytes, &size, kDataMessage))){
+            CFReleaseSafe(decodedBytes);
+            return;
+        }
+
+        if (size <= 0) { result = errSecDecode;  CFReleaseSafe(decodedBytes); return; }
+
+        if ((result = ReadAndVerifyByte(&bytes, &size, 0))) {  CFReleaseSafe(decodedBytes); return;} // No flags
+
+        if ((result = ReadLong(&bytes, &size, &theirID))){  CFReleaseSafe(decodedBytes); return; }
+
+        if (theirID != session->_theirKeyID &&
+            (session->_theirPreviousKey == NULL || theirID != (session->_theirKeyID - 1)))
+        {
+            result = ((theirID + 1) < session->_theirKeyID) ? errSecOTRTooOld : errSecOTRIDTooNew;
+            CFReleaseSafe(decodedBytes);
+            return;
+        };
+
+        if ((result = ReadLong(&bytes, &size, &myID))){  CFReleaseSafe(decodedBytes); return; }
+        if (myID != session->_keyID && myID != (session->_keyID + 1))
+        {
+            result = (myID < session->_keyID) ? errSecOTRTooOld : errSecOTRIDTooNew;
+            CFReleaseSafe(decodedBytes);
+            return;
+        };
+
+
+        // Choose appripriate keys for message:
+        {
+            uint8_t *messageKey;
+            uint8_t *macKey;
+            uint64_t *theirCounter;
+
+            SecOTRFullDHKeyRef myKeyForMessage = (myID == session->_keyID) ? session->_myKey : session->_myNextKey;
+            SecOTRPublicDHKeyRef theirKeyForMessage = (theirID == session->_theirKeyID) ? session->_theirKey : session->_theirPreviousKey;
+
+            SecOTRSFindKeysForMessage(session, myKeyForMessage, theirKeyForMessage, false,
+                                      &messageKey, &macKey, &theirCounter);
+
+            size_t nextKeyMPISize;
+            const uint8_t* nextKeyMPIBytes;
+            if ((result = SizeAndSkipMPI(&bytes, &size, &nextKeyMPIBytes, &nextKeyMPISize))){  CFReleaseSafe(decodedBytes); return;}
+
+            uint64_t counter;
+            if ((result = ReadLongLong(&bytes, &size, &counter))) {  CFReleaseSafe(decodedBytes); return; }
+
+            if (counter <= *theirCounter) { result = errSecOTRTooOld;  CFReleaseSafe(decodedBytes); return; };
+
+            size_t messageSize;
+            const uint8_t* messageStart;
+            if ((result = SizeAndSkipDATA(&bytes, &size, &messageStart, &messageSize))) {  CFReleaseSafe(decodedBytes); return; }
+
+            size_t macDataSize = (bytes - macDataStart) ? (size_t)(bytes - macDataStart) : 0;
+            uint8_t mac[CCSHA1_OUTPUT_SIZE];
+            if (sizeof(mac) > size) { result = errSecDecode;  CFReleaseSafe(decodedBytes); return; }
+
+#ifdef USECOMMONCRYPTO
+            CCHmac(kCCHmacAlgSHA1,
+                   macKey, kOTRMessageMacKeyBytes,
+                   macDataStart, macDataSize,
+                   mac);
+#else
+            cchmac(ccsha1_di(),
+                   kOTRMessageMacKeyBytes, macKey,
+                   macDataSize, macDataStart,
+                   mac);
+#endif
+
+            if (0 != constant_memcmp(mac, bytes, sizeof(mac))) { result = errSecAuthFailed;  CFReleaseSafe(decodedBytes); return; }
+            //if (messageSize > 65535) { result = errSecDataTooLarge;  CFReleaseSafe(decodedBytes); return; }
+            uint8_t* dataSpace = CFDataIncreaseLengthAndGetMutableBytes(exposedMessageContents, (CFIndex)messageSize);
+
+
+            AES_CTR_HighHalf_Transform(kOTRMessageKeyBytes, messageKey,
+                                       counter,
+                                       messageSize, messageStart,
+                                       dataSpace);
+
+            // Everything is good, accept the meta data.
+            *theirCounter = counter;
+
+            newKey = SecOTRPublicDHKCreateFromBytes(kCFAllocatorDefault, &nextKeyMPIBytes, &nextKeyMPISize);
+        }
+
+        SecOTRSPrecalculateKeysInternal(session);
+
+        bool acceptTheirNewKey = newKey != NULL && theirID == session->_theirKeyID;
+
+        if (acceptTheirNewKey) {
+            if (session->_theirPreviousKey) {
+                SecOTRSExpireCachedKeysForPublicKey(session, session->_theirPreviousKey);
+            }
+
+            CFReleaseNull(session->_theirPreviousKey);
+            session->_theirPreviousKey = session->_theirKey;
+            session->_theirKey = newKey;
+
+            session->_theirKeyID += 1;
+
+            newKey = NULL;
+        }
+
+        if (myID == (session->_keyID + 1)) {
+            SecOTRSExpireCachedKeysForFullKey(session, session->_myKey);
+
+            // Swap the keys so we know the current key.
+            {
+                SecOTRFullDHKeyRef oldKey = session->_myKey;
+                session->_myKey = session->_myNextKey;
+                session->_myNextKey = oldKey;
+            }
+
+            // Derive a new next key by regenerating over the old key.
+            SecFDHKNewKey(session->_myNextKey);
+
+            session->_keyID = myID;
+        }
+        CFReleaseSafe(decodedBytes);
+    });
+
+abort:
+    CFReleaseNull(newKey);
+    return result;
+}
+
+
+OSStatus SecOTRSEndSession(SecOTRSessionRef session,
+                           CFMutableDataRef messageToSend)
+{
+    return errSecUnimplemented;
+}
diff --git a/sec/Security/SecOTRSession.h b/sec/Security/SecOTRSession.h
new file mode 100644 (file)
index 0000000..cd06a6e
--- /dev/null
@@ -0,0 +1,112 @@
+//
+//  SecOTRSession.h
+//  libsecurity_libSecOTR
+//
+//  Created by Mitch Adler on 2/22/11.
+//  Copyright 2011 Apple Inc. All rights reserved.
+//
+
+#ifndef _SECOTRSESSION_H_
+#define _SECOTRSESSION_H_
+
+#include <CoreFoundation/CFBase.h>
+#include <CoreFoundation/CFData.h>
+
+#include <Security/SecOTR.h>
+
+__BEGIN_DECLS
+
+// MARK: MessageTypes
+
+enum SecOTRSMessageKind {
+    kOTRNegotiationPacket,
+    kOTRDataPacket,
+    kOTRUnknownPacket
+};
+
+// MARK: OTR Session
+
+enum SecOTRCreateFlags {
+    kSecOTRSendTextMessages = 1, // OTR messages will be encoded as Base-64 with header/footer per the standard, not just given back in binary
+};
+
+/*!
+ @typedef
+ @abstract   OTRSessions encapsulate a commuincaiton between to parties using the
+             otr protocol.
+ @discussion Sessions start with IDs. One end sends a start packet (created with AppendStartPacket).
+             Both sides process packets they exchange on the negotiation channel.
+ */
+typedef struct _SecOTRSession* SecOTRSessionRef;
+
+SecOTRSessionRef SecOTRSessionCreateFromID(CFAllocatorRef allocator,
+                                           SecOTRFullIdentityRef myID,
+                                           SecOTRPublicIdentityRef theirID);
+
+SecOTRSessionRef SecOTRSessionCreateFromIDAndFlags(CFAllocatorRef allocator,
+                                           SecOTRFullIdentityRef myID,
+                                           SecOTRPublicIdentityRef theirID,
+                                           uint32_t flags);
+
+SecOTRSessionRef SecOTRSessionCreateFromData(CFAllocatorRef allocator, CFDataRef data);
+
+    void SecOTRSessionReset(SecOTRSessionRef session);
+OSStatus SecOTRSAppendSerialization(SecOTRSessionRef publicID, CFMutableDataRef serializeInto);
+
+OSStatus SecOTRSAppendStartPacket(SecOTRSessionRef session, CFMutableDataRef appendInitiatePacket);
+
+OSStatus SecOTRSAppendRestartPacket(SecOTRSessionRef session, CFMutableDataRef appendPacket);
+
+OSStatus SecOTRSProcessPacket(SecOTRSessionRef session,
+                              CFDataRef incomingPacket,
+                              CFMutableDataRef negotiationResponse);
+    
+OSStatus SecOTRSEndSession(SecOTRSessionRef session,
+                           CFMutableDataRef messageToSend);
+
+
+bool SecOTRSGetIsReadyForMessages(SecOTRSessionRef session);
+bool SecOTRSGetIsIdle(SecOTRSessionRef session);
+
+enum SecOTRSMessageKind SecOTRSGetMessageKind(SecOTRSessionRef session, CFDataRef incomingPacket);
+
+/*!
+ @function
+ @abstract   Precalculates keys for current key sets to save time when sending or receiving.
+ @param      session                OTRSession receiving message
+ */
+void SecOTRSPrecalculateKeys(SecOTRSessionRef session);
+    
+/*!
+ @function
+ @abstract   Encrypts and Signs a message with OTR credentials.
+ @param      session                OTRSession receiving message
+ @param      incomingMessage        Cleartext message to protect
+ @param      protectedMessage       Data to append the encoded protected message to
+ @result     OSStatus               errSecAuthFailed -> bad signature, no data appended.
+ */
+
+OSStatus SecOTRSSignAndProtectMessage(SecOTRSessionRef session,
+                                      CFDataRef sourceMessage,
+                                      CFMutableDataRef protectedMessage);
+
+/*!
+ @function
+ @abstract   Verifies and exposes a message sent via OTR
+ @param      session                OTRSession receiving message
+ @param      incomingMessage        Encoded message
+ @param      exposedMessageContents Data to append the exposed message to
+ @result     OSStatus               errSecAuthFailed -> bad signature, no data appended.
+ */
+
+OSStatus SecOTRSVerifyAndExposeMessage(SecOTRSessionRef session,
+                                       CFDataRef incomingMessage,
+                                       CFMutableDataRef exposedMessageContents);
+
+
+
+const char *SecOTRPacketTypeString(CFDataRef message);
+
+__END_DECLS
+
+#endif
diff --git a/sec/Security/SecOTRSessionAKE.c b/sec/Security/SecOTRSessionAKE.c
new file mode 100644 (file)
index 0000000..8c6664a
--- /dev/null
@@ -0,0 +1,567 @@
+//
+//  SecOTRSession.c
+//  libsecurity_libSecOTR
+//
+//  Created by Mitch Adler on 2/22/11.
+//  Copyright 2011 Apple Inc. All rights reserved.
+//
+
+#include "SecOTRSession.h"
+
+#include "SecOTRMath.h"
+#include "SecOTRIdentityPriv.h"
+#include "SecOTRSessionPriv.h"
+#include "SecOTRPackets.h"
+#include "SecOTRPacketData.h"
+#include "SecOTRDHKey.h"
+
+#include <utilities/SecCFWrappers.h>
+
+#include <CoreFoundation/CFRuntime.h>
+#include <CoreFoundation/CFString.h>
+
+#include <Security/SecBase.h>
+#include <Security/SecRandom.h>
+
+#include <AssertMacros.h>
+
+#include <corecrypto/cchmac.h>
+#include <corecrypto/ccsha2.h>
+
+#include <string.h>
+
+static void SecOTRInitMyDHKeys(SecOTRSessionRef session)
+{
+    CFReleaseNull(session->_myKey);
+    session->_myKey = SecOTRFullDHKCreate(kCFAllocatorDefault);
+    CFReleaseNull(session->_myNextKey);
+    session->_myNextKey = SecOTRFullDHKCreate(kCFAllocatorDefault);
+    session->_keyID = 1;
+    
+    bzero(session->_keyCache, sizeof(session->_keyCache));
+}
+
+OSStatus SecOTRSAppendStartPacket(SecOTRSessionRef session, CFMutableDataRef appendPacket)
+{
+    __block OSStatus result = errSecSuccess;
+
+    dispatch_sync(session->_queue, ^{
+        session->_state = kAwaitingDHKey;
+
+        // Generate r and x and calculate gx:
+        SecOTRInitMyDHKeys(session);
+
+        CFMutableDataRef destinationMessage;
+        if (session->_textOutput) {
+            destinationMessage = CFDataCreateMutable(kCFAllocatorDefault, 0);
+        } else {
+            destinationMessage = appendPacket;
+        }
+
+
+        result = SecRandomCopyBytes(kSecRandomDefault, sizeof(session->_r), session->_r);
+        if (result == errSecSuccess) {
+            SecOTRAppendDHMessage(session, destinationMessage);
+            if (session->_textOutput) {
+                SecOTRPrepareOutgoingBytes(destinationMessage, appendPacket);
+                CFReleaseSafe(destinationMessage);
+            }
+        }
+    });
+
+    return result;
+}
+
+OSStatus SecOTRSAppendRestartPacket(SecOTRSessionRef session, CFMutableDataRef appendPacket)
+{
+    __block OSStatus result = errSecSuccess;
+
+    dispatch_sync(session->_queue, ^{
+        if (!session->_myKey) {
+            secerror("_myKey is NULL, avoiding crash");
+            result = errSecDecode;
+            return;
+        }
+        CFMutableDataRef destinationMessage;
+        if (session->_textOutput) {
+            destinationMessage = CFDataCreateMutable(kCFAllocatorDefault, 0);
+        } else {
+            destinationMessage = appendPacket;
+        }
+
+        session->_state = kAwaitingDHKey;
+        CFReleaseNull(session->_receivedDHMessage);
+        CFReleaseNull(session->_receivedDHKeyMessage);
+        
+        SecOTRAppendDHMessage(session, destinationMessage);
+        if (session->_textOutput) {
+            SecOTRPrepareOutgoingBytes(destinationMessage, appendPacket);
+            CFReleaseSafe(destinationMessage);
+        }
+    });
+
+    return result;
+}
+
+static const uint8_t* FindGXHash(CFDataRef dhPacket)
+{
+    const uint8_t* messageBytes = CFDataGetBytePtr(dhPacket);
+    size_t remainingBytes = (size_t)CFDataGetLength(dhPacket);
+    
+    OTRMessageType messageType;
+    
+    require_noerr(ReadHeader(&messageBytes, &remainingBytes, &messageType), fail);
+    require(messageType == kDHMessage, fail);
+    
+    uint32_t egxiLength = 0;
+    require_noerr(ReadLong(&messageBytes, &remainingBytes, & egxiLength), fail);
+    require(egxiLength <= remainingBytes, fail);
+    messageBytes += egxiLength;
+    remainingBytes -= egxiLength;
+    
+    uint32_t dataLength = 0;
+    require_noerr(ReadLong(&messageBytes, &remainingBytes, &dataLength), fail);
+    require(dataLength <= remainingBytes, fail);
+    require(dataLength == CCSHA256_OUTPUT_SIZE, fail);
+    
+    return messageBytes;
+    
+fail:
+    return NULL;
+}
+
+static bool SecOTRMyGXHashIsBigger(SecOTRSessionRef session, CFDataRef dhCommitMessage)
+{
+    bool mineIsBigger = false;
+
+    CFMutableDataRef myDHCommitMessage = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    
+    SecOTRAppendDHMessage(session, myDHCommitMessage);
+    
+    const uint8_t* myHash = FindGXHash(myDHCommitMessage);
+    const uint8_t* theirHash = FindGXHash(dhCommitMessage);
+    
+    require(myHash, fail);
+    require(theirHash, fail);
+    
+    mineIsBigger = 0 < memcmp(myHash, theirHash, CCSHA256_OUTPUT_SIZE);
+    
+fail:
+    CFReleaseNull(myDHCommitMessage);
+    return mineIsBigger;
+}
+
+static OSStatus SecOTRSProcessDHMessage(SecOTRSessionRef session,
+                                        CFDataRef incomingPacket,
+                                        CFMutableDataRef negotiationResponse)
+{
+    OSStatus result = errSecParam;
+
+    switch (session->_state) {
+        case kAwaitingDHKey:
+            // Compare hash values.
+            if (SecOTRMyGXHashIsBigger(session, incomingPacket)) {
+                // If we're bigger we resend to force them to deal.
+                CFReleaseNull(session->_receivedDHMessage);
+                SecOTRAppendDHMessage(session, negotiationResponse);
+                result = errSecSuccess;
+                break;
+            } // Else intentionally fall through to idle
+        case kAwaitingSignature:
+        case kIdle:
+        case kDone:
+            // Generate a new X and GX..
+            SecOTRInitMyDHKeys(session);
+            // If we were already waiting on reveal, then just send the packet again
+        case kAwaitingRevealSignature:
+            SecOTRAppendDHKeyMessage(session, negotiationResponse);
+
+            // Keep the packet for use later.
+            CFReleaseNull(session->_receivedDHMessage);
+            session->_receivedDHMessage = CFDataCreateCopy(kCFAllocatorDefault, incomingPacket);
+            
+            session->_state = kAwaitingRevealSignature;
+            result = errSecSuccess;
+            break;
+        default:
+            result = errSecInteractionNotAllowed;
+            break;
+    }
+
+    return result;
+}
+
+static OSStatus SecOTRSetupTheirKeyFrom(SecOTRSessionRef session, const uint8_t**data, size_t*size)
+{
+    SecOTRPublicDHKeyRef tempKey = SecOTRPublicDHKCreateFromSerialization(kCFAllocatorDefault, data, size);
+    require(tempKey != NULL, fail);
+    session->_theirKey = tempKey;
+    session->_theirKeyID = 1;
+    
+    return errSecSuccess;
+
+fail:
+    return errSecDecode;
+}
+
+static OSStatus SecOTRSExtractTheirPublicDHKey(SecOTRSessionRef session, CFDataRef dhPacket)
+{
+    OSStatus result = errSecParam;
+
+    const uint8_t *messageBytes = CFDataGetBytePtr(dhPacket);
+    size_t messageSize = (size_t)CFDataGetLength(dhPacket);
+    OTRMessageType messageType = kDHMessage; // Suppress warning.
+    
+    ReadHeader(&messageBytes, &messageSize, &messageType);
+    require(messageType == kDHKeyMessage, exit);
+    
+    result = SecOTRSetupTheirKeyFrom(session, &messageBytes, &messageSize);
+
+exit:
+    return result;
+}
+
+
+static OSStatus SecOTRSProcessDHKeyMessage(SecOTRSessionRef session,
+                                        CFDataRef incomingPacket,
+                                        CFMutableDataRef negotiationResponse)
+{
+    OSStatus result = errSecUnimplemented;
+    
+    result = SecOTRSExtractTheirPublicDHKey(session, incomingPacket);
+    require_noerr(result, exit);
+
+    switch (session->_state) {
+        case kAwaitingDHKey:
+            CFReleaseNull(session->_receivedDHKeyMessage);
+            SecOTRAppendRevealSignatureMessage(session, negotiationResponse);
+            session->_state = kAwaitingSignature;
+            session->_receivedDHKeyMessage = CFDataCreateCopy(kCFAllocatorDefault, incomingPacket);
+            CFRetain(incomingPacket);
+            result = errSecSuccess;
+            break;
+        case kAwaitingSignature:
+            if (CFEqualSafe(incomingPacket, session->_receivedDHKeyMessage))
+                SecOTRAppendRevealSignatureMessage(session, negotiationResponse);
+            result = errSecSuccess;
+            break;
+        case kIdle:
+        case kDone:
+        case kAwaitingRevealSignature:
+            result = errSecSuccess;
+            break;
+        default:
+            result = errSecInteractionNotAllowed;
+            break;
+    }
+
+exit:
+    return result;
+}
+
+
+static OSStatus SecOTRSExtractR(SecOTRSessionRef session,
+                                const uint8_t **messageBytes,
+                                size_t *messageSize)
+{
+    OSStatus result = errSecDecode;
+
+    OTRMessageType messageType = kDHMessage; // Suppress warning
+    
+    ReadHeader(messageBytes, messageSize, &messageType);
+    require(messageType == kRevealSignatureMessage, exit);
+    
+    {
+        uint32_t rSize = 0;
+        ReadLong(messageBytes, messageSize, &rSize);
+        require(rSize == kOTRAuthKeyBytes, exit);
+    }
+    
+    memcpy(session->_r, *messageBytes, kOTRAuthKeyBytes);
+    
+    *messageBytes += kOTRAuthKeyBytes;
+    *messageSize -= kOTRAuthKeyBytes;
+    
+    result = errSecSuccess;
+exit:
+    return result;
+}
+
+static OSStatus FindEncGYInDHPacket(SecOTRSessionRef session,
+                                      const uint8_t **dhMessageBytesPtr,
+                                      size_t *messageSizePtr,
+                                      size_t* encGYBufferSize)
+{
+    OSStatus result = errSecParam;
+    require_action(*encGYBufferSize >= kExponentiationBytes + 4, exit, result = errSecParam);
+    
+    OTRMessageType messageType;
+    result = ReadHeader(dhMessageBytesPtr, messageSizePtr, &messageType);
+    require_noerr(result, exit);
+    require_action(messageType == kDHMessage, exit, result = errSecDecode);
+    
+    uint32_t readEncSize;
+    result = ReadLong(dhMessageBytesPtr, messageSizePtr, &readEncSize);
+    require_noerr(result, exit);
+
+    *encGYBufferSize = readEncSize;
+exit:
+    // Don't bother erasing the public gy decrypted, it's public after all.
+    return result;
+    
+}
+
+static OSStatus SecOTRSExtractRAndTheirDHKey(SecOTRSessionRef session,
+                                     const uint8_t **messageBytes,
+                                     size_t *messageSize)
+{
+    OSStatus result = errSecDecode;
+    
+    require(session->_receivedDHMessage != NULL, exit);
+    result = SecOTRSExtractR(session, messageBytes, messageSize);
+    require_noerr(result, exit);
+    
+    uint8_t gxiDecrypted[kExponentiationBytes + 4];
+    const uint8_t *gxiDecryptedBuffer = gxiDecrypted;
+    
+    const uint8_t* dhMessageBytes = CFDataGetBytePtr(session->_receivedDHMessage);
+    size_t dhMessageSize = (size_t)CFDataGetLength(session->_receivedDHMessage);
+    
+    size_t encGYSize = sizeof(gxiDecrypted);
+    result = FindEncGYInDHPacket(session, &dhMessageBytes, &dhMessageSize, &encGYSize);
+    require_noerr(result, exit);
+    require_action(encGYSize <= kExponentiationBytes + 4, exit, result = errSecDecode);
+    
+    AES_CTR_IV0_Transform(sizeof(session->_r), session->_r, encGYSize, dhMessageBytes, gxiDecrypted);
+
+    result = SecOTRSetupTheirKeyFrom(session, &gxiDecryptedBuffer, &encGYSize);
+
+exit:
+    // Don't bother erasing the public gy decrypted, it's public after all.
+    return result;
+}
+
+static OSStatus SecVerifySignatureAndMac(SecOTRSessionRef session,
+                                         bool usePrimes,
+                                         const uint8_t **signatureAndMacBytes,
+                                         size_t *signatureAndMacSize)
+{
+    OSStatus result = errSecDecode;
+    
+    uint8_t m1[kOTRAuthMACKeyBytes];
+    uint8_t m2[kOTRAuthMACKeyBytes];
+    uint8_t c[kOTRAuthKeyBytes];
+    
+    {
+        cc_unit s[kExponentiationUnits];
+        
+        SecPDHKeyGenerateS(session->_myKey, session->_theirKey, s);
+        // Derive M1, M2 and C, either prime or normal versions.
+        DeriveOTR256BitsFromS(usePrimes ? kM1Prime : kM1,
+                              kExponentiationUnits, s, sizeof(m1), m1);
+        DeriveOTR256BitsFromS(usePrimes ? kM2Prime : kM2,
+                              kExponentiationUnits, s, sizeof(m2), m2);
+        DeriveOTR128BitPairFromS(kCs,
+                                 kExponentiationUnits, s,
+                                 sizeof(c),usePrimes ? NULL : c,
+                                 sizeof(c), usePrimes ? c : NULL);
+        bzero(s, sizeof(s));
+    }
+    
+    cchmac_di_decl(ccsha256_di(), mBContext);
+
+    cchmac_init(ccsha256_di(), mBContext, sizeof(m1), m1);
+
+    {
+        CFMutableDataRef toHash = CFDataCreateMutable(kCFAllocatorDefault, 0);
+        
+        SecPDHKAppendSerialization(session->_theirKey, toHash);
+        SecFDHKAppendPublicSerialization(session->_myKey, toHash);
+        
+        cchmac_update(ccsha256_di(), mBContext, (size_t)CFDataGetLength(toHash), CFDataGetBytePtr(toHash));
+        
+        CFReleaseNull(toHash);
+    }
+    
+    const uint8_t* encSigDataBlobStart = *signatureAndMacBytes;
+    
+    uint32_t xbSize = 0;
+    result = ReadLong(signatureAndMacBytes, signatureAndMacSize, &xbSize);
+    require_noerr(result, exit);
+    require(xbSize > 4, exit);
+    require(xbSize <= *signatureAndMacSize, exit);
+    
+    uint8_t signatureMac[CCSHA256_OUTPUT_SIZE];
+    cchmac(ccsha256_di(), sizeof(m2), m2, xbSize + 4, encSigDataBlobStart, signatureMac);
+    
+    require(xbSize + kSHA256HMAC160Bytes <= *signatureAndMacSize, exit);
+    const uint8_t *macStart = *signatureAndMacBytes + xbSize;
+
+    // check the outer hmac
+    require(0 == memcmp(macStart, signatureMac, kSHA256HMAC160Bytes), exit);
+           
+
+    {
+        uint8_t xb[xbSize];
+        // Decrypt and copy the signature block
+        AES_CTR_IV0_Transform(sizeof(c), c, xbSize, *signatureAndMacBytes, xb);
+
+        const uint8_t* signaturePacket = xb;
+        size_t signaturePacketSize = xbSize;
+        
+        uint16_t pubKeyType;
+        result = ReadShort(&signaturePacket, &signaturePacketSize, &pubKeyType);
+        require_noerr(result, exit);
+        require_action(pubKeyType == 0xF000, exit, result = errSecUnimplemented);
+
+        uint32_t pubKeySize;
+        result = ReadLong(&signaturePacket, &signaturePacketSize, &pubKeySize);
+        require_noerr(result, exit);
+        require_action(pubKeySize <= signaturePacketSize, exit, result = errSecDecode);
+        require(((CFIndex)pubKeySize) >= 0, exit);
+        
+        // Add the signature and keyid to the hash.
+        // PUBKEY of our type is 2 bytes of type, 2 bytes of size and size bytes.
+        // Key ID is 4 bytes.
+        cchmac_update(ccsha256_di(), mBContext, 2 + 4 + pubKeySize + 4, xb);
+        
+        uint8_t mb[CCSHA256_OUTPUT_SIZE];
+        cchmac_final(ccsha256_di(), mBContext, mb);
+
+        // Make reference to the deflated key
+        require_action(SecOTRPIEqualToBytes(session->_them, signaturePacket, (CFIndex)pubKeySize), exit, result = errSecAuthFailed);
+
+        signaturePacket += pubKeySize;
+        signaturePacketSize -= pubKeySize;
+       
+        result = ReadLong(&signaturePacket, &signaturePacketSize, &session->_theirKeyID);
+        require_noerr(result, exit);
+
+        uint32_t sigSize;
+        result = ReadLong(&signaturePacket, &signaturePacketSize, &sigSize);
+        require_noerr(result, exit);
+        require_action(sigSize <= signaturePacketSize, exit, result = errSecDecode);
+        
+        bool bresult = SecOTRPIVerifySignature(session->_them, mb, sizeof(mb), signaturePacket, sigSize, NULL);
+        result = bresult ? errSecSuccess : errSecDecode;
+        require_noerr(result, exit);
+        
+    }
+
+exit:
+    bzero(m1, sizeof(m1));
+    bzero(m2, sizeof(m2));
+    bzero(c, sizeof(c));
+    
+    return result;
+}
+
+static OSStatus SecOTRSProcessRevealSignatureMessage(SecOTRSessionRef session,
+                                        CFDataRef incomingPacket,
+                                        CFMutableDataRef negotiationResponse)
+{
+    OSStatus result = errSecParam;
+    
+    require_action_quiet(session->_state == kAwaitingRevealSignature, exit, result = errSecSuccess);
+
+    const uint8_t *messageBytes = CFDataGetBytePtr(incomingPacket);
+    size_t messageSize = (size_t)CFDataGetLength(incomingPacket);
+
+    result = SecOTRSExtractRAndTheirDHKey(session, &messageBytes, &messageSize);
+    require_noerr(result, exit);
+
+    result = SecVerifySignatureAndMac(session, false, &messageBytes, &messageSize);
+    require_noerr(result, exit);
+
+    SecOTRAppendSignatureMessage(session, negotiationResponse);
+
+    session->_state = kDone;
+    result = errSecSuccess;
+exit:
+    return result;
+}
+
+static OSStatus SecOTRSProcessSignatureMessage(SecOTRSessionRef session,
+                                        CFDataRef incomingPacket,
+                                        CFMutableDataRef negotiationResponse)
+{
+    OSStatus result = errSecParam;
+
+    require_action_quiet(session->_state == kAwaitingSignature, exit, result = errSecSuccess);
+
+    const uint8_t *messageBytes = CFDataGetBytePtr(incomingPacket);
+    size_t messageSize = (size_t)CFDataGetLength(incomingPacket);
+    
+    OTRMessageType messageType;
+    result = ReadHeader(&messageBytes, &messageSize, &messageType);
+    require_noerr(result, exit);
+    require_action(messageType == kSignatureMessage, exit, result = errSecDecode);
+    
+    result = SecVerifySignatureAndMac(session, true, &messageBytes, &messageSize);
+    require_noerr(result, exit);
+
+    CFReleaseNull(session->_receivedDHKeyMessage);
+    session->_state = kDone;
+
+    result = errSecSuccess;
+exit:
+    return result;
+}
+
+OSStatus SecOTRSProcessPacket(SecOTRSessionRef session,
+                              CFDataRef incomingPacket,
+                              CFMutableDataRef negotiationResponse)
+{
+    __block OSStatus result = errSecParam;
+
+    require(CFDataGetLength(incomingPacket) > 0, fail);
+    dispatch_sync(session->_queue, ^{
+        CFMutableDataRef decodedBytes = CFDataCreateMutable(kCFAllocatorDefault, 0);
+        SecOTRGetIncomingBytes(incomingPacket, decodedBytes);
+
+        const uint8_t* bytes = CFDataGetBytePtr(decodedBytes);
+        size_t size = CFDataGetLength(decodedBytes);
+
+        OTRMessageType packetType = kInvalidMessage;
+        if (ReadHeader(&bytes, &size, &packetType))
+            packetType = kInvalidMessage;
+
+        CFMutableDataRef destinationMessage;
+        if (session->_textOutput) {
+            destinationMessage = CFDataCreateMutable(kCFAllocatorDefault, 0);
+        } else {
+            destinationMessage = negotiationResponse;
+        }
+
+        switch (packetType) {
+            case kDHMessage:
+                result = SecOTRSProcessDHMessage(session, decodedBytes, destinationMessage);
+                break;
+            case kDHKeyMessage:
+                result = SecOTRSProcessDHKeyMessage(session, decodedBytes, destinationMessage);
+                break;
+            case kRevealSignatureMessage:
+                result = SecOTRSProcessRevealSignatureMessage(session, decodedBytes, destinationMessage);
+                break;
+            case kSignatureMessage:
+                result = SecOTRSProcessSignatureMessage(session, decodedBytes, destinationMessage);
+                break;
+            default:
+                result = errSecDecode;
+                break;
+        };
+        
+        if (result != errSecSuccess) {
+            secnotice("session", "Error %d processing packet type %d, session state %d, keyid %d, myKey %p, myNextKey %p, theirKeyId %d, theirKey %p, theirPreviousKey %p, bytes %@", (int)result, packetType, session->_state, session->_keyID, session->_myKey, session->_myNextKey, session->_theirKeyID, session->_theirKey, session->_theirPreviousKey, decodedBytes);
+        }
+        
+        if (session->_textOutput) {
+            SecOTRPrepareOutgoingBytes(destinationMessage, negotiationResponse);
+            CFReleaseSafe(destinationMessage);
+        }
+        CFReleaseSafe(decodedBytes);
+    });
+    
+fail:
+    return result;
+}
diff --git a/sec/Security/SecOTRSessionPriv.h b/sec/Security/SecOTRSessionPriv.h
new file mode 100644 (file)
index 0000000..cf738c4
--- /dev/null
@@ -0,0 +1,92 @@
+//
+//  SecOTRSessionPriv.h
+//  libsecurity_libSecOTR
+//
+//  Created by Mitch Adler on 2/23/11.
+//  Copyright 2011 Apple Inc. All rights reserved.
+//
+
+#ifndef _SECOTRSESSIONPRIV_H_
+#define _SECOTRSESSIONPRIV_H_
+
+#include <CoreFoundation/CFBase.h>
+#include <CoreFoundation/CFRuntime.h>
+
+#include <Security/SecOTR.h>
+#include <corecrypto/ccn.h>
+#include <corecrypto/ccmode.h>
+#include <corecrypto/ccsha1.h>
+
+#include <CommonCrypto/CommonDigest.h>
+
+#include <dispatch/dispatch.h>
+
+#include <Security/SecOTRMath.h>
+#include <Security/SecOTRDHKey.h>
+
+__BEGIN_DECLS
+
+typedef enum {
+    kIdle,
+    kAwaitingDHKey,
+    kAwaitingRevealSignature,
+    kAwaitingSignature,
+    kDone
+} SecOTRAuthState;
+
+struct _SecOTRCacheElement {
+    SecOTRFullDHKeyRef _fullKey;
+    uint8_t _fullKeyHash[CCSHA1_OUTPUT_SIZE];
+    SecOTRPublicDHKeyRef _publicKey;
+    uint8_t _publicKeyHash[CCSHA1_OUTPUT_SIZE];
+
+    uint8_t _sendMacKey[kOTRMessageMacKeyBytes];
+    uint8_t _sendEncryptionKey[kOTRMessageKeyBytes];
+
+    uint8_t _receiveMacKey[kOTRMessageMacKeyBytes];
+    uint8_t _receiveEncryptionKey[kOTRMessageKeyBytes];
+
+    uint64_t _counter;
+    uint64_t _theirCounter;
+    
+};
+typedef struct _SecOTRCacheElement SecOTRCacheElement;
+
+#define kOTRKeyCacheSize 4
+
+struct _SecOTRSession {
+    CFRuntimeBase _base;
+    
+    SecOTRAuthState _state;
+    
+    SecOTRFullIdentityRef    _me;
+    SecOTRPublicIdentityRef  _them;
+    
+    uint8_t _r[kOTRAuthKeyBytes];
+    
+    CFDataRef _receivedDHMessage;
+    CFDataRef _receivedDHKeyMessage;
+
+    uint32_t _keyID;
+    SecOTRFullDHKeyRef _myKey;
+    SecOTRFullDHKeyRef _myNextKey;
+
+    uint32_t _theirKeyID;
+    SecOTRPublicDHKeyRef _theirPreviousKey;
+    SecOTRPublicDHKeyRef _theirKey;
+    
+    CFMutableDataRef _macKeysToExpose;
+
+    dispatch_queue_t _queue;
+
+    SecOTRCacheElement _keyCache[kOTRKeyCacheSize];
+    
+    bool _textOutput;
+};
+
+void SecOTRGetIncomingBytes(CFDataRef incomingMessage, CFMutableDataRef decodedBytes);
+void SecOTRPrepareOutgoingBytes(CFMutableDataRef destinationMessage, CFMutableDataRef protectedMessage);
+
+__END_DECLS
+
+#endif
diff --git a/sec/Security/SecOTRUtils.c b/sec/Security/SecOTRUtils.c
new file mode 100644 (file)
index 0000000..76b2404
--- /dev/null
@@ -0,0 +1,204 @@
+//
+//  SecOTRUtils.c
+//  libSecOTR
+//
+//  Created by Keith Henrickson on 6/11/12.
+//
+//
+
+#include "SecOTR.h"
+#include "SecOTRIdentityPriv.h"
+#include "SecOTRSessionPriv.h"
+#include <utilities/SecCFWrappers.h>
+#include <stdlib.h>
+
+#include <AssertMacros.h>
+
+#include <Security/SecBase.h>
+#include <Security/SecItem.h>
+#include <Security/SecKey.h>
+#include <Security/SecKeyPriv.h>
+#include <Security/SecBase64.h>
+
+#include <TargetConditionals.h>
+
+CFStringRef sLocalErrorDomain = CFSTR("com.apple.security.otr.error");
+
+void SecOTRCreateError(enum SecOTRError family, CFIndex errorCode, CFStringRef descriptionString, CFErrorRef previousError, CFErrorRef *newError) {
+    if (newError && !(*newError)) {
+        const void* keys[2] = {kCFErrorDescriptionKey, kCFErrorUnderlyingErrorKey};
+        const void* values[2] = {descriptionString, previousError};
+        *newError = CFErrorCreateWithUserInfoKeysAndValues(kCFAllocatorDefault, (family == secOTRErrorLocal) ? sLocalErrorDomain : kCFErrorDomainOSStatus, errorCode, keys, values, (previousError != NULL) ? 2 : 1);
+    } else {
+        CFReleaseSafe(previousError);
+    }
+}
+
+OSStatus insertSize(CFIndex size, uint8_t* here)
+{
+    require(size < 0xFFFF, fail);
+    
+    uint8_t bytes[] = { (size >> 8) & 0xFF, size & 0xFF };
+    memcpy(here, bytes, sizeof(bytes));
+    
+    return errSecSuccess;
+    
+fail:
+    return errSecParam;
+}
+
+OSStatus appendSize(CFIndex size, CFMutableDataRef into)
+{
+    require(size < 0xFFFF, fail);
+    
+    uint8_t bytes[] = { (size >> 8) & 0xFF, size & 0xFF };
+    CFDataAppendBytes(into, bytes, sizeof(bytes));
+    
+    return errSecSuccess;
+    
+fail:
+    return errSecParam;
+}
+
+OSStatus readSize(const uint8_t** data, size_t* limit, uint16_t* size)
+{
+    require(limit != NULL, fail);
+    require(data != NULL, fail);
+    require(size != NULL, fail);
+    require(*limit > 1, fail);
+    
+    *size = ((uint16_t)(*data)[0]) << 8 | ((uint16_t) (*data)[1]) << 0;
+    
+    *limit -= 2;
+    *data += 2;
+    
+    return errSecSuccess;
+fail:
+    return errSecParam;
+}
+
+OSStatus appendSizeAndData(CFDataRef data, CFMutableDataRef appendTo)
+{
+    OSStatus status = errSecNotAvailable;
+    
+    require_noerr(appendSize(CFDataGetLength(data), appendTo), exit);
+    CFDataAppend(appendTo, data);
+    
+    status = errSecSuccess;
+    
+exit:
+    return status;
+}
+
+OSStatus appendPublicOctetsAndSize(SecKeyRef fromKey, CFMutableDataRef appendTo)
+{
+    OSStatus status = errSecDecode;
+    CFDataRef serializedKey = NULL;
+    
+    require_noerr(SecKeyCopyPublicBytes(fromKey, &serializedKey), exit);
+    require(serializedKey, exit);
+    
+    status = appendSizeAndData(serializedKey, appendTo);
+    
+exit:
+    CFReleaseNull(serializedKey);
+    return status;
+}
+
+OSStatus appendPublicOctets(SecKeyRef fromKey, CFMutableDataRef appendTo)
+{
+    OSStatus status = errSecDecode;
+    CFDataRef serializedKey = NULL;
+    
+    require_noerr(SecKeyCopyPublicBytes(fromKey, &serializedKey), exit);
+    require(serializedKey, exit);
+    
+    CFDataAppend(appendTo, serializedKey);
+    
+    status = errSecSuccess;
+    
+exit:
+    CFReleaseNull(serializedKey);
+    return status;
+}
+
+
+/* Given an EC public key in encoded form return a SecKeyRef representing
+ that key. Supported encodings are kSecKeyEncodingPkcs1. */
+static SecKeyRef SecKeyCreateECPublicKey(CFAllocatorRef allocator,
+                                  const uint8_t *keyData, CFIndex keyDataLength) {
+    CFDataRef tempData = CFDataCreate(kCFAllocatorDefault, keyData, keyDataLength);
+    SecKeyRef newPublicKey = SecKeyCreateFromPublicData(kCFAllocatorDefault, kSecECDSAAlgorithmID, tempData);
+
+    CFRelease(tempData);
+    return newPublicKey;
+}
+
+typedef SecKeyRef (*createFunction_t)(CFAllocatorRef allocator,
+                                      const uint8_t *keyData, CFIndex keyDataLength);
+
+static SecKeyRef CallCreateFunctionFrom(CFAllocatorRef allocator, const uint8_t** data, size_t* limit, createFunction_t create)
+{
+    uint16_t foundLength = 0;
+    const uint8_t* foundData = NULL;
+    
+    require(limit != NULL, fail);
+    require(data != NULL, fail);
+    
+    require_noerr(readSize(data, limit, &foundLength), fail);
+    require(foundLength <= *limit, fail);
+    
+    foundData = *data;
+    
+    *limit -= foundLength;
+    *data += foundLength;
+    
+fail:
+    
+    return create(allocator, foundData, foundLength);
+}
+
+SecKeyRef CreateECPublicKeyFrom(CFAllocatorRef allocator, const uint8_t** data, size_t* limit)
+{
+    return CallCreateFunctionFrom(allocator, data, limit, &SecKeyCreateECPublicKey);
+}
+
+void SecOTRGetIncomingBytes(CFDataRef incomingMessage, CFMutableDataRef decodedBytes)
+{
+    CFDataRef header = CFStringCreateExternalRepresentation(kCFAllocatorDefault, CFSTR("?OTR:"), kCFStringEncodingUTF8, '?');
+    CFDataRef footer = CFStringCreateExternalRepresentation(kCFAllocatorDefault, CFSTR("."), kCFStringEncodingUTF8, '?');
+    CFRange headerLoc = CFDataFind(incomingMessage, header, CFRangeMake(0, CFDataGetLength(header)), 0);
+    CFRange footerLoc = CFDataFind(incomingMessage, footer, CFRangeMake(0, CFDataGetLength(incomingMessage)), 0);
+    if (kCFNotFound == headerLoc.location) {
+        CFDataAppend(decodedBytes, incomingMessage);
+    } else {
+        CFDataRef bodyData = CFDataCreateReferenceFromRange(kCFAllocatorDefault, incomingMessage, CFRangeMake(headerLoc.length, footerLoc.location - headerLoc.length));
+        size_t size = SecBase64Decode((char*)CFDataGetBytePtr(bodyData), CFDataGetLength(bodyData), NULL, 0);
+        uint8_t decodedByteArray[size];
+        SecBase64Decode((char*)CFDataGetBytePtr(bodyData), CFDataGetLength(bodyData), decodedByteArray, size);
+        CFDataAppendBytes(decodedBytes, decodedByteArray, size);
+        CFRelease(bodyData);
+    }
+    CFRelease(header);
+    CFRelease(footer);
+}
+
+void SecOTRPrepareOutgoingBytes(CFMutableDataRef destinationMessage, CFMutableDataRef protectedMessage)
+{
+    CFDataRef header = CFStringCreateExternalRepresentation(kCFAllocatorDefault, CFSTR("?OTR:"), kCFStringEncodingUTF8, '?');
+    CFDataRef footer = CFStringCreateExternalRepresentation(kCFAllocatorDefault, CFSTR("."), kCFStringEncodingUTF8, '?');
+    size_t base64Len = SecBase64Encode(CFDataGetBytePtr(destinationMessage), CFDataGetLength(destinationMessage), NULL, 0);
+    char base64Message [base64Len];
+    SecBase64Encode(CFDataGetBytePtr(destinationMessage), CFDataGetLength(destinationMessage), base64Message, base64Len);
+    CFDataRef base64Data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (uint8_t*)base64Message, base64Len, kCFAllocatorNull);
+    
+    CFDataAppend(protectedMessage, header);
+    CFDataAppend(protectedMessage, base64Data);
+    CFDataAppend(protectedMessage, footer);
+    
+    CFRelease(header);
+    CFRelease(footer);
+    CFRelease(base64Data);
+}
+
+
diff --git a/sec/Security/SecOnOSX.h b/sec/Security/SecOnOSX.h
new file mode 100644 (file)
index 0000000..1bc01bd
--- /dev/null
@@ -0,0 +1,28 @@
+//
+//  SecOnOSX.h
+//  messsageProtection
+//
+//  Created by Keith on 10/21/11.
+//  Copyright (c) 2011 __MyCompanyName__. All rights reserved.
+//
+
+#ifndef _SECONOSX_H_
+#define _SECONOSX_H_
+
+#include <TargetConditionals.h>
+
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+
+#include <Security/SecKeyPriv.h>
+
+#define SecKeyCreateFromPublicData _SecKeyCreateFromPublicData
+
+#if 0
+SecKeyRef SecKeyCreateFromPublicData(CFAllocatorRef allocator, CFIndex algorithmID, CFDataRef serialized);
+#endif
+
+#endif  /* TARGET_OS_MAC */
+
+#endif /* _SECONOSX_H_ */
+
+
diff --git a/sec/Security/SecPasswordGenerate.c b/sec/Security/SecPasswordGenerate.c
new file mode 100644 (file)
index 0000000..07db08c
--- /dev/null
@@ -0,0 +1,1167 @@
+/*
+ * Copyright (c) 2013 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * SecPasswordStrength.c
+ */
+
+#include <limits.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecItem.h>
+#include <Security/SecBase.h>
+#include <Security/SecRandom.h>
+#include "SecPasswordGenerate.h"
+#include <AssertMacros.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <utilities/SecCFWrappers.h>
+#include <utilities/SecCFRelease.h>
+#include <utilities/SecCFError.h>
+
+// Keys for external dictionaries with password generation requirements we read from plist.
+CFStringRef kSecPasswordMinLengthKey = CFSTR("PasswordMinLength");
+CFStringRef kSecPasswordMaxLengthKey = CFSTR("PasswordMaxLength");
+CFStringRef kSecPasswordAllowedCharactersKey = CFSTR("PasswordAllowedCharacters");
+CFStringRef kSecPasswordRequiredCharactersKey = CFSTR("PasswordRequiredCharacters");
+CFStringRef kSecPasswordDefaultForType = CFSTR("PasswordDefaultForType");
+
+CFStringRef kSecPasswordDisallowedCharacters = CFSTR("PasswordDisallowedCharacters");
+CFStringRef kSecPasswordCantStartWithChars = CFSTR("PasswordCantStartWithChars");
+CFStringRef kSecPasswordCantEndWithChars = CFSTR("PasswordCantEndWithChars");
+CFStringRef kSecPasswordContainsNoMoreThanNSpecificCharacters = CFSTR("PasswordContainsNoMoreThanNSpecificCharacters");
+CFStringRef kSecPasswordContainsAtLeastNSpecificCharacters = CFSTR("PasswordContainsAtLeastNSpecificCharacters");
+CFStringRef kSecPasswordContainsNoMoreThanNConsecutiveIdenticalCharacters = CFSTR("PasswordContainsNoMoreThanNConsecutiveIdenticalCharacters");
+CFStringRef kSecPasswordCharacterCount = CFSTR("PasswordCharacterCount");
+CFStringRef kSecPasswordCharacters = CFSTR("PasswordCharacters");
+
+CFStringRef kSecPasswordGroupSize = CFSTR("PasswordGroupSize");
+CFStringRef kSecPasswordNumberOfGroups = CFSTR("PasswordNumberOfGroups");
+CFStringRef kSecPasswordSeparator = CFSTR("SecPasswordSeparator");
+
+// Keys for internally used dictionaries with password generation parameters (never exposed to external API).
+static CFStringRef kSecUseDefaultPasswordFormatKey = CFSTR("UseDefaultPasswordFormat");
+static CFStringRef kSecNumberOfRequiredRandomCharactersKey = CFSTR("NumberOfRequiredRandomCharacters");
+static CFStringRef kSecAllowedCharactersKey = CFSTR("AllowedCharacters");
+static CFStringRef kSecRequiredCharacterSetsKey = CFSTR("RequiredCharacterSets");
+
+static CFIndex defaultNumberOfRandomCharacters = 20;
+static CFIndex defaultPINLength = 4;
+static CFIndex defaultiCloudPasswordLength = 24;
+static CFIndex defaultWifiPasswordLength = 12;
+
+static CFStringRef defaultWifiCharacters = CFSTR("abcdefghijklmnopqrstuvwxyz1234567890");
+static CFStringRef defaultPINCharacters = CFSTR("0123456789");
+static CFStringRef defaultiCloudCharacters = CFSTR("ABCDEFGHJKLMNPQRSTUVWXYZ23456789");
+static CFStringRef defaultCharacters = CFSTR("abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ123456789");
+
+static CFCharacterSetRef uppercaseLetterCharacterSet;
+static CFCharacterSetRef lowercaseLetterCharacterSet;
+static CFCharacterSetRef decimalDigitCharacterSet;
+static CFCharacterSetRef punctuationCharacterSet;
+
+static CFIndex alphabetSetSize = 26;
+static CFIndex decimalSetSize = 10;
+static CFIndex punctuationSetSize = 33;
+static double entropyStrengthThreshold = 35.0;
+
+/*
+ generated with ruby badpins.rb | gperf
+ See this for PIN list:
+ A birthday present every eleven wallets? The security of customer-chosen banking PINs (2012),  by Joseph Bonneau , Sören Preibusch , Ross Anderson
+ */
+const char *in_word_set (const char *str, unsigned int len);
+
+#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
+&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
+&& (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
+&& ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
+&& ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
+&& ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
+&& ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
+&& ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
+&& ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
+&& ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
+&& ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
+&& ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
+&& ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
+&& ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
+&& ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
+&& ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
+&& ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
+&& ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
+&& ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
+&& ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
+&& ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
+&& ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
+&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
+/* The character set is not based on ISO-646.  */
+error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
+#endif
+
+
+#define TOTAL_KEYWORDS 100
+#define MIN_WORD_LENGTH 4
+#define MAX_WORD_LENGTH 4
+#define MIN_HASH_VALUE 21
+#define MAX_HASH_VALUE 275
+/* maximum key range = 255, duplicates = 0 */
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static unsigned int pinhash (const char *str, unsigned int len)
+{
+    static unsigned short asso_values[] =
+    {
+        276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+        276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+        276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+        276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+        276, 276, 276, 276, 276, 276, 276, 276,   5,   0,
+        10,  10,  30,  50, 100, 120,  70,  25,  57,  85,
+        2,   4,   1,  19,  14,  11,  92, 276, 276, 276,
+        276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+        276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+        276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+        276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+        276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+        276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+        276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+        276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+        276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+        276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+        276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+        276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+        276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+        276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+        276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+        276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+        276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+        276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+        276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+        276, 276, 276, 276, 276
+    };
+    return len + asso_values[(unsigned char)str[3]+9] + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[1]] + asso_values[(unsigned char)str[0]+3];
+}
+
+//pins that reached the top 20 list
+static const char *blacklist[] = {"1234", "1004", "2000", "1122", "4321", "2001", "2580"};
+
+bool SecPasswordIsPasswordWeak(CFStringRef passcode)
+{
+    uppercaseLetterCharacterSet = CFCharacterSetGetPredefined(kCFCharacterSetUppercaseLetter);
+    lowercaseLetterCharacterSet = CFCharacterSetGetPredefined(kCFCharacterSetLowercaseLetter);
+    decimalDigitCharacterSet = CFCharacterSetGetPredefined(kCFCharacterSetDecimalDigit);
+    punctuationCharacterSet = CFCharacterSetGetPredefined(kCFCharacterSetPunctuation);
+    
+    bool isNumber = true;
+    char* pin = NULL;
+    
+    //length checks
+    if( CFStringGetLength(passcode) < 4 ){
+        return true; //weak password
+    }
+    //check to see if passcode is a number
+    for(CFIndex i = 0; i < CFStringGetLength(passcode); i++){
+        if( CFStringFindCharacterFromSet(passcode, decimalDigitCharacterSet, CFRangeMake(i,1), 0, NULL))
+            continue;
+        else {
+            isNumber = false;
+            break;
+        }
+    }
+    //checking to see if it's a 4 digit pin
+    if(isNumber && CFStringGetLength(passcode) == 4){
+        
+        pin = CFStringToCString(passcode);
+        if(in_word_set(pin, 4)){
+            free(pin);
+            return true;
+        }
+
+        CFIndex blacklistLength = (CFIndex)sizeof(blacklist)/sizeof(blacklist[0]);
+        
+        //not all the same number
+        if(pin[0] == pin[1] == pin[2] == pin[3]){
+            free(pin);
+            return true; //weak password
+        }
+        //first two digits being the same and the last two digits being the same
+        if ( pin[0] == pin[1] && pin[2] == pin[3]){
+            free(pin);
+            return true; //weak password
+        }
+        //first two digits not being the same as the last two digits
+        if(pin[0] == pin[2] && pin[1] == pin[3]){
+            free(pin);
+            return true; //weak password
+        }
+        //not in this list
+        for(CFIndex i = 0; i < blacklistLength; i++)
+        {
+            const char* blackCode = blacklist[i];
+            if(0 == strcmp(blackCode, pin))
+            {
+                free(pin);
+                return true; //weak password
+            }
+        }
+    }
+    else if(isNumber){ //dealing with a numeric PIN
+        pin = CFStringToCString(passcode);
+        //check if PIN is all the same number
+        for(int i = 0; i < CFStringGetLength(passcode); i++){
+            if(i+1 >= CFStringGetLength(passcode)){
+                free(pin);
+                return true;
+            }
+            else if (pin[i] == pin[i+1])
+                continue;
+            else
+                break;
+        }
+        //check if PIN is a bunch of incrementing numbers
+        for(int i = 0; i < CFStringGetLength(passcode); i++){
+            if(i == CFStringGetLength(passcode)-1){
+                free(pin);
+                return true;
+            }
+            else if ((pin[i] + 1) == pin[i+1])
+                continue;
+            else
+                break;
+        }
+        //check if PIN is a bunch of decrementing numbers
+        for(int i = 0; i < CFStringGetLength(passcode); i++){
+            if(i == CFStringGetLength(passcode)-1){
+                free(pin);
+                return true;
+            }
+            else if ((pin[i]) == (pin[i+1] +1))
+                continue;
+            else
+                break;
+        }
+    }
+    else{ // password is complex, evaluate entropy
+        int u = 0;
+        int l = 0;
+        int d = 0;
+        int p = 0;
+        int characterSet = 0;
+        
+        //calculate new entropy
+        for(CFIndex i = 0; i < CFStringGetLength(passcode); i++){
+            
+            if( CFStringFindCharacterFromSet(passcode, uppercaseLetterCharacterSet, CFRangeMake(i,1), kCFCompareBackwards, NULL)){
+                u++;
+                continue;
+            }
+            if( CFStringFindCharacterFromSet(passcode, lowercaseLetterCharacterSet, CFRangeMake(i,1), kCFCompareBackwards, NULL)){
+                l++;
+                continue;
+            }
+            if( CFStringFindCharacterFromSet(passcode, decimalDigitCharacterSet, CFRangeMake(i,1), kCFCompareBackwards, NULL)){
+                d++;
+                continue;
+            }
+            if( CFStringFindCharacterFromSet(passcode, punctuationCharacterSet, CFRangeMake(i,1), kCFCompareBackwards, NULL)){
+                p++;
+                continue;
+            }
+            
+        }
+        if(u > 0){
+            characterSet += alphabetSetSize;
+        }
+        if(l > 0){
+            characterSet += alphabetSetSize;
+        }
+        if(d > 0){
+            characterSet += decimalSetSize;
+        }
+        if(p > 0){
+            characterSet += punctuationSetSize;
+        }
+        
+        double strength = CFStringGetLength(passcode)*log2(characterSet);
+        
+        if(strength < entropyStrengthThreshold){
+            return true; //weak
+        }
+        else
+            return false; //strong
+    }
+    if(pin)
+        free(pin);
+    
+    return false; //strong password
+    
+}
+
+static void getUniformRandomNumbers(uint8_t* buffer, size_t numberOfDesiredNumbers, uint8_t upperBound)
+{
+    
+    // The values returned by SecRandomCopyBytes are uniformly distributed in the range [0, 255]. If we try to map
+    // these values onto a smaller range using modulo we will introduce a bias towards lower numbers in situations
+    // where our smaller range doesn’t evenly divide in to [0, 255]. For example, with the desired range of [0, 54]
+    // the ranges 0..54, 55..109, 110..164, and 165..219 are uniformly distributed, but the range 220..255 modulo 55
+    // is only distributed over [0, 35], giving significant bias to these lower values. So, we ignore random numbers
+    // that would introduce this bias.
+    uint8_t limitAvoidingModuloBias = UCHAR_MAX - (UCHAR_MAX % upperBound);
+    
+    for (size_t numberOfAcceptedNumbers = 0; numberOfAcceptedNumbers < numberOfDesiredNumbers; ) {
+        if (SecRandomCopyBytes(kSecRandomDefault, numberOfDesiredNumbers - numberOfAcceptedNumbers, buffer + numberOfAcceptedNumbers) == -1)
+            continue;
+        for (size_t i = numberOfAcceptedNumbers; i < numberOfDesiredNumbers; ++i) {
+            if (buffer[i] < limitAvoidingModuloBias)
+                buffer[numberOfAcceptedNumbers++] = buffer[i] % upperBound;
+        }
+    }
+}
+
+static bool passwordContainsRequiredCharacters(CFStringRef password, CFArrayRef requiredCharacterSets)
+{
+    CFCharacterSetRef characterSet;
+    
+    for (CFIndex i = 0; i< CFArrayGetCount(requiredCharacterSets); i++) {
+        characterSet = CFArrayGetValueAtIndex(requiredCharacterSets, i);
+        CFRange rangeToSearch = CFRangeMake(0, CFStringGetLength(password));
+        require_quiet(CFStringFindCharacterFromSet(password, characterSet, rangeToSearch, 0, NULL), fail);
+    }
+    return true;
+
+fail:
+    return false;
+    
+}
+
+static bool passwordContainsLessThanNIdenticalCharacters(CFStringRef password, CFIndex identicalCount)
+{
+    unsigned char Char, nextChar;
+    int repeating = 0;
+    
+    for(CFIndex i = 0; i < CFStringGetLength(password); i++){
+        Char = CFStringGetCharacterAtIndex(password, i);
+        for(CFIndex j = i; j< CFStringGetLength(password); j++){
+            nextChar = CFStringGetCharacterAtIndex(password, j);
+            require_quiet(repeating <= identicalCount, fail);
+            if(Char == nextChar){
+                repeating++;
+            }else{
+                repeating = 0;
+                break;
+            }
+        }
+    }
+    return true;
+fail:
+    return false;
+}
+
+static bool passwordContainsAtLeastNCharacters(CFStringRef password, CFStringRef characters, CFIndex N)
+{
+    CFCharacterSetRef characterSet = NULL;
+    characterSet = CFCharacterSetCreateWithCharactersInString(kCFAllocatorDefault, characters);
+    CFIndex counter = 0;
+    
+    for(CFIndex i = 0; i < CFStringGetLength(password); i++){
+        if(CFStringFindCharacterFromSet(password, characterSet, CFRangeMake(i, 1), 0, NULL))
+            counter++;
+    }
+    CFReleaseNull(characterSet);
+    if(counter < N)
+        return false;
+    else
+        return true;
+}
+
+static bool passwordContainsLessThanNCharacters(CFStringRef password, CFStringRef characters, CFIndex N)
+{
+    CFCharacterSetRef characterSet = NULL;
+    characterSet = CFCharacterSetCreateWithCharactersInString(kCFAllocatorDefault, characters);
+    CFIndex counter = 0;
+    
+    for(CFIndex i = 0; i < CFStringGetLength(password); i++){
+        if(CFStringFindCharacterFromSet(password, characterSet, CFRangeMake(i, 1), 0, NULL))
+            counter++;
+    }
+    CFReleaseNull(characterSet);
+    if(counter > N)
+        return false;
+    else
+        return true;
+}
+
+static bool passwordDoesNotContainCharacters(CFStringRef password, CFStringRef prohibitedCharacters)
+{
+    CFCharacterSetRef characterSet = NULL;
+    characterSet = CFCharacterSetCreateWithCharactersInString(kCFAllocatorDefault, prohibitedCharacters);
+    CFRange rangeToSearch = CFRangeMake(0, CFStringGetLength(password));
+    
+    require_quiet(!CFStringFindCharacterFromSet(password, characterSet, rangeToSearch, 0, NULL), fail);
+    CFReleaseNull(characterSet);
+    return true;
+fail:
+    CFReleaseNull(characterSet);
+    return false;
+}
+
+static void getPasswordRandomCharacters(CFStringRef *returned, CFDictionaryRef requirements, CFIndex *numberOfRandomCharacters, CFStringRef allowedCharacters)
+{
+    uint8_t randomNumbers[*numberOfRandomCharacters];
+    unsigned char randomCharacters[*numberOfRandomCharacters];
+    getUniformRandomNumbers(randomNumbers, *numberOfRandomCharacters, CFStringGetLength(allowedCharacters));
+    
+    CFTypeRef prohibitedCharacters = NULL;
+    CFStringRef temp = NULL;
+    
+    if(!CFDictionaryGetValueIfPresent(requirements, kSecPasswordDisallowedCharacters, &prohibitedCharacters))
+        prohibitedCharacters = NULL;
+    
+    //it's faster for long characters to check each character produced for these cases
+    for (CFIndex i = 0; i < *numberOfRandomCharacters; ++i){
+        //check prohibited characters
+        UniChar randomChar[1];
+        randomChar[0] = CFStringGetCharacterAtIndex(allowedCharacters, randomNumbers[i]);
+        temp = CFStringCreateWithCharacters(kCFAllocatorDefault, randomChar, 1);
+        
+        if(prohibitedCharacters != NULL)
+        {
+            if(!passwordDoesNotContainCharacters(temp, prohibitedCharacters)){
+                //change up the random numbers so we don't get the same index into allowed
+                getUniformRandomNumbers(randomNumbers, *numberOfRandomCharacters, CFStringGetLength(allowedCharacters));
+                i--;
+                continue;
+            }
+        }
+        randomCharacters[i] = (unsigned char)randomChar[0];
+    }
+    
+    CFReleaseNull(temp);
+
+    *returned = CFStringCreateWithBytes(kCFAllocatorDefault, randomCharacters, *numberOfRandomCharacters, kCFStringEncodingUTF8, false);
+}
+
+static bool doesPasswordEndWith(CFStringRef password, CFStringRef prohibitedCharacters)
+{
+    CFCharacterSetRef characterSet = NULL;
+    characterSet = CFCharacterSetCreateWithCharactersInString(kCFAllocatorDefault, prohibitedCharacters);
+    
+    CFRange rangeToSearch = CFRangeMake(CFStringGetLength(password) - CFStringGetLength(prohibitedCharacters), CFStringGetLength(prohibitedCharacters));
+    require_quiet(0 == CFStringCompareWithOptions(password, prohibitedCharacters, rangeToSearch, 0), fail);
+    CFReleaseNull(characterSet);
+    return false;
+fail:
+    CFReleaseNull(characterSet);
+    return true;
+}
+
+static bool doesPasswordStartWith(CFStringRef password, CFStringRef prohibitedCharacters)
+{
+    CFCharacterSetRef characterSet = NULL;
+    characterSet = CFCharacterSetCreateWithCharactersInString(kCFAllocatorDefault, prohibitedCharacters);
+    
+    CFRange rangeToSearch = CFRangeMake(0, CFStringGetLength(prohibitedCharacters));
+    require_quiet(0 == CFStringCompareWithOptions(password, prohibitedCharacters, rangeToSearch, 0), fail);
+    CFReleaseNull(characterSet);
+    return false; //does not start with prohibitedCharacters
+fail:
+    CFReleaseNull(characterSet);
+    return true;
+}
+
+static void passwordGenerateDefaultParametersDictionary(CFDictionaryRef *returned, SecPasswordType type, CFDictionaryRef requirements){
+    
+    CFMutableArrayRef requiredCharacterSets = NULL;
+    CFNumberRef numReqChars = NULL;
+    CFStringRef defaultPasswordFormat = NULL;
+    requiredCharacterSets = CFArrayCreateMutable(NULL, 0, NULL);
+    defaultPasswordFormat = CFSTR("true");
+    CFTypeRef groupSizeRef = NULL, numberOfGroupsRef = NULL;
+    CFIndex groupSize, numberOfGroups;
+    switch(type){
+        case(kSecPasswordTypeiCloudRecovery):
+            numReqChars = CFNumberCreateWithCFIndex(kCFAllocatorDefault, defaultiCloudPasswordLength);
+            groupSize = 4;
+            numberOfGroups = 6;
+            groupSizeRef = CFNumberCreate(NULL, kCFNumberIntType, &groupSize);
+            numberOfGroupsRef = CFNumberCreate(NULL, kCFNumberIntType, &numberOfGroups);
+            
+            uppercaseLetterCharacterSet = CFCharacterSetGetPredefined(kCFCharacterSetUppercaseLetter);
+            decimalDigitCharacterSet = CFCharacterSetGetPredefined(kCFCharacterSetDecimalDigit);
+            CFArrayAppendValue(requiredCharacterSets, uppercaseLetterCharacterSet);
+            CFArrayAppendValue(requiredCharacterSets, decimalDigitCharacterSet);
+            *returned = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
+                                                    kSecUseDefaultPasswordFormatKey,   defaultPasswordFormat,
+                                                    kSecNumberOfRequiredRandomCharactersKey, numReqChars,
+                                                    kSecAllowedCharactersKey,   defaultiCloudCharacters,
+                                                    kSecRequiredCharacterSetsKey, requiredCharacterSets,
+                                                    kSecPasswordGroupSize, groupSizeRef,
+                                                    kSecPasswordNumberOfGroups, numberOfGroupsRef,
+                                                    NULL);
+            break;
+            
+        case(kSecPasswordTypePIN):
+            numReqChars = CFNumberCreateWithCFIndex(kCFAllocatorDefault, defaultPINLength);
+            groupSize = 4;
+            numberOfGroups = 1;
+            groupSizeRef = CFNumberCreate(NULL, kCFNumberIntType, &groupSize);
+            numberOfGroupsRef = CFNumberCreate(NULL, kCFNumberIntType, &numberOfGroups);
+
+            decimalDigitCharacterSet = CFCharacterSetGetPredefined(kCFCharacterSetDecimalDigit);
+            CFArrayAppendValue(requiredCharacterSets, decimalDigitCharacterSet);
+            *returned = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
+                                                                         kSecUseDefaultPasswordFormatKey,   defaultPasswordFormat,
+                                                                         kSecNumberOfRequiredRandomCharactersKey, numReqChars,
+                                                                         kSecAllowedCharactersKey,   defaultPINCharacters,
+                                                                         kSecRequiredCharacterSetsKey, requiredCharacterSets,
+                                                                         kSecPasswordGroupSize, groupSizeRef,
+                                                                         kSecPasswordNumberOfGroups, numberOfGroupsRef,
+                                                                         NULL);
+            break;
+
+        case(kSecPasswordTypeWifi):
+            groupSize = 4;
+            numberOfGroups = 3;
+            groupSizeRef = CFNumberCreate(NULL, kCFNumberIntType, &groupSize);
+            numberOfGroupsRef = CFNumberCreate(NULL, kCFNumberIntType, &numberOfGroups);
+
+            lowercaseLetterCharacterSet = CFCharacterSetGetPredefined(kCFCharacterSetLowercaseLetter);
+            decimalDigitCharacterSet = CFCharacterSetGetPredefined(kCFCharacterSetDecimalDigit);
+
+            numReqChars = CFNumberCreateWithCFIndex(kCFAllocatorDefault, defaultWifiPasswordLength);
+            CFArrayAppendValue(requiredCharacterSets, lowercaseLetterCharacterSet);
+            CFArrayAppendValue(requiredCharacterSets, decimalDigitCharacterSet);
+            *returned = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
+                                                                         kSecUseDefaultPasswordFormatKey,   defaultPasswordFormat,
+                                                                         kSecNumberOfRequiredRandomCharactersKey, numReqChars,
+                                                                         kSecAllowedCharactersKey,   defaultWifiCharacters,
+                                                                         kSecRequiredCharacterSetsKey, requiredCharacterSets,
+                                                                         kSecPasswordGroupSize, groupSizeRef,
+                                                                         kSecPasswordNumberOfGroups, numberOfGroupsRef,
+                                                                         NULL);
+            break;
+            
+        default:
+            groupSize = 4;
+            numberOfGroups = 6;
+            groupSizeRef = CFNumberCreate(NULL, kCFNumberIntType, &groupSize);
+            numberOfGroupsRef = CFNumberCreate(NULL, kCFNumberIntType, &numberOfGroups);
+            uppercaseLetterCharacterSet = CFCharacterSetGetPredefined(kCFCharacterSetUppercaseLetter);
+            lowercaseLetterCharacterSet = CFCharacterSetGetPredefined(kCFCharacterSetLowercaseLetter);
+            decimalDigitCharacterSet = CFCharacterSetGetPredefined(kCFCharacterSetDecimalDigit);
+            CFArrayAppendValue(requiredCharacterSets, uppercaseLetterCharacterSet);
+            CFArrayAppendValue(requiredCharacterSets, lowercaseLetterCharacterSet);
+            CFArrayAppendValue(requiredCharacterSets, decimalDigitCharacterSet);
+
+            numReqChars = CFNumberCreateWithCFIndex(kCFAllocatorDefault, defaultNumberOfRandomCharacters);
+            *returned = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
+                                                                         kSecUseDefaultPasswordFormatKey,   defaultPasswordFormat,
+                                                                         kSecNumberOfRequiredRandomCharactersKey, numReqChars,
+                                                                         kSecAllowedCharactersKey,   defaultCharacters,
+                                                                         kSecRequiredCharacterSetsKey, requiredCharacterSets,
+                                                                         kSecPasswordGroupSize, groupSizeRef,
+                                                                         kSecPasswordNumberOfGroups, numberOfGroupsRef,
+                                                                         NULL);
+            
+            
+
+            break;
+    }
+    
+    CFReleaseNull(numReqChars);
+    CFReleaseNull(requiredCharacterSets);
+    CFReleaseNull(groupSizeRef);
+    CFReleaseNull(numberOfGroupsRef);
+}
+static void passwordGenerationParametersDictionary(CFDictionaryRef *returned, SecPasswordType type, CFDictionaryRef requirements)
+{
+    CFMutableArrayRef requiredCharacterSets = CFArrayCreateMutable(NULL, 0, NULL);
+    CFArrayRef requiredCharactersArray = NULL;
+    CFNumberRef numReqChars = NULL;
+    CFIndex numberOfRequiredRandomCharacters;
+    CFStringRef allowedCharacters = NULL, useDefaultPasswordFormat = NULL;
+    uint64_t valuePtr;
+    CFTypeRef prohibitedCharacters = NULL, endWith = NULL, startWith = NULL,
+            groupSizeRef = NULL, numberOfGroupsRef = NULL, separatorRef = NULL,
+            atMostCharactersRef = NULL,atLeastCharactersRef = NULL, identicalRef = NULL;
+    
+    CFNumberRef min = (CFNumberRef)CFDictionaryGetValue(requirements, kSecPasswordMinLengthKey);
+    CFNumberRef max = (CFNumberRef)CFDictionaryGetValue(requirements, kSecPasswordMaxLengthKey);
+    
+    CFNumberGetValue(min, kCFNumberSInt64Type, &valuePtr);
+    CFIndex minPasswordLength = (long)valuePtr;
+    CFNumberGetValue(max, kCFNumberSInt64Type, &valuePtr);
+    CFIndex maxPasswordLength = (long)valuePtr;
+    
+    // If requirements allow, we will generate the password in default format.
+    useDefaultPasswordFormat = CFSTR("true");
+    numberOfRequiredRandomCharacters = defaultNumberOfRandomCharacters;
+    
+    if(type == kSecPasswordTypePIN)
+    {
+        if( maxPasswordLength && minPasswordLength )
+            numberOfRequiredRandomCharacters = maxPasswordLength;
+        else if( !maxPasswordLength && minPasswordLength )
+            numberOfRequiredRandomCharacters = minPasswordLength;
+        else if( !minPasswordLength && maxPasswordLength )
+            numberOfRequiredRandomCharacters = maxPasswordLength;
+        else
+            numberOfRequiredRandomCharacters = defaultPINLength;
+        
+        allowedCharacters = CFSTR("0123456789");
+        CFArrayAppendValue(requiredCharacterSets, decimalDigitCharacterSet);
+        requiredCharactersArray = CFArrayCreateCopy(NULL, requiredCharacterSets);
+        useDefaultPasswordFormat = CFSTR("false");
+    }
+    else{
+        if (minPasswordLength && minPasswordLength > defaultNumberOfRandomCharacters) {
+            useDefaultPasswordFormat = CFSTR("false");
+            numberOfRequiredRandomCharacters = minPasswordLength;
+        }
+        if (maxPasswordLength && maxPasswordLength < defaultNumberOfRandomCharacters) {
+            useDefaultPasswordFormat = CFSTR("false");
+            numberOfRequiredRandomCharacters = maxPasswordLength;
+        }
+        if (maxPasswordLength && minPasswordLength && maxPasswordLength == minPasswordLength && maxPasswordLength != defaultNumberOfRandomCharacters){
+            useDefaultPasswordFormat = CFSTR("false");
+            numberOfRequiredRandomCharacters = maxPasswordLength;
+        }
+        allowedCharacters = (CFStringRef)CFDictionaryGetValue(requirements, kSecPasswordAllowedCharactersKey);
+        requiredCharactersArray = (CFArrayRef)CFDictionaryGetValue(requirements, kSecPasswordRequiredCharactersKey);
+    }
+    if(!CFDictionaryGetValueIfPresent(requirements, kSecPasswordDisallowedCharacters, &prohibitedCharacters))
+        prohibitedCharacters = NULL;
+    
+    if(!CFDictionaryGetValueIfPresent(requirements, kSecPasswordCantEndWithChars, &endWith))
+        endWith = NULL;
+    
+    if(!CFDictionaryGetValueIfPresent(requirements, kSecPasswordCantStartWithChars, &startWith))
+        startWith = NULL;
+    
+    if(!CFDictionaryGetValueIfPresent(requirements, kSecPasswordGroupSize, &groupSizeRef))
+        groupSizeRef = NULL;
+    
+    if(!CFDictionaryGetValueIfPresent(requirements, kSecPasswordNumberOfGroups, &numberOfGroupsRef))
+        numberOfGroupsRef = NULL;
+    
+    if(!CFDictionaryGetValueIfPresent(requirements, kSecPasswordSeparator, &separatorRef))
+        separatorRef = NULL;
+    
+    if(!CFDictionaryGetValueIfPresent(requirements, kSecPasswordContainsNoMoreThanNSpecificCharacters, &atMostCharactersRef))
+        atMostCharactersRef = NULL;
+    
+    if(!CFDictionaryGetValueIfPresent(requirements, kSecPasswordContainsAtLeastNSpecificCharacters, &atLeastCharactersRef))
+        atLeastCharactersRef = NULL;
+    
+    if(!CFDictionaryGetValueIfPresent(requirements, kSecPasswordContainsNoMoreThanNConsecutiveIdenticalCharacters, &identicalRef))
+        identicalRef = NULL;
+    
+    if (allowedCharacters) {
+        if( false == CFStringFindWithOptions(allowedCharacters, CFSTR("-"), CFRangeMake(0, CFStringGetLength(allowedCharacters)), kCFCompareCaseInsensitive, NULL))
+            useDefaultPasswordFormat = CFSTR("false");
+    } else
+        allowedCharacters = defaultCharacters;
+    
+    // In default password format, we use dashes only as separators, not as symbols you can encounter at a random position.
+    if (useDefaultPasswordFormat == CFSTR("false")){
+        CFMutableStringRef mutatedAllowedCharacters = CFStringCreateMutableCopy(kCFAllocatorDefault, CFStringGetLength(allowedCharacters), allowedCharacters);
+        CFStringFindAndReplace (mutatedAllowedCharacters, CFSTR("-"), CFSTR(""), CFRangeMake(0, CFStringGetLength(allowedCharacters)),kCFCompareCaseInsensitive);
+        allowedCharacters = CFStringCreateCopy(kCFAllocatorDefault, mutatedAllowedCharacters);
+    }
+    
+    if (requiredCharactersArray) {
+        for (CFIndex i = 0; i < CFArrayGetCount(requiredCharactersArray); i++){
+            CFCharacterSetRef stringWithRequiredCharacters = CFArrayGetValueAtIndex(requiredCharactersArray, i);
+            if( CFStringFindCharacterFromSet(allowedCharacters, stringWithRequiredCharacters, CFRangeMake(0, CFStringGetLength(allowedCharacters)), 0, NULL)){
+                CFArrayAppendValue(requiredCharacterSets, stringWithRequiredCharacters);
+            }
+        }
+    } else{
+        uppercaseLetterCharacterSet = CFCharacterSetGetPredefined(kCFCharacterSetUppercaseLetter);
+        lowercaseLetterCharacterSet = CFCharacterSetGetPredefined(kCFCharacterSetLowercaseLetter);
+        decimalDigitCharacterSet = CFCharacterSetGetPredefined(kCFCharacterSetDecimalDigit);
+        CFArrayAppendValue(requiredCharacterSets, uppercaseLetterCharacterSet);
+        CFArrayAppendValue(requiredCharacterSets, lowercaseLetterCharacterSet);
+        CFArrayAppendValue(requiredCharacterSets, decimalDigitCharacterSet);
+    }
+    
+    
+    if (CFArrayGetCount(requiredCharacterSets) > numberOfRequiredRandomCharacters) {
+        CFReleaseNull(requiredCharacterSets);
+        requiredCharacterSets = NULL;
+    }
+    //create new CFDictionary
+    numReqChars = CFNumberCreateWithCFIndex(kCFAllocatorDefault, numberOfRequiredRandomCharacters);
+    CFMutableDictionaryRef updatedConstraints = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
+    CFDictionaryAddValue(updatedConstraints, kSecUseDefaultPasswordFormatKey, useDefaultPasswordFormat);
+    CFDictionarySetValue(updatedConstraints, kSecNumberOfRequiredRandomCharactersKey, numReqChars);
+    CFDictionaryAddValue(updatedConstraints, kSecAllowedCharactersKey, allowedCharacters);
+    if(requiredCharacterSets)
+        CFDictionaryAddValue(updatedConstraints, kSecRequiredCharacterSetsKey, requiredCharacterSets);
+    
+    //add the prohibited characters string if it exists to the new dictionary
+    if(prohibitedCharacters)
+        CFDictionaryAddValue(updatedConstraints, kSecPasswordDisallowedCharacters, prohibitedCharacters);
+    
+    //add the characters the password can't end with if it exists to the new dictionary
+    if(endWith)
+        CFDictionaryAddValue(updatedConstraints, kSecPasswordCantEndWithChars, endWith);
+    
+    //add the characters the password can't start with if it exists to the new dictionary
+    if(startWith)
+        CFDictionaryAddValue(updatedConstraints, kSecPasswordCantStartWithChars, startWith);
+    
+    if(groupSizeRef)
+        CFDictionaryAddValue(updatedConstraints, kSecPasswordGroupSize, groupSizeRef);
+    
+    if(numberOfGroupsRef)
+        CFDictionaryAddValue(updatedConstraints, kSecPasswordNumberOfGroups, numberOfGroupsRef);
+    
+    if(separatorRef)
+        CFDictionaryAddValue(updatedConstraints, kSecPasswordSeparator, separatorRef);
+    
+    if(atMostCharactersRef)
+        CFDictionaryAddValue(updatedConstraints, kSecPasswordContainsNoMoreThanNSpecificCharacters, atMostCharactersRef);
+    
+    if(atLeastCharactersRef)
+        CFDictionaryAddValue(updatedConstraints, kSecPasswordContainsAtLeastNSpecificCharacters, atLeastCharactersRef);
+    
+    if(identicalRef)
+        CFDictionaryAddValue(updatedConstraints, kSecPasswordContainsNoMoreThanNConsecutiveIdenticalCharacters, identicalRef);
+    
+    CFReleaseNull(useDefaultPasswordFormat);
+    CFReleaseNull(numReqChars);
+    CFReleaseNull(allowedCharacters);
+    CFReleaseNull(requiredCharacterSets);
+    
+    *returned = CFDictionaryCreateCopy(kCFAllocatorDefault, updatedConstraints);
+}
+
+static bool isDictionaryFormattedProperly(SecPasswordType type, CFDictionaryRef passwordRequirements, CFErrorRef *error){
+    
+    CFTypeRef defaults = NULL;
+    CFErrorRef tempError = NULL;
+    if(passwordRequirements == NULL){
+        return true;
+    }
+    
+    if( CFDictionaryGetValueIfPresent(passwordRequirements, kSecPasswordDefaultForType, &defaults) ){
+        if(isString(defaults) == true && 0 == CFStringCompare(defaults, CFSTR("true"), 0)){
+            return true;
+        }
+    }
+    //only need to check max and min pin length formatting
+    if(type == kSecPasswordTypePIN){
+        CFTypeRef minTest = NULL, maxTest = NULL;
+        uint64_t valuePtr;
+        CFIndex minPasswordLength = 0, maxPasswordLength= 0;
+        
+        if( CFDictionaryGetValueIfPresent(passwordRequirements, kSecPasswordDefaultForType, &defaults) ){
+            if(isString(defaults) == true && 0 == CFStringCompare(defaults, CFSTR("true"), 0)){
+                return true;
+            }
+        }
+        //check if the values exist!
+        if( CFDictionaryGetValueIfPresent(passwordRequirements, kSecPasswordMaxLengthKey, &maxTest) ){
+            require_action_quiet(isNull(maxTest)!= true, fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("To generate a password, need a max length"), (CFIndex)errSecBadReq, NULL));
+            require_action_quiet(isNumber(maxTest), fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The password's max length must be a CFNumberRef"), (CFIndex)errSecBadReq, NULL));
+            
+        }
+        if (CFDictionaryGetValueIfPresent(passwordRequirements, kSecPasswordMinLengthKey, &minTest) ){
+            require_action_quiet(isNull(minTest)!= true, fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("To generate a password, need a min length"), (CFIndex)errSecBadReq, NULL));
+            require_action_quiet(isNumber(minTest), fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The password's min length must be a CFNumberRef"), (CFIndex)errSecBadReq, NULL));
+        }
+        //check if the values exist!
+        if(maxTest){
+            CFNumberRef max = (CFNumberRef)maxTest;
+            CFNumberGetValue(max, kCFNumberSInt64Type, &valuePtr);
+            maxPasswordLength = (long)valuePtr;
+        }
+        if(minTest){
+            CFNumberRef min = (CFNumberRef)minTest;
+            CFNumberGetValue(min, kCFNumberSInt64Type, &valuePtr);
+            minPasswordLength = (long)valuePtr;
+        }
+        //make sure min and max make sense respective to each other and that they aren't less than 4 digits.
+        require_action_quiet(minPasswordLength && maxPasswordLength && minPasswordLength <= maxPasswordLength, fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The password's length parameters make no sense ( is max < min ?)"),  (CFIndex)errSecBadReq, NULL));
+        require_action_quiet((minPasswordLength && minPasswordLength >= 4) || (maxPasswordLength && maxPasswordLength >= 4), fail, tempError = CFErrorCreate(kCFAllocatorDefault,  CFSTR("The password's length parameters make no sense ( is max < min ?)"),  (CFIndex)errSecBadReq, NULL));
+    }
+    else{
+        CFTypeRef allowedTest, maxTest, minTest, requiredTest, prohibitedCharacters, endWith, startWith,
+        groupSizeRef, numberOfGroupsRef, separatorRef, atMostCharactersRef,
+        atLeastCharactersRef, thresholdRef, identicalRef, characters;
+        uint64_t valuePtr;
+        
+        //check if the values exist!
+        require_action_quiet(CFDictionaryGetValueIfPresent(passwordRequirements, kSecPasswordAllowedCharactersKey, &allowedTest), fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("Need a string of characters; password must only contain characters in this string"),  (CFIndex)errSecBadReq, NULL));
+        require_action_quiet( CFDictionaryGetValueIfPresent(passwordRequirements, kSecPasswordMaxLengthKey, &maxTest), fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("To generate a password, need a max length"), (CFIndex)errSecBadReq, NULL));
+        require_action_quiet( CFDictionaryGetValueIfPresent(passwordRequirements, kSecPasswordMinLengthKey, &minTest), fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("To generate a password, need a min length"), (CFIndex)errSecBadReq, NULL));
+        require_action_quiet(CFDictionaryGetValueIfPresent(passwordRequirements, kSecPasswordRequiredCharactersKey, &requiredTest), fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("Need an array of character sets, password must have at least 1 character from each set"), (CFIndex)errSecBadReq, NULL));
+        
+        //check if values are null?
+        require_action_quiet(isNull(allowedTest) != true, fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("Need a string of characters; password must only contain characters in this string"),  (CFIndex)errSecBadReq, NULL));
+        require_action_quiet(isNull(maxTest)!= true, fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("To generate a password, need a max length"), (CFIndex)errSecBadReq, NULL));
+        require_action_quiet(isNull(minTest)!= true, fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("To generate a password, need a min length"), (CFIndex)errSecBadReq, NULL));
+        require_action_quiet(isNull(requiredTest)!= true, fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("Need an array of character sets, password must have at least 1 character from each set"), (CFIndex)errSecBadReq, NULL));
+        
+        //check if the values are correct
+        require_action_quiet(isString(allowedTest), fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The password's allowed characters must be a CFStringRef"), (CFIndex)errSecBadReq, NULL));
+        require_action_quiet(isNumber(maxTest), fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The password's max length must be a CFNumberRef"), (CFIndex)errSecBadReq, NULL));
+        require_action_quiet(isNumber(minTest), fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The password's min length must be a CFNumberRef"), (CFIndex)errSecBadReq, NULL));
+        require_action_quiet(isArray(requiredTest), fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The password's required characters must be an array of CFCharacterSetRefs"), (CFIndex)errSecBadReq, NULL));
+        
+        CFNumberGetValue(minTest, kCFNumberSInt64Type, &valuePtr);
+        CFIndex minPasswordLength = (long)valuePtr;
+        CFNumberGetValue(maxTest, kCFNumberSInt64Type, &valuePtr);
+        CFIndex maxPasswordLength = (long)valuePtr;
+        
+        require_action_quiet(minPasswordLength <= maxPasswordLength, fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The password's length parameters make no sense ( is max < min ?)"),  (CFIndex)errSecBadReq, NULL));
+
+        require_action_quiet(CFStringGetLength((CFStringRef)allowedTest) != 0, fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("Need a string of characters; password must only contain characters in this string"),  (CFIndex)errSecBadReq, NULL));
+        require_action_quiet(CFArrayGetCount((CFArrayRef)requiredTest), fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("Need an array of character sets, password must have at least 1 character from each set"), (CFIndex)errSecBadReq, NULL));
+        
+        if(CFDictionaryGetValueIfPresent(passwordRequirements, kSecPasswordDisallowedCharacters, &prohibitedCharacters)){
+            require_action_quiet(isNull(prohibitedCharacters) != true, fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("Disallowed Characters dictionary parameter is either null or not a string"),  (CFIndex)errSecBadReq, NULL));
+            require_action_quiet(isString(prohibitedCharacters), fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("Disallowed Characters dictionary parameter is either null or not a string"), (CFIndex)errSecBadReq, NULL));
+        }
+        if(CFDictionaryGetValueIfPresent(passwordRequirements, kSecPasswordCantEndWithChars, &endWith)){
+            require_action_quiet(isNull(endWith) != true, fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The dictionary parameter 'EndWith' is either null or not a string"),  (CFIndex)errSecBadReq, NULL));
+            require_action_quiet(isString(endWith), fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The dictionary parameter 'EndWith' is either null or not a string"), (CFIndex)errSecBadReq, NULL));
+        }
+        if(CFDictionaryGetValueIfPresent(passwordRequirements, kSecPasswordCantStartWithChars, &startWith)){
+            require_action_quiet(isNull(startWith) != true, fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The dictionary parameter 'StartWith' is either null or not a string"),  (CFIndex)errSecBadReq, NULL));
+            require_action_quiet(isString(startWith), fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The dictionary parameter 'StartWith' is either null or not a string"), (CFIndex)errSecBadReq, NULL));
+        }
+        if(CFDictionaryGetValueIfPresent(passwordRequirements, kSecPasswordGroupSize, &groupSizeRef)){
+            require_action_quiet(isNull(groupSizeRef) != true, fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The dictionary parameter 'groupsize' is either null or not a number"),  (CFIndex)errSecBadReq, NULL));
+            require_action_quiet(isNumber(groupSizeRef), fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The dictionary parameter 'groupsize' is either null or not a number"), (CFIndex)errSecBadReq, NULL));
+        }
+        if(CFDictionaryGetValueIfPresent(passwordRequirements, kSecPasswordNumberOfGroups, &numberOfGroupsRef)){
+            require_action_quiet(isNull(numberOfGroupsRef) != true, fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The dictionary parameter 'number of groupds' is either null or not a number"),  (CFIndex)errSecBadReq, NULL));
+            require_action_quiet(isNumber(numberOfGroupsRef), fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The dictionary parameter 'number of groupds' is either null or not a number"), (CFIndex)errSecBadReq, NULL));
+        }
+        if(CFDictionaryGetValueIfPresent(passwordRequirements, kSecPasswordSeparator, &separatorRef)){
+            require_action_quiet(isNull(separatorRef) != true, fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The dictionary parameter 'password separator character' is either null or not a string"),  (CFIndex)errSecBadReq, NULL));
+            require_action_quiet(isString(separatorRef), fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The dictionary parameter 'password separator character' is either null or not a string"), (CFIndex)errSecBadReq, NULL));
+        }
+        
+        if(CFDictionaryGetValueIfPresent(passwordRequirements, kSecPasswordContainsNoMoreThanNSpecificCharacters, &atMostCharactersRef)){
+            require_action_quiet(isNull(atMostCharactersRef) != true, fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The dictionary parameter 'At Most N Characters' is either null or not a string"),  (CFIndex)errSecBadReq, NULL));
+            require_action_quiet(isDictionary(atMostCharactersRef), fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The dictionary parameter 'At Most N Characters' is either null or not a string"), (CFIndex)errSecBadReq, NULL));
+            
+            require_action_quiet(CFDictionaryGetValueIfPresent(atMostCharactersRef, kSecPasswordCharacterCount, &thresholdRef) != false, fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The dictionary parameter 'At Most N Characters' is either null or not a string"),  (CFIndex)errSecBadReq, NULL));
+            require_action_quiet(isNull(thresholdRef) != true, fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The dictionary parameter 'characters' is either null or not a number"),  (CFIndex)errSecBadReq, NULL));
+            require_action_quiet(isNumber(thresholdRef), fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The dictionary parameter 'characters' is either null or not a number"), (CFIndex)errSecBadReq, NULL));
+            
+            require_action_quiet(CFDictionaryGetValueIfPresent(atMostCharactersRef, kSecPasswordCharacters, &characters)!= false, fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The dictionary parameter 'At Most N Characters' is either null or not a string"),  (CFIndex)errSecBadReq, NULL));
+            require_action_quiet(isNull(characters) != true, fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The dictionary parameter 'Characters' is either null or not a string"),  (CFIndex)errSecBadReq, NULL));
+            require_action_quiet(isString(characters), fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The dictionary parameter 'Characters' is either null or not a string"), (CFIndex)errSecBadReq, NULL));
+        }
+        
+        if(CFDictionaryGetValueIfPresent(passwordRequirements, kSecPasswordContainsAtLeastNSpecificCharacters, &atLeastCharactersRef)){
+            require_action_quiet(isNull(atLeastCharactersRef) != true, fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The dictionary parameter 'At Least N Characters' is either null or not a string"),  (CFIndex)errSecBadReq, NULL));
+            require_action_quiet(isDictionary(atLeastCharactersRef), fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The dictionary parameter 'At Least N Characters' is either null or not a string"), (CFIndex)errSecBadReq, NULL));
+            
+            require_action_quiet(CFDictionaryGetValueIfPresent(atLeastCharactersRef, kSecPasswordCharacterCount, &thresholdRef) != false, fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The dictionary parameter 'At Least N Characters' is either null or not a string"),  (CFIndex)errSecBadReq, NULL));
+            
+            require_action_quiet(isNull(thresholdRef) != true, fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The dictionary parameter 'characters' is either null or not a number"),  (CFIndex)errSecBadReq, NULL));
+            require_action_quiet(isNumber(thresholdRef), fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The dictionary parameter 'characters' is either null or not a number"), (CFIndex)errSecBadReq, NULL));
+            
+            require_action_quiet(CFDictionaryGetValueIfPresent(atLeastCharactersRef, kSecPasswordCharacters, &characters) != false, fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The dictionary parameter 'At Least N Characters' is either null or not a string"),  (CFIndex)errSecBadReq, NULL));
+            require_action_quiet(isNull(characters) != true, fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The dictionary parameter 'Characters' is either null or not a string"),  (CFIndex)errSecBadReq, NULL));
+            require_action_quiet(isString(characters), fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The dictionary parameter 'Characters' is either null or not a string"), (CFIndex)errSecBadReq, NULL));
+        }
+       
+        if(CFDictionaryGetValueIfPresent(passwordRequirements, kSecPasswordContainsNoMoreThanNConsecutiveIdenticalCharacters, &identicalRef)){
+            require_action_quiet(isNull(identicalRef) != true, fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The dictionary parameter 'Identical Consecutive Characters' is either null or not a number"),  (CFIndex)errSecBadReq, NULL));
+            require_action_quiet(isNumber(identicalRef), fail, tempError = CFErrorCreate(kCFAllocatorDefault, CFSTR("The dictionary parameter 'Identical Consecutive Characters' is either null or not a number"), (CFIndex)errSecBadReq, NULL));
+        }
+    }
+fail:
+    if (tempError != NULL) {
+        *error = tempError;
+        CFRetain(*error);
+        return false;
+    }
+    
+    CFReleaseNull(tempError);
+    return true;
+}
+
+static bool doesFinalPasswordPass(CFStringRef password, CFDictionaryRef requirements){
+    
+    CFTypeRef characters, identicalRef = NULL, NRef = NULL, endWith= NULL, startWith= NULL, atLeastCharacters= NULL, atMostCharacters = NULL;
+    uint64_t valuePtr;
+    CFIndex N, identicalCount;
+    CFArrayRef requiredCharacterSet = (CFArrayRef)CFDictionaryGetValue(requirements, kSecRequiredCharacterSetsKey);
+    
+    if(!CFDictionaryGetValueIfPresent(requirements, kSecPasswordCantEndWithChars, &endWith))
+        endWith = NULL;
+    
+    if(!CFDictionaryGetValueIfPresent(requirements, kSecPasswordCantStartWithChars, &startWith))
+        startWith = NULL;
+    
+    if(!CFDictionaryGetValueIfPresent(requirements, kSecPasswordContainsAtLeastNSpecificCharacters, &atLeastCharacters))
+        atLeastCharacters = NULL;
+    
+    if(!CFDictionaryGetValueIfPresent(requirements, kSecPasswordContainsNoMoreThanNSpecificCharacters, &atMostCharacters))
+        atMostCharacters = NULL;
+    
+    if(!CFDictionaryGetValueIfPresent(requirements, kSecPasswordContainsNoMoreThanNConsecutiveIdenticalCharacters, &identicalRef))
+        identicalRef = NULL;
+    else{
+        CFNumberGetValue((CFNumberRef)identicalRef, kCFNumberSInt64Type, &valuePtr);
+        identicalCount = (long)valuePtr;
+    }
+    if(endWith != NULL)
+    {
+        if(!doesPasswordEndWith(password, endWith))
+            return false;
+    }
+    if(startWith != NULL){
+        if(!doesPasswordStartWith(password, startWith))
+            return false;
+    }
+    if(atLeastCharacters != NULL){
+        NRef = CFDictionaryGetValue(atLeastCharacters, kSecPasswordCharacterCount);
+        characters = CFDictionaryGetValue(atLeastCharacters, kSecPasswordCharacters);
+        CFNumberGetValue((CFNumberRef)NRef, kCFNumberSInt64Type, &valuePtr);
+        N = (long)valuePtr;
+        if(!passwordContainsAtLeastNCharacters(password, characters, N))
+            return false;
+    }
+    if(atMostCharacters != NULL){
+        NRef = CFDictionaryGetValue(atMostCharacters, kSecPasswordCharacterCount);
+        characters = CFDictionaryGetValue(atMostCharacters, kSecPasswordCharacters);
+        CFNumberGetValue((CFNumberRef)NRef, kCFNumberSInt64Type, &valuePtr);
+        N = (long)valuePtr;
+        if(!passwordContainsLessThanNCharacters(password, characters, N))
+            return false;
+    }
+    if(identicalRef != NULL){
+        if(!passwordContainsLessThanNIdenticalCharacters(password, identicalCount))
+            return false;
+    }
+    if (!passwordContainsRequiredCharacters(password, requiredCharacterSet))
+        return false;
+    
+    if(true == SecPasswordIsPasswordWeak(password))
+        return false;
+    
+    return true;
+}
+
+//entry point into password generation
+CF_RETURNS_RETAINED CFStringRef SecPasswordGenerate(SecPasswordType type, CFErrorRef *error, CFDictionaryRef passwordRequirements){
+    bool check = false;
+    CFTypeRef separator = NULL, defaults = NULL, groupSizeRef = NULL, numberOfGroupsRef = NULL;
+    CFDictionaryRef properlyFormattedRequirements = NULL;
+    *error = NULL;
+    uint64_t valuePtr, groupSize, numberOfGroups;
+    CFNumberRef numberOfRequiredRandomCharacters;
+    CFIndex requiredCharactersSize;
+    CFStringRef randomCharacters = NULL, password = NULL, allowedChars = NULL;
+    CFMutableStringRef finalPassword = NULL;
+    
+    check = isDictionaryFormattedProperly(type, passwordRequirements, error);
+    require_quiet(check != false, fail);
+    
+    //should we generate defaults?
+    if(passwordRequirements == NULL || (CFDictionaryGetValueIfPresent(passwordRequirements, kSecPasswordDefaultForType, &defaults) && isString(defaults) == true && 0 == CFStringCompare(defaults, CFSTR("true"), 0) ))
+        passwordGenerateDefaultParametersDictionary(&properlyFormattedRequirements, type, passwordRequirements);
+    else
+        passwordGenerationParametersDictionary(&properlyFormattedRequirements, type, passwordRequirements);
+    
+    CFRetain(properlyFormattedRequirements);
+    
+    require_quiet(*error == NULL && properlyFormattedRequirements != NULL, fail);
+    
+    numberOfRequiredRandomCharacters = (CFNumberRef)CFDictionaryGetValue(properlyFormattedRequirements, kSecNumberOfRequiredRandomCharactersKey);
+    CFNumberGetValue(numberOfRequiredRandomCharacters, kCFNumberSInt64Type, &valuePtr);
+    requiredCharactersSize = (long)valuePtr;
+    
+    if(!CFDictionaryGetValueIfPresent(properlyFormattedRequirements, kSecPasswordGroupSize, &groupSizeRef)){
+        groupSizeRef = NULL;
+    }
+    else
+        CFNumberGetValue((CFNumberRef)groupSizeRef, kCFNumberSInt64Type, &groupSize);
+    
+    if(!CFDictionaryGetValueIfPresent(properlyFormattedRequirements, kSecPasswordNumberOfGroups, &numberOfGroupsRef)){
+        numberOfGroupsRef = NULL;
+    }
+    else
+        CFNumberGetValue((CFNumberRef)numberOfGroupsRef, kCFNumberSInt64Type, &numberOfGroups);
+    
+    while (true) {
+        allowedChars = CFDictionaryGetValue(properlyFormattedRequirements, kSecAllowedCharactersKey);
+        getPasswordRandomCharacters(&randomCharacters, properlyFormattedRequirements, &requiredCharactersSize, allowedChars);
+        
+        if(numberOfGroupsRef && groupSizeRef){
+            finalPassword = CFStringCreateMutable(kCFAllocatorDefault, 0);
+            
+            if(!CFDictionaryGetValueIfPresent(properlyFormattedRequirements, kSecPasswordSeparator, &separator))
+                separator = NULL;
+            
+            if(separator == NULL)
+                separator = CFSTR("-");
+            
+            CFIndex i = 0;
+            while( i != requiredCharactersSize){
+                if((i + (CFIndex)groupSize) < requiredCharactersSize){
+                    CFStringAppend(finalPassword, CFStringCreateWithSubstring(kCFAllocatorDefault, randomCharacters, CFRangeMake(i, (CFIndex)groupSize)));
+                    CFStringAppend(finalPassword, separator);
+                    i+=groupSize;
+                }
+                else if((i+(CFIndex)groupSize) == requiredCharactersSize){
+                    CFStringAppend(finalPassword, CFStringCreateWithSubstring(kCFAllocatorDefault, randomCharacters, CFRangeMake(i, (CFIndex)groupSize)));
+                    i+=groupSize;
+                }
+                else {
+                    CFStringAppend(finalPassword, CFStringCreateWithSubstring(kCFAllocatorDefault, randomCharacters, CFRangeMake(i, requiredCharactersSize - i)));
+                    i+=(requiredCharactersSize - i);
+                }
+            }
+            password = CFStringCreateCopy(kCFAllocatorDefault, finalPassword);
+            CFReleaseNull(finalPassword);
+        }
+        //no fancy formatting
+        else {
+            password = CFStringCreateCopy(kCFAllocatorDefault, randomCharacters);
+        }
+        
+        CFReleaseNull(randomCharacters);
+        require_quiet(doesFinalPasswordPass(password, properlyFormattedRequirements), no_pass);
+        return password;
+        
+    no_pass:
+        CFReleaseNull(password);
+    }
+    
+fail:
+    CFReleaseNull(properlyFormattedRequirements);
+    return NULL;
+}
+
+const char *in_word_set (const char *str, unsigned int len){
+    static const char * wordlist[] =
+    {
+        "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
+        "", "", "0103", "", "", "", "", "0123", "", "", "", "", "0303", "", "", "",
+        "", "", "", "", "0110", "", "1103", "", "", "", "", "1123", "", "", "0000",
+        "", "1203", "", "0404", "", "", "", "", "1234", "1110", "2015", "2013", "",
+        "2014", "1010", "2005", "2003", "", "2004", "1210", "0505", "0111", "", "",
+        "", "2008", "0101", "", "2007", "", "", "", "", "2006", "2010", "1995", "1993",
+        "", "1994", "2000", "", "1111", "", "", "", "1998", "1101", "", "1997", "",
+        "0808", "1211", "", "1996", "0102", "", "1201", "", "", "1990", "", "", "",
+        "", "0202", "", "2011", "", "", "1112", "1958", "2001", "", "1957", "1102",
+        "", "3333", "", "1956", "1212", "1985", "1983", "", "1984", "1202", "", "0909",
+        "", "0606", "", "1988", "1991", "", "1987", "2012", "", "", "", "1986", "2002",
+        "", "", "", "0707", "1980", "", "2009", "", "", "2222", "1965", "1963", "",
+        "1964", "", "", "2229", "", "", "1992", "1968", "", "", "1967", "", "", "1999",
+        "", "1966", "", "1975", "1973", "", "1974", "1960", "", "1981", "", "4444",
+        "", "1978", "", "7465", "1977", "", "", "", "", "1976", "2580", "", "1959",
+        "", "", "1970", "", "", "", "", "", "", "", "", "", "1982", "", "1961", "",
+        "", "5252", "", "1989", "", "", "", "", "", "", "", "", "", "", "", "", "",
+        "", "1971", "", "", "", "", "", "", "", "1962", "", "5683", "", "6666", "",
+        "", "1969", "", "", "", "", "", "", "", "", "", "", "", "", "1972", "", "",
+        "", "", "", "", "1979", "", "", "", "7667"
+    };
+    
+    if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
+    {
+        register int key = pinhash (str, len);
+        
+        if (key <= MAX_HASH_VALUE && key >= 0)
+        {
+            register const char *s = wordlist[key];
+            if (*str == *s && !strcmp (str + 1, s + 1))
+                return s;
+        }
+    }
+    return 0;
+}
+CFDictionaryRef SecPasswordCopyDefaultPasswordLength(SecPasswordType type, CFErrorRef *error){
+    
+    CFIndex tupleLengthInt, numOfTuplesInt;
+    CFNumberRef tupleLength = NULL;
+    CFNumberRef numOfTuples = NULL;
+    
+    CFMutableDictionaryRef passwordLengthDefaults = NULL;
+
+    switch(type){
+        case(kSecPasswordTypeiCloudRecovery):
+            tupleLengthInt = 4;
+            numOfTuplesInt = 6;
+            tupleLength = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tupleLengthInt);
+            numOfTuples = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &numOfTuplesInt);
+            passwordLengthDefaults = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 0, 0);
+            CFDictionaryAddValue(passwordLengthDefaults, kSecPasswordGroupSize, tupleLength);
+            CFDictionaryAddValue(passwordLengthDefaults, kSecPasswordNumberOfGroups, numOfTuples);
+            return CFDictionaryCreateCopy(kCFAllocatorDefault, passwordLengthDefaults);
+
+        case(kSecPasswordTypePIN):
+            tupleLengthInt = 4;
+            numOfTuplesInt = 1;
+            tupleLength = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tupleLengthInt);
+            numOfTuples = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &numOfTuplesInt);
+            passwordLengthDefaults = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 0, 0);
+            CFDictionaryAddValue(passwordLengthDefaults, kSecPasswordGroupSize, tupleLength);
+            CFDictionaryAddValue(passwordLengthDefaults, kSecPasswordNumberOfGroups, numOfTuples);
+            return CFDictionaryCreateCopy(kCFAllocatorDefault, passwordLengthDefaults);
+        
+        case(kSecPasswordTypeSafari):
+            tupleLengthInt = 4;
+            numOfTuplesInt = 5;
+            tupleLength = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tupleLengthInt);
+            numOfTuples = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &numOfTuplesInt);
+            passwordLengthDefaults = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 0, 0);
+            CFDictionaryAddValue(passwordLengthDefaults, kSecPasswordGroupSize, tupleLength);
+            CFDictionaryAddValue(passwordLengthDefaults, kSecPasswordNumberOfGroups, numOfTuples);
+            return CFDictionaryCreateCopy(kCFAllocatorDefault, passwordLengthDefaults);
+
+        
+        case(kSecPasswordTypeWifi):
+            tupleLengthInt = 4;
+            numOfTuplesInt = 3;
+            tupleLength = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tupleLengthInt);
+            numOfTuples = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &numOfTuplesInt);
+            passwordLengthDefaults = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 0, 0);
+            CFDictionaryAddValue(passwordLengthDefaults, kSecPasswordGroupSize, tupleLength);
+            CFDictionaryAddValue(passwordLengthDefaults, kSecPasswordNumberOfGroups, numOfTuples);
+            return CFDictionaryCreateCopy(kCFAllocatorDefault, passwordLengthDefaults);
+
+        
+        default:
+            if(SecError(errSecBadReq, error, CFSTR("Password type does not exist.")) == false)
+            {
+                secdebug("secpasswordcopydefaultpasswordlength", "could not create error!");
+            }
+            return NULL;
+    }
+}
diff --git a/sec/Security/SecPasswordGenerate.h b/sec/Security/SecPasswordGenerate.h
new file mode 100644 (file)
index 0000000..012b9ab
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*!
+ @header SecPasswordGenerate
+ SecPassword implements logic to use the system facilities for acquiring a password,
+ optionally stored and retrieved from the user's keychain.
+ */
+
+#ifndef _SECURITY_SECPASSWORDGENERATE_H_
+#define _SECURITY_SECPASSWORDGENERATE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecBase.h>
+
+typedef uint32_t SecPasswordType;
+enum {
+    kSecPasswordTypeSafari = 0,
+    kSecPasswordTypeiCloudRecovery = 1,
+    kSecPasswordTypeWifi = 2,
+    kSecPasswordTypePIN = 3
+} __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+
+// Keys for external dictionaries with password generation requirements we read from plist.
+extern CFStringRef kSecPasswordDefaultForType
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+
+extern CFStringRef kSecPasswordMinLengthKey
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFStringRef kSecPasswordMaxLengthKey
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFStringRef kSecPasswordAllowedCharactersKey
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFStringRef kSecPasswordRequiredCharactersKey
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+
+extern CFStringRef kSecPasswordDisallowedCharacters
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFStringRef kSecPasswordCantStartWithChars
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFStringRef kSecPasswordCantEndWithChars
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+    
+extern CFStringRef kSecPasswordContainsNoMoreThanNSpecificCharacters
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFStringRef kSecPasswordContainsAtLeastNSpecificCharacters
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFStringRef kSecPasswordContainsNoMoreThanNConsecutiveIdenticalCharacters
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+    
+extern CFStringRef kSecPasswordCharacters
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFStringRef kSecPasswordCharacterCount
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+    
+extern CFStringRef kSecPasswordGroupSize
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFStringRef kSecPasswordNumberOfGroups
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFStringRef kSecPasswordSeparator
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+
+    
+/*
+    @function SecPasswordCopyDefaultPasswordLength
+    @abstract Returns the default length/number of tuples of a defaultly generated password
+    @param type: default password types kSecPasswordTypeSafari, kSecPasswordTypeiCloudRecovery, kSecPasswordTypeWifi, kSecPasswordTypePIN
+    @param error: An error code will be returned if an unrecognized password type is passed to the routine.
+    @result Dictionary consisting of length of tuple and number of tuples or a NULL if the passed type isn't recognized.
+*/
+CFDictionaryRef SecPasswordCopyDefaultPasswordLength(SecPasswordType type, CFErrorRef *error)
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+
+    
+/*
+ @function SecPasswordIsPasswordWeak
+ @abstract Evalutes the weakness of a passcode. This function can take any type of passcode.  Currently
+    the function evaluates passcodes with only ASCII characters
+ @param passcode a string of any length and type (4 digit PIN, complex passcode) 
+ @result True if the password is weak, False if the password is strong.
+ */
+
+bool SecPasswordIsPasswordWeak(CFStringRef passcode)
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+
+/*
+ @function SecPasswordGenerate.  Supports generating passwords for Safari, iCloud, Personal
+ Hotspot clients.  Will also generate 4 digit pins.
+ @abstract Returns a generated password based on a set of constraints
+ @param type: type of password to generate. Pass enum types
+ kSecPasswordTypeSafari, kSecPasswordTypeiCloudRecovery, kSecPasswordTypeWifi, or kSecPasswordTypePIN
+ @param error: An error code will be returned if an error is encountered.  Check SecBase.h for the list of codes.
+ @param passwordRequirements: a dictionary containing a set of password requirements.
+ ex: password type 'safari' requires at least: minLength, maxLength, string
+ of allowed characters, required characters
+ @return NULL or a CFStringRef password
+
+ *Note: This parameters is not required if kSecPasswordTypeiCloudRecovery or kSecPasswordTypePIN is supplied as the type.
+ If kSecPasswordTypeSafari or kSecPasswordTypeWifi is supplied, you must include these dictionary key/value pairs:
+ kSecPasswordMinLengthKey / CFNumberRef
+ kSecPasswordMaxLengthKey / CFNumberRef
+ kSecPasswordAllowedCharactersKey / CFStringRef
+ kSecPasswordRequiredCharactersKey / CFArrayRef of CFCharacterSetRefs
+  
+ *Note: Be sure to release the returned password when done using it.
+ */
+CF_RETURNS_RETAINED CFStringRef SecPasswordGenerate(SecPasswordType type, CFErrorRef *error, CFDictionaryRef passwordRequirements)
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_SECURITY_SECPASSWORDGENERATE_H_ */
index 953f51349250535c44001aa5f597e7fb9b457661..b2aaced092abcb5e559f2b3955595312a12096ba 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2007-2010 Apple Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2007-2013 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
-/* 
+/*
  * SecPolicy.c - Implementation of various X.509 certificate trust policies
  */
 
  * SecPolicy.c - Implementation of various X.509 certificate trust policies
  */
 
 #include <Security/SecPolicyPriv.h>
 #include <AssertMacros.h>
 #include <pthread.h>
 #include <Security/SecPolicyPriv.h>
 #include <AssertMacros.h>
 #include <pthread.h>
-#include <security_utilities/debugging.h>
+#include <utilities/debugging.h>
 #include <Security/SecInternal.h>
 #include <Security/SecInternal.h>
+#include <CoreFoundation/CFDictionary.h>
 #include <CoreFoundation/CFNumber.h>
 #include <CoreFoundation/CFRuntime.h>
 #include <CoreFoundation/CFString.h>
 #include <CoreFoundation/CFTimeZone.h>
 #include <Security/SecCertificateInternal.h>
 #include <CoreFoundation/CFNumber.h>
 #include <CoreFoundation/CFRuntime.h>
 #include <CoreFoundation/CFString.h>
 #include <CoreFoundation/CFTimeZone.h>
 #include <Security/SecCertificateInternal.h>
+#include <Security/SecCertificatePriv.h>
 #include <libDER/oids.h>
 #include <libDER/oids.h>
+#include <utilities/SecCFError.h>
+#include <utilities/SecCFWrappers.h>
+#include <utilities/array_size.h>
+#include <securityd_client.h>
 
 /********************************************************
  **************** SecPolicy Constants *******************
  ********************************************************/
 
 /********************************************************
  **************** SecPolicy Constants *******************
  ********************************************************/
-#pragma mark -
-#pragma mark SecPolicy Constants
+// MARK: -
+// MARK: SecPolicy Constants
+
+#define SEC_CONST_DECL(k,v) CFTypeRef k = (CFTypeRef)(CFSTR(v));
 
 /********************************************************
  ************** Unverified Leaf Checks ******************
 
 /********************************************************
  ************** Unverified Leaf Checks ******************
@@ -67,16 +75,22 @@ CFStringRef kSecPolicyCheckSubjectCommonNamePrefix = CFSTR("SubjectCommonNamePre
    matches the specified "<string>" or "TEST <string> TEST". */
 CFStringRef kSecPolicyCheckSubjectCommonNameTEST = CFSTR("SubjectCommonNameTEST");
 
    matches the specified "<string>" or "TEST <string> TEST". */
 CFStringRef kSecPolicyCheckSubjectCommonNameTEST = CFSTR("SubjectCommonNameTEST");
 
-/* Checks that the leaf has exactly one Organzation and that it
+/* Checks that the leaf has exactly one Organization and that it
    matches the specified string. */
 CFStringRef kSecPolicyCheckSubjectOrganization = CFSTR("SubjectOrganization");
 
    matches the specified string. */
 CFStringRef kSecPolicyCheckSubjectOrganization = CFSTR("SubjectOrganization");
 
+/* Checks that the leaf has exactly one Organizational Unit and that it
+   matches the specified string. */
+CFStringRef kSecPolicyCheckSubjectOrganizationalUnit = CFSTR("SubjectOrganizationalUnit");
+
 /* Check that the leaf is not valid before the specified date (or verifyDate
    if none is provided?). */
 CFStringRef kSecPolicyCheckNotValidBefore = CFSTR("NotValidBefore");
 
 CFStringRef kSecPolicyCheckEAPTrustedServerNames = CFSTR("EAPTrustedServerNames");
 
 /* Check that the leaf is not valid before the specified date (or verifyDate
    if none is provided?). */
 CFStringRef kSecPolicyCheckNotValidBefore = CFSTR("NotValidBefore");
 
 CFStringRef kSecPolicyCheckEAPTrustedServerNames = CFSTR("EAPTrustedServerNames");
 
+CFStringRef kSecPolicyCheckCertificatePolicy = CFSTR("CertificatePolicy");
+
 #if 0
 /* Check for basic constraints on leaf to be valid.  (rfc5280 check) */
 CFStringRef kSecPolicyCheckLeafBasicConstraints = CFSTR("LeafBasicContraints");
 #if 0
 /* Check for basic constraints on leaf to be valid.  (rfc5280 check) */
 CFStringRef kSecPolicyCheckLeafBasicConstraints = CFSTR("LeafBasicContraints");
@@ -145,12 +159,46 @@ CFStringRef kSecPolicyCheckNoNetworkAccess = CFSTR("NoNetworkAccess");
 
 /* Hack to quickly blacklist certain certs. */
 CFStringRef kSecPolicyCheckBlackListedLeaf = CFSTR("BlackListedLeaf");
 
 /* Hack to quickly blacklist certain certs. */
 CFStringRef kSecPolicyCheckBlackListedLeaf = CFSTR("BlackListedLeaf");
-CFStringRef kSecPolicyCheckBlackListedKey = CFSTR("BlackListedKey");
+CFStringRef kSecPolicyCheckGrayListedLeaf  = CFSTR("GrayListedLeaf");
+CFStringRef kSecPolicyCheckGrayListedKey   = CFSTR("GrayListedKey");
+CFStringRef kSecPolicyCheckBlackListedKey  = CFSTR("BlackListedKey");
 
 CFStringRef kSecPolicyCheckLeafMarkerOid = CFSTR("CheckLeafMarkerOid");
 CFStringRef kSecPolicyCheckIntermediateMarkerOid = CFSTR("CheckIntermediateMarkerOid");
 
 
 CFStringRef kSecPolicyCheckLeafMarkerOid = CFSTR("CheckLeafMarkerOid");
 CFStringRef kSecPolicyCheckIntermediateMarkerOid = CFSTR("CheckIntermediateMarkerOid");
 
-/* Policy names. */
+/* Public policy names. */
+SEC_CONST_DECL (kSecPolicyAppleX509Basic, "1.2.840.113635.100.1.2");
+SEC_CONST_DECL (kSecPolicyAppleSSL, "1.2.840.113635.100.1.3");
+SEC_CONST_DECL (kSecPolicyAppleSMIME, "1.2.840.113635.100.1.8");
+SEC_CONST_DECL (kSecPolicyAppleEAP, "1.2.840.113635.100.1.9");
+SEC_CONST_DECL (kSecPolicyAppleIPsec, "1.2.840.113635.100.1.11");
+SEC_CONST_DECL (kSecPolicyApplePKINITClient, "1.2.840.113635.100.1.14");
+SEC_CONST_DECL (kSecPolicyApplePKINITServer, "1.2.840.113635.100.1.15");
+SEC_CONST_DECL (kSecPolicyAppleCodeSigning, "1.2.840.113635.100.1.16");
+SEC_CONST_DECL (kSecPolicyApplePackageSigning, "1.2.840.113635.100.1.17");
+SEC_CONST_DECL (kSecPolicyAppleIDValidation, "1.2.840.113635.100.1.18");
+SEC_CONST_DECL (kSecPolicyMacAppStoreReceipt, "1.2.840.113635.100.1.19");
+SEC_CONST_DECL (kSecPolicyAppleTimeStamping, "1.2.840.113635.100.1.20");
+SEC_CONST_DECL (kSecPolicyAppleRevocation, "1.2.840.113635.100.1.21");
+SEC_CONST_DECL (kSecPolicyApplePassbookSigning, "1.2.840.113635.100.1.22");
+SEC_CONST_DECL (kSecPolicyAppleMobileStore, "1.2.840.113635.100.1.23");
+SEC_CONST_DECL (kSecPolicyAppleEscrowService, "1.2.840.113635.100.1.24");
+SEC_CONST_DECL (kSecPolicyAppleProfileSigner, "1.2.840.113635.100.1.25");
+SEC_CONST_DECL (kSecPolicyAppleQAProfileSigner, "1.2.840.113635.100.1.26");
+SEC_CONST_DECL (kSecPolicyAppleTestMobileStore, "1.2.840.113635.100.1.27");
+#if TARGET_OS_IPHONE
+SEC_CONST_DECL (kSecPolicyAppleOTAPKISigner, "1.2.840.113635.100.1.28");
+SEC_CONST_DECL (kSecPolicyAppleTestOTAPKISigner, "1.2.840.113635.100.1.29");
+SEC_CONST_DECL (kSecPolicyAppleIDValidationRecordSigningPolicy, "1.2.840.113625.100.1.30");
+#endif
+
+SEC_CONST_DECL (kSecPolicyOid, "SecPolicyOid");
+SEC_CONST_DECL (kSecPolicyName, "SecPolicyName");
+SEC_CONST_DECL (kSecPolicyClient, "SecPolicyClient");
+SEC_CONST_DECL (kSecPolicyRevocationFlags, "SecPolicyRevocationFlags");
+SEC_CONST_DECL (kSecPolicyTeamIdentifier, "SecPolicyTeamIdentifier");
+
+/* Private policy names */
 static CFStringRef kSecPolicyOIDBasicX509 = CFSTR("basicX509");
 static CFStringRef kSecPolicyOIDSSLServer = CFSTR("sslServer");
 static CFStringRef kSecPolicyOIDSSLClient = CFSTR("sslClient");
 static CFStringRef kSecPolicyOIDBasicX509 = CFSTR("basicX509");
 static CFStringRef kSecPolicyOIDSSLServer = CFSTR("sslServer");
 static CFStringRef kSecPolicyOIDSSLClient = CFSTR("sslClient");
@@ -180,6 +228,17 @@ static CFStringRef kSecPolicyOIDURLBag = CFSTR("URLBag");
 static CFStringRef kSecPolicyOIDOTATasking = CFSTR("OTATasking");
 static CFStringRef kSecPolicyOIDMobileAsset = CFSTR("MobileAsset");
 static CFStringRef kSecPolicyOIDAppleIDAuthority = CFSTR("AppleIDAuthority");
 static CFStringRef kSecPolicyOIDOTATasking = CFSTR("OTATasking");
 static CFStringRef kSecPolicyOIDMobileAsset = CFSTR("MobileAsset");
 static CFStringRef kSecPolicyOIDAppleIDAuthority = CFSTR("AppleIDAuthority");
+static CFStringRef kSecPolicyOIDAppleShoebox = CFSTR("AppleShoebox");
+static CFStringRef kSecPolicyOIDApplePassbook = CFSTR("ApplePassbook");
+static CFStringRef kSecPolicyOIDAppleMobileStore = CFSTR("AppleMobileStore");
+static CFStringRef kSecPolicyOIDAppleTestMobileStore = CFSTR("AppleTestMobileStore");
+static CFStringRef kSecPolicyOIDAppleEscrowService = CFSTR("AppleEscrowService");
+static CFStringRef kSecPolicyOIDAppleProfileSigner = CFSTR("AppleProfileSigner");
+static CFStringRef kSecPolicyOIDAppleQAProfileSigner = CFSTR("AppleQAProfileSigner");
+static CFStringRef kSecPolicyOIDAppleOTAPKIAssetSigner = CFSTR("AppleOTAPKIAssetSigner");
+static CFStringRef kSecPolicyOIDAppleTestOTAPKIAssetSigner = CFSTR("AppleTestOTAPKIAssetSigner");
+static CFStringRef kSecPolicyOIDAppleIDValidationRecordSigningPolicy = CFSTR("AppleIDValidationRecordSigningPolicy");
+
 
 /* Policies will now change to multiple categories of checks.
 
 
 /* Policies will now change to multiple categories of checks.
 
@@ -207,7 +266,7 @@ static CFStringRef kSecPolicyOIDAppleIDAuthority = CFSTR("AppleIDAuthority");
    by the client (if no exceptions were present for this certificate) we could
    short circuit fail the evaluation.
    IDEA: These checks can dynamically add new checks...[needs work]
    by the client (if no exceptions were present for this certificate) we could
    short circuit fail the evaluation.
    IDEA: These checks can dynamically add new checks...[needs work]
-   ALTERNATIVE: A policy can have one or more sub-policies.  Each sub-policy will be evaluated only after the parent policy succeeds.  Subpolicies can be either required (making the parent policy fail) or optional making the parent policy succeed, but allowing the chainbuilder to continue building chains after an optional subpolicy failure in search of a chain for which the subpolicy also succeeded.  Subpolicies can be dynamically added to the policy evaluation context tree (a tree with a node for every node in the certificate path. This tree however is from the leaf up stored in the SecCertificatePathRef objects themselves possibly - requiring a separate shared subtree of nodes for the underlying certificate state tree.) by a parent policy at any stage, since the subpolicy evaluation only starts after 
+   ALTERNATIVE: A policy can have one or more sub-policies.  Each sub-policy will be evaluated only after the parent policy succeeds.  Subpolicies can be either required (making the parent policy fail) or optional making the parent policy succeed, but allowing the chainbuilder to continue building chains after an optional subpolicy failure in search of a chain for which the subpolicy also succeeded.  Subpolicies can be dynamically added to the policy evaluation context tree (a tree with a node for every node in the certificate path. This tree however is from the leaf up stored in the SecCertificatePathRef objects themselves possibly - requiring a separate shared subtree of nodes for the underlying certificate state tree.) by a parent policy at any stage, since the subpolicy evaluation only starts after
    will have a key in the info (or even details and make info client side generated from info to indicate the success or failure of optional subpolicies) tree the value of which is an
    equivalent subtree from that level down.  So SSL has EV as a subpolicy, but
    EV dynamically enables the ocsp or crl or dcrl or any combination thereof subpolicies.
    will have a key in the info (or even details and make info client side generated from info to indicate the success or failure of optional subpolicies) tree the value of which is an
    equivalent subtree from that level down.  So SSL has EV as a subpolicy, but
    EV dynamically enables the ocsp or crl or dcrl or any combination thereof subpolicies.
@@ -218,7 +277,7 @@ static CFStringRef kSecPolicyOIDAppleIDAuthority = CFSTR("AppleIDAuthority");
    Static Subsidiary CA Checks.  The results of these checks for purposes of
    generating details could be cached in the SecCertificatePathRefs themselves, or we can short circuit fail and recalc details on demand later.
 
    Static Subsidiary CA Checks.  The results of these checks for purposes of
    generating details could be cached in the SecCertificatePathRefs themselves, or we can short circuit fail and recalc details on demand later.
 
-   Static Anchor Checks can do things like populate the chainbuilder level context value of the initial_valid_policy_tree with a particular anchors list of ev policies it represents or modify inputs to the policy itself. 
+   Static Anchor Checks can do things like populate the chainbuilder level context value of the initial_valid_policy_tree with a particular anchors list of ev policies it represents or modify inputs to the policy itself.
 
    Dynamic Subscriber Certificate Checks These can do things like check for EV policy conformance based on the valid_policy_tree at the end of the certificate evaluation, or based on things like the pathlen, etc. in the chain validation context.
 
 
    Dynamic Subscriber Certificate Checks These can do things like check for EV policy conformance based on the valid_policy_tree at the end of the certificate evaluation, or based on things like the pathlen, etc. in the chain validation context.
 
@@ -235,13 +294,13 @@ static CFStringRef kSecPolicyOIDAppleIDAuthority = CFSTR("AppleIDAuthority");
    If an optional subpolicy s_p has a required subpolicy r_s_p.  Then success of s_p will cause the entire chain evaluation to fail if r_s_p fails.
 
    All policies static revocation checks are run at the appropriate phase in the evaluation.  static leaf checks are done before chainbuilding even starts.  static intermediate checks are done in the chainbuilder for each cadidate parent certificate.  If all policies pass we check the signatures. We reject the whole chain if that step fails. Otherwise we add the path to builder->candidatePaths. If the top level policy or a required subpolicy or a required subpolicy of a successful subpolicy fails we stick the chain at the end of the expiredPaths, if one of the optional subpolicies fail, we stick the chain at the start of expiredPaths so it's considered first after all real candidatePaths have been processed.
    If an optional subpolicy s_p has a required subpolicy r_s_p.  Then success of s_p will cause the entire chain evaluation to fail if r_s_p fails.
 
    All policies static revocation checks are run at the appropriate phase in the evaluation.  static leaf checks are done before chainbuilding even starts.  static intermediate checks are done in the chainbuilder for each cadidate parent certificate.  If all policies pass we check the signatures. We reject the whole chain if that step fails. Otherwise we add the path to builder->candidatePaths. If the top level policy or a required subpolicy or a required subpolicy of a successful subpolicy fails we stick the chain at the end of the expiredPaths, if one of the optional subpolicies fail, we stick the chain at the start of expiredPaths so it's considered first after all real candidatePaths have been processed.
-   
+
    Static revocation policy checks could check the passed in ocspresponses or even the local cache, though the latter is probably best left for the dynamic phase.
 
    The same rules that apply above to the adding paths to candidatePaths v/s expiredPaths apply to dynamicpolicy checks, except that we don't remember failures anymore, we reject them.
    Static revocation policy checks could check the passed in ocspresponses or even the local cache, though the latter is probably best left for the dynamic phase.
 
    The same rules that apply above to the adding paths to candidatePaths v/s expiredPaths apply to dynamicpolicy checks, except that we don't remember failures anymore, we reject them.
-   
+
    We need to remember the best successful chain we find, where best is defined by: satisfies as many optional policies as possible.
    We need to remember the best successful chain we find, where best is defined by: satisfies as many optional policies as possible.
-   
+
    Chain building ends when either we find a chain that matches all optional and required policies, or we run out of chains to build.  Another case is if we run out of candiate paths but we already have a chain that matches at least the top level and required subpolicies.   In that case we don't even consider any expiredPaths.  Example: we find a valid SSL chain (top level policy), but no partial chain we constructed satisfied the static checks of the ev subpolicy, or the required revocation sub-subpolicy of the ev policy.
 
    In order for this to work well with exceptions on subpolicies, we'd need to move the validation of exceptions to the server, something we'd do anyway if we had full on truststore.  In this case exceptions would be live in the failure callback for a trust check.
    Chain building ends when either we find a chain that matches all optional and required policies, or we run out of chains to build.  Another case is if we run out of candiate paths but we already have a chain that matches at least the top level and required subpolicies.   In that case we don't even consider any expiredPaths.  Example: we find a valid SSL chain (top level policy), but no partial chain we constructed satisfied the static checks of the ev subpolicy, or the required revocation sub-subpolicy of the ev policy.
 
    In order for this to work well with exceptions on subpolicies, we'd need to move the validation of exceptions to the server, something we'd do anyway if we had full on truststore.  In this case exceptions would be live in the failure callback for a trust check.
@@ -327,23 +386,38 @@ static const UInt8 kAppleCASHA1[kSecPolicySHA1Size] = {
     0xD1, 0x4A, 0xE2, 0x24, 0x52, 0xD1, 0x98, 0xDF, 0x6C, 0x60
 };
 
     0xD1, 0x4A, 0xE2, 0x24, 0x52, 0xD1, 0x98, 0xDF, 0x6C, 0x60
 };
 
+static const UInt8 kAppleTESTCASHA1[kSecPolicySHA1Size] = {
+    0xbc, 0x30, 0x55, 0xc8, 0xc8, 0xd3, 0x48, 0x3f, 0xf4, 0x8d,
+    0xfe, 0x3d, 0x51, 0x75, 0x31, 0xc9, 0xf4, 0xd7, 0x4a, 0xf7
+};
+
 static const UInt8 kITMSCASHA1[kSecPolicySHA1Size] = {
 static const UInt8 kITMSCASHA1[kSecPolicySHA1Size] = {
-    0x1D, 0x33, 0x42, 0x46, 0x8B, 0x10, 0xBD, 0xE6, 0x45, 0xCE, 
+    0x1D, 0x33, 0x42, 0x46, 0x8B, 0x10, 0xBD, 0xE6, 0x45, 0xCE,
     0x44, 0x6E, 0xBB, 0xE8, 0xF5, 0x03, 0x5D, 0xF8, 0x32, 0x22
 };
 
 static const UInt8 kFactoryDeviceCASHA1[kSecPolicySHA1Size] = {
     0x44, 0x6E, 0xBB, 0xE8, 0xF5, 0x03, 0x5D, 0xF8, 0x32, 0x22
 };
 
 static const UInt8 kFactoryDeviceCASHA1[kSecPolicySHA1Size] = {
-  0xef, 0x68, 0x73, 0x17, 0xa4, 0xf8, 0xf9, 0x4b, 0x7b, 0x21, 
-  0xe2, 0x2f, 0x09, 0x8f, 0xfd, 0x6a, 0xae, 0xc0, 0x0d, 0x63
+       0xef, 0x68, 0x73, 0x17, 0xa4, 0xf8, 0xf9, 0x4b, 0x7b, 0x21,
+       0xe2, 0x2f, 0x09, 0x8f, 0xfd, 0x6a, 0xae, 0xc0, 0x0d, 0x63
+};
+
+static const UInt8 kApplePKISettingsAuthority[kSecPolicySHA1Size] = {
+       0x1D, 0x0C, 0xBA, 0xAD, 0x17, 0xFD, 0x7E, 0x9E, 0x9F, 0xF1, 
+       0xC9, 0xA2, 0x66, 0x79, 0x60, 0x00, 0x8B, 0xAE, 0x70, 0xB8  
+};
+
+static const UInt8 kAppleTestPKISettingsAuthority[kSecPolicySHA1Size] = {
+       0xDB, 0xBA, 0x25, 0x0B, 0xD8, 0x62, 0x71, 0x87, 0x54, 0x7E, 
+       0xD7, 0xEF, 0x11, 0x94, 0x7E, 0x82, 0xE6, 0xD8, 0x1C, 0x9A
 };
 
 };
 
-#pragma mark -
-#pragma mark SecPolicy
+// MARK: -
+// MARK: SecPolicy
 /********************************************************
  ****************** SecPolicy object ********************
  ********************************************************/
 
 /********************************************************
  ****************** SecPolicy object ********************
  ********************************************************/
 
-/* CFRuntime regsitration data. */
+/* CFRuntime registration data. */
 static pthread_once_t kSecPolicyRegisterClass = PTHREAD_ONCE_INIT;
 static CFTypeID kSecPolicyTypeID = _kCFRuntimeNotATypeID;
 
 static pthread_once_t kSecPolicyRegisterClass = PTHREAD_ONCE_INIT;
 static CFTypeID kSecPolicyTypeID = _kCFRuntimeNotATypeID;
 
@@ -366,12 +440,12 @@ static CFHashCode SecPolicyHash(CFTypeRef cf) {
        return CFHash(policy->_oid) + CFHash(policy->_options);
 }
 
        return CFHash(policy->_oid) + CFHash(policy->_options);
 }
 
-static CFStringRef SecPolicyDescribe(CFTypeRef cf) {
+static CF_RETURNS_RETAINED CFStringRef SecPolicyDescribe(CFTypeRef cf) {
        SecPolicyRef policy = (SecPolicyRef) cf;
     CFMutableStringRef desc = CFStringCreateMutable(kCFAllocatorDefault, 0);
     CFStringRef typeStr = CFCopyTypeIDDescription(CFGetTypeID(cf));
     CFStringAppendFormat(desc, NULL,
        SecPolicyRef policy = (SecPolicyRef) cf;
     CFMutableStringRef desc = CFStringCreateMutable(kCFAllocatorDefault, 0);
     CFStringRef typeStr = CFCopyTypeIDDescription(CFGetTypeID(cf));
     CFStringAppendFormat(desc, NULL,
-        CFSTR("<%@ %@: oid: %@ options %@"), typeStr,
+        CFSTR("<%@: oid: %@ options %@"), typeStr,
         policy->_oid, policy->_options);
     CFRelease(typeStr);
     CFStringAppend(desc, CFSTR(" >"));
         policy->_oid, policy->_options);
     CFRelease(typeStr);
     CFStringAppend(desc, CFSTR(" >"));
@@ -402,9 +476,8 @@ CFTypeID SecPolicyGetTypeID(void) {
 }
 
 /* AUDIT[securityd](done):
 }
 
 /* AUDIT[securityd](done):
-   oid (ok) is a caller providied string, only it's cf type has been checked.
-   options is a caller provided dictionary, only its cf type has
-   been checked.
+   oid (ok) is a caller provided string, only its cf type has been checked.
+   options is a caller provided dictionary, only its cf type has been checked.
  */
 SecPolicyRef SecPolicyCreate(CFStringRef oid, CFDictionaryRef options) {
        SecPolicyRef result = NULL;
  */
 SecPolicyRef SecPolicyCreate(CFStringRef oid, CFDictionaryRef options) {
        SecPolicyRef result = NULL;
@@ -425,26 +498,372 @@ errOut:
     return result;
 }
 
     return result;
 }
 
-static CFArrayRef SecPolicyCopyArray(SecPolicyRef policy) {
-    const void *values[] = { policy->_oid, policy->_options };
-    return CFArrayCreate(kCFAllocatorDefault, values, 2, &kCFTypeArrayCallBacks);
+SecPolicyRef SecPolicyCreateWithProperties(CFTypeRef policyIdentifier,
+       CFDictionaryRef properties) {
+       // Creates a policy reference for a given policy object identifier.
+       // If policy-specific parameters can be supplied (e.g. hostname),
+       // attempt to obtain from input properties dictionary.
+       // Returns NULL if the given identifier is unsupported.
+
+       SecPolicyRef policy = NULL;
+       CFStringRef name = NULL;
+       CFStringRef teamID = NULL;
+       Boolean client = false;
+       require(policyIdentifier && (CFStringGetTypeID() == CFGetTypeID(policyIdentifier)), errOut);
+
+       if (properties) {
+               name = CFDictionaryGetValue(properties, kSecPolicyName);
+               teamID = CFDictionaryGetValue(properties, kSecPolicyTeamIdentifier);
+
+               CFBooleanRef dictionaryClientValue;
+               client = (CFDictionaryGetValueIfPresent(properties, kSecPolicyClient, (const void **)&dictionaryClientValue) &&
+                               (dictionaryClientValue != NULL) && CFEqual(kCFBooleanTrue, dictionaryClientValue));
+       }
+
+       if (CFEqual(policyIdentifier, kSecPolicyAppleX509Basic)) {
+               policy = SecPolicyCreateBasicX509();
+       }
+       else if (CFEqual(policyIdentifier, kSecPolicyAppleSSL)) {
+               policy = SecPolicyCreateSSL(!client, name);
+       }
+       else if (CFEqual(policyIdentifier, kSecPolicyAppleEAP)) {
+               CFArrayRef array = CFArrayCreate(kCFAllocatorDefault, (const void **)&name, 1,
+                               &kCFTypeArrayCallBacks);
+               policy = SecPolicyCreateEAP(!client, array);
+               CFReleaseSafe(array);
+       }
+       else if (CFEqual(policyIdentifier, kSecPolicyAppleIPsec)) {
+               policy = SecPolicyCreateIPSec(!client, name);
+       }
+       else if (CFEqual(policyIdentifier, kSecPolicyAppleRevocation)) {
+               policy = SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod);
+       }
+       else if (CFEqual(policyIdentifier, kSecPolicyAppleSMIME)) {
+               policy = SecPolicyCreateSMIME(kSecSignSMIMEUsage | kSecAnyEncryptSMIME, name);
+       }
+       else if (CFEqual(policyIdentifier, kSecPolicyAppleCodeSigning)) {
+               policy = SecPolicyCreateCodeSigning();
+       }
+       else if (CFEqual(policyIdentifier, kSecPolicyAppleIDValidation)) {
+               policy = SecPolicyCreateAppleIDAuthorityPolicy();
+       }
+       else if (CFEqual(policyIdentifier, kSecPolicyApplePassbookSigning)) {
+               policy = SecPolicyCreatePassbookCardSigner(name, teamID);
+       }
+       else if (CFEqual(policyIdentifier, kSecPolicyAppleMobileStore)) {
+               policy = SecPolicyCreateMobileStoreSigner();
+       }
+       else if (CFEqual(policyIdentifier, kSecPolicyAppleTestMobileStore)) {
+               policy = SecPolicyCreateTestMobileStoreSigner();
+       }
+       else if (CFEqual(policyIdentifier, kSecPolicyAppleEscrowService)) {
+               policy = SecPolicyCreateEscrowServiceSigner();
+       }
+       else if (CFEqual(policyIdentifier, kSecPolicyAppleProfileSigner)) {
+       policy = SecPolicyCreateConfigurationProfileSigner();
+       }
+       else if (CFEqual(policyIdentifier, kSecPolicyAppleQAProfileSigner)) {
+       policy = SecPolicyCreateQAConfigurationProfileSigner();
+       }
+#if TARGET_OS_IPHONE
+       else if (CFEqual(policyIdentifier, kSecPolicyAppleOTAPKISigner)) {
+       policy = SecPolicyCreateOTAPKISigner();
+       }
+       else if (CFEqual(policyIdentifier, kSecPolicyAppleTestOTAPKISigner)) {
+       policy = SecPolicyCreateTestOTAPKISigner();
+       }
+       else if (CFEqual(policyIdentifier, kSecPolicyAppleIDValidationRecordSigningPolicy)) {
+               policy = SecPolicyCreateAppleIDValidationRecordSigningPolicy();
+       }
+#endif
+
+errOut:
+       return policy;
+}
+
+CFDictionaryRef SecPolicyCopyProperties(SecPolicyRef policyRef) {
+       // Builds and returns a dictionary which the caller must release.
+
+       if (!policyRef) return NULL;
+       CFMutableDictionaryRef properties = CFDictionaryCreateMutable(NULL, 0,
+               &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+       if (!properties) return NULL;
+       CFStringRef oid = (CFStringRef) CFRetain(policyRef->_oid);
+       CFTypeRef nameKey = NULL;
+
+       // Convert private to public OID if we have one
+       CFStringRef outOid = oid;
+       if (CFEqual(oid, kSecPolicyOIDBasicX509)) {
+               outOid = kSecPolicyAppleX509Basic;
+       }
+       else if (CFEqual(oid, kSecPolicyOIDSSLServer) ||
+                        CFEqual(oid, kSecPolicyOIDSSLClient)) {
+               outOid = kSecPolicyAppleSSL;
+               nameKey = kSecPolicyCheckSSLHostname;
+       }
+       else if (CFEqual(oid, kSecPolicyEAPServer) ||
+                        CFEqual(oid, kSecPolicyEAPClient)) {
+               outOid = kSecPolicyAppleEAP;
+               nameKey = kSecPolicyCheckEAPTrustedServerNames;
+       }
+       else if (CFEqual(oid, kSecPolicyOIDIPSecServer) ||
+                        CFEqual(oid, kSecPolicyOIDIPSecClient)) {
+               outOid = kSecPolicyAppleIPsec;
+               nameKey = kSecPolicyCheckSSLHostname;
+       }
+       else if (CFEqual(oid, kSecPolicyOIDRevocation)) {
+               outOid = kSecPolicyAppleRevocation;
+       }
+       else if (CFEqual(oid, kSecPolicyOIDSMIME)) {
+               outOid = kSecPolicyAppleSMIME;
+               nameKey = kSecPolicyCheckEmail;
+       }
+       else if (CFEqual(oid, kSecPolicyOIDCodeSigning)) {
+               outOid = kSecPolicyAppleCodeSigning;
+       }
+       else if (CFEqual(oid, kSecPolicyOIDAppleIDAuthority)) {
+               outOid = kSecPolicyAppleIDValidation;
+       }
+       else if (CFEqual(oid, kSecPolicyOIDApplePassbook)) {
+               outOid = kSecPolicyApplePassbookSigning;
+       }
+       else if (CFEqual(oid, kSecPolicyOIDAppleMobileStore)) {
+               outOid = kSecPolicyAppleMobileStore;
+       }
+       else if (CFEqual(oid, kSecPolicyOIDAppleTestMobileStore)) {
+               outOid = kSecPolicyAppleTestMobileStore; 
+       }
+       else if (CFEqual(oid, kSecPolicyOIDAppleEscrowService)) {
+               outOid = kSecPolicyAppleEscrowService;
+       }
+    else if (CFEqual(oid, kSecPolicyOIDAppleProfileSigner)) {
+       outOid = kSecPolicyAppleProfileSigner;
+       }
+       else if (CFEqual(oid, kSecPolicyOIDAppleQAProfileSigner)) {
+       outOid = kSecPolicyAppleQAProfileSigner;
+       }
+#if TARGET_OS_IPHONE
+       else if (CFEqual(oid, kSecPolicyOIDAppleOTAPKIAssetSigner)) {
+       outOid = kSecPolicyAppleOTAPKISigner;
+       }
+       else if (CFEqual(oid, kSecPolicyOIDAppleTestOTAPKIAssetSigner)) {
+       outOid = kSecPolicyAppleTestOTAPKISigner;
+       }
+       else if (CFEqual(oid, kSecPolicyOIDAppleIDValidationRecordSigningPolicy)) {
+               outOid = kSecPolicyAppleIDValidationRecordSigningPolicy;
+       }
+#endif 
+
+       // Set kSecPolicyOid
+       CFDictionarySetValue(properties, (const void *)kSecPolicyOid,
+               (const void *)outOid);
+
+       // Set kSecPolicyName if we have one
+       if (nameKey && policyRef->_options) {
+               CFTypeRef name = (CFTypeRef) CFDictionaryGetValue(policyRef->_options,
+                       nameKey);
+               if (name) {
+                       CFDictionarySetValue(properties, (const void *)kSecPolicyName,
+                               (const void *)name);
+               }
+       }
+
+       // Set kSecPolicyClient
+       if (CFEqual(oid, kSecPolicyOIDSSLClient) ||
+               CFEqual(oid, kSecPolicyOIDIPSecClient) ||
+               CFEqual(oid, kSecPolicyEAPClient)) {
+               CFDictionarySetValue(properties, (const void *)kSecPolicyClient,
+                       (const void *)kCFBooleanTrue);
+       }
+
+       CFRelease(oid);
+       return properties;
 }
 
 }
 
-static void serializePolicy(const void *value, void *context) {
-    CFTypeRef serializedPolicy = SecPolicyCopyArray((SecPolicyRef)value);
-    CFArrayAppendValue((CFMutableArrayRef)context, serializedPolicy);
-    CFRelease(serializedPolicy);
+#if TARGET_OS_MAC && !TARGET_OS_IPHONE
+static void SecPolicySetOid(SecPolicyRef policy, CFStringRef oid) {
+       if (!policy || !oid) return;
+       CFStringRef temp = policy->_oid;
+       CFRetain(oid);
+       policy->_oid = oid;
+       CFReleaseSafe(temp);
 }
 
 }
 
-CFArrayRef SecPolicyArraySerialize(CFArrayRef policies) {
-    CFMutableArrayRef result = NULL;
-    require_quiet(policies && CFGetTypeID(policies) == CFArrayGetTypeID(), errOut);
-    CFIndex count = CFArrayGetCount(policies);
-    result = CFArrayCreateMutable(kCFAllocatorDefault, count, &kCFTypeArrayCallBacks);
-    CFRange all_policies = { 0, count };
-    CFArrayApplyFunction(policies, all_policies, serializePolicy, result);
-errOut:
-    return result;
+static void SecPolicySetOptionsValue(SecPolicyRef policy, CFStringRef key, CFTypeRef value) {
+       if (!policy || !key) return;
+       CFMutableDictionaryRef options = (CFMutableDictionaryRef) policy->_options;
+       if (!options) {
+               options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+                               &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+               if (!options) return;
+               policy->_options = options;
+       }
+       CFDictionarySetValue(options, key, value);
+}
+
+OSStatus SecPolicySetProperties(SecPolicyRef policyRef, CFDictionaryRef properties) {
+       // Set policy options based on the provided dictionary keys.
+
+       if (!(policyRef && properties && (CFDictionaryGetTypeID() == CFGetTypeID(properties)))) {
+               return errSecParam;
+       }
+       CFStringRef oid = (CFStringRef) CFRetain(policyRef->_oid);
+       OSStatus result = errSecSuccess;
+
+       // kSecPolicyName
+       CFTypeRef name = NULL;
+       if (CFDictionaryGetValueIfPresent(properties, (const void *)kSecPolicyName,
+               (const void **)&name) && name) {
+               CFTypeID typeID = CFGetTypeID(name);
+               if (CFEqual(oid, kSecPolicyOIDSSLServer) ||
+                       CFEqual(oid, kSecPolicyOIDSSLClient) ||
+                       CFEqual(oid, kSecPolicyOIDIPSecServer) ||
+                       CFEqual(oid, kSecPolicyOIDIPSecClient)) {
+                       if (CFStringGetTypeID() == typeID) {
+                               SecPolicySetOptionsValue(policyRef, kSecPolicyCheckSSLHostname, name);
+                       }
+                       else result = errSecParam;
+               }
+               else if (CFEqual(oid, kSecPolicyEAPServer) ||
+                                CFEqual(oid, kSecPolicyEAPClient)) {
+                       if ((CFStringGetTypeID() == typeID) ||
+                               (CFArrayGetTypeID() == typeID)) {
+                               SecPolicySetOptionsValue(policyRef, kSecPolicyCheckEAPTrustedServerNames, name);
+                       }
+                       else result = errSecParam;
+               }
+               else if (CFEqual(oid, kSecPolicyOIDSMIME)) {
+                       if (CFStringGetTypeID() == typeID) {
+                               SecPolicySetOptionsValue(policyRef, kSecPolicyCheckEmail, name);
+                       }
+                       else result = errSecParam;
+               }
+       }
+
+       // kSecPolicyClient
+       CFTypeRef client = NULL;
+       if (CFDictionaryGetValueIfPresent(properties, (const void *)kSecPolicyClient,
+               (const void **)&client) && client) {
+               if (!(CFBooleanGetTypeID() == CFGetTypeID(client))) {
+                       result = errSecParam;
+               }
+               else if (CFEqual(client, kCFBooleanTrue)) {
+                       if (CFEqual(oid, kSecPolicyOIDSSLServer)) {
+                               SecPolicySetOid(policyRef, kSecPolicyOIDSSLClient);
+                       }
+                       else if (CFEqual(oid, kSecPolicyOIDIPSecServer)) {
+                               SecPolicySetOid(policyRef, kSecPolicyOIDIPSecClient);
+                       }
+                       else if (CFEqual(oid, kSecPolicyEAPServer)) {
+                               SecPolicySetOid(policyRef, kSecPolicyEAPClient);
+                       }
+               }
+               else {
+                       if (CFEqual(oid, kSecPolicyOIDSSLClient)) {
+                               SecPolicySetOid(policyRef, kSecPolicyOIDSSLServer);
+                       }
+                       else if (CFEqual(oid, kSecPolicyOIDIPSecClient)) {
+                               SecPolicySetOid(policyRef, kSecPolicyOIDIPSecServer);
+                       }
+                       else if (CFEqual(oid, kSecPolicyEAPClient)) {
+                               SecPolicySetOid(policyRef, kSecPolicyEAPServer);
+                       }
+               }
+       }
+
+       CFRelease(oid);
+       return result;
+}
+#endif
+
+static xpc_object_t SecPolicyCopyXPCObject(SecPolicyRef policy, CFErrorRef *error) {
+    xpc_object_t xpc_policy = NULL;
+    xpc_object_t data[2] = {};
+    require_action_quiet(data[0] = _CFXPCCreateXPCObjectFromCFObject(policy->_oid), exit,
+                         SecError(errSecParam, error, CFSTR("failed to create xpc_object from policy oid")));
+    require_action_quiet(data[1] = _CFXPCCreateXPCObjectFromCFObject(policy->_options), exit,
+                         SecError(errSecParam, error, CFSTR("failed to create xpc_object from policy options")));
+    require_action_quiet(xpc_policy = xpc_array_create(data, array_size(data)), exit,
+                         SecError(errSecAllocate, error, CFSTR("failed to create xpc_array for policy")));
+
+exit:
+    if (data[0]) xpc_release(data[0]);
+    if (data[1]) xpc_release(data[1]);
+    return xpc_policy;
+}
+
+static bool SecPolicyAppendToXPCArray(SecPolicyRef policy, xpc_object_t policies, CFErrorRef *error) {
+    if (!policy)
+        return true; // NOOP
+
+    xpc_object_t xpc_policy = SecPolicyCopyXPCObject(policy, error);
+    if (!xpc_policy)
+        return false;
+
+    xpc_array_append_value(policies, xpc_policy);
+    xpc_release(xpc_policy);
+    return true;
+}
+
+xpc_object_t SecPolicyArrayCopyXPCArray(CFArrayRef policies, CFErrorRef *error) {
+    xpc_object_t xpc_policies;
+    require_action_quiet(xpc_policies = xpc_array_create(NULL, 0), exit,
+                         SecError(errSecAllocate, error, CFSTR("failed to create xpc_array")));
+    CFIndex ix, count = CFArrayGetCount(policies);
+    for (ix = 0; ix < count; ++ix) {
+        if (!SecPolicyAppendToXPCArray((SecPolicyRef)CFArrayGetValueAtIndex(policies, ix), xpc_policies, error)) {
+            xpc_release(xpc_policies);
+            return NULL;
+        }
+    }
+exit:
+    return xpc_policies;
+}
+
+static SecPolicyRef SecPolicyCreateWithXPCObject(xpc_object_t xpc_policy, CFErrorRef *error) {
+    SecPolicyRef policy = NULL;
+    CFTypeRef oid = NULL;
+    CFTypeRef options = NULL;
+
+    require_action_quiet(xpc_policy, exit, SecError(errSecParam, error, CFSTR("policy xpc value is NULL")));
+    require_action_quiet(xpc_get_type(xpc_policy) == XPC_TYPE_ARRAY, exit, SecError(errSecDecode, error, CFSTR("policy xpc value is not an array")));
+    require_action_quiet(xpc_array_get_count(xpc_policy) == 2, exit, SecError(errSecDecode, error, CFSTR("policy xpc array count != 2")));
+    oid = _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy, 0));
+    require_action_quiet(isString(oid), exit,
+                         SecError(errSecParam, error, CFSTR("failed to convert xpc policy[0]=%@ to CFString"), oid));
+    options = _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy, 1));
+    require_action_quiet(isDictionary(options), exit,
+                         SecError(errSecParam, error, CFSTR("failed to convert xpc policy[1]=%@ to CFDictionary"), options));
+    require_action_quiet(policy = SecPolicyCreate(oid, options), exit, SecError(errSecDecode, error, CFSTR("Failed to create policy")));
+
+exit:
+    CFReleaseSafe(oid);
+    CFReleaseSafe(options);
+    return policy;
+}
+
+CFArrayRef SecPolicyXPCArrayCopyArray(xpc_object_t xpc_policies, CFErrorRef *error) {
+    CFMutableArrayRef policies = NULL;
+    require_action_quiet(xpc_get_type(xpc_policies) == XPC_TYPE_ARRAY, exit,
+                         SecError(errSecParam, error, CFSTR("policies xpc value is not an array")));
+    size_t count = xpc_array_get_count(xpc_policies);
+    require_action_quiet(policies = CFArrayCreateMutable(kCFAllocatorDefault, count, &kCFTypeArrayCallBacks), exit,
+                         SecError(errSecAllocate, error, CFSTR("failed to create CFArray of capacity %zu"), count));
+
+    size_t ix;
+    for (ix = 0; ix < count; ++ix) {
+        SecPolicyRef policy = SecPolicyCreateWithXPCObject(xpc_array_get_value(xpc_policies, ix), error);
+        if (!policy) {
+            CFRelease(policies);
+            return NULL;
+        }
+        CFArraySetValueAtIndex(policies, ix, policy);
+        CFRelease(policy);
+    }
+
+exit:
+    return policies;
+
 }
 
 static void add_element(CFMutableDictionaryRef options, CFStringRef key,
 }
 
 static void add_element(CFMutableDictionaryRef options, CFStringRef key,
@@ -497,6 +916,58 @@ static void add_oid(CFMutableDictionaryRef options, CFStringRef policy_key, cons
     }
 }
 
     }
 }
 
+static void add_leaf_marker_value(CFMutableDictionaryRef options, const DERItem *markerOid, CFStringRef string_value) {
+
+    CFTypeRef policyData = NULL;
+
+    if (NULL == string_value) {
+        policyData = CFDataCreate(kCFAllocatorDefault,
+                                markerOid ? markerOid->data : NULL,
+                                markerOid ? markerOid->length : 0);
+    } else {
+        CFStringRef oid_as_string = SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault, markerOid);
+
+        const void *key[1]   = { oid_as_string };
+        const void *value[1] = { string_value };
+        policyData = CFDictionaryCreate(kCFAllocatorDefault,
+                                        key, value, 1,
+                                        &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+        CFReleaseNull(oid_as_string);
+    }
+
+    add_element(options, kSecPolicyCheckLeafMarkerOid, policyData);
+
+    CFReleaseNull(policyData);
+
+}
+
+static void add_leaf_marker(CFMutableDictionaryRef options, const DERItem *markerOid) {
+    add_leaf_marker_value(options, markerOid, NULL);
+}
+
+
+static void add_certificate_policy_oid(CFMutableDictionaryRef options, const DERItem *certificatePolicyOid, CFStringRef string_value) {
+        CFTypeRef certificatePolicyData = NULL;
+
+       if (NULL == string_value) {
+        certificatePolicyData = CFDataCreate(kCFAllocatorDefault,
+                                certificatePolicyOid ? certificatePolicyOid->data : NULL,
+                                certificatePolicyOid ? certificatePolicyOid->length : 0);
+    } else {
+        CFStringRef oid_as_string = SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault, certificatePolicyOid);
+
+        const void *key[1]   = { oid_as_string };
+        const void *value[1] = { string_value };
+        certificatePolicyData = CFDictionaryCreate(kCFAllocatorDefault,
+                                        key, value, 1,
+                                        &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+        CFReleaseNull(oid_as_string);
+    }
+
+       add_element(options, kSecPolicyCheckCertificatePolicy, certificatePolicyData);
+
+       CFReleaseNull(certificatePolicyData);
+}
 //
 // Routines for adding dictionary entries for policies.
 //
 //
 // Routines for adding dictionary entries for policies.
 //
@@ -518,6 +989,10 @@ static void SecPolicyAddBasicX509Options(CFMutableDictionaryRef options)
     CFDictionaryAddValue(options, kSecPolicyCheckValidIntermediates, kCFBooleanTrue);
     CFDictionaryAddValue(options, kSecPolicyCheckValidLeaf, kCFBooleanTrue);
     CFDictionaryAddValue(options, kSecPolicyCheckValidRoot, kCFBooleanTrue);
     CFDictionaryAddValue(options, kSecPolicyCheckValidIntermediates, kCFBooleanTrue);
     CFDictionaryAddValue(options, kSecPolicyCheckValidLeaf, kCFBooleanTrue);
     CFDictionaryAddValue(options, kSecPolicyCheckValidRoot, kCFBooleanTrue);
+
+       // Make sure that black and gray leaf checks are performed for basic X509 chain building
+    CFDictionaryAddValue(options, kSecPolicyCheckBlackListedLeaf,  kCFBooleanTrue);
+    CFDictionaryAddValue(options, kSecPolicyCheckGrayListedLeaf,   kCFBooleanTrue);
 }
 
 static bool SecPolicyAddChainLengthOptions(CFMutableDictionaryRef options, CFIndex length)
 }
 
 static bool SecPolicyAddChainLengthOptions(CFMutableDictionaryRef options, CFIndex length)
@@ -543,7 +1018,7 @@ static bool SecPolicyAddAnchorSHA1Options(CFMutableDictionaryRef options,
     CFDataRef anchorData = NULL;
 
     require(anchorData = CFDataCreate(kCFAllocatorDefault, anchorSha1, kSecPolicySHA1Size), errOut);
     CFDataRef anchorData = NULL;
 
     require(anchorData = CFDataCreate(kCFAllocatorDefault, anchorSha1, kSecPolicySHA1Size), errOut);
-    CFDictionaryAddValue(options, kSecPolicyCheckAnchorSHA1, anchorData);
+    add_element(options, kSecPolicyCheckAnchorSHA1, anchorData);
 
     success = true;
 
 
     success = true;
 
@@ -557,6 +1032,12 @@ static bool SecPolicyAddAppleAnchorOptions(CFMutableDictionaryRef options)
     return SecPolicyAddAnchorSHA1Options(options, kAppleCASHA1);
 }
 
     return SecPolicyAddAnchorSHA1Options(options, kAppleCASHA1);
 }
 
+#if 0
+static bool SecPolicyAddAppleTESTAnchorOptions(CFMutableDictionaryRef options)
+{
+    return SecPolicyAddAnchorSHA1Options(options, kAppleTESTCASHA1);
+}
+#endif
 
 //
 // Policy Creation Functions
 
 //
 // Policy Creation Functions
@@ -569,6 +1050,8 @@ SecPolicyRef SecPolicyCreateBasicX509(void) {
                &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
 
     SecPolicyAddBasicX509Options(options);
                &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
 
     SecPolicyAddBasicX509Options(options);
+       CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess,
+                         kCFBooleanTrue);
 
        require(result = SecPolicyCreate(kSecPolicyOIDBasicX509, options), errOut);
 
 
        require(result = SecPolicyCreate(kSecPolicyOIDBasicX509, options), errOut);
 
@@ -594,8 +1077,9 @@ SecPolicyRef SecPolicyCreateSSL(Boolean server, CFStringRef hostname) {
        if (hostname) {
                CFDictionaryAddValue(options, kSecPolicyCheckSSLHostname, hostname);
        }
        if (hostname) {
                CFDictionaryAddValue(options, kSecPolicyCheckSSLHostname, hostname);
        }
-    CFDictionaryAddValue(options, kSecPolicyCheckBlackListedLeaf,
-        kCFBooleanTrue);
+
+    CFDictionaryAddValue(options, kSecPolicyCheckBlackListedLeaf,  kCFBooleanTrue);
+    CFDictionaryAddValue(options, kSecPolicyCheckGrayListedLeaf,   kCFBooleanTrue);
 
     /* If server and EKU ext present then EKU ext should contain one of
        CSSMOID_ServerAuth or CSSMOID_ExtendedKeyUsageAny or
 
     /* If server and EKU ext present then EKU ext should contain one of
        CSSMOID_ServerAuth or CSSMOID_ExtendedKeyUsageAny or
@@ -640,7 +1124,7 @@ SecPolicyRef SecPolicyCreateiPhoneActivation(void) {
 #endif
 
     /* Basic X.509 policy with the additional requirements that the chain
 #endif
 
     /* Basic X.509 policy with the additional requirements that the chain
-       length is 3, it's anchored at the AppleCA and the leaf certificate 
+       length is 3, it's anchored at the AppleCA and the leaf certificate
        has issuer "Apple iPhone Certification Authority" and
        subject "Apple iPhone Activation" for the common name. */
     CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
        has issuer "Apple iPhone Certification Authority" and
        subject "Apple iPhone Activation" for the common name. */
     CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
@@ -676,7 +1160,7 @@ SecPolicyRef SecPolicyCreateiPhoneDeviceCertificate(void) {
 #endif
 
     /* Basic X.509 policy with the additional requirements that the chain
 #endif
 
     /* Basic X.509 policy with the additional requirements that the chain
-       length is 4, it's anchored at the AppleCA and the first intermediate 
+       length is 4, it's anchored at the AppleCA and the first intermediate
        has the subject "Apple iPhone Device CA". */
     CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
         CFSTR("Apple iPhone Device CA"));
        has the subject "Apple iPhone Device CA". */
     CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
         CFSTR("Apple iPhone Device CA"));
@@ -862,14 +1346,14 @@ SecPolicyRef SecPolicyCreateiPhoneApplicationSigning(void) {
     SecPolicyAddBasicCertOptions(options);
 
     /* Basic X.509 policy with the additional requirements that the chain
     SecPolicyAddBasicCertOptions(options);
 
     /* Basic X.509 policy with the additional requirements that the chain
-       length is 3, it's anchored at the AppleCA and the leaf certificate 
+       length is 3, it's anchored at the AppleCA and the leaf certificate
        has issuer "Apple iPhone Certification Authority" and
        subject "Apple iPhone OS Application Signing" for the common name. */
     CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
         CFSTR("Apple iPhone Certification Authority"));
     CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonNameTEST,
         CFSTR("Apple iPhone OS Application Signing"));
        has issuer "Apple iPhone Certification Authority" and
        subject "Apple iPhone OS Application Signing" for the common name. */
     CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
         CFSTR("Apple iPhone Certification Authority"));
     CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonNameTEST,
         CFSTR("Apple iPhone OS Application Signing"));
-    
+
     require(SecPolicyAddChainLengthOptions(options, 3), errOut);
     require(SecPolicyAddAppleAnchorOptions(options), errOut);
 
     require(SecPolicyAddChainLengthOptions(options, 3), errOut);
     require(SecPolicyAddAppleAnchorOptions(options), errOut);
 
@@ -914,20 +1398,20 @@ SecPolicyRef SecPolicyCreateiPhoneProvisioningProfileSigning(void) {
     SecPolicyAddBasicCertOptions(options);
 
     /* Basic X.509 policy with the additional requirements that the chain
     SecPolicyAddBasicCertOptions(options);
 
     /* Basic X.509 policy with the additional requirements that the chain
-       length is 3, it's anchored at the AppleCA and the leaf certificate 
+       length is 3, it's anchored at the AppleCA and the leaf certificate
        has issuer "Apple iPhone Certification Authority" and
        subject "Apple iPhone OS Provisioning Profile Signing" for the common name. */
     CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
         CFSTR("Apple iPhone Certification Authority"));
     CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonNameTEST,
         CFSTR("Apple iPhone OS Provisioning Profile Signing"));
        has issuer "Apple iPhone Certification Authority" and
        subject "Apple iPhone OS Provisioning Profile Signing" for the common name. */
     CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
         CFSTR("Apple iPhone Certification Authority"));
     CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonNameTEST,
         CFSTR("Apple iPhone OS Provisioning Profile Signing"));
-        
+
     require(SecPolicyAddChainLengthOptions(options, 3), errOut);
     require(SecPolicyAddAppleAnchorOptions(options), errOut);
 
        require(result = SecPolicyCreate(kSecPolicyOIDiPhoneProvisioningProfileSigning, options),
         errOut);
     require(SecPolicyAddChainLengthOptions(options, 3), errOut);
     require(SecPolicyAddAppleAnchorOptions(options), errOut);
 
        require(result = SecPolicyCreate(kSecPolicyOIDiPhoneProvisioningProfileSigning, options),
         errOut);
-        
+
     /* 1.2.840.113635.100.6.2.2.1, non-critical: DER:05:00 - provisioning profile */
 
 errOut:
     /* 1.2.840.113635.100.6.2.2.1, non-critical: DER:05:00 - provisioning profile */
 
 errOut:
@@ -954,17 +1438,29 @@ errOut:
        return result;
 }
 
        return result;
 }
 
-SecPolicyRef SecPolicyCreateRevocation(void) {
+SecPolicyRef SecPolicyCreateRevocation(CFOptionFlags revocationFlags) {
        CFMutableDictionaryRef options = NULL;
        SecPolicyRef result = NULL;
 
        require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
        CFMutableDictionaryRef options = NULL;
        SecPolicyRef result = NULL;
 
        require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
+
     /* false = ocsp, true = crl, string/url value = crl distribution point,
        array = list of multiple values for example false, true, url1, url2
        check ocsp, crl, and url1 and url2 for certs which have no extensions.
      */
     /* false = ocsp, true = crl, string/url value = crl distribution point,
        array = list of multiple values for example false, true, url1, url2
        check ocsp, crl, and url1 and url2 for certs which have no extensions.
      */
-       CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kCFBooleanFalse);
+       if (revocationFlags & kSecRevocationOCSPMethod) {
+               CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kCFBooleanFalse);
+       }
+       else if (revocationFlags & kSecRevocationCRLMethod) {
+               CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kCFBooleanTrue);
+       }
+       //
+       //FIXME: check additional revocation flags
+       //
+
+       /* Only flag bits 0-4 are currently defined */
+       require(((revocationFlags >> 5) == 0), errOut);
 
        require(result = SecPolicyCreate(kSecPolicyOIDRevocation, options), errOut);
 
 
        require(result = SecPolicyCreate(kSecPolicyOIDRevocation, options), errOut);
 
@@ -1008,9 +1504,17 @@ SecPolicyRef SecPolicyCreateSMIME(CFIndex smimeUsage, CFStringRef email) {
                CFDictionaryAddValue(options, kSecPolicyCheckEmail, email);
        }
 
                CFDictionaryAddValue(options, kSecPolicyCheckEmail, email);
        }
 
-    /* To be a valid SMIME certifcate we have to have an eku extension.
-     * We only accept emailProtection (and not any) to make this policy
-     * effective for selection in Mail. */
+    /* RFC 3850 paragraph 4.4.4
+
+       If the extended key usage extension is present in the certificate
+       then interpersonal message S/MIME receiving agents MUST check that it
+       contains either the emailProtection or the anyExtendedKeyUsage OID as
+       defined in [KEYM].  S/MIME uses other than interpersonal messaging
+       MAY require the explicit presence of the extended key usage extension
+       or other OIDs to be present in the extension or both.
+     */
+    add_eku(options, NULL); /* eku extension is optional */
+    add_eku(options, &oidAnyExtendedKeyUsage);
     add_eku(options, &oidExtendedKeyUsageEmailProtection);
 
        require(result = SecPolicyCreate(kSecPolicyOIDSMIME, options), errOut);
     add_eku(options, &oidExtendedKeyUsageEmailProtection);
 
        require(result = SecPolicyCreate(kSecPolicyOIDSMIME, options), errOut);
@@ -1029,7 +1533,7 @@ SecPolicyRef SecPolicyCreateCodeSigning(void) {
 
     SecPolicyAddBasicX509Options(options);
 
 
     SecPolicyAddBasicX509Options(options);
 
-    /* If the keuusage extension is present we accept it having either of
+    /* If the keusage extension is present we accept it having either of
        these values. */
     add_ku(options, kSecKeyUsageDigitalSignature);
     add_ku(options, kSecKeyUsageNonRepudiation);
        these values. */
     add_ku(options, kSecKeyUsageDigitalSignature);
     add_ku(options, kSecKeyUsageNonRepudiation);
@@ -1170,7 +1674,7 @@ SecPolicyRef SecPolicyCreateAppleIDAuthorityPolicy(void)
 
     // with the addition of the existence check of an extension with "Apple ID Sharing Certificate" oid (1.2.840.113635.100.4.7)
     // NOTE: this obviously intended to have gone into Extended Key Usage, but evidence of existing certs proves the contrary.
 
     // with the addition of the existence check of an extension with "Apple ID Sharing Certificate" oid (1.2.840.113635.100.4.7)
     // NOTE: this obviously intended to have gone into Extended Key Usage, but evidence of existing certs proves the contrary.
-    add_oid(options, kSecPolicyCheckLeafMarkerOid, &oidAppleExtendedKeyUsageAppleID);
+    add_leaf_marker(options, &oidAppleExtendedKeyUsageAppleID);
 
     // and validate that intermediate has extension with CSSMOID_APPLE_EXTENSION_AAI_INTERMEDIATE  oid (1.2.840.113635.100.6.2.3) and goes back to the Apple Root CA.
     add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleID);
 
     // and validate that intermediate has extension with CSSMOID_APPLE_EXTENSION_AAI_INTERMEDIATE  oid (1.2.840.113635.100.6.2.3) and goes back to the Apple Root CA.
     add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleID);
@@ -1182,3 +1686,279 @@ out:
     CFReleaseSafe(options);
     return result;
 }
     CFReleaseSafe(options);
     return result;
 }
+
+static SecPolicyRef _SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer, CFStringRef teamIdentifier, bool requireTeamID)
+{
+       SecPolicyRef result = NULL;
+       CFMutableDictionaryRef options = NULL;
+       require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+                               &kCFTypeDictionaryKeyCallBacks,
+                               &kCFTypeDictionaryValueCallBacks), out);
+
+       SecPolicyAddBasicX509Options(options);
+       SecPolicyAddAppleAnchorOptions(options);
+
+       if (teamIdentifier) {
+               // If supplied, teamIdentifier must match subject OU field
+               CFDictionaryAddValue(options, kSecPolicyCheckSubjectOrganizationalUnit, teamIdentifier);
+       }
+       else {
+               // If not supplied, and it was required, fail
+               require(!requireTeamID, out);
+       }
+
+    // Must be both push and 3rd party package signing
+    add_leaf_marker_value(options, &oidAppleInstallerPackagingSigningExternal, cardIssuer);
+
+       // We should check that it also has push marker, but we don't support requiring both, only either.
+       // add_independent_oid(options, kSecPolicyCheckLeafMarkerOid, &oidApplePushServiceClient);
+
+       // And Shoebox signing eku
+       add_eku(options, &oidAppleExtendedKeyUsageShoebox);
+
+       require(result = SecPolicyCreate(kSecPolicyOIDApplePassbook, options), out);
+
+out:
+       CFReleaseSafe(options);
+       return result;
+}
+
+SecPolicyRef SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer, CFStringRef teamIdentifier)
+{
+    return _SecPolicyCreatePassbookCardSigner(cardIssuer, teamIdentifier, true);
+}
+
+
+SecPolicyRef SecPolicyCreateShoeboxCardSigner(CFStringRef cardIssuer)
+{
+       return _SecPolicyCreatePassbookCardSigner(cardIssuer, nil, false);
+}
+    
+static SecPolicyRef CreateMobileStoreSigner(Boolean forTest)
+{
+    
+    SecPolicyRef result = NULL;
+    CFMutableDictionaryRef options = NULL;
+    require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+                                                &kCFTypeDictionaryKeyCallBacks,
+                                                &kCFTypeDictionaryValueCallBacks), errOut);
+    SecPolicyAddBasicX509Options(options);
+    SecPolicyAddAppleAnchorOptions(options);
+    
+    require(SecPolicyAddChainLengthOptions(options, 3), errOut);
+    
+    CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
+                         CFSTR("Apple System Integration 2 Certification Authority"));
+    
+    add_ku(options, kSecKeyUsageDigitalSignature);
+    
+    const DERItem* pOID = (forTest) ? &oidApplePolicyTestMobileStore : &oidApplePolicyMobileStore;
+    
+    add_certificate_policy_oid(options, pOID, NULL);
+    
+    require(result = SecPolicyCreate(kSecPolicyOIDAppleMobileStore, options), errOut);
+    
+errOut:
+    CFReleaseSafe(options);
+    return result;
+}
+
+SecPolicyRef SecPolicyCreateMobileStoreSigner(void)
+{
+
+       return CreateMobileStoreSigner(false);
+}
+
+SecPolicyRef SecPolicyCreateTestMobileStoreSigner(void)
+{
+
+       return CreateMobileStoreSigner(true);
+}
+
+
+CF_RETURNS_RETAINED SecPolicyRef SecPolicyCreateEscrowServiceSigner(void)
+{
+       SecPolicyRef result = NULL;
+    CFMutableDictionaryRef options = NULL;
+       require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+                                                &kCFTypeDictionaryKeyCallBacks,
+                                                &kCFTypeDictionaryValueCallBacks), errOut);
+
+       SecPolicyAddBasicX509Options(options);
+
+       
+       add_ku(options, kSecKeyUsageKeyEncipherment);
+
+       //add_leaf_marker(options, &oidApplePolicyEscrowService);
+       require(SecPolicyAddChainLengthOptions(options, 2), errOut);    
+
+       
+       Boolean anchorAdded = false;
+       // Get the roots by calling the SecCertificateCopyEscrowRoots
+       CFArrayRef anArray = SecCertificateCopyEscrowRoots(kSecCertificateProductionEscrowRoot);
+    CFIndex numRoots = 0;
+       if (NULL == anArray || 0 == (numRoots = CFArrayGetCount(anArray)))
+       {
+               goto errOut;
+       }
+       
+       for (CFIndex iCnt = 0; iCnt < numRoots; iCnt++)
+       {               
+               SecCertificateRef aCert = (SecCertificateRef)CFArrayGetValueAtIndex(anArray, iCnt);
+               
+               if (NULL != aCert)
+               {
+                       CFDataRef sha_data = SecCertificateGetSHA1Digest(aCert);
+                       if (NULL != sha_data)
+                       {
+                               const UInt8* pSHAData = CFDataGetBytePtr(sha_data);
+                               if (NULL != pSHAData)
+                               {
+                                       SecPolicyAddAnchorSHA1Options(options, pSHAData);
+                                       anchorAdded = true;
+                               }
+                       }
+               }
+       }
+       CFRelease(anArray);
+       
+       if (!anchorAdded)
+       {
+               goto errOut;
+       }
+    
+
+    require(result = SecPolicyCreate(kSecPolicyOIDAppleEscrowService, options), errOut);
+
+errOut:
+       CFReleaseSafe(options);
+       return result;
+}
+
+SecCertificateRef SecPolicyCopyEscrowRootCertificate(void)
+{
+       SecCertificateRef result = NULL;
+
+       return result;
+}
+
+SecPolicyRef SecPolicyCreateConfigurationProfileSigner(void)
+{
+  SecPolicyRef result = NULL;
+  CFMutableDictionaryRef options = NULL;
+  require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+                                                &kCFTypeDictionaryKeyCallBacks,
+                                                &kCFTypeDictionaryValueCallBacks), errOut);
+
+  SecPolicyAddBasicX509Options(options);
+  SecPolicyAddAppleAnchorOptions(options);
+
+  // Require the profile signing EKU
+  add_eku(options, &oidAppleExtendedKeyUsageProfileSigning);
+
+  require(result = SecPolicyCreate(kSecPolicyOIDAppleProfileSigner, options), errOut);
+  
+errOut:
+  CFReleaseSafe(options);
+  return result;
+}
+
+
+SecPolicyRef SecPolicyCreateQAConfigurationProfileSigner(void)
+{
+  SecPolicyRef result = NULL;
+  CFMutableDictionaryRef options = NULL;
+  require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+                                                &kCFTypeDictionaryKeyCallBacks,
+                                                &kCFTypeDictionaryValueCallBacks), errOut);
+
+  SecPolicyAddBasicX509Options(options);
+  SecPolicyAddAppleAnchorOptions(options);
+
+  // Require the QA profile signing EKU
+  add_eku(options, &oidAppleExtendedKeyUsageQAProfileSigning);
+
+  require(result = SecPolicyCreate(kSecPolicyOIDAppleQAProfileSigner, options), errOut);
+  
+errOut:
+  CFReleaseSafe(options);
+  return result;
+}
+
+#if TARGET_OS_IPHONE
+SecPolicyRef SecPolicyCreateOTAPKISigner(void)
+{
+       SecPolicyRef result = NULL;
+       CFMutableDictionaryRef options = NULL;
+       require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+                                                     &kCFTypeDictionaryKeyCallBacks,
+                                                     &kCFTypeDictionaryValueCallBacks), errOut);
+       SecPolicyAddBasicX509Options(options);
+       
+       SecPolicyAddAnchorSHA1Options(options, kApplePKISettingsAuthority);
+    require(SecPolicyAddChainLengthOptions(options, 2), errOut);
+       
+       require(result = SecPolicyCreate(kSecPolicyOIDAppleOTAPKIAssetSigner, options), errOut);
+       
+errOut:
+  CFReleaseSafe(options);
+  return result;
+
+}
+
+
+SecPolicyRef SecPolicyCreateTestOTAPKISigner(void)
+{
+       SecPolicyRef result = NULL;
+       CFMutableDictionaryRef options = NULL;
+       require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+                                                     &kCFTypeDictionaryKeyCallBacks,
+                                                     &kCFTypeDictionaryValueCallBacks), errOut);
+       SecPolicyAddBasicX509Options(options);
+       
+       SecPolicyAddAnchorSHA1Options(options, kAppleTestPKISettingsAuthority);
+    require(SecPolicyAddChainLengthOptions(options, 2), errOut);
+       
+       require(result = SecPolicyCreate(kSecPolicyOIDAppleTestOTAPKIAssetSigner, options), errOut);
+       
+errOut:
+  CFReleaseSafe(options);
+  return result;
+}
+
+
+SecPolicyRef SecPolicyCreateAppleIDValidationRecordSigningPolicy(void)
+{
+       SecPolicyRef result = NULL;
+    CFMutableDictionaryRef options = NULL;
+       require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+                                                &kCFTypeDictionaryKeyCallBacks,
+                                                &kCFTypeDictionaryValueCallBacks), errOut);
+
+    //Leaf appears to be a SSL only cert, so policy should expand on that policy
+    SecPolicyAddBasicX509Options(options);
+
+    // Apple CA anchored
+    require(SecPolicyAddAppleAnchorOptions(options), errOut);
+
+    // Check for an extension with " Apple ID Validation Record Signing" oid (1.2.840.113635.100.6.25)
+    add_leaf_marker(options, &oidAppleCertExtensionAppleIDRecordValidationSigning);
+
+    // and validate that intermediate has extension 
+       // Application Integration Intermediate Certificate (1.2.840.113635.100.6.2.3) 
+       // and also validate that intermediate has extension 
+       // System Integration 2 Intermediate Certificate (1.2.840.113635.100.6.2.10)
+    add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleID);
+    add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleSystemIntg2);
+
+       // Ensure that revocation is checked (OCSP)
+       CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kCFBooleanFalse);
+
+       require(result = SecPolicyCreate(kSecPolicyOIDAppleIDValidationRecordSigningPolicy, options), errOut);
+       
+errOut:
+  CFReleaseSafe(options);
+  return result;
+}
+
+#endif // TARGET_OS_IPHONE
index 22b601bff6bf00180694a2d36f1ceebccf4469be..ccb1717fb66682f49fbfa6b84d228944ff500d37 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2007-2010 Apple Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2002-2010,2012-2013 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
 /*!
  * @APPLE_LICENSE_HEADER_END@
  */
 
 /*!
-    @header SecPolicy
-    The functions provided in SecPolicy.h provide an interface to various
+       @header SecPolicy
+       The functions provided in SecPolicy.h provide an interface to various
        X.509 certificate trust policies.
 */
 
 #ifndef _SECURITY_SECPOLICY_H_
 #define _SECURITY_SECPOLICY_H_
 
        X.509 certificate trust policies.
 */
 
 #ifndef _SECURITY_SECPOLICY_H_
 #define _SECURITY_SECPOLICY_H_
 
-#include <Security/SecBase.h>
 #include <CoreFoundation/CFBase.h>
 #include <CoreFoundation/CFBase.h>
+#include <CoreFoundation/CFDictionary.h>
+#include <Security/SecBase.h>
 
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 /*!
 
 /*!
-       @typedef SecPolicyRef
-       @abstract CFType representing a X.509 certificate trust policy.
+       @enum Policy Constants
+       @discussion Predefined constants used to specify a policy.
+       @constant kSecPolicyAppleX509Basic
+       @constant kSecPolicyAppleSSL
+       @constant kSecPolicyAppleSMIME
+       @constant kSecPolicyAppleEAP
+       @constant kSecPolicyAppleIPsec
+       @constant kSecPolicyApplePKINITClient
+       @constant kSecPolicyApplePKINITServer
+       @constant kSecPolicyAppleCodeSigning
+       @constant kSecPolicyMacAppStoreReceipt
+       @constant kSecPolicyAppleIDValidation
+       @constant kSecPolicyAppleTimeStamping
+       @constant kSecPolicyAppleRevocation
 */
 */
-typedef struct __SecPolicy *SecPolicyRef;
+extern CFTypeRef kSecPolicyAppleX509Basic
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0);
+extern CFTypeRef kSecPolicyAppleSSL
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0);
+extern CFTypeRef kSecPolicyAppleSMIME
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0);
+extern CFTypeRef kSecPolicyAppleEAP
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0);
+extern CFTypeRef kSecPolicyAppleIPsec
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0);
+extern CFTypeRef kSecPolicyApplePKINITClient
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+extern CFTypeRef kSecPolicyApplePKINITServer
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+extern CFTypeRef kSecPolicyAppleCodeSigning
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0);
+extern CFTypeRef kSecPolicyMacAppStoreReceipt
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+extern CFTypeRef kSecPolicyAppleIDValidation
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0);
+extern CFTypeRef kSecPolicyAppleTimeStamping
+    __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_7_0);
+extern CFTypeRef kSecPolicyAppleRevocation
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+
+/*!
+    @enum Policy Value Constants
+    @abstract Predefined property key constants used to get or set values in
+        a dictionary for a policy instance.
+    @discussion
+        All policies will have the following read-only value:
+            kSecPolicyOid       (the policy object identifier)
+
+        Additional policy values which your code can optionally set:
+            kSecPolicyName      (name which must be matched)
+            kSecPolicyClient    (evaluate for client, rather than server)
+            kSecPolicyRevocationFlags (only valid for a revocation policy)
+
+    @constant kSecPolicyOid Specifies the policy OID (value is a CFStringRef)
+    @constant kSecPolicyName Specifies a CFStringRef (or CFArrayRef of same)
+        containing a name which must be matched in the certificate to satisfy
+        this policy. For SSL/TLS, EAP, and IPSec policies, this specifies the
+        server name which must match the common name of the certificate.
+        For S/MIME, this specifies the RFC822 email address.
+    @constant kSecPolicyClient Specifies a CFBooleanRef value that indicates
+        this evaluation should be for a client certificate. If not set (or
+        false), the policy evaluates the certificate as a server certificate.
+    @constant kSecPolicyRevocationFlags Specifies a CFNumberRef that holds a
+        kCFNumberCFIndexType bitmask value. See "Revocation Policy Constants"
+        for a description of individual bits in this value.
+ */
+extern CFTypeRef kSecPolicyOid
+       __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0);
+extern CFTypeRef kSecPolicyName
+       __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0);
+extern CFTypeRef kSecPolicyClient
+       __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0);
+extern CFTypeRef kSecPolicyRevocationFlags
+       __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+
 
 /*!
     @function SecPolicyGetTypeID
 
 /*!
     @function SecPolicyGetTypeID
@@ -49,32 +119,273 @@ typedef struct __SecPolicy *SecPolicyRef;
     @result The CFTypeID of SecPolicy instances.
 */
 CFTypeID SecPolicyGetTypeID(void)
     @result The CFTypeID of SecPolicy instances.
 */
 CFTypeID SecPolicyGetTypeID(void)
-    __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_2_0);
+       __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_2_0);
+
+/*!
+    @function SecPolicyCopyProperties
+    @abstract Returns a dictionary of this policy's properties.
+    @param policyRef A policy reference.
+    @result A properties dictionary. See "Policy Value Constants" for a list
+    of currently defined property keys. It is the caller's responsibility to
+    CFRelease this reference when it is no longer needed.
+    @result A result code. See "Security Error Codes" (SecBase.h).
+    @discussion This function returns the properties for a policy, as set by the
+    policy's construction function or by a prior call to SecPolicySetProperties.
+*/
+CFDictionaryRef SecPolicyCopyProperties(SecPolicyRef policyRef)
+       __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0);
 
 /*!
     @function SecPolicyCreateBasicX509
     @abstract Returns a policy object for the default X.509 policy.
     @result A policy object. The caller is responsible for calling CFRelease
 
 /*!
     @function SecPolicyCreateBasicX509
     @abstract Returns a policy object for the default X.509 policy.
     @result A policy object. The caller is responsible for calling CFRelease
-       on this when it is no longer needed.
+    on this when it is no longer needed.
 */
 SecPolicyRef SecPolicyCreateBasicX509(void)
 */
 SecPolicyRef SecPolicyCreateBasicX509(void)
-    __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
+       __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
 
 /*!
     @function SecPolicyCreateSSL
     @abstract Returns a policy object for evaluating SSL certificate chains.
 
 /*!
     @function SecPolicyCreateSSL
     @abstract Returns a policy object for evaluating SSL certificate chains.
-       @param server Passing true for this parameter create a policy for SSL
-       server certificates.
-       @param hostname Optional; if present, the policy will require the specified
-       hostname to match the hostname in the leaf certificate.
+    @param server Passing true for this parameter creates a policy for SSL
+    server certificates.
+    @param hostname (Optional) If present, the policy will require the specified
+    hostname to match the hostname in the leaf certificate.
     @result A policy object. The caller is responsible for calling CFRelease
     @result A policy object. The caller is responsible for calling CFRelease
-       on this when it is no longer needed.
+    on this when it is no longer needed.
 */
 SecPolicyRef SecPolicyCreateSSL(Boolean server, CFStringRef hostname)
 */
 SecPolicyRef SecPolicyCreateSSL(Boolean server, CFStringRef hostname)
-    __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
+       __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
+
+/*!
+       @enum Revocation Policy Constants
+       @abstract Predefined constants which allow you to specify how revocation
+       checking will be performed for a trust evaluation.
+       @constant kSecRevocationOCSPMethod If this flag is set, perform revocation
+       checking using OCSP (Online Certificate Status Protocol).
+       @constant kSecRevocationCRLMethod If this flag is set, perform revocation
+       checking using the CRL (Certificate Revocation List) method.
+       @constant kSecRevocationPreferCRL If this flag is set, then CRL revocation
+       checking will be preferred over OCSP (by default, OCSP is preferred.)
+       Note that this flag only matters if both revocation methods are specified.
+       @constant kSecRevocationRequirePositiveResponse If this flag is set, then
+       the policy will fail unless a verified positive response is obtained. If
+       the flag is not set, revocation checking is done on a "best attempt" basis,
+       where failure to reach the server is not considered fatal.
+       @constant kSecRevocationNetworkAccessDisabled If this flag is set, then
+       no network access is performed; only locally cached replies are consulted.
+       @constant kSecRevocationUseAnyAvailableMethod Specifies that either
+       OCSP or CRL may be used, depending on the method(s) specified in the
+       certificate and the value of kSecRevocationPreferCRL.
+ */
+enum {
+       kSecRevocationOCSPMethod = (1 << 0),
+       kSecRevocationCRLMethod = (1 << 1),
+       kSecRevocationPreferCRL = (1 << 2),
+       kSecRevocationRequirePositiveResponse = (1 << 3),
+       kSecRevocationNetworkAccessDisabled = (1 << 4),
+       kSecRevocationUseAnyAvailableMethod = (kSecRevocationOCSPMethod |
+               kSecRevocationCRLMethod)
+};
+
+/*!
+       @function SecPolicyCreateRevocation
+       @abstract Returns a policy object for checking revocation of certificates.
+       @result A policy object. The caller is responsible for calling CFRelease
+       on this when it is no longer needed.
+       @param revocationFlags Flags to specify revocation checking options.
+       @discussion Use this function to create a revocation policy with behavior
+       specified by revocationFlags. See the "Revocation Policy Constants" section
+       for a description of these flags. Note: it is usually not necessary to
+       create a revocation policy yourself unless you wish to override default
+       system behavior (e.g. to force a particular method, or to disable
+       revocation checking entirely.)
+*/
+SecPolicyRef SecPolicyCreateRevocation(CFOptionFlags revocationFlags)
+       __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+
+/*!
+       @function SecPolicyCreateWithProperties
+       @abstract Returns a policy object based on an object identifier for the
+       policy type. See the "Policy Constants" section for a list of defined
+       policy object identifiers.
+       @param policyIdentifier The identifier for the desired policy type.
+       @param properties (Optional) A properties dictionary. See "Policy Value
+       Constants" for a list of currently defined property keys.
+       @result The returned policy reference, or NULL if the policy could not be
+       created.
+*/
+SecPolicyRef SecPolicyCreateWithProperties(CFTypeRef policyIdentifier,
+       CFDictionaryRef properties)
+       __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+
+
+/*
+ *  Legacy functions (OS X only)
+ */
+#if TARGET_OS_MAC && !TARGET_OS_IPHONE
+#include <Security/cssmtype.h>
+
+/*!
+    @enum Policy Value Constants (OS X)
+    @discussion Predefined property key constants used to get or set values in
+        a dictionary for a policy instance.
+
+        Some policy values may specify CFBooleanRef key usage constraints:
+            kSecPolicyKU_DigitalSignature
+            kSecPolicyKU_NonRepudiation
+            kSecPolicyKU_KeyEncipherment
+            kSecPolicyKU_DataEncipherment
+            kSecPolicyKU_KeyAgreement
+            kSecPolicyKU_KeyCertSign
+            kSecPolicyKU_CRLSign
+            kSecPolicyKU_EncipherOnly
+            kSecPolicyKU_DecipherOnly
+
+        kSecPolicyKU policy values define certificate-level key purposes,
+        in contrast to the key-level definitions in SecItem.h
+
+        For example, a key in a certificate might be acceptable to use for
+        signing a CRL, but not for signing another certificate. In either
+        case, this key would have the ability to sign (i.e. kSecAttrCanSign
+        is true), but may only sign for specific purposes allowed by these
+        policy constants. Similarly, a public key might have the capability
+        to perform encryption or decryption, but the certificate in which it
+        resides might have a decipher-only certificate policy.
+
+        These constants correspond to values defined in RFC 5280, section
+        4.2.1.3 (Key Usage) which define the purpose of a key contained in a
+        certificate, in contrast to section 4.1.2.7 which define the uses that
+        a key is capable of.
+
+        Note: these constants are not available on iOS. Your code should
+        avoid direct reliance on these values for making policy decisions
+        and use higher level policies where possible.
+
+    @constant kSecPolicyKU_DigitalSignature Specifies that the certificate must
+        have a key usage that allows it to be used for signing.
+    @constant kSecPolicyKU_NonRepudiation Specifies that the certificate must
+        have a key usage that allows it to be used for non-repudiation.
+    @constant kSecPolicyKU_KeyEncipherment Specifies that the certificate must
+        have a key usage that allows it to be used for key encipherment.
+    @constant kSecPolicyKU_DataEncipherment Specifies that the certificate must
+        have a key usage that allows it to be used for data encipherment.
+    @constant kSecPolicyKU_KeyAgreement Specifies that the certificate must
+        have a key usage that allows it to be used for key agreement.
+    @constant kSecPolicyKU_KeyCertSign Specifies that the certificate must
+        have a key usage that allows it to be used for signing certificates.
+    @constant kSecPolicyKU_CRLSign Specifies that the certificate must
+        have a key usage that allows it to be used for signing CRLs.
+    @constant kSecPolicyKU_EncipherOnly Specifies that the certificate must
+        have a key usage that permits it to be used for encryption only.
+    @constant kSecPolicyKU_DecipherOnly Specifies that the certificate must
+        have a key usage that permits it to be used for decryption only.
+ */
+extern CFTypeRef kSecPolicyKU_DigitalSignature
+       __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+extern CFTypeRef kSecPolicyKU_NonRepudiation
+       __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+extern CFTypeRef kSecPolicyKU_KeyEncipherment
+       __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+extern CFTypeRef kSecPolicyKU_DataEncipherment
+       __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+extern CFTypeRef kSecPolicyKU_KeyAgreement
+       __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+extern CFTypeRef kSecPolicyKU_KeyCertSign
+       __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+extern CFTypeRef kSecPolicyKU_CRLSign
+       __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+extern CFTypeRef kSecPolicyKU_EncipherOnly
+       __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+extern CFTypeRef kSecPolicyKU_DecipherOnly
+       __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+
+/*!
+       @function SecPolicyCreateWithOID
+       @abstract Returns a policy object based on an object identifier for the
+       policy type. See the "Policy Constants" section for a list of defined
+       policy object identifiers.
+       @param policyOID The OID of the desired policy.
+       @result The returned policy reference, or NULL if the policy could not be
+       created.
+       @discussion This function is deprecated in Mac OS X 10.9 and later;
+       use SecPolicyCreateWithProperties (or a more specific policy creation
+       function) instead.
+*/
+SecPolicyRef SecPolicyCreateWithOID(CFTypeRef policyOID)
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_7, __MAC_10_9, __IPHONE_NA, __IPHONE_NA);
+
+/*!
+       @function SecPolicyGetOID
+       @abstract Returns a policy's object identifier.
+       @param policyRef A policy reference.
+       @param oid On return, a pointer to the policy's object identifier.
+       @result A result code. See "Security Error Codes" (SecBase.h).
+       @discussion This function is deprecated in Mac OS X 10.7 and later;
+       use SecPolicyCopyProperties instead.
+*/
+OSStatus SecPolicyGetOID(SecPolicyRef policyRef, CSSM_OID *oid)
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA);
+
+/*!
+       @function SecPolicyGetValue
+       @abstract Returns a policy's value.
+       @param policyRef A policy reference.
+       @param value On return, a pointer to the policy's value.
+       @result A result code. See "Security Error Codes" (SecBase.h).
+       @discussion This function is deprecated in Mac OS X 10.7 and later;
+       use SecPolicyCopyProperties instead.
+*/
+OSStatus SecPolicyGetValue(SecPolicyRef policyRef, CSSM_DATA *value)
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA);
+
+/*!
+       @function SecPolicySetValue
+       @abstract Sets a policy's value.
+       @param policyRef A policy reference.
+       @param value The value to be set into the policy object, replacing any
+       previous value.
+       @result A result code. See "Security Error Codes" (SecBase.h).
+       @discussion This function is deprecated in Mac OS X 10.7 and later. Policy
+       instances should be considered read-only; in cases where your code would
+       consider changing properties of a policy, it should instead create a new
+       policy instance with the desired properties.
+*/
+OSStatus SecPolicySetValue(SecPolicyRef policyRef, const CSSM_DATA *value)
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA);
+
+/*!
+       @function SecPolicySetProperties
+       @abstract Sets a policy's properties.
+       @param policyRef A policy reference.
+       @param properties A properties dictionary. See "Policy Value Constants"
+       for a list of currently defined property keys. This dictionary replaces the
+       policy's existing properties, if any. Note that the policy OID (specified
+       by kSecPolicyOid) is a read-only property of the policy and cannot be set.
+       @result A result code. See "Security Error Codes" (SecBase.h).
+       @discussion This function is deprecated in Mac OS X 10.9 and later. Policy
+       instances should be considered read-only; in cases where your code would
+       consider changing properties of a policy, it should instead create a new
+       policy instance with the desired properties.
+*/
+OSStatus SecPolicySetProperties(SecPolicyRef policyRef,
+       CFDictionaryRef properties)
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_7, __MAC_10_9, __IPHONE_NA, __IPHONE_NA);
+
+/*!
+       @function SecPolicyGetTPHandle
+       @abstract Returns the CSSM trust policy handle for the given policy.
+       @param policyRef A policy reference.
+       @param tpHandle On return, a pointer to a value of type CSSM_TP_HANDLE.
+       @result A result code. See "Security Error Codes" (SecBase.h).
+       @discussion This function is deprecated in Mac OS X 10.7 and later.
+*/
+OSStatus SecPolicyGetTPHandle(SecPolicyRef policyRef, CSSM_TP_HANDLE *tpHandle)
+       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA);
+
+#endif /* TARGET_OS_MAC && !TARGET_OS_IPHONE */
+
 
 
-#if defined(__cplusplus)
-}
-#endif
+__END_DECLS
 
 #endif /* !_SECURITY_SECPOLICY_H_ */
 
 #endif /* !_SECURITY_SECPOLICY_H_ */
index 63979a01c891bffadcd17964a707ede1c1343bc9..44418aea0b0fb08b8e34143e4f3fa29789c0d498 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2008-2009 Apple Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2008-2012 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -37,9 +37,7 @@
 #include <CoreFoundation/CFString.h>
 #include <CoreFoundation/CFRuntime.h>
 
 #include <CoreFoundation/CFString.h>
 #include <CoreFoundation/CFRuntime.h>
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 /********************************************************
  ****************** SecPolicy struct ********************
 
 /********************************************************
  ****************** SecPolicy struct ********************
@@ -52,7 +50,7 @@ struct __SecPolicy {
 
 /*!
     @enum Policy Check Keys
 
 /*!
     @enum Policy Check Keys
-    @discussion Key that represent various check that can be done be a trust
+    @discussion Keys that represent various checks that can be done in a trust
        policy.
     @constant kSecPolicyCheckCriticalExtensions Ensure that no certificate in the chain has any critical extensions that we do not understand.
     @constant kSecPolicyCheckIdLinkage Check that all the certificates in the chain that have a SubjectId, match the AuthorityId of the certificate they sign.  This check is optional, in that if either certificate is missing the required extension the check succeeds.
        policy.
     @constant kSecPolicyCheckCriticalExtensions Ensure that no certificate in the chain has any critical extensions that we do not understand.
     @constant kSecPolicyCheckIdLinkage Check that all the certificates in the chain that have a SubjectId, match the AuthorityId of the certificate they sign.  This check is optional, in that if either certificate is missing the required extension the check succeeds.
@@ -98,25 +96,28 @@ extern CFStringRef kSecPolicyCheckIssuerCommonName;
 extern CFStringRef kSecPolicyCheckSubjectCommonName;
 extern CFStringRef kSecPolicyCheckSubjectCommonNameTEST;
 extern CFStringRef kSecPolicyCheckSubjectOrganization;
 extern CFStringRef kSecPolicyCheckSubjectCommonName;
 extern CFStringRef kSecPolicyCheckSubjectCommonNameTEST;
 extern CFStringRef kSecPolicyCheckSubjectOrganization;
+extern CFStringRef kSecPolicyCheckSubjectOrganizationalUnit;
 extern CFStringRef kSecPolicyCheckSubjectCommonNamePrefix;
 extern CFStringRef kSecPolicyCheckChainLength;
 extern CFStringRef kSecPolicyCheckNotValidBefore;
 extern CFStringRef kSecPolicyCheckEAPTrustedServerNames;
 extern CFStringRef kSecPolicyCheckSubjectCommonNamePrefix;
 extern CFStringRef kSecPolicyCheckChainLength;
 extern CFStringRef kSecPolicyCheckNotValidBefore;
 extern CFStringRef kSecPolicyCheckEAPTrustedServerNames;
+extern CFStringRef kSecPolicyCheckCertificatePolicy;
 extern CFStringRef kSecPolicyCheckBasicCertificateProcessing;
 extern CFStringRef kSecPolicyCheckExtendedValidation;
 extern CFStringRef kSecPolicyCheckRevocation;
 extern CFStringRef kSecPolicyCheckNoNetworkAccess;
 extern CFStringRef kSecPolicyCheckBlackListedLeaf;
 extern CFStringRef kSecPolicyCheckBlackListedKey;
 extern CFStringRef kSecPolicyCheckBasicCertificateProcessing;
 extern CFStringRef kSecPolicyCheckExtendedValidation;
 extern CFStringRef kSecPolicyCheckRevocation;
 extern CFStringRef kSecPolicyCheckNoNetworkAccess;
 extern CFStringRef kSecPolicyCheckBlackListedLeaf;
 extern CFStringRef kSecPolicyCheckBlackListedKey;
+extern CFStringRef kSecPolicyCheckGrayListedLeaf;
 extern CFStringRef kSecPolicyCheckLeafMarkerOid;
 extern CFStringRef kSecPolicyCheckIntermediateMarkerOid;
 extern CFStringRef kSecPolicyCheckLeafMarkerOid;
 extern CFStringRef kSecPolicyCheckIntermediateMarkerOid;
+extern CFStringRef kSecPolicyCheckGrayListedKey;
 
 SecPolicyRef SecPolicyCreate(CFStringRef oid, CFDictionaryRef options);
 
 
 SecPolicyRef SecPolicyCreate(CFStringRef oid, CFDictionaryRef options);
 
-CFArrayRef SecPolicyArraySerialize(CFArrayRef policies);
+xpc_object_t SecPolicyArrayCopyXPCArray(CFArrayRef policies, CFErrorRef *error);
+CFArrayRef SecPolicyXPCArrayCopyArray(xpc_object_t xpc_policies, CFErrorRef *error);
 
 
-#if defined(__cplusplus)
-}
-#endif
+__END_DECLS
 
 #endif /* !_SECURITY_SECPOLICYINTERNAL_H_ */
 
 #endif /* !_SECURITY_SECPOLICYINTERNAL_H_ */
index 96615ab3e34f2e9af4ac21f6891824824035c88e..306b3364f66eaa95627c8d6c14c1a5387ea12304 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2007-2009 Apple Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2007-2013 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
 #define _SECURITY_SECPOLICYPRIV_H_
 
 #include <Security/SecPolicy.h>
 #define _SECURITY_SECPOLICYPRIV_H_
 
 #include <Security/SecPolicy.h>
+#include <Security/SecCertificate.h>
 #include <CoreFoundation/CFArray.h>
 #include <CoreFoundation/CFString.h>
 
 #include <CoreFoundation/CFArray.h>
 #include <CoreFoundation/CFString.h>
 
-#if defined(__cplusplus)
-extern "C" {
+__BEGIN_DECLS
+
+/*!
+       @enum Policy Constants (Private)
+       @discussion Predefined constants used to specify a policy.
+       @constant kSecPolicyApplePassbookSigning
+       @constant kSecPolicyAppleMobileStore
+       @constant kSecPolicyAppleTestMobileStore
+       @constant kSecPolicyAppleEscrowService
+       @constant kSecPolicyAppleProfileSigner
+       @constant kSecPolicyAppleQAProfileSigner
+       @constant kSecPolicyAppleOTAPKISigner
+       @constant kSecPolicyAppleTestOTAPKISigner
+
+*/
+extern CFTypeRef kSecPolicyApplePassbookSigning
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFTypeRef kSecPolicyAppleMobileStore
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFTypeRef kSecPolicyAppleTestMobileStore 
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFTypeRef kSecPolicyAppleEscrowService
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFTypeRef kSecPolicyAppleProfileSigner
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFTypeRef kSecPolicyAppleQAProfileSigner
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+#if TARGET_OS_IPHONE
+extern CFTypeRef kSecPolicyAppleOTAPKISigner
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFTypeRef kSecPolicyAppleTestOTAPKISigner
+    __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_7_0);
+extern CFTypeRef kSecPolicyAppleIDValidationRecordSigningPolicy
+       __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_7_0);
 #endif
 
 #endif
 
+
+/*!
+    @enum Policy Value Constants
+    @abstract Predefined property key constants used to get or set values in
+        a dictionary for a policy instance.
+    @constant kSecPolicyTeamIdentifier Specifies a CFStringRef containing a
+        team identifier which must be matched in the certificate to satisfy
+        this policy. For the Passbook signing policy, this string must match
+        the Organizational Unit field of the certificate subject.
+*/
+extern CFTypeRef kSecPolicyTeamIdentifier
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+
 /*!
     @function SecPolicyCreateiPhoneActivation
     @abstract Returns a policy object for verifying iPhone Activation
 /*!
     @function SecPolicyCreateiPhoneActivation
     @abstract Returns a policy object for verifying iPhone Activation
@@ -54,7 +100,7 @@ SecPolicyRef SecPolicyCreateiPhoneActivation(void);
 
 /*!
     @function SecPolicyCreateiPhoneDeviceCertificate
 
 /*!
     @function SecPolicyCreateiPhoneDeviceCertificate
-    @abstract Returns a policy object for verifying iPhone Device certificate 
+    @abstract Returns a policy object for verifying iPhone Device certificate
     chains.
     @discussion This policy is like the Basic X.509 policy with the additional
     requirements that the chain must contain exactly four certificates, the
     chains.
     @discussion This policy is like the Basic X.509 policy with the additional
     requirements that the chain must contain exactly four certificates, the
@@ -67,7 +113,7 @@ SecPolicyRef SecPolicyCreateiPhoneDeviceCertificate(void);
 
 /*!
     @function SecPolicyCreateFactoryDeviceCertificate
 
 /*!
     @function SecPolicyCreateFactoryDeviceCertificate
-    @abstract Returns a policy object for verifying Factory Device certificate 
+    @abstract Returns a policy object for verifying Factory Device certificate
     chains.
     @discussion This policy is like the Basic X.509 policy with the additional
     requirements that the chain must be anchored to the factory device certificate
     chains.
     @discussion This policy is like the Basic X.509 policy with the additional
     requirements that the chain must be anchored to the factory device certificate
@@ -167,13 +213,6 @@ SecPolicyRef SecPolicyCreateiPhoneProvisioningProfileSigning(void);
 */
 SecPolicyRef SecPolicyCreateOCSPSigner(void);
 
 */
 SecPolicyRef SecPolicyCreateOCSPSigner(void);
 
-/*!
-    @function SecPolicyCreateRevocation
-    @abstract Returns a policy object for checking revocation of certificates.
-    @result A policy object. The caller is responsible for calling CFRelease
-       on this when it is no longer needed.
-*/
-SecPolicyRef SecPolicyCreateRevocation(void);
 
 enum {
     kSecSignSMIMEUsage = (1 << 0),
 
 enum {
     kSecSignSMIMEUsage = (1 << 0),
@@ -190,7 +229,7 @@ enum {
     @function SecPolicyCreateSMIME
     @abstract Returns a policy object for evaluating S/MIME certificate chains.
        @param smimeUsage Pass the bitwise or of one or more kSecXXXSMIMEUsage
     @function SecPolicyCreateSMIME
     @abstract Returns a policy object for evaluating S/MIME certificate chains.
        @param smimeUsage Pass the bitwise or of one or more kSecXXXSMIMEUsage
-    flags, to indicated the intended usage of this certificate.  A certificate which allows 
+    flags, to indicated the intended usage of this certificate.  A certificate which allows
        @param email Optional; if present, the policy will require the specified
        email to match the email in the leaf certificate.
     @result A policy object. The caller is responsible for calling CFRelease
        @param email Optional; if present, the policy will require the specified
        email to match the email in the leaf certificate.
     @result A policy object. The caller is responsible for calling CFRelease
@@ -235,13 +274,105 @@ SecPolicyRef SecPolicyCreateOTATasking(void);
 SecPolicyRef SecPolicyCreateMobileAsset(void);
 
 /*!
 SecPolicyRef SecPolicyCreateMobileAsset(void);
 
 /*!
   @function SecPolicyCreateAppleIDAuthorityPolicy
   @abstract check for an Apple ID identity per marker in the leaf and marker in the intermediate, rooted in the Apple CA.
+ @function SecPolicyCreateAppleIDAuthorityPolicy
+ @abstract check for an Apple ID identity per marker in the leaf and marker in the intermediate, rooted in the Apple CA.
  */
 SecPolicyRef SecPolicyCreateAppleIDAuthorityPolicy(void);
 
  */
 SecPolicyRef SecPolicyCreateAppleIDAuthorityPolicy(void);
 
-#if defined(__cplusplus)
-}
+/*!
+ @function SecPolicyCreatePassbookCardSigner
+ @abstract check rooted in the Apple CA, eku shoebox, marker shoebox and name matching
+ @param cardIssuer Required; must match name in marker extension.
+ @param teamIdentifier Optional; if present, the policy will require the specified
+ team ID to match the organizationalUnit field in the leaf certificate's subject.
+ @result A policy object. The caller is responsible for calling CFRelease
+       on this when it is no longer needed.
+ */
+SecPolicyRef SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer,
+       CFStringRef teamIdentifier);
+
+/*!
+ @function SecPolicyCreateShoeboxCardSigner
+ @abstract Deprecated; use SecPolicyCreatePassbookCardSigner instead
+ */
+SecPolicyRef SecPolicyCreateShoeboxCardSigner(CFStringRef cardIssuer);
+
+/*!
+ @function SecPolicyCreateMobileStoreSigner
+ @abstract Check for key usage of digital signature,
+       check for 3 long chain through Apple System Integration 2 Certification Authority
+       with a certificate policy OID of 1.2.840.113635.100.5.12 that roots to the
+       Apple root
+ */
+SecPolicyRef SecPolicyCreateMobileStoreSigner(void);
+
+/*!
+ @function SecPolicyCreateTestMobileStoreSigner
+ @abstract Check for key usage of digital signature,
+       check for 3 long chain through Apple System Integration 2 Certification Authority
+       with a certificate policy OID of 1.2.840.113635.100.5.12.1 that roots to the
+       Apple root
+ */
+SecPolicyRef SecPolicyCreateTestMobileStoreSigner(void);
+
+/*!
+ @function SecPolicyCreateEscrowServiceSigner
+ @abstract Check for key usage of digital signature, has a leaf marker OID of
+        1.2.840.113635.100.6.23.1 and roots to the Test Escrow Root
+ */
+SecPolicyRef SecPolicyCreateEscrowServiceSigner(void);
+
+/*!
+ @function SecPolicyCopyEscrowRootCertificate
+ @abstract Return back the Root certificate for the Escrow service
+*/
+SecCertificateRef SecPolicyCopyEscrowRootCertificate(void);
+
+/*!
+ @function SecPolicyCreateConfigurationProfileSigner
+ @abstract Check for key usage of digital signature, has a EKU OID of
+     1.2.840.113635.100.4.16 and 
+    roots to Apple Application Integration 2 Certification Authority
+*/
+SecPolicyRef SecPolicyCreateConfigurationProfileSigner(void);
+
+/*!
+ @function SecPolicyCreateQAConfigurationProfileSigner
+ @abstract Check for key usage of digital signature, has a EKU OID of
+    1.2.840.113635.100.4.17 and 
+    roots to Apple Application Integration 2 Certification Authority
+*/
+SecPolicyRef SecPolicyCreateQAConfigurationProfileSigner(void);
+
+#if TARGET_OS_IPHONE
+/*!
+ @function SecPolicyCreateOTAPKISigner
+ @abstract Check for key usage of digital signature, and
+    roots to Apple PKI Settings Root Certification Authority
+*/
+SecPolicyRef SecPolicyCreateOTAPKISigner(void);
+
+/*!
+ @function SecPolicyCreateTestOTAPKISigner
+ @abstract Check for key usage of digital signature, and
+    roots to Apple PKI Settings Root - TESTING
+*/
+SecPolicyRef SecPolicyCreateTestOTAPKISigner(void);
+
+/*!
+ @function SecPolicyCreateAppleIDValidationRecordSigningPolicy
+ @abstract Check for leaf certificate contains the
+       appleIDValidationRecordSigning (1 2 840 113635 100 6 25), and
+       intermediate certificate contains 
+       appleCertificateExtensionApplicationIntegrationIntermediate
+       (1 2 840 113635 100 6 2 3) and
+       appleCertificateExtensionSystemIntegration2Intermediate
+       (1 2 840 113635 100 6 2 10) and roots to the Apple root
+*/
+SecPolicyRef SecPolicyCreateAppleIDValidationRecordSigningPolicy(void);
+
 #endif
 
 #endif
 
+__END_DECLS
+
 #endif /* !_SECURITY_SECPOLICYPRIV_H_ */
 #endif /* !_SECURITY_SECPOLICYPRIV_H_ */
index a8361811c0f86bbce8780622630554b0d538bef9..51bb520793613a653f30a322a27dc92cc06ac26b 100644 (file)
@@ -1,15 +1,15 @@
 /*
  * Copyright (c) 2006-2010 Apple Inc. All Rights Reserved.
 /*
  * Copyright (c) 2006-2010 Apple Inc. All Rights Reserved.
- * 
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
-/* 
+/*
  * SecRSAKey.c - CoreFoundation based rsa key object
  */
 
  * SecRSAKey.c - CoreFoundation based rsa key object
  */
 
@@ -40,7 +40,8 @@
 #include <CoreFoundation/CFNumber.h>
 #include <Security/SecFramework.h>
 #include <Security/SecRandom.h>
 #include <CoreFoundation/CFNumber.h>
 #include <Security/SecFramework.h>
 #include <Security/SecRandom.h>
-#include <security_utilities/debugging.h>
+#include <utilities/debugging.h>
+#include <utilities/SecCFWrappers.h>
 #include "SecItemPriv.h"
 #include <Security/SecInternal.h>
 
 #include "SecItemPriv.h"
 #include <Security/SecInternal.h>
 
@@ -71,10 +72,10 @@ static void ccn_c_dump(cc_size count, const cc_unit *s)
     cc_size ix;
     for (ix = count; ix--;) {
         printf("0x%.02x, 0x%.02x, 0x%.02x, 0x%.02x, ",
     cc_size ix;
     for (ix = count; ix--;) {
         printf("0x%.02x, 0x%.02x, 0x%.02x, 0x%.02x, ",
-               (s[ix] >> 24) & 0xFF,
-               (s[ix] >> 16) & 0xFF,
-               (s[ix] >> 8 ) & 0xFF,
-               (s[ix] >> 0 ) & 0xFF);
+               (int) ((s[ix] >> 24) & 0xFF),
+               (int) ((s[ix] >> 16) & 0xFF),
+               (int) ((s[ix] >> 8 ) & 0xFF),
+               (int) ((s[ix] >> 0 ) & 0xFF));
     }
     printf("};");
 }
     }
     printf("};");
 }
@@ -92,7 +93,7 @@ void ccrsa_dump_full_key(ccrsa_full_ctx_t key) {
     ccn_cprint(ccrsa_ctx_n(key) + 1,  "uint8_t rm[] = ", cczp_recip(ccrsa_ctx_zm(key)));
     ccn_cprint(ccrsa_ctx_n(key),      "uint8_t e[]  = ", ccrsa_ctx_e(key));
     ccn_cprint(ccrsa_ctx_n(key),      "uint8_t d[]  = ", ccrsa_ctx_d(key));
     ccn_cprint(ccrsa_ctx_n(key) + 1,  "uint8_t rm[] = ", cczp_recip(ccrsa_ctx_zm(key)));
     ccn_cprint(ccrsa_ctx_n(key),      "uint8_t e[]  = ", ccrsa_ctx_e(key));
     ccn_cprint(ccrsa_ctx_n(key),      "uint8_t d[]  = ", ccrsa_ctx_d(key));
-
+    
     printf("cc_size np = %lu;\n", cczp_n(ccrsa_ctx_private_zp(ccrsa_ctx_private(key))));
     ccn_cprint(cczp_n(ccrsa_ctx_private_zp(ccrsa_ctx_private(key))),     "uint8_t p[]  = ",
                cczp_prime(ccrsa_ctx_private_zp(ccrsa_ctx_private(key))));
     printf("cc_size np = %lu;\n", cczp_n(ccrsa_ctx_private_zp(ccrsa_ctx_private(key))));
     ccn_cprint(cczp_n(ccrsa_ctx_private_zp(ccrsa_ctx_private(key))),     "uint8_t p[]  = ",
                cczp_prime(ccrsa_ctx_private_zp(ccrsa_ctx_private(key))));
@@ -117,7 +118,7 @@ void ccrsa_dump_public_key(ccrsa_pub_ctx_t key) {
     ccn_cprint(ccrsa_ctx_n(key),      "uint8_t m[]  = ", ccrsa_ctx_m(key));
     ccn_cprint(ccrsa_ctx_n(key) + 1,  "uint8_t rm[] = ", cczp_recip(ccrsa_ctx_zm(key)));
     ccn_cprint(ccrsa_ctx_n(key),      "uint8_t e[]  = ", ccrsa_ctx_e(key));
     ccn_cprint(ccrsa_ctx_n(key),      "uint8_t m[]  = ", ccrsa_ctx_m(key));
     ccn_cprint(ccrsa_ctx_n(key) + 1,  "uint8_t rm[] = ", cczp_recip(ccrsa_ctx_zm(key)));
     ccn_cprint(ccrsa_ctx_n(key),      "uint8_t e[]  = ", ccrsa_ctx_e(key));
-
+    
     printf("--\n");
 }
 
     printf("--\n");
 }
 
@@ -146,16 +147,16 @@ static int ccrsa_pub_init(ccrsa_pub_ctx_t pubkey,
                           size_t e_size, const uint8_t* e)
 {
     cc_skip_zeros(m_size, m);
                           size_t e_size, const uint8_t* e)
 {
     cc_skip_zeros(m_size, m);
-
+    
     cc_size nm = ccn_nof_size(m_size);
     if (nm > ccrsa_ctx_n(pubkey))
         return -1;
     cc_size nm = ccn_nof_size(m_size);
     if (nm > ccrsa_ctx_n(pubkey))
         return -1;
-
+    
     ccrsa_ctx_n(pubkey) = nm;
     ccrsa_ctx_n(pubkey) = nm;
-
+    
     ccn_read_uint(nm, ccrsa_ctx_m(pubkey), m_size, m);
     cczp_init(ccrsa_ctx_zm(pubkey));
     ccn_read_uint(nm, ccrsa_ctx_m(pubkey), m_size, m);
     cczp_init(ccrsa_ctx_zm(pubkey));
-
+    
     return ccn_read_uint(nm, ccrsa_ctx_e(pubkey), e_size, e);
 }
 
     return ccn_read_uint(nm, ccrsa_ctx_e(pubkey), e_size, e);
 }
 
@@ -163,22 +164,22 @@ static int ccrsa_pub_init(ccrsa_pub_ctx_t pubkey,
 static OSStatus ccrsa_pub_decode(ccrsa_pub_ctx_t pubkey, size_t pkcs1_size, const uint8_t* pkcs1)
 {
     OSStatus result = errSecParam;
 static OSStatus ccrsa_pub_decode(ccrsa_pub_ctx_t pubkey, size_t pkcs1_size, const uint8_t* pkcs1)
 {
     OSStatus result = errSecParam;
-
+    
        DERItem keyItem = {(DERByte *)pkcs1, pkcs1_size};
     DERRSAPubKeyPKCS1 decodedKey;
        DERItem keyItem = {(DERByte *)pkcs1, pkcs1_size};
     DERRSAPubKeyPKCS1 decodedKey;
-
+    
        require_noerr_action(DERParseSequence(&keyItem,
                                           DERNumRSAPubKeyPKCS1ItemSpecs, DERRSAPubKeyPKCS1ItemSpecs,
                                           &decodedKey, sizeof(decodedKey)),
                          errOut, result = errSecDecode);
        require_noerr_action(DERParseSequence(&keyItem,
                                           DERNumRSAPubKeyPKCS1ItemSpecs, DERRSAPubKeyPKCS1ItemSpecs,
                                           &decodedKey, sizeof(decodedKey)),
                          errOut, result = errSecDecode);
-
+    
     require_noerr(ccrsa_pub_init(pubkey,
                                  decodedKey.modulus.length, decodedKey.modulus.data,
                                  decodedKey.pubExponent.length, decodedKey.pubExponent.data),
                   errOut);
     require_noerr(ccrsa_pub_init(pubkey,
                                  decodedKey.modulus.length, decodedKey.modulus.data,
                                  decodedKey.pubExponent.length, decodedKey.pubExponent.data),
                   errOut);
-
+    
     result = errSecSuccess;
     result = errSecSuccess;
-
+    
 errOut:
     return result;
 }
 errOut:
     return result;
 }
@@ -186,25 +187,25 @@ errOut:
 static OSStatus ccrsa_pub_decode_apple(ccrsa_pub_ctx_t pubkey, size_t pkcs1_size, const uint8_t* pkcs1)
 {
     OSStatus result = errSecParam;
 static OSStatus ccrsa_pub_decode_apple(ccrsa_pub_ctx_t pubkey, size_t pkcs1_size, const uint8_t* pkcs1)
 {
     OSStatus result = errSecParam;
-
+    
        DERItem keyItem = {(DERByte *)pkcs1, pkcs1_size};
     DERRSAPubKeyApple decodedKey;
        DERItem keyItem = {(DERByte *)pkcs1, pkcs1_size};
     DERRSAPubKeyApple decodedKey;
-
+    
        require_noerr_action(DERParseSequence(&keyItem,
                                           DERNumRSAPubKeyAppleItemSpecs, DERRSAPubKeyAppleItemSpecs,
                                           &decodedKey, sizeof(decodedKey)),
                          errOut, result = errSecDecode);
        require_noerr_action(DERParseSequence(&keyItem,
                                           DERNumRSAPubKeyAppleItemSpecs, DERRSAPubKeyAppleItemSpecs,
                                           &decodedKey, sizeof(decodedKey)),
                          errOut, result = errSecDecode);
-
+    
     // We could honor the recipricol, but we don't think this is used enough to care.
     // Don't bother exploding the below function to try to handle this case, it computes.
     // We could honor the recipricol, but we don't think this is used enough to care.
     // Don't bother exploding the below function to try to handle this case, it computes.
-
+    
     require_noerr(ccrsa_pub_init(pubkey,
                                  decodedKey.modulus.length, decodedKey.modulus.data,
                                  decodedKey.pubExponent.length, decodedKey.pubExponent.data),
                   errOut);
     require_noerr(ccrsa_pub_init(pubkey,
                                  decodedKey.modulus.length, decodedKey.modulus.data,
                                  decodedKey.pubExponent.length, decodedKey.pubExponent.data),
                   errOut);
-
+    
     result = errSecSuccess;
     result = errSecSuccess;
-
+    
 errOut:
     return result;
 }
 errOut:
     return result;
 }
@@ -214,90 +215,90 @@ static void ccasn_encode_int(cc_size n, const cc_unit*s, size_t s_size, uint8_t
 {
     **buffer = ASN1_INTEGER;
     *buffer += 1;
 {
     **buffer = ASN1_INTEGER;
     *buffer += 1;
-
+    
     DERSize itemLength = 4;
     DEREncodeLength(s_size, *buffer, &itemLength);
     *buffer += itemLength;
     DERSize itemLength = 4;
     DEREncodeLength(s_size, *buffer, &itemLength);
     *buffer += itemLength;
-
+    
     ccn_write_int(n, s, s_size, *buffer);
     ccn_write_int(n, s, s_size, *buffer);
-
+    
     *buffer += s_size;
 }
 
 
 static OSStatus SecRSAPublicKeyInit(SecKeyRef key,
     *buffer += s_size;
 }
 
 
 static OSStatus SecRSAPublicKeyInit(SecKeyRef key,
-    const uint8_t *keyData, CFIndex keyDataLength, SecKeyEncoding encoding) {
-
+                                    const uint8_t *keyData, CFIndex keyDataLength, SecKeyEncoding encoding) {
+    
     OSStatus result = errSecParam;
     OSStatus result = errSecParam;
-
+    
     ccrsa_pub_ctx_t pubkey;
     pubkey.pub = key->key;
     ccrsa_pub_ctx_t pubkey;
     pubkey.pub = key->key;
-
+    
     // Set maximum size for parsers
     ccrsa_ctx_n(pubkey) = ccn_nof(kMaximumRSAKeyBits);
     // Set maximum size for parsers
     ccrsa_ctx_n(pubkey) = ccn_nof(kMaximumRSAKeyBits);
-
+    
     switch (encoding) {
     switch (encoding) {
-    case kSecKeyEncodingBytes: // Octets is PKCS1
-    case kSecKeyEncodingPkcs1:
-        result = ccrsa_pub_decode(pubkey, keyDataLength, keyData);
-        break;
-    case kSecKeyEncodingApplePkcs1:
-        result = ccrsa_pub_decode_apple(pubkey, keyDataLength, keyData);
-        break;
-    case kSecKeyEncodingRSAPublicParams:
-    {
-        SecRSAPublicKeyParams *params = (SecRSAPublicKeyParams *)keyData;
-
-        require_noerr(ccrsa_pub_init(pubkey,
-                       params->modulusLength, params->modulus,
-                       params->exponentLength, params->exponent), errOut);
-
-        result = errSecSuccess;
-        break;
-    }
-    case kSecExtractPublicFromPrivate:
-    {
-        ccrsa_full_ctx_t fullKey;
-        fullKey.full = (ccrsa_full_ctx*) keyData;
-
-        cc_size fullKeyN = ccrsa_ctx_n(fullKey);
-        require(fullKeyN <= ccrsa_ctx_n(pubkey), errOut);
-        memcpy(pubkey.pub, ccrsa_ctx_public(fullKey).pub, ccrsa_pub_ctx_size(ccn_sizeof_n(fullKeyN)));
-        result = errSecSuccess;
-        break;
-    }
-    default:
-        break;
+        case kSecKeyEncodingBytes: // Octets is PKCS1
+        case kSecKeyEncodingPkcs1:
+            result = ccrsa_pub_decode(pubkey, keyDataLength, keyData);
+            break;
+        case kSecKeyEncodingApplePkcs1:
+            result = ccrsa_pub_decode_apple(pubkey, keyDataLength, keyData);
+            break;
+        case kSecKeyEncodingRSAPublicParams:
+        {
+            SecRSAPublicKeyParams *params = (SecRSAPublicKeyParams *)keyData;
+            
+            require_noerr(ccrsa_pub_init(pubkey,
+                                         params->modulusLength, params->modulus,
+                                         params->exponentLength, params->exponent), errOut);
+            
+            result = errSecSuccess;
+            break;
+        }
+        case kSecExtractPublicFromPrivate:
+        {
+            ccrsa_full_ctx_t fullKey;
+            fullKey.full = (ccrsa_full_ctx*) keyData;
+            
+            cc_size fullKeyN = ccrsa_ctx_n(fullKey);
+            require(fullKeyN <= ccrsa_ctx_n(pubkey), errOut);
+            memcpy(pubkey.pub, ccrsa_ctx_public(fullKey).pub, ccrsa_pub_ctx_size(ccn_sizeof_n(fullKeyN)));
+            result = errSecSuccess;
+            break;
+        }
+        default:
+            break;
     }
     }
-
+    
 errOut:
     return result;
 }
 
 static OSStatus SecRSAPublicKeyRawVerify(SecKeyRef key, SecPadding padding,
 errOut:
     return result;
 }
 
 static OSStatus SecRSAPublicKeyRawVerify(SecKeyRef key, SecPadding padding,
-    const uint8_t *signedData, size_t signedDataLen,
-    const uint8_t *sig, size_t sigLen) {
+                                         const uint8_t *signedData, size_t signedDataLen,
+                                         const uint8_t *sig, size_t sigLen) {
     OSStatus result = errSSLCrypto;
     OSStatus result = errSSLCrypto;
-
+    
     ccrsa_pub_ctx_t pubkey;
     pubkey.pub = key->key;
     ccrsa_pub_ctx_t pubkey;
     pubkey.pub = key->key;
-
+    
     cc_unit s[ccrsa_ctx_n(pubkey)];
     cc_unit s[ccrsa_ctx_n(pubkey)];
-
+    
     ccn_read_uint(ccrsa_ctx_n(pubkey), s, sigLen, sig);
     ccrsa_pub_crypt(pubkey, s, s);
     ccn_swap(ccrsa_ctx_n(pubkey), s);
     ccn_read_uint(ccrsa_ctx_n(pubkey), s, sigLen, sig);
     ccrsa_pub_crypt(pubkey, s, s);
     ccn_swap(ccrsa_ctx_n(pubkey), s);
-
+    
     const uint8_t* sBytes = (uint8_t*) s;
     const uint8_t* sEnd = (uint8_t*) (s + ccrsa_ctx_n(pubkey));
     const uint8_t* sBytes = (uint8_t*) s;
     const uint8_t* sEnd = (uint8_t*) (s + ccrsa_ctx_n(pubkey));
-
+    
     switch (padding) {
         case kSecPaddingNone:
             // Skip leading zeros as long as s is bigger than signedData.
             while (((ptrdiff_t)signedDataLen < (sEnd - sBytes)) && (*sBytes == 0))
                 ++sBytes;
             break;
     switch (padding) {
         case kSecPaddingNone:
             // Skip leading zeros as long as s is bigger than signedData.
             while (((ptrdiff_t)signedDataLen < (sEnd - sBytes)) && (*sBytes == 0))
                 ++sBytes;
             break;
-
+            
         case kSecPaddingPKCS1:
         {
             // Verify and skip PKCS1 padding:
         case kSecPaddingPKCS1:
         {
             // Verify and skip PKCS1 padding:
@@ -309,16 +310,16 @@ static OSStatus SecRSAPublicKeyRawVerify(SecKeyRef key, SecPadding padding,
             
             while (prefix_zeros--)
                 require_quiet(*sBytes++ == 0x00, errOut);
             
             while (prefix_zeros--)
                 require_quiet(*sBytes++ == 0x00, errOut);
-
+            
             require_quiet(*sBytes++ == 0x00, errOut);
             require_quiet(*sBytes++ == RSA_PKCS1_PAD_SIGN, errOut);
             require_quiet(*sBytes++ == 0x00, errOut);
             require_quiet(*sBytes++ == RSA_PKCS1_PAD_SIGN, errOut);
-
+            
             while (*sBytes == 0xFF) {
                 require_quiet(++sBytes < sEnd, errOut);
             }
             // Required to have at least 8 0xFFs
             require_quiet((sBytes - (uint8_t*)s) - 2 >= 8, errOut);
             while (*sBytes == 0xFF) {
                 require_quiet(++sBytes < sEnd, errOut);
             }
             // Required to have at least 8 0xFFs
             require_quiet((sBytes - (uint8_t*)s) - 2 >= 8, errOut);
-
+            
             require_quiet(*sBytes == 0x00, errOut);
             require_quiet(++sBytes < sEnd, errOut);
             break;
             require_quiet(*sBytes == 0x00, errOut);
             require_quiet(++sBytes < sEnd, errOut);
             break;
@@ -326,45 +327,47 @@ static OSStatus SecRSAPublicKeyRawVerify(SecKeyRef key, SecPadding padding,
         case kSecPaddingOAEP:
             result = errSecParam;
             goto errOut;
         case kSecPaddingOAEP:
             result = errSecParam;
             goto errOut;
-
+            
         default:
             result = errSecUnimplemented;
             goto errOut;
     }
         default:
             result = errSecUnimplemented;
             goto errOut;
     }
-
+    
     // Compare the rest.
     require_quiet((sEnd - sBytes) == (ptrdiff_t)signedDataLen, errOut);
     require_quiet(memcmp(sBytes, signedData, signedDataLen) == 0, errOut);
     // Compare the rest.
     require_quiet((sEnd - sBytes) == (ptrdiff_t)signedDataLen, errOut);
     require_quiet(memcmp(sBytes, signedData, signedDataLen) == 0, errOut);
-
+    
     result = errSecSuccess;
     result = errSecSuccess;
-
+    
 errOut:
     cc_zero(ccrsa_ctx_n(pubkey), s);
 errOut:
     cc_zero(ccrsa_ctx_n(pubkey), s);
-
+    
     return result;
 }
 
 static OSStatus SecRSAPublicKeyRawEncrypt(SecKeyRef key, SecPadding padding,
     return result;
 }
 
 static OSStatus SecRSAPublicKeyRawEncrypt(SecKeyRef key, SecPadding padding,
-    const uint8_t *plainText, size_t plainTextLen,
-       uint8_t *cipherText, size_t *cipherTextLen) {
+                                          const uint8_t *plainText, size_t plainTextLen,
+                                          uint8_t *cipherText, size_t *cipherTextLen) {
     OSStatus result = errSecParam;
     ccrsa_pub_ctx_t pubkey;
     pubkey.pub = key->key;
     OSStatus result = errSecParam;
     ccrsa_pub_ctx_t pubkey;
     pubkey.pub = key->key;
-
+    
     cc_unit s[ccrsa_ctx_n(pubkey)];
     const size_t m_size = ccn_write_uint_size(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey));
     cc_unit s[ccrsa_ctx_n(pubkey)];
     const size_t m_size = ccn_write_uint_size(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey));
-
+    
     require(cipherTextLen, errOut);
     require(*cipherTextLen >= m_size, errOut);
     require(cipherTextLen, errOut);
     require(*cipherTextLen >= m_size, errOut);
-
+    
     uint8_t* sBytes = (uint8_t*) s;
     uint8_t* sBytes = (uint8_t*) s;
-
+    
     switch (padding) {
         case kSecPaddingNone:
     switch (padding) {
         case kSecPaddingNone:
+            // We'll allow modulus size assuming input is smaller than modulus
+            require_quiet(plainTextLen <= m_size, errOut);
             require_noerr_quiet(ccn_read_uint(ccrsa_ctx_n(pubkey), s, plainTextLen, plainText), errOut);
             require_quiet(ccn_cmp(ccrsa_ctx_n(pubkey), s, ccrsa_ctx_m(pubkey)) < 0, errOut);
             break;
             require_noerr_quiet(ccn_read_uint(ccrsa_ctx_n(pubkey), s, plainTextLen, plainText), errOut);
             require_quiet(ccn_cmp(ccrsa_ctx_n(pubkey), s, ccrsa_ctx_m(pubkey)) < 0, errOut);
             break;
-
+            
         case kSecPaddingPKCS1:
         {
             // Create PKCS1 padding:
         case kSecPaddingPKCS1:
         {
             // Create PKCS1 padding:
@@ -372,90 +375,90 @@ static OSStatus SecRSAPublicKeyRawEncrypt(SecKeyRef key, SecPadding padding,
             // 0x00, 0x01 (RSA_PKCS1_PAD_ENCRYPT), 0xFF .. 0x00, signedData
             //
             const int kMinimumPadding = 1 + 1 + 8 + 1;
             // 0x00, 0x01 (RSA_PKCS1_PAD_ENCRYPT), 0xFF .. 0x00, signedData
             //
             const int kMinimumPadding = 1 + 1 + 8 + 1;
-
-            require_quiet(plainTextLen < m_size - kMinimumPadding, errOut);
-
+            
+            require_quiet(plainTextLen <= m_size - kMinimumPadding, errOut);
+            
             size_t prefix_zeros = ccn_sizeof_n(ccrsa_ctx_n(pubkey)) - m_size;
             
             while (prefix_zeros--)
             size_t prefix_zeros = ccn_sizeof_n(ccrsa_ctx_n(pubkey)) - m_size;
             
             while (prefix_zeros--)
-                 *sBytes++ = 0x00;
-
-           size_t pad_size = m_size - plainTextLen;
-
+                *sBytes++ = 0x00;
+            
+            size_t pad_size = m_size - plainTextLen;
+            
             *sBytes++ = 0x00;
             *sBytes++ = RSA_PKCS1_PAD_ENCRYPT;
             *sBytes++ = 0x00;
             *sBytes++ = RSA_PKCS1_PAD_ENCRYPT;
-
+            
             ccrng_generate(ccrng_seckey, pad_size - 3, sBytes);
             // Remove zeroes from the random pad
             ccrng_generate(ccrng_seckey, pad_size - 3, sBytes);
             // Remove zeroes from the random pad
-
+            
             const uint8_t* sEndOfPad = sBytes + (pad_size - 3);
             while (sBytes < sEndOfPad)
             {
                 if (*sBytes == 0x00)
                     *sBytes = 0xFF; // Michael said 0xFF was good enough.
             const uint8_t* sEndOfPad = sBytes + (pad_size - 3);
             while (sBytes < sEndOfPad)
             {
                 if (*sBytes == 0x00)
                     *sBytes = 0xFF; // Michael said 0xFF was good enough.
-
+                
                 ++sBytes;
             }
                 ++sBytes;
             }
-
+            
             *sBytes++ = 0x00;
             *sBytes++ = 0x00;
-
+            
             memcpy(sBytes, plainText, plainTextLen);
             memcpy(sBytes, plainText, plainTextLen);
-
+            
             ccn_swap(ccrsa_ctx_n(pubkey), s);
             break;
         }
         case kSecPaddingOAEP:
         {
             const struct ccdigest_info* di = ccsha1_di();
             ccn_swap(ccrsa_ctx_n(pubkey), s);
             break;
         }
         case kSecPaddingOAEP:
         {
             const struct ccdigest_info* di = ccsha1_di();
-
+            
             const size_t encodingOverhead = 2 + 2 * di->output_size;
             const size_t encodingOverhead = 2 + 2 * di->output_size;
-
+            
             require_action(m_size > encodingOverhead, errOut, result = errSecParam);
             require_action(m_size > encodingOverhead, errOut, result = errSecParam);
-            require_action_quiet(plainTextLen < m_size - encodingOverhead, errOut, result = errSSLCrypto);
-
+            require_action_quiet(plainTextLen <= m_size - encodingOverhead, errOut, result = errSecParam);
+            
             require_noerr_action(ccrsa_oaep_encode(di,
                                                    ccrng_seckey,
                                                    m_size, s,
                                                    plainTextLen, plainText), errOut, result = errSecInternal);
             require_noerr_action(ccrsa_oaep_encode(di,
                                                    ccrng_seckey,
                                                    m_size, s,
                                                    plainTextLen, plainText), errOut, result = errSecInternal);
-           break;
+            break;
         }
         default:
             goto errOut;
     }
         }
         default:
             goto errOut;
     }
-
-
+    
+    
     ccrsa_pub_crypt(pubkey, s, s);
     ccrsa_pub_crypt(pubkey, s, s);
-
+    
     ccn_write_uint_padded(ccrsa_ctx_n(pubkey), s, m_size, cipherText);
     *cipherTextLen = m_size;
     ccn_write_uint_padded(ccrsa_ctx_n(pubkey), s, m_size, cipherText);
     *cipherTextLen = m_size;
-
+    
     result = errSecSuccess;
     result = errSecSuccess;
-
+    
 errOut:
     ccn_zero(ccrsa_ctx_n(pubkey), s);
     return result;
 }
 
 static OSStatus SecRSAPublicKeyRawDecrypt(SecKeyRef key, SecPadding padding,
 errOut:
     ccn_zero(ccrsa_ctx_n(pubkey), s);
     return result;
 }
 
 static OSStatus SecRSAPublicKeyRawDecrypt(SecKeyRef key, SecPadding padding,
-       const uint8_t *cipherText, size_t cipherTextLen, uint8_t *plainText, size_t *plainTextLen) {
+                                          const uint8_t *cipherText, size_t cipherTextLen, uint8_t *plainText, size_t *plainTextLen) {
     OSStatus result = errSSLCrypto;
     OSStatus result = errSSLCrypto;
-
+    
     ccrsa_pub_ctx_t pubkey;
     pubkey.pub = key->key;
     ccrsa_pub_ctx_t pubkey;
     pubkey.pub = key->key;
-
+    
     cc_unit s[ccrsa_ctx_n(pubkey)];
     cc_unit s[ccrsa_ctx_n(pubkey)];
-
+    
     require_action_quiet(cipherText != NULL, errOut, result = errSecParam);
     require_action_quiet(plainText != NULL, errOut, result = errSecParam);
     require_action_quiet(plainTextLen != NULL, errOut, result = errSecParam);
     require_action_quiet(cipherText != NULL, errOut, result = errSecParam);
     require_action_quiet(plainText != NULL, errOut, result = errSecParam);
     require_action_quiet(plainTextLen != NULL, errOut, result = errSecParam);
-
+    
     ccn_read_uint(ccrsa_ctx_n(pubkey), s, cipherTextLen, cipherText);
     ccrsa_pub_crypt(pubkey, s, s);
     ccn_swap(ccrsa_ctx_n(pubkey), s);
     ccn_read_uint(ccrsa_ctx_n(pubkey), s, cipherTextLen, cipherText);
     ccrsa_pub_crypt(pubkey, s, s);
     ccn_swap(ccrsa_ctx_n(pubkey), s);
-
+    
     const uint8_t* sBytes = (uint8_t*) s;
     const uint8_t* sEnd = (uint8_t*) (s + ccrsa_ctx_n(pubkey));
     const uint8_t* sBytes = (uint8_t*) s;
     const uint8_t* sEnd = (uint8_t*) (s + ccrsa_ctx_n(pubkey));
-
+    
     switch (padding) {
         case kSecPaddingNone:
             // Skip leading zeros
     switch (padding) {
         case kSecPaddingNone:
             // Skip leading zeros
@@ -464,7 +467,7 @@ static OSStatus SecRSAPublicKeyRawDecrypt(SecKeyRef key, SecPadding padding,
             while (sBytes < sEnd && *sBytes == 0x00)
                 ++sBytes;
             break;
             while (sBytes < sEnd && *sBytes == 0x00)
                 ++sBytes;
             break;
-
+            
         case kSecPaddingPKCS1:
         {
             // Verify and skip PKCS1 padding:
         case kSecPaddingPKCS1:
         {
             // Verify and skip PKCS1 padding:
@@ -476,19 +479,19 @@ static OSStatus SecRSAPublicKeyRawDecrypt(SecKeyRef key, SecPadding padding,
             
             while (prefix_zeros--)
                 require_quiet(*sBytes++ == 0x00, errOut);
             
             while (prefix_zeros--)
                 require_quiet(*sBytes++ == 0x00, errOut);
-
+            
             require_quiet(*sBytes++ == 0x00, errOut);
             require_quiet(*sBytes++ == RSA_PKCS1_PAD_ENCRYPT, errOut);
             require_quiet(*sBytes++ == 0x00, errOut);
             require_quiet(*sBytes++ == RSA_PKCS1_PAD_ENCRYPT, errOut);
-
+            
             while (*sBytes != 0x00) {
                 require_quiet(++sBytes < sEnd, errOut);
             }
             // Required to have at least 8 0xFFs
             require_quiet((sBytes - (uint8_t*)s) - 2 >= 8, errOut);
             while (*sBytes != 0x00) {
                 require_quiet(++sBytes < sEnd, errOut);
             }
             // Required to have at least 8 0xFFs
             require_quiet((sBytes - (uint8_t*)s) - 2 >= 8, errOut);
-
+            
             require_quiet(*sBytes == 0x00, errOut);
             require_quiet(++sBytes < sEnd, errOut);
             require_quiet(*sBytes == 0x00, errOut);
             require_quiet(++sBytes < sEnd, errOut);
-
+            
             break;
         }
         case kSecPaddingOAEP:
             break;
         }
         case kSecPaddingOAEP:
@@ -496,25 +499,25 @@ static OSStatus SecRSAPublicKeyRawDecrypt(SecKeyRef key, SecPadding padding,
         default:
             goto errOut;
     }
         default:
             goto errOut;
     }
-
+    
     // Return the rest.
     require_action((sEnd - sBytes) <= (ptrdiff_t)*plainTextLen, errOut, result = errSecParam);
     // Return the rest.
     require_action((sEnd - sBytes) <= (ptrdiff_t)*plainTextLen, errOut, result = errSecParam);
-
+    
     *plainTextLen = sEnd - sBytes;
     memcpy(plainText, sBytes, *plainTextLen);
     *plainTextLen = sEnd - sBytes;
     memcpy(plainText, sBytes, *plainTextLen);
-
+    
     result = errSecSuccess;
     result = errSecSuccess;
-
+    
 errOut:
     ccn_zero(ccrsa_ctx_n(pubkey), s);
 errOut:
     ccn_zero(ccrsa_ctx_n(pubkey), s);
-
+    
     return result;
 }
 
 static size_t SecRSAPublicKeyBlockSize(SecKeyRef key) {
     ccrsa_pub_ctx_t pubkey;
     pubkey.pub = key->key;
     return result;
 }
 
 static size_t SecRSAPublicKeyBlockSize(SecKeyRef key) {
     ccrsa_pub_ctx_t pubkey;
     pubkey.pub = key->key;
-
+    
     return ccn_write_uint_size(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey));
 }
 
     return ccn_write_uint_size(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey));
 }
 
@@ -523,30 +526,30 @@ static CFDataRef SecRSAPublicKeyCreatePKCS1(CFAllocatorRef allocator, ccrsa_pub_
 {
     size_t m_size = ccn_write_int_size(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey));
     size_t e_size = ccn_write_int_size(ccrsa_ctx_n(pubkey), ccrsa_ctx_e(pubkey));
 {
     size_t m_size = ccn_write_int_size(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey));
     size_t e_size = ccn_write_int_size(ccrsa_ctx_n(pubkey), ccrsa_ctx_e(pubkey));
-
+    
     const size_t seq_size = DERLengthOfItem(ASN1_INTEGER, m_size) +
     const size_t seq_size = DERLengthOfItem(ASN1_INTEGER, m_size) +
-                            DERLengthOfItem(ASN1_INTEGER, e_size);
-
+    DERLengthOfItem(ASN1_INTEGER, e_size);
+    
     const size_t result_size = DERLengthOfItem(ASN1_SEQUENCE, seq_size);
     const size_t result_size = DERLengthOfItem(ASN1_SEQUENCE, seq_size);
-
+    
        CFMutableDataRef pkcs1 = CFDataCreateMutable(allocator, result_size);
        CFMutableDataRef pkcs1 = CFDataCreateMutable(allocator, result_size);
-
+    
     if (pkcs1 == NULL)
         return NULL;
     if (pkcs1 == NULL)
         return NULL;
-
+    
        CFDataSetLength(pkcs1, result_size);
        CFDataSetLength(pkcs1, result_size);
-
+    
     uint8_t *bytes = CFDataGetMutableBytePtr(pkcs1);
     uint8_t *bytes = CFDataGetMutableBytePtr(pkcs1);
-
+    
     *bytes++ = ASN1_CONSTR_SEQUENCE;
     *bytes++ = ASN1_CONSTR_SEQUENCE;
-
+    
     DERSize itemLength = 4;
     DEREncodeLength(seq_size, bytes, &itemLength);
     bytes += itemLength;
     DERSize itemLength = 4;
     DEREncodeLength(seq_size, bytes, &itemLength);
     bytes += itemLength;
-
+    
     ccasn_encode_int(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey), m_size, &bytes);
     ccasn_encode_int(ccrsa_ctx_n(pubkey), ccrsa_ctx_e(pubkey), e_size, &bytes);
     ccasn_encode_int(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey), m_size, &bytes);
     ccasn_encode_int(ccrsa_ctx_n(pubkey), ccrsa_ctx_e(pubkey), e_size, &bytes);
-
+    
     return pkcs1;
 }
 
     return pkcs1;
 }
 
@@ -554,10 +557,10 @@ static OSStatus SecRSAPublicKeyCopyPublicSerialization(SecKeyRef key, CFDataRef*
 {
     ccrsa_pub_ctx_t pubkey;
     pubkey.pub = key->key;
 {
     ccrsa_pub_ctx_t pubkey;
     pubkey.pub = key->key;
-
+    
        CFAllocatorRef allocator = CFGetAllocator(key);
     *serialized = SecRSAPublicKeyCreatePKCS1(allocator, pubkey);
        CFAllocatorRef allocator = CFGetAllocator(key);
     *serialized = SecRSAPublicKeyCreatePKCS1(allocator, pubkey);
-
+    
     if (NULL == *serialized)
         return errSecDecode;
     else
     if (NULL == *serialized)
         return errSecDecode;
     else
@@ -568,6 +571,28 @@ static CFDictionaryRef SecRSAPublicKeyCopyAttributeDictionary(SecKeyRef key) {
     return SecKeyGeneratePublicAttributeDictionary(key, kSecAttrKeyTypeRSA);
 }
 
     return SecKeyGeneratePublicAttributeDictionary(key, kSecAttrKeyTypeRSA);
 }
 
+static CFStringRef SecRSAPublicKeyCopyDescription(SecKeyRef key) {
+    
+    CFStringRef keyDescription = NULL;
+    CFDataRef modRef = SecKeyCopyModulus(key);
+    
+    ccrsa_pub_ctx_t pubkey;
+    pubkey.pub = key->key;
+    
+    CFStringRef modulusString = CFDataCopyHexString(modRef);
+    require( modulusString, fail);
+    
+    keyDescription = CFStringCreateWithFormat(kCFAllocatorDefault,NULL,CFSTR( "<SecKeyRef algorithm id: %lu, key type: %s, version: %d, block size: %zu bits, exponent: {hex: %llx, decimal: %lld}, modulus: %@, addr: %p>"), SecKeyGetAlgorithmID(key), key->key_class->name, key->key_class->version, (8*SecKeyGetBlockSize(key)), (long long)*ccrsa_ctx_e(pubkey), (long long)*ccrsa_ctx_e(pubkey), modulusString, key);
+    
+fail:
+    CFReleaseSafe(modRef);
+    CFReleaseSafe(modulusString);
+       if(!keyDescription)
+               keyDescription = CFStringCreateWithFormat(kCFAllocatorDefault,NULL,CFSTR("<SecKeyRef algorithm id: %lu, key type: %s, version: %d, block size: %zu bits, addr: %p>"), (long)SecKeyGetAlgorithmID(key), key->key_class->name, key->key_class->version, (8*SecKeyGetBlockSize(key)), key);
+       
+       return keyDescription;
+}
+
 SecKeyDescriptor kSecRSAPublicKeyDescriptor = {
     kSecKeyDescriptorVersion,
     "RSAPublicKey",
 SecKeyDescriptor kSecRSAPublicKeyDescriptor = {
     kSecKeyDescriptorVersion,
     "RSAPublicKey",
@@ -581,53 +606,54 @@ SecKeyDescriptor kSecRSAPublicKeyDescriptor = {
     NULL, /* SecKeyComputeMethod */
     SecRSAPublicKeyBlockSize,
        SecRSAPublicKeyCopyAttributeDictionary,
     NULL, /* SecKeyComputeMethod */
     SecRSAPublicKeyBlockSize,
        SecRSAPublicKeyCopyAttributeDictionary,
+    SecRSAPublicKeyCopyDescription,
     NULL,
     SecRSAPublicKeyCopyPublicSerialization,
 };
 
 /* Public Key API functions. */
 SecKeyRef SecKeyCreateRSAPublicKey(CFAllocatorRef allocator,
     NULL,
     SecRSAPublicKeyCopyPublicSerialization,
 };
 
 /* Public Key API functions. */
 SecKeyRef SecKeyCreateRSAPublicKey(CFAllocatorRef allocator,
-    const uint8_t *keyData, CFIndex keyDataLength,
-    SecKeyEncoding encoding) {
+                                   const uint8_t *keyData, CFIndex keyDataLength,
+                                   SecKeyEncoding encoding) {
     return SecKeyCreate(allocator, &kSecRSAPublicKeyDescriptor, keyData,
     return SecKeyCreate(allocator, &kSecRSAPublicKeyDescriptor, keyData,
-        keyDataLength, encoding);
+                        keyDataLength, encoding);
 }
 
 CFDataRef SecKeyCopyModulus(SecKeyRef key) {
     ccrsa_pub_ctx_t pubkey;
     pubkey.pub = key->key;
 }
 
 CFDataRef SecKeyCopyModulus(SecKeyRef key) {
     ccrsa_pub_ctx_t pubkey;
     pubkey.pub = key->key;
-
+    
     size_t m_size = ccn_write_uint_size(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey));
     size_t m_size = ccn_write_uint_size(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey));
-
+    
        CFAllocatorRef allocator = CFGetAllocator(key);
        CFMutableDataRef modulusData = CFDataCreateMutable(allocator, m_size);
        CFAllocatorRef allocator = CFGetAllocator(key);
        CFMutableDataRef modulusData = CFDataCreateMutable(allocator, m_size);
-
+    
     if (modulusData == NULL)
         return NULL;
     if (modulusData == NULL)
         return NULL;
-
+    
        CFDataSetLength(modulusData, m_size);
        CFDataSetLength(modulusData, m_size);
-
+    
     ccn_write_uint(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey), m_size, CFDataGetMutableBytePtr(modulusData));
     ccn_write_uint(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey), m_size, CFDataGetMutableBytePtr(modulusData));
-
+    
     return modulusData;
 }
 
 CFDataRef SecKeyCopyExponent(SecKeyRef key) {
     ccrsa_pub_ctx_t pubkey;
     pubkey.pub = key->key;
     return modulusData;
 }
 
 CFDataRef SecKeyCopyExponent(SecKeyRef key) {
     ccrsa_pub_ctx_t pubkey;
     pubkey.pub = key->key;
-
+    
     size_t e_size = ccn_write_uint_size(ccrsa_ctx_n(pubkey), ccrsa_ctx_e(pubkey));
     size_t e_size = ccn_write_uint_size(ccrsa_ctx_n(pubkey), ccrsa_ctx_e(pubkey));
-
+    
        CFAllocatorRef allocator = CFGetAllocator(key);
        CFMutableDataRef exponentData = CFDataCreateMutable(allocator, e_size);
        CFAllocatorRef allocator = CFGetAllocator(key);
        CFMutableDataRef exponentData = CFDataCreateMutable(allocator, e_size);
-
+    
     if (exponentData == NULL)
         return NULL;
     if (exponentData == NULL)
         return NULL;
-
+    
        CFDataSetLength(exponentData, e_size);
        CFDataSetLength(exponentData, e_size);
-
+    
     ccn_write_uint(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey), e_size, CFDataGetMutableBytePtr(exponentData));
     ccn_write_uint(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey), e_size, CFDataGetMutableBytePtr(exponentData));
-
+    
     return exponentData;
 }
 
     return exponentData;
 }
 
@@ -654,10 +680,10 @@ static int ccrsa_priv_init(ccrsa_priv_ctx_t privkey,
                            size_t qinv_size, const uint8_t* qinv)
 {
     int result = -1;
                            size_t qinv_size, const uint8_t* qinv)
 {
     int result = -1;
-
+    
     const cc_size np = cczp_n(ccrsa_ctx_private_zp(privkey));
     cc_size nq = cczp_n(ccrsa_ctx_private_zq(privkey));
     const cc_size np = cczp_n(ccrsa_ctx_private_zp(privkey));
     cc_size nq = cczp_n(ccrsa_ctx_private_zq(privkey));
-
+    
     if (ccn_read_uint(np, CCZP_PRIME(ccrsa_ctx_private_zp(privkey)), p_size, p))
         goto errOut;
     cczp_init(ccrsa_ctx_private_zp(privkey));
     if (ccn_read_uint(np, CCZP_PRIME(ccrsa_ctx_private_zp(privkey)), p_size, p))
         goto errOut;
     cczp_init(ccrsa_ctx_private_zp(privkey));
@@ -665,19 +691,19 @@ static int ccrsa_priv_init(ccrsa_priv_ctx_t privkey,
         goto errOut;
     if (ccn_read_uint(np, ccrsa_ctx_private_qinv(privkey), qinv_size, qinv))
         goto errOut;
         goto errOut;
     if (ccn_read_uint(np, ccrsa_ctx_private_qinv(privkey), qinv_size, qinv))
         goto errOut;
-
+    
     if (ccn_read_uint(nq, CCZP_PRIME(ccrsa_ctx_private_zq(privkey)), q_size, q))
         goto errOut;
     if (ccn_read_uint(nq, CCZP_PRIME(ccrsa_ctx_private_zq(privkey)), q_size, q))
         goto errOut;
-
+    
     nq = ccn_n(nq, cczp_prime(ccrsa_ctx_private_zq(privkey)));
     CCZP_N(ccrsa_ctx_private_zq(privkey)) = nq;
     nq = ccn_n(nq, cczp_prime(ccrsa_ctx_private_zq(privkey)));
     CCZP_N(ccrsa_ctx_private_zq(privkey)) = nq;
-
+    
     cczp_init(ccrsa_ctx_private_zq(privkey));
     if (ccn_read_uint(nq, ccrsa_ctx_private_dq(privkey), dq_size, dq))
         goto errOut;
     cczp_init(ccrsa_ctx_private_zq(privkey));
     if (ccn_read_uint(nq, ccrsa_ctx_private_dq(privkey), dq_size, dq))
         goto errOut;
-
+    
     result = 0;
     result = 0;
-
+    
 errOut:
     return result;
 }
 errOut:
     return result;
 }
@@ -686,15 +712,15 @@ errOut:
 static OSStatus ccrsa_full_decode(ccrsa_full_ctx_t fullkey, size_t pkcs1_size, const uint8_t* pkcs1)
 {
     OSStatus result = errSecParam;
 static OSStatus ccrsa_full_decode(ccrsa_full_ctx_t fullkey, size_t pkcs1_size, const uint8_t* pkcs1)
 {
     OSStatus result = errSecParam;
-
+    
        DERItem keyItem = {(DERByte *)pkcs1, pkcs1_size};
     DERRSAKeyPair decodedKey;
        DERItem keyItem = {(DERByte *)pkcs1, pkcs1_size};
     DERRSAKeyPair decodedKey;
-
+    
        require_noerr_action(DERParseSequence(&keyItem,
                                           DERNumRSAKeyPairItemSpecs, DERRSAKeyPairItemSpecs,
                                           &decodedKey, sizeof(decodedKey)),
                          errOut, result = errSecDecode);
        require_noerr_action(DERParseSequence(&keyItem,
                                           DERNumRSAKeyPairItemSpecs, DERRSAKeyPairItemSpecs,
                                           &decodedKey, sizeof(decodedKey)),
                          errOut, result = errSecDecode);
-
+    
     require_noerr(ccrsa_pub_init(fullkey,
                                  decodedKey.n.length, decodedKey.n.data,
                                  decodedKey.e.length, decodedKey.e.data),
     require_noerr(ccrsa_pub_init(fullkey,
                                  decodedKey.n.length, decodedKey.n.data,
                                  decodedKey.e.length, decodedKey.e.data),
@@ -705,34 +731,34 @@ static OSStatus ccrsa_full_decode(ccrsa_full_ctx_t fullkey, size_t pkcs1_size, c
         ccrsa_priv_ctx_t privkey = ccrsa_ctx_private(fullkey);
         CCZP_N(ccrsa_ctx_private_zp(privkey)) = ccn_nof((ccn_bitsof_n(ccrsa_ctx_n(fullkey)) / 2) + 1);
         CCZP_N(ccrsa_ctx_private_zq(privkey)) = cczp_n(ccrsa_ctx_private_zp(privkey));
         ccrsa_priv_ctx_t privkey = ccrsa_ctx_private(fullkey);
         CCZP_N(ccrsa_ctx_private_zp(privkey)) = ccn_nof((ccn_bitsof_n(ccrsa_ctx_n(fullkey)) / 2) + 1);
         CCZP_N(ccrsa_ctx_private_zq(privkey)) = cczp_n(ccrsa_ctx_private_zp(privkey));
-
+        
         // TODO: Actually remember decodedKey.d.
         // TODO: Actually remember decodedKey.d.
-
+        
         require_noerr(ccrsa_priv_init(privkey,
         require_noerr(ccrsa_priv_init(privkey,
-                                     decodedKey.p.length, decodedKey.p.data,
+                                      decodedKey.p.length, decodedKey.p.data,
                                       decodedKey.q.length, decodedKey.q.data,
                                       decodedKey.dp.length, decodedKey.dp.data,
                                       decodedKey.dq.length, decodedKey.dq.data,
                                       decodedKey.qInv.length, decodedKey.qInv.data),
                       errOut);
     }
                                       decodedKey.q.length, decodedKey.q.data,
                                       decodedKey.dp.length, decodedKey.dp.data,
                                       decodedKey.dq.length, decodedKey.dq.data,
                                       decodedKey.qInv.length, decodedKey.qInv.data),
                       errOut);
     }
-
+    
     result = errSecSuccess;
     result = errSecSuccess;
-
+    
 errOut:
     return result;
 }
 
 static OSStatus SecRSAPrivateKeyInit(SecKeyRef key,
 errOut:
     return result;
 }
 
 static OSStatus SecRSAPrivateKeyInit(SecKeyRef key,
-    const uint8_t *keyData, CFIndex keyDataLength, SecKeyEncoding encoding) {
+                                     const uint8_t *keyData, CFIndex keyDataLength, SecKeyEncoding encoding) {
     OSStatus result = errSecParam;
     OSStatus result = errSecParam;
-
+    
     ccrsa_full_ctx_t fullkey;
     fullkey.full = key->key;
     ccrsa_full_ctx_t fullkey;
     fullkey.full = key->key;
-
+    
     // Set maximum size for parsers
     ccrsa_ctx_n(fullkey) = ccn_nof(kMaximumRSAKeyBits);
     // Set maximum size for parsers
     ccrsa_ctx_n(fullkey) = ccn_nof(kMaximumRSAKeyBits);
-
+    
     switch (encoding) {
         case kSecKeyEncodingBytes: // Octets is PKCS1
         case kSecKeyEncodingPkcs1:
     switch (encoding) {
         case kSecKeyEncodingBytes: // Octets is PKCS1
         case kSecKeyEncodingPkcs1:
@@ -741,15 +767,15 @@ static OSStatus SecRSAPrivateKeyInit(SecKeyRef key,
         case kSecGenerateKey:
         {
             CFDictionaryRef parameters = (CFDictionaryRef) keyData;
         case kSecGenerateKey:
         {
             CFDictionaryRef parameters = (CFDictionaryRef) keyData;
-
+            
             CFTypeRef ksize = CFDictionaryGetValue(parameters, kSecAttrKeySizeInBits);
             CFIndex keyLengthInBits = getIntValue(ksize);
             CFTypeRef ksize = CFDictionaryGetValue(parameters, kSecAttrKeySizeInBits);
             CFIndex keyLengthInBits = getIntValue(ksize);
-
+            
             if (keyLengthInBits < 256 || keyLengthInBits > kMaximumRSAKeyBits) {
                 secwarning("Invalid or missing key size in: %@", parameters);
                 return errSecKeySizeNotAllowed;
             }
             if (keyLengthInBits < 256 || keyLengthInBits > kMaximumRSAKeyBits) {
                 secwarning("Invalid or missing key size in: %@", parameters);
                 return errSecKeySizeNotAllowed;
             }
-
+            
             /* TODO: Add support for kSecPublicExponent parameter. */
             static uint8_t e[] = { 0x01, 0x00, 0x01 }; // Default is 65537
             if (!ccrsa_generate_key(keyLengthInBits, fullkey.full, sizeof(e), e, ccrng_seckey))
             /* TODO: Add support for kSecPublicExponent parameter. */
             static uint8_t e[] = { 0x01, 0x00, 0x01 }; // Default is 65537
             if (!ccrsa_generate_key(keyLengthInBits, fullkey.full, sizeof(e), e, ccrng_seckey))
@@ -759,33 +785,35 @@ static OSStatus SecRSAPrivateKeyInit(SecKeyRef key,
         default:
             break;
     }
         default:
             break;
     }
-
+    
     return result;
 }
 
 static OSStatus SecRSAPrivateKeyRawSign(SecKeyRef key, SecPadding padding,
     return result;
 }
 
 static OSStatus SecRSAPrivateKeyRawSign(SecKeyRef key, SecPadding padding,
-    const uint8_t *dataToSign, size_t dataToSignLen,
-    uint8_t *sig, size_t *sigLen) {
-
+                                        const uint8_t *dataToSign, size_t dataToSignLen,
+                                        uint8_t *sig, size_t *sigLen) {
+    
     OSStatus result = errSecParam;
     OSStatus result = errSecParam;
-
+    
     ccrsa_full_ctx_t fullkey;
     fullkey.full = key->key;
     ccrsa_full_ctx_t fullkey;
     fullkey.full = key->key;
-
+    
     size_t m_size = ccn_write_uint_size(ccrsa_ctx_n(fullkey), ccrsa_ctx_m(fullkey));
     cc_unit s[ccrsa_ctx_n(fullkey)];
     size_t m_size = ccn_write_uint_size(ccrsa_ctx_n(fullkey), ccrsa_ctx_m(fullkey));
     cc_unit s[ccrsa_ctx_n(fullkey)];
-
+    
     uint8_t* sBytes = (uint8_t*) s;
     uint8_t* sBytes = (uint8_t*) s;
-
+    
     require(sigLen, errOut);
     require(*sigLen >= m_size, errOut);
     require(sigLen, errOut);
     require(*sigLen >= m_size, errOut);
-
+    
     switch (padding) {
         case kSecPaddingNone:
     switch (padding) {
         case kSecPaddingNone:
+            // We'll allow modulus size assuming input is smaller than modulus
+            require_quiet(dataToSignLen <= m_size, errOut);
             require_noerr_quiet(ccn_read_uint(ccrsa_ctx_n(fullkey), s, dataToSignLen, dataToSign), errOut);
             require_quiet(ccn_cmp(ccrsa_ctx_n(fullkey), s, ccrsa_ctx_m(fullkey)) < 0, errOut);
             break;
             require_noerr_quiet(ccn_read_uint(ccrsa_ctx_n(fullkey), s, dataToSignLen, dataToSign), errOut);
             require_quiet(ccn_cmp(ccrsa_ctx_n(fullkey), s, ccrsa_ctx_m(fullkey)) < 0, errOut);
             break;
-
+            
         case kSecPaddingPKCS1:
         {
             // Create PKCS1 padding:
         case kSecPaddingPKCS1:
         {
             // Create PKCS1 padding:
@@ -793,29 +821,29 @@ static OSStatus SecRSAPrivateKeyRawSign(SecKeyRef key, SecPadding padding,
             // 0x00, 0x01 (RSA_PKCS1_PAD_SIGN), 0xFF .. 0x00, signedData
             //
             const int kMinimumPadding = 1 + 1 + 8 + 1;
             // 0x00, 0x01 (RSA_PKCS1_PAD_SIGN), 0xFF .. 0x00, signedData
             //
             const int kMinimumPadding = 1 + 1 + 8 + 1;
-
-            require(dataToSignLen < m_size - kMinimumPadding, errOut);
-
+            
+            require_quiet(dataToSignLen <= m_size - kMinimumPadding, errOut);
+            
             size_t prefix_zeros = ccn_sizeof_n(ccrsa_ctx_n(fullkey)) - m_size;
             
             while (prefix_zeros--)
                 *sBytes++ = 0x00;
             
             size_t pad_size = m_size - dataToSignLen;
             size_t prefix_zeros = ccn_sizeof_n(ccrsa_ctx_n(fullkey)) - m_size;
             
             while (prefix_zeros--)
                 *sBytes++ = 0x00;
             
             size_t pad_size = m_size - dataToSignLen;
-
+            
             *sBytes++ = 0x00;
             *sBytes++ = RSA_PKCS1_PAD_SIGN;
             *sBytes++ = 0x00;
             *sBytes++ = RSA_PKCS1_PAD_SIGN;
-
+            
             size_t ff_size;
             for(ff_size = pad_size - 3; ff_size > 0; --ff_size)
                 *sBytes++ = 0xFF;
             size_t ff_size;
             for(ff_size = pad_size - 3; ff_size > 0; --ff_size)
                 *sBytes++ = 0xFF;
-
+            
             *sBytes++ = 0x00;
             *sBytes++ = 0x00;
-
+            
             // Get the user data into s looking like a ccn.
             memcpy(sBytes, dataToSign, dataToSignLen);
             ccn_swap(ccrsa_ctx_n(fullkey), s);
             // Get the user data into s looking like a ccn.
             memcpy(sBytes, dataToSign, dataToSignLen);
             ccn_swap(ccrsa_ctx_n(fullkey), s);
-
+            
             break;
         }
         case kSecPaddingOAEP:
             break;
         }
         case kSecPaddingOAEP:
@@ -823,41 +851,41 @@ static OSStatus SecRSAPrivateKeyRawSign(SecKeyRef key, SecPadding padding,
         default:
             goto errOut;
     }
         default:
             goto errOut;
     }
-
+    
     ccrsa_priv_crypt(ccrsa_ctx_private(fullkey), s, s);
     ccrsa_priv_crypt(ccrsa_ctx_private(fullkey), s, s);
-
+    
     // Pad with leading zeros to fit in modulus size
     ccn_write_uint_padded(ccrsa_ctx_n(fullkey), s, m_size, sig);
     *sigLen = m_size;
     // Pad with leading zeros to fit in modulus size
     ccn_write_uint_padded(ccrsa_ctx_n(fullkey), s, m_size, sig);
     *sigLen = m_size;
-
+    
     result = errSecSuccess;
     result = errSecSuccess;
-
+    
 errOut:
     ccn_zero(ccrsa_ctx_n(fullkey), s);
     return result;
 }
 
 static OSStatus SecRSAPrivateKeyRawDecrypt(SecKeyRef key, SecPadding padding,
 errOut:
     ccn_zero(ccrsa_ctx_n(fullkey), s);
     return result;
 }
 
 static OSStatus SecRSAPrivateKeyRawDecrypt(SecKeyRef key, SecPadding padding,
-       const uint8_t *cipherText, size_t cipherTextLen,
-       uint8_t *plainText, size_t *plainTextLen) {
+                                           const uint8_t *cipherText, size_t cipherTextLen,
+                                           uint8_t *plainText, size_t *plainTextLen) {
     OSStatus result = errSSLCrypto;
     OSStatus result = errSSLCrypto;
-
+    
     ccrsa_full_ctx_t fullkey;
     fullkey.full = key->key;
     ccrsa_full_ctx_t fullkey;
     fullkey.full = key->key;
-
+    
     size_t m_size = ccn_write_uint_size(ccrsa_ctx_n(fullkey), ccrsa_ctx_m(fullkey));
     size_t m_size = ccn_write_uint_size(ccrsa_ctx_n(fullkey), ccrsa_ctx_m(fullkey));
-
+    
     cc_unit s[ccrsa_ctx_n(fullkey)];
     uint8_t recoveredData[ccn_sizeof_n(ccrsa_ctx_n(fullkey))];
     cc_unit s[ccrsa_ctx_n(fullkey)];
     uint8_t recoveredData[ccn_sizeof_n(ccrsa_ctx_n(fullkey))];
-
+    
     ccn_read_uint(ccrsa_ctx_n(fullkey), s, cipherTextLen, cipherText);
     ccrsa_priv_crypt(ccrsa_ctx_private(fullkey), s, s);
     ccn_read_uint(ccrsa_ctx_n(fullkey), s, cipherTextLen, cipherText);
     ccrsa_priv_crypt(ccrsa_ctx_private(fullkey), s, s);
-
+    
     const uint8_t* sBytes = (uint8_t*) s;
     const uint8_t* sEnd = (uint8_t*) (s + ccrsa_ctx_n(fullkey));
     const uint8_t* sBytes = (uint8_t*) s;
     const uint8_t* sEnd = (uint8_t*) (s + ccrsa_ctx_n(fullkey));
-
+    
     require(plainTextLen, errOut);
     require(plainTextLen, errOut);
-
+    
     switch (padding) {
         case kSecPaddingNone:
             ccn_swap(ccrsa_ctx_n(fullkey), s);
     switch (padding) {
         case kSecPaddingNone:
             ccn_swap(ccrsa_ctx_n(fullkey), s);
@@ -865,7 +893,7 @@ static OSStatus SecRSAPrivateKeyRawDecrypt(SecKeyRef key, SecPadding padding,
             while (sBytes < sEnd && *sBytes == 0x00)
                 ++sBytes;
             break;
             while (sBytes < sEnd && *sBytes == 0x00)
                 ++sBytes;
             break;
-
+            
         case kSecPaddingPKCS1:
         {
             ccn_swap(ccrsa_ctx_n(fullkey), s);
         case kSecPaddingPKCS1:
         {
             ccn_swap(ccrsa_ctx_n(fullkey), s);
@@ -881,13 +909,13 @@ static OSStatus SecRSAPrivateKeyRawDecrypt(SecKeyRef key, SecPadding padding,
             
             require_quiet(*sBytes++ == 0x00, errOut);
             require_quiet(*sBytes++ == RSA_PKCS1_PAD_ENCRYPT, errOut);
             
             require_quiet(*sBytes++ == 0x00, errOut);
             require_quiet(*sBytes++ == RSA_PKCS1_PAD_ENCRYPT, errOut);
-
+            
             while (*sBytes != 0x00) {
                 require_quiet(++sBytes < sEnd, errOut);
             }
             // Required to have at least 8 non-zeros
             require_quiet((sBytes - (uint8_t*)s) - 2 >= 8, errOut);
             while (*sBytes != 0x00) {
                 require_quiet(++sBytes < sEnd, errOut);
             }
             // Required to have at least 8 non-zeros
             require_quiet((sBytes - (uint8_t*)s) - 2 >= 8, errOut);
-
+            
             require_quiet(*sBytes == 0x00, errOut);
             require_quiet(++sBytes < sEnd, errOut);
             break;
             require_quiet(*sBytes == 0x00, errOut);
             require_quiet(++sBytes < sEnd, errOut);
             break;
@@ -895,11 +923,12 @@ static OSStatus SecRSAPrivateKeyRawDecrypt(SecKeyRef key, SecPadding padding,
         case kSecPaddingOAEP:
         {
             size_t length = sizeof(recoveredData);
         case kSecPaddingOAEP:
         {
             size_t length = sizeof(recoveredData);
-
+            
             require_noerr_quiet(ccrsa_oaep_decode(ccsha1_di(),
             require_noerr_quiet(ccrsa_oaep_decode(ccsha1_di(),
-                                                  ccn_write_uint_size(ccrsa_ctx_n(fullkey),ccrsa_ctx_m(fullkey)), s,
-                                                  &length, recoveredData), errOut);
-
+                                                                                                 &length, recoveredData,
+                                                  ccn_write_uint_size(ccrsa_ctx_n(fullkey),ccrsa_ctx_m(fullkey)), s
+                                                  ), errOut);
+            
             sBytes = recoveredData;
             sEnd = recoveredData + length;
             break;
             sBytes = recoveredData;
             sEnd = recoveredData + length;
             break;
@@ -907,87 +936,87 @@ static OSStatus SecRSAPrivateKeyRawDecrypt(SecKeyRef key, SecPadding padding,
         default:
             goto errOut;
     }
         default:
             goto errOut;
     }
-
+    
     require((sEnd - sBytes) <= (ptrdiff_t)*plainTextLen, errOut);
     *plainTextLen = sEnd - sBytes;
     memcpy(plainText, sBytes, *plainTextLen);
     require((sEnd - sBytes) <= (ptrdiff_t)*plainTextLen, errOut);
     *plainTextLen = sEnd - sBytes;
     memcpy(plainText, sBytes, *plainTextLen);
-
+    
     result = errSecSuccess;
     result = errSecSuccess;
-
+    
 errOut:
     bzero(recoveredData, sizeof(recoveredData));
     ccn_zero(ccrsa_ctx_n(fullkey), s);
 errOut:
     bzero(recoveredData, sizeof(recoveredData));
     ccn_zero(ccrsa_ctx_n(fullkey), s);
-
+    
     return result;
 }
 
 static size_t SecRSAPrivateKeyBlockSize(SecKeyRef key) {
     ccrsa_full_ctx_t fullkey;
     fullkey.full = key->key;
     return result;
 }
 
 static size_t SecRSAPrivateKeyBlockSize(SecKeyRef key) {
     ccrsa_full_ctx_t fullkey;
     fullkey.full = key->key;
-
+    
     return ccn_write_uint_size(ccrsa_ctx_n(fullkey), ccrsa_ctx_m(fullkey));
 }
 
 static CFDataRef SecRSAPrivateKeyCreatePKCS1(CFAllocatorRef allocator, ccrsa_full_ctx_t fullkey)
 {
     ccrsa_priv_ctx_t privkey = ccrsa_ctx_private(fullkey);
     return ccn_write_uint_size(ccrsa_ctx_n(fullkey), ccrsa_ctx_m(fullkey));
 }
 
 static CFDataRef SecRSAPrivateKeyCreatePKCS1(CFAllocatorRef allocator, ccrsa_full_ctx_t fullkey)
 {
     ccrsa_priv_ctx_t privkey = ccrsa_ctx_private(fullkey);
-
+    
     const cc_size np = cczp_n(ccrsa_ctx_private_zp(privkey));
     const cc_size nq = cczp_n(ccrsa_ctx_private_zq(privkey));
     const cc_size np = cczp_n(ccrsa_ctx_private_zp(privkey));
     const cc_size nq = cczp_n(ccrsa_ctx_private_zq(privkey));
-
+    
     size_t m_size = ccn_write_int_size(ccrsa_ctx_n(fullkey), ccrsa_ctx_m(fullkey));
     size_t e_size = ccn_write_int_size(ccrsa_ctx_n(fullkey), ccrsa_ctx_e(fullkey));
     size_t d_size = ccn_write_int_size(ccrsa_ctx_n(fullkey), ccrsa_ctx_d(fullkey));
     size_t m_size = ccn_write_int_size(ccrsa_ctx_n(fullkey), ccrsa_ctx_m(fullkey));
     size_t e_size = ccn_write_int_size(ccrsa_ctx_n(fullkey), ccrsa_ctx_e(fullkey));
     size_t d_size = ccn_write_int_size(ccrsa_ctx_n(fullkey), ccrsa_ctx_d(fullkey));
-
+    
     size_t p_size = ccn_write_int_size(np, cczp_prime(ccrsa_ctx_private_zp(privkey)));
     size_t q_size = ccn_write_int_size(nq, cczp_prime(ccrsa_ctx_private_zq(privkey)));
     size_t p_size = ccn_write_int_size(np, cczp_prime(ccrsa_ctx_private_zp(privkey)));
     size_t q_size = ccn_write_int_size(nq, cczp_prime(ccrsa_ctx_private_zq(privkey)));
-
+    
     size_t dp_size = ccn_write_int_size(np, ccrsa_ctx_private_dp(privkey));
     size_t dq_size = ccn_write_int_size(nq, ccrsa_ctx_private_dq(privkey));
     size_t dp_size = ccn_write_int_size(np, ccrsa_ctx_private_dp(privkey));
     size_t dq_size = ccn_write_int_size(nq, ccrsa_ctx_private_dq(privkey));
-
+    
     size_t qinv_size = ccn_write_int_size(np, ccrsa_ctx_private_qinv(privkey));
     size_t qinv_size = ccn_write_int_size(np, ccrsa_ctx_private_qinv(privkey));
-
+    
     const size_t seq_size = 3 +
     const size_t seq_size = 3 +
-                            DERLengthOfItem(ASN1_INTEGER, m_size) +
-                            DERLengthOfItem(ASN1_INTEGER, e_size) +
-                            DERLengthOfItem(ASN1_INTEGER, d_size) +
-                            DERLengthOfItem(ASN1_INTEGER, p_size) +
-                            DERLengthOfItem(ASN1_INTEGER, q_size) +
-                            DERLengthOfItem(ASN1_INTEGER, dp_size) +
-                            DERLengthOfItem(ASN1_INTEGER, dq_size) +
-                            DERLengthOfItem(ASN1_INTEGER, qinv_size);
-
+    DERLengthOfItem(ASN1_INTEGER, m_size) +
+    DERLengthOfItem(ASN1_INTEGER, e_size) +
+    DERLengthOfItem(ASN1_INTEGER, d_size) +
+    DERLengthOfItem(ASN1_INTEGER, p_size) +
+    DERLengthOfItem(ASN1_INTEGER, q_size) +
+    DERLengthOfItem(ASN1_INTEGER, dp_size) +
+    DERLengthOfItem(ASN1_INTEGER, dq_size) +
+    DERLengthOfItem(ASN1_INTEGER, qinv_size);
+    
     const size_t result_size = DERLengthOfItem(ASN1_SEQUENCE, seq_size);
     const size_t result_size = DERLengthOfItem(ASN1_SEQUENCE, seq_size);
-
+    
        CFMutableDataRef pkcs1 = CFDataCreateMutable(allocator, result_size);
        CFMutableDataRef pkcs1 = CFDataCreateMutable(allocator, result_size);
-
+    
     if (pkcs1 == NULL)
         return NULL;
     if (pkcs1 == NULL)
         return NULL;
-
+    
        CFDataSetLength(pkcs1, result_size);
        CFDataSetLength(pkcs1, result_size);
-
+    
     uint8_t *bytes = CFDataGetMutableBytePtr(pkcs1);
     uint8_t *bytes = CFDataGetMutableBytePtr(pkcs1);
-
+    
     *bytes++ = ASN1_CONSTR_SEQUENCE;
     *bytes++ = ASN1_CONSTR_SEQUENCE;
-
+    
     DERSize itemLength = 4;
     DEREncodeLength(seq_size, bytes, &itemLength);
     bytes += itemLength;
     DERSize itemLength = 4;
     DEREncodeLength(seq_size, bytes, &itemLength);
     bytes += itemLength;
-
+    
     *bytes++ = ASN1_INTEGER;
     *bytes++ = 0x01;
     *bytes++ = 0x00;
     *bytes++ = ASN1_INTEGER;
     *bytes++ = 0x01;
     *bytes++ = 0x00;
-
+    
     ccasn_encode_int(ccrsa_ctx_n(fullkey), ccrsa_ctx_m(fullkey), m_size, &bytes);
     ccasn_encode_int(ccrsa_ctx_n(fullkey), ccrsa_ctx_e(fullkey), e_size, &bytes);
     ccasn_encode_int(ccrsa_ctx_n(fullkey), ccrsa_ctx_d(fullkey), d_size, &bytes);
     ccasn_encode_int(ccrsa_ctx_n(fullkey), ccrsa_ctx_m(fullkey), m_size, &bytes);
     ccasn_encode_int(ccrsa_ctx_n(fullkey), ccrsa_ctx_e(fullkey), e_size, &bytes);
     ccasn_encode_int(ccrsa_ctx_n(fullkey), ccrsa_ctx_d(fullkey), d_size, &bytes);
-
+    
     ccasn_encode_int(np, cczp_prime(ccrsa_ctx_private_zp(privkey)), p_size, &bytes);
     ccasn_encode_int(nq, cczp_prime(ccrsa_ctx_private_zq(privkey)), q_size, &bytes);
     ccasn_encode_int(np, ccrsa_ctx_private_dp(privkey), dp_size, &bytes);
     ccasn_encode_int(nq, ccrsa_ctx_private_dq(privkey), dq_size, &bytes);
     ccasn_encode_int(np, ccrsa_ctx_private_qinv(privkey), qinv_size, &bytes);
     ccasn_encode_int(np, cczp_prime(ccrsa_ctx_private_zp(privkey)), p_size, &bytes);
     ccasn_encode_int(nq, cczp_prime(ccrsa_ctx_private_zq(privkey)), q_size, &bytes);
     ccasn_encode_int(np, ccrsa_ctx_private_dp(privkey), dp_size, &bytes);
     ccasn_encode_int(nq, ccrsa_ctx_private_dq(privkey), dq_size, &bytes);
     ccasn_encode_int(np, ccrsa_ctx_private_qinv(privkey), qinv_size, &bytes);
-
+    
     return pkcs1;
 }
 
     return pkcs1;
 }
 
@@ -995,7 +1024,7 @@ static CFDataRef SecRSAPrivateKeyCopyPKCS1(SecKeyRef key)
 {
     ccrsa_full_ctx_t fullkey;
     fullkey.full = key->key;
 {
     ccrsa_full_ctx_t fullkey;
     fullkey.full = key->key;
-
+    
        CFAllocatorRef allocator = CFGetAllocator(key);
     return SecRSAPrivateKeyCreatePKCS1(allocator, fullkey);
 }
        CFAllocatorRef allocator = CFGetAllocator(key);
     return SecRSAPrivateKeyCreatePKCS1(allocator, fullkey);
 }
@@ -1004,10 +1033,10 @@ static OSStatus SecRSAPrivateKeyCopyPublicSerialization(SecKeyRef key, CFDataRef
 {
     ccrsa_full_ctx_t fullkey;
     fullkey.full = key->key;
 {
     ccrsa_full_ctx_t fullkey;
     fullkey.full = key->key;
-
+    
        CFAllocatorRef allocator = CFGetAllocator(key);
     *serialized = SecRSAPublicKeyCreatePKCS1(allocator, fullkey);
        CFAllocatorRef allocator = CFGetAllocator(key);
     *serialized = SecRSAPublicKeyCreatePKCS1(allocator, fullkey);
-
+    
     if (NULL == *serialized)
         return errSecDecode;
     else
     if (NULL == *serialized)
         return errSecDecode;
     else
@@ -1018,19 +1047,24 @@ static OSStatus SecRSAPrivateKeyCopyPublicSerialization(SecKeyRef key, CFDataRef
 static CFDictionaryRef SecRSAPrivateKeyCopyAttributeDictionary(SecKeyRef key) {
        CFDictionaryRef dict = NULL;
        CFDataRef fullKeyBlob = NULL;
 static CFDictionaryRef SecRSAPrivateKeyCopyAttributeDictionary(SecKeyRef key) {
        CFDictionaryRef dict = NULL;
        CFDataRef fullKeyBlob = NULL;
-
+    
        /* PKCS1 encode the key pair. */
        fullKeyBlob = SecRSAPrivateKeyCopyPKCS1(key);
     require(fullKeyBlob, errOut);
        /* PKCS1 encode the key pair. */
        fullKeyBlob = SecRSAPrivateKeyCopyPKCS1(key);
     require(fullKeyBlob, errOut);
-
+    
        dict = SecKeyGeneratePrivateAttributeDictionary(key, kSecAttrKeyTypeRSA, fullKeyBlob);
        dict = SecKeyGeneratePrivateAttributeDictionary(key, kSecAttrKeyTypeRSA, fullKeyBlob);
-
+    
 errOut:
        CFReleaseSafe(fullKeyBlob);
 errOut:
        CFReleaseSafe(fullKeyBlob);
-
+    
        return dict;
 }
 
        return dict;
 }
 
+static CFStringRef SecRSAPrivateKeyCopyDescription(SecKeyRef key){
+    
+       return CFStringCreateWithFormat(kCFAllocatorDefault,NULL,CFSTR( "<SecKeyRef algorithm id: %lu, key type: %s, version: %d, block size: %zu bits, addr: %p>"), SecKeyGetAlgorithmID(key), key->key_class->name, key->key_class->version, (8*SecKeyGetBlockSize(key)), key);
+    
+}
 SecKeyDescriptor kSecRSAPrivateKeyDescriptor = {
     kSecKeyDescriptorVersion,
     "RSAPrivateKey",
 SecKeyDescriptor kSecRSAPrivateKeyDescriptor = {
     kSecKeyDescriptorVersion,
     "RSAPrivateKey",
@@ -1044,37 +1078,38 @@ SecKeyDescriptor kSecRSAPrivateKeyDescriptor = {
     NULL, /* SecKeyComputeMethod */
     SecRSAPrivateKeyBlockSize,
        SecRSAPrivateKeyCopyAttributeDictionary,
     NULL, /* SecKeyComputeMethod */
     SecRSAPrivateKeyBlockSize,
        SecRSAPrivateKeyCopyAttributeDictionary,
+    SecRSAPrivateKeyCopyDescription,
     NULL,
     SecRSAPrivateKeyCopyPublicSerialization,
 };
 
 /* Private Key API functions. */
 SecKeyRef SecKeyCreateRSAPrivateKey(CFAllocatorRef allocator,
     NULL,
     SecRSAPrivateKeyCopyPublicSerialization,
 };
 
 /* Private Key API functions. */
 SecKeyRef SecKeyCreateRSAPrivateKey(CFAllocatorRef allocator,
-    const uint8_t *keyData, CFIndex keyDataLength,
-    SecKeyEncoding encoding) {
+                                    const uint8_t *keyData, CFIndex keyDataLength,
+                                    SecKeyEncoding encoding) {
     return SecKeyCreate(allocator, &kSecRSAPrivateKeyDescriptor, keyData,
     return SecKeyCreate(allocator, &kSecRSAPrivateKeyDescriptor, keyData,
-        keyDataLength, encoding);
+                        keyDataLength, encoding);
 }
 
 
 OSStatus SecRSAKeyGeneratePair(CFDictionaryRef parameters,
 }
 
 
 OSStatus SecRSAKeyGeneratePair(CFDictionaryRef parameters,
-    SecKeyRef *rsaPublicKey, SecKeyRef *rsaPrivateKey) {
+                               SecKeyRef *rsaPublicKey, SecKeyRef *rsaPrivateKey) {
     OSStatus status = errSecParam;
     OSStatus status = errSecParam;
-
+    
     CFAllocatorRef allocator = NULL; /* @@@ get from parameters. */
     CFAllocatorRef allocator = NULL; /* @@@ get from parameters. */
-
+    
     SecKeyRef pubKey = NULL;
     SecKeyRef privKey = SecKeyCreate(allocator, &kSecRSAPrivateKeyDescriptor,
                                      (const void*) parameters, 0, kSecGenerateKey);
     SecKeyRef pubKey = NULL;
     SecKeyRef privKey = SecKeyCreate(allocator, &kSecRSAPrivateKeyDescriptor,
                                      (const void*) parameters, 0, kSecGenerateKey);
-
+    
     require(privKey, errOut);
     require(privKey, errOut);
-
+    
        /* Create SecKeyRef's from the pkcs1 encoded keys. */
     pubKey = SecKeyCreate(allocator, &kSecRSAPublicKeyDescriptor,
                           privKey->key, 0, kSecExtractPublicFromPrivate);
        /* Create SecKeyRef's from the pkcs1 encoded keys. */
     pubKey = SecKeyCreate(allocator, &kSecRSAPublicKeyDescriptor,
                           privKey->key, 0, kSecExtractPublicFromPrivate);
-
+    
     require(pubKey, errOut);
     require(pubKey, errOut);
-
+    
     if (rsaPublicKey) {
         *rsaPublicKey = pubKey;
         pubKey = NULL;
     if (rsaPublicKey) {
         *rsaPublicKey = pubKey;
         pubKey = NULL;
@@ -1083,12 +1118,12 @@ OSStatus SecRSAKeyGeneratePair(CFDictionaryRef parameters,
         *rsaPrivateKey = privKey;
         privKey = NULL;
     }
         *rsaPrivateKey = privKey;
         privKey = NULL;
     }
-
+    
     status = errSecSuccess;
     status = errSecSuccess;
-
+    
 errOut:
     CFReleaseSafe(pubKey);
     CFReleaseSafe(privKey);
 errOut:
     CFReleaseSafe(pubKey);
     CFReleaseSafe(privKey);
-
+    
        return status;
 }
        return status;
 }
index c4899e9817ad2852a9b72f4ba35099ff48ed5f38..706a06cf8548645537e2480b4790eb37a03d9a79 100644 (file)
@@ -34,9 +34,7 @@
 #include <Security/SecKeyPriv.h>
 #include <CoreFoundation/CFData.h>
 
 #include <Security/SecKeyPriv.h>
 #include <CoreFoundation/CFData.h>
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 typedef struct SecRSAPublicKeyParams {
        uint8_t             *modulus;                   /* modulus */
 
 typedef struct SecRSAPublicKeyParams {
        uint8_t             *modulus;                   /* modulus */
@@ -60,8 +58,6 @@ SecKeyRef SecKeyCreateRSAPrivateKey(CFAllocatorRef allocator,
     const uint8_t *keyData, CFIndex keyDataLength,
     SecKeyEncoding encoding);
 
     const uint8_t *keyData, CFIndex keyDataLength,
     SecKeyEncoding encoding);
 
-#if defined(__cplusplus)
-}
-#endif
+__END_DECLS
 
 #endif /* !_SECURITY_SECRSAKEY_H_ */
 
 #endif /* !_SECURITY_SECRSAKEY_H_ */
index b4e8395b0ae16110e34b8413e71f0e7286086735..bd3de485a660d1663b8ec667331c78e354d06ab8 100644 (file)
 
 #include <Security/SecRSAKey.h>
 
 
 #include <Security/SecRSAKey.h>
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 OSStatus SecRSAKeyGeneratePair(CFDictionaryRef parameters,
     SecKeyRef *rsaPublicKey, SecKeyRef *rsaPrivateKey);
 
 
 OSStatus SecRSAKeyGeneratePair(CFDictionaryRef parameters,
     SecKeyRef *rsaPublicKey, SecKeyRef *rsaPrivateKey);
 
-#if defined(__cplusplus)
-}
-#endif
+__END_DECLS
 
 #endif /* !_SECURITY_SECRSAKEY_H_ */
 
 #endif /* !_SECURITY_SECRSAKEY_H_ */
index cd493e951539bc3a77ba6b48e9249ed7237b7341..9afe53a12433cc973df576ed46c7b67643dcfce1 100644 (file)
@@ -34,9 +34,7 @@
 #include <stdint.h>
 #include <sys/types.h>
 
 #include <stdint.h>
 #include <sys/types.h>
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 /*!
     @typedef SecRandomRef
 
 /*!
     @typedef SecRandomRef
@@ -58,8 +56,6 @@ extern const SecRandomRef kSecRandomDefault
 int SecRandomCopyBytes(SecRandomRef rnd, size_t count, uint8_t *bytes)
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0);
 
 int SecRandomCopyBytes(SecRandomRef rnd, size_t count, uint8_t *bytes)
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0);
 
-#if defined(__cplusplus)
-}
-#endif
+__END_DECLS
 
 #endif /* !_SECURITY_SECRANDOM_H_ */
 
 #endif /* !_SECURITY_SECRANDOM_H_ */
index 9e81a06a556b7fb86e511df4a1dbc10392fdf406..6b25f1ac46fd473f0bbe3218c149ad4b9920f942 100644 (file)
@@ -29,6 +29,7 @@
 #include <string.h>
 #include <AssertMacros.h>
 #include <CommonCrypto/CommonDigest.h>
 #include <string.h>
 #include <AssertMacros.h>
 #include <CommonCrypto/CommonDigest.h>
+#include <CommonCrypto/CommonDigestSPI.h>
 #include <Security/SecItem.h>
 #include <Security/SecInternal.h>
 #include <Security/SecCertificateInternal.h>
 #include <Security/SecItem.h>
 #include <Security/SecInternal.h>
 #include <Security/SecCertificateInternal.h>
@@ -36,7 +37,9 @@
 #include <Security/SecInternal.h>
 #include <libDER/DER_Encode.h>
 #include <uuid/uuid.h>
 #include <Security/SecInternal.h>
 #include <libDER/DER_Encode.h>
 #include <uuid/uuid.h>
-#include <security_utilities/debugging.h>
+#include <utilities/array_size.h>
+#include <utilities/debugging.h>
+#include <utilities/SecIOFormat.h>
 
 typedef enum {
         messageType = 2,
 
 typedef enum {
         messageType = 2,
@@ -169,7 +172,7 @@ static CFDataRef pubkeyhash(SecKeyRef key)
                 CFEqual(key_type, kSecAttrKeyClassPublic), out);
     require(pubkey_data = CFDictionaryGetValue(pubkey_attrs, kSecValueData), out);
     require((unsigned long)CFDataGetLength(pubkey_data)<=UINT32_MAX, out); /* Correct as long as CFIndex is long */
                 CFEqual(key_type, kSecAttrKeyClassPublic), out);
     require(pubkey_data = CFDictionaryGetValue(pubkey_attrs, kSecValueData), out);
     require((unsigned long)CFDataGetLength(pubkey_data)<=UINT32_MAX, out); /* Correct as long as CFIndex is long */
-    CC_SHA1(CFDataGetBytePtr(pubkey_data), (CC_LONG)CFDataGetLength(pubkey_data), pubkey_hash);
+    CCDigest(kCCDigestSHA1, CFDataGetBytePtr(pubkey_data), (CC_LONG)CFDataGetLength(pubkey_data), pubkey_hash);
     hash_pubkey_data = CFDataCreate(kCFAllocatorDefault, pubkey_hash, sizeof(pubkey_hash));
 out:
     CFReleaseSafe(pubkey_attrs);
     hash_pubkey_data = CFDataCreate(kCFAllocatorDefault, pubkey_hash, sizeof(pubkey_hash));
 out:
     CFReleaseSafe(pubkey_attrs);
@@ -206,7 +209,7 @@ SecIdentityRef SecSCEPCreateTemporaryIdentity(SecKeyRef publicKey, SecKeyRef pri
        const void *key[] = { kSecCertificateKeyUsage };
        const void *val[] = { key_usage_num };
        self_signed_parameters = CFDictionaryCreate(kCFAllocatorDefault,
        const void *key[] = { kSecCertificateKeyUsage };
        const void *val[] = { key_usage_num };
        self_signed_parameters = CFDictionaryCreate(kCFAllocatorDefault,
-           key, val, sizeof(key)/sizeof(*key),
+           key, val, array_size(key),
                &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
        require(self_signed_parameters, out);
 
                &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
        require(self_signed_parameters, out);
 
@@ -426,7 +429,7 @@ SecSCEPCertifyRequest(CFDataRef request, SecIdentityRef ca_identity, CFDataRef s
        CFDataRef message_type_oid = scep_oid(messageType), message_type_value = scep_result(CertRep);
        const void *oid[] = { transid_oid_data, pki_status_oid, message_type_oid };
        const void *value[] = { transid_value, pki_status_value, message_type_value };
        CFDataRef message_type_oid = scep_oid(messageType), message_type_value = scep_result(CertRep);
        const void *oid[] = { transid_oid_data, pki_status_oid, message_type_oid };
        const void *value[] = { transid_value, pki_status_value, message_type_value };
-       simple_attr = CFDictionaryCreate(kCFAllocatorDefault, oid, value, sizeof(oid)/sizeof(*oid),
+       simple_attr = CFDictionaryCreate(kCFAllocatorDefault, oid, value, array_size(oid),
                &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
        CFReleaseSafe(pki_status_oid); CFReleaseSafe(pki_status_value);
        CFReleaseSafe(message_type_oid); CFReleaseSafe(message_type_value);
                &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
        CFReleaseSafe(pki_status_oid); CFReleaseSafe(pki_status_value);
        CFReleaseSafe(message_type_oid); CFReleaseSafe(message_type_value);
@@ -435,7 +438,7 @@ SecSCEPCertifyRequest(CFDataRef request, SecIdentityRef ca_identity, CFDataRef s
        signed_reply = CFDataCreateMutable(kCFAllocatorDefault, 0);
     const void *signing_params[] = { kSecCMSCertChainMode };
     const void *signing_params_vals[] = { kSecCMSCertChainModeNone };
        signed_reply = CFDataCreateMutable(kCFAllocatorDefault, 0);
     const void *signing_params[] = { kSecCMSCertChainMode };
     const void *signing_params_vals[] = { kSecCMSCertChainModeNone };
-    parameters = CFDictionaryCreate(kCFAllocatorDefault, signing_params, signing_params_vals, sizeof(signing_params)/sizeof(*signing_params), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    parameters = CFDictionaryCreate(kCFAllocatorDefault, signing_params, signing_params_vals, array_size(signing_params), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
     require_noerr_action(SecCMSCreateSignedData(ca_identity, cert_msg, parameters, simple_attr, signed_reply), out, CFReleaseNull(signed_reply));
 
 out:
     require_noerr_action(SecCMSCreateSignedData(ca_identity, cert_msg, parameters, simple_attr, signed_reply), out, CFReleaseNull(signed_reply));
 
 out:
@@ -631,7 +634,7 @@ OSStatus SecSCEPValidateCACertMessage(CFArrayRef certs,
         SecTrustResultType trust_result;
         SecTrustEvaluate(trust, &trust_result);
         CFIndex chain_count = SecTrustGetCertificateCount(trust);
         SecTrustResultType trust_result;
         SecTrustEvaluate(trust, &trust_result);
         CFIndex chain_count = SecTrustGetCertificateCount(trust);
-        secdebug("scep", "candidate leaf: %@ forms chain of length %d", candidate_leaf, chain_count);
+        secdebug("scep", "candidate leaf: %@ forms chain of length %" PRIdCFIndex, candidate_leaf, chain_count);
         if (chain_count > 1) {
             SecCertificateRef leaf = SecTrustGetCertificateAtIndex(trust, 0);
             SecCertificateRef ca_leaf = SecTrustGetCertificateAtIndex(trust, chain_count - 1);
         if (chain_count > 1) {
             SecCertificateRef leaf = SecTrustGetCertificateAtIndex(trust, 0);
             SecCertificateRef ca_leaf = SecTrustGetCertificateAtIndex(trust, chain_count - 1);
@@ -652,7 +655,7 @@ OSStatus SecSCEPValidateCACertMessage(CFArrayRef certs,
                             break;
 
                         case CC_SHA1_DIGEST_LENGTH:
                             break;
 
                         case CC_SHA1_DIGEST_LENGTH:
-                            CC_SHA1(ca_data, (CC_LONG)ca_data_len, ca_hash);
+                            CCDigest(kCCDigestSHA1, ca_data, (CC_LONG)ca_data_len, ca_hash);
                             break;
 
                         default:
                             break;
 
                         default:
@@ -718,7 +721,7 @@ OSStatus SecSCEPValidateCACertMessage(CFArrayRef certs,
         }
     }
 
         }
     }
 
-    status = noErr;
+    status = errSecSuccess;
 
 out:
     if (_ra_encryption_certificate) CFRelease(_ra_encryption_certificate);
 
 out:
     if (_ra_encryption_certificate) CFRelease(_ra_encryption_certificate);
index 220e0592cbc2026e9b4ecd7cf3d796ea9227ba01..bc26548c16a270855f0905af1cdce47971976ffe 100644 (file)
@@ -33,9 +33,7 @@
 #ifndef _SECURITY_SECSCEP_H_
 #define _SECURITY_SECSCEP_H_
 
 #ifndef _SECURITY_SECSCEP_H_
 #define _SECURITY_SECSCEP_H_
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 
 SecIdentityRef
 
 
 SecIdentityRef
@@ -57,7 +55,7 @@ SecSCEPCreateTemporaryIdentity(SecKeyRef publicKey, SecKeyRef privateKey);
 CFDataRef
 SecSCEPGenerateCertificateRequest(CFArrayRef subject, CFDictionaryRef parameters,
     SecKeyRef publicKey, SecKeyRef privateKey,
 CFDataRef
 SecSCEPGenerateCertificateRequest(CFArrayRef subject, CFDictionaryRef parameters,
     SecKeyRef publicKey, SecKeyRef privateKey,
-    SecIdentityRef signer, CFTypeRef recipient);
+    SecIdentityRef signer, CFTypeRef recipient) CF_RETURNS_RETAINED;
 
 /*!
     @function SecSCEPCertifyRequest
 
 /*!
     @function SecSCEPCertifyRequest
@@ -69,7 +67,7 @@ SecSCEPGenerateCertificateRequest(CFArrayRef subject, CFDictionaryRef parameters
        @param pend_request don't issue cert now
 */
 CFDataRef
        @param pend_request don't issue cert now
 */
 CFDataRef
-SecSCEPCertifyRequest(CFDataRef request, SecIdentityRef ca_identity, CFDataRef serialno, bool pend_request);
+SecSCEPCertifyRequest(CFDataRef request, SecIdentityRef ca_identity, CFDataRef serialno, bool pend_request) CF_RETURNS_RETAINED;
 
 /*!
     @function SecSCEPVerifyReply
 
 /*!
     @function SecSCEPVerifyReply
@@ -83,7 +81,7 @@ SecSCEPCertifyRequest(CFDataRef request, SecIdentityRef ca_identity, CFDataRef s
 */
 CFArrayRef
 SecSCEPVerifyReply(CFDataRef request, CFDataRef reply, CFTypeRef signer,
 */
 CFArrayRef
 SecSCEPVerifyReply(CFDataRef request, CFDataRef reply, CFTypeRef signer,
-    CFErrorRef *server_error);
+    CFErrorRef *server_error) CF_RETURNS_RETAINED;
 
 
 /*!
 
 
 /*!
@@ -104,7 +102,7 @@ SecSCEPGetCertInitial(SecCertificateRef ca_certificate, CFArrayRef subject, CFDi
     @param ca_certificate SecCertificateRef CA certificate
     @param ra_certificate SecCertificateRef RA certificate.  Use both for signing and encryption unless ra_encryption_certificate is also returned.
     @param ra_encryption_certificate SecCertificateRef RA encryption certificate.  Returned if there isn't an RA certificate that can both sign and encrypt.
     @param ca_certificate SecCertificateRef CA certificate
     @param ra_certificate SecCertificateRef RA certificate.  Use both for signing and encryption unless ra_encryption_certificate is also returned.
     @param ra_encryption_certificate SecCertificateRef RA encryption certificate.  Returned if there isn't an RA certificate that can both sign and encrypt.
-    @result status noErr on success.
+    @result status errSecSuccess on success.
 */
 OSStatus 
 SecSCEPValidateCACertMessage(CFArrayRef certs,
 */
 OSStatus 
 SecSCEPValidateCACertMessage(CFArrayRef certs,
@@ -113,8 +111,6 @@ SecSCEPValidateCACertMessage(CFArrayRef certs,
     SecCertificateRef *ra_encryption_certificate);
 
 
     SecCertificateRef *ra_encryption_certificate);
 
 
-#if defined(__cplusplus)
-}
-#endif
+__END_DECLS
 
 #endif /* _SECURITY_SECSCEP_H_ */
 
 #endif /* _SECURITY_SECSCEP_H_ */
index d3fef98fff3277ae2297ba8eb311a58df89c10cc..ece0826001adc57f952dcc530d636fc8169d4e3d 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2006-2010 Apple Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2006-2013 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  *
  * SecTrust.c - CoreFoundation based certificate trust evaluator
  * @APPLE_LICENSE_HEADER_END@
  *
  * SecTrust.c - CoreFoundation based certificate trust evaluator
  */
 
 #include <Security/SecTrustPriv.h>
  */
 
 #include <Security/SecTrustPriv.h>
-#include <Security/SecItem.h>
+#include <Security/SecItemPriv.h>
 #include <Security/SecCertificateInternal.h>
 #include <Security/SecCertificatePath.h>
 #include <Security/SecFramework.h>
 #include <Security/SecPolicyInternal.h>
 #include <Security/SecCertificateInternal.h>
 #include <Security/SecCertificatePath.h>
 #include <Security/SecFramework.h>
 #include <Security/SecPolicyInternal.h>
+#include <utilities/SecIOFormat.h>
 #include <CoreFoundation/CFRuntime.h>
 #include <CoreFoundation/CFSet.h>
 #include <CoreFoundation/CFString.h>
 #include <CoreFoundation/CFRuntime.h>
 #include <CoreFoundation/CFSet.h>
 #include <CoreFoundation/CFString.h>
 #include <string.h>
 #include <stdlib.h>
 #include <pthread.h>
 #include <string.h>
 #include <stdlib.h>
 #include <pthread.h>
-#include <MacErrors.h>
+#include <Security/SecBasePriv.h>
+#include <utilities/SecCFError.h>
+#include <utilities/SecCFWrappers.h>
+
 #include "SecRSAKey.h"
 #include <libDER/oids.h>
 #include "SecRSAKey.h"
 #include <libDER/oids.h>
-#include <security_utilities/debugging.h>
+#include <utilities/debugging.h>
 #include <Security/SecInternal.h>
 #include <ipc/securityd_client.h>
 #include <Security/SecInternal.h>
 #include <ipc/securityd_client.h>
-#include "securityd_server.h"
+#include <SecuritydXPC.h>
+#include <securityd/SecTrustServer.h>
+
+#define SEC_CONST_DECL(k,v) CFTypeRef k = (CFTypeRef)(CFSTR(v));
 
 
-CFStringRef kSecTrustInfoExtendedValidationKey = CFSTR("ExtendedValidation");
-CFStringRef kSecTrustInfoCompanyNameKey = CFSTR("CompanyName");
-CFStringRef kSecTrustInfoRevocationKey = CFSTR("Revocation");
-CFStringRef kSecTrustInfoRevocationValidUntilKey =
-    CFSTR("RevocationValidUntil");
+SEC_CONST_DECL (kSecTrustInfoExtendedValidationKey, "ExtendedValidation");
+SEC_CONST_DECL (kSecTrustInfoCompanyNameKey, "CompanyName");
+SEC_CONST_DECL (kSecTrustInfoRevocationKey, "Revocation");
+SEC_CONST_DECL (kSecTrustInfoRevocationValidUntilKey, "RevocationValidUntil");
+
+/* Public trust result constants */
+SEC_CONST_DECL (kSecTrustEvaluationDate, "TrustEvaluationDate");
+SEC_CONST_DECL (kSecTrustExtendedValidation, "TrustExtendedValidation");
+SEC_CONST_DECL (kSecTrustOrganizationName, "Organization");
+SEC_CONST_DECL (kSecTrustResultValue, "TrustResultValue");
+SEC_CONST_DECL (kSecTrustRevocationChecked, "TrustRevocationChecked");
+SEC_CONST_DECL (kSecTrustRevocationValidUntilDate, "TrustExpirationDate");
+SEC_CONST_DECL (kSecTrustResultDetails, "TrustResultDetails");
 
 #pragma mark -
 #pragma mark SecTrust
 
 #pragma mark -
 #pragma mark SecTrust
+
 /********************************************************
  ****************** SecTrust object *********************
  ********************************************************/
 struct __SecTrust {
 /********************************************************
  ****************** SecTrust object *********************
  ********************************************************/
 struct __SecTrust {
-    CFRuntimeBase                      _base;
-    CFArrayRef                         _certificates;
-    CFArrayRef                         _anchors;
-    CFTypeRef                          _policies;
+       CFRuntimeBase                   _base;
+       CFArrayRef                              _certificates;
+       CFArrayRef                              _anchors;
+       CFTypeRef                               _policies;
+       CFArrayRef                              _responses;
        CFDateRef                               _verifyDate;
        SecCertificatePathRef   _chain;
        SecKeyRef                               _publicKey;
        CFDateRef                               _verifyDate;
        SecCertificatePathRef   _chain;
        SecKeyRef                               _publicKey;
@@ -73,29 +90,42 @@ struct __SecTrust {
        CFDictionaryRef         _info;
        CFArrayRef              _exceptions;
 
        CFDictionaryRef         _info;
        CFArrayRef              _exceptions;
 
+    /* Note that a value of kSecTrustResultInvalid (0)
+     * indicates the trust must be (re)evaluated; any
+     * functions which modify trust parameters in a way
+     * that would invalidate the current result must set
+     * this value back to kSecTrustResultInvalid.
+     */
+    SecTrustResultType      _trustResult;
+
     /* If true we don't trust any anchors other than the ones in _anchors. */
     bool                    _anchorsOnly;
     /* If true we don't trust any anchors other than the ones in _anchors. */
     bool                    _anchorsOnly;
+
+       /* Master switch to permit or disable network use in policy evaluation */
+       SecNetworkPolicy                _networkPolicy;
 };
 
 };
 
-/* CFRuntime regsitration data. */
+/* CFRuntime registration data. */
 static pthread_once_t kSecTrustRegisterClass = PTHREAD_ONCE_INIT;
 static CFTypeID kSecTrustTypeID = _kCFRuntimeNotATypeID;
 
 static pthread_once_t kSecTrustRegisterClass = PTHREAD_ONCE_INIT;
 static CFTypeID kSecTrustTypeID = _kCFRuntimeNotATypeID;
 
-/* Forward declartions of static functions. */
+/* Forward declarations of static functions. */
 static CFStringRef SecTrustDescribe(CFTypeRef cf);
 static void SecTrustDestroy(CFTypeRef cf);
 static CFStringRef SecTrustDescribe(CFTypeRef cf);
 static void SecTrustDestroy(CFTypeRef cf);
+static OSStatus SecTrustEvaluateIfNecessary(SecTrustRef trust);
 
 /* Static functions. */
 
 /* Static functions. */
-static CFStringRef SecTrustDescribe(CFTypeRef cf) {
-    SecTrustRef certificate = (SecTrustRef)cf;
+static CF_RETURNS_RETAINED CFStringRef SecTrustDescribe(CFTypeRef cf) {
+    SecTrustRef trust = (SecTrustRef)cf;
     return CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
     return CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
-        CFSTR("<SecTrustRef: %p>"), certificate);
+        CFSTR("<SecTrustRef: %p>"), trust);
 }
 
 static void SecTrustDestroy(CFTypeRef cf) {
     SecTrustRef trust = (SecTrustRef)cf;
        CFReleaseSafe(trust->_certificates);
        CFReleaseSafe(trust->_policies);
 }
 
 static void SecTrustDestroy(CFTypeRef cf) {
     SecTrustRef trust = (SecTrustRef)cf;
        CFReleaseSafe(trust->_certificates);
        CFReleaseSafe(trust->_policies);
+       CFReleaseSafe(trust->_responses);
        CFReleaseSafe(trust->_verifyDate);
        CFReleaseSafe(trust->_anchors);
        CFReleaseSafe(trust->_chain);
        CFReleaseSafe(trust->_verifyDate);
        CFReleaseSafe(trust->_anchors);
        CFReleaseSafe(trust->_chain);
@@ -128,14 +158,14 @@ CFTypeID SecTrustGetTypeID(void) {
 }
 
 OSStatus SecTrustCreateWithCertificates(CFTypeRef certificates,
 }
 
 OSStatus SecTrustCreateWithCertificates(CFTypeRef certificates,
-    CFTypeRef policies, SecTrustRef *trustRef) {
+    CFTypeRef policies, SecTrustRef *trust) {
     OSStatus status = errSecParam;
     CFAllocatorRef allocator = kCFAllocatorDefault;
     CFArrayRef l_certs = NULL, l_policies = NULL;
     SecTrustRef result = NULL;
 
        check(certificates);
     OSStatus status = errSecParam;
     CFAllocatorRef allocator = kCFAllocatorDefault;
     CFArrayRef l_certs = NULL, l_policies = NULL;
     SecTrustRef result = NULL;
 
        check(certificates);
-       check(trustRef);
+       check(trust);
     CFTypeID certType = CFGetTypeID(certificates);
     if (certType == CFArrayGetTypeID()) {
         /* We need at least 1 certificate. */
     CFTypeID certType = CFGetTypeID(certificates);
     if (certType == CFArrayGetTypeID()) {
         /* We need at least 1 certificate. */
@@ -175,7 +205,7 @@ OSStatus SecTrustCreateWithCertificates(CFTypeRef certificates,
         SecTrustGetTypeID(), size - sizeof(CFRuntimeBase), 0), errOut);
     memset((char*)result + sizeof(result->_base), 0,
         sizeof(*result) - sizeof(result->_base));
         SecTrustGetTypeID(), size - sizeof(CFRuntimeBase), 0), errOut);
     memset((char*)result + sizeof(result->_base), 0,
         sizeof(*result) - sizeof(result->_base));
-    status = noErr;
+    status = errSecSuccess;
 
 errOut:
     if (status) {
 
 errOut:
     if (status) {
@@ -185,63 +215,208 @@ errOut:
     } else {
         result->_certificates = l_certs;
         result->_policies = l_policies;
     } else {
         result->_certificates = l_certs;
         result->_policies = l_policies;
-        *trustRef = result;
+        *trust = result;
     }
     return status;
 }
 
     }
     return status;
 }
 
+static void SetTrustSetNeedsEvaluation(SecTrustRef trust) {
+    check(trust);
+    if (trust) {
+        trust->_trustResult = kSecTrustResultInvalid;
+    }
+}
+
 OSStatus SecTrustSetAnchorCertificatesOnly(SecTrustRef trust,
     Boolean anchorCertificatesOnly) {
 OSStatus SecTrustSetAnchorCertificatesOnly(SecTrustRef trust,
     Boolean anchorCertificatesOnly) {
-    check(trust);
+    if (!trust) {
+        return errSecParam;
+    }
+    SetTrustSetNeedsEvaluation(trust);
     trust->_anchorsOnly = anchorCertificatesOnly;
 
     trust->_anchorsOnly = anchorCertificatesOnly;
 
-       /* FIXME changing this options should (potentially) invalidate the chain. */
-    return noErr;
+    return errSecSuccess;
 }
 
 OSStatus SecTrustSetAnchorCertificates(SecTrustRef trust,
     CFArrayRef anchorCertificates) {
 }
 
 OSStatus SecTrustSetAnchorCertificates(SecTrustRef trust,
     CFArrayRef anchorCertificates) {
-    check(trust);
-    check(anchorCertificates);
-       CFRetain(anchorCertificates);
+    if (!trust) {
+        return errSecParam;
+    }
+    SetTrustSetNeedsEvaluation(trust);
+    if (anchorCertificates)
+        CFRetain(anchorCertificates);
     if (trust->_anchors)
         CFRelease(trust->_anchors);
     trust->_anchors = anchorCertificates;
     if (trust->_anchors)
         CFRelease(trust->_anchors);
     trust->_anchors = anchorCertificates;
-    trust->_anchorsOnly = true;
+    trust->_anchorsOnly = (anchorCertificates != NULL);
+
+    return errSecSuccess;
+}
+
+OSStatus SecTrustCopyCustomAnchorCertificates(SecTrustRef trust,
+    CFArrayRef *anchors) {
+       if (!trust|| !anchors) {
+               return errSecParam;
+       }
+       CFArrayRef anchorsArray = NULL;
+       if (trust->_anchors) {
+               anchorsArray = CFArrayCreateCopy(kCFAllocatorDefault, trust->_anchors);
+               if (!anchorsArray) {
+                       return errSecAllocate;
+               }
+       }
+       *anchors = anchorsArray;
+       return errSecSuccess;
+}
+
+OSStatus SecTrustSetOCSPResponse(SecTrustRef trust, CFTypeRef responseData) {
+    if (!trust) {
+        return errSecParam;
+    }
+       SetTrustSetNeedsEvaluation(trust);
+       CFArrayRef responseArray = NULL;
+       if (responseData) {
+               if (CFGetTypeID(responseData) == CFArrayGetTypeID()) {
+            responseArray = CFArrayCreateCopy(kCFAllocatorDefault, responseData);
+        } else if (CFGetTypeID(responseData) == CFDataGetTypeID()) {
+            responseArray = CFArrayCreate(kCFAllocatorDefault, &responseData, 1,
+                                          &kCFTypeArrayCallBacks);
+        } else {
+            return errSecParam;
+        }
+    }
+       if (trust->_responses)
+               CFRelease(trust->_responses);
+       trust->_responses = responseArray;
 
 
-       /* FIXME changing the anchor set should invalidate the chain. */
-    return noErr;
+       return errSecSuccess;
 }
 
 OSStatus SecTrustSetVerifyDate(SecTrustRef trust, CFDateRef verifyDate) {
 }
 
 OSStatus SecTrustSetVerifyDate(SecTrustRef trust, CFDateRef verifyDate) {
-    check(trust);
+    if (!trust) {
+        return errSecParam;
+    }
+    SetTrustSetNeedsEvaluation(trust);
     check(verifyDate);
     check(verifyDate);
-    CFRetain(verifyDate);
+    CFRetainSafe(verifyDate);
     if (trust->_verifyDate)
         CFRelease(trust->_verifyDate);
     trust->_verifyDate = verifyDate;
 
     if (trust->_verifyDate)
         CFRelease(trust->_verifyDate);
     trust->_verifyDate = verifyDate;
 
-       /* FIXME changing the verifydate should invalidate the chain. */
-    return noErr;
+    return errSecSuccess;
+}
+
+OSStatus SecTrustSetPolicies(SecTrustRef trust, CFTypeRef newPolicies) {
+    if (!trust || !newPolicies) {
+        return errSecParam;
+    }
+    SetTrustSetNeedsEvaluation(trust);
+    check(newPolicies);
+
+    CFArrayRef policyArray = NULL;
+    if (CFGetTypeID(newPolicies) == CFArrayGetTypeID()) {
+               policyArray = CFArrayCreateCopy(kCFAllocatorDefault, newPolicies);
+       } else if (CFGetTypeID(newPolicies) == SecPolicyGetTypeID()) {
+               policyArray = CFArrayCreate(kCFAllocatorDefault, &newPolicies, 1,
+                       &kCFTypeArrayCallBacks);
+    } else {
+        return errSecParam;
+    }
+
+    if (trust->_policies)
+        CFRelease(trust->_policies);
+    trust->_policies = policyArray;
+
+    return errSecSuccess;
+}
+
+OSStatus SecTrustCopyPolicies(SecTrustRef trust, CFArrayRef *policies) {
+       if (!trust|| !policies) {
+               return errSecParam;
+       }
+       if (!trust->_policies) {
+               return errSecInternal;
+       }
+       CFArrayRef policyArray = CFArrayCreateCopy(kCFAllocatorDefault, trust->_policies);
+       if (!policyArray) {
+               return errSecAllocate;
+       }
+       *policies = policyArray;
+       return errSecSuccess;
+}
+
+OSStatus SecTrustSetNetworkFetchAllowed(SecTrustRef trust, Boolean allowFetch) {
+       if (!trust) {
+               return errSecParam;
+       }
+       trust->_networkPolicy = (allowFetch) ? useNetworkEnabled : useNetworkDisabled;
+       return errSecSuccess;
+}
+
+OSStatus SecTrustGetNetworkFetchAllowed(SecTrustRef trust, Boolean *allowFetch) {
+       if (!trust || !allowFetch) {
+               return errSecParam;
+       }
+       Boolean allowed = false;
+       SecNetworkPolicy netPolicy = trust->_networkPolicy;
+       if (netPolicy == useNetworkDefault) {
+               // network fetch is enabled by default for SSL only
+               CFIndex idx, count = (trust->_policies) ? CFArrayGetCount(trust->_policies) : 0;
+               for (idx=0; idx<count; idx++) {
+                       SecPolicyRef policy = (SecPolicyRef)CFArrayGetValueAtIndex(trust->_policies, idx);
+                       if (policy) {
+                               CFDictionaryRef props = SecPolicyCopyProperties(policy);
+                               if (props) {
+                                       CFTypeRef value = (CFTypeRef)CFDictionaryGetValue(props, kSecPolicyOid);
+                                       if (value) {
+                                               if (CFEqual(value, kSecPolicyAppleSSL)) {
+                                                       allowed = true;
+                                               }
+                                       }
+                                       CFRelease(props);
+                               }
+                       }
+               }
+       } else {
+               // caller has explicitly set the network policy
+               allowed = (netPolicy == useNetworkEnabled);
+       }
+       *allowFetch = allowed;
+       return errSecSuccess;
 }
 
 CFAbsoluteTime SecTrustGetVerifyTime(SecTrustRef trust) {
     CFAbsoluteTime verifyTime;
 }
 
 CFAbsoluteTime SecTrustGetVerifyTime(SecTrustRef trust) {
     CFAbsoluteTime verifyTime;
-    if (trust->_verifyDate) {
+    if (trust && trust->_verifyDate) {
         verifyTime = CFDateGetAbsoluteTime(trust->_verifyDate);
     } else {
         verifyTime = CFAbsoluteTimeGetCurrent();
                /* Record the verifyDate we ended up using. */
         verifyTime = CFDateGetAbsoluteTime(trust->_verifyDate);
     } else {
         verifyTime = CFAbsoluteTimeGetCurrent();
                /* Record the verifyDate we ended up using. */
-        trust->_verifyDate = CFDateCreate(CFGetAllocator(trust), verifyTime);
+        if (trust) {
+            trust->_verifyDate = CFDateCreate(CFGetAllocator(trust), verifyTime);
+        }
     }
     }
-
     return verifyTime;
 }
 
 CFArrayRef SecTrustGetDetails(SecTrustRef trust) {
     return verifyTime;
 }
 
 CFArrayRef SecTrustGetDetails(SecTrustRef trust) {
+       if (!trust) {
+               return NULL;
+       }
+    SecTrustEvaluateIfNecessary(trust);
     return trust->_details;
 }
 
     return trust->_details;
 }
 
+OSStatus SecTrustGetTrustResult(SecTrustRef trust,
+    SecTrustResultType *result) {
+       if (!trust || !result) {
+               return errSecParam;
+       }
+       *result = trust->_trustResult;
+       return errSecSuccess;
+}
+
 static CFStringRef kSecCertificateDetailSHA1Digest = CFSTR("SHA1Digest");
 
 static CFDictionaryRef SecTrustGetExceptionForCertificateAtIndex(SecTrustRef trust, CFIndex ix) {
 static CFStringRef kSecCertificateDetailSHA1Digest = CFSTR("SHA1Digest");
 
 static CFDictionaryRef SecTrustGetExceptionForCertificateAtIndex(SecTrustRef trust, CFIndex ix) {
@@ -251,7 +426,7 @@ static CFDictionaryRef SecTrustGetExceptionForCertificateAtIndex(SecTrustRef tru
     if (CFGetTypeID(exception) != CFDictionaryGetTypeID())
         return NULL;
 
     if (CFGetTypeID(exception) != CFDictionaryGetTypeID())
         return NULL;
 
-       SecCertificateRef certificate = SecTrustGetCertificateAtIndex(trust, ix);        
+       SecCertificateRef certificate = SecTrustGetCertificateAtIndex(trust, ix);
     if (!certificate)
         return NULL;
 
     if (!certificate)
         return NULL;
 
@@ -283,51 +458,162 @@ static void SecTrustCheckException(const void *key, const void *value, void *con
 }
 
 OSStatus SecTrustEvaluate(SecTrustRef trust, SecTrustResultType *result) {
 }
 
 OSStatus SecTrustEvaluate(SecTrustRef trust, SecTrustResultType *result) {
-    CFMutableDictionaryRef args_in = NULL;
-    CFTypeRef args_out = NULL;
-    OSStatus status;
+    if (!trust) {
+        return errSecParam;
+    }
+    OSStatus status = SecTrustEvaluateIfNecessary(trust);
+    if (status || !result)
+        return status;
+
+    /* post-process trust result based on exceptions */
+    SecTrustResultType trustResult = trust->_trustResult;
+    if (trustResult == kSecTrustResultUnspecified) {
+        /* If leaf is in exceptions -> proceed, otherwise unspecified. */
+        if (SecTrustGetExceptionForCertificateAtIndex(trust, 0))
+            trustResult = kSecTrustResultProceed;
+    } else if (trustResult == kSecTrustResultRecoverableTrustFailure) {
+        /* If we have exceptions get details and match to exceptions. */
+        CFIndex pathLength = CFArrayGetCount(trust->_details);
+        struct SecTrustCheckExceptionContext context = {};
+        CFIndex ix;
+        for (ix = 0; ix < pathLength; ++ix) {
+            CFDictionaryRef detail = (CFDictionaryRef)CFArrayGetValueAtIndex(trust->_details, ix);
+
+                       if ((ix == 0) && CFDictionaryContainsKey(detail, kSecPolicyCheckBlackListedLeaf))
+                       {
+                               trustResult = kSecTrustResultFatalTrustFailure;
+                               goto DoneCheckingTrust;
+                       }
+                       
+                       if (CFDictionaryContainsKey(detail, kSecPolicyCheckBlackListedKey))
+                       {
+                               trustResult = kSecTrustResultFatalTrustFailure;
+                               goto DoneCheckingTrust;
+                       }
+       
+            context.exception = SecTrustGetExceptionForCertificateAtIndex(trust, ix);
+            CFDictionaryApplyFunction(detail, SecTrustCheckException, &context);
+            if (context.exceptionNotFound) {
+                break;
+            }
+        }
+        if (!context.exceptionNotFound)
+            trustResult = kSecTrustResultProceed;
+    }
+DoneCheckingTrust:
+       trust->_trustResult = trustResult;
+
+#if DEBUG
+    /* log to syslog when there is a trust failure */
+    if (trustResult != kSecTrustResultProceed &&
+        trustResult != kSecTrustResultConfirm &&
+        trustResult != kSecTrustResultUnspecified) {
+        CFStringRef failureDesc = SecTrustCopyFailureDescription(trust);
+        secerror("%@", failureDesc);
+        CFRelease(failureDesc);
+    }
+#endif
 
 
-    check(trust);
-    check(result);
-    CFReleaseNull(trust->_chain);
-    CFReleaseNull(trust->_details);
-    CFReleaseNull(trust->_info);
+    *result = trustResult;
+
+    return status;
+}
+
+OSStatus SecTrustEvaluateAsync(SecTrustRef trust,
+       dispatch_queue_t queue, SecTrustCallback result)
+{
+       dispatch_async(queue, ^{
+               SecTrustResultType trustResult;
+               if (errSecSuccess != SecTrustEvaluate(trust, &trustResult)) {
+                       trustResult = kSecTrustResultInvalid;
+               }
+               result(trust, trustResult);
+       });
+       return errSecSuccess;
+}
+
+static bool SecXPCDictionarySetCertificates(xpc_object_t message, const char *key, CFArrayRef certificates, CFErrorRef *error) {
+    xpc_object_t xpc_certificates = SecCertificateArrayCopyXPCArray(certificates, error);
+    if (!xpc_certificates)
+        return false;
+
+    xpc_dictionary_set_value(message, key, xpc_certificates);
+    xpc_release(xpc_certificates);
+
+    return true;
+}
 
 
-    args_in = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
-        &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+static bool SecXPCDictionarySetPolicies(xpc_object_t message, const char *key, CFArrayRef policies, CFErrorRef *error) {
+    xpc_object_t xpc_policies = SecPolicyArrayCopyXPCArray(policies, error);
+    if (!xpc_policies)
+        return false;
+    xpc_dictionary_set_value(message, key, xpc_policies);
+    xpc_release(xpc_policies);
+    return true;
+}
 
 
-    /* Translate certificates to CFDataRefs. */
-    CFArrayRef certificates = SecCertificateArrayCopyDataArray(trust->_certificates);
-    CFDictionaryAddValue(args_in, kSecTrustCertificatesKey, certificates);
-    CFRelease(certificates);
+static bool SecXPCDictionaryCopyChainOptional(xpc_object_t message, const char *key, SecCertificatePathRef *path, CFErrorRef *error) {
+    xpc_object_t xpc_path = xpc_dictionary_get_value(message, key);
+    if (!xpc_path) {
+        *path = NULL;
+        return true;
+    }
+    *path = SecCertificatePathCreateWithXPCArray(xpc_path, error);
+    return *path;
+}
 
 
-    if (trust->_anchors) {
-        /* Translate anchors to CFDataRefs. */
-        CFArrayRef anchors = SecCertificateArrayCopyDataArray(trust->_anchors);
-        CFDictionaryAddValue(args_in, kSecTrustAnchorsKey, anchors);
-        CFRelease(anchors);
+static int SecXPCDictionaryGetNonZeroInteger(xpc_object_t message, const char *key, CFErrorRef *error) {
+    int64_t value = xpc_dictionary_get_int64(message, key);
+    if (!value) {
+        SecError(errSecInternal, error, CFSTR("object for key %s is 0"), key);
     }
     }
-    if (trust->_anchorsOnly)
-        CFDictionaryAddValue(args_in, kSecTrustAnchorsOnlyKey, kCFBooleanTrue);
+    return (int)value;
+}
 
 
-    /* Translate policies to plist capable CFTypeRefs. */
-    CFArrayRef serializedPolicies = SecPolicyArraySerialize(trust->_policies);
-    CFDictionaryAddValue(args_in, kSecTrustPoliciesKey, serializedPolicies);
-    CFRelease(serializedPolicies);
+static SecTrustResultType certs_anchors_bool_policies_date_ag_to_details_info_chain_int_error_request(enum SecXPCOperation op, CFArrayRef certificates, CFArrayRef anchors, bool anchorsOnly, CFArrayRef policies, CFAbsoluteTime verifyTime, __unused CFArrayRef accessGroups, CFArrayRef *details, CFDictionaryRef *info, SecCertificatePathRef *chain, CFErrorRef *error)
+{
+    __block SecTrustResultType tr = kSecTrustResultInvalid;
+    securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
+        if (!SecXPCDictionarySetCertificates(message, kSecTrustCertificatesKey, certificates, error))
+            return false;
+        if (anchors && !SecXPCDictionarySetCertificates(message, kSecTrustAnchorsKey, anchors, error))
+            return false;
+        if (anchorsOnly)
+            xpc_dictionary_set_bool(message, kSecTrustAnchorsOnlyKey, anchorsOnly);
+        if (!SecXPCDictionarySetPolicies(message, kSecTrustPoliciesKey, policies, error))
+            return false;
+        xpc_dictionary_set_double(message, kSecTrustVerifyDateKey, verifyTime);
+        return true;
+    }, ^bool(xpc_object_t response, CFErrorRef *error) {
+        secdebug("trust", "response: %@", response);
+        return SecXPCDictionaryCopyArrayOptional(response, kSecTrustDetailsKey, details, error) &&
+        SecXPCDictionaryCopyDictionaryOptional(response, kSecTrustInfoKey, info, error) &&
+        SecXPCDictionaryCopyChainOptional(response, kSecTrustChainKey, chain, error) &&
+        ((tr = SecXPCDictionaryGetNonZeroInteger(response, kSecTrustResultKey, error)) != kSecTrustResultInvalid);
+    });
+    return tr;
+}
+
+static OSStatus SecTrustEvaluateIfNecessary(SecTrustRef trust) {
+    check(trust);
+    if (!trust)
+        return errSecParam;
+    
+    if (trust->_trustResult != kSecTrustResultInvalid)
+        return errSecSuccess;
 
 
-    /* Ensure trust->_verifyDate is initialized. */
-    SecTrustGetVerifyTime(trust);
-    CFDictionaryAddValue(args_in, kSecTrustVerifyDateKey, trust->_verifyDate);
+    trust->_trustResult = kSecTrustResultOtherError; /* to avoid potential recursion */
+
+    CFReleaseNull(trust->_chain);
+    CFReleaseNull(trust->_details);
+    CFReleaseNull(trust->_info);
 
     /* @@@ Consider an optimization where we keep a side dictionary with the SHA1 hash of ever SecCertificateRef we send, so we only send potential duplicates once, and have the server respond with either just the SHA1 hash of a certificate, or the complete certificate in the response depending on whether the client already sent it, so we don't send back certificates to the client it already has. */
 
     /* @@@ Consider an optimization where we keep a side dictionary with the SHA1 hash of ever SecCertificateRef we send, so we only send potential duplicates once, and have the server respond with either just the SHA1 hash of a certificate, or the complete certificate in the response depending on whether the client already sent it, so we don't send back certificates to the client it already has. */
-    //status = SECURITYD(sec_trust_evaluate, args_in, &args_out);
-    if (gSecurityd) {
-        status = gSecurityd->sec_trust_evaluate(args_in, &args_out);
-    } else {
-        status = ServerCommandSendReceive(sec_trust_evaluate_id, 
-            args_in, &args_out);
-    }
-    if (status == errSecNotAvailable && CFArrayGetCount(trust->_certificates)) {
+    return SecOSStatusWith(^bool (CFErrorRef *error) {
+        trust->_trustResult = SECURITYD_XPC(sec_trust_evaluate, certs_anchors_bool_policies_date_ag_to_details_info_chain_int_error_request, trust->_certificates, trust->_anchors, trust->_anchorsOnly, trust->_policies, SecTrustGetVerifyTime(trust), SecAccessGroupsGetCurrent(), &trust->_details, &trust->_info, &trust->_chain, error);
+        if (trust->_trustResult == kSecTrustResultInvalid /* TODO check domain */ &&
+            SecErrorGetOSStatus(*error) == errSecNotAvailable &&
+            CFArrayGetCount(trust->_certificates)) {
         /* We failed to talk to securityd.  The only time this should
            happen is when we are running prior to launchd enabling
            registration of services.  This currently happens when we
         /* We failed to talk to securityd.  The only time this should
            happen is when we are running prior to launchd enabling
            registration of services.  This currently happens when we
@@ -335,79 +621,82 @@ OSStatus SecTrustEvaluate(SecTrustRef trust, SecTrustResultType *result) {
            _chain and return success with a failure as the trustResult, to
            make it seem like we did a cert evaluation, so ASR can extract
            the public key from the leaf. */
            _chain and return success with a failure as the trustResult, to
            make it seem like we did a cert evaluation, so ASR can extract
            the public key from the leaf. */
-        trust->_chain = SecCertificatePathCreate(NULL,
-            (SecCertificateRef)CFArrayGetValueAtIndex(trust->_certificates, 0));
-        if (result)
-            *result = kSecTrustResultOtherError;
-        status = noErr;
-        goto errOut;
+            trust->_chain = SecCertificatePathCreate(NULL, (SecCertificateRef)CFArrayGetValueAtIndex(trust->_certificates, 0));
+            if (error)
+                CFReleaseNull(*error);
+            return true;
     }
     }
-
-       require_quiet(args_out, errOut);
-
-       CFArrayRef details = (CFArrayRef)CFDictionaryGetValue(args_out, kSecTrustDetailsKey);
-    if (details) {
-        require(CFGetTypeID(details) == CFArrayGetTypeID(), errOut);
-        CFRetain(details);
-        trust->_details = details;
+        return trust->_trustResult != kSecTrustResultInvalid;
+    });
     }
 
     }
 
-       CFDictionaryRef info = (CFDictionaryRef)CFDictionaryGetValue(args_out, kSecTrustInfoKey);
-    if (info) {
-        require(CFGetTypeID(info) == CFDictionaryGetTypeID(), errOut);
-        CFRetain(info);
-        trust->_info = info;
-    }
+/* Helper for the qsort below. */
+static int compare_strings(const void *a1, const void *a2) {
+    CFStringRef s1 = *(CFStringRef *)a1;
+    CFStringRef s2 = *(CFStringRef *)a2;
+    return (int) CFStringCompare(s1, s2, kCFCompareForcedOrdering);
+}
 
 
-       CFArrayRef chainArray = (CFArrayRef)CFDictionaryGetValue(args_out, kSecTrustChainKey);
-    require(chainArray && CFGetTypeID(chainArray) == CFArrayGetTypeID(), errOut);
-    trust->_chain = SecCertificatePathCreateWithArray(chainArray);
-    require(trust->_chain, errOut);
-
-    CFNumberRef cfResult = (CFNumberRef)CFDictionaryGetValue(args_out, kSecTrustResultKey);
-    require(cfResult && CFGetTypeID(cfResult) == CFNumberGetTypeID(), errOut);
-    if (result) {
-        SInt32 trustResult;
-        CFNumberGetValue(cfResult, kCFNumberSInt32Type, &trustResult);
-        if (trustResult == kSecTrustResultUnspecified) {
-            /* If leaf is in exceptions -> proceed, otherwise unspecified. */
-            if (SecTrustGetExceptionForCertificateAtIndex(trust, 0))
-                trustResult = kSecTrustResultProceed;
-        } else if (trustResult == kSecTrustResultRecoverableTrustFailure) {
-            /* If we have exceptions get details and match to exceptions. */
-            CFIndex pathLength = CFArrayGetCount(details);
-            struct SecTrustCheckExceptionContext context = {};
-            CFIndex ix;
-            for (ix = 0; ix < pathLength; ++ix) {
-                CFDictionaryRef detail = (CFDictionaryRef)CFArrayGetValueAtIndex(details, ix);
-                if ((ix == 0) && CFDictionaryContainsKey(detail, kSecPolicyCheckBlackListedLeaf))
-                    trustResult = kSecTrustResultFatalTrustFailure;
-                context.exception = SecTrustGetExceptionForCertificateAtIndex(trust, ix);
-                CFDictionaryApplyFunction(detail, SecTrustCheckException, &context);
-                if (context.exceptionNotFound) {
-                    break;
-                }
+CFStringRef SecTrustCopyFailureDescription(SecTrustRef trust) {
+    CFMutableStringRef reason = CFStringCreateMutable(NULL, 0);
+    CFArrayRef details = SecTrustGetDetails(trust);
+    CFIndex pathLength = details ? CFArrayGetCount(details) : 0;
+    for (CFIndex ix = 0; ix < pathLength; ++ix) {
+        CFDictionaryRef detail = (CFDictionaryRef)CFArrayGetValueAtIndex(details, ix);
+        CFIndex dCount = CFDictionaryGetCount(detail);
+        if (dCount) {
+            if (ix == 0)
+                CFStringAppend(reason, CFSTR(" [leaf"));
+            else if (ix == pathLength - 1)
+                CFStringAppend(reason, CFSTR(" [root"));
+            else
+                CFStringAppendFormat(reason, NULL, CFSTR(" [ca%" PRIdCFIndex ), ix);
+
+            const void *keys[dCount];
+            CFDictionaryGetKeysAndValues(detail, &keys[0], NULL);
+            qsort(&keys[0], dCount, sizeof(keys[0]), compare_strings);
+            for (CFIndex kix = 0; kix < dCount; ++kix) {
+                CFStringRef key = keys[kix];
+                const void *value = CFDictionaryGetValue(detail, key);
+                CFStringAppendFormat(reason, NULL, CFSTR(" %@%@"), key,
+                                     (CFGetTypeID(value) == CFBooleanGetTypeID()
+                                      ? CFSTR("") : value));
             }
             }
-
-            if (!context.exceptionNotFound)
-                trustResult = kSecTrustResultProceed;
+            CFStringAppend(reason, CFSTR("]"));
         }
         }
-
-        *result = trustResult;
-       }
-
-errOut:
-    CFReleaseSafe(args_out);
-    CFReleaseSafe(args_in);
-       return status;
+    }
+    return reason;
 }
 
 }
 
-
 SecKeyRef SecTrustCopyPublicKey(SecTrustRef trust) {
 SecKeyRef SecTrustCopyPublicKey(SecTrustRef trust) {
-       if (!trust->_publicKey && trust->_chain) {
-               trust->_publicKey = SecCertificatePathCopyPublicKeyAtIndex(
-               trust->_chain, 0);
+    if (!trust) {
+        return NULL;
+    }
+       if (!trust->_publicKey) {
+        if (!trust->_chain) {
+            /* Trust hasn't been evaluated yet, first attempt to retrieve public key from leaf cert as is. */
+            trust->_publicKey = SecCertificateCopyPublicKey(SecTrustGetCertificateAtIndex(trust, 0));
+#if 0
+            if (!trust->_publicKey) {
+                /* If this fails use the passed in certs in order as if they are a valid cert path an attempt to extract the key. */
+                SecCertificatePathRef path;
+                // SecCertificatePathCreateWithArray Would have crashed if this code was every called
+                // since it expected an array of CFDataRefs not an array of certificates.
+                path = SecCertificatePathCreateWithArray(trust->_certificates);
+                trust->_publicKey = SecCertificatePathCopyPublicKeyAtIndex(path, 0);
+                CFRelease(path);
+            }
+#endif
+            if (!trust->_publicKey) {
+                /* Last resort, we evaluate the trust to get a _chain. */
+                SecTrustEvaluateIfNecessary(trust);
+            }
+        }
+        if (trust->_chain) {
+            trust->_publicKey = SecCertificatePathCopyPublicKeyAtIndex(trust->_chain, 0);
+        }
        }
        }
+
        if (trust->_publicKey)
                CFRetain(trust->_publicKey);
 
        if (trust->_publicKey)
                CFRetain(trust->_publicKey);
 
@@ -415,20 +704,30 @@ SecKeyRef SecTrustCopyPublicKey(SecTrustRef trust) {
 }
 
 CFIndex SecTrustGetCertificateCount(SecTrustRef trust) {
 }
 
 CFIndex SecTrustGetCertificateCount(SecTrustRef trust) {
-       return trust->_chain ? SecCertificatePathGetCount(trust->_chain) : 1;
+    if (!trust) {
+        return 0;
+    }
+    SecTrustEvaluateIfNecessary(trust);
+       return (trust->_chain) ? SecCertificatePathGetCount(trust->_chain) : 1;
 }
 
 SecCertificateRef SecTrustGetCertificateAtIndex(SecTrustRef trust,
     CFIndex ix) {
 }
 
 SecCertificateRef SecTrustGetCertificateAtIndex(SecTrustRef trust,
     CFIndex ix) {
-    if (trust->_chain)
-        return SecCertificatePathGetCertificateAtIndex(trust->_chain, ix);
-    else if (ix == 0)
-        return (SecCertificateRef)CFArrayGetValueAtIndex(trust->_certificates, 0);
-    else
+    if (!trust) {
         return NULL;
         return NULL;
+    }
+    if (ix == 0) {
+        return (SecCertificateRef)CFArrayGetValueAtIndex(trust->_certificates, 0);
+    }
+    SecTrustEvaluateIfNecessary(trust);
+    return (trust->_chain) ? SecCertificatePathGetCertificateAtIndex(trust->_chain, ix) : NULL;
 }
 
 CFDictionaryRef SecTrustCopyInfo(SecTrustRef trust) {
 }
 
 CFDictionaryRef SecTrustCopyInfo(SecTrustRef trust) {
+    if (!trust) {
+        return NULL;
+    }
+    SecTrustEvaluateIfNecessary(trust);
     CFDictionaryRef info = trust->_info;
     if (info)
         CFRetain(info);
     CFDictionaryRef info = trust->_info;
     if (info)
         CFRetain(info);
@@ -436,9 +735,8 @@ CFDictionaryRef SecTrustCopyInfo(SecTrustRef trust) {
 }
 
 CFDataRef SecTrustCopyExceptions(SecTrustRef trust) {
 }
 
 CFDataRef SecTrustCopyExceptions(SecTrustRef trust) {
-
     CFArrayRef details = SecTrustGetDetails(trust);
     CFArrayRef details = SecTrustGetDetails(trust);
-    CFIndex pathLength = CFArrayGetCount(details);
+    CFIndex pathLength = details ? CFArrayGetCount(details) : 0;
     CFMutableArrayRef exceptions = CFArrayCreateMutable(kCFAllocatorDefault, pathLength, &kCFTypeArrayCallBacks);
     CFIndex ix;
     for (ix = 0; ix < pathLength; ++ix) {
     CFMutableArrayRef exceptions = CFArrayCreateMutable(kCFAllocatorDefault, pathLength, &kCFTypeArrayCallBacks);
     CFIndex ix;
     for (ix = 0; ix < pathLength; ++ix) {
@@ -461,7 +759,7 @@ CFDataRef SecTrustCopyExceptions(SecTrustRef trust) {
 
     /* Remove any trailing empty dictionaries to save even more space (we skip the leaf
        since it will never be empty). */
 
     /* Remove any trailing empty dictionaries to save even more space (we skip the leaf
        since it will never be empty). */
-    for (ix = pathLength - 1; ix > 0; --ix) {
+    for (ix = pathLength; ix-- > 1;) {
         CFDictionaryRef exception = (CFDictionaryRef)CFArrayGetValueAtIndex(exceptions, ix);
         if (CFDictionaryGetCount(exception) == 0) {
             CFArrayRemoveValueAtIndex(exceptions, ix);
         CFDictionaryRef exception = (CFDictionaryRef)CFArrayGetValueAtIndex(exceptions, ix);
         if (CFDictionaryGetCount(exception) == 0) {
             CFArrayRemoveValueAtIndex(exceptions, ix);
@@ -478,13 +776,20 @@ CFDataRef SecTrustCopyExceptions(SecTrustRef trust) {
 }
 
 bool SecTrustSetExceptions(SecTrustRef trust, CFDataRef encodedExceptions) {
 }
 
 bool SecTrustSetExceptions(SecTrustRef trust, CFDataRef encodedExceptions) {
-    CFArrayRef exceptions;
-    exceptions = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, encodedExceptions, kCFPropertyListImmutable, NULL);
+       if (!trust) {
+               return false;
+       }
+       CFArrayRef exceptions = NULL;
+       
+       if (NULL != encodedExceptions) {
+               exceptions = CFPropertyListCreateWithData(kCFAllocatorDefault,
+                       encodedExceptions, kCFPropertyListImmutable, NULL, NULL);
+       }
+       
     if (exceptions && CFGetTypeID(exceptions) != CFArrayGetTypeID()) {
         CFRelease(exceptions);
         exceptions = NULL;
     }
     if (exceptions && CFGetTypeID(exceptions) != CFArrayGetTypeID()) {
         CFRelease(exceptions);
         exceptions = NULL;
     }
-
     CFReleaseSafe(trust->_exceptions);
     trust->_exceptions = exceptions;
 
     CFReleaseSafe(trust->_exceptions);
     trust->_exceptions = exceptions;
 
@@ -671,6 +976,7 @@ static void appendError(CFMutableArrayRef properties, CFStringRef error) {
         CFSTR("SecCertificate"));
     appendProperty(properties, kSecPropertyTypeError, NULL, NULL,
                    localizedError);
         CFSTR("SecCertificate"));
     appendProperty(properties, kSecPropertyTypeError, NULL, NULL,
                    localizedError);
+    CFReleaseNull(localizedError);
 }
 
 CFArrayRef SecTrustCopyProperties(SecTrustRef trust) {
 }
 
 CFArrayRef SecTrustCopyProperties(SecTrustRef trust) {
@@ -721,10 +1027,124 @@ CFArrayRef SecTrustCopyProperties(SecTrustRef trust) {
     return properties;
 }
 
     return properties;
 }
 
+CFDictionaryRef SecTrustCopyResult(SecTrustRef trust) {
+       // Builds and returns a dictionary of evaluation results.
+       if (!trust) {
+               return NULL;
+       }
+       CFMutableDictionaryRef results = CFDictionaryCreateMutable(NULL, 0,
+                       &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+
+       // kSecTrustResultDetails (per-cert results)
+       CFArrayRef details = SecTrustGetDetails(trust);
+       if (details) {
+               CFDictionarySetValue(results, (const void *)kSecTrustResultDetails, (const void *)details);
+       }
+
+       // kSecTrustResultValue (overall trust result)
+       CFNumberRef numValue = CFNumberCreate(NULL, kCFNumberSInt32Type, &trust->_trustResult);
+       if (numValue) {
+               CFDictionarySetValue(results, (const void *)kSecTrustResultValue, (const void *)numValue);
+               CFRelease(numValue);
+       }
+       if (trust->_trustResult == kSecTrustResultInvalid || !trust->_info)
+               return results; // we have nothing more to add
+
+       // kSecTrustEvaluationDate
+       CFDateRef evaluationDate = trust->_verifyDate;
+       if (evaluationDate) {
+               CFDictionarySetValue(results, (const void *)kSecTrustEvaluationDate, (const void *)evaluationDate);
+       }
+
+       // kSecTrustExtendedValidation, kSecTrustOrganizationName
+       CFDictionaryRef info = trust->_info;
+       if (info) {
+               CFBooleanRef evValue;
+               if (CFDictionaryGetValueIfPresent(info, kSecTrustInfoExtendedValidationKey, (const void **)&evValue)) {
+                       CFDictionarySetValue(results, (const void *)kSecTrustExtendedValidation, (const void *)evValue);
+               }
+               CFStringRef organizationName;
+               if (CFDictionaryGetValueIfPresent(info, kSecTrustInfoCompanyNameKey, (const void **)&organizationName)) {
+                       CFDictionarySetValue(results, (const void *)kSecTrustOrganizationName, (const void *)organizationName);
+               }
+       }
+
+#if 0
+//FIXME: need to add revocation results here
+       // kSecTrustRevocationChecked, kSecTrustRevocationValidUntilDate
+       CFTypeRef expirationDate;
+       if (CFDictionaryGetValueIfPresent(mExtendedResult, kSecTrustExpirationDate, (const void **)&expirationDate)) {
+               CFDictionarySetValue(results, (const void *)kSecTrustRevocationValidUntilDate, (const void *)expirationDate);
+               CFDictionarySetValue(results, (const void *)kSecTrustRevocationChecked, (const void *)kCFBooleanTrue);
+       }
+#endif
+
+       return results;
+}
+
+// Return 0 upon error.
+static int to_int_error_request(enum SecXPCOperation op, CFErrorRef *error) {
+    __block int64_t result = 0;
+    securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
+        result = xpc_dictionary_get_int64(response, kSecXPCKeyResult);
+        if (!result)
+            return SecError(errSecInternal, error, CFSTR("int64 missing in response"));
+        return true;
+    });
+    return (int)result;
+}
 
 
+// version 0 -> error, so we need to start at version 1 or later.
+OSStatus SecTrustGetOTAPKIAssetVersionNumber(int* versionNumber)
+{
+    return SecOSStatusWith(^bool(CFErrorRef *error) {
+        if (!versionNumber)
+            return SecError(errSecParam, error, CFSTR("versionNumber is NULL"));
+
+        return (*versionNumber = SECURITYD_XPC(sec_ota_pki_asset_version, to_int_error_request, error)) != 0;
+    });
+}
+
+#define do_if_registered(sdp, ...) if (gSecurityd && gSecurityd->sdp) { return gSecurityd->sdp(__VA_ARGS__); }
+
+static bool xpc_dictionary_entry_is_type(xpc_object_t dictionary, const char *key, xpc_type_t type)
+{
+    xpc_object_t value = xpc_dictionary_get_value(dictionary, key);
+    
+    return value && (xpc_get_type(value) == type);
+}
+               
+OSStatus SecTrustOTAPKIGetUpdatedAsset(int* didUpdateAsset)
+{
+       CFErrorRef error = NULL;
+       do_if_registered(sec_ota_pki_get_new_asset, &error);
+       
+       int64_t num = 0;
+    xpc_object_t message = securityd_create_message(kSecXPCOpOTAPKIGetNewAsset, &error);
+    if (message) 
+       {
+        xpc_object_t response = securityd_message_with_reply_sync(message, &error);
+        
+        if (response && xpc_dictionary_entry_is_type(response, kSecXPCKeyResult, XPC_TYPE_INT64)) 
+               {
+            num = (int64_t) xpc_dictionary_get_int64(response, kSecXPCKeyResult);
+                       xpc_release(response);
+        } 
+       
+        xpc_release(message);
+       }
+
+       if (NULL != didUpdateAsset)
+       {
+               *didUpdateAsset = (int)num;
+       }
+       return noErr;
+}
+
+               
 #if 0
 #if 0
-#pragma mark -
-#pragma mark SecTrustNode
+// MARK: -
+// MARK: SecTrustNode
 /********************************************************
  **************** SecTrustNode object *******************
  ********************************************************/
 /********************************************************
  **************** SecTrustNode object *******************
  ********************************************************/
@@ -776,11 +1196,11 @@ struct __SecTrustNode {
 };
 typedef struct __SecTrustNode SecTrustNode;
 
 };
 typedef struct __SecTrustNode SecTrustNode;
 
-/* CFRuntime regsitration data. */
+/* CFRuntime registration data. */
 static pthread_once_t kSecTrustNodeRegisterClass = PTHREAD_ONCE_INIT;
 static CFTypeID kSecTrustNodeTypeID = _kCFRuntimeNotATypeID;
 
 static pthread_once_t kSecTrustNodeRegisterClass = PTHREAD_ONCE_INIT;
 static CFTypeID kSecTrustNodeTypeID = _kCFRuntimeNotATypeID;
 
-/* Forward declartions of static functions. */
+/* Forward declarations of static functions. */
 static CFStringRef SecTrustNodeDescribe(CFTypeRef cf);
 static void SecTrustNodeDestroy(CFTypeRef cf);
 
 static CFStringRef SecTrustNodeDescribe(CFTypeRef cf);
 static void SecTrustNodeDestroy(CFTypeRef cf);
 
@@ -904,7 +1324,7 @@ SecTrustNodeRef SecTrustNodeCopyNextCandidate(SecTrustNodeRef node,
                 CFRelease(parent);
                 /* If another signature failed further down the chain we need
                    to backtrack down to whatever child is still a valid
                 CFRelease(parent);
                 /* If another signature failed further down the chain we need
                    to backtrack down to whatever child is still a valid
-                   candidate and has additional candidates to consider. 
+                   candidate and has additional candidates to consider.
                    @@@ We really want to make the fetchingState a global of
                    SecTrust itself as well and not have any node go beyond the
                    current state of SecTrust if there are other (read cheap)
                    @@@ We really want to make the fetchingState a global of
                    SecTrust itself as well and not have any node go beyond the
                    current state of SecTrust if there are other (read cheap)
@@ -992,7 +1412,7 @@ SecTrustNodeRef SecTrustNodeCopyNextCandidate(SecTrustNodeRef node,
            if we can find one in the local database. */
     }
 
            if we can find one in the local database. */
     }
 
-    return noErr;
+    return errSecSuccess;
 }
 
 CFArrayRef SecTrustNodeCopyNextChain(SecTrustNodeRef node,
 }
 
 CFArrayRef SecTrustNodeCopyNextChain(SecTrustNodeRef node,
@@ -1126,7 +1546,7 @@ class PathBuilder {
                        Nodes.sortBySize();
                        nit = nodes.begin();
                        /* Set the source list for all nodes. */
                        Nodes.sortBySize();
                        nit = nodes.begin();
                        /* Set the source list for all nodes. */
-                       
+
                }
                while (Node node = *nit) {
                        Node candidate = node.nextParent(currentSources);
                }
                while (Node node = *nit) {
                        Node candidate = node.nextParent(currentSources);
index acce22edae749b08b6cced5e18bee37dd6a498b5..2a114907b17f89a25f7871e537adbd76f3c0e1cb 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2002-2010 Apple Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2002-2010,2012-2013 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
 /*!
  * @APPLE_LICENSE_HEADER_END@
  */
 
 /*!
-       @header SecTrust
-       The functions and data types in SecTrust implement trust computation
-    and allow the user to apply trust decisions to the trust configuration.
-*/
+    @header SecTrust
+    The functions and data types in SecTrust implement trust computation
+    and allow the caller to apply trust decisions to the evaluation.
+ */
 
 #ifndef _SECURITY_SECTRUST_H_
 #define _SECURITY_SECTRUST_H_
 
 #include <Security/SecBase.h>
 
 #ifndef _SECURITY_SECTRUST_H_
 #define _SECURITY_SECTRUST_H_
 
 #include <Security/SecBase.h>
-#include <CoreFoundation/CFArray.h>
-#include <CoreFoundation/CFData.h>
-#include <CoreFoundation/CFDate.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <AvailabilityMacros.h>
 
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 /*!
 
 /*!
-       @typedef SecTrustResultType
-       @abstract Specifies the trust result type.
+    @typedef SecTrustResultType
+    @abstract Specifies the trust result type.
     @discussion SecTrustResultType results have two dimensions.  They specify
     both whether evaluation suceeded and whether this is because of a user
     @discussion SecTrustResultType results have two dimensions.  They specify
     both whether evaluation suceeded and whether this is because of a user
-    decision.  In practice the commonly expected result is kSecTrustResultUnspecified, 
+    decision.  The commonly expected result is kSecTrustResultUnspecified,
     which indicates a positive result that wasn't decided by the user.  The
     common failure is kSecTrustResultRecoverableTrustFailure, which means a
     negative result.  kSecTrustResultProceed and kSecTrustResultDeny are the
     positive and negative result respectively when decided by the user.  User
     decisions are persisted through the use of SecTrustCopyExceptions() and
     which indicates a positive result that wasn't decided by the user.  The
     common failure is kSecTrustResultRecoverableTrustFailure, which means a
     negative result.  kSecTrustResultProceed and kSecTrustResultDeny are the
     positive and negative result respectively when decided by the user.  User
     decisions are persisted through the use of SecTrustCopyExceptions() and
-    SecTrustSetExceptions().  Finally kSecTrustResultFatalTrustFailure is a
-    negative result that should not be circumvented.  In fact only in the case
-    of kSecTrustResultRecoverableTrustFailure should a user ever be asked.
-       @constant kSecTrustResultInvalid Indicates an invalid setting or result.
-       @constant kSecTrustResultProceed Indicates you may proceed.  This value
+    SecTrustSetExceptions().  Finally, kSecTrustResultFatalTrustFailure is a
+    negative result that must not be circumvented.
+    @constant kSecTrustResultInvalid Indicates an invalid setting or result.
+    This result usually means that SecTrustEvaluate has not yet been called.
+    @constant kSecTrustResultProceed Indicates you may proceed.  This value
     may be returned by the SecTrustEvaluate function or stored as part of
     may be returned by the SecTrustEvaluate function or stored as part of
-    the user trust settings. 
-       @constant kSecTrustResultConfirm Indicates confirmation with the user
-    is required before proceeding.  This value may be returned by the
-    SecTrustEvaluate function or stored as part of the user trust settings. 
-       @constant kSecTrustResultDeny Indicates a user-configured deny; do not
+    the user trust settings.
+    @constant kSecTrustResultConfirm Indicates confirmation with the user
+    is required before proceeding.  Important: this value is no longer returned
+    or supported by SecTrustEvaluate or the SecTrustSettings API starting in
+    OS X 10.5; its use is deprecated in OS X 10.9 and later, as well as in iOS.
+    @constant kSecTrustResultDeny Indicates a user-configured deny; do not
     proceed. This value may be returned by the SecTrustEvaluate function
     proceed. This value may be returned by the SecTrustEvaluate function
-    or stored as part of the user trust settings. 
-       @constant kSecTrustResultUnspecified Indicates user intent is unknown.
-    This value may be returned by the SecTrustEvaluate function or stored
-    as part of the user trust settings. 
-       @constant kSecTrustResultRecoverableTrustFailure Indicates a trust
-    framework failure; retry after fixing inputs. This value may be returned
+    or stored as part of the user trust settings.
+    @constant kSecTrustResultUnspecified Indicates the evaluation succeeded
+    and the certificate is implicitly trusted, but user intent was not
+    explicitly specified.  This value may be returned by the SecTrustEvaluate
+    function or stored as part of the user trust settings.
+    @constant kSecTrustResultRecoverableTrustFailure Indicates a trust policy
+    failure which can be overridden by the user.  This value may be returned
     by the SecTrustEvaluate function but not stored as part of the user
     by the SecTrustEvaluate function but not stored as part of the user
-    trust settings. 
-       @constant kSecTrustResultFatalTrustFailure Indicates a trust framework
-    failure; no "easy" fix. This value may be returned by the
+    trust settings.
+    @constant kSecTrustResultFatalTrustFailure Indicates a trust failure
+    which cannot be overridden by the user.  This value may be returned by the
     SecTrustEvaluate function but not stored as part of the user trust
     settings.
     SecTrustEvaluate function but not stored as part of the user trust
     settings.
-       @constant kSecTrustResultOtherError Indicates a failure other than that
+    @constant kSecTrustResultOtherError Indicates a failure other than that
     of trust evaluation. This value may be returned by the SecTrustEvaluate
     function but not stored as part of the user trust settings.
  */
     of trust evaluation. This value may be returned by the SecTrustEvaluate
     function but not stored as part of the user trust settings.
  */
-typedef UInt32 SecTrustResultType;
+typedef uint32_t SecTrustResultType;
 enum {
 enum {
-    kSecTrustResultInvalid,
-    kSecTrustResultProceed,
-    kSecTrustResultConfirm,
-    kSecTrustResultDeny,
-    kSecTrustResultUnspecified,
-    kSecTrustResultRecoverableTrustFailure,
-    kSecTrustResultFatalTrustFailure,
-    kSecTrustResultOtherError
+    kSecTrustResultInvalid = 0,
+    kSecTrustResultProceed = 1,
+    kSecTrustResultConfirm SEC_DEPRECATED_ATTRIBUTE = 2,
+    kSecTrustResultDeny = 3,
+    kSecTrustResultUnspecified = 4,
+    kSecTrustResultRecoverableTrustFailure = 5,
+    kSecTrustResultFatalTrustFailure = 6,
+    kSecTrustResultOtherError = 7
 };
 
 };
 
-
 /*!
 /*!
-       @typedef SecTrustRef
-       @abstract CFType used for performing X.509 certificate trust evaluations.
-*/
+    @typedef SecTrustRef
+    @abstract CFType used for performing X.509 certificate trust evaluations.
+ */
 typedef struct __SecTrust *SecTrustRef;
 
 /*!
 typedef struct __SecTrust *SecTrustRef;
 
 /*!
-       @function SecTrustGetTypeID
-       @abstract Returns the type identifier of SecTrust instances.
-       @result The CFTypeID of SecTrust instances.
-*/
+    @enum Trust Property Constants
+    @discussion Predefined key constants used to obtain values in a
+        per-certificate dictionary of trust evaluation results,
+        as retrieved from a call to SecTrustCopyProperties.
+    @constant kSecPropertyTypeTitle Specifies a key whose value is a
+        CFStringRef containing the title (display name) of this certificate.
+    @constant kSecPropertyTypeError Specifies a key whose value is a
+        CFStringRef containing the reason for a trust evaluation failure.
+ */
+extern CFTypeRef kSecPropertyTypeTitle
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0);
+extern CFTypeRef kSecPropertyTypeError
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0);
+
+/*!
+    @enum Trust Result Constants
+    @discussion Predefined key constants used to obtain values in a
+        dictionary of trust evaluation results for a certificate chain,
+        as retrieved from a call to SecTrustCopyResult.
+    @constant kSecTrustEvaluationDate
+        This key will be present if a trust evaluation has been performed
+        and results are available. Its value is a CFDateRef representing
+        when the evaluation for this trust object took place.
+    @constant kSecTrustExtendedValidation
+        This key will be present and have a value of kCFBooleanTrue
+        if this chain was validated for EV.
+    @constant kSecTrustOrganizationName
+        Organization name field of subject of leaf certificate. This
+        field is meant to be displayed to the user as the validated
+        name of the company or entity that owns the certificate if the
+        kSecTrustExtendedValidation key is present.
+    @constant kSecTrustResultValue
+        This key will be present if a trust evaluation has been performed.
+        Its value is a CFNumberRef representing the SecTrustResultType result
+        for the evaluation.
+    @constant kSecTrustRevocationChecked
+        This key will be present iff this chain had its revocation checked.
+        The value will be a kCFBooleanTrue if revocation checking was
+        successful and none of the certificates in the chain were revoked.
+        The value will be kCFBooleanFalse if no current revocation status
+        could be obtained for one or more certificates in the chain due
+        to connection problems or timeouts.  This is a hint to a client
+        to retry revocation checking at a later time.
+    @constant kSecTrustRevocationValidUntilDate
+        This key will be present iff kSecTrustRevocationChecked has a
+        value of kCFBooleanTrue. The value will be a CFDateRef representing
+        the earliest date at which the revocation info for one of the
+        certificates in this chain might change.
+ */
+extern CFTypeRef kSecTrustEvaluationDate
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFTypeRef kSecTrustExtendedValidation
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFTypeRef kSecTrustOrganizationName
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFTypeRef kSecTrustResultValue
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFTypeRef kSecTrustRevocationChecked
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+extern CFTypeRef kSecTrustRevocationValidUntilDate
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+
+#ifdef __BLOCKS__
+/*!
+    @typedef SecTrustCallback
+    @abstract Delivers the result from an asynchronous trust evaluation.
+    @param trustRef A reference to the trust object which has been evaluated.
+    @param trustResult The trust result of the evaluation. Additional status
+    information can be obtained by calling SecTrustCopyProperties().
+ */
+typedef void (^SecTrustCallback)(SecTrustRef trustRef, SecTrustResultType trustResult);
+#endif /* __BLOCKS__ */
+
+
+/*!
+    @function SecTrustGetTypeID
+    @abstract Returns the type identifier of SecTrust instances.
+    @result The CFTypeID of SecTrust instances.
+ */
 CFTypeID SecTrustGetTypeID(void)
     __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_2_0);
 
 /*!
 CFTypeID SecTrustGetTypeID(void)
     __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_2_0);
 
 /*!
-       @function SecTrustCreateWithCertificates
-       @abstract Creates a trust object based on the given certificates and
+    @function SecTrustCreateWithCertificates
+    @abstract Creates a trust object based on the given certificates and
     policies.
     @param certificates The group of certificates to verify.  This can either
     be a CFArrayRef of SecCertificateRef objects or a single SecCertificateRef
     @param policies An array of one or more policies. You may pass a
     SecPolicyRef to represent a single policy.
     policies.
     @param certificates The group of certificates to verify.  This can either
     be a CFArrayRef of SecCertificateRef objects or a single SecCertificateRef
     @param policies An array of one or more policies. You may pass a
     SecPolicyRef to represent a single policy.
-       @param trustRef On return, a pointer to the trust management reference.
-       @result A result code.  See "Security Error Codes" (SecBase.h).
+    @param trust On return, a pointer to the trust management reference.
+    @result A result code.  See "Security Error Codes" (SecBase.h).
     @discussion If multiple policies are passed in, all policies must verify
     for the chain to be considered valid.
     @discussion If multiple policies are passed in, all policies must verify
     for the chain to be considered valid.
-*/
+ */
 OSStatus SecTrustCreateWithCertificates(CFTypeRef certificates,
 OSStatus SecTrustCreateWithCertificates(CFTypeRef certificates,
-    CFTypeRef policies, SecTrustRef *trustRef)
+    CFTypeRef policies, SecTrustRef *trust)
     __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_2_0);
 
 /*!
     __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_2_0);
 
 /*!
-       @function SecTrustSetAnchorCertificates
-       @abstract Sets the anchor certificates for a given trust.
-       @param trust A reference to a trust object.
-       @param anchorCertificates An array of anchor certificates.
-       @result A result code.  See "Security Error Codes" (SecBase.h).
+    @function SecTrustSetPolicies
+    @abstract Set the policies for which trust should be verified.
+    @param trust A trust reference.
+    @param policies An array of one or more policies. You may pass a
+    SecPolicyRef to represent a single policy.
+    @result A result code. See "Security Error Codes" (SecBase.h).
+    @discussion This function will invalidate the existing trust result,
+    requiring a fresh evaluation for the newly-set policies.
+ */
+OSStatus SecTrustSetPolicies(SecTrustRef trust, CFTypeRef policies)
+    __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_6_0);
+
+/*!
+    @function SecTrustCopyPolicies
+    @abstract Returns an array of policies used for this evaluation.
+    @param trust  A reference to a trust object.
+    @param policies On return, an array of policies used by this trust.
+    Call the CFRelease function to release this reference.
+    @result A result code. See "Security Error Codes" (SecBase.h).
+ */
+OSStatus SecTrustCopyPolicies(SecTrustRef trust, CFArrayRef *policies)
+    __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_7_0);
+
+/*!
+    @function SecTrustSetNetworkFetchAllowed
+    @abstract Specifies whether a trust evaluation is permitted to fetch missing
+    intermediate certificates from the network.
+    @param trust A trust reference.
+    @param allowFetch If true, and a certificate's issuer is not present in the
+    trust reference but its network location is known, the evaluation is permitted
+    to attempt to download it automatically. Pass false to disable network fetch
+    for this trust evaluation.
+    @result A result code. See "Security Error Codes" (SecBase.h).
+    @discussion By default, network fetch of missing certificates is enabled if
+    the trust evaluation includes the SSL policy, otherwise it is disabled.
+ */
+OSStatus SecTrustSetNetworkFetchAllowed(SecTrustRef trust,
+    Boolean allowFetch)
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+
+/*!
+    @function SecTrustGetNetworkFetchAllowed
+    @abstract Returns whether a trust evaluation is permitted to fetch missing
+    intermediate certificates from the network.
+    @param trust A trust reference.
+    @param allowFetch On return, the boolean pointed to by this parameter is
+    set to true if the evaluation is permitted to download missing certificates.
+    @result A result code. See "Security Error Codes" (SecBase.h).
+    @discussion By default, network fetch of missing certificates is enabled if
+    the trust evaluation includes the SSL policy, otherwise it is disabled.
+ */
+OSStatus SecTrustGetNetworkFetchAllowed(SecTrustRef trust,
+    Boolean *allowFetch)
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+
+/*!
+    @function SecTrustSetAnchorCertificates
+    @abstract Sets the anchor certificates for a given trust.
+    @param trust A reference to a trust object.
+    @param anchorCertificates An array of anchor certificates.
+    @result A result code.  See "Security Error Codes" (SecBase.h).
     @discussion Calling this function without also calling
     SecTrustSetAnchorCertificatesOnly() will disable trusting any
     anchors other than the ones in anchorCertificates.
     @discussion Calling this function without also calling
     SecTrustSetAnchorCertificatesOnly() will disable trusting any
     anchors other than the ones in anchorCertificates.
-*/
+ */
 OSStatus SecTrustSetAnchorCertificates(SecTrustRef trust,
     CFArrayRef anchorCertificates)
     __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_2_0);
 
 /*!
 OSStatus SecTrustSetAnchorCertificates(SecTrustRef trust,
     CFArrayRef anchorCertificates)
     __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_2_0);
 
 /*!
-       @function SecTrustSetAnchorCertificatesOnly
-       @abstract Reenables trusting anchor certificates in addition to those
+    @function SecTrustSetAnchorCertificatesOnly
+    @abstract Reenables trusting anchor certificates in addition to those
     passed in via the SecTrustSetAnchorCertificates API.
     passed in via the SecTrustSetAnchorCertificates API.
-       @param trust A reference to a trust object.
-       @param anchorCertificatesOnly If true, disables trusting any anchors other
+    @param trust A reference to a trust object.
+    @param anchorCertificatesOnly If true, disables trusting any anchors other
     than the ones passed in via SecTrustSetAnchorCertificates().  If false,
     the built in anchor certificates are also trusted.
     than the ones passed in via SecTrustSetAnchorCertificates().  If false,
     the built in anchor certificates are also trusted.
-       @result A result code.  See "Security Error Codes" (SecBase.h).
-*/
+    @result A result code.  See "Security Error Codes" (SecBase.h).
+ */
 OSStatus SecTrustSetAnchorCertificatesOnly(SecTrustRef trust,
     Boolean anchorCertificatesOnly)
     __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
 
 /*!
 OSStatus SecTrustSetAnchorCertificatesOnly(SecTrustRef trust,
     Boolean anchorCertificatesOnly)
     __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
 
 /*!
-       @function SecTrustSetVerifyDate
-       @abstract Set the date on which the trust should be verified.
-       @param trust A reference to a trust object.
-       @param verifyDate The date on which to verify trust.
-       @result A result code.  See "Security Error Codes" (SecBase.h).
-    @discussion If this function is not called the time at which
-    SecTrustEvaluate() is called is used implicitly as the verification time.
-*/
+    @function SecTrustCopyCustomAnchorCertificates
+    @abstract Returns an array of custom anchor certificates used by a given
+    trust, as set by a prior call to SecTrustSetAnchorCertificates, or NULL if
+    no custom anchors have been specified.
+    @param trust  A reference to a trust object.
+    @param anchors On return, an array of custom anchor certificates (roots)
+    used by this trust, or NULL if no custom anchors have been specified. Call
+    the CFRelease function to release this reference.
+    @result A result code. See "Security Error Codes" (SecBase.h).
+ */
+OSStatus SecTrustCopyCustomAnchorCertificates(SecTrustRef trust,
+    CFArrayRef *anchors)
+    __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_7_0);
+
+/*!
+    @function SecTrustSetVerifyDate
+    @abstract Set the date for which the trust should be verified.
+    @param trust A reference to a trust object.
+    @param verifyDate The date for which to verify trust.
+    @result A result code.  See "Security Error Codes" (SecBase.h).
+    @discussion This function lets you evaluate certificate validity for a
+    given date (for example, to determine if a signature was valid on the date
+    it was signed, even if the certificate has since expired.) If this function
+    is not called, the time at which SecTrustEvaluate() is called is used
+    implicitly as the verification time.
+ */
 OSStatus SecTrustSetVerifyDate(SecTrustRef trust, CFDateRef verifyDate)
     __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_2_0);
 
 /*!
 OSStatus SecTrustSetVerifyDate(SecTrustRef trust, CFDateRef verifyDate)
     __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_2_0);
 
 /*!
-       @function SecTrustGetVerifyTime
-       @abstract Returns the verify time.
-       @param trust A reference to the trust object to verify.
-       @result A CFAbsoluteTime value representing the time at which certificates
-       should be checked for validity.
-*/
+    @function SecTrustGetVerifyTime
+    @abstract Returns the verify time.
+    @param trust A reference to the trust object being verified.
+    @result A CFAbsoluteTime value representing the time at which certificates
+    should be checked for validity.
+    @discussion This function retrieves the verification time for the given
+    trust reference, as set by a prior call to SecTrustSetVerifyDate(). If the
+    verification time has not been set, this function returns a value of 0,
+    indicating that the current date/time is implicitly used for verification.
+ */
 CFAbsoluteTime SecTrustGetVerifyTime(SecTrustRef trust)
     __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
 
 /*!
 CFAbsoluteTime SecTrustGetVerifyTime(SecTrustRef trust)
     __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
 
 /*!
-       @function SecTrustEvaluate
-       @abstract Evaluates a trust.
-       @param trust A reference to the trust object to evaluate.
-       @param result A pointer to a result type.
-       @result A result code.  See "Security Error Codes" (SecBase.h). 
-*/
+    @function SecTrustEvaluate
+    @abstract Evaluates a trust reference synchronously.
+    @param trust A reference to the trust object to evaluate.
+    @param result A pointer to a result type.
+    @result A result code. See "Security Error Codes" (SecBase.h).
+    @discussion This function will completely evaluate trust before returning,
+    possibly including network access to fetch intermediate certificates or to
+    perform revocation checking. Since this function can block during those
+    operations, you should call it from within a function that is placed on a
+    dispatch queue, or in a separate thread from your application's main
+    run loop. Alternatively, you can use the SecTrustEvaluateAsync function.
+ */
 OSStatus SecTrustEvaluate(SecTrustRef trust, SecTrustResultType *result)
     __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_2_0);
 
 OSStatus SecTrustEvaluate(SecTrustRef trust, SecTrustResultType *result)
     __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_2_0);
 
+#ifdef __BLOCKS__
 /*!
 /*!
-       @function SecTrustCopyPublicKey
-       @abstract Return the public key for a leaf certificate after it has 
-       been evaluated.
-       @param trust A reference to the trust object which has been evaluated.
-       @result The certificate's public key, or NULL if it the public key could
-       not be extracted (this can happen with DSA certificate chains if the
-        parameters in the chain cannot be found).  The caller is responsible
-        for calling CFRelease on the returned key when it is no longer needed.
-*/
+    @function SecTrustEvaluateAsync
+    @abstract Evaluates a trust reference asynchronously.
+    @param trust A reference to the trust object to evaluate.
+    @param queue A dispatch queue on which the result callback should be
+    executed. Pass NULL to use the current dispatch queue.
+    @param result A SecTrustCallback block which will be executed when the
+    trust evaluation is complete.
+    @result A result code. See "Security Error Codes" (SecBase.h).
+ */
+OSStatus SecTrustEvaluateAsync(SecTrustRef trust,
+    dispatch_queue_t queue, SecTrustCallback result)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0);
+#endif
+
+/*!
+    @function SecTrustGetTrustResult
+    @param trust A reference to a trust object.
+    @param result A pointer to the result from the most recent call to
+    SecTrustEvaluate for this trust reference. If SecTrustEvaluate has not been
+    called or trust parameters have changed, the result is kSecTrustResultInvalid.
+    @result A result code. See "Security Error Codes" (SecBase.h).
+    @discussion This function replaces SecTrustGetResult for the purpose of
+    obtaining the current evaluation result of a given trust reference.
+ */
+OSStatus SecTrustGetTrustResult(SecTrustRef trust,
+    SecTrustResultType *result)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0);
+
+/*!
+    @function SecTrustCopyPublicKey
+    @abstract Return the public key for a leaf certificate after it has
+    been evaluated.
+    @param trust A reference to the trust object which has been evaluated.
+    @result The certificate's public key, or NULL if it the public key could
+    not be extracted (this can happen with DSA certificate chains if the
+    parameters in the chain cannot be found).  The caller is responsible
+    for calling CFRelease on the returned key when it is no longer needed.
+ */
 SecKeyRef SecTrustCopyPublicKey(SecTrustRef trust)
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0);
 
 /*!
 SecKeyRef SecTrustCopyPublicKey(SecTrustRef trust)
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0);
 
 /*!
-       @function SecTrustGetCertificateCount
-       @abstract Returns the number of certificates in an evaluated certificate
+    @function SecTrustGetCertificateCount
+    @abstract Returns the number of certificates in an evaluated certificate
     chain.
     chain.
-       @param trust Reference to a trust object.
-       @result The number of certificates in the trust chain.  This function will
-    return 1 if the trust has not been evaluated, and the number of
-    certificates in the chain including the anchor if it has.
-*/
+    @param trust A reference to a trust object.
+    @result The number of certificates in the trust chain, including the anchor.
+    @discussion Important: if the trust reference has not yet been evaluated,
+    this function will evaluate it first before returning. If speed is critical,
+    you may want to call SecTrustGetTrustResult first to make sure that a
+    result other than kSecTrustResultInvalid is present for the trust object.
+ */
 CFIndex SecTrustGetCertificateCount(SecTrustRef trust)
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0);
 
 /*!
 CFIndex SecTrustGetCertificateCount(SecTrustRef trust)
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0);
 
 /*!
-       @function SecTrustGetCertificateAtIndex
-       @abstract Returns a certificate from the trust chain.
-       @param trust Reference to a trust object.
-       @param ix The index of the requested certificate.  Indices run from 0
+    @function SecTrustGetCertificateAtIndex
+    @abstract Returns a certificate from the trust chain.
+    @param trust Reference to a trust object.
+    @param ix The index of the requested certificate.  Indices run from 0
     (leaf) to the anchor (or last certificate found if no anchor was found).
     The leaf cert (index 0) is always present regardless of whether the trust
     reference has been evaluated or not.
     (leaf) to the anchor (or last certificate found if no anchor was found).
     The leaf cert (index 0) is always present regardless of whether the trust
     reference has been evaluated or not.
-       @result A SecCertificateRef for the requested certificate.
-*/
+    @result A SecCertificateRef for the requested certificate.
+ */
 SecCertificateRef SecTrustGetCertificateAtIndex(SecTrustRef trust, CFIndex ix)
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0);
 
 /*!
 SecCertificateRef SecTrustGetCertificateAtIndex(SecTrustRef trust, CFIndex ix)
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0);
 
 /*!
-       @function SecTrustCopyExceptions
-       @abstract Returns an opauqe cookie which will allow future evaluations
+    @function SecTrustCopyExceptions
+    @abstract Returns an opaque cookie which will allow future evaluations
     of the current certificate to succeed.
     of the current certificate to succeed.
-       @param trust A reference to an evaluated trust object.
-       @result An opaque cookie which when passed to SecTrustSetExceptions() will
+    @param trust A reference to an evaluated trust object.
+    @result An opaque cookie which when passed to SecTrustSetExceptions() will
     cause a call to SecTrustEvaluate() return kSecTrustResultProceed.  This
     will happen upon subsequent evaluation of the current certificate unless
     some new error starts happening that wasn't being reported when the cookie
     cause a call to SecTrustEvaluate() return kSecTrustResultProceed.  This
     will happen upon subsequent evaluation of the current certificate unless
     some new error starts happening that wasn't being reported when the cookie
-    was returned from this function, for example if the certificate expires
-    evaluation will start failing again.
+    was returned from this function (for example, if the certificate expires
+    then evaluation will start failing again until a new cookie is obtained.)
     @discussion Normally this API should only be called once the errors have
     been presented to the user and the user decided to trust the current
     certificate chain regardless of the errors being presented, for the
     @discussion Normally this API should only be called once the errors have
     been presented to the user and the user decided to trust the current
     certificate chain regardless of the errors being presented, for the
-    current application/server/protocol/etc.
-*/
+    current application/server/protocol combination.
+ */
 CFDataRef SecTrustCopyExceptions(SecTrustRef trust)
 CFDataRef SecTrustCopyExceptions(SecTrustRef trust)
-    __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_4_0);
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0);
 
 /*!
 
 /*!
-       @function SecTrustSetExceptions
-       @abstract Set a trust cookie to be used for evaluating this certificate chain.
-       @param trust A reference to an not yet evaluated trust object.
+    @function SecTrustSetExceptions
+    @abstract Set a trust cookie to be used for evaluating this certificate chain.
+    @param trust A reference to a trust object.
     @param exceptions An exceptions cookie as returned by a call to
     SecTrustCopyExceptions() in the past.
     @param exceptions An exceptions cookie as returned by a call to
     SecTrustCopyExceptions() in the past.
-       @result Upon calling SecTrustEvaluate(), any failures that where present at the
+    @result Upon calling SecTrustEvaluate(), any failures that where present at the
     time the exceptions object was created are ignored, and instead of returning
     kSecTrustResultRecoverableTrustFailure, kSecTrustResultProceed will be returned
     (if the certificate for which exceptions was created matches the current leaf
     certificate).
     time the exceptions object was created are ignored, and instead of returning
     kSecTrustResultRecoverableTrustFailure, kSecTrustResultProceed will be returned
     (if the certificate for which exceptions was created matches the current leaf
     certificate).
+    @result Returns true if the exceptions cookies was valid and matches the current
+    leaf certificate, false otherwise.  This function will invalidate the existing
+    trust result, requiring a subsequent evaluation for the newly-set exceptions.
+    Note that this function returning true doesn't mean the caller can skip calling
+    SecTrustEvaluate, as there may be new errors since the exceptions cookie was
+    created (for example, a certificate may have subsequently expired.)
     @discussion Clients of this interface will need to establish the context of this
     exception to later decide when this exception cookie is to be used.
     @discussion Clients of this interface will need to establish the context of this
     exception to later decide when this exception cookie is to be used.
-    Examples of elements of this context would be the server we are connecting to, the
-    ssid of the network this cert is for the account for which this cert should be
-    considered valid, etc.
-    @result true if the exceptions cookies was valid and matches the current leaf
-    certificate, false otherwise.  Note that this function returning true doesn't
-    mean the caller can skip calling SecTrustEvaluate(), as something could have
-    changed causing the evaluation to fail after all.
-*/
+    Examples of this context would be the server we are connecting to, the ssid
+    of the wireless network for which this cert is needed, the account for which
+    this cert should be considered valid, and so on.
+ */
 bool SecTrustSetExceptions(SecTrustRef trust, CFDataRef exceptions)
 bool SecTrustSetExceptions(SecTrustRef trust, CFDataRef exceptions)
-    __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_4_0);
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0);
 
 
-#if defined(__cplusplus)
-}
-#endif
+/*!
+    @function SecTrustCopyProperties
+    @abstract Return a property array for this trust evaluation.
+    @param trust A reference to a trust object. If the trust has not been
+    evaluated, the returned property array will be empty.
+    @result A property array. It is the caller's responsibility to CFRelease
+    the returned array when it is no longer needed.
+    @discussion This function returns an ordered array of CFDictionaryRef
+    instances for each certificate in the chain. Indices run from 0 (leaf) to
+    the anchor (or last certificate found if no anchor was found.) See the
+    "Trust Property Constants" section for a list of currently defined keys.
+ */
+CFArrayRef SecTrustCopyProperties(SecTrustRef trust)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0);
+
+/*!
+    @function SecTrustCopyResult
+    @abstract Returns a dictionary containing information about the
+    evaluated certificate chain for use by clients.
+    @param trust A reference to a trust object.
+    @result A dictionary with various fields that can be displayed to the user,
+    or NULL if no additional info is available or the trust has not yet been
+    validated.  The caller is responsible for calling CFRelease on the value
+    returned when it is no longer needed.
+    @discussion Returns a dictionary for the overall trust evaluation. See the
+    "Trust Result Constants" section for a list of currently defined keys.
+ */
+CFDictionaryRef SecTrustCopyResult(SecTrustRef trust)
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+
+/*!
+    @function SecTrustSetOCSPResponse
+    @abstract Attach OCSPResponse data to a trust object.
+    @param trust A reference to a trust object.
+    @param responseData This may be either a CFData object containing a single
+    DER-encoded OCSPResponse (per RFC 2560), or a CFArray of these.
+    @result A result code. See "Security Error Codes" (SecBase.h).
+    @discussion Allows the caller to provide OCSPResponse data (which may be
+    obtained during a TLS/SSL handshake, per RFC 3546) as input to a trust
+    evaluation. If this data is available, it can obviate the need to contact
+    an OCSP server for current revocation information.
+ */
+OSStatus SecTrustSetOCSPResponse(SecTrustRef trust, CFTypeRef responseData)
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+
+
+/*
+ *  Legacy functions (OS X only)
+ */
+#if TARGET_OS_MAC && !TARGET_OS_IPHONE
+#include <Security/cssmtype.h>
+#include <Security/cssmapple.h>
+
+/*!
+    @typedef SecTrustUserSetting
+    @abstract Specifies a user-specified trust setting value.
+    @discussion Deprecated in OS X 10.9. User trust settings are managed by
+    functions in SecTrustSettings.h (starting with OS X 10.5), and by the
+    SecTrustCopyExceptions and SecTrustSetExceptions functions (starting with
+    iOS 4 and OS X 10.9). The latter two functions are recommended for both OS X
+    and iOS, as they avoid the need to explicitly specify these values.
+ */
+typedef SecTrustResultType SecTrustUserSetting
+    __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_9, __IPHONE_NA, __IPHONE_NA);
+
+/*!
+    @typedef SecTrustOptionFlags
+    @abstract Options for customizing trust evaluation.
+    @constant kSecTrustOptionAllowExpired Allow expired certificates.
+    @constant kSecTrustOptionLeafIsCA Allow CA as leaf certificate.
+    @constant kSecTrustOptionFetchIssuerFromNet Allow network fetch of CA cert.
+    @constant kSecTrustOptionAllowExpiredRoot Allow expired roots.
+    @constant kSecTrustOptionRequireRevPerCert Require positive revocation
+    check per certificate.
+    @constant kSecTrustOptionUseTrustSettings Use TrustSettings instead of
+    anchors.
+    @constant kSecTrustOptionImplicitAnchors Properly self-signed certs are
+    treated as anchors implicitly.
+ */
+typedef uint32_t SecTrustOptionFlags;
+enum {
+    kSecTrustOptionAllowExpired       = 0x00000001,
+    kSecTrustOptionLeafIsCA           = 0x00000002,
+    kSecTrustOptionFetchIssuerFromNet = 0x00000004,
+    kSecTrustOptionAllowExpiredRoot   = 0x00000008,
+    kSecTrustOptionRequireRevPerCert  = 0x00000010,
+    kSecTrustOptionUseTrustSettings   = 0x00000020,
+    kSecTrustOptionImplicitAnchors    = 0x00000040
+};
+
+/*!
+    @function SecTrustSetOptions
+    @abstract Sets optional flags for customizing a trust evaluation.
+    @param trustRef A trust reference.
+    @param options Flags to change evaluation behavior for this trust.
+    @result A result code. See "Security Error Codes" (SecBase.h).
+    @discussion This function is not available on iOS. Use SecTrustSetExceptions
+    and SecTrustCopyExceptions to modify default trust results, and
+    SecTrustSetNetworkFetchAllowed to specify whether missing CA certificates
+    can be fetched from the network.
+ */
+OSStatus SecTrustSetOptions(SecTrustRef trustRef, SecTrustOptionFlags options)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+
+/*!
+    @function SecTrustSetParameters
+    @abstract Sets the action and action data for a trust object.
+    @param trustRef The reference to the trust to change.
+    @param action A trust action.
+    @param actionData A reference to data associated with this action.
+    @result A result code. See "Security Error Codes" (SecBase.h).
+    @discussion This function is deprecated in OS X 10.7 and later, where it
+    was replaced by SecTrustSetOptions, and is not available on iOS. Your code
+    should use SecTrustSetExceptions and SecTrustCopyExceptions to modify default
+    trust results, and SecTrustSetNetworkFetchAllowed to specify whether missing
+    CA certificates can be fetched from the network.
+ */
+OSStatus SecTrustSetParameters(SecTrustRef trustRef,
+    CSSM_TP_ACTION action, CFDataRef actionData)
+    __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA);
+
+/*!
+    @function SecTrustSetKeychains
+    @abstract Sets the keychains for a given trust object.
+    @param trust A reference to a trust object.
+    @param keychainOrArray A reference to an array of keychains to search, a
+    single keychain, or NULL to use the default keychain search list.
+    @result A result code. See "Security Error Codes" (SecBase.h).
+    @discussion By default, the user's keychain search list and the system
+    anchors keychain are searched for certificates to complete the chain. You
+    can specify a zero-element array if you do not want any keychains searched.
+    Note: this function is not applicable to iOS.
+ */
+OSStatus SecTrustSetKeychains(SecTrustRef trust, CFTypeRef keychainOrArray)
+    __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_NA);
+
+/*!
+    @function SecTrustGetResult
+    @abstract Returns detailed information on the outcome of an evaluation.
+    @param trustRef A reference to a trust object.
+    @param result A pointer to the result from the call to SecTrustEvaluate.
+    @param certChain On return, a pointer to the certificate chain used to
+    validate the input certificate. Call the CFRelease function to release
+    this pointer.
+    @param statusChain On return, a pointer to the status of the certificate
+    chain. Do not attempt to free this pointer; it remains valid until the
+    trust is destroyed or the next call to SecTrustEvaluate.
+    @result A result code. See "Security Error Codes" (SecBase.h).
+    @discussion This function is deprecated in OS X 10.7 and later,
+    and is not available on iOS.
+    To get the complete certificate chain, use SecTrustGetCertificateCount and
+    SecTrustGetCertificateAtIndex. To get detailed status information for each
+    certificate, use SecTrustCopyProperties. To get the overall trust result
+    for the evaluation, use SecTrustGetTrustResult.
+ */
+OSStatus SecTrustGetResult(SecTrustRef trustRef, SecTrustResultType *result,
+    CFArrayRef *certChain, CSSM_TP_APPLE_EVIDENCE_INFO **statusChain)
+    __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA);
+
+/*!
+    @function SecTrustGetCssmResult
+    @abstract Gets the CSSM trust result.
+    @param trust A reference to a trust.
+    @param result On return, a pointer to the CSSM trust result.
+    @result A result code. See "Security Error Codes" (SecBase.h).
+    @discussion This function is deprecated in OS X 10.7 and later,
+    and is not available on iOS.
+    To get detailed status information for each certificate, use
+    SecTrustCopyProperties. To get the overall trust result for the evaluation,
+    use SecTrustGetTrustResult.
+ */
+OSStatus SecTrustGetCssmResult(SecTrustRef trust,
+    CSSM_TP_VERIFY_CONTEXT_RESULT_PTR *result)
+    __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA);
+
+/*!
+    @function SecTrustGetCssmResultCode
+    @abstract Gets the result code from the most recent call to SecTrustEvaluate
+    for the specified trust.
+    @param trust A reference to a trust.
+    @param resultCode On return, the result code produced by the most recent
+    evaluation of the given trust (cssmerr.h). The value of resultCode is
+    undefined if SecTrustEvaluate has not been called.
+    @result A result code. See "Security Error Codes" (SecBase.h). Returns
+    errSecTrustNotAvailable if SecTrustEvaluate has not been called for the
+    specified trust.
+    @discussion This function is deprecated in OS X 10.7 and later,
+    and is not available on iOS.
+    To get detailed status information for each certificate, use
+    SecTrustCopyProperties. To get the overall trust result for the evaluation,
+    use SecTrustGetTrustResult.
+ */
+OSStatus SecTrustGetCssmResultCode(SecTrustRef trust, OSStatus *resultCode)
+    __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA);
+
+/*!
+    @function SecTrustGetTPHandle
+    @abstract Gets the CSSM trust handle
+    @param trust A reference to a trust.
+    @param handle On return, a CSSM trust handle.
+    @result A result code. See "Security Error Codes" (SecBase.h).
+    @discussion This function is deprecated in OS X 10.7 and later.
+ */
+OSStatus SecTrustGetTPHandle(SecTrustRef trust, CSSM_TP_HANDLE *handle)
+    __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA);
+
+/*!
+    @function SecTrustCopyAnchorCertificates
+    @abstract Returns an array of default anchor (root) certificates used by
+    the system.
+    @param anchors On return, an array containing the system's default anchors
+    (roots). Call the CFRelease function to release this pointer.
+    @result A result code. See "Security Error Codes" (SecBase.h).
+    @discussion This function is not available on iOS, as certificate data
+    for system-trusted roots is currently unavailable on that platform.
+ */
+OSStatus SecTrustCopyAnchorCertificates(CFArrayRef *anchors)
+    __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_NA);
+
+#endif /* TARGET_OS_MAC && !TARGET_OS_IPHONE */
+
+
+__END_DECLS
 
 #endif /* !_SECURITY_SECTRUST_H_ */
 
 #endif /* !_SECURITY_SECTRUST_H_ */
index 303ec02434ab2dc170b58dce455f310916cdb2f6..dfc7470987d28954c6010d88fffe30b6f8636d6a 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2008-2010 Apple Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2008-2013 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
 /*!
        @header SecTrustPriv
  * @APPLE_LICENSE_HEADER_END@
  */
 
 /*!
        @header SecTrustPriv
-       The functions and data types in SecTrustPriv implement trust computation and allow the user to apply trust decisions to the trust configuration.
+       The functions and data types in SecTrustPriv implement trust computation
+       and allow the user to apply trust decisions to the trust configuration.
 */
 
 #ifndef _SECURITY_SECTRUSTPRIV_H_
 */
 
 #ifndef _SECURITY_SECTRUSTPRIV_H_
 #include <CoreFoundation/CFData.h>
 #include <CoreFoundation/CFDictionary.h>
 
 #include <CoreFoundation/CFData.h>
 #include <CoreFoundation/CFDictionary.h>
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
+
+typedef enum {
+       useNetworkDefault,              // default policy: network fetch enabled only for SSL
+       useNetworkDisabled,             // explicitly disable network use for any policy
+       useNetworkEnabled               // explicitly enable network use for any policy
+} SecNetworkPolicy;
 
 /* Constants used as keys in property lists.  See
    SecTrustCopySummaryPropertiesAtIndex for more information. */
 
 /* Constants used as keys in property lists.  See
    SecTrustCopySummaryPropertiesAtIndex for more information. */
-extern CFStringRef kSecPropertyKeyType;
-extern CFStringRef kSecPropertyKeyLabel;
-extern CFStringRef kSecPropertyKeyLocalizedLabel;
-extern CFStringRef kSecPropertyKeyValue;
-
-extern CFStringRef kSecPropertyTypeWarning;
-extern CFStringRef kSecPropertyTypeError;
-extern CFStringRef kSecPropertyTypeSuccess;
-extern CFStringRef kSecPropertyTypeTitle;
-extern CFStringRef kSecPropertyTypeSection;
-extern CFStringRef kSecPropertyTypeData;
-extern CFStringRef kSecPropertyTypeString;
-extern CFStringRef kSecPropertyTypeURL;
-extern CFStringRef kSecPropertyTypeDate;
+extern CFTypeRef kSecPropertyKeyType;
+extern CFTypeRef kSecPropertyKeyLabel;
+extern CFTypeRef kSecPropertyKeyLocalizedLabel;
+extern CFTypeRef kSecPropertyKeyValue;
+
+extern CFTypeRef kSecPropertyTypeWarning;
+extern CFTypeRef kSecPropertyTypeSuccess;
+extern CFTypeRef kSecPropertyTypeSection;
+extern CFTypeRef kSecPropertyTypeData;
+extern CFTypeRef kSecPropertyTypeString;
+extern CFTypeRef kSecPropertyTypeURL;
+extern CFTypeRef kSecPropertyTypeDate;
 
 /* Constants used as keys in the dictionary returned by SecTrustCopyInfo. */
 
 /* Constants used as keys in the dictionary returned by SecTrustCopyInfo. */
-extern CFStringRef kSecTrustInfoExtendedValidationKey;
-extern CFStringRef kSecTrustInfoCompanyNameKey;
-extern CFStringRef kSecTrustInfoRevocationKey;
-extern CFStringRef kSecTrustInfoRevocationValidUntilKey;
+extern CFTypeRef kSecTrustInfoExtendedValidationKey;
+extern CFTypeRef kSecTrustInfoCompanyNameKey;
+extern CFTypeRef kSecTrustInfoRevocationKey;
+extern CFTypeRef kSecTrustInfoRevocationValidUntilKey;
 
 /*!
        @function SecTrustCopySummaryPropertiesAtIndex
 
 /*!
        @function SecTrustCopySummaryPropertiesAtIndex
@@ -68,7 +71,7 @@ extern CFStringRef kSecTrustInfoRevocationValidUntilKey;
     (leaf) to the anchor (or last certificate found if no anchor was found).
     @result A property array. It is the caller's responsibility to CFRelease
     the returned array when it is no longer needed. This function returns a
     (leaf) to the anchor (or last certificate found if no anchor was found).
     @result A property array. It is the caller's responsibility to CFRelease
     the returned array when it is no longer needed. This function returns a
-    short summary description of the certificate in question.  The property 
+    short summary description of the certificate in question.  The property
     at index 0 of the array might also include general information about the
     entire chain's validity in the context of this trust evaluation.
 
     at index 0 of the array might also include general information about the
     entire chain's validity in the context of this trust evaluation.
 
@@ -82,11 +85,11 @@ extern CFStringRef kSecTrustInfoRevocationValidUntilKey;
            kSecPropertyTypeWarning
                       The kSecPropertyKeyLocalizedLabel and kSecPropertyKeyLabel keys are not
                           set.  The kSecPropertyKeyValue is a CFStringRef which should
            kSecPropertyTypeWarning
                       The kSecPropertyKeyLocalizedLabel and kSecPropertyKeyLabel keys are not
                           set.  The kSecPropertyKeyValue is a CFStringRef which should
-                          be displayed in yellow with a warning triangle. 
+                          be displayed in yellow with a warning triangle.
            kSecPropertyTypeError
                       The kSecPropertyKeyLocalizedLabel and kSecPropertyKeyLabel keys are not
                           set.  The kSecPropertyKeyValue is a CFStringRef which should
            kSecPropertyTypeError
                       The kSecPropertyKeyLocalizedLabel and kSecPropertyKeyLabel keys are not
                           set.  The kSecPropertyKeyValue is a CFStringRef which should
-                          be displayed in red with an error X. 
+                          be displayed in red with an error X.
            kSecPropertyTypeSuccess
                       The kSecPropertyKeyLocalizedLabel and kSecPropertyKeyLabel keys are not
                           set.  The kSecPropertyKeyValue is a CFStringRef which should
            kSecPropertyTypeSuccess
                       The kSecPropertyKeyLocalizedLabel and kSecPropertyKeyLabel keys are not
                           set.  The kSecPropertyKeyValue is a CFStringRef which should
@@ -202,8 +205,25 @@ CFDictionaryRef SecTrustCopyInfo(SecTrustRef trust);
 /* For debugging purposes. */
 CFArrayRef SecTrustGetDetails(SecTrustRef trust);
 
 /* For debugging purposes. */
 CFArrayRef SecTrustGetDetails(SecTrustRef trust);
 
-#if defined(__cplusplus)
-}
-#endif
+/* For debugging purposes. */
+CFStringRef SecTrustCopyFailureDescription(SecTrustRef trust);
+
+/*!
+       @function SecTrustSetPolicies
+       @abstract Set the trust policies against which the trust should be verified.
+       @param trust A reference to a trust object.
+    @param policies An array of one or more policies. You may pass a
+    SecPolicyRef to represent a single policy.
+       @result A result code.  See "Security Error Codes" (SecBase.h).
+    @discussion This function does not invalidate the trust, but should do so in the future.
+*/
+OSStatus SecTrustSetPolicies(SecTrustRef trust, CFTypeRef policies)
+   __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_6_0);
+
+OSStatus SecTrustGetOTAPKIAssetVersionNumber(int* versionNumber);
+
+OSStatus SecTrustOTAPKIGetUpdatedAsset(int* didUpdateAsset);
+
+__END_DECLS
 
 #endif /* !_SECURITY_SECTRUSTPRIV_H_ */
 
 #endif /* !_SECURITY_SECTRUSTPRIV_H_ */
index 776f901630424bb983f61cc81be6cc166bc17753..a27cc9e3c94fb57e8123e112a175669d65693b5c 100644 (file)
@@ -30,7 +30,7 @@
 #include <Security/SecCertificatePriv.h>
 #include <AssertMacros.h>
 #include <pthread.h>
 #include <Security/SecCertificatePriv.h>
 #include <AssertMacros.h>
 #include <pthread.h>
-#include <security_utilities/debugging.h>
+#include <utilities/debugging.h>
 #include "SecBasePriv.h"
 #include <Security/SecInternal.h>
 #include <CoreFoundation/CFRuntime.h>
 #include "SecBasePriv.h"
 #include <Security/SecInternal.h>
 #include <CoreFoundation/CFRuntime.h>
 #define trustSettingsDbg(args...)              secdebug("trustSettings", ## args)
 #define trustSettingsEvalDbg(args...)  secdebug("trustSettingsEval", ## args)
 
 #define trustSettingsDbg(args...)              secdebug("trustSettings", ## args)
 #define trustSettingsEvalDbg(args...)  secdebug("trustSettingsEval", ## args)
 
-#pragma mark -
-#pragma mark Static Functions
-
-#if 0
-/* Return a (hex)string representation of a CFDataRef. */
-static CFStringRef SecCopyHexStringFromData(CFDataRef data)
-{
-    CFIndex ix, length;
-       const UInt8 *bytes;
-    CFMutableStringRef string;
-
-       if (data) {
-               length = CFDataGetLength(data);
-               bytes = CFDataGetBytePtr(data);
-       } else {
-               length = 0;
-               bytes = NULL;
-       }
-       string = CFStringCreateMutable(kCFAllocatorDefault, length * 2);
-    for (ix = 0; ix < length; ++ix)
-               CFStringAppendFormat(string, NULL, CFSTR("%02X"), bytes[ix]);
-
-    return string;
-}
-#endif
+// MARK: -
+// MARK: Static Functions
 
 /* Return a CFDataRef representation of a (hex)string. */
 static CFDataRef SecCopyDataFromHexString(CFStringRef string) {
 
 /* Return a CFDataRef representation of a (hex)string. */
 static CFDataRef SecCopyDataFromHexString(CFStringRef string) {
@@ -127,12 +104,12 @@ static CFStringRef SecTrustSettingsCertHashStrFromCert(
        }
 
        CFDataRef digest = SecCertificateGetSHA1Digest(certRef);
        }
 
        CFDataRef digest = SecCertificateGetSHA1Digest(certRef);
-       return SecCopyHexStringFromData(digest);
+       return CFDataCopyHexString(digest);
 }
 #endif
 
 }
 #endif
 
-#pragma mark -
-#pragma mark SecTrustSettings
+// MARK: -
+// MARK: SecTrustSettings
 /********************************************************
  ************** SecTrustSettings object *****************
  ********************************************************/
 /********************************************************
  ************** SecTrustSettings object *****************
  ********************************************************/
@@ -344,7 +321,7 @@ static OSStatus SecTrustSettingsValidate(SecTrustSettingsRef ts, bool trim) {
 
        /* Convert the per-cert entries from on disk to in memory format. */
        struct trustListContext context = {
 
        /* Convert the per-cert entries from on disk to in memory format. */
        struct trustListContext context = {
-               ts->_trustDict, ts->_dictVersion, trim, noErr
+               ts->_trustDict, ts->_dictVersion, trim, errSecSuccess
        };
        CFDictionaryApplyFunction(trustList, trustListApplierFunction, &context);
 
        };
        CFDictionaryApplyFunction(trustList, trustListApplierFunction, &context);
 
@@ -369,12 +346,13 @@ OSStatus SecTrustSettingsCreateFromExternal(SecTrustSettingsDomain domain,
        require(result = (SecTrustSettingsRef)_CFRuntimeCreateInstance(allocator,
                SecTrustSettingsGetTypeID(), size - sizeof(CFRuntimeBase), 0), errOut);
 
        require(result = (SecTrustSettingsRef)_CFRuntimeCreateInstance(allocator,
                SecTrustSettingsGetTypeID(), size - sizeof(CFRuntimeBase), 0), errOut);
 
-       CFStringRef errorString = NULL;
-       CFPropertyListRef plist = CFPropertyListCreateFromXMLData(
-               kCFAllocatorDefault, external, kCFPropertyListImmutable, &errorString);
+       CFErrorRef error = NULL;
+       CFPropertyListRef plist = CFPropertyListCreateWithData(kCFAllocatorDefault,
+        external, kCFPropertyListImmutable, NULL, &error);
        if (!plist) {
        if (!plist) {
-               secwarning("CFPropertyListCreateFromXMLData: %@", errorString);
-               CFReleaseSafe(errorString);
+               secwarning("SecTrustSettingsCreateFromExternal: %@", error);
+               CFReleaseSafe(error);
+        CFReleaseSafe(result);
                goto errOut;
        }
 
                goto errOut;
        }
 
@@ -384,7 +362,7 @@ OSStatus SecTrustSettingsCreateFromExternal(SecTrustSettingsDomain domain,
 
        *ts = result;
 
 
        *ts = result;
 
-       return noErr;
+       return errSecSuccess;
 
 errOut:
     return errSecInvalidTrustSettings;
 
 errOut:
     return errSecInvalidTrustSettings;
@@ -421,8 +399,8 @@ void SecTrustSettingsSet(SecCertificateRef certRef,
 
 
 
 
 
 
-#pragma mark -
-#pragma mark SPI functions
+// MARK: -
+// MARK: SPI functions
 
 
 /*
 
 
 /*
@@ -527,17 +505,17 @@ OSStatus SecTrustSettingsEvaluateCertificate(
                        trustSettingsDbg("SecTrustSettingsEvaluateCert: found in domain %d", domain);
                        *foundAnyEntry = true;
                        *foundMatchingEntry = true;
                        trustSettingsDbg("SecTrustSettingsEvaluateCert: found in domain %d", domain);
                        *foundAnyEntry = true;
                        *foundMatchingEntry = true;
-                       return noErr;
+                       return errSecSuccess;
                }
                foundAny |= foundAnyHere;
        }
        trustSettingsDbg("SecTrustSettingsEvaluateCert: NOT FOUND");
        *foundAnyEntry = foundAny;
        *foundMatchingEntry = false;
                }
                foundAny |= foundAnyHere;
        }
        trustSettingsDbg("SecTrustSettingsEvaluateCert: NOT FOUND");
        *foundAnyEntry = foundAny;
        *foundMatchingEntry = false;
-       return noErr;
+       return errSecSuccess;
        END_RCSAPI
 #endif
        END_RCSAPI
 #endif
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
 }
 
 /*
index 711e1bd24ef3bf2229eb0c1da060545abc5e9426..4ba1294be3f3e1d3c111f0836211b66be19b1d16 100644 (file)
 #include <CoreFoundation/CFString.h>
 #include <AssertMacros.h>
 #include "securityd_client.h"
 #include <CoreFoundation/CFString.h>
 #include <AssertMacros.h>
 #include "securityd_client.h"
+#include "SecuritydXPC.h"
+#include "SecFramework.h"
+#include <sys/stat.h>
+#include <stdio.h>
+#include <dirent.h>
+#include "SecTrustPriv.h"
+#include <utilities/SecCFError.h>
+#include "utilities/SecDb.h"
 
 static CFStringRef kSecTrustStoreUserName = CFSTR("user");
 
 
 static CFStringRef kSecTrustStoreUserName = CFSTR("user");
 
@@ -43,71 +51,75 @@ SecTrustStoreRef SecTrustStoreForDomain(SecTrustStoreDomain domain) {
     }
 
     if (gSecurityd) {
     }
 
     if (gSecurityd) {
-        return gSecurityd->sec_trust_store_for_domain(domainName);
+        return gSecurityd->sec_trust_store_for_domain(domainName, NULL);
     } else {
         return (SecTrustStoreRef)domainName;
     }
 }
 
     } else {
         return (SecTrustStoreRef)domainName;
     }
 }
 
+static bool string_data_to_bool_error(enum SecXPCOperation op, SecTrustStoreRef ts, CFDataRef digest, CFErrorRef *error)
+{
+    return securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
+        return SecXPCDictionarySetString(message, kSecXPCKeyDomain, (CFStringRef)ts, error) &&
+        SecXPCDictionarySetData(message, kSecXPCKeyDigest, digest, error);
+    }, NULL);
+}
+
+static bool string_data_to_bool_bool_error(enum SecXPCOperation op, SecTrustStoreRef ts, CFDataRef digest, bool *result, CFErrorRef *error)
+{
+    return securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
+        return SecXPCDictionarySetString(message, kSecXPCKeyDomain, (CFStringRef)ts, error) &&
+        SecXPCDictionarySetData(message, kSecXPCKeyDigest, digest, error);
+    }, ^bool(xpc_object_t response, CFErrorRef *error) {
+        if (result)
+            *result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
+        return true;
+    });
+}
+
 Boolean SecTrustStoreContains(SecTrustStoreRef ts,
        SecCertificateRef certificate) {
     CFDataRef digest;
 Boolean SecTrustStoreContains(SecTrustStoreRef ts,
        SecCertificateRef certificate) {
     CFDataRef digest;
-       bool contains = false;
+    bool ok = false;
+       __block bool contains = false;
 
        require(ts, errOut);
        require(digest = SecCertificateGetSHA1Digest(certificate), errOut);
 
        require(ts, errOut);
        require(digest = SecCertificateGetSHA1Digest(certificate), errOut);
-    if (gSecurityd) {
-        contains = gSecurityd->sec_trust_store_contains(ts, digest);
-    } else {
-        const void *values[] = {
-            (const void *)ts,
-            (const void *)digest
-        };
-        CFArrayRef in = CFArrayCreate(kCFAllocatorDefault, values,
-            2, &kCFTypeArrayCallBacks);
-        OSStatus status;
-        if (in) {
-            status = ServerCommandSendReceive(sec_trust_store_contains_id,
-                in, NULL);
-            CFRelease(in);
-        } else {
-            status = errSecAllocate;
-        }
-        contains = !status;
-    }
+    ok = (SecOSStatusWith(^bool (CFErrorRef *error) {
+        return SECURITYD_XPC(sec_trust_store_contains, string_data_to_bool_bool_error, ts, digest, &contains, error);
+    }) == errSecSuccess);
 
 errOut:
 
 errOut:
-       return contains;
+       return ok && contains;
+}
+
+static bool SecXPCDictionarySetCertificate(xpc_object_t message, const char *key, SecCertificateRef certificate, CFErrorRef *error) {
+    if (certificate) {
+        xpc_dictionary_set_data(message, key, SecCertificateGetBytePtr(certificate),
+                                SecCertificateGetLength(certificate));
+        return true;
+    }
+    return SecError(errSecParam, error, CFSTR("NULL certificate"));
+}
+
+
+static bool string_cert_cftype_to_error(enum SecXPCOperation op, SecTrustStoreRef ts, SecCertificateRef certificate, CFTypeRef trustSettingsDictOrArray, CFErrorRef *error)
+{
+    return securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
+        bool ok = false;
+        ok = SecXPCDictionarySetString(message, kSecXPCKeyDomain, (CFStringRef)ts, error) &&
+        SecXPCDictionarySetCertificate(message, kSecXPCKeyCertificate, certificate, error) &&
+        (!trustSettingsDictOrArray || SecXPCDictionarySetPList(message, kSecXPCKeySettings, trustSettingsDictOrArray, error));
+        return ok;
+    }, NULL);
 }
 
 OSStatus SecTrustStoreSetTrustSettings(SecTrustStoreRef ts,
        SecCertificateRef certificate,
     CFTypeRef trustSettingsDictOrArray) {
 }
 
 OSStatus SecTrustStoreSetTrustSettings(SecTrustStoreRef ts,
        SecCertificateRef certificate,
     CFTypeRef trustSettingsDictOrArray) {
-    CFDataRef certificateData = NULL;
-    OSStatus status = errSecParam;
-
-    if (gSecurityd) {
-        status = gSecurityd->sec_trust_store_set_trust_settings(ts, certificate, trustSettingsDictOrArray);
-    } else {
-        require(ts == (SecTrustStoreRef)kSecTrustStoreUserName, errOut);
-        require(certificateData = SecCertificateCopyData(certificate), errOut);
-        const void *values[] = {
-            (const void *)certificateData,
-            (const void *)trustSettingsDictOrArray
-        };
-        CFArrayRef in = CFArrayCreate(kCFAllocatorDefault, values,
-            (trustSettingsDictOrArray ? 2 : 1), &kCFTypeArrayCallBacks);
-        if (in) {
-            status = ServerCommandSendReceive(sec_trust_store_set_trust_settings_id, in, NULL);
-            CFRelease(in);
-        } else {
-            status = errSecAllocate;
-        }
-    }
-
-errOut:
-    CFReleaseSafe(certificateData);
-       return status;
+    return SecOSStatusWith(^bool (CFErrorRef *error) {
+        return SECURITYD_XPC(sec_trust_store_set_trust_settings, string_cert_cftype_to_error, ts, certificate, trustSettingsDictOrArray, error);
+    });
 }
 
 OSStatus SecTrustStoreRemoveCertificate(SecTrustStoreRef ts,
 }
 
 OSStatus SecTrustStoreRemoveCertificate(SecTrustStoreRef ts,
@@ -116,14 +128,43 @@ OSStatus SecTrustStoreRemoveCertificate(SecTrustStoreRef ts,
     CFDataRef digest;
     OSStatus status = errSecParam;
 
     CFDataRef digest;
     OSStatus status = errSecParam;
 
+       require(ts, errOut);
        require(digest = SecCertificateGetSHA1Digest(certificate), errOut);
        require(digest = SecCertificateGetSHA1Digest(certificate), errOut);
-    if (gSecurityd) {
-        status = gSecurityd->sec_trust_store_remove_certificate(ts, digest);
-    } else {
-        require(ts == (SecTrustStoreRef)kSecTrustStoreUserName, errOut);
-        status = ServerCommandSendReceive(sec_trust_store_remove_certificate_id, digest, NULL);
-    }
+    require(gSecurityd || ts == (SecTrustStoreRef)kSecTrustStoreUserName, errOut);
+    status = SecOSStatusWith(^bool (CFErrorRef *error) {
+        return SECURITYD_XPC(sec_trust_store_remove_certificate, string_data_to_bool_error, ts, digest, error);
+    });
 
 errOut:
        return status;
 }
 
 errOut:
        return status;
 }
+
+
+static CFIndex GetOTAAssetVersionNumber()
+{
+       CFIndex result = 0;
+    int version = 0;
+
+       if (errSecSuccess == SecTrustGetOTAPKIAssetVersionNumber(&version))
+       {
+               result = version;       
+       }
+    return result;
+}
+
+
+
+OSStatus SecTrustStoreGetSettingsVersionNumber(SecTrustSettingsVersionNumber* p_settings_version_number)
+{
+    OSStatus status = errSecParam;
+    if (NULL == p_settings_version_number)
+    {
+        return status;
+    }
+       
+    CFIndex versionNumber = GetOTAAssetVersionNumber();
+    *p_settings_version_number = (SecTrustSettingsVersionNumber)versionNumber;
+
+    return errSecSuccess;
+}
index de12b61ab2402f0e5ed5fac981d7d33f32c1ca55..fed3b79f96d17a28a4a34f7024bba8a62b9a9e05 100644 (file)
@@ -31,9 +31,7 @@
 
 #include <Security/SecCertificate.h>
 
 
 #include <Security/SecCertificate.h>
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 typedef struct __SecTrustStore *SecTrustStoreRef;
 
 
 typedef struct __SecTrustStore *SecTrustStoreRef;
 
@@ -43,6 +41,8 @@ enum {
 };
 typedef uint32_t SecTrustStoreDomain;
 
 };
 typedef uint32_t SecTrustStoreDomain;
 
+typedef int32_t SecTrustSettingsVersionNumber;
+
 SecTrustStoreRef SecTrustStoreForDomain(SecTrustStoreDomain domain);
 
 Boolean SecTrustStoreContains(SecTrustStoreRef source,
 SecTrustStoreRef SecTrustStoreForDomain(SecTrustStoreDomain domain);
 
 Boolean SecTrustStoreContains(SecTrustStoreRef source,
@@ -56,8 +56,8 @@ OSStatus SecTrustStoreSetTrustSettings(SecTrustStoreRef ts,
 OSStatus SecTrustStoreRemoveCertificate(SecTrustStoreRef ts,
        SecCertificateRef certificate);
 
 OSStatus SecTrustStoreRemoveCertificate(SecTrustStoreRef ts,
        SecCertificateRef certificate);
 
-#if defined(__cplusplus)
-}
-#endif
+OSStatus SecTrustStoreGetSettingsVersionNumber(SecTrustSettingsVersionNumber* p_settings_version_number);
+
+__END_DECLS
 
 #endif /* !_SECURITY_SECTRUSTSTORE_H_ */
 
 #endif /* !_SECURITY_SECTRUSTSTORE_H_ */
index 3ef177191fc58e9ba0fefe096c2e0b448c7f9ac4..25962d92c86b2df2066a63d51ac0096ef184d663 100644 (file)
@@ -30,3 +30,4 @@
 #include <Security/SecPolicy.h>
 #include <Security/SecRandom.h>
 #include <Security/SecTrust.h>
 #include <Security/SecPolicy.h>
 #include <Security/SecRandom.h>
 #include <Security/SecTrust.h>
+
diff --git a/sec/Security/SecuritydXPC.c b/sec/Security/SecuritydXPC.c
new file mode 100644 (file)
index 0000000..f4a5503
--- /dev/null
@@ -0,0 +1,281 @@
+//
+//  SecuritydXPC.c
+//  sec
+//
+//  Created by Mitch Adler on 11/16/12.
+//  Copyright (c) 2012-2013 Apple Inc. All rights reserved.
+//
+
+#include "SecuritydXPC.h"
+#include <ipc/securityd_client.h>
+#include <utilities/SecCFError.h>
+#include <utilities/SecDb.h>
+#include <utilities/SecCFWrappers.h>
+#include <utilities/der_plist.h>
+
+// TODO Shorten these string values to save ipc bandwidth.
+const char *kSecXPCKeyOperation = "operation";
+const char *kSecXPCKeyResult = "status";
+const char *kSecXPCKeyError = "error";
+const char *kSecXPCKeyPeerInfos = "peer-infos";
+const char *kSecXPCKeyUserLabel = "userlabel";
+const char *kSecXPCKeyBackup = "backup";
+const char *kSecXPCKeyKeybag = "keybag";
+const char *kSecXPCKeyUserPassword = "password";
+const char *kSecXPCKeyQuery = "query";
+const char *kSecXPCKeyAttributesToUpdate = "attributesToUpdate";
+const char *kSecXPCKeyDomain = "domain";
+const char *kSecXPCKeyDigest = "digest";
+const char *kSecXPCKeyCertificate = "cert";
+const char *kSecXPCKeySettings = "settings";
+const char *kSecXPCKeyOTAFileDirectory = "path";
+const char *kSecXPCLimitInMinutes = "limitMinutes";
+
+//
+// XPC Functions for both client and server.
+//
+
+
+CFStringRef SOSCCGetOperationDescription(enum SecXPCOperation op)
+{
+    switch (op) {
+        case sec_item_add_id:
+            return CFSTR("add");
+        case sec_item_copy_matching_id:
+            return CFSTR("copy_matching");
+        case sec_item_update_id:
+            return CFSTR("update");
+        case sec_item_delete_id:
+            return CFSTR("delete");
+        case sec_trust_store_contains_id:
+            return CFSTR("trust_store_contains");
+        case sec_trust_store_set_trust_settings_id:
+            return CFSTR("trust_store_set_trust_settings");
+        case sec_trust_store_remove_certificate_id:
+            return CFSTR("trust_store_remove_certificate");
+        case sec_delete_all_id:
+            return CFSTR("delete_all");
+        case sec_trust_evaluate_id:
+            return CFSTR("trust_evaluate");
+        case sec_keychain_backup_id:
+            return CFSTR("keychain_backup");
+        case sec_keychain_restore_id:
+            return CFSTR("keychain_restore");
+        case sec_keychain_sync_update_id:
+            return CFSTR("keychain_sync_update");
+        case sec_keychain_backup_syncable_id:
+            return CFSTR("keychain_backup_syncable");
+        case sec_keychain_restore_syncable_id:
+            return CFSTR("keychain_restore_syncable");
+        case sec_ota_pki_asset_version_id:
+            return CFSTR("ota_pki_asset_version");
+        case kSecXPCOpTryUserCredentials:
+            return CFSTR("TryUserCredentials");
+        case kSecXPCOpSetUserCredentials:
+            return CFSTR("SetUserCredentials");
+        case kSecXPCOpCanAuthenticate:
+            return CFSTR("CanAuthenticate");
+        case kSecXPCOpPurgeUserCredentials:
+            return CFSTR("PurgeUserCredentials");
+        case kSecXPCOpDeviceInCircle:
+            return CFSTR("DeviceInCircle");
+        case kSecXPCOpRequestToJoin:
+            return CFSTR("RequestToJoin");
+        case kSecXPCOpResetToOffering:
+            return CFSTR("ResetToOffering");
+        case kSecXPCOpResetToEmpty:
+            return CFSTR("ResetToEmpty");
+        case kSecXPCOpRemoveThisDeviceFromCircle:
+            return CFSTR("RemoveThisDevice");
+        case kSecXPCOpBailFromCircle:
+            return CFSTR("BailFromCircle");
+        case kSecXPCOpAcceptApplicants:
+            return CFSTR("AcceptApplicants");
+        case kSecXPCOpRejectApplicants:
+            return CFSTR("RejectApplicants");
+        case kSecXPCOpCopyApplicantPeerInfo:
+            return CFSTR("ApplicantPeerInfo");
+        case kSecXPCOpCopyPeerPeerInfo:
+            return CFSTR("PeerPeerInfo");
+        case kSecXPCOpCopyConcurringPeerPeerInfo:
+            return CFSTR("ConcurringPeerPeerInfo");
+        case kSecXPCOpOTAGetEscrowCertificates:
+            return CFSTR("OTAGetEscrowCertificates");
+               case kSecXPCOpOTAPKIGetNewAsset:
+                       return CFSTR("sec_ota_pki_get_new_asset");
+        case kSecXPCOpProcessSyncWithAllPeers:
+            return CFSTR("ProcessSyncWithAllPeers");
+        default:
+            return CFSTR("Unknown xpc operation");
+    }
+}
+
+bool SecXPCDictionarySetPList(xpc_object_t message, const char *key, CFTypeRef object, CFErrorRef *error)
+{
+    if (!object)
+        return SecError(errSecParam, error, CFSTR("object for key %s is NULL"), key);
+
+    size_t size = der_sizeof_plist(object, error);
+    if (!size)
+        return false;
+    uint8_t *der = malloc(size);
+    uint8_t *der_end = der + size;
+    uint8_t *der_start = der_encode_plist(object, error, der, der_end);
+    if (!der_start) {
+        free(der);
+        return false;
+    }
+
+    assert(der == der_start);
+    xpc_dictionary_set_data(message, key, der_start, der_end - der_start);
+    free(der);
+    return true;
+}
+
+bool SecXPCDictionarySetPListOptional(xpc_object_t message, const char *key, CFTypeRef object, CFErrorRef *error) {
+    return !object || SecXPCDictionarySetPList(message, key, object, error);
+}
+
+bool SecXPCDictionarySetData(xpc_object_t message, const char *key, CFDataRef data, CFErrorRef *error)
+{
+    if (!data)
+        return SecError(errSecParam, error, CFSTR("data for key %s is NULL"), key);
+
+    xpc_dictionary_set_data(message, key, CFDataGetBytePtr(data), CFDataGetLength(data));
+    return true;
+}
+
+bool SecXPCDictionarySetString(xpc_object_t message, const char *key, CFStringRef string, CFErrorRef *error)
+{
+    if (!string)
+        return SecError(errSecParam, error, CFSTR("string for key %s is NULL"), key);
+    
+    __block bool ok = true;
+    CFStringPerformWithCString(string, ^(const char *utf8Str) {
+        if (utf8Str)
+            xpc_dictionary_set_string(message, key, utf8Str);
+        else
+            ok = SecError(errSecParam, error, CFSTR("failed to convert string for key %s to utf8"), key);
+    });
+    return ok;
+}
+
+bool SecXPCDictionarySetDataOptional(xpc_object_t message, const char *key, CFDataRef data, CFErrorRef *error) {
+    return !data || SecXPCDictionarySetData(message, key, data, error);
+}
+
+CFArrayRef SecXPCDictionaryCopyArray(xpc_object_t message, const char *key, CFErrorRef *error) {
+    CFTypeRef array = SecXPCDictionaryCopyPList(message, key, error);
+    if (array) {
+        CFTypeID type_id = CFGetTypeID(array);
+        if (type_id != CFArrayGetTypeID()) {
+            CFStringRef description = CFCopyTypeIDDescription(type_id);
+            SecError(errSecParam, error, CFSTR("object for key %s not array but %@"), key, description);
+            CFReleaseNull(description);
+            CFReleaseNull(array);
+        }
+    }
+    return (CFArrayRef)array;
+}
+
+bool SecXPCDictionaryCopyArrayOptional(xpc_object_t message, const char *key, CFArrayRef *parray, CFErrorRef *error) {
+    if (!xpc_dictionary_get_value(message, key)) {
+        *parray = NULL;
+        return true;
+    }
+    *parray = SecXPCDictionaryCopyArray(message, key, error);
+    return *parray;
+}
+
+CFDataRef SecXPCDictionaryCopyData(xpc_object_t message, const char *key, CFErrorRef *error) {
+    CFDataRef data = NULL;
+    size_t size = 0;
+    const uint8_t *bytes = xpc_dictionary_get_data(message, key, &size);
+    if (!bytes) {
+        SecError(errSecParam, error, CFSTR("no data for key %s"), key);
+        return NULL;
+    }
+
+    data = CFDataCreate(kCFAllocatorDefault, bytes, size);
+    if (!data)
+        SecError(errSecParam, error, CFSTR("failed to create data for key %s"), key);
+
+    return data;
+}
+
+bool SecXPCDictionaryCopyDataOptional(xpc_object_t message, const char *key, CFDataRef *pdata, CFErrorRef *error) {
+    size_t size = 0;
+    if (!xpc_dictionary_get_data(message, key, &size)) {
+        *pdata = NULL;
+        return true;
+    }
+    *pdata = SecXPCDictionaryCopyData(message, key, error);
+    return *pdata;
+}
+
+CFDictionaryRef SecXPCDictionaryCopyDictionary(xpc_object_t message, const char *key, CFErrorRef *error) {
+    CFTypeRef dict = SecXPCDictionaryCopyPList(message, key, error);
+    if (dict) {
+        CFTypeID type_id = CFGetTypeID(dict);
+        if (type_id != CFDictionaryGetTypeID()) {
+            CFStringRef description = CFCopyTypeIDDescription(type_id);
+            SecError(errSecParam, error, CFSTR("object for key %s not dictionary but %@"), key, description);
+            CFReleaseNull(description);
+            CFReleaseNull(dict);
+        }
+    }
+    return (CFDictionaryRef)dict;
+}
+
+bool SecXPCDictionaryCopyDictionaryOptional(xpc_object_t message, const char *key, CFDictionaryRef *pdictionary, CFErrorRef *error) {
+    if (!xpc_dictionary_get_value(message, key)) {
+        *pdictionary = NULL;
+        return true;
+    }
+    *pdictionary = SecXPCDictionaryCopyDictionary(message, key, error);
+    return *pdictionary;
+}
+
+CFTypeRef SecXPCDictionaryCopyPList(xpc_object_t message, const char *key, CFErrorRef *error)
+{
+    CFTypeRef cfobject = NULL;
+    size_t size = 0;
+    const uint8_t *der = xpc_dictionary_get_data(message, key, &size);
+    if (!der) {
+        SecError(errSecParam, error, CFSTR("no object for key %s"), key);
+        return NULL;
+    }
+
+    const uint8_t *der_end = der + size;
+    der = der_decode_plist(kCFAllocatorDefault, kCFPropertyListImmutable,
+                                          &cfobject, error, der, der_end);
+    if (der != der_end) {
+        SecError(errSecParam, error, CFSTR("trailing garbage after der decoded object for key %s"), key);
+        CFReleaseNull(cfobject);
+    }
+    return cfobject;
+}
+
+bool SecXPCDictionaryCopyPListOptional(xpc_object_t message, const char *key, CFTypeRef *pobject, CFErrorRef *error) {
+    size_t size = 0;
+    if (!xpc_dictionary_get_data(message, key, &size)) {
+        *pobject = NULL;
+        return true;
+    }
+    *pobject = SecXPCDictionaryCopyPList(message, key, error);
+    return *pobject;
+}
+
+CFStringRef SecXPCDictionaryCopyString(xpc_object_t message, const char *key, CFErrorRef *error) {
+    const char *string = xpc_dictionary_get_string(message, key);
+    if (string) {
+        CFStringRef result = CFStringCreateWithCString(kCFAllocatorDefault, string, kCFStringEncodingUTF8);
+        if (!result) {
+            SecError(errSecAllocate, error, CFSTR("object for key %s failed to convert %s to CFString"), key, string);
+        }
+        return result;
+    } else {
+        SecError(errSecParam, error, CFSTR("object for key %s not string"), key);
+        return NULL;
+    }
+}
diff --git a/sec/Security/SecuritydXPC.h b/sec/Security/SecuritydXPC.h
new file mode 100644 (file)
index 0000000..1d87ddf
--- /dev/null
@@ -0,0 +1,38 @@
+//
+//  SecuritydXPC.h
+//  sec
+//
+//  Created by Mitch Adler on 11/16/12.
+//
+//
+
+#include <xpc/xpc.h>
+#include <CoreFoundation/CFError.h>
+
+#ifndef _UTILITIES_SECURITYDXPC_H_
+#define _UTILITIES_SECURITYDXPC_H_
+
+bool SecXPCDictionarySetData(xpc_object_t message, const char *key, CFDataRef data, CFErrorRef *error);
+bool SecXPCDictionarySetDataOptional(xpc_object_t message, const char *key, CFDataRef data, CFErrorRef *error);
+
+bool SecXPCDictionarySetPList(xpc_object_t message, const char *key, CFTypeRef object, CFErrorRef *error);
+bool SecXPCDictionarySetPListOptional(xpc_object_t message, const char *key, CFTypeRef object, CFErrorRef *error);
+
+bool SecXPCDictionarySetString(xpc_object_t message, const char *key, CFStringRef string, CFErrorRef *error);
+
+CFTypeRef SecXPCDictionaryCopyPList(xpc_object_t message, const char *key, CFErrorRef *error);
+bool SecXPCDictionaryCopyPListOptional(xpc_object_t message, const char *key, CFTypeRef *pobject, CFErrorRef *error);
+
+CFArrayRef SecXPCDictionaryCopyArray(xpc_object_t message, const char *key, CFErrorRef *error);
+bool SecXPCDictionaryCopyArrayOptional(xpc_object_t message, const char *key, CFArrayRef *parray, CFErrorRef *error);
+
+CFDataRef SecXPCDictionaryCopyData(xpc_object_t message, const char *key, CFErrorRef *error);
+bool SecXPCDictionaryCopyDataOptional(xpc_object_t message, const char *key, CFDataRef *pdata, CFErrorRef *error);
+
+CFDictionaryRef SecXPCDictionaryCopyDictionary(xpc_object_t message, const char *key, CFErrorRef *error);
+
+CFStringRef SecXPCDictionaryCopyString(xpc_object_t message, const char *key, CFErrorRef *error);
+bool SecXPCDictionaryCopyDictionaryOptional(xpc_object_t message, const char *key, CFDictionaryRef *pdictionary, CFErrorRef *error);
+
+
+#endif
diff --git a/sec/Security/Tool/SecurityCommands.h b/sec/Security/Tool/SecurityCommands.h
new file mode 100644 (file)
index 0000000..e03f901
--- /dev/null
@@ -0,0 +1,129 @@
+// This is a preprocessed file to define commands that we provide in Security part of the Sec module.
+
+#include <SecurityTool/security_tool_commands.h>
+
+SECURITY_COMMAND("add-internet-password", keychain_add_internet_password,
+                 "[-a accountName] [-d securityDomain] [-p path] [-P port] [-r protocol] [-s serverName] [-t authenticationType] [-w passwordData] [keychain]\n"
+                 "    -a Use \"accountName\".\n"
+                 "    -d Use \"securityDomain\".\n"
+                 "    -p Use \"path\".\n"
+                 "    -P Use \"port\".\n"
+                 "    -r Use \"protocol\".\n"
+                 "    -s Use \"serverName\".\n"
+                 "    -t Use \"authenticationType\".\n"
+                 "    -w Use passwordData.\n"
+                 "If no keychains is specified the password is added to the default keychain.",
+                 "Add an internet password item.")
+
+SECURITY_COMMAND("item", keychain_item,
+                 "[-v][-a|-D|-u attr=value,...|[-q][-g] attr=value,...] [-d password | -f datafile] [attr=value,...]\n"
+                 "-q Query for item matching (default)\n"
+                 "-g Get password data\n"
+                 "-a Add item to keychain\n"
+                 "-u Update item in keychain (require query to match)\n"
+                 "-D Delete item from keychain\n"
+                 "Add, query, update or delete items from the keychain.  Extra attr=value pairs after options always apply to the query\n"
+                 "class=[genp|inet|cert|keys] is required for the query",
+                 "Manipulate keychain items.")
+
+SECURITY_COMMAND_IOS("add-certificates", keychain_add_certificates,
+                 "[-k keychain] file...\n"
+                 "If no keychains is specified the certificates are added to the default keychain.\n"
+                 "\tadd-certificates -t file...\n"
+                 "Add the specified certificates to the users TrustSettings.sqlite3 database.",
+                 "Add certificates to the keychain.")
+
+SECURITY_COMMAND_IOS("show-certificates", keychain_show_certificates,
+                 "[-p][-s][-t] file...\n"
+                 "[-k][-p][-s][-v][-t][-f][-q attr=value,...] [attr=value,...]\n"
+                 "    -k Show all certificates in keychain.\n"
+                 "    -q Query for certificates matching (implies -k)\n"
+                 "    -p Output cert in PEM format.\n"
+                 "    -f Show fingerprint (SHA1 digest of octects inside the public key bit string.)\n"
+                 "    -s Show subject.\n"
+                 "    -v Show entire certificate in text form.\n"
+                 "    -t Evaluate trust.",
+                 "Display certificates in human readable form.")
+
+SECURITY_COMMAND("find-internet-password", keychain_find_internet_password,
+                 "[-a accountName] [-d securityDomain] [-g] [-p path] [-P port] [-r protocol] [-s serverName] [-t authenticationType] [keychain...]\n"
+                 "    -a Match on \"accountName\" when searching.\n"
+                 "    -d Match on \"securityDomain\" when searching.\n"
+                 "    -g Display the password for the item found.\n"
+                 "    -p Match on \"path\" when searching.\n"
+                 "    -P Match on \"port\" when searching.\n"
+                 "    -r Match on \"protocol\" when searching.\n"
+                 "    -s Match on \"serverName\" when searching.\n"
+                 "    -t Match on \"authenticationType\" when searching.\n"
+                 "If no keychains are specified the default search list is used.",
+                 "Find an internet password item.")
+
+SECURITY_COMMAND("find-generic-password", keychain_find_generic_password,
+                 "[-a accountName] [-s serviceName] [keychain...]\n"
+                 "    -a Match on \"accountName\" when searching.\n"
+                 "    -g Display the password for the item found.\n"
+                 "    -s Match on \"serviceName\" when searching.\n"
+                 "If no keychains are specified the default search list is used.",
+                 "Find a generic password item.")
+
+SECURITY_COMMAND("delete-internet-password", keychain_delete_internet_password,
+                 "[-a accountName] [-d securityDomain] [-g] [-p path] [-P port] [-r protocol] [-s serverName] [-t authenticationType] [keychain...]\n"
+                 "    -a Match on \"accountName\" when searching.\n"
+                 "    -d Match on \"securityDomain\" when searching.\n"
+                 "    -g Display the password for the item found.\n"
+                 "    -p Match on \"path\" when searching.\n"
+                 "    -P Match on \"port\" when searching.\n"
+                 "    -r Match on \"protocol\" when searching.\n"
+                 "    -s Match on \"serverName\" when searching.\n"
+                 "    -t Match on \"authenticationType\" when searching.\n"
+                 "If no keychains are specified the default search list is used.",
+                 "Delete one or more internet password items.")
+
+SECURITY_COMMAND("delete-generic-password", keychain_delete_generic_password,
+                 "[-a accountName] [-s serviceName] [keychain...]\n"
+                 "    -a Match on \"accountName\" when searching.\n"
+                 "    -g Display the password for the item found.\n"
+                 "    -s Match on \"serviceName\" when searching.\n"
+                 "If no keychains are specified the default search list is used.",
+                 "Delete one or more generic password items.")
+
+SECURITY_COMMAND_IOS("keychain-export", keychain_export,
+                 "-k <keybag> [-p password ] <plist>\n"
+                 "    <keybag>   keybag file name. (Can be created with keystorectl)\n"
+                 "    <password> backup password (optional)\n"
+                 "    <plist>    backup plist file\n",
+                 "Export keychain to a plist file.")
+
+SECURITY_COMMAND_IOS("keychain-import", keychain_import,
+                 "-k <keybag> [-p <password> ] <plist>\n"
+                 "    <keybag>   keybag file name. (Can be created with keystorectl)\n"
+                 "    <password> backup password (optional)\n"
+                 "    <plist>    backup plist file\n",
+                 "Import keychain from a plist file.")
+
+SECURITY_COMMAND_IOS("pkcs12", pkcs12_util,
+                 "[options] -p <password> file\n"
+                 "  -d           delete identity\n",
+                 "Manipulate pkcs12 blobs.")
+
+SECURITY_COMMAND_IOS("scep", command_scep,
+                 "[options] <url>\n"
+                 "   -b keysize      Keysize in bits.\n"
+                 "   -u usage        Key usage bitmask in decimal (Digital Signature = 1, Key Encipherment = 4).\n"
+                 "   -c challenge    Challenge password.\n"
+                 "   -n name         Service instance name (required for MS SCEP).\n"
+                 "   -v              Verbose.\n"
+                 "   -x              Turn cert validation off.\n"
+                 "   -s subject      Subject to request (O=Apple,CN=iPhone).\n"
+                 "   -h subjaltname  SubjectAlternateName (foo.com).\n"
+                 "   -o capabilities Override capabilities GetCACaps returns (POSTPKIOperation,SHA-1,DES3)\n",
+                 "Certify a public key using a SCEP server")
+
+SECURITY_COMMAND_IOS("codesign", codesign_util,
+                 "[options] <file>\n",
+                 "Verify code signature blob in binary.")
+
+SECURITY_COMMAND_IOS("enroll-secure-profile", command_spc,
+                 "[options] <file>\n",
+                 "Enroll in secure profile service.")
+
diff --git a/sec/Security/Tool/add_internet_password.c b/sec/Security/Tool/add_internet_password.c
new file mode 100644 (file)
index 0000000..9c36c11
--- /dev/null
@@ -0,0 +1,170 @@
+//
+//  add_internet_password.c
+//  sec
+//
+//  Created by Mitch Adler on 1/9/13.
+//
+//
+
+#include <string.h>
+#include <getopt.h>
+#include <stdlib.h>
+
+#include <Security/SecItem.h>
+#include <CoreFoundation/CFString.h>
+#include <CoreFoundation/CFNumber.h>
+
+#include <SecurityTool/tool_errors.h>
+
+#include "SecurityCommands.h"
+
+typedef uint32_t SecProtocolType;
+typedef uint32_t SecAuthenticationType;
+
+static int
+do_addinternetpassword(const char *keychainName, const char *serverName,
+                       const char *securityDomain, const char *accountName, const char *path,
+                       UInt16 port, SecProtocolType protocol,
+                       SecAuthenticationType authenticationType, const void *passwordData)
+{
+       OSStatus result;
+    CFDictionaryRef attributes = NULL;
+    const void *keys[9], *values[9];
+    CFIndex ix = 0;
+    
+    keys[ix] = kSecClass;
+    values[ix++] = kSecClassInternetPassword;
+    
+       if (serverName) {
+               keys[ix] = kSecAttrServer;
+               values[ix++] = CFStringCreateWithCStringNoCopy(NULL, serverName,
+                                                       kCFStringEncodingUTF8, kCFAllocatorNull);
+       }
+       if (securityDomain) {
+               keys[ix] = kSecAttrSecurityDomain;
+               values[ix++] = CFStringCreateWithCStringNoCopy(NULL, securityDomain,
+                                                       kCFStringEncodingUTF8, kCFAllocatorNull);
+       }
+       if (accountName) {
+               keys[ix] = kSecAttrAccount;
+               values[ix++] = CFStringCreateWithCStringNoCopy(NULL, accountName,
+                                                       kCFStringEncodingUTF8, kCFAllocatorNull);
+       }
+       if (path) {
+               keys[ix] = kSecAttrPath;
+               values[ix++] = CFStringCreateWithCStringNoCopy(NULL, path,
+                                                       kCFStringEncodingUTF8, kCFAllocatorNull);
+       }
+    keys[ix] = kSecAttrPort;
+    values[ix++] = CFNumberCreate(NULL, kCFNumberSInt16Type, &port);
+    /* Protocol is a 4 char code, perhaps we should use a string rep instead. */
+    keys[ix] = kSecAttrProtocol;
+    values[ix++] = CFNumberCreate(NULL, kCFNumberSInt32Type, &protocol);
+    keys[ix] = kSecAttrAuthenticationType;
+    values[ix++] = CFNumberCreate(NULL, kCFNumberSInt32Type, &authenticationType);
+    
+    if (passwordData)
+    {
+        keys[ix] = kSecValueData;
+        values[ix++] = CFDataCreateWithBytesNoCopy(NULL, passwordData,
+                                                   strlen(passwordData), kCFAllocatorNull);
+    }
+    
+    attributes = CFDictionaryCreate(NULL, keys, values, ix,
+                                    &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    
+       /* Release the values we just added to the dictionary. */
+       /* @@@ For performance reasons we could choose to make the dictionaries
+     CFRetain callback a no op and let the dictionary deal with the
+     releasing. */
+    for (; ix-- > 0;)
+        CFRelease(values[ix]);
+    
+       result = SecItemAdd(attributes, NULL);
+    
+    if (attributes)
+        CFRelease(attributes);
+    
+       if (result)
+       {
+               sec_perror("SecItemAdd", result);
+       }
+    
+       return result;
+}
+
+
+int keychain_add_internet_password(int argc, char * const *argv)
+{
+       char *serverName = NULL, *securityDomain = NULL, *accountName = NULL, *path = NULL, *passwordData  = NULL;
+    UInt16 port = 0;
+    SecProtocolType protocol = 0;
+    SecAuthenticationType authenticationType = 0;
+       int ch, result = 0;
+       const char *keychainName = NULL;
+    /*
+     -s Use servername\n"
+     "    -e Use securitydomain\n"
+     "    -a Use accountname\n"
+     "    -p Use path\n"
+     "    -o Use port \n"
+     "    -r Use protocol \n"
+     "    -c Use SecAuthenticationType  \n"
+     "    -w Use passwordData  \n"
+     */
+       while ((ch = getopt(argc, argv, "s:d:a:p:P:r:t:w:h")) != -1)
+       {
+               switch  (ch)
+               {
+            case 's':
+                serverName = optarg;
+                break;
+            case 'd':
+                securityDomain = optarg;
+                break;
+            case 'a':
+                accountName = optarg;
+                break;
+            case 'p':
+                path = optarg;
+                break;
+            case 'P':
+                port = atoi(optarg);
+                break;
+            case 'r':
+                memcpy(&protocol,optarg,4);
+                //protocol = (SecProtocolType)optarg;
+                break;
+            case 't':
+                memcpy(&authenticationType,optarg,4);
+                break;
+            case 'w':
+                passwordData = optarg;
+                break;
+            case '?':
+            default:
+                return 2; /* @@@ Return 2 triggers usage message. */
+               }
+       }
+    
+       argc -= optind;
+       argv += optind;
+    
+       if (argc == 1)
+       {
+               keychainName = argv[0];
+               if (*keychainName == '\0')
+               {
+                       result = 2;
+                       goto loser;
+               }
+       }
+       else if (argc != 0)
+               return 2;
+    
+       result = do_addinternetpassword(keychainName, serverName, securityDomain,
+                                    accountName, path, port, protocol,authenticationType, passwordData);
+    
+loser:
+       return result;
+}
diff --git a/sec/Security/Tool/codesign.c b/sec/Security/Tool/codesign.c
new file mode 100644 (file)
index 0000000..38e90a5
--- /dev/null
@@ -0,0 +1,424 @@
+/*
+ * Copyright (c) 2008,2010 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#include <TargetConditionals.h>
+#if TARGET_OS_EMBEDDED
+
+#include "SecurityCommands.h"
+
+#include <AssertMacros.h>
+#include <mach-o/loader.h>
+#include <mach-o/fat.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCMS.h>
+#include <Security/SecPolicyPriv.h>
+#include <CommonCrypto/CommonDigest.h>
+#include <CommonCrypto/CommonDigestSPI.h>
+
+/*
+ * Magic numbers used by Code Signing
+ */
+enum {
+       CSMAGIC_REQUIREMENT     = 0xfade0c00,           /* single Requirement blob */
+       CSMAGIC_REQUIREMENTS = 0xfade0c01,              /* Requirements vector (internal requirements) */
+       CSMAGIC_CODEDIRECTORY = 0xfade0c02,             /* CodeDirectory blob */
+       CSMAGIC_EMBEDDED_SIGNATURE = 0xfade0cc0, /* embedded form of signature data */
+       CSMAGIC_DETACHED_SIGNATURE = 0xfade0cc1, /* multi-arch collection of embedded signatures */
+       
+       CSSLOT_CODEDIRECTORY = 0,                               /* slot index for CodeDirectory */
+};
+
+
+/*
+ * Structure of an embedded-signature SuperBlob
+ */
+typedef struct __BlobIndex {
+       uint32_t type;                                  /* type of entry */
+       uint32_t offset;                                /* offset of entry */
+} CS_BlobIndex;
+
+typedef struct __SuperBlob {
+       uint32_t magic;                                 /* magic number */
+       uint32_t length;                                /* total length of SuperBlob */
+       uint32_t count;                                 /* number of index entries following */
+       CS_BlobIndex index[];                   /* (count) entries */
+       /* followed by Blobs in no particular order as indicated by offsets in index */
+} CS_SuperBlob;
+
+
+/*
+ * C form of a CodeDirectory.
+ */
+typedef struct __CodeDirectory {
+       uint32_t magic;                                 /* magic number (CSMAGIC_CODEDIRECTORY) */
+       uint32_t length;                                /* total length of CodeDirectory blob */
+       uint32_t version;                               /* compatibility version */
+       uint32_t flags;                                 /* setup and mode flags */
+       uint32_t hashOffset;                    /* offset of hash slot element at index zero */
+       uint32_t identOffset;                   /* offset of identifier string */
+       uint32_t nSpecialSlots;                 /* number of special hash slots */
+       uint32_t nCodeSlots;                    /* number of ordinary (code) hash slots */
+       uint32_t codeLimit;                             /* limit to main image signature range */
+       uint8_t hashSize;                               /* size of each hash in bytes */
+       uint8_t hashType;                               /* type of hash (cdHashType* constants) */
+       uint8_t spare1;                                 /* unused (must be zero) */
+       uint8_t pageSize;                               /* log2(page size in bytes); 0 => infinite */
+       uint32_t spare2;                                /* unused (must be zero) */
+       /* followed by dynamic content as located by offset fields above */
+} CS_CodeDirectory;
+
+
+       //assert(page < ntohl(cd->nCodeSlots));
+       //return base + ntohl(cd->hashOffset) + page * 20;
+
+#if 0
+static void debug_data(uint8_t *data, size_t length)
+{
+    uint32_t i, j;
+    for (i = 0; i < length; i+=16) {
+        fprintf(stderr, "%p   ", (void*)(data+i));
+        for (j = 0; (j < 16) && (j+i < length); j++) {
+            uint8_t byte = *(uint8_t*)(data+i+j);
+            fprintf(stderr, "%.02x %c|", byte, isprint(byte) ? byte : '?');
+        }
+        fprintf(stderr, "\n");
+    }
+}
+
+static void write_data(const char *path, uint8_t *data, size_t length)
+{
+    int fd = open(path, O_RDWR|O_TRUNC|O_CREAT, 0644);
+    require(fd>0, out);
+    write(fd, data, length);
+    close(fd);
+out:
+    return;
+}
+#endif
+
+static void fprint_digest(FILE *file, unsigned char *digest, size_t length) {
+    size_t ix;
+    for (ix = 0; ix < length; ++ix) {
+        fprintf(file, "%02x", digest[ix]);
+    }
+}
+
+static CFMutableDictionaryRef lc_code_sig(uint8_t *lc_code_signature, size_t lc_code_signature_len)
+{
+    CFMutableDictionaryRef code_signature =
+        CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+                &kCFTypeDictionaryKeyCallBacks,
+                &kCFTypeDictionaryValueCallBacks);
+    require(code_signature, out);
+
+    CS_SuperBlob *sb = (CS_SuperBlob*)lc_code_signature;
+    require(ntohl(sb->magic) == CSMAGIC_EMBEDDED_SIGNATURE, out);
+    uint32_t count;
+    for (count = 0; count < ntohl(sb->count); count++) {
+        //uint32_t type = ntohl(sb->index[count].type);
+        uint32_t offset = ntohl(sb->index[count].offset);
+        uint8_t *bytes = lc_code_signature + offset;
+        //fprintf(stderr, "blob[%d]: (type: 0x%.08x, offset: %p)\n", count, type, (void*)offset);
+        uint32_t magic = ntohl(*(uint32_t*)bytes);
+        uint32_t length = ntohl(*(uint32_t*)(bytes+4));
+        //fprintf(stderr, "    magic: 0x%.08x length: %d\n", magic, length);
+        switch(magic) {
+            case 0xfade0c01: //write_data("requirements", bytes, length);
+                break;
+            case 0xfade0c02: //write_data("codedir", bytes, length);
+            {
+                const CS_CodeDirectory *cd = (const CS_CodeDirectory *)bytes;
+                CFDataRef codedir = CFDataCreate(kCFAllocatorDefault, bytes, length);
+                require(codedir, out);
+                CFDictionarySetValue(code_signature, CFSTR("CodeDirectory"), codedir);
+                CFRelease(codedir);
+                require_string(ntohl(cd->version) >= 0x20001, out, "incompatible version");
+                require_string(ntohl(cd->version) <= 0x2F000, out, "incompatible version");
+                require_string(cd->hashSize == 20, out, "unexpected hash size");
+                require_string(cd->hashType == 1, out, "unexpected hash type");
+
+                uint32_t hash_offset = ntohl(cd->hashOffset);
+                uint32_t entitlement_slot = 5;
+
+                if (ntohl(cd->nSpecialSlots) >= entitlement_slot) {
+                    CFDataRef message = CFDataCreate(kCFAllocatorDefault, bytes+hash_offset-entitlement_slot*cd->hashSize, cd->hashSize);
+                    require(message, out);
+                    CFDictionarySetValue(code_signature, CFSTR("EntitlementsCDHash"), message);
+                    CFRelease(message);
+                } else
+                    fprintf(stderr, "no entitlements slot yet\n");
+            }
+                break;
+            case 0xfade0b01:  //write_data("signed", lc_code_signature, bytes-lc_code_signature);
+                if (length != 8) {
+                    CFDataRef message = CFDataCreate(kCFAllocatorDefault, bytes+8, length-8);
+                    require(message, out);
+                    CFDictionarySetValue(code_signature, CFSTR("SignedData"), message);
+                    CFRelease(message);
+                }
+                break;
+            case 0xfade7171:
+            {
+                unsigned char digest[CC_SHA1_DIGEST_LENGTH];
+                CCDigest(kCCDigestSHA1, bytes, length, digest);
+
+                CFDataRef message = CFDataCreate(kCFAllocatorDefault, digest, sizeof(digest));
+                require(message, out);
+                CFDictionarySetValue(code_signature, CFSTR("EntitlementsHash"), message);
+                CFRelease(message);
+                message = CFDataCreate(kCFAllocatorDefault, bytes+8, length-8);
+                require(message, out);
+                CFDictionarySetValue(code_signature, CFSTR("Entitlements"), message);
+                CFRelease(message);
+                break;
+            }
+            default:                
+                fprintf(stderr, "Skipping block with magic: 0x%x\n", magic);
+                break;
+        }
+    }
+    return code_signature;
+out:
+    if (code_signature) CFRelease(code_signature);
+    return NULL;
+}
+
+static FILE *
+open_bundle(const char * path, const char * mode)
+{
+    char full_path[1024] = {};
+    CFStringRef path_cfstring = NULL;
+    CFURLRef path_url = NULL;
+    CFBundleRef bundle = NULL;
+
+    path_cfstring = CFStringCreateWithFileSystemRepresentation(kCFAllocatorDefault, path);
+    require_quiet(path_cfstring, out);
+    path_url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path_cfstring, kCFURLPOSIXPathStyle, true);
+    require_quiet(path_url, out);
+       bundle =  CFBundleCreate(kCFAllocatorDefault, path_url);
+    require_quiet(bundle, out);
+    CFURLRef exec = CFBundleCopyExecutableURL(bundle);
+    require(exec, out);
+    require(CFURLGetFileSystemRepresentation(exec, true, (uint8_t*)full_path, sizeof(full_path)), out);
+out:
+    if (path_cfstring) CFRelease(path_cfstring);
+    if (path_url) CFRelease(path_url);
+    if (bundle) CFRelease(bundle);
+
+    return fopen(full_path, "r");
+}
+
+static CFMutableDictionaryRef load_code_signature(FILE *binary, size_t slice_offset)
+{
+    bool signature_found = false;
+    CFMutableDictionaryRef result = NULL;
+    struct load_command lc;
+    do {
+        require(1 == fread(&lc, sizeof(lc), 1, binary), out);
+        if (lc.cmd == LC_CODE_SIGNATURE) {
+            struct { uint32_t offset; uint32_t size; } sig;
+            require(1 == fread(&sig, sizeof(sig), 1, binary), out);
+            require_noerr(fseek(binary, slice_offset+sig.offset, SEEK_SET), out);
+            size_t length = sig.size;
+            uint8_t *data = malloc(length);
+            require(length && data, out);
+            require(1 == fread(data, length, 1, binary), out);
+            signature_found = true;
+            result = lc_code_sig(data, length);
+            free(data);
+            break;
+        }
+        require_noerr(fseek(binary, lc.cmdsize-sizeof(lc), SEEK_CUR), out);
+    } while(lc.cmd || lc.cmdsize); /* count lc */
+out:
+    if (!signature_found)
+        fprintf(stderr, "No LC_CODE_SIGNATURE segment found\n");
+    return result;
+}
+
+static CFArrayRef load_code_signatures(const char *path)
+{
+    bool fully_parsed_binary = false;
+    CFMutableDictionaryRef result = NULL;
+    CFMutableArrayRef results = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+
+    FILE *binary = open_bundle(path, "r");
+    if (!binary) binary = fopen(path, "r");
+    require(binary, out);
+
+    struct mach_header header;
+    require(1 == fread(&header, sizeof(header), 1, binary), out);
+    if ((header.magic == MH_MAGIC) || (header.magic == MH_MAGIC_64)) {
+       if (header.magic == MH_MAGIC_64)
+               fseek(binary, sizeof(struct mach_header_64) - sizeof(struct mach_header), SEEK_CUR);
+        result = load_code_signature(binary, 0 /*non fat*/);
+        require(result, out);
+        CFStringRef type = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("CPU type: (%d,%d)"), header.cputype, header.cpusubtype);
+        CFDictionarySetValue(result, CFSTR("ARCH"), type);
+        CFRelease(type);
+        CFArrayAppendValue(results, result);
+    }
+    else
+    {
+        struct fat_header fat;
+        require(!fseek(binary, 0L, SEEK_SET), out);
+        require(1 == fread(&fat, sizeof(fat), 1, binary), out);
+        require(ntohl(fat.magic) == FAT_MAGIC, out);
+        uint32_t slice, slices = ntohl(fat.nfat_arch);
+        struct fat_arch *archs = calloc(slices, sizeof(struct fat_arch));
+        require(slices == fread(archs, sizeof(struct fat_arch), slices, binary), out);
+        for (slice = 0; slice < slices; slice++) {
+            uint32_t slice_offset = ntohl(archs[slice].offset);
+            require(!fseek(binary, slice_offset, SEEK_SET), out);
+            require(1 == fread(&header, sizeof(header), 1, binary), out);
+           require((header.magic == MH_MAGIC) || (header.magic == MH_MAGIC_64), out);
+           if (header.magic == MH_MAGIC_64)
+                   fseek(binary, sizeof(struct mach_header_64) - sizeof(struct mach_header), SEEK_CUR);
+            result = load_code_signature(binary, slice_offset);
+            require(result, out);
+            CFStringRef type = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("CPU type: (%d,%d)"), header.cputype, header.cpusubtype);
+            CFDictionarySetValue(result, CFSTR("ARCH"), type);
+            CFRelease(type);
+            CFArrayAppendValue(results, result);
+            CFRelease(result);
+        }
+    }
+    fully_parsed_binary = true;
+out:
+    if (!fully_parsed_binary) {
+        if (results) {
+            CFRelease(results);
+            results = NULL;
+        }
+    }
+    if (binary)
+        fclose(binary);
+    return results;
+}
+
+
+extern int codesign_util(int argc, char * const *argv)
+{
+    int             result = 1, verbose = 0;
+    char            ch;
+
+    while ((ch = getopt(argc, argv, "v")) != -1)
+    {
+        switch (ch)
+        {
+        case 'v':
+            verbose++;
+            break;
+        default:
+            return 2; /* Trigger usage message. */
+        }
+    }
+    
+       argc -= optind;
+       argv += optind;
+
+    if (argc != 1)
+        return 2; /* Trigger usage message. */
+
+    CFArrayRef sigs = load_code_signatures(argv[0]);
+    require(sigs, out);
+
+    if (verbose >= 2)
+        CFShow(sigs);
+
+    CFIndex i, count = CFArrayGetCount(sigs);
+    
+    for (i = 0; i < count; i++) {
+        CFDictionaryRef signature = CFArrayGetValueAtIndex(sigs, i);
+
+        CFDataRef code_dir = CFDictionaryGetValue(signature, CFSTR("CodeDirectory"));
+        const CS_CodeDirectory *cd = (CS_CodeDirectory *)CFDataGetBytePtr(code_dir);
+
+        CFDataRef signed_data = CFDictionaryGetValue(signature, CFSTR("SignedData"));
+
+        CFDataRef entitlements = CFDictionaryGetValue(signature, CFSTR("Entitlements"));
+        CFDataRef entitlements_cd_hash = CFDictionaryGetValue(signature, CFSTR("EntitlementsCDHash"));
+        CFDataRef entitlements_hash = CFDictionaryGetValue(signature, CFSTR("EntitlementsHash"));
+
+        CFStringRef arch = CFDictionaryGetValue(signature, CFSTR("ARCH"));
+        
+        CFShow(arch);
+
+        SecPolicyRef policy = SecPolicyCreateiPhoneApplicationSigning();
+
+        if (signed_data) {
+            if (SecCMSVerify(signed_data, code_dir, policy, NULL, NULL)) {
+                fprintf(stderr, "Failed to verify signature\n");
+                result = -1;
+            } else
+                fprintf(stderr, "Signature ok\n");
+
+        } else
+            fprintf(stderr, "Ad-hoc signed binary\n");
+
+        if (entitlements_cd_hash) {
+            if (entitlements_hash && entitlements_cd_hash && CFEqual(entitlements_hash, entitlements_cd_hash))
+                fprintf(stderr, "Entitlements ok\n");
+            else
+                fprintf(stderr, "Entitlements modified\n");
+        }
+
+        if (verbose >= 2) {
+            fprintf(stderr, "magic: 0x%x length: %u(%lu)\n", ntohl(cd->magic), ntohl(cd->length), CFDataGetLength(code_dir));
+            fprintf(stderr, "code directory version/flags: 0x%x/0x%x special/code hash slots: %u/%u\n"
+                "codelimit: %u hash size/type: %u/%u hash/ident offset: %u/%u\n",
+                ntohl(cd->version), ntohl(cd->flags), ntohl(cd->nSpecialSlots), ntohl(cd->nCodeSlots),
+                ntohl(cd->codeLimit), cd->hashSize, cd->hashType, ntohl(cd->hashOffset), ntohl(cd->identOffset));
+            fprintf(stderr, "ident: '%s'\n", CFDataGetBytePtr(code_dir) + ntohl(cd->identOffset));
+
+            uint32_t ix;
+            uint8_t *hashes = (uint8_t *)CFDataGetBytePtr(code_dir) + ntohl(cd->hashOffset);
+            for (ix = 0; ix < ntohl(cd->nSpecialSlots); ++ix) {
+                fprint_digest(stderr, hashes, cd->hashSize);
+                fprintf(stderr, "\n");
+                hashes += cd->hashSize;
+            }
+        }
+
+        if (verbose >= 1) {
+            if (entitlements)
+                fprintf(stderr, "Entitlements\n%.*s", (int)CFDataGetLength(entitlements)-8, CFDataGetBytePtr(entitlements)+8);
+        }
+
+        if (verbose >= 2) {
+            if (entitlements_hash) {
+                fprintf(stderr, "digest: ");
+                fprint_digest(stderr, (uint8_t *)CFDataGetBytePtr(entitlements_hash), CC_SHA1_DIGEST_LENGTH);
+                fprintf(stderr, "\n");
+            }
+        }
+    }
+    
+    CFRelease(sigs);
+
+    return result;
+out:
+    return -1;
+}
+
+#endif // TARGET_OS_EMBEDDED
diff --git a/sec/Security/Tool/keychain_add.c b/sec/Security/Tool/keychain_add.c
new file mode 100644 (file)
index 0000000..b605e2b
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2003-2007,2009-2010 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ *
+ * keychain_add.c
+ */
+
+#include <TargetConditionals.h>
+#if TARGET_OS_EMBEDDED
+
+#include "Securitycommands.h"
+
+#include "security.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <CoreFoundation/CFNumber.h>
+#include <CoreFoundation/CFString.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecTrustStore.h>
+
+#include <SecurityTool/readline.h>
+#include <SecurityTool/tool_errors.h>
+
+static int
+do_add_certificates(const char *keychainName, bool trustSettings,
+       int argc, char * const *argv)
+{
+       int ix, result = 0;
+       OSStatus status;
+
+       CFMutableDictionaryRef attributes =
+               CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+       CFDictionarySetValue(attributes, kSecClass, kSecClassCertificate);
+
+       for (ix = 0; ix < argc; ++ix) {
+        CFDataRef data = copyFileContents(argv[ix]);
+        if (data) {
+            SecCertificateRef cert = SecCertificateCreateWithData(
+                kCFAllocatorDefault, data);
+            if (!cert) {
+                cert = SecCertificateCreateWithPEM(kCFAllocatorDefault, data);
+            }
+            CFRelease(data);
+            if (cert) {
+                               if (trustSettings) {
+                                       SecTrustStoreSetTrustSettings(
+                                               SecTrustStoreForDomain(kSecTrustStoreDomainUser),
+                                               cert, NULL);
+                               } else {
+                                       CFDictionarySetValue(attributes, kSecValueRef, cert);
+                                       status = SecItemAdd(attributes, NULL);
+                                       CFRelease(cert);
+                                       if (status) {
+                                               fprintf(stderr, "file %s: SecItemAdd %s",
+                                                       argv[ix], sec_errstr(status));
+                                               result = 1;
+                                       }
+                               }
+            } else {
+                result = 1;
+                fprintf(stderr, "file %s: does not contain a valid certificate",
+                    argv[ix]);
+            }
+        } else {
+            result = 1;
+        }
+    }
+
+       return result;
+}
+
+
+int
+keychain_add_certificates(int argc, char * const *argv)
+{
+       int ch, result = 0;
+       const char *keychainName = NULL;
+       bool trustSettings = false;
+       while ((ch = getopt(argc, argv, "hk:t")) != -1)
+       {
+               switch  (ch)
+               {
+        case 'k':
+            keychainName = optarg;
+                       if (*keychainName == '\0')
+                               return 2;
+            break;
+        case 't':
+            trustSettings = true;
+            break;
+               case '?':
+               default:
+                       return 2; /* Return 2 triggers usage message. */
+               }
+       }
+
+       argc -= optind;
+       argv += optind;
+
+       if (argc == 0)
+               return 2;
+
+       result = do_add_certificates(keychainName, trustSettings, argc, argv);
+
+       return result;
+}
+
+#endif // TARGET_OS_EMBEDDED
diff --git a/sec/Security/Tool/keychain_backup.c b/sec/Security/Tool/keychain_backup.c
new file mode 100644 (file)
index 0000000..29efe44
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2013 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ *
+ * keychain_backup.c
+ */
+
+#include <TargetConditionals.h>
+#if TARGET_OS_EMBEDDED
+
+#include "Securitycommands.h"
+
+#include <AssertMacros.h>
+#include <Security/SecItemPriv.h>
+
+#include <utilities/SecCFWrappers.h>
+
+#include <SecurityTool/readline.h>
+#include <SecurityTool/tool_errors.h>
+
+
+static int
+do_keychain_import(const char *backupPath, const char *keybagPath, const char *passwordString)
+{
+    CFDataRef backup=NULL;
+    CFDataRef keybag=NULL;
+    CFDataRef password=NULL;
+    bool ok=false;
+
+    if(passwordString) {
+        require(password = CFDataCreate(NULL, (UInt8 *)passwordString, strlen(passwordString)), out);
+    }
+    require(keybag=copyFileContents(keybagPath), out);
+    require(backup=copyFileContents(backupPath), out);
+
+    ok=_SecKeychainRestoreBackup(backup, keybag, password);
+
+out:
+    CFReleaseSafe(backup);
+    CFReleaseSafe(keybag);
+    CFReleaseSafe(password);
+
+    return ok?0:1;
+}
+
+static int
+do_keychain_export(const char *backupPath, const char *keybagPath, const char *passwordString)
+{
+    CFDataRef backup=NULL;
+    CFDataRef keybag=NULL;
+    CFDataRef password=NULL;
+    bool ok=false;
+
+    if(passwordString) {
+        require(password = CFDataCreate(NULL, (UInt8 *)passwordString, strlen(passwordString)), out);
+    }
+    require(keybag=copyFileContents(keybagPath), out);
+    require(backup=_SecKeychainCopyBackup(keybag, password), out);
+
+    ok=writeFileContents(backupPath, backup);
+
+out:
+    CFReleaseSafe(backup);
+    CFReleaseSafe(keybag);
+    CFReleaseSafe(password);
+
+    return ok?0:1;
+}
+
+
+int
+keychain_import(int argc, char * const *argv)
+{
+    int ch;
+    int verbose=0;
+    const char *keybag=NULL;
+    const char *password=NULL;
+
+    while ((ch = getopt(argc, argv, "vk:p:")) != -1)
+    {
+        switch (ch)
+        {
+            case 'v':
+                verbose++;
+                break;
+            case 'k':
+                keybag=optarg;
+                break;
+            case 'p':
+                password=optarg;
+                break;
+             default:
+                return 2; /* Trigger usage message. */
+        }
+    }
+
+    argc -= optind;
+    argv += optind;
+
+    if(keybag==NULL) {
+        sec_error("-k is required\n");
+        return 2;
+    }
+
+    if (argc != 1) {
+        sec_error("<backup> is required\n");
+        return 2; /* Trigger usage message. */
+    }
+    
+    return do_keychain_import(argv[0], keybag, password);
+}
+
+int
+keychain_export(int argc, char * const *argv)
+{
+    int ch;
+    int verbose=0;
+    const char *keybag=NULL;
+    const char *password=NULL;
+
+    while ((ch = getopt(argc, argv, "vk:p:")) != -1)
+    {
+        switch (ch)
+        {
+            case 'v':
+                verbose++;
+                break;
+            case 'k':
+                keybag=optarg;
+                break;
+            case 'p':
+                password=optarg;
+                break;
+            default:
+                return 2; /* Trigger usage message. */
+        }
+    }
+
+    argc -= optind;
+    argv += optind;
+
+    if(keybag==NULL) {
+        sec_error("-k is required\n");
+        return 2;
+    }
+
+    if (argc != 1) {
+        sec_error("<backup> is required\n");
+        return 2; /* Trigger usage message. */
+    }
+
+    return do_keychain_export(argv[0], keybag, password);
+}
+
+#endif /* TARGET_OS_EMBEDDED */
diff --git a/sec/Security/Tool/keychain_find.c b/sec/Security/Tool/keychain_find.c
new file mode 100644 (file)
index 0000000..2b248cc
--- /dev/null
@@ -0,0 +1,572 @@
+//
+//
+//
+//
+
+
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <Security/SecItem.h>
+
+#include <SecurityTool/tool_errors.h>
+#include <SecurityTool/readline.h>
+
+#include <utilities/SecCFWrappers.h>
+
+#include "SecurityCommands.h"
+
+//
+// Craptastic hacks.
+
+typedef uint32_t SecProtocolType;
+typedef uint32_t SecAuthenticationType;
+
+/* Parse a string of the form attr=value,attr=value,attr=value */
+static void
+keychain_query_parse_string(CFMutableDictionaryRef q, CFStringRef s) {
+    bool inkey = true;
+    bool escaped = false;
+    CFStringRef key = NULL;
+    CFMutableStringRef str = CFStringCreateMutable(0, 0);
+    CFRange rng = { .location = 0, .length = CFStringGetLength(s) };
+    CFCharacterSetRef cs_key = CFCharacterSetCreateWithCharactersInString(0, CFSTR("=\\"));
+    CFCharacterSetRef cs_value = CFCharacterSetCreateWithCharactersInString(0, CFSTR(",\\"));
+    while (rng.length) {
+        CFRange r;
+        CFStringRef sub;
+        bool complete = false;
+        if (escaped) {
+            r.location = rng.location;
+            r.length = 1;
+            sub = CFStringCreateWithSubstring(0, s, r);
+            escaped = false;
+        } else if (CFStringFindCharacterFromSet(s, inkey ? cs_key : cs_value, rng, 0, &r)) {
+            if (CFStringGetCharacterAtIndex(s, r.location) == '\\') {
+                escaped = true;
+            } else {
+                complete = true;
+            }
+            CFIndex next = r.location + 1;
+            r.length = r.location - rng.location;
+            r.location = rng.location;
+            sub = CFStringCreateWithSubstring(0, s, r);
+            rng.length -= next - rng.location;
+            rng.location = next;
+        } else {
+            sub = CFStringCreateWithSubstring(0, s, rng);
+            rng.location += rng.length;
+            rng.length = 0;
+            complete = true;
+        }
+        CFStringAppend(str, sub);
+        CFRelease(sub);
+        if (complete) {
+            CFStringRef value = CFStringCreateCopy(0, str);
+            CFStringReplaceAll(str, CFSTR(""));
+            if (inkey) {
+                key = value;
+            } else {
+                CFDictionarySetValue(q, key, value);
+                CFReleaseNull(value);
+                CFReleaseNull(key);
+            }
+            inkey = !inkey;
+        }
+    }
+    if (key) {
+        /* Dangeling key value is true?. */
+        CFDictionarySetValue(q, key, kCFBooleanTrue);
+        CFRelease(key);
+    }
+    
+    CFRelease(str);
+    CFReleaseSafe(cs_key);
+    CFReleaseSafe(cs_value);
+}
+
+static void
+keychain_query_parse_cstring(CFMutableDictionaryRef q, const char *query) {
+    CFStringRef s;
+    s = CFStringCreateWithCStringNoCopy(0, query, kCFStringEncodingUTF8, kCFAllocatorNull);
+    keychain_query_parse_string(q, s);
+    CFRelease(s);
+}
+
+static CFMutableDictionaryRef
+keychain_create_query_from_string(const char *query) {
+    CFMutableDictionaryRef q;
+
+    q = CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    keychain_query_parse_cstring(q, query);
+    return q;
+}
+
+static void add_key(const void *key, const void *value, void *context) {
+    CFArrayAppendValue(context, key);
+}
+
+static void display_item(const void *v_item, void *context) {
+    CFDictionaryRef item = (CFDictionaryRef)v_item;
+    CFIndex dict_count, key_ix, key_count;
+    CFMutableArrayRef keys = NULL;
+    CFIndex maxWidth = 10; /* Maybe precompute this or grab from context? */
+
+    dict_count = CFDictionaryGetCount(item);
+    keys = CFArrayCreateMutable(kCFAllocatorDefault, dict_count,
+        &kCFTypeArrayCallBacks);
+    CFDictionaryApplyFunction(item, add_key, keys);
+    key_count = CFArrayGetCount(keys);
+    CFArraySortValues(keys, CFRangeMake(0, key_count),
+        (CFComparatorFunction)CFStringCompare, 0);
+
+    for (key_ix = 0; key_ix < key_count; ++key_ix) {
+        CFStringRef key = (CFStringRef)CFArrayGetValueAtIndex(keys, key_ix);
+        CFTypeRef value = CFDictionaryGetValue(item, key);
+        CFMutableStringRef line = CFStringCreateMutable(NULL, 0);
+
+        CFStringAppend(line, key);
+        CFIndex jx;
+        for (jx = CFStringGetLength(key);
+            jx < maxWidth; ++jx) {
+            CFStringAppend(line, CFSTR(" "));
+        }
+        CFStringAppend(line, CFSTR(" : "));
+        if (CFStringGetTypeID() == CFGetTypeID(value)) {
+            CFStringAppend(line, (CFStringRef)value);
+        } else if (CFNumberGetTypeID() == CFGetTypeID(value)) {
+            CFNumberRef v_n = (CFNumberRef)value;
+            CFStringAppendFormat(line, NULL, CFSTR("%@"), v_n);
+        } else if (CFDateGetTypeID() == CFGetTypeID(value)) {
+            CFDateRef v_d = (CFDateRef)value;
+            CFStringAppendFormat(line, NULL, CFSTR("%@"), v_d);
+        } else if (CFDataGetTypeID() == CFGetTypeID(value)) {
+            CFDataRef v_d = (CFDataRef)value;
+            CFStringRef v_s = CFStringCreateFromExternalRepresentation(
+                kCFAllocatorDefault, v_d, kCFStringEncodingUTF8);
+            if (v_s) {
+                CFStringAppend(line, CFSTR("/"));
+                CFStringAppend(line, v_s);
+                CFStringAppend(line, CFSTR("/ "));
+                CFRelease(v_s);
+            }
+            const uint8_t *bytes = CFDataGetBytePtr(v_d);
+            CFIndex len = CFDataGetLength(v_d);
+            for (jx = 0; jx < len; ++jx) {
+                CFStringAppendFormat(line, NULL, CFSTR("%.02X"), bytes[jx]);
+            }
+        } else {
+            CFStringAppendFormat(line, NULL, CFSTR("%@"), value);
+        }
+
+        CFStringWriteToFileWithNewline(line, stdout);
+
+               CFRelease(line);
+    }
+    CFRelease(keys);
+    
+    CFStringWriteToFileWithNewline(CFSTR("===="), stdout);
+
+    //CFShow(item);
+}
+
+
+static void display_results(CFTypeRef results) {
+    if (CFGetTypeID(results) == CFArrayGetTypeID()) {
+        CFArrayRef r_a = (CFArrayRef)results;
+        CFArrayApplyFunction(r_a, CFRangeMake(0, CFArrayGetCount(r_a)),
+            display_item, NULL);
+    } else if (CFGetTypeID(results) == CFArrayGetTypeID()) {
+        display_item(results, NULL);
+    } else {
+        fprintf(stderr, "SecItemCopyMatching returned unexpected results:");
+        CFShow(results);
+    }
+}
+
+static OSStatus do_find_or_delete(CFDictionaryRef query, bool do_delete) {
+    OSStatus result;
+    if (do_delete) {
+        result = SecItemDelete(query);
+        if (result) {
+            sec_perror("SecItemDelete", result);
+        }
+    } else {
+        CFTypeRef results = NULL;
+        result = SecItemCopyMatching(query, &results);
+        if (result) {
+            sec_perror("SecItemCopyMatching", result);
+        } else {
+            display_results(results);
+        }
+        CFReleaseSafe(results);
+    }
+    return result;
+}
+
+static int
+do_keychain_find_or_delete_internet_password(Boolean do_delete,
+       const char *serverName, const char *securityDomain,
+       const char *accountName, const char *path, UInt16 port,
+       SecProtocolType protocol, SecAuthenticationType authenticationType,
+       Boolean get_password)
+ {
+       OSStatus result;
+    CFDictionaryRef query = NULL;
+    const void *keys[11], *values[11];
+    CFIndex ix = 0;
+
+    keys[ix] = kSecClass;
+    values[ix++] = kSecClassInternetPassword;
+       if (serverName) {
+               keys[ix] = kSecAttrServer;
+               values[ix++] = CFStringCreateWithCStringNoCopy(NULL, serverName,
+                       kCFStringEncodingUTF8, kCFAllocatorNull);
+       }
+       if (securityDomain) {
+               keys[ix] = kSecAttrSecurityDomain;
+               values[ix++] = CFStringCreateWithCStringNoCopy(NULL, securityDomain,
+                       kCFStringEncodingUTF8, kCFAllocatorNull);
+       }
+       if (accountName) {
+               keys[ix] = kSecAttrAccount;
+               values[ix++] = CFStringCreateWithCStringNoCopy(NULL, accountName,
+                       kCFStringEncodingUTF8, kCFAllocatorNull);
+       }
+       if (path) {
+               keys[ix] = kSecAttrPath;
+               values[ix++] = CFStringCreateWithCStringNoCopy(NULL, path,
+                       kCFStringEncodingUTF8, kCFAllocatorNull);
+       }
+       if (port != 0) {
+               keys[ix] = kSecAttrPort;
+               values[ix++] = CFNumberCreate(NULL, kCFNumberSInt16Type, &port);
+       }
+       if (protocol != 0) {
+               /* Protocol is a 4 char code, perhaps we should use a string rep
+                  instead. */
+               keys[ix] = kSecAttrProtocol;
+               values[ix++] = CFNumberCreate(NULL, kCFNumberSInt32Type, &protocol);
+       }
+       if (authenticationType != 0) {
+               keys[ix] = kSecAttrAuthenticationType;
+               values[ix++] = CFNumberCreate(NULL, kCFNumberSInt32Type,
+                       &authenticationType);
+       }
+    if (get_password) {
+        /* Only ask for the data if so required. */
+               keys[ix] = kSecReturnData;
+               values[ix++] = kCFBooleanTrue;
+    }
+    keys[ix] = kSecReturnAttributes;
+    values[ix++] = kCFBooleanTrue;
+       if (!do_delete) {
+               /* If we aren't deleting ask for all items. */
+               keys[ix] = kSecMatchLimit;
+               values[ix++] = kSecMatchLimitAll;
+       }
+
+    query = CFDictionaryCreate(NULL, keys, values, ix,
+        &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    result = do_find_or_delete(query, do_delete);
+    CFReleaseSafe(query);
+
+       return result;
+}
+
+static int
+parse_fourcharcode(const char *name, uint32_t *code)
+{
+       /* @@@ Check for errors. */
+       char *p = (char *)code;
+       strncpy(p, name, 4);
+       return 0;
+}
+
+static int
+keychain_find_or_delete_internet_password(Boolean do_delete, int argc, char * const *argv)
+{
+       char *serverName = NULL, *securityDomain = NULL, *accountName = NULL, *path = NULL;
+    UInt16 port = 0;
+    SecProtocolType protocol = 0;
+    SecAuthenticationType authenticationType = 0;
+       int ch, result = 0;
+       Boolean get_password = FALSE;
+
+       while ((ch = getopt(argc, argv, "a:d:hgp:P:r:s:t:")) != -1)
+       {
+               switch  (ch)
+               {
+        case 'a':
+            accountName = optarg;
+            break;
+        case 'd':
+            securityDomain = optarg;
+                       break;
+               case 'g':
+            if (do_delete)
+                return 2;
+                       get_password = TRUE;
+                       break;
+        case 'p':
+            path = optarg;
+            break;
+        case 'P':
+            port = atoi(optarg);
+            break;
+        case 'r':
+                       result = parse_fourcharcode(optarg, &protocol);
+                       if (result)
+                               goto loser;
+                       break;
+               case 's':
+                       serverName = optarg;
+                       break;
+        case 't':
+                       result = parse_fourcharcode(optarg, &authenticationType);
+                       if (result)
+                               goto loser;
+                       break;
+        case '?':
+               default:
+                       return 2; /* @@@ Return 2 triggers usage message. */
+               }
+       }
+  
+       argc -= optind;
+       argv += optind;
+
+       result = do_keychain_find_or_delete_internet_password(do_delete, serverName, securityDomain,
+               accountName, path, port, protocol,authenticationType, get_password);
+
+
+loser:
+
+       return result;
+}
+
+int
+keychain_find_internet_password(int argc, char * const *argv) {
+    return keychain_find_or_delete_internet_password(0, argc, argv);
+}
+
+int
+keychain_delete_internet_password(int argc, char * const *argv) {
+    return keychain_find_or_delete_internet_password(1, argc, argv);
+}
+
+static int
+do_keychain_find_or_delete_generic_password(Boolean do_delete,
+       const char *serviceName, const char *accountName,
+       Boolean get_password)
+ {
+       OSStatus result;
+    CFDictionaryRef query = NULL;
+    const void *keys[6], *values[6];
+    CFIndex ix = 0;
+
+    keys[ix] = kSecClass;
+    values[ix++] = kSecClassGenericPassword;
+       if (serviceName) {
+               keys[ix] = kSecAttrService;
+               values[ix++] = CFStringCreateWithCStringNoCopy(NULL, serviceName,
+                       kCFStringEncodingUTF8, kCFAllocatorNull);
+       }
+       if (accountName) {
+               keys[ix] = kSecAttrAccount;
+               values[ix++] = CFStringCreateWithCStringNoCopy(NULL, accountName,
+                       kCFStringEncodingUTF8, kCFAllocatorNull);
+       }
+    if (get_password) {
+        /* Only ask for the data if so required. */
+               keys[ix] = kSecReturnData;
+               values[ix++] = kCFBooleanTrue;
+    }
+    keys[ix] = kSecReturnAttributes;
+    values[ix++] = kCFBooleanTrue;
+       if (!do_delete) {
+               /* If we aren't deleting ask for all items. */
+               keys[ix] = kSecMatchLimit;
+               values[ix++] = kSecMatchLimitAll;
+       }
+
+    query = CFDictionaryCreate(NULL, keys, values, ix,
+        &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+
+    result = do_find_or_delete(query, do_delete);
+
+       CFReleaseSafe(query);
+
+       return result;
+}
+
+int keychain_item(int argc, char * const *argv) {
+       int ch, result = 0;
+    CFMutableDictionaryRef query, update = NULL;
+       bool get_password = false;
+    bool do_delete = false;
+    bool do_add = false;
+    bool verbose = false;
+    int limit = 0;
+
+    query = CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+       while ((ch = getopt(argc, argv, "ad:Df:gq:u:vl:")) != -1)
+       {
+               switch  (ch)
+               {
+            case 'a':
+                do_add = true;
+                break;
+            case 'D':
+                do_delete = true;
+                break;
+            case 'd':
+            {
+                CFStringRef data = CFStringCreateWithCString(0, optarg, kCFStringEncodingUTF8);
+                if (data) {
+                    CFDictionarySetValue(update ? update : query, kSecValueData, data);
+                    CFRelease(data);
+                } else {
+                    result = 1;
+                    goto out;
+                }
+                break;
+            }
+            case 'f':
+            {
+                CFDataRef data = copyFileContents(optarg);
+                CFDictionarySetValue(update ? update : query, kSecValueData, data);
+                CFRelease(data);
+                break;
+            }
+            case 'g':
+                get_password = true;
+                break;
+            case 'q':
+                keychain_query_parse_cstring(query, optarg);
+                break;
+            case 'u':
+                if (!update)
+                    update = keychain_create_query_from_string(optarg);
+                else
+                    keychain_query_parse_cstring(update, optarg);
+                break;
+            case 'v':
+                verbose = true;
+                break;
+            case 'l':
+                limit = atoi(optarg);
+                break;
+            case '?':
+            default:
+                /* Return 2 triggers usage message. */
+                result = 2;
+                goto out;
+               }
+       }
+
+    if (((do_add || do_delete) && (get_password || update)) || !query) {
+        result = 2;
+        goto out;
+    }
+
+       argc -= optind;
+       argv += optind;
+
+    int ix;
+    for (ix = 0; ix < argc; ++ix) {
+        keychain_query_parse_cstring(query, argv[ix]);
+    }
+
+    if (!update && !do_add && !do_delete) {
+        CFDictionarySetValue(query, kSecReturnAttributes, kCFBooleanTrue);
+        if(limit) {
+            CFNumberRef cfLimit = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &limit);
+            CFDictionarySetValue(query, kSecMatchLimit, cfLimit);
+            CFReleaseSafe(cfLimit);
+        } else {
+            CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitAll);
+        }
+        if (get_password)
+            CFDictionarySetValue(query, kSecReturnData, kCFBooleanTrue);
+    }
+
+    if (verbose)
+        CFShow(query);
+
+    OSStatus error;
+    if (do_add) {
+        error = SecItemAdd(query, NULL);
+        if (error) {
+            sec_perror("SecItemAdd", error);
+            result = 1;
+        }
+    } else if (update) {
+        error = SecItemUpdate(query, update);
+        if (error) {
+            sec_perror("SecItemUpdate", error);
+            result = 1;
+        }
+    } else if (do_delete) {
+        error = SecItemDelete(query);
+        if (error) {
+            sec_perror("SecItemDelete", error);
+            result = 1;
+        }
+    } else {
+        do_find_or_delete(query, do_delete);
+    }
+
+out:
+    CFReleaseSafe(query);
+    CFReleaseSafe(update);
+       return result;
+}
+
+static int
+keychain_find_or_delete_generic_password(Boolean do_delete,
+       int argc, char * const *argv)
+{
+       char *serviceName = NULL, *accountName = NULL;
+       int ch, result = 0;
+       Boolean get_password = FALSE;
+
+       while ((ch = getopt(argc, argv, "a:s:g")) != -1)
+       {
+               switch  (ch)
+               {
+        case 'a':
+            accountName = optarg;
+            break;
+        case 'g':
+            if (do_delete)
+                return 2;
+                       get_password = TRUE;
+                       break;
+               case 's':
+                       serviceName = optarg;
+                       break;
+        case '?':
+               default:
+                       return 2; /* @@@ Return 2 triggers usage message. */
+               }
+       }
+  
+       argc -= optind;
+       argv += optind;
+
+       result = do_keychain_find_or_delete_generic_password(do_delete,
+               serviceName, accountName, get_password);
+
+       return result;
+}
+
+int
+keychain_find_generic_password(int argc, char * const *argv) {
+    return keychain_find_or_delete_generic_password(0, argc, argv);
+}
+
+int
+keychain_delete_generic_password(int argc, char * const *argv) {
+    return keychain_find_or_delete_generic_password(1, argc, argv);
+}
diff --git a/sec/Security/Tool/pkcs12_util.c b/sec/Security/Tool/pkcs12_util.c
new file mode 100644 (file)
index 0000000..717a28d
--- /dev/null
@@ -0,0 +1,379 @@
+/*
+ * Copyright (c) 2008-2010 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#include <TargetConditionals.h>
+#if TARGET_OS_EMBEDDED
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <string.h>
+
+#include <CoreFoundation/CFData.h>
+#include <CoreFoundation/CFDictionary.h>
+#include <CoreFoundation/CFNumber.h>
+#include <CoreFoundation/CFString.h>
+#include <Security/SecImportExport.h>
+#include <Security/SecItem.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecIdentity.h>
+#include <Security/SecTrust.h>
+#include <Security/SecInternal.h>
+#include <utilities/array_size.h>
+
+#include "SecurityCommands.h"
+#include "SecurityTool/print_cert.h"
+
+static void *
+read_file(const char * filename, size_t * data_length)
+{
+    void *             data = NULL;
+    int         len = 0;
+    int                        fd = -1;
+    struct stat                sb;
+
+    *data_length = 0;
+    if (stat(filename, &sb) < 0)
+        goto done;
+    if (sb.st_size > INT32_MAX)
+        goto done;
+    len = (uint32_t)sb.st_size;
+    if (len == 0)
+        goto done;
+
+    data = malloc(len);
+    if (data == NULL)
+       goto done;
+
+    fd = open(filename, O_RDONLY);
+    if (fd < 0)
+       goto done;
+
+    if (read(fd, data, len) != len) {
+       goto done;
+    }
+ done:
+    if (fd >= 0)
+       close(fd);
+    if (data) {
+       *data_length = len;
+    }
+    return (data);
+}
+
+static OSStatus
+add_cert_item(SecCertificateRef cert)
+{
+    CFDictionaryRef    dict;
+    OSStatus           status;
+
+    dict = CFDictionaryCreate(NULL, 
+                             (const void * *)&kSecValueRef,
+                             (const void * *)&cert, 1,
+                             &kCFTypeDictionaryKeyCallBacks,
+                             &kCFTypeDictionaryValueCallBacks);
+    status = SecItemAdd(dict, NULL);
+    CFReleaseNull(dict);
+    return (status);
+}
+
+static OSStatus
+remove_cert_item(SecCertificateRef cert)
+{
+    CFDictionaryRef    dict;
+    OSStatus           status;
+
+    dict = CFDictionaryCreate(NULL, 
+                             (const void * *)&kSecValueRef,
+                             (const void * *)&cert, 1,
+                             &kCFTypeDictionaryKeyCallBacks,
+                             &kCFTypeDictionaryValueCallBacks);
+    status = SecItemDelete(dict);
+    CFReleaseNull(dict);
+    if (status == errSecItemNotFound)
+        status = errSecSuccess; /* already gone, no problem */
+    return (status);
+}
+
+static CFArrayRef
+PKCS12FileCreateArray(const char * filename, const char * password)
+{
+    void *             file_data = NULL;
+    size_t             file_data_length;
+    CFArrayRef                 items = NULL;
+    CFDictionaryRef    options = NULL;
+    CFDataRef          pkcs12_data = NULL;
+    CFStringRef        password_cf = NULL;
+
+    file_data = read_file(filename, &file_data_length);
+    if (file_data == NULL) {
+       int     this_error = errno;
+
+       fprintf(stderr, "failed to read file '%s', %s\n",
+               filename, strerror(this_error));
+       goto done;
+    }
+    pkcs12_data = CFDataCreate(NULL, file_data, file_data_length);
+    password_cf
+       = CFStringCreateWithCString(NULL, password, kCFStringEncodingUTF8);
+    
+    options = CFDictionaryCreate(NULL, 
+                                (const void * *)&kSecImportExportPassphrase,
+                                (const void * *)&password_cf, 1, 
+                                &kCFTypeDictionaryKeyCallBacks,
+                                &kCFTypeDictionaryValueCallBacks);
+    if (SecPKCS12Import(pkcs12_data, options, &items) != 0) {
+       fprintf(stderr, "failed to import PKCS12 '%s'\n",
+               filename);
+    }
+ done:
+    if (file_data != NULL) {
+       free(file_data);
+    }
+    CFReleaseNull(pkcs12_data);
+    CFReleaseNull(password_cf);
+    CFReleaseNull(options);
+    return (items);
+}
+
+static void
+find_identity_using_handle(CFTypeRef identity_handle)
+{
+    CFDictionaryRef    dict;
+    CFTypeRef          identity_ref;
+    const void *       keys[] = { kSecClass,
+                                  kSecReturnRef,
+                                  kSecValuePersistentRef };
+    const void *       values[] = { kSecClassIdentity,
+                                    kCFBooleanTrue,
+                                    identity_handle };
+    OSStatus           status;
+
+    /* find the identity using the persistent handle */
+    dict = CFDictionaryCreate(NULL, keys, values,
+                             (array_size(keys)),
+                             &kCFTypeDictionaryKeyCallBacks,
+                             &kCFTypeDictionaryValueCallBacks);
+    status = SecItemCopyMatching(dict, &identity_ref);
+    CFReleaseNull(dict);
+    if (status != errSecSuccess) {
+       fprintf(stderr, "SecItemCopyMatching() failed %d\n", 
+               (int)status);
+    }
+    else {
+       printf("Found identity:\n");
+       fflush(stdout);
+       fflush(stderr);
+       CFShow(identity_ref);
+       CFReleaseNull(identity_ref);
+    }
+    return;
+}
+
+static bool
+PKCS12ArrayAddSecItems(CFArrayRef items, bool verbose)
+{
+    CFIndex            count;
+    CFIndex            i;
+    bool               success = TRUE;
+
+    count = CFArrayGetCount(items);
+    for (i = 0; i < count; i++) {
+        SecTrustRef trust_ref;
+        SecIdentityRef identity;
+        CFDictionaryRef item_dict = CFArrayGetValueAtIndex(items, 0);
+        OSStatus       status;
+
+        /* add identity */
+        identity = (SecIdentityRef)CFDictionaryGetValue(item_dict, kSecImportItemIdentity);
+        if (identity != NULL) {
+            if (verbose) {
+                SecCertificateRef cert = NULL;
+                SecIdentityCopyCertificate(identity, &cert);
+                print_cert(cert, false);
+                CFReleaseSafe(cert);
+            }
+            CFDictionaryRef    dict;
+            CFTypeRef          identity_handle = NULL;
+            const void *       keys[] = { kSecReturnPersistentRef,
+                           kSecValueRef };
+            const void *       values[] = { kCFBooleanTrue,
+                             identity };
+            dict = CFDictionaryCreate(NULL, 
+                          keys, values,
+                          array_size(keys),
+                          &kCFTypeDictionaryKeyCallBacks,
+                          &kCFTypeDictionaryValueCallBacks);
+            status = SecItemAdd(dict, &identity_handle);
+            if (identity_handle != NULL) {
+            find_identity_using_handle(identity_handle);
+            }
+            CFReleaseNull(identity_handle);
+            if (status != errSecSuccess) {
+                fprintf(stderr, "SecItemAdd(identity) failed %d\n",
+                    (int)status);
+                success = FALSE;
+            }
+            CFReleaseNull(dict);
+        }
+
+        /* add certs */
+        trust_ref = (SecTrustRef)CFDictionaryGetValue(item_dict, kSecImportItemTrust);
+        if (trust_ref != NULL) {
+            CFIndex            cert_count;
+            CFIndex            cert_index;
+
+            cert_count = SecTrustGetCertificateCount(trust_ref);
+            for (cert_index = 1; cert_index < cert_count; cert_index++) {
+                SecCertificateRef cert = SecTrustGetCertificateAtIndex(trust_ref, cert_index);
+                if (verbose)
+                    print_cert(cert, false);
+                status = add_cert_item(cert);
+                if (status != errSecSuccess) {
+                    fprintf(stderr, "add_cert_item %d failed %d\n", (int)cert_index, (int)status);
+                    success = FALSE;
+                }
+            }
+        }
+    }
+    return (success);
+}
+
+static bool
+PKCS12ArrayRemoveSecItems(CFArrayRef items, bool verbose)
+{
+    CFIndex            count;
+    CFIndex            i;
+    bool               success = TRUE;
+
+    count = CFArrayGetCount(items);
+    for (i = 0; i < count; i++) {
+        CFTypeRef      cert_chain;
+        SecIdentityRef         identity;
+        CFDictionaryRef item_dict = CFArrayGetValueAtIndex(items, i);
+        OSStatus       status;
+
+        /* remove identity */
+        identity = (SecIdentityRef)CFDictionaryGetValue(item_dict,
+            kSecImportItemIdentity);
+        if (identity != NULL) {
+            if (verbose) {
+                SecCertificateRef cert = NULL;
+                SecIdentityCopyCertificate(identity, &cert);
+                print_cert(cert, false);
+                CFReleaseSafe(cert);
+            }
+            CFDictionaryRef    dict;
+
+            dict = CFDictionaryCreate(NULL, 
+                          (const void * *)&kSecValueRef,
+                          (const void * *)&identity, 1,
+                          &kCFTypeDictionaryKeyCallBacks,
+                          &kCFTypeDictionaryValueCallBacks);
+            status = SecItemDelete(dict);
+            if (status != errSecSuccess) {
+            fprintf(stderr, "SecItemDelete(identity) failed %d\n",
+                (int)status);
+            success = FALSE;
+            }
+            CFReleaseNull(dict);
+        }
+        /* remove cert chain */
+        cert_chain = CFDictionaryGetValue(item_dict, kSecImportItemCertChain);
+        if (cert_chain != NULL) {
+            CFIndex            cert_count;
+            CFIndex            cert_index;
+
+            cert_count = CFArrayGetCount(cert_chain);
+            for (cert_index = 0; cert_index < cert_count; cert_index++) {
+                SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(cert_chain, cert_index);
+                if (verbose)
+                    print_cert(cert, false);
+                status = remove_cert_item(cert);
+                if (status != errSecSuccess) {
+                    fprintf(stderr, "remove_cert_item %d failed %d\n", (int)cert_index, (int)status);
+                    success = FALSE;
+                }
+            }
+        }
+    }
+    return (success);
+}
+
+
+extern int pkcs12_util(int argc, char * const *argv)
+{
+    CFArrayRef         array;
+    const char *       filename = NULL;
+    const char *       passphrase = NULL;
+    bool            delete = false;
+    bool            verbose = false;
+    char            ch;
+    
+    while ((ch = getopt(argc, argv, "p:dv")) != -1)
+    {
+        switch (ch)
+        {
+        case 'p':
+            passphrase = optarg;
+            break;
+        case 'd':
+            delete = true;
+            break;
+        case 'v':
+            verbose = true;
+            break;
+        default:
+            return 2; /* Trigger usage message. */
+        }
+    }
+    
+       argc -= optind;
+       argv += optind;
+
+    if (argc != 1 || !passphrase)
+        return 2; /* Trigger usage message. */
+
+    filename = argv[0];
+    array = PKCS12FileCreateArray(filename, passphrase);
+    if (array == NULL)
+        return -1;
+    
+    bool success = false;
+    if (delete)
+        success = PKCS12ArrayRemoveSecItems(array, verbose);
+    else
+        success = PKCS12ArrayAddSecItems(array, verbose);
+
+    CFReleaseNull(array);
+    
+    return success ? 0 : -1;
+}
+
+#endif // TARGET_OS_EMBEDDED
diff --git a/sec/Security/Tool/scep.c b/sec/Security/Tool/scep.c
new file mode 100644 (file)
index 0000000..a477912
--- /dev/null
@@ -0,0 +1,581 @@
+/*
+ * Copyright (c) 2003-2004,2006-2007,2009-2010 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ *
+ * scep.c
+ */
+
+#include <TargetConditionals.h>
+#if TARGET_OS_EMBEDDED
+
+#include "SecurityCommands.h"
+
+#include <unistd.h>
+#include <uuid/uuid.h>
+#include <AssertMacros.h>
+
+#include <Security/SecItem.h>
+#include <Security/SecCertificateRequest.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecIdentityPriv.h>
+#include <Security/SecSCEP.h>
+#include <Security/SecCMS.h>
+
+#include <utilities/array_size.h>
+#include <utilities/SecIOFormat.h>
+
+#include <CommonCrypto/CommonDigest.h>
+
+#include <CFNetwork/CFNetwork.h>
+#include "SecBase64.h"
+
+
+#include <fcntl.h>
+static inline void write_data(const char * path, CFDataRef data)
+{
+    int data_file = open(path, O_CREAT|O_WRONLY|O_TRUNC, 0644);
+    write(data_file, CFDataGetBytePtr(data), CFDataGetLength(data));
+    close(data_file);
+}
+
+#define BUFSIZE 1024
+
+static CFHTTPMessageRef load_request(CFHTTPMessageRef request, CFMutableDataRef data, int retry, bool validate_cert)
+{
+    CFHTTPMessageRef result = NULL;
+    
+    if (retry < 0)
+        return result;
+
+    CFReadStreamRef rs;
+    rs = CFReadStreamCreateForHTTPRequest(NULL, request);
+
+       if (!validate_cert) {
+               const void *keys[] = {
+                       kCFStreamSSLValidatesCertificateChain,
+               };
+               const void *values[] = {
+                       kCFBooleanFalse,
+               };
+               CFDictionaryRef dict = CFDictionaryCreate(NULL, keys, values,
+                       array_size(keys),
+                       &kCFTypeDictionaryKeyCallBacks,
+                       &kCFTypeDictionaryValueCallBacks);
+               CFReadStreamSetProperty(rs, kCFStreamPropertySSLSettings, dict);
+               CFRelease(dict);
+               CFReadStreamSetProperty(rs, kCFStreamPropertyHTTPAttemptPersistentConnection, kCFBooleanTrue);
+       }
+    
+    if (CFReadStreamOpen(rs)) {
+        do {
+            UInt8 buf[BUFSIZE];
+            CFIndex bytesRead = CFReadStreamRead(rs, buf, BUFSIZE);
+            if (bytesRead > 0) {
+                CFDataAppendBytes(data, buf, bytesRead);
+            } else if (bytesRead == 0) {
+                result = (CFHTTPMessageRef)CFReadStreamCopyProperty(rs, kCFStreamPropertyHTTPResponseHeader);
+                break;
+            } else {
+                CFStreamStatus status = CFReadStreamGetStatus(rs);
+                CFStreamError error = CFReadStreamGetError(rs);
+                fprintf(stderr, "CFReadStreamRead status=%ld error(domain=%" PRIdCFIndex " error=%ld)\n",
+                    status, error.domain, (long) error.error);
+                break;
+            }
+        } while (true);
+    } else {
+        CFStreamStatus status = CFReadStreamGetStatus(rs);
+        CFStreamError error = CFReadStreamGetError(rs);
+        fprintf(stderr, "CFReadStreamRead status=%ld error(domain=%" PRIdCFIndex " error=%ld)\n",
+            status, error.domain, (long) error.error);
+    }
+
+    CFReadStreamClose(rs);
+    CFRelease(rs);
+    return result;
+}
+
+static CFDataRef MCNetworkLoadRequest(CFURLRef url, CFDataRef content, CFStringRef type,
+    CFStringRef *contentType, bool validate_cert)
+{
+    CFMutableDataRef out_data = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    CFHTTPMessageRef response = NULL;
+    CFStringRef request_type = content ? CFSTR("POST") : CFSTR("GET");
+    CFHTTPMessageRef request = CFHTTPMessageCreateRequest(kCFAllocatorDefault, 
+        request_type, url, kCFHTTPVersion1_0);
+    if (content)
+        CFHTTPMessageSetBody(request, content);
+    CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Content-Type"), type);
+
+    int retries = 1;
+    do {
+        response = load_request(request, out_data, 1, validate_cert);
+        if (!response && retries) {
+            sleep(5);
+            CFDataSetLength(out_data, 0);
+        }
+    } while (!response && retries--);
+    
+    CFRelease(request);
+    
+    CFIndex status_code = response ? CFHTTPMessageGetResponseStatusCode(response) : 0;
+    if (!response || (200 != status_code)) {
+        CFStringRef url_string = CFURLGetString(url);
+        if (url_string && request_type && out_data)
+            fprintf(stderr, "MCNetworkLoadRequest failed to load\n");
+        return NULL;
+    }
+
+    if (contentType)
+        *contentType = CFHTTPMessageCopyHeaderFieldValue(response, CFSTR("Content-Type"));
+        
+    CFRelease(response);
+    return out_data;
+}
+
+static void _query_string_apply(CFMutableStringRef query_string, const void *key, const void *value)
+{
+    CFStringRef escaped_key = 
+        CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, 
+            (CFStringRef)key, NULL, CFSTR("+/="), kCFStringEncodingUTF8);
+    CFStringRef escaped_value = 
+        CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, 
+            (CFStringRef)value, NULL, CFSTR("+/="), kCFStringEncodingUTF8);
+    
+    CFStringRef format;
+    if (CFStringGetLength(query_string) > 1)
+        format = CFSTR("&%@=%@");
+    else
+        format = CFSTR("%@=%@");
+
+    CFStringAppendFormat(query_string, NULL, format, escaped_key, escaped_value);
+    CFRelease(escaped_key);
+    CFRelease(escaped_value);
+}
+
+static CFURLRef scep_url_operation(CFStringRef base, CFStringRef operation, CFStringRef message)
+{
+    CFURLRef url = NULL, base_url = NULL;
+    CFMutableStringRef query_string = 
+        CFStringCreateMutableCopy(kCFAllocatorDefault, 0, CFSTR("?"));
+    require(query_string, out);
+    require(operation, out);
+    _query_string_apply(query_string, CFSTR("operation"), operation);
+    if (message)
+        _query_string_apply(query_string, CFSTR("message"), message);
+    base_url = CFURLCreateWithString(kCFAllocatorDefault, base, NULL);
+    url = CFURLCreateWithString(kCFAllocatorDefault, query_string, base_url);
+out:
+    if (query_string)
+        CFRelease(query_string);
+    if (base_url)
+        CFRelease(base_url);
+    return url;
+}
+
+static CFDataRef perform_pki_op(CFStringRef scep_base_url, CFDataRef scep_request, bool scep_can_use_post, bool validate_cert)
+{
+       CFDataRef scep_reply = NULL;
+       CFURLRef pki_op = NULL;
+    if (scep_can_use_post) {
+        pki_op = scep_url_operation(scep_base_url, CFSTR("PKIOperation"), NULL);
+        scep_reply = MCNetworkLoadRequest(pki_op, scep_request, CFSTR("application/x-pki-message"), NULL, validate_cert);
+    } else {
+        SecBase64Result base64_result;
+        size_t buffer_length = CFDataGetLength(scep_request)*2+1;
+        char *buffer = malloc(buffer_length);
+        require(buffer, out);
+        size_t output_size = SecBase64Encode2(CFDataGetBytePtr(scep_request), CFDataGetLength(scep_request), buffer, buffer_length,
+            kSecB64_F_LINE_LEN_INFINITE, -1, &base64_result);
+        *(buffer + output_size) = '\0';
+        require(!base64_result, out);
+        CFStringRef message = CFStringCreateWithCString(kCFAllocatorDefault, buffer, kCFStringEncodingASCII);
+        require(message, out);
+               pki_op = scep_url_operation(scep_base_url, CFSTR("PKIOperation"), message);
+        CFRelease(message);
+        fprintf(stderr, "Performing PKIOperation using GET\n");
+        scep_reply = MCNetworkLoadRequest(pki_op, NULL, CFSTR("application/x-pki-message"), NULL, validate_cert);
+    }
+out:
+       if (pki_op) CFRelease(pki_op);
+       return scep_reply;
+}
+
+
+static inline CFStringRef uuid_cfstring()
+{
+    char uuid_string[40] = "CN=";
+    uuid_t uuid;
+    uuid_generate_random(uuid);
+    uuid_unparse(uuid, uuid_string+3);
+    return CFStringCreateWithCString(kCFAllocatorDefault, uuid_string, kCFStringEncodingASCII);
+}
+
+/* /O=foo/CN=blah => [ [ [ O, foo ] ], [ [ CN, blah ] ] ] */
+static void make_subject_pairs(const void *value, void *context)
+{
+    CFArrayRef entries = NULL, array = NULL;
+    if (!CFStringGetLength(value))
+        return; /* skip '/'s that aren't separating key/vals */
+    entries = CFStringCreateArrayBySeparatingStrings(kCFAllocatorDefault, value, CFSTR("="));
+    require(entries, out);
+    if (CFArrayGetCount(entries)) {
+        array = CFArrayCreate(kCFAllocatorDefault, (const void **)&entries, 1, &kCFTypeArrayCallBacks);
+        require(array, out);
+        CFArrayAppendValue((CFMutableArrayRef)context, array);
+    }
+out:
+    if (entries) CFRelease(entries);
+    if (array) CFRelease(array);
+}
+
+static CFArrayRef make_scep_subject(CFStringRef scep_subject_name)
+{
+    CFMutableArrayRef subject = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+    require(subject, out);
+    CFArrayRef entries = NULL;
+    entries = CFStringCreateArrayBySeparatingStrings(kCFAllocatorDefault, scep_subject_name, CFSTR("/"));
+    require(entries, out);
+    CFArrayApplyFunction(entries, CFRangeMake(0, CFArrayGetCount(entries)), make_subject_pairs, subject);
+    CFRelease(entries);
+    if (CFArrayGetCount(subject))
+        return subject;
+out:
+    if (subject) CFRelease(subject);
+    return NULL;
+}
+
+
+extern int command_scep(int argc, char * const *argv)
+{
+    int             result = 1, verbose = 0;
+    char            ch;
+    int key_usage = 1, key_bitsize = 1024;
+    bool validate_cert = true;
+    CFStringRef scep_challenge = NULL, scep_instance_name = NULL,
+        scep_subject_name = uuid_cfstring(), scep_subject_alt_name = NULL,
+        scep_capabilities = NULL;
+
+    while ((ch = getopt(argc, argv, "vu:b:c:n:s:h:xo:")) != -1)
+    {
+        switch (ch)
+        {
+        case 'v':
+            verbose++;
+            break;
+        case 'u':
+            key_usage = atoi(optarg);
+            break;
+        case 'b':
+            key_bitsize = atoi(optarg);
+            break;
+        case 'c':
+            scep_challenge = CFStringCreateWithCString(kCFAllocatorDefault, optarg, kCFStringEncodingUTF8);
+            break;
+        case 'n':
+            scep_instance_name = CFStringCreateWithCString(kCFAllocatorDefault, optarg, kCFStringEncodingUTF8);
+            break;
+        case 's':
+            scep_subject_name = CFStringCreateWithCString(kCFAllocatorDefault, optarg, kCFStringEncodingUTF8);
+            break;
+        case 'h':
+            scep_subject_alt_name = CFStringCreateWithCString(kCFAllocatorDefault, optarg, kCFStringEncodingUTF8);
+            break;
+       case 'x':
+           validate_cert = false;
+           break;
+        case 'o':
+            scep_capabilities = CFStringCreateWithCString(kCFAllocatorDefault, optarg, kCFStringEncodingUTF8);
+            break;
+        default:
+            return 2; /* Trigger usage message. */
+        }
+    }
+
+    argc -= optind;
+    argv += optind;
+
+    if (argc != 1)
+        return 2; /* Trigger usage message. */
+
+    CFDataRef scep_request = NULL;
+    CFArrayRef issued_certs = NULL;
+    SecCertificateRef leaf = NULL;
+    SecIdentityRef candidate_identity = NULL;
+    CFMutableDictionaryRef csr_parameters = NULL;
+    CFDataRef scep_reply = NULL;
+    SecKeyRef phone_publicKey = NULL, phone_privateKey = NULL;
+    CFStringRef scep_base_url = NULL;
+    CFDictionaryRef identity_add = NULL;
+
+    scep_base_url = CFStringCreateWithCString(kCFAllocatorDefault, argv[0], kCFStringEncodingASCII);
+
+#if 0
+    CFStringRef uuid_cfstr = uuid_cfstring();
+    require(uuid_cfstr, out);
+    const void * ca_cn[] = { kSecOidCommonName, uuid_cfstr };
+    CFArrayRef ca_cn_dn = CFArrayCreate(kCFAllocatorDefault, ca_cn, 2, NULL);
+    const void *ca_dn_array[1];
+    ca_dn_array[0] = CFArrayCreate(kCFAllocatorDefault, (const void **)&ca_cn_dn, 1, NULL);
+    CFArrayRef scep_subject = CFArrayCreate(kCFAllocatorDefault, ca_dn_array, array_size(ca_dn_array), NULL);
+#else
+    CFArrayRef scep_subject = make_scep_subject(scep_subject_name);
+    require(scep_subject, out);
+    CFShow(scep_subject);
+#endif
+
+    CFNumberRef scep_key_usage = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &key_usage);
+    CFNumberRef scep_key_bitsize = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &key_bitsize);
+
+    const void *keygen_keys[] = { kSecAttrKeyType, kSecAttrKeySizeInBits };
+    const void *keygen_vals[] = { kSecAttrKeyTypeRSA, scep_key_bitsize };
+    CFDictionaryRef keygen_parameters = CFDictionaryCreate(kCFAllocatorDefault, 
+        keygen_keys, keygen_vals, array_size(keygen_vals),
+        &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks );
+    CFRelease(scep_key_bitsize);
+    require_noerr(SecKeyGeneratePair(keygen_parameters, &phone_publicKey, &phone_privateKey), out);
+    CFRelease(keygen_parameters);
+
+    /* GetCACert
+    
+        A binary X.509 CA certificate is sent back as a MIME object with a
+        Content-Type of application/x-x509-ca-cert.
+        
+        When an RA exists, both CA and RA certificates must be sent back in
+        the response to the GetCACert request.  The RA certificate(s) must be
+        signed by the CA.  A certificates-only PKCS#7 [RFC2315] SignedData is
+        used to carry the certificates to the requester, with a Content-Type
+        of application/x-x509-ca-ra-cert.
+    */
+    CFDataRef data = NULL;
+    CFStringRef ctype = NULL;
+    SecCertificateRef ca_certificate = NULL, ra_certificate = NULL;
+    SecCertificateRef ra_encryption_certificate = NULL;
+    CFArrayRef ra_certificates = NULL;
+    CFTypeRef scep_certificates = NULL;
+    SecCertificateRef scep_signing_certificate = NULL;
+
+    CFURLRef url = scep_url_operation(scep_base_url, CFSTR("GetCACert"), scep_instance_name);
+    data = MCNetworkLoadRequest(url, NULL, NULL, &ctype, validate_cert);
+
+    if (data && ctype) {
+        if (CFEqual(CFSTR("application/x-x509-ca-cert"), ctype)) {
+            ca_certificate = SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef)data);
+            fprintf(stderr, "GetCACert returned a single CA certificate.\n");
+        } else if (CFEqual(ctype, CFSTR("application/x-x509-ca-ra-cert"))) {
+            CFArrayRef cert_array = SecCMSCertificatesOnlyMessageCopyCertificates(data);
+            
+            require_noerr(SecSCEPValidateCACertMessage(cert_array,
+                NULL,
+                &ca_certificate,
+                &ra_certificate,
+                &ra_encryption_certificate), out);
+
+            if (ra_certificate && ra_encryption_certificate) {
+                const void *ra_certs[] = { ra_encryption_certificate, ra_certificate };
+                ra_certificates = CFArrayCreate(kCFAllocatorDefault, ra_certs, array_size(ra_certs), &kCFTypeArrayCallBacks);
+                fprintf(stderr, "GetCACert returned a separate signing and encryption certificates for RA.\n");
+            }
+            CFRelease(cert_array);
+        }
+    }
+
+    fprintf(stderr, "CA certificate to issue cert:\n");
+    CFShow(ca_certificate);
+    
+    if (ra_certificates) {
+        scep_certificates = ra_certificates;
+        scep_signing_certificate = ra_certificate;
+    } else if (ra_certificate) {
+        scep_certificates = ra_certificate;
+        scep_signing_certificate = ra_certificate;
+    } else if (ca_certificate) { 
+        scep_certificates = ca_certificate;
+        scep_signing_certificate = ca_certificate;
+    } else {
+        fprintf(stderr, "Unsupported GetCACert configuration: please file a bug.\n");
+        goto out;
+    }
+
+#if 0
+        GetCACaps capabilities advertised by SCEP server:
+
+   +--------------------+----------------------------------------------+
+   | Keyword            | Description                                  |
+   +--------------------+----------------------------------------------+
+   | "GetNextCACert"    | CA Supports the GetNextCACert message.       |
+   | "POSTPKIOperation" | PKIOPeration messages may be sent via HTTP   |
+   |                    | POST.                                        |
+   | "Renewal"          | Clients may use current certificate and key  |
+   |                    | to authenticate an enrollment request for a  |
+   |                    | new certificate.                             |
+   | "SHA-512"          | CA Supports the SHA-512 hashing algorithm in |
+   |                    | signatures and fingerprints.                 |
+   | "SHA-256"          | CA Supports the SHA-256 hashing algorithm in |
+   |                    | signatures and fingerprints.                 |
+   | "SHA-1"            | CA Supports the SHA-1 hashing algorithm in   |
+   |                    | signatures and fingerprints.                 |
+   | "DES3"             | CA Supports triple-DES for encryption.       |
+   +--------------------+----------------------------------------------+
+#endif
+
+    bool scep_can_use_post = false;
+    bool scep_use_3des = false;
+    bool scep_can_use_sha1 = false;
+
+    CFArrayRef caps = NULL;
+    if (!scep_capabilities) {
+        CFURLRef ca_caps_url = scep_url_operation(scep_base_url, CFSTR("GetCACaps"), scep_instance_name);
+        require(ca_caps_url, out);
+        CFDataRef caps_data = MCNetworkLoadRequest(ca_caps_url, NULL, NULL, NULL, validate_cert);
+        CFRelease(ca_caps_url);
+        if (caps_data) {
+            CFStringRef caps_data_string = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, caps_data, kCFStringEncodingASCII);
+            require(caps_data_string, out);
+            caps = CFStringCreateArrayBySeparatingStrings(kCFAllocatorDefault, caps_data_string, CFSTR("\n"));
+            if (!caps) {
+                fprintf(stderr, "GetCACaps couldn't be parsed:\n");
+                CFShow(caps_data);
+            }
+            CFRelease(caps_data);
+        }
+    } else {
+        caps = CFStringCreateArrayBySeparatingStrings(kCFAllocatorDefault, scep_capabilities, CFSTR(","));
+    }
+
+    if (caps) {
+        fprintf(stderr, "GetCACaps advertised following capabilities:\n");
+        CFShow(caps);
+
+        CFRange caps_length = CFRangeMake(0, CFArrayGetCount(caps));
+        scep_can_use_post = CFArrayContainsValue(caps, caps_length, CFSTR("POSTPKIOperation"));
+        scep_use_3des = CFArrayContainsValue(caps, caps_length, CFSTR("DES3"));
+        scep_can_use_sha1 = CFArrayContainsValue(caps, caps_length, CFSTR("SHA-1"));
+    }
+
+    scep_use_3des = true;
+    scep_can_use_sha1 = true;
+
+    csr_parameters = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 
+        &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    if (scep_key_usage)
+        CFDictionarySetValue(csr_parameters, kSecCertificateKeyUsage, scep_key_usage);
+    if (scep_challenge)
+        CFDictionarySetValue(csr_parameters, kSecCSRChallengePassword, scep_challenge);
+    else
+        fprintf(stderr, "No SCEP challenge provided, hope that's ok.\n");
+
+    if (!scep_use_3des) {
+        CFDictionarySetValue(csr_parameters, kSecCMSBulkEncryptionAlgorithm, kSecCMSEncryptionAlgorithmDESCBC);
+        fprintf(stderr, "SCEP server does not support 3DES, falling back to DES.  You should reconfigure your server.\n");
+    }
+    if (!scep_can_use_sha1) {
+        CFDictionarySetValue(csr_parameters, kSecCMSSignHashAlgorithm, kSecCMSHashingAlgorithmMD5);
+        fprintf(stderr, "SCEP server does not support SHA-1, falling back to MD5.  You should reconfigure your server.\n");    
+    }
+
+    if (scep_subject_alt_name) {
+        fprintf(stderr, "Adding subjectAltName to request\n");
+        CFStringRef name = CFSTR("dnsName");
+        CFDictionaryRef subject_alt_name = CFDictionaryCreate(kCFAllocatorDefault,
+            (const void **)&name, (const void **)&scep_subject_alt_name,
+            1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+        CFDictionarySetValue(csr_parameters, kSecSubjectAltName, subject_alt_name);
+    }
+
+    SecIdentityRef self_signed_identity = SecSCEPCreateTemporaryIdentity(phone_publicKey, phone_privateKey);
+
+    // store encryption identity in the keychain because the decrypt function looks in there only
+    identity_add = CFDictionaryCreate(NULL,
+        &kSecValueRef, (const void **)&self_signed_identity, 1, NULL, NULL);
+       require_noerr(SecItemAdd(identity_add, NULL), out);
+
+    require(scep_request = SecSCEPGenerateCertificateRequest((CFArrayRef)scep_subject, 
+        csr_parameters, phone_publicKey, phone_privateKey, self_signed_identity,
+        scep_certificates), out);
+
+    fprintf(stderr, "storing scep_request.der\n");
+    write_data("scep_request.der", scep_request);
+
+       scep_reply = perform_pki_op(scep_base_url, scep_request, scep_can_use_post, validate_cert);
+    require(scep_reply, out);
+
+    require_action(CFDataGetLength(scep_reply), out, fprintf(stderr, "Empty scep_reply, exiting.\n"));
+    fprintf(stderr, "Storing scep_reply.der\n");
+    write_data("scep_reply.der", scep_reply);
+
+       CFErrorRef server_error = NULL;
+       int retry_count = 3;
+    while ( !(issued_certs = SecSCEPVerifyReply(scep_request, scep_reply, scep_certificates, &server_error)) &&
+                       server_error &&
+                       retry_count--)
+       {
+               CFDataRef retry_get_cert_initial = NULL;
+               CFDictionaryRef error_dict = CFErrorCopyUserInfo(server_error);
+               retry_get_cert_initial = SecSCEPGetCertInitial(ra_certificate ? ra_certificate : ca_certificate, scep_subject, NULL, error_dict, self_signed_identity, scep_certificates);
+               if (scep_reply) CFRelease(scep_reply);
+               fprintf(stderr, "Waiting 10 seconds before trying a GetCertInitial\n");
+               sleep(10);
+               scep_reply = perform_pki_op(scep_base_url, retry_get_cert_initial, scep_can_use_post, validate_cert);
+       }
+
+    require(issued_certs, out);
+       require_string(CFArrayGetCount(issued_certs) > 0, out, "No certificates issued.");
+    
+    leaf = (SecCertificateRef)CFArrayGetValueAtIndex(issued_certs, 0);
+    require(leaf, out);
+    CFDataRef leaf_data = SecCertificateCopyData(leaf);
+    if (leaf_data) {
+        fprintf(stderr, "Storing issued_cert.der\n");
+        write_data("issued_cert.der", leaf_data);
+        CFRelease(leaf_data);
+    }
+    CFShow(leaf);
+
+    candidate_identity = SecIdentityCreate(kCFAllocatorDefault, leaf, phone_privateKey);
+
+    const void *keys_ref_to_persist[] = { 
+        /*kSecReturnPersistentRef, */kSecValueRef, kSecAttrLabel };
+    const void *values_ref_to_persist[] = { 
+        /*kCFBooleanTrue, */candidate_identity, scep_subject_name };
+    CFDictionaryRef dict = CFDictionaryCreate(NULL, 
+            (const void **)keys_ref_to_persist, 
+            (const void **)values_ref_to_persist, 
+            array_size(keys_ref_to_persist),
+            &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    OSStatus status = SecItemAdd(dict, NULL);
+    require_noerr_action(status, out, fprintf(stderr, "failed to store new identity, SecItemAdd: %" PRIdOSStatus, status));
+    result = 0;
+    
+out:
+    SecItemDelete(identity_add);
+    if (identity_add) CFRelease(identity_add);
+    //if (uuid_cfstr) CFRelease(uuid_cfstr);
+    if (candidate_identity) CFRelease(candidate_identity);
+    if (scep_request) CFRelease(scep_request);
+    if (scep_reply) CFRelease(scep_reply);
+    if (csr_parameters) CFRelease(csr_parameters);
+    
+    return result;
+}
+
+
+#endif // TARGET_OS_MAC
diff --git a/sec/Security/Tool/show_certificates.c b/sec/Security/Tool/show_certificates.c
new file mode 100644 (file)
index 0000000..1e404f5
--- /dev/null
@@ -0,0 +1,349 @@
+/*
+ * Copyright (c) 2003-2007,2009-2010 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ *
+ * keychain_find.c
+ */
+
+#include <TargetConditionals.h>
+#if TARGET_OS_EMBEDDED
+
+#include "SecurityCommands.h"
+
+#include "security.h"
+#include "SecurityTool/print_cert.h"
+#include "SecBase64.h"
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <SecurityTool/tool_errors.h>
+
+#include <Security/SecItem.h>
+
+#include <CoreFoundation/CFArray.h>
+#include <CoreFoundation/CFDate.h>
+#include <CoreFoundation/CFNumber.h>
+#include <CoreFoundation/CFString.h>
+
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecPolicyPriv.h>
+#include <Security/SecTrustPriv.h>
+#include <Security/SecInternal.h>
+
+#include <SecurityTool/readline.h>
+
+#include <utilities/SecCFWrappers.h>
+
+typedef uint32_t SecProtocolType;
+typedef uint32_t SecAuthenticationType;
+
+static void
+keychain_query_parse_string(CFMutableDictionaryRef q, CFStringRef s) {
+    bool inkey = true;
+    bool escaped = false;
+    CFStringRef key = NULL;
+    CFMutableStringRef str = CFStringCreateMutable(0, 0);
+    CFRange rng = { .location = 0, .length = CFStringGetLength(s) };
+    CFCharacterSetRef cs_key = CFCharacterSetCreateWithCharactersInString(0, CFSTR("=\\"));
+    CFCharacterSetRef cs_value = CFCharacterSetCreateWithCharactersInString(0, CFSTR(",\\"));
+    while (rng.length) {
+        CFRange r;
+        CFStringRef sub;
+        bool complete = false;
+        if (escaped) {
+            r.location = rng.location;
+            r.length = 1;
+            sub = CFStringCreateWithSubstring(0, s, r);
+            escaped = false;
+        } else if (CFStringFindCharacterFromSet(s, inkey ? cs_key : cs_value, rng, 0, &r)) {
+            if (CFStringGetCharacterAtIndex(s, r.location) == '\\') {
+                escaped = true;
+            } else {
+                complete = true;
+            }
+            CFIndex next = r.location + 1;
+            r.length = r.location - rng.location;
+            r.location = rng.location;
+            sub = CFStringCreateWithSubstring(0, s, r);
+            rng.length -= next - rng.location;
+            rng.location = next;
+        } else {
+            sub = CFStringCreateWithSubstring(0, s, rng);
+            rng.location += rng.length;
+            rng.length = 0;
+            complete = true;
+        }
+        CFStringAppend(str, sub);
+        CFRelease(sub);
+        if (complete) {
+            CFStringRef value = CFStringCreateCopy(0, str);
+            CFStringReplaceAll(str, CFSTR(""));
+            if (inkey) {
+                key = value;
+            } else {
+                CFDictionarySetValue(q, key, value);
+                CFReleaseNull(value);
+                CFReleaseNull(key);
+            }
+            inkey = !inkey;
+        }
+    }
+    if (key) {
+        /* Dangeling key value is true?. */
+        CFDictionarySetValue(q, key, kCFBooleanTrue);
+        CFRelease(key);
+    }
+    CFRelease(str);
+}
+
+static void
+keychain_query_parse_cstring(CFMutableDictionaryRef q, const char *query) {
+    CFStringRef s;
+    s = CFStringCreateWithCStringNoCopy(0, query, kCFStringEncodingUTF8, kCFAllocatorNull);
+    keychain_query_parse_string(q, s);
+    CFRelease(s);
+}
+
+static void show_cert_eval(CFArrayRef certs, bool verbose) {
+    SecPolicyRef policy = SecPolicyCreateSSL(true, NULL);
+    SecTrustRef trust = NULL;
+    OSStatus status = SecTrustCreateWithCertificates(certs, policy, &trust);
+    SecTrustResultType trustResult;
+    const char *trustResults[] = {
+        "invalid",
+        "proceed",
+        "confirm",
+        "deny",
+        "unspecified",
+        "recoverable trust failure",
+        "fatal trust failure",
+        "other error",
+    };
+    status = SecTrustEvaluate(trust, &trustResult);
+    printf("* trust: %s *\n", trustResults[trustResult]);
+    CFArrayRef properties = SecTrustCopyProperties(trust);
+    print_plist(properties);
+    CFReleaseNull(properties);
+    CFIndex ix, count = SecTrustGetCertificateCount(trust);
+    for (ix = 0; ix < count; ++ix) {
+        printf("* cert %ld summary properties *\n", ix);
+        properties = SecTrustCopySummaryPropertiesAtIndex(trust, ix);
+        print_plist(properties);
+        CFReleaseNull(properties);
+        if (verbose) {
+            printf("* cert %ld detail properties *\n", ix);
+            properties = SecTrustCopyDetailedPropertiesAtIndex(trust, ix);
+            print_plist(properties);
+            CFReleaseNull(properties);
+        }
+    }
+
+    CFDictionaryRef info = SecTrustCopyInfo(trust);
+    if (info) {
+        printf("* info *\n");
+        CFShow(info);
+        CFReleaseNull(info);
+    }
+}
+
+static size_t print_buffer_pem(FILE *stream, const char *pem_name, size_t length,
+                            const uint8_t *bytes) {
+    size_t pem_name_len = strlen(pem_name);
+    size_t b64_len = SecBase64Encode2(NULL, length, NULL, 0,
+                                      kSecB64_F_LINE_LEN_USE_PARAM, 64, NULL);
+    char *buffer = malloc(33 + 2 * pem_name_len + b64_len);
+    char *p = buffer;
+    p += sprintf(buffer, "-----BEGIN %s-----\n", pem_name);
+    SecBase64Result result;
+    p += SecBase64Encode2(bytes, length, p, b64_len,\
+                          kSecB64_F_LINE_LEN_USE_PARAM, 64, &result);
+    if (result) {
+        free(buffer);
+        return result;
+    }
+    p += sprintf(p, "\n-----END %s-----\n", pem_name);
+    size_t res = fwrite(buffer, 1, p - buffer, stream);
+    fflush(stream);
+    bzero(buffer, p - buffer);
+    free(buffer);
+    return res;
+}
+
+int keychain_show_certificates(int argc, char * const *argv)
+{
+       int ch, result = 0;
+       bool output_subject = false;
+       bool verbose = false;
+    bool trust_eval = false;
+    bool keychain_certs = false;
+    bool output_pem = false;
+    bool output_finger_print = false;
+    CFMutableArrayRef certs = NULL;
+    CFMutableDictionaryRef query = CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+
+       while ((ch = getopt(argc, argv, "kfq:pstv")) != -1)
+       {
+               switch  (ch)
+               {
+        case 'k':
+            keychain_certs = true;
+            break;
+        case 'p':
+            output_pem = true;
+            break;
+               case 's':
+                       output_subject = true;
+                       break;
+        case 'v':
+            verbose = true;
+            break;
+               case 't':
+                       trust_eval = true;
+                       break;
+        case 'f':
+            output_finger_print = true;
+            break;
+        case 'q':
+            keychain_query_parse_cstring(query, optarg);
+            keychain_certs = true;
+            break;
+        case '?':
+               default:
+                       return 2; /* @@@ Return 2 triggers usage message. */
+               }
+       }
+  
+       argc -= optind;
+       argv += optind;
+
+    if ((keychain_certs && argc > 0) || (!keychain_certs && argc < 1))
+        result = 2;
+
+    if (trust_eval)
+        certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+
+    CFArrayRef kc_certs = NULL;
+    int arg;
+    if (keychain_certs) {
+        for (arg = 0; arg < argc; ++arg) {
+            keychain_query_parse_cstring(query, argv[arg]);
+        }
+        CFDictionarySetValue(query, kSecClass, kSecClassCertificate);
+        CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitAll);
+        CFDictionarySetValue(query, kSecReturnRef, kCFBooleanTrue);
+        CFTypeRef results;
+        if (!SecItemCopyMatching(query, &results)) {
+            kc_certs = results;
+            argc = (int) CFArrayGetCount(kc_certs);
+        }
+    }
+
+    for (arg = 0; arg < argc; ++arg) {
+        SecCertificateRef cert = NULL;
+        if (keychain_certs) {
+            cert = (SecCertificateRef)CFArrayGetValueAtIndex(kc_certs, arg);
+        } else {
+            CFDataRef data = copyFileContents(argv[arg]);
+            if (data) {
+                cert = SecCertificateCreateWithData(
+                    kCFAllocatorDefault, data);
+                if (!cert) {
+                    /* DER failed, try PEM. */
+                    cert = SecCertificateCreateWithPEM(kCFAllocatorDefault, data);
+                }
+                CFRelease(data);
+            } else {
+                result = 1;
+            }
+        }
+
+        if (cert) {
+            if (!keychain_certs) {
+                printf(
+                       "*******************************************************\n"
+                       "%s\n"
+                       "*******************************************************\n"
+                       , argv[arg]);
+            }
+            if (trust_eval) {
+                if (keychain_certs) {
+                    CFArraySetValueAtIndex(certs, 0, cert);
+                    show_cert_eval(certs, verbose);
+                } else {
+                    CFArrayAppendValue(certs, cert);
+                }
+            } else {
+                if (verbose) {
+                    print_cert(cert, verbose);
+                } else if (output_subject) {
+                    CFStringRef subject = SecCertificateCopySubjectString(cert);
+                    if (subject) {
+                        CFStringWriteToFileWithNewline(subject, stdout);
+                        CFRelease(subject);
+                    }
+                } else if (!output_pem) {
+                    print_cert(cert, verbose);
+                }
+            }
+            if (output_finger_print) {
+                CFDataRef key_fingerprint = SecCertificateCopyPublicKeySHA1Digest(cert);
+                if (key_fingerprint) {
+                    int i;
+                    CFIndex j = CFDataGetLength(key_fingerprint);
+                    const uint8_t *byte = CFDataGetBytePtr(key_fingerprint);
+
+                    fprintf(stdout, "Key fingerprint:");
+                    for (i = 0; i < j; i++) {
+                        fprintf(stdout, " %02X", byte[i]);
+                    }
+                    fprintf(stdout, "\n");
+                }
+            }
+            if (output_pem) {
+                print_buffer_pem(stdout, "CERTIFICATE",
+                                 SecCertificateGetLength(cert),
+                                 SecCertificateGetBytePtr(cert));
+            }
+            if (!keychain_certs) {
+                CFRelease(cert);
+            }
+        } else {
+            result = 1;
+            fprintf(stderr, "file %s: does not contain a valid certificate",
+                argv[arg]);
+        }
+    }
+
+    if (trust_eval && !keychain_certs)
+        show_cert_eval(certs, verbose);
+
+    CFReleaseSafe(kc_certs);
+    CFReleaseSafe(certs);
+
+       return result;
+}
+
+#endif // TARGET_OS_EMBEDDED
diff --git a/sec/Security/Tool/spc.c b/sec/Security/Tool/spc.c
new file mode 100644 (file)
index 0000000..875ea6d
--- /dev/null
@@ -0,0 +1,704 @@
+/*
+ * Copyright (c) 2009-2010 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ *  spc.c - Security
+ *
+ *  Created by Conrad Sauerwald on 1/9/09.
+ *
+ */
+
+#include <TargetConditionals.h>
+#if TARGET_OS_EMBEDDED
+
+#include "SecurityCommands.h"
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <AssertMacros.h>
+#include <TargetConditionals.h>
+#include <CFNetwork/CFNetwork.h>
+
+extern const CFStringRef kCFStreamPropertySSLPeerTrust;
+#include <Security/SecTrust.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecImportExport.h>
+#include <Security/SecPolicy.h>
+#include <Security/SecIdentity.h>
+#include <Security/SecIdentityPriv.h>
+#include <Security/SecRSAKey.h>
+#include <Security/SecSCEP.h>
+#include <Security/SecCMS.h>
+#include <Security/SecItem.h>
+#include <Security/SecInternal.h>
+#include <utilities/array_size.h>
+#include <err.h>
+#include <stdio.h>
+#include <getopt.h>
+
+//static char *scep_url = "https://localhost:2000/cgi-bin/pkiclient.exe";
+static char *user = "webuser";
+static char *pass = "webpassowrd";
+static int debug = 0;
+
+#define BUFSIZE 1024
+
+unsigned char device_cert_der[] = {
+  0x30, 0x82, 0x02, 0xdf, 0x30, 0x82, 0x02, 0x48, 0xa0, 0x03, 0x02, 0x01,
+  0x02, 0x02, 0x0a, 0x01, 0x5c, 0x0a, 0x2f, 0xfd, 0x20, 0x02, 0x00, 0xe6,
+  0x27, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x01, 0x0b, 0x05, 0x00, 0x30, 0x5a, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+  0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06,
+  0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20,
+  0x49, 0x6e, 0x63, 0x2e, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04,
+  0x0b, 0x13, 0x0c, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x69, 0x50, 0x68,
+  0x6f, 0x6e, 0x65, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03,
+  0x13, 0x16, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x69, 0x50, 0x68, 0x6f,
+  0x6e, 0x65, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x20, 0x43, 0x41,
+  0x30, 0x1e, 0x17, 0x0d, 0x30, 0x38, 0x31, 0x32, 0x31, 0x32, 0x32, 0x33,
+  0x30, 0x33, 0x35, 0x36, 0x5a, 0x17, 0x0d, 0x31, 0x31, 0x31, 0x32, 0x31,
+  0x32, 0x32, 0x33, 0x30, 0x33, 0x35, 0x36, 0x5a, 0x30, 0x81, 0x87, 0x31,
+  0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x28, 0x66, 0x31,
+  0x66, 0x35, 0x30, 0x66, 0x38, 0x31, 0x32, 0x32, 0x66, 0x62, 0x31, 0x30,
+  0x31, 0x34, 0x36, 0x66, 0x36, 0x35, 0x65, 0x39, 0x30, 0x33, 0x38, 0x30,
+  0x31, 0x37, 0x36, 0x33, 0x34, 0x32, 0x61, 0x64, 0x64, 0x36, 0x61, 0x38,
+  0x35, 0x63, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+  0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08,
+  0x13, 0x02, 0x43, 0x41, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
+  0x07, 0x13, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f,
+  0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41,
+  0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x0f, 0x30,
+  0x0d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x06, 0x69, 0x50, 0x68, 0x6f,
+  0x6e, 0x65, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00,
+  0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xba, 0xc5, 0x2a, 0x7b, 0xb3,
+  0x29, 0x21, 0x8d, 0xbd, 0x01, 0x12, 0xff, 0x0b, 0xf6, 0x14, 0x66, 0x15,
+  0x7b, 0x99, 0xf8, 0x1e, 0x08, 0x46, 0x40, 0xd7, 0x48, 0x57, 0xf0, 0x9c,
+  0x08, 0xac, 0xbc, 0x93, 0xc3, 0xd8, 0x81, 0xd8, 0x52, 0xd7, 0x9e, 0x9b,
+  0x3e, 0x65, 0xef, 0x98, 0x8d, 0x93, 0x2e, 0x79, 0x58, 0x22, 0x98, 0xe2,
+  0xd9, 0x2f, 0x84, 0x6d, 0xf0, 0x50, 0xc6, 0xba, 0x52, 0x28, 0x29, 0xf1,
+  0x83, 0x4c, 0xad, 0xdd, 0x5a, 0x7a, 0xab, 0xd2, 0x74, 0xb2, 0x1d, 0xc1,
+  0xa9, 0xe4, 0x87, 0xbd, 0xa0, 0x94, 0x0e, 0x50, 0xa7, 0xc7, 0xf1, 0x0d,
+  0xda, 0x0c, 0x36, 0x94, 0xf4, 0x2c, 0xb8, 0x76, 0xc7, 0x7b, 0x32, 0x87,
+  0x23, 0x70, 0x9f, 0x3f, 0x19, 0xeb, 0xc3, 0xb5, 0x3a, 0x6e, 0xec, 0xa7,
+  0x9c, 0xb4, 0xdb, 0xe7, 0x6e, 0x6d, 0x5e, 0x3c, 0x14, 0xa1, 0xa6, 0xfb,
+  0x50, 0xfb, 0x17, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x7e, 0x30, 0x7c,
+  0x30, 0x1b, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x14, 0xb2, 0xfe, 0x21,
+  0x23, 0x44, 0x86, 0x95, 0x6a, 0x79, 0xd5, 0x81, 0x26, 0x8e, 0x73, 0x10,
+  0xd8, 0xa7, 0x4c, 0x8e, 0x74, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
+  0x04, 0x16, 0x04, 0x14, 0x33, 0x2f, 0xbd, 0x38, 0x86, 0xbc, 0xb0, 0xb2,
+  0x6a, 0xd3, 0x86, 0xca, 0x92, 0x7c, 0x0a, 0x6d, 0x55, 0xab, 0x34, 0x81,
+  0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02,
+  0x30, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
+  0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x20, 0x06, 0x03, 0x55, 0x1d,
+  0x25, 0x01, 0x01, 0xff, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06,
+  0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+  0x05, 0x07, 0x03, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0xe2,
+  0x0c, 0x37, 0x3e, 0x5f, 0x96, 0x10, 0x0d, 0xea, 0xa5, 0x15, 0x8f, 0xa2,
+  0x5b, 0x01, 0xe0, 0x1f, 0x15, 0x11, 0x42, 0x4b, 0x9e, 0x4b, 0x93, 0x90,
+  0x56, 0x4f, 0x4f, 0xbb, 0xc7, 0x32, 0x74, 0xfc, 0xbd, 0x1c, 0xcc, 0x06,
+  0x9f, 0xbb, 0x0b, 0x11, 0xa4, 0x8b, 0xa0, 0x52, 0x59, 0x94, 0xef, 0x87,
+  0x0c, 0xb1, 0xa8, 0xe0, 0x85, 0x96, 0xe1, 0x1b, 0x8b, 0x56, 0x12, 0x4d,
+  0x94, 0xd6, 0xa5, 0x52, 0x7f, 0x65, 0xf3, 0x21, 0x1f, 0xaa, 0x07, 0x8c,
+  0xaf, 0x69, 0xfa, 0x47, 0xbe, 0x3b, 0x74, 0x1a, 0x7c, 0xa6, 0x25, 0x63,
+  0x18, 0x5f, 0x0d, 0xda, 0xc4, 0x58, 0x01, 0xbc, 0xf2, 0x6d, 0x2d, 0xc1,
+  0x68, 0x3e, 0xa1, 0x2c, 0x59, 0x03, 0x3e, 0xa3, 0x13, 0x1b, 0xd9, 0x42,
+  0x28, 0x1e, 0x6c, 0x7f, 0x7f, 0x9d, 0x29, 0xf6, 0x43, 0x84, 0xe7, 0x60,
+  0xe3, 0x6f, 0x6a, 0x8a, 0x9f, 0x1d, 0x70
+};
+unsigned int device_cert_der_len = 739;
+
+unsigned char device_key[] = {
+  0x30, 0x82, 0x02, 0x5c, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xba,
+  0xc5, 0x2a, 0x7b, 0xb3, 0x29, 0x21, 0x8d, 0xbd, 0x01, 0x12, 0xff, 0x0b,
+  0xf6, 0x14, 0x66, 0x15, 0x7b, 0x99, 0xf8, 0x1e, 0x08, 0x46, 0x40, 0xd7,
+  0x48, 0x57, 0xf0, 0x9c, 0x08, 0xac, 0xbc, 0x93, 0xc3, 0xd8, 0x81, 0xd8,
+  0x52, 0xd7, 0x9e, 0x9b, 0x3e, 0x65, 0xef, 0x98, 0x8d, 0x93, 0x2e, 0x79,
+  0x58, 0x22, 0x98, 0xe2, 0xd9, 0x2f, 0x84, 0x6d, 0xf0, 0x50, 0xc6, 0xba,
+  0x52, 0x28, 0x29, 0xf1, 0x83, 0x4c, 0xad, 0xdd, 0x5a, 0x7a, 0xab, 0xd2,
+  0x74, 0xb2, 0x1d, 0xc1, 0xa9, 0xe4, 0x87, 0xbd, 0xa0, 0x94, 0x0e, 0x50,
+  0xa7, 0xc7, 0xf1, 0x0d, 0xda, 0x0c, 0x36, 0x94, 0xf4, 0x2c, 0xb8, 0x76,
+  0xc7, 0x7b, 0x32, 0x87, 0x23, 0x70, 0x9f, 0x3f, 0x19, 0xeb, 0xc3, 0xb5,
+  0x3a, 0x6e, 0xec, 0xa7, 0x9c, 0xb4, 0xdb, 0xe7, 0x6e, 0x6d, 0x5e, 0x3c,
+  0x14, 0xa1, 0xa6, 0xfb, 0x50, 0xfb, 0x17, 0x02, 0x03, 0x01, 0x00, 0x01,
+  0x02, 0x81, 0x80, 0x47, 0x9e, 0x91, 0xc2, 0xeb, 0x99, 0xeb, 0x26, 0xfa,
+  0x02, 0x2e, 0x71, 0xa4, 0xf9, 0x91, 0x2a, 0xf0, 0x33, 0xfc, 0x7f, 0xdb,
+  0xac, 0x5a, 0x9c, 0x44, 0xb1, 0x96, 0x1f, 0x4b, 0x06, 0x3c, 0x8e, 0xf7,
+  0xae, 0xd3, 0x18, 0x3f, 0x86, 0xcc, 0xee, 0x22, 0x23, 0xd4, 0x5d, 0x03,
+  0x47, 0xce, 0xd7, 0xb4, 0x6a, 0x6a, 0xa1, 0xeb, 0xe3, 0x52, 0xc8, 0x5a,
+  0x8c, 0x1b, 0xbd, 0x88, 0xf7, 0x36, 0x34, 0xd2, 0xfe, 0x6b, 0x75, 0x9c,
+  0xa4, 0x97, 0x2f, 0xeb, 0xa8, 0xec, 0x48, 0xb7, 0xe7, 0x53, 0x8f, 0xf1,
+  0x39, 0xca, 0xf8, 0xd2, 0xee, 0x34, 0xdc, 0x10, 0x99, 0x6f, 0xfd, 0x83,
+  0x21, 0xa9, 0xe0, 0xe9, 0x0c, 0x4e, 0x4e, 0x62, 0x5f, 0x9f, 0x0f, 0x05,
+  0xcd, 0xf4, 0x2b, 0x08, 0x06, 0x93, 0x55, 0x76, 0xaf, 0x63, 0x77, 0x80,
+  0x3e, 0xd5, 0xf2, 0xe0, 0x58, 0x7f, 0x3c, 0x41, 0x88, 0x4b, 0xc1, 0x02,
+  0x41, 0x01, 0x84, 0xfc, 0xa9, 0x26, 0x74, 0xe7, 0x4e, 0xe4, 0x39, 0xc4,
+  0x8f, 0x81, 0xe8, 0xc0, 0xd3, 0x6e, 0x01, 0x12, 0x7e, 0x12, 0x2d, 0x61,
+  0xaf, 0xe8, 0x60, 0x65, 0x8b, 0x50, 0x46, 0xdf, 0x02, 0x42, 0xe1, 0xea,
+  0xc1, 0x57, 0x9a, 0x2d, 0x90, 0xdc, 0x10, 0xf1, 0x79, 0xf0, 0xb5, 0x5c,
+  0x89, 0xef, 0x3b, 0xa8, 0x7a, 0x88, 0x3d, 0x54, 0xde, 0x35, 0x9c, 0xc3,
+  0x38, 0x4f, 0x2e, 0xb0, 0x74, 0xf7, 0x02, 0x40, 0x7a, 0xea, 0xc9, 0xfe,
+  0x48, 0xeb, 0x94, 0x20, 0x50, 0x33, 0x9d, 0x4f, 0x6f, 0x7f, 0xb1, 0x0e,
+  0xee, 0x42, 0x1c, 0xae, 0x72, 0x06, 0xb9, 0x9c, 0x80, 0x4a, 0xed, 0x07,
+  0xf8, 0x76, 0x5b, 0x37, 0x81, 0x45, 0x69, 0x09, 0xa5, 0x0d, 0x92, 0xed,
+  0xa8, 0xf0, 0x05, 0x6d, 0xb3, 0xa4, 0xef, 0xfb, 0x1b, 0xf0, 0x89, 0xea,
+  0x80, 0x2d, 0xaf, 0x9d, 0xbe, 0xc0, 0x08, 0x44, 0x58, 0x61, 0xc2, 0xe1,
+  0x02, 0x41, 0x01, 0x31, 0xaf, 0x14, 0x86, 0x82, 0x2c, 0x1c, 0x55, 0x42,
+  0x08, 0x73, 0xf6, 0x55, 0x20, 0xe3, 0x86, 0x79, 0x15, 0x3d, 0x39, 0xaf,
+  0xac, 0x2a, 0xfe, 0xe4, 0x72, 0x28, 0x2e, 0xe7, 0xe2, 0xec, 0xf5, 0xfe,
+  0x6f, 0xeb, 0x8c, 0x9a, 0x3e, 0xe0, 0xad, 0xf0, 0x2a, 0xb3, 0xf7, 0x33,
+  0xaf, 0x0b, 0x3e, 0x93, 0x95, 0x6c, 0xe5, 0x8f, 0xbd, 0x17, 0xfa, 0xed,
+  0xbc, 0x84, 0x8d, 0xc5, 0x55, 0x2a, 0x35, 0x02, 0x40, 0x6b, 0x4e, 0x1f,
+  0x4b, 0x03, 0x63, 0xcd, 0xab, 0xab, 0xf8, 0x73, 0x43, 0x8e, 0xa6, 0x1d,
+  0xef, 0x57, 0xe6, 0x95, 0x5d, 0x61, 0x24, 0x27, 0xd3, 0xcd, 0x58, 0x1b,
+  0xb7, 0x92, 0x9b, 0xd8, 0xa4, 0x0b, 0x11, 0x8a, 0x52, 0x26, 0x2a, 0x44,
+  0x73, 0x7f, 0xc1, 0x12, 0x2c, 0x23, 0xe1, 0x40, 0xb3, 0xaa, 0x3f, 0x82,
+  0x57, 0x1a, 0xd1, 0x47, 0x77, 0xe1, 0xb7, 0x89, 0x40, 0x09, 0x1c, 0x47,
+  0x61, 0x02, 0x41, 0x00, 0xa4, 0x47, 0x7d, 0x98, 0x74, 0x25, 0x95, 0x5a,
+  0xc9, 0xbe, 0x76, 0x66, 0xf8, 0x24, 0xb0, 0x83, 0x49, 0xd2, 0xce, 0x98,
+  0x75, 0x7c, 0xbb, 0xd9, 0x24, 0xe9, 0xc5, 0x53, 0xea, 0xd8, 0xec, 0x94,
+  0x79, 0xbb, 0x4e, 0x96, 0xc6, 0xd6, 0x17, 0x26, 0x77, 0xf3, 0x12, 0x3e,
+  0x15, 0x8e, 0x0c, 0x86, 0xdf, 0xa9, 0xf1, 0x34, 0x9b, 0x49, 0x28, 0x0a,
+  0x95, 0xb5, 0x29, 0x8f, 0x8a, 0x21, 0xff, 0xfc
+};
+unsigned int device_key_len = 608;
+
+
+static inline CFTypeRef valid_cf_obj(CFTypeRef obj, CFTypeID type)
+{
+    if (obj && CFGetTypeID(obj) == type)
+        return obj;
+    return NULL;
+}
+
+static inline CFTypeRef dict_get_value_of_type(CFDictionaryRef dict, CFTypeRef key, CFTypeID value_type)
+{
+    CFTypeRef value = CFDictionaryGetValue(dict, key);
+    return valid_cf_obj(value, value_type);
+}
+
+#include <fcntl.h>
+static inline void write_data(const char * path, CFDataRef data)
+{
+    int data_file = open(path, O_CREAT|O_WRONLY|O_TRUNC, 0644);
+    write(data_file, CFDataGetBytePtr(data), CFDataGetLength(data));
+    close(data_file);
+    printf("wrote intermediate result to: %s\n", path);
+}
+
+static void _query_string_apply(const void *key, const void *value, void *context)
+{
+    CFStringRef escaped_key = 
+        CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, 
+            (CFStringRef)key, NULL, NULL, kCFStringEncodingUTF8);
+    CFStringRef escaped_value = 
+        CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, 
+            (CFStringRef)value, NULL, NULL, kCFStringEncodingUTF8);
+    CFMutableStringRef query_string = (CFMutableStringRef)context;
+    
+    CFStringRef format;
+    if (CFStringGetLength(query_string) > 1)
+        format = CFSTR("&%@=%@");
+    else
+        format = CFSTR("%@=%@");
+
+    CFStringAppendFormat(query_string, NULL, format, escaped_key, escaped_value);
+    CFRelease(escaped_key);
+    CFRelease(escaped_value);
+}
+
+static CFURLRef build_url(CFStringRef base, CFDictionaryRef info)
+{
+    CFURLRef url = NULL, base_url = NULL;
+    CFMutableStringRef query_string = 
+        CFStringCreateMutableCopy(kCFAllocatorDefault, 0, CFSTR("?"));
+    require(query_string, out);
+    if (info)
+        CFDictionaryApplyFunction(info, _query_string_apply, query_string);
+    base_url = CFURLCreateWithString(kCFAllocatorDefault, base, NULL);
+    url = CFURLCreateWithString(kCFAllocatorDefault, query_string, base_url);
+out:    
+    CFReleaseSafe(base_url);
+    return url;
+}
+
+static CFURLRef scep_url_operation(CFStringRef base, CFStringRef operation, CFStringRef message)
+{
+    CFURLRef url = NULL;
+    const void *keys[] = { CFSTR("operation"), CFSTR("message") };
+    const void *values[] = { operation, message };
+    
+    require(operation, out);
+    CFDictionaryRef dict = CFDictionaryCreate(NULL, keys, values, message ? 2 : 1, NULL, NULL);
+    url = build_url(base, dict);
+    CFRelease(dict);
+out:
+    return url;
+}
+
+static bool auth_failed(CFHTTPMessageRef request, CFReadStreamRef readStream)
+{
+    bool isAuthenticationChallenge = false;
+    CFHTTPMessageRef responseHeaders = (CFHTTPMessageRef)CFReadStreamCopyProperty(readStream, kCFStreamPropertyHTTPResponseHeader);
+    if (responseHeaders) {
+        // Is the server response an challenge for credentials?
+        isAuthenticationChallenge = (CFHTTPMessageGetResponseStatusCode(responseHeaders) == 401);
+        if (isAuthenticationChallenge) {
+            CFStringRef cf_user = CFStringCreateWithCString(kCFAllocatorDefault, user, kCFStringEncodingUTF8);
+            CFStringRef cf_pass = CFStringCreateWithCString(kCFAllocatorDefault, pass, kCFStringEncodingUTF8);
+            CFHTTPMessageAddAuthentication(request, responseHeaders, cf_user, cf_pass, NULL, false);
+        }
+        CFRelease(responseHeaders);
+    }
+    return isAuthenticationChallenge;
+}
+
+static CFHTTPMessageRef load_request(CFHTTPMessageRef request, CFMutableDataRef data, int retry)
+{
+    CFHTTPMessageRef result = NULL;
+    
+    if (retry < 0)
+        return result;
+
+    CFReadStreamRef rs;
+    rs = CFReadStreamCreateForHTTPRequest(NULL, request);
+
+    const void *keys[] = { 
+        kCFStreamSSLValidatesCertificateChain, 
+//        kCFStreamSSLCertificates,
+    };
+    //CFArrayRef ident = mit_identity();
+    const void *values[] = {
+        kCFBooleanFalse, 
+//        ident,
+    };
+
+    CFDictionaryRef dict = CFDictionaryCreate(NULL, keys, values,
+        array_size(keys),
+        &kCFTypeDictionaryKeyCallBacks,
+        &kCFTypeDictionaryValueCallBacks);
+    CFReadStreamSetProperty(rs, kCFStreamPropertySSLSettings, dict);
+    CFRelease(dict);
+    CFReadStreamSetProperty(rs, kCFStreamPropertyHTTPAttemptPersistentConnection, kCFBooleanTrue);
+    
+    if (CFReadStreamOpen(rs)) {
+        do {
+            if (auth_failed(request, rs)) {
+                CFReadStreamClose(rs);
+                CFDataSetLength(data, 0);
+                if (retry)
+                    return load_request(request, data, retry - 1);
+                break;
+            }
+            UInt8 buf[BUFSIZE];
+            CFIndex bytesRead = CFReadStreamRead(rs, buf, BUFSIZE);
+            if (bytesRead > 0) {
+                CFDataAppendBytes(data, buf, bytesRead);
+            } else if (bytesRead == 0) {
+                // Success
+                result = (CFHTTPMessageRef)CFReadStreamCopyProperty(rs, kCFStreamPropertyHTTPResponseHeader);
+                break;
+            } else {
+                // Error
+                break;
+            }
+        } while (true);
+    } else {
+        // Error
+    }
+
+    CFReadStreamClose(rs);
+    CFRelease(rs);
+    if (debug)
+        CFShow(result);
+    return result;
+}
+
+
+static CFDictionaryRef get_encrypted_profile_packet(CFStringRef base_url)
+{
+#if 1
+    SecCertificateRef cert = SecCertificateCreateWithBytes(NULL, 
+        device_cert_der, device_cert_der_len);
+    SecKeyRef key = SecKeyCreateRSAPrivateKey(NULL, 
+        device_key, device_key_len, kSecKeyEncodingPkcs1);
+    SecIdentityRef identity = SecIdentityCreate(kCFAllocatorDefault, cert, key);
+    CFRelease(cert);
+    CFRelease(key);
+#else
+    SecIdentityRef identity = lockdown_copy_device_identity();
+#endif
+
+    CFMutableDictionaryRef machine_dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 
+        0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    CFDictionarySetValue(machine_dict, CFSTR("UDID"), CFSTR("f1f50f8122fb10146f65e90380176342add6a85c"));
+    CFStringRef cf_user = CFStringCreateWithCString(kCFAllocatorDefault, user, kCFStringEncodingUTF8);
+    if (cf_user) {
+        CFDictionarySetValue(machine_dict, CFSTR("USERNAME"), cf_user);
+        CFRelease(cf_user);
+    }
+    CFStringRef cf_pass = CFStringCreateWithCString(kCFAllocatorDefault, pass, kCFStringEncodingUTF8);
+    if (cf_pass) {
+        CFDictionarySetValue(machine_dict, CFSTR("PASSWORD"), cf_pass);
+        CFRelease(cf_pass);
+    }
+    CFDataRef machine_dict_data = CFPropertyListCreateXMLData(kCFAllocatorDefault, 
+        (CFPropertyListRef)machine_dict);
+    CFMutableDataRef signed_data = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    if (SecCMSSignDataAndAttributes(identity, machine_dict_data, false, signed_data, NULL))
+        errx(1, "failed to sign data");
+    CFRelease(identity);
+    CFRelease(machine_dict_data);
+    CFRelease(machine_dict);
+
+    CFURLRef url = build_url(base_url, NULL);
+    CFHTTPMessageRef request = CFHTTPMessageCreateRequest(kCFAllocatorDefault, 
+        CFSTR("POST"), url, kCFHTTPVersion1_1);
+    CFHTTPMessageSetBody(request, signed_data);
+    CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Content-Type"), 
+        CFSTR("application/pkcs7-signature"));
+    CFMutableDataRef data = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    CFHTTPMessageRef response = load_request(request, data, 1);
+    CFRelease(request);
+    CFRelease(response);
+    CFErrorRef error = NULL;
+    CFTypeRef result = CFPropertyListCreateWithData(kCFAllocatorDefault,
+        data, kCFPropertyListImmutable, NULL, &error);
+    CFRelease(data);
+    if (error) {
+        CFShow(error);
+        errx(1, "failed to decode encrypted profile response");
+        CFRelease(error);
+    }
+    if (CFGetTypeID(result) != CFDictionaryGetTypeID())
+    CFReleaseNull(result);
+    return (CFDictionaryRef)result;
+}
+
+static SecCertificateRef get_ca_cert(CFStringRef scep_base_url, CFStringRef scep_ca_name)
+{
+    SecCertificateRef cert = NULL;
+    CFMutableDataRef data = CFDataCreateMutable(kCFAllocatorDefault, 0);
+
+    CFURLRef url = scep_url_operation(scep_base_url, CFSTR("GetCACert"), scep_ca_name);
+    CFHTTPMessageRef request = CFHTTPMessageCreateRequest(kCFAllocatorDefault, 
+        CFSTR("GET"), url, kCFHTTPVersion1_1);
+    CFHTTPMessageRef result = load_request(request, data, 1);
+
+    if (!result)
+        return NULL;
+    CFStringRef contentTypeValue = CFHTTPMessageCopyHeaderFieldValue(result, CFSTR("Content-Type"));
+//    CFHTTPMessageRef response = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, false);
+//    CFHTTPMessageAppendBytes(response, CFDataGetBytePtr(data), CFDataGetLength(data));
+//    CFDataRef bodyValue = CFHTTPMessageCopyBody(response);
+    if (kCFCompareEqualTo == CFStringCompare(CFSTR("application/x-x509-ca-cert"), 
+        contentTypeValue, kCFCompareCaseInsensitive)) {
+        // CA only response: application/x-x509-ca-cert
+        cert = SecCertificateCreateWithData(kCFAllocatorDefault, data);
+        if (debug)
+            write_data("/tmp/ca_cert.der", data);
+    } else if (kCFCompareEqualTo == CFStringCompare(CFSTR("application/x-x509-ca-ra-cert"), 
+        contentTypeValue, kCFCompareCaseInsensitive)) {
+        // RA/CA response: application/x-x509-ca-ra-cert
+        CFArrayRef cert_array = SecCMSCertificatesOnlyMessageCopyCertificates(data);
+        if (debug)
+            write_data("/tmp/ca_cert_array.der", data);
+        cert = (SecCertificateRef)CFArrayGetValueAtIndex(cert_array, 0);
+        CFRetain(cert);
+        CFRelease(cert_array);
+    }
+    CFRelease(contentTypeValue);
+    CFRelease(data);
+    return cert;
+}
+
+
+static SecIdentityRef perform_scep(CFDictionaryRef scep_dict)
+{
+    SecIdentityRef identity = NULL;
+    CFDictionaryRef parameters = NULL, csr_parameters = NULL;
+    CFStringRef scep_base_url = NULL, scep_instance_name = NULL,
+        scep_challenge = NULL, scep_subject = NULL, scep_subject_requested = NULL;
+    CFTypeRef scep_key_bitsize = NULL;
+    const void *keygen_keys[] = { kSecAttrKeyType, kSecAttrKeySizeInBits };
+    const void *keygen_vals[] = { kSecAttrKeyTypeRSA, CFSTR("512") };
+
+    require(valid_cf_obj(scep_dict,CFDictionaryGetTypeID()), out);
+    require(scep_base_url = 
+        dict_get_value_of_type(scep_dict, CFSTR("URL"), CFStringGetTypeID()), out);
+    require(scep_instance_name = 
+        dict_get_value_of_type(scep_dict, CFSTR("NAME"), CFStringGetTypeID()), out);
+    require(scep_challenge = 
+        dict_get_value_of_type(scep_dict, CFSTR("CHALLENGE"), CFStringGetTypeID()), out);
+        
+    scep_subject_requested = 
+        dict_get_value_of_type(scep_dict, CFSTR("SUBJECT"), CFStringGetTypeID());
+    if (scep_subject_requested) {
+        CFArrayRef scep_subject_components = 
+            CFStringCreateArrayBySeparatingStrings(kCFAllocatorDefault, 
+                scep_subject_requested, CFSTR("="));
+        if (CFArrayGetCount(scep_subject_components) == 2)
+            scep_subject = CFArrayGetValueAtIndex(scep_subject_components, 1);
+    }
+
+    scep_key_bitsize =
+        dict_get_value_of_type(scep_dict, CFSTR("KEYSIZE"), CFNumberGetTypeID());
+    if (!scep_key_bitsize)
+        scep_key_bitsize =
+            dict_get_value_of_type(scep_dict, CFSTR("KEYSIZE"), CFStringGetTypeID());
+    if (scep_key_bitsize)
+        keygen_vals[1] = scep_key_bitsize;
+        
+    parameters = CFDictionaryCreate(kCFAllocatorDefault, 
+        keygen_keys, keygen_vals, array_size(keygen_vals),
+        &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks );
+
+    int key_usage = kSecKeyUsageDigitalSignature | kSecKeyUsageKeyEncipherment;
+    CFNumberRef key_usage_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &key_usage);
+    const void *key[] = { kSecCSRChallengePassword, kSecCertificateKeyUsage };
+    const void *val[] = { scep_challenge ? scep_challenge : CFSTR("magic"), key_usage_num };
+    csr_parameters = CFDictionaryCreate(kCFAllocatorDefault, 
+        key, val, array_size(key), NULL, NULL);
+
+    SecCertificateRef ca_cert = get_ca_cert(scep_base_url, scep_instance_name ? scep_instance_name : CFSTR("test"));
+    if (!ca_cert)
+        errx(1, "no ca cert returned from scep server.");
+
+    identity = NULL; // enroll_scep(scep_base_url, scep_subject, csr_parameters, parameters, ca_cert);
+    if (!identity)
+        errx(1, "failed to get identity from scep server.");
+    
+out:
+    CFReleaseSafe(parameters);
+    return identity;
+}
+
+static CFDataRef get_profile(CFStringRef url_cfstring, SecIdentityRef identity)
+{
+    CFURLRef url = NULL;
+    CFHTTPMessageRef request = NULL;
+    SecCertificateRef cert = NULL;
+    CFDataRef cert_data = NULL;
+    CFMutableDataRef data = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    CFHTTPMessageRef response = NULL;
+    
+    require(url = CFURLCreateWithString(kCFAllocatorDefault, url_cfstring, NULL), out);
+    require(request = CFHTTPMessageCreateRequest(kCFAllocatorDefault, 
+        CFSTR("POST"), url, kCFHTTPVersion1_1), out);
+    require_noerr(SecIdentityCopyCertificate(identity, &cert), out);
+    require(cert_data = SecCertificateCopyData(cert), out);
+    CFHTTPMessageSetBody(request, cert_data);
+    // this is technically the wrong mimetype; we'll probably switch to signed data
+    CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Content-Type"), CFSTR("application/x-x509-ca-cert"));
+    response = load_request(request, data, 1);
+    if (debug && data)
+        CFShow(data);
+out:
+    //CFReleaseSafe(response);
+    CFReleaseSafe(request);
+    CFReleaseSafe(url);
+    CFReleaseSafe(cert_data);
+    CFReleaseSafe(cert);
+    CFReleaseSafe(response);
+    return data;
+
+}
+
+static bool validate_profile(CFDataRef profile_plist_data, SecIdentityRef identity)
+{
+    CFStringRef type = NULL, uuid = NULL;
+    CFDataRef enc_payload = NULL;
+    CFTypeRef result = CFPropertyListCreateWithData(kCFAllocatorDefault,
+        profile_plist_data, kCFPropertyListImmutable, NULL, NULL);
+    require(valid_cf_obj(result, CFDictionaryGetTypeID()), out);
+    require(type = dict_get_value_of_type(result, CFSTR("PayloadType"), 
+        CFStringGetTypeID()), out);
+    require(uuid = dict_get_value_of_type(result, CFSTR("PayloadUUID"), 
+        CFStringGetTypeID()), out);
+    enc_payload = dict_get_value_of_type(result, CFSTR("EncryptedPayloadContent"), 
+        CFDataGetTypeID());
+    if (enc_payload) {
+        CFMutableDataRef dec_data = CFDataCreateMutable(kCFAllocatorDefault, 0);
+        require_noerr(SecCMSDecryptEnvelopedData(enc_payload, dec_data, NULL), out);
+        bool sub = validate_profile(dec_data, identity);
+        CFReleaseSafe(dec_data);
+        return sub;
+    } else {
+        if (debug)
+            write_data("/tmp/unencrypted_profile.mobileconfig", profile_plist_data);
+        //CFDictionaryRef sub_conf = dict_get_value_of_type(result, CFSTR("PayloadContent"), CFDictionaryGetTypeID());
+    }
+    return true;
+out:
+    return false;
+}
+
+#if 0
+static const char *auth = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
+<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/\n\
+PropertyList-1.0.dtd\">\n\
+<plist version=\"1.0\">\n\
+<dict>\n\
+        <key>PayloadContent</key>\n\
+        <dict>\n\
+                <key>URL</key>\n\
+                <string>https://phone.vpn.apple.com/deviceid/</string>\n\
+                <key>DeviceAttributes</key>\n\
+                <array>\n\
+                        <string>UDID</string>\n\
+                        <string>VERSION</string>\n\
+                        <string>MAC_ADDRESS_EN0</string>\n\
+                        <string>MAC_ADDRESS_IP0</string>\n\
+                </array>\n\
+              <key>CHALLENGE</key>\n\
+              <string>${USER_COOKIE}</string>\n\
+        </dict>\n\
+        <key>PayloadType</key>\n\
+        <string>Device Identification</string>\n\
+</dict>\n\
+</plist>\n";
+
+static void annotate_machine_info(const void *value, void *context)
+{
+    CFDictionaryRef machine_dict = NULL;
+    CFStringRef machine_key = NULL;
+    require(machine_dict = (CFDictionaryRef)valid_cf_obj(context, 
+        CFDictionaryGetTypeID()), out);
+    require(machine_key = (CFStringRef)valid_cf_obj((CFTypeRef)value, 
+        CFStringGetTypeID()), out);
+    if (CFEqual(machine_key, CFSTR("UDID"))) {
+    
+    }
+out:
+    return;
+}
+
+static void machine_authentication(CFDataRef req, CFDataRef reply)
+{
+    CFDataRef machine_auth_request = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, 
+        (uint8_t*)auth, strlen(auth), kCFAllocatorNull);
+    CFDictionaryRef auth_dict = NULL;
+    CFMutableDictionaryRef auth_reply_dict = 
+        CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 
+        &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+        
+    if (req) { CFRelease(machine_auth_request); machine_auth_request = req; CFRetain(req); }
+    CFDictionaryRef auth_request_dict = CFPropertyListCreateWithData(kCFAllocatorDefault,
+        machine_auth_request, kCFPropertyListImmutable, NULL, NULL);
+    
+    require(auth_reply_dict, out);
+    require(valid_cf_obj(auth_request_dict, CFDictionaryGetTypeID()), out);
+    require(auth_dict = dict_get_value_of_type(auth_request_dict, CFSTR("PayloadContent"), CFDictionaryGetTypeID()), out);
+    CFStringRef challenge = dict_get_value_of_type(auth_dict, CFSTR("CHALLENGE"), CFStringGetTypeID());
+    if (challenge)
+        CFDictionarySetValue(auth_reply_dict, CFSTR("CHALLENGE"), challenge);
+    CFArrayRef device_info = dict_get_value_of_type(auth_dict, CFSTR("DeviceAttributes"), CFArrayGetTypeID());
+    if (device_info)
+        CFArrayApplyFunction(device_info, CFRangeMake(0, CFArrayGetCount(device_info)), 
+            annotate_machine_info, auth_reply_dict);
+    
+    // make copy of reply dict
+out:
+    CFReleaseSafe(machine_auth_request);
+    CFReleaseSafe(auth_request_dict);
+}
+#endif
+
+extern int command_spc(int argc, char * const *argv)
+{
+    SecIdentityRef identity = NULL;
+       extern char *optarg;
+    extern int optind;
+       int arg;
+       while ((arg = getopt(argc, argv, "du:p:")) != -1) {
+               switch (arg) {
+            case 'd':
+                debug = 1;
+                break;
+            case 'u':
+                               user = optarg;
+                               break;
+                       case 'p':
+                pass = optarg;
+                               break;
+                       case 'h':
+                       default:
+                               return 2;
+               }
+       }
+
+       argc -= optind;
+       argv += optind;
+
+#if 0
+    if (argc == 1) {
+        // get plist from argv[0] url
+    } else if (argc == 0) {
+        machine_authentication(NULL, NULL);
+    } else return 2;
+#endif
+
+    if (argc != 1)
+        return 2;
+
+    CFStringRef machine_id_url_cfstring = CFStringCreateWithCString(kCFAllocatorDefault, 
+        argv[0], kCFStringEncodingUTF8);
+
+    CFDictionaryRef enroll_packet =
+        get_encrypted_profile_packet(machine_id_url_cfstring);
+    require(enroll_packet && CFGetTypeID(enroll_packet) == CFDictionaryGetTypeID(), out);
+    //require(payload_type(enroll_packet, "Encrypted Profile Service"), out);
+    CFDictionaryRef scep_config = NULL;
+    CFDictionaryRef payload_content = NULL;
+    require(payload_content = dict_get_value_of_type(enroll_packet, 
+        CFSTR("PayloadContent"), CFDictionaryGetTypeID()), out);
+    require(scep_config = dict_get_value_of_type(payload_content, 
+        CFSTR("SCEP"), CFDictionaryGetTypeID()), out);
+    require(identity = perform_scep(scep_config), out);
+    CFDictionaryRef dict = CFDictionaryCreate(NULL, &kSecValueRef, (const void **)&identity, 1, NULL, NULL);
+    require_noerr(SecItemAdd(dict, NULL), out);
+    CFReleaseSafe(dict);
+    CFStringRef profile_url = NULL;
+    require(profile_url = dict_get_value_of_type(payload_content, 
+        CFSTR("URL"), CFStringGetTypeID()), out);
+        
+    CFDataRef profile_data = NULL;
+    require(profile_data = get_profile(profile_url, identity), out);
+    CFDataRef profile_plist = NULL;
+    if (debug)
+        write_data("/tmp/profile.mobileconfig", profile_data);
+    
+    require_noerr(SecCMSVerify(profile_data, NULL, NULL, NULL, &profile_plist), out);
+    CFRelease(profile_data);
+    require(profile_plist, out);
+    require(validate_profile(profile_plist, identity), out);
+
+    return 0;
+out:        
+    errx(1, "fail.");
+    return -1;
+}
+
+
+#endif // TARGET_OS_EMBEDDED
diff --git a/sec/Security/cssmapple.h b/sec/Security/cssmapple.h
new file mode 100644 (file)
index 0000000..183bac7
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved.
+ * 
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ *
+ * cssmapple.h -- CSSM features specific to Apple's Implementation
+ */
+
+#ifndef _CSSMAPPLE_H_
+#define _CSSMAPPLE_H_  1
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* First, an array of bits indicating various status of the cert. */
+typedef uint32 CSSM_TP_APPLE_CERT_STATUS;
+enum 
+{
+    CSSM_CERT_STATUS_EXPIRED            = 0x00000001,
+    CSSM_CERT_STATUS_NOT_VALID_YET      = 0x00000002,
+    CSSM_CERT_STATUS_IS_IN_INPUT_CERTS  = 0x00000004,
+    CSSM_CERT_STATUS_IS_IN_ANCHORS      = 0x00000008,
+    CSSM_CERT_STATUS_IS_ROOT            = 0x00000010,
+    CSSM_CERT_STATUS_IS_FROM_NET        = 0x00000020,
+    /* settings found in per-user Trust Settings */
+    CSSM_CERT_STATUS_TRUST_SETTINGS_FOUND_USER      = 0x00000040,
+    /* settings found in Admin Trust Settings */
+    CSSM_CERT_STATUS_TRUST_SETTINGS_FOUND_ADMIN     = 0x00000080,
+    /* settings found in System Trust Settings */
+    CSSM_CERT_STATUS_TRUST_SETTINGS_FOUND_SYSTEM    = 0x00000100,
+    /* Trust Settings result = Trust */
+    CSSM_CERT_STATUS_TRUST_SETTINGS_TRUST           = 0x00000200,
+    /* Trust Settings result = Deny */
+    CSSM_CERT_STATUS_TRUST_SETTINGS_DENY            = 0x00000400,
+    /* Per-cert error ignored due to Trust Settings */
+    CSSM_CERT_STATUS_TRUST_SETTINGS_IGNORED_ERROR   = 0x00000800
+};
+
+typedef struct {
+    CSSM_TP_APPLE_CERT_STATUS   StatusBits;
+    uint32                      NumStatusCodes;
+    CSSM_RETURN                 *StatusCodes;
+    
+    /* index into raw cert group or AnchorCerts depending on IS_IN_ANCHORS */
+    uint32                      Index;   
+    
+    /* nonzero if cert came from a DLDB */
+    CSSM_DL_DB_HANDLE           DlDbHandle;
+    CSSM_DB_UNIQUE_RECORD_PTR   UniqueRecord;
+} CSSM_TP_APPLE_EVIDENCE_INFO;
+
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif /* _CSSMAPPLE_H_ */
diff --git a/sec/Security/keychain_find.h b/sec/Security/keychain_find.h
new file mode 100644 (file)
index 0000000..e1dcc0f
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2003-2007 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ *
+ * keychain_find.h
+ */
+
+#ifndef _KEYCHAIN_FINDINTERNETPASSWORD_H_
+#define _KEYCHAIN_FINDINTERNETPASSWORD_H_  1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int keychain_item(int argc, char * const *argv);
+
+extern int keychain_find_internet_password(int argc, char * const *argv);
+
+extern int keychain_find_generic_password(int argc, char * const *argv);
+
+extern int keychain_find_certificate(int argc, char * const *argv);
+
+extern int keychain_delete_internet_password(int argc, char * const *argv);
+
+extern int keychain_delete_generic_password(int argc, char * const *argv);
+
+extern int keychain_dump(int argc, char * const *argv);
+
+extern int keychain_show_certificates(int argc, char * const *argv);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _KEYCHAIN_FINDINTERNETPASSWORD_H_ */
index 2db74faf22f6e883ccf26369655efe258c3397ea..500055ab839f41c6ef6ec8ec8d8e9705a05c4eb1 100644 (file)
@@ -34,7 +34,7 @@
 
 #include <AssertMacros.h>
 #include <Security/SecInternal.h>
 
 #include <AssertMacros.h>
 #include <Security/SecInternal.h>
-#include <security_utilities/debugging.h>
+#include <utilities/debugging.h>
 
 #include "p12pbegen.h"
 #include "p12import.h"
 
 #include "p12pbegen.h"
 #include "p12import.h"
@@ -277,14 +277,23 @@ static int shroudedKeyBagParse(pkcs12_context * context, const NSS_P12_SafeBag *
     memset(&pki, 0, sizeof(pki));
        require_noerr(decode_item(context, &ptext, kSecAsn1PrivateKeyInfoTemplate,
                        &pki), out);
     memset(&pki, 0, sizeof(pki));
        require_noerr(decode_item(context, &ptext, kSecAsn1PrivateKeyInfoTemplate,
                        &pki), out);
+
     DERItem algorithm = { pki.algorithm.algorithm.Data, pki.algorithm.algorithm.Length };
     DERItem algorithm = { pki.algorithm.algorithm.Data, pki.algorithm.algorithm.Length };
-    require(DEROidCompare(&oidRsa, &algorithm), out);
+    CFDataRef algoidData = NULL;
+    if (DEROidCompare(&oidEcPubKey, &algorithm)) {
+        algoidData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, oidEcPubKey.data, oidEcPubKey.length, kCFAllocatorNull);
+    } else if (DEROidCompare(&oidRsa, &algorithm)) {
+        algoidData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, oidRsa.data, oidRsa.length, kCFAllocatorNull);
+    } else {
+        goto out;
+    }
+    require_noerr(emit_item(context, safeBag->bagAttrs, CFSTR("algid"), algoidData), out);
+    CFRelease(algoidData);
 
     CFDataRef keyData = CFDataCreate(kCFAllocatorDefault, pki.privateKey.Data, pki.privateKey.Length);
 
     CFDataRef keyData = CFDataCreate(kCFAllocatorDefault, pki.privateKey.Data, pki.privateKey.Length);
-
     require_noerr(emit_item(context, safeBag->bagAttrs, CFSTR("key"), keyData), out);
     CFRelease(keyData);
     require_noerr(emit_item(context, safeBag->bagAttrs, CFSTR("key"), keyData), out);
     CFRelease(keyData);
-    
+
     return 0;
 out:
     return -1;
     return 0;
 out:
     return -1;
index 6fb81fe9e3738fb949108f12cea4aa3db4451974..7d38b0061cbf49f8090e913cc144867095c4f2d9 100644 (file)
@@ -27,9 +27,7 @@
 #ifndef _SECURITY_P12IMPORT_H_
 #define _SECURITY_P12IMPORT_H_
 
 #ifndef _SECURITY_P12IMPORT_H_
 #define _SECURITY_P12IMPORT_H_
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 typedef enum {
     p12_noErr = 0,
 
 typedef enum {
     p12_noErr = 0,
@@ -45,8 +43,6 @@ typedef struct {
 
 p12_error p12decode(pkcs12_context * context, CFDataRef cdpfx);
 
 
 p12_error p12decode(pkcs12_context * context, CFDataRef cdpfx);
 
-#if defined(__cplusplus)
-}
-#endif
+__END_DECLS
 
 #endif /* !_SECURITY_P12IMPORT_H_ */
 
 #endif /* !_SECURITY_P12IMPORT_H_ */
index ee86c783954d6524a95473ec69d6276e6b37d20b..3341b409a588ed149f97844dbdc6f728fbb10502 100644 (file)
@@ -25,6 +25,7 @@
 #include <string.h> // memcpy
 
 #include <CommonCrypto/CommonDigest.h>
 #include <string.h> // memcpy
 
 #include <CommonCrypto/CommonDigest.h>
+#include <CommonCrypto/CommonDigestSPI.h>
 
 #include <corecrypto/ccn.h>
 
 
 #include <corecrypto/ccn.h>
 
@@ -86,15 +87,18 @@ int p12_pbe_gen(CFStringRef passphrase, uint8_t *salt_ptr, size_t salt_length,
     size_t salt_data_len = 0;
     if (salt_length)
         salt_data = concatenate_to_blocksize(salt_ptr, salt_length, hash_blocksize, &salt_data_len);
     size_t salt_data_len = 0;
     if (salt_length)
         salt_data = concatenate_to_blocksize(salt_ptr, salt_length, hash_blocksize, &salt_data_len);
-    if (!salt_data)
+    if (!salt_data){
+        free(passphrase_data);
         return -1;
         return -1;
-    
+    }
     /* generate S||P block */
     size_t I_length = salt_data_len + passphrase_data_len;
     uint8_t *I_data = malloc(I_length);
     /* generate S||P block */
     size_t I_length = salt_data_len + passphrase_data_len;
     uint8_t *I_data = malloc(I_length);
-    if (!I_data)
+    if (!I_data){
+        free(salt_data);
+        free(passphrase_data);
         return -1;
         return -1;
-        
+    }
     memcpy(I_data + 0, salt_data, salt_data_len);
     memcpy(I_data + salt_data_len, passphrase_data, passphrase_data_len);
     free(salt_data);
     memcpy(I_data + 0, salt_data, salt_data_len);
     memcpy(I_data + salt_data_len, passphrase_data, passphrase_data_len);
     free(salt_data);
@@ -105,9 +109,10 @@ int p12_pbe_gen(CFStringRef passphrase, uint8_t *salt_ptr, size_t salt_length,
     size_t temp_buf_size = hash_output_blocks * hash_outputsize;
     uint8_t *temp_buf = malloc(temp_buf_size);
     uint8_t *cursor = temp_buf;
     size_t temp_buf_size = hash_output_blocks * hash_outputsize;
     uint8_t *temp_buf = malloc(temp_buf_size);
     uint8_t *cursor = temp_buf;
-    if (!temp_buf)
+    if (!temp_buf){
+        free(I_data);
         return -1;
         return -1;
-
+    }
     /* 64 bits cast(s): worst case here is we dont hash all the data and incorectly derive the wrong key,
        when the passphrase + salt are over 2^32 bytes long */
     /* loop over output in hash_output_size increments */
     /* 64 bits cast(s): worst case here is we dont hash all the data and incorectly derive the wrong key,
        when the passphrase + salt are over 2^32 bytes long */
     /* loop over output in hash_output_size increments */
@@ -122,7 +127,7 @@ int p12_pbe_gen(CFStringRef passphrase, uint8_t *salt_ptr, size_t salt_length,
         /* run block through SHA-1 for iteration count */
         unsigned int i;
         for (i = 1; /*first round done above*/ i < iter_count; i++)
         /* run block through SHA-1 for iteration count */
         unsigned int i;
         for (i = 1; /*first round done above*/ i < iter_count; i++)
-            CC_SHA1(cursor, hash_outputsize, cursor);
+            CCDigest(kCCDigestSHA1, cursor, hash_outputsize, cursor);
 
         /*
          * b) Concatenate copies of A[i] to create a string B of 
 
         /*
          * b) Concatenate copies of A[i] to create a string B of 
@@ -132,9 +137,11 @@ int p12_pbe_gen(CFStringRef passphrase, uint8_t *salt_ptr, size_t salt_length,
         size_t A_i_len = 0;
         uint8_t *A_i = concatenate_to_blocksize(cursor, 
             hash_outputsize, hash_blocksize, &A_i_len);
         size_t A_i_len = 0;
         uint8_t *A_i = concatenate_to_blocksize(cursor, 
             hash_outputsize, hash_blocksize, &A_i_len);
-        if (!A_i)
+        if (!A_i){
+            free(I_data);
+            free(temp_buf);
             return -1;
             return -1;
-        
+        }
         /*
          * c) Treating I as a concatenation I[0], I[1], ..., 
          *    I[k-1] of v-bit blocks, where k = ceil(s/v) + ceil(p/v),
         /*
          * c) Treating I as a concatenation I[0], I[1], ..., 
          *    I[k-1] of v-bit blocks, where k = ceil(s/v) + ceil(p/v),
index 3a29fbfeeaad1bf6ce9c0953384186f577c4c932..0600ad3e01d1a60c58163245b3ff5242122c40cd 100644 (file)
@@ -37,7 +37,7 @@ F (PRF prf, size_t hLen,
    void *tempBuffer)
 {
        uint8_t *inBlock, *outBlock, *resultBlockPtr;
    void *tempBuffer)
 {
        uint8_t *inBlock, *outBlock, *resultBlockPtr;
-       uint32_t iteration;
+       size_t iteration;
        outBlock = (uint8_t*)tempBuffer;
        inBlock = outBlock + hLen;
        /* Set up inBlock to contain Salt || INT (blockNumber). */
        outBlock = (uint8_t*)tempBuffer;
        inBlock = outBlock + hLen;
        /* Set up inBlock to contain Salt || INT (blockNumber). */
@@ -72,7 +72,7 @@ F (PRF prf, size_t hLen,
 void pbkdf2 (PRF prf, size_t hLen,
                         const void *passwordPtr, size_t passwordLen,
                         const void *saltPtr, size_t saltLen,
 void pbkdf2 (PRF prf, size_t hLen,
                         const void *passwordPtr, size_t passwordLen,
                         const void *saltPtr, size_t saltLen,
-                        uint32_t iterationCount,
+                        size_t iterationCount,
                         void *dkPtr, size_t dkLen,
                         void *tempBuffer)
 {
                         void *dkPtr, size_t dkLen,
                         void *tempBuffer)
 {
index a69bbb98b3acc2a816fb06b58010d4add10cff6f..df556fdbb1ea297b93f0afdf5699e616bc7680da 100644 (file)
@@ -66,7 +66,7 @@ typedef void (*PRF)(const uint8_t *keyPtr, size_t keyLen,
 void pbkdf2 (PRF prf, size_t hLen,
                         const void *passwordPtr, size_t passwordLen,
                         const void *saltPtr, size_t saltLen,
 void pbkdf2 (PRF prf, size_t hLen,
                         const void *passwordPtr, size_t passwordLen,
                         const void *saltPtr, size_t saltLen,
-                        uint32_t iterationCount,
+                        size_t iterationCount,
                         void *dkPtr, size_t dkLen,
                         void *tempBuffer);
 
                         void *dkPtr, size_t dkLen,
                         void *tempBuffer);
 
index 14df58deba78d658e49dbd1e957eab4626e720f7..65763233bd98383e6eb712823221c7ec482c93ee 100644 (file)
@@ -16,7 +16,7 @@
 
 #include "vmdh.h"
 #include <CommonCrypto/CommonCryptor.h>
 
 #include "vmdh.h"
 #include <CommonCrypto/CommonCryptor.h>
-#include <security_utilities/debugging.h>
+#include <utilities/debugging.h>
 #include <string.h>
 #include <Security/SecInternal.h>
 #include <Security/SecDH.h>
 #include <string.h>
 #include <Security/SecInternal.h>
 #include <Security/SecDH.h>
diff --git a/sec/SecurityTool/SecurityTool.c b/sec/SecurityTool/SecurityTool.c
new file mode 100644 (file)
index 0000000..3d5ebd5
--- /dev/null
@@ -0,0 +1,405 @@
+/*
+ * Copyright (c) 2003-2010 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ *
+ * security.c
+ */
+
+#include "SecurityTool.h"
+
+#include <SecurityTool/readline.h>
+
+#include "leaks.h"
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <CoreFoundation/CFRunLoop.h>
+
+#if NO_SERVER
+#include <securityd/spi.h>
+#endif
+
+/* Maximum length of an input line in interactive mode. */
+#define MAX_LINE_LEN 4096
+/* Maximum number of arguments on an input line in interactive mode. */
+#define MAX_ARGS 32
+
+
+/* The default prompt. */
+const char *prompt_string = "security> ";
+
+/* The name of this program. */
+const char *prog_name;
+
+
+/* Forward declarations of static functions. */
+
+
+/* Global variables. */
+int do_quiet = 0;
+int do_verbose = 0;
+
+/* Return 1 if name matches command. */
+static int
+match_command(const char *command_name, const char *name)
+{
+       return !strncmp(command_name, name, strlen(name));
+}
+
+/* The help command. */
+int
+help(int argc, char * const *argv)
+{
+       const command *c;
+
+       if (argc > 1)
+       {
+               char * const *arg;
+               for (arg = argv + 1; *arg; ++arg)
+               {
+                       int found = 0;
+
+                       for (c = commands; c->c_name; ++c)
+                       {
+                               if (match_command(c->c_name, *arg))
+                               {
+                                       found = 1;
+                                       break;
+                               }
+                       }
+
+                       if (found)
+                               printf("Usage: %s %s\n", c->c_name, c->c_usage);
+                       else
+                       {
+                               fprintf(stderr, "%s: no such command: %s", argv[0], *arg);
+                               return 1;
+                       }
+               }
+       }
+       else
+       {
+               for (c = commands; c->c_name; ++c)
+                       printf("    %-17s %s\n", c->c_name, c->c_help);
+       }
+
+       return 0;
+}
+
+/* States for split_line parser. */
+typedef enum
+{
+       SKIP_WS,
+       READ_ARG,
+       READ_ARG_ESCAPED,
+       QUOTED_ARG,
+       QUOTED_ARG_ESCAPED
+} parse_state;
+
+/* Split a line into multiple arguments and return them in *pargc and *pargv. */
+static void
+split_line(char *line, int *pargc, char * const **pargv)
+{
+       static char *argvec[MAX_ARGS + 1];
+       int argc = 0;
+       char *ptr = line;
+       char *dst = line;
+       parse_state state = SKIP_WS;
+       int quote_ch = 0;
+
+       for (ptr = line; *ptr; ++ptr)
+       {
+               if (state == SKIP_WS)
+               {
+                       if (isspace(*ptr))
+                               continue;
+
+                       if (*ptr == '"' || *ptr == '\'')
+                       {
+                               quote_ch = *ptr;
+                               state = QUOTED_ARG;
+                               argvec[argc] = dst;
+                               continue; /* Skip the quote. */
+                       }
+                       else
+                       {
+                               state = READ_ARG;
+                               argvec[argc] = dst;
+                       }
+               }
+
+               if (state == READ_ARG)
+               {
+                       if (*ptr == '\\')
+                       {
+                               state = READ_ARG_ESCAPED;
+                               continue;
+                       }
+                       else if (isspace(*ptr))
+                       {
+                               /* 0 terminate each arg. */
+                               *dst++ = '\0';
+                               argc++;
+                               state = SKIP_WS;
+                               if (argc >= MAX_ARGS)
+                                       break;
+                       }
+                       else
+                               *dst++ = *ptr;
+               }
+
+               if (state == QUOTED_ARG)
+               {
+                       if (*ptr == '\\')
+                       {
+                               state = QUOTED_ARG_ESCAPED;
+                               continue;
+                       }
+                       if (*ptr == quote_ch)
+                       {
+                               /* 0 terminate each arg. */
+                               *dst++ = '\0';
+                               argc++;
+                               state = SKIP_WS;
+                               if (argc >= MAX_ARGS)
+                                       break;
+                       }
+                       else
+                               *dst++ = *ptr;
+               }
+
+               if (state == READ_ARG_ESCAPED)
+               {
+                       *dst++ = *ptr;
+                       state = READ_ARG;
+               }
+
+               if (state == QUOTED_ARG_ESCAPED)
+               {
+                       *dst++ = *ptr;
+                       state = QUOTED_ARG;
+               }
+       }
+
+       if (state != SKIP_WS)
+       {
+               /* Terminate last arg. */
+               *dst++ = '\0';
+               argc++;
+       }
+
+       /* Teminate arg vector. */
+       argvec[argc] = NULL;
+
+       *pargv = argvec;
+       *pargc = argc;
+}
+
+/* Print a (hopefully) useful usage message. */
+static int
+usage(void)
+{
+       printf(
+               "Usage: %s [-h] [-i] [-l] [-p prompt] [-q] [-v] [command] [opt ...]\n"
+               "    -i    Run in interactive mode.\n"
+               "    -l    Run /usr/bin/leaks -nocontext before exiting.\n"
+               "    -p    Set the prompt to \"prompt\" (implies -i).\n"
+               "    -q    Be less verbose.\n"
+               "    -v    Be more verbose about what's going on.\n"
+               "%s commands are:\n", prog_name, prog_name);
+       help(0, NULL);
+       return 2;
+}
+
+/* Execute a single command. */ 
+static int
+execute_command(int argc, char * const *argv)
+{
+       const command *c;
+       int found = 0;
+
+       /* Nothing to do. */
+       if (argc == 0)
+               return 0;
+
+       for (c = commands; c->c_name; ++c)
+       {
+               if (match_command(c->c_name, argv[0]))
+               {
+                       found = 1;
+                       break;
+               }
+       }
+
+       if (found)
+       {
+               int result;
+
+               /* Reset getopt for command proc. */
+               optind = 1;
+               optreset = 1;
+
+               if (do_verbose)
+               {
+                       int ix;
+
+                       fprintf(stderr, "%s", c->c_name);
+                       for (ix = 1; ix < argc; ++ix)
+                               fprintf(stderr, " \"%s\"", argv[ix]);
+                       fprintf(stderr, "\n");
+               }
+
+               result = c->c_func(argc, argv);
+               if (result == 2)
+                       fprintf(stderr, "Usage: %s %s\n        %s\n", c->c_name, c->c_usage, c->c_help);
+
+               return result;
+       }
+       else
+       {
+               fprintf(stderr, "unknown command \"%s\"", argv[0]);
+               return 1;
+       }
+}
+
+static void
+receive_notifications(void)
+{
+       /* Run the CFRunloop to get any pending notifications. */
+       while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.0, TRUE) == kCFRunLoopRunHandledSource);
+}
+
+int
+main(int argc, char * const *argv)
+{
+       int result = 0;
+       int do_help = 0;
+       int do_interactive = 0;
+       int do_leaks = 0;
+       int ch;
+
+       /* Remember my name. */
+       prog_name = strrchr(argv[0], '/');
+       prog_name = prog_name ? prog_name + 1 : argv[0];
+
+       /* Do getopt stuff for global options. */
+       optind = 1;
+       optreset = 1;
+       while ((ch = getopt(argc, argv, "hilp:qv")) != -1)
+       {
+               switch  (ch)
+               {
+               case 'h':
+                       do_help = 1;
+                       break;
+               case 'i':
+                       do_interactive = 1;
+                       break;
+               case 'l':
+                       do_leaks = 1;
+                       break;
+               case 'p':
+                       do_interactive = 1;
+                       prompt_string = optarg;
+                       break;
+               case 'q':
+                       do_quiet = 1;
+                       break;
+               case 'v':
+                       do_verbose = 1;
+                       break;
+               case '?':
+               default:
+                       return usage();
+               }
+       }
+
+       argc -= optind;
+       argv += optind;
+
+#if NO_SERVER
+# if DEBUG
+//    securityd_init();
+# endif
+#endif
+
+       if (do_help)
+       {
+               /* Munge argc/argv so that argv[0] is something. */
+               return help(argc + 1, argv - 1);
+       }
+       else if (argc > 0)
+       {
+               receive_notifications();
+               result = execute_command(argc, argv);
+               receive_notifications();
+       }
+       else if (do_interactive)
+       {
+               /* In interactive mode we just read commands and run them until readline returns NULL. */
+
+        /* Only show prompt string if stdin is a tty. */
+        int show_prompt = isatty(0);
+
+               for (;;)
+               {
+                       static char buffer[MAX_LINE_LEN];
+                       char * const *av, *input;
+                       int ac;
+
+            if (show_prompt)
+                fprintf(stderr, "%s", prompt_string);
+
+                       input = readline(buffer, MAX_LINE_LEN);
+                       if (!input)
+                               break;
+
+                       split_line(input, &ac, &av);
+                       receive_notifications();
+                       result = execute_command(ac, av);
+                       receive_notifications();
+                       if (result == -1)
+                       {
+                               result = 0;
+                               break;
+                       }
+
+                       if (result && ! do_quiet)
+                       {
+                               fprintf(stderr, "%s: returned %d\n", av[0], result);
+                       }
+               }
+       }
+       else
+               result = usage();
+
+       if (do_leaks)
+       {
+               char *const argvec[3] = { "leaks", "-nocontext", NULL };
+               leaks(2, argvec);
+       }
+
+       return result;
+}
diff --git a/sec/SecurityTool/SecurityTool.h b/sec/SecurityTool/SecurityTool.h
new file mode 100644 (file)
index 0000000..6f1bfc8
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2003-2004,2006-2007 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ *
+ * security.h
+ */
+
+#ifndef _SECURITYTOOL_H_
+#define _SECURITYTOOL_H_
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+typedef int(*command_func)(int argc, char * const *argv);
+
+/* Entry in commands array for a command. */
+typedef struct command
+{
+    const char *c_name;    /* name of the command. */
+    command_func c_func;   /* function to execute the command. */
+    const char *c_usage;   /* usage sting for command. */
+    const char *c_help;    /* help string for (or description of) command. */
+} command;
+
+/*
+ * The command array itself.
+ * Add commands here at will.
+ * Matching is done on a prefix basis.  The first command in the array
+ * gets matched first.
+ */
+extern const command commands[];
+
+/* Our one builtin command.
+ */
+int help(int argc, char * const *argv);
+    
+/* If 1 attempt to be as quiet as possible. */
+extern int do_quiet;
+
+/* If 1 attempt to be as verbose as possible. */
+extern int do_verbose;
+
+extern const char* prog_name;
+
+__END_DECLS
+
+#endif /*  _SECURITY_H_ */
diff --git a/sec/SecurityTool/builtin_commands.h b/sec/SecurityTool/builtin_commands.h
new file mode 100644 (file)
index 0000000..4973481
--- /dev/null
@@ -0,0 +1,21 @@
+//
+//  builtin_commands.h
+//  sec
+//
+//  Created by Mitch Adler on 1/9/13.
+//
+//
+
+#include "SecurityTool/security_tool_commands.h"
+
+SECURITY_COMMAND("help", help,
+                 "[command ...]",
+                 "Show all commands. Or show usage for a command.")
+
+SECURITY_COMMAND("digest", command_digest,
+                 "algo file(s)...\n"
+                 "Where algo is one of:\n"
+                 "    sha1\n"
+                 "    sha256\n"
+                 "    sha512\n",
+                 "Calculate a digest over the given file(s).")
diff --git a/sec/SecurityTool/digest_calc.c b/sec/SecurityTool/digest_calc.c
new file mode 100644 (file)
index 0000000..85710a3
--- /dev/null
@@ -0,0 +1,78 @@
+//
+//  digest_calc.c
+//  Digest calculation command for SecurityTool
+//
+//  Created by John Kelley on 4/27/11.
+//  Copyright 2011 Apple, Inc. All rights reserved.
+//
+
+#include "builtin_commands.h"
+
+#include <stdlib.h>
+#include <strings.h>
+
+#include <SecurityTool/readline.h>
+
+#include <corecrypto/ccsha1.h>
+#include <corecrypto/ccsha2.h>
+
+extern int command_digest(int argc, char * const *argv)
+{
+    int result = 1;
+    uint8_t *data = NULL;
+    size_t data_len;
+    const struct ccdigest_info *di;
+    unsigned char *digest = NULL;
+    unsigned long i,j;
+    
+    if (argc < 3)
+        return 2; /* Return 2 triggers usage message. */
+    
+    if (strcasecmp("sha1", argv[1]) == 0)
+    {
+        //printf("Calculating sha1\n");
+        di = ccsha1_di();        
+    }
+    else if (strcasecmp("sha256", argv[1]) == 0)
+    {
+        //printf("Calculating sha256\n");
+        di = ccsha256_di();
+    }
+    else if (strcasecmp("sha512", argv[1]) == 0)
+    {
+        //printf("Calculating sha256\n");
+        di = ccsha512_di();
+    }
+    else
+        return 2; /* Return 2 triggers usage message. */
+    
+    digest = malloc(di->output_size);
+    if (!digest)
+        goto exit;
+    
+    for (i = 2; i < (unsigned int)argc; ++i)
+    {
+        printf("%s(%s)= ", argv[1], argv[i]);
+        if (read_file( argv[i], &data, &data_len) != 0 || !data)
+        {
+            printf("error reading file\n");
+            continue;
+        }
+        ccdigest(di, data_len, data, digest);
+    
+        for (j = 0; j < di->output_size; j++)
+            printf("%02x", digest[j]);
+        printf("\n");
+        free(data);
+        data = NULL;
+    }
+    result = 0;
+    
+exit:
+    if(data)
+        free(data);
+    if (digest)
+        free(digest);
+    
+    return result;
+}
diff --git a/sec/SecurityTool/entitlements.plist b/sec/SecurityTool/entitlements.plist
new file mode 100644 (file)
index 0000000..a24c700
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>keychain-cloud-circle</key>
+       <true/>
+       <key>keychain-access-groups</key>
+       <array>
+               <string>test</string>
+               <string>*</string>
+       </array>
+       <key>modify-anchor-certificates</key>
+       <true/>
+       <key>application-identifier</key>
+       <string>com.apple.security</string>
+</dict>
+</plist>
diff --git a/sec/SecurityTool/leaks.c b/sec/SecurityTool/leaks.c
new file mode 100644 (file)
index 0000000..957ce9d
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2003-2004,2006-2007 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ *
+ * leaks.c
+ */
+
+#include "leaks.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+int
+leaks(int argc, char *const *argv)
+{
+       int result = 1;
+       pid_t child;
+       pid_t parent = getpid();
+
+       child = fork();
+       switch (child)
+       {
+       case -1:
+               /* Fork failed we're hosed. */
+               fprintf(stderr, "fork: %s", strerror(errno));
+               break;
+       case 0:
+       {
+               /* child. */
+               char **argvec = (char **)malloc((argc + 2) * sizeof(char *));
+               char pidstr[8];
+               int ix;
+       
+               sprintf(pidstr, "%d", parent);
+               argvec[0] = "/usr/bin/leaks";
+               for (ix = 1; ix < argc; ++ix)
+                       argvec[ix] = argv[ix];
+               argvec[ix] = pidstr;
+               argvec[ix + 1] = NULL;
+
+               execv(argvec[0], argvec);
+               fprintf(stderr, "exec: %s", strerror(errno));
+               _exit(1);
+               break;
+       }
+       default:
+       {
+               /* Parent. */
+               int status = 0;
+               for (;;)
+               {
+                       /* Wait for the child to exit. */
+                       pid_t waited_pid = waitpid(child, &status, 0);
+                       if (waited_pid == -1)
+                       {
+                               int error = errno;
+                               /* Keep going if we get interupted but bail out on any
+                                  other error. */
+                               if (error == EINTR)
+                                       continue;
+
+                               fprintf(stderr, "waitpid %d: %s", status, strerror(errno));
+                               break;
+                       }
+
+                       if (WIFEXITED(status))
+                       {
+                               if (WEXITSTATUS(status))
+                               {
+                                       /* Force usage message. */
+                                       result = 2;
+                                       fprintf(stderr, "leaks exited: %d", result);
+                               }
+                               break;
+                       }
+                       else if (WIFSIGNALED(status))
+                       {
+                               fprintf(stderr, "leaks terminated by signal: %d", WTERMSIG(status));
+                               break;
+                       }
+               }
+               break;
+       }
+       }
+
+       return result;
+}
diff --git a/sec/SecurityTool/leaks.h b/sec/SecurityTool/leaks.h
new file mode 100644 (file)
index 0000000..df6ac71
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2003-2004,2006-2007 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ *
+ * leaks.h
+ */
+
+#ifndef _LEAKS_H_
+#define _LEAKS_H_
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+int leaks(int argc, char *const *argv);
+
+__END_DECLS
+
+#endif /*  _LEAKS_H_ */
diff --git a/sec/SecurityTool/print_cert.c b/sec/SecurityTool/print_cert.c
new file mode 100644 (file)
index 0000000..7741a0a
--- /dev/null
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2003-2008,2011 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ *
+ *  print_cert.c
+ *
+ *  Created by Michael Brouwer on 10/10/06.
+ */
+
+
+#include "print_cert.h"
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecTrustPriv.h>
+#include <utilities/SecIOFormat.h>
+#include <utilities/SecCFWrappers.h>
+
+
+static void printPlist(CFArrayRef plist, CFIndex indent, CFIndex maxWidth) {
+    CFIndex count = CFArrayGetCount(plist);
+    CFIndex ix;
+    for (ix = 0; ix < count ; ++ix) {
+        CFDictionaryRef prop = (CFDictionaryRef)CFArrayGetValueAtIndex(plist,
+            ix);
+        CFStringRef pType = (CFStringRef)CFDictionaryGetValue(prop,
+            kSecPropertyKeyType);
+        CFStringRef label = (CFStringRef)CFDictionaryGetValue(prop,
+            kSecPropertyKeyLabel);
+        CFStringRef llabel = (CFStringRef)CFDictionaryGetValue(prop,
+            kSecPropertyKeyLocalizedLabel);
+        CFTypeRef value = (CFTypeRef)CFDictionaryGetValue(prop,
+            kSecPropertyKeyValue);
+
+        bool isSection = CFEqual(pType, kSecPropertyTypeSection);
+        CFMutableStringRef line = CFStringCreateMutable(NULL, 0);
+        CFIndex jx = 0;
+        for (jx = 0; jx < indent; ++jx) {
+            CFStringAppend(line, CFSTR("    "));
+        }
+        if (llabel) {
+            CFStringAppend(line, llabel);
+            if (!isSection) {
+                for (jx = CFStringGetLength(llabel) + indent * 4;
+                    jx < maxWidth; ++jx) {
+                    CFStringAppend(line, CFSTR(" "));
+                }
+                CFStringAppend(line, CFSTR(" : "));
+            }
+        }
+        if (CFEqual(pType, kSecPropertyTypeWarning)) {
+            CFStringAppend(line, CFSTR("*WARNING* "));
+            CFStringAppend(line, (CFStringRef)value);
+        } else if (CFEqual(pType, kSecPropertyTypeError)) {
+            CFStringAppend(line, CFSTR("*ERROR* "));
+            CFStringAppend(line, (CFStringRef)value);
+        } else if (CFEqual(pType, kSecPropertyTypeSuccess)) {
+            CFStringAppend(line, CFSTR("*OK* "));
+            CFStringAppend(line, (CFStringRef)value);
+        } else if (CFEqual(pType, kSecPropertyTypeTitle)) {
+            CFStringAppend(line, CFSTR("*"));
+            CFStringAppend(line, (CFStringRef)value);
+            CFStringAppend(line, CFSTR("*"));
+        } else if (CFEqual(pType, kSecPropertyTypeSection)) {
+        } else if (CFEqual(pType, kSecPropertyTypeData)) {
+            CFDataRef data = (CFDataRef)value;
+            CFIndex length = CFDataGetLength(data);
+            if (length > 20)
+                CFStringAppendFormat(line, NULL, CFSTR("[%" PRIdCFIndex " bytes] "), length);
+            const UInt8 *bytes = CFDataGetBytePtr(data);
+            for (jx = 0; jx < length; ++jx) {
+                if (jx == 0)
+                    CFStringAppendFormat(line, NULL, CFSTR("%02X"), bytes[jx]);
+                else if (jx < 15 || length <= 20)
+                    CFStringAppendFormat(line, NULL, CFSTR(" %02X"),
+                        bytes[jx]);
+                else {
+                    CFStringAppend(line, CFSTR(" ..."));
+                    break;
+                }
+            }
+        } else if (CFEqual(pType, kSecPropertyTypeString)) {
+            CFStringAppend(line, (CFStringRef)value);
+        } else if (CFEqual(pType, kSecPropertyTypeDate)) {
+            CFDateRef date = (CFDateRef)value;
+            CFLocaleRef lc = CFLocaleCopyCurrent();
+            CFDateFormatterRef df = CFDateFormatterCreate(NULL, lc, kCFDateFormatterMediumStyle, kCFDateFormatterLongStyle);
+            CFStringRef ds;
+            if (df) {
+                CFTimeZoneRef tz = CFTimeZoneCreateWithTimeIntervalFromGMT(NULL, 0.0);
+                CFDateFormatterSetProperty(df, kCFDateFormatterTimeZone, tz);
+                CFRelease(tz);
+                ds = CFDateFormatterCreateStringWithDate(NULL, df, date);
+                CFRelease(df);
+            } else {
+                ds = CFStringCreateWithFormat(NULL, NULL, CFSTR("%g"), CFDateGetAbsoluteTime(date));
+            }
+            CFStringAppend(line, ds);
+            CFRelease(ds);
+            CFRelease(lc);
+        } else if (CFEqual(pType, kSecPropertyTypeURL)) {
+            CFURLRef url = (CFURLRef)value;
+            CFStringAppend(line, CFSTR("<"));
+            CFStringAppend(line, CFURLGetString(url));
+            CFStringAppend(line, CFSTR(">"));
+        } else {
+            CFStringAppendFormat(line, NULL, CFSTR("*unknown type %@* = %@"),
+            pType, value);
+        }
+
+               if (!isSection || label)
+                       CFStringWriteToFileWithNewline(line, stdout);
+               CFRelease(line);
+        if (isSection) {
+            printPlist((CFArrayRef)value, indent + 1, maxWidth);
+        }
+    }
+}
+
+static CFIndex maxLabelWidth(CFArrayRef plist, CFIndex indent) {
+    CFIndex count = CFArrayGetCount(plist);
+    CFIndex ix;
+    CFIndex maxWidth = 0;
+    for (ix = 0; ix < count ; ++ix) {
+        CFDictionaryRef prop = (CFDictionaryRef)CFArrayGetValueAtIndex(plist,
+            ix);
+        CFStringRef pType = (CFStringRef)CFDictionaryGetValue(prop,
+            kSecPropertyKeyType);
+        CFStringRef llabel = (CFStringRef)CFDictionaryGetValue(prop,
+            kSecPropertyKeyLocalizedLabel);
+        CFTypeRef value = (CFTypeRef)CFDictionaryGetValue(prop,
+            kSecPropertyKeyValue);
+
+        if (CFEqual(pType, kSecPropertyTypeSection)) {
+            CFIndex width = maxLabelWidth((CFArrayRef)value, indent + 1);
+            if (width > maxWidth)
+                maxWidth = width;
+        } else if (llabel) {
+            CFIndex width = indent * 4 + CFStringGetLength(llabel);
+            if (width > maxWidth)
+                maxWidth = width;
+        }
+    }
+
+    return maxWidth;
+}
+
+void print_plist(CFArrayRef plist) {
+    if (plist)
+        printPlist(plist, 0, maxLabelWidth(plist, 0));
+    else
+        printf("NULL plist\n");
+}
+
+void print_cert(SecCertificateRef cert, bool verbose) {
+    CFArrayRef plist;
+    if (verbose)
+        plist = SecCertificateCopyProperties(cert);
+    else {
+        CFAbsoluteTime now = CFAbsoluteTimeGetCurrent();
+        plist = SecCertificateCopySummaryProperties(cert, now);
+    }
+
+    CFStringRef subject = SecCertificateCopySubjectString(cert);
+    if (subject) {
+        CFStringWriteToFileWithNewline(subject, stdout);
+        CFRelease(subject);
+    } else {
+        CFStringWriteToFileWithNewline(CFSTR("no subject"), stdout);
+    }
+
+    print_plist(plist);
+    CFRelease(plist);
+}
diff --git a/sec/SecurityTool/print_cert.h b/sec/SecurityTool/print_cert.h
new file mode 100644 (file)
index 0000000..2785c00
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2003-2007 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ *
+ *  print_cert.h
+ *
+ *  Created by Michael Brouwer on 10/10/06.
+ */
+
+#ifndef _PRINT_CERT_H_
+#define _PRINT_CERT_H_
+
+#include <sys/cdefs.h>
+#include <stdio.h>
+#include <Security/SecCertificate.h>
+#include <CoreFoundation/CFArray.h>
+
+__BEGIN_DECLS
+
+void print_plist(CFArrayRef plist);
+void print_cert(SecCertificateRef cert, bool verbose);
+
+__END_DECLS
+
+#endif /* _PRINT_CERT_H_ */
diff --git a/sec/SecurityTool/security.1 b/sec/SecurityTool/security.1
new file mode 100644 (file)
index 0000000..dba4ac9
--- /dev/null
@@ -0,0 +1,595 @@
+.\"Modified from man(1) of FreeBSD, the NetBSD mdoc.template, and mdoc.samples.
+.\"See Also:
+.\"man mdoc.samples for a complete listing of options
+.\"man mdoc for the short list of editing options
+.Dd Tue May 06 2003               \" DATE 
+.Dt security 1      \" Program name and manual section number 
+.Os Darwin
+.Sh NAME                 \" Section Header - required - don't modify 
+.Nm security
+.\" The following lines are read in generating the apropos(man -k) database. Use only key
+.\" words here as the database is built based on the words here and in the .ND line. 
+.\" Use .Nm macro to designate other names for the documented program.
+.Nd Command line interface to keychains and Security.framework
+.Sh SYNOPSIS             \" Section Header - required - don't modify
+.Nm
+.Op Fl hilqv             \" [-hilqv]
+.Op Fl p Ar prompt       \" [-p prompt] 
+.Op Ar command           \" [command]
+.Op Ar command_options   \" [command_options]
+.Op Ar command_args      \" [command_args]
+.Sh DESCRIPTION          \" Section Header - required - don't modify
+A simple command line interface which lets you administer Keychains,
+manipulate keys and certificates, and do just about anything the
+Security framework is capable of from the command line.  New commands
+are constantly being added over time.
+.Pp
+By default
+.Nm
+will execute the
+.Ar command
+supplied and report if anything went wrong.
+.Pp
+If the
+.Fl i
+or
+.Fl p
+options are provided,
+.Nm
+will enter interactive mode and allow the user to enter multiple commands on stdin.  When EOF is read from stdin
+.Nm
+will exit.
+.Pp
+Here is a complete list of the options available:
+.Bl -tag -width -indent
+.It Fl h
+If no arguments are specified show a list of all commands.  If arguments are provided show usage for each the specified commands.  This options is basically the same as the
+.Nm help
+command.
+.It Fl i
+Run
+.Nm
+in interactive mode.  A prompt 
+.Po
+.Li security>
+by default
+.Pc
+will be displayed and the user will be able to type commands on stdin until an EOF is encountered.
+.It Fl l
+Before
+.Nm
+exits run
+.Dl "/usr/bin/leaks -nocontext"
+on itself to see if the command(s) you executed leaks.
+.It Fl p Ar prompt
+This option implies the
+.Fl i
+option but changes the default prompt to the argument specified instead.
+.It Fl q
+Will make
+.Nm
+less verbose.
+.It Fl v
+Will make
+.Nm
+more verbose.
+.El                      \" Ends the list
+.Pp
+.Sh "SECURITY COMMAND SUMMARY"
+.Nm
+provides a rich variety of commands
+.Po Ar command
+in the
+.Sx SYNOPSIS Pc Ns
+, each of which often has a wealth of options, to allow access to
+the broad functionality provided by the Security framework.  However,
+you don't have to master every detail for
+.Nm
+to be useful to you.
+.Pp
+Here are brief descriptions of all the
+.Nm
+commands:
+.Pp
+.Bl -tag -width find-internet-password -compact
+.It Nm help
+Show all commands. Or show usage for a command.
+.It Nm list-keychains
+Display or manipulate the keychain search list.
+.It Nm default-keychain
+Display or set the default keychain.
+.It Nm login-keychain
+Display or set the login keychain.
+.It Nm create-keychain
+Create keychains and add them to the search list.
+.It Nm delete-keychain
+Delete keychains and remove them from the search list.
+.It Nm lock-keychain
+Lock the specified keychain.
+.It Nm unlock-keychain
+Unlock the specified keychain.
+.It Nm set-keychain-settings
+Set Nm settings for a keychain.
+.It Nm show-keychain-info
+Show the settings for keychain.
+.It Nm dump-keychain
+Dump the contents of one or more keychains.
+.It Nm create-keypair
+Create an assymetric keypair.
+.It Nm add-internet-password
+Add an internet password item.
+.It Nm add-certificates
+Add certificates to a keychain.
+.It Nm find-internet-password
+Find an internet password item.
+.It Nm find-certificate
+Find a certificate item.
+.It Nm create-db
+Create an db using the DL.
+.It Nm import
+Import item(s) into a keychain.
+.It Nm export
+Export item(s) from a keychain.
+.It Nm install-mds
+Install (or re-install) the MDS database.
+.It Nm leaks
+Run
+.Pa /usr/bin/leaks
+on this proccess.
+.El
+.Sh "COMMON COMMAND OPTIONS"
+This section describes the
+.Ar command_options
+that are available across all
+.Nm
+commands.
+.Bl -tag -width -indent
+.It Fl h
+Show a usage message for the specified command.  This option is
+basically the same as the
+.Ar help
+command.
+.El
+.Sh "SECURITY COMMANDS"
+Here (finally) are details on all the
+.Nm
+commands and the options each accepts.
+.Bl -item
+.It
+.Nm help
+.Op Fl h
+.Bl -item -offset -indent
+Show all commands. Or show usage for a command.
+.El
+.It
+.Nm list-keychains
+.Op Fl h
+.Op Fl d Ar user Ns | Ns Ar system Ns | Ns Ar common
+.Op Fl s Op Ar keychain...
+.Bl -item -offset -indent
+Display or set the keychain search list.
+.It
+Options:
+.Bl -tag -compact -width -indent
+.It Fl d Ar user Ns | Ns Ar system Ns | Ns Ar common
+Specify the preferences domain to be used.
+.It Fl s
+Set the search list to the specified keychains
+.El
+.El
+.It
+.Nm default-keychain
+.Op Fl h
+.Op Fl d Ar user Ns | Ns Ar system Ns | Ns Ar common
+.Op Fl s Op Ar keychain
+.Bl -item -offset -indent
+Display or set the default keychain.
+.It
+Options:
+.Bl -tag -compact -width -indent
+.It Fl d Ar user Ns | Ns Ar system Ns | Ns Ar common
+Specify the preferences domain to be used.
+.It Fl s
+Set the default keychain to the specified
+.Ar keychain Ns .
+Unset it if no keychain is specified.
+.El
+.El
+.It
+.Nm login-keychain
+.Op Fl h
+.Op Fl d Ar user Ns | Ns Ar system Ns | Ns Ar common
+.Op Fl s Op Ar keychain
+.Bl -item -offset -indent
+Display or set the login keychain.
+.It
+Options:
+.Bl -tag -compact -width -indent
+.It Fl d Ar user Ns | Ns Ar system Ns | Ns Ar common
+Specify the preferences domain to be used.
+.It Fl s
+Set the login keychain to the specified
+.Ar keychain Ns .
+Unset it if no keychain is specified.
+.El
+.El
+.It
+.Nm create-keychain
+.Op Fl hP
+.Op Fl p Ar password
+.Op Ar keychain...
+.Bl -item -offset -indent
+Create keychains and add them to the search list.  if no keychains are specified the user is prompted for one.
+.It  
+Options:
+.Bl -tag -compact -width -indent-indent
+.It Fl P
+Prompt the user for a password using the SecurityAgent.
+.It Fl p Ar password
+Use
+.Ar password
+as the password for the keychains being created.
+.El
+.It
+If neither
+.Fl P
+or
+.Fl p Ar password
+are specified the user is prompted for a password.
+.El
+.It
+.Nm delete-keychain
+.Op Fl h
+.Op Ar keychain...
+.Bl -item -offset -indent
+Delete keychains and remove them from the search list.
+.El
+.It
+.Nm lock-keychain
+.Op Fl h
+.Op Fl a Ns | Ns Ar keychain
+.Bl -item -offset -indent
+Lock
+.Ar keychain Ns
+\&. Or the default is none is specified.  If the
+.Fl a
+options is specified all keychains are locked.
+.El
+.It
+.Nm unlock-keychain
+.Op Fl hu
+.Op Fl p Ar password
+.Op Ar keychain
+.Bl -item -offset -indent
+Unlock
+.Ar keychain Ns
+\&. Or the default is none is specified.
+.El
+.It
+.Nm set-keychain-settings
+.Op Fl hlu
+.Op Fl t Ar timeout
+.Op Ar keychain
+.Bl -item -offset -indent
+Set settings for
+.Ar keychain Ns
+\&. Or the default is none is specified.
+.Bl -tag -compact -width -indent-indent
+.It Fl l 
+Lock keychain when the system sleeps
+.It Fl u 
+Lock keychain after certain period of time specified using
+.Fl t Ns
+\&.
+.It Fl t Ar timeout
+Automatically lock keychain after
+.Ar timeout
+seconds of inactivity.
+.El
+.El
+.It
+.Nm show-keychain-info
+.Op Fl h
+.Bl -item -offset -indent
+Show the settings for keychain.
+.El
+.It
+.Nm dump-keychain
+.Op Fl adhir
+.Bl -item -offset -indent
+Dump the contents of one or more keychains.
+.Bl -tag -compact -width -indent-indent
+.It Fl a
+Dump acl of items.
+.It Fl d
+Dump cleartext data of items.
+.It Fl i
+Interactive acl editing mode.
+.It Fl r
+Dump raw (possibly ciphertext) data of items.
+.El
+.El
+.It
+.Nm create-keypair
+.Op Fl h
+.Op Fl a Ar alg
+.Op Fl s Ar size
+.Op Fl f Ar from_date
+.Op Fl t Ar to_date
+.Op Fl v Ar days
+.Op Fl k Ar keychain
+.Op Fl n Ar name
+.Op Fl A Ns | Ns Fl T Ar app1:app2:...
+.Bl -item -offset -indent
+Create an assymetric keypair.
+.El
+.It
+.Nm add-internet-password
+.Op Fl h
+.Op Fl a Ar account_name
+.Op Fl d Ar security_domain
+.Op Fl p Ar path
+.Op Fl P Ar port
+.Op Fl r Ar protocol
+.Op Fl s Ar server_name
+.Op Fl t Ar authentication_type
+.Op Fl w Ar password_data
+.Op Ar keychain
+.Bl -item -offset -indent
+Add an internet password item.
+.El
+.It
+.Nm add-certificates
+.Op Fl h
+.Op Fl k Ar keychain
+.Ar file...
+.Bl -item -offset -indent
+Add certficates contained in the specified
+.Ar files
+to the default keychain.  The files must contain one DER encoded X509 certificate each.
+.Bl -tag -compact -width -indent-indent
+.It Fl k Ar keychain
+Use
+.Ar keychain
+rather than the default keychain.
+.El
+.El
+.It
+.Nm find-internet-password
+.Op Fl gh
+.Op Fl a Ar account_name
+.Op Fl d Ar security_domain
+.Op Fl p Ar path
+.Op Fl P Ar port
+.Op Fl r Ar protocol
+.Op Fl s Ar server_name
+.Op Fl t Ar authentication_type
+.Op Ar keychain...
+.Bl -item -offset -indent
+Find an internet password item.
+.El
+.It
+.Nm find-certificate
+.Op Fl ahmp
+.Op Fl e Ar email_address
+.Op Ar keychain...
+.Bl -item -offset -indent
+Find a certificate item.  If no
+.Ar keychain
+arguments are provided,
+.Nm
+will search the default search list.
+.It
+Options:
+.Bl -tag -compact -width -indent-indent
+.It Fl a
+Find all matching certificates, not just the first one.
+.It Fl g Ar dl Ns | Ns Ar cspdl
+Use the AppleDL (default) or AppleCspDL
+.It Fl e Ar email_address
+Match on "email_address" when searching.
+.It Fl m
+Show the email addresses in the certificate.
+.It Fl p
+Output certificate in pem form.  The default is to dump the attributes and keychain the cert is in.
+.El
+.It
+.Sy Examples
+.Bl -tag -width -indent
+.Dl security> find-certificate -a -p > allcerts.pem
+Exports all certificates from all keychains into a pem file called allcerts.pem.
+.Dl security> find-certificate -a -e me@foo.com -p > certs.pem
+Exports all certificates from all keychains with the email address
+mb@foo.com into a pem file called certs.pem.
+.El
+.El
+.It
+.Nm create-db
+.Op Fl aho0
+.Op Fl g Ar dl Ns | Ns Ar cspdl
+.Op Fl m Ar mode
+.Op Ar name
+.Bl -item -offset -indent
+Create an db using the DL.  If
+.Ar name
+isn't provided
+.Nm
+will prompt the user to type a name.
+.It
+Options:
+.Bl -tag -compact -width -indent-indent
+.It Fl a
+Turn off autocommit
+.It Fl g Ar dl Ns | Ns Ar cspdl
+Use the AppleDL (default) or AppleCspDL
+.It Fl m Ar mode
+Set the file permissions to
+.Ar mode Ns
+\&.
+.It Fl o
+Force using openparams argument
+.It Fl 0
+Force using version 0 openparams
+.El
+.It
+.Sy Examples
+.Bl -tag -width -indent
+.Dl security> create-db -m 0644 test.db
+.Dl security> create-db -g cspdl -a test2.db
+.El
+.\"new import/export commands.
+.El
+.It
+.Nm export
+.Op Fl k Ar keychain
+.Op Fl t Ar item_type
+.Op Fl f Ar item_format
+.Op Fl w
+.Op Fl p Ar item_format
+.Op Fl P Ar passphrase
+.Op Fl o Ar outfile
+.Bl -item -offset -indent
+Export one or more items from a keychain to one of a number of external representations.  If
+.Ar keychain
+isn't provided, items will be exported from the user's default keychain.
+.It
+Options:
+.Bl -tag -compact -width -indent-indent
+.It Fl k Ar keychain
+Specify keychain from which item(s) will be exported. 
+.It Fl t Ar item_type
+Specify the type of items to export. Possible types are certs, allKeys, pubKeys, privKeys, identities, and all. The default is all. An identity consists of both a certificate and the corresponding provate key. 
+.It Fl f Ar item_format
+Specify the format of the exported data. Possible formats are openssl, bsafe, pkcs7, pkcs8, pkcs12, x509, and pemseq. The default is pemseq if more than one item is being exported. The default is openssl if one key is being exported. The default is x509 if one certificate is being exported.
+.It Fl w
+Specifies that private keys are to be wrapped on export. 
+.It Fl p 
+Specifies that PEM armour is to be applied to the output data.
+.It Fl P Ar passphrase
+Specify the wrapping passphrase immediately. The default is to obtain a secure passphrase via GUI.
+.It Fl o Ar outfile
+Write the output data to 
+.Ar outfile Ns
+\&. Default is to write data to stdout. 
+.El
+.It
+.Sy Examples
+.Bl -tag -width -indent
+.Dl security> export -k login.keychain -t certs -o /tmp/certs.pem
+.Dl security> export -k newcert.keychain -t identities -f pkcs12 -o /tmp/mycerts.p12
+.El
+.\"marker.
+.El
+.It
+.Nm import
+inputfile
+.Op Fl k Ar keychain
+.Op Fl t Ar item_type
+.Op Fl f Ar item_format
+.Op Fl w
+.Op Fl P Ar passphrase
+.Bl -item -offset -indent
+Import one or more items from 
+.Ar inputfile Ns
+\& into a keychain. If
+.Ar keychain
+isn't provided, items will be imported into the user's default keychain.
+.It
+Options:
+.Bl -tag -compact -width -indent-indent
+.It Fl k Ar keychain
+Specify keychain into which item(s) will be imported. 
+.It Fl t Ar item_type
+Specify the type of items to import. Possible types are cert, pub, priv, session, cert, and agg. Pub, priv, and session refer to keys; agg is one of the aggregate types (pkcs12 and PEM sequence). The command can often figure out what item_type an item contains based in the filename and/or item_format.
+.It Fl f Ar item_format
+Specify the format of the exported data. Possible formats are openssl, bsafe, raw, pkcs7, pkcs8, pkcs12, x509, and pemseq. The command can often figure out what format an item is in based in the filename and/or item_type. 
+.It Fl w
+Specifies that private keys are wrapped and must be unwrapped on import. 
+.It Fl P Ar passphrase
+Specify the unwrapping passphrase immediately. The default is to obtain a secure passphrase via GUI.
+.El
+.It
+.Sy Examples
+.Bl -tag -width -indent
+.Dl security> import /tmp/certs.pem -k 
+.Dl security> import /tmp/mycerts.p12 -t agg -k newcert.keychain
+.Dl security> import /tmp/mycerts.p12 -f pkcs12 -k newcert.keychain
+.El
+.\"end of new import/export commands.
+.It
+.Nm install-mds
+.Bl -item -offset -indent
+Install (or re-install) the Module Directory Services (MDS) database. This is a system tool which is not normally used by users. There are no options. 
+.El
+.It
+.Nm leaks
+.Op Fl h
+.Op Fl cycles
+.Op Fl nocontext
+.Op Fl nostacks
+.Op Fl exclude Ar symbol
+.Bl -item -offset -indent
+Run
+.Li /usr/bin/leaks
+on this proccess.  This is to help find memory leaks after running
+certain commands.
+.It
+Options:
+.Bl -tag -compact -width -indent-indent
+.It Fl cycles
+Use a stricter algorithm (See
+.Xr leaks 1
+for details).
+.It Fl nocontext
+Withhold the hex dumps of the leaked memory.
+.It Fl nostacks
+Don't show stack traces of leaked memory.
+.It Fl exclude Ar symbol
+Ignore leaks called from
+.Ar symbol Ns .
+.El
+.El
+.El
+.El
+.Sh ENVIRONMENT      \" May not be needed
+.Bl -tag -width -indent
+.It Ev MallocStackLogging
+When using the
+.Nm leaks
+command or the
+.Fl l
+option it's probably a good idea to set this environment variable before
+.Nm
+is started.  Doing so will allow leaks to display symbolic backtraces.
+.El                      
+.Sh FILES
+.Bl -tag -width -indent
+.It Pa ~/Library/Preferences/com.apple.security.plist
+.Pp
+Propertylist file containing the current users default keychain and keychain search list.
+.It Pa /Library/Preferences/com.apple.security.plist
+.Pp
+Propertylist file containing the system default keychain and keychain search list.  This is used by processes started at boottime, or those requesting to use the system search domain, such as system daemons.
+.It Pa /Library/Preferences/com.apple.security-common.plist
+.Pp
+Propertylist file containing the a common keychain search list which is appended to every users searchlist and to the system search list as well.
+.El
+.Sh SEE ALSO 
+.\" List links in ascending order by section, alphabetically within a section.
+.\" Please do not reference files that do not exist without filing a bug report
+.Xr certtool 1 ,
+.Xr leaks 1
+.\" .Xr systemkeychain 8 
+.Sh HISTORY
+.Nm
+was first introduced in Mac OS X version 10.3
+.Sh AUTHORS
+.An "Michael Brouwer"
+.Sh BUGS
+.Nm
+still needs a lot more commands before it can be considered complete.
+In particular it should someday supersede both the
+.Li certtool
+and
+.Li systemkeychain
+commands.
diff --git a/sec/SecurityTool/tool_errors.h b/sec/SecurityTool/tool_errors.h
new file mode 100644 (file)
index 0000000..7b6ee3c
--- /dev/null
@@ -0,0 +1,60 @@
+//
+//  tool_errors.h
+//  sec
+//
+//  Created by Mitch Adler on 1/9/13.
+//
+//
+
+//
+// These functions should be deprectaed!
+// Try to find a better way instead of using them.
+//
+
+#ifndef _TOOL_ERRORS_H_
+#define _TOOL_ERRORS_H_
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "SecurityTool/SecurityTool.h"
+
+static inline const char *
+sec_errstr(int err)
+{
+    const char *errString;
+    static char buffer[12];
+    
+    sprintf(buffer, "%d", err);
+    errString = buffer;
+#if 0
+    if (IS_SEC_ERROR(err))
+        errString = SECErrorString(err);
+    else
+        errString = cssmErrorString(err);
+#endif
+    return errString;
+}
+
+static inline void
+sec_error(const char *msg, ...)
+{
+    va_list args;
+    
+    fprintf(stderr, "%s: ", prog_name);
+    
+    va_start(args, msg);
+    vfprintf(stderr, msg, args);
+    va_end(args);
+    
+    fprintf(stderr, "\n");
+}
+
+static inline void
+sec_perror(const char *msg, int err)
+{
+    sec_error("%s: %s", msg, sec_errstr(err));
+}
+
+
+
+#endif
index 1e170bffe7fdbe1d3c9f99c1f308413477365c3e..7e8251af611d9bc89703c29a435f7b5a11f366d7 100644 (file)
@@ -1,8 +1,47 @@
-CODE_SIGN_IDENTITY = -;
+CODE_SIGN_IDENTITY = -
 GCC_VERSION = com.apple.compilers.llvm.clang.1_0
 DEBUG_INFORMATION_FORMAT = dwarf-with-dsym
 CURRENT_PROJECT_VERSION = $(RC_ProjectSourceVersion)
 GCC_VERSION = com.apple.compilers.llvm.clang.1_0
 DEBUG_INFORMATION_FORMAT = dwarf-with-dsym
 CURRENT_PROJECT_VERSION = $(RC_ProjectSourceVersion)
-VERSIONING_SYSTEM = apple-generic;
-DEAD_CODE_STRIPPING = YES;
+VERSIONING_SYSTEM = apple-generic
+DEAD_CODE_STRIPPING = YES
 
 ARCHS = $(ARCHS_STANDARD_32_64_BIT)
 
 ARCHS = $(ARCHS_STANDARD_32_64_BIT)
+
+GCC_WARN_CHECK_SWITCH_STATEMENTS = YES
+GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO    // should be YES at some point
+CLANG_WARN_EMPTY_BODY = YES
+GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES
+GCC_WARN_SHADOW = NO                        // should be yes
+CLANG_WARN_CONSTANT_CONVERSION = YES
+GCC_WARN_64_TO_32_BIT_CONVERSION = YES
+CLANG_WARN_ENUM_CONVERSION = YES
+CLANG_WARN_INT_CONVERSION = NO// should be yes
+CLANG_WARN_IMPLICIT_SIGN_CONVERSION = NO    // should be yes
+GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES
+GCC_WARN_ABOUT_RETURN_TYPE = YES
+GCC_WARN_MISSING_PARENTHESES = YES
+GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = NO  // should be yes
+GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES
+GCC_WARN_ABOUT_MISSING_NEWLINE = YES
+//WARNING_CFLAGS
+GCC_WARN_ABOUT_POINTER_SIGNEDNESS = YES
+GCC_WARN_SIGN_COMPARE = YES
+CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = NO  // should be yes
+GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES
+GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES
+GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES
+GCC_WARN_UNINITIALIZED_AUTOS = YES
+GCC_WARN_UNKNOWN_PRAGMAS = YES
+GCC_WARN_UNUSED_FUNCTION = YES
+GCC_WARN_UNUSED_LABEL = YES
+GCC_WARN_UNUSED_PARAMETER = NO              // should be yes
+GCC_WARN_UNUSED_VALUE = YES
+GCC_WARN_UNUSED_VARIABLE = YES
+
+// No executables are made in sec, it can't know how
+// Therefore we shouldn't strip anyting
+// if somehow we decide to, the default is debuggable.
+
+COPY_PHASE_STRIP = NO
+STRIP_STYLE = debugging
+STRIP_INSTALLED_PRODUCT = NO
index a5093ac8804b786816baa8424cbd864f36dce7d3..727836ced156b677e23ecfe8ebe5fa3ffbbe8c2a 100644 (file)
@@ -1,3 +1,6 @@
+#include "base.xcconfig"
+
+OTHER_CFLAGS = $(inherited) -Wno-error=#warnings
+GCC_TREAT_WARNINGS_AS_ERRORS = YES
 GCC_OPTIMIZATION_LEVEL = 0
 GCC_OPTIMIZATION_LEVEL = 0
-GCC_PREPROCESSOR_DEFINITIONS = DEBUG=1 NO_SERVER=1 $(inherited)
-COPY_PHASE_STRIP = NO
+GCC_PREPROCESSOR_DEFINITIONS = $(inherited) DEBUG=1 NO_SERVER=1
diff --git a/sec/config/lib-arc-only.xcconfig b/sec/config/lib-arc-only.xcconfig
new file mode 100644 (file)
index 0000000..e7729b0
--- /dev/null
@@ -0,0 +1,9 @@
+#include "lib.xcconfig"
+
+ARCHS[sdk=macosx*] = x86_64
+VALID_ARCHS[sdk=macosx*] = x86_64
+
+// TODO: This horrible hack makes #import <Foundation/Foundation.h> work on osx
+HEADER_SEARCH_PATHS[sdk=macosx*] = $(PROJECT_DIR)/SOSCircle $(PROJECT_DIR)/../utilities $(PROJECT_DIR)/ipc $(PROJECT_DIR)/../libsecurity_asn1 $(PROJECT_DIR)/../regressions $(PROJECT_DIR)/../libsecurity_keychain/libDER  $(BUILT_PRODUCTS_DIR)$(INDIGO_INSTALL_PATH_PREFIX)/usr/local/include $(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Headers
+
+CLANG_ENABLE_OBJC_ARC = YES
index 0749bcd2a442259220970187b82292846d3c1dce..d77f9142d28f1b38979f2f6a35b9590a6d96c22c 100644 (file)
@@ -1,30 +1,32 @@
-#include "base.xcconfig"
-
 PRODUCT_NAME = $(TARGET_NAME)
 EXECUTABLE_PREFIX = 
 
 CODE_SIGN_IDENTITY = 
 
 PRODUCT_NAME = $(TARGET_NAME)
 EXECUTABLE_PREFIX = 
 
 CODE_SIGN_IDENTITY = 
 
-HEADER_SEARCH_PATHS[sdk=macosx*] = $(PROJECT_DIR) $(PROJECT_DIR)/ipc $(PROJECT_DIR)/.. $(PROJECT_DIR)/../libsecurity_keychain/libDER $(PROJECT_DIR)/../libsecurity_asn1 $(BUILT_PRODUCTS_DIR)/usr/local/include $(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Headers $(inherited)
+INDIGO_INSTALL_PATH_PREFIX[sdk=iphonesimulator*] = $(SDKROOT)
+
+HEADER_SEARCH_PATHS = $(inherited) $(PROJECT_DIR) $(PROJECT_DIR)/../utilities $(PROJECT_DIR)/ipc $(PROJECT_DIR)/../sectask $(PROJECT_DIR)/../libsecurity_asn1 $(PROJECT_DIR)/../libsecurity_ssl $(PROJECT_DIR)/../libsecurity_smime $(PROJECT_DIR)/../regressions $(PROJECT_DIR)/SOSCircle $(BUILT_PRODUCTS_DIR)$(INDIGO_INSTALL_PATH_PREFIX)/usr/local/include
+
+HEADER_SEARCH_PATHS[sdk=macosx*] = $(inherited) $(PROJECT_DIR)/../libsecurity_keychain/libDER $(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Headers
+
+HEADER_SEARCH_PATHS[sdk=iphone*] = $(inherited) $(PROJECT_DIR)/../libDER
 
 
-HEADER_SEARCH_PATHS[sdk=iphone*] = $(PROJECT_DIR) $(PROJECT_DIR)/ipc $(PROJECT_DIR)/.. $(PROJECT_DIR)/../libDER $(PROJECT_DIR)/../libsecurity_asn1 $(PROJECT_DIR)/../libsecurity_smime $(BUILT_PRODUCTS_DIR)$(INDIGO_INSTALL_PATH_PREFIX)/usr/local/include $(inherited)
+FRAMEWORK_SEARCH_PATHS[sdk=macosx*] = $(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks
 
 
+COPY_PHASE_STRIP = NO
 SKIP_INSTALL = YES
 SKIP_INSTALL = YES
+COPY_PHASE_STRIP = NO
 
 
-ALWAYS_SEARCH_USER_PATHS = NO
+ALWAYS_SEARCH_USER_PATHS = YES
 
 GCC_C_LANGUAGE_STANDARD = gnu99
 
 
 GCC_C_LANGUAGE_STANDARD = gnu99
 
-WARNING_CFLAGS = -Wmost -Wno-four-char-constants -Wno-unknown-pragmas $(inherited)
+HEADERMAP_INCLUDES_FRAMEWORK_ENTRIES_FOR_ALL_PRODUCT_TYPES = NO
 
 
-GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO
+WARNING_CFLAGS = $(inherited) -Wmost -Wno-four-char-constants -Wno-unknown-pragmas
 
 GCC_SYMBOLS_PRIVATE_EXTERN = NO
 
 GCC_SYMBOLS_PRIVATE_EXTERN = NO
-GCC_WARN_64_TO_32_BIT_CONVERSION = YES
-GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES
-GCC_WARN_ABOUT_RETURN_TYPE = YES
-GCC_WARN_UNUSED_VARIABLE = YES
 
 SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator
 
 
 SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator
 
-GCC_PREPROCESSOR_DEFINITIONS[sdk=iphonesimulator*] = INDIGO=1 $(inherited)
\ No newline at end of file
+GCC_PREPROCESSOR_DEFINITIONS[sdk=iphonesimulator*] = $(inherited) INDIGO=1
index 447dc3bc08a23ced45519ca4623c2b2b7e77c863..00de196e121cc8587bde60e623e625634f10bfd8 100644 (file)
@@ -1,4 +1,4 @@
-GCC_PREPROCESSOR_DEFINITIONS = NDEBUG=1 $(inherited)
-COPY_PHASE_STRIP = YES
+#include "base.xcconfig"
 
 
-GCC_PREPROCESSOR_DEFINITIONS[sdk=iphonesimulator*] = NO_SERVER=1 $(inherited)
\ No newline at end of file
+GCC_PREPROCESSOR_DEFINITIONS = $(inherited) NDEBUG=1
+GCC_PREPROCESSOR_DEFINITIONS[sdk=iphonesimulator*] = $(inherited) NO_SERVER=1
index 241ee0c451406d6d0372ce1c4d43720a11bbaba8..96dafb04bdb71ea2e9c66a4d2928b4135ce397a5 100644 (file)
@@ -1,15 +1,15 @@
 /*
  * Copyright (c) 2007-2009 Apple Inc. All Rights Reserved.
 /*
  * Copyright (c) 2007-2009 Apple Inc. All Rights Reserved.
- * 
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
-#include <mach/mach.h>
-#include <mach/message.h>
-#include <mach/mach_error.h>
-#include <servers/bootstrap.h>
-
-#include <pthread.h>
 #include <stdbool.h>
 #include <sys/queue.h>
 #include <stdbool.h>
 #include <sys/queue.h>
+#include <syslog.h>
 
 #include <CoreFoundation/CoreFoundation.h>
 #include <Security/SecItem.h>
 #include <Security/SecBasePriv.h>
 #include <Security/SecInternal.h>
 
 
 #include <CoreFoundation/CoreFoundation.h>
 #include <Security/SecItem.h>
 #include <Security/SecBasePriv.h>
 #include <Security/SecInternal.h>
 
-#include <security_utilities/debugging.h>
+#include <utilities/debugging.h>
+#include <utilities/SecCFError.h>
+#include <utilities/SecXPCError.h>
+#include <utilities/SecCFWrappers.h>
+#include <utilities/SecDispatchRelease.h>
+#include <utilities/SecDb.h> // TODO Fixme this gets us SecError().
 #include "securityd_client.h"
 #include "securityd_client.h"
-#include "securityd_req.h"
-
-#if NO_SERVER
-#define CHECK_ENTITLEMENTS 0
-#else
-#define CHECK_ENTITLEMENTS 1
-#endif
+#include "SecuritydXPC.h"
 
 struct securityd *gSecurityd;
 
 
 struct securityd *gSecurityd;
 
-/* XXX Not thread safe right now. */
-static CFArrayRef gAccessGroups = NULL;
+//
+// MARK: XPC IPC.
+//
 
 
-CFArrayRef SecAccessGroupsGetCurrent(void) {
-#if !CHECK_ENTITLEMENTS
-    if (!gAccessGroups) {
-        /* Initialize gAccessGroups for tests. */
-        const void *agrps[] = {
-            CFSTR("test"),
-#if 1
-            CFSTR("apple"),
-            CFSTR("lockdown-identities"),
+/* Hardcoded Access Groups for the server itself */
+static CFArrayRef SecServerCopyAccessGroups(void) {
+    return CFArrayCreateForCFTypes(kCFAllocatorDefault,
+#if NO_SERVER
+                                   CFSTR("test"),
+                                   CFSTR("apple"),
+                                   CFSTR("lockdown-identities"),
 #else
 #else
-            CFSTR("*"),
-#endif
-        };
-        gAccessGroups = CFArrayCreate(NULL, agrps,
-            sizeof(agrps) / sizeof(*agrps), &kCFTypeArrayCallBacks);
-    }
+                                   CFSTR("sync"),
 #endif
 #endif
-    return gAccessGroups;
-}
-
-void SecAccessGroupsSetCurrent(CFArrayRef accessGroups) {
-    if (accessGroups)
-        CFRetain(accessGroups);
-    CFReleaseSafe(gAccessGroups);
-    gAccessGroups = accessGroups;
+                                   CFSTR("com.apple.security.sos"),
+                                   NULL);
 }
 
 }
 
-static mach_port_t securityd_port = MACH_PORT_NULL;
-static pthread_once_t init_once = PTHREAD_ONCE_INIT;
-static pthread_key_t port_key;
-
-static CFStringRef kSecRunLoopModeRef = CFSTR("com.apple.securityd.runloop");
-
-struct request {
-    uint32_t seq_no;
-    uint32_t msgid;
-    SLIST_ENTRY(request) next;
-    int32_t rcode;
-    void *data;
-    size_t length;
-    volatile bool done;
-};
-
-typedef struct per_thread {
-    SLIST_HEAD(request_head, request) head;;
-    CFMachPortRef port;
-    uint32_t seq_no;
-    mach_msg_id_t notification; /* XXX for stacked requests, notifications
-                                    need to be matched up with seq_nos such
-                                    that only failed requests error out/retry */
-} *per_thread_t;
-
-
-static void destroy_per_thread(void *ex)
-{
-    per_thread_t pt = (per_thread_t)ex;
-    CFMachPortInvalidate(pt->port);
-    CFRelease(pt->port);
-    free(pt);
+CFArrayRef SecAccessGroupsGetCurrent(void) {
+    static CFArrayRef gSecServerAccessGroups;
+    static dispatch_once_t only_do_this_once;
+    dispatch_once(&only_do_this_once, ^{
+        gSecServerAccessGroups = SecServerCopyAccessGroups();
+        assert(gSecServerAccessGroups);
+    });
+    return gSecServerAccessGroups;
 }
 
 }
 
-static void securityd_port_reset(void) 
-{
-    pthread_once_t temp = PTHREAD_ONCE_INIT;
-    init_once = temp;
-    securityd_port = MACH_PORT_NULL;
+static xpc_connection_t securityd_create_connection(const char *name) {
+    if (!name)
+        name = kSecuritydXPCServiceName;
+    xpc_connection_t connection;
+    connection = xpc_connection_create_mach_service(name, NULL, 0);
+    xpc_connection_set_event_handler(connection, ^(xpc_object_t event) {
+        const char *description = xpc_dictionary_get_string(event, XPC_ERROR_KEY_DESCRIPTION);
+        secnotice("xpc", "got event: %s", description);
+    });
+    xpc_connection_resume(connection);
+    return connection;
 }
 
 }
 
-static void securityd_port_lookup(void) 
-{
-    kern_return_t ret;
-    mach_port_t bootstrap_lookup_port = MACH_PORT_NULL;
-
-    /* bootstrap_port is not initialized on embedded */
-    ret = task_get_bootstrap_port(mach_task_self(), &bootstrap_lookup_port);
-    if (ret != KERN_SUCCESS) {
-        secdebug("client", "task_get_bootstrap_port(): 0x%x: %s\n", ret, mach_error_string(ret));
-    }
-
-    ret = bootstrap_look_up(bootstrap_lookup_port, 
-            SECURITYSERVER_BOOTSTRAP_NAME, 
-            &securityd_port);
-    if (ret != KERN_SUCCESS) {
-        secdebug("client", "bootstrap_look_up(): 0x%x: %s\n", ret, mach_error_string(ret));
-    }
+static xpc_connection_t sSecuritydConnection;
 
 
-    pthread_key_create(&port_key, destroy_per_thread);
-
-    int err = pthread_atfork(NULL, NULL, securityd_port_reset);
-    if (err) {
-        secdebug("client", "pthread_atfork(): %d: %s\n", errno, strerror(errno));
-    }
+static xpc_connection_t securityd_connection(void) {
+    static dispatch_once_t once;
+    dispatch_once(&once, ^{
+        sSecuritydConnection = securityd_create_connection(NULL);
+    });
+    return sSecuritydConnection;
 }
 
 }
 
-union max_msg_size_union {
-    union __RequestUnion__securityd_client_securityd_request_subsystem request;
-};
+// NOTE: This is not thread safe, but this SPI is for testing only.
+void SecServerSetMachServiceName(const char *name) {
+    // Make sure sSecXPCServer.queue exists.
+    securityd_connection();
 
 
-static uint8_t reply_buffer[sizeof(union max_msg_size_union) + MAX_TRAILER_SIZE];
-
-static boolean_t maybe_notification(mach_msg_header_t *request)
-{
-    mach_no_senders_notification_t * notify = (mach_no_senders_notification_t *)request;
-    if ((notify->not_header.msgh_id > MACH_NOTIFY_LAST) ||
-            (notify->not_header.msgh_id < MACH_NOTIFY_FIRST))
-        return false;        /* if this is not a notification message */
-
-    per_thread_t pt = (per_thread_t)pthread_getspecific(port_key);
-    assert(pt);
-    mach_msg_id_t notification_id = notify->not_header.msgh_id;
-
-    switch(notification_id) {
-        case MACH_NOTIFY_SEND_ONCE: 
-            /* our send-once right for a reply died in the hands of another */
-            pt->notification = notification_id;
-            CFRunLoopStop(CFRunLoopGetCurrent());
-            break;
-        default:
-            secdebug("client", "unexpected notification %d", pt->notification);
-            break;
-    }
-    return true;
-}
-
-extern boolean_t securityd_reply_server
-(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP);
-
-static void cfmachport_callback(CFMachPortRef port, void *msg, CFIndex size, void *info)
-{
-    if (!maybe_notification((mach_msg_header_t *)msg))
-        securityd_reply_server(msg, (mach_msg_header_t *)reply_buffer);
+    xpc_connection_t oldConection = sSecuritydConnection;
+    sSecuritydConnection = securityd_create_connection(name);
+    if (oldConection)
+        xpc_release(oldConection);
 }
 
 }
 
-static int32_t send_receive(uint32_t msg_id, const void *data_in, size_t length_in,
-        void **data_out, size_t *length_out)
+xpc_object_t
+securityd_message_with_reply_sync(xpc_object_t message, CFErrorRef *error)
 {
 {
-    pthread_once(&init_once, securityd_port_lookup);
+    xpc_object_t reply = NULL;
+    xpc_connection_t connection = securityd_connection();
 
 
-    CFRunLoopRef rl = CFRunLoopGetCurrent();
-
-    per_thread_t pt = (per_thread_t)pthread_getspecific(port_key);
-    if (!pt) {
-        pt = calloc(1, sizeof(*pt));
-        SLIST_INIT(&pt->head);
-        pt->port = CFMachPortCreate (NULL, cfmachport_callback, NULL, false);
-        CFRunLoopSourceRef source = CFMachPortCreateRunLoopSource(NULL, pt->port, 0/*order*/);
-        CFRunLoopAddSource(rl, source, kSecRunLoopModeRef);
-        CFRelease(source);
-        pthread_setspecific(port_key, pt);
-    }
-
-    struct request req = { pt->seq_no++, msg_id, };
-    SLIST_INSERT_HEAD(&pt->head, &req, next);
-
-    int retries = 1;
-    kern_return_t ret;
-    do {
-        /* 64 bits cast: worst case here is the client send a truncated query, which the server will reject */
-        /* Debug check: The size of the request is of type natural_t.
-            The following is correct as long as natural_t is unsigned int */
-        assert(length_in<=UINT_MAX);
-        ret = securityd_client_request(securityd_port, 
-                CFMachPortGetPort(pt->port), req.seq_no, msg_id, 
-                (void *)data_in, (unsigned int) length_in);
-        secdebug("client", "securityd_client_request %d sent, retry %d, result %d\n", 
-            req.seq_no, retries, ret);
-
-        if (!ret) {
-            pt->notification = 0;
-            while (!pt->notification && !req.done) {
-                CFRunLoopRunInMode(kSecRunLoopModeRef, 10000, true);
-                secdebug("client", "return from runloop, notification %d, request %d %sdone\n",
-                    pt->notification, req.seq_no, !req.done ? "not " : "");
-            }
+    for (int try = 1; try <= 2; ++try) {
+        reply = xpc_connection_send_message_with_reply_sync(connection, message);
+        if (try == 1 && reply == XPC_ERROR_CONNECTION_INTERRUPTED) {
+            xpc_release(reply);
         } else {
         } else {
-            secdebug("client", "failed to send request to securityd (err=%d).", ret);
+            break;
         }
         }
-
-    } while ((ret || pt->notification) && retries--);
-
-    SLIST_REMOVE_HEAD(&pt->head, next);
-
-    struct request *next_head = SLIST_FIRST(&pt->head);
-    if (next_head) {
-        /* stop runloop if "new head" is also already done */
-        if (pt->notification || next_head->done)
-            CFRunLoopStop(rl);
     }
 
     }
 
-    if (req.done) {
-        if (data_out)
-            *data_out = req.data;
-        if (length_out)
-            *length_out = req.length;
-        return req.rcode;
+    if (xpc_get_type(reply) == XPC_TYPE_ERROR) {
+        CFIndex code =  0;
+        if (reply == XPC_ERROR_CONNECTION_INTERRUPTED || reply == XPC_ERROR_CONNECTION_INVALID)
+            code = kSecXPCErrorConnectionFailed;
+        else if (reply == XPC_ERROR_TERMINATION_IMMINENT)
+            code = kSecXPCErrorUnknown;
+        else
+            code = kSecXPCErrorUnknown;
+
+        char *conn_desc = xpc_copy_description(connection);
+        const char *description = xpc_dictionary_get_string(reply, XPC_ERROR_KEY_DESCRIPTION);
+        SecCFCreateErrorWithFormat(code, sSecXPCErrorDomain, NULL, error, NULL, CFSTR("%s: %s"), conn_desc, description);
+        free(conn_desc);
+        xpc_release(reply);
+        reply = NULL;
     }
 
     }
 
-    return errSecNotAvailable;
+    return reply;
 }
 
 }
 
-kern_return_t securityd_server_reply(mach_port_t receiver,
-        uint32_t seq_no, int32_t rcode,
-        uint8_t *msg_data, mach_msg_type_number_t msg_length);
-
-kern_return_t securityd_server_reply(mach_port_t receiver,
-        uint32_t seq_no, int32_t rcode,
-        uint8_t *msg_data, mach_msg_type_number_t msg_length)
+xpc_object_t securityd_create_message(enum SecXPCOperation op, CFErrorRef* error)
 {
 {
-    secdebug("client", "reply from port %d request_id %d data(%d,%p)\n",
-       receiver, seq_no, msg_length, msg_data);
-    per_thread_t pt = (per_thread_t)pthread_getspecific(port_key);
-    assert(pt);
-    struct request *req;
-    SLIST_FOREACH(req, &pt->head, next) {
-        if (req->seq_no == seq_no) {
-            req->rcode = rcode;
-            if (msg_length && msg_data) {
-                req->data = malloc(msg_length);
-                if (req->data) {
-                    req->length = msg_length;
-                    memcpy(req->data, msg_data, msg_length);
-                } else
-                    req->length = 0;
-            }
-            req->done = true;
-            /* if multiple requests were queued during nested invocations 
-               we wait until the last one inserted which is the deepest
-               nested one is done */
-            if (req == SLIST_FIRST(&pt->head))
-                CFRunLoopStop(CFRunLoopGetCurrent());
-            break;
-        }
+    xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
+    if (message) {
+        xpc_dictionary_set_uint64(message, kSecXPCKeyOperation, op);
+    } else {
+        SecCFCreateError(kSecXPCErrorConnectionFailed, sSecXPCErrorDomain,
+                         CFSTR("xpc_dictionary_create returned NULL"), NULL, error);
     }
     }
-    return 0;
+    return message;
 }
 
 }
 
-OSStatus ServerCommandSendReceive(uint32_t id, CFTypeRef in, CFTypeRef *out)
-{
-    CFDataRef data_in = NULL, data_out = NULL;
-    void *bytes_out = NULL; size_t length_out = 0;
+// Return true if there is no error in message, return false and set *error if there is.
+bool securityd_message_no_error(xpc_object_t message, CFErrorRef *error) {
+    xpc_object_t xpc_error = xpc_dictionary_get_value(message, kSecXPCKeyError);
+    if (xpc_error == NULL)
+        return true;
 
 
-    if (in) {
-#ifndef NDEBUG
-        CFDataRef query_debug = CFPropertyListCreateXMLData(kCFAllocatorDefault, in);
-        if (query_debug) {
-            secdebug("client", "securityd query: %.*s\n",
-                CFDataGetLength(query_debug), CFDataGetBytePtr(query_debug));
-            CFReleaseSafe(query_debug);
-        }
-#endif
-        CFErrorRef error = NULL;
-        data_in = CFPropertyListCreateData(kCFAllocatorDefault, in,
-                                           kCFPropertyListBinaryFormat_v1_0,
-                                           0, &error);
-        if (!data_in) {
-            secdebug("client", "failed to encode query: %@", error);
-            CFReleaseSafe(error);
-            return errSecItemIllegalQuery;
-        }
+    if (error) {
+        *error = SecCreateCFErrorWithXPCObject(xpc_error);
     }
     }
+    return false;
+}
 
 
-    OSStatus status = send_receive(id, data_in ? CFDataGetBytePtr(data_in) : NULL, 
-        data_in ? CFDataGetLength(data_in) : 0, &bytes_out, &length_out);
-    if (data_in) CFRelease(data_in);
-
-    if (bytes_out && length_out) {
-        data_out = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, bytes_out, length_out, kCFAllocatorMalloc);
-        if (out)
-            *out = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, data_out, kCFPropertyListImmutable, NULL);
-        CFRelease(data_out);
-    } 
-    else
-        if (!status && out)
-            *out = NULL;
+bool securityd_send_sync_and_do(enum SecXPCOperation op, CFErrorRef *error,
+                                bool (^add_to_message)(xpc_object_t message, CFErrorRef* error),
+                                bool (^handle_response)(xpc_object_t response, CFErrorRef* error)) {
+    xpc_object_t message = securityd_create_message(op, error);
+    bool ok = false;
+    if (message) {
+        if (!add_to_message || add_to_message(message, error)) {
+            xpc_object_t response = securityd_message_with_reply_sync(message, error);
+            if (response) {
+                if (securityd_message_no_error(response, error)) {
+                    ok = (!handle_response || handle_response(response, error));
+                }
+                xpc_release(response);
+            }
+        }
+        xpc_release(message);
+    }
 
 
-    return status;     
+    return ok;
 }
 
 }
 
+
 /* vi:set ts=4 sw=4 et: */
 /* vi:set ts=4 sw=4 et: */
index aff548006ab76462d13a0385e6178d0835e11781..ce7496f859676b6a7f6d4058ccdad7ae61ddb2ba 100644 (file)
@@ -2,12 +2,29 @@
 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 <plist version="1.0">
 <dict>
 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 <plist version="1.0">
 <dict>
+       <key>LimitLoadToSessionType</key>
+       <string>Background</string>
+       <key>POSIXSpawnType</key>
+       <string>Interactive</string>
+       <key>LaunchEvents</key>
+       <dict>
+               <key>com.apple.notifyd.matching</key>
+               <dict>
+                       <key>com.apple.security.cloudkeychainproxy.kvstorechange3</key>
+                       <dict>
+                               <key>Notification</key>
+                               <string>com.apple.security.cloudkeychainproxy.kvstorechange3</string>
+                       </dict>
+               </dict>
+       </dict>
        <key>Label</key>
        <string>com.apple.secd</string>
        <key>MachServices</key>
        <dict>
                <key>com.apple.secd</key>
                <true/>
        <key>Label</key>
        <string>com.apple.secd</string>
        <key>MachServices</key>
        <dict>
                <key>com.apple.secd</key>
                <true/>
+               <key>com.apple.securityd.xpc</key>
+               <true/>
        </dict>
        <key>OnDemand</key>
        <true/>
        </dict>
        <key>OnDemand</key>
        <true/>
        <true/>
        <key>Umask</key>
        <integer>54</integer>
        <true/>
        <key>Umask</key>
        <integer>54</integer>
+       <key>EnvironmentVariables</key>
+       <dict>
+               <key>DEBUGSCOPE</key>
+               <string>none</string>
+               <key>WAIT4DEBUGGER</key>
+               <string>NO</string>
+       </dict>
 </dict>
 </plist>
 </dict>
 </plist>
index 97352c9b49f2e7a7255876fa26dcf38234d17be0..91c21620d14ca9d1d3dd85e3acb8595bc0942453 100644 (file)
@@ -2,6 +2,15 @@
 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 <plist version="1.0">
 <dict>
 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 <plist version="1.0">
 <dict>
+       <key>EnableTransactions</key>
+       <true/>
+       <key>EnvironmentVariables</key>
+       <dict>
+               <key>DEBUGSCOPE</key>
+               <string>none</string>
+               <key>WAIT4DEBUGGER</key>
+               <string>NO</string>
+       </dict>
        <key>GroupName</key>
        <string>_securityd</string>
        <key>Label</key>
        <key>GroupName</key>
        <string>_securityd</string>
        <key>Label</key>
old mode 100644 (file)
new mode 100755 (executable)
index ffe0bf8..216dd06
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2007-2009 Apple Inc. All Rights Reserved.
+ * Copyright (c) 2007-2009,2013 Apple Inc. All Rights Reserved.
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
 #define _SECURITYD_CLIENT_H_
 
 #include <stdint.h>
 #define _SECURITYD_CLIENT_H_
 
 #include <stdint.h>
-#include <Security/SecTrustStore.h>
+
+# include <Security/SecTrust.h>
+#ifndef MINIMIZE_INCLUDES
+# include <Security/SecTrustStore.h>
+# include <Security/SecCertificatePath.h>
+#else
+typedef struct __SecTrustStore *SecTrustStoreRef;
+# ifndef _SECURITY_SECCERTIFICATE_H_
+typedef struct __SecCertificate *SecCertificateRef;
+# endif // _SECURITY_SECCERTIFICATE_H_
+# ifndef _SECURITY_SECCERTIFICATEPATH_H_
+typedef struct SecCertificatePath *SecCertificatePathRef;
+# endif // _SECURITY_SECCERTIFICATEPATH_H_
+#endif // MINIMIZE_INCLUDES
+
 #include <CoreFoundation/CFArray.h>
 #include <CoreFoundation/CFDictionary.h>
 #include <CoreFoundation/CFArray.h>
 #include <CoreFoundation/CFDictionary.h>
+#include <CoreFoundation/CFError.h>
+
+#include <SecureObjectSync/SOSCloudCircle.h>
+
+#include <xpc/xpc.h>
+#include <CoreFoundation/CFXPCBridge.h>
 
 
+// TODO: This should be in client of XPC code locations...
 #if SECITEM_SHIM_OSX
 #if SECITEM_SHIM_OSX
-#define SECURITYSERVER_BOOTSTRAP_NAME "com.apple.secd"
+#define kSecuritydXPCServiceName "com.apple.securityd.xpc"
 #else
 #else
-#define SECURITYSERVER_BOOTSTRAP_NAME "com.apple.securityd"
+#define kSecuritydXPCServiceName "com.apple.securityd"
 #endif // *** END SECITEM_SHIM_OSX ***
 
 #endif // *** END SECITEM_SHIM_OSX ***
 
-#define SECURITYD(SPI, IN, OUT) (gSecurityd \
-    ? gSecurityd->SPI(IN, OUT) \
-    : ServerCommandSendReceive(SPI ## _id, IN, OUT)) 
+//
+// MARK: XPC Information.
+//
+
+extern CFStringRef sSecXPCErrorDomain;
+
+extern const char *kSecXPCKeyOperation;
+extern const char *kSecXPCKeyResult;
+extern const char *kSecXPCKeyError;
+extern const char *kSecXPCKeyPeerInfos;
+extern const char *kSecXPCKeyUserLabel;
+extern const char *kSecXPCKeyBackup;
+extern const char *kSecXPCKeyKeybag;
+extern const char *kSecXPCKeyUserPassword;
+
+//
+// MARK: Dispatch macros
+//
+
+#define SECURITYD_XPC(sdp, wrapper, ...) ((gSecurityd && gSecurityd->sdp) ? gSecurityd->sdp(__VA_ARGS__) : wrapper(sdp ## _id, __VA_ARGS__))
 
 
-#define SECURITYD_AG(SPI, IN, OUT) (gSecurityd \
-    ? gSecurityd->SPI(IN, OUT, SecAccessGroupsGetCurrent()) \
-    : ServerCommandSendReceive(SPI ## _id, IN, OUT))
+//
+// MARK: Object to XPC format conversion.
+//
 
 
-enum {
-       sec_item_add_id,
-       sec_item_copy_matching_id,
-       sec_item_update_id,
-       sec_item_delete_id,
+
+//
+// MARK: XPC Interfaces
+//
+
+extern const char *kSecXPCKeyOperation;
+extern const char *kSecXPCKeyResult;
+extern const char *kSecXPCKeyError;
+extern const char *kSecXPCKeyPeerInfos;
+extern const char *kSecXPCKeyUserLabel;
+extern const char *kSecXPCKeyUserPassword;
+extern const char *kSecXPCLimitInMinutes;
+extern const char *kSecXPCKeyQuery;
+extern const char *kSecXPCKeyAttributesToUpdate;
+extern const char *kSecXPCKeyDomain;
+extern const char *kSecXPCKeyDigest;
+extern const char *kSecXPCKeyCertificate;
+extern const char *kSecXPCKeySettings;
+
+//
+// MARK: Mach port request IDs
+//
+enum SecXPCOperation {
+    sec_item_add_id,
+    sec_item_copy_matching_id,
+    sec_item_update_id,
+    sec_item_delete_id,
+    // trust_store_for_domain -- NOT an ipc
     sec_trust_store_contains_id,
     sec_trust_store_set_trust_settings_id,
     sec_trust_store_remove_certificate_id,
     sec_trust_store_contains_id,
     sec_trust_store_set_trust_settings_id,
     sec_trust_store_remove_certificate_id,
+    // remove_all -- NOT an ipc
     sec_delete_all_id,
     sec_trust_evaluate_id,
     sec_delete_all_id,
     sec_trust_evaluate_id,
-    sec_restore_keychain_id,
-    sec_migrate_keychain_id,
     sec_keychain_backup_id,
     sec_keychain_backup_id,
-    sec_keychain_restore_id
+    sec_keychain_restore_id,
+    sec_keychain_sync_update_id,
+    sec_keychain_backup_syncable_id,
+    sec_keychain_restore_syncable_id,
+    sec_ota_pki_asset_version_id,
+       kSecXPCOpOTAPKIGetNewAsset,
+       kSecXPCOpOTAGetEscrowCertificates,
+    kSecXPCOpProcessUnlockNotification,
+    kSecXPCOpProcessSyncWithAllPeers,
+    // any process using an operation below here is required to have entitlement keychain-cloud-circle
+    kSecXPCOpTryUserCredentials,
+    kSecXPCOpSetUserCredentials,
+    kSecXPCOpCanAuthenticate,
+    kSecXPCOpPurgeUserCredentials,
+    kSecXPCOpDeviceInCircle,
+    kSecXPCOpRequestToJoin,
+    kSecXPCOpRequestToJoinAfterRestore,
+    kSecXPCOpResetToOffering,
+    kSecXPCOpResetToEmpty,
+    kSecXPCOpRemoveThisDeviceFromCircle,
+    kSecXPCOpBailFromCircle,
+    kSecXPCOpAcceptApplicants,
+    kSecXPCOpRejectApplicants,
+    kSecXPCOpCopyApplicantPeerInfo,
+    kSecXPCOpCopyPeerPeerInfo,
+    kSecXPCOpCopyConcurringPeerPeerInfo,
+    kSecXPCOpGetLastDepartureReason,
+    kSecXPCOpCopyIncompatibilityInfo
 };
 
 };
 
+
+
 struct securityd {
 struct securityd {
-    OSStatus (*sec_item_add)(CFDictionaryRef attributes, CFTypeRef *result,
-    CFArrayRef accessGroups);
-    OSStatus (*sec_item_copy_matching)(CFDictionaryRef query,
-        CFTypeRef *result, CFArrayRef accessGroups);
-    OSStatus (*sec_item_update)(CFDictionaryRef query,
-        CFDictionaryRef attributesToUpdate, CFArrayRef accessGroups);
-    OSStatus (*sec_item_delete)(CFDictionaryRef query, CFArrayRef accessGroups);
-    SecTrustStoreRef (*sec_trust_store_for_domain)(CFStringRef domainName);
-    bool (*sec_trust_store_contains)(SecTrustStoreRef ts,
-        CFDataRef digest);
-    OSStatus (*sec_trust_store_set_trust_settings)(SecTrustStoreRef ts,
-        SecCertificateRef certificate, CFTypeRef trustSettingsDictOrArray);
-    OSStatus (*sec_trust_store_remove_certificate)(SecTrustStoreRef ts,
-        CFDataRef digest);
-    bool (*sec_truststore_remove_all)(SecTrustStoreRef ts);
-    bool (*sec_item_delete_all)(void);
-    OSStatus (*sec_trust_evaluate)(CFDictionaryRef args_in,
-        CFTypeRef *args_out);
-    OSStatus (*sec_restore_keychain)(void);
-    OSStatus (*sec_migrate_keychain)(CFArrayRef args_in, CFTypeRef *args_out);
-    OSStatus (*sec_keychain_backup)(CFArrayRef args_in, CFTypeRef *args_out);
-    OSStatus (*sec_keychain_restore)(CFArrayRef args_in, CFTypeRef *dummy);
+    bool (*sec_item_add)(CFDictionaryRef attributes, CFArrayRef accessGroups, CFTypeRef *result, CFErrorRef* error);
+    bool (*sec_item_copy_matching)(CFDictionaryRef query, CFArrayRef accessGroups, CFTypeRef *result, CFErrorRef* error);
+    bool (*sec_item_update)(CFDictionaryRef query, CFDictionaryRef attributesToUpdate, CFArrayRef accessGroups, CFErrorRef* error);
+    bool (*sec_item_delete)(CFDictionaryRef query, CFArrayRef accessGroups, CFErrorRef* error);
+    SecTrustStoreRef (*sec_trust_store_for_domain)(CFStringRef domainName, CFErrorRef* error);       // TODO: remove, has no msg id
+    bool (*sec_trust_store_contains)(SecTrustStoreRef ts, CFDataRef digest, bool *contains, CFErrorRef* error);
+    bool (*sec_trust_store_set_trust_settings)(SecTrustStoreRef ts, SecCertificateRef certificate, CFTypeRef trustSettingsDictOrArray, CFErrorRef* error);
+    bool (*sec_trust_store_remove_certificate)(SecTrustStoreRef ts, CFDataRef digest, CFErrorRef* error);
+    bool (*sec_truststore_remove_all)(SecTrustStoreRef ts, CFErrorRef* error);                         // TODO: remove, has no msg id
+    bool (*sec_item_delete_all)(CFErrorRef* error);
+    SecTrustResultType (*sec_trust_evaluate)(CFArrayRef certificates, CFArrayRef anchors, bool anchorsOnly, CFArrayRef policies, CFAbsoluteTime verifyTime, __unused CFArrayRef accessGroups, CFArrayRef *details, CFDictionaryRef *info, SecCertificatePathRef *chain, CFErrorRef *error);
+    CFDataRef (*sec_keychain_backup)(CFDataRef keybag, CFDataRef passcode, CFErrorRef* error);
+    bool (*sec_keychain_restore)(CFDataRef backup, CFDataRef keybag, CFDataRef passcode, CFErrorRef* error);
+    bool (*sec_keychain_sync_update)(CFDictionaryRef update, CFErrorRef *error);
+    CFDictionaryRef (*sec_keychain_backup_syncable)(CFDictionaryRef backup_in, CFDataRef keybag, CFDataRef passcode, CFErrorRef* error);
+    bool (*sec_keychain_restore_syncable)(CFDictionaryRef backup, CFDataRef keybag, CFDataRef passcode, CFErrorRef* error);
+    int (*sec_ota_pki_asset_version)(CFErrorRef* error);
+    bool (*soscc_TryUserCredentials)(CFStringRef user_label, CFDataRef user_password, CFErrorRef *error);
+    bool (*soscc_SetUserCredentials)(CFStringRef user_label, CFDataRef user_password, CFErrorRef *error);
+    bool (*soscc_CanAuthenticate)(CFErrorRef *error);
+    bool (*soscc_PurgeUserCredentials)(CFErrorRef *error);
+    SOSCCStatus (*soscc_ThisDeviceIsInCircle)(CFErrorRef* error);
+    bool (*soscc_RequestToJoinCircle)(CFErrorRef* error);
+    bool (*soscc_RequestToJoinCircleAfterRestore)(CFErrorRef* error);
+    bool (*soscc_ResetToOffering)(CFErrorRef* error);
+    bool (*soscc_ResetToEmpty)(CFErrorRef* error);
+    bool (*soscc_RemoveThisDeviceFromCircle)(CFErrorRef* error);
+    bool (*soscc_BailFromCircle)(uint64_t limit_in_seconds, CFErrorRef* error);
+    bool (*soscc_AcceptApplicants)(CFArrayRef applicants, CFErrorRef* error);
+    bool (*soscc_RejectApplicants)(CFArrayRef applicants, CFErrorRef* error);
+    CFArrayRef (*soscc_CopyApplicantPeerInfo)(CFErrorRef* error);
+    CFArrayRef (*soscc_CopyPeerInfo)(CFErrorRef* error);
+    CFArrayRef (*soscc_CopyConcurringPeerInfo)(CFErrorRef* error);
+    CFStringRef (*soscc_CopyIncompatibilityInfo)(CFErrorRef* error);
+    enum DepartureReason (*soscc_GetLastDepartureReason)(CFErrorRef* error);
+       CFArrayRef (*ota_CopyEscrowCertificates)(CFErrorRef* error);
+       int (*sec_ota_pki_get_new_asset)(CFErrorRef* error);
+    SyncWithAllPeersReason (*soscc_ProcessSyncWithAllPeers)(CFErrorRef* error);
 };
 
 extern struct securityd *gSecurityd;
 
 CFArrayRef SecAccessGroupsGetCurrent(void);
 };
 
 extern struct securityd *gSecurityd;
 
 CFArrayRef SecAccessGroupsGetCurrent(void);
-void SecAccessGroupsSetCurrent(CFArrayRef accessGroups);
 
 
-OSStatus ServerCommandSendReceive(uint32_t id, CFTypeRef in, CFTypeRef *out);
+// TODO Rename me
+CFStringRef SOSCCGetOperationDescription(enum SecXPCOperation op);
+xpc_object_t securityd_message_with_reply_sync(xpc_object_t message, CFErrorRef *error);
+xpc_object_t securityd_create_message(enum SecXPCOperation op, CFErrorRef *error);
+bool securityd_message_no_error(xpc_object_t message, CFErrorRef *error);
+
+
+bool securityd_send_sync_and_do(enum SecXPCOperation op, CFErrorRef *error,
+                                bool (^add_to_message)(xpc_object_t message, CFErrorRef* error),
+                                bool (^handle_response)(xpc_object_t response, CFErrorRef* error));
+
+// For testing only, never call this in a threaded program!
+void SecServerSetMachServiceName(const char *name);
 
 #endif /* _SECURITYD_CLIENT_H_ */
 
 #endif /* _SECURITYD_CLIENT_H_ */
diff --git a/sec/ipc/securityd_ipc_types.h b/sec/ipc/securityd_ipc_types.h
deleted file mode 100644 (file)
index ef3fd87..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2007 Apple Inc. All Rights Reserved.
- * 
- * @APPLE_LICENSE_HEADER_START@
- * 
- * 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 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-#ifndef _SECURITYD_IPC_TYPES_H_
-#define _SECURITYD_IPC_TYPES_H_
-
-typedef uint8_t * securityd_ipc_data;
-
-#endif /* _SECURITYD_IPC_TYPES_H_ */
diff --git a/sec/ipc/securityd_rep.defs b/sec/ipc/securityd_rep.defs
deleted file mode 100644 (file)
index 58a8ba0..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2007,2010 Apple Inc. All Rights Reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * 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 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <mach/std_types.defs>
-#include <mach/mach_types.defs>
-
-import "securityd_ipc_types.h";
-
-subsystem securityd_reply 1001;
-serverprefix securityd_server_;
-userprefix   securityd_client_;
-
-type securityd_ipc_data = array [] of char;
-
-simpleroutine reply(receiver: mach_port_move_send_once_t; 
-            request_id: uint32_t;
-            return_code: int32_t;
-            msg_data: securityd_ipc_data);
-
diff --git a/sec/ipc/securityd_req.defs b/sec/ipc/securityd_req.defs
deleted file mode 100644 (file)
index 49d2945..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2007-2008,2010 Apple Inc. All Rights Reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * 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 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <mach/std_types.defs>
-#include <mach/mach_types.defs>
-
-import "securityd_ipc_types.h";
-
-subsystem securityd_request 1000;
-serverprefix securityd_server_;
-userprefix   securityd_client_;
-
-type securityd_ipc_data = array [] of char;
-
-simpleroutine request(receiver: mach_port_t; 
-            reply: mach_port_make_send_once_t;
-            serveraudittoken sourceAudit: audit_token_t;
-            request_id: uint32_t;
-            msg_id: uint32_t;
-            msg_data: securityd_ipc_data);
diff --git a/sec/ipc/securityd_server.h b/sec/ipc/securityd_server.h
deleted file mode 100644 (file)
index a916986..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2007-2010 Apple Inc. All Rights Reserved.
- * 
- * @APPLE_LICENSE_HEADER_START@
- * 
- * 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 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#ifndef _SECURITYD_SERVER_H_
-#define _SECURITYD_SERVER_H_
-
-#include <mach/message.h>
-#include <securityd/SecItemServer.h>
-#include <securityd/SecTrustServer.h>
-#include <securityd/SecTrustStoreServer.h>
-
-/* Receiver takes on onwership of args_out. */
-kern_return_t securityd_server_send_reply(mach_port_t reply,
-    uint32_t request_id, OSStatus status, CFTypeRef args_out);
-
-#endif /* _SECURITYD_SERVER_H_ */
index 17070b7cee168589d8cacf2340073e2649b6243a..46541ba7f9dea2ce9f0c80f9fb5c8c9f56a626f5 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2007-2009 Apple Inc.  All Rights Reserved.
+ * Copyright (c) 2007-2013 Apple Inc.  All Rights Reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -23,7 +23,6 @@
 
 #include <mach/mach.h>
 #include <mach/message.h>
 
 #include <mach/mach.h>
 #include <mach/message.h>
-#include <servers/bootstrap.h>
 
 #include <stdlib.h>
 #include <sys/queue.h>
 
 #include <stdlib.h>
 #include <sys/queue.h>
 #include <Security/SecInternal.h>
 #include <Security/SecBasePriv.h>
 #include <Security/SecItemPriv.h> /* For SecItemDeleteAll */
 #include <Security/SecInternal.h>
 #include <Security/SecBasePriv.h>
 #include <Security/SecItemPriv.h> /* For SecItemDeleteAll */
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecPolicyInternal.h>
 #include <CoreFoundation/CoreFoundation.h>
 
 #include <asl.h>
 #include <CoreFoundation/CoreFoundation.h>
 
 #include <asl.h>
+#include <syslog.h>
 #include <bsm/libbsm.h>
 #include <bsm/libbsm.h>
-#include <security_utilities/debugging.h>
-#include <sys/sysctl.h>
+#include <utilities/SecIOFormat.h>
+#include <utilities/debugging.h>
 
 #include "securityd_client.h"
 
 #include "securityd_client.h"
-#include "securityd_rep.h"
-#include "securityd_server.h"
 
 
+#include <securityd/SecItemServer.h>
+#include <securityd/SecTrustServer.h>
+#include <securityd/SecTrustStoreServer.h>
 #include <securityd/spi.h>
 #include <securityd/spi.h>
-
-#ifndef SECITEM_SHIM_OSX
 #include <Security/SecTask.h>
 #include <Security/SecTask.h>
-#include <Security/SecEntitlements.h>
-#endif
 
 
-#if INDIGO || SECITEM_SHIM_OSX
-#define CHECK_ENTITLEMENTS 0
-#else
-#define CHECK_ENTITLEMENTS 1
-#endif
+#include <utilities/SecCFWrappers.h>
+#include <utilities/SecCFError.h>
+#include <utilities/SecXPCError.h>
 
 
-/* Time after which securityd exits. */
-#if NDEBUG
-#define TIMEOUT_IN_SECONDS  10.0
+// TODO: Make this include work on both platforms.
+#if TARGET_OS_EMBEDDED
+#include <Security/SecEntitlements.h>
 #else
 #else
-#define TIMEOUT_IN_SECONDS  10000.0
-#endif
-
-#if SECITEM_SHIM_OSX
+#define kSecEntitlementKeychainSyncUpdates CFSTR("keychain-sync-updates")
+#define kSecEntitlementKeychainCloudCircle CFSTR("keychain-cloud-circle")
 /* defines from <Security/SecTask.h> */
 /* defines from <Security/SecTask.h> */
-typedef struct __SecTask *SecTaskRef;
 /* defines from <Security/SecEntitlements.h> */
 #define kSecEntitlementGetTaskAllow CFSTR("get-task-allow")
 #define kSecEntitlementApplicationIdentifier CFSTR("application-identifier")
 /* defines from <Security/SecEntitlements.h> */
 #define kSecEntitlementGetTaskAllow CFSTR("get-task-allow")
 #define kSecEntitlementApplicationIdentifier CFSTR("application-identifier")
@@ -76,50 +70,36 @@ typedef struct __SecTask *SecTaskRef;
 #define kSecEntitlementRemoteNotificationConfigure CFSTR("com.apple.remotenotification.configure")
 #define kSecEntitlementMigrateKeychain CFSTR("migrate-keychain")
 #define kSecEntitlementRestoreKeychain CFSTR("restore-keychain")
 #define kSecEntitlementRemoteNotificationConfigure CFSTR("com.apple.remotenotification.configure")
 #define kSecEntitlementMigrateKeychain CFSTR("migrate-keychain")
 #define kSecEntitlementRestoreKeychain CFSTR("restore-keychain")
-
+#define kSecEntitlementSyncKeychain CFSTR("sync-keychain")
 #endif
 
 #endif
 
-static mach_port_t _server_port = MACH_PORT_NULL;
-static unsigned int active_requests = 0;
-static CFRunLoopTimerRef idle_timer = NULL;
+#include <Security/SecuritydXPC.h>
 
 
-static mach_port_t server_port(void *info)
-{
-    if (!_server_port) {
-        kern_return_t ret;
+#include <libkern/OSAtomic.h>
 
 
-        ret = bootstrap_check_in(bootstrap_port, SECURITYSERVER_BOOTSTRAP_NAME, &_server_port);
-        if (ret == KERN_SUCCESS) {
-            secdebug("server", "bootstrap_check_in() succeeded, return checked in port: 0x%x\n", _server_port);
-            return _server_port;
-        }
+#include <CoreFoundation/CFXPCBridge.h>
 
 
-#if 0
-        ret = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &_server_port);
-        if (ret != KERN_SUCCESS) {
-            secdebug("server", "mach_port_allocate(): 0x%x: %s\n", ret, mach_error_string(ret));
-            exit(2);
-        }
+#include <xpc/xpc.h>
+#include <xpc/private.h>
+#include <xpc/connection_private.h>
+#include <AssertMacros.h>
+#include <SecureObjectSync/SOSCloudCircle.h>
 
 
-        ret = mach_port_insert_right(mach_task_self(), _server_port, _server_port, MACH_MSG_TYPE_MAKE_SEND);
-        if (ret != KERN_SUCCESS) {
-            secdebug("server", "mach_port_insert_right(): 0x%x: %s\n", ret, mach_error_string(ret));
-            exit(3);
-        }
+#include <securityd/SOSCloudCircleServer.h>
+#include <SecureObjectSync/SOSCloudCircleInternal.h>
+#include <sys/sysctl.h>
 
 
-        ret = bootstrap_register(bootstrap_port, SECURITYSERVER_BOOTSTRAP_NAME, _server_port);
-        if (ret != BOOTSTRAP_SUCCESS) {
-            secdebug("server", "bootstrap_register(): 0x%x: %s\n", ret, mach_error_string(ret));
-            exit(4);
-        }
-#else
-        exit(1);
-#endif
+// For SecError
+#include <utilities/SecDb.h>
 
 
-    }
+#include <securityd/OTATrustUtilities.h>
 
 
-    return _server_port;
-}
+
+#if TARGET_IPHONE_SIMULATOR
+#define CHECK_ENTITLEMENTS 0
+#else
+#define CHECK_ENTITLEMENTS 1
+#endif
 
 #if CHECK_ENTITLEMENTS
 static CFStringRef SecTaskCopyStringForEntitlement(SecTaskRef task,
 
 #if CHECK_ENTITLEMENTS
 static CFStringRef SecTaskCopyStringForEntitlement(SecTaskRef task,
@@ -159,6 +139,7 @@ static CFArrayRef SecTaskCopyArrayOfStringsForEntitlement(SecTaskRef task,
 
     return value;
 }
 
     return value;
 }
+
 #endif /* CHECK_ENTITLEMENTS */
 
 static CFArrayRef SecTaskCopyAccessGroups(SecTaskRef task) {
 #endif /* CHECK_ENTITLEMENTS */
 
 static CFArrayRef SecTaskCopyAccessGroups(SecTaskRef task) {
@@ -196,471 +177,588 @@ static bool SecTaskGetBooleanValueForEntitlement(SecTaskRef task,
     if (!canModify)
         return false;
     CFTypeID canModifyType = CFGetTypeID(canModify);
     if (!canModify)
         return false;
     CFTypeID canModifyType = CFGetTypeID(canModify);
-    if (CFBooleanGetTypeID() == canModifyType) {
-        return CFBooleanGetValue((CFBooleanRef)canModify);
-    } else
-        return false;
+    bool ok = (CFBooleanGetTypeID() == canModifyType) && CFBooleanGetValue((CFBooleanRef)canModify);
+    CFRelease(canModify);
+    return ok;
 #else
     return true;
 #endif /* !CHECK_ENTITLEMENTS */
 }
 
 #else
     return true;
 #endif /* !CHECK_ENTITLEMENTS */
 }
 
-#if 0
-static CFDataRef CFArrayGetCheckedDataAtIndex() {
-}
-#endif
+static void with_label_and_password(xpc_object_t message, void (^action)(CFStringRef label, CFDataRef password)) {
+    const char *label_utf8 = xpc_dictionary_get_string(message, kSecXPCKeyUserLabel);
 
 
-static bool isDictionary(CFTypeRef cfType) {
-    return cfType && CFGetTypeID(cfType) == CFDictionaryGetTypeID();
-}
+    size_t password_length = 0;
+    const void *password_data = xpc_dictionary_get_data(message, kSecXPCKeyUserPassword, &password_length);
 
 
-static bool isData(CFTypeRef cfType) {
-    return cfType && CFGetTypeID(cfType) == CFDataGetTypeID();
-}
+    CFDataRef user_password = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, password_data, password_length, kCFAllocatorNull);
+    CFStringRef user_label = CFStringCreateWithCString(kCFAllocatorDefault, label_utf8, kCFStringEncodingUTF8);
 
 
-static bool isString(CFTypeRef cfType) {
-    return cfType && CFGetTypeID(cfType) == CFStringGetTypeID();
-}
+    action(user_label, user_password);
 
 
-static bool isArray(CFTypeRef cfType) {
-    return cfType && CFGetTypeID(cfType) == CFArrayGetTypeID();
+    CFReleaseNull(user_password);
+    CFReleaseNull(user_label);
 }
 
 }
 
-static bool isArrayOfLength(CFTypeRef cfType, CFIndex length) {
-    return isArray(cfType) && CFArrayGetCount(cfType) == length;
+static bool SecXPCDictionarySetChainOptional(xpc_object_t message, const char *key, SecCertificatePathRef path, CFErrorRef *error) {
+    if (!path)
+        return true;
+    xpc_object_t xpc_chain = SecCertificatePathCopyXPCArray(path, error);
+    if (!xpc_chain)
+        return false;
+
+    xpc_dictionary_set_value(message, key, xpc_chain);
+    xpc_release(xpc_chain);
+    return true;
 }
 
 }
 
-static void idle_timer_proc(CFRunLoopTimerRef timer, void *info)
-{
-    if (active_requests == 0) {
-        /* If the idle timer fired and we have no active requests we exit. */
-        exit(0);
+static SecCertificateRef SecXPCDictionaryCopyCertificate(xpc_object_t message, const char *key, CFErrorRef *error) {
+    size_t length = 0;
+    const void *bytes = xpc_dictionary_get_data(message, key, &length);
+    if (bytes) {
+        SecCertificateRef certificate = SecCertificateCreateWithBytes(kCFAllocatorDefault, bytes, length);
+        if (certificate)
+            return certificate;
+        SecError(errSecDecode, error, CFSTR("object for key %s failed to create certificate from data"), key);
+    } else {
+        SecError(errSecParam, error, CFSTR("object for key %s missing"), key);
     }
     }
+    return NULL;
 }
 
 }
 
-static void cancel_timeout()
-{
-    if (idle_timer) {
-        CFRunLoopTimerInvalidate(idle_timer);
-        CFRelease(idle_timer);
-        idle_timer = NULL;
-    }
+static bool SecXPCDictionaryCopyCertificates(xpc_object_t message, const char *key, CFArrayRef *certificates, CFErrorRef *error) {
+    xpc_object_t xpc_certificates = xpc_dictionary_get_value(message, key);
+    if (!xpc_certificates)
+        return SecError(errSecAllocate, error, CFSTR("no certs for key %s"), key);
+    *certificates = SecCertificateXPCArrayCopyArray(xpc_certificates, error);
+    return *certificates;
 }
 
 }
 
-static void register_timeout(void)
-{
-    if (idle_timer == NULL) {
-        idle_timer = CFRunLoopTimerCreate(kCFAllocatorDefault,
-            CFAbsoluteTimeGetCurrent() + TIMEOUT_IN_SECONDS,
-            TIMEOUT_IN_SECONDS, 0, 0, idle_timer_proc, NULL);
-        if (idle_timer == NULL) {
-            asl_log(NULL, NULL, ASL_LEVEL_CRIT,
-                "FATAL: failed to create idle timer, exiting.");
-            exit(1);
-        }
-        CFRunLoopAddTimer(CFRunLoopGetCurrent(), idle_timer,
-            kCFRunLoopDefaultMode);
+static bool SecXPCDictionaryCopyCertificatesOptional(xpc_object_t message, const char *key, CFArrayRef *certificates, CFErrorRef *error) {
+    xpc_object_t xpc_certificates = xpc_dictionary_get_value(message, key);
+    if (!xpc_certificates) {
+        *certificates = NULL;
+        return true;
     }
     }
+    *certificates = SecCertificateXPCArrayCopyArray(xpc_certificates, error);
+    return *certificates;
 }
 
 }
 
-static void request_begin(void)
-{
-    if (active_requests++ == 0) {
-        /* First request, cancel timer. */
-        cancel_timeout();
+static bool SecXPCDictionaryCopyPoliciesOptional(xpc_object_t message, const char *key, CFArrayRef *policies, CFErrorRef *error) {
+    xpc_object_t xpc_policies = xpc_dictionary_get_value(message, key);
+    if (!xpc_policies) {
+        if (policies)
+            *policies = NULL;
+        return true;
     }
     }
+    *policies = SecPolicyXPCArrayCopyArray(xpc_policies, error);
+    return *policies != NULL;
 }
 
 }
 
-static void request_end(void)
-{
-    if (--active_requests == 0) {
-        /* Last request, set timer. */
-        register_timeout();
+static SecTrustStoreRef SecXPCDictionaryGetTrustStore(xpc_object_t message, const char *key, CFErrorRef *error) {
+    SecTrustStoreRef ts = NULL;
+    CFStringRef domain = SecXPCDictionaryCopyString(message, key, error);
+    if (domain) {
+        ts = SecTrustStoreForDomainName(domain, error);
+        CFRelease(domain);
     }
     }
+    return ts;
 }
 
 }
 
-/* AUDIT[securityd](done):
-   reply (checked by mig) is a caller provided mach_port.
-   request_id (checked by mig) is caller provided value, that matches the
-       mig entry for the server function.
- */
-kern_return_t securityd_server_send_reply(mach_port_t reply,
-    uint32_t request_id, OSStatus status, CFTypeRef args_out) {
-    CFDataRef data_out = NULL;
-    if (args_out) {
-#ifndef NDEBUG
-        CFDataRef query_debug = CFPropertyListCreateXMLData(kCFAllocatorDefault,
-            args_out);
-        secdebug("client", "securityd response: %.*s\n",
-            CFDataGetLength(query_debug), CFDataGetBytePtr(query_debug));
-        CFReleaseSafe(query_debug);
-#endif
-        CFErrorRef error = NULL;
-        data_out = CFPropertyListCreateData(kCFAllocatorDefault, args_out,
-                                           kCFPropertyListBinaryFormat_v1_0,
-                                           0, &error);
-               CFRelease(args_out);
-        if (error) {
-            secdebug("server", "failed to encode return data: %@", error);
-             CFReleaseSafe(error);
-        }
+static bool SecXPCDictionaryGetDouble(xpc_object_t message, const char *key, double *pvalue, CFErrorRef *error) {
+    *pvalue = xpc_dictionary_get_double(message, key);
+    if (*pvalue == NAN) {
+        return SecError(errSecParam, error, CFSTR("object for key %s bad double"), key);
     }
     }
-
-    void *p = (data_out ? (void *)CFDataGetBytePtr(data_out) : NULL);
-    CFIndex l = (data_out ? CFDataGetLength(data_out) : 0);
-    /* 64 bits cast: securityd should never generate replies bigger than 2^32 bytes.
-       Worst case is we are truncating the reply we send to the client. This would only
-       cause the client side to not be able to decode the response. */
-    assert((unsigned long)l<UINT_MAX); /* Debug check */
-    kern_return_t err = securityd_client_reply(reply, request_id, status,
-        p, (unsigned int)l);
-
-    CFReleaseSafe(data_out);
-
-    request_end();
-
-    return err;
+    return true;
 }
 
 }
 
-struct securityd_server_trust_evaluation_context {
-    mach_port_t reply;
-    uint32_t request_id;
-};
-
-static void
-securityd_server_trust_evaluate_done(const void *userData,
-    SecCertificatePathRef chain, CFArrayRef details, CFDictionaryRef info,
-    SecTrustResultType result) {
-    struct securityd_server_trust_evaluation_context *tec =
-        (struct securityd_server_trust_evaluation_context *)userData;
-
-    /* @@@ This code snippit is also in SecTrustServer.c.  I'd factor it,
-       but a better fix would be to change the interfaces here to not use
-       single in/out args and do all the argument munging in server.c
-       and client.c. */
-    CFDictionaryRef args_out;
-    CFNumberRef resultNumber = NULL;
-    CFArrayRef chain_certs = NULL;
-    /* Proccess outgoing results. */
-    resultNumber = CFNumberCreate(NULL, kCFNumberSInt32Type, &result);
-    chain_certs = SecCertificatePathCopyArray(chain);
-    const void *out_keys[] = { kSecTrustChainKey, kSecTrustDetailsKey,
-        kSecTrustInfoKey, kSecTrustResultKey };
-    const void *out_values[] = { chain_certs, details, info, resultNumber };
-    args_out = (CFTypeRef)CFDictionaryCreate(kCFAllocatorDefault, out_keys,
-        out_values, sizeof(out_keys) / sizeof(*out_keys),
-        &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-    CFReleaseSafe(chain_certs);
-    CFReleaseSafe(resultNumber);
-
-    /* Send back the response to the client. */
-    securityd_server_send_reply(tec->reply, tec->request_id, noErr, args_out);
-
-    free(tec);
-}
+static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, xpc_object_t event) {
+       xpc_type_t type = xpc_get_type(event);
+    __block CFErrorRef error = NULL;
+    xpc_object_t xpcError = NULL;
+    xpc_object_t replyMessage = NULL;
+    SecTaskRef clientTask = NULL;
+    CFArrayRef accessGroups = NULL;
+
+    secdebug("serverxpc", "entering");
+    if (type == XPC_TYPE_DICTIONARY) {
+        // TODO: Find out what we're dispatching.
+        replyMessage = xpc_dictionary_create_reply(event);
+
+        uint64_t operation = xpc_dictionary_get_uint64(event, kSecXPCKeyOperation);
+               secdebug("serverxpc", "operation: %@ (%" PRIu64 ")", SOSCCGetOperationDescription((enum SecXPCOperation)operation), operation);
+
+        bool hasEntitlement;
+#if 1 // CHECK_ENTITLEMENTS
+        audit_token_t auditToken = {};
+        xpc_connection_get_audit_token(connection, &auditToken);
+        clientTask = SecTaskCreateWithAuditToken(kCFAllocatorDefault, auditToken);
+        accessGroups = SecTaskCopyAccessGroups(clientTask);
+
+        // operations before kSecXPCOpTryUserCredentials don't need this entitlement.
+        hasEntitlement = (operation < kSecXPCOpTryUserCredentials) ||
+            (clientTask && SecTaskGetBooleanValueForEntitlement(clientTask, kSecEntitlementKeychainCloudCircle));
+#else
+        clientTask = NULL;
+        hasEntitlement = true;
+#endif
 
 
-kern_return_t securityd_server_request(mach_port_t receiver, mach_port_t reply,
-        audit_token_t auditToken,
-        uint32_t request_id, uint32_t msg_id, uint8_t *msg_data,
-        mach_msg_type_number_t msg_length);
-
-/* AUDIT[securityd](done):
-   receiver (unused) is a mach_port owned by this process.
-   reply (checked by mig) is a caller provided mach_port.
-   auditToken (ok) is a kernel provided audit token.
-   request_id (checked by mig) is caller provided value, that matches the
-       mig entry for this function.
-   msg_id (ok) is caller provided value.
-   msg_data (ok) is a caller provided data of length:
-   msg_length (ok).
- */
-kern_return_t securityd_server_request(mach_port_t receiver, mach_port_t reply,
-        audit_token_t auditToken,
-        uint32_t request_id, uint32_t msg_id, uint8_t *msg_data,
-        mach_msg_type_number_t msg_length)
-{
-    CFTypeRef args_in = NULL;
-    CFTypeRef args_out = NULL;
-    bool sendResponse = true;
-    const char *op_name;
-
-    request_begin();
-
-    if (msg_length) {
-        CFDataRef data_in = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
-            msg_data, msg_length, kCFAllocatorNull);
-        if (data_in) {
-            args_in = CFPropertyListCreateFromXMLData(kCFAllocatorDefault,
-                data_in, kCFPropertyListImmutable, NULL);
-            CFRelease(data_in);
-        }
-    }
+         // Per <rdar://problem/13315020> Disable the entitlement check for "keychain-cloud-circle"
+         //  we disable entitlement enforcement. However, we still log so we know who needs the entitlement
 
 
-#if 0
-    static int crash_counter = 0;
-    if (crash_counter++) {
-        secdebug("server", "crash test");
-        exit(1);
-    }
-#endif
+         if (!hasEntitlement) {
+            CFErrorRef entitlementError = NULL;
+            SecError(errSecMissingEntitlement, &entitlementError, CFSTR("%@: %@ lacks entitlement %@"), SOSCCGetOperationDescription((enum SecXPCOperation)operation), clientTask, kSecEntitlementKeychainCloudCircle);
+            secnotice("serverxpc", "MissingEntitlement: %@", entitlementError);
+            CFReleaseSafe(entitlementError);
+        }
 
 
-    SecTaskRef clientTask = 
-#if CHECK_ENTITLEMENTS
-    SecTaskCreateWithAuditToken(kCFAllocatorDefault, auditToken);
-#else 
-    NULL;
-#endif
-    CFArrayRef groups = SecTaskCopyAccessGroups(clientTask);
-    SecAccessGroupsSetCurrent(groups);
-    OSStatus status = errSecParam;
-    switch(msg_id) {
-        case sec_item_add_id:
-            op_name = "SecItemAdd";
-            if (isDictionary(args_in))
-                status = _SecItemAdd(args_in, &args_out, groups);
-            break;
-        case sec_item_copy_matching_id:
-            op_name = "SecItemCopyMatching";
-            if (isDictionary(args_in))
-                status = _SecItemCopyMatching(args_in, &args_out, groups);
-            break;
-        case sec_item_delete_id:
-            op_name = "SecItemDelete";
-            if (isDictionary(args_in))
-                status = _SecItemDelete(args_in, groups);
-            break;
-        case sec_item_update_id:
-            op_name = "SecItemUpdate";
-            if (isArrayOfLength(args_in, 2)) {
-                CFDictionaryRef
-                    in0 = (CFDictionaryRef)CFArrayGetValueAtIndex(args_in, 0),
-                    in1 = (CFDictionaryRef)CFArrayGetValueAtIndex(args_in, 1);
-                if (isDictionary(in0) && isDictionary(in1))
-                    status = _SecItemUpdate(in0, in1, groups);
-            }
-            break;
-        case sec_trust_store_contains_id:
-        {
-            op_name = "SecTrustStoreContains";
-            if (!isArray(args_in))
-                break;
-            CFIndex argc_in = CFArrayGetCount(args_in);
-            if (argc_in != 2)
+        if (true) {
+            switch (operation)
+            {
+            case sec_item_add_id:
+            {
+                CFDictionaryRef query = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyQuery, &error);
+                if (query) {
+                    CFTypeRef result = NULL;
+                    if (_SecItemAdd(query, accessGroups, &result, &error) && result) {
+                        SecXPCDictionarySetPList(replyMessage, kSecXPCKeyResult, result, &error);
+                        CFRelease(result);
+                    }
+                    CFRelease(query);
+                }
                 break;
                 break;
-            CFStringRef domainName = CFArrayGetValueAtIndex(args_in, 0);
-            CFDataRef digest = CFArrayGetValueAtIndex(args_in, 1);
-            if (!isString(domainName) || !isData(digest))
+            }
+            case sec_item_copy_matching_id:
+            {
+                CFDictionaryRef query = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyQuery, &error);
+                if (query) {
+                    CFTypeRef result = NULL;
+                    if (_SecItemCopyMatching(query, accessGroups, &result, &error) && result) {
+                        SecXPCDictionarySetPList(replyMessage, kSecXPCKeyResult, result, &error);
+                        CFRelease(result);
+                    }
+                    CFRelease(query);
+                }
                 break;
                 break;
-
-            SecTrustStoreRef ts = SecTrustStoreForDomainName(domainName);
-            status = !SecTrustStoreContainsCertificateWithDigest(ts, digest);
-            break;
-        }
-        case sec_trust_store_set_trust_settings_id:
-        {
-            op_name = "SecTrustStoreSetTrustSettings";
-            /* Open the trust store unconditially so we can abuse this method
-               even in clients that just want to read from the truststore,
-               and this call will force it to be created. */
-            SecTrustStoreRef ts = SecTrustStoreForDomain(kSecTrustStoreDomainUser);
-            if (!isArray(args_in))
+            }
+            case sec_item_update_id:
+            {
+                CFDictionaryRef query = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyQuery, &error);
+                if (query) {
+                    CFDictionaryRef attributesToUpdate = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyAttributesToUpdate, &error);
+                    if (attributesToUpdate) {
+                        bool result = _SecItemUpdate(query, attributesToUpdate, accessGroups, &error);
+                        xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result);
+                        CFRelease(attributesToUpdate);
+                    }
+                    CFRelease(query);
+                }
                 break;
                 break;
-            CFIndex argc_in = CFArrayGetCount(args_in);
-            if (argc_in != 1 && argc_in != 2)
+            }
+            case sec_item_delete_id:
+            {
+                CFDictionaryRef query = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyQuery, &error);
+                if (query) {
+                    bool result = _SecItemDelete(query, accessGroups, &error);
+                    xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result);
+                    CFRelease(query);
+                }
                 break;
                 break;
-            if (!SecTaskGetBooleanValueForEntitlement(clientTask,
-                kSecEntitlementModifyAnchorCertificates)) {
-                status = errSecMissingEntitlement;
+            }
+            case sec_trust_store_contains_id:
+            {
+                SecTrustStoreRef ts = SecXPCDictionaryGetTrustStore(event, kSecXPCKeyDomain, &error);
+                if (ts) {
+                    CFDataRef digest = SecXPCDictionaryCopyData(event, kSecXPCKeyDigest, &error);
+                    if (digest) {
+                        bool contains;
+                        if (SecTrustStoreContainsCertificateWithDigest(ts, digest, &contains, &error))
+                            xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, contains);
+                        CFRelease(digest);
+                    }
+                }
                 break;
             }
                 break;
             }
-            CFDataRef certificateData = (CFDataRef)CFArrayGetValueAtIndex(args_in, 0);
-            if (!isData(certificateData))
-                break;
-            SecCertificateRef certificate = SecCertificateCreateWithData(NULL, certificateData);
-            if (certificate) {
-                CFTypeRef trustSettingsDictOrArray;
-                if (argc_in < 2) {
-                    trustSettingsDictOrArray = NULL;
-                } else {
-                    trustSettingsDictOrArray = CFArrayGetValueAtIndex(args_in, 1);
-                    if (trustSettingsDictOrArray) {
-                        CFTypeID tst = CFGetTypeID(trustSettingsDictOrArray);
-                        if (tst != CFArrayGetTypeID() && tst != CFDictionaryGetTypeID()) {
-                            CFRelease(certificate);
-                            break;
+            case sec_trust_store_set_trust_settings_id:
+            {
+                SecTrustStoreRef ts = SecXPCDictionaryGetTrustStore(event, kSecXPCKeyDomain, &error);
+                if (ts) {
+                    SecCertificateRef certificate = SecXPCDictionaryCopyCertificate(event, kSecXPCKeyCertificate, &error);
+                    if (certificate) {
+                        CFTypeRef trustSettingsDictOrArray = NULL;
+                        if (SecXPCDictionaryCopyPListOptional(event, kSecXPCKeySettings, &trustSettingsDictOrArray, &error)) {
+                            bool result = _SecTrustStoreSetTrustSettings(ts, certificate, trustSettingsDictOrArray, &error);
+                            xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result);
+                            CFReleaseSafe(trustSettingsDictOrArray);
                         }
                         }
+                        CFRelease(certificate);
                     }
                 }
                     }
                 }
-                status = _SecTrustStoreSetTrustSettings(ts, certificate, trustSettingsDictOrArray);
-                CFRelease(certificate);
+                break;
             }
             }
-            break;
-        }
-        case sec_trust_store_remove_certificate_id:
-            op_name = "SecTrustStoreRemoveCertificate";
-            if (SecTaskGetBooleanValueForEntitlement(clientTask,
-                    kSecEntitlementModifyAnchorCertificates)) {
-                SecTrustStoreRef ts = SecTrustStoreForDomain(kSecTrustStoreDomainUser);
-                if (isData(args_in)) {
-                    status = SecTrustStoreRemoveCertificateWithDigest(ts, args_in);
+            case sec_trust_store_remove_certificate_id:
+            {
+                SecTrustStoreRef ts = SecXPCDictionaryGetTrustStore(event, kSecXPCKeyDomain, &error);
+                if (ts) {
+                    CFDataRef digest = SecXPCDictionaryCopyData(event, kSecXPCKeyDigest, &error);
+                    if (digest) {
+                        bool result = SecTrustStoreRemoveCertificateWithDigest(ts, digest, &error);
+                        xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result);
+                        CFRelease(digest);
+                    }
                 }
                 }
-            } else {
-                status = errSecMissingEntitlement;
+                break;
             }
             }
-            break;
-        case sec_delete_all_id:
-            op_name = "SecDeleteAll";
-            if (SecTaskGetBooleanValueForEntitlement(clientTask,
-                kSecEntitlementWipeDevice)) {
-                status = SecItemDeleteAll();
-            } else {
-                status = errSecMissingEntitlement;
+            case sec_delete_all_id:
+                xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, _SecItemDeleteAll(&error));
+                break;
+            case sec_trust_evaluate_id:
+            {
+                CFArrayRef certificates = NULL, anchors = NULL, policies = NULL;
+                bool anchorsOnly = xpc_dictionary_get_bool(event, kSecTrustAnchorsOnlyKey);
+                double verifyTime;
+                if (SecXPCDictionaryCopyCertificates(event, kSecTrustCertificatesKey, &certificates, &error) &&
+                    SecXPCDictionaryCopyCertificatesOptional(event, kSecTrustAnchorsKey, &anchors, &error) &&
+                    SecXPCDictionaryCopyPoliciesOptional(event, kSecTrustPoliciesKey, &policies, &error) &&
+                    SecXPCDictionaryGetDouble(event, kSecTrustVerifyDateKey, &verifyTime, &error)) {
+                    // If we have no error yet, capture connection and reply in block and properly retain them.
+                    xpc_retain(connection);
+                    CFRetainSafe(clientTask);
+
+                    // Clear replyMessage so we don't send a synchronous reply.
+                    xpc_object_t asyncReply = replyMessage;
+                    replyMessage = NULL;
+
+                    SecTrustServerEvaluateBlock(certificates, anchors, anchorsOnly, policies, verifyTime, accessGroups, ^(SecTrustResultType tr, CFArrayRef details, CFDictionaryRef info, SecCertificatePathRef chain, CFErrorRef replyError) {
+                        // Send back reply now
+                        if (replyError) {
+                            CFRetain(replyError);
+                        } else {
+                            xpc_dictionary_set_int64(asyncReply, kSecTrustResultKey, tr);
+                            SecXPCDictionarySetPListOptional(asyncReply, kSecTrustDetailsKey, details, &replyError) &&
+                            SecXPCDictionarySetPListOptional(asyncReply, kSecTrustInfoKey, info, &replyError) &&
+                            SecXPCDictionarySetChainOptional(asyncReply, kSecTrustChainKey, chain, &replyError);
+                        }
+                        if (replyError) {
+                            secdebug("ipc", "%@ %@ %@", clientTask, SOSCCGetOperationDescription((enum SecXPCOperation)operation), replyError);
+                            xpc_object_t xpcReplyError = SecCreateXPCObjectWithCFError(replyError);
+                            if (xpcReplyError) {
+                                xpc_dictionary_set_value(asyncReply, kSecXPCKeyError, xpcReplyError);
+                                xpc_release(xpcReplyError);
+                            }
+                            CFRelease(replyError);
+                        } else {
+                            secdebug("ipc", "%@ %@ reponding %@", clientTask, SOSCCGetOperationDescription((enum SecXPCOperation)operation), asyncReply);
+                        }
+
+                        xpc_connection_send_message(connection, asyncReply);
+                        xpc_release(asyncReply);
+                        xpc_release(connection);
+                        CFReleaseSafe(clientTask);
+                    });
+                }
+                CFReleaseSafe(policies);
+                CFReleaseSafe(anchors);
+                CFReleaseSafe(certificates);
+                break;
             }
             }
-            break;
-        case sec_trust_evaluate_id:
-            op_name = "SecTrustEvaluate";
-            if (isDictionary(args_in)) {
-                struct securityd_server_trust_evaluation_context *tec = malloc(sizeof(*tec));
-                tec->reply = reply;
-                tec->request_id = request_id;
-                status = SecTrustServerEvaluateAsync(args_in,
-                    securityd_server_trust_evaluate_done, tec);
-                if (status == noErr || status == errSecWaitForCallback) {
-                    sendResponse = false;
-                } else {
-                    free(tec);
+            case sec_keychain_backup_id:
+            {
+                CFDataRef keybag = NULL, passcode = NULL;
+                if (SecXPCDictionaryCopyDataOptional(event, kSecXPCKeyKeybag, &keybag, &error)) {
+                    if (SecXPCDictionaryCopyDataOptional(event, kSecXPCKeyUserPassword, &passcode, &error)) {
+                        CFDataRef backup = _SecServerKeychainBackup(keybag, passcode, &error);
+                        if (backup) {
+                            SecXPCDictionarySetData(replyMessage, kSecXPCKeyResult, backup, &error);
+                            CFRelease(backup);
+                        }
+                        CFReleaseSafe(passcode);
+                    }
+                    CFReleaseSafe(keybag);
                 }
                 }
+                break;
             }
             }
-            break;
-        case sec_restore_keychain_id:
-            op_name = "SecRestoreKeychain";
-            if (SecTaskGetBooleanValueForEntitlement(clientTask,
-                kSecEntitlementRestoreKeychain)) {
-                status = _SecServerRestoreKeychain();
-            } else {
-                status = errSecMissingEntitlement;
+            case sec_keychain_restore_id:
+            {
+                CFDataRef backup = SecXPCDictionaryCopyData(event, kSecXPCKeyBackup, &error);
+                if (backup) {
+                    CFDataRef keybag = SecXPCDictionaryCopyData(event, kSecXPCKeyKeybag, &error);
+                    if (keybag) {
+                        CFDataRef passcode = NULL;
+                        if (SecXPCDictionaryCopyDataOptional(event, kSecXPCKeyUserPassword, &passcode, &error)) {
+                            bool result = _SecServerKeychainRestore(backup, keybag, passcode, &error);
+                            xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result);
+                            CFReleaseSafe(passcode);
+                        }
+                        CFRelease(keybag);
+                    }
+                    CFRelease(backup);
+                }
+                break;
             }
             }
-            break;
-        case sec_migrate_keychain_id:
-            op_name = "SecMigrateKeychain";
-            if (isArray(args_in)) {
-                if (SecTaskGetBooleanValueForEntitlement(clientTask,
-                    kSecEntitlementMigrateKeychain)) {
-                    status = _SecServerMigrateKeychain(args_in, &args_out);
-                } else {
-                    status = errSecMissingEntitlement;
+            case sec_keychain_sync_update_id:
+            {
+                CFDictionaryRef updates = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyQuery, &error);
+                if (updates) {
+                    bool result = _SecServerKeychainSyncUpdate(updates, &error);
+                    xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result);
+                    CFRelease(updates);
                 }
                 }
+                break;
             }
             }
-            break;
-        case sec_keychain_backup_id:
-            op_name = "SecKeychainBackup";
-            if (!args_in || isArray(args_in)) {
-                if (SecTaskGetBooleanValueForEntitlement(clientTask,
-                    kSecEntitlementRestoreKeychain)) {
-                    status = _SecServerKeychainBackup(args_in, &args_out);
-                } else {
-                    status = errSecMissingEntitlement;
+            case sec_keychain_backup_syncable_id:
+            {
+                CFDictionaryRef oldbackup = NULL;
+                if (SecXPCDictionaryCopyDictionaryOptional(event, kSecXPCKeyBackup, &oldbackup, &error)) {
+                    CFDataRef keybag = SecXPCDictionaryCopyData(event, kSecXPCKeyKeybag, &error);
+                    if (keybag) {
+                        CFDataRef passcode = NULL;
+                        if (SecXPCDictionaryCopyDataOptional(event, kSecXPCKeyUserPassword, &passcode, &error)) {
+                            CFDictionaryRef newbackup = _SecServerBackupSyncable(oldbackup, keybag, passcode, &error);
+                            if (newbackup) {
+                                SecXPCDictionarySetPList(replyMessage, kSecXPCKeyResult, newbackup, &error);
+                                CFRelease(newbackup);
+                            }
+                            CFReleaseSafe(passcode);
+                        }
+                        CFRelease(keybag);
+                    }
+                    CFReleaseSafe(oldbackup);
                 }
                 }
+                break;
             }
             }
-            break;
-        case sec_keychain_restore_id:
-            op_name = "SecKeychainRestore";
-            if (isArray(args_in)) {
-                if (SecTaskGetBooleanValueForEntitlement(clientTask,
-                    kSecEntitlementRestoreKeychain)) {
-                    status = _SecServerKeychainRestore(args_in, &args_out);
-                } else {
-                    status = errSecMissingEntitlement;
+            case sec_keychain_restore_syncable_id:
+            {
+                CFDictionaryRef backup = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyBackup, &error);
+                if (backup) {
+                    CFDataRef keybag = SecXPCDictionaryCopyData(event, kSecXPCKeyKeybag, &error);
+                    if (keybag) {
+                        CFDataRef passcode = NULL;
+                        if (SecXPCDictionaryCopyDataOptional(event, kSecXPCKeyUserPassword, &passcode, &error)) {
+                            bool result = _SecServerRestoreSyncable(backup, keybag, passcode, &error);
+                            xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result);
+                            CFReleaseSafe(passcode);
+                        }
+                        CFRelease(keybag);
+                    }
+                    CFRelease(backup);
                 }
                 }
+                break;
             }
             }
-            break;
-        default:
-            op_name = "invalid_operation";
-            status = errSecParam;
-            break;
-    }
+            case sec_ota_pki_asset_version_id:
+                xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult,
+                                         SecOTAPKIGetCurrentAssetVersion(&error));
+                break;
+            case kSecXPCOpTryUserCredentials:
+                with_label_and_password(event, ^(CFStringRef label, CFDataRef password) {
+                    xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
+                                            SOSCCTryUserCredentials_Server(label, password, &error));
+                });
+                break;
+            case kSecXPCOpSetUserCredentials:
+                with_label_and_password(event, ^(CFStringRef label, CFDataRef password) {
+                    xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
+                                            SOSCCSetUserCredentials_Server(label, password, &error));
+                });
+                break;
+            case kSecXPCOpCanAuthenticate:
+                xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
+                                        SOSCCCanAuthenticate_Server(&error));
+                break;
+            case kSecXPCOpPurgeUserCredentials:
+                xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
+                                        SOSCCPurgeUserCredentials_Server(&error));
+                break;
+            case kSecXPCOpDeviceInCircle:
+                xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult,
+                                         SOSCCThisDeviceIsInCircle_Server(&error));
+                break;
+            case kSecXPCOpRequestToJoin:
+                xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
+                                        SOSCCRequestToJoinCircle_Server(&error));
+                break;
+            case kSecXPCOpRequestToJoinAfterRestore:
+                xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
+                                        SOSCCRequestToJoinCircleAfterRestore_Server(&error));
+                break;
+            case kSecXPCOpResetToOffering:
+                xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
+                                        SOSCCResetToOffering_Server(&error));
+                break;
+            case kSecXPCOpResetToEmpty:
+                xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
+                                        SOSCCResetToEmpty_Server(&error));
+                break;
+            case kSecXPCOpRemoveThisDeviceFromCircle:
+                xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
+                                        SOSCCRemoveThisDeviceFromCircle_Server(&error));
+                break;
+            case kSecXPCOpBailFromCircle:
+                {
+                uint64_t limit_in_seconds = xpc_dictionary_get_uint64(event, kSecXPCLimitInMinutes);
+                xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
+                                        SOSCCBailFromCircle_Server(limit_in_seconds, &error));
+                }
+                break;
+            case kSecXPCOpAcceptApplicants:
+                {
+                    xpc_object_t xapplicants = xpc_dictionary_get_value(event, kSecXPCKeyPeerInfos);
+                    CFArrayRef applicants = CreateArrayOfPeerInfoWithXPCObject(xapplicants, &error); //(CFArrayRef)(_CFXPCCreateCFObjectFromXPCObject(xapplicants));
+                    xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
+                                            (applicants && SOSCCAcceptApplicants_Server(applicants, &error)));
+                    CFReleaseSafe(applicants);
+                }
+                break;
+            case kSecXPCOpRejectApplicants:
+                {
+                    xpc_object_t xapplicants = xpc_dictionary_get_value(event, kSecXPCKeyPeerInfos);
+                    CFArrayRef applicants = CreateArrayOfPeerInfoWithXPCObject(xapplicants, &error); //(CFArrayRef)(_CFXPCCreateCFObjectFromXPCObject(xapplicants));
+                    xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
+                                            (applicants && SOSCCRejectApplicants_Server(applicants, &error)));
+                    CFReleaseSafe(applicants);
+                }
+                break;
+            case kSecXPCOpCopyApplicantPeerInfo:
+                {
+                    CFArrayRef array = SOSCCCopyApplicantPeerInfo_Server(&error);
+                    if (array) {
+                        xpc_object_t xpc_array = CreateXPCObjectWithArrayOfPeerInfo(array, &error);
+                        xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_array);
+                        xpc_release(xpc_array);
+                    }
+                    CFReleaseNull(array);
+                }
+                break;
+            case kSecXPCOpCopyPeerPeerInfo:
+                {
+                    CFArrayRef array = SOSCCCopyPeerPeerInfo_Server(&error);
+                    if (array) {
+                        xpc_object_t xpc_array = CreateXPCObjectWithArrayOfPeerInfo(array, &error);
+                        xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_array);
+                        xpc_release(xpc_array);
+                    }
+                    CFReleaseNull(array);
+                }
+                break;
+            case kSecXPCOpCopyConcurringPeerPeerInfo:
+                {
+                    CFArrayRef array = SOSCCCopyConcurringPeerPeerInfo_Server(&error);
+                    if (array) {
+                        xpc_object_t xpc_array = CreateXPCObjectWithArrayOfPeerInfo(array, &error);
+                        xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_array);
+                        xpc_release(xpc_array);
+                    }
+                    CFReleaseNull(array);
+                }
+                break;
+            case kSecXPCOpGetLastDepartureReason:
+                xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult,
+                                         SOSCCGetLastDepartureReason_Server(&error));
+                    break;
+            case kSecXPCOpProcessSyncWithAllPeers:
+                xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult,
+                                         SOSCCProcessSyncWithAllPeers_Server(&error));
+                    break;
+            case kSecXPCOpCopyIncompatibilityInfo:
+                xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
+                                        SOSCCCopyIncompatibilityInfo_Server(&error));
+                break;
+                       case kSecXPCOpOTAGetEscrowCertificates:
+                               {
+                                       CFArrayRef array = SecOTAPKICopyCurrentEscrowCertificates(&error);
+                                       if (array) {
+                                               xpc_object_t xpc_array = _CFXPCCreateXPCObjectFromCFObject(array);
+                                               xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_array);
+                           xpc_release(xpc_array);
+                                       }
+                                       CFReleaseNull(array);
+                               }
+                               break;
+                       case kSecXPCOpOTAPKIGetNewAsset:
+                                xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult,
+                                                SecOTAPKISignalNewAsset(&error));
+                               break;
+           default:
+                break;
+            }
+        }
 
 
-    const char *proc_name;
-#ifdef NDEBUG
-    if (status == errSecMissingEntitlement) {
-#endif
-        pid_t pid;
-        audit_token_to_au32(auditToken, NULL, NULL, NULL, NULL, NULL, &pid, NULL, NULL);
-        int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
-        struct kinfo_proc kp;
-        size_t len = sizeof(kp);
-        if (sysctl(mib, 4, &kp, &len, NULL, 0) == -1 || len == 0)
-            proc_name = strerror(errno);
-        else
-            proc_name = kp.kp_proc.p_comm;
-
-#ifndef NDEBUG
-    if (status == errSecMissingEntitlement) {
-#endif
-        asl_log(NULL, NULL, ASL_LEVEL_ERR,
-            "%s[%u] %s: missing entitlement", proc_name, pid, op_name);
-        /* Remap errSecMissingEntitlement -> errSecInteractionNotAllowed. */
-        status = errSecInteractionNotAllowed;
+        if (error)
+        {
+            if(SecErrorGetOSStatus(error) == errSecItemNotFound)
+                secdebug("ipc", "%@ %@ %@", clientTask, SOSCCGetOperationDescription((enum SecXPCOperation)operation), error);
+            else
+                secerror("%@ %@ %@", clientTask, SOSCCGetOperationDescription((enum SecXPCOperation)operation), error);
+           
+            xpcError = SecCreateXPCObjectWithCFError(error);
+            xpc_dictionary_set_value(replyMessage, kSecXPCKeyError, xpcError);
+        } else if (replyMessage) {
+            secdebug("ipc", "%@ %@ reponding %@", clientTask, SOSCCGetOperationDescription((enum SecXPCOperation)operation), replyMessage);
+        }
+    } else {
+        SecCFCreateErrorWithFormatAndArguments(kSecXPCErrorUnexpectedType, sSecXPCErrorDomain, NULL, &error, 0, CFSTR("Messages expect to be xpc dictionary, got: %@"), event);
+        secerror("%@: returning error: %@", clientTask, error);
+        xpcError = SecCreateXPCObjectWithCFError(error);
+        replyMessage = xpc_create_reply_with_format(event, "{%string: %value}", kSecXPCKeyError, xpcError);
     }
 
     }
 
-    secdebug("ipc", "%s[%u] %s: returning: %d", proc_name, pid, op_name,
-        status);
-
-    CFReleaseSafe(groups);
+    if (replyMessage) {
+        xpc_connection_send_message(connection, replyMessage);
+        xpc_release(replyMessage);
+    }
+    if (xpcError)
+        xpc_release(xpcError);
+    CFReleaseSafe(error);
+    CFReleaseSafe(accessGroups);
     CFReleaseSafe(clientTask);
     CFReleaseSafe(clientTask);
-    SecAccessGroupsSetCurrent(NULL);
-
-    kern_return_t err = 0;
-    if (sendResponse)
-        err = securityd_server_send_reply(reply, request_id, status, args_out);
-
-    CFReleaseSafe(args_in);
-
-    return err;
 }
 
 }
 
-extern boolean_t securityd_request_server(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP);
-
-union max_msg_size_union {
-    union __RequestUnion__securityd_client_securityd_reply_subsystem reply;
-};
-
-static uint8_t reply_buffer[sizeof(union max_msg_size_union) + MAX_TRAILER_SIZE];
-
-static void *handle_message(void *msg, CFIndex size,
-        CFAllocatorRef allocator, void *info)
+static void securityd_xpc_init()
 {
 {
-    mach_msg_header_t *message = (mach_msg_header_t *)msg;
-    mach_msg_header_t *reply = (mach_msg_header_t *)reply_buffer;
+    secdebug("serverxpc", "start");
 
 
-    securityd_request_server(message, reply);
-
-    return NULL;
-}
-
-
-static void register_server(void)
-{
-    CFRunLoopSourceContext1 context = { 1, NULL, NULL, NULL, NULL, NULL, NULL,
-        server_port, handle_message };
-    CFRunLoopSourceRef source = CFRunLoopSourceCreate(NULL, 0,
-        (CFRunLoopSourceContext *)&context);
-
-    if (!source) {
-        secdebug("server", "failed to create source for port, exiting.");
-        exit(1);
+    xpc_track_activity();
+    xpc_connection_t listener = xpc_connection_create_mach_service(kSecuritydXPCServiceName, NULL, XPC_CONNECTION_MACH_SERVICE_LISTENER);
+    if (!listener) {
+        seccritical("security failed to register xpc listener, exiting");
+        abort();
     }
     }
-    CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
-    CFRelease(source);
-}
 
 
+    xpc_connection_set_event_handler(listener, ^(xpc_object_t connection) {
+        if (xpc_get_type(connection) == XPC_TYPE_CONNECTION) {
+            xpc_connection_set_event_handler(connection, ^(xpc_object_t event) {
+                if (xpc_get_type(event) == XPC_TYPE_DICTIONARY) {
+                    xpc_retain(connection);
+                    xpc_retain(event);
+                    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+                        securityd_xpc_dictionary_handler(connection, event);
+                        xpc_release(event);
+                        xpc_release(connection);
+                    });
+                }
+            });
+            xpc_connection_resume(connection);
+        }
+    });
+    xpc_connection_resume(listener);
+}
 
 int main(int argc, char *argv[])
 {
 
 int main(int argc, char *argv[])
 {
-    securityd_init();
-    register_server();
-    register_timeout();
-    CFRunLoopRun();
+    char *wait4debugger = getenv("WAIT4DEBUGGER");
+    if (wait4debugger && !strcasecmp("YES", wait4debugger)) {
+               seccritical("SIGSTOPing self, awaiting debugger");
+               kill(getpid(), SIGSTOP);
+               asl_log(NULL, NULL, ASL_LEVEL_CRIT,
+                "Again, for good luck (or bad debuggers)");
+               kill(getpid(), SIGSTOP);
+       }
+
+    securityd_init_server();
+    securityd_xpc_init();
+    dispatch_main();
     return 0;
 }
 
     return 0;
 }
 
index 1ee3fd538186705d7423b86b182284e20deab04c..04ee7ed5501da9676d121592c5c34050fd90e1f2 100644 (file)
@@ -7,12 +7,18 @@
        objects = {
 
 /* Begin PBXBuildFile section */
        objects = {
 
 /* Begin PBXBuildFile section */
+               0C062B1F175E784B00806CFE /* secd-30-keychain-upgrade.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C062B1C175E784B00806CFE /* secd-30-keychain-upgrade.c */; };
+               0C062B20175E784B00806CFE /* secd-31-keychain-bad.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C062B1D175E784B00806CFE /* secd-31-keychain-bad.c */; };
+               0C062B21175E784B00806CFE /* secd-31-keychain-unreadable.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C062B1E175E784B00806CFE /* secd-31-keychain-unreadable.c */; };
+               0C0BDB611756882A00BC1A7E /* secd_regressions.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C0BDB601756882A00BC1A7E /* secd_regressions.h */; };
+               0C0BDB63175688DA00BC1A7E /* secd-01-items.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C0BDB62175688DA00BC1A7E /* secd-01-items.c */; };
+               0C664AE8175951270092D3D9 /* secd-02-upgrade-while-locked.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C664AE7175951270092D3D9 /* secd-02-upgrade-while-locked.c */; };
+               0CBF93F8177B7CFC001E5658 /* secd-03-corrupted-items.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CBF93F5177B7CFC001E5658 /* secd-03-corrupted-items.c */; };
+               0CBF93F9177B7CFC001E5658 /* secd-04-corrupted-items.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CBF93F6177B7CFC001E5658 /* secd-04-corrupted-items.c */; };
+               0CBF93FC177BA9D9001E5658 /* secd-05-corrupted-items.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CBF93FB177BA9D9001E5658 /* secd-05-corrupted-items.c */; };
+               0CE7ABDF171383E30088968F /* keychain_backup.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CE7ABDE171383E30088968F /* keychain_backup.c */; };
                18270F5914CF654400B05E7F /* client.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AD560614CB6E7A008233F2 /* client.c */; };
                18270F5914CF654400B05E7F /* client.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AD560614CB6E7A008233F2 /* client.c */; };
-               18270F5A14CF654400B05E7F /* securityd_rep.defs in Sources */ = {isa = PBXBuildFile; fileRef = 18AD560A14CB6E7A008233F2 /* securityd_rep.defs */; settings = {ATTRIBUTES = (Server, ); }; };
-               18270F5B14CF654400B05E7F /* securityd_req.defs in Sources */ = {isa = PBXBuildFile; fileRef = 18AD560B14CB6E7A008233F2 /* securityd_req.defs */; };
                18AD560F14CB6E7A008233F2 /* securityd_client.h in Headers */ = {isa = PBXBuildFile; fileRef = 18AD560814CB6E7A008233F2 /* securityd_client.h */; };
                18AD560F14CB6E7A008233F2 /* securityd_client.h in Headers */ = {isa = PBXBuildFile; fileRef = 18AD560814CB6E7A008233F2 /* securityd_client.h */; };
-               18AD561014CB6E7A008233F2 /* securityd_ipc_types.h in Headers */ = {isa = PBXBuildFile; fileRef = 18AD560914CB6E7A008233F2 /* securityd_ipc_types.h */; };
-               18AD561314CB6E7A008233F2 /* securityd_server.h in Headers */ = {isa = PBXBuildFile; fileRef = 18AD560C14CB6E7A008233F2 /* securityd_server.h */; };
                18AD566714CB70A8008233F2 /* SecItem.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AD563714CB6EB9008233F2 /* SecItem.c */; };
                18D4043914CE1FE400A2BE4E /* p12import.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AD561614CB6EB9008233F2 /* p12import.c */; };
                18D4043A14CE1FE400A2BE4E /* p12pbegen.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AD561814CB6EB9008233F2 /* p12pbegen.c */; };
                18AD566714CB70A8008233F2 /* SecItem.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AD563714CB6EB9008233F2 /* SecItem.c */; };
                18D4043914CE1FE400A2BE4E /* p12import.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AD561614CB6EB9008233F2 /* p12import.c */; };
                18D4043A14CE1FE400A2BE4E /* p12pbegen.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AD561814CB6EB9008233F2 /* p12pbegen.c */; };
                18D4044E14CE1FE400A2BE4E /* SecTrustSettings.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AD564F14CB6EB9008233F2 /* SecTrustSettings.c */; };
                18D4044F14CE1FE400A2BE4E /* SecTrustStore.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AD565214CB6EB9008233F2 /* SecTrustStore.c */; };
                18D4045014CE1FE400A2BE4E /* vmdh.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AD565514CB6EB9008233F2 /* vmdh.c */; };
                18D4044E14CE1FE400A2BE4E /* SecTrustSettings.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AD564F14CB6EB9008233F2 /* SecTrustSettings.c */; };
                18D4044F14CE1FE400A2BE4E /* SecTrustStore.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AD565214CB6EB9008233F2 /* SecTrustStore.c */; };
                18D4045014CE1FE400A2BE4E /* vmdh.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AD565514CB6EB9008233F2 /* vmdh.c */; };
-               18D4055C14CE51FC00A2BE4E /* debugging.h in Headers */ = {isa = PBXBuildFile; fileRef = 18D4055914CE51FC00A2BE4E /* debugging.h */; };
-               18D4055D14CE51FC00A2BE4E /* sqlutils.h in Headers */ = {isa = PBXBuildFile; fileRef = 18D4055A14CE51FC00A2BE4E /* sqlutils.h */; };
                18D4056614CE53DD00A2BE4E /* asynchttp.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AD567D14CB865E008233F2 /* asynchttp.c */; };
                18D4056614CE53DD00A2BE4E /* asynchttp.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AD567D14CB865E008233F2 /* asynchttp.c */; };
-               18D4056714CE53DD00A2BE4E /* keystore.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AD568014CB865E008233F2 /* keystore.c */; };
                18D4056814CE53DD00A2BE4E /* policytree.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AD568214CB865E008233F2 /* policytree.c */; };
                18D4056914CE53DD00A2BE4E /* SecCAIssuerCache.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AD568414CB865E008233F2 /* SecCAIssuerCache.c */; };
                18D4056A14CE53DD00A2BE4E /* SecCAIssuerRequest.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AD568614CB865E008233F2 /* SecCAIssuerRequest.c */; };
                18D4056814CE53DD00A2BE4E /* policytree.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AD568214CB865E008233F2 /* policytree.c */; };
                18D4056914CE53DD00A2BE4E /* SecCAIssuerCache.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AD568414CB865E008233F2 /* SecCAIssuerCache.c */; };
                18D4056A14CE53DD00A2BE4E /* SecCAIssuerRequest.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AD568614CB865E008233F2 /* SecCAIssuerRequest.c */; };
                18D4057014CE53DD00A2BE4E /* SecTrustServer.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AD566114CB6F79008233F2 /* SecTrustServer.c */; };
                18D4057114CE53DD00A2BE4E /* SecTrustStoreServer.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AD566314CB6F79008233F2 /* SecTrustStoreServer.c */; };
                18D4057214CE547400A2BE4E /* spi.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AD566514CB6F79008233F2 /* spi.c */; };
                18D4057014CE53DD00A2BE4E /* SecTrustServer.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AD566114CB6F79008233F2 /* SecTrustServer.c */; };
                18D4057114CE53DD00A2BE4E /* SecTrustStoreServer.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AD566314CB6F79008233F2 /* SecTrustStoreServer.c */; };
                18D4057214CE547400A2BE4E /* spi.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AD566514CB6F79008233F2 /* spi.c */; };
+               4802A59616D711060059E5B9 /* SOSUserKeygen.c in Sources */ = {isa = PBXBuildFile; fileRef = 4802A59516D711060059E5B9 /* SOSUserKeygen.c */; };
+               4802A59816D7156D0059E5B9 /* SOSUserKeygen.h in Headers */ = {isa = PBXBuildFile; fileRef = 4802A59716D711190059E5B9 /* SOSUserKeygen.h */; settings = {ATTRIBUTES = (); }; };
+               486C6C691795F9D600387075 /* secd-61-account-leave-not-in-kansas-anymore.c in Sources */ = {isa = PBXBuildFile; fileRef = 486C6C671795F20E00387075 /* secd-61-account-leave-not-in-kansas-anymore.c */; };
+               4882C517177521AE0095D04B /* secd-58-password-change.c in Sources */ = {isa = PBXBuildFile; fileRef = 4882C516177521AE0095D04B /* secd-58-password-change.c */; };
+               488902EC16C2F88400F119FF /* SOSCoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 488902EB16C2F88400F119FF /* SOSCoder.c */; };
+               4898223A17BDB277003BEF32 /* secd-52-account-changed.c in Sources */ = {isa = PBXBuildFile; fileRef = 4898223917BDB277003BEF32 /* secd-52-account-changed.c */; };
+               48CE733E1731C49A004C2946 /* sc-130-resignationticket.c in Sources */ = {isa = PBXBuildFile; fileRef = 48CE733D1731C49A004C2946 /* sc-130-resignationticket.c */; };
+               48E928C5179DD05500A7F755 /* secd-51-account-inflate.c in Sources */ = {isa = PBXBuildFile; fileRef = 48E928C4179DD05500A7F755 /* secd-51-account-inflate.c */; };
+               48F32D7E1777AFA3001B84BA /* secd-59-account-cleanup.c in Sources */ = {isa = PBXBuildFile; fileRef = 48F32D7D1777AFA3001B84BA /* secd-59-account-cleanup.c */; };
+               4A5CCA5415ACEFD400702357 /* SecOTRDHKey.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A971683158FDEB800D439B7 /* SecOTRDHKey.c */; };
+               4A5CCA5515ACEFD400702357 /* SecOTRFullIdentity.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A971686158FDEB800D439B7 /* SecOTRFullIdentity.c */; };
+               4A5CCA5615ACEFD400702357 /* SecOTRMath.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A971688158FDEB800D439B7 /* SecOTRMath.c */; };
+               4A5CCA5715ACEFD400702357 /* SecOTRPacketData.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A97168B158FDEB800D439B7 /* SecOTRPacketData.c */; };
+               4A5CCA5815ACEFD400702357 /* SecOTRPackets.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A97168D158FDEB800D439B7 /* SecOTRPackets.c */; };
+               4A5CCA5915ACEFD400702357 /* SecOTRPublicIdentity.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A97168F158FDEB800D439B7 /* SecOTRPublicIdentity.c */; };
+               4A5CCA5A15ACEFD400702357 /* SecOTRSession.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A971690158FDEB800D439B7 /* SecOTRSession.c */; };
+               4A5CCA5B15ACEFD400702357 /* SecOTRSessionAKE.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A971692158FDEB800D439B7 /* SecOTRSessionAKE.c */; };
+               4A5CCA5C15ACEFD400702357 /* SecOTRUtils.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A971694158FDEB800D439B7 /* SecOTRUtils.c */; };
+               4A971695158FDEB800D439B7 /* SecOTR.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A971682158FDEB800D439B7 /* SecOTR.h */; };
+               4A971696158FDEB800D439B7 /* SecOTRDHKey.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A971683158FDEB800D439B7 /* SecOTRDHKey.c */; };
+               4A971697158FDEB800D439B7 /* SecOTRDHKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A971684158FDEB800D439B7 /* SecOTRDHKey.h */; };
+               4A971698158FDEB800D439B7 /* SecOTRErrors.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A971685158FDEB800D439B7 /* SecOTRErrors.h */; };
+               4A971699158FDEB800D439B7 /* SecOTRFullIdentity.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A971686158FDEB800D439B7 /* SecOTRFullIdentity.c */; };
+               4A97169A158FDEB800D439B7 /* SecOTRIdentityPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A971687158FDEB800D439B7 /* SecOTRIdentityPriv.h */; };
+               4A97169B158FDEB800D439B7 /* SecOTRMath.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A971688158FDEB800D439B7 /* SecOTRMath.c */; };
+               4A97169C158FDEB800D439B7 /* SecOTRMath.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A971689158FDEB800D439B7 /* SecOTRMath.h */; };
+               4A97169D158FDEB800D439B7 /* SecOTRMathPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A97168A158FDEB800D439B7 /* SecOTRMathPrivate.h */; };
+               4A97169E158FDEB800D439B7 /* SecOTRPacketData.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A97168B158FDEB800D439B7 /* SecOTRPacketData.c */; };
+               4A97169F158FDEB800D439B7 /* SecOTRPacketData.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A97168C158FDEB800D439B7 /* SecOTRPacketData.h */; };
+               4A9716A0158FDEB800D439B7 /* SecOTRPackets.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A97168D158FDEB800D439B7 /* SecOTRPackets.c */; };
+               4A9716A1158FDEB800D439B7 /* SecOTRPackets.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A97168E158FDEB800D439B7 /* SecOTRPackets.h */; };
+               4A9716A2158FDEB800D439B7 /* SecOTRPublicIdentity.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A97168F158FDEB800D439B7 /* SecOTRPublicIdentity.c */; };
+               4A9716A3158FDEB800D439B7 /* SecOTRSession.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A971690158FDEB800D439B7 /* SecOTRSession.c */; };
+               4A9716A4158FDEB800D439B7 /* SecOTRSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A971691158FDEB800D439B7 /* SecOTRSession.h */; };
+               4A9716A5158FDEB800D439B7 /* SecOTRSessionAKE.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A971692158FDEB800D439B7 /* SecOTRSessionAKE.c */; };
+               4A9716A6158FDEB800D439B7 /* SecOTRSessionPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A971693158FDEB800D439B7 /* SecOTRSessionPriv.h */; };
+               4A9716A7158FDEB800D439B7 /* SecOTRUtils.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A971694158FDEB800D439B7 /* SecOTRUtils.c */; };
+               4AD6F6F21651C86200DB4CE6 /* libSecureObjectSync.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E702E75614E1F3EA00CDE635 /* libSecureObjectSync.a */; };
+               4C143CDE164D8EF5003035A3 /* sd-70-engine.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C143CDD164D8EF5003035A3 /* sd-70-engine.c */; };
+               4C1C452714EB27F50018B1D9 /* SOSTransport.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C1C452614EB27F50018B1D9 /* SOSTransport.c */; };
+               4C1C452A14EB28260018B1D9 /* SOSTransport.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C1C452914EB28260018B1D9 /* SOSTransport.h */; settings = {ATTRIBUTES = (); }; };
+               4C2C8C3D17AB374700C24C13 /* si-12-item-stress.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2C8C3C17AB374700C24C13 /* si-12-item-stress.c */; };
+               4C3CE9E7176005A700B521C2 /* SecuritydXPC.c in Sources */ = {isa = PBXBuildFile; fileRef = E7B01B8816572579000485F1 /* SecuritydXPC.c */; };
+               4C3CE9E8176005B500B521C2 /* SecuritydXPC.c in Sources */ = {isa = PBXBuildFile; fileRef = E7B01B8816572579000485F1 /* SecuritydXPC.c */; };
+               4C4EBD541610D7D8007D06A5 /* sc-75-circle-engine.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C4EBD531610D7D8007D06A5 /* sc-75-circle-engine.c */; };
+               4C5F2E38162DF76A00AF8346 /* SOSTestTransport.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C5F2E36162DE87F00AF8346 /* SOSTestTransport.c */; };
+               4C6ED19515CB0E44004379B7 /* sc-70-engine.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C6ED19415CB0E43004379B7 /* sc-70-engine.c */; };
+               4C6ED19615CB0E72004379B7 /* sc-30-peerinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = E777C72815B9C9F0004044A8 /* sc-30-peerinfo.c */; };
+               4C6ED19715CB0E72004379B7 /* sc-60-peer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C6ED19115CB0E26004379B7 /* sc-60-peer.c */; };
+               4C8940DB166EA8CF00241770 /* osxshim.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C8940DA166EA8CF00241770 /* osxshim.c */; };
+               4C8D8627177A71E80019A804 /* SOSCloudCircle.c in Sources */ = {isa = PBXBuildFile; fileRef = E7217B1715F80E0F00D26031 /* SOSCloudCircle.c */; };
+               4C8D8628177A71FB0019A804 /* SecPasswordGenerate.c in Sources */ = {isa = PBXBuildFile; fileRef = CDC765C01729A72800721712 /* SecPasswordGenerate.c */; };
+               4C9DC91A15B602760036D941 /* SOSEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C9DC91915B602760036D941 /* SOSEngine.h */; settings = {ATTRIBUTES = (); }; };
+               4C9DC91D15B602910036D941 /* SOSEngine.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C9DC91C15B602910036D941 /* SOSEngine.c */; };
+               4CB8A83816164B7700B52EC7 /* SOSTestDataSource.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CB8A83716164B7700B52EC7 /* SOSTestDataSource.c */; };
+               4CC07E26171E252300DCB6CE /* SOSCloudCircle.c in Sources */ = {isa = PBXBuildFile; fileRef = E7217B1715F80E0F00D26031 /* SOSCloudCircle.c */; };
+               4CC929B315A3957800C6D578 /* SOSAccount.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC929AD15A3957800C6D578 /* SOSAccount.c */; };
+               4CC929B415A3957800C6D578 /* SOSAccount.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CC929AE15A3957800C6D578 /* SOSAccount.h */; settings = {ATTRIBUTES = (); }; };
+               4CC929B515A3957800C6D578 /* SOSCircle.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC929AF15A3957800C6D578 /* SOSCircle.c */; };
+               4CC929B615A3957800C6D578 /* SOSCircle.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CC929B015A3957800C6D578 /* SOSCircle.h */; settings = {ATTRIBUTES = (); }; };
+               4CC929B715A3957800C6D578 /* SOSPeer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC929B115A3957800C6D578 /* SOSPeer.c */; };
+               4CC929B815A3957800C6D578 /* SOSPeer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CC929B215A3957800C6D578 /* SOSPeer.h */; settings = {ATTRIBUTES = (); }; };
+               4CC92A5F15A3ABD400C6D578 /* pbkdf2-00-hmac-sha1.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A0F15A3ABD400C6D578 /* pbkdf2-00-hmac-sha1.c */; };
+               4CC92A6015A3ABD400C6D578 /* spbkdf-00-hmac-sha1.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A1015A3ABD400C6D578 /* spbkdf-00-hmac-sha1.c */; };
+               4CC92A6115A3ABD400C6D578 /* otr-00-identity.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A1215A3ABD400C6D578 /* otr-00-identity.c */; };
+               4CC92A6215A3ABD400C6D578 /* otr-30-negotiation.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A1315A3ABD400C6D578 /* otr-30-negotiation.c */; };
+               4CC92A6315A3ABD400C6D578 /* otr-otrdh.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A1415A3ABD400C6D578 /* otr-otrdh.c */; };
+               4CC92A6415A3ABD400C6D578 /* otr-packetdata.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A1515A3ABD400C6D578 /* otr-packetdata.c */; };
+               4CC92A6515A3ABD400C6D578 /* si-00-find-nothing.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A1715A3ABD400C6D578 /* si-00-find-nothing.c */; };
+               4CC92A6615A3ABD400C6D578 /* si-05-add.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A1815A3ABD400C6D578 /* si-05-add.c */; };
+               4CC92A6715A3ABD400C6D578 /* si-10-find-internet.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A1915A3ABD400C6D578 /* si-10-find-internet.c */; };
+               4CC92A6815A3ABD400C6D578 /* si-11-update-data.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A1A15A3ABD400C6D578 /* si-11-update-data.c */; };
+               4CC92A6915A3ABD400C6D578 /* si-14-dateparse.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A1B15A3ABD400C6D578 /* si-14-dateparse.c */; };
+               4CC92A6A15A3ABD400C6D578 /* si-15-certificate.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A1C15A3ABD400C6D578 /* si-15-certificate.c */; };
+               4CC92A6B15A3ABD400C6D578 /* si-16-ec-certificate.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A1D15A3ABD400C6D578 /* si-16-ec-certificate.c */; };
+               4CC92A6C15A3ABD400C6D578 /* si-20-sectrust-activation.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A1E15A3ABD400C6D578 /* si-20-sectrust-activation.c */; };
+               4CC92A6D15A3ABD400C6D578 /* si-20-sectrust.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A1F15A3ABD400C6D578 /* si-20-sectrust.c */; };
+               4CC92A6E15A3ABD400C6D578 /* si-21-sectrust-asr.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A2015A3ABD400C6D578 /* si-21-sectrust-asr.c */; };
+               4CC92A6F15A3ABD400C6D578 /* si-22-sectrust-iap.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A2115A3ABD400C6D578 /* si-22-sectrust-iap.c */; };
+               4CC92A7015A3ABD400C6D578 /* si-23-sectrust-ocsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A2215A3ABD400C6D578 /* si-23-sectrust-ocsp.c */; };
+               4CC92A7115A3ABD400C6D578 /* si-24-sectrust-appleid.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A2315A3ABD400C6D578 /* si-24-sectrust-appleid.c */; };
+               4CC92A7215A3ABD400C6D578 /* si-24-sectrust-digicert-malaysia.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A2415A3ABD400C6D578 /* si-24-sectrust-digicert-malaysia.c */; };
+               4CC92A7315A3ABD400C6D578 /* si-24-sectrust-diginotar.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A2515A3ABD400C6D578 /* si-24-sectrust-diginotar.c */; };
+               4CC92A7415A3ABD400C6D578 /* si-24-sectrust-itms.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A2615A3ABD400C6D578 /* si-24-sectrust-itms.c */; };
+               4CC92A7515A3ABD400C6D578 /* si-24-sectrust-mobileasset.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A2715A3ABD400C6D578 /* si-24-sectrust-mobileasset.c */; };
+               4CC92A7615A3ABD400C6D578 /* si-24-sectrust-nist.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A2815A3ABD400C6D578 /* si-24-sectrust-nist.c */; };
+               4CC92A7715A3ABD400C6D578 /* si-24-sectrust-otatasking.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A2915A3ABD400C6D578 /* si-24-sectrust-otatasking.c */; };
+               4CC92A7815A3ABD400C6D578 /* si-24-sectrust-shoebox.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A2A15A3ABD400C6D578 /* si-24-sectrust-shoebox.c */; };
+               4CC92A7915A3ABD400C6D578 /* si-25-sectrust-ipsec-eap.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A2B15A3ABD400C6D578 /* si-25-sectrust-ipsec-eap.c */; };
+               4CC92A7A15A3ABD400C6D578 /* si-26-applicationsigning.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A2C15A3ABD400C6D578 /* si-26-applicationsigning.c */; };
+               4CC92A7B15A3ABD400C6D578 /* si-27-sectrust-exceptions.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A2D15A3ABD400C6D578 /* si-27-sectrust-exceptions.c */; };
+               4CC92A7C15A3ABD400C6D578 /* si-28-sectrustsettings.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A2E15A3ABD400C6D578 /* si-28-sectrustsettings.c */; };
+               4CC92A7D15A3ABD400C6D578 /* si-29-sectrust-codesigning.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A2F15A3ABD400C6D578 /* si-29-sectrust-codesigning.c */; };
+               4CC92A7E15A3ABD400C6D578 /* si-30-keychain-upgrade.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A3015A3ABD400C6D578 /* si-30-keychain-upgrade.c */; };
+               4CC92A7F15A3ABD400C6D578 /* si-31-keychain-bad.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A3115A3ABD400C6D578 /* si-31-keychain-bad.c */; };
+               4CC92A8015A3ABD400C6D578 /* si-31-keychain-unreadable.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A3215A3ABD400C6D578 /* si-31-keychain-unreadable.c */; };
+               4CC92A8215A3ABD400C6D578 /* si-33-keychain-backup.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A3415A3ABD400C6D578 /* si-33-keychain-backup.c */; };
+               4CC92A8315A3ABD400C6D578 /* si-40-seckey-custom.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A3515A3ABD400C6D578 /* si-40-seckey-custom.c */; };
+               4CC92A8415A3ABD400C6D578 /* si-40-seckey.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A3615A3ABD400C6D578 /* si-40-seckey.c */; };
+               4CC92A8515A3ABD400C6D578 /* si-41-sececkey.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A3715A3ABD400C6D578 /* si-41-sececkey.c */; };
+               4CC92A8615A3ABD400C6D578 /* si-42-identity.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A3815A3ABD400C6D578 /* si-42-identity.c */; };
+               4CC92A8715A3ABD400C6D578 /* si-43-persistent.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A3915A3ABD400C6D578 /* si-43-persistent.c */; };
+               4CC92A8815A3ABD400C6D578 /* si-50-secrandom.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A3A15A3ABD400C6D578 /* si-50-secrandom.c */; };
+               4CC92A8915A3ABD400C6D578 /* si-60-cms.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A3B15A3ABD400C6D578 /* si-60-cms.c */; };
+               4CC92A8A15A3ABD400C6D578 /* si-61-pkcs12.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A3C15A3ABD400C6D578 /* si-61-pkcs12.c */; };
+               4CC92A8B15A3ABD400C6D578 /* si-62-csr.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A3D15A3ABD400C6D578 /* si-62-csr.c */; };
+               4CC92A8C15A3ABD400C6D578 /* getcacert-mdes.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CC92A3F15A3ABD400C6D578 /* getcacert-mdes.h */; };
+               4CC92A8D15A3ABD400C6D578 /* getcacert-mdesqa.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CC92A4015A3ABD400C6D578 /* getcacert-mdesqa.h */; };
+               4CC92A8E15A3ABD400C6D578 /* si-63-scep.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A4115A3ABD400C6D578 /* si-63-scep.c */; };
+               4CC92A8F15A3ABD400C6D578 /* si-63-scep.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CC92A4215A3ABD400C6D578 /* si-63-scep.h */; };
+               4CC92A9015A3ABD400C6D578 /* attached_no_data_signed_data.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CC92A4415A3ABD400C6D578 /* attached_no_data_signed_data.h */; };
+               4CC92A9115A3ABD400C6D578 /* attached_signed_data.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CC92A4515A3ABD400C6D578 /* attached_signed_data.h */; };
+               4CC92A9215A3ABD400C6D578 /* detached_content.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CC92A4615A3ABD400C6D578 /* detached_content.h */; };
+               4CC92A9315A3ABD400C6D578 /* detached_signed_data.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CC92A4715A3ABD400C6D578 /* detached_signed_data.h */; };
+               4CC92A9415A3ABD400C6D578 /* privkey.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CC92A4815A3ABD400C6D578 /* privkey.h */; };
+               4CC92A9515A3ABD400C6D578 /* signer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CC92A4915A3ABD400C6D578 /* signer.h */; };
+               4CC92A9615A3ABD400C6D578 /* si-64-ossl-cms.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A4A15A3ABD400C6D578 /* si-64-ossl-cms.c */; };
+               4CC92A9715A3ABD400C6D578 /* si-65-cms-cert-policy.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A4B15A3ABD400C6D578 /* si-65-cms-cert-policy.c */; };
+               4CC92A9815A3ABD400C6D578 /* signed-receipt.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CC92A4D15A3ABD400C6D578 /* signed-receipt.h */; };
+               4CC92A9915A3ABD400C6D578 /* si-66-smime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A4E15A3ABD400C6D578 /* si-66-smime.c */; };
+               4CC92A9A15A3ABD400C6D578 /* Global Trustee.cer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CC92A5015A3ABD400C6D578 /* Global Trustee.cer.h */; };
+               4CC92A9B15A3ABD400C6D578 /* UTN-USERFirst-Hardware.cer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CC92A5115A3ABD400C6D578 /* UTN-USERFirst-Hardware.cer.h */; };
+               4CC92A9C15A3ABD400C6D578 /* addons.mozilla.org.cer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CC92A5215A3ABD400C6D578 /* addons.mozilla.org.cer.h */; };
+               4CC92A9D15A3ABD400C6D578 /* login.live.com.cer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CC92A5315A3ABD400C6D578 /* login.live.com.cer.h */; };
+               4CC92A9E15A3ABD400C6D578 /* login.skype.com.cer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CC92A5415A3ABD400C6D578 /* login.skype.com.cer.h */; };
+               4CC92A9F15A3ABD400C6D578 /* login.yahoo.com.1.cer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CC92A5515A3ABD400C6D578 /* login.yahoo.com.1.cer.h */; };
+               4CC92AA015A3ABD400C6D578 /* login.yahoo.com.2.cer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CC92A5615A3ABD400C6D578 /* login.yahoo.com.2.cer.h */; };
+               4CC92AA115A3ABD400C6D578 /* login.yahoo.com.cer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CC92A5715A3ABD400C6D578 /* login.yahoo.com.cer.h */; };
+               4CC92AA215A3ABD400C6D578 /* mail.google.com.cer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CC92A5815A3ABD400C6D578 /* mail.google.com.cer.h */; };
+               4CC92AA315A3ABD400C6D578 /* www.google.com.cer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CC92A5915A3ABD400C6D578 /* www.google.com.cer.h */; };
+               4CC92AA415A3ABD400C6D578 /* si-67-sectrust-blacklist.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A5A15A3ABD400C6D578 /* si-67-sectrust-blacklist.c */; };
+               4CC92AA515A3ABD400C6D578 /* vmdh-40.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A5C15A3ABD400C6D578 /* vmdh-40.c */; };
+               4CC92AA615A3ABD400C6D578 /* vmdh-41-example.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A5D15A3ABD400C6D578 /* vmdh-41-example.c */; };
+               4CC92AA715A3ABD400C6D578 /* vmdh-42-example2.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92A5E15A3ABD400C6D578 /* vmdh-42-example2.c */; };
+               4CC92AC015A3BC4300C6D578 /* Security_regressions.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CC92AB015A3AD0000C6D578 /* Security_regressions.h */; };
+               4CC92AC115A3BC4D00C6D578 /* SOSCircle_regressions.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CC92AAF15A3ACE600C6D578 /* SOSCircle_regressions.h */; };
+               4CC92AF915A3BC6B00C6D578 /* sd-10-policytree.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC92AAC15A3AC4600C6D578 /* sd-10-policytree.c */; };
+               4CC92B1515A3BCA500C6D578 /* securityd_regressions.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CC92AAE15A3ACCE00C6D578 /* securityd_regressions.h */; };
+               4CD1897D169F835400BC96B8 /* print_cert.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CD1897B169F835400BC96B8 /* print_cert.c */; };
+               5214701B16977D7700DF0DB3 /* cloudkeychainproxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 521C0BB315FA5E3F00604B61 /* cloudkeychainproxy.m */; };
+               521C0A7615F908AF00604B61 /* sc-90-ckdclient.c in Sources */ = {isa = PBXBuildFile; fileRef = 521C0A7315F908A700604B61 /* sc-90-ckdclient.c */; };
+               521C0C8715FEB03300604B61 /* sc-120-cloudcircle.c in Sources */ = {isa = PBXBuildFile; fileRef = 521C0C8615FEB03300604B61 /* sc-120-cloudcircle.c */; };
+               521C0CD615FF9B3300604B61 /* SOSRegressionUtilities.c in Sources */ = {isa = PBXBuildFile; fileRef = 521C0CD515FF9B3300604B61 /* SOSRegressionUtilities.c */; };
+               521C0CDD15FFA05100604B61 /* CKDKeyValueStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 521C0CD915FFA05000604B61 /* CKDKeyValueStore.h */; };
+               521C68601614A6E100E31C3E /* SOSCloudKeychainClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 521C685D1614A6E100E31C3E /* SOSCloudKeychainClient.h */; settings = {ATTRIBUTES = (); }; };
+               521C691F16164B9900E31C3E /* sc-95-ckd2client.c in Sources */ = {isa = PBXBuildFile; fileRef = 521C691E16164B9900E31C3E /* sc-95-ckd2client.c */; };
+               522B0ED21648809300A4675D /* sc-103-syncupdate.c in Sources */ = {isa = PBXBuildFile; fileRef = 522B0ED11648809300A4675D /* sc-103-syncupdate.c */; };
+               5253946116608F6800BA9687 /* sc-51-persistentEC.c in Sources */ = {isa = PBXBuildFile; fileRef = 5253946016608F6800BA9687 /* sc-51-persistentEC.c */; };
+               525394AE1660A30000BA9687 /* SecDbItem.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C4B15931655ED9000734590 /* SecDbItem.c */; };
+               52840281163F2B060035F320 /* sc-102-cfusernotification.c in Sources */ = {isa = PBXBuildFile; fileRef = 52840280163F2B060035F320 /* sc-102-cfusernotification.c */; };
+               528402AE164446410035F320 /* CKDKVSProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 521C0BB015FA5E3F00604B61 /* CKDKVSProxy.m */; };
+               528402AF164446410035F320 /* CKDPersistentState.m in Sources */ = {isa = PBXBuildFile; fileRef = 521C0BB215FA5E3F00604B61 /* CKDPersistentState.m */; };
+               528402B1164446410035F320 /* CKDUserInteraction.m in Sources */ = {isa = PBXBuildFile; fileRef = 52840292164050C80035F320 /* CKDUserInteraction.m */; };
+               528402B2164447610035F320 /* SOSCloudKeychainConstants.c in Sources */ = {isa = PBXBuildFile; fileRef = E7217B2515F8131A00D26031 /* SOSCloudKeychainConstants.c */; };
+               52AF7083163D9AA20092A7ED /* sc-101-accountsync.c in Sources */ = {isa = PBXBuildFile; fileRef = 52AF7082163D9AA20092A7ED /* sc-101-accountsync.c */; };
+               52D0F028169CA72800F07D79 /* SecOnOSX.h in Headers */ = {isa = PBXBuildFile; fileRef = 52D0F026169CA72800F07D79 /* SecOnOSX.h */; };
+               52DEE9E2162DC8F1002F3BCD /* sc-100-devicecircle.c in Sources */ = {isa = PBXBuildFile; fileRef = 52DEE9E1162DC8F1002F3BCD /* sc-100-devicecircle.c */; };
+               52EAF4BE163C52EB00803D0F /* SOSCloudKeychainClient.c in Sources */ = {isa = PBXBuildFile; fileRef = 521C685C1614A6E100E31C3E /* SOSCloudKeychainClient.c */; };
+               5DE4A7BD17441CCD0036339E /* si-71-mobile-store-policy.c in Sources */ = {isa = PBXBuildFile; fileRef = 5DE4A7BC17441CCD0036339E /* si-71-mobile-store-policy.c */; };
+               7249E1CB16C01E5F003D7268 /* OTATrustUtilities.c in Sources */ = {isa = PBXBuildFile; fileRef = 72E2DC0616BC47C800E7B236 /* OTATrustUtilities.c */; };
+               7255A46C1783333D006A8B9A /* si-74-OTAPKISigner.c in Sources */ = {isa = PBXBuildFile; fileRef = 7255A46B1783333D006A8B9A /* si-74-OTAPKISigner.c */; };
+               7255F91417A973D5004A9F38 /* si-75-AppleIDRecordSigning.c in Sources */ = {isa = PBXBuildFile; fileRef = 7255F91317A973D5004A9F38 /* si-75-AppleIDRecordSigning.c */; };
+               BE62D7601747FF3E001EAA9D /* si-72-syncableitems.c in Sources */ = {isa = PBXBuildFile; fileRef = BE62D75F1747FF3E001EAA9D /* si-72-syncableitems.c */; };
+               BE62D7621747FF51001EAA9D /* si-70-sectrust-unified.c in Sources */ = {isa = PBXBuildFile; fileRef = BE62D7611747FF51001EAA9D /* si-70-sectrust-unified.c */; };
                BEFE994E14F2E17200356A97 /* SecDH.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AD562A14CB6EB9008233F2 /* SecDH.c */; };
                BEFE994E14F2E17200356A97 /* SecDH.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AD562A14CB6EB9008233F2 /* SecDH.c */; };
+               CD3FD10716C3064B00A83BB6 /* SecuritydXPC.c in Sources */ = {isa = PBXBuildFile; fileRef = E7B01B8816572579000485F1 /* SecuritydXPC.c */; };
+               CDC765C21729A72800721712 /* SecPasswordGenerate.c in Sources */ = {isa = PBXBuildFile; fileRef = CDC765C01729A72800721712 /* SecPasswordGenerate.c */; };
+               CDC765C41729A72800721712 /* SecPasswordGenerate.h in Headers */ = {isa = PBXBuildFile; fileRef = CDC765C11729A72800721712 /* SecPasswordGenerate.h */; };
+               CDD565A2173193AC00B6B074 /* si-73-secpasswordgenerate.c in Sources */ = {isa = PBXBuildFile; fileRef = CDD565A1173193AC00B6B074 /* si-73-secpasswordgenerate.c */; };
+               E703811514E1FEEF007CB458 /* SOSCloudCircle.h in Headers */ = {isa = PBXBuildFile; fileRef = E703811114E1FEE4007CB458 /* SOSCloudCircle.h */; };
+               E71049F3169E023B00DB0045 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 521C0B9815FA5C4A00604B61 /* Foundation.framework */; };
+               E7104A01169E036E00DB0045 /* SecurityTool.c in Sources */ = {isa = PBXBuildFile; fileRef = E71049FF169E036E00DB0045 /* SecurityTool.c */; };
+               E7104A18169E216E00DB0045 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 521C0B9815FA5C4A00604B61 /* Foundation.framework */; };
+               E7217B2715F8131A00D26031 /* SOSCloudKeychainConstants.c in Sources */ = {isa = PBXBuildFile; fileRef = E7217B2515F8131A00D26031 /* SOSCloudKeychainConstants.c */; };
+               E7217B2815F8131A00D26031 /* SOSCloudKeychainConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = E7217B2615F8131A00D26031 /* SOSCloudKeychainConstants.h */; settings = {ATTRIBUTES = (); }; };
+               E748744515A61AF800624935 /* si-68-secmatchissuer.c in Sources */ = {isa = PBXBuildFile; fileRef = E748744415A61AF800624935 /* si-68-secmatchissuer.c */; };
+               E763D6231624E2670038477D /* sc-20-keynames.c in Sources */ = {isa = PBXBuildFile; fileRef = E763D6221624E2670038477D /* sc-20-keynames.c */; };
+               E777C6B115B4DDF2004044A8 /* sc-40-circle.c in Sources */ = {isa = PBXBuildFile; fileRef = E777C6B015B4DDF2004044A8 /* sc-40-circle.c */; };
+               E777C71C15B73F59004044A8 /* SOSInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = E777C71B15B73F59004044A8 /* SOSInternal.h */; settings = {ATTRIBUTES = (); }; };
+               E777C71E15B73F9E004044A8 /* SOSInternal.c in Sources */ = {isa = PBXBuildFile; fileRef = E777C71D15B73F9E004044A8 /* SOSInternal.c */; };
+               E777C72615B87545004044A8 /* SOSPeerInfo.c in Sources */ = {isa = PBXBuildFile; fileRef = E777C72515B87544004044A8 /* SOSPeerInfo.c */; };
+               E777C72715B882E5004044A8 /* SOSPeerInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = E777C72415B87528004044A8 /* SOSPeerInfo.h */; settings = {ATTRIBUTES = (); }; };
+               E790C10A169E4FD200E0C0C9 /* digest_calc.c in Sources */ = {isa = PBXBuildFile; fileRef = E790C109169E4FD200E0C0C9 /* digest_calc.c */; };
+               E790C110169E53DF00E0C0C9 /* leaks.c in Sources */ = {isa = PBXBuildFile; fileRef = E790C10E169E53DF00E0C0C9 /* leaks.c */; };
+               E790C141169E5C6200E0C0C9 /* add_internet_password.c in Sources */ = {isa = PBXBuildFile; fileRef = E790C136169E5C6200E0C0C9 /* add_internet_password.c */; };
+               E790C142169E5C6200E0C0C9 /* codesign.c in Sources */ = {isa = PBXBuildFile; fileRef = E790C137169E5C6200E0C0C9 /* codesign.c */; };
+               E790C143169E5C6200E0C0C9 /* keychain_add.c in Sources */ = {isa = PBXBuildFile; fileRef = E790C138169E5C6200E0C0C9 /* keychain_add.c */; };
+               E790C144169E5C6200E0C0C9 /* keychain_find.c in Sources */ = {isa = PBXBuildFile; fileRef = E790C139169E5C6200E0C0C9 /* keychain_find.c */; };
+               E790C145169E5C6200E0C0C9 /* pkcs12_util.c in Sources */ = {isa = PBXBuildFile; fileRef = E790C13A169E5C6200E0C0C9 /* pkcs12_util.c */; };
+               E790C147169E5C6200E0C0C9 /* scep.c in Sources */ = {isa = PBXBuildFile; fileRef = E790C13D169E5C6200E0C0C9 /* scep.c */; };
+               E790C148169E5C6200E0C0C9 /* show_certificates.c in Sources */ = {isa = PBXBuildFile; fileRef = E790C13F169E5C6200E0C0C9 /* show_certificates.c */; };
+               E790C149169E5C6200E0C0C9 /* spc.c in Sources */ = {isa = PBXBuildFile; fileRef = E790C140169E5C6200E0C0C9 /* spc.c */; };
+               E79277E3163B110A0096F3E2 /* SOSFullPeerInfo.c in Sources */ = {isa = PBXBuildFile; fileRef = E79277E1163B110A0096F3E2 /* SOSFullPeerInfo.c */; };
+               E79277E4163B110A0096F3E2 /* SOSFullPeerInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = E79277E2163B110A0096F3E2 /* SOSFullPeerInfo.h */; settings = {ATTRIBUTES = (); }; };
+               E79D62BB176798FD005A9743 /* secd-50-account.c in Sources */ = {isa = PBXBuildFile; fileRef = E79D62B9176798BF005A9743 /* secd-50-account.c */; };
+               E79D62BC176799DB005A9743 /* SOSRegressionUtilities.c in Sources */ = {isa = PBXBuildFile; fileRef = 521C0CD515FF9B3300604B61 /* SOSRegressionUtilities.c */; };
+               E79D62BD176799EE005A9743 /* SOSTestDataSource.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CB8A83716164B7700B52EC7 /* SOSTestDataSource.c */; };
+               E79D62C01767A5BC005A9743 /* SecdTestKeychainUtilities.c in Sources */ = {isa = PBXBuildFile; fileRef = E79D62BE1767A547005A9743 /* SecdTestKeychainUtilities.c */; };
+               E7A10FAC1771246A00C4602F /* secd-55-account-circle.c in Sources */ = {isa = PBXBuildFile; fileRef = E7A10FAB1771246A00C4602F /* secd-55-account-circle.c */; };
+               E7A10FAE1771249C00C4602F /* secd-57-account-leave.c in Sources */ = {isa = PBXBuildFile; fileRef = E7A10FAD1771249C00C4602F /* secd-57-account-leave.c */; };
+               E7B01B5B16532507000485F1 /* SOSCloudCircleInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = E7B01B5A16532507000485F1 /* SOSCloudCircleInternal.h */; settings = {ATTRIBUTES = (); }; };
+               E7B01B691655DF20000485F1 /* SOSCloudCircleServer.c in Sources */ = {isa = PBXBuildFile; fileRef = E7B01B671655CCA6000485F1 /* SOSCloudCircleServer.c */; };
+               E7BE10A7167AB32300D2A178 /* sc-41-cloudcircle.c in Sources */ = {isa = PBXBuildFile; fileRef = E7BE10A5167AB2BF00D2A178 /* sc-41-cloudcircle.c */; };
+               E7CA197A17179EC20065299C /* si-69-keydesc.c in Sources */ = {isa = PBXBuildFile; fileRef = CDA7729616B899F10069434D /* si-69-keydesc.c */; };
+               E7F0D3EA177BBE35001ACBC1 /* secd-55-account-incompatibility.c in Sources */ = {isa = PBXBuildFile; fileRef = E7F0D3E9177BBE35001ACBC1 /* secd-55-account-incompatibility.c */; };
+               E7F18555177A44E000177B23 /* secd-60-account-cloud-identity.c in Sources */ = {isa = PBXBuildFile; fileRef = E7F18554177A44E000177B23 /* secd-60-account-cloud-identity.c */; };
+               E7F18557177A502900177B23 /* secd-56-account-apply.c in Sources */ = {isa = PBXBuildFile; fileRef = E7F18556177A502900177B23 /* secd-56-account-apply.c */; };
+               E7FEFB87169E363300E18152 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 521C0B9815FA5C4A00604B61 /* Foundation.framework */; };
+               E7FEFB91169E36D800E18152 /* keychain_sync.c in Sources */ = {isa = PBXBuildFile; fileRef = E7FEFB90169E36D800E18152 /* keychain_sync.c */; };
 /* End PBXBuildFile section */
 
 /* End PBXBuildFile section */
 
+/* Begin PBXCopyFilesBuildPhase section */
+               5284029E164445760035F320 /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 2147483647;
+                       dstPath = "include/${PRODUCT_NAME}";
+                       dstSubfolderSpec = 16;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               E71049F0169E023B00DB0045 /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 2147483647;
+                       dstPath = "include/${PRODUCT_NAME}";
+                       dstSubfolderSpec = 16;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               E7104A19169E216E00DB0045 /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 2147483647;
+                       dstPath = "include/${PRODUCT_NAME}";
+                       dstSubfolderSpec = 16;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               E7FEFB88169E363300E18152 /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 2147483647;
+                       dstPath = "include/${PRODUCT_NAME}";
+                       dstSubfolderSpec = 16;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXCopyFilesBuildPhase section */
+
 /* Begin PBXFileReference section */
 /* Begin PBXFileReference section */
+               0C062B1C175E784B00806CFE /* secd-30-keychain-upgrade.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "secd-30-keychain-upgrade.c"; sourceTree = "<group>"; };
+               0C062B1D175E784B00806CFE /* secd-31-keychain-bad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "secd-31-keychain-bad.c"; sourceTree = "<group>"; };
+               0C062B1E175E784B00806CFE /* secd-31-keychain-unreadable.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "secd-31-keychain-unreadable.c"; sourceTree = "<group>"; };
+               0C0BDB5F175687EC00BC1A7E /* libsecdRegressions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecdRegressions.a; sourceTree = BUILT_PRODUCTS_DIR; };
+               0C0BDB601756882A00BC1A7E /* secd_regressions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = secd_regressions.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
+               0C0BDB62175688DA00BC1A7E /* secd-01-items.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "secd-01-items.c"; sourceTree = "<group>"; };
+               0C664AE7175951270092D3D9 /* secd-02-upgrade-while-locked.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 0; path = "secd-02-upgrade-while-locked.c"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.c; };
+               0CBF93F5177B7CFC001E5658 /* secd-03-corrupted-items.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "secd-03-corrupted-items.c"; sourceTree = "<group>"; };
+               0CBF93F6177B7CFC001E5658 /* secd-04-corrupted-items.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "secd-04-corrupted-items.c"; sourceTree = "<group>"; };
+               0CBF93FB177BA9D9001E5658 /* secd-05-corrupted-items.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "secd-05-corrupted-items.c"; sourceTree = "<group>"; };
+               0CE7ABDE171383E30088968F /* keychain_backup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = keychain_backup.c; sourceTree = "<group>"; };
                18270C9714CF1AAD00B05E7F /* base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = base.xcconfig; sourceTree = "<group>"; };
                18270C9814CF1AAD00B05E7F /* debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = debug.xcconfig; sourceTree = "<group>"; };
                18270C9914CF1AAD00B05E7F /* lib.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = lib.xcconfig; sourceTree = "<group>"; };
                18270C9714CF1AAD00B05E7F /* base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = base.xcconfig; sourceTree = "<group>"; };
                18270C9814CF1AAD00B05E7F /* debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = debug.xcconfig; sourceTree = "<group>"; };
                18270C9914CF1AAD00B05E7F /* lib.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = lib.xcconfig; sourceTree = "<group>"; };
                18AD560614CB6E7A008233F2 /* client.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = client.c; sourceTree = "<group>"; };
                18AD560714CB6E7A008233F2 /* com.apple.securityd.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.securityd.plist; sourceTree = "<group>"; };
                18AD560814CB6E7A008233F2 /* securityd_client.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = securityd_client.h; sourceTree = "<group>"; };
                18AD560614CB6E7A008233F2 /* client.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = client.c; sourceTree = "<group>"; };
                18AD560714CB6E7A008233F2 /* com.apple.securityd.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.securityd.plist; sourceTree = "<group>"; };
                18AD560814CB6E7A008233F2 /* securityd_client.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = securityd_client.h; sourceTree = "<group>"; };
-               18AD560914CB6E7A008233F2 /* securityd_ipc_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = securityd_ipc_types.h; sourceTree = "<group>"; };
-               18AD560A14CB6E7A008233F2 /* securityd_rep.defs */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.mig; path = securityd_rep.defs; sourceTree = "<group>"; };
-               18AD560B14CB6E7A008233F2 /* securityd_req.defs */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.mig; path = securityd_req.defs; sourceTree = "<group>"; };
-               18AD560C14CB6E7A008233F2 /* securityd_server.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = securityd_server.h; sourceTree = "<group>"; };
                18AD560D14CB6E7A008233F2 /* server.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = server.c; sourceTree = "<group>"; };
                18AD561514CB6EB9008233F2 /* certextensions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = certextensions.h; sourceTree = "<group>"; };
                18AD561614CB6EB9008233F2 /* p12import.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = p12import.c; sourceTree = "<group>"; };
                18AD560D14CB6E7A008233F2 /* server.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = server.c; sourceTree = "<group>"; };
                18AD561514CB6EB9008233F2 /* certextensions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = certextensions.h; sourceTree = "<group>"; };
                18AD561614CB6EB9008233F2 /* p12import.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = p12import.c; sourceTree = "<group>"; };
                18AD567D14CB865E008233F2 /* asynchttp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = asynchttp.c; sourceTree = "<group>"; };
                18AD567E14CB865E008233F2 /* asynchttp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = asynchttp.h; sourceTree = "<group>"; };
                18AD567F14CB865E008233F2 /* entitlements.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = entitlements.plist; sourceTree = "<group>"; };
                18AD567D14CB865E008233F2 /* asynchttp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = asynchttp.c; sourceTree = "<group>"; };
                18AD567E14CB865E008233F2 /* asynchttp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = asynchttp.h; sourceTree = "<group>"; };
                18AD567F14CB865E008233F2 /* entitlements.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = entitlements.plist; sourceTree = "<group>"; };
-               18AD568014CB865E008233F2 /* keystore.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = keystore.c; sourceTree = "<group>"; };
-               18AD568114CB865E008233F2 /* keystore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = keystore.h; sourceTree = "<group>"; };
                18AD568214CB865E008233F2 /* policytree.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = policytree.c; sourceTree = "<group>"; };
                18AD568314CB865E008233F2 /* policytree.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = policytree.h; sourceTree = "<group>"; };
                18AD568414CB865E008233F2 /* SecCAIssuerCache.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecCAIssuerCache.c; sourceTree = "<group>"; };
                18AD568514CB865E008233F2 /* SecCAIssuerCache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecCAIssuerCache.h; sourceTree = "<group>"; };
                18AD568614CB865E008233F2 /* SecCAIssuerRequest.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecCAIssuerRequest.c; sourceTree = "<group>"; };
                18AD568714CB865E008233F2 /* SecCAIssuerRequest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecCAIssuerRequest.h; sourceTree = "<group>"; };
                18AD568214CB865E008233F2 /* policytree.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = policytree.c; sourceTree = "<group>"; };
                18AD568314CB865E008233F2 /* policytree.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = policytree.h; sourceTree = "<group>"; };
                18AD568414CB865E008233F2 /* SecCAIssuerCache.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecCAIssuerCache.c; sourceTree = "<group>"; };
                18AD568514CB865E008233F2 /* SecCAIssuerCache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecCAIssuerCache.h; sourceTree = "<group>"; };
                18AD568614CB865E008233F2 /* SecCAIssuerRequest.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecCAIssuerRequest.c; sourceTree = "<group>"; };
                18AD568714CB865E008233F2 /* SecCAIssuerRequest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecCAIssuerRequest.h; sourceTree = "<group>"; };
-               18AD568814CB865E008233F2 /* SecItemServer.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecItemServer.c; sourceTree = "<group>"; };
+               18AD568814CB865E008233F2 /* SecItemServer.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; lineEnding = 0; path = SecItemServer.c; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.c; };
                18D4043514CE0CF300A2BE4E /* libsecurity.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurity.a; sourceTree = BUILT_PRODUCTS_DIR; };
                18D4043514CE0CF300A2BE4E /* libsecurity.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurity.a; sourceTree = BUILT_PRODUCTS_DIR; };
-               18D4055914CE51FC00A2BE4E /* debugging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debugging.h; sourceTree = "<group>"; };
-               18D4055A14CE51FC00A2BE4E /* sqlutils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sqlutils.h; sourceTree = "<group>"; };
                18D4056214CE53C200A2BE4E /* libsecurityd.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurityd.a; sourceTree = BUILT_PRODUCTS_DIR; };
                18D4056214CE53C200A2BE4E /* libsecurityd.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurityd.a; sourceTree = BUILT_PRODUCTS_DIR; };
+               4802A59516D711060059E5B9 /* SOSUserKeygen.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SOSUserKeygen.c; sourceTree = "<group>"; };
+               4802A59716D711190059E5B9 /* SOSUserKeygen.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSUserKeygen.h; sourceTree = "<group>"; };
+               485835871779013E0050F074 /* SOSPeerInfoInternal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSPeerInfoInternal.h; sourceTree = "<group>"; };
+               486C6C671795F20E00387075 /* secd-61-account-leave-not-in-kansas-anymore.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "secd-61-account-leave-not-in-kansas-anymore.c"; sourceTree = "<group>"; };
+               4882C516177521AE0095D04B /* secd-58-password-change.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "secd-58-password-change.c"; sourceTree = "<group>"; };
+               488902EB16C2F88400F119FF /* SOSCoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SOSCoder.c; sourceTree = "<group>"; };
+               488902ED16C2F89700F119FF /* SOSCoder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSCoder.h; sourceTree = "<group>"; };
+               4898223917BDB277003BEF32 /* secd-52-account-changed.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "secd-52-account-changed.c"; sourceTree = "<group>"; };
+               48CE733D1731C49A004C2946 /* sc-130-resignationticket.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "sc-130-resignationticket.c"; sourceTree = "<group>"; };
+               48E928C4179DD05500A7F755 /* secd-51-account-inflate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "secd-51-account-inflate.c"; sourceTree = "<group>"; };
+               48F32D7D1777AFA3001B84BA /* secd-59-account-cleanup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "secd-59-account-cleanup.c"; sourceTree = "<group>"; };
+               4A5CCA4F15ACEFA500702357 /* libSecOtrOSX.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSecOtrOSX.a; sourceTree = BUILT_PRODUCTS_DIR; };
+               4A824B03158FF07000F932C0 /* libSecurityRegressions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSecurityRegressions.a; sourceTree = BUILT_PRODUCTS_DIR; };
+               4A971682158FDEB800D439B7 /* SecOTR.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecOTR.h; sourceTree = "<group>"; };
+               4A971683158FDEB800D439B7 /* SecOTRDHKey.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SecOTRDHKey.c; path = ../../../SecOTRDHKey.c; sourceTree = "<group>"; };
+               4A971684158FDEB800D439B7 /* SecOTRDHKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecOTRDHKey.h; sourceTree = "<group>"; };
+               4A971685158FDEB800D439B7 /* SecOTRErrors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecOTRErrors.h; sourceTree = "<group>"; };
+               4A971686158FDEB800D439B7 /* SecOTRFullIdentity.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecOTRFullIdentity.c; sourceTree = "<group>"; };
+               4A971687158FDEB800D439B7 /* SecOTRIdentityPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecOTRIdentityPriv.h; sourceTree = "<group>"; };
+               4A971688158FDEB800D439B7 /* SecOTRMath.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecOTRMath.c; sourceTree = "<group>"; };
+               4A971689158FDEB800D439B7 /* SecOTRMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecOTRMath.h; sourceTree = "<group>"; };
+               4A97168A158FDEB800D439B7 /* SecOTRMathPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecOTRMathPrivate.h; sourceTree = "<group>"; };
+               4A97168B158FDEB800D439B7 /* SecOTRPacketData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecOTRPacketData.c; sourceTree = "<group>"; };
+               4A97168C158FDEB800D439B7 /* SecOTRPacketData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecOTRPacketData.h; sourceTree = "<group>"; };
+               4A97168D158FDEB800D439B7 /* SecOTRPackets.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecOTRPackets.c; sourceTree = "<group>"; };
+               4A97168E158FDEB800D439B7 /* SecOTRPackets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecOTRPackets.h; sourceTree = "<group>"; };
+               4A97168F158FDEB800D439B7 /* SecOTRPublicIdentity.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecOTRPublicIdentity.c; sourceTree = "<group>"; };
+               4A971690158FDEB800D439B7 /* SecOTRSession.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecOTRSession.c; sourceTree = "<group>"; };
+               4A971691158FDEB800D439B7 /* SecOTRSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecOTRSession.h; sourceTree = "<group>"; };
+               4A971692158FDEB800D439B7 /* SecOTRSessionAKE.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecOTRSessionAKE.c; sourceTree = "<group>"; };
+               4A971693158FDEB800D439B7 /* SecOTRSessionPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecOTRSessionPriv.h; sourceTree = "<group>"; };
+               4A971694158FDEB800D439B7 /* SecOTRUtils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecOTRUtils.c; sourceTree = "<group>"; };
+               4C143CDD164D8EF5003035A3 /* sd-70-engine.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "sd-70-engine.c"; sourceTree = "<group>"; };
+               4C1C452614EB27F50018B1D9 /* SOSTransport.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SOSTransport.c; sourceTree = "<group>"; };
+               4C1C452914EB28260018B1D9 /* SOSTransport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSTransport.h; sourceTree = "<group>"; };
+               4C2C8C3C17AB374700C24C13 /* si-12-item-stress.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-12-item-stress.c"; sourceTree = "<group>"; };
+               4C4B15931655ED9000734590 /* SecDbItem.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecDbItem.c; sourceTree = "<group>"; };
+               4C4B15951655EDA700734590 /* SecDbItem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecDbItem.h; sourceTree = "<group>"; };
+               4C4EBD531610D7D8007D06A5 /* sc-75-circle-engine.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "sc-75-circle-engine.c"; sourceTree = "<group>"; };
+               4C5EA365164C791400A136B8 /* lib-arc-only.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "lib-arc-only.xcconfig"; sourceTree = "<group>"; };
+               4C5F2E35162DE84E00AF8346 /* SOSTestTransport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSTestTransport.h; sourceTree = "<group>"; };
+               4C5F2E36162DE87F00AF8346 /* SOSTestTransport.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SOSTestTransport.c; sourceTree = "<group>"; };
+               4C6ED19115CB0E26004379B7 /* sc-60-peer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "sc-60-peer.c"; sourceTree = "<group>"; };
+               4C6ED19415CB0E43004379B7 /* sc-70-engine.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "sc-70-engine.c"; sourceTree = "<group>"; };
+               4C8940DA166EA8CF00241770 /* osxshim.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = osxshim.c; sourceTree = "<group>"; };
+               4C9DC91915B602760036D941 /* SOSEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSEngine.h; sourceTree = "<group>"; };
+               4C9DC91C15B602910036D941 /* SOSEngine.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SOSEngine.c; sourceTree = "<group>"; };
+               4CB8A83716164B7700B52EC7 /* SOSTestDataSource.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SOSTestDataSource.c; sourceTree = "<group>"; };
+               4CB8A83916164B8C00B52EC7 /* SOSTestDataSource.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSTestDataSource.h; sourceTree = "<group>"; };
+               4CC929AD15A3957800C6D578 /* SOSAccount.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SOSAccount.c; sourceTree = "<group>"; };
+               4CC929AE15A3957800C6D578 /* SOSAccount.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSAccount.h; sourceTree = "<group>"; };
+               4CC929AF15A3957800C6D578 /* SOSCircle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SOSCircle.c; sourceTree = "<group>"; };
+               4CC929B015A3957800C6D578 /* SOSCircle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSCircle.h; sourceTree = "<group>"; };
+               4CC929B115A3957800C6D578 /* SOSPeer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SOSPeer.c; sourceTree = "<group>"; };
+               4CC929B215A3957800C6D578 /* SOSPeer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSPeer.h; sourceTree = "<group>"; };
+               4CC92A0F15A3ABD400C6D578 /* pbkdf2-00-hmac-sha1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "pbkdf2-00-hmac-sha1.c"; sourceTree = "<group>"; };
+               4CC92A1015A3ABD400C6D578 /* spbkdf-00-hmac-sha1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "spbkdf-00-hmac-sha1.c"; sourceTree = "<group>"; };
+               4CC92A1215A3ABD400C6D578 /* otr-00-identity.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "otr-00-identity.c"; sourceTree = "<group>"; };
+               4CC92A1315A3ABD400C6D578 /* otr-30-negotiation.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "otr-30-negotiation.c"; sourceTree = "<group>"; };
+               4CC92A1415A3ABD400C6D578 /* otr-otrdh.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "otr-otrdh.c"; sourceTree = "<group>"; };
+               4CC92A1515A3ABD400C6D578 /* otr-packetdata.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "otr-packetdata.c"; sourceTree = "<group>"; };
+               4CC92A1715A3ABD400C6D578 /* si-00-find-nothing.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-00-find-nothing.c"; sourceTree = "<group>"; };
+               4CC92A1815A3ABD400C6D578 /* si-05-add.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-05-add.c"; sourceTree = "<group>"; };
+               4CC92A1915A3ABD400C6D578 /* si-10-find-internet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-10-find-internet.c"; sourceTree = "<group>"; };
+               4CC92A1A15A3ABD400C6D578 /* si-11-update-data.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-11-update-data.c"; sourceTree = "<group>"; };
+               4CC92A1B15A3ABD400C6D578 /* si-14-dateparse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-14-dateparse.c"; sourceTree = "<group>"; };
+               4CC92A1C15A3ABD400C6D578 /* si-15-certificate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-15-certificate.c"; sourceTree = "<group>"; };
+               4CC92A1D15A3ABD400C6D578 /* si-16-ec-certificate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-16-ec-certificate.c"; sourceTree = "<group>"; };
+               4CC92A1E15A3ABD400C6D578 /* si-20-sectrust-activation.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-20-sectrust-activation.c"; sourceTree = "<group>"; };
+               4CC92A1F15A3ABD400C6D578 /* si-20-sectrust.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-20-sectrust.c"; sourceTree = "<group>"; };
+               4CC92A2015A3ABD400C6D578 /* si-21-sectrust-asr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-21-sectrust-asr.c"; sourceTree = "<group>"; };
+               4CC92A2115A3ABD400C6D578 /* si-22-sectrust-iap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-22-sectrust-iap.c"; sourceTree = "<group>"; };
+               4CC92A2215A3ABD400C6D578 /* si-23-sectrust-ocsp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-23-sectrust-ocsp.c"; sourceTree = "<group>"; };
+               4CC92A2315A3ABD400C6D578 /* si-24-sectrust-appleid.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-24-sectrust-appleid.c"; sourceTree = "<group>"; };
+               4CC92A2415A3ABD400C6D578 /* si-24-sectrust-digicert-malaysia.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-24-sectrust-digicert-malaysia.c"; sourceTree = "<group>"; };
+               4CC92A2515A3ABD400C6D578 /* si-24-sectrust-diginotar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-24-sectrust-diginotar.c"; sourceTree = "<group>"; };
+               4CC92A2615A3ABD400C6D578 /* si-24-sectrust-itms.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-24-sectrust-itms.c"; sourceTree = "<group>"; };
+               4CC92A2715A3ABD400C6D578 /* si-24-sectrust-mobileasset.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-24-sectrust-mobileasset.c"; sourceTree = "<group>"; };
+               4CC92A2815A3ABD400C6D578 /* si-24-sectrust-nist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-24-sectrust-nist.c"; sourceTree = "<group>"; };
+               4CC92A2915A3ABD400C6D578 /* si-24-sectrust-otatasking.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-24-sectrust-otatasking.c"; sourceTree = "<group>"; };
+               4CC92A2A15A3ABD400C6D578 /* si-24-sectrust-shoebox.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-24-sectrust-shoebox.c"; sourceTree = "<group>"; };
+               4CC92A2B15A3ABD400C6D578 /* si-25-sectrust-ipsec-eap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-25-sectrust-ipsec-eap.c"; sourceTree = "<group>"; };
+               4CC92A2C15A3ABD400C6D578 /* si-26-applicationsigning.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-26-applicationsigning.c"; sourceTree = "<group>"; };
+               4CC92A2D15A3ABD400C6D578 /* si-27-sectrust-exceptions.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-27-sectrust-exceptions.c"; sourceTree = "<group>"; };
+               4CC92A2E15A3ABD400C6D578 /* si-28-sectrustsettings.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-28-sectrustsettings.c"; sourceTree = "<group>"; };
+               4CC92A2F15A3ABD400C6D578 /* si-29-sectrust-codesigning.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-29-sectrust-codesigning.c"; sourceTree = "<group>"; };
+               4CC92A3015A3ABD400C6D578 /* si-30-keychain-upgrade.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-30-keychain-upgrade.c"; sourceTree = "<group>"; };
+               4CC92A3115A3ABD400C6D578 /* si-31-keychain-bad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-31-keychain-bad.c"; sourceTree = "<group>"; };
+               4CC92A3215A3ABD400C6D578 /* si-31-keychain-unreadable.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-31-keychain-unreadable.c"; sourceTree = "<group>"; };
+               4CC92A3415A3ABD400C6D578 /* si-33-keychain-backup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-33-keychain-backup.c"; sourceTree = "<group>"; };
+               4CC92A3515A3ABD400C6D578 /* si-40-seckey-custom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-40-seckey-custom.c"; sourceTree = "<group>"; };
+               4CC92A3615A3ABD400C6D578 /* si-40-seckey.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-40-seckey.c"; sourceTree = "<group>"; };
+               4CC92A3715A3ABD400C6D578 /* si-41-sececkey.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-41-sececkey.c"; sourceTree = "<group>"; };
+               4CC92A3815A3ABD400C6D578 /* si-42-identity.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-42-identity.c"; sourceTree = "<group>"; };
+               4CC92A3915A3ABD400C6D578 /* si-43-persistent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-43-persistent.c"; sourceTree = "<group>"; };
+               4CC92A3A15A3ABD400C6D578 /* si-50-secrandom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-50-secrandom.c"; sourceTree = "<group>"; };
+               4CC92A3B15A3ABD400C6D578 /* si-60-cms.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-60-cms.c"; sourceTree = "<group>"; };
+               4CC92A3C15A3ABD400C6D578 /* si-61-pkcs12.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-61-pkcs12.c"; sourceTree = "<group>"; };
+               4CC92A3D15A3ABD400C6D578 /* si-62-csr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-62-csr.c"; sourceTree = "<group>"; };
+               4CC92A3F15A3ABD400C6D578 /* getcacert-mdes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "getcacert-mdes.h"; sourceTree = "<group>"; };
+               4CC92A4015A3ABD400C6D578 /* getcacert-mdesqa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "getcacert-mdesqa.h"; sourceTree = "<group>"; };
+               4CC92A4115A3ABD400C6D578 /* si-63-scep.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-63-scep.c"; sourceTree = "<group>"; };
+               4CC92A4215A3ABD400C6D578 /* si-63-scep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "si-63-scep.h"; sourceTree = "<group>"; };
+               4CC92A4415A3ABD400C6D578 /* attached_no_data_signed_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = attached_no_data_signed_data.h; sourceTree = "<group>"; };
+               4CC92A4515A3ABD400C6D578 /* attached_signed_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = attached_signed_data.h; sourceTree = "<group>"; };
+               4CC92A4615A3ABD400C6D578 /* detached_content.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = detached_content.h; sourceTree = "<group>"; };
+               4CC92A4715A3ABD400C6D578 /* detached_signed_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = detached_signed_data.h; sourceTree = "<group>"; };
+               4CC92A4815A3ABD400C6D578 /* privkey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = privkey.h; sourceTree = "<group>"; };
+               4CC92A4915A3ABD400C6D578 /* signer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = signer.h; sourceTree = "<group>"; };
+               4CC92A4A15A3ABD400C6D578 /* si-64-ossl-cms.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-64-ossl-cms.c"; sourceTree = "<group>"; };
+               4CC92A4B15A3ABD400C6D578 /* si-65-cms-cert-policy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-65-cms-cert-policy.c"; sourceTree = "<group>"; };
+               4CC92A4D15A3ABD400C6D578 /* signed-receipt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "signed-receipt.h"; sourceTree = "<group>"; };
+               4CC92A4E15A3ABD400C6D578 /* si-66-smime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-66-smime.c"; sourceTree = "<group>"; };
+               4CC92A5015A3ABD400C6D578 /* Global Trustee.cer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Global Trustee.cer.h"; sourceTree = "<group>"; };
+               4CC92A5115A3ABD400C6D578 /* UTN-USERFirst-Hardware.cer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UTN-USERFirst-Hardware.cer.h"; sourceTree = "<group>"; };
+               4CC92A5215A3ABD400C6D578 /* addons.mozilla.org.cer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = addons.mozilla.org.cer.h; sourceTree = "<group>"; };
+               4CC92A5315A3ABD400C6D578 /* login.live.com.cer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = login.live.com.cer.h; sourceTree = "<group>"; };
+               4CC92A5415A3ABD400C6D578 /* login.skype.com.cer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = login.skype.com.cer.h; sourceTree = "<group>"; };
+               4CC92A5515A3ABD400C6D578 /* login.yahoo.com.1.cer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = login.yahoo.com.1.cer.h; sourceTree = "<group>"; };
+               4CC92A5615A3ABD400C6D578 /* login.yahoo.com.2.cer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = login.yahoo.com.2.cer.h; sourceTree = "<group>"; };
+               4CC92A5715A3ABD400C6D578 /* login.yahoo.com.cer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = login.yahoo.com.cer.h; sourceTree = "<group>"; };
+               4CC92A5815A3ABD400C6D578 /* mail.google.com.cer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mail.google.com.cer.h; sourceTree = "<group>"; };
+               4CC92A5915A3ABD400C6D578 /* www.google.com.cer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = www.google.com.cer.h; sourceTree = "<group>"; };
+               4CC92A5A15A3ABD400C6D578 /* si-67-sectrust-blacklist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-67-sectrust-blacklist.c"; sourceTree = "<group>"; };
+               4CC92A5C15A3ABD400C6D578 /* vmdh-40.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "vmdh-40.c"; sourceTree = "<group>"; };
+               4CC92A5D15A3ABD400C6D578 /* vmdh-41-example.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "vmdh-41-example.c"; sourceTree = "<group>"; };
+               4CC92A5E15A3ABD400C6D578 /* vmdh-42-example2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "vmdh-42-example2.c"; sourceTree = "<group>"; };
+               4CC92AAC15A3AC4600C6D578 /* sd-10-policytree.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "sd-10-policytree.c"; sourceTree = "<group>"; };
+               4CC92AAE15A3ACCE00C6D578 /* securityd_regressions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = securityd_regressions.h; sourceTree = "<group>"; };
+               4CC92AAF15A3ACE600C6D578 /* SOSCircle_regressions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSCircle_regressions.h; sourceTree = "<group>"; };
+               4CC92AB015A3AD0000C6D578 /* Security_regressions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Security_regressions.h; path = Regressions/Security_regressions.h; sourceTree = "<group>"; };
+               4CC92B1415A3BC6B00C6D578 /* libsecuritydRegressions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecuritydRegressions.a; sourceTree = BUILT_PRODUCTS_DIR; };
+               4CD1897B169F835400BC96B8 /* print_cert.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = print_cert.c; sourceTree = "<group>"; };
+               4CD1897C169F835400BC96B8 /* print_cert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = print_cert.h; sourceTree = "<group>"; };
+               521C0A7315F908A700604B61 /* sc-90-ckdclient.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "sc-90-ckdclient.c"; sourceTree = "<group>"; };
+               521C0B9815FA5C4A00604B61 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+               521C0BA615FA5D7400604B61 /* cloudkeychain.entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = cloudkeychain.entitlements.plist; path = SOSCircle/CloudKeychainProxy/cloudkeychain.entitlements.plist; sourceTree = SOURCE_ROOT; };
+               521C0BAD15FA5DA800604B61 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = InfoPlist.strings; sourceTree = "<group>"; };
+               521C0BAF15FA5E3F00604B61 /* CKDKVSProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = CKDKVSProxy.h; path = SOSCircle/CloudKeychainProxy/CKDKVSProxy.h; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
+               521C0BB015FA5E3F00604B61 /* CKDKVSProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CKDKVSProxy.m; path = SOSCircle/CloudKeychainProxy/CKDKVSProxy.m; sourceTree = SOURCE_ROOT; };
+               521C0BB115FA5E3F00604B61 /* CKDPersistentState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CKDPersistentState.h; path = SOSCircle/CloudKeychainProxy/CKDPersistentState.h; sourceTree = SOURCE_ROOT; };
+               521C0BB215FA5E3F00604B61 /* CKDPersistentState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CKDPersistentState.m; path = SOSCircle/CloudKeychainProxy/CKDPersistentState.m; sourceTree = SOURCE_ROOT; };
+               521C0BB315FA5E3F00604B61 /* cloudkeychainproxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = cloudkeychainproxy.m; path = SOSCircle/CloudKeychainProxy/cloudkeychainproxy.m; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
+               521C0C8615FEB03300604B61 /* sc-120-cloudcircle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "sc-120-cloudcircle.c"; sourceTree = "<group>"; };
+               521C0CD515FF9B3300604B61 /* SOSRegressionUtilities.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SOSRegressionUtilities.c; sourceTree = "<group>"; };
+               521C0CD815FF9B4B00604B61 /* SOSRegressionUtilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSRegressionUtilities.h; sourceTree = "<group>"; };
+               521C0CD915FFA05000604B61 /* CKDKeyValueStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = CKDKeyValueStore.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
+               521C0CDA15FFA05000604B61 /* CKDKeyValueStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKDKeyValueStore.m; sourceTree = "<group>"; };
+               521C685C1614A6E100E31C3E /* SOSCloudKeychainClient.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 0; path = SOSCloudKeychainClient.c; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.c; };
+               521C685D1614A6E100E31C3E /* SOSCloudKeychainClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = SOSCloudKeychainClient.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
+               521C691E16164B9900E31C3E /* sc-95-ckd2client.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "sc-95-ckd2client.c"; sourceTree = "<group>"; };
+               522B0ED11648809300A4675D /* sc-103-syncupdate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "sc-103-syncupdate.c"; sourceTree = "<group>"; };
+               522B0ED31649A68E00A4675D /* MobileKeyBag.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileKeyBag.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.Internal.sdk/System/Library/PrivateFrameworks/MobileKeyBag.framework; sourceTree = DEVELOPER_DIR; };
+               5253946016608F6800BA9687 /* sc-51-persistentEC.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "sc-51-persistentEC.c"; sourceTree = "<group>"; };
+               526CBA5116079FB4008DF7C8 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = "../../build/Products/Debug-iphoneos/Security.framework"; sourceTree = "<group>"; };
+               5272501916838BB20029AADD /* CloudKeychainProxy.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = CloudKeychainProxy.1; sourceTree = "<group>"; };
+               52840280163F2B060035F320 /* sc-102-cfusernotification.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "sc-102-cfusernotification.c"; sourceTree = "<group>"; };
+               52840291164050C80035F320 /* CKDUserInteraction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CKDUserInteraction.h; path = SOSCircle/CloudKeychainProxy/CKDUserInteraction.h; sourceTree = SOURCE_ROOT; };
+               52840292164050C80035F320 /* CKDUserInteraction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CKDUserInteraction.m; path = SOSCircle/CloudKeychainProxy/CKDUserInteraction.m; sourceTree = SOURCE_ROOT; };
+               528402A0164445760035F320 /* libCloudKeychainProxy.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libCloudKeychainProxy.a; sourceTree = BUILT_PRODUCTS_DIR; };
+               52849FC2164498C9005CDF23 /* SOSARCDefines.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SOSARCDefines.h; path = SOSCircle/SOSARCDefines.h; sourceTree = SOURCE_ROOT; };
+               52AF7082163D9AA20092A7ED /* sc-101-accountsync.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "sc-101-accountsync.c"; sourceTree = "<group>"; };
+               52C3D18E169A53150091D9D3 /* ckdmain.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = ckdmain.m; path = SOSCircle/CloudKeychainProxy/ckdmain.m; sourceTree = SOURCE_ROOT; };
+               52D0F026169CA72800F07D79 /* SecOnOSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecOnOSX.h; sourceTree = "<group>"; };
+               52DD7069160CD40B0027A346 /* libutilities.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libutilities.a; path = ../../build/Release/libutilities.a; sourceTree = "<group>"; };
+               52DEE9E1162DC8F1002F3BCD /* sc-100-devicecircle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "sc-100-devicecircle.c"; sourceTree = "<group>"; };
+               5DE4A7BC17441CCD0036339E /* si-71-mobile-store-policy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-71-mobile-store-policy.c"; sourceTree = "<group>"; };
+               724D7363177A13A500FA10A1 /* AppleBaselineEscrowCertificates.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppleBaselineEscrowCertificates.h; sourceTree = "<group>"; };
+               7255A46B1783333D006A8B9A /* si-74-OTAPKISigner.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-74-OTAPKISigner.c"; sourceTree = "<group>"; };
+               7255F91317A973D5004A9F38 /* si-75-AppleIDRecordSigning.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-75-AppleIDRecordSigning.c"; sourceTree = "<group>"; };
+               72E2DC0616BC47C800E7B236 /* OTATrustUtilities.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = OTATrustUtilities.c; sourceTree = "<group>"; };
+               72E2DC0716BC47C800E7B236 /* OTATrustUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTATrustUtilities.h; sourceTree = "<group>"; };
+               BE62D75F1747FF3E001EAA9D /* si-72-syncableitems.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-72-syncableitems.c"; sourceTree = "<group>"; };
+               BE62D7611747FF51001EAA9D /* si-70-sectrust-unified.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-70-sectrust-unified.c"; sourceTree = "<group>"; };
+               CDA7729616B899F10069434D /* si-69-keydesc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-69-keydesc.c"; sourceTree = "<group>"; };
+               CDC765C01729A72800721712 /* SecPasswordGenerate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecPasswordGenerate.c; sourceTree = "<group>"; };
+               CDC765C11729A72800721712 /* SecPasswordGenerate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecPasswordGenerate.h; sourceTree = "<group>"; };
+               CDD565A1173193AC00B6B074 /* si-73-secpasswordgenerate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-73-secpasswordgenerate.c"; sourceTree = "<group>"; };
+               E702E75614E1F3EA00CDE635 /* libSecureObjectSync.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSecureObjectSync.a; sourceTree = BUILT_PRODUCTS_DIR; };
+               E702E77814E1F48800CDE635 /* libSOSRegressions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSOSRegressions.a; sourceTree = BUILT_PRODUCTS_DIR; };
+               E703811114E1FEE4007CB458 /* SOSCloudCircle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSCloudCircle.h; sourceTree = "<group>"; };
+               E71049F2169E023B00DB0045 /* libSecurityTool.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSecurityTool.a; sourceTree = BUILT_PRODUCTS_DIR; };
+               E71049FE169E036E00DB0045 /* security.1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.man; path = security.1; sourceTree = "<group>"; };
+               E71049FF169E036E00DB0045 /* SecurityTool.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecurityTool.c; sourceTree = "<group>"; };
+               E7104A00169E036E00DB0045 /* SecurityTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecurityTool.h; sourceTree = "<group>"; };
+               E7104A0D169E1C1600DB0045 /* tool_errors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tool_errors.h; sourceTree = "<group>"; };
+               E7104A1D169E216E00DB0045 /* libSecurityCommands.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSecurityCommands.a; sourceTree = BUILT_PRODUCTS_DIR; };
+               E7217B1715F80E0F00D26031 /* SOSCloudCircle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 0; path = SOSCloudCircle.c; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.c; };
+               E7217B2515F8131A00D26031 /* SOSCloudKeychainConstants.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 0; path = SOSCloudKeychainConstants.c; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.c; };
+               E7217B2615F8131A00D26031 /* SOSCloudKeychainConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSCloudKeychainConstants.h; sourceTree = "<group>"; };
+               E7295C6714E3571A007FBB20 /* Empty.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = Empty.c; sourceTree = "<group>"; };
+               E748744415A61AF800624935 /* si-68-secmatchissuer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-68-secmatchissuer.c"; sourceTree = "<group>"; };
+               E763D6221624E2670038477D /* sc-20-keynames.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "sc-20-keynames.c"; sourceTree = "<group>"; };
+               E777C6B015B4DDF2004044A8 /* sc-40-circle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "sc-40-circle.c"; sourceTree = "<group>"; };
+               E777C71B15B73F59004044A8 /* SOSInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSInternal.h; sourceTree = "<group>"; };
+               E777C71D15B73F9E004044A8 /* SOSInternal.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SOSInternal.c; sourceTree = "<group>"; };
+               E777C72415B87528004044A8 /* SOSPeerInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSPeerInfo.h; sourceTree = "<group>"; };
+               E777C72515B87544004044A8 /* SOSPeerInfo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SOSPeerInfo.c; sourceTree = "<group>"; };
+               E777C72815B9C9F0004044A8 /* sc-30-peerinfo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "sc-30-peerinfo.c"; sourceTree = "<group>"; };
+               E790C0F4169E3D7200E0C0C9 /* SOSCommands.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSCommands.h; sourceTree = "<group>"; };
+               E790C108169E4E7900E0C0C9 /* builtin_commands.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = builtin_commands.h; sourceTree = "<group>"; };
+               E790C109169E4FD200E0C0C9 /* digest_calc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = digest_calc.c; sourceTree = "<group>"; };
+               E790C10E169E53DF00E0C0C9 /* leaks.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = leaks.c; sourceTree = "<group>"; };
+               E790C10F169E53DF00E0C0C9 /* leaks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = leaks.h; sourceTree = "<group>"; };
+               E790C136169E5C6200E0C0C9 /* add_internet_password.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = add_internet_password.c; sourceTree = "<group>"; };
+               E790C137169E5C6200E0C0C9 /* codesign.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = codesign.c; sourceTree = "<group>"; };
+               E790C138169E5C6200E0C0C9 /* keychain_add.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = keychain_add.c; sourceTree = "<group>"; };
+               E790C139169E5C6200E0C0C9 /* keychain_find.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = keychain_find.c; sourceTree = "<group>"; };
+               E790C13A169E5C6200E0C0C9 /* pkcs12_util.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkcs12_util.c; sourceTree = "<group>"; };
+               E790C13D169E5C6200E0C0C9 /* scep.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = scep.c; sourceTree = "<group>"; };
+               E790C13E169E5C6200E0C0C9 /* SecurityCommands.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecurityCommands.h; sourceTree = "<group>"; };
+               E790C13F169E5C6200E0C0C9 /* show_certificates.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = show_certificates.c; sourceTree = "<group>"; };
+               E790C140169E5C6200E0C0C9 /* spc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = spc.c; sourceTree = "<group>"; };
+               E79277E1163B110A0096F3E2 /* SOSFullPeerInfo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SOSFullPeerInfo.c; sourceTree = "<group>"; };
+               E79277E2163B110A0096F3E2 /* SOSFullPeerInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSFullPeerInfo.h; sourceTree = "<group>"; };
+               E79D62B9176798BF005A9743 /* secd-50-account.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "secd-50-account.c"; path = "securityd/Regressions/secd-50-account.c"; sourceTree = SOURCE_ROOT; };
+               E79D62BE1767A547005A9743 /* SecdTestKeychainUtilities.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecdTestKeychainUtilities.c; sourceTree = "<group>"; };
+               E79D62BF1767A55F005A9743 /* SecdTestKeychainUtilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecdTestKeychainUtilities.h; sourceTree = "<group>"; };
+               E7A10FAA1771245D00C4602F /* SOSAccountTesting.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSAccountTesting.h; sourceTree = "<group>"; };
+               E7A10FAB1771246A00C4602F /* secd-55-account-circle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "secd-55-account-circle.c"; sourceTree = "<group>"; };
+               E7A10FAD1771249C00C4602F /* secd-57-account-leave.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "secd-57-account-leave.c"; sourceTree = "<group>"; };
+               E7B00701170B58BD00B27966 /* SecExports.exp-in */ = {isa = PBXFileReference; lastKnownFileType = text; path = "SecExports.exp-in"; sourceTree = "<group>"; };
+               E7B00702170B5FE100B27966 /* SOSExports.exp-in */ = {isa = PBXFileReference; lastKnownFileType = text; path = "SOSExports.exp-in"; sourceTree = "<group>"; };
+               E7B01B5A16532507000485F1 /* SOSCloudCircleInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = SOSCloudCircleInternal.h; sourceTree = "<group>"; };
+               E7B01B661655CC99000485F1 /* SOSCloudCircleServer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSCloudCircleServer.h; sourceTree = "<group>"; };
+               E7B01B671655CCA6000485F1 /* SOSCloudCircleServer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SOSCloudCircleServer.c; sourceTree = "<group>"; };
+               E7B01B8816572579000485F1 /* SecuritydXPC.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecuritydXPC.c; sourceTree = "<group>"; };
+               E7B01B8A1657259F000485F1 /* SecuritydXPC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecuritydXPC.h; sourceTree = "<group>"; };
+               E7BE10A5167AB2BF00D2A178 /* sc-41-cloudcircle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "sc-41-cloudcircle.c"; sourceTree = "<group>"; };
+               E7F0D3E9177BBE35001ACBC1 /* secd-55-account-incompatibility.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "secd-55-account-incompatibility.c"; sourceTree = "<group>"; };
+               E7F18554177A44E000177B23 /* secd-60-account-cloud-identity.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "secd-60-account-cloud-identity.c"; sourceTree = "<group>"; };
+               E7F18556177A502900177B23 /* secd-56-account-apply.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "secd-56-account-apply.c"; sourceTree = "<group>"; };
+               E7FEFB8C169E363300E18152 /* libSOSCommands.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSOSCommands.a; sourceTree = BUILT_PRODUCTS_DIR; };
+               E7FEFB90169E36D800E18152 /* keychain_sync.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = keychain_sync.c; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
+               0C0BDB59175687EC00BC1A7E /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                18270F5214CF651900B05E7F /* Frameworks */ = {
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                18270F5214CF651900B05E7F /* Frameworks */ = {
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               4A5CCA4C15ACEFA500702357 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               4A824AFE158FF07000F932C0 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               4CC92AFA15A3BC6B00C6D578 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               5284029D164445760035F320 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               E702E74F14E1F3EA00CDE635 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               E702E77114E1F48800CDE635 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               4AD6F6F21651C86200DB4CE6 /* libSecureObjectSync.a in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               E71049EF169E023B00DB0045 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               E71049F3169E023B00DB0045 /* Foundation.framework in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               E7104A17169E216E00DB0045 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               E7104A18169E216E00DB0045 /* Foundation.framework in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               E7FEFB86169E363300E18152 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               E7FEFB87169E363300E18152 /* Foundation.framework in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
                        children = (
                                18270C9714CF1AAD00B05E7F /* base.xcconfig */,
                                18270C9814CF1AAD00B05E7F /* debug.xcconfig */,
                        children = (
                                18270C9714CF1AAD00B05E7F /* base.xcconfig */,
                                18270C9814CF1AAD00B05E7F /* debug.xcconfig */,
+                               4C5EA365164C791400A136B8 /* lib-arc-only.xcconfig */,
                                18270C9914CF1AAD00B05E7F /* lib.xcconfig */,
                                18270C9A14CF1AAD00B05E7F /* release.xcconfig */,
                        );
                                18270C9914CF1AAD00B05E7F /* lib.xcconfig */,
                                18270C9A14CF1AAD00B05E7F /* release.xcconfig */,
                        );
                        isa = PBXGroup;
                        children = (
                                18270C9614CF1AAD00B05E7F /* config */,
                        isa = PBXGroup;
                        children = (
                                18270C9614CF1AAD00B05E7F /* config */,
-                               18D4055714CE51CD00A2BE4E /* security_utilities */,
                                18AD565714CB6ECD008233F2 /* securityd */,
                                186CDD1F14CA126D00AF9171 /* ipc */,
                                18AD565714CB6ECD008233F2 /* securityd */,
                                186CDD1F14CA126D00AF9171 /* ipc */,
+                               E7AC69CE14E1F78400CB09C1 /* SOSCircle */,
                                186CDD3014CA159600AF9171 /* Security */,
                                186CDD3014CA159600AF9171 /* Security */,
+                               E71049F4169E023B00DB0045 /* SecurityTool */,
+                               521C0B9715FA5C4900604B61 /* Frameworks */,
                                186CDD1014CA116C00AF9171 /* Products */,
                        );
                        sourceTree = "<group>";
                                186CDD1014CA116C00AF9171 /* Products */,
                        );
                        sourceTree = "<group>";
                                18D4043514CE0CF300A2BE4E /* libsecurity.a */,
                                18D4056214CE53C200A2BE4E /* libsecurityd.a */,
                                18270F5514CF651900B05E7F /* libsecipc_client.a */,
                                18D4043514CE0CF300A2BE4E /* libsecurity.a */,
                                18D4056214CE53C200A2BE4E /* libsecurityd.a */,
                                18270F5514CF651900B05E7F /* libsecipc_client.a */,
+                               E702E75614E1F3EA00CDE635 /* libSecureObjectSync.a */,
+                               E702E77814E1F48800CDE635 /* libSOSRegressions.a */,
+                               4A824B03158FF07000F932C0 /* libSecurityRegressions.a */,
+                               4CC92B1415A3BC6B00C6D578 /* libsecuritydRegressions.a */,
+                               4A5CCA4F15ACEFA500702357 /* libSecOtrOSX.a */,
+                               528402A0164445760035F320 /* libCloudKeychainProxy.a */,
+                               E71049F2169E023B00DB0045 /* libSecurityTool.a */,
+                               E7104A1D169E216E00DB0045 /* libSecurityCommands.a */,
+                               E7FEFB8C169E363300E18152 /* libSOSCommands.a */,
+                               0C0BDB5F175687EC00BC1A7E /* libsecdRegressions.a */,
                        );
                        name = Products;
                        sourceTree = "<group>";
                        );
                        name = Products;
                        sourceTree = "<group>";
                                18AD560614CB6E7A008233F2 /* client.c */,
                                18AD560714CB6E7A008233F2 /* com.apple.securityd.plist */,
                                18AD560814CB6E7A008233F2 /* securityd_client.h */,
                                18AD560614CB6E7A008233F2 /* client.c */,
                                18AD560714CB6E7A008233F2 /* com.apple.securityd.plist */,
                                18AD560814CB6E7A008233F2 /* securityd_client.h */,
-                               18AD560914CB6E7A008233F2 /* securityd_ipc_types.h */,
-                               18AD560A14CB6E7A008233F2 /* securityd_rep.defs */,
-                               18AD560B14CB6E7A008233F2 /* securityd_req.defs */,
-                               18AD560C14CB6E7A008233F2 /* securityd_server.h */,
                                18AD560D14CB6E7A008233F2 /* server.c */,
                        );
                        path = ipc;
                                18AD560D14CB6E7A008233F2 /* server.c */,
                        );
                        path = ipc;
                186CDD3014CA159600AF9171 /* Security */ = {
                        isa = PBXGroup;
                        children = (
                186CDD3014CA159600AF9171 /* Security */ = {
                        isa = PBXGroup;
                        children = (
+                               E7104A0F169E1F0800DB0045 /* Tool */,
+                               4A824AFA158FF05900F932C0 /* Regressions */,
+                               52D0F026169CA72800F07D79 /* SecOnOSX.h */,
+                               4A971682158FDEB800D439B7 /* SecOTR.h */,
+                               4A971684158FDEB800D439B7 /* SecOTRDHKey.h */,
+                               4A971685158FDEB800D439B7 /* SecOTRErrors.h */,
+                               4A971686158FDEB800D439B7 /* SecOTRFullIdentity.c */,
+                               4A971687158FDEB800D439B7 /* SecOTRIdentityPriv.h */,
+                               4A971688158FDEB800D439B7 /* SecOTRMath.c */,
+                               4A971689158FDEB800D439B7 /* SecOTRMath.h */,
+                               4A97168A158FDEB800D439B7 /* SecOTRMathPrivate.h */,
+                               4A97168B158FDEB800D439B7 /* SecOTRPacketData.c */,
+                               4A97168C158FDEB800D439B7 /* SecOTRPacketData.h */,
+                               4A97168D158FDEB800D439B7 /* SecOTRPackets.c */,
+                               4A97168E158FDEB800D439B7 /* SecOTRPackets.h */,
+                               4A97168F158FDEB800D439B7 /* SecOTRPublicIdentity.c */,
+                               4A971690158FDEB800D439B7 /* SecOTRSession.c */,
+                               4A971691158FDEB800D439B7 /* SecOTRSession.h */,
+                               4A971692158FDEB800D439B7 /* SecOTRSessionAKE.c */,
+                               4A971693158FDEB800D439B7 /* SecOTRSessionPriv.h */,
+                               4A971694158FDEB800D439B7 /* SecOTRUtils.c */,
                                18AD561514CB6EB9008233F2 /* certextensions.h */,
                                18AD561614CB6EB9008233F2 /* p12import.c */,
                                18AD561714CB6EB9008233F2 /* p12import.h */,
                                18AD561514CB6EB9008233F2 /* certextensions.h */,
                                18AD561614CB6EB9008233F2 /* p12import.c */,
                                18AD561714CB6EB9008233F2 /* p12import.h */,
                                18AD561D14CB6EB9008233F2 /* SecBase64.c */,
                                18AD561E14CB6EB9008233F2 /* SecBase64.h */,
                                18AD561F14CB6EB9008233F2 /* SecBasePriv.h */,
                                18AD561D14CB6EB9008233F2 /* SecBase64.c */,
                                18AD561E14CB6EB9008233F2 /* SecBase64.h */,
                                18AD561F14CB6EB9008233F2 /* SecBasePriv.h */,
-                               18AD562014CB6EB9008233F2 /* SecCertificate.c */,
                                18AD562114CB6EB9008233F2 /* SecCertificate.h */,
                                18AD562214CB6EB9008233F2 /* SecCertificateInternal.h */,
                                18AD562314CB6EB9008233F2 /* SecCertificatePath.c */,
                                18AD562114CB6EB9008233F2 /* SecCertificate.h */,
                                18AD562214CB6EB9008233F2 /* SecCertificateInternal.h */,
                                18AD562314CB6EB9008233F2 /* SecCertificatePath.c */,
                                18AD562C14CB6EB9008233F2 /* SecECKey.c */,
                                18AD562D14CB6EB9008233F2 /* SecECKey.h */,
                                18AD562E14CB6EB9008233F2 /* SecFramework.c */,
                                18AD562C14CB6EB9008233F2 /* SecECKey.c */,
                                18AD562D14CB6EB9008233F2 /* SecECKey.h */,
                                18AD562E14CB6EB9008233F2 /* SecFramework.c */,
+                               18AD562014CB6EB9008233F2 /* SecCertificate.c */,
                                18AD562F14CB6EB9008233F2 /* SecFramework.h */,
                                18AD563014CB6EB9008233F2 /* SecFrameworkStrings.h */,
                                18AD563114CB6EB9008233F2 /* SecIdentity.c */,
                                18AD562F14CB6EB9008233F2 /* SecFramework.h */,
                                18AD563014CB6EB9008233F2 /* SecFrameworkStrings.h */,
                                18AD563114CB6EB9008233F2 /* SecIdentity.c */,
                                18AD563D14CB6EB9008233F2 /* SecKey.h */,
                                18AD563E14CB6EB9008233F2 /* SecKeyInternal.h */,
                                18AD563F14CB6EB9008233F2 /* SecKeyPriv.h */,
                                18AD563D14CB6EB9008233F2 /* SecKey.h */,
                                18AD563E14CB6EB9008233F2 /* SecKeyInternal.h */,
                                18AD563F14CB6EB9008233F2 /* SecKeyPriv.h */,
+                               CDC765C01729A72800721712 /* SecPasswordGenerate.c */,
+                               CDC765C11729A72800721712 /* SecPasswordGenerate.h */,
                                18AD564014CB6EB9008233F2 /* SecPBKDF.c */,
                                18AD564114CB6EB9008233F2 /* SecPBKDF.h */,
                                18AD564214CB6EB9008233F2 /* SecPolicy.c */,
                                18AD564014CB6EB9008233F2 /* SecPBKDF.c */,
                                18AD564114CB6EB9008233F2 /* SecPBKDF.h */,
                                18AD564214CB6EB9008233F2 /* SecPolicy.c */,
                                18AD565414CB6EB9008233F2 /* Security.h */,
                                18AD565514CB6EB9008233F2 /* vmdh.c */,
                                18AD565614CB6EB9008233F2 /* vmdh.h */,
                                18AD565414CB6EB9008233F2 /* Security.h */,
                                18AD565514CB6EB9008233F2 /* vmdh.c */,
                                18AD565614CB6EB9008233F2 /* vmdh.h */,
+                               E7B01B8816572579000485F1 /* SecuritydXPC.c */,
+                               E7B01B8A1657259F000485F1 /* SecuritydXPC.h */,
+                               E7B00701170B58BD00B27966 /* SecExports.exp-in */,
+                               724D7363177A13A500FA10A1 /* AppleBaselineEscrowCertificates.h */,
                        );
                        path = Security;
                        sourceTree = "<group>";
                        );
                        path = Security;
                        sourceTree = "<group>";
                18AD565714CB6ECD008233F2 /* securityd */ = {
                        isa = PBXGroup;
                        children = (
                18AD565714CB6ECD008233F2 /* securityd */ = {
                        isa = PBXGroup;
                        children = (
+                               4CC92AAB15A3AC4600C6D578 /* Regressions */,
                                18AD567D14CB865E008233F2 /* asynchttp.c */,
                                18AD567E14CB865E008233F2 /* asynchttp.h */,
                                18AD567F14CB865E008233F2 /* entitlements.plist */,
                                18AD567D14CB865E008233F2 /* asynchttp.c */,
                                18AD567E14CB865E008233F2 /* asynchttp.h */,
                                18AD567F14CB865E008233F2 /* entitlements.plist */,
-                               18AD568014CB865E008233F2 /* keystore.c */,
-                               18AD568114CB865E008233F2 /* keystore.h */,
+                               72E2DC0616BC47C800E7B236 /* OTATrustUtilities.c */,
+                               72E2DC0716BC47C800E7B236 /* OTATrustUtilities.h */,
                                18AD568214CB865E008233F2 /* policytree.c */,
                                18AD568314CB865E008233F2 /* policytree.h */,
                                18AD568414CB865E008233F2 /* SecCAIssuerCache.c */,
                                18AD568514CB865E008233F2 /* SecCAIssuerCache.h */,
                                18AD568614CB865E008233F2 /* SecCAIssuerRequest.c */,
                                18AD568714CB865E008233F2 /* SecCAIssuerRequest.h */,
                                18AD568214CB865E008233F2 /* policytree.c */,
                                18AD568314CB865E008233F2 /* policytree.h */,
                                18AD568414CB865E008233F2 /* SecCAIssuerCache.c */,
                                18AD568514CB865E008233F2 /* SecCAIssuerCache.h */,
                                18AD568614CB865E008233F2 /* SecCAIssuerRequest.c */,
                                18AD568714CB865E008233F2 /* SecCAIssuerRequest.h */,
+                               4C4B15931655ED9000734590 /* SecDbItem.c */,
+                               4C4B15951655EDA700734590 /* SecDbItem.h */,
                                18AD568814CB865E008233F2 /* SecItemServer.c */,
                                18AD565814CB6F79008233F2 /* SecItemServer.h */,
                                18AD565914CB6F79008233F2 /* SecOCSPCache.c */,
                                18AD568814CB865E008233F2 /* SecItemServer.c */,
                                18AD565814CB6F79008233F2 /* SecItemServer.h */,
                                18AD565914CB6F79008233F2 /* SecOCSPCache.c */,
                                18AD566214CB6F79008233F2 /* SecTrustServer.h */,
                                18AD566314CB6F79008233F2 /* SecTrustStoreServer.c */,
                                18AD566414CB6F79008233F2 /* SecTrustStoreServer.h */,
                                18AD566214CB6F79008233F2 /* SecTrustServer.h */,
                                18AD566314CB6F79008233F2 /* SecTrustStoreServer.c */,
                                18AD566414CB6F79008233F2 /* SecTrustStoreServer.h */,
+                               E7B01B671655CCA6000485F1 /* SOSCloudCircleServer.c */,
+                               E7B01B661655CC99000485F1 /* SOSCloudCircleServer.h */,
                                18AD566514CB6F79008233F2 /* spi.c */,
                                18AD566614CB6F79008233F2 /* spi.h */,
                        );
                        path = securityd;
                        sourceTree = "<group>";
                };
                                18AD566514CB6F79008233F2 /* spi.c */,
                                18AD566614CB6F79008233F2 /* spi.h */,
                        );
                        path = securityd;
                        sourceTree = "<group>";
                };
-               18D4055714CE51CD00A2BE4E /* security_utilities */ = {
+               4A824AFA158FF05900F932C0 /* Regressions */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4CC92AB015A3AD0000C6D578 /* Security_regressions.h */,
+                               4CC92A0E15A3ABD400C6D578 /* crypto */,
+                               4CC92A1115A3ABD400C6D578 /* otr */,
+                               4CC92A1615A3ABD400C6D578 /* secitem */,
+                               4CC92A5B15A3ABD400C6D578 /* vmdh */,
+                       );
+                       name = Regressions;
+                       sourceTree = "<group>";
+               };
+               4CC92A0E15A3ABD400C6D578 /* crypto */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4CC92A0F15A3ABD400C6D578 /* pbkdf2-00-hmac-sha1.c */,
+                               4CC92A1015A3ABD400C6D578 /* spbkdf-00-hmac-sha1.c */,
+                       );
+                       name = crypto;
+                       path = Regressions/crypto;
+                       sourceTree = "<group>";
+               };
+               4CC92A1115A3ABD400C6D578 /* otr */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4CC92A1215A3ABD400C6D578 /* otr-00-identity.c */,
+                               4CC92A1315A3ABD400C6D578 /* otr-30-negotiation.c */,
+                               4CC92A1415A3ABD400C6D578 /* otr-otrdh.c */,
+                               4CC92A1515A3ABD400C6D578 /* otr-packetdata.c */,
+                       );
+                       name = otr;
+                       path = Regressions/otr;
+                       sourceTree = "<group>";
+               };
+               4CC92A1615A3ABD400C6D578 /* secitem */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4CC92A1715A3ABD400C6D578 /* si-00-find-nothing.c */,
+                               4CC92A1815A3ABD400C6D578 /* si-05-add.c */,
+                               4CC92A1915A3ABD400C6D578 /* si-10-find-internet.c */,
+                               4CC92A1A15A3ABD400C6D578 /* si-11-update-data.c */,
+                               4C2C8C3C17AB374700C24C13 /* si-12-item-stress.c */,
+                               4CC92A1B15A3ABD400C6D578 /* si-14-dateparse.c */,
+                               4CC92A1C15A3ABD400C6D578 /* si-15-certificate.c */,
+                               4CC92A1D15A3ABD400C6D578 /* si-16-ec-certificate.c */,
+                               4CC92A1E15A3ABD400C6D578 /* si-20-sectrust-activation.c */,
+                               4CC92A1F15A3ABD400C6D578 /* si-20-sectrust.c */,
+                               4CC92A2015A3ABD400C6D578 /* si-21-sectrust-asr.c */,
+                               4CC92A2115A3ABD400C6D578 /* si-22-sectrust-iap.c */,
+                               4CC92A2215A3ABD400C6D578 /* si-23-sectrust-ocsp.c */,
+                               4CC92A2315A3ABD400C6D578 /* si-24-sectrust-appleid.c */,
+                               4CC92A2415A3ABD400C6D578 /* si-24-sectrust-digicert-malaysia.c */,
+                               4CC92A2515A3ABD400C6D578 /* si-24-sectrust-diginotar.c */,
+                               4CC92A2615A3ABD400C6D578 /* si-24-sectrust-itms.c */,
+                               4CC92A2715A3ABD400C6D578 /* si-24-sectrust-mobileasset.c */,
+                               4CC92A2815A3ABD400C6D578 /* si-24-sectrust-nist.c */,
+                               4CC92A2915A3ABD400C6D578 /* si-24-sectrust-otatasking.c */,
+                               4CC92A2A15A3ABD400C6D578 /* si-24-sectrust-shoebox.c */,
+                               4CC92A2B15A3ABD400C6D578 /* si-25-sectrust-ipsec-eap.c */,
+                               4CC92A2C15A3ABD400C6D578 /* si-26-applicationsigning.c */,
+                               4CC92A2D15A3ABD400C6D578 /* si-27-sectrust-exceptions.c */,
+                               4CC92A2E15A3ABD400C6D578 /* si-28-sectrustsettings.c */,
+                               4CC92A2F15A3ABD400C6D578 /* si-29-sectrust-codesigning.c */,
+                               4CC92A3015A3ABD400C6D578 /* si-30-keychain-upgrade.c */,
+                               4CC92A3115A3ABD400C6D578 /* si-31-keychain-bad.c */,
+                               4CC92A3215A3ABD400C6D578 /* si-31-keychain-unreadable.c */,
+                               4CC92A3415A3ABD400C6D578 /* si-33-keychain-backup.c */,
+                               4CC92A3515A3ABD400C6D578 /* si-40-seckey-custom.c */,
+                               4CC92A3615A3ABD400C6D578 /* si-40-seckey.c */,
+                               4CC92A3715A3ABD400C6D578 /* si-41-sececkey.c */,
+                               4CC92A3815A3ABD400C6D578 /* si-42-identity.c */,
+                               4CC92A3915A3ABD400C6D578 /* si-43-persistent.c */,
+                               4CC92A3A15A3ABD400C6D578 /* si-50-secrandom.c */,
+                               4CC92A3B15A3ABD400C6D578 /* si-60-cms.c */,
+                               4CC92A3C15A3ABD400C6D578 /* si-61-pkcs12.c */,
+                               4CC92A3D15A3ABD400C6D578 /* si-62-csr.c */,
+                               4CC92A3E15A3ABD400C6D578 /* si-63-scep */,
+                               4CC92A4115A3ABD400C6D578 /* si-63-scep.c */,
+                               4CC92A4215A3ABD400C6D578 /* si-63-scep.h */,
+                               4CC92A4315A3ABD400C6D578 /* si-64-ossl-cms */,
+                               4CC92A4A15A3ABD400C6D578 /* si-64-ossl-cms.c */,
+                               4CC92A4B15A3ABD400C6D578 /* si-65-cms-cert-policy.c */,
+                               4CC92A4C15A3ABD400C6D578 /* si-66-smime */,
+                               4CC92A4E15A3ABD400C6D578 /* si-66-smime.c */,
+                               4CC92A4F15A3ABD400C6D578 /* si-67-sectrust-blacklist */,
+                               4CC92A5A15A3ABD400C6D578 /* si-67-sectrust-blacklist.c */,
+                               E748744415A61AF800624935 /* si-68-secmatchissuer.c */,
+                               CDA7729616B899F10069434D /* si-69-keydesc.c */,
+                               BE62D7611747FF51001EAA9D /* si-70-sectrust-unified.c */,
+                               5DE4A7BC17441CCD0036339E /* si-71-mobile-store-policy.c */,
+                               BE62D75F1747FF3E001EAA9D /* si-72-syncableitems.c */,
+                               CDD565A1173193AC00B6B074 /* si-73-secpasswordgenerate.c */,
+                               7255A46B1783333D006A8B9A /* si-74-OTAPKISigner.c */,
+                               7255F91317A973D5004A9F38 /* si-75-AppleIDRecordSigning.c */,
+                       );
+                       name = secitem;
+                       path = Regressions/secitem;
+                       sourceTree = "<group>";
+               };
+               4CC92A3E15A3ABD400C6D578 /* si-63-scep */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4CC92A3F15A3ABD400C6D578 /* getcacert-mdes.h */,
+                               4CC92A4015A3ABD400C6D578 /* getcacert-mdesqa.h */,
+                       );
+                       path = "si-63-scep";
+                       sourceTree = "<group>";
+               };
+               4CC92A4315A3ABD400C6D578 /* si-64-ossl-cms */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4CC92A4415A3ABD400C6D578 /* attached_no_data_signed_data.h */,
+                               4CC92A4515A3ABD400C6D578 /* attached_signed_data.h */,
+                               4CC92A4615A3ABD400C6D578 /* detached_content.h */,
+                               4CC92A4715A3ABD400C6D578 /* detached_signed_data.h */,
+                               4CC92A4815A3ABD400C6D578 /* privkey.h */,
+                               4CC92A4915A3ABD400C6D578 /* signer.h */,
+                       );
+                       path = "si-64-ossl-cms";
+                       sourceTree = "<group>";
+               };
+               4CC92A4C15A3ABD400C6D578 /* si-66-smime */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4CC92A4D15A3ABD400C6D578 /* signed-receipt.h */,
+                       );
+                       path = "si-66-smime";
+                       sourceTree = "<group>";
+               };
+               4CC92A4F15A3ABD400C6D578 /* si-67-sectrust-blacklist */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4A971683158FDEB800D439B7 /* SecOTRDHKey.c */,
+                               4CC92A5015A3ABD400C6D578 /* Global Trustee.cer.h */,
+                               4CC92A5115A3ABD400C6D578 /* UTN-USERFirst-Hardware.cer.h */,
+                               4CC92A5215A3ABD400C6D578 /* addons.mozilla.org.cer.h */,
+                               4CC92A5315A3ABD400C6D578 /* login.live.com.cer.h */,
+                               4CC92A5415A3ABD400C6D578 /* login.skype.com.cer.h */,
+                               4CC92A5515A3ABD400C6D578 /* login.yahoo.com.1.cer.h */,
+                               4CC92A5615A3ABD400C6D578 /* login.yahoo.com.2.cer.h */,
+                               4CC92A5715A3ABD400C6D578 /* login.yahoo.com.cer.h */,
+                               4CC92A5815A3ABD400C6D578 /* mail.google.com.cer.h */,
+                               4CC92A5915A3ABD400C6D578 /* www.google.com.cer.h */,
+                       );
+                       path = "si-67-sectrust-blacklist";
+                       sourceTree = "<group>";
+               };
+               4CC92A5B15A3ABD400C6D578 /* vmdh */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4CC92A5C15A3ABD400C6D578 /* vmdh-40.c */,
+                               4CC92A5D15A3ABD400C6D578 /* vmdh-41-example.c */,
+                               4CC92A5E15A3ABD400C6D578 /* vmdh-42-example2.c */,
+                       );
+                       name = vmdh;
+                       path = Regressions/vmdh;
+                       sourceTree = "<group>";
+               };
+               4CC92AAB15A3AC4600C6D578 /* Regressions */ = {
                        isa = PBXGroup;
                        children = (
                        isa = PBXGroup;
                        children = (
-                               18D4055914CE51FC00A2BE4E /* debugging.h */,
-                               18D4055A14CE51FC00A2BE4E /* sqlutils.h */,
+                               0CBF93F5177B7CFC001E5658 /* secd-03-corrupted-items.c */,
+                               0CBF93F6177B7CFC001E5658 /* secd-04-corrupted-items.c */,
+                               0CBF93FB177BA9D9001E5658 /* secd-05-corrupted-items.c */,
+                               4CC92AAE15A3ACCE00C6D578 /* securityd_regressions.h */,
+                               4CC92AAC15A3AC4600C6D578 /* sd-10-policytree.c */,
+                               4C143CDD164D8EF5003035A3 /* sd-70-engine.c */,
+                               0C0BDB601756882A00BC1A7E /* secd_regressions.h */,
+                               0C0BDB62175688DA00BC1A7E /* secd-01-items.c */,
+                               0C664AE7175951270092D3D9 /* secd-02-upgrade-while-locked.c */,
+                               0C062B1C175E784B00806CFE /* secd-30-keychain-upgrade.c */,
+                               0C062B1D175E784B00806CFE /* secd-31-keychain-bad.c */,
+                               0C062B1E175E784B00806CFE /* secd-31-keychain-unreadable.c */,
+                               E79D62B9176798BF005A9743 /* secd-50-account.c */,
+                               48E928C4179DD05500A7F755 /* secd-51-account-inflate.c */,
+                               4898223917BDB277003BEF32 /* secd-52-account-changed.c */,
+                               E7A10FAB1771246A00C4602F /* secd-55-account-circle.c */,
+                               E7F0D3E9177BBE35001ACBC1 /* secd-55-account-incompatibility.c */,
+                               E7F18556177A502900177B23 /* secd-56-account-apply.c */,
+                               E7A10FAD1771249C00C4602F /* secd-57-account-leave.c */,
+                               4882C516177521AE0095D04B /* secd-58-password-change.c */,
+                               48F32D7D1777AFA3001B84BA /* secd-59-account-cleanup.c */,
+                               E7F18554177A44E000177B23 /* secd-60-account-cloud-identity.c */,
+                               486C6C671795F20E00387075 /* secd-61-account-leave-not-in-kansas-anymore.c */,
+                               E7A10FAA1771245D00C4602F /* SOSAccountTesting.h */,
+                               E79D62BE1767A547005A9743 /* SecdTestKeychainUtilities.c */,
+                               E79D62BF1767A55F005A9743 /* SecdTestKeychainUtilities.h */,
                        );
                        );
-                       name = security_utilities;
-                       path = ../security_utilities;
+                       path = Regressions;
+                       sourceTree = "<group>";
+               };
+               521C0B9715FA5C4900604B61 /* Frameworks */ = {
+                       isa = PBXGroup;
+                       children = (
+                               52DD7069160CD40B0027A346 /* libutilities.a */,
+                               526CBA5116079FB4008DF7C8 /* Security.framework */,
+                               521C0B9815FA5C4A00604B61 /* Foundation.framework */,
+                       );
+                       name = Frameworks;
+                       sourceTree = "<group>";
+               };
+               521C0B9B15FA5C4A00604B61 /* Supporting Files */ = {
+                       isa = PBXGroup;
+                       children = (
+                       );
+                       name = "Supporting Files";
+                       sourceTree = "<group>";
+               };
+               521C0BAB15FA5DA800604B61 /* en.lproj */ = {
+                       isa = PBXGroup;
+                       children = (
+                               521C0BAC15FA5DA800604B61 /* InfoPlist.strings */,
+                       );
+                       name = en.lproj;
+                       path = SOSCircle/CloudKeychainProxy/en.lproj;
+                       sourceTree = SOURCE_ROOT;
+               };
+               5272501416838BB20029AADD /* CloudKeychainProxy */ = {
+                       isa = PBXGroup;
+                       children = (
+                               52C3D18E169A53150091D9D3 /* ckdmain.m */,
+                               521C0BB315FA5E3F00604B61 /* cloudkeychainproxy.m */,
+                               521C0BAF15FA5E3F00604B61 /* CKDKVSProxy.h */,
+                               521C0BB015FA5E3F00604B61 /* CKDKVSProxy.m */,
+                               521C0BB115FA5E3F00604B61 /* CKDPersistentState.h */,
+                               521C0BB215FA5E3F00604B61 /* CKDPersistentState.m */,
+                               52840291164050C80035F320 /* CKDUserInteraction.h */,
+                               52840292164050C80035F320 /* CKDUserInteraction.m */,
+                               521C0B9B15FA5C4A00604B61 /* Supporting Files */,
+                               522B0ED31649A68E00A4675D /* MobileKeyBag.framework */,
+                               521C0BAB15FA5DA800604B61 /* en.lproj */,
+                               521C0BA615FA5D7400604B61 /* cloudkeychain.entitlements.plist */,
+                               5272501916838BB20029AADD /* CloudKeychainProxy.1 */,
+                               5272501716838BB20029AADD /* Supporting Files */,
+                       );
+                       name = CloudKeychainProxy;
+                       path = ../CloudKeychainProxy;
+                       sourceTree = "<group>";
+               };
+               5272501716838BB20029AADD /* Supporting Files */ = {
+                       isa = PBXGroup;
+                       children = (
+                       );
+                       name = "Supporting Files";
+                       sourceTree = "<group>";
+               };
+               E71049F4169E023B00DB0045 /* SecurityTool */ = {
+                       isa = PBXGroup;
+                       children = (
+                               E790C108169E4E7900E0C0C9 /* builtin_commands.h */,
+                               E790C109169E4FD200E0C0C9 /* digest_calc.c */,
+                               E790C10E169E53DF00E0C0C9 /* leaks.c */,
+                               E790C10F169E53DF00E0C0C9 /* leaks.h */,
+                               4CD1897B169F835400BC96B8 /* print_cert.c */,
+                               4CD1897C169F835400BC96B8 /* print_cert.h */,
+                               E71049FE169E036E00DB0045 /* security.1 */,
+                               E71049FF169E036E00DB0045 /* SecurityTool.c */,
+                               E7104A00169E036E00DB0045 /* SecurityTool.h */,
+                               E7104A0D169E1C1600DB0045 /* tool_errors.h */,
+                       );
+                       path = SecurityTool;
+                       sourceTree = "<group>";
+               };
+               E7104A0F169E1F0800DB0045 /* Tool */ = {
+                       isa = PBXGroup;
+                       children = (
+                               E790C136169E5C6200E0C0C9 /* add_internet_password.c */,
+                               E790C137169E5C6200E0C0C9 /* codesign.c */,
+                               E790C138169E5C6200E0C0C9 /* keychain_add.c */,
+                               E790C139169E5C6200E0C0C9 /* keychain_find.c */,
+                               0CE7ABDE171383E30088968F /* keychain_backup.c */,
+                               E790C13A169E5C6200E0C0C9 /* pkcs12_util.c */,
+                               E790C13D169E5C6200E0C0C9 /* scep.c */,
+                               E790C13E169E5C6200E0C0C9 /* SecurityCommands.h */,
+                               E790C13F169E5C6200E0C0C9 /* show_certificates.c */,
+                               E790C140169E5C6200E0C0C9 /* spc.c */,
+                       );
+                       path = Tool;
+                       sourceTree = "<group>";
+               };
+               E7217B2015F8126700D26031 /* CKBridge */ = {
+                       isa = PBXGroup;
+                       children = (
+                               521C685C1614A6E100E31C3E /* SOSCloudKeychainClient.c */,
+                               521C685D1614A6E100E31C3E /* SOSCloudKeychainClient.h */,
+                               E7217B2515F8131A00D26031 /* SOSCloudKeychainConstants.c */,
+                               E7217B2615F8131A00D26031 /* SOSCloudKeychainConstants.h */,
+                               52849FC2164498C9005CDF23 /* SOSARCDefines.h */,
+                       );
+                       path = CKBridge;
+                       sourceTree = "<group>";
+               };
+               E7295C6614E356FE007FBB20 /* Hacks */ = {
+                       isa = PBXGroup;
+                       children = (
+                               E7295C6714E3571A007FBB20 /* Empty.c */,
+                               4C8940DA166EA8CF00241770 /* osxshim.c */,
+                       );
+                       name = Hacks;
+                       sourceTree = "<group>";
+               };
+               E7AC69CE14E1F78400CB09C1 /* SOSCircle */ = {
+                       isa = PBXGroup;
+                       children = (
+                               E7FEFB81169E362100E18152 /* Tool */,
+                               E7295C6614E356FE007FBB20 /* Hacks */,
+                               E7AC69CF14E1F78400CB09C1 /* Regressions */,
+                               E7AC69D114E1F78400CB09C1 /* SecureObjectSync */,
+                               5272501416838BB20029AADD /* CloudKeychainProxy */,
+                               E7217B2015F8126700D26031 /* CKBridge */,
+                       );
+                       path = SOSCircle;
+                       sourceTree = "<group>";
+               };
+               E7AC69CF14E1F78400CB09C1 /* Regressions */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4CC92AAF15A3ACE600C6D578 /* SOSCircle_regressions.h */,
+                               E763D6221624E2670038477D /* sc-20-keynames.c */,
+                               E777C72815B9C9F0004044A8 /* sc-30-peerinfo.c */,
+                               E777C6B015B4DDF2004044A8 /* sc-40-circle.c */,
+                               E7BE10A5167AB2BF00D2A178 /* sc-41-cloudcircle.c */,
+                               5253946016608F6800BA9687 /* sc-51-persistentEC.c */,
+                               4C6ED19115CB0E26004379B7 /* sc-60-peer.c */,
+                               4C6ED19415CB0E43004379B7 /* sc-70-engine.c */,
+                               4C4EBD531610D7D8007D06A5 /* sc-75-circle-engine.c */,
+                               521C0A7315F908A700604B61 /* sc-90-ckdclient.c */,
+                               521C691E16164B9900E31C3E /* sc-95-ckd2client.c */,
+                               52DEE9E1162DC8F1002F3BCD /* sc-100-devicecircle.c */,
+                               52AF7082163D9AA20092A7ED /* sc-101-accountsync.c */,
+                               52840280163F2B060035F320 /* sc-102-cfusernotification.c */,
+                               522B0ED11648809300A4675D /* sc-103-syncupdate.c */,
+                               521C0C8615FEB03300604B61 /* sc-120-cloudcircle.c */,
+                               48CE733D1731C49A004C2946 /* sc-130-resignationticket.c */,
+                               521C0CD515FF9B3300604B61 /* SOSRegressionUtilities.c */,
+                               521C0CD815FF9B4B00604B61 /* SOSRegressionUtilities.h */,
+                               521C0CD915FFA05000604B61 /* CKDKeyValueStore.h */,
+                               521C0CDA15FFA05000604B61 /* CKDKeyValueStore.m */,
+                               4CB8A83716164B7700B52EC7 /* SOSTestDataSource.c */,
+                               4CB8A83916164B8C00B52EC7 /* SOSTestDataSource.h */,
+                               4C5F2E36162DE87F00AF8346 /* SOSTestTransport.c */,
+                               4C5F2E35162DE84E00AF8346 /* SOSTestTransport.h */,
+                       );
+                       path = Regressions;
+                       sourceTree = "<group>";
+               };
+               E7AC69D114E1F78400CB09C1 /* SecureObjectSync */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4CC929AD15A3957800C6D578 /* SOSAccount.c */,
+                               4CC929AE15A3957800C6D578 /* SOSAccount.h */,
+                               4CC929AF15A3957800C6D578 /* SOSCircle.c */,
+                               4CC929B015A3957800C6D578 /* SOSCircle.h */,
+                               E777C71D15B73F9E004044A8 /* SOSInternal.c */,
+                               E777C71B15B73F59004044A8 /* SOSInternal.h */,
+                               E703811114E1FEE4007CB458 /* SOSCloudCircle.h */,
+                               E7B01B5A16532507000485F1 /* SOSCloudCircleInternal.h */,
+                               E7217B1715F80E0F00D26031 /* SOSCloudCircle.c */,
+                               4C9DC91C15B602910036D941 /* SOSEngine.c */,
+                               4C9DC91915B602760036D941 /* SOSEngine.h */,
+                               4CC929B115A3957800C6D578 /* SOSPeer.c */,
+                               4CC929B215A3957800C6D578 /* SOSPeer.h */,
+                               E79277E1163B110A0096F3E2 /* SOSFullPeerInfo.c */,
+                               E79277E2163B110A0096F3E2 /* SOSFullPeerInfo.h */,
+                               E777C72515B87544004044A8 /* SOSPeerInfo.c */,
+                               E777C72415B87528004044A8 /* SOSPeerInfo.h */,
+                               485835871779013E0050F074 /* SOSPeerInfoInternal.h */,
+                               4C1C452614EB27F50018B1D9 /* SOSTransport.c */,
+                               4C1C452914EB28260018B1D9 /* SOSTransport.h */,
+                               488902EB16C2F88400F119FF /* SOSCoder.c */,
+                               488902ED16C2F89700F119FF /* SOSCoder.h */,
+                               4802A59516D711060059E5B9 /* SOSUserKeygen.c */,
+                               4802A59716D711190059E5B9 /* SOSUserKeygen.h */,
+                               E7B00702170B5FE100B27966 /* SOSExports.exp-in */,
+                       );
+                       path = SecureObjectSync;
+                       sourceTree = "<group>";
+               };
+               E7FEFB81169E362100E18152 /* Tool */ = {
+                       isa = PBXGroup;
+                       children = (
+                               E790C0F4169E3D7200E0C0C9 /* SOSCommands.h */,
+                               E7FEFB90169E36D800E18152 /* keychain_sync.c */,
+                       );
+                       path = Tool;
                        sourceTree = "<group>";
                };
 /* End PBXGroup section */
 
 /* Begin PBXHeadersBuildPhase section */
                        sourceTree = "<group>";
                };
 /* End PBXGroup section */
 
 /* Begin PBXHeadersBuildPhase section */
+               0C0BDB5A175687EC00BC1A7E /* Headers */ = {
+                       isa = PBXHeadersBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               0C0BDB611756882A00BC1A7E /* secd_regressions.h in Headers */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                18270F5314CF651900B05E7F /* Headers */ = {
                        isa = PBXHeadersBuildPhase;
                        buildActionMask = 2147483647;
                18270F5314CF651900B05E7F /* Headers */ = {
                        isa = PBXHeadersBuildPhase;
                        buildActionMask = 2147483647;
                        buildActionMask = 2147483647;
                        files = (
                                18AD560F14CB6E7A008233F2 /* securityd_client.h in Headers */,
                        buildActionMask = 2147483647;
                        files = (
                                18AD560F14CB6E7A008233F2 /* securityd_client.h in Headers */,
-                               18AD561014CB6E7A008233F2 /* securityd_ipc_types.h in Headers */,
-                               18AD561314CB6E7A008233F2 /* securityd_server.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        isa = PBXHeadersBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        isa = PBXHeadersBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
-                               18D4055C14CE51FC00A2BE4E /* debugging.h in Headers */,
-                               18D4055D14CE51FC00A2BE4E /* sqlutils.h in Headers */,
+                               CDC765C41729A72800721712 /* SecPasswordGenerate.h in Headers */,
+                               4A971695158FDEB800D439B7 /* SecOTR.h in Headers */,
+                               4A971697158FDEB800D439B7 /* SecOTRDHKey.h in Headers */,
+                               4A971698158FDEB800D439B7 /* SecOTRErrors.h in Headers */,
+                               4A97169A158FDEB800D439B7 /* SecOTRIdentityPriv.h in Headers */,
+                               4A97169C158FDEB800D439B7 /* SecOTRMath.h in Headers */,
+                               4A97169D158FDEB800D439B7 /* SecOTRMathPrivate.h in Headers */,
+                               4A97169F158FDEB800D439B7 /* SecOTRPacketData.h in Headers */,
+                               4A9716A1158FDEB800D439B7 /* SecOTRPackets.h in Headers */,
+                               4A9716A4158FDEB800D439B7 /* SecOTRSession.h in Headers */,
+                               4A9716A6158FDEB800D439B7 /* SecOTRSessionPriv.h in Headers */,
+                               52D0F028169CA72800F07D79 /* SecOnOSX.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               4A5CCA4D15ACEFA500702357 /* Headers */ = {
+                       isa = PBXHeadersBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               4A824AFF158FF07000F932C0 /* Headers */ = {
+                       isa = PBXHeadersBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               4CC92AC015A3BC4300C6D578 /* Security_regressions.h in Headers */,
+                               4CC92A8C15A3ABD400C6D578 /* getcacert-mdes.h in Headers */,
+                               4CC92A8D15A3ABD400C6D578 /* getcacert-mdesqa.h in Headers */,
+                               4CC92A8F15A3ABD400C6D578 /* si-63-scep.h in Headers */,
+                               4CC92A9015A3ABD400C6D578 /* attached_no_data_signed_data.h in Headers */,
+                               4CC92A9115A3ABD400C6D578 /* attached_signed_data.h in Headers */,
+                               4CC92A9215A3ABD400C6D578 /* detached_content.h in Headers */,
+                               4CC92A9315A3ABD400C6D578 /* detached_signed_data.h in Headers */,
+                               4CC92A9415A3ABD400C6D578 /* privkey.h in Headers */,
+                               4CC92A9515A3ABD400C6D578 /* signer.h in Headers */,
+                               4CC92A9815A3ABD400C6D578 /* signed-receipt.h in Headers */,
+                               4CC92A9A15A3ABD400C6D578 /* Global Trustee.cer.h in Headers */,
+                               4CC92A9B15A3ABD400C6D578 /* UTN-USERFirst-Hardware.cer.h in Headers */,
+                               4CC92A9C15A3ABD400C6D578 /* addons.mozilla.org.cer.h in Headers */,
+                               4CC92A9D15A3ABD400C6D578 /* login.live.com.cer.h in Headers */,
+                               4CC92A9E15A3ABD400C6D578 /* login.skype.com.cer.h in Headers */,
+                               4CC92A9F15A3ABD400C6D578 /* login.yahoo.com.1.cer.h in Headers */,
+                               4CC92AA015A3ABD400C6D578 /* login.yahoo.com.2.cer.h in Headers */,
+                               4CC92AA115A3ABD400C6D578 /* login.yahoo.com.cer.h in Headers */,
+                               4CC92AA215A3ABD400C6D578 /* mail.google.com.cer.h in Headers */,
+                               4CC92AA315A3ABD400C6D578 /* www.google.com.cer.h in Headers */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               4CC92AFB15A3BC6B00C6D578 /* Headers */ = {
+                       isa = PBXHeadersBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               4CC92B1515A3BCA500C6D578 /* securityd_regressions.h in Headers */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               E702E75014E1F3EA00CDE635 /* Headers */ = {
+                       isa = PBXHeadersBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               E703811514E1FEEF007CB458 /* SOSCloudCircle.h in Headers */,
+                               4C1C452A14EB28260018B1D9 /* SOSTransport.h in Headers */,
+                               4CC929B415A3957800C6D578 /* SOSAccount.h in Headers */,
+                               4CC929B615A3957800C6D578 /* SOSCircle.h in Headers */,
+                               4CC929B815A3957800C6D578 /* SOSPeer.h in Headers */,
+                               4C9DC91A15B602760036D941 /* SOSEngine.h in Headers */,
+                               E777C71C15B73F59004044A8 /* SOSInternal.h in Headers */,
+                               4802A59816D7156D0059E5B9 /* SOSUserKeygen.h in Headers */,
+                               E777C72715B882E5004044A8 /* SOSPeerInfo.h in Headers */,
+                               E7217B2815F8131A00D26031 /* SOSCloudKeychainConstants.h in Headers */,
+                               521C68601614A6E100E31C3E /* SOSCloudKeychainClient.h in Headers */,
+                               E79277E4163B110A0096F3E2 /* SOSFullPeerInfo.h in Headers */,
+                               E7B01B5B16532507000485F1 /* SOSCloudCircleInternal.h in Headers */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               E702E77214E1F48800CDE635 /* Headers */ = {
+                       isa = PBXHeadersBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               4CC92AC115A3BC4D00C6D578 /* SOSCircle_regressions.h in Headers */,
+                               521C0CDD15FFA05100604B61 /* CKDKeyValueStore.h in Headers */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
 /* End PBXHeadersBuildPhase section */
 
 /* Begin PBXNativeTarget section */
 /* End PBXHeadersBuildPhase section */
 
 /* Begin PBXNativeTarget section */
+               0C0BDB55175687EC00BC1A7E /* libsecdRegressions */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 0C0BDB5C175687EC00BC1A7E /* Build configuration list for PBXNativeTarget "libsecdRegressions" */;
+                       buildPhases = (
+                               0C0BDB56175687EC00BC1A7E /* Sources */,
+                               0C0BDB59175687EC00BC1A7E /* Frameworks */,
+                               0C0BDB5A175687EC00BC1A7E /* Headers */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = libsecdRegressions;
+                       productName = security;
+                       productReference = 0C0BDB5F175687EC00BC1A7E /* libsecdRegressions.a */;
+                       productType = "com.apple.product-type.library.static";
+               };
                18270F5414CF651900B05E7F /* libsecipc_client */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = 18270F5614CF651900B05E7F /* Build configuration list for PBXNativeTarget "libsecipc_client" */;
                18270F5414CF651900B05E7F /* libsecipc_client */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = 18270F5614CF651900B05E7F /* Build configuration list for PBXNativeTarget "libsecipc_client" */;
                        productReference = 18D4056214CE53C200A2BE4E /* libsecurityd.a */;
                        productType = "com.apple.product-type.library.static";
                };
                        productReference = 18D4056214CE53C200A2BE4E /* libsecurityd.a */;
                        productType = "com.apple.product-type.library.static";
                };
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
-               186CDD0614CA116C00AF9171 /* Project object */ = {
-                       isa = PBXProject;
-                       attributes = {
-                               LastUpgradeCheck = 0440;
-                       };
-                       buildConfigurationList = 186CDD0914CA116C00AF9171 /* Build configuration list for PBXProject "sec" */;
-                       compatibilityVersion = "Xcode 3.2";
-                       developmentRegion = English;
-                       hasScannedForEncodings = 0;
-                       knownRegions = (
-                               en,
+               4A5CCA4E15ACEFA500702357 /* libSecOtrOSX */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 4A5CCA5215ACEFA500702357 /* Build configuration list for PBXNativeTarget "libSecOtrOSX" */;
+                       buildPhases = (
+                               4A5CCA4B15ACEFA500702357 /* Sources */,
+                               4A5CCA4C15ACEFA500702357 /* Frameworks */,
+                               4A5CCA4D15ACEFA500702357 /* Headers */,
                        );
                        );
-                       mainGroup = 186CDD0414CA116C00AF9171;
-                       productRefGroup = 186CDD1014CA116C00AF9171 /* Products */;
-                       projectDirPath = "";
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = libSecOtrOSX;
+                       productName = libSecOtrOSX;
+                       productReference = 4A5CCA4F15ACEFA500702357 /* libSecOtrOSX.a */;
+                       productType = "com.apple.product-type.library.static";
+               };
+               4A824AFB158FF07000F932C0 /* libSecurityRegressions */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 4A824B00158FF07000F932C0 /* Build configuration list for PBXNativeTarget "libSecurityRegressions" */;
+                       buildPhases = (
+                               4A824AFC158FF07000F932C0 /* Sources */,
+                               4A824AFE158FF07000F932C0 /* Frameworks */,
+                               4A824AFF158FF07000F932C0 /* Headers */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = libSecurityRegressions;
+                       productName = security;
+                       productReference = 4A824B03158FF07000F932C0 /* libSecurityRegressions.a */;
+                       productType = "com.apple.product-type.library.static";
+               };
+               4CC92AC215A3BC6B00C6D578 /* libsecuritydRegressions */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 4CC92B1115A3BC6B00C6D578 /* Build configuration list for PBXNativeTarget "libsecuritydRegressions" */;
+                       buildPhases = (
+                               4CC92AC315A3BC6B00C6D578 /* Sources */,
+                               4CC92AFA15A3BC6B00C6D578 /* Frameworks */,
+                               4CC92AFB15A3BC6B00C6D578 /* Headers */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = libsecuritydRegressions;
+                       productName = security;
+                       productReference = 4CC92B1415A3BC6B00C6D578 /* libsecuritydRegressions.a */;
+                       productType = "com.apple.product-type.library.static";
+               };
+               5284029F164445760035F320 /* libCloudKeychainProxy */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 528402A9164445760035F320 /* Build configuration list for PBXNativeTarget "libCloudKeychainProxy" */;
+                       buildPhases = (
+                               5284029C164445760035F320 /* Sources */,
+                               5284029D164445760035F320 /* Frameworks */,
+                               5284029E164445760035F320 /* CopyFiles */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = libCloudKeychainProxy;
+                       productName = libCloudKeychainProxy;
+                       productReference = 528402A0164445760035F320 /* libCloudKeychainProxy.a */;
+                       productType = "com.apple.product-type.library.static";
+               };
+               E702E73514E1F3EA00CDE635 /* libSecureObjectSync */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = E702E75314E1F3EA00CDE635 /* Build configuration list for PBXNativeTarget "libSecureObjectSync" */;
+                       buildPhases = (
+                               E702E73614E1F3EA00CDE635 /* Sources */,
+                               E702E74F14E1F3EA00CDE635 /* Frameworks */,
+                               E702E75014E1F3EA00CDE635 /* Headers */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = libSecureObjectSync;
+                       productName = security;
+                       productReference = E702E75614E1F3EA00CDE635 /* libSecureObjectSync.a */;
+                       productType = "com.apple.product-type.library.static";
+               };
+               E702E75714E1F48800CDE635 /* libSOSRegressions */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = E702E77514E1F48800CDE635 /* Build configuration list for PBXNativeTarget "libSOSRegressions" */;
+                       buildPhases = (
+                               E702E75814E1F48800CDE635 /* Sources */,
+                               E702E77114E1F48800CDE635 /* Frameworks */,
+                               E702E77214E1F48800CDE635 /* Headers */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = libSOSRegressions;
+                       productName = security;
+                       productReference = E702E77814E1F48800CDE635 /* libSOSRegressions.a */;
+                       productType = "com.apple.product-type.library.static";
+               };
+               E71049F1169E023B00DB0045 /* libSecurityTool */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = E71049FD169E023B00DB0045 /* Build configuration list for PBXNativeTarget "libSecurityTool" */;
+                       buildPhases = (
+                               E71049EE169E023B00DB0045 /* Sources */,
+                               E71049EF169E023B00DB0045 /* Frameworks */,
+                               E71049F0169E023B00DB0045 /* CopyFiles */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = libSecurityTool;
+                       productName = SecurityTool;
+                       productReference = E71049F2169E023B00DB0045 /* libSecurityTool.a */;
+                       productType = "com.apple.product-type.library.static";
+               };
+               E7104A12169E216E00DB0045 /* libSecurityCommands */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = E7104A1A169E216E00DB0045 /* Build configuration list for PBXNativeTarget "libSecurityCommands" */;
+                       buildPhases = (
+                               E7104A13169E216E00DB0045 /* Sources */,
+                               E7104A17169E216E00DB0045 /* Frameworks */,
+                               E7104A19169E216E00DB0045 /* CopyFiles */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = libSecurityCommands;
+                       productName = SecurityTool;
+                       productReference = E7104A1D169E216E00DB0045 /* libSecurityCommands.a */;
+                       productType = "com.apple.product-type.library.static";
+               };
+               E7FEFB82169E363300E18152 /* libSOSCommands */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = E7FEFB89169E363300E18152 /* Build configuration list for PBXNativeTarget "libSOSCommands" */;
+                       buildPhases = (
+                               E7FEFB83169E363300E18152 /* Sources */,
+                               E7FEFB86169E363300E18152 /* Frameworks */,
+                               E7FEFB88169E363300E18152 /* CopyFiles */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = libSOSCommands;
+                       productName = SecurityTool;
+                       productReference = E7FEFB8C169E363300E18152 /* libSOSCommands.a */;
+                       productType = "com.apple.product-type.library.static";
+               };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+               186CDD0614CA116C00AF9171 /* Project object */ = {
+                       isa = PBXProject;
+                       attributes = {
+                               LastUpgradeCheck = 0500;
+                       };
+                       buildConfigurationList = 186CDD0914CA116C00AF9171 /* Build configuration list for PBXProject "sec" */;
+                       compatibilityVersion = "Xcode 3.2";
+                       developmentRegion = English;
+                       hasScannedForEncodings = 0;
+                       knownRegions = (
+                               en,
+                       );
+                       mainGroup = 186CDD0414CA116C00AF9171;
+                       productRefGroup = 186CDD1014CA116C00AF9171 /* Products */;
+                       projectDirPath = "";
                        projectRoot = "";
                        targets = (
                                18D4043414CE0CF300A2BE4E /* libsecurity */,
                                18D4056114CE53C200A2BE4E /* libsecurityd */,
                                186CDD0E14CA116C00AF9171 /* libSecItemShimOSX */,
                                18270F5414CF651900B05E7F /* libsecipc_client */,
                        projectRoot = "";
                        targets = (
                                18D4043414CE0CF300A2BE4E /* libsecurity */,
                                18D4056114CE53C200A2BE4E /* libsecurityd */,
                                186CDD0E14CA116C00AF9171 /* libSecItemShimOSX */,
                                18270F5414CF651900B05E7F /* libsecipc_client */,
+                               E702E73514E1F3EA00CDE635 /* libSecureObjectSync */,
+                               E702E75714E1F48800CDE635 /* libSOSRegressions */,
+                               4A824AFB158FF07000F932C0 /* libSecurityRegressions */,
+                               4CC92AC215A3BC6B00C6D578 /* libsecuritydRegressions */,
+                               4A5CCA4E15ACEFA500702357 /* libSecOtrOSX */,
+                               5284029F164445760035F320 /* libCloudKeychainProxy */,
+                               E71049F1169E023B00DB0045 /* libSecurityTool */,
+                               E7104A12169E216E00DB0045 /* libSecurityCommands */,
+                               E7FEFB82169E363300E18152 /* libSOSCommands */,
+                               0C0BDB55175687EC00BC1A7E /* libsecdRegressions */,
                        );
                };
 /* End PBXProject section */
 
 /* Begin PBXSourcesBuildPhase section */
                        );
                };
 /* End PBXProject section */
 
 /* Begin PBXSourcesBuildPhase section */
+               0C0BDB56175687EC00BC1A7E /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               E7F0D3EA177BBE35001ACBC1 /* secd-55-account-incompatibility.c in Sources */,
+                               0C0BDB63175688DA00BC1A7E /* secd-01-items.c in Sources */,
+                               4882C517177521AE0095D04B /* secd-58-password-change.c in Sources */,
+                               E7A10FAE1771249C00C4602F /* secd-57-account-leave.c in Sources */,
+                               E7F18555177A44E000177B23 /* secd-60-account-cloud-identity.c in Sources */,
+                               E7F18557177A502900177B23 /* secd-56-account-apply.c in Sources */,
+                               0C664AE8175951270092D3D9 /* secd-02-upgrade-while-locked.c in Sources */,
+                               0CBF93F8177B7CFC001E5658 /* secd-03-corrupted-items.c in Sources */,
+                               0CBF93FC177BA9D9001E5658 /* secd-05-corrupted-items.c in Sources */,
+                               0CBF93F9177B7CFC001E5658 /* secd-04-corrupted-items.c in Sources */,
+                               4898223A17BDB277003BEF32 /* secd-52-account-changed.c in Sources */,
+                               0C062B1F175E784B00806CFE /* secd-30-keychain-upgrade.c in Sources */,
+                               0C062B20175E784B00806CFE /* secd-31-keychain-bad.c in Sources */,
+                               0C062B21175E784B00806CFE /* secd-31-keychain-unreadable.c in Sources */,
+                               E79D62BB176798FD005A9743 /* secd-50-account.c in Sources */,
+                               48E928C5179DD05500A7F755 /* secd-51-account-inflate.c in Sources */,
+                               486C6C691795F9D600387075 /* secd-61-account-leave-not-in-kansas-anymore.c in Sources */,
+                               E79D62BD176799EE005A9743 /* SOSTestDataSource.c in Sources */,
+                               E79D62BC176799DB005A9743 /* SOSRegressionUtilities.c in Sources */,
+                               E7A10FAC1771246A00C4602F /* secd-55-account-circle.c in Sources */,
+                               E79D62C01767A5BC005A9743 /* SecdTestKeychainUtilities.c in Sources */,
+                               48F32D7E1777AFA3001B84BA /* secd-59-account-cleanup.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                18270F5114CF651900B05E7F /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                                18270F5914CF654400B05E7F /* client.c in Sources */,
                18270F5114CF651900B05E7F /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                                18270F5914CF654400B05E7F /* client.c in Sources */,
-                               18270F5A14CF654400B05E7F /* securityd_rep.defs in Sources */,
-                               18270F5B14CF654400B05E7F /* securityd_req.defs in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        files = (
                                18AD566714CB70A8008233F2 /* SecItem.c in Sources */,
                                BEFE994E14F2E17200356A97 /* SecDH.c in Sources */,
                        files = (
                                18AD566714CB70A8008233F2 /* SecItem.c in Sources */,
                                BEFE994E14F2E17200356A97 /* SecDH.c in Sources */,
+                               4C8D8627177A71E80019A804 /* SOSCloudCircle.c in Sources */,
+                               4C3CE9E7176005A700B521C2 /* SecuritydXPC.c in Sources */,
+                               4C8940DB166EA8CF00241770 /* osxshim.c in Sources */,
+                               4C8D8628177A71FB0019A804 /* SecPasswordGenerate.c in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                18D4044814CE1FE400A2BE4E /* SecKey.c in Sources */,
                                18D4044914CE1FE400A2BE4E /* SecPBKDF.c in Sources */,
                                18D4044A14CE1FE400A2BE4E /* SecPolicy.c in Sources */,
                                18D4044814CE1FE400A2BE4E /* SecKey.c in Sources */,
                                18D4044914CE1FE400A2BE4E /* SecPBKDF.c in Sources */,
                                18D4044A14CE1FE400A2BE4E /* SecPolicy.c in Sources */,
+                               4CC07E26171E252300DCB6CE /* SOSCloudCircle.c in Sources */,
                                18D4044B14CE1FE400A2BE4E /* SecRSAKey.c in Sources */,
                                18D4044C14CE1FE400A2BE4E /* SecSCEP.c in Sources */,
                                18D4044D14CE1FE400A2BE4E /* SecTrust.c in Sources */,
                                18D4044E14CE1FE400A2BE4E /* SecTrustSettings.c in Sources */,
                                18D4044B14CE1FE400A2BE4E /* SecRSAKey.c in Sources */,
                                18D4044C14CE1FE400A2BE4E /* SecSCEP.c in Sources */,
                                18D4044D14CE1FE400A2BE4E /* SecTrust.c in Sources */,
                                18D4044E14CE1FE400A2BE4E /* SecTrustSettings.c in Sources */,
+                               CDC765C21729A72800721712 /* SecPasswordGenerate.c in Sources */,
                                18D4044F14CE1FE400A2BE4E /* SecTrustStore.c in Sources */,
                                18D4045014CE1FE400A2BE4E /* vmdh.c in Sources */,
                                18D4044F14CE1FE400A2BE4E /* SecTrustStore.c in Sources */,
                                18D4045014CE1FE400A2BE4E /* vmdh.c in Sources */,
+                               4A971696158FDEB800D439B7 /* SecOTRDHKey.c in Sources */,
+                               4A971699158FDEB800D439B7 /* SecOTRFullIdentity.c in Sources */,
+                               4A97169B158FDEB800D439B7 /* SecOTRMath.c in Sources */,
+                               4A97169E158FDEB800D439B7 /* SecOTRPacketData.c in Sources */,
+                               4A9716A0158FDEB800D439B7 /* SecOTRPackets.c in Sources */,
+                               4A9716A2158FDEB800D439B7 /* SecOTRPublicIdentity.c in Sources */,
+                               4A9716A3158FDEB800D439B7 /* SecOTRSession.c in Sources */,
+                               4A9716A5158FDEB800D439B7 /* SecOTRSessionAKE.c in Sources */,
+                               4A9716A7158FDEB800D439B7 /* SecOTRUtils.c in Sources */,
+                               CD3FD10716C3064B00A83BB6 /* SecuritydXPC.c in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               7249E1CB16C01E5F003D7268 /* OTATrustUtilities.c in Sources */,
                                18D4056614CE53DD00A2BE4E /* asynchttp.c in Sources */,
                                18D4056614CE53DD00A2BE4E /* asynchttp.c in Sources */,
-                               18D4056714CE53DD00A2BE4E /* keystore.c in Sources */,
                                18D4056814CE53DD00A2BE4E /* policytree.c in Sources */,
                                18D4056914CE53DD00A2BE4E /* SecCAIssuerCache.c in Sources */,
                                18D4056A14CE53DD00A2BE4E /* SecCAIssuerRequest.c in Sources */,
                                18D4056B14CE53DD00A2BE4E /* SecItemServer.c in Sources */,
                                18D4056814CE53DD00A2BE4E /* policytree.c in Sources */,
                                18D4056914CE53DD00A2BE4E /* SecCAIssuerCache.c in Sources */,
                                18D4056A14CE53DD00A2BE4E /* SecCAIssuerRequest.c in Sources */,
                                18D4056B14CE53DD00A2BE4E /* SecItemServer.c in Sources */,
+                               4C3CE9E8176005B500B521C2 /* SecuritydXPC.c in Sources */,
                                18D4056C14CE53DD00A2BE4E /* SecOCSPCache.c in Sources */,
                                18D4056D14CE53DD00A2BE4E /* SecOCSPRequest.c in Sources */,
                                18D4056E14CE53DD00A2BE4E /* SecOCSPResponse.c in Sources */,
                                18D4056C14CE53DD00A2BE4E /* SecOCSPCache.c in Sources */,
                                18D4056D14CE53DD00A2BE4E /* SecOCSPRequest.c in Sources */,
                                18D4056E14CE53DD00A2BE4E /* SecOCSPResponse.c in Sources */,
                                18D4057014CE53DD00A2BE4E /* SecTrustServer.c in Sources */,
                                18D4057114CE53DD00A2BE4E /* SecTrustStoreServer.c in Sources */,
                                18D4057214CE547400A2BE4E /* spi.c in Sources */,
                                18D4057014CE53DD00A2BE4E /* SecTrustServer.c in Sources */,
                                18D4057114CE53DD00A2BE4E /* SecTrustStoreServer.c in Sources */,
                                18D4057214CE547400A2BE4E /* spi.c in Sources */,
+                               E7B01B691655DF20000485F1 /* SOSCloudCircleServer.c in Sources */,
+                               525394AE1660A30000BA9687 /* SecDbItem.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               4A5CCA4B15ACEFA500702357 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               4A5CCA5415ACEFD400702357 /* SecOTRDHKey.c in Sources */,
+                               4A5CCA5515ACEFD400702357 /* SecOTRFullIdentity.c in Sources */,
+                               4A5CCA5615ACEFD400702357 /* SecOTRMath.c in Sources */,
+                               4A5CCA5715ACEFD400702357 /* SecOTRPacketData.c in Sources */,
+                               4A5CCA5815ACEFD400702357 /* SecOTRPackets.c in Sources */,
+                               4A5CCA5915ACEFD400702357 /* SecOTRPublicIdentity.c in Sources */,
+                               4A5CCA5A15ACEFD400702357 /* SecOTRSession.c in Sources */,
+                               4A5CCA5B15ACEFD400702357 /* SecOTRSessionAKE.c in Sources */,
+                               4A5CCA5C15ACEFD400702357 /* SecOTRUtils.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               4A824AFC158FF07000F932C0 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               4CC92A5F15A3ABD400C6D578 /* pbkdf2-00-hmac-sha1.c in Sources */,
+                               4CC92A6015A3ABD400C6D578 /* spbkdf-00-hmac-sha1.c in Sources */,
+                               4CC92A6115A3ABD400C6D578 /* otr-00-identity.c in Sources */,
+                               4CC92A6215A3ABD400C6D578 /* otr-30-negotiation.c in Sources */,
+                               4CC92A6315A3ABD400C6D578 /* otr-otrdh.c in Sources */,
+                               4CC92A6415A3ABD400C6D578 /* otr-packetdata.c in Sources */,
+                               4CC92A6515A3ABD400C6D578 /* si-00-find-nothing.c in Sources */,
+                               4CC92A6615A3ABD400C6D578 /* si-05-add.c in Sources */,
+                               4CC92A6715A3ABD400C6D578 /* si-10-find-internet.c in Sources */,
+                               4CC92A6815A3ABD400C6D578 /* si-11-update-data.c in Sources */,
+                               4CC92A6915A3ABD400C6D578 /* si-14-dateparse.c in Sources */,
+                               4CC92A6A15A3ABD400C6D578 /* si-15-certificate.c in Sources */,
+                               4CC92A6B15A3ABD400C6D578 /* si-16-ec-certificate.c in Sources */,
+                               4CC92A6C15A3ABD400C6D578 /* si-20-sectrust-activation.c in Sources */,
+                               4CC92A6D15A3ABD400C6D578 /* si-20-sectrust.c in Sources */,
+                               BE62D7601747FF3E001EAA9D /* si-72-syncableitems.c in Sources */,
+                               4CC92A6E15A3ABD400C6D578 /* si-21-sectrust-asr.c in Sources */,
+                               4CC92A6F15A3ABD400C6D578 /* si-22-sectrust-iap.c in Sources */,
+                               4CC92A7015A3ABD400C6D578 /* si-23-sectrust-ocsp.c in Sources */,
+                               4CC92A7115A3ABD400C6D578 /* si-24-sectrust-appleid.c in Sources */,
+                               4CC92A7215A3ABD400C6D578 /* si-24-sectrust-digicert-malaysia.c in Sources */,
+                               4CC92A7315A3ABD400C6D578 /* si-24-sectrust-diginotar.c in Sources */,
+                               4CC92A7415A3ABD400C6D578 /* si-24-sectrust-itms.c in Sources */,
+                               4CC92A7515A3ABD400C6D578 /* si-24-sectrust-mobileasset.c in Sources */,
+                               4CC92A7615A3ABD400C6D578 /* si-24-sectrust-nist.c in Sources */,
+                               4CC92A7715A3ABD400C6D578 /* si-24-sectrust-otatasking.c in Sources */,
+                               4CC92A7815A3ABD400C6D578 /* si-24-sectrust-shoebox.c in Sources */,
+                               4CC92A7915A3ABD400C6D578 /* si-25-sectrust-ipsec-eap.c in Sources */,
+                               4CC92A7A15A3ABD400C6D578 /* si-26-applicationsigning.c in Sources */,
+                               4CC92A7B15A3ABD400C6D578 /* si-27-sectrust-exceptions.c in Sources */,
+                               4CC92A7C15A3ABD400C6D578 /* si-28-sectrustsettings.c in Sources */,
+                               4CC92A7D15A3ABD400C6D578 /* si-29-sectrust-codesigning.c in Sources */,
+                               4CC92A7E15A3ABD400C6D578 /* si-30-keychain-upgrade.c in Sources */,
+                               4C2C8C3D17AB374700C24C13 /* si-12-item-stress.c in Sources */,
+                               4CC92A7F15A3ABD400C6D578 /* si-31-keychain-bad.c in Sources */,
+                               4CC92A8015A3ABD400C6D578 /* si-31-keychain-unreadable.c in Sources */,
+                               4CC92A8215A3ABD400C6D578 /* si-33-keychain-backup.c in Sources */,
+                               4CC92A8315A3ABD400C6D578 /* si-40-seckey-custom.c in Sources */,
+                               E7CA197A17179EC20065299C /* si-69-keydesc.c in Sources */,
+                               BE62D7621747FF51001EAA9D /* si-70-sectrust-unified.c in Sources */,
+                               4CC92A8415A3ABD400C6D578 /* si-40-seckey.c in Sources */,
+                               4CC92A8515A3ABD400C6D578 /* si-41-sececkey.c in Sources */,
+                               4CC92A8615A3ABD400C6D578 /* si-42-identity.c in Sources */,
+                               4CC92A8715A3ABD400C6D578 /* si-43-persistent.c in Sources */,
+                               4CC92A8815A3ABD400C6D578 /* si-50-secrandom.c in Sources */,
+                               4CC92A8915A3ABD400C6D578 /* si-60-cms.c in Sources */,
+                               5DE4A7BD17441CCD0036339E /* si-71-mobile-store-policy.c in Sources */,
+                               CDD565A2173193AC00B6B074 /* si-73-secpasswordgenerate.c in Sources */,
+                               4CC92A8A15A3ABD400C6D578 /* si-61-pkcs12.c in Sources */,
+                               4CC92A8B15A3ABD400C6D578 /* si-62-csr.c in Sources */,
+                               4CC92A8E15A3ABD400C6D578 /* si-63-scep.c in Sources */,
+                               4CC92A9615A3ABD400C6D578 /* si-64-ossl-cms.c in Sources */,
+                               7255A46C1783333D006A8B9A /* si-74-OTAPKISigner.c in Sources */,
+                               7255F91417A973D5004A9F38 /* si-75-AppleIDRecordSigning.c in Sources */,
+                               4CC92A9715A3ABD400C6D578 /* si-65-cms-cert-policy.c in Sources */,
+                               4CC92A9915A3ABD400C6D578 /* si-66-smime.c in Sources */,
+                               4CC92AA415A3ABD400C6D578 /* si-67-sectrust-blacklist.c in Sources */,
+                               4CC92AA515A3ABD400C6D578 /* vmdh-40.c in Sources */,
+                               4CC92AA615A3ABD400C6D578 /* vmdh-41-example.c in Sources */,
+                               4CC92AA715A3ABD400C6D578 /* vmdh-42-example2.c in Sources */,
+                               E748744515A61AF800624935 /* si-68-secmatchissuer.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               4CC92AC315A3BC6B00C6D578 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               4CC92AF915A3BC6B00C6D578 /* sd-10-policytree.c in Sources */,
+                               4C143CDE164D8EF5003035A3 /* sd-70-engine.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               5284029C164445760035F320 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               5214701B16977D7700DF0DB3 /* cloudkeychainproxy.m in Sources */,
+                               528402AE164446410035F320 /* CKDKVSProxy.m in Sources */,
+                               528402AF164446410035F320 /* CKDPersistentState.m in Sources */,
+                               528402B1164446410035F320 /* CKDUserInteraction.m in Sources */,
+                               528402B2164447610035F320 /* SOSCloudKeychainConstants.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               E702E73614E1F3EA00CDE635 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               4C1C452714EB27F50018B1D9 /* SOSTransport.c in Sources */,
+                               4802A59616D711060059E5B9 /* SOSUserKeygen.c in Sources */,
+                               4CC929B315A3957800C6D578 /* SOSAccount.c in Sources */,
+                               4CC929B515A3957800C6D578 /* SOSCircle.c in Sources */,
+                               4CC929B715A3957800C6D578 /* SOSPeer.c in Sources */,
+                               4C9DC91D15B602910036D941 /* SOSEngine.c in Sources */,
+                               E777C71E15B73F9E004044A8 /* SOSInternal.c in Sources */,
+                               E777C72615B87545004044A8 /* SOSPeerInfo.c in Sources */,
+                               E7217B2715F8131A00D26031 /* SOSCloudKeychainConstants.c in Sources */,
+                               E79277E3163B110A0096F3E2 /* SOSFullPeerInfo.c in Sources */,
+                               52EAF4BE163C52EB00803D0F /* SOSCloudKeychainClient.c in Sources */,
+                               488902EC16C2F88400F119FF /* SOSCoder.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               E702E75814E1F48800CDE635 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               4C6ED19615CB0E72004379B7 /* sc-30-peerinfo.c in Sources */,
+                               E777C6B115B4DDF2004044A8 /* sc-40-circle.c in Sources */,
+                               4C6ED19715CB0E72004379B7 /* sc-60-peer.c in Sources */,
+                               4C6ED19515CB0E44004379B7 /* sc-70-engine.c in Sources */,
+                               521C0A7615F908AF00604B61 /* sc-90-ckdclient.c in Sources */,
+                               521C0C8715FEB03300604B61 /* sc-120-cloudcircle.c in Sources */,
+                               521C0CD615FF9B3300604B61 /* SOSRegressionUtilities.c in Sources */,
+                               48CE733E1731C49A004C2946 /* sc-130-resignationticket.c in Sources */,
+                               4C4EBD541610D7D8007D06A5 /* sc-75-circle-engine.c in Sources */,
+                               4CB8A83816164B7700B52EC7 /* SOSTestDataSource.c in Sources */,
+                               521C691F16164B9900E31C3E /* sc-95-ckd2client.c in Sources */,
+                               4C5F2E38162DF76A00AF8346 /* SOSTestTransport.c in Sources */,
+                               E763D6231624E2670038477D /* sc-20-keynames.c in Sources */,
+                               52DEE9E2162DC8F1002F3BCD /* sc-100-devicecircle.c in Sources */,
+                               52AF7083163D9AA20092A7ED /* sc-101-accountsync.c in Sources */,
+                               52840281163F2B060035F320 /* sc-102-cfusernotification.c in Sources */,
+                               522B0ED21648809300A4675D /* sc-103-syncupdate.c in Sources */,
+                               5253946116608F6800BA9687 /* sc-51-persistentEC.c in Sources */,
+                               E7BE10A7167AB32300D2A178 /* sc-41-cloudcircle.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               E71049EE169E023B00DB0045 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               0CE7ABDF171383E30088968F /* keychain_backup.c in Sources */,
+                               E7104A01169E036E00DB0045 /* SecurityTool.c in Sources */,
+                               E790C10A169E4FD200E0C0C9 /* digest_calc.c in Sources */,
+                               E790C110169E53DF00E0C0C9 /* leaks.c in Sources */,
+                               4CD1897D169F835400BC96B8 /* print_cert.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               E7104A13169E216E00DB0045 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               E790C141169E5C6200E0C0C9 /* add_internet_password.c in Sources */,
+                               E790C142169E5C6200E0C0C9 /* codesign.c in Sources */,
+                               E790C143169E5C6200E0C0C9 /* keychain_add.c in Sources */,
+                               E790C144169E5C6200E0C0C9 /* keychain_find.c in Sources */,
+                               E790C145169E5C6200E0C0C9 /* pkcs12_util.c in Sources */,
+                               E790C147169E5C6200E0C0C9 /* scep.c in Sources */,
+                               E790C148169E5C6200E0C0C9 /* show_certificates.c in Sources */,
+                               E790C149169E5C6200E0C0C9 /* spc.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               E7FEFB83169E363300E18152 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               E7FEFB91169E36D800E18152 /* keychain_sync.c in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
 /* End PBXSourcesBuildPhase section */
 
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
 /* End PBXSourcesBuildPhase section */
 
+/* Begin PBXVariantGroup section */
+               521C0BAC15FA5DA800604B61 /* InfoPlist.strings */ = {
+                       isa = PBXVariantGroup;
+                       children = (
+                               521C0BAD15FA5DA800604B61 /* en */,
+                       );
+                       name = InfoPlist.strings;
+                       sourceTree = "<group>";
+               };
+/* End PBXVariantGroup section */
+
 /* Begin XCBuildConfiguration section */
 /* Begin XCBuildConfiguration section */
+               0C0BDB5D175687EC00BC1A7E /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 18270C9914CF1AAD00B05E7F /* lib.xcconfig */;
+                       buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                       };
+                       name = Debug;
+               };
+               0C0BDB5E175687EC00BC1A7E /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 18270C9914CF1AAD00B05E7F /* lib.xcconfig */;
+                       buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                       };
+                       name = Release;
+               };
                18270F5714CF651900B05E7F /* Debug */ = {
                        isa = XCBuildConfiguration;
                18270F5714CF651900B05E7F /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 18270C9814CF1AAD00B05E7F /* debug.xcconfig */;
+                       baseConfigurationReference = 18270C9914CF1AAD00B05E7F /* lib.xcconfig */;
                        buildSettings = {
                        buildSettings = {
-                               GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
+                               COMBINE_HIDPI_IMAGES = YES;
                                "GCC_PREPROCESSOR_DEFINITIONS[sdk=macosx*]" = (
                                        "$(inherited)",
                                        "SECITEM_SHIM_OSX=1",
                                "GCC_PREPROCESSOR_DEFINITIONS[sdk=macosx*]" = (
                                        "$(inherited)",
                                        "SECITEM_SHIM_OSX=1",
                };
                18270F5814CF651900B05E7F /* Release */ = {
                        isa = XCBuildConfiguration;
                };
                18270F5814CF651900B05E7F /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 18270C9A14CF1AAD00B05E7F /* release.xcconfig */;
+                       baseConfigurationReference = 18270C9914CF1AAD00B05E7F /* lib.xcconfig */;
                        buildSettings = {
                        buildSettings = {
-                               GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
+                               COMBINE_HIDPI_IMAGES = YES;
                                "GCC_PREPROCESSOR_DEFINITIONS[sdk=macosx*]" = (
                                        "$(inherited)",
                                        "SECITEM_SHIM_OSX=1",
                                "GCC_PREPROCESSOR_DEFINITIONS[sdk=macosx*]" = (
                                        "$(inherited)",
                                        "SECITEM_SHIM_OSX=1",
                };
                186CDD1114CA116C00AF9171 /* Debug */ = {
                        isa = XCBuildConfiguration;
                };
                186CDD1114CA116C00AF9171 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 18270C9914CF1AAD00B05E7F /* lib.xcconfig */;
+                       baseConfigurationReference = 18270C9814CF1AAD00B05E7F /* debug.xcconfig */;
                        buildSettings = {
                        buildSettings = {
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
                        };
                        name = Debug;
                };
                186CDD1214CA116C00AF9171 /* Release */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Debug;
                };
                186CDD1214CA116C00AF9171 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 18270C9914CF1AAD00B05E7F /* lib.xcconfig */;
+                       baseConfigurationReference = 18270C9A14CF1AAD00B05E7F /* release.xcconfig */;
                        buildSettings = {
                        buildSettings = {
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
                        };
                        name = Release;
                };
                186CDD1414CA116C00AF9171 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Release;
                };
                186CDD1414CA116C00AF9171 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 18270C9814CF1AAD00B05E7F /* debug.xcconfig */;
+                       baseConfigurationReference = 18270C9914CF1AAD00B05E7F /* lib.xcconfig */;
                        buildSettings = {
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                GCC_PREPROCESSOR_DEFINITIONS = (
                                        "$(inherited)",
                                        "SECITEM_SHIM_OSX=1",
                                GCC_PREPROCESSOR_DEFINITIONS = (
                                        "$(inherited)",
                                        "SECITEM_SHIM_OSX=1",
                };
                186CDD1514CA116C00AF9171 /* Release */ = {
                        isa = XCBuildConfiguration;
                };
                186CDD1514CA116C00AF9171 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 18270C9A14CF1AAD00B05E7F /* release.xcconfig */;
+                       baseConfigurationReference = 18270C9914CF1AAD00B05E7F /* lib.xcconfig */;
                        buildSettings = {
                        buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
                                GCC_PREPROCESSOR_DEFINITIONS = (
                                        "$(inherited)",
                                        "SECITEM_SHIM_OSX=1",
                                GCC_PREPROCESSOR_DEFINITIONS = (
                                        "$(inherited)",
                                        "SECITEM_SHIM_OSX=1",
                };
                18D4043714CE0CF300A2BE4E /* Debug */ = {
                        isa = XCBuildConfiguration;
                };
                18D4043714CE0CF300A2BE4E /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 18270C9814CF1AAD00B05E7F /* debug.xcconfig */;
+                       baseConfigurationReference = 18270C9914CF1AAD00B05E7F /* lib.xcconfig */;
                        buildSettings = {
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = NO;
+                               CLANG_WARN_ENUM_CONVERSION = NO;
+                               CLANG_WARN_INT_CONVERSION = NO;
+                               COMBINE_HIDPI_IMAGES = YES;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
                        };
                        name = Debug;
                };
                18D4043814CE0CF300A2BE4E /* Release */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Debug;
                };
                18D4043814CE0CF300A2BE4E /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 18270C9A14CF1AAD00B05E7F /* release.xcconfig */;
+                       baseConfigurationReference = 18270C9914CF1AAD00B05E7F /* lib.xcconfig */;
                        buildSettings = {
                        buildSettings = {
+                               CLANG_WARN_CONSTANT_CONVERSION = NO;
+                               CLANG_WARN_ENUM_CONVERSION = NO;
+                               CLANG_WARN_INT_CONVERSION = NO;
+                               COMBINE_HIDPI_IMAGES = YES;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
                        };
                        name = Release;
                };
                18D4056414CE53C200A2BE4E /* Debug */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Release;
                };
                18D4056414CE53C200A2BE4E /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 18270C9814CF1AAD00B05E7F /* debug.xcconfig */;
+                       baseConfigurationReference = 18270C9914CF1AAD00B05E7F /* lib.xcconfig */;
                        buildSettings = {
                        buildSettings = {
-                               GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
+                               COMBINE_HIDPI_IMAGES = YES;
                                "GCC_PREPROCESSOR_DEFINITIONS[sdk=macosx*]" = (
                                        "$(inherited)",
                                        "SECITEM_SHIM_OSX=1",
                                "GCC_PREPROCESSOR_DEFINITIONS[sdk=macosx*]" = (
                                        "$(inherited)",
                                        "SECITEM_SHIM_OSX=1",
                };
                18D4056514CE53C200A2BE4E /* Release */ = {
                        isa = XCBuildConfiguration;
                };
                18D4056514CE53C200A2BE4E /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 18270C9A14CF1AAD00B05E7F /* release.xcconfig */;
+                       baseConfigurationReference = 18270C9914CF1AAD00B05E7F /* lib.xcconfig */;
                        buildSettings = {
                        buildSettings = {
-                               GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
+                               COMBINE_HIDPI_IMAGES = YES;
                                "GCC_PREPROCESSOR_DEFINITIONS[sdk=macosx*]" = (
                                        "$(inherited)",
                                        "SECITEM_SHIM_OSX=1",
                                "GCC_PREPROCESSOR_DEFINITIONS[sdk=macosx*]" = (
                                        "$(inherited)",
                                        "SECITEM_SHIM_OSX=1",
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
+               4A5CCA5015ACEFA500702357 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 18270C9914CF1AAD00B05E7F /* lib.xcconfig */;
+                       buildSettings = {
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               COMBINE_HIDPI_IMAGES = YES;
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "DEBUG=1",
+                                       "$(inherited)",
+                               );
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                       };
+                       name = Debug;
+               };
+               4A5CCA5115ACEFA500702357 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 18270C9914CF1AAD00B05E7F /* lib.xcconfig */;
+                       buildSettings = {
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               COMBINE_HIDPI_IMAGES = YES;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                       };
+                       name = Release;
+               };
+               4A824B01158FF07000F932C0 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 18270C9914CF1AAD00B05E7F /* lib.xcconfig */;
+                       buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                       };
+                       name = Debug;
+               };
+               4A824B02158FF07000F932C0 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 18270C9914CF1AAD00B05E7F /* lib.xcconfig */;
+                       buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                       };
+                       name = Release;
+               };
+               4CC92B1215A3BC6B00C6D578 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 18270C9914CF1AAD00B05E7F /* lib.xcconfig */;
+                       buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                       };
+                       name = Debug;
+               };
+               4CC92B1315A3BC6B00C6D578 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 18270C9914CF1AAD00B05E7F /* lib.xcconfig */;
+                       buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                       };
+                       name = Release;
+               };
+               528402AA164445760035F320 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 4C5EA365164C791400A136B8 /* lib-arc-only.xcconfig */;
+                       buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                       };
+                       name = Debug;
+               };
+               528402AB164445760035F320 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 4C5EA365164C791400A136B8 /* lib-arc-only.xcconfig */;
+                       buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                       };
+                       name = Release;
+               };
+               E702E75414E1F3EA00CDE635 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 18270C9914CF1AAD00B05E7F /* lib.xcconfig */;
+                       buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                       };
+                       name = Debug;
+               };
+               E702E75514E1F3EA00CDE635 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 18270C9914CF1AAD00B05E7F /* lib.xcconfig */;
+                       buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                       };
+                       name = Release;
+               };
+               E702E77614E1F48800CDE635 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 18270C9914CF1AAD00B05E7F /* lib.xcconfig */;
+                       buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                       };
+                       name = Debug;
+               };
+               E702E77714E1F48800CDE635 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 18270C9914CF1AAD00B05E7F /* lib.xcconfig */;
+                       buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                       };
+                       name = Release;
+               };
+               E71049FB169E023B00DB0045 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 18270C9914CF1AAD00B05E7F /* lib.xcconfig */;
+                       buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                       };
+                       name = Debug;
+               };
+               E71049FC169E023B00DB0045 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 18270C9914CF1AAD00B05E7F /* lib.xcconfig */;
+                       buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                       };
+                       name = Release;
+               };
+               E7104A1B169E216E00DB0045 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 18270C9914CF1AAD00B05E7F /* lib.xcconfig */;
+                       buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                       };
+                       name = Debug;
+               };
+               E7104A1C169E216E00DB0045 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 18270C9914CF1AAD00B05E7F /* lib.xcconfig */;
+                       buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                       };
+                       name = Release;
+               };
+               E7FEFB8A169E363300E18152 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 18270C9914CF1AAD00B05E7F /* lib.xcconfig */;
+                       buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                       };
+                       name = Debug;
+               };
+               E7FEFB8B169E363300E18152 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 18270C9914CF1AAD00B05E7F /* lib.xcconfig */;
+                       buildSettings = {
+                               COMBINE_HIDPI_IMAGES = YES;
+                       };
+                       name = Release;
+               };
 /* End XCBuildConfiguration section */
 
 /* Begin XCConfigurationList section */
 /* End XCBuildConfiguration section */
 
 /* Begin XCConfigurationList section */
+               0C0BDB5C175687EC00BC1A7E /* Build configuration list for PBXNativeTarget "libsecdRegressions" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               0C0BDB5D175687EC00BC1A7E /* Debug */,
+                               0C0BDB5E175687EC00BC1A7E /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
                18270F5614CF651900B05E7F /* Build configuration list for PBXNativeTarget "libsecipc_client" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                18270F5614CF651900B05E7F /* Build configuration list for PBXNativeTarget "libsecipc_client" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
+               4A5CCA5215ACEFA500702357 /* Build configuration list for PBXNativeTarget "libSecOtrOSX" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               4A5CCA5015ACEFA500702357 /* Debug */,
+                               4A5CCA5115ACEFA500702357 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               4A824B00158FF07000F932C0 /* Build configuration list for PBXNativeTarget "libSecurityRegressions" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               4A824B01158FF07000F932C0 /* Debug */,
+                               4A824B02158FF07000F932C0 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               4CC92B1115A3BC6B00C6D578 /* Build configuration list for PBXNativeTarget "libsecuritydRegressions" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               4CC92B1215A3BC6B00C6D578 /* Debug */,
+                               4CC92B1315A3BC6B00C6D578 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               528402A9164445760035F320 /* Build configuration list for PBXNativeTarget "libCloudKeychainProxy" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               528402AA164445760035F320 /* Debug */,
+                               528402AB164445760035F320 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               E702E75314E1F3EA00CDE635 /* Build configuration list for PBXNativeTarget "libSecureObjectSync" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               E702E75414E1F3EA00CDE635 /* Debug */,
+                               E702E75514E1F3EA00CDE635 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               E702E77514E1F48800CDE635 /* Build configuration list for PBXNativeTarget "libSOSRegressions" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               E702E77614E1F48800CDE635 /* Debug */,
+                               E702E77714E1F48800CDE635 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               E71049FD169E023B00DB0045 /* Build configuration list for PBXNativeTarget "libSecurityTool" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               E71049FB169E023B00DB0045 /* Debug */,
+                               E71049FC169E023B00DB0045 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               E7104A1A169E216E00DB0045 /* Build configuration list for PBXNativeTarget "libSecurityCommands" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               E7104A1B169E216E00DB0045 /* Debug */,
+                               E7104A1C169E216E00DB0045 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               E7FEFB89169E363300E18152 /* Build configuration list for PBXNativeTarget "libSOSCommands" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               E7FEFB8A169E363300E18152 /* Debug */,
+                               E7FEFB8B169E363300E18152 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
 /* End XCConfigurationList section */
        };
        rootObject = 186CDD0614CA116C00AF9171 /* Project object */;
 /* End XCConfigurationList section */
        };
        rootObject = 186CDD0614CA116C00AF9171 /* Project object */;
diff --git a/sec/securityd/OTATrustUtilities.c b/sec/securityd/OTATrustUtilities.c
new file mode 100644 (file)
index 0000000..b6423c3
--- /dev/null
@@ -0,0 +1,1147 @@
+/*
+ * Copyright (c) 2003-2004,2006-2010 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ *
+ * OTATrustUtilities.c
+ */
+
+#include "OTATrustUtilities.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <sys/syslimits.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <ftw.h>
+#include "SecFramework.h"
+#include <pthread.h>
+#include <sys/param.h>
+#include <stdlib.h>
+#include <utilities/SecCFRelease.h>
+#include <utilities/SecCFError.h>
+#include <utilities/SecCFWrappers.h>
+#include <Security/SecBasePriv.h>
+#include <Security/SecFramework.h>
+#include <dispatch/dispatch.h>
+#include <CommonCrypto/CommonDigest.h>
+
+//#define VERBOSE_LOGGING 1
+
+#if VERBOSE_LOGGING
+
+static void TestOTALog(const char* sz, ...)
+{
+    va_list va;
+    va_start(va, sz);
+
+    FILE* fp = fopen("/tmp/secd_OTAUtil.log", "a");
+    if (NULL != fp)
+    {
+        vfprintf(fp, sz, va);
+        fclose(fp);
+    }
+    va_end(va);
+}
+
+#else
+
+#define TestOTALog(sz, ...)
+
+#endif
+
+
+//#define NEW_LOCATION 1
+
+#if NEW_LOCATION
+static const char*  kBaseAssertDirectory = "/var/OTAPKI/Assets";
+#else
+static const char*     kBaseAssertDirectory = "/var/Keychains/Assets";
+#endif
+
+static const char*     kVersionDirectoryNamePrefix = "Version_";
+static const char*     kNumberString = "%d";
+
+struct index_record
+{
+    unsigned char hash[CC_SHA1_DIGEST_LENGTH];
+    uint32_t offset;
+};
+typedef struct index_record index_record;
+
+
+struct _OpaqueSecOTAPKI 
+{
+       CFRuntimeBase           _base;
+       CFSetRef                        _blackListSet;
+       CFSetRef                        _grayListSet;
+       CFArrayRef                      _escrowCertificates;
+       CFDictionaryRef         _evPolicyToAnchorMapping;
+       CFDictionaryRef         _anchorLookupTable;
+       const char*                     _anchorTable;
+       int                                     _assetVersion;
+};
+
+CFGiblisFor(SecOTAPKI)
+
+static CF_RETURNS_RETAINED CFStringRef SecOTAPKICopyDescription(CFTypeRef cf) 
+{
+    SecOTAPKIRef otapkiRef = (SecOTAPKIRef)cf;
+    return CFStringCreateWithFormat(kCFAllocatorDefault,NULL,CFSTR("<SecOTAPKIRef: version %d>"), otapkiRef->_assetVersion);
+}
+
+static void SecOTAPKIDestroy(CFTypeRef cf) 
+{
+    SecOTAPKIRef otapkiref = (SecOTAPKIRef)cf;
+    
+    CFReleaseNull(otapkiref->_blackListSet);
+    CFReleaseNull(otapkiref->_grayListSet);
+    CFReleaseNull(otapkiref->_escrowCertificates);
+    
+    CFReleaseNull(otapkiref->_evPolicyToAnchorMapping);
+    CFReleaseNull(otapkiref->_anchorLookupTable);
+
+       free((void *)otapkiref->_anchorTable);
+}
+
+static CFDataRef SecOTACopyFileContents(const char *path)
+{
+    CFMutableDataRef data = NULL;
+    int fd = open(path, O_RDONLY, 0666);
+
+    if (fd == -1) 
+       {
+        goto badFile;
+    }
+
+    off_t fsize = lseek(fd, 0, SEEK_END);
+    if (fsize == (off_t)-1) 
+       {
+        goto badFile;
+    }
+
+       if (fsize > (off_t)INT32_MAX) 
+       {
+               goto badFile;
+       }
+
+    data = CFDataCreateMutable(kCFAllocatorDefault, (CFIndex)fsize);
+       if (NULL == data)
+       {
+               goto badFile;
+       }
+       
+    CFDataSetLength(data, (CFIndex)fsize);
+    void *buf = CFDataGetMutableBytePtr(data);
+       if (NULL == buf)
+       {
+               goto badFile;
+       }
+       
+    off_t total_read = 0;
+    while (total_read < fsize) 
+       {
+        ssize_t bytes_read;
+
+        bytes_read = pread(fd, buf, (size_t)(fsize - total_read), total_read);
+        if (bytes_read == -1) 
+               {
+            goto badFile;
+        }
+        if (bytes_read == 0) 
+               {
+            goto badFile;
+        }
+        total_read += bytes_read;
+    }
+
+       close(fd);
+    return data;
+
+badFile:
+    if (fd != -1) 
+       {
+               close(fd);
+    }
+
+    if (data)
+       {       
+               CFRelease(data);
+       }
+        
+    return NULL;
+}
+
+static Boolean PathExists(const char* path, size_t* pFileSize)
+{
+       TestOTALog("In PathExists: checking path %s\n", path);
+       Boolean result = false;
+       struct stat         sb;
+       
+       if (NULL != pFileSize)
+       {
+               *pFileSize = 0;
+       }
+       
+       int stat_result = stat(path, &sb);
+       result = (stat_result == 0);
+       
+    
+    if (result)
+    {
+               TestOTALog("In PathExists: stat returned 0 for %s\n", path);
+        if (S_ISDIR(sb.st_mode))
+        {
+                       TestOTALog("In PathExists: %s is a directory\n", path);
+            // It is a directory
+            ;
+        }
+        else
+        {
+                       TestOTALog("In PathExists: %s is a file\n", path);
+            // It is a file
+            if (NULL != pFileSize)
+            {
+                *pFileSize = (size_t)sb.st_size;
+            }
+        }
+    }
+#if VERBOSE_LOGGING
+       else
+       {
+               TestOTALog("In PathExists: stat returned %d for %s\n", stat_result, path);
+               int local_errno = errno;
+               switch(local_errno)
+               {
+                       case EACCES:
+                               TestOTALog("In PathExists: stat failed because of EACCES\n");
+                               break;
+                               
+                       case EBADF:
+                               TestOTALog("In PathExists: stat failed because of EBADF (Not likely)\n");
+                               break;
+                               
+                       case EFAULT:
+                               TestOTALog("In PathExists: stat failed because of EFAULT (huh?)\n");
+                               break;
+                               
+                       case ELOOP:
+                               TestOTALog("In PathExists: stat failed because of ELOOP (huh?)\n");
+                               break;
+                               
+                       case ENAMETOOLONG:
+                               TestOTALog("In PathExists: stat failed because of ENAMETOOLONG (huh?)\n");
+                               break;
+               
+                       case ENOENT:
+                               TestOTALog("In PathExists: stat failed because of ENOENT (missing?)\n");
+                               break;
+                               
+                       case ENOMEM:
+                               TestOTALog("In PathExists: stat failed because of ENOMEM (really?)\n");
+                               break;
+                               
+                       case ENOTDIR:
+                               TestOTALog("In PathExists: stat failed because of ENOTDIR (really?)\n");
+                               break;
+                               
+                       case EOVERFLOW:
+                               TestOTALog("In PathExists: stat failed because of EOVERFLOW (really?)\n");
+                               break;
+                               
+                       default:
+                               TestOTALog("In PathExists: unknown errno of %d\n", local_errno);
+                               break;
+               }
+       }
+#endif // #if VERBOSE_LOGGING
+       
+       return result;
+}
+
+static int unlink_cb(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf)
+{
+    int rv = remove(fpath); 
+    return rv;
+}
+
+static int rmrf(char *path)
+{
+       const char* p1 = NULL;
+       char path_buffer[PATH_MAX];
+       memset(path_buffer, 0, sizeof(path_buffer));
+       
+       p1 = realpath(path, path_buffer);
+       if (!strncmp(path, p1, PATH_MAX))
+       {
+               return nftw(path, unlink_cb, 64, FTW_DEPTH | FTW_PHYS);
+       }
+       return -1;
+}
+
+static const char* InitOTADirectory(int* pAssetVersion)
+{
+       TestOTALog("In InitOTADirectory\n");
+       const char* result = NULL;
+       
+       char buffer[PATH_MAX];
+    DIR *dp;
+    struct dirent *ep;
+    int version = 0;
+    int current_version = 0;
+    CFIndex asset_number = 0;
+    
+       bool assetDirectoryExists = PathExists(kBaseAssertDirectory, NULL);
+    if (assetDirectoryExists)
+    {
+               TestOTALog("InitOTADirectory: %s exists\n", kBaseAssertDirectory);
+               dp = opendir (kBaseAssertDirectory);
+               if (NULL != dp)
+               {
+                       TestOTALog("InitOTADirectory: opendir sucessfully open %s\n", kBaseAssertDirectory);
+                       while ((ep = readdir(dp)))
+                       {
+                               TestOTALog("InitOTADirectory: processing name %s\n", ep->d_name);
+                               if (strstr(ep->d_name, kVersionDirectoryNamePrefix))
+                               {
+                                       TestOTALog("InitOTADirectory: %s matches\n", ep->d_name);
+                                       memset(buffer, 0, sizeof(buffer));
+                                       snprintf(buffer,  sizeof(buffer), "%s%s", kVersionDirectoryNamePrefix, kNumberString);
+
+                                       sscanf(ep->d_name, buffer, &version);
+                                       
+                                       TestOTALog("InitOTADirectory: version = %d\n", version);
+
+                                       if (current_version > 0)
+                                       {
+                                               if (version > current_version)
+                                               {
+                                                       // There is more than one Version_ directory.
+                                                       // Delete the one with the smaller version number
+                                                       memset(buffer, 0, sizeof(buffer));
+                                                       snprintf(buffer,  sizeof(buffer), "%s/%s%d", kBaseAssertDirectory, kVersionDirectoryNamePrefix, current_version);
+                                                       if (PathExists(buffer, NULL))
+                                                       {
+                                                               rmrf(buffer);
+                                                       }
+                                                       current_version = version;
+                                               }
+                                       }
+                                       else
+                                       {
+                                               current_version = version;
+                                       }
+                               }
+                       }
+                       closedir(dp);
+               }
+               else
+               {
+                       TestOTALog("InitOTADirectory: opendir failed to open  %s\n", kBaseAssertDirectory);
+               }
+       }
+       else
+       {
+               TestOTALog("InitOTADirectory: PathExists returned false for %s\n", kBaseAssertDirectory);
+       }
+    
+       memset(buffer, 0, sizeof(buffer));
+   
+    if (0 == current_version)
+    {
+               TestOTALog("InitOTADirectory: current_version = 0\n");
+        // No Assets are installed so get the Asset Verson from the AssertVersion.plist in the Security.framework
+        
+        // Look in the resources for a AssetVerstion.plst file
+        
+        CFDataRef assetVersionData = SecFrameworkCopyResourceContents(CFSTR("AssetVersion"), CFSTR("plist"), NULL);
+        if (NULL != assetVersionData)
+        {
+            CFPropertyListFormat propFormat;
+            CFDictionaryRef versionPlist =  CFPropertyListCreateWithData(kCFAllocatorDefault, assetVersionData, 0, &propFormat, NULL);
+            if (NULL != versionPlist && CFDictionaryGetTypeID() == CFGetTypeID(versionPlist))
+            {
+                CFNumberRef versionNumber = (CFNumberRef)CFDictionaryGetValue(versionPlist, (const void *)CFSTR("VersionNumber"));
+                if (NULL != versionNumber)
+                {                    
+                                       CFNumberGetValue(versionNumber, kCFNumberCFIndexType, &asset_number);
+                }
+            }
+                   CFReleaseSafe(versionPlist);
+            CFReleaseSafe(assetVersionData);
+        }
+        
+        current_version = (int)asset_number;
+    }
+       else
+       {
+               TestOTALog("InitOTADirectory: current_version = %d\n", current_version);                
+           snprintf(buffer, sizeof(buffer), "%s/%s%d", kBaseAssertDirectory, kVersionDirectoryNamePrefix, current_version);
+           size_t length = strlen(buffer);
+           char* temp_str = (char*)malloc(length + 1);
+           memset(temp_str, 0, (length + 1));
+           strncpy(temp_str, buffer, length);
+               result = temp_str;
+       }
+       
+       if (NULL != pAssetVersion)
+       {
+               *pAssetVersion = current_version;
+       }
+       return result;
+}
+
+static CFSetRef InitializeBlackList(const char* path_ptr)
+{
+       CFSetRef result = NULL;
+
+       // Check to see if the EVRoots.plist file is in the asset location
+       CFDataRef xmlData = NULL;
+       const char* asset_path = path_ptr;
+       if (NULL == asset_path)
+       {
+               // There is no OTA asset file so use the file in the Sercurity.framework bundle
+               xmlData = SecFrameworkCopyResourceContents(CFSTR("Blocked"), CFSTR("plist"), NULL);
+       }
+       else
+       {
+               char file_path_buffer[PATH_MAX];
+               memset(file_path_buffer, 0, PATH_MAX);
+               snprintf(file_path_buffer, PATH_MAX, "%s/Blocked.plist", asset_path);
+        
+        xmlData = SecOTACopyFileContents(file_path_buffer);
+        
+               if (NULL == xmlData)
+               {
+            xmlData = SecFrameworkCopyResourceContents(CFSTR("Blocked"), CFSTR("plist"), NULL);
+               }
+       }
+
+       CFPropertyListRef blackKeys = NULL;
+    if (xmlData)
+       {
+        blackKeys = CFPropertyListCreateWithData(kCFAllocatorDefault, xmlData, kCFPropertyListImmutable, NULL, NULL);
+        CFRelease(xmlData);
+    }
+
+       if (blackKeys)
+       {
+               CFMutableSetRef tempSet = NULL;
+               if (CFGetTypeID(blackKeys) == CFArrayGetTypeID())
+               {
+                       tempSet = CFSetCreateMutable(kCFAllocatorDefault, 0, &kCFTypeSetCallBacks);
+                       if (NULL == tempSet)
+                       {
+                               CFRelease(blackKeys);
+                               return result;
+                       }
+                       CFArrayRef blackKeyArray = (CFArrayRef)blackKeys;
+                       CFIndex num_keys = CFArrayGetCount(blackKeyArray);
+                       for (CFIndex idx = 0; idx < num_keys; idx++)
+                       {
+                               CFDataRef key_data = (CFDataRef)CFArrayGetValueAtIndex(blackKeyArray, idx);
+                               CFSetAddValue(tempSet, key_data);
+                       }
+               }
+               else
+               {
+                       CFRelease(blackKeys);
+                       return result;
+               }
+
+               if (NULL != tempSet)
+               {
+                       result = tempSet;
+               }
+               CFRelease(blackKeys);
+    }
+
+       return result;
+}
+
+static CFSetRef InitializeGrayList(const char* path_ptr)
+{
+       CFSetRef result = NULL;
+       
+       // Check to see if the EVRoots.plist file is in the asset location
+       CFDataRef xmlData = NULL;
+       const char* asset_path = path_ptr;
+       if (NULL == asset_path)
+       {
+               // There is no updated asset file so use the file in the Sercurity.framework bundle
+               xmlData = SecFrameworkCopyResourceContents(CFSTR("GrayListedKeys"), CFSTR("plist"), NULL);
+       }
+       else
+       {
+               char file_path_buffer[PATH_MAX];
+               memset(file_path_buffer, 0, PATH_MAX);
+               snprintf(file_path_buffer, PATH_MAX, "%s/GrayListedKeys.plist", asset_path);
+
+        xmlData = SecOTACopyFileContents(file_path_buffer);
+        
+               if (NULL == xmlData)
+               {
+            xmlData = SecFrameworkCopyResourceContents(CFSTR("GrayListedKeys"), CFSTR("plist"), NULL); 
+        }
+       }
+
+       CFPropertyListRef grayKeys = NULL;
+    if (xmlData)
+       {
+        grayKeys = CFPropertyListCreateWithData(kCFAllocatorDefault, xmlData, kCFPropertyListImmutable, NULL, NULL);
+        CFRelease(xmlData);
+    }
+
+       if (grayKeys)
+       {
+               CFMutableSetRef tempSet = NULL;
+               if (CFGetTypeID(grayKeys) == CFArrayGetTypeID())
+               {
+                       tempSet = CFSetCreateMutable(kCFAllocatorDefault, 0, &kCFTypeSetCallBacks);
+                       if (NULL == tempSet)
+                       {
+                               CFRelease(grayKeys);
+                               return result;
+                       }
+                       CFArrayRef grayKeyArray = (CFArrayRef)grayKeys;
+                       CFIndex num_keys = CFArrayGetCount(grayKeyArray);
+                       for (CFIndex idx = 0; idx < num_keys; idx++)
+                       {
+                               CFDataRef key_data = (CFDataRef)CFArrayGetValueAtIndex(grayKeyArray, idx);
+                               CFSetAddValue(tempSet, key_data);
+                       }
+               }
+               else
+               {
+                       CFRelease(grayKeys);
+                       return result;
+               }
+
+               if (NULL != tempSet)
+               {
+                       result = tempSet;
+               }
+       
+               CFRelease(grayKeys);
+    }
+       return result;
+}
+
+static CFDictionaryRef InitializeEVPolicyToAnchorDigestsTable(const char* path_ptr)
+{
+       CFDictionaryRef result = NULL;
+
+       // Check to see if the EVRoots.plist file is in the asset location
+       CFDataRef xmlData = NULL;
+       const char* asset_path = path_ptr;
+       if (NULL == asset_path)
+       {
+               // There is no updated asset file so use the file in the Sercurity.framework bundle
+               xmlData = SecFrameworkCopyResourceContents(CFSTR("EVRoots"), CFSTR("plist"), NULL);
+       }
+       else
+       {
+        char file_path_buffer[PATH_MAX];
+        memset(file_path_buffer, 0, PATH_MAX);
+        snprintf(file_path_buffer, PATH_MAX, "%s/EVRoots.plist", asset_path);
+
+        xmlData = SecOTACopyFileContents(file_path_buffer);
+        
+               if (NULL == xmlData)
+               {
+                       xmlData = SecFrameworkCopyResourceContents(CFSTR("EVRoots"), CFSTR("plist"), NULL);
+               }
+       }
+       
+       CFPropertyListRef evroots = NULL;
+    if (xmlData) 
+       {
+        evroots = CFPropertyListCreateWithData(
+            kCFAllocatorDefault, xmlData, kCFPropertyListImmutable, NULL, NULL);
+        CFRelease(xmlData);
+    }
+
+       if (evroots) 
+       {
+               if (CFGetTypeID(evroots) == CFDictionaryGetTypeID()) 
+               {
+            /* @@@ Ensure that each dictionary key is a dotted list of digits,
+               each value is an NSArrayRef and each element in the array is a
+               20 byte digest. */
+
+                       result = (CFDictionaryRef)evroots;
+               } 
+               else 
+               {
+                       secwarning("EVRoot.plist is wrong type.");
+                       CFRelease(evroots);
+               }
+    }
+
+       return result;
+}
+
+static void* MapFile(const char* path, int* out_fd, size_t* out_file_size)
+{     
+       void* result = NULL;
+       void* temp_result = NULL;
+       if (NULL == path || NULL == out_fd || NULL == out_file_size)
+       {
+               return result;
+       }
+       
+       *out_fd = -1;
+       *out_file_size = 0;
+       
+       
+       *out_fd  = open(path, O_RDONLY, 0666);
+
+    if (*out_fd == -1) 
+       {
+               return result;
+    }
+
+    off_t fsize = lseek(*out_fd, 0, SEEK_END);
+    if (fsize == (off_t)-1) 
+       {
+               return result;
+    }
+
+       if (fsize > (off_t)INT32_MAX) 
+       {
+               close(*out_fd);
+               *out_fd = -1;
+               return result;
+       }
+       
+       size_t malloc_size = (size_t)fsize;
+               
+       temp_result = malloc(malloc_size);
+       if (NULL == temp_result)
+       {
+               close(*out_fd);
+               *out_fd = -1;
+               return result;
+       }
+       
+       *out_file_size = malloc_size;
+       
+       off_t total_read = 0;
+    while (total_read < fsize) 
+       {
+        ssize_t bytes_read;
+
+        bytes_read = pread(*out_fd, temp_result, (size_t)(fsize - total_read), total_read);
+        if (bytes_read == -1) 
+               {
+                       free(temp_result);
+                       temp_result = NULL;
+            close(*out_fd);
+                       *out_fd = -1;
+               return result;
+        }
+        if (bytes_read == 0) 
+               {
+            free(temp_result);
+                       temp_result = NULL;
+            close(*out_fd);
+                       *out_fd = -1;
+               return result;
+        }
+        total_read += bytes_read;
+    }
+       
+       if (NULL != temp_result)
+    {
+               result =  temp_result;
+    }
+
+       return result;
+}
+
+static void UnMapFile(void* mapped_data, size_t data_size)
+{
+#pragma unused(mapped_data, data_size)
+       if (NULL != mapped_data)
+       {
+               free((void *)mapped_data);
+               mapped_data = NULL;
+       }
+}
+
+static bool InitializeAnchorTable(const char* path_ptr, CFDictionaryRef* pLookupTable, const char** ppAnchorTable)
+{
+       
+       bool result = false;
+       
+       if (NULL == pLookupTable || NULL == ppAnchorTable)
+       {
+               return result;
+       }
+       
+       *pLookupTable = NULL;
+       *ppAnchorTable = NULL;;
+       
+   // first see if there is a file at /var/db/OTA_Anchors
+    const char*                dir_path = NULL;
+       CFDataRef                               cert_index_file_data = NULL;
+       char                                    file_path_buffer[PATH_MAX];
+       CFURLRef                                table_data_url = NULL;
+       CFStringRef                             table_data_cstr_path = NULL;
+       const char*                             table_data_path = NULL;
+       const index_record*     pIndex = NULL;
+       size_t                  index_offset = 0;
+       size_t                                  index_data_size = 0;
+       CFMutableDictionaryRef  anchorLookupTable = NULL;
+       uint32_t                                offset_int_value = 0;
+       CFNumberRef             index_offset_value = NULL;
+       CFDataRef               index_hash = NULL;
+       CFMutableArrayRef       offsets = NULL;
+       Boolean                                 release_offset = false;
+       
+       char* local_anchorTable = NULL;
+       size_t local_anchorTableSize = 0;
+       int local_anchorTable_fd = -1;
+    
+       // ------------------------------------------------------------------------
+       // First determine if there are asset files at /var/Keychains.  If there 
+       // are files use them for the trust table.  Otherwise, use the files in the
+       // Security.framework bundle.
+       //
+       // The anchor table file is mapped into memory. This SHOULD be OK as the
+       // size of the data is around 250K.
+       // ------------------------------------------------------------------------
+       dir_path = path_ptr;
+       
+       if (NULL != dir_path)
+       {
+               // There is a set of OTA asset files
+               memset(file_path_buffer, 0, PATH_MAX);
+               snprintf(file_path_buffer, PATH_MAX, "%s/certsIndex.data", dir_path);
+        cert_index_file_data = SecOTACopyFileContents(file_path_buffer);
+        
+               if (NULL != cert_index_file_data)
+               {
+                       memset(file_path_buffer, 0, PATH_MAX);
+                       snprintf(file_path_buffer, PATH_MAX, "%s/certsTable.data", dir_path);
+            local_anchorTable  = (char *)MapFile(file_path_buffer, &local_anchorTable_fd, &local_anchorTableSize);
+        }
+
+               free((void *)dir_path);
+        dir_path = NULL;
+       }
+       
+       // Check to see if kAnchorTable was indeed set
+       if (NULL == local_anchorTable)
+    {  
+               // local_anchorTable is still NULL so the asset in the Security framework needs to be used.
+        CFReleaseSafe(cert_index_file_data);
+        cert_index_file_data = SecFrameworkCopyResourceContents(CFSTR("certsIndex"), CFSTR("data"), NULL);
+        table_data_url =  SecFrameworkCopyResourceURL(CFSTR("certsTable"), CFSTR("data"), NULL);
+        if (NULL != table_data_url)
+        {
+            table_data_cstr_path  = CFURLCopyFileSystemPath(table_data_url, kCFURLPOSIXPathStyle);
+            if (NULL != table_data_cstr_path)
+            {
+                memset(file_path_buffer, 0, PATH_MAX);
+                table_data_path = CFStringGetCStringPtr(table_data_cstr_path, kCFStringEncodingUTF8);
+                if (NULL == table_data_path)
+                {
+                    if (CFStringGetCString(table_data_cstr_path, file_path_buffer, PATH_MAX, kCFStringEncodingUTF8))
+                    {
+                        table_data_path = file_path_buffer;
+                    }
+                }
+                local_anchorTable  = (char *)MapFile(table_data_path, &local_anchorTable_fd, &local_anchorTableSize);
+                CFReleaseSafe(table_data_cstr_path);
+            }
+        }
+               CFReleaseSafe(table_data_url);
+       }
+               
+       if (NULL == local_anchorTable || NULL  == cert_index_file_data)
+       {
+               // we are in trouble
+               CFReleaseSafe(cert_index_file_data);
+               return result;
+       }
+
+       // ------------------------------------------------------------------------
+       // Now that the locations of the files are known and the table file has
+       // been mapped into memory, create a dictionary that maps the SHA1 hash of
+       // normalized issuer to the offset in the mapped anchor table file which
+       // contains a index_record to the correct certificate
+       // ------------------------------------------------------------------------
+       pIndex = (const index_record*)CFDataGetBytePtr(cert_index_file_data);
+       index_data_size = CFDataGetLength(cert_index_file_data);
+
+    anchorLookupTable = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 
+               &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+
+    for (index_offset = index_data_size; index_offset > 0; index_offset -= sizeof(index_record), pIndex++)
+    {
+        offset_int_value = pIndex->offset;
+
+        index_offset_value = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &offset_int_value);
+        index_hash = CFDataCreate(kCFAllocatorDefault, pIndex->hash, CC_SHA1_DIGEST_LENGTH);
+
+        // see if the dictionary already has this key
+               release_offset = false;
+        offsets = (CFMutableArrayRef)CFDictionaryGetValue(anchorLookupTable, index_hash);
+        if (NULL == offsets)
+        {
+                       offsets = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+                       release_offset = true;
+        }
+
+        // Add the offset
+        CFArrayAppendValue(offsets, index_offset_value);
+
+        // set the key value pair in the dictionary
+        CFDictionarySetValue(anchorLookupTable, index_hash, offsets);
+
+        CFRelease(index_offset_value);
+        CFRelease(index_hash);
+               if (release_offset)
+               {
+                       CFRelease(offsets);
+               }
+     }
+
+    CFRelease(cert_index_file_data);
+    
+    if (NULL != anchorLookupTable && NULL != local_anchorTable)
+    {
+               *pLookupTable = anchorLookupTable;
+               *ppAnchorTable = local_anchorTable;
+               result = true;
+    }
+    else
+    {
+               CFReleaseSafe(anchorLookupTable);
+        if (NULL != local_anchorTable)
+        {
+                       UnMapFile(local_anchorTable, local_anchorTableSize);
+            //munmap(kAnchorTable, local_anchorTableSize);
+            local_anchorTable = NULL;
+            local_anchorTableSize = 0;
+        }
+    }
+       
+       return result;  
+}
+
+static CFArrayRef InitializeEscrowCertificates(const char* path_ptr)
+{      
+       CFArrayRef result = NULL;
+       CFDataRef file_data = NULL;
+       
+       const char* dir_path = path_ptr;
+       if (NULL == dir_path)
+       {
+               file_data = SecFrameworkCopyResourceContents(CFSTR("AppleESCertificates"), CFSTR("plist"), NULL);
+       }
+       else
+       {
+               char buffer[1024];
+               memset(buffer, 0, 1024);
+               snprintf(buffer, 1024, "%s/AppleESCertificates.plist", dir_path);
+               file_data =  SecOTACopyFileContents(buffer);
+       }
+       
+       if (NULL != file_data)
+       {
+               CFPropertyListFormat propFormat;
+               CFDictionaryRef certsDictionary =  CFPropertyListCreateWithData(kCFAllocatorDefault, file_data, 0, &propFormat, NULL);          
+               if (NULL != certsDictionary && CFDictionaryGetTypeID() == CFGetTypeID((CFTypeRef)certsDictionary))
+               {       
+                       CFArrayRef certs = (CFArrayRef)CFDictionaryGetValue(certsDictionary, CFSTR("ProductionEscrowKey"));
+                       if (NULL != certs && CFArrayGetTypeID() == CFGetTypeID((CFTypeRef)certs) && CFArrayGetCount(certs) > 0)
+                       {
+                               result = CFArrayCreateCopy(kCFAllocatorDefault, certs);
+                       }
+                       CFRelease(certsDictionary);
+               }
+               CFRelease(file_data);
+       }
+       
+       return result;
+}
+
+
+static SecOTAPKIRef SecOTACreate()
+{
+       TestOTALog("In SecOTACreate\n");
+       
+       SecOTAPKIRef otapkiref = NULL;
+
+    otapkiref = CFTypeAllocate(SecOTAPKI, struct _OpaqueSecOTAPKI , kCFAllocatorDefault);
+
+       if (NULL == otapkiref)
+       {
+               return otapkiref;
+       }
+       
+       // Mkae suer that if this routine has to bail that the clean up 
+       // will do the right thing
+       otapkiref->_blackListSet = NULL;
+       otapkiref->_grayListSet = NULL;
+       otapkiref->_escrowCertificates = NULL;
+       otapkiref->_evPolicyToAnchorMapping = NULL;
+       otapkiref->_anchorLookupTable = NULL;
+       otapkiref->_anchorTable = NULL;
+       otapkiref->_assetVersion = 0;
+       
+       // Start off by getting the correct asset directory info
+       int asset_version = 0;
+       const char* path_ptr = InitOTADirectory(&asset_version);
+       otapkiref->_assetVersion = asset_version;
+       
+       TestOTALog("SecOTACreate: asset_path = %s\n", path_ptr);        
+       TestOTALog("SecOTACreate: asset_version = %d\n", asset_version);
+       
+       // Get the set of black listed keys
+       CFSetRef blackKeysSet = InitializeBlackList(path_ptr);
+       if (NULL == blackKeysSet)
+       {
+               CFReleaseNull(otapkiref);
+               return otapkiref;
+       }
+       otapkiref->_blackListSet = blackKeysSet;
+       
+       // Get the set of gray listed keys
+       CFSetRef grayKeysSet = InitializeGrayList(path_ptr);
+       if (NULL == grayKeysSet)
+       {
+               CFReleaseNull(otapkiref);
+               return otapkiref;
+       }
+       otapkiref->_grayListSet = grayKeysSet;
+       
+       CFArrayRef escrowCerts = InitializeEscrowCertificates(path_ptr);
+       if (NULL == escrowCerts)
+       {
+               CFReleaseNull(otapkiref);
+               return otapkiref;
+       }
+       otapkiref->_escrowCertificates = escrowCerts;
+       
+       // Geht the mapping of EV Policy OIDs to Anchor digest
+       CFDictionaryRef evOidToAnchorDigestMap = InitializeEVPolicyToAnchorDigestsTable(path_ptr);
+       if (NULL == evOidToAnchorDigestMap)
+       {
+               CFReleaseNull(otapkiref);
+               return otapkiref;
+       }
+       otapkiref->_evPolicyToAnchorMapping = evOidToAnchorDigestMap;
+       
+       CFDictionaryRef anchorLookupTable = NULL;
+       const char* anchorTablePtr = NULL;
+       
+       if (!InitializeAnchorTable(path_ptr, &anchorLookupTable, &anchorTablePtr))
+       {
+               CFReleaseSafe(anchorLookupTable);
+               if (NULL != anchorTablePtr)
+               {
+                       free((void *)anchorTablePtr);
+               }
+               
+               CFReleaseNull(otapkiref);
+               return otapkiref;
+       }
+       otapkiref->_anchorLookupTable = anchorLookupTable;
+       otapkiref->_anchorTable = anchorTablePtr;
+       return otapkiref;               
+}
+
+static dispatch_once_t kInitializeOTAPKI = 0;
+static const char* kOTAQueueLabel = "com.apple.security.OTAPKIQueue";
+static dispatch_queue_t kOTAQueue;
+static SecOTAPKIRef kCurrentOTAPKIRef = NULL;
+
+SecOTAPKIRef SecOTAPKICopyCurrentOTAPKIRef()
+{
+       __block SecOTAPKIRef result = NULL;
+       dispatch_once(&kInitializeOTAPKI,
+               ^{
+                       kOTAQueue = dispatch_queue_create(kOTAQueueLabel, NULL);
+                       kCurrentOTAPKIRef = SecOTACreate();
+               });
+
+       dispatch_sync(kOTAQueue, 
+               ^{
+                       result = kCurrentOTAPKIRef;
+                       CFRetainSafe(result);
+               });
+       return result;
+}
+
+
+CFSetRef SecOTAPKICopyBlackListSet(SecOTAPKIRef otapkiRef)
+{
+       CFSetRef result = NULL;
+       if (NULL == otapkiRef)
+       {
+               return result;
+       }
+       
+       result = otapkiRef->_blackListSet;
+       CFRetainSafe(result);
+       return result;
+}
+
+
+CFSetRef SecOTAPKICopyGrayList(SecOTAPKIRef otapkiRef)
+{
+       CFSetRef result = NULL;
+       if (NULL == otapkiRef)
+       {
+               return result;
+       }
+       
+       result = otapkiRef->_grayListSet;
+       CFRetainSafe(result);
+       return result;
+}
+
+CFArrayRef SecOTAPKICopyEscrowCertificates(SecOTAPKIRef otapkiRef)
+{
+       CFArrayRef result = NULL;
+       if (NULL == otapkiRef)
+       {
+               return result;
+       }
+       
+       result = otapkiRef->_escrowCertificates;
+       CFRetainSafe(result);
+       return result;
+}
+
+
+CFDictionaryRef SecOTAPKICopyEVPolicyToAnchorMapping(SecOTAPKIRef otapkiRef)
+{
+       CFDictionaryRef result = NULL;
+       if (NULL == otapkiRef)
+       {
+               return result;
+       }
+       
+       result = otapkiRef->_evPolicyToAnchorMapping;
+       CFRetainSafe(result);
+       return result;
+}
+
+
+CFDictionaryRef SecOTAPKICopyAnchorLookupTable(SecOTAPKIRef otapkiRef)
+{
+       CFDictionaryRef result = NULL;
+       if (NULL == otapkiRef)
+       {
+               return result;
+       }
+       
+       result = otapkiRef->_anchorLookupTable;
+       CFRetainSafe(result);
+       return result;
+}
+
+const char*    SecOTAPKIGetAnchorTable(SecOTAPKIRef otapkiRef)
+{
+       const char* result = NULL;
+       if (NULL == otapkiRef)
+       {
+               return result;
+       }
+       
+       result = otapkiRef->_anchorTable;
+       return result;
+}
+
+int SecOTAPKIGetAssetVersion(SecOTAPKIRef otapkiRef)
+{
+       int result = 0;
+       if (NULL == otapkiRef)
+       {
+               return result;
+       }
+       
+       result = otapkiRef->_assetVersion;
+       return result;
+}
+
+void SecOTAPKIRefreshData()
+{
+       TestOTALog("In SecOTAPKIRefreshData\n");
+       SecOTAPKIRef new_otaPKRef = SecOTACreate();
+       dispatch_sync(kOTAQueue, 
+               ^{
+                       CFReleaseSafe(kCurrentOTAPKIRef);
+                       kCurrentOTAPKIRef = new_otaPKRef;
+               });
+}
+
+CFArrayRef SecOTAPKICopyCurrentEscrowCertificates(CFErrorRef* error)
+{
+       CFArrayRef result = NULL;
+       
+       SecOTAPKIRef otapkiref = SecOTAPKICopyCurrentOTAPKIRef();
+       if (NULL == otapkiref)
+       {
+               SecError(errSecInternal, error, CFSTR("Unable to get the current OTAPKIRef"));
+               return result;
+       }
+       
+       result = SecOTAPKICopyEscrowCertificates(otapkiref);
+       CFRelease(otapkiref);
+       
+       if (NULL == result)
+       {
+               SecError(errSecInternal, error, CFSTR("Could not get the array of escrow certificates form the current OTAPKIRef"));
+       }
+       return result;
+}
+
+int SecOTAPKIGetCurrentAssetVersion(CFErrorRef* error)
+{
+       int result = 0;
+       
+       SecOTAPKIRef otapkiref = SecOTAPKICopyCurrentOTAPKIRef();
+       if (NULL == otapkiref)
+       {
+               SecError(errSecInternal, error, CFSTR("Unable to get the current OTAPKIRef"));
+               return result;
+       }
+       
+       result = otapkiref->_assetVersion;
+       return result;
+}
+
+int SecOTAPKISignalNewAsset(CFErrorRef* error)
+{
+       TestOTALog("SecOTAPKISignalNewAsset has been called!\n");
+       SecOTAPKIRefreshData();
+       return 1;       
+}
diff --git a/sec/securityd/OTATrustUtilities.h b/sec/securityd/OTATrustUtilities.h
new file mode 100644 (file)
index 0000000..f27218b
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2003-2004,2006-2010 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ *
+ * OTATrustUtilities.h
+ */
+
+#ifndef _OTATRUSTUTILITIES_H_
+#define _OTATRUSTUTILITIES_H_  1
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+__BEGIN_DECLS
+
+// Opawue type that holds the data for a specific version of the OTA PKI assets
+typedef struct _OpaqueSecOTAPKI *SecOTAPKIRef;
+
+// Get a reference to the current OTA PKI asset data
+// Caller is responsible for releasing the returned SecOTAPKIRef
+CF_EXPORT
+SecOTAPKIRef SecOTAPKICopyCurrentOTAPKIRef(void);
+
+// Accessor to retrieve a copy of the current black listed key.  
+// Caller is responsible for releasing the returned CFSetRef
+CF_EXPORT
+CFSetRef SecOTAPKICopyBlackListSet(SecOTAPKIRef otapkiRef);
+
+// Accessor to retrieve a copy of the current gray listed key.  
+// Caller is responsible for releasing the returned CFSetRef
+CF_EXPORT
+CFSetRef SecOTAPKICopyGrayList(SecOTAPKIRef otapkiRef);
+
+// Accessor to retrieve the array of Escrow certificates
+// Caller is responsible for releasing the returned CFArrayRef
+CF_EXPORT
+CFArrayRef SecOTAPKICopyEscrowCertificates(SecOTAPKIRef otapkiRef);
+
+// Accessor to retrieve the dictionary of EV Policy OIDs to Anchor digest
+// Caller is responsible for releasing the returned CFDictionaryRef
+CF_EXPORT
+CFDictionaryRef SecOTAPKICopyEVPolicyToAnchorMapping(SecOTAPKIRef otapkiRef);
+
+// Accessor to retrieve the dictionary of anchor digest to file offest
+// Caller is responsible for releasing the returned CFDictionaryRef
+CF_EXPORT
+CFDictionaryRef SecOTAPKICopyAnchorLookupTable(SecOTAPKIRef otapkiRef);
+
+// Accessor to retrieve the ponter to the top of the anchor certs file
+// Caller should NOT free the returned pointer.  The caller should hold
+// a reference to the SecOTAPKIRef object until finishing processing with
+// the returned const char*
+CF_EXPORT
+const char*    SecOTAPKIGetAnchorTable(SecOTAPKIRef otapkiRef);
+
+// Accessor to retrieve the current OTA PKI asset version number
+CF_EXPORT
+int SecOTAPKIGetAssetVersion(SecOTAPKIRef otapkiRef);
+
+// Signal that a new OTA PKI asset version is available. This call
+// will update the current SecOTAPKIRef to now reference the latest
+// asset data
+CF_EXPORT
+void SecOTAPKIRefreshData(void);
+
+// SPI to return the array of currently trusted Escrow certificates
+CF_EXPORT
+CFArrayRef SecOTAPKICopyCurrentEscrowCertificates(CFErrorRef* error);
+
+// SPI to return the current OTA PKI asset version
+CF_EXPORT
+int SecOTAPKIGetCurrentAssetVersion(CFErrorRef* error); 
+
+// SPI to signal securityd to get a new set of trust data
+CF_EXPORT
+int SecOTAPKISignalNewAsset(CFErrorRef* error);
+
+__END_DECLS
+
+#endif /* _OTATRUSTUTILITIES_H_ */
diff --git a/sec/securityd/Regressions/SOSAccountTesting.h b/sec/securityd/Regressions/SOSAccountTesting.h
new file mode 100644 (file)
index 0000000..00c1ec1
--- /dev/null
@@ -0,0 +1,254 @@
+//
+//  SOSAccountTesting.h
+//  sec
+//
+//  Created by Mitch Adler on 6/18/13.
+//
+//
+
+#ifndef SEC_SOSAccountTesting_h
+#define SEC_SOSAccountTesting_h
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <SecureObjectSync/SOSAccount.h>
+
+//
+// Account comparison
+//
+
+#define kAccountsAgreeTestMin 9
+#define kAccountsAgreeTestPerPeer 1
+#define accountsAgree(x) (kAccountsAgreeTestMin + kAccountsAgreeTestPerPeer * (x))
+
+static void unretired_peers_is_subset(const char* label, CFArrayRef peers, CFArrayRef allowed_peers)
+{
+    CFArrayForEach(peers, ^(const void *value) {
+        SOSPeerInfoRef pi = (SOSPeerInfoRef) value;
+        CFErrorRef leftError = NULL;
+        CFErrorRef rightError = NULL;
+        
+        ok(SOSPeerInfoIsRetirementTicket(pi) || SOSPeerInfoIsCloudIdentity(pi) || CFArrayContainsValue(allowed_peers, CFRangeMake(0, CFArrayGetCount(allowed_peers)), pi), "Peer is allowed (%s) Peer: %@, Allowed %@", label, pi, allowed_peers);
+        
+        CFReleaseNull(leftError);
+        CFReleaseNull(rightError);
+    });
+}
+
+static void accounts_agree_internal(char *label, SOSAccountRef left, SOSAccountRef right, bool check_peers)
+{
+    CFErrorRef error = NULL;
+    {
+        CFArrayRef leftPeers = SOSAccountCopyActivePeers(left, &error);
+        ok(leftPeers, "Left peers (%@) - %s", error, label);
+        CFReleaseNull(error);
+
+        CFArrayRef rightPeers = SOSAccountCopyActivePeers(right, &error);
+        ok(rightPeers, "Right peers (%@) - %s", error, label);
+        CFReleaseNull(error);
+
+        ok(CFEqual(leftPeers, rightPeers), "Matching peers (%s) Left: %@, Right: %@", label, leftPeers, rightPeers);
+
+        if (check_peers) {
+            CFMutableArrayRef allowed_identities = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
+
+            CFArrayRef leftIdentities = SOSAccountCopyAccountIdentityPeerInfos(left, kCFAllocatorDefault, &error);
+            ok(leftIdentities, "Get identities (%@)", error);
+            CFReleaseNull(error);
+            
+            CFArrayAppendArray(allowed_identities, leftIdentities, CFRangeMake(0, CFArrayGetCount(leftIdentities)));
+            
+            CFReleaseNull(leftIdentities);
+            
+            CFArrayRef rightIdentities = SOSAccountCopyAccountIdentityPeerInfos(right, kCFAllocatorDefault, &error);
+            ok(rightIdentities, "Get identities (%@)", error);
+            CFReleaseNull(error);
+            
+            CFArrayAppendArray(allowed_identities, rightIdentities, CFRangeMake(0, CFArrayGetCount(rightIdentities)));
+            
+            CFReleaseNull(rightIdentities);
+
+            unretired_peers_is_subset(label, leftPeers, allowed_identities);
+        }
+
+        CFReleaseNull(leftPeers);
+        CFReleaseNull(rightPeers);
+    }
+    {
+        CFArrayRef leftConcurringPeers = SOSAccountCopyConcurringPeers(left, &error);
+        ok(leftConcurringPeers, "Left peers (%@) - %s", error, label);
+
+        CFArrayRef rightConcurringPeers = SOSAccountCopyConcurringPeers(right, &error);
+        ok(rightConcurringPeers, "Right peers (%@) - %s", error, label);
+
+        ok(CFEqual(leftConcurringPeers, rightConcurringPeers), "Matching concurring peers Left: %@, Right: %@", leftConcurringPeers, rightConcurringPeers);
+
+        CFReleaseNull(leftConcurringPeers);
+        CFReleaseNull(rightConcurringPeers);
+    }
+    {
+        CFArrayRef leftApplicants = SOSAccountCopyApplicants(left, &error);
+        ok(leftApplicants, "Left Applicants (%@) - %s", error, label);
+
+        CFArrayRef rightApplicants = SOSAccountCopyApplicants(right, &error);
+        ok(rightApplicants, "Left Applicants (%@) - %s", error, label);
+
+        ok(CFEqual(leftApplicants, rightApplicants), "Matching applicants (%s) Left: %@, Right: %@", label, leftApplicants, rightApplicants);
+
+        CFReleaseNull(leftApplicants);
+        CFReleaseNull(rightApplicants);
+    }
+}
+
+static inline void accounts_agree(char *label, SOSAccountRef left, SOSAccountRef right)
+{
+    accounts_agree_internal(label, left, right, true);
+}
+
+
+//
+// Change handling
+//
+
+static CFMutableDictionaryRef ExtractPendingChanges(CFMutableDictionaryRef changes)
+{
+    CFMutableDictionaryRef extracted = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, changes);
+
+    CFDictionaryRemoveAllValues(changes);
+
+    return extracted;
+}
+
+#define kFeedChangesToMultieTestCountPer 1
+static inline void FeedChangesToMulti(CFMutableDictionaryRef changes, ...)
+{
+    CFDictionaryRef changes_to_send = ExtractPendingChanges(changes);
+
+    SOSAccountRef account;
+
+    secerror("Change block: %@", changes_to_send);
+
+    CFErrorRef error = NULL;
+       va_list argp;
+       va_start(argp, changes);
+    while((account = va_arg(argp, SOSAccountRef)) != NULL) {
+        ok(SOSAccountHandleUpdates(account, changes_to_send, &error), "SOSAccountHandleUpdates failed (%@)", error);
+        CFReleaseNull(error);
+    }
+}
+
+static inline void InjectChangeToMulti(CFStringRef changeKey, CFStringRef changeValue, ...)
+{
+    CFMutableDictionaryRef changes_to_send = CFDictionaryCreateMutable(NULL, 1, NULL, NULL);
+    CFDictionaryAddValue(changes_to_send, changeKey, changeValue);
+    
+    SOSAccountRef account;
+    
+    secerror("Change block: %@", changes_to_send);
+    
+    CFErrorRef error = NULL;
+       va_list argp;
+       va_start(argp, changeValue);
+    while((account = va_arg(argp, SOSAccountRef)) != NULL) {
+        ok(SOSAccountHandleUpdates(account, changes_to_send, &error), "SOSAccountHandleUpdates failed (%@)", error);
+        CFReleaseNull(error);
+    }
+    CFReleaseNull(changes_to_send);
+}
+
+
+
+#define kFeedChangesToTestCount 1
+static inline void FeedChangesTo(CFMutableDictionaryRef changes, SOSAccountRef account)
+{
+    CFDictionaryRef changes_to_send = ExtractPendingChanges(changes);
+
+    secerror("Change block: %@", changes_to_send);
+
+    CFErrorRef error = NULL;
+    ok(SOSAccountHandleUpdates(account, changes_to_send, &error), "SOSAccountHandleUpdates failed (%@)", error);
+    CFReleaseNull(error);
+    CFReleaseNull(changes_to_send);
+}
+
+
+static SOSAccountRef CreateAccountForLocalChanges(CFMutableDictionaryRef changes, CFStringRef name, CFStringRef data_source_name)
+{
+    SOSAccountKeyInterestBlock interest_block = ^(bool getNewKeysOnly, CFArrayRef alwaysKeys, CFArrayRef afterFirstUnlockKeys, CFArrayRef unlockedKeys) {};
+    SOSAccountDataUpdateBlock update_block = ^ bool (CFDictionaryRef keys, CFErrorRef *error) {
+        CFDictionaryForEach(keys, ^(const void *key, const void *value) {
+            CFDictionarySetValue(changes, key, value);
+        });
+        return true;
+    };
+
+    SOSDataSourceFactoryRef factory = SOSTestDataSourceFactoryCreate();
+    SOSTestDataSourceFactoryAddDataSource(factory, data_source_name, SOSTestDataSourceCreate());
+
+    CFDictionaryRef gestalt = SOSCreatePeerGestaltFromName(name);
+
+    SOSAccountRef result = SOSAccountCreate(kCFAllocatorDefault, gestalt, factory, interest_block, update_block);
+
+    CFReleaseNull(gestalt);
+
+    return result;
+}
+
+
+static inline int countPeers(SOSAccountRef account) {
+    CFErrorRef error = NULL;
+    CFArrayRef peers;
+    
+    peers = SOSAccountCopyPeers(account, &error);
+    int retval = (int) CFArrayGetCount(peers);
+    CFReleaseNull(error);
+    CFReleaseNull(peers);
+    return retval;
+}
+
+static inline int countActivePeers(SOSAccountRef account) {
+    CFErrorRef error = NULL;
+    CFArrayRef peers;
+    
+    peers = SOSAccountCopyActivePeers(account, &error);
+    int retval = (int) CFArrayGetCount(peers);
+    CFReleaseNull(error);
+    CFReleaseNull(peers);
+    return retval;
+}
+
+static inline int countActiveValidPeers(SOSAccountRef account) {
+    CFErrorRef error = NULL;
+    CFArrayRef peers;
+    
+    peers = SOSAccountCopyActiveValidPeers(account, &error);
+    int retval = (int) CFArrayGetCount(peers);
+    CFReleaseNull(error);
+    CFReleaseNull(peers);
+    return retval;
+}
+
+static inline int countApplicants(SOSAccountRef account) {
+    CFErrorRef error = NULL;
+    CFArrayRef applicants = SOSAccountCopyApplicants(account, &error);
+    int retval = 0;
+    
+    if(applicants) retval = (int)CFArrayGetCount(applicants);
+    CFReleaseNull(error);
+    CFReleaseNull(applicants);
+    return retval;
+}
+
+
+static inline void showActiveValidPeers(SOSAccountRef account) {
+    CFErrorRef error = NULL;
+    CFArrayRef peers;
+    
+    peers = SOSAccountCopyActiveValidPeers(account, &error);
+    CFArrayForEach(peers, ^(const void *value) {
+        SOSPeerInfoRef pi = (SOSPeerInfoRef) value;
+        ok(0, "Active Valid Peer %@", pi);
+    });
+    CFReleaseNull(peers);
+}
+
+#endif
diff --git a/sec/securityd/Regressions/SecdTestKeychainUtilities.c b/sec/securityd/Regressions/SecdTestKeychainUtilities.c
new file mode 100644 (file)
index 0000000..07a9c0c
--- /dev/null
@@ -0,0 +1,45 @@
+//
+//  SecdKeychainUtilities.c
+//  sec
+//
+//  Created by Mitch Adler on 6/11/13.
+//
+//
+
+#include "SecdTestKeychainUtilities.h"
+
+#include <test/testmore.h>
+#include <utilities/SecFileLocations.h>
+#include <utilities/SecCFWrappers.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+//#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+void kc_dbhandle_reset(void);
+
+void secd_test_setup_temp_keychain(const char* test_prefix, dispatch_block_t do_before_reset)
+{
+    CFStringRef tmp_dir = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("/tmp/%s.%X/"), test_prefix, arc4random());
+    CFStringRef keychain_dir = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@Library/Keychains"), tmp_dir);
+    
+    CFStringPerformWithCString(keychain_dir, ^(const char *keychain_dir_string) {
+        ok_unix(mkpath_np(keychain_dir_string, 0755), "Create temp dir");
+        
+        printf("Created temporary directory %s\n", keychain_dir_string);
+    });
+    
+    
+    /* set custom keychain dir, reset db */
+    CFStringPerformWithCString(tmp_dir, ^(const char *tmp_dir_string) {
+        SetCustomHomeURL(tmp_dir_string);
+    });
+
+    if(do_before_reset)
+        do_before_reset();
+    
+    kc_dbhandle_reset();
+}
diff --git a/sec/securityd/Regressions/SecdTestKeychainUtilities.h b/sec/securityd/Regressions/SecdTestKeychainUtilities.h
new file mode 100644 (file)
index 0000000..a95da55
--- /dev/null
@@ -0,0 +1,17 @@
+//
+//  SecdTestKeychainUtilities.h
+//  sec
+//
+//  Created by Mitch Adler on 6/11/13.
+//
+//
+
+#ifndef _SECDTESTKEYCHAINUTILITIES_
+#define _SECDTESTKEYCHAINUTILITIES_
+
+#include <dispatch/dispatch.h>
+
+#define kSecdTestSetupTestCount 1
+void secd_test_setup_temp_keychain(const char* test_prefix, dispatch_block_t do_before_reset);
+
+#endif
diff --git a/sec/securityd/Regressions/sd-10-policytree.c b/sec/securityd/Regressions/sd-10-policytree.c
new file mode 100644 (file)
index 0000000..4da60bb
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2009 Apple Inc. All Rights Reserved.
+ */
+
+#include <securityd/policytree.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <libDER/oids.h>
+
+#include "securityd_regressions.h"
+
+#define DUMP_POLICY_TREE  0
+
+int verbose = DUMP_POLICY_TREE;
+
+static bool randomly_add_children(policy_tree_t node, void *ctx) {
+    int i, count;
+    uint32_t rnd = arc4random();
+#if 1
+    count = rnd % 7;
+    if (count > 4)
+        count  = 0;
+#else
+    if (rnd < 0x40000000) {
+        count = 1;
+    } else if (rnd < 0x80000000) {
+        count = 2;
+    } else if (rnd < 0xc0000000) {
+        count = 3;
+    } else if (rnd < 0xf0000000) {
+        count = 4;
+    } else {
+        count = 0;
+    }
+#endif
+
+#if DUMP_POLICY_TREE
+    diag("node %p add %d children", node, count);
+#endif
+    for (i = 1; i <= count ; ++i) {
+        policy_tree_add_child(node, &oidAnyPolicy, NULL);
+        //diag("node %p %d/%d children added", node, i, count);
+        //policy_tree_dump(node);
+    }
+    return count != 0;
+}
+
+static void tests(void)
+{
+    policy_qualifier_t p_q = NULL;
+    policy_tree_t tree;
+    ok(tree = policy_tree_create(&oidAnyPolicy, p_q),
+        "create tree root");
+    if (verbose) policy_tree_dump(tree);
+
+#if 0
+    int i, count = 4;
+    for (i = 1; i <= count ; ++i) {
+        policy_tree_add_child(tree, &oidAnyPolicy, NULL);
+#if DUMP_POLICY_TREE
+        diag("node %p %d/%d children added", tree, i, count);
+#endif
+    }
+    policy_tree_dump(tree);
+#else
+    int depth;
+    for (depth = 0; tree && depth < 7; ++depth) {
+        bool added = false;
+        while (!added) {
+            added = policy_tree_walk_depth(tree, depth,
+                randomly_add_children, NULL);
+#if DUMP_POLICY_TREE
+            diag("depth: %d %s", depth,
+                (added ? "added children" : "no children added"));
+#endif
+        }
+        if (verbose) policy_tree_dump(tree);
+#if DUMP_POLICY_TREE
+        diag("prune_childless depth: %d", depth);
+#endif
+        policy_tree_prune_childless(&tree, depth);
+        if (verbose) {
+            if (tree)
+                policy_tree_dump(tree);
+            else {
+#if DUMP_POLICY_TREE
+                diag("tree empty at depth: %d", depth);
+#endif
+                break;
+            }
+        }
+    }
+#endif
+    if (tree)
+        policy_tree_prune(&tree);
+}
+
+int sd_10_policytree(int argc, char *const *argv)
+{
+       plan_tests(1);
+
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/securityd/Regressions/sd-70-engine.c b/sec/securityd/Regressions/sd-70-engine.c
new file mode 100644 (file)
index 0000000..eb9463c
--- /dev/null
@@ -0,0 +1,383 @@
+//
+//  sd-70-engine.c
+//  sec
+//
+//  Created by Michael Brouwer on 11/9/12.
+//  Copyright 2012 Apple Inc. All rights reserved.
+//
+//
+
+// Test syncing between SecItemDataSource and SOSTestDataSource
+
+#include <SecureObjectSync/SOSEngine.h>
+#include <SecureObjectSync/SOSPeer.h>
+
+#include "securityd_regressions.h"
+
+#include <corecrypto/ccsha2.h>
+#include <Security/SecBase64.h>
+#include <utilities/SecCFWrappers.h>
+#include <Security/SecItem.h>
+#include <Security/SecItemPriv.h>
+#include <securityd/SecItemServer.h>
+
+#include <utilities/SecFileLocations.h>
+
+#include <stdint.h>
+#include "SOSTestDataSource.h"
+#include "SOSTestTransport.h"
+
+#include <AssertMacros.h>
+
+static int kTestTestCount = 74;
+
+// TODO: Make this shared.
+static CFStringRef SOSMessageCopyDigestHex(CFDataRef message) {
+    uint8_t digest[CCSHA1_OUTPUT_SIZE];
+    ccdigest(ccsha1_di(), CFDataGetLength(message), CFDataGetBytePtr(message), digest);
+    CFMutableStringRef hex = CFStringCreateMutable(0, 2 * sizeof(digest));
+    for (unsigned int ix = 0; ix < sizeof(digest); ++ix) {
+        CFStringAppendFormat(hex, 0, CFSTR("%02X"), digest[ix]);
+    }
+    return hex;
+}
+
+static void testsync(const char *name,  const char *test_directive, const char *test_reason, void (^aliceInit)(SOSDataSourceRef ds), void (^bobInit)(SOSDataSourceRef ds), CFStringRef msg, ...) {
+    CFErrorRef error = NULL;
+
+    /* Setup Alice and Bob's dataSources. */
+    SOSDataSourceFactoryRef aliceDataSourceFactory = SecItemDataSourceFactoryCreateDefault();
+    SOSDataSourceRef aliceDataSource = NULL;
+    CFArrayRef ds_names = aliceDataSourceFactory->copy_names(aliceDataSourceFactory);
+    if (ds_names && CFArrayGetCount(ds_names) > 0) {
+        CFStringRef name = CFArrayGetValueAtIndex(ds_names, 0);
+        ok (aliceDataSource = aliceDataSourceFactory->create_datasource(aliceDataSourceFactory, name, false, &error), "create datasource \"%@\" [error: %@]", name, error);
+        CFReleaseNull(error);
+    }
+    CFReleaseNull(ds_names);
+
+    SOSDataSourceRef bobDataSource = SOSTestDataSourceCreate();
+
+    /* Setup Alice engine and peer for Alice to talk to Bob */
+    SOSEngineRef aliceEngine;
+    ok(aliceEngine = SOSEngineCreate(aliceDataSource, &error), "create alice engine: %@", error);
+    CFReleaseNull(error);
+    CFStringRef bobID = CFStringCreateWithFormat(kCFAllocatorDefault, 0, CFSTR("Bob-%s"), name);
+
+    __block CFDataRef queued_message = NULL;
+
+    SOSPeerSendBlock enqueueMessage =  ^bool (CFDataRef message, CFErrorRef *error) {
+        if (queued_message)
+            fail("We already had an unproccessed message");
+
+        queued_message = (CFDataRef) CFRetain(message);
+        return true;
+    };
+
+    CFDataRef (^dequeueMessage)() = ^CFDataRef () {
+        CFDataRef result = queued_message;
+        queued_message = NULL;
+
+        return result;
+    };
+
+    SOSPeerRef bobPeer;
+    ok(bobPeer = SOSPeerCreateSimple(bobID, kSOSPeerVersion, &error, enqueueMessage),
+       "create peer: %@", error);
+
+    /* Setup Bob engine and peer for Bob to talk to Alice */
+    SOSEngineRef bobEngine;
+    ok(bobEngine = SOSEngineCreate(bobDataSource, &error), "create bob engine: %@", error);
+    CFReleaseNull(error);
+    CFStringRef aliceID = CFStringCreateWithFormat(kCFAllocatorDefault, 0, CFSTR("Alice-%s"), name);
+
+    SOSPeerRef alicePeer;
+    ok(alicePeer = SOSPeerCreateSimple(aliceID, kSOSPeerVersion, &error, enqueueMessage),
+       "create peer: %@", error);
+    CFReleaseNull(error);
+
+    /* Now call provided setup blocks to populate the dataSources with
+     interesting stuff. */
+    aliceInit(aliceDataSource);
+    bobInit(bobDataSource);
+
+    /* Start syncing by making alice send the first message. */
+    ok(SOSEngineSyncWithPeer(aliceEngine, bobPeer, false, &error), "tell Alice sync with peer Bob");
+    CFDataRef message;
+
+       va_list msgs;
+       va_start(msgs, msg);
+
+    int msg_index = 0;
+    bool alice = false;
+    for (;;) {
+        message = dequeueMessage();
+        msg_index++;
+        /* We are expecting a message and msg is it's digest. */
+        if (message) {
+            CFStringRef messageDesc = SOSMessageCopyDescription(message);
+            CFStringRef messageDigestStr = SOSMessageCopyDigestHex(message);
+            if (msg) {
+                bool handeled = SOSEngineHandleMessage(alice ? aliceEngine : bobEngine, alice ? bobPeer : alicePeer, message, &error);
+                if (!CFEqual(messageDigestStr, msg)) {
+                    if (handeled) {
+                        fail("%s %s received message [%d] digest %@ != %@ %@", name, alice ? "Alice" : "Bob", msg_index, messageDigestStr, msg, messageDesc);
+                    } else {
+                        fail("%s %s failed to handle message [%d] digest %@ != %@ %@: %@", name, alice ? "Alice" : "Bob", msg_index, messageDigestStr, msg, messageDesc, error);
+                        CFReleaseNull(error);
+                    }
+                } else if (handeled) {
+                    pass("%s %s handled message [%d] %@", name, alice ? "Alice" : "Bob", msg_index, messageDesc);
+                } else {
+                    fail("%s %s failed to handle message [%d] %@: %@", name, alice ? "Alice" : "Bob", msg_index, messageDesc, error);
+                    CFReleaseNull(error);
+                }
+            } else {
+                fail("%s %s sent extra message [%d] with digest %@: %@", name, alice ? "Bob" : "Alice", msg_index, messageDigestStr, messageDesc);
+            }
+            CFRelease(messageDigestStr);
+            CFRelease(messageDesc);
+            CFRelease(message);
+        } else {
+            if (msg) {
+                fail("%s %s expected message [%d] with digest %@, none received", name, alice ? "Alice" : "Bob", msg_index, msg);
+            }
+        }
+
+        if (msg) {
+            alice = !alice;
+            msg = va_arg(msgs, CFStringRef);
+        } else
+            break;
+    }
+
+       va_end(msgs);
+
+    SOSEngineDispose(aliceEngine); // Also disposes aliceDataSource
+    SOSPeerDispose(alicePeer);
+    CFReleaseSafe(aliceID);
+
+    SOSEngineDispose(bobEngine); // Also disposes bobDataSource
+    SOSPeerDispose(bobPeer);
+    CFReleaseSafe(bobID);
+
+    aliceDataSourceFactory->release(aliceDataSourceFactory);
+}
+
+
+static SOSObjectRef SOSDataSourceCopyObject(SOSDataSourceRef ds, SOSObjectRef match, CFErrorRef *error)
+{
+    __block SOSObjectRef result = NULL;
+
+    CFDataRef digest = ds->copyDigest(match, error);
+    SOSManifestRef manifest = NULL;
+
+    require(digest, exit);
+   
+    manifest = SOSManifestCreateWithData(digest, error);
+
+    ds->foreach_object(ds, manifest, error, ^ bool (SOSObjectRef object, CFErrorRef *error) {
+        if (result == NULL) {
+            result = object;
+            CFRetainSafe(result);
+        }
+        
+        return true;
+    });
+        
+exit:
+    CFReleaseNull(manifest);
+    CFReleaseNull(digest);
+    return result;
+}
+
+static void synctests(void) {
+#if 0
+    // TODO: Adding items gives us non predictable creation and mod dates so
+    // the message hashes can't be precomputed.
+    CFDictionaryRef item = CFDictionaryCreateForCFTypes
+    (0,
+     kSecClass, kSecClassGenericPassword,
+     kSecAttrAccessible, kSecAttrAccessibleWhenUnlocked,
+     kSecAttrSynchronizable, kCFBooleanTrue,
+     kSecAttrService, CFSTR("service"),
+     kSecAttrAccount, CFSTR("account"),
+     NULL);
+    SecItemAdd(item, NULL);
+    CFReleaseSafe(item);
+#endif
+
+SKIP:
+    {
+
+#ifdef NO_SERVER
+    // Careful with this in !NO_SERVER, it'll destroy debug keychains.
+    WithPathInKeychainDirectory(CFSTR("keychain-2-debug.db"), ^(const char *keychain_path) {
+        unlink(keychain_path);
+    });
+    
+    // Don't ever do this in !NO_SERVER, it'll destroy real keychains.
+    WithPathInKeychainDirectory(CFSTR("keychain-2.db"), ^(const char *keychain_path) {
+        unlink(keychain_path);
+    });
+    
+    void kc_dbhandle_reset(void);
+    kc_dbhandle_reset();
+#else
+    skip("Keychain not reset", kTestTestCount, false);
+#endif
+
+    // Sync between 2 empty dataSources
+    testsync("sd_70_engine", test_directive, test_reason,
+             ^ (SOSDataSourceRef dataSource) {},
+             ^ (SOSDataSourceRef dataSource) {},
+             CFSTR("2AF312E092D67308A0083DFFBF2B6B754B967864"),
+             CFSTR("2AF312E092D67308A0083DFFBF2B6B754B967864"),
+             CFSTR("2AF312E092D67308A0083DFFBF2B6B754B967864"),
+             NULL);
+
+    // Sync a dataSource with one object to an empty dataSource
+    testsync("sd_70_engine-alice1", test_directive, test_reason,
+             ^ (SOSDataSourceRef dataSource) {
+                 CFErrorRef error = NULL;
+                 SOSObjectRef object = SOSDataSourceCreateGenericItem(dataSource, CFSTR("test_account"), CFSTR("test service"));
+                 // TODO: Needs to be a SecDBItemRef for the SecItemDataSource...
+                 ok(dataSource->add(dataSource, object, &error), "dataSource added object %@", error);
+                 CFReleaseSafe(object);
+                 CFReleaseNull(error);
+             },
+             ^ (SOSDataSourceRef dataSource) {},
+             CFSTR("ADAA3ACE75ED516CB91893413EE9CC9ED04CA47B"),
+             CFSTR("147B6C509908CC4A9FC4263973A842104A64CE01"),
+             CFSTR("019B494F3C06B48BB02C280AF1E19AD861A7003C"),
+             CFSTR("ADAA3ACE75ED516CB91893413EE9CC9ED04CA47B"),
+             NULL);
+
+    // Sync a dataSource with one object to another dataSource with the same object
+    testsync("sd_70_engine-alice1bob1", test_directive, test_reason,
+             ^ (SOSDataSourceRef dataSource) {
+#if 0
+                 CFErrorRef error = NULL;
+                 // TODO: Needs to be a SecDBItemRef for the SecItemDataSource...
+                 CFDictionaryRef object = SOSDataSourceCreateGenericItem(dataSource, CFSTR("test_account"), CFSTR("test service"));
+                 ok(dataSource->add(dataSource, object, &error), "dataSource added object %@", error);
+                 CFReleaseSafe(object);
+                 CFReleaseNull(error);
+#endif
+             },
+             ^ (SOSDataSourceRef dataSource) {
+                 CFErrorRef error = NULL;
+                 SOSObjectRef object = SOSDataSourceCreateGenericItem(dataSource, CFSTR("test_account"), CFSTR("test service"));
+                 ok(dataSource->add(dataSource, object, &error), "dataSource added object %@", error);
+                 CFReleaseSafe(object);
+                 CFReleaseNull(error);
+             },
+             CFSTR("ADAA3ACE75ED516CB91893413EE9CC9ED04CA47B"),
+             CFSTR("ADAA3ACE75ED516CB91893413EE9CC9ED04CA47B"),
+             CFSTR("ADAA3ACE75ED516CB91893413EE9CC9ED04CA47B"),
+             NULL);
+
+    // Sync a dataSource with one object to another dataSource with the same object
+    testsync("sd_70_engine-alice1bob2", test_directive, test_reason,
+             ^ (SOSDataSourceRef dataSource) {
+#if 0
+                 CFErrorRef error = NULL;
+                 // TODO: Needs to be a SecDBItemRef for the SecItemDataSource...
+                 SOSObjectRef object = SOSDataSourceCreateGenericItem(dataSource, CFSTR("test_account"), CFSTR("test service"));
+                 ok(dataSource->add(dataSource, object, &error), "dataSource added object %@", error);
+                 CFReleaseSafe(object);
+                 CFReleaseNull(error);
+#endif
+             },
+             ^ (SOSDataSourceRef dataSource) {
+                 CFErrorRef error = NULL;
+                 SOSObjectRef object = SOSDataSourceCreateGenericItem(dataSource, CFSTR("test_account"), CFSTR("test service"));
+                 ok(dataSource->add(dataSource, object, &error), "dataSource added object %@", error);
+                 CFReleaseSafe(object);
+                 object = SOSDataSourceCreateGenericItem(dataSource, CFSTR("account1"), CFSTR("service1"));
+                 ok(dataSource->add(dataSource, object, &error), "dataSource added object %@", error);
+                 CFReleaseSafe(object);
+                 CFReleaseNull(error);
+             },
+             CFSTR("ADAA3ACE75ED516CB91893413EE9CC9ED04CA47B"),
+             CFSTR("D4049A1063CFBF7CAF8424E13DE3CE926FF5856C"),
+             CFSTR("9624EA855BBED6B668868BB723443E804D04F6A1"),
+             CFSTR("063E097CCD4FEB7F3610ED12B3DA828467314846"),
+             CFSTR("D1B3944E3084425F41B2C2EA0BE82170E10AA37D"),
+             NULL);
+
+    // Sync a dataSource with a tombstone object to another dataSource with the same object
+    TODO: {
+    todo("<rdar://problem/14049022> Test case in sd-70-engine fails due to need for RowID");
+    testsync("sd_70_engine-update", test_directive, test_reason,
+             ^ (SOSDataSourceRef dataSource) {
+                 CFErrorRef error = NULL;
+                 const char *password = "password1";
+                 CFDataRef data = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)password, strlen(password));
+                 // TODO: Needs to be a SecDBItemRef for the SecItemDataSource...
+                 SOSObjectRef object_to_find = SOSDataSourceCreateGenericItemWithData(dataSource, CFSTR("test_account"), CFSTR("test service"), true, NULL);
+                 SOSObjectRef object = SOSDataSourceCopyObject(dataSource, object_to_find, &error);
+                 SOSObjectRef old_object = NULL;
+             SKIP: {
+                 skip("no object", 1, ok(object, "Finding object %@, error: %@", object_to_find, error));
+                 CFReleaseNull(data);
+                 // TODO: Needs to be a SecDBItemRef for the SecItemDataSource...
+                 old_object = SOSDataSourceCreateGenericItem(dataSource, CFSTR("test_account"), CFSTR("test service"));
+                 ok(dataSource->add(dataSource, object, &error), "dataSource update object %@", error);
+             }
+                 CFReleaseSafe(data);
+                 CFReleaseSafe(old_object);
+                 CFReleaseSafe(object);
+                 CFReleaseNull(error);
+             },
+             ^ (SOSDataSourceRef dataSource) {
+                 CFErrorRef error = NULL;
+                 SOSObjectRef object = SOSDataSourceCreateGenericItem(dataSource, CFSTR("test_account"), CFSTR("test service"));
+                 ok(dataSource->add(dataSource, object, &error), "dataSource added object %@", error);
+                 CFReleaseSafe(object);
+                 object = SOSDataSourceCreateGenericItem(dataSource, CFSTR("account1"), CFSTR("service1"));
+                 ok(dataSource->add(dataSource, object, &error), "dataSource added object %@", error);
+                 CFReleaseSafe(object);
+                 CFReleaseNull(error);
+             },
+             CFSTR("5D07A221A152D6D6C5F1919189F259A7278A08C5"),
+             CFSTR("D4049A1063CFBF7CAF8424E13DE3CE926FF5856C"),
+             CFSTR("137FD34E9BF11B4BA0620E8EBFAB8576BCCCF294"),
+             CFSTR("5D07A221A152D6D6C5F1919189F259A7278A08C5"),
+             NULL);
+    }
+
+    // Sync a dataSource with one object to another dataSource with the same object
+    testsync("sd_70_engine-foreign-add", test_directive, test_reason,
+             ^ (SOSDataSourceRef dataSource) {
+             },
+             ^ (SOSDataSourceRef dataSource) {
+                 CFErrorRef error = NULL;
+                 const char *password = "password1";
+                 CFDataRef data = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)password, strlen(password));
+                 SOSObjectRef object = SOSDataSourceCreateGenericItemWithData(dataSource, CFSTR("test_account"), CFSTR("test service"), false, data);
+                 CFReleaseSafe(data);
+                 ok(dataSource->add(dataSource, object, &error), "dataSource added object %@", error);
+                 CFReleaseSafe(object);
+                 CFReleaseNull(error);
+                 object = SOSDataSourceCreateGenericItem(dataSource, CFSTR("account1"), CFSTR("service1"));
+                 ok(dataSource->add(dataSource, object, &error), "dataSource added object %@", error);
+                 CFReleaseSafe(object);
+                 CFReleaseNull(error);
+             },
+             CFSTR("D1B3944E3084425F41B2C2EA0BE82170E10AA37D"),
+             CFSTR("607EEF976943FD781CFD2B3850E6DC7979AA61EF"),
+             CFSTR("28434CD1B90CC205460557CAC03D7F12067F2329"),
+             CFSTR("D1B3944E3084425F41B2C2EA0BE82170E10AA37D"),
+             NULL);
+    }
+}
+
+int sd_70_engine(int argc, char *const *argv)
+{
+    plan_tests(kTestTestCount);
+
+    synctests();
+
+       return 0;
+}
diff --git a/sec/securityd/Regressions/secd-01-items.c b/sec/securityd/Regressions/secd-01-items.c
new file mode 100644 (file)
index 0000000..2624aa1
--- /dev/null
@@ -0,0 +1,147 @@
+//
+//  secd-01-dbitems.c
+//  sec
+//
+//  Created by Fabrice Gautier on 5/29/13.
+//
+//
+
+
+#include "secd_regressions.h"
+
+#include <securityd/SecDbItem.h>
+#include <securityd/SecItemServer.h>
+
+#include <utilities/array_size.h>
+#include <utilities/SecFileLocations.h>
+
+#include <unistd.h>
+
+#include "SecdTestKeychainUtilities.h"
+
+#if USE_KEYSTORE
+#include <libaks.h>
+void kc_dbhandle_reset(void);
+
+int secd_01_items(int argc, char *const *argv)
+{
+    plan_tests(24 + kSecdTestSetupTestCount);
+
+    /* custom keychain dir */
+    secd_test_setup_temp_keychain("secd_01_items", ^{
+    });
+
+    /* custom keybag */
+    keybag_handle_t keybag;
+    keybag_state_t state;
+    char *passcode="password";
+    int passcode_len=(int)strlen(passcode);
+
+    ok(kIOReturnSuccess==aks_create_bag(passcode, passcode_len, kAppleKeyStoreDeviceBag, &keybag), "create keybag");
+    ok(kIOReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state");
+    ok(!(state&keybag_state_locked), "keybag unlocked");
+    SecItemServerSetKeychainKeybag(keybag);
+
+    /* lock */
+    ok(kIOReturnSuccess==aks_lock_bag(keybag), "lock keybag");
+    ok(kIOReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state");
+    ok(state&keybag_state_locked, "keybag locked");
+
+    
+    kc_dbhandle_reset();
+
+    /* Creating a password */
+    int v_eighty = 80;
+    CFNumberRef eighty = CFNumberCreate(NULL, kCFNumberSInt32Type, &v_eighty);
+    const char *v_data = "test";
+    CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data));
+    const void *keys[] = {
+        kSecClass,
+        kSecAttrServer,
+        kSecAttrAccount,
+        kSecAttrPort,
+        kSecAttrProtocol,
+        kSecAttrAuthenticationType,
+        kSecValueData
+    };
+    const void *values[] = {
+        kSecClassInternetPassword,
+        CFSTR("members.spamcop.net"),
+        CFSTR("smith"),
+        eighty,
+        CFSTR("http"),
+        CFSTR("dflt"),
+        pwdata
+    };
+    CFDictionaryRef item = CFDictionaryCreate(NULL, keys, values,
+                                              array_size(keys), NULL, NULL);
+
+    
+    is_status(SecItemAdd(item, NULL), errSecInteractionNotAllowed, "add internet password while locked");
+
+    /* unlock */
+    ok(kIOReturnSuccess==aks_unlock_bag(keybag, passcode, passcode_len), "unlock keybag");
+    ok(kIOReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state");
+    ok(!(state&keybag_state_locked), "keybag unlocked");
+
+    ok_status(SecItemAdd(item, NULL), "add internet password, while unlocked");
+
+    
+    /* lock */
+    ok(kIOReturnSuccess==aks_lock_bag(keybag), "lock keybag");
+    ok(kIOReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state");
+    ok(state&keybag_state_locked, "keybag locked");
+
+    is_status(SecItemAdd(item, NULL), errSecInteractionNotAllowed,
+              "add internet password again, while locked");
+
+    /* unlock */
+    ok(kIOReturnSuccess==aks_unlock_bag(keybag, passcode, passcode_len), "unlock keybag");
+    ok(kIOReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state");
+    ok(!(state&keybag_state_locked), "keybag unlocked");
+
+    is_status(SecItemAdd(item, NULL), errSecDuplicateItem,
+              "add internet password again, while unlocked");
+
+    CFTypeRef results = NULL;
+    /* Create a dict with all attrs except the data. */
+    CFDictionaryRef query = CFDictionaryCreate(NULL, keys, values,
+                                               (array_size(keys)) - 1, NULL, NULL);
+    ok_status(SecItemCopyMatching(query, &results), "find internet password, while unlocked ");
+    if (results) {
+        CFRelease(results);
+        results = NULL;
+    }
+
+    /* lock */
+    ok(kIOReturnSuccess==aks_lock_bag(keybag), "lock keybag");
+    ok(kIOReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state");
+    ok(state&keybag_state_locked, "keybag locked");
+
+    is_status(SecItemCopyMatching(query, &results), errSecInteractionNotAllowed, "find internet password, while locked ");
+
+    /* Reset keybag and custom $HOME */
+    SecItemServerResetKeychainKeybag();
+    SetCustomHomeURL(NULL);
+    kc_dbhandle_reset();
+
+       return 0;
+}
+
+#else
+
+int secd_01_items(int argc, char *const *argv)
+{
+    plan_tests(1);
+
+    todo("Not yet working in simulator");
+
+TODO: {
+    ok(false);
+}
+
+    /* not implemented in simulator (no keybag) */
+       return 0;
+}
+#endif
+
diff --git a/sec/securityd/Regressions/secd-02-upgrade-while-locked.c b/sec/securityd/Regressions/secd-02-upgrade-while-locked.c
new file mode 100644 (file)
index 0000000..640ca21
--- /dev/null
@@ -0,0 +1,177 @@
+//
+//  secd-02-corruption.c
+//  sec
+//
+//  Created by Fabrice Gautier on 5/31/13.
+//
+//
+
+#include "secd_regressions.h"
+
+#include <securityd/SecDbItem.h>
+#include <utilities/array_size.h>
+#include <utilities/SecCFWrappers.h>
+#include <utilities/SecFileLocations.h>
+#include <utilities/fileIo.h>
+
+#include <securityd/SOSCloudCircleServer.h>
+#include <securityd/SecItemServer.h>
+
+#include <Security/SecBasePriv.h>
+
+#include <TargetConditionals.h>
+#include <AssertMacros.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <pthread.h>
+
+#if TARGET_OS_IPHONE && USE_KEYSTORE
+#include <libaks.h>
+
+#include "SecdTestKeychainUtilities.h"
+
+#include "b_keychain_2_db.h"
+
+static OSStatus query_one(void)
+{
+    OSStatus ok;
+
+    /* querying a password */
+    const void *keys[] = {
+        kSecClass,
+        kSecAttrServer,
+    };
+    const void *values[] = {
+        kSecClassInternetPassword,
+        CFSTR("members.spamcop.net"),
+    };
+    CFDictionaryRef query = CFDictionaryCreate(NULL, keys, values,
+                                               array_size(keys), NULL, NULL);
+    CFTypeRef results = NULL;
+
+    ok = SecItemCopyMatching(query, &results);
+
+    CFReleaseSafe(results);
+    CFReleaseSafe(query);
+
+    return ok;
+}
+
+    
+
+static void *do_query(void *arg)
+{
+    /* querying a password */
+    const void *keys[] = {
+        kSecClass,
+        kSecAttrServer,
+    };
+    const void *values[] = {
+        kSecClassInternetPassword,
+        CFSTR("members.spamcop.net"),
+    };
+    CFDictionaryRef query = CFDictionaryCreate(NULL, keys, values,
+                                              array_size(keys), NULL, NULL);
+    CFTypeRef results = NULL;
+
+    for(int i=0;i<20;i++)
+        verify_action(SecItemCopyMatching(query, &results)==errSecUpgradePending, return (void *)-1);
+
+    CFReleaseSafe(query);
+    
+    return NULL;
+}
+
+static void *do_sos(void *arg)
+{
+    
+    for(int i=0;i<20;i++)
+        verify_action(SOSCCThisDeviceIsInCircle_Server(NULL)==-1, return (void *)-1);
+
+    return NULL;
+}
+
+
+#define N_THREADS 10
+
+int secd_02_upgrade_while_locked(int argc, char *const *argv)
+{
+    plan_tests(11 + N_THREADS + kSecdTestSetupTestCount);
+
+    __block keybag_handle_t keybag;
+    __block keybag_state_t state;
+    char *passcode="password";
+    int passcode_len=(int)strlen(passcode);
+
+    /* custom keychain dir */
+    secd_test_setup_temp_keychain("secd_02_upgrade_while_locked", ^{
+        CFStringRef keychain_path_cf = __SecKeychainCopyPath();
+        
+        CFStringPerformWithCString(keychain_path_cf, ^(const char *keychain_path) {
+            writeFile(keychain_path, b_keychain_2_db, b_keychain_2_db_len);            
+        
+            /* custom notification */
+            SecItemServerSetKeychainChangedNotification("com.apple.secdtests.keychainchanged");
+            
+            /* Create and lock custom keybag */            
+            ok(kIOReturnSuccess==aks_create_bag(passcode, passcode_len, kAppleKeyStoreDeviceBag, &keybag), "create keybag");
+            ok(kIOReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state");
+            ok(!(state&keybag_state_locked), "keybag unlocked");
+            SecItemServerSetKeychainKeybag(keybag);
+            
+            /* lock */
+            ok(kIOReturnSuccess==aks_lock_bag(keybag), "lock keybag");
+            ok(kIOReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state");
+            ok(state&keybag_state_locked, "keybag locked");
+        });
+        
+        CFReleaseSafe(keychain_path_cf);
+    });
+
+    pthread_t query_thread[N_THREADS];
+    pthread_t sos_thread;
+    void *query_err[N_THREADS] = {NULL,};
+    void *sos_err = NULL;
+
+    for(int i=0; i<N_THREADS; i++)
+        pthread_create(&query_thread[i], NULL, do_query, NULL);
+    pthread_create(&sos_thread, NULL, do_sos, NULL);
+
+    for(int i=0; i<N_THREADS; i++)
+        pthread_join(query_thread[i],&query_err[i]);
+    pthread_join(sos_thread, &sos_err);
+
+    for(int i=0; i<N_THREADS; i++)
+        ok(query_err[i]==NULL, "query thread ok");
+    ok(sos_err==NULL, "sos thread ok");
+
+    ok(kIOReturnSuccess==aks_unlock_bag(keybag, passcode, passcode_len), "lock keybag");
+    ok(kIOReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state");
+    ok(!(state&keybag_state_locked), "keybag unlocked");
+
+    is_status(query_one(), errSecItemNotFound, "Query after unlock");
+
+    /* Reset keybag */
+    SecItemServerResetKeychainKeybag();
+
+    return 0;
+}
+
+#else
+
+int secd_02_upgrade_while_locked(int argc, char *const *argv)
+{
+    plan_tests(1);
+
+    todo("Not yet working in simulator");
+
+TODO: {
+    ok(false);
+}
+    /* not implemented in simulator (no keybag) */
+    /* Not implemented in OSX (no upgrade scenario) */
+       return 0;
+}
+#endif
diff --git a/sec/securityd/Regressions/secd-03-corrupted-items.c b/sec/securityd/Regressions/secd-03-corrupted-items.c
new file mode 100644 (file)
index 0000000..336f456
--- /dev/null
@@ -0,0 +1,147 @@
+//
+//  secd-03-corrupted-item.c
+//  sec
+//
+//  Created by Fabrice Gautier on 06/19/13.
+//
+//
+
+#include "secd_regressions.h"
+
+#include <securityd/SecDbItem.h>
+#include <utilities/array_size.h>
+#include <utilities/SecCFWrappers.h>
+#include <utilities/SecFileLocations.h>
+#include <utilities/fileIo.h>
+
+#include <securityd/SOSCloudCircleServer.h>
+#include <securityd/SecItemServer.h>
+
+#include <Security/SecBasePriv.h>
+
+#include <AssertMacros.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <pthread.h>
+
+#include "SecdTestKeychainUtilities.h"
+
+static OSStatus do_query(void)
+{
+    /* querying a password */
+    const void *keys[] = {
+        kSecClass,
+        kSecAttrServer,
+        kSecReturnAttributes,
+    };
+    const void *values[] = {
+        kSecClassInternetPassword,
+        CFSTR("corrupt.spamcop.net"),
+        kCFBooleanTrue,
+    };
+    CFDictionaryRef query = CFDictionaryCreate(NULL, keys, values,
+                                              array_size(keys), NULL, NULL);
+    CFTypeRef results = NULL;
+
+    OSStatus err = SecItemCopyMatching(query, &results);
+    CFReleaseNull(query);
+    return err;
+}
+
+static void *do_add(void *arg)
+{
+    int tid=(int)(arg);
+    
+    for(int i=0;i<20;i++) {
+        /* Creating a password */
+        SInt32 v_eighty = (tid+1)*1000+i;
+        CFNumberRef eighty = CFNumberCreate(NULL, kCFNumberSInt32Type, &v_eighty);
+        const char *v_data = "test";
+        CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data));
+        const void *keys[] = {
+            kSecClass,
+            kSecAttrServer,
+            kSecAttrAccount,
+            kSecAttrPort,
+            kSecAttrProtocol,
+            kSecAttrAuthenticationType,
+            kSecValueData
+        };
+        const void *values[] = {
+            kSecClassInternetPassword,
+            CFSTR("members.spamcop.net"),
+            CFSTR("smith"),
+            eighty,
+            CFSTR("http"),
+            CFSTR("dflt"),
+            pwdata
+        };
+
+        CFDictionaryRef item = CFDictionaryCreate(NULL, keys, values,
+                                                  array_size(keys), NULL, NULL);
+
+        ok_status(SecItemAdd(item, NULL), "add internet password");
+    }
+
+    return NULL;
+}
+
+
+#define N_THREADS 10
+
+static const char *corrupt_item_sql = "UPDATE inet SET data=X'12345678' WHERE rowid=1";
+
+
+int secd_03_corrupted_items(int argc, char *const *argv)
+{
+    plan_tests(4 + N_THREADS*21 + kSecdTestSetupTestCount);
+    
+    /* custom keychain dir */
+    secd_test_setup_temp_keychain("secd_03_corrupted_items", NULL);
+
+    /* add a password */
+    int v_eighty = 80;
+    CFNumberRef eighty = CFNumberCreate(NULL, kCFNumberSInt32Type, &v_eighty);
+    const char *v_data = "test";
+    CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data));
+    CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(query, kSecClass, kSecClassInternetPassword);
+    CFDictionaryAddValue(query, kSecAttrServer, CFSTR("corrupt.spamcop.net"));
+    CFDictionaryAddValue(query, kSecAttrAccount, CFSTR("smith"));
+    CFDictionaryAddValue(query, kSecAttrPort, eighty);
+    CFDictionaryAddValue(query, kSecAttrProtocol, kSecAttrProtocolHTTP);
+    CFDictionaryAddValue(query, kSecAttrAuthenticationType, kSecAttrAuthenticationTypeDefault);
+    CFDictionaryAddValue(query, kSecValueData, pwdata);
+    ok_status(SecItemAdd(query, NULL), "add internet password");
+
+    /* corrupt the password */
+    CFStringRef keychain_path_cf = __SecKeychainCopyPath();
+
+    CFStringPerformWithCString(keychain_path_cf, ^(const char *keychain_path) {
+        /* Create a new keychain sqlite db */
+        sqlite3 *db;
+        
+        is(sqlite3_open(keychain_path, &db), SQLITE_OK, "create keychain");
+        is(sqlite3_exec(db, corrupt_item_sql, NULL, NULL, NULL), SQLITE_OK,
+           "corrupting keychain item1");
+
+    });
+
+    pthread_t add_thread[N_THREADS];
+    void *add_err[N_THREADS] = {NULL,};
+
+    for(int i=0; i<N_THREADS; i++)
+        pthread_create(&add_thread[i], NULL, do_add, (void*)(intptr_t)i);
+
+    is_status(do_query(), errSecItemNotFound, "query");
+
+    for(int i=0; i<N_THREADS; i++)
+        pthread_join(add_thread[i], &add_err[i]);
+
+    for(int i=0; i<N_THREADS; i++)
+        ok(add_err[i]==NULL, "add thread");
+
+    return 0;
+}
diff --git a/sec/securityd/Regressions/secd-04-corrupted-items.c b/sec/securityd/Regressions/secd-04-corrupted-items.c
new file mode 100644 (file)
index 0000000..0774ad3
--- /dev/null
@@ -0,0 +1,125 @@
+//
+//  secd-04-corrupted-item.c
+//  sec
+//
+//  Created by Fabrice Gautier on 06/19/13.
+//
+//
+
+#include "secd_regressions.h"
+
+#include <securityd/SecDbItem.h>
+#include <utilities/SecCFWrappers.h>
+#include <utilities/SecFileLocations.h>
+#include <utilities/fileIo.h>
+
+#include <securityd/SOSCloudCircleServer.h>
+#include <securityd/SecItemServer.h>
+
+#include <Security/SecBasePriv.h>
+
+#include <AssertMacros.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <pthread.h>
+
+#include "SecdTestKeychainUtilities.h"
+
+/* Corrupt 1st and 3rd item */
+static const char *corrupt_item_sql = "UPDATE inet SET data=X'12345678' WHERE rowid=1 OR rowid=3";
+
+int secd_04_corrupted_items(int argc, char *const *argv)
+{
+    plan_tests(11 + kSecdTestSetupTestCount);
+    
+    /* custom keychain dir */
+    secd_test_setup_temp_keychain("secd_04_corrupted_items", NULL);
+
+    /* add a password */
+    CFTypeRef ref1 = NULL;
+    int v_eighty = 80;
+    CFNumberRef eighty = CFNumberCreate(NULL, kCFNumberSInt32Type, &v_eighty);
+    const char *v_data = "test";
+    CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data));
+    CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(query, kSecClass, kSecClassInternetPassword);
+    CFDictionaryAddValue(query, kSecAttrServer, CFSTR("corrupt.spamcop.net"));
+    CFDictionaryAddValue(query, kSecAttrAccount, CFSTR("smith"));
+    CFDictionaryAddValue(query, kSecAttrPort, eighty);
+    CFDictionaryAddValue(query, kSecAttrProtocol, kSecAttrProtocolHTTP);
+    CFDictionaryAddValue(query, kSecAttrAuthenticationType, kSecAttrAuthenticationTypeDefault);
+    CFDictionaryAddValue(query, kSecValueData, pwdata);
+    CFDictionaryAddValue(query, kSecReturnPersistentRef, kCFBooleanTrue);
+    ok_status(SecItemAdd(query, &ref1), "add internet password port 80");
+
+    /* add another one */
+    CFTypeRef ref2 = NULL;
+    int v_eighty_one = 81;
+    CFNumberRef eighty_one = CFNumberCreate(NULL, kCFNumberSInt32Type, &v_eighty_one);
+    CFDictionarySetValue(query, kSecAttrPort, eighty_one);
+    ok_status(SecItemAdd(query, &ref2), "add internet password port 81");
+
+    /* add another one */
+    CFTypeRef ref3 = NULL;
+    int v_eighty_two = 82;
+    CFNumberRef eighty_two = CFNumberCreate(NULL, kCFNumberSInt32Type, &v_eighty_two);
+    CFDictionarySetValue(query, kSecAttrPort, eighty_two);
+    ok_status(SecItemAdd(query, &ref3), "add internet password port 82");
+
+    /* remove the data, and return key from the query */
+    CFDictionaryRemoveValue(query, kSecValueData);
+    CFDictionaryRemoveValue(query, kSecReturnPersistentRef);
+
+    /* update second password to conflict with first one */
+    CFDictionarySetValue(query, kSecAttrPort, eighty_one);
+    CFMutableDictionaryRef attributes = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(attributes, kSecAttrPort, eighty);
+    is_status(SecItemUpdate(query, attributes), errSecDuplicateItem, "update internet password port 80 to 81");
+
+    /* corrupt the first and 3rd password */
+    CFStringRef keychain_path_cf = __SecKeychainCopyPath();
+
+    CFStringPerformWithCString(keychain_path_cf, ^(const char *keychain_path) {
+        /* Create a new keychain sqlite db */
+        sqlite3 *db;
+        
+        is(sqlite3_open(keychain_path, &db), SQLITE_OK, "open keychain");
+        is(sqlite3_exec(db, corrupt_item_sql, NULL, NULL, NULL), SQLITE_OK,
+           "corrupting keychain items");
+
+    });
+
+    /* Try the update again */
+    ok_status(SecItemUpdate(query, attributes), "update internet password port 80 to 81 (after corrupting item)");
+
+    /* query the persistent ref */
+    CFTypeRef ref = NULL;
+    CFDictionarySetValue(query, kSecAttrPort, eighty);
+    CFDictionaryAddValue(query, kSecReturnPersistentRef, kCFBooleanTrue);
+    ok_status(SecItemCopyMatching(query, &ref), "Item 80 found");
+    
+    CFDictionaryRemoveValue(query, kSecReturnPersistentRef);
+    ok(CFEqual(ref, ref2), "persistent ref of item 2");
+
+    CFReleaseNull(attributes);
+    
+    /* Update the 3rd item (82) */
+    CFDictionarySetValue(query, kSecAttrPort, eighty_two);
+
+    attributes = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(attributes, kSecAttrLabel, CFSTR("This is the 3rd password"));
+    is_status(SecItemUpdate(query, attributes), errSecItemNotFound, "update internet password port 82 (after corrupting item)");
+
+    CFDictionarySetValue(query, kSecValueData, pwdata);
+    ok_status(SecItemAdd(query, NULL), "re-adding internet password port 82 (after corrupting item)");
+    CFReleaseNull(pwdata);
+    CFReleaseNull(attributes);
+    CFReleaseNull(query);
+    CFReleaseNull(eighty);
+    CFReleaseNull(eighty_one);
+    CFReleaseNull(eighty_two);
+
+    return 0;
+}
diff --git a/sec/securityd/Regressions/secd-05-corrupted-items.c b/sec/securityd/Regressions/secd-05-corrupted-items.c
new file mode 100644 (file)
index 0000000..9100767
--- /dev/null
@@ -0,0 +1,145 @@
+//
+//  secd-05-corrupted-item.c
+//  sec
+//
+//  Created by Fabrice Gautier on 06/26/13.
+//
+//
+
+#include "secd_regressions.h"
+
+#include <securityd/SecDbItem.h>
+#include <utilities/array_size.h>
+#include <utilities/SecCFWrappers.h>
+#include <utilities/SecFileLocations.h>
+#include <utilities/fileIo.h>
+
+#include <securityd/SOSCloudCircleServer.h>
+#include <securityd/SecItemServer.h>
+
+#include <Security/SecBasePriv.h>
+
+#include <AssertMacros.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <pthread.h>
+
+#include "SecdTestKeychainUtilities.h"
+
+#define N_ITEMS (100)
+#define N_THREADS (10)
+#define N_ADDS (20)
+
+static void *do_add(void *arg)
+{
+    int tid=(int)(arg);
+
+    for(int i=0;i<N_ADDS;i++) {
+        /* Creating a password */
+        SInt32 v_eighty = (tid+1)*1000+i;
+        CFNumberRef eighty = CFNumberCreate(NULL, kCFNumberSInt32Type, &v_eighty);
+        const char *v_data = "test";
+        CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data));
+        const void *keys[] = {
+            kSecClass,
+            kSecAttrServer,
+            kSecAttrAccount,
+            kSecAttrPort,
+            kSecAttrProtocol,
+            kSecAttrAuthenticationType,
+            kSecValueData
+        };
+        const void *values[] = {
+            kSecClassInternetPassword,
+            CFSTR("members.spamcop.net"),
+            CFSTR("smith"),
+            eighty,
+            CFSTR("http"),
+            CFSTR("dflt"),
+            pwdata
+        };
+
+        CFDictionaryRef item = CFDictionaryCreate(NULL, keys, values,
+                                                  array_size(keys), NULL, NULL);
+
+        ok_status(SecItemAdd(item, NULL), "add internet password");
+    }
+
+    return NULL;
+}
+
+
+int secd_05_corrupted_items(int argc, char *const *argv)
+{
+    plan_tests(1 + N_THREADS*(N_ADDS+1) + N_ITEMS*4 + kSecdTestSetupTestCount);
+    
+    /* custom keychain dir */
+    secd_test_setup_temp_keychain("secd_05_corrupted_items", NULL);
+
+    /* add a password */
+    const char *v_data = "test";
+    CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data));
+    CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(query, kSecClass, kSecClassInternetPassword);
+    CFDictionaryAddValue(query, kSecAttrServer, CFSTR("corrupt.spamcop.net"));
+    CFDictionaryAddValue(query, kSecAttrAccount, CFSTR("smith"));
+    CFDictionaryAddValue(query, kSecAttrProtocol, kSecAttrProtocolHTTP);
+    CFDictionaryAddValue(query, kSecAttrAuthenticationType, kSecAttrAuthenticationTypeDefault);
+    CFDictionaryAddValue(query, kSecValueData, pwdata);
+
+    SInt32 i;
+    for(i=1; i<=N_ITEMS; i++) {
+        CFNumberRef port = CFNumberCreate(NULL, kCFNumberSInt32Type, &i);
+        CFDictionarySetValue(query, kSecAttrPort, port);
+        ok_status(SecItemAdd(query, NULL), "add internet password");
+        CFReleaseNull(port);
+    }
+
+    /* corrupt all the password */
+    CFStringRef keychain_path_cf = __SecKeychainCopyPath();
+
+    CFStringPerformWithCString(keychain_path_cf, ^(const char *keychain_path) {
+        /* Create a new keychain sqlite db */
+        sqlite3 *db;
+
+        is(sqlite3_open(keychain_path, &db), SQLITE_OK, "open keychain");
+
+        char corrupt_item_sql[80];
+        for(int i=1;i<=N_ITEMS;i++) {
+            ok_unix(snprintf(corrupt_item_sql, sizeof(corrupt_item_sql), "UPDATE inet SET data=X'12345678' WHERE rowid=%d", i));
+            is(sqlite3_exec(db, corrupt_item_sql, NULL, NULL, NULL), SQLITE_OK, "corrupting keychain item");
+        }
+    });
+
+    /* start the adder threads */
+    pthread_t add_thread[N_THREADS];
+    void *add_err[N_THREADS] = {NULL,};
+
+    for(int i=0; i<N_THREADS; i++)
+        pthread_create(&add_thread[i], NULL, do_add, (void*)(intptr_t)i);
+
+    /* query the corrupted items */
+    CFDictionaryAddValue(query, kSecReturnPersistentRef, kCFBooleanTrue);
+    for(int i=1;i<=N_ITEMS;i++) {
+        CFTypeRef ref = NULL;
+        CFNumberRef port = CFNumberCreate(NULL, kCFNumberSInt32Type, &i);
+        CFDictionarySetValue(query, kSecAttrPort, port);
+        is_status(SecItemCopyMatching(query, &ref), errSecItemNotFound, "Item not found");
+        CFReleaseNull(port);
+        CFReleaseNull(ref);
+    }
+
+    /* collect the adder threads */
+    for(int i=0; i<N_THREADS; i++)
+        pthread_join(add_thread[i], &add_err[i]);
+
+    for(int i=0; i<N_THREADS; i++)
+        ok(add_err[i]==NULL, "add thread");
+
+
+    CFReleaseNull(query);
+
+    return 0;
+}
diff --git a/sec/securityd/Regressions/secd-30-keychain-upgrade.c b/sec/securityd/Regressions/secd-30-keychain-upgrade.c
new file mode 100644 (file)
index 0000000..01c729d
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ *  secd-30-keychain-upgrade.c
+ *  Security
+ *
+ *  Created by Michael Brouwer on 4/29/08.
+ *  Copyright (c) 2008,2010,2013 Apple Inc.. All Rights Reserved.
+ *
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecBase.h>
+#include <Security/SecItem.h>
+#include <Security/SecItemPriv.h>
+#include <Security/SecInternal.h>
+#include <utilities/SecCFWrappers.h>
+#include <utilities/SecFileLocations.h>
+
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sqlite3.h>
+
+#include "secd_regressions.h"
+
+/* TODO: This test needs to be updated. It was originally created to test upgrades from DB prior to the introduction of versionning, circa 2008.
+ We don't support upgrading from that old of keychain, but this test should be upgraded to test upgrades from v5 to v6 keychain, or more current
+ */
+
+const char *create_db_sql =
+"BEGIN TRANSACTION;"
+"CREATE TABLE genp(cdat REAL,mdat REAL,desc BLOB,icmt BLOB,crtr INTEGER,type INTEGER,scrp INTEGER,labl BLOB,alis BLOB,invi INTEGER,nega INTEGER,cusi INTEGER,prot BLOB,acct BLOB NOT NULL DEFAULT '',svce BLOB NOT NULL DEFAULT '',gena BLOB,data BLOB,PRIMARY KEY(acct,svce));"
+"INSERT INTO \"genp\" VALUES(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'4087574952','EnhancedVoicemail',NULL,X'34F32095A0ED6F32637629114439CE38E6FF39ADB591E761D20ED23F9FACF639258DA4F12454FD4D0189C0D39AAA9227');"
+"INSERT INTO \"genp\" VALUES(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'TlalocNet','AirPort',NULL,X'52E24441994D93D18F344DDF6A7F1F6EC43A63BCEB5F89B02FEBEEAAE108BB4933EAE73A0FB615F693C70BCFBCF034BE74BDF0280ECBEB357EEFA3B7EF03060B');"
+"INSERT INTO \"genp\" VALUES(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'weasels','AirPort',NULL,X'3FAD49851913382FBC92C9EB90D90D82A74B1DABB5F726648898B2FA2FBA405AA0B9D95D9837BBFF0F9B7C29954973249AA066F9F8AA68D79552970C687A7DA6');"
+"CREATE TABLE inet(cdat REAL,mdat REAL,desc BLOB,icmt BLOB,crtr INTEGER,type INTEGER,scrp INTEGER,labl BLOB,alis BLOB,invi INTEGER,nega INTEGER,cusi INTEGER,prot BLOB,acct BLOB NOT NULL DEFAULT '',sdmn BLOB NOT NULL DEFAULT '',srvr BLOB NOT NULL DEFAULT '',ptcl INTEGER NOT NULL DEFAULT 0,atyp BLOB NOT NULL DEFAULT '',port INTEGER NOT NULL DEFAULT 0,path BLOB NOT NULL DEFAULT '',data BLOB,PRIMARY KEY(acct,sdmn,srvr,ptcl,atyp,port,path));"
+"INSERT INTO \"inet\" VALUES(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'mb.7766@gmail.com','','imap.gmail.com','imap','',143,'',X'0029D7AFBF0000E0E386C8654070569B2DF1D7DC2D641AA29223297EC9E8AD86ED91CA6DEE3D2DA0FABD8F05DE5A7AD4CC46B134A211472B6DE50595EACAC149');"
+"INSERT INTO \"inet\" VALUES(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'brouwer','','phonehome.apple.com','imap','',143,'',X'BB373BAE840427C5E1247540ADA559AB14DF3788906B786498A8E1CFF4B4C596634E4A4C7F9C55EA1B646163AFCDADA8');"
+"INSERT INTO \"inet\" VALUES(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'mb.7766@gmail.com','','smtp.gmail.com','smtp','',25,'',X'042C08A4AECD3957822F531A602734F07B89DABA3BA6629ECEFE10E264C12635F83EFBB1707C6B39FB20CCE0200D8997B690FBB0B92911BFE9B2D1E05B1CD5F5');"
+"INSERT INTO \"inet\" VALUES(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'brouwer','','phonehome.apple.com','smtp','',25,'',X'25B0775265ADC808B8AFB2F2602C44B13F5ECC1F04B1D5E6EAE1B803446F3A817CCF8401416FE673CE366E25FACF5C55');"
+"CREATE TABLE cert(ctyp INTEGER NOT NULL DEFAULT 0,cenc INTEGER,labl BLOB,alis BLOB,subj BLOB,issr BLOB NOT NULL DEFAULT '',slnr BLOB NOT NULL DEFAULT '',skid BLOB,pkhh BLOB,data BLOB,PRIMARY KEY(ctyp,issr,slnr));"
+"CREATE TABLE keys(kcls INTEGER NOT NULL DEFAULT 0,labl BLOB,alis BLOB,perm INTEGER,priv INTEGER,modi INTEGER,klbl BLOB NOT NULL DEFAULT '',atag BLOB NOT NULL DEFAULT '',crtr INTEGER NOT NULL DEFAULT 0,type INTEGER NOT NULL DEFAULT 0,bsiz INTEGER NOT NULL DEFAULT 0,esiz INTEGER NOT NULL DEFAULT 0,sdat REAL NOT NULL DEFAULT 0,edat REAL NOT NULL DEFAULT 0,sens INTEGER,asen INTEGER,extr INTEGER,next INTEGER,encr INTEGER,decr INTEGER,drve INTEGER,sign INTEGER,vrfy INTEGER,snrc INTEGER,vyrc INTEGER,wrap INTEGER,unwp INTEGER,data BLOB,PRIMARY KEY(kcls,klbl,atag,crtr,type,bsiz,esiz,sdat,edat));"
+"CREATE INDEX ialis ON cert(alis);"
+"CREATE INDEX isubj ON cert(subj);"
+"CREATE INDEX iskid ON cert(skid);"
+"CREATE INDEX ipkhh ON cert(pkhh);"
+"CREATE INDEX ikcls ON keys(kcls);"
+"CREATE INDEX iklbl ON keys(klbl);"
+"CREATE INDEX iencr ON keys(encr);"
+"CREATE INDEX idecr ON keys(decr);"
+"CREATE INDEX idrve ON keys(drve);"
+"CREATE INDEX isign ON keys(sign);"
+"CREATE INDEX ivrfy ON keys(vrfy);"
+"CREATE INDEX iwrap ON keys(wrap);"
+"CREATE INDEX iunwp ON keys(unwp);"
+"COMMIT;";
+
+#include "SecdTestKeychainUtilities.h"
+
+#include <securityd/SecItemServer.h>
+#include <utilities/SecCFWrappers.h>
+
+/* Test basic add delete update copy matching stuff. */
+static void tests(void)
+{
+    /* custom keychain dir */
+    secd_test_setup_temp_keychain("secd_30_keychain_upgrade", ^{
+        CFStringRef keychain_path_cf = __SecKeychainCopyPath();
+        
+        CFStringPerformWithCString(keychain_path_cf, ^(const char *keychain_path) {
+            /* Create a new keychain sqlite db */
+            sqlite3 *db;
+            is(sqlite3_open(keychain_path, &db), SQLITE_OK, "create keychain");
+            is(sqlite3_exec(db, create_db_sql, NULL, NULL, NULL), SQLITE_OK,
+               "populate keychain");
+            
+        });
+        
+        CFReleaseSafe(keychain_path_cf);
+    });
+
+    int v_eighty = 80;
+    CFNumberRef eighty = CFNumberCreate(NULL, kCFNumberSInt32Type, &v_eighty);
+    const char *v_data = "test";
+    CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data));
+    CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(query, kSecClass, kSecClassInternetPassword);
+    CFDictionaryAddValue(query, kSecAttrServer, CFSTR("members.spamcop.net"));
+    CFDictionaryAddValue(query, kSecAttrAccount, CFSTR("smith"));
+    CFDictionaryAddValue(query, kSecAttrPort, eighty);
+    CFDictionaryAddValue(query, kSecAttrProtocol, kSecAttrProtocolHTTP);
+    CFDictionaryAddValue(query, kSecAttrAuthenticationType, kSecAttrAuthenticationTypeDefault);
+    CFDictionaryAddValue(query, kSecValueData, pwdata);
+    ok_status(SecItemAdd(query, NULL), "add internet password");
+    is_status(SecItemAdd(query, NULL), errSecDuplicateItem,
+       "add internet password again");
+
+    ok_status(SecItemCopyMatching(query, NULL), "Found the item we added");
+
+    ok_status(SecItemDelete(query), "Deleted the item we added");
+
+    CFReleaseSafe(eighty);
+    CFReleaseSafe(pwdata);
+    CFReleaseSafe(query);
+
+
+    
+}
+
+int secd_30_keychain_upgrade(int argc, char *const *argv)
+{
+       plan_tests(6 + kSecdTestSetupTestCount);
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/securityd/Regressions/secd-31-keychain-bad.c b/sec/securityd/Regressions/secd-31-keychain-bad.c
new file mode 100644 (file)
index 0000000..0297c12
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ *  secd-31-keychain-bad.c
+ *  Security
+ *
+ *  Created by Michael Brouwer on 5/23/08.
+ *  Copyright (c) 2008,2010,2013 Apple Inc.. All Rights Reserved.
+ *
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecBase.h>
+#include <Security/SecItem.h>
+#include <utilities/SecFileLocations.h>
+
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sqlite3.h>
+
+#include "secd_regressions.h"
+
+const uint8_t keychain_data[] = {
+    0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xd2, 0x01, 0x02, 0x03,
+    0x04, 0x5f, 0x10, 0x1b, 0x4e, 0x53, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77,
+    0x20, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x20, 0x50, 0x72, 0x6f, 0x63, 0x65,
+    0x73, 0x73, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x5f, 0x10, 0x1d, 0x4e, 0x53,
+    0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x46, 0x72, 0x61, 0x6d, 0x65,
+    0x20, 0x41, 0x62, 0x6f, 0x75, 0x74, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20,
+    0x4d, 0x61, 0x63, 0x5f, 0x10, 0x1c, 0x32, 0x38, 0x20, 0x33, 0x37, 0x33,
+    0x20, 0x33, 0x34, 0x36, 0x20, 0x32, 0x39, 0x30, 0x20, 0x30, 0x20, 0x30,
+    0x20, 0x31, 0x34, 0x34, 0x30, 0x20, 0x38, 0x37, 0x38, 0x20, 0x5f, 0x10,
+    0x1d, 0x35, 0x36, 0x38, 0x20, 0x33, 0x39, 0x35, 0x20, 0x33, 0x30, 0x37,
+    0x20, 0x33, 0x37, 0x39, 0x20, 0x30, 0x20, 0x30, 0x20, 0x31, 0x34, 0x34,
+    0x30, 0x20, 0x38, 0x37, 0x38, 0x20, 0x08, 0x0d, 0x2b, 0x4b, 0x6a, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a
+};
+
+#include "SecdTestKeychainUtilities.h"
+
+#include <securityd/SecItemServer.h>
+#include <utilities/SecCFWrappers.h>
+
+/* Test basic add delete update copy matching stuff. */
+static void tests(void)
+{
+    /* custom keychain dir */
+    secd_test_setup_temp_keychain("secd_31_keychain_bad", ^{
+        CFStringRef keychain_path_cf = __SecKeychainCopyPath();
+        
+        CFStringPerformWithCString(keychain_path_cf, ^(const char *keychain_path) {
+            int fd;
+            ok_unix(fd = open(keychain_path, O_RDWR | O_CREAT | O_TRUNC, 0644),
+                    "create keychain file");
+            is(write(fd, keychain_data, sizeof(keychain_data)),
+               (ssize_t)sizeof(keychain_data), "write garbage to keychain file");
+            ok_unix(close(fd), "close keychain file");
+            
+        });
+        
+        CFReleaseSafe(keychain_path_cf);
+    });
+
+    int v_eighty = 80;
+    CFNumberRef eighty = CFNumberCreate(NULL, kCFNumberSInt32Type, &v_eighty);
+    const char *v_data = "test";
+    CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data));
+    CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(query, kSecClass, kSecClassInternetPassword);
+    CFDictionaryAddValue(query, kSecAttrServer, CFSTR("members.spamcop.net"));
+    CFDictionaryAddValue(query, kSecAttrAccount, CFSTR("smith"));
+    CFDictionaryAddValue(query, kSecAttrPort, eighty);
+    CFDictionaryAddValue(query, kSecAttrProtocol, kSecAttrProtocolHTTP);
+    CFDictionaryAddValue(query, kSecAttrAuthenticationType, kSecAttrAuthenticationTypeDefault);
+    CFDictionaryAddValue(query, kSecValueData, pwdata);
+    ok_status(SecItemAdd(query, NULL), "add internet password");
+    is_status(SecItemAdd(query, NULL), errSecDuplicateItem,
+       "add internet password again");
+
+    ok_status(SecItemCopyMatching(query, NULL), "Found the item we added");
+
+    ok_status(SecItemDelete(query),"Deleted the item we added");
+
+    CFRelease(query);
+    CFRelease(eighty);
+    CFRelease(pwdata);
+}
+
+int secd_31_keychain_bad(int argc, char *const *argv)
+{
+       plan_tests(7 + kSecdTestSetupTestCount);
+
+       tests();
+
+       return 0;
+}
diff --git a/sec/securityd/Regressions/secd-31-keychain-unreadable.c b/sec/securityd/Regressions/secd-31-keychain-unreadable.c
new file mode 100644 (file)
index 0000000..95b2f9d
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ *  secd-31-keychain-unreadable.c
+ *  Security
+ *
+ *  Created by Michael Brouwer on 5/23/08.
+ *  Copyright (c) 2008-2010,2013 Apple Inc.  All Rights Reserved.
+ *
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecBase.h>
+#include <Security/SecItem.h>
+#include <Security/SecInternal.h>
+#include <utilities/SecFileLocations.h>
+#include <utilities/SecCFWrappers.h>
+
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sqlite3.h>
+
+#include "secd_regressions.h"
+
+#include <securityd/SecItemServer.h>
+
+#include "SecdTestKeychainUtilities.h"
+
+
+/* Create an empty keychain file that can't be read or written and make sure
+   securityd can deal with it. */
+static void tests(void)
+{
+    /* custom keychain dir */
+    secd_test_setup_temp_keychain("secd_31_keychain_unreadable", ^{
+        CFStringRef keychain_path_cf = __SecKeychainCopyPath();
+        
+        CFStringPerformWithCString(keychain_path_cf, ^(const char *keychain_path) {
+            int fd;
+            ok_unix(fd = open(keychain_path, O_RDWR | O_CREAT | O_TRUNC, 0644),
+                    "create keychain file '%s'", keychain_path);
+            ok_unix(fchmod(fd, 0), " keychain file '%s'", keychain_path);
+            ok_unix(close(fd), "close keychain file '%s'", keychain_path);
+
+        });
+        
+        CFReleaseSafe(keychain_path_cf);
+    });
+
+    int v_eighty = 80;
+    CFNumberRef eighty = CFNumberCreate(NULL, kCFNumberSInt32Type, &v_eighty);
+    const char *v_data = "test";
+    CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data));
+    CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(query, kSecClass, kSecClassInternetPassword);
+    CFDictionaryAddValue(query, kSecAttrServer, CFSTR("members.spamcop.net"));
+    CFDictionaryAddValue(query, kSecAttrAccount, CFSTR("smith"));
+    CFDictionaryAddValue(query, kSecAttrPort, eighty);
+    CFDictionaryAddValue(query, kSecAttrProtocol, kSecAttrProtocolHTTP);
+    CFDictionaryAddValue(query, kSecAttrAuthenticationType, kSecAttrAuthenticationTypeDefault);
+    CFDictionaryAddValue(query, kSecValueData, pwdata);
+    ok_status(SecItemAdd(query, NULL), "add internet password");
+    is_status(SecItemAdd(query, NULL), errSecDuplicateItem,
+       "add internet password again");
+
+    ok_status(SecItemCopyMatching(query, NULL), "Found the item we added");
+
+    ok_status(SecItemDelete(query),"Deleted the item we added");
+
+    CFReleaseSafe(eighty);
+    CFReleaseSafe(pwdata);
+    CFReleaseSafe(query);
+}
+
+int secd_31_keychain_unreadable(int argc, char *const *argv)
+{
+       plan_tests(7 + kSecdTestSetupTestCount);
+       tests();
+
+       return 0;
+}
diff --git a/sec/securityd/Regressions/secd-50-account.c b/sec/securityd/Regressions/secd-50-account.c
new file mode 100644 (file)
index 0000000..d9216ee
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ *  secd_50_account.c
+ *
+ *  Created by Mitch Adler on 1/25/121.
+ *  Copyright 2012 Apple Inc. All rights reserved.
+ *
+ */
+
+
+#include <Security/SecBase.h>
+#include <Security/SecItem.h>
+
+#include <SecureObjectSync/SOSAccount.h>
+#include <SecureObjectSync/SOSCloudCircle.h>
+#include <SecureObjectSync/SOSInternal.h>
+#include <SecureObjectSync/SOSUserKeygen.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "secd_regressions.h"
+#include "SOSTestDataSource.h"
+
+#include "SOSRegressionUtilities.h"
+#include <utilities/SecCFWrappers.h>
+
+#include <securityd/SOSCloudCircleServer.h>
+
+#include "SecdTestKeychainUtilities.h"
+
+static int kTestTestCount = 10 + kSecdTestSetupTestCount;
+static void tests(void)
+{
+    secd_test_setup_temp_keychain("secd_50_account", ^{
+    });
+
+    CFErrorRef error = NULL;
+    CFDataRef cfpassword = CFDataCreate(NULL, (uint8_t *) "FooFooFoo", 10);
+    CFStringRef cfaccount = CFSTR("test@test.org");
+
+    SOSAccountKeyInterestBlock interest_block = ^(bool getNewKeysOnly, CFArrayRef alwaysKeys, CFArrayRef afterFirstUnlockKeys, CFArrayRef unlockedKeys) {};
+    SOSAccountDataUpdateBlock update_block = ^ bool (CFDictionaryRef keys, CFErrorRef *error) {return true;};
+
+    SOSDataSourceFactoryRef test_factory = SOSTestDataSourceFactoryCreate();
+    SOSDataSourceRef test_source = SOSTestDataSourceCreate();
+    SOSTestDataSourceFactoryAddDataSource(test_factory, CFSTR("TestType"), test_source);
+
+    CFDictionaryRef gestalt = SOSCreatePeerGestaltFromName(CFSTR("Test Device"));
+    SOSAccountRef account = SOSAccountCreate(kCFAllocatorDefault, gestalt, test_factory, interest_block, update_block);
+    ok(SOSAccountAssertUserCredentials(account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
+    CFReleaseNull(error);
+    CFReleaseNull(cfpassword);
+
+    ok(NULL != account, "Created");
+
+    ok(1 == SOSAccountCountCircles(account), "Has one circle");
+
+    size_t size = SOSAccountGetDEREncodedSize(account, &error);
+    CFReleaseNull(error);
+    uint8_t buffer[size];
+    uint8_t* start = SOSAccountEncodeToDER(account, &error, buffer, buffer + sizeof(buffer));
+    CFReleaseNull(error);
+
+    ok(start, "successful encoding");
+    ok(start == buffer, "Used whole buffer");
+
+    const uint8_t *der = buffer;
+    SOSAccountRef inflated = SOSAccountCreateFromDER(kCFAllocatorDefault, test_factory, interest_block, update_block,
+                                                     &error, &der, buffer + sizeof(buffer));
+
+    ok(inflated, "inflated");
+    ok(CFEqual(inflated, account), "Compares");
+
+    CFDictionaryRef new_gestalt = SOSCreatePeerGestaltFromName(CFSTR("New Device"));
+
+    ok(SOSAccountResetToOffering(account, &error), "Reset to Offering  (%@)", error);
+    CFReleaseNull(error);
+    
+    is(SOSAccountIsInCircles(account, &error), kSOSCCInCircle, "Was in Circle  (%@)", error);
+    CFReleaseNull(error);
+
+    SOSAccountUpdateGestalt(account, new_gestalt);
+
+    is(SOSAccountIsInCircles(account, &error), kSOSCCInCircle, "Still in Circle  (%@)", error);
+    CFReleaseNull(error);
+
+    CFReleaseNull(gestalt);
+    CFReleaseNull(new_gestalt);
+    CFReleaseNull(account);
+}
+
+int secd_50_account(int argc, char *const *argv)
+{
+    plan_tests(kTestTestCount);
+       
+    tests();
+
+       return 0;
+}
diff --git a/sec/securityd/Regressions/secd-51-account-inflate.c b/sec/securityd/Regressions/secd-51-account-inflate.c
new file mode 100644 (file)
index 0000000..96766c5
--- /dev/null
@@ -0,0 +1,141 @@
+//
+//  secd-51-account-inflate.c
+//  sec
+//
+//  Created by Richard Murphy on 7/22/13.
+//
+//
+
+#include <Security/SecBase.h>
+#include <Security/SecItem.h>
+
+#include <SecureObjectSync/SOSAccount.h>
+#include <SecureObjectSync/SOSCloudCircle.h>
+#include <SecureObjectSync/SOSInternal.h>
+#include <SecureObjectSync/SOSUserKeygen.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "secd_regressions.h"
+#include "SOSTestDataSource.h"
+
+#include "SOSRegressionUtilities.h"
+#include <utilities/SecCFWrappers.h>
+
+#include <securityd/SOSCloudCircleServer.h>
+
+#include "SecdTestKeychainUtilities.h"
+
+uint8_t staticbuffer[439] = {
+    0x30, 0x82, 0x01, 0xB3, 0x31, 0x1D, 0x30, 0x1B, 0x0C, 0x0C, 0x43, 0x6F, 0x6D, 0x70, 0x75, 0x74,
+    0x65, 0x72, 0x4E, 0x61, 0x6D, 0x65, 0x0C, 0x0B, 0x54, 0x65, 0x73, 0x74, 0x20, 0x44, 0x65, 0x76,
+    0x69, 0x63, 0x65, 0x30, 0x82, 0x01, 0x1F, 0x30, 0x82, 0x01, 0x1B, 0x04, 0x1A, 0x30, 0x18, 0x02,
+    0x01, 0x01, 0x0C, 0x08, 0x54, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x02, 0x01, 0x01, 0x30,
+    0x00, 0x30, 0x00, 0x30, 0x00, 0x31, 0x00, 0x04, 0x81, 0xFC, 0x30, 0x81, 0xF9, 0x30, 0x81, 0xE8,
+    0x31, 0x81, 0x9D, 0x30, 0x14, 0x0C, 0x0F, 0x43, 0x6F, 0x6E, 0x66, 0x6C, 0x69, 0x63, 0x74, 0x56,
+    0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x02, 0x01, 0x01, 0x30, 0x2E, 0x0C, 0x0D, 0x44, 0x65, 0x76,
+    0x69, 0x63, 0x65, 0x47, 0x65, 0x73, 0x74, 0x61, 0x6C, 0x74, 0x31, 0x1D, 0x30, 0x1B, 0x0C, 0x0C,
+    0x43, 0x6F, 0x6D, 0x70, 0x75, 0x74, 0x65, 0x72, 0x4E, 0x61, 0x6D, 0x65, 0x0C, 0x0B, 0x54, 0x65,
+    0x73, 0x74, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x30, 0x55, 0x0C, 0x10, 0x50, 0x75, 0x62,
+    0x6C, 0x69, 0x63, 0x53, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67, 0x4B, 0x65, 0x79, 0x04, 0x41, 0x04,
+    0x35, 0xD6, 0x80, 0xF7, 0xB1, 0xC8, 0x83, 0x78, 0x74, 0x27, 0x3B, 0xDD, 0x3C, 0xBB, 0x0E, 0x35,
+    0xA3, 0xAC, 0x6A, 0xC5, 0xD6, 0xB1, 0xC7, 0x17, 0x17, 0xD9, 0xEE, 0x51, 0x34, 0x3F, 0x83, 0x60,
+    0xE0, 0x99, 0xCB, 0xF7, 0x6B, 0xC1, 0x27, 0x34, 0xB8, 0x4B, 0xE9, 0x2F, 0x43, 0xF9, 0x2F, 0x47,
+    0xD3, 0x45, 0x45, 0xEA, 0x01, 0x68, 0x53, 0xAF, 0x99, 0xEE, 0x49, 0xD3, 0xC6, 0x04, 0x56, 0x95,
+    0x04, 0x46, 0x30, 0x44, 0x02, 0x20, 0x79, 0xC9, 0x7A, 0xC9, 0x5D, 0x96, 0x7A, 0x95, 0xCC, 0xD3,
+    0xE5, 0xEC, 0x45, 0x2A, 0x40, 0x06, 0x09, 0x72, 0xFB, 0xBB, 0x20, 0x0E, 0x4A, 0x8E, 0x4A, 0x0B,
+    0x22, 0xF1, 0xA5, 0x38, 0x74, 0x78, 0x02, 0x20, 0x2E, 0xB1, 0x92, 0x3A, 0x8F, 0x42, 0xEC, 0x15,
+    0x87, 0x53, 0x57, 0xCB, 0x70, 0x2E, 0x17, 0x58, 0xA1, 0x12, 0x3E, 0x77, 0xE2, 0xA9, 0x14, 0x82,
+    0x9F, 0xF4, 0x63, 0x4B, 0xB3, 0x0F, 0xEB, 0x55, 0x04, 0x0C, 0x6B, 0x65, 0x79, 0x73, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x04, 0x41, 0x04, 0x1C, 0x1D, 0x2D, 0x00,
+    0x08, 0x30, 0x82, 0x5E, 0x98, 0x84, 0x83, 0x52, 0xEA, 0xA6, 0x65, 0x9B, 0x25, 0x27, 0x1E, 0x40,
+    0xBA, 0x36, 0x0C, 0x73, 0x07, 0xEA, 0x9B, 0x6F, 0xB4, 0x4E, 0x41, 0xD1, 0xF9, 0x49, 0x07, 0x59,
+    0x66, 0x63, 0xEE, 0x41, 0xB1, 0xF0, 0x7F, 0x5F, 0xBA, 0xE5, 0x3C, 0x0A, 0xDE, 0x42, 0xC6, 0x4A,
+    0xEF, 0x6F, 0x10, 0xC5, 0x8C, 0x1B, 0x5C, 0x1B, 0xDA, 0xD4, 0x5C, 0x3B, 0x04, 0x27, 0x30, 0x25,
+    0x04, 0x10, 0x24, 0x1F, 0x16, 0xC5, 0x82, 0xF9, 0xC3, 0xEE, 0x00, 0x09, 0x18, 0xF0, 0xFE, 0x55,
+    0xCC, 0x72, 0x02, 0x03, 0x00, 0xC3, 0x50, 0x02, 0x02, 0x01, 0x00, 0x06, 0x08, 0x2A, 0x86, 0x48,
+    0x86, 0xF7, 0x0D, 0x02, 0x07, 0x31, 0x00
+};
+
+
+
+static int kTestTestCount = 11 + kSecdTestSetupTestCount;
+static void tests(void)
+{
+    secd_test_setup_temp_keychain("secd_51_account_inflate", ^{
+    });
+
+    CFErrorRef error = NULL;
+    CFDataRef cfpassword = CFDataCreate(NULL, (uint8_t *) "FooFooFoo", 10);
+    CFStringRef cfaccount = CFSTR("test@test.org");
+
+    SOSAccountKeyInterestBlock interest_block = ^(bool getNewKeysOnly, CFArrayRef alwaysKeys, CFArrayRef afterFirstUnlockKeys, CFArrayRef unlockedKeys) {};
+    SOSAccountDataUpdateBlock update_block = ^ bool (CFDictionaryRef keys, CFErrorRef *error) {return true;};
+
+    SOSDataSourceFactoryRef test_factory = SOSTestDataSourceFactoryCreate();
+    SOSDataSourceRef test_source = SOSTestDataSourceCreate();
+    SOSTestDataSourceFactoryAddDataSource(test_factory, CFSTR("TestType"), test_source);
+
+    CFDictionaryRef gestalt = SOSCreatePeerGestaltFromName(CFSTR("Test Device"));
+    SOSAccountRef account = SOSAccountCreate(kCFAllocatorDefault, gestalt, test_factory,
+                                             interest_block, update_block);
+    ok(SOSAccountAssertUserCredentials(account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
+    CFReleaseNull(error);
+    CFReleaseNull(cfpassword);
+
+    ok(NULL != account, "Created");
+
+    ok(1 == SOSAccountCountCircles(account), "Has one circle");
+
+    // Use this part with suitable changes to test when we allow account upgrades.
+    size_t size = SOSAccountGetDEREncodedSize(account, &error);
+    CFReleaseNull(error);
+    uint8_t buffer[size];
+    uint8_t* start = SOSAccountEncodeToDER(account, &error, buffer, buffer + sizeof(buffer));
+    CFReleaseNull(error);
+
+    ok(start, "successful encoding");
+    ok(start == buffer, "Used whole buffer");
+
+    const uint8_t *der = buffer;
+    SOSAccountRef inflated = SOSAccountCreateFromDER(kCFAllocatorDefault, test_factory, interest_block, update_block,
+                                                     &error, &der, buffer + sizeof(buffer));
+
+    ok(inflated, "inflated");
+    ok(CFEqual(inflated, account), "Compares");
+
+#if UPGRADE_FROM_PREVIOUS_VERSION
+    CFDictionaryRef new_gestalt = SOSCreatePeerGestaltFromName(CFSTR("New Device"));
+
+    ok(SOSAccountResetToOffering(account, &error), "Reset to Offering  (%@)", error);
+    CFReleaseNull(error);
+
+    is(SOSAccountIsInCircles(account, &error), kSOSCCInCircle, "Was in Circle  (%@)", error);
+    CFReleaseNull(error);
+
+    SOSAccountUpdateGestalt(account, new_gestalt);
+
+    is(SOSAccountIsInCircles(account, &error), kSOSCCInCircle, "Still in Circle  (%@)", error);
+    CFReleaseNull(error);
+
+// See if this account inflates:
+
+    const uint8_t *der2 = staticbuffer;
+    SOSAccountRef inflated2 = SOSAccountCreateFromDER(kCFAllocatorDefault, test_factory, interest_block, update_block,
+                                                      &error, &der2, staticbuffer + sizeof(staticbuffer));
+
+    ok(!inflated2, "inflated2");
+#endif
+    CFReleaseNull(gestalt);
+    CFReleaseNull(account);
+}
+
+int secd_51_account_inflate(int argc, char *const *argv)
+{
+    plan_tests(kTestTestCount);
+
+    tests();
+
+       return 0;
+}
diff --git a/sec/securityd/Regressions/secd-52-account-changed.c b/sec/securityd/Regressions/secd-52-account-changed.c
new file mode 100644 (file)
index 0000000..8972233
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ *  secd_52_account_changed.c
+ *
+ *  Created by Richard Murphy on 09152013.
+ *  Copyright 2013 Apple Inc. All rights reserved.
+ *
+ */
+
+
+#include <Security/SecBase.h>
+#include <Security/SecItem.h>
+
+#include <SecureObjectSync/SOSAccount.h>
+#include <SecureObjectSync/SOSCloudCircle.h>
+#include <SecureObjectSync/SOSInternal.h>
+#include <SecureObjectSync/SOSUserKeygen.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "secd_regressions.h"
+#include "SOSTestDataSource.h"
+
+#include "SOSRegressionUtilities.h"
+#include <utilities/SecCFWrappers.h>
+
+#include <securityd/SOSCloudCircleServer.h>
+
+#include "SecdTestKeychainUtilities.h"
+#include "SOSAccountTesting.h"
+
+
+static int kTestTestCount = 133;
+
+
+static void tests(void)
+{
+    CFErrorRef error = NULL;
+    CFDataRef cfpassword = CFDataCreate(NULL, (uint8_t *) "FooFooFoo", 10);
+    CFStringRef cfaccount = CFSTR("test@test.org");
+    
+    CFMutableDictionaryRef changes = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
+    
+    SOSAccountRef alice_account = CreateAccountForLocalChanges(changes, CFSTR("Alice"), CFSTR("TestSource"));
+    SOSAccountRef bob_account = CreateAccountForLocalChanges(changes, CFSTR("Bob"), CFSTR("TestSource"));
+    SOSAccountRef carol_account = CreateAccountForLocalChanges(changes, CFSTR("Carol"), CFSTR("TestSource"));
+    
+    ok(SOSAccountAssertUserCredentials(bob_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
+    
+    // Bob wins writing at this point, feed the changes back to alice.
+    
+    FeedChangesToMulti(changes, alice_account, carol_account, NULL);
+    
+    ok(SOSAccountAssertUserCredentials(alice_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
+    CFReleaseNull(error);
+    ok(SOSAccountAssertUserCredentials(carol_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
+    CFReleaseNull(error);
+    CFReleaseNull(cfpassword);
+    
+    /* ==================== Three Accounts setup =============================================*/
+    
+    ok(SOSAccountResetToOffering(alice_account, &error), "Reset to offering (%@)", error);
+    CFReleaseNull(error);
+    
+    FeedChangesToMulti(changes, bob_account, carol_account, NULL);
+    
+    ok(SOSAccountJoinCircles(bob_account, &error), "Bob Applies (%@)", error);
+    CFReleaseNull(error);
+    
+    FeedChangesToMulti(changes, alice_account, carol_account, bob_account, NULL);
+    
+    ok(SOSAccountJoinCircles(carol_account, &error), "Carol Applies (%@)", error);
+    CFReleaseNull(error);
+    
+    FeedChangesToMulti(changes, alice_account, carol_account, bob_account, NULL);
+
+    {
+        CFArrayRef applicants = SOSAccountCopyApplicants(alice_account, &error);
+        
+        ok(applicants && CFArrayGetCount(applicants) == 2, "See two applicants %@ (%@)", applicants, error);
+        ok(SOSAccountAcceptApplicants(alice_account, applicants, &error), "Alice accepts (%@)", error);
+        CFReleaseNull(error);
+        CFReleaseNull(applicants);
+    }
+    
+    FeedChangesToMulti(changes, bob_account, NULL); // let bob concurr
+    FeedChangesToMulti(changes, alice_account, carol_account, NULL); // let carol concurr
+    FeedChangesToMulti(changes, alice_account, bob_account, carol_account, NULL); // all synced
+    FeedChangesToMulti(changes, alice_account, bob_account, carol_account, NULL); // all synced
+    FeedChangesToMulti(changes, alice_account, bob_account, carol_account, NULL); // all synced
+    
+    ok(CFDictionaryGetCount(changes) == 0, "We converged. (%@)", changes);
+    
+    accounts_agree_internal("bob&alice pair", bob_account, alice_account, false);
+    accounts_agree_internal("bob&carol pair", bob_account, carol_account, false);
+    /* ==================== Three Accounts in circle =============================================*/
+    InjectChangeToMulti(CFSTR("^AccountChanged"), CFSTR("none"), alice_account, bob_account, carol_account, NULL);
+    
+    is(SOSAccountIsInCircles(alice_account, &error), kSOSCCError, "Account reset - no user keys - error");
+    is(SOSAccountIsInCircles(bob_account, &error), kSOSCCError, "Account reset - no user keys - error");
+    is(SOSAccountIsInCircles(carol_account, &error), kSOSCCError, "Account reset - no user keys - error");
+
+    CFDataRef cfpassword2 = CFDataCreate(NULL, (uint8_t *) "ooFooFooF", 10);
+    CFStringRef cfaccount2 = CFSTR("test2@test.org");
+
+    ok(SOSAccountAssertUserCredentials(alice_account, cfaccount2, cfpassword2, &error), "Credential setting (%@)", error);
+    CFReleaseNull(error);
+
+    is(SOSAccountIsInCircles(alice_account, &error), kSOSCCCircleAbsent, "Account reset - circle is absent");
+    is(SOSAccountIsInCircles(bob_account, &error), kSOSCCError, "Account reset - no user keys - error");
+    FeedChangesToMulti(changes, bob_account, carol_account, NULL);
+
+    ok(SOSAccountAssertUserCredentials(bob_account, cfaccount2, cfpassword2, &error), "Credential setting (%@)", error);
+    CFReleaseNull(error);
+
+    ok(SOSAccountAssertUserCredentials(carol_account, cfaccount2, cfpassword2, &error), "Credential setting (%@)", error);
+    CFReleaseNull(error);
+
+    is(SOSAccountIsInCircles(bob_account, &error), kSOSCCCircleAbsent, "Account reset - circle is absent");
+    is(SOSAccountIsInCircles(carol_account, &error), kSOSCCCircleAbsent, "Account reset - circle is absent");
+    // Now everyone is playing the same account.
+
+    /* ==================== Three Accounts setup =============================================*/
+
+    ok(SOSAccountResetToOffering(alice_account, &error), "Reset to offering (%@)", error);
+    CFReleaseNull(error);
+    is(countActivePeers(alice_account), 2, "2 peers - alice and icloud");
+
+    FeedChangesToMulti(changes, bob_account, carol_account, NULL);
+    is(SOSAccountIsInCircles(alice_account, &error), kSOSCCInCircle, "Alice is in circle");
+    is(SOSAccountIsInCircles(bob_account, &error), kSOSCCNotInCircle, "Bob is not in circle");
+    is(SOSAccountIsInCircles(carol_account, &error), kSOSCCNotInCircle, "Carol is not in circle");
+
+    ok(SOSAccountJoinCircles(bob_account, &error), "Bob Applies (%@)", error);
+    CFReleaseNull(error);
+
+    FeedChangesToMulti(changes, alice_account, carol_account, bob_account, NULL);
+    is(SOSAccountIsInCircles(bob_account, &error), kSOSCCRequestPending, "Bob has a pending request");
+
+    ok(SOSAccountJoinCircles(carol_account, &error), "Carol Applies (%@)", error);
+    CFReleaseNull(error);
+
+    FeedChangesToMulti(changes, alice_account, carol_account, bob_account, NULL);
+    is(SOSAccountIsInCircles(carol_account, &error), kSOSCCRequestPending, "Carol has a pending request");
+
+    {
+        CFArrayRef applicants = SOSAccountCopyApplicants(alice_account, &error);
+
+        ok(applicants && CFArrayGetCount(applicants) == 2, "See two applicants %@ (%@)", applicants, error);
+        ok(SOSAccountAcceptApplicants(alice_account, applicants, &error), "Alice accepts (%@)", error);
+        CFReleaseNull(error);
+        CFReleaseNull(applicants);
+        is(countActivePeers(alice_account), 4, "4 peers - alice, bob, carol, and icloud");
+    }
+
+    FeedChangesToMulti(changes, bob_account, NULL); // let bob concurr
+    is(SOSAccountIsInCircles(bob_account, &error), kSOSCCInCircle, "Bob is in circle");
+    FeedChangesToMulti(changes, alice_account, carol_account, NULL); // let carol concurr
+    is(SOSAccountIsInCircles(carol_account, &error), kSOSCCInCircle, "Carol is in circle");
+    FeedChangesToMulti(changes, alice_account, bob_account, carol_account, NULL); // all synced
+    FeedChangesToMulti(changes, alice_account, bob_account, carol_account, NULL); // all synced
+    FeedChangesToMulti(changes, alice_account, bob_account, carol_account, NULL); // all synced
+
+    ok(CFDictionaryGetCount(changes) == 0, "We converged. (%@)", changes);
+
+    accounts_agree_internal("bob&alice pair", bob_account, alice_account, false);
+    accounts_agree_internal("bob&carol pair", bob_account, carol_account, false);
+
+}
+
+
+int secd_52_account_changed(int argc, char *const *argv)
+{
+    plan_tests(kTestTestCount);
+       
+    tests();
+    
+       return 0;
+}
diff --git a/sec/securityd/Regressions/secd-55-account-circle.c b/sec/securityd/Regressions/secd-55-account-circle.c
new file mode 100644 (file)
index 0000000..af4bec9
--- /dev/null
@@ -0,0 +1,298 @@
+//
+//  secd-55-account-circle.c
+//  sec
+//
+//  Created by Mitch Adler on 1/25/12.
+//
+//
+
+
+
+#include <Security/SecBase.h>
+#include <Security/SecItem.h>
+
+#include <CoreFoundation/CFDictionary.h>
+
+#include <SecureObjectSync/SOSAccount.h>
+#include <SecureObjectSync/SOSCloudCircle.h>
+#include <SecureObjectSync/SOSInternal.h>
+#include <SecureObjectSync/SOSUserKeygen.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "secd_regressions.h"
+#include "SOSTestDataSource.h"
+
+#include "SOSRegressionUtilities.h"
+#include <utilities/SecCFWrappers.h>
+#include <Security/SecKeyPriv.h>
+
+#include <securityd/SOSCloudCircleServer.h>
+
+#include "SOSAccountTesting.h"
+
+
+static int kTestTestCount = 202;
+
+static void tests(void)
+{
+    CFErrorRef error = NULL;
+    CFDataRef cfpassword = CFDataCreate(NULL, (uint8_t *) "FooFooFoo", 10);
+    CFDataRef cfwrong_password = CFDataCreate(NULL, (uint8_t *) "NotFooFooFoo", 10);
+    CFStringRef cfaccount = CFSTR("test@test.org");
+
+    CFMutableDictionaryRef changes = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
+
+    SOSAccountRef alice_account = CreateAccountForLocalChanges(changes, CFSTR("Alice"), CFSTR("TestSource"));
+    SOSAccountRef bob_account = CreateAccountForLocalChanges(changes, CFSTR("Bob"), CFSTR("TestSource"));
+    SOSAccountRef carol_account = CreateAccountForLocalChanges(changes, CFSTR("Carol"), CFSTR("TestSource"));
+
+    ok(SOSAccountAssertUserCredentials(bob_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
+
+    // Bob wins writing at this point, feed the changes back to alice.
+
+    FeedChangesToMulti(changes, alice_account, carol_account, NULL);
+
+    ok(SOSAccountAssertUserCredentials(alice_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
+    CFReleaseNull(error);
+    ok(SOSAccountTryUserCredentials(alice_account, cfaccount, cfpassword, &error), "Credential trying (%@)", error);
+    CFReleaseNull(error);
+    ok(!SOSAccountTryUserCredentials(alice_account, cfaccount, cfwrong_password, &error), "Credential failing (%@)", error);
+    CFReleaseNull(cfwrong_password);
+    is(error ? CFErrorGetCode(error) : 0, kSOSErrorWrongPassword, "Expected SOSErrorWrongPassword");
+    CFReleaseNull(error);
+
+    ok(SOSAccountResetToOffering(alice_account, &error), "Reset to offering (%@)", error);
+    CFReleaseNull(error);
+
+    FeedChangesTo(changes, bob_account);
+
+    ok(SOSAccountJoinCircles(bob_account, &error), "Bob Applies (%@)", error);
+    CFReleaseNull(error);
+
+    FeedChangesTo(changes, alice_account);
+
+    {
+        CFArrayRef applicants = SOSAccountCopyApplicants(alice_account, &error);
+
+        ok(applicants && CFArrayGetCount(applicants) == 1, "See one applicant %@ (%@)", applicants, error);
+        ok(SOSAccountAcceptApplicants(alice_account, applicants, &error), "Alice accepts (%@)", error);
+        CFReleaseNull(error);
+        CFReleaseNull(applicants);
+    }
+
+
+    FeedChangesTo(changes, bob_account); // Bob sees he's accepted
+
+    FeedChangesTo(changes, alice_account); // Alice sees bob-concurring
+
+    ok(CFDictionaryGetCount(changes) == 0, "We converged. (%@)", changes);
+
+    accounts_agree("bob&alice pair", bob_account, alice_account);
+
+    CFArrayRef peers = SOSAccountCopyPeers(alice_account, &error);
+    ok(peers && CFArrayGetCount(peers) == 2, "See two peers %@ (%@)", peers, error);
+    CFReleaseNull(peers);
+
+    CFDictionaryRef alice_new_gestalt = SOSCreatePeerGestaltFromName(CFSTR("Alice, but different"));
+
+    ok(SOSAccountUpdateGestalt(alice_account, alice_new_gestalt), "Update gestalt %@ (%@)", alice_account, error);
+    CFReleaseNull(alice_new_gestalt);
+
+    FeedChangesTo(changes, bob_account); // Bob sees alice change her name.
+
+    FeedChangesTo(changes, alice_account); // Alice sees the fallout.
+
+    accounts_agree("Alice's name changed", bob_account, alice_account);
+
+    ok(SOSAccountLeaveCircles(alice_account, &error), "Alice Leaves (%@)", error);
+    CFReleaseNull(error);
+
+    FeedChangesTo(changes, bob_account); // Bob sees alice bail.
+
+    FeedChangesTo(changes, alice_account); // Alice sees the fallout.
+
+    accounts_agree("Alice bails", bob_account, alice_account);
+
+    peers = SOSAccountCopyPeers(alice_account, &error);
+    ok(peers && CFArrayGetCount(peers) == 1, "See one peer %@ (%@)", peers, error);
+    CFReleaseNull(peers);
+
+    ok(SOSAccountJoinCircles(alice_account, &error), "Alice re-applies (%@)", error);
+    CFReleaseNull(error);
+
+    FeedChangesTo(changes, bob_account);
+
+
+    {
+        CFArrayRef applicants = SOSAccountCopyApplicants(alice_account, &error);
+
+        ok(applicants && CFArrayGetCount(applicants) == 1, "See one applicant %@ (%@)", applicants, error);
+        ok(SOSAccountAcceptApplicants(bob_account, applicants, &error), "Bob accepts (%@)", error);
+        CFReleaseNull(error);
+        CFReleaseNull(applicants);
+    }
+
+    FeedChangesTo(changes, alice_account); // Alice sees bob accepting
+
+    FeedChangesTo(changes, bob_account); // Bob sees Alice concurring
+
+    accounts_agree("Alice accepts' Bob", bob_account, alice_account);
+
+    ok(SOSAccountLeaveCircles(alice_account, &error), "Alice Leaves (%@)", error);
+    CFReleaseNull(error);
+    ok(SOSAccountJoinCircles(alice_account, &error), "Alice re-applies (%@)", error);
+    CFReleaseNull(error);
+
+    FeedChangesTo(changes, bob_account); // Bob sees Alice leaving and rejoining
+    FeedChangesTo(changes, alice_account); // Alice sees bob concurring
+
+    {
+        CFArrayRef applicants = SOSAccountCopyApplicants(alice_account, &error);
+
+        ok(applicants && CFArrayGetCount(applicants) == 1, "See one applicant %@ (%@)", applicants, error);
+        ok(SOSAccountAcceptApplicants(bob_account, applicants, &error), "Bob accepts (%@)", error);
+        CFReleaseNull(error);
+        CFReleaseNull(applicants);
+    }
+
+    FeedChangesTo(changes, alice_account); // Alice sees bob accepting
+
+    FeedChangesTo(changes, bob_account); // Bob sees Alice concurring
+
+    accounts_agree("Bob accepts Alice", bob_account, alice_account);
+
+    // As of PR-13917727/PR-13906870 this no longer works (by "design"), in favor of making another more common
+    // failure (apply/OSX-psudo-reject/re-apply) work.  Write races might be "fixed better" with affirmitave rejection.
+#if 0
+
+    //
+    // Write race emulation.
+    //
+    //
+
+    ok(SOSAccountLeaveCircles(alice_account, &error), "Alice Leaves (%@)", error);
+    CFReleaseNull(error);
+    FeedChangesTo(changes, bob_account); // Bob sees Alice leaving and rejoining
+    FeedChangesTo(changes, alice_account); // Alice sees bob concurring
+
+    accounts_agree("Alice leaves & returns", bob_account, alice_account);
+
+    ok(SOSAccountJoinCircles(alice_account, &error), "Alice re-applies (%@)", error);
+    CFReleaseNull(error);
+
+    FeedChangesTo(changes, bob_account); // Bob sees Alice Applying
+
+    {
+        CFArrayRef applicants = SOSAccountCopyApplicants(alice_account, &error);
+
+        ok(applicants && CFArrayGetCount(applicants) == 1, "See one applicant %@ (%@)", applicants, error);
+        ok(SOSAccountAcceptApplicants(bob_account, applicants, &error), "Bob accepts (%@)", error);
+        CFReleaseNull(error);
+        CFReleaseNull(applicants);
+    }
+
+    CFMutableDictionaryRef bobAcceptanceChanges = ExtractPendingChanges(changes);
+
+    // Alice re-applies without seeing that she was accepted.
+    ok(SOSAccountLeaveCircles(alice_account, &error), "Alice Leaves again  (%@)", error);
+    CFReleaseNull(error);
+    ok(SOSAccountJoinCircles(alice_account, &error), "Alice re-applies (%@)", error);
+    CFReleaseNull(error);
+
+    CFReleaseSafe(ExtractPendingChanges(changes)); // Alice loses the race to write her changes - bob never sees em.
+
+    FeedChangesTo(&bobAcceptanceChanges, alice_account); // Alice sees bob inviting her in the circle.
+
+    FeedChangesTo(changes, bob_account); // Bob sees Alice Concurring
+
+    // As of PR-13917727/PR-13906870
+    accounts_agree("Alice leave, applies back, loses a race and eventually gets in", bob_account, alice_account);
+#endif
+
+    // Both in circle.
+
+    // We want Alice to leave circle while an Applicant on a full concordance signed circle with old-Alice as an Alum and Bob a peer.
+    // ZZZ
+    ok(SOSAccountLeaveCircles(alice_account, &error), "Alice leaves once more  (%@)", error);
+    CFReleaseNull(error);
+
+    FeedChangesTo(changes, bob_account); // Bob sees Alice become an Alum.
+    FeedChangesTo(changes, alice_account); // Alice sees bob concurring
+    accounts_agree("Alice and Bob see Alice out of circle", bob_account, alice_account);
+
+    ok(SOSAccountJoinCircles(alice_account, &error), "Alice re-applies (%@)", error);
+    CFReleaseNull(error);
+
+    ok(SOSAccountLeaveCircles(alice_account, &error), "Alice leaves while applying  (%@)", error);
+    FeedChangesTo(changes, bob_account); // Bob sees Alice become an Alum.
+
+    CFReleaseNull(error);
+
+    is(SOSAccountIsInCircles(alice_account, &error), kSOSCCNotInCircle, "Alice isn't applying any more");
+    accounts_agree("Alice leaves & some fancy concordance stuff happens", bob_account, alice_account);
+
+    ok(SOSAccountJoinCircles(alice_account, &error), "Alice re-applies (%@)", error);
+    CFReleaseNull(error);
+
+    FeedChangesTo(changes, bob_account); // Bob sees Alice reapply.
+
+    {
+        CFArrayRef applicants = SOSAccountCopyApplicants(alice_account, &error);
+
+        ok(applicants && CFArrayGetCount(applicants) == 1, "See one applicant %@ (%@)", applicants, error);
+        ok(SOSAccountAcceptApplicants(bob_account, applicants, &error), "Bob accepts (%@)", error);
+        CFReleaseNull(error);
+        CFReleaseNull(applicants);
+    }
+
+    FeedChangesTo(changes, alice_account); // Alice sees bob accepting her
+    FeedChangesTo(changes, bob_account); // Bob sees Alice concur
+
+    accounts_agree("Alice comes back", bob_account, alice_account);
+
+    // Emulation of <rdar://problem/13889901>
+    FeedChangesTo(changes, carol_account);
+
+    ok(SOSAccountAssertUserCredentials(carol_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
+    CFReleaseNull(cfpassword);
+    ok(SOSAccountJoinCircles(carol_account, &error), "Carol Applies (%@)", error);
+    CFReleaseNull(error);
+    CFReleaseSafe(ExtractPendingChanges(changes)); // Alice and Bob loses the race to see Carol's changes.
+
+    ok(SOSAccountResetToOffering(carol_account, &error), "Reset to offering (%@)", error);
+    CFReleaseNull(error);
+    FeedChangesTo(changes, bob_account);
+    accounts_agree("13889901", carol_account, bob_account);
+    is(SOSAccountGetLastDepartureReason(bob_account, &error), kSOSMembershipRevoked, "Bob affirms he hasn't left.");
+
+    ok(SOSAccountJoinCircles(bob_account, &error), "Bob ReApplies (%@)", error);
+    FeedChangesTo(changes, carol_account);
+    {
+        CFArrayRef applicants = SOSAccountCopyApplicants(carol_account, &error);
+
+        ok(applicants && CFArrayGetCount(applicants) == 1, "See one applicant %@ (%@)", applicants, error);
+        ok(SOSAccountAcceptApplicants(carol_account, applicants, &error), "Carol accepts (%@)", error);
+        CFReleaseNull(error);
+        CFReleaseNull(applicants);
+    }
+    FeedChangesTo(changes, bob_account);
+    FeedChangesTo(changes, carol_account);
+    accounts_agree("rdar://problem/13889901-II", bob_account, carol_account);
+
+    CFReleaseNull(alice_new_gestalt);
+
+    CFReleaseNull(bob_account);
+    CFReleaseNull(alice_account);
+    CFReleaseNull(carol_account);
+}
+
+int secd_55_account_circle(int argc, char *const *argv)
+{
+    plan_tests(kTestTestCount);
+
+    tests();
+
+       return 0;
+}
diff --git a/sec/securityd/Regressions/secd-55-account-incompatibility.c b/sec/securityd/Regressions/secd-55-account-incompatibility.c
new file mode 100644 (file)
index 0000000..24694aa
--- /dev/null
@@ -0,0 +1,197 @@
+//
+//  secd-55-account-circle.c
+//  sec
+//
+//  Created by Mitch Adler on 1/25/12.
+//
+//
+
+
+
+#include <Security/SecBase.h>
+#include <Security/SecItem.h>
+
+#include <CoreFoundation/CFDictionary.h>
+
+#include <SecureObjectSync/SOSAccount.h>
+#include <SecureObjectSync/SOSCloudCircle.h>
+#include <SecureObjectSync/SOSInternal.h>
+#include <SecureObjectSync/SOSUserKeygen.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "secd_regressions.h"
+#include "SOSTestDataSource.h"
+
+#include "SOSRegressionUtilities.h"
+#include <utilities/SecCFWrappers.h>
+#include <Security/SecKeyPriv.h>
+
+#include <securityd/SOSCloudCircleServer.h>
+
+#include "SOSAccountTesting.h"
+
+
+static int kTestTestCount = 9;
+
+static void tests(void)
+{
+    CFErrorRef error = NULL;
+    CFDataRef cfpassword = CFDataCreate(NULL, (uint8_t *) "FooFooFoo", 10);
+    CFDataRef cfwrong_password = CFDataCreate(NULL, (uint8_t *) "NotFooFooFoo", 10);
+    CFStringRef cfaccount = CFSTR("test@test.org");
+    CFStringRef data_name = CFSTR("TestSource");
+    CFStringRef circle_key_name = SOSCircleKeyCreateWithName(data_name, NULL);
+
+    CFMutableDictionaryRef changes = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
+
+    SOSAccountRef alice_account = CreateAccountForLocalChanges(changes, CFSTR("Alice"), data_name);
+    SOSAccountRef bob_account = CreateAccountForLocalChanges(changes, CFSTR("Bob"), data_name);
+    SOSAccountRef carol_account = CreateAccountForLocalChanges(changes, CFSTR("Carol"), data_name);
+
+    ok(SOSAccountAssertUserCredentials(bob_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
+
+    // Bob wins writing at this point, feed the changes back to alice.
+
+    FeedChangesToMulti(changes, alice_account, carol_account, NULL);
+
+    ok(SOSAccountAssertUserCredentials(alice_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
+    CFReleaseNull(error);
+    ok(SOSAccountTryUserCredentials(alice_account, cfaccount, cfpassword, &error), "Credential trying (%@)", error);
+    CFReleaseNull(error);
+    CFReleaseNull(cfpassword);
+    
+    ok(!SOSAccountTryUserCredentials(alice_account, cfaccount, cfwrong_password, &error), "Credential failing (%@)", error);
+    CFReleaseNull(cfwrong_password);
+    is(error ? CFErrorGetCode(error) : 0, kSOSErrorWrongPassword, "Expected SOSErrorWrongPassword");
+    CFReleaseNull(error);
+    
+    CFDataRef incompatibleDER = SOSCircleCreateIncompatibleCircleDER(&error);
+    
+    CFDictionarySetValue(changes, circle_key_name, incompatibleDER);
+    
+    FeedChangesTo(changes, alice_account);
+    CFReleaseNull(incompatibleDER);
+    CFReleaseNull(circle_key_name);
+    is(SOSAccountIsInCircles(alice_account, &error), kSOSCCError, "Is in circle");
+    CFReleaseNull(error);
+
+#if 0
+    ok(SOSAccountResetToOffering(alice_account, &error), "Reset to offering (%@)", error);
+    CFReleaseNull(error);
+
+    FeedChangesTo(changes, bob_account);
+
+    ok(SOSAccountJoinCircles(bob_account, &error), "Bob Applies (%@)", error);
+    CFReleaseNull(error);
+
+    FeedChangesTo(changes, alice_account);
+
+    {
+        CFArrayRef applicants = SOSAccountCopyApplicants(alice_account, &error);
+
+        ok(applicants && CFArrayGetCount(applicants) == 1, "See one applicant %@ (%@)", applicants, error);
+        ok(SOSAccountAcceptApplicants(alice_account, applicants, &error), "Alice accepts (%@)", error);
+        CFReleaseNull(error);
+        CFReleaseNull(applicants);
+    }
+
+
+    FeedChangesTo(changes, bob_account); // Bob sees he's accepted
+
+    FeedChangesTo(changes, alice_account); // Alice sees bob-concurring
+
+    ok(CFDictionaryGetCount(changes) == 0, "We converged. (%@)", changes);
+
+    accounts_agree("bob&alice pair", bob_account, alice_account);
+
+    CFArrayRef peers = SOSAccountCopyPeers(alice_account, &error);
+    ok(peers && CFArrayGetCount(peers) == 2, "See two peers %@ (%@)", peers, error);
+    CFReleaseNull(peers);
+
+    CFDictionaryRef alice_new_gestalt = SOSCreatePeerGestaltFromName(CFSTR("Alice, but different"));
+
+    ok(SOSAccountUpdateGestalt(alice_account, alice_new_gestalt), "Update gestalt %@ (%@)", alice_account, error);
+    CFReleaseNull(alice_new_gestalt);
+
+    FeedChangesTo(changes, bob_account); // Bob sees alice change her name.
+
+    FeedChangesTo(changes, alice_account); // Alice sees the fallout.
+
+    accounts_agree("Alice's name changed", bob_account, alice_account);
+
+    ok(SOSAccountLeaveCircles(alice_account, &error), "Alice Leaves (%@)", error);
+    CFReleaseNull(error);
+
+    FeedChangesTo(changes, bob_account); // Bob sees alice bail.
+
+    FeedChangesTo(changes, alice_account); // Alice sees the fallout.
+
+    accounts_agree("Alice bails", bob_account, alice_account);
+
+    peers = SOSAccountCopyPeers(alice_account, &error);
+    ok(peers && CFArrayGetCount(peers) == 1, "See one peer %@ (%@)", peers, error);
+    CFReleaseNull(peers);
+
+    ok(SOSAccountJoinCircles(alice_account, &error), "Alice re-applies (%@)", error);
+    CFReleaseNull(error);
+
+    FeedChangesTo(changes, bob_account);
+
+
+    {
+        CFArrayRef applicants = SOSAccountCopyApplicants(alice_account, &error);
+
+        ok(applicants && CFArrayGetCount(applicants) == 1, "See one applicant %@ (%@)", applicants, error);
+        ok(SOSAccountAcceptApplicants(bob_account, applicants, &error), "Bob accepts (%@)", error);
+        CFReleaseNull(error);
+        CFReleaseNull(applicants);
+    }
+
+    FeedChangesTo(changes, alice_account); // Alice sees bob accepting
+
+    FeedChangesTo(changes, bob_account); // Bob sees Alice concurring
+
+    accounts_agree("Alice accepts' Bob", bob_account, alice_account);
+
+    ok(SOSAccountLeaveCircles(alice_account, &error), "Alice Leaves (%@)", error);
+    CFReleaseNull(error);
+    ok(SOSAccountJoinCircles(alice_account, &error), "Alice re-applies (%@)", error);
+    CFReleaseNull(error);
+
+    FeedChangesTo(changes, bob_account); // Bob sees Alice leaving and rejoining
+    FeedChangesTo(changes, alice_account); // Alice sees bob concurring
+
+    {
+        CFArrayRef applicants = SOSAccountCopyApplicants(alice_account, &error);
+
+        ok(applicants && CFArrayGetCount(applicants) == 1, "See one applicant %@ (%@)", applicants, error);
+        ok(SOSAccountAcceptApplicants(bob_account, applicants, &error), "Bob accepts (%@)", error);
+        CFReleaseNull(error);
+        CFReleaseNull(applicants);
+    }
+
+    FeedChangesTo(changes, alice_account); // Alice sees bob accepting
+
+    FeedChangesTo(changes, bob_account); // Bob sees Alice concurring
+
+    accounts_agree("Bob accepts Alice", bob_account, alice_account);
+
+
+    CFReleaseNull(alice_new_gestalt);
+#endif
+
+    CFReleaseNull(bob_account);
+    CFReleaseNull(alice_account);
+    CFReleaseNull(carol_account);
+}
+
+int secd_55_account_incompatibility(int argc, char *const *argv)
+{
+    plan_tests(kTestTestCount);
+
+    tests();
+
+       return 0;
+}
diff --git a/sec/securityd/Regressions/secd-56-account-apply.c b/sec/securityd/Regressions/secd-56-account-apply.c
new file mode 100644 (file)
index 0000000..6bc9f4b
--- /dev/null
@@ -0,0 +1,223 @@
+//
+//  sc-60-account-cloud-identity.c
+//  sec
+//
+//  Created by Mitch Adler on 6/25/13.
+//
+//
+
+
+
+#include <Security/SecBase.h>
+#include <Security/SecItem.h>
+
+#include <CoreFoundation/CFDictionary.h>
+
+#include <SecureObjectSync/SOSAccount.h>
+#include <SecureObjectSync/SOSCloudCircle.h>
+#include <SecureObjectSync/SOSInternal.h>
+#include <SecureObjectSync/SOSUserKeygen.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "secd_regressions.h"
+#include "SOSTestDataSource.h"
+
+#include "SOSRegressionUtilities.h"
+#include <utilities/SecCFWrappers.h>
+#include <Security/SecKeyPriv.h>
+
+#include <securityd/SOSCloudCircleServer.h>
+
+#include "SOSAccountTesting.h"
+
+
+static int kTestTestCount = 97;
+
+#if 0
+static int countPeers(SOSAccountRef account, bool active) {
+    CFErrorRef error = NULL;
+    CFArrayRef peers;
+    
+    if(active) peers = SOSAccountCopyActivePeers(account, &error);
+    else peers = SOSAccountCopyPeers(account, &error);
+    int retval = (int) CFArrayGetCount(peers);
+    CFReleaseNull(error);
+    CFReleaseNull(peers);
+    return retval;
+}
+#endif
+
+static void tests(void)
+{
+    CFErrorRef error = NULL;
+    CFDataRef cfpassword = CFDataCreate(NULL, (uint8_t *) "FooFooFoo", 10);
+    CFStringRef cfaccount = CFSTR("test@test.org");
+
+    CFMutableDictionaryRef changes = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
+
+    SOSAccountRef alice_account = CreateAccountForLocalChanges(changes, CFSTR("Alice"), CFSTR("TestSource"));
+    SOSAccountRef bob_account = CreateAccountForLocalChanges(changes, CFSTR("Bob"), CFSTR("TestSource"));
+    SOSAccountRef carole_account = CreateAccountForLocalChanges(changes, CFSTR("Carole"), CFSTR("TestSource"));
+    SOSAccountRef david_account = CreateAccountForLocalChanges(changes, CFSTR("David"), CFSTR("TestSource"));
+
+    ok(SOSAccountAssertUserCredentials(bob_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
+
+    // Bob wins writing at this point, feed the changes back to alice.
+
+    FeedChangesToMulti(changes, alice_account, carole_account, david_account, NULL);
+
+    ok(SOSAccountAssertUserCredentials(alice_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
+    CFReleaseNull(error);
+    
+    ok(SOSAccountAssertUserCredentials(carole_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
+    CFReleaseNull(error);
+    
+    ok(SOSAccountAssertUserCredentials(david_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
+    CFReleaseNull(cfpassword);
+    CFReleaseNull(error);
+    
+    ok(SOSAccountResetToOffering(alice_account, &error), "Reset to offering (%@)", error);
+    CFReleaseNull(error);
+
+    // Lost Application Scenario
+    FeedChangesToMulti(changes, bob_account, carole_account, NULL);
+
+    ok(SOSAccountJoinCircles(bob_account, &error), "Bob Applies (%@)", error);
+    CFReleaseNull(error);
+
+    ok(SOSAccountJoinCircles(carole_account, &error), "Carole Applies too (%@)", error);
+    CFReleaseNull(error);
+    
+    FeedChangesToMulti(changes, alice_account, bob_account, NULL);
+    FeedChangesToMulti(changes, alice_account, bob_account, carole_account, NULL);
+
+    accounts_agree("alice and carole agree", alice_account, carole_account);
+    accounts_agree("alice and bob agree", alice_account, bob_account);
+    
+    {
+        CFArrayRef applicants = SOSAccountCopyApplicants(alice_account, &error);
+
+        ok(applicants && CFArrayGetCount(applicants) == 2, "See two applicants %@ (%@)", applicants, error);
+        CFReleaseNull(error);
+        CFReleaseSafe(applicants);
+    }
+
+    FeedChangesToMulti(changes, bob_account, carole_account, NULL);
+    FeedChangesToMulti(changes, bob_account, alice_account, carole_account, NULL);
+    accounts_agree("alice and carole agree", alice_account, carole_account);
+    ok(CFDictionaryGetCount(changes) == 0, "Nothing left to deal with (%@)", changes);
+    CFReleaseNull(error);
+    
+    {
+        CFArrayRef applicants = SOSAccountCopyApplicants(alice_account, &error);
+        ok(applicants && CFArrayGetCount(applicants) == 2, "See two applicants %@ (%@)", applicants, error);
+        ok(SOSAccountRejectApplicants(alice_account, applicants, &error), "Everyone out the pool");
+        CFReleaseNull(error);
+        CFReleaseSafe(applicants);
+    }
+    
+    FeedChangesToMulti(changes, bob_account, carole_account, NULL);
+    FeedChangesToMulti(changes, bob_account, alice_account, carole_account, NULL);
+    accounts_agree("alice and carole agree", alice_account, carole_account);
+    ok(CFDictionaryGetCount(changes) == 0, "Nothing left to deal with (%@)", changes);
+
+    {
+        CFArrayRef applicants = SOSAccountCopyApplicants(alice_account, &error);
+        ok(applicants && CFArrayGetCount(applicants) == 0, "See no applicants %@ (%@)", applicants, error);
+        CFReleaseNull(error);
+        CFReleaseSafe(applicants);
+    }
+
+    ok(SOSAccountJoinCircles(bob_account, &error), "Bob asks again");
+    CFReleaseNull(error);
+    FeedChangesToMulti(changes, bob_account, alice_account, carole_account, NULL);
+    ok(CFDictionaryGetCount(changes) == 0, "Nothing left to deal with (%@)", changes);
+    
+    {
+        CFArrayRef applicants = SOSAccountCopyApplicants(alice_account, &error);
+        ok(applicants && CFArrayGetCount(applicants) == 1, "See one applicants %@ (%@)", applicants, error);
+        CFReleaseNull(error);
+        ok(SOSAccountAcceptApplicants(alice_account, applicants, &error), "Accept bob into the fold");
+        CFReleaseNull(error);
+        CFReleaseSafe(applicants);
+    }
+    
+    FeedChangesTo(changes, bob_account);    // Countersign
+    FeedChangesToMulti(changes, alice_account, bob_account, carole_account, NULL); // Everyone sees the fallout.
+    ok(CFDictionaryGetCount(changes) == 0, "Nothing left to deal with (%@)", changes);
+
+#if 0
+    
+    {
+        CFArrayRef applicants = SOSAccountCopyApplicants(alice_account, &error);
+        
+        ok(applicants && CFArrayGetCount(applicants) == 1, "Bob automatically re-applied %@ (%@)", applicants, error);
+        ok(SOSAccountAcceptApplicants(alice_account, applicants, &error), "Alice accepts (%@)", error);
+        CFReleaseNull(error);
+        CFReleaseNull(applicants);
+    }
+    
+    is(countPeers(alice_account, 0), 3, "Bob is accepted after auto-reapply");
+    FeedChangesToMulti(changes, bob_account, carole_account, david_account, NULL);
+    FeedChangesToMulti(changes, alice_account, bob_account, carole_account, david_account, NULL);
+    FeedChangesToMulti(changes, alice_account, bob_account, carole_account, david_account, NULL);
+    accounts_agree("alice and carole agree after bob gets in", alice_account, carole_account);
+    
+    // Rejected Application Scenario
+    ok(SOSAccountJoinCircles(david_account, &error), "Dave Applies (%@)", error);
+    CFReleaseNull(error);
+    
+    FeedChangesTo(changes, alice_account);
+    SOSAccountPurgePrivateCredential(alice_account);
+    
+    {
+        CFArrayRef applicants = SOSAccountCopyApplicants(alice_account, &error);
+        
+        ok(applicants && CFArrayGetCount(applicants) == 1, "See one applicant %@ (%@)", applicants, error);
+        ok(SOSAccountRejectApplicants(alice_account, applicants, &error), "Alice rejects (%@)", error);
+        CFReleaseNull(error);
+        CFReleaseNull(applicants);
+    }
+    FeedChangesToMulti(changes, alice_account, bob_account, carole_account, david_account, NULL);
+    FeedChangesToMulti(changes, alice_account, bob_account, carole_account, david_account, NULL);
+    FeedChangesToMulti(changes, alice_account, bob_account, carole_account, david_account, NULL);
+    accounts_agree("alice and carole still agree after david is rejected", alice_account, carole_account);
+    ok(SOSAccountTryUserCredentials(alice_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
+    CFReleaseNull(error);
+
+
+    
+
+    FeedChangesToMulti(changes, alice_account, carole_account, NULL); // Everyone sees conurring circle
+
+    ok(CFDictionaryGetCount(changes) == 0, "We converged. (%@)", changes);
+
+    accounts_agree("bob&alice pair", bob_account, alice_account);
+    
+    ok(SOSAccountJoinCirclesAfterRestore(carole_account, &error), "Carole cloud identiy joins (%@)", error);
+    CFReleaseNull(error);
+    
+    is(countPeers(carole_account, false), 3, "Carole sees 3 valid peers after sliding in");
+
+    FeedChangesTo(changes, bob_account);
+    FeedChangesTo(changes, alice_account);
+    FeedChangesToMulti(changes, bob_account, carole_account, NULL); // Bob and carole see the final result.
+
+    accounts_agree_internal("Carole's in", bob_account, alice_account, false);
+    accounts_agree_internal("Carole's in - 2", bob_account, carole_account, false);
+#endif
+    CFReleaseNull(bob_account);
+    CFReleaseNull(alice_account);
+    CFReleaseNull(carole_account);
+}
+
+int secd_56_account_apply(int argc, char *const *argv)
+{
+    plan_tests(kTestTestCount);
+
+    tests();
+
+       return 0;
+}
diff --git a/sec/securityd/Regressions/secd-57-account-leave.c b/sec/securityd/Regressions/secd-57-account-leave.c
new file mode 100644 (file)
index 0000000..747dac2
--- /dev/null
@@ -0,0 +1,238 @@
+//
+//  sc-57-account-leave.c
+//  sec
+//
+//  Created by Mitch Adler on 6/18/13.
+//
+//
+
+
+
+#include <Security/SecBase.h>
+#include <Security/SecItem.h>
+
+#include <CoreFoundation/CFDictionary.h>
+
+#include <SecureObjectSync/SOSAccount.h>
+#include <SecureObjectSync/SOSCloudCircle.h>
+#include <SecureObjectSync/SOSInternal.h>
+#include <SecureObjectSync/SOSUserKeygen.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "secd_regressions.h"
+#include "SOSTestDataSource.h"
+
+#include "SOSRegressionUtilities.h"
+#include <utilities/SecCFWrappers.h>
+#include <Security/SecKeyPriv.h>
+
+#include <securityd/SOSCloudCircleServer.h>
+
+#include "SOSAccountTesting.h"
+
+
+static int kTestTestCount = 158;
+
+/*
+static void trim_retirements_from_circle(SOSAccountRef account) {
+    SOSAccountForEachCircle(account, ^(SOSCircleRef circle) {
+        SOSCircleRemoveRetired(circle, NULL);
+    });
+}
+ */
+
+
+static void tests(void)
+{
+    CFErrorRef error = NULL;
+    CFDataRef cfpassword = CFDataCreate(NULL, (uint8_t *) "FooFooFoo", 10);
+    CFStringRef cfaccount = CFSTR("test@test.org");
+
+    CFMutableDictionaryRef changes = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
+
+    SOSAccountRef alice_account = CreateAccountForLocalChanges(changes, CFSTR("Alice"), CFSTR("TestSource"));
+    SOSAccountRef bob_account = CreateAccountForLocalChanges(changes, CFSTR("Bob"), CFSTR("TestSource"));
+    SOSAccountRef carole_account = CreateAccountForLocalChanges(changes, CFSTR("Carole"), CFSTR("TestSource"));
+    SOSAccountRef david_account = CreateAccountForLocalChanges(changes, CFSTR("David"), CFSTR("TestSource"));
+
+    ok(SOSAccountAssertUserCredentials(bob_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
+
+    // Bob wins writing at this point, feed the changes back to alice.
+
+    FeedChangesToMulti(changes, alice_account, carole_account, david_account, NULL);
+
+    ok(SOSAccountAssertUserCredentials(alice_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
+    CFReleaseNull(error);
+    
+    ok(SOSAccountAssertUserCredentials(carole_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
+    CFReleaseNull(error);
+    
+    ok(SOSAccountResetToOffering(alice_account, &error), "Reset to offering (%@)", error);
+    CFReleaseNull(error);
+
+    FeedChangesTo(changes, bob_account);
+
+    ok(SOSAccountJoinCircles(bob_account, &error), "Bob Applies (%@)", error);
+    CFReleaseNull(error);
+
+    FeedChangesTo(changes, alice_account);
+
+    {
+        CFArrayRef applicants = SOSAccountCopyApplicants(alice_account, &error);
+
+        ok(applicants && CFArrayGetCount(applicants) == 1, "See one applicant %@ (%@)", applicants, error);
+        ok(SOSAccountAcceptApplicants(alice_account, applicants, &error), "Alice accepts (%@)", error);
+        CFReleaseNull(error);
+        CFReleaseNull(applicants);
+    }
+
+
+    FeedChangesTo(changes, bob_account); // Bob sees he's accepted
+
+    FeedChangesTo(changes, alice_account); // Alice sees bob-concurring
+
+    ok(CFDictionaryGetCount(changes) == 0, "We converged. (%@)", changes);
+
+    accounts_agree("bob&alice pair", bob_account, alice_account);
+    is(SOSAccountGetLastDepartureReason(bob_account, &error), kSOSNeverLeftCircle, "Bob affirms he hasn't left.");
+
+    CFArrayRef peers = SOSAccountCopyPeers(alice_account, &error);
+    ok(peers && CFArrayGetCount(peers) == 2, "See two peers %@ (%@)", peers, error);
+    CFReleaseNull(peers);
+
+    SOSAccountPurgePrivateCredential(alice_account);
+
+    ok(SOSAccountLeaveCircles(alice_account, &error), "Alice Leaves (%@)", error);
+    CFReleaseNull(error);
+
+    FeedChangesTo(changes, bob_account); // Bob sees alice bail.
+
+    FeedChangesTo(changes, alice_account); // Alice sees the fallout.
+
+    accounts_agree("Alice bails", bob_account, alice_account);
+
+    {
+        CFArrayRef concurring = SOSAccountCopyConcurringPeers(alice_account, &error);
+        
+        ok(concurring && CFArrayGetCount(concurring) == 2, "See two concurring %@ (%@)", concurring, error);
+        CFReleaseNull(error);
+        CFReleaseNull(concurring);
+    }
+    
+    ok(SOSAccountTryUserCredentials(alice_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
+    CFReleaseNull(error);
+
+    ok(SOSAccountJoinCircles(alice_account, &error), "Alice re-applies (%@)", error);
+    CFReleaseNull(error);
+    
+    FeedChangesTo(changes, bob_account); // Bob sees alice request.
+    
+    is(countActivePeers(bob_account), 3, "Bob sees 2 active peers");
+    is(countPeers(bob_account), 1, "Bob sees 1 valid peer");
+
+    {
+        CFArrayRef applicants = SOSAccountCopyApplicants(bob_account, &error);
+        
+        ok(applicants && CFArrayGetCount(applicants) == 1, "See alice's reapp. %@ (%@)", applicants, error);
+        ok(SOSAccountAcceptApplicants(bob_account, applicants, &error), "Bob accepts (%@)", error);
+        CFReleaseNull(error);
+        CFReleaseNull(applicants);
+    }
+    
+
+    is(countActivePeers(bob_account), 3, "Bob sees 3 active peers");
+    is(countPeers(bob_account), 2, "Bob sees 2 valid peers");
+    
+    is(countActivePeers(alice_account), 3, "Alice sees 2 active peers");
+    is(countPeers(alice_account), 1, "Alice sees 1 valid peers");
+
+    FeedChangesToMulti(changes, alice_account, carole_account, NULL); // Alice sees bob accepts.
+    
+    FeedChangesToMulti(changes, bob_account, carole_account, NULL); // Bob sees Alice concurr.
+    
+    accounts_agree("Alice rejoined", bob_account, alice_account);
+    accounts_agree_internal("Alice rejoined, carole noticed", bob_account, carole_account, false);
+    
+    ok(SOSAccountJoinCircles(carole_account, &error), "Carole applies (%@)", error);
+    CFReleaseNull(error);
+    
+    FeedChangesToMulti(changes, bob_account, alice_account, NULL); // Bob and carole see the final result.
+
+    accounts_agree_internal("Carole applied", bob_account, alice_account, false);
+    accounts_agree_internal("Carole applied - 2", bob_account, carole_account, false);
+    
+    {
+        CFArrayRef applicants = SOSAccountCopyApplicants(bob_account, &error);
+        
+        ok(applicants && CFArrayGetCount(applicants) == 1, "See Carole's eapp. %@ (%@)", applicants, error);
+        ok(SOSAccountAcceptApplicants(bob_account, applicants, &error), "Bob accepts carole (%@)", error);
+        CFReleaseNull(error);
+        CFReleaseNull(applicants);
+    }
+    
+    FeedChangesToMulti(changes, alice_account, NULL); // Alice sees the change and countersigns
+    FeedChangesToMulti(changes, carole_account, NULL); // Carole countersigns her acceptance.
+    FeedChangesToMulti(changes, bob_account, alice_account, david_account, NULL); // Bob and Alice see carole's counter signature.
+    // david ends up with a 3 peerinfo member circle.
+
+    accounts_agree_internal("Carole joined", bob_account, alice_account, false);
+    accounts_agree_internal("Carole joined - 2", bob_account, carole_account, false);
+    
+    // Now test lost circle change when two leave simultaneously, needing us to see the retirement tickets
+    
+    ok(SOSAccountLeaveCircles(alice_account, &error), "Alice Leaves (%@)", error);
+    CFReleaseNull(error);
+    
+    ok(SOSAccountLeaveCircles(carole_account, &error), "carole Leaves (%@)", error);
+    CFReleaseNull(error);
+
+    FeedChangesToMulti(changes, bob_account, NULL); // Bob sees both retirements and a circle missing one
+    
+    is(countPeers(bob_account), 1, "Bob sees 1 valid peer");
+    is(countActivePeers(bob_account), 4, "Bob sees 4 active peers");
+    FeedChangesToMulti(changes, carole_account, alice_account, david_account, NULL);
+
+    is(SOSAccountGetLastDepartureReason(carole_account, &error), kSOSWithdrewMembership, "Carole affirms she left on her own.");
+
+    ok(SOSAccountAssertUserCredentials(david_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
+    CFReleaseNull(error);
+    CFReleaseNull(cfpassword);
+    is(countPeers(david_account), 1, "david sees 1 peers");
+    is(countActivePeers(david_account), 4, "david sees 4 active peers");
+    
+    ok(SOSAccountJoinCircles(david_account, &error), "David applies (%@)", error);
+    CFReleaseNull(error);
+    is(countPeers(david_account), 1, "david sees 1 peers");
+    is(countActivePeers(david_account), 4, "david sees 4 active peers");
+
+    FeedChangesToMulti(changes, carole_account, alice_account, bob_account, NULL);
+
+    {
+        CFArrayRef applicants = SOSAccountCopyApplicants(bob_account, &error);
+        
+        ok(applicants && CFArrayGetCount(applicants) == 1, "See David's app. %@ (%@)", applicants, error);
+        ok(SOSAccountAcceptApplicants(bob_account, applicants, &error), "Bob accepts carole (%@)", error);
+        CFReleaseNull(error);
+        CFReleaseNull(applicants);
+    }
+   
+    FeedChangesToMulti(changes, carole_account, alice_account, david_account, NULL);
+
+    is(countPeers(bob_account), 2, "Bob sees 2 valid peer");
+    is(countActivePeers(bob_account), 3, "Bob sees 3 active peers");
+
+    CFReleaseNull(bob_account);
+    CFReleaseNull(alice_account);
+}
+
+int secd_57_account_leave(int argc, char *const *argv)
+{
+    plan_tests(kTestTestCount);
+
+    tests();
+
+       return 0;
+}
diff --git a/sec/securityd/Regressions/secd-58-password-change.c b/sec/securityd/Regressions/secd-58-password-change.c
new file mode 100644 (file)
index 0000000..4f1e85f
--- /dev/null
@@ -0,0 +1,198 @@
+//
+//  secd-58-password-change.c
+//  sec
+//
+//  Created by Mitch Adler on 6/18/13.
+//
+//
+
+
+
+#include <Security/SecBase.h>
+#include <Security/SecItem.h>
+
+#include <CoreFoundation/CFDictionary.h>
+
+#include <SecureObjectSync/SOSAccount.h>
+#include <SecureObjectSync/SOSCloudCircle.h>
+#include <SecureObjectSync/SOSInternal.h>
+#include <SecureObjectSync/SOSUserKeygen.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "secd_regressions.h"
+#include "SOSTestDataSource.h"
+
+#include "SOSRegressionUtilities.h"
+#include <utilities/SecCFWrappers.h>
+#include <Security/SecKeyPriv.h>
+
+#include <securityd/SOSCloudCircleServer.h>
+
+#include "SOSAccountTesting.h"
+
+
+static int kTestTestCount = 300;
+
+static bool AssertCreds(SOSAccountRef account, CFStringRef acct_name, CFDataRef password) {
+    CFErrorRef error = NULL;
+    bool retval;
+    ok((retval = SOSAccountAssertUserCredentials(account, acct_name, password, &error)), "Credential setting (%@)", error);
+    CFReleaseNull(error);
+    return retval;
+}
+
+static bool ResetToOffering(SOSAccountRef account) {
+    CFErrorRef error = NULL;
+    bool retval;
+    ok((retval = SOSAccountResetToOffering(account, &error)), "Reset to offering (%@)", error);
+    CFReleaseNull(error);
+    return retval;
+}
+
+static bool JoinCircle(SOSAccountRef account) {
+    CFErrorRef error = NULL;
+    bool retval;
+    ok((retval = SOSAccountJoinCircles(account, &error)), "Join Circle (%@)", error);
+    CFReleaseNull(error);
+    return retval;
+}
+
+static bool AcceptApplicants(SOSAccountRef account, CFIndex cnt) {
+    CFErrorRef error = NULL;
+    bool retval = false;
+    CFArrayRef applicants = SOSAccountCopyApplicants(account, &error);
+        
+    ok((retval = (applicants && CFArrayGetCount(applicants) == cnt)), "See applicants %@ (%@)", applicants, error);
+    if(retval) ok((retval = SOSAccountAcceptApplicants(account, applicants, &error)), "Accept Applicants (%@)", error);
+    CFReleaseNull(applicants);
+    CFReleaseNull(error);
+    return retval;
+}
+
+
+static void tests(void)
+{
+    CFDataRef cfpassword = CFDataCreate(NULL, (uint8_t *) "FooFooFoo", 10);
+    CFStringRef cfaccount = CFSTR("test@test.org");
+    
+    CFMutableDictionaryRef changes = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
+    
+    SOSAccountRef alice_account = CreateAccountForLocalChanges(changes, CFSTR("Alice"), CFSTR("TestSource"));
+    SOSAccountRef bob_account = CreateAccountForLocalChanges(changes, CFSTR("Bob"), CFSTR("TestSource"));
+    SOSAccountRef carol_account = CreateAccountForLocalChanges(changes, CFSTR("Carol"), CFSTR("TestSource"));
+    
+    /* Set Initial Credentials and Parameters for the Syncing Circles ---------------------------------------*/
+    ok(AssertCreds(bob_account, cfaccount, cfpassword), "Setting credentials for Bob");
+    // Bob wins writing at this point, feed the changes back to alice.
+    FeedChangesToMulti(changes, alice_account, carol_account, NULL);
+    ok(AssertCreds(alice_account, cfaccount, cfpassword), "Setting credentials for Alice");
+    ok(AssertCreds(carol_account, cfaccount, cfpassword), "Setting credentials for Carol");
+    CFReleaseNull(cfpassword);
+    
+    /* Make Alice First Peer -------------------------------------------------------------------------------*/
+    ok(ResetToOffering(alice_account), "Reset to offering - Alice as first peer");
+    FeedChangesToMulti(changes, bob_account, carol_account, NULL);
+
+    /* Bob Joins -------------------------------------------------------------------------------------------*/
+    ok(JoinCircle(bob_account), "Bob Applies");
+    FeedChangesToMulti(changes, alice_account, carol_account, NULL);
+
+    /* Alice Accepts -------------------------------------------------------------------------------------------*/
+    ok(AcceptApplicants(alice_account, 1), "Alice Accepts Bob's Application");
+    FeedChangesToMulti(changes, bob_account, carol_account, NULL); // Bob sees he's accepted
+    FeedChangesToMulti(changes, alice_account, carol_account, NULL); // Alice sees bob-concurring
+    ok(CFDictionaryGetCount(changes) == 0, "We converged. (%@)", changes);
+    accounts_agree("bob&alice pair", bob_account, alice_account);
+    
+    /* Carol Applies -------------------------------------------------------------------------------------------*/
+    ok(JoinCircle(carol_account), "Carol Applies");
+    FeedChangesToMulti(changes, alice_account, bob_account, NULL);
+    
+    is(countPeers(alice_account), 2, "See two peers");
+    
+    
+    /* Change Password ------------------------------------------------------------------------------------------*/
+    CFDataRef cfnewpassword = CFDataCreate(NULL, (uint8_t *) "ooFooFooF", 10);
+    
+    ok(AssertCreds(bob_account, cfaccount, cfnewpassword), "Credential resetting for Bob");
+    is(countPeers(bob_account), 2, "There are two valid peers - iCloud and Bob");
+    is(countActivePeers(bob_account), 3, "There are three active peers - bob, alice, and iCloud");
+    is(countActiveValidPeers(bob_account), 2, "There is two active valid peer - Bob and iCloud");
+    FeedChangesToMulti(changes, alice_account, carol_account, NULL);
+
+    ok(AssertCreds(alice_account, cfaccount, cfnewpassword), "Credential resetting for Alice");
+    is(countPeers(alice_account), 2, "There are two peers - bob and alice");
+    is(countActiveValidPeers(alice_account), 3, "There are three active valid peers - alice, bob, and icloud");
+    FeedChangesToMulti(changes, bob_account, carol_account, NULL);
+    FeedChangesToMulti(changes, alice_account, carol_account, NULL);
+    FeedChangesToMulti(changes, alice_account, bob_account, NULL);
+    accounts_agree("bob&alice pair", bob_account, alice_account);
+    is(countPeers(alice_account), 2, "There are two peers - bob and alice");
+    is(countActiveValidPeers(alice_account), 3, "There are three active valid peers - alice, bob, and icloud");
+    
+    ok(AssertCreds(carol_account, cfaccount, cfnewpassword), "Credential resetting for Carol");
+    FeedChangesToMulti(changes, alice_account, bob_account, NULL);
+    FeedChangesToMulti(changes, bob_account, carol_account, alice_account, NULL);
+    FeedChangesToMulti(changes, bob_account, carol_account, alice_account, NULL);
+    FeedChangesToMulti(changes, bob_account, carol_account, alice_account, NULL);
+    accounts_agree("bob&alice pair", bob_account, alice_account);
+
+    ok(AcceptApplicants(alice_account, 1), "Alice Accepts Carol's Application");
+    FeedChangesToMulti(changes, bob_account, carol_account, NULL); // Carol sees she's accepted
+    FeedChangesToMulti(changes, alice_account, bob_account, carol_account, NULL); // Alice sees bob-concurring
+    FeedChangesToMulti(changes, alice_account, bob_account, carol_account, NULL); // Alice sees bob-concurring
+    FeedChangesToMulti(changes, alice_account, bob_account, carol_account, NULL); // Alice sees bob-concurring
+    accounts_agree_internal("bob&alice pair", bob_account, alice_account, false);
+    accounts_agree_internal("bob&carol pair", bob_account, carol_account, false);
+    accounts_agree_internal("carol&alice pair", alice_account, carol_account, false);
+    
+    
+    /* Change Password 2 ----------------------------------------------------------------------------------------*/
+    CFReleaseNull(cfnewpassword);
+    cfnewpassword = CFDataCreate(NULL, (uint8_t *) "ffoffoffo", 10);
+    
+    /* Bob */
+    ok(AssertCreds(bob_account, cfaccount, cfnewpassword), "Credential resetting for Bob");
+    is(countPeers(bob_account), 3, "There are three peers - Alice, Carol, Bob");
+    is(countActivePeers(bob_account), 4, "There are four active peers - bob, alice, carol and iCloud");
+    is(countActiveValidPeers(bob_account), 2, "There is two active valid peer - Bob and iCloud");
+    FeedChangesToMulti(changes, alice_account, carol_account, NULL);
+
+    /* Alice */
+    ok(AssertCreds(alice_account, cfaccount, cfnewpassword), "Credential resetting for Alice");
+    is(countPeers(alice_account), 3, "There are three peers - Alice, Carol, Bob");
+    is(countActivePeers(alice_account), 4, "There are four active peers - bob, alice, carol and iCloud");
+    is(countActiveValidPeers(alice_account), 3, "There are three active valid peers - alice, bob, and icloud");
+    FeedChangesToMulti(changes, bob_account, carol_account, NULL);
+    FeedChangesToMulti(changes, alice_account, bob_account, carol_account, NULL);
+    FeedChangesToMulti(changes, alice_account, bob_account, carol_account, NULL);
+    
+    /* Carol */
+    ok(AssertCreds(carol_account, cfaccount, cfnewpassword), "Credential resetting for Carol");
+    is(countPeers(carol_account), 3, "There are three peers - Alice, Carol, Bob");
+    is(countActivePeers(carol_account), 4, "There are four active peers - bob, alice, carol and iCloud");
+    is(countActiveValidPeers(carol_account), 4, "There are three active valid peers - alice, bob, carol, and icloud");
+
+    FeedChangesToMulti(changes, alice_account, bob_account, NULL);
+    FeedChangesToMulti(changes, bob_account, carol_account, alice_account, NULL);
+    FeedChangesToMulti(changes, bob_account, carol_account, alice_account, NULL);
+    FeedChangesToMulti(changes, bob_account, carol_account, alice_account, NULL);
+    accounts_agree_internal("bob&alice pair", bob_account, alice_account, false);
+
+    CFReleaseNull(bob_account);
+    CFReleaseNull(alice_account);
+    CFReleaseNull(carol_account);
+    CFReleaseNull(cfnewpassword);
+
+}
+
+int secd_58_password_change(int argc, char *const *argv)
+{
+    plan_tests(kTestTestCount);
+    
+    tests();
+    
+       return 0;
+}
diff --git a/sec/securityd/Regressions/secd-59-account-cleanup.c b/sec/securityd/Regressions/secd-59-account-cleanup.c
new file mode 100644 (file)
index 0000000..2c2337b
--- /dev/null
@@ -0,0 +1,180 @@
+//
+//  secd-59-account-cleanup.c
+//  sec
+//
+//  Created by Mitch Adler on 6/18/13.
+//
+//
+
+
+
+#include <Security/SecBase.h>
+#include <Security/SecItem.h>
+
+#include <CoreFoundation/CFDictionary.h>
+
+#include <SecureObjectSync/SOSAccount.h>
+#include <SecureObjectSync/SOSCloudCircle.h>
+#include <SecureObjectSync/SOSInternal.h>
+#include <SecureObjectSync/SOSUserKeygen.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "secd_regressions.h"
+#include "SOSTestDataSource.h"
+
+#include "SOSRegressionUtilities.h"
+#include <utilities/SecCFWrappers.h>
+#include <Security/SecKeyPriv.h>
+
+#include <securityd/SOSCloudCircleServer.h>
+
+#include "SOSAccountTesting.h"
+
+
+static int kTestTestCount = 93;
+
+static void tests(void)
+{
+    CFErrorRef error = NULL;
+    CFDataRef cfpassword = CFDataCreate(NULL, (uint8_t *) "FooFooFoo", 10);
+    CFStringRef cfaccount = CFSTR("test@test.org");
+    CFStringRef circle_name = CFSTR("TestSource");
+    
+    CFMutableDictionaryRef changes = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
+    
+    SOSAccountRef alice_account = CreateAccountForLocalChanges(changes, CFSTR("Alice"), circle_name);
+    SOSAccountRef bob_account = CreateAccountForLocalChanges(changes, CFSTR("Bob"), circle_name);
+    SOSAccountRef carole_account = CreateAccountForLocalChanges(changes, CFSTR("Carole"), circle_name);
+
+    ok(SOSAccountAssertUserCredentials(bob_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
+    
+    // Bob wins writing at this point, feed the changes back to alice.
+    
+    FeedChangesToMulti(changes, alice_account, carole_account, NULL);
+    
+    ok(SOSAccountAssertUserCredentials(alice_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
+    CFReleaseNull(error);
+    
+    ok(SOSAccountAssertUserCredentials(carole_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
+    CFReleaseNull(error);
+    ok(SOSAccountResetToOffering(alice_account, &error), "Reset to offering (%@)", error);
+    CFReleaseNull(error);
+    
+    FeedChangesTo(changes, bob_account);
+
+    ok(SOSAccountJoinCircles(bob_account, &error), "Bob Applies (%@)", error);
+    CFReleaseNull(error);
+    
+    FeedChangesTo(changes, alice_account);
+    
+    {
+        CFArrayRef applicants = SOSAccountCopyApplicants(alice_account, &error);
+        
+        ok(applicants && CFArrayGetCount(applicants) == 1, "See one applicant %@ (%@)", applicants, error);
+        ok(SOSAccountAcceptApplicants(alice_account, applicants, &error), "Alice accepts (%@)", error);
+        CFReleaseNull(error);
+        CFReleaseNull(applicants);
+    }
+    
+    
+    FeedChangesTo(changes, bob_account); // Bob sees he's accepted
+    
+    FeedChangesTo(changes, alice_account); // Alice sees bob-concurring
+    
+    ok(CFDictionaryGetCount(changes) == 0, "We converged. (%@)", changes);
+    
+    accounts_agree("bob&alice pair", bob_account, alice_account);
+    
+    CFArrayRef peers = SOSAccountCopyPeers(alice_account, &error);
+    ok(peers && CFArrayGetCount(peers) == 2, "See two peers %@ (%@)", peers, error);
+    CFReleaseNull(peers);
+
+    SOSFullPeerInfoRef fpiAlice = SOSAccountGetMyFullPeerInCircleNamed(alice_account, circle_name, NULL);
+    CFStringRef alice_id = CFStringCreateCopy(NULL, SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(fpiAlice)));
+    
+    ok(SOSAccountLeaveCircles(alice_account, &error), "Alice Leaves (%@)", error);
+    CFReleaseNull(error);
+    CFReleaseNull(cfpassword);
+    
+    FeedChangesTo(changes, bob_account); // Bob sees alice bail.
+    
+    is(CFDictionaryGetCountOfValue(changes, kCFNull),2, "2 Keys Nulled Out");
+
+    CFDictionaryForEach(changes, ^(const void *key, const void *value) {
+        if(isNull(value)) {
+            CFStringRef circle_name = NULL, from_name = NULL, to_name = NULL;
+            SOSKVSKeyType keytype = SOSKVSKeyGetKeyTypeAndParse(key, &circle_name, &from_name, &to_name);
+            is(keytype, kMessageKey, "Expect only a message key");
+            bool testcmp = CFEqualSafe(alice_id, from_name) || CFEqualSafe(alice_id, to_name);
+            ok(testcmp, "Alice is from_name(%@) or to_name(%@)", from_name, to_name);
+            CFReleaseNull(circle_name);
+            CFReleaseNull(from_name);
+            CFReleaseNull(to_name);
+        }
+    });
+
+    FeedChangesToMulti(changes, alice_account, carole_account, NULL);
+
+    accounts_agree("Alice bails", bob_account, alice_account);
+    accounts_agree("Alice bails", bob_account, carole_account);
+    
+    SOSAccountCleanupRetirementTickets(bob_account, 0, &error);
+    is(CFDictionaryGetCountOfValue(changes, kCFNull),0, "0 Keys Nulled Out");
+    
+    ok(SOSAccountJoinCircles(carole_account, &error), "Carole Applies (%@)", error);
+    CFReleaseNull(error);
+    
+    FeedChangesTo(changes, bob_account);
+    
+    {
+        CFArrayRef applicants = SOSAccountCopyApplicants(bob_account, &error);
+        
+        ok(applicants && CFArrayGetCount(applicants) == 1, "See one applicant %@ (%@)", applicants, error);
+        ok(SOSAccountAcceptApplicants(bob_account, applicants, &error), "Bob accepts Carole (%@)", error);
+        CFReleaseNull(error);
+        CFReleaseNull(applicants);
+    }
+
+    // Bob should not yet cleanup Alice's retirment here on his own since it hasn't been long enough
+    // by default.
+    is(CFDictionaryGetCountOfValue(changes, kCFNull),0, "0 Keys Nulled Out");
+
+    FeedChangesTo(changes, carole_account); // Carole sees he's accepted
+    FeedChangesTo(changes, bob_account); // Bob sees she's all happy.
+
+    accounts_agree("Carole joins", bob_account, carole_account);
+
+    SOSAccountCleanupRetirementTickets(bob_account, 0, &error);
+
+    is(countPeers(bob_account), 2, "Active peers after forced cleanup");
+    is(countActivePeers(bob_account), 3, "Inactive peers after forced cleanup");
+
+    is(CFDictionaryGetCountOfValue(changes, kCFNull), 1, "1 Keys Nulled Out");
+    
+    CFDictionaryForEach(changes, ^(const void *key, const void *value) {
+        if(isNull(value)) {
+            CFStringRef circle_name = NULL, retiree = NULL;
+            SOSKVSKeyType keytype = SOSKVSKeyGetKeyTypeAndParse(key, &circle_name, &retiree, NULL);
+            is(keytype, kRetirementKey, "Expect only a retirement key");
+            ok(CFEqualSafe(alice_id, retiree), "Alice (%@) is retiree (%@)", alice_id, retiree);
+            CFReleaseNull(circle_name);
+            CFReleaseNull(retiree);
+        }
+    });
+    
+    CFReleaseNull(alice_id);
+    CFReleaseNull(carole_account);
+    CFReleaseNull(bob_account);
+    CFReleaseNull(alice_account);
+}
+
+int secd_59_account_cleanup(int argc, char *const *argv)
+{
+    plan_tests(kTestTestCount);
+    
+    tests();
+    
+       return 0;
+}
diff --git a/sec/securityd/Regressions/secd-60-account-cloud-identity.c b/sec/securityd/Regressions/secd-60-account-cloud-identity.c
new file mode 100644 (file)
index 0000000..e808eb8
--- /dev/null
@@ -0,0 +1,151 @@
+//
+//  sc-60-account-cloud-identity.c
+//  sec
+//
+//  Created by Mitch Adler on 6/25/13.
+//
+//
+
+
+
+#include <Security/SecBase.h>
+#include <Security/SecItem.h>
+
+#include <CoreFoundation/CFDictionary.h>
+
+#include <SecureObjectSync/SOSAccount.h>
+#include <SecureObjectSync/SOSCloudCircle.h>
+#include <SecureObjectSync/SOSInternal.h>
+#include <SecureObjectSync/SOSUserKeygen.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "secd_regressions.h"
+#include "SOSTestDataSource.h"
+
+#include "SOSRegressionUtilities.h"
+#include <utilities/SecCFWrappers.h>
+#include <Security/SecKeyPriv.h>
+
+#include <securityd/SOSCloudCircleServer.h>
+
+#include "SOSAccountTesting.h"
+
+
+static int kTestTestCount = 95;
+
+
+
+static void tests(void)
+{
+    CFErrorRef error = NULL;
+    CFDataRef cfpassword = CFDataCreate(NULL, (uint8_t *) "FooFooFoo", 10);
+    CFStringRef cfaccount = CFSTR("test@test.org");
+
+    CFMutableDictionaryRef changes = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
+
+    SOSAccountRef alice_account = CreateAccountForLocalChanges(changes, CFSTR("Alice"), CFSTR("TestSource"));
+    SOSAccountRef bob_account = CreateAccountForLocalChanges(changes, CFSTR("Bob"), CFSTR("TestSource"));
+    SOSAccountRef carole_account = CreateAccountForLocalChanges(changes, CFSTR("Carole"), CFSTR("TestSource"));
+
+    ok(SOSAccountAssertUserCredentials(bob_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
+
+    // Bob wins writing at this point, feed the changes back to alice.
+
+    FeedChangesToMulti(changes, alice_account, carole_account, NULL);
+
+    ok(SOSAccountAssertUserCredentials(alice_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
+    CFReleaseNull(error);
+    
+    ok(SOSAccountAssertUserCredentials(carole_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
+    CFReleaseNull(error);
+    CFReleaseNull(cfpassword);
+    ok(SOSAccountResetToOffering(alice_account, &error), "Reset to offering (%@)", error);
+    CFReleaseNull(error);
+
+    FeedChangesToMulti(changes, bob_account, carole_account, NULL);
+
+    ok(SOSAccountJoinCircles(bob_account, &error), "Bob Applies (%@)", error);
+    CFReleaseNull(error);
+
+    FeedChangesTo(changes, alice_account);
+
+    {
+        CFArrayRef applicants = SOSAccountCopyApplicants(alice_account, &error);
+
+        ok(applicants && CFArrayGetCount(applicants) == 1, "See one applicant %@ (%@)", applicants, error);
+        ok(SOSAccountAcceptApplicants(alice_account, applicants, &error), "Alice accepts (%@)", error);
+        CFReleaseNull(error);
+        CFReleaseNull(applicants);
+    }
+
+
+    FeedChangesTo(changes, bob_account); // Bob sees he's accepted
+
+    FeedChangesToMulti(changes, alice_account, carole_account, NULL); // Everyone sees conurring circle
+
+    ok(CFDictionaryGetCount(changes) == 0, "We converged. (%@)", changes);
+
+    accounts_agree("bob&alice pair", bob_account, alice_account);
+    
+    /*----- normal join after restore -----*/
+
+    ok(SOSAccountJoinCirclesAfterRestore(carole_account, &error), "Carole cloud identity joins (%@)", error);
+    CFReleaseNull(error);
+    
+    FeedChangesToMulti(changes, bob_account, carole_account, NULL); // Bob and carole see the final result.
+    FeedChangesToMulti(changes, alice_account, bob_account, carole_account, NULL); // Bob and carole see the final result.
+
+    is(countApplicants(alice_account), 0, "See no applicants");
+    
+    is(countPeers(carole_account), 3, "Carole sees 3 valid peers after sliding in");
+
+    FeedChangesToMulti(changes, bob_account, carole_account, NULL); // Bob and carole see the final result.
+
+    accounts_agree_internal("Carole's in", bob_account, alice_account, false);
+    accounts_agree_internal("Carole's in - 2", bob_account, carole_account, false);
+    
+    ok(SOSAccountLeaveCircles(carole_account, &error), "Carol Leaves again");
+    CFReleaseNull(error);
+    FeedChangesToMulti(changes, bob_account, alice_account, NULL);
+    FeedChangesToMulti(changes, alice_account, bob_account, carole_account, NULL);
+    
+    /*----- join - join after restore -----*/
+    
+    ok(SOSAccountJoinCircles(carole_account, &error), "Carole normally joins (%@)", error);
+    CFReleaseNull(error);
+    FeedChangesTo(changes, alice_account);
+    
+    is(countApplicants(alice_account), 1, "See one applicant");
+    
+    ok(SOSAccountJoinCirclesAfterRestore(carole_account, &error), "Carole cloud identity joins (%@)", error);
+    CFReleaseNull(error);
+    
+    FeedChangesToMulti(changes, bob_account, carole_account, NULL); // Bob and carole see the final result.
+    FeedChangesToMulti(changes, alice_account, bob_account, carole_account, NULL); // Bob and carole see the final result.
+    
+    is(countApplicants(alice_account), 0, "See no applicants");
+    
+    is(countPeers(carole_account), 3, "Carole sees 3 valid peers after sliding in");
+    
+    FeedChangesToMulti(changes, bob_account, carole_account, NULL); // Bob and carole see the final result.
+    
+    accounts_agree_internal("Carole's in", bob_account, alice_account, false);
+    accounts_agree_internal("Carole's in - 2", bob_account, carole_account, false);
+    
+
+    
+    CFReleaseNull(bob_account);
+    CFReleaseNull(alice_account);
+    CFReleaseNull(carole_account);
+}
+
+int secd_60_account_cloud_identity(int argc, char *const *argv)
+{
+    plan_tests(kTestTestCount);
+
+    tests();
+
+       return 0;
+}
diff --git a/sec/securityd/Regressions/secd-61-account-leave-not-in-kansas-anymore.c b/sec/securityd/Regressions/secd-61-account-leave-not-in-kansas-anymore.c
new file mode 100644 (file)
index 0000000..5cbeeb5
--- /dev/null
@@ -0,0 +1,194 @@
+//
+//  secd-61-account-leave-not-in-kansas-anymore.c
+//  sec
+//
+//  Created by Richard Murphy on 7/16/13.
+//
+
+
+#include <Security/SecBase.h>
+#include <Security/SecItem.h>
+
+#include <CoreFoundation/CFDictionary.h>
+
+#include <SecureObjectSync/SOSAccount.h>
+#include <SecureObjectSync/SOSCloudCircle.h>
+#include <SecureObjectSync/SOSInternal.h>
+#include <SecureObjectSync/SOSUserKeygen.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "secd_regressions.h"
+#include "SOSTestDataSource.h"
+
+#include "SOSRegressionUtilities.h"
+#include <utilities/SecCFWrappers.h>
+#include <Security/SecKeyPriv.h>
+
+#include <securityd/SOSCloudCircleServer.h>
+
+#include "SOSAccountTesting.h"
+
+
+static int kTestTestCount = 102;
+#if 0
+static int countPeers(SOSAccountRef account, bool active) {
+    CFErrorRef error = NULL;
+    CFArrayRef peers;
+
+    if(active) peers = SOSAccountCopyActivePeers(account, &error);
+    else peers = SOSAccountCopyPeers(account, &error);
+    int retval = (int) CFArrayGetCount(peers);
+    CFReleaseNull(error);
+    CFReleaseNull(peers);
+    return retval;
+}
+#endif
+/*
+ static void trim_retirements_from_circle(SOSAccountRef account) {
+ SOSAccountForEachCircle(account, ^(SOSCircleRef circle) {
+ SOSCircleRemoveRetired(circle, NULL);
+ });
+ }
+ */
+static bool accept_applicants(SOSAccountRef account, int count) {
+    CFErrorRef error = NULL;
+    CFArrayRef applicants = SOSAccountCopyApplicants(account, &error);
+    bool retval = false;
+    ok(applicants, "Have Applicants");
+    if(!applicants) goto errout;
+    is(CFArrayGetCount(applicants), count, "See applicants %@ (%@)", applicants, error);
+    if(CFArrayGetCount(applicants) != count) goto errout;
+    ok(retval = SOSAccountAcceptApplicants(account, applicants, &error), "Account accepts (%@)", error);
+errout:
+    CFReleaseNull(error);
+    CFReleaseNull(applicants);
+    return retval;
+}
+
+
+static void tests(void)
+{
+    CFErrorRef error = NULL;
+    CFDataRef cfpassword = CFDataCreate(NULL, (uint8_t *) "FooFooFoo", 10);
+    CFStringRef cfaccount = CFSTR("test@test.org");
+
+    CFMutableDictionaryRef changes = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
+
+    SOSAccountRef alice_account = CreateAccountForLocalChanges(changes, CFSTR("Alice"), CFSTR("TestSource"));
+    SOSAccountRef bob_account = CreateAccountForLocalChanges(changes, CFSTR("Bob"), CFSTR("TestSource"));
+    SOSAccountRef carole_account = CreateAccountForLocalChanges(changes, CFSTR("Carole"), CFSTR("TestSource"));
+    SOSAccountRef david_account = CreateAccountForLocalChanges(changes, CFSTR("David"), CFSTR("TestSource"));
+
+    ok(SOSAccountAssertUserCredentials(bob_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
+
+    // Bob wins writing at this point, feed the changes back to alice.
+
+    FeedChangesToMulti(changes, alice_account, carole_account, david_account, NULL);
+
+    ok(SOSAccountAssertUserCredentials(alice_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
+    CFReleaseNull(error);
+
+    ok(SOSAccountAssertUserCredentials(carole_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
+    CFReleaseNull(error);
+
+    ok(SOSAccountAssertUserCredentials(david_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
+    CFReleaseNull(error);
+
+    ok(SOSAccountResetToOffering(alice_account, &error), "Reset to offering (%@)", error);
+    CFReleaseNull(error);
+
+    FeedChangesTo(changes, bob_account);
+
+    ok(SOSAccountJoinCircles(bob_account, &error), "Bob Applies (%@)", error);
+    CFReleaseNull(error);
+
+    FeedChangesTo(changes, alice_account);
+
+    ok(accept_applicants(alice_account, 1), "Alice Accepts Application");
+
+    FeedChangesToMulti(changes, alice_account, bob_account, carole_account, david_account, NULL);
+
+    FeedChangesToMulti(changes, alice_account, bob_account, carole_account, david_account, NULL);
+
+    ok(CFDictionaryGetCount(changes) == 0, "We converged. (%@)", changes);
+
+    accounts_agree("bob&alice pair", bob_account, alice_account);
+    is(SOSAccountGetLastDepartureReason(bob_account, &error), kSOSNeverLeftCircle, "Bob affirms he hasn't left.");
+
+    // ==============================  Alice and Bob are in the Account. ============================================
+
+    ok(SOSAccountJoinCircles(carole_account, &error), "Carole Applies (%@)", error);
+    CFReleaseNull(error);
+
+    FeedChangesToMulti(changes, alice_account, carole_account, david_account, NULL);
+
+    ok(accept_applicants(alice_account, 1), "Alice Accepts Application");
+
+    // Let everyone concur.
+    FeedChangesToMulti(changes, alice_account, carole_account, david_account, NULL);
+
+    CFArrayRef peers = SOSAccountCopyPeers(alice_account, &error);
+    ok(peers && CFArrayGetCount(peers) == 3, "See three peers %@ (%@)", peers, error);
+    CFReleaseNull(peers);
+
+
+    // SOSAccountPurgePrivateCredential(alice_account);
+
+    ok(SOSAccountLeaveCircles(alice_account, &error), "Alice Leaves (%@)", error);
+    CFReleaseNull(error);
+
+    FeedChangesToMulti(changes, alice_account, carole_account, david_account, NULL);
+    FeedChangesToMulti(changes, alice_account, carole_account, david_account, NULL);
+    FeedChangesToMulti(changes, alice_account, carole_account, david_account, NULL);
+
+    ok(SOSAccountJoinCircles(david_account, &error), "David Applies (%@)", error);
+    CFReleaseNull(error);
+
+    FeedChangesToMulti(changes, alice_account, carole_account, david_account, NULL);
+
+    CFReleaseNull(error);
+    ok(accept_applicants(carole_account, 1), "Carole Accepts Application");
+
+    // ==============================  We added Carole and David while Bob was in a drawer. Alice has left ============================================
+
+    // ==============================  Bob comes out of the drawer seeing alice left and doesn't recognize the remainder. ============================================
+
+    FeedChangesToMulti(changes, alice_account, carole_account, david_account, NULL);
+    FeedChangesToMulti(changes, bob_account, alice_account, carole_account, david_account, NULL);
+    FeedChangesToMulti(changes, alice_account, carole_account, david_account, bob_account, NULL);
+    FeedChangesToMulti(changes, alice_account, carole_account, david_account, bob_account, NULL);
+    FeedChangesToMulti(changes, alice_account, carole_account, david_account, bob_account, NULL);
+    FeedChangesToMulti(changes, alice_account, carole_account, david_account, bob_account, NULL);
+    FeedChangesToMulti(changes, alice_account, carole_account, david_account, bob_account, NULL);
+
+    CFReleaseNull(error);
+    is(SOSAccountIsInCircles(carole_account, &error), kSOSCCInCircle, "Carole still in Circle  (%@)", error);
+    CFReleaseNull(error);
+    is(SOSAccountIsInCircles(david_account, &error), kSOSCCInCircle, "David still in Circle  (%@)", error);
+    CFReleaseNull(error);
+    is(SOSAccountIsInCircles(bob_account, &error), kSOSCCNotInCircle, "Bob is not in Circle  (%@)", error);
+    CFReleaseNull(error);
+    is(SOSAccountGetLastDepartureReason(bob_account, &error), kSOSLeftUntrustedCircle, "Bob affirms he left because he doesn't know anyone.");
+    CFReleaseNull(error);
+    is(SOSAccountIsInCircles(alice_account, &error), kSOSCCNotInCircle, "Alice is not in Circle  (%@)", error);
+    CFReleaseNull(error);
+    is(SOSAccountGetLastDepartureReason(alice_account, &error), kSOSWithdrewMembership, "Alice affirms she left by request.");
+    CFReleaseNull(error);
+
+
+    CFReleaseNull(carole_account);
+    CFReleaseNull(david_account);
+    CFReleaseNull(bob_account);
+    CFReleaseNull(alice_account);
+}
+
+int secd_61_account_leave_not_in_kansas_anymore(int argc, char *const *argv)
+{
+    plan_tests(kTestTestCount);
+
+    tests();
+
+       return 0;
+}
diff --git a/sec/securityd/Regressions/secd_regressions.h b/sec/securityd/Regressions/secd_regressions.h
new file mode 100644 (file)
index 0000000..391a06a
--- /dev/null
@@ -0,0 +1,31 @@
+//
+//  secd_regressions.h
+//  sec
+//
+//  Created by Fabrice Gautier on 5/29/13.
+//
+//
+
+#include <test/testmore.h>
+
+ONE_TEST(secd_01_items)
+ONE_TEST(secd_02_upgrade_while_locked)
+ONE_TEST(secd_03_corrupted_items)
+ONE_TEST(secd_04_corrupted_items)
+ONE_TEST(secd_05_corrupted_items)
+
+DISABLED_ONE_TEST(secd_30_keychain_upgrade) //obsolete, needs updating
+ONE_TEST(secd_31_keychain_bad)
+ONE_TEST(secd_31_keychain_unreadable)
+
+ONE_TEST(secd_50_account)
+ONE_TEST(secd_51_account_inflate)
+ONE_TEST(secd_52_account_changed)
+ONE_TEST(secd_55_account_circle)
+ONE_TEST(secd_55_account_incompatibility)
+ONE_TEST(secd_56_account_apply)
+ONE_TEST(secd_57_account_leave)
+ONE_TEST(secd_58_password_change)
+ONE_TEST(secd_59_account_cleanup)
+ONE_TEST(secd_60_account_cloud_identity)
+ONE_TEST(secd_61_account_leave_not_in_kansas_anymore)
diff --git a/sec/securityd/Regressions/securityd_regressions.h b/sec/securityd/Regressions/securityd_regressions.h
new file mode 100644 (file)
index 0000000..b1d2a50
--- /dev/null
@@ -0,0 +1,12 @@
+/* To add a test:
+ 1) add it here
+ 2) Add it as command line argument for SecurityTest.app in the Release and Debug schemes
+ */
+#include <test/testmore.h>
+
+ONE_TEST(sd_10_policytree)
+#ifdef NO_SERVER
+ONE_TEST(sd_70_engine)
+#else
+OFF_ONE_TEST(sd_70_engine)
+#endif
diff --git a/sec/securityd/SOSCloudCircleServer.c b/sec/securityd/SOSCloudCircleServer.c
new file mode 100644 (file)
index 0000000..3910d2e
--- /dev/null
@@ -0,0 +1,986 @@
+//
+//  SOSCloudCircleServer.c
+//  sec
+//
+//  Created by Mitch Adler on 11/15/12.
+//
+//
+
+#include <AssertMacros.h>
+#include <CoreFoundation/CFURL.h>
+
+#include <securityd/SOSCloudCircleServer.h>
+#include <SecureObjectSync/SOSCloudCircle.h>
+#include <SecureObjectSync/SOSCloudCircleInternal.h>
+#include <SecureObjectSync/SOSCircle.h>
+#include <SecureObjectSync/SOSAccount.h>
+#include <SecureObjectSync/SOSFullPeerInfo.h>
+#include <SecureObjectSync/SOSPeerInfoInternal.h>
+#include <SecureObjectSync/SOSInternal.h>
+#include <SecureObjectSync/SOSUserKeygen.h>
+
+#include <utilities/SecCFWrappers.h>
+#include <utilities/SecCFRelease.h>
+#include <utilities/debugging.h>
+#include "SOSCloudKeychainClient.h"
+
+#include <corecrypto/ccrng.h>
+#include <corecrypto/ccrng_pbkdf2_prng.h>
+#include <corecrypto/ccec.h>
+#include <corecrypto/ccdigest.h>
+#include <corecrypto/ccsha2.h>
+#include <CommonCrypto/CommonRandomSPI.h>
+#include <Security/SecKeyPriv.h>
+#include <Security/SecFramework.h>
+
+#include <utilities/SecFileLocations.h>
+#include <utilities/SecAKSWrappers.h>
+#include <SecItemServer.h>
+#include <SecItemPriv.h>
+
+#include <TargetConditionals.h>
+
+#include <utilities/iCloudKeychainTrace.h>
+
+#if TARGET_OS_EMBEDDED || TARGET_IPHONE_SIMULATOR
+#include <MobileGestalt.h>
+#else
+#include <AppleSystemInfo/AppleSystemInfo.h>
+
+// We need authorization, but that doesn't exist
+// on sec built for desktop (iOS in a process)
+// Define AuthorizationRef here to make SystemConfiguration work
+// as if it's on iOS.
+typedef const struct AuthorizationOpaqueRef *  AuthorizationRef;
+#endif
+
+#define SOSCKCSCOPE "sync"
+
+#define USE_SYSTEMCONFIGURATION_PRIVATE_HEADERS
+#import <SystemConfiguration/SystemConfiguration.h>
+
+#include <notify.h>
+
+CloudKeychainReplyBlock log_error = ^(CFDictionaryRef returnedValues __unused, CFErrorRef error) {
+    if (error) {
+        secerror("Error putting: %@", error);
+        CFReleaseSafe(error);
+    }
+};
+
+static SOSCCAccountDataSourceFactoryBlock accountDataSourceOverride = NULL;
+
+bool SOSKeychainAccountSetFactoryForAccount(SOSCCAccountDataSourceFactoryBlock block)
+{
+    accountDataSourceOverride = Block_copy(block);
+    
+    return true;
+}
+
+static void do_with_account(void (^action)(SOSAccountRef account));
+
+
+//
+// Constants
+//
+CFStringRef kSOSInternalAccessGroup = CFSTR("com.apple.security.sos");
+
+CFStringRef kSOSAccountLabel = CFSTR("iCloud Keychain Account Meta-data");
+CFStringRef kSOSPeerDataLabel = CFSTR("iCloud Peer Data Meta-data");
+
+static CFStringRef accountFileName = CFSTR("PersistedAccount.plist");
+
+static CFDictionaryRef SOSItemCopyQueryForSyncItems(CFStringRef service, bool returnData)
+{
+    return CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
+                                        kSecClass,           kSecClassGenericPassword,
+                                        kSecAttrService,     service,
+                                        kSecAttrAccessGroup, kSOSInternalAccessGroup,
+                                        kSecReturnData,      returnData ? kCFBooleanTrue : kCFBooleanFalse,
+                                        NULL);
+}
+
+CFDataRef SOSItemGet(CFStringRef service, CFErrorRef* error)
+{
+    CFDictionaryRef query = SOSItemCopyQueryForSyncItems(service, true);
+
+    CFDataRef result = NULL;
+
+    OSStatus copyResult = SecItemCopyMatching(query, (CFTypeRef*) &result);
+
+    CFReleaseNull(query);
+
+    if (copyResult != noErr) {
+        SecError(copyResult, error, CFSTR("Error %@ reading for service '%@'"), result, service);
+        CFReleaseNull(result);
+        return NULL;
+    }
+
+    if (!isData(result)) {
+        SOSCreateErrorWithFormat(kSOSErrorProcessingFailure, NULL, error, NULL, CFSTR("SecItemCopyMatching returned non-data in '%@'"), service);
+        return NULL;
+    }
+
+    return result;
+}
+
+static CFDataRef SOSKeychainCopySavedAccountData()
+{
+    CFErrorRef error = NULL;
+    CFDataRef accountData = SOSItemGet(kSOSAccountLabel, &error);
+    if (!accountData)
+        secnotice("account", "Failed to load account: %@", error);
+    CFReleaseNull(error);
+
+    return accountData;
+}
+
+
+bool SOSItemUpdateOrAdd(CFStringRef service, CFStringRef accessibility, CFDataRef data, CFErrorRef *error)
+{
+    CFDictionaryRef query = SOSItemCopyQueryForSyncItems(service, false);
+
+    CFDictionaryRef update = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
+                                                          kSecValueData,         data,
+                                                          kSecAttrAccessible,    accessibility,
+                                                          NULL);
+    OSStatus saveStatus = SecItemUpdate(query, update);
+
+    if (errSecItemNotFound == saveStatus) {
+        CFMutableDictionaryRef add = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, query);
+        CFDictionaryForEach(update, ^(const void *key, const void *value) {
+            CFDictionaryAddValue(add, key, value);
+        });
+        saveStatus = SecItemAdd(add, NULL);
+        CFReleaseNull(add);
+    }
+
+    CFReleaseNull(query);
+    CFReleaseNull(update);
+
+    return SecError(saveStatus, error, CFSTR("Error saving %@ to service '%@'"), data, service);
+}
+
+static CFStringRef accountStatusFileName = CFSTR("accountStatus.plist");
+#include <utilities/der_plist.h>
+#include <utilities/der_plist_internal.h>
+#include <corecrypto/ccder.h>
+
+static const uint8_t* ccder_decode_bool(bool* boolean, const uint8_t* der, const uint8_t *der_end)
+{
+    if (NULL == der)
+        return NULL;
+    
+    size_t payload_size = 0;
+    const uint8_t *payload = ccder_decode_tl(CCDER_BOOLEAN, &payload_size, der, der_end);
+    
+    if (NULL == payload || (der_end - payload) < 1 || payload_size != 1) {
+        return NULL;
+    }
+    
+    if (boolean)
+        *boolean = (*payload != 0);
+    
+    return payload + payload_size;
+}
+
+bool SOSCCCircleIsOn_Artifact(void) {
+    CFURLRef accountStatusFileURL = SecCopyURLForFileInKeychainDirectory(accountStatusFileName);
+    CFDataRef accountStatus = (CFDataRef) CFPropertyListReadFromFile(accountStatusFileURL);
+    CFReleaseSafe(accountStatusFileURL);
+    bool circle_on = false;
+    
+    if (accountStatus && !isData(accountStatus)) {
+        CFReleaseNull(accountStatus);
+    } else if(accountStatus) {
+        size_t size = CFDataGetLength(accountStatus);
+        const uint8_t *der = CFDataGetBytePtr(accountStatus);
+        const uint8_t *der_p = der;
+        
+        const uint8_t *sequence_end;
+        der_p = ccder_decode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, &sequence_end, der_p, der_p + size);
+        der_p = ccder_decode_bool(&circle_on, der_p, sequence_end);
+    } else {
+        
+    }
+    return circle_on;
+}
+
+
+static size_t ccder_sizeof_bool(bool value __unused, CFErrorRef *error)
+{
+    return ccder_sizeof(CCDER_BOOLEAN, 1);
+}
+
+
+static uint8_t* ccder_encode_bool(bool value, const uint8_t *der, uint8_t *der_end)
+{
+    uint8_t value_byte = value;
+    
+    return ccder_encode_tl(CCDER_BOOLEAN, 1, der,
+                           ccder_encode_body(1, &value_byte, der, der_end));
+}
+
+static void SOSCCCircleIsOn_SetArtifact(bool account_on) {
+    static CFDataRef sLastSavedAccountStatus = NULL;
+    CFErrorRef saveError = NULL;
+    size_t der_size = ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, ccder_sizeof_bool(account_on, NULL));
+    uint8_t der[der_size];
+    uint8_t *der_end = der + der_size;
+    der_end = ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der,
+                                           ccder_encode_bool(account_on, der, der_end));
+
+    CFDataRef accountStatusAsData = CFDataCreate(kCFAllocatorDefault, der_end, der_size);
+    
+    require_quiet(accountStatusAsData, exit);
+    if (sLastSavedAccountStatus && CFEqual(sLastSavedAccountStatus, accountStatusAsData))  goto exit;
+    
+    CFURLRef accountStatusFileURL = SecCopyURLForFileInKeychainDirectory(accountStatusFileName);
+    CFPropertyListWriteToFile((CFPropertyListRef) accountStatusAsData, accountStatusFileURL);
+    CFReleaseSafe(accountStatusFileURL);
+    
+    CFReleaseNull(sLastSavedAccountStatus);
+    sLastSavedAccountStatus = accountStatusAsData;
+    accountStatusAsData = NULL;
+    
+exit:
+    CFReleaseNull(saveError);
+    CFReleaseNull(accountStatusAsData);
+}
+
+
+static void SOSKeychainAccountEnsureSaved(SOSAccountRef account)
+{
+    static CFDataRef sLastSavedAccountData = NULL;
+    
+    CFErrorRef saveError = NULL;
+    SOSCCStatus currentStatus = SOSAccountIsInCircles(account, NULL);
+    bool account_on = (currentStatus == kSOSCCCircleAbsent || currentStatus == kSOSCCNotInCircle) ? false: true;
+    SOSCCCircleIsOn_SetArtifact(account_on);
+    
+    CFDataRef accountAsData = SOSAccountCopyEncodedData(account, kCFAllocatorDefault, &saveError);
+    
+    require_action_quiet(accountAsData, exit, secerror("Failed to transform account into data, error: %@", saveError));
+    require_quiet(!CFEqualSafe(sLastSavedAccountData, accountAsData), exit);
+    
+    if (!SOSItemUpdateOrAdd(kSOSAccountLabel, kSecAttrAccessibleAlwaysThisDeviceOnly, accountAsData, &saveError)) {
+        secerror("Can't save account: %@", saveError);
+        goto exit;
+    }
+    
+    CFReleaseNull(sLastSavedAccountData);
+    sLastSavedAccountData = accountAsData;
+    accountAsData = NULL;
+    
+exit:
+    CFReleaseNull(saveError);
+    CFReleaseNull(accountAsData);
+}
+
+
+/*
+ Stolen from keychain_sync.c
+ */
+
+static bool clearAllKVS(CFErrorRef *error)
+{
+    return true;
+    __block bool result = false;
+    const uint64_t maxTimeToWaitInSeconds = 30ull * NSEC_PER_SEC;
+    dispatch_queue_t processQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
+    dispatch_semaphore_t waitSemaphore = dispatch_semaphore_create(0);
+    dispatch_time_t finishTime = dispatch_time(DISPATCH_TIME_NOW, maxTimeToWaitInSeconds);
+
+    SOSCloudKeychainClearAll(processQueue, ^(CFDictionaryRef returnedValues, CFErrorRef cerror)
+                             {
+                                 result = (cerror != NULL);
+                                 dispatch_semaphore_signal(waitSemaphore);
+                             });
+
+       dispatch_semaphore_wait(waitSemaphore, finishTime);
+    dispatch_release(waitSemaphore);
+
+    return result;
+}
+
+static SOSAccountRef SOSKeychainAccountCreateSharedAccount(CFDictionaryRef our_gestalt)
+{
+    SOSAccountKeyInterestBlock updateKVSKeys = ^(bool getNewKeysOnly, CFArrayRef alwaysKeys, CFArrayRef afterFirstUnlockKeys, CFArrayRef unlockedKeys) {
+        CFErrorRef error = NULL;
+
+        if (!SOSCloudKeychainUpdateKeys(getNewKeysOnly, alwaysKeys, afterFirstUnlockKeys, unlockedKeys, &error))
+        {
+            secerror("Error updating keys: %@", error);
+            // TODO: propagate error(s) to callers.
+        } else {
+            if (CFArrayGetCount(unlockedKeys) == 0) {
+                secnotice(SOSCKCSCOPE, "Unlocked keys were empty!");
+            }
+            // This leaks 3 CFStringRefs in DEBUG builds.
+            CFStringRef alwaysKeysDesc = SOSInterestListCopyDescription(alwaysKeys);
+            CFStringRef afterFirstUnlockKeysDesc = SOSInterestListCopyDescription(afterFirstUnlockKeys);
+            CFStringRef unlockedKeysDesc = SOSInterestListCopyDescription(unlockedKeys);
+            secdebug(SOSCKCSCOPE, "Updating interest: always: %@,\nfirstUnlock: %@,\nunlockedKeys: %@",
+                     alwaysKeysDesc,
+                     afterFirstUnlockKeysDesc,
+                     unlockedKeysDesc);
+            CFReleaseNull(alwaysKeysDesc);
+            CFReleaseNull(afterFirstUnlockKeysDesc);
+            CFReleaseNull(unlockedKeysDesc);
+        }
+
+        CFReleaseNull(error);
+    };
+    
+    SOSAccountDataUpdateBlock updateKVS = ^ bool (CFDictionaryRef changes, CFErrorRef *error) {
+        SOSCloudKeychainPutObjectsInCloud(changes, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), log_error);
+
+        CFStringRef changeDescription = SOSChangesCopyDescription(changes, true);
+        secnotice("account", "Keys Sent: %@", changeDescription);
+        CFReleaseSafe(changeDescription);
+
+        return true;
+    };
+
+    secdebug("account", "Created account");
+        
+    CFDataRef savedAccount = SOSKeychainCopySavedAccountData();
+    
+    // At this point we might have an account structure from keychain that may or may not match the account we're building this for
+    // murf ZZZ we should probably make sure this is a good thing before using it.
+
+    SOSAccountRef account = NULL;
+    
+    if (savedAccount) {
+        CFErrorRef inflationError = NULL;
+        SOSDataSourceFactoryRef factory = accountDataSourceOverride ? accountDataSourceOverride() : SecItemDataSourceFactoryCreateDefault();
+
+        account = SOSAccountCreateFromData(kCFAllocatorDefault, savedAccount, factory, updateKVSKeys, updateKVS, &inflationError);
+        
+        if (account)
+            SOSAccountUpdateGestalt(account, our_gestalt);
+        else
+            secerror("Got error inflating account: %@", inflationError);
+        CFReleaseNull(inflationError);
+    }
+
+    CFReleaseSafe(savedAccount);
+    
+    if (!account) {
+               // If we get here then we are creating a new accout and so increment the peer count for ourselves.
+        SOSDataSourceFactoryRef factory = accountDataSourceOverride ? accountDataSourceOverride() : SecItemDataSourceFactoryCreateDefault();
+
+        account = SOSAccountCreate(kCFAllocatorDefault, our_gestalt, factory, updateKVSKeys, updateKVS);
+
+        if (!account)
+            secerror("Got NULL creating account");
+    }
+
+    return account;
+}
+
+//
+// Mark: Gestalt Handling
+//
+
+static CFStringRef CopyModelName(void)
+{
+    static dispatch_once_t once;
+    static CFStringRef modelName = NULL;
+    dispatch_once(&once, ^{
+#if TARGET_OS_EMBEDDED || TARGET_IPHONE_SIMULATOR
+        modelName = MGCopyAnswer(kMGQDeviceName, NULL);
+#else
+        modelName = ASI_CopyComputerModelName(FALSE);
+#endif
+        if (modelName == NULL)
+            modelName = CFSTR("Unknown model");
+    });
+    return CFStringCreateCopy(kCFAllocatorDefault, modelName);
+}
+
+static CFStringRef CopyComputerName(SCDynamicStoreRef store)
+{
+    CFStringRef deviceName = SCDynamicStoreCopyComputerName(store, NULL);
+    if (deviceName == NULL) {
+        deviceName = CFSTR("Unknown name");
+    }
+    return deviceName;
+}
+
+static CFDictionaryRef GatherDeviceGestalt(SCDynamicStoreRef store, CFArrayRef keys, void *context)
+{
+    CFStringRef modelName = CopyModelName();
+    CFStringRef computerName = CopyComputerName(store);
+
+    CFDictionaryRef gestalt = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
+                                                           kPIUserDefinedDeviceName, computerName,
+                                                           kPIDeviceModelName,       modelName,
+                                                           NULL);
+    CFRelease(modelName);
+    CFRelease(computerName);
+
+    return gestalt;
+}
+
+static void SOSCCProcessGestaltUpdate(SCDynamicStoreRef store, CFArrayRef keys, void *context)
+{
+    do_with_account(^(SOSAccountRef account) {
+        CFDictionaryRef gestalt = GatherDeviceGestalt(store, keys, context);
+        if (SOSAccountUpdateGestalt(account, gestalt)) {
+            notify_post(kSOSCCCircleChangedNotification);
+        }
+        CFReleaseSafe(gestalt);
+    });
+}
+
+
+static CFDictionaryRef RegisterForGestaltUpdate(dispatch_queue_t queue, void *info)
+{
+    SCDynamicStoreContext context = { .info = info };
+    SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("com.apple.securityd.cloudcircleserver"), SOSCCProcessGestaltUpdate, &context);
+    CFStringRef computerKey = SCDynamicStoreKeyCreateComputerName(NULL);
+    CFArrayRef keys = NULL;
+    CFDictionaryRef gestalt = NULL;
+
+    if (store == NULL || computerKey == NULL) {
+        goto done;
+    }
+    keys = CFArrayCreate(NULL, (const void **)&computerKey, 1, &kCFTypeArrayCallBacks);
+    if (keys == NULL) {
+        goto done;
+    }
+    gestalt = GatherDeviceGestalt(store, keys, info);
+    SCDynamicStoreSetNotificationKeys(store, keys, NULL);
+    SCDynamicStoreSetDispatchQueue(store, queue);
+
+done:
+    if (store) CFRelease(store);
+    if (computerKey) CFRelease(computerKey);
+    if (keys) CFRelease(keys);
+    return gestalt;
+}
+
+static void do_with_account(void (^action)(SOSAccountRef account));
+static void do_with_account_async(void (^action)(SOSAccountRef account));
+
+static void do_with_account_dynamic(void (^action)(SOSAccountRef account), bool sync) {
+    static SOSAccountRef sSharedAccount;
+    static dispatch_once_t onceToken;
+    
+    dispatch_once(&onceToken, ^{
+        secdebug(SOSCKCSCOPE, "Account Creation start");
+        
+        CFDictionaryRef gestalt = RegisterForGestaltUpdate(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), NULL);
+        
+        if (!gestalt) {
+#if TARGET_OS_IPHONE && TARGET_IPHONE_SIMULATOR
+            gestalt = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, NULL);
+#else
+            secerror("Didn't get machine gestalt! This is going to be ugly.");
+#endif
+        }
+
+        sSharedAccount = SOSKeychainAccountCreateSharedAccount(gestalt);
+
+        CFReleaseSafe(gestalt);
+        
+        SOSCCSetThisDeviceDefinitelyNotActiveInCircle(SOSAccountIsInCircles(sSharedAccount, NULL));
+        
+        SOSAccountAddChangeBlock(sSharedAccount, ^(SOSCircleRef circle,
+                                                   CFArrayRef peer_additions,      CFArrayRef peer_removals,
+                                                   CFArrayRef applicant_additions, CFArrayRef applicant_removals) {
+            CFErrorRef pi_error = NULL;
+            SOSPeerInfoRef me = SOSAccountGetMyPeerInCircle(sSharedAccount, circle, &pi_error);
+            if (!me) {
+                secerror("Error finding me for change: %@", pi_error);
+                CFReleaseNull(pi_error);
+            } else {
+                CFReleaseSafe(pi_error);
+                
+                if (CFArrayContainsValue(peer_additions, CFRangeMake(0, CFArrayGetCount(peer_additions)), me)) {
+                    SOSCCSyncWithAllPeers();
+                }
+            }
+
+            if (CFArrayGetCount(peer_additions) != 0 ||
+                CFArrayGetCount(peer_removals) != 0 ||
+                CFArrayGetCount(applicant_additions) != 0 ||
+                CFArrayGetCount(applicant_removals) != 0) {
+                
+                SOSCCSetThisDeviceDefinitelyNotActiveInCircle(SOSAccountIsInCircles(sSharedAccount, NULL));
+                notify_post(kSOSCCCircleChangedNotification);
+           }
+        });
+        
+        SOSCloudKeychainSetItemsChangedBlock(^(CFDictionaryRef changes) {
+            CFRetainSafe(changes);
+            do_with_account_async(^(SOSAccountRef account) {
+                CFStringRef changeDescription = SOSChangesCopyDescription(changes, false);
+                secdebug(SOSCKCSCOPE, "Received: %@", changeDescription);
+                CFReleaseSafe(changeDescription);
+                
+                CFErrorRef error = NULL;
+                if (!SOSAccountHandleUpdates(account, changes, &error)) {
+                    secerror("Error handling updates: %@", error);
+                    CFReleaseNull(error);
+                    return;
+                }
+                    CFReleaseNull(error);
+                CFReleaseSafe(changes);
+            });
+        });
+
+    });
+    
+    dispatch_block_t do_action_and_save =  ^{
+        action(sSharedAccount);
+        SOSKeychainAccountEnsureSaved(sSharedAccount);
+    };
+
+    if (sync) {
+        dispatch_sync(SOSAccountGetQueue(sSharedAccount), do_action_and_save);
+    } else {
+        dispatch_async(SOSAccountGetQueue(sSharedAccount), do_action_and_save);
+    }
+}
+
+static void do_with_account_async(void (^action)(SOSAccountRef account)) {
+    do_with_account_dynamic(action, false);
+}
+
+static void do_with_account(void (^action)(SOSAccountRef account)) {
+    do_with_account_dynamic(action, true);
+}
+
+#if TARGET_IPHONE_SIMULATOR
+#define MKBDeviceUnlockedSinceBoot() true
+#endif
+
+static bool do_if_after_first_unlock(CFErrorRef *error, dispatch_block_t action)
+{
+    bool beenUnlocked = false;
+    require_quiet(SecAKSGetHasBeenUnlocked(&beenUnlocked, error), fail);
+
+    require_action_quiet(beenUnlocked, fail,
+                         SOSCreateErrorWithFormat(kSOSErrorNotReady, NULL, error, NULL,
+                                                  CFSTR("Keybag never unlocked, ask after first unlock")));
+
+    action();
+    return true;
+
+fail:
+    return false;
+}
+
+static bool do_with_account_if_after_first_unlock(CFErrorRef *error, bool (^action)(SOSAccountRef account, CFErrorRef* error))
+{
+    __block bool action_result = false;
+
+    return do_if_after_first_unlock(error, ^{
+        do_with_account(^(SOSAccountRef account) {
+            action_result = action(account, error);
+        });
+
+    }) && action_result;
+}
+
+static bool do_with_account_while_unlocked(CFErrorRef *error, bool (^action)(SOSAccountRef account, CFErrorRef* error))
+{
+    __block bool action_result = false;
+
+    return SecAKSDoWhileUserBagLocked(error, ^{
+        do_with_account(^(SOSAccountRef account) {
+            action_result = action(account, error);
+        });
+
+    }) && action_result;
+}
+
+SOSAccountRef SOSKeychainAccountGetSharedAccount()
+{
+    __block SOSAccountRef result = NULL;
+    
+    do_with_account(^(SOSAccountRef account) {
+        result = account;
+    });
+    
+    return result;
+}
+
+//
+// Mark: Credential processing
+//
+
+
+bool SOSCCTryUserCredentials_Server(CFStringRef user_label, CFDataRef user_password, CFErrorRef *error)
+{
+    return do_with_account_if_after_first_unlock(error, ^bool (SOSAccountRef account, CFErrorRef* block_error) {
+        return SOSAccountTryUserCredentials(account, user_label, user_password, block_error);
+    });
+}
+
+
+static bool EnsureFreshParameters(SOSAccountRef account, CFErrorRef *error) {
+    dispatch_semaphore_t wait_for = dispatch_semaphore_create(0);
+    dispatch_retain(wait_for); // Both this scope and the block own it.
+    
+    CFMutableArrayRef keysToGet = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
+    CFArrayAppendValue(keysToGet, kSOSKVSKeyParametersKey);
+    
+    __block CFDictionaryRef valuesToUpdate = NULL;
+    __block bool success = false;
+    
+    SOSAccountForEachCircle(account, ^(SOSCircleRef circle) {
+        CFStringRef circle_key = SOSCircleKeyCreateWithName(SOSCircleGetName(circle), NULL);
+        CFArrayAppendValue(keysToGet, circle_key);
+        CFReleaseNull(circle_key);
+    });
+    
+    secnotice("updates", "***** EnsureFreshParameters *****");
+
+    SOSCloudKeychainSynchronizeAndWait(keysToGet, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(CFDictionaryRef returnedValues, CFErrorRef sync_error) {
+
+        if (sync_error) {
+            secerror("SOSCloudKeychainSynchronizeAndWait: %@", sync_error);
+            if (error) {
+                *error = sync_error;
+                CFRetainSafe(*error);
+            }
+        } else {
+            secnotice("updates", "SOSCloudKeychainSynchronizeAndWait: results: %@", returnedValues);
+            valuesToUpdate = returnedValues;
+            CFRetainSafe(valuesToUpdate);
+            success = true;
+        }
+        
+        dispatch_semaphore_signal(wait_for);
+        dispatch_release(wait_for);
+    });
+
+    dispatch_semaphore_wait(wait_for, DISPATCH_TIME_FOREVER);
+    // TODO: Maybe we timeout here... used to dispatch_time(DISPATCH_TIME_NOW, 30ull * NSEC_PER_SEC));
+    dispatch_release(wait_for);
+    
+    if ((valuesToUpdate) && (account)) {
+        if (!SOSAccountHandleUpdates(account, valuesToUpdate, error)) {
+            secerror("Freshness update failed: %@", *error);
+            
+            success = false;
+        }
+    }
+
+    CFReleaseNull(valuesToUpdate);
+    CFReleaseNull(keysToGet);
+
+    return success;
+}
+
+static bool EnsureFreshParameters_once(SOSAccountRef account, CFErrorRef *error) {
+    static dispatch_once_t once;
+    __block bool retval = false;
+    dispatch_once(&once, ^{
+        retval = EnsureFreshParameters(account, error);
+    });
+    return retval;
+}
+
+bool SOSCCSetUserCredentials_Server(CFStringRef user_label, CFDataRef user_password, CFErrorRef *error)
+{
+    return do_with_account_if_after_first_unlock(error, ^bool (SOSAccountRef account, CFErrorRef* block_error) {        
+        if (!EnsureFreshParameters(account, block_error)) {
+            secnotice("updates", "EnsureFreshParameters error: %@", *block_error);
+            return false;
+        }
+        if (!SOSAccountAssertUserCredentials(account, user_label, user_password, block_error)) {
+            secnotice("updates", "EnsureFreshParameters/SOSAccountAssertUserCredentials error: %@", *block_error);
+            return false;
+        }
+
+        return true;
+    });
+
+}
+
+bool SOSCCCanAuthenticate_Server(CFErrorRef *error)
+{
+    bool result = do_with_account_if_after_first_unlock(error, ^bool (SOSAccountRef account, CFErrorRef* block_error) {
+        return SOSAccountGetPrivateCredential(account, block_error) != NULL;
+    });
+    
+    if (!result && error && *error && CFErrorGetDomain(*error) == kSOSErrorDomain) {
+        CFIndex code = CFErrorGetCode(*error);
+        if (code == kSOSErrorPrivateKeyAbsent || code == kSOSErrorPublicKeyAbsent) {
+            CFReleaseNull(*error);
+        }
+    }
+
+    return result;
+}
+
+bool SOSCCPurgeUserCredentials_Server(CFErrorRef *error)
+{
+    return do_with_account_if_after_first_unlock(error, ^bool (SOSAccountRef account, CFErrorRef* block_error) {
+        SOSAccountPurgePrivateCredential(account);
+        return true;
+    });
+}
+
+
+#if USE_BETTER
+static bool sAccountInCircleCache = false;
+
+static void do_with_not_in_circle_bool_queue(bool start_account, dispatch_block_t action)
+{
+    static dispatch_queue_t account_start_queue;
+    static dispatch_queue_t not_in_circle_queue;
+    static bool account_started = false;
+
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        not_in_circle_queue = dispatch_queue_create("nis queue", DISPATCH_QUEUE_SERIAL);
+        account_start_queue = dispatch_queue_create("init nis queue", DISPATCH_QUEUE_SERIAL);;
+        account_started = false;
+    });
+    
+    __block bool done = false;
+    dispatch_sync(not_in_circle_queue, ^{
+        if (account_started) {
+            done = true;
+            action();
+        }
+    });
+    
+    if (!done && start_account) {
+        dispatch_sync(account_start_queue, ^{
+            __block bool do_start = false;
+            dispatch_sync(not_in_circle_queue, ^{
+                do_start = !account_started;
+                account_started = true;
+            });
+            if (do_start)
+                SOSCCThisDeviceIsInCircle(NULL); // Inflate account.
+        });
+
+        dispatch_sync(not_in_circle_queue, action);
+    }
+}
+#endif
+
+bool SOSCCThisDeviceDefinitelyNotActiveInCircle()
+{
+    return !SOSCCCircleIsOn_Artifact();
+#if USE_BETTER
+    __block bool result = false;
+    do_with_not_in_circle_bool_queue(true, ^{
+        result = sAccountInCircleCache;
+    });
+    
+    return result;
+#endif
+}
+
+void SOSCCSetThisDeviceDefinitelyNotActiveInCircle(SOSCCStatus currentStatus)
+{
+    bool active = !(currentStatus == kSOSCCCircleAbsent || currentStatus == kSOSCCNotInCircle);
+    SOSCCCircleIsOn_SetArtifact(active);
+#if USE_BETTER
+    do_with_not_in_circle_bool_queue(false, ^{
+        sAccountInCircleCache = notActive;
+    });
+#endif
+}
+
+
+SOSCCStatus SOSCCThisDeviceIsInCircle_Server(CFErrorRef *error)
+{
+    __block SOSCCStatus status;
+    
+    return do_with_account_if_after_first_unlock(error, ^bool (SOSAccountRef account, CFErrorRef* block_error) {
+        EnsureFreshParameters_once(account, NULL);
+        status = SOSAccountIsInCircles(account, block_error);
+        return true;
+    }) ? status : kSOSCCError;
+}
+
+bool SOSCCRequestToJoinCircle_Server(CFErrorRef* error)
+{
+    return do_with_account_while_unlocked(error, ^bool (SOSAccountRef account, CFErrorRef* block_error) {
+        EnsureFreshParameters_once(account, NULL);
+        return SOSAccountJoinCircles(account, block_error);
+    });
+}
+
+bool SOSCCRequestToJoinCircleAfterRestore_Server(CFErrorRef* error)
+{
+    return do_with_account_while_unlocked(error, ^bool (SOSAccountRef account, CFErrorRef* block_error) {
+        EnsureFreshParameters_once(account, NULL);
+        return SOSAccountJoinCirclesAfterRestore(account, block_error);
+    });
+}
+
+bool SOSCCResetToOffering_Server(CFErrorRef* error)
+{
+    return do_with_account_while_unlocked(error, ^bool (SOSAccountRef account, CFErrorRef* block_error) {
+        EnsureFreshParameters_once(account, NULL);
+        clearAllKVS(NULL);
+        return SOSAccountResetToOffering(account, block_error);
+    });
+}
+
+bool SOSCCResetToEmpty_Server(CFErrorRef* error)
+{
+    return do_with_account_while_unlocked(error, ^bool (SOSAccountRef account, CFErrorRef* block_error) {
+        return SOSAccountResetToEmpty(account, block_error);
+    });
+}
+
+bool SOSCCRemoveThisDeviceFromCircle_Server(CFErrorRef* error)
+{
+    return do_with_account_while_unlocked(error, ^bool (SOSAccountRef account, CFErrorRef* block_error) {
+        bool result = SOSAccountLeaveCircles(account, block_error);
+        return result;
+    });
+}
+
+bool SOSCCBailFromCircle_Server(uint64_t limit_in_seconds, CFErrorRef* error)
+{
+    return do_with_account_while_unlocked(error, ^bool (SOSAccountRef account, CFErrorRef* block_error) {
+        return SOSAccountBail(account, limit_in_seconds, block_error);
+    });
+}
+
+CFArrayRef SOSCCCopyApplicantPeerInfo_Server(CFErrorRef* error)
+{
+    __block CFArrayRef result = NULL;
+
+    (void) do_with_account_if_after_first_unlock(error, ^bool (SOSAccountRef account, CFErrorRef* block_error) {
+        EnsureFreshParameters_once(account, NULL);
+        result = SOSAccountCopyApplicants(account, block_error);
+        return result != NULL;
+    });
+    
+    return result;
+}
+
+
+bool SOSCCAcceptApplicants_Server(CFArrayRef applicants, CFErrorRef* error)
+{
+    return do_with_account_while_unlocked(error, ^bool (SOSAccountRef account, CFErrorRef* block_error) {
+        EnsureFreshParameters_once(account, NULL);
+        return SOSAccountAcceptApplicants(account, applicants, block_error);
+    });
+}
+
+bool SOSCCRejectApplicants_Server(CFArrayRef applicants, CFErrorRef* error)
+{
+    return do_with_account_while_unlocked(error, ^bool (SOSAccountRef account, CFErrorRef* block_error) {
+        EnsureFreshParameters_once(account, NULL);
+        return SOSAccountRejectApplicants(account, applicants, block_error);
+    });
+}
+
+CFArrayRef SOSCCCopyPeerPeerInfo_Server(CFErrorRef* error)
+{
+    __block CFArrayRef result = NULL;
+    
+    (void) do_with_account_if_after_first_unlock(error, ^bool (SOSAccountRef account, CFErrorRef* block_error) {
+        EnsureFreshParameters_once(account, NULL);
+        result = SOSAccountCopyPeers(account, block_error);
+        return result != NULL;
+    });
+    
+    return result;
+}
+
+CFArrayRef SOSCCCopyConcurringPeerPeerInfo_Server(CFErrorRef* error)
+{
+    __block CFArrayRef result = NULL;
+    
+    (void) do_with_account_if_after_first_unlock(error, ^bool (SOSAccountRef account, CFErrorRef* block_error) {
+        EnsureFreshParameters_once(account, NULL);
+        result = SOSAccountCopyConcurringPeers(account, block_error);
+        return result != NULL;
+    });
+    
+    return result;
+}
+
+CFStringRef SOSCCCopyIncompatibilityInfo_Server(CFErrorRef* error)
+{
+    __block CFStringRef result = NULL;
+    
+    (void) do_with_account_if_after_first_unlock(error, ^bool (SOSAccountRef account, CFErrorRef* block_error) {
+        EnsureFreshParameters_once(account, NULL);
+        result = SOSAccountCopyIncompatibilityInfo(account, block_error);
+        return result != NULL;
+    });
+    
+    return result;
+}
+
+enum DepartureReason SOSCCGetLastDepartureReason_Server(CFErrorRef* error)
+{
+    __block enum DepartureReason result = kSOSDepartureReasonError;
+    
+    (void) do_with_account_if_after_first_unlock(error, ^bool (SOSAccountRef account, CFErrorRef* block_error) {
+        EnsureFreshParameters_once(account, NULL);
+        result = SOSAccountGetLastDepartureReason(account, block_error);
+        return result != kSOSDepartureReasonError;
+    });
+    
+    return result;
+}
+
+SyncWithAllPeersReason SOSCCProcessSyncWithAllPeers_Server(CFErrorRef* error)
+{
+    /*
+     #define kIOReturnLockedRead      iokit_common_err(0x2c3) // device read locked
+     #define kIOReturnLockedWrite     iokit_common_err(0x2c4) // device write locked
+    */
+    __block SyncWithAllPeersReason result = kSyncWithAllPeersSuccess;
+    CFErrorRef action_error = NULL;
+
+    if (!do_with_account_while_unlocked(&action_error, ^bool (SOSAccountRef account, CFErrorRef* block_error) {
+        CFErrorRef localError = NULL;
+        if (!SOSAccountSyncWithAllPeers(account, &localError)) {
+            secerror("sync with all peers failed: %@", localError);
+            CFReleaseSafe(localError);
+            // This isn't a device-locked error, but returning false will
+            // have CloudKeychainProxy ask us to try sync again after next unlock
+            result = kSyncWithAllPeersOtherFail;
+            return false;
+        }
+        return true;
+    })) {
+        if (action_error) {
+            if (SecErrorGetOSStatus(action_error) == errSecInteractionNotAllowed) {
+                secnotice("updates", "SOSAccountSyncWithAllPeers failed because device is locked; letting CloudKeychainProxy know");
+                result = kSyncWithAllPeersLocked;        // tell CloudKeychainProxy to call us back when device unlocks
+                CFReleaseNull(action_error);
+            } else {
+                secerror("Unexpected error: %@", action_error);
+            }
+
+            if (error && *error == NULL) {
+                *error = action_error;
+                action_error = NULL;
+            }
+
+            CFReleaseNull(action_error);
+        }
+    }
+
+    return result;
+}
+
+void SOSCCSyncWithAllPeers(void)
+{
+    SOSCloudKeychainRequestSyncWithAllPeers(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), NULL);
+}
+
+void SOSCCHandleUpdate(CFDictionaryRef updates)
+{
+    SOSCloudKeychainHandleUpdate(updates);
+}
+
diff --git a/sec/securityd/SOSCloudCircleServer.h b/sec/securityd/SOSCloudCircleServer.h
new file mode 100644 (file)
index 0000000..ab1ceb2
--- /dev/null
@@ -0,0 +1,85 @@
+//
+//  SOSCloudCircleServer.h
+//  sec
+//
+//  Created by Mitch Adler on 11/15/12.
+//
+//
+
+#ifndef _SECURITY_SOSCLOUDCIRCLESERVER_H_
+#define _SECURITY_SOSCLOUDCIRCLESERVER_H_
+
+#include <SecureObjectSync/SOSCloudCircle.h>
+#include <SecureObjectSync/SOSAccount.h>
+
+//
+// MARK: Server versions of our SPI
+//
+bool SOSCCTryUserCredentials_Server(CFStringRef user_label, CFDataRef user_password, CFErrorRef *error);
+bool SOSCCSetUserCredentials_Server(CFStringRef user_label, CFDataRef user_password, CFErrorRef *error);
+bool SOSCCCanAuthenticate_Server(CFErrorRef *error);
+bool SOSCCPurgeUserCredentials_Server(CFErrorRef *error);
+
+SOSCCStatus SOSCCThisDeviceIsInCircle_Server(CFErrorRef *error);
+bool SOSCCRequestToJoinCircle_Server(CFErrorRef* error);
+bool SOSCCRequestToJoinCircleAfterRestore_Server(CFErrorRef* error);
+bool SOSCCRemoveThisDeviceFromCircle_Server(CFErrorRef* error);
+bool SOSCCBailFromCircle_Server(uint64_t limit_in_seconds, CFErrorRef* error);
+
+CFArrayRef SOSCCCopyApplicantPeerInfo_Server(CFErrorRef* error);
+bool SOSCCRejectApplicants_Server(CFArrayRef applicants, CFErrorRef* error);
+bool SOSCCAcceptApplicants_Server(CFArrayRef applicants, CFErrorRef* error);
+
+CFArrayRef SOSCCCopyPeerPeerInfo_Server(CFErrorRef* error);
+CFArrayRef SOSCCCopyConcurringPeerPeerInfo_Server(CFErrorRef* error);
+
+bool SOSCCResetToOffering_Server(CFErrorRef* error);
+bool SOSCCResetToEmpty_Server(CFErrorRef* error);
+
+CFStringRef SOSCCCopyIncompatibilityInfo_Server(CFErrorRef* error);
+enum DepartureReason SOSCCGetLastDepartureReason_Server(CFErrorRef* error);
+
+SyncWithAllPeersReason SOSCCProcessSyncWithAllPeers_Server(CFErrorRef* error);
+
+//
+// MARK: Internal kicks.
+//
+
+void SOSCCHandleUpdate(CFDictionaryRef updates);
+
+// Expected to be called when the data source changes.
+void SOSCCSyncWithAllPeers(void);
+
+// Internal careful questioning.
+bool SOSCCThisDeviceDefinitelyNotActiveInCircle(void);
+void SOSCCSetThisDeviceDefinitelyNotActiveInCircle(SOSCCStatus currentStatus);
+
+//
+// MARK: Internal access to local account for tests.
+//
+typedef SOSDataSourceFactoryRef (^SOSCCAccountDataSourceFactoryBlock)();
+
+SOSAccountRef SOSKeychainAccountGetSharedAccount(void);
+bool SOSKeychainAccountSetFactoryForAccount(SOSCCAccountDataSourceFactoryBlock factory);
+
+//
+// MARK: Testing operations, dangerous to call in normal operation.
+//
+bool SOSKeychainSaveAccountDataAndPurge(CFErrorRef *error);
+
+
+//
+// MARK: Constants for where we store persistent information in the keychain
+//
+
+extern CFStringRef kSOSInternalAccessGroup;
+
+extern CFStringRef kSOSAccountLabel;
+extern CFStringRef kSOSPeerDataLabel;
+
+CFDataRef SOSItemGet(CFStringRef label, CFErrorRef* error);
+bool SOSItemUpdateOrAdd(CFStringRef label, CFStringRef accessibility, CFDataRef data, CFErrorRef *error);
+
+bool SOSCCCircleIsOn_Artifact(void);
+
+#endif
index 7f55d83a94b7f034e4a4692676dc22ea7fe9a2f9..685b73e24c91680edb8e9348fb9ce45f0b232500 100644 (file)
@@ -28,7 +28,7 @@
  */
 
 #include <securityd/SecCAIssuerCache.h>
  */
 
 #include <securityd/SecCAIssuerCache.h>
-#include <security_utilities/debugging.h>
+#include <utilities/debugging.h>
 #include <Security/SecCertificateInternal.h>
 #include <Security/SecFramework.h>
 #include <Security/SecInternal.h>
 #include <Security/SecCertificateInternal.h>
 #include <Security/SecFramework.h>
 #include <Security/SecInternal.h>
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <errno.h>
-#include <pthread.h>
+#include <dispatch/dispatch.h>
 #include <asl.h>
 #include <asl.h>
-#include "sqlutils.h"
+#include "utilities/sqlutils.h"
+#include "utilities/iOSforOSX.h"
+
+#include <CoreFoundation/CFUtilities.h>
+#include <utilities/SecFileLocations.h>
 
 #define caissuerErrorLog(args...)     asl_log(NULL, NULL, ASL_LEVEL_ERR, ## args)
 
 static const char expireSQL[] = "DELETE FROM issuers WHERE expires<?";
 static const char beginTxnSQL[] = "BEGIN EXCLUSIVE TRANSACTION";
 static const char endTxnSQL[] = "COMMIT TRANSACTION";
 
 #define caissuerErrorLog(args...)     asl_log(NULL, NULL, ASL_LEVEL_ERR, ## args)
 
 static const char expireSQL[] = "DELETE FROM issuers WHERE expires<?";
 static const char beginTxnSQL[] = "BEGIN EXCLUSIVE TRANSACTION";
 static const char endTxnSQL[] = "COMMIT TRANSACTION";
-static const char insertIssuerSQL[] = "INSERT INTO issuers "
+static const char insertIssuerSQL[] = "INSERT OR REPLACE INTO issuers "
     "(uri,expires,certificate) VALUES (?,?,?)";
 static const char selectIssuerSQL[] = "SELECT certificate FROM "
     "issuers WHERE uri=?";
 
     "(uri,expires,certificate) VALUES (?,?,?)";
 static const char selectIssuerSQL[] = "SELECT certificate FROM "
     "issuers WHERE uri=?";
 
-#if NO_SERVER
-CF_EXPORT
-CFURLRef CFCopyHomeDirectoryURLForUser(CFStringRef uName);     /* Pass NULL for the current user's home directory */
-#endif
-
-#define kSecCAIssuerCachePath "/Library/Keychains/caissuercache.sqlite3";
+#define kSecCAIssuerFileName "caissuercache.sqlite3"
 
 typedef struct __SecCAIssuerCache *SecCAIssuerCacheRef;
 struct __SecCAIssuerCache {
 
 typedef struct __SecCAIssuerCache *SecCAIssuerCacheRef;
 struct __SecCAIssuerCache {
+    dispatch_queue_t queue;
        sqlite3 *s3h;
        sqlite3_stmt *expire;
        sqlite3_stmt *beginTxn;
        sqlite3 *s3h;
        sqlite3_stmt *expire;
        sqlite3_stmt *beginTxn;
@@ -72,8 +72,8 @@ struct __SecCAIssuerCache {
     bool in_transaction;
 };
 
     bool in_transaction;
 };
 
-static pthread_once_t kSecCAIssuerCacheOnce = PTHREAD_ONCE_INIT;
-static SecCAIssuerCacheRef kSecCAIssuerCache = NULL;
+static dispatch_once_t kSecCAIssuerCacheOnce;
+static SecCAIssuerCacheRef kSecCAIssuerCache;
 
 /* @@@ Duplicated from SecTrustStore.c */
 static int sec_create_path(const char *path)
 
 /* @@@ Duplicated from SecTrustStore.c */
 static int sec_create_path(const char *path)
@@ -192,7 +192,8 @@ static SecCAIssuerCacheRef SecCAIssuerCacheCreate(const char *db_name) {
        int s3e;
     bool create = true;
 
        int s3e;
     bool create = true;
 
-    require(this = (SecCAIssuerCacheRef)malloc(sizeof(struct __SecCAIssuerCache)), errOut);
+    require(this = (SecCAIssuerCacheRef)calloc(sizeof(struct __SecCAIssuerCache), 1), errOut);
+    require_action_quiet((this->queue = dispatch_queue_create("caissuercache", 0)), errOut, s3e = errSecAllocate);
     require_noerr(s3e = sec_sqlite3_open(db_name, &this->s3h, create), errOut);
     this->in_transaction = false;
 
     require_noerr(s3e = sec_sqlite3_open(db_name, &this->s3h, create), errOut);
     this->in_transaction = false;
 
@@ -240,7 +241,10 @@ static SecCAIssuerCacheRef SecCAIssuerCacheCreate(const char *db_name) {
 
 errOut:
        if (this) {
 
 errOut:
        if (this) {
-               sqlite3_close(this->s3h);
+        if (this->queue)
+            dispatch_release(this->queue);
+        if (this->s3h)
+            sqlite3_close(this->s3h);
                free(this);
        }
 
                free(this);
        }
 
@@ -248,42 +252,10 @@ errOut:
 }
 
 static void SecCAIssuerCacheInit(void) {
 }
 
 static void SecCAIssuerCacheInit(void) {
-       static const char *path = kSecCAIssuerCachePath;
-#if NO_SERVER
-    /* Added this block of code back to keep the tests happy for now. */
-       const char *home = getenv("HOME");
-       char buffer[PATH_MAX];
-       size_t homeLen;
-       size_t pathLen = strlen(path);
-       if (home) {
-               homeLen = strlen(home);
-               if (homeLen + pathLen >= sizeof(buffer)) {
-                       return;
-               }
-
-               strlcpy(buffer, home, sizeof(buffer));
-       } else {
-               CFURLRef homeURL = CFCopyHomeDirectoryURLForUser(NULL);
-               if (!homeURL)
-                       return;
-
-               CFURLGetFileSystemRepresentation(homeURL, true, (uint8_t *)buffer,
-                                         sizeof(buffer));
-               CFRelease(homeURL);
-               homeLen = strlen(buffer);
-               buffer[homeLen] = '\0';
-               if (homeLen + pathLen >= sizeof(buffer)) {
-                       return;
-               }
-       }
+    WithPathInKeychainDirectory(CFSTR(kSecCAIssuerFileName), ^(const char *utf8String) {
+        kSecCAIssuerCache = SecCAIssuerCacheCreate(utf8String);
+    });
 
 
-       strlcat(buffer, path, sizeof(buffer));
-
-    path = buffer;
-
-#endif
-
-    kSecCAIssuerCache = SecCAIssuerCacheCreate(path);
     if (kSecCAIssuerCache)
         atexit(SecCAIssuerCacheGC);
 }
     if (kSecCAIssuerCache)
         atexit(SecCAIssuerCacheGC);
 }
@@ -402,19 +374,27 @@ static void _SecCAIssuerCacheFlush(void *context) {
 
 void SecCAIssuerCacheAddCertificate(SecCertificateRef certificate,
                                     CFURLRef uri, CFAbsoluteTime expires) {
 
 void SecCAIssuerCacheAddCertificate(SecCertificateRef certificate,
                                     CFURLRef uri, CFAbsoluteTime expires) {
-    pthread_once(&kSecCAIssuerCacheOnce, SecCAIssuerCacheInit);
+    dispatch_once(&kSecCAIssuerCacheOnce, ^{
+        SecCAIssuerCacheInit();
+    });
     if (!kSecCAIssuerCache)
         return;
 
     if (!kSecCAIssuerCache)
         return;
 
-    _SecCAIssuerCacheAddCertificate(kSecCAIssuerCache, certificate, uri, expires);
+    dispatch_sync(kSecCAIssuerCache->queue, ^{
+        _SecCAIssuerCacheAddCertificate(kSecCAIssuerCache, certificate, uri, expires);
+    });
 }
 
 SecCertificateRef SecCAIssuerCacheCopyMatching(CFURLRef uri) {
 }
 
 SecCertificateRef SecCAIssuerCacheCopyMatching(CFURLRef uri) {
-    pthread_once(&kSecCAIssuerCacheOnce, SecCAIssuerCacheInit);
-    if (!kSecCAIssuerCache)
-        return NULL;
-
-    return _SecCAIssuerCacheCopyMatching(kSecCAIssuerCache, uri);
+    dispatch_once(&kSecCAIssuerCacheOnce, ^{
+        SecCAIssuerCacheInit();
+    });
+    __block SecCertificateRef cert = NULL;
+    if (kSecCAIssuerCache)
+        dispatch_sync(kSecCAIssuerCache->queue, ^{
+            cert = _SecCAIssuerCacheCopyMatching(kSecCAIssuerCache, uri);
+        });
+    return cert;
 }
 
 /* This should be called on a normal non emergency exit. This function
 }
 
 /* This should be called on a normal non emergency exit. This function
@@ -432,11 +412,15 @@ SecCertificateRef SecCAIssuerCacheCopyMatching(CFURLRef uri) {
  */
 void SecCAIssuerCacheGC(void) {
     if (kSecCAIssuerCache)
  */
 void SecCAIssuerCacheGC(void) {
     if (kSecCAIssuerCache)
-        _SecCAIssuerCacheGC(kSecCAIssuerCache);
+        dispatch_sync(kSecCAIssuerCache->queue, ^{
+            _SecCAIssuerCacheGC(kSecCAIssuerCache);
+        });
 }
 
 /* Call this periodically or perhaps when we are exiting due to low memory. */
 void SecCAIssuerCacheFlush(void) {
     if (kSecCAIssuerCache)
 }
 
 /* Call this periodically or perhaps when we are exiting due to low memory. */
 void SecCAIssuerCacheFlush(void) {
     if (kSecCAIssuerCache)
-        _SecCAIssuerCacheFlush(kSecCAIssuerCache);
+        dispatch_sync(kSecCAIssuerCache->queue, ^{
+            _SecCAIssuerCacheFlush(kSecCAIssuerCache);
+        });
 }
 }
index fb5a0886318ebb4b2046e67ec716ebf1c6636615..460b7533be69f93c660bd41e67f73910873b2994 100644 (file)
@@ -37,9 +37,7 @@
 #include <CoreFoundation/CFDate.h>
 #include <CoreFoundation/CFURL.h>
 
 #include <CoreFoundation/CFDate.h>
 #include <CoreFoundation/CFURL.h>
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 
 void SecCAIssuerCacheAddCertificate(SecCertificateRef certificate,
 
 
 void SecCAIssuerCacheAddCertificate(SecCertificateRef certificate,
@@ -53,8 +51,6 @@ void SecCAIssuerCacheGC(void);
 /* Call this periodically or perhaps when we are exiting due to low memory. */
 void SecCAIssuerCacheFlush(void);
 
 /* Call this periodically or perhaps when we are exiting due to low memory. */
 void SecCAIssuerCacheFlush(void);
 
-#if defined(__cplusplus)
-}
-#endif
+__END_DECLS
 
 #endif /* _SECURITY_SECCAISSUERCACHE_H_ */
 
 #endif /* _SECURITY_SECCAISSUERCACHE_H_ */
index 237251283ae40c83dfb69eb85fbb739a3cac7007..d2e8af02c1ad7d2cf4a1c2ce8cad34b7d139a409 100644 (file)
@@ -40,7 +40,7 @@
 #include <Security/SecInternal.h>
 #include <CoreFoundation/CFURL.h>
 #include <CFNetwork/CFHTTPMessage.h>
 #include <Security/SecInternal.h>
 #include <CoreFoundation/CFURL.h>
 #include <CFNetwork/CFHTTPMessage.h>
-#include <security_utilities/debugging.h>
+#include <utilities/debugging.h>
 #include <Security/SecCertificateInternal.h>
 #include <securityd/asynchttp.h>
 #include <stdlib.h>
 #include <Security/SecCertificateInternal.h>
 #include <securityd/asynchttp.h>
 #include <stdlib.h>
@@ -76,8 +76,10 @@ static bool SecCAIssuerRequestIssue(SecCAIssuerRequestRef request) {
                     secdebug("caissuer", "%@", msg);
                     bool done = asynchttp_request(msg, &request->http);
                     CFRelease(msg);
                     secdebug("caissuer", "%@", msg);
                     bool done = asynchttp_request(msg, &request->http);
                     CFRelease(msg);
-                    if (done == false)
+                    if (done == false) {
+                        CFRelease(scheme);
                         return done;
                         return done;
+                    }
                 }
                 secdebug("caissuer", "failed to get %@", issuer);
             } else {
                 }
                 secdebug("caissuer", "failed to get %@", issuer);
             } else {
@@ -159,6 +161,7 @@ static CFArrayRef SecCAIssuerRequestCacheCopyParents(SecCertificateRef cert,
                     SecCAIssuerCacheCopyMatching(issuer));
                 if (parents) {
                     secdebug("caissuer", "cache hit, for %@ no request issued", issuer);
                     SecCAIssuerCacheCopyMatching(issuer));
                 if (parents) {
                     secdebug("caissuer", "cache hit, for %@ no request issued", issuer);
+                   CFRelease(scheme);
                     return parents;
                 }
             }
                     return parents;
                 }
             }
@@ -168,7 +171,7 @@ static CFArrayRef SecCAIssuerRequestCacheCopyParents(SecCertificateRef cert,
     return NULL;
 }
 
     return NULL;
 }
 
-bool SecCAIssuerCopyParents(SecCertificateRef certificate,
+bool SecCAIssuerCopyParents(SecCertificateRef certificate, dispatch_queue_t queue,
     void *context, void (*callback)(void *, CFArrayRef)) {
     CFArrayRef issuers = SecCertificateGetCAIssuers(certificate);
     if (!issuers) {
     void *context, void (*callback)(void *, CFArrayRef)) {
     CFArrayRef issuers = SecCertificateGetCAIssuers(certificate);
     if (!issuers) {
@@ -187,6 +190,7 @@ bool SecCAIssuerCopyParents(SecCertificateRef certificate,
     /* Cache miss, let's issue a network request. */
     SecCAIssuerRequestRef request =
         (SecCAIssuerRequestRef)calloc(1, sizeof(*request));
     /* Cache miss, let's issue a network request. */
     SecCAIssuerRequestRef request =
         (SecCAIssuerRequestRef)calloc(1, sizeof(*request));
+    request->http.queue = queue;
     request->http.completed = SecCAIssuerRequestCompleted;
     CFRetain(certificate);
     request->certificate = certificate;
     request->http.completed = SecCAIssuerRequestCompleted;
     CFRetain(certificate);
     request->certificate = certificate;
index e6768a82de9b878dc63be75f345ee75faaede91d..9f6e31dcceccde58bf00a63e09c0f03111270beb 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <Security/SecCertificate.h>
 #include <CoreFoundation/CFArray.h>
 
 #include <Security/SecCertificate.h>
 #include <CoreFoundation/CFArray.h>
+#include <dispatch/dispatch.h>
 
 bool SecCAIssuerCopyParents(SecCertificateRef certificate,
 
 bool SecCAIssuerCopyParents(SecCertificateRef certificate,
-    void *context, void (*callback)(void *, CFArrayRef));
+    dispatch_queue_t queue, void *context, void (*callback)(void *, CFArrayRef));
diff --git a/sec/securityd/SecDbItem.c b/sec/securityd/SecDbItem.c
new file mode 100644 (file)
index 0000000..34ec0b5
--- /dev/null
@@ -0,0 +1,1504 @@
+/*
+ * Copyright (c) 2012 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * SecDbItem.c - CoreFoundation-based constants and functions representing
+ * database items (certificates, keys, identities, and passwords.)
+ * Created by Michael Brouwer on 11/15/12.
+ */
+
+#include <securityd/SecDbItem.h>
+#include <utilities/SecCFWrappers.h>
+#include <utilities/der_date.h>
+#include <utilities/debugging.h>
+
+#include <Security/SecBasePriv.h>
+#include <Security/SecInternal.h>
+#include <corecrypto/ccsha1.h>
+#include <Security/SecItem.h>
+#include <Security/SecItemPriv.h>
+
+// MARK: type converters
+
+CFStringRef copyString(CFTypeRef obj) {
+    CFTypeID tid = CFGetTypeID(obj);
+    if (tid == CFStringGetTypeID())
+        return CFStringCreateCopy(0, obj);
+    else if (tid == CFDataGetTypeID())
+        return CFStringCreateFromExternalRepresentation(0, obj, kCFStringEncodingUTF8);
+    else
+        return NULL;
+}
+
+CFDataRef copyData(CFTypeRef obj) {
+    CFTypeID tid = CFGetTypeID(obj);
+    if (tid == CFDataGetTypeID()) {
+        return CFDataCreateCopy(0, obj);
+    } else if (tid == CFStringGetTypeID()) {
+        return CFStringCreateExternalRepresentation(0, obj, kCFStringEncodingUTF8, 0);
+    } else if (tid == CFNumberGetTypeID()) {
+        SInt32 value;
+        CFNumberGetValue(obj, kCFNumberSInt32Type, &value);
+        return CFDataCreate(0, (const UInt8 *)&value, sizeof(value));
+    } else {
+        return NULL;
+    }
+}
+
+CFTypeRef copyBlob(CFTypeRef obj) {
+    CFTypeID tid = CFGetTypeID(obj);
+    if (tid == CFDataGetTypeID()) {
+        return CFDataCreateCopy(0, obj);
+    } else if (tid == CFStringGetTypeID()) {
+        return CFStringCreateCopy(0, obj);
+    } else if (tid == CFNumberGetTypeID()) {
+        CFRetain(obj);
+        return obj;
+    } else {
+        return NULL;
+    }
+}
+
+CFDataRef copySHA1(CFTypeRef obj) {
+    CFTypeID tid = CFGetTypeID(obj);
+    if (tid == CFDataGetTypeID() && CFDataGetLength(obj) == CCSHA1_OUTPUT_SIZE) {
+        return CFDataCreateCopy(CFGetAllocator(obj), obj);
+    } else {
+        return NULL;
+    }
+}
+
+CFTypeRef copyNumber(CFTypeRef obj) {
+    CFTypeID tid = CFGetTypeID(obj);
+    if (tid == CFNumberGetTypeID()) {
+        CFRetain(obj);
+        return obj;
+    } else if (tid == CFBooleanGetTypeID()) {
+        SInt32 value = CFBooleanGetValue(obj);
+        return CFNumberCreate(0, kCFNumberSInt32Type, &value);
+    } else if (tid == CFStringGetTypeID()) {
+        SInt32 value = CFStringGetIntValue(obj);
+        CFStringRef t = CFStringCreateWithFormat(0, 0, CFSTR("%ld"), (long) value);
+        /* If a string converted to an int isn't equal to the int printed as
+           a string, return a CFStringRef instead. */
+        if (!CFEqual(t, obj)) {
+            CFRelease(t);
+            return CFStringCreateCopy(0, obj);
+        }
+        CFRelease(t);
+        return CFNumberCreate(0, kCFNumberSInt32Type, &value);
+    } else
+        return NULL;
+}
+
+CFDateRef copyDate(CFTypeRef obj) {
+    CFTypeID tid = CFGetTypeID(obj);
+    if (tid == CFDateGetTypeID()) {
+        CFRetain(obj);
+        return obj;
+    } else
+        return NULL;
+}
+
+// MARK: SecDbColumn accessors, to retrieve values as CF types in SecDbStep.
+
+static CFDataRef SecDbColumnCopyData(CFAllocatorRef allocator, sqlite3_stmt *stmt, int col, CFErrorRef *error) {
+    return CFDataCreate(allocator, sqlite3_column_blob(stmt, col),
+                        sqlite3_column_bytes(stmt, col));
+    //return CFDataCreateWithBytesNoCopy(0, sqlite3_column_blob(stmt, col),
+    //                                   sqlite3_column_bytes(stmt, col),
+    //                                   kCFAllocatorNull);
+}
+
+static CFDateRef SecDbColumnCopyDate(CFAllocatorRef allocator, sqlite3_stmt *stmt, int col, CFErrorRef *error) {
+    return CFDateCreate(allocator, sqlite3_column_double(stmt, col));
+}
+
+static CFNumberRef SecDbColumnCopyDouble(CFAllocatorRef allocator, sqlite3_stmt *stmt, int col, CFErrorRef *error) {
+    double number = sqlite3_column_double(stmt, col);
+    return CFNumberCreate(allocator, kCFNumberDoubleType, &number);
+}
+
+static CFNumberRef SecDbColumnCopyNumber64(CFAllocatorRef allocator, sqlite3_stmt *stmt, int col, CFErrorRef *error) {
+    sqlite_int64 number = sqlite3_column_int64(stmt, col);
+    return CFNumberCreate(allocator, kCFNumberSInt64Type, &number);
+}
+
+static CFNumberRef SecDbColumnCopyNumber(CFAllocatorRef allocator, sqlite3_stmt *stmt, int col, CFErrorRef *error) {
+    sqlite_int64 number = sqlite3_column_int64(stmt, col);
+    if (INT32_MIN <= number && number <= INT32_MAX) {
+        int32_t num32 = (int32_t)number;
+        return CFNumberCreate(allocator, kCFNumberSInt32Type, &num32);
+    } else {
+        return CFNumberCreate(allocator, kCFNumberSInt64Type, &number);
+    }
+}
+
+static CFStringRef SecDbColumnCopyString(CFAllocatorRef allocator, sqlite3_stmt *stmt, int col, CFErrorRef *error) {
+    const unsigned char *text = sqlite3_column_text(stmt, col);
+    return CFStringCreateWithBytes(allocator, text, strlen((const char *)text), kCFStringEncodingUTF8, false);
+}
+
+// MARK: SecDbClass helpers
+
+const SecDbAttr *SecDbClassAttrWithKind(const SecDbClass *class, SecDbAttrKind kind, CFErrorRef *error) {
+    const SecDbAttr *result = NULL;
+    SecDbForEachAttr(class, desc) {
+        if (desc->kind == kind)
+            result = desc;
+    }
+
+    if (!result)
+        SecError(errSecInternal, error, CFSTR("Can't find attribute of kind %d in class %@"), kind, class->name);
+
+    return result;
+}
+
+// MARK: SecDbAttr helpers
+
+static bool SecDbIsTombstoneDbSelectAttr(const SecDbAttr *attr) {
+    return attr->flags & kSecDbPrimaryKeyFlag || attr->kind == kSecDbTombAttr;
+}
+
+#if 0
+static bool SecDbIsTombstoneDbInsertAttr(const SecDbAttr *attr) {
+    return SecDbIsTombstoneDbSelectAttr(attr) || attr->kind == kSecDbAccessAttr || attr->kind == kSecDbCreationDateAttr || attr->kind == kSecDbModificationDateAttr;
+}
+#endif
+
+static bool SecDbIsTombstoneDbUpdateAttr(const SecDbAttr *attr) {
+    return SecDbIsTombstoneDbSelectAttr(attr) || attr->kind == kSecDbAccessAttr || attr->kind == kSecDbCreationDateAttr || attr->kind == kSecDbRowIdAttr;
+}
+
+static bool SecDbAttrBind(const SecDbAttr *attr, sqlite3_stmt *stmt, int col, CFTypeRef value, CFErrorRef *error) {
+    bool ok = true;
+    if (value && !CFEqual(kCFNull, value) && attr->flags & kSecDbSHA1ValueInFlag) {
+        CFDataRef data = copyData(value);
+        if (!data) {
+            SecError(errSecInternal, error, CFSTR("failed to get attribute %@ data"), attr->name);
+            return false;
+        }
+
+        CFMutableDataRef digest = CFDataCreateMutable(kCFAllocatorDefault, CCSHA1_OUTPUT_SIZE);
+        CFDataSetLength(digest, CCSHA1_OUTPUT_SIZE);
+        /* 64 bits cast: worst case is we generate the wrong hash */
+        assert((unsigned long)CFDataGetLength(data)<UINT32_MAX); /* Debug check. Correct as long as CFIndex is long */
+        ccdigest(ccsha1_di(), CFDataGetLength(data), CFDataGetBytePtr(data), CFDataGetMutableBytePtr(digest));
+        CFRelease(data);
+        ok &= SecDbBindObject(stmt, col, digest, error);
+        CFRelease(digest);
+    } else {
+        ok &= SecDbBindObject(stmt, col, value, error);
+    }
+    return ok;
+}
+
+// MARK: SecDbItem
+
+CFTypeRef SecDbItemGetCachedValueWithName(SecDbItemRef item, CFStringRef name) {
+    return CFDictionaryGetValue(item->attributes, name);
+}
+
+static CFTypeRef SecDbItemGetCachedValue(SecDbItemRef item, const SecDbAttr *desc) {
+    return CFDictionaryGetValue(item->attributes, desc->name);
+}
+
+CFMutableDictionaryRef SecDbItemCopyPListWithMask(SecDbItemRef item, CFOptionFlags mask, CFErrorRef *error) {
+    CFMutableDictionaryRef dict = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
+    SecDbForEachAttrWithMask(item->class, desc, mask) {
+        CFTypeRef value = SecDbItemGetValue(item, desc, error);
+        if (value) {
+            if (!CFEqual(kCFNull, value)) {
+                CFDictionarySetValue(dict, desc->name, value);
+            } else if (desc->flags & kSecDbNotNullFlag) {
+                SecError(errSecInternal, error, CFSTR("attribute %@ has NULL value"), desc->name);
+                secerror("%@", error ? *error : (CFErrorRef)CFSTR("error == NULL"));
+                CFReleaseNull(dict);
+                break;
+            }
+        } else {
+            CFReleaseNull(dict);
+            break;
+        }
+    }
+    return dict;
+}
+
+static CFDataRef SecDbItemCopyDERWithMask(SecDbItemRef item, CFOptionFlags mask, CFErrorRef *error) {
+    CFDataRef der = NULL;
+    CFMutableDictionaryRef dict = SecDbItemCopyPListWithMask(item, mask, error);
+    if (dict) {
+        der = kc_plist_copy_der(dict, error);
+        CFRelease(dict);
+    }
+    return der;
+}
+
+static CFDataRef SecDbItemCopyDigestWithMask(SecDbItemRef item, CFOptionFlags mask, CFErrorRef *error) {
+    CFDataRef digest = NULL;
+    CFDataRef der = SecDbItemCopyDERWithMask(item, mask, error);
+    if (der) {
+        digest = kc_copy_sha1(CFDataGetLength(der), CFDataGetBytePtr(der), error);
+        CFRelease(der);
+    }
+    return digest;
+}
+
+static CFDataRef SecDbItemCopyPrimaryKey(SecDbItemRef item, CFErrorRef *error) {
+    return SecDbItemCopyDigestWithMask(item, kSecDbPrimaryKeyFlag, error);
+}
+
+static CFDataRef SecDbItemCopySHA1(SecDbItemRef item, CFErrorRef *error) {
+    return SecDbItemCopyDigestWithMask(item, kSecDbInHashFlag, error);
+}
+
+static CFDataRef SecDbItemCopyUnencryptedData(SecDbItemRef item, CFErrorRef *error) {
+    return SecDbItemCopyDERWithMask(item, kSecDbInCryptoDataFlag, error);
+}
+
+static keyclass_t SecDbItemParseKeyclass(CFTypeRef value, CFErrorRef *error) {
+    if (!isString(value)) {
+        SecError(errSecParam, error, CFSTR("accessible attribute %@ not a string"), value);
+    } else if (CFEqual(value, kSecAttrAccessibleWhenUnlocked)) {
+        return key_class_ak;
+    } else if (CFEqual(value, kSecAttrAccessibleAfterFirstUnlock)) {
+        return key_class_ck;
+    } else if (CFEqual(value, kSecAttrAccessibleAlways)) {
+        return key_class_dk;
+    } else if (CFEqual(value, kSecAttrAccessibleWhenUnlockedThisDeviceOnly)) {
+        return key_class_aku;
+    } else if (CFEqual(value, kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly)) {
+        return key_class_cku;
+    } else if (CFEqual(value, kSecAttrAccessibleAlwaysThisDeviceOnly)) {
+        return key_class_dku;
+    } else {
+        SecError(errSecParam, error, CFSTR("accessible attribute %@ unknown"), value);
+    }
+    return 0;
+}
+
+keyclass_t SecDbItemGetKeyclass(SecDbItemRef item, CFErrorRef *error) {
+    if (!item->keyclass) {
+        const SecDbAttr *desc = SecDbClassAttrWithKind(item->class, kSecDbAccessAttr, error);
+        if (desc) {
+            CFTypeRef value = SecDbItemGetValue(item, desc, error);
+            if (value) {
+                item->keyclass = SecDbItemParseKeyclass(value, error);
+            }
+        }
+    }
+    return item->keyclass;
+}
+
+static CFDataRef SecDbItemCopyEncryptedData(SecDbItemRef item, CFErrorRef *error) {
+    CFDataRef edata = NULL;
+    CFDataRef plain = SecDbItemCopyUnencryptedData(item, error);
+    if (plain) {
+        keyclass_t keyclass = SecDbItemGetKeyclass(item, error);
+        if (keyclass) {
+            if (ks_encrypt_data(item->keybag, keyclass, plain, &edata, error)) {
+                item->_edataState = kSecDbItemEncrypting;
+            } else {
+                seccritical("ks_encrypt_data (db): failed: %@", error ? *error : (CFErrorRef)CFSTR(""));
+            }
+        }
+        CFRelease(plain);
+    }
+
+    return edata;
+}
+
+CFDataRef SecDbItemCopyEncryptedDataToBackup(SecDbItemRef item, uint64_t handle, CFErrorRef *error) {
+    CFDataRef edata = NULL;
+    keybag_handle_t keybag = (keybag_handle_t)handle;
+    CFDataRef plain = SecDbItemCopyUnencryptedData(item, error);
+    if (plain) {
+        keyclass_t keyclass = SecDbItemGetKeyclass(item, error);
+        if (keyclass) {
+            if (!ks_encrypt_data(keybag, keyclass, plain, &edata, error))
+                seccritical("ks_encrypt_data (db): failed: %@", error ? *error : (CFErrorRef)CFSTR(""));
+        }
+        CFRelease(plain);
+    }
+    return edata;
+}
+
+static bool SecDbItemEnsureDecrypted(SecDbItemRef item, CFErrorRef *error) {
+
+    // If we haven't yet decrypted the item, make sure we do so now
+    bool result = true;
+    if (item->_edataState == kSecDbItemEncrypted) {
+        const SecDbAttr *attr = SecDbClassAttrWithKind(item->class, kSecDbEncryptedDataAttr, error);
+        if (attr) {
+            CFDataRef edata = SecDbItemGetCachedValue(item, attr);
+            if (!edata)
+                return SecError(errSecInternal, error, CFSTR("state= encrypted but edata is NULL"));
+            // Decrypt calls set value a bunch of times which clears our edata and changes our state.
+            item->_edataState = kSecDbItemDecrypting;
+            result = SecDbItemDecrypt(item, edata, error);
+            if (result)
+                item->_edataState = kSecDbItemClean;
+            else
+                item->_edataState = kSecDbItemEncrypted;
+        }
+    }
+    return result;
+}
+
+// Only called if cached value is not found.
+static CFTypeRef SecDbItemCopyValue(SecDbItemRef item, const SecDbAttr *attr, CFErrorRef *error) {
+    CFTypeRef value = NULL;
+    switch (attr->kind) {
+        case kSecDbSHA1Attr:
+            value = SecDbItemCopySHA1(item, error);
+            break;
+        case kSecDbEncryptedDataAttr:
+            value = SecDbItemCopyEncryptedData(item, error);
+            break;
+        case kSecDbPrimaryKeyAttr:
+            value = SecDbItemCopyPrimaryKey(item, error);
+            break;
+        case kSecDbAccessAttr:
+        case kSecDbStringAttr:
+        case kSecDbBlobAttr:
+            if (attr->flags & kSecDbNotNullFlag) {
+                if (attr->flags & kSecDbDefault0Flag) {
+                    value = CFSTR("0");
+                    break;
+                } else if (attr->kind != kSecDbBlobAttr && attr->flags & kSecDbDefaultEmptyFlag) {
+                    // blob drops through to data everything else is empty string
+                    value = CFSTR("");
+                    break;
+                }
+            }
+            //DROPTHROUGH
+        case kSecDbDataAttr:
+            if (attr->flags & kSecDbNotNullFlag && attr->flags & kSecDbDefaultEmptyFlag) {
+                value = CFDataCreate(CFGetAllocator(item), NULL, 0);
+            } else {
+                value = kCFNull;
+            }
+            break;
+        case kSecDbNumberAttr:
+        case kSecDbSyncAttr:
+        case kSecDbTombAttr:
+            if (attr->flags & kSecDbNotNullFlag) {
+                int32_t zero = 0;
+                value = CFNumberCreate(CFGetAllocator(item), kCFNumberSInt32Type, &zero);
+            } else {
+                value = kCFNull;
+            }
+            break;
+        case kSecDbDateAttr:
+            if (attr->flags & kSecDbNotNullFlag && attr->flags & kSecDbDefault0Flag) {
+                value = CFDateCreate(kCFAllocatorDefault, 0.0);
+            } else {
+                value = kCFNull;
+            }
+            break;
+        case kSecDbRowIdAttr:
+            if (attr->flags & kSecDbNotNullFlag) {
+                // No can do, error?
+            }
+            value = kCFNull;
+            break;
+        case kSecDbCreationDateAttr:
+        case kSecDbModificationDateAttr:
+            value = CFDateCreate(CFGetAllocator(item), CFAbsoluteTimeGetCurrent());
+            break;
+    }
+
+    return value;
+}
+
+// SecDbItemGetValue will return kCFNull if there is no value for an attribute and this was not
+// an error.  It will return NULL and optionally set *error if there was an error computing an
+// attribute, or if a required attribute was missing a value and had no known way to compute
+// it's value.
+CF_RETURNS_NOT_RETAINED CFTypeRef SecDbItemGetValue(SecDbItemRef item, const SecDbAttr *desc, CFErrorRef *error) {
+    // Propagate chained errors
+    if (!desc)
+        return NULL;
+
+    if (desc->flags & kSecDbInCryptoDataFlag) {
+        if (!SecDbItemEnsureDecrypted(item, error))
+            return NULL;
+    }
+
+    CFTypeRef value = SecDbItemGetCachedValue(item, desc);
+    if (!value) {
+        value = SecDbItemCopyValue(item, desc, error);
+        if (value) {
+            if (!CFEqual(kCFNull, value)) {
+                SecDbItemSetValue(item, desc, value, error);
+                CFRelease(value);
+                value = SecDbItemGetCachedValue(item, desc);
+            }
+        }
+    }
+    return value;
+}
+
+static bool SecDbItemGetBoolValue(SecDbItemRef item, const SecDbAttr *desc, bool *bvalue, CFErrorRef *error) {
+    CFTypeRef value = SecDbItemGetValue(item, desc, error);
+    if (!value)
+        return false;
+    char cvalue;
+    *bvalue = (isNumber(value) && CFNumberGetValue(value, kCFNumberCharType, &cvalue) && cvalue == 1);
+    return true;
+}
+
+static CFStringRef SecDbItemCopyDescription(CFTypeRef cf) {
+#if 0 //defined(DEBUG) && DEBUG != 0
+    SecDbItemRef item = (SecDbItemRef)cf;
+    CFMutableStringRef desc = CFStringCreateMutable(CFGetAllocator(cf), 0);
+    CFStringAppendFormat(desc, NULL, CFSTR("<%@"), item->class->name);
+    SecDbForEachAttr(item->class, attr) {
+            CFTypeRef value = SecDbItemGetValue(item, attr, NULL);
+            if (value) {
+                CFStringAppend(desc, CFSTR(","));
+                CFStringAppend(desc, attr->name);
+                CFStringAppend(desc, CFSTR("="));
+                if (CFEqual(CFSTR("data"), attr->name)) {
+                    CFStringAppendEncryptedData(desc, value);
+                } else if (CFEqual(CFSTR("v_Data"), attr->name)) {
+                    CFStringAppend(desc, CFSTR("<?>"));
+                } else if (isData(value)) {
+                    CFStringAppendHexData(desc, value);
+                } else {
+                    CFStringAppendFormat(desc, 0, CFSTR("%@"), value);
+                }
+            }
+    }
+    CFStringAppend(desc, CFSTR(">"));
+#else
+    SecDbItemRef item = (SecDbItemRef)cf;
+    const UInt8 zero4[4] = {};
+    const UInt8 *pk = &zero4[0], *sha1 = &zero4[0];
+    char sync = 0;
+    char tomb = 0;
+    SInt64 rowid = 0;
+    CFStringRef access = NULL;
+    uint8_t mdatbuf[32] = {};
+    uint8_t *mdat = &mdatbuf[0];
+    CFMutableStringRef attrs = CFStringCreateMutable(kCFAllocatorDefault, 0);
+    CFStringRef agrp = NULL;
+
+    SecDbForEachAttr(item->class, attr) {
+        CFTypeRef value;
+        switch (attr->kind) {
+            case kSecDbBlobAttr:
+            case kSecDbDataAttr:
+            case kSecDbStringAttr:
+            case kSecDbNumberAttr:
+            case kSecDbDateAttr:
+            case kSecDbEncryptedDataAttr:
+                if (attr->flags & (kSecDbReturnAttrFlag | kSecDbReturnDataFlag) && (value = SecDbItemGetValue(item, attr, NULL)) && !CFEqual(value, kCFNull)) {
+                    if (isString(value) && CFEqual(attr->name, kSecAttrAccessGroup)) {
+                        agrp = value;
+                    } else {
+                        // We don't log these, just record that we saw the attribute.
+                        CFStringAppend(attrs, CFSTR(","));
+                        CFStringAppend(attrs, attr->name);
+                    }
+                }
+                break;
+            case kSecDbCreationDateAttr:
+                // We don't care about this and every object has one.
+                break;
+            case kSecDbModificationDateAttr:
+                value = SecDbItemGetValue(item, attr, NULL);
+                if (isDate(value))
+                    mdat = der_encode_generalizedtime_body(CFDateGetAbsoluteTime(value), NULL, mdat, &mdatbuf[31]);
+                break;
+            case kSecDbSHA1Attr:
+                value = SecDbItemGetValue(item, attr, NULL);
+                if (isData(value))
+                    sha1 = CFDataGetBytePtr(value);
+                break;
+            case kSecDbRowIdAttr:
+                value = SecDbItemGetValue(item, attr, NULL);
+                if (isNumber(value))
+                    CFNumberGetValue(value, kCFNumberSInt64Type, &rowid);
+                break;
+            case kSecDbPrimaryKeyAttr:
+                value = SecDbItemGetValue(item, attr, NULL);
+                if (isData(value))
+                    pk = CFDataGetBytePtr(value);
+                break;
+            case kSecDbSyncAttr:
+                value = SecDbItemGetValue(item, attr, NULL);
+                if (isNumber(value))
+                    CFNumberGetValue(value, kCFNumberCharType, &sync);
+                break;
+            case kSecDbTombAttr:
+                value = SecDbItemGetValue(item, attr, NULL);
+                if (isNumber(value))
+                    CFNumberGetValue(value, kCFNumberCharType, &tomb);
+                break;
+            case kSecDbAccessAttr:
+                value = SecDbItemGetValue(item, attr, NULL);
+                if (isString(value))
+                    access = value;
+                break;
+        }
+    }
+
+    CFStringRef desc = CFStringCreateWithFormat(CFGetAllocator(cf), NULL,
+        CFSTR(
+              "%s,"
+              "%@,"
+              "%02X%02X%02X%02X,"
+              "%s,"
+              "%@,"
+              "%@,"
+              "%"PRId64
+              "%@,"
+              "%s,"
+              "%02X%02X%02X%02X"),
+        tomb ? "T" : "O",
+        item->class->name,
+        pk[0], pk[1], pk[2], pk[3],
+        sync ? "S" : "L",
+        access,
+        agrp,
+        rowid,
+        attrs,
+        mdat,
+        sha1[0], sha1[1], sha1[2], sha1[3]);
+    CFReleaseSafe(attrs);
+#endif
+
+    return desc;
+}
+
+static void SecDbItemDestroy(CFTypeRef cf) {
+    SecDbItemRef item = (SecDbItemRef)cf;
+    CFReleaseSafe(item->attributes);
+}
+
+static CFHashCode SecDbItemHash(CFTypeRef cf) {
+    SecDbItemRef item = (SecDbItemRef)cf;
+    CFDataRef digest = SecDbItemGetSHA1(item, NULL);
+    CFHashCode code;
+    const UInt8 *p = CFDataGetBytePtr(digest);
+    // Read first 8 bytes of digest in order
+    code = p[0] + ((p[1] + ((p[2] + ((p[3] + ((p[4] + ((p[5] + ((p[6] + (p[7] << 8)) << 8)) << 8)) << 8)) << 8)) << 8)) << 8);
+    return code;
+}
+
+static Boolean SecDbItemCompare(CFTypeRef cf1, CFTypeRef cf2) {
+    SecDbItemRef item1 = (SecDbItemRef)cf1;
+    SecDbItemRef item2 = (SecDbItemRef)cf2;
+    CFDataRef digest1 = NULL;
+    CFDataRef digest2 = NULL;
+    if (item1)
+        digest1 = SecDbItemGetSHA1(item1, NULL);
+    if (item2)
+        digest2 = SecDbItemGetSHA1(item2, NULL);
+    Boolean equal = CFEqual(digest1, digest2);
+    return equal;
+}
+
+CFGiblisWithHashFor(SecDbItem)
+
+static SecDbItemRef SecDbItemCreate(CFAllocatorRef allocator, const SecDbClass *class, keybag_handle_t keybag) {
+    SecDbItemRef item = CFTypeAllocate(SecDbItem, struct SecDbItem, allocator);
+    item->class = class;
+    item->attributes = CFDictionaryCreateMutableForCFTypes(allocator);
+    item->keybag = keybag;
+    item->_edataState = kSecDbItemDirty;
+    return item;
+}
+
+const SecDbClass *SecDbItemGetClass(SecDbItemRef item) {
+    return item->class;
+}
+
+const keybag_handle_t SecDbItemGetKeybag(SecDbItemRef item) {
+    return item->keybag;
+}
+
+bool SecDbItemSetKeybag(SecDbItemRef item, keybag_handle_t keybag, CFErrorRef *error) {
+    if (!SecDbItemEnsureDecrypted(item, error))
+        return false;
+    if (item->keybag != keybag) {
+        item->keybag = keybag;
+        if (item->_edataState == kSecDbItemClean) {
+            SecDbItemSetValue(item, SecDbClassAttrWithKind(item->class, kSecDbEncryptedDataAttr, NULL), kCFNull, NULL);
+        }
+    }
+
+    return true;
+}
+
+bool SecDbItemSetValue(SecDbItemRef item, const SecDbAttr *desc, CFTypeRef value, CFErrorRef *error) {
+    // Propagate chained errors.
+    if (!desc)
+        return false;
+
+    bool changed = false;
+    CFTypeRef attr = NULL;
+    if (desc->flags & kSecDbInCryptoDataFlag)
+        if (!SecDbItemEnsureDecrypted(item, error))
+            return false;
+
+    switch (desc->kind) {
+        case kSecDbPrimaryKeyAttr:
+        case kSecDbDataAttr:
+            attr = copyData(value);
+            break;
+        case kSecDbEncryptedDataAttr:
+            attr = copyData(value);
+            if (attr) {
+                if (item->_edataState == kSecDbItemEncrypting)
+                    item->_edataState = kSecDbItemClean;
+                else
+                    item->_edataState = kSecDbItemEncrypted;
+            } else if (!value || CFEqual(kCFNull, value)) {
+                item->_edataState = kSecDbItemDirty;
+            }
+            break;
+        case kSecDbBlobAttr:
+            attr = copyBlob(value);
+            break;
+        case kSecDbDateAttr:
+        case kSecDbCreationDateAttr:
+        case kSecDbModificationDateAttr:
+            attr = copyDate(value);
+            break;
+        case kSecDbNumberAttr:
+        case kSecDbSyncAttr:
+        case kSecDbTombAttr:
+        case kSecDbRowIdAttr:
+            attr = copyNumber(value);
+            break;
+        case kSecDbAccessAttr:
+        case kSecDbStringAttr:
+            attr = copyString(value);
+            break;
+        case kSecDbSHA1Attr:
+            attr = copySHA1(value);
+            break;
+    }
+
+    if (attr) {
+        CFTypeRef ovalue = CFDictionaryGetValue(item->attributes, desc->name);
+        changed = (!ovalue || !CFEqual(ovalue, attr));
+        CFDictionarySetValue(item->attributes, desc->name, attr);
+        CFRelease(attr);
+    } else {
+        if (value && !CFEqual(kCFNull, value)) {
+            SecError(errSecItemInvalidValue, error, CFSTR("attribute %@: value: %@ failed to convert"), desc->name, value);
+            return false;
+        }
+        CFTypeRef ovalue = CFDictionaryGetValue(item->attributes, desc->name);
+        changed = (ovalue && !CFEqual(ovalue, kCFNull));
+        CFDictionaryRemoveValue(item->attributes, desc->name);
+    }
+
+    if (changed) {
+        if (desc->flags & kSecDbInHashFlag)
+            SecDbItemSetValue(item, SecDbClassAttrWithKind(item->class, kSecDbSHA1Attr, NULL), kCFNull, NULL);
+        if (desc->flags & kSecDbPrimaryKeyFlag)
+            SecDbItemSetValue(item, SecDbClassAttrWithKind(item->class, kSecDbPrimaryKeyAttr, NULL), kCFNull, NULL);
+        if (desc->flags & kSecDbInCryptoDataFlag && item->_edataState == kSecDbItemClean)
+            SecDbItemSetValue(item, SecDbClassAttrWithKind(item->class, kSecDbEncryptedDataAttr, NULL), kCFNull, NULL);
+    }
+
+    return true;
+}
+
+bool SecDbItemSetValues(SecDbItemRef item, CFDictionaryRef values, CFErrorRef *error) {
+    SecDbForEachAttr(item->class, attr) {
+        CFTypeRef value = CFDictionaryGetValue(values, attr->name);
+        if (value && !SecDbItemSetValue(item, attr, value, error))
+            return false;
+    }
+    return true;
+}
+
+bool SecDbItemSetValueWithName(SecDbItemRef item, CFStringRef name, CFTypeRef value, CFErrorRef *error) {
+    SecDbForEachAttr(item->class, attr) {
+        if (CFEqual(attr->name, name)) {
+            return SecDbItemSetValue(item, attr, value, error);
+        }
+    }
+    return false;
+}
+
+static bool SecDbItemSetNumber(SecDbItemRef item, const SecDbAttr *desc, int32_t number, CFErrorRef *error) {
+    bool ok = true;
+    CFNumberRef value = CFNumberCreate(CFGetAllocator(item), kCFNumberSInt32Type, &number);
+    if (value) {
+        ok = SecDbItemSetValue(item, desc, value, error);
+        CFRelease(value);
+    } else {
+        ok = SecError(errSecInternal, error, CFSTR("Failed to create CFNumber for %" PRId32), number);
+    }
+    return ok;
+}
+
+bool SecDbItemSetKeyclass(SecDbItemRef item, keyclass_t keyclass, CFErrorRef *error) {
+    bool ok = SecDbItemSetValue(item, SecDbClassAttrWithKind(item->class, kSecDbEncryptedDataAttr, error), kCFNull, error);
+    if (ok) {
+        item->_edataState = kSecDbItemDirty;
+        ok = SecDbItemSetNumber(item, SecDbClassAttrWithKind(item->class, kSecDbAccessAttr, error), keyclass, error);
+    }
+    return ok;
+}
+
+SecDbItemRef SecDbItemCreateWithAttributes(CFAllocatorRef allocator, const SecDbClass *class, CFDictionaryRef attributes, keybag_handle_t keybag, CFErrorRef *error) {
+    SecDbItemRef item = SecDbItemCreate(kCFAllocatorDefault, class, keybag);
+    if (item && !SecDbItemSetValues(item, attributes, error))
+        CFReleaseNull(item);
+    return item;
+}
+
+static CFTypeRef
+SecDbColumnCopyValueWithAttr(CFAllocatorRef allocator, sqlite3_stmt *stmt, const SecDbAttr *attr, int col, CFErrorRef *error) {
+    CFTypeRef value = NULL;
+    switch (attr->kind) {
+        case kSecDbDateAttr:
+        case kSecDbCreationDateAttr:
+        case kSecDbModificationDateAttr:
+            value = SecDbColumnCopyDate(allocator, stmt, col, error);
+            break;
+        case kSecDbBlobAttr:
+            switch (sqlite3_column_type(stmt, col)) {
+                case SQLITE_INTEGER:
+                    value = SecDbColumnCopyNumber(allocator, stmt, col, error);
+                    break;
+                case SQLITE_FLOAT:
+                    value = SecDbColumnCopyDouble(allocator, stmt, col, error);
+                    break;
+                case SQLITE_TEXT:
+                    value = SecDbColumnCopyString(allocator, stmt, col, error);
+                    break;
+                case SQLITE_BLOB:
+                    value = SecDbColumnCopyData(allocator, stmt, col, error);
+                    break;
+                case SQLITE_NULL:
+                    value = kCFNull;
+                    break;
+            }
+            break;
+        case kSecDbAccessAttr:
+        case kSecDbStringAttr:
+            value = SecDbColumnCopyString(allocator, stmt, col, error);
+            break;
+        case kSecDbDataAttr:
+        case kSecDbSHA1Attr:
+        case kSecDbPrimaryKeyAttr:
+            value = SecDbColumnCopyData(allocator, stmt, col, error);
+            break;
+        case kSecDbEncryptedDataAttr:
+            value = SecDbColumnCopyData(allocator, stmt, col, error);
+            break;
+        case kSecDbSyncAttr:
+        case kSecDbTombAttr:
+        case kSecDbNumberAttr:
+            value = SecDbColumnCopyNumber(allocator, stmt, col, error);
+            break;
+        case kSecDbRowIdAttr:
+            value = SecDbColumnCopyNumber64(allocator, stmt, col, error);
+            break;
+    }
+    return value;
+}
+
+SecDbItemRef SecDbItemCreateWithStatement(CFAllocatorRef allocator, const SecDbClass *class, sqlite3_stmt *stmt, keybag_handle_t keybag, CFErrorRef *error, bool (^return_attr)(const SecDbAttr *attr)) {
+    SecDbItemRef item = SecDbItemCreate(allocator, class, keybag);
+    int col = 0;
+    SecDbForEachAttr(class, attr) {
+        if (return_attr(attr)) {
+            CFTypeRef value = SecDbColumnCopyValueWithAttr(allocator, stmt, attr, col++, error);
+            if (value) {
+                SecDbItemSetValue(item, attr, value, error);
+                CFRelease(value);
+            }
+        }
+    }
+
+    return item;
+}
+
+SecDbItemRef SecDbItemCreateWithEncryptedData(CFAllocatorRef allocator, const SecDbClass *class,
+                                              CFDataRef edata, keybag_handle_t keybag, CFErrorRef *error) {
+    SecDbItemRef item = SecDbItemCreate(allocator, class, keybag);
+    const SecDbAttr *edata_attr = SecDbClassAttrWithKind(class, kSecDbEncryptedDataAttr, error);
+    if (edata_attr) {
+        if (!SecDbItemSetValue(item, edata_attr, edata, error))
+            CFReleaseNull(item);
+    }
+    return item;
+}
+
+#if 0
+SecDbItemRef SecDbItemCreateWithRowId(CFAllocatorRef allocator, const SecDbClass *class, sqlite_int64 row_id, keybag_handle_t keybag, CFErrorRef *error) {
+    SecDbItemRef item = SecDbItemCreate(allocator, class, keybag);
+    if (!SecDbItemSetRowId(item, row_id, error))
+        CFReleaseNull(item);
+    return item;
+}
+#endif
+
+SecDbItemRef SecDbItemCopyWithUpdates(SecDbItemRef item, CFDictionaryRef updates, CFErrorRef *error) {
+    SecDbItemRef new_item = SecDbItemCreate(CFGetAllocator(item), item->class, item->keybag);
+    SecDbForEachAttr(item->class, attr) {
+        // Copy each attribute, except the mod date attribute (it will be reset to now when needed),
+        // from the updates dict unless it's not there in which case we copy the attribute from the passed in item.
+        if (attr->kind != kSecDbModificationDateAttr && attr->kind != kSecDbEncryptedDataAttr && attr->kind != kSecDbSHA1Attr && attr->kind != kSecDbPrimaryKeyAttr) {
+            CFTypeRef value = NULL;
+            if (CFDictionaryGetValueIfPresent(updates, attr->name, &value)) {
+                if (!value)
+                    SecError(errSecParam, error, CFSTR("NULL value in dictionary"));
+            } else {
+                value = SecDbItemGetValue(item, attr, error);
+            }
+            if (!value || !SecDbItemSetValue(new_item, attr, value, error)) {
+                CFReleaseNull(new_item);
+                break;
+            }
+        }
+    }
+    return new_item;
+}
+
+// Ensure that the date value of attr of new_item is greater than that of old_item.
+static bool SecDbItemMakeAttrYounger(SecDbItemRef new_item, SecDbItemRef old_item, const SecDbAttr *attr, CFErrorRef *error) {
+    CFDateRef old_date = SecDbItemGetValue(old_item, attr, error);
+    if (!old_date)
+        return false;
+    CFDateRef new_date = SecDbItemGetValue(new_item, attr, error);
+    if (!new_date)
+        return false;
+    bool ok = true;
+    if (CFDateCompare(new_date, old_date, NULL) != kCFCompareGreaterThan) {
+        CFDateRef adjusted_date = CFDateCreate(kCFAllocatorDefault, CFDateGetAbsoluteTime(old_date) + 0.001);
+        if (adjusted_date) {
+            ok = SecDbItemSetValue(new_item, attr, adjusted_date, error);
+            CFRelease(adjusted_date);
+        }
+    }
+    return ok;
+}
+
+// Ensure that the mod date of new_item is greater than that of old_item.
+static bool SecDbItemMakeYounger(SecDbItemRef new_item, SecDbItemRef old_item, CFErrorRef *error) {
+    const SecDbAttr *attr = SecDbClassAttrWithKind(new_item->class, kSecDbModificationDateAttr, error);
+    return attr && SecDbItemMakeAttrYounger(new_item, old_item, attr, error);
+}
+
+SecDbItemRef SecDbItemCopyTombstone(SecDbItemRef item, CFErrorRef *error) {
+    SecDbItemRef new_item = SecDbItemCreate(CFGetAllocator(item), item->class, item->keybag);
+    SecDbForEachAttr(item->class, attr) {
+        if (attr->kind == kSecDbTombAttr) {
+            // Set the tomb attr to true to indicate a tombstone.
+            if (!SecDbItemSetValue(new_item, attr, kCFBooleanTrue, error)) {
+                CFReleaseNull(new_item);
+                break;
+            }
+        } else if (SecDbIsTombstoneDbUpdateAttr(attr)) {
+            // Copy all primary key attributes and creation timestamps from the original item.
+            CFTypeRef value = SecDbItemGetValue(item, attr, error);
+            if (!value || (!CFEqual(kCFNull, value) && !SecDbItemSetValue(new_item, attr, value, error))) {
+                CFReleaseNull(new_item);
+                break;
+            }
+        } else if (attr->kind == kSecDbModificationDateAttr) {
+            if (!SecDbItemMakeAttrYounger(new_item, item, attr, error)) {
+                CFReleaseNull(new_item);
+                break;
+            }
+        }
+    }
+
+    return new_item;
+}
+
+// MARK: -
+// MARK: SQL Construction helpers -- These should become private in the future
+
+void SecDbAppendElement(CFMutableStringRef sql, CFStringRef value, bool *needComma) {
+    assert(needComma);
+    if (*needComma) {
+        CFStringAppend(sql, CFSTR(","));
+    } else {
+        *needComma = true;
+    }
+    CFStringAppend(sql, value);
+}
+
+static void SecDbAppendElementEquals(CFMutableStringRef sql, CFStringRef value, bool *needComma) {
+    SecDbAppendElement(sql, value, needComma);
+    CFStringAppend(sql, CFSTR("=?"));
+}
+
+/* Append AND is needWhere is NULL or *needWhere is false.  Append WHERE
+ otherwise.  Upon return *needWhere will be false.  */
+void
+SecDbAppendWhereOrAnd(CFMutableStringRef sql, bool *needWhere) {
+    if (!needWhere || !*needWhere) {
+        CFStringAppend(sql, CFSTR(" AND "));
+    } else {
+        CFStringAppend(sql, CFSTR(" WHERE "));
+        *needWhere = false;
+    }
+}
+
+void
+SecDbAppendWhereOrAndEquals(CFMutableStringRef sql, CFStringRef col, bool *needWhere) {
+    SecDbAppendWhereOrAnd(sql, needWhere);
+    CFStringAppend(sql, col);
+    CFStringAppend(sql, CFSTR("=?"));
+}
+
+static CFStringRef SecDbItemCopyInsertSQL(SecDbItemRef item, bool(^use_attr)(const SecDbAttr *attr)) {
+    CFMutableStringRef sql = CFStringCreateMutable(CFGetAllocator(item), 0);
+    CFStringAppend(sql, CFSTR("INSERT INTO "));
+    CFStringAppend(sql, item->class->name);
+    CFStringAppend(sql, CFSTR("("));
+    bool needComma = false;
+    CFIndex used_attr = 0;
+    SecDbForEachAttr(item->class, attr) {
+        if (use_attr(attr)) {
+            ++used_attr;
+            SecDbAppendElement(sql, attr->name, &needComma);
+        }
+    }
+    CFStringAppend(sql, CFSTR(")VALUES(?"));
+    while (used_attr-- > 1) {
+        CFStringAppend(sql, CFSTR(",?"));
+    }
+    CFStringAppend(sql, CFSTR(")"));
+    return sql;
+
+}
+
+static bool SecDbItemInsertBind(SecDbItemRef item, sqlite3_stmt *stmt, CFErrorRef *error, bool(^use_attr)(const SecDbAttr *attr)) {
+    bool ok = true;
+    int param = 0;
+    SecDbForEachAttr(item->class, attr) {
+        if (use_attr(attr)) {
+            CFTypeRef value = SecDbItemGetValue(item, attr, error);
+            if (!value || !SecDbAttrBind(attr, stmt, ++param, value, error)) {
+                ok = false;
+                break;
+            }
+        }
+    }
+    return ok;
+}
+
+sqlite3_int64 SecDbItemGetRowId(SecDbItemRef item, CFErrorRef *error) {
+    sqlite3_int64 row_id = 0;
+    const SecDbAttr *attr = SecDbClassAttrWithKind(item->class, kSecDbRowIdAttr, error);
+    if (attr) {
+        CFNumberRef number = SecDbItemGetValue(item, attr, error);
+        if (!isNumber(number)|| !CFNumberGetValue(number, kCFNumberSInt64Type, &row_id))
+            SecDbError(SQLITE_ERROR, error, CFSTR("rowid %@ is not a 64 bit number"), number);
+    }
+
+    return row_id;
+}
+
+static CFNumberRef SecDbItemCreateRowId(SecDbItemRef item, sqlite3_int64 rowid, CFErrorRef *error) {
+    return CFNumberCreate(CFGetAllocator(item), kCFNumberSInt64Type, &rowid);
+}
+
+bool SecDbItemSetRowId(SecDbItemRef item, sqlite3_int64 rowid, CFErrorRef *error) {
+    bool ok = true;
+    const SecDbAttr *attr = SecDbClassAttrWithKind(item->class, kSecDbRowIdAttr, error);
+    if (attr) {
+        CFNumberRef value = SecDbItemCreateRowId(item, rowid, error);
+        if (!value)
+            return false;
+
+        ok = SecDbItemSetValue(item, attr, value, error);
+        CFRelease(value);
+    }
+    return ok;
+}
+
+static bool SecDbItemClearRowId(SecDbItemRef item, CFErrorRef *error) {
+    bool ok = true;
+    const SecDbAttr *attr = SecDbClassAttrWithKind(item->class, kSecDbRowIdAttr, error);
+    if (attr) {
+        CFDictionaryRemoveValue(item->attributes, attr->name);
+        //ok = SecDbItemSetValue(item, attr, kCFNull, error);
+    }
+    return ok;
+}
+
+static bool SecDbItemSetLastInsertRowId(SecDbItemRef item, SecDbConnectionRef dbconn, CFErrorRef *error) {
+    sqlite3_int64 rowid = sqlite3_last_insert_rowid(SecDbHandle(dbconn));
+    return SecDbItemSetRowId(item, rowid, error);
+}
+
+bool SecDbItemIsSyncable(SecDbItemRef item) {
+    bool is_syncable;
+    if (SecDbItemGetBoolValue(item, SecDbClassAttrWithKind(item->class, kSecDbSyncAttr, NULL), &is_syncable, NULL))
+        return is_syncable;
+    return false;
+}
+
+bool SecDbItemSetSyncable(SecDbItemRef item, bool sync, CFErrorRef *error)
+{
+    return SecDbItemSetValue(item, SecDbClassAttrWithKind(item->class, kSecDbSyncAttr, error), sync ? kCFBooleanTrue : kCFBooleanFalse, error);
+}
+
+bool SecDbItemIsTombstone(SecDbItemRef item) {
+    bool is_tomb;
+    if (SecDbItemGetBoolValue(item, SecDbClassAttrWithKind(item->class, kSecDbTombAttr, NULL), &is_tomb, NULL))
+        return is_tomb;
+    return false;
+}
+
+CFDataRef SecDbItemGetPrimaryKey(SecDbItemRef item, CFErrorRef *error) {
+    return SecDbItemGetValue(item, SecDbClassAttrWithKind(item->class, kSecDbPrimaryKeyAttr, error), error);
+}
+
+CFDataRef SecDbItemGetSHA1(SecDbItemRef item, CFErrorRef *error) {
+    return SecDbItemGetValue(item, SecDbClassAttrWithKind(item->class, kSecDbSHA1Attr, error), error);
+}
+
+static SecDbQueryRef SecDbQueryCreateWithItemPrimaryKey(SecDbItemRef item, CFErrorRef *error) {
+    CFMutableDictionaryRef dict = SecDbItemCopyPListWithMask(item, kSecDbPrimaryKeyFlag, error);
+    if (!dict)
+        return NULL;
+
+    SecDbQueryRef query = query_create(item->class, NULL, error);
+    if (query)
+        query->q_item = dict;
+    else
+        CFRelease(dict);
+
+    return query;
+}
+
+static bool SecDbItemIsCorrupt(SecDbItemRef item, bool *is_corrupt, CFErrorRef *error) {
+    CFErrorRef localError = NULL;
+    bool ok = SecDbItemEnsureDecrypted(item, &localError);
+    if (localError) {
+        if (SecErrorGetOSStatus(localError) == errSecDecode) {
+            // We failed to decrypt the item
+            secerror("error %@ reading item %@ (corrupted)", localError, item);
+            __security_simulatecrash(CFSTR("Corrupted item found in keychain"), __sec_exception_code_CorruptItem);
+            *is_corrupt = true;
+            ok = true;
+        } else if (error && *error == NULL) {
+            *error = localError;
+            localError = NULL;
+        }
+        CFReleaseSafe(localError);
+    }
+    return ok;
+}
+
+static bool SecDbItemDoInsert(SecDbItemRef item, SecDbConnectionRef dbconn, CFErrorRef *error) {
+    bool (^use_attr)(const SecDbAttr *attr) = ^bool(const SecDbAttr *attr) {
+        return (attr->flags & kSecDbInFlag);
+    };
+    CFStringRef sql = SecDbItemCopyInsertSQL(item, use_attr);
+    __block bool ok = sql;
+    if (sql) {
+        ok &= SecDbPrepare(dbconn, sql, error, ^(sqlite3_stmt *stmt) {
+            ok = (SecDbItemInsertBind(item, stmt, error, use_attr) &&
+                  SecDbStep(dbconn, stmt, error, NULL) &&
+                  SecDbItemSetLastInsertRowId(item, dbconn, error));
+        });
+        CFRelease(sql);
+    }
+    if (ok)
+        secnotice("item", "inserted %@", item);
+
+    return ok;
+}
+
+bool SecDbItemInsertOrReplace(SecDbItemRef item, SecDbConnectionRef dbconn, CFErrorRef *error, void(^duplicate)(SecDbItemRef item, SecDbItemRef *replace)) {
+    __block CFErrorRef localError = NULL;
+    __block bool ok = SecDbItemDoInsert(item, dbconn, &localError);
+    if (!ok && localError && CFErrorGetCode(localError) == SQLITE_CONSTRAINT && CFEqual(kSecDbErrorDomain, CFErrorGetDomain(localError))) {
+        SecDbQueryRef query = SecDbQueryCreateWithItemPrimaryKey(item, error);
+        if (query) {
+            SecDbItemSelect(query, dbconn, error, ^bool(const SecDbAttr *attr) {
+                return attr->flags & kSecDbPrimaryKeyFlag;
+            }, NULL, NULL, ^(SecDbItemRef old_item, bool *stop) {
+                bool is_corrupt = false;
+                ok = SecDbItemIsCorrupt(old_item, &is_corrupt, error);
+                SecDbItemRef replace = NULL;
+                if (is_corrupt) {
+                    // If old_item is corrupted pretend it's not there and just replace it.
+                    replace = item;
+                    CFRetain(replace);
+                } else if (ok && duplicate) {
+                    duplicate(old_item, &replace);
+                }
+                if (replace) {
+                    const SecDbAttr *rowid_attr = SecDbClassAttrWithKind(old_item->class, kSecDbRowIdAttr, error);
+                    CFNumberRef oldrowid = SecDbItemGetCachedValue(old_item, rowid_attr);
+                    if (oldrowid) {
+                        ok = SecDbItemSetValue(replace, rowid_attr, oldrowid, &localError);
+                        if (ok && !is_corrupt) {
+                            ok = SecDbItemMakeYounger(replace, old_item, error);
+                        }
+                        ok = ok && SecDbItemDoUpdate(old_item, replace, dbconn, &localError, ^bool (const SecDbAttr *attr) {
+                            return attr->kind == kSecDbRowIdAttr;
+                        });
+                    } else {
+                        ok = SecError(errSecInternal, &localError, CFSTR("no rowid for %@"), old_item);
+                    }
+                    CFRelease(replace);
+                    if (ok)
+                        CFReleaseNull(localError); // Clear the error, since we replaced the item.
+                }
+            });
+            ok &= query_destroy(query, error);
+        }
+        if (localError)
+            ok = false;  // We didn't clear the error so we're failing again.
+    }
+
+    if (!ok) {
+        /*
+            CFErrorRef e = localError ? localError : error ? *error : NULL;
+            secerror("INSERT %@ failed: %@%s", item, e, (e && CFErrorGetCode(e) == SQLITE_CONSTRAINT) ?
+                " and SELECT failed to find tombstone" : "");
+         */
+        secerror("INSERT failed: %@", localError);
+        if (localError) {
+            if (error && *error == NULL) {
+                *error = localError;
+                localError = NULL;
+            } else {
+                CFReleaseNull(localError);
+            }
+        }
+    }
+
+    return ok;
+}
+
+bool SecDbItemInsert(SecDbItemRef item, SecDbConnectionRef dbconn, CFErrorRef *error) {
+    return SecDbItemInsertOrReplace(item, dbconn, error, ^(SecDbItemRef old_item, SecDbItemRef *replace) {
+        if (SecDbItemIsTombstone(old_item)) {
+            CFRetain(item);
+            *replace = item;
+        }
+    });
+}
+
+static CFStringRef SecDbItemCopyUpdateSQL(SecDbItemRef old_item, SecDbItemRef new_item, bool(^use_attr_in_where)(const SecDbAttr *attr)) {
+    CFMutableStringRef sql = CFStringCreateMutable(CFGetAllocator(new_item), 0);
+    CFStringAppend(sql, CFSTR("UPDATE "));
+    CFStringAppend(sql, new_item->class->name);
+    CFStringAppend(sql, CFSTR(" SET "));
+    bool needComma = false;
+    CFIndex used_attr = 0;
+    SecDbForEachAttrWithMask(new_item->class, attr, kSecDbInFlag) {
+        ++used_attr;
+        SecDbAppendElementEquals(sql, attr->name, &needComma);
+    }
+
+    bool needWhere = true;
+    SecDbForEachAttr(old_item->class, attr) {
+        if (use_attr_in_where(attr)) {
+            SecDbAppendWhereOrAndEquals(sql, attr->name, &needWhere);
+        }
+    }
+
+    return sql;
+}
+
+static bool SecDbItemUpdateBind(SecDbItemRef old_item, SecDbItemRef new_item, sqlite3_stmt *stmt, CFErrorRef *error, bool(^use_attr_in_where)(const SecDbAttr *attr)) {
+    bool ok = true;
+    int param = 0;
+    SecDbForEachAttrWithMask(new_item->class, attr, kSecDbInFlag) {
+        CFTypeRef value = SecDbItemGetValue(new_item, attr, error);
+        ok &= value && SecDbAttrBind(attr, stmt, ++param, value, error);
+        if (!ok)
+            break;
+    }
+    SecDbForEachAttr(old_item->class, attr) {
+        if (use_attr_in_where(attr)) {
+            CFTypeRef value = SecDbItemGetValue(old_item, attr, error);
+            ok &= value && SecDbAttrBind(attr, stmt, ++param, value, error);
+            if (!ok)
+                break;
+        }
+    }
+    return ok;
+}
+
+// Primary keys are the same -- do an update
+bool SecDbItemDoUpdate(SecDbItemRef old_item, SecDbItemRef new_item, SecDbConnectionRef dbconn, CFErrorRef *error, bool (^use_attr_in_where)(const SecDbAttr *attr)) {
+    CFStringRef sql = SecDbItemCopyUpdateSQL(old_item, new_item, use_attr_in_where);
+    __block bool ok = sql;
+    if (sql) {
+        ok &= SecDbPrepare(dbconn, sql, error, ^(sqlite3_stmt *stmt) {
+            ok = SecDbItemUpdateBind(old_item, new_item, stmt, error, use_attr_in_where) && SecDbStep(dbconn, stmt, error, NULL);
+        });
+        CFRelease(sql);
+    }
+    if (ok)
+        secnotice("item", "replaced %@ with %@ in %@", old_item, new_item, dbconn);
+    return ok;
+}
+
+static CFStringRef SecDbItemCopyDeleteSQL(SecDbItemRef item, bool(^use_attr_in_where)(const SecDbAttr *attr)) {
+    CFMutableStringRef sql = CFStringCreateMutable(CFGetAllocator(item), 0);
+    CFStringAppend(sql, CFSTR("DELETE FROM "));
+    CFStringAppend(sql, item->class->name);
+    bool needWhere = true;
+    SecDbForEachAttr(item->class, attr) {
+        if (use_attr_in_where(attr)) {
+            SecDbAppendWhereOrAndEquals(sql, attr->name, &needWhere);
+        }
+    }
+
+    return sql;
+}
+
+static bool SecDbItemDeleteBind(SecDbItemRef item, sqlite3_stmt *stmt, CFErrorRef *error, bool(^use_attr_in_where)(const SecDbAttr *attr)) {
+    bool ok = true;
+    int param = 0;
+    SecDbForEachAttr(item->class, attr) {
+        if (use_attr_in_where(attr)) {
+            CFTypeRef value = SecDbItemGetValue(item, attr, error);
+            ok &= value && SecDbAttrBind(attr, stmt, ++param, value, error);
+            if (!ok)
+                break;
+        }
+    }
+    return ok;
+}
+
+static bool SecDbItemDoDelete(SecDbItemRef item, SecDbConnectionRef dbconn, CFErrorRef *error, bool (^use_attr_in_where)(const SecDbAttr *attr)) {
+    CFStringRef sql = SecDbItemCopyDeleteSQL(item, use_attr_in_where);
+    __block bool ok = sql;
+    if (sql) {
+        ok &= SecDbPrepare(dbconn, sql, error, ^(sqlite3_stmt *stmt) {
+            ok = SecDbItemDeleteBind(item, stmt, error, use_attr_in_where) && SecDbStep(dbconn, stmt, error, NULL);
+        });
+        CFRelease(sql);
+    }
+    if (ok)
+        secnotice("item", "deleted %@ from %@", item, dbconn);
+    return ok;
+}
+
+#if 0
+static bool SecDbItemDeleteTombstone(SecDbItemRef item, SecDbConnectionRef dbconn, CFErrorRef *error) {
+    bool ok = true;
+    // TODO: Treat non decryptable items like tombstones here too and delete them
+    SecDbItemRef tombstone = SecDbItemCopyTombstone(item, error);
+    ok = tombstone;
+    if (tombstone) {
+        ok = SecDbItemClearRowId(tombstone, error);
+        if (ok) {
+            ok = SecDbItemDoDelete(tombstone, dbconn, error, ^bool (const SecDbAttr *attr) {
+                return SecDbIsTombstoneDbSelectAttr(attr);
+            });
+        }
+        CFRelease(tombstone);
+    }
+    return ok;
+}
+#endif
+
+// Replace old_item with new_item.  If primary keys are the same this does an update otherwise it does a delete + add
+bool SecDbItemUpdate(SecDbItemRef old_item, SecDbItemRef new_item, SecDbConnectionRef dbconn, bool makeTombstone, CFErrorRef *error) {
+    __block bool ok = true;
+    __block CFErrorRef localError = NULL;
+
+    CFDataRef old_pk = SecDbItemGetPrimaryKey(old_item, error);
+    CFDataRef new_pk = SecDbItemGetPrimaryKey(new_item, error);
+
+    ok = old_pk && new_pk;
+
+    bool pk_equal = ok && CFEqual(old_pk, new_pk);
+    if (pk_equal) {
+        ok = SecDbItemMakeYounger(new_item, old_item, error);
+    }
+    ok = ok && SecDbItemDoUpdate(old_item, new_item, dbconn, &localError, ^bool(const SecDbAttr *attr) {
+        return attr->kind == kSecDbRowIdAttr;
+    });
+
+    if (localError) {
+        if(CFErrorGetCode(localError) == SQLITE_CONSTRAINT && CFEqual(kSecDbErrorDomain, CFErrorGetDomain(localError))) {
+            /* Update failed because we changed the PrimaryKey and there was a dup.
+               Find the dup and see if it is a tombstone or corrupted item. */
+            SecDbQueryRef query = SecDbQueryCreateWithItemPrimaryKey(new_item, error);
+            ok = query;
+            if (query) {
+                ok &= SecDbItemSelect(query, dbconn, error, ^bool(const SecDbAttr *attr) {
+                    return attr->flags & kSecDbPrimaryKeyFlag;
+                }, NULL, NULL, ^(SecDbItemRef duplicate_item, bool *stop) {
+                    bool is_corrupt = false;
+                    bool is_tomb = false;
+                    ok = SecDbItemIsCorrupt(duplicate_item, &is_corrupt, error);
+                    if (ok && !is_corrupt) {
+                        if ((is_tomb = SecDbItemIsTombstone(duplicate_item)))
+                            ok = SecDbItemMakeYounger(new_item, duplicate_item, error);
+                    }
+                    if (ok && (is_corrupt || is_tomb)) {
+                        ok = SecDbItemDoDelete(old_item, dbconn, error, ^bool (const SecDbAttr *attr) {
+                            return attr->kind == kSecDbRowIdAttr;
+                        });
+                        ok = ok && SecDbItemDoUpdate(duplicate_item, new_item, dbconn, error, ^bool (const SecDbAttr *attr) {
+                            return attr->kind == kSecDbRowIdAttr;
+                        });
+                        CFReleaseNull(localError);
+                    }
+                });
+                ok &= query_destroy(query, error);
+            }
+        }
+
+        if (localError) {
+            ok = false;
+            if (error && *error == NULL) {
+                *error = localError;
+                localError = NULL;
+            }
+            CFReleaseSafe(localError);
+        }
+    }
+
+    if (ok && !pk_equal && makeTombstone) {
+        /* The primary key of new_item is different than that of old_item, we
+           have been asked to make a tombstone so leave one for the old_item. */
+        SecDbItemRef tombstone = SecDbItemCopyTombstone(old_item, error);
+        ok = tombstone;
+        if (tombstone) {
+            ok = (SecDbItemClearRowId(tombstone, error) &&
+                  SecDbItemDoInsert(tombstone, dbconn, error));
+            CFRelease(tombstone);
+        }
+    }
+
+    return ok;
+}
+
+// Replace the object with a tombstone
+bool SecDbItemDelete(SecDbItemRef item, SecDbConnectionRef dbconn, bool makeTombstone, CFErrorRef *error) {
+    bool ok = false;
+    if (makeTombstone) {
+        SecDbItemRef tombstone = SecDbItemCopyTombstone(item, error);
+        if (tombstone) {
+            ok = SecDbItemDoUpdate(item, tombstone, dbconn, error, ^bool(const SecDbAttr *attr) {
+                return attr->kind == kSecDbRowIdAttr;
+            });
+            CFRelease(tombstone);
+        }
+    } else {
+        ok = SecDbItemDoDelete(item, dbconn, error, ^bool(const SecDbAttr *attr) {
+            return attr->kind == kSecDbRowIdAttr;
+        });
+    }
+    return ok;
+}
+
+CFStringRef SecDbItemCopySelectSQL(SecDbQueryRef query,
+                                   bool (^return_attr)(const SecDbAttr *attr),
+                                   bool (^use_attr_in_where)(const SecDbAttr *attr),
+                                   bool (^add_where_sql)(CFMutableStringRef sql, bool *needWhere)) {
+    CFMutableStringRef sql = CFStringCreateMutable(kCFAllocatorDefault, 0);
+    CFStringAppend(sql, CFSTR("SELECT "));
+    // What are we selecting?
+    bool needComma = false;
+    SecDbForEachAttr(query->q_class, attr) {
+        if (return_attr(attr))
+            SecDbAppendElement(sql, attr->name, &needComma);
+    }
+
+    // From which table?
+    CFStringAppend(sql, CFSTR(" FROM "));
+    CFStringAppend(sql, query->q_class->name);
+
+    // And which elements do we want to select
+    bool needWhere = true;
+    SecDbForEachAttr(query->q_class, attr) {
+        if (use_attr_in_where(attr)) {
+            SecDbAppendWhereOrAndEquals(sql, attr->name, &needWhere);
+        }
+    }
+    // Append SQL for access groups and limits.
+    if (add_where_sql)
+        add_where_sql(sql, &needWhere);
+
+    return sql;
+}
+
+bool SecDbItemSelectBind(SecDbQueryRef query, sqlite3_stmt *stmt, CFErrorRef *error,
+                         bool (^use_attr_in_where)(const SecDbAttr *attr),
+                         bool (^bind_added_where)(sqlite3_stmt *stmt, int col)) {
+    bool ok = true;
+    int param = 0;
+    SecDbForEachAttr(query->q_class, attr) {
+        if (use_attr_in_where(attr)) {
+            CFTypeRef value = CFDictionaryGetValue(query->q_item, attr->name);
+            ok &= SecDbAttrBind(attr, stmt, ++param, value, error);
+            if (!ok)
+                break;
+        }
+    }
+    // TODO: Bind arguments for access groups and limits.
+    if (bind_added_where)
+        bind_added_where(stmt, ++param);
+
+    return ok;
+}
+
+bool SecDbItemSelect(SecDbQueryRef query, SecDbConnectionRef dbconn, CFErrorRef *error,
+                     bool (^use_attr_in_where)(const SecDbAttr *attr),
+                     bool (^add_where_sql)(CFMutableStringRef sql, bool *needWhere),
+                     bool (^bind_added_where)(sqlite3_stmt *stmt, int col),
+                     void (^handle_row)(SecDbItemRef item, bool *stop)) {
+    __block bool ok = true;
+    bool (^return_attr)(const SecDbAttr *attr) = ^bool (const SecDbAttr * attr) {
+        return attr->kind == kSecDbRowIdAttr || attr->kind == kSecDbEncryptedDataAttr;
+    };
+    CFStringRef sql = SecDbItemCopySelectSQL(query, return_attr, use_attr_in_where, add_where_sql);
+    if (sql) {
+        ok &= SecDbPrepare(dbconn, sql, error, ^(sqlite3_stmt *stmt) {
+            ok = (SecDbItemSelectBind(query, stmt, error, use_attr_in_where, bind_added_where) &&
+                  SecDbStep(dbconn, stmt, error, ^(bool *stop) {
+                SecDbItemRef item = SecDbItemCreateWithStatement(kCFAllocatorDefault, query->q_class, stmt, query->q_keybag, error, return_attr);
+                if (item) {
+                    handle_row(item, stop);
+                    CFRelease(item);
+                } else {
+                    //*stop = true;
+                    //ok = false;
+                }
+            }));
+        });
+        CFRelease(sql);
+    } else {
+        ok = false;
+    }
+    return ok;
+}
+
diff --git a/sec/securityd/SecDbItem.h b/sec/securityd/SecDbItem.h
new file mode 100644 (file)
index 0000000..236ac2b
--- /dev/null
@@ -0,0 +1,404 @@
+/*
+ * Copyright (c) 2012 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*!
+ @header SecDbItem
+ The functions provided in SecDbItem provide an interface to
+ database items (certificates, keys, identities, and passwords).
+ */
+
+#ifndef _SECURITYD_SECDBITEM_H_
+#define _SECURITYD_SECDBITEM_H_
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <TargetConditionals.h>
+#include <corecrypto/ccsha1.h> // For CCSHA1_OUTPUT_SIZE
+#include <sqlite3.h>
+#include <utilities/SecCFError.h>
+#include <utilities/SecCFWrappers.h>
+#include <utilities/SecDb.h>
+#include <utilities/SecAKSWrappers.h>
+
+#if TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_IPHONE_SIMULATOR)
+#define USE_KEYSTORE  1
+#elif TARGET_OS_EMBEDDED && !TARGET_IPHONE_SIMULATOR
+#define USE_KEYSTORE  1
+#else /* no keystore on this platform */
+#define USE_KEYSTORE  0
+#endif
+
+#if USE_KEYSTORE
+#include <Kernel/IOKit/crypto/AppleKeyStoreDefs.h>
+#endif /* USE_KEYSTORE */
+
+__BEGIN_DECLS
+
+// TODO: Get this out of this file
+#if USE_KEYSTORE
+typedef int32_t keyclass_t;
+#else
+
+/* TODO: this needs to be available in the sim! */
+#define kAppleKeyStoreKeyWrap 0
+#define kAppleKeyStoreKeyUnwrap 1
+typedef int32_t keyclass_t;
+typedef int32_t key_handle_t;
+enum key_classes {
+    key_class_ak = 6,
+    key_class_ck,
+    key_class_dk,
+    key_class_aku,
+    key_class_cku,
+    key_class_dku
+};
+#endif /* !USE_KEYSTORE */
+
+// MARK SecDbAttrKind, SecDbFlag
+
+typedef enum {
+    kSecDbBlobAttr,  // CFString or CFData, preserves caller provided type.
+    kSecDbDataAttr,
+    kSecDbStringAttr,
+    kSecDbNumberAttr,
+    kSecDbDateAttr,
+    kSecDbCreationDateAttr,
+    kSecDbModificationDateAttr,
+    kSecDbSHA1Attr,
+    kSecDbRowIdAttr,
+    kSecDbEncryptedDataAttr,
+    kSecDbPrimaryKeyAttr,
+    kSecDbSyncAttr,
+    kSecDbTombAttr,
+    kSecDbAccessAttr
+} SecDbAttrKind;
+
+enum {
+    kSecDbPrimaryKeyFlag    = (1 <<  0),    // attr is part of primary key
+    kSecDbInFlag            = (1 <<  1),    // attr exists in db
+    kSecDbIndexFlag         = (1 <<  2),    // attr should have a db index
+    kSecDbSHA1ValueInFlag   = (1 <<  3),    // col in db is sha1 of attr value
+    kSecDbReturnAttrFlag    = (1 <<  4),
+    kSecDbReturnDataFlag    = (1 <<  5),
+    kSecDbReturnRefFlag     = (1 <<  6),
+    kSecDbInCryptoDataFlag  = (1 <<  7),
+    kSecDbInHashFlag        = (1 <<  8),
+    kSecDbInBackupFlag      = (1 <<  9),
+    kSecDbDefault0Flag      = (1 << 10),    // default attr value is 0
+    kSecDbDefaultEmptyFlag  = (1 << 11),    // default attr value is ""
+    kSecDbNotNullFlag       = (1 << 12),    // attr value can't be null
+};
+
+#define SecVersionDbFlag(v) ((v & 0xFF) << 8)
+
+#define SecDbFlagGetVersion(flags) ((flags >> 8) & 0xFF)
+
+#define SECDB_ATTR(var, name, kind, flags) const SecDbAttr var = { CFSTR(name), kSecDb ## kind ## Attr, flags }
+
+typedef struct SecDbAttr {
+    CFStringRef name;
+    SecDbAttrKind kind;
+    CFOptionFlags flags;
+} SecDbAttr;
+
+typedef struct SecDbClass {
+    CFStringRef name;
+    const SecDbAttr *attrs[];
+} SecDbClass;
+
+typedef struct Pair *SecDbPairRef;
+typedef struct Query *SecDbQueryRef;
+
+/* Return types. */
+typedef uint32_t ReturnTypeMask;
+enum
+{
+    kSecReturnDataMask = 1 << 0,
+    kSecReturnAttributesMask = 1 << 1,
+    kSecReturnRefMask = 1 << 2,
+    kSecReturnPersistentRefMask = 1 << 3,
+};
+
+/* Constant indicating there is no limit to the number of results to return. */
+enum
+{
+    kSecMatchUnlimited = kCFNotFound
+};
+
+typedef struct Pair
+{
+    const void *key;
+    const void *value;
+} Pair;
+
+/* Nothing in this struct is retained since all the
+ values below are extracted from the dictionary passed in by the
+ caller. */
+typedef struct Query
+{
+    /* Class of this query. */
+    const SecDbClass *q_class;
+
+    /* Dictionary with all attributes and values in clear (to be encrypted). */
+    CFMutableDictionaryRef q_item;
+
+    /* q_pairs is an array of Pair structs.  Elements with indices
+     [0, q_attr_end) contain attribute key value pairs.  Elements with
+     indices [q_match_begin, q_match_end) contain match key value pairs.
+     Thus q_attr_end is the number of attrs in q_pairs and
+     q_match_begin - q_match_end is the number of matches in q_pairs.  */
+    CFIndex q_match_begin;
+    CFIndex q_match_end;
+    CFIndex q_attr_end;
+
+    CFErrorRef q_error;
+    ReturnTypeMask q_return_type;
+
+    CFDataRef q_data;
+    CFTypeRef q_ref;
+    sqlite_int64 q_row_id;
+
+    CFArrayRef q_use_item_list;
+    CFBooleanRef q_use_tomb;
+#if defined(MULTIPLE_KEYCHAINS)
+    CFArrayRef q_use_keychain;
+    CFArrayRef q_use_keychain_list;
+#endif /* !defined(MULTIPLE_KEYCHAINS) */
+
+    /* Value of kSecMatchLimit key if present. */
+    CFIndex q_limit;
+
+    /* True if query contained a kSecAttrSynchronizable attribute,
+     * regardless of its actual value. If this is false, then we
+     * will add an explicit sync=0 to the query. */
+    bool q_sync;
+
+    // Set to true if we modified any item as part of executing this query
+    bool q_changed;
+
+    // Set to true if we modified any synchronizable item as part of executing this query
+    bool q_sync_changed;
+
+    /* Keybag handle to use for this item. */
+    keybag_handle_t q_keybag;
+    keyclass_t q_keyclass;
+    //CFStringRef q_keyclass_s;
+
+    // SHA1 digest of DER encoded primary key
+    CFDataRef q_primary_key_digest;
+
+    CFArrayRef q_match_issuer;
+
+    /* Store all the corrupted rows found during the query */
+    CFMutableArrayRef corrupted_rows;
+
+    Pair q_pairs[];
+} Query;
+
+
+#define SecDbForEachAttr(class, attr) for (const SecDbAttr * const* _pattr = (class)->attrs, *attr = *_pattr; attr; attr = *(++_pattr))
+
+#define SecDbForEachAttrWithMask(class, attr, flag_mask) SecDbForEachAttr(class, attr) if ((attr->flags & (flag_mask)) == (flag_mask))
+
+// MARK: Stuff that needs to move out of SecItemServer.c
+
+// Move this or do crypto in a block
+bool ks_encrypt_data(keybag_handle_t keybag, keyclass_t keyclass, CFDataRef plainText, CFDataRef *pBlob, CFErrorRef *error);
+bool ks_decrypt_data(keybag_handle_t keybag, keyclass_t *pkeyclass, CFDataRef blob, CFDataRef *pPlainText,
+                            uint32_t *version_p, CFErrorRef *error);
+
+CFDataRef kc_copy_sha1(size_t len, const void *data, CFErrorRef *error);
+CFDataRef kc_copy_plist_sha1(CFPropertyListRef plist, CFErrorRef *error);
+CFDataRef kc_plist_copy_der(CFPropertyListRef plist, CFErrorRef *error);
+Query *query_create(const SecDbClass *qclass, CFDictionaryRef query, CFErrorRef *error);
+bool query_destroy(Query *q, CFErrorRef *error);
+
+// MARK: SecDbItem
+
+typedef struct SecDbItem *SecDbItemRef;
+
+enum SecDbItemState {
+    kSecDbItemDirty,          // We have no edata (or if we do it's invalid), attributes are the truth
+    kSecDbItemEncrypted,      // Attributes haven't been decrypted yet from edata
+    kSecDbItemClean,          // Attributes and _edata are in sync.
+    kSecDbItemDecrypting,     // Temporary state while we are decrypting so set knows not to blow away the edata.
+    kSecDbItemEncrypting,     // Temporary state while we are encrypting so set knows to move to clean.
+};
+
+struct SecDbItem {
+    CFRuntimeBase _base;
+    const SecDbClass *class;
+    keyclass_t keyclass;
+    keybag_handle_t keybag;
+    //sqlite3_int64 _rowid;
+    //CFDataRef _primaryKey;
+    //CFDataRef _sha1;
+    //CFDataRef _edata;
+    enum SecDbItemState _edataState;
+    CFMutableDictionaryRef attributes;
+};
+
+// TODO: Make this a callback to client
+bool SecDbItemDecrypt(SecDbItemRef item, CFDataRef edata, CFErrorRef *error);
+
+CFTypeID SecDbItemGetTypeID(void);
+
+static inline size_t SecDbClassAttrCount(const SecDbClass *dbClass) {
+    size_t n_attrs = 0;
+    SecDbForEachAttr(dbClass, attr) { n_attrs++; }
+    return n_attrs;
+}
+
+const SecDbAttr *SecDbClassAttrWithKind(const SecDbClass *class, SecDbAttrKind kind, CFErrorRef *error);
+
+SecDbItemRef SecDbItemCreateWithAttributes(CFAllocatorRef allocator, const SecDbClass *class, CFDictionaryRef attributes, keybag_handle_t keybag, CFErrorRef *error);
+
+const SecDbClass *SecDbItemGetClass(SecDbItemRef item);
+const keybag_handle_t SecDbItemGetKeybag(SecDbItemRef item);
+bool SecDbItemSetKeybag(SecDbItemRef item, keybag_handle_t keybag, CFErrorRef *error);
+keyclass_t SecDbItemGetKeyclass(SecDbItemRef item, CFErrorRef *error);
+bool SecDbItemSetKeyclass(SecDbItemRef item, keyclass_t keyclass, CFErrorRef *error);
+
+CFTypeRef SecDbItemGetCachedValueWithName(SecDbItemRef item, CFStringRef name);
+CF_RETURNS_NOT_RETAINED CFTypeRef SecDbItemGetValue(SecDbItemRef item, const SecDbAttr *desc, CFErrorRef *error);
+
+bool SecDbItemSetValue(SecDbItemRef item, const SecDbAttr *desc, CFTypeRef value, CFErrorRef *error);
+bool SecDbItemSetValues(SecDbItemRef item, CFDictionaryRef values, CFErrorRef *error);
+bool SecDbItemSetValueWithName(SecDbItemRef item, CFStringRef name, CFTypeRef value, CFErrorRef *error);
+
+sqlite3_int64 SecDbItemGetRowId(SecDbItemRef item, CFErrorRef *error);
+bool SecDbItemSetRowId(SecDbItemRef item, sqlite3_int64 rowid, CFErrorRef *error);
+
+bool SecDbItemIsSyncable(SecDbItemRef item);
+
+bool SecDbItemSetSyncable(SecDbItemRef item, bool sync, CFErrorRef *error);
+
+bool SecDbItemIsTombstone(SecDbItemRef item);
+
+CFMutableDictionaryRef SecDbItemCopyPListWithMask(SecDbItemRef item, CFOptionFlags mask, CFErrorRef *error);
+
+CFDataRef SecDbItemGetPrimaryKey(SecDbItemRef item, CFErrorRef *error);
+CFDataRef SecDbItemGetSHA1(SecDbItemRef item, CFErrorRef *error);
+
+CFDataRef SecDbItemCopyEncryptedDataToBackup(SecDbItemRef item, uint64_t handle, CFErrorRef *error);
+
+SecDbItemRef SecDbItemCreateWithStatement(CFAllocatorRef allocator, const SecDbClass *class, sqlite3_stmt *stmt, keybag_handle_t keybag, CFErrorRef *error, bool (^return_attr)(const SecDbAttr *attr));
+
+SecDbItemRef SecDbItemCreateWithEncryptedData(CFAllocatorRef allocator, const SecDbClass *class,
+                                              CFDataRef edata, keybag_handle_t keybag, CFErrorRef *error);
+
+SecDbItemRef SecDbItemCreateWithPrimaryKey(CFAllocatorRef allocator, const SecDbClass *class, CFDataRef primary_key);
+
+#if 0
+SecDbItemRef SecDbItemCreateWithRowId(CFAllocatorRef allocator, const SecDbClass *class, sqlite_int64 row_id, keybag_handle_t keybag, CFErrorRef *error);
+#endif
+
+SecDbItemRef SecDbItemCopyWithUpdates(SecDbItemRef item, CFDictionaryRef updates, CFErrorRef *error);
+
+SecDbItemRef SecDbItemCopyTombstone(SecDbItemRef item, CFErrorRef *error);
+
+bool SecDbItemInsertOrReplace(SecDbItemRef item, SecDbConnectionRef dbconn, CFErrorRef *error, void(^duplicate)(SecDbItemRef item, SecDbItemRef *replace));
+
+bool SecDbItemInsert(SecDbItemRef item, SecDbConnectionRef dbconn, CFErrorRef *error);
+
+bool SecDbItemDelete(SecDbItemRef item, SecDbConnectionRef dbconn, bool makeTombstone, CFErrorRef *error);
+
+// Low level update, just do the update
+bool SecDbItemDoUpdate(SecDbItemRef old_item, SecDbItemRef new_item, SecDbConnectionRef dbconn, CFErrorRef *error, bool (^use_attr_in_where)(const SecDbAttr *attr));
+
+// High level update, will replace tombstones and create them if needed.
+bool SecDbItemUpdate(SecDbItemRef old_item, SecDbItemRef new_item, SecDbConnectionRef dbconn, bool makeTombstone, CFErrorRef *error);
+
+bool SecDbItemSelect(SecDbQueryRef query, SecDbConnectionRef dbconn, CFErrorRef *error,
+                     bool (^use_attr_in_where)(const SecDbAttr *attr),
+                     bool (^add_where_sql)(CFMutableStringRef sql, bool *needWhere),
+                     bool (^bind_added_where)(sqlite3_stmt *stmt, int col),
+                     void (^handle_row)(SecDbItemRef item, bool *stop));
+
+CFStringRef SecDbItemCopySelectSQL(SecDbQueryRef query,
+                                   bool (^return_attr)(const SecDbAttr *attr),
+                                   bool (^use_attr_in_where)(const SecDbAttr *attr),
+                                   bool (^add_where_sql)(CFMutableStringRef sql, bool *needWhere));
+bool SecDbItemSelectBind(SecDbQueryRef query, sqlite3_stmt *stmt, CFErrorRef *error,
+                         bool (^use_attr_in_where)(const SecDbAttr *attr),
+                         bool (^bind_added_where)(sqlite3_stmt *stmt, int col));
+
+
+// MARK: -
+// MARK: SQL Construction helpers -- These should become private in the future
+
+void SecDbAppendElement(CFMutableStringRef sql, CFStringRef value, bool *needComma);
+void SecDbAppendWhereOrAnd(CFMutableStringRef sql, bool *needWhere);
+void SecDbAppendWhereOrAndEquals(CFMutableStringRef sql, CFStringRef col, bool *needWhere);
+
+// MARK: -
+// MARK: SecItemDb (a SecDb of SecDbItems)
+
+typedef struct SecItemDb *SecItemDbRef;
+typedef struct SecItemDbConnection *SecItemDbConnectionRef;
+
+struct SecItemDb {
+    CFRuntimeBase _base;
+    SecDbRef db;
+    CFDictionaryRef classes; // className -> SecItemClass mapping
+};
+
+struct SecItemDbConnection {
+    SecDbConnectionRef db;
+};
+
+SecItemDbRef SecItemDbCreate(SecDbRef db);
+SecItemDbRef SecItemDbRegisterClass(SecItemDbRef db, const SecDbClass *class, void(^upgrade)(SecDbItemRef item, uint32_t current_version));
+
+SecItemDbConnectionRef SecItemDbAquireConnection(SecItemDbRef db);
+void SecItemDbReleaseConnection(SecItemDbRef db, SecItemDbConnectionRef dbconn);
+
+bool SecItemDbInsert(SecItemDbConnectionRef dbconn, SecDbItemRef item, CFErrorRef *error);
+
+bool SecItemDbDelete(SecItemDbConnectionRef dbconn, SecDbItemRef item, CFErrorRef *error);
+
+// Low level update, just do the update
+bool SecItemDbDoUpdate(SecItemDbConnectionRef dbconn, SecDbItemRef old_item, SecDbItemRef new_item, CFErrorRef *error,
+                       bool (^use_attr_in_where)(const SecDbAttr *attr));
+
+// High level update, will replace tombstones and create them if needed.
+bool SecItemDbUpdate(SecItemDbConnectionRef dbconn, SecDbItemRef old_item, SecDbItemRef new_item, CFErrorRef *error);
+
+bool SecItemDbSelect(SecItemDbConnectionRef dbconn, SecDbQueryRef query, CFErrorRef *error,
+                     bool (^use_attr_in_where)(const SecDbAttr *attr),
+                     bool (^add_where_sql)(CFMutableStringRef sql, bool *needWhere),
+                     bool (^bind_added_where)(sqlite3_stmt *stmt, int col),
+                     void (^handle_row)(SecDbItemRef item, bool *stop));
+
+// MARK: type converters.
+// TODO: these should be static and private to SecDbItem, or part of the schema
+
+CFStringRef copyString(CFTypeRef obj);
+CFDataRef copyData(CFTypeRef obj);
+CFTypeRef copyBlob(CFTypeRef obj);
+CFDataRef copySHA1(CFTypeRef obj);
+CFTypeRef copyNumber(CFTypeRef obj);
+CFDateRef copyDate(CFTypeRef obj);
+
+__END_DECLS
+
+#endif /* _SECURITYD_SECDBITEM_H_ */
index eb01bc4a2b0c26c687317f1aab5b7178dbc36f67..9df01c545eb68f29e62c7d2c1733f84aac15c8a4 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2006-2010 Apple Inc. All Rights Reserved.
- * 
+ * Copyright (c) 2006-2013 Apple Inc. All Rights Reserved.
+ *
  * @APPLE_LICENSE_HEADER_START@
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * 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 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ 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,
  * 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,
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS 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_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
-/* 
+/*
  * SecItemServer.c - CoreFoundation-based constants and functions for
     access to Security items (certificates, keys, identities, and
     passwords.)
  */
 
 #include <securityd/SecItemServer.h>
  * SecItemServer.c - CoreFoundation-based constants and functions for
     access to Security items (certificates, keys, identities, and
     passwords.)
  */
 
 #include <securityd/SecItemServer.h>
+#include <securityd/SecDbItem.h>
 
 #include <Security/SecItem.h>
 #include <Security/SecItemPriv.h>
 
 #include <Security/SecItem.h>
 #include <Security/SecItemPriv.h>
 #include <Security/SecFramework.h>
 #include <Security/SecRandom.h>
 #include <Security/SecBasePriv.h>
 #include <Security/SecFramework.h>
 #include <Security/SecRandom.h>
 #include <Security/SecBasePriv.h>
-#include <errno.h>
+#include <utilities/SecIOFormat.h>
+#include <utilities/SecCFWrappers.h>
+#include <utilities/SecCFError.h>
+#include <utilities/der_plist.h>
 #include <limits.h>
 #include <limits.h>
-#include <pthread.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 #include <Security/SecBase.h>
 #include <CoreFoundation/CFData.h>
 #include <CoreFoundation/CFDate.h>
 #include <Security/SecBase.h>
 #include <CoreFoundation/CFData.h>
 #include <CoreFoundation/CFDate.h>
+#include <CoreFoundation/CFArray.h>
 #include <CoreFoundation/CFDictionary.h>
 #include <CoreFoundation/CFNumber.h>
 #include <CoreFoundation/CFString.h>
 #include <CoreFoundation/CFURL.h>
 #include <CommonCrypto/CommonDigest.h>
 #include <CoreFoundation/CFDictionary.h>
 #include <CoreFoundation/CFNumber.h>
 #include <CoreFoundation/CFString.h>
 #include <CoreFoundation/CFURL.h>
 #include <CommonCrypto/CommonDigest.h>
+#include <CommonCrypto/CommonDigestSPI.h>
 #include <CommonCrypto/CommonCryptor.h>
 #include <CommonCrypto/CommonCryptorSPI.h>
 #include <libkern/OSByteOrder.h>
 #include <CommonCrypto/CommonCryptor.h>
 #include <CommonCrypto/CommonCryptorSPI.h>
 #include <libkern/OSByteOrder.h>
-#include <security_utilities/debugging.h>
+#include <utilities/debugging.h>
 #include <assert.h>
 #include <Security/SecInternal.h>
 #include <assert.h>
 #include <Security/SecInternal.h>
-#include <TargetConditionals.h>
 #include "securityd_client.h"
 #include "securityd_client.h"
-#include "securityd_server.h"
-#include "sqlutils.h"
+#include "utilities/sqlutils.h"
+#include "utilities/SecIOFormat.h"
+#include "utilities/SecFileLocations.h"
+#include <utilities/iCloudKeychainTrace.h>
 #include <AssertMacros.h>
 #include <asl.h>
 #include <inttypes.h>
 #include <AssertMacros.h>
 #include <asl.h>
 #include <inttypes.h>
-
-#if TARGET_OS_EMBEDDED && !TARGET_IPHONE_SIMULATOR
-#define USE_HWAES  1
-#define USE_KEYSTORE  1
-#else /* no hardware aes */
-#define USE_HWAES 0
-#define USE_KEYSTORE  0
-#endif /* hardware aes */
-
-#if USE_HWAES
-#include <IOKit/IOKitLib.h>
-#include <Kernel/IOKit/crypto/IOAESTypes.h>
-#endif /* USE_HWAES */
+#include <utilities/array_size.h>
+#include <utilities/SecDb.h>
+#include <securityd/SOSCloudCircleServer.h>
+#include <notify.h>
+#include "OTATrustUtilities.h"
 
 #if USE_KEYSTORE
 
 #if USE_KEYSTORE
-#include <Kernel/IOKit/crypto/AppleKeyStoreDefs.h>
+#include <IOKit/IOKitLib.h>
+#include <libaks.h>
+#if TARGET_OS_EMBEDDED
 #include <MobileKeyBag/MobileKeyBag.h>
 #include <MobileKeyBag/MobileKeyBag.h>
-typedef int32_t keyclass_t;
-#else
-/* TODO: this needs to be available in the sim! */
-#define kAppleKeyStoreKeyWrap 0
-#define kAppleKeyStoreKeyUnwrap 1
-typedef int32_t keyclass_t;
-typedef int32_t key_handle_t;
-typedef int32_t keybag_handle_t;
-enum key_classes {
-    key_class_ak = 6,
-    key_class_ck,
-    key_class_dk,
-    key_class_aku,
-    key_class_cku,
-    key_class_dku
-};
+#endif
 #endif /* USE_KEYSTORE */
 
 #endif /* USE_KEYSTORE */
 
-/* KEYBAG_LEGACY and KEYBAG_NONE are private to security and have special meaning.
-   They should not collide with AppleKeyStore constants, but are only referenced
-   in here.
- */
-enum {
-    KEYBAG_LEGACY = -3, /* Set q_keybag to KEYBAG_LEGACY to use legacy decrypt. */
-    KEYBAG_BACKUP = -2, /* -2 == backup_keybag_handle, constant dictated by AKS */
-    KEYBAG_NONE =   -1, /* Set q_keybag to KEYBAG_NONE to obtain cleartext data. */
-    KEYBAG_DEVICE = 0, /* 0 == device_keybag_handle, constant dictated by AKS */
-};
 
 
-#if 0
-#include <CoreFoundation/CFPriv.h>
+/* g_keychain_handle is the keybag handle used for encrypting item in the keychain.
+   For testing purposes, it can be set to something other than the default, with SecItemServerSetKeychainKeybag */
+#if USE_KEYSTORE
+#if TARGET_OS_MAC && !TARGET_OS_EMBEDDED
+static keybag_handle_t g_keychain_keybag = session_keybag_handle;
 #else
 #else
-/* Pass NULL for the current user's home directory */
-CF_EXPORT
-CFURLRef CFCopyHomeDirectoryURLForUser(CFStringRef uName);
+static keybag_handle_t g_keychain_keybag = device_keybag_handle;
 #endif
 #endif
+#else /* !USE_KEYSTORE */
+static int32_t g_keychain_keybag = 0; /* 0 == device_keybag_handle, constant dictated by AKS */
+#endif /* USE_KEYSTORE */
 
 
-/* label when certificate data is joined with key data */
-#define CERTIFICATE_DATA_COLUMN_LABEL "certdata" 
-
-#define CURRENT_DB_VERSION 5
-
-#define CLOSE_DB  0
-
-static bool isArray(CFTypeRef cfType) {
-    return cfType && CFGetTypeID(cfType) == CFArrayGetTypeID();
+void SecItemServerSetKeychainKeybag(int32_t keybag)
+{
+    g_keychain_keybag=keybag;
 }
 
 }
 
-static bool isData(CFTypeRef cfType) {
-    return cfType && CFGetTypeID(cfType) == CFDataGetTypeID();
+void SecItemServerResetKeychainKeybag(void)
+{
+#if USE_KEYSTORE
+#if TARGET_OS_MAC && !TARGET_OS_EMBEDDED
+    g_keychain_keybag = session_keybag_handle;
+#else
+    g_keychain_keybag = device_keybag_handle;
+#endif
+#else /* !USE_KEYSTORE */
+    g_keychain_keybag = 0; /* 0 == device_keybag_handle, constant dictated by AKS */
+#endif /* USE_KEYSTORE */
 }
 
 }
 
-static bool isDictionary(CFTypeRef cfType) {
-    return cfType && CFGetTypeID(cfType) == CFDictionaryGetTypeID();
-}
+/* KEYBAG_NONE is private to security and have special meaning.
+   They should not collide with AppleKeyStore constants, but are only referenced
+   in here.
+ */
+#define KEYBAG_NONE (-1)   /* Set q_keybag to KEYBAG_NONE to obtain cleartext data. */
+#define KEYBAG_DEVICE (g_keychain_keybag) /* actual keybag used to encrypt items */
 
 
-static bool isNumber(CFTypeRef cfType) {
-    return cfType && CFGetTypeID(cfType) == CFNumberGetTypeID();
-}
+/* Changed the name of the keychain changed notification, for testing */
+static const char *g_keychain_changed_notification = kSecServerKeychainChangedNotification;
 
 
-static bool isNumberOfType(CFTypeRef cfType, CFNumberType number) {
-    return isNumber(cfType) && CFNumberGetType(cfType) == number;
+void SecItemServerSetKeychainChangedNotification(const char *notification_name)
+{
+    g_keychain_changed_notification = notification_name;
 }
 
 }
 
-static bool isString(CFTypeRef cfType) {
-    return cfType && CFGetTypeID(cfType) == CFStringGetTypeID();
-}
+/* label when certificate data is joined with key data */
+#define CERTIFICATE_DATA_COLUMN_LABEL "certdata"
 
 
-typedef struct s3dl_db
-{
-       char *db_name;
-       pthread_key_t key;
-       pthread_mutex_t mutex;
-       /* Linked list of s3dl_db_thread * */
-       struct s3dl_db_thread *dbt_head;
-       /* True iff crypto facilities are available and keychain key is usable. */
-       bool use_hwaes;
-} s3dl_db;
-
-typedef s3dl_db *db_handle;
-
-typedef struct s3dl_db_thread
-{
-       struct s3dl_db_thread *dbt_next;
-       s3dl_db *db;
-       sqlite3 *s3_handle;
-       bool autocommit;
-       bool in_transaction;
-} s3dl_db_thread;
-
-typedef struct s3dl_results_handle
-{
-    uint32_t recordid;
-    sqlite3_stmt *stmt;
-} s3dl_results_handle;
+#define CURRENT_DB_VERSION 6
 
 
-/* Mapping from class name to kc_class pointer. */
-static CFDictionaryRef gClasses;
+#define CLOSE_DB  0
 
 /* Forward declaration of import export SPIs. */
 enum SecItemFilter {
 
 /* Forward declaration of import export SPIs. */
 enum SecItemFilter {
@@ -192,645 +149,403 @@ enum SecItemFilter {
     kSecBackupableItemFilter,
 };
 
     kSecBackupableItemFilter,
 };
 
-static CFDictionaryRef SecServerExportKeychainPlist(s3dl_db_thread *dbt,
+static CF_RETURNS_RETAINED CFDictionaryRef SecServerExportKeychainPlist(SecDbConnectionRef dbt,
     keybag_handle_t src_keybag, keybag_handle_t dest_keybag,
     keybag_handle_t src_keybag, keybag_handle_t dest_keybag,
-    enum SecItemFilter filter, int version, OSStatus *error);
-static OSStatus SecServerImportKeychainInPlist(s3dl_db_thread *dbt,
+    enum SecItemFilter filter, CFErrorRef *error);
+static bool SecServerImportKeychainInPlist(SecDbConnectionRef dbt,
     keybag_handle_t src_keybag, keybag_handle_t dest_keybag,
     keybag_handle_t src_keybag, keybag_handle_t dest_keybag,
-    CFDictionaryRef keychain, enum SecItemFilter filter);
-
-#if USE_HWAES || USE_KEYSTORE
-/*
- * Encryption support.
- */
-static pthread_once_t hwcrypto_init_once = PTHREAD_ONCE_INIT;
-static io_connect_t hwaes_codec = MACH_PORT_NULL;
-static io_connect_t keystore = MACH_PORT_NULL;
-
-static void service_matching_callback(void *refcon, io_iterator_t iterator)
-{
-       io_object_t obj = IO_OBJECT_NULL;
-
-       while ((obj = IOIteratorNext(iterator))) {
-        kern_return_t ret = IOServiceOpen(obj, mach_task_self(), 0,
-            (io_connect_t*)refcon);
-        if (ret) {
-            asl_log(NULL, NULL, ASL_LEVEL_ERR,
-                "IOServiceOpen() failed: %x", ret);
-        }
-        IOObjectRelease(obj);
-       }
-}
-
-static void connect_to_service(const char *className, io_connect_t *connect)
-{
-       kern_return_t kernResult;
-       io_iterator_t iterator = MACH_PORT_NULL;
-    IONotificationPortRef port = MACH_PORT_NULL;
-       CFDictionaryRef classToMatch;
-
-       if ((classToMatch = IOServiceMatching(className)) == NULL) {
-               asl_log(NULL, NULL, ASL_LEVEL_ERR,
-            "IOServiceMatching failed for '%s'", className);
-               return;
-       }
-
-    /* consumed by IOServiceGetMatchingServices, we need it if that fails. */
-    CFRetain(classToMatch);
-    kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault,
-        classToMatch, &iterator);
-
-    if (kernResult == KERN_SUCCESS) {
-        CFRelease(classToMatch);
-    } else {
-        asl_log(NULL, NULL, ASL_LEVEL_WARNING,
-            "IOServiceGetMatchingServices() failed %x using notifiction",
-            kernResult);
-
-        port = IONotificationPortCreate(kIOMasterPortDefault);
-        if (!port) {
-            asl_log(NULL, NULL, ASL_LEVEL_ERR,
-                "IONotificationPortCreate() failed");
-            return;
-        }
-
-        kernResult = IOServiceAddMatchingNotification(port,
-            kIOFirstMatchNotification, classToMatch, service_matching_callback,
-            connect, &iterator);
-        if (kernResult) {
-            asl_log(NULL, NULL, ASL_LEVEL_ERR,
-                "IOServiceAddMatchingNotification() failed: %x", kernResult);
-            return;
-        }
-    }
-
-    /* Check whether it was already there before we registered for the
-       notification. */
-    service_matching_callback(connect, iterator);
-
-    if (port) {
-        /* We'll get set up to wait for it to appear */
-        if (*connect == MACH_PORT_NULL) {
-            asl_log(NULL, NULL, ASL_LEVEL_ERR,
-                "Waiting for %s to show up.", className);
-            CFStringRef mode = CFSTR("WaitForCryptoService");
-            CFRunLoopAddSource(CFRunLoopGetCurrent(),
-                IONotificationPortGetRunLoopSource(port), mode);
-            CFRunLoopRunInMode(mode, 30.0, true);
-            if (hwaes_codec == MACH_PORT_NULL)
-                asl_log(NULL, NULL, ASL_LEVEL_ERR, "Cannot find AES driver");
-        }
-        IONotificationPortDestroy(port);
-    }
-
-    IOObjectRelease(iterator);
+    CFDictionaryRef keychain, enum SecItemFilter filter, CFErrorRef *error);
 
 
-    if (*connect) {
-        asl_log(NULL, NULL, ASL_LEVEL_INFO, "Obtained connection %d for %s",
-            *connect, className);
-    }
-       return;
-}
-
-static void hwcrypto_init(void)
-{
-    connect_to_service(kIOAESAcceleratorClass, &hwaes_codec);
-    connect_to_service(kAppleKeyStoreServiceName, &keystore);
-
-    if (keystore != MACH_PORT_NULL) {
-        IOReturn kernResult = IOConnectCallMethod(keystore,
-            kAppleKeyStoreUserClientOpen, NULL, 0, NULL, 0, NULL, NULL,
-            NULL, NULL);
-        if (kernResult) {
-            asl_log(NULL, NULL, ASL_LEVEL_ERR,
-                "Failed to open AppleKeyStore: %x", kernResult);
-        } else {
-            asl_log(NULL, NULL, ASL_LEVEL_INFO, "Opened AppleKeyStore");
-        }
-    }
-    /* TODO: Remove this once the kext runs the daemon on demand if
-       there is no system keybag. */
-    int kb_state = MKBGetDeviceLockState(NULL);
-    asl_log(NULL, NULL, ASL_LEVEL_INFO, "AppleKeyStore lock state: %d",
-        kb_state);
-}
-
-static bool hwaes_crypt(IOAESOperation operation, UInt32 keyHandle,
-       UInt32 keySizeInBits, const UInt8 *keyBits, const UInt8 *iv,
-       UInt32 textLength, UInt8 *plainText, UInt8 *cipherText)
-{
-       struct IOAESAcceleratorRequest aesRequest;
-       kern_return_t kernResult;
-       IOByteCount outSize;
-
-    if (!hwaes_codec) {
-               asl_log(NULL, NULL, ASL_LEVEL_ERR, "aes codec not initialized");
-        return false;
-    }
-
-       aesRequest.plainText = plainText;
-       aesRequest.cipherText = cipherText;
-       aesRequest.textLength = textLength;
-       memcpy(aesRequest.iv.ivBytes, iv, 16);
-       aesRequest.operation = operation;
-       aesRequest.keyData.key.keyLength = keySizeInBits;
-    aesRequest.keyData.keyHandle = keyHandle;
-       if (keyBits) {
-               memcpy(aesRequest.keyData.key.keyBytes, keyBits, keySizeInBits / 8);
-       } else {
-               bzero(aesRequest.keyData.key.keyBytes, keySizeInBits / 8);
-       }
-
-       outSize = sizeof(aesRequest);
-       kernResult = IOConnectCallStructMethod(hwaes_codec, 
-               kIOAESAcceleratorPerformAES, &aesRequest, outSize, 
-               &aesRequest, &outSize);
-
-       if (kernResult != KERN_SUCCESS) {
-               asl_log(NULL, NULL, ASL_LEVEL_ERR, "kIOAESAcceleratorPerformAES: %x",
-            kernResult);
-               return false;
-       }
-
-    asl_log(NULL, NULL, ASL_LEVEL_INFO,
-        "kIOAESAcceleratorPerformAES processed: %lu bytes", textLength);
-
-       return true;
-}
+#if USE_KEYSTORE
 
 static bool hwaes_key_available(void)
 {
 
 static bool hwaes_key_available(void)
 {
-    /* The AES driver needs to have a 16byte aligned address */
-    UInt8 buf[32] = {};
-    UInt8 *bufp = (UInt8*)(((intptr_t)&buf[15]) & ~15);
-
-    pthread_once(&hwcrypto_init_once, hwcrypto_init);
-    return hwaes_crypt(IOAESOperationEncrypt,
-               kIOAESAcceleratorKeyHandleKeychain, 128, NULL, bufp, 16, bufp, bufp);
+    keybag_handle_t handle = bad_keybag_handle;
+    keybag_handle_t special_handle = bad_keybag_handle;
+#if TARGET_OS_MAC && !TARGET_OS_EMBEDDED
+    special_handle = session_keybag_handle;
+#elif TARGET_OS_EMBEDDED
+    special_handle = device_keybag_handle;
+#endif
+    kern_return_t kr = aks_get_system(special_handle, &handle);
+    if (kr != kIOReturnSuccess) {
+#if TARGET_OS_EMBEDDED
+        /* TODO: Remove this once the kext runs the daemon on demand if
+         there is no system keybag. */
+        int kb_state = MKBGetDeviceLockState(NULL);
+        asl_log(NULL, NULL, ASL_LEVEL_INFO, "AppleKeyStore lock state: %d", kb_state);
+#endif
+    }
+    return true;
 }
 
 }
 
-
-#else /* !USE_HWAES */
+#else /* !USE_KEYSTORE */
 
 static bool hwaes_key_available(void)
 {
        return false;
 }
 
 
 static bool hwaes_key_available(void)
 {
        return false;
 }
 
-#endif /* !USE_HWAES */
-
-static int s3dl_create_path(const char *path)
-{
-       char pathbuf[PATH_MAX];
-       size_t pos, len = strlen(path);
-       if (len == 0 || len > PATH_MAX)
-               return SQLITE_CANTOPEN;
-       memcpy(pathbuf, path, len);
-       for (pos = len; --pos > 0;)
-       {
-               /* Search backwards for trailing '/'. */
-               if (pathbuf[pos] == '/')
-               {
-                       pathbuf[pos] = '\0';
-                       /* Attempt to create parent directories of the database. */
-                       if (!mkdir(pathbuf, 0777))
-                               break;
-                       else 
-                       {
-                               int err = errno;
-                               if (err == EEXIST)
-                                       return 0;
-                               if (err == ENOTDIR)
-                                       return SQLITE_CANTOPEN;
-                               if (err == EROFS)
-                                       return SQLITE_READONLY;
-                               if (err == EACCES)
-                                       return SQLITE_PERM;
-                               if (err == ENOSPC || err == EDQUOT)
-                                       return SQLITE_FULL;
-                               if (err == EIO)
-                                       return SQLITE_IOERR;
-
-                               /* EFAULT || ELOOP | ENAMETOOLONG || something else */
-                               return SQLITE_INTERNAL;
-                       }
-               }
-       }
-       return 0;
-}
-
-/* Start an exclusive transaction if we don't have one yet. */
-static int s3dl_begin_transaction(s3dl_db_thread *dbt)
-{
-       if (dbt->in_transaction)
-               return dbt->autocommit ? SQLITE_INTERNAL : SQLITE_OK;
-
-       int s3e = sqlite3_exec(dbt->s3_handle, "BEGIN EXCLUSIVE TRANSACTION",
-               NULL, NULL, NULL);
-       if (s3e == SQLITE_OK)
-               dbt->in_transaction = true;
-
-       return s3e;
-}
-
-/* Commit the current transaction if we have one. */
-static int s3dl_commit_transaction(s3dl_db_thread *dbt)
-{
-       if (!dbt->in_transaction)
-               return SQLITE_OK;
-
-       int s3e = sqlite3_exec(dbt->s3_handle, "COMMIT TRANSACTION",
-               NULL, NULL, NULL);
-       if (s3e == SQLITE_OK)
-               dbt->in_transaction = false;
-
-       return s3e;
-}
-
-/* Rollback the current transaction if we have one. */
-static int s3dl_rollback_transaction(s3dl_db_thread *dbt)
-{
-       if (!dbt->in_transaction)
-               return SQLITE_OK;
-
-       int s3e = sqlite3_exec(dbt->s3_handle, "ROLLBACK TRANSACTION",
-               NULL, NULL, NULL);
-       if (s3e == SQLITE_OK)
-               dbt->in_transaction = false;
-
-       return s3e;
-}
-
-/* If we are in a transaction and autocommt is on, commit the transaction
-   if s3e == SQLITE_OK, otherwise rollback the transaction. */
-static int s3dl_end_transaction(s3dl_db_thread *dbt, int s3e)
-{
-       if (dbt->autocommit)
-       {
-               if (s3e == SQLITE_OK)
-                       return s3dl_commit_transaction(dbt);
-               else
-                       s3dl_rollback_transaction(dbt);
-       }
-
-       return s3e;
-}
-
-static int s3dl_close_dbt(s3dl_db_thread *dbt)
-{
-       int s3e = sqlite3_close(dbt->s3_handle);
-       free(dbt);
-       return s3e;
-}
-
-typedef enum {
-    kc_blob_attr,  // CFString or CFData, preserves caller provided type.
-    kc_data_attr,
-    kc_string_attr,
-    kc_number_attr,
-    kc_date_attr,
-    kc_creation_date_attr,
-    kc_modification_date_attr
-} kc_attr_kind;
-
-enum {
-    kc_constrain_not_null = (1 << 0),       // attr value can't be null
-    kc_constrain_default_0 = (1 << 1),      // default attr value is 0
-    kc_constrain_default_empty = (1 << 2),  // default attr value is ""
-    kc_digest_attr = (1 << 3),              // col in db is sha1 of attr value
-};
-
-typedef struct kc_attr_desc {
-    CFStringRef name;
-    kc_attr_kind kind;
-    CFOptionFlags flags;
-} kc_attr_desc;
-
-typedef struct kc_class {
-    CFStringRef name;
-    CFIndex n_attrs;
-    const kc_attr_desc *attrs;
-} kc_class;
-
-#if 0
-typedef struct kc_item {
-    kc_class *c;
-    CFMutableDictionaryRef a;
-} kc_item;
-
-typedef CFIndex kc_attr_id;
-#endif
+#endif /* USE_KEYSTORE */
 
 
-#define KC_ATTR(name, kind, flags) { CFSTR(name), kc_ ## kind ## _attr, flags }
-
-static const kc_attr_desc genp_attrs[] = {
-    KC_ATTR("pdmn", string, 0),
-    KC_ATTR("agrp", string, 0),
-    KC_ATTR("cdat", creation_date, 0),
-    KC_ATTR("mdat", modification_date, 0),
-    KC_ATTR("desc", blob, kc_digest_attr),
-    KC_ATTR("icmt", blob, kc_digest_attr),
-    KC_ATTR("crtr", number, 0),
-    KC_ATTR("type", number, 0),
-    KC_ATTR("scrp", number, 0),
-    KC_ATTR("labl", blob, kc_digest_attr),
-    KC_ATTR("alis", blob, kc_digest_attr),
-    KC_ATTR("invi", number, 0),
-    KC_ATTR("nega", number, 0),
-    KC_ATTR("cusi", number, 0),
-    KC_ATTR("prot", blob, kc_digest_attr),
-    KC_ATTR("acct", blob, kc_constrain_not_null | kc_constrain_default_empty | kc_digest_attr),
-    KC_ATTR("svce", blob, kc_constrain_not_null | kc_constrain_default_empty | kc_digest_attr),
-    KC_ATTR("gena", blob, kc_digest_attr),
-};
-#if 0
-static const kc_attr_id genp_unique[] = {
-    // acct, svce, agrp
-    15, 16, 1
-};
-static kc_class_constraint genp_constraints[] = {
-    { kc_unique_constraint, sizeof(genp_unique) / sizeof(*genp_unique), genp_unique },
-};
-#endif
-static const kc_class genp_class = {
+// MARK -
+// MARK Keychain version 6 schema
+
+#define __FLAGS(ARG, ...) SECDBFLAGS(__VA_ARGS__)
+#define SECDBFLAGS(ARG, ...) __FLAGS_##ARG | __FLAGS(__VA_ARGS__)
+
+#define SecDbFlags(P,L,I,S,A,D,R,C,H,B,Z,E,N) (__FLAGS_##P|__FLAGS_##L|__FLAGS_##I|__FLAGS_##S|__FLAGS_##A|__FLAGS_##D|__FLAGS_##R|__FLAGS_##C|__FLAGS_##H|__FLAGS_##B|__FLAGS_##Z|__FLAGS_##E|__FLAGS_##N)
+
+#define __FLAGS_   0
+#define __FLAGS_P  kSecDbPrimaryKeyFlag
+#define __FLAGS_L  kSecDbInFlag
+#define __FLAGS_I  kSecDbIndexFlag
+#define __FLAGS_S  kSecDbSHA1ValueInFlag
+#define __FLAGS_A  kSecDbReturnAttrFlag
+#define __FLAGS_D  kSecDbReturnDataFlag
+#define __FLAGS_R  kSecDbReturnRefFlag
+#define __FLAGS_C  kSecDbInCryptoDataFlag
+#define __FLAGS_H  kSecDbInHashFlag
+#define __FLAGS_B  kSecDbInBackupFlag
+#define __FLAGS_Z  kSecDbDefault0Flag
+#define __FLAGS_E  kSecDbDefaultEmptyFlag
+#define __FLAGS_N  kSecDbNotNullFlag
+
+//                                                                   ,------------- P : Part of primary key
+//                                                                  / ,------------ L : Stored in local database
+//                                                                 / / ,----------- I : Attribute wants an index in the database
+//                                                                / / / ,---------- S : SHA1 hashed attribute value in database (implies L)
+//                                                               / / / / ,--------- A : Returned to client as attribute in queries
+//                                                              / / / / / ,-------- D : Returned to client as data in queries
+//                                                             / / / / / / ,------- R : Returned to client as ref/persistant ref in queries
+//                                                            / / / / / / / ,------ C : Part of encrypted blob
+//                                                           / / / / / / / / ,----- H : Attribute is part of item SHA1 hash (Implied by C)
+//                                                          / / / / / / / / / ,---- B : Attribute is part of iTunes/iCloud backup bag
+//                                                         / / / / / / / / / / ,--- Z : Attribute has a default value of 0
+//                                                        / / / / / / / / / / / ,-- E : Attribute has a default value of "" or empty data
+//                                                       / / / / / / / / / / / / ,- N : Attribute must have a value
+//                                                      / / / / / / / / / / / / /
+//                                                     / / / / / / / / / / / / /
+//                                                    | | | | | | | | | | | | |
+// common to all                                      | | | | | | | | | | | | |
+SECDB_ATTR(v6rowid, "rowid", RowId,        SecDbFlags( ,L, , , , ,R, , ,B, , , ));
+SECDB_ATTR(v6cdat, "cdat", CreationDate,   SecDbFlags( ,L, , ,A, , ,C,H, , , , ));
+SECDB_ATTR(v6mdat, "mdat",ModificationDate,SecDbFlags( ,L, , ,A, , ,C,H, , , , ));
+SECDB_ATTR(v6labl, "labl", Blob,           SecDbFlags( ,L, ,S,A, , ,C,H, , , , ));
+SECDB_ATTR(v6data, "data", EncryptedData,  SecDbFlags( ,L, , , , , , , ,B, , , ));
+SECDB_ATTR(v6agrp, "agrp", String,         SecDbFlags(P,L, , ,A, , ,C,H, , , , ));
+SECDB_ATTR(v6pdmn, "pdmn", Access,         SecDbFlags( ,L, , ,A, , ,C,H, , , , ));
+SECDB_ATTR(v6sync, "sync", Sync,           SecDbFlags(P,L,I, ,A, , ,C,H, ,Z, ,N));
+SECDB_ATTR(v6tomb, "tomb", Tomb,           SecDbFlags( ,L, , , , , ,C,H, ,Z, ,N));
+SECDB_ATTR(v6sha1, "sha1", SHA1,           SecDbFlags( ,L,I, ,A, ,R, , , , , , ));
+SECDB_ATTR(v6v_Data, "v_Data", Data,       SecDbFlags( , , , , ,D, ,C,H, , , , ));
+SECDB_ATTR(v6v_pk, "v_pk", PrimaryKey,     SecDbFlags( , , , , , , , , , , , , ));
+// genp and inet and keys                             | | | | | | | | | | | | |
+SECDB_ATTR(v6crtr, "crtr", Number,         SecDbFlags( ,L, , ,A, , ,C,H, , , , ));
+SECDB_ATTR(v6alis, "alis", Blob,           SecDbFlags( ,L, ,S,A, , ,C,H, , , , ));
+// genp and inet                                      | | | | | | | | | | | | |
+SECDB_ATTR(v6desc, "desc", Blob,           SecDbFlags( ,L, ,S,A, , ,C,H, , , , ));
+SECDB_ATTR(v6icmt, "icmt", Blob,           SecDbFlags( ,L, ,S,A, , ,C,H, , , , ));
+SECDB_ATTR(v6type, "type", Number,         SecDbFlags( ,L, , ,A, , ,C,H, , , , ));
+SECDB_ATTR(v6invi, "invi", Number,         SecDbFlags( ,L, , ,A, , ,C,H, , , , ));
+SECDB_ATTR(v6nega, "nega", Number,         SecDbFlags( ,L, , ,A, , ,C,H, , , , ));
+SECDB_ATTR(v6cusi, "cusi", Number,         SecDbFlags( ,L, , ,A, , ,C,H, , , , ));
+SECDB_ATTR(v6prot, "prot", Blob,           SecDbFlags( ,L, ,S,A, , ,C,H, , , , ));
+SECDB_ATTR(v6scrp, "scrp", Number,         SecDbFlags( ,L, , ,A, , ,C,H, , , , ));
+SECDB_ATTR(v6acct, "acct", Blob,           SecDbFlags(P,L, ,S,A, , ,C,H, , ,E,N));
+// genp only                                          | | | | | | | | | | | | |
+SECDB_ATTR(v6svce, "svce", Blob,           SecDbFlags(P,L, ,S,A, , ,C,H, , ,E,N));
+SECDB_ATTR(v6gena, "gena", Blob,           SecDbFlags( ,L, ,S,A, , ,C,H, , , , ));
+// inet only                                          | | | | | | | | | | | | |
+SECDB_ATTR(v6sdmn, "sdmn", Blob,           SecDbFlags(P,L, ,S,A, , ,C,H, , ,E,N));
+SECDB_ATTR(v6srvr, "srvr", Blob,           SecDbFlags(P,L, ,S,A, , ,C,H, , ,E,N));
+SECDB_ATTR(v6ptcl, "ptcl", Number,         SecDbFlags(P,L, , ,A, , ,C,H, ,Z, ,N));
+SECDB_ATTR(v6atyp, "atyp", Blob,           SecDbFlags(P,L, ,S,A, , ,C,H, , ,E,N));
+SECDB_ATTR(v6port, "port", Number,         SecDbFlags(P,L, , ,A, , ,C,H, ,Z, ,N));
+SECDB_ATTR(v6path, "path", Blob,           SecDbFlags(P,L, ,S,A, , ,C,H, , ,E,N));
+// cert only                                          | | | | | | | | | | | | |
+SECDB_ATTR(v6ctyp, "ctyp", Number,         SecDbFlags(P,L, , ,A, , ,C,H, ,Z, ,N));
+SECDB_ATTR(v6cenc, "cenc", Number,         SecDbFlags( ,L, , ,A, , ,C,H, , , , ));
+SECDB_ATTR(v6subj, "subj", Data,           SecDbFlags( ,L,I,S,A, , ,C,H, , , , ));
+SECDB_ATTR(v6issr, "issr", Data,           SecDbFlags(P,L, ,S,A, , ,C,H, , ,E,N));
+SECDB_ATTR(v6slnr, "slnr", Data,           SecDbFlags(P,L, ,S,A, , ,C,H, , ,E,N));
+SECDB_ATTR(v6skid, "skid", Data,           SecDbFlags( ,L,I,S,A, , ,C,H, , , , ));
+SECDB_ATTR(v6pkhh, "pkhh", Data,           SecDbFlags( ,L,I, ,A, , ,C,H, , , , ));
+// cert attributes that share names with common ones but have different flags
+SECDB_ATTR(v6certalis, "alis", Blob,       SecDbFlags( ,L,I,S,A, , ,C,H, , , , ));
+// keys only                                          | | | | | | | | | | | | |
+SECDB_ATTR(v6kcls, "kcls", Number,         SecDbFlags(P,L,I,S,A, , ,C,H, ,Z, ,N));
+SECDB_ATTR(v6perm, "perm", Number,         SecDbFlags( ,L, , ,A, , ,C,H, , , , ));
+SECDB_ATTR(v6priv, "priv", Number,         SecDbFlags( ,L, , ,A, , ,C,H, , , , ));
+SECDB_ATTR(v6modi, "modi", Number,         SecDbFlags( ,L, , ,A, , ,C,H, , , , ));
+SECDB_ATTR(v6klbl, "klbl", Data,           SecDbFlags(P,L,I, ,A, , ,C,H, , ,E,N));
+SECDB_ATTR(v6atag, "atag", Blob,           SecDbFlags(P,L, ,S,A, , ,C,H, , ,E,N));
+SECDB_ATTR(v6bsiz, "bsiz", Number,         SecDbFlags(P,L, , ,A, , ,C,H, ,Z, ,N));
+SECDB_ATTR(v6esiz, "esiz", Number,         SecDbFlags(P,L, , ,A, , ,C,H, ,Z, ,N));
+SECDB_ATTR(v6sdat, "sdat", Date,           SecDbFlags(P,L, , ,A, , ,C,H, ,Z, ,N));
+SECDB_ATTR(v6edat, "edat", Date,           SecDbFlags(P,L, , ,A, , ,C,H, ,Z, ,N));
+SECDB_ATTR(v6sens, "sens", Number,         SecDbFlags( ,L, , ,A, , ,C,H, , , , ));
+SECDB_ATTR(v6asen, "asen", Number,         SecDbFlags( ,L, , ,A, , ,C,H, , , , ));
+SECDB_ATTR(v6extr, "extr", Number,         SecDbFlags( ,L, , ,A, , ,C,H, , , , ));
+SECDB_ATTR(v6next, "next", Number,         SecDbFlags( ,L, , ,A, , ,C,H, , , , ));
+SECDB_ATTR(v6encr, "encr", Number,         SecDbFlags( ,L,I, ,A, , ,C,H, , , , ));
+SECDB_ATTR(v6decr, "decr", Number,         SecDbFlags( ,L,I, ,A, , ,C,H, , , , ));
+SECDB_ATTR(v6drve, "drve", Number,         SecDbFlags( ,L,I, ,A, , ,C,H, , , , ));
+SECDB_ATTR(v6sign, "sign", Number,         SecDbFlags( ,L,I, ,A, , ,C,H, , , , ));
+SECDB_ATTR(v6vrfy, "vrfy", Number,         SecDbFlags( ,L,I, ,A, , ,C,H, , , , ));
+SECDB_ATTR(v6snrc, "snrc", Number,         SecDbFlags( ,L, , ,A, , ,C,H, , , , ));
+SECDB_ATTR(v6vyrc, "vyrc", Number,         SecDbFlags( ,L, , ,A, , ,C,H, , , , ));
+SECDB_ATTR(v6wrap, "wrap", Number,         SecDbFlags( ,L,I, ,A, , ,C,H, , , , ));
+SECDB_ATTR(v6unwp, "unwp", Number,         SecDbFlags( ,L,I, ,A, , ,C,H, , , , ));
+// keys attributes that share names with common ones but have different flags
+SECDB_ATTR(v6keytype, "type", Number,      SecDbFlags(P,L, , ,A, , ,C,H, ,Z, ,N));
+SECDB_ATTR(v6keycrtr, "crtr", Number,      SecDbFlags(P,L, , ,A, , ,C,H, ,Z, ,N));
+
+static const SecDbClass genp_class = {
     .name = CFSTR("genp"),
     .name = CFSTR("genp"),
-    .n_attrs = sizeof(genp_attrs) / sizeof(*genp_attrs),
-    .attrs = genp_attrs,
+    .attrs = {
+        &v6rowid,
+        &v6cdat,
+        &v6mdat,
+        &v6desc,
+        &v6icmt,
+        &v6crtr,
+        &v6type,
+        &v6scrp,
+        &v6labl,
+        &v6alis,
+        &v6invi,
+        &v6nega,
+        &v6cusi,
+        &v6prot,
+        &v6acct,
+        &v6svce,
+        &v6gena,
+        &v6data,
+        &v6agrp,
+        &v6pdmn,
+        &v6sync,
+        &v6tomb,
+        &v6sha1,
+        &v6v_Data,
+        &v6v_pk,
+        NULL
+    },
 };
 
 };
 
-static const kc_attr_desc inet_attrs[] = {
-    KC_ATTR("pdmn", string, 0),
-    KC_ATTR("agrp", string, 0),
-    KC_ATTR("cdat", creation_date, 0),
-    KC_ATTR("mdat", modification_date, 0),
-    KC_ATTR("desc", blob, kc_digest_attr),
-    KC_ATTR("icmt", blob, kc_digest_attr),
-    KC_ATTR("crtr", number, 0),
-    KC_ATTR("type", number, 0),
-    KC_ATTR("scrp", number, 0),
-    KC_ATTR("labl", blob, kc_digest_attr),
-    KC_ATTR("alis", blob, kc_digest_attr),
-    KC_ATTR("invi", number, 0),
-    KC_ATTR("nega", number, 0),
-    KC_ATTR("cusi", number, 0),
-    KC_ATTR("prot", blob, kc_digest_attr),
-    KC_ATTR("acct", blob, kc_constrain_not_null | kc_constrain_default_empty | kc_digest_attr),
-    KC_ATTR("sdmn", blob, kc_constrain_not_null | kc_constrain_default_empty | kc_digest_attr),
-    KC_ATTR("srvr", blob, kc_constrain_not_null | kc_constrain_default_empty | kc_digest_attr),
-    KC_ATTR("ptcl", number, kc_constrain_not_null | kc_constrain_default_0),
-    KC_ATTR("atyp", blob, kc_digest_attr),
-    KC_ATTR("port", number, kc_constrain_not_null | kc_constrain_default_0),
-    KC_ATTR("path", blob, kc_constrain_not_null | kc_constrain_default_empty | kc_digest_attr),
-};
-#if 0
-static const kc_attr_id inet_unique[] = {
-    // acct, sdmn, srvr, ptcl, atyp, port, path, agrp
-    15, 16, 17, 18, 19, 20, 21, 1
-};
-static kc_class_constraint inet_constraints[] = {
-    { kc_unique_constraint, sizeof(inet_unique) / sizeof(*inet_unique), inet_unique },
-};
-#endif
-static const kc_class inet_class = {
+static const SecDbClass inet_class = {
     .name = CFSTR("inet"),
     .name = CFSTR("inet"),
-    .n_attrs = sizeof(inet_attrs) / sizeof(*inet_attrs),
-    .attrs = inet_attrs,
+    .attrs = {
+        &v6rowid,
+        &v6cdat,
+        &v6mdat,
+        &v6desc,
+        &v6icmt,
+        &v6crtr,
+        &v6type,
+        &v6scrp,
+        &v6labl,
+        &v6alis,
+        &v6invi,
+        &v6nega,
+        &v6cusi,
+        &v6prot,
+        &v6acct,
+        &v6sdmn,
+        &v6srvr,
+        &v6ptcl,
+        &v6atyp,
+        &v6port,
+        &v6path,
+        &v6data,
+        &v6agrp,
+        &v6pdmn,
+        &v6sync,
+        &v6tomb,
+        &v6sha1,
+        &v6v_Data,
+        &v6v_pk,
+        0
+    },
 };
 
 };
 
-static const kc_attr_desc cert_attrs[] = {
-    KC_ATTR("pdmn", string, 0),
-    KC_ATTR("agrp", string, 0),
-    KC_ATTR("cdat", creation_date, 0),
-    KC_ATTR("mdat", modification_date, 0),
-    KC_ATTR("ctyp", number, kc_constrain_not_null | kc_constrain_default_0),
-    KC_ATTR("cenc", number, 0),
-    KC_ATTR("labl", blob, kc_digest_attr),
-    KC_ATTR("alis", blob, kc_digest_attr),
-    KC_ATTR("subj", data, kc_digest_attr),
-    KC_ATTR("issr", data, kc_constrain_not_null | kc_constrain_default_empty | kc_digest_attr),
-    KC_ATTR("slnr", data, kc_constrain_not_null | kc_constrain_default_empty | kc_digest_attr),
-    KC_ATTR("skid", data, kc_digest_attr),
-    KC_ATTR("pkhh", data, 0),
-};
-#if 0
-static const kc_attr_id cert_unique[] = {
-    //ctyp, issr, slnr, agrp
-    2, 7, 8, 1
-};
-static kc_class_constraint cert_constraints[] = {
-    { kc_unique_constraint, sizeof(cert_unique) / sizeof(*cert_unique), cert_unique, },
-};
-#endif
-static const kc_class cert_class = {
+static const SecDbClass cert_class = {
     .name = CFSTR("cert"),
     .name = CFSTR("cert"),
-    .n_attrs = sizeof(cert_attrs) / sizeof(*cert_attrs),
-    .attrs = cert_attrs,
+    .attrs = {
+        &v6rowid,
+        &v6cdat,
+        &v6mdat,
+        &v6ctyp,
+        &v6cenc,
+        &v6labl,
+        &v6certalis,
+        &v6subj,
+        &v6issr,
+        &v6slnr,
+        &v6skid,
+        &v6pkhh,
+        &v6data,
+        &v6agrp,
+        &v6pdmn,
+        &v6sync,
+        &v6tomb,
+        &v6sha1,
+        &v6v_Data,
+        &v6v_pk,
+        0
+    },
 };
 
 };
 
-static const kc_attr_desc keys_attrs[] = {
-    KC_ATTR("pdmn", string, 0),
-    KC_ATTR("agrp", string, 0),
-    KC_ATTR("cdat", creation_date, 0),
-    KC_ATTR("mdat", modification_date, 0),
-    KC_ATTR("kcls", number, kc_constrain_not_null | kc_constrain_default_0),
-    KC_ATTR("labl", blob, kc_digest_attr),
-    KC_ATTR("alis", blob, kc_digest_attr),
-    KC_ATTR("perm", number, 0),
-    KC_ATTR("priv", number, 0),
-    KC_ATTR("modi", number, 0),
-    KC_ATTR("klbl", data, kc_constrain_not_null | kc_constrain_default_empty),
-    KC_ATTR("atag", blob, kc_constrain_not_null | kc_constrain_default_empty | kc_digest_attr),
-    KC_ATTR("crtr", number, kc_constrain_not_null | kc_constrain_default_0),
-    KC_ATTR("type", number, kc_constrain_not_null | kc_constrain_default_0),
-    KC_ATTR("bsiz", number, kc_constrain_not_null | kc_constrain_default_0),
-    KC_ATTR("esiz", number, kc_constrain_not_null | kc_constrain_default_0),
-    KC_ATTR("sdat", date, kc_constrain_not_null | kc_constrain_default_0),
-    KC_ATTR("edat", date, kc_constrain_not_null | kc_constrain_default_0),
-    KC_ATTR("sens", number, 0),
-    KC_ATTR("asen", number, 0),
-    KC_ATTR("extr", number, 0),
-    KC_ATTR("next", number, 0),
-    KC_ATTR("encr", number, 0),
-    KC_ATTR("decr", number, 0),
-    KC_ATTR("drve", number, 0),
-    KC_ATTR("sign", number, 0),
-    KC_ATTR("vrfy", number, 0),
-    KC_ATTR("snrc", number, 0),
-    KC_ATTR("vyrc", number, 0),
-    KC_ATTR("wrap", number, 0),
-    KC_ATTR("unwp", number, 0),
-};
-#if 0
-static const kc_attr_id keys_unique[] = {
-    // kcls, klbl, atag, crtr, type, bsiz, esiz, sdat, edat, agrp
-    2, 8, 9, 10, 11, 12, 13, 14, 15, 1
-};
-static kc_class_constraint keys_constraints[] = {
-    { kc_unique_constraint, sizeof(keys_unique) / sizeof(*keys_unique), keys_unique, },
-};
-#endif
-static const kc_class keys_class = {
+static const SecDbClass keys_class = {
     .name = CFSTR("keys"),
     .name = CFSTR("keys"),
-    .n_attrs = sizeof(keys_attrs) / sizeof(*keys_attrs),
-    .attrs = keys_attrs,
+    .attrs = {
+        &v6rowid,
+        &v6cdat,
+        &v6mdat,
+        &v6kcls,
+        &v6labl,
+        &v6alis,
+        &v6perm,
+        &v6priv,
+        &v6modi,
+        &v6klbl,
+        &v6atag,
+        &v6keycrtr,
+        &v6keytype,
+        &v6bsiz,
+        &v6esiz,
+        &v6sdat,
+        &v6edat,
+        &v6sens,
+        &v6asen,
+        &v6extr,
+        &v6next,
+        &v6encr,
+        &v6decr,
+        &v6drve,
+        &v6sign,
+        &v6vrfy,
+        &v6snrc,
+        &v6vyrc,
+        &v6wrap,
+        &v6unwp,
+        &v6data,
+        &v6agrp,
+        &v6pdmn,
+        &v6sync,
+        &v6tomb,
+        &v6sha1,
+        &v6v_Data,
+        &v6v_pk,
+        0
+    }
 };
 
 /* An identity which is really a cert + a key, so all cert and keys attrs are
  allowed. */
 };
 
 /* An identity which is really a cert + a key, so all cert and keys attrs are
  allowed. */
-static const kc_class identity_class = {
+static const SecDbClass identity_class = {
     .name = CFSTR("idnt"),
     .name = CFSTR("idnt"),
-    .n_attrs = 0,
-    .attrs = NULL,
+    .attrs = {
+        0
+    },
 };
 
 };
 
-static const kc_attr_desc *kc_attr_desc_with_key(const kc_class *c,
-                                                 CFTypeRef key,
-                                                 OSStatus *error) {
+static const SecDbAttr *SecDbAttrWithKey(const SecDbClass *c,
+                                         CFTypeRef key,
+                                         CFErrorRef *error) {
     /* Special case: identites can have all attributes of either cert
        or keys. */
     if (c == &identity_class) {
     /* Special case: identites can have all attributes of either cert
        or keys. */
     if (c == &identity_class) {
-        const kc_attr_desc *desc;
-        if (!(desc = kc_attr_desc_with_key(&cert_class, key, 0)))
-            desc = kc_attr_desc_with_key(&keys_class, key, error);
+        const SecDbAttr *desc;
+        if (!(desc = SecDbAttrWithKey(&cert_class, key, 0)))
+            desc = SecDbAttrWithKey(&keys_class, key, error);
         return desc;
     }
 
     if (isString(key)) {
         return desc;
     }
 
     if (isString(key)) {
-        CFIndex ix;
-        for (ix = 0; ix < c->n_attrs; ++ix) {
-            if (CFEqual(c->attrs[ix].name, key)) {
-                return &c->attrs[ix];
-            }
+        SecDbForEachAttr(c, a) {
+            if (CFEqual(a->name, key))
+                return a;
         }
         }
+    }
 
 
-        /* TODO: Remove this hack since it's violating this function's contract to always set an error when it returns NULL. */
-        if (CFEqual(key, kSecAttrSynchronizable))
-            return NULL;
+    SecError(errSecNoSuchAttr, error, CFSTR("attribute %@ not found in class %@"), key, c->name);
+
+    return NULL;
+}
 
 
+static bool kc_transaction(SecDbConnectionRef dbt, CFErrorRef *error, bool(^perform)()) {
+    __block bool ok = true;
+    return ok && SecDbTransaction(dbt, kSecDbExclusiveTransactionType, error, ^(bool *commit) {
+        ok = *commit = perform();
+    });
+}
+
+static CFStringRef SecDbGetKindSQL(SecDbAttrKind kind) {
+    switch (kind) {
+        case kSecDbBlobAttr:
+        case kSecDbDataAttr:
+        case kSecDbSHA1Attr:
+        case kSecDbPrimaryKeyAttr:
+        case kSecDbEncryptedDataAttr:
+            return CFSTR("BLOB");
+        case kSecDbAccessAttr:
+        case kSecDbStringAttr:
+            return CFSTR("TEXT");
+        case kSecDbNumberAttr:
+        case kSecDbSyncAttr:
+        case kSecDbTombAttr:
+            return CFSTR("INTEGER");
+        case kSecDbDateAttr:
+        case kSecDbCreationDateAttr:
+        case kSecDbModificationDateAttr:
+            return CFSTR("REAL");
+        case kSecDbRowIdAttr:
+            return CFSTR("INTEGER PRIMARY KEY AUTOINCREMENT");
     }
     }
+}
 
 
-    if (error && !*error)
-        *error = errSecNoSuchAttr;
+static void SecDbAppendUnqiue(CFMutableStringRef sql, CFStringRef value, bool *haveUnique) {
+    assert(haveUnique);
+    if (!*haveUnique)
+        CFStringAppend(sql, CFSTR("UNIQUE("));
 
 
-    return NULL;
+    SecDbAppendElement(sql, value, haveUnique);
+}
+
+static void SecDbAppendCreateTableWithClass(CFMutableStringRef sql, const SecDbClass *c) {
+    CFStringAppendFormat(sql, 0, CFSTR("CREATE TABLE %@("), c->name);
+    SecDbForEachAttrWithMask(c,desc,kSecDbInFlag) {
+        CFStringAppendFormat(sql, 0, CFSTR("%@ %@"), desc->name, SecDbGetKindSQL(desc->kind));
+        if (desc->flags & kSecDbNotNullFlag)
+            CFStringAppend(sql, CFSTR(" NOT NULL"));
+        if (desc->flags & kSecDbDefault0Flag)
+            CFStringAppend(sql, CFSTR(" DEFAULT 0"));
+        if (desc->flags & kSecDbDefaultEmptyFlag)
+            CFStringAppend(sql, CFSTR(" DEFAULT ''"));
+        CFStringAppend(sql, CFSTR(","));
+    }
+
+    bool haveUnique = false;
+    SecDbForEachAttrWithMask(c,desc,kSecDbPrimaryKeyFlag | kSecDbInFlag) {
+        SecDbAppendUnqiue(sql, desc->name, &haveUnique);
+    }
+    if (haveUnique)
+        CFStringAppend(sql, CFSTR(")"));
+
+    CFStringAppend(sql, CFSTR(");"));
 }
 
 static const char * const s3dl_upgrade_sql[] = {
     /* 0 */
 }
 
 static const char * const s3dl_upgrade_sql[] = {
     /* 0 */
-    /* Upgrade from version 0 -- empty db a.k.a. current schema. */
-    "CREATE TABLE genp("
-    "rowid INTEGER PRIMARY KEY AUTOINCREMENT,"
-    "cdat REAL,"
-    "mdat REAL,"
-    "desc BLOB,"
-    "icmt BLOB,"
-    "crtr INTEGER,"
-    "type INTEGER,"
-    "scrp INTEGER,"
-    "labl BLOB,"
-    "alis BLOB,"
-    "invi INTEGER,"
-    "nega INTEGER,"
-    "cusi INTEGER,"
-    "prot BLOB,"
-    "acct BLOB NOT NULL DEFAULT '',"
-    "svce BLOB NOT NULL DEFAULT '',"
-    "gena BLOB,"
-    "data BLOB,"
-    "agrp TEXT,"
-    "pdmn TEXT,"
-    "UNIQUE("
-    "acct,svce,agrp"
-    "));"
-    "CREATE TABLE inet("
-    "rowid INTEGER PRIMARY KEY AUTOINCREMENT,"
-    "cdat REAL,"
-    "mdat REAL,"
-    "desc BLOB,"
-    "icmt BLOB,"
-    "crtr INTEGER,"
-    "type INTEGER,"
-    "scrp INTEGER,"
-    "labl BLOB,"
-    "alis BLOB,"
-    "invi INTEGER,"
-    "nega INTEGER,"
-    "cusi INTEGER,"
-    "prot BLOB,"
-    "acct BLOB NOT NULL DEFAULT '',"
-    "sdmn BLOB NOT NULL DEFAULT '',"
-    "srvr BLOB NOT NULL DEFAULT '',"
-    "ptcl INTEGER NOT NULL DEFAULT 0,"
-    "atyp BLOB NOT NULL DEFAULT '',"
-    "port INTEGER NOT NULL DEFAULT 0,"
-    "path BLOB NOT NULL DEFAULT '',"
-    "data BLOB,"
-    "agrp TEXT,"
-    "pdmn TEXT,"
-    "UNIQUE("
-    "acct,sdmn,srvr,ptcl,atyp,port,path,agrp"
-    "));"
-    "CREATE TABLE cert("
-    "rowid INTEGER PRIMARY KEY AUTOINCREMENT,"
-    "cdat REAL,"
-    "mdat REAL,"
-    "ctyp INTEGER NOT NULL DEFAULT 0,"
-    "cenc INTEGER,"
-    "labl BLOB,"
-    "alis BLOB,"
-    "subj BLOB,"
-    "issr BLOB NOT NULL DEFAULT '',"
-    "slnr BLOB NOT NULL DEFAULT '',"
-    "skid BLOB,"
-    "pkhh BLOB,"
-    "data BLOB,"
-    "agrp TEXT,"
-    "pdmn TEXT,"
-    "UNIQUE("
-    "ctyp,issr,slnr,agrp"
-    "));"
-    "CREATE TABLE keys("
-    "rowid INTEGER PRIMARY KEY AUTOINCREMENT,"
-    "cdat REAL,"
-    "mdat REAL,"
-    "kcls INTEGER NOT NULL DEFAULT 0,"
-    "labl BLOB,"
-    "alis BLOB,"
-    "perm INTEGER,"
-    "priv INTEGER,"
-    "modi INTEGER,"
-    "klbl BLOB NOT NULL DEFAULT '',"
-    "atag BLOB NOT NULL DEFAULT '',"
-    "crtr INTEGER NOT NULL DEFAULT 0,"
-    "type INTEGER NOT NULL DEFAULT 0,"
-    "bsiz INTEGER NOT NULL DEFAULT 0,"
-    "esiz INTEGER NOT NULL DEFAULT 0,"
-    "sdat REAL NOT NULL DEFAULT 0,"
-    "edat REAL NOT NULL DEFAULT 0,"
-    "sens INTEGER,"
-    "asen INTEGER,"
-    "extr INTEGER,"
-    "next INTEGER,"
-    "encr INTEGER,"
-    "decr INTEGER,"
-    "drve INTEGER,"
-    "sign INTEGER,"
-    "vrfy INTEGER,"
-    "snrc INTEGER,"
-    "vyrc INTEGER,"
-    "wrap INTEGER,"
-    "unwp INTEGER,"
-    "data BLOB,"
-    "agrp TEXT,"
-    "pdmn TEXT,"
-    "UNIQUE("
-    "kcls,klbl,atag,crtr,type,bsiz,esiz,sdat,edat,agrp"
-    "));"
-    "CREATE TABLE tversion(version INTEGER);"
-    "INSERT INTO tversion(version) VALUES(5);",
+    "",
 
     /* 1 */
     /* Create indices. */
 
     /* 1 */
     /* Create indices. */
+    "CREATE INDEX igsha ON genp(sha1);"
+    "CREATE INDEX iisha ON inet(sha1);"
+    "CREATE INDEX icsha ON cert(sha1);"
+    "CREATE INDEX iksha ON keys(sha1);"
     "CREATE INDEX ialis ON cert(alis);"
     "CREATE INDEX isubj ON cert(subj);"
     "CREATE INDEX iskid ON cert(skid);"
     "CREATE INDEX ialis ON cert(alis);"
     "CREATE INDEX isubj ON cert(subj);"
     "CREATE INDEX iskid ON cert(skid);"
@@ -846,11 +561,7 @@ static const char * const s3dl_upgrade_sql[] = {
     "CREATE INDEX iunwp ON keys(unwp);",
 
     /* 2 */
     "CREATE INDEX iunwp ON keys(unwp);",
 
     /* 2 */
-    /* Rename version 1 tables. */
-    "ALTER TABLE genp RENAME TO ogenp;"
-    "ALTER TABLE inet RENAME TO oinet;"
-    "ALTER TABLE cert RENAME TO ocert;"
-    "ALTER TABLE keys RENAME TO okeys;",
+    "",
 
     /* 3 */
     /* Rename version 2 or version 3 tables and drop version table since
 
     /* 3 */
     /* Rename version 2 or version 3 tables and drop version table since
@@ -862,458 +573,208 @@ static const char * const s3dl_upgrade_sql[] = {
     "DROP TABLE tversion;",
 
     /* 4 */
     "DROP TABLE tversion;",
 
     /* 4 */
-    /* Move data from version 1 or version 2 tables to new ones and drop old
-       ones. */
-    /* Set the agrp on all (apple internal) items to apple. */
-    "INSERT INTO genp (rowid,cdat,mdat,desc,icmt,crtr,type,scrp,labl,alis,invi,nega,cusi,prot,acct,svce,gena,data) SELECT rowid,cdat,mdat,desc,icmt,crtr,type,scrp,labl,alis,invi,nega,cusi,prot,acct,svce,gena,data from ogenp;"
-    "INSERT INTO inet (rowid,cdat,mdat,desc,icmt,crtr,type,scrp,labl,alis,invi,nega,cusi,prot,acct,sdmn,srvr,ptcl,atyp,port,path,data) SELECT rowid,cdat,mdat,desc,icmt,crtr,type,scrp,labl,alis,invi,nega,cusi,prot,acct,sdmn,srvr,ptcl,atyp,port,path,data from oinet;"
-    "INSERT INTO cert (rowid,ctyp,cenc,labl,alis,subj,issr,slnr,skid,pkhh,data) SELECT rowid,ctyp,cenc,labl,alis,subj,issr,slnr,skid,pkhh,data from ocert;"
-    "INSERT INTO keys (rowid,kcls,labl,alis,perm,priv,modi,klbl,atag,crtr,type,bsiz,esiz,sdat,edat,sens,asen,extr,next,encr,decr,drve,sign,vrfy,snrc,vyrc,wrap,unwp,data) SELECT rowid,kcls,labl,alis,perm,priv,modi,klbl,atag,crtr,type,bsiz,esiz,sdat,edat,sens,asen,extr,next,encr,decr,drve,sign,vrfy,snrc,vyrc,wrap,unwp,data from okeys;"
-    "UPDATE genp SET agrp='apple';"
-    "UPDATE inet SET agrp='apple';"
-    "UPDATE cert SET agrp='apple';"
-    "UPDATE keys SET agrp='apple';"
-    "DROP TABLE ogenp;"
-    "DROP TABLE oinet;"
-    "DROP TABLE ocert;"
-    "DROP TABLE okeys;",
+    "",
 
     /* 5 */
 
     /* 5 */
-    /* Move data from version 3 tables to new ones and drop old ones. */
-    "INSERT INTO genp (rowid,cdat,mdat,desc,icmt,crtr,type,scrp,labl,alis,invi,nega,cusi,prot,acct,svce,gena,data,agrp) SELECT rowid,cdat,mdat,desc,icmt,crtr,type,scrp,labl,alis,invi,nega,cusi,prot,acct,svce,gena,data,agrp from ogenp;"
-    "INSERT INTO inet (rowid,cdat,mdat,desc,icmt,crtr,type,scrp,labl,alis,invi,nega,cusi,prot,acct,sdmn,srvr,ptcl,atyp,port,path,data,agrp) SELECT rowid,cdat,mdat,desc,icmt,crtr,type,scrp,labl,alis,invi,nega,cusi,prot,acct,sdmn,srvr,ptcl,atyp,port,path,data,agrp from oinet;"
-    "INSERT INTO cert (rowid,ctyp,cenc,labl,alis,subj,issr,slnr,skid,pkhh,data,agrp) SELECT rowid,ctyp,cenc,labl,alis,subj,issr,slnr,skid,pkhh,data,agrp from ocert;"
-    "INSERT INTO keys (rowid,kcls,labl,alis,perm,priv,modi,klbl,atag,crtr,type,bsiz,esiz,sdat,edat,sens,asen,extr,next,encr,decr,drve,sign,vrfy,snrc,vyrc,wrap,unwp,data,agrp) SELECT rowid,kcls,labl,alis,perm,priv,modi,klbl,atag,crtr,type,bsiz,esiz,sdat,edat,sens,asen,extr,next,encr,decr,drve,sign,vrfy,snrc,vyrc,wrap,unwp,data,agrp from okeys;"
-    "DROP TABLE ogenp;"
-    "DROP TABLE oinet;"
-    "DROP TABLE ocert;"
-    "DROP TABLE okeys;",
+    "",
 
     /* 6 */
 
     /* 6 */
-    /* Move data from version 4 tables to new ones and drop old ones. */
+    "",
+
+    /* 7 */
+    /* Move data from version 5 tables to new ones and drop old ones. */
     "INSERT INTO genp (rowid,cdat,mdat,desc,icmt,crtr,type,scrp,labl,alis,invi,nega,cusi,prot,acct,svce,gena,data,agrp,pdmn) SELECT rowid,cdat,mdat,desc,icmt,crtr,type,scrp,labl,alis,invi,nega,cusi,prot,acct,svce,gena,data,agrp,pdmn from ogenp;"
     "INSERT INTO inet (rowid,cdat,mdat,desc,icmt,crtr,type,scrp,labl,alis,invi,nega,cusi,prot,acct,sdmn,srvr,ptcl,atyp,port,path,data,agrp,pdmn) SELECT rowid,cdat,mdat,desc,icmt,crtr,type,scrp,labl,alis,invi,nega,cusi,prot,acct,sdmn,srvr,ptcl,atyp,port,path,data,agrp,pdmn from oinet;"
     "INSERT INTO genp (rowid,cdat,mdat,desc,icmt,crtr,type,scrp,labl,alis,invi,nega,cusi,prot,acct,svce,gena,data,agrp,pdmn) SELECT rowid,cdat,mdat,desc,icmt,crtr,type,scrp,labl,alis,invi,nega,cusi,prot,acct,svce,gena,data,agrp,pdmn from ogenp;"
     "INSERT INTO inet (rowid,cdat,mdat,desc,icmt,crtr,type,scrp,labl,alis,invi,nega,cusi,prot,acct,sdmn,srvr,ptcl,atyp,port,path,data,agrp,pdmn) SELECT rowid,cdat,mdat,desc,icmt,crtr,type,scrp,labl,alis,invi,nega,cusi,prot,acct,sdmn,srvr,ptcl,atyp,port,path,data,agrp,pdmn from oinet;"
-    "INSERT INTO cert (rowid,ctyp,cenc,labl,alis,subj,issr,slnr,skid,pkhh,data,agrp,pdmn) SELECT rowid,ctyp,cenc,labl,alis,subj,issr,slnr,skid,pkhh,data,agrp,pdmn from ocert;"
-    "INSERT INTO keys (rowid,kcls,labl,alis,perm,priv,modi,klbl,atag,crtr,type,bsiz,esiz,sdat,edat,sens,asen,extr,next,encr,decr,drve,sign,vrfy,snrc,vyrc,wrap,unwp,data,agrp,pdmn) SELECT rowid,kcls,labl,alis,perm,priv,modi,klbl,atag,crtr,type,bsiz,esiz,sdat,edat,sens,asen,extr,next,encr,decr,drve,sign,vrfy,snrc,vyrc,wrap,unwp,data,agrp,pdmn from okeys;"
+    "INSERT INTO cert (rowid,cdat,mdat,ctyp,cenc,labl,alis,subj,issr,slnr,skid,pkhh,data,agrp,pdmn) SELECT rowid,cdat,mdat,ctyp,cenc,labl,alis,subj,issr,slnr,skid,pkhh,data,agrp,pdmn from ocert;"
+    "INSERT INTO keys (rowid,cdat,mdat,kcls,labl,alis,perm,priv,modi,klbl,atag,crtr,type,bsiz,esiz,sdat,edat,sens,asen,extr,next,encr,decr,drve,sign,vrfy,snrc,vyrc,wrap,unwp,data,agrp,pdmn) SELECT rowid,cdat,mdat,kcls,labl,alis,perm,priv,modi,klbl,atag,crtr,type,bsiz,esiz,sdat,edat,sens,asen,extr,next,encr,decr,drve,sign,vrfy,snrc,vyrc,wrap,unwp,data,agrp,pdmn from okeys;"
     "DROP TABLE ogenp;"
     "DROP TABLE oinet;"
     "DROP TABLE ocert;"
     "DROP TABLE ogenp;"
     "DROP TABLE oinet;"
     "DROP TABLE ocert;"
-    "DROP TABLE okeys;",
+    "DROP TABLE okeys;"
+    "CREATE INDEX igsha ON genp(sha1);"
+    "CREATE INDEX iisha ON inet(sha1);"
+    "CREATE INDEX icsha ON cert(sha1);"
+    "CREATE INDEX iksha ON keys(sha1);",
 };
 
 struct sql_stages {
     int pre;
     int main;
     int post;
 };
 
 struct sql_stages {
     int pre;
     int main;
     int post;
-    bool init_pdmn;
+    bool init_pdmn; // If true do a full export followed by an import of the entire database so all items are re-encoded.
 };
 
 };
 
+/* On disk database format version upgrade scripts.
+   If pre is 0, version is unsupported and db is considered corrupt for having that version.
+   First entry creates the current db, each susequent entry upgrade to current from the version
+   represented by the index of the slot.  Each script is either -1 (disabled) of the number of
+   the script in the main table.
+    {pre,main,post, reencode} */
 static struct sql_stages s3dl_upgrade_script[] = {
 static struct sql_stages s3dl_upgrade_script[] = {
-    { -1, 0, 1, false },  /* Create version 5 database. */
-    { 2, 0, 4, true },    /* Upgrade to version 5 from version 1 (LittleBear). */
-    { 3, 0, 4, true },    /* Upgrade to version 5 from version 2 (BigBearBeta). */
-    { 3, 0, 5, true },    /* Upgrade to version 5 from version 3 (Apex). */
-    { 3, 0, 6, true },    /* Upgrade to version 5 from version 4 (Telluride). */
+    { -1, 0, 1, false },/* 0->current: Create version 6 database. */
+    {},                 /* 1->current: Upgrade to version 6 from version 1 -- Unsupported. */
+    {},                 /* 2->current: Upgrade to version 6 from version 2 -- Unsupported */
+    {},                 /* 3->current: Upgrade to version 6 from version 3 -- Unsupported */
+    {},                 /* 4->current: Upgrade to version 6 from version 4 -- Unsupported */
+    { 3, 0, 7, true },  /* 5->current: Upgrade to version 6 from version 5. */
 };
 
 };
 
-static int sql_run_script(s3dl_db_thread *dbt, int number)
+static bool sql_run_script(SecDbConnectionRef dbt, int number, CFErrorRef *error)
 {
 {
-    int s3e;
-
     /* Script -1 == skip this step. */
     if (number < 0)
     /* Script -1 == skip this step. */
     if (number < 0)
-        return SQLITE_OK;
+        return true;
 
     /* If we are attempting to run a script we don't have, fail. */
 
     /* If we are attempting to run a script we don't have, fail. */
-    if ((size_t)number >= sizeof(s3dl_upgrade_sql) / sizeof(*s3dl_upgrade_sql))
-        return SQLITE_CORRUPT;
-
-    char *errmsg = NULL;
-    s3e = sqlite3_exec(dbt->s3_handle, s3dl_upgrade_sql[number],
-        NULL, NULL, &errmsg);
-    if (errmsg) {
-        secwarning("script %d: %s", number, errmsg);
-        sqlite3_free(errmsg);
+    if ((size_t)number >= array_size(s3dl_upgrade_sql))
+        return SecDbError(SQLITE_CORRUPT, error, CFSTR("script %d exceeds maximum %d"),
+                                number, (int)(array_size(s3dl_upgrade_sql)));
+    __block bool ok = true;
+    if (number == 0) {
+        CFMutableStringRef sql = CFStringCreateMutable(0, 0);
+        SecDbAppendCreateTableWithClass(sql, &genp_class);
+        SecDbAppendCreateTableWithClass(sql, &inet_class);
+        SecDbAppendCreateTableWithClass(sql, &cert_class);
+        SecDbAppendCreateTableWithClass(sql, &keys_class);
+        CFStringAppend(sql, CFSTR("CREATE TABLE tversion(version INTEGER);INSERT INTO tversion(version) VALUES(6);"));
+        CFStringPerformWithCString(sql, ^(const char *sql_string) {
+            ok = SecDbErrorWithDb(sqlite3_exec(SecDbHandle(dbt), sql_string, NULL, NULL, NULL),
+                                     SecDbHandle(dbt), error, CFSTR("sqlite3_exec: %s"), sql_string);
+        });
+        CFReleaseSafe(sql);
+    } else {
+        ok = SecDbErrorWithDb(sqlite3_exec(SecDbHandle(dbt), s3dl_upgrade_sql[number], NULL, NULL, NULL),
+                                 SecDbHandle(dbt), error, CFSTR("sqlite3_exec: %s"), s3dl_upgrade_sql[number]);
     }
     }
-
-    return s3e;
+    return ok;
 }
 
 }
 
-
-static int s3dl_dbt_upgrade_from_version(s3dl_db_thread *dbt, int version)
+/* Return the current database version in *version.  Returns a
+ SQLITE error. */
+static bool s3dl_dbt_get_version(SecDbConnectionRef dbt, int *version, CFErrorRef *error)
 {
 {
-    /* We need to go from db version to CURRENT_DB_VERSION, let's do so. */
-    int s3e;
-
-    /* If we are attempting to upgrade to a version greater than what we have
-       an upgrade script for, fail. */
-    if (version < 0 ||
-        (size_t)version >= sizeof(s3dl_upgrade_script) / sizeof(*s3dl_upgrade_script))
-        return SQLITE_CORRUPT;
-
-    struct sql_stages *script = &s3dl_upgrade_script[version];
-    s3e = sql_run_script(dbt, script->pre);
-    if (s3e == SQLITE_OK)
-        s3e = sql_run_script(dbt, script->main);
-    if (s3e == SQLITE_OK)
-        s3e = sql_run_script(dbt, script->post);
-    if (script->init_pdmn) {
-        OSStatus status = s3e;
-        /* version 3 and earlier used legacy blob. */
-        CFDictionaryRef backup = SecServerExportKeychainPlist(dbt,
-            version < 4 ? KEYBAG_LEGACY : KEYBAG_DEVICE,
-            KEYBAG_NONE, kSecNoItemFilter, version, &status);
-        if (backup) {
-            if (status) {
-                secerror("Ignoring export error: %d during upgrade", status);
+    CFStringRef sql = CFSTR("SELECT version FROM tversion LIMIT 1");
+    return SecDbWithSQL(dbt, sql, error, ^(sqlite3_stmt *stmt) {
+        __block bool found_version = false;
+        bool step_ok = SecDbForEach(stmt, error, ^(int row_index __unused) {
+            if (!found_version) {
+                *version = sqlite3_column_int(stmt, 0);
+                found_version = true;
             }
             }
-            status = SecServerImportKeychainInPlist(dbt, KEYBAG_NONE,
-                KEYBAG_DEVICE, backup, kSecNoItemFilter);
-            CFRelease(backup);
-        } else if (status == errSecInteractionNotAllowed){
-            status = errSecUpgradePending;
+            return found_version;
+        });
+        if (!found_version) {
+            /* We have a tversion table but we didn't find a single version
+             value, now what? I suppose we pretend the db is corrupted
+             since this isn't supposed to ever happen. */
+            step_ok = SecDbError(SQLITE_CORRUPT, error, CFSTR("Failed to read version: database corrupt"));
+            secwarning("SELECT version step: %@", error ? *error : NULL);
         }
         }
-        s3e = status;
-    }
-
-    return s3e;
-}
-
-static int s3dl_dbt_create_or_upgrade(s3dl_db_thread *dbt)
-{
-    sqlite3_stmt *stmt = NULL;
-       int s3e;
-
-    /* Find out if we need to upgrade from version 0 (empty db) or version 1
-       -- the db schema before we had a tversion table. */
-    s3e = sqlite3_prepare(dbt->s3_handle, "SELECT cdat FROM genp", -1, &stmt, NULL);
-    if (stmt)
-        sqlite3_finalize(stmt);
-
-    return s3dl_dbt_upgrade_from_version(dbt, s3e ? 0 : 1);
-}
-
-/* Return the current database version in *version.  Returns a
-   SQLITE error. */
-static int s3dl_dbt_get_version(s3dl_db_thread *dbt, int *version)
-{
-       sqlite3 *s3h = dbt->s3_handle;
-       int s3e;
-
-    sqlite3_stmt *stmt = NULL;
-    static const char sql[] = "SELECT version FROM tversion LIMIT 1;";
-    s3e = sqlite3_prepare(s3h, sql, sizeof(sql) - 1, &stmt, NULL);
-    if (s3e)
-        goto errOut;
-
-    s3e = sqlite3_step(stmt);
-    if (s3e == SQLITE_ROW) {
-        *version = sqlite3_column_int(stmt, 0);
-        s3e = SQLITE_OK;
-    } else if (s3e) {
-        secwarning("SELECT version step: %s", sqlite3_errmsg(s3h));
-    } else {
-        /* We have a VERSION table but we didn't find a version
-           value now what?   I suppose we pretend the db is corrupted
-           since this isn't supposed to ever happen. */
-        s3e = SQLITE_CORRUPT;
-    } 
-
-errOut:
-    if (stmt) {
-        /* We ignore this error since this function may return SQLITE_ERROR,
-        SQLITE_IOERR_READ or SQLITE_ABORT if the stmt itself failed, but
-        that's something we would have handeled already. */
-               sqlite3_finalize(stmt);
-    }
-
-       return s3e;
+        return step_ok;
+    });
 }
 
 }
 
-/* This function is called if the db doesn't have the proper version.  We
-   start an exclusive transaction and recheck the version, and then perform
-   the upgrade within that transaction. */
-static int s3dl_dbt_upgrade(s3dl_db_thread *dbt)
+static bool s3dl_dbt_upgrade_from_version(SecDbConnectionRef dbt, int version, CFErrorRef *error)
 {
 {
-    int version;
-    int s3e;
-
-    require_noerr(s3e = s3dl_begin_transaction(dbt), errOut);
-    s3e = s3dl_dbt_get_version(dbt, &version);
-    if (!s3e) {
-        s3e = s3dl_dbt_upgrade_from_version(dbt, version);
-    } else {
-        /* We have no version table yet so we need to create a new db or
-           upgrade from version 1 (the db schema without a tversion table). */
-        require_noerr(s3e = s3dl_dbt_create_or_upgrade(dbt), errOut);
+    /* We need to go from db version to CURRENT_DB_VERSION, let's do so. */
+    __block bool ok = true;
+    /* O, guess we're done already. */
+    if (version == CURRENT_DB_VERSION)
+        return ok;
+
+    if (ok && version < 6) {
+        // Pre v6 keychains need to have WAL enabled, since SecDb only
+        // does this at db creation time.
+        // NOTE: This has to be run outside of a transaction.
+        ok = (SecDbExec(dbt, CFSTR("PRAGMA auto_vacuum = FULL"), error) &&
+              SecDbExec(dbt, CFSTR("PRAGMA journal_mode = WAL"), error));
     }
 
     }
 
-errOut:
-
-    return s3dl_end_transaction(dbt, s3e);
-}
-
-static int s3dl_create_dbt(s3dl_db *db, s3dl_db_thread **pdbt, int create)
-{
-       sqlite3 *s3h;
-       int retries, s3e;
-    for (retries = 0; retries < 2; ++retries) {
-        s3e = sqlite3_open(db->db_name, &s3h);
-        if (s3e == SQLITE_CANTOPEN && create)
-        {
-            /* Make sure the path to db->db_name exists and is writable, then
-               try again. */
-            s3dl_create_path(db->db_name);
-            s3e = sqlite3_open(db->db_name, &s3h);
+    // Start a transaction to do the upgrade within
+    if (ok) { ok = SecDbTransaction(dbt, kSecDbExclusiveTransactionType, error, ^(bool *commit) {
+        // Be conservative and get the version again once we start a transaction.
+        int cur_version = version;
+        s3dl_dbt_get_version(dbt, &cur_version, NULL);
+
+        /* If we are attempting to upgrade to a version greater than what we have
+         an upgrade script for, fail. */
+        if (ok && (cur_version < 0 ||
+            (size_t)cur_version >= array_size(s3dl_upgrade_script))) {
+            ok = SecDbError(SQLITE_CORRUPT, error, CFSTR("no upgrade script for version: %d"), cur_version);
+            secerror("no upgrade script for version %d", cur_version);
         }
 
         }
 
-        if (!s3e) {
-            s3dl_db_thread *dbt = (s3dl_db_thread *)malloc(sizeof(s3dl_db_thread));
-            dbt->dbt_next = NULL;
-            dbt->db = db;
-            dbt->s3_handle = s3h;
-            dbt->autocommit = true;
-            dbt->in_transaction = false;
-
-            int version;
-            s3e = s3dl_dbt_get_version(dbt, &version);
-            if (s3e == SQLITE_EMPTY || s3e == SQLITE_ERROR || (!s3e && version < CURRENT_DB_VERSION)) {
-                s3e = s3dl_dbt_upgrade(dbt);
-                if (s3e) {
-                    asl_log(NULL, NULL, ASL_LEVEL_CRIT,
-                        "failed to upgrade keychain %s: %d", db->db_name, s3e);
-                    if (s3e != errSecUpgradePending) {
-                        s3e = SQLITE_CORRUPT;
-                    }
+        struct sql_stages *script;
+        if (ok) {
+            script = &s3dl_upgrade_script[cur_version];
+            if (script->pre == 0)
+                ok = SecDbError(SQLITE_CORRUPT, error, CFSTR("unsupported db version %d"), cur_version);
+        }
+        if (ok)
+            ok = sql_run_script(dbt, script->pre, error);
+        if (ok)
+            ok = sql_run_script(dbt, script->main, error);
+        if (ok)
+            ok = sql_run_script(dbt, script->post, error);
+        if (ok && script->init_pdmn) {
+            CFErrorRef localError = NULL;
+            CFDictionaryRef backup = SecServerExportKeychainPlist(dbt,
+                                                                  KEYBAG_DEVICE, KEYBAG_NONE, kSecNoItemFilter, &localError);
+            if (backup) {
+                if (localError) {
+                    secerror("Ignoring export error: %@ during upgrade export", localError);
+                    CFReleaseNull(localError);
                 }
                 }
-            } else if (s3e) {
-                asl_log(NULL, NULL, ASL_LEVEL_ERR,
-                    "failed to obtain database version for %s: %d",
-                    db->db_name, s3e);
-            } else if (version > CURRENT_DB_VERSION) {
-                /* We can't downgrade so we treat a too new db as corrupted. */
-                asl_log(NULL, NULL, ASL_LEVEL_ERR,
-                    "found keychain %s with version: %d which is newer than %d marking as corrupted",
-                    db->db_name, version, CURRENT_DB_VERSION);
-                s3e = SQLITE_CORRUPT;
-            }
-
-            if (s3e) {
-                s3dl_close_dbt(dbt);
+                ok = SecServerImportKeychainInPlist(dbt, KEYBAG_NONE,
+                                                    KEYBAG_DEVICE, backup, kSecNoItemFilter, &localError);
+                CFRelease(backup);
             } else {
             } else {
-                *pdbt = dbt;
-                break;
+                ok = false;
+
+                if (localError && CFErrorGetCode(localError) == errSecInteractionNotAllowed) {
+                    SecError(errSecUpgradePending, error,
+                         CFSTR("unable to complete upgrade due to device lock state"));
+                    secerror("unable to complete upgrade due to device lock state");
+                } else {
+                    secerror("unable to complete upgrade for unknown reason, marking DB as corrupt: %@", localError);
+                    SecDbCorrupt(dbt);
+                }
             }
             }
-        }
 
 
-        if (s3e == SQLITE_CORRUPT || s3e == SQLITE_NOTADB ||
-            s3e == SQLITE_CANTOPEN || s3e == SQLITE_PERM ||
-            s3e == SQLITE_CONSTRAINT) {
-            size_t len = strlen(db->db_name);
-            char *old_db_name = malloc(len + 9);
-            memcpy(old_db_name, db->db_name, len);
-            strcpy(old_db_name + len, ".corrupt");
-            if (rename(db->db_name, old_db_name)) {
-                asl_log(NULL, NULL, ASL_LEVEL_CRIT,
-                    "unable to rename corrupt keychain %s -> %s: %s",
-                    db->db_name, old_db_name, strerror(errno));
-                free(old_db_name);
-                break;
-            } else {
-                asl_log(NULL, NULL, ASL_LEVEL_ERR,
-                    "renamed corrupt keychain %s -> %s (%d)",
-                    db->db_name, old_db_name, s3e);
+            if (localError) {
+                if (error && !*error)
+                    *error = localError;
+                else
+                    CFRelease(localError);
             }
             }
-            free(old_db_name);
-        } else if (s3e) {
-            asl_log(NULL, NULL, ASL_LEVEL_CRIT,
-                "failed to open keychain %s: %d", db->db_name, s3e);
-            break;
+        } else if (!ok) {
+            secerror("unable to complete upgrade scripts, marking DB as corrupt: %@", error ? *error : NULL);
+            SecDbCorrupt(dbt);
         }
         }
+        *commit = ok;
+    }); } else {
+        secerror("unable to complete upgrade scripts, marking DB as corrupt: %@", error ? *error : NULL);
+        SecDbCorrupt(dbt);
     }
 
     }
 
-       return s3e;
+    return ok;
 }
 
 }
 
-/* Called when a thread that was using this db goes away. */
-static void s3dl_dbt_destructor(void *data)
-{
-       s3dl_db_thread *dbt = (s3dl_db_thread *)data;
-       int found = 0;
-
-       /* Remove the passed in dbt from the linked list. */
-       /* TODO: Log pthread errors. */
-       pthread_mutex_lock(&dbt->db->mutex);
-       s3dl_db_thread **pdbt = &dbt->db->dbt_head;
-       for (;*pdbt; pdbt = &(*pdbt)->dbt_next)
-       {
-               if (*pdbt == dbt)
-               {
-                       *pdbt = dbt->dbt_next;
-                       found = 1;
-                       break;
-               }
-       }
-       /* TODO: Log pthread errors. */
-       pthread_mutex_unlock(&dbt->db->mutex);
-
-       /* Don't hold dbt->db->mutex while cleaning up the dbt. */
-       if (found)
-               s3dl_close_dbt(dbt);
-}
 
 
-/* Agressivly write to pdbHandle since we want to be able to call internal SPI
-   function during initialization. */
-static int s3dl_create_db_handle(const char *db_name, db_handle *pdbHandle,
-       s3dl_db_thread **pdbt, bool autocommit, bool create, bool use_hwaes)
+/* This function is called if the db doesn't have the proper version.  We
+   start an exclusive transaction and recheck the version, and then perform
+   the upgrade within that transaction. */
+static bool s3dl_dbt_upgrade(SecDbConnectionRef dbt, CFErrorRef *error)
 {
 {
-       void *mem = malloc(sizeof(s3dl_db) + strlen(db_name) + 1);
-       s3dl_db *db = (s3dl_db *)mem;
-       db->db_name = ((char *)mem) + sizeof(*db);
-       strcpy(db->db_name, db_name);
-    /* Make sure we set this before calling s3dl_create_dbt, since that might
-       trigger a db upgrade which needs to decrypt stuff. */
-    db->use_hwaes = use_hwaes;
-
-       s3dl_db_thread *dbt;
-       int s3e = s3dl_create_dbt(db, &dbt, create);
-       if (s3e != SQLITE_OK)
-       {
-        if (s3e == errSecUpgradePending) {
-            secerror("Device locked during initial open + upgrade attempt");
-            dbt = NULL;
-        } else {
-            free(mem);
-            return s3e;
-        }
-       } else {
-        dbt->autocommit = autocommit;
-    }
-       db->dbt_head = dbt;
-
-       int err = pthread_key_create(&db->key, s3dl_dbt_destructor);
-       if (!err)
-               err = pthread_mutex_init(&db->mutex, NULL);
-       if (!err && dbt)
-               err = pthread_setspecific(db->key, dbt);
-       if (err)
-       {
-               /* TODO: Log err (which is an errno) somehow. */
-        if (dbt)
-            s3e = s3dl_close_dbt(dbt);
-               if (s3e == SQLITE_OK)
-                       s3e = SQLITE_INTERNAL;
-
-               free(mem);
-       } else {
-               if (pdbt)
-                       *pdbt = dbt;
-
-               *pdbHandle = (db_handle)db;
-       }
-
-    return s3e;
+    // Already in a transaction
+    //return kc_transaction(dbt, error, ^{
+        int version = 0; // Upgrade from version 0 == create new db
+        s3dl_dbt_get_version(dbt, &version, NULL);
+        return s3dl_dbt_upgrade_from_version(dbt, version, error);
+    //});
 }
 
 }
 
-static int s3dl_close_db_handle(db_handle dbHandle)
-{
-       s3dl_db *db = (s3dl_db *)dbHandle;
-       int s3e = SQLITE_OK;
-
-       /* Walk the list of dbt's and close them all. */
-       s3dl_db_thread *next_dbt = db->dbt_head;
-       while (next_dbt)
-       {
-               s3dl_db_thread *dbt = next_dbt;
-               next_dbt = next_dbt->dbt_next;
-               int s3e2 = s3dl_close_dbt(dbt);
-               if (s3e2 != SQLITE_OK && s3e == SQLITE_OK)
-                       s3e = s3e2;
-       }
-
-       pthread_key_delete(db->key);
-       free(db);
-
-       return s3e;
-}
-
-static int s3dl_get_dbt(db_handle dbHandle, s3dl_db_thread **pdbt)
-{
-       if (!dbHandle)
-        return SQLITE_ERROR;
-
-       s3dl_db *db = (s3dl_db *)dbHandle;
-       int s3e = SQLITE_OK;
-       s3dl_db_thread *dbt = pthread_getspecific(db->key);
-       if (!dbt)
-       {
-               /* We had no dbt yet, so create a new one, but don't create the
-                  database. */
-               s3e = s3dl_create_dbt(db, &dbt, false);
-               if (s3e == SQLITE_OK)
-               {
-                       /* Lock the mutex, insert the new entry at the head of the
-                          linked list and release the lock. */
-                       int err = pthread_mutex_lock(&db->mutex);
-                       if (!err)
-                       {
-                               dbt->dbt_next = db->dbt_head;
-                               db->dbt_head = dbt;
-                               err = pthread_mutex_unlock(&db->mutex);
-                       }
-
-                       /* Set the dbt as this threads dbt for db. */
-                       if (!err)
-                               err = pthread_setspecific(db->key, dbt);
-                       if (err)
-                       {
-                               /* TODO: Log err (which is an errno) somehow. */
-                               s3e = s3dl_close_dbt(dbt);
-                               if (s3e == SQLITE_OK)
-                                       s3e = SQLITE_INTERNAL;
-                       }
-               }
-       }
-       *pdbt = dbt;
-       return s3e;
-}
-
-/* Return an OSStatus for a sqlite3 error code. */
-static OSStatus osstatus_for_s3e(int s3e)
-{
-       if (s3e > 0 && s3e <= SQLITE_DONE) switch (s3e)
-       {
-       case SQLITE_OK:
-               return 0;
-       case SQLITE_ERROR:
-               return errSecNotAvailable; /* errSecDuplicateItem; */
-       case SQLITE_FULL: /* Happens if we run out of uniqueids */
-               return errSecNotAvailable; /* TODO: Replace with a better error code. */
-       case SQLITE_PERM:
-       case SQLITE_READONLY:
-               return errSecNotAvailable;
-       case SQLITE_CANTOPEN:
-               return errSecNotAvailable;
-       case SQLITE_EMPTY:
-               return errSecNotAvailable;
-       case SQLITE_CONSTRAINT:
-        return errSecDuplicateItem;
-       case SQLITE_ABORT:
-               return -1;
-       case SQLITE_MISMATCH:
-               return errSecNoSuchAttr;
-       case SQLITE_AUTH:
-               return errSecNotAvailable;
-       case SQLITE_NOMEM:
-               return -2; /* TODO: Replace with a real error code. */
-       case SQLITE_INTERNAL:
-       default:
-               return errSecNotAvailable; /* TODO: Replace with a real error code. */
-       }
-    return s3e;
-}
-
-const uint32_t v0KeyWrapOverHead = 8;
+const uint32_t v0KeyWrapOverHead = 8;
 
 /* Wrap takes a 128 - 256 bit key as input and returns output of
    inputsize + 64 bits.
 
 /* Wrap takes a 128 - 256 bit key as input and returns output of
    inputsize + 64 bits.
@@ -1321,47 +782,33 @@ const uint32_t v0KeyWrapOverHead = 8;
    16 byte (128 bit) key returns a 24 byte wrapped key
    24 byte (192 bit) key returns a 32 byte wrapped key
    32 byte (256 bit) key returns a 40 byte wrapped key  */
    16 byte (128 bit) key returns a 24 byte wrapped key
    24 byte (192 bit) key returns a 32 byte wrapped key
    32 byte (256 bit) key returns a 40 byte wrapped key  */
-static int ks_crypt(uint32_t selector, keybag_handle_t keybag,
-    keyclass_t keyclass, uint32_t textLength, const uint8_t *source, uint8_t *dest, size_t *dest_len) {
+static bool ks_crypt(uint32_t selector, keybag_handle_t keybag,
+    keyclass_t keyclass, uint32_t textLength, const uint8_t *source, uint8_t *dest, size_t *dest_len, CFErrorRef *error) {
 #if USE_KEYSTORE
 #if USE_KEYSTORE
-       kern_return_t kernResult;
+       kern_return_t kernResult = kIOReturnBadArgument;
 
 
-    if (keystore == MACH_PORT_NULL) {
-               asl_log(NULL, NULL, ASL_LEVEL_ERR, "No AppleKeyStore connection");
-        return errSecNotAvailable;
+    if (selector == kAppleKeyStoreKeyWrap) {
+        kernResult = aks_wrap_key(source, textLength, keyclass, keybag, dest, (int*)dest_len);
+    } else if (selector == kAppleKeyStoreKeyUnwrap) {
+        kernResult = aks_unwrap_key(source, textLength, keyclass, keybag, dest, (int*)dest_len);
     }
 
     }
 
-    uint64_t inputs[] = { keybag, keyclass };
-    uint32_t num_inputs = sizeof(inputs)/sizeof(*inputs);
-    kernResult = IOConnectCallMethod(keystore, selector, inputs,
-        num_inputs, source, textLength, NULL, NULL, dest, dest_len);
-
        if (kernResult != KERN_SUCCESS) {
        if (kernResult != KERN_SUCCESS) {
-        if (kernResult == kIOReturnNotPermitted) {
+        if ((kernResult == kIOReturnNotPermitted) || (kernResult == kIOReturnNotPrivileged)) {
             /* Access to item attempted while keychain is locked. */
             /* Access to item attempted while keychain is locked. */
-            asl_log(NULL, NULL, ASL_LEVEL_INFO,
-                "%s sel: %d bag: %d cls: %d src: %p len: %"PRIu32" err: kIOReturnNotPermitted",
-                (selector == kAppleKeyStoreKeyWrap ? "kAppleKeyStoreKeyWrap"
-                 : "kAppleKeyStoreKeyUnwrap"),
-                selector, keybag, keyclass, source, textLength);
-            return errSecInteractionNotAllowed;
+            return SecError(errSecInteractionNotAllowed, error, CFSTR("ks_crypt: %x failed to %s item (class %"PRId32", bag: %"PRId32") Access to item attempted while keychain is locked."),
+                     kernResult, (selector == kAppleKeyStoreKeyWrap ? "wrap" : "unwrap"), keyclass, keybag);
         } else if (kernResult == kIOReturnError) {
             /* Item can't be decrypted on this device, ever, so drop the item. */
         } else if (kernResult == kIOReturnError) {
             /* Item can't be decrypted on this device, ever, so drop the item. */
-            secerror("%s sel: %d bag: %d cls: %d src: %p len: %lu err: kIOReturnError",
-                (selector == kAppleKeyStoreKeyWrap ? "kAppleKeyStoreKeyWrap"
-                 : "kAppleKeyStoreKeyUnwrap"),
-                selector, keybag, keyclass, source, textLength);
-            return errSecDecode;
+            return SecError(errSecDecode, error, CFSTR("ks_crypt: %x failed to %s item (class %"PRId32", bag: %"PRId32") Item can't be decrypted on this device, ever, so drop the item."),
+                     kernResult, (selector == kAppleKeyStoreKeyWrap ? "wrap" : "unwrap"), keyclass, keybag);
         } else {
         } else {
-            secerror("%s sel: %d bag: %d cls: %d src: %p len: %lu err: %x",
-                (selector == kAppleKeyStoreKeyWrap ? "kAppleKeyStoreKeyWrap"
-                 : "kAppleKeyStoreKeyUnwrap"),
-                selector, keybag, keyclass, source, textLength, kernResult);
-            return errSecNotAvailable;
+            return SecError(errSecNotAvailable, error, CFSTR("ks_crypt: %x failed to %s item (class %"PRId32", bag: %"PRId32")"),
+                     kernResult, (selector == kAppleKeyStoreKeyWrap ? "wrap" : "unwrap"), keyclass, keybag);
         }
        }
         }
        }
-       return errSecSuccess;
-#else
+       return true;
+#else /* !USE_KEYSTORE */
     if (selector == kAppleKeyStoreKeyWrap) {
         /* The no encryption case. */
         if (*dest_len >= textLength + 8) {
     if (selector == kAppleKeyStoreKeyWrap) {
         /* The no encryption case. */
         if (*dest_len >= textLength + 8) {
@@ -1369,117 +816,66 @@ static int ks_crypt(uint32_t selector, keybag_handle_t keybag,
             memset(dest + textLength, 8, 8);
             *dest_len = textLength + 8;
         } else
             memset(dest + textLength, 8, 8);
             *dest_len = textLength + 8;
         } else
-            return errSecNotAvailable;
+            return SecError(errSecNotAvailable, error, CFSTR("ks_crypt: failed to wrap item (class %"PRId32")"), keyclass);
     } else if (selector == kAppleKeyStoreKeyUnwrap) {
         if (*dest_len + 8 >= textLength) {
             memcpy(dest, source, textLength - 8);
             *dest_len = textLength - 8;
         } else
     } else if (selector == kAppleKeyStoreKeyUnwrap) {
         if (*dest_len + 8 >= textLength) {
             memcpy(dest, source, textLength - 8);
             *dest_len = textLength - 8;
         } else
-            return errSecNotAvailable;
+            return SecError(errSecNotAvailable, error, CFSTR("ks_crypt: failed to unwrap item (class %"PRId32")"), keyclass);
     }
     }
-    return errSecSuccess;
-#endif
+    return true;
+#endif /* USE_KEYSTORE */
 }
 
 }
 
-#if 0
-
-typedef struct kc_item {
-    CFMutableDictionaryRef item;
-    CFIndex n_attrs;
-    CFStringRef *attrs;
-    void *values[];
-} kc_item;
-
-#define kc_item_size(n) sizeof(kc_item) + 2 * sizeof(void *)
-#define kc_item_init(i, n) do { \
-    kc_item *_kc_item_a = (i); \
-    _kc_item_a->item = NULL; \
-    _kc_item_a->n_attrs = (n); \
-    _kc_item_a->attrs = (CFStringRef *)&_kc_item_a->values[_kc_item_a->n_attrs]; \
-} while(0)
-
-static kc_item *kc_item_create(CFIndex n_attrs) {
-    kc_item *item = malloc(kc_item_size(n_attrs));
-    kc_item_init(item, n_attrs);
-    return item;
-}
 
 
-static void kc_item_destroy(kc_item *item) {
-    CFReleaseSafe(item->item);
-    free(item);
+CFDataRef kc_plist_copy_der(CFPropertyListRef plist, CFErrorRef *error) {
+    size_t len = der_sizeof_plist(plist, error);
+    CFMutableDataRef encoded = CFDataCreateMutable(0, len);
+    CFDataSetLength(encoded, len);
+    uint8_t *der_end = CFDataGetMutableBytePtr(encoded);
+    const uint8_t *der = der_end;
+    der_end += len;
+    der_end = der_encode_plist(plist, error, der, der_end);
+    if (!der_end) {
+        CFReleaseNull(encoded);
+    } else {
+        assert(!der_end || der_end == der);
+    }
+    return encoded;
 }
 
 }
 
-static kc_item *kc_item_init_with_data() {
-
+static CFDataRef kc_copy_digest(const struct ccdigest_info *di, size_t len,
+                                const void *data, CFErrorRef *error) {
+    CFMutableDataRef digest = CFDataCreateMutable(0, di->output_size);
+    CFDataSetLength(digest, di->output_size);
+    ccdigest(di, len, data, CFDataGetMutableBytePtr(digest));
+    return digest;
 }
 
 }
 
-/* Encodes an item. */
-static CFDataRef kc_item_encode(const kc_item *item) {
-    CFDictionaryRef attrs = CFDictionaryCreate(0, (const void **)item->attrs,
-                                               (const void **)item->values,
-                                               item->n_attrs, 0, 0);
-    CFDataRef encoded = CFPropertyListCreateData(0, attrs,
-        kCFPropertyListBinaryFormat_v1_0, 0, 0);
-    CFRelease(attrs);
-    return encoded;
+CFDataRef kc_copy_sha1(size_t len, const void *data, CFErrorRef *error) {
+    return kc_copy_digest(ccsha1_di(), len, data, error);
 }
 
 }
 
-struct kc_item_set_attr {
-    CFIndex ix;
-    kc_item *item;
-    OSStatus error;
-};
-
-static void kc_item_set_attr(CFStringRef key, void *value,
-                             void *context) {
-    struct kc_item_set_attr *c = context;
-    if (CFGetTypeID(key) != CFStringGetTypeID()) {
-        c->error = 1;
-        return;
+CFDataRef kc_copy_plist_sha1(CFPropertyListRef plist, CFErrorRef *error) {
+    CFDataRef der = kc_plist_copy_der(plist, error);
+    CFDataRef digest = NULL;
+    if (der) {
+        digest = kc_copy_sha1(CFDataGetLength(der), CFDataGetBytePtr(der), error);
+        CFRelease(der);
     }
     }
-    c->item->attrs[c->ix] = key;
-    c->item->values[c->ix++] = value;
+    return digest;
 }
 
 }
 
-/* Returns a malloced item. */
-static CFDictionaryRef kc_item_decode(CFDataRef encoded_item) {
-    CFPropertyListFormat format;
-    CFPropertyListRef attrs;
-    attrs = CFPropertyListCreateWithData(0, encoded_item,
-                                         kCFPropertyListImmutable, &format, 0);
-    if (!attrs)
-        return NULL;
-
-    kc_item *item = NULL;
-    if (CFGetTypeID(attrs) != CFDictionaryGetTypeID())
-        goto errOut;
-
-    item = kc_item_create(CFDictionaryGetCount(attrs));
-    int failed = 0;
-    CFDictionaryApplyFunction(attrs,
-                              (CFDictionaryApplierFunction)kc_item_set_attr,
-                              &failed);
-
-errOut:
-#if 0
-    CFRelease(attrs);
-    return item;
-#else
-    kc_item_destroy(item);
-    return attrs;
-#endif
-}
-
-#endif
-
 /* Given plainText create and return a CFDataRef containing:
    BULK_KEY = RandomKey()
    version || keyclass || KeyStore_WRAP(keyclass, BULK_KEY) ||
     AES(BULK_KEY, NULL_IV, plainText || padding)
  */
 /* Given plainText create and return a CFDataRef containing:
    BULK_KEY = RandomKey()
    version || keyclass || KeyStore_WRAP(keyclass, BULK_KEY) ||
     AES(BULK_KEY, NULL_IV, plainText || padding)
  */
-static int ks_encrypt_data(keybag_handle_t keybag,
-    keyclass_t keyclass, CFDataRef plainText, CFDataRef *pBlob) {
+bool ks_encrypt_data(keybag_handle_t keybag,
+    keyclass_t keyclass, CFDataRef plainText, CFDataRef *pBlob, CFErrorRef *error) {
     CFMutableDataRef blob = NULL;
     CFMutableDataRef blob = NULL;
+    bool ok = true;
     //check(keybag >= 0);
 
     /* Precalculate output blob length. */
     //check(keybag >= 0);
 
     /* Precalculate output blob length. */
@@ -1490,26 +886,26 @@ static int ks_encrypt_data(keybag_handle_t keybag,
     size_t bulkKeyWrappedSize = sizeof(bulkKeyWrapped);
     uint32_t key_wrapped_size;
 
     size_t bulkKeyWrappedSize = sizeof(bulkKeyWrapped);
     uint32_t key_wrapped_size;
 
-       /* TODO: We should return a better error here. */
-       int s3e = errSecAllocate;
     if (!plainText || CFGetTypeID(plainText) != CFDataGetTypeID()
         || keyclass == 0) {
     if (!plainText || CFGetTypeID(plainText) != CFDataGetTypeID()
         || keyclass == 0) {
-        s3e = errSecParam;
+        ok = SecError(errSecParam, error, CFSTR("ks_encrypt_data: invalid plain text"));
         goto out;
     }
 
     size_t ptLen = CFDataGetLength(plainText);
     size_t ctLen = ptLen;
     size_t tagLen = 16;
         goto out;
     }
 
     size_t ptLen = CFDataGetLength(plainText);
     size_t ctLen = ptLen;
     size_t tagLen = 16;
-    uint32_t version = 2;
+    uint32_t version = 3;
 
 
-    if (SecRandomCopyBytes(kSecRandomDefault, bulkKeySize, bulkKey))
+    if (SecRandomCopyBytes(kSecRandomDefault, bulkKeySize, bulkKey)) {
+        ok = SecError(errSecAllocate, error, CFSTR("ks_encrypt_data: SecRandomCopyBytes failed"));
         goto out;
         goto out;
+    }
 
     /* Now that we're done using the bulkKey, in place encrypt it. */
 
     /* Now that we're done using the bulkKey, in place encrypt it. */
-    require_noerr_quiet(s3e = ks_crypt(kAppleKeyStoreKeyWrap, keybag, keyclass,
+    require_quiet(ok = ks_crypt(kAppleKeyStoreKeyWrap, keybag, keyclass,
                                        bulkKeySize, bulkKey, bulkKeyWrapped,
                                        bulkKeySize, bulkKey, bulkKeyWrapped,
-                                       &bulkKeyWrappedSize), out);
+                                       &bulkKeyWrappedSize, error), out);
     key_wrapped_size = (uint32_t)bulkKeyWrappedSize;
 
     size_t blobLen = sizeof(version) + sizeof(keyclass) +
     key_wrapped_size = (uint32_t)bulkKeyWrappedSize;
 
     size_t blobLen = sizeof(version) + sizeof(keyclass) +
@@ -1540,45 +936,47 @@ static int ks_encrypt_data(keybag_handle_t keybag,
                                          cursor,
                                          cursor + ctLen, &tagLen);
     if (ccerr) {
                                          cursor,
                                          cursor + ctLen, &tagLen);
     if (ccerr) {
-        asl_log(NULL, NULL, ASL_LEVEL_ERR, "CCCryptorGCM failed: %d", ccerr);
-        s3e = errSecInternal;
+        ok = SecError(errSecInternal, error, CFSTR("ks_encrypt_data: CCCryptorGCM failed: %d"), ccerr);
         goto out;
     }
     if (tagLen != 16) {
         goto out;
     }
     if (tagLen != 16) {
-        asl_log(NULL, NULL, ASL_LEVEL_ERR,
-                "CCCryptorGCM expected: 16 got: %ld byte tag", tagLen);
-        s3e = errSecInternal;
+        ok = SecError(errSecInternal, error, CFSTR("ks_encrypt_data: CCCryptorGCM expected: 16 got: %ld byte tag"), tagLen);
         goto out;
     }
 
 out:
     memset(bulkKey, 0, sizeof(bulkKey));
         goto out;
     }
 
 out:
     memset(bulkKey, 0, sizeof(bulkKey));
-       if (s3e) {
+       if (!ok) {
                CFReleaseSafe(blob);
        } else {
                *pBlob = blob;
        }
                CFReleaseSafe(blob);
        } else {
                *pBlob = blob;
        }
-       return s3e;
+    return ok;
 }
 
 /* Given cipherText containing:
    version || keyclass || KeyStore_WRAP(keyclass, BULK_KEY) ||
     AES(BULK_KEY, NULL_IV, plainText || padding)
    return the plainText. */
 }
 
 /* Given cipherText containing:
    version || keyclass || KeyStore_WRAP(keyclass, BULK_KEY) ||
     AES(BULK_KEY, NULL_IV, plainText || padding)
    return the plainText. */
-static int ks_decrypt_data(keybag_handle_t keybag,
+bool ks_decrypt_data(keybag_handle_t keybag,
     keyclass_t *pkeyclass, CFDataRef blob, CFDataRef *pPlainText,
     keyclass_t *pkeyclass, CFDataRef blob, CFDataRef *pPlainText,
-    uint32_t *version_p) {
+    uint32_t *version_p, CFErrorRef *error) {
     const uint32_t bulkKeySize = 32; /* Use 256 bit AES key for bulkKey. */
     uint8_t bulkKey[bulkKeySize];
     size_t bulkKeyCapacity = sizeof(bulkKey);
     const uint32_t bulkKeySize = 32; /* Use 256 bit AES key for bulkKey. */
     uint8_t bulkKey[bulkKeySize];
     size_t bulkKeyCapacity = sizeof(bulkKey);
+    bool ok = true;
 
     CFMutableDataRef plainText = NULL;
 
     CFMutableDataRef plainText = NULL;
+#if USE_KEYSTORE
+#if TARGET_OS_IPHONE
     check(keybag >= 0);
     check(keybag >= 0);
+#else
+    check((keybag >= 0) || (keybag == session_keybag_handle));
+#endif
+#endif
 
 
-       int s3e = errSecDecode;
     if (!blob) {
     if (!blob) {
-        /* TODO: We should return a better error here. */
-        s3e = errSecParam;
+        ok = SecError(errSecParam, error, CFSTR("ks_decrypt_data: invalid blob"));
         goto out;
     }
 
         goto out;
     }
 
@@ -1590,8 +988,10 @@ static int ks_decrypt_data(keybag_handle_t keybag,
 
     /* Check for underflow, ensuring we have at least one full AES block left. */
     if (blobLen < sizeof(version) + sizeof(keyclass) +
 
     /* Check for underflow, ensuring we have at least one full AES block left. */
     if (blobLen < sizeof(version) + sizeof(keyclass) +
-        bulkKeySize + v0KeyWrapOverHead + 16)
+        bulkKeySize + v0KeyWrapOverHead + 16) {
+        ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: Check for underflow"));
         goto out;
         goto out;
+    }
 
     version = *((uint32_t *)cursor);
     cursor += sizeof(version);
 
     version = *((uint32_t *)cursor);
     cursor += sizeof(version);
@@ -1609,6 +1009,9 @@ static int ks_decrypt_data(keybag_handle_t keybag,
             wrapped_key_size = bulkKeySize + v0KeyWrapOverHead;
             break;
         case 2:
             wrapped_key_size = bulkKeySize + v0KeyWrapOverHead;
             break;
         case 2:
+            /* DROPTHROUGH */
+            /* v2 and v3 have the same crypto, just different dictionary encodings. */
+        case 3:
             tagLen = 16;
             minimum_blob_len -= 16; // Remove PKCS7 padding block requirement
             ctLen -= tagLen;        // Remove tagLen from ctLen
             tagLen = 16;
             minimum_blob_len -= 16; // Remove PKCS7 padding block requirement
             ctLen -= tagLen;        // Remove tagLen from ctLen
@@ -1620,23 +1023,28 @@ static int ks_decrypt_data(keybag_handle_t keybag,
             ctLen -= sizeof(wrapped_key_size);
             break;
         default:
             ctLen -= sizeof(wrapped_key_size);
             break;
         default:
+            ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: invalid version %d"), version);
             goto out;
     }
 
     /* Validate key wrap length against total length */
     require(blobLen - minimum_blob_len - tagLen >= wrapped_key_size, out);
     ctLen -= wrapped_key_size;
             goto out;
     }
 
     /* Validate key wrap length against total length */
     require(blobLen - minimum_blob_len - tagLen >= wrapped_key_size, out);
     ctLen -= wrapped_key_size;
-    if (version < 2 && (ctLen & 0xF) != 0)
+    if (version < 2 && (ctLen & 0xF) != 0) {
+        ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: invalid version"));
         goto out;
         goto out;
+    }
 
     /* Now unwrap the bulk key using a key in the keybag. */
 
     /* Now unwrap the bulk key using a key in the keybag. */
-    require_noerr_quiet(s3e = ks_crypt(kAppleKeyStoreKeyUnwrap, keybag,
-        keyclass, wrapped_key_size, cursor, bulkKey, &bulkKeyCapacity), out);
+    require_quiet(ok = ks_crypt(kAppleKeyStoreKeyUnwrap, keybag,
+        keyclass, wrapped_key_size, cursor, bulkKey, &bulkKeyCapacity, error), out);
     cursor += wrapped_key_size;
 
     plainText = CFDataCreateMutable(NULL, ctLen);
     cursor += wrapped_key_size;
 
     plainText = CFDataCreateMutable(NULL, ctLen);
-    if (!plainText)
+    if (!plainText) {
+        ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: failed to allocate data for plain text"));
         goto out;
         goto out;
+    }
     CFDataSetLength(plainText, ctLen);
 
     /* Decrypt the cipherText with the bulkKey. */
     CFDataSetLength(plainText, ctLen);
 
     /* Decrypt the cipherText with the bulkKey. */
@@ -1651,21 +1059,19 @@ static int ks_decrypt_data(keybag_handle_t keybag,
                              CFDataGetMutableBytePtr(plainText),
                              tag, &tagLen);
         if (ccerr) {
                              CFDataGetMutableBytePtr(plainText),
                              tag, &tagLen);
         if (ccerr) {
-            secerror("CCCryptorGCM failed: %d", ccerr);
             /* TODO: Should this be errSecDecode once AppleKeyStore correctly
              identifies uuid unwrap failures? */
             /* TODO: Should this be errSecDecode once AppleKeyStore correctly
              identifies uuid unwrap failures? */
-            s3e = errSecDecode; /* errSecInteractionNotAllowed; */
+            /* errSecInteractionNotAllowed; */
+            ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: CCCryptorGCM failed: %d"), ccerr);
             goto out;
         }
         if (tagLen != 16) {
             goto out;
         }
         if (tagLen != 16) {
-            secerror("CCCryptorGCM expected: 16 got: %ld byte tag", tagLen);
-            s3e = errSecInternal;
+            ok = SecError(errSecInternal, error, CFSTR("ks_decrypt_data: CCCryptorGCM expected: 16 got: %ld byte tag"), tagLen);
             goto out;
         }
         cursor += ctLen;
         if (memcmp(tag, cursor, tagLen)) {
             goto out;
         }
         cursor += ctLen;
         if (memcmp(tag, cursor, tagLen)) {
-            secerror("CCCryptorGCM computed tag not same as tag in blob");
-            s3e = errSecDecode;
+            ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: CCCryptorGCM computed tag not same as tag in blob"));
             goto out;
         }
     } else {
             goto out;
         }
     } else {
@@ -1674,390 +1080,47 @@ static int ks_decrypt_data(keybag_handle_t keybag,
                         bulkKey, bulkKeySize, NULL, cursor, ctLen,
                         CFDataGetMutableBytePtr(plainText), ctLen, &ptLen);
         if (ccerr) {
                         bulkKey, bulkKeySize, NULL, cursor, ctLen,
                         CFDataGetMutableBytePtr(plainText), ctLen, &ptLen);
         if (ccerr) {
-            secerror("CCCrypt failed: %d", ccerr);
             /* TODO: Should this be errSecDecode once AppleKeyStore correctly
                identifies uuid unwrap failures? */
             /* TODO: Should this be errSecDecode once AppleKeyStore correctly
                identifies uuid unwrap failures? */
-            s3e = errSecDecode; /* errSecInteractionNotAllowed; */
+            /* errSecInteractionNotAllowed; */
+            ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: CCCrypt failed: %d"), ccerr);
             goto out;
         }
         CFDataSetLength(plainText, ptLen);
     }
             goto out;
         }
         CFDataSetLength(plainText, ptLen);
     }
-       s3e = errSecSuccess;
     if (version_p) *version_p = version;
 out:
     memset(bulkKey, 0, bulkKeySize);
     if (version_p) *version_p = version;
 out:
     memset(bulkKey, 0, bulkKeySize);
-       if (s3e) {
-               CFReleaseSafe(plainText);
-       } else {
-               *pPlainText = plainText;
-       }
-    return s3e;
-}
-
-/* Iff dir_encrypt is true dir_encrypt source -> dest, otherwise decrypt
-   source -> dest.  In both cases iv is used asa the Initialization Vector and
-   textLength bytes are encrypted or decrypted.   TextLength must be a multiple
-   of 16, since this function does not do any padding. */
-static bool kc_aes_crypt(s3dl_db_thread *dbt, bool dir_encrypt, const UInt8 *iv,
-       UInt32 textLength, const UInt8 *source, UInt8 *dest) {
-#if USE_HWAES
-       if (dbt->db->use_hwaes) {
-               IOAESOperation operation;
-               UInt8 *plainText;
-               UInt8 *cipherText;
-
-               if (dir_encrypt) {
-                       operation = IOAESOperationEncrypt;
-                       plainText = (UInt8 *)source;
-                       cipherText = dest;
-               } else {
-                       operation = IOAESOperationDecrypt;
-                       plainText = dest;
-                       cipherText = (UInt8 *)source;
-               }
-
-               return hwaes_crypt(operation,
-                       kIOAESAcceleratorKeyHandleKeychain, 128, NULL, iv, textLength,
-                       plainText, cipherText);
-       }
-       else
-#endif /* USE_HWAES */
-       {
-               /* The no encryption case. */
-               memcpy(dest, source, textLength);
-               return true;
-       }
-}
-
-#if 0
-/* Pre 4.0 blob encryption code, unused when keystore support is enabled. */
-
-/* Given plainText create and return a CFDataRef containing:
-   IV || AES(KC_KEY, IV, plainText || SHA1(plainText) || padding)
- */
-static int kc_encrypt_data(s3dl_db_thread *dbt, CFDataRef plainText,
-       CFDataRef *pCipherText) {
-    CFMutableDataRef cipherText = NULL;
-       /* TODO: We should return a better error here. */
-       int s3e = SQLITE_AUTH;
-    if (!plainText || CFGetTypeID(plainText) != CFDataGetTypeID()) {
-        s3e = SQLITE_MISMATCH;
-        goto out;
-    }
-
-    CFIndex ptLen = CFDataGetLength(plainText);
-       CFIndex ctLen = ptLen + CC_SHA1_DIGEST_LENGTH;
-       CFIndex padLen = 16 - (ctLen & 15);
-       /* Pad output buffer capacity to nearest multiple of 32 bytes for cache
-          coherency. */
-    CFIndex paddedTotalLength = (16 + ctLen + padLen + 0x1F) & ~0x1F;
-       cipherText = CFDataCreateMutable(NULL, paddedTotalLength);
-    if (!cipherText)
-        goto out;
-    CFDataSetLength(cipherText, 16 + ctLen + padLen);
-       UInt8 *iv = CFDataGetMutableBytePtr(cipherText);
-    if (SecRandomCopyBytes(kSecRandomDefault, 16, iv))
-        goto out;
-
-       UInt8 *ct = iv + 16;
-    const UInt8 *pt = CFDataGetBytePtr(plainText);
-       memcpy(ct, pt, ptLen);
-       CC_SHA1(pt, ptLen, ct + ptLen);
-       memset(ct + ctLen, padLen, padLen);
-
-       /* Encrypt the data in place. */
-    if (!kc_aes_crypt(dbt, true, iv, ctLen + padLen, ct, ct)) {
-        goto out;
-    }
-
-       s3e = SQLITE_OK;
-out:
-       if (s3e) {
-               CFReleaseSafe(cipherText);
-       } else {
-               *pCipherText = cipherText;
-       }
-       return s3e;
-}
-#endif
-
-/* Given cipherText containing:
-   IV || AES(KC_KEY, IV, plainText || SHA1(plainText) || padding)
-   return the plainText. */
-static int kc_decrypt_data(s3dl_db_thread *dbt, CFDataRef cipherText,
-       CFDataRef *pPlainText) {
-    CFMutableDataRef plainText = NULL;
-       /* TODO: We should return a better error here. */
-       int s3e = SQLITE_AUTH;
-    if (!cipherText)
-        goto out;
-
-    CFIndex ctLen = CFDataGetLength(cipherText);
-    if (ctLen < 48 || (ctLen & 0xF) != 0)
-        goto out;
-
-    const UInt8 *iv = CFDataGetBytePtr(cipherText);
-    const UInt8 *ct = iv + 16;
-    CFIndex ptLen = ctLen - 16;
-
-    /* Cast: debug check for overflow before casting to uint32_t later */
-    assert((unsigned long)ptLen<UINT32_MAX); /* correct as long as CFIndex is signed long */
-
-       /* Pad output buffer capacity to nearest multiple of 32 bytes for cache
-          coherency. */
-    CFIndex paddedLength = (ptLen + 0x1F) & ~0x1F;
-    plainText = CFDataCreateMutable(NULL, paddedLength);
-    if (!plainText)
-        goto out;
-    CFDataSetLength(plainText, ptLen);
-    UInt8 *pt = CFDataGetMutableBytePtr(plainText);
-
-    /* 64 bits case: Worst case here is we dont decrypt the full data. No security issue */
-    if (!kc_aes_crypt(dbt, false, iv, (uint32_t)ptLen, ct, pt)) {
-        goto out;
-    }
-
-       /* Now check and remove the padding. */
-       UInt8 pad = pt[ptLen - 1];
-       if (pad < 1 || pad > 16) {
-               asl_log(NULL, NULL, ASL_LEVEL_ERR,
-            "kc_decrypt_data: bad padding bytecount: 0x%02X", pad);
-               goto out;
-       }
-       CFIndex ix;
-       ptLen -= pad;
-       for (ix = 0; ix < pad - 1; ++ix) {
-               if (pt[ptLen + ix] != pad) {
-            asl_log(NULL, NULL, ASL_LEVEL_ERR,
-                "kc_decrypt_data: bad padding byte: %lu: 0x%02X",
-                               ix, pt[ptLen + ix]);
-                       goto out;
-               }
-       }
-
-       UInt8 sha1[CC_SHA1_DIGEST_LENGTH];
-       ptLen -= CC_SHA1_DIGEST_LENGTH;
-    /* 64 bits cast: worst case here is we dont hash the full data and the decrypt fail or
-       suceed when it should not have. No security issue. */
-       CC_SHA1(pt, (CC_LONG)ptLen, sha1);
-       if (memcmp(sha1, pt + ptLen, CC_SHA1_DIGEST_LENGTH)) {
-               asl_log(NULL, NULL, ASL_LEVEL_ERR, "kc_decrypt_data: digest mismatch");
-               goto out;
-       }
-
-       CFDataSetLength(plainText, ptLen);
-
-       s3e = SQLITE_OK;
-out:
-       if (s3e) {
+       if (!ok) {
                CFReleaseSafe(plainText);
        } else {
                *pPlainText = plainText;
        }
                CFReleaseSafe(plainText);
        } else {
                *pPlainText = plainText;
        }
-    return s3e;
+    return ok;
 }
 
 }
 
-/* AUDIT[securityd](done):
-   value (ok) is a caller provided, non NULL CFTypeRef.
- */
-static int kc_bind_paramter(sqlite3_stmt *stmt, int param, CFTypeRef value)
-{
-    CFTypeID valueId;
-    int s3e;
-
-       /* TODO: Can we use SQLITE_STATIC below everwhere we currently use
-          SQLITE_TRANSIENT since we finalize the statement before the value
-          goes out of scope? */
-    if (!value || (valueId = CFGetTypeID(value)) == CFNullGetTypeID()) {
-        /* Skip bindings for NULL values.  sqlite3 will interpret unbound
-           params as NULL which is exactly what we want. */
-#if 1
-               s3e = SQLITE_OK;
-#else
-               s3e = sqlite3_bind_null(stmt, param);
-#endif
-               secdebug("bind", "bind_null: %d", s3e);
-    } else if (valueId == CFStringGetTypeID()) {
-        const char *cstr = CFStringGetCStringPtr(value, kCFStringEncodingUTF8);
-        if (cstr) {
-            s3e = sqlite3_bind_text_wrapper(stmt, param, cstr, strlen(cstr),
-                SQLITE_TRANSIENT);
-                       secdebug("bind", "quick bind_text: %s: %d", cstr, s3e);
+static bool use_hwaes() {
+    static bool use_hwaes;
+    static dispatch_once_t check_once;
+    dispatch_once(&check_once, ^{
+        use_hwaes = hwaes_key_available();
+        if (use_hwaes) {
+            asl_log(NULL, NULL, ASL_LEVEL_INFO, "using hwaes key");
         } else {
         } else {
-            CFIndex len = 0;
-            CFRange range = { 0, CFStringGetLength(value) };
-            CFStringGetBytes(value, range, kCFStringEncodingUTF8,
-                0, FALSE, NULL, 0, &len);
-            {
-                CFIndex usedlen = 0;
-                char buf[len];
-                CFStringGetBytes(value, range, kCFStringEncodingUTF8,
-                    0, FALSE, (UInt8 *)buf, len, &usedlen);
-                s3e = sqlite3_bind_text_wrapper(stmt, param, buf, usedlen,
-                    SQLITE_TRANSIENT);
-                               secdebug("bind", "slow bind_text: %.*s: %d", usedlen, buf, s3e);
-            }
-        }
-    } else if (valueId == CFDataGetTypeID()) {
-        CFIndex len = CFDataGetLength(value);
-        if (len) {
-            s3e = sqlite3_bind_blob_wrapper(stmt, param, CFDataGetBytePtr(value),
-                len, SQLITE_TRANSIENT);
-            secdebug("bind", "bind_blob: %.*s: %d",
-                CFDataGetLength(value), CFDataGetBytePtr(value), s3e);
-        } else {
-            s3e = sqlite3_bind_text(stmt, param, "", 0, SQLITE_TRANSIENT);
-        }
-    } else if (valueId == CFDateGetTypeID()) {
-        CFAbsoluteTime abs_time = CFDateGetAbsoluteTime(value);
-        s3e = sqlite3_bind_double(stmt, param, abs_time);
-               secdebug("bind", "bind_double: %f: %d", abs_time, s3e);
-    } else if (valueId == CFBooleanGetTypeID()) {
-        int bval = CFBooleanGetValue(value);
-        s3e = sqlite3_bind_int(stmt, param, bval);
-        secdebug("bind", "bind_int: %d: %d", bval, s3e);
-    } else if (valueId == CFNumberGetTypeID()) {
-        Boolean convertOk;
-        if (CFNumberIsFloatType(value)) {
-            double nval;
-            convertOk = CFNumberGetValue(value, kCFNumberDoubleType, &nval);
-            s3e = sqlite3_bind_double(stmt, param, nval);
-                       secdebug("bind", "bind_double: %f: %d", nval, s3e);
-        } else {
-            CFIndex len = CFNumberGetByteSize(value);
-            /* TODO: should sizeof int be 4?  sqlite seems to think so. */
-            if (len <= (CFIndex)sizeof(int)) {
-                int nval;
-                convertOk = CFNumberGetValue(value, kCFNumberIntType, &nval);
-                s3e = sqlite3_bind_int(stmt, param, nval);
-                               secdebug("bind", "bind_int: %d: %d", nval, s3e);
-            } else {
-                sqlite_int64 nval;
-                convertOk = CFNumberGetValue(value, kCFNumberLongLongType,
-                    &nval);
-                s3e = sqlite3_bind_int64(stmt, param, nval);
-                               secdebug("bind", "bind_int64: %lld: %d", nval, s3e);
-            }
-        }
-        if (!convertOk) {
-            /* TODO: CFNumberGetValue failed somehow. */
-            s3e = SQLITE_INTERNAL;
-        }
-    } else {
-        /* Unsupported CF type used. */
-        s3e = SQLITE_MISMATCH;
-    }
-
-       return s3e;
-}
-
-/* Compile the statement in sql and return it as stmt. */
-static int kc_prepare_statement(sqlite3 *s3h, CFStringRef sql,
-    sqlite3_stmt **stmt)
-{
-    int s3e;
-    const char *cstr = CFStringGetCStringPtr(sql, kCFStringEncodingUTF8);
-    if (cstr) {
-        secdebug("sql", "quick prepare: %s", cstr);
-        s3e = sqlite3_prepare_wrapper(s3h, cstr, strlen(cstr), stmt, NULL);
-    } else {
-        CFIndex len = 0;
-        CFRange range = { 0, CFStringGetLength(sql) };
-        CFStringGetBytes(sql, range, kCFStringEncodingUTF8,
-            0, FALSE, NULL, 0, &len);
-        {
-            CFIndex usedlen = 0;
-            char buf[len];
-            CFStringGetBytes(sql, range, kCFStringEncodingUTF8,
-                0, FALSE, (UInt8 *)buf, len, &usedlen);
-            secdebug("sql", "slow prepare: %.*s", usedlen, buf);
-            s3e = sqlite3_prepare_wrapper(s3h, buf, usedlen, stmt, NULL);
+            asl_log(NULL, NULL, ASL_LEVEL_ERR, "unable to access hwaes key");
         }
         }
-    }
-
-    /* sqlite3_prepare returns SQLITE_ERROR if the table doesn't exist or one
-       of the attributes the caller passed in doesn't exist.  */
-    if (s3e == SQLITE_ERROR) {
-        secdebug("sql", "sqlite3_prepare: %s", sqlite3_errmsg(s3h));
-        s3e = errSecParam;
-    }
-
-    return s3e;
+    });
+    return use_hwaes;
 }
 
 }
 
-/* Return types. */
-typedef uint32_t ReturnTypeMask;
-enum
-{
-    kSecReturnDataMask = 1 << 0,
-    kSecReturnAttributesMask = 1 << 1,
-    kSecReturnRefMask = 1 << 2,
-    kSecReturnPersistentRefMask = 1 << 3,
-};
-
-/* Constant indicating there is no limit to the number of results to return. */
-enum
-{
-    kSecMatchUnlimited = kCFNotFound
-};
-
 /* Upper limit for number of keys in a QUERY dictionary. */
 /* Upper limit for number of keys in a QUERY dictionary. */
+#define QUERY_KEY_LIMIT_BASE    (128)
 #ifdef NO_SERVER
 #ifdef NO_SERVER
-#define QUERY_KEY_LIMIT  (31 + 53)
+#define QUERY_KEY_LIMIT  (31 + QUERY_KEY_LIMIT_BASE)
 #else
 #else
-#define QUERY_KEY_LIMIT  (53)
+#define QUERY_KEY_LIMIT  QUERY_KEY_LIMIT_BASE
 #endif
 
 #endif
 
-typedef struct Pair
-{
-    const void *key;
-    const void *value;
-} Pair;
-
-/* Nothing in this struct is retained since all the
-   values below are extracted from the dictionary passed in by the
-   caller. */
-typedef struct Query
-{
-    /* Class of this query. */
-    const kc_class *q_class;
-
-    /* Dictionary with all attributes and values in clear (to be encrypted). */
-    CFMutableDictionaryRef q_item;
-
-    /* q_pairs is an array of Pair structs.  Elements with indices
-     [0, q_attr_end) contain attribute key value pairs.  Elements with
-     indices [q_match_begin, q_match_end) contain match key value pairs.
-     Thus q_attr_end is the number of attrs in q_pairs and
-     q_match_begin - q_match_end is the number of matches in q_pairs.  */
-    CFIndex q_match_begin;
-    CFIndex q_match_end;
-    CFIndex q_attr_end;
-
-    OSStatus q_error;
-    ReturnTypeMask q_return_type;
-
-    CFDataRef q_data;
-    CFTypeRef q_ref;
-    sqlite_int64 q_row_id;
-
-    CFArrayRef q_use_item_list;
-#if defined(MULTIPLE_KEYCHAINS)
-    CFArrayRef q_use_keychain;
-    CFArrayRef q_use_keychain_list;
-#endif /* !defined(MULTIPLE_KEYCHAINS) */
-
-    /* Value of kSecMatchLimit key if present. */
-    CFIndex q_limit;
-
-    /* Keybag handle to use for this item. */
-    keybag_handle_t q_keybag;
-    keyclass_t q_keyclass;
-    //CFStringRef q_keyclass_s;
-
-    Pair q_pairs[];
-} Query;
-
 /* Inline accessors to attr and match values in a query. */
 static inline CFIndex query_attr_count(const Query *q)
 {
 /* Inline accessors to attr and match values in a query. */
 static inline CFIndex query_attr_count(const Query *q)
 {
@@ -2084,7 +1147,7 @@ static inline Pair query_match_at(const Query *q, CFIndex ix)
 /* Sets q_keyclass based on value. */
 static void query_parse_keyclass(const void *value, Query *q) {
     if (!isString(value)) {
 /* Sets q_keyclass based on value. */
 static void query_parse_keyclass(const void *value, Query *q) {
     if (!isString(value)) {
-        q->q_error = errSecParam;
+        SecError(errSecParam, &q->q_error, CFSTR("accessible attribute %@ not a string"), value);
         return;
     } else if (CFEqual(value, kSecAttrAccessibleWhenUnlocked)) {
         q->q_keyclass = key_class_ak;
         return;
     } else if (CFEqual(value, kSecAttrAccessibleWhenUnlocked)) {
         q->q_keyclass = key_class_ak;
@@ -2099,121 +1162,89 @@ static void query_parse_keyclass(const void *value, Query *q) {
     } else if (CFEqual(value, kSecAttrAccessibleAlwaysThisDeviceOnly)) {
         q->q_keyclass = key_class_dku;
     } else {
     } else if (CFEqual(value, kSecAttrAccessibleAlwaysThisDeviceOnly)) {
         q->q_keyclass = key_class_dku;
     } else {
-        q->q_error = errSecParam;
+        SecError(errSecParam, &q->q_error, CFSTR("accessible attribute %@ unknown"), value);
         return;
     }
     //q->q_keyclass_s = value;
 }
 
         return;
     }
     //q->q_keyclass_s = value;
 }
 
-static CFStringRef copyString(CFTypeRef obj) {
-    CFTypeID tid = CFGetTypeID(obj);
-    if (tid == CFStringGetTypeID())
-        return CFStringCreateCopy(0, obj);
-    else if (tid == CFDataGetTypeID())
-        return CFStringCreateFromExternalRepresentation(0, obj, kCFStringEncodingUTF8);
-    else
-        return NULL;
-}
-
-static CFDataRef copyData(CFTypeRef obj) {
-    CFTypeID tid = CFGetTypeID(obj);
-    if (tid == CFDataGetTypeID()) {
-        return CFDataCreateCopy(0, obj);
-    } else if (tid == CFStringGetTypeID()) {
-        return CFStringCreateExternalRepresentation(0, obj, kCFStringEncodingUTF8, 0);
-    } else if (tid == CFNumberGetTypeID()) {
-        SInt32 value;
-        CFNumberGetValue(obj, kCFNumberSInt32Type, &value);
-        return CFDataCreate(0, (const UInt8 *)&value, sizeof(value));
-    } else {
-        return NULL;
-    }
-}
-
-static CFTypeRef copyBlob(CFTypeRef obj) {
-    CFTypeID tid = CFGetTypeID(obj);
-    if (tid == CFDataGetTypeID()) {
-        return CFDataCreateCopy(0, obj);
-    } else if (tid == CFStringGetTypeID()) {
-        return CFStringCreateCopy(0, obj);
-    } else if (tid == CFNumberGetTypeID()) {
-        CFRetain(obj);
-        return obj;
-    } else {
-        return NULL;
+static const SecDbClass *kc_class_with_name(CFStringRef name) {
+    if (isString(name)) {
+#if 0
+        // TODO Iterate kc_db_classes and look for name == class->name.
+        // Or get clever and switch on first letter of class name and compare to verify
+        static const void *kc_db_classes[] = {
+            &genp_class,
+            &inet_class,
+            &cert_class,
+            &keys_class,
+            &identity_class
+        };
+#endif
+        if (CFEqual(name, kSecClassGenericPassword))
+            return &genp_class;
+        else if (CFEqual(name, kSecClassInternetPassword))
+            return &inet_class;
+        else if (CFEqual(name, kSecClassCertificate))
+            return &cert_class;
+        else if (CFEqual(name, kSecClassKey))
+            return &keys_class;
+        else if (CFEqual(name, kSecClassIdentity))
+            return &identity_class;
     }
     }
-}
-
-static CFTypeRef copyNumber(CFTypeRef obj) {
-    CFTypeID tid = CFGetTypeID(obj);
-    if (tid == CFNumberGetTypeID()) {
-        CFRetain(obj);
-        return obj;
-    } else if (tid == CFBooleanGetTypeID()) {
-        SInt32 value = CFBooleanGetValue(obj);
-        return CFNumberCreate(0, kCFNumberSInt32Type, &value);
-    } else if (tid == CFStringGetTypeID()) {
-        SInt32 value = CFStringGetIntValue(obj);
-        CFStringRef t = CFStringCreateWithFormat(0, 0, CFSTR("%ld"), value);
-        /* If a string converted to an int isn't equal to the int printed as
-           a string, return a CFStringRef instead. */
-        if (!CFEqual(t, obj)) {
-            CFRelease(t);
-            return CFStringCreateCopy(0, obj);
-        }
-        CFRelease(t);
-        return CFNumberCreate(0, kCFNumberSInt32Type, &value);
-    } else
-        return NULL;
-}
-
-static CFDateRef copyDate(CFTypeRef obj) {
-    CFTypeID tid = CFGetTypeID(obj);
-    if (tid == CFDateGetTypeID()) {
-        CFRetain(obj);
-        return obj;
-    } else
-        return NULL;
+    return NULL;
 }
 
 /* AUDIT[securityd](done):
    key (ok) is a caller provided, string or number of length 4.
    value (ok) is a caller provided, non NULL CFTypeRef.
  */
 }
 
 /* AUDIT[securityd](done):
    key (ok) is a caller provided, string or number of length 4.
    value (ok) is a caller provided, non NULL CFTypeRef.
  */
-static void query_add_attribute(const void *key, const void *value, Query *q)
+static void query_add_attribute_with_desc(const SecDbAttr *desc, const void *value, Query *q)
 {
 {
-    const kc_attr_desc *desc;
-    if (!(desc = kc_attr_desc_with_key(q->q_class, key, &q->q_error)))
-        return;
+    if (CFEqual(desc->name, kSecAttrSynchronizable)) {
+        q->q_sync = true;
+        if (CFEqual(value, kSecAttrSynchronizableAny))
+            return; /* skip the attribute so it isn't part of the search */
+    }
 
     CFTypeRef attr = NULL;
     switch (desc->kind) {
 
     CFTypeRef attr = NULL;
     switch (desc->kind) {
-        case kc_data_attr:
+        case kSecDbDataAttr:
             attr = copyData(value);
             break;
             attr = copyData(value);
             break;
-        case kc_blob_attr:
+        case kSecDbBlobAttr:
             attr = copyBlob(value);
             break;
             attr = copyBlob(value);
             break;
-        case kc_date_attr:
-        case kc_creation_date_attr:
-        case kc_modification_date_attr:
+        case kSecDbDateAttr:
+        case kSecDbCreationDateAttr:
+        case kSecDbModificationDateAttr:
             attr = copyDate(value);
             break;
             attr = copyDate(value);
             break;
-        case kc_number_attr:
+        case kSecDbNumberAttr:
+        case kSecDbSyncAttr:
+        case kSecDbTombAttr:
             attr = copyNumber(value);
             break;
             attr = copyNumber(value);
             break;
-        case kc_string_attr:
+        case kSecDbAccessAttr:
+        case kSecDbStringAttr:
             attr = copyString(value);
             break;
             attr = copyString(value);
             break;
+        case kSecDbSHA1Attr:
+            attr = copySHA1(value);
+            break;
+        case kSecDbRowIdAttr:
+        case kSecDbPrimaryKeyAttr:
+        case kSecDbEncryptedDataAttr:
+            break;
     }
 
     if (!attr) {
     }
 
     if (!attr) {
-        q->q_error = errSecItemInvalidValue;
+        SecError(errSecItemInvalidValue, &q->q_error, CFSTR("attribute %@: value: %@ failed to convert"), desc->name, value);
         return;
     }
 
         return;
     }
 
-    /* Store plaintext attr data in q_item. */
-    if (q->q_item) {
+    /* Store plaintext attr data in q_item unless it's a kSecDbSHA1Attr. */
+    if (q->q_item && desc->kind != kSecDbSHA1Attr) {
         CFDictionarySetValue(q->q_item, desc->name, attr);
     }
 
         CFDictionarySetValue(q->q_item, desc->name, attr);
     }
 
@@ -2222,11 +1253,11 @@ static void query_add_attribute(const void *key, const void *value, Query *q)
     }
 
     /* Convert attr to (sha1) digest if requested. */
     }
 
     /* Convert attr to (sha1) digest if requested. */
-    if (desc->flags & kc_digest_attr) {
+    if (desc->flags & kSecDbSHA1ValueInFlag) {
         CFDataRef data = copyData(attr);
         CFRelease(attr);
         if (!data) {
         CFDataRef data = copyData(attr);
         CFRelease(attr);
         if (!data) {
-            q->q_error = errSecInternal;
+            SecError(errSecInternal, &q->q_error, CFSTR("failed to get attribute %@ data"), desc->name);
             return;
         }
 
             return;
         }
 
@@ -2234,7 +1265,7 @@ static void query_add_attribute(const void *key, const void *value, Query *q)
         CFDataSetLength(digest, CC_SHA1_DIGEST_LENGTH);
         /* 64 bits cast: worst case is we generate the wrong hash */
         assert((unsigned long)CFDataGetLength(data)<UINT32_MAX); /* Debug check. Correct as long as CFIndex is long */
         CFDataSetLength(digest, CC_SHA1_DIGEST_LENGTH);
         /* 64 bits cast: worst case is we generate the wrong hash */
         assert((unsigned long)CFDataGetLength(data)<UINT32_MAX); /* Debug check. Correct as long as CFIndex is long */
-        CC_SHA1(CFDataGetBytePtr(data), (CC_LONG)CFDataGetLength(data),
+        CCDigest(kCCDigestSHA1, CFDataGetBytePtr(data), (CC_LONG)CFDataGetLength(data),
                 CFDataGetMutableBytePtr(digest));
         CFRelease(data);
         attr = digest;
                 CFDataGetMutableBytePtr(digest));
         CFRelease(data);
         attr = digest;
@@ -2245,23 +1276,30 @@ static void query_add_attribute(const void *key, const void *value, Query *q)
     q->q_pairs[q->q_attr_end++].value = attr;
 }
 
     q->q_pairs[q->q_attr_end++].value = attr;
 }
 
+static void query_add_attribute(const void *key, const void *value, Query *q)
+{
+    const SecDbAttr *desc = SecDbAttrWithKey(q->q_class, key, &q->q_error);
+    if (desc)
+        query_add_attribute_with_desc(desc, value, q);
+}
+
 /* First remove key from q->q_pairs if it's present, then add the attribute again. */
 /* First remove key from q->q_pairs if it's present, then add the attribute again. */
-static void query_set_attribute(const void *key, const void *value, Query *q) {
-    if (CFDictionaryContainsKey(q->q_item, key)) {
+static void query_set_attribute_with_desc(const SecDbAttr *desc, const void *value, Query *q) {
+    if (CFDictionaryContainsKey(q->q_item, desc->name)) {
         CFIndex ix;
         for (ix = 0; ix < q->q_attr_end; ++ix) {
         CFIndex ix;
         for (ix = 0; ix < q->q_attr_end; ++ix) {
-            if (CFEqual(key, q->q_pairs[ix].key)) {
+            if (CFEqual(desc->name, q->q_pairs[ix].key)) {
                 CFReleaseSafe(q->q_pairs[ix].value);
                 --q->q_attr_end;
                 for (; ix < q->q_attr_end; ++ix) {
                     q->q_pairs[ix] = q->q_pairs[ix + 1];
                 }
                 CFReleaseSafe(q->q_pairs[ix].value);
                 --q->q_attr_end;
                 for (; ix < q->q_attr_end; ++ix) {
                     q->q_pairs[ix] = q->q_pairs[ix + 1];
                 }
-                CFDictionaryRemoveValue(q->q_item, key);
+                CFDictionaryRemoveValue(q->q_item, desc->name);
                 break;
             }
         }
     }
                 break;
             }
         }
     }
-    query_add_attribute(key, value, q);
+    query_add_attribute_with_desc(desc, value, q);
 }
 
 /* AUDIT[securityd](done):
 }
 
 /* AUDIT[securityd](done):
@@ -2279,33 +1317,56 @@ static void query_add_match(const void *key, const void *value, Query *q)
         /* Figure out what the value for kSecMatchLimit is if specified. */
         if (CFGetTypeID(value) == CFNumberGetTypeID()) {
             if (!CFNumberGetValue(value, kCFNumberCFIndexType, &q->q_limit))
         /* Figure out what the value for kSecMatchLimit is if specified. */
         if (CFGetTypeID(value) == CFNumberGetTypeID()) {
             if (!CFNumberGetValue(value, kCFNumberCFIndexType, &q->q_limit))
-                q->q_error = errSecItemInvalidValue;
+                SecError(errSecItemInvalidValue, &q->q_error, CFSTR("failed to convert match limit %@ to CFIndex"), value);
         } else if (CFEqual(kSecMatchLimitAll, value)) {
             q->q_limit = kSecMatchUnlimited;
         } else if (CFEqual(kSecMatchLimitOne, value)) {
             q->q_limit = 1;
         } else {
         } else if (CFEqual(kSecMatchLimitAll, value)) {
             q->q_limit = kSecMatchUnlimited;
         } else if (CFEqual(kSecMatchLimitOne, value)) {
             q->q_limit = 1;
         } else {
-            q->q_error = errSecItemInvalidValue;
+            SecError(errSecItemInvalidValue, &q->q_error, CFSTR("unsupported match limit %@"), value);
+        }
+    } else if (CFEqual(kSecMatchIssuers, key) &&
+               (CFGetTypeID(value) == CFArrayGetTypeID()))
+    {
+        CFMutableArrayRef canonical_issuers = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+        if (canonical_issuers) {
+            CFIndex i, count = CFArrayGetCount(value);
+            for (i = 0; i < count; i++) {
+                CFTypeRef issuer_data = CFArrayGetValueAtIndex(value, i);
+                CFDataRef issuer_canonical = NULL;
+                if (CFDataGetTypeID() == CFGetTypeID(issuer_data))
+                    issuer_canonical = SecDistinguishedNameCopyNormalizedContent((CFDataRef)issuer_data);
+                if (issuer_canonical) {
+                    CFArrayAppendValue(canonical_issuers, issuer_canonical);
+                    CFRelease(issuer_canonical);
+                }
+            }
+
+            if (CFArrayGetCount(canonical_issuers) > 0) {
+                q->q_match_issuer = canonical_issuers;
+            } else
+                CFRelease(canonical_issuers);
         }
     }
 }
 
         }
     }
 }
 
-static bool query_set_class(Query *q, CFStringRef c_name, OSStatus *error) {
-    const void *value;
+static bool query_set_class(Query *q, CFStringRef c_name, CFErrorRef *error) {
+    const SecDbClass *value;
     if (c_name && CFGetTypeID(c_name) == CFStringGetTypeID() &&
     if (c_name && CFGetTypeID(c_name) == CFStringGetTypeID() &&
-        (value = CFDictionaryGetValue(gClasses, c_name)) &&
+        (value = kc_class_with_name(c_name)) &&
         (q->q_class == 0 || q->q_class == value)) {
         q->q_class = value;
         return true;
     }
 
     if (error && !*error)
         (q->q_class == 0 || q->q_class == value)) {
         q->q_class = value;
         return true;
     }
 
     if (error && !*error)
-        *error = c_name ? errSecNoSuchClass : errSecItemClassMissing;
+        SecError((c_name ? errSecNoSuchClass : errSecItemClassMissing), error, CFSTR("can find class named: %@"), c_name);
+
 
     return false;
 }
 
 
     return false;
 }
 
-static const kc_class *query_get_class(CFDictionaryRef query, OSStatus *error) {
+static const SecDbClass *query_get_class(CFDictionaryRef query, CFErrorRef *error) {
     CFStringRef c_name = NULL;
     const void *value = CFDictionaryGetValue(query, kSecClass);
     if (isString(value)) {
     CFStringRef c_name = NULL;
     const void *value = CFDictionaryGetValue(query, kSecClass);
     if (isString(value)) {
@@ -2318,12 +1379,14 @@ static const kc_class *query_get_class(CFDictionaryRef query, OSStatus *error) {
         }
     }
 
         }
     }
 
-    if (c_name && (value = CFDictionaryGetValue(gClasses, c_name))) {
+    if (c_name && (value = kc_class_with_name(c_name))) {
         return value;
     } else {
         return value;
     } else {
-        if (error && !*error)
-            *error = c_name ? errSecNoSuchClass : errSecItemClassMissing;
-        return false;
+        if (c_name)
+            SecError(errSecNoSuchClass, error, CFSTR("can't find class named: %@"), c_name);
+        else
+            SecError(errSecItemClassMissing, error, CFSTR("query missing class name"));
+        return NULL;
     }
 }
 
     }
 }
 
@@ -2336,7 +1399,7 @@ static void query_add_class(const void *key, const void *value, Query *q)
     if (CFEqual(key, kSecClass)) {
         query_set_class(q, value, &q->q_error);
     } else {
     if (CFEqual(key, kSecClass)) {
         query_set_class(q, value, &q->q_error);
     } else {
-        q->q_error = errSecItemInvalidKey;
+        SecError(errSecItemInvalidKey, &q->q_error, CFSTR("add_class: key %@ is not %@"), key, kSecClass);
     }
 }
 
     }
 }
 
@@ -2348,7 +1411,7 @@ static void query_add_return(const void *key, const void *value, Query *q)
 {
     ReturnTypeMask mask;
     if (CFGetTypeID(value) != CFBooleanGetTypeID()) {
 {
     ReturnTypeMask mask;
     if (CFGetTypeID(value) != CFBooleanGetTypeID()) {
-        q->q_error = errSecItemInvalidValue;
+        SecError(errSecItemInvalidValue, &q->q_error, CFSTR("add_return: value %@ is not CFBoolean"), value);
         return;
     }
 
         return;
     }
 
@@ -2363,7 +1426,7 @@ static void query_add_return(const void *key, const void *value, Query *q)
     else if (CFEqual(key, kSecReturnPersistentRef))
         mask = kSecReturnPersistentRefMask;
     else {
     else if (CFEqual(key, kSecReturnPersistentRef))
         mask = kSecReturnPersistentRefMask;
     else {
-        q->q_error = errSecItemInvalidKey;
+        SecError(errSecItemInvalidKey, &q->q_error, CFSTR("add_return: unknown key %@"), key);
         return;
     }
 
         return;
     }
 
@@ -2386,22 +1449,32 @@ static void query_add_use(const void *key, const void *value, Query *q)
     if (CFEqual(key, kSecUseItemList)) {
         /* TODO: Add sanity checking when we start using this. */
         q->q_use_item_list = value;
     if (CFEqual(key, kSecUseItemList)) {
         /* TODO: Add sanity checking when we start using this. */
         q->q_use_item_list = value;
-    }
+    } else if (CFEqual(key, kSecUseTombstones)) {
+        if (CFGetTypeID(value) == CFBooleanGetTypeID()) {
+            q->q_use_tomb = value;
+        } else if (CFGetTypeID(value) == CFNumberGetTypeID()) {
+            q->q_use_tomb = CFBooleanGetValue(value) ? kCFBooleanTrue : kCFBooleanFalse;
+        } else if (CFGetTypeID(value) == CFStringGetTypeID()) {
+            q->q_use_tomb = CFStringGetIntValue(value) ? kCFBooleanTrue : kCFBooleanFalse;
+        } else {
+            SecError(errSecItemInvalidValue, &q->q_error, CFSTR("add_use: value %@ for key %@ is neither CFBoolean nor CFNumber"), value, key);
+            return;
+        }
 #if defined(MULTIPLE_KEYCHAINS)
 #if defined(MULTIPLE_KEYCHAINS)
-    else if (CFEqual(key, kSecUseKeychain))
+    } else if (CFEqual(key, kSecUseKeychain)) {
         q->q_use_keychain = value;
         q->q_use_keychain = value;
-    else if (CFEqual(key, kSecUseKeychainList))
+    } else if (CFEqual(key, kSecUseKeychainList)) {
         q->q_use_keychain_list = value;
 #endif /* !defined(MULTIPLE_KEYCHAINS) */
         q->q_use_keychain_list = value;
 #endif /* !defined(MULTIPLE_KEYCHAINS) */
-    else {
-        q->q_error = errSecItemInvalidKey;
+    else {
+        SecError(errSecItemInvalidKey, &q->q_error, CFSTR("add_use: unknown key %@"), key);
         return;
     }
 }
 
 static void query_set_data(const void *value, Query *q) {
     if (!isData(value)) {
         return;
     }
 }
 
 static void query_set_data(const void *value, Query *q) {
     if (!isData(value)) {
-        q->q_error = errSecItemInvalidValue;
+        SecError(errSecItemInvalidValue, &q->q_error, CFSTR("set_data: value %@ is not type data"), value);
     } else {
         q->q_data = value;
         if (q->q_item)
     } else {
         q->q_data = value;
         if (q->q_item)
@@ -2417,7 +1490,7 @@ static void query_add_value(const void *key, const void *value, Query *q)
 {
     if (CFEqual(key, kSecValueData)) {
         query_set_data(value, q);
 {
     if (CFEqual(key, kSecValueData)) {
         query_set_data(value, q);
-#if NO_SERVER
+#ifdef NO_SERVER
     } else if (CFEqual(key, kSecValueRef)) {
         q->q_ref = value;
         /* TODO: Add value type sanity checking. */
     } else if (CFEqual(key, kSecValueRef)) {
         q->q_ref = value;
         /* TODO: Add value type sanity checking. */
@@ -2427,9 +1500,9 @@ static void query_add_value(const void *key, const void *value, Query *q)
         if (_SecItemParsePersistentRef(value, &c_name, &q->q_row_id))
             query_set_class(q, c_name, &q->q_error);
         else
         if (_SecItemParsePersistentRef(value, &c_name, &q->q_row_id))
             query_set_class(q, c_name, &q->q_error);
         else
-            q->q_error = errSecItemInvalidValue;
+            SecError(errSecItemInvalidValue, &q->q_error, CFSTR("add_value: value %@ is not a valid persitent ref"), value);
     } else {
     } else {
-        q->q_error = errSecItemInvalidKey;
+        SecError(errSecItemInvalidKey, &q->q_error, CFSTR("add_value: unknown key %@"), key);
         return;
     }
 }
         return;
     }
 }
@@ -2448,24 +1521,18 @@ static void query_update_applier(const void *key, const void *value,
 
     /* Make sure we have a string key. */
     if (!isString(key)) {
 
     /* Make sure we have a string key. */
     if (!isString(key)) {
-        q->q_error = errSecItemInvalidKeyType;
+        SecError(errSecItemInvalidKeyType, &q->q_error, CFSTR("update_applier: unknown key type %@"), key);
         return;
     }
 
     if (!value) {
         return;
     }
 
     if (!value) {
-        q->q_error = errSecItemInvalidValue;
+        SecError(errSecItemInvalidValue, &q->q_error, CFSTR("update_applier: key %@ has NULL value"), key);
         return;
     }
 
     if (CFEqual(key, kSecValueData)) {
         query_set_data(value, q);
     } else {
         return;
     }
 
     if (CFEqual(key, kSecValueData)) {
         query_set_data(value, q);
     } else {
-        /* Make sure we have a value. */
-        if (!value) {
-            q->q_error = errSecItemInvalidValue;
-            return;
-        }
-
         query_add_attribute(key, value, q);
     }
 }
         query_add_attribute(key, value, q);
     }
 }
@@ -2483,13 +1550,13 @@ static void query_applier(const void *key, const void *value, void *context)
 
     /* Make sure we have a key. */
     if (!key) {
 
     /* Make sure we have a key. */
     if (!key) {
-        q->q_error = errSecItemInvalidKeyType;
+        SecError(errSecItemInvalidKeyType, &q->q_error, CFSTR("applier: NULL key"));
         return;
     }
 
     /* Make sure we have a value. */
     if (!value) {
         return;
     }
 
     /* Make sure we have a value. */
     if (!value) {
-        q->q_error = errSecItemInvalidValue;
+        SecError(errSecItemInvalidValue, &q->q_error, CFSTR("applier: key %@ has NULL value"), key);
         return;
     }
 
         return;
     }
 
@@ -2529,11 +1596,11 @@ static void query_applier(const void *key, const void *value, void *context)
                 query_add_value(key, value, q);
                 break;
             default:
                 query_add_value(key, value, q);
                 break;
             default:
-                q->q_error = errSecItemInvalidKey;
+                SecError(errSecItemInvalidKey, &q->q_error, CFSTR("applier: key %@ invalid"), key);
                 break;
             }
         } else {
                 break;
             }
         } else {
-            q->q_error = errSecItemInvalidKey;
+            SecError(errSecItemInvalidKey, &q->q_error, CFSTR("applier: key %@ invalid length"), key);
         }
     } else if (key_id == CFNumberGetTypeID()) {
         /* Numeric keys are always (extended) attributes. */
         }
     } else if (key_id == CFNumberGetTypeID()) {
         /* Numeric keys are always (extended) attributes. */
@@ -2541,7 +1608,7 @@ static void query_applier(const void *key, const void *value, void *context)
         query_add_attribute(key, value, q);
     } else {
         /* We only support string and number type keys. */
         query_add_attribute(key, value, q);
     } else {
         /* We only support string and number type keys. */
-        q->q_error = errSecItemInvalidKeyType;
+        SecError(errSecItemInvalidKeyType, &q->q_error, CFSTR("applier: key %@ neither string nor number"), key);
     }
 }
 
     }
 }
 
@@ -2567,57 +1634,98 @@ static void query_ensure_keyclass(Query *q, CFStringRef agrp) {
     }
 }
 
     }
 }
 
-static void query_destroy(Query *q, OSStatus *status)
-{
-    if (status && *status == 0 && q->q_error)
-        *status = q->q_error;
+static bool query_error(Query *q, CFErrorRef *error) {
+    if (q->q_error) {
+        CFErrorRef tmp = q->q_error;
+        q->q_error = NULL;
+        if (error && !*error) {
+            *error = tmp;
+        } else {
+            CFRelease(tmp);
+        }
+        return false;
+    }
+    return true;
+}
 
 
+bool query_destroy(Query *q, CFErrorRef *error) {
+    bool ok = query_error(q, error);
     CFIndex ix, attr_count = query_attr_count(q);
     for (ix = 0; ix < attr_count; ++ix) {
         CFReleaseSafe(query_attr_at(q, ix).value);
     }
     CFReleaseSafe(q->q_item);
     CFIndex ix, attr_count = query_attr_count(q);
     for (ix = 0; ix < attr_count; ++ix) {
         CFReleaseSafe(query_attr_at(q, ix).value);
     }
     CFReleaseSafe(q->q_item);
+    CFReleaseSafe(q->q_primary_key_digest);
+    CFReleaseSafe(q->q_match_issuer);
+
     free(q);
     free(q);
+    return ok;
+}
+
+static void SecKeychainChanged(bool syncWithPeers) {
+    uint32_t result = notify_post(g_keychain_changed_notification);
+    if (syncWithPeers)
+        SOSCCSyncWithAllPeers();
+    if (result == NOTIFY_STATUS_OK)
+        secnotice("item", "Sent %s%s", syncWithPeers ? "SyncWithAllPeers and " : "", g_keychain_changed_notification);
+    else
+        secerror("%snotify_post %s returned: %" PRIu32, syncWithPeers ? "Sent SyncWithAllPeers, " : "", g_keychain_changed_notification, result);
+}
+
+static bool query_notify_and_destroy(Query *q, bool ok, CFErrorRef *error) {
+    if (ok && !q->q_error && q->q_sync_changed) {
+        SecKeychainChanged(true);
+    }
+    return query_destroy(q, error) && ok;
 }
 
 /* Allocate and initialize a Query object for query. */
 }
 
 /* Allocate and initialize a Query object for query. */
-static Query *query_create(const kc_class *qclass, CFDictionaryRef query,
-                           OSStatus *error)
+Query *query_create(const SecDbClass *qclass, CFDictionaryRef query,
+                    CFErrorRef *error)
 {
     if (!qclass) {
         if (error && !*error)
 {
     if (!qclass) {
         if (error && !*error)
-            *error = errSecItemClassMissing;
+            SecError(errSecItemClassMissing, error, CFSTR("Missing class"));
         return NULL;
     }
 
     /* Number of pairs we need is the number of attributes in this class
        plus the number of keys in the dictionary, minus one for each key in
        the dictionary that is a regular attribute. */
         return NULL;
     }
 
     /* Number of pairs we need is the number of attributes in this class
        plus the number of keys in the dictionary, minus one for each key in
        the dictionary that is a regular attribute. */
-    CFIndex key_count = qclass->n_attrs;
+    CFIndex key_count = SecDbClassAttrCount(qclass);
+    if (key_count == 0) {
+        // Identities claim to have 0 attributes, but they really support any keys or cert attribute.
+        key_count = SecDbClassAttrCount(&cert_class) + SecDbClassAttrCount(&keys_class);
+    }
+
     if (query) {
         key_count += CFDictionaryGetCount(query);
     if (query) {
         key_count += CFDictionaryGetCount(query);
-        CFIndex ix;
-        for (ix = 0; ix < qclass->n_attrs; ++ix) {
-            if (CFDictionaryContainsKey(query, qclass->attrs[ix].name))
+        SecDbForEachAttr(qclass, attr) {
+            if (CFDictionaryContainsKey(query, attr->name))
                 --key_count;
         }
     }
 
     if (key_count > QUERY_KEY_LIMIT) {
         if (error && !*error)
                 --key_count;
         }
     }
 
     if (key_count > QUERY_KEY_LIMIT) {
         if (error && !*error)
-            *error = errSecItemIllegalQuery;
+        {
+            secerror("key_count: %ld, QUERY_KEY_LIMIT: %d", (long)key_count, QUERY_KEY_LIMIT);
+            SecError(errSecItemIllegalQuery, error, CFSTR("Past query key limit"));
+        }
         return NULL;
     }
 
     Query *q = calloc(1, sizeof(Query) + sizeof(Pair) * key_count);
     if (q == NULL) {
         if (error && !*error)
         return NULL;
     }
 
     Query *q = calloc(1, sizeof(Query) + sizeof(Pair) * key_count);
     if (q == NULL) {
         if (error && !*error)
-            *error = errSecAllocate;
+            SecError(errSecAllocate, error, CFSTR("Out of memory"));
         return NULL;
     }
 
         return NULL;
     }
 
+    q->q_keybag = KEYBAG_DEVICE;
     q->q_class = qclass;
     q->q_match_begin = q->q_match_end = key_count;
     q->q_class = qclass;
     q->q_match_begin = q->q_match_end = key_count;
+    q->q_item = CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
 
     return q;
 }
 
     return q;
 }
@@ -2625,34 +1733,25 @@ static Query *query_create(const kc_class *qclass, CFDictionaryRef query,
 /* Parse query for a Query object q. */
 static bool query_parse_with_applier(Query *q, CFDictionaryRef query,
                                      CFDictionaryApplierFunction applier,
 /* Parse query for a Query object q. */
 static bool query_parse_with_applier(Query *q, CFDictionaryRef query,
                                      CFDictionaryApplierFunction applier,
-                                     OSStatus *error) {
-    if (q->q_item == NULL) {
-        q->q_item = CFDictionaryCreateMutable(0, 0,
-                                              &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-    }
+                                     CFErrorRef *error) {
     CFDictionaryApplyFunction(query, applier, q);
     CFDictionaryApplyFunction(query, applier, q);
-    if (q->q_error) {
-        if (error && !*error)
-            *error = q->q_error;
-        return false;
-    }
-    return true;
+    return query_error(q, error);
 }
 
 /* Parse query for a Query object q. */
 static bool query_parse(Query *q, CFDictionaryRef query,
 }
 
 /* Parse query for a Query object q. */
 static bool query_parse(Query *q, CFDictionaryRef query,
-                               OSStatus *error) {
+                        CFErrorRef *error) {
     return query_parse_with_applier(q, query, query_applier, error);
 }
 
 /* Parse query for a Query object q. */
 static bool query_update_parse(Query *q, CFDictionaryRef update,
     return query_parse_with_applier(q, query, query_applier, error);
 }
 
 /* Parse query for a Query object q. */
 static bool query_update_parse(Query *q, CFDictionaryRef update,
-                        OSStatus *error) {
+                               CFErrorRef *error) {
     return query_parse_with_applier(q, update, query_update_applier, error);
 }
 
 static Query *query_create_with_limit(CFDictionaryRef query, CFIndex limit,
     return query_parse_with_applier(q, update, query_update_applier, error);
 }
 
 static Query *query_create_with_limit(CFDictionaryRef query, CFIndex limit,
-                                      OSStatus *error) {
+                                      CFErrorRef *error) {
     Query *q;
     q = query_create(query_get_class(query, error), query, error);
     if (q) {
     Query *q;
     q = query_create(query_get_class(query, error), query, error);
     if (q) {
@@ -2661,37 +1760,43 @@ static Query *query_create_with_limit(CFDictionaryRef query, CFIndex limit,
             query_destroy(q, error);
             return NULL;
         }
             query_destroy(q, error);
             return NULL;
         }
+        if (!q->q_sync && !q->q_row_id) {
+            /* query did not specify a kSecAttrSynchronizable attribute,
+             * and did not contain a persistent reference. */
+            query_add_attribute(kSecAttrSynchronizable, kCFBooleanFalse, q);
+        }
     }
     return q;
 }
 
     }
     return q;
 }
 
+
+//TODO: Move this to SecDbItemRef
+
 /* Make sure all attributes that are marked as not_null have a value.  If
    force_date is false, only set mdat and cdat if they aren't already set. */
 static void
 query_pre_add(Query *q, bool force_date) {
     CFDateRef now = CFDateCreate(0, CFAbsoluteTimeGetCurrent());
 /* Make sure all attributes that are marked as not_null have a value.  If
    force_date is false, only set mdat and cdat if they aren't already set. */
 static void
 query_pre_add(Query *q, bool force_date) {
     CFDateRef now = CFDateCreate(0, CFAbsoluteTimeGetCurrent());
-    CFIndex ix;
-    for (ix = 0; ix < q->q_class->n_attrs; ++ix) {
-        const kc_attr_desc *desc = &q->q_class->attrs[ix];
-        if (desc->kind == kc_creation_date_attr ||
-            desc->kind == kc_modification_date_attr) {
+    SecDbForEachAttrWithMask(q->q_class, desc, kSecDbInFlag) {
+        if (desc->kind == kSecDbCreationDateAttr ||
+            desc->kind == kSecDbModificationDateAttr) {
             if (force_date) {
             if (force_date) {
-                query_set_attribute(desc->name, now, q);
+                query_set_attribute_with_desc(desc, now, q);
             } else if (!CFDictionaryContainsKey(q->q_item, desc->name)) {
             } else if (!CFDictionaryContainsKey(q->q_item, desc->name)) {
-                query_add_attribute(desc->name, now, q);
+                query_add_attribute_with_desc(desc, now, q);
             }
             }
-        } else if ((desc->flags & kc_constrain_not_null) &&
+        } else if ((desc->flags & kSecDbNotNullFlag) &&
                    !CFDictionaryContainsKey(q->q_item, desc->name)) {
             CFTypeRef value = NULL;
                    !CFDictionaryContainsKey(q->q_item, desc->name)) {
             CFTypeRef value = NULL;
-            if (desc->flags & kc_constrain_default_0) {
-                if (desc->kind == kc_date_attr)
+            if (desc->flags & kSecDbDefault0Flag) {
+                if (desc->kind == kSecDbDateAttr)
                     value = CFDateCreate(kCFAllocatorDefault, 0.0);
                 else {
                     SInt32 vzero = 0;
                     value = CFNumberCreate(0, kCFNumberSInt32Type, &vzero);
                 }
                     value = CFDateCreate(kCFAllocatorDefault, 0.0);
                 else {
                     SInt32 vzero = 0;
                     value = CFNumberCreate(0, kCFNumberSInt32Type, &vzero);
                 }
-            } else if (desc->flags & kc_constrain_default_empty) {
-                if (desc->kind == kc_data_attr)
+            } else if (desc->flags & kSecDbDefaultEmptyFlag) {
+                if (desc->kind == kSecDbDataAttr)
                     value = CFDataCreate(kCFAllocatorDefault, NULL, 0);
                 else {
                     value = CFSTR("");
                     value = CFDataCreate(kCFAllocatorDefault, NULL, 0);
                 else {
                     value = CFSTR("");
@@ -2701,7 +1806,7 @@ query_pre_add(Query *q, bool force_date) {
             if (value) {
                 /* Safe to use query_add_attribute here since the attr wasn't
                  set yet. */
             if (value) {
                 /* Safe to use query_add_attribute here since the attr wasn't
                  set yet. */
-                query_add_attribute(desc->name, value, q);
+                query_add_attribute_with_desc(desc, value, q);
                 CFRelease(value);
             }
         }
                 CFRelease(value);
             }
         }
@@ -2709,15 +1814,15 @@ query_pre_add(Query *q, bool force_date) {
     CFReleaseSafe(now);
 }
 
     CFReleaseSafe(now);
 }
 
+//TODO: Move this to SecDbItemRef
+
 /* Update modification_date if needed. */
 static void
 query_pre_update(Query *q) {
 /* Update modification_date if needed. */
 static void
 query_pre_update(Query *q) {
-    CFIndex ix;
-    for (ix = 0; ix < q->q_class->n_attrs; ++ix) {
-        const kc_attr_desc *desc = &q->q_class->attrs[ix];
-        if (desc->kind == kc_modification_date_attr) {
+    SecDbForEachAttr(q->q_class, desc) {
+        if (desc->kind == kSecDbModificationDateAttr) {
             CFDateRef now = CFDateCreate(0, CFAbsoluteTimeGetCurrent());
             CFDateRef now = CFDateCreate(0, CFAbsoluteTimeGetCurrent());
-            query_set_attribute(desc->name, now, q);
+            query_set_attribute_with_desc(desc, now, q);
             CFReleaseSafe(now);
         }
     }
             CFReleaseSafe(now);
         }
     }
@@ -2758,7 +1863,7 @@ static void s3dl_merge_into_dict(const void *key, const void *value, void *conte
 
 /* Return whatever the caller requested based on the value of q->q_return_type.
    keys and values must be 3 larger than attr_count in size to accomadate the
 
 /* Return whatever the caller requested based on the value of q->q_return_type.
    keys and values must be 3 larger than attr_count in size to accomadate the
-   optional data, class and persistant ref results.  This is so we can use
+   optional data, class and persistent ref results.  This is so we can use
    the CFDictionaryCreate() api here rather than appending to a
    mutable dictionary. */
 static CFTypeRef handle_result(Query *q, CFMutableDictionaryRef item,
    the CFDictionaryCreate() api here rather than appending to a
    mutable dictionary. */
 static CFTypeRef handle_result(Query *q, CFMutableDictionaryRef item,
@@ -2808,88 +1913,74 @@ static CFTypeRef handle_result(Query *q, CFMutableDictionaryRef item,
        return a_result;
 }
 
        return a_result;
 }
 
-static CFStringRef s3dl_insert_sql(Query *q) {
-    /* We always have at least one attribute, the agrp. */
-    CFMutableStringRef sql = CFStringCreateMutable(NULL, 0);
-    CFStringAppendFormat(sql, NULL, CFSTR("INSERT INTO %@(data"), q->q_class->name);
-
-    CFIndex ix, attr_count = query_attr_count(q);
-    for (ix = 0; ix < attr_count; ++ix) {
-        CFStringAppendFormat(sql, NULL, CFSTR(",%@"),
-                             query_attr_at(q, ix).key);
-    }
-    if (q->q_row_id) {
-        CFStringAppendFormat(sql, NULL, CFSTR(",rowid"));
-    }
-
-    CFStringAppend(sql, CFSTR(")VALUES(?"));
-
-    for (ix = 0; ix < attr_count; ++ix) {
-        CFStringAppend(sql, CFSTR(",?"));
-       }
-    if (q->q_row_id) {
-        CFStringAppendFormat(sql, NULL, CFSTR(",%qd"), q->q_row_id);
-    }
-    CFStringAppend(sql, CFSTR(");"));
-    return sql;
+static CFDataRef SecDbItemMakePersistentRef(SecDbItemRef item, CFErrorRef *error) {
+    sqlite3_int64 row_id = SecDbItemGetRowId(item, error);
+    if (row_id)
+        return _SecItemMakePersistentRef(SecDbItemGetClass(item)->name, row_id);
+    return NULL;
 }
 
 }
 
-static CFDataRef s3dl_encode_item(keybag_handle_t keybag, keyclass_t keyclass,
-                                  CFDictionaryRef item, OSStatus *error) {
-    /* Encode to be encrypted item. */
-    CFDataRef plain = CFPropertyListCreateData(0, item,
-        kCFPropertyListBinaryFormat_v1_0, 0, 0);
-    CFDataRef edata = NULL;
-       if (plain) {
-        int s3e = ks_encrypt_data(keybag, keyclass, plain, &edata);
-        if (s3e) {
-            asl_log(NULL, NULL, ASL_LEVEL_CRIT,
-                    "ks_encrypt_data: failed: %d", s3e);
-            if (error && !*error)
-                *error = s3e;
-        }
-        CFRelease(plain);
-    } else {
-        if (error && !*error)
-            *error = errSecAllocate;
-    }
-    return edata;
-}
-
-/* Bind the parameters to the INSERT statement. */
-static int s3dl_insert_bind(Query *q, sqlite3_stmt *stmt) {
-    int s3e = SQLITE_OK;
-       int param = 1;
-    OSStatus error = 0;
-    CFDataRef edata = s3dl_encode_item(q->q_keybag, q->q_keyclass, q->q_item, &error);
-       if (edata) {
-        s3e = sqlite3_bind_blob_wrapper(stmt, param, CFDataGetBytePtr(edata),
-                                CFDataGetLength(edata), SQLITE_TRANSIENT);
-        secdebug("bind", "bind_blob: %.*s: %d",
-                 CFDataGetLength(edata), CFDataGetBytePtr(edata), s3e);
-        CFRelease(edata);
-       } else {
-        s3e = error;
-    }
-       param++;
+static CFTypeRef SecDbItemCopyResult(SecDbItemRef item, ReturnTypeMask return_type, CFErrorRef *error) {
+    CFTypeRef a_result;
 
 
-    CFIndex ix, attr_count = query_attr_count(q);
-    for (ix = 0; s3e == SQLITE_OK && ix < attr_count; ++ix) {
-        s3e = kc_bind_paramter(stmt, param++, query_attr_at(q, ix).value);
+       if (return_type == 0) {
+               /* Caller isn't interested in any results at all. */
+               a_result = kCFNull;
+       } else if (return_type == kSecReturnDataMask) {
+        a_result = SecDbItemGetCachedValueWithName(item, kSecValueData);
+        if (a_result) {
+            CFRetainSafe(a_result);
+        } else {
+            a_result = CFDataCreate(kCFAllocatorDefault, NULL, 0);
+        }
+       } else if (return_type == kSecReturnPersistentRefMask) {
+               a_result = SecDbItemMakePersistentRef(item, error);
+       } else {
+        CFMutableDictionaryRef dict = CFDictionaryCreateMutableForCFTypes(CFGetAllocator(item));
+               /* We need to return more than one value. */
+        if (return_type & kSecReturnRefMask) {
+            CFDictionarySetValue(dict, kSecClass, SecDbItemGetClass(item)->name);
+        }
+        CFOptionFlags mask = (((return_type & kSecReturnDataMask || return_type & kSecReturnRefMask) ? kSecDbReturnDataFlag : 0) |
+                              ((return_type & kSecReturnAttributesMask || return_type & kSecReturnRefMask) ? kSecDbReturnAttrFlag : 0));
+        SecDbForEachAttr(SecDbItemGetClass(item), desc) {
+            if ((desc->flags & mask) != 0) {
+                CFTypeRef value = SecDbItemGetValue(item, desc, error);
+                if (value && !CFEqual(kCFNull, value)) {
+                    CFDictionarySetValue(dict, desc->name, value);
+                } else if (value == NULL) {
+                    CFReleaseNull(dict);
+                    break;
+                }
+            }
+        }
+               if (return_type & kSecReturnPersistentRefMask) {
+            CFDataRef pref = SecDbItemMakePersistentRef(item, error);
+                       CFDictionarySetValue(dict, kSecValuePersistentRef, pref);
+            CFRelease(pref);
+               }
+
+               a_result = dict;
        }
 
        }
 
-    return s3e;
+       return a_result;
 }
 
 }
 
+
+// MARK: -
+// MARK: Forward declarations
+
+static CFMutableDictionaryRef
+s3dl_item_from_col(sqlite3_stmt *stmt, Query *q, int col,
+                   CFArrayRef accessGroups, keyclass_t *keyclass, CFErrorRef *error);
+
 /* AUDIT[securityd](done):
    attributes (ok) is a caller provided dictionary, only its cf type has
        been checked.
  */
 /* AUDIT[securityd](done):
    attributes (ok) is a caller provided dictionary, only its cf type has
        been checked.
  */
-static OSStatus
-s3dl_query_add(s3dl_db_thread *dbt, Query *q, CFTypeRef *result)
+static bool
+s3dl_query_add(SecDbConnectionRef dbt, Query *q, CFTypeRef *result, CFErrorRef *error)
 {
 {
-    int s3e;
-
     if (query_match_count(q) != 0)
         return errSecItemMatchUnsupported;
 
     if (query_match_count(q) != 0)
         return errSecItemMatchUnsupported;
 
@@ -2897,89 +1988,129 @@ s3dl_query_add(s3dl_db_thread *dbt, Query *q, CFTypeRef *result)
     if (q->q_use_item_list)
         return errSecUseItemListUnsupported;
 
     if (q->q_use_item_list)
         return errSecUseItemListUnsupported;
 
-       /* Actual work here. */
-       sqlite3 *s3h = dbt->s3_handle;
-
-    CFStringRef sql = s3dl_insert_sql(q);
-       sqlite3_stmt *stmt = NULL;
-    s3e = kc_prepare_statement(s3h, sql, &stmt);
-       CFRelease(sql);
-
-       if (s3e == SQLITE_OK)
-        s3e = s3dl_insert_bind(q, stmt);
-
-       /* Now execute the INSERT statement (step). */
-       if (s3e == SQLITE_OK) {
-               s3e = sqlite3_step(stmt);
-               if (s3e == SQLITE_DONE) {
-                       s3e = SQLITE_OK;
-            if (q->q_return_type) {
-                *result = handle_result(q, q->q_item, sqlite3_last_insert_rowid(s3h));
-            }
-               } else if (s3e == SQLITE_ERROR) {
-                       secdebug("sql", "insert: %s", sqlite3_errmsg(s3h));
-            /* The object already existed. */
-                       s3e = errSecDuplicateItem;
+    /* Actual work here. */
+    SecDbItemRef item = SecDbItemCreateWithAttributes(kCFAllocatorDefault, q->q_class, q->q_item, KEYBAG_DEVICE, error);
+    if (!item)
+        return false;
+
+    bool ok = true;
+    if (q->q_data)
+        ok = SecDbItemSetValueWithName(item, CFSTR("v_Data"), q->q_data, error);
+    if (q->q_row_id)
+        ok = SecDbItemSetRowId(item, q->q_row_id, error);
+
+    if (ok)
+        ok = SecDbItemInsert(item, dbt, error);
+    if (ok) {
+        if (result && q->q_return_type) {
+            *result = SecDbItemCopyResult(item, q->q_return_type, error);
         }
         }
-       }
+    }
+    if (!ok && error && *error) {
+        if (CFEqual(CFErrorGetDomain(*error), kSecDbErrorDomain) && CFErrorGetCode(*error) == SQLITE_CONSTRAINT) {
+            CFReleaseNull(*error);
+            SecError(errSecDuplicateItem, error, CFSTR("duplicate item %@"), item);
+        }
+    }
 
 
-       /* Free the stmt. */
-       if (stmt) {
-               int s3e2 = sqlite3_finalize(stmt);
-               if (s3e2 != SQLITE_OK && s3e == SQLITE_OK)
-                       s3e = s3e2;
-       }
+    if (ok) {
+        q->q_changed = true;
+        if (SecDbItemIsSyncable(item))
+            q->q_sync_changed = true;
+    }
+
+    secdebug("dbitem", "inserting item %@%s%@", item, ok ? "" : "failed: ", ok || error == NULL ? (CFErrorRef)CFSTR("") : *error);
+
+    CFRelease(item);
 
 
-       return s3e == SQLITE_OK ? 0 : osstatus_for_s3e(s3e);
+       return ok;
 }
 
 typedef void (*s3dl_handle_row)(sqlite3_stmt *stmt, void *context);
 
 }
 
 typedef void (*s3dl_handle_row)(sqlite3_stmt *stmt, void *context);
 
+/* Return a (mutable) dictionary if plist is a dictionary, return NULL and set error otherwise.  Does nothing if plist is already NULL. */
+static CFMutableDictionaryRef dictionaryFromPlist(CFPropertyListRef plist, CFErrorRef *error) {
+    if (plist && !isDictionary(plist)) {
+        CFStringRef typeName = CFCopyTypeIDDescription(CFGetTypeID((CFTypeRef)plist));
+        SecError(errSecDecode, error, CFSTR("plist is a %@, expecting a dictionary"), typeName);
+        CFReleaseSafe(typeName);
+        CFReleaseNull(plist);
+    }
+    return (CFMutableDictionaryRef)plist;
+}
+
+static CFMutableDictionaryRef s3dl_item_v2_decode(CFDataRef plain, CFErrorRef *error) {
+    CFPropertyListRef item;
+    item = CFPropertyListCreateWithData(0, plain, kCFPropertyListMutableContainers, NULL, error);
+    return dictionaryFromPlist(item, error);
+}
+
+static CFMutableDictionaryRef s3dl_item_v3_decode(CFDataRef plain, CFErrorRef *error) {
+    CFPropertyListRef item = NULL;
+    const uint8_t *der = CFDataGetBytePtr(plain);
+    const uint8_t *der_end = der + CFDataGetLength(plain);
+    der = der_decode_plist(0, kCFPropertyListMutableContainers, &item, error, der, der_end);
+    if (der && der != der_end) {
+        SecCFCreateError(errSecDecode, kSecErrorDomain, CFSTR("trailing garbage at end of decrypted item"), NULL, error);
+        CFReleaseNull(item);
+    }
+    return dictionaryFromPlist(item, error);
+}
+
 static CFMutableDictionaryRef
 static CFMutableDictionaryRef
-s3dl_item_from_col(sqlite3_stmt *stmt, Query *q, int col,
-                   CFArrayRef accessGroups, keyclass_t *keyclass) {
+s3dl_item_from_data(CFDataRef edata, Query *q, CFArrayRef accessGroups, keyclass_t *keyclass, CFErrorRef *error) {
     CFMutableDictionaryRef item = NULL;
     CFMutableDictionaryRef item = NULL;
-    CFErrorRef error = NULL;
-    CFDataRef edata = NULL;
     CFDataRef plain =  NULL;
 
     CFDataRef plain =  NULL;
 
-    require_action(edata = CFDataCreateWithBytesNoCopy(0, sqlite3_column_blob(stmt, col),
-                                                       sqlite3_column_bytes(stmt, col),
-                                                       kCFAllocatorNull),
-                   out, q->q_error = errSecDecode);
-
     /* Decrypt and decode the item and check the decoded attributes against the query. */
     uint32_t version;
     /* Decrypt and decode the item and check the decoded attributes against the query. */
     uint32_t version;
-    require_noerr((q->q_error = ks_decrypt_data(q->q_keybag, keyclass, edata, &plain, &version)), out);
+    require_quiet((ks_decrypt_data(q->q_keybag, keyclass, edata, &plain, &version, error)), out);
     if (version < 2) {
         goto out;
     }
 
     if (version < 2) {
         goto out;
     }
 
-    CFPropertyListFormat format;
-    item = (CFMutableDictionaryRef)CFPropertyListCreateWithData(0, plain,
-        kCFPropertyListMutableContainers, &format, &error);
-    if (!item) {
-        secerror("decode failed: %@ [item: %@]", error, plain);
-        q->q_error = (OSStatus)CFErrorGetCode(error); /* possibly truncated error codes: whatever */
-        CFRelease(error);
-    } else if (!isDictionary(item)) {
-        CFRelease(item);
-        item = NULL;
-    } else if (!itemInAccessGroup(item, accessGroups)) {
+    if (version < 3) {
+        item = s3dl_item_v2_decode(plain, error);
+    } else {
+        item = s3dl_item_v3_decode(plain, error);
+    }
+
+    if (!item && plain) {
+        secerror("decode v%d failed: %@ [item: %@]", version, error ? *error : NULL, plain);
+    }
+    if (item && !itemInAccessGroup(item, accessGroups)) {
         secerror("items accessGroup %@ not in %@",
                  CFDictionaryGetValue(item, kSecAttrAccessGroup),
                  accessGroups);
         secerror("items accessGroup %@ not in %@",
                  CFDictionaryGetValue(item, kSecAttrAccessGroup),
                  accessGroups);
-        CFRelease(item);
-        item = NULL;
+        CFReleaseNull(item);
     }
     /* TODO: Validate keyclass attribute. */
 
 out:
     }
     /* TODO: Validate keyclass attribute. */
 
 out:
-    CFReleaseSafe(edata);
     CFReleaseSafe(plain);
     return item;
 }
 
     CFReleaseSafe(plain);
     return item;
 }
 
+static CFDataRef
+s3dl_copy_data_from_col(sqlite3_stmt *stmt, int col, CFErrorRef *error) {
+    return CFDataCreateWithBytesNoCopy(0, sqlite3_column_blob(stmt, col),
+                                        sqlite3_column_bytes(stmt, col),
+                                        kCFAllocatorNull);
+}
+
+static CFMutableDictionaryRef
+s3dl_item_from_col(sqlite3_stmt *stmt, Query *q, int col,
+                   CFArrayRef accessGroups, keyclass_t *keyclass, CFErrorRef *error) {
+    CFMutableDictionaryRef item = NULL;
+    CFDataRef edata = NULL;
+    require(edata = s3dl_copy_data_from_col(stmt, col, error), out);
+    item = s3dl_item_from_data(edata, q, accessGroups, keyclass, error);
+
+out:
+    CFReleaseSafe(edata);
+    return item;
+}
+
 struct s3dl_query_ctx {
     Query *q;
     CFArrayRef accessGroups;
 struct s3dl_query_ctx {
     Query *q;
     CFArrayRef accessGroups;
@@ -2987,19 +2118,62 @@ struct s3dl_query_ctx {
     int found;
 };
 
     int found;
 };
 
+static bool match_item(Query *q, CFArrayRef accessGroups, CFDictionaryRef item);
+
 static void s3dl_query_row(sqlite3_stmt *stmt, void *context) {
     struct s3dl_query_ctx *c = context;
     Query *q = c->q;
 
     CFMutableDictionaryRef item = s3dl_item_from_col(stmt, q, 1,
 static void s3dl_query_row(sqlite3_stmt *stmt, void *context) {
     struct s3dl_query_ctx *c = context;
     Query *q = c->q;
 
     CFMutableDictionaryRef item = s3dl_item_from_col(stmt, q, 1,
-                                                     c->accessGroups, NULL);
-    if (!item)
+                                                     c->accessGroups, NULL, &q->q_error);
+    sqlite_int64 rowid = sqlite3_column_int64(stmt, 0);
+    if (!item) {
+        secerror("decode %@,rowid=%" PRId64 " failed (%ld): %@", q->q_class->name, rowid, CFErrorGetCode(q->q_error), q->q_error);
+        // errSecDecode means the tiem is corrupted, stash it for delete.
+        if(CFErrorGetCode(q->q_error)==errSecDecode)
+        {
+            secerror("We should attempt to delete this row (%lld)", rowid);
+
+            {
+                CFDataRef edata = s3dl_copy_data_from_col(stmt, 1, NULL);
+                CFMutableStringRef edatastring =  CFStringCreateMutable(kCFAllocatorDefault, 0);
+                if(edatastring) {
+                    CFStringAppendEncryptedData(edatastring, edata);
+                    secnotice("item", "corrupted edata=%@", edatastring);
+                }
+                CFReleaseSafe(edata);
+                CFReleaseSafe(edatastring);
+            }
+
+            if(q->corrupted_rows==NULL) {
+                q->corrupted_rows=CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
+            }
+
+            if(q->corrupted_rows==NULL) {
+                secerror("Could not create a mutable array to store corrupted row! No memory ?");
+            } else {
+                long long row=rowid;
+                CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberLongLongType, &row);
+                if(number==NULL) {
+                    secerror("Could not create a CFNumber to store corrupted row! No memory ?");
+                } else {
+                    CFArrayAppendValue(q->corrupted_rows, number);
+                    CFReleaseNull(number);
+                    /* Hide this error, this will just pretend the item didnt exist at all */
+                    CFReleaseNull(q->q_error);
+                }
+            }
+        }
+        // q->q_error will be released appropriately by a call to query_error
         return;
         return;
+    }
 
     if (q->q_class == &identity_class) {
 
     if (q->q_class == &identity_class) {
-        // TODO: Use col 2 for key rowid and use both rowids in persistant ref.
+        // TODO: Use col 2 for key rowid and use both rowids in persistent ref.
         CFMutableDictionaryRef key = s3dl_item_from_col(stmt, q, 3,
         CFMutableDictionaryRef key = s3dl_item_from_col(stmt, q, 3,
-                                                        c->accessGroups, NULL);
+                                                        c->accessGroups, NULL, &q->q_error);
+
+        /* TODO : if there is a errSecDecode error here, we should cleanup */
         if (!key)
             goto out;
 
         if (!key)
             goto out;
 
@@ -3014,7 +2188,9 @@ static void s3dl_query_row(sqlite3_stmt *stmt, void *context) {
         item = key;
     }
 
         item = key;
     }
 
-    sqlite_int64 rowid = sqlite3_column_int64(stmt, 0);
+    if (!match_item(q, c->accessGroups, item))
+        goto out;
+
     CFTypeRef a_result = handle_result(q, item, rowid);
     if (a_result) {
         if (a_result == kCFNull) {
     CFTypeRef a_result = handle_result(q, item, rowid);
     if (a_result) {
         if (a_result == kCFNull) {
@@ -3033,111 +2209,26 @@ out:
     CFRelease(item);
 }
 
     CFRelease(item);
 }
 
-struct s3dl_update_row_ctx {
-    struct s3dl_query_ctx qc;
-    Query *u;
-    sqlite3_stmt *update_stmt;
-};
-
-
-static void s3dl_update_row(sqlite3_stmt *stmt, void *context)
-{
-    struct s3dl_update_row_ctx *c = context;
-    Query *q = c->qc.q;
-
-    int s3e = SQLITE_OK;
-    CFDataRef edata = NULL;
-    keyclass_t keyclass;
-    sqlite_int64 rowid = sqlite3_column_int64(stmt, 0);
-    CFMutableDictionaryRef item;
-    require(item = s3dl_item_from_col(stmt, q, 1, c->qc.accessGroups,
-                                      &keyclass), out);
-
-    /* Update modified attributes in item and reencrypt. */
-    Query *u = c->u;
-    CFDictionaryApplyFunction(u->q_item, s3dl_merge_into_dict, item);
-    if (u->q_keyclass) {
-        keyclass = u->q_keyclass;
-    }
-
-    require(edata = s3dl_encode_item(q->q_keybag, keyclass, item, &q->q_error),
-            out);
-
-    /* Bind rowid and data to UPDATE statement and step. */
-    /* Skip over already bound attribute values being updated, since we don't
-       change them for each item. */
-    CFIndex count = 1 + query_attr_count(u);
-    /* 64 bits cast: worst case is if you try to have more than 2^32 attributes, we will drop some */
-    assert(count < INT_MAX); /* Debug check */
-    int param = (int)count;
-    s3e = sqlite3_bind_blob_wrapper(c->update_stmt, param++,
-                            CFDataGetBytePtr(edata), CFDataGetLength(edata),
-                            SQLITE_TRANSIENT);
-    if (s3e == SQLITE_OK)
-        s3e = sqlite3_bind_int64(c->update_stmt, param++, rowid);
-
-    /* Now execute the UPDATE statement (step). */
-       if (s3e == SQLITE_OK) {
-               s3e = sqlite3_step(c->update_stmt);
-               if (s3e == SQLITE_DONE) {
-            s3e = SQLITE_OK;
-            c->qc.found++;
-            secdebug("sql", "updated row: %llu", rowid);
-               } else if (s3e == SQLITE_ERROR) {
-            /* sqlite3_reset() below will return the real error. */
-            s3e = SQLITE_OK;
-        }
-       }
-
-out:
-    if (s3e) q->q_error = osstatus_for_s3e(s3e);
-    s3e = sqlite3_reset(c->update_stmt);    /* Reset state, but not bindings. */
-    if (s3e && !q->q_error) q->q_error = osstatus_for_s3e(s3e);
-    if (q->q_error) { secdebug("sql", "update failed: %d", q->q_error); }
-
-       CFReleaseSafe(item);
-       CFReleaseSafe(edata);
-}
-
-/* Append AND is needWhere is NULL or *needWhere is false.  Append WHERE
-   otherwise.  Upon return *needWhere will be false.  */
-static void
-sqlAppendWhereOrAnd(CFMutableStringRef sql, bool *needWhere) {
-    if (!needWhere || !*needWhere) {
-        CFStringAppend(sql, CFSTR(" AND "));
-    } else {
-        CFStringAppend(sql, CFSTR(" WHERE "));
-        *needWhere = false;
-    }
-}
-
-static void
-sqlAppendWhereBind(CFMutableStringRef sql, CFStringRef col, bool *needWhere) {
-    sqlAppendWhereOrAnd(sql, needWhere);
-    CFStringAppend(sql, col);
-    CFStringAppend(sql, CFSTR("=?"));
-}
-
 static void
 static void
-sqlAppendWhereROWID(CFMutableStringRef sql,
+SecDbAppendWhereROWID(CFMutableStringRef sql,
                     CFStringRef col, sqlite_int64 row_id,
                     bool *needWhere) {
     if (row_id > 0) {
                     CFStringRef col, sqlite_int64 row_id,
                     bool *needWhere) {
     if (row_id > 0) {
-        sqlAppendWhereOrAnd(sql, needWhere);
+        SecDbAppendWhereOrAnd(sql, needWhere);
         CFStringAppendFormat(sql, NULL, CFSTR("%@=%lld"), col, row_id);
     }
 }
 
 static void
         CFStringAppendFormat(sql, NULL, CFSTR("%@=%lld"), col, row_id);
     }
 }
 
 static void
-sqlAppendWhereAttrs(CFMutableStringRef sql, const Query *q, bool *needWhere) {
+SecDbAppendWhereAttrs(CFMutableStringRef sql, const Query *q, bool *needWhere) {
     CFIndex ix, attr_count = query_attr_count(q);
     for (ix = 0; ix < attr_count; ++ix) {
     CFIndex ix, attr_count = query_attr_count(q);
     for (ix = 0; ix < attr_count; ++ix) {
-        sqlAppendWhereBind(sql, query_attr_at(q, ix).key, needWhere);
+        SecDbAppendWhereOrAndEquals(sql, query_attr_at(q, ix).key, needWhere);
     }
 }
 
 static void
     }
 }
 
 static void
-sqlAppendWhereAccessGroups(CFMutableStringRef sql,
+SecDbAppendWhereAccessGroups(CFMutableStringRef sql,
                            CFStringRef col,
                            CFArrayRef accessGroups,
                            bool *needWhere) {
                            CFStringRef col,
                            CFArrayRef accessGroups,
                            bool *needWhere) {
@@ -3146,353 +2237,361 @@ sqlAppendWhereAccessGroups(CFMutableStringRef sql,
         return;
     }
 
         return;
     }
 
-    sqlAppendWhereOrAnd(sql, needWhere);
-#if 1
+    SecDbAppendWhereOrAnd(sql, needWhere);
     CFStringAppend(sql, col);
     CFStringAppend(sql, CFSTR(" IN (?"));
     for (ix = 1; ix < ag_count; ++ix) {
         CFStringAppend(sql, CFSTR(",?"));
     }
     CFStringAppend(sql, CFSTR(")"));
     CFStringAppend(sql, col);
     CFStringAppend(sql, CFSTR(" IN (?"));
     for (ix = 1; ix < ag_count; ++ix) {
         CFStringAppend(sql, CFSTR(",?"));
     }
     CFStringAppend(sql, CFSTR(")"));
-#else
-    CFStringAppendFormat(sql, 0, CFSTR("(%@=?"), col);
-    for (ix = 1; ix < ag_count; ++ix) {
-        CFStringAppendFormat(sql, 0, CFSTR(" OR %@=?"), col);
-    }
-    CFStringAppend(sql, CFSTR(")"));
-#endif
 }
 
 }
 
-static void sqlAppendWhereClause(CFMutableStringRef sql, const Query *q,
+static void SecDbAppendWhereClause(CFMutableStringRef sql, const Query *q,
     CFArrayRef accessGroups) {
     bool needWhere = true;
     CFArrayRef accessGroups) {
     bool needWhere = true;
-    sqlAppendWhereROWID(sql, CFSTR("ROWID"), q->q_row_id, &needWhere);
-    sqlAppendWhereAttrs(sql, q, &needWhere);
-    sqlAppendWhereAccessGroups(sql, CFSTR("agrp"), accessGroups, &needWhere);
+    SecDbAppendWhereROWID(sql, CFSTR("ROWID"), q->q_row_id, &needWhere);
+    SecDbAppendWhereAttrs(sql, q, &needWhere);
+    SecDbAppendWhereAccessGroups(sql, CFSTR("agrp"), accessGroups, &needWhere);
 }
 
 }
 
-static void sqlAppendLimit(CFMutableStringRef sql, CFIndex limit) {
+static void SecDbAppendLimit(CFMutableStringRef sql, CFIndex limit) {
     if (limit != kSecMatchUnlimited)
     if (limit != kSecMatchUnlimited)
-        CFStringAppendFormat(sql, NULL, CFSTR(" LIMIT %d;"), limit);
-    else
-        CFStringAppend(sql, CFSTR(";"));
+        CFStringAppendFormat(sql, NULL, CFSTR(" LIMIT %" PRIdCFIndex), limit);
 }
 
 }
 
-static CFStringRef s3dl_select_sql(Query *q, int version, CFArrayRef accessGroups) {
+static CFStringRef s3dl_select_sql(Query *q, CFArrayRef accessGroups) {
     CFMutableStringRef sql = CFStringCreateMutable(NULL, 0);
        if (q->q_class == &identity_class) {
         CFStringAppendFormat(sql, NULL, CFSTR("SELECT crowid, "
     CFMutableStringRef sql = CFStringCreateMutable(NULL, 0);
        if (q->q_class == &identity_class) {
         CFStringAppendFormat(sql, NULL, CFSTR("SELECT crowid, "
-            CERTIFICATE_DATA_COLUMN_LABEL ", rowid, data FROM "
+            CERTIFICATE_DATA_COLUMN_LABEL ", rowid,data FROM "
             "(SELECT cert.rowid AS crowid, cert.labl AS labl,"
             " cert.issr AS issr, cert.slnr AS slnr, cert.skid AS skid,"
             "(SELECT cert.rowid AS crowid, cert.labl AS labl,"
             " cert.issr AS issr, cert.slnr AS slnr, cert.skid AS skid,"
-            " keys.*, cert.data AS " CERTIFICATE_DATA_COLUMN_LABEL
+            " keys.*,cert.data AS " CERTIFICATE_DATA_COLUMN_LABEL
             " FROM keys, cert"
             " WHERE keys.priv == 1 AND cert.pkhh == keys.klbl"));
             " FROM keys, cert"
             " WHERE keys.priv == 1 AND cert.pkhh == keys.klbl"));
-        sqlAppendWhereAccessGroups(sql, CFSTR("cert.agrp"), accessGroups, 0);
-        /* The next 3 sqlAppendWhere calls are in the same order as in
-           sqlAppendWhereClause().  This makes sqlBindWhereClause() work,
+        SecDbAppendWhereAccessGroups(sql, CFSTR("cert.agrp"), accessGroups, 0);
+        /* The next 3 SecDbAppendWhere calls are in the same order as in
+           SecDbAppendWhereClause().  This makes sqlBindWhereClause() work,
            as long as we do an extra sqlBindAccessGroups first. */
            as long as we do an extra sqlBindAccessGroups first. */
-        sqlAppendWhereROWID(sql, CFSTR("crowid"), q->q_row_id, 0);
+        SecDbAppendWhereROWID(sql, CFSTR("crowid"), q->q_row_id, 0);
         CFStringAppend(sql, CFSTR(")"));
         bool needWhere = true;
         CFStringAppend(sql, CFSTR(")"));
         bool needWhere = true;
-        sqlAppendWhereAttrs(sql, q, &needWhere);
-        sqlAppendWhereAccessGroups(sql, CFSTR("agrp"), accessGroups, &needWhere);
+        SecDbAppendWhereAttrs(sql, q, &needWhere);
+        SecDbAppendWhereAccessGroups(sql, CFSTR("agrp"), accessGroups, &needWhere);
        } else {
        } else {
-        CFStringAppend(sql, (version < 5 ? CFSTR("SELECT * FROM ") :
-                             CFSTR("SELECT rowid, data FROM ")));
+        CFStringAppend(sql, CFSTR("SELECT rowid, data FROM "));
                CFStringAppend(sql, q->q_class->name);
                CFStringAppend(sql, q->q_class->name);
-        sqlAppendWhereClause(sql, q, accessGroups);
+        SecDbAppendWhereClause(sql, q, accessGroups);
     }
     }
-    sqlAppendLimit(sql, q->q_limit);
+    SecDbAppendLimit(sql, q->q_limit);
 
     return sql;
 }
 
 
     return sql;
 }
 
-static int sqlBindAccessGroups(sqlite3_stmt *stmt, CFArrayRef accessGroups,
-                               int *pParam) {
-    int s3e = SQLITE_OK;
+static bool sqlBindAccessGroups(sqlite3_stmt *stmt, CFArrayRef accessGroups,
+                               int *pParam, CFErrorRef *error) {
+    bool result = true;
     int param = *pParam;
     CFIndex ix, count = accessGroups ? CFArrayGetCount(accessGroups) : 0;
     for (ix = 0; ix < count; ++ix) {
     int param = *pParam;
     CFIndex ix, count = accessGroups ? CFArrayGetCount(accessGroups) : 0;
     for (ix = 0; ix < count; ++ix) {
-        s3e = kc_bind_paramter(stmt, param++,
-                               CFArrayGetValueAtIndex(accessGroups, ix));
-        if (s3e)
+        result = SecDbBindObject(stmt, param++,
+                                  CFArrayGetValueAtIndex(accessGroups, ix),
+                                  error);
+        if (!result)
             break;
     }
     *pParam = param;
             break;
     }
     *pParam = param;
-    return s3e;
+    return result;
 }
 
 }
 
-static int sqlBindWhereClause(sqlite3_stmt *stmt, const Query *q,
-    CFArrayRef accessGroups, int *pParam) {
-    int s3e = SQLITE_OK;
+static bool sqlBindWhereClause(sqlite3_stmt *stmt, const Query *q,
+    CFArrayRef accessGroups, int *pParam, CFErrorRef *error) {
+    bool result = true;
     int param = *pParam;
     CFIndex ix, attr_count = query_attr_count(q);
     for (ix = 0; ix < attr_count; ++ix) {
     int param = *pParam;
     CFIndex ix, attr_count = query_attr_count(q);
     for (ix = 0; ix < attr_count; ++ix) {
-        s3e = kc_bind_paramter(stmt, param++, query_attr_at(q, ix).value);
-        if (s3e)
+        result = SecDbBindObject(stmt, param++, query_attr_at(q, ix).value, error);
+        if (!result)
             break;
        }
 
     /* Bind the access group to the sql. */
             break;
        }
 
     /* Bind the access group to the sql. */
-    if (s3e == SQLITE_OK) {
-        s3e = sqlBindAccessGroups(stmt, accessGroups, &param);
+    if (result) {
+        result = sqlBindAccessGroups(stmt, accessGroups, &param, error);
     }
 
     *pParam = param;
     }
 
     *pParam = param;
-    return s3e;
+    return result;
+}
+
+static bool SecDbItemQuery(SecDbQueryRef query, CFArrayRef accessGroups, SecDbConnectionRef dbconn, CFErrorRef *error,
+                    void (^handle_row)(SecDbItemRef item, bool *stop)) {
+    __block bool ok = true;
+    /* Sanity check the query. */
+    if (query->q_ref)
+        return SecError(errSecValueRefUnsupported, error, CFSTR("value ref not supported by queries"));
+
+    bool (^return_attr)(const SecDbAttr *attr) = ^bool (const SecDbAttr * attr) {
+        return attr->kind == kSecDbRowIdAttr || attr->kind == kSecDbEncryptedDataAttr;
+    };
+
+    CFStringRef sql = s3dl_select_sql(query, accessGroups);
+    ok = sql;
+    if (sql) {
+        ok &= SecDbPrepare(dbconn, sql, error, ^(sqlite3_stmt *stmt) {
+            /* Bind the values being searched for to the SELECT statement. */
+            int param = 1;
+            if (query->q_class == &identity_class) {
+                /* Bind the access groups to cert.agrp. */
+                ok &= sqlBindAccessGroups(stmt, accessGroups, &param, error);
+            }
+            if (ok)
+                ok &= sqlBindWhereClause(stmt, query, accessGroups, &param, error);
+            if (ok) {
+                SecDbStep(dbconn, stmt, error, ^(bool *stop) {
+                    SecDbItemRef item = SecDbItemCreateWithStatement(kCFAllocatorDefault, query->q_class, stmt, query->q_keybag, error, return_attr);
+                    if (item) {
+                        if (match_item(query, accessGroups, item->attributes))
+                            handle_row(item, stop);
+                        CFRelease(item);
+                    } else {
+                        secerror("failed to create item from stmt: %@", error ? *error : (CFErrorRef)"no error");
+                        if (error) {
+                            CFReleaseNull(*error);
+                        }
+                        //*stop = true;
+                        //ok = false;
+                    }
+                });
+            }
+        });
+        CFRelease(sql);
+    }
+
+    return ok;
 }
 
 }
 
-static OSStatus
-s3dl_query(s3dl_db_thread *dbt, s3dl_handle_row handle_row, int version,
-           void *context)
+static bool
+s3dl_query(SecDbConnectionRef dbt, s3dl_handle_row handle_row,
+           void *context, CFErrorRef *error)
 {
     struct s3dl_query_ctx *c = context;
     Query *q = c->q;
     CFArrayRef accessGroups = c->accessGroups;
 {
     struct s3dl_query_ctx *c = context;
     Query *q = c->q;
     CFArrayRef accessGroups = c->accessGroups;
-    int s3e;
 
     /* Sanity check the query. */
     if (q->q_ref)
 
     /* Sanity check the query. */
     if (q->q_ref)
-        return errSecValueRefUnsupported;
-    if (q->q_row_id && query_attr_count(q))
-        return errSecItemIllegalQuery;
+        return SecError(errSecValueRefUnsupported, error, CFSTR("value ref not supported by queries"));
 
        /* Actual work here. */
 
        /* Actual work here. */
-       sqlite3 *s3h = dbt->s3_handle;
-
-    CFStringRef sql = s3dl_select_sql(q, version, accessGroups);
-       sqlite3_stmt *stmt = NULL;
-    s3e = kc_prepare_statement(s3h, sql, &stmt);
-       CFRelease(sql);
-
-       /* Bind the values being searched for to the SELECT statement. */
-       if (s3e == SQLITE_OK) {
-        int param = 1;
-        if (q->q_class == &identity_class) {
-            /* Bind the access groups to cert.agrp. */
-            s3e = sqlBindAccessGroups(stmt, accessGroups, &param);
-        }
-        if (s3e == SQLITE_OK)
-            s3e = sqlBindWhereClause(stmt, q, accessGroups, &param);
-    }
-
-       /* Now execute the SELECT statement (step). */
     if (q->q_limit == 1) {
         c->result = NULL;
     } else {
         c->result = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
     }
     if (q->q_limit == 1) {
         c->result = NULL;
     } else {
         c->result = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
     }
-       while (s3e == SQLITE_OK &&
-        (q->q_limit == kSecMatchUnlimited || c->found < q->q_limit)) {
-               s3e = sqlite3_step(stmt);
-               if (s3e == SQLITE_ROW) {
-                       handle_row(stmt, context);
-            /* Extract the error returned by handle_row. */
-            s3e = q->q_error;
-            if (s3e == errSecDecode) {
-                secerror("Ignoring undecryptable %@ item: ", q->q_class->name);
-                /* Ignore decode errors, since that means the item in question
-                   is unreadable forever, this allows export to skip these
-                   items and a backup/restore cycle to filter broken items
-                   from your keychain.
-                   Ideally we should mark the current rowid for removal since
-                   it's corrupt.  The tricky bit is at this level we no longer
-                   know if the key or the cert failed to decode when dealing
-                   with identities. */
-                s3e = SQLITE_OK;
-            }
-               } else if (s3e == SQLITE_DONE) {
-            if (c->found == 0) {
-                /* We ran out of rows and didn't get any matches yet. */
-                s3e = errSecItemNotFound;
-            } else {
-                               /* We got at least one match, so set the error status to ok. */
-                               s3e = SQLITE_OK;
-                       }
-            break;
-               } else if (s3e != SQLITE_OK) {
-                       secdebug("sql", "select: %d: %s", s3e, sqlite3_errmsg(s3h));
+    CFStringRef sql = s3dl_select_sql(q, accessGroups);
+    bool ok = SecDbWithSQL(dbt, sql, error, ^(sqlite3_stmt *stmt) {
+        bool sql_ok = true;
+        /* Bind the values being searched for to the SELECT statement. */
+        int param = 1;
+        if (q->q_class == &identity_class) {
+            /* Bind the access groups to cert.agrp. */
+            sql_ok = sqlBindAccessGroups(stmt, accessGroups, &param, error);
         }
         }
-       }
+        if (sql_ok)
+            sql_ok = sqlBindWhereClause(stmt, q, accessGroups, &param, error);
+        if (sql_ok) {
+            SecDbForEach(stmt, error, ^bool (int row_index) {
+                handle_row(stmt, context);
+                return (!q->q_error) && (q->q_limit == kSecMatchUnlimited || c->found < q->q_limit);
+            });
+        }
+        return sql_ok;
+    });
 
 
-       /* Free the stmt. */
-       if (stmt) {
-               int s3e2 = sqlite3_finalize(stmt);
-               if (s3e2 != SQLITE_OK && s3e == SQLITE_OK)
-                       s3e = s3e2;
-       }
+    CFRelease(sql);
+
+    // First get the error from the query, since errSecDuplicateItem from an
+    // update query should superceed the errSecItemNotFound below.
+    if (!query_error(q, error))
+        ok = false;
+    if (ok && c->found == 0)
+        ok = SecError(errSecItemNotFound, error, CFSTR("no matching items found"));
+
+    return ok;
+}
+
+#if 0
+/* Gross hack to recover from item corruption */
+static void
+s3dl_cleanup_corrupted(SecDbConnectionRef dbt, Query *q, CFErrorRef *error)
+{
+
+    if(q->corrupted_rows==NULL)
+        return;
+
+    __security_simulatecrash(CFSTR("Corrupted items found in keychain"));
+
+    if (q->q_class == &identity_class) {
+        /* TODO: how to cleanup in that case */
+        secerror("Cleaning up corrupted identities is not implemented yet");
+        goto out;
+    }
+
+    CFArrayForEach(q->corrupted_rows, ^(const void *value) {
+        CFMutableStringRef sql=CFStringCreateMutable(kCFAllocatorDefault, 0);
+
+        if(sql==NULL) {
+            secerror("Could not allocate CFString for sql, out of memory ?");
+        } else {
+            CFStringAppend(sql, CFSTR("DELETE FROM "));
+            CFStringAppend(sql, q->q_class->name);
+            CFStringAppendFormat(sql, NULL, CFSTR(" WHERE rowid=%@"), value);
+
+            secerror("Attempting cleanup with %@", sql);
+
+            if(!SecDbExec(dbt, sql, error)) {
+                secerror("Cleanup Failed using %@, error: %@", sql, error?NULL:*error);
+            } else {
+                secerror("Cleanup Succeeded using %@", sql);
+            }
 
 
-    OSStatus status;
-       if (s3e) status = osstatus_for_s3e(s3e);
-    else if (q->q_error) status = q->q_error;
-    else return 0;
+            CFReleaseSafe(sql);
+        }
+    });
 
 
-    CFReleaseNull(c->result);
-    return status;
+out:
+    CFReleaseNull(q->corrupted_rows);
 }
 }
+#endif
 
 
-static OSStatus
-s3dl_copy_matching(s3dl_db_thread *dbt, Query *q, CFTypeRef *result,
-                   CFArrayRef accessGroups)
+static bool
+s3dl_copy_matching(SecDbConnectionRef dbt, Query *q, CFTypeRef *result,
+                   CFArrayRef accessGroups, CFErrorRef *error)
 {
     struct s3dl_query_ctx ctx = {
         .q = q, .accessGroups = accessGroups,
     };
 {
     struct s3dl_query_ctx ctx = {
         .q = q, .accessGroups = accessGroups,
     };
-    OSStatus status = s3dl_query(dbt, s3dl_query_row, CURRENT_DB_VERSION, &ctx);
-    if (result)
+    if (q->q_row_id && query_attr_count(q))
+        return SecError(errSecItemIllegalQuery, error,
+                        CFSTR("attributes to query illegal; both row_id and other attributes can't be searched at the same time"));
+
+    // Only copy things that aren't tombstones unless the client explicitly asks otherwise.
+    if (!CFDictionaryContainsKey(q->q_item, kSecAttrTombstone))
+        query_add_attribute(kSecAttrTombstone, kCFBooleanFalse, q);
+    bool ok = s3dl_query(dbt, s3dl_query_row, &ctx, error);
+    if (ok && result)
         *result = ctx.result;
     else
         CFReleaseSafe(ctx.result);
         *result = ctx.result;
     else
         CFReleaseSafe(ctx.result);
-    return status;
-}
-
-static CFStringRef s3dl_update_sql(Query *q) {
-    CFMutableStringRef sql = CFStringCreateMutable(NULL, 0);
-    CFStringAppendFormat(sql, NULL, CFSTR("UPDATE %@ SET"), q->q_class->name);
-
-    CFIndex ix, attr_count = query_attr_count(q);
-    for (ix = 0; ix < attr_count; ++ix) {
-        CFStringAppendFormat(sql, NULL, CFSTR(" %@=?,"),
-                             query_attr_at(q, ix).key);
-    }
-    CFStringAppend(sql, CFSTR(" data=? WHERE ROWID=?;"));
 
 
-    return sql;
-}
+    // s3dl_cleanup_corrupted(dbt, q, error);
 
 
-/* Bind the parameters to the UPDATE statement; data=? and ROWID=? are left
-   unbound, since they are bound in s3dl_update_row when the update statement
-   is (re)used. */
-static int s3dl_update_bind(Query *q, sqlite3_stmt *stmt) {
-       /* Bind the values being updated to the UPDATE statement. */
-    int s3e = SQLITE_OK;
-       int param = 1;
-    CFIndex ix, attr_count = query_attr_count(q);
-    for (ix = 0; s3e == SQLITE_OK && ix < attr_count; ++ix) {
-        s3e = kc_bind_paramter(stmt, param++, query_attr_at(q, ix).value);
-       }
-    return s3e;
+    return ok;
 }
 
 /* AUDIT[securityd](done):
    attributesToUpdate (ok) is a caller provided dictionary,
        only its cf types have been checked.
  */
 }
 
 /* AUDIT[securityd](done):
    attributesToUpdate (ok) is a caller provided dictionary,
        only its cf types have been checked.
  */
-static OSStatus
-s3dl_query_update(s3dl_db_thread *dbt, Query *q,
-    CFDictionaryRef attributesToUpdate, CFArrayRef accessGroups)
+static bool
+s3dl_query_update(SecDbConnectionRef dbt, Query *q,
+    CFDictionaryRef attributesToUpdate, CFArrayRef accessGroups, CFErrorRef *error)
 {
     /* Sanity check the query. */
     if (query_match_count(q) != 0)
 {
     /* Sanity check the query. */
     if (query_match_count(q) != 0)
-        return errSecItemMatchUnsupported;
+        return SecError(errSecItemMatchUnsupported, error, CFSTR("match not supported in attributes to update"));
     if (q->q_ref)
     if (q->q_ref)
-        return errSecValueRefUnsupported;
+        return SecError(errSecValueRefUnsupported, error, CFSTR("value ref not supported in attributes to update"));
     if (q->q_row_id && query_attr_count(q))
     if (q->q_row_id && query_attr_count(q))
-        return errSecItemIllegalQuery;
-
-    int s3e = SQLITE_OK;
+        return SecError(errSecItemIllegalQuery, error, CFSTR("attributes to update illegal; both row_id and other attributes can't be updated at the same time"));
 
 
-    Query *u = query_create(q->q_class, attributesToUpdate, &q->q_error);
-    if (u == NULL) return q->q_error;
-    if (!query_update_parse(u, attributesToUpdate, &q->q_error))
-        goto errOut;
+    __block bool result = true;
+    Query *u = query_create(q->q_class, attributesToUpdate, error);
+    if (u == NULL) return false;
+    require_action_quiet(query_update_parse(u, attributesToUpdate, error), errOut, result = false);
     query_pre_update(u);
     query_pre_update(u);
+    result &= SecDbTransaction(dbt, kSecDbExclusiveTransactionType, error, ^(bool *commit) {
+        // Make sure we only update real items, not tombstones, unless the client explicitly asks otherwise.
+        if (!CFDictionaryContainsKey(q->q_item, kSecAttrTombstone))
+            query_add_attribute(kSecAttrTombstone, kCFBooleanFalse, q);
+        result &= SecDbItemQuery(q, accessGroups, dbt, error, ^(SecDbItemRef item, bool *stop) {
+            //We always need to know the error here.
+            CFErrorRef localError = NULL;
+            SecDbItemRef new_item = SecDbItemCopyWithUpdates(item, u->q_item, &localError);
+            if(SecErrorGetOSStatus(localError)==errSecDecode) {
+                // We just ignore this, and treat as if item is not found
+                secerror("Trying to update to a corrupted item");
+                CFReleaseSafe(localError);
+                return;
+            }
 
 
-       /* Actual work here. */
-       sqlite3 *s3h = dbt->s3_handle;
-
-    CFStringRef sql = s3dl_update_sql(u);
-       sqlite3_stmt *stmt = NULL;
-    s3e = kc_prepare_statement(s3h, sql, &stmt);
-       CFRelease(sql);
-
-    if (s3e == SQLITE_OK)
-        s3e = s3dl_update_bind(u, stmt);
-
-    if (s3e == SQLITE_OK) {
-        s3e = s3dl_begin_transaction(dbt);
-        q->q_return_type = 0;
-        struct s3dl_update_row_ctx ctx = {
-            .qc = {
-                .q = q, .accessGroups = accessGroups,
-            },
-            .u = u,
-            .update_stmt = stmt
-        };
-        u->q_error = s3dl_query(dbt, s3dl_update_row, CURRENT_DB_VERSION, &ctx);
-        s3e = s3dl_end_transaction(dbt, s3e);
-    }
-
-       /* Free the stmt. */
-       if (stmt) {
-               int s3e2 = sqlite3_finalize(stmt);
-               if (s3e2 != SQLITE_OK && s3e == SQLITE_OK)
-                       s3e = s3e2;
-       }
-
+            if (error && *error == NULL) {
+                *error = localError;
+                localError = NULL;
+            }
+            CFReleaseSafe(localError);
+
+            result = new_item;
+            if (new_item) {
+                bool item_is_sync = SecDbItemIsSyncable(item);
+                bool makeTombstone = q->q_use_tomb ? CFBooleanGetValue(q->q_use_tomb) : (item_is_sync && !SecDbItemIsTombstone(item));
+                result = SecDbItemUpdate(item, new_item, dbt, makeTombstone, error);
+                if (result) {
+                    q->q_changed = true;
+                    if (item_is_sync || SecDbItemIsSyncable(new_item))
+                        q->q_sync_changed = true;
+                }
+                CFRelease(new_item);
+            }
+            if (!result)
+                *stop = true;
+        });
+        if (!result)
+            *commit = false;
+    });
+    if (result && !q->q_changed)
+        result = SecError(errSecItemNotFound, error, CFSTR("No items updated"));
 errOut:
 errOut:
-    query_destroy(u, &q->q_error);
-
-       if (s3e) return osstatus_for_s3e(s3e);
-    if (q->q_error) return q->q_error;
-    return 0;
+    if (!query_destroy(u, error))
+        result = false;
+    return result;
 }
 
 }
 
-static OSStatus
-s3dl_query_delete(s3dl_db_thread *dbt, Query *q, CFArrayRef accessGroups)
+static bool
+s3dl_query_delete(SecDbConnectionRef dbt, Query *q, CFArrayRef accessGroups, CFErrorRef *error)
 {
 {
-       sqlite3 *s3h = dbt->s3_handle;
-       sqlite3_stmt *stmt = NULL;
-    CFMutableStringRef sql;
-    int s3e;
-
-    sql = CFStringCreateMutable(NULL, 0);
-    CFStringAppendFormat(sql, NULL, CFSTR("DELETE FROM %@"), q->q_class->name);
-    sqlAppendWhereClause(sql, q, accessGroups);
-    CFStringAppend(sql, CFSTR(";"));
-    s3e = kc_prepare_statement(s3h, sql, &stmt);
-       CFRelease(sql);
-
-       /* Bind the parameters to the DELETE statement. */
-       if (s3e == SQLITE_OK) {
-        int param = 1;
-        s3e = sqlBindWhereClause(stmt, q, accessGroups, &param);
-    }
-
-       /* Now execute the DELETE statement (step). */
-       if (s3e == SQLITE_OK) {
-               s3e = sqlite3_step(stmt);
-               if (s3e == SQLITE_DONE) {
-            int changes = sqlite3_changes(s3h);
-                       /* When doing a delete without a where clause sqlite reports 0
-                          changes since it drops and recreates the table rather than
-                          deleting all the records in it.  */
-            if (changes == 0 && query_attr_count(q) > 0) {
-                s3e = errSecItemNotFound;
-            } else {
-                s3e = SQLITE_OK;
-                               secdebug("sql", "deleted: %d records", changes);
-                       }
-               } else if (s3e != SQLITE_OK) {
-                       secdebug("sql", "delete: %d: %s", s3e, sqlite3_errmsg(s3h));
+    __block bool ok = true;
+    // Only delete things that aren't tombstones, unless the client explicitly asks otherwise.
+    if (!CFDictionaryContainsKey(q->q_item, kSecAttrTombstone))
+        query_add_attribute(kSecAttrTombstone, kCFBooleanFalse, q);
+    ok &= SecDbItemSelect(q, dbt, error, ^bool(const SecDbAttr *attr) {
+        return false;
+    },^bool(CFMutableStringRef sql, bool *needWhere) {
+        SecDbAppendWhereClause(sql, q, accessGroups);
+        return true;
+    },^bool(sqlite3_stmt * stmt, int col) {
+        return sqlBindWhereClause(stmt, q, accessGroups, &col, error);
+    }, ^(SecDbItemRef item, bool *stop) {
+        bool item_is_sync = SecDbItemIsSyncable(item);
+        bool makeTombstone = q->q_use_tomb ? CFBooleanGetValue(q->q_use_tomb) : (item_is_sync && !SecDbItemIsTombstone(item));
+        ok = SecDbItemDelete(item, dbt, makeTombstone, error);
+        if (ok) {
+            q->q_changed = true;
+            if (item_is_sync)
+                q->q_sync_changed = true;
         }
         }
-       }
-
-       /* Free the stmt. */
-       if (stmt) {
-               int s3e2 = sqlite3_finalize(stmt);
-               if (s3e2 != SQLITE_OK && s3e == SQLITE_OK)
-                       s3e = s3e2;
-       }
-
-    return s3e;
+    });
+    if (ok && !q->q_changed) {
+        ok = SecError(errSecItemNotFound, error, CFSTR("Delete failed to delete anything"));
+    }
+    return ok;
 }
 
 /* Return true iff the item in question should not be backed up, nor restored,
    but when restoring a backup the original version of the item should be
    added back to the keychain again after the restore completes. */
 }
 
 /* Return true iff the item in question should not be backed up, nor restored,
    but when restoring a backup the original version of the item should be
    added back to the keychain again after the restore completes. */
-static bool SecItemIsSystemBound(CFDictionaryRef item, const kc_class *class) {
+static bool SecItemIsSystemBound(CFDictionaryRef item, const SecDbClass *class) {
     CFStringRef agrp = CFDictionaryGetValue(item, kSecAttrAccessGroup);
     if (!isString(agrp))
         return false;
     CFStringRef agrp = CFDictionaryGetValue(item, kSecAttrAccessGroup);
     if (!isString(agrp))
         return false;
@@ -3521,124 +2620,31 @@ static bool SecItemIsSystemBound(CFDictionaryRef item, const kc_class *class) {
    place upgrade we don't delete items in the 'lockdown-identities'
    access group, this ensures that an import or restore of a backup
    will never overwrite an existing activation record. */
    place upgrade we don't delete items in the 'lockdown-identities'
    access group, this ensures that an import or restore of a backup
    will never overwrite an existing activation record. */
-static OSStatus SecServerDeleteAll(s3dl_db_thread *dbt) {
-    int s3e = sqlite3_exec(dbt->s3_handle,
-        "DELETE from genp;"
-        "DELETE from inet;"
-        "DELETE FROM cert;"
-        "DELETE FROM keys;",
-        NULL, NULL, NULL);
-    return s3e == SQLITE_OK ? 0 : osstatus_for_s3e(s3e);
+static bool SecServerDeleteAll(SecDbConnectionRef dbt, CFErrorRef *error) {
+    return kc_transaction(dbt, error, ^{
+        bool ok = (SecDbExec(dbt, CFSTR("DELETE from genp;"), error) &&
+                   SecDbExec(dbt, CFSTR("DELETE from inet;"), error) &&
+                   SecDbExec(dbt, CFSTR("DELETE from cert;"), error) &&
+                   SecDbExec(dbt, CFSTR("DELETE from keys;"), error));
+        return ok;
+    });
 }
 
 struct s3dl_export_row_ctx {
     struct s3dl_query_ctx qc;
     keybag_handle_t dest_keybag;
     enum SecItemFilter filter;
 }
 
 struct s3dl_export_row_ctx {
     struct s3dl_query_ctx qc;
     keybag_handle_t dest_keybag;
     enum SecItemFilter filter;
-    int version;
-    s3dl_db_thread *dbt;
+    SecDbConnectionRef dbt;
 };
 
 };
 
-/* Return NULL if the current row isn't a match.  Return kCFNull if the
- current row is a match and q->q_return_type == 0.  Otherwise return
- whatever the caller requested based on the value of q->q_return_type. */
-static CFMutableDictionaryRef
-s3dl_item_from_pre_v5(sqlite3_stmt *stmt, Query *q, s3dl_db_thread *dbt,
-                      keyclass_t *keyclass, sqlite_int64 *rowid) {
-       int cix = 0, cc = sqlite3_column_count(stmt);
-
-    CFMutableDictionaryRef item = CFDictionaryCreateMutable(0, 0,
-        &kCFTypeDictionaryKeyCallBacks, & kCFTypeDictionaryValueCallBacks);
-       for (cix = 0; cix < cc; ++cix) {
-        const char *cname = sqlite3_column_name(stmt, cix);
-        CFStringRef key = NULL;
-        CFTypeRef value = NULL;
-               int ctype = sqlite3_column_type(stmt, cix);
-               switch (ctype) {
-            case SQLITE_INTEGER:
-            {
-                sqlite_int64 i64Value = sqlite3_column_int64(stmt, cix);
-                if (!strcmp(cname, "rowid")) {
-                    *rowid = i64Value;
-                    continue;
-                } else if (i64Value > INT_MAX || i64Value < INT_MIN) {
-                    value = CFNumberCreate(0, kCFNumberLongLongType, &i64Value);
-                } else {
-                    int iValue = (int)i64Value;
-                    value = CFNumberCreate(0, kCFNumberIntType, &iValue);
-                }
-                break;
-            }
-            case SQLITE_FLOAT:
-                value = CFDateCreate(0, sqlite3_column_double(stmt, cix));
-                break;
-            case SQLITE_TEXT:
-                value = CFStringCreateWithCString(0,
-                                                  (const char *)sqlite3_column_text(stmt, cix),
-                                                  kCFStringEncodingUTF8);
-                break;
-            case SQLITE_BLOB:
-                value = CFDataCreate(0, sqlite3_column_blob(stmt, cix),
-                                     sqlite3_column_bytes(stmt, cix));
-                if (value && !strcmp(cname, "data")) {
-                    CFDataRef plain;
-                    if (q->q_keybag == KEYBAG_LEGACY) {
-                        q->q_error = kc_decrypt_data(dbt, value, &plain);
-                    } else {
-                        q->q_error = ks_decrypt_data(q->q_keybag, keyclass,
-                                                     value, &plain, 0);
-                    }
-                    CFRelease(value);
-                    if (q->q_error) {
-                        secerror("failed to decrypt data: %d", q->q_error);
-                        goto out;
-                    }
-                    value = plain;
-                    key = kSecValueData;
-                }
-                break;
-            default:
-                secwarning("Unsupported column type: %d", ctype);
-                /*DROPTHROUGH*/
-            case SQLITE_NULL:
-                /* Don't return NULL valued attributes to the caller. */
-                continue;
-               }
-
-        if (!value)
-            continue;
-
-        if (key) {
-            CFDictionarySetValue(item, key, value);
-        } else {
-            key = CFStringCreateWithCString(0, cname, kCFStringEncodingUTF8);
-            if (key) {
-                CFDictionarySetValue(item, key, value);
-                CFRelease(key);
-            }
-        }
-        CFRelease(value);
-       }
-
-    return item;
-out:
-    CFReleaseSafe(item);
-       return NULL;
-}
-
 static void s3dl_export_row(sqlite3_stmt *stmt, void *context) {
     struct s3dl_export_row_ctx *c = context;
     Query *q = c->qc.q;
     keyclass_t keyclass = 0;
 static void s3dl_export_row(sqlite3_stmt *stmt, void *context) {
     struct s3dl_export_row_ctx *c = context;
     Query *q = c->qc.q;
     keyclass_t keyclass = 0;
+    CFErrorRef localError = NULL;
 
 
-    CFMutableDictionaryRef item;
-    sqlite_int64 rowid = -1;
-    if (c->version < 5) {
-        item = s3dl_item_from_pre_v5(stmt, q, c->dbt, &keyclass, &rowid);
-    } else {
-        item = s3dl_item_from_col(stmt, q, 1, c->qc.accessGroups, &keyclass);
-        rowid = sqlite3_column_int64(stmt, 0);
-    }
+    sqlite_int64 rowid = sqlite3_column_int64(stmt, 0);
+    CFMutableDictionaryRef item = s3dl_item_from_col(stmt, q, 1, c->qc.accessGroups, &keyclass, &localError);
 
     if (item) {
         /* Only export sysbound items is do_sys_bound is true, only export non sysbound items otherwise. */
 
     if (item) {
         /* Only export sysbound items is do_sys_bound is true, only export non sysbound items otherwise. */
@@ -3652,16 +2658,16 @@ static void s3dl_export_row(sqlite3_stmt *stmt, void *context) {
             if (pref) {
                 if (c->dest_keybag != KEYBAG_NONE) {
                     /* Encode and encrypt the item to the specified keybag. */
             if (pref) {
                 if (c->dest_keybag != KEYBAG_NONE) {
                     /* Encode and encrypt the item to the specified keybag. */
-                    CFDataRef plain = CFPropertyListCreateData(0, item, kCFPropertyListBinaryFormat_v1_0, 0, 0);
+                    CFDataRef plain = kc_plist_copy_der(item, &q->q_error);
                     CFDictionaryRemoveAllValues(item);
                     if (plain) {
                         CFDataRef edata = NULL;
                     CFDictionaryRemoveAllValues(item);
                     if (plain) {
                         CFDataRef edata = NULL;
-                        int s3e = ks_encrypt_data(c->dest_keybag, keyclass, plain, &edata);
-                        if (s3e)
-                            q->q_error = osstatus_for_s3e(s3e);
-                        if (edata) {
+                        if (ks_encrypt_data(c->dest_keybag, keyclass, plain, &edata, &q->q_error)) {
                             CFDictionarySetValue(item, kSecValueData, edata);
                             CFDictionarySetValue(item, kSecValueData, edata);
-                            CFRelease(edata);
+                            CFReleaseSafe(edata);
+                        } else {
+                            seccritical("ks_encrypt_data %@,rowid=%" PRId64 ": failed: %@", q->q_class->name, rowid, q->q_error);
+                            CFReleaseNull(q->q_error);
                         }
                         CFRelease(plain);
                     }
                         }
                         CFRelease(plain);
                     }
@@ -3671,23 +2677,33 @@ static void s3dl_export_row(sqlite3_stmt *stmt, void *context) {
                     CFArrayAppendValue((CFMutableArrayRef)c->qc.result, item);
                     c->qc.found++;
                 }
                     CFArrayAppendValue((CFMutableArrayRef)c->qc.result, item);
                     c->qc.found++;
                 }
-                CFRelease(pref);
+                CFReleaseSafe(pref);
             }
         }
         CFRelease(item);
             }
         }
         CFRelease(item);
+    } else {
+        /* This happens a lot when trying to migrate keychain before first unlock, so only a notice */
+        /* If the error is "corrupted item" then we just ignore it, otherwise we save it in the query */
+        secnotice("item","Could not export item for rowid %llu: %@", rowid, localError);
+        if(SecErrorGetOSStatus(localError)==errSecDecode) {
+            CFReleaseNull(localError);
+        } else {
+            CFReleaseSafe(q->q_error);
+            q->q_error=localError;
+        }
     }
 }
 
     }
 }
 
-static CFDictionaryRef SecServerExportKeychainPlist(s3dl_db_thread *dbt,
+static CF_RETURNS_RETAINED CFDictionaryRef SecServerExportKeychainPlist(SecDbConnectionRef dbt,
     keybag_handle_t src_keybag, keybag_handle_t dest_keybag,
     keybag_handle_t src_keybag, keybag_handle_t dest_keybag,
-    enum SecItemFilter filter, int version, OSStatus *error) {
+    enum SecItemFilter filter, CFErrorRef *error) {
     CFMutableDictionaryRef keychain;
     keychain = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
         &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
     if (!keychain) {
         if (error && !*error)
     CFMutableDictionaryRef keychain;
     keychain = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
         &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
     if (!keychain) {
         if (error && !*error)
-            *error = errSecAllocate;
-        goto errOut;
+            SecError(errSecAllocate, error, CFSTR("Can't create keychain dictionary"));
+         goto errOut;
     }
     unsigned class_ix;
     Query q = { .q_keybag = src_keybag };
     }
     unsigned class_ix;
     Query q = { .q_keybag = src_keybag };
@@ -3696,171 +2712,115 @@ static CFDictionaryRef SecServerExportKeychainPlist(s3dl_db_thread *dbt,
     q.q_limit = kSecMatchUnlimited;
 
     /* Get rid of this duplicate. */
     q.q_limit = kSecMatchUnlimited;
 
     /* Get rid of this duplicate. */
-    const kc_class *kc_classes[] = {
+    const SecDbClass *SecDbClasses[] = {
         &genp_class,
         &inet_class,
         &cert_class,
         &keys_class
     };
 
         &genp_class,
         &inet_class,
         &cert_class,
         &keys_class
     };
 
-    for (class_ix = 0; class_ix < sizeof(kc_classes) / sizeof(*kc_classes);
+    for (class_ix = 0; class_ix < array_size(SecDbClasses);
         ++class_ix) {
         ++class_ix) {
-        q.q_class = kc_classes[class_ix];
+        q.q_class = SecDbClasses[class_ix];
         struct s3dl_export_row_ctx ctx = {
             .qc = { .q = &q, },
         struct s3dl_export_row_ctx ctx = {
             .qc = { .q = &q, },
-            .dest_keybag = dest_keybag, .filter = filter, .version = version,
+            .dest_keybag = dest_keybag, .filter = filter,
             .dbt = dbt,
         };
             .dbt = dbt,
         };
-        ctx.qc.result = CFArrayCreateMutable(kCFAllocatorDefault, 0,
-                                             &kCFTypeArrayCallBacks);
-        if (ctx.qc.result) {
-            OSStatus status = s3dl_query(dbt, s3dl_export_row, version, &ctx);
-            if (status == noErr) {
-                if (CFArrayGetCount(ctx.qc.result))
-                    CFDictionaryAddValue(keychain, q.q_class->name, ctx.qc.result);
-                CFRelease(ctx.qc.result);
-            } else if (status != errSecItemNotFound) {
-                if (error && !*error)
-                    *error = status;
-                if (status == errSecInteractionNotAllowed) {
-                    secerror("Device locked during attempted keychain upgrade");
-                    CFReleaseNull(keychain);
-                    break;
+
+        secnotice("item", "exporting class '%@'", q.q_class->name);
+
+        CFErrorRef localError = NULL;
+        if (s3dl_query(dbt, s3dl_export_row, &ctx, &localError)) {
+            if (CFArrayGetCount(ctx.qc.result))
+                CFDictionaryAddValue(keychain, q.q_class->name, ctx.qc.result);
+
+        } else {
+            OSStatus status = (OSStatus)CFErrorGetCode(localError);
+            if (status == errSecItemNotFound) {
+                CFRelease(localError);
+            } else {
+                secerror("Export failed: %@", localError);
+                if (error) {
+                    CFReleaseSafe(*error);
+                    *error = localError;
+                } else {
+                    CFRelease(localError);
                 }
                 }
+                CFReleaseNull(keychain);
+                break;
             }
         }
             }
         }
+        CFReleaseNull(ctx.qc.result);
     }
 errOut:
     return keychain;
 }
 
     }
 errOut:
     return keychain;
 }
 
-static OSStatus SecServerExportKeychain(s3dl_db_thread *dbt,
-    keybag_handle_t src_keybag, keybag_handle_t dest_keybag,
-    CFDataRef *data_out) {
-    OSStatus status = noErr;
+static CF_RETURNS_RETAINED CFDataRef SecServerExportKeychain(SecDbConnectionRef dbt,
+    keybag_handle_t src_keybag, keybag_handle_t dest_keybag, CFErrorRef *error) {
+    CFDataRef data_out = NULL;
     /* Export everything except the items for which SecItemIsSystemBound()
        returns true. */
     CFDictionaryRef keychain = SecServerExportKeychainPlist(dbt,
     /* Export everything except the items for which SecItemIsSystemBound()
        returns true. */
     CFDictionaryRef keychain = SecServerExportKeychainPlist(dbt,
-        src_keybag, dest_keybag, kSecBackupableItemFilter, CURRENT_DB_VERSION,
-        &status);
+        src_keybag, dest_keybag, kSecBackupableItemFilter,
+        error);
     if (keychain) {
     if (keychain) {
-        CFErrorRef error = NULL;
-        *data_out = CFPropertyListCreateData(kCFAllocatorDefault, keychain,
+        data_out = CFPropertyListCreateData(kCFAllocatorDefault, keychain,
                                              kCFPropertyListBinaryFormat_v1_0,
                                              kCFPropertyListBinaryFormat_v1_0,
-                                             0, &error);
+                                             0, error);
         CFRelease(keychain);
         CFRelease(keychain);
-        if (error) {
-            secerror("Error encoding keychain: %@", error);
-            status = (OSStatus)CFErrorGetCode(error); /* possibly truncated error code, whatever */
-            CFRelease(error);
-        }
     }
 
     }
 
-    return status;
+    return data_out;
 }
 
 struct SecServerImportClassState {
 }
 
 struct SecServerImportClassState {
-       s3dl_db_thread *dbt;
-    OSStatus status;
+       SecDbConnectionRef dbt;
+    CFErrorRef error;
     keybag_handle_t src_keybag;
     keybag_handle_t dest_keybag;
     enum SecItemFilter filter;
 };
 
 struct SecServerImportItemState {
     keybag_handle_t src_keybag;
     keybag_handle_t dest_keybag;
     enum SecItemFilter filter;
 };
 
 struct SecServerImportItemState {
-    const kc_class *class;
+    const SecDbClass *class;
        struct SecServerImportClassState *s;
 };
 
        struct SecServerImportClassState *s;
 };
 
-/* Infer a keyclass for 3.x items being imported from a backup.  Return NULL
-   to leave keyclass unchanged. */
-static void SecItemImportInferAccessible(Query *q) {
-    CFStringRef agrp = CFDictionaryGetValue(q->q_item, kSecAttrAccessGroup);
-    CFStringRef accessible = NULL;
-    if (isString(agrp)) {
-        if (CFEqual(agrp, CFSTR("apple"))) {
-            if (q->q_class == &cert_class) {
-                /* apple certs are always dk. */
-                accessible = kSecAttrAccessibleAlways;
-            } else if (q->q_class == &genp_class) {
-                CFStringRef svce = CFDictionaryGetValue(q->q_item, kSecAttrService);
-                if (isString(svce)) {
-                    if (CFEqual(svce, CFSTR("iTools"))) {
-                        /* iTools password is dk for now. */
-                        accessible = kSecAttrAccessibleAlways;
-                    } else if (CFEqual(svce, CFSTR("BackupAgent"))) {
-                        /* We assume that acct == BackupPassword use aku. */
-                        accessible = kSecAttrAccessibleWhenUnlockedThisDeviceOnly;
-                    } else if (CFEqual(svce, CFSTR("MobileBluetooth"))) {
-                        /* MobileBlueTooh uses cku. */
-                        accessible = kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly;
-                    }
-                }
-            } else if (q->q_class == &inet_class) {
-                CFStringRef ptcl = CFDictionaryGetValue(q->q_item, kSecAttrProtocol);
-                if (isString(ptcl)) {
-                    /* LDAP is never needed without UI so ak. */
-                    if (CFEqual(ptcl, kSecAttrProtocolLDAP) ||
-                        CFEqual(ptcl, kSecAttrProtocolLDAPS)) {
-                        accessible = kSecAttrAccessibleWhenUnlocked;
-                    }
-                }
-            }
-            if (accessible == NULL) {
-                /* Everything not covered by a special case in the apple
-                   access group (including keys) ends up in class Ck. */
-                accessible = kSecAttrAccessibleAfterFirstUnlock;
-            }
-        } else if (CFEqual(agrp, CFSTR("com.apple.apsd"))
-                   || CFEqual(agrp, CFSTR("lockdown-identities"))) {
-            /* apsd and lockdown are always dku. */
-            accessible = kSecAttrAccessibleAlwaysThisDeviceOnly;
-        }
-    }
-    if (accessible == NULL) {
-        if (q->q_class == &cert_class) {
-            /* third party certs are always dk. */
-            accessible = kSecAttrAccessibleAlways;
-        } else {
-            /* The rest defaults to ak. */
-            accessible = kSecAttrAccessibleWhenUnlocked;
-        }
-    }
-    query_add_attribute(kSecAttrAccessible, accessible, q);
-}
-
 /* Infer accessibility and access group for pre-v2 (iOS4.x and earlier) items
 /* Infer accessibility and access group for pre-v2 (iOS4.x and earlier) items
-   being imported from a backup.  */
-static void SecItemImportMigrate(Query *q) {
-    CFStringRef agrp = CFDictionaryGetValue(q->q_item, kSecAttrAccessGroup);
-    CFStringRef accessible = CFDictionaryGetValue(q->q_item, kSecAttrAccessible);
+ being imported from a backup.  */
+static bool SecDbItemImportMigrate(SecDbItemRef item, CFErrorRef *error) {
+    bool ok = true;
+    CFStringRef agrp = SecDbItemGetCachedValueWithName(item, kSecAttrAccessGroup);
+    CFStringRef accessible = SecDbItemGetCachedValueWithName(item, kSecAttrAccessible);
 
     if (!isString(agrp) || !isString(accessible))
 
     if (!isString(agrp) || !isString(accessible))
-        return;
-    if (q->q_class == &genp_class && CFEqual(accessible, kSecAttrAccessibleAlways)) {
-        CFStringRef svce = CFDictionaryGetValue(q->q_item, kSecAttrService);
-        if (!isString(svce)) return;
+        return ok;
+    if (SecDbItemGetClass(item) == &genp_class && CFEqual(accessible, kSecAttrAccessibleAlways)) {
+        CFStringRef svce = SecDbItemGetCachedValueWithName(item, kSecAttrService);
+        if (!isString(svce)) return ok;
         if (CFEqual(agrp, CFSTR("apple"))) {
             if (CFEqual(svce, CFSTR("AirPort"))) {
         if (CFEqual(agrp, CFSTR("apple"))) {
             if (CFEqual(svce, CFSTR("AirPort"))) {
-                query_set_attribute(kSecAttrAccessible, kSecAttrAccessibleAfterFirstUnlock, q);
+                ok = SecDbItemSetValueWithName(item, kSecAttrAccessible, kSecAttrAccessibleAfterFirstUnlock, error);
             } else if (CFEqual(svce, CFSTR("com.apple.airplay.password"))) {
             } else if (CFEqual(svce, CFSTR("com.apple.airplay.password"))) {
-                query_set_attribute(kSecAttrAccessible, kSecAttrAccessibleWhenUnlocked, q);
+                ok = SecDbItemSetValueWithName(item, kSecAttrAccessible, kSecAttrAccessibleWhenUnlocked, error);
             } else if (CFEqual(svce, CFSTR("YouTube"))) {
             } else if (CFEqual(svce, CFSTR("YouTube"))) {
-                query_set_attribute(kSecAttrAccessible, kSecAttrAccessibleWhenUnlocked, q);
-                query_set_attribute(kSecAttrAccessGroup, CFSTR("com.apple.youtube.credentials"), q);
+                ok = (SecDbItemSetValueWithName(item, kSecAttrAccessible, kSecAttrAccessibleWhenUnlocked, error) &&
+                      SecDbItemSetValueWithName(item, kSecAttrAccessGroup, CFSTR("com.apple.youtube.credentials"), error));
             } else {
             } else {
-                CFStringRef desc = CFDictionaryGetValue(q->q_item, kSecAttrDescription);
-                if (!isString(desc)) return;
+                CFStringRef desc = SecDbItemGetCachedValueWithName(item, kSecAttrDescription);
+                if (!isString(desc)) return ok;
                 if (CFEqual(desc, CFSTR("IPSec Shared Secret")) || CFEqual(desc, CFSTR("PPP Password"))) {
                 if (CFEqual(desc, CFSTR("IPSec Shared Secret")) || CFEqual(desc, CFSTR("PPP Password"))) {
-                    query_set_attribute(kSecAttrAccessible, kSecAttrAccessibleAfterFirstUnlock, q);
+                    ok = SecDbItemSetValueWithName(item, kSecAttrAccessible, kSecAttrAccessibleAfterFirstUnlock, error);
                 }
             }
         }
                 }
             }
         }
-    } else if (q->q_class == &inet_class && CFEqual(accessible, kSecAttrAccessibleAlways)) {
+    } else if (SecDbItemGetClass(item) == &inet_class && CFEqual(accessible, kSecAttrAccessibleAlways)) {
         if (CFEqual(agrp, CFSTR("PrintKitAccessGroup"))) {
         if (CFEqual(agrp, CFSTR("PrintKitAccessGroup"))) {
-            query_set_attribute(kSecAttrAccessible, kSecAttrAccessibleWhenUnlocked, q);
+            ok = SecDbItemSetValueWithName(item, kSecAttrAccessible, kSecAttrAccessibleWhenUnlocked, error);
         } else if (CFEqual(agrp, CFSTR("apple"))) {
         } else if (CFEqual(agrp, CFSTR("apple"))) {
-            CFTypeRef ptcl = CFDictionaryGetValue(q->q_item, kSecAttrProtocol);
+            CFTypeRef ptcl = SecDbItemGetCachedValueWithName(item, kSecAttrProtocol);
             bool is_proxy = false;
             if (isNumber(ptcl)) {
                 SInt32 iptcl;
             bool is_proxy = false;
             if (isNumber(ptcl)) {
                 SInt32 iptcl;
@@ -3880,136 +2840,181 @@ static void SecItemImportMigrate(Query *q) {
                             CFEqual(ptcl, kSecAttrProtocolFTPProxy));
             }
             if (is_proxy)
                             CFEqual(ptcl, kSecAttrProtocolFTPProxy));
             }
             if (is_proxy)
-                query_set_attribute(kSecAttrAccessible, kSecAttrAccessibleWhenUnlocked, q);
+                ok = SecDbItemSetValueWithName(item, kSecAttrAccessible, kSecAttrAccessibleWhenUnlocked, error);
+        }
+    }
+    return ok;
+}
+
+bool SecDbItemDecrypt(SecDbItemRef item, CFDataRef edata, CFErrorRef *error) {
+    bool ok = true;
+    CFDataRef pdata = NULL;
+    keyclass_t keyclass;
+    uint32_t version;
+    ok = ks_decrypt_data(SecDbItemGetKeybag(item), &keyclass, edata, &pdata, &version, error);
+    if (!ok)
+        return ok;
+
+    if (version < 2) {
+        /* Old V4 style keychain backup being imported. */
+        ok = SecDbItemSetValueWithName(item, CFSTR("v_Data"), pdata, error) &&
+        SecDbItemImportMigrate(item, error);
+    } else {
+        CFDictionaryRef dict;
+        if (version < 3) {
+            dict = s3dl_item_v2_decode(pdata, error);
+        } else {
+            dict = s3dl_item_v3_decode(pdata, error);
+        }
+        ok = dict && SecDbItemSetValues(item, dict, error);
+       CFReleaseSafe(dict);
+    }
+
+    CFReleaseSafe(pdata);
+
+    keyclass_t my_keyclass = SecDbItemGetKeyclass(item, NULL);
+    if (!my_keyclass) {
+        ok = ok && SecDbItemSetKeyclass(item, keyclass, error);
+    } else {
+        /* Make sure the keyclass in the dictionary matched what we got
+           back from decoding the data blob. */
+        if (my_keyclass != keyclass) {
+            ok = SecError(errSecDecode, error, CFSTR("keyclass attribute %d doesn't match keyclass in blob %d"), my_keyclass, keyclass);
         }
     }
         }
     }
+
+    return ok;
+}
+
+/* Automagically make a item syncable, based on various attributes. */
+static bool SecDbItemInferSyncable(SecDbItemRef item, CFErrorRef *error)
+{
+    CFStringRef agrp = SecDbItemGetCachedValueWithName(item, kSecAttrAccessGroup);
+
+    if (!isString(agrp))
+        return true;
+
+    if (CFEqual(agrp, CFSTR("com.apple.cfnetwork")) && SecDbItemGetClass(item) == &inet_class) {
+        CFTypeRef srvr = SecDbItemGetCachedValueWithName(item, kSecAttrServer);
+        CFTypeRef ptcl = SecDbItemGetCachedValueWithName(item, kSecAttrProtocol);
+        CFTypeRef atyp = SecDbItemGetCachedValueWithName(item, kSecAttrAuthenticationType);
+
+        if (isString(srvr) && isString(ptcl) && isString(atyp)) {
+            /* This looks like a Mobile Safari Password,  make syncable */
+            secnotice("item", "Make this item syncable: %@", item);
+            return SecDbItemSetSyncable(item, true, error);
+        }
+    }
+
+    return true;
+}
+
+/* This create a SecDbItem from the item dictionnary that are exported for backups.
+   Item are stored in the backup as a dictionary containing two keys:
+    - v_Data: the encrypted data blob
+    - v_PersistentRef: a persistent Ref.
+   src_keybag is normally the backup keybag.
+   dst_keybag is normally the device keybag.
+*/
+static SecDbItemRef SecDbItemCreateWithBackupDictionary(CFAllocatorRef allocator, const SecDbClass *dbclass, CFDictionaryRef dict, keybag_handle_t src_keybag, keybag_handle_t dst_keybag, CFErrorRef *error)
+{
+    CFDataRef edata = CFDictionaryGetValue(dict, CFSTR("v_Data"));
+    SecDbItemRef item = NULL;
+
+    if (edata) {
+        item = SecDbItemCreateWithEncryptedData(kCFAllocatorDefault, dbclass, edata, src_keybag, error);
+        if (item)
+            if (!SecDbItemSetKeybag(item, dst_keybag, error))
+                CFReleaseNull(item);
+    } else {
+        SecError(errSecDecode, error, CFSTR("No v_Data in backup dictionary %@"), dict);
+    }
+
+    return item;
+}
+
+static bool SecDbItemExtractRowIdFromBackupDictionary(SecDbItemRef item, CFDictionaryRef dict, CFErrorRef *error) {
+    CFDataRef ref = CFDictionaryGetValue(dict, CFSTR("v_PersistentRef"));
+    if (!ref)
+        return SecError(errSecDecode, error, CFSTR("No v_PersistentRef in backup dictionary %@"), dict);
+
+    CFStringRef className;
+    sqlite3_int64 rowid;
+    if (!_SecItemParsePersistentRef(ref, &className, &rowid))
+        return SecError(errSecDecode, error, CFSTR("v_PersistentRef %@ failed to decode"), ref);
+
+    if (!CFEqual(SecDbItemGetClass(item)->name, className))
+        return SecError(errSecDecode, error, CFSTR("v_PersistentRef has unexpected class %@"), className);
+
+    return SecDbItemSetRowId(item, rowid, error);
 }
 
 static void SecServerImportItem(const void *value, void *context) {
     struct SecServerImportItemState *state =
         (struct SecServerImportItemState *)context;
 }
 
 static void SecServerImportItem(const void *value, void *context) {
     struct SecServerImportItemState *state =
         (struct SecServerImportItemState *)context;
-    if (state->s->status)
+    if (state->s->error)
         return;
     if (!isDictionary(value)) {
         return;
     if (!isDictionary(value)) {
-        state->s->status = errSecParam;
+        SecError(errSecParam, &state->s->error, CFSTR("value %@ is not a dictionary"), value);
         return;
     }
 
         return;
     }
 
-    CFDictionaryRef item = (CFDictionaryRef)value;
+    CFDictionaryRef dict = (CFDictionaryRef)value;
+
+    secdebug("item", "Import Item : %@", dict);
 
     /* We don't filter non sys_bound items during import since we know we
        will never have any in this case, we use the kSecSysBoundItemFilter
        to indicate that we don't preserve rowid's during import instead. */
     if (state->s->filter == kSecBackupableItemFilter &&
 
     /* We don't filter non sys_bound items during import since we know we
        will never have any in this case, we use the kSecSysBoundItemFilter
        to indicate that we don't preserve rowid's during import instead. */
     if (state->s->filter == kSecBackupableItemFilter &&
-        SecItemIsSystemBound(item, state->class))
+        SecItemIsSystemBound(dict, state->class))
         return;
 
         return;
 
-    Query *q = query_create(state->class, item, &state->s->status);
-    if (!q)
-        return;
-
-    /* TODO: We'd like to use query_update_applier here instead of
-       query_parse(), since only attrs, kSecValueData and kSecValuePersistentRef. */
-    query_parse(q, item, &state->s->status);
+    SecDbItemRef item;
 
 
-    CFDataRef pdata = NULL;
+    /* This is sligthly confusing:
+       - During upgrade all items are exported with KEYBAG_NONE.
+       - During restore from backup, existing sys_bound items are exported with KEYBAG_NONE, and are exported as dictionary of attributes.
+       - Item in the actual backup are export with a real keybag, and are exported as encrypted v_Data and v_PersistentRef
+    */
     if (state->s->src_keybag == KEYBAG_NONE) {
     if (state->s->src_keybag == KEYBAG_NONE) {
-        /* Not strictly needed if we are restoring from cleartext db that is
-           version 5 or later, but currently that never happens.  Also the
-           migrate code should be specific enough that it's still safe even
-           in that case, it's just slower. */
-        SecItemImportMigrate(q);
+        item = SecDbItemCreateWithAttributes(kCFAllocatorDefault, state->class, dict, state->s->dest_keybag,  &state->s->error);
     } else {
     } else {
-        if (q->q_data) {
-            keyclass_t keyclass;
-            /* Decrypt the data using state->s->dest_keybag. */
-            uint32_t version;
-            q->q_error = ks_decrypt_data(state->s->src_keybag,
-                &keyclass, q->q_data, &pdata, &version);
-            if (q->q_error) {
-                /* keyclass attribute doesn't match decoded value, fail. */
-                q->q_error = errSecDecode;
-                asl_log(NULL, NULL, ASL_LEVEL_ERR,
-                    "keyclass attribute %d doesn't match keyclass in blob %d",
-                    q->q_keyclass, keyclass);
-            }
-            if (version < 2) {
-                /* Old V4 style keychain backup being imported. */
-                /* Make sure the keyclass in the dictionary matched what we got
-                   back from decoding the data blob. */
-                if (q->q_keyclass && q->q_keyclass != keyclass) {
-                    q->q_error = errSecDecode;
-                    asl_log(NULL, NULL, ASL_LEVEL_ERR,
-                            "keyclass attribute %d doesn't match keyclass in blob %d",
-                            q->q_keyclass, keyclass);
-                } else {
-                    query_set_data(pdata, q);
-                    SecItemImportMigrate(q);
-                }
-            } else {
-                /* version 2 or later backup. */
-                CFErrorRef error = NULL;
-                CFPropertyListFormat format;
-                item = CFPropertyListCreateWithData(0, pdata, kCFPropertyListImmutable, &format, &error);
-                if (item) {
-                    query_update_parse(q, item, &state->s->status);
-                    secdebug("item", "importing status: %ld %@",
-                             state->s->status, item);
-                    CFRelease(item);
-                } else if (error) {
-                    secerror("failed to decode v%d item data: %@",
-                             version, error);
-                    CFRelease(error);
-                }
-            }
-        }
+        item = SecDbItemCreateWithBackupDictionary(kCFAllocatorDefault, state->class, dict, state->s->src_keybag, state->s->dest_keybag, &state->s->error);
     }
 
     }
 
-    if (q->q_keyclass == 0)
-        SecItemImportInferAccessible(q);
-
-    if (q->q_error) {
-        state->s->status = q->q_error;
-    } else {
-        if (q->q_keyclass == 0) {
-            state->s->status = errSecParam;
-        } else {
-            if (state->s->filter == kSecSysBoundItemFilter) {
-                /* We don't set the rowid of sys_bound items we reimport
-                   after an import since that might fail if an item in the
-                   restored keychain already used that rowid. */
-                q->q_row_id = 0;
-            }
-            query_pre_add(q, false);
-            state->s->status = s3dl_query_add(state->s->dbt, q, NULL);
+    if (item) {
+        if(state->s->filter != kSecSysBoundItemFilter) {
+            SecDbItemExtractRowIdFromBackupDictionary(item, dict, &state->s->error);
         }
         }
+        SecDbItemInferSyncable(item, &state->s->error);
+        SecDbItemInsert(item, state->s->dbt, &state->s->error);
     }
     }
-    CFReleaseSafe(pdata);
-    query_destroy(q, &state->s->status);
 
     /* Reset error if we had one, since we just skip the current item
        and continue importing what we can. */
 
     /* Reset error if we had one, since we just skip the current item
        and continue importing what we can. */
-    if (state->s->status) {
-        secerror("Failed to import %@ item %ld ignoring error",
-                 state->class->name, state->s->status);
-        state->s->status = 0;
+    if (state->s->error) {
+        secwarning("Failed to import an item (%@) of class '%@': %@ - ignoring error.",
+                 item, state->class->name, state->s->error);
+        CFReleaseNull(state->s->error);
     }
     }
+
+    CFReleaseSafe(item);
 }
 
 static void SecServerImportClass(const void *key, const void *value,
     void *context) {
     struct SecServerImportClassState *state =
         (struct SecServerImportClassState *)context;
 }
 
 static void SecServerImportClass(const void *key, const void *value,
     void *context) {
     struct SecServerImportClassState *state =
         (struct SecServerImportClassState *)context;
-    if (state->status)
+    if (state->error)
         return;
     if (!isString(key)) {
         return;
     if (!isString(key)) {
-        state->status = errSecParam;
+        SecError(errSecParam, &state->error, CFSTR("class name %@ is not a string"), key);
         return;
     }
         return;
     }
-    const void *desc = CFDictionaryGetValue(gClasses, key);
-    const kc_class *class = desc;
+    const SecDbClass *class = kc_class_with_name(key);
     if (!class || class == &identity_class) {
     if (!class || class == &identity_class) {
-        state->status = errSecParam;
+        SecError(errSecParam, &state->error, CFSTR("attempt to import an identity"));
         return;
     }
     struct SecServerImportItemState item_state = {
         return;
     }
     struct SecServerImportItemState item_state = {
@@ -4025,28 +3030,28 @@ static void SecServerImportClass(const void *key, const void *value,
     }
 }
 
     }
 }
 
-static OSStatus SecServerImportKeychainInPlist(s3dl_db_thread *dbt,
+static bool SecServerImportKeychainInPlist(SecDbConnectionRef dbt,
     keybag_handle_t src_keybag, keybag_handle_t dest_keybag,
     keybag_handle_t src_keybag, keybag_handle_t dest_keybag,
-    CFDictionaryRef keychain, enum SecItemFilter filter) {
-    OSStatus status = errSecSuccess;
+    CFDictionaryRef keychain, enum SecItemFilter filter, CFErrorRef *error) {
+    bool ok = true;
 
     CFDictionaryRef sys_bound = NULL;
     if (filter == kSecBackupableItemFilter) {
         /* Grab a copy of all the items for which SecItemIsSystemBound()
            returns true. */
         require(sys_bound = SecServerExportKeychainPlist(dbt, KEYBAG_DEVICE,
 
     CFDictionaryRef sys_bound = NULL;
     if (filter == kSecBackupableItemFilter) {
         /* Grab a copy of all the items for which SecItemIsSystemBound()
            returns true. */
         require(sys_bound = SecServerExportKeychainPlist(dbt, KEYBAG_DEVICE,
-            KEYBAG_NONE, kSecSysBoundItemFilter, CURRENT_DB_VERSION,
-            &status), errOut);
+                                                         KEYBAG_NONE, kSecSysBoundItemFilter,
+                                                         error), errOut);
     }
 
     /* Delete everything in the keychain. */
     }
 
     /* Delete everything in the keychain. */
-    require_noerr(status = SecServerDeleteAll(dbt), errOut);
+    require(ok = SecServerDeleteAll(dbt, error), errOut);
 
     struct SecServerImportClassState state = {
         .dbt = dbt,
         .src_keybag = src_keybag,
         .dest_keybag = dest_keybag,
 
     struct SecServerImportClassState state = {
         .dbt = dbt,
         .src_keybag = src_keybag,
         .dest_keybag = dest_keybag,
-        .filter = filter
+        .filter = filter,
     };
     /* Import the provided items, preserving rowids. */
     CFDictionaryApplyFunction(keychain, SecServerImportClass, &state);
     };
     /* Import the provided items, preserving rowids. */
     CFDictionaryApplyFunction(keychain, SecServerImportClass, &state);
@@ -4058,323 +3063,314 @@ static OSStatus SecServerImportKeychainInPlist(s3dl_db_thread *dbt,
         CFDictionaryApplyFunction(sys_bound, SecServerImportClass, &state);
         CFRelease(sys_bound);
     }
         CFDictionaryApplyFunction(sys_bound, SecServerImportClass, &state);
         CFRelease(sys_bound);
     }
-    status = state.status;
+    if (state.error) {
+        if (error) {
+            CFReleaseSafe(*error);
+            *error = state.error;
+        } else {
+            CFRelease(state.error);
+        }
+        ok = false;
+    }
 
 errOut:
 
 errOut:
-    return status;
+    return ok;
 }
 
 }
 
-static OSStatus SecServerImportKeychain(s3dl_db_thread *dbt,
+static bool SecServerImportKeychain(SecDbConnectionRef dbt,
     keybag_handle_t src_keybag,
     keybag_handle_t src_keybag,
-    keybag_handle_t dest_keybag, CFDataRef data) {
-    int s3e = s3dl_begin_transaction(dbt);
-    OSStatus status = errSecSuccess;
-    if (s3e != SQLITE_OK) {
-        status = osstatus_for_s3e(s3e);
-    } else {
+    keybag_handle_t dest_keybag, CFDataRef data, CFErrorRef *error) {
+    return kc_transaction(dbt, error, ^{
+        bool ok = false;
         CFDictionaryRef keychain;
         CFDictionaryRef keychain;
-        CFPropertyListFormat format;
-        CFErrorRef error = NULL;
         keychain = CFPropertyListCreateWithData(kCFAllocatorDefault, data,
         keychain = CFPropertyListCreateWithData(kCFAllocatorDefault, data,
-                                             kCFPropertyListImmutable, &format,
-                                             &error);
+                                                kCFPropertyListImmutable, NULL,
+                                                error);
         if (keychain) {
             if (isDictionary(keychain)) {
         if (keychain) {
             if (isDictionary(keychain)) {
-                status = SecServerImportKeychainInPlist(dbt, src_keybag,
-                                                        dest_keybag, keychain,
-                                                        kSecBackupableItemFilter);
+                ok = SecServerImportKeychainInPlist(dbt, src_keybag,
+                                                    dest_keybag, keychain,
+                                                    kSecBackupableItemFilter,
+                                                    error);
             } else {
             } else {
-                status = errSecParam;
+                ok = SecError(errSecParam, error, CFSTR("import: keychain is not a dictionary"));
             }
             CFRelease(keychain);
             }
             CFRelease(keychain);
-        } else {
-            secerror("Error decoding keychain: %@", error);
-            status = (OSStatus)CFErrorGetCode(error); /* possibly truncated error code, whatever */
-            CFRelease(error);
         }
         }
-    }
-
-    s3e = s3dl_end_transaction(dbt, status);
-    return status ? status : osstatus_for_s3e(s3e);
+        return ok;
+    });
 }
 
 }
 
-static OSStatus
-SecServerMigrateKeychain(s3dl_db_thread *dbt,
-    int32_t handle_in, CFDataRef data_in,
-    int32_t *handle_out, CFDataRef *data_out) {
-    OSStatus status;
-
-    if (handle_in == kSecMigrateKeychainImport) {
-        if (data_in == NULL) {
-            return errSecParam;
-        }
-        /* Import data_in. */
-        status = SecServerImportKeychain(dbt, KEYBAG_NONE, KEYBAG_DEVICE, data_in);
-        *data_out = NULL;
-        *handle_out = 0;
-    } else if (handle_in == kSecMigrateKeychainExport) {
-        if (data_in != NULL) {
-            return errSecParam;
-        }
-        /* Export the keychain and return the result in data_out. */
-        status = SecServerExportKeychain(dbt, KEYBAG_DEVICE, KEYBAG_NONE, data_out);
-        *handle_out = 0;
-    } else {
-        status = errSecParam;
-    }
-
-    return status;
-}
-
-static keybag_handle_t ks_open_keybag(CFDataRef keybag, CFDataRef password) {
+static bool ks_open_keybag(CFDataRef keybag, CFDataRef password, keybag_handle_t *handle, CFErrorRef *error) {
 #if USE_KEYSTORE
 #if USE_KEYSTORE
-    uint64_t outputs[] = { KEYBAG_NONE };
-    uint32_t num_outputs = sizeof(outputs) / sizeof(*outputs);
-    IOReturn kernResult;
+    kern_return_t kernResult;
+    kernResult = aks_load_bag(CFDataGetBytePtr(keybag), (int)CFDataGetLength(keybag), handle);
+    if (kernResult)
+        return SecKernError(kernResult, error, CFSTR("aks_load_bag failed: %@"), keybag);
 
 
-    kernResult = IOConnectCallMethod(keystore,
-        kAppleKeyStoreKeyBagCreateWithData, NULL, 0, CFDataGetBytePtr(keybag),
-        CFDataGetLength(keybag), outputs, &num_outputs, NULL, 0);
-    if (kernResult) {
-        asl_log(NULL, NULL, ASL_LEVEL_ERR,
-            "kAppleKeyStoreKeyBagCreateWithData: %x", kernResult);
-        goto errOut;
-    }
     if (password) {
     if (password) {
-        kernResult = IOConnectCallMethod(keystore, kAppleKeyStoreKeyBagUnlock,
-            outputs, 1, CFDataGetBytePtr(password), CFDataGetLength(password),
-            NULL, 0, NULL, NULL);
+        kernResult = aks_unlock_bag(*handle, CFDataGetBytePtr(password), (int)CFDataGetLength(password));
         if (kernResult) {
         if (kernResult) {
-            asl_log(NULL, NULL, ASL_LEVEL_ERR,
-                "kAppleKeyStoreKeyBagCreateWithData: %x", kernResult);
-            goto errOut;
+            aks_unload_bag(*handle);
+            return SecKernError(kernResult, error, CFSTR("aks_unlock_bag failed"));
         }
     }
         }
     }
-    return (keybag_handle_t)outputs[0];
-errOut:
-    return -3;
-#else
-    return KEYBAG_NONE;
-#endif
+    return true;
+#else /* !USE_KEYSTORE */
+    *handle = KEYBAG_NONE;
+    return true;
+#endif /* USE_KEYSTORE */
 }
 
 }
 
-static void ks_close_keybag(keybag_handle_t keybag) {
+static bool ks_close_keybag(keybag_handle_t keybag, CFErrorRef *error) {
 #if USE_KEYSTORE
 #if USE_KEYSTORE
-    uint64_t inputs[] = { keybag };
-       IOReturn kernResult = IOConnectCallMethod(keystore,
-        kAppleKeyStoreKeyBagRelease, inputs, 1, NULL, 0, NULL, NULL, NULL, 0);
+       IOReturn kernResult = aks_unload_bag(keybag);
     if (kernResult) {
     if (kernResult) {
-        asl_log(NULL, NULL, ASL_LEVEL_ERR,
-            "kAppleKeyStoreKeyBagRelease: %d: %x", keybag, kernResult);
+        return SecKernError(kernResult, error, CFSTR("aks_unload_bag failed"));
     }
     }
-#endif
+#endif /* USE_KEYSTORE */
+    return true;
 }
 
 }
 
-static OSStatus SecServerKeychainBackup(s3dl_db_thread *dbt, CFDataRef keybag,
-    CFDataRef password, CFDataRef *backup) {
-    OSStatus status;
-    keybag_handle_t backup_keybag = ks_open_keybag(keybag, password);
-    /* Export from system keybag to backup keybag. */
-    status = SecServerExportKeychain(dbt, KEYBAG_DEVICE, backup_keybag,
-        backup);
-    ks_close_keybag(backup_keybag);
-    return status;
+static CF_RETURNS_RETAINED CFDataRef SecServerKeychainBackup(SecDbConnectionRef dbt, CFDataRef keybag,
+    CFDataRef password, CFErrorRef *error) {
+    CFDataRef backup = NULL;
+    keybag_handle_t backup_keybag;
+    if (ks_open_keybag(keybag, password, &backup_keybag, error)) {
+        /* Export from system keybag to backup keybag. */
+        backup = SecServerExportKeychain(dbt, KEYBAG_DEVICE, backup_keybag, error);
+        if (!ks_close_keybag(backup_keybag, error)) {
+            CFReleaseNull(backup);
+        }
+    }
+    return backup;
 }
 
 }
 
-static OSStatus SecServerKeychainRestore(s3dl_db_thread *dbt, CFDataRef backup,
-    CFDataRef keybag, CFDataRef password) {
-    OSStatus status;
-    keybag_handle_t backup_keybag = ks_open_keybag(keybag, password);
+static bool SecServerKeychainRestore(SecDbConnectionRef dbt, CFDataRef backup,
+    CFDataRef keybag, CFDataRef password, CFErrorRef *error) {
+    keybag_handle_t backup_keybag;
+    if (!ks_open_keybag(keybag, password, &backup_keybag, error))
+        return false;
+
     /* Import from backup keybag to system keybag. */
     /* Import from backup keybag to system keybag. */
-    status = SecServerImportKeychain(dbt, backup_keybag, KEYBAG_DEVICE,
-        backup);
-    ks_close_keybag(backup_keybag);
-    return status;
+    bool ok = SecServerImportKeychain(dbt, backup_keybag, KEYBAG_DEVICE,
+                                      backup, error);
+    ok &= ks_close_keybag(backup_keybag, error);
+
+    return ok;
 }
 
 }
 
-/* External SPI support code. */
 
 
-/* Pthread_once protecting the kc_dbhandle and the singleton kc_dbhandle. */
-static pthread_once_t kc_dbhandle_init_once = PTHREAD_ONCE_INIT;
-static db_handle kc_dbhandle = NULL;
+// MARK - External SPI support code.
 
 
-/* This function is called only once and should initialize kc_dbhandle. */
-static void kc_dbhandle_init(void)
-{
-#if 0
-    CFTypeRef kc_attributes[] = {
-        kSecAttrAccessible,
-        kSecAttrAccessGroup,
-        kSecAttrCreationDate,
-        kSecAttrModificationDate,
-        kSecAttrDescription,
-        kSecAttrComment,
-        kSecAttrCreator,
-        kSecAttrType,
-        kSecAttrLabel,
-        kSecAttrIsInvisible,
-        kSecAttrIsNegative,
-        kSecAttrAccount,
-        kSecAttrService,
-        kSecAttrGeneric,
-        kSecAttrSecurityDomain,
-        kSecAttrServer,
-        kSecAttrProtocol,
-        kSecAttrAuthenticationType,
-        kSecAttrPort,
-        kSecAttrPath,
-        kSecAttrSubject,
-        kSecAttrIssuer,
-        kSecAttrSerialNumber,
-        kSecAttrSubjectKeyID,
-        kSecAttrPublicKeyHash,
-        kSecAttrCertificateType,
-        kSecAttrCertificateEncoding,
-        kSecAttrKeyClass,
-        kSecAttrApplicationLabel,
-        kSecAttrIsPermanent,
-        kSecAttrApplicationTag,
-        kSecAttrKeyType,
-        kSecAttrKeySizeInBits,
-        kSecAttrEffectiveKeySize,
-        kSecAttrCanEncrypt,
-        kSecAttrCanDecrypt,
-        kSecAttrCanDerive,
-        kSecAttrCanSign,
-        kSecAttrCanVerify,
-        kSecAttrCanWrap,
-        kSecAttrCanUnwrap,
-        kSecAttrScriptCode,
-        kSecAttrAlias,
-        kSecAttrHasCustomIcon,
-        kSecAttrVolume,
-        kSecAttrAddress,
-        kSecAttrAFPServerSignature,
-        kSecAttrCRLType,
-        kSecAttrCRLEncoding,
-        kSecAttrKeyCreator,
-        kSecAttrIsPrivate,
-        kSecAttrIsModifiable,
-        kSecAttrStartDate,
-        kSecAttrEndDate,
-        kSecAttrIsSensitive,
-        kSecAttrWasAlwaysSensitive,
-        kSecAttrIsExtractable,
-        kSecAttrWasNeverExtractable,
-        kSecAttrCanSignRecover,
-        kSecAttrCanVerifyRecover
-    };
-#endif
-    CFTypeRef kc_class_names[] = {
-        kSecClassGenericPassword,
-        kSecClassInternetPassword,
-        kSecClassCertificate,
-        kSecClassKey,
-        kSecClassIdentity
-    };
-    const void *kc_classes[] = {
-        &genp_class,
-        &inet_class,
-        &cert_class,
-        &keys_class,
-        &identity_class
-    };
+CFStringRef __SecKeychainCopyPath(void) {
+    CFStringRef kcRelPath = NULL;
+    if (use_hwaes()) {
+        kcRelPath = CFSTR("keychain-2.db");
+    } else {
+        kcRelPath = CFSTR("keychain-2-debug.db");
+    }
 
 
-#if 0
-    gAttributes = CFSetCreate(kCFAllocatorDefault, kc_attributes,
-        sizeof(kc_attributes) / sizeof(*kc_attributes), &kCFTypeSetCallBacks);
-#endif
-    gClasses = CFDictionaryCreate(kCFAllocatorDefault, kc_class_names,
-                                  kc_classes,
-                                  sizeof(kc_classes) / sizeof(*kc_classes),
-                                  &kCFTypeDictionaryKeyCallBacks, 0);
+    CFStringRef kcPath = NULL;
+    CFURLRef kcURL = SecCopyURLForFileInKeychainDirectory(kcRelPath);
+    if (kcURL) {
+        kcPath = CFURLCopyFileSystemPath(kcURL, kCFURLPOSIXPathStyle);
+        CFRelease(kcURL);
+    }
+    return kcPath;
 
 
-       const char *kcRelPath;
+}
 
 
-       bool use_hwaes = hwaes_key_available();
-       if (use_hwaes) {
-               asl_log(NULL, NULL, ASL_LEVEL_INFO, "using hwaes key");
-               kcRelPath = "/Library/Keychains/keychain-2.db";
-       } else {
-               asl_log(NULL, NULL, ASL_LEVEL_ERR, "unable to access hwaes key");
-               kcRelPath = "/Library/Keychains/keychain-2-debug.db";
-       }
+// MARK; -
+// MARK: kc_dbhandle init and reset
 
 
-       bool autocommit = true;
-       bool create = true;
+static SecDbRef SecKeychainDbCreate(CFStringRef path) {
+    return SecDbCreate(path, ^bool (SecDbConnectionRef dbconn, bool didCreate, CFErrorRef *localError) {
+        bool ok;
+        if (didCreate)
+            ok = s3dl_dbt_upgrade_from_version(dbconn, 0, localError);
+        else
+            ok = s3dl_dbt_upgrade(dbconn, localError);
 
 
-#if NO_SERVER
-        /* Added this block of code back to keep the tests happy for now. */
-       const char *home = getenv("HOME");
-       char path[PATH_MAX];
-       size_t homeLen = strlen(home);
-       size_t kcRelPathLen = strlen(kcRelPath);
-        if (homeLen + kcRelPathLen > sizeof(path))
-            return;
-        strlcpy(path, home, sizeof(path));
-        strlcat(path, kcRelPath, sizeof(path));
-        kcRelPath = path;
-#endif
-       s3dl_create_db_handle(kcRelPath, &kc_dbhandle, NULL /* dbt */, autocommit,
-               create, use_hwaes);
+        if (!ok)
+            secerror("Upgrade %sfailed: %@", didCreate ? "from v0 " : "", localError ? *localError : NULL);
+
+        return ok;
+    });
+}
+
+static SecDbRef _kc_dbhandle = NULL;
+
+static void kc_dbhandle_init(void) {
+    SecDbRef oldHandle = _kc_dbhandle;
+    _kc_dbhandle = NULL;
+    CFStringRef dbPath = __SecKeychainCopyPath();
+    if (dbPath) {
+        _kc_dbhandle = SecKeychainDbCreate(dbPath);
+        CFRelease(dbPath);
+    }
+    if (oldHandle) {
+        secerror("replaced %@ with %@", oldHandle, _kc_dbhandle);
+        CFRelease(oldHandle);
+    }
 }
 
 }
 
-#if NO_SERVER
+static dispatch_once_t _kc_dbhandle_once;
+
+static SecDbRef kc_dbhandle(void) {
+    dispatch_once(&_kc_dbhandle_once, ^{
+        kc_dbhandle_init();
+    });
+    return _kc_dbhandle;
+}
+
+/* For whitebox testing only */
 void kc_dbhandle_reset(void);
 void kc_dbhandle_reset(void)
 {
 void kc_dbhandle_reset(void);
 void kc_dbhandle_reset(void)
 {
-    s3dl_close_db_handle(kc_dbhandle);
-    kc_dbhandle_init();
+    __block bool done = false;
+    dispatch_once(&_kc_dbhandle_once, ^{
+        kc_dbhandle_init();
+        done = true;
+    });
+    // TODO: Not thread safe at all! - FOR DEBUGGING ONLY
+    if (!done)
+        kc_dbhandle_init();
 }
 }
-#endif
 
 
+static SecDbConnectionRef kc_aquire_dbt(bool writeAndRead, CFErrorRef *error) {
+    return SecDbConnectionAquire(kc_dbhandle(), !writeAndRead, error);
+}
 
 /* Return a per thread dbt handle for the keychain.  If create is true create
 
 /* Return a per thread dbt handle for the keychain.  If create is true create
  the database if it does not yet exist.  If it is false, just return an
  error if it fails to auto-create. */
-static int kc_get_dbt(s3dl_db_thread **dbt, bool create)
+ the database if it does not yet exist.  If it is false, just return an
+ error if it fails to auto-create. */
+static bool kc_with_dbt(bool writeAndRead, CFErrorRef *error, bool (^perform)(SecDbConnectionRef dbt))
 {
 {
-    return s3dl_get_dbt(kc_dbhandle, dbt);
+    bool ok = false;
+    SecDbConnectionRef dbt = kc_aquire_dbt(writeAndRead, error);
+    if (dbt) {
+        ok = perform(dbt);
+        SecDbConnectionRelease(dbt);
+    }
+    return ok;
 }
 
 }
 
-static int kc_release_dbt(s3dl_db_thread *dbt)
+static bool
+items_matching_issuer_parent(CFArrayRef accessGroups,
+                            CFDataRef issuer, CFArrayRef issuers, int recurse)
 {
 {
-#if CLOSE_DB
-       s3dl_dbt_destructor(dbt);
-       pthread_setspecific(dbt->db->key, NULL);
-       //int s3e = s3dl_close_db_handle(dbt->db);
-       //return s3e;
-#endif
-       return SQLITE_OK;
+    Query *q;
+    CFArrayRef results = NULL;
+    SecDbConnectionRef dbt = NULL;
+    CFIndex i, count;
+    bool found = false;
+
+    if (CFArrayContainsValue(issuers, CFRangeMake(0, CFArrayGetCount(issuers)), issuer))
+        return true;
+
+    const void *keys[] = { kSecClass, kSecReturnRef, kSecAttrSubject };
+    const void *vals[] = { kSecClassCertificate, kCFBooleanTrue, issuer };
+    CFDictionaryRef query = CFDictionaryCreate(kCFAllocatorDefault, keys, vals, array_size(keys), NULL, NULL);
+
+    if (!query)
+        return false;
+
+    CFErrorRef localError = NULL;
+    q = query_create_with_limit(query, kSecMatchUnlimited, &localError);
+    CFRelease(query);
+    if (q) {
+        if ((dbt = SecDbConnectionAquire(kc_dbhandle(), true, &localError))) {
+            s3dl_copy_matching(dbt, q, (CFTypeRef*)&results, accessGroups, &localError);
+            SecDbConnectionRelease(dbt);
+        }
+        query_destroy(q, &localError);
+    }
+    if (localError) {
+        secerror("items matching issuer parent: %@", localError);
+        CFReleaseNull(localError);
+        return false;
+    }
+
+    count = CFArrayGetCount(results);
+    for (i = 0; (i < count) && !found; i++) {
+        CFDictionaryRef cert_dict = (CFDictionaryRef)CFArrayGetValueAtIndex(results, i);
+        CFDataRef cert_issuer = CFDictionaryGetValue(cert_dict, kSecAttrIssuer);
+        if (CFEqual(cert_issuer, issuer))
+            continue;
+        if (recurse-- > 0)
+            found = items_matching_issuer_parent(accessGroups, cert_issuer, issuers, recurse);
+    }
+    CFRelease(results);
+
+    return found;
 }
 
 }
 
+static bool match_item(Query *q, CFArrayRef accessGroups, CFDictionaryRef item)
+{
+    if (q->q_match_issuer) {
+        CFDataRef issuer = CFDictionaryGetValue(item, kSecAttrIssuer);
+        if (!items_matching_issuer_parent(accessGroups, issuer, q->q_match_issuer, 10 /*max depth*/))
+            return false;
+    }
+
+    /* Add future match checks here. */
+
+    return true;
+}
 
 /****************************************************************************
  **************** Beginning of Externally Callable Interface ****************
  ****************************************************************************/
 
 
 /****************************************************************************
  **************** Beginning of Externally Callable Interface ****************
  ****************************************************************************/
 
+#if 0
+// TODO Use as a safety wrapper
+static bool SecErrorWith(CFErrorRef *in_error, bool (^perform)(CFErrorRef *error)) {
+    CFErrorRef error = in_error ? *in_error : NULL;
+    bool ok;
+    if ((ok = perform(&error))) {
+        assert(error == NULL);
+        if (error)
+            secerror("error + success: %@", error);
+    } else {
+        assert(error);
+        OSStatus status = SecErrorGetOSStatus(error);
+        if (status != errSecItemNotFound)           // Occurs in normal operation, so exclude
+            secerror("error:[%" PRIdOSStatus "] %@", status, error);
+        if (in_error) {
+            *in_error = error;
+        } else {
+            CFReleaseNull(error);
+        }
+    }
+    return ok;
+}
+#endif
 
 /* AUDIT[securityd](done):
    query (ok) is a caller provided dictionary, only its cf type has been checked.
  */
 
 /* AUDIT[securityd](done):
    query (ok) is a caller provided dictionary, only its cf type has been checked.
  */
-OSStatus
-_SecItemCopyMatching(CFDictionaryRef query, CFTypeRef *result,
-    CFArrayRef accessGroups)
+static bool
+SecItemServerCopyMatching(CFDictionaryRef query, CFTypeRef *result,
+    CFArrayRef accessGroups, CFErrorRef *error)
 {
 {
-       pthread_once(&kc_dbhandle_init_once, kc_dbhandle_init);
     CFIndex ag_count;
     CFIndex ag_count;
-    if (!accessGroups || 0 == (ag_count = CFArrayGetCount(accessGroups)))
-        return errSecMissingEntitlement;
+    if (!accessGroups || 0 == (ag_count = CFArrayGetCount(accessGroups))) {
+        return SecError(errSecMissingEntitlement, error,
+                         CFSTR("client has neither application-identifier nor keychain-access-groups entitlements"));
+    }
 
 
-    /* Having the special accessGroup "*" allows access to all accessGroups. */
-    if (CFArrayContainsValue(accessGroups, CFRangeMake(0, ag_count), CFSTR("*")))
+    if (CFArrayContainsValue(accessGroups, CFRangeMake(0, ag_count), CFSTR("*"))) {
+        /* Having the special accessGroup "*" allows access to all accessGroups. */
         accessGroups = NULL;
         accessGroups = NULL;
+    }
 
 
-    OSStatus error = 0;
-    Query *q = query_create_with_limit(query, 1, &error);
+    bool ok = false;
+    Query *q = query_create_with_limit(query, 1, error);
     if (q) {
         CFStringRef agrp = CFDictionaryGetValue(q->q_item, kSecAttrAccessGroup);
         if (agrp && accessGroupsAllows(accessGroups, agrp)) {
     if (q) {
         CFStringRef agrp = CFDictionaryGetValue(q->q_item, kSecAttrAccessGroup);
         if (agrp && accessGroupsAllows(accessGroups, agrp)) {
+            // TODO: Return an error if agrp is not NULL and accessGroupsAllows() fails above.
             const void *val = agrp;
             accessGroups = CFArrayCreate(0, &val, 1, &kCFTypeArrayCallBacks);
         } else {
             const void *val = agrp;
             accessGroups = CFArrayCreate(0, &val, 1, &kCFTypeArrayCallBacks);
         } else {
@@ -4383,47 +3379,50 @@ _SecItemCopyMatching(CFDictionaryRef query, CFTypeRef *result,
 
         /* Sanity check the query. */
         if (q->q_use_item_list) {
 
         /* Sanity check the query. */
         if (q->q_use_item_list) {
-            error = errSecUseItemListUnsupported;
+            ok = SecError(errSecUseItemListUnsupported, error, CFSTR("use item list unsupported"));
 #if defined(MULTIPLE_KEYCHAINS)
         } else if (q->q_use_keychain) {
 #if defined(MULTIPLE_KEYCHAINS)
         } else if (q->q_use_keychain) {
-            error = errSecUseKeychainUnsupported;
+            ok = SecError(errSecUseKeychainUnsupported, error, CFSTR("use keychain list unsupported"));
 #endif
 #endif
+        } else if (q->q_match_issuer && ((q->q_class != &cert_class) &&
+                    (q->q_class != &identity_class))) {
+            ok = SecError(errSecUnsupportedOperation, error, CFSTR("unsupported match attribute"));
         } else if (q->q_return_type != 0 && result == NULL) {
         } else if (q->q_return_type != 0 && result == NULL) {
-            error = errSecReturnMissingPointer;
+            ok = SecError(errSecReturnMissingPointer, error, CFSTR("missing pointer"));
         } else if (!q->q_error) {
         } else if (!q->q_error) {
-            s3dl_db_thread *dbt;
-            int s3e = s3dl_get_dbt(kc_dbhandle, &dbt);
-            if (s3e == SQLITE_OK) {
-                s3e = s3dl_copy_matching(dbt, q, result, accessGroups);
-                /* TODO: Check error of this function if s3e is noErr. */
-                kc_release_dbt(dbt);
-            }
-            if (s3e)
-                error = osstatus_for_s3e(s3e);
+            ok = kc_with_dbt(false, error, ^(SecDbConnectionRef dbt) {
+                return s3dl_copy_matching(dbt, q, result, accessGroups, error);
+            });
         }
 
         CFReleaseSafe(accessGroups);
         }
 
         CFReleaseSafe(accessGroups);
-        query_destroy(q, &error);
+        if (!query_destroy(q, error))
+            ok = false;
     }
 
     }
 
-       return error;
+       return ok;
+}
+
+bool
+_SecItemCopyMatching(CFDictionaryRef query, CFArrayRef accessGroups, CFTypeRef *result, CFErrorRef *error) {
+    return SecItemServerCopyMatching(query, result, accessGroups, error);
 }
 
 /* AUDIT[securityd](done):
    attributes (ok) is a caller provided dictionary, only its cf type has
        been checked.
  */
 }
 
 /* AUDIT[securityd](done):
    attributes (ok) is a caller provided dictionary, only its cf type has
        been checked.
  */
-OSStatus
-_SecItemAdd(CFDictionaryRef attributes, CFTypeRef *result,
-    CFArrayRef accessGroups)
+bool
+_SecItemAdd(CFDictionaryRef attributes, CFArrayRef accessGroups,
+            CFTypeRef *result, CFErrorRef *error)
 {
 {
-       pthread_once(&kc_dbhandle_init_once, kc_dbhandle_init);
+    bool ok = true;
     CFIndex ag_count;
     if (!accessGroups || 0 == (ag_count = CFArrayGetCount(accessGroups)))
     CFIndex ag_count;
     if (!accessGroups || 0 == (ag_count = CFArrayGetCount(accessGroups)))
-        return errSecMissingEntitlement;
+        return SecError(errSecMissingEntitlement, error,
+                           CFSTR("client has neither application-identifier nor keychain-access-groups entitlements"));
 
 
-    OSStatus error = 0;
-    Query *q = query_create_with_limit(attributes, 0, &error);
+    Query *q = query_create_with_limit(attributes, 0, error);
     if (q) {
         /* Access group sanity checking. */
         CFStringRef agrp = (CFStringRef)CFDictionaryGetValue(attributes,
     if (q) {
         /* Access group sanity checking. */
         CFStringRef agrp = (CFStringRef)CFDictionaryGetValue(attributes,
@@ -4437,7 +3436,7 @@ _SecItemAdd(CFDictionaryRef attributes, CFTypeRef *result,
         if (agrp) {
             /* The user specified an explicit access group, validate it. */
             if (!accessGroupsAllows(accessGroups, agrp))
         if (agrp) {
             /* The user specified an explicit access group, validate it. */
             if (!accessGroupsAllows(accessGroups, agrp))
-                return errSecNoAccessForItem;
+                return SecError(errSecNoAccessForItem, error, CFSTR("NoAccessForItem"));
         } else {
             agrp = (CFStringRef)CFArrayGetValueAtIndex(ag, 0);
 
         } else {
             agrp = (CFStringRef)CFArrayGetValueAtIndex(ag, 0);
 
@@ -4449,64 +3448,63 @@ _SecItemAdd(CFDictionaryRef attributes, CFTypeRef *result,
         query_ensure_keyclass(q, agrp);
 
         if (q->q_row_id)
         query_ensure_keyclass(q, agrp);
 
         if (q->q_row_id)
-            error = errSecValuePersistentRefUnsupported;
+            ok = SecError(errSecValuePersistentRefUnsupported, error, CFSTR("q_row_id"));  // TODO: better error string
     #if defined(MULTIPLE_KEYCHAINS)
         else if (q->q_use_keychain_list)
     #if defined(MULTIPLE_KEYCHAINS)
         else if (q->q_use_keychain_list)
-            error = errSecUseKeychainListUnsupported;
+            ok = SecError(errSecUseKeychainListUnsupported, error, CFSTR("q_use_keychain_list"));  // TODO: better error string;
     #endif
         else if (!q->q_error) {
     #endif
         else if (!q->q_error) {
-            s3dl_db_thread *dbt;
-            int s3e = s3dl_get_dbt(kc_dbhandle, &dbt);
-            if (s3e == SQLITE_OK) {
-                s3e = s3dl_begin_transaction(dbt);
-                if (s3e == SQLITE_OK) {
+            ok = kc_with_dbt(true, error, ^(SecDbConnectionRef dbt){
+                return kc_transaction(dbt, error, ^{
                     query_pre_add(q, true);
                     query_pre_add(q, true);
-                    s3e = s3dl_query_add(dbt, q, result);
-                }
-                s3e = s3dl_end_transaction(dbt, s3e);
-            }
-
-            /* TODO: Check error on this function if s3e is 0. */
-            kc_release_dbt(dbt);
-
-            if (s3e)
-                error = osstatus_for_s3e(s3e);
+                    return s3dl_query_add(dbt, q, result, error);
+                });
+            });
         }
         }
-        query_destroy(q, &error);
+        ok = query_notify_and_destroy(q, ok, error);
+    } else {
+        ok = false;
     }
     }
-    return error;
+    return ok;
 }
 
 /* AUDIT[securityd](done):
    query (ok) and attributesToUpdate (ok) are a caller provided dictionaries,
        only their cf types have been checked.
  */
 }
 
 /* AUDIT[securityd](done):
    query (ok) and attributesToUpdate (ok) are a caller provided dictionaries,
        only their cf types have been checked.
  */
-OSStatus
-_SecItemUpdate(CFDictionaryRef query,
-    CFDictionaryRef attributesToUpdate, CFArrayRef accessGroups)
+bool
+_SecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate,
+               CFArrayRef accessGroups, CFErrorRef *error)
 {
 {
-       pthread_once(&kc_dbhandle_init_once, kc_dbhandle_init);
     CFIndex ag_count;
     CFIndex ag_count;
-    if (!accessGroups || 0 == (ag_count = CFArrayGetCount(accessGroups)))
-        return errSecMissingEntitlement;
+    if (!accessGroups || 0 == (ag_count = CFArrayGetCount(accessGroups))) {
+        return SecError(errSecMissingEntitlement, error,
+                         CFSTR("client has neither application-identifier nor keychain-access-groups entitlements"));
+    }
 
 
-    /* Having the special accessGroup "*" allows access to all accessGroups. */
-    if (CFArrayContainsValue(accessGroups, CFRangeMake(0, ag_count), CFSTR("*")))
+    if (CFArrayContainsValue(accessGroups, CFRangeMake(0, ag_count), CFSTR("*"))) {
+        /* Having the special accessGroup "*" allows access to all accessGroups. */
         accessGroups = NULL;
         accessGroups = NULL;
+    }
 
 
-    OSStatus error = 0;
-    Query *q = query_create_with_limit(query, kSecMatchUnlimited, &error);
-    if (q) {
+    bool ok = true;
+    Query *q = query_create_with_limit(query, kSecMatchUnlimited, error);
+    if (!q) {
+        ok = false;
+    }
+    if (ok) {
         /* Sanity check the query. */
         if (q->q_use_item_list) {
         /* Sanity check the query. */
         if (q->q_use_item_list) {
-            error = errSecUseItemListUnsupported;
+            ok = SecError(errSecUseItemListUnsupported, error, CFSTR("use item list not supported"));
         } else if (q->q_return_type & kSecReturnDataMask) {
             /* Update doesn't return anything so don't ask for it. */
         } else if (q->q_return_type & kSecReturnDataMask) {
             /* Update doesn't return anything so don't ask for it. */
-            error = errSecReturnDataUnsupported;
+            ok = SecError(errSecReturnDataUnsupported, error, CFSTR("return data not supported by update"));
         } else if (q->q_return_type & kSecReturnAttributesMask) {
         } else if (q->q_return_type & kSecReturnAttributesMask) {
-            error = errSecReturnAttributesUnsupported;
+            ok = SecError(errSecReturnAttributesUnsupported, error, CFSTR("return attributes not supported by update"));
         } else if (q->q_return_type & kSecReturnRefMask) {
         } else if (q->q_return_type & kSecReturnRefMask) {
-            error = errSecReturnRefUnsupported;
+            ok = SecError(errSecReturnRefUnsupported, error, CFSTR("return ref not supported by update"));
+        } else if (q->q_return_type & kSecReturnPersistentRefMask) {
+            ok = SecError(errSecReturnPersitentRefUnsupported, error, CFSTR("return persistent ref not supported by update"));
         } else {
             /* Access group sanity checking. */
             CFStringRef agrp = (CFStringRef)CFDictionaryGetValue(attributesToUpdate,
         } else {
             /* Access group sanity checking. */
             CFStringRef agrp = (CFStringRef)CFDictionaryGetValue(attributesToUpdate,
@@ -4514,255 +3512,935 @@ _SecItemUpdate(CFDictionaryRef query,
             if (agrp) {
                 /* The user is attempting to modify the access group column,
                    validate it to make sure the new value is allowable. */
             if (agrp) {
                 /* The user is attempting to modify the access group column,
                    validate it to make sure the new value is allowable. */
-                if (!accessGroupsAllows(accessGroups, agrp))
-                    error = errSecNoAccessForItem;
-            }
-
-            if (!error) {
-                s3dl_db_thread *dbt;
-                int s3e = s3dl_get_dbt(kc_dbhandle, &dbt);
-                if (s3e == SQLITE_OK) {
-                    s3e = s3dl_query_update(dbt, q, attributesToUpdate, accessGroups);
-
-                    /* TODO: Check error on this function if s3e is 0. */
-                    kc_release_dbt(dbt);
+                if (!accessGroupsAllows(accessGroups, agrp)) {
+                    ok = SecError(errSecNoAccessForItem, error, CFSTR("accessGroup %@ not in %@"), agrp, accessGroups);
                 }
                 }
-
-                if (s3e)
-                    error = osstatus_for_s3e(s3e);
             }
         }
             }
         }
-        query_destroy(q, &error);
     }
     }
-    return error;
+    if (ok) {
+        if (!q->q_use_tomb && SOSCCThisDeviceDefinitelyNotActiveInCircle()) {
+            q->q_use_tomb = kCFBooleanFalse;
+        }
+        ok = kc_with_dbt(true, error, ^(SecDbConnectionRef dbt) {
+            return s3dl_query_update(dbt, q, attributesToUpdate, accessGroups, error);
+        });
+    }
+    if (q) {
+        ok = query_notify_and_destroy(q, ok, error);
+    }
+    return ok;
 }
 
 }
 
+
 /* AUDIT[securityd](done):
    query (ok) is a caller provided dictionary, only its cf type has been checked.
  */
 /* AUDIT[securityd](done):
    query (ok) is a caller provided dictionary, only its cf type has been checked.
  */
-OSStatus
-_SecItemDelete(CFDictionaryRef query, CFArrayRef accessGroups)
+bool
+_SecItemDelete(CFDictionaryRef query, CFArrayRef accessGroups, CFErrorRef *error)
 {
 {
-       pthread_once(&kc_dbhandle_init_once, kc_dbhandle_init);
     CFIndex ag_count;
     CFIndex ag_count;
-    if (!accessGroups || 0 == (ag_count = CFArrayGetCount(accessGroups)))
-        return errSecMissingEntitlement;
+    if (!accessGroups || 0 == (ag_count = CFArrayGetCount(accessGroups))) {
+        return SecError(errSecMissingEntitlement, error,
+                           CFSTR("client has neither application-identifier nor keychain-access-groups entitlements"));
+    }
 
 
-    /* Having the special accessGroup "*" allows access to all accessGroups. */
-    if (CFArrayContainsValue(accessGroups, CFRangeMake(0, ag_count), CFSTR("*")))
+    if (CFArrayContainsValue(accessGroups, CFRangeMake(0, ag_count), CFSTR("*"))) {
+        /* Having the special accessGroup "*" allows access to all accessGroups. */
         accessGroups = NULL;
         accessGroups = NULL;
+    }
 
 
-    OSStatus error = 0;
-    Query *q = query_create_with_limit(query, kSecMatchUnlimited, &error);
+    Query *q = query_create_with_limit(query, kSecMatchUnlimited, error);
+    bool ok;
     if (q) {
         /* Sanity check the query. */
         if (q->q_limit != kSecMatchUnlimited)
     if (q) {
         /* Sanity check the query. */
         if (q->q_limit != kSecMatchUnlimited)
-            error = errSecMatchLimitUnsupported;
+            ok = SecError(errSecMatchLimitUnsupported, error, CFSTR("match limit not supported by delete"));
         else if (query_match_count(q) != 0)
         else if (query_match_count(q) != 0)
-            error = errSecItemMatchUnsupported;
+            ok = SecError(errSecItemMatchUnsupported, error, CFSTR("match not supported by delete"));
         else if (q->q_ref)
         else if (q->q_ref)
-            error = errSecValueRefUnsupported;
+            ok = SecError(errSecValueRefUnsupported, error, CFSTR("value ref not supported by delete"));
         else if (q->q_row_id && query_attr_count(q))
         else if (q->q_row_id && query_attr_count(q))
-            error = errSecItemIllegalQuery;
+            ok = SecError(errSecItemIllegalQuery, error, CFSTR("rowid and other attributes are mutually exclusive"));
         else {
         else {
-            s3dl_db_thread *dbt;
-            int s3e = s3dl_get_dbt(kc_dbhandle, &dbt);
-            if (s3e == SQLITE_OK) {
-                s3e = s3dl_query_delete(dbt, q, accessGroups);
-
-                /* TODO: Check error on this function if s3e is 0. */
-                kc_release_dbt(dbt);
+            if (!q->q_use_tomb && SOSCCThisDeviceDefinitelyNotActiveInCircle()) {
+                q->q_use_tomb = kCFBooleanFalse;
             }
             }
-            if (s3e)
-                error = osstatus_for_s3e(s3e);
+            ok = kc_with_dbt(true, error, ^(SecDbConnectionRef dbt) {
+                return s3dl_query_delete(dbt, q, accessGroups, error);
+            });
         }
         }
-        query_destroy(q, &error);
+        ok = query_notify_and_destroy(q, ok, error);
+    } else {
+        ok = false;
     }
     }
-    return error;
+    return ok;
 }
 
 }
 
+
 /* AUDIT[securityd](done):
    No caller provided inputs.
  */
 /* AUDIT[securityd](done):
    No caller provided inputs.
  */
+static bool
+SecItemServerDeleteAll(CFErrorRef *error) {
+    return kc_with_dbt(true, error, ^bool (SecDbConnectionRef dbt) {
+        return (kc_transaction(dbt, error, ^bool {
+            return (SecDbExec(dbt, CFSTR("DELETE from genp;"), error) &&
+                    SecDbExec(dbt, CFSTR("DELETE from inet;"), error) &&
+                    SecDbExec(dbt, CFSTR("DELETE from cert;"), error) &&
+                    SecDbExec(dbt, CFSTR("DELETE from keys;"), error));
+        }) && SecDbExec(dbt, CFSTR("VACUUM;"), error));
+    });
+}
+
 bool
 bool
-_SecItemDeleteAll(void)
-{
-       pthread_once(&kc_dbhandle_init_once, kc_dbhandle_init);
-    static const char deleteAllSQL[] = "BEGIN EXCLUSIVE TRANSACTION; "
-            "DELETE from inet; DELETE from cert; DELETE from keys; DELETE from genp; "
-            "COMMIT TRANSACTION; VACUUM;";
+_SecItemDeleteAll(CFErrorRef *error) {
+    return SecItemServerDeleteAll(error);
+}
+
+CFDataRef
+_SecServerKeychainBackup(CFDataRef keybag, CFDataRef passcode, CFErrorRef *error) {
+    CFDataRef backup;
+       SecDbConnectionRef dbt = SecDbConnectionAquire(kc_dbhandle(), false, error);
+
+       if (!dbt)
+               return NULL;
+
+    if (keybag == NULL && passcode == NULL) {
+#if USE_KEYSTORE
+        backup = SecServerExportKeychain(dbt, KEYBAG_DEVICE, backup_keybag_handle, error);
+#else /* !USE_KEYSTORE */
+        SecError(errSecParam, error, CFSTR("Why are you doing this?"));
+        backup = NULL;
+#endif /* USE_KEYSTORE */
+    } else {
+        backup = SecServerKeychainBackup(dbt, keybag, passcode, error);
+    }
+
+    SecDbConnectionRelease(dbt);
+
+    return backup;
+}
+
+bool
+_SecServerKeychainRestore(CFDataRef backup, CFDataRef keybag, CFDataRef passcode, CFErrorRef *error) {
+    if (backup == NULL || keybag == NULL)
+        return SecError(errSecParam, error, CFSTR("backup or keybag missing"));
+
+    __block bool ok = true;
+    ok &= SecDbPerformWrite(kc_dbhandle(), error, ^(SecDbConnectionRef dbconn) {
+        ok = SecServerKeychainRestore(dbconn, backup, keybag, passcode, error);
+    });
 
 
-       s3dl_db_thread *dbt;
-       int s3e = kc_get_dbt(&dbt, true);
-    if (s3e == SQLITE_OK) {
-        s3e = sqlite3_exec(dbt->s3_handle, deleteAllSQL, NULL, NULL, NULL);
-        kc_release_dbt(dbt);
+    if (ok) {
+        SecKeychainChanged(true);
     }
     }
-    return (s3e == SQLITE_OK);
+
+    return ok;
 }
 
 }
 
-/* TODO: Move to a location shared between securityd and Security framework. */
-static const char *restore_keychain_location = "/Library/Keychains/keychain.restoring";
 
 
-/* AUDIT[securityd](done):
-   No caller provided inputs.
+/*
+ *
+ *
+ * SecItemDataSource
+ *
+ *
  */
  */
-OSStatus
-_SecServerRestoreKeychain(void)
-{
-    static db_handle restore_dbhandle = NULL;
-       s3dl_db_thread *restore_dbt = NULL, *dbt = NULL;
-    CFDataRef backup = NULL;
-    OSStatus status = errSecSuccess;
-    int s3e;
-
-       pthread_once(&kc_dbhandle_init_once, kc_dbhandle_init);
-       require_noerr(s3e = s3dl_get_dbt(kc_dbhandle, &dbt), errOut);
-
-    /* Export everything from the keychain we are restoring, this upgrades it
-       to whatever version is current first if needed. */
-       bool use_hwaes = hwaes_key_available();
-       require_noerr(s3e = s3dl_create_db_handle(restore_keychain_location,
-        &restore_dbhandle, &restore_dbt, true, false, use_hwaes), errOut);
-    require_noerr(status = SecServerExportKeychain(restore_dbt, KEYBAG_DEVICE,
-        KEYBAG_NONE, &backup), errOut);
-    require_noerr(status = SecServerImportKeychain(dbt, KEYBAG_NONE,
-        KEYBAG_DEVICE, backup), errOut);
+static CFStringRef kSecItemDataSourceErrorDomain = CFSTR("com.apple.secitem.datasource");
 
 
-errOut:
-    s3e = s3dl_close_db_handle(restore_dbhandle);
-    CFReleaseSafe(backup);
-    kc_release_dbt(restore_dbt);
-    kc_release_dbt(dbt);
+enum {
+    kSecObjectMallocFailed = 1,
+    kSecAddDuplicateEntry,
+    kSecObjectNotFoundError,
+    kSOSAccountCreationFailed,
+};
+
+typedef struct SecItemDataSource *SecItemDataSourceRef;
+
+struct SecItemDataSource {
+    struct SOSDataSource ds;
+    SecDbRef db;
+    bool readOnly;
+    SecDbConnectionRef _dbconn;
+    unsigned gm_count;
+    unsigned cm_count;
+    unsigned co_count;
+    bool dv_loaded;
+    struct SOSDigestVector dv;
+    struct SOSDigestVector toadd;
+    struct SOSDigestVector todel;
+    SOSManifestRef manifest;
+    uint8_t manifest_digest[SOSDigestSize];
+    bool changed;
+    bool syncWithPeersWhenDone;
+};
 
 
-       if (s3e != SQLITE_OK)
-               return osstatus_for_s3e(s3e);
-    return status;
+static SecDbConnectionRef SecItemDataSourceGetConnection(SecItemDataSourceRef ds, CFErrorRef *error) {
+    if (!ds->_dbconn) {
+        ds->_dbconn = SecDbConnectionAquire(ds->db, ds->readOnly, error);
+        if (ds->_dbconn) {
+            ds->changed = false;
+        } else {
+            secerror("SecDbConnectionAquire failed: %@", error ? *error : NULL);
+        }
+    }
+    return ds->_dbconn;
 }
 
 }
 
-/* AUDIT[securityd](done):
-   args_in (ok) is a caller provided, CFArrayRef.
- */
-OSStatus
-_SecServerMigrateKeychain(CFArrayRef args_in, CFTypeRef *args_out)
-{
-       pthread_once(&kc_dbhandle_init_once, kc_dbhandle_init);
-    CFMutableArrayRef args = NULL;
-    CFNumberRef hin = NULL, hout = NULL;
-    int32_t handle_in, handle_out = 0;
-    CFDataRef data_in, data_out = NULL;
-    OSStatus status = errSecParam;
-    CFIndex argc = CFArrayGetCount(args_in);
-
-       s3dl_db_thread *dbt;
-       int s3e = s3dl_get_dbt(kc_dbhandle, &dbt);
-       if (s3e != SQLITE_OK)
-               return osstatus_for_s3e(s3e);
-
-    require_quiet(argc == 1 || argc == 2, errOut);
-    hin = (CFNumberRef)CFArrayGetValueAtIndex(args_in, 0);
-    require_quiet(isNumberOfType(hin, kCFNumberSInt32Type), errOut);
-    require_quiet(CFNumberGetValue(hin, kCFNumberSInt32Type, &handle_in), errOut);
-    if (argc > 1) {
-        data_in = (CFDataRef)CFArrayGetValueAtIndex(args_in, 1);
-        require_quiet(data_in, errOut);
-        require_quiet(CFGetTypeID(data_in) == CFDataGetTypeID(), errOut);
+static bool SecItemDataSourceRecordUpdate(SecItemDataSourceRef ds, SecDbItemRef deleted, SecDbItemRef inserted, CFErrorRef *error) {
+    bool ok = true;
+    CFDataRef digest;
+    if (ds->dv_loaded) {
+        if (inserted) {
+            ok = digest = SecDbItemGetSHA1(inserted, error);
+            if (ok) SOSDigestVectorAppend(&ds->toadd, CFDataGetBytePtr(digest));
+        }
+        if (ok && deleted) {
+            ok = digest = SecDbItemGetSHA1(deleted, error);
+            if (ok) SOSDigestVectorAppend(&ds->todel, CFDataGetBytePtr(digest));
+        }
+        if (inserted || deleted) {
+            CFReleaseNull(ds->manifest);
+            ds->changed = true;
+        }
+
+        if (!ok) {
+            ds->dv_loaded = false;
+        }
+    }
+    return ok;
+}
+
+static bool SecItemDataSourceRecordAdd(SecItemDataSourceRef ds, SecDbItemRef inserted, CFErrorRef *error) {
+    return SecItemDataSourceRecordUpdate(ds, NULL, inserted, error);
+}
+
+static bool SecDbItemSelectSHA1(SecDbQueryRef query, SecDbConnectionRef dbconn, CFErrorRef *error,
+                                bool (^use_attr_in_where)(const SecDbAttr *attr),
+                                bool (^add_where_sql)(CFMutableStringRef sql, bool *needWhere),
+                                bool (^bind_added_where)(sqlite3_stmt *stmt, int col),
+                                void (^row)(sqlite3_stmt *stmt, bool *stop)) {
+    __block bool ok = true;
+    bool (^return_attr)(const SecDbAttr *attr) = ^bool (const SecDbAttr * attr) {
+        return attr->kind == kSecDbSHA1Attr;
+    };
+    CFStringRef sql = SecDbItemCopySelectSQL(query, return_attr, use_attr_in_where, add_where_sql);
+    if (sql) {
+        ok &= SecDbPrepare(dbconn, sql, error, ^(sqlite3_stmt *stmt) {
+            ok = (SecDbItemSelectBind(query, stmt, error, use_attr_in_where, bind_added_where) &&
+                  SecDbStep(dbconn, stmt, error, ^(bool *stop){ row(stmt, stop); }));
+        });
+        CFRelease(sql);
     } else {
     } else {
-        data_in = NULL;
+        ok = false;
     }
     }
+    return ok;
+}
 
 
-    secdebug("migrate", "migrate: %d %d", handle_in, data_in);
+static bool SecItemDataSourceLoadManifest(SecItemDataSourceRef ds, CFErrorRef *error) {
+    bool ok = true;
+    SecDbConnectionRef dbconn;
+    if (!(dbconn = SecItemDataSourceGetConnection(ds, error))) return false;
 
 
-    status = SecServerMigrateKeychain(dbt, handle_in, data_in, &handle_out, &data_out);
+    /* Fetch all syncable items. */
+    const SecDbClass *synced_classes[] = {
+        &genp_class,
+        &inet_class,
+        &keys_class,
+    };
 
 
-    require_quiet(args = CFArrayCreateMutable(kCFAllocatorDefault, 2, &kCFTypeArrayCallBacks), errOut);
-    require_quiet(hout = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &handle_out), errOut);
-    CFArrayAppendValue(args, hout);
-    if (data_out)
-        CFArrayAppendValue(args, data_out);
-    *args_out = args;
-    args = NULL;
+    ds->dv.count = 0; // Empty the digest vectory before we begin
+    CFErrorRef localError = NULL;
+    for (size_t class_ix = 0; class_ix < array_size(synced_classes);
+         ++class_ix) {
+        Query *q = query_create(synced_classes[class_ix], NULL, &localError);
+        if (q) {
+            q->q_return_type = kSecReturnDataMask | kSecReturnAttributesMask;
+            q->q_limit = kSecMatchUnlimited;
+            q->q_keybag = KEYBAG_DEVICE;
+            query_add_attribute(kSecAttrSynchronizable, kCFBooleanTrue, q);
+            //query_add_attribute(kSecAttrAccessible, ds->name, q);
+            // Select everything including tombstones that is synchronizable.
+            if (!SecDbItemSelectSHA1(q, dbconn, &localError, ^bool(const SecDbAttr *attr) {
+                return attr->kind == kSecDbSyncAttr;
+            }, NULL, NULL, ^(sqlite3_stmt *stmt, bool *stop) {
+                const uint8_t *digest = sqlite3_column_blob(stmt, 0);
+                size_t digestLen = sqlite3_column_bytes(stmt, 0);
+                if (digestLen != SOSDigestSize) {
+                    secerror("digest %zu bytes", digestLen);
+                } else {
+                    SOSDigestVectorAppend(&ds->dv, digest);
+                }
+            })) {
+                secerror("SecDbItemSelect failed: %@", localError);
+                CFReleaseNull(localError);
+            }
+            query_destroy(q, &localError);
+            if (localError) {
+                secerror("query_destroy failed: %@", localError);
+                CFReleaseNull(localError);
+            }
+        } else if (localError) {
+            secerror("query_create failed: %@", localError);
+            CFReleaseNull(localError);
+        }
+    }
+    SOSDigestVectorSort(&ds->dv);
+    return ok;
+}
+
+static bool SecItemDataSourceEnsureFreshManifest(SecItemDataSourceRef ds, CFErrorRef *error) {
+    bool ok = true;
+    if (ds->dv_loaded && (ds->toadd.count || ds->todel.count)) {
+        CFErrorRef patchError = NULL;
+        struct SOSDigestVector new_dv = SOSDigestVectorInit;
+        ok = SOSDigestVectorPatch(&ds->dv, &ds->todel, &ds->toadd, &new_dv, &patchError);
+        if (!ok) secerror("patch failed %@ manifest: %@ toadd: %@ todel: %@", patchError, &ds->dv, &ds->todel, &ds->toadd);
+        CFReleaseSafe(patchError);
+        SOSDigestVectorFree(&ds->dv);
+        SOSDigestVectorFree(&ds->toadd);
+        SOSDigestVectorFree(&ds->todel);
+        ds->dv = new_dv;
+    }
+    // If we failed to patch or we haven't loaded yet, force a load from the db.
+    return (ok && ds->dv_loaded) || (ds->dv_loaded = SecItemDataSourceLoadManifest(ds, error));
+}
 
 
-errOut:
-    kc_release_dbt(dbt);
-    CFReleaseSafe(args);
-    CFReleaseSafe(hout);
-    CFReleaseSafe(data_out);
-       return status;
-}
-
-OSStatus
-_SecServerKeychainBackup(CFArrayRef args_in, CFTypeRef *args_out) {
-       pthread_once(&kc_dbhandle_init_once, kc_dbhandle_init);
-    OSStatus status = errSecParam;
-    CFIndex argc = args_in ? CFArrayGetCount(args_in) : 0;
-    CFDataRef backup = NULL;
+/* DataSource protocol. */
+static bool ds_get_manifest_digest(SOSDataSourceRef data_source, uint8_t *out_digest, CFErrorRef *error) {
+    struct SecItemDataSource *ds = (struct SecItemDataSource *)data_source;
+    if (!ds->manifest) {
+        SOSManifestRef mf = data_source->copy_manifest(data_source, error);
+        if (mf) {
+            CFRelease(mf);
+        } else {
+            return false;
+        }
+    }
+    memcpy(out_digest, ds->manifest_digest, SOSDigestSize);
+    ds->gm_count++;
+    return true;
+}
 
 
-       s3dl_db_thread *dbt;
-       int s3e = s3dl_get_dbt(kc_dbhandle, &dbt);
-       if (s3e != SQLITE_OK)
-               return osstatus_for_s3e(s3e);
+static SOSManifestRef ds_copy_manifest(SOSDataSourceRef data_source, CFErrorRef *error) {
+    struct SecItemDataSource *ds = (struct SecItemDataSource *)data_source;
+    ds->cm_count++;
+    if (ds->manifest) {
+        CFRetain(ds->manifest);
+        return ds->manifest;
+    }
 
 
-    require_quiet(args_out != NULL, errOut);
-    if (argc == 0) {
-#if USE_KEYSTORE
-        require_noerr_quiet(status = SecServerExportKeychain(dbt, KEYBAG_DEVICE, backup_keybag_handle, &backup), errOut);
-#else
-        goto errOut;
-#endif
+    if (!SecItemDataSourceEnsureFreshManifest(ds, error)) return NULL;
+
+    ds->manifest = SOSManifestCreateWithBytes((const uint8_t *)ds->dv.digest, ds->dv.count * SOSDigestSize, error);
+    // TODO move digest
+    ccdigest(ccsha1_di(), SOSManifestGetSize(ds->manifest), SOSManifestGetBytePtr(ds->manifest), ds->manifest_digest);
+
+    return (SOSManifestRef)CFRetain(ds->manifest);
+}
+
+static bool ds_foreach_object(SOSDataSourceRef data_source, SOSManifestRef manifest, CFErrorRef *error, bool (^handle_object)(SOSObjectRef object, CFErrorRef *error)) {
+    struct SecItemDataSource *ds = (struct SecItemDataSource *)data_source;
+    ds->co_count++;
+    __block bool result = true;
+    const SecDbAttr *sha1Attr = SecDbClassAttrWithKind(&genp_class, kSecDbSHA1Attr, error);
+    if (!sha1Attr) return false;
+    bool (^return_attr)(const SecDbAttr *attr) = ^bool (const SecDbAttr * attr) {
+        return attr->kind == kSecDbRowIdAttr || attr->kind == kSecDbEncryptedDataAttr;
+    };
+    bool (^use_attr_in_where)(const SecDbAttr *attr) = ^bool (const SecDbAttr * attr) {
+        return attr->kind == kSecDbSHA1Attr;
+    };
+    const SecDbClass *synced_classes[] = {
+        &genp_class,
+        &inet_class,
+        &keys_class,
+    };
+    Query *select_queries[array_size(synced_classes)];
+    CFStringRef select_sql[array_size(synced_classes)];
+    sqlite3_stmt *select_stmts[array_size(synced_classes)];
+
+    __block Query **queries = select_queries;
+    __block CFStringRef *sqls = select_sql;
+    __block sqlite3_stmt **stmts = select_stmts;
+
+    SecDbConnectionRef dbconn;
+    result = dbconn = SecItemDataSourceGetConnection(ds, error);
+
+    // Setup
+    for (size_t class_ix = 0; class_ix < array_size(synced_classes); ++class_ix) {
+        result = (result
+                  && (queries[class_ix] = query_create(synced_classes[class_ix], NULL, error))
+                  && (sqls[class_ix] = SecDbItemCopySelectSQL(queries[class_ix], return_attr, use_attr_in_where, NULL))
+                  && (stmts[class_ix] = SecDbCopyStmt(dbconn, sqls[class_ix], NULL, error)));
     }
     }
-    else if (argc == 1 || argc == 2) {
-        CFDataRef keybag = (CFDataRef)CFArrayGetValueAtIndex(args_in, 0);
-        require_quiet(isData(keybag), errOut);
-        CFDataRef password;
-        if (argc > 1) {
-            password = (CFDataRef)CFArrayGetValueAtIndex(args_in, 1);
-            require_quiet(isData(password), errOut);
+
+    if (result) SOSManifestForEach(manifest, ^(CFDataRef key) {
+        __block bool gotItem = false;
+        for (size_t class_ix = 0; result && !gotItem && class_ix < array_size(synced_classes); ++class_ix) {
+            CFDictionarySetValue(queries[class_ix]->q_item, sha1Attr->name, key);
+            result &= (SecDbItemSelectBind(queries[class_ix], stmts[class_ix], error, use_attr_in_where, NULL) && SecDbStep(dbconn, stmts[class_ix], error, ^(bool *stop) {
+                SecDbItemRef item = SecDbItemCreateWithStatement(kCFAllocatorDefault, queries[class_ix]->q_class, stmts[class_ix], KEYBAG_DEVICE, error, return_attr);
+                if (item) {
+                    CFErrorRef localError=NULL;
+                    gotItem = true;
+                    // Stop on errors from handle_object, except decode errors
+                    if(!(result=handle_object((SOSObjectRef)item, &localError))){
+                        if (SecErrorGetOSStatus(localError) == errSecDecode) {
+                            const uint8_t *p=CFDataGetBytePtr(key);
+                            secnotice("item", "Found corrupted item, removing from manifest key=%02X%02X%02X%02X, item=%@", p[0],p[1],p[2],p[3], item);
+                            /* Removing from Manifest: */
+                            SOSDigestVectorAppend(&ds->todel, p);
+                            CFReleaseNull(ds->manifest);
+                        } else {
+                            *stop=true;
+                        }
+                        if(error && *error == NULL) {
+                            *error = localError;
+                            localError = NULL;
+                        }
+                    }
+                    CFRelease(item);
+                    CFReleaseSafe(localError);
+                }
+            })) && SecDbReset(stmts[class_ix], error);
+        }
+        if (!gotItem) {
+            result = false;
+            if (error && !*error) {
+                SecCFCreateErrorWithFormat(kSecObjectNotFoundError, kSecItemDataSourceErrorDomain, NULL, error, 0, CFSTR("key %@ not in database"), key);
+            }
+        }
+    });
+
+    // Cleanup
+    for (size_t class_ix = 0; class_ix < array_size(synced_classes); ++class_ix) {
+        result &= SecDbReleaseCachedStmt(dbconn, sqls[class_ix], stmts[class_ix], error);
+        CFReleaseSafe(sqls[class_ix]);
+        result &= query_destroy(queries[class_ix], error);
+    }
+    return result;
+}
+
+static void ds_dispose(SOSDataSourceRef data_source) {
+    struct SecItemDataSource *ds = (struct SecItemDataSource *)data_source;
+    if (ds->_dbconn)
+        SecDbConnectionRelease(ds->_dbconn);
+    if (ds->changed)
+        SecKeychainChanged(ds->syncWithPeersWhenDone);
+    CFReleaseSafe(ds->manifest);
+    SOSDigestVectorFree(&ds->dv);
+    free(ds);
+}
+
+static SOSObjectRef ds_create_with_property_list(SOSDataSourceRef ds, CFDictionaryRef plist, CFErrorRef *error) {
+    SecDbItemRef item = NULL;
+    const SecDbClass *class = NULL;
+    CFTypeRef cname = CFDictionaryGetValue(plist, kSecClass);
+    if (cname) {
+        class = kc_class_with_name(cname);
+        if (class) {
+            item = SecDbItemCreateWithAttributes(kCFAllocatorDefault, class, plist, KEYBAG_DEVICE, error);
         } else {
         } else {
-            password = NULL;
+            SecError(errSecNoSuchClass, error, CFSTR("can find class named: %@"), cname);
         }
         }
-        require_noerr_quiet(status = SecServerKeychainBackup(dbt, keybag, password, &backup), errOut);
+    } else {
+        SecError(errSecItemClassMissing, error, CFSTR("query missing %@ attribute"), kSecClass);
     }
     }
-    *args_out = backup;
+    return (SOSObjectRef)item;
+}
 
 
-errOut:
-    kc_release_dbt(dbt);
-    return status;
-}
-
-OSStatus
-_SecServerKeychainRestore(CFArrayRef args_in, CFTypeRef *dummy) {
-       pthread_once(&kc_dbhandle_init_once, kc_dbhandle_init);
-    OSStatus status = errSecParam;
-    CFIndex argc = CFArrayGetCount(args_in);
-
-       s3dl_db_thread *dbt;
-       int s3e = s3dl_get_dbt(kc_dbhandle, &dbt);
-       if (s3e != SQLITE_OK)
-               return osstatus_for_s3e(s3e);
-
-    require_quiet(argc == 2 || argc == 3, errOut);
-    CFDataRef backup = (CFDataRef)CFArrayGetValueAtIndex(args_in, 0);
-    require_quiet(isData(backup), errOut);
-    CFDataRef keybag = (CFDataRef)CFArrayGetValueAtIndex(args_in, 1);
-    require_quiet(isData(keybag), errOut);
-    CFDataRef password;
-    if (argc > 2) {
-        password = (CFDataRef)CFArrayGetValueAtIndex(args_in, 2);
-        require_quiet(isData(password), errOut);
-    } else {
-        password = NULL;
+static CFDataRef ds_copy_digest(SOSObjectRef object, CFErrorRef *error) {
+    SecDbItemRef item = (SecDbItemRef) object;
+    CFDataRef digest = SecDbItemGetSHA1(item, error);
+    CFRetainSafe(digest);
+    return digest;
+}
+
+static CFDataRef ds_copy_primary_key(SOSObjectRef object, CFErrorRef *error) {
+    SecDbItemRef item = (SecDbItemRef) object;
+    CFDataRef pk = SecDbItemGetPrimaryKey(item, error);
+    CFRetainSafe(pk);
+    return pk;
+}
+
+static CFDictionaryRef ds_copy_property_list(SOSObjectRef object, CFErrorRef *error) {
+    SecDbItemRef item = (SecDbItemRef) object;
+    CFMutableDictionaryRef plist = SecDbItemCopyPListWithMask(item, kSecDbInCryptoDataFlag, error);
+    if (plist)
+        CFDictionaryAddValue(plist, kSecClass, SecDbItemGetClass(item)->name);
+    return plist;
+}
+
+// Return the newest object
+static SOSObjectRef ds_copy_merged_object(SOSObjectRef object1, SOSObjectRef object2, CFErrorRef *error) {
+    SecDbItemRef item1 = (SecDbItemRef) object1;
+    SecDbItemRef item2 = (SecDbItemRef) object2;
+    SOSObjectRef result = NULL;
+    CFDateRef m1, m2;
+    const SecDbAttr *desc = SecDbAttrWithKey(SecDbItemGetClass(item1), kSecAttrModificationDate, error);
+    m1 = SecDbItemGetValue(item1, desc, error);
+    if (!m1)
+        return NULL;
+    m2 = SecDbItemGetValue(item2, desc, error);
+    if (!m2)
+        return NULL;
+    switch (CFDateCompare(m1, m2, NULL)) {
+        case kCFCompareGreaterThan:
+            result = (SOSObjectRef)item1;
+            break;
+        case kCFCompareLessThan:
+            result = (SOSObjectRef)item2;
+            break;
+        case kCFCompareEqualTo:
+        {
+            // Return the item with the smallest digest.
+            CFDataRef digest1 = ds_copy_digest(object1, error);
+            CFDataRef digest2 = ds_copy_digest(object2, error);
+            if (digest1 && digest2) switch (CFDataCompare(digest1, digest2)) {
+                case kCFCompareGreaterThan:
+                case kCFCompareEqualTo:
+                    result = (SOSObjectRef)item2;
+                    break;
+                case kCFCompareLessThan:
+                    result = (SOSObjectRef)item1;
+                    break;
+            }
+            CFReleaseSafe(digest2);
+            CFReleaseSafe(digest1);
+            break;
+        }
+    }
+    CFRetainSafe(result);
+    return result;
+}
+
+static SOSMergeResult dsMergeObject(SOSDataSourceRef data_source, SOSObjectRef peersObject, CFErrorRef *error) {
+    struct SecItemDataSource *ds = (struct SecItemDataSource *)data_source;
+    SecDbItemRef peersItem = (SecDbItemRef)peersObject;
+    SecDbConnectionRef dbconn = SecItemDataSourceGetConnection(ds, error);
+    __block SOSMergeResult mr = kSOSMergeFailure;
+    __block SecDbItemRef mergedItem = NULL;
+    __block SecDbItemRef replacedItem = NULL;
+    if (!peersItem || !dbconn || !SecDbItemSetKeybag(peersItem, KEYBAG_DEVICE, error)) return mr;
+    if (SecDbItemInsertOrReplace(peersItem, dbconn, error, ^(SecDbItemRef myItem, SecDbItemRef *replace) {
+        // An item with the same primary key as dbItem already exists in the the database.  That item is old_item.
+        // Let the conflict resolver choose which item to keep.
+        mergedItem = (SecDbItemRef)ds_copy_merged_object(peersObject, (SOSObjectRef)myItem, error);
+        if (!mergedItem) return;
+        if (CFEqual(mergedItem, myItem)) {
+            // Conflict resolver choose my (local) item
+            mr = kSOSMergeLocalObject;
+        } else {
+            CFRetainSafe(myItem);
+            replacedItem = myItem;
+            CFRetainSafe(mergedItem);
+            *replace = mergedItem;
+            if (CFEqual(mergedItem, peersItem)) {
+                // Conflict resolver choose peers item
+                mr = kSOSMergePeersObject;
+            } else {
+                mr = kSOSMergeCreatedObject;
+            }
+        }
+    })) {
+        if (mr == kSOSMergeFailure) {
+            mr = kSOSMergePeersObject;
+            SecItemDataSourceRecordAdd(ds, peersItem, error);
+        } else if (mr != kSOSMergeLocalObject) {
+            SecItemDataSourceRecordUpdate(ds, replacedItem, mergedItem, error);
+        }
     }
 
     }
 
-    status = SecServerKeychainRestore(dbt, backup, keybag, password);
-    if (!backup) {
+    if (error && *error && mr != kSOSMergeFailure)
+        CFReleaseNull(*error);
+
+    CFReleaseSafe(mergedItem);
+    CFReleaseSafe(replacedItem);
+    return mr;
+}
+
+
+/*
+    Truthy backup format is a dictionary from sha1 => item.
+    Each item has class, hash and item data.
+
+    TODO: sha1 is included as binary blob to avoid parsing key.
+ */
+enum {
+    kSecBackupIndexHash = 0,
+    kSecBackupIndexClass,
+    kSecBackupIndexData,
+};
+
+static const void *kSecBackupKeys[] = {
+    [kSecBackupIndexHash] = CFSTR("hash"),
+    [kSecBackupIndexClass] = CFSTR("class"),
+    [kSecBackupIndexData] = CFSTR("data"),
+};
+
+#define kSecBackupHash kSecBackupKeys[kSecBackupIndexHash]
+#define kSecBackupClass kSecBackupKeys[kSecBackupIndexClass]
+#define kSecBackupData kSecBackupKeys[kSecBackupIndexData]
+
+static CFDictionaryRef ds_backup_object(SOSObjectRef object, uint64_t handle, CFErrorRef *error) {
+    const void *values[array_size(kSecBackupKeys)];
+    SecDbItemRef item = (SecDbItemRef)object;
+    CFDictionaryRef backup_item = NULL;
+
+    if ((values[kSecBackupIndexHash] = SecDbItemGetSHA1(item, error))) {
+        if ((values[kSecBackupIndexData] = SecDbItemCopyEncryptedDataToBackup(item, handle, error))) {
+            values[kSecBackupIndexClass] = SecDbItemGetClass(item)->name;
+            backup_item = CFDictionaryCreate(kCFAllocatorDefault, kSecBackupKeys, values, array_size(kSecBackupKeys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+            CFRelease(values[kSecBackupIndexData]);
+        }
+    }
+
+    return backup_item;
+}
+
+static bool ds_restore_object(SOSDataSourceRef data_source, uint64_t handle, CFDictionaryRef item, CFErrorRef *error) {
+    struct SecItemDataSource *ds = (struct SecItemDataSource *)data_source;
+    SecDbConnectionRef dbconn = SecItemDataSourceGetConnection(ds, error);
+    if (!dbconn) return false;
+
+    CFStringRef item_class = CFDictionaryGetValue(item, kSecBackupClass);
+    CFDataRef data = CFDictionaryGetValue(item, kSecBackupData);
+    const SecDbClass *dbclass = NULL;
+
+    if (!item_class || !data)
+        return SecError(errSecDecode, error, CFSTR("no class or data in object"));
+    
+    dbclass = kc_class_with_name(item_class);
+    if (!dbclass)
+        return SecError(errSecDecode, error, CFSTR("no such class %@; update kc_class_with_name "), item_class);
+
+    __block SecDbItemRef dbitem = SecDbItemCreateWithEncryptedData(kCFAllocatorDefault, dbclass, data, (keybag_handle_t)handle, error);
+    if (!dbitem)
+        return false;
+    
+    __block bool ok = SecDbItemSetKeybag(dbitem, KEYBAG_DEVICE, error);
+
+    if (ok) {
+        __block SecDbItemRef replaced_item = NULL;
+        ok &= SecDbItemInsertOrReplace(dbitem, dbconn, error, ^(SecDbItemRef old_item, SecDbItemRef *replace) {
+            // An item with the same primary key as dbItem already exists in the the database.  That item is old_item.
+            // Let the conflict resolver choose which item to keep.
+            SecDbItemRef chosen_item = (SecDbItemRef)ds_copy_merged_object((SOSObjectRef)dbitem, (SOSObjectRef)old_item, error);
+            if (chosen_item) {
+                if (CFEqual(chosen_item, old_item)) {
+                    // We're keeping the exisiting item, so we don't need to change anything.
+                    CFRelease(chosen_item);
+                    CFReleaseNull(dbitem);
+                } else {
+                    // We choose a different item than what's in the database already.  Let's set dbitem to what
+                    // we are replacing the item in the database with, and set replaced_item to the item we are replacing.
+                    CFRelease(dbitem); // Release the item created via SecDbItemCreateWithEncryptedData
+                    // Record what we put in the database
+                    CFRetain(chosen_item); // retain what we are about to return in *replace, since SecDbItemInsertOrReplace() CFReleases it.
+                    *replace = dbitem = chosen_item;
+                    // Record that we are replaced old_item in replaced_item.
+                    CFRetain(old_item);
+                    replaced_item = old_item;
+                }
+            } else {
+                ok = false;
+            }
+        })
+        && SecItemDataSourceRecordUpdate(ds, replaced_item, dbitem, error);
+        CFReleaseSafe(replaced_item);
+    }
+    CFReleaseSafe(dbitem);
+
+    return ok;
+}
+
+
+static SOSDataSourceRef SecItemDataSourceCreate(SecDbRef db, bool readOnly, bool syncWithPeersWhenDone, CFErrorRef *error) {
+    __block SecItemDataSourceRef ds = calloc(1, sizeof(struct SecItemDataSource));
+    ds->ds.get_manifest_digest = ds_get_manifest_digest;
+    ds->ds.copy_manifest = ds_copy_manifest;
+    ds->ds.foreach_object = ds_foreach_object;
+    ds->ds.release = ds_dispose;
+    ds->ds.add = dsMergeObject;
+
+    ds->ds.createWithPropertyList = ds_create_with_property_list;
+    ds->ds.copyDigest = ds_copy_digest;
+    ds->ds.copyPrimaryKey = ds_copy_primary_key;
+    ds->ds.copyPropertyList = ds_copy_property_list;
+    ds->ds.copyMergedObject = ds_copy_merged_object;
+    ds->ds.backupObject = ds_backup_object;
+    ds->ds.restoreObject = ds_restore_object;
+
+    ds->syncWithPeersWhenDone = syncWithPeersWhenDone;
+    ds->db = (SecDbRef)CFRetain(db);
+    ds->readOnly = readOnly;
+
+    ds->changed = false;
+    struct SOSDigestVector dv = SOSDigestVectorInit;
+    ds->dv = dv;
+
+    return (SOSDataSourceRef)ds;
+}
+
+static CFArrayRef SecItemDataSourceFactoryCopyNames(SOSDataSourceFactoryRef factory)
+{
+    return CFArrayCreateForCFTypes(kCFAllocatorDefault,
+                                   kSecAttrAccessibleWhenUnlocked,
+                                   //kSecAttrAccessibleAfterFirstUnlock,
+                                   //kSecAttrAccessibleAlways,
+                                   NULL);
+}
+
+struct SecItemDataSourceFactory {
+    struct SOSDataSourceFactory factory;
+    SecDbRef db;
+};
+
+
+static SOSDataSourceRef SecItemDataSourceFactoryCopyDataSource(SOSDataSourceFactoryRef factory, CFStringRef dataSourceName, bool readOnly, CFErrorRef *error)
+{
+    struct SecItemDataSourceFactory *f = (struct SecItemDataSourceFactory *)factory;
+    return SecItemDataSourceCreate(f->db, readOnly, false, error);
+}
+
+static void SecItemDataSourceFactoryDispose(SOSDataSourceFactoryRef factory)
+{
+    struct SecItemDataSourceFactory *f = (struct SecItemDataSourceFactory *)factory;
+    CFReleaseSafe(f->db);
+    free(f);
+}
+
+SOSDataSourceFactoryRef SecItemDataSourceFactoryCreate(SecDbRef db) {
+    struct SecItemDataSourceFactory *dsf = calloc(1, sizeof(struct SecItemDataSourceFactory));
+    dsf->factory.copy_names = SecItemDataSourceFactoryCopyNames;
+    dsf->factory.create_datasource = SecItemDataSourceFactoryCopyDataSource;
+    dsf->factory.release = SecItemDataSourceFactoryDispose;
+    CFRetainSafe(db);
+    dsf->db = db;
+
+    return &dsf->factory;
+}
+
+SOSDataSourceFactoryRef SecItemDataSourceFactoryCreateDefault(void) {
+    return SecItemDataSourceFactoryCreate(kc_dbhandle());
+}
+
+void SecItemServerAppendItemDescription(CFMutableStringRef desc, CFDictionaryRef object) {
+    SOSObjectRef item = ds_create_with_property_list(NULL, object, NULL);
+    if (item) {
+        CFStringRef itemDesc = CFCopyDescription(item);
+        if (itemDesc) {
+            CFStringAppend(desc, itemDesc);
+            CFReleaseSafe(itemDesc);
+        }
+        CFRelease(item);
+    }
+}
+
+/* AUDIT[securityd]:
+   args_in (ok) is a caller provided, CFDictionaryRef.
+ */
+bool
+_SecServerKeychainSyncUpdate(CFDictionaryRef updates, CFErrorRef *error) {
+    // This never fails, trust us!
+    CFRetainSafe(updates);
+    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+        SOSCCHandleUpdate(updates);
+        CFReleaseSafe(updates);
+    });
+    return true;
+}
+
+//
+// Truthiness in the cloud backup/restore support.
+//
+
+static CFStringRef SOSCopyItemKey(SOSDataSourceRef ds, SOSObjectRef object, CFErrorRef *error)
+{
+    CFStringRef item_key = NULL;
+    CFDataRef digest_data = ds->copyDigest(object, error);
+    if (digest_data) {
+        item_key = CFDataCopyHexString(digest_data);
+        CFRelease(digest_data);
     }
     }
-    if (dummy) {
-        *dummy = NULL;
+    return item_key;
+}
+
+static SOSManifestRef SOSCopyManifestFromBackup(CFDictionaryRef backup)
+{
+    CFMutableDataRef manifest = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    if (backup) {
+        CFDictionaryForEach(backup, ^void (const void * key, const void * value) {
+            if (isDictionary(value)) {
+                /* converting key back to binary blob is horrible */
+                CFDataRef sha1 = CFDictionaryGetValue(value, kSecBackupHash);
+                if (isData(sha1))
+                    CFDataAppend(manifest, sha1);
+            }
+        });
     }
     }
+    return (SOSManifestRef)manifest;
+}
+
+static CFDictionaryRef
+_SecServerCopyTruthInTheCloud(CFDataRef keybag, CFDataRef password,
+    CFDictionaryRef backup, CFErrorRef *error)
+{
+    SOSManifestRef mold = NULL, mnow = NULL, mdelete = NULL, madd = NULL;
+    CFErrorRef foreachError = NULL;
+    CFDictionaryRef backup_out = NULL;
+    keybag_handle_t bag_handle;
+    if (!ks_open_keybag(keybag, password, &bag_handle, error))
+        return NULL;
+
+    CFMutableDictionaryRef backup_new = NULL;
+    SOSDataSourceRef ds = SecItemDataSourceCreate(kc_dbhandle(), true, false, error);
+    if (ds) {
+        backup_new = backup ? CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, backup) : CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+        mold = SOSCopyManifestFromBackup(backup);
+        mnow = ds->copy_manifest(ds, error);
+        SOSManifestDiff(mold, mnow, &mdelete, &madd, error);
+
+        // Delete everything from the new_backup that is no longer in the datasource according to the datasources manifest.
+        SOSManifestForEach(mdelete, ^(CFDataRef digest_data) {
+            CFStringRef deleted_item_key = CFDataCopyHexString(digest_data);
+            CFDictionaryRemoveValue(backup_new, deleted_item_key);
+            CFRelease(deleted_item_key);
+        });
+
+        if(!ds->foreach_object(ds, madd, &foreachError, ^bool(SOSObjectRef object, CFErrorRef *localError) {
+            bool ok = true;
+            CFStringRef key = SOSCopyItemKey(ds, object, localError);
+            CFTypeRef value = ds->backupObject(object, bag_handle, localError);
+
+            if (!key || !value) {
+                ok = false;
+            } else {
+                CFDictionarySetValue(backup_new, key, value);
+            }
+            CFReleaseSafe(key);
+            CFReleaseSafe(value);
+            return ok;
+        })) {
+            if(!SecErrorGetOSStatus(foreachError)==errSecDecode) {
+                if(error && *error==NULL) {
+                    *error = foreachError;
+                    foreachError = NULL;
+                }
+                goto out;
+            }
+        }
+
+        backup_out = backup_new;
+        backup_new = NULL;
+    }
+
+out:
+    if(ds)
+        ds->release(ds);
+
+    CFReleaseSafe(foreachError);
+    CFReleaseSafe(mold);
+    CFReleaseSafe(mnow);
+    CFReleaseSafe(madd);
+    CFReleaseSafe(mdelete);
+    CFReleaseSafe(backup_new);
+
+    if (!ks_close_keybag(bag_handle, error))
+        CFReleaseNull(backup_out);
+
+    return backup_out;
+}
+
+static bool
+_SecServerRestoreTruthInTheCloud(CFDataRef keybag, CFDataRef password, CFDictionaryRef backup_in, CFErrorRef *error) {
+    __block bool ok = true;
+    keybag_handle_t bag_handle;
+    if (!ks_open_keybag(keybag, password, &bag_handle, error))
+        return false;
+
+    SOSManifestRef mbackup = SOSCopyManifestFromBackup(backup_in);
+    if (mbackup) {
+        SOSDataSourceRef ds = SecItemDataSourceCreate(kc_dbhandle(), false, true, error);
+        if (ds) {
+            SOSManifestRef mnow = ds->copy_manifest(ds, error);
+            SOSManifestRef mdelete = NULL, madd = NULL;
+            SOSManifestDiff(mnow, mbackup, &mdelete, &madd, error);
+
+            // Don't delete everything in datasource not in backup.
+
+            // Add items from the backup
+            SOSManifestForEach(madd, ^void(CFDataRef e) {
+                CFDictionaryRef item = NULL;
+                CFStringRef sha1 = CFDataCopyHexString(e);
+                if (sha1) {
+                    item = CFDictionaryGetValue(backup_in, sha1);
+                    CFRelease(sha1);
+                }
+                if (item) {
+                    CFErrorRef localError = NULL;
+                    if (!ds->restoreObject(ds, bag_handle, item, &localError)) {
+                        if (SecErrorGetOSStatus(localError) == errSecDuplicateItem) {
+                            // Log and ignore duplicate item errors during restore
+                            secnotice("titc", "restore %@ not replacing existing item", item);
+                        } else {
+                            // Propagate the first other error upwards (causing the restore to fail).
+                            secerror("restore %@ failed %@", item, localError);
+                            ok = false;
+                            if (error && !*error) {
+                                *error = localError;
+                                localError = NULL;
+                            }
+                        }
+                        CFReleaseSafe(localError);
+                    }
+                }
+            });
+
+            ds->release(ds);
+            CFReleaseNull(mdelete);
+            CFReleaseNull(madd);
+            CFReleaseNull(mnow);
+        } else {
+            ok = false;
+        }
+        CFRelease(mbackup);
+    }
+
+    ok &= ks_close_keybag(bag_handle, error);
+
+    return ok;
+}
+
+
+CF_RETURNS_RETAINED CFDictionaryRef
+_SecServerBackupSyncable(CFDictionaryRef backup, CFDataRef keybag, CFDataRef password, CFErrorRef *error) {
+    require_action_quiet(isData(keybag), errOut, SecError(errSecParam, error, CFSTR("keybag %@ not a data"), keybag));
+    require_action_quiet(!backup || isDictionary(backup), errOut, SecError(errSecParam, error, CFSTR("backup %@ not a dictionary"), backup));
+    require_action_quiet(!password || isData(password), errOut, SecError(errSecParam, error, CFSTR("password %@ not a data"), password));
+
+    return _SecServerCopyTruthInTheCloud(keybag, password, backup, error);
+
+errOut:
+    return NULL;
+}
+
+bool
+_SecServerRestoreSyncable(CFDictionaryRef backup, CFDataRef keybag, CFDataRef password, CFErrorRef *error) {
+    bool ok;
+    require_action_quiet(isData(keybag), errOut, ok = SecError(errSecParam, error, CFSTR("keybag %@ not a data"), keybag));
+    require_action_quiet(isDictionary(backup), errOut, ok = SecError(errSecParam, error, CFSTR("backup %@ not a dictionary"), backup));
+    if (password) {
+        require_action_quiet(isData(password), errOut, ok = SecError(errSecParam, error, CFSTR("password not a data")));
+    }
+
+    ok = _SecServerRestoreTruthInTheCloud(keybag, password, backup, error);
 
 
-    status = errSecSuccess;
 errOut:
 errOut:
-    kc_release_dbt(dbt);
-    return status;
+    return ok;
 }
 }
+
+
+
index b3faf118f9e0bdb46f9406b2cbf14e004dbee5a6..5bb0ba9fcc1633c57ce4d939e3999a1dbe308a9d 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2007-2009 Apple Inc. All Rights Reserved.
+ * Copyright (c) 2007-2009,2012 Apple Inc. All Rights Reserved.
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
 #define _SECURITYD_SECITEMSERVER_H_
 
 #include <CoreFoundation/CoreFoundation.h>
 #define _SECURITYD_SECITEMSERVER_H_
 
 #include <CoreFoundation/CoreFoundation.h>
+#include <SecureObjectSync/SOSEngine.h>
+#include <SecureObjectSync/SOSCircle.h>
+#include <utilities/SecDb.h>
 
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-OSStatus _SecItemCopyMatching(CFDictionaryRef query, CFTypeRef *result,
-    CFArrayRef accessGroups);
-OSStatus _SecItemAdd(CFDictionaryRef attributes, CFTypeRef *result,
-    CFArrayRef accessGroups);
-OSStatus _SecItemUpdate(CFDictionaryRef query,
-    CFDictionaryRef attributesToUpdate, CFArrayRef accessGroups);
-OSStatus _SecItemDelete(CFDictionaryRef query, CFArrayRef accessGroups);
-bool _SecItemDeleteAll(void);
-OSStatus _SecServerRestoreKeychain(void);
-OSStatus _SecServerMigrateKeychain(CFArrayRef args, CFTypeRef *result);
-OSStatus _SecServerKeychainBackup(CFArrayRef args_in, CFTypeRef *args_out);
-OSStatus _SecServerKeychainRestore(CFArrayRef args_in, CFTypeRef *dummy);
-
-#if defined(__cplusplus)
-}
-#endif
+__BEGIN_DECLS
+
+bool _SecItemAdd(CFDictionaryRef attributes, CFArrayRef accessGroups, CFTypeRef *result, CFErrorRef *error);
+bool _SecItemCopyMatching(CFDictionaryRef query, CFArrayRef accessGroups, CFTypeRef *result, CFErrorRef *error);
+bool _SecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate, CFArrayRef accessGroups, CFErrorRef *error);
+bool _SecItemDelete(CFDictionaryRef query, CFArrayRef accessGroups, CFErrorRef *error);
+bool _SecItemDeleteAll(CFErrorRef *error);
+bool _SecServerRestoreKeychain(CFErrorRef *error);
+bool _SecServerMigrateKeychain(int32_t handle_in, CFDataRef data_in, int32_t *handle_out, CFDataRef *data_out, CFErrorRef *error);
+CFDataRef _SecServerKeychainBackup(CFDataRef keybag, CFDataRef passcode, CFErrorRef *error);
+bool _SecServerKeychainRestore(CFDataRef backup, CFDataRef keybag, CFDataRef passcode, CFErrorRef *error);
+bool _SecServerKeychainSyncUpdate(CFDictionaryRef updates, CFErrorRef *error);
+CFDictionaryRef _SecServerBackupSyncable(CFDictionaryRef backup, CFDataRef keybag, CFDataRef password, CFErrorRef *error);
+bool _SecServerRestoreSyncable(CFDictionaryRef backup, CFDataRef keybag, CFDataRef password, CFErrorRef *error);
+
+// Hack to log objects from inside SOS code
+void SecItemServerAppendItemDescription(CFMutableStringRef desc, CFDictionaryRef object);
+
+// These are visible for testing.
+SOSDataSourceFactoryRef SecItemDataSourceFactoryCreate(SecDbRef db);
+SOSDataSourceFactoryRef SecItemDataSourceFactoryCreateDefault(void);
+
+/* FIXME: there is a specific type for keybag handle (keybag_handle_t)
+   but it's not defined for simulator so we just use an int32_t */
+void SecItemServerSetKeychainKeybag(int32_t keybag);
+void SecItemServerResetKeychainKeybag(void);
+
+void SecItemServerSetKeychainChangedNotification(const char *notification_name);
+
+CFStringRef __SecKeychainCopyPath(void);
+
+__END_DECLS
 
 #endif /* _SECURITYD_SECITEMSERVER_H_ */
 
 #endif /* _SECURITYD_SECITEMSERVER_H_ */
index 614b3cc3f9f0b0ca84971a711ba8331408607d7e..1ae99dbed5951534f54f1ea79745b1bd66190c7e 100644 (file)
  *  SecOCSPCache.c - securityd
  */
 
  *  SecOCSPCache.c - securityd
  */
 
+#include <CoreFoundation/CFUtilities.h>
+#include <CoreFoundation/CFString.h>
 #include <securityd/SecOCSPCache.h>
 #include <securityd/SecOCSPCache.h>
-#include <security_utilities/debugging.h>
+#include <utilities/debugging.h>
 #include <Security/SecCertificateInternal.h>
 #include <Security/SecFramework.h>
 #include <Security/SecInternal.h>
 #include <Security/SecCertificateInternal.h>
 #include <Security/SecFramework.h>
 #include <Security/SecInternal.h>
-#include <sqlite3.h>
 #include <AssertMacros.h>
 #include <stdlib.h>
 #include <limits.h>
 #include <AssertMacros.h>
 #include <stdlib.h>
 #include <limits.h>
-#include <string.h>
-#include <fcntl.h>
 #include <sys/stat.h>
 #include <sys/stat.h>
-#include <errno.h>
-#include <pthread.h>
 #include <asl.h>
 #include <asl.h>
-#include "sqlutils.h"
-
-#define ocspErrorLog(args...)     asl_log(NULL, NULL, ASL_LEVEL_ERR, ## args)
-
-static const char expireSQL[] = "DELETE FROM responses WHERE expires<?";
-static const char beginTxnSQL[] = "BEGIN EXCLUSIVE TRANSACTION";
-static const char endTxnSQL[] = "COMMIT TRANSACTION";
-static const char insertResponseSQL[] = "INSERT INTO responses "
-    "(ocspResponse,responderURI,expires,lastUsed) VALUES (?,?,?,?)";
-static const char insertLinkSQL[] = "INSERT INTO ocsp (hashAlgorithm,"
-    "issuerNameHash,issuerPubKeyHash,serialNum,responseId) VALUES (?,?,?,?,?)";
-static const char selectHashAlgorithmSQL[] = "SELECT DISTINCT hashAlgorithm "
-    "FROM ocsp WHERE serialNum=?";
-static const char selectResponseSQL[] = "SELECT ocspResponse,responseId FROM "
-    "responses WHERE responseId=(SELECT responseId FROM ocsp WHERE "
-    "issuerNameHash=? AND issuerPubKeyHash=? AND serialNum=? AND hashAlgorithm=?)"
-    " ORDER BY expires DESC";
-
-#if NO_SERVER
-CF_EXPORT
-CFURLRef CFCopyHomeDirectoryURLForUser(CFStringRef uName);     /* Pass NULL for the current user's home directory */
-#endif
-
-#define kSecOCSPCachePath "/Library/Keychains/ocspcache.sqlite3";
+#include "utilities/SecDb.h"
+#include "utilities/SecFileLocations.h"
+#include "utilities/iOSforOSX.h"
+
+#define expireSQL  CFSTR("DELETE FROM responses WHERE expires<?")
+#define beginTxnSQL  CFSTR("BEGIN EXCLUSIVE TRANSACTION")
+#define endTxnSQL  CFSTR("COMMIT TRANSACTION")
+#define insertResponseSQL  CFSTR("INSERT INTO responses " \
+    "(ocspResponse,responderURI,expires,lastUsed) VALUES (?,?,?,?)")
+#define insertLinkSQL  CFSTR("INSERT INTO ocsp (hashAlgorithm," \
+    "issuerNameHash,issuerPubKeyHash,serialNum,responseId) VALUES (?,?,?,?,?)")
+#define selectHashAlgorithmSQL  CFSTR("SELECT DISTINCT hashAlgorithm " \
+    "FROM ocsp WHERE serialNum=?")
+#define selectResponseSQL  CFSTR("SELECT ocspResponse,responseId FROM " \
+    "responses WHERE responseId=(SELECT responseId FROM ocsp WHERE " \
+    "issuerNameHash=? AND issuerPubKeyHash=? AND serialNum=? AND hashAlgorithm=?)" \
+    " ORDER BY expires DESC")
+
+
+#define kSecOCSPCacheFileName CFSTR("ocspcache.sqlite3")
+
+
+// MARK; -
+// MARK: SecOCSPCacheDb
+
+static SecDbRef SecOCSPCacheDbCreate(CFStringRef path) {
+    return SecDbCreate(path, ^bool (SecDbConnectionRef dbconn, bool didCreate, CFErrorRef *error) {
+        __block bool ok;
+        ok = (SecDbExec(dbconn, CFSTR("PRAGMA auto_vacuum = FULL"), error) &&
+              SecDbExec(dbconn, CFSTR("PRAGMA journal_mode = WAL"), error));
+        CFErrorRef localError = NULL;
+        if (ok && !SecDbWithSQL(dbconn, selectHashAlgorithmSQL /* expireSQL */, &localError, NULL) && CFErrorGetCode(localError) == SQLITE_ERROR) {
+            /* SecDbWithSQL returns SQLITE_ERROR if the table we are preparing the above statement for doesn't exist. */
+            ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, error, ^(bool *commit) {
+                ok = SecDbExec(dbconn,
+                    CFSTR("CREATE TABLE ocsp("
+                          "issuerNameHash BLOB NOT NULL,"
+                          "issuerPubKeyHash BLOB NOT NULL,"
+                          "serialNum BLOB NOT NULL,"
+                          "hashAlgorithm BLOB NOT NULL,"
+                          "responseId INTEGER NOT NULL"
+                          ");"
+                          "CREATE INDEX iResponseId ON ocsp(responseId);"
+                          "CREATE INDEX iserialNum ON ocsp(serialNum);"
+                          "CREATE INDEX iSNumDAlg ON ocsp(serialNum,hashAlgorithm);"
+                          "CREATE TABLE responses("
+                          "responseId INTEGER PRIMARY KEY,"
+                          "ocspResponse BLOB NOT NULL,"
+                          "responderURI BLOB,"
+                          "expires DOUBLE NOT NULL,"
+                          "lastUsed DOUBLE NOT NULL"
+                          ");"
+                          "CREATE INDEX iexpires ON responses(expires);"
+                          "CREATE TRIGGER tocspdel BEFORE DELETE ON responses FOR EACH ROW "
+                          "BEGIN "
+                          "DELETE FROM ocsp WHERE responseId=OLD.responseId;"
+                          " END;"), error);
+                *commit = ok;
+            });
+        }
+        CFReleaseSafe(localError);
+        if (!ok)
+            secerror("%s failed: %@", didCreate ? "Create" : "Open", error ? *error : NULL);
+        return ok;
+    });
+}
+
+// MARK; -
+// MARK: SecOCSPCache
 
 typedef struct __SecOCSPCache *SecOCSPCacheRef;
 struct __SecOCSPCache {
 
 typedef struct __SecOCSPCache *SecOCSPCacheRef;
 struct __SecOCSPCache {
-       sqlite3 *s3h;
-       sqlite3_stmt *expire;
-       sqlite3_stmt *beginTxn;
-       sqlite3_stmt *endTxn;
-       sqlite3_stmt *insertResponse;
-       sqlite3_stmt *insertLink;
-       sqlite3_stmt *selectHashAlgorithm;
-       sqlite3_stmt *selectResponse;
-    bool in_transaction;
+       SecDbRef db;
 };
 
 };
 
-static pthread_once_t kSecOCSPCacheOnce = PTHREAD_ONCE_INIT;
+static dispatch_once_t kSecOCSPCacheOnce;
 static SecOCSPCacheRef kSecOCSPCache = NULL;
 
 static SecOCSPCacheRef kSecOCSPCache = NULL;
 
-/* @@@ Duplicated from SecTrustStore.c */
-static int sec_create_path(const char *path)
-{
-       char pathbuf[PATH_MAX];
-       size_t pos, len = strlen(path);
-       if (len == 0 || len > PATH_MAX)
-               return SQLITE_CANTOPEN;
-       memcpy(pathbuf, path, len);
-       for (pos = len-1; pos > 0; --pos)
-       {
-               /* Search backwards for trailing '/'. */
-               if (pathbuf[pos] == '/')
-               {
-                       pathbuf[pos] = '\0';
-                       /* Attempt to create parent directories of the database. */
-                       if (!mkdir(pathbuf, 0777))
-                               break;
-                       else
-                       {
-                               int err = errno;
-                               if (err == EEXIST)
-                                       return 0;
-                               if (err == ENOTDIR)
-                                       return SQLITE_CANTOPEN;
-                               if (err == EROFS)
-                                       return SQLITE_READONLY;
-                               if (err == EACCES)
-                                       return SQLITE_PERM;
-                               if (err == ENOSPC || err == EDQUOT)
-                                       return SQLITE_FULL;
-                               if (err == EIO)
-                                       return SQLITE_IOERR;
-
-                               /* EFAULT || ELOOP | ENAMETOOLONG || something else */
-                               return SQLITE_INTERNAL;
-                       }
-               }
-       }
-       return SQLITE_OK;
-}
-
-static int sec_sqlite3_open(const char *db_name, sqlite3 **s3h,
-       bool create_path)
-{
-       int s3e;
-       s3e = sqlite3_open(db_name, s3h);
-       if (s3e == SQLITE_CANTOPEN && create_path) {
-               /* Make sure the path to db_name exists and is writable, then
-                  try again. */
-               s3e = sec_create_path(db_name);
-               if (!s3e)
-                       s3e = sqlite3_open(db_name, s3h);
-       }
-
-       return s3e;
-}
-
-static int sec_sqlite3_reset(sqlite3_stmt *stmt, int s3e) {
-    int s3e2;
-    if (s3e == SQLITE_ROW || s3e == SQLITE_DONE)
-        s3e = SQLITE_OK;
-    s3e2 = sqlite3_reset(stmt);
-    if (s3e2 && !s3e)
-        s3e = s3e2;
-    s3e2 = sqlite3_clear_bindings(stmt);
-    if (s3e2 && !s3e)
-        s3e = s3e2;
-    return s3e;
-}
-
-static int SecOCSPCacheEnsureTxn(SecOCSPCacheRef this) {
-    int s3e, s3e2;
-
-    if (this->in_transaction)
-        return SQLITE_OK;
-
-    s3e = sqlite3_step(this->beginTxn);
-    if (s3e == SQLITE_DONE) {
-        this->in_transaction = true;
-        s3e = SQLITE_OK;
-    } else {
-        secdebug("ocspcache", "sqlite3_step returned [%d]: %s", s3e,
-            sqlite3_errmsg(this->s3h));
-    }
-    s3e2 = sqlite3_reset(this->beginTxn);
-    if (s3e2 && !s3e)
-        s3e = s3e2;
-
-    return s3e;
-}
-
-static int SecOCSPCacheCommitTxn(SecOCSPCacheRef this) {
-    int s3e, s3e2;
-
-    if (!this->in_transaction)
-        return SQLITE_OK;
-
-    s3e = sqlite3_step(this->endTxn);
-    if (s3e == SQLITE_DONE) {
-        this->in_transaction = false;
-        s3e = SQLITE_OK;
-    } else {
-        secdebug("ocspcache", "sqlite3_step returned [%d]: %s", s3e,
-            sqlite3_errmsg(this->s3h));
-    }
-    s3e2 = sqlite3_reset(this->endTxn);
-    if (s3e2 && !s3e)
-        s3e = s3e2;
-
-    return s3e;
-}
-
-static SecOCSPCacheRef SecOCSPCacheCreate(const char *db_name) {
+static SecOCSPCacheRef SecOCSPCacheCreate(CFStringRef db_name) {
        SecOCSPCacheRef this;
        SecOCSPCacheRef this;
-       int s3e;
-    bool create = true;
 
        require(this = (SecOCSPCacheRef)malloc(sizeof(struct __SecOCSPCache)), errOut);
 
        require(this = (SecOCSPCacheRef)malloc(sizeof(struct __SecOCSPCache)), errOut);
-       require_noerr(s3e = sec_sqlite3_open(db_name, &this->s3h, create), errOut);
-    this->in_transaction = false;
-
-       s3e = sqlite3_prepare_v2(this->s3h, beginTxnSQL, sizeof(beginTxnSQL),
-               &this->beginTxn, NULL);
-       require_noerr(s3e, errOut);
-       s3e = sqlite3_prepare_v2(this->s3h, endTxnSQL, sizeof(endTxnSQL),
-               &this->endTxn, NULL);
-       require_noerr(s3e, errOut);
-
-       s3e = sqlite3_prepare_v2(this->s3h, expireSQL, sizeof(expireSQL),
-               &this->expire, NULL);
-       if (create && s3e == SQLITE_ERROR) {
-        s3e = SecOCSPCacheEnsureTxn(this);
-               require_noerr(s3e, errOut);
-
-               /* sqlite3_prepare returns SQLITE_ERROR if the table we are
-                  compiling this statement for doesn't exist. */
-               char *errmsg = NULL;
-               s3e = sqlite3_exec(this->s3h,
-                       "CREATE TABLE ocsp("
-                       "issuerNameHash BLOB NOT NULL,"
-                       "issuerPubKeyHash BLOB NOT NULL,"
-                       "serialNum BLOB NOT NULL,"
-                       "hashAlgorithm BLOB NOT NULL,"
-                       "responseId INTEGER NOT NULL"
-                       ");"
-                       "CREATE INDEX iResponseId ON ocsp(responseId);"
-                       "CREATE INDEX iserialNum ON ocsp(serialNum);"
-                       "CREATE INDEX iSNumDAlg ON ocsp(serialNum,hashAlgorithm);"
-                       "CREATE TABLE responses("
-            "responseId INTEGER PRIMARY KEY,"
-                       "ocspResponse BLOB NOT NULL,"
-                       "responderURI BLOB,"
-            "expires DOUBLE NOT NULL,"
-            "lastUsed DOUBLE NOT NULL"
-                       ");"
-                       "CREATE INDEX iexpires ON responses(expires);"
-            "CREATE TRIGGER tocspdel BEFORE DELETE ON responses FOR EACH ROW "
-            "BEGIN "
-            "DELETE FROM ocsp WHERE responseId=OLD.responseId;"
-            " END;"
-                       , NULL, NULL, &errmsg);
-               if (errmsg) {
-                       ocspErrorLog("ocsp db CREATE TABLES: %s", errmsg);
-                       sqlite3_free(errmsg);
-               }
-               require_noerr(s3e, errOut);
-        s3e = sqlite3_prepare_v2(this->s3h, expireSQL, sizeof(expireSQL),
-            &this->expire, NULL);
-       }
-       require_noerr(s3e, errOut);
-       s3e = sqlite3_prepare_v2(this->s3h, insertResponseSQL, sizeof(insertResponseSQL),
-               &this->insertResponse, NULL);
-       require_noerr(s3e, errOut);
-       s3e = sqlite3_prepare_v2(this->s3h, insertLinkSQL, sizeof(insertLinkSQL),
-               &this->insertLink, NULL);
-       require_noerr(s3e, errOut);
-       s3e = sqlite3_prepare_v2(this->s3h, selectHashAlgorithmSQL, sizeof(selectHashAlgorithmSQL),
-               &this->selectHashAlgorithm, NULL);
-       require_noerr(s3e, errOut);
-       s3e = sqlite3_prepare_v2(this->s3h, selectResponseSQL, sizeof(selectResponseSQL),
-               &this->selectResponse, NULL);
-       require_noerr(s3e, errOut);
+    require(this->db = SecOCSPCacheDbCreate(db_name), errOut);
 
        return this;
 
 errOut:
        if (this) {
 
        return this;
 
 errOut:
        if (this) {
-               sqlite3_close(this->s3h);
+        CFReleaseSafe(this->db);
                free(this);
        }
 
        return NULL;
 }
 
                free(this);
        }
 
        return NULL;
 }
 
-static void SecOCSPCacheInit(void) {
-       static const char *path = kSecOCSPCachePath;
-#if NO_SERVER
-    /* Added this block of code back to keep the tests happy for now. */
-       const char *home = getenv("HOME");
-       char buffer[PATH_MAX];
-       size_t homeLen;
-       size_t pathLen = strlen(path);
-       if (home) {
-               homeLen = strlen(home);
-               if (homeLen + pathLen >= sizeof(buffer)) {
-                       return;
-               }
-
-               strlcpy(buffer, home, sizeof(buffer));
-       } else {
-               CFURLRef homeURL = CFCopyHomeDirectoryURLForUser(NULL);
-               if (!homeURL)
-                       return;
-
-               CFURLGetFileSystemRepresentation(homeURL, true, (uint8_t *)buffer,
-                       sizeof(buffer));
-               CFRelease(homeURL);
-               homeLen = strlen(buffer);
-               buffer[homeLen] = '\0';
-               if (homeLen + pathLen >= sizeof(buffer)) {
-                       return;
-               }
-       }
-
-       strlcat(buffer, path, sizeof(buffer));
-
-    path = buffer;
-
-#endif
+static CFStringRef SecOCSPCacheCopyPath(void) {
+    CFStringRef ocspRelPath = kSecOCSPCacheFileName;
+    CFURLRef ocspURL = SecCopyURLForFileInKeychainDirectory(ocspRelPath);
+    CFStringRef ocspPath = NULL;
+    if (ocspURL) {
+        ocspPath = CFURLCopyFileSystemPath(ocspURL, kCFURLPOSIXPathStyle);
+        CFRelease(ocspURL);
+    }
+    return ocspPath;
+}
 
 
-    kSecOCSPCache = SecOCSPCacheCreate(path);
-    if (kSecOCSPCache)
-        atexit(SecOCSPCacheGC);
+static void SecOCSPCacheWith(void(^cacheJob)(SecOCSPCacheRef cache)) {
+    dispatch_once(&kSecOCSPCacheOnce, ^{
+        CFStringRef dbPath = SecOCSPCacheCopyPath();
+        if (dbPath) {
+            kSecOCSPCache = SecOCSPCacheCreate(dbPath);
+            CFRelease(dbPath);
+        }
+    });
+    // Do pre job run work here (cancel idle timers etc.)
+    cacheJob(kSecOCSPCache);
+    // Do post job run work here (gc timer, etc.)
 }
 
 /* Instance implemenation. */
 
 static void _SecOCSPCacheAddResponse(SecOCSPCacheRef this,
     SecOCSPResponseRef ocspResponse, CFURLRef localResponderURI) {
 }
 
 /* Instance implemenation. */
 
 static void _SecOCSPCacheAddResponse(SecOCSPCacheRef this,
     SecOCSPResponseRef ocspResponse, CFURLRef localResponderURI) {
-    int s3e;
-
     secdebug("ocspcache", "adding response from %@", localResponderURI);
     secdebug("ocspcache", "adding response from %@", localResponderURI);
-    require_noerr(s3e = SecOCSPCacheEnsureTxn(this), errOut);
-
     /* responses.ocspResponse */
     CFDataRef responseData = SecOCSPResponseGetData(ocspResponse);
     /* responses.ocspResponse */
     CFDataRef responseData = SecOCSPResponseGetData(ocspResponse);
-    s3e = sqlite3_bind_blob_wrapper(this->insertResponse, 1,
-        CFDataGetBytePtr(responseData),
-        CFDataGetLength(responseData), SQLITE_TRANSIENT);
-
-    /* responses.responderURI */
-    if (!s3e) {
-        CFDataRef uriData = NULL;
-        if (localResponderURI) {
-            uriData = CFURLCreateData(kCFAllocatorDefault, localResponderURI,
-                kCFStringEncodingUTF8, false);
-        }
-        if (uriData) {
-            s3e = sqlite3_bind_blob_wrapper(this->insertResponse, 2,
-                    CFDataGetBytePtr(uriData),
-                    CFDataGetLength(uriData), SQLITE_TRANSIENT);
-            CFRelease(uriData);
-        } else {
-            s3e = sqlite3_bind_null(this->insertResponse, 2);
-        }
-    }
-    /* responses.expires */
-    if (!s3e) s3e = sqlite3_bind_double(this->insertResponse, 3,
-            SecOCSPResponseGetExpirationTime(ocspResponse));
-    /* responses.lastUsed */
-    if (!s3e) s3e = sqlite3_bind_double(this->insertResponse, 4,
-            SecOCSPResponseVerifyTime(ocspResponse));
-
-    /* Execute the insert statement. */
-    if (!s3e) s3e = sqlite3_step(this->insertResponse);
-    require_noerr(s3e = sec_sqlite3_reset(this->insertResponse, s3e), errOut);
-
-    sqlite3_int64 responseId = sqlite3_last_insert_rowid(this->s3h);
-
-    /* Now add a link record for every singleResponse in the ocspResponse. */
-    SecAsn1OCSPSingleResponse **responses;
-    for (responses = ocspResponse->responseData.responses;
-        *responses; ++responses) {
-               SecAsn1OCSPSingleResponse *resp = *responses;
-        SecAsn1OCSPCertID *certId = &resp->certID;
-
-        s3e = sqlite3_bind_blob_wrapper(this->insertLink, 1,
-            certId->algId.algorithm.Data, certId->algId.algorithm.Length,
-            SQLITE_TRANSIENT);
-        if (!s3e) s3e = sqlite3_bind_blob_wrapper(this->insertLink, 2,
-            certId->issuerNameHash.Data, certId->issuerNameHash.Length,
-            SQLITE_TRANSIENT);
-        if (!s3e) s3e = sqlite3_bind_blob_wrapper(this->insertLink, 3,
-            certId->issuerPubKeyHash.Data, certId->issuerPubKeyHash.Length,
-            SQLITE_TRANSIENT);
-        if (!s3e) s3e = sqlite3_bind_blob_wrapper(this->insertLink, 4,
-            certId->serialNumber.Data, certId->serialNumber.Length,
-            SQLITE_TRANSIENT);
-        if (!s3e) s3e = sqlite3_bind_int64(this->insertLink, 5,
-            responseId);
-
-        /* Execute the insert statement. */
-        if (!s3e) s3e = sqlite3_step(this->insertLink);
-        require_noerr(s3e = sec_sqlite3_reset(this->insertLink, s3e), errOut);
-    }
-
-errOut:
-    if (s3e) {
-        ocspErrorLog("ocsp cache add failed: %s", sqlite3_errmsg(this->s3h));
-        /* @@@ Blow away the cache and create a new db. */
+    __block CFErrorRef localError = NULL;
+    __block bool ok = true;
+    ok &= SecDbPerformWrite(this->db, &localError, ^(SecDbConnectionRef dbconn) {
+        ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, &localError, ^(bool *commit) {
+            __block sqlite3_int64 responseId;
+            ok = SecDbWithSQL(dbconn, insertResponseSQL, &localError, ^bool(sqlite3_stmt *insertResponse) {
+                if (ok)
+                    ok = SecDbBindBlob(insertResponse, 1,
+                                       CFDataGetBytePtr(responseData),
+                                       CFDataGetLength(responseData),
+                                       SQLITE_TRANSIENT, &localError);
+
+                /* responses.responderURI */
+                if (ok) {
+                    CFDataRef uriData = NULL;
+                    if (localResponderURI) {
+                        uriData = CFURLCreateData(kCFAllocatorDefault, localResponderURI,
+                                                  kCFStringEncodingUTF8, false);
+                    }
+                    if (uriData) {
+                        ok = SecDbBindBlob(insertResponse, 2,
+                                           CFDataGetBytePtr(uriData),
+                                           CFDataGetLength(uriData),
+                                           SQLITE_TRANSIENT, &localError);
+                        CFRelease(uriData);
+                    } else {
+                        // Since we use SecDbClearBindings this shouldn't be needed.
+                        //ok = SecDbBindNull(insertResponse, 2, &localError);
+                    }
+                }
+                /* responses.expires */
+                if (ok)
+                    ok = SecDbBindDouble(insertResponse, 3,
+                                         SecOCSPResponseGetExpirationTime(ocspResponse),
+                                         &localError);
+                /* responses.lastUsed */
+                if (ok)
+                    ok = SecDbBindDouble(insertResponse, 4,
+                                         SecOCSPResponseVerifyTime(ocspResponse),
+                                         &localError);
+
+                /* Execute the insert statement. */
+                if (ok)
+                    ok = SecDbStep(dbconn, insertResponse, &localError, NULL);
+
+                responseId = sqlite3_last_insert_rowid(SecDbHandle(dbconn));
+                return ok;
+            });
+
+            /* Now add a link record for every singleResponse in the ocspResponse. */
+            if (ok) ok = SecDbWithSQL(dbconn, insertLinkSQL, &localError, ^bool(sqlite3_stmt *insertLink) {
+                SecAsn1OCSPSingleResponse **responses;
+                for (responses = ocspResponse->responseData.responses;
+                     *responses; ++responses) {
+                    SecAsn1OCSPSingleResponse *resp = *responses;
+                    SecAsn1OCSPCertID *certId = &resp->certID;
+                    if (ok) ok = SecDbBindBlob(insertLink, 1,
+                                               certId->algId.algorithm.Data,
+                                               certId->algId.algorithm.Length,
+                                               SQLITE_TRANSIENT, &localError);
+                    if (ok) ok = SecDbBindBlob(insertLink, 2,
+                                               certId->issuerNameHash.Data,
+                                               certId->issuerNameHash.Length,
+                                               SQLITE_TRANSIENT, &localError);
+                    if (ok) ok = SecDbBindBlob(insertLink, 3,
+                                               certId->issuerPubKeyHash.Data,
+                                               certId->issuerPubKeyHash.Length,
+                                               SQLITE_TRANSIENT, &localError);
+                    if (ok) ok = SecDbBindBlob(insertLink, 4,
+                                               certId->serialNumber.Data,
+                                               certId->serialNumber.Length,
+                                               SQLITE_TRANSIENT, &localError);
+                    if (ok) ok = SecDbBindInt64(insertLink, 5, responseId, &localError);
+
+                    /* Execute the insert statement. */
+                    if (ok) ok = SecDbStep(dbconn, insertLink, &localError, NULL);
+                    if (ok) ok = SecDbReset(insertLink, &localError);
+                }
+                return ok;
+            });
+            if (!ok)
+                *commit = false;
+        });
+    });
+    if (!ok) {
+        secerror("_SecOCSPCacheAddResponse failed: %@", localError);
     }
     }
+    CFReleaseSafe(localError);
 }
 
 static SecOCSPResponseRef _SecOCSPCacheCopyMatching(SecOCSPCacheRef this,
     SecOCSPRequestRef request, CFURLRef responderURI) {
 }
 
 static SecOCSPResponseRef _SecOCSPCacheCopyMatching(SecOCSPCacheRef this,
     SecOCSPRequestRef request, CFURLRef responderURI) {
-    SecOCSPResponseRef response = NULL;
     const DERItem *publicKey;
     CFDataRef issuer = NULL;
     CFDataRef serial = NULL;
     const DERItem *publicKey;
     CFDataRef issuer = NULL;
     CFDataRef serial = NULL;
-    int s3e = SQLITE_ERROR;
+    __block SecOCSPResponseRef response = NULL;
+    __block CFErrorRef localError = NULL;
+    __block bool ok = true;
 
     require(publicKey = SecCertificateGetPublicKeyData(request->issuer), errOut);
     require(issuer = SecCertificateCopyIssuerSequence(request->certificate), errOut);
     require(serial = SecCertificateCopySerialNumber(request->certificate), errOut);
 
     require(publicKey = SecCertificateGetPublicKeyData(request->issuer), errOut);
     require(issuer = SecCertificateCopyIssuerSequence(request->certificate), errOut);
     require(serial = SecCertificateCopySerialNumber(request->certificate), errOut);
-    s3e = sqlite3_bind_blob_wrapper(this->selectHashAlgorithm, 1,
-        CFDataGetBytePtr(serial), CFDataGetLength(serial), SQLITE_TRANSIENT);
-    while (!s3e && !response &&
-        (s3e = sqlite3_step(this->selectHashAlgorithm)) == SQLITE_ROW) {
-        SecAsn1Oid algorithm;
-        algorithm.Data = (uint8_t *)sqlite3_column_blob(this->selectHashAlgorithm, 0);
-        algorithm.Length = sqlite3_column_bytes(this->selectHashAlgorithm, 0);
-
-        /* Calcluate the issuerKey and issuerName digests using the returned
-           hashAlgorithm. */
-        CFDataRef issuerNameHash = SecDigestCreate(kCFAllocatorDefault,
-            &algorithm, NULL, CFDataGetBytePtr(issuer), CFDataGetLength(issuer));
-        CFDataRef issuerPubKeyHash = SecDigestCreate(kCFAllocatorDefault,
-            &algorithm, NULL, publicKey->data, publicKey->length);
-
-        require(issuerNameHash && issuerPubKeyHash, nextResponse);
-
-        /* Now we have the serial, algorithm, issuerNameHash and
-           issuerPubKeyHash so let's lookup the db entry. */
-        s3e = sqlite3_bind_blob_wrapper(this->selectResponse, 1, CFDataGetBytePtr(issuerNameHash),
-            CFDataGetLength(issuerNameHash), SQLITE_TRANSIENT);
-        if (!s3e) s3e = sqlite3_bind_blob_wrapper(this->selectResponse, 2, CFDataGetBytePtr(issuerPubKeyHash),
-            CFDataGetLength(issuerPubKeyHash), SQLITE_TRANSIENT);
-        if (!s3e) s3e = sqlite3_bind_blob_wrapper(this->selectResponse, 3, CFDataGetBytePtr(serial),
-            CFDataGetLength(serial), SQLITE_TRANSIENT);
-        if (!s3e) s3e = sqlite3_bind_blob_wrapper(this->selectResponse, 4, algorithm.Data,
-            algorithm.Length, SQLITE_TRANSIENT);
-
-        if (!s3e) s3e = sqlite3_step(this->selectResponse);
-        if (s3e == SQLITE_ROW) {
-            /* Found an entry! */
-            secdebug("ocspcache", "found cached response");
-
-            const void *respData = sqlite3_column_blob(this->selectResponse, 0);
-            int respLen = sqlite3_column_bytes(this->selectResponse, 0);
-            CFDataRef resp = CFDataCreate(kCFAllocatorDefault, respData, respLen);
-            if (resp) {
-                response = SecOCSPResponseCreate(resp, NULL_TIME);
-                CFRelease(resp);
-            }
-            if (response) {
-                //sqlite3_int64 responseId = sqlite3_column_int64(this->selectResponse, 1);
-                /* @@@ Update the lastUsed field in the db. */
-            }
-        }
 
 
-nextResponse:
-        s3e = sec_sqlite3_reset(this->selectResponse, s3e);
-        CFReleaseSafe(issuerNameHash);
-        CFReleaseSafe(issuerPubKeyHash);
-    }
-    require_noerr(s3e = sec_sqlite3_reset(this->selectHashAlgorithm, s3e), errOut);
+    ok &= SecDbPerformRead(this->db, &localError, ^(SecDbConnectionRef dbconn) {
+        ok &= SecDbWithSQL(dbconn, selectHashAlgorithmSQL, &localError, ^bool(sqlite3_stmt *selectHash) {
+            ok = SecDbBindBlob(selectHash, 1, CFDataGetBytePtr(serial), CFDataGetLength(serial), SQLITE_TRANSIENT, &localError);
+            ok &= SecDbStep(dbconn, selectHash, &localError, ^(bool *stopHash) {
+                SecAsn1Oid algorithm;
+                algorithm.Data = (uint8_t *)sqlite3_column_blob(selectHash, 0);
+                algorithm.Length = sqlite3_column_bytes(selectHash, 0);
+
+                /* Calcluate the issuerKey and issuerName digests using the returned
+                 hashAlgorithm. */
+                CFDataRef issuerNameHash = SecDigestCreate(kCFAllocatorDefault,
+                                                           &algorithm, NULL, CFDataGetBytePtr(issuer), CFDataGetLength(issuer));
+                CFDataRef issuerPubKeyHash = SecDigestCreate(kCFAllocatorDefault,
+                                                             &algorithm, NULL, publicKey->data, publicKey->length);
+
+                if (issuerNameHash && issuerPubKeyHash && ok) ok &= SecDbWithSQL(dbconn, selectResponseSQL, &localError, ^bool(sqlite3_stmt *selectResponse) {
+                    /* Now we have the serial, algorithm, issuerNameHash and
+                     issuerPubKeyHash so let's lookup the db entry. */
+                    if (ok) ok = SecDbBindBlob(selectResponse, 1, CFDataGetBytePtr(issuerNameHash),
+                                               CFDataGetLength(issuerNameHash), SQLITE_TRANSIENT, &localError);
+                    if (ok) ok = SecDbBindBlob(selectResponse, 2, CFDataGetBytePtr(issuerPubKeyHash),
+                                               CFDataGetLength(issuerPubKeyHash), SQLITE_TRANSIENT, &localError);
+                    if (ok) ok = SecDbBindBlob(selectResponse, 3, CFDataGetBytePtr(serial),
+                                               CFDataGetLength(serial), SQLITE_TRANSIENT, &localError);
+                    if (ok) ok = SecDbBindBlob(selectResponse, 4, algorithm.Data,
+                                               algorithm.Length, SQLITE_TRANSIENT, &localError);
+                    if (ok) ok &= SecDbStep(dbconn, selectResponse, &localError, ^(bool *stopResponse) {
+                        /* Found an entry! */
+                        secdebug("ocspcache", "found cached response");
+                        CFDataRef resp = CFDataCreate(kCFAllocatorDefault,
+                                                      sqlite3_column_blob(selectResponse, 0),
+                                                      sqlite3_column_bytes(selectResponse, 0));
+                        if (resp) {
+                            response = SecOCSPResponseCreate(resp, NULL_TIME);
+                            CFRelease(resp);
+                        }
+                        if (response) {
+                            //sqlite3_int64 responseId = sqlite3_column_int64(this->selectResponse, 1);
+                            /* @@@ Update the lastUsed field in the db. */
+                        }
+                    });
+                    return ok;
+                });
+
+                CFReleaseSafe(issuerNameHash);
+                CFReleaseSafe(issuerPubKeyHash);
+            });
+            return ok;
+        });
+    });
 
 errOut:
     CFReleaseSafe(serial);
     CFReleaseSafe(issuer);
 
 
 errOut:
     CFReleaseSafe(serial);
     CFReleaseSafe(issuer);
 
-    if (s3e) {
-        ocspErrorLog("ocsp cache lookup failed: %s", sqlite3_errmsg(this->s3h));
-        /* @@@ Blow away the cache and create a new db. */
-
+    if (!ok) {
+        secerror("ocsp cache lookup failed: %@", localError);
         if (response) {
             SecOCSPResponseFinalize(response);
             response = NULL;
         }
     }
         if (response) {
             SecOCSPResponseFinalize(response);
             response = NULL;
         }
     }
+    CFReleaseSafe(localError);
 
     secdebug("ocspcache", "returning %s", (response ? "cached response" : "NULL"));
 
 
     secdebug("ocspcache", "returning %s", (response ? "cached response" : "NULL"));
 
@@ -478,51 +336,47 @@ errOut:
 }
 
 static void _SecOCSPCacheGC(SecOCSPCacheRef this) {
 }
 
 static void _SecOCSPCacheGC(SecOCSPCacheRef this) {
-    int s3e;
-
-    require_noerr(s3e = SecOCSPCacheEnsureTxn(this), errOut);
     secdebug("ocspcache", "expiring stale responses");
     secdebug("ocspcache", "expiring stale responses");
-    s3e = sqlite3_bind_double(this->expire, 1, CFAbsoluteTimeGetCurrent());
-    if (!s3e) s3e = sqlite3_step(this->expire);
-    require_noerr(s3e = sec_sqlite3_reset(this->expire, s3e), errOut);
-    require_noerr(s3e = SecOCSPCacheCommitTxn(this), errOut);
 
 
-errOut:
-    if (s3e) {
-        ocspErrorLog("ocsp cache expire failed: %s", sqlite3_errmsg(this->s3h));
-        /* @@@ Blow away the cache and create a new db. */
+    __block CFErrorRef localError = NULL;
+    __block bool ok = true;
+    ok &= SecDbPerformWrite(this->db, &localError, ^(SecDbConnectionRef dbconn) {
+        ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, &localError, ^(bool *commit) {
+            ok &= SecDbWithSQL(dbconn, expireSQL, &localError, ^bool(sqlite3_stmt *expire) {
+                return SecDbBindDouble(expire, 1, CFAbsoluteTimeGetCurrent(), &localError) &&
+                    SecDbStep(dbconn, expire, &localError, NULL);
+            });
+            *commit = ok;
+        });
+    });
+
+    if (!ok) {
+        secerror("ocsp cache expire failed: %@", localError);
     }
     }
+    CFReleaseSafe(localError);
 }
 
 static void _SecOCSPCacheFlush(SecOCSPCacheRef this) {
 }
 
 static void _SecOCSPCacheFlush(SecOCSPCacheRef this) {
-    int s3e;
     secdebug("ocspcache", "flushing pending changes");
     secdebug("ocspcache", "flushing pending changes");
-    s3e = SecOCSPCacheCommitTxn(this);
-
-    if (s3e) {
-        ocspErrorLog("ocsp cache flush failed: %s", sqlite3_errmsg(this->s3h));
-        /* @@@ Blow away the cache and create a new db. */
-    }
+    // NOOP since we use WAL now and commit right away.
 }
 
 /* Public API */
 
 void SecOCSPCacheAddResponse(SecOCSPResponseRef response,
     CFURLRef localResponderURI) {
 }
 
 /* Public API */
 
 void SecOCSPCacheAddResponse(SecOCSPResponseRef response,
     CFURLRef localResponderURI) {
-    pthread_once(&kSecOCSPCacheOnce, SecOCSPCacheInit);
-    if (!kSecOCSPCache)
-        return;
-
-    _SecOCSPCacheAddResponse(kSecOCSPCache, response, localResponderURI);
+    SecOCSPCacheWith(^(SecOCSPCacheRef cache) {
+        _SecOCSPCacheAddResponse(cache, response, localResponderURI);
+    });
 }
 
 SecOCSPResponseRef SecOCSPCacheCopyMatching(SecOCSPRequestRef request,
     CFURLRef localResponderURI /* may be NULL */) {
 }
 
 SecOCSPResponseRef SecOCSPCacheCopyMatching(SecOCSPRequestRef request,
     CFURLRef localResponderURI /* may be NULL */) {
-    pthread_once(&kSecOCSPCacheOnce, SecOCSPCacheInit);
-    if (!kSecOCSPCache)
-        return NULL;
-
-    return _SecOCSPCacheCopyMatching(kSecOCSPCache, request, localResponderURI);
+    __block SecOCSPResponseRef response = NULL;
+    SecOCSPCacheWith(^(SecOCSPCacheRef cache) {
+        response = _SecOCSPCacheCopyMatching(cache, request, localResponderURI);
+    });
+    return response;
 }
 
 /* This should be called on a normal non emergency exit. This function
 }
 
 /* This should be called on a normal non emergency exit. This function
index 2bd0dc4cd23ce9e7404664b3687d1312ed375884..99813329dc3cf5116b9c5f95c1a11feeffb26e5d 100644 (file)
@@ -36,9 +36,7 @@
 #include <securityd/SecOCSPResponse.h>
 #include <CoreFoundation/CFURL.h>
 
 #include <securityd/SecOCSPResponse.h>
 #include <CoreFoundation/CFURL.h>
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 
 void SecOCSPCacheAddResponse(SecOCSPResponseRef response,
 
 
 void SecOCSPCacheAddResponse(SecOCSPResponseRef response,
@@ -53,9 +51,7 @@ void SecOCSPCacheGC(void);
 /* Call this periodically or perhaps when we are exiting due to low memory. */
 void SecOCSPCacheFlush(void);
 
 /* Call this periodically or perhaps when we are exiting due to low memory. */
 void SecOCSPCacheFlush(void);
 
-#if defined(__cplusplus)
-}
-#endif
+__END_DECLS
 
 #endif /* _SECURITY_SECOCSPCACHE_H_ */
 
 
 #endif /* _SECURITY_SECOCSPCACHE_H_ */
 
index 75d74f3e5975e60a5e2c91871d4b89ef7839e863..d69df8837a9c2eddc92f3f2db7549b6c9af2ee1b 100644 (file)
@@ -28,7 +28,7 @@
 #include <securityd/SecOCSPRequest.h>
 #include <Security/SecCertificateInternal.h>
 #include <AssertMacros.h>
 #include <securityd/SecOCSPRequest.h>
 #include <Security/SecCertificateInternal.h>
 #include <AssertMacros.h>
-#include <security_utilities/debugging.h>
+#include <utilities/debugging.h>
 #include <security_asn1/SecAsn1Coder.h>
 #include <security_asn1/ocspTemplates.h>
 #include <security_asn1/oidsalg.h>
 #include <security_asn1/SecAsn1Coder.h>
 #include <security_asn1/ocspTemplates.h>
 #include <security_asn1/oidsalg.h>
index f7e4434e05357bab88cf9fbaaf75d75829a4340c..01bf65648a934eac584bb95c2cb9acc270591333 100644 (file)
@@ -33,9 +33,7 @@
 #include <Security/SecAsn1Coder.h>
 #include <CoreFoundation/CFData.h>
 
 #include <Security/SecAsn1Coder.h>
 #include <CoreFoundation/CFData.h>
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 /*!
        @typedef SecOCSPRequestRef
 
 /*!
        @typedef SecOCSPRequestRef
@@ -75,8 +73,6 @@ CFDataRef SecOCSPRequestGetDER(SecOCSPRequestRef ocspRequest);
 */
 void SecOCSPRequestFinalize(SecOCSPRequestRef ocspRequest);
 
 */
 void SecOCSPRequestFinalize(SecOCSPRequestRef ocspRequest);
 
-#if defined(__cplusplus)
-}
-#endif
+__END_DECLS
 
 #endif /* !_SECURITY_SECOCSPREQUEST_H_ */
 
 #endif /* !_SECURITY_SECOCSPREQUEST_H_ */
index 1b52065642e5ede489338f1d49fc533424ef7224..0bbf7c5f888ffbbd9daad1e0b39c728c73a37dfd 100644 (file)
@@ -30,7 +30,7 @@
 #include <Security/SecFramework.h>
 #include <Security/SecKeyPriv.h>
 #include <AssertMacros.h>
 #include <Security/SecFramework.h>
 #include <Security/SecKeyPriv.h>
 #include <AssertMacros.h>
-#include <security_utilities/debugging.h>
+#include <utilities/debugging.h>
 #include <security_asn1/SecAsn1Coder.h>
 #include <security_asn1/ocspTemplates.h>
 #include <security_asn1/oidsalg.h>
 #include <security_asn1/SecAsn1Coder.h>
 #include <security_asn1/ocspTemplates.h>
 #include <security_asn1/oidsalg.h>
@@ -175,6 +175,8 @@ errOut:
     return NULL;
 }
 
     return NULL;
 }
 
+#define LEEWAY (4500.0)
+
 /* Calculate temporal validity; set latestNextUpdate and expireTime. Only
    called from SecOCSPResponseCreate. Returns true if valid, else returns
    false. */
 /* Calculate temporal validity; set latestNextUpdate and expireTime. Only
    called from SecOCSPResponseCreate. Returns true if valid, else returns
    false. */
@@ -184,8 +186,8 @@ static bool SecOCSPResponseCalculateValidity(SecOCSPResponseRef this,
        this->latestNextUpdate = NULL_TIME;
        CFAbsoluteTime now = this->verifyTime = CFAbsoluteTimeGetCurrent();
 
        this->latestNextUpdate = NULL_TIME;
        CFAbsoluteTime now = this->verifyTime = CFAbsoluteTimeGetCurrent();
 
-    if (this->producedAt > now) {
-        ocspdErrorLog("OCSPResponse: producedAt later than current time");
+    if (this->producedAt > now + LEEWAY) {
+        ocspdErrorLog("OCSPResponse: producedAt more than 1:15 from now");
         return false;
     }
 
         return false;
     }
 
@@ -197,8 +199,8 @@ static bool SecOCSPResponseCalculateValidity(SecOCSPResponseRef this,
                
                /* thisUpdate later than 'now' invalidates the whole response. */
                CFAbsoluteTime thisUpdate = genTimeToCFAbsTime(&resp->thisUpdate);
                
                /* thisUpdate later than 'now' invalidates the whole response. */
                CFAbsoluteTime thisUpdate = genTimeToCFAbsTime(&resp->thisUpdate);
-               if (thisUpdate > now) {
-                       ocspdErrorLog("OCSPResponse: thisUpdate later than current time");
+               if (thisUpdate > now + LEEWAY) {
+                       ocspdErrorLog("OCSPResponse: thisUpdate more than 1:15 from now");
                        return false;
                }
 
                        return false;
                }
 
@@ -258,8 +260,8 @@ static bool SecOCSPResponseCalculateValidity(SecOCSPResponseRef this,
         /* See comment above on RFC 5019 section 2.2.4. */
                /* Absolute expire time = current time plus defaultTTL */
                this->expireTime = now + defaultTTL;
         /* See comment above on RFC 5019 section 2.2.4. */
                /* Absolute expire time = current time plus defaultTTL */
                this->expireTime = now + defaultTTL;
-       } else if (this->latestNextUpdate < now) {
-                       ocspdErrorLog("OCSPResponse: now > latestNextUpdate");
+       } else if (this->latestNextUpdate < now - LEEWAY) {
+                       ocspdErrorLog("OCSPResponse: latestNextUpdate more than 1:15 ago");
                        return false;
     } else if (maxAge > 0) {
         /* Beware of double overflows such as:
                        return false;
     } else if (maxAge > 0) {
         /* Beware of double overflows such as:
@@ -430,6 +432,7 @@ CFArrayRef SecOCSPResponseCopySigners(SecOCSPResponseRef this) {
 
 void SecOCSPResponseFinalize(SecOCSPResponseRef this) {
     CFReleaseSafe(this->data);
 
 void SecOCSPResponseFinalize(SecOCSPResponseRef this) {
     CFReleaseSafe(this->data);
+    CFReleaseSafe(this->nonce);
     SecAsn1CoderRelease(this->coder);
     free(this);
 }
     SecAsn1CoderRelease(this->coder);
     free(this);
 }
@@ -538,7 +541,7 @@ static bool SecOCSPResponseVerifySignature(SecOCSPResponseRef this,
         this->basicResponse.tbsResponseData.Data,
         this->basicResponse.tbsResponseData.Length,
         this->basicResponse.sig.Data,
         this->basicResponse.tbsResponseData.Data,
         this->basicResponse.tbsResponseData.Length,
         this->basicResponse.sig.Data,
-        this->basicResponse.sig.Length / 8) == noErr;
+        this->basicResponse.sig.Length / 8) == errSecSuccess;
 }
 
 static bool SecOCSPResponseIsIssuer(SecOCSPResponseRef this,
 }
 
 static bool SecOCSPResponseIsIssuer(SecOCSPResponseRef this,
index 5949e3df8b5ec3c85c3aa2383d48ae4fe1f955cd..ebd02d53fc6a920fd4f1c18d2ca5143795f8282c 100644 (file)
@@ -38,9 +38,7 @@
 #include <security_asn1/ocspTemplates.h>
 #include <Security/SecCertificatePath.h>
 
 #include <security_asn1/ocspTemplates.h>
 #include <Security/SecCertificatePath.h>
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 typedef enum {
        kSecOCSPBad = -2,
 
 typedef enum {
        kSecOCSPBad = -2,
@@ -153,8 +151,6 @@ void SecOCSPSingleResponseDestroy(SecOCSPSingleResponseRef this);
 SecCertificatePathRef SecOCSPResponseCopySigner(SecOCSPResponseRef this,
     SecCertificatePathRef issuerPath);
 
 SecCertificatePathRef SecOCSPResponseCopySigner(SecOCSPResponseRef this,
     SecCertificatePathRef issuerPath);
 
-#if defined(__cplusplus)
-}
-#endif
+__END_DECLS
 
 #endif /* !_SECURITY_SECOCSPRESPONSE_H_ */
 
 #endif /* !_SECURITY_SECOCSPRESPONSE_H_ */
index 976ad214428f974678fe73db9b52454948815553..fc2b910ce09001ec01529926eabbef3369cc55db 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2008-2011 Apple Inc. All Rights Reserved.
+ * Copyright (c) 2008-2012 Apple Inc. All Rights Reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 #include <securityd/SecPolicyServer.h>
 #include <Security/SecPolicyInternal.h>
 #include <Security/SecPolicyPriv.h>
 #include <securityd/SecPolicyServer.h>
 #include <Security/SecPolicyInternal.h>
 #include <Security/SecPolicyPriv.h>
-
+#include <utilities/SecIOFormat.h>
 #include <securityd/asynchttp.h>
 #include <securityd/policytree.h>
 #include <securityd/asynchttp.h>
 #include <securityd/policytree.h>
-#include <pthread.h>
 #include <CoreFoundation/CFTimeZone.h>
 #include <wctype.h>
 #include <libDER/oids.h>
 #include <CoreFoundation/CFNumber.h>
 #include <Security/SecCertificateInternal.h>
 #include <AssertMacros.h>
 #include <CoreFoundation/CFTimeZone.h>
 #include <wctype.h>
 #include <libDER/oids.h>
 #include <CoreFoundation/CFNumber.h>
 #include <Security/SecCertificateInternal.h>
 #include <AssertMacros.h>
-#include <security_utilities/debugging.h>
+#include <utilities/debugging.h>
 #include <security_asn1/SecAsn1Coder.h>
 #include <security_asn1/ocspTemplates.h>
 #include <security_asn1/oidsalg.h>
 #include <security_asn1/SecAsn1Coder.h>
 #include <security_asn1/ocspTemplates.h>
 #include <security_asn1/oidsalg.h>
@@ -57,6 +56,9 @@
 #include <securityd/asynchttp.h>
 #include <securityd/SecTrustServer.h>
 #include <securityd/SecOCSPCache.h>
 #include <securityd/asynchttp.h>
 #include <securityd/SecTrustServer.h>
 #include <securityd/SecOCSPCache.h>
+#include <utilities/array_size.h>
+#include <utilities/SecCFWrappers.h>
+#include "OTATrustUtilities.h"
 
 #define ocspdErrorLog(args...)     asl_log(NULL, NULL, ASL_LEVEL_ERR, ## args)
 
 
 #define ocspdErrorLog(args...)     asl_log(NULL, NULL, ASL_LEVEL_ERR, ## args)
 
@@ -78,77 +80,44 @@ static void secdumpdata(CFDataRef data, const char *name) {
 
 #endif
 
 
 #endif
 
+
 /********************************************************
  ****************** SecPolicy object ********************
  ********************************************************/
 
 static CFMutableDictionaryRef gSecPolicyLeafCallbacks = NULL;
 static CFMutableDictionaryRef gSecPolicyPathCallbacks = NULL;
 /********************************************************
  ****************** SecPolicy object ********************
  ********************************************************/
 
 static CFMutableDictionaryRef gSecPolicyLeafCallbacks = NULL;
 static CFMutableDictionaryRef gSecPolicyPathCallbacks = NULL;
-static CFSetRef gBlackListedKeys = NULL;
-
-static pthread_once_t gSecEVPolicyToAnchorDigestsOnce = PTHREAD_ONCE_INIT;
-static CFDictionaryRef gSecEVPolicyToAnchorDigests = NULL;
-
-/* Helper functions. */
 
 
-static bool isArray(CFTypeRef cfType) {
-    return cfType && CFGetTypeID(cfType) == CFArrayGetTypeID();
-}
-
-static bool isData(CFTypeRef cfType) {
-    return cfType && CFGetTypeID(cfType) == CFDataGetTypeID();
-}
-
-static bool isDate(CFTypeRef cfType) {
-    return cfType && CFGetTypeID(cfType) == CFDateGetTypeID();
-}
-
-static bool isDictionary(CFTypeRef cfType) {
-    return cfType && CFGetTypeID(cfType) == CFDictionaryGetTypeID();
-}
-
-static bool isString(CFTypeRef cfType) {
-    return cfType && CFGetTypeID(cfType) == CFStringGetTypeID();
-}
-
-static void SecEVPolicyToAnchorDigestsInit(void) {
-       CFDataRef xmlData = SecFrameworkCopyResourceContents(
-               CFSTR("EVRoots"), CFSTR("plist"), NULL);
-       CFPropertyListRef evroots = NULL;
-    if (xmlData) {
-        evroots = CFPropertyListCreateFromXMLData(
-            kCFAllocatorDefault, xmlData, kCFPropertyListImmutable, NULL);
-        CFRelease(xmlData);
-    }
-       if (evroots) {
-               if (CFGetTypeID(evroots) == CFDictionaryGetTypeID()) {
-            /* @@@ Ensure that each dictionary key is a dotted list of digits,
-               each value is an NSArrayRef and each element in the array is a
-               20 byte digest. */
-                       gSecEVPolicyToAnchorDigests = (CFDictionaryRef)evroots;
-               } else {
-                       secwarning("EVRoot.plist is wrong type.");
-                       CFRelease(evroots);
-               }
+static CFArrayRef SecPolicyAnchorDigestsForEVPolicy(const DERItem *policyOID)
+{
+       CFArrayRef result = NULL;
+       SecOTAPKIRef otapkiRef = SecOTAPKICopyCurrentOTAPKIRef();
+       if (NULL == otapkiRef)
+       {
+               return result;
+       }
+       
+       CFDictionaryRef evToPolicyAnchorDigest = SecOTAPKICopyEVPolicyToAnchorMapping(otapkiRef);
+       CFRelease(otapkiRef);
+       
+    if (NULL == evToPolicyAnchorDigest)
+    {
+        return result;
     }
     }
-}
 
 
-static CFArrayRef SecPolicyAnchorDigestsForEVPolicy(const DERItem *policyOID) {
-    pthread_once(&gSecEVPolicyToAnchorDigestsOnce,
-        SecEVPolicyToAnchorDigestsInit);
     CFArrayRef roots = NULL;
     CFArrayRef roots = NULL;
-    CFStringRef oid = SecDERItemCopyOIDDecimalRepresentation(
-        kCFAllocatorDefault, policyOID);
-    if (oid) {
-        roots = (CFArrayRef)CFDictionaryGetValue(gSecEVPolicyToAnchorDigests,
-            oid);
-               if (roots && CFGetTypeID(roots) != CFArrayGetTypeID()) {
+    CFStringRef oid = SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault, policyOID);
+    if (oid && evToPolicyAnchorDigest) 
+       {
+        result = (CFArrayRef)CFDictionaryGetValue(evToPolicyAnchorDigest, oid);
+               if (roots && CFGetTypeID(result) != CFArrayGetTypeID()) 
+               {
             ocspdErrorLog("EVRoot.plist has non array value");
             ocspdErrorLog("EVRoot.plist has non array value");
-            roots = NULL;
+            result = NULL;
         }
         CFRelease(oid);
     }
         }
         CFRelease(oid);
     }
-    return roots;
+    return result;
 }
 
 
 }
 
 
@@ -898,19 +867,26 @@ static void SecPolicyCheckAnchorSHA1(SecPVCRef pvc,
     CFIndex count = SecPVCGetCertificateCount(pvc);
        SecCertificateRef cert = SecPVCGetCertificateAtIndex(pvc, count - 1);
        SecPolicyRef policy = SecPVCGetPolicy(pvc);
     CFIndex count = SecPVCGetCertificateCount(pvc);
        SecCertificateRef cert = SecPVCGetCertificateAtIndex(pvc, count - 1);
        SecPolicyRef policy = SecPVCGetPolicy(pvc);
-    CFDataRef sha1Digest =
-        (CFDataRef)CFDictionaryGetValue(policy->_options, key);
-    if (!isData(sha1Digest)) {
-        /* @@@ We can't return an error here and making the evaluation fail
-           won't help much either. */
-        return;
-    }
+    CFTypeRef value = CFDictionaryGetValue(policy->_options, key);
     CFDataRef anchorSHA1 = SecCertificateGetSHA1Digest(cert);
     CFDataRef anchorSHA1 = SecCertificateGetSHA1Digest(cert);
-       if (!CFEqual(anchorSHA1, sha1Digest)) {
-               /* Certificate chain is not issued by required anchor. */
-               if (!SecPVCSetResult(pvc, kSecPolicyCheckAnchorSHA1, 0, kCFBooleanFalse))
-                       return;
-       }
+
+    bool foundMatch = false;
+
+    if (isData(value))
+        foundMatch = CFEqual(anchorSHA1, value);
+    else if (isArray(value))
+        foundMatch = CFArrayContainsValue((CFArrayRef) value, CFRangeMake(0, CFArrayGetCount((CFArrayRef) value)), anchorSHA1);
+    else {
+        /* @@@ We only support Data and Array but we can't return an error here so.
+               we let the evaluation fail (not much help) and assert in debug. */
+        assert(false);
+    }
+
+    if (!foundMatch)
+        if (!SecPVCSetResult(pvc, kSecPolicyCheckAnchorSHA1, 0, kCFBooleanFalse))
+            return;
+
+    return;
 }
 
 /* AUDIT[securityd](done):
 }
 
 /* AUDIT[securityd](done):
@@ -937,6 +913,26 @@ static void SecPolicyCheckSubjectOrganization(SecPVCRef pvc,
        CFReleaseSafe(organization);
 }
 
        CFReleaseSafe(organization);
 }
 
+static void SecPolicyCheckSubjectOrganizationalUnit(SecPVCRef pvc,
+       CFStringRef key) {
+       SecCertificateRef cert = SecPVCGetCertificateAtIndex(pvc, 0);
+       SecPolicyRef policy = SecPVCGetPolicy(pvc);
+       CFStringRef orgUnit = (CFStringRef)CFDictionaryGetValue(policy->_options,
+               key);
+    if (!isString(orgUnit)) {
+        /* @@@ We can't return an error here and making the evaluation fail
+           won't help much either. */
+        return;
+    }
+       CFArrayRef organizationalUnit = SecCertificateCopyOrganizationalUnit(cert);
+       if (!organizationalUnit || CFArrayGetCount(organizationalUnit) != 1 ||
+               !CFEqual(orgUnit, CFArrayGetValueAtIndex(organizationalUnit, 0))) {
+               /* Leaf Subject Organizational Unit mismatch. */
+               SecPVCSetResult(pvc, key, 0, kCFBooleanFalse);
+       }
+       CFReleaseSafe(organizationalUnit);
+}
+
 /* AUDIT[securityd](done):
    policy->_options is a caller provided dictionary, only its cf type has
    been checked.
 /* AUDIT[securityd](done):
    policy->_options is a caller provided dictionary, only its cf type has
    been checked.
@@ -972,6 +968,7 @@ static void SecPolicyCheckEAPTrustedServerNames(SecPVCRef pvc,
                 if (!isString(serverName)) {
                     /* @@@ We can't return an error here and making the
                        evaluation fail won't help much either. */
                 if (!isString(serverName)) {
                     /* @@@ We can't return an error here and making the
                        evaluation fail won't help much either. */
+                    CFReleaseSafe(dnsNames);
                     return;
                 }
                 /* we purposefully reverse the arguments here such that dns names
                     return;
                 }
                 /* we purposefully reverse the arguments here such that dns names
@@ -996,7 +993,7 @@ static void SecPolicyCheckEAPTrustedServerNames(SecPVCRef pvc,
        }
 }
 
        }
 }
 
-static const unsigned char const UTN_USERFirst_Hardware_Serial[][16] = {
+static const unsigned char UTN_USERFirst_Hardware_Serial[][16] = {
 { 0xd8, 0xf3, 0x5f, 0x4e, 0xb7, 0x87, 0x2b, 0x2d, 0xab, 0x06, 0x92, 0xe3, 0x15, 0x38, 0x2f, 0xb0 },
 { 0x92, 0x39, 0xd5, 0x34, 0x8f, 0x40, 0xd1, 0x69, 0x5a, 0x74, 0x54, 0x70, 0xe1, 0xf2, 0x3f, 0x43 },
 { 0xb0, 0xb7, 0x13, 0x3e, 0xd0, 0x96, 0xf9, 0xb5, 0x6f, 0xae, 0x91, 0xc8, 0x74, 0xbd, 0x3a, 0xc0 },
 { 0xd8, 0xf3, 0x5f, 0x4e, 0xb7, 0x87, 0x2b, 0x2d, 0xab, 0x06, 0x92, 0xe3, 0x15, 0x38, 0x2f, 0xb0 },
 { 0x92, 0x39, 0xd5, 0x34, 0x8f, 0x40, 0xd1, 0x69, 0x5a, 0x74, 0x54, 0x70, 0xe1, 0xf2, 0x3f, 0x43 },
 { 0xb0, 0xb7, 0x13, 0x3e, 0xd0, 0x96, 0xf9, 0xb5, 0x6f, 0xae, 0x91, 0xc8, 0x74, 0xbd, 0x3a, 0xc0 },
@@ -1046,12 +1043,13 @@ static void SecPolicyCheckBlackListedLeaf(SecPVCRef pvc,
 
             if (serial_length == (CFIndex)sizeof(*UTN_USERFirst_Hardware_Serial)) {
                 unsigned int i;
 
             if (serial_length == (CFIndex)sizeof(*UTN_USERFirst_Hardware_Serial)) {
                 unsigned int i;
-                for (i = 0; i < sizeof(UTN_USERFirst_Hardware_Serial)/sizeof(*UTN_USERFirst_Hardware_Serial); i++)
+                for (i = 0; i < array_size(UTN_USERFirst_Hardware_Serial); i++)
                 {
                     if (0 == memcmp(UTN_USERFirst_Hardware_Serial[i],
                         serial_ptr, sizeof(*UTN_USERFirst_Hardware_Serial)))
                     {
                         SecPVCSetResult(pvc, key, 0, kCFBooleanFalse);
                 {
                     if (0 == memcmp(UTN_USERFirst_Hardware_Serial[i],
                         serial_ptr, sizeof(*UTN_USERFirst_Hardware_Serial)))
                     {
                         SecPVCSetResult(pvc, key, 0, kCFBooleanFalse);
+                        CFReleaseSafe(serial);
                         return;
                     }
                 }
                         return;
                     }
                 }
@@ -1059,14 +1057,62 @@ static void SecPolicyCheckBlackListedLeaf(SecPVCRef pvc,
             CFRelease(serial);
         }
     }
             CFRelease(serial);
         }
     }
+
+       SecOTAPKIRef otapkiRef = SecOTAPKICopyCurrentOTAPKIRef();
+       if (NULL != otapkiRef)
+       {
+               CFSetRef blackListedKeys = SecOTAPKICopyBlackListSet(otapkiRef);
+               CFRelease(otapkiRef);
+               if (NULL != blackListedKeys)
+               {
+                       /* Check for blacklisted intermediates keys. */
+                       CFDataRef dgst = SecCertificateCopyPublicKeySHA1Digest(cert);
+                       if (dgst) 
+                       {
+                               /* Check dgst against blacklist. */
+                               if (CFSetContainsValue(blackListedKeys, dgst)) 
+                               {
+                                       SecPVCSetResult(pvc, key, 0, kCFBooleanFalse);
+                               }
+                               CFRelease(dgst);
+                       }
+                       CFRelease(blackListedKeys);
+               }
+       }
 }
 
 }
 
+static void SecPolicyCheckGrayListedLeaf(SecPVCRef pvc, CFStringRef key)
+{
+       SecOTAPKIRef otapkiRef = SecOTAPKICopyCurrentOTAPKIRef();
+       if (NULL != otapkiRef)
+       {
+               CFSetRef grayListedKeys = SecOTAPKICopyGrayList(otapkiRef);
+               CFRelease(otapkiRef);
+               if (NULL != grayListedKeys)
+               {
+                       SecCertificateRef cert = SecPVCGetCertificateAtIndex(pvc, 0);
+
+                       CFDataRef dgst = SecCertificateCopyPublicKeySHA1Digest(cert);
+                       if (dgst) 
+                       {
+                               /* Check dgst against gray. */
+                               if (CFSetContainsValue(grayListedKeys, dgst)) 
+                               {
+                                       SecPVCSetResult(pvc, key, 0, kCFBooleanFalse);
+                               }
+                               CFRelease(dgst);
+                       }
+                       CFRelease(grayListedKeys);
+               }
+       }
+ }
+
 static void SecPolicyCheckLeafMarkerOid(SecPVCRef pvc, CFStringRef key)
 {
        SecCertificateRef cert = SecPVCGetCertificateAtIndex(pvc, 0);
     SecPolicyRef policy = SecPVCGetPolicy(pvc);
     CFTypeRef value = CFDictionaryGetValue(policy->_options, key);
 static void SecPolicyCheckLeafMarkerOid(SecPVCRef pvc, CFStringRef key)
 {
        SecCertificateRef cert = SecPVCGetCertificateAtIndex(pvc, 0);
     SecPolicyRef policy = SecPVCGetPolicy(pvc);
     CFTypeRef value = CFDictionaryGetValue(policy->_options, key);
-    
+
     if (value && SecCertificateHasMarkerExtension(cert, value))
         return;
 
     if (value && SecCertificateHasMarkerExtension(cert, value))
         return;
 
@@ -1087,6 +1133,8 @@ static void SecPolicyCheckIntermediateMarkerOid(SecPVCRef pvc, CFStringRef key)
     SecPVCSetResult(pvc, key, 0, kCFBooleanFalse);
 }
 
     SecPVCSetResult(pvc, key, 0, kCFBooleanFalse);
 }
 
+
+
 /****************************************************************************
  *********************** New rfc5280 Chain Validation ***********************
  ****************************************************************************/
 /****************************************************************************
  *********************** New rfc5280 Chain Validation ***********************
  ****************************************************************************/
@@ -1166,7 +1214,7 @@ static bool policy_tree_add_if_any(policy_tree_t node, void *ctx) {
 /* Return true iff node has a child with a valid_policy equal to oid. */
 static bool policy_tree_has_child_with_oid(policy_tree_t node,
     const oid_t *oid) {
 /* Return true iff node has a child with a valid_policy equal to oid. */
 static bool policy_tree_has_child_with_oid(policy_tree_t node,
     const oid_t *oid) {
-    policy_tree_t child = node->children;
+    policy_tree_t child;
     for (child = node->children; child; child = child->siblings) {
         if (oid_equal(child->valid_policy, (*oid))) {
             return true;
     for (child = node->children; child; child = child->siblings) {
         if (oid_equal(child->valid_policy, (*oid))) {
             return true;
@@ -1614,6 +1662,35 @@ certificatePolicies or extendedKeyUsage extensions.
 */
 }
 
 */
 }
 
+
+static void SecPolicyCheckCertificatePolicyOid(SecPVCRef pvc, CFStringRef key)
+{
+       CFIndex ix, count = SecPVCGetCertificateCount(pvc);
+    SecPolicyRef policy = SecPVCGetPolicy(pvc);
+    CFTypeRef value = CFDictionaryGetValue(policy->_options, key);
+       DERItem key_value;
+       key_value.data = NULL;
+       key_value.length = 0;
+    
+       if (CFGetTypeID(value) == CFDataGetTypeID())
+       {
+               CFDataRef key_data = (CFDataRef)value;
+               key_value.data = (DERByte *)CFDataGetBytePtr(key_data);
+               key_value.length = (DERSize)CFDataGetLength(key_data);
+               
+               for (ix = 0; ix < count; ix++) {
+               SecCertificateRef cert = SecPVCGetCertificateAtIndex(pvc, ix);
+            policy_set_t policies = policies_for_cert(cert);
+                       
+                       if (policy_set_contains(policies, &key_value)) {
+                               return;
+                       }
+               }
+               SecPVCSetResult(pvc, key, 0, kCFBooleanFalse);
+       }
+}
+
+
 static void SecPolicyCheckRevocation(SecPVCRef pvc,
        CFStringRef key) {
     SecPVCSetCheckRevocation(pvc);
 static void SecPolicyCheckRevocation(SecPVCRef pvc,
        CFStringRef key) {
     SecPVCSetCheckRevocation(pvc);
@@ -1624,8 +1701,8 @@ static void SecPolicyCheckNoNetworkAccess(SecPVCRef pvc,
     SecPathBuilderSetCanAccessNetwork(pvc->builder, false);
 }
 
     SecPathBuilderSetCanAccessNetwork(pvc->builder, false);
 }
 
-#pragma mark -
-#pragma mark SecRVCRef
+// MARK: -
+// MARK: SecRVCRef
 /********************************************************
  ****************** SecRVCRef Functions *****************
  ********************************************************/
 /********************************************************
  ****************** SecRVCRef Functions *****************
  ********************************************************/
@@ -1714,7 +1791,7 @@ static bool SecOCSPSingleResponseProccess(SecOCSPSingleResponseRef this,
     bool proccessed;
        switch (this->certStatus) {
     case CS_Good:
     bool proccessed;
        switch (this->certStatus) {
     case CS_Good:
-        secdebug("ocsp", "CS_Good for cert %u", rvc->certIX);
+        secdebug("ocsp", "CS_Good for cert %" PRIdCFIndex, rvc->certIX);
         /* @@@ Mark cert as valid until a given date (nextUpdate if we have one)
            in the info dictionary. */
         //cert.revokeCheckGood(true);
         /* @@@ Mark cert as valid until a given date (nextUpdate if we have one)
            in the info dictionary. */
         //cert.revokeCheckGood(true);
@@ -1722,7 +1799,7 @@ static bool SecOCSPSingleResponseProccess(SecOCSPSingleResponseRef this,
         proccessed = true;
         break;
     case CS_Revoked:
         proccessed = true;
         break;
     case CS_Revoked:
-        secdebug("ocsp", "CS_Revoked for cert %u", rvc->certIX);
+        secdebug("ocsp", "CS_Revoked for cert %" PRIdCFIndex, rvc->certIX);
         /* @@@ Mark cert as revoked (with reason) at revocation date in
            the info dictionary, or perhaps we should use a different key per
            reason?   That way a client using exceptions can ignore some but
         /* @@@ Mark cert as revoked (with reason) at revocation date in
            the info dictionary, or perhaps we should use a different key per
            reason?   That way a client using exceptions can ignore some but
@@ -1736,11 +1813,11 @@ static bool SecOCSPSingleResponseProccess(SecOCSPSingleResponseRef this,
         break;
     case CS_Unknown:
         /* not an error, no per-cert status, nothing here */
         break;
     case CS_Unknown:
         /* not an error, no per-cert status, nothing here */
-        secdebug("ocsp", "CS_Unknown for cert %u", rvc->certIX);
+        secdebug("ocsp", "CS_Unknown for cert %" PRIdCFIndex, rvc->certIX);
         proccessed = false;
         break;
     default:
         proccessed = false;
         break;
     default:
-        secdebug("ocsp", "BAD certStatus (%d) for cert %u",
+        secdebug("ocsp", "BAD certStatus (%d) for cert %" PRIdCFIndex,
             (int)this->certStatus, rvc->certIX);
         proccessed = false;
         break;
             (int)this->certStatus, rvc->certIX);
         proccessed = false;
         break;
@@ -1789,7 +1866,7 @@ static bool SecOCSPResponseVerify(SecOCSPResponseRef ocspResponse, SecRVCRef rvc
                 }
             }
             if (ospvc.result) {
                 }
             }
             if (ospvc.result) {
-                secdebug("ocsp", "response satisfies ocspSigner policy",
+                secdebug("ocsp", "response satisfies ocspSigner policy (%@)",
                     rvc->responder);
                 trusted = true;
             } else {
                     rvc->responder);
                 trusted = true;
             } else {
@@ -1900,6 +1977,7 @@ static void SecRVCInit(SecRVCRef rvc, SecPVCRef pvc, CFIndex certIX) {
     secdebug("alloc", "%p", rvc);
     rvc->pvc = pvc;
     rvc->certIX = certIX;
     secdebug("alloc", "%p", rvc);
     rvc->pvc = pvc;
     rvc->certIX = certIX;
+    rvc->http.queue = SecPathBuilderGetQueue(pvc->builder);
     rvc->http.completed = SecOCSPFetchCompleted;
     rvc->http.info = rvc;
     rvc->ocspRequest = NULL;
     rvc->http.completed = SecOCSPFetchCompleted;
     rvc->http.info = rvc;
     rvc->ocspRequest = NULL;
@@ -1985,7 +2063,7 @@ static bool SecPVCCheckRevocation(SecPVCRef pvc) {
        all the jobs. To avoid this we pretend we issued certCount async jobs,
        and decrement pvc->asyncJobCount for each cert that we don't start a
        background fetch for. */
        all the jobs. To avoid this we pretend we issued certCount async jobs,
        and decrement pvc->asyncJobCount for each cert that we don't start a
        background fetch for. */
-    pvc->asyncJobCount = certCount;
+    pvc->asyncJobCount = (unsigned int) certCount;
 
     /* Loop though certificates again and issue an ocsp fetch if the
        revocation status checking isn't done yet. */
 
     /* Loop though certificates again and issue an ocsp fetch if the
        revocation status checking isn't done yet. */
@@ -2045,7 +2123,7 @@ static bool SecPVCCheckRevocation(SecPVCRef pvc) {
         bool fetch_done = true;
         if (rvc->done || !SecPathBuilderCanAccessNetwork(pvc->builder) ||
             (fetch_done = SecRVCFetchNext(rvc))) {
         bool fetch_done = true;
         if (rvc->done || !SecPathBuilderCanAccessNetwork(pvc->builder) ||
             (fetch_done = SecRVCFetchNext(rvc))) {
-            /* We got a cache hit or we aren't allowed to acces the network,
+            /* We got a cache hit or we aren't allowed to access the network,
                or the async http post failed. */
             SecRVCDelete(rvc);
             /* We didn't really start a background job for this cert. */
                or the async http post failed. */
             SecRVCDelete(rvc);
             /* We didn't really start a background job for this cert. */
@@ -2065,6 +2143,7 @@ static bool SecPVCCheckRevocation(SecPVCRef pvc) {
     return completed;
 }
 
     return completed;
 }
 
+
 void SecPolicyServerInitalize(void) {
        gSecPolicyLeafCallbacks = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                &kCFTypeDictionaryKeyCallBacks, NULL);
 void SecPolicyServerInitalize(void) {
        gSecPolicyLeafCallbacks = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                &kCFTypeDictionaryKeyCallBacks, NULL);
@@ -2116,6 +2195,9 @@ void SecPolicyServerInitalize(void) {
        CFDictionaryAddValue(gSecPolicyLeafCallbacks,
                kSecPolicyCheckSubjectOrganization,
                SecPolicyCheckSubjectOrganization);
        CFDictionaryAddValue(gSecPolicyLeafCallbacks,
                kSecPolicyCheckSubjectOrganization,
                SecPolicyCheckSubjectOrganization);
+       CFDictionaryAddValue(gSecPolicyLeafCallbacks,
+               kSecPolicyCheckSubjectOrganizationalUnit,
+               SecPolicyCheckSubjectOrganizationalUnit);
        CFDictionaryAddValue(gSecPolicyLeafCallbacks,
                kSecPolicyCheckEAPTrustedServerNames,
         SecPolicyCheckEAPTrustedServerNames);
        CFDictionaryAddValue(gSecPolicyLeafCallbacks,
                kSecPolicyCheckEAPTrustedServerNames,
         SecPolicyCheckEAPTrustedServerNames);
@@ -2131,41 +2213,18 @@ void SecPolicyServerInitalize(void) {
     CFDictionaryAddValue(gSecPolicyLeafCallbacks,
         kSecPolicyCheckBlackListedLeaf,
         SecPolicyCheckBlackListedLeaf);
     CFDictionaryAddValue(gSecPolicyLeafCallbacks,
         kSecPolicyCheckBlackListedLeaf,
         SecPolicyCheckBlackListedLeaf);
+       CFDictionaryAddValue(gSecPolicyLeafCallbacks,
+        kSecPolicyCheckGrayListedLeaf,
+        SecPolicyCheckGrayListedLeaf);
     CFDictionaryAddValue(gSecPolicyLeafCallbacks,
         kSecPolicyCheckLeafMarkerOid,
         SecPolicyCheckLeafMarkerOid);
     CFDictionaryAddValue(gSecPolicyPathCallbacks,
         kSecPolicyCheckIntermediateMarkerOid,
         SecPolicyCheckIntermediateMarkerOid);
     CFDictionaryAddValue(gSecPolicyLeafCallbacks,
         kSecPolicyCheckLeafMarkerOid,
         SecPolicyCheckLeafMarkerOid);
     CFDictionaryAddValue(gSecPolicyPathCallbacks,
         kSecPolicyCheckIntermediateMarkerOid,
         SecPolicyCheckIntermediateMarkerOid);
-
-    /* Initialize gBlackListedKeys. */
-    const uint8_t blacklisted_keys[][CC_SHA1_DIGEST_LENGTH] = {
-        /* DigiNotar Root CA by DigiNotar Root CA (is also cross certified by entrust) */
-        { 0x88, 0x68, 0xBF, 0xE0, 0x8E, 0x35, 0xC4, 0x3B, 0x38, 0x6B, 0x62, 0xF7, 0x28, 0x3B, 0x84, 0x81, 0xC8, 0x0C, 0xD7, 0x4D },
-        /* DigiNotar Services 1024 CA.cer by Entrust.net Secure Server Certification Authority (revoked) */
-        { 0xFE, 0xDC, 0x94, 0x49, 0x0C, 0x6F, 0xEF, 0x5C, 0x7F, 0xC6, 0xF1, 0x12, 0x99, 0x4F, 0x16, 0x49, 0xAD, 0xFB, 0x82, 0x65 },
-        /* DigiNotar Cyber CA issued by GTE CyberTrust Global Root. (no yet revoked) */
-        { 0xAB, 0xF9, 0x68, 0xDF, 0xCF, 0x4A, 0x37, 0xD7, 0x7B, 0x45, 0x8C, 0x5F, 0x72, 0xDE, 0x40, 0x44, 0xC3, 0x65, 0xBB, 0xC2 },
-        /* DigiNotar PKIoverheid CA Overheid en Bedrijven */
-        { 0x4C, 0x08, 0xC9, 0x8D, 0x76, 0xF1, 0x98, 0xC7, 0x3E, 0xDF, 0x3C, 0xD7, 0x2F, 0x75, 0x0D, 0xB1, 0x76, 0x79, 0x97, 0xCC },
-        /* DigiNotar PKIoverheid CA Organisatie - G2 */
-        { 0xBC, 0x5D, 0x94, 0x3B, 0xD9, 0xAB, 0x7B, 0x03, 0x25, 0x73, 0x61, 0xC2, 0xDB, 0x2D, 0xEE, 0xFC, 0xAB, 0x8F, 0x65, 0xA1 },
-        /* Digisign Server ID - (Enrich) cross-certified by Entrust.net Certification Authority (2048), serial 1276011370 */
-        {   0xa1, 0x3f, 0xd3, 0x7c, 0x04, 0x5b, 0xb4, 0xa3, 0x11, 0x2b,
-            0xd8, 0x9b, 0x1a, 0x07, 0xe9, 0x04, 0xb2, 0xd2, 0x6e, 0x26 },
-        /* Digisign Server ID - (Enrich) cross-certified by GTE CyberTrust Global Root, serial 120001705 */
-        {   0xc6, 0x16, 0x93, 0x4e, 0x16, 0x17, 0xec, 0x16, 0xae, 0x8c,
-            0x94, 0x76, 0xf3, 0x86, 0x6d, 0xc5, 0x74, 0x6e, 0x84, 0x77 },
-    };
-#define NUM_BLACKLISTED_KEYS  (sizeof(blacklisted_keys) / sizeof(*blacklisted_keys))
-
-    const void *keys[NUM_BLACKLISTED_KEYS];
-    size_t ix;
-    for (ix = 0; ix < NUM_BLACKLISTED_KEYS; ++ix) {
-        keys[ix] = CFDataCreateWithBytesNoCopy(0, blacklisted_keys[ix], CC_SHA1_DIGEST_LENGTH, kCFAllocatorNull);
-    }
-    gBlackListedKeys = CFSetCreate(0, keys, NUM_BLACKLISTED_KEYS, &kCFTypeSetCallBacks);
-    CFSetApplyFunction(gBlackListedKeys, (CFSetApplierFunction)CFRelease, 0);
+       CFDictionaryAddValue(gSecPolicyLeafCallbacks,
+               kSecPolicyCheckCertificatePolicy,
+               SecPolicyCheckCertificatePolicyOid);
 }
 
 /* AUDIT[securityd](done):
 }
 
 /* AUDIT[securityd](done):
@@ -2215,8 +2274,8 @@ errOut:
     return result;
 }
 
     return result;
 }
 
-#pragma mark -
-#pragma mark SecPVCRef
+// MARK: -
+// MARK: SecPVCRef
 /********************************************************
  ****************** SecPVCRef Functions *****************
  ********************************************************/
 /********************************************************
  ****************** SecPVCRef Functions *****************
  ********************************************************/
@@ -2317,7 +2376,7 @@ CFAbsoluteTime SecPVCGetVerifyTime(SecPVCRef pvc) {
 bool SecPVCSetResultForced(SecPVCRef pvc,
        CFStringRef key, CFIndex ix, CFTypeRef result, bool force) {
 
 bool SecPVCSetResultForced(SecPVCRef pvc,
        CFStringRef key, CFIndex ix, CFTypeRef result, bool force) {
 
-    secdebug("policy", "cert[%d]: %@ =(%s)[%s]> %@", ix, key,
+    secdebug("policy", "cert[%d]: %@ =(%s)[%s]> %@", (int) ix, key,
         (pvc->callbacks == gSecPolicyLeafCallbacks ? "leaf"
             : (pvc->callbacks == gSecPolicyPathCallbacks ? "path"
                 : "custom")),
         (pvc->callbacks == gSecPolicyLeafCallbacks ? "leaf"
             : (pvc->callbacks == gSecPolicyPathCallbacks ? "path"
                 : "custom")),
@@ -2464,23 +2523,68 @@ errOut:
 
 bool SecPVCBlackListedKeyChecks(SecPVCRef pvc, CFIndex ix) {
     /* Check stuff common to intermediate and anchors. */
 
 bool SecPVCBlackListedKeyChecks(SecPVCRef pvc, CFIndex ix) {
     /* Check stuff common to intermediate and anchors. */
-       SecCertificateRef cert = SecPVCGetCertificateAtIndex(pvc, ix);
-    bool is_anchor = (ix == SecPVCGetCertificateCount(pvc) - 1
-                      && SecPVCIsAnchored(pvc));
-    if (!is_anchor) {
-        /* Check for blacklisted intermediates keys. */
-        CFDataRef dgst = SecCertificateCopyPublicKeySHA1Digest(cert);
-        if (dgst) {
-            /* Check dgst against blacklist. */
-            if (CFSetContainsValue(gBlackListedKeys, dgst)) {
-                SecPVCSetResultForced(pvc, kSecPolicyCheckBlackListedKey,
-                                      ix, kCFBooleanFalse, true);
-            }
-            CFRelease(dgst);
-        }
-    }
 
 
-    return pvc->result;
+       SecOTAPKIRef otapkiRef = SecOTAPKICopyCurrentOTAPKIRef();
+       if (NULL != otapkiRef)
+       {
+               CFSetRef blackListedKeys = SecOTAPKICopyBlackListSet(otapkiRef);
+               CFRelease(otapkiRef);
+               if (NULL != blackListedKeys)
+               {
+                       SecCertificateRef cert = SecPVCGetCertificateAtIndex(pvc, ix);
+                   bool is_anchor = (ix == SecPVCGetCertificateCount(pvc) - 1
+                                     && SecPVCIsAnchored(pvc));
+                   if (!is_anchor) {
+                       /* Check for blacklisted intermediates keys. */
+                       CFDataRef dgst = SecCertificateCopyPublicKeySHA1Digest(cert);
+                       if (dgst) {
+                           /* Check dgst against blacklist. */
+                           if (CFSetContainsValue(blackListedKeys, dgst)) {
+                               SecPVCSetResultForced(pvc, kSecPolicyCheckBlackListedKey,
+                                                     ix, kCFBooleanFalse, true);
+                           }
+                           CFRelease(dgst);
+                       }
+                   }
+                       CFRelease(blackListedKeys);
+                   return pvc->result;
+               }
+       }
+       // Assume OK
+       return true;
+}
+
+bool SecPVCGrayListedKeyChecks(SecPVCRef pvc, CFIndex ix)
+{
+    /* Check stuff common to intermediate and anchors. */
+       SecOTAPKIRef otapkiRef = SecOTAPKICopyCurrentOTAPKIRef();
+       if (NULL != otapkiRef)
+       {
+               CFSetRef grayListKeys = SecOTAPKICopyGrayList(otapkiRef);
+               CFRelease(otapkiRef);
+               if (NULL != grayListKeys)
+               {
+                       SecCertificateRef cert = SecPVCGetCertificateAtIndex(pvc, ix);
+                   bool is_anchor = (ix == SecPVCGetCertificateCount(pvc) - 1
+                                     && SecPVCIsAnchored(pvc));
+                   if (!is_anchor) {
+                       /* Check for gray listed intermediates keys. */
+                       CFDataRef dgst = SecCertificateCopyPublicKeySHA1Digest(cert);
+                       if (dgst) {
+                           /* Check dgst against gray list. */
+                           if (CFSetContainsValue(grayListKeys, dgst)) {
+                               SecPVCSetResultForced(pvc, kSecPolicyCheckGrayListedKey,
+                                                     ix, kCFBooleanFalse, true);
+                           }
+                           CFRelease(dgst);
+                       }
+                   }
+                       CFRelease(grayListKeys);
+                   return pvc->result;
+               }
+       }
+       // Assume ok
+       return true;
 }
 
 /* AUDIT[securityd](done):
 }
 
 /* AUDIT[securityd](done):
index 1997877137e611d0727b5b6b26a99f719fdc1193..c46e22725dccbf9a4eabba9b888cedc8b6ad9154 100644 (file)
@@ -35,9 +35,7 @@
 #include <securityd/policytree.h>
 #include <securityd/SecTrustServer.h>
 
 #include <securityd/policytree.h>
 #include <securityd/SecTrustServer.h>
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 typedef struct OpaqueSecPVC *SecPVCRef;
 
 
 typedef struct OpaqueSecPVC *SecPVCRef;
 
@@ -95,6 +93,9 @@ bool SecPVCParentCertificateChecks(SecPVCRef pvc, CFIndex ix);
 
 /* Check whether an intermediate certificates key has been blacklisted. */
 bool SecPVCBlackListedKeyChecks(SecPVCRef pvc, CFIndex ix);
 
 /* Check whether an intermediate certificates key has been blacklisted. */
 bool SecPVCBlackListedKeyChecks(SecPVCRef pvc, CFIndex ix);
+/* Check whether an intermediate certificates key has been gray listed. */
+bool SecPVCGrayListedKeyChecks(SecPVCRef pvc, CFIndex ix);
 
 /* Run dynamic checks on the complete path in pvc.  Return true if the
    operation is complete, returns false if an async backgroup request was
 
 /* Run dynamic checks on the complete path in pvc.  Return true if the
    operation is complete, returns false if an async backgroup request was
@@ -122,8 +123,8 @@ void SecPolicyServerInitalize(void);
 /* True iff certificate could be an extended validation (EV) certificate. */
 bool SecPolicySubscriberCertificateCouldBeEV(SecCertificateRef certificate);
 
 /* True iff certificate could be an extended validation (EV) certificate. */
 bool SecPolicySubscriberCertificateCouldBeEV(SecCertificateRef certificate);
 
-#if defined(__cplusplus)
-}
-#endif
+void SecEVPolicyToAnchorDigestsInit(void);
+
+__END_DECLS
 
 #endif /* !_SECURITY_SECPOLICYSERVER_H_ */
 
 #endif /* !_SECURITY_SECPOLICYSERVER_H_ */
index 33f103101d7f3b09040b5deafe0090aa6b34e529..fc12a774d38f7fe89de2846e5dece6fe8fe2f47e 100644 (file)
 #include <securityd/SecPolicyServer.h>
 #include <securityd/SecTrustStoreServer.h>
 #include <securityd/SecCAIssuerRequest.h>
 #include <securityd/SecPolicyServer.h>
 #include <securityd/SecTrustStoreServer.h>
 #include <securityd/SecCAIssuerRequest.h>
+#include <securityd/SecItemServer.h>
+
+#include <utilities/SecIOFormat.h>
+#include <utilities/SecDispatchRelease.h>
 
 #include <Security/SecTrustPriv.h>
 #include <Security/SecItem.h>
 
 #include <Security/SecTrustPriv.h>
 #include <Security/SecItem.h>
 #include <stdbool.h>
 #include <string.h>
 #include <stdlib.h>
 #include <stdbool.h>
 #include <string.h>
 #include <stdlib.h>
-#include <pthread.h>
-#include <MacErrors.h>
+#include <limits.h>
+#include <Security/SecBase.h>
 #include "SecRSAKey.h"
 #include <libDER/oids.h>
 #include "SecRSAKey.h"
 #include <libDER/oids.h>
-#include <security_utilities/debugging.h>
+#include <utilities/debugging.h>
+#include <utilities/SecCFWrappers.h>
 #include <Security/SecInternal.h>
 #include "securityd_client.h"
 #include <Security/SecInternal.h>
 #include "securityd_client.h"
-#include "securityd_server.h"
+#include <CommonCrypto/CommonDigest.h>
+#include "OTATrustUtilities.h"
+
+
+/********************************************************
+ ***************** OTA Trust support ********************
+ ********************************************************/
 
 
-const struct digest_to_ix_t *
-digest_to_anchor_ix (register const char *str, register unsigned int len);
-const struct subject_to_ix_t *
-subject_to_anchor_ix (register const char *str, register unsigned int len);
-const struct ev_oids *
-ev_oid (register const char *str, register unsigned int len);
 
 #ifndef SECITEM_SHIM_OSX
 
 #ifndef SECITEM_SHIM_OSX
-#include "evroots.h"
+
+static CFArrayRef subject_to_anchors(CFDataRef nic);
+static CFArrayRef CopyCertsFromIndices(CFArrayRef offsets);
+
+static CFArrayRef subject_to_anchors(CFDataRef nic)
+{
+    CFArrayRef result = NULL;
+
+    if (NULL == nic)
+    {
+        return result;
+    }
+
+       SecOTAPKIRef otapkiref = SecOTAPKICopyCurrentOTAPKIRef();
+       if (NULL == otapkiref)
+       {
+               return result;
+       }
+       
+       CFDictionaryRef lookupTable = SecOTAPKICopyAnchorLookupTable(otapkiref);
+       CFRelease(otapkiref);
+
+       if (NULL == lookupTable)
+       {
+               return result;
+       }
+
+    unsigned char subject_digest[CC_SHA1_DIGEST_LENGTH];
+    memset(subject_digest, 0, CC_SHA1_DIGEST_LENGTH);
+
+    (void)CC_SHA1(CFDataGetBytePtr(nic), (CC_LONG)CFDataGetLength(nic), subject_digest);
+    CFDataRef sha1Digest = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, subject_digest, CC_SHA1_DIGEST_LENGTH, kCFAllocatorNull);
+
+
+    result = (CFArrayRef)CFDictionaryGetValue(lookupTable, sha1Digest);
+       CFReleaseSafe(lookupTable);
+    CFReleaseSafe(sha1Digest);
+
+    return result;
+}
+
+static CFArrayRef CopyCertDataFromIndices(CFArrayRef offsets)
+{
+    CFMutableArrayRef result = NULL;
+
+       SecOTAPKIRef otapkiref = SecOTAPKICopyCurrentOTAPKIRef();
+       if (NULL == otapkiref)
+       {
+               return result;
+       }
+       
+       const char* anchorTable = SecOTAPKIGetAnchorTable(otapkiref);   
+       if (NULL == anchorTable)
+       {
+               CFReleaseSafe(otapkiref);
+               return result;
+       }
+
+       CFIndex num_offsets = CFArrayGetCount(offsets);
+       
+       result = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+       
+       for (CFIndex idx = 0; idx < num_offsets; idx++)
+    {
+               CFNumberRef offset = (CFNumberRef)CFArrayGetValueAtIndex(offsets, idx);
+               uint32_t offset_value = 0;
+               if (CFNumberGetValue(offset, kCFNumberSInt32Type, &offset_value))
+               {
+                       char* pDataPtr = (char *)(anchorTable + offset_value);
+                       //int32_t record_length = *((int32_t * )pDataPtr);
+                       //record_length = record_length;
+                       pDataPtr += sizeof(uint32_t);
+
+                       int32_t cert_data_length = *((int32_t * )pDataPtr);
+                       pDataPtr += sizeof(uint32_t);
+
+                       CFDataRef cert_data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8 *)pDataPtr,
+                                                              cert_data_length, kCFAllocatorNull);
+                       if (NULL != cert_data)
+                       {
+                CFArrayAppendValue(result, cert_data);
+                CFReleaseSafe(cert_data);
+            }
+               }
+       }
+       CFReleaseSafe(otapkiref);
+       return result;
+}
+
+static CFArrayRef CopyCertsFromIndices(CFArrayRef offsets)
+{
+       CFMutableArrayRef result = NULL;
+
+    CFArrayRef cert_data_array = CopyCertDataFromIndices(offsets);
+
+    if (NULL != cert_data_array)
+    {
+        result = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+        CFIndex num_cert_datas = CFArrayGetCount(cert_data_array);
+        for (CFIndex idx = 0; idx < num_cert_datas; idx++)
+        {
+            CFDataRef cert_data = (CFDataRef)CFArrayGetValueAtIndex(cert_data_array, idx);
+            if (NULL != cert_data)
+            {
+                SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault, cert_data);
+                if (NULL != cert)
+                {
+                    CFArrayAppendValue(result, cert);
+                    CFRelease(cert);
+                }
+            }
+        }
+        CFRelease(cert_data_array);
+    }
+    return result;
+
+}
 #endif
 
 #endif
 
+/********************************************************
+ *************** END OTA Trust support ******************
+ ********************************************************/
+
 #define MAX_CHAIN_LENGTH  15
 
 /* Forward declaration for use in SecCertificateSource. */
 static void SecPathBuilderExtendPaths(void *context, CFArrayRef parents);
 
 
 #define MAX_CHAIN_LENGTH  15
 
 /* Forward declaration for use in SecCertificateSource. */
 static void SecPathBuilderExtendPaths(void *context, CFArrayRef parents);
 
 
-#pragma mark -
-#pragma mark SecCertificateSource
+// MARK: -
+// MARK: SecCertificateSource
 /********************************************************
  ************ SecCertificateSource object ***************
  ********************************************************/
 /********************************************************
  ************ SecCertificateSource object ***************
  ********************************************************/
@@ -102,21 +227,45 @@ static bool SecCertificateSourceContains(SecCertificateSourceRef source,
        return source->contains(source, certificate);
 }
 
        return source->contains(source, certificate);
 }
 
-#pragma mark -
-#pragma mark SecItemCertificateSource
+// MARK: -
+// MARK: SecItemCertificateSource
 /********************************************************
  *********** SecItemCertificateSource object ************
  ********************************************************/
 /********************************************************
  *********** SecItemCertificateSource object ************
  ********************************************************/
+struct SecItemCertificateSource {
+       struct SecCertificateSource base;
+       CFArrayRef accessGroups;
+};
+typedef struct SecItemCertificateSource *SecItemCertificateSourceRef;
+
+static CFTypeRef SecItemCertificateSourceResultsPost(CFTypeRef raw_results) {
+    if (isArray(raw_results)) {
+        CFMutableArrayRef result = CFArrayCreateMutable(kCFAllocatorDefault, CFArrayGetCount(raw_results), &kCFTypeArrayCallBacks);
+        CFArrayForEach(raw_results, ^(const void *value) {
+            SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault, value);
+            if (cert) {
+                CFArrayAppendValue(result, cert);
+                               CFRelease(cert);
+                       }
+        });
+        return result;
+    } else if (isData(raw_results)) {
+        return SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef)raw_results);
+    }
+    return NULL;
+}
+
 static bool SecItemCertificateSourceCopyParents(
        SecCertificateSourceRef source, SecCertificateRef certificate,
         void *context, SecCertificateSourceParents callback) {
 static bool SecItemCertificateSourceCopyParents(
        SecCertificateSourceRef source, SecCertificateRef certificate,
         void *context, SecCertificateSourceParents callback) {
+       SecItemCertificateSourceRef msource = (SecItemCertificateSourceRef)source;
     /* FIXME: Search for things other than just subject of our issuer if we
        have a subjectID or authorityKeyIdentifier. */
     CFDataRef normalizedIssuer =
         SecCertificateGetNormalizedIssuerContent(certificate);
     const void *keys[] = {
         kSecClass,
     /* FIXME: Search for things other than just subject of our issuer if we
        have a subjectID or authorityKeyIdentifier. */
     CFDataRef normalizedIssuer =
         SecCertificateGetNormalizedIssuerContent(certificate);
     const void *keys[] = {
         kSecClass,
-        kSecReturnRef,
+        kSecReturnData,
         kSecMatchLimit,
         kSecAttrSubject
     },
         kSecMatchLimit,
         kSecAttrSubject
     },
@@ -130,18 +279,24 @@ static bool SecItemCertificateSourceCopyParents(
                NULL, NULL);
     CFTypeRef results = NULL;
     /* We can make this async or run this on a queue now easily. */
                NULL, NULL);
     CFTypeRef results = NULL;
     /* We can make this async or run this on a queue now easily. */
-    OSStatus status = SecItemCopyMatching(query, &results);
-    CFRelease(query);
-    if (status) {
-               secdebug("trust", "SecItemCopyMatching status: %lu", status);
+    CFErrorRef localError = NULL;
+    if (!_SecItemCopyMatching(query, msource->accessGroups, &results, &localError)) {
+        if (CFErrorGetCode(localError) != errSecItemNotFound) {
+            secdebug("trust", "_SecItemCopyMatching: %@", localError);
+        }
+        CFRelease(localError);
     }
     }
-    callback(context, results);
+    CFRelease(query);
+    CFTypeRef certs = SecItemCertificateSourceResultsPost(results);
     CFReleaseSafe(results);
     CFReleaseSafe(results);
+    callback(context, certs);
+    CFReleaseSafe(certs);
     return true;
 }
 
 static bool SecItemCertificateSourceContains(SecCertificateSourceRef source,
        SecCertificateRef certificate) {
     return true;
 }
 
 static bool SecItemCertificateSourceContains(SecCertificateSourceRef source,
        SecCertificateRef certificate) {
+       SecItemCertificateSourceRef msource = (SecItemCertificateSourceRef)source;
     /* Lookup a certificate by issuer and serial number. */
     CFDataRef normalizedSubject =
         SecCertificateGetNormalizedSubjectContent(certificate);
     /* Lookup a certificate by issuer and serial number. */
     CFDataRef normalizedSubject =
         SecCertificateGetNormalizedSubjectContent(certificate);
@@ -149,146 +304,78 @@ static bool SecItemCertificateSourceContains(SecCertificateSourceRef source,
         SecCertificateCopySerialNumber(certificate);
     const void *keys[] = {
         kSecClass,
         SecCertificateCopySerialNumber(certificate);
     const void *keys[] = {
         kSecClass,
-        kSecReturnRef,
         kSecMatchLimit,
         kSecAttrIssuer,
                kSecAttrSerialNumber
     },
     *values[] = {
         kSecClassCertificate,
         kSecMatchLimit,
         kSecAttrIssuer,
                kSecAttrSerialNumber
     },
     *values[] = {
         kSecClassCertificate,
-        kCFBooleanTrue,
         kSecMatchLimitOne,
         normalizedSubject,
                serialNumber
     };
     CFDictionaryRef query = CFDictionaryCreate(NULL, keys, values, 5,
         NULL, NULL);
         kSecMatchLimitOne,
         normalizedSubject,
                serialNumber
     };
     CFDictionaryRef query = CFDictionaryCreate(NULL, keys, values, 5,
         NULL, NULL);
-    OSStatus status = SecItemCopyMatching(query, NULL);
+    CFErrorRef localError = NULL;
+    CFTypeRef results = NULL;
+    bool ok = _SecItemCopyMatching(query, msource->accessGroups, &results, &localError);
     CFRelease(query);
     CFRelease(serialNumber);
     CFRelease(query);
     CFRelease(serialNumber);
-
-    if (status) {
-               if (status != errSecItemNotFound) {
-                       secdebug("trust", "SecItemCopyMatching returned %d", status);
-               }
+    CFReleaseSafe(results);
+    if (!ok) {
+        if (CFErrorGetCode(localError) != errSecItemNotFound) {
+            secdebug("trust", "_SecItemCopyMatching: %@", localError);
+        }
+        CFRelease(localError);
                return false;
     }
     return true;
 }
 
                return false;
     }
     return true;
 }
 
-struct SecCertificateSource kSecItemCertificateSource = {
-       SecItemCertificateSourceCopyParents,
-       SecItemCertificateSourceContains
-};
-
-#if 0
-#pragma mark -
-#pragma mark SecSystemAnchorSource
-/********************************************************
- *********** SecSystemAnchorSource object ************
- ********************************************************/
-struct SecSystemAnchorSource {
-       struct SecCertificateSource base;
-       CFSetRef digests;
-};
-typedef struct SecSystemAnchorSource *SecSystemAnchorSourceRef;
-
-/* One time init data. */
-static pthread_once_t kSecSystemAnchorSourceInit = PTHREAD_ONCE_INIT;
-static SecCertificateSourceRef kSecSystemAnchorSource = NULL;
-
-static bool SecSystemAnchorSourceCopyParents(
-       SecCertificateSourceRef source, SecCertificateRef certificate,
-        void *context, SecCertificateSourceParents callback) {
-    callback(context, NULL);
-    return true;
-}
-
-static bool SecSystemAnchorSourceContains(SecCertificateSourceRef source,
-       SecCertificateRef certificate) {
-       SecSystemAnchorSourceRef sasource = (SecSystemAnchorSourceRef)source;
-       CFDataRef digest = SecCertificateGetSHA1Digest(certificate);
-       return CFSetContainsValue(sasource->digests, digest);
+static SecCertificateSourceRef SecItemCertificateSourceCreate(CFArrayRef accessGroups) {
+       SecItemCertificateSourceRef result = (SecItemCertificateSourceRef)malloc(sizeof(*result));
+       result->base.copyParents = SecItemCertificateSourceCopyParents;
+       result->base.contains = SecItemCertificateSourceContains;
+       result->accessGroups = accessGroups;
+    CFRetainSafe(accessGroups);
+       return (SecCertificateSourceRef)result;
 }
 
 }
 
-static void SecSystemAnchorSourceInit(void) {
-       SecSystemAnchorSourceRef result = (SecSystemAnchorSourceRef)
-               malloc(sizeof(*result));
-       result->base.copyParents = SecSystemAnchorSourceCopyParents;
-       result->base.contains = SecSystemAnchorSourceContains;
-
-       CFDataRef xmlData = SecFrameworkCopyResourceContents(
-               CFSTR("SystemAnchors"), CFSTR("plist"), NULL);
-       CFPropertyListRef plist = CFPropertyListCreateFromXMLData(
-               kCFAllocatorDefault, xmlData, kCFPropertyListImmutable, NULL);
-       if (plist) {
-               if (CFGetTypeID(plist) == CFDictionaryGetTypeID()) {
-                       result->digests = (CFSetRef)plist;
-               } else {
-                       secwarning("SystemAnchors plist is wrong type.");
-                       CFRelease(plist);
-               }
-       }
-
-       if (!result->digests) {
-               result->digests = CFSetCreate(kCFAllocatorDefault, NULL, 0,
-                       &kCFTypeSetCallBacks);
-       }
-
-       kSecSystemAnchorSource = (SecCertificateSourceRef)result;
+static void SecItemCertificateSourceDestroy(SecCertificateSourceRef source) {
+       SecItemCertificateSourceRef msource = (SecItemCertificateSourceRef)source;
+       CFReleaseSafe(msource->accessGroups);
+       free(msource);
 }
 
 }
 
-static SecCertificateSourceRef SecSystemAnchorSourceGetDefault(void) {
-    pthread_once(&kSecSystemAnchorSourceInit, SecSystemAnchorSourceInit);
-    return kSecSystemAnchorSource;
-}
-#else
-#pragma mark -
-#pragma mark SecSystemAnchorSource
+// MARK: -
+// MARK: SecSystemAnchorSource
 /********************************************************
  *********** SecSystemAnchorSource object ************
  ********************************************************/
 /********************************************************
  *********** SecSystemAnchorSource object ************
  ********************************************************/
+
 static bool SecSystemAnchorSourceCopyParents(
        SecCertificateSourceRef source, SecCertificateRef certificate,
         void *context, SecCertificateSourceParents callback) {
 #ifndef SECITEM_SHIM_OSX
 static bool SecSystemAnchorSourceCopyParents(
        SecCertificateSourceRef source, SecCertificateRef certificate,
         void *context, SecCertificateSourceParents callback) {
 #ifndef SECITEM_SHIM_OSX
-    CFMutableArrayRef parents = NULL;
+    CFArrayRef parents = NULL;
+       CFArrayRef anchors = NULL;
+       SecOTAPKIRef otapkiref = NULL;
+       
     CFDataRef nic = SecCertificateGetNormalizedIssuerContent(certificate);
     /* 64 bits cast: the worst that can happen here is we truncate the length and match an actual anchor.
        It does not matter since we would be returning the wrong anchors */
     assert((unsigned long)CFDataGetLength(nic)<UINT_MAX); /* Debug check. correct as long as CFIndex is signed long */
     CFDataRef nic = SecCertificateGetNormalizedIssuerContent(certificate);
     /* 64 bits cast: the worst that can happen here is we truncate the length and match an actual anchor.
        It does not matter since we would be returning the wrong anchors */
     assert((unsigned long)CFDataGetLength(nic)<UINT_MAX); /* Debug check. correct as long as CFIndex is signed long */
-    const struct subject_to_ix_t *i2x =
-        subject_to_anchor_ix((const char *)CFDataGetBytePtr(nic),
-            (unsigned int)CFDataGetLength(nic));
-    require_quiet(i2x, errOut);
-    int anchor_ix = i2x->anchor_ix;
-    CFIndex capacity = 0;
-    do {
-        ++capacity;
-    } while ((anchor_ix = anchorslist[anchor_ix].next_same_subject));
-
-    parents = CFArrayCreateMutable(kCFAllocatorDefault, capacity,
-        &kCFTypeArrayCallBacks);
-    anchor_ix = i2x->anchor_ix;
-    do {
-        const void *anchor = NULL;
-        CFDataRef anchor_data = NULL;
-
-        require_quiet(anchor_data = CFDataCreateWithBytesNoCopy(
-            kCFAllocatorDefault, (const UInt8 *)anchorslist[anchor_ix].data,
-            anchorslist[anchor_ix].length, kCFAllocatorNull), errOut);
-        anchor = SecCertificateCreateWithData(kCFAllocatorDefault,
-            anchor_data);
-        CFRelease(anchor_data);
-        if (anchor) {
-            CFArrayAppendValue(parents, anchor);
-            CFRelease(anchor);
-        }
-    } while ((anchor_ix = anchorslist[anchor_ix].next_same_subject));
+
+       otapkiref = SecOTAPKICopyCurrentOTAPKIRef();
+       require_quiet(otapkiref, errOut);
+       anchors = subject_to_anchors(nic);
+       require_quiet(anchors, errOut);
+       parents = CopyCertsFromIndices(anchors);
 
 errOut:
     callback(context, parents);
     CFReleaseSafe(parents);
 
 errOut:
     callback(context, parents);
     CFReleaseSafe(parents);
+       CFReleaseSafe(otapkiref);
 #endif
     return true;
 }
 #endif
     return true;
 }
@@ -297,36 +384,67 @@ errOut:
    before all others and we remember if we got a cert from an anchorsource. */
 static bool SecSystemAnchorSourceContains(SecCertificateSourceRef source,
        SecCertificateRef certificate) {
    before all others and we remember if we got a cert from an anchorsource. */
 static bool SecSystemAnchorSourceContains(SecCertificateSourceRef source,
        SecCertificateRef certificate) {
+       bool result = false;
 #ifndef SECITEM_SHIM_OSX
 #ifndef SECITEM_SHIM_OSX
+       CFArrayRef anchors = NULL;
+       SecOTAPKIRef otapkiref = NULL;
+       CFArrayRef cert_datas = NULL;
+       
     CFDataRef nic = SecCertificateGetNormalizedSubjectContent(certificate);
     /* 64 bits cast: the worst that can happen here is we truncate the length and match an actual anchor.
      It does not matter since we would be returning the wrong anchors */
     assert((unsigned long)CFDataGetLength(nic)<UINT_MAX); /* Debug check. correct as long as CFIndex is signed long */
     CFDataRef nic = SecCertificateGetNormalizedSubjectContent(certificate);
     /* 64 bits cast: the worst that can happen here is we truncate the length and match an actual anchor.
      It does not matter since we would be returning the wrong anchors */
     assert((unsigned long)CFDataGetLength(nic)<UINT_MAX); /* Debug check. correct as long as CFIndex is signed long */
-    const struct subject_to_ix_t *i2x =
-        subject_to_anchor_ix((const char *)CFDataGetBytePtr(nic),
-            (unsigned int)CFDataGetLength(nic));
-    require_quiet(i2x, errOut);
+    
+       otapkiref = SecOTAPKICopyCurrentOTAPKIRef();
+       require_quiet(otapkiref, errOut);
+    anchors = subject_to_anchors(nic);
+       require_quiet(anchors, errOut);
+    cert_datas = CopyCertDataFromIndices(anchors);
+    require_quiet(cert_datas, errOut);
+  
     CFIndex cert_length = SecCertificateGetLength(certificate);
     CFIndex cert_length = SecCertificateGetLength(certificate);
-    const UInt8 *cert_data = SecCertificateGetBytePtr(certificate);
-    int anchor_ix = i2x->anchor_ix;
-    do {
-        if (cert_length == anchorslist[anchor_ix].length &&
-            !memcmp(anchorslist[anchor_ix].data, cert_data, cert_length))
-            return true;
-    } while ((anchor_ix = anchorslist[anchor_ix].next_same_subject));
+    const UInt8 *cert_data_ptr = SecCertificateGetBytePtr(certificate);
+    
+    CFIndex num_cert_datas = CFArrayGetCount(cert_datas);
+    for (CFIndex idx = 0; idx < num_cert_datas; idx++)
+    {
+        CFDataRef cert_data = (CFDataRef)CFArrayGetValueAtIndex(cert_datas, idx);
+               
+               if (NULL != cert_data)
+               {
+            if (CFGetTypeID(cert_data) == CFDataGetTypeID())
+            {
+                CFIndex  aCert_Length = CFDataGetLength(cert_data);
+                const UInt8*  aCert_Data_Ptr = CFDataGetBytePtr(cert_data);
+                
+                if (aCert_Length == cert_length)
+                {
+                    if (!memcmp(cert_data_ptr, aCert_Data_Ptr, cert_length))
+                    {
+                                               result = true;
+                                               break;
+                    }
+                }
+            }
+               }
+    }
 
 errOut:
 
 errOut:
+       CFReleaseSafe(cert_datas);
+       CFReleaseSafe(otapkiref);
 #endif
 #endif
-    return false;
+    return result;
 }
 
 }
 
+
+
 struct SecCertificateSource kSecSystemAnchorSource = {
        SecSystemAnchorSourceCopyParents,
        SecSystemAnchorSourceContains
 };
 
 struct SecCertificateSource kSecSystemAnchorSource = {
        SecSystemAnchorSourceCopyParents,
        SecSystemAnchorSourceContains
 };
 
-#pragma mark -
-#pragma mark SecUserAnchorSource
+// MARK: -
+// MARK: SecUserAnchorSource
 /********************************************************
  *********** SecUserAnchorSource object ************
  ********************************************************/
 /********************************************************
  *********** SecUserAnchorSource object ************
  ********************************************************/
@@ -334,7 +452,7 @@ static bool SecUserAnchorSourceCopyParents(
        SecCertificateSourceRef source, SecCertificateRef certificate,
         void *context, SecCertificateSourceParents callback) {
     CFArrayRef parents = SecTrustStoreCopyParents(
        SecCertificateSourceRef source, SecCertificateRef certificate,
         void *context, SecCertificateSourceParents callback) {
     CFArrayRef parents = SecTrustStoreCopyParents(
-        SecTrustStoreForDomain(kSecTrustStoreDomainUser), certificate);
+        SecTrustStoreForDomain(kSecTrustStoreDomainUser), certificate, NULL);
     callback(context, parents);
     CFReleaseSafe(parents);
     return true;
     callback(context, parents);
     CFReleaseSafe(parents);
     return true;
@@ -350,10 +468,9 @@ struct SecCertificateSource kSecUserAnchorSource = {
        SecUserAnchorSourceCopyParents,
        SecUserAnchorSourceContains
 };
        SecUserAnchorSourceCopyParents,
        SecUserAnchorSourceContains
 };
-#endif
 
 
-#pragma mark -
-#pragma mark SecMemoryCertificateSource
+// MARK: -
+// MARK: SecMemoryCertificateSource
 /********************************************************
  *********** SecMemoryCertificateSource object ************
  ********************************************************/
 /********************************************************
  *********** SecMemoryCertificateSource object ************
  ********************************************************/
@@ -448,15 +565,15 @@ static void SecMemoryCertificateSourceDestroy(
        free(msource);
 }
 
        free(msource);
 }
 
-#pragma mark -
-#pragma mark SecCAIssuerCertificateSource
+// MARK: -
+// MARK: SecCAIssuerCertificateSource
 /********************************************************
  ********* SecCAIssuerCertificateSource object **********
  ********************************************************/
 static bool SecCAIssuerCertificateSourceCopyParents(
        SecCertificateSourceRef source, SecCertificateRef certificate,
         void *context, SecCertificateSourceParents callback) {
 /********************************************************
  ********* SecCAIssuerCertificateSource object **********
  ********************************************************/
 static bool SecCAIssuerCertificateSourceCopyParents(
        SecCertificateSourceRef source, SecCertificateRef certificate,
         void *context, SecCertificateSourceParents callback) {
-    return SecCAIssuerCopyParents(certificate, context, callback);
+    return SecCAIssuerCopyParents(certificate, SecPathBuilderGetQueue((SecPathBuilderRef)context), context, callback);
 }
 
 static bool SecCAIssuerCertificateSourceContains(
 }
 
 static bool SecCAIssuerCertificateSourceContains(
@@ -469,13 +586,15 @@ struct SecCertificateSource kSecCAIssuerSource = {
        SecCAIssuerCertificateSourceContains
 };
 
        SecCAIssuerCertificateSourceContains
 };
 
-#pragma mark -
-#pragma mark SecPathBuilder
+// MARK: -
+// MARK: SecPathBuilder
 /********************************************************
  *************** SecPathBuilder object ******************
  ********************************************************/
 struct SecPathBuilder {
 /********************************************************
  *************** SecPathBuilder object ******************
  ********************************************************/
 struct SecPathBuilder {
+    dispatch_queue_t queue;
        SecCertificateSourceRef certificateSource;
        SecCertificateSourceRef certificateSource;
+       SecCertificateSourceRef itemCertificateSource;
        SecCertificateSourceRef anchorSource;
        CFMutableArrayRef               anchorSources;
        CFIndex                                 nextParentSource;
        SecCertificateSourceRef anchorSource;
        CFMutableArrayRef               anchorSources;
        CFIndex                                 nextParentSource;
@@ -550,11 +669,13 @@ static void SecPathBuilderLeafCertificateChecks(SecPathBuilderRef builder,
 
 static void SecPathBuilderInit(SecPathBuilderRef builder,
        CFArrayRef certificates, CFArrayRef anchors, bool anchorsOnly,
 
 static void SecPathBuilderInit(SecPathBuilderRef builder,
        CFArrayRef certificates, CFArrayRef anchors, bool anchorsOnly,
-    CFArrayRef policies, CFAbsoluteTime verifyTime,
+    CFArrayRef policies, CFAbsoluteTime verifyTime, CFArrayRef accessGroups,
     SecPathBuilderCompleted completed, const void *context) {
     secdebug("alloc", "%p", builder);
        CFAllocatorRef allocator = kCFAllocatorDefault;
 
     SecPathBuilderCompleted completed, const void *context) {
     secdebug("alloc", "%p", builder);
        CFAllocatorRef allocator = kCFAllocatorDefault;
 
+    builder->queue = dispatch_queue_create("builder", DISPATCH_QUEUE_SERIAL);
+
        builder->nextParentSource = 1;
        builder->considerPartials = false;
     builder->canAccessNetwork = true;
        builder->nextParentSource = 1;
        builder->considerPartials = false;
     builder->canAccessNetwork = true;
@@ -589,7 +710,8 @@ static void SecPathBuilderInit(SecPathBuilderRef builder,
        if (builder->anchorSource) {
                CFArrayAppendValue(builder->anchorSources, builder->anchorSource);
        }
        if (builder->anchorSource) {
                CFArrayAppendValue(builder->anchorSources, builder->anchorSource);
        }
-       CFArrayAppendValue(builder->parentSources, &kSecItemCertificateSource);
+    builder->itemCertificateSource = SecItemCertificateSourceCreate(accessGroups);
+       CFArrayAppendValue(builder->parentSources, builder->itemCertificateSource);
     if (anchorsOnly) {
         /* Add the system and user anchor certificate db to the search list
            if we don't explicitly trust them. */
     if (anchorsOnly) {
         /* Add the system and user anchor certificate db to the search list
            if we don't explicitly trust them. */
@@ -624,21 +746,23 @@ static void SecPathBuilderInit(SecPathBuilderRef builder,
 
 SecPathBuilderRef SecPathBuilderCreate(CFArrayRef certificates,
     CFArrayRef anchors, bool anchorsOnly, CFArrayRef policies,
 
 SecPathBuilderRef SecPathBuilderCreate(CFArrayRef certificates,
     CFArrayRef anchors, bool anchorsOnly, CFArrayRef policies,
-    CFAbsoluteTime verifyTime,
+    CFAbsoluteTime verifyTime, CFArrayRef accessGroups,
     SecPathBuilderCompleted completed, const void *context) {
     SecPathBuilderRef builder = malloc(sizeof(*builder));
     SecPathBuilderInit(builder, certificates, anchors, anchorsOnly,
     SecPathBuilderCompleted completed, const void *context) {
     SecPathBuilderRef builder = malloc(sizeof(*builder));
     SecPathBuilderInit(builder, certificates, anchors, anchorsOnly,
-        policies, verifyTime, completed, context);
+        policies, verifyTime, accessGroups, completed, context);
     return builder;
 }
 
 static void SecPathBuilderDestroy(SecPathBuilderRef builder) {
     secdebug("alloc", "%p", builder);
     return builder;
 }
 
 static void SecPathBuilderDestroy(SecPathBuilderRef builder) {
     secdebug("alloc", "%p", builder);
+    dispatch_release_null(builder->queue);
        if (builder->anchorSource)
                SecMemoryCertificateSourceDestroy(builder->anchorSource);
        if (builder->certificateSource)
                SecMemoryCertificateSourceDestroy(builder->certificateSource);
        if (builder->anchorSource)
                SecMemoryCertificateSourceDestroy(builder->anchorSource);
        if (builder->certificateSource)
                SecMemoryCertificateSourceDestroy(builder->certificateSource);
-
+    if (builder->itemCertificateSource)
+        SecItemCertificateSourceDestroy(builder->itemCertificateSource);
        CFReleaseSafe(builder->anchorSources);
        CFReleaseSafe(builder->parentSources);
        CFReleaseSafe(builder->allPaths);
        CFReleaseSafe(builder->anchorSources);
        CFReleaseSafe(builder->parentSources);
        CFReleaseSafe(builder->allPaths);
@@ -738,7 +862,7 @@ static void SecPathBuilderProccessParents(SecPathBuilderRef builder,
     CFIndex parentIX;
     bool is_anchor = SecCertificatePathGetNextSourceIndex(partial) <=
         CFArrayGetCount(builder->anchorSources);
     CFIndex parentIX;
     bool is_anchor = SecCertificatePathGetNextSourceIndex(partial) <=
         CFArrayGetCount(builder->anchorSources);
-    secdebug("trust", "found %d candidate %s", num_parents,
+    secdebug("trust", "found %" PRIdCFIndex " candidate %s", num_parents,
              (is_anchor ? "anchors" : "parents"));
     for (parentIX = 0; parentIX < num_parents; ++parentIX) {
         SecCertificateRef parent = (SecCertificateRef)
              (is_anchor ? "anchors" : "parents"));
     for (parentIX = 0; parentIX < num_parents; ++parentIX) {
         SecCertificateRef parent = (SecCertificateRef)
@@ -771,7 +895,7 @@ static void SecPathBuilderProccessParents(SecPathBuilderRef builder,
                    candiate partial. */
                 CFArrayInsertValueAtIndex(builder->partialPaths,
                     ++builder->partialIX, path);
                    candiate partial. */
                 CFArrayInsertValueAtIndex(builder->partialPaths,
                     ++builder->partialIX, path);
-                secdebug("trust", "Adding partial for parent %d/%d %@",
+                secdebug("trust", "Adding partial for parent %" PRIdCFIndex "/%" PRIdCFIndex " %@",
                     parentIX + 1, num_parents, path);
             }
             secdebug("trust", "found new path %@", path);
                     parentIX + 1, num_parents, path);
             }
             secdebug("trust", "found new path %@", path);
@@ -836,7 +960,7 @@ static bool SecPathBuilderGetNext(SecPathBuilderRef builder) {
         CFIndex num_sources = CFArrayGetCount(builder->parentSources);
         if (builder->nextParentSource < num_sources) {
             builder->nextParentSource++;
         CFIndex num_sources = CFArrayGetCount(builder->parentSources);
         if (builder->nextParentSource < num_sources) {
             builder->nextParentSource++;
-            secdebug("trust", "broading search to %d/%d sources",
+            secdebug("trust", "broading search to %" PRIdCFIndex "/%" PRIdCFIndex " sources",
                 builder->nextParentSource, num_sources);
         } else {
             /* We've run out of new sources to consider so let's look at
                 builder->nextParentSource, num_sources);
         } else {
             /* We've run out of new sources to consider so let's look at
@@ -860,7 +984,7 @@ static bool SecPathBuilderGetNext(SecPathBuilderRef builder) {
             }
         }
         builder->partialIX = CFArrayGetCount(builder->partialPaths) - 1;
             }
         }
         builder->partialIX = CFArrayGetCount(builder->partialPaths) - 1;
-        secdebug("trust", "re-checking %d partials", builder->partialIX + 1);
+        secdebug("trust", "re-checking %" PRIdCFIndex " partials", builder->partialIX + 1);
         return true;
     }
 
         return true;
     }
 
@@ -879,7 +1003,7 @@ static bool SecPathBuilderGetNext(SecPathBuilderRef builder) {
 
     /* Attempt to extend this partial path with another certificate. This
        should give us a list of potential parents to consider. */
 
     /* Attempt to extend this partial path with another certificate. This
        should give us a list of potential parents to consider. */
-    secdebug("trust", "looking for parents of partial %d/%d: %@",
+    secdebug("trust", "looking for parents of partial %" PRIdCFIndex "/%" PRIdCFIndex ": %@",
         builder->partialIX + 1, CFArrayGetCount(builder->partialPaths),
         partial);
 
         builder->partialIX + 1, CFArrayGetCount(builder->partialPaths),
         partial);
 
@@ -892,13 +1016,13 @@ static bool SecPathBuilderGetNext(SecPathBuilderRef builder) {
         if (sourceIX < num_anchor_sources) {
             source = (SecCertificateSourceRef)
                 CFArrayGetValueAtIndex(builder->anchorSources, sourceIX);
         if (sourceIX < num_anchor_sources) {
             source = (SecCertificateSourceRef)
                 CFArrayGetValueAtIndex(builder->anchorSources, sourceIX);
-            secdebug("trust", "searching anchor source %d/%d", sourceIX + 1,
+            secdebug("trust", "searching anchor source %" PRIdCFIndex "/%" PRIdCFIndex, sourceIX + 1,
                      num_anchor_sources);
         } else {
             CFIndex parentIX = sourceIX - num_anchor_sources;
             source = (SecCertificateSourceRef)
                 CFArrayGetValueAtIndex(builder->parentSources, parentIX);
                      num_anchor_sources);
         } else {
             CFIndex parentIX = sourceIX - num_anchor_sources;
             source = (SecCertificateSourceRef)
                 CFArrayGetValueAtIndex(builder->parentSources, parentIX);
-            secdebug("trust", "searching parent source %d/%d", parentIX + 1,
+            secdebug("trust", "searching parent source %" PRIdCFIndex "/%" PRIdCFIndex, parentIX + 1,
                      builder->nextParentSource);
         }
         SecCertificatePathSetNextSourceIndex(partial, sourceIX + 1);
                      builder->nextParentSource);
         }
         SecCertificatePathSetNextSourceIndex(partial, sourceIX + 1);
@@ -951,13 +1075,13 @@ static void SecPathBuilderReject(SecPathBuilderRef builder) {
        if (!builder->bestPath || score > rejectScore) {
         if (builder->bestPath) {
             secdebug("reject",
        if (!builder->bestPath || score > rejectScore) {
         if (builder->bestPath) {
             secdebug("reject",
-                "replacing %sev %s score: %ld with %sev reject score: %d %@",
+                "replacing %sev %s score: %ld with %sev reject score: %" PRIdCFIndex " %@",
                 (builder->bestPathIsEV ? "" : "non "),
                 (builder->rejectScore == INTPTR_MAX ? "accept" : "reject"),
                 builder->rejectScore,
                 (builder->bestPathIsEV ? "" : "non "),
                 (builder->rejectScore == INTPTR_MAX ? "accept" : "reject"),
                 builder->rejectScore,
-                (pvc->is_ev ? "" : "non "), score, builder->path.path);
+                (pvc->is_ev ? "" : "non "), (long)score, builder->path.path);
         } else {
         } else {
-            secdebug("reject", "%sev reject score: %d %@",
+            secdebug("reject", "%sev reject score: %" PRIdCFIndex " %@",
                 (pvc->is_ev ? "" : "non "), score, builder->path.path);
         }
 
                 (pvc->is_ev ? "" : "non "), score, builder->path.path);
         }
 
@@ -965,7 +1089,7 @@ static void SecPathBuilderReject(SecPathBuilderRef builder) {
         builder->bestPath = pvc->path;
         builder->bestPathIsEV = pvc->is_ev;
        } else {
         builder->bestPath = pvc->path;
         builder->bestPathIsEV = pvc->is_ev;
        } else {
-        secdebug("reject", "%sev reject score: %d lower than %d %@",
+        secdebug("reject", "%sev reject score: %" PRIdCFIndex " lower than %" PRIdCFIndex " %@",
             (pvc->is_ev ? "" : "non "), score, rejectScore, builder->path.path);
     }
 }
             (pvc->is_ev ? "" : "non "), score, rejectScore, builder->path.path);
     }
 }
@@ -1017,6 +1141,7 @@ static bool SecPathBuilderDidValidatePath(SecPathBuilderRef builder) {
 }
 
 static bool SecPathBuilderComputeDetails(SecPathBuilderRef builder) {
 }
 
 static bool SecPathBuilderComputeDetails(SecPathBuilderRef builder) {
+    // foobar
     SecPVCRef pvc = &builder->path;
 #if 0
     if (!builder->caller_wants_details) {
     SecPVCRef pvc = &builder->path;
 #if 0
     if (!builder->caller_wants_details) {
@@ -1041,7 +1166,8 @@ static bool SecPathBuilderComputeDetails(SecPathBuilderRef builder) {
         CFArrayAppendValue(details, certDetail);
         CFRelease(certDetail);
         SecPVCParentCertificateChecks(pvc, ix);
         CFArrayAppendValue(details, certDetail);
         CFRelease(certDetail);
         SecPVCParentCertificateChecks(pvc, ix);
-        SecPVCBlackListedKeyChecks(pvc, ix);
+               SecPVCGrayListedKeyChecks(pvc, ix);
+               SecPVCBlackListedKeyChecks(pvc, ix);
     }
     builder->state = SecPathBuilderReportResult;
     bool completed = SecPVCPathChecks(pvc);
     }
     builder->state = SecPathBuilderReportResult;
     bool completed = SecPVCPathChecks(pvc);
@@ -1131,8 +1257,10 @@ bool SecPathBuilderStep(SecPathBuilderRef builder) {
 
     SecTrustResultType result = (builder->rejectScore == INTPTR_MAX
         ? kSecTrustResultUnspecified : kSecTrustResultRecoverableTrustFailure);
 
     SecTrustResultType result = (builder->rejectScore == INTPTR_MAX
         ? kSecTrustResultUnspecified : kSecTrustResultRecoverableTrustFailure);
+    
     secdebug("trust", "completed: %@ details: %@ result: %d",
         builder->bestPath, builder->path.details, result);
     secdebug("trust", "completed: %@ details: %@ result: %d",
         builder->bestPath, builder->path.details, result);
+    
     if (builder->completed) {
         builder->completed(builder->context, builder->bestPath,
             builder->path.details, builder->path.info, result);
     if (builder->completed) {
         builder->completed(builder->context, builder->bestPath,
             builder->path.details, builder->path.info, result);
@@ -1145,113 +1273,67 @@ bool SecPathBuilderStep(SecPathBuilderRef builder) {
     return false;
 }
 
     return false;
 }
 
+dispatch_queue_t SecPathBuilderGetQueue(SecPathBuilderRef builder) {
+    return builder->queue;
+}
 
 
-#pragma mark -
-#pragma mark SecTrustServer
+// MARK: -
+// MARK: SecTrustServer
 /********************************************************
  ****************** SecTrustServer **********************
  ********************************************************/
 
 /********************************************************
  ****************** SecTrustServer **********************
  ********************************************************/
 
-/* AUDIT[securityd](done):
-   args_in (ok) is a caller provided dictionary, only its cf type has been checked.
- */
-OSStatus
-SecTrustServerEvaluateAsync(CFDictionaryRef args_in,
-    SecPathBuilderCompleted completed, const void *userData) {
-    OSStatus status = paramErr;
-    CFArrayRef certificates = NULL, anchors = NULL, policies = NULL;
-
-    /* Proccess incoming arguments. */
-    CFArrayRef certificatesData = (CFArrayRef)CFDictionaryGetValue(args_in, kSecTrustCertificatesKey);
-    require_quiet(certificatesData && CFGetTypeID(certificatesData) == CFArrayGetTypeID(), errOut);
-    certificates = SecCertificateDataArrayCopyArray(certificatesData);
-    require_quiet(certificates
-        && CFGetTypeID(certificates) == CFArrayGetTypeID()
-        && CFArrayGetCount(certificates) > 0, errOut);
-    CFArrayRef anchorsData = (CFArrayRef)CFDictionaryGetValue(args_in, kSecTrustAnchorsKey);
-    if (anchorsData) {
-        require_quiet(CFGetTypeID(anchorsData) == CFArrayGetTypeID(), errOut);
-        anchors = SecCertificateDataArrayCopyArray(anchorsData);
-    }
-    bool anchorsOnly = CFDictionaryContainsKey(args_in, kSecTrustAnchorsOnlyKey);
-    CFArrayRef serializedPolicies = (CFArrayRef)CFDictionaryGetValue(args_in, kSecTrustPoliciesKey);
-    if (serializedPolicies) {
-        require_quiet(CFGetTypeID(serializedPolicies) == CFArrayGetTypeID(), errOut);
-        policies = SecPolicyArrayDeserialize(serializedPolicies);
-    }
-    CFDateRef verifyDate = (CFDateRef)CFDictionaryGetValue(args_in, kSecTrustVerifyDateKey);
-    require_quiet(verifyDate && CFGetTypeID(verifyDate) == CFDateGetTypeID(), errOut);
-    CFAbsoluteTime verifyTime = CFDateGetAbsoluteTime(verifyDate);
+typedef void (^SecTrustServerEvaluationCompleted)(SecTrustResultType tr, CFArrayRef details, CFDictionaryRef info, SecCertificatePathRef chain, CFErrorRef error);
+
+static void
+SecTrustServerEvaluateCompleted(const void *userData,
+                                SecCertificatePathRef chain, CFArrayRef details, CFDictionaryRef info,
+                                SecTrustResultType result) {
+    SecTrustServerEvaluationCompleted evaluated = (SecTrustServerEvaluationCompleted)userData;
+    evaluated(result, details, info, chain, NULL);
+    Block_release(evaluated);
+}
 
 
+void
+SecTrustServerEvaluateBlock(CFArrayRef certificates, CFArrayRef anchors, bool anchorsOnly, CFArrayRef policies, CFAbsoluteTime verifyTime, __unused CFArrayRef accessGroups, void (^evaluated)(SecTrustResultType tr, CFArrayRef details, CFDictionaryRef info, SecCertificatePathRef chain, CFErrorRef error)) {
+    SecTrustServerEvaluationCompleted userData = Block_copy(evaluated);
     /* Call the actual evaluator function. */
     SecPathBuilderRef builder = SecPathBuilderCreate(certificates, anchors,
     /* Call the actual evaluator function. */
     SecPathBuilderRef builder = SecPathBuilderCreate(certificates, anchors,
-        anchorsOnly, policies, verifyTime, completed, userData);
-    status = SecPathBuilderStep(builder) ? errSecWaitForCallback : noErr;
-
-errOut:
-    CFReleaseSafe(policies);
-    CFReleaseSafe(anchors);
-    CFReleaseSafe(certificates);
-    return status;
+                                                     anchorsOnly, policies,
+                                                     verifyTime, accessGroups,
+                                                     SecTrustServerEvaluateCompleted, userData);
+    dispatch_async(builder->queue, ^{ SecPathBuilderStep(builder); });
 }
 
 }
 
-struct SecTrustEvaluationContext {
-    CFTypeRef args_out;
-    bool running;
-};
-
-static void
-SecTrustServerEvaluateDone(const void *userData,
-    SecCertificatePathRef chain, CFArrayRef details, CFDictionaryRef info,
-    SecTrustResultType result) {
-    struct SecTrustEvaluationContext *tec =
-        (struct SecTrustEvaluationContext *)userData;
-
-    /* @@@ This code snippit is also in server.c.  I'd factor it, but a better
-       fix would be to chage the interfaces here to not use single in/out args
-       and do all the argument munging in server.c and client.c. */
-    CFDictionaryRef args_out;
-    CFNumberRef resultNumber = NULL;
-    CFArrayRef chain_certs = NULL;
-    /* Proccess outgoing results. */
-    resultNumber = CFNumberCreate(NULL, kCFNumberSInt32Type, &result);
-    chain_certs = SecCertificatePathCopyArray(chain);
-    const void *out_keys[] = { kSecTrustChainKey, kSecTrustDetailsKey,
-        kSecTrustInfoKey, kSecTrustResultKey };
-    const void *out_values[] = { chain_certs, details, info, resultNumber };
-    args_out = (CFTypeRef)CFDictionaryCreate(kCFAllocatorDefault, out_keys,
-        out_values, sizeof(out_keys) / sizeof(*out_keys),
-        &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-    CFReleaseSafe(chain_certs);
-    CFReleaseSafe(resultNumber);
-
-    /* Return the final result. */
-    tec->args_out = args_out;
-    if (tec->running) {
-        /* Stop the runloop in SecTrustServerEvaluate if it is running. */
-        CFRunLoopStop(CFRunLoopGetCurrent());
-    }
-}
 
 
-OSStatus
-SecTrustServerEvaluate(CFDictionaryRef args_in, CFTypeRef *args_out) {
-    OSStatus status;
-    struct SecTrustEvaluationContext tec;
-    tec.args_out = NULL;
-    tec.running = false;
-    status = SecTrustServerEvaluateAsync(args_in, SecTrustServerEvaluateDone,
-        &tec);
-    if (status == noErr || status == errSecWaitForCallback) {
-        if (status == errSecWaitForCallback) {
-            /* Since errSecWaitForCallback isn't a real error clear status. */
-            status = noErr;
-            /* Mark the context as running so the callback will stop the runloop,
-               and run the default runloop until the callback stops us. */
-            tec.running = true;
-            CFRunLoopRun();
+// NO_SERVER Shim code only, xpc interface should call SecTrustServerEvaluateBlock() directly
+SecTrustResultType SecTrustServerEvaluate(CFArrayRef certificates, CFArrayRef anchors, bool anchorsOnly, CFArrayRef policies, CFAbsoluteTime verifyTime, __unused CFArrayRef accessGroups, CFArrayRef *pdetails, CFDictionaryRef *pinfo, SecCertificatePathRef *pchain, CFErrorRef *perror) {
+    dispatch_semaphore_t done = dispatch_semaphore_create(0);
+    __block SecTrustResultType result = kSecTrustResultInvalid;
+    SecTrustServerEvaluateBlock(certificates, anchors, anchorsOnly, policies, verifyTime, accessGroups, ^(SecTrustResultType tr, CFArrayRef details, CFDictionaryRef info, SecCertificatePathRef chain, CFErrorRef error) {
+        result = tr;
+        if (tr == kSecTrustResultInvalid) {
+            if (perror) {
+                *perror = error;
+                CFRetainSafe(error);
+            }
+        } else {
+            if (pdetails) {
+                *pdetails = details;
+                CFRetainSafe(details);
+            }
+            if (pinfo) {
+                *pinfo = info;
+                CFRetainSafe(info);
+            }
+            if (pchain) {
+                *pchain = chain;
+                CFRetainSafe(chain);
+            }
         }
         }
-        *args_out = tec.args_out;
-    }
+        dispatch_semaphore_signal(done);
+    });
+    dispatch_semaphore_wait(done, DISPATCH_TIME_FOREVER);
 
 
-    return status;
+    return result;
 }
 }
index 695a8779b3d3d6ea93c228b0128ce90f7cceb576..0a5b88887f6e75a8e9a6429a1ed8b33dd9e7e3fd 100644 (file)
 #include <mach/port.h>
 
 
 #include <mach/port.h>
 
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 
 /* args_in keys. */
 
 
 /* args_in keys. */
-#define kSecTrustCertificatesKey CFSTR("certificates")
-#define kSecTrustAnchorsKey CFSTR("anchors")
-#define kSecTrustAnchorsOnlyKey CFSTR("anchorsOnly")
-#define kSecTrustPoliciesKey CFSTR("policies")
-#define kSecTrustVerifyDateKey CFSTR("verifyDate")
+#define kSecTrustCertificatesKey "certificates"
+#define kSecTrustAnchorsKey "anchors"
+#define kSecTrustAnchorsOnlyKey "anchorsOnly"
+#define kSecTrustPoliciesKey "policies"
+#define kSecTrustVerifyDateKey "verifyDate"
 
 /* args_out keys. */
 
 /* args_out keys. */
-#define kSecTrustDetailsKey CFSTR("details")
-#define kSecTrustChainKey CFSTR("chain")
-#define kSecTrustResultKey CFSTR("result")
-#define kSecTrustInfoKey CFSTR("info")
+#define kSecTrustDetailsKey "details"
+#define kSecTrustChainKey "chain"
+#define kSecTrustResultKey "result"
+#define kSecTrustInfoKey "info"
 
 typedef struct SecPathBuilder *SecPathBuilderRef;
 
 
 typedef struct SecPathBuilder *SecPathBuilderRef;
 
@@ -65,7 +63,7 @@ typedef void(*SecPathBuilderCompleted)(const void *userData,
 /* Returns a new trust path builder and policy evaluation engine instance. */
 SecPathBuilderRef SecPathBuilderCreate(CFArrayRef certificates,
     CFArrayRef anchors, bool anchorsOnly, CFArrayRef policies,
 /* Returns a new trust path builder and policy evaluation engine instance. */
 SecPathBuilderRef SecPathBuilderCreate(CFArrayRef certificates,
     CFArrayRef anchors, bool anchorsOnly, CFArrayRef policies,
-    CFAbsoluteTime verifyTime,
+    CFAbsoluteTime verifyTime, CFArrayRef accessGroups,
     SecPathBuilderCompleted completed, const void *userData);
 
 /* Returns true if it's ok to perform network operations for this builder. */
     SecPathBuilderCompleted completed, const void *userData);
 
 /* Returns true if it's ok to perform network operations for this builder. */
@@ -81,19 +79,17 @@ void SecPathBuilderSetCanAccessNetwork(SecPathBuilderRef builder, bool allow);
    network). */
 bool SecPathBuilderStep(SecPathBuilderRef builder);
 
    network). */
 bool SecPathBuilderStep(SecPathBuilderRef builder);
 
+/* Return the dispatch queue to be used by this builder. */
+dispatch_queue_t SecPathBuilderGetQueue(SecPathBuilderRef builder);
 
 
-/* Returns noErr if the operation has completed synchronously.  Returns
-   errSecWaitForCallback if the operation is running in the background. Can
-   also return paramErr if one or more of the inputs aren't correct.  Upon
-   completion the completed callback is called. */
-OSStatus SecTrustServerEvaluateAsync(CFDictionaryRef args_in,
-    SecPathBuilderCompleted completed, const void *userData);
+/* Evaluate trust and call evaluated when done. */
+void SecTrustServerEvaluateBlock(CFArrayRef certificates, CFArrayRef anchors, bool anchorsOnly, CFArrayRef policies, CFAbsoluteTime verifyTime, __unused CFArrayRef accessGroups, void (^evaluated)(SecTrustResultType tr, CFArrayRef details, CFDictionaryRef info, SecCertificatePathRef chain, CFErrorRef error));
+
+/* Synchronously invoke SecTrustServerEvaluateBlock. */
+SecTrustResultType SecTrustServerEvaluate(CFArrayRef certificates, CFArrayRef anchors, bool anchorsOnly, CFArrayRef policies, CFAbsoluteTime verifyTime, __unused CFArrayRef accessGroups, CFArrayRef *details, CFDictionaryRef *info, SecCertificatePathRef *chain, CFErrorRef *error);
 
 
-/* Synchronously invoke SecTrustServerEvaluateAsync. */
-OSStatus SecTrustServerEvaluate(CFDictionaryRef args_in, CFTypeRef *args_out);
+void InitializeAnchorTable(void);
 
 
-#if defined(__cplusplus)
-}
-#endif
+__END_DECLS
 
 #endif /* !_SECURITY_SECTRUSTSERVER_H_ */
 
 #endif /* !_SECURITY_SECTRUSTSERVER_H_ */
index 549886f843b78f193f0c6dd907322cb96fee4f4e..18a1e48cc3a5ff20938ec6bf4e3b2d597c409c9d 100644 (file)
@@ -30,7 +30,7 @@
 #include <Security/SecFramework.h>
 #include <errno.h>
 #include <limits.h>
 #include <Security/SecFramework.h>
 #include <errno.h>
 #include <limits.h>
-#include <pthread.h>
+#include <dispatch/dispatch.h>
 #include <sqlite3.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <sqlite3.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <CoreFoundation/CFPropertyList.h>
 #include <CoreFoundation/CFURL.h>
 #include <AssertMacros.h>
 #include <CoreFoundation/CFPropertyList.h>
 #include <CoreFoundation/CFURL.h>
 #include <AssertMacros.h>
-#include <security_utilities/debugging.h>
+#include <utilities/debugging.h>
 #include "SecBasePriv.h"
 #include <Security/SecInternal.h>
 #include "securityd_client.h"
 #include "SecBasePriv.h"
 #include <Security/SecInternal.h>
 #include "securityd_client.h"
-#include "securityd_server.h"
-#include "sqlutils.h"
+#include <securityd/SecTrustStoreServer.h>
+#include "utilities/sqlutils.h"
+#include "utilities/SecDb.h"
+#include <utilities/SecCFError.h>
+#include "utilities/SecFileLocations.h"
+#include <utilities/SecDispatchRelease.h>
 
 /* uid of the _securityd user. */
 #define SECURTYD_UID 64
 
 
 /* uid of the _securityd user. */
 #define SECURTYD_UID 64
 
-#if 0
-#include <CoreFoundation/CFPriv.h>
-#else
-CF_EXPORT
-CFURLRef CFCopyHomeDirectoryURLForUser(CFStringRef uName);     /* Pass NULL for the current user's home directory */
-#endif
-
-static pthread_once_t kSecTrustStoreUserOnce = PTHREAD_ONCE_INIT;
+static dispatch_once_t kSecTrustStoreUserOnce;
 static SecTrustStoreRef kSecTrustStoreUser = NULL;
 
 static const char copyParentsSQL[] = "SELECT data FROM tsettings WHERE subj=?";
 static SecTrustStoreRef kSecTrustStoreUser = NULL;
 
 static const char copyParentsSQL[] = "SELECT data FROM tsettings WHERE subj=?";
@@ -72,11 +69,11 @@ static const char deleteAllSQL[] = "BEGIN EXCLUSIVE TRANSACTION; DELETE from tse
 #define kSecTrustStoreName CFSTR("TrustStore")
 #define kSecTrustStoreDbExtension CFSTR("sqlite3")
 
 #define kSecTrustStoreName CFSTR("TrustStore")
 #define kSecTrustStoreDbExtension CFSTR("sqlite3")
 
-#define kSecTrustStoreUserPath "/Library/Keychains/TrustStore.sqlite3"
+#define kTrustStoreFileName CFSTR("TrustStore.sqlite3")
 
 
 struct __SecTrustStore {
 
 
 struct __SecTrustStore {
-       pthread_mutex_t lock;
+    dispatch_queue_t queue;
        sqlite3 *s3h;
        sqlite3_stmt *copyParents;
        sqlite3_stmt *contains;
        sqlite3 *s3h;
        sqlite3_stmt *copyParents;
        sqlite3_stmt *contains;
@@ -145,7 +142,7 @@ static SecTrustStoreRef SecTrustStoreCreate(const char *db_name,
        int s3e;
 
        require(ts = (SecTrustStoreRef)malloc(sizeof(struct __SecTrustStore)), errOut);
        int s3e;
 
        require(ts = (SecTrustStoreRef)malloc(sizeof(struct __SecTrustStore)), errOut);
-       pthread_mutex_init(&ts->lock, NULL);
+    ts->queue = dispatch_queue_create("truststore", DISPATCH_QUEUE_SERIAL);
        require_noerr(s3e = sec_sqlite3_open(db_name, &ts->s3h, create), errOut);
 
        s3e = sqlite3_prepare(ts->s3h, copyParentsSQL, sizeof(copyParentsSQL),
        require_noerr(s3e = sec_sqlite3_open(db_name, &ts->s3h, create), errOut);
 
        s3e = sqlite3_prepare(ts->s3h, copyParentsSQL, sizeof(copyParentsSQL),
@@ -181,63 +178,46 @@ static SecTrustStoreRef SecTrustStoreCreate(const char *db_name,
 errOut:
        if (ts) {
                sqlite3_close(ts->s3h);
 errOut:
        if (ts) {
                sqlite3_close(ts->s3h);
-               pthread_mutex_destroy(&ts->lock);
+        dispatch_release_safe(ts->queue);
                free(ts);
        }
 
        return NULL;
 }
 
                free(ts);
        }
 
        return NULL;
 }
 
-static void SecTrustStoreInitUser(void) {
-       static const char * path = kSecTrustStoreUserPath;
-#if NO_SERVER
-    /* Added this block of code back to keep the tests happy for now. */
-       const char *home = getenv("HOME");
-       char buffer[PATH_MAX];
-       size_t homeLen;
-       size_t pathLen = strlen(path);
-       if (home) {
-               homeLen = strlen(home);
-               if (homeLen + pathLen >= sizeof(buffer)) {
-                       return;
-               }
-
-               strlcpy(buffer, home, sizeof(buffer));
-       } else {
-               CFURLRef homeURL = CFCopyHomeDirectoryURLForUser(NULL);
-               if (!homeURL)
-                       return;
-
-               CFURLGetFileSystemRepresentation(homeURL, true, (uint8_t *)buffer,
-                       sizeof(buffer));
-               CFRelease(homeURL);
-               homeLen = strlen(buffer);
-               buffer[homeLen] = '\0';
-               if (homeLen + pathLen >= sizeof(buffer)) {
-                       return;
-               }
-       }
-
-       strlcat(buffer, path, sizeof(buffer));
-
-    path = buffer;
-
-#endif
+static bool SecExtractFilesystemPathForKeychainFile(CFStringRef file, UInt8 *buffer, CFIndex maxBufLen)
+{
+    bool translated = false;
+    CFURLRef fileURL = SecCopyURLForFileInKeychainDirectory(file);
+    
+    if (fileURL && CFURLGetFileSystemRepresentation(fileURL, false, buffer, maxBufLen))
+        translated = true;
+    CFReleaseSafe(fileURL);
+    
+    return translated;
+}
 
 
-       kSecTrustStoreUser = SecTrustStoreCreate(path, true);
-    if (kSecTrustStoreUser)
-               kSecTrustStoreUser->readOnly = false;
+static void SecTrustStoreInitUser(void) {
+       const char path[MAXPATHLEN];
+    
+    if (SecExtractFilesystemPathForKeychainFile(kTrustStoreFileName, (UInt8*) path, (CFIndex) sizeof(path)))
+    {
+        kSecTrustStoreUser = SecTrustStoreCreate(path, true);
+        if (kSecTrustStoreUser)
+            kSecTrustStoreUser->readOnly = false;
+    }    
 }
 
 /* AUDIT[securityd](done):
    domainName (ok) is a caller provided string of any length (might be 0), only
        its cf type has been checked.
  */
 }
 
 /* AUDIT[securityd](done):
    domainName (ok) is a caller provided string of any length (might be 0), only
        its cf type has been checked.
  */
-SecTrustStoreRef SecTrustStoreForDomainName(CFStringRef domainName) {
+SecTrustStoreRef SecTrustStoreForDomainName(CFStringRef domainName, CFErrorRef *error) {
        if (CFEqual(CFSTR("user"), domainName)) {
        if (CFEqual(CFSTR("user"), domainName)) {
-               pthread_once(&kSecTrustStoreUserOnce, SecTrustStoreInitUser);
+               dispatch_once(&kSecTrustStoreUserOnce, ^{ SecTrustStoreInitUser(); });
                return kSecTrustStoreUser;
        } else {
                return kSecTrustStoreUser;
        } else {
+        SecError(errSecParam, error, CFSTR("unknown domain: %@"), domainName);
                return NULL;
        }
 }
                return NULL;
        }
 }
@@ -248,199 +228,196 @@ SecTrustStoreRef SecTrustStoreForDomainName(CFStringRef domainName) {
    trustSettingsDictOrArray (checked by CFPropertyListCreateXMLData) is either
    NULL, a dictionary or an array, but its contents have not been checked.
  */
    trustSettingsDictOrArray (checked by CFPropertyListCreateXMLData) is either
    NULL, a dictionary or an array, but its contents have not been checked.
  */
-OSStatus _SecTrustStoreSetTrustSettings(SecTrustStoreRef ts,
+bool _SecTrustStoreSetTrustSettings(SecTrustStoreRef ts,
        SecCertificateRef certificate,
        SecCertificateRef certificate,
-    CFTypeRef trustSettingsDictOrArray) {
-       OSStatus status = errSecParam;
+    CFTypeRef tsdoa, CFErrorRef *error) {
+    __block bool ok;
+       require_action_quiet(ts, errOutNotLocked, ok = SecError(errSecParam, error, CFSTR("truststore is NULL")));
+    require_action_quiet(!ts->readOnly, errOutNotLocked, ok = SecError(errSecReadOnly, error, CFSTR("truststore is readOnly")));
+    dispatch_sync(ts->queue, ^{
+        CFTypeRef trustSettingsDictOrArray = tsdoa;
+        sqlite3_stmt *insert = NULL, *update = NULL;
+        CFDataRef xmlData = NULL;
+        CFArrayRef array = NULL;
+
+        CFDataRef subject;
+        require_action_quiet(subject = SecCertificateGetNormalizedSubjectContent(certificate),
+                             errOut, ok = SecError(errSecParam, error, CFSTR("get normalized subject failed")));
+        CFDataRef digest;
+        require_action_quiet(digest = SecCertificateGetSHA1Digest(certificate), errOut, ok = SecError(errSecParam, error, CFSTR("get sha1 digest failed")));
+
+        /* Do some basic checks on the trust settings passed in. */
+        if (trustSettingsDictOrArray == NULL) {
+            require_action_quiet(array = CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks), errOut, ok = SecError(errSecAllocate, error, CFSTR("CFArrayCreate failed")));
+            trustSettingsDictOrArray = array;
+        }
+        else if(CFGetTypeID(trustSettingsDictOrArray) == CFDictionaryGetTypeID()) {
+            /* array-ize it */
+            array = CFArrayCreate(NULL, &trustSettingsDictOrArray, 1,
+                                  &kCFTypeArrayCallBacks);
+            trustSettingsDictOrArray = array;
+        }
+        else {
+            require_action_quiet(CFGetTypeID(trustSettingsDictOrArray) == CFArrayGetTypeID(), errOut, ok = SecError(errSecParam, error, CFSTR("trustSettingsDictOrArray neither dict nor array")));
+        }
 
 
-       require_quiet(ts, errOutNotLocked);
-       if (ts->readOnly) {
-               status = errSecReadOnly;
-        goto errOutNotLocked;
-    }
-       require_noerr(pthread_mutex_lock(&ts->lock), errOutNotLocked);
-       sqlite3_stmt *insert = NULL, *update = NULL;
-    CFDataRef xmlData = NULL;
-    CFArrayRef array = NULL;
-
-       CFDataRef subject;
-       require(subject = SecCertificateGetNormalizedSubjectContent(certificate),
-               errOut);
-    CFDataRef digest;
-       require(digest = SecCertificateGetSHA1Digest(certificate), errOut);
-
-       /* Do some basic checks on the trust settings passed in. */
-       if(trustSettingsDictOrArray == NULL) {
-               require(array = CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks), errOut);
-               trustSettingsDictOrArray = array;
-       }
-       else if(CFGetTypeID(trustSettingsDictOrArray) == CFDictionaryGetTypeID()) {
-               /* array-ize it */
-               array = CFArrayCreate(NULL, &trustSettingsDictOrArray, 1,
-                       &kCFTypeArrayCallBacks);
-               trustSettingsDictOrArray = array;
-       }
-       else {
-               require(CFGetTypeID(trustSettingsDictOrArray) == CFArrayGetTypeID(), errOut);
-       }
+        require_action_quiet(xmlData = CFPropertyListCreateXMLData(kCFAllocatorDefault,
+                                                                   trustSettingsDictOrArray), errOut, ok = SecError(errSecParam, error, CFSTR("xml encode failed")));
+
+        int s3e = sqlite3_exec(ts->s3h, "BEGIN EXCLUSIVE TRANSACTION", NULL, NULL, NULL);
+        require_action_quiet(s3e == SQLITE_OK, errOut, ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e));
+
+        /* Parameter order is sha1,subj,tset,data. */
+        require_noerr_action_quiet(sqlite3_prepare(ts->s3h, insertSQL, sizeof(insertSQL),
+                                                   &insert, NULL), errOutSql, ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e));
+        require_noerr_action_quiet(sqlite3_bind_blob_wrapper(insert, 1,
+                                                             CFDataGetBytePtr(digest), CFDataGetLength(digest), SQLITE_STATIC),
+                                   errOutSql, ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e));
+        require_noerr_action_quiet(sqlite3_bind_blob_wrapper(insert, 2,
+                                                             CFDataGetBytePtr(subject), CFDataGetLength(subject),
+                                                             SQLITE_STATIC), errOutSql, ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e));
+        require_noerr_action_quiet(sqlite3_bind_blob_wrapper(insert, 3,
+                                                             CFDataGetBytePtr(xmlData), CFDataGetLength(xmlData),
+                                                             SQLITE_STATIC), errOutSql, ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e));
+        require_noerr_action_quiet(sqlite3_bind_blob_wrapper(insert, 4,
+                                                             SecCertificateGetBytePtr(certificate),
+                                                             SecCertificateGetLength(certificate), SQLITE_STATIC), errOutSql, ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e));
+        s3e = sqlite3_step(insert);
+        if (s3e == SQLITE_DONE) {
+            /* Great the insert worked. */
+            ok = true;
+        } else if (s3e == SQLITE_ERROR) {
+            /* Try update. */
+            require_noerr_action_quiet(s3e = sqlite3_prepare(ts->s3h, updateSQL, sizeof(updateSQL),
+                                                             &update, NULL), errOutSql, ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e));
+            require_noerr_action_quiet(s3e = sqlite3_bind_blob_wrapper(update, 1,
+                                                                       CFDataGetBytePtr(xmlData), CFDataGetLength(xmlData),
+                                                                       SQLITE_STATIC), errOutSql, ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e));
+            require_noerr_action_quiet(s3e = sqlite3_bind_blob_wrapper(update, 2,
+                                                                       CFDataGetBytePtr(digest), CFDataGetLength(digest), SQLITE_STATIC),
+                                       errOutSql, ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e));
+            s3e = sqlite3_step(update);
+            require_action_quiet(s3e == SQLITE_DONE, errOutSql, ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e));
+            s3e = SQLITE_OK;
+            ok = true;
+        } else {
+            require_noerr_action_quiet(s3e, errOutSql, ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e));
+            ok = true;
+        }
 
 
-       require(xmlData = CFPropertyListCreateXMLData(kCFAllocatorDefault,
-               trustSettingsDictOrArray), errOut);
-
-       int s3e = sqlite3_exec(ts->s3h, "BEGIN EXCLUSIVE TRANSACTION", NULL, NULL, NULL);
-       if (s3e != SQLITE_OK) {
-        status = errSecInternal;
-        goto errOut;
-    }
-
-       /* Parameter order is sha1,subj,tset,data. */
-       require_noerr(sqlite3_prepare(ts->s3h, insertSQL, sizeof(insertSQL),
-               &insert, NULL), errOutSql);
-       require_noerr(sqlite3_bind_blob_wrapper(insert, 1,
-               CFDataGetBytePtr(digest), CFDataGetLength(digest), SQLITE_STATIC),
-               errOutSql);
-       require_noerr(sqlite3_bind_blob_wrapper(insert, 2,
-               CFDataGetBytePtr(subject), CFDataGetLength(subject),
-               SQLITE_STATIC), errOutSql);
-       require_noerr(sqlite3_bind_blob_wrapper(insert, 3,
-               CFDataGetBytePtr(xmlData), CFDataGetLength(xmlData),
-               SQLITE_STATIC), errOutSql);
-       require_noerr(sqlite3_bind_blob_wrapper(insert, 4,
-               SecCertificateGetBytePtr(certificate),
-               SecCertificateGetLength(certificate), SQLITE_STATIC), errOutSql);
-       s3e = sqlite3_step(insert);
-       if (s3e == SQLITE_DONE) {
-               /* Great the insert worked. */
-               status = noErr;
-       } else if (s3e == SQLITE_ERROR) {
-        /* Try update. */
-        require_noerr(sqlite3_prepare(ts->s3h, updateSQL, sizeof(updateSQL),
-            &update, NULL), errOutSql);
-        require_noerr(sqlite3_bind_blob_wrapper(update, 1,
-            CFDataGetBytePtr(xmlData), CFDataGetLength(xmlData),
-            SQLITE_STATIC), errOutSql);
-        require_noerr(sqlite3_bind_blob_wrapper(update, 2,
-            CFDataGetBytePtr(digest), CFDataGetLength(digest), SQLITE_STATIC),
-            errOutSql);
-        s3e = sqlite3_step(update);
-               require(s3e == SQLITE_DONE, errOutSql);
-        status = noErr;
-    } else {
-               require_noerr(s3e, errOutSql);
-       }
+    errOutSql:
+        if (insert)
+            s3e = sqlite3_finalize(insert);
+        if (update)
+            s3e = sqlite3_finalize(update);
 
 
-errOutSql:
-       if (insert)
-               s3e = sqlite3_finalize(insert);
-       if (update)
-               s3e = sqlite3_finalize(update);
+        if (ok && s3e == SQLITE_OK)
+            s3e = sqlite3_exec(ts->s3h, "COMMIT TRANSACTION", NULL, NULL, NULL);
 
 
-    if (s3e == SQLITE_OK)
-        sqlite3_exec(ts->s3h, "COMMIT TRANSACTION", NULL, NULL, NULL);
-    else
-        sqlite3_exec(ts->s3h, "ROLLBACK TRANSACTION", NULL, NULL, NULL);
+        if (!ok || s3e != SQLITE_OK) {
+            sqlite3_exec(ts->s3h, "ROLLBACK TRANSACTION", NULL, NULL, NULL);
+            if (ok) {
+                ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e);
+            }
+        }
 
 
-errOut:
-       CFReleaseSafe(xmlData);
-       CFReleaseSafe(array);
-       verify_noerr(pthread_mutex_unlock(&ts->lock));
+    errOut:
+        CFReleaseSafe(xmlData);
+        CFReleaseSafe(array);
+    });
 errOutNotLocked:
 errOutNotLocked:
-       return status;
+       return ok;
 }
 
 /* AUDIT[securityd](done):
    ts (ok) might be NULL.
    digest (ok) is a data of any length (might be 0).
  */
 }
 
 /* AUDIT[securityd](done):
    ts (ok) might be NULL.
    digest (ok) is a data of any length (might be 0).
  */
-OSStatus SecTrustStoreRemoveCertificateWithDigest(SecTrustStoreRef ts,
-    CFDataRef digest) {
-       sqlite3_stmt *deleteStmt = NULL;
-
+bool SecTrustStoreRemoveCertificateWithDigest(SecTrustStoreRef ts,
+    CFDataRef digest, CFErrorRef *error) {
        require_quiet(ts, errOutNotLocked);
        require(!ts->readOnly, errOutNotLocked);
        require_quiet(ts, errOutNotLocked);
        require(!ts->readOnly, errOutNotLocked);
-       require_noerr(pthread_mutex_lock(&ts->lock), errOutNotLocked);
-    require_noerr(sqlite3_prepare(ts->s3h, deleteSQL, sizeof(deleteSQL),
-        &deleteStmt, NULL), errOut);
-    require_noerr(sqlite3_bind_blob_wrapper(deleteStmt, 1,
-        CFDataGetBytePtr(digest), CFDataGetLength(digest), SQLITE_STATIC),
-        errOut);
-       sqlite3_step(deleteStmt);
-
-errOut:
-    if (deleteStmt) {
-        verify_noerr(sqlite3_finalize(deleteStmt));
-    }
-       verify_noerr(pthread_mutex_unlock(&ts->lock));
+    dispatch_sync(ts->queue, ^{
+        sqlite3_stmt *deleteStmt = NULL;
+        require_noerr(sqlite3_prepare(ts->s3h, deleteSQL, sizeof(deleteSQL),
+                                      &deleteStmt, NULL), errOut);
+        require_noerr(sqlite3_bind_blob_wrapper(deleteStmt, 1,
+                                                CFDataGetBytePtr(digest), CFDataGetLength(digest), SQLITE_STATIC),
+                      errOut);
+        sqlite3_step(deleteStmt);
+
+    errOut:
+        if (deleteStmt) {
+            verify_noerr(sqlite3_finalize(deleteStmt));
+        }
+    });
 errOutNotLocked:
 errOutNotLocked:
-       return noErr;
+       return true;
 }
 
 }
 
-bool _SecTrustStoreRemoveAll(SecTrustStoreRef ts)
+bool _SecTrustStoreRemoveAll(SecTrustStoreRef ts, CFErrorRef *error)
 {
 {
-    bool removed_all = false;
+    __block bool removed_all = false;
        require(ts, errOutNotLocked);
        require(!ts->readOnly, errOutNotLocked);
        require(ts, errOutNotLocked);
        require(!ts->readOnly, errOutNotLocked);
-       require_noerr(pthread_mutex_lock(&ts->lock), errOutNotLocked);
-    if (SQLITE_OK == sqlite3_exec(ts->s3h, deleteAllSQL, NULL, NULL, NULL))
-        removed_all = true;
-
-    /* prepared statements become unusable after deleteAllSQL, reset them */
-    if (ts->copyParents)
-        sqlite3_finalize(ts->copyParents);
-    sqlite3_prepare(ts->s3h, copyParentsSQL, sizeof(copyParentsSQL),
-        &ts->copyParents, NULL);
-    if (ts->contains)
-        sqlite3_finalize(ts->contains);
-    sqlite3_prepare(ts->s3h, containsSQL, sizeof(containsSQL),
-        &ts->contains, NULL);
-
-       verify_noerr(pthread_mutex_unlock(&ts->lock));
+    dispatch_sync(ts->queue, ^{
+        if (SQLITE_OK == sqlite3_exec(ts->s3h, deleteAllSQL, NULL, NULL, NULL))
+            removed_all = true;
+
+        /* prepared statements become unusable after deleteAllSQL, reset them */
+        if (ts->copyParents)
+            sqlite3_finalize(ts->copyParents);
+        sqlite3_prepare(ts->s3h, copyParentsSQL, sizeof(copyParentsSQL),
+                        &ts->copyParents, NULL);
+        if (ts->contains)
+            sqlite3_finalize(ts->contains);
+        sqlite3_prepare(ts->s3h, containsSQL, sizeof(containsSQL),
+                        &ts->contains, NULL);
+    });
 errOutNotLocked:
        return removed_all;
 }
 
 CFArrayRef SecTrustStoreCopyParents(SecTrustStoreRef ts,
 errOutNotLocked:
        return removed_all;
 }
 
 CFArrayRef SecTrustStoreCopyParents(SecTrustStoreRef ts,
-       SecCertificateRef certificate) {
-       CFMutableArrayRef parents = NULL;
-
+       SecCertificateRef certificate, CFErrorRef *error) {
+       __block CFMutableArrayRef parents = NULL;
        require(ts, errOutNotLocked);
        require(ts, errOutNotLocked);
-       require_noerr(pthread_mutex_lock(&ts->lock), errOutNotLocked);
-
-    CFDataRef issuer;
-       require(issuer = SecCertificateGetNormalizedIssuerContent(certificate),
-               errOut);
-       /* @@@ Might have to use SQLITE_TRANSIENT */
-       require_noerr(sqlite3_bind_blob_wrapper(ts->copyParents, 1,
-               CFDataGetBytePtr(issuer), CFDataGetLength(issuer),
-               SQLITE_STATIC), errOut);
-
-       require(parents = CFArrayCreateMutable(kCFAllocatorDefault, 0,
-               &kCFTypeArrayCallBacks), errOut);
-       for (;;) {
-               int s3e = sqlite3_step(ts->copyParents);
-               if (s3e == SQLITE_ROW) {
-                       SecCertificateRef cert;
-                       require(cert = SecCertificateCreateWithBytes(kCFAllocatorDefault,
-                               sqlite3_column_blob(ts->copyParents, 0),
-                               sqlite3_column_bytes(ts->copyParents, 0)), errOut);
-                       CFArrayAppendValue(parents, cert);
-                       CFRelease(cert);
-               } else {
-                       require(s3e == SQLITE_DONE, errOut);
-            break;
+    dispatch_sync(ts->queue, ^{
+        CFDataRef issuer;
+        require(issuer = SecCertificateGetNormalizedIssuerContent(certificate),
+            errOut);
+        /* @@@ Might have to use SQLITE_TRANSIENT */
+        require_noerr(sqlite3_bind_blob_wrapper(ts->copyParents, 1,
+            CFDataGetBytePtr(issuer), CFDataGetLength(issuer),
+            SQLITE_STATIC), errOut);
+
+        require(parents = CFArrayCreateMutable(kCFAllocatorDefault, 0,
+            &kCFTypeArrayCallBacks), errOut);
+        for (;;) {
+            int s3e = sqlite3_step(ts->copyParents);
+            if (s3e == SQLITE_ROW) {
+                SecCertificateRef cert;
+                require(cert = SecCertificateCreateWithBytes(kCFAllocatorDefault,
+                    sqlite3_column_blob(ts->copyParents, 0),
+                    sqlite3_column_bytes(ts->copyParents, 0)), errOut);
+                CFArrayAppendValue(parents, cert);
+                CFRelease(cert);
+            } else {
+                require(s3e == SQLITE_DONE, errOut);
+                break;
+            }
         }
         }
-       }
 
 
-       goto ok;
-errOut:
-       if (parents) {
-               CFRelease(parents);
-               parents = NULL;
-       }
-ok:
-       verify_noerr(sqlite3_reset(ts->copyParents));
-       verify_noerr(sqlite3_clear_bindings(ts->copyParents));
-       verify_noerr(pthread_mutex_unlock(&ts->lock));
+        goto ok;
+    errOut:
+        if (parents) {
+            CFRelease(parents);
+            parents = NULL;
+        }
+    ok:
+        verify_noerr(sqlite3_reset(ts->copyParents));
+        verify_noerr(sqlite3_clear_bindings(ts->copyParents));
+    });
 errOutNotLocked:
        return parents;
 }
 errOutNotLocked:
        return parents;
 }
@@ -451,27 +428,28 @@ errOutNotLocked:
    been checked.
 */
 bool SecTrustStoreContainsCertificateWithDigest(SecTrustStoreRef ts,
    been checked.
 */
 bool SecTrustStoreContainsCertificateWithDigest(SecTrustStoreRef ts,
-       CFDataRef digest) {
-       bool contains = false;
-
-       require_quiet(ts, errOutNotLocked);
-       require_noerr(pthread_mutex_lock(&ts->lock), errOutNotLocked);
-
-       /* @@@ Might have to use SQLITE_TRANSIENT */
-       require_noerr(sqlite3_bind_blob_wrapper(ts->contains, 1,
-               CFDataGetBytePtr(digest), CFDataGetLength(digest), SQLITE_STATIC),
-               errOut);
-       int s3e = sqlite3_step(ts->contains);
-       if (s3e == SQLITE_ROW) {
-               contains = true;
-       } else {
-               require(s3e == SQLITE_DONE, errOut);
-       }
+       CFDataRef digest, bool *contains, CFErrorRef *error) {
+    if (contains)
+        *contains = false;
+    __block bool ok = true;
+       require_action_quiet(ts, errOutNotLocked, ok = SecError(errSecParam, error, CFSTR("ts is NULL")));
+    dispatch_sync(ts->queue, ^{
+        int s3e;
+        require_noerr_action(s3e = sqlite3_bind_blob_wrapper(ts->contains, 1,
+            CFDataGetBytePtr(digest), CFDataGetLength(digest), SQLITE_STATIC),
+            errOut, ok = SecDbErrorWithStmt(s3e, ts->contains, error, CFSTR("sqlite3_bind_blob failed")));
+        s3e = sqlite3_step(ts->contains);
+        if (s3e == SQLITE_ROW) {
+            if (contains)
+                *contains = true;
+        } else {
+            require_action(s3e == SQLITE_DONE, errOut, ok = SecDbErrorWithStmt(s3e, ts->contains, error, CFSTR("sqlite3_step failed")));
+        }
 
 
-errOut:
-       verify_noerr(sqlite3_reset(ts->contains));
-       verify_noerr(sqlite3_clear_bindings(ts->contains));
-       verify_noerr(pthread_mutex_unlock(&ts->lock));
+    errOut:
+        verify_noerr(sqlite3_reset(ts->contains));
+        verify_noerr(sqlite3_clear_bindings(ts->contains));
+    });
 errOutNotLocked:
 errOutNotLocked:
-       return contains;
+       return ok;
 }
 }
index e8bcd7a766411c836d3f67b4b017b36e67ecd862..e51cb1def80505366ce1e14048cf0e78c7d2d1f1 100644 (file)
 
 #include <Security/SecTrustStore.h>
 #include <CoreFoundation/CFArray.h>
 
 #include <Security/SecTrustStore.h>
 #include <CoreFoundation/CFArray.h>
+#include <CoreFoundation/CFError.h>
 
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 
-SecTrustStoreRef SecTrustStoreForDomainName(CFStringRef domain);
+SecTrustStoreRef SecTrustStoreForDomainName(CFStringRef domainName, CFErrorRef *error);
 
 
-OSStatus _SecTrustStoreSetTrustSettings(SecTrustStoreRef ts,
+bool _SecTrustStoreSetTrustSettings(SecTrustStoreRef ts,
        SecCertificateRef certificate,
        SecCertificateRef certificate,
-    CFTypeRef trustSettingsDictOrArray);
+    CFTypeRef trustSettingsDictOrArray, CFErrorRef *error);
 
 
-OSStatus SecTrustStoreRemoveCertificateWithDigest(SecTrustStoreRef ts, CFDataRef digest);
+bool SecTrustStoreRemoveCertificateWithDigest(SecTrustStoreRef ts, CFDataRef digest, CFErrorRef *error);
 
 
-bool _SecTrustStoreRemoveAll(SecTrustStoreRef ts);
+bool _SecTrustStoreRemoveAll(SecTrustStoreRef ts, CFErrorRef *error);
 
 CFArrayRef SecTrustStoreCopyParents(SecTrustStoreRef ts,
 
 CFArrayRef SecTrustStoreCopyParents(SecTrustStoreRef ts,
-    SecCertificateRef certificate);
+    SecCertificateRef certificate, CFErrorRef *error);
 
 
-bool SecTrustStoreContainsCertificateWithDigest(SecTrustStoreRef source, CFDataRef digest);
+bool SecTrustStoreContainsCertificateWithDigest(SecTrustStoreRef source, CFDataRef digest, bool *contains, CFErrorRef *error);
 
 
 
 
-#if defined(__cplusplus)
-}
-#endif
+__END_DECLS
 
 #endif /* !_SECURITY_SECTRUSTSTORESERVER_H_ */
 
 #endif /* !_SECURITY_SECTRUSTSTORESERVER_H_ */
index 09ea2e66e100f469e7bb5f0a583389dd81bb85df..155f8d8d313376fe29838da66a574723074b002d 100644 (file)
 #include <Security/SecInternal.h>
 #include "SecBase64.h"
 #include <AssertMacros.h>
 #include <Security/SecInternal.h>
 #include "SecBase64.h"
 #include <AssertMacros.h>
-#include <security_utilities/debugging.h>
+#include <utilities/debugging.h>
+#include <utilities/SecDispatchRelease.h>
 #include <asl.h>
 #include <string.h>
 
 #include <asl.h>
 #include <string.h>
 
+#include <inttypes.h>
+
 #if __LP64__
 #define PRIstatus "d"
 #else
 #if __LP64__
 #define PRIstatus "d"
 #else
@@ -54,23 +57,14 @@ static CFStringRef kAppOcspRequest  = CFSTR("application/ocsp-request");
 #define _kCFStreamPropertyReadTimeout   CFSTR("_kCFStreamPropertyReadTimeout")
 #define _kCFStreamPropertyWriteTimeout   CFSTR("_kCFStreamPropertyWriteTimeout")
 
 #define _kCFStreamPropertyReadTimeout   CFSTR("_kCFStreamPropertyReadTimeout")
 #define _kCFStreamPropertyWriteTimeout   CFSTR("_kCFStreamPropertyWriteTimeout")
 
-/* the timeout we set */
-#define STREAM_TIMEOUT         7.0
+/* The timeout we set - 7 seconds */
+#define STREAM_TIMEOUT         (7 * NSEC_PER_SEC)
 
 #define POST_BUFSIZE   2048
 
 
 #define POST_BUFSIZE   2048
 
-static void terminate_stream(CFReadStreamRef stream)
-{
-    CFReadStreamSetClient(stream, kCFStreamEventNone, NULL, NULL);
-    CFReadStreamUnscheduleFromRunLoop(stream, CFRunLoopGetCurrent(),
-        kCFRunLoopCommonModes);
-    CFReadStreamClose(stream);
-    //CFRelease(stream);
-}
-
 /* There has got to be an easier way to do this.  For now we based this code
    on CFNetwork/Connection/URLResponse.cpp. */
 /* There has got to be an easier way to do this.  For now we based this code
    on CFNetwork/Connection/URLResponse.cpp. */
-static CFStringRef parseMaxAge(CFStringRef cacheControlHeader) {
+static CFStringRef copyParseMaxAge(CFStringRef cacheControlHeader) {
     /* The format of the cache control header is a comma-separated list, but
        each list element could be a key-value pair, with the value quoted and
        possibly containing a comma. */
     /* The format of the cache control header is a comma-separated list, but
        each list element could be a key-value pair, with the value quoted and
        possibly containing a comma. */
@@ -162,14 +156,16 @@ static CFStringRef parseMaxAge(CFStringRef cacheControlHeader) {
 
 static void asynchttp_complete(asynchttp_t *http) {
     secdebug("http", "http: %p", http);
 
 static void asynchttp_complete(asynchttp_t *http) {
     secdebug("http", "http: %p", http);
-    /* Shutdown streams and timers, we're about to invoke our client callback. */
+    /* Shutdown streams and timer, we're about to invoke our client callback. */
     if (http->stream) {
     if (http->stream) {
-        terminate_stream(http->stream);
+        CFReadStreamSetClient(http->stream, kCFStreamEventNone, NULL, NULL);
+        CFReadStreamSetDispatchQueue(http->stream, NULL);
+        CFReadStreamClose(http->stream);
         CFReleaseNull(http->stream);
     }
     if (http->timer) {
         CFReleaseNull(http->stream);
     }
     if (http->timer) {
-        CFRunLoopTimerInvalidate(http->timer);
-        CFReleaseNull(http->timer);
+        dispatch_source_cancel(http->timer);
+        dispatch_release_null(http->timer);
     }
 
     if (http->completed) {
     }
 
     if (http->completed) {
@@ -179,7 +175,7 @@ static void asynchttp_complete(asynchttp_t *http) {
             CFStringRef cacheControl = CFHTTPMessageCopyHeaderFieldValue(
                 http->response, CFSTR("cache-control"));
             if (cacheControl) {
             CFStringRef cacheControl = CFHTTPMessageCopyHeaderFieldValue(
                 http->response, CFSTR("cache-control"));
             if (cacheControl) {
-                CFStringRef maxAgeValue = parseMaxAge(cacheControl);
+                CFStringRef maxAgeValue = copyParseMaxAge(cacheControl);
                 CFRelease(cacheControl);
                 if (maxAgeValue) {
                     secdebug("http", "http header max-age: %@", maxAgeValue);
                 CFRelease(cacheControl);
                 if (maxAgeValue) {
                     secdebug("http", "http header max-age: %@", maxAgeValue);
@@ -195,6 +191,11 @@ static void asynchttp_complete(asynchttp_t *http) {
 static void handle_server_response(CFReadStreamRef stream,
     CFStreamEventType type, void *info) {
     asynchttp_t *http = (asynchttp_t *)info;
 static void handle_server_response(CFReadStreamRef stream,
     CFStreamEventType type, void *info) {
     asynchttp_t *http = (asynchttp_t *)info;
+    if (!http->stream) {
+        secerror("Avoiding crash due to CFReadStream invoking us after we called CFReadStreamSetDispatchQueue(stream, NULL) on a different block on our serial queue");
+        return;
+    }
+
     switch (type) {
     case kCFStreamEventHasBytesAvailable:
     {
     switch (type) {
     case kCFStreamEventHasBytesAvailable:
     {
@@ -231,7 +232,7 @@ static void handle_server_response(CFReadStreamRef stream,
 
         secdebug("http",
             "stream: %@ kCFStreamEventErrorOccurred domain: %ld error: %ld",
 
         secdebug("http",
             "stream: %@ kCFStreamEventErrorOccurred domain: %ld error: %ld",
-            stream, error.domain, error.error);
+            stream, error.domain, (long) error.error);
 
         if (error.domain == kCFStreamErrorDomainPOSIX) {
             ocspdErrorLog("CFReadStream posix: %s", strerror(error.error));
 
         if (error.domain == kCFStreamErrorDomainPOSIX) {
             ocspdErrorLog("CFReadStream posix: %s", strerror(error.error));
@@ -382,13 +383,10 @@ errOut:
 }
 
 
 }
 
 
-static void asynchttp_timer_proc(CFRunLoopTimerRef timer, void *info) {
-    asynchttp_t *http = (asynchttp_t *)info;
+static void asynchttp_timer_proc(asynchttp_t *http) {
     CFStringRef req_meth = http->request ? CFHTTPMessageCopyRequestMethod(http->request) : NULL;
     CFURLRef req_url = http->request ? CFHTTPMessageCopyRequestURL(http->request) : NULL;
     CFStringRef req_meth = http->request ? CFHTTPMessageCopyRequestMethod(http->request) : NULL;
     CFURLRef req_url = http->request ? CFHTTPMessageCopyRequestURL(http->request) : NULL;
-    secdebug("http", "Timeout during %@ %@.", req_meth, req_url);
-    /* TODO: Add logging of url that timed out. */
-    //asl_log(NULL, NULL, ASL_LEVEL_NOTICE, "Timeout during %@ %@.", req_meth, req_url);
+    secnotice("http", "Timeout during %@ %@.", req_meth, req_url);
     CFReleaseSafe(req_url);
     CFReleaseSafe(req_meth);
     asynchttp_complete(http);
     CFReleaseSafe(req_url);
     CFReleaseSafe(req_meth);
     asynchttp_complete(http);
@@ -401,11 +399,7 @@ void asynchttp_free(asynchttp_t *http) {
         CFReleaseNull(http->response);
         CFReleaseNull(http->data);
         CFReleaseNull(http->stream);
         CFReleaseNull(http->response);
         CFReleaseNull(http->data);
         CFReleaseNull(http->stream);
-        CFReleaseNull(http->source);
-        if (http->timer) {
-            CFRunLoopTimerInvalidate(http->timer);
-            CFReleaseNull(http->timer);
-        }
+        dispatch_release_null(http->timer);
     }
 }
 
     }
 }
 
@@ -422,16 +416,14 @@ bool asynchttp_request(CFHTTPMessageRef request, asynchttp_t *http) {
         kCFAllocatorDefault, http->request), errOut);
 
        /* Set a reasonable timeout */
         kCFAllocatorDefault, http->request), errOut);
 
        /* Set a reasonable timeout */
-    CFRunLoopTimerContext tctx = { .info = http };
-    http->timer = CFRunLoopTimerCreate(kCFAllocatorDefault,
-        CFAbsoluteTimeGetCurrent() + STREAM_TIMEOUT,
-        0, 0, 0, asynchttp_timer_proc, &tctx);
-    if (http->timer == NULL) {
-        asl_log(NULL, NULL, ASL_LEVEL_ERR, "FATAL: failed to create timer.");
-    } else {
-        CFRunLoopAddTimer(CFRunLoopGetCurrent(), http->timer,
-            kCFRunLoopDefaultMode);
-    }
+    require_quiet(http->timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, http->queue), errOut);
+    dispatch_source_set_event_handler(http->timer, ^{
+        asynchttp_timer_proc(http);
+    });
+    // Set the timer's fire time to now + STREAM_TIMEOUT seconds with a .5 second fuzz factor.
+    dispatch_source_set_timer(http->timer, dispatch_time(DISPATCH_TIME_NOW, STREAM_TIMEOUT),
+                              DISPATCH_TIME_FOREVER, (int64_t)(500 * NSEC_PER_MSEC));
+    dispatch_resume(http->timer);
 
        /* Set up possible proxy info */
        CFDictionaryRef proxyDict = CFNetworkCopySystemProxySettings();
 
        /* Set up possible proxy info */
        CFDictionaryRef proxyDict = CFNetworkCopySystemProxySettings();
@@ -448,9 +440,9 @@ bool asynchttp_request(CFHTTPMessageRef request, asynchttp_t *http) {
          | kCFStreamEventErrorOccurred
          | kCFStreamEventEndEncountered),
         handle_server_response, &stream_context);
          | kCFStreamEventErrorOccurred
          | kCFStreamEventEndEncountered),
         handle_server_response, &stream_context);
-    CFReadStreamScheduleWithRunLoop(http->stream, CFRunLoopGetCurrent(),
-        kCFRunLoopCommonModes);
+    CFReadStreamSetDispatchQueue(http->stream, http->queue);
     CFReadStreamOpen(http->stream);
     CFReadStreamOpen(http->stream);
+
     return false; /* false -> something was scheduled. */
 
 errOut:
     return false; /* false -> something was scheduled. */
 
 errOut:
index a315c2525b0ef707ec97a98b4715a0b43e0395a9..9db96d8c902f4aee6f616f7eb4bd86b3c19be2d6 100644 (file)
 #include <CoreFoundation/CFDate.h>
 #include <CFNetwork/CFHTTPMessage.h>
 #include <CFNetwork/CFHTTPStream.h>
 #include <CoreFoundation/CFDate.h>
 #include <CFNetwork/CFHTTPMessage.h>
 #include <CFNetwork/CFHTTPStream.h>
+#include <dispatch/dispatch.h>
 
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 typedef struct asynchttp_s {
     void(*completed)(struct asynchttp_s *http, CFTimeInterval maxAge);
     void *info;
     CFHTTPMessageRef request;
     CFHTTPMessageRef response;
 
 typedef struct asynchttp_s {
     void(*completed)(struct asynchttp_s *http, CFTimeInterval maxAge);
     void *info;
     CFHTTPMessageRef request;
     CFHTTPMessageRef response;
+    dispatch_queue_t queue;
     /* The fields below should be considered private. */
     CFMutableDataRef data;
     CFReadStreamRef stream;
     /* The fields below should be considered private. */
     CFMutableDataRef data;
     CFReadStreamRef stream;
-    CFRunLoopSourceRef source;
-    CFRunLoopTimerRef timer;
+    dispatch_source_t timer;
 } asynchttp_t;
 
 /* Return false if work was scheduled and the callback will be invoked,
 } asynchttp_t;
 
 /* Return false if work was scheduled and the callback will be invoked,
@@ -65,8 +64,6 @@ void asynchttp_free(asynchttp_t *http);
 /* */
 
 
 /* */
 
 
-#if defined(__cplusplus)
-}
-#endif
+__END_DECLS
 
 #endif /* !_SECURITYD_ASYNCHTTP_H_ */
 
 #endif /* !_SECURITYD_ASYNCHTTP_H_ */
index 193bab7d955b6b71f1a7c5f89396b2d9f4b5d627..e3248a6cdb14da3f064b148485cb955cddf4b612 100644 (file)
@@ -6,5 +6,7 @@
        <string>com.apple.securityd</string>
        <key>com.apple.keystore.access-keychain-keys</key>
        <true/>
        <string>com.apple.securityd</string>
        <key>com.apple.keystore.access-keychain-keys</key>
        <true/>
+       <key>com.apple.keystore.lockassertion</key>
+       <true/>
 </dict>
 </plist>
 </dict>
 </plist>
diff --git a/sec/securityd/keystore.c b/sec/securityd/keystore.c
deleted file mode 100644 (file)
index f478081..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Copyright (c) 2010 Apple Inc. All Rights Reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * 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 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/*
- * keystore.c - C API for the AppleKeyStore kext
- */
-
-#include <securityd/keystore.h>
-
-#include <errno.h>
-#include <limits.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <CoreFoundation/CFData.h>
-#include <CommonCrypto/CommonDigest.h>
-#include <CommonCrypto/CommonCryptor.h>
-#include <libkern/OSByteOrder.h>
-#include <security_utilities/debugging.h>
-#include <assert.h>
-#include <Security/SecInternal.h>
-#include <TargetConditionals.h>
-#include <AssertMacros.h>
-#include <asl.h>
-
-#if TARGET_OS_EMBEDDED && !TARGET_IPHONE_SIMULATOR
-#define USE_KEYSTORE  1
-#define USE_DISPATCH  1 /* Shouldn't be here. */
-#else /* No AppleKeyStore.kext on this OS. */
-#define USE_KEYSTORE  0
-#endif /* hardware aes */
-
-#if USE_KEYSTORE
-#include <Kernel/IOKit/crypto/AppleKeyStoreDefs.h>
-
-#if USE_DISPATCH
-#include <dispatch/dispatch.h>
-static dispatch_once_t ks_init_once;
-#else /* !USE_DISPATCH use pthreads instead. */
-#include <pthread.h>
-static pthread_once_t ks_init_once = PTHREAD_ONCE_INIT;
-#endif
-
-static io_connect_t ks_connect_handle = MACH_PORT_NULL;
-
-static void ks_service_matching_callback(void *refcon, io_iterator_t iterator)
-{
-       io_object_t obj = IO_OBJECT_NULL;
-
-       while ((obj = IOIteratorNext(iterator))) {
-        kern_return_t ret = IOServiceOpen(obj, mach_task_self(), 0,
-            (io_connect_t*)refcon);
-        if (ret) {
-            asl_log(NULL, NULL, ASL_LEVEL_ERR,
-                "IOServiceOpen() failed: %d", ret);
-        }
-        IOObjectRelease(obj);
-       }
-}
-
-io_connect_t ks_connect_to_service(const char *className)
-{
-       kern_return_t kernResult;
-    io_connect_t connect = IO_OBJECT_NULL;
-       io_iterator_t iterator = IO_OBJECT_NULL;
-    IONotificationPortRef notifyport = NULL;
-       CFDictionaryRef classToMatch;
-
-       if ((classToMatch = IOServiceMatching(className)) == NULL) {
-               asl_log(NULL, NULL, ASL_LEVEL_ERR,
-            "IOServiceMatching failed for '%s'", className);
-               return connect;
-       }
-
-    /* consumed by IOServiceGetMatchingServices, we need it if that fails. */
-    CFRetain(classToMatch);
-    kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault,
-        classToMatch, &iterator);
-
-    if (kernResult == KERN_SUCCESS) {
-        CFRelease(classToMatch);
-    } else {
-        asl_log(NULL, NULL, ASL_LEVEL_WARNING,
-            "IOServiceGetMatchingServices() failed %d", kernResult);
-
-        notifyport = IONotificationPortCreate(kIOMasterPortDefault);
-        if (!notifyport) {
-            asl_log(NULL, NULL, ASL_LEVEL_ERR,
-                "IONotificationPortCreate() failed");
-            return connect;
-        }
-
-        kernResult = IOServiceAddMatchingNotification(notifyport,
-            kIOFirstMatchNotification, classToMatch,
-            ks_service_matching_callback, &connect, &iterator);
-        if (kernResult) {
-            asl_log(NULL, NULL, ASL_LEVEL_ERR,
-                "IOServiceAddMatchingNotification() failed: %d", kernResult);
-            return connect;
-        }
-    }
-
-    /* Check whether it was already there before we registered for the
-       notification. */
-    ks_service_matching_callback(&connect, iterator);
-
-    if (notifyport) {
-        /* We'll get set up to wait for it to appear */
-        if (connect == IO_OBJECT_NULL) {
-            asl_log(NULL, NULL, ASL_LEVEL_ERR,
-                "Waiting for %s to show up.", className);
-            CFStringRef mode = CFSTR("WaitForCryptoService");
-            CFRunLoopAddSource(CFRunLoopGetCurrent(),
-                IONotificationPortGetRunLoopSource(notifyport), mode);
-            CFRunLoopRunInMode(mode, 30.0, true);
-            if (connect == MACH_PORT_NULL)
-                asl_log(NULL, NULL, ASL_LEVEL_ERR, "Cannot find %s", className);
-        }
-        IONotificationPortDestroy(notifyport);
-    }
-
-    IOObjectRelease(iterator);
-
-    if (connect != IO_OBJECT_NULL) {
-        secdebug("iokit", "obtained connection for '%s'", className);
-    }
-    return connect;
-}
-
-#if USE_DISPATCH
-static void ks_crypto_init(void *unused)
-#else
-static void ks_crypto_init(void)
-#endif
-{
-    ks_connect_handle = ks_connect_to_service(kAppleKeyStoreServiceName);
-}
-
-io_connect_t ks_get_connect(void)
-{
-#if USE_DISPATCH
-    dispatch_once_f(&ks_init_once, NULL, ks_crypto_init);
-#else
-    pthread_once(&ks_init_once, ks_crypto_init);
-#endif
-    return ks_connect_handle;
-}
-
-bool ks_available(void)
-{
-    ks_get_connect();
-       return true;
-}
-
-
-static bool ks_crypt(uint32_t selector, uint64_t keybag,
-    uint64_t keyclass, const uint8_t *input, size_t inputLength,
-    uint8_t *buffer, size_t *keySize) {
-       kern_return_t kernResult;
-
-    if (!ks_connect_handle) {
-        secdebug("ks", "AppleKeyStore.kext not found");
-        return false;
-    }
-
-    uint64_t inputs[] = { keybag, keyclass };
-    uint32_t num_inputs = sizeof(inputs)/sizeof(*inputs);
-    kernResult = IOConnectCallMethod(ks_connect_handle, selector,
-        inputs, num_inputs, input, inputLength, NULL, NULL, buffer,
-        keySize);
-
-       if (kernResult != KERN_SUCCESS) {
-               asl_log(NULL, NULL, ASL_LEVEL_ERR, "kAppleKeyStore selector(%d): %d",
-            selector, kernResult);
-               return false;
-       }
-       return true;
-}
-
-void ks_free(ks_object_t object) {
-    /* TODO: this might need to be vm_deallocate in some cases. */
-    free(object._kso);
-}
-
-uint8_t *ks_unwrap(uint64_t keybag, uint64_t keyclass,
-    const uint8_t *wrappedKey, size_t wrappedKeySize,
-    uint8_t *buffer, size_t bufferSize, size_t *keySize) {
-    *keySize = bufferSize;
-    if (!ks_crypt(kAppleKeyStoreKeyUnwrap,
-        keybag, keyclass, wrappedKey, wrappedKeySize, buffer, keySize))
-        return NULL;
-    return buffer;
-}
-
-
-uint8_t *ks_wrap(uint64_t keybag, uint64_t keyclass,
-    const uint8_t *key, size_t keyByteSize,
-    uint8_t *buffer, size_t bufferSize, size_t *wrappedKeySize) {
-    *wrappedKeySize = bufferSize;
-    if (ks_crypt(kAppleKeyStoreKeyWrap,
-        keybag, keyclass, key, keyByteSize,
-        buffer, wrappedKeySize))
-        return NULL;
-    return buffer;
-}
-
-
-#else /* !USE_KEYSTORE */
-
-bool ks_available(void)
-{
-       return false;
-}
-
-#endif /* !USE_KEYSTORE */
diff --git a/sec/securityd/keystore.h b/sec/securityd/keystore.h
deleted file mode 100644 (file)
index 90dd9ba..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (c) 2010 Apple Inc. All Rights Reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * 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 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/*!
-    @header keystore
-    The functions provided in keystore.h provide an interface to
-    the AppleKeyStore kext.
-*/
-
-#ifndef _SECURITYD_KEYSTORE_H_
-#define _SECURITYD_KEYSTORE_H_
-
-#include <IOKit/IOKitLib.h>
-
-#ifdef __cplusplus
-/*
- * ks objects are NOT C++ objects. Nevertheless, we can at least keep C++
- * aware of type compatibility.
- */
-typedef struct ks_object_s {
-private:
-       ks_object_s();
-       ~ks_object_s();
-       ks_object_s(const ks_object_s &);
-       void operator=(const ks_object_s &);
-} *ks_object_t;
-#else
-typedef union {
-       struct ks_object_s *_kso;
-       struct ks_key_s *_ksk;
-       struct ks_buffer_s *_ksb;
-       struct ks_stream_s *_kss;
-} ks_object_t __attribute__((transparent_union));
-#endif
-
-#ifdef __cplusplus
-#define KS_DECL(name) typedef struct name##_s : public ks_object_s {} *name##_t;
-#else
-/*! @parseOnly */
-#define KS_DECL(name) typedef struct name##_s *name##_t;
-#endif
-
-KS_DECL(ks_buffer);
-KS_DECL(ks_key);
-KS_DECL(ks_stream);
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-enum {
-    KS_KEY_SIZE_128 = 16,
-    KS_KEY_SIZE_192 = 24,
-    KS_KEY_SIZE_256 = 32,
-};
-
-ks_key_t ks_generate_key(long size);
-void ks_encrypt(ks_key_t key, ks_object_t data_in, ks_object_t data_out);
-void ks_decrypt(ks_key_t key, ks_object_t data_in, ks_object_t data_out);
-
-ks_buffer_t ks_buffer(size_t capacity);
-size_t ks_get_length(ks_buffer_t buffer);
-void ks_set_length(ks_buffer_t buffer, size_t length);
-uint8_t *ks_bytes(ks_buffer_t buffer);
-ks_buffer_t ks_append(size_t capacity);
-
-
-/* TODO: Move to iokitutils or something since this is generic. */
-io_connect_t ks_connect_to_service(const char *className);
-
-io_connect_t ks_get_connect(void);
-
-
-/*!
-    @function ks_available
-    @abstract Check if the AppleKeyStore.kext is available, you must call
-    this function before using any other library function.
-    @result true, unless for some reason ks isn't available then false.
- */
-bool ks_available(void);
-
-/*!
-    @function ks_free
-    @abstract free something allocated by a ks_ function.
-    @param ks_object buffer allocated by the
- */
-void ks_free(ks_object_t ks_object);
-
-/*!
-    @function ks_unwrap
-    @abstract unwrap a key using the specified keyclass.
-    @param keybag the keybag handle containing the class key which will be
-    doing the wrapping.
-    @param keyclass handle for the wrapping key.
-    @param bufferSize number of bytes available in array pointed to by buffer
-    @param buffer pointer to a buffer.
-    @param wrappedKeySize (output) size of the wrappedKey if it had been
-    written to buffer.
-    @param error (optional) pointer to a CFErrorRef who's value will only be
-    changed if it is NULL, in which case the caller is responsible for
-    calling CFRelease on it.
-    @result Returns pointer to the wrappedKey, or
-    NULL if an error occured. Pass in a pointer to a CFErrorRef who's value
-    is NULL to obtain an error object.
-    @discussion If and only if NULL is passed for the buffer parameter, this
-    function will allocate a buffer to which it writes the wrappedKey.
- */
-uint8_t *ks_unwrap(uint64_t keybag, uint64_t keyclass,
-    const uint8_t *wrappedKey, size_t wrappedKeySize,
-    uint8_t *buffer, size_t bufferSize, size_t *keySize);
-
-/*!
-    @function ks_wrap
-    @abstract wrap a 128 bit (16 byte), 192 bit (24 byte) or 256 bit (32 byte)
-    key using the specified keyclass.
-    @param keybag the keybag handle containing the class key which will be
-    doing the wrapping.
-    @param keyclass handle for the wrapping key.
-    @param bufferSize number of bytes available in array pointed to by buffer
-    @param buffer pointer to a buffer.
-    @param wrappedKeySize (output) size of the wrappedKey if it had been
-    written to buffer.
-    @param error (optional) pointer to a CFErrorRef who's value will only be
-    changed if it is NULL, in which case the caller is responsible for
-    calling CFRelease on it.
-    @result Returns pointer to the wrappedKey, or
-    NULL if an error occured. Pass in a pointer to a CFErrorRef who's value
-    is NULL to obtain an error object.
-    @discussion If and only if NULL is passed for the buffer parameter, this
-    function will allocate a buffer to which it writes the wrappedKey.
- */
-uint8_t *ks_wrap(uint64_t keybag, uint64_t keyclass,
-    const uint8_t *key, size_t keyByteSize,
-    uint8_t *buffer, size_t bufferSize, size_t *wrappedKeySize);
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* _SECURITYD_KEYSTORE_H_ */
index 198de9e88f788592eb1426c9f6f8327639799d30..a85b1cdc512622935991792905b9dbbee86bd00e 100644 (file)
@@ -28,7 +28,7 @@
 #include "policytree.h"
 #include <libDER/oids.h>
 
 #include "policytree.h"
 #include <libDER/oids.h>
 
-#include <security_utilities/debugging.h>
+#include <utilities/debugging.h>
 
 #include <stdlib.h>
 
 
 #include <stdlib.h>
 
index 3debd608c5b72796c681721f883f749ca0496d27..ef5761dfcba4db0f0c4b18707e18ac7a57f99101 100644 (file)
@@ -35,9 +35,7 @@
 #include <stdbool.h>
 #include <Security/certextensions.h>
 
 #include <stdbool.h>
 #include <Security/certextensions.h>
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 
 #define oid_equal(oid1, oid2) DEROidCompare(&oid1, &oid2)
 
 
 #define oid_equal(oid1, oid2) DEROidCompare(&oid1, &oid2)
@@ -81,8 +79,6 @@ void policy_tree_set_expected_policy(policy_tree_t node,
 /* noop unless !defined NDEBUG */
 void policy_tree_dump(policy_tree_t node);
 
 /* noop unless !defined NDEBUG */
 void policy_tree_dump(policy_tree_t node);
 
-#if defined(__cplusplus)
-}
-#endif
+__END_DECLS
 
 #endif /* !_SECURITY_POLICYTREE_H_ */
 
 #endif /* !_SECURITY_POLICYTREE_H_ */
index 7ecf3c53fe4928299482dc0ee470c2c17a28cc54..711dde2557e6afbeededa4823db216520446988b 100644 (file)
@@ -9,28 +9,67 @@
 
 #include <securityd/spi.h>
 #include <securityd_client.h>
 
 #include <securityd/spi.h>
 #include <securityd_client.h>
-#include <securityd_server.h>
 #include <securityd/SecPolicyServer.h>
 #include <securityd/SecPolicyServer.h>
+#include <securityd/SecItemServer.h>
+#include <securityd/SecTrustStoreServer.h>
+#include <SecureObjectSync/SOSPeerInfo.h>
+#include <CoreFoundation/CFString.h>
+#include <CoreFoundation/CFError.h>
+#include <securityd/SOSCloudCircleServer.h>
+
+#include "securityd_client.h"
+#include <CoreFoundation/CFXPCBridge.h>
+#include "utilities/iOSforOSX.h"
+#include "utilities/SecFileLocations.h"
+#include "OTATrustUtilities.h"
 
 static struct securityd spi = {
 
 static struct securityd spi = {
-    _SecItemAdd,
-    _SecItemCopyMatching,
-    _SecItemUpdate,
-    _SecItemDelete,
-    SecTrustStoreForDomainName,
-    SecTrustStoreContainsCertificateWithDigest,
-    _SecTrustStoreSetTrustSettings,
-    SecTrustStoreRemoveCertificateWithDigest,
-    _SecTrustStoreRemoveAll,
-    _SecItemDeleteAll,
-    SecTrustServerEvaluate,
-    _SecServerRestoreKeychain,
-    _SecServerMigrateKeychain,
-    _SecServerKeychainBackup,
-    _SecServerKeychainRestore
+    .sec_item_add                           = _SecItemAdd,
+    .sec_item_copy_matching                 = _SecItemCopyMatching,
+    .sec_item_update                        = _SecItemUpdate,
+    .sec_item_delete                        = _SecItemDelete,
+    .sec_trust_store_for_domain             = SecTrustStoreForDomainName,
+    .sec_trust_store_contains               = SecTrustStoreContainsCertificateWithDigest,
+    .sec_trust_store_set_trust_settings     = _SecTrustStoreSetTrustSettings,
+    .sec_trust_store_remove_certificate     = SecTrustStoreRemoveCertificateWithDigest,
+    .sec_truststore_remove_all              = _SecTrustStoreRemoveAll,
+    .sec_item_delete_all                    = _SecItemDeleteAll,
+    .sec_trust_evaluate                     = SecTrustServerEvaluate,
+    .sec_keychain_backup                    = _SecServerKeychainBackup,
+    .sec_keychain_restore                   = _SecServerKeychainRestore,
+    .sec_keychain_sync_update               = _SecServerKeychainSyncUpdate,
+    .sec_keychain_backup_syncable           = _SecServerBackupSyncable,
+    .sec_keychain_restore_syncable          = _SecServerRestoreSyncable,
+    .sec_ota_pki_asset_version              = SecOTAPKIGetCurrentAssetVersion,
+    .soscc_TryUserCredentials               = SOSCCTryUserCredentials_Server,
+    .soscc_SetUserCredentials               = SOSCCSetUserCredentials_Server,
+    .soscc_CanAuthenticate                  = SOSCCCanAuthenticate_Server,
+    .soscc_PurgeUserCredentials             = SOSCCPurgeUserCredentials_Server,
+    .soscc_ThisDeviceIsInCircle             = SOSCCThisDeviceIsInCircle_Server,
+    .soscc_RequestToJoinCircle              = SOSCCRequestToJoinCircle_Server,
+    .soscc_RequestToJoinCircleAfterRestore  = SOSCCRequestToJoinCircleAfterRestore_Server,
+    .soscc_ResetToOffering                  = SOSCCResetToOffering_Server,
+    .soscc_ResetToEmpty                     = SOSCCResetToEmpty_Server,
+    .soscc_RemoveThisDeviceFromCircle       = SOSCCRemoveThisDeviceFromCircle_Server,
+    .soscc_BailFromCircle                   = SOSCCBailFromCircle_Server,
+    .soscc_AcceptApplicants                 = SOSCCAcceptApplicants_Server,
+    .soscc_RejectApplicants                 = SOSCCRejectApplicants_Server,
+    .soscc_CopyApplicantPeerInfo            = SOSCCCopyApplicantPeerInfo_Server,
+    .soscc_CopyPeerInfo                     = SOSCCCopyPeerPeerInfo_Server,
+    .soscc_CopyConcurringPeerInfo           = SOSCCCopyConcurringPeerPeerInfo_Server,
+    .ota_CopyEscrowCertificates                                = SecOTAPKICopyCurrentEscrowCertificates,
+       .sec_ota_pki_get_new_asset              = SecOTAPKISignalNewAsset,
+    .soscc_ProcessSyncWithAllPeers          = SOSCCProcessSyncWithAllPeers_Server
 };
 
 };
 
-void securityd_init(void) {
+void securityd_init_server(void) {
     gSecurityd = &spi;
     SecPolicyServerInitalize();
 }
     gSecurityd = &spi;
     SecPolicyServerInitalize();
 }
+
+void securityd_init(char* home_path) {
+    if (home_path)
+        SetCustomHomeURL(home_path);
+
+    securityd_init_server();
+}
index 16c32701ab092a34e71f3de13a86fb67c6216781..ceb2bca70ee0d167cf58fde605366a06aa396893 100644 (file)
 #ifndef _SECURITYD_SPI_H_
 #define _SECURITYD_SPI_H_
 
 #ifndef _SECURITYD_SPI_H_
 #define _SECURITYD_SPI_H_
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+#include <utilities/SecCFError.h>
+#include <xpc/xpc.h>
 
 
+__BEGIN_DECLS
 
 /* Calling this function initializes the spi interface in the library to call
 
 /* Calling this function initializes the spi interface in the library to call
-   directly into the backend. */
-void securityd_init(void);
+   directly into the backend. It uses home_dir for root of files if specified. */
+void securityd_init(char* home_dir);
 
 
-#if defined(__cplusplus)
-}
-#endif
+// Don't call this function unless you are really securityd
+void securityd_init_server(void);
+
+__END_DECLS
 
 #endif /* _SECURITYD_SPI_H_ */
 
 #endif /* _SECURITYD_SPI_H_ */
diff --git a/secdtests/main.c b/secdtests/main.c
new file mode 100644 (file)
index 0000000..fb6392e
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *  main.c
+ *  Security
+ *
+ *  Created by Fabrice Gautier on 8/7/12.
+ *  Copyright 2012 Apple, Inc. All rights reserved.
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include "test/testenv.h"
+
+#include "testlist.h"
+#include <test/testlist_begin.h>
+#include "testlist.h"
+#include <test/testlist_end.h>
+
+#include <securityd/spi.h>
+
+int main(int argc, char *argv[])
+{
+    printf("Build date : %s %s\n", __DATE__, __TIME__);
+
+    /* We run this as if we are secd, so we need to initialize this */
+    securityd_init(NULL);
+
+    int result = tests_begin(argc, argv);
+
+    fflush(stderr);
+    fflush(stdout);
+
+    sleep(1);
+
+    return result;
+}
diff --git a/secdtests/testlist.h b/secdtests/testlist.h
new file mode 100644 (file)
index 0000000..e4b0f70
--- /dev/null
@@ -0,0 +1,4 @@
+/* Don't prevent multiple inclusion of this file. */
+#include <utilities/Regressions/utilities_regressions.h>
+#include <sec/SOSCircle/Regressions/SOSCircle_regressions.h>
+#include <sec/securityd/Regressions/secd_regressions.h>
diff --git a/sectests/SecurityTests-Entitlements.plist b/sectests/SecurityTests-Entitlements.plist
new file mode 100644 (file)
index 0000000..cfa9a9e
--- /dev/null
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>keychain-cloud-circle</key>
+       <true/>
+       <key>com.apple.keystore.access-keychain-keys</key>
+       <true/>
+       <key>com.apple.keystore.device</key>
+       <true/>
+       <key>restore-keychain</key>
+       <true/>
+       <key>migrate-keychain</key>
+       <true/>
+       <key>modify-anchor-certificates</key>
+       <true/>
+       <key>com.apple.springboard.wipedevice</key>
+       <true/>
+       <key>application-identifier</key>
+       <string>com.apple.security.regressions</string>
+       <key>keychain-access-groups</key>
+       <array>
+               <string>com.apple.security.regressions</string>
+               <string>lockdown-identities</string>
+               <string>apple</string>
+       </array>
+       <key>com.apple.private.ubiquity-kvstore-access</key>
+       <array>
+               <string>com.apple.securityd</string>
+       </array>
+       <key>com.apple.developer.ubiquity-kvstore-identifier</key>
+       <string>com.apple.security.cloudkeychainproxy3</string>
+       <key>com.apple.developer.ubiquity-container-identifiers</key>
+       <array>
+               <string>com.apple.security.cloudkeychainproxy3</string>
+               <string>com.apple.security.cloudkeychain</string>
+               <string>CloudKeychainProxy.xpc</string>
+       </array>
+</dict>
+</plist>
diff --git a/sectests/main.c b/sectests/main.c
new file mode 100644 (file)
index 0000000..7d2290d
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ *  main.c
+ *  Security
+ *
+ *  Created by Fabrice Gautier on 8/7/12.
+ *  Copyright 2012 Apple, Inc. All rights reserved.
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include "test/testenv.h"
+
+#include "testlist.h"
+#include <test/testlist_begin.h>
+#include "testlist.h"
+#include <test/testlist_end.h>
+
+int main(int argc, char *argv[])
+{
+    printf("Build date : %s %s\n", __DATE__, __TIME__);
+
+    int result = tests_begin(argc, argv);
+
+    fflush(stderr);
+    fflush(stdout);
+
+    sleep(1);
+
+    return result;
+}
diff --git a/sectests/test/testenv.c b/sectests/test/testenv.c
new file mode 100644 (file)
index 0000000..a9a00c2
--- /dev/null
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2005-2007,2009-2011 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ *
+ * testenv.c
+ */
+
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdbool.h>
+
+#include "testmore.h"
+#include "testenv.h"
+
+int test_verbose = 0;
+
+#if NO_SERVER
+#include <securityd/spi.h>
+
+static int current_dir = -1;
+static char scratch_dir[50];
+static char *home_var;
+static bool keep_scratch_dir = false;
+
+static int
+rmdir_recursive(const char *path)
+{
+       char command_buf[256];
+       if (strlen(path) + 10 > sizeof(command_buf) || strchr(path, '\''))
+       {
+               fprintf(stderr, "# rmdir_recursive: invalid path: %s", path);
+               return -1;
+       }
+
+       sprintf(command_buf, "rm -rf '%s'", path);
+       return system(command_buf);
+}
+#endif
+
+static int tests_init(void) {
+#if NO_SERVER
+       char preferences_dir[80];
+       char library_dir[70];
+
+    char *path = getenv("TESTHOME");
+    if (path)
+        setenv("TESTHOME", path, 1);
+    securityd_init();
+
+       setup("tests_init");
+    
+    /* Create scratch dir for tests to run in. */
+    sprintf(scratch_dir, "/tmp/tst-%d", getpid());
+    if (keep_scratch_dir) {
+        printf("running tests with HOME=%s\n", scratch_dir);
+    }
+    sprintf(library_dir, "%s/Library", scratch_dir);
+    sprintf(preferences_dir, "%s/Preferences", library_dir);
+    return (ok_unix(mkdir(scratch_dir, 0755), "mkdir") &&
+            ok_unix(current_dir = open(".", O_RDONLY), "open") &&
+            ok_unix(chdir(scratch_dir), "chdir") &&
+            ok_unix(setenv("HOME", scratch_dir, 1), "setenv") &&
+            /* @@@ Work around a bug that the prefs code in
+             libsecurity_keychain never creates the Library/Preferences
+             dir. */
+            ok_unix(mkdir(library_dir, 0755), "mkdir") &&
+            ok_unix(mkdir(preferences_dir, 0755), "mkdir") &&
+            ok(home_var = getenv("HOME"), "getenv"));
+    
+#else
+    return 0;
+#endif 
+}
+
+static int
+tests_end(void)
+{
+#if NO_SERVER
+       setup("tests_end");
+       /* Restore previous cwd and remove scratch dir. */
+       int ok = ok_unix(fchdir(current_dir), "fchdir");
+       if (ok)
+               ok = ok_unix(close(current_dir), "close");
+       if (ok) {
+               if (!keep_scratch_dir) {
+                       ok = ok_unix(rmdir_recursive(scratch_dir), "rmdir_recursive");
+               }
+       }
+    
+       return ok;
+#else
+    return 0;
+#endif
+}
+
+static void usage(const char *progname)
+{
+    fprintf(stderr, "usage: %s [-k][-w][testname [testargs] ...]\n", progname);
+    exit(1);
+}
+
+static int tests_run_index(int i, int argc, char * const *argv)
+{
+    int ch;
+
+    while ((ch = getopt(argc, argv, "v")) != -1)
+    {
+        switch  (ch)
+        {
+            case 'v':
+                test_verbose++;
+                break;
+            default:
+                usage(argv[0]);
+        }
+    }
+
+    fprintf(stderr, "TEST: Test Case '%s' started.\n", testlist[i].name);
+    
+    run_one_test(&testlist[i], argc, argv);
+    if(testlist[i].failed_tests) {
+        fprintf(stderr, "FAIL: Test Case '%s' failed.\n", testlist[i].name);
+    } else {
+        fprintf(stderr, "PASS: Test Case '%s' passed. (%lu ms)\n", testlist[i].name, testlist[i].duration);
+    }
+    return testlist[i].failed_tests;
+}
+
+static int strcmp_under_is_dash(const char *s, const char *t) {
+    for (;;) {
+        char a = *s++, b = *t++;
+        if (a != b) {
+            if (a != '_' || b != '-')
+                return a - b;
+        } else if (a == 0) {
+            return 0;
+        }
+    }
+}
+
+static int tests_named_index(const char *testcase)
+{
+    int i;
+
+    for (i = 0; testlist[i].name; ++i) {
+        if (strcmp_under_is_dash(testlist[i].name, testcase) == 0) {
+            return i;
+        }
+    }
+
+    return -1;
+}
+
+static int tests_run_all(int argc, char * const *argv)
+{
+    int curroptind = optind;
+    int i;
+    int failcount=0;
+
+    for (i = 0; testlist[i].name; ++i) {
+        if(!testlist[i].off) {
+            failcount+=tests_run_index(i, argc, argv);
+            optind = curroptind;
+        }
+    }
+    
+    return failcount;
+}
+
+int
+tests_begin(int argc, char * const *argv)
+{
+    const char *testcase = NULL;
+    bool initialized = false;
+    int testix = -1;
+    int failcount = 0;
+       int ch;
+    int loop = 0;
+
+    for (;;) {
+        while (!testcase && (ch = getopt(argc, argv, "klw")) != -1)
+        {
+            switch  (ch)
+            {
+#ifdef NO_SERVER
+            case 'k':
+                keep_scratch_dir = true;
+                break;
+#endif
+            case 'w':
+                sleep(100);
+                break;
+            case 'l':
+                loop=1;
+                break;
+            case '?':
+            default:
+                printf("invalid option %c\n",ch); 
+                usage(argv[0]);
+            }
+        }
+
+        if (optind < argc) {
+            testix = tests_named_index(argv[optind]);
+            if(testix<0) {
+                printf("invalid test %s\n",argv[optind]); 
+                usage(argv[0]);
+            }
+        }
+
+        if (testix < 0) {
+            if (!initialized) {
+                initialized = true;
+                tests_init();
+                failcount+=tests_run_all(argc, argv);
+            }
+            break;
+        } else {
+            if (!initialized) {
+                tests_init();
+                initialized = true;
+            }
+            optind++;
+            failcount+=tests_run_index(testix, argc, argv);
+            testix = -1;
+        }
+    }
+        
+    printf("Total failcount = %d\n", failcount);
+
+    /* Cleanups */
+    tests_end();
+    
+    if(loop) {
+        printf("Looping until key press 'q'. You can run leaks now.\n");
+        while(getchar()!='q');
+    }
+
+    return failcount;
+}
+
diff --git a/sectests/testlist.h b/sectests/testlist.h
new file mode 100644 (file)
index 0000000..afd1665
--- /dev/null
@@ -0,0 +1,3 @@
+/* Don't prevent multiple inclusion of this file. */
+#include <libsecurity_ssl/regressions/ssl_regressions.h>
+#include <libsecurity_keychain/regressions/keychain_regressions.h>
diff --git a/security2/security2.1 b/security2/security2.1
new file mode 100644 (file)
index 0000000..621b26d
--- /dev/null
@@ -0,0 +1,79 @@
+.\"Modified from man(1) of FreeBSD, the NetBSD mdoc.template, and mdoc.samples.\r
+.\"See Also:\r
+.\"man mdoc.samples for a complete listing of options\r
+.\"man mdoc for the short list of editing options\r
+.\"/usr/share/misc/mdoc.template\r
+.Dd 1/10/13               \" DATE \r
+.Dt security2 1      \" Program name and manual section number \r
+.Os Darwin\r
+.Sh NAME                 \" Section Header - required - don't modify \r
+.Nm security2,\r
+.\" The following lines are read in generating the apropos(man -k) database. Use only key\r
+.\" words here as the database is built based on the words here and in the .ND line. \r
+.Nm Other_name_for_same_program(),\r
+.Nm Yet another name for the same program.\r
+.\" Use .Nm macro to designate other names for the documented program.\r
+.Nd This line parsed for whatis database.\r
+.Sh SYNOPSIS             \" Section Header - required - don't modify\r
+.Nm\r
+.Op Fl abcd              \" [-abcd]\r
+.Op Fl a Ar path         \" [-a path] \r
+.Op Ar file              \" [file]\r
+.Op Ar                   \" [file ...]\r
+.Ar arg0                 \" Underlined argument - use .Ar anywhere to underline\r
+arg2 ...                 \" Arguments\r
+.Sh DESCRIPTION          \" Section Header - required - don't modify\r
+Use the .Nm macro to refer to your program throughout the man page like such:\r
+.Nm\r
+Underlining is accomplished with the .Ar macro like this:\r
+.Ar underlined text .\r
+.Pp                      \" Inserts a space\r
+A list of items with descriptions:\r
+.Bl -tag -width -indent  \" Begins a tagged list \r
+.It item a               \" Each item preceded by .It macro\r
+Description of item a\r
+.It item b\r
+Description of item b\r
+.El                      \" Ends the list\r
+.Pp\r
+A list of flags and their descriptions:\r
+.Bl -tag -width -indent  \" Differs from above in tag removed \r
+.It Fl a                 \"-a flag as a list item\r
+Description of -a flag\r
+.It Fl b\r
+Description of -b flag\r
+.El                      \" Ends the list\r
+.Pp\r
+.\" .Sh ENVIRONMENT      \" May not be needed\r
+.\" .Bl -tag -width "ENV_VAR_1" -indent \" ENV_VAR_1 is width of the string ENV_VAR_1\r
+.\" .It Ev ENV_VAR_1\r
+.\" Description of ENV_VAR_1\r
+.\" .It Ev ENV_VAR_2\r
+.\" Description of ENV_VAR_2\r
+.\" .El                      \r
+.Sh FILES                \" File used or created by the topic of the man page\r
+.Bl -tag -width "/Users/joeuser/Library/really_long_file_name" -compact\r
+.It Pa /usr/share/file_name\r
+FILE_1 description\r
+.It Pa /Users/joeuser/Library/really_long_file_name\r
+FILE_2 description\r
+.El                      \" Ends the list\r
+.\" .Sh DIAGNOSTICS       \" May not be needed\r
+.\" .Bl -diag\r
+.\" .It Diagnostic Tag\r
+.\" Diagnostic informtion here.\r
+.\" .It Diagnostic Tag\r
+.\" Diagnostic informtion here.\r
+.\" .El\r
+.Sh SEE ALSO \r
+.\" List links in ascending order by section, alphabetically within a section.\r
+.\" Please do not reference files that do not exist without filing a bug report\r
+.Xr a 1 , \r
+.Xr b 1 ,\r
+.Xr c 1 ,\r
+.Xr a 2 ,\r
+.Xr b 2 ,\r
+.Xr a 3 ,\r
+.Xr b 3 \r
+.\" .Sh BUGS              \" Document known, unremedied bugs \r
+.\" .Sh HISTORY           \" Document history if command behaves in a unique manner
\ No newline at end of file
diff --git a/security2/security_tool_commands.c b/security2/security_tool_commands.c
new file mode 100644 (file)
index 0000000..c7f3f92
--- /dev/null
@@ -0,0 +1,28 @@
+//
+//  security_tool_commands.c
+//  Security
+//
+//  Created by J Osborne on 1/10/13.
+//
+//
+
+#include <TargetConditionals.h>
+#include <stdio.h>
+#include "SecurityTool/SecurityTool.h"
+
+#include "SecurityTool/security_tool_commands.h"
+
+#include "SecurityTool/builtin_commands.h"
+#include "security2/sub_commands.h"
+
+// Redefine for making them declaraionts.
+#include "SecurityTool/security_tool_commands_table.h"
+
+const command commands[] =
+{
+#include "SecurityTool/builtin_commands.h"
+    
+#include "security2/sub_commands.h"
+    
+    {}
+};
diff --git a/security2/sub_commands.h b/security2/sub_commands.h
new file mode 100644 (file)
index 0000000..8ceb3b1
--- /dev/null
@@ -0,0 +1,12 @@
+//
+//  sub_commands.h
+//  Security
+//
+//  Created by J Osborne on 1/10/13.
+//
+//
+
+// This file can't be once, it gets included multiple times to get definitions and declarations.
+
+#include "Security/Tool/SecurityCommands.h"
+#include "SOSCircle/Tool/SOSCommands.h"
diff --git a/security_utilities/debugging.c b/security_utilities/debugging.c
deleted file mode 100644 (file)
index 7e1a04b..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (c) 2006-2010 Apple Inc. All Rights Reserved.
- * 
- * @APPLE_LICENSE_HEADER_START@
- * 
- * 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 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-
-
-/* 
- * debugging.c - non-trivial debug support
- */
-#include <security_utilities/debugging.h>
-#include <CoreFoundation/CFSet.h>
-#include <CoreFoundation/CFString.h>
-
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <pthread.h>
-#include <asl.h>
-
-#define MAX_SCOPE_LENGTH  12
-
-#if !defined(NDEBUG)
-static CFStringRef copyScopeName(const char *scope, CFIndex scopeLen) {
-       if (scopeLen > MAX_SCOPE_LENGTH)
-               scopeLen = MAX_SCOPE_LENGTH - 1;
-       return CFStringCreateWithBytes(kCFAllocatorDefault, (const UInt8 *)scope,
-               scopeLen, kCFStringEncodingUTF8, false);
-}
-
-pthread_once_t __security_debug_once = PTHREAD_ONCE_INIT;
-static const char *gDebugScope;
-static CFMutableSetRef scopeSet;
-static bool negate = false;
-
-static void __security_debug_init(void) {
-       const char *cur_scope = gDebugScope = getenv("DEBUGSCOPE");
-       if (cur_scope) {
-               if (!strcmp(cur_scope, "all")) {
-                       scopeSet = NULL;
-                       negate = true;
-               } else if (!strcmp(cur_scope, "none")) {
-                       scopeSet = NULL;
-                       negate = false;
-               } else {
-                       scopeSet = CFSetCreateMutable(kCFAllocatorDefault, 0,
-                               &kCFTypeSetCallBacks);
-                       if (cur_scope[0] == '-') {
-                               negate = true;
-                               cur_scope++;
-                       } else {
-                               negate = false;
-                       }
-
-                       const char *sep;
-                       while ((sep = strchr(cur_scope, ','))) {
-                               CFStringRef scopeName = copyScopeName(cur_scope,
-                                       sep - cur_scope);
-                               CFSetAddValue(scopeSet, scopeName);
-                               CFRelease(scopeName);
-                               cur_scope = sep + 1;
-                       }
-
-                       CFStringRef scopeName = copyScopeName(cur_scope,
-                               strlen(cur_scope));
-                       CFSetAddValue(scopeSet, scopeName);
-                       CFRelease(scopeName);
-               }
-       } else {
-               scopeSet = NULL;
-               negate = false;
-       }
-}
-
-#endif
-
-void __security_debug(CFStringRef scope, const char *function,
-    const char *file, int line, CFStringRef format, ...)
-{
-#if !defined(NDEBUG)
-       pthread_once(&__security_debug_once, __security_debug_init);
-
-       /* Scope NULL is always enabled. */
-       if (scope) {
-               /* Check if the scope is enabled. */
-               if (scopeSet) {
-                       if (negate == CFSetContainsValue(scopeSet, scope)) {
-                               return;
-                       }
-               } else if (!negate) {
-                       return;
-               }
-       }
-#endif
-
-       va_list args;
-       va_start(args, format);
-       CFStringRef message = CFStringCreateWithFormatAndArguments(
-               kCFAllocatorDefault, NULL, format, args);
-       va_end(args);
-       time_t now = time(NULL);
-       char *date = ctime(&now);
-       date[19] = '\0';
-       CFStringRef logStr = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
-               CFSTR("%s %@ %s %@\n"), date + 4,
-        scope ? scope : CFSTR(""), function, message);
-       CFShow(logStr);
-    char logMsg[4096];
-    if (CFStringGetCString(logStr, logMsg, sizeof(logMsg), kCFStringEncodingUTF8)) {
-        char scopeStr[MAX_SCOPE_LENGTH + 1];
-        aslmsg msg = asl_new(ASL_TYPE_MSG);
-        if (scope) {
-            if (CFStringGetCString(scope, scopeStr, sizeof(scopeStr),
-                                   kCFStringEncodingUTF8)) {
-                asl_set(msg, ASL_KEY_FACILITY, scopeStr);
-            }
-            asl_set(msg, ASL_KEY_LEVEL, ASL_STRING_INFO);
-        } else {
-            asl_set(msg, ASL_KEY_LEVEL, ASL_STRING_ERR);
-        }
-        asl_set(msg, ASL_KEY_MSG, logMsg);
-        asl_send(NULL, msg);
-        asl_free(msg);
-    }
-       CFRelease(logStr);
-       CFRelease(message);
-}
diff --git a/security_utilities/debugging.h b/security_utilities/debugging.h
deleted file mode 100644 (file)
index 8aa6e96..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2006-2007,2009-2010 Apple Inc. All Rights Reserved.
- * 
- * @APPLE_LICENSE_HEADER_START@
- * 
- * 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 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/* 
- * debugging.h - non-trivial debug support
- */
-#ifndef _SECURITY_UTILITIES_DEBUGGING_H_
-#define _SECURITY_UTILITIES_DEBUGGING_H_
-
-#include <CoreFoundation/CFString.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern void __security_debug(CFStringRef scope,
-                             const char *function, const char *file, int line,
-                             CFStringRef format, ...) CF_FORMAT_FUNCTION(5,6);
-
-#define secerror(format, ...)  __security_debug(NULL, \
-    __FUNCTION__, __FILE__, __LINE__, \
-    CFSTR(format), ## __VA_ARGS__)
-
-#if !defined(NDEBUG)
-# define secdebug(scope,format, ...)   __security_debug(CFSTR(scope), \
-    __FUNCTION__, __FILE__, __LINE__, \
-    CFSTR(format), ## __VA_ARGS__)
-
-# define secwarning(format, ...)       __security_debug(NULL, \
-__FUNCTION__, __FILE__, __LINE__, \
-CFSTR(format), ## __VA_ARGS__)
-#else
-# define secdebug(scope,...)   /* nothing */
-# define secwarning(scope,...) /* nothing */
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SECURITY_UTILITIES_DEBUGGING_H_ */
diff --git a/security_utilities/fileIo.c b/security_utilities/fileIo.c
deleted file mode 100644 (file)
index 42fcb11..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2005-2007,2010 Apple Inc. All Rights Reserved.
- */
-
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdint.h>
-#include "fileIo.h"
-
-int writeFile(
-       const char                      *fileName,
-       const unsigned char     *bytes,
-       size_t              numBytes)
-{
-       int             rtn;
-       int     fd;
-
-    if (!fileName) {
-        fwrite(bytes, 1, numBytes, stdout);
-        fflush(stdout);
-        return ferror(stdout);
-    }
-
-       fd = open(fileName, O_RDWR | O_CREAT | O_TRUNC, 0600);
-       if(fd <= 0) {
-               return errno;
-       }
-       rtn = write(fd, bytes, (size_t)numBytes);
-       if(rtn != (int)numBytes) {
-               if(rtn >= 0) {
-                       fprintf(stderr, "writeFile: short write\n");
-               }
-               rtn = EIO;
-       }
-       else {
-               rtn = 0;
-       }
-       close(fd);
-       return rtn;
-}
-       
-/*
- * Read entire file. 
- */
-int readFile(
-       const char              *fileName,
-       unsigned char   **bytes,                // mallocd and returned
-       size_t          *numBytes)              // returned
-{
-       int rtn;
-       int fd;
-       char *buf;
-       struct stat     sb;
-       size_t size;
-       
-       *numBytes = 0;
-       *bytes = NULL;
-       fd = open(fileName, O_RDONLY);
-       if(fd <= 0) {
-               return errno;
-       }
-       rtn = fstat(fd, &sb);
-       if(rtn) {
-               goto errOut;
-       }
-       if (sb.st_size > SIZE_MAX) {
-               rtn = EFBIG;
-               goto errOut;
-       }
-       size = (size_t)sb.st_size;
-       buf = (char *)malloc(size);
-       if(buf == NULL) {
-               rtn = ENOMEM;
-               goto errOut;
-       }
-       rtn = read(fd, buf, (size_t)size);
-       if(rtn != (int)size) {
-               if(rtn >= 0) {
-                       fprintf(stderr, "readFile: short read\n");
-               }
-               rtn = EIO;
-       }
-       else {
-               rtn = 0;
-               *bytes = (unsigned char *)buf;
-               *numBytes = size;
-       }
-
-errOut:
-       close(fd);
-       return rtn;
-}
diff --git a/security_utilities/fileIo.h b/security_utilities/fileIo.h
deleted file mode 100644 (file)
index e6470c1..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2005-2007,2010 Apple Inc. All Rights Reserved.
- */
-
-#include <sys/types.h>
-
-/*
- * Read entire file. 
- */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int readFile(
-       const char                      *fileName,
-       unsigned char           **bytes,                // mallocd and returned
-       size_t              *numBytes);         // returned
-
-int writeFile(
-       const char                      *fileName,
-       const unsigned char     *bytes,
-       size_t              numBytes);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/security_utilities/sqlutils.h b/security_utilities/sqlutils.h
deleted file mode 100644 (file)
index 6837a03..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-//
-//  sqlutils.h
-//  Security
-//
-//  Created by Fabrice Gautier on 8/26/11.
-//  Copyright (c) 2011 Apple, Inc. All rights reserved.
-//
-
-/*
- * sqlutils.h - some wrapper for sql3lite
- */
-#ifndef _SECURITY_UTILITIES_SQLUTILS_H_
-#define _SECURITY_UTILITIES_SQLUTILS_H_
-
-#include <sqlite3.h>
-
-/* Those are just wrapper around the sqlite3 functions, but they have size_t for some len parameters,
-   and checks for overflow before casting to int */
-static inline int sqlite3_bind_blob_wrapper(sqlite3_stmt* pStmt, int i, const void* zData, size_t n, void(*xDel)(void*))
-{
-    if(n>INT_MAX) return SQLITE_TOOBIG;
-    return sqlite3_bind_blob(pStmt, i, zData, (int)n, xDel);
-}
-
-static inline int sqlite3_bind_text_wrapper(sqlite3_stmt* pStmt, int i, const void* zData, size_t n, void(*xDel)(void*))
-{
-    if(n>INT_MAX) return SQLITE_TOOBIG;
-    return sqlite3_bind_text(pStmt, i, zData, (int)n, xDel);
-}
-
-static inline int sqlite3_prepare_wrapper(sqlite3 *db, const char *zSql, size_t nByte, sqlite3_stmt **ppStmt, const char **pzTail)
-{
-    if(nByte>INT_MAX) return SQLITE_TOOBIG;
-    return sqlite3_prepare(db, zSql, (int)nByte, ppStmt, pzTail);
-}
-
-#endif
diff --git a/tlsnke/loadkext.sh b/tlsnke/loadkext.sh
new file mode 100755 (executable)
index 0000000..0320d5e
--- /dev/null
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+# install this script in /var/root/ to use with the xcode project.
+
+cp -R $1 /tmp
+kextunload -v /tmp/tlsnke.kext/
+kextload -v /tmp/tlsnke.kext/
+
diff --git a/tlsnke/tlsnke.xcodeproj/project.pbxproj b/tlsnke/tlsnke.xcodeproj/project.pbxproj
new file mode 100644 (file)
index 0000000..a822502
--- /dev/null
@@ -0,0 +1,593 @@
+// !$*UTF8*$!
+{
+       archiveVersion = 1;
+       classes = {
+       };
+       objectVersion = 46;
+       objects = {
+
+/* Begin PBXAggregateTarget section */
+               0CE08A7E148FF61C000473EB /* host-loadkext */ = {
+                       isa = PBXAggregateTarget;
+                       buildConfigurationList = 0CE08A7F148FF61C000473EB /* Build configuration list for PBXAggregateTarget "host-loadkext" */;
+                       buildPhases = (
+                               0CE08A89148FF86C000473EB /* ShellScript */,
+                       );
+                       dependencies = (
+                               0CE08A83148FF628000473EB /* PBXTargetDependency */,
+                       );
+                       name = "host-loadkext";
+                       productName = all;
+               };
+/* End PBXAggregateTarget section */
+
+/* Begin PBXBuildFile section */
+               0C271D7515C8C80300560531 /* libsecurity_ssl_kext.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CBE354615C8C3A5006241C7 /* libsecurity_ssl_kext.a */; };
+               0C38E43D14BF707500DD862C /* tlsnke.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C38E43C14BF707500DD862C /* tlsnke.h */; };
+               0C6C642715D5A9C200BC68CD /* ssl-utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C6C642515D5A9C200BC68CD /* ssl-utils.c */; };
+               0C7CF8D714E18A9F00DF9D95 /* dtls_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C7CF8D614E18A9F00DF9D95 /* dtls_client.c */; };
+               0CBE354515C8C340006241C7 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CBE354415C8C340006241C7 /* Security.framework */; };
+               0CC9A7FA146DF66000C18F89 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0CC9A7F8146DF66000C18F89 /* InfoPlist.strings */; };
+               0CC9A7FC146DF66000C18F89 /* tlsnke.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CC9A7FB146DF66000C18F89 /* tlsnke.c */; };
+               0CDF46A414DC794F00FFE2FD /* tlssocket.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CA31A4214B7DFAB00BD348C /* tlssocket.c */; };
+               0CDF46A514DC795400FFE2FD /* tlssocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CA31A4514B7DFBA00BD348C /* tlssocket.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0CDF46A614DC79FA00FFE2FD /* libtlssocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CDF46A014DC794300FFE2FD /* libtlssocket.a */; };
+               0CE08A77148FF2C7000473EB /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CE08A76148FF2C7000473EB /* main.c */; };
+               0CEF580014C0E227000A93B0 /* st_test.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CEF57FF14C0E227000A93B0 /* st_test.c */; };
+               0CEF580614C0E566000A93B0 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CEF580514C0E566000A93B0 /* CoreFoundation.framework */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+               0CDF46A714DC79FF00FFE2FD /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 0CC9A7E5146DF66000C18F89 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 0CDF469F14DC794300FFE2FD;
+                       remoteInfo = tlssocket;
+               };
+               0CE08A82148FF628000473EB /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 0CC9A7E5146DF66000C18F89 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 0CC9A7EF146DF66000C18F89;
+                       remoteInfo = tlsnke;
+               };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+               0CE08A71148FF2C6000473EB /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 2147483647;
+                       dstPath = /usr/share/man/man1/;
+                       dstSubfolderSpec = 0;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+               0C31453A1492D4B600427C0B /* tlsnke-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "tlsnke-Info.plist"; sourceTree = "<group>"; };
+               0C38E43C14BF707500DD862C /* tlsnke.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tlsnke.h; sourceTree = "<group>"; };
+               0C6C642515D5A9C200BC68CD /* ssl-utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "ssl-utils.c"; sourceTree = "<group>"; };
+               0C6C642615D5A9C200BC68CD /* ssl-utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ssl-utils.h"; sourceTree = "<group>"; };
+               0C7CF8D614E18A9F00DF9D95 /* dtls_client.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dtls_client.c; sourceTree = "<group>"; };
+               0CA31A4214B7DFAB00BD348C /* tlssocket.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tlssocket.c; path = tlsnketest/tlssocket.c; sourceTree = "<group>"; };
+               0CA31A4514B7DFBA00BD348C /* tlssocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tlssocket.h; path = tlsnketest/tlssocket.h; sourceTree = "<group>"; };
+               0CBE354415C8C340006241C7 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Security.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+               0CBE354615C8C3A5006241C7 /* libsecurity_ssl_kext.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libsecurity_ssl_kext.a; sourceTree = BUILT_PRODUCTS_DIR; };
+               0CC9A7F0146DF66000C18F89 /* tlsnke.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = tlsnke.kext; sourceTree = BUILT_PRODUCTS_DIR; };
+               0CC9A7F4146DF66000C18F89 /* Kernel.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Kernel.framework; path = System/Library/Frameworks/Kernel.framework; sourceTree = SDKROOT; };
+               0CC9A7F9146DF66000C18F89 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+               0CC9A7FB146DF66000C18F89 /* tlsnke.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = tlsnke.c; sourceTree = "<group>"; };
+               0CC9A7FD146DF66000C18F89 /* tlsnke-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "tlsnke-Prefix.pch"; sourceTree = "<group>"; };
+               0CDF468F14DC788000FFE2FD /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+               0CDF46A014DC794300FFE2FD /* libtlssocket.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libtlssocket.a; sourceTree = BUILT_PRODUCTS_DIR; };
+               0CE08A73148FF2C6000473EB /* tlsnketest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = tlsnketest; sourceTree = BUILT_PRODUCTS_DIR; };
+               0CE08A76148FF2C7000473EB /* main.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = "<group>"; };
+               0CEF57FF14C0E227000A93B0 /* st_test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = st_test.c; sourceTree = "<group>"; };
+               0CEF580514C0E566000A93B0 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+               0CC9A7EB146DF66000C18F89 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               0C271D7515C8C80300560531 /* libsecurity_ssl_kext.a in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               0CDF469D14DC794300FFE2FD /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               0CE08A70148FF2C6000473EB /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               0CDF46A614DC79FA00FFE2FD /* libtlssocket.a in Frameworks */,
+                               0CBE354515C8C340006241C7 /* Security.framework in Frameworks */,
+                               0CEF580614C0E566000A93B0 /* CoreFoundation.framework in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+               0C953FB814E4621800077526 /* Libraries */ = {
+                       isa = PBXGroup;
+                       children = (
+                               0CBE354615C8C3A5006241C7 /* libsecurity_ssl_kext.a */,
+                       );
+                       name = Libraries;
+                       sourceTree = "<group>";
+               };
+               0CC9A7E3146DF66000C18F89 = {
+                       isa = PBXGroup;
+                       children = (
+                               0CDF468814DC784200FFE2FD /* tlssocket */,
+                               0CC9A7F5146DF66000C18F89 /* tlsnke */,
+                               0CE08A75148FF2C6000473EB /* tlsnketest */,
+                               0CC9A7F2146DF66000C18F89 /* Frameworks */,
+                               0C953FB814E4621800077526 /* Libraries */,
+                               0CC9A7F1146DF66000C18F89 /* Products */,
+                       );
+                       sourceTree = "<group>";
+               };
+               0CC9A7F1146DF66000C18F89 /* Products */ = {
+                       isa = PBXGroup;
+                       children = (
+                               0CC9A7F0146DF66000C18F89 /* tlsnke.kext */,
+                               0CE08A73148FF2C6000473EB /* tlsnketest */,
+                               0CDF46A014DC794300FFE2FD /* libtlssocket.a */,
+                       );
+                       name = Products;
+                       sourceTree = "<group>";
+               };
+               0CC9A7F2146DF66000C18F89 /* Frameworks */ = {
+                       isa = PBXGroup;
+                       children = (
+                               0CBE354415C8C340006241C7 /* Security.framework */,
+                               0CEF580514C0E566000A93B0 /* CoreFoundation.framework */,
+                               0CDF468F14DC788000FFE2FD /* Foundation.framework */,
+                               0CC9A7F3146DF66000C18F89 /* Other Frameworks */,
+                       );
+                       name = Frameworks;
+                       sourceTree = "<group>";
+               };
+               0CC9A7F3146DF66000C18F89 /* Other Frameworks */ = {
+                       isa = PBXGroup;
+                       children = (
+                               0CC9A7F4146DF66000C18F89 /* Kernel.framework */,
+                       );
+                       name = "Other Frameworks";
+                       sourceTree = "<group>";
+               };
+               0CC9A7F5146DF66000C18F89 /* tlsnke */ = {
+                       isa = PBXGroup;
+                       children = (
+                               0CC9A7FB146DF66000C18F89 /* tlsnke.c */,
+                               0C38E43C14BF707500DD862C /* tlsnke.h */,
+                               0CC9A7F6146DF66000C18F89 /* Supporting Files */,
+                       );
+                       path = tlsnke;
+                       sourceTree = "<group>";
+               };
+               0CC9A7F6146DF66000C18F89 /* Supporting Files */ = {
+                       isa = PBXGroup;
+                       children = (
+                               0C31453A1492D4B600427C0B /* tlsnke-Info.plist */,
+                               0CC9A7F8146DF66000C18F89 /* InfoPlist.strings */,
+                               0CC9A7FD146DF66000C18F89 /* tlsnke-Prefix.pch */,
+                       );
+                       name = "Supporting Files";
+                       sourceTree = "<group>";
+               };
+               0CDF468814DC784200FFE2FD /* tlssocket */ = {
+                       isa = PBXGroup;
+                       children = (
+                               0CA31A4214B7DFAB00BD348C /* tlssocket.c */,
+                               0CA31A4514B7DFBA00BD348C /* tlssocket.h */,
+                       );
+                       name = tlssocket;
+                       sourceTree = "<group>";
+               };
+               0CE08A75148FF2C6000473EB /* tlsnketest */ = {
+                       isa = PBXGroup;
+                       children = (
+                               0C6C642515D5A9C200BC68CD /* ssl-utils.c */,
+                               0C6C642615D5A9C200BC68CD /* ssl-utils.h */,
+                               0CE08A76148FF2C7000473EB /* main.c */,
+                               0CEF57FF14C0E227000A93B0 /* st_test.c */,
+                               0C7CF8D614E18A9F00DF9D95 /* dtls_client.c */,
+                       );
+                       path = tlsnketest;
+                       sourceTree = "<group>";
+               };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+               0CC9A7EC146DF66000C18F89 /* Headers */ = {
+                       isa = PBXHeadersBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               0C38E43D14BF707500DD862C /* tlsnke.h in Headers */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               0CDF469E14DC794300FFE2FD /* Headers */ = {
+                       isa = PBXHeadersBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               0CDF46A514DC795400FFE2FD /* tlssocket.h in Headers */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+               0CC9A7EF146DF66000C18F89 /* tlsnke */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 0CC9A800146DF66000C18F89 /* Build configuration list for PBXNativeTarget "tlsnke" */;
+                       buildPhases = (
+                               0CC9A7EA146DF66000C18F89 /* Sources */,
+                               0CC9A7EB146DF66000C18F89 /* Frameworks */,
+                               0CC9A7EC146DF66000C18F89 /* Headers */,
+                               0CC9A7ED146DF66000C18F89 /* Resources */,
+                               0CC9A7EE146DF66000C18F89 /* Rez */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = tlsnke;
+                       productName = tlsnke;
+                       productReference = 0CC9A7F0146DF66000C18F89 /* tlsnke.kext */;
+                       productType = "com.apple.product-type.kernel-extension";
+               };
+               0CDF469F14DC794300FFE2FD /* tlssocket */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 0CDF46A114DC794300FFE2FD /* Build configuration list for PBXNativeTarget "tlssocket" */;
+                       buildPhases = (
+                               0CDF469C14DC794300FFE2FD /* Sources */,
+                               0CDF469D14DC794300FFE2FD /* Frameworks */,
+                               0CDF469E14DC794300FFE2FD /* Headers */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = tlssocket;
+                       productName = tlssocket;
+                       productReference = 0CDF46A014DC794300FFE2FD /* libtlssocket.a */;
+                       productType = "com.apple.product-type.library.static";
+               };
+               0CE08A72148FF2C6000473EB /* tlsnketest */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 0CE08A7C148FF2C7000473EB /* Build configuration list for PBXNativeTarget "tlsnketest" */;
+                       buildPhases = (
+                               0CE08A6F148FF2C6000473EB /* Sources */,
+                               0CE08A70148FF2C6000473EB /* Frameworks */,
+                               0CE08A71148FF2C6000473EB /* CopyFiles */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                               0CDF46A814DC79FF00FFE2FD /* PBXTargetDependency */,
+                       );
+                       name = tlsnketest;
+                       productName = tlsnketest;
+                       productReference = 0CE08A73148FF2C6000473EB /* tlsnketest */;
+                       productType = "com.apple.product-type.tool";
+               };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+               0CC9A7E5146DF66000C18F89 /* Project object */ = {
+                       isa = PBXProject;
+                       attributes = {
+                               LastUpgradeCheck = 0430;
+                               ORGANIZATIONNAME = "Apple, Inc.";
+                       };
+                       buildConfigurationList = 0CC9A7E8146DF66000C18F89 /* Build configuration list for PBXProject "tlsnke" */;
+                       compatibilityVersion = "Xcode 3.2";
+                       developmentRegion = English;
+                       hasScannedForEncodings = 0;
+                       knownRegions = (
+                               en,
+                       );
+                       mainGroup = 0CC9A7E3146DF66000C18F89;
+                       productRefGroup = 0CC9A7F1146DF66000C18F89 /* Products */;
+                       projectDirPath = "";
+                       projectRoot = "";
+                       targets = (
+                               0CE08A7E148FF61C000473EB /* host-loadkext */,
+                               0CC9A7EF146DF66000C18F89 /* tlsnke */,
+                               0CE08A72148FF2C6000473EB /* tlsnketest */,
+                               0CDF469F14DC794300FFE2FD /* tlssocket */,
+                       );
+               };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+               0CC9A7ED146DF66000C18F89 /* Resources */ = {
+                       isa = PBXResourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               0CC9A7FA146DF66000C18F89 /* InfoPlist.strings in Resources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXRezBuildPhase section */
+               0CC9A7EE146DF66000C18F89 /* Rez */ = {
+                       isa = PBXRezBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXRezBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+               0CE08A89148FF86C000473EB /* ShellScript */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputPaths = (
+                       );
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "sudo /var/root/loadkext.sh ${BUILT_PRODUCTS_DIR}/tlsnke.kext\n";
+               };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+               0CC9A7EA146DF66000C18F89 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               0CC9A7FC146DF66000C18F89 /* tlsnke.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               0CDF469C14DC794300FFE2FD /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               0CDF46A414DC794F00FFE2FD /* tlssocket.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               0CE08A6F148FF2C6000473EB /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               0CE08A77148FF2C7000473EB /* main.c in Sources */,
+                               0CEF580014C0E227000A93B0 /* st_test.c in Sources */,
+                               0C7CF8D714E18A9F00DF9D95 /* dtls_client.c in Sources */,
+                               0C6C642715D5A9C200BC68CD /* ssl-utils.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+               0CDF46A814DC79FF00FFE2FD /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 0CDF469F14DC794300FFE2FD /* tlssocket */;
+                       targetProxy = 0CDF46A714DC79FF00FFE2FD /* PBXContainerItemProxy */;
+               };
+               0CE08A83148FF628000473EB /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 0CC9A7EF146DF66000C18F89 /* tlsnke */;
+                       targetProxy = 0CE08A82148FF628000473EB /* PBXContainerItemProxy */;
+               };
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+               0CC9A7F8146DF66000C18F89 /* InfoPlist.strings */ = {
+                       isa = PBXVariantGroup;
+                       children = (
+                               0CC9A7F9146DF66000C18F89 /* en */,
+                       );
+                       name = InfoPlist.strings;
+                       sourceTree = "<group>";
+               };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+               0CC9A7FE146DF66000C18F89 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+                               COPY_PHASE_STRIP = NO;
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "DEBUG=1",
+                                       "$(inherited)",
+                               );
+                               GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+                               GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               SUPPORTED_PLATFORMS = "iphoneos macosx";
+                       };
+                       name = Debug;
+               };
+               0CC9A7FF146DF66000C18F89 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+                               COPY_PHASE_STRIP = YES;
+                               DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+                               GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               SUPPORTED_PLATFORMS = "iphoneos macosx";
+                       };
+                       name = Release;
+               };
+               0CC9A801146DF66000C18F89 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               GCC_PRECOMPILE_PREFIX_HEADER = YES;
+                               GCC_PREFIX_HEADER = "tlsnke/tlsnke-Prefix.pch";
+                               HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/../libsecurity_ssl/lib";
+                               INFOPLIST_FILE = "tlsnke/tlsnke-Info.plist";
+                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Extensions";
+                               MODULE_NAME = com.apple.nke.tls;
+                               MODULE_START = tlsnke_start;
+                               MODULE_STOP = tlsnke_stop;
+                               MODULE_VERSION = 1.0;
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               WRAPPER_EXTENSION = kext;
+                       };
+                       name = Debug;
+               };
+               0CC9A802146DF66000C18F89 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               GCC_PRECOMPILE_PREFIX_HEADER = YES;
+                               GCC_PREFIX_HEADER = "tlsnke/tlsnke-Prefix.pch";
+                               HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/../libsecurity_ssl/lib";
+                               INFOPLIST_FILE = "tlsnke/tlsnke-Info.plist";
+                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Extensions";
+                               MODULE_NAME = com.apple.nke.tls;
+                               MODULE_START = tlsnke_start;
+                               MODULE_STOP = tlsnke_stop;
+                               MODULE_VERSION = 1.0;
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               WRAPPER_EXTENSION = kext;
+                       };
+                       name = Release;
+               };
+               0CDF46A214DC794300FFE2FD /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               EXECUTABLE_PREFIX = lib;
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Debug;
+               };
+               0CDF46A314DC794300FFE2FD /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               EXECUTABLE_PREFIX = lib;
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Release;
+               };
+               0CE08A7A148FF2C7000473EB /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               FRAMEWORK_SEARCH_PATHS = "$(inherited)";
+                               HEADER_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)/usr/local/include";
+                               LIBRARY_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       "$(BUILT_PRODUCTS_DIR)",
+                               );
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Debug;
+               };
+               0CE08A7B148FF2C7000473EB /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               FRAMEWORK_SEARCH_PATHS = "$(inherited)";
+                               HEADER_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)/usr/local/include";
+                               LIBRARY_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       "$(BUILT_PRODUCTS_DIR)",
+                               );
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Release;
+               };
+               0CE08A80148FF61C000473EB /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Debug;
+               };
+               0CE08A81148FF61C000473EB /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Release;
+               };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+               0CC9A7E8146DF66000C18F89 /* Build configuration list for PBXProject "tlsnke" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               0CC9A7FE146DF66000C18F89 /* Debug */,
+                               0CC9A7FF146DF66000C18F89 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               0CC9A800146DF66000C18F89 /* Build configuration list for PBXNativeTarget "tlsnke" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               0CC9A801146DF66000C18F89 /* Debug */,
+                               0CC9A802146DF66000C18F89 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               0CDF46A114DC794300FFE2FD /* Build configuration list for PBXNativeTarget "tlssocket" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               0CDF46A214DC794300FFE2FD /* Debug */,
+                               0CDF46A314DC794300FFE2FD /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               0CE08A7C148FF2C7000473EB /* Build configuration list for PBXNativeTarget "tlsnketest" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               0CE08A7A148FF2C7000473EB /* Debug */,
+                               0CE08A7B148FF2C7000473EB /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               0CE08A7F148FF61C000473EB /* Build configuration list for PBXAggregateTarget "host-loadkext" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               0CE08A80148FF61C000473EB /* Debug */,
+                               0CE08A81148FF61C000473EB /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+/* End XCConfigurationList section */
+       };
+       rootObject = 0CC9A7E5146DF66000C18F89 /* Project object */;
+}
diff --git a/tlsnke/tlsnke.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/tlsnke/tlsnke.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644 (file)
index 0000000..4efa47d
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+   version = "1.0">
+   <FileRef
+      location = "self:tlsnke.xcodeproj">
+   </FileRef>
+</Workspace>
diff --git a/tlsnke/tlsnke.xcodeproj/xcshareddata/xcschemes/Device.xcscheme b/tlsnke/tlsnke.xcodeproj/xcshareddata/xcschemes/Device.xcscheme
new file mode 100644 (file)
index 0000000..4a68422
--- /dev/null
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "0500"
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "0CC9A7EF146DF66000C18F89"
+               BuildableName = "tlsnke.kext"
+               BlueprintName = "tlsnke"
+               ReferencedContainer = "container:tlsnke.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.GDB"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      buildConfiguration = "Debug">
+      <Testables>
+      </Testables>
+      <MacroExpansion>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "0CE08A72148FF2C6000473EB"
+            BuildableName = "tlsnketest"
+            BlueprintName = "tlsnketest"
+            ReferencedContainer = "container:tlsnke.xcodeproj">
+         </BuildableReference>
+      </MacroExpansion>
+   </TestAction>
+   <LaunchAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Debug"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      allowLocationSimulation = "YES">
+      <BuildableProductRunnable>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "0CE08A72148FF2C6000473EB"
+            BuildableName = "tlsnketest"
+            BlueprintName = "tlsnketest"
+            ReferencedContainer = "container:tlsnke.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+      <AdditionalOptions>
+      </AdditionalOptions>
+   </LaunchAction>
+   <ProfileAction
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Release"
+      debugDocumentVersioning = "YES">
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>
diff --git a/tlsnke/tlsnke.xcodeproj/xcshareddata/xcschemes/Host.xcscheme b/tlsnke/tlsnke.xcodeproj/xcshareddata/xcschemes/Host.xcscheme
new file mode 100644 (file)
index 0000000..66703eb
--- /dev/null
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "0500"
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "0CE08A7E148FF61C000473EB"
+               BuildableName = "host-loadkext"
+               BlueprintName = "host-loadkext"
+               ReferencedContainer = "container:tlsnke.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.GDB"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      buildConfiguration = "Debug">
+      <Testables>
+      </Testables>
+      <MacroExpansion>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "0CE08A72148FF2C6000473EB"
+            BuildableName = "tlsnketest"
+            BlueprintName = "tlsnketest"
+            ReferencedContainer = "container:tlsnke.xcodeproj">
+         </BuildableReference>
+      </MacroExpansion>
+   </TestAction>
+   <LaunchAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.GDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Debug"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      allowLocationSimulation = "YES">
+      <BuildableProductRunnable>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "0CE08A72148FF2C6000473EB"
+            BuildableName = "tlsnketest"
+            BlueprintName = "tlsnketest"
+            ReferencedContainer = "container:tlsnke.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+      <AdditionalOptions>
+      </AdditionalOptions>
+   </LaunchAction>
+   <ProfileAction
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Release"
+      debugDocumentVersioning = "YES">
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>
diff --git a/tlsnke/tlsnke.xcodeproj/xcshareddata/xcschemes/tlsnke.xcscheme b/tlsnke/tlsnke.xcodeproj/xcshareddata/xcschemes/tlsnke.xcscheme
new file mode 100644 (file)
index 0000000..bb35936
--- /dev/null
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "0500"
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "0CC9A7EF146DF66000C18F89"
+               BuildableName = "tlsnke.kext"
+               BlueprintName = "tlsnke"
+               ReferencedContainer = "container:tlsnke.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.GDB"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      buildConfiguration = "Debug">
+      <Testables>
+      </Testables>
+   </TestAction>
+   <LaunchAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.GDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Debug"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      allowLocationSimulation = "YES">
+      <AdditionalOptions>
+      </AdditionalOptions>
+   </LaunchAction>
+   <ProfileAction
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Release"
+      debugDocumentVersioning = "YES">
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>
diff --git a/tlsnke/tlsnke.xcodeproj/xcshareddata/xcschemes/tlsnketest.xcscheme b/tlsnke/tlsnke.xcodeproj/xcshareddata/xcschemes/tlsnketest.xcscheme
new file mode 100644 (file)
index 0000000..1d30b00
--- /dev/null
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "0500"
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "0CE08A72148FF2C6000473EB"
+               BuildableName = "tlsnketest"
+               BlueprintName = "tlsnketest"
+               ReferencedContainer = "container:tlsnke.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.GDB"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      buildConfiguration = "Debug">
+      <Testables>
+      </Testables>
+      <MacroExpansion>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "0CE08A72148FF2C6000473EB"
+            BuildableName = "tlsnketest"
+            BlueprintName = "tlsnketest"
+            ReferencedContainer = "container:tlsnke.xcodeproj">
+         </BuildableReference>
+      </MacroExpansion>
+   </TestAction>
+   <LaunchAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.GDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Debug"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      allowLocationSimulation = "YES">
+      <BuildableProductRunnable>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "0CE08A72148FF2C6000473EB"
+            BuildableName = "tlsnketest"
+            BlueprintName = "tlsnketest"
+            ReferencedContainer = "container:tlsnke.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+      <AdditionalOptions>
+      </AdditionalOptions>
+   </LaunchAction>
+   <ProfileAction
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Release"
+      debugDocumentVersioning = "YES">
+      <BuildableProductRunnable>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "0CE08A72148FF2C6000473EB"
+            BuildableName = "tlsnketest"
+            BlueprintName = "tlsnketest"
+            ReferencedContainer = "container:tlsnke.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>
diff --git a/tlsnke/tlsnke.xcodeproj/xcuserdata/fabrice.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist b/tlsnke/tlsnke.xcodeproj/xcuserdata/fabrice.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist
new file mode 100644 (file)
index 0000000..05301bc
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Bucket
+   type = "1"
+   version = "1.0">
+</Bucket>
diff --git a/tlsnke/tlsnke/en.lproj/InfoPlist.strings b/tlsnke/tlsnke/en.lproj/InfoPlist.strings
new file mode 100644 (file)
index 0000000..477b28f
--- /dev/null
@@ -0,0 +1,2 @@
+/* Localized versions of Info.plist keys */
+
diff --git a/tlsnke/tlsnke/tlsnke-Info.plist b/tlsnke/tlsnke/tlsnke-Info.plist
new file mode 100644 (file)
index 0000000..aa6f997
--- /dev/null
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>English</string>
+       <key>CFBundleExecutable</key>
+       <string>${EXECUTABLE_NAME}</string>
+       <key>CFBundleIconFile</key>
+       <string></string>
+       <key>CFBundleIdentifier</key>
+       <string>com.apple.nke.tls</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundleName</key>
+       <string>${PRODUCT_NAME}</string>
+       <key>CFBundlePackageType</key>
+       <string>KEXT</string>
+       <key>CFBundleShortVersionString</key>
+       <string>1.0</string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>1</string>
+       <key>NSHumanReadableCopyright</key>
+       <string>Copyright ©  2011  Apple Inc. All rights reserved.</string>
+       <key>OSBundleLibraries</key>
+       <dict>
+               <key>com.apple.kec.corecrypto</key>
+               <string>1.0</string>
+               <key>com.apple.kpi.unsupported</key>
+               <string>13.0</string>
+               <key>com.apple.kpi.mach</key>
+               <string>13.0</string>
+               <key>com.apple.kpi.iokit</key>
+               <string>13.0</string>
+               <key>com.apple.kpi.bsd</key>
+               <string>13.0</string>
+               <key>com.apple.kpi.private</key>
+               <string>13.0</string>
+               <key>com.apple.kpi.libkern</key>
+               <string>13.0</string>
+       </dict>
+       <key>IOKitPersonalities</key>
+       <dict/>
+</dict>
+</plist>
diff --git a/tlsnke/tlsnke/tlsnke-Prefix.pch b/tlsnke/tlsnke/tlsnke-Prefix.pch
new file mode 100644 (file)
index 0000000..bc4326d
--- /dev/null
@@ -0,0 +1,4 @@
+//
+// Prefix header for all source files of the 'tlsnke' target in the 'tlsnke' project
+//
+
diff --git a/tlsnke/tlsnke/tlsnke.c b/tlsnke/tlsnke/tlsnke.c
new file mode 100644 (file)
index 0000000..2dbab03
--- /dev/null
@@ -0,0 +1,1102 @@
+//
+//  tlsnke.c
+//  tlsnke
+//
+//  Created by Fabrice Gautier on 11/11/11.
+//  Copyright (c) 2011 Apple, Inc. All rights reserved.
+//
+
+#include <mach/mach_types.h>
+#include <sys/kernel_types.h>
+#include <sys/kpi_socket.h>
+#include <sys/kpi_socketfilter.h>
+#include <sys/kpi_mbuf.h>
+#include <sys/malloc.h>
+#include <sys/socketvar.h>
+#include <sys/queue.h>
+#include <sys/mbuf.h>
+#include <sys/param.h>
+
+#include <netinet/in.h>
+
+#include <libkern/libkern.h>
+#include <libkern/OSMalloc.h>
+
+#include <stdint.h>
+
+/* For IOLog */
+#include <IOKit/IOLib.h>
+#include <stdarg.h>
+
+#define DEBUG_ASSERT_COMPONENT_NAME_STRING "tlsnke"
+#define DEBUG_ASSERT_PRODUCTION_CODE 0
+
+#include <AssertMacros.h>
+
+
+#include "SSLRecordInternal.h"
+#include "tlsnke.h"
+
+#include <net/if_utun_crypto_dtls.h>
+
+/*
+ Used a registered creator type here - to register for one - go to the
+ Apple Developer Connection Datatype Registration page
+ <http://developer.apple.com/datatype/>
+ */
+#define MYBUNDLEID             "com.apple.kext.tlsnke"
+
+
+#define TLS_DEBUG 0
+#define TLS_TEST  0  /* To enable the bsd devfs interface for testing the utun code path */
+/* ==================================== */
+
+
+typedef struct dtls_ctx *dtls_ctx_t; /* forward declaration, see below */
+
+
+/* =================================== */
+
+/* global dtls contexts table */
+
+/* TODO: LOCK/UNLOCK global context table */
+
+#define N_DTLS_MAX 1
+static dtls_ctx_t g_dtls_contexts[N_DTLS_MAX];
+
+static void clear_dtls_contexts(void)
+{
+    memset(g_dtls_contexts, 0, sizeof(g_dtls_contexts));
+}
+
+static dtls_ctx_t get_dtls_context(int dtls_handle)
+{
+    if(dtls_handle>=0 && dtls_handle<N_DTLS_MAX) {
+        return g_dtls_contexts[dtls_handle];
+    } else {
+        return NULL;
+    }
+}
+
+static int register_dtls_context(dtls_ctx_t dtls_ref)
+{
+    int i;
+    for(i=0; i<N_DTLS_MAX; i++) {
+        if(g_dtls_contexts[i]==NULL) {
+            g_dtls_contexts[i]=dtls_ref;
+            return i;
+        }
+    }
+    return -1;
+}
+
+static int unregister_dtls_context(dtls_ctx_t dtls_ref)
+{
+    int i;
+    for(i=0; i<N_DTLS_MAX; i++) {
+        if(g_dtls_contexts[i]==dtls_ref) {
+            g_dtls_contexts[i]=NULL;
+            return i;
+        }
+    }
+    return -1;
+}
+
+/* =================================== */
+// MARK:  Utility Functions
+
+/*
+ * Messages to the system log
+ */
+
+static void
+tls_printf(const char *fmt, ...)
+{
+#if TLS_DEBUG
+       va_list listp;
+       char log_buffer[252];
+    
+    log_buffer[250]='\n';
+    log_buffer[251]=0;
+       
+    va_start(listp, fmt);
+    
+       vsnprintf(log_buffer, sizeof(log_buffer)-2, fmt, listp);
+       //printf("%s", log_buffer);
+    IOLog("%s", log_buffer);
+       va_end(listp);
+#endif
+}
+
+static void
+tls_dump(const unsigned char *p, size_t len)
+{
+#if TLS_DEBUG
+    size_t i;
+    for(i=0; i<len; i++) {
+        tls_printf("%02x ", p[i]);
+        if(i%0x1F==0x1F)
+            tls_printf("\n");
+    }
+    tls_printf("\n");
+#endif
+}
+
+
+
+/* =================================== */
+
+static OSMallocTag             gOSMallocTag;   // tag for use with OSMalloc calls which is used to associate memory
+                                        // allocations made with this kext. Preferred to using MALLOC and FREE
+
+
+/* the PktQueueItem record is used to store packet information for queued packets. */
+struct PktQueueItem {
+       STAILQ_ENTRY(PktQueueItem) next; /* link to next queued entry or NULL */
+       mbuf_t                                  data;
+       sflt_data_flag_t                flags;
+};
+
+/* Internal DTLS context for socket filter */
+
+struct dtls_ctx {
+    socket_t socket;    /* socket to which we are attached - may not be needed */
+    bool has_from; 
+    struct sockaddr from; /* from address */
+    bool has_to;
+    struct sockaddr to;   /* to address */
+    struct utun_pcb *utun_ref;     /* utun handle, if bypass is enabled */
+    bool wait_for_key;
+    SSLRecordContextRef ssl_ctx; /* ctx for actual SSL implementation */
+    STAILQ_HEAD(, PktQueueItem) in_queue;
+    size_t in_off;
+#ifdef TLS_TEST
+    bool queue_to_tlsnkedev;      /* for testing only, if true, queue decrypted incoming data
+                                   in the tlsnkedev queue instead of sending to utun or userland */
+#endif
+};
+
+
+/* =================================== */
+
+#if TLS_TEST
+/* Q for incoming data */
+static int tlsnkedev_queue(mbuf_t m);
+#endif
+
+/* Wrappers around utun functions */
+
+/* Send a data packet to utun interface */
+static int utun_data_packet_input(struct utun_pcb *utun_ref, mbuf_t data)
+{
+    tls_printf("tlsnke():%s\n",__FUNCTION__);
+    return utun_pkt_dtls_input(utun_ref, &data, 0);
+}
+
+/* Disable the DTLS bypass in utun - Called by DTLS when socket is clsoed or other error cases */
+static void utun_disable_dtls(struct utun_pcb *utun_ref)
+{
+    tls_printf("tlsnke():%s\n",__FUNCTION__);
+    /* TODO: This is not exported from xnu yet */
+    //utun_ctl_disable_crypto_dtls(utun_ref);
+}
+
+
+/*===== DTLS IO Callbacks =====*/
+// MARK:  DTLS IO Callbacks
+
+static 
+int DTLSIOReadFunc (SSLIOConnectionRef connection, void *data, size_t *dataLength)
+{
+    dtls_ctx_t dtls_ref = connection;
+    struct PktQueueItem *in_q = STAILQ_FIRST(&dtls_ref->in_queue);
+    size_t avail;
+    size_t len = *dataLength;
+    int rc = 0;
+
+    check(dtls_ref);
+    check(data);
+    check(dataLength);
+    
+    if(in_q==NULL) {
+        *dataLength=0;
+        return errSSLRecordWouldBlock;
+    }
+    
+    avail = mbuf_pkthdr_len(in_q->data)-dtls_ref->in_off;
+    
+    tls_printf("tlsnke(%p):%s - avail=%d wants=%d\n", dtls_ref, __FUNCTION__, avail, *dataLength);
+    
+    if(len>avail) {
+        /* Note: This should never happen for DTLS here */
+        check(0);
+        len = avail;
+    }
+    
+    require_noerr_action(mbuf_copydata(in_q->data, dtls_ref->in_off, *dataLength, data), out, rc=errSSLRecordInternal);
+    *dataLength = len;
+
+    //const unsigned char *p=data;
+    //tls_printf("tlsnke(%p):%s - IORead rc=%d, err=%d, len=%d/%d, avail=%d, off=%d, in_q=%p, mbuf=%p\n", dtls_ref, __FUNCTION__,
+    //           rc, err, len, *dataLength, avail, dtls_ref->in_off, in_q, in_q->data);
+    //tls_dump(p, len);
+
+    /* We consumed a full packet, remove it from the queue */
+    if(len==avail) {
+        STAILQ_REMOVE_HEAD(&dtls_ref->in_queue, next);
+        mbuf_freem(in_q->data);
+        OSFree(in_q, sizeof(struct PktQueueItem), gOSMallocTag);
+        dtls_ref->in_off=0;
+    } else {
+        dtls_ref->in_off += len;
+    }
+    
+out:
+    return rc;
+}
+
+static
+int DTLSIOWriteFunc (SSLIOConnectionRef connection, const void *data, size_t *dataLength)
+{
+    /* Write data callback: */
+    dtls_ctx_t dtls_ref = connection;
+    mbuf_t out_mbuf=NULL;
+
+    check(dtls_ref);
+    
+    //const unsigned char *p=data;
+    //tls_printf("tlsnke(%p):%s - IOWrite len=%d\n", dtls_ref, __FUNCTION__, *dataLength);
+    //tls_dump(p, *dataLength);
+
+    /* create a new data mbuf */
+    require_noerr(mbuf_allocpacket(M_NOWAIT, *dataLength, NULL, &out_mbuf), fail);
+    require(out_mbuf, fail);
+    require_noerr(mbuf_copyback(out_mbuf, 0, *dataLength, data, M_NOWAIT), fail);
+    
+    //tls_printf("tlsnke(%p):%s - inject to=%p mbuf flags=0x%x\n", dtls_ref, __FUNCTION__, dtls_ref->has_to?&dtls_ref->to:NULL, mbuf_flags(out_mbuf));
+
+    /* out_mbuf is freed here in anycase */
+    return sock_inject_data_out(dtls_ref->socket, dtls_ref->has_to?&dtls_ref->to:NULL, out_mbuf, NULL, 0);
+
+fail:
+    /* If we allocated an mbuf, and something failed, we have to free it */
+    if(out_mbuf)
+        mbuf_freem(out_mbuf);
+
+    return errSSLRecordInternal;
+}
+
+static
+dtls_ctx_t dtls_create_context(socket_t so)
+{
+    dtls_ctx_t dtls_ref;
+    
+    dtls_ref = (dtls_ctx_t)OSMalloc(sizeof(struct dtls_ctx), gOSMallocTag);
+    require(dtls_ref, fail);
+    memset(dtls_ref, 0, sizeof(struct dtls_ctx));
+
+    dtls_ref->socket=so;
+    STAILQ_INIT(&dtls_ref->in_queue);
+    dtls_ref->ssl_ctx = SSLCreateInternalRecordLayer(true);
+    require(dtls_ref->ssl_ctx, fail);
+
+    /* Those two functions never fail */
+    SSLSetInternalRecordLayerIOFuncs(dtls_ref->ssl_ctx, DTLSIOReadFunc, DTLSIOWriteFunc);
+    SSLSetInternalRecordLayerConnection(dtls_ref->ssl_ctx, dtls_ref);
+
+    return dtls_ref;
+    
+fail:
+    if(dtls_ref)
+        OSFree(dtls_ref, sizeof(struct dtls_ctx), gOSMallocTag);
+    return NULL;
+}
+
+
+static
+void dtls_free_context(dtls_ctx_t dtls_ref)
+{
+    /* TODO: LOCK this dtls ref */
+
+    /* Disable bridge to utun if enabled */
+    if(dtls_ref->utun_ref) {
+        utun_disable_dtls(dtls_ref->utun_ref);
+    }
+
+    /* TODO: Clear incoming mbuf queue */
+
+    SSLDestroyInternalRecordLayer(dtls_ref->ssl_ctx);
+
+    unregister_dtls_context(dtls_ref);
+
+    OSFree(dtls_ref, sizeof(struct dtls_ctx), gOSMallocTag);
+    /* TODO: UNLOCK */
+}
+
+/* Get the tls_record_hdr from the control mbuf */
+static 
+tls_record_hdr_t dtls_get_header(mbuf_t *control)
+{
+    struct cmsghdr *cm;
+    tls_record_hdr_t hdr;
+
+    if(control==NULL)
+        return NULL;
+    
+    if((*control)==NULL)
+        return NULL;
+
+    /* Needs to be in one mbuf */
+    if (mbuf_next(*control))
+        return NULL;
+    /* Control mbuf needs to be big enough for the tls_record_hdr struct - <rdar://problem/11204421> */
+    if (mbuf_len(*control) < CMSG_LEN(sizeof(struct tls_record_hdr)))
+        return NULL;
+    
+    cm = mbuf_data(*control);
+    
+    if(cm==NULL)
+        return NULL;
+    
+    hdr=(tls_record_hdr_t)CMSG_DATA(cm);
+    
+    return hdr;
+}
+
+
+/* encrypt a dtls record */
+
+
+static
+int dtls_process_output_packet(dtls_ctx_t dtls_ref, mbuf_t data,  tls_record_hdr_t hdr)
+{
+    /* This should be thread safe as this may be called from both
+     the userland socket or from utun -- maybe ? */
+    
+    SSLRecord rec;
+    size_t len = mbuf_pkthdr_len(data);
+    errno_t err;
+    int rc = errSSLRecordInternal;
+    
+    require(len<UINT32_MAX, out);
+    rec.contents.data = OSMalloc((uint32_t)len, gOSMallocTag);
+    rec.contents.length = len;
+    require(rec.contents.data, out);
+
+    rec.contentType = hdr->content_type;
+    rec.protocolVersion = hdr->protocol_version;
+    
+    tls_printf("tlsnke(%p):%s ct=%d, pv=%04x, len=%d\n", dtls_ref, __FUNCTION__, rec.contentType, rec.protocolVersion, len);
+
+    /* ...then the data */
+    err = mbuf_copydata(data, 0, len, rec.contents.data);
+    require_noerr(err, out);
+
+    rc=SSLRecordLayerInternal.write(dtls_ref->ssl_ctx, rec);
+
+out:
+    /* Free the allocated record */
+    if(rec.contents.data)
+        OSFree(rec.contents.data, (uint32_t)len, gOSMallocTag);
+
+    return rc;
+}
+
+
+static void dtls_process_incoming_queue(dtls_ctx_t dtls_ref)
+{
+    /* TODO: LOCK this dtls_ref */
+    SSLRecord rec;
+    struct cmsghdr *cmsg;
+    tls_record_hdr_t hdr;
+    size_t cbuf_len = CMSG_SPACE(sizeof(*hdr));
+    uint8_t *cbuf; //cbuf_len;
+
+    int rc;
+    errno_t err;
+    mbuf_t data;
+    mbuf_t control;
+    struct sockaddr *from;
+
+    tls_printf("tlsnke(%p):%s \n", dtls_ref, __FUNCTION__);
+
+    rc=0;
+    while(rc==0) {
+        rc=SSLRecordLayerInternal.read(dtls_ref->ssl_ctx, &rec);
+        
+        if(rc)
+            break;
+            
+        /* Create a new control mbuf to store the DTLS header */
+        check_noerr(mbuf_get(M_NOWAIT, MBUF_TYPE_CONTROL, &control));
+        check(mbuf_maxlen(control)>=cbuf_len);
+        mbuf_setlen(control, cbuf_len);
+        cbuf = mbuf_data(control);
+
+        cmsg = (struct cmsghdr *)cbuf;
+        cmsg->cmsg_len = CMSG_LEN(sizeof(*hdr));
+        cmsg->cmsg_level = SOL_SOCKET;
+        cmsg->cmsg_type = SCM_TLS_HEADER;
+
+        hdr = (tls_record_hdr_t)CMSG_DATA(cmsg);
+        hdr->content_type = rec.contentType;
+        hdr->protocol_version = rec.protocolVersion;
+        
+        /* create a new data mbuf */
+        check_noerr(mbuf_allocpacket(M_NOWAIT, rec.contents.length, NULL, &data));
+        check_noerr(mbuf_copyback(data, 0, rec.contents.length, rec.contents.data, M_NOWAIT));
+        SSLRecordLayerInternal.free(dtls_ref->ssl_ctx, rec);
+
+        /* We pause processing when getting a change cipher spec */
+        if(hdr->content_type==SSL_RecordTypeChangeCipher) {
+            tls_printf("tlsnke(%p):%s got a ChangeCipher message\n", dtls_ref, __FUNCTION__);
+            dtls_ref->wait_for_key=true;
+        }
+
+        if(dtls_ref->has_from)
+            from=&dtls_ref->from;
+        else
+            from=NULL;
+
+        tls_printf("tlsnke(%p):%s injecting packet d=%p c=%p h=%p, from=%p, flags=0x%x\n", dtls_ref, __FUNCTION__, data, control, hdr, from, mbuf_flags(data));
+
+        err = sock_inject_data_in(dtls_ref->socket, from, data, control, 0);
+
+        check_noerr(err);
+    }
+    
+}
+
+
+
+/* =================================== */
+// MARK: Socket Filter Functions
+
+
+static void
+tls_unregistered_fn(sflt_handle handle)
+{
+    tls_printf("tlsnke:%s\n", __FUNCTION__);
+}
+
+static errno_t
+tls_attach_fn(void **cookie, socket_t so)
+{
+    tls_printf("tlsnke:%s (so=%p)\n", __FUNCTION__, so);
+    
+    dtls_ctx_t dtls_ref;
+    
+    dtls_ref = dtls_create_context(so);
+    
+    *cookie=dtls_ref;
+    
+    if(dtls_ref)
+        return 0;
+    else
+        return -1;
+}
+
+static void    
+tls_detach_fn(void *cookie, socket_t so)
+{
+    dtls_ctx_t dtls_ref = (dtls_ctx_t)cookie;
+    tls_printf("tlsnke(%p):%s\n", cookie, __FUNCTION__);
+
+    /* disconnect from utun if necessary */
+    if(dtls_ref->utun_ref) {
+        utun_disable_dtls(dtls_ref->utun_ref);
+    }
+
+    dtls_free_context(dtls_ref);
+}
+
+static void
+tls_notify_fn(void *cookie, socket_t so, sflt_event_t event, void *param)
+{              
+    tls_printf("tlsnke(%p):%s - so: %p - evt: %d\n", cookie, __FUNCTION__, so, event);
+}
+
+static errno_t 
+tls_data_in_fn(void *cookie, socket_t so, const struct sockaddr *from,
+               mbuf_t *data, mbuf_t *control, sflt_data_flag_t flags)
+{
+    /* TODO: LOCK ? */
+    dtls_ctx_t dtls_ref = (dtls_ctx_t)cookie;
+    struct tls_record_hdr *hdr;
+    errno_t err;
+    
+    tls_printf("tlsnke(%p):%s so=%p, data=%p/l=%d, control=%p/l=%d, from=%p, flags=0x%x\n",
+               cookie, __FUNCTION__, so,
+               data?*data:(void*)-1, (data && *data)?mbuf_pkthdr_len(*data):-1,
+               control?*control:(void*)-1, (control && *control)?mbuf_pkthdr_len(*control):-1,
+               from, flags);
+
+    // If this packet already has a DTLS header, just drop it through */
+    hdr = dtls_get_header(control);
+    
+    if(hdr) {
+        tls_printf("tlsnke(%p):%s This was already processed. hdr=%p\n", cookie, __FUNCTION__, hdr);
+        
+#if TLS_TEST
+        /* if switch enabled and this is a application data packet, send to tlsnkedev Q */
+        if((dtls_ref->queue_to_tlsnkedev) && (hdr->content_type==SSL_RecordTypeAppData)) {
+            /* Q data into tlsnkedev Q */
+            tls_printf("tlsnke(%p):%s Sending packet to tlsnkdev. data=%p\n", cookie, __FUNCTION__, *data);
+            err = tlsnkedev_queue(*data);
+            verify_noerr_action(err, return err);
+            /* no error, lets free the control mbuf... */
+            mbuf_freem(*control);
+            /* ... and swallow */
+            return EJUSTRETURN;
+        }
+#endif
+        /* There should never be a case where we have dtls header and no data, but we test that data is non null anyway */
+
+        /* if switch enabled and this is a application data packet, send to utun */
+        if(data && (dtls_ref->utun_ref) && (hdr->content_type==SSL_RecordTypeAppData)) {
+            /* reinject data into utun */
+            tls_printf("tlsnke(%p):%s Sending packet to utun. data=%p\n", cookie, __FUNCTION__, *data);
+            err = utun_data_packet_input(dtls_ref->utun_ref, *data);
+            verify_noerr_action(err, return err);
+            /* no error, lets free the control mbuf... */
+            mbuf_freem(*control);
+            /* ... and swallow */
+            return EJUSTRETURN;
+        }
+        
+        /* keep the packet moving up in the stack to userland */
+        return 0;
+    }
+    tls_printf("tlsnke(%p):%s Queuing the data %p\n", cookie, __FUNCTION__, data);
+
+    /* Queue the packet */
+    if(data) {
+        struct PktQueueItem    *tlq= (struct PktQueueItem *)OSMalloc(sizeof (struct PktQueueItem), gOSMallocTag);
+    
+        /* If we can't allocate, we return an error, so the socket layer will free that mbuf */
+        verify_action(tlq, return ENOMEM);
+
+        tlq->data = *data;
+
+        STAILQ_INSERT_TAIL(&dtls_ref->in_queue, tlq, next);    
+    }
+    
+    if(from) {
+        dtls_ref->has_from=true;
+        memcpy(&dtls_ref->from, from, sizeof(struct sockaddr));
+    } else {
+        dtls_ref->has_from=false;
+    }
+
+    /* If we are waiting for userland, just return */
+    if(dtls_ref->wait_for_key) {
+        tls_printf("tlsnke(%p):%s holding the Q\n", cookie, __FUNCTION__);
+    } else {
+        /* Process incoming queue */
+        dtls_process_incoming_queue(dtls_ref);
+    }
+    
+    return EJUSTRETURN;
+}
+
+static errno_t 
+tls_data_out_fn(void *cookie, socket_t so, const struct sockaddr *to, mbuf_t *data,
+                mbuf_t *control, sflt_data_flag_t flags)
+{
+    /* TODO: LOCK ? */
+    errno_t err;
+    dtls_ctx_t dtls_ref = (dtls_ctx_t)cookie;
+    tls_record_hdr_t hdr;
+    
+    tls_printf("tlsnke(%p):%s so=%p, data=%p/l=%d, control=%p/l=%d, to=%p, flags=0x%x\n", cookie, __FUNCTION__, so,
+               data?*data:(void *)-1, (data && *data)?mbuf_pkthdr_len(*data):-1,
+               control?*control:(void *)-1, (control && *control)?mbuf_pkthdr_len(*control):-1, to, flags);
+
+    hdr = dtls_get_header(control);
+    
+    /* It may be possible for a data to be NULL. Never seen it, but this is not documented
+       otherwise, so lets not rely on current behaviour */
+
+    if(hdr && data) {
+        if(to) {
+            dtls_ref->has_to=true;
+            memcpy(&dtls_ref->to, to, sizeof(struct sockaddr));
+        } else {
+            dtls_ref->has_to=false;
+        }
+            
+        err = dtls_process_output_packet(dtls_ref, *data, hdr);
+        verify_noerr_action(err, return err);
+
+        /* We have to free the mbufs only if we have no error */
+        mbuf_freem(*data);
+        mbuf_freem(*control);
+
+        return EJUSTRETURN;
+    } else {
+        /* No TLS header, just send. Dont process this */
+        return 0;
+    }
+}
+
+static errno_t 
+tls_connect_in_fn(void *cookie, socket_t so, const struct sockaddr *from)
+{
+    tls_printf("tlsnke(%p):%s\n", cookie, __FUNCTION__);
+    return 0;
+}
+
+static errno_t 
+tls_connect_out_fn(void *cookie, socket_t so, const struct sockaddr *to)
+{
+    tls_printf("tlsnke(%p):%s\n", cookie, __FUNCTION__);
+    return 0;
+}
+
+static errno_t 
+tls_bind_fn(void *cookie, socket_t so, const struct sockaddr *to)
+{
+    tls_printf("tlsnke(%p):%s\n", cookie, __FUNCTION__);
+    return 0;
+}
+
+static errno_t 
+tls_setoption_fn(void *cookie, socket_t so, sockopt_t opt)
+{
+    /* TODO : LOCK ? */
+    errno_t err;
+    int rc;
+    dtls_ctx_t dtls_ref = (dtls_ctx_t)cookie;
+
+    int level = sockopt_level(opt);
+    int name = sockopt_name(opt);
+    size_t valsize = sockopt_valsize(opt);
+    
+    tls_printf("tlsnke(%p):%s - %x %x %d\n", cookie, __FUNCTION__, level, name, valsize);
+
+    /* We only handle SOL_SOCKET level options */
+    if(level!=SOL_SOCKET)
+        return 0;
+    
+    switch (name) {
+        case SO_TLS_INIT_CIPHER:
+            {
+                uint16_t selectedCipher;
+                bool server;
+                SSLBuffer key;
+                unsigned char *buf;
+                
+                verify_action(valsize>=4, return EINVAL);
+                verify_action(valsize<=4096, return EINVAL);
+            
+                buf=OSMalloc((uint32_t)valsize, gOSMallocTag);
+                
+                verify_action(buf, return ENOMEM);
+                err=sockopt_copyin(opt, buf, valsize);
+                verify_noerr_action(err, return err);
+                    
+                selectedCipher = (buf[0] << 8) | buf[1];
+                server = buf[2];
+                key.length = valsize - 3;
+                key.data = buf + 3;
+
+                tls_printf("tlsnke(%p):%s - Init Ciphers. cipherspec=%04x. server=%d.\n", dtls_ref, __FUNCTION__, selectedCipher, server);
+                rc = SSLRecordLayerInternal.initPendingCiphers(dtls_ref->ssl_ctx, selectedCipher, server, key);
+                tls_printf("tlsnke(%p):%s - Init Ciphers done rc=%d\n", dtls_ref, __FUNCTION__, rc);
+            }
+            break;
+        case SO_TLS_ADVANCE_READ_CIPHER:
+            check(dtls_ref->wait_for_key);
+            rc = SSLRecordLayerInternal.advanceReadCipher(dtls_ref->ssl_ctx);
+            tls_printf("tlsnke(%p):%s - Read Cipher Advanced, process incoming queue now.\n", dtls_ref, __FUNCTION__);
+            dtls_ref->wait_for_key=false;
+            dtls_process_incoming_queue(dtls_ref);
+            break;
+        case SO_TLS_ADVANCE_WRITE_CIPHER:
+            tls_printf("tlsnke(%p):%s - Advancing write cipher.\n", dtls_ref, __FUNCTION__);
+            rc = SSLRecordLayerInternal.advanceWriteCipher(dtls_ref->ssl_ctx);
+            break;
+        case SO_TLS_ROLLBACK_WRITE_CIPHER:
+            tls_printf("tlsnke(%p):%s - Rolling back write cipher.\n", dtls_ref, __FUNCTION__);
+            rc = SSLRecordLayerInternal.rollbackWriteCipher(dtls_ref->ssl_ctx);
+            break;
+        case SO_TLS_PROTOCOL_VERSION:
+            {
+                SSLProtocolVersion pv;
+                verify_action(valsize==sizeof(SSLProtocolVersion), return EINVAL);
+                err=sockopt_copyin(opt, &pv, sizeof(SSLProtocolVersion));
+                verify_noerr_action(err, return err);
+                tls_printf("tlsnke(%p):%s - Setting protocol version %04x\n", dtls_ref, __FUNCTION__, pv);
+                rc = SSLRecordLayerInternal.setProtocolVersion(dtls_ref->ssl_ctx, pv);
+            }
+            break;
+        case SO_TLS_SERVICE_WRITE_QUEUE:
+            tls_printf("tlsnke(%p):%s - Servicing the write Queue.\n", dtls_ref, __FUNCTION__);
+            rc = SSLRecordLayerInternal.serviceWriteQueue(dtls_ref->ssl_ctx);
+            break;
+        default:
+            /* We just ignore other option. We dont normally get any */
+            return 0;
+    }
+    
+    /* Option was a valid filter specific option, return JUSTRETURN
+       or the result from the call */
+    if(rc==0)
+        return EJUSTRETURN;
+    else    
+        return rc;
+}
+
+static errno_t
+tls_getoption_fn(void *cookie, socket_t so, sockopt_t opt)
+{
+    errno_t err;
+    dtls_ctx_t dtls_ref = (dtls_ctx_t)cookie;
+    
+    int level = sockopt_level(opt);
+    int name = sockopt_name(opt);
+    size_t valsize = sockopt_valsize(opt);
+    
+    int handle;
+    
+    if(level!=SOL_SOCKET)
+        return 0;
+    
+    switch (name) {
+        case SO_TLS_HANDLE:
+            handle=register_dtls_context(dtls_ref);
+            verify_action(handle>=0, return EBUSY); /* No space in the global table */
+            verify_action(valsize==sizeof(handle), return EINVAL);
+            err = sockopt_copyout(opt, &handle, valsize);
+            verify_noerr_action(err, return err);
+            tls_printf("tlsnke(%p):%s - get handle : %d\n", cookie, __FUNCTION__, handle);
+            break;
+        default:
+            /* We just ignore other options. Another option we often get is SO_NREAD. */
+            return 0;
+    }
+    
+
+    return EJUSTRETURN;
+}
+
+static errno_t 
+tls_listen_fn(void *cookie, socket_t so)
+{
+    tls_printf("tlsnke(%p):%s\n", cookie, __FUNCTION__);
+
+    return 0;
+}
+
+
+/* Dispatch vector for TCPLogger IPv4 socket functions */
+static struct sflt_filter tls_sflt_filter_ip4 = {
+       TLS_HANDLE_IP4,         /* sflt_handle - use a registered creator type - <http://developer.apple.com/datatype/> */
+       SFLT_PROG,                      /* sf_flags */
+       MYBUNDLEID,                             /* sf_name - cannot be nil else param err results */
+       tls_unregistered_fn,    /* sf_unregistered_func */
+       tls_attach_fn,          /* sf_attach_func - cannot be nil else param err results */                     
+       tls_detach_fn,                  /* sf_detach_func - cannot be nil else param err results */
+       tls_notify_fn,                  /* sf_notify_func */
+       NULL,                                   /* sf_getpeername_func */
+       NULL,                                   /* sf_getsockname_func */
+       tls_data_in_fn,                 /* sf_data_in_func */
+       tls_data_out_fn,                /* sf_data_out_func */
+       tls_connect_in_fn,              /* sf_connect_in_func */
+       tls_connect_out_fn,             /* sf_connect_out_func */
+       tls_bind_fn,                    /* sf_bind_func */
+       tls_setoption_fn,               /* sf_setoption_func */
+       tls_getoption_fn,               /* sf_getoption_func */
+       tls_listen_fn,                  /* sf_listen_func */
+       NULL                                    /* sf_ioctl_func */
+};
+
+
+static caddr_t tls_utun_crypto_kpi_connect_fn(int dtls_handle, struct utun_pcb *utun_ref)
+{
+    dtls_ctx_t dtls_ref;
+
+    tls_printf("tlsnke:%s - handle=%d\n", __FUNCTION__, dtls_handle);
+
+    dtls_ref=get_dtls_context(dtls_handle);
+
+    if(dtls_ref) {
+        dtls_ref->utun_ref = utun_ref;
+    }
+
+    return (caddr_t)dtls_ref;
+}
+
+static errno_t tls_utun_crypto_kpi_send_fn(caddr_t ref, mbuf_t *pkt)
+{
+    dtls_ctx_t dtls_ref = (dtls_ctx_t)ref;
+    mbuf_t control = NULL;
+    struct cmsghdr *cmsg;
+    tls_record_hdr_t hdr;
+    size_t cbuf_len = CMSG_SPACE(sizeof(*hdr));
+    uint8_t cbuf[cbuf_len];
+    errno_t err;
+    int tmp=0;
+
+    check(ref);
+    check(pkt);
+
+    cmsg = (struct cmsghdr *)cbuf;
+    cmsg->cmsg_len = CMSG_LEN(sizeof(*hdr));
+    cmsg->cmsg_level = SOL_SOCKET;
+    cmsg->cmsg_type = SCM_TLS_HEADER;
+
+    hdr = (tls_record_hdr_t) CMSG_DATA(cmsg);
+    hdr->content_type = SSL_RecordTypeAppData;
+    hdr->protocol_version = DTLS_Version_1_0;
+
+    /*
+     Inject the packet that came from utun on top of the socket,
+     the socket filter will see the packet in tls_data_out_fn
+     where we do the decryption
+     TODO: do we need to specify dest address and/or flags ?
+     */
+
+    require_noerr(err=mbuf_allocpacket(M_NOWAIT, cbuf_len, NULL, &control), free_and_fail);
+    require_noerr(err=mbuf_copyback(control, 0, cbuf_len, cbuf, M_NOWAIT), free_and_fail);
+
+    /* TODO: Locking ?? only to get the socket out of the dtls_ref ? */
+    /* sock_inject_data_out will always free the mbufs, so we have a different fail path after that call */
+    require_noerr(err=sock_inject_data_out(dtls_ref->socket, NULL, *pkt, control, 0), just_fail);
+
+    require_noerr(err=sock_setsockopt(dtls_ref->socket, SOL_SOCKET, SO_TLS_SERVICE_WRITE_QUEUE, &tmp, 0), just_fail);
+
+/* Fail path before calling sock_inject_data_out */
+free_and_fail:
+    if(control)
+        mbuf_freem(control);
+    if(*pkt)
+        mbuf_freem(*pkt);
+
+/* Fail path after calling sock_inject_data_out */
+just_fail:
+    return err;
+}
+
+static struct utun_crypto_kpi_reg tls_utun_crypto_kpi = {
+    /* Dispatch functions */
+    .crypto_kpi_type = UTUN_CRYPTO_TYPE_DTLS,
+    .crypto_kpi_flags = 0,
+    .crypto_kpi_connect = tls_utun_crypto_kpi_connect_fn,
+    .crypto_kpi_send = tls_utun_crypto_kpi_send_fn
+};
+
+
+#if TLS_TEST
+/* BSD interface for testing only */
+#include <sys/conf.h>
+#include <miscfs/devfs/devfs.h>
+#include <sys/uio.h>
+
+/* Queue mbuf to tlsnkdev in Q */
+static STAILQ_HEAD(, PktQueueItem) tlsnkedev_inq;
+static lck_grp_attr_t *tlsnkedev_lock_grp_attr;
+static lck_grp_t *tlsnkedev_lock_grp;
+static lck_attr_t *tlsnkedev_lock_attr;
+static lck_mtx_t *tlsnkedev_lock;
+
+
+static int tlsnkedev_queue(mbuf_t m)
+{
+    struct PktQueueItem        *tlq= (struct PktQueueItem *)OSMalloc(sizeof (struct PktQueueItem), gOSMallocTag);
+
+    tls_printf("tlsnkedev:%s\n", __FUNCTION__);
+
+    /* If we can't allocate, we just drop */
+    verify_action(tlq, return ENOMEM);
+    tlq->data = m;
+
+    lck_mtx_lock(tlsnkedev_lock);
+    STAILQ_INSERT_TAIL(&tlsnkedev_inq, tlq, next);
+    wakeup(&tlsnkedev_inq);
+    lck_mtx_unlock(tlsnkedev_lock);
+
+    return 0;
+}
+
+static int tlsnkedev_open(__unused dev_t dev, int flags, __unused int devtype, __unused struct proc *p)
+{
+    dtls_ctx_t dtls_ref;
+
+    tls_printf("tlsnkedev:%s\n", __FUNCTION__);
+
+    dtls_ref = get_dtls_context(0);
+    dtls_ref->queue_to_tlsnkedev=true;
+
+    /* Reinitialize the Q */
+    STAILQ_INIT(&tlsnkedev_inq);
+
+    tls_printf("tlsnkedev:%s. inq first=%p last=%p\n", __FUNCTION__, tlsnkedev_inq.stqh_first, tlsnkedev_inq.stqh_last);
+
+    return 0;
+}
+
+static int tlsnkedev_close(__unused dev_t dev, __unused int flags, __unused int mode, __unused struct proc *p)
+{
+    dtls_ctx_t dtls_ref;
+
+    tls_printf("tlsnkedev:%s\n", __FUNCTION__);
+
+    dtls_ref = get_dtls_context(0);
+    dtls_ref->queue_to_tlsnkedev=false;
+
+    return 0;
+}
+
+static int tlsnkedev_read(dev_t dev, struct uio *uio, int ioflag)
+{
+    int err=0;
+    int ulen, mlen, amnt;
+    char *buffer=NULL;
+    mbuf_t m;
+    struct PktQueueItem *in_q;
+
+    tls_printf("tlsnkedev:%s\n", __FUNCTION__);
+
+    ulen=uio_resid(uio);
+
+    lck_mtx_lock(tlsnkedev_lock);
+    if(STAILQ_EMPTY(&tlsnkedev_inq)) {
+        msleep(&tlsnkedev_inq, tlsnkedev_lock, 0, __FUNCTION__, NULL);
+    }
+    in_q = STAILQ_FIRST(&tlsnkedev_inq);
+    STAILQ_REMOVE_HEAD(&tlsnkedev_inq, next);
+    lck_mtx_unlock(tlsnkedev_lock);
+
+    tls_printf("tlsnkedev:%s. got %p from inq\n", __FUNCTION__, in_q);
+
+    verify_action(in_q, return EAGAIN); // This should not happen since we are blocking.
+
+    m = in_q->data;
+    verify_action(m, return EFAULT); // we should never queue NULL mbufs
+
+    mlen=mbuf_len(m);
+    check(mlen); // we should never queue empty mbufs, but we can just return a read of 0.
+    check(ulen); // user requested 0 bytes? sure, but this will drop the mbuf.
+
+    amnt = MIN(mlen, ulen);
+
+    buffer=OSMalloc(amnt, gOSMallocTag);
+    verify_action(buffer, return ENOMEM); // We drop the mbuf in that case too.
+
+    require_noerr(err=mbuf_copydata(m, 0, amnt, buffer), out);
+    require_noerr(err=uiomove(buffer, amnt, uio), out);
+
+out:
+    OSFree(in_q, sizeof (struct PktQueueItem), gOSMallocTag);
+    mbuf_freem(m);
+    OSFree(buffer, amnt, gOSMallocTag);
+    return 0;
+}
+
+static int tlsnkedev_write(dev_t dev, struct uio *uio, int ioflag)
+{
+    int err=0;
+    int len;
+    char *buffer=NULL;
+    mbuf_t m=NULL;
+
+    tls_printf("tlsnkedev:%s\n", __FUNCTION__);
+
+    len=uio_resid(uio);
+
+    buffer=OSMalloc(len, gOSMallocTag);
+    verify_action(buffer, return ENOMEM);
+
+    require_noerr(err=uiomove(buffer, len, uio), out);
+    require_noerr(err=mbuf_allocpacket(M_NOWAIT, len, NULL, &m), out);
+    require_noerr(err=mbuf_copyback(m, 0, len, buffer, M_NOWAIT), out);
+
+
+    err=tls_utun_crypto_kpi_send_fn((caddr_t)get_dtls_context(0), &m);
+
+out:
+    OSFree(buffer, len, gOSMallocTag);
+
+    return err;
+}
+
+static struct cdevsw tlsnkedev_cdevsw =
+{
+    tlsnkedev_open,    /* open */
+    tlsnkedev_close,   /* close */
+    tlsnkedev_read,    /* read */
+    tlsnkedev_write,   /* write */
+    eno_ioctl,      /* ioctl */
+    eno_stop,       /* stop */
+    eno_reset,      /* reset */
+    NULL,           /* tty's */
+    eno_select,     /* select */
+    eno_mmap,       /* mmap */
+    eno_strat,      /* strategy */
+    eno_getc,       /* getc */
+    eno_putc,       /* putc */
+    0               /* type */
+};
+
+static void tlsnkedev_devinit(void)
+{
+    int ret;
+
+    ret = cdevsw_add(-1, &tlsnkedev_cdevsw);
+
+    tls_printf("tlsnkedev:%s - major=%d\n", __FUNCTION__, ret);
+
+    devfs_make_node(makedev(ret, 0), DEVFS_CHAR, UID_ROOT, GID_WHEEL, 0666, "tlsnke");
+
+
+    /* allocate lock group attribute and group */
+    tlsnkedev_lock_grp_attr = lck_grp_attr_alloc_init();
+    tlsnkedev_lock_grp =  lck_grp_alloc_init("tlsnkedev_lock", tlsnkedev_lock_grp_attr);
+    /* Allocate lock attribute */
+    tlsnkedev_lock_attr = lck_attr_alloc_init();
+    tlsnkedev_lock = lck_mtx_alloc_init(tlsnkedev_lock_grp, tlsnkedev_lock_attr);
+
+
+}
+#endif /* TLS_TEST */
+
+kern_return_t tlsnke_start(kmod_info_t * ki, void *d);
+kern_return_t tlsnke_stop(kmod_info_t *ki, void *d);
+
+kern_return_t tlsnke_start(kmod_info_t * ki, void *d)
+{
+    kern_return_t retval;
+    
+    tls_printf("tlsnke:%s\n", __FUNCTION__);
+    
+#if TLS_TEST
+    //Init the BSD device
+    tlsnkedev_devinit();
+#endif
+
+    // set up the tag value associated with this NKE in preparation for swallowing packets and re-injecting them
+       gOSMallocTag = OSMalloc_Tagalloc(MYBUNDLEID, OSMT_DEFAULT); // don't want the flag set to OSMT_PAGEABLE since
+                                                                // it would indicate that the memory was pageable.
+       verify_action(gOSMallocTag, return KERN_MEMORY_ERROR);
+    
+    clear_dtls_contexts();
+    
+    retval = utun_ctl_register_dtls(&tls_utun_crypto_kpi);
+    require_noerr(retval, out);
+
+    retval = sflt_register(&tls_sflt_filter_ip4, PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+
+out:
+    return retval;
+}
+
+kern_return_t tlsnke_stop(kmod_info_t *ki, void *d)
+{
+    kern_return_t retval;
+    tls_printf("tlsnke:%s\n", __FUNCTION__);
+    
+    retval = sflt_unregister(TLS_HANDLE_IP4);
+
+    return KERN_SUCCESS;
+}
diff --git a/tlsnke/tlsnke/tlsnke.h b/tlsnke/tlsnke/tlsnke.h
new file mode 100644 (file)
index 0000000..cd4c063
--- /dev/null
@@ -0,0 +1,88 @@
+//
+//  tlsnke.h
+//  tlsnke
+//
+//  Created by Fabrice Gautier on 1/12/12.
+//  Copyright (c) 2012 Apple, Inc. All rights reserved.
+//
+
+#ifndef __TLSNKE_H__
+#define __TLSNKE_H__
+
+/* Those should be defined in kernel headers eg <sys/scoket.h> */
+
+
+#define TLS_HANDLE_IP4 0xBABABABA              /* Temp hack to identify this filter */
+#define TLS_HANDLE_IP6 0xABABABAB              /* Temp hack to identify this filter */
+
+
+/*
+SO_TLS_HANDLE: 
+Get the DTLS handle used to enable utun to dtls bypass. (getsockopt only) 
+option_value type: int
+*/
+#define SO_TLS_HANDLE 0x20000
+
+/*
+SO_TLS_INIT_CIPHER:
+Initialize the new cipher key material. (setsockopt only)
+option_value type: 
+struct {
+    uint16_t cipherspec;
+    bool server;
+    int keylen;
+    char key[keylen];
+} 
+*/
+#define SO_TLS_INIT_CIPHER 0x20001
+
+/*
+SO_TLS_PROTOCOL_VERSION:
+Set the protocol version. (setsockopt only)
+option_value type: int
+*/
+#define SO_TLS_PROTOCOL_VERSION 0x20002
+
+/*
+SO_TLS_ADVANCE_READ_CIPHER:
+Update the read cipher to use the new key. (setsockopt only)
+No option value.
+*/
+#define SO_TLS_ADVANCE_READ_CIPHER 0x20003
+
+/*
+SO_TLS_ADVANCE_WRITE_CIPHER:
+Update the write cipher to use the new key. (setsockopt only)
+No option value.
+*/
+#define SO_TLS_ADVANCE_WRITE_CIPHER 0x20004
+
+/*
+SO_TLS_ROLLBACK_WRITE_CIPHER: 
+Rollback the write cipher to the previous key. (setsockopt only)
+No option value.
+*/
+#define SO_TLS_ROLLBACK_WRITE_CIPHER 0x20005
+
+/*
+ SO_TLS_SERVICE_WRITE_QUEUE:
+ Service the record write queue
+ No option value.
+ */
+#define SO_TLS_SERVICE_WRITE_QUEUE 0x20006
+
+
+/* 
+SCM_TLS_HEADER: 
+ Type of anciallary data for DTLS record header
+*/
+
+#define SCM_TLS_HEADER 0x12345
+
+typedef struct tls_record_hdr{
+    uint8_t content_type;
+    uint16_t protocol_version;
+} *tls_record_hdr_t;
+
+
+#endif /* __TLSNKE_H__ */
diff --git a/tlsnke/tlsnketest/cert-1.h b/tlsnke/tlsnketest/cert-1.h
new file mode 100644 (file)
index 0000000..54bf58f
--- /dev/null
@@ -0,0 +1,66 @@
+unsigned char cert_1_der[] = {
+  0x30, 0x82, 0x02, 0xef, 0x30, 0x82, 0x02, 0x58, 0xa0, 0x03, 0x02, 0x01,
+  0x02, 0x02, 0x09, 0x00, 0x9f, 0xeb, 0x16, 0x7c, 0xc1, 0x64, 0xe6, 0x84,
+  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+  0x05, 0x05, 0x00, 0x30, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+  0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
+  0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49,
+  0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b,
+  0x13, 0x18, 0x43, 0x6f, 0x72, 0x65, 0x4f, 0x53, 0x20, 0x50, 0x6c, 0x61,
+  0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69,
+  0x74, 0x79, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+  0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30, 0x1e,
+  0x17, 0x0d, 0x31, 0x32, 0x30, 0x38, 0x31, 0x30, 0x31, 0x38, 0x30, 0x30,
+  0x31, 0x36, 0x5a, 0x17, 0x0d, 0x32, 0x32, 0x30, 0x38, 0x30, 0x38, 0x31,
+  0x38, 0x30, 0x30, 0x31, 0x36, 0x5a, 0x30, 0x59, 0x31, 0x0b, 0x30, 0x09,
+  0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30,
+  0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c,
+  0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03,
+  0x55, 0x04, 0x0b, 0x13, 0x18, 0x43, 0x6f, 0x72, 0x65, 0x4f, 0x53, 0x20,
+  0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x53, 0x65, 0x63,
+  0x75, 0x72, 0x69, 0x74, 0x79, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55,
+  0x04, 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
+  0x74, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30,
+  0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xbb, 0x2c, 0xef, 0x95, 0x09, 0x80,
+  0xff, 0xca, 0xb1, 0xd3, 0xd1, 0x15, 0xb6, 0x01, 0x15, 0xc1, 0x7c, 0x39,
+  0x81, 0xf6, 0x31, 0x13, 0xf2, 0x46, 0x75, 0xe6, 0xc6, 0xae, 0x2e, 0x68,
+  0x3a, 0xb8, 0x48, 0x70, 0x47, 0xf9, 0x44, 0x5d, 0x6a, 0x0e, 0x37, 0x2f,
+  0x71, 0x1e, 0x54, 0x6c, 0x33, 0x21, 0xe2, 0x2f, 0x0c, 0xd4, 0xfa, 0x88,
+  0x72, 0xad, 0x2b, 0x27, 0x02, 0x7c, 0x48, 0x10, 0x28, 0x18, 0x24, 0x4b,
+  0xf0, 0x87, 0x15, 0xf8, 0xac, 0xb6, 0x69, 0x1c, 0x1c, 0x25, 0xd6, 0xaf,
+  0xb3, 0xc8, 0x60, 0x1a, 0xa4, 0x8a, 0x20, 0xa9, 0x9b, 0x7d, 0x5a, 0xcd,
+  0xea, 0x97, 0x20, 0x45, 0x1a, 0x3b, 0xda, 0xbc, 0x15, 0x30, 0x84, 0x17,
+  0x08, 0xda, 0x50, 0xc0, 0x93, 0xa6, 0xd3, 0x28, 0x06, 0xc5, 0x6a, 0xc3,
+  0x9c, 0x48, 0x53, 0x38, 0x96, 0x8e, 0x33, 0x2f, 0xf9, 0x42, 0xac, 0xf0,
+  0xb1, 0x7f, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xbe, 0x30, 0x81,
+  0xbb, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
+  0x73, 0x7a, 0xcc, 0xf7, 0x1c, 0xf4, 0xc2, 0xa3, 0x95, 0xac, 0x64, 0x48,
+  0xbd, 0x5f, 0x1d, 0x09, 0xa6, 0x8c, 0x91, 0x08, 0x30, 0x81, 0x8b, 0x06,
+  0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0x83, 0x30, 0x81, 0x80, 0x80, 0x14,
+  0x73, 0x7a, 0xcc, 0xf7, 0x1c, 0xf4, 0xc2, 0xa3, 0x95, 0xac, 0x64, 0x48,
+  0xbd, 0x5f, 0x1d, 0x09, 0xa6, 0x8c, 0x91, 0x08, 0xa1, 0x5d, 0xa4, 0x5b,
+  0x30, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+  0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
+  0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+  0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x18, 0x43,
+  0x6f, 0x72, 0x65, 0x4f, 0x53, 0x20, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f,
+  0x72, 0x6d, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x31,
+  0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x09, 0x6c, 0x6f,
+  0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x82, 0x09, 0x00, 0x9f, 0xeb,
+  0x16, 0x7c, 0xc1, 0x64, 0xe6, 0x84, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d,
+  0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,
+  0x81, 0x81, 0x00, 0x4e, 0x9f, 0x0c, 0x99, 0x1b, 0x39, 0xf9, 0xf6, 0xd0,
+  0x3a, 0x16, 0x9b, 0xd9, 0xd1, 0x62, 0xb9, 0x71, 0xb2, 0xf7, 0x9a, 0x61,
+  0x60, 0x5a, 0x0f, 0x16, 0x07, 0xd9, 0x0e, 0x4d, 0xa3, 0x86, 0x7b, 0x18,
+  0xe2, 0xce, 0xa2, 0xbb, 0x44, 0x59, 0x57, 0xe0, 0x32, 0xeb, 0x75, 0x09,
+  0x15, 0xe1, 0xc5, 0x8c, 0x25, 0xfc, 0x04, 0x95, 0xa0, 0x2e, 0x75, 0xab,
+  0x54, 0x8b, 0x86, 0xf2, 0x43, 0x17, 0x79, 0x2f, 0xe8, 0x7f, 0x7c, 0x17,
+  0xaf, 0xf6, 0x91, 0xf7, 0xb0, 0x27, 0x53, 0x61, 0xf9, 0xd9, 0xb7, 0x22,
+  0x71, 0x78, 0x00, 0xfc, 0x8e, 0xc9, 0xd3, 0xb9, 0x5b, 0x09, 0x23, 0xa7,
+  0x92, 0xc5, 0xdc, 0x44, 0xcf, 0x4a, 0x6c, 0x0a, 0xf8, 0xda, 0x5c, 0x7d,
+  0x14, 0x36, 0x48, 0xc1, 0x76, 0xde, 0x6e, 0xde, 0xb6, 0xa0, 0xc6, 0x3a,
+  0x58, 0xd0, 0xc6, 0xfd, 0xe2, 0x32, 0xce, 0x49, 0x15, 0xcb, 0x71
+};
+unsigned int cert_1_der_len = 755;
diff --git a/tlsnke/tlsnketest/dtls_client.c b/tlsnke/tlsnketest/dtls_client.c
new file mode 100644 (file)
index 0000000..1dc76b0
--- /dev/null
@@ -0,0 +1,261 @@
+//
+//  dtls_client.c
+//  tlsnke
+//
+//  Created by Fabrice Gautier on 2/7/12.
+//  Copyright (c) 2012 Apple, Inc. All rights reserved.
+//
+
+/*
+ *  dtlsEchoClient.c
+ *  Security
+ *
+ *  Created by Fabrice Gautier on 1/31/11.
+ *  Copyright 2011 Apple, Inc. All rights reserved.
+ *
+ */
+
+#include <Security/Security.h>
+
+#include "ssl-utils.h"
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h> /* close() */
+#include <string.h> /* memset() */
+#include <fcntl.h>
+#include <time.h>
+
+#include "tlssocket.h"
+
+#define SERVER "10.0.2.1"
+#define PORT 23232
+#define BUFLEN 128
+#define COUNT 10
+
+#if 0
+static void dumppacket(const unsigned char *data, unsigned long len)
+{
+    unsigned long i;
+    for(i=0;i<len;i++)
+    {
+        if((i&0xf)==0) printf("%04lx :",i);
+        printf(" %02x", data[i]);
+        if((i&0xf)==0xf) printf("\n");
+    }
+    printf("\n");
+}
+#endif
+
+
+/* print a '.' every few seconds to keep UI alive while connecting */
+static time_t lastTime = (time_t)0;
+#define TIME_INTERVAL          3
+
+static void sslOutputDot()
+{
+       time_t thisTime = time(0);
+       
+       if((thisTime - lastTime) >= TIME_INTERVAL) {
+               printf("."); fflush(stdout);
+               lastTime = thisTime;
+       }
+}
+
+static void printSslErrStr(
+                    const char         *op,
+                    OSStatus   err)
+{
+       printf("*** %s: %ld\n", op, (long)err);
+}
+
+/* 2K should be enough for everybody */
+#define MTU 2048
+
+
+int dtls_client(const char *hostname, int bypass);
+
+int dtls_client(const char *hostname, int bypass)
+{
+    int fd;
+    int tlsfd;
+    struct sockaddr_in sa;
+    
+    printf("Running dtls_client test with hostname=%s, bypass=%d\n", hostname, bypass);
+
+    if ((fd=socket(AF_INET, SOCK_DGRAM, 0))==-1) {
+        perror("socket");
+        exit(-1);
+    }
+    
+    memset((char *) &sa, 0, sizeof(sa));
+    sa.sin_family = AF_INET;
+    sa.sin_port = htons(PORT);
+    if (inet_aton(hostname, &sa.sin_addr)==0) {
+        fprintf(stderr, "inet_aton() failed\n");
+        exit(1);
+    }
+    
+    if(connect(fd, (struct sockaddr *)&sa, sizeof(sa))==-1)
+    {
+        perror("connect");
+        return errno;
+    }
+    
+    /* Change to non blocking io */
+    fcntl(fd, F_SETFL, O_NONBLOCK);
+    
+    SSLRecordContextRef c=(intptr_t)fd;
+    
+    
+    OSStatus            ortn;
+    SSLContextRef       ctx = NULL;
+    
+    SSLClientCertificateState certState;
+    SSLCipherSuite negCipher;
+    SSLProtocol negVersion;
+    
+       /*
+        * Set up a SecureTransport session.
+        */
+    
+    ctx = SSLCreateContextWithRecordFuncs(kCFAllocatorDefault, kSSLClientSide, kSSLDatagramType, &TLSSocket_Funcs);
+    if(!ctx) {
+        printSslErrStr("SSLCreateContextWithRecordFuncs", -1);
+        return -1;
+    }
+
+    printf("Attaching filter\n");
+    ortn = TLSSocket_Attach(fd);
+    if(ortn) {
+               printSslErrStr("TLSSocket_Attach", ortn);
+               return ortn;        
+    }
+    
+    if(bypass) {
+        tlsfd = open("/dev/tlsnke", O_RDWR);
+        if(tlsfd<0) {
+            perror("opening tlsnke dev");
+            exit(-1);
+        }
+    }
+
+    ortn = SSLSetRecordContext(ctx, c);
+       if(ortn) {
+               printSslErrStr("SSLSetRecordContext", ortn);
+               return ortn;
+       }
+    
+    ortn = SSLSetMaxDatagramRecordSize(ctx, 600);
+    if(ortn) {
+               printSslErrStr("SSLSetMaxDatagramRecordSize", ortn);
+        return ortn;
+       }
+    
+    /* Lets not verify the cert, which is a random test cert */
+    ortn = SSLSetEnableCertVerify(ctx, false);
+    if(ortn) {
+        printSslErrStr("SSLSetEnableCertVerify", ortn);
+        return ortn;
+    }
+    
+    ortn = SSLSetCertificate(ctx, server_chain());
+    if(ortn) {
+        printSslErrStr("SSLSetCertificate", ortn);
+        return ortn;
+    }
+    
+    printf("Handshake...\n");
+
+    do {
+               ortn = SSLHandshake(ctx);
+           if(ortn == errSSLWouldBlock) {
+            /* keep UI responsive */
+            sslOutputDot();
+           }
+    } while (ortn == errSSLWouldBlock);
+    
+    
+    SSLGetClientCertificateState(ctx, &certState);
+       SSLGetNegotiatedCipher(ctx, &negCipher);
+       SSLGetNegotiatedProtocolVersion(ctx, &negVersion);
+    
+    int count;
+    size_t len;
+    ssize_t sreadLen, swriteLen;
+    size_t readLen, writeLen;
+
+    char buffer[BUFLEN];
+    
+    count = 0;
+    while(count<COUNT) {
+        int timeout = 10000;
+        
+        snprintf(buffer, BUFLEN, "Message %d", count);
+        len = strlen(buffer);
+        
+        if(bypass) {
+            /* Send data through the side channel, kind of like utun would */
+            swriteLen=write(tlsfd, buffer, len);
+            if(swriteLen<0) {
+                perror("write to tlsfd");
+                break;
+            }
+            writeLen=swriteLen;
+        } else {
+            ortn=SSLWrite(ctx, buffer, len, &writeLen);
+            if(ortn) {
+                printSslErrStr("SSLWrite", ortn);
+                break;
+            }
+        }
+
+        printf("Wrote %lu bytes\n", writeLen);
+        
+        count++;
+        
+        if(bypass) {
+            do {
+                sreadLen=read(tlsfd, buffer, BUFLEN);
+            } while((sreadLen==-1) && (errno==EAGAIN) && (timeout--));
+            if((sreadLen==-1) && (errno==EAGAIN)) {
+                printf("Read timeout...\n");
+                continue;
+            }
+            if(sreadLen<0) {
+                perror("read from tlsfd");
+                break;
+            }
+            readLen=sreadLen;
+        }
+        else {
+            do {
+                ortn=SSLRead(ctx, buffer, BUFLEN, &readLen);
+            } while((ortn==errSSLWouldBlock) && (timeout--));
+            if(ortn==errSSLWouldBlock) {
+                printf("SSLRead timeout...\n");
+                continue;
+            }
+            if(ortn) {
+                printSslErrStr("SSLRead", ortn);
+                break;
+            }
+        }
+
+        buffer[readLen]=0;
+        printf("Received %lu bytes: %s\n", readLen, buffer);
+        
+    }
+    
+    SSLClose(ctx);
+    
+    SSLDisposeContext(ctx);
+    
+    return ortn;
+}
+
diff --git a/tlsnke/tlsnketest/identity-1.h b/tlsnke/tlsnketest/identity-1.h
new file mode 100644 (file)
index 0000000..21d55d6
--- /dev/null
@@ -0,0 +1,151 @@
+unsigned char identity_1_p12[] = {
+  0x30, 0x82, 0x06, 0xe9, 0x02, 0x01, 0x03, 0x30, 0x82, 0x06, 0xaf, 0x06,
+  0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82,
+  0x06, 0xa0, 0x04, 0x82, 0x06, 0x9c, 0x30, 0x82, 0x06, 0x98, 0x30, 0x82,
+  0x03, 0x97, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07,
+  0x06, 0xa0, 0x82, 0x03, 0x88, 0x30, 0x82, 0x03, 0x84, 0x02, 0x01, 0x00,
+  0x30, 0x82, 0x03, 0x7d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x01, 0x0c, 0x01, 0x06, 0x30, 0x0e, 0x04, 0x08, 0xa1, 0x57, 0x35,
+  0x2d, 0xf3, 0x28, 0xdb, 0xf8, 0x02, 0x02, 0x08, 0x00, 0x80, 0x82, 0x03,
+  0x50, 0xf7, 0xae, 0x62, 0x01, 0x60, 0x8f, 0xa2, 0xda, 0x59, 0xf6, 0x8a,
+  0xc3, 0x46, 0xe7, 0x61, 0x69, 0x10, 0x7a, 0x4f, 0xab, 0x70, 0xf0, 0x73,
+  0xa9, 0x87, 0xba, 0x55, 0xdf, 0x47, 0x0c, 0xc4, 0xdd, 0x2e, 0x4c, 0x86,
+  0xb1, 0x06, 0x65, 0xad, 0xee, 0x2f, 0x7e, 0x8c, 0x5f, 0xbe, 0x7e, 0x46,
+  0x81, 0xa7, 0xe7, 0xa6, 0xca, 0x62, 0x65, 0xcb, 0x05, 0xe3, 0x67, 0x80,
+  0x3f, 0x3d, 0x7d, 0xf5, 0xbd, 0xb6, 0x6e, 0x3a, 0xb5, 0xc1, 0xa2, 0x99,
+  0x16, 0x0b, 0x21, 0x05, 0xf5, 0xc9, 0xde, 0x58, 0x77, 0xe4, 0x96, 0x75,
+  0x37, 0x85, 0x32, 0x2b, 0xed, 0x71, 0x99, 0xf3, 0xbe, 0xa4, 0x6c, 0x53,
+  0xe5, 0xe2, 0xea, 0x70, 0xaa, 0x63, 0x38, 0xa7, 0x5d, 0x4d, 0x8a, 0x39,
+  0xe7, 0xf4, 0xf5, 0xac, 0x43, 0xb1, 0x1f, 0x2b, 0xf6, 0x46, 0xee, 0xb1,
+  0x16, 0x27, 0x0d, 0x59, 0x6b, 0xc5, 0xff, 0xae, 0xb6, 0xfa, 0x76, 0x2b,
+  0x5c, 0x62, 0x9d, 0x19, 0x1c, 0xef, 0x6b, 0x1a, 0x69, 0x98, 0x43, 0x60,
+  0x03, 0x1f, 0x2a, 0x56, 0xe9, 0x26, 0x19, 0x4a, 0xe4, 0x3e, 0xd0, 0x85,
+  0xe4, 0x0d, 0x46, 0x2d, 0xaa, 0x2d, 0x61, 0x68, 0x8d, 0x00, 0xb8, 0xcd,
+  0x8b, 0x9d, 0xdc, 0xa9, 0xa8, 0xe9, 0xf7, 0x93, 0xdf, 0xb3, 0x84, 0x47,
+  0xe5, 0x12, 0xa4, 0xcd, 0x76, 0xd5, 0x28, 0xf4, 0xa9, 0xd5, 0x5e, 0x31,
+  0x94, 0x30, 0x44, 0x58, 0xbb, 0xcc, 0x5a, 0xe8, 0xf6, 0xc0, 0x67, 0x8b,
+  0xf5, 0x66, 0xe1, 0xdb, 0x28, 0x79, 0xf1, 0xa8, 0x78, 0x5a, 0x34, 0x1f,
+  0x3e, 0x2f, 0x57, 0x9d, 0xda, 0xa6, 0xbf, 0x38, 0xb6, 0x7e, 0xd4, 0x07,
+  0x30, 0x03, 0x65, 0xf9, 0xa2, 0xc9, 0xa5, 0x93, 0x2f, 0xc2, 0xf1, 0xbb,
+  0x1a, 0x2d, 0x39, 0xba, 0xa7, 0x47, 0xd3, 0x39, 0x70, 0xe1, 0x36, 0xf8,
+  0xba, 0x62, 0x57, 0x99, 0xf3, 0x38, 0xec, 0x82, 0xe2, 0x46, 0xe2, 0x39,
+  0x7e, 0x71, 0x08, 0x91, 0xbf, 0x8e, 0x5d, 0xf3, 0x31, 0x00, 0xf1, 0xff,
+  0xbf, 0x9e, 0xd6, 0x3b, 0xe6, 0xaa, 0xa0, 0x2c, 0xec, 0x1d, 0x50, 0x2b,
+  0xf3, 0xe0, 0xcd, 0xbd, 0x43, 0x94, 0xa9, 0x91, 0xff, 0x3c, 0x9f, 0xde,
+  0x70, 0x30, 0xc9, 0xee, 0x3f, 0xde, 0x8d, 0x4f, 0x75, 0x89, 0x5b, 0x58,
+  0x43, 0x33, 0x0c, 0x19, 0x85, 0x55, 0xc7, 0x22, 0x9f, 0xa7, 0xf3, 0x83,
+  0x6a, 0x34, 0xca, 0x8e, 0xfc, 0xcb, 0xa0, 0x71, 0x78, 0x59, 0xf4, 0x0b,
+  0x7f, 0xda, 0x2e, 0x21, 0x43, 0x0b, 0x11, 0xbb, 0xd5, 0x85, 0x09, 0xed,
+  0x08, 0x6e, 0x1b, 0x02, 0xb0, 0x1e, 0xf8, 0x45, 0xa0, 0xc4, 0xbb, 0xd4,
+  0xc4, 0x51, 0xb9, 0x16, 0x37, 0xd1, 0xfe, 0xf1, 0xa6, 0x41, 0x94, 0xbc,
+  0xb0, 0xaa, 0xf3, 0x7b, 0x90, 0xa7, 0xa2, 0xac, 0xc1, 0x82, 0xe5, 0x7c,
+  0x18, 0xcd, 0xd1, 0x83, 0x2b, 0xcd, 0x2d, 0x60, 0x5a, 0x48, 0x59, 0x2a,
+  0x27, 0x32, 0x1e, 0x14, 0xe6, 0x5b, 0x44, 0x98, 0xe7, 0xa0, 0x14, 0x22,
+  0x84, 0x52, 0xfa, 0x28, 0x1f, 0x54, 0xc5, 0xfc, 0x75, 0x12, 0x15, 0x9e,
+  0x22, 0xae, 0x12, 0xae, 0x7a, 0x98, 0xc4, 0x99, 0xa7, 0x26, 0x4f, 0xd3,
+  0x96, 0xd6, 0xbf, 0x98, 0x5f, 0x36, 0xf5, 0xd6, 0xee, 0xe8, 0x9a, 0x91,
+  0x8f, 0x23, 0x95, 0xe0, 0xa3, 0x30, 0x38, 0xc9, 0x7c, 0x03, 0xb7, 0x51,
+  0x96, 0x8d, 0x34, 0xbd, 0x4f, 0x10, 0x33, 0xdf, 0x48, 0xb3, 0x4e, 0x74,
+  0x43, 0x01, 0x55, 0x40, 0x85, 0x1a, 0xde, 0xa7, 0x34, 0xf0, 0x5e, 0x02,
+  0xa7, 0x1f, 0x24, 0x6c, 0x89, 0xf5, 0x3b, 0xe6, 0xdf, 0xae, 0xec, 0x06,
+  0x60, 0xe2, 0xfd, 0x1a, 0xa8, 0x03, 0x6c, 0xd8, 0x12, 0xbf, 0x11, 0x50,
+  0xd2, 0x6d, 0x64, 0xa0, 0xdc, 0x46, 0x4a, 0x26, 0x40, 0x80, 0x75, 0xec,
+  0x60, 0xa7, 0xbc, 0x6e, 0x0b, 0xdb, 0x76, 0x71, 0x20, 0xc5, 0x82, 0xfd,
+  0xe6, 0xd0, 0xc8, 0x14, 0x75, 0xf8, 0x3d, 0xd6, 0xd7, 0xe8, 0x46, 0x7f,
+  0x9d, 0x0a, 0xac, 0xa2, 0xfd, 0x32, 0xd9, 0xdc, 0x37, 0x00, 0x1d, 0xb0,
+  0x8e, 0x0b, 0x31, 0xba, 0x97, 0x1e, 0x0b, 0x42, 0x92, 0xe0, 0xaf, 0xe9,
+  0xe5, 0x06, 0xa4, 0xec, 0x3e, 0x97, 0x67, 0x7f, 0x0d, 0xef, 0xea, 0x53,
+  0xc1, 0xd3, 0x79, 0x33, 0xb8, 0xbd, 0x1d, 0x39, 0x33, 0xa2, 0x3d, 0xb0,
+  0x9d, 0xa2, 0x50, 0x85, 0xc9, 0x6e, 0x7e, 0x14, 0x88, 0x66, 0x5b, 0x10,
+  0x85, 0x95, 0xb9, 0xd0, 0x8b, 0xcb, 0xc5, 0x81, 0x0b, 0x16, 0xef, 0x05,
+  0x92, 0x99, 0x23, 0xc6, 0x78, 0xf0, 0x76, 0x30, 0x36, 0xda, 0x8e, 0x7d,
+  0x22, 0xbf, 0x73, 0x25, 0xd4, 0xfc, 0xa4, 0x20, 0xd9, 0x2f, 0x69, 0xa1,
+  0x1f, 0xca, 0xce, 0x28, 0xe8, 0xfd, 0xe0, 0x91, 0xfb, 0xe8, 0x76, 0x7f,
+  0xe2, 0xda, 0xfc, 0x7f, 0xa1, 0xd2, 0xc5, 0xd4, 0xac, 0x38, 0x7a, 0x28,
+  0x6b, 0xd7, 0x78, 0xed, 0xdf, 0xbf, 0xb5, 0xab, 0xa2, 0x2f, 0xa6, 0xdc,
+  0xfb, 0x12, 0x9c, 0xab, 0x89, 0x14, 0x88, 0x7c, 0x75, 0x15, 0x2a, 0x75,
+  0x83, 0x15, 0x89, 0x15, 0x28, 0x40, 0x48, 0xbf, 0x63, 0x81, 0xe2, 0x95,
+  0x65, 0x4d, 0x90, 0xf9, 0xd6, 0xc0, 0x67, 0x5f, 0x0d, 0xb4, 0x0f, 0x5c,
+  0xdb, 0xa9, 0x4f, 0x31, 0xe3, 0x71, 0x2d, 0x16, 0xfa, 0x81, 0x20, 0x45,
+  0xbf, 0xbb, 0xe7, 0x60, 0x0e, 0x59, 0xce, 0x33, 0x22, 0x98, 0x09, 0x3f,
+  0x7b, 0x7c, 0x80, 0x2f, 0xde, 0x5f, 0x6b, 0x51, 0x08, 0xae, 0xe4, 0x07,
+  0xef, 0x42, 0x90, 0x6d, 0xa9, 0x31, 0x7d, 0xe3, 0xaa, 0x55, 0x51, 0x79,
+  0x55, 0x83, 0xb0, 0x8d, 0x8e, 0xab, 0x5a, 0xe2, 0x18, 0xc5, 0x4e, 0x38,
+  0x2c, 0x2c, 0x68, 0x85, 0x7e, 0x55, 0xba, 0x50, 0x17, 0x6a, 0xa0, 0xb8,
+  0x7b, 0x84, 0xd1, 0xad, 0x37, 0xd0, 0x44, 0x92, 0x11, 0xfc, 0x69, 0x5c,
+  0x42, 0x8b, 0xe3, 0x43, 0xba, 0x35, 0x5b, 0x8f, 0xf0, 0xfa, 0xd1, 0xbd,
+  0x70, 0xf5, 0x4d, 0x75, 0x2f, 0x94, 0xc0, 0x77, 0xb3, 0xba, 0x95, 0x64,
+  0x27, 0x03, 0x10, 0x83, 0xc8, 0x2b, 0x01, 0xdf, 0xb7, 0xd3, 0xad, 0x41,
+  0x53, 0x14, 0x9f, 0xe8, 0x5d, 0x84, 0xb0, 0x27, 0x29, 0xb1, 0x99, 0xfe,
+  0x8b, 0xeb, 0x9f, 0xb7, 0x1e, 0x0c, 0xd5, 0x55, 0xa8, 0x30, 0x82, 0x02,
+  0xf9, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01,
+  0xa0, 0x82, 0x02, 0xea, 0x04, 0x82, 0x02, 0xe6, 0x30, 0x82, 0x02, 0xe2,
+  0x30, 0x82, 0x02, 0xde, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+  0x01, 0x0c, 0x0a, 0x01, 0x02, 0xa0, 0x82, 0x02, 0xa6, 0x30, 0x82, 0x02,
+  0xa2, 0x30, 0x1c, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x0c, 0x01, 0x03, 0x30, 0x0e, 0x04, 0x08, 0xd4, 0xf3, 0x35, 0x1a, 0xbd,
+  0x5e, 0xcd, 0x9f, 0x02, 0x02, 0x08, 0x00, 0x04, 0x82, 0x02, 0x80, 0xe4,
+  0x9c, 0x93, 0xc2, 0x8b, 0x15, 0xb0, 0xfd, 0x41, 0x40, 0x8f, 0xe2, 0x32,
+  0xd6, 0x46, 0x3b, 0x89, 0x3d, 0xed, 0xfa, 0x3f, 0x31, 0xa6, 0xf0, 0x5f,
+  0x42, 0x63, 0x57, 0xaf, 0x3c, 0xf0, 0x1f, 0x28, 0x2e, 0x8e, 0x0f, 0x6e,
+  0x98, 0x9a, 0xf2, 0x2c, 0x9f, 0x05, 0x87, 0xf9, 0xd1, 0x32, 0xf3, 0x1d,
+  0xc1, 0x6d, 0x24, 0xd2, 0x33, 0x67, 0x38, 0x1b, 0x5a, 0x9e, 0x92, 0x01,
+  0xcb, 0x2b, 0x4b, 0x0e, 0x94, 0x63, 0xf7, 0xd9, 0x42, 0xc7, 0x08, 0xcc,
+  0x2e, 0xe0, 0xee, 0x89, 0xe2, 0xaf, 0x56, 0xe3, 0x64, 0x22, 0xb0, 0xdf,
+  0x7d, 0x5a, 0x71, 0xd5, 0x8e, 0xc2, 0xac, 0xc5, 0x70, 0x7f, 0x24, 0x2c,
+  0x2f, 0x61, 0x1a, 0xa1, 0x55, 0xec, 0x53, 0x16, 0xd6, 0xb7, 0xfb, 0xfd,
+  0x61, 0x89, 0xdc, 0x4c, 0xe3, 0x62, 0xe9, 0xc4, 0x41, 0x80, 0xe6, 0xf1,
+  0x25, 0xd6, 0x16, 0xd9, 0xe9, 0x6a, 0x7c, 0x9c, 0xf4, 0xae, 0xa5, 0x26,
+  0xbd, 0x4f, 0x8d, 0x2b, 0x14, 0x7e, 0xe0, 0xc0, 0x21, 0xe4, 0x94, 0x45,
+  0x66, 0xd4, 0x4e, 0xcc, 0x7e, 0x92, 0xe3, 0xb6, 0xdd, 0x25, 0x0b, 0x61,
+  0x27, 0x1f, 0x06, 0x51, 0x8d, 0x23, 0xf1, 0x13, 0xe7, 0xb6, 0x42, 0x96,
+  0xc8, 0x6b, 0xb5, 0x5d, 0x8c, 0x7e, 0x5c, 0xbc, 0x6a, 0x6e, 0xc8, 0x7f,
+  0xa0, 0x0f, 0x1b, 0xed, 0x4f, 0x14, 0xd5, 0xa1, 0xf6, 0xe8, 0xb9, 0x51,
+  0xd4, 0x02, 0x3c, 0xdd, 0xff, 0xca, 0x72, 0x1c, 0x0b, 0xd3, 0x53, 0xa0,
+  0x42, 0x55, 0x00, 0xfa, 0x2d, 0x17, 0x16, 0xd9, 0xe8, 0x2d, 0x2c, 0xad,
+  0xf4, 0x54, 0x14, 0xda, 0x13, 0x1f, 0xb9, 0x16, 0x5e, 0x29, 0x8a, 0xa8,
+  0xee, 0xfd, 0x87, 0xee, 0xa2, 0xe5, 0x6a, 0x86, 0x53, 0x35, 0xb5, 0xa2,
+  0xa0, 0x2e, 0x27, 0x9a, 0x16, 0xb8, 0xa8, 0x8c, 0x92, 0x28, 0xe6, 0x54,
+  0xea, 0xf2, 0x82, 0x7b, 0x4b, 0x8a, 0xa7, 0x5c, 0x25, 0xb8, 0xa7, 0x6d,
+  0x61, 0x02, 0x51, 0xd7, 0xe0, 0xb8, 0x28, 0x88, 0x21, 0xeb, 0x3c, 0x54,
+  0x7a, 0x01, 0x13, 0x76, 0x26, 0x1b, 0x03, 0x2d, 0xec, 0x3d, 0xc3, 0xa9,
+  0x78, 0xf4, 0xd3, 0x27, 0x81, 0x08, 0x5c, 0x70, 0x14, 0x8a, 0x1e, 0xe8,
+  0x0d, 0x89, 0x78, 0x87, 0x97, 0xfe, 0xc1, 0x28, 0x8b, 0xa0, 0xcc, 0xed,
+  0x63, 0xd5, 0x10, 0x01, 0x36, 0xdc, 0xb6, 0xf7, 0x2e, 0x34, 0x9b, 0x45,
+  0x0a, 0x5c, 0x91, 0xb5, 0x3e, 0xb9, 0x47, 0xfe, 0x8f, 0xd6, 0xdb, 0x9c,
+  0xb1, 0x4b, 0xd8, 0xeb, 0xf4, 0x21, 0x96, 0xf1, 0x6b, 0xe3, 0xad, 0xfd,
+  0xa5, 0xce, 0x36, 0xef, 0xc5, 0xe2, 0x33, 0xa1, 0x58, 0x00, 0x4d, 0x9f,
+  0xf7, 0x9e, 0x51, 0x9d, 0x5a, 0xe4, 0x62, 0x15, 0x5e, 0xf9, 0x0e, 0x29,
+  0x9a, 0xf4, 0xdb, 0x10, 0x9a, 0x14, 0x91, 0x74, 0x3c, 0xa1, 0xa7, 0x0e,
+  0x71, 0x2c, 0x36, 0x5c, 0x2f, 0x08, 0x09, 0x66, 0xb5, 0xb3, 0xec, 0x6b,
+  0xe2, 0x58, 0xed, 0x39, 0x90, 0xc2, 0x54, 0xd2, 0xf3, 0x80, 0xe9, 0x4f,
+  0xf2, 0xa0, 0xac, 0x2c, 0xb5, 0x6f, 0x9c, 0x1e, 0x36, 0x80, 0xe8, 0xe2,
+  0x27, 0x29, 0x97, 0x9a, 0x4b, 0xa2, 0xac, 0xac, 0x55, 0x13, 0x6c, 0x86,
+  0x1c, 0x94, 0xb7, 0x20, 0x0d, 0x9c, 0x82, 0x95, 0xcc, 0xb3, 0xbd, 0x84,
+  0x5f, 0x92, 0xcd, 0xe2, 0x98, 0x5b, 0x8e, 0x3a, 0x63, 0x63, 0xe8, 0x40,
+  0xcc, 0xfc, 0x91, 0x71, 0xfd, 0xf1, 0xce, 0x3d, 0xba, 0x62, 0x21, 0x57,
+  0x46, 0x18, 0x8c, 0x7e, 0x60, 0xfb, 0xc4, 0xb8, 0x9e, 0xb0, 0xdd, 0x30,
+  0x90, 0x0f, 0xdd, 0x41, 0x75, 0x68, 0xa4, 0x82, 0xa7, 0xdd, 0xc1, 0x16,
+  0x2e, 0x17, 0x8f, 0x7a, 0xd9, 0xa9, 0xb3, 0xae, 0x1b, 0x0f, 0x99, 0xdc,
+  0xe1, 0x86, 0x76, 0x0c, 0x19, 0xbf, 0x00, 0xc8, 0xda, 0x8c, 0xa0, 0x16,
+  0x29, 0xaf, 0x62, 0x76, 0x7f, 0xe4, 0x8e, 0xd4, 0x10, 0xf2, 0x85, 0x37,
+  0x72, 0x9e, 0xba, 0xd6, 0x45, 0xd9, 0x61, 0x9b, 0xa5, 0xf1, 0x78, 0xab,
+  0x39, 0x67, 0x4d, 0xed, 0xfb, 0x25, 0x25, 0x2f, 0x57, 0xfe, 0xb0, 0xe8,
+  0xd6, 0x88, 0x26, 0xff, 0xe3, 0xbd, 0x55, 0xc8, 0x0f, 0xe8, 0x16, 0x0a,
+  0x7c, 0x25, 0xbd, 0x7f, 0xe0, 0x67, 0xe2, 0x22, 0x06, 0xd8, 0xb2, 0xbb,
+  0xd0, 0x83, 0x05, 0x4d, 0x00, 0x6e, 0xe8, 0x69, 0xd9, 0xc7, 0xec, 0x53,
+  0xfe, 0xc8, 0x73, 0xe1, 0x8e, 0x56, 0xae, 0xe5, 0x75, 0x38, 0xa7, 0x4a,
+  0x90, 0x5a, 0x2b, 0x93, 0xf3, 0x19, 0xf5, 0x90, 0x8a, 0x9a, 0xe3, 0x71,
+  0x93, 0x42, 0xb8, 0xbe, 0x05, 0xb6, 0xbe, 0x25, 0x39, 0xd1, 0x57, 0x37,
+  0x3f, 0x17, 0x9c, 0xa7, 0xf2, 0xf5, 0x9d, 0xed, 0x69, 0x4d, 0x87, 0x1e,
+  0x3e, 0x09, 0xad, 0x31, 0x25, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x09, 0x15, 0x31, 0x16, 0x04, 0x14, 0xe9, 0xac,
+  0x89, 0x1c, 0xee, 0x1d, 0xf8, 0xdd, 0xcb, 0xbc, 0x16, 0x15, 0xbf, 0xa5,
+  0x91, 0xdb, 0x2e, 0x6f, 0x42, 0x5b, 0x30, 0x31, 0x30, 0x21, 0x30, 0x09,
+  0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x24,
+  0xb2, 0x2c, 0x67, 0x3b, 0xe2, 0xee, 0xd9, 0x33, 0xeb, 0x6a, 0x79, 0xb3,
+  0x5c, 0x80, 0x10, 0x8f, 0xff, 0x53, 0x83, 0x04, 0x08, 0x12, 0x28, 0x41,
+  0x03, 0x3a, 0x0f, 0x13, 0xb9, 0x02, 0x02, 0x08, 0x00
+};
+unsigned int identity_1_p12_len = 1773;
diff --git a/tlsnke/tlsnketest/main.c b/tlsnke/tlsnketest/main.c
new file mode 100644 (file)
index 0000000..a27aa69
--- /dev/null
@@ -0,0 +1,279 @@
+//
+//  main.c
+//  tlsnketest
+//
+//  Created by Fabrice Gautier on 12/7/11.
+//  Copyright (c) 2011 Apple, Inc. All rights reserved.
+//
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <unistd.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <net/kext_net.h>
+#include <pthread.h>
+#include <netdb.h>
+#include <fcntl.h>
+
+#include <stdbool.h>
+
+#include <AssertMacros.h>
+#include "tlssocket.h"
+#include "tlsnke.h"
+
+
+static void print_data(const char *s, size_t l, const unsigned char *p)
+{
+    printf("%s, %zu:",s, l);
+    for(int i=0; i<l; i++)
+        printf(" %02x", p[i]);
+    printf("\n");
+}
+
+static void *server_thread_func(void *arg)
+{
+    int sock;
+    struct sockaddr_in server_addr;
+    int err;
+    
+    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
+        perror("server socket");
+        exit(1);
+    }
+    
+    // Dont use TLSSocket_Attach for the server:
+    // TLSSocket_Attach can only open one TLS socket at a time.
+    {
+        struct so_nke so_tlsnke;
+
+        memset(&so_tlsnke, 0, sizeof(so_tlsnke));
+        so_tlsnke.nke_handle = TLS_HANDLE_IP4;
+        err=setsockopt(sock, SOL_SOCKET, SO_NKE, &so_tlsnke, sizeof(so_tlsnke));
+        if(err<0) {
+            perror("attach (server)");
+            exit(err);
+        }
+    }
+    
+    server_addr.sin_family = AF_INET;         
+    server_addr.sin_port = htons(23232);
+    server_addr.sin_addr.s_addr = INADDR_ANY; 
+    bzero(&(server_addr.sin_zero),8); 
+    
+    if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr))
+        == -1) {
+        perror("Unable to bind");
+        exit(1);
+    }
+    
+    printf("\nBound - Server Waiting for client on port 23232\n");
+    fflush(stdout);
+    
+    while (1)
+    {
+        int rc;
+        SSLRecord rec;
+        rc=TLSSocket_Funcs.read((intptr_t)sock, &rec);
+        if(!rc) {
+            print_data("recvd", rec.contents.length, rec.contents.data);
+            rec.contents.data[rec.contents.length-1]=0;
+            printf("recvd: %ld, %s\n", rec.contents.length, rec.contents.data);
+            free(rec.contents.data);
+        } else {
+            printf("read failed: %d\n", rc);
+        }
+    }
+    
+    close(sock);
+    return NULL;
+}
+
+static int create_client_socket(const char *hostname)
+{
+    int sock;
+    int err;
+    
+    
+    printf("Create client socket\n");
+    sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+    if(sock<0) {
+        perror("client socket");
+        return sock;
+    }
+
+    
+#if 1
+    err=TLSSocket_Attach(sock);
+    if(err<0) {
+        perror("TLSSocket_Attach (server)");
+        exit(err);
+    }
+#endif 
+    
+
+    struct hostent *host;
+    struct sockaddr_in server_addr;  
+    
+    //host = gethostbyname("kruk.apple.com");
+    //host = gethostbyname("localhost");
+    host= gethostbyname(hostname);
+    if(!host) {
+        herror("host");
+        return -1;
+    }
+    server_addr.sin_family = AF_INET;     
+    server_addr.sin_port = htons(23232);   
+    server_addr.sin_addr = *((struct in_addr *)host->h_addr);
+    bzero(&(server_addr.sin_zero),8); 
+    
+    err = connect(sock, (struct sockaddr *)&server_addr,
+                  sizeof(struct sockaddr));
+    if(err)
+    {
+        perror("connect");
+        return err;
+    }
+
+    return sock;
+}
+
+/* simple test */
+static int kext_test(const char *hostname, int bypass)
+{ 
+    int sock, i;
+    char send_data[1024];
+    int tlsfd;
+    pthread_t server_thread;
+    
+    if(strcmp(hostname, "localhost")==0) {
+        pthread_create(&server_thread, NULL, server_thread_func, NULL);
+        // Just wait for the server to be setup
+        sleep(1);
+    }
+    
+    
+    sock = create_client_socket(hostname);
+
+    if(bypass) {
+        /* Have to open this after we attached the filter to the client socket */
+        tlsfd=open("/dev/tlsnke", O_RDWR);
+        if(tlsfd<0) {
+            perror("open tlsnke");
+            exit(1);
+        }
+    }
+    
+
+    for(i=0; i<20;i++) {
+        int n;
+        ssize_t err;
+        n=sprintf(send_data, "Message #%d\n", i);
+        if(n<0) {
+            perror("sprintf");
+            exit(1);
+        }
+
+        printf("Client(1) sending %d bytes (\"%s\")\n", n, send_data);
+        
+        if(bypass) {
+            err = write(tlsfd, send_data, n);
+            if(err<0) {
+                perror("write to tlsnke");
+                exit(1);
+            }
+        } else {
+            SSLRecord rec;
+
+            rec.contentType = SSL_RecordTypeAppData;
+            rec.protocolVersion = DTLS_Version_1_0;
+            rec.contents.data = (uint8_t *)send_data;
+            rec.contents.length = n;
+
+            err = TLSSocket_Funcs.write((intptr_t)sock, rec);
+            if(err<0) {
+                perror("write to socket");
+                exit(1);
+            }
+
+            /* serviceWriteQueue every 2 writes, this will trigger rdar://11348395 */
+            if(i&1) {
+                int err;
+                err = TLSSocket_Funcs.serviceWriteQueue((intptr_t)sock);
+                if(err<0) {
+                    perror("service write queue");
+                    exit(1);
+                }
+            }
+        }
+
+        sleep(1);
+    }
+
+    return 0;
+}
+
+
+/* handshake test */
+int st_test();
+
+/* echo test */
+int dtls_client(const char *hostname, int bypass);
+
+static
+int usage(const char *argv0)
+{
+    printf("Usage: %s <test> <hostname> <bypass>\n", argv0);
+    printf("     <test>: type of test: 's'imple, 'h'andshake or 'e'cho] (see below)\n");
+    printf("     <hostname>: hostname of server\n");
+    printf("     <bypass>: use /dev/tlsnke bypass test\n");
+
+    printf("\n    'S'imple test:\n"           
+           "\tVery basic test with no handshake. DTLS packets are sent through the socket filter, non encrypted.\n"
+           "\tIf hostname is 'localhost', a local simple server will be created that will also use the tls filter,\n"
+           "\tsuch that the input path is tested.\n" 
+           "\tOtherwise, a server on the other side is not required only the output path is tested. If there is no server replying\n"
+           "\tonly the ouput path will be tested. If a server is replying, input packet will be processed but are never read to userspace\n"
+           "\tif bypass=1, also send the same packet through the /dev/tlsnke interface, as if they were coming from utun\n");
+
+    printf("\n    'H'andshake:\n");
+    printf("\tTest SSL Handshake with various ciphers, between a local client going through the tlsnke\n"
+           "\tfilter, and a local server using only the userland SecureTransport.\n"
+           "\thostname and bypass are ignored.\n");
+   
+    printf("\n    'E'cho:\n");
+    printf("\tTest to connect to an udp echo server indicated by hostname, on port 23232.\n"
+           "\tSet bypass=1 to use the /dev/tlsnke bsd device to send/recv the app data (emulate utun behaviour)\n");
+    
+    printf("\n\tbypass=1 require the tlsnke kext to be compiled with TLS_TEST=1 (not the default in the build)\n");
+    
+    return -1;
+}
+
+int main (int argc, const char * argv[])
+{
+    
+    printf("argv0=%s argc=%d\n", argv[0], argc);
+    if(argc<2)
+        return usage(argv[0]);
+    
+    switch (argv[1][0]) {
+    case 's':
+    case 'S':
+            if(argc<3) return usage(argv[0]);
+            return kext_test(argv[2], atoi(argv[3])?1:0);
+    case 'h':
+    case 'H':
+            return st_test();
+    case 'e':
+    case 'E':            
+            if(argc<3) return usage(argv[0]);
+            return dtls_client(argv[2], atoi(argv[3])?1:0);
+    default:
+            return usage(argv[0]);
+    }
+}
+
diff --git a/tlsnke/tlsnketest/privkey-1.h b/tlsnke/tlsnketest/privkey-1.h
new file mode 100644 (file)
index 0000000..f39a5a5
--- /dev/null
@@ -0,0 +1,54 @@
+unsigned char privkey_1_der[] = {
+  0x30, 0x82, 0x02, 0x5e, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xbb,
+  0x2c, 0xef, 0x95, 0x09, 0x80, 0xff, 0xca, 0xb1, 0xd3, 0xd1, 0x15, 0xb6,
+  0x01, 0x15, 0xc1, 0x7c, 0x39, 0x81, 0xf6, 0x31, 0x13, 0xf2, 0x46, 0x75,
+  0xe6, 0xc6, 0xae, 0x2e, 0x68, 0x3a, 0xb8, 0x48, 0x70, 0x47, 0xf9, 0x44,
+  0x5d, 0x6a, 0x0e, 0x37, 0x2f, 0x71, 0x1e, 0x54, 0x6c, 0x33, 0x21, 0xe2,
+  0x2f, 0x0c, 0xd4, 0xfa, 0x88, 0x72, 0xad, 0x2b, 0x27, 0x02, 0x7c, 0x48,
+  0x10, 0x28, 0x18, 0x24, 0x4b, 0xf0, 0x87, 0x15, 0xf8, 0xac, 0xb6, 0x69,
+  0x1c, 0x1c, 0x25, 0xd6, 0xaf, 0xb3, 0xc8, 0x60, 0x1a, 0xa4, 0x8a, 0x20,
+  0xa9, 0x9b, 0x7d, 0x5a, 0xcd, 0xea, 0x97, 0x20, 0x45, 0x1a, 0x3b, 0xda,
+  0xbc, 0x15, 0x30, 0x84, 0x17, 0x08, 0xda, 0x50, 0xc0, 0x93, 0xa6, 0xd3,
+  0x28, 0x06, 0xc5, 0x6a, 0xc3, 0x9c, 0x48, 0x53, 0x38, 0x96, 0x8e, 0x33,
+  0x2f, 0xf9, 0x42, 0xac, 0xf0, 0xb1, 0x7f, 0x02, 0x03, 0x01, 0x00, 0x01,
+  0x02, 0x81, 0x81, 0x00, 0xb0, 0x57, 0xb5, 0xa0, 0x84, 0x43, 0xb4, 0xba,
+  0x12, 0xaf, 0xac, 0xdc, 0xf7, 0x8c, 0x2e, 0x23, 0x0c, 0x16, 0x62, 0x0a,
+  0xc0, 0x52, 0x3a, 0x7f, 0x87, 0xb4, 0xd4, 0x9a, 0x65, 0xbe, 0x6d, 0x14,
+  0x11, 0xab, 0x37, 0x23, 0xf0, 0xf4, 0xd1, 0x66, 0x73, 0x37, 0x8f, 0x2b,
+  0x33, 0xfe, 0x7c, 0x6d, 0xff, 0xda, 0xb4, 0x0c, 0x33, 0xbd, 0x39, 0xcd,
+  0x4c, 0x4a, 0x84, 0x5c, 0xf2, 0xc7, 0xc5, 0xfc, 0xdc, 0x03, 0x86, 0x8f,
+  0x2f, 0xac, 0x68, 0x11, 0x86, 0x55, 0x1c, 0x86, 0x51, 0x5d, 0xae, 0x18,
+  0x20, 0x33, 0x9d, 0x12, 0x59, 0x4c, 0x1a, 0xb9, 0x5a, 0x48, 0x89, 0xc4,
+  0x1a, 0x7c, 0x24, 0xf7, 0xff, 0xd6, 0x21, 0xa7, 0x7a, 0x14, 0xe8, 0x8c,
+  0x14, 0x3b, 0x80, 0xee, 0x4b, 0xc1, 0x33, 0x7d, 0x4e, 0x22, 0x23, 0xf7,
+  0xe8, 0x18, 0x0e, 0x24, 0x39, 0x62, 0x48, 0x66, 0x5e, 0x47, 0xa5, 0x81,
+  0x02, 0x41, 0x00, 0xe2, 0x4c, 0x05, 0x28, 0xdf, 0xa7, 0x4a, 0xb7, 0x41,
+  0x1c, 0xff, 0xc2, 0x65, 0x91, 0xa2, 0xd0, 0x0b, 0xe2, 0xf5, 0x32, 0x27,
+  0x3d, 0x14, 0xd5, 0xb2, 0xc2, 0x01, 0x18, 0x05, 0x54, 0x55, 0xb9, 0xd8,
+  0xed, 0xb2, 0x86, 0x69, 0xd6, 0x90, 0x0f, 0x40, 0xe7, 0x8a, 0x70, 0x5e,
+  0x60, 0x7a, 0xf5, 0x81, 0x5a, 0x22, 0x0e, 0x8b, 0x92, 0x5a, 0x43, 0xe7,
+  0xeb, 0xb2, 0x6b, 0x97, 0x6d, 0xee, 0xc5, 0x02, 0x41, 0x00, 0xd3, 0xbe,
+  0x5d, 0xca, 0x62, 0x62, 0x88, 0x48, 0x55, 0x8b, 0x23, 0xb4, 0x62, 0x2c,
+  0xba, 0xb4, 0xbc, 0xb7, 0xdc, 0xb1, 0xc5, 0x27, 0xd9, 0x5b, 0x36, 0xbb,
+  0x8f, 0x39, 0x4c, 0xb1, 0x7b, 0xa6, 0xac, 0x1a, 0xcd, 0x14, 0xca, 0xdc,
+  0x17, 0x45, 0x89, 0x37, 0x37, 0x14, 0x0a, 0x4e, 0xf2, 0x2d, 0xb5, 0x23,
+  0xbf, 0x3e, 0x0a, 0xb7, 0xb9, 0x16, 0x95, 0xcd, 0xda, 0xf0, 0x21, 0xdb,
+  0xa3, 0x73, 0x02, 0x40, 0x0b, 0xf9, 0x91, 0xdc, 0x53, 0xd9, 0x7a, 0x6e,
+  0xb0, 0x17, 0x64, 0xc1, 0x58, 0xb6, 0x98, 0x33, 0x02, 0x2e, 0x04, 0x63,
+  0x9f, 0x07, 0xf0, 0x6e, 0x4e, 0x83, 0x4d, 0xa3, 0x83, 0xc4, 0xae, 0xb4,
+  0xa2, 0xf2, 0x11, 0x1c, 0x63, 0xc5, 0x62, 0xe2, 0x2b, 0xc1, 0x14, 0xe6,
+  0x55, 0x58, 0x2d, 0xa9, 0x88, 0x2a, 0xc8, 0xda, 0x94, 0x30, 0x2e, 0x6e,
+  0xa1, 0x7b, 0x2b, 0x79, 0xde, 0x0d, 0x87, 0x31, 0x02, 0x41, 0x00, 0xbe,
+  0xed, 0x4a, 0x78, 0xf1, 0x19, 0xd3, 0xb5, 0x15, 0x9d, 0x6e, 0xc6, 0x7a,
+  0x37, 0xc6, 0xea, 0xad, 0xb8, 0x44, 0x41, 0xef, 0x7a, 0xad, 0x1c, 0xf8,
+  0x4f, 0x4b, 0x27, 0xe9, 0xa5, 0xa7, 0xcf, 0x74, 0x24, 0x7e, 0x83, 0x9f,
+  0x1f, 0xb1, 0xc4, 0x3b, 0xa4, 0x13, 0xff, 0xf8, 0x03, 0x93, 0x8f, 0xef,
+  0x63, 0x9a, 0x50, 0x01, 0x2e, 0x04, 0xb0, 0xfe, 0xc7, 0x2e, 0x01, 0x95,
+  0x26, 0x0d, 0x4d, 0x02, 0x41, 0x00, 0x84, 0x5d, 0xd1, 0xc6, 0xe9, 0xa2,
+  0x43, 0x94, 0xb4, 0xb9, 0x8b, 0x97, 0xe3, 0x52, 0xf4, 0xf0, 0x05, 0xd2,
+  0x24, 0x6c, 0x92, 0x90, 0xa1, 0x5e, 0xf8, 0xa7, 0xe8, 0x1b, 0xf3, 0x10,
+  0x09, 0xe7, 0xb0, 0xf0, 0xd4, 0xf5, 0x3b, 0x22, 0xd0, 0x2b, 0xa4, 0xdd,
+  0xd3, 0xd0, 0xdb, 0xc2, 0x11, 0xc1, 0x98, 0xff, 0xc6, 0x00, 0xae, 0x44,
+  0x1a, 0x29, 0x0e, 0xcd, 0x92, 0x65, 0x78, 0x6e, 0x6e, 0xb2
+};
+unsigned int privkey_1_der_len = 610;
diff --git a/tlsnke/tlsnketest/ssl-utils.c b/tlsnke/tlsnketest/ssl-utils.c
new file mode 100644 (file)
index 0000000..f2bf9c1
--- /dev/null
@@ -0,0 +1,107 @@
+//
+//  ssl-utils.c
+//  libsecurity_ssl
+//
+//  Created by Fabrice Gautier on 8/7/12.
+//
+//
+
+#include <Security/Security.h>
+#include <AssertMacros.h>
+
+#include "ssl-utils.h"
+
+#if TARGET_OS_IPHONE
+
+
+#include <Security/Security.h>
+#include <Security/SecRSAKey.h>
+#include <Security/SecECKey.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecIdentityPriv.h>
+
+
+#include "privkey-1.h"
+#include "cert-1.h"
+
+static
+CFArrayRef chain_from_der(const unsigned char *cert_der, size_t cert_der_len, const unsigned char *pkey_der, size_t pkey_der_len)
+{
+    SecKeyRef pkey = NULL;
+    SecCertificateRef cert = NULL;
+    SecIdentityRef ident = NULL;
+    CFArrayRef items = NULL;
+
+    require(pkey = SecKeyCreateRSAPrivateKey(kCFAllocatorDefault, pkey_der, pkey_der_len, kSecKeyEncodingPkcs1), errOut);
+    require(cert = SecCertificateCreateWithBytes(kCFAllocatorDefault, cert_der, cert_der_len), errOut);
+    require(ident = SecIdentityCreate(kCFAllocatorDefault, cert, pkey), errOut);
+    require(items = CFArrayCreate(kCFAllocatorDefault, (const void **)&ident, 1, &kCFTypeArrayCallBacks), errOut);
+
+errOut:
+    CFReleaseSafe(pkey);
+    CFReleaseSafe(cert);
+    CFReleaseSafe(ident);
+    return items;
+}
+
+#else
+
+#include "identity-1.h"
+#define P12_PASSWORD "password"
+
+static
+CFArrayRef chain_from_p12(const unsigned char *p12_data, size_t p12_len)
+{
+    char keychain_path[] = "/tmp/keychain.XXXXXX";
+
+    SecKeychainRef keychain;
+    CFArrayRef list;
+    CFDataRef data;
+
+    require_noerr(SecKeychainCopyDomainSearchList(kSecPreferencesDomainUser, &list), errOut);
+    require(mktemp(keychain_path), errOut);
+    require_noerr(SecKeychainCreate (keychain_path, strlen(P12_PASSWORD), P12_PASSWORD,
+                                     FALSE, NULL, &keychain), errOut);
+    require_noerr(SecKeychainSetDomainSearchList(kSecPreferencesDomainUser, list), errOut);    // restores the previous search list
+    require(data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, p12_data, p12_len, kCFAllocatorNull), errOut);
+
+    SecExternalFormat format=kSecFormatPKCS12;
+    SecExternalItemType type=kSecItemTypeAggregate;
+    SecItemImportExportFlags flags=0;
+    SecKeyImportExportParameters params = {0,};
+    CFArrayRef out = NULL;
+
+    params.passphrase=CFSTR("password");
+    params.keyAttributes = CSSM_KEYATTR_PERMANENT | CSSM_KEYATTR_SENSITIVE;
+
+    require_noerr(SecKeychainItemImport(data, CFSTR(".p12"), &format, &type, flags,
+                                        &params, keychain, &out), errOut);
+
+errOut:
+    CFReleaseSafe(keychain);
+    CFReleaseSafe(list);
+
+    return out;
+}
+
+#endif
+
+CFArrayRef server_chain(void)
+{
+#if TARGET_OS_IPHONE
+    return chain_from_der(privkey_1_der, privkey_1_der_len, cert_1_der, cert_1_der_len);
+#else
+    return chain_from_p12(identity_1_p12, identity_1_p12_len);
+#endif
+}
+
+CFArrayRef client_chain(void)
+{
+#if TARGET_OS_IPHONE
+    return chain_from_der(privkey_1_der, privkey_1_der_len, cert_1_der, cert_1_der_len);
+#else
+    return chain_from_p12(identity_1_p12, identity_1_p12_len);
+#endif
+}
+
+
diff --git a/tlsnke/tlsnketest/ssl-utils.h b/tlsnke/tlsnketest/ssl-utils.h
new file mode 100644 (file)
index 0000000..5ac9414
--- /dev/null
@@ -0,0 +1,18 @@
+//
+//  ssl-utils.h
+//  libsecurity_ssl
+//
+//  Created by Fabrice Gautier on 8/7/12.
+//
+//
+
+#ifndef __SSL_UTILS_H__
+#define __SSL_UTILS_H__
+
+#define CFReleaseSafe(CF) { CFTypeRef _cf = (CF); if (_cf) {  CFRelease(_cf); } }
+#define CFReleaseNull(CF) { CFTypeRef _cf = (CF); if (_cf) {  (CF) = NULL; CFRelease(_cf); } }
+
+CFArrayRef server_chain(void);
+CFArrayRef client_chain(void);
+
+#endif
diff --git a/tlsnke/tlsnketest/st_test.c b/tlsnke/tlsnketest/st_test.c
new file mode 100644 (file)
index 0000000..224373f
--- /dev/null
@@ -0,0 +1,743 @@
+//
+//  st_test.c
+//  tlsnke
+//
+//  Created by Fabrice Gautier on 1/13/12.
+//  Copyright (c) 2012 Apple, Inc. All rights reserved.
+//
+
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/Security.h>
+#include <Security/SecureTransportPriv.h> /* SSLSetOption */
+#include <Security/SecRandom.h>
+
+#include <AssertMacros.h>
+
+#include "ssl-utils.h"
+
+#if 0
+#include <Security/SecPolicy.h>
+#include <Security/SecTrust.h>
+#include <Security/SecIdentity.h>
+#include <Security/SecIdentityPriv.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecKeyPriv.h>
+#if TARGET_OS_IPHONE
+#include <Security/SecRSAKey.h>
+#endif
+#include <Security/SecItem.h>
+#include <Security/SecRandom.h>
+#endif
+
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/mman.h>
+#include <mach/mach_time.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#include "tlssocket.h"
+
+/*
+ SSL CipherSuite tests
+
+ Below are all the ciphers that are individually tested.  The first element
+ is the SecureTransport/RFC name; the second is what openssl calls it, which
+ can be looked up in ciphers(1).
+
+ All SSL_DH_* and TLS_DH_* are disabled because neither openssl nor
+ securetranport support them:
+ SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_DH_DSS_WITH_DES_CBC_SHA,
+ SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA, SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
+ SSL_DH_RSA_WITH_DES_CBC_SHA, SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA,
+ TLS_DH_DSS_WITH_AES_128_CBC_SHA, TLS_DH_RSA_WITH_AES_128_CBC_SHA,
+ TLS_DH_DSS_WITH_AES_256_CBC_SHA, TLS_DH_RSA_WITH_AES_256_CBC_SHA,
+
+ DSS is unimplemented by securetransport on the phone:
+ SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA,
+ SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
+ TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
+
+ SSLv2 ciphersuites disabled by securetransport on phone:
+ SSL_RSA_WITH_RC2_CBC_MD5, SSL_RSA_WITH_IDEA_CBC_MD5,
+ SSL_RSA_WITH_DES_CBC_MD5, SSL_RSA_WITH_3DES_EDE_CBC_MD5,
+
+ SSLv3 ciphersuites disabled by securetransport on phone:
+ SSL_RSA_WITH_IDEA_CBC_SHA, SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5
+
+ Export ciphersuites disabled on iOS 5.0:
+ SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA,
+ SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
+ SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DH_anon_EXPORT_WITH_RC4_40_MD5,
+ SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, SSL_DH_anon_WITH_DES_CBC_SHA
+
+ */
+
+typedef struct _CipherSuiteName {
+    SSLCipherSuite cipher;
+    const char *name;
+    bool dh_anonymous;
+} CipherSuiteName;
+
+#define CIPHER(cipher, dh_anonymous) { cipher, #cipher, dh_anonymous },
+
+static const CipherSuiteName ciphers[] = {
+    //SSL_NULL_WITH_NULL_NULL, unsupported
+    CIPHER(SSL_RSA_WITH_NULL_SHA, false)
+    CIPHER(SSL_RSA_WITH_NULL_MD5, false)
+    CIPHER(TLS_RSA_WITH_NULL_SHA256, false)
+
+    //    CIPHER(SSL_RSA_WITH_RC4_128_MD5, false)
+    //CIPHER(SSL_RSA_WITH_RC4_128_SHA, false)
+    CIPHER(SSL_RSA_WITH_3DES_EDE_CBC_SHA, false)
+
+    CIPHER(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, false)
+    //CIPHER(SSL_DH_anon_WITH_RC4_128_MD5, true)
+    CIPHER(SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, true)
+    CIPHER(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, false)
+    CIPHER(TLS_DH_anon_WITH_AES_128_CBC_SHA, true)
+    CIPHER(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, false)
+    CIPHER(TLS_DH_anon_WITH_AES_256_CBC_SHA, true)
+
+    CIPHER(TLS_RSA_WITH_AES_128_CBC_SHA, false)
+    CIPHER(TLS_RSA_WITH_AES_256_CBC_SHA, false)
+
+
+#if 0
+    CIPHER(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, false)
+    CIPHER(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, false)
+
+    CIPHER(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, false)
+    CIPHER(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, false)
+
+    CIPHER(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, false)
+    CIPHER(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, false)
+
+    CIPHER(TLS_ECDH_anon_WITH_AES_128_CBC_SHA, true)
+    CIPHER(TLS_ECDH_anon_WITH_AES_256_CBC_SHA, true)
+
+    CIPHER(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, false)
+    CIPHER(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, false)
+    CIPHER(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, false)
+    CIPHER(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, false)
+#endif
+
+#if 0
+    CIPHER(TLS_RSA_WITH_AES_256_GCM_SHA384, false)
+    CIPHER(TLS_RSA_WITH_AES_128_GCM_SHA256, false)
+#endif
+
+    /* Export ciphers are disabled */
+#if 0
+    CIPHER(SSL_RSA_EXPORT_WITH_RC4_40_MD5, false)
+    CIPHER(SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, false)
+    CIPHER(SSL_RSA_WITH_DES_CBC_SHA,  false)
+    CIPHER(SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,  false)
+    CIPHER(SSL_DHE_RSA_WITH_DES_CBC_SHA, false)
+    CIPHER(SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, true)
+    CIPHER(SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA,  true)
+    CIPHER(SSL_DH_anon_WITH_DES_CBC_SHA, true)
+#endif
+
+    { -1 }
+};
+
+static int protos[]={kTLSProtocol1, kTLSProtocol11, kTLSProtocol12 };
+
+#if 0 // currently unused
+static SSLCipherSuite sslcipher_atoi(const char *name)
+{
+    const CipherSuiteName *a = ciphers;
+    while(a->name) {
+        if (0 == strcmp(a->name, name)) break;
+        a++;
+    }
+    return a->cipher;
+}
+
+static const char * sslcipher_itoa(SSLCipherSuite num)
+{
+    const CipherSuiteName *a = ciphers;
+    while(a->cipher >= 0) {
+        if (num == a->cipher) break;
+        a++;
+    }
+    return a->name;
+}
+#endif // currently unused
+
+static unsigned char dh_param_512_bytes[] = {
+    0x30, 0x46, 0x02, 0x41, 0x00, 0xdb, 0x3c, 0xfa, 0x13, 0xa6, 0xd2, 0x64,
+    0xdf, 0xcc, 0x40, 0xb1, 0x21, 0xd4, 0xf2, 0xad, 0x22, 0x7f, 0xce, 0xa0,
+    0xb9, 0x5b, 0x95, 0x1c, 0x2e, 0x99, 0xb0, 0x27, 0xd0, 0xed, 0xf4, 0xbd,
+    0xbb, 0x36, 0x93, 0xd0, 0x9d, 0x2b, 0x32, 0xa3, 0x56, 0x53, 0xe3, 0x7b,
+    0xed, 0xa1, 0x71, 0x82, 0x2e, 0x83, 0x14, 0xf9, 0xc0, 0x2f, 0x15, 0xcb,
+    0xcf, 0x97, 0xab, 0x88, 0x49, 0x20, 0x28, 0x2e, 0x63, 0x02, 0x01, 0x02
+};
+static unsigned char *dh_param_512_der = dh_param_512_bytes;
+static unsigned int dh_param_512_der_len = 72;
+
+
+typedef struct {
+    uint32_t session_id;
+    bool is_session_resume;
+    SSLContextRef st;
+    bool is_server;
+    bool is_dtls;
+    bool client_side_auth;
+    bool dh_anonymous;
+    int comm;
+    CFArrayRef certs;
+    SSLProtocol proto;
+} ssl_test_handle;
+
+
+// MARK: -
+// MARK: SecureTransport support
+
+#if 0
+static void hexdump(const uint8_t *bytes, size_t len) {
+       size_t ix;
+    printf("socket write(%p, %lu)\n", bytes, len);
+       for (ix = 0; ix < len; ++ix) {
+        if (!(ix % 16))
+            printf("\n");
+               printf("%02X ", bytes[ix]);
+       }
+       printf("\n");
+}
+#else
+#define hexdump(bytes, len)
+#endif
+
+
+/* 2K should be enough for everybody */
+#define MTU 8000
+static unsigned char readBuffer[MTU];
+static unsigned int  readOff=0;
+static size_t        readLeft=0;
+
+static
+OSStatus SocketRead(
+                    SSLConnectionRef   connection,
+                    void                               *data,
+                    size_t                             *dataLength)
+{
+    int fd = (int)connection;
+    ssize_t len;
+
+    if(readLeft==0)
+    {
+        // printf("SocketRead(%d): waiting for data %ld\n", fd, *dataLength);
+
+        len = read(fd, readBuffer, MTU);
+
+        if(len>0) {
+            readOff=0;
+            readLeft=(size_t) len;
+            //printf("SocketRead(%d): %ld bytes... epoch: %02x seq=%02x%02x\n",
+            //       fd, len, d[4], d[9], d[10]);
+
+        } else {
+            int theErr = errno;
+            switch(theErr) {
+                case EAGAIN:
+                    printf("SocketRead(%d): WouldBlock\n", fd);
+                    *dataLength=0;
+                    /* nonblocking, no data */
+                    return errSSLWouldBlock;
+                default:
+                    perror("SocketRead");
+                    return -36;
+            }
+        }
+    }
+
+    if(readLeft<*dataLength) {
+        *dataLength=readLeft;
+    }
+
+
+    memcpy(data, readBuffer+readOff, *dataLength);
+    readLeft-=*dataLength;
+    readOff+=*dataLength;
+
+    // printf("%s: returning %ld bytes, left %ld\n", __FUNCTION__, *dataLength, readLeft);
+
+    return errSecSuccess;
+
+}
+
+static
+OSStatus SocketWrite(
+                     SSLConnectionRef   connection,
+                     const void         *data,
+                     size_t                    *dataLength)    /* IN/OUT */
+{
+    int fd = (int)connection;
+    ssize_t len;
+    OSStatus err = errSecSuccess;
+
+#if 0
+    const uint8_t *d=data;
+
+    if((rand()&3)==1) {
+
+        /* drop 1/8th packets */
+        printf("SocketWrite: Drop %ld bytes... epoch: %02x seq=%02x%02x\n",
+               *dataLength, d[4], d[9], d[10]);
+        return errSecSuccess;
+
+    }
+#endif
+
+    // printf("SocketWrite(%d): Sending %ld bytes... epoch: %02x seq=%02x%02x\n",
+    //        fd, *dataLength, d[4], d[9], d[10]);
+
+    len = send(fd, data, *dataLength, 0);
+    if(len>0) {
+        *dataLength=(size_t)len;
+        return err;
+    }
+
+    int theErr = errno;
+    switch(theErr) {
+        case EAGAIN:
+            /* nonblocking, no data */
+            printf("SocketWrite(%d): WouldBlock\n", fd);
+            err = errSSLWouldBlock;
+            break;
+        default:
+            perror("SocketWrite");
+            err = -36;
+            break;
+    }
+
+    return err;
+
+}
+
+
+static unsigned char dn[] = {
+    0x30, 0x5e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+    0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
+    0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+    0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41,
+    0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+    0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
+    0x72, 0x69, 0x74, 0x79, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
+    0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74
+};
+static unsigned int dn_len = 96;
+
+
+static SSLContextRef make_ssl_ref(bool server, bool client_side_auth, bool dh_anonymous,
+                                  bool dtls, int sock, CFArrayRef certs, SSLProtocol proto, bool kernel)
+{
+    SSLContextRef ctx;
+
+    if(kernel) {
+        require(dtls, out);
+        ctx = SSLCreateContextWithRecordFuncs(kCFAllocatorDefault, server?kSSLServerSide:kSSLClientSide, dtls?kSSLDatagramType:kSSLStreamType, &TLSSocket_Funcs);
+        require(ctx, out);
+        printf("Attaching filter\n");
+        require_noerr(TLSSocket_Attach(sock), out);
+        require_noerr(SSLSetRecordContext(ctx, (intptr_t) sock), out);
+    } else {
+        ctx = SSLCreateContext(kCFAllocatorDefault, server?kSSLServerSide:kSSLClientSide, dtls?kSSLDatagramType:kSSLStreamType);
+        require(ctx, out);
+        require_noerr(SSLSetIOFuncs(ctx,
+                                    (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
+        require_noerr(SSLSetConnection(ctx, (intptr_t)sock), out);
+    }
+    require(ctx, out);
+
+    if(dtls) {
+        size_t mtu;
+        require_noerr(SSLSetMaxDatagramRecordSize(ctx, 400), out);
+        require_noerr(SSLGetMaxDatagramRecordSize(ctx, &mtu), out);
+    } else {
+        require_noerr(SSLSetProtocolVersionMax(ctx, proto), out);
+        kernel = false; // not available for tls, only dtls currently.
+    }
+
+    static const char *peer_domain_name = "localhost";
+    require_noerr(SSLSetPeerDomainName(ctx, peer_domain_name,
+                                       strlen(peer_domain_name)), out);
+
+    if (!dh_anonymous) {
+        if (server)
+            require_noerr(SSLSetCertificate(ctx, certs), out);
+        if (client_side_auth && server) {
+            SSLAuthenticate auth;
+            require_noerr(SSLSetClientSideAuthenticate(ctx, kAlwaysAuthenticate), out);
+            require_noerr(SSLGetClientSideAuthenticate(ctx, &auth), out);
+            require(auth==kAlwaysAuthenticate, out);
+            require_noerr(SSLAddDistinguishedName(ctx, dn, dn_len), out);
+        }
+#if 0 /* Setting client certificate in advance */
+        if (client_side_auth && !server)
+            require_noerr(SSLSetCertificate(ctx, certs), out);
+#endif
+        if (client_side_auth && !server) /* enable break from SSLHandshake */
+            require_noerr(SSLSetSessionOption(ctx,
+                                              kSSLSessionOptionBreakOnCertRequested, true), out);
+        require_noerr(SSLSetSessionOption(ctx,
+                                          kSSLSessionOptionBreakOnServerAuth, true), out);
+    }
+
+    /* Tell SecureTransport to not check certs itself: it will break out of the
+     handshake to let us take care of it instead. */
+    require_noerr(SSLSetEnableCertVerify(ctx, false), out);
+
+    if (server) {
+        require_noerr(SSLSetDiffieHellmanParams(ctx,
+                                                 dh_param_512_der, dh_param_512_der_len), out);
+    }
+    else /* if client */ {
+    }
+
+    return ctx;
+out:
+    if (ctx)
+        CFRelease(ctx);
+    return NULL;
+}
+
+static void *securetransport_ssl_thread(void *arg)
+{
+    OSStatus ortn;
+    ssl_test_handle * ssl = (ssl_test_handle *)arg;
+    SSLContextRef ctx = ssl->st;
+    SecTrustRef trust = NULL;
+    bool got_server_auth = false, got_client_cert_req = false;
+
+
+    if(ssl->is_server) {
+        struct sockaddr_in ca; /* client address for connect */
+        ssize_t l;
+        int fd = ssl->comm;
+
+        printf("Server waiting for first packet...\n");
+        /* PEEK only... */
+        socklen_t slen=sizeof(ca);
+        char b;
+        if((l=recvfrom(fd, &b, 1, MSG_PEEK, (struct sockaddr *)&ca, &slen))==-1)
+        {
+            perror("recvfrom");
+            return NULL;
+        }
+
+        printf("Received packet from %s:%d (%ld), connecting...\n", inet_ntoa(ca.sin_addr), ca.sin_port, l);
+
+        if(connect(fd, (struct sockaddr *)&ca, sizeof(ca))==-1)
+        {
+            perror("connect");
+            return NULL;
+        }
+    }
+
+    //uint64_t start = mach_absolute_time();
+    do {
+        ortn = SSLHandshake(ctx);
+
+        if (ortn == errSSLServerAuthCompleted)
+        {
+            require_string(!got_server_auth, out, "second server auth");
+            require_string(!got_client_cert_req, out, "got client cert req before server auth");
+            got_server_auth = true;
+            require_string(!trust, out, "Got errSSLServerAuthCompleted twice?");
+            /* verify peer cert chain */
+            require_noerr(SSLCopyPeerTrust(ctx, &trust), out);
+            SecTrustResultType trust_result = 0;
+            /* this won't verify without setting up a trusted anchor */
+            require_noerr(SecTrustEvaluate(trust, &trust_result), out);
+
+            CFIndex n_certs = SecTrustGetCertificateCount(trust);
+            /*fprintf(stderr, "%ld certs; trust_eval: %d\n", n_certs, trust_result); */
+
+            CFMutableArrayRef peer_cert_array =
+            CFArrayCreateMutable(NULL, n_certs, &kCFTypeArrayCallBacks);
+            CFMutableArrayRef orig_peer_cert_array =
+            CFArrayCreateMutableCopy(NULL, n_certs, ssl->certs);
+            while (n_certs--)
+                CFArrayInsertValueAtIndex(peer_cert_array, 0,
+                                          SecTrustGetCertificateAtIndex(trust, n_certs));
+
+            SecIdentityRef ident =
+            (SecIdentityRef)CFArrayGetValueAtIndex(orig_peer_cert_array, 0);
+            SecCertificateRef peer_cert = NULL;
+            require_noerr(SecIdentityCopyCertificate(ident, &peer_cert), out);
+            CFArraySetValueAtIndex(orig_peer_cert_array, 0, peer_cert);
+            CFRelease(peer_cert);
+
+            require(CFEqual(orig_peer_cert_array, peer_cert_array), out);
+            CFRelease(orig_peer_cert_array);
+            CFRelease(peer_cert_array);
+
+            /*
+             CFStringRef cert_name = SecCertificateCopySubjectSummary(cert);
+             char cert_name_buffer[1024];
+             require(CFStringGetFileSystemRepresentation(cert_name,
+             cert_name_buffer, sizeof(cert_name_buffer)), out);
+             fprintf(stderr, "cert name: %s\n", cert_name_buffer);
+             CFRelease(trust);
+             */
+        } else if (ortn == errSSLClientCertRequested) {
+            require_string(!got_client_cert_req, out, "second client cert req");
+            require_string(got_server_auth, out, "didn't get server auth first");
+            got_client_cert_req = true;
+
+            /* set client cert */
+            require_string(!ssl->is_server, out, "errSSLClientCertRequested while running server");
+            require_string(!ssl->dh_anonymous, out, "errSSLClientCertRequested while running anon DH");
+
+            CFArrayRef DNs = NULL;
+            require_noerr(SSLCopyDistinguishedNames    (ctx, &DNs), out);
+            require(DNs, out);
+            CFRelease(DNs);
+
+            require_string(ssl->client_side_auth, out, "errSSLClientCertRequested in run not testing that");
+            require_noerr(SSLSetCertificate(ctx, ssl->certs), out);
+        }
+    } while (ortn == errSSLWouldBlock
+             || ortn == errSSLServerAuthCompleted
+             || ortn == errSSLClientCertRequested);
+    require_noerr_action_quiet(ortn, out,
+                               fprintf(stderr, "Fell out of SSLHandshake with error: %ld\n", (long)ortn));
+
+    if (!ssl->is_server && !ssl->dh_anonymous && !ssl->is_session_resume) {
+        require_string(got_server_auth, out, "never got server auth");
+        if (ssl->client_side_auth)
+            require_string(got_client_cert_req, out, "never got client cert req");
+    }
+    //uint64_t elapsed = mach_absolute_time() - start;
+    //fprintf(stderr, "setr elapsed: %lld\n", elapsed);
+
+    /*
+     SSLProtocol proto = kSSLProtocolUnknown;
+     require_noerr_quiet(SSLGetNegotiatedProtocolVersion(ctx, &proto), out); */
+
+    SSLCipherSuite cipherSuite;
+    require_noerr_quiet(ortn = SSLGetNegotiatedCipher(ctx, &cipherSuite), out);
+    //fprintf(stderr, "st negotiated %s\n", sslcipher_itoa(cipherSuite));
+
+    if(ssl->is_dtls) {
+        size_t sz;
+        SSLGetDatagramWriteSize(ctx, &sz);
+        // fprintf(stderr, "Max Write Size = %ld\n", sz);
+    }
+
+       Boolean sessionWasResumed = false;
+    uint8_t session_id_data[MAX_SESSION_ID_LENGTH];
+    size_t session_id_length = sizeof(session_id_data);
+    require_noerr_quiet(ortn = SSLGetResumableSessionInfo(ctx, &sessionWasResumed, session_id_data, &session_id_length), out);
+    require_action(ssl->dh_anonymous || (ssl->is_session_resume == sessionWasResumed), out, ortn = -1);
+    // if (sessionWasResumed) fprintf(stderr, "st resumed session\n");
+    //hexdump(session_id_data, session_id_length);
+
+    unsigned char ibuf[300], obuf[300];
+    size_t len;
+    if (ssl->is_server) {
+        SecRandomCopyBytes(kSecRandomDefault, sizeof(obuf), obuf);
+        require_noerr_quiet(ortn = SSLWrite(ctx, obuf, sizeof(obuf), &len), out);
+        require_action_quiet(len == sizeof(obuf), out, ortn = -1);
+    }
+    require_noerr_quiet(ortn = SSLRead(ctx, ibuf, sizeof(ibuf), &len), out);
+    require_action_quiet(len == sizeof(ibuf), out, ortn = -1);
+
+    if (ssl->is_server) {
+        require_noerr(memcmp(ibuf, obuf, sizeof(ibuf)), out);
+    } else {
+        require_noerr_quiet(ortn = SSLWrite(ctx, ibuf, sizeof(ibuf), &len), out);
+        require_action_quiet(len == sizeof(ibuf), out, ortn = -1);
+    }
+
+out:
+    SSLClose(ctx);
+    CFRelease(ctx);
+    if (trust) CFRelease(trust);
+    close(ssl->comm);
+    pthread_exit((void *)(intptr_t)ortn);
+    return NULL;
+}
+
+
+
+static ssl_test_handle *
+ssl_test_handle_create(uint32_t session_id, bool resume, bool server, bool client_side_auth, bool dh_anonymous, bool dtls,
+                       int comm, CFArrayRef certs, SSLProtocol proto, bool kernel)
+{
+    ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle));
+    if (handle) {
+        handle->session_id = session_id;
+        handle->is_session_resume = resume;
+        handle->is_server = server;
+        handle->is_dtls = dtls;
+        handle->client_side_auth = client_side_auth;
+        handle->dh_anonymous = dh_anonymous;
+        handle->comm = comm;
+        handle->certs = certs;
+        handle->proto = proto;
+        handle->st = make_ssl_ref(server, client_side_auth, dh_anonymous, dtls, comm, certs, proto, kernel);
+    }
+    return handle;
+}
+
+
+
+static void createsockets(int sp[2])
+{
+
+
+    int sock;
+    struct sockaddr_in server_addr;
+    struct hostent *host;
+    int err;
+
+    host = gethostbyname("localhost");
+
+    server_addr.sin_family = AF_INET;
+    server_addr.sin_port = htons(5000);
+    server_addr.sin_addr = *((struct in_addr *)host->h_addr);
+    bzero(&(server_addr.sin_zero),8);
+    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
+        perror("server socket");
+        exit(1);
+    }
+
+    if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr))
+        == -1) {
+        perror("Unable to bind");
+        exit(1);
+    }
+
+    printf("Server Waiting for client on port 5000\n");
+
+    sp[0]=sock;
+
+    printf("Create client socket\n");
+    sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+    if(sock<0) {
+        perror("client socket");
+        exit(1);
+    }
+
+    err = connect(sock, (struct sockaddr *)&server_addr,
+                  sizeof(struct sockaddr));
+    if(err)
+    {
+        perror("connect");
+        exit(1);
+    }
+
+    sp[1]=sock;
+
+    printf("Connected\n");
+
+
+}
+
+int st_test(void);
+int st_test(void)
+{
+    pthread_t client_thread, server_thread;
+    CFArrayRef server_certs = server_chain();
+    check(server_certs);
+
+    char msg[128];
+
+    /* Enable this if you want to test a specific d/i/k/l/p/ combination */
+#if 0
+    int d=0, i=0, l=0, c=0, k=0; { {
+#else
+    int d,i,c,k,l,p;
+
+        p=0;
+        //for (p=0; p<nprotos; p++)
+        d=1;
+        //for (d=0;d<2; d++)  /* dtls or not dtls */
+            //for (c=0; c<2; k++) /* csa or not */
+            for (k=1; k<2; k++) /* kernel or not */
+            {
+                for (i=0; ciphers[i].cipher != (SSLCipherSuite)(-1); i++) {
+                    l=0;
+                    //for (l = 0; l<2; l++) {
+#endif
+                    SKIP:{
+                        //skip("Session resumption tests do not work at this point", 1, l != 1);
+                        int sp[2];
+
+#if 0
+                        if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) exit(errno);
+                        fcntl(sp[0], F_SETNOSIGPIPE, 1);
+                        fcntl(sp[1], F_SETNOSIGPIPE, 1);
+#else
+                        createsockets(sp);
+#endif
+                        ssl_test_handle *server, *client;
+
+                        bool client_side_auth = (c);
+                        bool kernel = (k);
+                        uint32_t session_id = (c+1) << 16 | (i+1);
+                        //fprintf(stderr, "session_id: %d\n", session_id);
+                        server = ssl_test_handle_create(session_id, (l == 1), true /*server*/,
+                                                        client_side_auth, ciphers[i].dh_anonymous, d,
+                                                        sp[0], server_certs, protos[p], false);
+                        client = ssl_test_handle_create(session_id, (l == 1), false/*client*/,
+                                                        client_side_auth, ciphers[i].dh_anonymous, d,
+                                                        sp[1], server_certs, protos[p], kernel);
+
+                        require_noerr(SSLSetPeerID(server->st, &session_id, sizeof(session_id)), out);
+                        require_noerr(SSLSetPeerID(client->st, &session_id, sizeof(session_id)), out);
+
+                        /* set fixed cipher on client and server */
+                        require_noerr(SSLSetEnabledCiphers(client->st, &ciphers[i].cipher, 1), out);
+                        require_noerr(SSLSetEnabledCiphers(server->st, &ciphers[i].cipher, 1), out);
+
+
+                        snprintf(msg, sizeof(msg),
+                                 "%40s ADH:%d CSA:%d DTLS:%d RESUME:%d PROTO:%d KERNEL:%d",
+                                 ciphers[i].name,
+                                 server->dh_anonymous,
+                                 server->client_side_auth,
+                                 d, l, p, k);
+
+                        printf("%s\n", msg);
+
+                        pthread_create(&client_thread, NULL, securetransport_ssl_thread, client);
+                        pthread_create(&server_thread, NULL, securetransport_ssl_thread, server);
+
+                        int server_err, client_err;
+                        pthread_join(client_thread, (void*)&client_err);
+                        pthread_join(server_thread, (void*)&server_err);
+
+
+                        __Check_String(!server_err && !client_err, msg);
+
+                    out:
+                        free(client);
+                        free(server);
+
+                        printf("\n\n");
+                        sleep(2);
+                    }
+                } /* all ciphers */
+            } /* all configs */
+
+    CFRelease(server_certs);
+
+    return 0;
+}
+
+
diff --git a/tlsnke/tlsnketest/tlssocket.c b/tlsnke/tlsnketest/tlssocket.c
new file mode 100644 (file)
index 0000000..03c6bb6
--- /dev/null
@@ -0,0 +1,318 @@
+//
+//  tlssocket.c
+//  tlsnke
+//
+//  Created by Fabrice Gautier on 1/6/12.
+//  Copyright (c) 2012 Apple, Inc. All rights reserved.
+//
+
+#include <Security/SecureTransportPriv.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+
+#include <net/kext_net.h>
+
+#include "tlssocket.h"
+#include "tlsnke.h"
+
+#include <AssertMacros.h>
+#include <errno.h>
+
+/* TLSSocket functions */
+
+static 
+int TLSSocket_Read(SSLRecordContextRef ref,
+                        SSLRecord *rec)
+{
+    int socket = (int)ref;
+    int rc;
+    ssize_t sz;
+    struct sockaddr_in client_addr;
+    int avail;
+    socklen_t avail_size;
+    struct cmsghdr *cmsg;
+    tls_record_hdr_t hdr;
+    struct msghdr msg;
+    struct iovec iov;
+    int cbuf_len=CMSG_SPACE(sizeof(*hdr))+1024;
+    uint8_t cbuf[cbuf_len];
+   
+
+    //    printf("%s: Waiting for some data...\n", __FUNCTION__);
+    /* PEEK only... */
+    char b;
+    rc = (int)recv(socket, &b, 1, MSG_PEEK);
+    
+    if(rc==-1)
+    {
+        if(errno==EAGAIN)
+            return errSSLRecordWouldBlock;
+        else {
+            perror("recv");
+            return errno;
+        }
+    }
+    
+    /* get the next packet size */
+    avail_size = sizeof(avail);
+    rc = getsockopt(socket, SOL_SOCKET, SO_NREAD, &avail, &avail_size);
+    
+    check_noerr(rc); 
+    check(avail_size==sizeof(avail));
+    
+    if(rc || (avail_size !=sizeof(avail)))
+        return errSSLRecordInternal;
+
+    //    printf("%s: Available = %d\n", __FUNCTION__, avail);
+    
+    if(avail==0)
+        return errSSLRecordWouldBlock;
+
+        
+    /* Allocate a buffer */
+    rec->contents.data = malloc(avail);
+    rec->contents.length = avail;
+    
+    /* read the message */
+    iov.iov_base = rec->contents.data;
+    iov.iov_len = rec->contents.length;
+    msg.msg_name = &client_addr;
+    msg.msg_namelen = sizeof(client_addr);
+    msg.msg_iov = &iov;
+    msg.msg_iovlen = 1;
+    msg.msg_control = cbuf;
+    msg.msg_controllen = cbuf_len;
+    
+    sz = recvmsg(socket, &msg, 0);
+    check(sz==avail);
+    
+    //    printf("%s: received = %ld, ctrl: l=%d f=%x\n", __FUNCTION__, sz, msg.msg_controllen, msg.msg_flags);
+    rec->contents.length = sz;
+    
+    cmsg = CMSG_FIRSTHDR(&msg);
+    check(cmsg);
+    if(!cmsg)
+        return 0;
+    
+    check(cmsg->cmsg_type == SCM_TLS_HEADER);
+    check(cmsg->cmsg_level == SOL_SOCKET);
+    check(cmsg->cmsg_len == CMSG_LEN(sizeof(*hdr)));
+    hdr = (tls_record_hdr_t)CMSG_DATA(cmsg);
+    check(hdr);
+    
+    /* print msg info */
+    /*
+    printf("%s: rc=%d, msg: %ld , cmsg = %d, %x, %x, hdr = %d, %x - from %s:%d\n", __FUNCTION__, rc,
+           iov.iov_len,
+           cmsg->cmsg_len, cmsg->cmsg_level, cmsg->cmsg_type,
+           hdr->content_type, hdr->protocol_version,
+           inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port)); 
+    */
+    rec->contentType = hdr->content_type;
+    rec->protocolVersion = hdr->protocol_version;
+    
+    if(rec->contentType==SSL_RecordTypeChangeCipher) {
+        printf("%s: Received ChangeCipherSpec message\n", __FUNCTION__);
+    }
+    return 0;
+}
+
+static
+int TLSSocket_Free(SSLRecordContextRef ref,
+                         SSLRecord rec)
+{
+    free(rec.contents.data);
+    return 0;
+}
+
+static 
+int TLSSocket_Write(SSLRecordContextRef ref,
+                          SSLRecord rec)
+{
+    int socket = (int)ref;
+    ssize_t sz;
+    
+    struct msghdr msg;
+    struct iovec iov;
+    tls_record_hdr_t hdr;
+    struct cmsghdr *cmsg;
+    int cbuf_len=CMSG_SPACE(sizeof(*hdr));
+    uint8_t cbuf[cbuf_len];
+
+    if(rec.contentType==SSL_RecordTypeChangeCipher) {
+        printf("%s: Sending ChangeCipherSpec message\n", __FUNCTION__);
+    }
+    // printf("%s: fd=%d, rec.len=%ld\n", __FUNCTION__, socket, rec.contents.length);
+
+    /* write the message */
+    iov.iov_base = rec.contents.data;
+    iov.iov_len = rec.contents.length;
+    msg.msg_name = NULL;
+    msg.msg_namelen = 0;
+    msg.msg_iov = &iov;
+    msg.msg_iovlen = 1;
+    msg.msg_control = cbuf;
+    msg.msg_controllen = cbuf_len;
+
+    cmsg = CMSG_FIRSTHDR(&msg);
+    cmsg->cmsg_level = SOL_SOCKET;
+    cmsg->cmsg_type = SCM_TLS_HEADER;
+    cmsg->cmsg_len = CMSG_LEN(sizeof(*hdr));
+    hdr = (tls_record_hdr_t)CMSG_DATA(cmsg);
+    hdr->content_type = rec.contentType;
+    hdr->protocol_version = rec.protocolVersion;
+    
+    /* print msg info */
+    sz = sendmsg(socket, &msg, 0);
+    
+    if(sz<0)
+        perror("sendmsg");
+    
+    /*
+       printf("%s: sz=%ld, msg: %ld , cmsg = %d, %d, %04x\n", __FUNCTION__, sz,
+           iov.iov_len,
+           cmsg->cmsg_len, cmsg->cmsg_level, cmsg->cmsg_type);
+    */
+    
+    check(sz==rec.contents.length);
+
+    if(sz<0)
+        return (int)sz;
+    else
+        return 0;
+}
+
+
+static
+int TLSSocket_InitPendingCiphers(SSLRecordContextRef   ref,
+                                       uint16_t              selectedCipher,
+                                       bool                  server,
+                                       SSLBuffer             key)
+{
+    int socket = (int)ref;
+    int rc;
+    char *buf;
+    
+    buf = malloc(key.length+3);
+    buf[0] = selectedCipher >> 8;
+    buf[1] = selectedCipher & 0xff;
+    buf[2] = server;
+    memcpy(buf+3, key.data, key.length);
+    
+    printf("%s: cipher=%04x, keylen=%ld\n", __FUNCTION__, selectedCipher, key.length);
+    
+    rc = setsockopt(socket, SOL_SOCKET, SO_TLS_INIT_CIPHER, buf, (socklen_t)(key.length+3));
+    
+    printf("%s: rc=%d\n", __FUNCTION__, rc);
+    
+    free(buf);
+    
+    return rc;
+}
+
+static 
+int TLSSocket_AdvanceWriteCipher(SSLRecordContextRef ref)
+{
+    int socket = (int)ref;
+    int rc;
+    rc = setsockopt(socket, SOL_SOCKET, SO_TLS_ADVANCE_WRITE_CIPHER, NULL, 0);
+    
+    printf("%s: rc=%d\n", __FUNCTION__, rc);
+    
+    return rc;
+}
+
+static 
+int TLSSocket_RollbackWriteCipher(SSLRecordContextRef ref)
+{
+    int socket = (int)ref;
+    int rc;
+    rc = setsockopt(socket, SOL_SOCKET, SO_TLS_ROLLBACK_WRITE_CIPHER, NULL, 0);
+    
+    printf("%s: rc=%d\n", __FUNCTION__, rc);
+    
+    return rc;
+}
+
+static 
+int TLSSocket_AdvanceReadCipher(SSLRecordContextRef    ref)
+{
+    int socket = (int)ref;
+    int rc;
+    rc = setsockopt(socket, SOL_SOCKET, SO_TLS_ADVANCE_READ_CIPHER, NULL, 0);
+    
+    printf("%s: rc=%d\n", __FUNCTION__, rc);
+    
+    return rc;
+}
+
+static 
+int TLSSocket_SetProtocolVersion(SSLRecordContextRef    ref,
+                                 SSLProtocolVersion     protocolVersion)
+{
+    int socket = (int)ref;
+    int rc;
+    rc = setsockopt(socket, SOL_SOCKET, SO_TLS_PROTOCOL_VERSION, &protocolVersion, sizeof(protocolVersion));
+    
+    printf("%s: rc=%d\n", __FUNCTION__, rc);
+    
+    return rc;
+}
+
+
+static
+int TLSSocket_ServiceWriteQueue(SSLRecordContextRef    ref)
+{
+    int socket = (int)ref;
+    int rc;
+    rc = setsockopt(socket, SOL_SOCKET, SO_TLS_SERVICE_WRITE_QUEUE, NULL, 0);
+
+    return rc;
+}
+
+
+const struct SSLRecordFuncs TLSSocket_Funcs = {
+    .read                = TLSSocket_Read,
+    .write               = TLSSocket_Write,
+    .initPendingCiphers  = TLSSocket_InitPendingCiphers,
+    .advanceWriteCipher  = TLSSocket_AdvanceWriteCipher,
+    .rollbackWriteCipher = TLSSocket_RollbackWriteCipher,
+    .advanceReadCipher   = TLSSocket_AdvanceReadCipher,
+    .setProtocolVersion  = TLSSocket_SetProtocolVersion,
+    .free                = TLSSocket_Free,
+    .serviceWriteQueue   = TLSSocket_ServiceWriteQueue,
+};
+
+
+/* TLSSocket SPIs */
+
+int TLSSocket_Attach(int socket)
+{
+    
+    /* Attach the TLS socket filter and return handle */
+    struct so_nke so_tlsnke;
+    int rc;
+    int handle;
+    socklen_t len;
+    
+    memset(&so_tlsnke, 0, sizeof(so_tlsnke));
+    so_tlsnke.nke_handle = TLS_HANDLE_IP4;
+    rc=setsockopt(socket, SOL_SOCKET, SO_NKE, &so_tlsnke, sizeof(so_tlsnke));
+    if(rc)
+        return rc;
+
+    len = sizeof(handle);
+    rc = getsockopt(socket, SOL_SOCKET, SO_TLS_HANDLE, &handle, &len);
+    if(rc)
+        return rc;
+
+    assert(len==sizeof(handle));
+    
+    return handle;
+}
+
diff --git a/tlsnke/tlsnketest/tlssocket.h b/tlsnke/tlsnketest/tlssocket.h
new file mode 100644 (file)
index 0000000..3d43df1
--- /dev/null
@@ -0,0 +1,43 @@
+//
+//  tlssocket.h
+//  tlsnke
+//
+//  Created by Fabrice Gautier on 1/6/12.
+//  Copyright (c) 2012 Apple, Inc. All rights reserved.
+//
+
+#ifndef __TLSSOCKET_H__
+#define __TLSSOCKET_H__
+
+#include <Security/SecureTransportPriv.h>
+
+/* 
+   Attach the TLS socket filter.
+   This makes a socket a TLS socket by attaching the TLS socket filter to that socket.
+   Return a positive TLS handle or a negative error.
+   The return TLS handle can be used to route VPN data directly through this TLS 
+   socket
+ */
+int TLSSocket_Attach(int socket);
+
+/* 
+ Detach the TLS socket filter.
+ Return 0 or negative error. 
+ If the TLS Socket is used with SecureTransport, one should make sure 
+ to tear down the SecureTransport session before calling this.
+ It is not required to use this, as closing the socket would have the same effect.
+*/
+int TLSSocket_Detach(int socket);
+
+/*
+    Secure Transport Record Layer functions for TLS Sockets.
+    To use SecureTransport with a TLS kernel socket, pass this to SSLSetRecordFuncs and
+    the socket descriptor to SSLSetRecordContext
+ */ 
+const struct SSLRecordFuncs TLSSocket_Funcs;
+
+
+#endif
diff --git a/utilities/Regressions/su-10-cfstring-der.c b/utilities/Regressions/su-10-cfstring-der.c
new file mode 100644 (file)
index 0000000..efcd6fc
--- /dev/null
@@ -0,0 +1,90 @@
+//
+//  su-10-cfstring-der.c
+//  utilities
+//
+//  Created by Mitch Adler on 6/18/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#include "utilities/der_plist.h"
+#include "utilities/der_plist_internal.h"
+
+#include "utilities/SecCFRelease.h"
+#include "utilities/array_size.h"
+
+#include <CoreFoundation/CFString.h>
+
+#include "utilities_regressions.h"
+
+
+#define kMaxResultSize 256
+
+struct test_case {
+    CFStringRef str;
+    size_t      size;
+    uint8_t     res[kMaxResultSize];
+};
+
+static struct test_case test_cases[] = {
+    { .str = CFSTR("FOO"),                  .size = 5, .res = { 0x0C, 0x03, 0x46, 0x4F, 0x4F, } },
+    { .str = CFSTR("!ß∂ƒ˙圈ø¥®xzfff"),     .size = 29, .res = { 0x0C, 0x1B, 0x21, 0xC3, 0x9F, 0xE2, 0x88, 0x82, 0xC6, 0x92,
+                                                                 0xCB, 0x99, 0xC3, 0xA5, 0xC5, 0x93, 0xCB, 0x86, 0xC3, 0xB8,
+                                                                 0xC2, 0xA5, 0xC2, 0xAE, 0x78, 0x7A, 0x66, 0x66, 0x66, } },
+};
+
+
+#define kTestsPerTestCase 8
+static void one_test(const struct test_case * thisCase)
+{
+    uint8_t buffer[4 * kMaxResultSize + 1];
+    uint8_t* buffer_end = buffer + sizeof(buffer);
+
+    uint8_t* encoded = der_encode_string(thisCase->str, NULL, buffer, buffer_end);
+
+    ok(encoded != NULL &&
+       (thisCase->size == (buffer_end - encoded)) &&
+       (memcmp(encoded, thisCase->res, thisCase->size) == 0));
+
+    CFStringRef decoded = NULL;
+
+    const uint8_t* decode_end = der_decode_string(NULL, kCFPropertyListMutableContainersAndLeaves,
+                                                  &decoded, NULL, encoded, buffer_end);
+
+    ok(decode_end == buffer_end);
+    ok((decoded != NULL) && CFEqual(decoded, thisCase->str));
+
+    encoded = der_encode_plist(thisCase->str, NULL, buffer, buffer_end);
+
+    ok(encoded != NULL &&
+       (thisCase->size == (buffer_end - encoded)) &&
+       (memcmp(encoded, thisCase->res, thisCase->size) == 0));
+
+    CFTypeRef decoded_type = NULL;
+
+    decode_end = der_decode_plist(NULL, kCFPropertyListMutableContainersAndLeaves,
+                                  &decoded_type, NULL, encoded, buffer_end);
+
+    ok(decode_end == buffer_end);
+    ok((decoded_type != NULL) && CFEqual(decoded_type, thisCase->str));
+
+    ok(der_sizeof_string(thisCase->str, NULL) == thisCase->size);
+    ok(der_sizeof_plist(thisCase->str, NULL) == thisCase->size);
+
+    CFReleaseNull(decoded);
+    CFReleaseNull(decoded_type);
+}
+
+#define kTestCount (array_size(test_cases) * kTestsPerTestCase)
+static void tests(void)
+{
+    for (int testnumber = 0; testnumber < array_size(test_cases); ++testnumber)
+        one_test(test_cases + testnumber);
+}
+
+int su_10_cfstring_der(int argc, char *const *argv)
+{
+    plan_tests(kTestCount);
+    tests();
+
+    return 0;
+}
diff --git a/utilities/Regressions/su-11-cfdata-der.c b/utilities/Regressions/su-11-cfdata-der.c
new file mode 100644 (file)
index 0000000..34b5fca
--- /dev/null
@@ -0,0 +1,141 @@
+//
+//  su-11-cfdata-der.c
+//  utilities
+//
+//  Created by Mitch Adler on 6/20/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#include "utilities/der_plist.h"
+#include "utilities/der_plist_internal.h"
+
+#include "utilities/SecCFRelease.h"
+#include "utilities/array_size.h"
+
+#include <CoreFoundation/CFData.h>
+
+#include "utilities_regressions.h"
+
+#define kMaxResultSize 512
+
+struct test_case {
+    size_t      data_size;
+    uint8_t     data[kMaxResultSize];
+    size_t      result_size;
+    uint8_t     result[kMaxResultSize];
+};
+
+static struct test_case test_cases[] = {
+    { .data_size = 3,   .data = { 0xFE, 0xFB, 0x10 },
+      .result_size = 5, .result = { 0x04, 0x03, 0xFE, 0xFB, 0x10, }, },
+    { .data_size = 260,   .data = { 0xf2, 0x82, 0x8f, 0x71, 0x50, 0xdc, 0x2e, 0x7d, 0x1d, 0x9e, 0x1c, 0xea,
+                                    0xb4, 0x47, 0x2c, 0xc7, 0xc6, 0x11, 0x5d, 0x2d, 0xe6, 0xec, 0x3d, 0xea,
+                                    0x24, 0x06, 0x6a, 0x37, 0xbc, 0x80, 0xdd, 0x8e, 0x9b, 0xf0, 0x5d, 0x5c,
+                                    0x1a, 0xb4, 0x48, 0xec, 0x23, 0x20, 0x98, 0x63, 0x87, 0x0e, 0x21, 0xa6,
+                                    0x20, 0xef, 0xd8, 0xde, 0xd8, 0x89, 0xca, 0x8c, 0x42, 0x3c, 0xce, 0xdc,
+                                    0xc3, 0x7f, 0xa0, 0xb2, 0xce, 0xf6, 0xcc, 0x0b, 0x46, 0x5f, 0xc0, 0xd6,
+                                    0x2a, 0x6e, 0x0d, 0x4e, 0x78, 0xa1, 0x4c, 0x17, 0xb6, 0xa7, 0x48, 0xca,
+                                    0x05, 0x54, 0xf1, 0xa1, 0x03, 0xac, 0xb0, 0x2e, 0xa5, 0xdd, 0xf2, 0x6a,
+                                    0x51, 0xe5, 0xa0, 0xcf, 0xd1, 0x94, 0xbc, 0x8c, 0x45, 0xa8, 0xa6, 0x41,
+                                    0x71, 0xaf, 0x9c, 0x95, 0xb3, 0xb6, 0x71, 0x07, 0xdb, 0x95, 0xc9, 0x36,
+                                    0x18, 0xbc, 0x61, 0x24, 0x33, 0x4c, 0x39, 0x04, 0x82, 0xcb, 0x1d, 0x09,
+                                    0xf4, 0xb7, 0x2c, 0xe8, 0x23, 0x5e, 0x24, 0x99, 0x85, 0x0a, 0xc4, 0x2f,
+                                    0xe7, 0xdc, 0xb4, 0x3c, 0xa8, 0xf3, 0xfb, 0xc6, 0x6e, 0xd8, 0xfd, 0x76,
+                                    0xc2, 0x50, 0x15, 0xc9, 0x6d, 0x2f, 0xcf, 0x1b, 0x8f, 0x73, 0x24, 0x19,
+                                    0x12, 0x21, 0xa1, 0x50, 0x37, 0x8f, 0xa4, 0x27, 0x6c, 0x0b, 0x39, 0xef,
+                                    0x24, 0xd8, 0x3d, 0x97, 0xc8, 0x46, 0x5d, 0x86, 0x0f, 0x99, 0x24, 0x48,
+                                    0x94, 0xd0, 0x51, 0x49, 0x9a, 0xb2, 0x29, 0x51, 0x66, 0x41, 0xd0, 0x52,
+                                    0xa3, 0x15, 0x5a, 0x99, 0xfb, 0xf2, 0x2d, 0xfc, 0x73, 0xa7, 0x03, 0xd5,
+                                    0xb6, 0x45, 0x48, 0x11, 0x93, 0xa9, 0xb7, 0x2d, 0xd4, 0x22, 0xbb, 0x87,
+                                    0xa3, 0xd4, 0x5d, 0xff, 0xda, 0x84, 0x91, 0x6c, 0xea, 0x72, 0x52, 0x7a,
+                                    0xfc, 0x36, 0xe1, 0xc4, 0x40, 0xc6, 0x65, 0x8e, 0x55, 0x5b, 0x54, 0x21,
+                                    0x41, 0x1d, 0xe0, 0xe5, 0x0b, 0x4b, 0x62, 0xc5 },
+        .result_size = 264, .result = { 0x04, 0x82, 0x01, 0x04,
+                                        0xF2, 0x82, 0x8F, 0x71, 0x50, 0xDC, 0x2E, 0x7D, 0x1D, 0x9E, 0x1C, 0xEA,
+                                        0xB4, 0x47, 0x2C, 0xC7, 0xC6, 0x11, 0x5D, 0x2D, 0xE6, 0xEC, 0x3D, 0xEA,
+                                        0x24, 0x06, 0x6A, 0x37, 0xBC, 0x80, 0xDD, 0x8E, 0x9B, 0xF0, 0x5D, 0x5C,
+                                        0x1A, 0xB4, 0x48, 0xEC, 0x23, 0x20, 0x98, 0x63, 0x87, 0x0E, 0x21, 0xA6,
+                                        0x20, 0xEF, 0xD8, 0xDE, 0xD8, 0x89, 0xCA, 0x8C, 0x42, 0x3C, 0xCE, 0xDC,
+                                        0xC3, 0x7F, 0xA0, 0xB2, 0xCE, 0xF6, 0xCC, 0x0B, 0x46, 0x5F, 0xC0, 0xD6,
+                                        0x2A, 0x6E, 0x0D, 0x4E, 0x78, 0xA1, 0x4C, 0x17, 0xB6, 0xA7, 0x48, 0xCA,
+                                        0x05, 0x54, 0xF1, 0xA1, 0x03, 0xAC, 0xB0, 0x2E, 0xA5, 0xDD, 0xF2, 0x6A,
+                                        0x51, 0xE5, 0xA0, 0xCF, 0xD1, 0x94, 0xBC, 0x8C, 0x45, 0xA8, 0xA6, 0x41,
+                                        0x71, 0xAF, 0x9C, 0x95, 0xB3, 0xB6, 0x71, 0x07, 0xDB, 0x95, 0xC9, 0x36,
+                                        0x18, 0xBC, 0x61, 0x24, 0x33, 0x4C, 0x39, 0x04, 0x82, 0xCB, 0x1D, 0x09,
+                                        0xF4, 0xB7, 0x2C, 0xE8, 0x23, 0x5E, 0x24, 0x99, 0x85, 0x0A, 0xC4, 0x2F,
+                                        0xE7, 0xDC, 0xB4, 0x3C, 0xA8, 0xF3, 0xFB, 0xC6, 0x6E, 0xD8, 0xFD, 0x76,
+                                        0xC2, 0x50, 0x15, 0xC9, 0x6D, 0x2F, 0xCF, 0x1B, 0x8F, 0x73, 0x24, 0x19,
+                                        0x12, 0x21, 0xA1, 0x50, 0x37, 0x8F, 0xA4, 0x27, 0x6C, 0x0B, 0x39, 0xEF,
+                                        0x24, 0xD8, 0x3D, 0x97, 0xC8, 0x46, 0x5D, 0x86, 0x0F, 0x99, 0x24, 0x48,
+                                        0x94, 0xD0, 0x51, 0x49, 0x9A, 0xB2, 0x29, 0x51, 0x66, 0x41, 0xD0, 0x52,
+                                        0xA3, 0x15, 0x5A, 0x99, 0xFB, 0xF2, 0x2D, 0xFC, 0x73, 0xA7, 0x03, 0xD5,
+                                        0xB6, 0x45, 0x48, 0x11, 0x93, 0xA9, 0xB7, 0x2D, 0xD4, 0x22, 0xBB, 0x87,
+                                        0xA3, 0xD4, 0x5D, 0xFF, 0xDA, 0x84, 0x91, 0x6C, 0xEA, 0x72, 0x52, 0x7A,
+                                        0xFC, 0x36, 0xE1, 0xC4, 0x40, 0xC6, 0x65, 0x8E, 0x55, 0x5B, 0x54, 0x21,
+                                        0x41, 0x1D, 0xE0, 0xE5, 0x0B, 0x4B, 0x62, 0xC5, }, },
+};
+
+
+#define kTestsPerTestCase 8
+static void one_test(const struct test_case * thisCase)
+{
+    CFDataRef start = CFDataCreateWithBytesNoCopy(NULL, thisCase->data, thisCase->data_size, kCFAllocatorNull);
+
+    uint8_t buffer[kMaxResultSize];
+    uint8_t *buffer_end = buffer + sizeof(buffer);
+
+    uint8_t* encoded = der_encode_plist(start, NULL, buffer, buffer_end);
+
+    ok(encoded != NULL &&
+       (thisCase->result_size == (buffer_end - encoded)) &&
+       (memcmp(encoded, thisCase->result, thisCase->result_size) == 0));
+
+    encoded = der_encode_data(start, NULL, buffer, buffer_end);
+
+    ok(encoded != NULL &&
+       (thisCase->result_size == (buffer_end - encoded)) &&
+       (memcmp(encoded, thisCase->result, thisCase->result_size) == 0));
+
+#if 0
+    printf(".size = %d, .res = { ", (buffer_end - encoded));
+    for(int c = 0; c < (buffer_end - encoded); ++c)
+        printf("0x%02X, ", encoded[c]);
+    printf("},\n");
+#endif
+
+    CFDataRef decoded = NULL;
+    const uint8_t* decode_end = der_decode_data(NULL, kCFPropertyListMutableContainersAndLeaves,
+                                                &decoded, NULL, encoded, buffer_end);
+
+    ok(decode_end == buffer_end);
+    ok((decoded != NULL) && CFEqual(decoded, start));
+
+    CFTypeRef decoded_type = NULL;
+    decode_end = der_decode_plist(NULL, kCFPropertyListMutableContainersAndLeaves,
+                                  &decoded_type, NULL, encoded, buffer_end);
+
+    ok(decode_end == buffer_end);
+    ok((decoded != NULL) && CFEqual(decoded_type, start));
+
+    ok(der_sizeof_data(start, NULL) == thisCase->result_size);
+    ok(der_sizeof_plist(start, NULL) == thisCase->result_size);
+
+    CFReleaseNull(start);
+    CFReleaseNull(decoded);
+    CFReleaseNull(decoded_type);
+}
+
+#define kTestCount (array_size(test_cases) * kTestsPerTestCase)
+static void tests(void)
+{
+    for (int testnumber = 0; testnumber < array_size(test_cases); ++testnumber)
+        one_test(test_cases + testnumber);
+}
+
+int su_11_cfdata_der(int argc, char *const *argv)
+{
+    plan_tests(kTestCount);
+    tests();
+
+    return 0;
+}
diff --git a/utilities/Regressions/su-12-cfboolean-der.c b/utilities/Regressions/su-12-cfboolean-der.c
new file mode 100644 (file)
index 0000000..45f2028
--- /dev/null
@@ -0,0 +1,86 @@
+//
+//  su-11-cfdata-der.c
+//  utilities
+//
+//  Created by Mitch Adler on 6/20/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#include "utilities/der_plist.h"
+#include "utilities/der_plist_internal.h"
+
+#include "utilities/SecCFRelease.h"
+#include "utilities/array_size.h"
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include "utilities_regressions.h"
+
+#define kMaxResultSize 16
+
+#define kTestsPerTestCase 8
+static void one_test(CFBooleanRef value, size_t der_size, const uint8_t *expected_der)
+{
+
+    uint8_t buffer[kMaxResultSize];
+    uint8_t *buffer_end = buffer + sizeof(buffer);
+
+    uint8_t* encoded = der_encode_plist(value, NULL, buffer, buffer_end);
+
+    ok(encoded != NULL &&
+       (der_size == (buffer_end - encoded)) &&
+       (memcmp(encoded, expected_der, der_size) == 0));
+
+    encoded = der_encode_boolean(value, NULL, buffer, buffer_end);
+
+    ok(encoded != NULL &&
+       (der_size == (buffer_end - encoded)) &&
+       (memcmp(encoded, expected_der, der_size) == 0));
+
+#if 0
+    printf(".size = %d, .res = { ", (buffer_end - encoded));
+    for(int c = 0; c < (buffer_end - encoded); ++c)
+        printf("0x%02X, ", encoded[c]);
+    printf("},\n");
+#endif
+
+    CFBooleanRef decoded = NULL;
+    const uint8_t* decode_end = der_decode_boolean(NULL, kCFPropertyListMutableContainersAndLeaves,
+                                                   &decoded, NULL, encoded, buffer_end);
+
+    ok(decode_end == buffer_end);
+    ok((decoded != NULL) && CFEqual(decoded, value));
+
+    CFPropertyListRef decoded_type = NULL;
+    decode_end = der_decode_plist(NULL, kCFPropertyListMutableContainersAndLeaves,
+                                  &decoded_type, NULL, encoded, buffer_end);
+
+    ok(decode_end == buffer_end);
+    ok((decoded != NULL) && CFEqual(decoded_type, value));
+
+    ok(der_sizeof_boolean(value, NULL) == der_size);
+    ok(der_sizeof_plist(value, NULL) == der_size);
+
+    CFReleaseNull(decoded);
+    CFReleaseNull(decoded_type);
+}
+
+#define kTestCount (2 * kTestsPerTestCase)
+static void tests(void)
+{
+    const uint8_t der_true[] = { 0x01, 0x01, 0x01 };
+
+    one_test(kCFBooleanTrue, sizeof(der_true), der_true);
+    
+    const uint8_t der_false[] = { 0x01, 0x01, 0x00 };
+    
+    one_test(kCFBooleanFalse, sizeof(der_false), der_false);
+}
+
+int su_12_cfboolean_der(int argc, char *const *argv)
+{
+    plan_tests(kTestCount);
+    tests();
+
+    return 0;
+}
diff --git a/utilities/Regressions/su-13-cfnumber-der.c b/utilities/Regressions/su-13-cfnumber-der.c
new file mode 100644 (file)
index 0000000..d9bc0c4
--- /dev/null
@@ -0,0 +1,103 @@
+//
+//  su-13-cfnumber-der.c
+//  utilities
+//
+//  Created by Mitch Adler on 6/20/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#include "utilities/der_plist.h"
+#include "utilities/der_plist_internal.h"
+
+#include "utilities/SecCFRelease.h"
+#include "utilities/array_size.h"
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include "utilities_regressions.h"
+
+#define kMaxResultSize 30
+
+struct test_case {
+    long long value;
+    size_t    encoded_size;
+    uint8_t   encoded[20];
+};
+
+static struct test_case test_cases[] =
+{
+    { .value = 0, .encoded_size = 3,    .encoded = { 0x02, 0x01, 0x00 }, },
+    { .value = 1, .encoded_size = 3, .encoded = { 0x02, 0x01, 0x01 }, },
+    { .value = 128, .encoded_size = 4, .encoded = { 0x02, 0x02, 0x00, 0x80 }, },
+    { .value = -1, .encoded_size = 3, .encoded = { 0x02, 0x01, 0xFF }, },
+    { .value = -129, .encoded_size = 4, .encoded = { 0x02, 0x02, 0xFF, 0x7F }, },
+    { .value = 1000, .encoded_size = 4, .encoded = { 0x02, 0x02, 0x03, 0xE8, }, },
+    { .value = 65280, .encoded_size = 5, .encoded = { 0x02, 0x03, 0x00, 0xFF, 0x00 }, },
+    { .value = 41234576, .encoded_size = 6, .encoded = { 0x02, 0x04, 0x02, 0x75, 0x30, 0x90 }, },
+    { .value = -412343576, .encoded_size = 6, .encoded = { 0x02, 0x04, 0xE7, 0x6C, 0x22, 0xE8 }, },
+};
+
+#define kTestsPerTestCase 8
+static void one_test(const struct test_case * thisCase)
+{
+    uint8_t buffer[kMaxResultSize];
+    uint8_t* buffer_end = buffer + sizeof(buffer);
+    
+    CFNumberRef initialValue = CFNumberCreate(NULL, kCFNumberLongLongType, &thisCase->value);
+
+    uint8_t* encoded = der_encode_plist(initialValue, NULL, buffer, buffer_end);
+
+    ok(encoded != NULL &&
+       (thisCase->encoded_size == (buffer_end - encoded)) &&
+       (memcmp(encoded, thisCase->encoded, thisCase->encoded_size) == 0));
+
+    encoded = der_encode_number(initialValue, NULL, buffer, buffer_end);
+
+    ok(encoded != NULL &&
+       (thisCase->encoded_size == (buffer_end - encoded)) &&
+       (memcmp(encoded, thisCase->encoded, thisCase->encoded_size) == 0));
+
+#if 0
+    printf(".size = %d, .res = { ", (buffer_end - encoded));
+    for(int c = 0; c < (buffer_end - encoded); ++c)
+        printf("0x%02X, ", encoded[c]);
+    printf("},\n");
+#endif
+
+    CFNumberRef decoded = NULL;
+    
+    const uint8_t* decode_end = der_decode_number(NULL, kCFPropertyListMutableContainersAndLeaves,
+                                                  &decoded, NULL, encoded, buffer_end);
+    
+    ok(decode_end == buffer_end, "didn't decode whole buffer");
+    ok((decoded != NULL) && CFEqual(decoded, initialValue), "Didn't make equal value.");
+
+    CFPropertyListRef decoded_type = NULL;
+
+    decode_end = der_decode_plist(NULL, kCFPropertyListMutableContainersAndLeaves,
+                                  &decoded_type, NULL, encoded, buffer_end);
+
+    ok(decode_end == buffer_end, "didn't decode whole buffer");
+    ok((decoded != NULL) && CFEqual(decoded_type, initialValue), "Didn't make equal value.");
+
+    ok(der_sizeof_number(initialValue, NULL) == thisCase->encoded_size, "Size correct.");
+    ok(der_sizeof_plist(initialValue, NULL) == thisCase->encoded_size, "Size correct.");
+
+    CFReleaseNull(decoded);
+    CFReleaseNull(decoded_type);
+}
+
+#define kTestCount (array_size(test_cases) * kTestsPerTestCase)
+static void tests(void)
+{
+    for (int testnumber = 0; testnumber < array_size(test_cases); ++testnumber)
+        one_test(test_cases + testnumber);
+}
+
+int su_13_cfnumber_der(int argc, char *const *argv)
+{
+    plan_tests(kTestCount);
+    tests();
+
+    return 0;
+}
diff --git a/utilities/Regressions/su-14-cfarray-der.c b/utilities/Regressions/su-14-cfarray-der.c
new file mode 100644 (file)
index 0000000..1763a1b
--- /dev/null
@@ -0,0 +1,106 @@
+//
+//  su-14-cfarray-der.c
+//  utilities
+//
+//  Created by Mitch Adler on 6/20/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#include "utilities/der_plist.h"
+#include "utilities/der_plist_internal.h"
+
+#include "utilities/SecCFRelease.h"
+#include "utilities/array_size.h"
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include "utilities_regressions.h"
+
+#define kMaxResultSize 1024
+
+struct test_case {
+    CFTypeRef elements[10];
+    size_t    encoded_size;
+    uint8_t   encoded[20];
+};
+
+static struct test_case test_cases[] =
+{
+    { .elements = { CFSTR("First") },
+        .encoded_size = 9, .encoded = { 0x30, 0x07, 0x0C, 0x05, 0x46, 0x69, 0x72, 0x73, 0x74, }, },
+    { .elements = { CFSTR("First"), CFSTR("SECOND") },
+        .encoded_size = 17, .encoded = { 0x30, 0x0F, 0x0C, 0x05, 0x46, 0x69, 0x72, 0x73, 0x74, 0x0C, 0x06, 0x53, 0x45, 0x43, 0x4F, 0x4E, 0x44, }, },
+    { .elements = { },
+        .encoded_size = 2, .encoded = { 0x30, 0x00, } },
+};
+
+#define kTestsPerTestCase 8
+static void one_test(const struct test_case * thisCase)
+{
+    CFIndex element_count = 0;
+    while (element_count < array_size(thisCase->elements) && thisCase->elements[element_count] != NULL)
+        ++element_count;
+
+    CFArrayRef testValue = CFArrayCreate(NULL, (const void **)&thisCase->elements, element_count, &kCFTypeArrayCallBacks);
+
+    uint8_t buffer[kMaxResultSize];
+    uint8_t* buffer_end = buffer + sizeof(buffer);
+    
+    uint8_t* encoded = der_encode_plist(testValue, NULL, buffer, buffer_end);
+
+    ok(encoded != NULL &&
+       (thisCase->encoded_size == (buffer_end - encoded)) &&
+       (memcmp(encoded, thisCase->encoded, thisCase->encoded_size) == 0));
+
+    encoded = der_encode_array(testValue, NULL, buffer, buffer_end);
+
+    ok(encoded != NULL &&
+       (thisCase->encoded_size == (buffer_end - encoded)) &&
+       (memcmp(encoded, thisCase->encoded, thisCase->encoded_size) == 0));
+
+#if 0
+    printf(".encoded_size = %d, .encoded = { ", (buffer_end - encoded));
+    for(int c = 0; c < (buffer_end - encoded); ++c)
+        printf("0x%02X, ", encoded[c]);
+    printf("},\n");
+#endif
+
+    CFArrayRef decoded = NULL;
+    
+    const uint8_t* decode_end = der_decode_array(NULL, kCFPropertyListMutableContainersAndLeaves,
+                                                 &decoded, NULL, encoded, buffer_end);
+    
+    ok(decode_end == buffer_end, "didn't decode whole buffer");
+    ok((decoded != NULL) && CFEqual(decoded, testValue), "Didn't make equal value.");
+
+    CFTypeRef decoded_type = NULL;
+
+    decode_end = der_decode_plist(NULL, kCFPropertyListMutableContainersAndLeaves,
+                                  &decoded_type, NULL, encoded, buffer_end);
+
+    ok(decode_end == buffer_end, "didn't decode whole buffer");
+    ok((decoded != NULL) && CFEqual(decoded_type, testValue), "Didn't make equal value.");
+
+    ok(der_sizeof_array(testValue, NULL) == thisCase->encoded_size, "Size correct.");
+    ok(der_sizeof_plist(testValue, NULL) == thisCase->encoded_size, "Size correct.");
+
+    CFReleaseNull(decoded);
+    CFReleaseNull(decoded_type);
+    
+    CFReleaseNull(testValue);
+}
+
+#define kTestCount (array_size(test_cases) * kTestsPerTestCase)
+static void tests(void)
+{
+    for (int testnumber = 0; testnumber < array_size(test_cases); ++testnumber)
+        one_test(test_cases + testnumber);
+}
+
+int su_14_cfarray_der(int argc, char *const *argv)
+{
+    plan_tests(kTestCount);
+    tests();
+
+    return 0;
+}
diff --git a/utilities/Regressions/su-15-cfdictionary-der.c b/utilities/Regressions/su-15-cfdictionary-der.c
new file mode 100644 (file)
index 0000000..f414e62
--- /dev/null
@@ -0,0 +1,162 @@
+//
+//  su-15-cfdictionary-der.c
+//  utilities
+//
+//  Created by Mitch Adler on 6/20/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#include "utilities_regressions.h"
+
+#include "utilities/der_plist.h"
+#include "utilities/der_plist_internal.h"
+
+#include "utilities/SecCFRelease.h"
+#include "utilities/array_size.h"
+
+#include <CoreFoundation/CoreFoundation.h>
+
+
+#define kMaxResultSize 1024
+
+struct test_case {
+    CFTypeRef keys[10];
+    CFTypeRef values[10];
+    size_t    encoded_size;
+    uint8_t   encoded[256];
+};
+
+static struct test_case test_cases[] =
+{
+    { .keys = { CFSTR("First"), },
+        .values = { CFSTR("First Value!"), },
+        .encoded_size = 25, .encoded = { 0x31, 0x17, 0x30, 0x15, 0x0C, 0x05, 0x46, 0x69, 0x72, 0x73, 0x74, 0x0C, 0x0C, 0x46, 0x69, 0x72, 0x73, 0x74, 0x20, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x21, },
+    },
+    { .keys = { CFSTR("First"), CFSTR("Second"), },
+      .values = { CFSTR("First Value!"), CFSTR("A second value"), },
+      .encoded_size = 51, .encoded = { 0x31, 0x31,
+                                       0x30, 0x15, 0x0C, 0x05, 0x46, 0x69, 0x72, 0x73, 0x74, 0x0C, 0x0C, 0x46, 0x69, 0x72, 0x73, 0x74, 0x20, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x21,
+                                       0x30, 0x18, 0x0C, 0x06, 0x53, 0x65, 0x63, 0x6F, 0x6E, 0x64, 0x0C, 0x0E, 0x41, 0x20, 0x73, 0x65, 0x63, 0x6F, 0x6E, 0x64, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, },
+    },
+};
+
+#define kTestsPerDictionaryTest 8
+static void test_dictionary(CFDictionaryRef testValue, size_t expected_size, const uint8_t* expected_data)
+{
+    uint8_t buffer[kMaxResultSize];
+    uint8_t* buffer_end = buffer + sizeof(buffer);
+    
+    uint8_t* encoded = der_encode_plist(testValue, NULL, buffer, buffer_end);
+    
+    ok(encoded != NULL &&
+       (expected_size == (buffer_end - encoded)) &&
+       (memcmp(encoded, expected_data, expected_size) == 0));
+    
+    encoded = der_encode_dictionary(testValue, NULL, buffer, buffer_end);
+    
+    ok(encoded != NULL &&
+       (expected_size == (buffer_end - encoded)) &&
+       (memcmp(encoded, expected_data, expected_size) == 0));
+    
+#if 0
+    printf(".encoded_size = %d, .encoded = { ", (buffer_end - encoded));
+    for(int c = 0; c < (buffer_end - encoded); ++c)
+        printf("0x%02X, ", encoded[c]);
+    printf("},\n");
+#endif
+    
+    CFDictionaryRef decoded = NULL;
+    
+    const uint8_t* decode_end = der_decode_dictionary(NULL, kCFPropertyListMutableContainersAndLeaves,
+                                                      &decoded, NULL, encoded, buffer_end);
+    
+    ok(decode_end == buffer_end, "didn't decode whole buffer");
+    ok((decoded != NULL) && CFEqual(decoded, testValue), "Didn't make equal value.");
+    
+    CFPropertyListRef decoded_type = NULL;
+    
+    decode_end = der_decode_plist(NULL, kCFPropertyListMutableContainersAndLeaves,
+                                  &decoded_type, NULL, encoded, buffer_end);
+    
+    ok(decode_end == buffer_end, "didn't decode whole buffer");
+    ok((decoded != NULL) && CFEqual(decoded_type, testValue), "Didn't make equal value.");
+    
+    ok(der_sizeof_dictionary(testValue, NULL) == expected_size, "Size correct.");
+    ok(der_sizeof_plist(testValue, NULL) == expected_size, "Size correct.");
+    
+    CFReleaseNull(decoded);
+    CFReleaseNull(decoded_type);
+}
+
+
+#define kTestsPerTestCase (1 + kTestsPerDictionaryTest)
+static void one_test(const struct test_case * thisCase)
+{
+    CFIndex key_count = 0;
+    while (key_count < array_size(thisCase->keys) && thisCase->keys[key_count] != NULL)
+        ++key_count;
+    
+    CFIndex value_count = 0;
+    while (value_count < array_size(thisCase->values) && thisCase->values[value_count] != NULL)
+        ++value_count;
+    
+    ok(key_count == value_count);
+
+    CFDictionaryRef testValue = CFDictionaryCreate(NULL, (const void**)thisCase->keys, (const void**)thisCase->values, key_count,
+                                                   &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+
+    test_dictionary(testValue, thisCase->encoded_size, thisCase->encoded);
+    
+    CFReleaseNull(testValue);
+}
+
+#define kTestCount (array_size(test_cases) * kTestsPerTestCase) + kTestsPerDictionaryTest
+static void tests(void)
+{
+    for (int testnumber = 0; testnumber < array_size(test_cases); ++testnumber)
+        one_test(test_cases + testnumber);
+    
+    
+    // Big honking test case.
+    CFMutableDictionaryRef dictionary = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    
+    const uint8_t some[] = { 0x10, 0xFF, 0x00, 0x12, 0xA5 };
+    CFDataRef someData = CFDataCreate(NULL, some, array_size(some));
+
+    const void * arrayElements[] = { kCFBooleanFalse, someData, CFSTR("In Array"), };
+    
+    CFArrayRef arrayValue = CFArrayCreate(NULL, arrayElements, array_size(arrayElements), &kCFTypeArrayCallBacks);
+    CFReleaseNull(someData);
+    
+    const uint8_t key[] = { 0xFC, 0xFF, 0xFA };
+    CFDataRef dataKey = CFDataCreate(NULL, key, array_size(key));
+    
+    CFDictionaryAddValue(dictionary, dataKey, arrayValue);
+    CFReleaseNull(dataKey);
+    CFReleaseNull(arrayValue);
+    
+    int numberValueValue = 2313;
+    CFNumberRef numberValue = CFNumberCreate(NULL, kCFNumberIntType, &numberValueValue);
+
+    CFDictionaryAddValue(dictionary, CFSTR("Oh yeah"), kCFBooleanTrue);
+    CFDictionaryAddValue(dictionary, kCFBooleanFalse, numberValue);
+    CFReleaseNull(numberValue);
+
+    int numberKeyValue = 2313;
+    CFNumberRef numberKey = CFNumberCreate(NULL, kCFNumberIntType, &numberKeyValue);
+    
+    CFDictionaryAddValue(dictionary, numberKey, kCFBooleanTrue);
+    CFReleaseNull(numberKey);
+    
+    uint8_t expected_result[] = { 0x31, 0x3D, 0x30, 0x07, 0x01, 0x01, 0x00, 0x02, 0x02, 0x09, 0x09, 0x30, 0x07, 0x02, 0x02, 0x09, 0x09, 0x01, 0x01, 0x01, 0x30, 0x0C, 0x0C, 0x07, 0x4F, 0x68, 0x20, 0x79, 0x65, 0x61, 0x68, 0x01, 0x01, 0x01, 0x30, 0x1B, 0x04, 0x03, 0xFC, 0xFF, 0xFA, 0x30, 0x14, 0x01, 0x01, 0x00, 0x04, 0x05, 0x10, 0xFF, 0x00, 0x12, 0xA5, 0x0C, 0x08, 0x49, 0x6E, 0x20, 0x41, 0x72, 0x72, 0x61, 0x79, };
+    test_dictionary(dictionary, array_size(expected_result), expected_result);
+    CFReleaseSafe(dictionary);
+}
+
+int su_15_cfdictionary_der(int argc, char *const *argv)
+{
+    plan_tests(kTestCount);
+    tests();
+
+    return 0;
+}
diff --git a/utilities/Regressions/su-16-cfdate-der.c b/utilities/Regressions/su-16-cfdate-der.c
new file mode 100644 (file)
index 0000000..9cd4160
--- /dev/null
@@ -0,0 +1,165 @@
+//
+//  su-16-cfdate-der.c
+//  utilities
+//
+//  Created by Michael Brouwer on 7/10/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#include "utilities/der_plist.h"
+#include "utilities/der_plist_internal.h"
+#include "utilities/der_date.h"
+
+#include "utilities/SecCFRelease.h"
+#include "utilities/array_size.h"
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <corecrypto/ccder.h>
+
+#include "utilities_regressions.h"
+
+#define kMaxResultSize 100
+
+struct test_case {
+    CFAbsoluteTime value;
+    char      *expected;
+};
+
+static struct test_case test_cases[] =
+{
+    { .value = 0.0,                     .expected = "20010101000000Z", },
+    { .value = 1.0,                     .expected = "20010101000001Z", },
+    { .value = 0.1,                     .expected = "20010101000000.1Z", },
+    { .value = 0.0001,                  .expected = "20010101000000.0001Z", },
+    { .value = 128.0,                   .expected = "20010101000208Z", },
+    { .value = -1.0,                    .expected = "20001231235959Z", },
+    { .value = -0.9,                    .expected = "20001231235959.1Z", },
+    { .value = -129.0,                  .expected = "20001231235751Z", },
+    { .value = 1000.0,                  .expected = "20010101001640Z", },
+    { .value = 65280.0,                 .expected = "20010101180800Z", },
+    { .value = 41234576.0,              .expected = "20020423060256Z", },
+    { .value = -412343576.0,            .expected = "19871208120704Z", },
+    { .value = 381778873.238063,        .expected = "20130205174113.238063Z", },
+    { .value = 381778873.638063,        .expected = "20130205174113.638063Z", },
+    { .value = 1400603.141,             .expected = "20010117050323.141Z", },
+    { .value = -412343576.238063,       .expected = "19871208120703.761937Z", },
+    { .value = -412343576.638063,       .expected = "19871208120703.361937Z", },
+    { .value = 5.000539014,             .expected = "20010101000005.000539014Z", },
+    { .value = -5.00053901,             .expected = "20001231235954.99946099Z", },
+    { .value = 0.000539014,             .expected = "20010101000000.000539014Z", },
+    { .value = -0.00053901,             .expected = "20001231235959.99946099Z", },
+    { .value = 11031400603.141,         .expected = "23500729055643.141Z", }, // Michael's 400th birthday
+    // Pedantic tests within 1 second of the epoch.
+    { .value = 0.000100120234,          .expected = "20010101000000.000100120234Z", },
+    { .value =                  0.00000000000000000000000000000000000000000010012654182354326,
+      .expected = "20010101000000.00000000000000000000000000000000000000000010012654182354326Z", },
+    { .value =                 -0.00000000000000000000000000000000000000000010012654182354326,
+      .expected = "20001231235959.99999999999999999999999999999999999999999989987345817645674Z", },
+    { .value = 0.0001234522366234637,   .expected = "20010101000000.0001234522366234637Z", },
+};
+
+static CFStringRef string_create_with_hex(const uint8_t* start, const uint8_t* end) {
+    CFMutableStringRef s = CFStringCreateMutable(NULL, 0);
+    CFStringAppendFormat(s, 0, CFSTR(".size = %" PRIdPTR ", .res = { "), (intptr_t)(end - start));
+    while (start < end)
+        CFStringAppendFormat(s, 0, CFSTR("0x%02X, "), *start++);
+    CFStringAppend(s, CFSTR("},\n"));
+    return s;
+}
+
+static bool ok_der_date_is(int testnumber, const char *expected, const uint8_t *der, const uint8_t *der_end) {
+    size_t elen = strlen(expected);
+    size_t dlen;
+    const uint8_t *body = ccder_decode_tl(CCDER_GENERALIZED_TIME, &dlen, der, der_end);
+    if (!body) {
+        return fail("[%d] encoded date %@ expected %s not a generalized time", testnumber, string_create_with_hex(der, der_end), expected);
+    } else if (body + dlen != der_end) {
+        return fail("[%d] Trailing garbage in encoded string after generalized time got: %@ expected: %s", testnumber, string_create_with_hex(der, der_end), expected);
+    } else if (dlen != elen) {
+        return fail("[%d] encoded date len %zu != %zu got: %.*s expected: %s", testnumber, dlen , elen, (int)dlen, (char *)body, expected);
+    } else if (memcmp(body, expected, elen)) {
+        return fail("[%d] encoded got: %.*s expected: %s", testnumber, (int)dlen, (char *)body, expected);
+    } else {
+        return pass("[%d] properly encoded %s", testnumber, expected);
+    }
+}
+
+static bool ok_date_equals(int testnumber, CFDateRef decoded, CFDateRef expected) {
+    CFAbsoluteTime t1 = CFDateGetAbsoluteTime(decoded);
+    CFAbsoluteTime t2 = CFDateGetAbsoluteTime(expected);
+    if (-1.0 < t1 && t1 < 1.0) {
+        // Dates near the epoch can't be off by more than 1 nanosecond.  Other dates should be exactly right.
+        return ok((decoded != NULL) && fabs(t1 - t2) < 7e-18, "[%d] Delta too big %g %a != %a (%g != %g).", testnumber, fabs(t1 - t2), t1, t2, t1, t2);
+    } else {
+        return ok((decoded != NULL) && CFEqual(decoded, expected), "[%d] Didn't make equal value %a != %a (%g != %g).", testnumber, t1, t2, t1, t2);
+    }
+}
+
+#define kTestsPerTestCase 12
+static void one_test(const struct test_case * thisCase, int testnumber)
+{
+    uint8_t buffer[kMaxResultSize];
+    uint8_t* buffer_end = buffer + sizeof(buffer);
+
+    CFDateRef initialValue = CFDateCreate(NULL, thisCase->value);
+    CFErrorRef error = NULL;
+
+    uint8_t* encoded = der_encode_plist(initialValue, &error, buffer, buffer_end);
+    SKIP:
+    {
+        skip("der_encode_plist failed", 1,
+             ok(encoded != NULL, "[%d] der_encode_plist failed: %@", testnumber, error));
+        ok_der_date_is(testnumber, thisCase->expected, encoded, buffer_end);
+    }
+    CFReleaseNull(error);
+
+    encoded = der_encode_date(initialValue, &error, buffer, buffer_end);
+    SKIP:
+    {
+        skip("der_encode_date failed", 1,
+             ok(encoded != NULL, "[%d] der_encode_date failed: %@", testnumber, error));
+        ok_der_date_is(testnumber, thisCase->expected, encoded, buffer_end);
+    }
+    CFReleaseNull(error);
+
+    CFDateRef decoded = NULL;
+    const uint8_t* decode_end = der_decode_date(NULL, kCFPropertyListMutableContainers,
+                                                  &decoded, &error, encoded, buffer_end);
+    ok(error == NULL, "[%d] der_decode_date failed: %@", testnumber, error);
+    CFReleaseNull(error);
+
+    ok(decode_end == buffer_end, "[%d] didn't decode whole buffer", testnumber);
+    ok_date_equals(testnumber, decoded, initialValue);
+
+    CFPropertyListRef decoded_type = NULL;
+
+    decode_end = der_decode_plist(NULL, kCFPropertyListMutableContainers,
+                                  &decoded_type, &error, encoded, buffer_end);
+    ok(error == NULL, "[%d] der_decode_plist failed: %@", testnumber, error);
+    CFReleaseNull(error);
+
+    ok(decode_end == buffer_end, "[%d] didn't decode whole buffer", testnumber);
+    ok_date_equals(testnumber, decoded, initialValue);
+
+    is(der_sizeof_date(initialValue, NULL), ccder_sizeof(CCDER_GENERALIZED_TIME, strlen(thisCase->expected)), "[%d] der_sizeof_date mismatch", testnumber);
+    is(der_sizeof_plist(initialValue, NULL), ccder_sizeof(CCDER_GENERALIZED_TIME, strlen(thisCase->expected)), "[%d] der_sizeof_plist mismatch", testnumber);
+
+    CFReleaseSafe(initialValue);
+    CFReleaseNull(decoded);
+    CFReleaseNull(decoded_type);
+}
+
+#define kTestCount (array_size(test_cases) * kTestsPerTestCase)
+static void tests(void)
+{
+    for (int testnumber = 0; testnumber < array_size(test_cases); ++testnumber)
+        one_test(test_cases + testnumber, testnumber);
+}
+
+int su_16_cfdate_der(int argc, char *const *argv)
+{
+    plan_tests(kTestCount);
+    tests();
+
+    return 0;
+}
diff --git a/utilities/Regressions/su-40-secdb.c b/utilities/Regressions/su-40-secdb.c
new file mode 100644 (file)
index 0000000..6a60617
--- /dev/null
@@ -0,0 +1,175 @@
+//
+//  su-40-secdb.c
+//  utilities
+//
+//  Created by Michael Brouwer on 11/15/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#include <utilities/SecCFRelease.h>
+#include <utilities/SecDb.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include "utilities_regressions.h"
+#include <time.h>
+
+#define kTestCount 31
+
+static int count_func(SecDbRef db, const char *name, CFIndex *max_conn_count, bool (*perform)(SecDbRef db, CFErrorRef *error, void (^perform)(SecDbConnectionRef dbconn))) {
+    __block int count = 0;
+    __block int max_count = 0;
+    *max_conn_count = 0;
+    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
+    dispatch_group_t group = dispatch_group_create();
+
+    for (int i = 0; i < 100; ++i) {
+        dispatch_group_async(group, queue, ^{
+            CFIndex conn_count = SecDbIdleConnectionCount(db);
+            if (conn_count > *max_conn_count) {
+                *max_conn_count = conn_count;
+            }
+
+            CFErrorRef error = NULL;
+            if (!perform(db, &error, ^void (SecDbConnectionRef dbconn) {
+                count++;
+                if (count > max_count) {
+                    max_count = count;
+                }
+                struct timespec ts = { .tv_nsec = 200000 };
+                nanosleep(&ts, NULL);
+                count--;
+            })) {
+                fail("perform %s %@", name, error);
+                CFReleaseNull(error);
+            }
+        });
+    }
+    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
+    dispatch_release(group);
+    return max_count;
+}
+
+static void count_connections(SecDbRef db) {
+    __block CFIndex max_conn_count = 0;
+    dispatch_group_t group = dispatch_group_create();
+    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
+    dispatch_group_async(group, queue, ^{
+        cmp_ok(count_func(db, "writers", &max_conn_count, SecDbPerformWrite), <=, kSecDbMaxWriters, "max writers is %d", kSecDbMaxWriters);
+    TODO: {
+        todo("can't guarantee all threads used");
+        is(count_func(db, "writers", &max_conn_count, SecDbPerformWrite), kSecDbMaxWriters, "max writers is %d", kSecDbMaxWriters);
+        }
+    });
+    dispatch_group_async(group, queue, ^{
+        cmp_ok(count_func(db, "readers",  &max_conn_count, SecDbPerformRead), <=, kSecDbMaxReaders, "max readers is %d", kSecDbMaxReaders);
+    TODO: {
+        todo("can't guarantee all threads used");
+        is(count_func(db, "readers",  &max_conn_count, SecDbPerformRead), kSecDbMaxReaders, "max readers is %d", kSecDbMaxReaders);
+        }
+    });
+    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
+    dispatch_release(group);
+    cmp_ok(max_conn_count, <=, kSecDbMaxIdleHandles, "max idle connection count is %d", kSecDbMaxIdleHandles);
+    TODO: {
+        todo("can't guarantee all threads idle");
+        is(max_conn_count, kSecDbMaxIdleHandles, "max idle connection count is %d", kSecDbMaxIdleHandles);
+    }
+
+}
+
+static void tests(void)
+{
+    CFTypeID typeID = SecDbGetTypeID();
+    CFStringRef tid = CFCopyTypeIDDescription(typeID);
+    ok(CFEqual(CFSTR("SecDb"), tid), "tid matches");
+    CFReleaseNull(tid);
+
+    typeID = SecDbConnectionGetTypeID();
+    tid = CFCopyTypeIDDescription(typeID);
+    ok(CFEqual(CFSTR("SecDbConnection"), tid), "tid matches");
+    CFReleaseNull(tid);
+
+    const char *home_var = getenv("HOME");
+    CFStringRef dbName = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%s/Library/Keychains/su-40-sqldb.db"), home_var ? home_var : "");
+
+    SecDbRef db = SecDbCreate(dbName, NULL);
+    ok(db, "SecDbCreate");
+
+    __block CFErrorRef error = NULL;
+    ok(SecDbPerformWrite(db, &error, ^void (SecDbConnectionRef dbconn) {
+        ok(SecDbExec(dbconn, CFSTR("CREATE TABLE tablea(key TEXT,value BLOB);"), &error),
+           "exec: %@", error);
+        ok(SecDbExec(dbconn, CFSTR("INSERT INTO tablea(key,value)VALUES(1,2);"), &error),
+           "exec: %@", error);
+
+        CFStringRef sql = CFSTR("INSERT INTO tablea(key,value)VALUES(?,?);");
+        ok(SecDbPrepare(dbconn, sql, &error, ^void (sqlite3_stmt *stmt) {
+            ok_status(sqlite3_bind_text(stmt, 1, "key1", 4, NULL), "bind_text[1]");
+            ok_status(sqlite3_bind_blob(stmt, 2, "value1", 6, NULL), "bind_blob[2]");
+            ok(SecDbStep(dbconn, stmt, &error, NULL), "SecDbStep: %@", error);
+            CFReleaseNull(error);
+        }), "SecDbPrepare: %@", error);
+        CFReleaseNull(error);
+
+        sql = CFSTR("SELECT key,value FROM tablea;");
+        ok(SecDbPrepare(dbconn, sql, &error, ^void (sqlite3_stmt *stmt) {
+            ok(SecDbStep(dbconn, stmt, &error, ^(bool *stop) {
+                const unsigned char *key = sqlite3_column_text(stmt, 1);
+                pass("got a row key: %s", key);
+                // A row happened, we're done
+                *stop = true;
+            }), "SecDbStep: %@", error);
+            CFReleaseNull(error);
+        }), "SecDbPrepare: %@", error);
+        CFReleaseNull(error);
+
+        ok(SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, &error, ^(bool *commit) {
+            ok(SecDbExec(dbconn, CFSTR("INSERT INTO tablea (key,value)VALUES(13,21);"), &error),
+               "exec: %@", error);
+            ok(SecDbExec(dbconn, CFSTR("INSERT INTO tablea (key,value)VALUES(2,5);"), &error),
+               "exec: %@", error);
+        }), "SecDbTransaction: %@", error);
+
+        ok(SecDbPrepare(dbconn, sql, &error, ^void (sqlite3_stmt *stmt) {
+            ok(SecDbStep(dbconn, stmt, &error, ^(bool *stop) {
+                const unsigned char *key = sqlite3_column_text(stmt, 1);
+                pass("got a row key: %s", key);
+            }), "SecDbStep: %@", error);
+            CFReleaseNull(error);
+            sqlite3_reset(stmt);
+            ok(SecDbStep(dbconn, stmt, &error, ^(bool *stop) {
+                const unsigned char *key = sqlite3_column_text(stmt, 1);
+                pass("got a row key: %s", key);
+                *stop = true;
+            }), "SecDbStep: %@", error);
+            CFReleaseNull(error);
+
+        }), "SecDbPrepare: %@", error);
+
+        ok(SecDbExec(dbconn, CFSTR("DROP TABLE tablea;"), &error),
+           "exec: %@", error);
+    }), "SecDbPerformWrite: %@", error);
+    CFReleaseNull(error);
+
+    count_connections(db);
+
+    CFReleaseNull(db);
+}
+
+int su_40_secdb(int argc, char *const *argv)
+{
+    plan_tests(kTestCount);
+    tests();
+    
+    return 0;
+}
+
+#if 0
+// The following still need tests.
+ok(SecDbTransaction(dbconn, kSecDbNoneTransactionType, &error, ^bool {}), "");
+ok(SecDbTransaction(dbconn, kSecDbImmediateTransactionType, &error, ^bool {}), "");
+ok(SecDbTransaction(dbconn, kSecDbNormalTransactionType, &error, ^bool {}), "");
+ok(SecDbPerformRead(SecDbRef db, CFErrorRef *error, void ^(SecDbConnectionRef dbconn){}), "");
+SecDbCheckpoint(SecDbConnectionRef dbconn);
+#endif
diff --git a/utilities/Regressions/su-41-secdb-stress.c b/utilities/Regressions/su-41-secdb-stress.c
new file mode 100644 (file)
index 0000000..f348604
--- /dev/null
@@ -0,0 +1,238 @@
+//
+//  su-41-secdb-stress.c
+//  utilities
+//
+//  Created by Michael Brouwer on 7/25/13.
+//  Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#include <utilities/SecCFWrappers.h>
+#include <utilities/SecDb.h>
+#include <utilities/SecDispatchRelease.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include "utilities_regressions.h"
+#include <time.h>
+
+#define kTestCount 3415
+
+// Queue to protect counters and test_ok invocations
+static dispatch_queue_t count_queue;
+
+#define ts_ok(THIS, ...) \
+({ \
+    bool is_ok = !!(THIS); \
+    dispatch_sync(count_queue, ^{ \
+        test_ok(is_ok, test_create_description(__VA_ARGS__), test_directive, \
+            test_reason, __FILE__, __LINE__, NULL); \
+    }); \
+    is_ok; \
+})
+
+#define ts_ok_status(THIS, ...) \
+({ \
+    OSStatus _this = (THIS); \
+    __block bool is_ok; \
+    dispatch_sync(count_queue, ^{ \
+        is_ok = test_ok(!_this, test_create_description(__VA_ARGS__), \
+            test_directive, test_reason, __FILE__, __LINE__, \
+            "#     status: %s(%ld)\n", \
+            sec_errstr(_this), _this); \
+    }); \
+    is_ok; \
+})
+
+
+typedef void (^SecDbBlock)(SecDbConnectionRef dbconn);
+
+#define SecDbExecWithSql(dbconn, sql)  test_SecDbExecWithSql(dbconn, sql, test_directive, test_reason, __FILE__, __LINE__)
+
+static void test_SecDbExecWithSql(SecDbConnectionRef dbconn, CFStringRef sql CF_CONSUMED, const char *directive,
+                                        const char *reason, const char *file, unsigned line) {
+    CFErrorRef execError = NULL;
+    bool is_ok = !!(SecDbExec(dbconn, sql, &execError));
+    dispatch_sync(count_queue, ^{
+        test_ok(is_ok, test_create_description("exec %@: %@", sql, execError), directive, reason, file, line, NULL);
+    });
+    CFReleaseNull(execError);
+    CFReleaseSafe(sql);
+}
+
+#define SecDbDeleteWithInts(dbconn, key, value)  test_SecDbDeleteWithInts(dbconn, key, value, test_directive, test_reason, __FILE__, __LINE__)
+static void test_SecDbDeleteWithInts(SecDbConnectionRef dbconn, int key, int value, const char *directive,
+                                                 const char *reason, const char *file, unsigned line) {
+    test_SecDbExecWithSql(dbconn, CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
+                                                           CFSTR("DELETE FROM tablea WHERE key=%d AND value=%d;"), key, value), directive, reason, file, line);
+}
+
+static void SecDbDoReadOp(SecDbConnectionRef dbconn, size_t seed) {
+    switch (seed % 2) {
+        case 0:
+        {
+            CFErrorRef prepareError = NULL;
+            CFStringRef sql = CFSTR("SELECT key,value FROM tablea;");
+            ts_ok(SecDbPrepare(dbconn, sql, &prepareError, ^void (sqlite3_stmt *stmt) {
+                CFErrorRef stepError = NULL;
+                ts_ok(SecDbStep(dbconn, stmt, &stepError, ^(bool *stop) {
+                    //const unsigned char *key = sqlite3_column_text(stmt, 1);
+                    //pass("got a row key: %s", key);
+                    // A row happened, we're done
+                    *stop = true;
+                }), "SecDbStep: %@", stepError);
+                CFReleaseNull(stepError);
+            }), "SecDbPrepare: %@", prepareError);
+            CFReleaseNull(prepareError);
+            break;
+        }
+        case 1:
+        {
+            CFErrorRef prepareError = NULL;
+            CFStringRef sql = CFSTR("SELECT key,value FROM tablea;");
+            ts_ok(SecDbPrepare(dbconn, sql, &prepareError, ^void (sqlite3_stmt *stmt) {
+                CFErrorRef stepError = NULL;
+                ts_ok(SecDbStep(dbconn, stmt, &stepError, ^(bool *stop) {
+                    //const unsigned char *key = sqlite3_column_text(stmt, 1);
+                    //pass("got a row key: %s", key);
+                }), "SecDbStep: %@", stepError);
+                CFReleaseNull(stepError);
+                sqlite3_reset(stmt);
+                ts_ok(SecDbStep(dbconn, stmt, &stepError, ^(bool *stop) {
+                    //const unsigned char *key = sqlite3_column_text(stmt, 1);
+                    //pass("got a row key: %s", key);
+                    *stop = true;
+                }), "SecDbStep: %@", stepError);
+                CFReleaseNull(stepError);
+            }), "SecDbPrepare: %@", prepareError);
+            CFReleaseNull(prepareError);
+            break;
+        }
+    }
+}
+
+static void SecDbDoWriteOp(SecDbConnectionRef dbconn, size_t seed) {
+    switch (seed % 6) {
+        case 0:
+            SecDbExecWithSql(dbconn, CFSTR("INSERT INTO tablea(key,value)VALUES(1,2);"));
+            break;
+        case 1:
+        {
+            CFErrorRef txnError = NULL;
+            ts_ok(SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, &txnError, ^(bool *commit) {
+                CFErrorRef execError = NULL;
+                ts_ok(SecDbExec(dbconn, CFSTR("INSERT INTO tablea (key,value)VALUES(13,21);"), &execError),
+                      "exec: %@", execError);
+                CFReleaseNull(execError);
+                ts_ok(SecDbExec(dbconn, CFSTR("INSERT INTO tablea (key,value)VALUES(2,5);"), &execError),
+                      "exec: %@", execError);
+                CFReleaseNull(execError);
+            }), "SecDbTransaction: %@", txnError);
+            CFReleaseNull(txnError);
+            break;
+        }
+        case 2:
+        {
+            CFErrorRef prepareError = NULL;
+            CFStringRef sql = CFSTR("INSERT INTO tablea(key,value)VALUES(?,?);");
+            ts_ok(SecDbPrepare(dbconn, sql, &prepareError, ^void (sqlite3_stmt *stmt) {
+                CFErrorRef stepError = NULL;
+                ts_ok_status(sqlite3_bind_text(stmt, 1, "key1", 4, NULL), "bind_text[1]");
+                ts_ok_status(sqlite3_bind_blob(stmt, 2, "value1", 6, NULL), "bind_blob[2]");
+                ts_ok(SecDbStep(dbconn, stmt, &stepError, NULL), "SecDbStep: %@", stepError);
+                CFReleaseNull(stepError);
+            }), "SecDbPrepare: %@", prepareError);
+            CFReleaseNull(prepareError);
+            break;
+        }
+        case 3:
+            SecDbDeleteWithInts(dbconn, 1, 2);
+            break;
+        case 4:
+            SecDbDeleteWithInts(dbconn, 13, 21);
+            break;
+        case 5:
+            SecDbDeleteWithInts(dbconn, 2, 5);
+            break;
+    }
+}
+
+static void tests(void)
+{
+    count_queue = dispatch_queue_create("count_queue", DISPATCH_QUEUE_SERIAL);
+
+    CFTypeID typeID = SecDbGetTypeID();
+    CFStringRef tid = CFCopyTypeIDDescription(typeID);
+    ts_ok(CFEqual(CFSTR("SecDb"), tid), "TypeIdDescription is SecDb");
+    CFReleaseNull(tid);
+
+    typeID = SecDbConnectionGetTypeID();
+    tid = CFCopyTypeIDDescription(typeID);
+    ts_ok(CFEqual(CFSTR("SecDbConnection"), tid), "TypeIdDescription is SecDbConnection");
+    CFReleaseNull(tid);
+
+    const char *home_var = getenv("HOME");
+    CFStringRef dbName = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%s/Library/Keychains/su-41-sqldb-stress.db"), home_var ? home_var : "");
+    CFStringPerformWithCString(dbName, ^(const char *path) { unlink(path); });
+
+    SecDbRef db = SecDbCreate(dbName, ^bool (SecDbConnectionRef dbconn, bool did_create, CFErrorRef *firstOpenError) {
+        // This test will run when the database is first opened.
+        return ts_ok(SecDbExec(dbconn, CFSTR("CREATE TABLE tablea(key TEXT,value BLOB);"), firstOpenError),
+           "create table: %@", *firstOpenError);
+    });
+    ts_ok(db, "SecDbCreate");
+
+    __block CFIndex max_idle = 0;
+    __block CFIndex max_readers = 0;
+    __block CFIndex max_writers = 0;
+    __block CFIndex cur_readers = 0;
+    __block CFIndex cur_writers = 0;
+
+    dispatch_group_t group = dispatch_group_create();
+    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
+    for (size_t job=0; job < 1000; ++job) {
+        dispatch_group_async(group, queue, ^{
+            CFIndex cur_idle = SecDbIdleConnectionCount(db);
+            dispatch_sync(count_queue, ^{ if (max_idle < cur_idle) max_idle = cur_idle; });
+            CFErrorRef performError = NULL;
+            if (job % 7 == 0) {
+                ts_ok(SecDbPerformWrite(db, &performError, ^void (SecDbConnectionRef dbconn) {
+                    dispatch_sync(count_queue, ^{ cur_writers++; if (max_writers < cur_writers) max_writers = cur_writers; });
+                    SecDbDoWriteOp(dbconn, job);
+                    dispatch_sync(count_queue, ^{ cur_writers--; });
+                }), "write %@", performError);
+            } else {
+                CFErrorRef performError = NULL;
+                ts_ok(SecDbPerformRead(db, &performError, ^void (SecDbConnectionRef dbconn) {
+                    dispatch_sync(count_queue, ^{ cur_readers++; if (max_readers < cur_readers) max_readers = cur_readers; });
+                    SecDbDoReadOp(dbconn, job);
+                    dispatch_sync(count_queue, ^{ cur_readers--; });
+                }), "read %@", performError);
+            }
+            CFReleaseNull(performError);
+        });
+    }
+    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
+    dispatch_release(group);
+
+    CFErrorRef writeError = NULL;
+    ts_ok(SecDbPerformWrite(db, &writeError, ^(SecDbConnectionRef dbconn){
+        SecDbExecWithSql(dbconn, CFSTR("DROP TABLE tablea;"));
+    }), "SecDbPerformWrite: %@", writeError);
+    CFReleaseNull(writeError);
+
+    dispatch_release_null(count_queue);
+
+    is(max_idle, kSecDbMaxIdleHandles, "max idle connection count is %d", kSecDbMaxIdleHandles);
+    is(max_writers, kSecDbMaxWriters, "max writers is %d", kSecDbMaxWriters);
+    is(max_readers, kSecDbMaxReaders, "max readers is %d", kSecDbMaxReaders);
+
+    CFReleaseNull(db);
+}
+
+int su_41_secdb_stress(int argc, char *const *argv)
+{
+    plan_tests(kTestCount);
+    tests();
+
+    return 0;
+}
diff --git a/utilities/Regressions/utilities_regressions.h b/utilities/Regressions/utilities_regressions.h
new file mode 100644 (file)
index 0000000..6b34bcc
--- /dev/null
@@ -0,0 +1,15 @@
+/* To add a test:
+ 1) add it here
+ 2) Add it as command line argument for SecurityTest.app in the Release and Debug schemes
+ */
+#include <test/testmore.h>
+
+ONE_TEST(su_10_cfstring_der)
+ONE_TEST(su_11_cfdata_der)
+ONE_TEST(su_12_cfboolean_der)
+ONE_TEST(su_13_cfnumber_der)
+ONE_TEST(su_14_cfarray_der)
+ONE_TEST(su_15_cfdictionary_der)
+ONE_TEST(su_16_cfdate_der)
+OFF_ONE_TEST(su_40_secdb)
+ONE_TEST(su_41_secdb_stress)
diff --git a/utilities/SecurityTool/not_on_this_platorm.c b/utilities/SecurityTool/not_on_this_platorm.c
new file mode 100644 (file)
index 0000000..da4ca13
--- /dev/null
@@ -0,0 +1,14 @@
+//
+//  File.c
+//  utilities
+//
+//  Created by J Osborne on 1/11/13.
+//  Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+int command_not_on_this_platform(int argc, char * const *argv);
+
+int command_not_on_this_platform(int argc, char * const *argv)
+{
+    return 0;
+}
\ No newline at end of file
diff --git a/utilities/SecurityTool/readline.c b/utilities/SecurityTool/readline.c
new file mode 100644 (file)
index 0000000..c0132d4
--- /dev/null
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 2003-2004,2006-2010 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ *
+ * readline.c
+ */
+
+#include "readline.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/* Read a line from stdin into buffer as a null terminated string.  If buffer is
+   non NULL use at most buffer_size bytes and return a pointer to buffer.  Otherwise
+   return a newly malloced buffer.
+   if EOF is read this function returns NULL.  */
+char *
+readline(char *buffer, int buffer_size)
+{
+       int ix = 0, bytes_malloced = 0;
+
+       if (!buffer)
+       {
+               bytes_malloced = 64;
+               buffer = (char *)malloc(bytes_malloced);
+               buffer_size = bytes_malloced;
+       }
+
+       for (;;++ix)
+       {
+               int ch;
+
+               if (ix == buffer_size - 1)
+               {
+                       if (!bytes_malloced)
+                               break;
+                       bytes_malloced += bytes_malloced;
+                       buffer = (char *)realloc(buffer, bytes_malloced);
+                       buffer_size = bytes_malloced;
+               }
+
+               ch = getchar();
+               if (ch == EOF)
+               {
+                       if (bytes_malloced)
+                               free(buffer);
+                       return NULL;
+               }
+               if (ch == '\n')
+                       break;
+               buffer[ix] = ch;
+       }
+
+       /* 0 terminate buffer. */
+       buffer[ix] = '\0';
+
+       return buffer;
+}
+
+/* Read the file name into buffer.  On return buffer contains a newly
+   malloced buffer or length buffer_size. Return 0 on success and -1 on failure.  */
+int
+read_file(const char *name, uint8_t **outData, size_t *outLength)
+{
+       int fd, result;
+       char *buffer = NULL;
+       off_t off_end;
+       ssize_t bytes_read;
+       size_t length;
+
+       do {
+               fd = open(name, O_RDONLY, 0);
+       } while (fd == -1 && errno == EINTR);
+
+       if (fd == -1)
+       {
+               fprintf(stderr, "open %s: %s", name, strerror(errno));
+               result = -1;
+               goto loser;
+       }
+
+       off_end = lseek(fd, 0, SEEK_END);
+       if (off_end == -1)
+       {
+               fprintf(stderr, "lseek %s, SEEK_END: %s", name, strerror(errno));
+               result = -1;
+               goto loser;
+       }
+
+       if (off_end > (off_t)SIZE_MAX) {
+               fprintf(stderr, "file %s too large %llu bytes", name, off_end);
+               result = -1;
+               goto loser;
+       }
+
+       length = (size_t)off_end;
+       buffer = malloc(length);
+
+       do {
+               bytes_read = pread(fd, buffer, length, 0);
+       } while (bytes_read == -1 && errno == EINTR);
+
+       if (bytes_read == -1)
+       {
+               fprintf(stderr, "pread %s: %s", name, strerror(errno));
+               result = -1;
+               goto loser;
+       }
+       if (bytes_read != (ssize_t)length)
+       {
+               fprintf(stderr, "read %s: only read %zu of %zu bytes", name, bytes_read, length);
+               result = -1;
+               goto loser;
+       }
+
+       do {
+               result = close(fd);
+       } while (result == -1 && errno == EINTR);
+
+       if (result == -1)
+       {
+               fprintf(stderr, "close %s: %s", name, strerror(errno));
+               goto loser;
+       }
+
+       *outData = (uint8_t *)buffer;
+       *outLength = length;
+
+       return result;
+
+loser:
+       if (buffer)
+               free(buffer);
+
+       return result;
+}      
+
+CFDataRef copyFileContents(const char *path) {
+    CFMutableDataRef data = NULL;
+    int fd = open(path, O_RDONLY, 0666);
+    if (fd == -1) {
+        fprintf(stderr, "open %s: %s", path, strerror(errno));
+        goto badFile;
+    }
+
+    off_t fsize = lseek(fd, 0, SEEK_END);
+    if (fsize == (off_t)-1) {
+        fprintf(stderr, "lseek %s, 0, SEEK_END: %s", path, strerror(errno));
+        goto badFile;
+    }
+
+       if (fsize > (off_t)INT32_MAX) {
+               fprintf(stderr, "file %s too large %llu bytes", path, fsize);
+               goto badFile;
+       }
+
+    data = CFDataCreateMutable(kCFAllocatorDefault, (CFIndex)fsize);
+    CFDataSetLength(data, (CFIndex)fsize);
+    void *buf = CFDataGetMutableBytePtr(data);
+    off_t total_read = 0;
+    while (total_read < fsize) {
+        ssize_t bytes_read;
+
+        bytes_read = pread(fd, buf, (size_t)(fsize - total_read), total_read);
+        if (bytes_read == -1) {
+            fprintf(stderr, "read %s: %s", path, strerror(errno));
+            goto badFile;
+        }
+        if (bytes_read == 0) {
+            fprintf(stderr, "read %s: unexpected end of file", path);
+            goto badFile;
+        }
+        total_read += bytes_read;
+    }
+
+    if (close(fd) == -1) {
+        fprintf(stderr, "close %s: %s", path, strerror(errno));
+        /* Failure to close the file isn't fatal. */
+    }
+
+    return data;
+badFile:
+    if (fd != -1) {
+        if (close(fd) == -1) {
+            fprintf(stderr, "close %s: %s", path, strerror(errno));
+        }
+    }
+    if (data)
+        CFRelease(data);
+    return NULL;
+}
+
+
+bool writeFileContents(const char *path, CFDataRef data) {
+    int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0666);
+    if (fd == -1) {
+        fprintf(stderr, "open %s: %s", path, strerror(errno));
+        goto badFile;
+    }
+
+    const void *buf = CFDataGetBytePtr(data);
+    off_t fsize = CFDataGetLength(data);
+
+    off_t total_write = 0;
+    while (total_write < fsize) {
+        ssize_t bytes_write;
+
+        bytes_write = pwrite(fd, buf, (size_t)(fsize - total_write), total_write);
+        if (bytes_write == -1) {
+            fprintf(stderr, "write %s: %s", path, strerror(errno));
+            goto badFile;
+        }
+        if (bytes_write == 0) {
+            fprintf(stderr, "write %s: unexpected end of file", path);
+            goto badFile;
+        }
+        total_write += bytes_write;
+    }
+
+    if (close(fd) == -1) {
+        fprintf(stderr, "close %s: %s", path, strerror(errno));
+        /* Failure to close the file isn't fatal. */
+    }
+
+    return true;
+badFile:
+    if (fd != -1) {
+        if (close(fd) == -1) {
+            fprintf(stderr, "close %s: %s", path, strerror(errno));
+        }
+    }
+    if (data)
+        CFRelease(data);
+    return false;
+}
diff --git a/utilities/SecurityTool/readline.h b/utilities/SecurityTool/readline.h
new file mode 100644 (file)
index 0000000..a82449a
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2003-2004,2006-2010 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ *
+ * readline.h
+ */
+
+#ifndef _READLINE_H_
+#define _READLINE_H_  1
+
+#include <CoreFoundation/CFData.h>
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Read a line from stdin into buffer as a null terminated string.  If buffer is
+   non NULL use at most buffer_size bytes and return a pointer to buffer.  Otherwise
+   return a newly malloced buffer.
+   if EOF is read this function returns NULL.  */
+extern char *readline(char *buffer, int buffer_size);
+
+/* Read the file name into buffer.  On return outData.Data contains a newly
+   malloced buffer of outData.Length bytes. Return 0 on success and -1 on failure.  */
+extern int read_file(const char *name, uint8_t **outData, size_t *outLength);
+
+extern CFDataRef copyFileContents(const char *path);
+
+extern bool writeFileContents(const char *path, CFDataRef data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _READLINE_H_ */
diff --git a/utilities/SecurityTool/security_tool_commands.h b/utilities/SecurityTool/security_tool_commands.h
new file mode 100644 (file)
index 0000000..48a50f7
--- /dev/null
@@ -0,0 +1,28 @@
+//
+//  security_tool_commands.h
+//  Security
+//
+//  Created by Mitch Adler on 1/9/13.
+//
+//
+
+// This is included to make SECURITY_COMMAND macros result in declarations of
+// commands for use in SecurityTool
+
+#ifndef SECURITY_COMMAND
+#define SECURITY_COMMAND(name, function, parameters, description) int function(int argc, char * const *argv);
+
+#if TARGET_OS_EMBEDDED
+#define SECURITY_COMMAND_IOS(name, function, parameters, description) int function(int argc, char * const *argv);
+#else
+#define SECURITY_COMMAND_IOS(name, function, parameters, description) extern int command_not_on_this_platform(int argc, char * const *argv);
+#endif
+
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+#define SECURITY_COMMAND_MAC(name, function, parameters, description) int function(int argc, char * const *argv);
+#else
+#define SECURITY_COMMAND_MAC(name, function, parameters, description) extern int command_not_on_this_platform(int argc, char * const *argv);
+#endif
+
+
+#endif
diff --git a/utilities/SecurityTool/security_tool_commands_table.h b/utilities/SecurityTool/security_tool_commands_table.h
new file mode 100644 (file)
index 0000000..c44ce69
--- /dev/null
@@ -0,0 +1,29 @@
+//
+//  security_tool_commands_table.h
+//  utilities
+//
+//  Created by J Osborne on 1/11/13.
+//  Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+
+// This is included to make SECURITY_COMMAND macros result in table of
+// commands for use in SecurityTool
+
+#undef SECURITY_COMMAND
+#undef SECURITY_COMMAND_IOS
+#undef SECURITY_COMMAND_MAC
+#define SECURITY_COMMAND(name, function, parameters, description)  { name, function, parameters, description },
+
+#if TARGET_OS_EMBEDDED
+#define SECURITY_COMMAND_IOS(name, function, parameters, description)  { name, function, parameters, description },
+#else
+#define SECURITY_COMMAND_IOS(name, function, parameters, description)  { name, command_not_on_this_platform, "", "Not avilable on this platform" },
+#endif
+
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+#define SECURITY_COMMAND_MAC(name, function, parameters, description)  { name, function, parameters, description },
+#else
+#define SECURITY_COMMAND_MAC(name, function, parameters, description) { name, command_not_on_this_platform, "", "Not avilable on this platform" },
+#endif
+
diff --git a/utilities/src/SecAKSWrappers.c b/utilities/src/SecAKSWrappers.c
new file mode 100644 (file)
index 0000000..037fa4d
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+//
+//  SecAKSWrappers.c
+//  utilities
+//
+
+#include <utilities/SecAKSWrappers.h>
+#include <utilities/SecCFWrappers.h>
+
+#if TARGET_IPHONE_SIMULATOR
+#  define change_notification "com.apple.will.never.happen"
+#elif TARGET_OS_IPHONE
+#  include <MobileKeyBag/MobileKeyBag.h>
+#  define change_notification kMobileKeyBagLockStatusNotificationID
+#elif TARGET_OS_MAC
+#  include <AppleKeyStoreEvents.h>
+#  define change_notification kAppleKeyStoreLockStatusNotificationID
+#else
+#  error "unsupported target platform"
+#endif
+
+const char * const kUserKeybagStateChangeNotification = change_notification;
+
+bool SecAKSDoWhileUserBagLocked(CFErrorRef *error, dispatch_block_t action)
+{
+#if TARGET_IPHONE_SIMULATOR
+    action();
+    return true;
+#else
+    // Acquire lock assertion, ref count?
+    
+    __block kern_return_t status = kIOReturnSuccess;
+    static dispatch_once_t queue_once;
+    static dispatch_queue_t assertion_queue;
+    
+#if TARGET_OS_MAC && !TARGET_OS_EMBEDDED                            // OS X
+    AKSAssertionType_t lockAssertType = kAKSAssertTypeOther;
+    keybag_handle_t keybagHandle = session_keybag_handle;
+#else                                                               // iOS, but not simulator
+    AKSAssertionType_t lockAssertType = kAKSAssertTypeProfile;      // Profile supports timeouts, but only available on iOS
+    keybag_handle_t keybagHandle = device_keybag_handle;
+#endif
+    
+    dispatch_once(&queue_once, ^{
+        assertion_queue = dispatch_queue_create("AKS Lock Assertion Queue", NULL);
+    });
+    
+    static uint32_t count = 0;
+    
+    dispatch_sync(assertion_queue, ^{
+        if (count == 0) {
+            uint64_t timeout = 60ull;
+            secnotice("lockassertions", "Requesting lock assertion for %lld seconds", timeout);
+            status = aks_assert_hold(keybagHandle, lockAssertType, timeout);
+        }
+        
+        if (status == kIOReturnSuccess)
+            ++count;
+    });
+    
+    if (status == kIOReturnSuccess) {
+        action();
+        dispatch_sync(assertion_queue, ^{
+            if (count && (--count == 0)) {
+                secnotice("lockassertions", "Dropping lock assertion");
+                status = aks_assert_drop(keybagHandle, lockAssertType);
+            }
+        });
+    }
+    return SecKernError(status, error, CFSTR("Kern return error"));
+#endif  /* !TARGET_IPHONE_SIMULATOR */
+}
diff --git a/utilities/src/SecAKSWrappers.h b/utilities/src/SecAKSWrappers.h
new file mode 100644 (file)
index 0000000..d968374
--- /dev/null
@@ -0,0 +1,105 @@
+//
+//  SecAKSWrappers.h
+//  utilities
+//
+//  Created by Mitch Adler on 6/5/13.
+//  Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#ifndef _SECAKSWRAPPERS_H_
+#define _SECAKSWRAPPERS_H_
+
+#include <utilities/SecCFError.h>
+#include <AssertMacros.h>
+#include <dispatch/dispatch.h>
+
+#if TARGET_IPHONE_SIMULATOR
+
+#include <IOKit/IOReturn.h>
+
+// Make the compiler happy so this will compile.
+#define device_keybag_handle 0
+#define session_keybag_handle 0
+
+enum keybag_state {
+    keybag_state_unlocked = 0,
+    keybag_state_locked = 1 << 0,
+    keybag_state_no_pin = 1 << 1,
+    keybag_state_been_unlocked = 1 << 2,
+};
+typedef uint32_t keybag_state_t;
+typedef int32_t keybag_handle_t;
+
+static kern_return_t aks_get_lock_state(keybag_handle_t handle, keybag_state_t *state) {
+    if (state) *state = keybag_state_no_pin & keybag_state_been_unlocked;
+    return kIOReturnSuccess;
+}
+
+#else
+
+#include <libaks.h>
+
+#endif
+
+//
+// MARK: User lock state
+//
+
+enum {
+    user_keybag_handle = TARGET_OS_EMBEDDED ? device_keybag_handle : session_keybag_handle,
+};
+
+extern const char * const kUserKeybagStateChangeNotification;
+
+static inline bool SecAKSGetLockedState(keybag_state_t *state, CFErrorRef* error)
+{
+    kern_return_t status = aks_get_lock_state(user_keybag_handle, state);
+    
+    if (kIOReturnSuccess != status) {
+        SecCFCreateError(status, CFSTR("com.apple.kern_return_t"), CFSTR("Kern return error"), NULL, error);
+        return false;
+    }
+
+    return true;
+}
+
+// returns true if any of the bits in bits is set in the current state of the user bag
+static inline bool SecAKSLockedAnyStateBitIsSet(bool* isSet, keybag_state_t bits, CFErrorRef* error)
+{
+    keybag_state_t state;
+    bool success = SecAKSGetLockedState(&state, error);
+    
+    require_quiet(success, exit);
+    
+    if (isSet)
+        *isSet = (state & bits);
+    
+exit:
+    return success;
+
+}
+
+static inline bool SecAKSGetIsLocked(bool* isLocked, CFErrorRef* error)
+{
+    return SecAKSLockedAnyStateBitIsSet(isLocked, keybag_state_locked, error);
+}
+
+static inline bool SecAKSGetIsUnlocked(bool* isUnlocked, CFErrorRef* error)
+{
+    bool isLocked = false;
+    bool success = SecAKSGetIsLocked(&isLocked, error);
+
+    if (success && isUnlocked)
+        *isUnlocked = !isLocked;
+
+    return success;
+}
+
+static inline bool SecAKSGetHasBeenUnlocked(bool* hasBeenUnlocked, CFErrorRef* error)
+{
+    return SecAKSLockedAnyStateBitIsSet(hasBeenUnlocked, keybag_state_been_unlocked, error);
+}
+
+bool SecAKSDoWhileUserBagLocked(CFErrorRef *error, dispatch_block_t action);
+
+#endif
diff --git a/utilities/src/SecCFCanonicalHashes.c b/utilities/src/SecCFCanonicalHashes.c
new file mode 100644 (file)
index 0000000..3d5a133
--- /dev/null
@@ -0,0 +1,120 @@
+//
+//  SecCFCanonicalHashes.c
+//  utilities
+//
+//  Created by Mitch Adler on 2/8/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#include <stdio.h>
+
+#include "utilities/SecCFCanonicalHashes.h"
+#include "utilities/comparison.h"
+
+#include <CoreFoundation/CFArray.h>
+#include <CoreFoundation/CFString.h>
+#include <CoreFoundation/CFData.h>
+#include <utilities/SecCFRelease.h>
+#include <corecrypto/ccdigest.h>
+
+struct AddKeyValueHashContext {
+    CFMutableArrayRef array;
+    const struct ccdigest_info* di;
+    bool fail;
+};
+
+static void AddKeyValueHashData(const void *key, const void *value, void *context)
+{
+    struct AddKeyValueHashContext* akvContext = (struct AddKeyValueHashContext*) context;
+
+    size_t key_len;
+    const void* key_data;
+    if (CFGetTypeID(key) == CFStringGetTypeID()) {
+        key_len = CFStringGetLength((CFStringRef) key);
+        key_data = CFStringGetCharactersPtr((CFStringRef) key);
+    } else {
+        akvContext->fail = true;
+        return;
+    }
+
+    size_t value_len;
+    const void* value_data;
+    if (CFGetTypeID(key) == CFStringGetTypeID()) {
+        value_len = CFStringGetLength((CFStringRef) value);
+        value_data = CFStringGetCharactersPtr((CFStringRef) value);
+    } else if (CFGetTypeID(key) == CFDataGetTypeID()) {
+        value_len = CFDataGetLength((CFDataRef)value);
+        value_data = CFDataGetBytePtr((CFDataRef)value);
+    } else {
+        akvContext->fail = true;
+        return;
+    }
+
+    UInt8 hashBuffer[akvContext->di->output_size];
+
+    ccdigest_di_decl(akvContext->di, finalContext);
+
+    ccdigest(akvContext->di, key_len, key_data, hashBuffer);
+
+    ccdigest_init(akvContext->di, finalContext);
+    ccdigest_update(akvContext->di, finalContext, sizeof(hashBuffer), hashBuffer);
+
+    ccdigest_update(akvContext->di, finalContext, sizeof(hashBuffer), hashBuffer);
+    ccdigest(akvContext->di, value_len, value_data, hashBuffer);
+
+    ccdigest_final(akvContext->di, finalContext, (void*)hashBuffer);
+
+    CFDataRef hash = CFDataCreate(kCFAllocatorDefault, hashBuffer, sizeof(hashBuffer));
+    CFArrayAppendValue(akvContext->array, hash);
+    CFReleaseSafe(hash);
+}
+
+static CFComparisonResult CFDataCompare(CFDataRef d1, CFDataRef d2)
+{
+    CFIndex d1_size = CFDataGetLength(d1);
+    CFIndex d2_size = CFDataGetLength(d2);
+
+    CFIndex comparison = memcmp(CFDataGetBytePtr(d1), CFDataGetBytePtr(d2), MIN(d1_size, d2_size));
+
+    if (comparison == 0)
+        comparison = d1_size - d2_size;
+
+    return (comparison > 0) ? kCFCompareGreaterThan : ((comparison < 0) ? kCFCompareLessThan : kCFCompareEqualTo);
+}
+
+static CFComparisonResult CFEqualComparitor(const void *val1, const void *val2, void * context __unused)
+{
+    return CFDataCompare((CFDataRef) val1, (CFDataRef) val2);
+}
+
+struct array_hashing_context {
+    const struct ccdigest_info* di;
+    struct ccdigest_ctx *       ctx;
+};
+
+static void hash_CFDatas(const void *value, void *context)
+{
+    struct array_hashing_context* ahc = (struct array_hashing_context*) context;
+
+    ccdigest_update(ahc->di, ahc->ctx, CFDataGetLength((CFDataRef) value), CFDataGetBytePtr((CFDataRef) value));
+}
+
+
+bool SecCFAppendCFDictionaryHash(CFDictionaryRef thisDictionary, const struct ccdigest_info* di, CFMutableDataRef toThis)
+{
+    CFMutableArrayRef hashArray = CFArrayCreateMutable(kCFAllocatorDefault, CFDictionaryGetCount(thisDictionary), &kCFTypeArrayCallBacks);
+
+    CFDictionaryApplyFunction(thisDictionary, &AddKeyValueHashData, hashArray);
+
+    CFRange wholeArray = CFRangeMake(0, CFArrayGetCount(hashArray));
+
+    CFArraySortValues(hashArray, wholeArray, &CFEqualComparitor, NULL);
+
+    ccdigest_di_decl(di, finalContext);
+
+    struct array_hashing_context ahc = { .di = di, .ctx = (struct ccdigest_ctx*)&finalContext};
+
+    CFArrayApplyFunction(hashArray, wholeArray, hash_CFDatas, &ahc);
+
+    return true;
+}
diff --git a/utilities/src/SecCFCanonicalHashes.h b/utilities/src/SecCFCanonicalHashes.h
new file mode 100644 (file)
index 0000000..39f35a4
--- /dev/null
@@ -0,0 +1,20 @@
+//
+//  SecCFCanonicalHashes.h
+//  Security
+//
+//  Created by Mitch Adler on 2/8/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#ifndef _SECCFCANONICALHASHES_H_
+#define _SECCFCANONICALHASHES_H_
+
+#include <CoreFoundation/CFDictionary.h>
+#include <CoreFoundation/CFData.h>
+
+#include <corecrypto/ccdigest.h>
+
+bool SecCFAppendCFDictionaryHash(CFDictionaryRef thisDictionary, const struct ccdigest_info* di, CFMutableDataRef toThis);
+
+
+#endif
diff --git a/utilities/src/SecCFError.c b/utilities/src/SecCFError.c
new file mode 100644 (file)
index 0000000..cd25943
--- /dev/null
@@ -0,0 +1,106 @@
+//
+//  SecCFError.c
+//  utilities
+//
+//  Created by Mitch Adler on 7/18/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#include <Security/SecBase.h>
+#include <utilities/SecCFError.h>
+#include <utilities/SecCFRelease.h>
+#include <utilities/debugging.h>
+
+bool SecKernError(kern_return_t result, CFErrorRef *error, CFStringRef format, ...) {
+    if (!result) return true;
+    if (error) {
+        va_list args;
+        CFIndex code = result;
+        CFErrorRef previousError = *error;
+
+        *error = NULL;
+        va_start(args, format);
+        SecCFCreateErrorWithFormatAndArguments(code, kSecKernDomain, previousError, error, NULL, format, args);
+        va_end(args);
+    }
+    return false;
+}
+
+bool SecCheckErrno(int result, CFErrorRef *error, CFStringRef format, ...) {
+    if (result == 0) return true;
+    if (error) {
+        va_list args;
+        int errnum = errno;
+        CFIndex code = errnum;
+        CFErrorRef previousError = *error;
+
+        *error = NULL;
+        va_start(args, format);
+        CFStringRef message = CFStringCreateWithFormatAndArguments(kCFAllocatorDefault, NULL, format, args);
+        va_end(args);
+        SecCFCreateErrorWithFormat(code, kSecErrnoDomain, previousError, error, NULL, CFSTR("%@: [%d] %s"), message, errnum, strerror(errnum));
+        CFReleaseSafe(message);
+    }
+    return false;
+}
+
+bool SecError(OSStatus status, CFErrorRef *error, CFStringRef format, ...) {
+    if (status == errSecSuccess) return true;
+    if (error) {
+        va_list args;
+        CFIndex code = status;
+        CFErrorRef previousError = *error;
+
+        *error = NULL;
+        va_start(args, format);
+        SecCFCreateErrorWithFormatAndArguments(code, kSecErrorDomain, previousError, error, NULL, format, args);
+        va_end(args);
+    }
+    return false;
+}
+
+
+void SecCFCreateError(CFIndex errorCode, CFStringRef domain, CFStringRef descriptionString,
+                      CFErrorRef previousError, CFErrorRef *newError)
+{
+#pragma clang diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-security"
+    SecCFCreateErrorWithFormat(errorCode, domain, previousError, newError, NULL, descriptionString);
+#pragma clang diagnostic pop
+}
+
+void SecCFCreateErrorWithFormat(CFIndex errorCode, CFStringRef domain, CFErrorRef previousError, CFErrorRef *newError,
+                                CFDictionaryRef formatoptions, CFStringRef format, ...)
+{
+    va_list args;
+    va_start(args, format);
+
+    SecCFCreateErrorWithFormatAndArguments(errorCode, domain, previousError, newError, formatoptions, format, args);
+
+    va_end(args);
+}
+
+void SecCFCreateErrorWithFormatAndArguments(CFIndex errorCode, CFStringRef domain,
+                                            CFErrorRef previousError, CFErrorRef *newError,
+                                            CFDictionaryRef formatoptions, CFStringRef format, va_list args)
+{
+    if (newError && !(*newError)) {
+        CFStringRef formattedString = CFStringCreateWithFormatAndArguments(NULL, formatoptions, format, args);
+        
+        const void* keys[2] =   { kCFErrorDescriptionKey,   kCFErrorUnderlyingErrorKey};
+        const void* values[2] = { formattedString,          previousError };
+        const CFIndex numEntriesToUse = (previousError != NULL) ? 2 : 1;
+
+        *newError = CFErrorCreateWithUserInfoKeysAndValues(kCFAllocatorDefault, domain, errorCode,
+                                                           keys, values, numEntriesToUse);
+
+        CFReleaseNull(formattedString);
+        if (previousError)
+            secnotice("error", "encapsulated %@ with new error: %@", previousError, *newError);
+    } else {
+        if (previousError && newError && (previousError != *newError)) {
+            secnotice("error", "dropping %@", previousError);
+            CFRelease(previousError);
+        }
+    }
+}
diff --git a/utilities/src/SecCFError.h b/utilities/src/SecCFError.h
new file mode 100644 (file)
index 0000000..3bfb676
--- /dev/null
@@ -0,0 +1,46 @@
+//
+//  SecCFError.h
+//  utilities
+//
+//  Created by Mitch Adler on 7/18/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#ifndef _SECCFERROR_H_
+#define _SECCFERROR_H_
+
+#include <CoreFoundation/CoreFoundation.h>
+
+//
+// Leaf error creation from other systems
+//
+
+// kern_return_t errors
+#define kSecKernDomain  kCFErrorDomainMach
+bool SecKernError(kern_return_t result, CFErrorRef *error, CFStringRef format, ...);
+
+// Unix errno errors
+#define kSecErrnoDomain  kCFErrorDomainPOSIX
+bool SecCheckErrno(int result, CFErrorRef *error, CFStringRef format, ...);
+
+// OSStatus errors
+#define kSecErrorDomain  kCFErrorDomainOSStatus
+bool SecError(OSStatus status, CFErrorRef *error, CFStringRef format, ...);
+
+//
+// Create and chain
+//
+void SecCFCreateError(CFIndex errorCode, CFStringRef domain, CFStringRef descriptionString,
+                      CFErrorRef previousError, CFErrorRef *newError);
+
+void SecCFCreateErrorWithFormat(CFIndex errorCode, CFStringRef domain, CFErrorRef previousError, CFErrorRef *newError,
+                                CFDictionaryRef formatoptions, CFStringRef descriptionString, ...)
+                        CF_FORMAT_FUNCTION(6,7);
+
+
+void SecCFCreateErrorWithFormatAndArguments(CFIndex errorCode, CFStringRef domain,
+                                            CFErrorRef previousError, CFErrorRef *newError,
+                                            CFDictionaryRef formatoptions, CFStringRef descriptionString, va_list args)
+                                CF_FORMAT_FUNCTION(6, 0);
+
+#endif
diff --git a/utilities/src/SecCFRelease.h b/utilities/src/SecCFRelease.h
new file mode 100644 (file)
index 0000000..f63eabf
--- /dev/null
@@ -0,0 +1,34 @@
+//
+//  SecCFRelease.h
+//  utilities
+//
+//  Created by Mitch Adler on 2/9/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#ifndef _SECCFRELEASE_H_
+#define _SECCFRELEASE_H_
+
+#include <CoreFoundation/CFBase.h>
+
+#define CFRetainSafe(CF) {  \
+    CFTypeRef _cf = (CF);   \
+    if (_cf)                \
+        CFRetain(_cf);      \
+    }
+
+#define CFReleaseSafe(CF) { \
+    CFTypeRef _cf = (CF);   \
+    if (_cf)                \
+        CFRelease(_cf);     \
+    }
+
+#define CFReleaseNull(CF) { \
+    CFTypeRef _cf = (CF);   \
+    if (_cf) {              \
+        (CF) = NULL;        \
+        CFRelease(_cf);     \
+        }                   \
+    }
+
+#endif
diff --git a/utilities/src/SecCFWrappers.c b/utilities/src/SecCFWrappers.c
new file mode 100644 (file)
index 0000000..d16ed67
--- /dev/null
@@ -0,0 +1,71 @@
+//
+//  SecCFWrappers.c
+//  utilities
+//
+//  Created by Michael Brouwer on 11/15/12.
+//  Copyright 2012 Apple Inc. All rights reserved.
+//
+
+#include <utilities/SecCFWrappers.h>
+
+void CFStringPerformWithCStringAndLength(CFStringRef inStr, void(^operation)(const char *utf8String, size_t utf8Length)) {
+    const char *cstr = CFStringGetCStringPtr(inStr, kCFStringEncodingUTF8);
+    if (cstr) {
+        operation(cstr, strlen(cstr));
+    } else {
+        CFIndex neededLen = 0;
+        CFRange range = { 0, CFStringGetLength(inStr) };
+        CFStringGetBytes(inStr, range, kCFStringEncodingUTF8,
+                         0, FALSE, NULL, 0, &neededLen);
+        CFIndex usedLen = 0;
+        if (neededLen < 4096) {
+            char buf[neededLen + 1];
+            CFStringGetBytes(inStr, range, kCFStringEncodingUTF8,
+                             0, FALSE, (UInt8 *)buf, neededLen, &usedLen);
+            assert(usedLen == neededLen);
+            buf[usedLen] = 0;
+            operation(buf, (size_t)usedLen);
+            //cc_zero(neededLen, buf);
+        } else {
+            char *buf = malloc(neededLen + 1);
+            CFStringGetBytes(inStr, range, kCFStringEncodingUTF8,
+                             0, FALSE, (UInt8 *)buf, neededLen, &usedLen);
+            assert(usedLen == neededLen);
+            buf[usedLen] = 0;
+            operation(buf, (size_t)usedLen);
+            //cc_zero(neededLen, buf);
+            free(buf);
+        }
+    }
+}
+
+void CFStringPerformWithCString(CFStringRef inStr, void(^operation)(const char *utf8String)) {
+    const char *cstr = CFStringGetCStringPtr(inStr, kCFStringEncodingUTF8);
+    if (cstr) {
+        operation(cstr);
+    } else {
+        CFIndex neededLen = 0;
+        CFRange range = { 0, CFStringGetLength(inStr) };
+        CFStringGetBytes(inStr, range, kCFStringEncodingUTF8,
+                         0, FALSE, NULL, 0, &neededLen);
+        CFIndex usedLen = 0;
+        if (neededLen < 4096) {
+            char buf[neededLen + 1];
+            CFStringGetBytes(inStr, range, kCFStringEncodingUTF8,
+                             0, FALSE, (UInt8 *)buf, neededLen, &usedLen);
+            assert(usedLen == neededLen);
+            buf[usedLen] = 0;
+            operation(buf);
+            //cc_zero(neededLen, buf);
+        } else {
+            char *buf = malloc(neededLen + 1);
+            CFStringGetBytes(inStr, range, kCFStringEncodingUTF8,
+                             0, FALSE, (UInt8 *)buf, neededLen, &usedLen);
+            assert(usedLen == neededLen);
+            buf[usedLen] = 0;
+            operation(buf);
+            //cc_zero(neededLen, buf);
+            free(buf);
+        }
+    }
+}
diff --git a/utilities/src/SecCFWrappers.h b/utilities/src/SecCFWrappers.h
new file mode 100644 (file)
index 0000000..93bcc92
--- /dev/null
@@ -0,0 +1,585 @@
+//
+//  SecCFWrappers.h
+//
+//  Created by Mitch Adler on 1/27/11.
+//  Copyright 2011 Apple Inc. All rights reserved.
+//
+
+#ifndef _SECCFWRAPPERS_H_
+#define _SECCFWRAPPERS_H_
+
+#include <CoreFoundation/CFRuntime.h>
+#include <CoreFoundation/CFNumber.h>
+#include <CoreFoundation/CFData.h>
+#include <CoreFoundation/CFDate.h>
+#include <CoreFoundation/CFString.h>
+#include <CoreFoundation/CFPropertyList.h>
+
+#include <utilities/SecCFRelease.h>
+#include <utilities/debugging.h>
+
+#include <assert.h>
+#include <dispatch/dispatch.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+
+//
+// Convenience routines.
+//
+
+//
+// Macros for the pattern
+//
+// typedef struct _privateNewClass* NewClassRef;
+//
+// struct _privateNewClass {
+//      CFRuntimeBase _base;
+//      ... class additions
+// };
+//
+// kClassNameRegisterClass
+// kClassNameTypeID
+//
+// ClassNameGetTypeID()
+//
+// CFGiblisFor(NewClass);
+//
+// .. define NewClassDestroy
+// .. define NewClassCopyDescription
+//
+// .. use CFTypeAllocate(NewClass, _privateNewClass, allocator);
+//
+//
+
+#define CFGiblisWithFunctions(gibliClassName, describe_func, destroy_func, compare_func, hash_func) \
+    CFTypeID gibliClassName##GetTypeID(void); \
+    CFTypeID gibliClassName##GetTypeID(void) { \
+    static dispatch_once_t  k##gibliClassName##RegisterClass; \
+    static CFTypeID         k##gibliClassName##TypeID = _kCFRuntimeNotATypeID; \
+    \
+    dispatch_once(&k##gibliClassName##RegisterClass, ^{ \
+        static const CFRuntimeClass k##gibliClassName##Class = { \
+        .className = #gibliClassName, \
+        .finalize = destroy_func, \
+        .copyDebugDesc = describe_func, \
+        .equal = compare_func, \
+        .hash = hash_func, \
+        }; \
+        \
+        k##gibliClassName##TypeID = _CFRuntimeRegisterClass(&k##gibliClassName##Class); \
+    }); \
+    return k##gibliClassName##TypeID; \
+    }
+
+
+#define CFGiblisWithHashFor(gibliClassName) \
+    static CFStringRef  gibliClassName##CopyDescription(CFTypeRef cf); \
+    static void         gibliClassName##Destroy(CFTypeRef cf); \
+    static Boolean      gibliClassName##Compare(CFTypeRef lhs, CFTypeRef rhs); \
+    static CFHashCode   gibliClassName##Hash(CFTypeRef cf); \
+    \
+    CFGiblisWithFunctions(gibliClassName, gibliClassName##CopyDescription, gibliClassName##Destroy, gibliClassName##Compare, gibliClassName##Hash)
+
+#define CFGiblisWithCompareFor(gibliClassName) \
+    static CFStringRef  gibliClassName##CopyDescription(CFTypeRef cf); \
+    static void         gibliClassName##Destroy(CFTypeRef cf); \
+    static Boolean      gibliClassName##Compare(CFTypeRef lhs, CFTypeRef rhs); \
+    \
+    CFGiblisWithFunctions(gibliClassName, gibliClassName##CopyDescription, gibliClassName##Destroy, gibliClassName##Compare, NULL)
+
+
+#define CFGiblisFor(gibliClassName) \
+    static CFStringRef  gibliClassName##CopyDescription(CFTypeRef cf); \
+    static void         gibliClassName##Destroy(CFTypeRef cf); \
+    \
+    CFGiblisWithFunctions(gibliClassName, gibliClassName##CopyDescription, gibliClassName##Destroy, NULL, NULL)
+
+#define CFTypeAllocate(classType, internalType, allocator) \
+    (classType##Ref) _CFRuntimeCreateInstance(allocator, classType##GetTypeID(), \
+                                              sizeof(internalType) - sizeof(CFRuntimeBase), \
+                                              NULL)
+
+__BEGIN_DECLS
+
+//
+// Call block function
+//
+
+static void apply_block_1(const void *value, void *context)
+{
+    return ((void (^)(const void *value))context)(value);
+}
+
+static void apply_block_2(const void *key, const void *value, void *context)
+{
+    return ((void (^)(const void *key, const void *value))context)(key, value);
+}
+
+//
+// CFEqual Helpers
+//
+
+static inline bool CFEqualSafe(CFTypeRef left, CFTypeRef right)
+{
+    if (left == NULL || right == NULL)
+        return left == right;
+    else
+        return CFEqual(left, right);
+}
+
+//
+// CFNumber Helpers
+//
+
+static inline CFNumberRef CFNumberCreateWithCFIndex(CFAllocatorRef allocator, CFIndex value)
+{
+    return CFNumberCreate(allocator, kCFNumberCFIndexType, &value);
+}
+
+//
+// CFData Helpers
+//
+
+static inline CFMutableDataRef CFDataCreateMutableWithScratch(CFAllocatorRef allocator, CFIndex size) {
+    CFMutableDataRef result = CFDataCreateMutable(allocator, 0);
+    CFDataSetLength(result, size);
+
+    return result;
+}
+
+static inline void CFDataAppend(CFMutableDataRef appendTo, CFDataRef dataToAppend)
+{
+    CFDataAppendBytes(appendTo, CFDataGetBytePtr(dataToAppend), CFDataGetLength(dataToAppend));
+}
+
+static inline CFDataRef CFDataCreateReferenceFromRange(CFAllocatorRef allocator, CFDataRef sourceData, CFRange range)
+{
+    return CFDataCreateWithBytesNoCopy(allocator,
+                                       CFDataGetBytePtr(sourceData) + range.location, range.length,
+                                       kCFAllocatorNull);
+}
+
+static inline CFDataRef CFDataCreateCopyFromRange(CFAllocatorRef allocator, CFDataRef sourceData, CFRange range)
+{
+    return CFDataCreate(allocator, CFDataGetBytePtr(sourceData) + range.location, range.length);
+}
+
+static inline uint8_t* CFDataIncreaseLengthAndGetMutableBytes(CFMutableDataRef data, CFIndex extraLength)
+{
+    CFIndex startOffset = CFDataGetLength(data);
+
+    CFDataIncreaseLength(data, extraLength);
+
+    return CFDataGetMutableBytePtr(data) + startOffset;
+}
+
+static inline uint8_t* CFDataGetMutablePastEndPtr(CFMutableDataRef theData)
+{
+    return CFDataGetMutableBytePtr(theData) + CFDataGetLength(theData);
+}
+
+static inline const uint8_t* CFDataGetPastEndPtr(CFDataRef theData) {
+    return CFDataGetBytePtr(theData) + CFDataGetLength(theData);
+}
+
+static inline CFComparisonResult CFDataCompare(CFDataRef left, CFDataRef right)
+{
+    const size_t left_size = CFDataGetLength(left);
+    const size_t right_size = CFDataGetLength(right);
+    const size_t shortest = (left_size <= right_size) ? left_size : right_size;
+    
+    int comparison = memcmp(CFDataGetBytePtr(left), CFDataGetBytePtr(right), shortest);
+
+    if (comparison > 0 || (comparison == 0 && left_size > right_size))
+        return kCFCompareGreaterThan;
+    else if (comparison < 0 || (comparison == 0 && left_size < right_size))
+        return kCFCompareLessThan;
+    else
+        return kCFCompareEqualTo;
+}
+
+
+//
+// CFString Helpers
+//
+
+//
+// Turn a CFString into an allocated UTF8-encoded C string.
+//
+static inline char *CFStringToCString(CFStringRef inStr)
+{
+    if (!inStr)
+        return (char *)strdup("");
+    CFRetain(inStr);        // compensate for release on exit
+
+    // need to extract into buffer
+    CFIndex length = CFStringGetLength(inStr);  // in 16-bit character units
+    size_t len = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8);
+    char *buffer = (char *)malloc(len);                 // pessimistic
+    if (!CFStringGetCString(inStr, buffer, len, kCFStringEncodingUTF8))
+        buffer[0] = 0;
+
+    CFRelease(inStr);
+    return buffer;
+}
+
+// runs operation with inStr as a zero terminated C string
+// in utf8 encoding passed to the operation block.
+void CFStringPerformWithCString(CFStringRef inStr, void(^operation)(const char *utf8Str));
+
+// runs operation with inStr as a zero terminated C string
+// in utf8 passed to the operation block, the length of
+// the string is also provided to the block.
+void CFStringPerformWithCStringAndLength(CFStringRef inStr, void(^operation)(const char *utf8Str, size_t utf8Length));
+
+#include <CommonNumerics/CommonCRC.h>
+
+static inline void CFStringAppendEncryptedData(CFMutableStringRef s, CFDataRef edata)
+{
+    const uint8_t *bytes = CFDataGetBytePtr(edata);
+    CFIndex len = CFDataGetLength(edata);
+    CFStringAppendFormat(s, 0, CFSTR("%04lx:"), len);
+    if(len<=8) {
+        for (CFIndex ix = 0; ix < len; ++ix) {
+            CFStringAppendFormat(s, 0, CFSTR("%02X"), bytes[ix]);
+        }
+    } else {
+        uint64_t crc = 0;
+        CNCRC(kCN_CRC_64_ECMA_182, bytes+8, len-8, &crc);
+        for (CFIndex ix = 0; ix < 8; ++ix) {
+            CFStringAppendFormat(s, 0, CFSTR("%02X"), bytes[ix]);
+        }
+        CFStringAppendFormat(s, 0, CFSTR("...|%08llx"), crc);
+    }
+}
+
+static inline void CFStringAppendHexData(CFMutableStringRef s, CFDataRef data) {
+    const uint8_t *bytes = CFDataGetBytePtr(data);
+    CFIndex len = CFDataGetLength(data);
+    for (CFIndex ix = 0; ix < len; ++ix) {
+        CFStringAppendFormat(s, 0, CFSTR("%02X"), bytes[ix]);
+    }
+}
+
+static inline CFStringRef CFDataCopyHexString(CFDataRef data) {
+    CFMutableStringRef hexString = CFStringCreateMutable(kCFAllocatorDefault, 2 * CFDataGetLength(data));
+    CFStringAppendHexData(hexString, data);
+    return hexString;
+}
+
+static inline void CFDataPerformWithHexString(CFDataRef data, void (^operation)(CFStringRef dataString)) {
+    CFStringRef hexString = CFDataCopyHexString(data);
+    operation(hexString);
+    CFRelease(hexString);
+}
+
+static inline void BufferPerformWithHexString(const UInt8 *bytes, CFIndex length, void (^operation)(CFStringRef dataString)) {
+    CFDataRef bufferAsData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, bytes, length, kCFAllocatorNull);
+    
+    CFDataPerformWithHexString(bufferAsData, operation);
+    
+    CFReleaseNull(bufferAsData);
+}
+
+
+
+static inline void CFStringWriteToFile(CFStringRef inStr, FILE* file)
+{
+    CFStringPerformWithCStringAndLength(inStr, ^(const char *utf8Str, size_t utf8Length) {
+        fwrite(utf8Str, 1, utf8Length, file);
+    });
+}
+
+static inline void CFStringWriteToFileWithNewline(CFStringRef inStr, FILE* file)
+{
+    CFStringWriteToFile(inStr, file);
+    fputc('\n', file);
+}
+
+//
+// MARK: CFArray Helpers
+//
+
+static inline CFIndex CFArrayRemoveAllValue(CFMutableArrayRef array, const void* value)
+{
+    CFIndex position = kCFNotFound;
+    CFIndex numberRemoved = 0;
+    
+    position = CFArrayGetFirstIndexOfValue(array, CFRangeMake(0, CFArrayGetCount(array)), value);
+    while (position != kCFNotFound) {
+        CFArrayRemoveValueAtIndex(array, position);
+        ++numberRemoved;
+        position = CFArrayGetFirstIndexOfValue(array, CFRangeMake(0, CFArrayGetCount(array)), value);
+    }
+    
+    return numberRemoved;
+}
+
+static inline void CFArrayForEach(CFArrayRef array, void (^operation)(const void *value)) {
+    CFArrayApplyFunction(array, CFRangeMake(0, CFArrayGetCount(array)), apply_block_1, operation);
+}
+
+static inline void CFArrayForEachReverse(CFArrayRef array, void (^operation)(const void *value)) {
+    for(CFIndex count = CFArrayGetCount(array); count > 0; --count) {
+        operation(CFArrayGetValueAtIndex(array, count - 1));
+    }
+}
+
+static inline const void *CFArrayGetValueMatching(CFArrayRef array, bool (^match)(const void *value)) {
+    CFIndex i, n = CFArrayGetCount(array);
+    for (i = 0; i < n; ++i) {
+        const void *value = CFArrayGetValueAtIndex(array, i);
+        if (match(value)) {
+            return value;
+        }
+    }
+    return NULL;
+}
+
+static inline bool CFArrayHasValueMatching(CFArrayRef array, bool (^match)(const void *value)) {
+    return CFArrayGetValueMatching(array, match) != NULL;
+}
+
+static inline void CFMutableArrayModifyValues(CFMutableArrayRef array, const void * (^process)(const void *value)) {
+    CFIndex i, n = CFArrayGetCount(array);
+    for (i = 0; i < n; ++i) {
+        const void *value = CFArrayGetValueAtIndex(array, i);
+        CFArraySetValueAtIndex(array, i, process(value));
+    }
+}
+
+//
+// MARK: CFArray creatino Var args helper functions.
+//
+static inline CFArrayRef CFArrayCreateCountedForVC(CFAllocatorRef allocator, const CFArrayCallBacks *cbs, CFIndex entries, va_list args)
+{
+    const void *values[entries];
+    
+    for(CFIndex currentValue = 0; currentValue < entries; ++currentValue)
+    {
+        values[currentValue] = va_arg(args, void*);
+        
+        if (values[currentValue] == NULL)
+            values[currentValue] = kCFNull;
+    }
+    
+    return CFArrayCreate(allocator, values, entries, cbs);
+}
+
+static inline CFArrayRef CFArrayCreateForVC(CFAllocatorRef allocator, const CFArrayCallBacks *cbs, va_list args)
+{
+    va_list count;
+    va_copy(count, args);
+
+    CFIndex entries = 0;
+    while (NULL != va_arg(count, void*)) {
+        entries += 1;
+    }
+
+    return CFArrayCreateCountedForVC(allocator, cbs, entries, args);
+    
+}
+
+//
+// MARK: CFArray of CFTypes support
+//
+
+static inline CFMutableArrayRef CFArrayCreateMutableForCFTypes(CFAllocatorRef allocator)
+{
+    return CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks);
+}
+
+static inline CFArrayRef CFArrayCreateForCFTypes(CFAllocatorRef allocator, ...)
+{
+    va_list args;
+    va_start(args, allocator);
+    
+    return CFArrayCreateForVC(allocator, &kCFTypeArrayCallBacks, args);
+    
+}
+
+static inline CFArrayRef CFArrayCreateCountedForCFTypes(CFAllocatorRef allocator, CFIndex entries, ...)
+{
+    va_list args;
+    va_start(args, entries);
+    
+    return CFArrayCreateCountedForVC(allocator, &kCFTypeArrayCallBacks, entries, args);
+}
+
+static inline CFArrayRef CFArrayCreateCountedForCFTypesV(CFAllocatorRef allocator, CFIndex entries, va_list args)
+{
+    return CFArrayCreateCountedForVC(allocator, &kCFTypeArrayCallBacks, entries, args);
+}
+
+//
+// MARK: CFDictionary of CFTypes helpers
+//
+
+static inline CFDictionaryRef CFDictionaryCreateCountedForCFTypesV(CFAllocatorRef allocator, CFIndex entries, va_list args)
+{
+    const void *keys[entries];
+    const void *values[entries];
+    
+    for(CFIndex currentValue = 0; currentValue < entries; ++currentValue)
+    {
+        keys[currentValue] = va_arg(args, void*);
+        values[currentValue] = va_arg(args, void*);
+        
+        if (values[currentValue] == NULL)
+            values[currentValue] = kCFNull;
+    }
+    
+    return CFDictionaryCreate(allocator, keys, values, entries,
+                              &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+}
+
+static inline CFDictionaryRef CFDictionaryCreateForCFTypes(CFAllocatorRef allocator, ...)
+{
+    va_list args;
+    va_start(args, allocator);
+
+    CFIndex entries = 0;
+    while (NULL != va_arg(args, void*)) {
+        entries += 2;
+        (void) va_arg(args, void*);
+    }
+
+    entries /= 2;
+
+    va_start(args, allocator);
+
+    return CFDictionaryCreateCountedForCFTypesV(allocator, entries, args);
+
+}
+
+static inline CFDictionaryRef CFDictionaryCreateCountedForCFTypes(CFAllocatorRef allocator, CFIndex entries, ...)
+{
+    va_list args;
+    va_start(args, entries);
+
+    return CFDictionaryCreateCountedForCFTypesV(allocator, entries, args);
+}
+
+static inline CFMutableDictionaryRef CFDictionaryCreateMutableForCFTypes(CFAllocatorRef allocator)
+{
+    return CFDictionaryCreateMutable(allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+}
+
+static inline CFMutableDictionaryRef CFDictionaryCreateMutableForCFTypesWith(CFAllocatorRef allocator, ...)
+{
+    CFMutableDictionaryRef result = CFDictionaryCreateMutableForCFTypes(allocator);
+
+    va_list args;
+    va_start(args, allocator);
+
+    void* key = va_arg(args, void*);
+
+    while (key != NULL) {
+        CFDictionarySetValue(result, key, va_arg(args, void*));
+        key = va_arg(args, void*);
+    };
+
+    return result;
+}
+
+//
+// MARK: CFDictionary Helpers
+//
+
+static inline void CFDictionaryForEach(CFDictionaryRef dictionary, void (^operation)(const void *key, const void *value)) {
+    CFDictionaryApplyFunction(dictionary, apply_block_2, operation);
+}
+
+//
+// Type checking
+//
+
+static inline bool isArray(CFTypeRef cfType) {
+    return cfType && CFGetTypeID(cfType) == CFArrayGetTypeID();
+}
+
+static inline bool isData(CFTypeRef cfType) {
+    return cfType && CFGetTypeID(cfType) == CFDataGetTypeID();
+}
+
+static inline bool isDate(CFTypeRef cfType) {
+    return cfType && CFGetTypeID(cfType) == CFDateGetTypeID();
+}
+
+static inline bool isDictionary(CFTypeRef cfType) {
+    return cfType && CFGetTypeID(cfType) == CFDictionaryGetTypeID();
+}
+
+static inline bool isNumber(CFTypeRef cfType) {
+    return cfType && CFGetTypeID(cfType) == CFNumberGetTypeID();
+}
+
+static inline bool isNumberOfType(CFTypeRef cfType, CFNumberType number) {
+    return isNumber(cfType) && CFNumberGetType((CFNumberRef)cfType) == number;
+}
+
+static inline bool isString(CFTypeRef cfType) {
+    return cfType && CFGetTypeID(cfType) == CFStringGetTypeID();
+}
+
+static inline bool isBoolean(CFTypeRef cfType) {
+    return cfType && CFGetTypeID(cfType) == CFBooleanGetTypeID();
+}
+
+static inline bool isNull(CFTypeRef cfType) {
+    return cfType && CFGetTypeID(cfType) == CFNullGetTypeID();
+}
+
+
+//
+// MARK: PropertyList Helpers
+//
+
+//
+// Crazy reading and writing stuff
+//
+
+static inline void CFPropertyListWriteToFile(CFPropertyListRef plist, CFURLRef file)
+{
+    CFWriteStreamRef writeStream = CFWriteStreamCreateWithFile(kCFAllocatorDefault, file);
+    CFErrorRef error = NULL;
+    
+    CFWriteStreamOpen(writeStream);
+    CFPropertyListWrite(plist, writeStream, kCFPropertyListBinaryFormat_v1_0, 0, &error);
+    if (error)
+        secerror("Can't write plist: %@", error);
+    
+    CFReleaseNull(error);
+    CFReleaseNull(writeStream);
+}
+
+static inline CF_RETURNS_RETAINED CFPropertyListRef CFPropertyListReadFromFile(CFURLRef file)
+{
+    CFPropertyListRef result = NULL;
+    CFErrorRef error = NULL;
+    CFBooleanRef isRegularFile;
+    if (!CFURLCopyResourcePropertyForKey(file, kCFURLIsRegularFileKey, &isRegularFile, &error)) {
+        secerror("file %@: %@", file, error);
+    } else if (CFBooleanGetValue(isRegularFile)) {
+        CFReadStreamRef readStream = CFReadStreamCreateWithFile(kCFAllocatorDefault, file);
+        if (readStream) {
+            if (CFReadStreamOpen(readStream)) {
+                CFPropertyListFormat format;
+                result = CFPropertyListCreateWithStream(kCFAllocatorDefault, readStream, 0, kCFPropertyListMutableContainers, &format, &error);
+                if (!result) {
+                    secerror("read plist from %@: %@", file, error);
+                }
+            }
+            CFRelease(readStream);
+        }
+    }
+    CFReleaseNull(error);
+    
+    return result;
+}
+
+__END_DECLS
+
+#endif
diff --git a/utilities/src/SecDb.c b/utilities/src/SecDb.c
new file mode 100644 (file)
index 0000000..e204d58
--- /dev/null
@@ -0,0 +1,1203 @@
+//
+//  SecDb.c
+//  utilities
+//
+//  Created by Michael Brouwer on 11/12/12.
+//  Copyright (c) 2012-2013 Apple Inc. All rights reserved.
+//
+
+#include "SecDb.h"
+#include "debugging.h"
+
+#include <sqlite3.h>
+#include <sqlite3_private.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <libgen.h>
+#include <sys/stat.h>
+#include <AssertMacros.h>
+#include "SecCFWrappers.h"
+#include "SecCFError.h"
+#include "SecIOFormat.h"
+#include <stdio.h>
+#include "Security/SecBase.h"
+
+#define LOGE(ARG,...) secerror(ARG, ## __VA_ARGS__)
+#define LOGV(ARG,...) secdebug("secdb", ARG, ## __VA_ARGS__)
+#define LOGD(ARG,...) secdebug("secdb", ARG, ## __VA_ARGS__)
+
+#define HAVE_UNLOCK_NOTIFY  0
+#define USE_BUSY_HANDLER  1
+
+struct __OpaqueSecDbStatement {
+    CFRuntimeBase _base;
+
+    SecDbConnectionRef dbconn;
+    sqlite3_stmt *stmt;
+};
+
+struct __OpaqueSecDbConnection {
+    CFRuntimeBase _base;
+
+    //CFMutableDictionaryRef statements;
+
+    SecDbRef db;     // NONRETAINED, since db or block retains us
+    bool readOnly;
+    bool inTransaction;
+    bool isCorrupted;
+    sqlite3 *handle;
+};
+
+struct __OpaqueSecDb {
+    CFRuntimeBase _base;
+
+    CFStringRef db_path;
+    dispatch_queue_t queue;
+    CFMutableArrayRef connections;
+    dispatch_semaphore_t write_semaphore;
+    dispatch_semaphore_t read_semaphore;
+    bool didFirstOpen;
+    bool (^opened)(SecDbConnectionRef dbconn, bool did_create, CFErrorRef *error);
+};
+
+// MARK: Error domains and error helper functions
+
+CFStringRef kSecDbErrorDomain = CFSTR("com.apple.utilities.sqlite3");
+
+bool SecDbError(int sql_code, CFErrorRef *error, CFStringRef format, ...) {
+    if (sql_code == SQLITE_OK) return true;
+    if (error) {
+        va_list args;
+        CFIndex code = sql_code;
+        CFErrorRef previousError = *error;
+
+        *error = NULL;
+        va_start(args, format);
+        SecCFCreateErrorWithFormatAndArguments(code, kSecDbErrorDomain, previousError, error, NULL, format, args);
+        va_end(args);
+    }
+    return false;
+}
+
+bool SecDbErrorWithDb(int sql_code, sqlite3 *db, CFErrorRef *error, CFStringRef format, ...) {
+    if (sql_code == SQLITE_OK) return true;
+    if (error) {
+        va_list args;
+        va_start(args, format);
+        CFStringRef message = CFStringCreateWithFormatAndArguments(kCFAllocatorDefault, NULL, format, args);
+        va_end(args);
+
+        int extended_code = sqlite3_extended_errcode(db);
+        if (sql_code == extended_code)
+            SecDbError(sql_code, error, CFSTR("%@: [%d] %s"), message, sql_code, sqlite3_errmsg(db));
+        else
+            SecDbError(sql_code, error, CFSTR("%@: [%d->%d] %s"), message, sql_code, extended_code, sqlite3_errmsg(db));
+        CFReleaseSafe(message);
+    }
+    return false;
+}
+
+bool SecDbErrorWithStmt(int sql_code, sqlite3_stmt *stmt, CFErrorRef *error, CFStringRef format, ...) {
+    if (sql_code == SQLITE_OK) return true;
+    if (error) {
+        va_list args;
+        va_start(args, format);
+        CFStringRef message = CFStringCreateWithFormatAndArguments(kCFAllocatorDefault, NULL, format, args);
+        va_end(args);
+
+        sqlite3 *db = sqlite3_db_handle(stmt);
+        const char *sql = sqlite3_sql(stmt);
+        int extended_code = sqlite3_extended_errcode(db);
+        if (sql_code == extended_code)
+            SecDbError(sql_code, error, CFSTR("%@: [%d] %s sql: %s"), message, sql_code, sqlite3_errmsg(db), sql);
+        else
+            SecDbError(sql_code, error, CFSTR("%@: [%d->%d] %s sql: %s"), message, sql_code, extended_code, sqlite3_errmsg(db), sql);
+        CFReleaseSafe(message);
+    }
+    return false;
+}
+
+
+// MARK: -
+// MARK: Static helper functions
+
+static bool SecDbOpenHandle(SecDbConnectionRef dbconn, bool *created, CFErrorRef *error);
+static bool SecDbHandleCorrupt(SecDbConnectionRef dbconn, int rc, CFErrorRef *error);
+
+#pragma mark -
+#pragma mark SecDbRef
+
+static CFStringRef
+SecDbCopyDescription(CFTypeRef value)
+{
+    SecDbRef db = (SecDbRef)value;
+    return CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("<SecDb path:%@ connections: %@>"), db->db_path, db->connections);
+}
+
+
+static void
+SecDbDestroy(CFTypeRef value)
+{
+    SecDbRef db = (SecDbRef)value;
+    CFReleaseSafe(db->connections);
+    CFReleaseSafe(db->db_path);
+    dispatch_release(db->queue);
+    dispatch_release(db->read_semaphore);
+    dispatch_release(db->write_semaphore);
+}
+
+CFGiblisFor(SecDb)
+
+SecDbRef
+SecDbCreate(CFStringRef dbName,
+            bool (^opened)(SecDbConnectionRef dbconn, bool did_create, CFErrorRef *error))
+{
+    SecDbRef db = NULL;
+
+    db = CFTypeAllocate(SecDb, struct __OpaqueSecDb, kCFAllocatorDefault);
+    require(db != NULL, done);
+
+    CFStringPerformWithCString(dbName, ^(const char *dbNameStr) {
+        db->queue = dispatch_queue_create(dbNameStr, DISPATCH_QUEUE_SERIAL);
+    });
+    db->read_semaphore = dispatch_semaphore_create(kSecDbMaxReaders);
+    db->write_semaphore = dispatch_semaphore_create(kSecDbMaxWriters);
+    db->connections = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
+    db->opened = opened;
+    if (getenv("__OSINSTALL_ENVIRONMENT") != NULL) {
+        // TODO: Move this code out of this layer
+        LOGV("sqlDb: running from installer");
+        db->db_path = CFSTR("file::memory:?cache=shared");
+    } else {
+        db->db_path = CFStringCreateCopy(kCFAllocatorDefault, dbName);
+    }
+done:
+    return db;
+}
+
+CFIndex
+SecDbIdleConnectionCount(SecDbRef db) {
+    __block CFIndex count = 0;
+    dispatch_sync(db->queue, ^{
+        count = CFArrayGetCount(db->connections);
+    });
+    return count;
+}
+
+
+#pragma mark -
+#pragma mark SecDbConnectionRef
+
+static bool SecDbCheckCorrupted(SecDbConnectionRef dbconn)
+{
+    __block bool isCorrupted = true;
+    __block CFErrorRef error = NULL;
+    SecDbPrepare(dbconn, CFSTR("PRAGMA integrity_check"), &error, ^(sqlite3_stmt *stmt) {
+        SecDbStep(dbconn, stmt, &error, ^(bool *stop) {
+            const char * result = (const char*)sqlite3_column_text(stmt, 0);
+            if (result && strncasecmp(result, "ok", 3) == 0) {
+                isCorrupted = false;
+            }
+        });
+    });
+    if (error) {
+        LOGV("sqlDb: warning error %@ when running integrity check", error);
+        CFRelease(error);
+    }
+    return isCorrupted;
+}
+
+static bool SecDbDidCreateFirstConnection(SecDbConnectionRef dbconn, bool didCreate, CFErrorRef *error)
+{
+    LOGD("sqlDb: starting maintenance");
+    bool ok = true;
+
+    if (!didCreate && !dbconn->isCorrupted) {
+        dbconn->isCorrupted = SecDbCheckCorrupted(dbconn);
+        if (dbconn->isCorrupted)
+            secerror("integrity check=fail");
+        else
+            LOGD("sqlDb: integrity check=pass");
+    }
+
+    if (!dbconn->isCorrupted && dbconn->db->opened) {
+        CFErrorRef localError = NULL;
+
+        ok = dbconn->db->opened(dbconn, didCreate, &localError);
+
+        if (!ok)
+            secerror("opened block failed: %@", localError);
+
+        if (!dbconn->isCorrupted && error && *error == NULL) {
+            *error = localError;
+            localError = NULL;
+        } else {
+            secerror("opened block failed: error is released and lost");
+            CFReleaseNull(localError);
+        }
+    }
+
+    if (dbconn->isCorrupted) {
+        ok = SecDbHandleCorrupt(dbconn, 0, error);
+    }
+
+    LOGD("sqlDb: finished maintenance");
+    return ok;
+}
+
+void SecDbCorrupt(SecDbConnectionRef dbconn)
+{
+    dbconn->isCorrupted = true;
+}
+
+
+static uint8_t knownDbPathIndex(SecDbConnectionRef dbconn)
+{
+
+    if(CFEqual(dbconn->db->db_path, CFSTR("/Library/Keychains/keychain-2.db")))
+        return 1;
+    if(CFEqual(dbconn->db->db_path, CFSTR("/Library/Keychains/ocspcache.sqlite3")))
+        return 2;
+    if(CFEqual(dbconn->db->db_path, CFSTR("/Library/Keychains/TrustStore.sqlite3")))
+        return 3;
+    if(CFEqual(dbconn->db->db_path, CFSTR("/Library/Keychains/caissuercache.sqlite3")))
+        return 4;
+
+    /* Unknown DB path */
+    return 0;
+}
+
+
+// Return true if there was no error, returns false otherwise and set *error to an appropriate CFErrorRef.
+static bool SecDbConnectionCheckCode(SecDbConnectionRef dbconn, int code, CFErrorRef *error, CFStringRef desc, ...) {
+    if (code == SQLITE_OK || code == SQLITE_DONE)
+        return true;
+
+    if (error) {
+        va_list args;
+        va_start(args, desc);
+        CFStringRef msg = CFStringCreateWithFormatAndArguments(kCFAllocatorDefault, NULL, desc, args);
+        va_end(args);
+        SecDbErrorWithDb(code, dbconn->handle, error, msg);
+        CFRelease(msg);
+    }
+
+    /* If it's already corrupted, don't try to recover */
+    if (dbconn->isCorrupted) {
+        CFStringRef reason = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("SQL DB %@ is corrupted already. Not trying to recover"), dbconn->db->db_path);
+        secerror("%@",reason);
+        __security_simulatecrash(reason, __sec_exception_code_TwiceCorruptDb(knownDbPathIndex(dbconn)));
+        CFReleaseSafe(reason);
+        return false;
+    }
+
+    dbconn->isCorrupted = (SQLITE_CORRUPT == code) || (SQLITE_NOTADB == code) || (SQLITE_IOERR == code) || (SQLITE_CANTOPEN == code);
+    if (dbconn->isCorrupted) {
+        /* Run integrity check and only make dbconn->isCorrupted true and
+           run the corruption handler if the integrity check conclusively fails. */
+        dbconn->isCorrupted = SecDbCheckCorrupted(dbconn);
+        if (dbconn->isCorrupted) {
+            secerror("operation returned code: %d integrity check=fail", code);
+            SecDbHandleCorrupt(dbconn, code, error);
+        } else {
+            secerror("operation returned code: %d: integrity check=pass", code);
+        }
+    }
+
+    return false;
+}
+
+#if HAVE_UNLOCK_NOTIFY
+
+static void SecDbUnlockNotify(void **apArg, int nArg) {
+    int i;
+    for(i=0; i<nArg; i++) {
+        dispatch_semaphore_t dsema = (dispatch_semaphore_t)apArg[i];
+        dispatch_semaphore_signal(dsema);
+    }
+}
+
+static bool SecDbWaitForUnlockNotify(SecDbConnectionRef dbconn, sqlite3_stmt *stmt, CFErrorRef *error) {
+    int rc;
+    dispatch_semaphore_t dsema = dispatch_semaphore_create(0);
+    rc = sqlite3_unlock_notify(dbconn->handle, SecDbUnlockNotify, dsema);
+    assert(rc == SQLITE_LOCKED || rc == SQLITE_OK);
+    if (rc == SQLITE_OK) {
+        dispatch_semaphore_wait(dsema, DISPATCH_TIME_FOREVER);
+    }
+    dispatch_release(dsema);
+    return (rc == SQLITE_OK
+            ? true
+            : (stmt
+               ? SecDbErrorWithStmt(rc, stmt, error, CFSTR("sqlite3_unlock_notify"))
+               : SecDbErrorWithDb(rc, dbconn->handle, error, CFSTR("sqlite3_unlock_notify"))));
+}
+
+#endif
+
+#if USE_BUSY_HANDLER
+
+// Return 0 to stop retrying.
+static int SecDbHandleBusy(void *ctx, int retryCount) {
+    SecDbConnectionRef dbconn __unused = ctx;
+    struct timespec sleeptime = { .tv_sec = 0, .tv_nsec = 10000 };
+    while (retryCount--) {
+        // Double sleeptime until we hit one second then add one
+        // second more every time we sleep.
+        if (sleeptime.tv_sec) {
+            sleeptime.tv_sec++;
+        } else {
+            sleeptime.tv_nsec *= 2;
+            if (sleeptime.tv_nsec > NSEC_PER_SEC) {
+                sleeptime.tv_nsec = 0;
+                sleeptime.tv_sec++;
+            }
+        }
+    }
+    struct timespec unslept = {};
+    nanosleep(&sleeptime, &unslept);
+
+    return 1;
+}
+
+static bool SecDbBusyHandler(SecDbConnectionRef dbconn, CFErrorRef *error) {
+    return SecDbErrorWithDb(sqlite3_busy_handler(dbconn->handle, SecDbHandleBusy, dbconn), dbconn->handle, error, CFSTR("busy_handler"));
+}
+
+#endif // USE_BUSY_HANDLER
+
+// Return true causes the operation to be tried again.
+static bool SecDbWaitIfNeeded(SecDbConnectionRef dbconn, int s3e, sqlite3_stmt *stmt, CFStringRef desc, struct timespec *sleeptime, CFErrorRef *error) {
+#if HAVE_UNLOCK_NOTIFY
+    if (s3e == SQLITE_LOCKED) { // Optionally check for extended code being SQLITE_LOCKED_SHAREDCACHE
+        return SecDbWaitForUnlockNotify(dbconn, stmt, error))
+    }
+#endif
+
+#if !USE_BUSY_HANDLER
+    if (s3e == SQLITE_LOCKED || s3e == SQLITE_BUSY) {
+        LOGV("sqlDb: %s", sqlite3_errmsg(dbconn->handle));
+        while (s3e == SQLITE_LOCKED || s3e == SQLITE_BUSY) {
+            struct timespec unslept = {};
+            nanosleep(sleeptime, &unslept);
+            s3e = SQLITE_OK;
+            if (stmt)
+                s3e = sqlite3_reset(stmt);
+
+            // Double sleeptime until we hit one second the add one
+            // second more every time we sleep.
+            if (sleeptime->tv_sec) {
+                sleeptime->tv_sec++;
+            } else {
+                sleeptime->tv_nsec *= 2;
+                if (sleeptime->tv_nsec > NSEC_PER_SEC) {
+                    sleeptime->tv_nsec = 0;
+                    sleeptime->tv_sec++;
+                }
+            }
+        }
+        if (s3e)
+            return SecDbErrorWithStmt(s3e, stmt, error, CFSTR("reset"));
+    } else
+#endif // !USE_BUSY_HANDLER
+    {
+        return SecDbConnectionCheckCode(dbconn, s3e, error, desc);
+    }
+    return true;
+}
+
+enum SecDbStepResult {
+    kSecDbErrorStep = 0,
+    kSecDbRowStep = 1,
+    kSecDbDoneStep = 2,
+};
+typedef enum SecDbStepResult SecDbStepResult;
+
+static SecDbStepResult _SecDbStep(SecDbConnectionRef dbconn, sqlite3_stmt *stmt, CFErrorRef *error) {
+    assert(stmt != NULL);
+    int s3e;
+    struct timespec sleeptime = { .tv_sec = 0, .tv_nsec = 10000 };
+    for (;;) {
+        s3e = sqlite3_step(stmt);
+        if (s3e == SQLITE_ROW)
+            return kSecDbRowStep;
+        else if (s3e == SQLITE_DONE)
+            return kSecDbDoneStep;
+        else if (!SecDbWaitIfNeeded(dbconn, s3e, stmt, CFSTR("step"), &sleeptime, error))
+            return kSecDbErrorStep;
+    };
+}
+
+bool
+SecDbExec(SecDbConnectionRef dbconn, CFStringRef sql, CFErrorRef *error)
+{
+    bool ok = true;
+    CFRetain(sql);
+    while (sql) {
+        CFStringRef tail = NULL;
+        if (ok) {
+            sqlite3_stmt *stmt = SecDbCopyStmt(dbconn, sql, &tail, error);
+            ok = stmt != NULL;
+            if (stmt) {
+                SecDbStepResult sr;
+                while ((sr = _SecDbStep(dbconn, stmt, error)) == kSecDbRowStep);
+                if (sr == kSecDbErrorStep)
+                    ok = false;
+                ok &= SecDbReleaseCachedStmt(dbconn, sql, stmt, error);
+            }
+        } else {
+            // TODO We already have an error here we really just want the left over sql in it's userData
+            ok = SecDbError(SQLITE_ERROR, error, CFSTR("Error with unexecuted sql remaining %@"), sql);
+        }
+        CFRelease(sql);
+        sql = tail;
+    }
+    return ok;
+}
+
+static bool SecDbBeginTransaction(SecDbConnectionRef dbconn, SecDbTransactionType type, CFErrorRef *error)
+{
+    bool ok = true;
+    CFStringRef query;
+    switch (type) {
+        case kSecDbImmediateTransactionType:
+            query = CFSTR("BEGIN IMMEDATE");
+            break;
+        case kSecDbExclusiveTransactionType:
+            query = CFSTR("BEGIN EXCLUSIVE");
+            break;
+        case kSecDbNormalTransactionType:
+            query = CFSTR("BEGIN");
+            break;
+        default:
+            ok = SecDbError(SQLITE_ERROR, error, CFSTR("invalid transaction type %" PRIu32), type);
+            query = NULL;
+            break;
+    }
+
+    if (query != NULL && sqlite3_get_autocommit(dbconn->handle) != 0) {
+        ok = SecDbExec(dbconn, query, error);
+    }
+
+    return ok;
+}
+
+static bool SecDbEndTransaction(SecDbConnectionRef dbconn, bool commit, CFErrorRef *error)
+{
+    if (commit) {
+        return SecDbExec(dbconn, CFSTR("END"), error);
+    } else {
+        return SecDbExec(dbconn, CFSTR("ROLLBACK"), error);
+    }
+}
+
+bool SecDbTransaction(SecDbConnectionRef dbconn, SecDbTransactionType type,
+                      CFErrorRef *error, void (^transaction)(bool *commit))
+{
+    bool ok = true;
+    bool commit = true;
+
+    if (dbconn->inTransaction) {
+        transaction(&commit);
+        if (!commit) {
+            LOGV("sqlDb: nested transaction asked to not be committed");
+        }
+    } else {
+        ok = SecDbBeginTransaction(dbconn, type, error);
+        if (ok) {
+            dbconn->inTransaction = true;
+            transaction(&commit);
+            dbconn->inTransaction = false;
+            ok = SecDbEndTransaction(dbconn, commit, error);
+        }
+    }
+
+done:
+    return ok && commit;
+}
+
+sqlite3 *SecDbHandle(SecDbConnectionRef dbconn) {
+    return dbconn->handle;
+}
+
+bool SecDbStep(SecDbConnectionRef dbconn, sqlite3_stmt *stmt, CFErrorRef *error, void (^row)(bool *stop)) {
+    for (;;) {
+        switch (_SecDbStep(dbconn, stmt, error)) {
+            case kSecDbErrorStep:
+                return false;
+            case kSecDbRowStep:
+                if (row) {
+                    bool stop = false;
+                    row(&stop);
+                    if (stop)
+                        return true;
+                    break;
+                }
+                SecDbError(SQLITE_ERROR, error, CFSTR("SecDbStep SQLITE_ROW returned without a row handler"));
+                return false;
+            case kSecDbDoneStep:
+                return true;
+        }
+    }
+}
+
+bool SecDbCheckpoint(SecDbConnectionRef dbconn, CFErrorRef *error)
+{
+    return SecDbConnectionCheckCode(dbconn, sqlite3_wal_checkpoint(dbconn->handle, NULL), error, CFSTR("wal_checkpoint"));
+}
+
+static bool SecDbFileControl(SecDbConnectionRef dbconn, int op, void *arg, CFErrorRef *error) {
+    return SecDbConnectionCheckCode(dbconn, sqlite3_file_control(dbconn->handle, NULL, op, arg), error, CFSTR("file_control"));
+}
+
+static sqlite3 *_SecDbOpenV2(const char *path, int flags, CFErrorRef *error) {
+#if HAVE_UNLOCK_NOTIFY
+    flags |= SQLITE_OPEN_SHAREDCACHE;
+#endif
+    sqlite3 *handle = NULL;
+    int s3e = sqlite3_open_v2(path, &handle, flags, NULL);
+    if (s3e) {
+        if (handle) {
+            SecDbErrorWithDb(s3e, handle, error, CFSTR("open_v2 \"%s\" 0x%X"), path, flags);
+            sqlite3_close(handle);
+            handle = NULL;
+        } else {
+            SecDbError(s3e, error, CFSTR("open_v2 \"%s\" 0x%X"), path, flags);
+        }
+    }
+    return handle;
+}
+
+static bool SecDbOpenV2(SecDbConnectionRef dbconn, const char *path, int flags, CFErrorRef *error) {
+    return (dbconn->handle = _SecDbOpenV2(path, flags, error)) != NULL;
+}
+
+static bool SecDbTruncate(SecDbConnectionRef dbconn, CFErrorRef *error)
+{
+    int flags = SQLITE_TRUNCATE_JOURNALMODE_WAL | SQLITE_TRUNCATE_AUTOVACUUM_FULL;
+    __block bool ok = SecDbFileControl(dbconn, SQLITE_TRUNCATE_DATABASE, &flags, error);
+    if (!ok) {
+        sqlite3_close(dbconn->handle);
+        dbconn->handle = NULL;
+        CFStringPerformWithCString(dbconn->db->db_path, ^(const char *path) {
+            if (error)
+                CFReleaseNull(*error);
+            if (SecCheckErrno(unlink(path), error, CFSTR("unlink %s"), path)) {
+                ok = SecDbOpenHandle(dbconn, NULL, error);
+            }
+        });
+        if (!ok) {
+            secerror("Failed to delete db handle: %@", error ? *error : NULL);
+            abort();
+        }
+    }
+
+    return ok;
+}
+
+static bool SecDbHandleCorrupt(SecDbConnectionRef dbconn, int rc, CFErrorRef *error)
+{
+    CFStringRef reason = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("SQL DB %@ is corrupted, trying to recover (rc=%d)"), dbconn->db->db_path, rc);
+    __security_simulatecrash(reason, __sec_exception_code_CorruptDb(knownDbPathIndex(dbconn), rc));
+    CFReleaseSafe(reason);
+
+    // Backup current db.
+    __block bool didRename = false;
+    CFStringPerformWithCString(dbconn->db->db_path, ^(const char *db_path) {
+        sqlite3 *corrupt_db = NULL;
+        char buf[PATH_MAX+1];
+        snprintf(buf, sizeof(buf), "%s-corrupt", db_path);
+        if (dbconn->handle && (corrupt_db = _SecDbOpenV2(buf, SQLITE_OPEN_READWRITE, error))) {
+            int on = 1;
+            didRename =  SecDbErrorWithDb(sqlite3_file_control(corrupt_db, NULL, SQLITE_FCNTL_PERSIST_WAL, &on), corrupt_db, error, CFSTR("persist wal"));
+            didRename &=  SecDbErrorWithDb(sqlite3_file_control(corrupt_db, NULL, SQLITE_REPLACE_DATABASE, (void *)dbconn->handle), corrupt_db, error, CFSTR("replace database"));
+            sqlite3_close(corrupt_db);
+        }
+        if (!didRename) {
+            if (dbconn->handle)
+                secerror("Tried to rename corrupt database at path %@, but we failed: %@, trying explicit rename", dbconn->db->db_path, error ? *error : NULL);
+            if (error)
+                CFReleaseNull(*error);
+
+            didRename = SecCheckErrno(rename(db_path, buf), error, CFSTR("rename %s %s"), db_path, buf) &&
+                (!dbconn->handle || SecDbError(sqlite3_close(dbconn->handle), error, CFSTR("close"))) &&
+                SecDbOpenHandle(dbconn, NULL, error);
+        }
+        if (didRename) {
+            secerror("Database at path %@ is corrupt. Copied it to %s for further investigation.", dbconn->db->db_path, buf);
+        } else {
+            seccritical("Tried to copy corrupt database at path %@, but we failed: %@", dbconn->db->db_path, error ? *error : NULL);
+        }
+    });
+
+    bool ok = (didRename &&
+               (dbconn->handle || SecDbOpenHandle(dbconn, NULL, error)) &&
+               SecDbTruncate(dbconn, error));
+
+    // Mark the db as not corrupted, even if something failed.
+    // Always note we are no longer in the corruption handler
+    dbconn->isCorrupted = false;
+
+    // Invoke our callers opened callback, since we just created a new database
+    if (ok && dbconn->db->opened)
+        ok = dbconn->db->opened(dbconn, true, error);
+
+    return ok;
+}
+
+static bool SecDbProfileEnabled(void)
+{
+#if 0
+    static dispatch_once_t onceToken;
+    static bool profile_enabled = false;
+    
+#if DEBUG
+    //sudo defaults write /Library/Preferences/com.apple.security.auth profile -bool true
+    dispatch_once(&onceToken, ^{
+               CFTypeRef profile = (CFNumberRef)CFPreferencesCopyValue(CFSTR("profile"), CFSTR(SECURITY_AUTH_NAME), kCFPreferencesAnyUser, kCFPreferencesCurrentHost);
+        
+        if (profile && CFGetTypeID(profile) == CFBooleanGetTypeID()) {
+            profile_enabled = CFBooleanGetValue((CFBooleanRef)profile);
+        }
+        
+        LOGV("sqlDb: sql profile: %s", profile_enabled ? "enabled" : "disabled");
+        
+        CFReleaseSafe(profile);
+    });
+#endif
+    
+    return profile_enabled;
+#else
+#if DEBUG
+    return true;
+#else
+    return false;
+#endif
+#endif
+}
+
+#if 0
+static void SecDbProfile(void *context __unused, const char *sql, sqlite3_uint64 ns) {
+    LOGV("==\nsqlDb: %s\nTime: %llu ms\n", sql, ns >> 20);
+}
+#else
+static void SecDbProfile(void *context, const char *sql, sqlite3_uint64 ns) {
+    sqlite3 *s3h = context;
+    int code = sqlite3_extended_errcode(s3h);
+    if (code == SQLITE_OK || code == SQLITE_DONE) {
+        secdebug("profile", "==\nsqlDb: %s\nTime: %llu ms\n", sql, ns >> 20);
+    } else {
+        secdebug("profile", "==error[%d]: %s==\nsqlDb: %s\nTime: %llu ms \n", code, sqlite3_errmsg(s3h), sql, ns >> 20);
+    }
+}
+#endif
+
+static bool SecDbTraceEnabled(void)
+{
+#if DEBUG
+    return true;
+#else
+    return false;
+#endif
+}
+
+static void SecDbTrace(void *ctx, const char *trace) {
+    SecDbConnectionRef dbconn __unused = ctx;
+    static dispatch_queue_t queue;
+    static dispatch_once_t once;
+    dispatch_once(&once, ^{
+        queue = dispatch_queue_create("trace_queue", DISPATCH_QUEUE_SERIAL);
+    });
+    dispatch_sync(queue, ^{
+        __security_debug(CFSTR("trace"), "", "", 0, CFSTR("%s"), trace);
+    });
+}
+
+static bool SecDbOpenHandle(SecDbConnectionRef dbconn, bool *created, CFErrorRef *error)
+{
+    __block bool ok = true;
+    CFStringPerformWithCString(dbconn->db->db_path, ^(const char *db_path) {
+        ok = created && SecDbOpenV2(dbconn, db_path, SQLITE_OPEN_READWRITE, NULL);
+        if (!ok) {
+            ok = true;
+            if (created) {
+                char *tmp = dirname((char *)db_path);
+                if (tmp) {
+                    int errnum = mkpath_np(tmp, 0700);
+                    if (errnum != 0 && errnum != EEXIST) {
+                        SecCFCreateErrorWithFormat(errnum, kSecErrnoDomain, NULL, error, NULL,
+                                                   CFSTR("mkpath_np %s: [%d] %s"), tmp, errnum, strerror(errnum));
+                        ok = false;
+                    }
+                }
+            }
+            ok = ok && SecDbOpenV2(dbconn, db_path, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, error);
+            if (ok) {
+                chmod(db_path, S_IRUSR | S_IWUSR);
+                if (created)
+                    *created = true;
+            }
+        }
+
+        if (ok && SecDbProfileEnabled()) {
+            sqlite3_profile(dbconn->handle, SecDbProfile, dbconn->handle);
+        }
+        if (ok && SecDbTraceEnabled()) {
+            sqlite3_trace(dbconn->handle, SecDbTrace, dbconn);
+        }
+#if USE_BUSY_HANDLER
+        ok = ok && SecDbBusyHandler(dbconn, error);
+#endif
+    });
+
+done:
+    return ok;
+}
+
+static SecDbConnectionRef
+SecDbConnectionCreate(SecDbRef db, bool readOnly, CFErrorRef *error)
+{
+    SecDbConnectionRef dbconn = NULL;
+
+    dbconn = CFTypeAllocate(SecDbConnection, struct __OpaqueSecDbConnection, kCFAllocatorDefault);
+    require(dbconn != NULL, done);
+
+    dbconn->db = db;
+    dbconn->readOnly = readOnly;
+
+done:
+    return dbconn;
+}
+
+static bool SecDbConnectionIsReadOnly(SecDbConnectionRef dbconn) {
+    return dbconn->readOnly;
+}
+
+static void SecDbConectionSetReadOnly(SecDbConnectionRef dbconn, bool readOnly) {
+    dbconn->readOnly = readOnly;
+}
+
+/* Read only connections go to the end of the queue, writeable connections
+ go to the start of the queue. */
+SecDbConnectionRef SecDbConnectionAquire(SecDbRef db, bool readOnly, CFErrorRef *error) {
+    CFRetain(db);
+    secdebug("dbconn", "aquire %s connection", readOnly ? "ro" : "rw");
+    dispatch_semaphore_wait(readOnly ? db->read_semaphore : db->write_semaphore, DISPATCH_TIME_FOREVER);
+    __block SecDbConnectionRef dbconn = NULL;
+    __block bool ok = true;
+    dispatch_sync(db->queue, ^{
+        if (!db->didFirstOpen) {
+            bool didCreate = false;
+            ok = dbconn = SecDbConnectionCreate(db, false, error);
+            CFErrorRef localError = NULL;
+            if (ok && !SecDbOpenHandle(dbconn, &didCreate, &localError)) {
+                secerror("Unable to create database: %@", localError);
+                if (localError && CFEqual(CFErrorGetDomain(localError), kSecDbErrorDomain)) {
+                    int code = (int)CFErrorGetCode(localError);
+                    dbconn->isCorrupted = (SQLITE_CORRUPT == code) || (SQLITE_NOTADB == code) || (SQLITE_IOERR == code) || (SQLITE_CANTOPEN == code);
+                }
+                // If the open failure isn't due to corruption, propagte the error.
+                ok = dbconn->isCorrupted;
+                if (!ok && error && *error == NULL) {
+                    *error = localError;
+                    localError = NULL;
+                }
+            }
+            CFReleaseNull(localError);
+
+            if (ok)
+                db->didFirstOpen = ok = SecDbDidCreateFirstConnection(dbconn, didCreate, error);
+            if (!ok)
+                CFReleaseNull(dbconn);
+        } else {
+            /* Try to get one from the cache */
+            CFIndex count = CFArrayGetCount(db->connections);
+            while (count && !dbconn) {
+                CFIndex ix = readOnly ? count - 1 : 0;
+                dbconn = (SecDbConnectionRef)CFArrayGetValueAtIndex(db->connections, ix);
+                if (dbconn)
+                    CFRetain(dbconn);
+                else
+                    secerror("got NULL dbconn at index: %" PRIdCFIndex " skipping", ix);
+                CFArrayRemoveValueAtIndex(db->connections, ix);
+            }
+        }
+    });
+
+    if (dbconn) {
+        /* Make sure the connection we found has the right access */
+        if (SecDbConnectionIsReadOnly(dbconn) != readOnly) {
+            SecDbConectionSetReadOnly(dbconn, readOnly);
+        }
+    } else if (ok) {
+        /* Nothing found in cache, create a new connection */
+        bool created = false;
+        dbconn = SecDbConnectionCreate(db, readOnly, error);
+        if (dbconn && !SecDbOpenHandle(dbconn, &created, error)) {
+            CFReleaseNull(dbconn);
+        }
+    }
+
+    if (!dbconn) {
+        // If aquire fails we need to signal the semaphore again.
+        dispatch_semaphore_signal(readOnly ? db->read_semaphore : db->write_semaphore);
+        CFRelease(db);
+    }
+
+    return dbconn;
+}
+
+void SecDbConnectionRelease(SecDbConnectionRef dbconn) {
+    if (!dbconn) {
+        secerror("called with NULL dbconn");
+        return;
+    }
+    SecDbRef db = dbconn->db;
+    secdebug("dbconn", "release %@", dbconn);
+    dispatch_sync(db->queue, ^{
+        CFIndex count = CFArrayGetCount(db->connections);
+        // Add back possible writable dbconn to the pool.
+        bool readOnly = SecDbConnectionIsReadOnly(dbconn);
+        CFArrayInsertValueAtIndex(db->connections, readOnly ? count : 0, dbconn);
+        // Remove the last (probably read-only) dbconn from the pool.
+        if (count >= kSecDbMaxIdleHandles) {
+            CFArrayRemoveValueAtIndex(db->connections, count);
+        }
+        // Signal after we have put the connection back in the pool of connections
+        dispatch_semaphore_signal(readOnly ? db->read_semaphore : db->write_semaphore);
+        CFRelease(dbconn);
+        CFRelease(db);
+    });
+}
+
+bool SecDbPerformRead(SecDbRef db, CFErrorRef *error, void (^perform)(SecDbConnectionRef dbconn)) {
+    SecDbConnectionRef dbconn = SecDbConnectionAquire(db, true, error);
+    bool success = false;
+    if (dbconn) {
+        perform(dbconn);
+        success = true;
+        SecDbConnectionRelease(dbconn);
+    }
+    return success;
+}
+
+bool SecDbPerformWrite(SecDbRef db, CFErrorRef *error, void (^perform)(SecDbConnectionRef dbconn)) {
+    SecDbConnectionRef dbconn = SecDbConnectionAquire(db, false, error);
+    bool success = false;
+    if (dbconn) {
+        perform(dbconn);
+        success = true;
+        SecDbConnectionRelease(dbconn);
+    }
+    return success;
+}
+
+static CFStringRef
+SecDbConnectionCopyDescription(CFTypeRef value)
+{
+    SecDbConnectionRef dbconn = (SecDbConnectionRef)value;
+    return CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("<SecDbConnection %s %s>"),
+                                    dbconn->readOnly ? "ro" : "rw", dbconn->handle ? "open" : "closed");
+}
+
+static void
+SecDbConnectionDestroy(CFTypeRef value)
+{
+    SecDbConnectionRef dbconn = (SecDbConnectionRef)value;
+    if (dbconn->handle) {
+        sqlite3_close(dbconn->handle);
+    }
+    dbconn->db = NULL;
+}
+
+
+// MARK: -
+// MARK: Bind helpers
+
+#if 0
+bool SecDbBindNull(sqlite3_stmt *stmt, int param, CFErrorRef *error) {
+    bool ok = SecDbErrorWithStmt(sqlite3_bind_null(stmt, param),
+                                 stmt, error, CFSTR("bind_null[%d]"), param);
+    secdebug("bind", "bind_null[%d]: %@", param, error ? *error : NULL);
+    return ok;
+}
+#endif
+
+bool SecDbBindBlob(sqlite3_stmt *stmt, int param, const void *zData, size_t n, void(*xDel)(void*), CFErrorRef *error) {
+    if (n > INT_MAX) {
+        return SecDbErrorWithStmt(SQLITE_TOOBIG, stmt, error,
+                                  CFSTR("bind_blob[%d]: blob bigger than INT_MAX"), param);
+    }
+    bool ok = SecDbErrorWithStmt(sqlite3_bind_blob(stmt, param, zData, (int)n, xDel),
+                                 stmt, error, CFSTR("bind_blob[%d]"), param);
+    secdebug("bind", "bind_blob[%d]: %.*s: %@", param, (int)n, zData, error ? *error : NULL);
+    return ok;
+}
+
+bool SecDbBindText(sqlite3_stmt *stmt, int param, const char *zData, size_t n, void(*xDel)(void*), CFErrorRef *error) {
+    if (n > INT_MAX) {
+        return SecDbErrorWithStmt(SQLITE_TOOBIG, stmt, error,
+                                  CFSTR("bind_text[%d]: text bigger than INT_MAX"), param);
+    }
+    bool ok = SecDbErrorWithStmt(sqlite3_bind_text(stmt, param, zData, (int)n, xDel), stmt, error,
+                                 CFSTR("bind_text[%d]"), param);
+    secdebug("bind", "bind_text[%d]: \"%s\": %@", param, zData, error ? *error : NULL);
+    return ok;
+}
+
+bool SecDbBindDouble(sqlite3_stmt *stmt, int param, double value, CFErrorRef *error) {
+    bool ok = SecDbErrorWithStmt(sqlite3_bind_double(stmt, param, value), stmt, error,
+                                 CFSTR("bind_double[%d]"), param);
+    secdebug("bind", "bind_double[%d]: %f: %@", param, value, error ? *error : NULL);
+    return ok;
+}
+
+bool SecDbBindInt(sqlite3_stmt *stmt, int param, int value, CFErrorRef *error) {
+    bool ok = SecDbErrorWithStmt(sqlite3_bind_int(stmt, param, value), stmt, error,
+                                 CFSTR("bind_int[%d]"), param);
+    secdebug("bind", "bind_int[%d]: %d: %@", param, value, error ? *error : NULL);
+    return ok;
+}
+
+bool SecDbBindInt64(sqlite3_stmt *stmt, int param, sqlite3_int64 value, CFErrorRef *error) {
+    bool ok = SecDbErrorWithStmt(sqlite3_bind_int64(stmt, param, value), stmt, error,
+                                 CFSTR("bind_int64[%d]"), param);
+    secdebug("bind", "bind_int64[%d]: %lld: %@", param, value, error ? *error : NULL);
+    return ok;
+}
+
+
+/* AUDIT[securityd](done):
+ value (ok) is a caller provided, non NULL CFTypeRef.
+ */
+bool SecDbBindObject(sqlite3_stmt *stmt, int param, CFTypeRef value, CFErrorRef *error) {
+    CFTypeID valueId;
+    __block bool result = false;
+
+       /* TODO: Can we use SQLITE_STATIC below everwhere we currently use
+     SQLITE_TRANSIENT since we finalize the statement before the value
+     goes out of scope? */
+    if (!value || (valueId = CFGetTypeID(value)) == CFNullGetTypeID()) {
+        /* Skip bindings for NULL values.  sqlite3 will interpret unbound
+         params as NULL which is exactly what we want. */
+#if 1
+        result = true;
+#else
+        result = SecDbBindNull(stmt, param, error);
+#endif
+    } else if (valueId == CFStringGetTypeID()) {
+        CFStringPerformWithCStringAndLength(value, ^(const char *cstr, size_t clen) {
+            result = SecDbBindText(stmt, param, cstr, clen, SQLITE_TRANSIENT, error);
+        });
+    } else if (valueId == CFDataGetTypeID()) {
+        CFIndex len = CFDataGetLength(value);
+        if (len) {
+            result = SecDbBindBlob(stmt, param, CFDataGetBytePtr(value),
+                                   len, SQLITE_TRANSIENT, error);
+        } else {
+            result = SecDbBindText(stmt, param, "", 0, SQLITE_TRANSIENT, error);
+        }
+    } else if (valueId == CFDateGetTypeID()) {
+        CFAbsoluteTime abs_time = CFDateGetAbsoluteTime(value);
+        result = SecDbBindDouble(stmt, param, abs_time, error);
+    } else if (valueId == CFBooleanGetTypeID()) {
+        int bval = CFBooleanGetValue(value);
+        result = SecDbBindInt(stmt, param, bval, error);
+    } else if (valueId == CFNumberGetTypeID()) {
+        Boolean convertOk;
+        if (CFNumberIsFloatType(value)) {
+            double nval;
+            convertOk = CFNumberGetValue(value, kCFNumberDoubleType, &nval);
+            result = SecDbBindDouble(stmt, param, nval, error);
+        } else {
+            int nval;
+            convertOk = CFNumberGetValue(value, kCFNumberSInt32Type, &nval);
+            if (convertOk) {
+                result = SecDbBindInt(stmt, param, nval, error);
+            } else {
+                sqlite_int64 nval64;
+                convertOk = CFNumberGetValue(value, kCFNumberSInt64Type, &nval64);
+                if (convertOk)
+                    result = SecDbBindInt64(stmt, param, nval64, error);
+            }
+        }
+        if (!convertOk) {
+            result = SecDbError(SQLITE_INTERNAL, error, CFSTR("bind CFNumberGetValue failed for %@"), value);
+        }
+    } else {
+        if (error) {
+            CFStringRef valueDesc = CFCopyTypeIDDescription(valueId);
+            SecDbError(SQLITE_MISMATCH, error, CFSTR("bind unsupported type %@"), valueDesc);
+            CFReleaseSafe(valueDesc);
+        }
+    }
+
+       return result;
+}
+
+// MARK: -
+// MARK: SecDbStatementRef
+
+bool SecDbReset(sqlite3_stmt *stmt, CFErrorRef *error) {
+    return SecDbErrorWithStmt(sqlite3_reset(stmt), stmt, error, CFSTR("reset"));
+}
+
+bool SecDbClearBindings(sqlite3_stmt *stmt, CFErrorRef *error) {
+    return SecDbErrorWithStmt(sqlite3_clear_bindings(stmt), stmt, error, CFSTR("clear bindings"));
+}
+
+bool SecDbFinalize(sqlite3_stmt *stmt, CFErrorRef *error) {
+    int s3e = sqlite3_finalize(stmt);
+    return s3e == SQLITE_OK ? true : SecDbErrorWithDb(s3e, sqlite3_db_handle(stmt), error, CFSTR("finalize: %p"), stmt);
+}
+
+sqlite3_stmt *SecDbPrepareV2(SecDbConnectionRef dbconn, const char *sql, size_t sqlLen, const char **sqlTail, CFErrorRef *error) {
+    sqlite3 *db = SecDbHandle(dbconn);
+    if (sqlLen > INT_MAX) {
+        SecDbErrorWithDb(SQLITE_TOOBIG, db, error, CFSTR("prepare_v2: sql bigger than INT_MAX"));
+        return NULL;
+    }
+    struct timespec sleeptime = { .tv_sec = 0, .tv_nsec = 10000 };
+    for (;;) {
+        sqlite3_stmt *stmt = NULL;
+        int s3e = sqlite3_prepare_v2(db, sql, (int)sqlLen, &stmt, sqlTail);
+        if (s3e == SQLITE_OK)
+            return stmt;
+        else if (!SecDbWaitIfNeeded(dbconn, s3e, NULL, CFSTR("preparev2"), &sleeptime, error))
+            return NULL;
+    }
+}
+
+static sqlite3_stmt *SecDbCopyStatementWithTailRange(SecDbConnectionRef dbconn, CFStringRef sql, CFRange *sqlTail, CFErrorRef *error) {
+    __block sqlite3_stmt *stmt = NULL;
+    if (sql) CFStringPerformWithCStringAndLength(sql, ^(const char *sqlStr, size_t sqlLen) {
+        const char *tail = NULL;
+        stmt = SecDbPrepareV2(dbconn, sqlStr, sqlLen, &tail, error);
+        if (sqlTail && sqlStr < tail && tail < sqlStr + sqlLen) {
+            sqlTail->location = tail - sqlStr;
+            sqlTail->length = sqlLen - sqlTail->location;
+        }
+    });
+
+    return stmt;
+}
+
+sqlite3_stmt *SecDbCopyStmt(SecDbConnectionRef dbconn, CFStringRef sql, CFStringRef *tail, CFErrorRef *error) {
+    // TODO: Add caching and cache lookup of statements
+    CFRange sqlTail = {};
+    sqlite3_stmt *stmt = SecDbCopyStatementWithTailRange(dbconn, sql, &sqlTail, error);
+    if (sqlTail.length > 0) {
+        CFStringRef excess = CFStringCreateWithSubstring(CFGetAllocator(sql), sql, sqlTail);
+        if (tail) {
+            *tail = excess;
+        } else {
+            SecDbError(SQLITE_INTERNAL, error,
+                       CFSTR("prepare_v2: %@ unused sql: %@"),
+                       sql, excess);
+            CFReleaseSafe(excess);
+            SecDbFinalize(stmt, error);
+            stmt = NULL;
+        }
+    }
+    return stmt;
+}
+
+/*
+ TODO: Could do a hack here with a custom kCFAllocatorNULL allocator for a second CFRuntimeBase inside a SecDbStatement,
+ TODO: Better yet make a full blow SecDbStatement instance whenever SecDbCopyStmt is called.  Then, when the statement is released, in the Dispose method, we Reset and ClearBindings the sqlite3_stmt * and hand it back to the SecDb with the original CFStringRef for the sql (or hash thereof) as an argument. */
+bool SecDbReleaseCachedStmt(SecDbConnectionRef dbconn, CFStringRef sql, sqlite3_stmt *stmt, CFErrorRef *error) {
+    if (stmt) {
+        return SecDbReset(stmt, error) && SecDbClearBindings(stmt, error) && SecDbFinalize(stmt, error);
+    }
+    return true;
+}
+
+bool SecDbPrepare(SecDbConnectionRef dbconn, CFStringRef sql, CFErrorRef *error, void(^exec)(sqlite3_stmt *stmt)) {
+    assert(sql != NULL);
+    sqlite3_stmt *stmt = SecDbCopyStmt(dbconn, sql, NULL, error);
+    if (!stmt)
+        return false;
+
+    exec(stmt);
+    return SecDbReleaseCachedStmt(dbconn, sql, stmt, error);
+}
+
+bool SecDbWithSQL(SecDbConnectionRef dbconn, CFStringRef sql, CFErrorRef *error, bool(^perform)(sqlite3_stmt *stmt)) {
+    bool ok = true;
+    CFRetain(sql);
+    while (sql) {
+        CFStringRef tail = NULL;
+        if (ok) {
+            sqlite3_stmt *stmt = SecDbCopyStmt(dbconn, sql, &tail, error);
+            ok = stmt != NULL;
+            if (stmt) {
+                if (perform) {
+                    ok = perform(stmt);
+                } else {
+                    // TODO: Use a different error scope here.
+                    ok = SecError(-50 /* errSecParam */, error, CFSTR("SecDbWithSQL perform block missing"));
+                }
+                ok &= SecDbReleaseCachedStmt(dbconn, sql, stmt, error);
+            }
+        } else {
+            // TODO We already have an error here we really just want the left over sql in it's userData
+            ok = SecDbError(SQLITE_ERROR, error, CFSTR("Error with unexecuted sql remaining %@"), sql);
+        }
+        CFRelease(sql);
+        sql = tail;
+    }
+    return ok;
+}
+
+#if 1
+/* SecDbForEach returns true if all SQLITE_ROW returns of sqlite3_step() return true from the row block.
+ If the row block returns false and doesn't set an error (to indicate it has reached a limit),
+ this entire function returns false. In that case no error will be set. */
+bool SecDbForEach(sqlite3_stmt *stmt, CFErrorRef *error, bool(^row)(int row_index)) {
+    bool result = false;
+    for (int row_ix = 0;;++row_ix) {
+        int s3e = sqlite3_step(stmt);
+        if (s3e == SQLITE_ROW) {
+            if (row) {
+                if (!row(row_ix)) {
+                    break;
+                }
+            } else {
+                // If we have no row block then getting SQLITE_ROW is an error
+                SecDbError(s3e, error,
+                           CFSTR("step[%d]: %s returned SQLITE_ROW with NULL row block"),
+                           row_ix, sqlite3_sql(stmt));
+            }
+        } else {
+            if (s3e == SQLITE_DONE) {
+                result = true;
+            } else {
+                SecDbErrorWithStmt(s3e, stmt, error, CFSTR("step[%d]"), row_ix);
+            }
+            break;
+        }
+    }
+    return result;
+}
+#else
+bool SecDbForEach(sqlite3_stmt *stmt, CFErrorRef *error, bool(^row)(int row_index)) {
+    int row_ix = 0;
+    for (;;) {
+        switch (_SecDbStep(dbconn, stmt, error)) {
+            case kSecDbErrorStep:
+                return false;
+            case kSecDbRowStep:
+                if (row) {
+                    if (row(row_ix++))
+                        break;
+                } else {
+                    SecDbError(SQLITE_ERROR, error, CFSTR("SecDbStep SQLITE_ROW returned without a row handler"));
+                }
+                return false;
+            case kSecDbDoneStep:
+                return true;
+        }
+    }
+}
+#endif
+
+CFGiblisFor(SecDbConnection)
diff --git a/utilities/src/SecDb.h b/utilities/src/SecDb.h
new file mode 100644 (file)
index 0000000..d72504b
--- /dev/null
@@ -0,0 +1,117 @@
+//
+//  SecDb.h
+//  utilities
+//
+//  Created by Michael Brouwer on 11/12/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#ifndef _UTILITIES_SECDB_H_
+#define _UTILITIES_SECDB_H_
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <sqlite3.h>
+
+__BEGIN_DECLS
+
+// MARK: SecDbRef and SecDbConnectionRef forward declarations
+typedef struct __OpaqueSecDb *SecDbRef;
+typedef struct __OpaqueSecDbConnection *SecDbConnectionRef;
+typedef struct __OpaqueSecDbStatement *SecDbStatementRef;
+
+// MARK: Configuration values, not used by clients directly.
+// TODO: Move this section to a private header
+enum {
+    kSecDbMaxReaders = 4,
+    kSecDbMaxWriters = 1,
+    kSecDbMaxIdleHandles = 3,
+};
+
+// MARK: SecDbTransactionType
+enum {
+    kSecDbNoneTransactionType = 0,
+    kSecDbImmediateTransactionType,
+    kSecDbExclusiveTransactionType,
+    kSecDbNormalTransactionType
+};
+typedef uint32_t SecDbTransactionType;
+
+// MARK: --
+// MARK: Error creation helpers.
+
+// SQLITE3 errors are in this domain
+extern CFStringRef kSecDbErrorDomain;
+
+bool SecDbError(int sql_code, CFErrorRef *error, CFStringRef format, ...);
+bool SecDbErrorWithDb(int sql_code, sqlite3 *db, CFErrorRef *error, CFStringRef format, ...);
+bool SecDbErrorWithStmt(int sql_code, sqlite3_stmt *stmt, CFErrorRef *error, CFStringRef format, ...);
+
+// MARK: mark -
+// MARK: mark SecDbRef
+
+CFTypeID SecDbGetTypeID(void);
+
+SecDbRef SecDbCreate(CFStringRef dbName, bool (^opened)(SecDbConnectionRef dbconn, bool did_create, CFErrorRef *error));
+
+// Read only connections go to the end of the queue, writeable
+// connections go to the start of the queue.  Use SecDbPerformRead() and SecDbPerformWrite() if you
+// can to avoid leaks.
+SecDbConnectionRef SecDbConnectionAquire(SecDbRef db, bool readOnly, CFErrorRef *error);
+void SecDbConnectionRelease(SecDbConnectionRef dbconn);
+
+// Perform a database read operation,
+bool SecDbPerformRead(SecDbRef db, CFErrorRef *error, void (^perform)(SecDbConnectionRef dbconn));
+bool SecDbPerformWrite(SecDbRef db, CFErrorRef *error, void (^perform)(SecDbConnectionRef dbconn));
+
+// TODO: DEBUG only -> Private header
+CFIndex SecDbIdleConnectionCount(SecDbRef db);
+
+// MARK: -
+// MARK: SecDbConectionRef
+
+CFTypeID SecDbConnectionGetTypeID(void);
+
+bool SecDbPrepare(SecDbConnectionRef dbconn, CFStringRef sql, CFErrorRef *error, void(^exec)(sqlite3_stmt *stmt));
+
+bool SecDbStep(SecDbConnectionRef dbconn, sqlite3_stmt *stmt, CFErrorRef *error, void (^row)(bool *stop));
+
+bool SecDbExec(SecDbConnectionRef dbconn, CFStringRef sql, CFErrorRef *error);
+
+bool SecDbCheckpoint(SecDbConnectionRef dbconn, CFErrorRef *error);
+
+bool SecDbTransaction(SecDbConnectionRef dbconn, SecDbTransactionType ttype, CFErrorRef *error,
+                      void (^transaction)(bool *commit));
+
+sqlite3 *SecDbHandle(SecDbConnectionRef dbconn);
+
+// MARK: -
+// MARK: Bind helpers
+
+#if 0
+bool SecDbBindNull(sqlite3_stmt *stmt, int param, CFErrorRef *error);
+#endif
+bool SecDbBindBlob(sqlite3_stmt *stmt, int param, const void *zData, size_t n, void(*xDel)(void*), CFErrorRef *error);
+bool SecDbBindText(sqlite3_stmt *stmt, int param, const char *zData, size_t n, void(*xDel)(void*), CFErrorRef *error);
+bool SecDbBindDouble(sqlite3_stmt *stmt, int param, double value, CFErrorRef *error);
+bool SecDbBindInt(sqlite3_stmt *stmt, int param, int value, CFErrorRef *error);
+bool SecDbBindInt64(sqlite3_stmt *stmt, int param, sqlite3_int64 value, CFErrorRef *error);
+bool SecDbBindObject(sqlite3_stmt *stmt, int param, CFTypeRef value, CFErrorRef *error);
+
+// MARK: -
+// MARK: SecDbStatementRef
+
+bool SecDbReset(sqlite3_stmt *stmt, CFErrorRef *error);
+bool SecDbClearBindings(sqlite3_stmt *stmt, CFErrorRef *error);
+bool SecDbFinalize(sqlite3_stmt *stmt, CFErrorRef *error);
+sqlite3_stmt *SecDbPrepareV2(SecDbConnectionRef dbconn, const char *sql, size_t sqlLen, const char **sqlTail, CFErrorRef *error);
+sqlite3_stmt *SecDbCopyStmt(SecDbConnectionRef dbconn, CFStringRef sql, CFStringRef *tail, CFErrorRef *error);
+bool SecDbReleaseCachedStmt(SecDbConnectionRef dbconn, CFStringRef sql, sqlite3_stmt *stmt, CFErrorRef *error);
+bool SecDbWithSQL(SecDbConnectionRef dbconn, CFStringRef sql, CFErrorRef *error, bool(^perform)(sqlite3_stmt *stmt));
+bool SecDbForEach(sqlite3_stmt *stmt, CFErrorRef *error, bool(^row)(int row_index));
+
+// Mark the database as corrupted.
+void SecDbCorrupt(SecDbConnectionRef dbconn);
+
+__END_DECLS
+
+#endif /* !_UTILITIES_SECDB_H_ */
diff --git a/utilities/src/SecDispatchRelease.h b/utilities/src/SecDispatchRelease.h
new file mode 100644 (file)
index 0000000..81db2f1
--- /dev/null
@@ -0,0 +1,58 @@
+//
+//  SecDispatchRelease.h
+//  utilities
+//
+//  Created by Mitch Adler on 11/26/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+
+#ifndef _SECDISPATCHRELEASE_H_
+#define _SECDISPATCHRELEASE_H_
+
+#include <dispatch/dispatch.h>
+#include <xpc/xpc.h>
+
+#define dispatch_retain_safe(DO) {  \
+    __typeof__(DO) _do = (DO);      \
+    if (_do)                        \
+        dispatch_retain(_do);       \
+}
+
+#define dispatch_release_safe(DO) { \
+    __typeof__(DO) _do = (DO);      \
+    if (_do)                        \
+        dispatch_release(_do);      \
+}
+
+#define dispatch_release_null(DO) { \
+    __typeof__(DO) _do = (DO);      \
+    if (_do) {                      \
+        (DO) = NULL;                \
+        dispatch_release(_do);      \
+    }                               \
+}
+
+
+#define xpc_retain_safe(XO) {  \
+    __typeof__(XO) _xo = (XO); \
+    if (_xo)                   \
+        xpc_retain(_xo);       \
+}
+
+#define xpc_release_safe(XO) { \
+    __typeof__(XO) _xo = (XO); \
+    if (_xo)                   \
+        xpc_release(_xo);      \
+}
+
+#define xpc_release_null(XO) {  \
+    __typeof__(XO) _xo = (XO); \
+    if (_xo) {                  \
+        (XO) = NULL;            \
+        xpc_release(_xo);       \
+    }                           \
+}
+
+#endif
+
diff --git a/utilities/src/SecFileLocations.c b/utilities/src/SecFileLocations.c
new file mode 100644 (file)
index 0000000..93dc294
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2012-2013 Apple, Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+//
+//  SecFileLocations.c
+//  utilities
+//
+
+/*
+    This file incorporates code from securityd_files.c (iOS) and iOSforOSX.c (OSX).
+ */
+
+#include <TargetConditionals.h>
+#include <AssertMacros.h>
+#include <CoreFoundation/CFPriv.h>
+#include <CoreFoundation/CFString.h>
+#include <CoreFoundation/CFURL.h>
+#include <CoreFoundation/CFUtilities.h>
+#include <utilities/SecCFWrappers.h>
+#include <utilities/SecCFRelease.h>
+#include <sys/stat.h>
+#include <uuid/uuid.h>
+#include <copyfile.h>
+
+#include "SecFileLocations.h"
+
+static CFURLRef sCustomHomeURL = NULL;
+
+static CFURLRef SecCopyHomeURL(void)
+{
+    // This returns a CFURLRef so that it can be passed as the second parameter
+    // to CFURLCreateCopyAppendingPathComponent
+
+    CFURLRef homeURL = sCustomHomeURL;
+    if (homeURL) {
+        CFRetain(homeURL);
+    } else {
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+        // We would use CFCopyHomeDirectoryURL but it doesn't exist on MACOS.
+        // This does the same.
+        homeURL = CFCopyHomeDirectoryURLForUser(NULL);
+#else
+        homeURL = CFCopyHomeDirectoryURL();
+#endif
+    }
+
+    return homeURL;
+}
+
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+static const char * get_host_uuid()
+{
+    static uuid_string_t hostuuid = {};
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        struct timespec timeout = {30, 0};
+        uuid_t uuid = {};
+        if (gethostuuid(uuid, &timeout) == 0) {
+            uuid_unparse(uuid, hostuuid);
+        } else {
+            secerror("failed to get host uuid");
+        }
+    });
+
+    return hostuuid;
+}
+
+static CFStringRef copy_keychain_uuid_path(CFURLRef keyChainBaseURL)
+{
+    CFStringRef baseURLString = NULL;
+    CFStringRef uuid_path = NULL;
+
+    require(keyChainBaseURL, done);
+
+    baseURLString = CFURLCopyFileSystemPath(keyChainBaseURL, kCFURLPOSIXPathStyle);
+    require(baseURLString, done);
+
+    uuid_path = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@/%s"), baseURLString, get_host_uuid());
+
+done:
+    CFReleaseSafe(baseURLString);
+    return uuid_path;
+}
+
+// See _kb_verify_create_path in securityd
+static bool keychain_verify_create_path(const char *keychainBasePath)
+{
+    bool created = false;
+    struct stat st_info = {};
+    char new_path[PATH_MAX] = {};
+    char kb_path[PATH_MAX] = {};
+    snprintf(kb_path, sizeof(kb_path), "%s", keychainBasePath);
+    if (lstat(kb_path, &st_info) == 0) {
+        if (S_ISDIR(st_info.st_mode)) {
+            created = true;
+        } else {
+            secerror("invalid directory at '%s' moving aside", kb_path);
+            snprintf(new_path, sizeof(new_path), "%s-invalid", kb_path);
+            unlink(new_path);
+            if (rename(kb_path, new_path) != 0) {
+                secerror("failed to rename file: %s (%s)", kb_path, strerror(errno));
+                goto done;
+            }
+        }
+    }
+    if (!created) {
+        require_action(mkpath_np(kb_path, 0700) == 0, done, secerror("could not create path: %s (%s)", kb_path, strerror(errno)));
+        created = true;
+    }
+
+done:
+    return created;
+}
+#endif /*(TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
+
+static CFURLRef SecCopyBaseFilesURL()
+{
+    CFURLRef baseURL = sCustomHomeURL;
+    if (baseURL) {
+        CFRetain(baseURL);
+    } else {
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED))
+        baseURL = SecCopyHomeURL();
+#else
+        baseURL = CFURLCreateWithFileSystemPath(NULL, CFSTR("/"), kCFURLPOSIXPathStyle, true);
+#endif
+    }
+    return baseURL;
+}
+
+static CFURLRef SecCopyURLForFileInBaseDirectory(CFStringRef directoryPath, CFStringRef fileName)
+{
+    CFURLRef fileURL = NULL;
+    CFStringRef suffix = NULL;
+    CFURLRef homeURL = SecCopyBaseFilesURL();
+
+    if (fileName)
+        suffix = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@/%@"), directoryPath, fileName);
+    else
+    if (directoryPath)
+        suffix = CFStringCreateCopy(kCFAllocatorDefault, directoryPath);
+
+    if (homeURL && suffix)
+        fileURL = CFURLCreateCopyAppendingPathComponent(kCFAllocatorDefault, homeURL, suffix, false);
+    CFReleaseSafe(suffix);
+    CFReleaseSafe(homeURL);
+    return fileURL;
+}
+
+CFURLRef SecCopyURLForFileInKeychainDirectory(CFStringRef fileName)
+{
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+    // need to tack on uuid here
+    Boolean isDirectory = (fileName == NULL);
+    CFURLRef resultURL = NULL;
+    CFStringRef resultStr = NULL;
+    __block bool directoryExists = false;
+
+    CFURLRef keyChainBaseURL = SecCopyURLForFileInBaseDirectory(CFSTR("Library/Keychains"), NULL);
+    CFStringRef uuid_path = copy_keychain_uuid_path(keyChainBaseURL);
+    CFStringPerformWithCString(uuid_path, ^(const char *utf8Str) {
+        directoryExists = keychain_verify_create_path(utf8Str);
+    });
+    require(directoryExists, done);
+    if (fileName)
+        resultStr = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@/%@"), uuid_path, fileName);
+    else
+        resultStr = CFStringCreateCopy(kCFAllocatorDefault, uuid_path);
+
+done:
+    CFReleaseSafe(uuid_path);
+    CFReleaseSafe(keyChainBaseURL);
+    if (resultStr)
+    {
+        resultURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, resultStr, kCFURLPOSIXPathStyle, isDirectory);
+        CFRelease(resultStr);
+    }
+    return resultURL;
+#else
+    return SecCopyURLForFileInBaseDirectory(CFSTR("Library/Keychains"), fileName);
+#endif
+}
+
+CFURLRef SecCopyURLForFileInPreferencesDirectory(CFStringRef fileName)
+{
+    return SecCopyURLForFileInBaseDirectory(CFSTR("Library/Preferences"), fileName);
+}
+
+void WithPathInKeychainDirectory(CFStringRef fileName, void(^operation)(const char *utf8String))
+{
+    CFURLRef fileURL = SecCopyURLForFileInKeychainDirectory(fileName);
+    UInt8 buffer[MAXPATHLEN];
+    CFURLGetFileSystemRepresentation(fileURL, false, buffer, sizeof(buffer));
+
+    operation((const char*)buffer);
+    CFRelease(fileURL);
+}
+
+void SetCustomHomeURLString(CFStringRef home_path)
+{
+    CFReleaseNull(sCustomHomeURL);
+    if (home_path) {
+        sCustomHomeURL = CFURLCreateWithFileSystemPath(NULL, home_path, kCFURLPOSIXPathStyle, true);
+    }
+}
+
+void SetCustomHomeURL(const char* path)
+{
+    if (path) {
+        CFStringRef path_cf = CFStringCreateWithCStringNoCopy(NULL, path, kCFStringEncodingUTF8, kCFAllocatorNull);
+        SetCustomHomeURLString(path_cf);
+        CFReleaseSafe(path_cf);
+    } else {
+        SetCustomHomeURLString(NULL);
+    }
+}
+
+
diff --git a/utilities/src/SecFileLocations.h b/utilities/src/SecFileLocations.h
new file mode 100644 (file)
index 0000000..443b80f
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2012-2013 Apple, Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+//
+//  SecFileLocations.h
+//  utilities
+//
+
+
+#ifndef _SECFILELOCATIONS_H_
+#define _SECFILELOCATIONS_H_
+
+#include <CoreFoundation/CFURL.h>
+
+__BEGIN_DECLS
+
+CFURLRef SecCopyURLForFileInKeychainDirectory(CFStringRef fileName);
+CFURLRef SecCopyURLForFileInPreferencesDirectory(CFStringRef fileName);
+
+void WithPathInKeychainDirectory(CFStringRef fileName, void(^operation)(const char *utf8String));
+
+void SetCustomHomeURL(const char* path);
+void SetCustomHomeURLString(CFStringRef path);
+
+__END_DECLS
+
+#endif
diff --git a/utilities/src/SecIOFormat.h b/utilities/src/SecIOFormat.h
new file mode 100644 (file)
index 0000000..f593307
--- /dev/null
@@ -0,0 +1,50 @@
+//
+//  SecIOFormat.h
+//  utilities
+//
+//  Created by Mitch Adler on 10/1/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#ifndef _SECIOFORMAT_H_
+#define _SECIOFORMAT_H_
+
+#include <inttypes.h>
+
+// MARK: CFIndex printing support
+
+#ifdef __LLP64__
+#  define PRIdCFIndex    "lld"
+#  define PRIiCFIndex    "lli"
+#  define PRIoCFIndex    "llo"
+#  define PRIuCFIndex    "llu"
+#  define PRIxCFIndex    "llx"
+#  define PRIXCFIndex    "llX"
+#else
+#  define PRIdCFIndex    "ld"
+#  define PRIiCFIndex    "li"
+#  define PRIoCFIndex    "lo"
+#  define PRIuCFIndex    "lu"
+#  define PRIxCFIndex    "lx"
+#  define PRIXCFIndex    "lX"
+#endif
+
+// MARK: OSStatus printing support
+
+#ifdef __LP64__
+#  define PRIdOSStatus    "d"
+#  define PRIiOSStatus    "i"
+#  define PRIoOSStatus    "o"
+#  define PRIuOSStatus    "u"
+#  define PRIxOSStatus    "x"
+#  define PRIXOSStatus    "X"
+#else
+#  define PRIdOSStatus    "ld"
+#  define PRIiOSStatus    "li"
+#  define PRIoOSStatus    "lo"
+#  define PRIuOSStatus    "lu"
+#  define PRIxOSStatus    "lx"
+#  define PRIXOSStatus    "lX"
+#endif
+
+#endif
diff --git a/utilities/src/SecXPCError.c b/utilities/src/SecXPCError.c
new file mode 100644 (file)
index 0000000..a420061
--- /dev/null
@@ -0,0 +1,67 @@
+//
+//  SecCFXPCWrappers.c
+//  utilities
+//
+//  Created by John Hurley on 5/6/13.
+//  Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#include <stdio.h>
+
+#include <utilities/SecXPCError.h>
+#include <utilities/SecCFError.h>
+#include <utilities/SecCFWrappers.h>
+
+CFStringRef sSecXPCErrorDomain = CFSTR("com.apple.security.xpc");
+
+static const char* kDomainKey = "domain";
+static const char* kDescriptionKey = "description";
+static const char* kCodeKey = "code";
+
+CFErrorRef SecCreateCFErrorWithXPCObject(xpc_object_t xpc_error)
+{
+    CFErrorRef result = NULL;
+
+    if (xpc_get_type(xpc_error) == XPC_TYPE_DICTIONARY) {
+        CFStringRef domain = NULL;
+
+        const char * domain_string = xpc_dictionary_get_string(xpc_error, kDomainKey);
+        if (domain_string != NULL) {
+            domain = CFStringCreateWithCString(kCFAllocatorDefault, domain_string, kCFStringEncodingUTF8);
+        } else {
+            domain = sSecXPCErrorDomain;
+            CFRetain(domain);
+        }
+        CFIndex code = (CFIndex) xpc_dictionary_get_int64(xpc_error, kCodeKey);
+
+        const char *description = xpc_dictionary_get_string(xpc_error, kDescriptionKey);
+
+        SecCFCreateErrorWithFormat(code, domain, NULL, &result, NULL, CFSTR("Remote error : %s"), description);
+
+        CFReleaseSafe(domain);
+    } else {
+        SecCFCreateErrorWithFormat(kSecXPCErrorUnexpectedType, sSecXPCErrorDomain, NULL, &result, NULL, CFSTR("Remote error not dictionary!: %@"), xpc_error);
+    }
+    return result;
+}
+
+static void SecXPCDictionarySetCFString(xpc_object_t dict, const char *key, CFStringRef string)
+{
+    CFStringPerformWithCString(string, ^(const char *utf8Str) {
+        xpc_dictionary_set_string(dict, key, utf8Str);
+    });
+}
+
+xpc_object_t SecCreateXPCObjectWithCFError(CFErrorRef error)
+{
+    xpc_object_t error_xpc = xpc_dictionary_create(NULL, NULL, 0);
+
+    SecXPCDictionarySetCFString(error_xpc, kDomainKey, CFErrorGetDomain(error));
+    xpc_dictionary_set_int64(error_xpc, kCodeKey, CFErrorGetCode(error));
+
+    CFStringRef description = CFErrorCopyDescription(error);
+    SecXPCDictionarySetCFString(error_xpc, kDescriptionKey, description);
+    CFReleaseNull(description);
+
+    return error_xpc;
+}
diff --git a/utilities/src/SecXPCError.h b/utilities/src/SecXPCError.h
new file mode 100644 (file)
index 0000000..0a5896b
--- /dev/null
@@ -0,0 +1,33 @@
+//
+//  SecXPCError.h
+//  utilities
+//
+//  Created by John Hurley on 5/6/13.
+//  Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#ifndef _UTILITIES_SECXPCERROR_H_
+#define _UTILITIES_SECXPCERROR_H_
+
+#include <CoreFoundation/CFString.h>
+#include <CoreFoundation/CFError.h>
+#include <xpc/xpc.h>
+
+__BEGIN_DECLS
+
+extern CFStringRef sSecXPCErrorDomain;
+
+enum {
+    kSecXPCErrorSuccess = 0,
+    kSecXPCErrorUnexpectedType = 1,
+    kSecXPCErrorUnexpectedNull = 2,
+    kSecXPCErrorConnectionFailed = 3,
+    kSecXPCErrorUnknown = 4,
+};
+
+CFErrorRef SecCreateCFErrorWithXPCObject(xpc_object_t xpc_error);
+xpc_object_t SecCreateXPCObjectWithCFError(CFErrorRef error);
+
+__END_DECLS
+
+#endif /* UTILITIES_SECXPCERROR_H */
diff --git a/utilities/src/array_size.h b/utilities/src/array_size.h
new file mode 100644 (file)
index 0000000..9d7cb90
--- /dev/null
@@ -0,0 +1,14 @@
+//
+//  array_size.h
+//  utilities
+//
+//  Created by Mitch Adler on 2/10/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#ifndef utilities_array_size_h
+#define utilities_array_size_h
+
+#define array_size(array) (sizeof(array)/sizeof(*array))
+
+#endif
diff --git a/utilities/src/cloud_keychain_diagnose.c b/utilities/src/cloud_keychain_diagnose.c
new file mode 100644 (file)
index 0000000..7581ad1
--- /dev/null
@@ -0,0 +1,1256 @@
+/*
+ * clang cloud_keychain_diagnose.c -laks -framework CoreFoundation -framework IOKit -framework Security -o /tmp/cloud_keychain_diagnose
+ */
+
+
+#if !TARGET_OS_EMBEDDED
+#include "sec/Security/SecBase.h"
+#include "sec/Security/SecKey.h"
+#endif
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreFoundation/CFPriv.h>
+
+#if !TARGET_IPHONE_SIMULATOR
+
+/* Header Declarations */
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <asl.h>
+#include <asl_msg.h>
+
+#if TARGET_OS_EMBEDDED
+#include <asl_core.h>
+#endif
+
+#include <string.h>
+#include <errno.h>
+#include <libaks.h>
+
+#include "SOSCloudCircle.h"
+#include "SOSPeerInfo.h"
+
+
+/* Constant Declarations */
+#define SUCCESS 0
+#define FAILURE -1
+
+#define MAX_PATH_LEN                1024
+#define SUFFIX_LENGTH               4
+#define BUFFER_SIZE                 1024
+#define MAX_DATA_RATE               32
+
+/* External CloudKeychain Bridge Types */
+typedef void (^CloudKeychainReplyBlock)(CFDictionaryRef returnedValues, CFErrorRef error);
+extern void SOSCloudKeychainGetAllObjectsFromCloud(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
+
+/* External AppleKeyStore Types */
+enum {
+ my_keybag_state_bio_unlock = 1 << 3
+};
+
+
+/* Dictionary Dump State */
+struct dict_dump_state
+{
+    FILE                *log_file;
+    CFDictionaryRef     dict;
+    unsigned int        indent_level;
+};
+
+/* Static Function Declarations */
+static
+void
+usage();
+
+static
+int
+gather_diagnostics();
+
+static
+int
+enable_cloud_keychain_diagnostics(
+    const unsigned int enable_flag);
+
+static
+int
+build_log_path(
+    char *log_path);
+
+static
+int
+dump_system_information(
+    FILE *log_file);
+
+static
+int
+dump_circle_state(
+    FILE *log_file);
+
+static
+int
+dump_keychain_sync_kvs(
+    FILE *log_file);
+
+static
+void
+dump_dict(
+    FILE *log_file,
+    CFDictionaryRef dict,
+    const unsigned int indent_level);
+
+static
+void
+dump_dict_applier(
+    const void *key,
+    const void *value,
+    void *context);
+
+static
+int
+dump_asl_sender(
+    FILE *log_file,
+    const char *asl_sender);
+
+static
+void
+dump_cferror(
+    FILE *log_file,
+    const char *description,
+    CFErrorRef error);
+
+/* Function Definitions */
+int
+main(
+    int argc,
+    char **argv)
+{
+    int result = EXIT_FAILURE;
+    
+    /* Parse the arguments. */
+    if (argc > 2) {
+    
+        usage();
+    }
+
+    /* Should we just gather logs and status? */
+    if (argc == 1) {
+    
+        if (gather_diagnostics()) {
+            
+            fprintf(stderr, "Could not gather diagnostics\n");
+            goto BAIL;
+        }        
+    } else {
+    
+        /* Should we enable or disable logging? */
+        if (strncmp(argv[1], "enable", 6) == 0) {
+        
+            /* Enable. */
+            if (enable_cloud_keychain_diagnostics(1)) {
+            
+                fprintf(stderr, "Could not enable additional cloud keychain diagnostics\n");
+                goto BAIL;
+            }            
+        } else if (strncmp(argv[1], "disable", 7) == 0) {
+
+            /* Enable. */
+            if (enable_cloud_keychain_diagnostics(1)) {
+            
+                fprintf(stderr, "Could not disable additional cloud keychain diagnostics\n");
+                goto BAIL;
+            } 
+        } else {
+        
+            /* Get a job, hippy. */
+            usage();
+        }
+    }
+    
+    /* Set the exit status to success. */
+    result = EXIT_FAILURE;
+    
+BAIL:
+
+    return result;
+}
+
+/* Static Function Definitions */
+static
+void
+usage()
+{
+    fprintf(stderr, "usage: cloud_keychain_diagnose [enable|disable]\n");
+    exit(EXIT_FAILURE);
+}
+
+static
+int
+gather_diagnostics()
+{
+    int     result = FAILURE;
+    char    log_path[MAX_PATH_LEN] = "";
+    int     log_fd = -1;
+    FILE    *log_file = NULL;
+    
+    /*
+     * Create the diagnostics file.
+     *
+     * Dump the system information.
+     *     on OS X, defaults read if the shim is active
+     * Dump the circle state.
+     * Dump the raw KVS data.
+     * Dump known ASL logs
+     *
+     * Remaining work to do from rdar://12479351
+     * grab the syslog
+     * query for all items with sync=1
+     * enable KVS logging
+     * enable push notification logging
+     */
+    
+    /* Build the log path. */
+    if (build_log_path(log_path)) {
+    
+        fprintf(stderr, "Could not build the log path\n");
+        goto BAIL;
+    }
+    
+    /* Create it with a randomized suffix. */
+    log_fd = mkstemps(log_path, SUFFIX_LENGTH);
+    if (log_fd == -1) {
+    
+        fprintf(stderr, "Could not create the log file: %s\n", strerror(errno));
+        goto BAIL;
+    }
+    
+    /* Create a file object from the descriptor. */
+    log_file = fdopen(log_fd, "w");
+    if (log_file == NULL) {
+    
+        fprintf(stderr, "Could not recreate the log file: %s\n", strerror(errno));
+        goto BAIL;
+    }
+    
+    log_fd = -1;
+    
+    printf("Writing cloud keychain diagnostics to %s\n", log_path);
+    
+    /* Dump the system information. */
+    if (dump_system_information(log_file)) {
+    
+        fprintf(stderr, "Could not dump the system information\n");
+        goto BAIL;
+    }
+    
+    /* Dump the SOS circle state. */
+    if (dump_circle_state(log_file)) {
+    
+        fprintf(stderr, "Could not dump the SOS circle state\n");
+        goto BAIL;
+    }
+    
+    /* Dump the raw keychain syncing KVS. */
+    if (dump_keychain_sync_kvs(log_file)) {
+    
+        fprintf(stderr, "Could not the raw keychain syncing KVS\n");
+        goto BAIL;
+    }
+    
+    /* 
+     * Dump the various and sundry ASL logs.
+     */
+    
+    if (dump_asl_sender(log_file, "com.apple.kb-service")) {
+    
+        fprintf(stderr, "Could not dump the ASL log for com.apple.kb-service\n");
+        goto BAIL;
+    }
+    
+    if (dump_asl_sender(log_file, "com.apple.securityd")) {
+    
+        fprintf(stderr, "Could not dump the ASL log for com.apple.securityd\n");
+        goto BAIL;
+    }
+    
+    if (dump_asl_sender(log_file, "com.apple.secd")) {
+    
+        fprintf(stderr, "Could not dump the ASL log for com.apple.secd\n");
+        goto BAIL;
+    }
+    
+    if (dump_asl_sender(log_file, "CloudKeychainProxy")) {
+    
+        fprintf(stderr, "Could not dump the ASL log for CloudKeychainProxy\n");
+        goto BAIL;
+    }
+    
+    if (dump_asl_sender(log_file, "securityd")) {
+    
+        fprintf(stderr, "Could not dump the ASL log for securityd\n");
+        goto BAIL;
+    }
+    
+    if (dump_asl_sender(log_file, "secd")) {
+    
+        fprintf(stderr, "Could not dump the ASL log for secd\n");
+        goto BAIL;
+    }
+
+    /* Set the result to success. */
+    result = SUCCESS;
+
+BAIL:
+
+    /* Close the diagnostics file? */
+    if (log_file != NULL) {
+    
+        fclose(log_file);
+        log_file = NULL;
+    }
+    
+    /* Close the diagnostics file descriptor? */
+    if (log_fd != -1) {
+    
+        close(log_fd);
+        log_fd = -1;
+    }
+    
+    return result;
+}
+
+static
+int
+enable_cloud_keychain_diagnostics(
+    const unsigned int enable_flag)
+{
+    int result = FAILURE;
+    
+    /* Set the result to success. */
+    result = SUCCESS;
+    
+    return result;
+}
+
+static
+int
+build_log_path(
+    char *log_path)
+{
+    int             result = FAILURE;
+    time_t          now;
+    struct tm       *time_cube;
+    CFDictionaryRef system_version_dict = NULL;
+    CFStringRef     product_name = NULL;
+    
+    /* Get the current time. */
+    now = time(NULL);
+    
+    /* Convert the time into something usable. */
+    time_cube = localtime(&now);
+    if (time_cube == NULL) {
+    
+        fprintf(stderr, "I don't know what time it is.\n");
+        goto BAIL;
+    }
+    
+    /* Copy the system version dictionary. */
+    system_version_dict = _CFCopySystemVersionDictionary();
+    if (system_version_dict == NULL) {
+    
+        fprintf(stderr, "Could not copy the system version dictionary\n");
+        goto BAIL;
+    }
+    
+    /* Extract the product name. */
+    product_name = CFDictionaryGetValue(system_version_dict, _kCFSystemVersionProductNameKey);
+    if (product_name == NULL) {
+    
+        fprintf(stderr, "Could not extract the product name from the system version dictionary\n");
+        goto BAIL;
+    }
+
+    /* Is this a Mac? */
+    if (CFEqual(product_name, CFSTR("Mac OS X"))) {
+    
+        /* Prepare the file template to go into /tmp. */
+        snprintf(
+            log_path,
+            MAX_PATH_LEN,
+            "/tmp/cloud_keychain_diagnostics.%d_%d_%d.%d%d%d.XXXX.txt",
+            1900 + time_cube->tm_year,
+            time_cube->tm_mon,
+            time_cube->tm_mday,
+            time_cube->tm_hour,
+            time_cube->tm_min,
+            time_cube->tm_sec);
+    } else {
+    
+        /* Prepare the file template to go into CrashReporter. */
+        snprintf(
+            log_path,
+            MAX_PATH_LEN,
+            "/Library/Logs/CrashReporter/cloud_keychain_diagnostics.%d_%d_%d.%d%d%d.XXXX.txt",
+            1900 + time_cube->tm_year,
+            time_cube->tm_mon,
+            time_cube->tm_mday,
+            time_cube->tm_hour,
+            time_cube->tm_min,
+            time_cube->tm_sec);
+    }
+    
+    /* Set the result to success. */
+    result = SUCCESS;
+    
+BAIL:
+
+    /* Release the system version dictionary? */
+    if (system_version_dict != NULL) {
+    
+        CFRelease(system_version_dict);
+        system_version_dict = NULL;
+    }
+    
+    return result;
+}
+
+static
+int
+dump_system_information(
+    FILE *log_file)
+{
+    int             result = FAILURE;
+    CFDictionaryRef dict = NULL;
+    char            buffer[BUFFER_SIZE];
+    CFStringRef     product_name;
+    CFStringRef     product_version;
+    CFStringRef     product_build_version;
+    time_t          now;
+    CFTypeRef       shim_flag = NULL;
+    int             keybag_handle = bad_keybag_handle;
+    kern_return_t   kr = 0;
+    keybag_state_t  keybag_state = 0;
+    
+    /*
+     * Dump the system information.
+     *  ProductName
+     *  ProductVersion
+     *  ProductBuildVersion
+     *  Host name
+     */
+    
+    /* Dump a header. */
+    fprintf(log_file, "Host Information:\n");
+    fprintf(log_file, "=================\n");
+    
+    /* Copy the system version dictionary. */
+    dict = _CFCopySystemVersionDictionary();
+    if (dict == NULL) {
+    
+        fprintf(stderr, "Could not copy the system version dictionary\n");
+        goto BAIL;
+    }
+    
+    /* Extract the product name. */
+    product_name = CFDictionaryGetValue(dict, _kCFSystemVersionProductNameKey);
+    if (product_name == NULL) {
+    
+        fprintf(stderr, "Could not extract the product name from the system version dictionary\n");
+        goto BAIL;
+    }
+    
+    /* Convert the product name to a C string. */
+    if (!CFStringGetCString(product_name, buffer, BUFFER_SIZE, kCFStringEncodingUTF8)) {
+    
+        fprintf(stderr, "Could not convert the product name to a C string\n");
+        goto BAIL;
+    }
+    
+    /* Dump the product name. */
+    fprintf(log_file, "Product Name: %s\n", buffer);
+    
+    /* Extract the product version. */
+    product_version = CFDictionaryGetValue(dict, _kCFSystemVersionProductVersionKey);
+    if (product_version == NULL) {
+    
+        fprintf(stderr, "Could not extract the product version from the system version dictionary\n");
+        goto BAIL;
+    }
+    
+    /* Convert the product version to a C string. */
+    if (!CFStringGetCString(product_version, buffer, BUFFER_SIZE, kCFStringEncodingUTF8)) {
+    
+        fprintf(stderr, "Could not convert the product version to a C string\n");
+        goto BAIL;
+    }
+    
+    /* Dump the product version */
+    fprintf(log_file, "Product Version: %s\n", buffer);
+    
+    /* Extract the product build version. */
+    product_build_version = CFDictionaryGetValue(dict, _kCFSystemVersionBuildVersionKey);
+    if (product_build_version == NULL) {
+    
+        fprintf(stderr, "Could not extract the product build version from the system version dictionary\n");
+        goto BAIL;
+    }
+    
+    /* Convert the product build version to a C string. */
+    if (!CFStringGetCString(product_build_version, buffer, BUFFER_SIZE, kCFStringEncodingUTF8)) {
+    
+        fprintf(stderr, "Could not convert the product build version to a C string\n");
+        goto BAIL;
+    }
+    
+    /* Dump the product build version. */
+    fprintf(log_file, "Product Build Version: %s\n", buffer);
+    
+    /* Lookup the host name. */
+    if (gethostname(buffer, BUFFER_SIZE) == -1) {
+    
+        fprintf(stderr, "Could not lookup the host name\n");
+        goto BAIL;
+    }
+    
+    /* Dump the host name. */
+    fprintf(log_file, "Host Name: %s\n", buffer);
+    
+    /* Lookup the current time. */
+    if (gethostname(buffer, BUFFER_SIZE) == -1) {
+    
+        fprintf(stderr, "Could not lookup the host name\n");
+        goto BAIL;
+    }
+
+    /* Get the current time. */
+    now = time(NULL);
+    
+    /* Dump the current time. */
+    fprintf(log_file, "Time: %s", ctime(&now));
+    
+    /* Is this a Mac? */
+    if (CFEqual(product_name, CFSTR("Mac OS X"))) {
+    
+        /* Set the keybag handle. */
+        keybag_handle = session_keybag_handle;
+        
+        /* Lookup the state of the shim. */
+        shim_flag = (CFNumberRef)CFPreferencesCopyValue(CFSTR("SecItemSynchronizable"), CFSTR("com.apple.security"), kCFPreferencesAnyUser, kCFPreferencesCurrentHost);
+        if (shim_flag && CFGetTypeID(shim_flag) == CFBooleanGetTypeID()) {
+        
+            /* Is the shim enabled? */
+            if (CFBooleanGetValue((CFBooleanRef)shim_flag)) {
+            
+                fprintf(log_file, "The SecItem shim is enabled\n");
+            } else {
+                
+                fprintf(log_file, "The SecItem shim is disabled\n");
+            }
+        } else {
+        
+            fprintf(log_file, "The SecItem shim is disabled\n");
+        }
+    } else {
+    
+        /* Set the keybag handle. */
+        keybag_handle = device_keybag_handle;
+    }
+    
+    /* Get the keybag state. */
+    kr = aks_get_lock_state(keybag_handle, &keybag_state);
+    if (kr) {
+    
+        fprintf(stderr, "Could not call aks_get_lock_state\n");
+    } else {
+    
+        switch (keybag_state) {
+        
+            case keybag_state_unlocked: {
+                
+                fprintf(log_file, "Keybag State: Unlocked\n");
+            }break;
+            
+            case keybag_state_locked: {
+                
+                fprintf(log_file, "Keybag State: Locked\n");
+            }break;
+            
+            case keybag_state_no_pin: {
+                
+                fprintf(log_file, "Keybag State: No Passcode\n");
+            }break;
+            
+            case keybag_state_been_unlocked: {
+                
+                fprintf(log_file, "Keybag State: Been Unlocked\n");
+            }break;
+            
+            case my_keybag_state_bio_unlock: {
+                
+                fprintf(log_file, "Keybag State: Bio Unlock\n");
+            }break;
+            
+            default: {
+            
+                fprintf(log_file, "Keybag State: UNKNOWN\n");
+            }break;
+        }
+    }
+    
+    /* Dump a footer. */
+    fprintf(log_file, "=================\n\n");
+
+    /* Set the result to success. */
+    result = SUCCESS;
+    
+BAIL:
+
+    /* Release the shim flag? */
+    if (shim_flag) {
+    
+        CFRelease(shim_flag);
+        shim_flag = NULL;
+    }
+    
+    /* Release the system version dictionary? */
+    if (dict != NULL) {
+    
+        CFRelease(dict);
+        dict = NULL;
+    }
+    
+    return result;
+}
+
+static
+int
+dump_circle_state(
+    FILE *log_file)
+{
+    int             result = FAILURE;
+    CFErrorRef      error = NULL;
+    SOSCCStatus     circle_status;
+    char            *circle_state_string = NULL;
+    CFArrayRef      peer_list = NULL;
+    CFIndex         num_peers;
+    CFIndex         i;
+    SOSPeerInfoRef  peer_info;
+    CFDictionaryRef peer_gestalt = NULL;
+    CFStringRef     peer_name;
+    CFStringRef     peer_device_type;
+    CFStringRef     peerID;
+    char            buffer[BUFFER_SIZE];
+
+    /*
+     * Dump the SOS circle state.
+     */
+    
+    /* Dump a header. */
+    fprintf(log_file, "SOS Circle State:\n");
+    fprintf(log_file, "=================\n");
+
+    /* Are we in a circle? */
+    circle_status = SOSCCThisDeviceIsInCircle(&error);
+    if (error != NULL) {
+    
+        /* Dump and consume the error. */
+        dump_cferror(log_file, "Could not call SOSCCThisDeviceIsInCircle", error);
+    } else {
+    
+        switch (circle_status) {
+        
+            case kSOSCCInCircle: {
+                circle_state_string = "kSOSCCInCircle";
+            }break;
+            
+            case kSOSCCNotInCircle: {
+                circle_state_string = "kSOSCCNotInCircle";
+            }break;
+            
+            case kSOSCCRequestPending: {
+                circle_state_string = "kSOSCCRequestPending";
+            }break;
+            
+            case kSOSCCCircleAbsent: {
+                circle_state_string = "kSOSCCCircleAbsent";
+            }break;
+            
+            case kSOSCCError: {
+                circle_state_string = "kSOSCCError";
+            }break;
+            
+            case kSOSCCParamErr: {
+                circle_state_string = "kSOSCCParamErr";
+            }break;
+            
+            case kSOSCCMemoryErr: {
+                circle_state_string = "kSOSCCMemoryErr";
+            }break;
+    
+            default: {
+                circle_state_string = "Unknown circle status?";
+            }
+        }
+        
+        fprintf(log_file, "Circle Status: %s\n", circle_state_string);
+    }
+    
+    /* Can we authenticate? */
+    if (!SOSCCCanAuthenticate(&error)) {
+
+        if (error) {
+        
+            /* Dump and consume the error. */
+            dump_cferror(log_file, "Could not call SOSCCCanAuthenticate", error);
+        } else {
+
+            fprintf(log_file, "Can Authenticate: NO\n");
+        }
+    } else {
+    
+        fprintf(log_file, "Can Authenticate: YES\n");
+    }
+    
+    /* Copy the peers. */
+    peer_list = SOSCCCopyPeerPeerInfo(&error);
+    if (error) {
+
+        /* Dump the error. */
+        dump_cferror(log_file, "Could not call SOSCCCopyPeerPeerInfo", error);
+    } else {
+    
+        /* Get the number of peers. */
+        num_peers = CFArrayGetCount(peer_list);
+        
+        fprintf(log_file, "Number of syncing peers: %ld\n", num_peers);
+        
+        if (num_peers > 0) {
+        
+            fprintf(log_file, "\n");
+        }
+        
+        /* Enumerate the peers. */
+        for (i = 0; i < num_peers; i++) {
+        
+            peer_info = (SOSPeerInfoRef) CFArrayGetValueAtIndex(peer_list, i);
+            if (peer_info == NULL) {
+            
+                fprintf(stderr, "Could not extract peer %ld of %ld\n", i, num_peers);
+                goto BAIL;
+            }
+            
+            /*
+            peer_gestalt = SOSPeerInfoCopyPeerGestalt(peer_info);
+            if (peer_gestalt == NULL) {
+
+                fprintf(stderr, "Could not copy peer gestalt %ld of %ld\n", i, num_peers);
+                goto BAIL;            
+            }
+            */
+            
+            /* Get the peer name. */
+            peer_name = SOSPeerInfoGetPeerName(peer_info);
+            if (peer_name == NULL) {
+            
+                fprintf(stderr, "Could not extract peer name %ld of %ld\n", i, num_peers);
+                goto BAIL;
+            }
+            
+            /* Convert the peer name to a C string. */
+            if (!CFStringGetCString(peer_name, buffer, BUFFER_SIZE, kCFStringEncodingUTF8)) {
+            
+                fprintf(stderr, "Could not convert the peer name to a C string\n");
+                goto BAIL;
+            }
+    
+            /* Dump the peer name. */
+            fprintf(log_file, " Peer Name: %s\n", buffer);
+            
+            /* Get the peer device type. */
+            peer_device_type = SOSPeerInfoGetPeerDeviceType(peer_info);
+            if (peer_device_type == NULL) {
+            
+                fprintf(stderr, "Could not extract peer device type %ld of %ld\n", i, num_peers);
+                goto BAIL;
+            }
+            
+            /* Convert the peer device type to a C string. */
+            if (!CFStringGetCString(peer_device_type, buffer, BUFFER_SIZE, kCFStringEncodingUTF8)) {
+            
+                fprintf(stderr, "Could not convert the peer device type to a C string\n");
+                goto BAIL;
+            }
+            
+            /* Dump the peer name. */
+            fprintf(log_file, " Peer Device Type: %s\n", buffer);
+            
+            /* Get the peer ID. */            
+            peerID = SOSPeerInfoGetPeerID(peer_info);
+            if (peerID == NULL) {
+            
+                fprintf(stderr, "Could not extract peer ID %ld of %ld\n", i, num_peers);
+                goto BAIL;
+            }
+            
+            /* Dump the peer name. */
+            fprintf(log_file, " Peer ID: %s\n", buffer);
+            
+            /* Convert the peer ID to a C string. */
+            if (!CFStringGetCString(peerID, buffer, BUFFER_SIZE, kCFStringEncodingUTF8)) {
+            
+                fprintf(stderr, "Could not convert the peer ID to a C string\n");
+                goto BAIL;
+            }
+            
+            /* Make it pretty. */
+            fprintf(log_file, "\n");
+        }
+        
+        /* Release the peer list. */
+        CFRelease(peer_list);
+        peer_list = NULL;
+    }
+
+    /* Copy the applicant peers. */
+    peer_list = SOSCCCopyApplicantPeerInfo(&error);
+    if (error) {
+
+        /* Dump the error. */
+        dump_cferror(log_file, "Could not call SOSCCCopyApplicantPeerInfo", error);
+    } else {
+    
+        /* Get the number of peers. */
+        num_peers = CFArrayGetCount(peer_list);
+        
+        fprintf(log_file, "Number of applicant peers: %ld\n", num_peers);
+        
+        if (num_peers > 0) {
+        
+            fprintf(log_file, "\n");
+        }
+        
+        /* Enumerate the peers. */
+        for (i = 0; i < num_peers; i++) {
+        
+            peer_info = (SOSPeerInfoRef) CFArrayGetValueAtIndex(peer_list, i);
+            if (peer_info == NULL) {
+            
+                fprintf(stderr, "Could not extract peer %ld of %ld\n", i, num_peers);
+                goto BAIL;
+            }
+            
+            /*
+            peer_gestalt = SOSPeerInfoCopyPeerGestalt(peer_info);
+            if (peer_gestalt == NULL) {
+
+                fprintf(stderr, "Could not copy peer gestalt %ld of %ld\n", i, num_peers);
+                goto BAIL;            
+            }
+            */
+            
+            /* Get the peer name. */
+            peer_name = SOSPeerInfoGetPeerName(peer_info);
+            if (peer_name == NULL) {
+            
+                fprintf(stderr, "Could not extract peer name %ld of %ld\n", i, num_peers);
+                goto BAIL;
+            }
+            
+            /* Convert the peer name to a C string. */
+            if (!CFStringGetCString(peer_name, buffer, BUFFER_SIZE, kCFStringEncodingUTF8)) {
+            
+                fprintf(stderr, "Could not convert the peer name to a C string\n");
+                goto BAIL;
+            }
+    
+            /* Dump the peer name. */
+            fprintf(log_file, " Applicant Name: %s\n", buffer);
+            
+            /* Get the peer device type. */
+            peer_device_type = SOSPeerInfoGetPeerDeviceType(peer_info);
+            if (peer_device_type == NULL) {
+            
+                fprintf(stderr, "Could not extract peer device type %ld of %ld\n", i, num_peers);
+                goto BAIL;
+            }
+            
+            /* Convert the peer device type to a C string. */
+            if (!CFStringGetCString(peer_device_type, buffer, BUFFER_SIZE, kCFStringEncodingUTF8)) {
+            
+                fprintf(stderr, "Could not convert the peer device type to a C string\n");
+                goto BAIL;
+            }
+            
+            /* Dump the peer name. */
+            fprintf(log_file, " Applicant Device Type: %s\n", buffer);
+            
+            /* Get the peer ID. */            
+            peerID = SOSPeerInfoGetPeerID(peer_info);
+            if (peerID == NULL) {
+            
+                fprintf(stderr, "Could not extract peer ID %ld of %ld\n", i, num_peers);
+                goto BAIL;
+            }
+            
+            /* Dump the peer name. */
+            fprintf(log_file, " Applicant ID: %s\n", buffer);
+            
+            /* Convert the peer ID to a C string. */
+            if (!CFStringGetCString(peerID, buffer, BUFFER_SIZE, kCFStringEncodingUTF8)) {
+            
+                fprintf(stderr, "Could not convert the peer ID to a C string\n");
+                goto BAIL;
+            }
+            
+            /* Make it pretty. */
+            if (i < num_peers - 1) {
+            
+                fprintf(log_file, "\n");
+            }
+        }
+        
+        /* Release the peer list. */
+        CFRelease(peer_list);
+        peer_list = NULL;
+    }
+    
+    /* Dump a footer. */
+    fprintf(log_file, "=================\n\n");
+
+    /* Set the result to success. */
+    result = SUCCESS;
+    
+BAIL:
+    
+    /* Release the peer gestalt? */
+    if (peer_gestalt != NULL) {
+    
+        CFRelease(peer_gestalt);
+        peer_gestalt = NULL;
+    }
+    
+    /* Release the peer list? */
+    if (peer_list != NULL) {
+    
+        CFRelease(peer_list);
+        peer_list = NULL;
+    }
+    
+    /* Release the error string? */
+    if (error != NULL) {
+    
+        CFRelease(error);
+        error = NULL;
+    }
+    
+    return result;
+}
+
+static
+int
+dump_keychain_sync_kvs(
+    FILE *log_file)
+{
+    int                     result = FAILURE;
+    dispatch_group_t        cloud_group;
+    dispatch_queue_t        cloud_queue;
+    dispatch_semaphore_t    waitSemaphore;
+    dispatch_time_t         finishTime;
+    __block CFDictionaryRef kvs_dict = NULL;
+
+    /*
+     * Dump the keychain syncing KVS.
+     */
+    
+    /* Dump a header. */
+    fprintf(log_file, "Keychain Syncing KVS:\n");
+    fprintf(log_file, "=================\n");
+    
+    /* Create the serial dispatch queue to talk to CloudKeychainProxy. */
+    cloud_queue = dispatch_queue_create("cloud_queue", DISPATCH_QUEUE_SERIAL);
+
+    /* Create a semaphore. */
+    waitSemaphore = dispatch_semaphore_create(0);
+    
+    /* Create the finish time. */
+    finishTime = dispatch_time(DISPATCH_TIME_NOW, 30ull * NSEC_PER_SEC);
+    
+    /* Create the dispatch group. */
+    cloud_group = dispatch_group_create();
+
+    /* Enter the dispatch group. */
+    dispatch_group_enter(cloud_group);
+
+    /* Establish the CloudKeychainProxy reply hander. */
+    CloudKeychainReplyBlock replyBlock = ^(CFDictionaryRef returnedValues, CFErrorRef error)
+    {
+        /* Did we get back some values? */
+        if (returnedValues) {
+        
+            kvs_dict = (returnedValues);
+            CFRetain(kvs_dict);
+        }
+        
+        /* Leave the cloud group. */
+        dispatch_group_leave(cloud_group);
+        
+        /* Signal the other queue we're done. */
+        dispatch_semaphore_signal(waitSemaphore);
+    };
+
+    /* Ask CloudKeychainProxy for all of the raw KVS data. */
+    SOSCloudKeychainGetAllObjectsFromCloud(cloud_queue, replyBlock);
+
+    /* Wait for CloudKeychainProxy to respond, up to 30 seconds. */
+    dispatch_semaphore_wait(waitSemaphore, finishTime);
+    
+    /* Release the semaphore. */
+       dispatch_release(waitSemaphore);
+    
+    /* Did we get any raw KVS data from CloudKeychainProxy? */
+    if (kvs_dict) {
+
+        dump_dict(log_file, kvs_dict, 0);
+    }
+    
+    /* Dump a footer. */
+    fprintf(log_file, "=================\n\n");
+
+    /* Set the result to success. */
+    result = SUCCESS;
+        
+    /* Release the KVS dictionary? */
+    if (kvs_dict != NULL) {
+    
+        CFRelease(kvs_dict);
+        kvs_dict = NULL;
+    }
+    
+    return result;
+}
+
+static
+void
+dump_dict(
+    FILE *log_file,
+    CFDictionaryRef dict,
+    const unsigned int indent_level)
+{
+    struct dict_dump_state dump_state;
+    
+    /* Setup the context. */
+    dump_state.log_file = log_file;
+    dump_state.dict = dict;
+    dump_state.indent_level = indent_level;
+
+    /* Apply the dumper to each element in the dictionary. */
+    CFDictionaryApplyFunction(dict, dump_dict_applier, (void *)&dump_state);
+}
+
+static
+void
+dump_dict_applier(
+    const void *key,
+    const void *value,
+    void *context)
+{
+    CFTypeRef               key_object;
+    CFTypeRef               value_object;
+    struct dict_dump_state  *dump_state;
+    unsigned int            i;
+    char                    buffer[BUFFER_SIZE];
+    CFIndex                 length;
+    const UInt8*            bytes;
+    
+    /* Assign the CF types. */
+    key_object = (CFTypeRef) key;
+    value_object = (CFTypeRef) value;
+    
+    /* Get the context. */
+    dump_state = (struct dict_dump_state *)context;
+    
+    /* Indent appropriately. */
+    for (i = 0; i < dump_state->indent_level; i++) {
+    
+        fprintf(dump_state->log_file, " ");
+    }
+    
+    /* Determine the key type. */
+    if (CFGetTypeID(key_object) == CFStringGetTypeID()) {
+
+        /* Convert the key to a C string. */
+        if (!CFStringGetCString((CFStringRef) key_object, buffer, BUFFER_SIZE, kCFStringEncodingUTF8)) {
+        
+            fprintf(stderr, "Could not convert the key to a C string\n");
+            fprintf(dump_state->log_file, "[Failed Key Type]: ");
+        } else {
+        
+            fprintf(dump_state->log_file, "%s: ", buffer);
+        }
+    }
+    
+    /* Determine the value type. */
+    if (CFGetTypeID(value_object) == CFStringGetTypeID()) {
+
+        /* Convert the value to a C string. */
+        if (!CFStringGetCString((CFStringRef) value_object, buffer, BUFFER_SIZE, kCFStringEncodingUTF8)) {
+        
+            fprintf(stderr, "Could not convert the value to a C string\n");
+            fprintf(dump_state->log_file, "[Failed Value Type]: ");
+        } else {
+        
+            fprintf(dump_state->log_file, "%s\n", buffer);
+        }
+    } else if (CFGetTypeID(value_object) == CFDataGetTypeID()) {
+        
+        length = CFDataGetLength((CFDataRef)value_object);
+        bytes = CFDataGetBytePtr((CFDataRef) value_object);
+        
+        fprintf(dump_state->log_file, "0x");        
+
+        for (i = 0; i < (unsigned int)length && i < MAX_DATA_RATE; i++) {
+        
+            fprintf(dump_state->log_file, "%02x", (unsigned char)bytes[i]);
+        }
+        
+        fprintf(dump_state->log_file, " (%ld bytes)\n", length);
+        
+        
+    } else if (CFGetTypeID(value_object) == CFDictionaryGetTypeID()) {
+        
+        fprintf(dump_state->log_file, "\n");
+        dump_dict(dump_state->log_file, (CFDictionaryRef) value_object, dump_state->indent_level + 1);
+    } else {
+    
+        fprintf(dump_state->log_file, "[Unknown Value Type]\n");
+    }
+}
+
+static
+int
+dump_asl_sender(
+    FILE *log_file,
+    const char *asl_sender)
+{
+    int             result = FAILURE;
+    aslmsg          log_query = NULL;
+    aslresponse     log_response = NULL;
+    aslmsg          log_message;
+    char            *message_string;
+    uint32_t        message_length;
+    
+    /*
+     * Dump the ASL logs for the given sender.
+     */
+    
+    /* Dump a header. */
+    fprintf(log_file, "ASL: %s\n", asl_sender);
+    fprintf(log_file, "=================\n");
+    
+    /* Create the ASL query. */
+    log_query = asl_new(ASL_TYPE_QUERY);
+    if (log_query == NULL) {
+    
+        fprintf(stderr, "Could not create ASL query\n");
+        goto BAIL;
+    }
+    
+    /* Setup the ASL query. */
+    asl_set_query(log_query, ASL_KEY_SENDER, asl_sender, ASL_QUERY_OP_EQUAL);
+    
+    /* Perform the ASL search. */
+    log_response = asl_search(NULL, log_query);
+    if (log_response == NULL) {
+    
+        fprintf(log_file, "Could not perform ASL search for %s\n", asl_sender);
+    } else {
+    
+        /* Enumerate the ASL messages in the response. */
+        while ((log_message = aslresponse_next(log_response)) != NULL) {
+        
+            /* Format the message entry. */
+            message_string = asl_format_message((asl_msg_t *)log_message, ASL_MSG_FMT_STD, ASL_TIME_FMT_LCL, ASL_ENCODE_SAFE, &message_length);
+            if (message_string == NULL) {
+            
+                fprintf(stderr, "Could not create ASL message string\n");
+                goto BAIL;
+            }
+            
+            fprintf(log_file, "%s", message_string);
+            
+            /* Release the message string. */
+            free(message_string);
+            message_string = NULL;        
+        }
+    }
+    
+    /* Dump a footer. */
+    fprintf(log_file, "=================\n\n");
+
+    /* Set the result to success. */
+    result = SUCCESS;
+    
+BAIL:
+    
+    /* Release the ASL response? */
+    if (log_response != NULL) {
+    
+        aslresponse_free(log_response);
+        log_response = NULL;
+    }
+    
+    /* Release the ASL query? */
+    if (log_query != NULL) {
+    
+        asl_free(log_query);
+        log_query = NULL;
+    }
+    
+    return result;
+}
+
+static
+void
+dump_cferror(
+    FILE *log_file,
+    const char *description,
+    CFErrorRef error)
+{
+    CFStringRef     error_string = NULL;
+    char            buffer[BUFFER_SIZE];
+    
+    error_string = CFErrorCopyDescription(error);
+    if (error_string == NULL) {
+    
+        fprintf(stderr, "Could not copy error description?\n");
+        goto BAIL;
+    }
+    
+    (void) CFStringGetCString(error_string, buffer, BUFFER_SIZE, kCFStringEncodingUTF8);
+    
+    fprintf(stderr, "%s: %s\n", description, buffer);
+    fprintf(log_file, "%s: %s\n", description, buffer);
+
+BAIL:
+
+    /* Release the error string? */
+    if (error_string != NULL) {
+    
+        CFRelease(error_string);
+        error_string = NULL;
+    }
+}
+
+#else  // TARGET_IPHONE_SIMULATOR
+
+int
+main(
+     int argc,
+     char **argv)
+{
+#pragma unused (argc, argv)
+    return 0;
+}
+
+#endif
diff --git a/utilities/src/comparison.c b/utilities/src/comparison.c
new file mode 100644 (file)
index 0000000..d0d287d
--- /dev/null
@@ -0,0 +1,19 @@
+//
+//  comparison.c
+//  utilities
+//
+//  Created by Keith Henrickson on 7/1/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#include <stdio.h>
+#include <stdint.h>
+#include "comparison.h"
+
+uint64_t constant_memcmp(const uint8_t *first, const uint8_t *second, size_t count) {
+    uint64_t error_counter = 0;
+    for (size_t counter = 0; counter < count; counter++) {
+        error_counter |= first[counter] ^ second[counter];
+    }
+    return error_counter;
+}
diff --git a/utilities/src/comparison.h b/utilities/src/comparison.h
new file mode 100644 (file)
index 0000000..c28e3bf
--- /dev/null
@@ -0,0 +1,17 @@
+//
+//  comparison.h
+//  utilities
+//
+//  Created by Mitch Adler on 6/14/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#ifndef utilities_comparison_h
+#define utilities_comparison_h
+
+#define MIN(a, b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a <= _b ? _a : _b; })
+#define MAX(a, b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a >= _b ? _a : _b; })
+
+uint64_t constant_memcmp(const uint8_t *first, const uint8_t *second, size_t count);
+
+#endif
diff --git a/utilities/src/debugging.c b/utilities/src/debugging.c
new file mode 100644 (file)
index 0000000..462de8b
--- /dev/null
@@ -0,0 +1,294 @@
+/*
+ * Copyright (c) 2006-2010 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+
+/*
+ * debugging.c - non-trivial debug support
+ */
+#include "utilities/debugging.h"
+#include "utilities/SecCFWrappers.h"
+#include <CoreFoundation/CFSet.h>
+#include <CoreFoundation/CFString.h>
+
+#include <dispatch/dispatch.h>
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <pthread.h>
+#include <asl.h>
+
+/** begin: For SimulateCrash **/
+#include <dlfcn.h>
+#include <mach/mach.h>
+/// Type to represent a boolean value.
+#if TARGET_OS_IPHONE  &&  __LP64__
+typedef bool BOOL;
+#else
+typedef signed char BOOL;
+// BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C"
+// even if -funsigned-char is used.
+#endif
+/** end: For SimulateCrash **/
+
+#define MAX_SCOPE_LENGTH  12
+
+#if !defined(NDEBUG)
+static CFStringRef copyScopeName(const char *scope, CFIndex scopeLen) {
+       if (scopeLen > MAX_SCOPE_LENGTH)
+               scopeLen = MAX_SCOPE_LENGTH - 1;
+       return CFStringCreateWithBytes(kCFAllocatorDefault, (const UInt8 *)scope,
+               scopeLen, kCFStringEncodingUTF8, false);
+}
+
+pthread_once_t __security_debug_once = PTHREAD_ONCE_INIT;
+static const char *gDebugScope;
+static CFMutableSetRef scopeSet;
+static bool negate = false;
+
+static void __security_debug_init(void) {
+       const char *cur_scope = gDebugScope = getenv("DEBUGSCOPE");
+       if (cur_scope) {
+               if (!strcmp(cur_scope, "all")) {
+                       scopeSet = NULL;
+                       negate = true;
+               } else if (!strcmp(cur_scope, "none")) {
+                       scopeSet = NULL;
+                       negate = false;
+               } else {
+                       scopeSet = CFSetCreateMutable(kCFAllocatorDefault, 0,
+                               &kCFTypeSetCallBacks);
+                       if (cur_scope[0] == '-') {
+                               negate = true;
+                               cur_scope++;
+                       } else {
+                               negate = false;
+                       }
+
+                       const char *sep;
+                       while ((sep = strchr(cur_scope, ','))) {
+                               CFStringRef scopeName = copyScopeName(cur_scope,
+                                       sep - cur_scope);
+                               CFSetAddValue(scopeSet, scopeName);
+                               CFRelease(scopeName);
+                               cur_scope = sep + 1;
+                       }
+
+                       CFStringRef scopeName = copyScopeName(cur_scope,
+                               strlen(cur_scope));
+                       CFSetAddValue(scopeSet, scopeName);
+                       CFRelease(scopeName);
+               }
+       } else {
+               scopeSet = NULL;
+               negate = false;
+       }
+}
+
+#endif
+
+static CFMutableArrayRef sSecurityLogHandlers;
+
+static CFMutableArrayRef get_log_handlers()
+{
+    static dispatch_once_t handlers_once;
+    
+    dispatch_once(&handlers_once, ^{
+        sSecurityLogHandlers = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
+        
+        CFArrayAppendValue(sSecurityLogHandlers, ^(const char *level, CFStringRef scope, const char *function,
+                                                   const char *file, int line, CFStringRef message){
+            CFStringRef logStr = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@ %s %@\n"), scope ? scope : CFSTR(""), function, message);
+            CFStringPerformWithCString(logStr, ^(const char *logMsg) {
+                aslmsg msg = asl_new(ASL_TYPE_MSG);
+                if (scope) {
+                    CFStringPerformWithCString(scope, ^(const char *scopeStr) {
+                        asl_set(msg, ASL_KEY_FACILITY, scopeStr);
+                    });
+                }
+                asl_set(msg, ASL_KEY_LEVEL, level);
+                asl_set(msg, ASL_KEY_MSG, logMsg);
+                asl_send(NULL, msg);
+                asl_free(msg);
+            });
+            CFReleaseSafe(logStr);
+        });
+    });
+    
+    return sSecurityLogHandlers;
+}
+
+static void clean_aslclient(void *client)
+{
+    asl_close(client);
+}
+
+static aslclient get_aslclient()
+{
+    static dispatch_once_t once;
+    static pthread_key_t asl_client_key;
+    dispatch_once(&once, ^{
+        pthread_key_create(&asl_client_key, clean_aslclient);
+    });
+    aslclient client = pthread_getspecific(asl_client_key);
+    if (!client) {
+        client = asl_open(NULL, "SecAPI", 0);
+        asl_set_filter(client, ASL_FILTER_MASK_UPTO(ASL_LEVEL_DEBUG));
+        pthread_setspecific(asl_client_key, client);
+    }
+    
+    return client;
+}
+
+void __security_trace_enter_api(const char *api, CFStringRef format, ...)
+{
+    aslmsg msg = asl_new(ASL_TYPE_MSG);
+    asl_set(msg, ASL_KEY_LEVEL, ASL_STRING_DEBUG);
+    asl_set(msg, "SecAPITrace", api);
+    asl_set(msg, "ENTER", "");
+       va_list args;
+       va_start(args, format);
+    if (format) {
+        CFStringRef message = CFStringCreateWithFormatAndArguments(kCFAllocatorDefault, NULL, format, args);
+        va_end(args);
+        CFStringPerformWithCString(message, ^(const char *utf8Str) {
+            asl_set(msg, ASL_KEY_MSG, utf8Str);
+        });
+        CFReleaseSafe(message);
+    }
+    
+    {
+        char stack_info[80];
+        
+        snprintf(stack_info, sizeof(stack_info), "C%p F%p", __builtin_return_address(1), __builtin_frame_address(2));
+        asl_set(msg, "CALLER", stack_info);
+    }
+    
+    asl_send(get_aslclient(), msg);
+    asl_free(msg);
+}
+
+void __security_trace_return_api(const char *api, CFStringRef format, ...)
+{
+    aslmsg msg = asl_new(ASL_TYPE_MSG);
+    asl_set(msg, ASL_KEY_LEVEL, ASL_STRING_DEBUG);
+    asl_set(msg, "SecAPITrace", api);
+    asl_set(msg, "RETURN", "");
+       va_list args;
+       va_start(args, format);
+    if (format) {
+        CFStringRef message = CFStringCreateWithFormatAndArguments(kCFAllocatorDefault, NULL, format, args);
+        va_end(args);
+        CFStringPerformWithCString(message, ^(const char *utf8Str) {
+            asl_set(msg, ASL_KEY_MSG, utf8Str);
+        });
+        CFReleaseSafe(message);
+    }
+    asl_send(get_aslclient(), msg);
+    asl_free(msg);
+}
+
+
+void add_security_log_hanlder(security_log_handler handler)
+{
+    CFArrayAppendValue(get_log_handlers(), handler);
+}
+
+static void __security_log_msg(const char *level, CFStringRef scope, const char *function,
+                    const char *file, int line, CFStringRef message)
+{
+    
+    CFArrayForEach(get_log_handlers(), ^(const void *value) {
+        security_log_handler handler = (security_log_handler) value;
+        
+        handler(level, scope, function, file, line, message);
+    });
+}
+
+void __security_debug(CFStringRef scope, const char *function,
+                      const char *file, int line, CFStringRef format, ...)
+{
+#if !defined(NDEBUG)
+       pthread_once(&__security_debug_once, __security_debug_init);
+
+    /* Check if scope is enabled. */
+    if (scope && ((scopeSet && negate == CFSetContainsValue(scopeSet, scope)) ||
+                  (!scopeSet && !negate)))
+        return;
+#endif
+
+       va_list args;
+       va_start(args, format);
+       CFStringRef message = CFStringCreateWithFormatAndArguments(
+        kCFAllocatorDefault, NULL, format, args);
+       va_end(args);
+
+    /* DEBUG scopes are logged as notice when enabled. */
+    __security_log_msg(ASL_STRING_NOTICE, scope, function, file, line, message);
+    CFRelease(message);
+}
+
+void __security_log(const char *level, CFStringRef scope, const char *function,
+    const char *file, int line, CFStringRef format, ...)
+{
+       va_list args;
+       va_start(args, format);
+       CFStringRef message = CFStringCreateWithFormatAndArguments(
+               kCFAllocatorDefault, NULL, format, args);
+       va_end(args);
+    __security_log_msg(level, scope, function, file, line, message);
+    CFRelease(message);
+}
+
+static void __security_simulatecrash_link(CFStringRef reason, uint32_t code)
+{
+#if !TARGET_IPHONE_SIMULATOR
+    // Prototype defined in <CrashReporterSupport/CrashReporterSupport.h>, but objC only.
+    // Soft linking here so we don't link unless we hit this.
+    static BOOL (*__SimulateCrash)(pid_t pid, mach_exception_data_type_t exceptionCode, CFStringRef description);
+
+    static dispatch_once_t once = 0;
+    dispatch_once(&once, ^{
+        void *image = dlopen("/System/Library/PrivateFrameworks/CrashReporterSupport.framework/CrashReporterSupport", RTLD_NOW);
+        if (image)
+            __SimulateCrash = dlsym(image, "SimulateCrash");
+        else
+            __SimulateCrash = NULL;
+    });
+
+    if (__SimulateCrash)
+        __SimulateCrash(getpid(), code, reason);
+    else
+        secerror("SimulateCrash not available");
+#else
+    secerror("SimulateCrash not available in iOS simulator");
+#endif
+}
+
+
+void __security_simulatecrash(CFStringRef reason, uint32_t code)
+{
+    secerror("Simulating crash, reason: %@, code=%08x", reason, code);
+    __security_simulatecrash_link(reason, code);
+}
diff --git a/utilities/src/debugging.h b/utilities/src/debugging.h
new file mode 100644 (file)
index 0000000..c6e0ee4
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2006-2007,2009-2010 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * debugging.h - non-trivial debug support
+ */
+#ifndef _SECURITY_UTILITIES_DEBUGGING_H_
+#define _SECURITY_UTILITIES_DEBUGGING_H_
+
+#ifdef KERNEL
+        #include <libkern/libkern.h>
+        #define secalert(format, ...) printf((format), ## __VA_ARGS__)
+        #define secemergency(format, ...) printf((format), ## __VA_ARGS__)
+        #define seccritical(format, ...) printf((format), ## __VA_ARGS__)
+        #define secerror(format, ...) printf((format), ## __VA_ARGS__)
+        #define secwarning(format, ...) printf((format), ## __VA_ARGS__)
+        #define secnotice(scope, format, ...) printf((format), ## __VA_ARGS__)
+        #define secinfo(scope, format, ...) printf((format), ## __VA_ARGS__)
+    #if !defined(NDEBUG)
+        #define secdebug(scope, format, ...) printf((format), ## __VA_ARGS__)
+    #else // NDEBUG
+        #define secdebug(scope, format, ...)   /* nothing */
+    #endif // NDEBUG
+#else // !KERNEL
+
+#include <TargetConditionals.h>
+#include <CoreFoundation/CFString.h>
+#include <asl.h>
+
+__BEGIN_DECLS
+
+extern void __security_trace_enter_api(const char *api, CFStringRef format, ...) CF_FORMAT_FUNCTION(2, 3);
+extern void __security_trace_return_api(const char *api, CFStringRef format, ...) CF_FORMAT_FUNCTION(2, 3);
+
+extern void __security_debug(CFStringRef scope,
+                             const char *function, const char *file, int line,
+                             CFStringRef format, ...) CF_FORMAT_FUNCTION(5,6);
+
+extern void __security_log(const char *level, CFStringRef scope,
+                           const char *function, const char *file, int line,
+                           CFStringRef format, ...) CF_FORMAT_FUNCTION(6,7);
+
+#define sec_trace_enter_api(format...) __security_trace_enter_api(__FUNCTION__, format)
+#define sec_trace_return_api(rtype, body, format...) { rtype _r = body(); __security_trace_return_api(__FUNCTION__, format, _r); return _r; }
+#define sec_trace_return_bool_api(body, format...) { bool _r = body(); typeof(format) _fmt = format; __security_trace_return_api(__FUNCTION__, _fmt ? _fmt : CFSTR("return=%d"), (int)_r); return _r; }
+
+#define secemergency(format, ...)      __security_log(ASL_STRING_EMERG, NULL, \
+    __FUNCTION__, __FILE__, __LINE__, \
+    CFSTR(format), ## __VA_ARGS__)
+
+#define secalert(format, ...)  __security_log(ASL_STRING_ALERT, NULL, \
+    __FUNCTION__, __FILE__, __LINE__, \
+    CFSTR(format), ## __VA_ARGS__)
+
+#define seccritical(format, ...)       __security_log(ASL_STRING_CRIT, NULL, \
+    __FUNCTION__, __FILE__, __LINE__, \
+    CFSTR(format), ## __VA_ARGS__)
+
+#define secerror(format, ...)  __security_log(ASL_STRING_ERR, NULL, \
+    __FUNCTION__, __FILE__, __LINE__, \
+    CFSTR(format), ## __VA_ARGS__)
+
+#define secwarning(format, ...)        __security_log(ASL_STRING_WARNING, NULL, \
+    __FUNCTION__, __FILE__, __LINE__, \
+    CFSTR(format), ## __VA_ARGS__)
+
+#define secnotice(scope, format, ...)  __security_log(ASL_STRING_NOTICE, CFSTR(scope), \
+    __FUNCTION__, __FILE__, __LINE__, \
+    CFSTR(format), ## __VA_ARGS__)
+
+#define secinfo(scope, format, ...)    __security_log(ASL_STRING_INFO, CFSTR(scope), \
+    __FUNCTION__, __FILE__, __LINE__, \
+    CFSTR(format), ## __VA_ARGS__)
+
+#if !defined(NDEBUG)
+
+# define secdebug(scope,format, ...)   __security_debug(CFSTR(scope), \
+    __FUNCTION__, __FILE__, __LINE__, \
+    CFSTR(format), ## __VA_ARGS__)
+#else
+# define secdebug(scope,...)   /* nothing */
+#endif
+
+typedef void (^security_log_handler)(const char *level, CFStringRef scope, const char *function,
+                                     const char *file, int line, CFStringRef message);
+
+void add_security_log_hanlder(security_log_handler handler);
+
+/* To simulate a process crash in some conditions */
+void __security_simulatecrash(CFStringRef reason, uint32_t code);
+
+/* predefined simulate crash exception codes */
+#define __sec_exception_code(x) (0x53c00000+x)
+#define __sec_exception_code_CorruptDb(db,rc)       __sec_exception_code(1|((db)<<8)|((rc)<<16))
+#define __sec_exception_code_CorruptItem            __sec_exception_code(2)
+#define __sec_exception_code_OTRError               __sec_exception_code(3)
+#define __sec_exception_code_DbItemDescribe         __sec_exception_code(4)
+#define __sec_exception_code_TwiceCorruptDb(db)     __sec_exception_code(5|((db)<<8))
+
+__END_DECLS
+
+#endif // !KERNEL
+
+#endif /* _SECURITY_UTILITIES_DEBUGGING_H_ */
diff --git a/utilities/src/der_array.c b/utilities/src/der_array.c
new file mode 100644 (file)
index 0000000..4ca54f6
--- /dev/null
@@ -0,0 +1,75 @@
+//
+//  der_array.c
+//  utilities
+//
+//  Created by Mitch Adler on 7/2/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#include <stdio.h>
+
+#include "utilities/SecCFRelease.h"
+#include "utilities/der_plist.h"
+#include "utilities/der_plist_internal.h"
+
+#include <corecrypto/ccder.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+
+const uint8_t* der_decode_array(CFAllocatorRef allocator, CFOptionFlags mutability,
+                                CFArrayRef* array, CFErrorRef *error,
+                                const uint8_t* der, const uint8_t *der_end)
+{
+    if (NULL == der)
+        return NULL;
+
+    CFMutableArrayRef result = CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks);
+
+    const uint8_t *elements_end;
+    const uint8_t *current_element = ccder_decode_sequence_tl(&elements_end, der, der_end);
+    
+    while (current_element != NULL && current_element < elements_end) {
+        CFPropertyListRef element = NULL;
+        current_element = der_decode_plist(allocator, mutability, &element, error, current_element, elements_end);
+        if (current_element) {
+            CFArrayAppendValue(result, element);
+            CFReleaseNull(element);
+        }
+    }
+
+    if (current_element) {
+        *array = result;
+        result = NULL;
+    }
+
+    CFReleaseNull(result);
+    return current_element;
+}
+
+
+size_t der_sizeof_array(CFArrayRef data, CFErrorRef *error)
+{
+    size_t body_size = 0;
+    for(CFIndex position = CFArrayGetCount(data) - 1;
+        position >= 0;
+        --position)
+    {
+        body_size += der_sizeof_plist(CFArrayGetValueAtIndex(data, position), error);
+    }
+    return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, body_size);
+}
+
+
+uint8_t* der_encode_array(CFArrayRef array, CFErrorRef *error,
+                          const uint8_t *der, uint8_t *der_end)
+{
+    uint8_t* original_der_end = der_end;
+    for(CFIndex position = CFArrayGetCount(array) - 1;
+        position >= 0;
+        --position)
+    {
+        der_end = der_encode_plist(CFArrayGetValueAtIndex(array, position), error, der, der_end);
+    }
+    
+    return ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, original_der_end, der, der_end);
+}
diff --git a/utilities/src/der_boolean.c b/utilities/src/der_boolean.c
new file mode 100644 (file)
index 0000000..7391bd4
--- /dev/null
@@ -0,0 +1,54 @@
+//
+//  der_boolean.c
+//  utilities
+//
+//  Created by Mitch Adler on 6/19/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#include <stdio.h>
+
+#include "utilities/SecCFRelease.h"
+#include "utilities/der_plist.h"
+#include "utilities/der_plist_internal.h"
+
+#include <corecrypto/ccder.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+
+const uint8_t* der_decode_boolean(CFAllocatorRef allocator, CFOptionFlags mutability,
+                                  CFBooleanRef* boolean, CFErrorRef *error,
+                                  const uint8_t* der, const uint8_t *der_end)
+{
+    if (NULL == der)
+        return NULL;
+
+    size_t payload_size = 0;
+    const uint8_t *payload = ccder_decode_tl(CCDER_BOOLEAN, &payload_size, der, der_end);
+
+    if (NULL == payload || (der_end - payload) < payload_size || payload_size != 1) {
+        SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Unknown boolean encoding"), NULL, error);
+        return NULL;
+    }
+
+    *boolean = *payload ? kCFBooleanTrue : kCFBooleanFalse;
+
+    return payload + payload_size;
+}
+
+
+size_t der_sizeof_boolean(CFBooleanRef data __unused, CFErrorRef *error)
+{
+    return ccder_sizeof(CCDER_BOOLEAN, 1);
+}
+
+
+uint8_t* der_encode_boolean(CFBooleanRef boolean, CFErrorRef *error,
+                            const uint8_t *der, uint8_t *der_end)
+{
+    uint8_t value = CFBooleanGetValue(boolean);
+
+    return ccder_encode_tl(CCDER_BOOLEAN, 1, der,
+           ccder_encode_body(1, &value, der, der_end));
+
+}
diff --git a/utilities/src/der_data.c b/utilities/src/der_data.c
new file mode 100644 (file)
index 0000000..0eb726f
--- /dev/null
@@ -0,0 +1,87 @@
+//
+//  der_data.c
+//  utilities
+//
+//  Created by Mitch Adler on 6/18/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#include <stdio.h>
+
+#include "utilities/SecCFRelease.h"
+#include "utilities/der_plist.h"
+#include "utilities/der_plist_internal.h"
+
+#include <corecrypto/ccder.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+
+const uint8_t* der_decode_data_mutable(CFAllocatorRef allocator, CFOptionFlags mutability,
+                                       CFMutableDataRef* data, CFErrorRef *error,
+                                       const uint8_t* der, const uint8_t *der_end)
+{
+    if (NULL == der)
+        return NULL;
+
+    size_t payload_size = 0;
+    const uint8_t *payload = ccder_decode_tl(CCDER_OCTET_STRING, &payload_size, der, der_end);
+
+    if (NULL == payload || (der_end - payload) < payload_size) {
+        SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Unknown data encoding"), NULL, error);
+        return NULL;
+    }
+
+    *data = CFDataCreateMutable(allocator, 0);
+
+    if (NULL == *data) {
+        SecCFDERCreateError(kSecDERErrorUnderlyingError, CFSTR("Failed to create data"), NULL, error);
+        return NULL;
+    }
+
+    CFDataAppendBytes(*data, payload, payload_size);
+
+    return payload + payload_size;
+}
+
+
+const uint8_t* der_decode_data(CFAllocatorRef allocator, CFOptionFlags mutability,
+                               CFDataRef* data, CFErrorRef *error,
+                               const uint8_t* der, const uint8_t *der_end)
+{
+    if (NULL == der)
+        return NULL;
+
+    size_t payload_size = 0;
+    const uint8_t *payload = ccder_decode_tl(CCDER_OCTET_STRING, &payload_size, der, der_end);
+
+    if (NULL == payload || (der_end - payload) < payload_size) {
+        SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Unknown data encoding"), NULL, error);
+        return NULL;
+    }
+    
+    *data = CFDataCreate(allocator, payload, payload_size);
+
+    if (NULL == *data) {
+        SecCFDERCreateError(kSecDERErrorUnderlyingError, CFSTR("Failed to create data"), NULL, error);
+        return NULL;
+    }
+
+    return payload + payload_size;
+}
+
+
+size_t der_sizeof_data(CFDataRef data, CFErrorRef *error)
+{
+    return ccder_sizeof_raw_octet_string(CFDataGetLength(data));
+}
+
+
+uint8_t* der_encode_data(CFDataRef data, CFErrorRef *error,
+                         const uint8_t *der, uint8_t *der_end)
+{
+    const CFIndex data_length = CFDataGetLength(data);
+
+    return ccder_encode_tl(CCDER_OCTET_STRING, data_length, der,
+           ccder_encode_body(data_length, CFDataGetBytePtr(data), der, der_end));
+
+}
diff --git a/utilities/src/der_date.c b/utilities/src/der_date.c
new file mode 100644 (file)
index 0000000..e8a8e63
--- /dev/null
@@ -0,0 +1,406 @@
+//
+//  SecCFDER_CFDate.c
+//  utilities
+//
+//  Created by Michael Brouwer on 7/7/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#include "utilities/SecCFRelease.h"
+#include "utilities/der_date.h"
+#include "utilities/der_plist.h"
+#include "utilities/der_plist_internal.h"
+
+#include <corecrypto/ccder.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <math.h>
+
+#define NULL_TIME NAN
+
+CFAbsoluteTime SecCFGregorianDateGetAbsoluteTime(CFGregorianDate g, CFTimeInterval timeZoneOffset, CFErrorRef *error);
+CFGregorianDate SecCFAbsoluteTimeGetGregorianDate(CFAbsoluteTime at, CFTimeInterval timeZoneOffset, CFErrorRef *error);
+
+/* Cumalitive number of days in the year for months up to month i.  */
+static int mdays[13] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
+
+CFAbsoluteTime SecCFGregorianDateGetAbsoluteTime(CFGregorianDate g, CFTimeInterval timeZoneOffset, CFErrorRef *error) {
+    int day = g.day;
+    int is_leap_year = g.year % 4 == 0 && (g.year % 100 != 0 || g.year % 400 == 0) ? 1 : 0;
+    if (g.month < 1 || g.month > 12 || day < 1 || day > 31 || g.hour >= 24 || g.minute >= 60 || g.second >= 60.0
+        || (g.month == 2 && day > mdays[g.month] - mdays[g.month - 1] + is_leap_year)
+        || (g.month != 2 && day > mdays[g.month] - mdays[g.month - 1])) {
+        /* Invalid date. */
+        SecCFDERCreateError(-1000, CFSTR("Invalid date."), 0, error);
+        return NULL_TIME;
+    }
+
+    int dy = g.year - 2001;
+    if (dy < 0) {
+        dy += 1;
+        day -= 1;
+    }
+
+    int leap_days = dy / 4 - dy / 100 + dy / 400;
+    day += ((g.year - 2001) * 365 + leap_days) + mdays[g.month - 1] - 1;
+    if (g.month > 2)
+        day += is_leap_year;
+
+#if 0
+    int64_t time = day;
+    time *= 24;
+    time += g.hour;
+    time *= 60;
+    time += g.minute;
+    time *= 60;
+    time += lrint(g.second);
+    time -= lrint(timeZoneOffset);
+    return time;
+#else
+    CFAbsoluteTime absTime = (CFAbsoluteTime)((day * 24 + g.hour) * 60 + g.minute) * 60 + g.second;
+       return absTime - timeZoneOffset;
+#endif
+}
+
+CFGregorianDate SecCFAbsoluteTimeGetGregorianDate(CFAbsoluteTime at, CFTimeInterval timeZoneOffset, CFErrorRef *error) {
+    CFTimeZoneRef tz = CFTimeZoneCreateWithTimeIntervalFromGMT(0, timeZoneOffset);
+    if (!tz) {
+        SecCFDERCreateError(-1000, CFSTR("timezone creation failed."), 0, error);
+        CFGregorianDate g = {};
+        return g;
+    } else {
+        CFGregorianDate g = CFAbsoluteTimeGetGregorianDate(at, tz);
+        CFRelease(tz);
+        return g;
+    }
+}
+
+
+static int der_get_char(const uint8_t **der_p, const uint8_t *der_end,
+                         CFErrorRef *error) {
+    const uint8_t *der = *der_p;
+    if (!der) {
+        /* Don't create a new error in this case. */
+        return -1;
+    }
+
+    if (der >= der_end) {
+        SecCFDERCreateError(kSecDERErrorUnknownEncoding,
+                            CFSTR("Unexpected end of datetime"), 0, error);
+        *der_p = NULL;
+        return -1;
+    }
+
+    int ch = *der++;
+    *der_p = der;
+    return ch;
+}
+
+
+static int der_decode_decimal(const uint8_t **der_p, const uint8_t *der_end,
+                             CFErrorRef *error) {
+    char ch = der_get_char(der_p, der_end, error);
+    if (ch < '0' || ch > '9') {
+        SecCFDERCreateError(kSecDERErrorUnknownEncoding,
+                            CFSTR("Not a decimal digit"), 0, error);
+        *der_p = NULL;
+        return -1;
+    }
+    return ch - '0';
+}
+
+static int der_decode_decimal_pair(const uint8_t **der_p, const uint8_t *der_end,
+                            CFErrorRef *error) {
+    return (10 * der_decode_decimal(der_p, der_end, error))
+        + der_decode_decimal(der_p, der_end, error);
+}
+
+static int der_peek_byte(const uint8_t *der, const uint8_t *der_end) {
+    if (!der || der >= der_end)
+        return -1;
+
+    return *der;
+}
+
+static const uint8_t *der_decode_decimal_fraction(double *fraction, CFErrorRef *error,
+                                                  const uint8_t* der, const uint8_t *der_end) {
+    int ch = der_peek_byte(der, der_end);
+    if (ch == -1) {
+        der = NULL;
+    } else if (ch == '.') {
+        uint64_t divisor = 1;
+        uint64_t value = 0;
+        int last = -1;
+        while (++der < der_end) {
+            last = ch;
+            ch = *der;
+            if (ch < '0' || ch > '9') {
+                break;
+            }
+            if (divisor < UINT64_MAX / 10) {
+                divisor *= 10;
+                value *= 10;
+                value += (ch - '0');
+            }
+        }
+        if (der >= der_end)
+            der = NULL;
+        else if (last == '0') {
+            SecCFDERCreateError(kSecDERErrorUnknownEncoding,
+                                CFSTR("fraction ends in 0"), 0, error);
+            der = NULL;
+        } else if (last == '.') {
+            SecCFDERCreateError(kSecDERErrorUnknownEncoding,
+                                CFSTR("fraction without digits"), 0, error);
+            der = NULL;
+        } else {
+            *fraction = (double)value / divisor;
+        }
+    } else {
+        *fraction = 0.0;
+    }
+
+    return der;
+}
+
+static const CFTimeInterval der_decode_timezone_offset(const uint8_t **der_p,
+                                                       const uint8_t *der_end,
+                                                       CFErrorRef *error) {
+    CFTimeInterval timeZoneOffset;
+    int ch = der_get_char(der_p, der_end, error);
+    if (ch == 'Z') {
+        /* Zulu time. */
+        timeZoneOffset = 0.0;
+    } else {
+               /* ZONE INDICATOR */
+        int multiplier;
+        if (ch == '-')
+            multiplier = -60;
+        else if (ch == '+')
+            multiplier = +60;
+        else {
+            SecCFDERCreateError(kSecDERErrorUnknownEncoding,
+                                CFSTR("Invalid datetime character"), 0, error);
+            timeZoneOffset = NULL_TIME;
+        }
+        
+        timeZoneOffset = multiplier *
+            (der_decode_decimal_pair(der_p, der_end, error)
+             * 60 + der_decode_decimal_pair(der_p, der_end, error));
+    }
+    return timeZoneOffset;
+}
+
+static const uint8_t* der_decode_commontime_body(CFAbsoluteTime *at, CFErrorRef *error, SInt32 year,
+                                                 const uint8_t* der, const uint8_t *der_end)
+{
+    CFGregorianDate g;
+    g.year = year;
+       g.month = der_decode_decimal_pair(&der, der_end, error);
+       g.day = der_decode_decimal_pair(&der, der_end, error);
+       g.hour = der_decode_decimal_pair(&der, der_end, error);
+       g.minute = der_decode_decimal_pair(&der, der_end, error);
+    g.second = der_decode_decimal_pair(&der, der_end, error);
+    double fraction;
+    der = der_decode_decimal_fraction(&fraction, error, der, der_end);
+
+       CFTimeInterval timeZoneOffset = der_decode_timezone_offset(&der, der_end, error);
+
+#if 0
+    secdebug("dateparse",
+             "date %.*s year: %04d%02d%02d%02d%02d%02d%+05g",
+             length, bytes, g.year, g.month,
+             g.day, g.hour, g.minute, g.second,
+             timeZoneOffset / 60);
+#endif
+
+    if (der) {
+        if (der != der_end) {
+            SecCFDERCreateError(kSecDERErrorUnknownEncoding,
+                                CFSTR("trailing garbage at end of datetime"), 0, error);
+            return NULL;
+        }
+
+        *at = SecCFGregorianDateGetAbsoluteTime(g, timeZoneOffset, error) + fraction;
+        if (*at == NULL_TIME)
+            return NULL;
+    }
+
+    return der;
+}
+
+const uint8_t* der_decode_generalizedtime_body(CFAbsoluteTime *at, CFErrorRef *error,
+                                               const uint8_t* der, const uint8_t *der_end)
+{
+    SInt32 year = 100 * der_decode_decimal_pair(&der, der_end, error) + der_decode_decimal_pair(&der, der_end, error);
+    return der_decode_commontime_body(at, error, year, der, der_end);
+}
+
+const uint8_t* der_decode_universaltime_body(CFAbsoluteTime *at, CFErrorRef *error,
+                                             const uint8_t* der, const uint8_t *der_end)
+{
+    SInt32 year = der_decode_decimal_pair(&der, der_end, error);
+    if (year < 50) {
+        /* 0  <= year <  50 : assume century 21 */
+        year += 2000;
+    } else if (year < 70) {
+        /* 50 <= year <  70 : illegal per PKIX */
+        SecCFDERCreateError(kSecDERErrorUnknownEncoding,
+                            CFSTR("Invalid universal time year between 50 and 70"), 0, error);
+        der = NULL;
+    } else {
+        /* 70 <  year <= 99 : assume century 20 */
+        year += 1900;
+    }
+
+    return der_decode_commontime_body(at, error, year, der, der_end);
+}
+
+const uint8_t* der_decode_date(CFAllocatorRef allocator, CFOptionFlags mutability,
+                               CFDateRef* date, CFErrorRef *error,
+                               const uint8_t* der, const uint8_t *der_end)
+{
+    if (NULL == der)
+        return NULL;
+
+    der = ccder_decode_constructed_tl(CCDER_GENERALIZED_TIME, &der_end, der, der_end);
+    CFAbsoluteTime at;
+    der = der_decode_generalizedtime_body(&at, error, der, der_end);
+    if (der) {
+        *date = CFDateCreate(allocator, at);
+        if (NULL == *date) {
+            SecCFDERCreateError(kSecDERErrorUnderlyingError, CFSTR("Failed to create date"), NULL, error);
+            return NULL;
+        }
+    }
+    return der;
+}
+
+extern char *__dtoa(double _d, int mode, int ndigits, int *decpt, int *sign, char **rve);
+extern void  __freedtoa(char *);
+
+static size_t ccder_sizeof_nanoseconds(CFAbsoluteTime at) {
+    int dotoff;
+    int sign;
+    char *end;
+    char *str = __dtoa(at, 0, 0, &dotoff, &sign, &end);
+    ptrdiff_t len = end - str;
+    __freedtoa(str);
+    return len < dotoff ? 0 : len - dotoff;
+    //return len < dotoff ? 0 : len - dotoff > 9 ? 9 : len - dotoff;
+}
+
+size_t der_sizeof_generalizedtime_body(CFAbsoluteTime at, CFErrorRef *error)
+{
+    size_t subsec_digits = ccder_sizeof_nanoseconds(at);
+
+    /* Generalized zulu time YYYYMMDDhhmmss[.ssss]Z */
+    return subsec_digits ? 16 + subsec_digits : 15;
+}
+
+size_t der_sizeof_generalizedtime(CFAbsoluteTime at, CFErrorRef *error)
+{
+    return ccder_sizeof(CCDER_GENERALIZED_TIME,
+                        der_sizeof_generalizedtime_body(at, error));
+}
+
+size_t der_sizeof_date(CFDateRef date, CFErrorRef *error)
+{
+    return der_sizeof_generalizedtime(CFDateGetAbsoluteTime(date), error);
+}
+
+
+static uint8_t *ccder_encode_byte(uint8_t byte,
+                                  const uint8_t *der, uint8_t *der_end) {
+    if (der + 1 > der_end) {
+        return NULL;
+    }
+    *--der_end = byte;
+    return der_end;
+}
+
+static uint8_t *ccder_encode_decimal_pair(int v, const uint8_t *der,
+                                          uint8_t *der_end) {
+    if (der + 2 > der_end) {
+        return NULL;
+    }
+    assert(v < 100);
+    *--der_end = '0' + v % 10;
+    *--der_end = '0' + v / 10;
+    return der_end;
+}
+
+static uint8_t *ccder_encode_decimal_quad(int v, const uint8_t *der,
+                                          uint8_t *der_end) {
+    return ccder_encode_decimal_pair(v / 100, der,
+           ccder_encode_decimal_pair(v % 100, der, der_end));
+}
+
+static uint8_t *ccder_encode_nanoseconds(CFAbsoluteTime at, const uint8_t *der,
+                                         uint8_t *der_end) {
+    int dotoff;
+    int sign;
+    char *end;
+    char *str = __dtoa(at, 0, 0, &dotoff, &sign, &end);
+    char *begin = str + (dotoff < 0 ? 0 : dotoff);
+    // Compute 1.0000000 - fraction in ascii space
+    if (at < 0.0 && begin < end) {
+        char *p = end - 1;
+        // Borrow for last digit
+        *p = ('9' + 1) - (*p - '0');
+        while (p-- > begin) {
+            // Every other digit is a 9 since we borrowed from the last one
+            *p = '9' - (*p - '0');
+        }
+    }
+
+    ptrdiff_t len = end - str;
+    if (len > dotoff) {
+        if (dotoff < 0) {
+            assert(-1.0 < at && at < 1.0);
+            der_end = ccder_encode_body(len, (const uint8_t *)str, der, der_end);
+            der_end = ccder_encode_body_nocopy(-dotoff, der, der_end);
+            if (der_end)
+                memset(der_end, at < 0.0 ? '9' : '0', -dotoff);
+        } else {
+            der_end = ccder_encode_body(len - dotoff, (const uint8_t *)(str + dotoff), der, der_end);
+        }
+        der_end = ccder_encode_byte('.', der, der_end);
+    }
+    __freedtoa(str);
+
+    return der_end;
+}
+
+/* Encode generalized zulu time YYYYMMDDhhmmss[.ssss]Z */
+uint8_t* der_encode_generalizedtime_body(CFAbsoluteTime at, CFErrorRef *error,
+                                         const uint8_t *der, uint8_t *der_end)
+{
+    CFGregorianDate g = SecCFAbsoluteTimeGetGregorianDate(floor(at), 0.0, error);
+    if (g.year == 0)
+        return NULL;
+
+    return ccder_encode_decimal_quad(g.year, der,
+           ccder_encode_decimal_pair(g.month, der,
+           ccder_encode_decimal_pair(g.day, der,
+           ccder_encode_decimal_pair(g.hour, der,
+           ccder_encode_decimal_pair(g.minute, der,
+           ccder_encode_decimal_pair(g.second, der,
+           ccder_encode_nanoseconds(at, der,
+           ccder_encode_byte('Z', der, der_end))))))));
+}
+
+uint8_t* der_encode_generalizedtime(CFAbsoluteTime at, CFErrorRef *error,
+                                    const uint8_t *der, uint8_t *der_end)
+{
+    return ccder_encode_constructed_tl(CCDER_GENERALIZED_TIME, der_end, der,
+           der_encode_generalizedtime_body(at, error, der, der_end));
+}
+
+
+uint8_t* der_encode_date(CFDateRef date, CFErrorRef *error,
+                         const uint8_t *der, uint8_t *der_end)
+{
+    return der_encode_generalizedtime(CFDateGetAbsoluteTime(date), error,
+                                      der, der_end);
+}
diff --git a/utilities/src/der_date.h b/utilities/src/der_date.h
new file mode 100644 (file)
index 0000000..9fcb506
--- /dev/null
@@ -0,0 +1,27 @@
+//
+//  der_date.h
+//  utilities
+//
+//  Created by Michael Brouwer on 7/9/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#ifndef _UTILITIES_DER_DATE_H_
+#define _UTILITIES_DER_DATE_H_
+
+#include <CoreFoundation/CoreFoundation.h>
+
+const uint8_t* der_decode_generalizedtime_body(CFAbsoluteTime *at, CFErrorRef *error,
+                                               const uint8_t* der, const uint8_t *der_end);
+const uint8_t* der_decode_universaltime_body(CFAbsoluteTime *at, CFErrorRef *error,
+                                             const uint8_t* der, const uint8_t *der_end);
+
+size_t der_sizeof_generalizedtime(CFAbsoluteTime at, CFErrorRef *error);
+uint8_t* der_encode_generalizedtime(CFAbsoluteTime at, CFErrorRef *error,
+                                    const uint8_t *der, uint8_t *der_end);
+
+size_t der_sizeof_generalizedtime_body(CFAbsoluteTime at, CFErrorRef *error);
+uint8_t* der_encode_generalizedtime_body(CFAbsoluteTime at, CFErrorRef *error,
+                                         const uint8_t *der, uint8_t *der_end);
+
+#endif /* _UTILITIES_DER_DATE_H_ */
diff --git a/utilities/src/der_dictionary.c b/utilities/src/der_dictionary.c
new file mode 100644 (file)
index 0000000..eb70aef
--- /dev/null
@@ -0,0 +1,227 @@
+//
+//  der_dictionary.c
+//  utilities
+//
+//  Created by Mitch Adler on 6/18/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#include <stdio.h>
+
+#include "utilities/SecCFRelease.h"
+#include "utilities/der_plist.h"
+#include "utilities/der_plist_internal.h"
+#include "utilities/SecCFWrappers.h"
+
+#include <corecrypto/ccder.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+static const uint8_t* der_decode_key_value(CFAllocatorRef allocator, CFOptionFlags mutability,
+                                           CFPropertyListRef* key, CFPropertyListRef* value, CFErrorRef *error,
+                                           const uint8_t* der, const uint8_t *der_end)
+{
+    const uint8_t *payload_end = 0;
+    const uint8_t *payload = ccder_decode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, &payload_end, der, der_end);
+    
+    if (NULL == payload) {
+        SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Unknown data encoding, expected CCDER_CONSTRUCTED_SEQUENCE"), NULL, error);
+        return NULL;
+    }
+    
+    CFTypeRef keyObject = NULL;
+    CFTypeRef valueObject = NULL;
+    
+    
+    payload = der_decode_plist(allocator, mutability, &keyObject, error, payload, payload_end);
+    payload = der_decode_plist(allocator, mutability, &valueObject, error, payload, payload_end);
+
+    if (payload != NULL) {
+        *key = keyObject;
+        *value = valueObject;
+    } else {
+        CFReleaseNull(keyObject);
+        CFReleaseNull(valueObject);
+    }
+    return payload;
+}
+
+const uint8_t* der_decode_dictionary(CFAllocatorRef allocator, CFOptionFlags mutability,
+                                     CFDictionaryRef* dictionary, CFErrorRef *error,
+                                     const uint8_t* der, const uint8_t *der_end)
+{
+    if (NULL == der)
+        return NULL;
+
+    const uint8_t *payload_end = 0;
+    const uint8_t *payload = ccder_decode_constructed_tl(CCDER_CONSTRUCTED_SET, &payload_end, der, der_end);
+
+    if (NULL == payload) {
+        SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Unknown data encoding, expected CCDER_CONSTRUCTED_SET"), NULL, error);
+        return NULL;
+    }
+    
+    
+    CFMutableDictionaryRef dict = CFDictionaryCreateMutable(allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    
+    if (NULL == dict) {
+        SecCFDERCreateError(kSecDERErrorUnderlyingError, CFSTR("Failed to create data"), NULL, error);
+        payload = NULL;
+        goto exit;
+    }
+
+    while (payload != NULL && payload < payload_end) {
+        CFTypeRef key = NULL;
+        CFTypeRef value = NULL;
+        
+        payload = der_decode_key_value(allocator, mutability, &key, &value, error, payload, payload_end);
+        
+        if (payload) {
+            CFDictionaryAddValue(dict, key, value);
+            CFReleaseNull(key);
+            CFReleaseNull(value);
+        }
+    }
+    
+    
+exit:
+    if (payload == payload_end) {
+        *dictionary = dict;
+        dict = NULL;
+    }
+
+    CFReleaseNull(dict);
+
+    return payload;
+}
+
+struct size_context {
+    bool   success;
+    size_t size;
+    CFErrorRef *error;
+};
+
+static size_t der_sizeof_key_value(CFTypeRef key, CFTypeRef value, CFErrorRef *error) {
+    size_t key_size = der_sizeof_plist(key, error);
+    if (key_size == 0) {
+        return 0;
+    }
+    size_t value_size = der_sizeof_plist(value, error);
+    if (value_size == 0) {
+        return 0;
+    }
+    return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, key_size + value_size);
+}
+
+static void add_key_value_size(const void *key_void, const void *value_void, void *context_void)
+{
+    CFTypeRef key = (CFTypeRef) key_void;
+    CFTypeRef value = (CFTypeRef) value_void;
+    struct size_context *context = (struct size_context*) context_void;
+
+    if (!context->success)
+        return;
+
+    size_t kv_size = der_sizeof_key_value(key, value, context->error);
+    if (kv_size == 0) {
+        context->success = false;
+        return;
+    }
+
+    context->size += kv_size;
+}
+
+size_t der_sizeof_dictionary(CFDictionaryRef dict, CFErrorRef *error)
+{
+    struct size_context context = { .success = true, .size = 0, .error = error };
+
+    
+    CFDictionaryApplyFunction(dict, add_key_value_size, &context);
+    
+    if (!context.success)
+        return 0;
+
+    return ccder_sizeof(CCDER_CONSTRUCTED_SET, context.size);
+}
+
+static uint8_t* der_encode_key_value(CFPropertyListRef key, CFPropertyListRef value, CFErrorRef *error,
+                                     const uint8_t* der, uint8_t *der_end)
+{
+    return ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der,
+           der_encode_plist(key, error, der,
+           der_encode_plist(value, error, der, der_end)));
+}
+
+struct encode_context {
+    bool         success;
+    CFErrorRef * error;
+    CFMutableArrayRef list;
+    CFAllocatorRef allocator;
+};
+
+static void add_sequence_to_array(const void *key_void, const void *value_void, void *context_void)
+{
+    struct encode_context *context = (struct encode_context *) context_void;
+    if (context->success) {
+        CFTypeRef key = (CFTypeRef) key_void;
+        CFTypeRef value = (CFTypeRef) value_void;
+
+        size_t der_size = der_sizeof_key_value(key, value, context->error);
+        if (der_size == 0) {
+            context-> success = false;
+        } else {
+            CFMutableDataRef encoded_kv = CFDataCreateMutable(context->allocator, der_size);
+            CFDataSetLength(encoded_kv, der_size);
+
+            uint8_t* const encode_begin = CFDataGetMutableBytePtr(encoded_kv);
+            uint8_t* encode_end = encode_begin + der_size;
+
+            encode_end = der_encode_key_value(key, value, context->error, encode_begin, encode_end);
+
+            if (encode_end != NULL) {
+                CFDataDeleteBytes(encoded_kv, CFRangeMake(0, (encode_end - encode_begin)));
+                CFArrayAppendValue(context->list, encoded_kv);
+            } else {
+                context-> success = false;
+            }
+
+            CFReleaseNull(encoded_kv);
+        }
+    }
+}
+
+static CFComparisonResult cfdata_compare_contents(const void *val1, const void *val2, void *context __unused)
+{
+    return CFDataCompare((CFDataRef) val1, (CFDataRef) val2);
+}
+
+
+uint8_t* der_encode_dictionary(CFDictionaryRef dictionary, CFErrorRef *error,
+                               const uint8_t *der, uint8_t *der_end)
+{
+    CFMutableArrayRef elements = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+    
+    struct encode_context context = { .success = true, .error = error, .list = elements };
+    CFDictionaryApplyFunction(dictionary, add_sequence_to_array, &context);
+    
+    if (!context.success) {
+        CFReleaseNull(elements);
+        return NULL;
+    }
+    
+    CFRange allOfThem = CFRangeMake(0, CFArrayGetCount(elements));
+
+    CFArraySortValues(elements, allOfThem, cfdata_compare_contents, NULL);
+
+    uint8_t* original_der_end = der_end;
+
+    for(CFIndex position = CFArrayGetCount(elements); position > 0;) {
+        --position;
+        CFDataRef data = CFArrayGetValueAtIndex(elements, position);
+        der_end = ccder_encode_body(CFDataGetLength(data), CFDataGetBytePtr(data), der, der_end);
+    }
+
+    CFReleaseNull(elements);
+
+    return ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SET, original_der_end, der, der_end);
+
+}
diff --git a/utilities/src/der_null.c b/utilities/src/der_null.c
new file mode 100644 (file)
index 0000000..52e3944
--- /dev/null
@@ -0,0 +1,50 @@
+//
+//  der_null.c
+//  utilities
+//
+//  Created by Josh Osborne on 4/30/13.
+//  Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#include <stdio.h>
+
+#include "utilities/SecCFRelease.h"
+#include "utilities/der_plist.h"
+#include "utilities/der_plist_internal.h"
+
+#include <corecrypto/ccder.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+
+const uint8_t* der_decode_null(CFAllocatorRef allocator, CFOptionFlags mutability,
+                                  CFNullRef* nul, CFErrorRef *error,
+                                  const uint8_t* der, const uint8_t *der_end)
+{
+    if (NULL == der)
+        return NULL;
+       
+    size_t payload_size = 0;
+    const uint8_t *payload = ccder_decode_tl(CCDER_NULL, &payload_size, der, der_end);
+       
+       if (NULL == payload || payload_size != 0) {
+        SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Unknown null encoding"), NULL, error);
+        return NULL;
+    }
+       
+    *nul = kCFNull;
+       
+    return payload + payload_size;
+}
+
+
+size_t der_sizeof_null(CFNullRef data __unused, CFErrorRef *error)
+{
+    return ccder_sizeof(CCDER_NULL, 0);
+}
+
+
+uint8_t* der_encode_null(CFNullRef boolean __unused, CFErrorRef *error,
+                            const uint8_t *der, uint8_t *der_end)
+{
+       return ccder_encode_tl(CCDER_NULL, 0, der, der_end);
+}
diff --git a/utilities/src/der_number.c b/utilities/src/der_number.c
new file mode 100644 (file)
index 0000000..979b97b
--- /dev/null
@@ -0,0 +1,122 @@
+//
+//  der_number.c
+//  utilities
+//
+//  Created by Mitch Adler on 6/19/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+
+#include <stdio.h>
+
+#include "utilities/SecCFRelease.h"
+#include "utilities/der_plist.h"
+#include "utilities/der_plist_internal.h"
+
+#include <corecrypto/ccder.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+
+const uint8_t* der_decode_number(CFAllocatorRef allocator, CFOptionFlags mutability,
+                                 CFNumberRef* number, CFErrorRef *error,
+                                 const uint8_t* der, const uint8_t *der_end)
+{
+    if (NULL == der)
+        return NULL;
+
+    size_t payload_size = 0;
+    const uint8_t *payload = ccder_decode_tl(CCDER_INTEGER, &payload_size, der, der_end);
+
+    if (NULL == payload || (der_end - payload) < payload_size) {
+        SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Unknown number encoding"), NULL, error);
+        return NULL;
+    }
+    if (payload_size > sizeof(long long)) {
+        SecCFDERCreateError(kSecDERErrorUnsupportedNumberType, CFSTR("Number too large"), NULL, error);
+        return NULL;
+
+    }
+
+    long long value = 0;
+    
+    if (payload_size > 0) {
+        if ((*payload & 0x80) == 0x80)
+            value = -1; // Negative integers fill with 1s so we end up negative.
+        
+        const uint8_t* const payload_end = payload + payload_size;
+        
+        for (const uint8_t *payload_byte = payload;
+             payload_byte < payload_end;
+             ++payload_byte) {
+            value <<= 8;
+            value |= *payload_byte;
+        }
+    }
+
+    *number = CFNumberCreate(allocator, kCFNumberLongLongType, &value);
+    
+    if (*number == NULL) {
+        SecCFDERCreateError(kSecDERErrorAllocationFailure, CFSTR("Number allocation failed"), NULL, error);
+        return NULL;
+    }
+    
+    return payload + payload_size;
+}
+
+
+static inline uint8_t byte_of(size_t byteNumber, long long value)
+{
+    return value >> (8 * (byteNumber - 1));
+}
+
+static inline size_t bytes_when_encoded(long long value)
+{
+    size_t bytes_encoded = sizeof(long long);
+    
+    uint8_t first_byte = byte_of(bytes_encoded, value);
+    
+    // Skip initial 0xFFs or 0x00
+    if (first_byte == 0xFF || first_byte == 0x00) {
+        do {
+            --bytes_encoded;
+        } while (bytes_encoded > 1 && (byte_of(bytes_encoded, value) == first_byte));
+        
+        if ((first_byte & 0x80) != (byte_of(bytes_encoded, value) & 0x80))
+            bytes_encoded += 1;
+    }
+    
+    return bytes_encoded;
+}
+
+size_t der_sizeof_number(CFNumberRef data, CFErrorRef *error)
+{
+    long long value;
+    if (!CFNumberGetValue(data, kCFNumberLongLongType, &value))
+        return 0;
+    
+    return ccder_sizeof(CCDER_INTEGER, bytes_when_encoded(value));
+}
+
+uint8_t* der_encode_number(CFNumberRef number, CFErrorRef *error,
+                           const uint8_t *der, uint8_t *der_end)
+{
+    long long value;
+    if (!CFNumberGetValue(number, kCFNumberLongLongType, &value))
+        return NULL;
+    
+    size_t first_byte_to_include = bytes_when_encoded(value);
+    
+    if (!der_end || der_end - der < first_byte_to_include)
+        return NULL;
+
+    // Put the bytes we should include on the end.
+    for(int bytes_included = 0; bytes_included < first_byte_to_include; ++bytes_included)
+    {
+        --der_end;
+        *der_end = value & 0xFF;
+        value >>= 8;
+    }
+
+    return ccder_encode_tl(CCDER_INTEGER, first_byte_to_include, der, der_end);
+
+}
diff --git a/utilities/src/der_plist.c b/utilities/src/der_plist.c
new file mode 100644 (file)
index 0000000..6899aa1
--- /dev/null
@@ -0,0 +1,131 @@
+//
+//  der_plist.c
+//  utilities
+//
+//  Created by Mitch Adler on 7/2/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#include <stdio.h>
+
+#include "utilities/SecCFRelease.h"
+#include "utilities/der_plist.h"
+#include "utilities/der_plist_internal.h"
+
+#include <corecrypto/ccder.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+//
+// der..CFPropertyList
+//
+// We support:
+//
+//   CFBoolean
+//   CFData
+//   CFDate
+//   CFString
+//   CFNumber
+//   CFNull
+//
+//   CFArray
+//   CFDictionary
+//
+//
+
+const uint8_t* der_decode_plist(CFAllocatorRef allocator, CFOptionFlags mutability,
+                                CFPropertyListRef* pl, CFErrorRef *error,
+                                const uint8_t* der, const uint8_t *der_end)
+{    if (NULL == der)
+    return NULL;
+
+    ccder_tag tag;
+    if (NULL == ccder_decode_tag(&tag, der, der_end))
+        return NULL;
+
+    switch (tag) {
+               case CCDER_NULL:
+                       return der_decode_null(allocator, mutability, (CFNullRef*)pl, error, der, der_end);
+        case CCDER_BOOLEAN:
+            return der_decode_boolean(allocator, mutability, (CFBooleanRef*)pl, error, der, der_end);
+        case CCDER_OCTET_STRING:
+            return der_decode_data(allocator, mutability, (CFDataRef*)pl, error, der, der_end);
+        case CCDER_GENERALIZED_TIME:
+            return der_decode_date(allocator, mutability, (CFDateRef*)pl, error, der, der_end);
+        case CCDER_CONSTRUCTED_SEQUENCE:
+            return der_decode_array(allocator, mutability, (CFArrayRef*)pl, error, der, der_end);
+        case CCDER_UTF8_STRING:
+            return der_decode_string(allocator, mutability, (CFStringRef*)pl, error, der, der_end);
+        case CCDER_INTEGER:
+            return der_decode_number(allocator, mutability, (CFNumberRef*)pl, error, der, der_end);
+        case CCDER_CONSTRUCTED_SET:
+            return der_decode_dictionary(allocator, mutability, (CFDictionaryRef*)pl, error, der, der_end);
+        default:
+            SecCFDERCreateError(kSecDERErrorUnsupportedDERType, CFSTR("Unsupported DER Type"), NULL, error);
+            return NULL;
+    }
+}
+
+
+size_t der_sizeof_plist(CFPropertyListRef pl, CFErrorRef *error)
+{
+    if (!pl) {
+        SecCFDERCreateError(kSecDERErrorUnsupportedCFObject, CFSTR("Null CFType"), NULL, error);
+        return 0;
+    }
+
+    CFTypeID  dataType = CFGetTypeID(pl);
+
+    if (CFArrayGetTypeID() == dataType)
+        return der_sizeof_array((CFArrayRef) pl, error);
+    else if (CFBooleanGetTypeID() == dataType)
+        return der_sizeof_boolean((CFBooleanRef) pl, error);
+    else if (CFDataGetTypeID() == dataType)
+        return der_sizeof_data((CFDataRef) pl, error);
+    else if (CFDateGetTypeID() == dataType)
+        return der_sizeof_date((CFDateRef) pl, error);
+    else if (CFDictionaryGetTypeID() == dataType)
+        return der_sizeof_dictionary((CFDictionaryRef) pl, error);
+    else if (CFStringGetTypeID() == dataType)
+        return der_sizeof_string((CFStringRef) pl, error);
+    else if (CFNumberGetTypeID() == dataType)
+        return der_sizeof_number((CFNumberRef) pl, error);
+       if (CFNullGetTypeID() == dataType)
+               return der_sizeof_null((CFNullRef) pl, error);
+       else {
+        SecCFDERCreateError(kSecDERErrorUnsupportedCFObject, CFSTR("Unsupported CFType"), NULL, error);
+        return 0;
+    }
+}
+
+
+uint8_t* der_encode_plist(CFPropertyListRef pl, CFErrorRef *error,
+                          const uint8_t *der, uint8_t *der_end)
+{
+    if (!pl) {
+        SecCFDERCreateError(kSecDERErrorUnsupportedCFObject, CFSTR("Null CFType"), NULL, error);
+        return NULL;
+    }
+
+    CFTypeID  dataType = CFGetTypeID(pl);
+
+    if (CFArrayGetTypeID() == dataType)
+        return der_encode_array((CFArrayRef) pl, error, der, der_end);
+    else if (CFBooleanGetTypeID() == dataType)
+        return der_encode_boolean((CFBooleanRef) pl, error, der, der_end);
+    else if (CFDataGetTypeID() == dataType)
+        return der_encode_data((CFDataRef) pl, error, der, der_end);
+    else if (CFDateGetTypeID() == dataType)
+        return der_encode_date((CFDateRef) pl, error, der, der_end);
+    else if (CFDictionaryGetTypeID() == dataType)
+        return der_encode_dictionary((CFDictionaryRef) pl, error, der, der_end);
+    else if (CFStringGetTypeID() == dataType)
+        return der_encode_string((CFStringRef) pl, error, der, der_end);
+    else if (CFNumberGetTypeID() == dataType)
+        return der_encode_number((CFNumberRef) pl, error, der, der_end);
+       else if (CFNullGetTypeID() == dataType)
+               return der_encode_null((CFNullRef) pl, error, der, der_end);
+    else {
+        SecCFDERCreateError(kSecDERErrorUnsupportedCFObject, CFSTR("Unsupported CFType"), NULL, error);
+        return NULL;
+    }
+}
diff --git a/utilities/src/der_plist.h b/utilities/src/der_plist.h
new file mode 100644 (file)
index 0000000..f7e4720
--- /dev/null
@@ -0,0 +1,39 @@
+//
+//  der_plist.h
+//  utilities
+//
+//  Created by Mitch Adler on 6/18/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#ifndef _DER_PLIST_H_
+#define _DER_PLIST_H_
+
+#include <CoreFoundation/CoreFoundation.h>
+
+//
+// Error Codes for PropertyList <-> DER
+//
+
+static const CFIndex kSecDERErrorUnknownEncoding = -1;
+static const CFIndex kSecDERErrorUnsupportedCFObject = -2;
+static const CFIndex kSecDERErrorUnsupportedDERType = -2;
+static const CFIndex kSecDERErrorAllocationFailure = -3;
+static const CFIndex kSecDERErrorUnsupportedNumberType = -4;
+
+static const CFIndex kSecDERErrorUnderlyingError = -100;
+
+extern CFStringRef sSecDERErrorDomain;
+
+// PropertyList <-> DER Functions
+
+size_t der_sizeof_plist(CFPropertyListRef pl, CFErrorRef *error);
+
+uint8_t* der_encode_plist(CFPropertyListRef pl, CFErrorRef *error,
+                           const uint8_t *der, uint8_t *der_end);
+
+const uint8_t* der_decode_plist(CFAllocatorRef pl, CFOptionFlags mutability,
+                                CFPropertyListRef* cf, CFErrorRef *error,
+                                const uint8_t* der, const uint8_t *der_end);
+
+#endif
diff --git a/utilities/src/der_plist_internal.c b/utilities/src/der_plist_internal.c
new file mode 100644 (file)
index 0000000..f99d123
--- /dev/null
@@ -0,0 +1,18 @@
+//
+//  SecCFToDER.c
+//  utilities
+//
+//  Created by Mitch Adler on 7/2/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#include "utilities/der_plist_internal.h"
+#include "utilities/SecCFError.h"
+#include "utilities/SecCFRelease.h"
+#include <CoreFoundation/CoreFoundation.h>
+
+CFStringRef sSecDERErrorDomain = CFSTR("com.apple.security.cfder.error");
+
+void SecCFDERCreateError(CFIndex errorCode, CFStringRef descriptionString, CFErrorRef previousError, CFErrorRef *newError) {
+    SecCFCreateError(errorCode, sSecDERErrorDomain, descriptionString, previousError, newError);
+}
diff --git a/utilities/src/der_plist_internal.h b/utilities/src/der_plist_internal.h
new file mode 100644 (file)
index 0000000..5ab3038
--- /dev/null
@@ -0,0 +1,105 @@
+//
+//  der_plist_internal.h
+//  utilities
+//
+//  Created by Mitch Adler on 7/2/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#ifndef _DER_PLIST_INTERNAL_H_
+#define _DER_PLIST_INTERNAL_H_
+
+#include <CoreFoundation/CoreFoundation.h>
+
+void SecCFDERCreateError(CFIndex errorCode, CFStringRef descriptionString, CFErrorRef previousError, CFErrorRef *newError);
+
+
+// CFArray <-> DER
+size_t der_sizeof_array(CFArrayRef array, CFErrorRef *error);
+
+uint8_t* der_encode_array(CFArrayRef array, CFErrorRef *error,
+                          const uint8_t *der, uint8_t *der_end);
+
+const uint8_t* der_decode_array(CFAllocatorRef allocator, CFOptionFlags mutability,
+                                CFArrayRef* array, CFErrorRef *error,
+                                const uint8_t* der, const uint8_t *der_end);
+
+// CFNull <-> DER
+size_t der_sizeof_null(CFNullRef       nul, CFErrorRef *error);
+
+uint8_t* der_encode_null(CFNullRef     nul, CFErrorRef *error,
+                            const uint8_t *der, uint8_t *der_end);
+
+const uint8_t* der_decode_null(CFAllocatorRef allocator, CFOptionFlags mutability,
+                                  CFNullRef    *nul, CFErrorRef *error,
+                                  const uint8_t* der, const uint8_t *der_end);
+
+
+// CFBoolean <-> DER
+size_t der_sizeof_boolean(CFBooleanRef boolean, CFErrorRef *error);
+
+uint8_t* der_encode_boolean(CFBooleanRef boolean, CFErrorRef *error,
+                            const uint8_t *der, uint8_t *der_end);
+
+const uint8_t* der_decode_boolean(CFAllocatorRef allocator, CFOptionFlags mutability,
+                                  CFBooleanRef* boolean, CFErrorRef *error,
+                                  const uint8_t* der, const uint8_t *der_end);
+
+// CFData <-> DER
+size_t der_sizeof_data(CFDataRef data, CFErrorRef *error);
+
+uint8_t* der_encode_data(CFDataRef data, CFErrorRef *error,
+                         const uint8_t *der, uint8_t *der_end);
+
+const uint8_t* der_decode_data(CFAllocatorRef allocator, CFOptionFlags mutability,
+                               CFDataRef* data, CFErrorRef *error,
+                               const uint8_t* der, const uint8_t *der_end);
+
+const uint8_t* der_decode_data_mutable(CFAllocatorRef allocator, CFOptionFlags mutability,
+                                       CFMutableDataRef* data, CFErrorRef *error,
+                                       const uint8_t* der, const uint8_t *der_end);
+
+
+// CFDate <-> DER
+size_t der_sizeof_date(CFDateRef date, CFErrorRef *error);
+
+uint8_t* der_encode_date(CFDateRef date, CFErrorRef *error,
+                         const uint8_t *der, uint8_t *der_end);
+
+const uint8_t* der_decode_date(CFAllocatorRef allocator, CFOptionFlags mutability,
+                               CFDateRef* date, CFErrorRef *error,
+                               const uint8_t* der, const uint8_t *der_end);
+
+
+// CFDictionary <-> DER
+size_t der_sizeof_dictionary(CFDictionaryRef dictionary, CFErrorRef *error);
+
+uint8_t* der_encode_dictionary(CFDictionaryRef dictionary, CFErrorRef *error,
+                               const uint8_t *der, uint8_t *der_end);
+
+const uint8_t* der_decode_dictionary(CFAllocatorRef allocator, CFOptionFlags mutability,
+                                     CFDictionaryRef* dictionary, CFErrorRef *error,
+                                     const uint8_t* der, const uint8_t *der_end);
+
+// CFNumber <-> DER
+// Currently only supports signed 64 bit values. No floating point.
+size_t der_sizeof_number(CFNumberRef number, CFErrorRef *error);
+
+uint8_t* der_encode_number(CFNumberRef number, CFErrorRef *error,
+                           const uint8_t *der, uint8_t *der_end);
+
+const uint8_t* der_decode_number(CFAllocatorRef allocator, CFOptionFlags mutability,
+                                 CFNumberRef* number, CFErrorRef *error,
+                                 const uint8_t* der, const uint8_t *der_end);
+
+// CFString <-> DER
+size_t der_sizeof_string(CFStringRef string, CFErrorRef *error);
+
+uint8_t* der_encode_string(CFStringRef string, CFErrorRef *error,
+                           const uint8_t *der, uint8_t *der_end);
+
+const uint8_t* der_decode_string(CFAllocatorRef allocator, CFOptionFlags mutability,
+                                 CFStringRef* string, CFErrorRef *error,
+                                 const uint8_t* der, const uint8_t *der_end);
+
+#endif
diff --git a/utilities/src/der_string.c b/utilities/src/der_string.c
new file mode 100644 (file)
index 0000000..67199f3
--- /dev/null
@@ -0,0 +1,78 @@
+//
+//  der_string.c
+//  utilities
+//
+//  Created by Mitch Adler on 6/18/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#include <stdio.h>
+
+#include "utilities/SecCFRelease.h"
+#include "utilities/der_plist.h"
+#include "utilities/der_plist_internal.h"
+
+#include <corecrypto/ccder.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+
+const uint8_t* der_decode_string(CFAllocatorRef allocator, CFOptionFlags mutability,
+                                 CFStringRef* string, CFErrorRef *error,
+                                 const uint8_t* der, const uint8_t *der_end)
+{
+    if (NULL == der)
+        return NULL;
+
+    size_t payload_size = 0;
+    const uint8_t *payload = ccder_decode_tl(CCDER_UTF8_STRING, &payload_size, der, der_end);
+
+    if (NULL == payload || (der_end - payload) < payload_size){
+        SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Unknown string encoding"), NULL, error);
+        return NULL;
+    }
+
+    *string = CFStringCreateWithBytes(allocator, payload, payload_size, kCFStringEncodingUTF8, false);
+
+    if (NULL == *string) {
+        SecCFDERCreateError(kSecDERErrorAllocationFailure, CFSTR("String allocation failed"), NULL, error);
+        return NULL;
+    }
+
+    return payload + payload_size;
+}
+
+
+size_t der_sizeof_string(CFStringRef str, CFErrorRef *error)
+{
+    const CFIndex str_length    = CFStringGetLength(str);
+    const CFIndex maximum       = CFStringGetMaximumSizeForEncoding(str_length, kCFStringEncodingUTF8);
+
+    CFIndex encodedLen = 0;
+    CFIndex converted = CFStringGetBytes(str, CFRangeMake(0, str_length), kCFStringEncodingUTF8, 0, false, NULL, maximum, &encodedLen);
+
+    return ccder_sizeof(CCDER_UTF8_STRING, (converted == str_length) ? encodedLen : 0);
+}
+
+
+uint8_t* der_encode_string(CFStringRef string, CFErrorRef *error,
+                           const uint8_t *der, uint8_t *der_end)
+{
+    // Obey the NULL allowed rules.
+    if (!der_end)
+        return NULL;
+
+    const CFIndex str_length = CFStringGetLength(string);
+
+    ptrdiff_t der_space = der_end - der;
+    CFIndex bytes_used = 0;
+    uint8_t *buffer = der_end - der_space;
+    CFIndex converted = CFStringGetBytes(string, CFRangeMake(0, str_length), kCFStringEncodingUTF8, 0, false, buffer, der_space, &bytes_used);
+    if (converted != str_length){
+        SecCFDERCreateError(kSecDERErrorUnderlyingError, CFSTR("String extraction failed"), NULL, error);
+        return NULL;
+    }
+
+    return ccder_encode_tl(CCDER_UTF8_STRING, bytes_used, der,
+           ccder_encode_body(bytes_used, buffer, der, der_end));
+
+}
diff --git a/utilities/src/fileIo.c b/utilities/src/fileIo.c
new file mode 100644 (file)
index 0000000..5c2ff64
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2005-2007,2010 Apple Inc. All Rights Reserved.
+ */
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdint.h>
+#include "fileIo.h"
+
+int writeFile(
+       const char                      *fileName,
+       const unsigned char     *bytes,
+       size_t              numBytes)
+{
+       int             rtn;
+       int     fd;
+    ssize_t wrc;
+
+    if (!fileName) {
+        fwrite(bytes, 1, numBytes, stdout);
+        fflush(stdout);
+        return ferror(stdout);
+    }
+
+       fd = open(fileName, O_RDWR | O_CREAT | O_TRUNC, 0600);
+       if(fd <= 0) {
+               return errno;
+       }
+       wrc = write(fd, bytes, (size_t)numBytes);
+       if(wrc != numBytes) {
+               if(wrc >= 0) {
+                       fprintf(stderr, "writeFile: short write\n");
+               }
+               rtn = EIO;
+       }
+       else {
+               rtn = 0;
+       }
+       close(fd);
+       return rtn;
+}
+
+/*
+ * Read entire file.
+ */
+int readFile(
+       const char              *fileName,
+       unsigned char   **bytes,                // mallocd and returned
+       size_t          *numBytes)              // returned
+{
+       int rtn;
+       int fd;
+       char *buf;
+       struct stat     sb;
+       size_t size;
+    ssize_t rrc;
+
+       *numBytes = 0;
+       *bytes = NULL;
+       fd = open(fileName, O_RDONLY);
+       if(fd <= 0) {
+               return errno;
+       }
+       rtn = fstat(fd, &sb);
+       if(rtn) {
+               goto errOut;
+       }
+       if (sb.st_size > SIZE_MAX) {
+               rtn = EFBIG;
+               goto errOut;
+       }
+       size = (size_t)sb.st_size;
+       buf = (char *)malloc(size);
+       if(buf == NULL) {
+               rtn = ENOMEM;
+               goto errOut;
+       }
+       rrc = read(fd, buf, size);
+       if(rrc != size) {
+               if(rtn >= 0) {
+            free(buf);
+                       fprintf(stderr, "readFile: short read\n");
+               }
+               rtn = EIO;
+       }
+       else {
+               rtn = 0;
+               *bytes = (unsigned char *)buf;
+               *numBytes = size;
+       }
+
+errOut:
+       close(fd);
+       return rtn;
+}
diff --git a/utilities/src/fileIo.h b/utilities/src/fileIo.h
new file mode 100644 (file)
index 0000000..f23ba03
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2005-2007,2010 Apple Inc. All Rights Reserved.
+ */
+
+#include <sys/types.h>
+
+/*
+ * Read entire file.
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int readFile(
+       const char                      *fileName,
+       unsigned char           **bytes,                // mallocd and returned
+       size_t              *numBytes);         // returned
+
+int writeFile(
+       const char                      *fileName,
+       const unsigned char     *bytes,
+       size_t              numBytes);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/utilities/src/iCloudKeychainTrace.c b/utilities/src/iCloudKeychainTrace.c
new file mode 100644 (file)
index 0000000..5b744ae
--- /dev/null
@@ -0,0 +1,195 @@
+//
+//  iCloudKeychainTrace.c
+//  utilities
+//
+//  Created  on 7/17/13.
+//  Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#include "iCloudKeychainTrace.h"
+#include <TargetConditionals.h>
+#include <inttypes.h>
+#include "SecCFWrappers.h"
+
+const CFStringRef kCloudKeychainNumbrerOfSyncingConflicts = CFSTR("com.apple.cloudkeychain.conflictsCount");
+const CFStringRef kCloudKeychainNumberOfTimesSyncFailed = CFSTR("com.apple.cloudkeychain.syncFailureCount");
+const CFStringRef kCloudKeychainNumberOfConflictsResolved = CFSTR("com.apple.cloudkeychain.conflictsResolved");
+const CFStringRef kCloudKeychainNumberOfTimesSyncedWithPeers = CFSTR("com.apple.cloudkeychain.syncedWithPeers");
+
+static const CFStringRef gMessageTracerPrefix = CFSTR("com.apple.message.");
+
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR))
+#include <asl.h>
+
+static const char* gMessageTracerDomainField = "com.apple.message.domain";
+//static const char* gTopLevelKeyForiCloudKeychainTracing = "com.apple.cloudkeychain";
+
+static bool OSX_SetCloudKeychainTraceValueForKey(CFStringRef key, int64_t value)
+{
+       bool result = false;
+       
+       if (NULL == key)
+       {
+               return result;
+       }
+       
+       aslmsg mAsl = NULL;
+       mAsl = asl_new(ASL_TYPE_MSG);
+       if (NULL == mAsl)
+       {
+               return result;
+       }
+    
+    CFIndex key_length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(key), kCFStringEncodingUTF8);
+    key_length += 1; // For null
+    char base_key_buffer[key_length];
+    memset(base_key_buffer, 0,key_length);
+    if (!CFStringGetCString(key, base_key_buffer, key_length, kCFStringEncodingUTF8))
+    {
+        asl_free(mAsl);
+         return result;
+    }
+    
+    
+    CFStringRef key_str = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@%@"), gMessageTracerPrefix, key);
+    if (NULL == key_str)
+    {
+        asl_free(mAsl);
+        return result;
+    }
+       
+       CFStringRef value_str = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%lld"), value);
+    if (NULL == value_str)
+    {
+        asl_free(mAsl);
+        CFRelease(key_str);
+        return result;
+    }
+    
+    CFIndex key_str_numBytes = CFStringGetMaximumSizeForEncoding(CFStringGetLength(key_str), kCFStringEncodingUTF8);
+    key_str_numBytes += 1; // For null
+    char key_buffer[key_str_numBytes];
+    memset(key_buffer, 0, key_str_numBytes);
+    if (!CFStringGetCString(key_str, key_buffer, key_str_numBytes, kCFStringEncodingUTF8))
+    {
+        asl_free(mAsl);
+        CFRelease(key_str);
+        CFRelease(value_str);
+        return result;
+    }
+    CFRelease(key_str);
+    
+    CFIndex value_str_numBytes = CFStringGetMaximumSizeForEncoding(CFStringGetLength(value_str), kCFStringEncodingUTF8);
+    value_str_numBytes += 1; // For null
+    char value_buffer[value_str_numBytes];
+    memset(value_buffer, 0, value_str_numBytes);
+    if (!CFStringGetCString(value_str, value_buffer, value_str_numBytes, kCFStringEncodingUTF8))
+    {
+        asl_free(mAsl);
+        CFRelease(value_str);
+        return result;
+    }
+    CFRelease(value_str);
+       
+       asl_set(mAsl, gMessageTracerDomainField, base_key_buffer);
+       
+       asl_set(mAsl, key_buffer, value_buffer);
+       asl_log(NULL, mAsl, ASL_LEVEL_NOTICE, "%s is %lld", key_buffer, value);
+       asl_free(mAsl);
+       return true;
+}
+#endif
+
+#if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR)
+
+typedef void (*type_ADClientClearScalarKey)(CFStringRef key);
+typedef void (*type_ADClientAddValueForScalarKey)(CFStringRef key, int64_t value);
+
+static type_ADClientClearScalarKey gADClientClearScalarKey = NULL;
+static type_ADClientAddValueForScalarKey gADClientAddValueForScalarKey = NULL;
+
+static dispatch_once_t gADFunctionPointersSet = 0;
+static CFBundleRef gAggdBundleRef = NULL;
+static bool gFunctionPointersAreLoaded = false;
+
+static bool InitializeADFunctionPointers()
+{    
+       if (gFunctionPointersAreLoaded)
+       {
+               return gFunctionPointersAreLoaded;
+       }
+    
+    dispatch_once(&gADFunctionPointersSet,
+      ^{
+          CFStringRef path_to_aggd_framework = CFSTR("/System/Library/PrivateFrameworks/AggregateDictionary.framework");
+          
+          CFURLRef aggd_url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path_to_aggd_framework, kCFURLPOSIXPathStyle, true);
+          
+          if (NULL != aggd_url)
+          {
+              gAggdBundleRef = CFBundleCreate(kCFAllocatorDefault, aggd_url);
+              if (NULL != gAggdBundleRef)
+              {  
+                  gADClientClearScalarKey = (type_ADClientClearScalarKey)
+                    CFBundleGetFunctionPointerForName(gAggdBundleRef, CFSTR("ADClientClearScalarKey"));
+                  
+                  gADClientAddValueForScalarKey = (type_ADClientAddValueForScalarKey)
+                    CFBundleGetFunctionPointerForName(gAggdBundleRef, CFSTR("ADClientAddValueForScalarKey"));
+              }
+              CFRelease(aggd_url);
+          }
+      });
+    
+    gFunctionPointersAreLoaded = ((NULL != gADClientClearScalarKey) && (NULL != gADClientAddValueForScalarKey));
+    return gFunctionPointersAreLoaded;
+}
+
+static void Internal_ADClientClearScalarKey(CFStringRef key)
+{
+    if (InitializeADFunctionPointers())
+    {
+        gADClientClearScalarKey(key);
+    }
+}
+
+static void Internal_ADClientAddValueForScalarKey(CFStringRef key, int64_t value)
+{
+    if (InitializeADFunctionPointers())
+    {
+        gADClientAddValueForScalarKey(key, value);
+    }
+}
+
+static bool iOS_SetCloudKeychainTraceValueForKey(CFStringRef key, int64_t value)
+{
+       if (NULL == key)
+       {
+               return false;
+       }
+    
+    if (0LL == value)
+    {
+        Internal_ADClientClearScalarKey(key);
+    }
+    else
+    {
+        Internal_ADClientAddValueForScalarKey(key, value);
+    }
+       return true;
+}
+#endif
+
+bool SetCloudKeychainTraceValueForKey(CFStringRef key, int64_t value)
+{
+#if (TARGET_IPHONE_SIMULATOR)
+       return false;
+#endif 
+
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+       return OSX_SetCloudKeychainTraceValueForKey(key, value);
+#endif
+
+#if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR)
+       return iOS_SetCloudKeychainTraceValueForKey(key, value);
+#endif
+}
diff --git a/utilities/src/iCloudKeychainTrace.h b/utilities/src/iCloudKeychainTrace.h
new file mode 100644 (file)
index 0000000..4f635f5
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2006-2007,2009-2010 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * iCloudKeychainTrace.h - log statistics for iCloud Keychain usage
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+
+const CFStringRef kCloudKeychainNumbrerOfSyncingConflicts
+       __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+const CFStringRef kCloudKeychainNumberOfTimesSyncFailed
+       __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+const CFStringRef kCloudKeychainNumberOfConflictsResolved
+       __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+const CFStringRef kCloudKeychainNumberOfTimesSyncedWithPeers
+    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+
+bool SetCloudKeychainTraceValueForKey(CFStringRef key, int64_t value)  
+       __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+
+
diff --git a/utilities/src/iOSforOSX-SecAttr.c b/utilities/src/iOSforOSX-SecAttr.c
new file mode 100644 (file)
index 0000000..9b34f28
--- /dev/null
@@ -0,0 +1,27 @@
+//
+//  iOSforOSX.c
+//  utilities
+//
+//  Created by J Osborne on 11/13/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#include <TargetConditionals.h>
+
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <sys/types.h>
+#include <pwd.h>
+#include <uuid/uuid.h>
+#include "iOSforOSX.h"
+#include <pwd.h>
+#include <unistd.h>
+
+// Was in SOSAccount.c
+#define SEC_CONST_DECL(k,v) CFTypeRef k = (CFTypeRef)(CFSTR(v));
+// We may not have all of these we need
+SEC_CONST_DECL (kSecAttrAccessible, "pdmn");
+SEC_CONST_DECL (kSecAttrAccessibleAlwaysThisDeviceOnly, "dku");
+
+#endif
diff --git a/utilities/src/iOSforOSX-SecRandom.c b/utilities/src/iOSforOSX-SecRandom.c
new file mode 100644 (file)
index 0000000..4950cb2
--- /dev/null
@@ -0,0 +1,13 @@
+//
+//  iOSforOSX.c
+//  utilities
+//
+//  Created by J Osborne on 11/13/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#include <TargetConditionals.h>
+
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+const void *kSecRandomDefault = (void*)0;
+#endif
diff --git a/utilities/src/iOSforOSX.c b/utilities/src/iOSforOSX.c
new file mode 100644 (file)
index 0000000..d17cbef
--- /dev/null
@@ -0,0 +1,67 @@
+//
+//  iOSforOSX.c
+//  utilities
+//
+//  Created by J Osborne on 11/13/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#include <TargetConditionals.h>
+
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <AssertMacros.h>
+#include <utilities/SecCFWrappers.h>
+
+#include <sys/types.h>
+#include <pwd.h>
+#include <uuid/uuid.h>
+#include "iOSforOSX.h"
+#include <pwd.h>
+#include <unistd.h>
+
+#include ".././libsecurity_keychain/lib/SecBase64P.c"
+
+CFURLRef SecCopyKeychainDirectoryFile(CFStringRef file)
+{
+    struct passwd *passwd = getpwuid(getuid());
+    if (!passwd)
+        return NULL;
+    
+    CFURLRef pathURL = NULL;
+    CFURLRef fileURL = NULL;
+    CFStringRef home = NULL;
+    CFStringRef filePath = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%s/%@"), "Library/Keychains", file);
+    require(filePath, xit);
+    
+    if (passwd->pw_dir)
+        home = CFStringCreateWithCString(NULL, passwd->pw_dir, kCFStringEncodingUTF8);
+
+    pathURL = CFURLCreateWithFileSystemPath(NULL, home?home:CFSTR("/"), kCFURLPOSIXPathStyle, true);
+    if (pathURL)
+        fileURL = CFURLCreateCopyAppendingPathComponent(kCFAllocatorDefault, pathURL, filePath, false);
+
+xit:
+    CFReleaseSafe(filePath);
+    CFReleaseSafe(pathURL);
+    CFReleaseSafe(home);
+    return fileURL;
+}
+
+// XXX: do we still need this?  see securityd_files?
+CFURLRef PortableCFCopyHomeDirectoryURL(void)
+{
+    char *path = getenv("HOME");
+    if (!path) {
+        struct passwd *pw = getpwuid(getuid());
+        path = pw->pw_dir;
+    }
+    CFStringRef path_cf = CFStringCreateWithCStringNoCopy(NULL, path, kCFStringEncodingUTF8, kCFAllocatorNull);
+    CFURLRef path_url = CFURLCreateWithFileSystemPath(NULL, path_cf, kCFURLPOSIXPathStyle, true);
+    
+    CFRelease(path_cf);
+    return path_url;
+}
+
+#endif
diff --git a/utilities/src/iOSforOSX.h b/utilities/src/iOSforOSX.h
new file mode 100644 (file)
index 0000000..96cb072
--- /dev/null
@@ -0,0 +1,34 @@
+//
+//  iOSforOSX.h
+//  utilities
+//
+//  Created by J Osborne on 11/13/12.
+//  Copyright (c) 2012 Apple Inc. All rights reserved.
+//
+
+#ifndef utilities_iOSforOSX_h
+#define utilities_iOSforOSX_h
+
+#include <TargetConditionals.h>
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+
+extern CFURLRef SecCopyKeychainDirectoryFile(CFStringRef file);
+
+CFURLRef PortableCFCopyHomeDirectoryURL(void);
+
+#ifndef _SECURITY_SECRANDOM_H_
+extern const void *kSecRandomDefault;
+#endif
+
+#ifndef _SECURITY_SECBASE_H_
+typedef struct OpaqueSecKeyRef *SecKeyRef;
+#endif
+OSStatus SecKeyCopyPersistentRef(SecKeyRef item, CFDataRef *newPersistantRef);
+OSStatus SecKeyFindWithPersistentRef(CFDataRef persistantRef, SecKeyRef *key);
+
+
+#endif
+
+CFURLRef PortableCFCopyHomeDirectoryURL(void) asm("_CFCopyHomeDirectoryURL");
+
+#endif
diff --git a/utilities/src/sqlutils.h b/utilities/src/sqlutils.h
new file mode 100644 (file)
index 0000000..6837a03
--- /dev/null
@@ -0,0 +1,37 @@
+//
+//  sqlutils.h
+//  Security
+//
+//  Created by Fabrice Gautier on 8/26/11.
+//  Copyright (c) 2011 Apple, Inc. All rights reserved.
+//
+
+/*
+ * sqlutils.h - some wrapper for sql3lite
+ */
+#ifndef _SECURITY_UTILITIES_SQLUTILS_H_
+#define _SECURITY_UTILITIES_SQLUTILS_H_
+
+#include <sqlite3.h>
+
+/* Those are just wrapper around the sqlite3 functions, but they have size_t for some len parameters,
+   and checks for overflow before casting to int */
+static inline int sqlite3_bind_blob_wrapper(sqlite3_stmt* pStmt, int i, const void* zData, size_t n, void(*xDel)(void*))
+{
+    if(n>INT_MAX) return SQLITE_TOOBIG;
+    return sqlite3_bind_blob(pStmt, i, zData, (int)n, xDel);
+}
+
+static inline int sqlite3_bind_text_wrapper(sqlite3_stmt* pStmt, int i, const void* zData, size_t n, void(*xDel)(void*))
+{
+    if(n>INT_MAX) return SQLITE_TOOBIG;
+    return sqlite3_bind_text(pStmt, i, zData, (int)n, xDel);
+}
+
+static inline int sqlite3_prepare_wrapper(sqlite3 *db, const char *zSql, size_t nByte, sqlite3_stmt **ppStmt, const char **pzTail)
+{
+    if(nByte>INT_MAX) return SQLITE_TOOBIG;
+    return sqlite3_prepare(db, zSql, (int)nByte, ppStmt, pzTail);
+}
+
+#endif
diff --git a/utilities/utilities b/utilities/utilities
new file mode 120000 (symlink)
index 0000000..945c9b4
--- /dev/null
@@ -0,0 +1 @@
+.
\ No newline at end of file
diff --git a/utilities/utilities.xcodeproj/project.pbxproj b/utilities/utilities.xcodeproj/project.pbxproj
new file mode 100644 (file)
index 0000000..e38ce72
--- /dev/null
@@ -0,0 +1,538 @@
+// !$*UTF8*$!
+{
+       archiveVersion = 1;
+       classes = {
+       };
+       objectVersion = 46;
+       objects = {
+
+/* Begin PBXBuildFile section */
+               4C068F811653146500E8A1BB /* iOSforOSX.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C068F801653146500E8A1BB /* iOSforOSX.h */; };
+               4C143CF8165172AD003035A3 /* SecDb.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C143CF7165172AD003035A3 /* SecDb.c */; };
+               4C3600451680DEB90049891B /* iOSforOSX-SecAttr.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C3600431680DEB90049891B /* iOSforOSX-SecAttr.c */; };
+               4C3600461680DEB90049891B /* iOSforOSX-SecRandom.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C3600441680DEB90049891B /* iOSforOSX-SecRandom.c */; };
+               4C3963D915ACF2E700762091 /* su-16-cfdate-der.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C3963D815ACF2E700762091 /* su-16-cfdate-der.c */; };
+               4C5BCD8A17304CE600DCEFB4 /* der_null.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C5BCD8917304B8100DCEFB4 /* der_null.c */; };
+               4C6882D415ABADBC00028C8F /* SecCFCanonicalHashes.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C6882BD15ABADBC00028C8F /* SecCFCanonicalHashes.c */; };
+               4C6882D515ABADBC00028C8F /* SecCFCanonicalHashes.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C6882BE15ABADBC00028C8F /* SecCFCanonicalHashes.h */; };
+               4C6882D615ABADBC00028C8F /* SecCFRelease.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C6882BF15ABADBC00028C8F /* SecCFRelease.h */; };
+               4C6882D715ABADBC00028C8F /* SecCFWrappers.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C6882C015ABADBC00028C8F /* SecCFWrappers.h */; };
+               4C6882D815ABADBC00028C8F /* array_size.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C6882C115ABADBC00028C8F /* array_size.h */; };
+               4C6882D915ABADBC00028C8F /* comparison.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C6882C215ABADBC00028C8F /* comparison.c */; };
+               4C6882DA15ABADBC00028C8F /* comparison.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C6882C315ABADBC00028C8F /* comparison.h */; };
+               4C6882DB15ABADBC00028C8F /* debugging.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C6882C415ABADBC00028C8F /* debugging.c */; };
+               4C6882DC15ABADBC00028C8F /* debugging.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C6882C515ABADBC00028C8F /* debugging.h */; };
+               4C6882DD15ABADBC00028C8F /* der_array.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C6882C615ABADBC00028C8F /* der_array.c */; };
+               4C6882DE15ABADBC00028C8F /* der_boolean.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C6882C715ABADBC00028C8F /* der_boolean.c */; };
+               4C6882DF15ABADBC00028C8F /* der_data.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C6882C815ABADBC00028C8F /* der_data.c */; };
+               4C6882E015ABADBC00028C8F /* der_date.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C6882C915ABADBC00028C8F /* der_date.c */; };
+               4C6882E115ABADBC00028C8F /* der_dictionary.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C6882CA15ABADBC00028C8F /* der_dictionary.c */; };
+               4C6882E215ABADBC00028C8F /* der_number.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C6882CB15ABADBC00028C8F /* der_number.c */; };
+               4C6882E315ABADBC00028C8F /* der_plist.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C6882CC15ABADBC00028C8F /* der_plist.c */; };
+               4C6882E415ABADBC00028C8F /* der_plist.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C6882CD15ABADBC00028C8F /* der_plist.h */; };
+               4C6882E515ABADBC00028C8F /* der_plist_internal.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C6882CE15ABADBC00028C8F /* der_plist_internal.c */; };
+               4C6882E615ABADBC00028C8F /* der_plist_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C6882CF15ABADBC00028C8F /* der_plist_internal.h */; };
+               4C6882E715ABADBC00028C8F /* der_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C6882D015ABADBC00028C8F /* der_string.c */; };
+               4C6882E815ABADBC00028C8F /* fileIo.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C6882D115ABADBC00028C8F /* fileIo.c */; };
+               4C6882E915ABADBC00028C8F /* fileIo.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C6882D215ABADBC00028C8F /* fileIo.h */; };
+               4C6882EA15ABADBC00028C8F /* sqlutils.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C6882D315ABADBC00028C8F /* sqlutils.h */; };
+               4CB23B9816A09503003A0131 /* not_on_this_platorm.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CB23B9716A09503003A0131 /* not_on_this_platorm.c */; };
+               4CC0275217A1C796004067B2 /* su-41-secdb-stress.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CC0275117A1C796004067B2 /* su-41-secdb-stress.c */; };
+               4CC92B1F15A3C55200C6D578 /* utilities_regressions.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CC92B1E15A3C55200C6D578 /* utilities_regressions.h */; };
+               4CF1FAC21654EAD100261CF4 /* SecCFWrappers.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CF1FAC11654EAD100261CF4 /* SecCFWrappers.c */; };
+               4CF1FAC416550F6900261CF4 /* su-40-secdb.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CF1FAC316550F6900261CF4 /* su-40-secdb.c */; };
+               52743BD616BB278C001A299D /* SecFileLocations.c in Sources */ = {isa = PBXBuildFile; fileRef = 52743BD516BB278C001A299D /* SecFileLocations.c */; };
+               52743BD816BB27A1001A299D /* SecFileLocations.h in Headers */ = {isa = PBXBuildFile; fileRef = 52743BD716BB27A1001A299D /* SecFileLocations.h */; };
+               52E2E4951738371400E78313 /* SecXPCError.h in Headers */ = {isa = PBXBuildFile; fileRef = 52E2E4941738371400E78313 /* SecXPCError.h */; };
+               52E2E4971738394C00E78313 /* SecXPCError.c in Sources */ = {isa = PBXBuildFile; fileRef = 52E2E4961738394C00E78313 /* SecXPCError.c */; };
+               72B918A1179723B500940533 /* iCloudKeychainTrace.c in Sources */ = {isa = PBXBuildFile; fileRef = 72B9189F179723AE00940533 /* iCloudKeychainTrace.c */; };
+               72B918A2179723C100940533 /* iCloudKeychainTrace.h in Headers */ = {isa = PBXBuildFile; fileRef = 72B918A0179723AE00940533 /* iCloudKeychainTrace.h */; };
+               E72D461E175FB73100F70B9B /* SecAKSWrappers.h in Headers */ = {isa = PBXBuildFile; fileRef = E72D461D175FAF1E00F70B9B /* SecAKSWrappers.h */; };
+               E72D462D175FC35500F70B9B /* SecAKSWrappers.c in Sources */ = {isa = PBXBuildFile; fileRef = E72D462C175FC35500F70B9B /* SecAKSWrappers.c */; };
+               E765E23615A79F77006C7347 /* su-15-cfdictionary-der.c in Sources */ = {isa = PBXBuildFile; fileRef = E765E23315A79EA6006C7347 /* su-15-cfdictionary-der.c */; };
+               E777C72115B74029004044A8 /* SecCFError.h in Headers */ = {isa = PBXBuildFile; fileRef = E777C71F15B74024004044A8 /* SecCFError.h */; };
+               E777C72315B74038004044A8 /* SecCFError.c in Sources */ = {isa = PBXBuildFile; fileRef = E777C72215B74037004044A8 /* SecCFError.c */; };
+               E790C14C169E5D9C00E0C0C9 /* readline.c in Sources */ = {isa = PBXBuildFile; fileRef = E790C14A169E5D9C00E0C0C9 /* readline.c */; };
+               E790C14D169E5D9C00E0C0C9 /* readline.h in Headers */ = {isa = PBXBuildFile; fileRef = E790C14B169E5D9C00E0C0C9 /* readline.h */; };
+               E7934D7115A3A29D007666E0 /* su-14-cfarray-der.c in Sources */ = {isa = PBXBuildFile; fileRef = E7934D6E15A3A298007666E0 /* su-14-cfarray-der.c */; };
+               E79D9CE3159D2DB8000834EC /* su-12-cfboolean-der.c in Sources */ = {isa = PBXBuildFile; fileRef = E79D9CE2159D2DB8000834EC /* su-12-cfboolean-der.c */; };
+               E79D9CE5159D3138000834EC /* su-13-cfnumber-der.c in Sources */ = {isa = PBXBuildFile; fileRef = E79D9CE4159D3138000834EC /* su-13-cfnumber-der.c */; };
+               E7AAB5FA15929D44005C8BCC /* su-11-cfdata-der.c in Sources */ = {isa = PBXBuildFile; fileRef = E7AAB5F815929D3E005C8BCC /* su-11-cfdata-der.c */; };
+               E7E0D909158FD9CD002CA176 /* su-10-cfstring-der.c in Sources */ = {isa = PBXBuildFile; fileRef = E7E0D908158FD9CD002CA176 /* su-10-cfstring-der.c */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+               4C068F801653146500E8A1BB /* iOSforOSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iOSforOSX.h; sourceTree = "<group>"; };
+               4C068F821653147D00E8A1BB /* iOSforOSX.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = iOSforOSX.c; sourceTree = "<group>"; };
+               4C143CF7165172AD003035A3 /* SecDb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecDb.c; sourceTree = "<group>"; };
+               4C143CF9165172C0003035A3 /* SecDb.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecDb.h; sourceTree = "<group>"; };
+               4C3600431680DEB90049891B /* iOSforOSX-SecAttr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "iOSforOSX-SecAttr.c"; sourceTree = "<group>"; };
+               4C3600441680DEB90049891B /* iOSforOSX-SecRandom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "iOSforOSX-SecRandom.c"; sourceTree = "<group>"; };
+               4C3963D815ACF2E700762091 /* su-16-cfdate-der.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "su-16-cfdate-der.c"; sourceTree = "<group>"; };
+               4C5BCD8917304B8100DCEFB4 /* der_null.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = der_null.c; sourceTree = "<group>"; };
+               4C6882BD15ABADBC00028C8F /* SecCFCanonicalHashes.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecCFCanonicalHashes.c; sourceTree = "<group>"; };
+               4C6882BE15ABADBC00028C8F /* SecCFCanonicalHashes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCFCanonicalHashes.h; sourceTree = "<group>"; };
+               4C6882BF15ABADBC00028C8F /* SecCFRelease.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCFRelease.h; sourceTree = "<group>"; };
+               4C6882C015ABADBC00028C8F /* SecCFWrappers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCFWrappers.h; sourceTree = "<group>"; };
+               4C6882C115ABADBC00028C8F /* array_size.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = array_size.h; sourceTree = "<group>"; };
+               4C6882C215ABADBC00028C8F /* comparison.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = comparison.c; sourceTree = "<group>"; };
+               4C6882C315ABADBC00028C8F /* comparison.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = comparison.h; sourceTree = "<group>"; };
+               4C6882C415ABADBC00028C8F /* debugging.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = debugging.c; sourceTree = "<group>"; };
+               4C6882C515ABADBC00028C8F /* debugging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debugging.h; sourceTree = "<group>"; };
+               4C6882C615ABADBC00028C8F /* der_array.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_array.c; sourceTree = "<group>"; };
+               4C6882C715ABADBC00028C8F /* der_boolean.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_boolean.c; sourceTree = "<group>"; };
+               4C6882C815ABADBC00028C8F /* der_data.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_data.c; sourceTree = "<group>"; };
+               4C6882C915ABADBC00028C8F /* der_date.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_date.c; sourceTree = "<group>"; };
+               4C6882CA15ABADBC00028C8F /* der_dictionary.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_dictionary.c; sourceTree = "<group>"; };
+               4C6882CB15ABADBC00028C8F /* der_number.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_number.c; sourceTree = "<group>"; };
+               4C6882CC15ABADBC00028C8F /* der_plist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_plist.c; sourceTree = "<group>"; };
+               4C6882CD15ABADBC00028C8F /* der_plist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = der_plist.h; sourceTree = "<group>"; };
+               4C6882CE15ABADBC00028C8F /* der_plist_internal.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_plist_internal.c; sourceTree = "<group>"; };
+               4C6882CF15ABADBC00028C8F /* der_plist_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = der_plist_internal.h; sourceTree = "<group>"; };
+               4C6882D015ABADBC00028C8F /* der_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_string.c; sourceTree = "<group>"; };
+               4C6882D115ABADBC00028C8F /* fileIo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fileIo.c; sourceTree = "<group>"; };
+               4C6882D215ABADBC00028C8F /* fileIo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fileIo.h; sourceTree = "<group>"; };
+               4C6882D315ABADBC00028C8F /* sqlutils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sqlutils.h; sourceTree = "<group>"; };
+               4C6882EB15ABC4B400028C8F /* der_date.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = der_date.h; sourceTree = "<group>"; };
+               4CB23B9616A09318003A0131 /* security_tool_commands_table.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = security_tool_commands_table.h; sourceTree = "<group>"; };
+               4CB23B9716A09503003A0131 /* not_on_this_platorm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = not_on_this_platorm.c; sourceTree = "<group>"; };
+               4CC0275117A1C796004067B2 /* su-41-secdb-stress.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "su-41-secdb-stress.c"; sourceTree = "<group>"; };
+               4CC92B1E15A3C55200C6D578 /* utilities_regressions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utilities_regressions.h; sourceTree = "<group>"; };
+               4CF1FAC11654EAD100261CF4 /* SecCFWrappers.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecCFWrappers.c; sourceTree = "<group>"; };
+               4CF1FAC316550F6900261CF4 /* su-40-secdb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "su-40-secdb.c"; sourceTree = "<group>"; };
+               52743BD516BB278C001A299D /* SecFileLocations.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecFileLocations.c; sourceTree = "<group>"; };
+               52743BD716BB27A1001A299D /* SecFileLocations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecFileLocations.h; sourceTree = "<group>"; };
+               52E2E4941738371400E78313 /* SecXPCError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecXPCError.h; sourceTree = "<group>"; };
+               52E2E4961738394C00E78313 /* SecXPCError.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecXPCError.c; sourceTree = "<group>"; };
+               72B9189F179723AE00940533 /* iCloudKeychainTrace.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = iCloudKeychainTrace.c; sourceTree = "<group>"; };
+               72B918A0179723AE00940533 /* iCloudKeychainTrace.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = iCloudKeychainTrace.h; sourceTree = "<group>"; };
+               E72D461D175FAF1E00F70B9B /* SecAKSWrappers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecAKSWrappers.h; sourceTree = "<group>"; };
+               E72D462C175FC35500F70B9B /* SecAKSWrappers.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecAKSWrappers.c; sourceTree = "<group>"; };
+               E742A09C14E343E70052A486 /* libutilities.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libutilities.a; sourceTree = BUILT_PRODUCTS_DIR; };
+               E742A0C014E344940052A486 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
+               E765E23315A79EA6006C7347 /* su-15-cfdictionary-der.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "su-15-cfdictionary-der.c"; sourceTree = "<group>"; };
+               E777C71F15B74024004044A8 /* SecCFError.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecCFError.h; sourceTree = "<group>"; };
+               E777C72215B74037004044A8 /* SecCFError.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecCFError.c; sourceTree = "<group>"; };
+               E790C0F6169E4B8500E0C0C9 /* security_tool_commands.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = security_tool_commands.h; sourceTree = "<group>"; };
+               E790C14A169E5D9C00E0C0C9 /* readline.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = readline.c; sourceTree = "<group>"; };
+               E790C14B169E5D9C00E0C0C9 /* readline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = readline.h; sourceTree = "<group>"; };
+               E7934D6E15A3A298007666E0 /* su-14-cfarray-der.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "su-14-cfarray-der.c"; sourceTree = "<group>"; };
+               E79D9CE2159D2DB8000834EC /* su-12-cfboolean-der.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "su-12-cfboolean-der.c"; sourceTree = "<group>"; };
+               E79D9CE4159D3138000834EC /* su-13-cfnumber-der.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "su-13-cfnumber-der.c"; sourceTree = "<group>"; };
+               E7AAB5F815929D3E005C8BCC /* su-11-cfdata-der.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "su-11-cfdata-der.c"; sourceTree = "<group>"; };
+               E7B01B961664031B000485F1 /* SecDispatchRelease.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecDispatchRelease.h; sourceTree = "<group>"; };
+               E7E0D8F9158FA9A3002CA176 /* libutilitiesRegressions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libutilitiesRegressions.a; sourceTree = BUILT_PRODUCTS_DIR; };
+               E7E0D908158FD9CD002CA176 /* su-10-cfstring-der.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "su-10-cfstring-der.c"; sourceTree = "<group>"; };
+               E7FC081B161A3038008E0760 /* SecIOFormat.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecIOFormat.h; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+               E742A09914E343E70052A486 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               E7E0D8ED158FA9A3002CA176 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+               4C6882BC15ABADBC00028C8F /* src */ = {
+                       isa = PBXGroup;
+                       children = (
+                               72B9189F179723AE00940533 /* iCloudKeychainTrace.c */,
+                               72B918A0179723AE00940533 /* iCloudKeychainTrace.h */,
+                               E72D462C175FC35500F70B9B /* SecAKSWrappers.c */,
+                               E72D461D175FAF1E00F70B9B /* SecAKSWrappers.h */,
+                               4C6882BD15ABADBC00028C8F /* SecCFCanonicalHashes.c */,
+                               4C6882BE15ABADBC00028C8F /* SecCFCanonicalHashes.h */,
+                               4C6882BF15ABADBC00028C8F /* SecCFRelease.h */,
+                               4CF1FAC11654EAD100261CF4 /* SecCFWrappers.c */,
+                               4C6882C015ABADBC00028C8F /* SecCFWrappers.h */,
+                               E777C72215B74037004044A8 /* SecCFError.c */,
+                               E777C71F15B74024004044A8 /* SecCFError.h */,
+                               E7B01B961664031B000485F1 /* SecDispatchRelease.h */,
+                               E7FC081B161A3038008E0760 /* SecIOFormat.h */,
+                               4C6882C115ABADBC00028C8F /* array_size.h */,
+                               4C6882C215ABADBC00028C8F /* comparison.c */,
+                               4C6882C315ABADBC00028C8F /* comparison.h */,
+                               4C6882C415ABADBC00028C8F /* debugging.c */,
+                               4C6882C515ABADBC00028C8F /* debugging.h */,
+                               4C6882C615ABADBC00028C8F /* der_array.c */,
+                               4C6882C715ABADBC00028C8F /* der_boolean.c */,
+                               4C5BCD8917304B8100DCEFB4 /* der_null.c */,
+                               4C6882C815ABADBC00028C8F /* der_data.c */,
+                               4C6882C915ABADBC00028C8F /* der_date.c */,
+                               4C6882EB15ABC4B400028C8F /* der_date.h */,
+                               4C6882CA15ABADBC00028C8F /* der_dictionary.c */,
+                               4C6882CB15ABADBC00028C8F /* der_number.c */,
+                               4C6882CC15ABADBC00028C8F /* der_plist.c */,
+                               4C6882CD15ABADBC00028C8F /* der_plist.h */,
+                               4C6882CE15ABADBC00028C8F /* der_plist_internal.c */,
+                               4C6882CF15ABADBC00028C8F /* der_plist_internal.h */,
+                               4C6882D015ABADBC00028C8F /* der_string.c */,
+                               4C6882D115ABADBC00028C8F /* fileIo.c */,
+                               4C6882D215ABADBC00028C8F /* fileIo.h */,
+                               4C6882D315ABADBC00028C8F /* sqlutils.h */,
+                               4C068F801653146500E8A1BB /* iOSforOSX.h */,
+                               4C068F821653147D00E8A1BB /* iOSforOSX.c */,
+                               4C3600431680DEB90049891B /* iOSforOSX-SecAttr.c */,
+                               4C3600441680DEB90049891B /* iOSforOSX-SecRandom.c */,
+                               4C143CF7165172AD003035A3 /* SecDb.c */,
+                               4C143CF9165172C0003035A3 /* SecDb.h */,
+                               52743BD516BB278C001A299D /* SecFileLocations.c */,
+                               52743BD716BB27A1001A299D /* SecFileLocations.h */,
+                               52E2E4941738371400E78313 /* SecXPCError.h */,
+                               52E2E4961738394C00E78313 /* SecXPCError.c */,
+                       );
+                       path = src;
+                       sourceTree = "<group>";
+               };
+               E742A09114E343E70052A486 = {
+                       isa = PBXGroup;
+                       children = (
+                               4C6882BC15ABADBC00028C8F /* src */,
+                               E7E0D8E7158FA984002CA176 /* Regressions */,
+                               E790C0F5169E4B5E00E0C0C9 /* SecurityTool */,
+                               E742A09E14E343E70052A486 /* Frameworks */,
+                               E742A09D14E343E70052A486 /* Products */,
+                       );
+                       sourceTree = "<group>";
+               };
+               E742A09D14E343E70052A486 /* Products */ = {
+                       isa = PBXGroup;
+                       children = (
+                               E742A09C14E343E70052A486 /* libutilities.a */,
+                               E7E0D8F9158FA9A3002CA176 /* libutilitiesRegressions.a */,
+                       );
+                       name = Products;
+                       sourceTree = "<group>";
+               };
+               E742A09E14E343E70052A486 /* Frameworks */ = {
+                       isa = PBXGroup;
+                       children = (
+                               E742A0C014E344940052A486 /* CoreFoundation.framework */,
+                       );
+                       name = Frameworks;
+                       sourceTree = "<group>";
+               };
+               E790C0F5169E4B5E00E0C0C9 /* SecurityTool */ = {
+                       isa = PBXGroup;
+                       children = (
+                               E790C14A169E5D9C00E0C0C9 /* readline.c */,
+                               E790C14B169E5D9C00E0C0C9 /* readline.h */,
+                               E790C0F6169E4B8500E0C0C9 /* security_tool_commands.h */,
+                               4CB23B9616A09318003A0131 /* security_tool_commands_table.h */,
+                               4CB23B9716A09503003A0131 /* not_on_this_platorm.c */,
+                       );
+                       path = SecurityTool;
+                       sourceTree = "<group>";
+               };
+               E7E0D8E7158FA984002CA176 /* Regressions */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4CC92B1E15A3C55200C6D578 /* utilities_regressions.h */,
+                               E7E0D908158FD9CD002CA176 /* su-10-cfstring-der.c */,
+                               E7AAB5F815929D3E005C8BCC /* su-11-cfdata-der.c */,
+                               E79D9CE2159D2DB8000834EC /* su-12-cfboolean-der.c */,
+                               E79D9CE4159D3138000834EC /* su-13-cfnumber-der.c */,
+                               E7934D6E15A3A298007666E0 /* su-14-cfarray-der.c */,
+                               E765E23315A79EA6006C7347 /* su-15-cfdictionary-der.c */,
+                               4C3963D815ACF2E700762091 /* su-16-cfdate-der.c */,
+                               4CF1FAC316550F6900261CF4 /* su-40-secdb.c */,
+                               4CC0275117A1C796004067B2 /* su-41-secdb-stress.c */,
+                       );
+                       path = Regressions;
+                       sourceTree = "<group>";
+               };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+               E742A09A14E343E70052A486 /* Headers */ = {
+                       isa = PBXHeadersBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               72B918A2179723C100940533 /* iCloudKeychainTrace.h in Headers */,
+                               4C6882D515ABADBC00028C8F /* SecCFCanonicalHashes.h in Headers */,
+                               4C6882D615ABADBC00028C8F /* SecCFRelease.h in Headers */,
+                               52E2E4951738371400E78313 /* SecXPCError.h in Headers */,
+                               4C6882D715ABADBC00028C8F /* SecCFWrappers.h in Headers */,
+                               E72D461E175FB73100F70B9B /* SecAKSWrappers.h in Headers */,
+                               4C6882D815ABADBC00028C8F /* array_size.h in Headers */,
+                               4C6882DA15ABADBC00028C8F /* comparison.h in Headers */,
+                               4C6882DC15ABADBC00028C8F /* debugging.h in Headers */,
+                               4C6882E415ABADBC00028C8F /* der_plist.h in Headers */,
+                               4C6882E615ABADBC00028C8F /* der_plist_internal.h in Headers */,
+                               4C6882E915ABADBC00028C8F /* fileIo.h in Headers */,
+                               4C6882EA15ABADBC00028C8F /* sqlutils.h in Headers */,
+                               E777C72115B74029004044A8 /* SecCFError.h in Headers */,
+                               4C068F811653146500E8A1BB /* iOSforOSX.h in Headers */,
+                               E790C14D169E5D9C00E0C0C9 /* readline.h in Headers */,
+                               52743BD816BB27A1001A299D /* SecFileLocations.h in Headers */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               E7E0D8EF158FA9A3002CA176 /* Headers */ = {
+                       isa = PBXHeadersBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               4CC92B1F15A3C55200C6D578 /* utilities_regressions.h in Headers */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+               E742A09B14E343E70052A486 /* utilities */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = E742A0A914E343E70052A486 /* Build configuration list for PBXNativeTarget "utilities" */;
+                       buildPhases = (
+                               E742A09814E343E70052A486 /* Sources */,
+                               E742A09914E343E70052A486 /* Frameworks */,
+                               E742A09A14E343E70052A486 /* Headers */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = utilities;
+                       productName = security_utilities;
+                       productReference = E742A09C14E343E70052A486 /* libutilities.a */;
+                       productType = "com.apple.product-type.library.static";
+               };
+               E7E0D8E8158FA9A3002CA176 /* utilitiesRegressions */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = E7E0D8F6158FA9A3002CA176 /* Build configuration list for PBXNativeTarget "utilitiesRegressions" */;
+                       buildPhases = (
+                               E7E0D8E9158FA9A3002CA176 /* Sources */,
+                               E7E0D8ED158FA9A3002CA176 /* Frameworks */,
+                               E7E0D8EF158FA9A3002CA176 /* Headers */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = utilitiesRegressions;
+                       productName = security_utilities;
+                       productReference = E7E0D8F9158FA9A3002CA176 /* libutilitiesRegressions.a */;
+                       productType = "com.apple.product-type.library.static";
+               };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+               E742A09314E343E70052A486 /* Project object */ = {
+                       isa = PBXProject;
+                       attributes = {
+                               LastUpgradeCheck = 0450;
+                               ORGANIZATIONNAME = "Apple Inc.";
+                       };
+                       buildConfigurationList = E742A09614E343E70052A486 /* Build configuration list for PBXProject "utilities" */;
+                       compatibilityVersion = "Xcode 3.2";
+                       developmentRegion = English;
+                       hasScannedForEncodings = 0;
+                       knownRegions = (
+                               en,
+                       );
+                       mainGroup = E742A09114E343E70052A486;
+                       productRefGroup = E742A09D14E343E70052A486 /* Products */;
+                       projectDirPath = "";
+                       projectRoot = "";
+                       targets = (
+                               E742A09B14E343E70052A486 /* utilities */,
+                               E7E0D8E8158FA9A3002CA176 /* utilitiesRegressions */,
+                       );
+               };
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+               E742A09814E343E70052A486 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               4C6882D415ABADBC00028C8F /* SecCFCanonicalHashes.c in Sources */,
+                               4C6882D915ABADBC00028C8F /* comparison.c in Sources */,
+                               4C6882DB15ABADBC00028C8F /* debugging.c in Sources */,
+                               72B918A1179723B500940533 /* iCloudKeychainTrace.c in Sources */,
+                               4C6882DD15ABADBC00028C8F /* der_array.c in Sources */,
+                               4C6882DE15ABADBC00028C8F /* der_boolean.c in Sources */,
+                               4C6882DF15ABADBC00028C8F /* der_data.c in Sources */,
+                               4C6882E015ABADBC00028C8F /* der_date.c in Sources */,
+                               E72D462D175FC35500F70B9B /* SecAKSWrappers.c in Sources */,
+                               4C6882E115ABADBC00028C8F /* der_dictionary.c in Sources */,
+                               4C6882E215ABADBC00028C8F /* der_number.c in Sources */,
+                               4C6882E315ABADBC00028C8F /* der_plist.c in Sources */,
+                               4C6882E515ABADBC00028C8F /* der_plist_internal.c in Sources */,
+                               4C6882E715ABADBC00028C8F /* der_string.c in Sources */,
+                               4C6882E815ABADBC00028C8F /* fileIo.c in Sources */,
+                               E777C72315B74038004044A8 /* SecCFError.c in Sources */,
+                               4C143CF8165172AD003035A3 /* SecDb.c in Sources */,
+                               4CF1FAC21654EAD100261CF4 /* SecCFWrappers.c in Sources */,
+                               52E2E4971738394C00E78313 /* SecXPCError.c in Sources */,
+                               4C3600451680DEB90049891B /* iOSforOSX-SecAttr.c in Sources */,
+                               4C3600461680DEB90049891B /* iOSforOSX-SecRandom.c in Sources */,
+                               E790C14C169E5D9C00E0C0C9 /* readline.c in Sources */,
+                               4CB23B9816A09503003A0131 /* not_on_this_platorm.c in Sources */,
+                               4C5BCD8A17304CE600DCEFB4 /* der_null.c in Sources */,
+                               52743BD616BB278C001A299D /* SecFileLocations.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               E7E0D8E9158FA9A3002CA176 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               4CC0275217A1C796004067B2 /* su-41-secdb-stress.c in Sources */,
+                               E7E0D909158FD9CD002CA176 /* su-10-cfstring-der.c in Sources */,
+                               E7AAB5FA15929D44005C8BCC /* su-11-cfdata-der.c in Sources */,
+                               E79D9CE3159D2DB8000834EC /* su-12-cfboolean-der.c in Sources */,
+                               E79D9CE5159D3138000834EC /* su-13-cfnumber-der.c in Sources */,
+                               E7934D7115A3A29D007666E0 /* su-14-cfarray-der.c in Sources */,
+                               E765E23615A79F77006C7347 /* su-15-cfdictionary-der.c in Sources */,
+                               4C3963D915ACF2E700762091 /* su-16-cfdate-der.c in Sources */,
+                               4CF1FAC416550F6900261CF4 /* su-40-secdb.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+               E742A0A714E343E70052A486 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+                               CLANG_ENABLE_OBJC_ARC = YES;
+                               COPY_PHASE_STRIP = NO;
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "$(inherited)",
+                                       "DEBUG=1",
+                               );
+                               GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               SUPPORTED_PLATFORMS = "iphonesimulator iphoneos macosx";
+                       };
+                       name = Debug;
+               };
+               E742A0A814E343E70052A486 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+                               CLANG_ENABLE_OBJC_ARC = YES;
+                               COPY_PHASE_STRIP = NO;
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_PREPROCESSOR_DEFINITIONS = "NDEBUG=1";
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               SUPPORTED_PLATFORMS = "iphonesimulator iphoneos macosx";
+                               VALIDATE_PRODUCT = YES;
+                       };
+                       name = Release;
+               };
+               E742A0AA14E343E70052A486 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               HEADER_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       "$(PROJECT_DIR)",
+                                       "$(PROJECT_DIR)/../sec",
+                                       "$(BUILT_PRODUCTS_DIR)$(INDIGO_INSTALL_PATH_PREFIX)/usr/local/include",
+                               );
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               SKIP_INSTALL = YES;
+                       };
+                       name = Debug;
+               };
+               E742A0AB14E343E70052A486 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               HEADER_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       "$(PROJECT_DIR)",
+                                       "$(PROJECT_DIR)/../sec",
+                                       "$(BUILT_PRODUCTS_DIR)$(INDIGO_INSTALL_PATH_PREFIX)/usr/local/include",
+                               );
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               SKIP_INSTALL = YES;
+                       };
+                       name = Release;
+               };
+               E7E0D8F7158FA9A3002CA176 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               HEADER_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       "$(PROJECT_DIR)",
+                                       "$(PROJECT_DIR)/../regressions",
+                                       "$(INDIGO_INSTALL_PATH_PREFIX)/usr/local/include",
+                               );
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               SKIP_INSTALL = YES;
+                       };
+                       name = Debug;
+               };
+               E7E0D8F8158FA9A3002CA176 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               HEADER_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       "$(PROJECT_DIR)",
+                                       "$(PROJECT_DIR)/../regressions",
+                                       "$(INDIGO_INSTALL_PATH_PREFIX)/usr/local/include",
+                               );
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               SKIP_INSTALL = YES;
+                       };
+                       name = Release;
+               };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+               E742A09614E343E70052A486 /* Build configuration list for PBXProject "utilities" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               E742A0A714E343E70052A486 /* Debug */,
+                               E742A0A814E343E70052A486 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               E742A0A914E343E70052A486 /* Build configuration list for PBXNativeTarget "utilities" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               E742A0AA14E343E70052A486 /* Debug */,
+                               E742A0AB14E343E70052A486 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               E7E0D8F6158FA9A3002CA176 /* Build configuration list for PBXNativeTarget "utilitiesRegressions" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               E7E0D8F7158FA9A3002CA176 /* Debug */,
+                               E7E0D8F8158FA9A3002CA176 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+/* End XCConfigurationList section */
+       };
+       rootObject = E742A09314E343E70052A486 /* Project object */;
+}